From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 03 Jan 2024 09:43:39 +0000
Subject: [PATCH] update kernel to 5.10.198

---
 kernel/drivers/tty/serial/qcom_geni_serial.c                                                              |   30 
 kernel/include/dt-bindings/clock/imx8mp-clock.h                                                           |   10 
 kernel/drivers/misc/ocxl/file.c                                                                           |    7 
 kernel/drivers/soc/qcom/apr.c                                                                             |  143 
 kernel/fs/btrfs/rcu-string.h                                                                              |    6 
 kernel/arch/arm/boot/dts/armada-39x.dtsi                                                                  |    6 
 kernel/drivers/media/dvb-frontends/dib0070.c                                                              |    2 
 kernel/tools/power/x86/turbostat/turbostat.c                                                              |    2 
 kernel/drivers/media/platform/omap3isp/isp.c                                                              |    9 
 kernel/drivers/video/rockchip/mpp/mpp_vepu2.c                                                             |   45 
 kernel/drivers/media/tuners/fc0013.c                                                                      |    2 
 kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c                                                |   27 
 kernel/drivers/video/fbdev/nvidia/nvidia.c                                                                |    2 
 kernel/fs/sysv/itree.c                                                                                    |    6 
 kernel/kernel/trace/trace_output.c                                                                        |    3 
 kernel/drivers/media/i2c/ov2740.c                                                                         |    4 
 kernel/drivers/gpu/drm/panfrost/panfrost_mmu.c                                                            |    3 
 kernel/arch/x86/boot/main.c                                                                               |    2 
 kernel/drivers/mmc/host/rtsx_usb_sdmmc.c                                                                  |   11 
 kernel/drivers/platform/x86/mxm-wmi.c                                                                     |    8 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy0.dtsi                          |   46 
 kernel/drivers/gpu/drm/radeon/ci_dpm.c                                                                    |   28 
 kernel/net/ipv4/esp4_offload.c                                                                            |    3 
 kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-two-vp-two-separate-single-channel-lvds.dts      |  178 
 kernel/drivers/gpu/drm/amd/display/dc/inc/core_types.h                                                    |    3 
 kernel/drivers/usb/dwc3/core.c                                                                            |   68 
 kernel/drivers/net/tap.c                                                                                  |   12 
 kernel/include/sound/soc-dapm.h                                                                           |    1 
 kernel/drivers/mmc/host/pxamci.c                                                                          |    7 
 kernel/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c                                              |    3 
 kernel/drivers/mailbox/zynqmp-ipi-mailbox.c                                                               |   23 
 kernel/net/bluetooth/hidp/core.c                                                                          |    2 
 kernel/sound/firewire/tascam/tascam-stream.c                                                              |    2 
 kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-channel-lvds.dts                            |  108 
 kernel/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c                                                       |   10 
 kernel/fs/nfs/sysfs.c                                                                                     |   16 
 kernel/drivers/gpu/drm/amd/display/modules/freesync/freesync.c                                            |    9 
 kernel/include/linux/nmi.h                                                                                |    2 
 kernel/tools/power/x86/turbostat/turbostat.8                                                              |    2 
 kernel/drivers/usb/dwc3/core.h                                                                            |    3 
 kernel/drivers/mfd/rkx110_x120/rkx120_linkrx.c                                                            |  780 
 kernel/include/linux/usb/typec_altmode.h                                                                  |    2 
 kernel/kernel/sched/core.c                                                                                |   58 
 kernel/drivers/staging/rtl8712/rtl871x_xmit.c                                                             |   46 
 kernel/drivers/input/touchscreen/ads7846.c                                                                |  477 
 kernel/drivers/uio/uio_dmem_genirq.c                                                                      |   13 
 kernel/drivers/watchdog/pcwd_usb.c                                                                        |    6 
 kernel/kernel/events/core.c                                                                               |   30 
 kernel/include/uapi/linux/in.h                                                                            |    2 
 kernel/sound/soc/codecs/Kconfig                                                                           |   13 
 kernel/arch/x86/events/intel/uncore_snb.c                                                                 |    3 
 kernel/fs/nilfs2/the_nilfs.c                                                                              |  137 
 kernel/scripts/checkkconfigsymbols.py                                                                     |   13 
 kernel/drivers/firmware/meson/meson_sm.c                                                                  |    2 
 kernel/drivers/tty/serial/8250/8250_core.c                                                                |    1 
 kernel/fs/nilfs2/the_nilfs.h                                                                              |    2 
 kernel/include/linux/cpuset.h                                                                             |    9 
 kernel/drivers/net/ethernet/mediatek/mtk_eth_soc.h                                                        |    1 
 kernel/drivers/acpi/processor_idle.c                                                                      |   23 
 kernel/kernel/workqueue.c                                                                                 |   13 
 kernel/drivers/net/ethernet/mediatek/mtk_eth_soc.c                                                        |    6 
 kernel/drivers/infiniband/hw/hns/hns_roce_main.c                                                          |    8 
 kernel/security/integrity/ima/ima_modsig.c                                                                |    3 
 kernel/drivers/ata/libata-sata.c                                                                          |   21 
 kernel/tools/testing/selftests/net/vrf-xfrm-tests.sh                                                      |   32 
 kernel/drivers/scsi/scsi.c                                                                                |   11 
 kernel/net/tipc/name_distr.h                                                                              |    2 
 kernel/drivers/input/mouse/focaltech.c                                                                    |    8 
 kernel/arch/x86/kernel/apic/x2apic_phys.c                                                                 |    5 
 kernel/drivers/net/ethernet/intel/igbvf/igbvf.h                                                           |    4 
 kernel/include/linux/highmem.h                                                                            |   18 
 kernel/drivers/tty/serial/atmel_serial.c                                                                  |   12 
 kernel/drivers/clk/rockchip/clk-out.c                                                                     |    7 
 kernel/drivers/gpio/gpio-aspeed.c                                                                         |    2 
 kernel/drivers/media/i2c/sc2336.c                                                                         |   31 
 kernel/fs/lockd/mon.c                                                                                     |    3 
 kernel/drivers/net/ethernet/intel/ice/ice_xsk.c                                                           |    4 
 kernel/drivers/i2c/busses/i2c-mxs.c                                                                       |    4 
 kernel/net/sched/act_bpf.c                                                                                |    2 
 kernel/drivers/rtc/rtc-pcf85063.c                                                                         |   10 
 kernel/drivers/nvme/host/core.c                                                                           |   60 
 kernel/tools/perf/builtin-sched.c                                                                         |    2 
 kernel/drivers/perf/arm-cmn.c                                                                             |    7 
 kernel/arch/arm/boot/dts/vf610-zii-dev-rev-c.dts                                                          |    2 
 kernel/drivers/net/ethernet/sun/cassini.c                                                                 |    6 
 kernel/tools/testing/selftests/resctrl/cache.c                                                            |   18 
 kernel/drivers/net/phy/meson-gxl.c                                                                        |    4 
 kernel/drivers/video/rockchip/rga3/include/rga_hw_config.h                                                |   24 
 kernel/drivers/gpu/drm/rockchip/dw-dp.c                                                                   |    2 
 kernel/fs/xfs/libxfs/xfs_btree.c                                                                          |    8 
 kernel/drivers/media/radio/radio-shark2.c                                                                 |   10 
 kernel/drivers/rtc/rtc-ds1347.c                                                                           |    2 
 kernel/drivers/opp/core.c                                                                                 |    2 
 kernel/drivers/s390/net/ctcm_main.c                                                                       |   11 
 kernel/fs/configfs/dir.c                                                                                  |    2 
 kernel/drivers/input/mouse/alps.c                                                                         |   16 
 kernel/drivers/acpi/ec.c                                                                                  |    1 
 kernel/drivers/ata/libahci.c                                                                              |   49 
 kernel/include/linux/mmc/host.h                                                                           |    1 
 kernel/drivers/media/i2c/maxim4c/maxim4c_drv.c                                                            |  188 
 kernel/drivers/bus/mhi/host/Kconfig                                                                       |   31 
 kernel/drivers/gpu/drm/exynos/exynos_drm_crtc.c                                                           |    5 
 kernel/drivers/media/i2c/maxim4c/maxim4c_drv.h                                                            |    8 
 kernel/net/ipv4/raw.c                                                                                     |    5 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c                                               |   38 
 kernel/net/netfilter/core.c                                                                               |   16 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h                                               |    2 
 kernel/drivers/soc/rockchip/minidump/rk_minidump.c                                                        |   54 
 kernel/arch/x86/kernel/reboot.c                                                                           |   88 
 kernel/drivers/usb/host/xhci-pci.c                                                                        |   14 
 kernel/arch/arm/boot/dts/at91sam9261ek.dts                                                                |    2 
 kernel/arch/powerpc/kernel/vmlinux.lds.S                                                                  |    6 
 kernel/drivers/infiniband/hw/usnic/usnic_uiom.c                                                           |    8 
 kernel/sound/soc/codecs/ssm2602.c                                                                         |   15 
 kernel/drivers/net/ethernet/amd/lance.c                                                                   |    2 
 kernel/include/linux/string.h                                                                             |    7 
 kernel/arch/arm/boot/dts/omap4-cpu-thermal.dtsi                                                           |   29 
 kernel/drivers/mailbox/ti-msgmgr.c                                                                        |   12 
 kernel/drivers/gpu/drm/i915/i915_pci.c                                                                    |    3 
 kernel/arch/riscv/mm/fault.c                                                                              |    2 
 kernel/android/abi_gki_aarch64_asus                                                                       |    2 
 kernel/drivers/bus/mhi/host/debugfs.c                                                                     |    0 
 kernel/arch/alpha/kernel/module.c                                                                         |    4 
 kernel/drivers/clk/Kconfig                                                                                |    3 
 kernel/net/iucv/iucv.c                                                                                    |    2 
 kernel/drivers/block/null_blk/Kconfig                                                                     |   12 
 kernel/tools/perf/util/annotate.c                                                                         |   10 
 kernel/drivers/edac/i10nm_base.c                                                                          |    3 
 kernel/drivers/gpu/drm/i915/gvt/debugfs.c                                                                 |   17 
 kernel/fs/ubifs/dir.c                                                                                     |   10 
 kernel/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c                                                          |    5 
 kernel/drivers/thermal/intel/intel_soc_dts_iosf.c                                                         |    2 
 kernel/drivers/clk/imx/clk-imx8mp.c                                                                       |   52 
 kernel/drivers/mtd/maps/pxa2xx-flash.c                                                                    |    2 
 kernel/fs/dlm/lock.c                                                                                      |   53 
 kernel/drivers/md/bcache/btree.h                                                                          |    1 
 kernel/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c                                                   |   51 
 kernel/drivers/mmc/host/Kconfig                                                                           |    5 
 kernel/drivers/gpu/drm/amd/display/dmub/dmub_srv.h                                                        |    2 
 kernel/drivers/md/bcache/btree.c                                                                          |   25 
 kernel/drivers/tty/serial/8250/8250_em.c                                                                  |    4 
 kernel/scripts/tracing/ftrace-bisect.sh                                                                   |   34 
 kernel/drivers/gpu/drm/i915/gt/intel_ring.c                                                               |    6 
 kernel/net/netfilter/xt_sctp.c                                                                            |    2 
 kernel/drivers/net/usb/sr9700.c                                                                           |    2 
 kernel/include/linux/sensor-dev.h                                                                         |    2 
 kernel/block/blk-iocost.c                                                                                 |   28 
 kernel/android/abi_gki_aarch64_generic                                                                    |    9 
 kernel/arch/parisc/include/asm/ropes.h                                                                    |    3 
 kernel/drivers/bluetooth/btqcomsmd.c                                                                      |   17 
 kernel/arch/x86/kernel/apic/io_apic.c                                                                     |   14 
 kernel/fs/incfs/vfs.c                                                                                     |   48 
 kernel/net/netfilter/ipset/ip_set_hash_ipmark.c                                                           |   13 
 kernel/mm/compaction.c                                                                                    |   27 
 kernel/drivers/soc/ti/knav_qmss_queue.c                                                                   |    6 
 kernel/sound/pci/emu10k1/emufx.c                                                                          |  112 
 kernel/fs/eventpoll.c                                                                                     |    6 
 kernel/fs/squashfs/squashfs_fs_sb.h                                                                       |    2 
 kernel/scripts/mod/modpost.c                                                                              |   26 
 kernel/scripts/tags.sh                                                                                    |   20 
 kernel/drivers/mfd/rkx110_x120/Makefile                                                                   |    4 
 kernel/drivers/hwtracing/coresight/coresight-tmc.h                                                        |    2 
 kernel/drivers/crypto/hisilicon/sgl.c                                                                     |    3 
 kernel/arch/x86/kernel/x86_init.c                                                                         |    4 
 kernel/drivers/media/i2c/maxim4c/maxim4c_api.h                                                            |    5 
 kernel/drivers/net/wireguard/queueing.h                                                                   |   25 
 kernel/drivers/of/device.c                                                                                |    7 
 kernel/drivers/net/wireless/intel/iwlwifi/mvm/sta.c                                                       |    2 
 kernel/include/linux/usb/typec.h                                                                          |    8 
 kernel/sound/soc/codecs/es8316.c                                                                          |   42 
 kernel/drivers/acpi/acpica/dswstate.c                                                                     |   11 
 kernel/drivers/staging/rtl8712/ieee80211.c                                                                |   12 
 kernel/arch/arm64/boot/dts/rockchip/rk3568-evb.dtsi                                                       |    0 
 kernel/drivers/net/ethernet/toshiba/ps3_gelic_net.h                                                       |    5 
 kernel/net/batman-adv/bat_v_elp.c                                                                         |    3 
 kernel/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi                                                 |   10 
 kernel/drivers/net/wireguard/queueing.c                                                                   |    1 
 kernel/fs/nfs/filelayout/filelayout.c                                                                     |    8 
 kernel/drivers/net/ethernet/toshiba/ps3_gelic_net.c                                                       |   43 
 kernel/net/sched/act_ctinfo.c                                                                             |    6 
 kernel/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c                                        |    3 
 kernel/drivers/vhost/net.c                                                                                |    3 
 kernel/net/ceph/mon_client.c                                                                              |    6 
 kernel/net/netfilter/ipset/ip_set_hash_ipportip.c                                                         |   13 
 kernel/arch/powerpc/platforms/embedded6xx/flipper-pic.c                                                   |    2 
 kernel/arch/riscv/net/bpf_jit.h                                                                           |    5 
 kernel/fs/f2fs/checkpoint.c                                                                               |   12 
 kernel/drivers/gpu/drm/nouveau/dispnv50/disp.c                                                            |   48 
 kernel/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c                                                 |    2 
 kernel/drivers/clk/clk-cdce925.c                                                                          |   12 
 kernel/fs/nilfs2/btnode.c                                                                                 |   12 
 kernel/tools/testing/selftests/bpf/verifier/bounds_mix_sign_unsign.c                                      |  110 
 kernel/fs/overlayfs/copy_up.c                                                                             |    2 
 kernel/net/ipv4/udplite.c                                                                                 |   10 
 kernel/arch/powerpc/mm/book3s64/radix_pgtable.c                                                           |   44 
 kernel/drivers/nvme/target/core.c                                                                         |    4 
 kernel/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts                                                      |   13 
 kernel/sound/soc/meson/axg-spdifin.c                                                                      |   49 
 kernel/net/smc/af_smc.c                                                                                   |   13 
 kernel/drivers/net/vxlan/vxlan_core.c                                                                     |   81 
 kernel/tools/testing/selftests/lib.mk                                                                     |    5 
 kernel/arch/arm/boot/dts/bcm947189acdbmr.dts                                                              |    6 
 kernel/drivers/ata/libata-core.c                                                                          |   49 
 kernel/drivers/bus/sunxi-rsb.c                                                                            |    8 
 kernel/drivers/net/phy/phy_device.c                                                                       |   29 
 kernel/arch/arm/nwfpe/Makefile                                                                            |    6 
 kernel/arch/sh/kernel/cpu/sh2/probe.c                                                                     |    2 
 kernel/arch/um/Kconfig                                                                                    |    1 
 kernel/include/linux/irqdomain.h                                                                          |    4 
 kernel/include/linux/regulator/pca9450.h                                                                  |    4 
 kernel/kernel/relay.c                                                                                     |    7 
 kernel/drivers/infiniband/hw/hfi1/firmware.c                                                              |    6 
 kernel/fs/namei.c                                                                                         |  107 
 kernel/kernel/trace/kprobe_event_gen_test.c                                                               |    4 
 kernel/drivers/gpu/drm/msm/msm_ringbuffer.h                                                               |    7 
 kernel/drivers/gpu/drm/msm/msm_ringbuffer.c                                                               |    2 
 kernel/arch/alpha/kernel/setup.c                                                                          |    3 
 kernel/drivers/net/wireless/ath/ath9k/htc_drv_init.c                                                      |    2 
 kernel/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi                                                             |  210 
 kernel/drivers/mcb/mcb-parse.c                                                                            |    2 
 kernel/drivers/nvme/host/rdma.c                                                                           |    3 
 kernel/sound/soc/codecs/pcm512x.c                                                                         |    8 
 kernel/drivers/iio/light/max44009.c                                                                       |   13 
 kernel/include/linux/uaccess.h                                                                            |    4 
 kernel/drivers/mmc/host/bcm2835.c                                                                         |    4 
 kernel/arch/x86/purgatory/Makefile                                                                        |    8 
 kernel/drivers/misc/sgi-gru/grufault.c                                                                    |   13 
 kernel/drivers/net/wireless/ath/ath11k/dp_rx.c                                                            |   10 
 kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dtsi              |  122 
 kernel/drivers/bluetooth/btusb.c                                                                          |   15 
 mk-rootfs.sh                                                                                              |    4 
 kernel/drivers/devfreq/rockchip_dmc_common.c                                                              |    9 
 kernel/fs/erofs/zmap.c                                                                                    |   10 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96756-dphy0.dtsi                          |  199 
 kernel/arch/arm/boot/dts/sam9x60.dtsi                                                                     |    2 
 kernel/net/nsh/nsh.c                                                                                      |    8 
 kernel/drivers/mtd/ubi/eba.c                                                                              |   19 
 kernel/net/netfilter/nf_tables_core.c                                                                     |    2 
 kernel/drivers/acpi/pci_root.c                                                                            |    3 
 kernel/arch/x86/lib/iomap_copy_64.S                                                                       |    2 
 kernel/Documentation/virt/kvm/devices/vm.rst                                                              |    4 
 kernel/net/netfilter/xt_osf.c                                                                             |    1 
 kernel/drivers/gpu/drm/tegra/dc.c                                                                         |    4 
 kernel/crypto/drbg.c                                                                                      |   16 
 kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c                                                   |   71 
 kernel/lib/dim/rdma_dim.c                                                                                 |    3 
 kernel/arch/sh/kernel/idle.c                                                                              |    1 
 kernel/arch/x86/entry/entry_32.S                                                                          |    6 
 kernel/drivers/scsi/qla2xxx/qla_iocb.c                                                                    |   65 
 kernel/drivers/phy/rockchip/phy-rockchip-inno-usb2.c                                                      |    8 
 kernel/net/bridge/br_netfilter_hooks.c                                                                    |   16 
 kernel/drivers/mtd/spi-nor/gigadevice.c                                                                   |    3 
 kernel/drivers/rtc/rtc-rockchip.c                                                                         |   30 
 kernel/drivers/media/platform/rockchip/isp/isp_stats_v2x.c                                                |    2 
 kernel/drivers/bus/mhi/host/internal.h                                                                    |    0 
 kernel/fs/ubifs/file.c                                                                                    |   12 
 kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c                                              |    8 
 kernel/Documentation/driver-api/spi.rst                                                                   |    4 
 kernel/drivers/media/cec/i2c/Kconfig                                                                      |    1 
 kernel/fs/ext4/extents_status.c                                                                           |   33 
 kernel/net/smc/smc_llc.c                                                                                  |    4 
 kernel/arch/s390/kernel/perf_cpum_sf.c                                                                    |  101 
 kernel/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts                                               |    6 
 kernel/arch/x86/events/intel/uncore.h                                                                     |    1 
 kernel/sound/soc/fsl/fsl_asrc_dma.c                                                                       |   11 
 kernel/arch/um/configs/x86_64_defconfig                                                                   |    1 
 kernel/drivers/hid/wacom_wac.h                                                                            |    3 
 kernel/net/ncsi/ncsi-aen.c                                                                                |    6 
 kernel/android/abi_gki_aarch64_type_visibility                                                            |    2 
 kernel/drivers/hid/wacom_wac.c                                                                            |  125 
 kernel/drivers/mmc/host/usdhi6rol0.c                                                                      |    6 
 kernel/net/mpls/af_mpls.c                                                                                 |    4 
 kernel/block/partitions/amiga.c                                                                           |  104 
 kernel/net/sctp/diag.c                                                                                    |    4 
 kernel/drivers/usb/host/xhci-trace.h                                                                      |    4 
 kernel/drivers/net/wireless/ath/ath11k/mac.c                                                              |    2 
 kernel/kernel/Makefile                                                                                    |    2 
 kernel/drivers/net/xen-netback/common.h                                                                   |    2 
 kernel/drivers/iio/adc/mxs-lradc-adc.c                                                                    |   10 
 kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-lp3-v10.dtsi                                               |    8 
 kernel/mm/migrate.c                                                                                       |    7 
 kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c                                          |    5 
 kernel/drivers/media/platform/rcar_fdp1.c                                                                 |   50 
 kernel/net/netfilter/nft_immediate.c                                                                      |   99 
 kernel/drivers/tty/tty_jobctrl.c                                                                          |    1 
 kernel/samples/bpf/tracex6_kern.c                                                                         |   17 
 kernel/drivers/md/dm-clone-target.c                                                                       |    2 
 kernel/arch/arm/probes/kprobes/checkers-common.c                                                          |    2 
 kernel/drivers/clk/clk.c                                                                                  |   11 
 kernel/arch/arm/boot/dts/omap3-cpu-thermal.dtsi                                                           |    3 
 kernel/lib/kobject.c                                                                                      |    5 
 kernel/fs/cifs/file.c                                                                                     |    6 
 kernel/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c                                                      |   92 
 kernel/mm/memfd.c                                                                                         |    3 
 kernel/fs/ext2/super.c                                                                                    |   30 
 kernel/block/blk-cgroup.c                                                                                 |    5 
 kernel/drivers/nubus/proc.c                                                                               |   22 
 kernel/drivers/target/target_core_tmr.c                                                                   |  168 
 kernel/arch/riscv/kernel/signal.c                                                                         |    9 
 kernel/drivers/phy/tegra/xusb.c                                                                           |    6 
 kernel/arch/arm/boot/dts/rk3308-evb-audio-v10-display-rgb-aarch32.dts                                     |   17 
 kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10.dts                                                 |    2 
 kernel/net/packet/af_packet.c                                                                             |   74 
 kernel/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c                                                      |    4 
 kernel/drivers/acpi/arm64/iort.c                                                                          |    5 
 kernel/drivers/of/dynamic.c                                                                               |   31 
 kernel/fs/udf/super.c                                                                                     |    1 
 kernel/fs/squashfs/xattr.h                                                                                |    4 
 kernel/security/integrity/ima/ima_main.c                                                                  |    8 
 kernel/drivers/regulator/max77802-regulator.c                                                             |   34 
 kernel/arch/x86/include/asm/debugreg.h                                                                    |   26 
 kernel/drivers/net/wireless/intersil/orinoco/orinoco_cs.c                                                 |   13 
 kernel/drivers/gpu/drm/tegra/sor.c                                                                        |    2 
 kernel/drivers/iommu/amd/iommu_v2.c                                                                       |    1 
 kernel/drivers/net/can/rockchip/rockchip_canfd.c                                                          |   77 
 kernel/android/abi_gki_aarch64_xiaomi                                                                     |  142 
 kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds-linux.dts         |   23 
 kernel/drivers/fpga/stratix10-soc.c                                                                       |    4 
 kernel/net/ipv6/netfilter/nf_reject_ipv6.c                                                                |    5 
 kernel/arch/sh/Kconfig.debug                                                                              |    2 
 kernel/arch/xtensa/kernel/traps.c                                                                         |   18 
 kernel/drivers/net/wireless/marvell/mwifiex/tdls.c                                                        |    9 
 kernel/arch/arm64/include/asm/efi.h                                                                       |    6 
 kernel/drivers/gpu/drm/exynos/exynos5433_drm_decon.c                                                      |    4 
 kernel/include/linux/arm_sdei.h                                                                           |    4 
 kernel/lib/kstrtox.c                                                                                      |    5 
 kernel/arch/x86/kernel/ftrace.c                                                                           |    2 
 kernel/fs/f2fs/sysfs.c                                                                                    |   11 
 kernel/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c                                             |    5 
 kernel/arch/alpha/mm/fault.c                                                                              |    2 
 kernel/drivers/gpu/drm/vc4/vc4_plane.c                                                                    |    2 
 kernel/fs/nilfs2/page.c                                                                                   |   10 
 kernel/Documentation/admin-guide/cgroup-v1/memory.rst                                                     |   13 
 kernel/include/scsi/libsas.h                                                                              |   12 
 kernel/drivers/pci/controller/pcie-rockchip-ep.c                                                          |   65 
 kernel/drivers/block/drbd/drbd_main.c                                                                     |    4 
 kernel/lib/test_kmod.c                                                                                    |   26 
 kernel/tools/lib/bpf/libbpf.c                                                                             |    3 
 kernel/drivers/clk/rockchip/clk-pll.c                                                                     |    1 
 kernel/net/ipv4/ip_tunnel.c                                                                               |   12 
 kernel/drivers/media/dvb-frontends/s5h1432.c                                                              |    2 
 kernel/security/integrity/platform_certs/load_uefi.c                                                      |    1 
 kernel/drivers/gpio/gpio-davinci.c                                                                        |    2 
 kernel/include/linux/power/bq27xxx_battery.h                                                              |    4 
 kernel/arch/arm64/kernel/head.S                                                                           |    2 
 kernel/drivers/net/wireless/mediatek/mt76/mac80211.c                                                      |    8 
 kernel/arch/powerpc/platforms/pseries/papr_scm.c                                                          |    7 
 kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android.dts                                     |    2 
 kernel/drivers/gpu/drm/rockchip/rockchip_drm_gem.c                                                        |    3 
 kernel/include/uapi/linux/netfilter_bridge/ebtables.h                                                     |   14 
 kernel/drivers/base/firmware_loader/fallback.h                                                            |    4 
 kernel/sound/usb/caiaq/input.c                                                                            |    1 
 kernel/drivers/net/ethernet/qlogic/qed/qed_l2.c                                                           |    2 
 kernel/drivers/staging/ks7010/ks_wlan_net.c                                                               |    6 
 kernel/arch/um/configs/i386_defconfig                                                                     |    1 
 kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c                                                       |   14 
 kernel/net/caif/caif_socket.c                                                                             |    1 
 kernel/drivers/base/firmware_loader/fallback.c                                                            |   10 
 kernel/drivers/tty/serial/8250/8250_port.c                                                                |   20 
 kernel/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.c                                                    |    6 
 kernel/drivers/infiniband/core/cma_priv.h                                                                 |    1 
 kernel/include/net/netfilter/nf_tproxy.h                                                                  |    7 
 kernel/arch/um/include/asm/pgtable-3level.h                                                               |    2 
 kernel/drivers/base/regmap/regcache.c                                                                     |    6 
 kernel/drivers/video/fbdev/intelfb/intelfbdrv.c                                                           |    3 
 kernel/block/blk-mq-sysfs.c                                                                               |   11 
 kernel/drivers/net/ethernet/realtek/r8169_phy_config.c                                                    |    3 
 kernel/include/linux/hugetlb.h                                                                            |   24 
 kernel/drivers/base/class.c                                                                               |    5 
 kernel/include/linux/workqueue.h                                                                          |   15 
 kernel/drivers/mfd/dln2.c                                                                                 |    1 
 kernel/drivers/clk/clk-si5341.c                                                                           |  242 
 kernel/drivers/nvmem/qcom-spmi-sdam.c                                                                     |    1 
 kernel/sound/soc/intel/boards/bytcr_rt5640.c                                                              |   27 
 kernel/drivers/soc/qcom/qmi_encdec.c                                                                      |    4 
 kernel/drivers/iio/adc/ad_sigma_delta.c                                                                   |    8 
 kernel/drivers/bus/mhi/host/main.c                                                                        |    0 
 kernel/kernel/rcu/refscale.c                                                                              |    5 
 kernel/drivers/target/tcm_fc/tfc_cmd.c                                                                    |    2 
 kernel/net/netfilter/nfnetlink.c                                                                          |    5 
 kernel/sound/core/oss/pcm_plugin.h                                                                        |   16 
 kernel/drivers/video/backlight/pwm_bl.c                                                                   |    2 
 kernel/drivers/tty/Makefile                                                                               |    1 
 kernel/arch/s390/boot/ipl_report.c                                                                        |    8 
 kernel/include/net/ip.h                                                                                   |    3 
 kernel/include/net/net_namespace.h                                                                        |    2 
 kernel/net/ipv4/af_inet.c                                                                                 |    2 
 kernel/drivers/macintosh/windfarm_smu_sat.c                                                               |    1 
 kernel/drivers/gpu/drm/armada/armada_overlay.c                                                            |    6 
 kernel/drivers/gpu/drm/rockchip/rk3066_hdmi.c                                                             |    2 
 kernel/drivers/md/dm-cache-target.c                                                                       |   15 
 kernel/drivers/usb/dwc3/dwc3-meson-g12a.c                                                                 |   11 
 kernel/fs/ext4/namei.c                                                                                    |   90 
 kernel/include/linux/dmaengine.h                                                                          |    8 
 kernel/drivers/mfd/display-serdes/serdes-panel-split.c                                                    |  277 
 kernel/include/trace/events/ext4.h                                                                        |    7 
 kernel/drivers/mfd/Kconfig                                                                                |    8 
 kernel/include/linux/interrupt.h                                                                          |    4 
 kernel/drivers/base/firmware_loader/main.c                                                                |    9 
 kernel/drivers/net/ipvlan/ipvlan_l3s.c                                                                    |    5 
 kernel/drivers/media/i2c/maxim2c/maxim2c_remote.c                                                         |  434 
 kernel/arch/x86/kernel/cpu/scattered.c                                                                    |    4 
 kernel/tools/testing/selftests/net/fcnal-test.sh                                                          |   27 
 kernel/drivers/net/ethernet/xilinx/ll_temac_main.c                                                        |   16 
 kernel/drivers/tty/tty_buffer.c                                                                           |    2 
 kernel/sound/soc/sof/intel/hda-dai.c                                                                      |    8 
 kernel/drivers/hid/hid-logitech-hidpp.c                                                                   |   87 
 kernel/arch/nds32/kernel/fpu.c                                                                            |    2 
 kernel/scripts/recordmcount.c                                                                             |    6 
 kernel/arch/powerpc/platforms/powernv/pci-sriov.c                                                         |    6 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi                                                       |   10 
 kernel/fs/f2fs/compress.c                                                                                 |    6 
 kernel/drivers/ata/pata_ftide010.c                                                                        |    1 
 kernel/drivers/infiniband/hw/hns/hns_roce_qp.c                                                            |    2 
 kernel/fs/ext4/verity.c                                                                                   |    7 
 kernel/drivers/iommu/sun50i-iommu.c                                                                       |   16 
 kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c                                           |    2 
 kernel/arch/x86/include/asm/mem_encrypt.h                                                                 |    7 
 kernel/drivers/media/i2c/maxim2c/maxim2c_remote.h                                                         |   36 
 kernel/fs/gfs2/bmap.c                                                                                     |    3 
 kernel/fs/nfs/flexfilelayout/flexfilelayout.c                                                             |    1 
 kernel/drivers/media/tuners/mt2266.c                                                                      |    2 
 kernel/drivers/s390/scsi/zfcp_aux.c                                                                       |    9 
 kernel/arch/x86/kernel/cpu/topology.c                                                                     |    5 
 kernel/drivers/gpu/drm/arm/malidp_planes.c                                                                |    2 
 kernel/include/linux/mfd/rk806.h                                                                          |    4 
 kernel/net/nfc/hci/llc_shdlc.c                                                                            |   10 
 kernel/drivers/usb/gadget/function/f_uac2.c                                                               |    1 
 kernel/arch/arm64/boot/dts/rockchip/rk3399-tve1205g.dts                                                   |    2 
 kernel/drivers/iio/accel/adis16201.c                                                                      |    1 
 kernel/net/netfilter/nft_dynset.c                                                                         |   11 
 kernel/include/drm/drm_mipi_dsi.h                                                                         |    4 
 kernel/drivers/mtd/nand/raw/ingenic/ingenic_ecc.h                                                         |    8 
 kernel/fs/cifs/cifsglob.h                                                                                 |   69 
 kernel/drivers/gpu/drm/msm/adreno/a2xx_gpu.c                                                              |    8 
 kernel/drivers/hwmon/k10temp.c                                                                            |    4 
 kernel/arch/x86/Kconfig                                                                                   |   42 
 kernel/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c                                                         |   64 
 kernel/arch/mips/configs/mtx1_defconfig                                                                   |    2 
 kernel/net/netfilter/ipset/ip_set_core.c                                                                  |   23 
 kernel/net/batman-adv/translation-table.c                                                                 |    1 
 kernel/drivers/media/i2c/gc8034.c                                                                         |    2 
 kernel/drivers/media/dvb-frontends/isl6405.c                                                              |    2 
 kernel/fs/udf/udf_i.h                                                                                     |    3 
 kernel/arch/arm/boot/dts/rv1106g-evb2-v12-nofastae-emmc.dts                                               |    2 
 kernel/Documentation/admin-guide/kernel-parameters.txt                                                    |  109 
 kernel/block/blk-mq.c                                                                                     |    5 
 kernel/drivers/soc/rockchip/minidump/minidump_memory.c                                                    |    2 
 kernel/tools/perf/Makefile.config                                                                         |   51 
 kernel/tools/gpio/lsgpio.c                                                                                |    2 
 kernel/drivers/scsi/scsi_debug.c                                                                          |   11 
 kernel/net/sched/sch_htb.c                                                                                |    5 
 kernel/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c                                               |    4 
 kernel/drivers/media/dvb-frontends/tda10086.c                                                             |    2 
 kernel/drivers/media/dvb-frontends/lg2160.c                                                               |    2 
 kernel/drivers/usb/gadget/function/u_audio.c                                                              |    2 
 kernel/net/netfilter/ipset/ip_set_hash_netnet.c                                                           |   23 
 kernel/drivers/tty/vt/vc_screen.c                                                                         |   25 
 kernel/drivers/dma/at_xdmac.c                                                                             |   55 
 kernel/drivers/nvmem/core.c                                                                               |   18 
 kernel/arch/arm/boot/dts/s5pv210-aquila.dts                                                               |   12 
 kernel/drivers/media/tuners/tda18218.c                                                                    |    2 
 kernel/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c                                                  |    4 
 kernel/fs/jfs/namei.c                                                                                     |    5 
 kernel/fs/autofs/waitq.c                                                                                  |    3 
 kernel/drivers/gpu/drm/radeon/radeon_bios.c                                                               |   19 
 kernel/drivers/mfd/rkx110_x120/rkx120.c                                                                   |   30 
 kernel/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c                                          |    4 
 kernel/arch/arm/boot/dts/imx23.dtsi                                                                       |    2 
 kernel/drivers/mmc/host/mvsdio.c                                                                          |    2 
 kernel/net/core/dev.c                                                                                     |   21 
 kernel/drivers/infiniband/hw/bnxt_re/ib_verbs.c                                                           |   45 
 kernel/drivers/of/base.c                                                                                  |   27 
 kernel/arch/arm/kernel/hw_breakpoint.c                                                                    |    8 
 kernel/drivers/mtd/nand/raw/omap_elm.c                                                                    |   24 
 kernel/drivers/clk/x86/clk-cgu-pll.c                                                                      |   23 
 kernel/drivers/soc/rockchip/rockchip_opp_select.c                                                         |  228 
 kernel/net/sched/ematch.c                                                                                 |    2 
 kernel/arch/parisc/kernel/ptrace.c                                                                        |   15 
 kernel/drivers/hid/hid-debug.c                                                                            |    1 
 kernel/drivers/media/dvb-frontends/nxt6000.c                                                              |    2 
 kernel/drivers/power/supply/power_supply_core.c                                                           |   72 
 kernel/tools/perf/util/debug.c                                                                            |    4 
 kernel/arch/arm64/configs/px30_linux_defconfig                                                            |    9 
 kernel/drivers/media/dvb-frontends/stv0299.c                                                              |    2 
 kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb.h                                                        |   30 
 kernel/drivers/scsi/libsas/sas_expander.c                                                                 |    2 
 kernel/include/linux/icm4260x.h                                                                           |  432 
 kernel/drivers/mfd/rk806-spi.c                                                                            |   10 
 kernel/kernel/kprobes.c                                                                                   |   20 
 kernel/scripts/mod/file2alias.c                                                                           |    2 
 kernel/drivers/media/platform/rockchip/isp/capture_v20.c                                                  |    6 
 kernel/net/ipv6/ip6_gre.c                                                                                 |   20 
 kernel/drivers/media/dvb-frontends/si21xx.c                                                               |    2 
 kernel/scripts/gdb/linux/genpd.py                                                                         |    4 
 kernel/drivers/i2c/busses/i2c-npcm7xx.c                                                                   |   17 
 kernel/include/trace/events/f2fs.h                                                                        |    2 
 kernel/arch/x86/boot/bioscall.S                                                                           |    4 
 kernel/drivers/iio/dac/mcp4725.c                                                                          |   16 
 kernel/net/sched/act_mpls.c                                                                               |   10 
 kernel/drivers/s390/cio/qdio.h                                                                            |   25 
 kernel/fs/f2fs/gc.c                                                                                       |  140 
 kernel/sound/soc/meson/axg-tdm-formatter.c                                                                |   42 
 kernel/block/bio-integrity.c                                                                              |    1 
 kernel/drivers/spi/spi-bcm63xx-hsspi.c                                                                    |   19 
 kernel/arch/arm/boot/dts/rv1106g-evb2-v11-trailcam-emmc.dts                                               |    2 
 kernel/drivers/w1/w1.c                                                                                    |   10 
 kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c                                        |   35 
 kernel/arch/arm/boot/dts/s5pv210-smdkv210.dts                                                             |   30 
 kernel/net/ipv4/ip_output.c                                                                               |   18 
 kernel/drivers/media/dvb-frontends/mt352.c                                                                |    2 
 kernel/drivers/net/ethernet/sfc/efx_common.c                                                              |   12 
 kernel/drivers/scsi/lpfc/lpfc_debugfs.c                                                                   |   17 
 kernel/drivers/tty/serial/cpm_uart/cpm_uart_core.c                                                        |   13 
 kernel/drivers/media/pci/cx23885/cx23885-video.c                                                          |    2 
 kernel/drivers/hid/hid-multitouch.c                                                                       |   17 
 kernel/net/ipv4/route.c                                                                                   |    5 
 kernel/drivers/spi/spi-bcm-qspi.c                                                                         |   10 
 kernel/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c                                                |    2 
 kernel/drivers/net/ethernet/sfc/efx_common.h                                                              |    6 
 kernel/drivers/hwtracing/coresight/coresight-etm4x-core.c                                                 |   24 
 kernel/virt/kvm/coalesced_mmio.c                                                                          |    8 
 kernel/arch/powerpc/platforms/embedded6xx/hlwd-pic.c                                                      |    2 
 kernel/drivers/video/fbdev/matrox/matroxfb_base.c                                                         |    4 
 kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c                                                  |    1 
 kernel/include/scsi/scsi_transport_iscsi.h                                                                |    9 
 kernel/arch/s390/boot/compressed/decompressor.c                                                           |    2 
 kernel/drivers/usb/host/ehci-fsl.c                                                                        |    2 
 kernel/arch/x86/xen/spinlock.c                                                                            |    6 
 kernel/arch/mips/configs/decstation_r4k_defconfig                                                         |    2 
 kernel/drivers/bus/mhi/host/boot.c                                                                        |    0 
 kernel/drivers/scsi/libsas/sas_task.c                                                                     |    4 
 kernel/net/nfc/nfc.h                                                                                      |    3 
 kernel/include/soc/rockchip/rockchip_opp_select.h                                                         |   15 
 kernel/arch/powerpc/mm/pgtable_64.c                                                                       |    4 
 kernel/drivers/media/platform/rockchip/isp/capture_v21.c                                                  |   19 
 kernel/drivers/infiniband/hw/hns/hns_roce_cmd.h                                                           |    4 
 kernel/drivers/iio/light/cm32181.c                                                                        |   12 
 kernel/tools/bootconfig/test-bootconfig.sh                                                                |   12 
 kernel/drivers/infiniband/hw/hns/hns_roce_cmd.c                                                           |   27 
 kernel/security/integrity/digsig.c                                                                        |    6 
 kernel/drivers/mmc/host/omap_hsmmc.c                                                                      |   10 
 kernel/drivers/media/rc/imon.c                                                                            |    6 
 kernel/fs/fuse/inode.c                                                                                    |    5 
 kernel/sound/soc/intel/boards/sof_sdw.c                                                                   |   48 
 kernel/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts                                                     |    2 
 kernel/net/dccp/output.c                                                                                  |    2 
 kernel/arch/arm/boot/dts/omap5-cm-t54.dts                                                                 |   58 
 kernel/drivers/platform/x86/dell-wmi.c                                                                    |    3 
 kernel/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi                                                 |  207 
 kernel/drivers/media/i2c/sc530ai.c                                                                        |   90 
 kernel/drivers/media/tuners/mc44s803.c                                                                    |    2 
 kernel/drivers/pci/hotplug/pciehp_ctrl.c                                                                  |    8 
 kernel/drivers/iio/adc/stm32-dfsdm-adc.c                                                                  |    1 
 kernel/drivers/media/usb/ttusb-dec/ttusb_dec.c                                                            |    3 
 kernel/drivers/net/ethernet/intel/iavf/iavf_txrx.c                                                        |    2 
 kernel/drivers/input/touchscreen/gt9xx/gt9xx_firmware.h                                                   |    4 
 kernel/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c                                     |  171 
 kernel/net/netfilter/nft_byteorder.c                                                                      |   14 
 kernel/drivers/clk/keystone/pll.c                                                                         |    2 
 kernel/include/trace/events/jbd2.h                                                                        |   44 
 kernel/tools/testing/selftests/net/forwarding/ethtool_extended_state.sh                                   |    2 
 kernel/drivers/cpuidle/cpuidle-pseries.c                                                                  |    8 
 kernel/arch/arm64/boot/dts/mediatek/mt6797.dtsi                                                           |    2 
 kernel/arch/powerpc/platforms/pseries/setup.c                                                             |    2 
 kernel/drivers/media/usb/dvb-usb-v2/az6007.c                                                              |   11 
 kernel/kernel/fail_function.c                                                                             |    5 
 kernel/fs/libfs.c                                                                                         |   22 
 kernel/drivers/usb/host/xhci-mtk.c                                                                        |    1 
 kernel/net/netfilter/nft_flow_offload.c                                                                   |    8 
 kernel/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c                                                          |   40 
 kernel/tools/perf/util/auxtrace.c                                                                         |    7 
 kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c                                                             |   24 
 kernel/drivers/iio/adc/meson_saradc.c                                                                     |    2 
 kernel/drivers/net/phy/mscc/mscc_main.c                                                                   |   55 
 kernel/drivers/gpu/drm/amd/display/dc/core/dc_resource.c                                                  |    3 
 kernel/fs/jffs2/xattr.h                                                                                   |    4 
 kernel/arch/m68k/68000/entry.S                                                                            |    2 
 kernel/fs/jffs2/xattr.c                                                                                   |   13 
 kernel/fs/ext4/indirect.c                                                                                 |   19 
 kernel/drivers/media/platform/rockchip/isp/isp_params_v21.c                                               |   63 
 kernel/lib/radix-tree.c                                                                                   |    1 
 kernel/drivers/net/ethernet/intel/iavf/iavf_register.h                                                    |    2 
 kernel/android/abi_gki_aarch64_unisoc                                                                     |    3 
 kernel/arch/arm64/lib/csum.c                                                                              |    2 
 kernel/arch/m68k/kernel/traps.c                                                                           |    6 
 kernel/drivers/media/i2c/sc5336.c                                                                         |   22 
 kernel/net/rds/tcp_connect.c                                                                              |    2 
 kernel/sound/soc/codecs/wm8904.c                                                                          |   10 
 kernel/drivers/scsi/be2iscsi/be_iscsi.c                                                                   |    4 
 kernel/sound/soc/codecs/rt298.c                                                                           |    7 
 kernel/drivers/regulator/s5m8767.c                                                                        |    6 
 kernel/kernel/cpu.c                                                                                       |    9 
 kernel/drivers/media/platform/rockchip/isp/isp_rockit.c                                                   |   69 
 kernel/drivers/block/null_blk/main.c                                                                      |   11 
 kernel/include/linux/usb.h                                                                                |    8 
 kernel/drivers/mfd/rkx110_x120/rkx110_combrxphy.c                                                         |   76 
 kernel/include/net/bonding.h                                                                              |   26 
 kernel/net/netfilter/nf_conntrack_proto_dccp.c                                                            |   52 
 kernel/drivers/media/dvb-frontends/lgdt330x.c                                                             |    2 
 kernel/Documentation/ABI/testing/sysfs-fs-f2fs                                                            |   17 
 kernel/drivers/media/dvb-frontends/or51211.c                                                              |    2 
 kernel/arch/s390/kernel/signal.c                                                                          |    2 
 kernel/drivers/ntb/hw/intel/ntb_hw_gen1.c                                                                 |    7 
 kernel/drivers/nvme/target/fcloop.c                                                                       |   48 
 kernel/block/blk-merge.c                                                                                  |    2 
 kernel/drivers/infiniband/hw/bnxt_re/main.c                                                               |   20 
 kernel/drivers/media/usb/uvc/uvcvideo.h                                                                   |    6 
 kernel/drivers/pinctrl/pinconf-generic.c                                                                  |    4 
 kernel/drivers/net/ethernet/qualcomm/qca_spi.c                                                            |    3 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22.dts                                            |  152 
 kernel/drivers/rknpu/include/rknpu_ioctl.h                                                                |    4 
 kernel/include/uapi/linux/netlink.h                                                                       |    2 
 kernel/drivers/rtc/rtc-mxc_v2.c                                                                           |    4 
 kernel/arch/sparc/kernel/traps_64.c                                                                       |    4 
 kernel/include/linux/mtd/spinand.h                                                                        |    1 
 kernel/drivers/thunderbolt/tunnel.c                                                                       |    2 
 kernel/fs/dlm/recover.c                                                                                   |   39 
 kernel/drivers/gpu/drm/etnaviv/etnaviv_gpu.c                                                              |   11 
 kernel/drivers/mmc/host/meson-gx-mmc.c                                                                    |   66 
 kernel/drivers/staging/media/atomisp/Kconfig                                                              |    1 
 kernel/crypto/lrw.c                                                                                       |    6 
 kernel/arch/riscv/net/bpf_jit_core.c                                                                      |   29 
 kernel/fs/f2fs/extent_cache.c                                                                             |   54 
 kernel/net/core/netpoll.c                                                                                 |   19 
 kernel/arch/arm64/include/asm/kvm_host.h                                                                  |    1 
 kernel/net/xfrm/xfrm_interface_core.c                                                                     |   58 
 kernel/net/ethtool/ioctl.c                                                                                |    6 
 kernel/block/bfq-cgroup.c                                                                                 |    8 
 kernel/drivers/media/dvb-frontends/drxd_hard.c                                                            |    2 
 kernel/sound/core/seq/oss/seq_oss_midi.c                                                                  |   35 
 kernel/net/tipc/node.c                                                                                    |   14 
 kernel/drivers/media/dvb-frontends/isl6421.c                                                              |    2 
 kernel/drivers/video/rockchip/mpp/mpp_iommu.c                                                             |    6 
 kernel/drivers/android/vendor_hooks.c                                                                     |   28 
 kernel/drivers/clk/rockchip/clk-rk3562.c                                                                  |    8 
 kernel/drivers/dma/tegra210-adma.c                                                                        |    2 
 kernel/fs/eventfd.c                                                                                       |    7 
 kernel/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts                                             |    2 
 kernel/drivers/video/rockchip/vtunnel/Kconfig                                                             |   12 
 kernel/drivers/mailbox/mailbox-test.c                                                                     |   13 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c                                                 |    6 
 kernel/drivers/media/usb/dvb-usb-v2/gl861.c                                                               |    2 
 kernel/drivers/net/ethernet/intel/iavf/iavf_main.c                                                        |   20 
 kernel/fs/ubifs/tnc.c                                                                                     |  152 
 kernel/include/linux/cgroup.h                                                                             |    3 
 kernel/arch/powerpc/include/asm/paca.h                                                                    |    7 
 kernel/arch/x86/include/asm/boot.h                                                                        |   47 
 kernel/arch/arm/mach-imx/cpu-imx35.c                                                                      |    1 
 kernel/arch/powerpc/include/asm/topology.h                                                                |    6 
 kernel/arch/arm64/kernel/debug-monitors.c                                                                 |    5 
 kernel/drivers/video/rockchip/rga3/rga_drv.c                                                              |    7 
 kernel/fs/btrfs/inode.c                                                                                   |   12 
 kernel/include/linux/sched/task_stack.h                                                                   |    2 
 kernel/drivers/media/tuners/fc0012.c                                                                      |    2 
 kernel/fs/verity/signature.c                                                                              |   16 
 kernel/drivers/iommu/intel/pasid.c                                                                        |   28 
 kernel/net/sched/act_nat.c                                                                                |    2 
 kernel/drivers/net/wireless/ath/ath9k/wmi.c                                                               |   25 
 kernel/arch/ia64/kernel/traps.c                                                                           |    2 
 kernel/drivers/hid/wacom.h                                                                                |    4 
 kernel/drivers/scsi/qla2xxx/qla_bsg.c                                                                     |    6 
 kernel/mm/vmscan.c                                                                                        |   13 
 kernel/arch/arm/boot/dts/motorola-mapphone-common.dtsi                                                    |   33 
 kernel/arch/riscv/kernel/ftrace.c                                                                         |   14 
 kernel/drivers/soc/fsl/qe/Kconfig                                                                         |    1 
 kernel/drivers/video/rockchip/Kconfig                                                                     |    2 
 kernel/include/soc/rockchip/pm_domains.h                                                                  |    8 
 kernel/drivers/usb/chipidea/otg.c                                                                         |    5 
 kernel/drivers/mmc/host/sdhci-acpi.c                                                                      |    2 
 kernel/sound/pci/asihpi/hpi6205.c                                                                         |    2 
 kernel/tools/testing/selftests/kselftest_harness.h                                                        |   11 
 kernel/arch/arm/configs/rv1106-wakeup.config                                                              |   14 
 kernel/arch/sh/include/asm/processor_32.h                                                                 |    1 
 kernel/drivers/media/dvb-frontends/m88ds3103.c                                                            |    2 
 kernel/drivers/media/i2c/techpoint/techpoint_v4l2.c                                                       |    2 
 kernel/drivers/net/hamradio/scc.c                                                                         |    6 
 kernel/arch/arm/boot/dts/rv1106g-evb2-v11-emmc.dts                                                        |    2 
 kernel/arch/arm64/include/asm/sdei.h                                                                      |    6 
 kernel/drivers/input/touchscreen/Kconfig                                                                  |    9 
 kernel/drivers/i2c/muxes/i2c-demux-pinctrl.c                                                              |    4 
 kernel/arch/mips/Kconfig                                                                                  |    1 
 kernel/arch/x86/mm/mem_encrypt_identity.c                                                                 |    3 
 kernel/security/apparmor/policy.c                                                                         |    2 
 kernel/drivers/tty/serial/sprd_serial.c                                                                   |   30 
 kernel/arch/x86/entry/entry_64.S                                                                          |    6 
 kernel/drivers/misc/mei/hw-me-regs.h                                                                      |    2 
 kernel/arch/um/Makefile                                                                                   |    2 
 kernel/net/l2tp/l2tp_core.c                                                                               |  116 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy3.dtsi                          |   46 
 kernel/arch/x86/boot/boot.h                                                                               |   36 
 kernel/arch/mips/kernel/vpe-mt.c                                                                          |   11 
 kernel/drivers/iio/accel/adis16209.c                                                                      |    1 
 kernel/arch/arm64/kernel/traps.c                                                                          |    2 
 kernel/drivers/gpu/drm/amd/amdgpu/cik.c                                                                   |   36 
 kernel/include/linux/random.h                                                                             |    6 
 kernel/include/linux/mhi.h                                                                                |    2 
 kernel/drivers/char/tpm/tpm_crb.c                                                                         |   31 
 kernel/drivers/hv/channel_mgmt.c                                                                          |   18 
 kernel/drivers/net/ethernet/freescale/enetc/enetc_qos.c                                                   |    6 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-linux.dtsi                                                     |   31 
 kernel/include/net/sch_generic.h                                                                          |    6 
 kernel/drivers/staging/media/tegra-video/csi.h                                                            |    2 
 kernel/sound/soc/rockchip/Makefile                                                                        |    4 
 kernel/drivers/ata/sata_gemini.c                                                                          |    1 
 kernel/drivers/media/platform/rockchip/cif/cif-scale.c                                                    |    2 
 kernel/drivers/staging/media/tegra-video/csi.c                                                            |    4 
 kernel/arch/sh/kernel/setup.c                                                                             |   59 
 kernel/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi                                                         |    4 
 kernel/android/abi_gki_aarch64_moto                                                                       |    6 
 kernel/net/ipv6/exthdrs_core.c                                                                            |    2 
 kernel/lib/lockref.c                                                                                      |    1 
 kernel/fs/fuse/readdir.c                                                                                  |   10 
 kernel/drivers/media/platform/qcom/venus/helpers.c                                                        |   10 
 kernel/arch/arm/boot/dts/imx7d.dtsi                                                                       |    6 
 kernel/drivers/hid/hid-cp2112.c                                                                           |    1 
 kernel/drivers/vhost/vsock.c                                                                              |    9 
 kernel/drivers/watchdog/iTCO_wdt.c                                                                        |   26 
 kernel/drivers/power/supply/ab8500_btemp.c                                                                |    6 
 kernel/fs/ocfs2/xattr.c                                                                                   |   30 
 kernel/drivers/net/ethernet/intel/ice/ice_fltr.c                                                          |    2 
 kernel/arch/powerpc/sysdev/tsi108_pci.c                                                                   |    5 
 kernel/net/xfrm/xfrm_policy.c                                                                             |   24 
 kernel/lib/ts_bm.c                                                                                        |    4 
 kernel/arch/arm/boot/dts/rv1106g-evb1-v11-cvr-dual-cam.dts                                                |    2 
 kernel/fs/btrfs/extent_io.c                                                                               |   15 
 kernel/mm/util.c                                                                                          |    7 
 kernel/net/wireless/sme.c                                                                                 |   29 
 kernel/sound/soc/rockchip/rockchip_dlp_pcm.h                                                              |   28 
 kernel/arch/parisc/include/uapi/asm/mman.h                                                                |   27 
 kernel/tools/testing/selftests/kselftest/runner.sh                                                        |   29 
 kernel/include/linux/nospec.h                                                                             |    4 
 kernel/drivers/gpio/gpiolib.c                                                                             |   12 
 kernel/fs/ext4/acl.c                                                                                      |    2 
 kernel/arch/arm64/boot/dts/rockchip/rk1808.dtsi                                                           |   22 
 kernel/net/nfc/llcp.h                                                                                     |    9 
 kernel/include/net/lwtunnel.h                                                                             |    5 
 kernel/drivers/usb/core/quirks.c                                                                          |    7 
 kernel/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst                                         |  109 
 kernel/sound/soc/codecs/cs42l51-i2c.c                                                                     |    6 
 kernel/drivers/net/ethernet/mscc/ocelot_flower.c                                                          |   24 
 kernel/arch/x86/kernel/crash.c                                                                            |   17 
 kernel/drivers/media/platform/rockchip/isp/isp_external.h                                                 |   10 
 kernel/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c                                                  |    2 
 kernel/drivers/video/rockchip/rga3/include/rga_common.h                                                   |    1 
 kernel/sound/soc/rockchip/rockchip_dlp_pcm.c                                                              |  516 
 kernel/drivers/spi/Makefile                                                                               |    1 
 kernel/fs/ext2/xattr.c                                                                                    |    4 
 kernel/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi                                                        |   20 
 kernel/drivers/rpmsg/Kconfig                                                                              |   17 
 kernel/drivers/clk/rockchip/regmap/clk-regmap-fractional-divider.c                                        |   10 
 kernel/drivers/net/usb/usbnet.c                                                                           |    6 
 kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h                                        |   12 
 kernel/drivers/net/phy/dp83822.c                                                                          |    6 
 kernel/drivers/scsi/device_handler/scsi_dh_alua.c                                                         |    6 
 kernel/drivers/soc/rockchip/rockchip-cpuinfo.c                                                            |    9 
 kernel/drivers/pwm/pwm-tegra.c                                                                            |    4 
 kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c                                        |   19 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c                                                  |  105 
 kernel/drivers/scsi/fcoe/fcoe_ctlr.c                                                                      |   20 
 kernel/arch/arm/boot/dts/rk3288-evb-android-rk808-edp.dtsi                                                |    2 
 kernel/arch/csky/kernel/traps.c                                                                           |    2 
 kernel/drivers/net/ethernet/sun/ldmvsw.c                                                                  |    3 
 kernel/drivers/nvme/target/fc.c                                                                           |    4 
 kernel/drivers/media/pci/bt8xx/dst_ca.c                                                                   |    2 
 kernel/drivers/media/usb/dvb-usb/af9005.c                                                                 |    5 
 kernel/include/soc/rockchip/rockchip-system-status.h                                                      |    2 
 kernel/net/can/isotp.c                                                                                    |   24 
 kernel/arch/powerpc/configs/ppc6xx_defconfig                                                              |    2 
 kernel/drivers/staging/rtl8192e/rtl8192e/rtl_core.c                                                       |    1 
 kernel/include/linux/kexec.h                                                                              |    2 
 kernel/arch/arm/boot/dts/qcom-ipq4019.dtsi                                                                |    4 
 kernel/fs/incfs/verity.c                                                                                  |    2 
 kernel/drivers/net/mdio/mdio-mux-meson-g12a.c                                                             |   23 
 kernel/drivers/pci/hotplug/pciehp_pci.c                                                                   |   15 
 kernel/net/sched/cls_flower.c                                                                             |   13 
 kernel/drivers/media/dvb-frontends/dib7000p.c                                                             |    4 
 kernel/io_uring/io-wq.c                                                                                   |   18 
 kernel/drivers/gpu/drm/msm/msm_gem_submit.c                                                               |    5 
 kernel/drivers/scsi/megaraid/megaraid_sas.h                                                               |    4 
 kernel/fs/aio.c                                                                                           |    4 
 kernel/include/linux/ceph/msgr.h                                                                          |    9 
 kernel/drivers/acpi/acpica/nsrepair.c                                                                     |   12 
 kernel/io_uring/io-wq.h                                                                                   |    1 
 kernel/drivers/media/platform/rockchip/cif/hw.c                                                           |   44 
 kernel/arch/x86/kernel/sysfb_efi.c                                                                        |   16 
 kernel/drivers/scsi/qedf/qedf_main.c                                                                      |   28 
 kernel/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc                                  |    2 
 kernel/drivers/net/wireless/microchip/wilc1000/sdio.c                                                     |    1 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c                                                |    3 
 kernel/kernel/irq/irqdomain.c                                                                             |  289 
 kernel/drivers/gpio/gpio-tb10x.c                                                                          |    6 
 kernel/drivers/net/ethernet/intel/e1000e/netdev.c                                                         |   51 
 kernel/kernel/locking/rwsem.c                                                                             |   15 
 kernel/drivers/clk/st/clkgen-fsyn.c                                                                       |    5 
 kernel/mm/page_alloc.c                                                                                    |   51 
 kernel/arch/arm/kernel/module-plts.c                                                                      |    2 
 kernel/drivers/gpio/gpio-pmic-eic-sprd.c                                                                  |    1 
 kernel/drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2_tlv_multi.c                                         |    2 
 kernel/drivers/mmc/host/alcor.c                                                                           |    5 
 kernel/arch/arm64/kernel/entry.S                                                                          |   31 
 kernel/include/net/scm.h                                                                                  |   13 
 kernel/security/integrity/ima/ima_policy.c                                                                |   56 
 kernel/arch/arm/mach-rockchip/rockchip_hptimer.h                                                          |   22 
 kernel/drivers/clk/socfpga/clk-periph.c                                                                   |    8 
 kernel/drivers/media/dvb-frontends/stb6100.c                                                              |    2 
 kernel/arch/arm/mach-rockchip/rockchip_hptimer.c                                                          |  221 
 kernel/include/linux/pci.h                                                                                |    1 
 kernel/drivers/net/ethernet/google/gve/gve_ethtool.c                                                      |    8 
 kernel/arch/arm64/boot/dts/qcom/sdm630.dtsi                                                               |    2 
 kernel/net/netfilter/nf_tables_offload.c                                                                  |   30 
 kernel/include/linux/if_arp.h                                                                             |    4 
 kernel/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c                                                    |    5 
 kernel/drivers/pwm/pwm-lpc32xx.c                                                                          |   16 
 kernel/drivers/mfd/display-serdes/maxim/maxim-max96772.h                                                  |   24 
 kernel/arch/riscv/include/asm/ftrace.h                                                                    |    2 
 kernel/drivers/infiniband/hw/hfi1/file_ops.c                                                              |    7 
 kernel/drivers/irqchip/irq-xilinx-intc.c                                                                  |    2 
 kernel/drivers/mfd/display-serdes/maxim/maxim-max96772.c                                                  |  642 
 kernel/drivers/usb/core/buffer.c                                                                          |   41 
 kernel/fs/nilfs2/gcinode.c                                                                                |    6 
 kernel/drivers/tty/serial/sifive.c                                                                        |    2 
 kernel/drivers/gpu/drm/omapdrm/dss/dsi.c                                                                  |   26 
 kernel/fs/overlayfs/file.c                                                                                |   37 
 kernel/include/linux/mbcache.h                                                                            |   41 
 kernel/drivers/usb/core/message.c                                                                         |   29 
 kernel/net/sctp/stream_sched_prio.c                                                                       |   52 
 kernel/arch/x86/include/asm/resctrl.h                                                                     |   19 
 kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h                                                      |   13 
 kernel/drivers/media/dvb-frontends/tda8261.c                                                              |    2 
 kernel/drivers/gpu/drm/msm/Makefile                                                                       |    2 
 kernel/include/uapi/asm-generic/socket.h                                                                  |    2 
 kernel/tools/testing/selftests/rcutorture/bin/console-badness.sh                                          |    3 
 kernel/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi                                             |    2 
 kernel/drivers/infiniband/hw/efa/efa_verbs.c                                                              |    2 
 kernel/fs/hfsplus/inode.c                                                                                 |   36 
 kernel/drivers/media/usb/uvc/uvc_driver.c                                                                 |   66 
 kernel/arch/x86/mm/init.c                                                                                 |   32 
 kernel/drivers/video/fbdev/arcfb.c                                                                        |   15 
 kernel/drivers/scsi/scsi_lib.c                                                                            |    2 
 kernel/include/linux/sunrpc/sched.h                                                                       |    3 
 kernel/arch/x86/events/zhaoxin/core.c                                                                     |    8 
 kernel/drivers/gpu/drm/bridge/tc358764.c                                                                  |    2 
 kernel/drivers/soc/qcom/Kconfig                                                                           |    1 
 kernel/kernel/power/energy_model.c                                                                        |    5 
 kernel/drivers/usb/core/hcd.c                                                                             |   10 
 kernel/drivers/net/ethernet/marvell/mvneta.c                                                              |    4 
 kernel/drivers/hwmon/nct7802.c                                                                            |    2 
 kernel/fs/ext4/ext4.h                                                                                     |   44 
 kernel/fs/mbcache.c                                                                                       |  121 
 kernel/drivers/net/ethernet/intel/igb/igb.h                                                               |    4 
 kernel/android/abi_gki_aarch64_vivo                                                                       |   19 
 kernel/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c                                                        |   23 
 kernel/drivers/iio/light/vcnl4035.c                                                                       |    3 
 kernel/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c                                              |    3 
 kernel/Documentation/admin-guide/sysctl/net.rst                                                           |   15 
 kernel/fs/exfat/inode.c                                                                                   |    6 
 kernel/drivers/net/usb/rndis_host.c                                                                       |    3 
 kernel/sound/oss/dmasound/dmasound_core.c                                                                 |   26 
 kernel/include/net/sock.h                                                                                 |   54 
 kernel/arch/ia64/mm/contig.c                                                                              |    2 
 kernel/net/ipv4/tcp_metrics.c                                                                             |   70 
 kernel/fs/ocfs2/super.c                                                                                   |  114 
 kernel/drivers/net/wireless/realtek/rtlwifi/debug.c                                                       |   12 
 kernel/drivers/scsi/megaraid/megaraid_sas_fp.c                                                            |    2 
 kernel/arch/arm/boot/dts/imx51.dtsi                                                                       |    2 
 kernel/drivers/misc/ocxl/config.c                                                                         |   20 
 kernel/drivers/base/power/domain.c                                                                        |    6 
 kernel/drivers/gpu/drm/i915/gvt/handlers.c                                                                |   44 
 kernel/arch/powerpc/include/asm/book3s/64/pgtable.h                                                       |   11 
 kernel/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi                                                  |   10 
 kernel/drivers/i2c/busses/i2c-omap.c                                                                      |    2 
 kernel/init/Kconfig                                                                                       |   12 
 kernel/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi                                                        |   20 
 kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h                                                  |    1 
 kernel/kernel/irq/dummychip.c                                                                             |    2 
 kernel/arch/arm64/kvm/psci.c                                                                              |    2 
 kernel/arch/x86/kernel/fpu/xstate.c                                                                       |    8 
 kernel/arch/arm/boot/dts/armada-370.dtsi                                                                  |    2 
 kernel/Documentation/filesystems/autofs.rst                                                               |    2 
 kernel/drivers/md/bcache/writeback.c                                                                      |   10 
 kernel/drivers/media/platform/rockchip/cif/regs.h                                                         |    9 
 kernel/tools/testing/ktest/sample.conf                                                                    |    5 
 kernel/arch/arm64/boot/dts/rockchip/rk3308-evb-audio-amic-v10.dts                                         |   52 
 kernel/net/9p/trans_xen.c                                                                                 |   52 
 kernel/net/ipv6/icmp.c                                                                                    |    5 
 kernel/arch/m68k/Kconfig                                                                                  |    1 
 kernel/drivers/irqchip/irq-sun4i.c                                                                        |    2 
 kernel/drivers/media/platform/qcom/venus/hfi_venus_io.h                                                   |  110 
 kernel/drivers/media/dvb-frontends/or51132.c                                                              |    2 
 kernel/arch/arm64/kernel/efi.c                                                                            |    2 
 kernel/drivers/crypto/inside-secure/safexcel.c                                                            |   37 
 kernel/drivers/gpu/drm/exynos/exynos_drm_g2d.c                                                            |    2 
 kernel/drivers/infiniband/hw/hns/hns_roce_hw_v1.h                                                         |    7 
 kernel/drivers/media/dvb-frontends/s5h1420.c                                                              |    2 
 kernel/drivers/video/fbdev/core/fbcon.c                                                                   |    7 
 kernel/include/linux/rockchip/rockchip_pm_config.h                                                        |   32 
 kernel/security/integrity/ima/Kconfig                                                                     |   35 
 kernel/drivers/net/ethernet/intel/i40e/i40e_debugfs.c                                                     |    2 
 kernel/arch/x86/include/asm/msr-index.h                                                                   |   18 
 kernel/drivers/gpu/drm/exynos/exynos_drm_g2d.h                                                            |    4 
 kernel/drivers/net/wireguard/allowedips.c                                                                 |    8 
 kernel/drivers/rtc/rtc-rk630.c                                                                            |  637 
 kernel/drivers/infiniband/hw/hns/hns_roce_hw_v1.c                                                         |   93 
 kernel/drivers/net/wireless/ath/ath9k/htc_drv_debug.c                                                     |    2 
 kernel/net/ipv6/exthdrs.c                                                                                 |   29 
 kernel/sound/pci/hda/patch_ca0132.c                                                                       |    7 
 kernel/net/bluetooth/l2cap_core.c                                                                         |  212 
 kernel/drivers/gpu/drm/drm_connector.c                                                                    |    3 
 kernel/drivers/usb/core/devio.c                                                                           |   22 
 kernel/drivers/rtc/rtc-sun6i.c                                                                            |   16 
 kernel/net/caif/cfctrl.c                                                                                  |    6 
 kernel/arch/arm/boot/dts/rv1106g-evb1-v11-cvr-ext-dual-cam.dts                                            |  177 
 kernel/arch/powerpc/kernel/rtas.c                                                                         |   46 
 kernel/drivers/iio/adc/berlin2-adc.c                                                                      |    4 
 kernel/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts                                          |    1 
 kernel/drivers/mmc/host/omap.c                                                                            |    2 
 kernel/drivers/vfio/platform/vfio_platform_common.c                                                       |    3 
 kernel/fs/f2fs/inline.c                                                                                   |   28 
 kernel/net/netfilter/nft_objref.c                                                                         |   10 
 kernel/Documentation/ABI/testing/sysfs-fs-incfs                                                           |    6 
 kernel/drivers/scsi/mpt3sas/mpt3sas_transport.c                                                           |   16 
 kernel/fs/btrfs/inode-map.h                                                                               |    3 
 kernel/net/nfc/llcp_core.c                                                                                |   98 
 kernel/drivers/watchdog/sbsa_gwdt.c                                                                       |    1 
 kernel/drivers/gpu/drm/drm_client_modeset.c                                                               |    6 
 kernel/arch/s390/purgatory/Makefile                                                                       |    1 
 kernel/net/netfilter/ipset/ip_set_hash_ip.c                                                               |   14 
 kernel/drivers/nfc/pn533/usb.c                                                                            |   45 
 kernel/drivers/clk/socfpga/clk-pll.c                                                                      |   17 
 kernel/drivers/gpu/drm/ast/ast_post.c                                                                     |    2 
 kernel/drivers/gpu/drm/amd/amdgpu/si.c                                                                    |   36 
 kernel/arch/riscv/include/asm/uaccess.h                                                                   |    2 
 kernel/drivers/ata/libata-transport.c                                                                     |    9 
 kernel/drivers/clk/renesas/renesas-cpg-mssr.c                                                             |    8 
 kernel/arch/arm64/boot/dts/rockchip/rk3528-demo.dtsi                                                      |    2 
 kernel/drivers/net/ethernet/amazon/ena/ena_com.c                                                          |    3 
 kernel/drivers/rapidio/devices/rio_mport_cdev.c                                                           |   15 
 kernel/drivers/pci/controller/dwc/pcie-dw-dmatest.c                                                       |  162 
 kernel/drivers/media/platform/rcar-vin/rcar-dma.c                                                         |    4 
 kernel/arch/powerpc/platforms/pseries/hotplug-memory.c                                                    |    2 
 kernel/drivers/iio/imu/adis16460.c                                                                        |    5 
 kernel/drivers/pci/controller/dwc/pcie-dw-dmatest.h                                                       |   15 
 kernel/drivers/infiniband/hw/mlx4/sysfs.c                                                                 |    2 
 kernel/drivers/mtd/nand/raw/meson_nand.c                                                                  |   21 
 kernel/drivers/pinctrl/stm32/pinctrl-stm32.c                                                              |    1 
 kernel/crypto/asymmetric_keys/x509_public_key.c                                                           |    5 
 kernel/drivers/gpu/drm/i915/display/intel_dp.c                                                            |    5 
 kernel/drivers/input/touchscreen/elants_i2c.c                                                             |    9 
 kernel/tools/perf/util/llvm-utils.c                                                                       |   25 
 kernel/drivers/rknpu/Makefile                                                                             |    1 
 kernel/drivers/usb/gadget/udc/amd5536udc_pci.c                                                            |    3 
 kernel/fs/btrfs/inode-map.c                                                                               |   55 
 kernel/net/core/bpf_sk_storage.c                                                                          |    5 
 kernel/Documentation/devicetree/bindings/cpufreq/cpufreq-rockchip.txt                                     |   81 
 kernel/fs/btrfs/ioctl.c                                                                                   |   24 
 kernel/arch/arm64/kvm/arm.c                                                                               |   28 
 kernel/drivers/acpi/acpica/Makefile                                                                       |    2 
 kernel/drivers/i2c/busses/i2c-xiic.c                                                                      |   39 
 kernel/drivers/media/cec/usb/pulse8/pulse8-cec.c                                                          |    7 
 kernel/arch/arm/boot/dts/imx6qdl-prti6q.dtsi                                                              |   11 
 kernel/arch/sh/boards/mach-ap325rxa/setup.c                                                               |    2 
 kernel/drivers/tee/amdtee/amdtee_if.h                                                                     |   10 
 kernel/arch/sh/Kconfig                                                                                    |    1 
 kernel/drivers/pci/pcie/aspm.c                                                                            |  102 
 kernel/fs/udf/file.c                                                                                      |   26 
 kernel/arch/arm64/configs/rockchip_gki.config                                                             |    2 
 kernel/arch/arm/mach-imx/mmdc.c                                                                           |   24 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v20.dtsi                                           |   27 
 kernel/arch/arm64/boot/dts/rockchip/rk3308-evb-audio-v10-display-rgb.dts                                  |  162 
 kernel/fs/zonefs/super.c                                                                                  |   22 
 kernel/include/net/netfilter/ipv4/nf_reject.h                                                             |    4 
 kernel/drivers/counter/stm32-lptimer-cnt.c                                                                |    2 
 kernel/mm/memcontrol.c                                                                                    |    9 
 kernel/Documentation/admin-guide/sysctl/kernel.rst                                                        |   19 
 kernel/drivers/mmc/host/tmio_mmc_core.c                                                                   |    8 
 kernel/drivers/dma/imx-sdma.c                                                                             |    4 
 kernel/drivers/media/usb/uvc/uvc_status.c                                                                 |   40 
 kernel/arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts                                                       |    1 
 kernel/fs/nilfs2/inode.c                                                                                  |   33 
 kernel/lib/notifier-error-inject.c                                                                        |    2 
 kernel/net/nfc/netlink.c                                                                                  |   76 
 kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c                                                    |    2 
 kernel/arch/sh/include/asm/processor.h                                                                    |    2 
 kernel/drivers/net/phy/rk630phy.c                                                                         |    6 
 kernel/drivers/ata/libata-scsi.c                                                                          |   36 
 kernel/drivers/media/platform/rockchip/isp/isp_params_v3x.c                                               |   41 
 kernel/arch/arm/boot/dts/imx31.dtsi                                                                       |    2 
 kernel/sound/soc/rockchip/rockchip_multicodecs.c                                                          |   49 
 kernel/arch/s390/kvm/interrupt.c                                                                          |   12 
 kernel/net/sched/sch_plug.c                                                                               |    2 
 kernel/net/netlabel/netlabel_kapi.c                                                                       |    3 
 kernel/drivers/power/supply/rk818_battery.c                                                               |    7 
 kernel/arch/parisc/kernel/drivers.c                                                                       |    2 
 kernel/arch/alpha/include/asm/pgtable.h                                                                   |    8 
 kernel/fs/btrfs/backref.c                                                                                 |    4 
 kernel/drivers/video/rockchip/mpp/mpp_common.h                                                            |   57 
 kernel/fs/overlayfs/export.c                                                                              |    3 
 kernel/drivers/net/wireless/ath/wil6210/txrx.h                                                            |    6 
 kernel/net/dccp/ipv4.c                                                                                    |   12 
 kernel/drivers/video/rockchip/mpp/mpp_common.c                                                            |   14 
 kernel/net/netrom/nr_timer.c                                                                              |    1 
 kernel/arch/arm64/configs/rockchip_defconfig                                                              |   12 
 kernel/drivers/mmc/core/quirks.h                                                                          |   14 
 kernel/drivers/thermal/hisi_thermal.c                                                                     |    4 
 kernel/drivers/staging/media/rkvdec/rkvdec.c                                                              |    4 
 kernel/arch/mips/alchemy/devboards/db1200.c                                                               |   25 
 kernel/drivers/bus/mhi/host/pm.c                                                                          |    8 
 kernel/drivers/media/usb/uvc/uvc_entity.c                                                                 |    2 
 kernel/drivers/net/ethernet/intel/igbvf/netdev.c                                                          |    8 
 kernel/drivers/clk/ti/clkctrl.c                                                                           |    7 
 kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-lp4-linux.dts                               |    2 
 kernel/drivers/net/wireless/cisco/airo.c                                                                  |    5 
 kernel/arch/x86/include/asm/pgtable_types.h                                                               |   11 
 kernel/drivers/video/fbdev/core/modedb.c                                                                  |    5 
 kernel/drivers/usb/host/xhci-debugfs.c                                                                    |    1 
 kernel/drivers/pinctrl/pinctrl-rockchip.c                                                                 |    9 
 kernel/net/nfc/core.c                                                                                     |    4 
 kernel/drivers/scsi/iscsi_tcp.c                                                                           |   12 
 kernel/net/nfc/llcp_commands.c                                                                            |   59 
 kernel/drivers/staging/emxx_udc/emxx_udc.c                                                                |    7 
 kernel/arch/arm64/mm/proc.S                                                                               |   54 
 kernel/drivers/net/wireless/atmel/atmel_cs.c                                                              |   13 
 kernel/Documentation/admin-guide/hw-vuln/index.rst                                                        |    2 
 kernel/drivers/net/wireless/ath/wil6210/txrx.c                                                            |    2 
 kernel/drivers/power/supply/sc27xx_fuel_gauge.c                                                           |    9 
 kernel/fs/nilfs2/segment.c                                                                                |   42 
 kernel/arch/arm64/boot/dts/qcom/msm8994.dtsi                                                              |    2 
 kernel/arch/arm/boot/dts/rv1103g-evb2-v10.dts                                                             |  304 
 kernel/arch/arm64/boot/dts/rockchip/px30.dtsi                                                             |   16 
 kernel/Documentation/networking/index.rst                                                                 |    1 
 kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h                                                   |    2 
 kernel/drivers/media/dvb-frontends/cxd2820r_core.c                                                        |    2 
 kernel/arch/riscv/mm/cacheflush.c                                                                         |    4 
 kernel/drivers/watchdog/sp5100_tco.c                                                                      |    4 
 kernel/arch/x86/include/asm/intel-family.h                                                                |    7 
 kernel/fs/debugfs/file.c                                                                                  |   28 
 kernel/fs/nilfs2/ioctl.c                                                                                  |    9 
 kernel/net/ipv6/ip6_tunnel.c                                                                              |    4 
 kernel/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c                                                   |    7 
 kernel/net/netfilter/nf_tables_api.c                                                                      | 1323 
 kernel/mm/backing-dev.c                                                                                   |   12 
 kernel/fs/ceph/mds_client.c                                                                               |   10 
 kernel/arch/arm/boot/dts/meson8.dtsi                                                                      |    4 
 kernel/drivers/gpu/drm/bridge/adv7511/adv7511.h                                                           |    3 
 kernel/drivers/pci/controller/dwc/pcie-dw-rockchip.c                                                      |  177 
 kernel/drivers/media/dvb-frontends/tda8083.c                                                              |    2 
 kernel/drivers/pinctrl/pinctrl-ingenic.c                                                                  |    3 
 kernel/drivers/net/arcnet/arcnet.c                                                                        |    2 
 kernel/fs/ceph/mds_client.h                                                                               |    5 
 kernel/drivers/s390/net/qeth_l3_main.c                                                                    |    8 
 kernel/drivers/hwtracing/coresight/coresight-tmc-etr.c                                                    |    7 
 kernel/Documentation/ABI/testing/configfs-usb-gadget-uvc                                                  |    2 
 kernel/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts                                                       |   13 
 kernel/arch/arm/mach-pxa/sharpsl_pm.c                                                                     |    2 
 kernel/arch/x86/kvm/svm/svm.c                                                                             |   17 
 kernel/drivers/media/platform/rockchip/isp/isp_mipi_luma.c                                                |    2 
 kernel/drivers/gpu/drm/sun4i/sun4i_drv.c                                                                  |    4 
 kernel/arch/arm/boot/dts/stm32f7-pinctrl.dtsi                                                             |   82 
 kernel/drivers/nfc/st-nci/ndlc.c                                                                          |    6 
 kernel/drivers/firmware/google/framebuffer-coreboot.c                                                     |    4 
 kernel/sound/soc/codecs/cs42l51.h                                                                         |    1 
 kernel/fs/nfs/namespace.c                                                                                 |    2 
 kernel/drivers/media/dvb-frontends/cx24113.c                                                              |    2 
 kernel/drivers/scsi/pm8001/pm8001_sas.c                                                                   |    4 
 kernel/include/asm-generic/pgtable-nop4d.h                                                                |    2 
 kernel/drivers/thermal/sun8i_thermal.c                                                                    |   55 
 kernel/include/linux/eventfd.h                                                                            |    8 
 kernel/drivers/platform/x86/msi-laptop.c                                                                  |    8 
 kernel/sound/soc/codecs/cs42l51.c                                                                         |    7 
 kernel/net/xfrm/xfrm_input.c                                                                              |    4 
 kernel/net/ipv4/ip_gre.c                                                                                  |    4 
 kernel/tools/virtio/vringh_test.c                                                                         |    2 
 kernel/drivers/media/i2c/m5mols/m5mols_core.c                                                             |    2 
 kernel/include/sound/hdaudio_ext.h                                                                        |    1 
 kernel/drivers/base/firmware_loader/firmware.h                                                            |    1 
 kernel/arch/parisc/include/asm/pgtable.h                                                                  |    4 
 kernel/drivers/mtd/nand/spi/unim.c                                                                        |  130 
 kernel/fs/ocfs2/stackglue.c                                                                               |    8 
 kernel/arch/s390/kernel/vmlinux.lds.S                                                                     |    3 
 kernel/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c                                                 |  476 
 kernel/drivers/infiniband/core/device.c                                                                   |   13 
 kernel/Documentation/filesystems/autofs-mount-control.rst                                                 |    2 
 kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c                                                        |    2 
 kernel/include/asm-generic/vmlinux.lds.h                                                                  |    5 
 kernel/arch/powerpc/mm/book3s64/radix_tlb.c                                                               |   11 
 kernel/arch/x86/xen/smp_pv.c                                                                              |   14 
 kernel/net/hsr/hsr_forward.c                                                                              |   16 
 kernel/drivers/iommu/amd/init.c                                                                           |  112 
 kernel/kernel/time/tick-internal.h                                                                        |    1 
 kernel/drivers/media/i2c/maxim4c/maxim4c_debugfs.c                                                        |   60 
 kernel/kernel/trace/trace_events_synth.c                                                                  |    2 
 kernel/drivers/acpi/acpica/dbnames.c                                                                      |    3 
 kernel/drivers/crypto/rockchip/cryptodev_linux/ioctl.c                                                    |    2 
 kernel/arch/arm/boot/dts/exynos5420.dtsi                                                                  |    2 
 kernel/drivers/net/wireguard/timers.c                                                                     |    8 
 kernel/drivers/rtc/rtc-omap.c                                                                             |    1 
 kernel/fs/nfs/direct.c                                                                                    |   48 
 kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c                                                |   23 
 kernel/drivers/infiniband/sw/siw/siw_cm.c                                                                 |   17 
 kernel/drivers/media/dvb-frontends/dib9000.c                                                              |    2 
 kernel/arch/arm64/boot/dts/rockchip/rk3562-evb1-lp4x-v10.dtsi                                             |   12 
 kernel/drivers/ptp/ptp_qoriq.c                                                                            |    2 
 kernel/fs/overlayfs/dir.c                                                                                 |   51 
 kernel/drivers/net/ethernet/intel/i40e/i40e_main.c                                                        |   14 
 kernel/arch/arm/mach-omap2/board-generic.c                                                                |    1 
 kernel/drivers/cpufreq/qcom-cpufreq-hw.c                                                                  |    1 
 kernel/drivers/pci/irq.c                                                                                  |    2 
 kernel/mm/shmem.c                                                                                         |   30 
 kernel/drivers/gpu/drm/msm/dp/dp_display.c                                                                |    5 
 kernel/drivers/net/ethernet/intel/ice/ice_base.c                                                          |    3 
 kernel/net/ipv4/inet_hashtables.c                                                                         |   12 
 kernel/sound/pci/hda/patch_realtek.c                                                                      |  191 
 kernel/drivers/tty/tty_io.c                                                                               |   13 
 kernel/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c                                                     |    4 
 kernel/drivers/mfd/rkx110_x120/rkx120_combtxphy.c                                                         |  101 
 kernel/drivers/clk/renesas/r9a06g032-clocks.c                                                             |    3 
 kernel/arch/arm64/mm/mmu.c                                                                                |    4 
 kernel/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi                                                         |    2 
 kernel/drivers/block/null_blk/trace.c                                                                     |    2 
 kernel/drivers/pci/controller/dwc/pci-imx6.c                                                              |    7 
 kernel/drivers/leds/led-class.c                                                                           |    6 
 kernel/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.h                                  |    4 
 kernel/arch/arm64/boot/dts/rockchip/rk3399pro-npu.dtsi                                                    |    1 
 kernel/drivers/gpu/drm/tidss/tidss_dispc.c                                                                |    4 
 kernel/drivers/net/ethernet/rdc/r6040.c                                                                   |    5 
 kernel/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c                                  |   72 
 kernel/drivers/md/dm-cache-metadata.c                                                                     |   54 
 kernel/arch/mips/kernel/smp-cps.c                                                                         |    8 
 kernel/drivers/net/ethernet/amd/atarilance.c                                                              |    2 
 kernel/drivers/block/null_blk/trace.h                                                                     |    2 
 kernel/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c                                              |    2 
 kernel/drivers/infiniband/sw/rxe/rxe_task.h                                                               |    5 
 kernel/drivers/media/pci/intel/ipu3/ipu3-cio2.c                                                           |    5 
 kernel/Documentation/translations/it_IT/kernel-hacking/locking.rst                                        |    2 
 kernel/net/l2tp/l2tp_ppp.c                                                                                |  127 
 kernel/drivers/phy/hisilicon/phy-hisi-inno-usb2.c                                                         |    2 
 kernel/net/wireless/reg.c                                                                                 |    4 
 kernel/arch/arm/boot/dts/armada-380.dtsi                                                                  |    4 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-maxim-cameras-s66.dtsi                                 |   12 
 kernel/drivers/media/i2c/maxim2c/Makefile                                                                 |   14 
 kernel/drivers/infiniband/sw/rxe/rxe_task.c                                                               |    5 
 kernel/drivers/infiniband/hw/hfi1/vnic_sdma.c                                                             |    3 
 kernel/drivers/iio/Kconfig                                                                                |    1 
 kernel/tools/testing/selftests/resctrl/resctrl.h                                                          |    1 
 kernel/tools/testing/selftests/bpf/verifier/search_pruning.c                                              |   36 
 kernel/kernel/irq/internals.h                                                                             |    2 
 kernel/drivers/char/tpm/eventlog/acpi.c                                                                   |   18 
 kernel/net/sunrpc/auth_gss/auth_gss.c                                                                     |   19 
 kernel/drivers/acpi/device_pm.c                                                                           |   29 
 kernel/drivers/media/dvb-frontends/tda1004x.c                                                             |    4 
 kernel/net/netfilter/ipset/ip_set_bitmap_ip.c                                                             |    4 
 kernel/tools/power/cpupower/Makefile                                                                      |    8 
 kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c                                             |    4 
 kernel/net/netlink/af_netlink.c                                                                           |  128 
 kernel/drivers/net/usb/smsc95xx.c                                                                         |    6 
 kernel/drivers/staging/iio/resolver/ad2s1210.c                                                            |    2 
 kernel/drivers/remoteproc/mtk_scp_ipi.c                                                                   |   11 
 kernel/arch/s390/Makefile                                                                                 |    1 
 kernel/arch/x86/boot/compressed/head_64.S                                                                 |   30 
 kernel/drivers/net/wireless/broadcom/b43legacy/b43legacy.h                                                |    2 
 kernel/net/sched/sch_mqprio.c                                                                             |  144 
 kernel/arch/arm/boot/dts/omap3-ldp.dts                                                                    |    2 
 kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h                                             |    4 
 kernel/net/sched/act_skbedit.c                                                                            |    2 
 kernel/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h                                                   |    3 
 kernel/arch/arm/boot/dts/omap3-gta04a5one.dts                                                             |    4 
 kernel/drivers/spi/spi-qup.c                                                                              |   59 
 kernel/drivers/spi/spi-zynqmp-gqspi.c                                                                     |   24 
 kernel/drivers/infiniband/sw/rxe/rxe_qp.c                                                                 |   22 
 kernel/arch/arm/boot/dts/vexpress-v2p-ca5s.dts                                                            |    1 
 kernel/net/tipc/crypto.h                                                                                  |    6 
 kernel/fs/btrfs/super.c                                                                                   |    4 
 kernel/net/can/bcm.c                                                                                      |   28 
 kernel/drivers/gpio/gpio-mockup.c                                                                         |    2 
 kernel/drivers/video/rockchip/rga3/rga_job.c                                                              |  124 
 kernel/net/tipc/crypto.c                                                                                  |    7 
 kernel/drivers/gpu/drm/nouveau/nouveau_drm.c                                                              |   14 
 kernel/drivers/bus/Makefile                                                                               |    2 
 kernel/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi                                                      |   11 
 kernel/net/ipv6/netfilter/ip6_tables.c                                                                    |    3 
 kernel/arch/arm/boot/dts/rv1106g-evb2-v12-nofastae-spi-nand.dts                                           |    2 
 kernel/Documentation/sphinx/load_config.py                                                                |    6 
 kernel/kernel/kexec_core.c                                                                                |   33 
 kernel/drivers/rpmsg/rpmsg_core.c                                                                         |   23 
 kernel/drivers/tty/serial/serial_core.c                                                                   |    3 
 kernel/arch/arm/boot/dts/rv1106g-evb2-v10.dts                                                             |    2 
 kernel/drivers/dma/mcf-edma.c                                                                             |   13 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712.dtsi                                |    6 
 kernel/include/trace/events/writeback.h                                                                   |    2 
 kernel/drivers/tty/tty_audit.c                                                                            |    1 
 kernel/drivers/staging/rtl8712/rtl871x_ioctl_linux.c                                                      |    8 
 kernel/drivers/media/dvb-frontends/drx39xyj/drxj.c                                                        |    2 
 kernel/fs/incfs/sysfs.c                                                                                   |    4 
 kernel/drivers/base/dd.c                                                                                  |   13 
 kernel/include/linux/hyperv.h                                                                             |    2 
 kernel/net/rxrpc/output.c                                                                                 |    2 
 kernel/fs/xattr.c                                                                                         |    2 
 kernel/include/linux/raid_class.h                                                                         |    4 
 kernel/drivers/iommu/amd/amd_iommu_types.h                                                                |    4 
 kernel/drivers/media/platform/rockchip/isp/isp_stats_v21.c                                                |    2 
 kernel/drivers/xen/pcpu.c                                                                                 |   20 
 kernel/net/ipv4/udp.c                                                                                     |   29 
 kernel/drivers/clk/imx/clk-imx8mn.c                                                                       |   20 
 kernel/drivers/mmc/host/sdhci-esdhc-imx.c                                                                 |   29 
 kernel/fs/nfsd/blocklayoutxdr.c                                                                           |    9 
 kernel/drivers/input/joystick/xpad.c                                                                      |    6 
 kernel/arch/mips/configs/nlm_xlr_defconfig                                                                |    2 
 kernel/arch/x86/pci/fixup.c                                                                               |   21 
 kernel/drivers/media/tuners/fc0011.c                                                                      |    2 
 kernel/drivers/gpu/drm/i915/gvt/gvt.h                                                                     |    3 
 kernel/fs/nfs/file.c                                                                                      |   15 
 kernel/kernel/trace/trace_irqsoff.c                                                                       |    3 
 kernel/tools/testing/selftests/net/tls.c                                                                  |   11 
 kernel/arch/arm/boot/dts/e60k02.dtsi                                                                      |    1 
 kernel/arch/arm/boot/dts/imx6ul-pico-dwarf.dts                                                            |    2 
 kernel/drivers/nfc/nfcsim.c                                                                               |    4 
 kernel/drivers/media/i2c/Kconfig                                                                          |  128 
 kernel/drivers/pwm/pwm-iqs620a.c                                                                          |    1 
 kernel/include/soc/rockchip/rockchip_sip.h                                                                |    1 
 kernel/arch/arm/boot/dts/imx7d-pico-nymph.dts                                                             |    4 
 kernel/drivers/hid/hid-ids.h                                                                              |    6 
 kernel/drivers/firmware/efi/libstub/x86-stub.c                                                            |    2 
 kernel/include/net/tcp.h                                                                                  |   39 
 kernel/drivers/tty/serial/serial-tegra.c                                                                  |   12 
 kernel/fs/jbd2/journal.c                                                                                  |    2 
 kernel/drivers/net/wireless/ath/ath9k/ahb.c                                                               |    4 
 kernel/mm/memory.c                                                                                        |   38 
 kernel/include/dt-bindings/suspend/rockchip-rv1106.h                                                      |   81 
 kernel/mm/swapfile.c                                                                                      |   22 
 kernel/net/mac80211/mesh_pathtbl.c                                                                        |   89 
 kernel/drivers/usb/gadget/function/f_uvc.c                                                                |    5 
 kernel/drivers/hid/hid-betopff.c                                                                          |   17 
 kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-single-channel-lvds.dts                          |  121 
 kernel/arch/riscv/Kconfig                                                                                 |   23 
 kernel/drivers/char/ipmi/ipmi_ssif.c                                                                      |  196 
 kernel/arch/arm/mach-s3c/s3c64xx.c                                                                        |    3 
 kernel/arch/x86/kernel/apic/apic.c                                                                        |    5 
 kernel/tools/testing/selftests/bpf/progs/test_sk_assign_libbpf.c                                          |    3 
 kernel/net/ipv6/af_inet6.c                                                                                |   15 
 kernel/drivers/crypto/ccp/psp-dev.c                                                                       |    6 
 kernel/drivers/media/dvb-frontends/tda665x.c                                                              |    2 
 kernel/arch/m68k/coldfire/entry.S                                                                         |    2 
 kernel/drivers/hwmon/xgene-hwmon.c                                                                        |    1 
 kernel/drivers/s390/net/netiucv.c                                                                         |    9 
 kernel/arch/arm64/boot/dts/rockchip/rk3562.dtsi                                                           |  191 
 kernel/drivers/xen/privcmd.c                                                                              |    2 
 kernel/drivers/spi/spidev-rkslv.c                                                                         |   45 
 kernel/drivers/block/Kconfig                                                                              |   17 
 kernel/drivers/net/ethernet/pasemi/pasemi_mac.c                                                           |    2 
 kernel/net/batman-adv/bat_v_ogm.c                                                                         |    7 
 kernel/drivers/iio/adc/rockchip_saradc.c                                                                  |   21 
 kernel/include/linux/pipe_fs_i.h                                                                          |    4 
 kernel/drivers/irqchip/irq-loongson-pch-pic.c                                                             |    2 
 kernel/drivers/iommu/mtk_iommu_v1.c                                                                       |   26 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-maxim-split.dtsi                    | 2438 
 kernel/drivers/video/rockchip/mpp_osal/mpp_osal.h                                                         |   18 
 kernel/drivers/video/rockchip/rga3/include/rga_mm.h                                                       |    4 
 kernel/drivers/base/regmap/regcache-rbtree.c                                                              |   13 
 kernel/drivers/block/rbd.c                                                                                |  637 
 kernel/drivers/nfc/st-nci/se.c                                                                            |    6 
 kernel/drivers/video/rockchip/mpp_osal/mpp_osal.c                                                         |   30 
 kernel/include/linux/timerqueue.h                                                                         |    2 
 kernel/drivers/gpu/drm/rockchip/rockchip_drm_vvop.c                                                       |  551 
 kernel/drivers/crypto/ccp/sev-dev.h                                                                       |    3 
 kernel/arch/riscv/kernel/stacktrace.c                                                                     |   14 
 kernel/drivers/usb/host/xhci-tegra.c                                                                      |   14 
 kernel/drivers/gpu/drm/i915/gvt/gvt.c                                                                     |    9 
 kernel/drivers/crypto/ccp/sev-dev.c                                                                       |  220 
 kernel/drivers/iio/adc/ti-adc128s052.c                                                                    |   14 
 kernel/drivers/video/backlight/gpio_backlight.c                                                           |    5 
 kernel/drivers/net/hamradio/baycom_epp.c                                                                  |    2 
 kernel/net/netfilter/nft_exthdr.c                                                                         |  193 
 kernel/sound/soc/soc-compress.c                                                                           |    2 
 kernel/drivers/firmware/tegra/bpmp-debugfs.c                                                              |    5 
 kernel/drivers/iommu/rockchip-iommu.c                                                                     |   14 
 kernel/net/802/mrp.c                                                                                      |   18 
 kernel/drivers/tty/serial/8250/8250_pci.c                                                                 |    5 
 kernel/drivers/cpuidle/dt_idle_states.c                                                                   |    2 
 kernel/drivers/dax/kmem.c                                                                                 |    4 
 kernel/net/hsr/hsr_framereg.c                                                                             |   11 
 kernel/arch/powerpc/include/asm/nohash/64/pgtable-4k.h                                                    |    6 
 kernel/drivers/clk/clk-versaclock5.c                                                                      |   29 
 kernel/net/hsr/hsr_framereg.h                                                                             |    2 
 kernel/arch/x86/mm/init_64.c                                                                              |    4 
 kernel/drivers/usb/core/hub.c                                                                             |  375 
 kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c                                                  |   35 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c                                          |    5 
 kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c                                            |    6 
 kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop.h                                                        |    8 
 kernel/fs/inode.c                                                                                         |  122 
 kernel/tools/objtool/arch.h                                                                               |    1 
 kernel/drivers/net/wireless/mediatek/mt76/mt76.h                                                          |    5 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-android.dtsi                                                   |    2 
 kernel/kernel/sched/psi.c                                                                                 |    7 
 kernel/drivers/net/phy/smsc.c                                                                             |    5 
 kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop.c                                                        |   50 
 kernel/drivers/irqchip/irq-gic-v3.c                                                                       |   87 
 kernel/arch/powerpc/mm/numa.c                                                                             |  433 
 kernel/drivers/nfc/st21nfca/se.c                                                                          |    6 
 kernel/drivers/s390/net/qeth_core.h                                                                       |    1 
 kernel/drivers/base/power/wakeirq.c                                                                       |  111 
 kernel/virt/kvm/kvm_main.c                                                                                |  149 
 kernel/drivers/gpu/drm/tiny/gm12u320.c                                                                    |   10 
 kernel/fs/ocfs2/journal.h                                                                                 |    1 
 kernel/drivers/net/macsec.c                                                                               |   37 
 kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11-i2s-dmic.dts                                     |    2 
 kernel/drivers/remoteproc/remoteproc_core.c                                                               |    9 
 kernel/fs/ocfs2/journal.c                                                                                 |    2 
 kernel/net/bridge/br_forward.c                                                                            |    2 
 kernel/drivers/gpu/drm/radeon/rv740_dpm.c                                                                 |    8 
 kernel/fs/cifs/smbdirect.c                                                                                |    5 
 kernel/arch/arm/configs/rk3308_linux_aarch32_defconfig                                                    |  107 
 kernel/arch/x86/include/asm/pgtable_64.h                                                                  |    4 
 kernel/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi                                                          |    6 
 kernel/tools/lib/bpf/btf_dump.c                                                                           |  192 
 kernel/drivers/staging/media/atomisp/pci/atomisp_cmd.c                                                    |    3 
 kernel/fs/btrfs/disk-io.h                                                                                 |    2 
 kernel/drivers/i2c/busses/i2c-designware-master.c                                                         |   15 
 kernel/drivers/net/ethernet/atheros/atl1e/atl1e_main.c                                                    |    7 
 kernel/drivers/hwtracing/coresight/coresight-etm4x.h                                                      |   20 
 kernel/fs/btrfs/disk-io.c                                                                                 |   99 
 kernel/drivers/spi/spi-fsl-lpspi.c                                                                        |    7 
 kernel/drivers/media/platform/mtk-vpu/mtk_vpu.c                                                           |    6 
 kernel/net/sched/Makefile                                                                                 |    3 
 kernel/net/netfilter/nfnetlink_log.c                                                                      |    4 
 kernel/fs/exfat/dir.c                                                                                     |   77 
 kernel/kernel/kcsan/report.c                                                                              |    4 
 kernel/drivers/power/supply/sbs-charger.c                                                                 |    2 
 kernel/android/abi_gki_aarch64_mtk                                                                        |   24 
 kernel/fs/fuse/file.c                                                                                     |   31 
 kernel/arch/arm64/include/asm/pgtable.h                                                                   |    8 
 kernel/arch/riscv/kernel/time.c                                                                           |    3 
 kernel/drivers/scsi/qla2xxx/qla_dfs.c                                                                     |    6 
 kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c                                            |    1 
 kernel/lib/dim/net_dim.c                                                                                  |    3 
 kernel/arch/arm64/boot/dts/rockchip/rk3562-evb1-cam.dtsi                                                  |    1 
 kernel/net/vmw_vsock/vmci_transport.c                                                                     |    6 
 kernel/drivers/usb/cdns3/gadget.h                                                                         |    9 
 kernel/include/uapi/linux/uvcvideo.h                                                                      |    2 
 kernel/drivers/media/dvb-frontends/dib8000.c                                                              |    2 
 kernel/drivers/usb/cdns3/gadget.c                                                                         |   60 
 kernel/arch/parisc/kernel/sys_parisc.c                                                                    |   27 
 kernel/mm/memory-failure.c                                                                                |  136 
 kernel/tools/testing/selftests/net/mptcp/Makefile                                                         |    2 
 kernel/crypto/seqiv.c                                                                                     |    2 
 kernel/drivers/media/dvb-frontends/dib0090.c                                                              |    4 
 kernel/drivers/hv/ring_buffer.c                                                                           |   13 
 kernel/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c                                                   |    5 
 kernel/arch/arm64/boot/dts/amlogic/meson-axg.dtsi                                                         |    8 
 kernel/drivers/firmware/raspberrypi.c                                                                     |   30 
 kernel/drivers/gpu/drm/i915/i915_drv.h                                                                    |    1 
 kernel/drivers/gpu/drm/i915/i915_drv.c                                                                    |    4 
 kernel/kernel/sched/cpuacct.c                                                                             |   84 
 kernel/drivers/net/wireless/marvell/mwifiex/sta_rx.c                                                      |   26 
 kernel/drivers/tty/n_gsm.c                                                                                |    8 
 kernel/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.c                                                     |  592 
 kernel/drivers/net/wireless/ath/ar5523/ar5523.c                                                           |    6 
 kernel/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.h                                                     |   66 
 kernel/arch/arm64/boot/dts/rockchip/rk3568-toybrick.dtsi                                                  |    2 
 kernel/drivers/memory/mvebu-devbus.c                                                                      |    3 
 kernel/fs/jfs/jfs_imap.c                                                                                  |    1 
 kernel/drivers/mfd/rkx110_x120/rkx110_x120_core.c                                                         |  474 
 kernel/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi                                                         |    2 
 kernel/sound/soc/rockchip/rockchip_dlp.c                                                                  | 1323 
 kernel/arch/m68k/include/asm/motorola_pgtable.h                                                           |    2 
 kernel/drivers/gpu/drm/panfrost/panfrost_drv.c                                                            |   27 
 kernel/drivers/crypto/caam/ctrl.c                                                                         |    6 
 kernel/sound/soc/rockchip/rockchip_dlp.h                                                                  |  128 
 kernel/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts                                             |    3 
 kernel/fs/ceph/snap.c                                                                                     |   17 
 kernel/tools/testing/selftests/memfd/fuse_test.c                                                          |    1 
 kernel/drivers/firmware/rockchip_sip.c                                                                    |   27 
 kernel/fs/nfs/blocklayout/dev.c                                                                           |    4 
 kernel/sound/soc/atmel/mchp-spdiftx.c                                                                     |    2 
 kernel/arch/arm/configs/rk3128_linux.config                                                               |    5 
 kernel/drivers/tty/serial/8250/8250_exar.c                                                                |   68 
 kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v12.dts                                              |    2 
 kernel/tools/perf/ui/browsers/hists.c                                                                     |   60 
 kernel/drivers/irqchip/irq-gic-pm.c                                                                       |    2 
 kernel/include/linux/cpu.h                                                                                |   10 
 kernel/drivers/mmc/host/jz4740_mmc.c                                                                      |   10 
 kernel/android/abi_gki_aarch64_qcom                                                                       |   27 
 kernel/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi                                                       |    6 
 kernel/drivers/net/ethernet/cadence/macb_main.c                                                           |   13 
 kernel/include/sound/pcm.h                                                                                |   34 
 kernel/sound/usb/quirks-table.h                                                                           |   31 
 kernel/drivers/gpu/drm/sti/sti_hdmi.c                                                                     |    7 
 kernel/fs/hfs/inode.c                                                                                     |   13 
 kernel/arch/sparc/kernel/setup_32.c                                                                       |    7 
 kernel/drivers/net/wireless/ath/ath6kl/htc_pipe.c                                                         |    4 
 kernel/drivers/pnp/core.c                                                                                 |    4 
 kernel/security/selinux/ss/policydb.c                                                                     |    2 
 kernel/arch/arm64/boot/dts/rockchip/rk3528.dtsi                                                           |   13 
 kernel/arch/riscv/include/asm/hugetlb.h                                                                   |    6 
 kernel/arch/x86/kernel/process_64.c                                                                       |    2 
 kernel/include/linux/tick.h                                                                               |    2 
 kernel/fs/nilfs2/sufile.c                                                                                 |    9 
 kernel/fs/ext4/page-io.c                                                                                  |   11 
 kernel/arch/x86/kvm/svm/vmenter.S                                                                         |    3 
 kernel/lib/test_firmware.c                                                                                |  108 
 kernel/drivers/media/tuners/mxl5005s.c                                                                    |    2 
 kernel/drivers/video/rockchip/rga3/include/rga_drv.h                                                      |    4 
 kernel/tools/testing/selftests/net/mptcp/config                                                           |    2 
 kernel/lib/ubsan.c                                                                                        |   11 
 kernel/drivers/bluetooth/btbcm.c                                                                          |   49 
 kernel/drivers/usb/dwc2/platform.c                                                                        |   17 
 kernel/kernel/bpf/queue_stack_maps.c                                                                      |   21 
 kernel/drivers/usb/gadget/composite.c                                                                     |    4 
 kernel/arch/arm64/kernel/cpufeature.c                                                                     |    3 
 kernel/drivers/hid/hid-sensor-custom.c                                                                    |    2 
 kernel/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi                                                   |    6 
 kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c                                                             |   20 
 kernel/arch/x86/kernel/cpu/mce/internal.h                                                                 |   12 
 kernel/drivers/irqchip/irq-meson-gpio.c                                                                   |    2 
 kernel/drivers/gpu/drm/mediatek/mtk_drm_gem.c                                                             |   10 
 kernel/drivers/rtc/rtc-pic32.c                                                                            |    8 
 kernel/drivers/net/ethernet/amd/xgbe/xgbe-drv.c                                                           |    3 
 kernel/drivers/spi/spi-imx.c                                                                              |   38 
 kernel/arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts                                                         |    2 
 kernel/drivers/gpu/drm/vkms/vkms_drv.c                                                                    |    3 
 kernel/drivers/media/dvb-frontends/drxk_hard.c                                                            |    2 
 kernel/include/soc/rockchip/rockchip_rockit.h                                                             |    7 
 kernel/drivers/media/i2c/techpoint/Makefile                                                               |    2 
 kernel/tools/testing/selftests/proc/proc-uptime-002.c                                                     |    3 
 kernel/drivers/net/can/usb/gs_usb.c                                                                       |    7 
 kernel/arch/powerpc/kernel/hw_breakpoint.c                                                                |    7 
 kernel/drivers/media/dvb-frontends/dib3000mb.c                                                            |    2 
 kernel/arch/x86/events/intel/uncore_snbep.c                                                               |   48 
 kernel/arch/arm/mach-imx/cpu-imx27.c                                                                      |    1 
 kernel/tools/perf/util/sort.c                                                                             |    3 
 kernel/drivers/media/platform/rockchip/isp/isp_stats_v3x.c                                                |    2 
 kernel/include/linux/acpi.h                                                                               |    5 
 kernel/drivers/net/wireguard/selftest/allowedips.c                                                        |   16 
 kernel/arch/nios2/boot/dts/10m50_devboard.dts                                                             |    2 
 kernel/include/net/udplite.h                                                                              |    8 
 kernel/arch/sparc/kernel/traps_32.c                                                                       |    4 
 kernel/sound/soc/codecs/rk817_codec.c                                                                     |   31 
 kernel/arch/arm64/boot/dts/qcom/sdm845-db845c.dts                                                         |   15 
 kernel/drivers/gpu/drm/radeon/radeon_gem.c                                                                |    4 
 kernel/drivers/media/tuners/mt2060.c                                                                      |    2 
 kernel/sound/soc/codecs/rk817_codec.h                                                                     |   12 
 kernel/fs/verity/enable.c                                                                                 |   24 
 kernel/drivers/media/dvb-frontends/lgdt3305.c                                                             |    2 
 kernel/tools/testing/selftests/net/fib_tests.sh                                                           |    4 
 kernel/drivers/firmware/arm_sdei.c                                                                        |   32 
 kernel/kernel/time/posix-stubs.c                                                                          |    2 
 kernel/include/uapi/linux/rkcif-config.h                                                                  |    9 
 kernel/fs/ext4/balloc.c                                                                                   |   56 
 kernel/arch/arm/boot/dts/rv1106.dtsi                                                                      |   50 
 kernel/drivers/infiniband/hw/hfi1/verbs.c                                                                 |    4 
 kernel/include/net/mrp.h                                                                                  |    1 
 kernel/net/l2tp/l2tp_ip6.c                                                                                |    4 
 kernel/drivers/staging/rtl8712/rtl871x_mlme.c                                                             |   10 
 kernel/arch/riscv/include/asm/pgtable-64.h                                                                |    4 
 kernel/arch/arm/include/asm/pgtable-3level.h                                                              |    2 
 kernel/sound/firewire/digi00x/digi00x-stream.c                                                            |    4 
 kernel/drivers/usb/gadget/function/uvc_v4l2.c                                                             |    2 
 kernel/drivers/irqchip/irq-mtk-cirq.c                                                                     |    2 
 kernel/drivers/net/ethernet/renesas/ravb_main.c                                                           |   12 
 kernel/arch/x86/boot/compressed/ident_map_64.c                                                            |    8 
 kernel/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c                                                   |    7 
 kernel/arch/arm64/configs/gki_defconfig                                                                   |    4 
 kernel/drivers/media/i2c/ov2680.c                                                                         |  264 
 kernel/drivers/staging/iio/accel/adis16240.c                                                              |    1 
 kernel/arch/arm/boot/dts/imx6qdl.dtsi                                                                     |    8 
 kernel/drivers/net/ethernet/ti/am65-cpsw-nuss.c                                                           |   86 
 kernel/arch/arm64/include/asm/atomic_ll_sc.h                                                              |  114 
 kernel/arch/arm/boot/dts/omap3-cm-t3517.dts                                                               |   12 
 kernel/drivers/hwmon/pmbus/adm1266.c                                                                      |    1 
 kernel/drivers/media/dvb-frontends/ves1820.c                                                              |    2 
 kernel/drivers/net/wireless/mediatek/mt76/mt7615/dma.c                                                    |    2 
 kernel/net/can/j1939/main.c                                                                               |   24 
 kernel/fs/jfs/jfs_txnmgr.c                                                                                |    5 
 kernel/drivers/usb/host/uhci-pci.c                                                                        |   10 
 kernel/arch/arm/mach-orion5x/common.h                                                                     |    6 
 kernel/drivers/char/hw_random/imx-rngc.c                                                                  |    6 
 kernel/drivers/gpu/drm/sti/sti_hda.c                                                                      |    7 
 kernel/sound/pci/ymfpci/ymfpci_main.c                                                                     |   74 
 kernel/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c                                                    |    4 
 kernel/drivers/rknpu/include/rknpu_drv.h                                                                  |   19 
 kernel/drivers/pci/pci.c                                                                                  |   71 
 kernel/arch/arm/boot/dts/rv1106-evb-cam.dtsi                                                              |  108 
 kernel/drivers/media/dvb-frontends/stv090x.c                                                              |    2 
 kernel/drivers/media/platform/rockchip/isp/version.h                                                      |   24 
 kernel/sound/pci/hda/hda_intel.c                                                                          |   27 
 kernel/drivers/bus/mhi/host/Makefile                                                                      |    6 
 kernel/tools/objtool/check.c                                                                              |   63 
 kernel/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts                                                       |    4 
 kernel/drivers/media/usb/dvb-usb-v2/anysee.c                                                              |    2 
 kernel/net/dccp/proto.c                                                                                   |   38 
 kernel/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10-avb.dts                                             |    4 
 kernel/drivers/pinctrl/pinctrl-ocelot.c                                                                   |    2 
 kernel/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json                                            |    2 
 kernel/tools/gpio/gpio-event-mon.c                                                                        |    1 
 kernel/drivers/md/dm-ioctl.c                                                                              |    7 
 kernel/block/keyslot-manager.c                                                                            |   43 
 kernel/drivers/pci/pci.h                                                                                  |   59 
 kernel/drivers/net/ethernet/broadcom/genet/bcmmii.c                                                       |   15 
 kernel/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts                                                    |    3 
 kernel/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi                                                          |    1 
 kernel/arch/x86/kernel/acpi/cstate.c                                                                      |   15 
 kernel/drivers/net/wireless/marvell/libertas_tf/if_usb.c                                                  |    2 
 kernel/arch/powerpc/sysdev/xive/spapr.c                                                                   |    1 
 kernel/drivers/s390/net/qeth_l2_main.c                                                                    |    9 
 kernel/arch/arm/boot/dts/meson8b.dtsi                                                                     |    4 
 kernel/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c                                              |    1 
 kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-linux.dts                                       |    2 
 kernel/drivers/media/i2c/Makefile                                                                         |   15 
 kernel/drivers/clk/tegra/clk-tegra124-emc.c                                                               |    2 
 kernel/block/mq-deadline-main.c                                                                           |   18 
 kernel/drivers/input/misc/adxl34x.c                                                                       |    3 
 kernel/drivers/media/i2c/maxim4c/remote_max96715.c                                                        |   17 
 kernel/drivers/media/platform/rockchip/cif/subdev-itf.h                                                   |    1 
 kernel/drivers/thunderbolt/usb4.c                                                                         |   22 
 kernel/fs/orangefs/orangefs-debugfs.c                                                                     |   29 
 kernel/drivers/net/ethernet/mellanox/mlxsw/i2c.c                                                          |    5 
 kernel/fs/f2fs/f2fs.h                                                                                     |    8 
 kernel/include/linux/pwm.h                                                                                |    2 
 kernel/arch/x86/um/vdso/um_vdso.c                                                                         |   12 
 kernel/drivers/media/platform/rockchip/cif/subdev-itf.c                                                   |  155 
 kernel/net/ipv4/devinet.c                                                                                 |   10 
 kernel/drivers/infiniband/hw/i40iw/i40iw.h                                                                |    5 
 kernel/drivers/mmc/host/sh_mmcif.c                                                                        |    2 
 kernel/drivers/iio/adc/stx104.c                                                                           |   98 
 kernel/fs/hugetlbfs/inode.c                                                                               |    6 
 kernel/drivers/net/ntb_netdev.c                                                                           |    4 
 kernel/drivers/usb/storage/unusual_uas.h                                                                  |   12 
 kernel/include/trace/trace_events.h                                                                       |    2 
 kernel/sound/usb/line6/midibuf.h                                                                          |    5 
 kernel/arch/arm/boot/dts/armada-385.dtsi                                                                  |    6 
 kernel/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c                                                    |   14 
 kernel/tools/perf/tests/builtin-test.c                                                                    |    3 
 kernel/drivers/block/nbd.c                                                                                |   20 
 kernel/tools/objtool/arch/x86/decode.c                                                                    |    6 
 kernel/include/uapi/sound/asequencer.h                                                                    |    8 
 kernel/net/ipv6/route.c                                                                                   |   11 
 kernel/arch/arm64/mm/fault.c                                                                              |   14 
 kernel/arch/m68k/kernel/setup_mm.c                                                                        |    3 
 kernel/drivers/char/hw_random/st-rng.c                                                                    |   21 
 kernel/kernel/sched/rt.c                                                                                  |   10 
 kernel/net/netfilter/nf_tables_trace.c                                                                    |    6 
 kernel/mm/kfence/Makefile                                                                                 |    2 
 kernel/arch/xtensa/boot/Makefile                                                                          |    3 
 kernel/drivers/usb/gadget/function/f_ncm.c                                                                |   30 
 kernel/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi                                               |   12 
 kernel/drivers/char/hw_random/iproc-rng200.c                                                              |   25 
 kernel/arch/arm64/mm/dma-mapping.c                                                                        |    4 
 kernel/block/blk-crypto-internal.h                                                                        |   25 
 kernel/drivers/misc/uid_sys_stats.c                                                                       |  112 
 kernel/net/ipv4/fib_trie.c                                                                                |    3 
 kernel/drivers/firmware/efi/memattr.c                                                                     |    2 
 kernel/android/abi_gki_aarch64_oplus                                                                      |  131 
 kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c                                                |    6 
 kernel/drivers/pwm/core.c                                                                                 |    2 
 kernel/arch/arm64/boot/dts/qcom/msm8916.dtsi                                                              |    4 
 kernel/drivers/thermal/intel/intel_quark_dts_thermal.c                                                    |   12 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c                                            |   13 
 kernel/sound/soc/qcom/lpass-cpu.c                                                                         |    5 
 kernel/drivers/infiniband/hw/hns/hns_roce_hw_v2.h                                                         |    6 
 kernel/drivers/infiniband/hw/hns/hns_roce_hw_v2.c                                                         |   33 
 kernel/arch/x86/events/amd/core.c                                                                         |    4 
 kernel/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c                                               |   16 
 kernel/arch/arm/boot/dts/imx6sll.dtsi                                                                     |   26 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v10.dts                                            |    2 
 kernel/tools/testing/selftests/net/rtnetlink.sh                                                           |    1 
 kernel/drivers/net/usb/cdc_ether.c                                                                        |   21 
 kernel/drivers/rknpu/rknpu_debugger.c                                                                     |   10 
 kernel/drivers/usb/core/usb-acpi.c                                                                        |   65 
 kernel/arch/s390/kernel/sthyi.c                                                                           |    6 
 kernel/drivers/vdpa/mlx5/core/mr.c                                                                        |    1 
 kernel/kernel/irq/timings.c                                                                               |    2 
 kernel/drivers/gpu/drm/msm/adreno/adreno_gpu.h                                                            |   10 
 kernel/drivers/android/binder.c                                                                           |   35 
 kernel/drivers/gpu/drm/msm/adreno/adreno_gpu.c                                                            |    5 
 kernel/sound/usb/line6/midibuf.c                                                                          |   25 
 kernel/drivers/clk/rockchip/clk-rk3399.c                                                                  |    2 
 kernel/drivers/usb/chipidea/usbmisc_imx.c                                                                 |    8 
 kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11.dts                                                 |    2 
 kernel/net/netfilter/nf_conntrack_netlink.c                                                               |   31 
 kernel/drivers/mfd/rkx110_x120/serdes_combphy.h                                                           |   23 
 kernel/arch/s390/crypto/paes_s390.c                                                                       |    2 
 kernel/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c                                                  |    2 
 kernel/tools/lib/bpf/btf.c                                                                                |   13 
 kernel/drivers/infiniband/hw/hfi1/sdma.c                                                                  |   28 
 kernel/drivers/media/dvb-frontends/stv0297.c                                                              |    2 
 kernel/drivers/net/ethernet/emulex/benet/be_main.c                                                        |    7 
 kernel/drivers/pinctrl/mediatek/pinctrl-paris.c                                                           |    4 
 kernel/arch/powerpc/platforms/512x/clock-commonclk.c                                                      |    2 
 kernel/drivers/infiniband/hw/hfi1/sdma.h                                                                  |   58 
 kernel/drivers/infiniband/hw/hns/hns_roce_device.h                                                        |    2 
 kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c                                   |   10 
 kernel/android/abi_gki_aarch64_transsion                                                                  |  121 
 kernel/drivers/soc/qcom/llcc-qcom.c                                                                       |    2 
 kernel/Documentation/virt/kvm/api.rst                                                                     |   78 
 kernel/arch/arm64/boot/dts/rockchip/rk3562-rk817-tablet-v10.dts                                           |   12 
 kernel/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c                                                             |   65 
 kernel/drivers/mfd/rkx110_x120/rkx110_linktx.c                                                            |  685 
 kernel/arch/arm/boot/dts/armada-xp-mv78260.dtsi                                                           |   16 
 kernel/arch/mips/include/asm/vpe.h                                                                        |    1 
 kernel/arch/parisc/kernel/firmware.c                                                                      |    5 
 kernel/drivers/media/i2c/max9286.c                                                                        |    2 
 kernel/sound/soc/rockchip/Kconfig                                                                         |    7 
 kernel/fs/xfs/xfs_file.c                                                                                  |   24 
 kernel/fs/overlayfs/util.c                                                                                |   24 
 kernel/include/net/vxlan.h                                                                                |   17 
 kernel/arch/arm/boot/dts/imx6sx.dtsi                                                                      |    7 
 kernel/drivers/net/dsa/mt7530.c                                                                           |    6 
 kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c                                                  |    7 
 kernel/scripts/gcc-plugins/gcc-common.h                                                                   |    9 
 kernel/kernel/irq/irqdesc.c                                                                               |   17 
 kernel/drivers/rpmsg/qcom_glink_native.c                                                                  |    5 
 kernel/drivers/md/dm-crypt.c                                                                              |   16 
 kernel/drivers/net/ethernet/ti/cpsw_ale.c                                                                 |   24 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c                                                  |    1 
 kernel/drivers/hwmon/coretemp.c                                                                           |  134 
 kernel/fs/f2fs/inode.c                                                                                    |   10 
 kernel/include/linux/trace_events.h                                                                       |    3 
 kernel/android/abi_gki_aarch64.xml                                                                        | 14586 ++--
 kernel/drivers/scsi/hosts.c                                                                               |    5 
 kernel/arch/x86/kernel/i8259.c                                                                            |    1 
 kernel/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c                                                             |    4 
 kernel/drivers/media/i2c/maxim4c/maxim4c_link.c                                                           |   12 
 kernel/sound/soc/mediatek/common/mtk-btcvsd.c                                                             |    6 
 kernel/drivers/mmc/host/tmio_mmc.h                                                                        |    1 
 kernel/arch/um/os-Linux/Makefile                                                                          |    2 
 kernel/drivers/i2c/muxes/i2c-mux-reg.c                                                                    |    5 
 kernel/drivers/video/fbdev/hyperv_fb.c                                                                    |    8 
 kernel/tools/virtio/linux/kmsan.h                                                                         |   12 
 kernel/arch/arm/boot/dts/omap3-cm-t3x.dtsi                                                                |    2 
 kernel/drivers/leds/leds-tca6507.c                                                                        |    5 
 kernel/drivers/net/wireless/mediatek/mt7601u/dma.c                                                        |    3 
 kernel/net/ipv4/tcp_fastopen.c                                                                            |    6 
 kernel/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c                                                |   15 
 kernel/arch/arm64/boot/dts/rockchip/rk3588s.dtsi                                                          |   41 
 kernel/drivers/net/ppp/ppp_generic.c                                                                      |    2 
 kernel/drivers/dma/pl330.c                                                                                |  203 
 kernel/drivers/misc/cxl/guest.c                                                                           |   24 
 kernel/include/trace/hooks/mm.h                                                                           |   57 
 kernel/arch/arm/boot/dts/bcm53573.dtsi                                                                    |   27 
 kernel/drivers/gpu/drm/nouveau/nouveau_bo.c                                                               |    9 
 kernel/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi                                                             |    2 
 kernel/fs/kernfs/dir.c                                                                                    |    2 
 kernel/arch/csky/abiv1/alignment.c                                                                        |    2 
 kernel/arch/arm/mm/fault.c                                                                                |    2 
 kernel/include/linux/tpm_eventlog.h                                                                       |    4 
 kernel/net/netfilter/ipvs/ip_vs_sync.c                                                                    |    6 
 kernel/drivers/media/usb/uvc/uvc_ctrl.c                                                                   |   30 
 kernel/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c                                      |   24 
 kernel/drivers/video/rockchip/mpp_osal/Kconfig                                                            |    8 
 kernel/arch/riscv/include/asm/patch.h                                                                     |    2 
 kernel/include/linux/percpu-rwsem.h                                                                       |    2 
 kernel/drivers/mtd/mtdblock.c                                                                             |   12 
 kernel/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h                                      |    4 
 kernel/arch/mips/bmips/dma.c                                                                              |    5 
 kernel/arch/parisc/kernel/syscalls/syscall.tbl                                                            |    2 
 kernel/drivers/hid/hid-input.c                                                                            |    8 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c                                                    |   18 
 kernel/fs/ceph/caps.c                                                                                     |   17 
 kernel/Documentation/admin-guide/hw-vuln/srso.rst                                                         |  133 
 kernel/drivers/crypto/n2_core.c                                                                           |    6 
 kernel/drivers/media/cec/core/cec-adap.c                                                                  |    3 
 kernel/drivers/media/tuners/mt2131.c                                                                      |    2 
 kernel/include/trace/hooks/dtask.h                                                                        |   24 
 kernel/net/netfilter/ipvs/ip_vs_ctl.c                                                                     |    4 
 kernel/arch/arm/mach-omap1/timer.c                                                                        |    2 
 kernel/fs/ext4/inode.c                                                                                    |  122 
 kernel/arch/x86/kernel/cpu/common.c                                                                       |  212 
 kernel/drivers/perf/arm_dsu_pmu.c                                                                         |    6 
 kernel/drivers/scsi/qla2xxx/qla_init.c                                                                    |   66 
 kernel/net/netfilter/ipset/ip_set_hash_netportnet.c                                                       |   41 
 kernel/arch/x86/kernel/traps.c                                                                            |    7 
 kernel/drivers/soc/ti/pm33xx.c                                                                            |   22 
 kernel/kernel/resource.c                                                                                  |   14 
 kernel/drivers/infiniband/hw/hfi1/trace_tx.h                                                              |  179 
 kernel/drivers/iio/dac/Makefile                                                                           |    2 
 kernel/drivers/gpu/drm/mediatek/mtk_drm_crtc.c                                                            |    2 
 kernel/drivers/mtd/nand/raw/brcmnand/brcmnand.h                                                           |   29 
 kernel/net/tipc/name_table.h                                                                              |    9 
 kernel/tools/testing/ktest/ktest.pl                                                                       |   49 
 kernel/drivers/remoteproc/stm32_rproc.c                                                                   |   14 
 kernel/drivers/rpmsg/virtio_rpmsg_bus.c                                                                   |   10 
 kernel/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi                                         |    4 
 kernel/tools/perf/util/dwarf-aux.c                                                                        |   25 
 kernel/arch/arm/boot/dts/rv1106-thunder-boot-emmc.dtsi                                                    |    6 
 kernel/fs/ext4/ioctl.c                                                                                    |   27 
 kernel/sound/soc/intel/boards/sof_rt5682.c                                                                |    3 
 kernel/arch/arm/mach-imx/cpu-imx31.c                                                                      |    1 
 kernel/arch/parisc/kernel/irq.c                                                                           |    2 
 kernel/drivers/video/rockchip/mpp_osal/Makefile                                                           |    2 
 kernel/drivers/net/usb/lan78xx.c                                                                          |  189 
 kernel/drivers/media/dvb-frontends/mb86a16.c                                                              |    2 
 kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c                                                  |    4 
 kernel/drivers/media/pci/saa7134/saa7134-vbi.c                                                            |    1 
 kernel/include/net/bluetooth/l2cap.h                                                                      |    1 
 kernel/drivers/scsi/aic94xx/aic94xx_task.c                                                                |    5 
 kernel/fs/ceph/super.c                                                                                    |   10 
 kernel/include/soc/rockchip/rockchip_dmc.h                                                                |    8 
 kernel/fs/ceph/super.h                                                                                    |    1 
 kernel/drivers/s390/crypto/zcrypt_api.c                                                                   |    1 
 kernel/kernel/time/tick-common.c                                                                          |    9 
 kernel/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c                                                  |   61 
 kernel/sound/soc/codecs/Makefile                                                                          |    2 
 kernel/drivers/net/netdevsim/dev.c                                                                        |    9 
 kernel/arch/sparc/include/uapi/asm/socket.h                                                               |    2 
 kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.c                                                           |    3 
 kernel/include/linux/netfilter/nfnetlink.h                                                                |    1 
 kernel/drivers/media/i2c/techpoint/techpoint_tp9951.c                                                     |  638 
 kernel/drivers/scsi/qla2xxx/qla_nvme.c                                                                    |   34 
 kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.h                                                           |    5 
 kernel/drivers/s390/block/dasd_int.h                                                                      |    2 
 kernel/arch/mips/configs/decstation_64_defconfig                                                          |    2 
 kernel/drivers/input/sensors/gyro/icm4260x_gyro.c                                                         |  211 
 kernel/tools/bpf/bpftool/prog.c                                                                           |   38 
 kernel/arch/powerpc/include/asm/plpar_wrappers.h                                                          |    1 
 kernel/drivers/clocksource/timer-cadence-ttc.c                                                            |   19 
 kernel/sound/core/pcm_compat.c                                                                            |    8 
 kernel/drivers/iio/imu/adis16400.c                                                                        |    1 
 kernel/drivers/scsi/lpfc/lpfc_sli.c                                                                       |    8 
 kernel/arch/s390/kvm/intercept.c                                                                          |   41 
 kernel/drivers/usb/gadget/function/f_mass_storage.c                                                       |    2 
 kernel/arch/arm64/boot/dts/mediatek/mt2712e.dtsi                                                          |   22 
 kernel/drivers/nfc/pn533/pn533.c                                                                          |    4 
 kernel/drivers/iio/accel/hid-sensor-accel-3d.c                                                            |    1 
 kernel/net/netrom/af_netrom.c                                                                             |   10 
 kernel/drivers/md/dm-thin-metadata.c                                                                      |   60 
 kernel/fs/jfs/jfs_dmap.c                                                                                  |   38 
 kernel/fs/udf/unicode.c                                                                                   |    2 
 kernel/drivers/clk/sprd/common.c                                                                          |    9 
 kernel/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c                                          |    2 
 kernel/include/uapi/linux/blkzoned.h                                                                      |   10 
 kernel/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c                                                  |   26 
 kernel/tools/testing/selftests/bpf/benchs/run_bench_rename.sh                                             |    2 
 kernel/drivers/irqchip/irq-gic-v3-its.c                                                                   |   85 
 kernel/fs/jbd2/transaction.c                                                                              |   53 
 kernel/drivers/infiniband/core/cm.c                                                                       |    3 
 kernel/drivers/pci/controller/dwc/pcie-designware.c                                                       |    2 
 kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c                                  |    6 
 kernel/arch/arm/boot/dts/exynos4.dtsi                                                                     |    2 
 kernel/include/trace/events/timer.h                                                                       |    9 
 kernel/drivers/media/dvb-frontends/isl6423.c                                                              |    2 
 kernel/drivers/input/touchscreen/raspberrypi-ts.c                                                         |    3 
 kernel/drivers/usb/gadget/udc/fsl_qe_udc.c                                                                |    6 
 kernel/net/wireless/scan.c                                                                                |  219 
 kernel/arch/x86/mm/pat/set_memory.c                                                                       |    4 
 kernel/drivers/media/dvb-frontends/lnbp22.c                                                               |    2 
 kernel/mm/filemap.c                                                                                       |   14 
 kernel/arch/s390/mm/extmem.c                                                                              |   12 
 kernel/Documentation/devicetree/bindings/phy/amlogic,g12a-usb2-phy.yaml                                   |    8 
 kernel/drivers/iio/adc/palmas_gpadc.c                                                                     |    2 
 kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.h                                  |    4 
 kernel/drivers/clk/qcom/gcc-sm8250.c                                                                      |   97 
 kernel/drivers/nvme/host/tcp.c                                                                            |   49 
 kernel/arch/parisc/kernel/traps.c                                                                         |    6 
 kernel/drivers/mtd/nand/raw/brcmnand/brcmnand.c                                                           |  147 
 kernel/drivers/net/wireless/marvell/mwifiex/scan.c                                                        |    6 
 kernel/drivers/spi/spi-geni-qcom.c                                                                        |    2 
 kernel/fs/binfmt_misc.c                                                                                   |    8 
 kernel/net/sched/cls_route.c                                                                              |    1 
 kernel/tools/perf/builtin-top.c                                                                           |    1 
 kernel/drivers/input/touchscreen/gt9xx/gt9xx_update.c                                                     |  195 
 kernel/drivers/spi/Kconfig                                                                                |   12 
 kernel/sound/hda/intel-dsp-config.c                                                                       |   17 
 kernel/drivers/media/dvb-frontends/stv0900_core.c                                                         |    2 
 kernel/fs/ocfs2/namei.c                                                                                   |    7 
 kernel/drivers/net/dsa/bcm_sf2.c                                                                          |    8 
 kernel/drivers/memstick/host/r592.c                                                                       |    6 
 kernel/net/can/j1939/address-claim.c                                                                      |   40 
 kernel/arch/arm64/include/asm/processor.h                                                                 |    4 
 kernel/arch/arm/boot/dts/Makefile                                                                         |    6 
 kernel/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts                                                       |    2 
 kernel/drivers/media/i2c/imx415.c                                                                         |  522 
 kernel/scripts/Kconfig.include                                                                            |    6 
 kernel/drivers/gpu/drm/i915/gvt/scheduler.c                                                               |    1 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h                                                |    3 
 kernel/fs/btrfs/scrub.c                                                                                   |    9 
 kernel/net/netfilter/nft_synproxy.c                                                                       |    4 
 kernel/drivers/gpu/drm/radeon/radeon_cs.c                                                                 |    3 
 kernel/include/uapi/linux/netfilter/nfnetlink_cttimeout.h                                                 |    2 
 kernel/arch/x86/include/asm/kvm_host.h                                                                    |    5 
 kernel/drivers/net/ethernet/broadcom/bnxt/bnxt.h                                                          |    1 
 kernel/drivers/usb/storage/ene_ub6250.c                                                                   |    2 
 kernel/drivers/media/i2c/imx219.c                                                                         |  259 
 kernel/drivers/media/i2c/os04d10.c                                                                        | 1510 
 kernel/drivers/net/ethernet/broadcom/bnxt/bnxt.c                                                          |   72 
 kernel/fs/cifs/cifssmb.c                                                                                  |    9 
 kernel/arch/powerpc/boot/dts/fsl/t1040rdb-rev-a.dts                                                       |    1 
 kernel/android/abi_gki_aarch64_virtual_device                                                             |   92 
 kernel/drivers/video/fbdev/via/via-core.c                                                                 |    9 
 kernel/drivers/media/platform/rockchip/isp/isp_params_v32.c                                               |   81 
 kernel/drivers/media/platform/rockchip/hdmirx/Kconfig                                                     |    1 
 kernel/net/batman-adv/distributed-arp-table.c                                                             |    2 
 kernel/drivers/hwmon/hwmon.c                                                                              |    7 
 kernel/arch/s390/kernel/nmi.c                                                                             |    2 
 kernel/arch/arm/configs/rk3308bs_aarch32_mipi_display.config                                              |    1 
 kernel/sound/pci/emu10k1/emupcm.c                                                                         |    4 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c                                                |  168 
 kernel/drivers/mmc/core/host.c                                                                            |   26 
 kernel/drivers/gpu/drm/radeon/si.c                                                                        |   37 
 kernel/net/netfilter/nf_flow_table_offload.c                                                              |    6 
 kernel/fs/nfsd/nfs4state.c                                                                                |   63 
 kernel/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c                                                   |    9 
 kernel/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c                                                        |   10 
 kernel/drivers/video/fbdev/au1200fb.c                                                                     |    6 
 kernel/drivers/net/ethernet/amd/xgbe/xgbe.h                                                               |    2 
 kernel/drivers/net/wireless/ath/ath9k/main.c                                                              |   11 
 kernel/drivers/net/bonding/bond_main.c                                                                    |   30 
 kernel/net/ipv4/syncookies.c                                                                              |    7 
 kernel/drivers/infiniband/hw/hfi1/sdma_txreq.h                                                            |    3 
 kernel/drivers/media/dvb-frontends/cx24120.c                                                              |    6 
 kernel/include/linux/blk-crypto.h                                                                         |    4 
 kernel/fs/affs/file.c                                                                                     |    2 
 kernel/sound/pci/hda/patch_via.c                                                                          |    3 
 kernel/arch/hexagon/kernel/traps.c                                                                        |    2 
 kernel/drivers/cpufreq/armada-37xx-cpufreq.c                                                              |    2 
 kernel/drivers/net/wireless/intersil/orinoco/hw.c                                                         |    2 
 kernel/drivers/gpu/drm/virtio/virtgpu_object.c                                                            |    6 
 kernel/drivers/vme/bridges/vme_tsi148.c                                                                   |    1 
 kernel/fs/nilfs2/super.c                                                                                  |   36 
 kernel/fs/attr.c                                                                                          |   90 
 kernel/drivers/media/i2c/maxim2c/Kconfig                                                                  |   46 
 kernel/include/linux/ftrace.h                                                                             |    2 
 kernel/net/openvswitch/meter.c                                                                            |    4 
 kernel/fs/btrfs/extent-tree.c                                                                             |   17 
 kernel/drivers/media/dvb-frontends/stv0367.c                                                              |    6 
 kernel/drivers/usb/storage/alauda.c                                                                       |   14 
 kernel/arch/arm/mach-sa1100/jornada720_ssp.c                                                              |    5 
 kernel/drivers/rknpu/rknpu_drv.c                                                                          |  873 
 kernel/security/apparmor/lsm.c                                                                            |    4 
 kernel/drivers/infiniband/sw/siw/siw_qp_tx.c                                                              |    4 
 kernel/drivers/irqchip/irq-gic.c                                                                          |   12 
 kernel/drivers/net/wireless/rsi/rsi_91x_sdio.c                                                            |    9 
 kernel/drivers/mfd/rkx110_x120/rkx120_dsi_tx.c                                                            |   57 
 kernel/drivers/media/dvb-frontends/ves1x93.c                                                              |    2 
 kernel/drivers/mfd/rkx110_x120/rkx120_dsi_tx.h                                                            |    2 
 kernel/fs/btrfs/delayed-inode.c                                                                           |   19 
 kernel/arch/ia64/kernel/setup.c                                                                           |    3 
 kernel/drivers/usb/host/xhci.c                                                                            |   17 
 kernel/drivers/clocksource/timer-ti-dm-systimer.c                                                         |    4 
 kernel/drivers/usb/host/xhci.h                                                                            |    4 
 kernel/drivers/crypto/amlogic/amlogic-gxl.h                                                               |    2 
 kernel/drivers/hwmon/ltc2945.c                                                                            |    2 
 kernel/net/ipv4/netfilter/ip_tables.c                                                                     |    3 
 kernel/drivers/char/hw_random/geode-rng.c                                                                 |   36 
 kernel/fs/proc/proc_sysctl.c                                                                              |   41 
 kernel/arch/arm/include/asm/bugs.h                                                                        |    4 
 kernel/drivers/media/i2c/lt6911uxc.h                                                                      |    5 
 kernel/drivers/net/wireless/ath/ath6kl/htc_mbox.c                                                         |   15 
 kernel/lib/errname.c                                                                                      |   22 
 kernel/drivers/media/i2c/ad5820.c                                                                         |   12 
 kernel/fs/overlayfs/super.c                                                                               |   11 
 kernel/drivers/media/i2c/lt6911uxc.c                                                                      |  279 
 kernel/kernel/kexec_internal.h                                                                            |   15 
 kernel/kernel/trace/trace_events_hist.c                                                                   |   27 
 kernel/drivers/net/ethernet/qlogic/qed/qed_dev.c                                                          |    5 
 kernel/drivers/net/wireless/intel/iwlwifi/mvm/tx.c                                                        |   12 
 kernel/drivers/pwm/pwm-rockchip.c                                                                         | 1290 
 kernel/drivers/media/i2c/maxim4c/remote_max9295.c                                                         |    2 
 kernel/fs/gfs2/glops.c                                                                                    |    6 
 kernel/drivers/mtd/ubi/fastmap-wl.c                                                                       |   12 
 kernel/drivers/net/wireless/marvell/mwifiex/util.c                                                        |   10 
 kernel/drivers/mmc/host/renesas_sdhi_core.c                                                               |   39 
 kernel/drivers/md/dm-bufio.c                                                                              |   17 
 kernel/include/asm-generic/pgtable-nopmd.h                                                                |    2 
 kernel/arch/x86/include/asm/virtext.h                                                                     |   22 
 kernel/net/core/lwt_bpf.c                                                                                 |    7 
 kernel/drivers/mfd/rkx110_x120/rkx120_reg.h                                                               |   73 
 kernel/drivers/net/ethernet/xircom/xirc2ps_cs.c                                                           |    5 
 kernel/drivers/spi/spi-nxp-fspi.c                                                                         |    7 
 kernel/drivers/tty/n_hdlc.c                                                                               |    1 
 kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c                                                  |   10 
 kernel/fs/udf/balloc.c                                                                                    |   33 
 kernel/Documentation/devicetree/bindings/spi/spi-rockchip-slave.yaml                                      |   92 
 kernel/drivers/s390/crypto/pkey_api.c                                                                     |    5 
 kernel/tools/bpf/bpftool/xlated_dumper.c                                                                  |    7 
 kernel/net/tipc/subscr.h                                                                                  |   11 
 kernel/arch/h8300/mm/fault.c                                                                              |    2 
 kernel/include/linux/ima.h                                                                                |    6 
 kernel/drivers/usb/gadget/udc/core.c                                                                      |   39 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp-linux.dts                                     |    4 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-s66-v10.dts                                            |   10 
 kernel/drivers/gpu/drm/mediatek/mtk_drm_drv.c                                                             |    1 
 kernel/drivers/media/dvb-frontends/stb6000.c                                                              |    2 
 kernel/arch/x86/include/asm/perf_event.h                                                                  |    2 
 kernel/drivers/remoteproc/qcom_sysmon.c                                                                   |    5 
 kernel/net/ipv6/sit.c                                                                                     |    8 
 kernel/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c                                            |   31 
 kernel/drivers/rpmsg/rpmsg_internal.h                                                                     |    4 
 kernel/drivers/pci/controller/cadence/pcie-cadence-host.c                                                 |   27 
 kernel/arch/xtensa/kernel/perf_event.c                                                                    |   17 
 kernel/sound/soc/codecs/wm8994.c                                                                          |    5 
 kernel/tools/testing/selftests/net/udpgso_bench_tx.c                                                      |   36 
 kernel/drivers/infiniband/hw/hns/hns_roce_mr.c                                                            |    8 
 kernel/include/trace/events/rcu.h                                                                         |    2 
 kernel/arch/arm/mach-ep93xx/timer-ep93xx.c                                                                |    3 
 kernel/drivers/scsi/pm8001/pm8001_init.c                                                                  |   51 
 kernel/fs/hfsplus/options.c                                                                               |    4 
 kernel/drivers/media/i2c/og02b10.c                                                                        | 1774 
 kernel/drivers/firmware/efi/libstub/random.c                                                              |   42 
 kernel/fs/ext4/resize.c                                                                                   |    6 
 kernel/drivers/net/wireless/mediatek/mt76/mt7915/init.c                                                   |    5 
 kernel/fs/exfat/file.c                                                                                    |    3 
 kernel/drivers/gpu/drm/armada/armada_drv.c                                                                |    1 
 kernel/drivers/dma/xilinx/xilinx_dma.c                                                                    |    4 
 kernel/include/linux/mailbox/zynqmp-ipi-message.h                                                         |    2 
 kernel/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml                                      |  158 
 kernel/arch/mips/kernel/setup.c                                                                           |   22 
 kernel/drivers/mmc/host/mmci.c                                                                            |    8 
 kernel/net/ipv4/xfrm4_input.c                                                                             |    1 
 kernel/drivers/clk/imx/clk.c                                                                              |    3 
 kernel/fs/ubifs/budget.c                                                                                  |    9 
 kernel/arch/x86/kernel/process.c                                                                          |    2 
 kernel/drivers/infiniband/hw/bnxt_re/qplib_res.c                                                          |   12 
 kernel/drivers/pwm/pwm-sprd.c                                                                             |    1 
 kernel/fs/ubifs/super.c                                                                                   |   17 
 kernel/samples/bpf/tcp_basertt_kern.c                                                                     |    2 
 kernel/arch/arm64/include/asm/exception.h                                                                 |    5 
 kernel/drivers/tty/serial/8250/8250_omap.c                                                                |   25 
 kernel/drivers/hid/intel-ish-hid/ishtp/dma-if.c                                                           |   10 
 kernel/drivers/i2c/busses/i2c-sh7760.c                                                                    |    3 
 kernel/drivers/mfd/rk806-core.c                                                                           |   10 
 kernel/drivers/tty/serial/sc16is7xx.c                                                                     |   68 
 kernel/drivers/scsi/3w-xxxx.c                                                                             |    4 
 kernel/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10.dtsi                                                |    8 
 kernel/drivers/mtd/ubi/build.c                                                                            |   23 
 kernel/drivers/media/dvb-frontends/mt312.c                                                                |    2 
 kernel/net/netfilter/nft_masq.c                                                                           |    2 
 kernel/drivers/net/wireless/marvell/mwifiex/uap_txrx.c                                                    |   30 
 kernel/drivers/net/usb/plusb.c                                                                            |    4 
 kernel/drivers/platform/x86/touchscreen_dmi.c                                                             |   75 
 kernel/scripts/asn1_compiler.c                                                                            |    2 
 kernel/arch/x86/kernel/cpu/amd.c                                                                          |  248 
 kernel/drivers/usb/typec/class.c                                                                          |    2 
 kernel/drivers/gpu/drm/drm_atomic.c                                                                       |   12 
 kernel/drivers/usb/gadget/configfs.c                                                                      |   11 
 kernel/arch/arm/boot/dts/imx7s.dtsi                                                                       |   15 
 kernel/drivers/platform/x86/intel-hid.c                                                                   |   21 
 kernel/arch/s390/mm/vmem.c                                                                                |    6 
 kernel/drivers/misc/vmw_vmci/vmci_host.c                                                                  |    8 
 kernel/drivers/spi/spi-synquacer.c                                                                        |    7 
 kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c                                                      |   30 
 kernel/drivers/usb/gadget/function/uvc.h                                                                  |    1 
 kernel/mm/hugetlb.c                                                                                       |   51 
 kernel/arch/arm/boot/dts/rv1106g-evb2-v12-wakeup.dts                                                      |   66 
 kernel/drivers/char/ipmi/ipmi_si_intf.c                                                                   |   32 
 kernel/drivers/net/ethernet/microchip/lan743x_main.c                                                      |   21 
 kernel/drivers/target/iscsi/iscsi_target_configfs.c                                                       |   54 
 kernel/net/sunrpc/clnt.c                                                                                  |   13 
 kernel/drivers/isdn/mISDN/dsp_cmx.c                                                                       |    2 
 kernel/drivers/media/radio/si470x/radio-si470x-usb.c                                                      |    4 
 kernel/drivers/net/ethernet/ti/netcp_core.c                                                               |    2 
 kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c                                               |   91 
 kernel/include/linux/kernel_stat.h                                                                        |    2 
 kernel/drivers/base/power/power.h                                                                         |    8 
 kernel/net/netlink/diag.c                                                                                 |    7 
 kernel/drivers/cpufreq/powernow-k8.c                                                                      |    3 
 kernel/drivers/tty/serial/altera_uart.c                                                                   |   21 
 kernel/drivers/input/touchscreen/goodix.c                                                                 |   14 
 kernel/kernel/irq/manage.c                                                                                |   17 
 kernel/drivers/media/dvb-frontends/dib3000mc.c                                                            |    2 
 kernel/drivers/usb/host/ohci-platform.c                                                                   |    4 
 kernel/arch/arm64/boot/dts/ti/k3-am65-main.dtsi                                                           |    1 
 kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c                                                            |   14 
 kernel/drivers/mfd/display-serdes/serdes-irq.c                                                            |   15 
 kernel/drivers/mfd/display-serdes/serdes-bridge-split.c                                                   |  371 
 kernel/drivers/net/ethernet/xilinx/xilinx_emaclite.c                                                      |    2 
 kernel/drivers/hid/hid-quirks.c                                                                           |    2 
 kernel/drivers/iio/imu/adis16475.c                                                                        |    6 
 kernel/arch/powerpc/platforms/powernv/pci-ioda.c                                                          |    3 
 kernel/drivers/net/wireguard/netlink.c                                                                    |   14 
 kernel/arch/arm/boot/dts/rv1126.dtsi                                                                      |   16 
 kernel/drivers/acpi/button.c                                                                              |    9 
 kernel/arch/sh/boards/mach-se/7724/setup.c                                                                |    6 
 kernel/drivers/net/wireless/intel/iwlwifi/mvm/ops.c                                                       |    5 
 kernel/drivers/gpu/drm/vc4/vc4_regs.h                                                                     |    6 
 kernel/drivers/media/i2c/jaguar1_drv/jaguar1_v4l2.c                                                       |  371 
 kernel/drivers/usb/dwc3/gadget.c                                                                          |  115 
 kernel/tools/testing/selftests/netfilter/nft_nat.sh                                                       |    2 
 kernel/fs/nfsd/netns.h                                                                                    |    6 
 kernel/include/asm-generic/word-at-a-time.h                                                               |    2 
 kernel/include/uapi/drm/drm_fourcc.h                                                                      |   44 
 kernel/drivers/media/dvb-frontends/tua6100.c                                                              |    2 
 kernel/fs/cifs/misc.c                                                                                     |    4 
 kernel/net/netfilter/ipset/ip_set_hash_net.c                                                              |   17 
 kernel/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c                                              |    4 
 kernel/fs/ocfs2/move_extents.c                                                                            |   34 
 kernel/drivers/infiniband/hw/hfi1/user_sdma.h                                                             |    7 
 kernel/fs/nilfs2/bmap.c                                                                                   |   16 
 kernel/arch/powerpc/kernel/iommu.c                                                                        |   17 
 kernel/arch/arm/boot/dts/omap3-n900.dts                                                                   |   40 
 kernel/drivers/gpu/drm/amd/amdkfd/kfd_events.c                                                            |    9 
 kernel/arch/nds32/kernel/traps.c                                                                          |    8 
 kernel/drivers/infiniband/hw/hfi1/user_sdma.c                                                             |  651 
 kernel/include/linux/fs.h                                                                                 |   65 
 kernel/arch/s390/kernel/dumpstack.c                                                                       |    2 
 kernel/include/linux/pm_wakeirq.h                                                                         |    9 
 kernel/crypto/tcrypt.c                                                                                    |    9 
 kernel/fs/pstore/zone.c                                                                                   |    2 
 kernel/drivers/infiniband/hw/hfi1/trace_mmu.h                                                             |    4 
 kernel/sound/soc/soc-pcm.c                                                                                |   20 
 kernel/tools/testing/selftests/net/forwarding/ethtool.sh                                                  |    2 
 kernel/kernel/dma/remap.c                                                                                 |    4 
 kernel/sound/pci/asihpi/hpioctl.c                                                                         |    2 
 kernel/sound/soc/rockchip/rockchip_spdif.c                                                                |    1 
 kernel/arch/arm/boot/dts/omap4460.dtsi                                                                    |    1 
 kernel/net/sched/sch_fq_pie.c                                                                             |   35 
 kernel/Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml                                       |    2 
 kernel/kernel/time/posix-timers.c                                                                         |   49 
 kernel/Documentation/devicetree/bindings/sound/tas2764.yaml                                               |    6 
 kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c                                |    6 
 kernel/drivers/net/wireless/ath/ath10k/pci.c                                                              |   29 
 kernel/drivers/net/wireless/microchip/wilc1000/hif.c                                                      |    8 
 kernel/net/ipv4/tcp_ipv4.c                                                                                |    2 
 kernel/include/uapi/linux/rk-isp2-config.h                                                                |   13 
 kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h                                |    4 
 kernel/fs/ubifs/ubifs.h                                                                                   |    5 
 kernel/drivers/media/i2c/techpoint/techpoint_tp9951.h                                                     |   76 
 kernel/sound/soc/codecs/rt711.h                                                                           |   29 
 kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c                                             |    8 
 kernel/sound/soc/codecs/rt711.c                                                                           |   30 
 kernel/security/apparmor/policy_ns.c                                                                      |    2 
 kernel/drivers/bus/mhi/host/pci_generic.c                                                                 |  345 
 kernel/drivers/net/dsa/mv88e6xxx/global1.h                                                                |    1 
 kernel/tools/bpf/bpftool/feature.c                                                                        |   24 
 kernel/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi                                                   |    2 
 kernel/drivers/video/backlight/bd6107.c                                                                   |    2 
 kernel/tools/testing/selftests/bpf/progs/test_cls_redirect.h                                              |    9 
 kernel/net/core/skbuff.c                                                                                  |   59 
 kernel/drivers/media/dvb-frontends/ds3000.c                                                               |    2 
 kernel/sound/pci/hda/hda_codec.c                                                                          |    1 
 kernel/drivers/scsi/qedf/qedf_dbg.h                                                                       |    2 
 kernel/net/ipv4/tcp_output.c                                                                              |   11 
 kernel/include/linux/debugfs.h                                                                            |   19 
 kernel/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c                                              |    2 
 kernel/arch/arm/kernel/traps.c                                                                            |    2 
 kernel/drivers/gpu/arm/bifrost/csf/mali_kbase_csf_kcpu.c                                                  |    8 
 kernel/drivers/net/dsa/mv88e6xxx/global1.c                                                                |   31 
 kernel/drivers/rpmsg/rockchip_rpmsg_softirq.c                                                             |  129 
 kernel/drivers/scsi/scsi_transport_iscsi.c                                                                |  130 
 kernel/kernel/sched/loadavg.c                                                                             |    1 
 kernel/drivers/isdn/mISDN/dsp_core.c                                                                      |    2 
 kernel/drivers/net/wireless/intel/iwlwifi/pcie/trans.c                                                    |    5 
 kernel/drivers/gpu/drm/drm_fb_helper.c                                                                    |    3 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c                                     |    3 
 kernel/drivers/crypto/nx/nx.h                                                                             |    4 
 kernel/drivers/gpu/drm/i915/gt/intel_workarounds.c                                                        |   32 
 kernel/net/smc/smc_rx.c                                                                                   |    4 
 kernel/drivers/remoteproc/qcom_q6v5_mss.c                                                                 |   59 
 kernel/arch/arm/boot/dts/imx7d-sdb.dts                                                                    |    2 
 kernel/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c                                              |   57 
 kernel/drivers/net/ethernet/intel/igb/igb_ethtool.c                                                       |    3 
 kernel/drivers/net/ethernet/myricom/myri10ge/myri10ge.c                                                   |    1 
 kernel/fs/exfat/exfat_fs.h                                                                                |    9 
 kernel/include/uapi/linux/swab.h                                                                          |    2 
 kernel/tools/perf/tests/shell/test_uprobe_from_different_cu.sh                                            |   83 
 kernel/net/sched/act_skbmod.c                                                                             |    2 
 kernel/arch/mips/cavium-octeon/executive/cvmx-helper-board.c                                              |    2 
 kernel/drivers/gpu/drm/msm/dp/dp_aux.c                                                                    |    4 
 kernel/drivers/media/platform/exynos4-is/fimc-core.c                                                      |    2 
 kernel/drivers/scsi/qedf/qedf_io.c                                                                        |   10 
 kernel/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt                                           |    2 
 kernel/sound/soc/generic/audio-graph-card.c                                                               |    4 
 kernel/arch/arm/mach-omap2/timer.c                                                                        |    1 
 kernel/net/sched/Kconfig                                                                                  |   39 
 kernel/tools/testing/selftests/ftrace/ftracetest                                                          |    8 
 kernel/drivers/hid/hid-google-hammer.c                                                                    |    2 
 kernel/net/xdp/xdp_umem.c                                                                                 |   13 
 kernel/drivers/usb/serial/option.c                                                                        |   70 
 kernel/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c                                                        |    6 
 kernel/arch/x86/include/asm/microcode.h                                                                   |    5 
 kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c                                                   |   23 
 kernel/arch/powerpc/include/asm/firmware.h                                                                |    7 
 kernel/drivers/soc/rockchip/pm_domains.c                                                                  |  194 
 kernel/net/netfilter/ipvs/ip_vs_xmit.c                                                                    |    2 
 kernel/net/ipv6/ping.c                                                                                    |    9 
 kernel/kernel/trace/bpf_trace.c                                                                           |   26 
 kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c                                              |    2 
 kernel/arch/x86/kvm/hyperv.c                                                                              |   15 
 kernel/fs/exfat/balloc.c                                                                                  |    6 
 kernel/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c                                                 |    2 
 kernel/drivers/target/iscsi/iscsi_target_nego.c                                                           |    4 
 kernel/drivers/mfd/stmpe.c                                                                                |    4 
 kernel/fs/btrfs/block-group.c                                                                             |   23 
 kernel/Documentation/admin-guide/security-bugs.rst                                                        |   37 
 kernel/drivers/gpu/drm/mediatek/mtk_dsi.c                                                                 |    2 
 kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c                                          |    7 
 kernel/kernel/trace/trace_uprobe.c                                                                        |    6 
 kernel/drivers/mtd/nand/spi/core.c                                                                        |    1 
 kernel/arch/arm64/boot/dts/mediatek/mt7622.dtsi                                                           |    1 
 kernel/drivers/power/supply/power_supply_sysfs.c                                                          |    3 
 kernel/drivers/irqchip/irq-mips-gic.c                                                                     |   63 
 kernel/drivers/s390/block/dasd_3990_erp.c                                                                 |    2 
 kernel/fs/cifs/smb2pdu.c                                                                                  |   15 
 kernel/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h                                                         |    1 
 kernel/drivers/phy/rockchip/phy-rockchip-naneng-usb2.c                                                    |    8 
 kernel/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c                                                         |   46 
 kernel/drivers/usb/gadget/function/uvc_video.c                                                            |    9 
 kernel/fs/ceph/locks.c                                                                                    |    4 
 kernel/arch/arm/configs/rv1106-tb-nofastae.config                                                         |    2 
 kernel/arch/s390/include/asm/cpu_mf.h                                                                     |   31 
 kernel/drivers/mfd/pcf50633-adc.c                                                                         |    7 
 kernel/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c                                                 |   13 
 kernel/include/uapi/linux/rk_hdmirx_config.h                                                              |    3 
 kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h                                                    |   10 
 kernel/net/dccp/dccp.h                                                                                    |    1 
 kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c                                                           |    9 
 kernel/Documentation/core-api/kernel-api.rst                                                              |    7 
 kernel/drivers/media/i2c/imx464.c                                                                         |    2 
 kernel/drivers/net/wireless/marvell/mwifiex/sdio.c                                                        |    3 
 kernel/drivers/input/joystick/Kconfig                                                                     |    1 
 kernel/net/mac80211/agg-tx.c                                                                              |    6 
 kernel/sound/soc/fsl/fsl_sai.c                                                                            |    3 
 kernel/arch/x86/crypto/ghash-clmulni-intel_glue.c                                                         |    6 
 kernel/sound/soc/fsl/fsl_sai.h                                                                            |    1 
 kernel/sound/soc/rockchip/rockchip_multi_dais_pcm.c                                                       |  366 
 kernel/drivers/net/ethernet/broadcom/bgmac-bcma.c                                                         |    6 
 kernel/drivers/net/ethernet/stmicro/stmmac/dwmac5.c                                                       |    3 
 kernel/net/ipv6/udplite.c                                                                                 |   11 
 kernel/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi                                                    |   29 
 kernel/build.config.gki.aarch64                                                                           |    3 
 kernel/drivers/scsi/megaraid/megaraid_sas_fusion.c                                                        |    4 
 kernel/arch/riscv/kernel/traps.c                                                                          |   16 
 kernel/sound/soc/fsl/fsl_micfil.c                                                                         |   16 
 kernel/drivers/mfd/display-serdes/maxim/maxim-max96752.c                                                  |  527 
 kernel/tools/perf/util/symbol-elf.c                                                                       |    4 
 kernel/net/bluetooth/l2cap_sock.c                                                                         |   10 
 kernel/drivers/clk/qcom/gcc-qcs404.c                                                                      |   24 
 kernel/sound/oss/dmasound/dmasound.h                                                                      |    6 
 kernel/fs/exfat/super.c                                                                                   |    3 
 kernel/drivers/irqchip/irq-gic-v2m.c                                                                      |    2 
 kernel/arch/powerpc/Makefile                                                                              |   10 
 kernel/drivers/isdn/hardware/mISDN/hfcsusb.c                                                              |   12 
 kernel/include/net/xfrm.h                                                                                 |    1 
 kernel/fs/squashfs/xattr_id.c                                                                             |    2 
 kernel/net/unix/scm.c                                                                                     |    6 
 kernel/arch/nios2/kernel/traps.c                                                                          |    4 
 kernel/drivers/net/wireless/mac80211_hwsim.c                                                              |    7 
 kernel/drivers/soundwire/bus.c                                                                            |   31 
 kernel/drivers/iio/light/tsl2772.c                                                                        |    1 
 kernel/drivers/media/platform/sti/bdisp/bdisp-v4l2.c                                                      |    2 
 kernel/drivers/pinctrl/pinctrl-at91.c                                                                     |    2 
 kernel/fs/proc/task_mmu.c                                                                                 |    4 
 kernel/sound/drivers/mts64.c                                                                              |    3 
 kernel/fs/hfsplus/super.c                                                                                 |    4 
 kernel/arch/arm64/boot/dts/rockchip/rk3588s-evb8-lp4x.dtsi                                                |    4 
 kernel/drivers/mfd/display-serdes/maxim/maxim-max96752.h                                                  |   31 
 kernel/fs/ocfs2/file.c                                                                                    |   12 
 kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c                                                   |    8 
 kernel/fs/btrfs/ctree.h                                                                                   |    2 
 kernel/net/sched/sch_ingress.c                                                                            |   16 
 kernel/drivers/block/loop.c                                                                               |    8 
 kernel/include/acpi/apei.h                                                                                |    4 
 kernel/drivers/net/ethernet/3com/3c589_cs.c                                                               |   11 
 kernel/drivers/gpu/drm/meson/meson_drv.c                                                                  |   20 
 kernel/drivers/s390/block/dasd_fba.c                                                                      |    7 
 kernel/include/media/v4l2-mem2mem.h                                                                       |   18 
 kernel/drivers/power/supply/ucs1002_power.c                                                               |    3 
 kernel/fs/xfs/xfs_iops.c                                                                                  |   56 
 kernel/drivers/media/pci/dm1105/dm1105.c                                                                  |    1 
 kernel/fs/btrfs/ctree.c                                                                                   |   36 
 kernel/fs/xfs/xfs_iops.h                                                                                  |    1 
 kernel/drivers/soundwire/cadence_master.h                                                                 |   13 
 kernel/drivers/video/rockchip/vtunnel/Makefile                                                            |    3 
 kernel/drivers/clk/sunxi-ng/ccu_mmc_timing.c                                                              |    2 
 kernel/fs/binfmt_elf_fdpic.c                                                                              |   10 
 kernel/drivers/scsi/mvsas/mv_sas.c                                                                        |   10 
 kernel/drivers/soundwire/cadence_master.c                                                                 |   43 
 kernel/drivers/clocksource/sh_cmt.c                                                                       |  102 
 kernel/sound/soc/rockchip/rockchip_multi_dais.c                                                           |   74 
 kernel/drivers/tty/serial/fsl_lpuart.c                                                                    |   90 
 kernel/drivers/usb/gadget/function/uvc_configfs.c                                                         |   59 
 kernel/arch/arm/boot/dts/exynos5250.dtsi                                                                  |    2 
 kernel/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h                                       |    1 
 kernel/drivers/firmware/stratix10-svc.c                                                                   |    8 
 kernel/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c                                       |   28 
 kernel/drivers/platform/x86/asus-nb-wmi.c                                                                 |    3 
 kernel/drivers/infiniband/core/cma_configfs.c                                                             |    2 
 kernel/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts                                                          |    4 
 kernel/net/kcm/kcmsock.c                                                                                  |   15 
 kernel/net/core/datagram.c                                                                                |   15 
 kernel/arch/parisc/kernel/processor.c                                                                     |   18 
 kernel/arch/x86/xen/smp.c                                                                                 |   24 
 kernel/drivers/net/wireless/marvell/mwifiex/11n.c                                                         |    6 
 kernel/tools/testing/selftests/bpf/prog_tests/btf.c                                                       |   28 
 kernel/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c                                                   |   10 
 kernel/arch/arm/boot/dts/imx6ul.dtsi                                                                      |    6 
 kernel/include/uapi/linux/bpf.h                                                                           |    4 
 kernel/fs/btrfs/file-item.c                                                                               |    4 
 kernel/arch/mips/include/asm/pgtable-64.h                                                                 |    8 
 kernel/drivers/mmc/host/vub300.c                                                                          |   16 
 kernel/drivers/net/dsa/mv88e6xxx/chip.c                                                                   |   40 
 kernel/drivers/net/bonding/bond_3ad.c                                                                     |    1 
 kernel/include/media/dvbdev.h                                                                             |   47 
 kernel/arch/arm64/boot/dts/renesas/r8a77990.dtsi                                                          |    3 
 kernel/drivers/iio/imu/adis16480.c                                                                        |    1 
 rockdev/baseparameter                                                                                     |    0 
 kernel/arch/arm64/kernel/suspend.c                                                                        |    2 
 kernel/drivers/net/Makefile                                                                               |    2 
 kernel/drivers/platform/chrome/cros_usbpd_notify.c                                                        |    6 
 kernel/drivers/net/ethernet/qlogic/qede/qede_fp.c                                                         |   10 
 kernel/drivers/usb/storage/uas-detect.h                                                                   |   13 
 kernel/drivers/tee/amdtee/core.c                                                                          |   29 
 kernel/lib/clz_ctz.c                                                                                      |   32 
 kernel/drivers/net/dsa/sja1105/sja1105_main.c                                                             |   38 
 kernel/fs/ocfs2/dlmglue.c                                                                                 |    8 
 kernel/arch/x86/include/asm/microcode_amd.h                                                               |    6 
 kernel/drivers/regulator/fixed.c                                                                          |    2 
 kernel/drivers/hwtracing/coresight/coresight-etm-perf.c                                                   |    1 
 kernel/include/linux/irq.h                                                                                |    4 
 kernel/drivers/net/usb/qmi_wwan.c                                                                         |    6 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi                          |   45 
 kernel/drivers/media/dvb-frontends/mb86a20s.c                                                             |    2 
 kernel/drivers/pci/quirks.c                                                                               |   25 
 kernel/drivers/watchdog/dw_wdt.c                                                                          |   14 
 kernel/arch/ia64/include/asm/pgtable.h                                                                    |    4 
 kernel/fs/nfsd/nfssvc.c                                                                                   |   37 
 kernel/drivers/clk/qcom/gpucc-sc7180.c                                                                    |    7 
 kernel/drivers/iommu/fsl_pamu.c                                                                           |    2 
 kernel/security/device_cgroup.c                                                                           |   35 
 kernel/drivers/usb/misc/sisusbvga/sisusb.c                                                                |   14 
 kernel/drivers/media/dvb-core/dvb_ca_en50221.c                                                            |   51 
 kernel/fs/gfs2/super.c                                                                                    |   42 
 kernel/net/bluetooth/hci_sock.c                                                                           |   48 
 kernel/sound/soc/fsl/fsl_mqs.c                                                                            |   15 
 kernel/arch/arm/boot/dts/imx28.dtsi                                                                       |    2 
 kernel/drivers/mmc/host/sdhci_am654.c                                                                     |    4 
 kernel/drivers/media/i2c/maxim2c/maxim2c_v4l2.c                                                           |  992 
 kernel/arch/powerpc/perf/hv-gpci.h                                                                        |    1 
 kernel/fs/nfs/nfs4xdr.c                                                                                   |   12 
 kernel/include/linux/perf_event.h                                                                         |   22 
 kernel/drivers/media/usb/go7007/go7007-i2c.c                                                              |    2 
 kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy.c                                                      |   86 
 kernel/drivers/net/phy/at803x.c                                                                           |    2 
 kernel/scripts/gdb/linux/utils.py                                                                         |    5 
 kernel/arch/arm/include/asm/thread_info.h                                                                 |   13 
 kernel/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi                                                      |    2 
 kernel/drivers/net/phy/mscc/mscc.h                                                                        |    1 
 kernel/arch/s390/include/asm/percpu.h                                                                     |    2 
 kernel/drivers/mfd/rkx110_x120/rkx110_x120_display.h                                                      |   19 
 kernel/arch/arm/boot/dts/imx35.dtsi                                                                       |    2 
 kernel/drivers/char/tpm/tpm_vtpm_proxy.c                                                                  |   30 
 kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c                                              |    3 
 kernel/arch/arm64/boot/dts/renesas/r8a774c0.dtsi                                                          |    3 
 kernel/drivers/mfd/rkx110_x120/rkx110_x120_display.c                                                      |  275 
 kernel/drivers/isdn/hardware/mISDN/hfcmulti.c                                                             |   19 
 kernel/drivers/media/i2c/maxim2c/remote_max96715.c                                                        |  381 
 kernel/fs/nfsd/nfsctl.c                                                                                   |   14 
 kernel/drivers/mtd/nand/spi/xtx.c                                                                         |   27 
 kernel/tools/perf/perf-completion.sh                                                                      |   11 
 kernel/kernel/sched/deadline.c                                                                            |   71 
 kernel/Documentation/powerpc/associativity.rst                                                            |  105 
 kernel/drivers/gpu/drm/bridge/tc358762.c                                                                  |    2 
 kernel/mm/mempolicy.c                                                                                     |    5 
 kernel/drivers/net/ethernet/sfc/ef100_netdev.c                                                            |    6 
 kernel/arch/arm/boot/dts/rv1106g-evb2-v12-nofastae-spi-nor.dts                                            |    2 
 kernel/drivers/pwm/pwm-hibvt.c                                                                            |    1 
 kernel/drivers/net/wireless/intel/iwlegacy/4965-mac.c                                                     |   12 
 kernel/include/linux/vt_buffer.h                                                                          |    2 
 kernel/drivers/perf/fsl_imx8_ddr_perf.c                                                                   |   24 
 kernel/drivers/soc/ux500/ux500-soc-id.c                                                                   |   10 
 kernel/drivers/net/phy/mdio_bus.c                                                                         |    7 
 kernel/net/ipv6/tcp_ipv6.c                                                                                |   21 
 kernel/arch/arm64/boot/dts/amlogic/meson-gx.dtsi                                                          |   12 
 kernel/arch/powerpc/platforms/pseries/eeh_pseries.c                                                       |   14 
 kernel/fs/cifs/link.c                                                                                     |    1 
 kernel/arch/arm/boot/dts/rv1106-tb-nofastae-emmc.dtsi                                                     |    6 
 kernel/drivers/pci/controller/pcie-rockchip.c                                                             |   17 
 kernel/arch/powerpc/perf/hv-gpci.c                                                                        |   33 
 kernel/fs/btrfs/block-rsv.c                                                                               |    3 
 kernel/drivers/pci/controller/pcie-rockchip.h                                                             |   11 
 kernel/drivers/media/dvb-frontends/s5h1409.c                                                              |    2 
 kernel/net/qrtr/ns.c                                                                                      |   20 
 kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c                                                        |   13 
 kernel/tools/perf/builtin-script.c                                                                        |   34 
 kernel/drivers/media/test-drivers/vidtv/vidtv_bridge.c                                                    |   24 
 kernel/drivers/scsi/pm8001/pm8001_hwi.c                                                                   |   18 
 kernel/drivers/mmc/host/sdhci-of-esdhc.c                                                                  |   24 
 kernel/drivers/clk/qcom/reset.h                                                                           |    2 
 kernel/drivers/staging/rtl8712/wifi.h                                                                     |   15 
 kernel/drivers/media/dvb-frontends/m88rs2000.c                                                            |    2 
 kernel/include/linux/sysctl.h                                                                             |   19 
 kernel/drivers/clk/qcom/reset.c                                                                           |    9 
 kernel/drivers/ntb/hw/amd/ntb_hw_amd.c                                                                    |    7 
 kernel/drivers/mfd/rkx110_x120/hal/cru_rkx111.c                                                           |    5 
 kernel/net/sched/act_pedit.c                                                                              |    3 
 kernel/drivers/media/dvb-frontends/stb0899_drv.c                                                          |    2 
 kernel/drivers/char/tpm/tpm_tis.c                                                                         |   25 
 kernel/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c                                                   |    3 
 kernel/drivers/net/ethernet/sfc/efx.c                                                                     |   44 
 kernel/drivers/net/phy/sfp.c                                                                              |   13 
 kernel/drivers/gpu/drm/i915/gvt/mmio.h                                                                    |    4 
 kernel/drivers/md/dm-verity-target.c                                                                      |   16 
 kernel/net/rose/af_rose.c                                                                                 |    8 
 kernel/Documentation/devicetree/bindings/usb/cdns,usb3.yaml                                               |    2 
 kernel/fs/nfsd/nfs4proc.c                                                                                 |   28 
 kernel/net/dccp/ipv6.c                                                                                    |   36 
 kernel/drivers/iio/adc/twl6030-gpadc.c                                                                    |   32 
 kernel/drivers/irqchip/irq-vic.c                                                                          |    4 
 kernel/drivers/net/ethernet/neterion/s2io.c                                                               |    2 
 kernel/arch/arm64/include/asm/mte.h                                                                       |    5 
 kernel/drivers/nvme/host/nvme.h                                                                           |    2 
 kernel/drivers/scsi/dpt_i2o.c                                                                             |  278 
 kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-common.h                                               |    6 
 kernel/drivers/media/i2c/maxim2c/remote_max9295.c                                                         |  331 
 kernel/drivers/net/wireless/ath/ath9k/htc.h                                                               |   30 
 kernel/fs/nfs/nfs4_fs.h                                                                                   |    1 
 kernel/drivers/s390/block/dasd_diag.c                                                                     |    7 
 kernel/drivers/virtio/virtio_mmio.c                                                                       |    8 
 kernel/drivers/gpu/drm/rockchip/inno_hdmi.c                                                               |    2 
 kernel/drivers/scsi/qla2xxx/qla_dbg.c                                                                     |   18 
 kernel/drivers/mmc/host/mxcmmc.c                                                                          |    4 
 kernel/drivers/acpi/bus.c                                                                                 |    2 
 kernel/fs/ceph/metric.c                                                                                   |    2 
 kernel/tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c                                     |   80 
 kernel/arch/xtensa/platforms/iss/network.c                                                                |    6 
 kernel/drivers/media/platform/rockchip/isp/capture_v32.c                                                  |    8 
 kernel/drivers/pci/controller/dwc/pcie-tegra194.c                                                         |   13 
 kernel/arch/arm/boot/dts/imx6sl.dtsi                                                                      |    5 
 kernel/net/ipv4/fib_frontend.c                                                                            |    3 
 kernel/arch/arm/configs/rk3128_linux_spi_nand.config                                                      |    5 
 kernel/drivers/hwmon/mlxreg-fan.c                                                                         |    6 
 /dev/null                                                                                                 |  738 
 kernel/fs/afs/dir.c                                                                                       |    3 
 kernel/drivers/media/i2c/ov5640.c                                                                         |    6 
 kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-two-vp-two-separate-single-channel-lvds.dts      |  173 
 kernel/drivers/target/iscsi/iscsi_target.c                                                                |   22 
 kernel/net/sched/cls_api.c                                                                                |   16 
 kernel/drivers/rtc/rtc-snvs.c                                                                             |   16 
 kernel/lib/usercopy.c                                                                                     |    7 
 kernel/drivers/cpufreq/cpufreq-dt-platdev.c                                                               |    1 
 kernel/drivers/rknpu/include/rknpu_devfreq.h                                                              |   46 
 kernel/drivers/usb/gadget/function/f_fs.c                                                                 |    2 
 kernel/arch/x86/kernel/cpu/bugs.c                                                                         |  437 
 kernel/drivers/media/platform/qcom/venus/firmware.c                                                       |   28 
 kernel/drivers/iio/imu/adis_buffer.c                                                                      |   10 
 kernel/arch/arm/boot/dts/exynos5422-odroidhc1.dts                                                         |   10 
 kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h                                                    |    1 
 kernel/fs/f2fs/segment.h                                                                                  |    9 
 kernel/arch/arm/mach-omap2/powerdomain.c                                                                  |    2 
 kernel/fs/f2fs/segment.c                                                                                  |   86 
 kernel/drivers/media/usb/dvb-usb/dvb-usb-init.c                                                           |    4 
 kernel/net/ipv6/ipv6_sockglue.c                                                                           |   20 
 kernel/drivers/dma/Kconfig                                                                                |    2 
 kernel/include/drm/drm_bridge.h                                                                           |    4 
 kernel/fs/fuse/fuse_i.h                                                                                   |    3 
 kernel/drivers/hwtracing/coresight/coresight-trbe.c                                                       |    1 
 kernel/drivers/infiniband/hw/hns/hns_roce_hem.h                                                           |   15 
 kernel/drivers/crypto/rockchip/cryptodev_linux/zc.c                                                       |    2 
 kernel/drivers/infiniband/hw/hns/hns_roce_hem.c                                                           |  131 
 kernel/drivers/pinctrl/intel/pinctrl-cherryview.c                                                         |   20 
 kernel/drivers/staging/rtl8712/xmit_linux.c                                                               |    6 
 kernel/tools/arch/x86/include/asm/cpufeatures.h                                                           |   20 
 kernel/drivers/clk/qcom/gpucc-sdm845.c                                                                    |    7 
 kernel/sound/usb/line6/pod.c                                                                              |    3 
 kernel/drivers/infiniband/hw/mlx5/qp.c                                                                    |   51 
 kernel/arch/parisc/kernel/real2.S                                                                         |    5 
 kernel/drivers/clk/qcom/gcc-mdm9615.c                                                                     |    2 
 kernel/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic_event_syntax_errors.tc |   35 
 kernel/drivers/ntb/hw/idt/ntb_hw_idt.c                                                                    |    7 
 kernel/drivers/gpu/drm/i915/i915_reg.h                                                                    |    3 
 kernel/drivers/media/dvb-frontends/l64781.c                                                               |    2 
 kernel/drivers/md/raid1.c                                                                                 |    4 
 kernel/security/smack/smack.h                                                                             |    1 
 kernel/drivers/media/dvb-frontends/helene.c                                                               |    4 
 kernel/arch/arm/boot/dts/exynos5410-odroidxu.dts                                                          |    1 
 kernel/drivers/soc/rockchip/rockchip_system_monitor.c                                                     |   93 
 kernel/arch/x86/kernel/kprobes/opt.c                                                                      |   43 
 kernel/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c                                                |    2 
 kernel/fs/nfs/nfs3xdr.c                                                                                   |    2 
 kernel/arch/x86/include/asm/required-features.h                                                           |    4 
 kernel/fs/cifs/smb2ops.c                                                                                  |  164 
 kernel/fs/hfs/trans.c                                                                                     |    2 
 kernel/drivers/net/ethernet/intel/igc/igc.h                                                               |   39 
 kernel/fs/f2fs/data.c                                                                                     |   14 
 kernel/fs/verity/verify.c                                                                                 |   12 
 kernel/drivers/tty/tty.h                                                                                  |  117 
 kernel/arch/arm/mach-imx/cpu-imx5.c                                                                       |    1 
 kernel/drivers/media/pci/netup_unidvb/netup_unidvb_core.c                                                 |   19 
 kernel/sound/pci/hda/hda_bind.c                                                                           |    2 
 kernel/net/ipv4/sysctl_net_ipv4.c                                                                         |    2 
 kernel/drivers/crypto/ccree/cc_debugfs.c                                                                  |    2 
 kernel/drivers/net/ethernet/intel/iavf/iavf_common.c                                                      |    2 
 kernel/include/uapi/linux/netfilter/nf_tables.h                                                           |    2 
 kernel/fs/udf/namei.c                                                                                     |    8 
 kernel/drivers/scsi/isci/request.c                                                                        |   10 
 kernel/drivers/net/tun.c                                                                                  |    4 
 kernel/drivers/net/phy/dp83869.c                                                                          |    6 
 kernel/drivers/net/wireguard/receive.c                                                                    |    2 
 kernel/drivers/bus/imx-weim.c                                                                             |    2 
 kernel/drivers/gpu/drm/i915/gvt/gtt.c                                                                     |   85 
 kernel/drivers/mtd/nand/raw/marvell_nand.c                                                                |   10 
 kernel/drivers/gpu/drm/i915/i915_request.c                                                                |    2 
 kernel/drivers/gpu/drm/i915/gvt/gtt.h                                                                     |    5 
 kernel/drivers/usb/host/xhci-rcar.c                                                                       |    3 
 kernel/drivers/media/dvb-frontends/ix2505v.c                                                              |    2 
 kernel/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c                                                        |   19 
 kernel/crypto/asymmetric_keys/public_key.c                                                                |   38 
 kernel/drivers/media/usb/uvc/uvc_video.c                                                                  |   20 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c                                      |    4 
 kernel/fs/hfsplus/hfsplus_fs.h                                                                            |    2 
 kernel/include/linux/nfs_xdr.h                                                                            |    2 
 kernel/drivers/net/wireless/intel/iwlwifi/fw/dbg.c                                                        |    4 
 kernel/drivers/usb/mtu3/mtu3_qmu.c                                                                        |    5 
 kernel/arch/x86/kvm/lapic.c                                                                               |   10 
 kernel/drivers/gpu/drm/i915/display/intel_bw.c                                                            |   80 
 kernel/kernel/locking/mutex.c                                                                             |   16 
 kernel/drivers/scsi/qla2xxx/qla_os.c                                                                      |  248 
 kernel/arch/x86/kernel/smp.c                                                                              |    6 
 kernel/arch/x86/include/asm/pgtable.h                                                                     |    8 
 kernel/drivers/gpu/drm/amd/include/kgd_pp_interface.h                                                     |    3 
 kernel/drivers/bluetooth/hci_h5.c                                                                         |    2 
 kernel/drivers/input/misc/soc_button_array.c                                                              |   30 
 kernel/drivers/firmware/google/gsmi.c                                                                     |    7 
 kernel/arch/mips/lantiq/prom.c                                                                            |    6 
 kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c                                                         |    7 
 kernel/arch/arm64/kernel/module-plts.c                                                                    |    3 
 kernel/drivers/bluetooth/hci_ll.c                                                                         |    2 
 kernel/kernel/fork.c                                                                                      |   64 
 kernel/drivers/bluetooth/hci_bcsp.c                                                                       |    2 
 kernel/drivers/net/dsa/b53/b53_mmap.c                                                                     |   14 
 kernel/drivers/media/dvb-frontends/dib7000m.c                                                             |    2 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c                                          |    3 
 kernel/net/batman-adv/netlink.c                                                                           |    3 
 kernel/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c                                               |    5 
 kernel/drivers/gpu/drm/i915/display/intel_display.c                                                       |    3 
 kernel/drivers/pci/controller/dwc/pcie-qcom.c                                                             |    8 
 kernel/arch/arm/mach-rockchip/rockchip.c                                                                  |    1 
 kernel/drivers/gpu/drm/drm_mipi_dsi.c                                                                     |   54 
 kernel/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c                                               |    2 
 kernel/net/netfilter/nf_conntrack_proto_tcp.c                                                             |   10 
 kernel/drivers/irqchip/irq-ti-sci-intr.c                                                                  |    1 
 kernel/drivers/usb/typec/bus.c                                                                            |   14 
 kernel/drivers/video/fbdev/vermilion/vermilion.c                                                          |    4 
 kernel/Documentation/admin-guide/hw-vuln/spectre.rst                                                      |   21 
 kernel/drivers/media/platform/rockchip/isp/isp_stats_v32.c                                                |   15 
 kernel/drivers/irqchip/irq-alpine-msi.c                                                                   |    1 
 kernel/fs/btrfs/zlib.c                                                                                    |    2 
 kernel/drivers/gpu/drm/radeon/cypress_dpm.c                                                               |    8 
 kernel/drivers/irqchip/irq-ti-sci-inta.c                                                                  |    2 
 kernel/fs/btrfs/relocation.c                                                                              |   14 
 kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c                                                   |  151 
 kernel/drivers/bus/ti-sysc.c                                                                              |   39 
 kernel/fs/jffs2/file.c                                                                                    |   15 
 kernel/sound/pci/hda/hda_controller.c                                                                     |    4 
 kernel/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi                                                 |   44 
 kernel/arch/arm/boot/dts/armada-385-turris-omnia.dts                                                      |   18 
 kernel/drivers/media/i2c/sc401ai.c                                                                        |   97 
 kernel/drivers/staging/rtl8192e/rtllib_rx.c                                                               |    2 
 kernel/kernel/time/tick-sched.c                                                                           |  152 
 kernel/drivers/base/regmap/regmap-i2c.c                                                                   |    8 
 kernel/drivers/soc/rockchip/rockchip_csu.c                                                                |  377 
 kernel/net/sctp/stream_interleave.c                                                                       |    3 
 kernel/drivers/hid/hid-plantronics.c                                                                      |    9 
 kernel/arch/um/drivers/Kconfig                                                                            |   16 
 kernel/drivers/fsi/fsi-sbefifo.c                                                                          |    6 
 kernel/include/net/ipv6.h                                                                                 |   12 
 kernel/sound/soc/codecs/rt711-sdw.h                                                                       |    2 
 kernel/Documentation/ABI/testing/sysfs-kernel-warn_count                                                  |    6 
 kernel/drivers/fpga/fpga-bridge.c                                                                         |    2 
 kernel/drivers/net/ethernet/nvidia/forcedeth.c                                                            |    1 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c                                              |    4 
 kernel/drivers/iio/addac/Kconfig                                                                          |    8 
 kernel/arch/powerpc/mm/kasan/Makefile                                                                     |    1 
 kernel/drivers/infiniband/ulp/ipoib/ipoib_netlink.c                                                       |    7 
 kernel/net/sunrpc/svcauth_unix.c                                                                          |   17 
 kernel/drivers/ata/ahci_xgene.c                                                                           |    4 
 kernel/kernel/compat.c                                                                                    |    2 
 kernel/drivers/target/target_core_device.c                                                                |   28 
 kernel/drivers/mcb/mcb-core.c                                                                             |    4 
 kernel/net/sctp/associola.c                                                                               |    3 
 kernel/include/linux/etherdevice.h                                                                        |   12 
 kernel/net/9p/trans_virtio.c                                                                              |    2 
 kernel/sound/soc/intel/boards/sof_sdw_common.h                                                            |    5 
 kernel/arch/x86/include/asm/disabled-features.h                                                           |    4 
 kernel/kernel/cgroup/namespace.c                                                                          |    6 
 kernel/arch/riscv/include/asm/jump_label.h                                                                |    2 
 kernel/drivers/video/rockchip/rga3/rga_common.c                                                           |   14 
 kernel/arch/arm/boot/dts/am3517-evm.dts                                                                   |    2 
 kernel/kernel/futex/Makefile                                                                              |    3 
 kernel/include/linux/nvme-tcp.h                                                                           |    5 
 kernel/drivers/iommu/amd/iommu.c                                                                          |    3 
 kernel/sound/soc/codecs/cs42l56.c                                                                         |    6 
 kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10-linux.dts                                           |    2 
 kernel/drivers/media/dvb-frontends/lnbp21.c                                                               |    4 
 kernel/drivers/media/i2c/maxim2c/remote_max96717.c                                                        |  310 
 kernel/drivers/video/fbdev/ep93xx-fb.c                                                                    |    1 
 kernel/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi                                                 |   10 
 kernel/drivers/cpufreq/cpufreq.c                                                                          |    4 
 kernel/drivers/video/rockchip/rga3/rga2_reg_info.c                                                        |    9 
 kernel/arch/m68k/Kconfig.devices                                                                          |    1 
 kernel/drivers/net/usb/kalmia.c                                                                           |    8 
 kernel/net/ipv4/udp_tunnel_core.c                                                                         |    1 
 kernel/drivers/usb/roles/class.c                                                                          |    5 
 kernel/drivers/fsi/fsi-master-aspeed.c                                                                    |    2 
 kernel/drivers/gpu/drm/msm/adreno/adreno_device.c                                                         |    7 
 kernel/kernel/module.c                                                                                    |   43 
 kernel/drivers/scsi/qla2xxx/qla_isr.c                                                                     |   16 
 kernel/scripts/diffconfig                                                                                 |   16 
 kernel/drivers/net/wireless/marvell/mwifiex/debugfs.c                                                     |    9 
 kernel/drivers/rtc/rtc-ds1685.c                                                                           |    2 
 kernel/arch/arm/boot/dts/spear600.dtsi                                                                    |    2 
 kernel/drivers/hid/hid-bigbenff.c                                                                         |   76 
 kernel/drivers/net/vxlan/Makefile                                                                         |    7 
 kernel/drivers/s390/crypto/zcrypt_ep11misc.h                                                              |    9 
 kernel/scripts/package/mkdebian                                                                           |    2 
 kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c                                                 |    1 
 kernel/arch/sh/kernel/signal_32.c                                                                         |    3 
 kernel/drivers/gpu/drm/msm/dp/dp_audio.h                                                                  |    2 
 kernel/mm/page_pinner.c                                                                                   |    1 
 kernel/include/soc/rockchip/rockchip_csu.h                                                                |   46 
 kernel/arch/arm64/include/asm/cputype.h                                                                   |    2 
 kernel/drivers/gpu/drm/msm/dp/dp_audio.c                                                                  |   12 
 kernel/drivers/gpu/drm/radeon/radeon_device.c                                                             |    1 
 kernel/arch/arm/boot/dts/imx50.dtsi                                                                       |    2 
 kernel/drivers/s390/cio/qdio_main.c                                                                       |   62 
 kernel/drivers/usb/typec/tps6598x.c                                                                       |    2 
 kernel/drivers/s390/crypto/zcrypt_ep11misc.c                                                              |    4 
 kernel/include/net/netfilter/nf_tables.h                                                                  |  210 
 kernel/drivers/bluetooth/hci_nokia.c                                                                      |    6 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c                                                  |   16 
 kernel/drivers/block/rnbd/rnbd-proto.h                                                                    |    2 
 kernel/drivers/gpu/drm/mxsfb/Kconfig                                                                      |    1 
 kernel/drivers/firmware/efi/libstub/efistub.h                                                             |    2 
 kernel/drivers/hid/hid-asus.c                                                                             |   38 
 kernel/drivers/dio/dio.c                                                                                  |    8 
 kernel/drivers/base/test/test_async_driver_probe.c                                                        |    4 
 kernel/drivers/mfd/rkx110_x120/pattern_gen.c                                                              |  310 
 kernel/net/ipv6/ila/ila_xlat.c                                                                            |    1 
 kernel/kernel/time/tick-sched.h                                                                           |    4 
 kernel/drivers/char/ipmi/ipmi_msghandler.c                                                                |   12 
 kernel/net/ipv6/ip6mr.c                                                                                   |    2 
 kernel/Documentation/admin-guide/kdump/gdbmacros.txt                                                      |    2 
 kernel/drivers/gpu/drm/drm_dp_mst_topology.c                                                              |    5 
 kernel/drivers/media/i2c/dw9800w.c                                                                        |  101 
 kernel/drivers/scsi/scsi_devinfo.c                                                                        |    1 
 kernel/drivers/base/cpu.c                                                                                 |   19 
 kernel/drivers/gpu/drm/msm/adreno/a5xx_gpu.c                                                              |   18 
 kernel/arch/arm/boot/dts/rv1106g-evb2-v12-dual-camera-avs.dts                                             |  122 
 kernel/drivers/mmc/host/wmt-sdmmc.c                                                                       |    6 
 kernel/drivers/scsi/fcoe/fcoe_sysfs.c                                                                     |   19 
 kernel/drivers/mtd/nand/raw/sunxi_nand.c                                                                  |    2 
 kernel/Documentation/ABI/testing/sysfs-devices-system-cpu                                                 |   15 
 kernel/arch/arm/mach-imx/cpu-imx25.c                                                                      |    1 
 kernel/kernel/bpf/bpf_local_storage.c                                                                     |   16 
 kernel/arch/x86/configs/gki_defconfig                                                                     |    4 
 kernel/drivers/usb/dwc3/dwc3-qcom.c                                                                       |   51 
 kernel/arch/arm64/boot/dts/rockchip/rk3326-863-lp3-v10-rkisp1.dts                                         |    4 
 kernel/tools/perf/util/header.c                                                                           |   11 
 kernel/arch/arm/boot/dts/omap3-pandora-common.dtsi                                                        |    2 
 kernel/arch/arm/boot/dts/omap3-gta04.dtsi                                                                 |   24 
 kernel/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi                                                           |    2 
 kernel/arch/x86/kernel/cpu/microcode/amd.c                                                                |   55 
 kernel/include/uapi/linux/idxd.h                                                                          |    2 
 kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtsi                                             |    1 
 kernel/drivers/block/null_blk/Makefile                                                                    |   11 
 kernel/net/ipv4/icmp.c                                                                                    |    5 
 kernel/drivers/thermal/qcom/tsens.c                                                                       |    6 
 kernel/drivers/hv/connection.c                                                                            |    4 
 kernel/drivers/usb/dwc3/debugfs.c                                                                         |  109 
 kernel/Documentation/devicetree/bindings/soc/rockchip/rockchip-pm-config.txt                              |   23 
 kernel/sound/soc/fsl/fsl_spdif.c                                                                          |    2 
 kernel/drivers/mmc/host/wbsd.c                                                                            |   10 
 kernel/drivers/infiniband/core/user_mad.c                                                                 |   23 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722.dtsi                                |    6 
 kernel/drivers/soc/rockchip/fiq_debugger/fiq_debugger.c                                                   |   40 
 kernel/kernel/trace/trace_events_inject.c                                                                 |    3 
 kernel/arch/powerpc/perf/core-fsl-emb.c                                                                   |    8 
 kernel/init/main.c                                                                                        |   21 
 kernel/net/ipv4/ip_sockglue.c                                                                             |   12 
 kernel/drivers/thermal/qcom/tsens.h                                                                       |    2 
 kernel/drivers/s390/net/lcs.c                                                                             |    8 
 kernel/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi                                          |   24 
 kernel/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c                                     |    5 
 kernel/drivers/video/fbdev/udlfb.c                                                                        |   13 
 kernel/include/uapi/linux/rk-isp32-config.h                                                               |    3 
 kernel/sound/core/pcm_native.c                                                                            |    4 
 kernel/drivers/block/null_blk/null_blk.h                                                                  |    0 
 kernel/drivers/media/platform/coda/coda-jpeg.c                                                            |   10 
 kernel/include/linux/rmap.h                                                                               |   27 
 kernel/drivers/net/ethernet/atheros/atl1c/atl1c_main.c                                                    |    7 
 kernel/drivers/media/platform/rockchip/cif/cif-luma.c                                                     |    2 
 kernel/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h                                                        |    2 
 kernel/arch/arm/include/asm/arch_gicv3.h                                                                  |    1 
 kernel/drivers/net/wireless/ath/ath.h                                                                     |   12 
 kernel/kernel/watch_queue.c                                                                               |    1 
 kernel/include/net/nfc/nfc.h                                                                              |    4 
 kernel/crypto/asymmetric_keys/pkcs7_verify.c                                                              |   10 
 kernel/tools/testing/selftests/net/mptcp/diag.sh                                                          |    4 
 kernel/MAINTAINERS                                                                                        |   11 
 kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c                                                       |  145 
 kernel/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c                                                 |    4 
 kernel/arch/arm/kernel/unwind.c                                                                           |   25 
 kernel/drivers/usb/host/xhci-mem.c                                                                        |   39 
 kernel/drivers/pinctrl/aspeed/pinctrl-aspeed.c                                                            |    2 
 kernel/drivers/net/net_failover.c                                                                         |    8 
 kernel/drivers/net/wan/fsl_ucc_hdlc.c                                                                     |   18 
 kernel/include/dt-bindings/soc/rockchip-system-status.h                                                   |    1 
 kernel/tools/testing/selftests/tc-testing/settings                                                        |    1 
 kernel/drivers/macintosh/macio-adb.c                                                                      |    4 
 kernel/drivers/net/ethernet/intel/igc/igc_tsn.c                                                           |   11 
 kernel/drivers/infiniband/hw/mlx5/devx.c                                                                  |   31 
 kernel/tools/testing/selftests/net/mptcp/mptcp_connect.sh                                                 |    4 
 kernel/sound/soc/rockchip/rockchip_pdm.c                                                                  |   79 
 kernel/drivers/gpu/drm/etnaviv/etnaviv_dump.c                                                             |   14 
 kernel/net/sched/act_police.c                                                                             |    2 
 kernel/drivers/gpu/drm/drm_fourcc.c                                                                       |   15 
 kernel/drivers/media/platform/rockchip/cif/capture.c                                                      | 1168 
 kernel/drivers/net/ethernet/atheros/alx/ethtool.c                                                         |    5 
 kernel/arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi                                                 |    2 
 kernel/drivers/bluetooth/hci_qca.c                                                                        |   74 
 kernel/drivers/net/ethernet/stmicro/stmmac/common.h                                                       |    1 
 kernel/arch/arm64/boot/dts/rockchip/rk3568-evb5-ddr4-v10.dtsi                                             |    1 
 kernel/arch/powerpc/xmon/xmon.c                                                                           |   12 
 kernel/tools/testing/selftests/sigaltstack/sas.c                                                          |    7 
 kernel/drivers/char/agp/parisc-agp.c                                                                      |   17 
 kernel/scripts/clang-tools/run-clang-tools.py                                                             |   21 
 kernel/drivers/media/rc/gpio-ir-recv.c                                                                    |   20 
 kernel/include/linux/rpmsg.h                                                                              |   10 
 kernel/drivers/hid/hid-core.c                                                                             |   26 
 kernel/arch/arm/boot/dts/rv1106g-dual-sensor-extboard.dtsi                                                |  246 
 kernel/drivers/edac/edac_module.h                                                                         |    2 
 kernel/fs/ramfs/inode.c                                                                                   |    2 
 kernel/drivers/char/tpm/tpm_tis_core.c                                                                    |  167 
 kernel/drivers/gpu/drm/i915/intel_gvt.h                                                                   |    5 
 kernel/drivers/char/tpm/tpm_tis_core.h                                                                    |    2 
 kernel/drivers/i2c/busses/i2c-cadence.c                                                                   |    6 
 kernel/drivers/media/i2c/max96756.c                                                                       | 1397 
 kernel/drivers/acpi/apei/ghes.c                                                                           |   19 
 kernel/drivers/media/i2c/max96756.h                                                                       |   11 
 kernel/drivers/pwm/pwm-rockchip-irq-callbacks.h                                                           |   64 
 kernel/drivers/watchdog/menz69_wdt.c                                                                      |   16 
 kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c                                                  |    1 
 kernel/drivers/video/rockchip/rga3/rga_policy.c                                                           |   50 
 kernel/include/trace/events/qrtr.h                                                                        |   33 
 kernel/tools/perf/util/pmu.c                                                                              |    2 
 kernel/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c                                                         |   16 
 kernel/drivers/char/hw_random/virtio-rng.c                                                                |   86 
 kernel/drivers/net/mdio/mdio-mvusb.c                                                                      |   11 
 kernel/arch/powerpc/kernel/ptrace/ptrace-view.c                                                           |    6 
 kernel/scripts/kconfig/preprocess.c                                                                       |    3 
 kernel/arch/xtensa/boot/lib/zmem.c                                                                        |    5 
 kernel/drivers/mfd/rkx110_x120/rkx120_pwm.c                                                               |  393 
 kernel/net/netfilter/ipset/ip_set_hash_ipport.c                                                           |   13 
 kernel/arch/parisc/kernel/cache.c                                                                         |    5 
 kernel/tools/hv/vmbus_testing                                                                             |    4 
 kernel/drivers/gpu/arm/bifrost/device/mali_kbase_device.c                                                 |   10 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/health.c                                                   |    7 
 kernel/net/ipv4/netfilter/nf_reject_ipv4.c                                                                |    6 
 kernel/drivers/vhost/vringh.c                                                                             |    5 
 kernel/security/integrity/iint.c                                                                          |   15 
 kernel/sound/soc/kirkwood/kirkwood-dma.c                                                                  |    2 
 kernel/arch/arm/mach-rockchip/rv1106_pm.h                                                                 |    3 
 kernel/arch/um/drivers/Makefile                                                                           |    2 
 kernel/drivers/soc/rockchip/rockchip_pm_config.c                                                          |  112 
 kernel/net/dsa/tag_sja1105.c                                                                              |    4 
 kernel/drivers/infiniband/hw/mlx5/main.c                                                                  |   35 
 kernel/drivers/media/platform/qcom/camss/camss-video.c                                                    |    3 
 kernel/drivers/spi/spi-rockchip.c                                                                         |    6 
 kernel/arch/arm/mach-rockchip/rv1106_pm.c                                                                 |  140 
 kernel/drivers/atm/idt77252.c                                                                             |   11 
 kernel/net/xfrm/Makefile                                                                                  |    2 
 kernel/drivers/usb/typec/ucsi/ucsi.c                                                                      |   11 
 kernel/include/linux/sunrpc/cache.h                                                                       |    1 
 kernel/tools/virtio/linux/build_bug.h                                                                     |    7 
 kernel/kernel/time/tick-broadcast.c                                                                       |    2 
 kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c                                            |    1 
 kernel/drivers/soc/rockchip/minidump/minidump_private.h                                                   |    1 
 kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h                                              |    5 
 kernel/drivers/net/dsa/mv88e6xxx/global2.h                                                                |    1 
 kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c                                              |    7 
 kernel/drivers/input/mouse/elantech.c                                                                     |    9 
 kernel/drivers/ata/libata.h                                                                               |    2 
 kernel/drivers/iio/Makefile                                                                               |    1 
 kernel/drivers/pwm/sysfs.c                                                                                |   91 
 kernel/drivers/video/rockchip/rga3/include/rga.h                                                          |    6 
 kernel/tools/include/uapi/linux/bpf.h                                                                     |    4 
 kernel/include/linux/moduleloader.h                                                                       |    5 
 kernel/include/linux/mlx5/mlx5_ifc.h                                                                      |    3 
 kernel/drivers/net/team/team.c                                                                            |   30 
 kernel/drivers/rpmsg/rockchip_rpmsg_mbox.c                                                                |    8 
 kernel/drivers/s390/block/dasd_ioctl.c                                                                    |    5 
 kernel/drivers/media/dvb-frontends/itd1000.c                                                              |    2 
 kernel/drivers/tty/serial/lantiq.c                                                                        |    1 
 kernel/drivers/net/dsa/mv88e6xxx/global2.c                                                                |    2 
 kernel/include/linux/soc/qcom/apr.h                                                                       |   12 
 kernel/drivers/gpu/drm/exynos/exynos_drm_vidi.c                                                           |    2 
 kernel/drivers/media/dvb-frontends/stv6110.c                                                              |    2 
 kernel/drivers/mfd/Makefile                                                                               |    1 
 kernel/drivers/usb/typec/altmodes/displayport.c                                                           |   34 
 kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android-avb.dts                                 |    2 
 kernel/drivers/net/ethernet/intel/igb/e1000_mac.c                                                         |    4 
 kernel/drivers/spi/spi-dw-core.c                                                                          |    2 
 kernel/drivers/net/wireless/ath/ath9k/hif_usb.c                                                           |  127 
 kernel/drivers/gpu/drm/panfrost/panfrost_gem.h                                                            |    5 
 kernel/arch/powerpc/kernel/traps.c                                                                        |    2 
 kernel/drivers/net/gtp.c                                                                                  |    2 
 kernel/drivers/mfd/display-serdes/serdes-gpio.c                                                           |    1 
 kernel/arch/arc/include/asm/linkage.h                                                                     |    8 
 kernel/drivers/net/ethernet/intel/igbvf/vf.c                                                              |   13 
 kernel/drivers/video/fbdev/pm2fb.c                                                                        |    9 
 kernel/drivers/gpu/drm/i915/intel_gvt.c                                                                   |   15 
 kernel/security/selinux/Makefile                                                                          |    8 
 kernel/drivers/bus/mhi/Makefile                                                                           |    4 
 kernel/drivers/gpu/drm/panfrost/panfrost_gem.c                                                            |   16 
 kernel/drivers/video/rockchip/rve/include/rve_drv.h                                                       |    2 
 kernel/include/linux/netfilter/ipset/ip_set.h                                                             |    2 
 kernel/net/smc/smc_core.c                                                                                 |    4 
 kernel/drivers/gpio/Kconfig                                                                               |    2 
 kernel/drivers/mmc/host/moxart-mmc.c                                                                      |   12 
 kernel/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c                                          |    2 
 kernel/drivers/net/ethernet/amd/xgbe/xgbe-dev.c                                                           |   23 
 kernel/drivers/platform/x86/Kconfig                                                                       |    3 
 kernel/arch/powerpc/platforms/pseries/lpar.c                                                              |   34 
 kernel/drivers/md/dm-integrity.c                                                                          |   14 
 kernel/drivers/crypto/rockchip/rk3288_crypto.h                                                            |   51 
 kernel/drivers/hwtracing/coresight/coresight-tmc-etf.c                                                    |    2 
 kernel/drivers/rknpu/include/rknpu_job.h                                                                  |    3 
 kernel/drivers/target/target_core_sbc.c                                                                   |    2 
 kernel/drivers/amba/bus.c                                                                                 |    1 
 kernel/drivers/scsi/libsas/sas_ata.c                                                                      |    7 
 kernel/include/linux/clk.h                                                                                |  189 
 kernel/arch/arm64/boot/dts/rockchip/rk3308b-amp.dtsi                                                      |   28 
 kernel/include/net/mptcp.h                                                                                |   12 
 kernel/kernel/sched/sched.h                                                                               |   53 
 kernel/arch/arm/configs/rk3126_linux_slc_nand.config                                                      |    3 
 kernel/drivers/clk/clk-devres.c                                                                           |  116 
 kernel/drivers/crypto/rockchip/rk3288_crypto.c                                                            |  193 
 kernel/arch/arm64/boot/dts/rockchip/rk3328.dtsi                                                           |  887 
 kernel/drivers/irqchip/irq-csky-apb-intc.c                                                                |    2 
 kernel/arch/powerpc/kvm/book3s_hv_ras.c                                                                   |    1 
 kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h                                                           |    5 
 kernel/drivers/soc/rockchip/rockchip_thunderboot_service.c                                                |    6 
 kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11-linux.dts                                           |    2 
 kernel/drivers/media/dvb-frontends/au8522_dig.c                                                           |    2 
 kernel/net/sched/sch_qfq.c                                                                                |   60 
 kernel/drivers/i2c/busses/i2c-rk3x.c                                                                      |  105 
 kernel/net/sched/cls_fw.c                                                                                 |   11 
 kernel/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c                                                           |    4 
 kernel/Documentation/filesystems/incfs.rst                                                                |    3 
 kernel/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c                                                             |    8 
 kernel/drivers/pwm/pwm-stm32-lp.c                                                                         |    2 
 kernel/drivers/irqchip/irq-gic-common.c                                                                   |   12 
 kernel/fs/xfs/xfs_buf_item_recover.c                                                                      |   10 
 kernel/net/netfilter/nf_conntrack_proto_sctp.c                                                            |  122 
 kernel/crypto/algapi.c                                                                                    |    4 
 kernel/drivers/media/dvb-frontends/dvb-pll.c                                                              |    2 
 kernel/drivers/input/touchscreen/Makefile                                                                 |    1 
 kernel/arch/arm/boot/dts/dove.dtsi                                                                        |    2 
 kernel/drivers/irqchip/irq-gic-common.h                                                                   |    1 
 kernel/drivers/rtc/Kconfig                                                                                |   10 
 kernel/tools/testing/selftests/bpf/progs/test_sk_assign.c                                                 |   11 
 kernel/Documentation/trace/ftrace.rst                                                                     |    2 
 kernel/drivers/usb/typec/tcpm/tcpm.c                                                                      |   24 
 kernel/drivers/dma-buf/sw_sync.c                                                                          |   18 
 kernel/drivers/i2c/busses/i2c-designware-platdrv.c                                                        |    5 
 kernel/drivers/net/veth.c                                                                                 |   14 
 kernel/arch/arm/boot/dts/exynos4210.dtsi                                                                  |    1 
 kernel/net/ceph/osd_client.c                                                                              |   20 
 kernel/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h                                    |    2 
 kernel/drivers/clk/socfpga/clk-gate.c                                                                     |   16 
 kernel/drivers/media/dvb-frontends/bcm3510.c                                                              |    3 
 kernel/net/rds/rdma_transport.c                                                                           |    8 
 kernel/drivers/gpu/drm/i915/intel_dram.c                                                                  |   82 
 kernel/drivers/mfd/rk630-spi.c                                                                            |   10 
 kernel/drivers/soc/rockchip/rockchip_disable_unused.c                                                     |   24 
 kernel/arch/arm/mach-orion5x/board-dt.c                                                                   |    3 
 kernel/drivers/usb/common/usb-conn-gpio.c                                                                 |    6 
 kernel/drivers/edac/qcom_edac.c                                                                           |    5 
 kernel/drivers/net/ethernet/intel/iavf/iavf_ethtool.c                                                     |    2 
 kernel/drivers/gpu/drm/drm_edid.c                                                                         |   21 
 kernel/drivers/net/ethernet/qualcomm/emac/emac.c                                                          |    6 
 kernel/tools/testing/selftests/ptp/testptp.c                                                              |    6 
 kernel/android/abi_gki_aarch64_rockchip                                                                   |    5 
 kernel/drivers/spi/spi-fsl-dspi.c                                                                         |   15 
 kernel/arch/sh/kernel/vmlinux.lds.S                                                                       |    1 
 kernel/drivers/net/wireless/intel/iwlwifi/dvm/sta.c                                                       |    5 
 kernel/drivers/net/ethernet/sfc/ethtool_common.c                                                          |    2 
 kernel/drivers/clocksource/timer-davinci.c                                                                |   30 
 kernel/drivers/media/i2c/maxim4c/remote_max96717.c                                                        |    2 
 kernel/drivers/phy/broadcom/phy-brcm-usb.c                                                                |    6 
 kernel/fs/ext4/sysfs.c                                                                                    |    9 
 kernel/drivers/mfd/rk806-i2c.c                                                                            |   62 
 kernel/drivers/i2c/busses/i2c-ocores.c                                                                    |   35 
 kernel/drivers/mfd/display-serdes/gpio.h                                                                  |   64 
 kernel/drivers/infiniband/hw/hfi1/chip.c                                                                  |   60 
 kernel/drivers/staging/rtl8712/usb_intf.c                                                                 |    1 
 kernel/include/linux/acpi_iort.h                                                                          |    1 
 kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c                                                   |  437 
 kernel/drivers/infiniband/sw/siw/siw_main.c                                                               |    3 
 kernel/drivers/net/wireless/intel/iwlegacy/common.c                                                       |    4 
 kernel/drivers/media/test-drivers/vivid/vivid-vid-cap.c                                                   |    1 
 kernel/Documentation/arm64/silicon-errata.rst                                                             |    6 
 kernel/arch/um/kernel/um_arch.c                                                                           |    5 
 kernel/sound/soc/rockchip/rockchip_utils.h                                                                |   18 
 kernel/drivers/gpu/drm/ttm/ttm_tt.c                                                                       |    1 
 kernel/drivers/gpu/drm/i915/i915_active.c                                                                 |  126 
 kernel/arch/arm/boot/dts/spear320-hmi.dts                                                                 |    2 
 kernel/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c                                                 |    6 
 kernel/drivers/net/usb/r8152.c                                                                            |    3 
 kernel/drivers/power/supply/ab8500_fg.c                                                                   |    6 
 kernel/drivers/gpu/drm/mediatek/mtk_dpi.c                                                                 |   12 
 kernel/drivers/infiniband/hw/efa/efa_main.c                                                               |    3 
 kernel/drivers/pinctrl/pinctrl-mcp23s08_spi.c                                                             |   10 
 kernel/drivers/media/dvb-frontends/sp887x.c                                                               |    2 
 kernel/fs/jfs/jfs_extent.c                                                                                |    5 
 kernel/net/wireless/wext-core.c                                                                           |    6 
 kernel/drivers/usb/dwc3/dwc3-pci.c                                                                        |    6 
 kernel/net/sunrpc/svc.c                                                                                   |    8 
 kernel/drivers/devfreq/rockchip_dmc.c                                                                     |   17 
 kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c                                                           |   12 
 kernel/sound/soc/rockchip/rockchip_utils.c                                                                |  150 
 kernel/drivers/platform/chrome/cros_ec_chardev.c                                                          |    2 
 kernel/security/integrity/ima/ima_template.c                                                              |    9 
 kernel/drivers/acpi/acpica/dsmethod.c                                                                     |   10 
 kernel/drivers/ata/pata_ixp4xx_cf.c                                                                       |    2 
 kernel/fs/ext4/fast_commit.h                                                                              |    1 
 kernel/arch/mips/include/asm/cpu-features.h                                                               |   21 
 kernel/drivers/video/fbdev/Kconfig                                                                        |    3 
 kernel/drivers/clk/rockchip/clk-rk3568.c                                                                  |    6 
 kernel/drivers/media/i2c/maxim4c/maxim4c_v4l2.c                                                           |   34 
 kernel/fs/ext4/fast_commit.c                                                                              |   49 
 kernel/sound/hda/hdac_stream.c                                                                            |   27 
 kernel/kernel/torture.c                                                                                   |    2 
 kernel/arch/ia64/kernel/mca_drv.c                                                                         |    2 
 kernel/arch/mips/fw/lib/cmdline.c                                                                         |    2 
 kernel/arch/powerpc/kernel/rtas_flash.c                                                                   |    6 
 kernel/Documentation/devicetree/bindings/opp/rockchip-opp.txt                                             |  183 
 kernel/drivers/interconnect/core.c                                                                        |    4 
 kernel/include/linux/dim.h                                                                                |    3 
 kernel/fs/xfs/xfs_bmap_util.c                                                                             |    9 
 kernel/drivers/media/tuners/xc5000.c                                                                      |    2 
 kernel/net/ipv4/fib_semantics.c                                                                           |    7 
 kernel/include/soc/rockchip/rk_minidump.h                                                                 |   10 
 kernel/tools/testing/selftests/intel_pstate/aperf.c                                                       |   22 
 kernel/drivers/gpu/drm/radeon/cik.c                                                                       |   36 
 kernel/arch/arm64/boot/dts/rockchip/rk3588s-evb1-lp4x.dtsi                                                |    4 
 kernel/drivers/mtd/spi-nor/core.c                                                                         |   30 
 kernel/drivers/net/phy/phy.c                                                                              |   23 
 kernel/drivers/rtc/rtc-cmos.c                                                                             |  366 
 kernel/net/core/sock_map.c                                                                                |    4 
 kernel/drivers/hwmon/Kconfig                                                                              |    1 
 kernel/net/ipv4/netfilter/ipt_REJECT.c                                                                    |    3 
 kernel/drivers/media/i2c/sc230ai.c                                                                        |   90 
 kernel/crypto/rsa-pkcs1pad.c                                                                              |   34 
 kernel/drivers/media/platform/rockchip/isp/bridge_v30.c                                                   |    4 
 kernel/drivers/mtd/spi-nor/core.h                                                                         |    1 
 kernel/drivers/misc/rockchip/pcie-rkep.c                                                                  | 1032 
 kernel/fs/ext4/fsmap.c                                                                                    |    2 
 kernel/net/ipv6/netfilter/ip6t_REJECT.c                                                                   |    2 
 kernel/arch/arm/boot/dts/qcom-ipq8064.dtsi                                                                |   12 
 kernel/tools/lib/bpf/nlattr.c                                                                             |    2 
 kernel/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c                                                |    6 
 kernel/lib/nlattr.c                                                                                       |    3 
 kernel/drivers/media/pci/saa7134/saa7134-core.c                                                           |    2 
 kernel/drivers/media/dvb-frontends/cx24116.c                                                              |    2 
 kernel/kernel/ksysfs.c                                                                                    |    7 
 kernel/drivers/crypto/rockchip/rk3288_crypto_skcipher.c                                                   |  417 
 kernel/include/net/rpl.h                                                                                  |    3 
 kernel/arch/ia64/kernel/salinfo.c                                                                         |    2 
 kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c                                             |   60 
 kernel/include/asm-generic/pgtable-nopud.h                                                                |    2 
 kernel/include/uapi/linux/netfilter/nf_conntrack_sctp.h                                                   |    2 
 kernel/include/uapi/linux/usb/video.h                                                                     |   30 
 kernel/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c                                                |    4 
 kernel/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts                                                    |    4 
 kernel/arch/riscv/net/bpf_jit_comp64.c                                                                    |   13 
 kernel/drivers/media/usb/siano/smsusb.c                                                                   |   23 
 kernel/net/netrom/nr_subr.c                                                                               |    7 
 kernel/drivers/acpi/acpica/hwvalid.c                                                                      |    7 
 kernel/drivers/mfd/rkx110_x120/rkx110_x120.h                                                              |   62 
 kernel/drivers/pci/hotplug/pciehp_hpc.c                                                                   |   12 
 kernel/kernel/kcsan/Makefile                                                                              |    3 
 kernel/drivers/net/wireless/ath/wil6210/txrx_edma.c                                                       |    2 
 kernel/drivers/net/wireless/ath/wil6210/txrx_edma.h                                                       |    6 
 kernel/drivers/clk/x86/clk-cgu.h                                                                          |   46 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c                                          |    2 
 kernel/drivers/scsi/snic/snic_disc.c                                                                      |    5 
 kernel/Documentation/devicetree/bindings/sound/tas2562.yaml                                               |    6 
 kernel/sound/usb/line6/midi.c                                                                             |    6 
 kernel/drivers/remoteproc/st_remoteproc.c                                                                 |    5 
 kernel/drivers/char/ipmi/ipmi_watchdog.c                                                                  |    8 
 kernel/fs/nilfs2/alloc.c                                                                                  |    3 
 kernel/drivers/scsi/megaraid.c                                                                            |    1 
 kernel/arch/arm64/boot/dts/qcom/msm8996.dtsi                                                              |   30 
 kernel/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts                                              |   30 
 kernel/drivers/i2c/busses/i2c-sprd.c                                                                      |    8 
 kernel/kernel/auditsc.c                                                                                   |    2 
 kernel/arch/arm64/boot/dts/rockchip/px30-android.dtsi                                                     |    8 
 kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-lp4-v11-linux.dts                                       |    2 
 kernel/drivers/net/usb/cdc_mbim.c                                                                         |    5 
 kernel/lib/mpi/mpicoder.c                                                                                 |    3 
 kernel/drivers/iio/accel/mma9551_core.c                                                                   |   10 
 kernel/drivers/tty/tty_port.c                                                                             |    1 
 kernel/tools/testing/selftests/resctrl/mba_test.c                                                         |    7 
 kernel/drivers/clk/imx/clk-composite-8m.c                                                                 |   12 
 kernel/drivers/ata/libata-eh.c                                                                            |   13 
 kernel/arch/x86/entry/vdso/vma.c                                                                          |    4 
 kernel/arch/arm64/boot/dts/mediatek/mt2712-evb.dts                                                        |   12 
 kernel/drivers/pinctrl/qcom/pinctrl-msm8976.c                                                             |    8 
 kernel/mm/damon/dbgfs.c                                                                                   |    7 
 kernel/drivers/mfd/tqmx86.c                                                                               |   76 
 kernel/drivers/tty/serial/8250/Kconfig                                                                    |    4 
 kernel/drivers/pci/controller/dwc/pcie-dw-ep-rockchip.c                                                   |  150 
 kernel/include/asm-generic/io.h                                                                           |    4 
 kernel/net/ipv4/igmp.c                                                                                    |    3 
 kernel/arch/arm/boot/dts/imx53.dtsi                                                                       |    2 
 kernel/drivers/media/i2c/gc2093.c                                                                         |   67 
 kernel/drivers/net/ethernet/broadcom/tg3.c                                                                |    9 
 kernel/drivers/net/wireless/ath/ath11k/debugfs.c                                                          |   48 
 kernel/drivers/scsi/ufs/ufshcd.c                                                                          |   82 
 kernel/drivers/staging/iio/accel/adis16203.c                                                              |    1 
 kernel/drivers/mmc/host/mtk-sd.c                                                                          |    2 
 kernel/net/sctp/socket.c                                                                                  |   50 
 kernel/drivers/video/rockchip/vehicle/vehicle_cif.c                                                       |    1 
 kernel/include/linux/libata.h                                                                             |    8 
 kernel/drivers/mfd/stmfx.c                                                                                |    7 
 kernel/drivers/rknpu/rknpu_mem.c                                                                          |   35 
 kernel/drivers/clk/x86/clk-cgu.c                                                                          |  106 
 kernel/drivers/net/bonding/bond_alb.c                                                                     |    6 
 kernel/arch/arm64/kernel/smp.c                                                                            |    8 
 kernel/drivers/md/raid0.h                                                                                 |    1 
 kernel/drivers/usb/phy/phy-mxs-usb.c                                                                      |   10 
 kernel/drivers/media/usb/dvb-usb-v2/rtl28xxu.c                                                            |   20 
 kernel/drivers/md/raid0.c                                                                                 |   62 
 kernel/fs/xfs/xfs_pnfs.c                                                                                  |    9 
 kernel/net/netfilter/nft_set_bitmap.c                                                                     |    5 
 kernel/drivers/video/rockchip/rga3/rga3_reg_info.c                                                        |    8 
 kernel/drivers/mfd/display-serdes/core.h                                                                  |   90 
 kernel/sound/pci/hda/patch_hdmi.c                                                                         |   29 
 kernel/net/sctp/proc.c                                                                                    |    2 
 kernel/net/xfrm/xfrm_user.c                                                                               |   13 
 kernel/net/bridge/br_stp_if.c                                                                             |    3 
 kernel/drivers/tty/pty.c                                                                                  |    1 
 kernel/drivers/scsi/scsi_error.c                                                                          |   14 
 kernel/include/linux/rcupdate.h                                                                           |   13 
 kernel/drivers/char/ipmi/Kconfig                                                                          |    3 
 kernel/include/net/rtnetlink.h                                                                            |    4 
 kernel/tools/arch/x86/include/asm/disabled-features.h                                                     |    3 
 kernel/sound/core/pcm_memory.c                                                                            |   44 
 kernel/drivers/gpu/drm/etnaviv/etnaviv_mmu.c                                                              |    4 
 kernel/drivers/irqchip/irq-aspeed-vic.c                                                                   |    4 
 kernel/fs/overlayfs/ovl_entry.h                                                                           |    9 
 kernel/drivers/net/wireless/mediatek/mt76/mt7615/mac.c                                                    |    3 
 kernel/drivers/infiniband/hw/mlx5/qpc.c                                                                   |   10 
 kernel/fs/f2fs/verity.c                                                                                   |   12 
 kernel/arch/mips/kernel/vmlinux.lds.S                                                                     |    2 
 kernel/sound/soc/codecs/rt5670.c                                                                          |    2 
 kernel/arch/powerpc/mm/book3s64/slb.c                                                                     |    1 
 kernel/drivers/infiniband/hw/hfi1/affinity.c                                                              |    2 
 kernel/include/net/netns/nftables.h                                                                       |    7 
 kernel/net/ipv6/ndisc.c                                                                                   |    3 
 kernel/drivers/media/dvb-frontends/zl10039.c                                                              |    2 
 kernel/include/linux/stmmac.h                                                                             |    1 
 kernel/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c                                                       |   27 
 kernel/arch/arm64/boot/dts/qcom/qcs404.dtsi                                                               |   12 
 kernel/drivers/thermal/intel/Kconfig                                                                      |    3 
 kernel/net/ipv6/rpl.c                                                                                     |    3 
 kernel/Documentation/dev-tools/gdb-kernel-debugging.rst                                                   |    4 
 kernel/net/netfilter/nf_conntrack_sip.c                                                                   |    2 
 kernel/arch/x86/kernel/process_32.c                                                                       |    2 
 kernel/net/ipv4/netfilter/nft_reject_ipv4.c                                                               |    3 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-edp-8lanes-M280DCA.dts                            |  229 
 kernel/arch/mips/include/asm/syscall.h                                                                    |    2 
 kernel/drivers/gpu/drm/amd/amdgpu/soc15.c                                                                 |    5 
 kernel/drivers/infiniband/ulp/isert/ib_isert.c                                                            |   18 
 kernel/drivers/mfd/display-serdes/serdes-core.c                                                           |   69 
 kernel/drivers/platform/x86/sony-laptop.c                                                                 |   21 
 kernel/drivers/ata/pata_ns87415.c                                                                         |    2 
 kernel/drivers/video/fbdev/tgafb.c                                                                        |    3 
 kernel/arch/arm/boot/dts/rv1106-evb-ext-mcu-v20.dtsi                                                      |  266 
 kernel/drivers/scsi/qedi/qedi_main.c                                                                      |   26 
 kernel/drivers/acpi/nfit/core.c                                                                           |    2 
 kernel/drivers/net/wireless/realtek/rtw88/mac.c                                                           |    8 
 kernel/drivers/input/keyboard/gpio_keys.c                                                                 |   18 
 kernel/drivers/media/i2c/sc200ai.c                                                                        |  213 
 kernel/arch/arm64/boot/dts/rockchip/rk3566-evb2-lp4x-v10-edp.dts                                          |    2 
 kernel/drivers/net/ethernet/intel/igc/igc_ethtool.c                                                       |    2 
 kernel/fs/super.c                                                                                         |   11 
 kernel/drivers/gpu/drm/nouveau/nouveau_acpi.c                                                             |    3 
 kernel/drivers/net/wireless/ath/ath9k/pci.c                                                               |    4 
 kernel/drivers/acpi/processor_perflib.c                                                                   |   42 
 kernel/drivers/edac/highbank_mc_edac.c                                                                    |    7 
 kernel/drivers/media/dvb-frontends/ts2020.c                                                               |    2 
 kernel/drivers/mtd/nand/raw/fsmc_nand.c                                                                   |    7 
 kernel/drivers/acpi/thermal.c                                                                             |    2 
 kernel/drivers/clk/keystone/sci-clk.c                                                                     |    2 
 kernel/arch/s390/kernel/kprobes.c                                                                         |    4 
 kernel/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c                                                  |    4 
 kernel/fs/udf/truncate.c                                                                                  |   48 
 kernel/tools/testing/selftests/bpf/prog_tests/sk_assign.c                                                 |   25 
 kernel/drivers/mmc/host/sdhci-msm.c                                                                       |    3 
 kernel/drivers/soc/rockchip/minidump/minidump_log.c                                                       |  268 
 kernel/net/ipv6/esp6_offload.c                                                                            |    3 
 kernel/include/linux/kstrtox.h                                                                            |  155 
 kernel/include/linux/seqlock.h                                                                            |  104 
 kernel/net/netfilter/nf_conntrack_core.c                                                                  |    3 
 kernel/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c                                                 |   23 
 kernel/drivers/i2c/busses/i2c-i801.c                                                                      |    1 
 kernel/Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml                              |    6 
 kernel/drivers/gpu/drm/drm_atomic_helper.c                                                                |   11 
 kernel/drivers/w1/w1_int.c                                                                                |    5 
 kernel/drivers/video/fbdev/omap/lcd_mipid.c                                                               |    6 
 kernel/arch/powerpc/platforms/pseries/firmware.c                                                          |    3 
 kernel/drivers/media/i2c/sc450ai.c                                                                        | 1640 
 kernel/net/ipv4/tcp_ulp.c                                                                                 |    4 
 kernel/kernel/bpf/cgroup.c                                                                                |    9 
 kernel/arch/arm/boot/dts/rv1106g-evb1-v11.dts                                                             |    2 
 kernel/kernel/irq/msi.c                                                                                   |    2 
 kernel/fs/tracefs/inode.c                                                                                 |    3 
 kernel/drivers/spmi/spmi.c                                                                                |    3 
 kernel/drivers/net/wireless/microchip/wilc1000/netdev.c                                                   |    1 
 kernel/include/net/udp.h                                                                                  |    2 
 kernel/drivers/scsi/ipr.c                                                                                 |   51 
 kernel/kernel/irq/chip.c                                                                                  |    2 
 kernel/include/linux/power_supply.h                                                                       |    5 
 kernel/drivers/pci/controller/pci-ftpci100.c                                                              |   14 
 kernel/net/sunrpc/auth_gss/svcauth_gss.c                                                                  |    9 
 kernel/arch/sparc/Kconfig                                                                                 |    3 
 kernel/drivers/gpu/drm/rockchip/rk628/rk628_dsi.c                                                         |    3 
 kernel/drivers/mfd/intel-lpss-acpi.c                                                                      |    3 
 kernel/drivers/cpufreq/intel_pstate.c                                                                     |   16 
 kernel/fs/ext4/super.c                                                                                    |  309 
 kernel/drivers/tty/rpmsg_tty.c                                                                            |  287 
 kernel/sound/i2c/cs8427.c                                                                                 |    7 
 kernel/arch/arm64/boot/dts/rockchip/rk3562-evb.dtsi                                                       |    2 
 kernel/drivers/scsi/megaraid/megaraid_sas_base.c                                                          |   23 
 kernel/include/linux/usb/hcd.h                                                                            |    5 
 kernel/net/netfilter/nft_set_rbtree.c                                                                     |  496 
 kernel/arch/arm/boot/dts/rv1106g-evb1-v11-dual-cam.dts                                                    |    2 
 kernel/mm/vmalloc.c                                                                                       |    4 
 kernel/drivers/nvme/host/pci.c                                                                            |  191 
 kernel/drivers/pinctrl/pinctrl-single.c                                                                   |    2 
 kernel/drivers/tty/serial/pch_uart.c                                                                      |    6 
 kernel/arch/arm64/boot/dts/qcom/sc7180.dtsi                                                               |    4 
 kernel/arch/arm64/boot/dts/rockchip/rk3308-evb-audio-v10.dtsi                                             |   59 
 kernel/arch/mips/include/asm/mach-rc32434/pci.h                                                           |    2 
 kernel/drivers/pinctrl/intel/pinctrl-intel.c                                                              |   16 
 kernel/drivers/media/dvb-frontends/tda10021.c                                                             |    2 
 kernel/fs/pstore/ram_core.c                                                                               |   10 
 kernel/drivers/macintosh/windfarm_smu_sensors.c                                                           |    4 
 kernel/drivers/iio/imu/fxos8700_core.c                                                                    |  111 
 kernel/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c                                                             |   81 
 kernel/tools/testing/selftests/net/forwarding/tc_flower.sh                                                |    8 
 kernel/arch/arm64/boot/dts/rockchip/rk3328-evb.dts                                                        |  410 
 kernel/drivers/scsi/dpti.h                                                                                |    1 
 kernel/include/soc/rockchip/rockchip_amp.h                                                                |   17 
 kernel/drivers/mtd/mtdcore.c                                                                              |    4 
 kernel/drivers/media/platform/coda/coda-bit.c                                                             |   14 
 kernel/lib/dim/dim.c                                                                                      |    5 
 kernel/include/uapi/linux/ipv6.h                                                                          |    1 
 kernel/drivers/i2c/busses/i2c-qup.c                                                                       |   21 
 kernel/drivers/media/usb/dvb-usb/az6027.c                                                                 |   16 
 kernel/drivers/block/xen-blkfront.c                                                                       |    3 
 kernel/arch/arm/boot/dts/omap3-lilly-a83x.dtsi                                                            |    2 
 kernel/net/bridge/br_private_tunnel.h                                                                     |    8 
 kernel/drivers/media/i2c/maxim2c/maxim2c_i2c.h                                                            |   55 
 kernel/net/can/j1939/transport.c                                                                          |    9 
 kernel/drivers/gpu/drm/amd/display/dc/core/dc.c                                                           |    4 
 kernel/drivers/firmware/xilinx/zynqmp.c                                                                   |    2 
 kernel/arch/m68k/kernel/relocate_kernel.S                                                                 |    4 
 kernel/drivers/media/radio/radio-shark.c                                                                  |   10 
 kernel/net/ipv4/metrics.c                                                                                 |    2 
 kernel/kernel/kexec.c                                                                                     |   41 
 kernel/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c                                                       |   12 
 kernel/net/tls/tls_sw.c                                                                                   |   30 
 kernel/drivers/gpu/drm/drm_probe_helper.c                                                                 |    5 
 kernel/net/sctp/sysctl.c                                                                                  |   73 
 kernel/arch/x86/include/asm/entry-common.h                                                                |    1 
 kernel/samples/bpf/hbm.c                                                                                  |    1 
 kernel/drivers/crypto/caam/caampkc.c                                                                      |    4 
 kernel/drivers/irqchip/irq-bcm6345-l1.c                                                                   |   14 
 kernel/net/bluetooth/hci_core.c                                                                           |   27 
 kernel/drivers/mtd/nand/raw/stm32_fmc2_nand.c                                                             |    3 
 kernel/drivers/net/ethernet/pensando/ionic/ionic_lif.c                                                    |   20 
 kernel/drivers/mmc/host/owl-mmc.c                                                                         |    2 
 kernel/drivers/mtd/nand/bbt_store.c                                                                       |  261 
 kernel/arch/riscv/include/uapi/asm/setup.h                                                                |    8 
 kernel/sound/hda/hdac_device.c                                                                            |    2 
 kernel/include/linux/pgtable.h                                                                            |    4 
 kernel/drivers/tee/amdtee/call.c                                                                          |   28 
 kernel/arch/arm/mach-zynq/slcr.c                                                                          |    1 
 kernel/arch/um/kernel/vmlinux.lds.S                                                                       |    2 
 kernel/drivers/power/supply/bq27xxx_battery_i2c.c                                                         |    3 
 kernel/arch/powerpc/platforms/pseries/lparcfg.c                                                           |   24 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c                                                 |    9 
 kernel/sound/soc/rockchip/rockchip_i2s_tdm.h                                                              |   12 
 kernel/kernel/acct.c                                                                                      |    2 
 kernel/include/uapi/linux/rk-mpp.h                                                                        |   82 
 kernel/sound/soc/rockchip/rockchip_i2s_tdm.c                                                              |   88 
 kernel/drivers/md/dm-zoned-target.c                                                                       |   15 
 kernel/include/linux/tracepoint.h                                                                         |   15 
 kernel/fs/squashfs/squashfs_fs.h                                                                          |    2 
 kernel/drivers/pinctrl/meson/pinctrl-meson-axg.c                                                          |    1 
 kernel/arch/m68k/kernel/signal.c                                                                          |   14 
 kernel/drivers/net/wireless/marvell/libertas/main.c                                                       |    3 
 kernel/drivers/infiniband/hw/mlx4/main.c                                                                  |   14 
 kernel/include/linux/bootconfig.h                                                                         |    2 
 kernel/drivers/bus/mhi/host/init.c                                                                        |   12 
 kernel/drivers/i2c/busses/i2c-tiny-usb.c                                                                  |    4 
 kernel/drivers/gpu/drm/rockchip/rockchip_vop_reg.c                                                        |    4 
 kernel/mm/page_owner.c                                                                                    |    2 
 kernel/drivers/video/fbdev/smscufx.c                                                                      |   46 
 kernel/drivers/dma/dmaengine.c                                                                            |    7 
 kernel/drivers/soc/qcom/ocmem.c                                                                           |   14 
 kernel/arch/arm64/boot/dts/rockchip/rk1808-fpga.dts                                                       |    4 
 kernel/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c                                                            |   29 
 kernel/samples/hw_breakpoint/data_breakpoint.c                                                            |    4 
 kernel/drivers/nfc/fdp/i2c.c                                                                              |    4 
 kernel/net/key/af_key.c                                                                                   |   16 
 kernel/drivers/gpu/drm/rockchip/rockchip_drm_clk.c                                                        |  284 
 kernel/drivers/thermal/intel/intel_powerclamp.c                                                           |   20 
 kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c                                                       |   28 
 kernel/arch/parisc/kernel/pci-dma.c                                                                       |   18 
 kernel/arch/powerpc/Kconfig.debug                                                                         |    2 
 kernel/drivers/target/target_core_transport.c                                                             |   59 
 kernel/drivers/irqchip/irq-jcore-aic.c                                                                    |   11 
 kernel/net/packet/diag.c                                                                                  |    6 
 kernel/arch/openrisc/kernel/entry.S                                                                       |    6 
 kernel/drivers/input/misc/drv260x.c                                                                       |    1 
 kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c                                                          |   52 
 kernel/drivers/mmc/core/block.c                                                                           |   23 
 kernel/fs/cifs/cifsfs.c                                                                                   |    8 
 kernel/fs/cifs/cifsfs.h                                                                                   |    5 
 kernel/drivers/hwmon/pmbus/bel-pfe.c                                                                      |   16 
 kernel/fs/char_dev.c                                                                                      |    2 
 kernel/net/core/neighbour.c                                                                               |   56 
 kernel/drivers/net/ethernet/intel/i40e/i40e_diag.h                                                        |    2 
 kernel/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts                                         |    2 
 kernel/kernel/trace/trace.h                                                                               |    4 
 kernel/drivers/net/ethernet/intel/i40e/i40e_diag.c                                                        |   11 
 kernel/kernel/trace/trace.c                                                                               |  125 
 kernel/drivers/infiniband/hw/mthca/mthca_qp.c                                                             |    2 
 kernel/drivers/gpu/drm/xlnx/zynqmp_dpsub.c                                                                |    4 
 kernel/arch/s390/kernel/ptrace.c                                                                          |    8 
 kernel/drivers/net/wireless/wl3501_cs.c                                                                   |   29 
 kernel/drivers/iio/imu/adis_trigger.c                                                                     |   20 
 kernel/drivers/pci/setup-bus.c                                                                            |  191 
 kernel/arch/arm/boot/dts/am57xx-cl-som-am57x.dts                                                          |    2 
 kernel/drivers/spi/spi-gpio.c                                                                             |   16 
 kernel/Documentation/networking/af_xdp.rst                                                                |    9 
 kernel/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c                                                          |    5 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp.dts                                           |    4 
 kernel/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c                                                      |   10 
 kernel/net/qrtr/af_qrtr.c                                                                                 |   15 
 kernel/fs/ext4/mballoc.h                                                                                  |    2 
 kernel/arch/arm/boot/dts/imx7d-pico-dwarf.dts                                                             |    4 
 kernel/arch/x86/lib/retpoline.S                                                                           |  158 
 kernel/drivers/net/ethernet/intel/igc/igc_defines.h                                                       |    2 
 kernel/drivers/media/tuners/xc4000.c                                                                      |    2 
 kernel/fs/ext4/mballoc.c                                                                                  |  592 
 kernel/drivers/media/dvb-frontends/lgs8gxx.c                                                              |    2 
 kernel/include/linux/sunrpc/rpc_pipe_fs.h                                                                 |    5 
 kernel/drivers/misc/eeprom/Kconfig                                                                        |    1 
 kernel/net/Kconfig                                                                                        |    2 
 kernel/arch/sh/boards/mach-ecovec24/setup.c                                                               |    6 
 kernel/include/linux/rockchip/rockchip_sip.h                                                              |   29 
 kernel/drivers/i2c/busses/i2c-bcm-iproc.c                                                                 |   11 
 kernel/arch/arm/boot/dts/iwg20d-q7-common.dtsi                                                            |    2 
 kernel/drivers/media/i2c/imx577.c                                                                         |   10 
 kernel/drivers/media/platform/rockchip/isp/isp_params.h                                                   |    2 
 kernel/drivers/net/ethernet/natsemi/sonic.c                                                               |    4 
 kernel/drivers/media/platform/rockchip/isp/isp_params.c                                                   |   61 
 kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dts               |   14 
 kernel/drivers/net/wireless/ath/ath11k/core.h                                                             |    1 
 kernel/drivers/input/serio/i8042.h                                                                        |    2 
 kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11.dts                                              |    2 
 kernel/include/uapi/linux/auto_dev-ioctl.h                                                                |    2 
 kernel/net/bridge/netfilter/ebtables.c                                                                    |    5 
 kernel/fs/gfs2/aops.c                                                                                     |    5 
 kernel/Documentation/ABI/testing/sysfs-kernel-oops_count                                                  |    6 
 kernel/include/uapi/linux/btrfs.h                                                                         |    1 
 kernel/fs/xfs/xfs_qm.c                                                                                    |    9 
 kernel/arch/arm64/include/asm/debug-monitors.h                                                            |    1 
 kernel/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c                                                 |    8 
 kernel/drivers/media/i2c/mis4001.c                                                                        | 1643 
 kernel/drivers/media/i2c/maxim2c/maxim2c_video_pipe.c                                                     |  346 
 kernel/drivers/misc/rockchip/Kconfig                                                                      |    1 
 kernel/drivers/infiniband/hw/hfi1/ipoib_tx.c                                                              |   21 
 kernel/drivers/media/i2c/maxim2c/maxim2c_video_pipe.h                                                     |   44 
 kernel/include/linux/posix-timers.h                                                                       |   17 
 kernel/fs/overlayfs/namei.c                                                                               |    3 
 kernel/drivers/usb/gadget/function/u_serial.c                                                             |   39 
 kernel/kernel/sched/fair.c                                                                                |  294 
 kernel/drivers/irqchip/irq-mxs.c                                                                          |    4 
 kernel/arch/x86/include/asm/reboot.h                                                                      |    2 
 kernel/drivers/powercap/Kconfig                                                                           |    4 
 kernel/sound/soc/dwc/dwc-i2s.c                                                                            |   45 
 kernel/drivers/media/dvb-frontends/cx22702.c                                                              |    2 
 kernel/drivers/net/ethernet/marvell/octeontx2/af/cgx.h                                                    |    6 
 kernel/drivers/net/ethernet/pensando/ionic/ionic_txrx.c                                                   |    2 
 kernel/drivers/media/dvb-frontends/s5h1411.c                                                              |    2 
 kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c                                                             |    5 
 kernel/tools/testing/selftests/bpf/prog_tests/cg_storage_multi.c                                          |    8 
 kernel/drivers/remoteproc/qcom_q6v5_pas.c                                                                 |    4 
 kernel/include/soc/bcm2835/raspberrypi-firmware.h                                                         |    8 
 kernel/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c                                                             |   19 
 kernel/arch/m68k/fpsp040/skeleton.S                                                                       |    4 
 kernel/drivers/net/ethernet/marvell/octeontx2/af/cgx.c                                                    |   17 
 kernel/fs/erofs/Kconfig                                                                                   |   17 
 kernel/arch/x86/kernel/cpu/mce/amd.c                                                                      |   51 
 kernel/drivers/media/dvb-frontends/nxt200x.c                                                              |    2 
 kernel/drivers/net/phy/broadcom.c                                                                         |   13 
 kernel/include/linux/pwm-rockchip.h                                                                       |  187 
 kernel/arch/powerpc/kernel/fadump.c                                                                       |    1 
 kernel/drivers/power/supply/cros_usbpd-charger.c                                                          |    2 
 kernel/drivers/iio/adc/ad7791.c                                                                           |    2 
 kernel/net/core/sock.c                                                                                    |   73 
 kernel/drivers/media/dvb-frontends/mn88443x.c                                                             |    2 
 kernel/drivers/net/ethernet/intel/igb/igb_ptp.c                                                           |   24 
 kernel/kernel/panic.c                                                                                     |   90 
 kernel/fs/cifs/connect.c                                                                                  |    4 
 kernel/drivers/media/i2c/cam-tb-setup.c                                                                   |   97 
 kernel/drivers/infiniband/hw/hns/hns_roce_srq.c                                                           |    1 
 kernel/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c                                                     |    2 
 kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c                                                          |    6 
 kernel/drivers/media/i2c/cam-tb-setup.h                                                                   |   33 
 kernel/drivers/media/i2c/sc4336p.c                                                                        | 1586 
 kernel/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c                                                         |   39 
 kernel/drivers/phy/ti/Kconfig                                                                             |    4 
 kernel/kernel/futex/core.c                                                                                |   28 
 kernel/sound/pci/ac97/ac97_codec.c                                                                        |    5 
 kernel/drivers/scsi/mpt3sas/mpt3sas_base.c                                                                |   69 
 kernel/net/ipv6/netfilter/nft_reject_ipv6.c                                                               |    3 
 kernel/sound/soc/qcom/lpass-sc7180.c                                                                      |    3 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v20.dts                                            |   73 
 kernel/lib/Kconfig.debug                                                                                  |    1 
 kernel/drivers/media/dvb-frontends/ec100.c                                                                |    2 
 kernel/drivers/scsi/mpt3sas/mpt3sas_base.h                                                                |    1 
 kernel/arch/mips/alchemy/devboards/db1000.c                                                               |   12 
 kernel/fs/pstore/ram.c                                                                                    |    4 
 kernel/drivers/iio/gyro/adis16136.c                                                                       |    1 
 kernel/drivers/spi/spi-fsl-spi.c                                                                          |   51 
 kernel/drivers/infiniband/ulp/rtrs/rtrs.c                                                                 |    4 
 kernel/drivers/misc/fastrpc.c                                                                             |   35 
 kernel/arch/x86/kvm/x86.c                                                                                 |  179 
 kernel/drivers/media/i2c/sc223a.c                                                                         |  322 
 kernel/drivers/mfd/rt5033.c                                                                               |    3 
 kernel/include/uapi/linux/rk-pcie-ep.h                                                                    |   57 
 kernel/drivers/crypto/rockchip/cryptodev_linux/rk_cryptodev.c                                             |    2 
 kernel/tools/virtio/linux/bug.h                                                                           |    8 
 kernel/net/bpf/test_run.c                                                                                 |    3 
 kernel/arch/arm64/boot/dts/rockchip/rk3568-pcie-ep-lp4x-v10-linux.dts                                     |  641 
 kernel/drivers/irqchip/irq-mvebu-gicp.c                                                                   |    1 
 kernel/arch/s390/kvm/vsie.c                                                                               |    6 
 kernel/drivers/net/ethernet/qlogic/qed/qed_ll2.h                                                          |    2 
 kernel/drivers/dma/mv_xor_v2.c                                                                            |    2 
 kernel/drivers/gpu/drm/msm/adreno/a6xx_gpu.c                                                              |    4 
 kernel/arch/arm/boot/dts/bcm53016-meraki-mr32.dts                                                         |    2 
 kernel/drivers/watchdog/diag288_wdt.c                                                                     |   15 
 kernel/drivers/gpu/drm/bridge/lontium-lt9611.c                                                            |   66 
 kernel/kernel/scftorture.c                                                                                |    6 
 kernel/sound/usb/format.c                                                                                 |    9 
 kernel/drivers/gpu/drm/nouveau/nouveau_connector.c                                                        |    5 
 kernel/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c                                                   |    6 
 kernel/net/ipv6/netfilter/nf_tproxy_ipv6.c                                                                |    2 
 kernel/drivers/leds/trigger/ledtrig-netdev.c                                                              |    3 
 kernel/drivers/scsi/qla2xxx/qla_gbl.h                                                                     |    3 
 kernel/mm/frame_vector.c                                                                                  |    6 
 kernel/drivers/scsi/qla2xxx/qla_def.h                                                                     |   13 
 kernel/samples/ftrace/ftrace-direct-too.c                                                                 |   14 
 kernel/fs/reiserfs/super.c                                                                                |    6 
 kernel/drivers/gpu/drm/panel/panel-sitronix-st7701.c                                                      |   10 
 kernel/mm/madvise.c                                                                                       |    9 
 kernel/drivers/usb/gadget/udc/tegra-xudc.c                                                                |   10 
 kernel/drivers/gpu/drm/rockchip/Makefile                                                                  |    2 
 kernel/arch/arm64/boot/dts/rockchip/rk3528-evb.dtsi                                                       |    2 
 kernel/drivers/dax/bus.c                                                                                  |   63 
 kernel/net/netfilter/nft_redir.c                                                                          |    4 
 kernel/arch/powerpc/kernel/time.c                                                                         |    4 
 kernel/tools/perf/pmu-events/Build                                                                        |    5 
 kernel/drivers/net/ppp/pptp.c                                                                             |   31 
 kernel/drivers/gpu/drm/tegra/dpaux.c                                                                      |    6 
 kernel/drivers/media/platform/qcom/venus/vdec.c                                                           |  120 
 kernel/arch/x86/include/asm/kprobes.h                                                                     |   24 
 kernel/sound/soc/codecs/rt5665.c                                                                          |    2 
 kernel/lib/iov_iter.c                                                                                     |   14 
 kernel/drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c                                                      |    2 
 kernel/drivers/gpu/drm/radeon/ni_dpm.c                                                                    |    8 
 kernel/drivers/gpu/drm/msm/dsi/dsi_host.c                                                                 |    3 
 kernel/arch/arm/boot/dts/omap443x.dtsi                                                                    |    1 
 kernel/sound/soc/rockchip/rockchip_i2s.h                                                                  |   22 
 kernel/include/net/sctp/structs.h                                                                         |    1 
 kernel/sound/soc/rockchip/rockchip_i2s.c                                                                  |   92 
 kernel/drivers/scsi/Kconfig                                                                               |    2 
 kernel/drivers/irqchip/irq-brcmstb-l2.c                                                                   |    6 
 kernel/tools/perf/builtin-bench.c                                                                         |    7 
 kernel/drivers/edac/edac_device.c                                                                         |   30 
 kernel/drivers/infiniband/core/verbs.c                                                                    |    9 
 kernel/drivers/soc/ti/smartreflex.c                                                                       |    1 
 kernel/drivers/media/usb/dvb-usb/m920x.c                                                                  |    5 
 kernel/drivers/usb/gadget/legacy/inode.c                                                                  |   28 
 kernel/drivers/media/i2c/maxim2c/maxim2c_i2c.c                                                            |  407 
 kernel/drivers/dma-buf/heaps/page_pool.c                                                                  |    1 
 kernel/drivers/media/platform/rockchip/isp/csi.c                                                          |   10 
 kernel/include/linux/kprobes.h                                                                            |    2 
 kernel/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c                                  |   62 
 kernel/drivers/media/platform/rockchip/isp/csi.h                                                          |    2 
 kernel/mm/userfaultfd.c                                                                                   |    2 
 kernel/net/netfilter/nft_chain_filter.c                                                                   |   11 
 kernel/net/ipv6/udp.c                                                                                     |   46 
 kernel/drivers/infiniband/ulp/srp/ib_srp.c                                                                |  100 
 kernel/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.h                                  |    4 
 kernel/drivers/infiniband/sw/siw/siw_cq.c                                                                 |   24 
 kernel/drivers/infiniband/ulp/srp/ib_srp.h                                                                |    8 
 kernel/drivers/usb/serial/usb-serial-simple.c                                                             |   73 
 kernel/kernel/pid_namespace.c                                                                             |   17 
 kernel/drivers/net/wireless/ray_cs.c                                                                      |   36 
 kernel/drivers/base/power/runtime.c                                                                       |   24 
 kernel/kernel/time/alarmtimer.c                                                                           |   40 
 kernel/drivers/mfd/display-serdes/rohm/rohm-bu18tl82.c                                                    |    6 
 kernel/drivers/gpu/drm/i915/gt/intel_reset.c                                                              |   34 
 kernel/kernel/exit.c                                                                                      |   72 
 kernel/kernel/cgroup/cgroup.c                                                                             |   42 
 kernel/drivers/net/ethernet/socionext/netsec.c                                                            |   11 
 kernel/drivers/net/ethernet/qlogic/qed/qed_debug.c                                                        |    3 
 kernel/sound/soc/codecs/tlv320adcx140.c                                                                   |    2 
 kernel/drivers/soc/qcom/cpr.c                                                                             |    6 
 kernel/include/linux/rcutree.h                                                                            |    2 
 kernel/Documentation/devicetree/bindings/sound/tas2770.yaml                                               |    6 
 kernel/kernel/trace/ring_buffer.c                                                                         |  184 
 kernel/drivers/watchdog/watchdog_dev.c                                                                    |    2 
 kernel/crypto/asymmetric_keys/verify_pefile.c                                                             |   32 
 kernel/drivers/scsi/storvsc_drv.c                                                                         |   30 
 kernel/drivers/usb/chipidea/ci.h                                                                          |    2 
 kernel/android/abi_gki_aarch64_zebra                                                                      |    4 
 kernel/drivers/dma/dw-edma/dw-edma-core.c                                                                 |   27 
 kernel/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c                                             |    6 
 kernel/sound/soc/codecs/da7219-aad.c                                                                      |   12 
 kernel/drivers/net/ipvlan/ipvlan_main.c                                                                   |    3 
 kernel/drivers/clk/at91/clk-sam9x60-pll.c                                                                 |    2 
 kernel/drivers/md/dm.c                                                                                    |    6 
 kernel/drivers/cpuidle/cpuidle-psci-domain.c                                                              |    3 
 kernel/drivers/usb/class/usbtmc.c                                                                         |    2 
 kernel/Documentation/scsi/scsi_mid_low_api.rst                                                            |    4 
 kernel/arch/x86/kernel/cpu/mce/core.c                                                                     |   96 
 kernel/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c                                                       |    4 
 kernel/arch/powerpc/perf/hv-24x7.c                                                                        |   44 
 kernel/drivers/gpu/drm/bridge/adv7511/adv7533.c                                                           |   28 
 kernel/drivers/net/dsa/vitesse-vsc73xx-core.c                                                             |    6 
 kernel/sound/soc/pxa/mmp-pcm.c                                                                            |    2 
 kernel/net/netfilter/xt_u32.c                                                                             |   21 
 kernel/drivers/regulator/stm32-pwr.c                                                                      |    7 
 kernel/drivers/ntb/ntb_transport.c                                                                        |   21 
 kernel/drivers/rapidio/rio.c                                                                              |    9 
 kernel/drivers/usb/gadget/legacy/raw_gadget.c                                                             |   12 
 kernel/drivers/media/i2c/cam-sleep-wakeup.h                                                               |  131 
 kernel/arch/arm64/include/asm/scs.h                                                                       |    7 
 kernel/drivers/gpu/drm/msm/adreno/a5xx_preempt.c                                                          |   16 
 kernel/drivers/staging/comedi/drivers/adv_pci1760.c                                                       |    2 
 kernel/include/linux/printk.h                                                                             |   19 
 kernel/net/ipv4/tcp_timer.c                                                                               |   22 
 kernel/drivers/infiniband/hw/bnxt_re/qplib_fp.h                                                           |    2 
 kernel/net/core/filter.c                                                                                  |   32 
 kernel/drivers/usb/core/usb.h                                                                             |    4 
 kernel/drivers/infiniband/hw/bnxt_re/qplib_fp.c                                                           |   51 
 kernel/drivers/media/platform/rockchip/isp/capture_v30.c                                                  |   15 
 kernel/arch/arm64/configs/rk3308bs_mipi_display.config                                                    |    1 
 kernel/drivers/usb/core/usb.c                                                                             |   76 
 kernel/drivers/infiniband/hw/hfi1/user_exp_rcv.c                                                          |  211 
 kernel/net/9p/trans_rdma.c                                                                                |   15 
 kernel/drivers/media/i2c/cam-sleep-wakeup.c                                                               |  198 
 kernel/drivers/rkflash/Kconfig                                                                            |    2 
 kernel/net/sched/sch_atm.c                                                                                |    5 
 kernel/tools/testing/selftests/bpf/test_verifier.c                                                        |   12 
 kernel/arch/x86/kernel/cpu/microcode/intel.c                                                              |    8 
 kernel/drivers/power/supply/rk816_battery.c                                                               |    7 
 kernel/drivers/scsi/qla2xxx/qla_attr.c                                                                    |   15 
 kernel/fs/coda/upcall.c                                                                                   |    2 
 kernel/drivers/crypto/rockchip/rk3288_crypto_ahash.c                                                      |  193 
 kernel/tools/include/linux/objtool.h                                                                      |   28 
 kernel/drivers/media/i2c/maxim2c/maxim2c_link.c                                                           |  618 
 kernel/drivers/xen/events/events_base.c                                                                   |   87 
 kernel/drivers/media/i2c/maxim2c/maxim2c_link.h                                                           |   80 
 kernel/arch/arm/boot/dts/rv1106-uvc.dtsi                                                                  |    1 
 kernel/drivers/usb/serial/cp210x.c                                                                        |    2 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/main.c                                                     |   14 
 kernel/arch/arm/configs/rv1106-evb.config                                                                 |    4 
 kernel/drivers/infiniband/hw/hfi1/user_exp_rcv.h                                                          |    3 
 kernel/drivers/mfd/display-serdes/maxim/maxim-max96789.h                                                  |  184 
 kernel/Documentation/fault-injection/fault-injection.rst                                                  |   16 
 kernel/drivers/mfd/display-serdes/maxim/maxim-max96789.c                                                  |  549 
 kernel/drivers/video/fbdev/mmp/hw/mmp_ctrl.c                                                              |    4 
 kernel/drivers/nvme/host/trace.h                                                                          |   15 
 kernel/drivers/nvme/target/passthru.c                                                                     |   11 
 kernel/drivers/block/Makefile                                                                             |    9 
 kernel/drivers/gpio/gpio-sifive.c                                                                         |    1 
 kernel/arch/Kconfig                                                                                       |    3 
 kernel/net/smc/smc_close.c                                                                                |    4 
 kernel/drivers/gpu/drm/sti/sti_dvo.c                                                                      |    7 
 kernel/drivers/spi/spi-cadence-quadspi.c                                                                  |   19 
 kernel/fs/fuse/virtio_fs.c                                                                                |   46 
 kernel/arch/parisc/include/uapi/asm/socket.h                                                              |    2 
 kernel/drivers/gpu/drm/rockchip/cdn-dp-core.c                                                             |    2 
 kernel/drivers/net/ethernet/amd/nmclan_cs.c                                                               |    2 
 kernel/drivers/memory/atmel-sdramc.c                                                                      |    6 
 kernel/drivers/clk/tegra/clk-tegra20.c                                                                    |   26 
 kernel/drivers/usb/gadget/function/f_hid.c                                                                |    1 
 kernel/include/linux/page_pinner.h                                                                        |    6 
 kernel/sound/Kconfig                                                                                      |    2 
 kernel/kernel/kheaders.c                                                                                  |   10 
 kernel/arch/arm/boot/dts/s5pv210.dtsi                                                                     |    2 
 kernel/crypto/essiv.c                                                                                     |    7 
 kernel/drivers/gpu/drm/msm/msm_iommu.c                                                                    |    7 
 kernel/drivers/gpu/drm/nouveau/dispnv50/wndw.c                                                            |   12 
 kernel/include/linux/objtool.h                                                                            |   28 
 kernel/drivers/gpu/drm/nouveau/dispnv50/wndw.h                                                            |    7 
 kernel/sound/pci/hda/hda_generic.c                                                                        |    7 
 kernel/drivers/gpu/drm/drm_gem_shmem_helper.c                                                             |   15 
 kernel/drivers/rtc/rtc-meson-vrtc.c                                                                       |    4 
 kernel/net/netfilter/nft_set_pipapo.c                                                                     |  154 
 kernel/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt                                    |   12 
 kernel/net/mac80211/sta_info.c                                                                            |    5 
 kernel/fs/nfs/write.c                                                                                     |   23 
 kernel/arch/x86/mm/pkeys.c                                                                                |    6 
 kernel/drivers/misc/sgi-gru/grumain.c                                                                     |   22 
 kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-one-vp-two-single-channel-lvds.dts               |   91 
 kernel/security/keys/trusted-keys/trusted_tpm2.c                                                          |    2 
 kernel/drivers/crypto/Kconfig                                                                             |    1 
 kernel/drivers/mfd/arizona-core.c                                                                         |    2 
 kernel/drivers/firmware/efi/efi.c                                                                         |   15 
 kernel/arch/arm64/boot/dts/mediatek/mt8183.dtsi                                                           |   12 
 kernel/fs/reiserfs/xattr_security.c                                                                       |   10 
 kernel/drivers/pci/hotplug/acpiphp_glue.c                                                                 |    9 
 kernel/drivers/gpu/drm/vc4/vc4_hdmi.c                                                                     |    8 
 kernel/arch/powerpc/platforms/embedded6xx/wii.c                                                           |    4 
 kernel/drivers/rknpu/rknpu_job.c                                                                          |  130 
 kernel/drivers/media/i2c/ar2020.c                                                                         | 5413 +
 kernel/fs/statfs.c                                                                                        |    4 
 kernel/arch/powerpc/include/asm/nohash/64/pgtable.h                                                       |    6 
 kernel/arch/powerpc/platforms/pseries/hotplug-cpu.c                                                       |    2 
 kernel/drivers/crypto/amcc/crypto4xx_core.c                                                               |   10 
 kernel/include/uapi/linux/sync_file.h                                                                     |    2 
 kernel/drivers/hwmon/ina3221.c                                                                            |    2 
 kernel/net/smc/smc_tx.c                                                                                   |    4 
 kernel/net/sched/sch_api.c                                                                                |   94 
 kernel/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts                                        |    2 
 kernel/tools/testing/selftests/net/mptcp/simult_flows.sh                                                  |    4 
 kernel/drivers/block/sunvdc.c                                                                             |    2 
 kernel/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml                                 |    2 
 kernel/include/xen/xen.h                                                                                  |   11 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-display-v20.dtsi                                |  795 
 kernel/drivers/media/platform/qcom/venus/core.h                                                           |   17 
 kernel/arch/mips/kernel/cpu-probe.c                                                                       |    9 
 kernel/drivers/media/platform/qcom/venus/core.c                                                           |   12 
 kernel/drivers/mfd/display-serdes/maxim/maxim-max96745.h                                                  |    7 
 kernel/arch/x86/mm/pgtable.c                                                                              |    2 
 kernel/drivers/infiniband/ulp/rtrs/rtrs-clt.c                                                             |    2 
 kernel/drivers/mfd/display-serdes/maxim/maxim-max96745.c                                                  |  244 
 kernel/drivers/media/pci/bt8xx/dst.c                                                                      |    2 
 kernel/fs/fs_context.c                                                                                    |    3 
 kernel/drivers/net/ethernet/intel/i40e/i40e_alloc.h                                                       |   17 
 kernel/tools/virtio/linux/gfp.h                                                                           |    7 
 kernel/drivers/i2c/busses/i2c-pxa-pci.c                                                                   |   10 
 kernel/fs/ext4/xattr.c                                                                                    |  317 
 kernel/net/sched/act_ipt.c                                                                                |    2 
 kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c                                                     |   96 
 kernel/fs/ext4/xattr.h                                                                                    |    7 
 kernel/arch/riscv/Makefile                                                                                |   15 
 kernel/net/netfilter/nft_lookup.c                                                                         |    2 
 kernel/drivers/media/platform/rockchip/cif/dev.h                                                          |   63 
 kernel/sound/soc/codecs/rt5682-sdw.c                                                                      |    7 
 kernel/tools/testing/selftests/sigaltstack/current_stack_pointer.h                                        |   23 
 kernel/arch/x86/kvm/vmx/nested.c                                                                          |   65 
 kernel/kernel/rcu/tree.h                                                                                  |    1 
 kernel/drivers/usb/storage/scsiglue.c                                                                     |   28 
 kernel/drivers/media/platform/rockchip/cif/dev.c                                                          |   64 
 kernel/arch/x86/kernel/cpu/resctrl/rdtgroup.c                                                             |   48 
 kernel/drivers/video/backlight/lv5207lp.c                                                                 |    2 
 kernel/drivers/gpu/drm/panfrost/Kconfig                                                                   |    3 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/sriov.c                                                    |    3 
 kernel/net/sched/sch_cbq.c                                                                                |    4 
 kernel/drivers/ata/ahci.c                                                                                 |  152 
 kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-v13-android-avb.dts                             |    2 
 kernel/drivers/gpu/drm/drm_atomic_uapi.c                                                                  |   14 
 kernel/fs/ext4/migrate.c                                                                                  |    6 
 kernel/net/batman-adv/hard-interface.c                                                                    |   14 
 kernel/drivers/ata/ahci.h                                                                                 |  241 
 kernel/arch/x86/kernel/smpboot.c                                                                          |   27 
 kernel/net/ipv4/esp4.c                                                                                    |    2 
 kernel/drivers/mmc/host/sunxi-mmc.c                                                                       |   12 
 kernel/tools/testing/selftests/tc-testing/config                                                          |    1 
 kernel/kernel/rcu/tree.c                                                                                  |   73 
 kernel/drivers/media/i2c/ov772x.c                                                                         |    3 
 kernel/tools/perf/bench/bench.h                                                                           |   12 
 kernel/drivers/clk/tegra/clk-bpmp.c                                                                       |    2 
 kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.h                                                     |   35 
 kernel/drivers/media/usb/dvb-usb/digitv.c                                                                 |    4 
 kernel/security/tomoyo/Makefile                                                                           |    2 
 kernel/arch/x86/kernel/fpu/core.c                                                                         |   67 
 kernel/drivers/interconnect/qcom/osm-l3.c                                                                 |    2 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy0.dtsi                          |   46 
 kernel/arch/arm/boot/dts/omap3-zoom3.dts                                                                  |   44 
 kernel/fs/ext2/ext2.h                                                                                     |   13 
 kernel/arch/arm/boot/dts/imx6qdl-gw560x.dtsi                                                              |    1 
 kernel/tools/perf/util/data.c                                                                             |    2 
 kernel/arch/nios2/boot/dts/3c120_devboard.dts                                                             |    2 
 kernel/drivers/gpio/gpio-pxa.c                                                                            |    1 
 kernel/drivers/net/wireless/broadcom/b43/b43.h                                                            |    2 
 kernel/arch/arm64/kernel/sdei.c                                                                           |    3 
 kernel/drivers/vme/bridges/vme_fake.c                                                                     |    2 
 kernel/drivers/iio/gyro/adis16260.c                                                                       |    1 
 kernel/drivers/iio/addac/Makefile                                                                         |    6 
 kernel/drivers/media/dvb-frontends/cx24123.c                                                              |    2 
 kernel/net/xdp/xsk.c                                                                                      |    5 
 kernel/Documentation/sound/hd-audio/models.rst                                                            |    2 
 kernel/drivers/media/usb/dvb-usb-v2/ec168.c                                                               |   12 
 kernel/drivers/misc/mei/pci-me.c                                                                          |    2 
 kernel/arch/arm/mm/nommu.c                                                                                |    2 
 kernel/include/linux/iopoll.h                                                                             |    2 
 kernel/tools/testing/selftests/bpf/Makefile                                                               |    2 
 kernel/arch/x86/kernel/apm_32.c                                                                           |    6 
 kernel/fs/btrfs/send.c                                                                                    |    6 
 kernel/drivers/video/fbdev/geode/lxfb_core.c                                                              |    3 
 kernel/drivers/media/pci/solo6x10/solo6x10-core.c                                                         |    1 
 kernel/arch/alpha/kernel/traps.c                                                                          |   36 
 kernel/net/batman-adv/soft-interface.c                                                                    |    3 
 kernel/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h                                                                |   13 
 kernel/net/netfilter/nft_payload.c                                                                        |   12 
 kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu.c                                                    |  134 
 kernel/net/netfilter/nf_conntrack_helper.c                                                                |    4 
 kernel/drivers/media/dvb-core/dvb_frontend.c                                                              |   26 
 kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu.h                                                    |   15 
 kernel/tools/testing/selftests/net/forwarding/settings                                                    |    1 
 kernel/arch/alpha/include/uapi/asm/socket.h                                                               |    2 
 kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c                                                            |   13 
 kernel/arch/arm64/boot/dts/qcom/sdm845.dtsi                                                               |   33 
 kernel/arch/x86/kvm/cpuid.h                                                                               |    1 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy1.dtsi                         |   48 
 kernel/drivers/power/supply/bq27xxx_battery.c                                                             |  269 
 kernel/net/netfilter/nf_conntrack_proto_icmpv6.c                                                          |   53 
 kernel/drivers/net/ipvlan/ipvlan_core.c                                                                   |   15 
 kernel/include/linux/tty.h                                                                                |   97 
 kernel/kernel/bpf/btf.c                                                                                   |   39 
 kernel/arch/x86/kvm/cpuid.c                                                                               |   37 
 kernel/tools/testing/selftests/Makefile                                                                   |   26 
 kernel/fs/cifs/smb2inode.c                                                                                |   31 
 kernel/net/bluetooth/rfcomm/core.c                                                                        |    2 
 kernel/fs/exfat/namei.c                                                                                   |   11 
 kernel/arch/powerpc/mm/init_64.c                                                                          |    5 
 kernel/drivers/media/dvb-frontends/ascot2e.c                                                              |    2 
 kernel/arch/arm/boot/dts/imx6dl-prtrvt.dts                                                                |    4 
 kernel/drivers/macintosh/Kconfig                                                                          |    1 
 kernel/drivers/net/ethernet/broadcom/bgmac.h                                                              |    2 
 kernel/drivers/tty/serial/8250/8250.h                                                                     |   12 
 kernel/drivers/infiniband/core/uverbs_std_types_counters.c                                                |    2 
 kernel/drivers/net/wireless/ath/ath6kl/bmi.c                                                              |    2 
 kernel/arch/mips/include/uapi/asm/socket.h                                                                |    2 
 kernel/drivers/iommu/iommu.c                                                                              |   28 
 kernel/crypto/cryptd.c                                                                                    |   36 
 kernel/drivers/media/i2c/maxim2c/maxim2c_pattern.h                                                        |   15 
 kernel/drivers/net/ethernet/freescale/enetc/enetc_ptp.c                                                   |    2 
 kernel/drivers/media/platform/rockchip/isp1/dev.c                                                         |    1 
 kernel/arch/mips/include/asm/dec/prom.h                                                                   |    2 
 kernel/security/integrity/evm/evm_main.c                                                                  |    2 
 kernel/arch/mips/include/asm/bugs.h                                                                       |   17 
 kernel/drivers/pci/pci-sysfs.c                                                                            |   13 
 kernel/drivers/media/i2c/maxim2c/maxim2c_pattern.c                                                        |  351 
 kernel/drivers/media/i2c/techpoint/techpoint_dev.c                                                        |   30 
 kernel/drivers/media/dvb-core/dvb_net.c                                                                   |   38 
 kernel/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c                                                 |   10 
 kernel/arch/mips/configs/rm200_defconfig                                                                  |    2 
 kernel/include/media/dvb_net.h                                                                            |    4 
 kernel/tools/lib/bpf/bpf_helpers.h                                                                        |   15 
 kernel/arch/mips/alchemy/devboards/db1300.c                                                               |   14 
 kernel/drivers/net/wireless/rsi/rsi_91x_hal.c                                                             |    6 
 kernel/arch/arm64/boot/dts/rockchip/rk3562-amp.dtsi                                                       |    7 
 kernel/drivers/iio/adc/ti-ads7950.c                                                                       |    1 
 kernel/net/sched/act_sample.c                                                                             |   13 
 kernel/fs/udf/udf_sb.h                                                                                    |    2 
 kernel/tools/testing/radix-tree/regression1.c                                                             |    2 
 kernel/drivers/net/ethernet/intel/igc/igc_main.c                                                          |  296 
 kernel/drivers/tty/tty_mutex.c                                                                            |    1 
 kernel/arch/arm64/boot/dts/qcom/ipq8074.dtsi                                                              |   93 
 kernel/arch/parisc/kernel/process.c                                                                       |   11 
 kernel/drivers/net/wireless/rsi/rsi_91x_coex.c                                                            |    1 
 kernel/kernel/bpf/core.c                                                                                  |    5 
 kernel/include/uapi/linux/ip.h                                                                            |    1 
 kernel/drivers/net/ethernet/broadcom/bgmac.c                                                              |   12 
 kernel/net/mac80211/ieee80211_i.h                                                                         |   24 
 kernel/drivers/net/phy/microchip.c                                                                        |   32 
 kernel/drivers/mmc/host/sdhci-sprd.c                                                                      |   16 
 kernel/drivers/s390/cio/device.c                                                                          |    5 
 kernel/security/keys/request_key.c                                                                        |   44 
 kernel/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi                                                  |   11 
 kernel/drivers/mfd/display-serdes/serdes-bridge.c                                                         |   62 
 kernel/drivers/media/dvb-frontends/cx24110.c                                                              |    2 
 kernel/include/linux/units.h                                                                              |   16 
 kernel/arch/arm64/kernel/kgdb.c                                                                           |    2 
 kernel/include/linux/mfd/rk630.h                                                                          |  344 
 kernel/fs/f2fs/super.c                                                                                    |   67 
 kernel/fs/jffs2/build.c                                                                                   |    5 
 kernel/drivers/scsi/qla2xxx/qla_inline.h                                                                  |   51 
 kernel/net/netfilter/nft_tproxy.c                                                                         |   12 
 kernel/drivers/net/ethernet/apple/mace.c                                                                  |    2 
 kernel/sound/soc/fsl/imx-audmix.c                                                                         |   11 
 kernel/drivers/misc/mei/bus-fixup.c                                                                       |    8 
 kernel/arch/arm/boot/dts/bcm53015-meraki-mr26.dts                                                         |    2 
 kernel/drivers/scsi/scsi_proc.c                                                                           |   30 
 kernel/drivers/input/touchscreen/gt9xx/gt9xx_cfg.h                                                        |   16 
 kernel/drivers/i2c/busses/i2c-ismt.c                                                                      |    3 
 kernel/drivers/firmware/arm_scmi/mailbox.c                                                                |   37 
 kernel/net/packet/internal.h                                                                              |   26 
 kernel/drivers/media/platform/qcom/venus/hfi_venus.c                                                      |   94 
 kernel/drivers/macintosh/windfarm_lm75_sensor.c                                                           |    4 
 kernel/drivers/net/wireless/ath/ath9k/htc_hst.c                                                           |   12 
 kernel/arch/arm/boot/dts/rv1106g-evb2-v10-dual-camera.dts                                                 |    2 
 kernel/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi                                                           |    3 
 kernel/net/xfrm/xfrm_state.c                                                                              |    3 
 kernel/drivers/spi/spidev.c                                                                               |   23 
 kernel/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c                                                    |   19 
 kernel/drivers/mtd/nand/spi/toshiba.c                                                                     |    4 
 kernel/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h                                                     |    2 
 kernel/fs/nfsd/nfs4layouts.c                                                                              |    4 
 kernel/arch/x86/include/asm/cpufeature.h                                                                  |   10 
 kernel/Documentation/kernel-hacking/locking.rst                                                           |    2 
 kernel/drivers/bluetooth/btsdio.c                                                                         |    1 
 kernel/drivers/acpi/acpica/utcopy.c                                                                       |    7 
 kernel/sound/soc/intel/skylake/skl.c                                                                      |    7 
 kernel/include/sound/soc-dpcm.h                                                                           |    4 
 kernel/drivers/mfd/rkx110_x120/rkx110_reg.h                                                               |   67 
 kernel/fs/notify/inotify/inotify_fsnotify.c                                                               |   11 
 kernel/drivers/gpu/drm/bridge/tc358768.c                                                                  |   93 
 kernel/drivers/infiniband/hw/hfi1/mmu_rb.h                                                                |   11 
 kernel/drivers/gpu/drm/drm_panel_orientation_quirks.c                                                     |   25 
 kernel/drivers/rapidio/rio-scan.c                                                                         |    8 
 kernel/drivers/infiniband/hw/hfi1/mmu_rb.c                                                                |  160 
 kernel/arch/x86/kernel/cpu/cpu.h                                                                          |    2 
 kernel/arch/arm64/boot/dts/rockchip/rk3562-evb2-ddr4-v10-linux-amp.dts                                    |   29 
 kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c                                            |   46 
 kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c                                                    |    8 
 kernel/drivers/usb/host/ohci-at91.c                                                                       |    8 
 kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-single-channel-lvds.dts                          |  114 
 kernel/drivers/net/wireless/rsi/rsi_91x_core.c                                                            |    4 
 kernel/include/linux/sh_intc.h                                                                            |    5 
 kernel/kernel/watchdog_hld.c                                                                              |    6 
 kernel/net/ipv4/ip_tunnel_core.c                                                                          |    2 
 kernel/tools/virtio/linux/kernel.h                                                                        |    1 
 kernel/drivers/tty/tty_ldisc.c                                                                            |    1 
 kernel/drivers/infiniband/hw/mlx4/qp.c                                                                    |   26 
 kernel/drivers/media/pci/saa7164/saa7164-core.c                                                           |    4 
 kernel/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi                                                 |   44 
 kernel/fs/btrfs/free-space-cache.c                                                                        |    7 
 kernel/fs/incfs/pseudo_files.c                                                                            |    4 
 kernel/drivers/net/wireless/marvell/mwifiex/pcie.c                                                        |   27 
 kernel/drivers/crypto/ccree/cc_driver.c                                                                   |   10 
 kernel/arch/sparc/include/asm/pgtable_64.h                                                                |   10 
 kernel/drivers/ata/pata_arasan_cf.c                                                                       |    3 
 kernel/kernel/printk/printk_ringbuffer.c                                                                  |    2 
 kernel/drivers/media/dvb-frontends/zl10036.c                                                              |    2 
 kernel/drivers/gpio/gpiolib-cdev.c                                                                        |   97 
 kernel/drivers/infiniband/hw/bnxt_re/qplib_sp.c                                                           |   22 
 kernel/drivers/media/i2c/mis2031.c                                                                        | 1651 
 kernel/drivers/net/ethernet/sun/niu.c                                                                     |    2 
 kernel/arch/arm64/boot/dts/rockchip/rk3588s-evb3-lp4x-v10-sii9022-bt1120-to-hdmi.dts                      |   15 
 kernel/net/sctp/sm_statefuns.c                                                                            |    2 
 kernel/arch/arm/mach-rockchip/Kconfig                                                                     |    6 
 kernel/drivers/infiniband/hw/bnxt_re/qplib_sp.h                                                           |    2 
 kernel/drivers/thunderbolt/nhi.c                                                                          |    2 
 kernel/drivers/net/wireless/intersil/orinoco/spectrum_cs.c                                                |   13 
 kernel/fs/nfs/nfs4trace.h                                                                                 |   42 
 kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c                                        |    5 
 kernel/drivers/thermal/qcom/tsens-v1.c                                                                    |   63 
 kernel/net/vmw_vsock/af_vsock.c                                                                           |    2 
 kernel/arch/arm64/boot/dts/rockchip/rk3399-android.dtsi                                                   |   10 
 kernel/drivers/crypto/amlogic/amlogic-gxl-core.c                                                          |    1 
 kernel/drivers/gpu/drm/amd/pm/amdgpu_pm.c                                                                 |   10 
 kernel/drivers/net/phy/marvell10g.c                                                                       |    7 
 kernel/net/tipc/socket.c                                                                                  |    4 
 kernel/drivers/scsi/fcoe/fcoe.c                                                                           |    1 
 kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c                                                           |    1 
 kernel/drivers/gpu/drm/i915/display/intel_dsi_vbt.c                                                       |    4 
 kernel/drivers/pci/pci-driver.c                                                                           |    4 
 kernel/drivers/gpu/drm/i915/gem/i915_gem_tiling.c                                                         |    9 
 kernel/drivers/mtd/spi-nor/sfdp.c                                                                         |    4 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb2-lp4-v10-edp.dts                                           |    4 
 kernel/drivers/gpu/drm/meson/meson_vpp.c                                                                  |    2 
 kernel/drivers/mfd/display-serdes/serdes-i2c.c                                                            |   93 
 kernel/arch/alpha/kernel/entry.S                                                                          |    4 
 kernel/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h                                                      |    9 
 kernel/lib/cpu_rmap.c                                                                                     |    5 
 kernel/arch/x86/kernel/cpu/microcode/core.c                                                               |  148 
 kernel/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c                                                      |  185 
 kernel/drivers/media/i2c/ov16885.c                                                                        | 2165 
 kernel/drivers/clk/x86/clk-lgm.c                                                                          |   18 
 kernel/arch/powerpc/kernel/prom_init.c                                                                    |    3 
 kernel/drivers/spi/spi-tegra20-sflash.c                                                                   |    6 
 kernel/include/linux/iio/imu/adis.h                                                                       |   63 
 kernel/include/net/pkt_sched.h                                                                            |   13 
 kernel/drivers/thermal/imx8mm_thermal.c                                                                   |    8 
 kernel/drivers/gpu/drm/msm/hdmi/hdmi.c                                                                    |   82 
 kernel/drivers/rpmsg/Makefile                                                                             |    3 
 kernel/drivers/usb/gadget/function/u_ether.c                                                              |    3 
 kernel/drivers/net/virtio_net.c                                                                           |   63 
 kernel/drivers/extcon/extcon.c                                                                            |    8 
 kernel/drivers/iio/adc/at91-sama5d2_adc.c                                                                 |    2 
 kernel/mm/memory_hotplug.c                                                                                |  111 
 kernel/drivers/gpu/drm/msm/hdmi/hdmi.h                                                                    |   32 
 kernel/drivers/ata/ahci_brcm.c                                                                            |    2 
 kernel/drivers/regulator/core.c                                                                           |  142 
 kernel/include/linux/bpf.h                                                                                |    2 
 kernel/drivers/scsi/qla4xxx/ql4_os.c                                                                      |   15 
 kernel/net/sctp/sm_sideeffect.c                                                                           |    5 
 kernel/mm/rmap.c                                                                                          |   31 
 kernel/drivers/hid/hid-logitech-dj.c                                                                      |    5 
 kernel/tools/include/linux/btf_ids.h                                                                      |    2 
 kernel/tools/testing/selftests/net/udpgso_bench.sh                                                        |   22 
 kernel/drivers/media/i2c/ov7670.c                                                                         |    2 
 kernel/drivers/pwm/pwm-imx-tpm.c                                                                          |    7 
 kernel/drivers/gpu/drm/amd/amdgpu/vi.c                                                                    |   11 
 kernel/drivers/tty/serial/8250/8250_tegra.c                                                               |    4 
 kernel/include/linux/proc_fs.h                                                                            |    2 
 kernel/drivers/usb/gadget/udc/fotg210-udc.c                                                               |   12 
 kernel/arch/arm/boot/dts/rv1106g-evb1-mcu-display-v20.dts                                                 |  302 
 kernel/drivers/gpio/gpio-tps68470.c                                                                       |    6 
 kernel/tools/testing/selftests/bpf/progs/connect4_prog.c                                                  |    2 
 kernel/fs/nfs/nfs4proc.c                                                                                  |   78 
 kernel/drivers/hwmon/gsc-hwmon.c                                                                          |    6 
 kernel/drivers/scsi/53c700.c                                                                              |    2 
 kernel/drivers/tty/Kconfig                                                                                |   12 
 kernel/fs/btrfs/print-tree.c                                                                              |    6 
 kernel/drivers/misc/cxl/pci.c                                                                             |   21 
 kernel/drivers/scsi/stex.c                                                                                |    4 
 kernel/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi                                                          |    6 
 kernel/drivers/mmc/core/sdio_cis.c                                                                        |   12 
 kernel/drivers/net/phy/dp83867.c                                                                          |   24 
 kernel/sound/soc/jz4740/jz4740-i2s.c                                                                      |   39 
 kernel/drivers/s390/block/dasd.c                                                                          |  133 
 kernel/include/linux/btf_ids.h                                                                            |    2 
 kernel/drivers/iio/adc/ad7192.c                                                                           |    8 
 kernel/kernel/gcov/gcc_4_7.c                                                                              |    5 
 kernel/drivers/hwmon/jc42.c                                                                               |  243 
 kernel/drivers/crypto/ccp/ccp-dmaengine.c                                                                 |   21 
 kernel/drivers/mtd/ubi/vmt.c                                                                              |   18 
 kernel/drivers/usb/cdns3/cdns3-pci-wrap.c                                                                 |    5 
 kernel/Makefile                                                                                           |  131 
 kernel/drivers/media/test-drivers/vimc/vimc-core.c                                                        |    2 
 kernel/arch/powerpc/perf/hv-gpci-requests.h                                                               |    4 
 kernel/drivers/memory/brcmstb_dpfe.c                                                                      |    4 
 kernel/fs/reiserfs/journal.c                                                                              |    4 
 kernel/drivers/net/usb/smsc75xx.c                                                                         |   11 
 kernel/include/uapi/linux/affs_hardblocks.h                                                               |   68 
 kernel/Documentation/powerpc/index.rst                                                                    |    1 
 kernel/tools/lib/bpf/bpf.h                                                                                |    7 
 kernel/tools/power/cpupower/bench/Makefile                                                                |    2 
 kernel/fs/ext4/block_validity.c                                                                           |   34 
 kernel/arch/powerpc/include/asm/paravirt.h                                                                |    1 
 kernel/block/blk-crypto.c                                                                                 |   69 
 kernel/drivers/scsi/ses.c                                                                                 |   74 
 kernel/drivers/power/supply/bq24190_charger.c                                                             |   77 
 kernel/block/bfq-iosched.c                                                                                |   19 
 kernel/drivers/media/dvb-frontends/tda10048.c                                                             |    2 
 kernel/drivers/net/wireless/ath/ath9k/xmit.c                                                              |    4 
 kernel/arch/arm/configs/rk3126_linux.config                                                               |    3 
 kernel/drivers/rtc/rtc-pm8xxx.c                                                                           |   24 
 kernel/drivers/soc/rockchip/Kconfig                                                                       |   15 
 kernel/arch/arm/boot/dts/exynos4412-itop-elite.dts                                                        |    2 
 kernel/drivers/net/wireless/mediatek/mt76/dma.c                                                           |   13 
 kernel/drivers/hwtracing/coresight/coresight-core.c                                                       |    9 
 kernel/drivers/video/fbdev/core/sysimgblt.c                                                               |   64 
 kernel/tools/bpf/bpftool/skeleton/profiler.bpf.c                                                          |   27 
 kernel/fs/cifs/transport.c                                                                                |   21 
 kernel/drivers/media/platform/rockchip/isp/dev.h                                                          |   14 
 kernel/drivers/usb/gadget/legacy/webcam.c                                                                 |    3 
 kernel/fs/incfs/data_mgmt.c                                                                               |   87 
 kernel/arch/m68k/kernel/entry.S                                                                           |    3 
 kernel/drivers/input/sensors/accel/icm4260x_acc.c                                                         |  470 
 kernel/fs/incfs/data_mgmt.h                                                                               |    6 
 kernel/sound/soc/generic/simple-card.c                                                                    |    1 
 kernel/drivers/mmc/host/sdhci.c                                                                           |    4 
 kernel/arch/xtensa/include/asm/core.h                                                                     |   13 
 kernel/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h                                                 |    6 
 kernel/drivers/i2c/busses/i2c-imx-lpi2c.c                                                                 |   10 
 kernel/fs/ext4/file.c                                                                                     |    4 
 kernel/drivers/regulator/rk806-regulator.c                                                                |   25 
 kernel/drivers/media/i2c/techpoint/techpoint_common.h                                                     |    1 
 kernel/fs/hfs/bnode.c                                                                                     |    1 
 kernel/drivers/mmc/host/atmel-mci.c                                                                       |   12 
 kernel/tools/perf/pmu-events/arch/powerpc/power9/other.json                                               |    4 
 kernel/drivers/gpu/drm/i915/intel_sideband.c                                                              |   15 
 kernel/arch/sh/kernel/nmi_debug.c                                                                         |    4 
 kernel/kernel/padata.c                                                                                    |   15 
 kernel/security/smack/smackfs.c                                                                           |    2 
 kernel/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c                                           |    6 
 kernel/kernel/time/posix-cpu-timers.c                                                                     |   81 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/en_main.c                                                  |    2 
 kernel/drivers/md/md-bitmap.c                                                                             |   92 
 kernel/fs/jfs/jfs_filsys.h                                                                                |    2 
 kernel/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c                                                     |    6 
 kernel/drivers/gpu/drm/virtio/virtgpu_ioctl.c                                                             |   10 
 kernel/sound/soc/fsl/fsl-asoc-card.c                                                                      |    8 
 kernel/fs/fs-writeback.c                                                                                  |   19 
 kernel/net/sched/act_connmark.c                                                                           |    2 
 kernel/drivers/mfd/display-serdes/serdes-pinctrl.c                                                        |    5 
 kernel/kernel/rcu/tree_exp.h                                                                              |   13 
 kernel/drivers/hwmon/pmbus/ucd9000.c                                                                      |   75 
 kernel/drivers/clk/clk-conf.c                                                                             |   12 
 kernel/drivers/video/rockchip/Makefile                                                                    |    2 
 kernel/drivers/gpu/drm/drm_gem_vram_helper.c                                                              |    6 
 kernel/drivers/infiniband/ulp/srpt/ib_srpt.c                                                              |   23 
 kernel/io_uring/io_uring.c                                                                                |  439 
 kernel/drivers/regulator/da9211-regulator.c                                                               |   11 
 kernel/drivers/gpu/drm/vc4/vc4_dpi.c                                                                      |   64 
 kernel/drivers/platform/x86/intel_scu_ipc.c                                                               |   68 
 kernel/drivers/video/fbdev/core/bitblit.c                                                                 |    3 
 kernel/drivers/char/hw_random/amd-rng.c                                                                   |   18 
 kernel/drivers/usb/chipidea/core.c                                                                        |   13 
 kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-linux.dts                                   |    2 
 kernel/arch/powerpc/include/asm/lppaca.h                                                                  |   13 
 kernel/drivers/net/wireless/ath/ath9k/mac.h                                                               |    6 
 kernel/drivers/net/wireless/mediatek/mt76/mt76x0/init.c                                                   |    4 
 kernel/tools/testing/selftests/net/udpgso_bench_rx.c                                                      |   10 
 kernel/drivers/rtc/rtc-st-lpc.c                                                                           |    3 
 kernel/net/llc/af_llc.c                                                                                   |    8 
 kernel/drivers/platform/mellanox/Kconfig                                                                  |    1 
 kernel/sound/pci/hda/patch_sigmatel.c                                                                     |   10 
 kernel/kernel/trace/ftrace.c                                                                              |   90 
 kernel/tools/virtio/linux/scatterlist.h                                                                   |    1 
 kernel/net/can/j1939/socket.c                                                                             |    7 
 kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dtsi                                    |    2 
 kernel/drivers/i2c/busses/i2c-xgene-slimpro.c                                                             |    3 
 kernel/fs/f2fs/node.c                                                                                     |    4 
 kernel/arch/arm/configs/multi_v7_defconfig                                                                |    1 
 kernel/arch/ia64/Kconfig                                                                                  |    3 
 kernel/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c                                                      |   18 
 kernel/kernel/kcsan/kcsan-test.c                                                                          |    7 
 kernel/drivers/media/pci/saa7134/saa7134-video.c                                                          |    1 
 kernel/drivers/net/ethernet/intel/igb/igb_main.c                                                          |   33 
 kernel/arch/arm64/boot/dts/rockchip/rk3588s-tablet.dtsi                                                   |    2 
 kernel/net/tls/tls_main.c                                                                                 |   12 
 kernel/drivers/target/iscsi/iscsi_target_parameters.c                                                     |   12 
 kernel/drivers/net/ethernet/qlogic/qed/qed_sriov.c                                                        |    5 
 kernel/drivers/net/usb/zaurus.c                                                                           |   21 
 kernel/drivers/net/ipa/gsi_trans.c                                                                        |    2 
 kernel/drivers/vhost/vhost.c                                                                              |   25 
 kernel/include/net/dst.h                                                                                  |    6 
 kernel/net/core/devlink.c                                                                                 |    9 
 kernel/drivers/soc/rockchip/Makefile                                                                      |    2 
 kernel/sound/hda/ext/hdac_ext_stream.c                                                                    |   17 
 kernel/drivers/mmc/host/mmc_spi.c                                                                         |    8 
 kernel/drivers/platform/x86/huawei-wmi.c                                                                  |   22 
 kernel/drivers/video/fbdev/imsttfb.c                                                                      |   34 
 kernel/drivers/vhost/vhost.h                                                                              |    9 
 kernel/include/linux/device.h                                                                             |    1 
 kernel/drivers/usb/core/sysfs.c                                                                           |    5 
 kernel/drivers/hwmon/pmbus/adm1275.c                                                                      |   94 
 kernel/net/sched/sch_fq.c                                                                                 |    6 
 kernel/drivers/dma/ste_dma40.c                                                                            |    4 
 kernel/drivers/video/rockchip/rga3/rga_hw_config.c                                                        |   48 
 kernel/drivers/net/wireless/intel/iwlwifi/pcie/drv.c                                                      |    3 
 kernel/drivers/mmc/host/toshsd.c                                                                          |    6 
 kernel/drivers/staging/media/atomisp/pci/atomisp_ioctl.c                                                  |    3 
 kernel/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c                                                                |  269 
 kernel/kernel/trace/trace_probe.h                                                                         |    2 
 kernel/arch/x86/hyperv/hv_init.c                                                                          |    2 
 kernel/arch/arm/boot/dts/s5pv210-aries.dtsi                                                               |    4 
 kernel/drivers/gpu/drm/i915/intel_sideband.h                                                              |    2 
 kernel/arch/sh/include/asm/pgtable-3level.h                                                               |    4 
 kernel/drivers/net/ethernet/sfc/ef10.c                                                                    |   53 
 kernel/kernel/trace/trace_events.c                                                                        |   22 
 kernel/drivers/fsi/fsi-master-ast-cf.c                                                                    |    1 
 kernel/include/dt-bindings/iio/addac/adi,ad74413r.h                                                       |   21 
 kernel/drivers/media/dvb-frontends/s921.c                                                                 |    2 
 kernel/drivers/media/platform/rockchip/isp/isp_params_v2x.c                                               |   41 
 kernel/android/abi_gki_aarch64_lenovo                                                                     |   10 
 kernel/drivers/net/xen-netback/netback.c                                                                  |   46 
 kernel/net/ipv6/ip6_vti.c                                                                                 |    4 
 kernel/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts                                                  |    1 
 kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c                                     |    8 
 kernel/arch/x86/kernel/vmlinux.lds.S                                                                      |   38 
 kernel/drivers/media/usb/dvb-usb/dw2102.c                                                                 |   26 
 kernel/arch/powerpc/perf/req-gen/perf.h                                                                   |   20 
 kernel/kernel/kcsan/core.c                                                                                |   52 
 kernel/arch/mips/bcm63xx/clk.c                                                                            |    2 
 kernel/fs/cifs/cifsproto.h                                                                                |    4 
 kernel/drivers/power/supply/power_supply_leds.c                                                           |    5 
 kernel/fs/open.c                                                                                          |    8 
 kernel/arch/x86/include/asm/processor.h                                                                   |   12 
 kernel/drivers/video/fbdev/core/fbmem.c                                                                   |    2 
 kernel/scripts/dummy-tools/gcc                                                                            |    6 
 kernel/sound/pci/ice1712/aureon.c                                                                         |    2 
 kernel/drivers/media/platform/rockchip/isp/dmarx.c                                                        |    8 
 kernel/drivers/scsi/qla2xxx/qla_target.c                                                                  |   14 
 kernel/drivers/crypto/cavium/nitrox/nitrox_mbx.c                                                          |    1 
 kernel/drivers/media/dvb-frontends/lgdt3306a.c                                                            |    2 
 kernel/net/ipv6/datagram.c                                                                                |    2 
 kernel/tools/testing/selftests/net/forwarding/tc_actions.sh                                               |   48 
 kernel/fs/ext4/mmp.c                                                                                      |   39 
 kernel/drivers/md/dm-flakey.c                                                                             |   34 
 kernel/drivers/tty/serial/arc_uart.c                                                                      |    7 
 kernel/drivers/video/fbdev/stifb.c                                                                        |   28 
 kernel/net/netfilter/nft_nat.c                                                                            |    2 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c                                               |    1 
 kernel/drivers/acpi/battery.c                                                                             |    2 
 kernel/drivers/misc/sgi-gru/grutables.h                                                                   |    2 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-rohm.dtsi                           |  253 
 kernel/arch/arm64/configs/rockchip_linux_pcie_ep.config                                                   |    7 
 kernel/arch/mips/kernel/vpe-cmp.c                                                                         |    4 
 kernel/drivers/infiniband/sw/rdmavt/qp.c                                                                  |    2 
 kernel/drivers/char/hw_random/nomadik-rng.c                                                               |   12 
 kernel/net/mptcp/protocol.c                                                                               |    7 
 kernel/drivers/tty/hvc/hvc_xen.c                                                                          |   46 
 kernel/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts                                                          |    2 
 kernel/drivers/pci/controller/rockchip-pcie-dma.h                                                         |   53 
 kernel/drivers/acpi/video_detect.c                                                                        |   45 
 kernel/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c                                                                |    3 
 kernel/arch/sh/boards/mach-kfr2r09/setup.c                                                                |    2 
 kernel/arch/x86/events/amd/ibs.c                                                                          |   53 
 kernel/drivers/clk/qcom/clk-krait.c                                                                       |    2 
 kernel/drivers/mfd/display-serdes/rohm/rohm-bu18rl82.c                                                    |   68 
 kernel/drivers/gpu/drm/panel/panel-simple.c                                                               |   55 
 kernel/drivers/firmware/qcom_scm.c                                                                        |    3 
 kernel/drivers/infiniband/core/uverbs_main.c                                                              |   14 
 kernel/drivers/media/usb/dvb-usb-v2/af9035.c                                                              |   14 
 kernel/drivers/scsi/qla2xxx/qla_mbx.c                                                                     |    7 
 kernel/drivers/clk/qcom/gcc-sc7180.c                                                                      |   33 
 kernel/drivers/irqchip/irqchip.c                                                                          |    8 
 kernel/arch/arm/boot/dts/bcm5301x.dtsi                                                                    |    5 
 kernel/drivers/net/ethernet/intel/iavf/iavf.h                                                             |    2 
 kernel/drivers/parisc/iosapic.c                                                                           |    4 
 kernel/drivers/rtc/Makefile                                                                               |    1 
 kernel/drivers/video/fbdev/imxfb.c                                                                        |    4 
 kernel/drivers/mmc/host/dw_mmc.c                                                                          |   55 
 kernel/kernel/power/snapshot.c                                                                            |    4 
 kernel/drivers/usb/host/xhci-mvebu.c                                                                      |    2 
 kernel/net/8021q/vlan_dev.c                                                                               |    6 
 kernel/drivers/firmware/arm_scmi/shmem.c                                                                  |    9 
 kernel/fs/xfs/xfs_aops.c                                                                                  |   45 
 kernel/drivers/net/wireless/ath/key.c                                                                     |    2 
 kernel/drivers/char/tpm/tpm_ftpm_tee.c                                                                    |    8 
 kernel/drivers/pci/pcie/dpc.c                                                                             |    4 
 kernel/include/linux/pci_ids.h                                                                            |    4 
 kernel/fs/fuse/dir.c                                                                                      |    9 
 kernel/fs/proc/task_nommu.c                                                                               |   27 
 kernel/drivers/net/usb/cdc_ncm.c                                                                          |   24 
 kernel/drivers/net/ethernet/ibm/ibmveth.c                                                                 |    2 
 kernel/arch/arm/boot/dts/rv1106g-evb2-v12-aov-spi-nor.dts                                                 |   29 
 kernel/drivers/net/wireless/rndis_wlan.c                                                                  |   19 
 kernel/drivers/firmware/efi/runtime-wrappers.c                                                            |    1 
 kernel/drivers/power/supply/da9150-charger.c                                                              |    1 
 kernel/drivers/gpu/arm/bifrost/mali_kbase_gpu_memory_debugfs.c                                            |   14 
 kernel/drivers/net/ethernet/ibm/ibmvnic.c                                                                 |   38 
 kernel/android/abi_gki_aarch64_nothing                                                                    |    4 
 kernel/arch/arm/probes/kprobes/core.c                                                                     |    2 
 kernel/drivers/usb/musb/musb_gadget.c                                                                     |    2 
 kernel/drivers/leds/Kconfig                                                                               |    2 
 kernel/drivers/gpio/gpio-mxc.c                                                                            |    2 
 kernel/include/linux/virtio_net.h                                                                         |    4 
 kernel/include/linux/util_macros.h                                                                        |   12 
 kernel/arch/sh/math-emu/sfp-util.h                                                                        |    4 
 kernel/net/core/flow_dissector.c                                                                          |    3 
 kernel/arch/x86/kernel/kprobes/core.c                                                                     |  670 
 kernel/drivers/mfd/display-serdes/maxim/maxim-max96755.c                                                  |   27 
 kernel/net/sctp/bind_addr.c                                                                               |    6 
 kernel/arch/arm64/kernel/hw_breakpoint.c                                                                  |    4 
 kernel/arch/arm/probes/kprobes/test-core.c                                                                |    2 
 kernel/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh                                       |    3 
 kernel/drivers/staging/rtl8712/os_intfs.c                                                                 |    1 
 kernel/fs/nfs/inode.c                                                                                     |    6 
 kernel/arch/arm64/boot/dts/rockchip/Makefile                                                              |   15 
 kernel/net/openvswitch/datapath.c                                                                         |   31 
 kernel/arch/m68k/mm/fault.c                                                                               |    2 
 kernel/drivers/isdn/hardware/mISDN/hfcpci.c                                                               |   23 
 kernel/fs/notify/fanotify/fanotify_user.c                                                                 |   22 
 kernel/kernel/locking/percpu-rwsem.c                                                                      |    3 
 kernel/kernel/rcu/rcuscale.c                                                                              |  216 
 kernel/drivers/media/dvb-frontends/stv0288.c                                                              |    7 
 kernel/drivers/soc/rockchip/rk_dmabuf_procfs.c                                                            |    6 
 kernel/include/linux/mlx5/driver.h                                                                        |   12 
 kernel/drivers/pcmcia/rsrc_nonstatic.c                                                                    |    2 
 kernel/net/atm/resources.c                                                                                |    2 
 kernel/drivers/tty/tty_ioctl.c                                                                            |   48 
 kernel/drivers/irqchip/irq-bcm7120-l2.c                                                                   |    5 
 kernel/fs/orangefs/orangefs-mod.c                                                                         |    8 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c                                           |    7 
 kernel/drivers/pinctrl/pinctrl-at91-pio4.c                                                                |    7 
 kernel/sound/soc/codecs/nau8824.c                                                                         |   24 
 kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c                                                  |  198 
 kernel/drivers/net/wireless/ath/ath5k/eeprom.c                                                            |    2 
 kernel/security/security.c                                                                                |    7 
 kernel/arch/arm/probes/kprobes/test-core.h                                                                |    4 
 kernel/arch/m68k/ifpsp060/os.S                                                                            |    4 
 kernel/drivers/vfio/vfio_iommu_type1.c                                                                    |   43 
 kernel/lib/debugobjects.c                                                                                 |  162 
 kernel/sound/hda/hdac_regmap.c                                                                            |    7 
 kernel/tools/testing/selftests/efivarfs/efivarfs.sh                                                       |    5 
 kernel/drivers/hid/wacom_sys.c                                                                            |   42 
 kernel/drivers/net/wireless/marvell/libertas/cmdresp.c                                                    |    2 
 kernel/tools/testing/selftests/kselftest_deps.sh                                                          |   77 
 kernel/drivers/md/raid10.c                                                                                |  112 
 kernel/drivers/spi/spi-bcm63xx.c                                                                          |    2 
 kernel/drivers/edac/skx_base.c                                                                            |    4 
 kernel/net/xdp/xsk_queue.h                                                                                |    1 
 kernel/tools/perf/util/Build                                                                              |    6 
 kernel/mm/page_ext.c                                                                                      |    2 
 kernel/tools/testing/selftests/rseq/Makefile                                                              |    4 
 kernel/tools/objtool/elf.h                                                                                |    1 
 kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c                                            |    2 
 kernel/arch/arm64/include/asm/atomic_lse.h                                                                |   16 
 kernel/fs/xfs/xfs_mount.c                                                                                 |    3 
 kernel/drivers/video/rockchip/rve/include/rve_reg.h                                                       |    2 
 kernel/fs/udf/inode.c                                                                                     |  195 
 kernel/net/hsr/hsr_device.c                                                                               |   59 
 kernel/arch/arm/boot/dts/armada-xp-mv78230.dtsi                                                           |    8 
 kernel/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c                                                    |   11 
 kernel/drivers/gpu/drm/rockchip/rk628/rk628_combtxphy.c                                                   |    4 
 kernel/include/net/ip_vs.h                                                                                |    6 
 kernel/drivers/media/platform/rockchip/isp/dev.c                                                          |  194 
 kernel/tools/arch/x86/include/asm/required-features.h                                                     |    3 
 kernel/arch/arm/boot/dts/qcom-apq8064.dtsi                                                                |    2 
 kernel/drivers/crypto/omap-sham.c                                                                         |    2 
 kernel/mm/khugepaged.c                                                                                    |   18 
 kernel/arch/arm64/kernel/mte.c                                                                            |   51 
 kernel/drivers/usb/typec/tcpm/tcpci.h                                                                     |    1 
 kernel/arch/powerpc/include/asm/word-at-a-time.h                                                          |    2 
 kernel/drivers/clk/rockchip/clk-rk3588.c                                                                  |    8 
 kernel/fs/nfs/nfs2xdr.c                                                                                   |    2 
 kernel/drivers/usb/typec/tcpm/tcpci.c                                                                     |    9 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-rk628-hdmi2csi.dts                                |  264 
 kernel/tools/testing/selftests/bpf/prog_tests/align.c                                                     |   36 
 kernel/tools/testing/selftests/wireguard/netns.sh                                                         |   30 
 kernel/net/ipv6/raw.c                                                                                     |    9 
 kernel/sound/usb/line6/driver.c                                                                           |    3 
 kernel/drivers/usb/misc/iowarrior.c                                                                       |    2 
 kernel/drivers/crypto/marvell/cesa/cipher.c                                                               |    2 
 kernel/drivers/pci/controller/pci-hyperv.c                                                                |  112 
 kernel/net/netfilter/nft_set_hash.c                                                                       |  108 
 kernel/sound/pci/hda/patch_conexant.c                                                                     |    7 
 kernel/drivers/pinctrl/renesas/pinctrl-rza2.c                                                             |   17 
 kernel/arch/arm/boot/dts/armada-375.dtsi                                                                  |    2 
 kernel/drivers/tty/serial/sh-sci.c                                                                        |   10 
 kernel/net/smc/smc_cdc.c                                                                                  |    3 
 kernel/sound/soc/codecs/rockchip-spi-codec.h                                                              |   49 
 kernel/net/sched/act_ife.c                                                                                |    2 
 kernel/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h                                                       |    2 
 kernel/kernel/bpf/verifier.c                                                                              |  462 
 kernel/sound/soc/codecs/rockchip-spi-codec.c                                                              |  370 
 kernel/net/core/rtnetlink.c                                                                               |  155 
 kernel/drivers/pci/endpoint/functions/pci-epf-test.c                                                      |    2 
 kernel/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc                                |   15 
 kernel/drivers/iio/dac/cio-dac.c                                                                          |    4 
 kernel/drivers/media/platform/rockchip/isp/rkisp.h                                                        |    2 
 kernel/scripts/gdb/linux/clk.py                                                                           |    2 
 kernel/arch/x86/include/asm/nospec-branch.h                                                               |   34 
 kernel/sound/pci/ymfpci/ymfpci.c                                                                          |   71 
 kernel/drivers/power/supply/test_power.c                                                                  |    2 
 kernel/tools/testing/selftests/resctrl/fill_buf.c                                                         |    5 
 kernel/arch/mips/configs/decstation_defconfig                                                             |    2 
 kernel/drivers/message/fusion/mptlan.c                                                                    |    2 
 kernel/drivers/gpu/drm/sun4i/sun4i_tcon.c                                                                 |   19 
 kernel/drivers/media/platform/rockchip/isp/rkisp.c                                                        |  282 
 kernel/include/dt-bindings/soc/rockchip-csu.h                                                             |   15 
 kernel/fs/erofs/zdata.c                                                                                   |  191 
 kernel/fs/erofs/zdata.h                                                                                   |    2 
 kernel/drivers/usb/host/xhci-ring.c                                                                       |   34 
 kernel/net/rds/message.c                                                                                  |    8 
 kernel/drivers/input/touchscreen/gt9xx/gt9xx.c                                                            |   91 
 kernel/drivers/infiniband/core/nldev.c                                                                    |    7 
 kernel/drivers/gpu/drm/vc4/vc4_hvs.c                                                                      |   11 
 kernel/net/mac80211/wme.c                                                                                 |    6 
 kernel/arch/mips/configs/nlm_xlp_defconfig                                                                |    2 
 kernel/drivers/hwmon/it87.c                                                                               |    4 
 kernel/arch/microblaze/kernel/exceptions.c                                                                |    4 
 kernel/drivers/mfd/display-serdes/Makefile                                                                |    2 
 kernel/drivers/net/can/kvaser_pciefd.c                                                                    |   51 
 kernel/drivers/hwmon/adt7475.c                                                                            |   14 
 kernel/tools/testing/selftests/net/devlink_port_split.py                                                  |   30 
 kernel/arch/sh/drivers/dma/dma-sh.c                                                                       |   37 
 kernel/fs/afs/vl_probe.c                                                                                  |    4 
 kernel/include/linux/netdevice.h                                                                          |   35 
 kernel/tools/testing/selftests/net/mptcp/pm_netlink.sh                                                    |   16 
 kernel/fs/nfsd/nfsd.h                                                                                     |    3 
 kernel/drivers/spi/spi-rockchip-test.c                                                                    |   17 
 kernel/fs/dlm/plock.c                                                                                     |  185 
 kernel/net/mptcp/subflow.c                                                                                |   77 
 kernel/fs/ext4/inline.c                                                                                   |   31 
 kernel/drivers/net/bonding/bond_debugfs.c                                                                 |    2 
 kernel/drivers/clk/qcom/gcc-ipq6018.c                                                                     |   34 
 kernel/net/bridge/br_if.c                                                                                 |    5 
 kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c                                                   |  115 
 kernel/arch/arm64/boot/dts/rockchip/rk3566-box.dtsi                                                       |    2 
 kernel/drivers/soc/rockchip/rockchip_debug.c                                                              |  128 
 kernel/scripts/gdb/linux/timerlist.py                                                                     |    4 
 kernel/arch/arm/boot/dts/imx7d-pico-hobbit.dts                                                            |    2 
 kernel/arch/mips/include/asm/atomic.h                                                                     |    2 
 kernel/sound/soc/rockchip/rockchip_sai.h                                                                  |   12 
 kernel/drivers/md/dm-cache-policy-smq.c                                                                   |   28 
 kernel/drivers/video/rockchip/rga2/rga2_drv.c                                                             |   17 
 kernel/drivers/input/mouse/synaptics.c                                                                    |    1 
 kernel/fs/internal.h                                                                                      |    8 
 kernel/sound/soc/rockchip/rockchip_sai.c                                                                  |   95 
 kernel/lib/test_meminit.c                                                                                 |    2 
 kernel/include/net/ip_tunnels.h                                                                           |   12 
 kernel/kernel/trace/trace_probe_tmpl.h                                                                    |   20 
 kernel/drivers/s390/crypto/vfio_ap_drv.c                                                                  |    3 
 kernel/tools/virtio/linux/cpumask.h                                                                       |    7 
 kernel/drivers/bus/mhi/Kconfig                                                                            |   18 
 kernel/kernel/cgroup/cpuset.c                                                                             |  100 
 kernel/arch/arm/boot/dts/exynos3250-rinato.dts                                                            |    2 
 kernel/drivers/media/dvb-frontends/lnbh25.c                                                               |    2 
 kernel/drivers/media/dvb-frontends/tda10023.c                                                             |    2 
 kernel/drivers/perf/arm_smmuv3_pmu.c                                                                      |   54 
 kernel/include/uapi/sound/skl-tplg-interface.h                                                            |    3 
 kernel/include/linux/tcp.h                                                                                |    2 
 kernel/Documentation/filesystems/directory-locking.rst                                                    |   26 
 kernel/net/ipv6/xfrm6_input.c                                                                             |    3 
 kernel/drivers/media/i2c/tvp5150.c                                                                        |    4 
 kernel/security/apparmor/policy_unpack.c                                                                  |   11 
 kernel/net/ipv4/inet_connection_sock.c                                                                    |   29 
 kernel/drivers/scsi/isci/task.c                                                                           |    2 
 kernel/drivers/infiniband/core/uverbs_cmd.c                                                               |    9 
 kernel/fs/overlayfs/overlayfs.h                                                                           |    6 
 kernel/drivers/i2c/busses/i2c-ibm_iic.c                                                                   |    4 
 kernel/drivers/watchdog/at91sam9_wdt.c                                                                    |    7 
 kernel/arch/openrisc/kernel/traps.c                                                                       |    2 
 kernel/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi                                                    |    2 
 kernel/arch/sh/kernel/traps.c                                                                             |    2 
 kernel/net/llc/llc_input.c                                                                                |    3 
 kernel/arch/x86/kvm/vmx/evmcs.h                                                                           |   11 
 kernel/drivers/cpufreq/amd_freq_sensitivity.c                                                             |    2 
 kernel/drivers/gpu/drm/lima/lima_drv.c                                                                    |    6 
 kernel/drivers/media/platform/ti-vpe/cal.h                                                                |    2 
 kernel/drivers/media/platform/qcom/venus/pm_helpers.c                                                     |   16 
 kernel/lib/parser.c                                                                                       |    1 
 kernel/arch/arm/kernel/bugs.c                                                                             |    3 
 kernel/arch/s390/lib/uaccess.c                                                                            |    2 
 kernel/drivers/md/md.c                                                                                    |   38 
 kernel/net/ipv4/tcp.c                                                                                     |   75 
 kernel/arch/powerpc/perf/imc-pmu.c                                                                        |  122 
 kernel/drivers/soc/rockchip/fiq_debugger/rk_fiq_debugger.c                                                |    5 
 kernel/kernel/trace/trace_kprobe.c                                                                        |    3 
 kernel/include/uapi/linux/videodev2.h                                                                     |    2 
 kernel/drivers/input/touchscreen/gt9xx/gt9xx.h                                                            |   23 
 kernel/drivers/virtio/virtio_ring.c                                                                       |    2 
 kernel/include/net/bond_alb.h                                                                             |    4 
 kernel/drivers/net/mdio/mdio-thunder.c                                                                    |    1 
 kernel/drivers/mtd/ubi/wl.c                                                                               |   30 
 kernel/drivers/crypto/nx/Makefile                                                                         |    2 
 kernel/drivers/pwm/pwm-meson.c                                                                            |   38 
 kernel/arch/arm/boot/dts/rk3288-evb.dtsi                                                                  |    2 
 kernel/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi                                                    |    2 
 kernel/drivers/pwm/pwm-cros-ec.c                                                                          |    1 
 kernel/include/net/xsk_buff_pool.h                                                                        |    9 
 kernel/net/ipv4/ip_vti.c                                                                                  |    4 
 kernel/security/loadpin/loadpin.c                                                                         |   30 
 kernel/net/sched/act_gate.c                                                                               |    2 
 kernel/arch/arm/probes/kprobes/opt-arm.c                                                                  |    2 
 kernel/arch/arm/boot/dts/rv1106g-evb1-v11-4k.dts                                                          |   17 
 kernel/fs/reiserfs/namei.c                                                                                |    4 
 kernel/drivers/cpufreq/rockchip-cpufreq.c                                                                 |    1 
 kernel/tools/testing/selftests/net/forwarding/lib.sh                                                      |   20 
 kernel/arch/parisc/include/asm/ldcw.h                                                                     |   36 
 kernel/drivers/mtd/nand/raw/fsl_upm.c                                                                     |    2 
 kernel/arch/x86/mm/kaslr.c                                                                                |    8 
 kernel/sound/synth/emux/emux_nrpn.c                                                                       |    3 
 kernel/arch/powerpc/include/asm/prom.h                                                                    |    3 
 kernel/net/ipv4/tcp_bpf.c                                                                                 |   14 
 kernel/net/core/net_namespace.c                                                                           |   21 
 kernel/tools/arch/parisc/include/uapi/asm/mman.h                                                          |   12 
 kernel/kernel/trace/trace_sched_wakeup.c                                                                  |    2 
 kernel/drivers/net/wireless/intel/ipw2x00/ipw2200.c                                                       |   11 
 kernel/drivers/md/bcache/super.c                                                                          |    4 
 kernel/drivers/gpu/drm/i915/display/intel_quirks.c                                                        |    2 
 kernel/fs/quota/dquot.c                                                                                   |  181 
 kernel/drivers/pinctrl/pinctrl-amd.h                                                                      |    1 
 kernel/net/netfilter/nfnetlink_osf.c                                                                      |    9 
 kernel/net/mac80211/driver-ops.c                                                                          |    3 
 kernel/net/sched/sch_taprio.c                                                                             |   10 
 kernel/include/target/target_core_base.h                                                                  |   16 
 kernel/security/smack/smack_lsm.c                                                                         |   65 
 kernel/include/net/netfilter/ipv6/nf_reject.h                                                             |    5 
 kernel/fs/ext4/ialloc.c                                                                                   |   12 
 kernel/drivers/net/wireguard/send.c                                                                       |    2 
 kernel/kernel/dma/debug.c                                                                                 |   20 
 kernel/drivers/net/ethernet/freescale/enetc/enetc.c                                                       |    8 
 kernel/arch/arm/boot/dts/am335x-guardian.dts                                                              |    9 
 kernel/drivers/scsi/raid_class.c                                                                          |   47 
 kernel/drivers/s390/net/qeth_l3_sys.c                                                                     |    2 
 kernel/include/linux/if_vlan.h                                                                            |   17 
 kernel/drivers/acpi/acpica/psopcode.c                                                                     |    2 
 kernel/arch/mips/kernel/traps.c                                                                           |    2 
 kernel/drivers/media/platform/exynos4-is/media-dev.h                                                      |    2 
 kernel/drivers/mmc/core/sdio_bus.c                                                                        |   17 
 kernel/fs/nfs/nfs42proc.c                                                                                 |    5 
 kernel/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c                                                              |    1 
 kernel/arch/s390/kvm/kvm-s390.c                                                                           |   21 
 kernel/sound/soc/codecs/adau7118.c                                                                        |   19 
 kernel/drivers/gpu/drm/rcar-du/Kconfig                                                                    |   25 
 kernel/drivers/i2c/busses/i2c-designware-common.c                                                         |   11 
 kernel/arch/x86/kernel/uprobes.c                                                                          |    4 
 kernel/include/linux/nfs_page.h                                                                           |    4 
 kernel/drivers/gpu/ipu-v3/ipu-common.c                                                                    |    1 
 kernel/drivers/regulator/fan53555.c                                                                       |   13 
 kernel/arch/alpha/boot/tools/objstrip.c                                                                   |    2 
 kernel/net/ipv4/tcp_input.c                                                                               |   32 
 kernel/arch/arm/boot/dts/imx53-ppd.dts                                                                    |    2 
 kernel/net/ipv4/ip_input.c                                                                                |    3 
 kernel/arch/arm/boot/dts/s3c6410-mini6410.dts                                                             |    6 
 kernel/drivers/media/i2c/maxim2c/maxim2c_api.h                                                            |  103 
 kernel/samples/vfio-mdev/mdpy-fb.c                                                                        |    8 
 kernel/drivers/media/dvb-frontends/zl10353.c                                                              |    2 
 kernel/net/rxrpc/sendmsg.c                                                                                |    4 
 kernel/drivers/i2c/busses/i2c-aspeed.c                                                                    |    7 
 kernel/drivers/net/can/usb/esd_usb2.c                                                                     |    4 
 kernel/drivers/media/platform/exynos4-is/media-dev.c                                                      |   32 
 kernel/drivers/crypto/stm32/stm32-hash.c                                                                  |    9 
 kernel/drivers/media/platform/s5p-mfc/s5p_mfc.c                                                           |   17 
 kernel/drivers/md/dm-stats.h                                                                              |    2 
 kernel/drivers/md/dm-stats.c                                                                              |    7 
 kernel/fs/nfsd/nfs4xdr.c                                                                                  |   38 
 kernel/drivers/tty/serial/amba-pl011.c                                                                    |   14 
 kernel/drivers/watchdog/intel-mid_wdt.c                                                                   |    1 
 kernel/drivers/s390/block/dasd_eckd.c                                                                     |   82 
 kernel/drivers/video/rockchip/vtunnel/rkvtunnel.c                                                         | 1527 
 kernel/include/linux/sched.h                                                                              |    4 
 kernel/drivers/media/i2c/maxim2c/maxim2c_drv.c                                                            |  750 
 kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c                                                |   15 
 kernel/drivers/soc/amlogic/meson-secure-pwrc.c                                                            |    2 
 kernel/drivers/gpu/drm/tiny/ili9486.c                                                                     |   13 
 kernel/arch/riscv/kernel/patch.c                                                                          |   28 
 kernel/drivers/video/rockchip/vtunnel/rkvtunnel.h                                                         |   81 
 kernel/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c                                          |    1 
 kernel/block/blk-sysfs.c                                                                                  |    2 
 kernel/arch/parisc/include/asm/processor.h                                                                |    1 
 kernel/arch/parisc/include/asm/spinlock_types.h                                                           |    5 
 kernel/drivers/pinctrl/pinctrl-amd.c                                                                      |   45 
 kernel/drivers/media/i2c/maxim2c/maxim2c_drv.h                                                            |  110 
 kernel/include/net/netns/netfilter.h                                                                      |    3 
 kernel/drivers/media/rc/ene_ir.c                                                                          |    3 
 kernel/arch/sparc/include/asm/pgtable_32.h                                                                |    6 
 kernel/drivers/iio/imu/adis.c                                                                             |   98 
 kernel/net/ipv4/tcp_minisocks.c                                                                           |   16 
 kernel/include/linux/skbuff.h                                                                             |   47 
 kernel/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c                                                      |    1 
 kernel/arch/powerpc/kernel/eeh_driver.c                                                                   |   71 
 kernel/drivers/media/i2c/dw9800v.c                                                                        | 1068 
 kernel/net/x25/af_x25.c                                                                                   |    6 
 kernel/tools/iio/iio_utils.c                                                                              |   23 
 kernel/drivers/powercap/intel_rapl_msr.c                                                                  |    1 
 kernel/include/sound/hdaudio.h                                                                            |    2 
 kernel/include/linux/netfilter_defs.h                                                                     |    8 
 kernel/tools/perf/builtin-trace.c                                                                         |   32 
 kernel/drivers/media/i2c/sc2355.c                                                                         | 1522 
 kernel/drivers/isdn/mISDN/dsp.h                                                                           |    2 
 kernel/drivers/tty/n_tty.c                                                                                |    1 
 kernel/drivers/mfd/display-serdes/serdes-panel.c                                                          |   53 
 kernel/arch/arm64/boot/dts/rockchip/rk3568-toybrick-sd0.dtsi                                              |    2 
 kernel/net/ipv6/addrconf.c                                                                                |   19 
 kernel/drivers/media/dvb-frontends/tda826x.c                                                              |    2 
 kernel/drivers/infiniband/hw/hns/hns_roce_cq.c                                                            |    2 
 kernel/drivers/net/dsa/lan9303-core.c                                                                     |    8 
 kernel/lib/idr.c                                                                                          |    2 
 kernel/drivers/media/dvb-frontends/atbm8830.c                                                             |    2 
 kernel/android/abi_gki_aarch64_galaxy                                                                     | 7193 +-
 kernel/arch/x86/kernel/static_call.c                                                                      |   13 
 kernel/Documentation/admin-guide/sysctl/vm.rst                                                            |    2 
 kernel/include/trace/events/btrfs.h                                                                       |    2 
 kernel/drivers/mfd/rk630-i2c.c                                                                            |    9 
 kernel/drivers/parisc/led.c                                                                               |    7 
 kernel/drivers/net/phy/xilinx_gmii2rgmii.c                                                                |    1 
 kernel/net/ipv6/udp_impl.h                                                                                |    1 
 kernel/tools/testing/selftests/drivers/net/netdevsim/devlink.sh                                           |   22 
 kernel/kernel/bpf/bpf_lru_list.h                                                                          |    7 
 kernel/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c                                     |   12 
 kernel/kernel/bpf/bpf_lru_list.c                                                                          |   21 
 kernel/include/rdma/ib_addr.h                                                                             |   23 
 kernel/net/sched/act_mirred.c                                                                             |   46 
 kernel/include/dt-bindings/soc/rockchip,boot-mode.h                                                       |    2 
 kernel/drivers/input/touchscreen/gt9xx/Makefile                                                           |    2 
 kernel/arch/x86/kernel/irqinit.c                                                                          |    4 
 kernel/drivers/media/dvb-frontends/stv6110x.c                                                             |    2 
 kernel/fs/locks.c                                                                                         |   25 
 kernel/drivers/net/wireless/ath/ath6kl/htc.h                                                              |   15 
 kernel/arch/s390/include/asm/debug.h                                                                      |    6 
 kernel/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c                                                   |    2 
 kernel/drivers/media/platform/rockchip/isp/common.h                                                       |    1 
 kernel/drivers/gpu/drm/meson/meson_viu.c                                                                  |    5 
 kernel/include/trace/hooks/wakeupbypass.h                                                                 |   17 
 kernel/net/sched/act_simple.c                                                                             |    2 
 kernel/Documentation/filesystems/vfs.rst                                                                  |    2 
 kernel/drivers/infiniband/sw/siw/siw_verbs.c                                                              |   42 
 kernel/include/linux/kernel.h                                                                             |  152 
 kernel/security/apparmor/apparmorfs.c                                                                     |    4 
 kernel/net/mac80211/trace.h                                                                               |    2 
 kernel/drivers/dax/dax-private.h                                                                          |    4 
 kernel/drivers/mfd/rk630.c                                                                                |   83 
 kernel/drivers/net/ieee802154/mac802154_hwsim.c                                                           |    6 
 kernel/net/sched/cls_u32.c                                                                                |   75 
 kernel/arch/ia64/mm/hugetlbpage.c                                                                         |    2 
 kernel/drivers/tty/serial/8250/8250_dma.c                                                                 |   30 
 kernel/drivers/media/usb/dvb-usb-v2/ce6230.c                                                              |    8 
 kernel/drivers/media/platform/rockchip/isp/common.c                                                       |   20 
 kernel/drivers/counter/104-quad-8.c                                                                       |   28 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dtsi                                           |   27 
 kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c                                                        |    5 
 kernel/drivers/mfd/rkx110_x120/rkx110_dsi_rx.c                                                            |   16 
 kernel/Documentation/userspace-api/ioctl/ioctl-number.rst                                                 |    1 
 kernel/drivers/gpu/drm/exynos/exynos_drm_dsi.c                                                            |    7 
 kernel/mm/huge_memory.c                                                                                   |    9 
 kernel/net/wireless/nl80211.c                                                                             |    2 
 kernel/sound/core/jack.c                                                                                  |   11 
 kernel/drivers/media/i2c/os02k10.c                                                                        |   51 
 kernel/drivers/net/ethernet/apple/bmac.c                                                                  |    2 
 kernel/drivers/input/misc/iqs269a.c                                                                       |  327 
 kernel/drivers/video/rockchip/mpp/mpp_rkvenc2.c                                                           |  191 
 kernel/drivers/block/drbd/drbd_receiver.c                                                                 |    2 
 kernel/drivers/media/dvb-frontends/cxd2841er.c                                                            |    4 
 kernel/drivers/media/v4l2-core/v4l2-fwnode.c                                                              |   18 
 kernel/arch/mips/configs/gpr_defconfig                                                                    |    2 
 kernel/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c                                               |   10 
 kernel/include/linux/netfilter.h                                                                          |    5 
 kernel/drivers/scsi/pm8001/pm80xx_hwi.c                                                                   |   18 
 kernel/net/sunrpc/xprtrdma/verbs.c                                                                        |   11 
 kernel/drivers/video/fbdev/uvesafb.c                                                                      |    1 
 kernel/net/xfrm/xfrm_compat.c                                                                             |    6 
 kernel/arch/arm64/configs/rk3308_linux_defconfig                                                          |  117 
 kernel/drivers/media/platform/rockchip/isp/hw.c                                                           |  278 
 kernel/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c                                                    |   13 
 kernel/net/qrtr/Makefile                                                                                  |    3 
 kernel/drivers/media/platform/rockchip/isp/hw.h                                                           |    4 
 kernel/tools/virtio/linux/topology.h                                                                      |    7 
 kernel/drivers/net/ethernet/qlogic/qede/qede_main.c                                                       |   34 
 kernel/drivers/parisc/iosapic_private.h                                                                   |    4 
 kernel/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c                                                 |    7 
 kernel/arch/arm/mach-rockchip/Makefile                                                                    |    2 
 kernel/drivers/target/target_core_file.c                                                                  |    4 
 kernel/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c                                                         |    3 
 kernel/arch/parisc/include/asm/cacheflush.h                                                               |    5 
 kernel/drivers/platform/mellanox/mlxbf-tmfifo.c                                                           |   91 
 kernel/drivers/net/ieee802154/ca8210.c                                                                    |    5 
 kernel/drivers/net/dsa/microchip/ksz9477.c                                                                |    4 
 kernel/drivers/acpi/processor_pdc.c                                                                       |   11 
 kernel/drivers/media/dvb-core/dvb_demux.c                                                                 |    4 
 kernel/net/ipv4/netfilter/nf_tproxy_ipv4.c                                                                |    2 
 kernel/drivers/input/sensors/accel/Makefile                                                               |    1 
 kernel/drivers/clk/samsung/clk-pll.c                                                                      |    1 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-lt6911uxc-dual-mipi.dts                           |  326 
 kernel/arch/arm64/boot/dts/microchip/sparx5.dtsi                                                          |    2 
 kernel/drivers/i2c/busses/i2c-nomadik.c                                                                   |   42 
 kernel/drivers/tty/serial/8250/8250_dwlib.c                                                               |    6 
 kernel/arch/x86/include/asm/bugs.h                                                                        |    2 
 kernel/drivers/misc/pci_endpoint_test.c                                                                   |   10 
 kernel/drivers/net/ethernet/broadcom/genet/bcmgenet.c                                                     |   17 
 kernel/drivers/mmc/host/sdhci_f_sdh30.c                                                                   |   69 
 kernel/fs/nfs/nfs4state.c                                                                                 |   61 
 kernel/arch/arm/mach-mmp/time.c                                                                           |   11 
 kernel/drivers/md/dm-table.c                                                                              |   19 
 kernel/arch/powerpc/perf/callchain.c                                                                      |    1 
 kernel/fs/f2fs/debug.c                                                                                    |    4 
 kernel/drivers/net/ethernet/sfc/net_driver.h                                                              |   50 
 kernel/drivers/iommu/arm/arm-smmu/qcom_iommu.c                                                            |    7 
 kernel/net/unix/af_unix.c                                                                                 |   35 
 kernel/drivers/spi/spi-fsl-cpm.c                                                                          |   23 
 kernel/net/nfc/llcp_sock.c                                                                                |   21 
 kernel/drivers/gpu/drm/vgem/vgem_fence.c                                                                  |    1 
 kernel/drivers/scsi/scsi_scan.c                                                                           |    7 
 kernel/arch/x86/kvm/vmx/vmx.c                                                                             |  174 
 kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c                                                          |    8 
 kernel/net/bluetooth/hci_event.c                                                                          |   13 
 kernel/arch/h8300/kernel/traps.c                                                                          |    3 
 kernel/sound/soc/codecs/wsa881x.c                                                                         |    1 
 kernel/drivers/rknpu/rknpu_devfreq.c                                                                      |  765 
 kernel/drivers/media/i2c/sc3338.c                                                                         |   63 
 kernel/drivers/mfd/rkx110_x120/rkx110_x120_panel.c                                                        |  494 
 kernel/drivers/iio/temperature/ltc2983.c                                                                  |   10 
 kernel/drivers/net/ethernet/intel/igc/igc_ptp.c                                                           |   71 
 kernel/drivers/media/tuners/qt1010.c                                                                      |   13 
 kernel/fs/afs/fs_probe.c                                                                                  |    5 
 kernel/net/sunrpc/sched.c                                                                                 |    1 
 kernel/arch/powerpc/purgatory/Makefile                                                                    |    5 
 kernel/drivers/md/dm-raid.c                                                                               |   20 
 kernel/drivers/net/ethernet/dnet.c                                                                        |    4 
 kernel/fs/ocfs2/aops.c                                                                                    |   18 
 kernel/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c                                                 |    5 
 kernel/drivers/gpu/drm/rockchip/rockchip_drm_drv.c                                                        |    3 
 kernel/drivers/cpufreq/brcmstb-avs-cpufreq.c                                                              |    6 
 kernel/drivers/gpu/drm/rockchip/rockchip_drm_drv.h                                                        |    2 
 kernel/drivers/s390/scsi/zfcp_fc.c                                                                        |    6 
 kernel/arch/sh/boards/mach-migor/setup.c                                                                  |    2 
 kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v10.dts                                              |    2 
 kernel/drivers/net/can/m_can/tcan4x5x.c                                                                   |    5 
 kernel/drivers/net/wireless/marvell/libertas/if_usb.c                                                     |    2 
 kernel/arch/arm/mach-pxa/spitz.c                                                                          |   14 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy0.dtsi                         |   48 
 kernel/tools/testing/selftests/rseq/rseq.c                                                                |   33 
 kernel/include/uapi/linux/rk-camera-module.h                                                              |    4 
 kernel/drivers/clk/rockchip/clk.h                                                                         |    7 
 kernel/sound/soc/atmel/atmel-i2s.c                                                                        |    5 
 kernel/fs/nfs/pnfs_dev.c                                                                                  |    2 
 kernel/arch/mips/bmips/setup.c                                                                            |    8 
 kernel/drivers/base/core.c                                                                                |    7 
 kernel/drivers/clk/rockchip/clk.c                                                                         |   49 
 kernel/drivers/power/supply/generic-adc-battery.c                                                         |    3 
 kernel/fs/drop_caches.c                                                                                   |    2 
 kernel/drivers/infiniband/core/cma.c                                                                      |   89 
 kernel/crypto/xts.c                                                                                       |   14 
 kernel/arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts                                                 |    2 
 kernel/arch/arm64/boot/dts/qcom/msm8998.dtsi                                                              |    4 
 kernel/drivers/of/unittest.c                                                                              |   12 
 kernel/net/batman-adv/types.h                                                                             |    6 
 kernel/arch/powerpc/platforms/83xx/mpc832x_rdb.c                                                          |    2 
 kernel/drivers/firmware/Kconfig                                                                           |    1 
 kernel/net/Makefile                                                                                       |    1 
 kernel/drivers/media/dvb-frontends/cx22700.c                                                              |    2 
 kernel/drivers/pwm/pwm-sifive.c                                                                           |   21 
 kernel/drivers/devfreq/devfreq.c                                                                          |    1 
 kernel/drivers/media/dvb-frontends/horus3a.c                                                              |    2 
 kernel/fs/proc/base.c                                                                                     |   49 
 kernel/drivers/gpu/drm/ingenic/ingenic-drm-drv.c                                                          |    6 
 kernel/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c                                                |    6 
 kernel/drivers/scsi/hpsa.c                                                                                |   11 
 kernel/drivers/spi/spi-rockchip-slave.c                                                                   | 1060 
 kernel/drivers/usb/chipidea/ci_hdrc_imx.c                                                                 |   15 
 kernel/arch/arm/Kconfig                                                                                   |    1 
 kernel/drivers/scsi/lpfc/lpfc_init.c                                                                      |   10 
 kernel/sound/soc/atmel/mchp-spdifrx.c                                                                     |  338 
 kernel/net/netfilter/nf_conntrack_standalone.c                                                            |   11 
 kernel/drivers/md/dm-default-key.c                                                                        |    6 
 kernel/drivers/net/fddi/defxx.c                                                                           |   22 
 kernel/tools/bpf/bpftool/json_writer.c                                                                    |    3 
 kernel/drivers/net/ethernet/freescale/fec_main.c                                                          |   15 
 kernel/arch/parisc/include/asm/led.h                                                                      |    4 
 kernel/drivers/media/v4l2-core/videobuf-dma-contig.c                                                      |   22 
 kernel/arch/x86/kernel/dumpstack.c                                                                        |   11 
 kernel/drivers/net/ethernet/sfc/ef100_tx.c                                                                |    3 
 kernel/drivers/usb/gadget/udc/renesas_usb3.c                                                              |    1 
 kernel/scripts/as-version.sh                                                                              |   69 
 kernel/drivers/net/vmxnet3/vmxnet3_drv.c                                                                  |    8 
 kernel/arch/s390/kernel/ipl.c                                                                             |    2 
 kernel/arch/arm/configs/rv1106-pm.config                                                                  |    1 
 kernel/drivers/mcb/mcb-pci.c                                                                              |   27 
 kernel/drivers/s390/net/qeth_core_main.c                                                                  |    2 
 kernel/drivers/mmc/host/via-sdmmc.c                                                                       |    4 
 kernel/drivers/gpu/drm/nouveau/nouveau_dp.c                                                               |    8 
 kernel/kernel/kexec_file.c                                                                                |   18 
 kernel/drivers/crypto/img-hash.c                                                                          |    8 
 kernel/net/netfilter/ipset/ip_set_hash_netport.c                                                          |   19 
 kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts                                            |    2 
 kernel/drivers/net/wireless/intel/iwlegacy/3945-mac.c                                                     |   16 
 kernel/net/batman-adv/gateway_common.c                                                                    |    2 
 kernel/net/sched/sch_netem.c                                                                              |   61 
 kernel/Documentation/devicetree/bindings/display/panel/panel-simple.yaml                                  |   74 
 kernel/arch/riscv/include/asm/parse_asm.h                                                                 |    7 
 kernel/drivers/android/binder_alloc.h                                                                     |    1 
 kernel/drivers/block/brd.c                                                                                |   26 
 kernel/drivers/mfd/rkx110_x120/rkx110.c                                                                   |   15 
 kernel/tools/testing/selftests/bpf/verifier/spill_fill.c                                                  |   30 
 kernel/fs/erofs/internal.h                                                                                |    2 
 kernel/fs/pstore/Kconfig                                                                                  |    1 
 kernel/net/ipv6/ip6_output.c                                                                              |    9 
 kernel/arch/sh/kernel/head_32.S                                                                           |    6 
 kernel/drivers/gpu/drm/msm/msm_fence.c                                                                    |    2 
 kernel/fs/nfsd/flexfilelayoutxdr.c                                                                        |    9 
 kernel/drivers/android/binder_alloc.c                                                                     |    6 
 kernel/drivers/power/supply/rk817_battery.c                                                               |   10 
 kernel/drivers/mtd/spi-nor/puya.c                                                                         |    2 
 kernel/drivers/net/ethernet/xilinx/xilinx_axienet_main.c                                                  |   10 
 kernel/drivers/tty/serial/sunsab.c                                                                        |    8 
 kernel/drivers/md/dm-thin.c                                                                               |   22 
 kernel/net/core/stream.c                                                                                  |   19 
 kernel/drivers/media/pci/saa7134/saa7134-ts.c                                                             |    1 
 kernel/drivers/net/thunderbolt.c                                                                          |    3 
 kernel/drivers/net/can/vxcan.c                                                                            |    7 
 kernel/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c                                             |    4 
 kernel/drivers/mtd/lpddr/lpddr2_nvm.c                                                                     |    2 
 kernel/drivers/net/wireless/mediatek/mt76/testmode.c                                                      |    1 
 kernel/include/linux/ramfs.h                                                                              |    1 
 kernel/drivers/w1/slaves/w1_therm.c                                                                       |   31 
 kernel/net/tipc/bearer.h                                                                                  |   10 
 kernel/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c                                                    |    4 
 kernel/include/linux/nvme.h                                                                               |    7 
 kernel/arch/x86/include/asm/fpu/internal.h                                                                |    2 
 kernel/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h                                              |    4 
 kernel/net/tipc/bearer.c                                                                                  |    4 
 kernel/drivers/media/dvb-core/dvbdev.c                                                                    |  121 
 kernel/tools/testing/selftests/net/mptcp/mptcp_lib.sh                                                     |  104 
 kernel/fs/btrfs/transaction.c                                                                             |   17 
 kernel/drivers/misc/tifm_7xx1.c                                                                           |    2 
 kernel/arch/arm/boot/dts/exynos4210-i9100.dts                                                             |    4 
 kernel/drivers/input/serio/i8042-acpipnpio.h                                                              | 1897 
 kernel/arch/arm/boot/dts/s5pv210-goni.dts                                                                 |   14 
 kernel/net/sched/sch_hfsc.c                                                                               |    4 
 kernel/security/keys/keyctl.c                                                                             |   11 
 kernel/drivers/of/address.c                                                                               |   21 
 kernel/drivers/crypto/hisilicon/qm.h                                                                      |    6 
 kernel/arch/s390/mm/gmap.c                                                                                |    1 
 kernel/arch/um/drivers/vector_kern.c                                                                      |    1 
 kernel/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c                                                              |    7 
 kernel/drivers/soc/rockchip/rockchip_amp.c                                                                |  108 
 kernel/drivers/scsi/qedf/qedf_debugfs.c                                                                   |   35 
 kernel/fs/xfs/xfs_extent_busy.c                                                                           |   14 
 kernel/drivers/media/tuners/max2165.c                                                                     |    2 
 kernel/drivers/input/sensors/accel/Kconfig                                                                |    6 
 kernel/drivers/net/ethernet/intel/ice/ice_main.c                                                          |   32 
 kernel/kernel/sys.c                                                                                       |   71 
 kernel/drivers/pwm/pwm-mtk-disp.c                                                                         |   98 
 kernel/drivers/tty/serial/samsung_tty.c                                                                   |   14 
 kernel/fs/nilfs2/segbuf.c                                                                                 |    6 
 kernel/drivers/soc/rockchip/rockchip_thunderboot_mmc.c                                                    |   17 
 kernel/drivers/input/sensors/gyro/Kconfig                                                                 |    6 
 kernel/include/linux/if_team.h                                                                            |    3 
 kernel/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c                                                             |    8 
 kernel/kernel/sysctl.c                                                                                    |  120 
 kernel/kernel/trace/blktrace.c                                                                            |    3 
 kernel/block/blk-core.c                                                                                   |   13 
 kernel/net/netfilter/nft_reject_inet.c                                                                    |    6 
 kernel/drivers/powercap/powercap_sys.c                                                                    |   14 
 kernel/drivers/block/null_blk/zoned.c                                                                     |    2 
 kernel/net/netfilter/ipset/ip_set_hash_netiface.c                                                         |   15 
 kernel/drivers/media/platform/rockchip/cif/mipi-csi2.c                                                    |   33 
 kernel/net/sunrpc/svcsock.c                                                                               |   23 
 kernel/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c                                                 |   22 
 kernel/net/caif/caif_usb.c                                                                                |    3 
 kernel/drivers/of/overlay.c                                                                               |    4 
 kernel/drivers/video/rockchip/rga3/rga_mm.c                                                               |   89 
 kernel/arch/ia64/mm/fault.c                                                                               |    2 
 kernel/sound/pci/lx6464es/lx_core.c                                                                       |   11 
 kernel/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c                                                   |    6 
 kernel/kernel/rcu/tasks.h                                                                                 |  139 
 kernel/drivers/firewire/core-cdev.c                                                                       |    4 
 kernel/fs/f2fs/file.c                                                                                     |   20 
 kernel/drivers/net/ethernet/sfc/mcdi_port_common.c                                                        |   11 
 kernel/fs/btrfs/qgroup.c                                                                                  |   57 
 kernel/drivers/net/ethernet/intel/i40e/i40e_nvm.c                                                         |   16 
 kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.h                                                           |    2 
 kernel/include/net/neighbour.h                                                                            |    7 
 kernel/arch/mips/cavium-octeon/executive/cvmx-helper.c                                                    |    2 
 kernel/sound/soc/atmel/tse850-pcm5142.c                                                                   |    2 
 kernel/drivers/input/sensors/gyro/Makefile                                                                |    1 
 kernel/drivers/hwmon/tmp513.c                                                                             |    4 
 kernel/tools/testing/selftests/net/mptcp/mptcp_join.sh                                                    |   69 
 kernel/include/net/cfg80211.h                                                                             |    3 
 kernel/fs/nfsd/nfs4callback.c                                                                             |   12 
 kernel/arch/x86/include/asm/cpufeatures.h                                                                 |   30 
 kernel/arch/arm/boot/dts/imx25.dtsi                                                                       |    2 
 kernel/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c                                                 |   33 
 kernel/drivers/usb/phy/phy-tahvo.c                                                                        |    2 
 kernel/arch/sh/kernel/cpu/sh4/sq.c                                                                        |    2 
 kernel/drivers/gpio/gpio-vf610.c                                                                          |    2 
 kernel/drivers/media/i2c/maxim4c/Makefile                                                                 |    3 
 kernel/drivers/media/i2c/lt8619c.c                                                                        |    3 
 kernel/drivers/clk/x86/Kconfig                                                                            |    5 
 kernel/drivers/gpu/drm/radeon/atombios_encoders.c                                                         |    5 
 kernel/include/linux/sched/task.h                                                                         |   31 
 kernel/drivers/rkflash/sfc_nand_mtd_bbt.c                                                                 |  330 
 kernel/drivers/opp/debugfs.c                                                                              |    2 
 kernel/arch/powerpc/include/asm/imc-pmu.h                                                                 |    2 
 kernel/drivers/hid/hid-mcp2221.c                                                                          |   12 
 kernel/fs/btrfs/volumes.h                                                                                 |    3 
 kernel/fs/nilfs2/btree.c                                                                                  |   15 
 kernel/arch/arm64/include/asm/kvm_emulate.h                                                               |   22 
 kernel/drivers/gpu/host1x/hw/syncpt_hw.c                                                                  |    3 
 kernel/drivers/scsi/hisi_sas/hisi_sas_main.c                                                              |    2 
 kernel/fs/afs/inode.c                                                                                     |    1 
 kernel/drivers/gpu/drm/drm_mode_config.c                                                                  |    8 
 kernel/mm/gup.c                                                                                           |    2 
 kernel/drivers/net/wireless/ath/ath9k/ar9003_hw.c                                                         |   27 
 kernel/net/socket.c                                                                                       |   37 
 kernel/arch/arm64/include/asm/sysreg.h                                                                    |    6 
 kernel/drivers/net/ethernet/qlogic/qede/qede.h                                                            |    4 
 kernel/drivers/net/wan/farsync.c                                                                          |    2 
 kernel/tools/testing/selftests/netfilter/conntrack_icmp_related.sh                                        |   36 
 kernel/android/abi_gki_aarch64_exynos                                                                     |   12 
 kernel/arch/s390/kernel/machine_kexec_file.c                                                              |    5 
 kernel/fs/xfs/xfs_trans_dquot.c                                                                           |   13 
 kernel/lib/mpi/mpi-cmp.c                                                                                  |    8 
 kernel/drivers/macintosh/macio_asic.c                                                                     |    2 
 kernel/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c                                          |    8 
 kernel/fs/ext4/extents.c                                                                                  |   11 
 kernel/drivers/media/i2c/ov5675.c                                                                         |    4 
 kernel/drivers/media/platform/rockchip/isp/bridge_v20.c                                                   |    8 
 kernel/fs/btrfs/volumes.c                                                                                 |   44 
 kernel/sound/soc/fsl/fsl_ssi.c                                                                            |    4 
 kernel/drivers/media/pci/cx23885/cx23885-dvb.c                                                            |   12 
 kernel/kernel/time/hrtimer.c                                                                              |    2 
 kernel/drivers/xen/pvcalls-back.c                                                                         |   17 
 kernel/net/mac80211/mesh.h                                                                                |   22 
 kernel/drivers/media/i2c/og01a10.c                                                                        | 1437 
 kernel/block/blk-mq-sched.c                                                                               |    7 
 kernel/net/dcb/dcbnl.c                                                                                    |    2 
 kernel/include/linux/irqdesc.h                                                                            |    2 
 kernel/arch/x86/kernel/fpu/init.c                                                                         |   15 
 kernel/drivers/net/ethernet/sun/sunvnet.c                                                                 |    3 
 kernel/Documentation/devicetree/bindings/serial/renesas,scif.yaml                                         |    4 
 kernel/lib/fonts/fonts.c                                                                                  |    4 
 kernel/arch/riscv/include/asm/mmio.h                                                                      |   16 
 kernel/drivers/pci/pcie/edr.c                                                                             |    1 
 kernel/drivers/hsi/controllers/omap_ssi_core.c                                                            |   14 
 kernel/drivers/tty/tty_baudrate.c                                                                         |    1 
 kernel/tools/testing/selftests/bpf/progs/btf_dump_test_case_bitfields.c                                   |    2 
 kernel/fs/pnode.c                                                                                         |    2 
 kernel/drivers/net/wan/lapbether.c                                                                        |    3 
 kernel/mm/kasan/report.c                                                                                  |   12 
 kernel/drivers/memstick/core/memstick.c                                                                   |    5 
 kernel/drivers/net/ethernet/qlogic/qede/qede_ethtool.c                                                    |   24 
 kernel/include/linux/efi.h                                                                                |    2 
 kernel/drivers/platform/x86/wmi.c                                                                         |   64 
 kernel/fs/file.c                                                                                          |   25 
 kernel/arch/powerpc/platforms/pseries/ibmebus.c                                                           |    1 
 kernel/drivers/phy/st/phy-miphy28lp.c                                                                     |   42 
 4,599 files changed, 131,631 insertions(+), 46,561 deletions(-)

diff --git a/kernel/Documentation/ABI/testing/configfs-usb-gadget-uvc b/kernel/Documentation/ABI/testing/configfs-usb-gadget-uvc
index a87724e..36c84a4 100644
--- a/kernel/Documentation/ABI/testing/configfs-usb-gadget-uvc
+++ b/kernel/Documentation/ABI/testing/configfs-usb-gadget-uvc
@@ -52,7 +52,7 @@
 KernelVersion:	4.0
 Description:	Default output terminal descriptors
 
-		All attributes read only:
+		All attributes read only except bSourceID:
 
 		==============	=============================================
 		iTerminal	index of string descriptor
diff --git a/kernel/Documentation/ABI/testing/sysfs-devices-system-cpu b/kernel/Documentation/ABI/testing/sysfs-devices-system-cpu
index 3a06e3b..2827e3c 100644
--- a/kernel/Documentation/ABI/testing/sysfs-devices-system-cpu
+++ b/kernel/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -510,17 +510,18 @@
 		cpu_capacity: capacity of cpu#.
 
 What:		/sys/devices/system/cpu/vulnerabilities
-		/sys/devices/system/cpu/vulnerabilities/meltdown
-		/sys/devices/system/cpu/vulnerabilities/spectre_v1
-		/sys/devices/system/cpu/vulnerabilities/spectre_v2
-		/sys/devices/system/cpu/vulnerabilities/spec_store_bypass
+		/sys/devices/system/cpu/vulnerabilities/gather_data_sampling
+		/sys/devices/system/cpu/vulnerabilities/itlb_multihit
 		/sys/devices/system/cpu/vulnerabilities/l1tf
 		/sys/devices/system/cpu/vulnerabilities/mds
-		/sys/devices/system/cpu/vulnerabilities/srbds
-		/sys/devices/system/cpu/vulnerabilities/tsx_async_abort
-		/sys/devices/system/cpu/vulnerabilities/itlb_multihit
+		/sys/devices/system/cpu/vulnerabilities/meltdown
 		/sys/devices/system/cpu/vulnerabilities/mmio_stale_data
 		/sys/devices/system/cpu/vulnerabilities/retbleed
+		/sys/devices/system/cpu/vulnerabilities/spec_store_bypass
+		/sys/devices/system/cpu/vulnerabilities/spectre_v1
+		/sys/devices/system/cpu/vulnerabilities/spectre_v2
+		/sys/devices/system/cpu/vulnerabilities/srbds
+		/sys/devices/system/cpu/vulnerabilities/tsx_async_abort
 Date:		January 2018
 Contact:	Linux kernel mailing list <linux-kernel@vger.kernel.org>
 Description:	Information about CPU vulnerabilities
diff --git a/kernel/Documentation/ABI/testing/sysfs-fs-f2fs b/kernel/Documentation/ABI/testing/sysfs-fs-f2fs
index 75f4bbb..020284a 100644
--- a/kernel/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/kernel/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -271,11 +271,16 @@
 What:		/sys/fs/f2fs/<disk>/gc_urgent
 Date:		August 2017
 Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
-Description:	Do background GC agressively when set. When gc_urgent = 1,
-		background thread starts to do GC by given gc_urgent_sleep_time
-		interval. When gc_urgent = 2, F2FS will lower the bar of
-		checking idle in order to process outstanding discard commands
-		and GC a little bit aggressively. It is set to 0 by default.
+Description:	Do background GC aggressively when set. Set to 0 by default.
+		gc urgent high(1): does GC forcibly in a period of given
+		gc_urgent_sleep_time and ignores I/O idling check. uses greedy
+		GC approach and turns SSR mode on.
+		gc urgent low(2): lowers the bar of checking I/O idling in
+		order to process outstanding discard commands and GC a
+		little bit aggressively. uses cost benefit GC approach.
+		gc urgent mid(3): does GC forcibly in a period of given
+		gc_urgent_sleep_time and executes a mid level of I/O idling check.
+		uses cost benefit GC approach.
 
 What:		/sys/fs/f2fs/<disk>/gc_urgent_sleep_time
 Date:		August 2017
@@ -506,7 +511,7 @@
 Contact:	"Daeho Jeong" <daehojeong@google.com>
 Description:	Show how many segments have been reclaimed by GC during a specific
 		GC mode (0: GC normal, 1: GC idle CB, 2: GC idle greedy,
-		3: GC idle AT, 4: GC urgent high, 5: GC urgent low)
+		3: GC idle AT, 4: GC urgent high, 5: GC urgent low 6: GC urgent mid)
 		You can re-initialize this value to "0".
 
 What:		/sys/fs/f2fs/<disk>/gc_segment_mode
diff --git a/kernel/Documentation/ABI/testing/sysfs-fs-incfs b/kernel/Documentation/ABI/testing/sysfs-fs-incfs
index 690c687..e4e05f9 100644
--- a/kernel/Documentation/ABI/testing/sysfs-fs-incfs
+++ b/kernel/Documentation/ABI/testing/sysfs-fs-incfs
@@ -15,6 +15,12 @@
 Description:	Reads 'supported'. Present if zstd compression is supported
 		for data blocks.
 
+What:		/sys/fs/incremental-fs/features/bugfix_throttling
+Date:		January 2023
+Contact:	Paul Lawrence <paullawrence@google.com>
+Description:	Reads 'supported'. Present if the throttling lock bug is fixed
+		https://android-review.git.corp.google.com/c/kernel/common/+/2381827
+
 What:		/sys/fs/incremental-fs/instances/[name]
 Date:		April 2021
 Contact:	Paul Lawrence <paullawrence@google.com>
diff --git a/kernel/Documentation/ABI/testing/sysfs-kernel-oops_count b/kernel/Documentation/ABI/testing/sysfs-kernel-oops_count
new file mode 100644
index 0000000..156cca9
--- /dev/null
+++ b/kernel/Documentation/ABI/testing/sysfs-kernel-oops_count
@@ -0,0 +1,6 @@
+What:		/sys/kernel/oops_count
+Date:		November 2022
+KernelVersion:	6.2.0
+Contact:	Linux Kernel Hardening List <linux-hardening@vger.kernel.org>
+Description:
+		Shows how many times the system has Oopsed since last boot.
diff --git a/kernel/Documentation/ABI/testing/sysfs-kernel-warn_count b/kernel/Documentation/ABI/testing/sysfs-kernel-warn_count
new file mode 100644
index 0000000..90a0298
--- /dev/null
+++ b/kernel/Documentation/ABI/testing/sysfs-kernel-warn_count
@@ -0,0 +1,6 @@
+What:		/sys/kernel/warn_count
+Date:		November 2022
+KernelVersion:	6.2.0
+Contact:	Linux Kernel Hardening List <linux-hardening@vger.kernel.org>
+Description:
+		Shows how many times the system has Warned since last boot.
diff --git a/kernel/Documentation/admin-guide/cgroup-v1/memory.rst b/kernel/Documentation/admin-guide/cgroup-v1/memory.rst
index 12757e6..7882037 100644
--- a/kernel/Documentation/admin-guide/cgroup-v1/memory.rst
+++ b/kernel/Documentation/admin-guide/cgroup-v1/memory.rst
@@ -82,6 +82,8 @@
  memory.swappiness		     set/show swappiness parameter of vmscan
 				     (See sysctl's vm.swappiness)
  memory.move_charge_at_immigrate     set/show controls of moving charges
+                                     This knob is deprecated and shouldn't be
+                                     used.
  memory.oom_control		     set/show oom controls.
  memory.numa_stat		     show the number of memory usage per numa
 				     node
@@ -740,8 +742,15 @@
        It is recommended to set the soft limit always below the hard limit,
        otherwise the hard limit will take precedence.
 
-8. Move charges at task migration
-=================================
+8. Move charges at task migration (DEPRECATED!)
+===============================================
+
+THIS IS DEPRECATED!
+
+It's expensive and unreliable! It's better practice to launch workload
+tasks directly from inside their target cgroup. Use dedicated workload
+cgroups to allow fine-grained policy adjustments without having to
+move physical pages between control domains.
 
 Users can move charges associated with a task along with task migration, that
 is, uncharge task's pages from the old cgroup and charge them to the new cgroup.
diff --git a/kernel/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst b/kernel/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst
new file mode 100644
index 0000000..264bfa9
--- /dev/null
+++ b/kernel/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst
@@ -0,0 +1,109 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+GDS - Gather Data Sampling
+==========================
+
+Gather Data Sampling is a hardware vulnerability which allows unprivileged
+speculative access to data which was previously stored in vector registers.
+
+Problem
+-------
+When a gather instruction performs loads from memory, different data elements
+are merged into the destination vector register. However, when a gather
+instruction that is transiently executed encounters a fault, stale data from
+architectural or internal vector registers may get transiently forwarded to the
+destination vector register instead. This will allow a malicious attacker to
+infer stale data using typical side channel techniques like cache timing
+attacks. GDS is a purely sampling-based attack.
+
+The attacker uses gather instructions to infer the stale vector register data.
+The victim does not need to do anything special other than use the vector
+registers. The victim does not need to use gather instructions to be
+vulnerable.
+
+Because the buffers are shared between Hyper-Threads cross Hyper-Thread attacks
+are possible.
+
+Attack scenarios
+----------------
+Without mitigation, GDS can infer stale data across virtually all
+permission boundaries:
+
+	Non-enclaves can infer SGX enclave data
+	Userspace can infer kernel data
+	Guests can infer data from hosts
+	Guest can infer guest from other guests
+	Users can infer data from other users
+
+Because of this, it is important to ensure that the mitigation stays enabled in
+lower-privilege contexts like guests and when running outside SGX enclaves.
+
+The hardware enforces the mitigation for SGX. Likewise, VMMs should  ensure
+that guests are not allowed to disable the GDS mitigation. If a host erred and
+allowed this, a guest could theoretically disable GDS mitigation, mount an
+attack, and re-enable it.
+
+Mitigation mechanism
+--------------------
+This issue is mitigated in microcode. The microcode defines the following new
+bits:
+
+ ================================   ===   ============================
+ IA32_ARCH_CAPABILITIES[GDS_CTRL]   R/O   Enumerates GDS vulnerability
+                                          and mitigation support.
+ IA32_ARCH_CAPABILITIES[GDS_NO]     R/O   Processor is not vulnerable.
+ IA32_MCU_OPT_CTRL[GDS_MITG_DIS]    R/W   Disables the mitigation
+                                          0 by default.
+ IA32_MCU_OPT_CTRL[GDS_MITG_LOCK]   R/W   Locks GDS_MITG_DIS=0. Writes
+                                          to GDS_MITG_DIS are ignored
+                                          Can't be cleared once set.
+ ================================   ===   ============================
+
+GDS can also be mitigated on systems that don't have updated microcode by
+disabling AVX. This can be done by setting gather_data_sampling="force" or
+"clearcpuid=avx" on the kernel command-line.
+
+If used, these options will disable AVX use by turning off XSAVE YMM support.
+However, the processor will still enumerate AVX support.  Userspace that
+does not follow proper AVX enumeration to check both AVX *and* XSAVE YMM
+support will break.
+
+Mitigation control on the kernel command line
+---------------------------------------------
+The mitigation can be disabled by setting "gather_data_sampling=off" or
+"mitigations=off" on the kernel command line. Not specifying either will default
+to the mitigation being enabled. Specifying "gather_data_sampling=force" will
+use the microcode mitigation when available or disable AVX on affected systems
+where the microcode hasn't been updated to include the mitigation.
+
+GDS System Information
+------------------------
+The kernel provides vulnerability status information through sysfs. For
+GDS this can be accessed by the following sysfs file:
+
+/sys/devices/system/cpu/vulnerabilities/gather_data_sampling
+
+The possible values contained in this file are:
+
+ ============================== =============================================
+ Not affected                   Processor not vulnerable.
+ Vulnerable                     Processor vulnerable and mitigation disabled.
+ Vulnerable: No microcode       Processor vulnerable and microcode is missing
+                                mitigation.
+ Mitigation: AVX disabled,
+ no microcode                   Processor is vulnerable and microcode is missing
+                                mitigation. AVX disabled as mitigation.
+ Mitigation: Microcode          Processor is vulnerable and mitigation is in
+                                effect.
+ Mitigation: Microcode (locked) Processor is vulnerable and mitigation is in
+                                effect and cannot be disabled.
+ Unknown: Dependent on
+ hypervisor status              Running on a virtual guest processor that is
+                                affected but with no way to know if host
+                                processor is mitigated or vulnerable.
+ ============================== =============================================
+
+GDS Default mitigation
+----------------------
+The updated microcode will enable the mitigation by default. The kernel's
+default action is to leave the mitigation enabled.
diff --git a/kernel/Documentation/admin-guide/hw-vuln/index.rst b/kernel/Documentation/admin-guide/hw-vuln/index.rst
index 2adec1e..84742be 100644
--- a/kernel/Documentation/admin-guide/hw-vuln/index.rst
+++ b/kernel/Documentation/admin-guide/hw-vuln/index.rst
@@ -16,3 +16,5 @@
    multihit.rst
    special-register-buffer-data-sampling.rst
    processor_mmio_stale_data.rst
+   gather_data_sampling.rst
+   srso
diff --git a/kernel/Documentation/admin-guide/hw-vuln/spectre.rst b/kernel/Documentation/admin-guide/hw-vuln/spectre.rst
index 7e061ed..0fba375 100644
--- a/kernel/Documentation/admin-guide/hw-vuln/spectre.rst
+++ b/kernel/Documentation/admin-guide/hw-vuln/spectre.rst
@@ -479,8 +479,16 @@
    On Intel Skylake-era systems the mitigation covers most, but not all,
    cases. See :ref:`[3] <spec_ref3>` for more details.
 
-   On CPUs with hardware mitigation for Spectre variant 2 (e.g. Enhanced
-   IBRS on x86), retpoline is automatically disabled at run time.
+   On CPUs with hardware mitigation for Spectre variant 2 (e.g. IBRS
+   or enhanced IBRS on x86), retpoline is automatically disabled at run time.
+
+   Systems which support enhanced IBRS (eIBRS) enable IBRS protection once at
+   boot, by setting the IBRS bit, and they're automatically protected against
+   Spectre v2 variant attacks, including cross-thread branch target injections
+   on SMT systems (STIBP). In other words, eIBRS enables STIBP too.
+
+   Legacy IBRS systems clear the IBRS bit on exit to userspace and
+   therefore explicitly enable STIBP for that
 
    The retpoline mitigation is turned on by default on vulnerable
    CPUs. It can be forced on or off by the administrator
@@ -504,9 +512,12 @@
    For Spectre variant 2 mitigation, individual user programs
    can be compiled with return trampolines for indirect branches.
    This protects them from consuming poisoned entries in the branch
-   target buffer left by malicious software.  Alternatively, the
-   programs can disable their indirect branch speculation via prctl()
-   (See :ref:`Documentation/userspace-api/spec_ctrl.rst <set_spec_ctrl>`).
+   target buffer left by malicious software.
+
+   On legacy IBRS systems, at return to userspace, implicit STIBP is disabled
+   because the kernel clears the IBRS bit. In this case, the userspace programs
+   can disable indirect branch speculation via prctl() (See
+   :ref:`Documentation/userspace-api/spec_ctrl.rst <set_spec_ctrl>`).
    On x86, this will turn on STIBP to guard against attacks from the
    sibling thread when the user program is running, and use IBPB to
    flush the branch target buffer when switching to/from the program.
diff --git a/kernel/Documentation/admin-guide/hw-vuln/srso.rst b/kernel/Documentation/admin-guide/hw-vuln/srso.rst
new file mode 100644
index 0000000..f79cb11
--- /dev/null
+++ b/kernel/Documentation/admin-guide/hw-vuln/srso.rst
@@ -0,0 +1,133 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Speculative Return Stack Overflow (SRSO)
+========================================
+
+This is a mitigation for the speculative return stack overflow (SRSO)
+vulnerability found on AMD processors. The mechanism is by now the well
+known scenario of poisoning CPU functional units - the Branch Target
+Buffer (BTB) and Return Address Predictor (RAP) in this case - and then
+tricking the elevated privilege domain (the kernel) into leaking
+sensitive data.
+
+AMD CPUs predict RET instructions using a Return Address Predictor (aka
+Return Address Stack/Return Stack Buffer). In some cases, a non-architectural
+CALL instruction (i.e., an instruction predicted to be a CALL but is
+not actually a CALL) can create an entry in the RAP which may be used
+to predict the target of a subsequent RET instruction.
+
+The specific circumstances that lead to this varies by microarchitecture
+but the concern is that an attacker can mis-train the CPU BTB to predict
+non-architectural CALL instructions in kernel space and use this to
+control the speculative target of a subsequent kernel RET, potentially
+leading to information disclosure via a speculative side-channel.
+
+The issue is tracked under CVE-2023-20569.
+
+Affected processors
+-------------------
+
+AMD Zen, generations 1-4. That is, all families 0x17 and 0x19. Older
+processors have not been investigated.
+
+System information and options
+------------------------------
+
+First of all, it is required that the latest microcode be loaded for
+mitigations to be effective.
+
+The sysfs file showing SRSO mitigation status is:
+
+  /sys/devices/system/cpu/vulnerabilities/spec_rstack_overflow
+
+The possible values in this file are:
+
+ - 'Not affected'               The processor is not vulnerable
+
+ - 'Vulnerable: no microcode'   The processor is vulnerable, no
+                                microcode extending IBPB functionality
+                                to address the vulnerability has been
+                                applied.
+
+ - 'Mitigation: microcode'      Extended IBPB functionality microcode
+                                patch has been applied. It does not
+                                address User->Kernel and Guest->Host
+                                transitions protection but it does
+                                address User->User and VM->VM attack
+                                vectors.
+
+                                (spec_rstack_overflow=microcode)
+
+ - 'Mitigation: safe RET'       Software-only mitigation. It complements
+                                the extended IBPB microcode patch
+                                functionality by addressing User->Kernel
+                                and Guest->Host transitions protection.
+
+                                Selected by default or by
+                                spec_rstack_overflow=safe-ret
+
+ - 'Mitigation: IBPB'           Similar protection as "safe RET" above
+                                but employs an IBPB barrier on privilege
+                                domain crossings (User->Kernel,
+                                Guest->Host).
+
+                                (spec_rstack_overflow=ibpb)
+
+ - 'Mitigation: IBPB on VMEXIT' Mitigation addressing the cloud provider
+                                scenario - the Guest->Host transitions
+                                only.
+
+                                (spec_rstack_overflow=ibpb-vmexit)
+
+In order to exploit vulnerability, an attacker needs to:
+
+ - gain local access on the machine
+
+ - break kASLR
+
+ - find gadgets in the running kernel in order to use them in the exploit
+
+ - potentially create and pin an additional workload on the sibling
+   thread, depending on the microarchitecture (not necessary on fam 0x19)
+
+ - run the exploit
+
+Considering the performance implications of each mitigation type, the
+default one is 'Mitigation: safe RET' which should take care of most
+attack vectors, including the local User->Kernel one.
+
+As always, the user is advised to keep her/his system up-to-date by
+applying software updates regularly.
+
+The default setting will be reevaluated when needed and especially when
+new attack vectors appear.
+
+As one can surmise, 'Mitigation: safe RET' does come at the cost of some
+performance depending on the workload. If one trusts her/his userspace
+and does not want to suffer the performance impact, one can always
+disable the mitigation with spec_rstack_overflow=off.
+
+Similarly, 'Mitigation: IBPB' is another full mitigation type employing
+an indrect branch prediction barrier after having applied the required
+microcode patch for one's system. This mitigation comes also at
+a performance cost.
+
+Mitigation: safe RET
+--------------------
+
+The mitigation works by ensuring all RET instructions speculate to
+a controlled location, similar to how speculation is controlled in the
+retpoline sequence.  To accomplish this, the __x86_return_thunk forces
+the CPU to mispredict every function return using a 'safe return'
+sequence.
+
+To ensure the safety of this mitigation, the kernel must ensure that the
+safe return sequence is itself free from attacker interference.  In Zen3
+and Zen4, this is accomplished by creating a BTB alias between the
+untraining function srso_alias_untrain_ret() and the safe return
+function srso_alias_safe_ret() which results in evicting a potentially
+poisoned BTB entry and using that safe one for all function returns.
+
+In older Zen1 and Zen2, this is accomplished using a reinterpretation
+technique similar to Retbleed one: srso_untrain_ret() and
+srso_safe_ret().
diff --git a/kernel/Documentation/admin-guide/kdump/gdbmacros.txt b/kernel/Documentation/admin-guide/kdump/gdbmacros.txt
index 82aecdc..030de95 100644
--- a/kernel/Documentation/admin-guide/kdump/gdbmacros.txt
+++ b/kernel/Documentation/admin-guide/kdump/gdbmacros.txt
@@ -312,10 +312,10 @@
 			set var $prev_flags = $info->flags
 		end
 
-		set var $id = ($id + 1) & $id_mask
 		if ($id == $end_id)
 			loop_break
 		end
+		set var $id = ($id + 1) & $id_mask
 	end
 end
 document dmesg
diff --git a/kernel/Documentation/admin-guide/kernel-parameters.txt b/kernel/Documentation/admin-guide/kernel-parameters.txt
index c841b52..c505b06 100644
--- a/kernel/Documentation/admin-guide/kernel-parameters.txt
+++ b/kernel/Documentation/admin-guide/kernel-parameters.txt
@@ -894,10 +894,6 @@
 
 	debugpat	[X86] Enable PAT debugging
 
-	decnet.addr=	[HW,NET]
-			Format: <area>[,<node>]
-			See also Documentation/networking/decnet.rst.
-
 	default_hugepagesz=
 			[HW] The size of the default HugeTLB page. This is
 			the size represented by the legacy /proc/ hugepages
@@ -1487,6 +1483,26 @@
 	gart_fix_e820=	[X86-64] disable the fix e820 for K8 GART
 			Format: off | on
 			default: on
+
+	gather_data_sampling=
+			[X86,INTEL] Control the Gather Data Sampling (GDS)
+			mitigation.
+
+			Gather Data Sampling is a hardware vulnerability which
+			allows unprivileged speculative access to data which was
+			previously stored in vector registers.
+
+			This issue is mitigated by default in updated microcode.
+			The mitigation may have a performance impact but can be
+			disabled. On systems without the microcode mitigation
+			disabling AVX serves as a mitigation.
+
+			force:	Disable AVX to mitigate systems without
+				microcode mitigation. No effect if the microcode
+				mitigation is present. Known to cause crashes in
+				userspace with buggy AVX enumeration.
+
+			off:    Disable GDS mitigation.
 
 	gcov_persist=	[GCOV] When non-zero (default), profiling data for
 			kernel modules is saved and remains accessible via
@@ -2144,24 +2160,57 @@
 
 	ivrs_ioapic	[HW,X86-64]
 			Provide an override to the IOAPIC-ID<->DEVICE-ID
-			mapping provided in the IVRS ACPI table. For
-			example, to map IOAPIC-ID decimal 10 to
-			PCI device 00:14.0 write the parameter as:
+			mapping provided in the IVRS ACPI table.
+			By default, PCI segment is 0, and can be omitted.
+
+			For example, to map IOAPIC-ID decimal 10 to
+			PCI segment 0x1 and PCI device 00:14.0,
+			write the parameter as:
+				ivrs_ioapic=10@0001:00:14.0
+
+			Deprecated formats:
+			* To map IOAPIC-ID decimal 10 to PCI device 00:14.0
+			  write the parameter as:
 				ivrs_ioapic[10]=00:14.0
+			* To map IOAPIC-ID decimal 10 to PCI segment 0x1 and
+			  PCI device 00:14.0 write the parameter as:
+				ivrs_ioapic[10]=0001:00:14.0
 
 	ivrs_hpet	[HW,X86-64]
 			Provide an override to the HPET-ID<->DEVICE-ID
-			mapping provided in the IVRS ACPI table. For
-			example, to map HPET-ID decimal 0 to
-			PCI device 00:14.0 write the parameter as:
+			mapping provided in the IVRS ACPI table.
+			By default, PCI segment is 0, and can be omitted.
+
+			For example, to map HPET-ID decimal 10 to
+			PCI segment 0x1 and PCI device 00:14.0,
+			write the parameter as:
+				ivrs_hpet=10@0001:00:14.0
+
+			Deprecated formats:
+			* To map HPET-ID decimal 0 to PCI device 00:14.0
+			  write the parameter as:
 				ivrs_hpet[0]=00:14.0
+			* To map HPET-ID decimal 10 to PCI segment 0x1 and
+			  PCI device 00:14.0 write the parameter as:
+				ivrs_ioapic[10]=0001:00:14.0
 
 	ivrs_acpihid	[HW,X86-64]
 			Provide an override to the ACPI-HID:UID<->DEVICE-ID
-			mapping provided in the IVRS ACPI table. For
-			example, to map UART-HID:UID AMD0020:0 to
-			PCI device 00:14.5 write the parameter as:
+			mapping provided in the IVRS ACPI table.
+			By default, PCI segment is 0, and can be omitted.
+
+			For example, to map UART-HID:UID AMD0020:0 to
+			PCI segment 0x1 and PCI device ID 00:14.5,
+			write the parameter as:
+				ivrs_acpihid=AMD0020:0@0001:00:14.5
+
+			Deprecated formats:
+			* To map UART-HID:UID AMD0020:0 to PCI segment is 0,
+			  PCI device ID 00:14.5, write the parameter as:
 				ivrs_acpihid[00:14.5]=AMD0020:0
+			* To map UART-HID:UID AMD0020:0 to PCI segment 0x1 and
+			  PCI device ID 00:14.5, write the parameter as:
+				ivrs_acpihid[0001:00:14.5]=AMD0020:0
 
 	js=		[HW,JOY] Analog joystick
 			See Documentation/input/joydev/joystick.rst.
@@ -2310,6 +2359,8 @@
 
 	kvm-arm.mode=
 			[KVM,ARM] Select one of KVM/arm64's modes of operation.
+
+			none: Forcefully disable KVM.
 
 			nvhe: Standard nVHE-based mode, without support for
 			      protected guests.
@@ -2918,22 +2969,23 @@
 				Disable all optional CPU mitigations.  This
 				improves system performance, but it may also
 				expose users to several CPU vulnerabilities.
-				Equivalent to: nopti [X86,PPC]
+				Equivalent to: gather_data_sampling=off [X86]
 					       kpti=0 [ARM64]
-					       nospectre_v1 [X86,PPC]
-					       nobp=0 [S390]
-					       nospectre_v2 [X86,PPC,S390,ARM64]
-					       spectre_v2_user=off [X86]
-					       spec_store_bypass_disable=off [X86,PPC]
-					       ssbd=force-off [ARM64]
+					       kvm.nx_huge_pages=off [X86]
 					       l1tf=off [X86]
 					       mds=off [X86]
-					       tsx_async_abort=off [X86]
-					       kvm.nx_huge_pages=off [X86]
+					       mmio_stale_data=off [X86]
 					       no_entry_flush [PPC]
 					       no_uaccess_flush [PPC]
-					       mmio_stale_data=off [X86]
+					       nobp=0 [S390]
+					       nopti [X86,PPC]
+					       nospectre_v1 [X86,PPC]
+					       nospectre_v2 [X86,PPC,S390,ARM64]
 					       retbleed=off [X86]
+					       spec_store_bypass_disable=off [X86,PPC]
+					       spectre_v2_user=off [X86]
+					       ssbd=force-off [ARM64]
+					       tsx_async_abort=off [X86]
 
 				Exceptions:
 					       This does not have any effect on
@@ -5191,6 +5243,17 @@
 			Not specifying this option is equivalent to
 			spectre_v2_user=auto.
 
+	spec_rstack_overflow=
+			[X86] Control RAS overflow mitigation on AMD Zen CPUs
+
+			off		- Disable mitigation
+			microcode	- Enable microcode mitigation only
+			safe-ret	- Enable sw-only safe RET mitigation (default)
+			ibpb		- Enable mitigation by issuing IBPB on
+					  kernel entry
+			ibpb-vmexit	- Issue IBPB only on VMEXIT
+					  (cloud-specific mitigation)
+
 	spec_store_bypass_disable=
 			[HW] Control Speculative Store Bypass (SSB) Disable mitigation
 			(Speculative Store Bypass vulnerability)
diff --git a/kernel/Documentation/admin-guide/security-bugs.rst b/kernel/Documentation/admin-guide/security-bugs.rst
index c32eb78..d6d93e9 100644
--- a/kernel/Documentation/admin-guide/security-bugs.rst
+++ b/kernel/Documentation/admin-guide/security-bugs.rst
@@ -63,31 +63,28 @@
 of the report are treated confidentially even after the embargo has been
 lifted, in perpetuity.
 
-Coordination
-------------
+Coordination with other groups
+------------------------------
 
-Fixes for sensitive bugs, such as those that might lead to privilege
-escalations, may need to be coordinated with the private
-<linux-distros@vs.openwall.org> mailing list so that distribution vendors
-are well prepared to issue a fixed kernel upon public disclosure of the
-upstream fix. Distros will need some time to test the proposed patch and
-will generally request at least a few days of embargo, and vendor update
-publication prefers to happen Tuesday through Thursday. When appropriate,
-the security team can assist with this coordination, or the reporter can
-include linux-distros from the start. In this case, remember to prefix
-the email Subject line with "[vs]" as described in the linux-distros wiki:
-<http://oss-security.openwall.org/wiki/mailing-lists/distros#how-to-use-the-lists>
+The kernel security team strongly recommends that reporters of potential
+security issues NEVER contact the "linux-distros" mailing list until
+AFTER discussing it with the kernel security team.  Do not Cc: both
+lists at once.  You may contact the linux-distros mailing list after a
+fix has been agreed on and you fully understand the requirements that
+doing so will impose on you and the kernel community.
+
+The different lists have different goals and the linux-distros rules do
+not contribute to actually fixing any potential security problems.
 
 CVE assignment
 --------------
 
-The security team does not normally assign CVEs, nor do we require them
-for reports or fixes, as this can needlessly complicate the process and
-may delay the bug handling. If a reporter wishes to have a CVE identifier
-assigned ahead of public disclosure, they will need to contact the private
-linux-distros list, described above. When such a CVE identifier is known
-before a patch is provided, it is desirable to mention it in the commit
-message if the reporter agrees.
+The security team does not assign CVEs, nor do we require them for
+reports or fixes, as this can needlessly complicate the process and may
+delay the bug handling.  If a reporter wishes to have a CVE identifier
+assigned, they should find one by themselves, for example by contacting
+MITRE directly.  However under no circumstances will a patch inclusion
+be delayed to wait for a CVE identifier to arrive.
 
 Non-disclosure agreements
 -------------------------
diff --git a/kernel/Documentation/admin-guide/sysctl/kernel.rst b/kernel/Documentation/admin-guide/sysctl/kernel.rst
index a4b1ebc..6b0c7b6 100644
--- a/kernel/Documentation/admin-guide/sysctl/kernel.rst
+++ b/kernel/Documentation/admin-guide/sysctl/kernel.rst
@@ -663,6 +663,15 @@
 an oops event is detected.
 
 
+oops_limit
+==========
+
+Number of kernel oopses after which the kernel should panic when
+``panic_on_oops`` is not set. Setting this to 0 disables checking
+the count. Setting this to  1 has the same effect as setting
+``panic_on_oops=1``. The default value is 10000.
+
+
 osrelease, ostype & version
 ===========================
 
@@ -1469,6 +1478,16 @@
 2 Unprivileged calls to ``bpf()`` are disabled
 = =============================================================
 
+
+warn_limit
+==========
+
+Number of kernel warnings after which the kernel should panic when
+``panic_on_warn`` is not set. Setting this to 0 disables checking
+the warning count. Setting this to 1 has the same effect as setting
+``panic_on_warn=1``. The default value is 0.
+
+
 watchdog
 ========
 
diff --git a/kernel/Documentation/admin-guide/sysctl/net.rst b/kernel/Documentation/admin-guide/sysctl/net.rst
index 7f55385..4f1a686 100644
--- a/kernel/Documentation/admin-guide/sysctl/net.rst
+++ b/kernel/Documentation/admin-guide/sysctl/net.rst
@@ -34,13 +34,14 @@
  ========= =================== = ========== ==================
  Directory Content               Directory  Content
  ========= =================== = ========== ==================
- core      General parameter     appletalk  Appletalk protocol
- unix      Unix domain sockets   netrom     NET/ROM
- 802       E802 protocol         ax25       AX25
- ethernet  Ethernet protocol     rose       X.25 PLP layer
- ipv4      IP version 4          x25        X.25 protocol
- bridge    Bridging              decnet     DEC net
- ipv6      IP version 6          tipc       TIPC
+ 802       E802 protocol         mptcp     Multipath TCP
+ appletalk Appletalk protocol    netfilter Network Filter
+ ax25      AX25                  netrom     NET/ROM
+ bridge    Bridging              rose      X.25 PLP layer
+ core      General parameter     tipc      TIPC
+ ethernet  Ethernet protocol     unix      Unix domain sockets
+ ipv4      IP version 4          x25       X.25 protocol
+ ipv6      IP version 6
  ========= =================== = ========== ==================
 
 1. /proc/sys/net/core - Network core options
diff --git a/kernel/Documentation/admin-guide/sysctl/vm.rst b/kernel/Documentation/admin-guide/sysctl/vm.rst
index 9c321c7..c7d8218 100644
--- a/kernel/Documentation/admin-guide/sysctl/vm.rst
+++ b/kernel/Documentation/admin-guide/sysctl/vm.rst
@@ -970,7 +970,7 @@
 
 The unit is in fractions of 10,000. The default value of 10 means the
 distances between watermarks are 0.1% of the available memory in the
-node/system. The maximum value is 1000, or 10% of memory.
+node/system. The maximum value is 3000, or 30% of memory.
 
 A high rate of threads entering direct reclaim (allocstall) or kswapd
 going to sleep prematurely (kswapd_low_wmark_hit_quickly) can indicate
diff --git a/kernel/Documentation/arm64/silicon-errata.rst b/kernel/Documentation/arm64/silicon-errata.rst
index 3ec0657..08b6b40 100644
--- a/kernel/Documentation/arm64/silicon-errata.rst
+++ b/kernel/Documentation/arm64/silicon-errata.rst
@@ -113,6 +113,9 @@
 | ARM            | MMU-500         | #841119,826419  | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | GIC-700         | #2941627        | ARM64_ERRATUM_2941627       |
++----------------+-----------------+-----------------+-----------------------------+
++----------------+-----------------+-----------------+-----------------------------+
 | Broadcom       | Brahma-B53      | N/A             | ARM64_ERRATUM_845719        |
 +----------------+-----------------+-----------------+-----------------------------+
 | Broadcom       | Brahma-B53      | N/A             | ARM64_ERRATUM_843419        |
@@ -155,6 +158,9 @@
 +----------------+-----------------+-----------------+-----------------------------+
 | Hisilicon      | Hip08 SMMU PMCG | #162001800      | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
+| Hisilicon      | Hip08 SMMU PMCG | #162001900      | N/A                         |
+|                | Hip09 SMMU PMCG |                 |                             |
++----------------+-----------------+-----------------+-----------------------------+
 +----------------+-----------------+-----------------+-----------------------------+
 | Qualcomm Tech. | Kryo/Falkor v1  | E1003           | QCOM_FALKOR_ERRATUM_1003    |
 +----------------+-----------------+-----------------+-----------------------------+
diff --git a/kernel/Documentation/core-api/kernel-api.rst b/kernel/Documentation/core-api/kernel-api.rst
index 741aa37..2a7444e 100644
--- a/kernel/Documentation/core-api/kernel-api.rst
+++ b/kernel/Documentation/core-api/kernel-api.rst
@@ -24,11 +24,8 @@
 .. kernel-doc:: lib/vsprintf.c
    :export:
 
-.. kernel-doc:: include/linux/kernel.h
-   :functions: kstrtol
-
-.. kernel-doc:: include/linux/kernel.h
-   :functions: kstrtoul
+.. kernel-doc:: include/linux/kstrtox.h
+   :functions: kstrtol kstrtoul
 
 .. kernel-doc:: lib/kstrtox.c
    :export:
diff --git a/kernel/Documentation/dev-tools/gdb-kernel-debugging.rst b/kernel/Documentation/dev-tools/gdb-kernel-debugging.rst
index 4756f6b..10cdd99 100644
--- a/kernel/Documentation/dev-tools/gdb-kernel-debugging.rst
+++ b/kernel/Documentation/dev-tools/gdb-kernel-debugging.rst
@@ -39,6 +39,10 @@
   this mode. In this case, you should build the kernel with
   CONFIG_RANDOMIZE_BASE disabled if the architecture supports KASLR.
 
+- Build the gdb scripts (required on kernels v5.1 and above)::
+
+    make scripts_gdb
+
 - Enable the gdb stub of QEMU/KVM, either
 
     - at VM startup time by appending "-s" to the QEMU command line
diff --git a/kernel/Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml b/kernel/Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml
index 229af98..7cd88bc 100644
--- a/kernel/Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml
+++ b/kernel/Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml
@@ -16,8 +16,6 @@
   reads required input clock frequencies from the devicetree and acts as clock
   provider for all clock consumers of PS clocks.
 
-select: false
-
 properties:
   compatible:
     const: xlnx,versal-clk
diff --git a/kernel/Documentation/devicetree/bindings/cpufreq/cpufreq-rockchip.txt b/kernel/Documentation/devicetree/bindings/cpufreq/cpufreq-rockchip.txt
index 617572a..55865c2 100644
--- a/kernel/Documentation/devicetree/bindings/cpufreq/cpufreq-rockchip.txt
+++ b/kernel/Documentation/devicetree/bindings/cpufreq/cpufreq-rockchip.txt
@@ -8,83 +8,4 @@
 on operating-points-v2, but the driver can also create the "cpufreq-dt"
 platform_device to compatibility with operating-points.
 
-For more information about the expected DT format [See: ../opp/opp.txt].
-
-Optional properties:
-In 'operating-points-v2' table:
-- rockchip,leakage-voltage-sel: The property is an array of 3-tuples items, and
-                       each item consists of leakage and voltage selector like
-                       <min-leakage max-leakage volt-selector>.
-                       min-leakage: minimum leakage in mA, ranges from 1 to 254.
-                       max-leakage: maximum leakage in mA, ranges from 1 to 254.
-                       voltage-selector: a sequence number which is used to math
-                       opp-microvolt-L<number> roperty in OPP node.
-
-- rockchip,pvtm-voltage-sel: The property is an array of 3-tuples items, and
-                       each item consists of pvtm and voltage selector like
-                       <min-pvtm max-pvtm volt-selector>.
-                       min-pvtm: minimum frequency count in KHz.
-                       max-pvtm: maximum frequency count in KHz.
-                       voltage-selector: a sequence number which is used to math
-                       opp-microvolt-L<number> roperty in OPP node.
-- rockchip,pvtm-freq: Clock frequency in KHz, which is used to set the cpu clock
-                       frequency before get frequency count of pvtm.
-- rockchip,pvtm-volt: Voltage in uV, which is used to set the cpu voltage before
-                       get frequency count of pvtm.
-- rockchip,pvtm-ch: An array of two integers containing pvtm channel and clock
-                       oscillation ring.
-- rockchip,pvtm-sample-time: The number of milliseconds to wait for pvtm to
-                       finish counting.
-- rockchip,pvtm-number: An integer indicating the number of sampling points.
-- rockchip,pvtm-error: An integer indicating the error between the sample
-                       results.
-- rockchip,pvtm-ref-temp: The SoC internal temperature in degree centigrade, the
-                       min-pvtm and max-pvtm in 'leakage-voltage-sel' are
-                       measured at reference temperature.
-- rockchip,pvtm-temp-prop: An array of two integers containing proportional
-                       constants which is used to convert the value at current
-                       temperature to reference temperature. The first one is
-                       used when current temperature is below reference
-                       temperature. Conversely, The second one is used when
-                       current temperature is above reference temperature.
-- rockchip,pvtm-thermal-zone: A thermal zone node containing thermal sensor,
-                       it's used to get the current temperature.
-- rockchip,thermal-zone: A thermal zone node containing thermal sensor,
-                       it's used to get the current temperature.
-
-- nvmem-cells: A phandle to cpu_leakage data provided by a nvmem device.
-- nvmem-cell-names: Should be "cpu_leakage"
-
-- rockchip,threshold-freq: Clock frequency in KHz, it's used to reduce power
-                       for SoCs with two clusters.
-- rockchip,freq-limit: Only one cluster can contain the property, and the
-                       cluster's maximum frequency will be limited to its
-                       threshold frequency, if the other cluster's frequency
-                       is geater than or equal to its threshold frequency.
-
-Examples:
-
-cpus {
-	cpu@0 {
-		operating-points-v2 = <&cluster0_opp>;
-	};
-}
-
-cluster0_opp: opp_table0 {
-	compatible = "operating-points-v2";
-	opp-shared;
-	rockchip,leakage-voltage-sel = <
-		1   24   0
-		25  254  1
-	>;
-	nvmem-cells = <&cpu_leakage>;
-	nvmem-cell-names = "cpu_leakage";
-
-	opp@216000000 {
-		opp-hz = /bits/ 64 <216000000>;
-		opp-microvolt = <950000 950000 1350000>;
-		opp-microvolt-L0 = <1050000 1050000 1350000>;
-		opp-microvolt-L1 = <950000 950000 1350000>;
-		opp-suspend;
-	}
-};
+For more information about the expected DT format [See: ../opp/rockchip-opp.txt].
diff --git a/kernel/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/kernel/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
index edb53ab..8fcf8c0 100644
--- a/kernel/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/kernel/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -29,6 +29,10 @@
     # compatible must be listed in alphabetical order, ordered by compatible.
     # The description in the comment is mandatory for each compatible.
 
+        # common simple panel
+      - simple-panel
+        # common simple dsi panel
+      - simple-panel-dsi
         # Ampire AM-1280800N3TZQW-T00H 10.1" WQVGA TFT LCD panel
       - ampire,am-1280800n3tzqw-t00h
         # Ampire AM-480272H3TMQW-T01H 4.3" WQVGA TFT LCD panel
@@ -288,6 +292,76 @@
   port: true
   power-supply: true
 
+  reset-gpios:
+    description: GPIO pin to reset the panel
+
+  prepare-delay-ms:
+    description: |
+      the time (in milliseconds) that it takes for the panel to
+      become ready and start receiving video data
+  enable-delay-ms:
+    description: |
+      the time (in milliseconds) that it takes for the panel to
+      display the first valid frame after starting to receive
+      video data
+  disable-delay-ms:
+    description: |
+      the time (in milliseconds) that it takes for the panel to
+      turn the display off (no content is visible)
+  unprepare-delay-ms:
+    description: |
+      the time (in milliseconds) that it takes for the panel
+      to power itself down completely
+  reset-delay-ms:
+    description: |
+      the time (in milliseconds) that it takes for the panel to
+      reset itself completely
+  init-delay-ms:
+    description: |
+      the time (in milliseconds) that it takes for the panel to
+      send init command sequence after reset deassert
+
+  width-mm:
+    description: width (in millimeters) of the panel's active display area
+  height-mm:
+    description: height (in millimeters) of the panel's active display area
+
+  bpc:
+    description: bits per color/component
+  bus-format:
+    description: pixel data format on the wire
+
+  dsi,lanes:
+    description: number of active data lanes
+  dsi,format:
+    description: pixel format for video mode
+  dsi,flags:
+    description: DSI operation mode related flags
+
+  panel-init-sequence: true
+  panel-exit-sequence:
+    description: |
+      A byte stream formed by simple multiple dcs packets.
+        byte 0 - dcs data type
+        byte 1 - wait number of specified ms after dcs command transmitted
+        byte 2 - packet payload length
+        byte 3 - and beyond: number byte of payload
+  rockchip,cmd-type:
+    description: default is DSI cmd, or "spi", "mcu" cmd type
+  spi-sdi:
+    description: spi init panel for spi-sdi io
+  spi-scl:
+    description: spi init panel for spi-scl io
+  spi-cs:
+    description: spi init pael for spi-cs io
+
+  power-invert:
+    description: power invert control
+  vsp-supply:
+    description: positive voltage supply
+  vsn-supply:
+    description: negative voltage supply
+
 additionalProperties: false
 
 required:
diff --git a/kernel/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml b/kernel/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml
new file mode 100644
index 0000000..baa65a5
--- /dev/null
+++ b/kernel/Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml
@@ -0,0 +1,158 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/addac/adi,ad74413r.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices AD74412R/AD74413R device
+
+maintainers:
+  - Cosmin Tanislav <cosmin.tanislav@analog.com>
+
+description: |
+  The AD74412R and AD74413R are quad-channel software configurable input/output
+  solutions for building and process control applications. They contain
+  functionality for analog output, analog input, digital input, resistance
+  temperature detector, and thermocouple measurements integrated
+  into a single chip solution with an SPI interface.
+  The devices feature a 16-bit ADC and four configurable 13-bit DACs to provide
+  four configurable input/output channels and a suite of diagnostic functions.
+  The AD74413R differentiates itself from the AD74412R by being HART-compatible.
+    https://www.analog.com/en/products/ad74412r.html
+    https://www.analog.com/en/products/ad74413r.html
+
+properties:
+  compatible:
+    enum:
+      - adi,ad74412r
+      - adi,ad74413r
+
+  reg:
+    maxItems: 1
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 0
+
+  spi-max-frequency:
+    maximum: 1000000
+
+  spi-cpol: true
+
+  interrupts:
+    maxItems: 1
+
+  refin-supply: true
+
+  shunt-resistor-micro-ohms:
+    description:
+      Shunt (sense) resistor value in micro-Ohms.
+    default: 100000000
+
+required:
+  - compatible
+  - reg
+  - spi-max-frequency
+  - spi-cpol
+  - refin-supply
+
+additionalProperties: false
+
+patternProperties:
+  "^channel@[0-3]$":
+    type: object
+    description: Represents the external channels which are connected to the device.
+
+    properties:
+      reg:
+        description: |
+          The channel number. It can have up to 4 channels numbered from 0 to 3.
+        minimum: 0
+        maximum: 3
+
+      adi,ch-func:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Channel function.
+          HART functions are not supported on AD74412R.
+          0 - CH_FUNC_HIGH_IMPEDANCE
+          1 - CH_FUNC_VOLTAGE_OUTPUT
+          2 - CH_FUNC_CURRENT_OUTPUT
+          3 - CH_FUNC_VOLTAGE_INPUT
+          4 - CH_FUNC_CURRENT_INPUT_EXT_POWER
+          5 - CH_FUNC_CURRENT_INPUT_LOOP_POWER
+          6 - CH_FUNC_RESISTANCE_INPUT
+          7 - CH_FUNC_DIGITAL_INPUT_LOGIC
+          8 - CH_FUNC_DIGITAL_INPUT_LOOP_POWER
+          9 - CH_FUNC_CURRENT_INPUT_EXT_POWER_HART
+          10 - CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART
+        minimum: 0
+        maximum: 10
+        default: 0
+
+      adi,gpo-comparator:
+        type: boolean
+        description: |
+          Whether to configure GPO as a comparator or not.
+          When not configured as a comparator, the GPO will be treated as an
+          output-only GPIO.
+
+    required:
+      - reg
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/iio/addac/adi,ad74413r.h>
+
+    spi {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      cs-gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
+      status = "okay";
+
+      ad74413r@0 {
+        compatible = "adi,ad74413r";
+        reg = <0>;
+        spi-max-frequency = <1000000>;
+        spi-cpol;
+
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        interrupt-parent = <&gpio>;
+        interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
+
+        refin-supply = <&ad74413r_refin>;
+
+        channel@0 {
+          reg = <0>;
+
+          adi,ch-func = <CH_FUNC_VOLTAGE_OUTPUT>;
+        };
+
+        channel@1 {
+          reg = <1>;
+
+          adi,ch-func = <CH_FUNC_CURRENT_OUTPUT>;
+        };
+
+        channel@2 {
+          reg = <2>;
+
+          adi,ch-func = <CH_FUNC_DIGITAL_INPUT_LOGIC>;
+          adi,gpo-comparator;
+        };
+
+        channel@3 {
+          reg = <3>;
+
+          adi,ch-func = <CH_FUNC_CURRENT_INPUT_EXT_POWER>;
+        };
+      };
+    };
+...
diff --git a/kernel/Documentation/devicetree/bindings/opp/rockchip-opp.txt b/kernel/Documentation/devicetree/bindings/opp/rockchip-opp.txt
new file mode 100644
index 0000000..fa018aa
--- /dev/null
+++ b/kernel/Documentation/devicetree/bindings/opp/rockchip-opp.txt
@@ -0,0 +1,183 @@
+Rockchip OPP bindings to describe OPP nodes
+
+The bindings are based on top of the operating-points-v2 bindings
+described in Documentation/devicetree/bindings/opp/opp.txt
+Additional properties are described below.
+
+Optional properties:
+In 'operating-points-v2' table:
+- rockchip,supported-hw: The property allows to set supported hardware version.
+
+- rockchip,opp-shared-dsu: Indicates the dsu also uses the opp table.
+
+- rockchip,leakage-voltage-sel: The property is an array of 3-tuples items, and
+                       each item consists of leakage and voltage selector like
+                       <min-leakage max-leakage volt-selector>.
+                       min-leakage: minimum leakage in mA, ranges from 1 to 254.
+                       max-leakage: maximum leakage in mA, ranges from 1 to 254.
+                       voltage-selector: a sequence number which is used to math
+                       opp-microvolt-L<number> property in OPP node.
+- rockchip,leakage-scaling-sel: Similar to 'rockchip,leakage-voltage-sel', this
+                       allows to change max frequency according to leakage.
+
+- rockchip,pvtm-hw: Similar to 'opp-supported-hw', but only one hierarchical
+                       level, if hardware version is set in the property, the
+                       'rockchip,pvtm-voltage-sel-hw' will be used, otherwise
+                       'rockchip,pvtm-voltage-sel' will be used.
+- rockchip,pvtm-voltage-sel-hw: Similar to 'rockchip,pvtm-voltage-sel', this
+                       depends on 'rockchip,pvtm-hw' property.
+- rockchip,pvtm-voltage-sel: The property is an array of 3-tuples items, and
+                       each item consists of pvtm and voltage selector like
+                       <min-pvtm max-pvtm volt-selector>.
+                       min-pvtm: minimum frequency count in KHz.
+                       max-pvtm: maximum frequency count in KHz.
+                       voltage-selector: a sequence number which is used to math
+                       opp-microvolt-L<number> property in OPP node.
+- rockchip,pvtm-voltage-sel-B<number>: Similar to 'rockchip,pvtm-voltage-sel', this
+                       depends on 'rockchip,pvtm-hw' property. If contain
+                       'rockchip,pvtm-voltage-sel-hw', the property is unused.
+
+- rockchip,pvtm-scaling-sel: Similar to 'rockchip,pvtm-voltage-sel', this allows
+                       to change maximum frequency according to pvtm.
+
+- rockchip,bin-voltage-sel: The property is an array of 2-tuples items, and
+                       each item consists of bin and voltage selector like
+                       <min-bin volt-selector>.
+                       min-bin: chip version.
+                       voltage-selector: a sequence number which is used to math
+                       opp-microvolt-L<number> property in OPP node.
+- rockchip,bin-scaling-sel: Similar to 'rockchip,bin-voltage-sel', this allows
+                       to change maximum frequency according to chip version.
+
+- rockchip,grf: The phandle of the syscon node for GRF register.
+- rockchip,dsu-grf: the phandle of the syscon node for DSU GRF register.
+- rockchip,opp-clocks: List of clocks for accessing pvtpll and read margin.
+- volt-mem-read-margin: The property is an array of 2-tuples items, and
+                       each item consists voltage an memory read margin like
+                       <voltage_uV rm>, this allows to change read margin
+                       according to voltage.
+- low-volt-mem-read-margin: The memory read margin value of low voltage.
+- intermediate-threshold-freq: Clock frequency in KHz, if current frequency or
+                       target frequency less than the threshold frequency,
+                       there may be no need to set intermediate rate.
+
+- rockchip,pvtpll-table: The property is an array of 5-tuples items, and
+                       each item consists frequency and pvtpll config like
+                       <freq_khz ring length low_temp_ring low_temp_length>,
+                       this allows to change pvtpll config through sip smc interface.
+- rockchip,pvtpll-table-B<number>: Similar to 'rockchip,pvtpll-table'.
+
+- rockchip,pvtpll-avg-offset: The offset of average value register.
+- rockchip,pvtpll-min-rate: Clock frequency in KHz, if opp frequency is higher
+                       than the minimum frequency, the opp voltage will be
+                       changed.
+- rockchip,pvtpll-volt-step: Voltage step in uV.
+
+- rockchip,pvtm-pvtpll: Indicates pvtm value is from pvtpll.
+- rockchip,pvtm-offset: The offset of pvtm value register.
+- rockchip,pvtm-freq: Clock frequency in KHz, which is used to set the cpu clock
+                       frequency before get frequency count of pvtm.
+- rockchip,pvtm-volt: Voltage in uV, which is used to set the cpu voltage before
+                       get frequency count of pvtm.
+- rockchip,pvtm-ch: An array of two integers containing pvtm channel and clock
+                       oscillation ring.
+- rockchip,pvtm-sample-time: The number of milliseconds to wait for pvtm to
+                       finish counting.
+- rockchip,pvtm-number: An integer indicating the number of sampling points.
+- rockchip,pvtm-error: An integer indicating the error between the sample
+                       results.
+- rockchip,pvtm-ref-temp: The SoC internal temperature in degree centigrade, the
+                       min-pvtm and max-pvtm in 'leakage-voltage-sel' are
+                       measured at reference temperature.
+- rockchip,pvtm-temp-prop: An array of two integers containing proportional
+                       constants which is used to convert the value at current
+                       temperature to reference temperature. The first one is
+                       used when current temperature is below reference
+                       temperature. Conversely, The second one is used when
+                       current temperature is above reference temperature.
+- rockchip,pvtm-thermal-zone: A thermal zone node containing thermal sensor,
+                       it's used to get the current temperature.
+- rockchip,thermal-zone: A thermal zone node containing thermal sensor,
+                       it's used to get the current temperature.
+
+- nvmem-cells: A phandle to soc info provided by a nvmem device.
+- nvmem-cell-names: Should be "leakage", "pvtm", "mbist-vmin", "opp-info",
+                      "specification_serial_number", "performance", or
+                      "remark_spec_serial_number".
+
+- rockchip,threshold-freq: Clock frequency in KHz, it's used to reduce power
+                       for SoCs with two clusters.
+- rockchip,freq-limit: Only one cluster can contain the property, and the
+                       cluster's maximum frequency will be limited to its
+                       threshold frequency, if the other cluster's frequency
+                       is geater than or equal to its threshold frequency.
+
+- rockchip,init-freq: The initial clock frequency in KHz.
+
+- rockchip,max-volt: The maximum voltage of opp.
+- rockchip,evb-irdrop: The evb irdrop in uV.
+- rockchip,board-irdrop: The property is an array of 3-tuples items, and
+                       each item consists of frequency and voltage like
+                       <min-freq max-freq volt>. This allows to change voltage
+                       for different frequencice.
+
+- rockchip,temp-hysteresis: Temperature hysteresis in millicelsius.
+- rockchip,low-temp: Threshold temperature in millicelsius.
+- rockchip,low-temp-adjust-volt: The property is an array of 3-tuples items, and
+                       each item consists of frequency and voltage like
+                       <min-freq max-freq volt>. This allows to change voltage
+                       according to different frequencice at low temperature.
+- rockchip,low-temp-min-volt: The minimum voltage of regulator at low temperature.
+- rockchip,high-temp: Threshold temperature in millicelsius.
+- rockchip,high-temp-max-volt: The maximum voltage of regulator at high temperature.
+- rockchip,high-temp-max-freq: The maximum frequency of clock at high temperature.
+- rockchip,temp-freq-table: The property is an array of 2-tuples items, and each
+                       item consists of temperature and frequency like
+                       <min-temp max-freq>. This allows to change the max
+                       frequency according to temperature.
+- rockchip,high-temp-limit-table: Similar to 'rockchip,temp-freq-table', but
+                       it's discarded.
+
+- rockchip,early-min-microvolt: Voltage in uV, this allows to limit the minimum
+                       voltage of regulator when start up.
+
+- rockchip,video-4k-freq: Clock frequency in KHz, change to the frequency when
+                       enter SYS_STATUS_VIDEO_4K status.
+- rockchip,reboot-freq: Clock frequency in KHz, change to the frequency when
+                       reboot.
+
+- rockchip,avs-enable: Similar to 'rockchip,avs', but it's discarded.
+- rockchip,avs: Indicates avs is enabled.
+- rockchip,avs-scale: The minimum scale of avs.
+- clocks: PLL clock, it's used to get avs frequency and avs scale.
+
+- mbist-vmin: The minimum voltage of memory, this allows to adjust opp voltage
+                       according to mbist in otp.
+
+Examples:
+
+cpus {
+	cpu@0 {
+		operating-points-v2 = <&cluster0_opp>;
+	};
+}
+
+cluster0_opp: opp_table0 {
+	compatible = "operating-points-v2";
+	opp-shared;
+
+	rockchip,leakage-voltage-sel = <
+		1   24   0
+		25  254  1
+	>;
+	nvmem-cells = <&cpu_leakage>;
+	nvmem-cell-names = "leakage";
+
+	opp@216000000 {
+		opp-hz = /bits/ 64 <216000000>;
+		opp-microvolt = <950000 950000 1350000>;
+		opp-microvolt-L0 = <1050000 1050000 1350000>;
+		opp-microvolt-L1 = <950000 950000 1350000>;
+		opp-suspend;
+	}
+};
diff --git a/kernel/Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb2-phy.yaml b/kernel/Documentation/devicetree/bindings/phy/amlogic,g12a-usb2-phy.yaml
similarity index 85%
rename from kernel/Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb2-phy.yaml
rename to kernel/Documentation/devicetree/bindings/phy/amlogic,g12a-usb2-phy.yaml
index 399ebde..ff86c87 100644
--- a/kernel/Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb2-phy.yaml
+++ b/kernel/Documentation/devicetree/bindings/phy/amlogic,g12a-usb2-phy.yaml
@@ -2,7 +2,7 @@
 # Copyright 2019 BayLibre, SAS
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/phy/amlogic,meson-g12a-usb2-phy.yaml#"
+$id: "http://devicetree.org/schemas/phy/amlogic,g12a-usb2-phy.yaml#"
 $schema: "http://devicetree.org/meta-schemas/core.yaml#"
 
 title: Amlogic G12A USB2 PHY
@@ -13,8 +13,8 @@
 properties:
   compatible:
     enum:
-      - amlogic,meson-g12a-usb2-phy
-      - amlogic,meson-a1-usb2-phy
+      - amlogic,g12a-usb2-phy
+      - amlogic,a1-usb2-phy
 
   reg:
     maxItems: 1
@@ -68,7 +68,7 @@
 examples:
   - |
     phy@36000 {
-          compatible = "amlogic,meson-g12a-usb2-phy";
+          compatible = "amlogic,g12a-usb2-phy";
           reg = <0x36000 0x2000>;
           clocks = <&xtal>;
           clock-names = "xtal";
diff --git a/kernel/Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml b/kernel/Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml
similarity index 82%
rename from kernel/Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml
rename to kernel/Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml
index 453c083..8473864 100644
--- a/kernel/Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml
+++ b/kernel/Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml
@@ -2,7 +2,7 @@
 # Copyright 2019 BayLibre, SAS
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml#"
+$id: "http://devicetree.org/schemas/phy/amlogic,g12a-usb3-pcie-phy.yaml#"
 $schema: "http://devicetree.org/meta-schemas/core.yaml#"
 
 title: Amlogic G12A USB3 + PCIE Combo PHY
@@ -13,7 +13,7 @@
 properties:
   compatible:
     enum:
-      - amlogic,meson-g12a-usb3-pcie-phy
+      - amlogic,g12a-usb3-pcie-phy
 
   reg:
     maxItems: 1
@@ -49,7 +49,7 @@
 examples:
   - |
     phy@46000 {
-          compatible = "amlogic,meson-g12a-usb3-pcie-phy";
+          compatible = "amlogic,g12a-usb3-pcie-phy";
           reg = <0x46000 0x2000>;
           clocks = <&ref_clk>;
           clock-names = "ref_clk";
diff --git a/kernel/Documentation/devicetree/bindings/power/rockchip-cpu-avs.txt b/kernel/Documentation/devicetree/bindings/power/rockchip-cpu-avs.txt
deleted file mode 100644
index 25ba862..0000000
--- a/kernel/Documentation/devicetree/bindings/power/rockchip-cpu-avs.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-Rockchip cpu avs device tree bindings
--------------------------------------
-
-Under the same frequency, the operating voltage tends to decrease with
-increasing leakage. so it is necessary to adjust opp's voltage according
-to leakage for power.
-
-
-Required properties:
-- cluster-id: At runtime, the platform can find a cpu's cluster_id
-  according to it's cpu_id and match cluster-id property.
-- min-volt: The minimum voltage in uV. Even though opp's voltage will be
-  adjusted, it must be bigger than or equal to the minimum.
-- min-freq: The minimum frequency in KHz. If an opp's frequency is bigger
-  than or equal to the minimum, its volatge will be adjusted.
-- leakage-adjust-volt: The property is an array of 3-tuples items, and
-  each item consists of leakage and voltage like
-  <min-leakage-mA max-leakage-mA volt-uV>.
-	min-leakage: minimum leakage in mA, ranges from 0 to 254.
-	max-leakage: maximum leakage in mA, ranges from 0 to 254.
-	volt: voltage offset in uV to apply to the opp table entries.
-- nvmem-cells: A phandle to the leakage data provided by efuse.
-- nvmem-cell-names: Should be "cpu_leakage".
-
-Example:
-
-	cpu_avs: cpu-avs {
-		cluster0-avs {
-			cluster-id = <0>;
-			min-volt = <800000>; /* uV */
-			min-freq = <408000>; /* KHz */
-			leakage-adjust-volt = <
-			/*  mA        mA         uV */
-			    0         254        0
-			>;
-			nvmem-cells = <&cpul_leakage>;
-			nvmem-cell-names = "cpu_leakage";
-		};
-		cluster1-avs {
-			cluster-id = <1>;
-			min-volt = <800000>; /* uV */
-			min-freq = <408000>; /* KHz */
-			leakage-adjust-volt = <
-			/*  mA        mA         uV */
-			    0         254        0
-			>;
-			nvmem-cells = <&cpub_leakage>;
-			nvmem-cell-names = "cpu_leakage";
-		};
-	};
diff --git a/kernel/Documentation/devicetree/bindings/serial/renesas,scif.yaml b/kernel/Documentation/devicetree/bindings/serial/renesas,scif.yaml
index eda3d2c..dbaa043 100644
--- a/kernel/Documentation/devicetree/bindings/serial/renesas,scif.yaml
+++ b/kernel/Documentation/devicetree/bindings/serial/renesas,scif.yaml
@@ -74,7 +74,7 @@
           - description: Error interrupt
           - description: Receive buffer full interrupt
           - description: Transmit buffer empty interrupt
-          - description: Transmit End interrupt
+          - description: Break interrupt
       - items:
           - description: Error interrupt
           - description: Receive buffer full interrupt
@@ -89,7 +89,7 @@
           - const: eri
           - const: rxi
           - const: txi
-          - const: tei
+          - const: bri
       - items:
           - const: eri
           - const: rxi
diff --git a/kernel/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt b/kernel/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
index 9d9652e..ef7c2d4 100644
--- a/kernel/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
+++ b/kernel/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
@@ -18,6 +18,7 @@
 	"rockchip,rk3366-power-controller" - for RK3366 SoCs.
 	"rockchip,rk3368-power-controller" - for RK3368 SoCs.
 	"rockchip,rk3399-power-controller" - for RK3399 SoCs.
+	"rockchip,rk3562-power-controller" - for RK3562 SoCs.
 	"rockchip,rk3568-power-controller" - for RK3568 SoCs.
 - #power-domain-cells: Number of cells in a power-domain specifier.
 	Should be 1 for multiple PM domains.
@@ -39,6 +40,7 @@
 	"include/dt-bindings/power/rk3366-power.h" - for RK3366 type power domain.
 	"include/dt-bindings/power/rk3368-power.h" - for RK3368 type power domain.
 	"include/dt-bindings/power/rk3399-power.h" - for RK3399 type power domain.
+	"include/dt-bindings/power/rk3562-power.h" - for RK3562 type power domain.
 	"include/dt-bindings/power/rk3568-power.h" - for RK3568 type power domain.
 - clocks (optional): phandles to clocks which need to be enabled while power domain
 	switches state.
@@ -50,6 +52,14 @@
 	qos_gpu: qos_gpu@ffaf0000 {
 		compatible ="syscon";
 		reg = <0x0 0xffaf0000 0x0 0x20>;
+		priority-init = <0x202>;
+	};
+
+Shaping Example:
+	shaping_gpu: shaping@fee30088 {
+		compatible = "syscon";
+		reg = <0x0 0xfee30088 0x0 0x4>;
+		shaping-init = <0xff>;
 	};
 
 Example:
@@ -64,6 +74,7 @@
 			reg = <RK3288_PD_GPU>;
 			clocks = <&cru ACLK_GPU>;
 			pm_qos = <&qos_gpu>;
+			pm_shaping = <&shaping_gpu>;
 		};
 	};
 
@@ -122,6 +133,7 @@
 	"include/dt-bindings/power/rk3366-power.h" - for rk3366 type power domain.
 	"include/dt-bindings/power/rk3368-power.h" - for rk3368 type power domain.
 	"include/dt-bindings/power/rk3399-power.h" - for rk3399 type power domain.
+	"include/dt-bindings/power/rk3562-power.h" - for rk3562 type power domain.
 	"include/dt-bindings/power/rk3568-power.h" - for rk3568 type power domain.
 
 Example of the node using power domain:
diff --git a/kernel/Documentation/devicetree/bindings/soc/rockchip/rockchip-pm-config.txt b/kernel/Documentation/devicetree/bindings/soc/rockchip/rockchip-pm-config.txt
index 717b59b..4ca44e4 100644
--- a/kernel/Documentation/devicetree/bindings/soc/rockchip/rockchip-pm-config.txt
+++ b/kernel/Documentation/devicetree/bindings/soc/rockchip/rockchip-pm-config.txt
@@ -2,6 +2,7 @@
 
 Required properties:
 - compatible: Should be one of the following.
+- "rockchip,pm-config" - for ROCKCHIP SOCs.
 - "rockchip,pm-px30" - for PX30 SOCs.
 - "rockchip,pm-rk1808" - for RK1808 SOCs.
 - "rockchip,pm-rk322x" - for RK322x SOCs.
@@ -24,6 +25,28 @@
 
 Example:
 	rockchip_suspend: rockchip-suspend {
+		compatible = "rockchip,pm-config";
+		status = "disabled";
+		rockchip,sleep-debug-en = <0>;
+		rockchip,sleep-mode-config = <
+			(0
+			| RKPM_SLP_ARMOFF
+			| RKPM_SLP_PMU_HW_PLLS_PD
+			| RKPM_SLP_PMU_PMUALIVE_32K
+			| RKPM_SLP_PMU_DIS_OSC
+			| RKPM_SLP_PMIC_LP
+			)
+		>;
+		rockchip,wakeup-config = <
+			(0
+			| RKPM_CLUSTER_WKUP_EN
+			| RKPM_GPIO_WKUP_EN
+			| RKPM_USB_WKUP_EN
+			)
+		>;
+	};
+
+	rockchip_suspend: rockchip-suspend {
 		compatible = "rockchip,pm-px30";
 		status = "disabled";
 		rockchip,sleep-debug-en = <0>;
diff --git a/kernel/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml b/kernel/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
index 2e35aea..89e3819 100644
--- a/kernel/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
+++ b/kernel/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
@@ -61,7 +61,7 @@
         description: phandle of the CPU DAI
 
     patternProperties:
-      "^codec-[0-9]+$":
+      "^codec(-[0-9]+)?$":
         type: object
         description: |-
           Codecs:
diff --git a/kernel/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt b/kernel/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt
index 5d6ea66..1f75fee 100644
--- a/kernel/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt
+++ b/kernel/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt
@@ -109,7 +109,7 @@
 	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>,
diff --git a/kernel/Documentation/devicetree/bindings/sound/tas2562.yaml b/kernel/Documentation/devicetree/bindings/sound/tas2562.yaml
index 27f7132..6ccb346 100644
--- a/kernel/Documentation/devicetree/bindings/sound/tas2562.yaml
+++ b/kernel/Documentation/devicetree/bindings/sound/tas2562.yaml
@@ -50,7 +50,9 @@
     description: TDM TX current sense time slot.
 
   '#sound-dai-cells':
-    const: 1
+    # The codec has a single DAI, the #sound-dai-cells=<1>; case is left in for backward
+    # compatibility but is deprecated.
+    enum: [0, 1]
 
 required:
   - compatible
@@ -67,7 +69,7 @@
      codec: codec@4c {
        compatible = "ti,tas2562";
        reg = <0x4c>;
-       #sound-dai-cells = <1>;
+       #sound-dai-cells = <0>;
        interrupt-parent = <&gpio1>;
        interrupts = <14>;
        shutdown-gpios = <&gpio1 15 0>;
diff --git a/kernel/Documentation/devicetree/bindings/sound/tas2764.yaml b/kernel/Documentation/devicetree/bindings/sound/tas2764.yaml
index 5bf8c76..1ffe1a0 100644
--- a/kernel/Documentation/devicetree/bindings/sound/tas2764.yaml
+++ b/kernel/Documentation/devicetree/bindings/sound/tas2764.yaml
@@ -46,7 +46,9 @@
     description: TDM TX voltage sense time slot.
 
   '#sound-dai-cells':
-    const: 1
+    # The codec has a single DAI, the #sound-dai-cells=<1>; case is left in for backward
+    # compatibility but is deprecated.
+    enum: [0, 1]
 
 required:
   - compatible
@@ -63,7 +65,7 @@
      codec: codec@38 {
        compatible = "ti,tas2764";
        reg = <0x38>;
-       #sound-dai-cells = <1>;
+       #sound-dai-cells = <0>;
        interrupt-parent = <&gpio1>;
        interrupts = <14>;
        reset-gpios = <&gpio1 15 0>;
diff --git a/kernel/Documentation/devicetree/bindings/sound/tas2770.yaml b/kernel/Documentation/devicetree/bindings/sound/tas2770.yaml
index 07e7f99..f3d0ca0 100644
--- a/kernel/Documentation/devicetree/bindings/sound/tas2770.yaml
+++ b/kernel/Documentation/devicetree/bindings/sound/tas2770.yaml
@@ -52,7 +52,9 @@
       - 1 # Falling edge
 
   '#sound-dai-cells':
-    const: 1
+    # The codec has a single DAI, the #sound-dai-cells=<1>; case is left in for backward
+    # compatibility but is deprecated.
+    enum: [0, 1]
 
 required:
   - compatible
@@ -69,7 +71,7 @@
      codec: codec@41 {
        compatible = "ti,tas2770";
        reg = <0x41>;
-       #sound-dai-cells = <1>;
+       #sound-dai-cells = <0>;
        interrupt-parent = <&gpio1>;
        interrupts = <14>;
        reset-gpio = <&gpio1 15 0>;
diff --git a/kernel/Documentation/devicetree/bindings/spi/spi-rockchip-slave.yaml b/kernel/Documentation/devicetree/bindings/spi/spi-rockchip-slave.yaml
new file mode 100644
index 0000000..c5fc1ab
--- /dev/null
+++ b/kernel/Documentation/devicetree/bindings/spi/spi-rockchip-slave.yaml
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clauseyy
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/spi-rockchip-slave.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip SPI Slave Controller
+
+description:
+  The Rockchip SPI Slave controller is used to interface with SPI Master Controller.
+
+allOf:
+  - $ref: "spi-controller.yaml#"
+
+maintainers:
+  - Heiko Stuebner <heiko@sntech.de>
+
+# Everything else is described in the common file
+properties:
+  compatible:
+    oneOf:
+      - const: rockchip,spi-slave
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: transfer-clock
+      - description: peripheral clock
+
+  clock-names:
+    items:
+      - const: spiclk
+      - const: apb_pclk
+      - const: sclk_in
+
+  dmas:
+    items:
+      - description: TX DMA Channel
+      - description: RX DMA Channel
+
+  dma-names:
+    items:
+      - const: tx
+      - const: rx
+
+  rockchip,cs-inactive-disable:
+    description: Add this property to disable the cs inactive interrupt for spi
+      slave.
+    type: boolean
+
+  ready-gpios:
+    description: GPIO spec for the spi slave ready signal.
+    maxItems: 1
+
+  rockchip,autosuspend-delay-ms:
+    default: 0
+    description: Set pm runtime autosuspend value in milliseconds.
+
+  rockchip,sram:
+    description: Specify sram buffer as SPI Slave DMA buffer.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rk3188-cru-common.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    spi0: spi@ff110000 {
+      compatible = "rockchip,spi-slave";
+      reg = <0xff110000 0x1000>;
+      interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+      clocks = <&cru CLK_SPI0>, <&cru PCLK_SPI0>, <&cru SCLK_IN_SPI0>;
+      clock-names = "spiclk", "apb_pclk", "sclk_in";
+      dmas = <&pdma1 11>, <&pdma1 12>;
+      dma-names = "tx", "rx";
+      #address-cells = <1>;
+      #size-cells = <0>;
+      ready-gpios = <&gpio1 RK_PD3 GPIO_ACTIVE_LOW>;
+    };
diff --git a/kernel/Documentation/devicetree/bindings/usb/cdns,usb3.yaml b/kernel/Documentation/devicetree/bindings/usb/cdns,usb3.yaml
index d6af279..703921e 100644
--- a/kernel/Documentation/devicetree/bindings/usb/cdns,usb3.yaml
+++ b/kernel/Documentation/devicetree/bindings/usb/cdns,usb3.yaml
@@ -59,7 +59,7 @@
     description:
       size of memory intended as internal memory for endpoints
       buffers expressed in KB
-    $ref: /schemas/types.yaml#/definitions/uint32
+    $ref: /schemas/types.yaml#/definitions/uint16
 
   cdns,phyrst-a-enable:
     description: Enable resetting of PHY if Rx fail is detected
diff --git a/kernel/Documentation/driver-api/spi.rst b/kernel/Documentation/driver-api/spi.rst
index f64cb66..f288870 100644
--- a/kernel/Documentation/driver-api/spi.rst
+++ b/kernel/Documentation/driver-api/spi.rst
@@ -25,8 +25,8 @@
 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
diff --git a/kernel/Documentation/fault-injection/fault-injection.rst b/kernel/Documentation/fault-injection/fault-injection.rst
index 31ecfe4..47de500 100644
--- a/kernel/Documentation/fault-injection/fault-injection.rst
+++ b/kernel/Documentation/fault-injection/fault-injection.rst
@@ -78,8 +78,8 @@
 
 - /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".
 
 - /sys/kernel/debug/fail*/space:
 
@@ -167,11 +167,13 @@
 	- 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
 ^^^^^^^^^^^
@@ -336,7 +338,7 @@
     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
diff --git a/kernel/Documentation/filesystems/autofs-mount-control.rst b/kernel/Documentation/filesystems/autofs-mount-control.rst
index bf4b511..b5a379d 100644
--- a/kernel/Documentation/filesystems/autofs-mount-control.rst
+++ b/kernel/Documentation/filesystems/autofs-mount-control.rst
@@ -196,7 +196,7 @@
 		    struct args_ismountpoint	ismountpoint;
 	    };
 
-	    char path[0];
+	    char path[];
     };
 
 The ioctlfd field is a mount point file descriptor of an autofs mount
diff --git a/kernel/Documentation/filesystems/autofs.rst b/kernel/Documentation/filesystems/autofs.rst
index 681c6a4..1b49576 100644
--- a/kernel/Documentation/filesystems/autofs.rst
+++ b/kernel/Documentation/filesystems/autofs.rst
@@ -467,7 +467,7 @@
 			struct args_ismountpoint	ismountpoint;
 		};
 
-                char path[0];
+                char path[];
         };
 
 For the **OPEN_MOUNT** and **IS_MOUNTPOINT** commands, the target
diff --git a/kernel/Documentation/filesystems/directory-locking.rst b/kernel/Documentation/filesystems/directory-locking.rst
index 504ba94..dccd61c 100644
--- a/kernel/Documentation/filesystems/directory-locking.rst
+++ b/kernel/Documentation/filesystems/directory-locking.rst
@@ -22,12 +22,11 @@
 3) object removal.  Locking rules: caller locks parent, finds victim,
 locks victim and calls the method.  Locks are exclusive.
 
-4) rename() that is _not_ cross-directory.  Locking rules: caller locks
-the parent and finds source and target.  In case of exchange (with
-RENAME_EXCHANGE in flags argument) lock both.  In any case,
-if the target already exists, lock it.  If the source is a non-directory,
-lock it.  If we need to lock both, lock them in inode pointer order.
-Then call the method.  All locks are exclusive.
+4) rename() that is _not_ cross-directory.  Locking rules: caller locks the
+parent and finds source and target.  We lock both (provided they exist).  If we
+need to lock two inodes of different type (dir vs non-dir), we lock directory
+first.  If we need to lock two inodes of the same type, lock them in inode
+pointer order.  Then call the method.  All locks are exclusive.
 NB: we might get away with locking the source (and target in exchange
 case) shared.
 
@@ -44,15 +43,17 @@
 rules:
 
 	* lock the filesystem
-	* lock parents in "ancestors first" order.
+	* lock parents in "ancestors first" order. If one is not ancestor of
+	  the other, lock them in inode pointer order.
 	* find source and target.
 	* if old parent is equal to or is a descendent of target
 	  fail with -ENOTEMPTY
 	* if new parent is equal to or is a descendent of source
 	  fail with -ELOOP
-	* If it's an exchange, lock both the source and the target.
-	* If the target exists, lock it.  If the source is a non-directory,
-	  lock it.  If we need to lock both, do so in inode pointer order.
+	* Lock both the source and the target provided they exist. If we
+	  need to lock two inodes of different type (dir vs non-dir), we lock
+	  the directory first. If we need to lock two inodes of the same type,
+	  lock them in inode pointer order.
 	* call the method.
 
 All ->i_rwsem are taken exclusive.  Again, we might get away with locking
@@ -66,8 +67,9 @@
 
 Proof:
 
-	First of all, at any moment we have a partial ordering of the
-	objects - A < B iff A is an ancestor of B.
+	First of all, at any moment we have a linear ordering of the
+	objects - A < B iff (A is an ancestor of B) or (B is not an ancestor
+        of A and ptr(A) < ptr(B)).
 
 	That ordering can change.  However, the following is true:
 
diff --git a/kernel/Documentation/filesystems/incfs.rst b/kernel/Documentation/filesystems/incfs.rst
index 19db303..f0fb1d0 100644
--- a/kernel/Documentation/filesystems/incfs.rst
+++ b/kernel/Documentation/filesystems/incfs.rst
@@ -35,6 +35,9 @@
 /sys/fs/incremental-fs/features/zstd
   Reads 'supported'. Present if zstd compression is supported for data blocks.
 
+/sys/fs/incremental-fs/features/bugfix_throttling
+  Reads 'supported'. Present if the throttling lock bug is fixed
+
 Optional per mount
 ------------------
 
diff --git a/kernel/Documentation/filesystems/vfs.rst b/kernel/Documentation/filesystems/vfs.rst
index ca52c82..f7b69a0 100644
--- a/kernel/Documentation/filesystems/vfs.rst
+++ b/kernel/Documentation/filesystems/vfs.rst
@@ -1188,7 +1188,7 @@
 	return
 	-ECHILD and it will be called again in ref-walk mode.
 
-``_weak_revalidate``
+``d_weak_revalidate``
 	called when the VFS needs to revalidate a "jumped" dentry.  This
 	is called when a path-walk ends at dentry that was not acquired
 	by doing a lookup in the parent directory.  This includes "/",
diff --git a/kernel/Documentation/kernel-hacking/locking.rst b/kernel/Documentation/kernel-hacking/locking.rst
index 6ed806e..a6d89ef 100644
--- a/kernel/Documentation/kernel-hacking/locking.rst
+++ b/kernel/Documentation/kernel-hacking/locking.rst
@@ -1358,7 +1358,7 @@
 Futex API reference
 ===================
 
-.. kernel-doc:: kernel/futex.c
+.. kernel-doc:: kernel/futex/core.c
    :internal:
 
 Further reading
diff --git a/kernel/Documentation/networking/af_xdp.rst b/kernel/Documentation/networking/af_xdp.rst
index 2ccc564..70623cb 100644
--- a/kernel/Documentation/networking/af_xdp.rst
+++ b/kernel/Documentation/networking/af_xdp.rst
@@ -433,6 +433,15 @@
 application to use. The final option is the flags field, but it will
 be dealt with in separate sections for each UMEM flag.
 
+SO_BINDTODEVICE setsockopt
+--------------------------
+
+This is a generic SOL_SOCKET option that can be used to tie AF_XDP
+socket to a particular network interface.  It is useful when a socket
+is created by a privileged process and passed to a non-privileged one.
+Once the option is set, kernel will refuse attempts to bind that socket
+to a different interface.  Updating the value requires CAP_NET_RAW.
+
 XDP_STATISTICS getsockopt
 -------------------------
 
diff --git a/kernel/Documentation/networking/decnet.rst b/kernel/Documentation/networking/decnet.rst
deleted file mode 100644
index b8bc11f..0000000
--- a/kernel/Documentation/networking/decnet.rst
+++ /dev/null
@@ -1,243 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=========================================
-Linux DECnet Networking Layer Information
-=========================================
-
-1. Other documentation....
-==========================
-
-   - Project Home Pages
-     - http://www.chygwyn.com/				   - Kernel info
-     - http://linux-decnet.sourceforge.net/                - Userland tools
-     - http://www.sourceforge.net/projects/linux-decnet/   - Status page
-
-2. Configuring the kernel
-=========================
-
-Be sure to turn on the following options:
-
-    - CONFIG_DECNET (obviously)
-    - CONFIG_PROC_FS (to see what's going on)
-    - CONFIG_SYSCTL (for easy configuration)
-
-if you want to try out router support (not properly debugged yet)
-you'll need the following options as well...
-
-    - CONFIG_DECNET_ROUTER (to be able to add/delete routes)
-    - CONFIG_NETFILTER (will be required for the DECnet routing daemon)
-
-Don't turn on SIOCGIFCONF support for DECnet unless you are really sure
-that you need it, in general you won't and it can cause ifconfig to
-malfunction.
-
-Run time configuration has changed slightly from the 2.4 system. If you
-want to configure an endnode, then the simplified procedure is as follows:
-
- - Set the MAC address on your ethernet card before starting _any_ other
-   network protocols.
-
-As soon as your network card is brought into the UP state, DECnet should
-start working. If you need something more complicated or are unsure how
-to set the MAC address, see the next section. Also all configurations which
-worked with 2.4 will work under 2.5 with no change.
-
-3. Command line options
-=======================
-
-You can set a DECnet address on the kernel command line for compatibility
-with the 2.4 configuration procedure, but in general it's not needed any more.
-If you do st a DECnet address on the command line, it has only one purpose
-which is that its added to the addresses on the loopback device.
-
-With 2.4 kernels, DECnet would only recognise addresses as local if they
-were added to the loopback device. In 2.5, any local interface address
-can be used to loop back to the local machine. Of course this does not
-prevent you adding further addresses to the loopback device if you
-want to.
-
-N.B. Since the address list of an interface determines the addresses for
-which "hello" messages are sent, if you don't set an address on the loopback
-interface then you won't see any entries in /proc/net/neigh for the local
-host until such time as you start a connection. This doesn't affect the
-operation of the local communications in any other way though.
-
-The kernel command line takes options looking like the following::
-
-    decnet.addr=1,2
-
-the two numbers are the node address 1,2 = 1.2 For 2.2.xx kernels
-and early 2.3.xx kernels, you must use a comma when specifying the
-DECnet address like this. For more recent 2.3.xx kernels, you may
-use almost any character except space, although a `.` would be the most
-obvious choice :-)
-
-There used to be a third number specifying the node type. This option
-has gone away in favour of a per interface node type. This is now set
-using /proc/sys/net/decnet/conf/<dev>/forwarding. This file can be
-set with a single digit, 0=EndNode, 1=L1 Router and  2=L2 Router.
-
-There are also equivalent options for modules. The node address can
-also be set through the /proc/sys/net/decnet/ files, as can other system
-parameters.
-
-Currently the only supported devices are ethernet and ip_gre. The
-ethernet address of your ethernet card has to be set according to the DECnet
-address of the node in order for it to be autoconfigured (and then appear in
-/proc/net/decnet_dev). There is a utility available at the above
-FTP sites called dn2ethaddr which can compute the correct ethernet
-address to use. The address can be set by ifconfig either before or
-at the time the device is brought up. If you are using RedHat you can
-add the line::
-
-    MACADDR=AA:00:04:00:03:04
-
-or something similar, to /etc/sysconfig/network-scripts/ifcfg-eth0 or
-wherever your network card's configuration lives. Setting the MAC address
-of your ethernet card to an address starting with "hi-ord" will cause a
-DECnet address which matches to be added to the interface (which you can
-verify with iproute2).
-
-The default device for routing can be set through the /proc filesystem
-by setting /proc/sys/net/decnet/default_device to the
-device you want DECnet to route packets out of when no specific route
-is available. Usually this will be eth0, for example::
-
-    echo -n "eth0" >/proc/sys/net/decnet/default_device
-
-If you don't set the default device, then it will default to the first
-ethernet card which has been autoconfigured as described above. You can
-confirm that by looking in the default_device file of course.
-
-There is a list of what the other files under /proc/sys/net/decnet/ do
-on the kernel patch web site (shown above).
-
-4. Run time kernel configuration
-================================
-
-
-This is either done through the sysctl/proc interface (see the kernel web
-pages for details on what the various options do) or through the iproute2
-package in the same way as IPv4/6 configuration is performed.
-
-Documentation for iproute2 is included with the package, although there is
-as yet no specific section on DECnet, most of the features apply to both
-IP and DECnet, albeit with DECnet addresses instead of IP addresses and
-a reduced functionality.
-
-If you want to configure a DECnet router you'll need the iproute2 package
-since its the _only_ way to add and delete routes currently. Eventually
-there will be a routing daemon to send and receive routing messages for
-each interface and update the kernel routing tables accordingly. The
-routing daemon will use netfilter to listen to routing packets, and
-rtnetlink to update the kernels routing tables.
-
-The DECnet raw socket layer has been removed since it was there purely
-for use by the routing daemon which will now use netfilter (a much cleaner
-and more generic solution) instead.
-
-5. How can I tell if its working?
-=================================
-
-Here is a quick guide of what to look for in order to know if your DECnet
-kernel subsystem is working.
-
-   - Is the node address set (see /proc/sys/net/decnet/node_address)
-   - Is the node of the correct type
-     (see /proc/sys/net/decnet/conf/<dev>/forwarding)
-   - Is the Ethernet MAC address of each Ethernet card set to match
-     the DECnet address. If in doubt use the dn2ethaddr utility available
-     at the ftp archive.
-   - If the previous two steps are satisfied, and the Ethernet card is up,
-     you should find that it is listed in /proc/net/decnet_dev and also
-     that it appears as a directory in /proc/sys/net/decnet/conf/. The
-     loopback device (lo) should also appear and is required to communicate
-     within a node.
-   - If you have any DECnet routers on your network, they should appear
-     in /proc/net/decnet_neigh, otherwise this file will only contain the
-     entry for the node itself (if it doesn't check to see if lo is up).
-   - If you want to send to any node which is not listed in the
-     /proc/net/decnet_neigh file, you'll need to set the default device
-     to point to an Ethernet card with connection to a router. This is
-     again done with the /proc/sys/net/decnet/default_device file.
-   - Try starting a simple server and client, like the dnping/dnmirror
-     over the loopback interface. With luck they should communicate.
-     For this step and those after, you'll need the DECnet library
-     which can be obtained from the above ftp sites as well as the
-     actual utilities themselves.
-   - If this seems to work, then try talking to a node on your local
-     network, and see if you can obtain the same results.
-   - At this point you are on your own... :-)
-
-6. How to send a bug report
-===========================
-
-If you've found a bug and want to report it, then there are several things
-you can do to help me work out exactly what it is that is wrong. Useful
-information (_most_ of which _is_ _essential_) includes:
-
- - What kernel version are you running ?
- - What version of the patch are you running ?
- - How far though the above set of tests can you get ?
- - What is in the /proc/decnet* files and /proc/sys/net/decnet/* files ?
- - Which services are you running ?
- - Which client caused the problem ?
- - How much data was being transferred ?
- - Was the network congested ?
- - How can the problem be reproduced ?
- - Can you use tcpdump to get a trace ? (N.B. Most (all?) versions of
-   tcpdump don't understand how to dump DECnet properly, so including
-   the hex listing of the packet contents is _essential_, usually the -x flag.
-   You may also need to increase the length grabbed with the -s flag. The
-   -e flag also provides very useful information (ethernet MAC addresses))
-
-7. MAC FAQ
-==========
-
-A quick FAQ on ethernet MAC addresses to explain how Linux and DECnet
-interact and how to get the best performance from your hardware.
-
-Ethernet cards are designed to normally only pass received network frames
-to a host computer when they are addressed to it, or to the broadcast address.
-
-Linux has an interface which allows the setting of extra addresses for
-an ethernet card to listen to. If the ethernet card supports it, the
-filtering operation will be done in hardware, if not the extra unwanted packets
-received will be discarded by the host computer. In the latter case,
-significant processor time and bus bandwidth can be used up on a busy
-network (see the NAPI documentation for a longer explanation of these
-effects).
-
-DECnet makes use of this interface to allow running DECnet on an ethernet
-card which has already been configured using TCP/IP (presumably using the
-built in MAC address of the card, as usual) and/or to allow multiple DECnet
-addresses on each physical interface. If you do this, be aware that if your
-ethernet card doesn't support perfect hashing in its MAC address filter
-then your computer will be doing more work than required. Some cards
-will simply set themselves into promiscuous mode in order to receive
-packets from the DECnet specified addresses. So if you have one of these
-cards its better to set the MAC address of the card as described above
-to gain the best efficiency. Better still is to use a card which supports
-NAPI as well.
-
-
-8. Mailing list
-===============
-
-If you are keen to get involved in development, or want to ask questions
-about configuration, or even just report bugs, then there is a mailing
-list that you can join, details are at:
-
-http://sourceforge.net/mail/?group_id=4993
-
-9. Legal Info
-=============
-
-The Linux DECnet project team have placed their code under the GPL. The
-software is provided "as is" and without warranty express or implied.
-DECnet is a trademark of Compaq. This software is not a product of
-Compaq. We acknowledge the help of people at Compaq in providing extra
-documentation above and beyond what was previously publicly available.
-
-Steve Whitehouse <SteveW@ACM.org>
-
diff --git a/kernel/Documentation/networking/index.rst b/kernel/Documentation/networking/index.rst
index 63ef386..9fab919 100644
--- a/kernel/Documentation/networking/index.rst
+++ b/kernel/Documentation/networking/index.rst
@@ -46,7 +46,6 @@
    cdc_mbim
    dccp
    dctcp
-   decnet
    dns_resolver
    driver
    eql
diff --git a/kernel/Documentation/powerpc/associativity.rst b/kernel/Documentation/powerpc/associativity.rst
new file mode 100644
index 0000000..4d01c73
--- /dev/null
+++ b/kernel/Documentation/powerpc/associativity.rst
@@ -0,0 +1,105 @@
+============================
+NUMA resource associativity
+============================
+
+Associativity represents the groupings of the various platform resources into
+domains of substantially similar mean performance relative to resources outside
+of that domain. Resources subsets of a given domain that exhibit better
+performance relative to each other than relative to other resources subsets
+are represented as being members of a sub-grouping domain. This performance
+characteristic is presented in terms of NUMA node distance within the Linux kernel.
+From the platform view, these groups are also referred to as domains.
+
+PAPR interface currently supports different ways of communicating these resource
+grouping details to the OS. These are referred to as Form 0, Form 1 and Form2
+associativity grouping. Form 0 is the oldest format and is now considered deprecated.
+
+Hypervisor indicates the type/form of associativity used via "ibm,architecture-vec-5 property".
+Bit 0 of byte 5 in the "ibm,architecture-vec-5" property indicates usage of Form 0 or Form 1.
+A value of 1 indicates the usage of Form 1 associativity. For Form 2 associativity
+bit 2 of byte 5 in the "ibm,architecture-vec-5" property is used.
+
+Form 0
+------
+Form 0 associativity supports only two NUMA distances (LOCAL and REMOTE).
+
+Form 1
+------
+With Form 1 a combination of ibm,associativity-reference-points, and ibm,associativity
+device tree properties are used to determine the NUMA distance between resource groups/domains.
+
+The “ibm,associativity” property contains a list of one or more numbers (domainID)
+representing the resource’s platform grouping domains.
+
+The “ibm,associativity-reference-points” property contains a list of one or more numbers
+(domainID index) that represents the 1 based ordinal in the associativity lists.
+The list of domainID indexes represents an increasing hierarchy of resource grouping.
+
+ex:
+{ primary domainID index, secondary domainID index, tertiary domainID index.. }
+
+Linux kernel uses the domainID at the primary domainID index as the NUMA node id.
+Linux kernel computes NUMA distance between two domains by recursively comparing
+if they belong to the same higher-level domains. For mismatch at every higher
+level of the resource group, the kernel doubles the NUMA distance between the
+comparing domains.
+
+Form 2
+-------
+Form 2 associativity format adds separate device tree properties representing NUMA node distance
+thereby making the node distance computation flexible. Form 2 also allows flexible primary
+domain numbering. With numa distance computation now detached from the index value in
+"ibm,associativity-reference-points" property, Form 2 allows a large number of primary domain
+ids at the same domainID index representing resource groups of different performance/latency
+characteristics.
+
+Hypervisor indicates the usage of FORM2 associativity using bit 2 of byte 5 in the
+"ibm,architecture-vec-5" property.
+
+"ibm,numa-lookup-index-table" property contains a list of one or more numbers representing
+the domainIDs present in the system. The offset of the domainID in this property is
+used as an index while computing numa distance information via "ibm,numa-distance-table".
+
+prop-encoded-array: The number N of the domainIDs encoded as with encode-int, followed by
+N domainID encoded as with encode-int
+
+For ex:
+"ibm,numa-lookup-index-table" =  {4, 0, 8, 250, 252}. The offset of domainID 8 (2) is used when
+computing the distance of domain 8 from other domains present in the system. For the rest of
+this document, this offset will be referred to as domain distance offset.
+
+"ibm,numa-distance-table" property contains a list of one or more numbers representing the NUMA
+distance between resource groups/domains present in the system.
+
+prop-encoded-array: The number N of the distance values encoded as with encode-int, followed by
+N distance values encoded as with encode-bytes. The max distance value we could encode is 255.
+The number N must be equal to the square of m where m is the number of domainIDs in the
+numa-lookup-index-table.
+
+For ex:
+ibm,numa-lookup-index-table = <3 0 8 40>;
+ibm,numa-distace-table = <9>, /bits/ 8 < 10  20  80 20  10 160 80 160  10>;
+
+::
+
+	  | 0    8   40
+	--|------------
+	  |
+	0 | 10   20  80
+	  |
+	8 | 20   10  160
+	  |
+	40| 80   160  10
+
+A possible "ibm,associativity" property for resources in node 0, 8 and 40
+
+{ 3, 6, 7, 0 }
+{ 3, 6, 9, 8 }
+{ 3, 6, 7, 40}
+
+With "ibm,associativity-reference-points"  { 0x3 }
+
+"ibm,lookup-index-table" helps in having a compact representation of distance matrix.
+Since domainID can be sparse, the matrix of distances can also be effectively sparse.
+With "ibm,lookup-index-table" we can achieve a compact representation of
+distance information.
diff --git a/kernel/Documentation/powerpc/index.rst b/kernel/Documentation/powerpc/index.rst
index 6ec64b0..4663b72 100644
--- a/kernel/Documentation/powerpc/index.rst
+++ b/kernel/Documentation/powerpc/index.rst
@@ -7,6 +7,7 @@
 .. toctree::
     :maxdepth: 1
 
+    associativity
     booting
     bootwrapper
     cpu_families
diff --git a/kernel/Documentation/scsi/scsi_mid_low_api.rst b/kernel/Documentation/scsi/scsi_mid_low_api.rst
index 5bc17d0..d65c902 100644
--- a/kernel/Documentation/scsi/scsi_mid_low_api.rst
+++ b/kernel/Documentation/scsi/scsi_mid_low_api.rst
@@ -1195,11 +1195,11 @@
 		 - pointer to scsi_device object that this command is
                    associated with.
     resid
-		 - an LLD should set this signed integer to the requested
+		 - an LLD should set this unsigned integer to the requested
                    transfer length (i.e. 'request_bufflen') less the number
                    of bytes that are actually transferred. 'resid' is
                    preset to 0 so an LLD can ignore it if it cannot detect
-                   underruns (overruns should be rare). If possible an LLD
+                   underruns (overruns should not be reported). An LLD
                    should set 'resid' prior to invoking 'done'. The most
                    interesting case is data transfers from a SCSI target
                    device (e.g. READs) that underrun.
diff --git a/kernel/Documentation/sound/hd-audio/models.rst b/kernel/Documentation/sound/hd-audio/models.rst
index 9b52f50..1204304 100644
--- a/kernel/Documentation/sound/hd-audio/models.rst
+++ b/kernel/Documentation/sound/hd-audio/models.rst
@@ -704,7 +704,7 @@
 no-jd
     BIOS setup but without jack-detection
 intel
-    Intel DG45* mobos
+    Intel D*45* mobos
 dell-m6-amic
     Dell desktops/laptops with analog mics
 dell-m6-dmic
diff --git a/kernel/Documentation/sphinx/load_config.py b/kernel/Documentation/sphinx/load_config.py
index eeb394b..8b416bf 100644
--- a/kernel/Documentation/sphinx/load_config.py
+++ b/kernel/Documentation/sphinx/load_config.py
@@ -3,7 +3,7 @@
 
 import os
 import sys
-from sphinx.util.pycompat import execfile_
+from sphinx.util.osutil import fs_encoding
 
 # ------------------------------------------------------------------------------
 def loadConfig(namespace):
@@ -48,7 +48,9 @@
             sys.stdout.write("load additional sphinx-config: %s\n" % config_file)
             config = namespace.copy()
             config['__file__'] = config_file
-            execfile_(config_file, config)
+            with open(config_file, 'rb') as f:
+                code = compile(f.read(), fs_encoding, 'exec')
+                exec(code, config)
             del config['__file__']
             namespace.update(config)
         else:
diff --git a/kernel/Documentation/trace/ftrace.rst b/kernel/Documentation/trace/ftrace.rst
index 34a3b84..ecca086 100644
--- a/kernel/Documentation/trace/ftrace.rst
+++ b/kernel/Documentation/trace/ftrace.rst
@@ -2926,7 +2926,7 @@
               bash-1994  [000] ....  4342.324898: ima_get_action <-process_measurement
               bash-1994  [000] ....  4342.324898: ima_match_policy <-ima_get_action
               bash-1994  [000] ....  4342.324899: do_truncate <-do_last
-              bash-1994  [000] ....  4342.324899: should_remove_suid <-do_truncate
+              bash-1994  [000] ....  4342.324899: setattr_should_drop_suidgid <-do_truncate
               bash-1994  [000] ....  4342.324899: notify_change <-do_truncate
               bash-1994  [000] ....  4342.324900: current_fs_time <-notify_change
               bash-1994  [000] ....  4342.324900: current_kernel_time <-current_fs_time
diff --git a/kernel/Documentation/translations/it_IT/kernel-hacking/locking.rst b/kernel/Documentation/translations/it_IT/kernel-hacking/locking.rst
index bf1acd6..192ab8e 100644
--- a/kernel/Documentation/translations/it_IT/kernel-hacking/locking.rst
+++ b/kernel/Documentation/translations/it_IT/kernel-hacking/locking.rst
@@ -1400,7 +1400,7 @@
 Riferimento per l'API dei Futex
 ===============================
 
-.. kernel-doc:: kernel/futex.c
+.. kernel-doc:: kernel/futex/core.c
    :internal:
 
 Approfondimenti
diff --git a/kernel/Documentation/userspace-api/ioctl/ioctl-number.rst b/kernel/Documentation/userspace-api/ioctl/ioctl-number.rst
index 55a2d9b..a7373d4 100644
--- a/kernel/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/kernel/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -303,7 +303,6 @@
 0x89  00-06  arch/x86/include/asm/sockios.h
 0x89  0B-DF  linux/sockios.h
 0x89  E0-EF  linux/sockios.h                                         SIOCPROTOPRIVATE range
-0x89  E0-EF  linux/dn.h                                              PROTOPRIVATE range
 0x89  F0-FF  linux/sockios.h                                         SIOCDEVPRIVATE range
 0x8B  all    linux/wireless.h
 0x8C  00-3F                                                          WiNRADiO driver
diff --git a/kernel/Documentation/virt/kvm/api.rst b/kernel/Documentation/virt/kvm/api.rst
index 88a1441..1d319bd 100644
--- a/kernel/Documentation/virt/kvm/api.rst
+++ b/kernel/Documentation/virt/kvm/api.rst
@@ -4036,6 +4036,18 @@
 :Parameters: struct kvm_s390_cmma_log (in, out)
 :Returns: 0 on success, a negative value on error
 
+Errors:
+
+  ======     =============================================================
+  ENOMEM     not enough memory can be allocated to complete the task
+  ENXIO      if CMMA is not enabled
+  EINVAL     if KVM_S390_CMMA_PEEK is not set but migration mode was not enabled
+  EINVAL     if KVM_S390_CMMA_PEEK is not set but dirty tracking has been
+             disabled (and thus migration mode was automatically disabled)
+  EFAULT     if the userspace address is invalid or if no page table is
+             present for the addresses (e.g. when using hugepages).
+  ======     =============================================================
+
 This ioctl is used to get the values of the CMMA bits on the s390
 architecture. It is meant to be used in two scenarios:
 
@@ -4115,12 +4127,6 @@
 mask is unused.
 
 values points to the userspace buffer where the result will be stored.
-
-This ioctl can fail with -ENOMEM if not enough memory can be allocated to
-complete the task, with -ENXIO if CMMA is not enabled, with -EINVAL if
-KVM_S390_CMMA_PEEK is not set but migration mode was not enabled, with
--EFAULT if the userspace address is invalid or if no page table is
-present for the addresses (e.g. when using hugepages).
 
 4.108 KVM_S390_SET_CMMA_BITS
 ----------------------------
@@ -6403,3 +6409,63 @@
 guest according to the bits in the KVM_CPUID_FEATURES CPUID leaf
 (0x40000001). Otherwise, a guest may use the paravirtual features
 regardless of what has actually been exposed through the CPUID leaf.
+
+9. Known KVM API problems
+=========================
+
+In some cases, KVM's API has some inconsistencies or common pitfalls
+that userspace need to be aware of.  This section details some of
+these issues.
+
+Most of them are architecture specific, so the section is split by
+architecture.
+
+9.1. x86
+--------
+
+``KVM_GET_SUPPORTED_CPUID`` issues
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In general, ``KVM_GET_SUPPORTED_CPUID`` is designed so that it is possible
+to take its result and pass it directly to ``KVM_SET_CPUID2``.  This section
+documents some cases in which that requires some care.
+
+Local APIC features
+~~~~~~~~~~~~~~~~~~~
+
+CPU[EAX=1]:ECX[21] (X2APIC) is reported by ``KVM_GET_SUPPORTED_CPUID``,
+but it can only be enabled if ``KVM_CREATE_IRQCHIP`` or
+``KVM_ENABLE_CAP(KVM_CAP_IRQCHIP_SPLIT)`` are used to enable in-kernel emulation of
+the local APIC.
+
+The same is true for the ``KVM_FEATURE_PV_UNHALT`` paravirtualized feature.
+
+CPU[EAX=1]:ECX[24] (TSC_DEADLINE) is not reported by ``KVM_GET_SUPPORTED_CPUID``.
+It can be enabled if ``KVM_CAP_TSC_DEADLINE_TIMER`` is present and the kernel
+has enabled in-kernel emulation of the local APIC.
+
+CPU topology
+~~~~~~~~~~~~
+
+Several CPUID values include topology information for the host CPU:
+0x0b and 0x1f for Intel systems, 0x8000001e for AMD systems.  Different
+versions of KVM return different values for this information and userspace
+should not rely on it.  Currently they return all zeroes.
+
+If userspace wishes to set up a guest topology, it should be careful that
+the values of these three leaves differ for each CPU.  In particular,
+the APIC ID is found in EDX for all subleaves of 0x0b and 0x1f, and in EAX
+for 0x8000001e; the latter also encodes the core id and node id in bits
+7:0 of EBX and ECX respectively.
+
+Obsolete ioctls and capabilities
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+KVM_CAP_DISABLE_QUIRKS does not let userspace know which quirks are actually
+available.  Use ``KVM_CHECK_EXTENSION(KVM_CAP_DISABLE_QUIRKS2)`` instead if
+available.
+
+Ordering of KVM_GET_*/KVM_SET_* ioctls
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+TBD
diff --git a/kernel/Documentation/virt/kvm/devices/vm.rst b/kernel/Documentation/virt/kvm/devices/vm.rst
index 60acc39..147efec 100644
--- a/kernel/Documentation/virt/kvm/devices/vm.rst
+++ b/kernel/Documentation/virt/kvm/devices/vm.rst
@@ -302,6 +302,10 @@
 Setting this attribute when migration mode is already active will have
 no effects.
 
+Dirty tracking must be enabled on all memslots, else -EINVAL is returned. When
+dirty tracking is disabled on any memslot, migration mode is automatically
+stopped.
+
 :Parameters: none
 :Returns:   -ENOMEM if there is not enough free memory to start migration mode;
 	    -EINVAL if the state of the VM is invalid (e.g. no memory defined);
diff --git a/kernel/MAINTAINERS b/kernel/MAINTAINERS
index 63a1fdd..fa38656 100644
--- a/kernel/MAINTAINERS
+++ b/kernel/MAINTAINERS
@@ -3001,7 +3001,7 @@
 AUDIT SUBSYSTEM
 M:	Paul Moore <paul@paul-moore.com>
 M:	Eric Paris <eparis@redhat.com>
-L:	linux-audit@redhat.com (moderated for non-subscribers)
+L:	audit@vger.kernel.org
 S:	Supported
 W:	https://github.com/linux-audit
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git
@@ -4904,13 +4904,6 @@
 F:	include/linux/tfrc.h
 F:	include/uapi/linux/dccp.h
 F:	net/dccp/
-
-DECnet NETWORK LAYER
-L:	linux-decnet-user@lists.sourceforge.net
-S:	Orphan
-W:	http://linux-decnet.sourceforge.net
-F:	Documentation/networking/decnet.rst
-F:	net/decnet/
 
 DECSTATION PLATFORM SUPPORT
 M:	"Maciej W. Rozycki" <macro@linux-mips.org>
@@ -7280,7 +7273,7 @@
 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 49d1d03..020e2b6 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 VERSION = 5
 PATCHLEVEL = 10
-SUBLEVEL = 160
+SUBLEVEL = 198
 EXTRAVERSION =
 NAME = Dare mighty things
 
@@ -93,9 +93,16 @@
 
 # If the user is running make -s (silent mode), suppress echoing of
 # commands
+# make-4.0 (and later) keep single letter options in the 1st word of MAKEFLAGS.
 
-ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),)
-  quiet=silent_
+ifeq ($(filter 3.%,$(MAKE_VERSION)),)
+silence:=$(findstring s,$(firstword -$(MAKEFLAGS)))
+else
+silence:=$(findstring s,$(filter-out --%,$(MAKEFLAGS)))
+endif
+
+ifeq ($(silence),s)
+quiet=silent_
 endif
 
 export quiet Q KBUILD_VERBOSE
@@ -597,8 +604,10 @@
 ifneq ($(GCC_TOOLCHAIN),)
 CLANG_FLAGS	+= --gcc-toolchain=$(GCC_TOOLCHAIN)
 endif
-ifneq ($(LLVM_IAS),1)
-CLANG_FLAGS	+= -no-integrated-as
+ifeq ($(LLVM_IAS),1)
+CLANG_FLAGS	+= -fintegrated-as
+else
+CLANG_FLAGS	+= -fno-integrated-as
 endif
 CLANG_FLAGS	+= -Werror=unknown-warning-option
 KBUILD_CFLAGS	+= $(CLANG_FLAGS)
@@ -828,6 +837,10 @@
 KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
 
 KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable)
+
+# These result in bogus false positives
+KBUILD_CFLAGS += $(call cc-disable-warning, dangling-pointer)
+
 ifdef CONFIG_FRAME_POINTER
 KBUILD_CFLAGS	+= -fno-omit-frame-pointer -fno-optimize-sibling-calls
 else
@@ -871,7 +884,7 @@
 DEBUG_CFLAGS	+= -g
 endif
 
-ifeq ($(LLVM_IAS),1)
+ifdef CONFIG_AS_IS_LLVM
 KBUILD_AFLAGS	+= -g
 else
 KBUILD_AFLAGS	+= -Wa,-gdwarf-2
@@ -1519,9 +1532,7 @@
 
 PHONY += modules
 # if KBUILD_BUILTIN && !KBUILD_MIXED_TREE, depend on vmlinux
-modules: $(if $(KBUILD_BUILTIN), $(if $(KBUILD_MIXED_TREE),,vmlinux))
-modules: modules_check modules_prepare
-	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
+modules: $(if $(KBUILD_BUILTIN), $(if $(KBUILD_MIXED_TREE),,vmlinux)) modules_check modules_prepare
 
 PHONY += modules_check
 modules_check: modules.order
@@ -1539,12 +1550,9 @@
 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
@@ -1556,34 +1564,12 @@
 	@sed 's:^:kernel/:' modules.order > $(MODLIB)/modules.order
 	@cp -f $(mixed-build-prefix)modules.builtin $(MODLIB)/
 	@cp -f $(or $(mixed-build-prefix),$(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
 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
 
@@ -1832,25 +1818,8 @@
 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
-
-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
-_emodinst_post: _emodinst_
-	$(call cmd,depmod)
 
 compile_commands.json: $(extmod-prefix)compile_commands.json
 PHONY += compile_commands.json
@@ -1876,6 +1845,41 @@
 
 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) $(mixed-build-prefix)
+
+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
+
+KBUILD_MODULES :=
+
+endif # CONFIG_MODULES
+
 # Single targets
 # ---------------------------------------------------------------------------
 # To build individual files in subdirectories, you can do like this:
@@ -1899,18 +1903,12 @@
 $(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))
 
@@ -1918,10 +1916,6 @@
 build-dirs := $(foreach d, $(build-dirs), \
 			$(if $(filter $(d)/%, $(KBUILD_SINGLE_TARGETS)), $(d)))
 
-endif
-
-ifndef CONFIG_MODULES
-KBUILD_MODULES :=
 endif
 
 # Handle descending into subdirectories listed in $(build-dirs)
@@ -2064,11 +2058,6 @@
 
 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) $(mixed-build-prefix)
 
 # read saved command lines for existing targets
 existing-targets := $(wildcard $(sort $(targets)))
diff --git a/kernel/android/abi_gki_aarch64.xml b/kernel/android/abi_gki_aarch64.xml
index 1bc86e8..2aacb29 100644
--- a/kernel/android/abi_gki_aarch64.xml
+++ b/kernel/android/abi_gki_aarch64.xml
@@ -144,6 +144,7 @@
       <elf-symbol name='__i2c_smbus_xfer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x53eea490'/>
       <elf-symbol name='__i2c_transfer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x74210c6f'/>
       <elf-symbol name='__iio_device_register' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x122a9634'/>
+      <elf-symbol name='__iio_trigger_register' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1b174e36'/>
       <elf-symbol name='__inet6_lookup_established' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1cd4b3ad'/>
       <elf-symbol name='__inet_lookup_established' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc328de8f'/>
       <elf-symbol name='__init_rwsem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf5a94b83'/>
@@ -189,6 +190,7 @@
       <elf-symbol name='__mmc_claim_host' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4a164b4d'/>
       <elf-symbol name='__mmc_send_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x46aa6131'/>
       <elf-symbol name='__mmdrop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2f76d662'/>
+      <elf-symbol name='__mod_lruvec_state' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x123fd4a0'/>
       <elf-symbol name='__mod_node_page_state' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb4f24d4d'/>
       <elf-symbol name='__mod_zone_page_state' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x5104c6ef'/>
       <elf-symbol name='__module_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x96c21ce0'/>
@@ -269,6 +271,7 @@
       <elf-symbol name='__serio_register_port' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x195dc13f'/>
       <elf-symbol name='__set_page_dirty_buffers' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3a13ccf5'/>
       <elf-symbol name='__set_page_dirty_nobuffers' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x13363289'/>
+      <elf-symbol name='__set_page_owner' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x18ed2a68'/>
       <elf-symbol name='__sg_page_iter_dma_next' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xcc445ceb'/>
       <elf-symbol name='__sg_page_iter_next' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7c9ca58f'/>
       <elf-symbol name='__sg_page_iter_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xccd4c999'/>
@@ -306,6 +309,8 @@
       <elf-symbol name='__traceiter_android_rvh_after_enqueue_task' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf3381861'/>
       <elf-symbol name='__traceiter_android_rvh_alloc_si' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x51a6f087'/>
       <elf-symbol name='__traceiter_android_rvh_alloc_swap_slot_cache' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7b025ee7'/>
+      <elf-symbol name='__traceiter_android_rvh_arm64_serror_panic' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe90dfa30'/>
+      <elf-symbol name='__traceiter_android_rvh_bad_mode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3dc2e9e1'/>
       <elf-symbol name='__traceiter_android_rvh_binder_transaction' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf57c4087'/>
       <elf-symbol name='__traceiter_android_rvh_build_perf_domains' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4b4a53af'/>
       <elf-symbol name='__traceiter_android_rvh_can_migrate_task' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x44f6f339'/>
@@ -321,11 +326,15 @@
       <elf-symbol name='__traceiter_android_rvh_dequeue_entity' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1cb584b'/>
       <elf-symbol name='__traceiter_android_rvh_dequeue_task' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8881d31b'/>
       <elf-symbol name='__traceiter_android_rvh_dequeue_task_fair' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x37a9a528'/>
+      <elf-symbol name='__traceiter_android_rvh_dequeue_task_idle' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb69c8270'/>
       <elf-symbol name='__traceiter_android_rvh_die_kernel_fault' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x91f68209'/>
       <elf-symbol name='__traceiter_android_rvh_dma_buf_stats_teardown' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8d429a3c'/>
       <elf-symbol name='__traceiter_android_rvh_do_mem_abort' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x669812d6'/>
+      <elf-symbol name='__traceiter_android_rvh_do_ptrauth_fault' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xed8c3884'/>
       <elf-symbol name='__traceiter_android_rvh_do_sched_yield' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe0fb88e'/>
+      <elf-symbol name='__traceiter_android_rvh_do_sea' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe1b06d02'/>
       <elf-symbol name='__traceiter_android_rvh_do_sp_pc_abort' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x47243dfd'/>
+      <elf-symbol name='__traceiter_android_rvh_do_undefinstr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xace8e825'/>
       <elf-symbol name='__traceiter_android_rvh_drain_slots_cache_cpu' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb13f9ec0'/>
       <elf-symbol name='__traceiter_android_rvh_enqueue_entity' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb0c4e55d'/>
       <elf-symbol name='__traceiter_android_rvh_enqueue_task' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x58dae35a'/>
@@ -356,6 +365,7 @@
       <elf-symbol name='__traceiter_android_rvh_preempt_disable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1585c762'/>
       <elf-symbol name='__traceiter_android_rvh_preempt_enable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3235e37a'/>
       <elf-symbol name='__traceiter_android_rvh_prepare_prio_fork' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3633d247'/>
+      <elf-symbol name='__traceiter_android_rvh_refrigerator' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x811d8704'/>
       <elf-symbol name='__traceiter_android_rvh_replace_next_task_fair' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x58959f85'/>
       <elf-symbol name='__traceiter_android_rvh_report_bug' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x41d4f1c5'/>
       <elf-symbol name='__traceiter_android_rvh_resume_cpus' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb534bb05'/>
@@ -385,6 +395,9 @@
       <elf-symbol name='__traceiter_android_rvh_set_user_nice' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9846879c'/>
       <elf-symbol name='__traceiter_android_rvh_setscheduler' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7f5f9ee2'/>
       <elf-symbol name='__traceiter_android_rvh_show_max_freq' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x92dadd45'/>
+      <elf-symbol name='__traceiter_android_rvh_tcp_recvmsg' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x40c4a5e0'/>
+      <elf-symbol name='__traceiter_android_rvh_tcp_recvmsg_stat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9d00e491'/>
+      <elf-symbol name='__traceiter_android_rvh_tcp_sendmsg_locked' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x46ae6a77'/>
       <elf-symbol name='__traceiter_android_rvh_tick_entry' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xed5a5fe0'/>
       <elf-symbol name='__traceiter_android_rvh_try_to_wake_up' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3e25f11d'/>
       <elf-symbol name='__traceiter_android_rvh_try_to_wake_up_success' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x42380ebc'/>
@@ -392,6 +405,8 @@
       <elf-symbol name='__traceiter_android_rvh_typec_tcpci_chk_contaminant' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x760027e1'/>
       <elf-symbol name='__traceiter_android_rvh_typec_tcpci_get_vbus' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x37614c90'/>
       <elf-symbol name='__traceiter_android_rvh_uclamp_eff_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd727fd8d'/>
+      <elf-symbol name='__traceiter_android_rvh_udp_recvmsg' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa08f1726'/>
+      <elf-symbol name='__traceiter_android_rvh_udp_sendmsg' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe0d327c'/>
       <elf-symbol name='__traceiter_android_rvh_ufs_complete_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x347db806'/>
       <elf-symbol name='__traceiter_android_rvh_ufs_reprogram_all_keys' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xac38cf23'/>
       <elf-symbol name='__traceiter_android_rvh_update_cpu_capacity' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc7020ac9'/>
@@ -402,9 +417,11 @@
       <elf-symbol name='__traceiter_android_rvh_v4l2subdev_set_frame_interval' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xcd8a2711'/>
       <elf-symbol name='__traceiter_android_rvh_v4l2subdev_set_selection' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1a092cf8'/>
       <elf-symbol name='__traceiter_android_rvh_wake_up_new_task' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x198d7179'/>
+      <elf-symbol name='__traceiter_android_vh___cgroup_throttle_swaprate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x455f7944'/>
       <elf-symbol name='__traceiter_android_vh_account_swap_pages' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3ed42b1e'/>
       <elf-symbol name='__traceiter_android_vh_account_task_time' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x5f7a1ebe'/>
       <elf-symbol name='__traceiter_android_vh_add_page_to_lrulist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1fd92753'/>
+      <elf-symbol name='__traceiter_android_vh_add_to_avail_list' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xbd5bd58b'/>
       <elf-symbol name='__traceiter_android_vh_aes_decrypt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb0d1574b'/>
       <elf-symbol name='__traceiter_android_vh_aes_encrypt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6160ff0c'/>
       <elf-symbol name='__traceiter_android_vh_aes_expandkey' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xdc004b58'/>
@@ -451,12 +468,14 @@
       <elf-symbol name='__traceiter_android_vh_check_page_look_around_ref' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1d290d6f'/>
       <elf-symbol name='__traceiter_android_vh_check_uninterruptible_tasks' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xdefaa9d5'/>
       <elf-symbol name='__traceiter_android_vh_check_uninterruptible_tasks_dn' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x886d1e23'/>
+      <elf-symbol name='__traceiter_android_vh_cleanup_old_buffers_bypass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x221ef9d7'/>
       <elf-symbol name='__traceiter_android_vh_clear_mask_adjust' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xcbeb1478'/>
       <elf-symbol name='__traceiter_android_vh_clear_reserved_fmt_fields' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3409706a'/>
       <elf-symbol name='__traceiter_android_vh_cma_alloc_finish' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9f7a01cf'/>
       <elf-symbol name='__traceiter_android_vh_cma_alloc_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x44fcd06e'/>
       <elf-symbol name='__traceiter_android_vh_cma_drain_all_pages_bypass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc098c853'/>
       <elf-symbol name='__traceiter_android_vh_commit_creds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9177823e'/>
+      <elf-symbol name='__traceiter_android_vh_compact_finished' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x585aa39f'/>
       <elf-symbol name='__traceiter_android_vh_count_pswpin' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x23b6bee6'/>
       <elf-symbol name='__traceiter_android_vh_count_pswpout' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x75ef15f9'/>
       <elf-symbol name='__traceiter_android_vh_count_swpout_vm_event' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x102c287e'/>
@@ -470,7 +489,10 @@
       <elf-symbol name='__traceiter_android_vh_cpufreq_target' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x84b3623a'/>
       <elf-symbol name='__traceiter_android_vh_cpuidle_psci_enter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6cbffc19'/>
       <elf-symbol name='__traceiter_android_vh_cpuidle_psci_exit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9e5cd40b'/>
+      <elf-symbol name='__traceiter_android_vh_del_from_avail_list' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x22f91cec'/>
       <elf-symbol name='__traceiter_android_vh_del_page_from_lrulist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe35293fd'/>
+      <elf-symbol name='__traceiter_android_vh_disable_thermal_cooling_stats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3a893f24'/>
+      <elf-symbol name='__traceiter_android_vh_dm_bufio_shrink_scan_bypass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7be804c5'/>
       <elf-symbol name='__traceiter_android_vh_do_futex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xdee6d8f'/>
       <elf-symbol name='__traceiter_android_vh_do_page_trylock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xef9d9d8d'/>
       <elf-symbol name='__traceiter_android_vh_do_send_sig_info' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9d17560f'/>
@@ -479,6 +501,7 @@
       <elf-symbol name='__traceiter_android_vh_drain_all_pages_bypass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe9b2635d'/>
       <elf-symbol name='__traceiter_android_vh_drain_slots_cache_cpu' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3b4c4050'/>
       <elf-symbol name='__traceiter_android_vh_dump_throttled_rt_tasks' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1a34d1a3'/>
+      <elf-symbol name='__traceiter_android_vh_dup_task_struct' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xdcdc594f'/>
       <elf-symbol name='__traceiter_android_vh_em_cpu_energy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd60a0819'/>
       <elf-symbol name='__traceiter_android_vh_enable_thermal_genl_check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc39a1e16'/>
       <elf-symbol name='__traceiter_android_vh_ep_create_wakeup_source' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1e8ed582'/>
@@ -492,6 +515,7 @@
       <elf-symbol name='__traceiter_android_vh_free_pages' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xca1155b7'/>
       <elf-symbol name='__traceiter_android_vh_free_swap_slot' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb403f7cb'/>
       <elf-symbol name='__traceiter_android_vh_free_task' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4e6d4c7'/>
+      <elf-symbol name='__traceiter_android_vh_free_unref_page_bypass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xfaedcda5'/>
       <elf-symbol name='__traceiter_android_vh_freq_qos_add_request' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2337c613'/>
       <elf-symbol name='__traceiter_android_vh_freq_qos_remove_request' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x332e571d'/>
       <elf-symbol name='__traceiter_android_vh_freq_qos_update_request' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe802443d'/>
@@ -513,6 +537,7 @@
       <elf-symbol name='__traceiter_android_vh_gpio_block_read' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xfbb0ca4d'/>
       <elf-symbol name='__traceiter_android_vh_handle_failed_page_trylock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2df34b95'/>
       <elf-symbol name='__traceiter_android_vh_handle_pte_fault_end' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb6feefc7'/>
+      <elf-symbol name='__traceiter_android_vh_handle_tlb_conf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1554e1e6'/>
       <elf-symbol name='__traceiter_android_vh_inactive_is_low' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x500ba3a7'/>
       <elf-symbol name='__traceiter_android_vh_include_reserved_zone' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe1272155'/>
       <elf-symbol name='__traceiter_android_vh_init_swap_info_struct' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x98d473fa'/>
@@ -523,15 +548,19 @@
       <elf-symbol name='__traceiter_android_vh_iommu_setup_dma_ops' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4272ebae'/>
       <elf-symbol name='__traceiter_android_vh_ipi_stop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x250fcbba'/>
       <elf-symbol name='__traceiter_android_vh_ipv6_gen_linklocal_addr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xed05983e'/>
+      <elf-symbol name='__traceiter_android_vh_irqtime_account_process_tick' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe7bd48e9'/>
       <elf-symbol name='__traceiter_android_vh_is_fpsimd_save' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6e9c369e'/>
       <elf-symbol name='__traceiter_android_vh_jiffies_update' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x67d76d04'/>
       <elf-symbol name='__traceiter_android_vh_kfree_skb' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd93a42f0'/>
       <elf-symbol name='__traceiter_android_vh_killed_process' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x879b427f'/>
       <elf-symbol name='__traceiter_android_vh_kmalloc_slab' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7cb30b6'/>
+      <elf-symbol name='__traceiter_android_vh_kvmalloc_node_use_vmalloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3844ae56'/>
       <elf-symbol name='__traceiter_android_vh_logbuf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7e160169'/>
       <elf-symbol name='__traceiter_android_vh_logbuf_pr_cont' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3f999f8c'/>
       <elf-symbol name='__traceiter_android_vh_look_around' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd20d37b7'/>
       <elf-symbol name='__traceiter_android_vh_look_around_migrate_page' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x941f700b'/>
+      <elf-symbol name='__traceiter_android_vh_madvise_cold_or_pageout' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6cc02209'/>
+      <elf-symbol name='__traceiter_android_vh_madvise_cold_or_pageout_abort' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x12f21c5'/>
       <elf-symbol name='__traceiter_android_vh_map_util_freq' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd3e2145e'/>
       <elf-symbol name='__traceiter_android_vh_mark_page_accessed' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd79c0547'/>
       <elf-symbol name='__traceiter_android_vh_media_device_setup_link' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe465b969'/>
@@ -549,11 +578,15 @@
       <elf-symbol name='__traceiter_android_vh_mmc_blk_reset' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xae47a396'/>
       <elf-symbol name='__traceiter_android_vh_mmc_gpio_cd_irqt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x20027843'/>
       <elf-symbol name='__traceiter_android_vh_mmput' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd04683dd'/>
+      <elf-symbol name='__traceiter_android_vh_mutex_can_spin_on_owner' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xea48526a'/>
+      <elf-symbol name='__traceiter_android_vh_mutex_opt_spin_finish' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x63b1abd8'/>
+      <elf-symbol name='__traceiter_android_vh_mutex_opt_spin_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x594e81b5'/>
       <elf-symbol name='__traceiter_android_vh_mutex_unlock_slowpath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7f35aa75'/>
       <elf-symbol name='__traceiter_android_vh_mutex_unlock_slowpath_end' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x436c4a85'/>
       <elf-symbol name='__traceiter_android_vh_mutex_wait_finish' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd86d1cd6'/>
       <elf-symbol name='__traceiter_android_vh_mutex_wait_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x5eedd5ac'/>
       <elf-symbol name='__traceiter_android_vh_of_i2c_get_board_info' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x63d6e3b9'/>
+      <elf-symbol name='__traceiter_android_vh_oom_check_panic' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x86ab2cc7'/>
       <elf-symbol name='__traceiter_android_vh_override_creds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9a373561'/>
       <elf-symbol name='__traceiter_android_vh_page_isolated_for_reclaim' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1bf70d78'/>
       <elf-symbol name='__traceiter_android_vh_page_referenced_check_bypass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe8cedd'/>
@@ -563,10 +596,14 @@
       <elf-symbol name='__traceiter_android_vh_page_trylock_get_result' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xeadfb49'/>
       <elf-symbol name='__traceiter_android_vh_page_trylock_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x75a90eb7'/>
       <elf-symbol name='__traceiter_android_vh_pagecache_get_page' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x57236bba'/>
+      <elf-symbol name='__traceiter_android_vh_pageset_update' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf5c57c7a'/>
       <elf-symbol name='__traceiter_android_vh_pcplist_add_cma_pages_bypass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1e223464'/>
+      <elf-symbol name='__traceiter_android_vh_percpu_rwsem_wq_add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x62fdb45d'/>
       <elf-symbol name='__traceiter_android_vh_prepare_update_load_avg_se' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf9429c7b'/>
       <elf-symbol name='__traceiter_android_vh_printk_hotplug' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x5728d98f'/>
       <elf-symbol name='__traceiter_android_vh_process_killed' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xaf2abc9b'/>
+      <elf-symbol name='__traceiter_android_vh_psi_event' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd13ea9bd'/>
+      <elf-symbol name='__traceiter_android_vh_psi_group' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3960e408'/>
       <elf-symbol name='__traceiter_android_vh_ptype_head' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9eb05f'/>
       <elf-symbol name='__traceiter_android_vh_ra_tuning_max_page' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1b994310'/>
       <elf-symbol name='__traceiter_android_vh_record_mutex_lock_starttime' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xcf74421b'/>
@@ -576,10 +613,18 @@
       <elf-symbol name='__traceiter_android_vh_remove_vmalloc_stack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xcbd56ed4'/>
       <elf-symbol name='__traceiter_android_vh_revert_creds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd5c61c41'/>
       <elf-symbol name='__traceiter_android_vh_rmqueue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x48f52d6c'/>
+      <elf-symbol name='__traceiter_android_vh_rmqueue_bulk_bypass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9d555273'/>
       <elf-symbol name='__traceiter_android_vh_rproc_recovery' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x91abb8e'/>
       <elf-symbol name='__traceiter_android_vh_rproc_recovery_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb63695c9'/>
+      <elf-symbol name='__traceiter_android_vh_rtmutex_wait_finish' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x750e0a1'/>
+      <elf-symbol name='__traceiter_android_vh_rtmutex_wait_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe9bb6123'/>
+      <elf-symbol name='__traceiter_android_vh_rwsem_can_spin_on_owner' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xeabb7b4f'/>
       <elf-symbol name='__traceiter_android_vh_rwsem_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xce4ae038'/>
       <elf-symbol name='__traceiter_android_vh_rwsem_mark_wake_readers' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6caae76b'/>
+      <elf-symbol name='__traceiter_android_vh_rwsem_opt_spin_finish' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1a7edc2b'/>
+      <elf-symbol name='__traceiter_android_vh_rwsem_opt_spin_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x901addbf'/>
+      <elf-symbol name='__traceiter_android_vh_rwsem_read_wait_finish' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xfa305911'/>
+      <elf-symbol name='__traceiter_android_vh_rwsem_read_wait_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x608da8a2'/>
       <elf-symbol name='__traceiter_android_vh_rwsem_set_owner' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb5ba5e92'/>
       <elf-symbol name='__traceiter_android_vh_rwsem_set_reader_owned' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xcf580971'/>
       <elf-symbol name='__traceiter_android_vh_rwsem_up_read_end' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x71072d'/>
@@ -587,10 +632,13 @@
       <elf-symbol name='__traceiter_android_vh_rwsem_wake' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7a813da7'/>
       <elf-symbol name='__traceiter_android_vh_rwsem_wake_finish' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xbd987012'/>
       <elf-symbol name='__traceiter_android_vh_rwsem_write_finished' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd61e47bf'/>
+      <elf-symbol name='__traceiter_android_vh_rwsem_write_wait_finish' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x86904185'/>
+      <elf-symbol name='__traceiter_android_vh_rwsem_write_wait_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1c7a8b6c'/>
       <elf-symbol name='__traceiter_android_vh_save_track_hash' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9bc3dfb7'/>
       <elf-symbol name='__traceiter_android_vh_save_vmalloc_stack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xdf510618'/>
       <elf-symbol name='__traceiter_android_vh_sched_pelt_multiplier' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb77c8f2d'/>
       <elf-symbol name='__traceiter_android_vh_sched_setaffinity_early' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3a5239a6'/>
+      <elf-symbol name='__traceiter_android_vh_sched_show_task' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xeb77bfc8'/>
       <elf-symbol name='__traceiter_android_vh_sched_stat_runtime_rt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x18567cdf'/>
       <elf-symbol name='__traceiter_android_vh_scheduler_tick' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8c91de8f'/>
       <elf-symbol name='__traceiter_android_vh_scmi_timeout_sync' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa40e7e09'/>
@@ -611,6 +659,9 @@
       <elf-symbol name='__traceiter_android_vh_set_wake_flags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb592ac11'/>
       <elf-symbol name='__traceiter_android_vh_setscheduler_uclamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc34cea02'/>
       <elf-symbol name='__traceiter_android_vh_sha256' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x88fe3e25'/>
+      <elf-symbol name='__traceiter_android_vh_shmem_alloc_page' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4842b608'/>
+      <elf-symbol name='__traceiter_android_vh_should_alloc_pages_retry' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc5dd7624'/>
+      <elf-symbol name='__traceiter_android_vh_should_end_madvise' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf15ac74f'/>
       <elf-symbol name='__traceiter_android_vh_show_mapcount_pages' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x68acba8b'/>
       <elf-symbol name='__traceiter_android_vh_show_max_freq' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc5681f17'/>
       <elf-symbol name='__traceiter_android_vh_show_mem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1d424b7d'/>
@@ -620,10 +671,13 @@
       <elf-symbol name='__traceiter_android_vh_shrink_node_memcgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2907a08b'/>
       <elf-symbol name='__traceiter_android_vh_shrink_slab_bypass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa0334e59'/>
       <elf-symbol name='__traceiter_android_vh_si_swapinfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x549c7529'/>
+      <elf-symbol name='__traceiter_android_vh_skip_swapcache' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd3267893'/>
       <elf-symbol name='__traceiter_android_vh_snapshot_refaults' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8c6a1bd0'/>
       <elf-symbol name='__traceiter_android_vh_snd_compr_use_pause_in_drain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb6ab1ad2'/>
       <elf-symbol name='__traceiter_android_vh_snd_soc_card_get_comp_chain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x469905b0'/>
       <elf-symbol name='__traceiter_android_vh_sound_usb_support_cpu_suspend' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4e022349'/>
+      <elf-symbol name='__traceiter_android_vh_subpage_dma_contig_alloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa3865615'/>
+      <elf-symbol name='__traceiter_android_vh_swap_avail_heads_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2abc2182'/>
       <elf-symbol name='__traceiter_android_vh_swap_slot_cache_active' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2fc3faeb'/>
       <elf-symbol name='__traceiter_android_vh_swapin_add_anon_rmap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x552d1953'/>
       <elf-symbol name='__traceiter_android_vh_sync_txn_recvd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x584627e2'/>
@@ -632,8 +686,11 @@
       <elf-symbol name='__traceiter_android_vh_thermal_pm_notify_suspend' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8d0ef19f'/>
       <elf-symbol name='__traceiter_android_vh_timer_calc_index' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x110d6b1e'/>
       <elf-symbol name='__traceiter_android_vh_timerfd_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8c68d59c'/>
+      <elf-symbol name='__traceiter_android_vh_try_to_freeze_todo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd1146850'/>
+      <elf-symbol name='__traceiter_android_vh_try_to_freeze_todo_unfrozen' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6dbc0417'/>
       <elf-symbol name='__traceiter_android_vh_try_to_unmap_one' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2d6f2e0f'/>
       <elf-symbol name='__traceiter_android_vh_tune_inactive_ratio' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc3c873e2'/>
+      <elf-symbol name='__traceiter_android_vh_tune_mmap_readaround' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x5c25963'/>
       <elf-symbol name='__traceiter_android_vh_tune_scan_type' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x842cf72c'/>
       <elf-symbol name='__traceiter_android_vh_tune_swappiness' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd2ac8d57'/>
       <elf-symbol name='__traceiter_android_vh_typec_store_partner_src_caps' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3707443'/>
@@ -651,6 +708,7 @@
       <elf-symbol name='__traceiter_android_vh_ufs_send_uic_command' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xfa724649'/>
       <elf-symbol name='__traceiter_android_vh_ufs_update_sdev' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x5afd339e'/>
       <elf-symbol name='__traceiter_android_vh_ufs_update_sysfs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x68f34378'/>
+      <elf-symbol name='__traceiter_android_vh_unreserve_highatomic_bypass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xed603041'/>
       <elf-symbol name='__traceiter_android_vh_unuse_swap_page' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe37d6d40'/>
       <elf-symbol name='__traceiter_android_vh_update_page_mapcount' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xafae7b4a'/>
       <elf-symbol name='__traceiter_android_vh_update_topology_flags_workfn' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf9046f81'/>
@@ -659,7 +717,11 @@
       <elf-symbol name='__traceiter_android_vh_v4l2subdev_set_fmt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x966f8717'/>
       <elf-symbol name='__traceiter_android_vh_v4l2subdev_set_frame_interval' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x56062d28'/>
       <elf-symbol name='__traceiter_android_vh_v4l2subdev_set_selection' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x841c50e9'/>
+      <elf-symbol name='__traceiter_android_vh_vmpressure' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x72bfa1b6'/>
       <elf-symbol name='__traceiter_android_vh_waiting_for_page_migration' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc398818c'/>
+      <elf-symbol name='__traceiter_android_vh_wakeup_bypass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x585c30a1'/>
+      <elf-symbol name='__traceiter_android_vh_watchdog_timer_softlockup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf7d0def4'/>
+      <elf-symbol name='__traceiter_android_vh_wq_lockup_pool' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x62c05483'/>
       <elf-symbol name='__traceiter_binder_transaction_received' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x692569ee'/>
       <elf-symbol name='__traceiter_block_bio_complete' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf3283a8b'/>
       <elf-symbol name='__traceiter_block_bio_queue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x89358ed9'/>
@@ -696,6 +758,10 @@
       <elf-symbol name='__traceiter_map' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x71c059d8'/>
       <elf-symbol name='__traceiter_mm_vmscan_direct_reclaim_begin' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x803bf202'/>
       <elf-symbol name='__traceiter_mm_vmscan_direct_reclaim_end' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf2520b8a'/>
+      <elf-symbol name='__traceiter_net_dev_queue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8f43ca5f'/>
+      <elf-symbol name='__traceiter_net_dev_xmit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf3c1c53d'/>
+      <elf-symbol name='__traceiter_netif_receive_skb' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4881e2b3'/>
+      <elf-symbol name='__traceiter_netif_rx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6d540fe8'/>
       <elf-symbol name='__traceiter_pelt_cfs_tp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc83a44f4'/>
       <elf-symbol name='__traceiter_pelt_dl_tp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x762ec4c8'/>
       <elf-symbol name='__traceiter_pelt_irq_tp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x5d7a9f3f'/>
@@ -730,6 +796,8 @@
       <elf-symbol name='__tty_insert_flip_char' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa93df441'/>
       <elf-symbol name='__typec_altmode_register_driver' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2d72e52a'/>
       <elf-symbol name='__udelay' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9e7d6bd0'/>
+      <elf-symbol name='__udp4_lib_lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xcb2c111b'/>
+      <elf-symbol name='__udp6_lib_lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x20c53042'/>
       <elf-symbol name='__uio_register_device' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x27c24536'/>
       <elf-symbol name='__unregister_chrdev' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6bc3fbc0'/>
       <elf-symbol name='__update_load_avg_blocked_se' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xfbdf5c3e'/>
@@ -754,6 +822,7 @@
       <elf-symbol name='__wake_up_sync_key' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xba220db7'/>
       <elf-symbol name='__warn_printk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x56470118'/>
       <elf-symbol name='__xa_alloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf40e7a73'/>
+      <elf-symbol name='__xa_alloc_cyclic' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1765ea1f'/>
       <elf-symbol name='__xa_clear_mark' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb9af1d0d'/>
       <elf-symbol name='__xa_insert' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x296cb509'/>
       <elf-symbol name='__xfrm_decode_session' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x41b76380'/>
@@ -863,6 +932,7 @@
       <elf-symbol name='arch_mmap_rnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x70ff6cfa'/>
       <elf-symbol name='argv_free' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe0b13336'/>
       <elf-symbol name='argv_split' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7380dffa'/>
+      <elf-symbol name='arm64_noalias_setup_dma_ops' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd3eaf99b'/>
       <elf-symbol name='async_schedule_node' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf5f370e0'/>
       <elf-symbol name='async_schedule_node_domain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd21b61bd'/>
       <elf-symbol name='async_synchronize_full_domain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6ca4bf88'/>
@@ -1031,6 +1101,7 @@
       <elf-symbol name='blkcg_deactivate_policy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x95e0f7e4'/>
       <elf-symbol name='blkcg_policy_register' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2679bfca'/>
       <elf-symbol name='blkcg_policy_unregister' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf3d8b077'/>
+      <elf-symbol name='blkcg_schedule_throttle' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x525b80a6'/>
       <elf-symbol name='blkdev_fsync' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x653dfdd4'/>
       <elf-symbol name='blkdev_get_by_dev' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1aa5f837'/>
       <elf-symbol name='blkdev_get_by_path' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xedd07e1a'/>
@@ -1131,6 +1202,7 @@
       <elf-symbol name='cec_transmit_attempt_done_ts' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf0e3cb34'/>
       <elf-symbol name='cec_transmit_done_ts' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6de41e89'/>
       <elf-symbol name='cec_unregister_adapter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9c8d8606'/>
+      <elf-symbol name='cgroup_add_dfl_cftypes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xefadfa8'/>
       <elf-symbol name='cgroup_add_legacy_cftypes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xaa120638'/>
       <elf-symbol name='cgroup_path_ns' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x35df6fa8'/>
       <elf-symbol name='cgroup_taskset_first' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x19f55823'/>
@@ -1167,6 +1239,7 @@
       <elf-symbol name='clk_get_parent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x63150e06'/>
       <elf-symbol name='clk_get_phase' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1c5ff742'/>
       <elf-symbol name='clk_get_rate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x556e4390'/>
+      <elf-symbol name='clk_has_parent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2b952517'/>
       <elf-symbol name='clk_hw_get_flags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xee3aa642'/>
       <elf-symbol name='clk_hw_get_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb62ec837'/>
       <elf-symbol name='clk_hw_get_num_parents' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xcc8b1059'/>
@@ -1248,6 +1321,7 @@
       <elf-symbol name='console_unlock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc631580a'/>
       <elf-symbol name='consume_skb' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xdc88620f'/>
       <elf-symbol name='copy_from_kernel_nofault' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4531ab62'/>
+      <elf-symbol name='copy_highpage' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7f2ef89a'/>
       <elf-symbol name='copy_page' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4d0d163d'/>
       <elf-symbol name='copy_to_user_fromio' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x342a2354'/>
       <elf-symbol name='cpu_have_feature' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x41237f71'/>
@@ -2737,6 +2811,7 @@
       <elf-symbol name='get_each_dmabuf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd4a0a2a0'/>
       <elf-symbol name='get_each_object_track' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x882f614f'/>
       <elf-symbol name='get_freelist_nr_pages' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x618b006f'/>
+      <elf-symbol name='get_fs_type' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd960956f'/>
       <elf-symbol name='get_governor_parent_kobj' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb8da8552'/>
       <elf-symbol name='get_kernel_pages' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3b413908'/>
       <elf-symbol name='get_mem_cgroup_from_mm' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2cf77b2d'/>
@@ -3027,7 +3102,10 @@
       <elf-symbol name='iio_read_const_attr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1de95da3'/>
       <elf-symbol name='iio_read_mount_matrix' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4657b098'/>
       <elf-symbol name='iio_show_mount_matrix' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3fd71ac4'/>
+      <elf-symbol name='iio_trigger_alloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9f710efb'/>
+      <elf-symbol name='iio_trigger_free' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x165fa02e'/>
       <elf-symbol name='iio_trigger_notify_done' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x32c17b35'/>
+      <elf-symbol name='iio_trigger_unregister' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc327a9e0'/>
       <elf-symbol name='iio_update_buffers' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6304f8c5'/>
       <elf-symbol name='iio_write_channel_raw' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xfd0c8ed0'/>
       <elf-symbol name='ilookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x5823099b'/>
@@ -3227,6 +3305,7 @@
       <elf-symbol name='irq_work_queue_on' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf64a80c9'/>
       <elf-symbol name='irq_work_run' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x541bd60a'/>
       <elf-symbol name='irq_work_sync' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf361a95b'/>
+      <elf-symbol name='is_ashmem_file' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x94fc40b5'/>
       <elf-symbol name='is_bad_inode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2d628931'/>
       <elf-symbol name='is_console_locked' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x944a564d'/>
       <elf-symbol name='is_dma_buf_file' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xabcf70c3'/>
@@ -3236,6 +3315,7 @@
       <elf-symbol name='isolate_anon_lru_page' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1b395e30'/>
       <elf-symbol name='iter_file_splice_write' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xad12a621'/>
       <elf-symbol name='iterate_fd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7371390e'/>
+      <elf-symbol name='iterate_supers_type' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x58403213'/>
       <elf-symbol name='iunique' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd8cc9361'/>
       <elf-symbol name='iw_handler_get_spy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x762c33d7'/>
       <elf-symbol name='iw_handler_get_thrspy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xbaccc24'/>
@@ -3482,6 +3562,7 @@
       <elf-symbol name='media_request_object_complete' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc8c9eb59'/>
       <elf-symbol name='media_request_put' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x95df91f1'/>
       <elf-symbol name='mem_cgroup_from_id' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2450c381'/>
+      <elf-symbol name='mem_cgroup_update_lru_size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xeec6d1b'/>
       <elf-symbol name='memblock_end_of_DRAM' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4c894766'/>
       <elf-symbol name='memblock_free' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9f0ec720'/>
       <elf-symbol name='memchr' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes' crc='0xa07a37f0'/>
@@ -3618,6 +3699,7 @@
       <elf-symbol name='mmc_select_timing' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xdf721daa'/>
       <elf-symbol name='mmc_send_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2ec60b84'/>
       <elf-symbol name='mmc_send_tuning' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6b9e0402'/>
+      <elf-symbol name='mmc_set_blocklen' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc0d922f'/>
       <elf-symbol name='mmc_set_clock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa99f2303'/>
       <elf-symbol name='mmc_set_data_timeout' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2d4e8591'/>
       <elf-symbol name='mmc_set_initial_state' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4d8084f3'/>
@@ -3674,6 +3756,7 @@
       <elf-symbol name='netdev_info' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x756da890'/>
       <elf-symbol name='netdev_lower_state_changed' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x726ef0e1'/>
       <elf-symbol name='netdev_master_upper_dev_link' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x67573634'/>
+      <elf-symbol name='netdev_notice' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x5fe58f37'/>
       <elf-symbol name='netdev_notify_peers' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x19130aec'/>
       <elf-symbol name='netdev_pick_tx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1b8a0de7'/>
       <elf-symbol name='netdev_rss_key_fill' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x467df16d'/>
@@ -3732,6 +3815,7 @@
       <elf-symbol name='nonseekable_open' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x82885f25'/>
       <elf-symbol name='noop_llseek' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9f5afe9b'/>
       <elf-symbol name='notify_change' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xcbe83eee'/>
+      <elf-symbol name='nr_free_buffer_pages' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x27fa66e1'/>
       <elf-symbol name='nr_ipi_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x215054f8'/>
       <elf-symbol name='ns_capable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf3adccc5'/>
       <elf-symbol name='ns_to_kernel_old_timeval' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6b853d06'/>
@@ -3765,6 +3849,7 @@
       <elf-symbol name='of_clk_get_parent_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd03f2be3'/>
       <elf-symbol name='of_clk_hw_onecell_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x70951935'/>
       <elf-symbol name='of_clk_hw_simple_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3c247ec4'/>
+      <elf-symbol name='of_clk_parent_fill' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc3059899'/>
       <elf-symbol name='of_clk_set_defaults' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd052824e'/>
       <elf-symbol name='of_clk_src_onecell_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x50eb7fa5'/>
       <elf-symbol name='of_clk_src_simple_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb4c76b57'/>
@@ -3826,6 +3911,7 @@
       <elf-symbol name='of_get_next_child' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x69601c70'/>
       <elf-symbol name='of_get_next_parent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6172fe2a'/>
       <elf-symbol name='of_get_parent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf7c453f0'/>
+      <elf-symbol name='of_get_pci_domain_nr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xdfbaa17b'/>
       <elf-symbol name='of_get_phy_mode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc4529e86'/>
       <elf-symbol name='of_get_property' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xad0a8a5a'/>
       <elf-symbol name='of_get_regulator_init_data' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe9c56740'/>
@@ -3927,6 +4013,7 @@
       <elf-symbol name='page_pool_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x12fce2d2'/>
       <elf-symbol name='page_pool_put_page' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2dcee344'/>
       <elf-symbol name='page_pool_release_page' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc13ff9dc'/>
+      <elf-symbol name='page_referenced' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa22fd349'/>
       <elf-symbol name='page_reporting_register' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7a216f9'/>
       <elf-symbol name='page_reporting_unregister' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x16d35611'/>
       <elf-symbol name='page_symlink' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x94bee97e'/>
@@ -3995,7 +4082,9 @@
       <elf-symbol name='pci_free_irq' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x43137fea'/>
       <elf-symbol name='pci_free_irq_vectors' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7631967b'/>
       <elf-symbol name='pci_generic_config_read' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb556c195'/>
+      <elf-symbol name='pci_generic_config_read32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9e9992'/>
       <elf-symbol name='pci_generic_config_write' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x611bb548'/>
+      <elf-symbol name='pci_generic_config_write32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa9709230'/>
       <elf-symbol name='pci_get_device' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc2bd87e4'/>
       <elf-symbol name='pci_get_domain_bus_and_slot' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf6af64d0'/>
       <elf-symbol name='pci_get_slot' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3133aa0c'/>
@@ -4008,6 +4097,7 @@
       <elf-symbol name='pci_irq_vector' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa75dc53e'/>
       <elf-symbol name='pci_load_and_free_saved_state' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1322500d'/>
       <elf-symbol name='pci_load_saved_state' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa1ffe003'/>
+      <elf-symbol name='pci_lock_rescan_remove' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xddbeeecc'/>
       <elf-symbol name='pci_map_rom' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9eb152a6'/>
       <elf-symbol name='pci_match_id' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa1648ead'/>
       <elf-symbol name='pci_msi_create_irq_domain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa7c664da'/>
@@ -4016,6 +4106,8 @@
       <elf-symbol name='pci_msi_unmask_irq' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x43eb9092'/>
       <elf-symbol name='pci_msix_vec_count' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1c547591'/>
       <elf-symbol name='pci_num_vf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9eb483fe'/>
+      <elf-symbol name='pci_pio_to_address' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf05fbf09'/>
+      <elf-symbol name='pci_prepare_to_sleep' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xbd6af6f3'/>
       <elf-symbol name='pci_read_config_byte' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd49eba8d'/>
       <elf-symbol name='pci_read_config_dword' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4412c58e'/>
       <elf-symbol name='pci_read_config_word' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf5e7ab97'/>
@@ -4042,6 +4134,7 @@
       <elf-symbol name='pci_stop_root_bus' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xfce1d90e'/>
       <elf-symbol name='pci_store_saved_state' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7180a796'/>
       <elf-symbol name='pci_try_set_mwi' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xcc072d8f'/>
+      <elf-symbol name='pci_unlock_rescan_remove' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x5790e7a0'/>
       <elf-symbol name='pci_unmap_rom' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x93d7a4c2'/>
       <elf-symbol name='pci_unregister_driver' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe1e4290c'/>
       <elf-symbol name='pci_vfs_assigned' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6e96d32a'/>
@@ -4104,6 +4197,7 @@
       <elf-symbol name='phy_drivers_unregister' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x10e46d5d'/>
       <elf-symbol name='phy_ethtool_get_eee' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xca8a507c'/>
       <elf-symbol name='phy_ethtool_get_link_ksettings' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe11de541'/>
+      <elf-symbol name='phy_ethtool_get_wol' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8a3f30c4'/>
       <elf-symbol name='phy_ethtool_ksettings_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6e0fe577'/>
       <elf-symbol name='phy_ethtool_ksettings_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8d679adb'/>
       <elf-symbol name='phy_ethtool_nway_reset' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7cfa9588'/>
@@ -4150,6 +4244,7 @@
       <elf-symbol name='phy_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa751b989'/>
       <elf-symbol name='phy_start_aneg' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x72889a7e'/>
       <elf-symbol name='phy_stop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xceef0b7f'/>
+      <elf-symbol name='phy_support_asym_pause' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x940570ee'/>
       <elf-symbol name='phy_support_sym_pause' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x34ce063c'/>
       <elf-symbol name='phy_suspend' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4a51c13b'/>
       <elf-symbol name='phy_unregister_fixup_for_uid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd738ca1b'/>
@@ -5515,7 +5610,9 @@
       <elf-symbol name='ttm_bo_move_ttm' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x11a3f8ab'/>
       <elf-symbol name='ttm_bo_put' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1ae736e0'/>
       <elf-symbol name='ttm_bo_unlock_delayed_workqueue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe42af0f4'/>
+      <elf-symbol name='ttm_bo_unmap_virtual' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x96129596'/>
       <elf-symbol name='ttm_bo_validate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x93ee0456'/>
+      <elf-symbol name='ttm_bo_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x96b90ffd'/>
       <elf-symbol name='ttm_dma_page_alloc_debugfs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc9808f57'/>
       <elf-symbol name='ttm_dma_populate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x71b70ac6'/>
       <elf-symbol name='ttm_dma_tt_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xcda16493'/>
@@ -5534,6 +5631,7 @@
       <elf-symbol name='ttm_tt_destroy_common' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xeba2f3ab'/>
       <elf-symbol name='ttm_tt_populate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x69b40311'/>
       <elf-symbol name='ttm_tt_set_placement_caching' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa48e052c'/>
+      <elf-symbol name='ttm_tt_unpopulate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x53aaecf8'/>
       <elf-symbol name='ttm_unmap_and_unpopulate_pages' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2d35252c'/>
       <elf-symbol name='tty_driver_flush_buffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2f2814e2'/>
       <elf-symbol name='tty_encode_baud_rate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf1e71df5'/>
@@ -5559,6 +5657,7 @@
       <elf-symbol name='tty_termios_baud_rate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x409873e3'/>
       <elf-symbol name='tty_termios_copy_hw' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x30e74134'/>
       <elf-symbol name='tty_termios_encode_baud_rate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x5641485b'/>
+      <elf-symbol name='tty_termios_hw_change' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6c257ac0'/>
       <elf-symbol name='tty_unregister_device' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc65f0be5'/>
       <elf-symbol name='tty_unregister_driver' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf4a49dea'/>
       <elf-symbol name='tty_unregister_ldisc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa120d33c'/>
@@ -5751,8 +5850,10 @@
       <elf-symbol name='usb_disabled' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x19a304ba'/>
       <elf-symbol name='usb_driver_claim_interface' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe26688dd'/>
       <elf-symbol name='usb_driver_release_interface' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x361c5d2f'/>
+      <elf-symbol name='usb_driver_set_configuration' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa823be'/>
       <elf-symbol name='usb_enable_autosuspend' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc6c961cb'/>
       <elf-symbol name='usb_enable_intel_xhci_ports' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x39bab8b7'/>
+      <elf-symbol name='usb_enable_lpm' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x613613f'/>
       <elf-symbol name='usb_ep_alloc_request' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x880d48e4'/>
       <elf-symbol name='usb_ep_autoconfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x70832c42'/>
       <elf-symbol name='usb_ep_clear_halt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9370b708'/>
@@ -5845,6 +5946,7 @@
       <elf-symbol name='usb_remove_function' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x62ecc28b'/>
       <elf-symbol name='usb_remove_hcd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9a048fef'/>
       <elf-symbol name='usb_remove_phy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf6d7a707'/>
+      <elf-symbol name='usb_reset_device' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xff4cca38'/>
       <elf-symbol name='usb_role_switch_find_by_fwnode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7652f247'/>
       <elf-symbol name='usb_role_switch_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc67dad16'/>
       <elf-symbol name='usb_role_switch_get_drvdata' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1690b503'/>
@@ -5867,6 +5969,7 @@
       <elf-symbol name='usb_unlink_urb' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3b4651b8'/>
       <elf-symbol name='usb_unpoison_urb' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc518a377'/>
       <elf-symbol name='usb_unregister_notify' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x811dc334'/>
+      <elf-symbol name='usb_wait_anchor_empty_timeout' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x407af304'/>
       <elf-symbol name='usb_wakeup_enabled_descendants' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa8576ad'/>
       <elf-symbol name='usb_wakeup_notification' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x84edb62f'/>
       <elf-symbol name='usbnet_cdc_unbind' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd8edf3d6'/>
@@ -6401,9 +6504,11 @@
       <elf-symbol name='__tracepoint_android_rvh_v4l2subdev_set_frame_interval' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4c8ac417'/>
       <elf-symbol name='__tracepoint_android_rvh_v4l2subdev_set_selection' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x173d29f2'/>
       <elf-symbol name='__tracepoint_android_rvh_wake_up_new_task' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6b60d8f1'/>
+      <elf-symbol name='__tracepoint_android_vh___cgroup_throttle_swaprate' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xbeeef23d'/>
       <elf-symbol name='__tracepoint_android_vh_account_swap_pages' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x628a58c5'/>
       <elf-symbol name='__tracepoint_android_vh_account_task_time' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf1afbf0d'/>
       <elf-symbol name='__tracepoint_android_vh_add_page_to_lrulist' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb9d54bc5'/>
+      <elf-symbol name='__tracepoint_android_vh_add_to_avail_list' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8a9d0f84'/>
       <elf-symbol name='__tracepoint_android_vh_aes_decrypt' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xde5b1cc7'/>
       <elf-symbol name='__tracepoint_android_vh_aes_encrypt' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x10f648a3'/>
       <elf-symbol name='__tracepoint_android_vh_aes_expandkey' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf7274615'/>
@@ -6450,12 +6555,14 @@
       <elf-symbol name='__tracepoint_android_vh_check_page_look_around_ref' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x69f2f1be'/>
       <elf-symbol name='__tracepoint_android_vh_check_uninterruptible_tasks' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x63a6e496'/>
       <elf-symbol name='__tracepoint_android_vh_check_uninterruptible_tasks_dn' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xbfea98d1'/>
+      <elf-symbol name='__tracepoint_android_vh_cleanup_old_buffers_bypass' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1a4120ec'/>
       <elf-symbol name='__tracepoint_android_vh_clear_mask_adjust' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4b0c9da7'/>
       <elf-symbol name='__tracepoint_android_vh_clear_reserved_fmt_fields' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x43071b0c'/>
       <elf-symbol name='__tracepoint_android_vh_cma_alloc_finish' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x13105ce6'/>
       <elf-symbol name='__tracepoint_android_vh_cma_alloc_start' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc79303a7'/>
       <elf-symbol name='__tracepoint_android_vh_cma_drain_all_pages_bypass' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xaa06d74e'/>
       <elf-symbol name='__tracepoint_android_vh_commit_creds' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8defd009'/>
+      <elf-symbol name='__tracepoint_android_vh_compact_finished' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xeaefd1c2'/>
       <elf-symbol name='__tracepoint_android_vh_count_pswpin' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe9ce09de'/>
       <elf-symbol name='__tracepoint_android_vh_count_pswpout' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x63217582'/>
       <elf-symbol name='__tracepoint_android_vh_count_swpout_vm_event' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9200b1e7'/>
@@ -6469,8 +6576,10 @@
       <elf-symbol name='__tracepoint_android_vh_cpufreq_target' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xaa641f23'/>
       <elf-symbol name='__tracepoint_android_vh_cpuidle_psci_enter' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x137e6ebe'/>
       <elf-symbol name='__tracepoint_android_vh_cpuidle_psci_exit' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xaaacb3b6'/>
+      <elf-symbol name='__tracepoint_android_vh_del_from_avail_list' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe0c0ccd5'/>
       <elf-symbol name='__tracepoint_android_vh_del_page_from_lrulist' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd32d8431'/>
       <elf-symbol name='__tracepoint_android_vh_disable_thermal_cooling_stats' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe8d666d'/>
+      <elf-symbol name='__tracepoint_android_vh_dm_bufio_shrink_scan_bypass' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa2158428'/>
       <elf-symbol name='__tracepoint_android_vh_do_futex' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x76782dd0'/>
       <elf-symbol name='__tracepoint_android_vh_do_page_trylock' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8ed4864a'/>
       <elf-symbol name='__tracepoint_android_vh_do_send_sig_info' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6db82691'/>
@@ -6493,6 +6602,7 @@
       <elf-symbol name='__tracepoint_android_vh_free_pages' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7e1983c0'/>
       <elf-symbol name='__tracepoint_android_vh_free_swap_slot' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1238733c'/>
       <elf-symbol name='__tracepoint_android_vh_free_task' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x25db8da7'/>
+      <elf-symbol name='__tracepoint_android_vh_free_unref_page_bypass' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd865ea92'/>
       <elf-symbol name='__tracepoint_android_vh_freq_qos_add_request' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x20f6db7a'/>
       <elf-symbol name='__tracepoint_android_vh_freq_qos_remove_request' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc15e1ec8'/>
       <elf-symbol name='__tracepoint_android_vh_freq_qos_update_request' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8e8623e4'/>
@@ -6531,11 +6641,13 @@
       <elf-symbol name='__tracepoint_android_vh_kfree_skb' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7d60c113'/>
       <elf-symbol name='__tracepoint_android_vh_killed_process' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8f7fac90'/>
       <elf-symbol name='__tracepoint_android_vh_kmalloc_slab' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xbc488301'/>
+      <elf-symbol name='__tracepoint_android_vh_kvmalloc_node_use_vmalloc' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x44575f03'/>
       <elf-symbol name='__tracepoint_android_vh_logbuf' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8bf980ca'/>
       <elf-symbol name='__tracepoint_android_vh_logbuf_pr_cont' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x783fd15a'/>
       <elf-symbol name='__tracepoint_android_vh_look_around' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x86aa7fb3'/>
       <elf-symbol name='__tracepoint_android_vh_look_around_migrate_page' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x23569ba4'/>
       <elf-symbol name='__tracepoint_android_vh_madvise_cold_or_pageout' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4ac6383e'/>
+      <elf-symbol name='__tracepoint_android_vh_madvise_cold_or_pageout_abort' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4ebf12b4'/>
       <elf-symbol name='__tracepoint_android_vh_map_util_freq' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf9624317'/>
       <elf-symbol name='__tracepoint_android_vh_mark_page_accessed' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2e42e519'/>
       <elf-symbol name='__tracepoint_android_vh_media_device_setup_link' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x32ff9f07'/>
@@ -6553,6 +6665,9 @@
       <elf-symbol name='__tracepoint_android_vh_mmc_blk_reset' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x28c3f8b2'/>
       <elf-symbol name='__tracepoint_android_vh_mmc_gpio_cd_irqt' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xad02c3d3'/>
       <elf-symbol name='__tracepoint_android_vh_mmput' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xabcddfae'/>
+      <elf-symbol name='__tracepoint_android_vh_mutex_can_spin_on_owner' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x5d00a7e9'/>
+      <elf-symbol name='__tracepoint_android_vh_mutex_opt_spin_finish' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8cd73093'/>
+      <elf-symbol name='__tracepoint_android_vh_mutex_opt_spin_start' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xbf1bd3e1'/>
       <elf-symbol name='__tracepoint_android_vh_mutex_unlock_slowpath' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6440606b'/>
       <elf-symbol name='__tracepoint_android_vh_mutex_unlock_slowpath_end' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x30de9614'/>
       <elf-symbol name='__tracepoint_android_vh_mutex_wait_finish' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe119258f'/>
@@ -6568,7 +6683,9 @@
       <elf-symbol name='__tracepoint_android_vh_page_trylock_get_result' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc7cf863'/>
       <elf-symbol name='__tracepoint_android_vh_page_trylock_set' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x92e4d5a7'/>
       <elf-symbol name='__tracepoint_android_vh_pagecache_get_page' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xbcb3c40e'/>
+      <elf-symbol name='__tracepoint_android_vh_pageset_update' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc61161c2'/>
       <elf-symbol name='__tracepoint_android_vh_pcplist_add_cma_pages_bypass' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x133564aa'/>
+      <elf-symbol name='__tracepoint_android_vh_percpu_rwsem_wq_add' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6ad0ccb3'/>
       <elf-symbol name='__tracepoint_android_vh_prepare_update_load_avg_se' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3b73d0f'/>
       <elf-symbol name='__tracepoint_android_vh_printk_hotplug' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe329d35d'/>
       <elf-symbol name='__tracepoint_android_vh_process_killed' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb4b343cc'/>
@@ -6583,12 +6700,16 @@
       <elf-symbol name='__tracepoint_android_vh_remove_vmalloc_stack' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1f5d8a1'/>
       <elf-symbol name='__tracepoint_android_vh_revert_creds' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xbedc98e0'/>
       <elf-symbol name='__tracepoint_android_vh_rmqueue' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xa8c074b9'/>
+      <elf-symbol name='__tracepoint_android_vh_rmqueue_bulk_bypass' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x975eb8dc'/>
       <elf-symbol name='__tracepoint_android_vh_rproc_recovery' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe1337b04'/>
       <elf-symbol name='__tracepoint_android_vh_rproc_recovery_set' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe9cd95b9'/>
       <elf-symbol name='__tracepoint_android_vh_rtmutex_wait_finish' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xee6fc031'/>
       <elf-symbol name='__tracepoint_android_vh_rtmutex_wait_start' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xdaf6aebd'/>
+      <elf-symbol name='__tracepoint_android_vh_rwsem_can_spin_on_owner' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x827d458e'/>
       <elf-symbol name='__tracepoint_android_vh_rwsem_init' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9be0ac46'/>
       <elf-symbol name='__tracepoint_android_vh_rwsem_mark_wake_readers' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xcde9c83e'/>
+      <elf-symbol name='__tracepoint_android_vh_rwsem_opt_spin_finish' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3663f883'/>
+      <elf-symbol name='__tracepoint_android_vh_rwsem_opt_spin_start' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xdbe5c615'/>
       <elf-symbol name='__tracepoint_android_vh_rwsem_read_wait_finish' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x460eeeee'/>
       <elf-symbol name='__tracepoint_android_vh_rwsem_read_wait_start' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xdc072410'/>
       <elf-symbol name='__tracepoint_android_vh_rwsem_set_owner' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb3d88f79'/>
@@ -6626,6 +6747,8 @@
       <elf-symbol name='__tracepoint_android_vh_setscheduler_uclamp' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7ae79b81'/>
       <elf-symbol name='__tracepoint_android_vh_sha256' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x890676c3'/>
       <elf-symbol name='__tracepoint_android_vh_shmem_alloc_page' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf528a71b'/>
+      <elf-symbol name='__tracepoint_android_vh_should_alloc_pages_retry' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xec1e3033'/>
+      <elf-symbol name='__tracepoint_android_vh_should_end_madvise' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xcb28c690'/>
       <elf-symbol name='__tracepoint_android_vh_show_mapcount_pages' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x40d48791'/>
       <elf-symbol name='__tracepoint_android_vh_show_max_freq' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8965f857'/>
       <elf-symbol name='__tracepoint_android_vh_show_mem' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x4520b6b9'/>
@@ -6635,11 +6758,13 @@
       <elf-symbol name='__tracepoint_android_vh_shrink_node_memcgs' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xcefd3011'/>
       <elf-symbol name='__tracepoint_android_vh_shrink_slab_bypass' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xecea3e92'/>
       <elf-symbol name='__tracepoint_android_vh_si_swapinfo' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xed9cd089'/>
+      <elf-symbol name='__tracepoint_android_vh_skip_swapcache' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc4559434'/>
       <elf-symbol name='__tracepoint_android_vh_snapshot_refaults' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1d6ecab7'/>
       <elf-symbol name='__tracepoint_android_vh_snd_compr_use_pause_in_drain' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9b89d106'/>
       <elf-symbol name='__tracepoint_android_vh_snd_soc_card_get_comp_chain' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x3011ec02'/>
       <elf-symbol name='__tracepoint_android_vh_sound_usb_support_cpu_suspend' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xdc96142a'/>
       <elf-symbol name='__tracepoint_android_vh_subpage_dma_contig_alloc' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x63c884a5'/>
+      <elf-symbol name='__tracepoint_android_vh_swap_avail_heads_init' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xae8a89d9'/>
       <elf-symbol name='__tracepoint_android_vh_swap_slot_cache_active' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7ebd576'/>
       <elf-symbol name='__tracepoint_android_vh_swapin_add_anon_rmap' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xe8f9d26'/>
       <elf-symbol name='__tracepoint_android_vh_sync_txn_recvd' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xaa651215'/>
@@ -6652,6 +6777,7 @@
       <elf-symbol name='__tracepoint_android_vh_try_to_freeze_todo_unfrozen' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8324d153'/>
       <elf-symbol name='__tracepoint_android_vh_try_to_unmap_one' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x57e416b7'/>
       <elf-symbol name='__tracepoint_android_vh_tune_inactive_ratio' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xebfa95d0'/>
+      <elf-symbol name='__tracepoint_android_vh_tune_mmap_readaround' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x452f4bbf'/>
       <elf-symbol name='__tracepoint_android_vh_tune_scan_type' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2b51008f'/>
       <elf-symbol name='__tracepoint_android_vh_tune_swappiness' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x69b36725'/>
       <elf-symbol name='__tracepoint_android_vh_typec_store_partner_src_caps' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xed5b195a'/>
@@ -6669,6 +6795,7 @@
       <elf-symbol name='__tracepoint_android_vh_ufs_send_uic_command' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8016b1df'/>
       <elf-symbol name='__tracepoint_android_vh_ufs_update_sdev' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xff48ed3d'/>
       <elf-symbol name='__tracepoint_android_vh_ufs_update_sysfs' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd1493d2e'/>
+      <elf-symbol name='__tracepoint_android_vh_unreserve_highatomic_bypass' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x382b76ea'/>
       <elf-symbol name='__tracepoint_android_vh_unuse_swap_page' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf1bb3cbd'/>
       <elf-symbol name='__tracepoint_android_vh_update_page_mapcount' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x9ef9f5c0'/>
       <elf-symbol name='__tracepoint_android_vh_update_topology_flags_workfn' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd28119e8'/>
@@ -6679,6 +6806,7 @@
       <elf-symbol name='__tracepoint_android_vh_v4l2subdev_set_selection' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xd163b93e'/>
       <elf-symbol name='__tracepoint_android_vh_vmpressure' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xf9257104'/>
       <elf-symbol name='__tracepoint_android_vh_waiting_for_page_migration' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1c9778c8'/>
+      <elf-symbol name='__tracepoint_android_vh_wakeup_bypass' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x154b88c4'/>
       <elf-symbol name='__tracepoint_android_vh_watchdog_timer_softlockup' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x74ea651e'/>
       <elf-symbol name='__tracepoint_android_vh_wq_lockup_pool' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x5980aaff'/>
       <elf-symbol name='__tracepoint_binder_transaction_received' size='72' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xab619a41'/>
@@ -6860,6 +6988,8 @@
       <elf-symbol name='of_root' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xfdee4fc'/>
       <elf-symbol name='oops_in_progress' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xb1c3a01a'/>
       <elf-symbol name='overflowuid' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8b618d08'/>
+      <elf-symbol name='page_owner_inited' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xda1512e5'/>
+      <elf-symbol name='page_pinner_inited' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xacfe4142'/>
       <elf-symbol name='panic_notifier_list' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x7ceeac9'/>
       <elf-symbol name='panic_timeout' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x1f8544b8'/>
       <elf-symbol name='param_array_ops' size='32' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xaf81f891'/>
@@ -6888,6 +7018,7 @@
       <elf-symbol name='rcu_cpu_stall_suppress_at_boot' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x789c73d9'/>
       <elf-symbol name='reboot_mode' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x429c3f9c'/>
       <elf-symbol name='reservation_ww_class' size='32' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xcc328a5c'/>
+      <elf-symbol name='root_mem_cgroup' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2b546308'/>
       <elf-symbol name='root_task_group' size='448' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xfe4b2c1d'/>
       <elf-symbol name='rps_needed' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x8761c87b'/>
       <elf-symbol name='runqueues' size='4672' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x6b95284e'/>
@@ -6924,6 +7055,7 @@
       <elf-symbol name='tracepoint_srcu' size='696' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xbf451872'/>
       <elf-symbol name='ttm_bo_glob' size='200' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x685376c6'/>
       <elf-symbol name='tty_std_termios' size='44' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x67b27ec1'/>
+      <elf-symbol name='udp_table' size='24' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x95a67b07'/>
       <elf-symbol name='usb_debug_root' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xbc6f9adc'/>
       <elf-symbol name='usb_hcd_pci_pm_ops' size='192' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x57b277fa'/>
       <elf-symbol name='usb_hcds_loaded' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc17515d7'/>
@@ -6941,12 +7073,12 @@
       <elf-symbol name='zero_pfn' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x85efc7e0'/>
     </elf-variable-symbols>
     <abi-instr address-size='64' language='LANG_C89' path='various'>
-      <class-decl name='mmpin' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/skbuff.h' line='481' column='1' id='0009269e'>
+      <class-decl name='mmpin' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/skbuff.h' line='482' column='1' id='0009269e'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='user' type-id='273a7d34' visibility='default' filepath='include/linux/skbuff.h' line='482' column='1'/>
+          <var-decl name='user' type-id='273a7d34' visibility='default' filepath='include/linux/skbuff.h' line='483' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='num_pg' type-id='f0981eeb' visibility='default' filepath='include/linux/skbuff.h' line='483' column='1'/>
+          <var-decl name='num_pg' type-id='f0981eeb' visibility='default' filepath='include/linux/skbuff.h' line='484' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='b5b8ebc4' size-in-bits='64' id='001b67aa'/>
@@ -7322,7 +7454,7 @@
         <return type-id='48b5725f'/>
       </function-type>
       <qualified-type-def type-id='dbc7d793' const='yes' id='01863b98'/>
-      <enum-decl name='irqchip_irq_state' filepath='include/linux/interrupt.h' line='478' column='1' id='0187da1b'>
+      <enum-decl name='irqchip_irq_state' filepath='include/linux/interrupt.h' line='482' column='1' id='0187da1b'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='IRQCHIP_STATE_PENDING' value='0'/>
         <enumerator name='IRQCHIP_STATE_ACTIVE' value='1'/>
@@ -7446,15 +7578,15 @@
       </array-type-def>
       <pointer-type-def type-id='ffad938a' size-in-bits='64' id='01ffd89c'/>
       <pointer-type-def type-id='400ed05a' size-in-bits='64' id='0200a298'/>
-      <class-decl name='bpf_xdp_link' size-in-bits='768' is-struct='yes' visibility='default' filepath='net/core/dev.c' line='8994' column='1' id='0200d321'>
+      <class-decl name='bpf_xdp_link' size-in-bits='768' is-struct='yes' visibility='default' filepath='net/core/dev.c' line='9001' column='1' id='0200d321'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='link' type-id='e07e9784' visibility='default' filepath='net/core/dev.c' line='8995' column='1'/>
+          <var-decl name='link' type-id='e07e9784' visibility='default' filepath='net/core/dev.c' line='9002' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='dev' type-id='68a2d05b' visibility='default' filepath='net/core/dev.c' line='8996' column='1'/>
+          <var-decl name='dev' type-id='68a2d05b' visibility='default' filepath='net/core/dev.c' line='9003' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='flags' type-id='95e97e5e' visibility='default' filepath='net/core/dev.c' line='8997' column='1'/>
+          <var-decl name='flags' type-id='95e97e5e' visibility='default' filepath='net/core/dev.c' line='9004' column='1'/>
         </data-member>
       </class-decl>
       <array-type-def dimensions='1' type-id='8f048e17' size-in-bits='64' id='0209ab38'>
@@ -7828,71 +7960,71 @@
           <var-decl name='debug' type-id='e15671b8' visibility='default' filepath='include/drm/ttm/ttm_resource.h' line='98' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='softnet_data' size-in-bits='5632' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='3267' column='1' id='035aa62d'>
+      <class-decl name='softnet_data' size-in-bits='5632' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='3268' column='1' id='035aa62d'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='poll_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='3268' column='1'/>
+          <var-decl name='poll_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='3269' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='process_queue' type-id='e61c85d0' visibility='default' filepath='include/linux/netdevice.h' line='3269' column='1'/>
+          <var-decl name='process_queue' type-id='e61c85d0' visibility='default' filepath='include/linux/netdevice.h' line='3270' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='processed' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3272' column='1'/>
+          <var-decl name='processed' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3273' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='352'>
-          <var-decl name='time_squeeze' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3273' column='1'/>
+          <var-decl name='time_squeeze' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3274' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='received_rps' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3274' column='1'/>
+          <var-decl name='received_rps' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3275' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='rps_ipi_list' type-id='80c9c0cd' visibility='default' filepath='include/linux/netdevice.h' line='3276' column='1'/>
+          <var-decl name='rps_ipi_list' type-id='80c9c0cd' visibility='default' filepath='include/linux/netdevice.h' line='3277' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='flow_limit' type-id='4c83bbe7' visibility='default' filepath='include/linux/netdevice.h' line='3279' column='1'/>
+          <var-decl name='flow_limit' type-id='4c83bbe7' visibility='default' filepath='include/linux/netdevice.h' line='3280' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='output_queue' type-id='ee406209' visibility='default' filepath='include/linux/netdevice.h' line='3281' column='1'/>
+          <var-decl name='output_queue' type-id='ee406209' visibility='default' filepath='include/linux/netdevice.h' line='3282' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='output_queue_tailp' type-id='325a7d19' visibility='default' filepath='include/linux/netdevice.h' line='3282' column='1'/>
+          <var-decl name='output_queue_tailp' type-id='325a7d19' visibility='default' filepath='include/linux/netdevice.h' line='3283' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='completion_queue' type-id='0fbf3cfd' visibility='default' filepath='include/linux/netdevice.h' line='3283' column='1'/>
+          <var-decl name='completion_queue' type-id='0fbf3cfd' visibility='default' filepath='include/linux/netdevice.h' line='3284' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='xmit' type-id='75fc4829' visibility='default' filepath='include/linux/netdevice.h' line='3291' column='1'/>
+          <var-decl name='xmit' type-id='75fc4829' visibility='default' filepath='include/linux/netdevice.h' line='3292' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='input_queue_head' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3296' column='1'/>
+          <var-decl name='input_queue_head' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3297' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='csd' type-id='223a68bd' visibility='default' filepath='include/linux/netdevice.h' line='3299' column='1'/>
+          <var-decl name='csd' type-id='223a68bd' visibility='default' filepath='include/linux/netdevice.h' line='3300' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1792'>
-          <var-decl name='rps_ipi_next' type-id='80c9c0cd' visibility='default' filepath='include/linux/netdevice.h' line='3300' column='1'/>
+          <var-decl name='rps_ipi_next' type-id='80c9c0cd' visibility='default' filepath='include/linux/netdevice.h' line='3301' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1856'>
-          <var-decl name='cpu' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3301' column='1'/>
+          <var-decl name='cpu' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3302' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1888'>
-          <var-decl name='input_queue_tail' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3302' column='1'/>
+          <var-decl name='input_queue_tail' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3303' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1920'>
-          <var-decl name='dropped' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3304' column='1'/>
+          <var-decl name='dropped' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3305' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1984'>
-          <var-decl name='input_pkt_queue' type-id='e61c85d0' visibility='default' filepath='include/linux/netdevice.h' line='3305' column='1'/>
+          <var-decl name='input_pkt_queue' type-id='e61c85d0' visibility='default' filepath='include/linux/netdevice.h' line='3306' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2176'>
-          <var-decl name='backlog' type-id='291e3bb5' visibility='default' filepath='include/linux/netdevice.h' line='3306' column='1'/>
+          <var-decl name='backlog' type-id='291e3bb5' visibility='default' filepath='include/linux/netdevice.h' line='3307' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='netdev_bpf' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='927' column='1' id='0360a184'>
+      <class-decl name='netdev_bpf' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='932' column='1' id='0360a184'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='command' type-id='fa64b30d' visibility='default' filepath='include/linux/netdevice.h' line='928' column='1'/>
+          <var-decl name='command' type-id='fa64b30d' visibility='default' filepath='include/linux/netdevice.h' line='933' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='' type-id='814b2a03' visibility='default' filepath='include/linux/netdevice.h' line='929' column='1'/>
+          <var-decl name='' type-id='814b2a03' visibility='default' filepath='include/linux/netdevice.h' line='934' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='f2c03b9b' size-in-bits='64' id='03676ee7'/>
@@ -8201,7 +8333,7 @@
           <var-decl name='no_retry' type-id='b50a4934' visibility='default' filepath='include/drm/ttm/ttm_bo_driver.h' line='352' column='1'/>
         </data-member>
       </class-decl>
-      <enum-decl name='dwc3_ep0_state' filepath='drivers/usb/dwc3/core.h' line='781' column='1' id='045093ad'>
+      <enum-decl name='dwc3_ep0_state' filepath='drivers/usb/dwc3/core.h' line='782' column='1' id='045093ad'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='EP0_UNCONNECTED' value='0'/>
         <enumerator name='EP0_SETUP_PHASE' value='1'/>
@@ -8415,12 +8547,12 @@
       <array-type-def dimensions='1' type-id='8f048e17' size-in-bits='1600' id='0530f1a6'>
         <subrange length='200' type-id='7ff19f0f' id='53119c2f'/>
       </array-type-def>
-      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/tty.h' line='60' column='1' id='053892cc'>
+      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/tty.h' line='36' column='1' id='053892cc'>
         <data-member access='public'>
-          <var-decl name='next' type-id='a150e667' visibility='default' filepath='include/linux/tty.h' line='61' column='1'/>
+          <var-decl name='next' type-id='a150e667' visibility='default' filepath='include/linux/tty.h' line='37' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='free' type-id='c5ccfee8' visibility='default' filepath='include/linux/tty.h' line='62' column='1'/>
+          <var-decl name='free' type-id='c5ccfee8' visibility='default' filepath='include/linux/tty.h' line='38' column='1'/>
         </data-member>
       </union-decl>
       <class-decl name='tty_ldisc_ops' size-in-bits='1344' is-struct='yes' visibility='default' filepath='include/linux/tty_ldisc.h' line='176' column='1' id='053f72e5'>
@@ -8684,12 +8816,12 @@
         <parameter type-id='95e97e5e'/>
         <return type-id='95e97e5e'/>
       </function-type>
-      <class-decl name='bpf_xdp_entity' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='922' column='1' id='05d9ea82'>
+      <class-decl name='bpf_xdp_entity' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='927' column='1' id='05d9ea82'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='prog' type-id='bdcee7ae' visibility='default' filepath='include/linux/netdevice.h' line='923' column='1'/>
+          <var-decl name='prog' type-id='bdcee7ae' visibility='default' filepath='include/linux/netdevice.h' line='928' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='link' type-id='122b01f9' visibility='default' filepath='include/linux/netdevice.h' line='924' column='1'/>
+          <var-decl name='link' type-id='122b01f9' visibility='default' filepath='include/linux/netdevice.h' line='929' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='96c81365' size-in-bits='64' id='05dc2175'/>
@@ -9380,12 +9512,12 @@
         <parameter type-id='cfff5953'/>
         <return type-id='48b5725f'/>
       </function-type>
-      <class-decl name='usb2_lpm_parameters' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='518' column='1' id='07c4f5ca'>
+      <class-decl name='usb2_lpm_parameters' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='523' column='1' id='07c4f5ca'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='besl' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='522' column='1'/>
+          <var-decl name='besl' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='527' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='timeout' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='528' column='1'/>
+          <var-decl name='timeout' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='533' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='07c62f88'>
@@ -9400,9 +9532,9 @@
         <return type-id='48b5725f'/>
       </function-type>
       <function-type size-in-bits='64' id='07cce116'>
-        <parameter type-id='723d4d79' name='bdev'/>
-        <parameter type-id='c21baddd' name='ttm'/>
-        <parameter type-id='7c3e509a' name='ctx'/>
+        <parameter type-id='723d4d79'/>
+        <parameter type-id='c21baddd'/>
+        <parameter type-id='7c3e509a'/>
         <return type-id='95e97e5e'/>
       </function-type>
       <pointer-type-def type-id='fc87d78f' size-in-bits='64' id='07d0a3e7'/>
@@ -9704,6 +9836,41 @@
       <array-type-def dimensions='1' type-id='19c2251e' size-in-bits='1920' id='08b4ad9f'>
         <subrange length='60' type-id='7ff19f0f' id='b114e3c3'/>
       </array-type-def>
+      <class-decl name='oom_control' size-in-bits='640' is-struct='yes' visibility='default' filepath='include/linux/oom.h' line='29' column='1' id='08b65638'>
+        <data-member access='public' layout-offset-in-bits='0'>
+          <var-decl name='zonelist' type-id='8d55c7ff' visibility='default' filepath='include/linux/oom.h' line='31' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='64'>
+          <var-decl name='nodemask' type-id='f461c050' visibility='default' filepath='include/linux/oom.h' line='34' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='128'>
+          <var-decl name='memcg' type-id='223696fb' visibility='default' filepath='include/linux/oom.h' line='37' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='192'>
+          <var-decl name='gfp_mask' type-id='96d7cfec' visibility='default' filepath='include/linux/oom.h' line='40' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='224'>
+          <var-decl name='order' type-id='2448a865' visibility='default' filepath='include/linux/oom.h' line='46' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='256'>
+          <var-decl name='totalpages' type-id='7359adad' visibility='default' filepath='include/linux/oom.h' line='49' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='320'>
+          <var-decl name='chosen' type-id='f23e2572' visibility='default' filepath='include/linux/oom.h' line='50' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='384'>
+          <var-decl name='chosen_points' type-id='bd54fe1a' visibility='default' filepath='include/linux/oom.h' line='51' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='448'>
+          <var-decl name='chosen_non_negative_adj' type-id='f23e2572' visibility='default' filepath='include/linux/oom.h' line='52' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='512'>
+          <var-decl name='chosen_non_negative_adj_points' type-id='bd54fe1a' visibility='default' filepath='include/linux/oom.h' line='53' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='576'>
+          <var-decl name='constraint' type-id='5bc89d69' visibility='default' filepath='include/linux/oom.h' line='56' column='1'/>
+        </data-member>
+      </class-decl>
       <function-type size-in-bits='64' id='08bcc9e6'>
         <parameter type-id='0343ce83'/>
         <parameter type-id='0343ce83'/>
@@ -9855,7 +10022,7 @@
       </class-decl>
       <pointer-type-def type-id='4ca0c298' size-in-bits='64' id='08e531de'/>
       <pointer-type-def type-id='195ce0ad' size-in-bits='64' id='08ed88d1'/>
-      <enum-decl name='__anonymous_enum__' is-anonymous='yes' filepath='include/linux/netdevice.h' line='2139' column='1' id='08f5ca17'>
+      <enum-decl name='__anonymous_enum__' is-anonymous='yes' filepath='include/linux/netdevice.h' line='2140' column='1' id='08f5ca17'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='NETREG_UNINITIALIZED' value='0'/>
         <enumerator name='NETREG_REGISTERED' value='1'/>
@@ -9864,7 +10031,7 @@
         <enumerator name='NETREG_RELEASED' value='4'/>
         <enumerator name='NETREG_DUMMY' value='5'/>
       </enum-decl>
-      <enum-decl name='__anonymous_enum__' is-anonymous='yes' filepath='include/linux/netdevice.h' line='2149' column='1' id='08f5ca18'>
+      <enum-decl name='__anonymous_enum__' is-anonymous='yes' filepath='include/linux/netdevice.h' line='2150' column='1' id='08f5ca18'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='RTNL_LINK_INITIALIZED' value='0'/>
         <enumerator name='RTNL_LINK_INITIALIZING' value='1'/>
@@ -10603,14 +10770,14 @@
         <return type-id='48b5725f'/>
       </function-type>
       <pointer-type-def type-id='4e8a6f85' size-in-bits='64' id='0a0775b5'/>
-      <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' naming-typedef-id='c9df1e6c' visibility='default' filepath='include/net/net_namespace.h' line='321' column='1' id='0a0aec0a'>
+      <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' naming-typedef-id='c9df1e6c' visibility='default' filepath='include/net/net_namespace.h' line='319' column='1' id='0a0aec0a'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='net' type-id='a2bff676' visibility='default' filepath='include/net/net_namespace.h' line='323' column='1'/>
+          <var-decl name='net' type-id='a2bff676' visibility='default' filepath='include/net/net_namespace.h' line='321' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='be9189df' size-in-bits='64' id='0a0aff97'/>
       <pointer-type-def type-id='fd1f8b7c' size-in-bits='64' id='0a18715a'/>
-      <enum-decl name='typec_port_type' filepath='include/linux/usb/typec.h' line='25' column='1' id='0a19b04e'>
+      <enum-decl name='typec_port_type' filepath='include/linux/usb/typec.h' line='26' column='1' id='0a19b04e'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='TYPEC_PORT_SRC' value='0'/>
         <enumerator name='TYPEC_PORT_SNK' value='1'/>
@@ -10699,13 +10866,13 @@
           <var-decl name='hooks_arp' type-id='d82cf371' visibility='default' filepath='include/net/netns/netfilter.h' line='24' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1856'>
-          <var-decl name='defrag_ipv4' type-id='b50a4934' visibility='default' filepath='include/net/netns/netfilter.h' line='33' column='1'/>
+          <var-decl name='defrag_ipv4' type-id='b50a4934' visibility='default' filepath='include/net/netns/netfilter.h' line='30' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1864'>
-          <var-decl name='defrag_ipv6' type-id='b50a4934' visibility='default' filepath='include/net/netns/netfilter.h' line='36' column='1'/>
+          <var-decl name='defrag_ipv6' type-id='b50a4934' visibility='default' filepath='include/net/netns/netfilter.h' line='33' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1920'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/net/netns/netfilter.h' line='39' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/net/netns/netfilter.h' line='36' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='0a77e414'>
@@ -12040,6 +12207,7 @@
         <parameter type-id='6dcf57f3'/>
         <return type-id='95e97e5e'/>
       </function-type>
+      <pointer-type-def type-id='3572f41a' size-in-bits='64' id='0e64a118'/>
       <array-type-def dimensions='1' type-id='e710f78e' size-in-bits='576' id='0e685653'>
         <subrange length='3' type-id='7ff19f0f' id='56f209d2'/>
       </array-type-def>
@@ -12101,18 +12269,18 @@
           <var-decl name='icmpv6msgdev' type-id='793f0d19' visibility='default' filepath='include/net/if_inet6.h' line='168' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='ipv6_rt_hdr' size-in-bits='32' is-struct='yes' visibility='default' filepath='include/uapi/linux/ipv6.h' line='49' column='1' id='0eae882e'>
+      <class-decl name='ipv6_rt_hdr' size-in-bits='32' is-struct='yes' visibility='default' filepath='include/uapi/linux/ipv6.h' line='50' column='1' id='0eae882e'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='nexthdr' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ipv6.h' line='50' column='1'/>
+          <var-decl name='nexthdr' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ipv6.h' line='51' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8'>
-          <var-decl name='hdrlen' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ipv6.h' line='51' column='1'/>
+          <var-decl name='hdrlen' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ipv6.h' line='52' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='16'>
-          <var-decl name='type' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ipv6.h' line='52' column='1'/>
+          <var-decl name='type' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ipv6.h' line='53' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='24'>
-          <var-decl name='segments_left' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ipv6.h' line='53' column='1'/>
+          <var-decl name='segments_left' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ipv6.h' line='54' column='1'/>
         </data-member>
       </class-decl>
       <typedef-decl name='mm_context_t' type-id='c9e2b4ad' filepath='arch/arm64/include/asm/mmu.h' line='27' column='1' id='0eb9c3fd'/>
@@ -12194,18 +12362,18 @@
         <parameter type-id='d9863f2f'/>
         <return type-id='48b5725f'/>
       </function-type>
-      <class-decl name='__anonymous_struct__' size-in-bits='96' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='472' column='1' id='0efb3709'>
+      <class-decl name='__anonymous_struct__' size-in-bits='96' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='473' column='1' id='0efb3709'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='id' type-id='19c2251e' visibility='default' filepath='include/linux/skbuff.h' line='473' column='1'/>
+          <var-decl name='id' type-id='19c2251e' visibility='default' filepath='include/linux/skbuff.h' line='474' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='len' type-id='1dc6a898' visibility='default' filepath='include/linux/skbuff.h' line='474' column='1'/>
+          <var-decl name='len' type-id='1dc6a898' visibility='default' filepath='include/linux/skbuff.h' line='475' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='zerocopy' type-id='1dc6a898' visibility='default' filepath='include/linux/skbuff.h' line='475' column='1'/>
+          <var-decl name='zerocopy' type-id='1dc6a898' visibility='default' filepath='include/linux/skbuff.h' line='476' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='bytelen' type-id='19c2251e' visibility='default' filepath='include/linux/skbuff.h' line='476' column='1'/>
+          <var-decl name='bytelen' type-id='19c2251e' visibility='default' filepath='include/linux/skbuff.h' line='477' column='1'/>
         </data-member>
       </class-decl>
       <union-decl name='__anonymous_union__' size-in-bits='128' is-anonymous='yes' visibility='default' filepath='include/uapi/linux/in6.h' line='34' column='1' id='0efc37b8'>
@@ -12605,24 +12773,24 @@
       </function-type>
       <pointer-type-def type-id='bd4974e4' size-in-bits='64' id='100f2106'/>
       <qualified-type-def type-id='78e57306' const='yes' id='10117043'/>
-      <class-decl name='trace_subsystem_dir' size-in-bits='384' is-struct='yes' visibility='default' filepath='kernel/trace/trace.h' line='1440' column='1' id='10143522'>
+      <class-decl name='trace_subsystem_dir' size-in-bits='384' is-struct='yes' visibility='default' filepath='kernel/trace/trace.h' line='1441' column='1' id='10143522'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='kernel/trace/trace.h' line='1441' column='1'/>
+          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='kernel/trace/trace.h' line='1442' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='subsystem' type-id='841939f3' visibility='default' filepath='kernel/trace/trace.h' line='1442' column='1'/>
+          <var-decl name='subsystem' type-id='841939f3' visibility='default' filepath='kernel/trace/trace.h' line='1443' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='tr' type-id='898c1076' visibility='default' filepath='kernel/trace/trace.h' line='1443' column='1'/>
+          <var-decl name='tr' type-id='898c1076' visibility='default' filepath='kernel/trace/trace.h' line='1444' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='entry' type-id='27675065' visibility='default' filepath='kernel/trace/trace.h' line='1444' column='1'/>
+          <var-decl name='entry' type-id='27675065' visibility='default' filepath='kernel/trace/trace.h' line='1445' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='ref_count' type-id='95e97e5e' visibility='default' filepath='kernel/trace/trace.h' line='1445' column='1'/>
+          <var-decl name='ref_count' type-id='95e97e5e' visibility='default' filepath='kernel/trace/trace.h' line='1446' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='352'>
-          <var-decl name='nr_events' type-id='95e97e5e' visibility='default' filepath='kernel/trace/trace.h' line='1446' column='1'/>
+          <var-decl name='nr_events' type-id='95e97e5e' visibility='default' filepath='kernel/trace/trace.h' line='1447' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='v4l2_frmsize_discrete' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/uapi/linux/videodev2.h' line='814' column='1' id='10186cf6'>
@@ -12639,21 +12807,21 @@
           <var-decl name='frame_sequence' type-id='3f1a6b60' visibility='default' filepath='include/uapi/linux/videodev2.h' line='2366' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='pcpu_sw_netstats' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='2628' column='1' id='101eeec5'>
+      <class-decl name='pcpu_sw_netstats' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='2629' column='1' id='101eeec5'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='rx_packets' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2629' column='1'/>
+          <var-decl name='rx_packets' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2630' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='rx_bytes' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2630' column='1'/>
+          <var-decl name='rx_bytes' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2631' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='tx_packets' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2631' column='1'/>
+          <var-decl name='tx_packets' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2632' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='tx_bytes' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2632' column='1'/>
+          <var-decl name='tx_bytes' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2633' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='syncp' type-id='e4d85780' visibility='default' filepath='include/linux/netdevice.h' line='2633' column='1'/>
+          <var-decl name='syncp' type-id='e4d85780' visibility='default' filepath='include/linux/netdevice.h' line='2634' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='b5990c25' size-in-bits='64' id='10216dc5'/>
@@ -12666,48 +12834,48 @@
       <qualified-type-def type-id='852a961e' const='yes' id='1027eea9'/>
       <pointer-type-def type-id='c01f4982' size-in-bits='64' id='102ab76c'/>
       <pointer-type-def type-id='6e03f2ca' size-in-bits='64' id='103756a0'/>
-      <class-decl name='extcon_cable' size-in-bits='1664' is-struct='yes' visibility='default' filepath='drivers/extcon/extcon.c' line='200' column='1' id='103b4c26'>
+      <class-decl name='extcon_cable' size-in-bits='1664' is-struct='yes' visibility='default' filepath='drivers/extcon/extcon.c' line='208' column='1' id='103b4c26'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='edev' type-id='c0d6fada' visibility='default' filepath='drivers/extcon/extcon.c' line='201' column='1'/>
+          <var-decl name='edev' type-id='c0d6fada' visibility='default' filepath='drivers/extcon/extcon.c' line='209' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='cable_index' type-id='95e97e5e' visibility='default' filepath='drivers/extcon/extcon.c' line='202' column='1'/>
+          <var-decl name='cable_index' type-id='95e97e5e' visibility='default' filepath='drivers/extcon/extcon.c' line='210' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='attr_g' type-id='e4af473b' visibility='default' filepath='drivers/extcon/extcon.c' line='204' column='1'/>
+          <var-decl name='attr_g' type-id='e4af473b' visibility='default' filepath='drivers/extcon/extcon.c' line='212' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='attr_name' type-id='dbf3947c' visibility='default' filepath='drivers/extcon/extcon.c' line='205' column='1'/>
+          <var-decl name='attr_name' type-id='dbf3947c' visibility='default' filepath='drivers/extcon/extcon.c' line='213' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='attr_state' type-id='dbf3947c' visibility='default' filepath='drivers/extcon/extcon.c' line='206' column='1'/>
+          <var-decl name='attr_state' type-id='dbf3947c' visibility='default' filepath='drivers/extcon/extcon.c' line='214' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='attrs' type-id='ff62a050' visibility='default' filepath='drivers/extcon/extcon.c' line='208' column='1'/>
+          <var-decl name='attrs' type-id='ff62a050' visibility='default' filepath='drivers/extcon/extcon.c' line='216' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='usb_propval' type-id='475a4bff' visibility='default' filepath='drivers/extcon/extcon.c' line='210' column='1'/>
+          <var-decl name='usb_propval' type-id='475a4bff' visibility='default' filepath='drivers/extcon/extcon.c' line='218' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1248'>
-          <var-decl name='chg_propval' type-id='0b5e6ab9' visibility='default' filepath='drivers/extcon/extcon.c' line='211' column='1'/>
+          <var-decl name='chg_propval' type-id='0b5e6ab9' visibility='default' filepath='drivers/extcon/extcon.c' line='219' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1280'>
-          <var-decl name='jack_propval' type-id='0b5e6ab9' visibility='default' filepath='drivers/extcon/extcon.c' line='212' column='1'/>
+          <var-decl name='jack_propval' type-id='0b5e6ab9' visibility='default' filepath='drivers/extcon/extcon.c' line='220' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1312'>
-          <var-decl name='disp_propval' type-id='0b5c2c22' visibility='default' filepath='drivers/extcon/extcon.c' line='213' column='1'/>
+          <var-decl name='disp_propval' type-id='0b5c2c22' visibility='default' filepath='drivers/extcon/extcon.c' line='221' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1408'>
-          <var-decl name='usb_bits' type-id='f066dd3c' visibility='default' filepath='drivers/extcon/extcon.c' line='215' column='1'/>
+          <var-decl name='usb_bits' type-id='f066dd3c' visibility='default' filepath='drivers/extcon/extcon.c' line='223' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1472'>
-          <var-decl name='chg_bits' type-id='f066dd3c' visibility='default' filepath='drivers/extcon/extcon.c' line='216' column='1'/>
+          <var-decl name='chg_bits' type-id='f066dd3c' visibility='default' filepath='drivers/extcon/extcon.c' line='224' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='jack_bits' type-id='f066dd3c' visibility='default' filepath='drivers/extcon/extcon.c' line='217' column='1'/>
+          <var-decl name='jack_bits' type-id='f066dd3c' visibility='default' filepath='drivers/extcon/extcon.c' line='225' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1600'>
-          <var-decl name='disp_bits' type-id='f066dd3c' visibility='default' filepath='drivers/extcon/extcon.c' line='218' column='1'/>
+          <var-decl name='disp_bits' type-id='f066dd3c' visibility='default' filepath='drivers/extcon/extcon.c' line='226' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='103ba521'>
@@ -12746,15 +12914,15 @@
         <subrange length='8' type-id='7ff19f0f' id='56e0c0b1'/>
       </array-type-def>
       <pointer-type-def type-id='1dad932c' size-in-bits='64' id='1065554a'/>
-      <class-decl name='posix_cputimers' size-in-bits='640' is-struct='yes' visibility='default' filepath='include/linux/posix-timers.h' line='123' column='1' id='1069de27'>
+      <class-decl name='posix_cputimers' size-in-bits='640' is-struct='yes' visibility='default' filepath='include/linux/posix-timers.h' line='126' column='1' id='1069de27'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='bases' type-id='0e685653' visibility='default' filepath='include/linux/posix-timers.h' line='124' column='1'/>
+          <var-decl name='bases' type-id='0e685653' visibility='default' filepath='include/linux/posix-timers.h' line='127' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='timers_active' type-id='f0981eeb' visibility='default' filepath='include/linux/posix-timers.h' line='125' column='1'/>
+          <var-decl name='timers_active' type-id='f0981eeb' visibility='default' filepath='include/linux/posix-timers.h' line='128' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='608'>
-          <var-decl name='expiry_active' type-id='f0981eeb' visibility='default' filepath='include/linux/posix-timers.h' line='126' column='1'/>
+          <var-decl name='expiry_active' type-id='f0981eeb' visibility='default' filepath='include/linux/posix-timers.h' line='129' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='ff_periodic_effect' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/uapi/linux/input.h' line='401' column='1' id='106cd915'>
@@ -13627,12 +13795,12 @@
         <parameter type-id='eaa32e2f'/>
         <return type-id='48b5725f'/>
       </function-type>
-      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='725' column='1' id='1285aa79'>
+      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='727' column='1' id='1285aa79'>
         <data-member access='public'>
-          <var-decl name='dev' type-id='68a2d05b' visibility='default' filepath='include/linux/skbuff.h' line='726' column='1'/>
+          <var-decl name='dev' type-id='68a2d05b' visibility='default' filepath='include/linux/skbuff.h' line='728' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='dev_scratch' type-id='7359adad' visibility='default' filepath='include/linux/skbuff.h' line='731' column='1'/>
+          <var-decl name='dev_scratch' type-id='7359adad' visibility='default' filepath='include/linux/skbuff.h' line='733' column='1'/>
         </data-member>
       </union-decl>
       <class-decl name='xfrm_state_walk' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/net/xfrm.h' line='120' column='1' id='12872440'>
@@ -13911,7 +14079,7 @@
       </function-type>
       <pointer-type-def type-id='ee14fd94' size-in-bits='64' id='13103032'/>
       <pointer-type-def type-id='1a7fa4c7' size-in-bits='64' id='1314e51b'/>
-      <enum-decl name='typec_orientation' filepath='include/linux/usb/typec.h' line='70' column='1' id='131b0a9c'>
+      <enum-decl name='typec_orientation' filepath='include/linux/usb/typec.h' line='71' column='1' id='131b0a9c'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='TYPEC_ORIENTATION_NONE' value='0'/>
         <enumerator name='TYPEC_ORIENTATION_NORMAL' value='1'/>
@@ -14603,12 +14771,12 @@
       <pointer-type-def type-id='1c210187' size-in-bits='64' id='149deb03'/>
       <pointer-type-def type-id='34072a4b' size-in-bits='64' id='149f0e1f'/>
       <pointer-type-def type-id='b4a65d38' size-in-bits='64' id='14a0013e'/>
-      <class-decl name='netdev_phys_item_id' size-in-bits='264' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='853' column='1' id='14a30316'>
+      <class-decl name='netdev_phys_item_id' size-in-bits='264' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='858' column='1' id='14a30316'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='id' type-id='fc872715' visibility='default' filepath='include/linux/netdevice.h' line='854' column='1'/>
+          <var-decl name='id' type-id='fc872715' visibility='default' filepath='include/linux/netdevice.h' line='859' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='id_len' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='855' column='1'/>
+          <var-decl name='id_len' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='860' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='5049bff3' size-in-bits='64' id='14a7c87f'/>
@@ -14752,7 +14920,7 @@
         <return type-id='48b5725f'/>
       </function-type>
       <pointer-type-def type-id='2b7b3388' size-in-bits='64' id='14f24806'/>
-      <class-decl name='anon_vma' size-in-bits='832' is-struct='yes' visibility='default' filepath='include/linux/rmap.h' line='33' column='1' id='14f332cc'>
+      <class-decl name='anon_vma' size-in-bits='960' is-struct='yes' visibility='default' filepath='include/linux/rmap.h' line='33' column='1' id='14f332cc'>
         <data-member access='public' layout-offset-in-bits='0'>
           <var-decl name='root' type-id='a8f86cda' visibility='default' filepath='include/linux/rmap.h' line='34' column='1'/>
         </data-member>
@@ -14763,13 +14931,19 @@
           <var-decl name='refcount' type-id='49178f86' visibility='default' filepath='include/linux/rmap.h' line='43' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='608'>
-          <var-decl name='degree' type-id='f0981eeb' visibility='default' filepath='include/linux/rmap.h' line='51' column='1'/>
+          <var-decl name='degree' type-id='f0981eeb' visibility='default' filepath='include/linux/rmap.h' line='45' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='parent' type-id='a8f86cda' visibility='default' filepath='include/linux/rmap.h' line='53' column='1'/>
+          <var-decl name='parent' type-id='a8f86cda' visibility='default' filepath='include/linux/rmap.h' line='47' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='rb_root' type-id='6fe1603d' visibility='default' filepath='include/linux/rmap.h' line='65' column='1'/>
+          <var-decl name='rb_root' type-id='6fe1603d' visibility='default' filepath='include/linux/rmap.h' line='59' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='832'>
+          <var-decl name='num_children' type-id='7359adad' visibility='default' filepath='include/linux/rmap.h' line='74' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='896'>
+          <var-decl name='num_active_vmas' type-id='7359adad' visibility='default' filepath='include/linux/rmap.h' line='76' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='031a4ff0' size-in-bits='64' id='1507ee2a'/>
@@ -14971,37 +15145,12 @@
       </class-decl>
       <pointer-type-def type-id='bc51cf2c' size-in-bits='64' id='156433b6'/>
       <pointer-type-def type-id='61a50456' size-in-bits='64' id='156888c8'/>
-      <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='924' column='1' id='156952c4'>
+      <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/sched.h' line='1380' column='1' id='156952c4'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/skbuff.h' line='924' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1380' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='io_uring_task' size-in-bits='1408' is-struct='yes' visibility='default' filepath='include/linux/io_uring.h' line='25' column='1' id='156a7d89'>
-        <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='xa' type-id='d39738ac' visibility='default' filepath='include/linux/io_uring.h' line='27' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='wait' type-id='cff07063' visibility='default' filepath='include/linux/io_uring.h' line='28' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='last' type-id='77e79a4b' visibility='default' filepath='include/linux/io_uring.h' line='29' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='inflight' type-id='b92c8d0d' visibility='default' filepath='include/linux/io_uring.h' line='30' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='__identity' type-id='50ac43c8' visibility='default' filepath='include/linux/io_uring.h' line='31' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='1280'>
-          <var-decl name='identity' type-id='8a1be3fe' visibility='default' filepath='include/linux/io_uring.h' line='32' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='1344'>
-          <var-decl name='in_idle' type-id='49178f86' visibility='default' filepath='include/linux/io_uring.h' line='33' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='1376'>
-          <var-decl name='sqpoll' type-id='b50a4934' visibility='default' filepath='include/linux/io_uring.h' line='34' column='1'/>
-        </data-member>
-      </class-decl>
+      <class-decl name='io_uring_task' is-struct='yes' visibility='default' is-declaration-only='yes' id='156a7d89'/>
       <enum-decl name='migrate_mode' filepath='include/linux/migrate_mode.h' line='15' column='1' id='157252dd'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='MIGRATE_ASYNC' value='0'/>
@@ -15172,45 +15321,45 @@
         <parameter type-id='0fbf3cfd'/>
         <return type-id='48b5725f'/>
       </function-type>
-      <class-decl name='packet_type' size-in-bits='832' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='2589' column='1' id='164a08b2'>
+      <class-decl name='packet_type' size-in-bits='832' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='2590' column='1' id='164a08b2'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='type' type-id='84a5c3d4' visibility='default' filepath='include/linux/netdevice.h' line='2590' column='1'/>
+          <var-decl name='type' type-id='84a5c3d4' visibility='default' filepath='include/linux/netdevice.h' line='2591' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='16'>
-          <var-decl name='ignore_outgoing' type-id='b50a4934' visibility='default' filepath='include/linux/netdevice.h' line='2591' column='1'/>
+          <var-decl name='ignore_outgoing' type-id='b50a4934' visibility='default' filepath='include/linux/netdevice.h' line='2592' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='dev' type-id='68a2d05b' visibility='default' filepath='include/linux/netdevice.h' line='2592' column='1'/>
+          <var-decl name='dev' type-id='68a2d05b' visibility='default' filepath='include/linux/netdevice.h' line='2593' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='func' type-id='29242f3e' visibility='default' filepath='include/linux/netdevice.h' line='2593' column='1'/>
+          <var-decl name='func' type-id='29242f3e' visibility='default' filepath='include/linux/netdevice.h' line='2594' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='list_func' type-id='af0e0afc' visibility='default' filepath='include/linux/netdevice.h' line='2597' column='1'/>
+          <var-decl name='list_func' type-id='af0e0afc' visibility='default' filepath='include/linux/netdevice.h' line='2598' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='id_match' type-id='ca97eb2a' visibility='default' filepath='include/linux/netdevice.h' line='2600' column='1'/>
+          <var-decl name='id_match' type-id='ca97eb2a' visibility='default' filepath='include/linux/netdevice.h' line='2601' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='af_packet_net' type-id='a2bff676' visibility='default' filepath='include/linux/netdevice.h' line='2602' column='1'/>
+          <var-decl name='af_packet_net' type-id='a2bff676' visibility='default' filepath='include/linux/netdevice.h' line='2603' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='af_packet_priv' type-id='eaa32e2f' visibility='default' filepath='include/linux/netdevice.h' line='2603' column='1'/>
+          <var-decl name='af_packet_priv' type-id='eaa32e2f' visibility='default' filepath='include/linux/netdevice.h' line='2604' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='2604' column='1'/>
+          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='2605' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2606' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2607' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2607' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2608' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2608' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2609' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2609' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2610' column='1'/>
         </data-member>
       </class-decl>
       <union-decl name='__anonymous_union__' size-in-bits='384' is-anonymous='yes' visibility='default' filepath='include/net/flow_offload.h' line='202' column='1' id='164b6d73'>
@@ -16441,12 +16590,12 @@
           <var-decl name='fsx_pad' type-id='491d0410' visibility='default' filepath='include/uapi/linux/fs.h' line='121' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='__anonymous_struct__' size-in-bits='256' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/netdevice.h' line='1940' column='1' id='19245258'>
+      <class-decl name='__anonymous_struct__' size-in-bits='256' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/netdevice.h' line='1944' column='1' id='19245258'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='upper' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1941' column='1'/>
+          <var-decl name='upper' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1945' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='lower' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1942' column='1'/>
+          <var-decl name='lower' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1946' column='1'/>
         </data-member>
       </class-decl>
       <qualified-type-def type-id='f9b06939' const='yes' id='19272f09'/>
@@ -17254,69 +17403,69 @@
           <var-decl name='base' type-id='58ba85d8' visibility='default' filepath='include/crypto/internal/hash.h' line='59' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='usb_driver' size-in-bits='2688' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='1207' column='1' id='1ab3428c'>
+      <class-decl name='usb_driver' size-in-bits='2688' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='1215' column='1' id='1ab3428c'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='name' type-id='80f4b756' visibility='default' filepath='include/linux/usb.h' line='1208' column='1'/>
+          <var-decl name='name' type-id='80f4b756' visibility='default' filepath='include/linux/usb.h' line='1216' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='probe' type-id='a324decb' visibility='default' filepath='include/linux/usb.h' line='1210' column='1'/>
+          <var-decl name='probe' type-id='a324decb' visibility='default' filepath='include/linux/usb.h' line='1218' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='disconnect' type-id='b6566954' visibility='default' filepath='include/linux/usb.h' line='1213' column='1'/>
+          <var-decl name='disconnect' type-id='b6566954' visibility='default' filepath='include/linux/usb.h' line='1221' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='unlocked_ioctl' type-id='52006477' visibility='default' filepath='include/linux/usb.h' line='1215' column='1'/>
+          <var-decl name='unlocked_ioctl' type-id='52006477' visibility='default' filepath='include/linux/usb.h' line='1223' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='suspend' type-id='31eb8cc0' visibility='default' filepath='include/linux/usb.h' line='1218' column='1'/>
+          <var-decl name='suspend' type-id='31eb8cc0' visibility='default' filepath='include/linux/usb.h' line='1226' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='resume' type-id='46d1c941' visibility='default' filepath='include/linux/usb.h' line='1219' column='1'/>
+          <var-decl name='resume' type-id='46d1c941' visibility='default' filepath='include/linux/usb.h' line='1227' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='reset_resume' type-id='46d1c941' visibility='default' filepath='include/linux/usb.h' line='1220' column='1'/>
+          <var-decl name='reset_resume' type-id='46d1c941' visibility='default' filepath='include/linux/usb.h' line='1228' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='pre_reset' type-id='46d1c941' visibility='default' filepath='include/linux/usb.h' line='1222' column='1'/>
+          <var-decl name='pre_reset' type-id='46d1c941' visibility='default' filepath='include/linux/usb.h' line='1230' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='post_reset' type-id='46d1c941' visibility='default' filepath='include/linux/usb.h' line='1223' column='1'/>
+          <var-decl name='post_reset' type-id='46d1c941' visibility='default' filepath='include/linux/usb.h' line='1231' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='id_table' type-id='bc57058f' visibility='default' filepath='include/linux/usb.h' line='1225' column='1'/>
+          <var-decl name='id_table' type-id='bc57058f' visibility='default' filepath='include/linux/usb.h' line='1233' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='dev_groups' type-id='c97de1ac' visibility='default' filepath='include/linux/usb.h' line='1226' column='1'/>
+          <var-decl name='dev_groups' type-id='c97de1ac' visibility='default' filepath='include/linux/usb.h' line='1234' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='dynids' type-id='cb08bae1' visibility='default' filepath='include/linux/usb.h' line='1228' column='1'/>
+          <var-decl name='dynids' type-id='cb08bae1' visibility='default' filepath='include/linux/usb.h' line='1236' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='drvwrap' type-id='33780378' visibility='default' filepath='include/linux/usb.h' line='1229' column='1'/>
+          <var-decl name='drvwrap' type-id='33780378' visibility='default' filepath='include/linux/usb.h' line='1237' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='no_dynamic_id' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1230' column='1'/>
+          <var-decl name='no_dynamic_id' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1238' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1'>
-          <var-decl name='supports_autosuspend' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1231' column='1'/>
+          <var-decl name='supports_autosuspend' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1239' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2'>
-          <var-decl name='disable_hub_initiated_lpm' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1232' column='1'/>
+          <var-decl name='disable_hub_initiated_lpm' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1240' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3'>
-          <var-decl name='soft_unbind' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1233' column='1'/>
+          <var-decl name='soft_unbind' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1241' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2432'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1235' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1243' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2496'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1236' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1244' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2560'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1237' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1245' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2624'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1238' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1246' column='1'/>
         </data-member>
       </class-decl>
       <typedef-decl name='seqcount_ww_mutex_t' type-id='b7e534b2' filepath='include/linux/seqlock.h' line='280' column='1' id='1abc0b16'/>
@@ -17340,18 +17489,18 @@
       </enum-decl>
       <pointer-type-def type-id='83ac033d' size-in-bits='64' id='1ac0dc69'/>
       <qualified-type-def type-id='1f03d7fe' const='yes' id='1ac45f89'/>
-      <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/sysctl.h' line='133' column='1' id='1acab550'>
+      <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/sysctl.h' line='143' column='1' id='1acab550'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='ctl_table' type-id='631dc3c1' visibility='default' filepath='include/linux/sysctl.h' line='134' column='1'/>
+          <var-decl name='ctl_table' type-id='631dc3c1' visibility='default' filepath='include/linux/sysctl.h' line='144' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='used' type-id='95e97e5e' visibility='default' filepath='include/linux/sysctl.h' line='135' column='1'/>
+          <var-decl name='used' type-id='95e97e5e' visibility='default' filepath='include/linux/sysctl.h' line='145' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='count' type-id='95e97e5e' visibility='default' filepath='include/linux/sysctl.h' line='136' column='1'/>
+          <var-decl name='count' type-id='95e97e5e' visibility='default' filepath='include/linux/sysctl.h' line='146' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='nreg' type-id='95e97e5e' visibility='default' filepath='include/linux/sysctl.h' line='137' column='1'/>
+          <var-decl name='nreg' type-id='95e97e5e' visibility='default' filepath='include/linux/sysctl.h' line='147' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='__anonymous_struct__' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/uapi/linux/bpf.h' line='517' column='1' id='1ad3cea4'>
@@ -17728,84 +17877,84 @@
       <pointer-type-def type-id='e613f28a' size-in-bits='64' id='1c33159c'/>
       <pointer-type-def type-id='064acd7a' size-in-bits='64' id='1c475548'/>
       <pointer-type-def type-id='97e3fb6c' size-in-bits='64' id='1c51ec16'/>
-      <class-decl name='pci_sriov' size-in-bits='1280' is-struct='yes' visibility='default' filepath='drivers/pci/pci.h' line='324' column='1' id='1c590219'>
+      <class-decl name='pci_sriov' size-in-bits='1280' is-struct='yes' visibility='default' filepath='drivers/pci/pci.h' line='338' column='1' id='1c590219'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='pos' type-id='95e97e5e' visibility='default' filepath='drivers/pci/pci.h' line='325' column='1'/>
+          <var-decl name='pos' type-id='95e97e5e' visibility='default' filepath='drivers/pci/pci.h' line='339' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='nres' type-id='95e97e5e' visibility='default' filepath='drivers/pci/pci.h' line='326' column='1'/>
+          <var-decl name='nres' type-id='95e97e5e' visibility='default' filepath='drivers/pci/pci.h' line='340' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='cap' type-id='19c2251e' visibility='default' filepath='drivers/pci/pci.h' line='327' column='1'/>
+          <var-decl name='cap' type-id='19c2251e' visibility='default' filepath='drivers/pci/pci.h' line='341' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='ctrl' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='328' column='1'/>
+          <var-decl name='ctrl' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='342' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='112'>
-          <var-decl name='total_VFs' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='329' column='1'/>
+          <var-decl name='total_VFs' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='343' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='initial_VFs' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='330' column='1'/>
+          <var-decl name='initial_VFs' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='344' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='144'>
-          <var-decl name='num_VFs' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='331' column='1'/>
+          <var-decl name='num_VFs' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='345' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='160'>
-          <var-decl name='offset' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='332' column='1'/>
+          <var-decl name='offset' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='346' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='176'>
-          <var-decl name='stride' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='333' column='1'/>
+          <var-decl name='stride' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='347' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='vf_device' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='334' column='1'/>
+          <var-decl name='vf_device' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='348' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='224'>
-          <var-decl name='pgsz' type-id='19c2251e' visibility='default' filepath='drivers/pci/pci.h' line='335' column='1'/>
+          <var-decl name='pgsz' type-id='19c2251e' visibility='default' filepath='drivers/pci/pci.h' line='349' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='link' type-id='f9b06939' visibility='default' filepath='drivers/pci/pci.h' line='336' column='1'/>
+          <var-decl name='link' type-id='f9b06939' visibility='default' filepath='drivers/pci/pci.h' line='350' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='264'>
-          <var-decl name='max_VF_buses' type-id='f9b06939' visibility='default' filepath='drivers/pci/pci.h' line='337' column='1'/>
+          <var-decl name='max_VF_buses' type-id='f9b06939' visibility='default' filepath='drivers/pci/pci.h' line='351' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='272'>
-          <var-decl name='driver_max_VFs' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='338' column='1'/>
+          <var-decl name='driver_max_VFs' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='352' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='dev' type-id='85196e3f' visibility='default' filepath='drivers/pci/pci.h' line='339' column='1'/>
+          <var-decl name='dev' type-id='85196e3f' visibility='default' filepath='drivers/pci/pci.h' line='353' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='self' type-id='85196e3f' visibility='default' filepath='drivers/pci/pci.h' line='340' column='1'/>
+          <var-decl name='self' type-id='85196e3f' visibility='default' filepath='drivers/pci/pci.h' line='354' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='class' type-id='19c2251e' visibility='default' filepath='drivers/pci/pci.h' line='341' column='1'/>
+          <var-decl name='class' type-id='19c2251e' visibility='default' filepath='drivers/pci/pci.h' line='355' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='480'>
-          <var-decl name='hdr_type' type-id='f9b06939' visibility='default' filepath='drivers/pci/pci.h' line='342' column='1'/>
+          <var-decl name='hdr_type' type-id='f9b06939' visibility='default' filepath='drivers/pci/pci.h' line='356' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='496'>
-          <var-decl name='subsystem_vendor' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='343' column='1'/>
+          <var-decl name='subsystem_vendor' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='357' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='subsystem_device' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='344' column='1'/>
+          <var-decl name='subsystem_device' type-id='1dc6a898' visibility='default' filepath='drivers/pci/pci.h' line='358' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='barsz' type-id='21e79dbc' visibility='default' filepath='drivers/pci/pci.h' line='345' column='1'/>
+          <var-decl name='barsz' type-id='21e79dbc' visibility='default' filepath='drivers/pci/pci.h' line='359' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='drivers_autoprobe' type-id='b50a4934' visibility='default' filepath='drivers/pci/pci.h' line='346' column='1'/>
+          <var-decl name='drivers_autoprobe' type-id='b50a4934' visibility='default' filepath='drivers/pci/pci.h' line='360' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='drivers/pci/pci.h' line='348' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='drivers/pci/pci.h' line='362' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1088'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='drivers/pci/pci.h' line='349' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='drivers/pci/pci.h' line='363' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='drivers/pci/pci.h' line='350' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='drivers/pci/pci.h' line='364' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='drivers/pci/pci.h' line='351' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='drivers/pci/pci.h' line='365' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='mipi_dsi_device_info' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/drm/drm_mipi_dsi.h' line='166' column='1' id='1c5d084f'>
@@ -18548,36 +18697,36 @@
       <qualified-type-def type-id='d334c4a2' const='yes' id='1ec1e54d'/>
       <pointer-type-def type-id='2922fb19' size-in-bits='64' id='1ed1e4cd'/>
       <pointer-type-def type-id='76959226' size-in-bits='64' id='1ed3660c'/>
-      <class-decl name='iphdr' size-in-bits='160' is-struct='yes' visibility='default' filepath='include/uapi/linux/ip.h' line='86' column='1' id='1edbefa6'>
+      <class-decl name='iphdr' size-in-bits='160' is-struct='yes' visibility='default' filepath='include/uapi/linux/ip.h' line='87' column='1' id='1edbefa6'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='ihl' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ip.h' line='88' column='1'/>
+          <var-decl name='ihl' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ip.h' line='89' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4'>
-          <var-decl name='version' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ip.h' line='89' column='1'/>
+          <var-decl name='version' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ip.h' line='90' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8'>
-          <var-decl name='tos' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ip.h' line='96' column='1'/>
+          <var-decl name='tos' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ip.h' line='97' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='16'>
-          <var-decl name='tot_len' type-id='84a5c3d4' visibility='default' filepath='include/uapi/linux/ip.h' line='97' column='1'/>
+          <var-decl name='tot_len' type-id='84a5c3d4' visibility='default' filepath='include/uapi/linux/ip.h' line='98' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='id' type-id='84a5c3d4' visibility='default' filepath='include/uapi/linux/ip.h' line='98' column='1'/>
+          <var-decl name='id' type-id='84a5c3d4' visibility='default' filepath='include/uapi/linux/ip.h' line='99' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='48'>
-          <var-decl name='frag_off' type-id='84a5c3d4' visibility='default' filepath='include/uapi/linux/ip.h' line='99' column='1'/>
+          <var-decl name='frag_off' type-id='84a5c3d4' visibility='default' filepath='include/uapi/linux/ip.h' line='100' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='ttl' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ip.h' line='100' column='1'/>
+          <var-decl name='ttl' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ip.h' line='101' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='72'>
-          <var-decl name='protocol' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ip.h' line='101' column='1'/>
+          <var-decl name='protocol' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ip.h' line='102' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='80'>
-          <var-decl name='check' type-id='7dac1e36' visibility='default' filepath='include/uapi/linux/ip.h' line='102' column='1'/>
+          <var-decl name='check' type-id='7dac1e36' visibility='default' filepath='include/uapi/linux/ip.h' line='103' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='' type-id='86910b4e' visibility='default' filepath='include/uapi/linux/ip.h' line='104' column='1'/>
+          <var-decl name='' type-id='86910b4e' visibility='default' filepath='include/uapi/linux/ip.h' line='105' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='1ee07c27'>
@@ -18679,7 +18828,7 @@
           <var-decl name='n_fts' type-id='cf114704' visibility='default' filepath='drivers/pci/controller/dwc/pcie-designware.h' line='275' column='1'/>
         </data-member>
       </class-decl>
-      <enum-decl name='skb_free_reason' filepath='include/linux/netdevice.h' line='3866' column='1' id='1f17c6b4'>
+      <enum-decl name='skb_free_reason' filepath='include/linux/netdevice.h' line='3867' column='1' id='1f17c6b4'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='SKB_REASON_CONSUMED' value='0'/>
         <enumerator name='SKB_REASON_DROPPED' value='1'/>
@@ -18710,42 +18859,42 @@
       </function-type>
       <pointer-type-def type-id='5d1d7263' size-in-bits='64' id='1f211d93'/>
       <pointer-type-def type-id='ae89b201' size-in-bits='64' id='1f2a8949'/>
-      <class-decl name='typec_capability' size-in-bits='576' is-struct='yes' visibility='default' filepath='include/linux/usb/typec.h' line='243' column='1' id='1f2b9a61'>
+      <class-decl name='typec_capability' size-in-bits='576' is-struct='yes' visibility='default' filepath='include/linux/usb/typec.h' line='249' column='1' id='1f2b9a61'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='type' type-id='0a19b04e' visibility='default' filepath='include/linux/usb/typec.h' line='244' column='1'/>
+          <var-decl name='type' type-id='0a19b04e' visibility='default' filepath='include/linux/usb/typec.h' line='250' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='data' type-id='89aae82e' visibility='default' filepath='include/linux/usb/typec.h' line='245' column='1'/>
+          <var-decl name='data' type-id='89aae82e' visibility='default' filepath='include/linux/usb/typec.h' line='251' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='revision' type-id='1dc6a898' visibility='default' filepath='include/linux/usb/typec.h' line='246' column='1'/>
+          <var-decl name='revision' type-id='1dc6a898' visibility='default' filepath='include/linux/usb/typec.h' line='252' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='80'>
-          <var-decl name='pd_revision' type-id='1dc6a898' visibility='default' filepath='include/linux/usb/typec.h' line='247' column='1'/>
+          <var-decl name='pd_revision' type-id='1dc6a898' visibility='default' filepath='include/linux/usb/typec.h' line='253' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='svdm_version' type-id='664a29a4' visibility='default' filepath='include/linux/usb/typec.h' line='248' column='1'/>
+          <var-decl name='svdm_version' type-id='664a29a4' visibility='default' filepath='include/linux/usb/typec.h' line='254' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='prefer_role' type-id='95e97e5e' visibility='default' filepath='include/linux/usb/typec.h' line='249' column='1'/>
+          <var-decl name='prefer_role' type-id='95e97e5e' visibility='default' filepath='include/linux/usb/typec.h' line='255' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='160'>
-          <var-decl name='accessory' type-id='ee8e0be0' visibility='default' filepath='include/linux/usb/typec.h' line='250' column='1'/>
+          <var-decl name='accessory' type-id='ee8e0be0' visibility='default' filepath='include/linux/usb/typec.h' line='256' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='orientation_aware' type-id='f0981eeb' visibility='default' filepath='include/linux/usb/typec.h' line='251' column='1'/>
+          <var-decl name='orientation_aware' type-id='f0981eeb' visibility='default' filepath='include/linux/usb/typec.h' line='257' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='fwnode' type-id='4a935625' visibility='default' filepath='include/linux/usb/typec.h' line='253' column='1'/>
+          <var-decl name='fwnode' type-id='4a935625' visibility='default' filepath='include/linux/usb/typec.h' line='259' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='driver_data' type-id='eaa32e2f' visibility='default' filepath='include/linux/usb/typec.h' line='254' column='1'/>
+          <var-decl name='driver_data' type-id='eaa32e2f' visibility='default' filepath='include/linux/usb/typec.h' line='260' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='ops' type-id='ebbbab1e' visibility='default' filepath='include/linux/usb/typec.h' line='256' column='1'/>
+          <var-decl name='ops' type-id='ebbbab1e' visibility='default' filepath='include/linux/usb/typec.h' line='262' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb/typec.h' line='257' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb/typec.h' line='263' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='neigh_hash_table' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/net/neighbour.h' line='192' column='1' id='1f305e7e'>
@@ -18899,42 +19048,42 @@
           <var-decl name='packets' type-id='d3130597' visibility='default' filepath='include/net/gen_stats.h' line='13' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='xhci_vendor_ops' size-in-bits='768' is-struct='yes' visibility='default' filepath='drivers/usb/host/xhci.h' line='2243' column='1' id='1faef6b3'>
+      <class-decl name='xhci_vendor_ops' size-in-bits='768' is-struct='yes' visibility='default' filepath='drivers/usb/host/xhci.h' line='2245' column='1' id='1faef6b3'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='vendor_init' type-id='e2d5afe3' visibility='default' filepath='drivers/usb/host/xhci.h' line='2244' column='1'/>
+          <var-decl name='vendor_init' type-id='e2d5afe3' visibility='default' filepath='drivers/usb/host/xhci.h' line='2246' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='vendor_cleanup' type-id='465f7e18' visibility='default' filepath='drivers/usb/host/xhci.h' line='2245' column='1'/>
+          <var-decl name='vendor_cleanup' type-id='465f7e18' visibility='default' filepath='drivers/usb/host/xhci.h' line='2247' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='is_usb_offload_enabled' type-id='65f4b33e' visibility='default' filepath='drivers/usb/host/xhci.h' line='2246' column='1'/>
+          <var-decl name='is_usb_offload_enabled' type-id='65f4b33e' visibility='default' filepath='drivers/usb/host/xhci.h' line='2248' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='queue_irq_work' type-id='19cf2a10' visibility='default' filepath='drivers/usb/host/xhci.h' line='2249' column='1'/>
+          <var-decl name='queue_irq_work' type-id='19cf2a10' visibility='default' filepath='drivers/usb/host/xhci.h' line='2251' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='alloc_dcbaa' type-id='ffedaefa' visibility='default' filepath='drivers/usb/host/xhci.h' line='2251' column='1'/>
+          <var-decl name='alloc_dcbaa' type-id='ffedaefa' visibility='default' filepath='drivers/usb/host/xhci.h' line='2253' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='free_dcbaa' type-id='465f7e18' visibility='default' filepath='drivers/usb/host/xhci.h' line='2253' column='1'/>
+          <var-decl name='free_dcbaa' type-id='465f7e18' visibility='default' filepath='drivers/usb/host/xhci.h' line='2255' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='alloc_transfer_ring' type-id='7a09678a' visibility='default' filepath='drivers/usb/host/xhci.h' line='2255' column='1'/>
+          <var-decl name='alloc_transfer_ring' type-id='7a09678a' visibility='default' filepath='drivers/usb/host/xhci.h' line='2257' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='free_transfer_ring' type-id='60881d05' visibility='default' filepath='drivers/usb/host/xhci.h' line='2258' column='1'/>
+          <var-decl name='free_transfer_ring' type-id='60881d05' visibility='default' filepath='drivers/usb/host/xhci.h' line='2260' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='sync_dev_ctx' type-id='2916d511' visibility='default' filepath='drivers/usb/host/xhci.h' line='2260' column='1'/>
+          <var-decl name='sync_dev_ctx' type-id='2916d511' visibility='default' filepath='drivers/usb/host/xhci.h' line='2262' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='usb_offload_skip_urb' type-id='75f1eb36' visibility='default' filepath='drivers/usb/host/xhci.h' line='2261' column='1'/>
+          <var-decl name='usb_offload_skip_urb' type-id='75f1eb36' visibility='default' filepath='drivers/usb/host/xhci.h' line='2263' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='alloc_container_ctx' type-id='6d5e21be' visibility='default' filepath='drivers/usb/host/xhci.h' line='2262' column='1'/>
+          <var-decl name='alloc_container_ctx' type-id='6d5e21be' visibility='default' filepath='drivers/usb/host/xhci.h' line='2264' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='free_container_ctx' type-id='a23db496' visibility='default' filepath='drivers/usb/host/xhci.h' line='2264' column='1'/>
+          <var-decl name='free_container_ctx' type-id='a23db496' visibility='default' filepath='drivers/usb/host/xhci.h' line='2266' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='__anonymous_struct__' size-in-bits='160' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/uapi/linux/bpf.h' line='568' column='1' id='1fb21a42'>
@@ -19058,12 +19207,12 @@
       </function-type>
       <pointer-type-def type-id='3490ee41' size-in-bits='64' id='200ffa89'/>
       <pointer-type-def type-id='a721b4ab' size-in-bits='64' id='20174b1f'/>
-      <union-decl name='__anonymous_union__' size-in-bits='192' is-anonymous='yes' visibility='default' filepath='include/linux/sysctl.h' line='132' column='1' id='201d54e5'>
+      <union-decl name='__anonymous_union__' size-in-bits='192' is-anonymous='yes' visibility='default' filepath='include/linux/sysctl.h' line='142' column='1' id='201d54e5'>
         <data-member access='public'>
-          <var-decl name='' type-id='1acab550' visibility='default' filepath='include/linux/sysctl.h' line='133' column='1'/>
+          <var-decl name='' type-id='1acab550' visibility='default' filepath='include/linux/sysctl.h' line='143' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/sysctl.h' line='139' column='1'/>
+          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/sysctl.h' line='149' column='1'/>
         </data-member>
       </union-decl>
       <function-type size-in-bits='64' id='201ffa8e'>
@@ -21604,7 +21753,7 @@
         <parameter type-id='98d7a132'/>
         <return type-id='02ac9d9d'/>
       </function-type>
-      <typedef-decl name='filldir_t' type-id='78efe913' filepath='include/linux/fs.h' line='1821' column='1' id='262124ef'/>
+      <typedef-decl name='filldir_t' type-id='78efe913' filepath='include/linux/fs.h' line='1828' column='1' id='262124ef'/>
       <class-decl name='snd_soc_tplg_vendor_value_elem' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/uapi/sound/asoc.h' line='207' column='1' id='26236645'>
         <data-member access='public' layout-offset-in-bits='0'>
           <var-decl name='token' type-id='2f162548' visibility='default' filepath='include/uapi/sound/asoc.h' line='208' column='1'/>
@@ -22007,12 +22156,12 @@
         <parameter type-id='0f1b379b'/>
         <return type-id='48b5725f'/>
       </function-type>
-      <union-decl name='__anonymous_union__' size-in-bits='128' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='755' column='1' id='271a40b8'>
+      <union-decl name='__anonymous_union__' size-in-bits='128' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='757' column='1' id='271a40b8'>
         <data-member access='public'>
-          <var-decl name='' type-id='710cec71' visibility='default' filepath='include/linux/skbuff.h' line='756' column='1'/>
+          <var-decl name='' type-id='710cec71' visibility='default' filepath='include/linux/skbuff.h' line='758' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='tcp_tsorted_anchor' type-id='72f469ec' visibility='default' filepath='include/linux/skbuff.h' line='760' column='1'/>
+          <var-decl name='tcp_tsorted_anchor' type-id='72f469ec' visibility='default' filepath='include/linux/skbuff.h' line='762' column='1'/>
         </data-member>
       </union-decl>
       <class-decl name='pp_alloc_cache' size-in-bits='8256' is-struct='yes' visibility='default' filepath='include/net/page_pool.h' line='67' column='1' id='271cf31a'>
@@ -22273,18 +22422,18 @@
         <enumerator name='USB_EVENT_ENUMERATED' value='4'/>
       </enum-decl>
       <pointer-type-def type-id='b86ed83e' size-in-bits='64' id='27936440'/>
-      <class-decl name='xps_map' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='797' column='1' id='279bdcdf'>
+      <class-decl name='xps_map' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='802' column='1' id='279bdcdf'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='len' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='798' column='1'/>
+          <var-decl name='len' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='803' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='alloc_len' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='799' column='1'/>
+          <var-decl name='alloc_len' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='804' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/netdevice.h' line='800' column='1'/>
+          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/netdevice.h' line='805' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='queues' type-id='0f300383' visibility='default' filepath='include/linux/netdevice.h' line='801' column='1'/>
+          <var-decl name='queues' type-id='0f300383' visibility='default' filepath='include/linux/netdevice.h' line='806' column='1'/>
         </data-member>
       </class-decl>
       <typedef-decl name='regmap_hw_async_alloc' type-id='68f92bd7' filepath='include/linux/regmap.h' line='468' column='1' id='27a024fd'/>
@@ -22335,11 +22484,11 @@
       <array-type-def dimensions='1' type-id='f0981eeb' size-in-bits='448' id='27cbf0c8'>
         <subrange length='14' type-id='7ff19f0f' id='48882d96'/>
       </array-type-def>
-      <typedef-decl name='dio_submit_t' type-id='6d229cce' filepath='include/linux/fs.h' line='3103' column='1' id='27d499b2'/>
+      <typedef-decl name='dio_submit_t' type-id='6d229cce' filepath='include/linux/fs.h' line='3110' column='1' id='27d499b2'/>
       <pointer-type-def type-id='af1e6651' size-in-bits='64' id='27db53a1'/>
-      <class-decl name='snd_soc_dapm_wcache' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/sound/soc-dapm.h' line='682' column='1' id='27dc472b'>
+      <class-decl name='snd_soc_dapm_wcache' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/sound/soc-dapm.h' line='683' column='1' id='27dc472b'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='widget' type-id='810606ec' visibility='default' filepath='include/sound/soc-dapm.h' line='683' column='1'/>
+          <var-decl name='widget' type-id='810606ec' visibility='default' filepath='include/sound/soc-dapm.h' line='684' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='watchdog_ops' size-in-bits='640' is-struct='yes' visibility='default' filepath='include/linux/watchdog.h' line='43' column='1' id='27dec419'>
@@ -22635,63 +22784,63 @@
         <parameter type-id='0b8718c0'/>
         <return type-id='0f4f6276'/>
       </function-type>
-      <class-decl name='napi_struct' size-in-bits='3392' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='328' column='1' id='291e3bb5'>
+      <class-decl name='napi_struct' size-in-bits='3392' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='330' column='1' id='291e3bb5'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='poll_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='335' column='1'/>
+          <var-decl name='poll_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='337' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='state' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='337' column='1'/>
+          <var-decl name='state' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='339' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='weight' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='338' column='1'/>
+          <var-decl name='weight' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='340' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='224'>
-          <var-decl name='defer_hard_irqs_count' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='339' column='1'/>
+          <var-decl name='defer_hard_irqs_count' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='341' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='gro_bitmask' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='340' column='1'/>
+          <var-decl name='gro_bitmask' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='342' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='poll' type-id='f07d90b4' visibility='default' filepath='include/linux/netdevice.h' line='341' column='1'/>
+          <var-decl name='poll' type-id='f07d90b4' visibility='default' filepath='include/linux/netdevice.h' line='343' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='dev' type-id='68a2d05b' visibility='default' filepath='include/linux/netdevice.h' line='345' column='1'/>
+          <var-decl name='dev' type-id='68a2d05b' visibility='default' filepath='include/linux/netdevice.h' line='347' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='gro_hash' type-id='91671be8' visibility='default' filepath='include/linux/netdevice.h' line='346' column='1'/>
+          <var-decl name='gro_hash' type-id='91671be8' visibility='default' filepath='include/linux/netdevice.h' line='348' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1984'>
-          <var-decl name='skb' type-id='0fbf3cfd' visibility='default' filepath='include/linux/netdevice.h' line='347' column='1'/>
+          <var-decl name='skb' type-id='0fbf3cfd' visibility='default' filepath='include/linux/netdevice.h' line='349' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2048'>
-          <var-decl name='rx_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='348' column='1'/>
+          <var-decl name='rx_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='350' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2176'>
-          <var-decl name='rx_count' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='349' column='1'/>
+          <var-decl name='rx_count' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='351' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2240'>
-          <var-decl name='timer' type-id='b6993efc' visibility='default' filepath='include/linux/netdevice.h' line='350' column='1'/>
+          <var-decl name='timer' type-id='b6993efc' visibility='default' filepath='include/linux/netdevice.h' line='352' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2816'>
-          <var-decl name='dev_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='351' column='1'/>
+          <var-decl name='dev_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='353' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2944'>
-          <var-decl name='napi_hash_node' type-id='03a4a074' visibility='default' filepath='include/linux/netdevice.h' line='352' column='1'/>
+          <var-decl name='napi_hash_node' type-id='03a4a074' visibility='default' filepath='include/linux/netdevice.h' line='354' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3072'>
-          <var-decl name='napi_id' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='353' column='1'/>
+          <var-decl name='napi_id' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='355' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3136'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='355' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='357' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3200'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='356' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='358' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3264'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='357' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='359' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3328'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='358' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='360' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='2922fb19'>
@@ -22959,7 +23108,7 @@
         <parameter type-id='eaa32e2f'/>
         <return type-id='95e97e5e'/>
       </function-type>
-      <typedef-decl name='irq_handler_t' type-id='3fefe9b7' filepath='include/linux/interrupt.h' line='92' column='1' id='29591c9a'/>
+      <typedef-decl name='irq_handler_t' type-id='3fefe9b7' filepath='include/linux/interrupt.h' line='96' column='1' id='29591c9a'/>
       <function-type size-in-bits='64' id='29599587'>
         <parameter type-id='9f763fd8'/>
         <parameter type-id='2ae08426'/>
@@ -23534,7 +23683,7 @@
         <parameter type-id='861f302a'/>
         <return type-id='95e97e5e'/>
       </function-type>
-      <union-decl name='__anonymous_union__' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='924' column='1' id='2a125a28'/>
+      <union-decl name='__anonymous_union__' is-anonymous='yes' visibility='default' filepath='include/linux/sched.h' line='1380' column='1' id='2a125a28'/>
       <pointer-type-def type-id='e290c28c' size-in-bits='64' id='2a128f5a'/>
       <class-decl name='drm_client_buffer' size-in-bits='320' is-struct='yes' visibility='default' filepath='include/drm/drm_client.h' line='122' column='1' id='2a13094b'>
         <data-member access='public' layout-offset-in-bits='0'>
@@ -23694,12 +23843,12 @@
           <var-decl name='rb_left' type-id='e6532500' visibility='default' filepath='include/linux/rbtree.h' line='27' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='tty_port_client_operations' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/tty.h' line='226' column='1' id='2a8ca227'>
+      <class-decl name='tty_port_client_operations' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/tty.h' line='202' column='1' id='2a8ca227'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='receive_buf' type-id='1a7b1e1d' visibility='default' filepath='include/linux/tty.h' line='227' column='1'/>
+          <var-decl name='receive_buf' type-id='1a7b1e1d' visibility='default' filepath='include/linux/tty.h' line='203' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='write_wakeup' type-id='7e5b379d' visibility='default' filepath='include/linux/tty.h' line='228' column='1'/>
+          <var-decl name='write_wakeup' type-id='7e5b379d' visibility='default' filepath='include/linux/tty.h' line='204' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='spi_mem_driver' size-in-bits='1920' is-struct='yes' visibility='default' filepath='include/linux/spi/spi-mem.h' line='295' column='1' id='2a9bc482'>
@@ -24704,42 +24853,42 @@
         <parameter type-id='95e97e5e'/>
         <return type-id='95e97e5e'/>
       </function-type>
-      <class-decl name='dwc3_hwparams' size-in-bits='448' is-struct='yes' visibility='default' filepath='drivers/usb/dwc3/core.h' line='866' column='1' id='2d79d174'>
+      <class-decl name='dwc3_hwparams' size-in-bits='448' is-struct='yes' visibility='default' filepath='drivers/usb/dwc3/core.h' line='867' column='1' id='2d79d174'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='hwparams0' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='867' column='1'/>
+          <var-decl name='hwparams0' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='868' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='hwparams1' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='868' column='1'/>
+          <var-decl name='hwparams1' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='869' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='hwparams2' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='869' column='1'/>
+          <var-decl name='hwparams2' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='870' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='hwparams3' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='870' column='1'/>
+          <var-decl name='hwparams3' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='871' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='hwparams4' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='871' column='1'/>
+          <var-decl name='hwparams4' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='872' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='160'>
-          <var-decl name='hwparams5' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='872' column='1'/>
+          <var-decl name='hwparams5' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='873' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='hwparams6' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='873' column='1'/>
+          <var-decl name='hwparams6' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='874' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='224'>
-          <var-decl name='hwparams7' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='874' column='1'/>
+          <var-decl name='hwparams7' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='875' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='hwparams8' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='875' column='1'/>
+          <var-decl name='hwparams8' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='876' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='288'>
-          <var-decl name='hwparams9' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='876' column='1'/>
+          <var-decl name='hwparams9' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='877' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='878' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='879' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='879' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='880' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='425bcb9d' size-in-bits='64' id='2d81b115'/>
@@ -24847,27 +24996,27 @@
       <pointer-type-def type-id='7fb3a80c' size-in-bits='64' id='2dd1b3d2'/>
       <qualified-type-def type-id='81cd3626' const='yes' id='2dd1eb6f'/>
       <pointer-type-def type-id='f8cf7305' size-in-bits='64' id='2deec881'/>
-      <class-decl name='usb_host_config' size-in-bits='5440' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='380' column='1' id='2df0328b'>
+      <class-decl name='usb_host_config' size-in-bits='5440' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='385' column='1' id='2df0328b'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='desc' type-id='372ebfa4' visibility='default' filepath='include/linux/usb.h' line='381' column='1'/>
+          <var-decl name='desc' type-id='372ebfa4' visibility='default' filepath='include/linux/usb.h' line='386' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='string' type-id='26a90f95' visibility='default' filepath='include/linux/usb.h' line='383' column='1'/>
+          <var-decl name='string' type-id='26a90f95' visibility='default' filepath='include/linux/usb.h' line='388' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='intf_assoc' type-id='3e3c9632' visibility='default' filepath='include/linux/usb.h' line='387' column='1'/>
+          <var-decl name='intf_assoc' type-id='3e3c9632' visibility='default' filepath='include/linux/usb.h' line='392' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='interface' type-id='a2aad346' visibility='default' filepath='include/linux/usb.h' line='391' column='1'/>
+          <var-decl name='interface' type-id='a2aad346' visibility='default' filepath='include/linux/usb.h' line='396' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3264'>
-          <var-decl name='intf_cache' type-id='11a8d8e5' visibility='default' filepath='include/linux/usb.h' line='395' column='1'/>
+          <var-decl name='intf_cache' type-id='11a8d8e5' visibility='default' filepath='include/linux/usb.h' line='400' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5312'>
-          <var-decl name='extra' type-id='cf536864' visibility='default' filepath='include/linux/usb.h' line='397' column='1'/>
+          <var-decl name='extra' type-id='cf536864' visibility='default' filepath='include/linux/usb.h' line='402' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5376'>
-          <var-decl name='extralen' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='398' column='1'/>
+          <var-decl name='extralen' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='403' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='192c003a' size-in-bits='64' id='2dfafd2c'/>
@@ -25179,7 +25328,7 @@
         <parameter type-id='eaa32e2f'/>
         <return type-id='f0981eeb'/>
       </function-type>
-      <enum-decl name='system_states' filepath='include/linux/kernel.h' line='576' column='1' id='2ead22b4'>
+      <enum-decl name='system_states' filepath='include/linux/kernel.h' line='432' column='1' id='2ead22b4'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='SYSTEM_BOOTING' value='0'/>
         <enumerator name='SYSTEM_SCHEDULING' value='1'/>
@@ -25218,6 +25367,17 @@
         <return type-id='95e97e5e'/>
       </function-type>
       <pointer-type-def type-id='ee780377' size-in-bits='64' id='2edb3e4b'/>
+      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/sched.h' line='1380' column='1' id='2ee593e9'>
+        <data-member access='public'>
+          <var-decl name='pf_io_worker' type-id='eaa32e2f' visibility='default' filepath='include/linux/sched.h' line='1380' column='1'/>
+        </data-member>
+        <data-member access='public'>
+          <var-decl name='' type-id='156952c4' visibility='default' filepath='include/linux/sched.h' line='1380' column='1'/>
+        </data-member>
+        <data-member access='public'>
+          <var-decl name='' type-id='2a125a28' visibility='default' filepath='include/linux/sched.h' line='1380' column='1'/>
+        </data-member>
+      </union-decl>
       <class-decl name='ieee80211_vht_cap' size-in-bits='96' is-struct='yes' visibility='default' filepath='include/linux/ieee80211.h' line='1731' column='1' id='2eec6999'>
         <data-member access='public' layout-offset-in-bits='0'>
           <var-decl name='vht_cap_info' type-id='2f162548' visibility='default' filepath='include/linux/ieee80211.h' line='1732' column='1'/>
@@ -25285,93 +25445,93 @@
           <var-decl name='byte_tx' type-id='3f1a6b60' visibility='default' filepath='include/net/bluetooth/hci_sock.h' line='105' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='tty_buffer' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/tty.h' line='59' column='1' id='2f351d1f'>
+      <class-decl name='tty_buffer' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/tty.h' line='35' column='1' id='2f351d1f'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='' type-id='053892cc' visibility='default' filepath='include/linux/tty.h' line='60' column='1'/>
+          <var-decl name='' type-id='053892cc' visibility='default' filepath='include/linux/tty.h' line='36' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='used' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='64' column='1'/>
+          <var-decl name='used' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='40' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='size' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='65' column='1'/>
+          <var-decl name='size' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='41' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='commit' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='66' column='1'/>
+          <var-decl name='commit' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='42' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='160'>
-          <var-decl name='read' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='67' column='1'/>
+          <var-decl name='read' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='43' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='flags' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='68' column='1'/>
+          <var-decl name='flags' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='44' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='data' type-id='c99b5ecd' visibility='default' filepath='include/linux/tty.h' line='70' column='1'/>
+          <var-decl name='data' type-id='c99b5ecd' visibility='default' filepath='include/linux/tty.h' line='46' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='8c6e144c' size-in-bits='64' id='2f3c74d6'/>
       <pointer-type-def type-id='9502627f' size-in-bits='64' id='2f4077f3'/>
       <pointer-type-def type-id='676b848c' size-in-bits='64' id='2f4512ea'/>
       <pointer-type-def type-id='7364da7b' size-in-bits='64' id='2f59f71f'/>
-      <class-decl name='file_system_type' size-in-bits='832' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='2301' column='1' id='2f5a60be'>
+      <class-decl name='file_system_type' size-in-bits='832' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='2308' column='1' id='2f5a60be'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='name' type-id='80f4b756' visibility='default' filepath='include/linux/fs.h' line='2302' column='1'/>
+          <var-decl name='name' type-id='80f4b756' visibility='default' filepath='include/linux/fs.h' line='2309' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='fs_flags' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='2303' column='1'/>
+          <var-decl name='fs_flags' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='2310' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='init_fs_context' type-id='57f0383a' visibility='default' filepath='include/linux/fs.h' line='2311' column='1'/>
+          <var-decl name='init_fs_context' type-id='57f0383a' visibility='default' filepath='include/linux/fs.h' line='2318' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='parameters' type-id='8d4f223b' visibility='default' filepath='include/linux/fs.h' line='2312' column='1'/>
+          <var-decl name='parameters' type-id='8d4f223b' visibility='default' filepath='include/linux/fs.h' line='2319' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='mount' type-id='d9394db1' visibility='default' filepath='include/linux/fs.h' line='2313' column='1'/>
+          <var-decl name='mount' type-id='d9394db1' visibility='default' filepath='include/linux/fs.h' line='2320' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='kill_sb' type-id='1ff54a45' visibility='default' filepath='include/linux/fs.h' line='2315' column='1'/>
+          <var-decl name='kill_sb' type-id='1ff54a45' visibility='default' filepath='include/linux/fs.h' line='2322' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='owner' type-id='2730d015' visibility='default' filepath='include/linux/fs.h' line='2316' column='1'/>
+          <var-decl name='owner' type-id='2730d015' visibility='default' filepath='include/linux/fs.h' line='2323' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='next' type-id='21e53d44' visibility='default' filepath='include/linux/fs.h' line='2317' column='1'/>
+          <var-decl name='next' type-id='21e53d44' visibility='default' filepath='include/linux/fs.h' line='2324' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='fs_supers' type-id='e151255a' visibility='default' filepath='include/linux/fs.h' line='2318' column='1'/>
+          <var-decl name='fs_supers' type-id='e151255a' visibility='default' filepath='include/linux/fs.h' line='2325' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='s_lock_key' type-id='47479831' visibility='default' filepath='include/linux/fs.h' line='2320' column='1'/>
+          <var-decl name='s_lock_key' type-id='47479831' visibility='default' filepath='include/linux/fs.h' line='2327' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='s_umount_key' type-id='47479831' visibility='default' filepath='include/linux/fs.h' line='2321' column='1'/>
+          <var-decl name='s_umount_key' type-id='47479831' visibility='default' filepath='include/linux/fs.h' line='2328' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='s_vfs_rename_key' type-id='47479831' visibility='default' filepath='include/linux/fs.h' line='2322' column='1'/>
+          <var-decl name='s_vfs_rename_key' type-id='47479831' visibility='default' filepath='include/linux/fs.h' line='2329' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='s_writers_key' type-id='9c02e2a6' visibility='default' filepath='include/linux/fs.h' line='2323' column='1'/>
+          <var-decl name='s_writers_key' type-id='9c02e2a6' visibility='default' filepath='include/linux/fs.h' line='2330' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='i_lock_key' type-id='47479831' visibility='default' filepath='include/linux/fs.h' line='2325' column='1'/>
+          <var-decl name='i_lock_key' type-id='47479831' visibility='default' filepath='include/linux/fs.h' line='2332' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='i_mutex_key' type-id='47479831' visibility='default' filepath='include/linux/fs.h' line='2326' column='1'/>
+          <var-decl name='i_mutex_key' type-id='47479831' visibility='default' filepath='include/linux/fs.h' line='2333' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='i_mutex_dir_key' type-id='47479831' visibility='default' filepath='include/linux/fs.h' line='2327' column='1'/>
+          <var-decl name='i_mutex_dir_key' type-id='47479831' visibility='default' filepath='include/linux/fs.h' line='2334' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2329' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2336' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2330' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2337' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2331' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2338' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2332' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2339' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='skcipher_instance' size-in-bits='6144' is-struct='yes' visibility='default' filepath='include/crypto/internal/skcipher.h' line='20' column='1' id='2f61a822'>
@@ -25500,15 +25660,15 @@
         <return type-id='95e97e5e'/>
       </function-type>
       <pointer-type-def type-id='06f84b1d' size-in-bits='64' id='2fde6795'/>
-      <class-decl name='workqueue_attrs' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/workqueue.h' line='143' column='1' id='2fe6f208'>
+      <class-decl name='workqueue_attrs' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/workqueue.h' line='144' column='1' id='2fe6f208'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='nice' type-id='95e97e5e' visibility='default' filepath='include/linux/workqueue.h' line='147' column='1'/>
+          <var-decl name='nice' type-id='95e97e5e' visibility='default' filepath='include/linux/workqueue.h' line='148' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='cpumask' type-id='b16b461b' visibility='default' filepath='include/linux/workqueue.h' line='152' column='1'/>
+          <var-decl name='cpumask' type-id='b16b461b' visibility='default' filepath='include/linux/workqueue.h' line='153' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='no_numa' type-id='b50a4934' visibility='default' filepath='include/linux/workqueue.h' line='161' column='1'/>
+          <var-decl name='no_numa' type-id='b50a4934' visibility='default' filepath='include/linux/workqueue.h' line='162' column='1'/>
         </data-member>
       </class-decl>
       <qualified-type-def type-id='5b3ea0c8' const='yes' id='2fecddf7'/>
@@ -25929,6 +26089,7 @@
       </class-decl>
       <typedef-decl name='__s32' type-id='95e97e5e' filepath='include/uapi/asm-generic/int-ll64.h' line='26' column='1' id='3158a266'/>
       <pointer-type-def type-id='6ae7a739' size-in-bits='64' id='3168497d'/>
+      <pointer-type-def type-id='12878ab3' size-in-bits='64' id='316cdcd3'/>
       <class-decl name='key_tag' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/key.h' line='102' column='1' id='3173bc57'>
         <data-member access='public' layout-offset-in-bits='0'>
           <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/key.h' line='103' column='1'/>
@@ -26701,12 +26862,12 @@
           <var-decl name='tail' type-id='1dc6a898' visibility='default' filepath='include/asm-generic/qspinlock_types.h' line='30' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='usbdrv_wrap' size-in-bits='1472' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='1136' column='1' id='33780378'>
+      <class-decl name='usbdrv_wrap' size-in-bits='1472' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='1144' column='1' id='33780378'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='driver' type-id='fe007c02' visibility='default' filepath='include/linux/usb.h' line='1137' column='1'/>
+          <var-decl name='driver' type-id='fe007c02' visibility='default' filepath='include/linux/usb.h' line='1145' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1408'>
-          <var-decl name='for_devices' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1138' column='1'/>
+          <var-decl name='for_devices' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1146' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='337862e8'>
@@ -26728,15 +26889,15 @@
         <parameter type-id='0c2c419d' name='iovad'/>
         <return type-id='48b5725f'/>
       </function-type>
-      <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/netdevice.h' line='931' column='1' id='33bba89f'>
+      <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/netdevice.h' line='936' column='1' id='33bba89f'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='flags' type-id='19c2251e' visibility='default' filepath='include/linux/netdevice.h' line='932' column='1'/>
+          <var-decl name='flags' type-id='19c2251e' visibility='default' filepath='include/linux/netdevice.h' line='937' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='prog' type-id='bdcee7ae' visibility='default' filepath='include/linux/netdevice.h' line='933' column='1'/>
+          <var-decl name='prog' type-id='bdcee7ae' visibility='default' filepath='include/linux/netdevice.h' line='938' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='extack' type-id='5799dc94' visibility='default' filepath='include/linux/netdevice.h' line='934' column='1'/>
+          <var-decl name='extack' type-id='5799dc94' visibility='default' filepath='include/linux/netdevice.h' line='939' column='1'/>
         </data-member>
       </class-decl>
       <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/usb/cdc_ncm.h' line='120' column='1' id='33c33336'>
@@ -27082,18 +27243,18 @@
       <typedef-decl name='probes_handler_t' type-id='ae26a81a' filepath='arch/arm64/include/asm/probes.h' line='13' column='1' id='34a2420f'/>
       <pointer-type-def type-id='ee6561a9' size-in-bits='64' id='34aa5735'/>
       <pointer-type-def type-id='7fc6cf35' size-in-bits='64' id='34b38511'/>
-      <class-decl name='usb3_lpm_parameters' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='538' column='1' id='34bd0a0b'>
+      <class-decl name='usb3_lpm_parameters' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='543' column='1' id='34bd0a0b'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='mel' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='545' column='1'/>
+          <var-decl name='mel' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='550' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='pel' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='551' column='1'/>
+          <var-decl name='pel' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='556' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='sel' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='561' column='1'/>
+          <var-decl name='sel' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='566' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='timeout' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='567' column='1'/>
+          <var-decl name='timeout' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='572' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='6d22a61b' size-in-bits='64' id='34c443b7'/>
@@ -27287,7 +27448,7 @@
           <var-decl name='lists' type-id='a8e1fb22' visibility='default' filepath='include/linux/mmzone.h' line='328' column='1'/>
         </data-member>
       </class-decl>
-      <enum-decl name='typec_accessory' filepath='include/linux/usb/typec.h' line='62' column='1' id='357a6a78'>
+      <enum-decl name='typec_accessory' filepath='include/linux/usb/typec.h' line='63' column='1' id='357a6a78'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='TYPEC_ACCESSORY_NONE' value='0'/>
         <enumerator name='TYPEC_ACCESSORY_AUDIO' value='1'/>
@@ -27298,12 +27459,12 @@
         <parameter type-id='4fa10f9e'/>
         <return type-id='79a0948f'/>
       </function-type>
-      <class-decl name='__anonymous_struct__' size-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='873' column='1' id='358587ec'>
+      <class-decl name='__anonymous_struct__' size-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='875' column='1' id='358587ec'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='csum_start' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='874' column='1'/>
+          <var-decl name='csum_start' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='876' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='16'>
-          <var-decl name='csum_offset' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='875' column='1'/>
+          <var-decl name='csum_offset' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='877' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/uapi/asm-generic/siginfo.h' line='34' column='1' id='35888a92'>
@@ -28089,6 +28250,7 @@
         <enumerator name='DOMAIN_BUS_WAKEUP' value='9'/>
         <enumerator name='DOMAIN_BUS_VMD_MSI' value='10'/>
       </enum-decl>
+      <qualified-type-def type-id='2f8662b5' const='yes' id='38664924'/>
       <class-decl name='elevator_mq_ops' size-in-bits='1664' is-struct='yes' visibility='default' filepath='include/linux/elevator.h' line='30' column='1' id='386fe521'>
         <data-member access='public' layout-offset-in-bits='0'>
           <var-decl name='init_sched' type-id='c2889977' visibility='default' filepath='include/linux/elevator.h' line='31' column='1'/>
@@ -28666,198 +28828,198 @@
           <var-decl name='vqmmc' type-id='850c13f6' visibility='default' filepath='include/linux/mmc/host.h' line='279' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='usb_device' size-in-bits='12480' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='647' column='1' id='39b596d4'>
+      <class-decl name='usb_device' size-in-bits='12480' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='652' column='1' id='39b596d4'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='devnum' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='648' column='1'/>
+          <var-decl name='devnum' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='653' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='devpath' type-id='ac1fa8c0' visibility='default' filepath='include/linux/usb.h' line='649' column='1'/>
+          <var-decl name='devpath' type-id='ac1fa8c0' visibility='default' filepath='include/linux/usb.h' line='654' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='160'>
-          <var-decl name='route' type-id='19c2251e' visibility='default' filepath='include/linux/usb.h' line='650' column='1'/>
+          <var-decl name='route' type-id='19c2251e' visibility='default' filepath='include/linux/usb.h' line='655' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='state' type-id='901a91cb' visibility='default' filepath='include/linux/usb.h' line='651' column='1'/>
+          <var-decl name='state' type-id='901a91cb' visibility='default' filepath='include/linux/usb.h' line='656' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='224'>
-          <var-decl name='speed' type-id='4e532009' visibility='default' filepath='include/linux/usb.h' line='652' column='1'/>
+          <var-decl name='speed' type-id='4e532009' visibility='default' filepath='include/linux/usb.h' line='657' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='rx_lanes' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='653' column='1'/>
+          <var-decl name='rx_lanes' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='658' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='288'>
-          <var-decl name='tx_lanes' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='654' column='1'/>
+          <var-decl name='tx_lanes' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='659' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='tt' type-id='bf95a8f0' visibility='default' filepath='include/linux/usb.h' line='656' column='1'/>
+          <var-decl name='tt' type-id='bf95a8f0' visibility='default' filepath='include/linux/usb.h' line='661' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='ttport' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='657' column='1'/>
+          <var-decl name='ttport' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='662' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='416'>
-          <var-decl name='toggle' type-id='0d532ec1' visibility='default' filepath='include/linux/usb.h' line='659' column='1'/>
+          <var-decl name='toggle' type-id='0d532ec1' visibility='default' filepath='include/linux/usb.h' line='664' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='parent' type-id='25e60cb2' visibility='default' filepath='include/linux/usb.h' line='661' column='1'/>
+          <var-decl name='parent' type-id='25e60cb2' visibility='default' filepath='include/linux/usb.h' line='666' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='bus' type-id='3ab7d422' visibility='default' filepath='include/linux/usb.h' line='662' column='1'/>
+          <var-decl name='bus' type-id='3ab7d422' visibility='default' filepath='include/linux/usb.h' line='667' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='ep0' type-id='325f6f30' visibility='default' filepath='include/linux/usb.h' line='663' column='1'/>
+          <var-decl name='ep0' type-id='325f6f30' visibility='default' filepath='include/linux/usb.h' line='668' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1280'>
-          <var-decl name='dev' type-id='66e487eb' visibility='default' filepath='include/linux/usb.h' line='665' column='1'/>
+          <var-decl name='dev' type-id='66e487eb' visibility='default' filepath='include/linux/usb.h' line='670' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8448'>
-          <var-decl name='descriptor' type-id='582de67c' visibility='default' filepath='include/linux/usb.h' line='667' column='1'/>
+          <var-decl name='descriptor' type-id='582de67c' visibility='default' filepath='include/linux/usb.h' line='672' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8640'>
-          <var-decl name='bos' type-id='ea484b4b' visibility='default' filepath='include/linux/usb.h' line='668' column='1'/>
+          <var-decl name='bos' type-id='ea484b4b' visibility='default' filepath='include/linux/usb.h' line='673' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8704'>
-          <var-decl name='config' type-id='2ba3cceb' visibility='default' filepath='include/linux/usb.h' line='669' column='1'/>
+          <var-decl name='config' type-id='2ba3cceb' visibility='default' filepath='include/linux/usb.h' line='674' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8768'>
-          <var-decl name='actconfig' type-id='2ba3cceb' visibility='default' filepath='include/linux/usb.h' line='671' column='1'/>
+          <var-decl name='actconfig' type-id='2ba3cceb' visibility='default' filepath='include/linux/usb.h' line='676' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8832'>
-          <var-decl name='ep_in' type-id='cfc91983' visibility='default' filepath='include/linux/usb.h' line='672' column='1'/>
+          <var-decl name='ep_in' type-id='cfc91983' visibility='default' filepath='include/linux/usb.h' line='677' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9856'>
-          <var-decl name='ep_out' type-id='cfc91983' visibility='default' filepath='include/linux/usb.h' line='673' column='1'/>
+          <var-decl name='ep_out' type-id='cfc91983' visibility='default' filepath='include/linux/usb.h' line='678' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10880'>
-          <var-decl name='rawdescriptors' type-id='9b23c9ad' visibility='default' filepath='include/linux/usb.h' line='675' column='1'/>
+          <var-decl name='rawdescriptors' type-id='9b23c9ad' visibility='default' filepath='include/linux/usb.h' line='680' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10944'>
-          <var-decl name='bus_mA' type-id='8efea9e5' visibility='default' filepath='include/linux/usb.h' line='677' column='1'/>
+          <var-decl name='bus_mA' type-id='8efea9e5' visibility='default' filepath='include/linux/usb.h' line='682' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10960'>
-          <var-decl name='portnum' type-id='f9b06939' visibility='default' filepath='include/linux/usb.h' line='678' column='1'/>
+          <var-decl name='portnum' type-id='f9b06939' visibility='default' filepath='include/linux/usb.h' line='683' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10968'>
-          <var-decl name='level' type-id='f9b06939' visibility='default' filepath='include/linux/usb.h' line='679' column='1'/>
+          <var-decl name='level' type-id='f9b06939' visibility='default' filepath='include/linux/usb.h' line='684' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10976'>
-          <var-decl name='devaddr' type-id='f9b06939' visibility='default' filepath='include/linux/usb.h' line='680' column='1'/>
+          <var-decl name='devaddr' type-id='f9b06939' visibility='default' filepath='include/linux/usb.h' line='685' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8'>
-          <var-decl name='can_submit' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='682' column='1'/>
+          <var-decl name='can_submit' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='687' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9'>
-          <var-decl name='persist_enabled' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='683' column='1'/>
+          <var-decl name='persist_enabled' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='688' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10'>
-          <var-decl name='have_langid' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='684' column='1'/>
+          <var-decl name='have_langid' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='689' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11'>
-          <var-decl name='authorized' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='685' column='1'/>
+          <var-decl name='authorized' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='690' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='12'>
-          <var-decl name='authenticated' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='686' column='1'/>
+          <var-decl name='authenticated' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='691' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='13'>
-          <var-decl name='wusb' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='687' column='1'/>
+          <var-decl name='wusb' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='692' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='14'>
-          <var-decl name='lpm_capable' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='688' column='1'/>
+          <var-decl name='lpm_capable' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='693' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='15'>
-          <var-decl name='usb2_hw_lpm_capable' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='689' column='1'/>
+          <var-decl name='usb2_hw_lpm_capable' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='694' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='16'>
-          <var-decl name='usb2_hw_lpm_besl_capable' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='690' column='1'/>
+          <var-decl name='usb2_hw_lpm_besl_capable' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='695' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='17'>
-          <var-decl name='usb2_hw_lpm_enabled' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='691' column='1'/>
+          <var-decl name='usb2_hw_lpm_enabled' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='696' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='18'>
-          <var-decl name='usb2_hw_lpm_allowed' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='692' column='1'/>
+          <var-decl name='usb2_hw_lpm_allowed' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='697' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='19'>
-          <var-decl name='usb3_lpm_u1_enabled' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='693' column='1'/>
+          <var-decl name='usb3_lpm_u1_enabled' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='698' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='20'>
-          <var-decl name='usb3_lpm_u2_enabled' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='694' column='1'/>
+          <var-decl name='usb3_lpm_u2_enabled' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='699' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11008'>
-          <var-decl name='string_langid' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='695' column='1'/>
+          <var-decl name='string_langid' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='700' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11072'>
-          <var-decl name='product' type-id='26a90f95' visibility='default' filepath='include/linux/usb.h' line='698' column='1'/>
+          <var-decl name='product' type-id='26a90f95' visibility='default' filepath='include/linux/usb.h' line='703' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11136'>
-          <var-decl name='manufacturer' type-id='26a90f95' visibility='default' filepath='include/linux/usb.h' line='699' column='1'/>
+          <var-decl name='manufacturer' type-id='26a90f95' visibility='default' filepath='include/linux/usb.h' line='704' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11200'>
-          <var-decl name='serial' type-id='26a90f95' visibility='default' filepath='include/linux/usb.h' line='700' column='1'/>
+          <var-decl name='serial' type-id='26a90f95' visibility='default' filepath='include/linux/usb.h' line='705' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11264'>
-          <var-decl name='filelist' type-id='72f469ec' visibility='default' filepath='include/linux/usb.h' line='702' column='1'/>
+          <var-decl name='filelist' type-id='72f469ec' visibility='default' filepath='include/linux/usb.h' line='707' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11392'>
-          <var-decl name='maxchild' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='704' column='1'/>
+          <var-decl name='maxchild' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='709' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11424'>
-          <var-decl name='quirks' type-id='19c2251e' visibility='default' filepath='include/linux/usb.h' line='706' column='1'/>
+          <var-decl name='quirks' type-id='19c2251e' visibility='default' filepath='include/linux/usb.h' line='711' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11456'>
-          <var-decl name='urbnum' type-id='49178f86' visibility='default' filepath='include/linux/usb.h' line='707' column='1'/>
+          <var-decl name='urbnum' type-id='49178f86' visibility='default' filepath='include/linux/usb.h' line='712' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11520'>
-          <var-decl name='active_duration' type-id='7359adad' visibility='default' filepath='include/linux/usb.h' line='709' column='1'/>
+          <var-decl name='active_duration' type-id='7359adad' visibility='default' filepath='include/linux/usb.h' line='714' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11584'>
-          <var-decl name='connect_time' type-id='7359adad' visibility='default' filepath='include/linux/usb.h' line='712' column='1'/>
+          <var-decl name='connect_time' type-id='7359adad' visibility='default' filepath='include/linux/usb.h' line='717' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='do_remote_wakeup' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='714' column='1'/>
+          <var-decl name='do_remote_wakeup' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='719' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1'>
-          <var-decl name='reset_resume' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='715' column='1'/>
+          <var-decl name='reset_resume' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='720' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2'>
-          <var-decl name='port_is_suspended' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='716' column='1'/>
+          <var-decl name='port_is_suspended' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='721' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11712'>
-          <var-decl name='wusb_dev' type-id='ca0a9af6' visibility='default' filepath='include/linux/usb.h' line='718' column='1'/>
+          <var-decl name='wusb_dev' type-id='ca0a9af6' visibility='default' filepath='include/linux/usb.h' line='723' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11776'>
-          <var-decl name='slot_id' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='719' column='1'/>
+          <var-decl name='slot_id' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='724' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11808'>
-          <var-decl name='removable' type-id='b9886e9f' visibility='default' filepath='include/linux/usb.h' line='720' column='1'/>
+          <var-decl name='removable' type-id='b9886e9f' visibility='default' filepath='include/linux/usb.h' line='725' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11840'>
-          <var-decl name='l1_params' type-id='07c4f5ca' visibility='default' filepath='include/linux/usb.h' line='721' column='1'/>
+          <var-decl name='l1_params' type-id='07c4f5ca' visibility='default' filepath='include/linux/usb.h' line='726' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11904'>
-          <var-decl name='u1_params' type-id='34bd0a0b' visibility='default' filepath='include/linux/usb.h' line='722' column='1'/>
+          <var-decl name='u1_params' type-id='34bd0a0b' visibility='default' filepath='include/linux/usb.h' line='727' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='12032'>
-          <var-decl name='u2_params' type-id='34bd0a0b' visibility='default' filepath='include/linux/usb.h' line='723' column='1'/>
+          <var-decl name='u2_params' type-id='34bd0a0b' visibility='default' filepath='include/linux/usb.h' line='728' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='12160'>
-          <var-decl name='lpm_disable_count' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='724' column='1'/>
+          <var-decl name='lpm_disable_count' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='729' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='12192'>
-          <var-decl name='hub_delay' type-id='1dc6a898' visibility='default' filepath='include/linux/usb.h' line='726' column='1'/>
+          <var-decl name='hub_delay' type-id='1dc6a898' visibility='default' filepath='include/linux/usb.h' line='731' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='16'>
-          <var-decl name='use_generic_driver' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='727' column='1'/>
+          <var-decl name='use_generic_driver' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='732' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='12224'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='729' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='734' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='12288'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='730' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='735' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='12352'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='731' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='736' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='12416'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='732' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='737' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='6ac80b14' size-in-bits='64' id='39c41052'/>
@@ -29366,18 +29528,18 @@
         <return type-id='b59d7dce'/>
       </function-type>
       <class-decl name='dirty_throttle_control' is-struct='yes' visibility='default' is-declaration-only='yes' id='3ad43c0e'/>
-      <class-decl name='typec_partner_desc' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/usb/typec.h' line='197' column='1' id='3ad5d94d'>
+      <class-decl name='typec_partner_desc' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/usb/typec.h' line='203' column='1' id='3ad5d94d'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='usb_pd' type-id='f0981eeb' visibility='default' filepath='include/linux/usb/typec.h' line='198' column='1'/>
+          <var-decl name='usb_pd' type-id='f0981eeb' visibility='default' filepath='include/linux/usb/typec.h' line='204' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='accessory' type-id='357a6a78' visibility='default' filepath='include/linux/usb/typec.h' line='199' column='1'/>
+          <var-decl name='accessory' type-id='357a6a78' visibility='default' filepath='include/linux/usb/typec.h' line='205' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='identity' type-id='09dbca85' visibility='default' filepath='include/linux/usb/typec.h' line='200' column='1'/>
+          <var-decl name='identity' type-id='09dbca85' visibility='default' filepath='include/linux/usb/typec.h' line='206' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='pd_revision' type-id='1dc6a898' visibility='default' filepath='include/linux/usb/typec.h' line='201' column='1'/>
+          <var-decl name='pd_revision' type-id='1dc6a898' visibility='default' filepath='include/linux/usb/typec.h' line='207' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='3ae10cc4'>
@@ -31016,12 +31178,12 @@
           <var-decl name='__i_nlink' type-id='f0981eeb' visibility='default' filepath='include/linux/fs.h' line='658' column='1'/>
         </data-member>
       </union-decl>
-      <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='468' column='1' id='3ee84947'>
+      <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='469' column='1' id='3ee84947'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='desc' type-id='7359adad' visibility='default' filepath='include/linux/skbuff.h' line='469' column='1'/>
+          <var-decl name='desc' type-id='7359adad' visibility='default' filepath='include/linux/skbuff.h' line='470' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='ctx' type-id='eaa32e2f' visibility='default' filepath='include/linux/skbuff.h' line='470' column='1'/>
+          <var-decl name='ctx' type-id='eaa32e2f' visibility='default' filepath='include/linux/skbuff.h' line='471' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='47308153' size-in-bits='64' id='3eef3bc7'/>
@@ -31508,7 +31670,7 @@
         <subrange length='7' type-id='7ff19f0f' id='16fc326e'/>
       </array-type-def>
       <pointer-type-def type-id='86af1d10' size-in-bits='64' id='3fab024e'/>
-      <enum-decl name='gro_result' filepath='include/linux/netdevice.h' line='381' column='1' id='3facc5aa'>
+      <enum-decl name='gro_result' filepath='include/linux/netdevice.h' line='383' column='1' id='3facc5aa'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='GRO_MERGED' value='0'/>
         <enumerator name='GRO_MERGED_FREE' value='1'/>
@@ -31529,12 +31691,12 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='abcb190c' size-in-bits='64' id='3fbbdf8e'/>
-      <class-decl name='ctl_table_set' size-in-bits='768' is-struct='yes' visibility='default' filepath='include/linux/sysctl.h' line='156' column='1' id='3fc3d262'>
+      <class-decl name='ctl_table_set' size-in-bits='768' is-struct='yes' visibility='default' filepath='include/linux/sysctl.h' line='166' column='1' id='3fc3d262'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='is_seen' type-id='35e8c658' visibility='default' filepath='include/linux/sysctl.h' line='157' column='1'/>
+          <var-decl name='is_seen' type-id='35e8c658' visibility='default' filepath='include/linux/sysctl.h' line='167' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='dir' type-id='7c7d6006' visibility='default' filepath='include/linux/sysctl.h' line='158' column='1'/>
+          <var-decl name='dir' type-id='7c7d6006' visibility='default' filepath='include/linux/sysctl.h' line='168' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='fscrypt_master_key_secret' size-in-bits='1152' is-struct='yes' visibility='default' filepath='fs/crypto/fscrypt_private.h' line='441' column='1' id='3fc794fa'>
@@ -31926,7 +32088,7 @@
           <var-decl name='flags' type-id='3f1a6b60' visibility='default' filepath='include/uapi/linux/bpf.h' line='695' column='1'/>
         </data-member>
       </class-decl>
-      <typedef-decl name='usb_complete_t' type-id='79dbccfb' filepath='include/linux/usb.h' line='1404' column='1' id='4086973b'/>
+      <typedef-decl name='usb_complete_t' type-id='79dbccfb' filepath='include/linux/usb.h' line='1412' column='1' id='4086973b'/>
       <function-type size-in-bits='64' id='40877b8a'>
         <parameter type-id='abd62a96'/>
         <return type-id='95e97e5e'/>
@@ -32079,36 +32241,36 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='2572f485' size-in-bits='64' id='40f624e9'/>
-      <class-decl name='usb_host_bos' size-in-bits='640' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='402' column='1' id='40f66efb'>
+      <class-decl name='usb_host_bos' size-in-bits='640' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='407' column='1' id='40f66efb'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='desc' type-id='d42add34' visibility='default' filepath='include/linux/usb.h' line='403' column='1'/>
+          <var-decl name='desc' type-id='d42add34' visibility='default' filepath='include/linux/usb.h' line='408' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='ext_cap' type-id='95e6deec' visibility='default' filepath='include/linux/usb.h' line='406' column='1'/>
+          <var-decl name='ext_cap' type-id='95e6deec' visibility='default' filepath='include/linux/usb.h' line='411' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='ss_cap' type-id='653a1605' visibility='default' filepath='include/linux/usb.h' line='407' column='1'/>
+          <var-decl name='ss_cap' type-id='653a1605' visibility='default' filepath='include/linux/usb.h' line='412' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='ssp_cap' type-id='9d8ff465' visibility='default' filepath='include/linux/usb.h' line='408' column='1'/>
+          <var-decl name='ssp_cap' type-id='9d8ff465' visibility='default' filepath='include/linux/usb.h' line='413' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='ss_id' type-id='4373df76' visibility='default' filepath='include/linux/usb.h' line='409' column='1'/>
+          <var-decl name='ss_id' type-id='4373df76' visibility='default' filepath='include/linux/usb.h' line='414' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='ptm_cap' type-id='9d94f8e4' visibility='default' filepath='include/linux/usb.h' line='410' column='1'/>
+          <var-decl name='ptm_cap' type-id='9d94f8e4' visibility='default' filepath='include/linux/usb.h' line='415' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='412' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='417' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='413' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='418' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='414' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='419' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='415' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='420' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='snd_soc_ops' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/sound/soc.h' line='724' column='1' id='40fc482f'>
@@ -33229,7 +33391,7 @@
           <var-decl name='reserved' type-id='839e8989' visibility='default' filepath='include/uapi/linux/media.h' line='233' column='1'/>
         </data-member>
       </class-decl>
-      <enum-decl name='typec_pwr_opmode' filepath='include/linux/usb/typec.h' line='55' column='1' id='44ea1984'>
+      <enum-decl name='typec_pwr_opmode' filepath='include/linux/usb/typec.h' line='56' column='1' id='44ea1984'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='TYPEC_PWR_MODE_USB' value='0'/>
         <enumerator name='TYPEC_PWR_MODE_1_5A' value='1'/>
@@ -33724,7 +33886,7 @@
         <parameter type-id='1c63cc3f'/>
         <return type-id='b59d7dce'/>
       </function-type>
-      <enum-decl name='sock_shutdown_cmd' filepath='include/linux/net.h' line='93' column='1' id='45c08bac'>
+      <enum-decl name='sock_shutdown_cmd' filepath='include/linux/net.h' line='91' column='1' id='45c08bac'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='SHUT_RD' value='0'/>
         <enumerator name='SHUT_WR' value='1'/>
@@ -33828,6 +33990,7 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='855e3679' size-in-bits='64' id='464f84a9'/>
+      <pointer-type-def type-id='80b5c3cd' size-in-bits='64' id='46530b39'/>
       <class-decl name='wake_irq' size-in-bits='192' is-struct='yes' visibility='default' filepath='drivers/base/power/power.h' line='31' column='1' id='4657336c'>
         <data-member access='public' layout-offset-in-bits='0'>
           <var-decl name='dev' type-id='fa0b179b' visibility='default' filepath='drivers/base/power/power.h' line='32' column='1'/>
@@ -34342,66 +34505,66 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='32197ce9' size-in-bits='64' id='47877f81'/>
-      <class-decl name='gs_port' size-in-bits='6016' is-struct='yes' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='98' column='1' id='4788f063'>
+      <class-decl name='gs_port' size-in-bits='6016' is-struct='yes' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='101' column='1' id='4788f063'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='port' type-id='7e1e521a' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='99' column='1'/>
+          <var-decl name='port' type-id='7e1e521a' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='102' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3392'>
-          <var-decl name='port_lock' type-id='fb4018a0' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='100' column='1'/>
+          <var-decl name='port_lock' type-id='fb4018a0' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='103' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3456'>
-          <var-decl name='port_usb' type-id='3921c1a0' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='102' column='1'/>
+          <var-decl name='port_usb' type-id='3921c1a0' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='105' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3520'>
-          <var-decl name='port_num' type-id='f9b06939' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='107' column='1'/>
+          <var-decl name='port_num' type-id='f9b06939' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='110' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3584'>
-          <var-decl name='read_pool' type-id='72f469ec' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='109' column='1'/>
+          <var-decl name='read_pool' type-id='72f469ec' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='112' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3712'>
-          <var-decl name='read_started' type-id='95e97e5e' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='110' column='1'/>
+          <var-decl name='read_started' type-id='95e97e5e' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='113' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3744'>
-          <var-decl name='read_allocated' type-id='95e97e5e' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='111' column='1'/>
+          <var-decl name='read_allocated' type-id='95e97e5e' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='114' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3776'>
-          <var-decl name='read_queue' type-id='72f469ec' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='112' column='1'/>
+          <var-decl name='read_queue' type-id='72f469ec' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='115' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3904'>
-          <var-decl name='n_read' type-id='f0981eeb' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='113' column='1'/>
+          <var-decl name='n_read' type-id='f0981eeb' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='116' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3968'>
-          <var-decl name='push' type-id='5ad6e0ef' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='114' column='1'/>
+          <var-decl name='push' type-id='5ad6e0ef' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='117' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5056'>
-          <var-decl name='write_pool' type-id='72f469ec' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='116' column='1'/>
+          <var-decl name='write_pool' type-id='72f469ec' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='119' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5184'>
-          <var-decl name='write_started' type-id='95e97e5e' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='117' column='1'/>
+          <var-decl name='write_started' type-id='95e97e5e' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='120' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5216'>
-          <var-decl name='write_allocated' type-id='95e97e5e' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='118' column='1'/>
+          <var-decl name='write_allocated' type-id='95e97e5e' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='121' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5248'>
-          <var-decl name='port_write_buf' type-id='7664edcc' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='119' column='1'/>
+          <var-decl name='port_write_buf' type-id='7664edcc' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='122' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5440'>
-          <var-decl name='drain_wait' type-id='b5ab048f' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='120' column='1'/>
+          <var-decl name='drain_wait' type-id='b5ab048f' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='123' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5632'>
-          <var-decl name='write_busy' type-id='b50a4934' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='121' column='1'/>
+          <var-decl name='write_busy' type-id='b50a4934' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='124' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5696'>
-          <var-decl name='close_wait' type-id='b5ab048f' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='122' column='1'/>
+          <var-decl name='close_wait' type-id='b5ab048f' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='125' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5888'>
-          <var-decl name='suspended' type-id='b50a4934' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='123' column='1'/>
+          <var-decl name='suspended' type-id='b50a4934' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='126' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5896'>
-          <var-decl name='start_delayed' type-id='b50a4934' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='124' column='1'/>
+          <var-decl name='start_delayed' type-id='b50a4934' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='127' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5904'>
-          <var-decl name='port_line_coding' type-id='d4a32434' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='127' column='1'/>
+          <var-decl name='port_line_coding' type-id='d4a32434' visibility='default' filepath='drivers/usb/gadget/function/u_serial.c' line='130' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='deferred_freelist_item' size-in-bits='256' is-struct='yes' visibility='default' filepath='drivers/dma-buf/heaps/deferred-free-helper.h' line='37' column='1' id='479592e1'>
@@ -34555,18 +34718,18 @@
       <pointer-type-def type-id='b9d8dce4' size-in-bits='64' id='47fc8c26'/>
       <pointer-type-def type-id='674bdea8' size-in-bits='64' id='4813c4da'/>
       <pointer-type-def type-id='81c3d1f5' size-in-bits='64' id='4814c3f9'/>
-      <class-decl name='ip_ra_chain' size-in-bits='320' is-struct='yes' visibility='default' filepath='include/net/ip.h' line='125' column='1' id='4816a146'>
+      <class-decl name='ip_ra_chain' size-in-bits='320' is-struct='yes' visibility='default' filepath='include/net/ip.h' line='127' column='1' id='4816a146'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='next' type-id='00c4cbac' visibility='default' filepath='include/net/ip.h' line='126' column='1'/>
+          <var-decl name='next' type-id='00c4cbac' visibility='default' filepath='include/net/ip.h' line='128' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='sk' type-id='f772df6d' visibility='default' filepath='include/net/ip.h' line='127' column='1'/>
+          <var-decl name='sk' type-id='f772df6d' visibility='default' filepath='include/net/ip.h' line='129' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='' type-id='4fa91678' visibility='default' filepath='include/net/ip.h' line='128' column='1'/>
+          <var-decl name='' type-id='4fa91678' visibility='default' filepath='include/net/ip.h' line='130' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/net/ip.h' line='132' column='1'/>
+          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/net/ip.h' line='134' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='d67e1739' size-in-bits='64' id='4817356d'/>
@@ -34577,60 +34740,60 @@
         <parameter type-id='83c1bde6'/>
         <return type-id='48b5725f'/>
       </function-type>
-      <class-decl name='dwc3_request' size-in-bits='1664' is-struct='yes' visibility='default' filepath='drivers/usb/dwc3/core.h' line='919' column='1' id='48288128'>
+      <class-decl name='dwc3_request' size-in-bits='1664' is-struct='yes' visibility='default' filepath='drivers/usb/dwc3/core.h' line='920' column='1' id='48288128'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='request' type-id='43806adf' visibility='default' filepath='drivers/usb/dwc3/core.h' line='920' column='1'/>
+          <var-decl name='request' type-id='43806adf' visibility='default' filepath='drivers/usb/dwc3/core.h' line='921' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='drivers/usb/dwc3/core.h' line='921' column='1'/>
+          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='drivers/usb/dwc3/core.h' line='922' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='dep' type-id='b31af340' visibility='default' filepath='drivers/usb/dwc3/core.h' line='922' column='1'/>
+          <var-decl name='dep' type-id='b31af340' visibility='default' filepath='drivers/usb/dwc3/core.h' line='923' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='sg' type-id='bf3ef905' visibility='default' filepath='drivers/usb/dwc3/core.h' line='923' column='1'/>
+          <var-decl name='sg' type-id='bf3ef905' visibility='default' filepath='drivers/usb/dwc3/core.h' line='924' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1088'>
-          <var-decl name='start_sg' type-id='bf3ef905' visibility='default' filepath='drivers/usb/dwc3/core.h' line='924' column='1'/>
+          <var-decl name='start_sg' type-id='bf3ef905' visibility='default' filepath='drivers/usb/dwc3/core.h' line='925' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='num_pending_sgs' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='926' column='1'/>
+          <var-decl name='num_pending_sgs' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='927' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1184'>
-          <var-decl name='num_queued_sgs' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='927' column='1'/>
+          <var-decl name='num_queued_sgs' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='928' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='remaining' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='928' column='1'/>
+          <var-decl name='remaining' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='929' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1248'>
-          <var-decl name='status' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='930' column='1'/>
+          <var-decl name='status' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='931' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1280'>
-          <var-decl name='epnum' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='939' column='1'/>
+          <var-decl name='epnum' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='940' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1344'>
-          <var-decl name='trb' type-id='0d6a59e1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='940' column='1'/>
+          <var-decl name='trb' type-id='0d6a59e1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='941' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1408'>
-          <var-decl name='trb_dma' type-id='cf29c9b3' visibility='default' filepath='drivers/usb/dwc3/core.h' line='941' column='1'/>
+          <var-decl name='trb_dma' type-id='cf29c9b3' visibility='default' filepath='drivers/usb/dwc3/core.h' line='942' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1472'>
-          <var-decl name='num_trbs' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='943' column='1'/>
+          <var-decl name='num_trbs' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='944' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='needs_extra_trb' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='945' column='1'/>
+          <var-decl name='needs_extra_trb' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='946' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1'>
-          <var-decl name='direction' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='946' column='1'/>
+          <var-decl name='direction' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='947' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2'>
-          <var-decl name='mapped' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='947' column='1'/>
+          <var-decl name='mapped' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='948' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='949' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='950' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1600'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='950' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='951' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='08594205' size-in-bits='64' id='482ccc39'/>
@@ -34939,57 +35102,57 @@
         <return type-id='95e97e5e'/>
       </function-type>
       <pointer-type-def type-id='54f638e6' size-in-bits='64' id='49a58c0c'/>
-      <class-decl name='netdev_queue' size-in-bits='3584' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='593' column='1' id='49a7c5a7'>
+      <class-decl name='netdev_queue' size-in-bits='3584' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='595' column='1' id='49a7c5a7'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='dev' type-id='68a2d05b' visibility='default' filepath='include/linux/netdevice.h' line='597' column='1'/>
+          <var-decl name='dev' type-id='68a2d05b' visibility='default' filepath='include/linux/netdevice.h' line='599' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='qdisc' type-id='ee406209' visibility='default' filepath='include/linux/netdevice.h' line='598' column='1'/>
+          <var-decl name='qdisc' type-id='ee406209' visibility='default' filepath='include/linux/netdevice.h' line='600' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='qdisc_sleeping' type-id='ee406209' visibility='default' filepath='include/linux/netdevice.h' line='599' column='1'/>
+          <var-decl name='qdisc_sleeping' type-id='ee406209' visibility='default' filepath='include/linux/netdevice.h' line='601' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='kobj' type-id='b6ab8849' visibility='default' filepath='include/linux/netdevice.h' line='601' column='1'/>
+          <var-decl name='kobj' type-id='b6ab8849' visibility='default' filepath='include/linux/netdevice.h' line='603' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='tx_maxrate' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='606' column='1'/>
+          <var-decl name='tx_maxrate' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='608' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='trans_timeout' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='611' column='1'/>
+          <var-decl name='trans_timeout' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='613' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1088'>
-          <var-decl name='sb_dev' type-id='68a2d05b' visibility='default' filepath='include/linux/netdevice.h' line='614' column='1'/>
+          <var-decl name='sb_dev' type-id='68a2d05b' visibility='default' filepath='include/linux/netdevice.h' line='616' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='pool' type-id='81e0c1b8' visibility='default' filepath='include/linux/netdevice.h' line='616' column='1'/>
+          <var-decl name='pool' type-id='81e0c1b8' visibility='default' filepath='include/linux/netdevice.h' line='618' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='_xmit_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/netdevice.h' line='621' column='1'/>
+          <var-decl name='_xmit_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/netdevice.h' line='623' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1568'>
-          <var-decl name='xmit_lock_owner' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='622' column='1'/>
+          <var-decl name='xmit_lock_owner' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='624' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1600'>
-          <var-decl name='trans_start' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='626' column='1'/>
+          <var-decl name='trans_start' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='628' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1664'>
-          <var-decl name='state' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='628' column='1'/>
+          <var-decl name='state' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='630' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2048'>
-          <var-decl name='dql' type-id='471cb386' visibility='default' filepath='include/linux/netdevice.h' line='631' column='1'/>
+          <var-decl name='dql' type-id='471cb386' visibility='default' filepath='include/linux/netdevice.h' line='633' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3072'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='634' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='636' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3136'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='635' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='637' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3200'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='636' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='638' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3264'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='637' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='639' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='ehci_sitd' size-in-bits='768' is-struct='yes' visibility='default' filepath='drivers/usb/host/ehci.h' line='553' column='1' id='49addcd9'>
@@ -35361,21 +35524,21 @@
         <enumerator name='SERDEV_PARITY_EVEN' value='1'/>
         <enumerator name='SERDEV_PARITY_ODD' value='2'/>
       </enum-decl>
-      <class-decl name='snd_soc_dapm_route' size-in-bits='768' is-struct='yes' visibility='default' filepath='include/sound/soc-dapm.h' line='572' column='1' id='4a91f65b'>
+      <class-decl name='snd_soc_dapm_route' size-in-bits='768' is-struct='yes' visibility='default' filepath='include/sound/soc-dapm.h' line='573' column='1' id='4a91f65b'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='sink' type-id='80f4b756' visibility='default' filepath='include/sound/soc-dapm.h' line='573' column='1'/>
+          <var-decl name='sink' type-id='80f4b756' visibility='default' filepath='include/sound/soc-dapm.h' line='574' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='control' type-id='80f4b756' visibility='default' filepath='include/sound/soc-dapm.h' line='574' column='1'/>
+          <var-decl name='control' type-id='80f4b756' visibility='default' filepath='include/sound/soc-dapm.h' line='575' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='source' type-id='80f4b756' visibility='default' filepath='include/sound/soc-dapm.h' line='575' column='1'/>
+          <var-decl name='source' type-id='80f4b756' visibility='default' filepath='include/sound/soc-dapm.h' line='576' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='connected' type-id='4b433675' visibility='default' filepath='include/sound/soc-dapm.h' line='578' column='1'/>
+          <var-decl name='connected' type-id='4b433675' visibility='default' filepath='include/sound/soc-dapm.h' line='579' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='dobj' type-id='01edcafc' visibility='default' filepath='include/sound/soc-dapm.h' line='581' column='1'/>
+          <var-decl name='dobj' type-id='01edcafc' visibility='default' filepath='include/sound/soc-dapm.h' line='582' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='d5ace205' size-in-bits='64' id='4a935625'/>
@@ -35956,153 +36119,153 @@
         <parameter type-id='1c936db9'/>
         <return type-id='721b74e7'/>
       </function-type>
-      <class-decl name='tty_struct' size-in-bits='6720' is-struct='yes' visibility='default' filepath='include/linux/tty.h' line='290' column='1' id='4c8d9cac'>
+      <class-decl name='tty_struct' size-in-bits='6720' is-struct='yes' visibility='default' filepath='include/linux/tty.h' line='266' column='1' id='4c8d9cac'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='magic' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='291' column='1'/>
+          <var-decl name='magic' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='267' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='kref' type-id='400fb07b' visibility='default' filepath='include/linux/tty.h' line='292' column='1'/>
+          <var-decl name='kref' type-id='400fb07b' visibility='default' filepath='include/linux/tty.h' line='268' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='dev' type-id='fa0b179b' visibility='default' filepath='include/linux/tty.h' line='293' column='1'/>
+          <var-decl name='dev' type-id='fa0b179b' visibility='default' filepath='include/linux/tty.h' line='269' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='driver' type-id='c2b4b27b' visibility='default' filepath='include/linux/tty.h' line='294' column='1'/>
+          <var-decl name='driver' type-id='c2b4b27b' visibility='default' filepath='include/linux/tty.h' line='270' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='ops' type-id='f2c18b44' visibility='default' filepath='include/linux/tty.h' line='295' column='1'/>
+          <var-decl name='ops' type-id='f2c18b44' visibility='default' filepath='include/linux/tty.h' line='271' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='index' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='296' column='1'/>
+          <var-decl name='index' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='272' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='ldisc_sem' type-id='d3aa38f0' visibility='default' filepath='include/linux/tty.h' line='299' column='1'/>
+          <var-decl name='ldisc_sem' type-id='d3aa38f0' visibility='default' filepath='include/linux/tty.h' line='275' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='ldisc' type-id='e0bbd59c' visibility='default' filepath='include/linux/tty.h' line='300' column='1'/>
+          <var-decl name='ldisc' type-id='e0bbd59c' visibility='default' filepath='include/linux/tty.h' line='276' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='atomic_write_lock' type-id='925167dc' visibility='default' filepath='include/linux/tty.h' line='302' column='1'/>
+          <var-decl name='atomic_write_lock' type-id='925167dc' visibility='default' filepath='include/linux/tty.h' line='278' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='legacy_mutex' type-id='925167dc' visibility='default' filepath='include/linux/tty.h' line='303' column='1'/>
+          <var-decl name='legacy_mutex' type-id='925167dc' visibility='default' filepath='include/linux/tty.h' line='279' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='throttle_mutex' type-id='925167dc' visibility='default' filepath='include/linux/tty.h' line='304' column='1'/>
+          <var-decl name='throttle_mutex' type-id='925167dc' visibility='default' filepath='include/linux/tty.h' line='280' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1920'>
-          <var-decl name='termios_rwsem' type-id='f19fdb93' visibility='default' filepath='include/linux/tty.h' line='305' column='1'/>
+          <var-decl name='termios_rwsem' type-id='f19fdb93' visibility='default' filepath='include/linux/tty.h' line='281' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2432'>
-          <var-decl name='winsize_mutex' type-id='925167dc' visibility='default' filepath='include/linux/tty.h' line='306' column='1'/>
+          <var-decl name='winsize_mutex' type-id='925167dc' visibility='default' filepath='include/linux/tty.h' line='282' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2816'>
-          <var-decl name='ctrl_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/tty.h' line='307' column='1'/>
+          <var-decl name='ctrl_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/tty.h' line='283' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2848'>
-          <var-decl name='flow_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/tty.h' line='308' column='1'/>
+          <var-decl name='flow_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/tty.h' line='284' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2880'>
-          <var-decl name='termios' type-id='2f8662b5' visibility='default' filepath='include/linux/tty.h' line='310' column='1'/>
+          <var-decl name='termios' type-id='2f8662b5' visibility='default' filepath='include/linux/tty.h' line='286' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3232'>
-          <var-decl name='termios_locked' type-id='2f8662b5' visibility='default' filepath='include/linux/tty.h' line='310' column='1'/>
+          <var-decl name='termios_locked' type-id='2f8662b5' visibility='default' filepath='include/linux/tty.h' line='286' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3584'>
-          <var-decl name='termiox' type-id='684d860d' visibility='default' filepath='include/linux/tty.h' line='313' column='1'/>
+          <var-decl name='termiox' type-id='684d860d' visibility='default' filepath='include/linux/tty.h' line='289' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3648'>
-          <var-decl name='name' type-id='59daf3ef' visibility='default' filepath='include/linux/tty.h' line='315' column='1'/>
+          <var-decl name='name' type-id='59daf3ef' visibility='default' filepath='include/linux/tty.h' line='291' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4160'>
-          <var-decl name='pgrp' type-id='b94e5398' visibility='default' filepath='include/linux/tty.h' line='316' column='1'/>
+          <var-decl name='pgrp' type-id='b94e5398' visibility='default' filepath='include/linux/tty.h' line='292' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4224'>
-          <var-decl name='session' type-id='b94e5398' visibility='default' filepath='include/linux/tty.h' line='321' column='1'/>
+          <var-decl name='session' type-id='b94e5398' visibility='default' filepath='include/linux/tty.h' line='297' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4288'>
-          <var-decl name='flags' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='322' column='1'/>
+          <var-decl name='flags' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='298' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4352'>
-          <var-decl name='count' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='323' column='1'/>
+          <var-decl name='count' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='299' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4384'>
-          <var-decl name='winsize' type-id='a818b7a0' visibility='default' filepath='include/linux/tty.h' line='324' column='1'/>
+          <var-decl name='winsize' type-id='a818b7a0' visibility='default' filepath='include/linux/tty.h' line='300' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='stopped' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='325' column='1'/>
+          <var-decl name='stopped' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='301' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='33'>
-          <var-decl name='flow_stopped' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='326' column='1'/>
+          <var-decl name='flow_stopped' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='302' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='unused' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='327' column='1'/>
+          <var-decl name='unused' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='303' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4544'>
-          <var-decl name='hw_stopped' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='328' column='1'/>
+          <var-decl name='hw_stopped' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='304' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='ctrl_status' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='329' column='1'/>
+          <var-decl name='ctrl_status' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='305' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='40'>
-          <var-decl name='packet' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='330' column='1'/>
+          <var-decl name='packet' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='306' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='unused_ctrl' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='331' column='1'/>
+          <var-decl name='unused_ctrl' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='307' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4672'>
-          <var-decl name='receive_room' type-id='f0981eeb' visibility='default' filepath='include/linux/tty.h' line='332' column='1'/>
+          <var-decl name='receive_room' type-id='f0981eeb' visibility='default' filepath='include/linux/tty.h' line='308' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4704'>
-          <var-decl name='flow_change' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='333' column='1'/>
+          <var-decl name='flow_change' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='309' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4736'>
-          <var-decl name='link' type-id='572fbdca' visibility='default' filepath='include/linux/tty.h' line='335' column='1'/>
+          <var-decl name='link' type-id='572fbdca' visibility='default' filepath='include/linux/tty.h' line='311' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4800'>
-          <var-decl name='fasync' type-id='5bb9c75d' visibility='default' filepath='include/linux/tty.h' line='336' column='1'/>
+          <var-decl name='fasync' type-id='5bb9c75d' visibility='default' filepath='include/linux/tty.h' line='312' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4864'>
-          <var-decl name='write_wait' type-id='b5ab048f' visibility='default' filepath='include/linux/tty.h' line='337' column='1'/>
+          <var-decl name='write_wait' type-id='b5ab048f' visibility='default' filepath='include/linux/tty.h' line='313' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5056'>
-          <var-decl name='read_wait' type-id='b5ab048f' visibility='default' filepath='include/linux/tty.h' line='338' column='1'/>
+          <var-decl name='read_wait' type-id='b5ab048f' visibility='default' filepath='include/linux/tty.h' line='314' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5248'>
-          <var-decl name='hangup_work' type-id='ef9025d0' visibility='default' filepath='include/linux/tty.h' line='339' column='1'/>
+          <var-decl name='hangup_work' type-id='ef9025d0' visibility='default' filepath='include/linux/tty.h' line='315' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5632'>
-          <var-decl name='disc_data' type-id='eaa32e2f' visibility='default' filepath='include/linux/tty.h' line='340' column='1'/>
+          <var-decl name='disc_data' type-id='eaa32e2f' visibility='default' filepath='include/linux/tty.h' line='316' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5696'>
-          <var-decl name='driver_data' type-id='eaa32e2f' visibility='default' filepath='include/linux/tty.h' line='341' column='1'/>
+          <var-decl name='driver_data' type-id='eaa32e2f' visibility='default' filepath='include/linux/tty.h' line='317' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5760'>
-          <var-decl name='files_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/tty.h' line='342' column='1'/>
+          <var-decl name='files_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/tty.h' line='318' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5824'>
-          <var-decl name='tty_files' type-id='72f469ec' visibility='default' filepath='include/linux/tty.h' line='343' column='1'/>
+          <var-decl name='tty_files' type-id='72f469ec' visibility='default' filepath='include/linux/tty.h' line='319' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5952'>
-          <var-decl name='closing' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='347' column='1'/>
+          <var-decl name='closing' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='323' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6016'>
-          <var-decl name='write_buf' type-id='cf536864' visibility='default' filepath='include/linux/tty.h' line='348' column='1'/>
+          <var-decl name='write_buf' type-id='cf536864' visibility='default' filepath='include/linux/tty.h' line='324' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6080'>
-          <var-decl name='write_cnt' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='349' column='1'/>
+          <var-decl name='write_cnt' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='325' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6144'>
-          <var-decl name='SAK_work' type-id='ef9025d0' visibility='default' filepath='include/linux/tty.h' line='351' column='1'/>
+          <var-decl name='SAK_work' type-id='ef9025d0' visibility='default' filepath='include/linux/tty.h' line='327' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6528'>
-          <var-decl name='port' type-id='ec77b5b8' visibility='default' filepath='include/linux/tty.h' line='352' column='1'/>
+          <var-decl name='port' type-id='ec77b5b8' visibility='default' filepath='include/linux/tty.h' line='328' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6592'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/tty.h' line='354' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/tty.h' line='330' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6656'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/tty.h' line='355' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/tty.h' line='331' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='a5dc8838' size-in-bits='64' id='4c9695fa'/>
@@ -36598,105 +36761,105 @@
         <subrange length='6' type-id='7ff19f0f' id='52fa524b'/>
       </array-type-def>
       <pointer-type-def type-id='850c13f6' size-in-bits='64' id='4e034354'/>
-      <class-decl name='proto_ops' size-in-bits='2048' is-struct='yes' visibility='default' filepath='include/linux/net.h' line='140' column='1' id='4e0399c2'>
+      <class-decl name='proto_ops' size-in-bits='2048' is-struct='yes' visibility='default' filepath='include/linux/net.h' line='138' column='1' id='4e0399c2'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='family' type-id='95e97e5e' visibility='default' filepath='include/linux/net.h' line='141' column='1'/>
+          <var-decl name='family' type-id='95e97e5e' visibility='default' filepath='include/linux/net.h' line='139' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='flags' type-id='f0981eeb' visibility='default' filepath='include/linux/net.h' line='142' column='1'/>
+          <var-decl name='flags' type-id='f0981eeb' visibility='default' filepath='include/linux/net.h' line='140' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='owner' type-id='2730d015' visibility='default' filepath='include/linux/net.h' line='143' column='1'/>
+          <var-decl name='owner' type-id='2730d015' visibility='default' filepath='include/linux/net.h' line='142' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='release' type-id='27936440' visibility='default' filepath='include/linux/net.h' line='144' column='1'/>
+          <var-decl name='release' type-id='27936440' visibility='default' filepath='include/linux/net.h' line='143' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='bind' type-id='c9664af8' visibility='default' filepath='include/linux/net.h' line='145' column='1'/>
+          <var-decl name='bind' type-id='c9664af8' visibility='default' filepath='include/linux/net.h' line='144' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='connect' type-id='be6c7be7' visibility='default' filepath='include/linux/net.h' line='148' column='1'/>
+          <var-decl name='connect' type-id='be6c7be7' visibility='default' filepath='include/linux/net.h' line='147' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='socketpair' type-id='be3a232b' visibility='default' filepath='include/linux/net.h' line='151' column='1'/>
+          <var-decl name='socketpair' type-id='be3a232b' visibility='default' filepath='include/linux/net.h' line='150' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='accept' type-id='2136470b' visibility='default' filepath='include/linux/net.h' line='153' column='1'/>
+          <var-decl name='accept' type-id='2136470b' visibility='default' filepath='include/linux/net.h' line='152' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='getname' type-id='c9664af8' visibility='default' filepath='include/linux/net.h' line='155' column='1'/>
+          <var-decl name='getname' type-id='c9664af8' visibility='default' filepath='include/linux/net.h' line='154' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='poll' type-id='e93ad56e' visibility='default' filepath='include/linux/net.h' line='158' column='1'/>
+          <var-decl name='poll' type-id='e93ad56e' visibility='default' filepath='include/linux/net.h' line='157' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='ioctl' type-id='82a9a11e' visibility='default' filepath='include/linux/net.h' line='160' column='1'/>
+          <var-decl name='ioctl' type-id='82a9a11e' visibility='default' filepath='include/linux/net.h' line='159' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='compat_ioctl' type-id='82a9a11e' visibility='default' filepath='include/linux/net.h' line='163' column='1'/>
+          <var-decl name='compat_ioctl' type-id='82a9a11e' visibility='default' filepath='include/linux/net.h' line='162' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='gettstamp' type-id='d78dd406' visibility='default' filepath='include/linux/net.h' line='166' column='1'/>
+          <var-decl name='gettstamp' type-id='d78dd406' visibility='default' filepath='include/linux/net.h' line='165' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='listen' type-id='6dfd92af' visibility='default' filepath='include/linux/net.h' line='168' column='1'/>
+          <var-decl name='listen' type-id='6dfd92af' visibility='default' filepath='include/linux/net.h' line='167' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='shutdown' type-id='6dfd92af' visibility='default' filepath='include/linux/net.h' line='169' column='1'/>
+          <var-decl name='shutdown' type-id='6dfd92af' visibility='default' filepath='include/linux/net.h' line='168' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='setsockopt' type-id='47365a28' visibility='default' filepath='include/linux/net.h' line='170' column='1'/>
+          <var-decl name='setsockopt' type-id='47365a28' visibility='default' filepath='include/linux/net.h' line='169' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='getsockopt' type-id='a9c0cdab' visibility='default' filepath='include/linux/net.h' line='173' column='1'/>
+          <var-decl name='getsockopt' type-id='a9c0cdab' visibility='default' filepath='include/linux/net.h' line='172' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='show_fdinfo' type-id='1767a135' visibility='default' filepath='include/linux/net.h' line='175' column='1'/>
+          <var-decl name='show_fdinfo' type-id='1767a135' visibility='default' filepath='include/linux/net.h' line='174' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1088'>
-          <var-decl name='sendmsg' type-id='f38728c0' visibility='default' filepath='include/linux/net.h' line='176' column='1'/>
+          <var-decl name='sendmsg' type-id='f38728c0' visibility='default' filepath='include/linux/net.h' line='175' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='recvmsg' type-id='93abc02f' visibility='default' filepath='include/linux/net.h' line='186' column='1'/>
+          <var-decl name='recvmsg' type-id='93abc02f' visibility='default' filepath='include/linux/net.h' line='185' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='mmap' type-id='3eef3bc7' visibility='default' filepath='include/linux/net.h' line='188' column='1'/>
+          <var-decl name='mmap' type-id='3eef3bc7' visibility='default' filepath='include/linux/net.h' line='187' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1280'>
-          <var-decl name='sendpage' type-id='42b02383' visibility='default' filepath='include/linux/net.h' line='190' column='1'/>
+          <var-decl name='sendpage' type-id='42b02383' visibility='default' filepath='include/linux/net.h' line='189' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1344'>
-          <var-decl name='splice_read' type-id='21641a6b' visibility='default' filepath='include/linux/net.h' line='192' column='1'/>
+          <var-decl name='splice_read' type-id='21641a6b' visibility='default' filepath='include/linux/net.h' line='191' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1408'>
-          <var-decl name='set_peek_off' type-id='95208a5e' visibility='default' filepath='include/linux/net.h' line='194' column='1'/>
+          <var-decl name='set_peek_off' type-id='95208a5e' visibility='default' filepath='include/linux/net.h' line='193' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1472'>
-          <var-decl name='peek_len' type-id='27936440' visibility='default' filepath='include/linux/net.h' line='195' column='1'/>
+          <var-decl name='peek_len' type-id='27936440' visibility='default' filepath='include/linux/net.h' line='194' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='read_sock' type-id='8755cc63' visibility='default' filepath='include/linux/net.h' line='200' column='1'/>
+          <var-decl name='read_sock' type-id='8755cc63' visibility='default' filepath='include/linux/net.h' line='199' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1600'>
-          <var-decl name='sendpage_locked' type-id='65399e23' visibility='default' filepath='include/linux/net.h' line='202' column='1'/>
+          <var-decl name='sendpage_locked' type-id='65399e23' visibility='default' filepath='include/linux/net.h' line='201' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1664'>
-          <var-decl name='sendmsg_locked' type-id='1df08751' visibility='default' filepath='include/linux/net.h' line='204' column='1'/>
+          <var-decl name='sendmsg_locked' type-id='1df08751' visibility='default' filepath='include/linux/net.h' line='203' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1728'>
-          <var-decl name='set_rcvlowat' type-id='95208a5e' visibility='default' filepath='include/linux/net.h' line='206' column='1'/>
+          <var-decl name='set_rcvlowat' type-id='95208a5e' visibility='default' filepath='include/linux/net.h' line='205' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1792'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/net.h' line='208' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/net.h' line='207' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1856'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/net.h' line='209' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/net.h' line='208' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1920'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/net.h' line='210' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/net.h' line='209' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1984'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/net.h' line='211' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/net.h' line='210' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='4e0a6ade'>
@@ -37071,12 +37234,12 @@
         </data-member>
       </union-decl>
       <pointer-type-def type-id='9487d957' size-in-bits='64' id='4edb5fc7'/>
-      <class-decl name='xps_dev_maps' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='810' column='1' id='4edc4180'>
+      <class-decl name='xps_dev_maps' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='815' column='1' id='4edc4180'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/netdevice.h' line='811' column='1'/>
+          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/netdevice.h' line='816' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='attr_map' type-id='a0955e2b' visibility='default' filepath='include/linux/netdevice.h' line='812' column='1'/>
+          <var-decl name='attr_map' type-id='a0955e2b' visibility='default' filepath='include/linux/netdevice.h' line='817' column='1'/>
         </data-member>
       </class-decl>
       <typedef-decl name='rcu_callback_t' type-id='eb839374' filepath='include/linux/types.h' line='222' column='1' id='4edd56e3'/>
@@ -37298,12 +37461,12 @@
         <parameter type-id='eaa32e2f'/>
         <return type-id='855e3679'/>
       </function-type>
-      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/net/ip.h' line='128' column='1' id='4fa91678'>
+      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/net/ip.h' line='130' column='1' id='4fa91678'>
         <data-member access='public'>
-          <var-decl name='destructor' type-id='841969d0' visibility='default' filepath='include/net/ip.h' line='129' column='1'/>
+          <var-decl name='destructor' type-id='841969d0' visibility='default' filepath='include/net/ip.h' line='131' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='saved_sk' type-id='f772df6d' visibility='default' filepath='include/net/ip.h' line='130' column='1'/>
+          <var-decl name='saved_sk' type-id='f772df6d' visibility='default' filepath='include/net/ip.h' line='132' column='1'/>
         </data-member>
       </union-decl>
       <function-type size-in-bits='64' id='4fab04f8'>
@@ -37916,38 +38079,6 @@
       <pointer-type-def type-id='08cbad52' size-in-bits='64' id='50a213e8'/>
       <pointer-type-def type-id='48b94b91' size-in-bits='64' id='50a51839'/>
       <pointer-type-def type-id='7552fc26' size-in-bits='64' id='50abd760'/>
-      <class-decl name='io_identity' size-in-bits='576' is-struct='yes' visibility='default' filepath='include/linux/io_uring.h' line='8' column='1' id='50ac43c8'>
-        <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='files' type-id='16c53416' visibility='default' filepath='include/linux/io_uring.h' line='9' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='mm' type-id='df4b7819' visibility='default' filepath='include/linux/io_uring.h' line='10' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='blkcg_css' type-id='cfff5953' visibility='default' filepath='include/linux/io_uring.h' line='12' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='creds' type-id='bc33861a' visibility='default' filepath='include/linux/io_uring.h' line='14' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='nsproxy' type-id='dc5ce118' visibility='default' filepath='include/linux/io_uring.h' line='15' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='fs' type-id='08890290' visibility='default' filepath='include/linux/io_uring.h' line='16' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='fsize' type-id='7359adad' visibility='default' filepath='include/linux/io_uring.h' line='17' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='loginuid' type-id='d80b72e6' visibility='default' filepath='include/linux/io_uring.h' line='19' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='480'>
-          <var-decl name='sessionid' type-id='f0981eeb' visibility='default' filepath='include/linux/io_uring.h' line='20' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='count' type-id='64615833' visibility='default' filepath='include/linux/io_uring.h' line='22' column='1'/>
-        </data-member>
-      </class-decl>
       <function-type size-in-bits='64' id='50acc06b'>
         <parameter type-id='f772df6d'/>
         <return type-id='19c2251e'/>
@@ -38164,7 +38295,7 @@
         <enumerator name='IEEE80211_EDMG_BW_CONFIG_14' value='14'/>
         <enumerator name='IEEE80211_EDMG_BW_CONFIG_15' value='15'/>
       </enum-decl>
-      <typedef-decl name='sk_read_actor_t' type-id='0c197ddf' filepath='include/linux/net.h' line='137' column='1' id='514d4e0e'/>
+      <typedef-decl name='sk_read_actor_t' type-id='0c197ddf' filepath='include/linux/net.h' line='135' column='1' id='514d4e0e'/>
       <class-decl name='of_phandle_iterator' size-in-bits='512' is-struct='yes' visibility='default' filepath='include/linux/of.h' line='80' column='1' id='514d8c48'>
         <data-member access='public' layout-offset-in-bits='0'>
           <var-decl name='cells_name' type-id='80f4b756' visibility='default' filepath='include/linux/of.h' line='82' column='1'/>
@@ -38613,32 +38744,32 @@
           <var-decl name='set_promiscuous_mode' type-id='b8afdb72' visibility='default' filepath='include/net/mac802154.h' line='231' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='mipi_dsi_driver' size-in-bits='1600' is-struct='yes' visibility='default' filepath='include/drm/drm_mipi_dsi.h' line='306' column='1' id='51d715c2'>
+      <class-decl name='mipi_dsi_driver' size-in-bits='1600' is-struct='yes' visibility='default' filepath='include/drm/drm_mipi_dsi.h' line='310' column='1' id='51d715c2'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='driver' type-id='fe007c02' visibility='default' filepath='include/drm/drm_mipi_dsi.h' line='307' column='1'/>
+          <var-decl name='driver' type-id='fe007c02' visibility='default' filepath='include/drm/drm_mipi_dsi.h' line='311' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1408'>
-          <var-decl name='probe' type-id='289e8bdc' visibility='default' filepath='include/drm/drm_mipi_dsi.h' line='308' column='1'/>
+          <var-decl name='probe' type-id='289e8bdc' visibility='default' filepath='include/drm/drm_mipi_dsi.h' line='312' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1472'>
-          <var-decl name='remove' type-id='289e8bdc' visibility='default' filepath='include/drm/drm_mipi_dsi.h' line='309' column='1'/>
+          <var-decl name='remove' type-id='289e8bdc' visibility='default' filepath='include/drm/drm_mipi_dsi.h' line='313' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='shutdown' type-id='fea4b945' visibility='default' filepath='include/drm/drm_mipi_dsi.h' line='310' column='1'/>
+          <var-decl name='shutdown' type-id='fea4b945' visibility='default' filepath='include/drm/drm_mipi_dsi.h' line='314' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='924' column='1' id='51db537c'>
+      <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='930' column='1' id='51db537c'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='scm_io_uring' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='924' column='1'/>
+          <var-decl name='scm_io_uring' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='930' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8'>
-          <var-decl name='android_kabi_reserved1_padding1' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='924' column='1'/>
+          <var-decl name='android_kabi_reserved1_padding1' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='930' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='16'>
-          <var-decl name='android_kabi_reserved1_padding2' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='924' column='1'/>
+          <var-decl name='android_kabi_reserved1_padding2' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='930' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='android_kabi_reserved1_padding3' type-id='3f1a6b60' visibility='default' filepath='include/linux/skbuff.h' line='924' column='1'/>
+          <var-decl name='android_kabi_reserved1_padding3' type-id='3f1a6b60' visibility='default' filepath='include/linux/skbuff.h' line='930' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='net_rate_estimator' is-struct='yes' visibility='default' is-declaration-only='yes' id='51dbeb7e'/>
@@ -38675,7 +38806,14 @@
         <parameter type-id='a42536cd'/>
         <return type-id='a42536cd'/>
       </function-type>
-      <class-decl name='raw_hashinfo' is-struct='yes' visibility='default' is-declaration-only='yes' id='51ee3086'/>
+      <class-decl name='raw_hashinfo' size-in-bits='16448' is-struct='yes' visibility='default' filepath='include/net/raw.h' line='35' column='1' id='51ee3086'>
+        <data-member access='public' layout-offset-in-bits='0'>
+          <var-decl name='lock' type-id='ac16795b' visibility='default' filepath='include/net/raw.h' line='36' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='64'>
+          <var-decl name='ht' type-id='a7c26c7b' visibility='default' filepath='include/net/raw.h' line='37' column='1'/>
+        </data-member>
+      </class-decl>
       <pointer-type-def type-id='918531c2' size-in-bits='64' id='51f1236c'/>
       <pointer-type-def type-id='25c33493' size-in-bits='64' id='52006477'/>
       <pointer-type-def type-id='cd1fc343' size-in-bits='64' id='52009e4b'/>
@@ -39323,9 +39461,9 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='fb246cd7' size-in-bits='64' id='53f7c7e3'/>
-      <class-decl name='execute_work' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/workqueue.h' line='174' column='1' id='53f7ea88'>
+      <class-decl name='execute_work' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/workqueue.h' line='175' column='1' id='53f7ea88'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='work' type-id='ef9025d0' visibility='default' filepath='include/linux/workqueue.h' line='175' column='1'/>
+          <var-decl name='work' type-id='ef9025d0' visibility='default' filepath='include/linux/workqueue.h' line='176' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='spinlock' size-in-bits='32' is-struct='yes' visibility='default' filepath='include/linux/spinlock_types.h' line='71' column='1' id='53fb272e'>
@@ -39544,60 +39682,60 @@
           <var-decl name='' type-id='7432b366' visibility='default' filepath='include/linux/io-pgtable.h' line='96' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='tcp_congestion_ops' size-in-bits='1216' is-struct='yes' visibility='default' filepath='include/net/tcp.h' line='1062' column='1' id='54718f09'>
+      <class-decl name='tcp_congestion_ops' size-in-bits='1216' is-struct='yes' visibility='default' filepath='include/net/tcp.h' line='1063' column='1' id='54718f09'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/net/tcp.h' line='1063' column='1'/>
+          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/net/tcp.h' line='1064' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='key' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1064' column='1'/>
+          <var-decl name='key' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1065' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='160'>
-          <var-decl name='flags' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1065' column='1'/>
+          <var-decl name='flags' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1066' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='init' type-id='841969d0' visibility='default' filepath='include/net/tcp.h' line='1068' column='1'/>
+          <var-decl name='init' type-id='841969d0' visibility='default' filepath='include/net/tcp.h' line='1069' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='release' type-id='841969d0' visibility='default' filepath='include/net/tcp.h' line='1070' column='1'/>
+          <var-decl name='release' type-id='841969d0' visibility='default' filepath='include/net/tcp.h' line='1071' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='ssthresh' type-id='8af06487' visibility='default' filepath='include/net/tcp.h' line='1073' column='1'/>
+          <var-decl name='ssthresh' type-id='8af06487' visibility='default' filepath='include/net/tcp.h' line='1074' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='cong_avoid' type-id='ece3af1e' visibility='default' filepath='include/net/tcp.h' line='1075' column='1'/>
+          <var-decl name='cong_avoid' type-id='ece3af1e' visibility='default' filepath='include/net/tcp.h' line='1076' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='set_state' type-id='f5feb7a4' visibility='default' filepath='include/net/tcp.h' line='1077' column='1'/>
+          <var-decl name='set_state' type-id='f5feb7a4' visibility='default' filepath='include/net/tcp.h' line='1078' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='cwnd_event' type-id='bfacbc7a' visibility='default' filepath='include/net/tcp.h' line='1079' column='1'/>
+          <var-decl name='cwnd_event' type-id='bfacbc7a' visibility='default' filepath='include/net/tcp.h' line='1080' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='in_ack_event' type-id='815f64bf' visibility='default' filepath='include/net/tcp.h' line='1081' column='1'/>
+          <var-decl name='in_ack_event' type-id='815f64bf' visibility='default' filepath='include/net/tcp.h' line='1082' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='undo_cwnd' type-id='8af06487' visibility='default' filepath='include/net/tcp.h' line='1083' column='1'/>
+          <var-decl name='undo_cwnd' type-id='8af06487' visibility='default' filepath='include/net/tcp.h' line='1084' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='pkts_acked' type-id='bffb5883' visibility='default' filepath='include/net/tcp.h' line='1085' column='1'/>
+          <var-decl name='pkts_acked' type-id='bffb5883' visibility='default' filepath='include/net/tcp.h' line='1086' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='min_tso_segs' type-id='8af06487' visibility='default' filepath='include/net/tcp.h' line='1087' column='1'/>
+          <var-decl name='min_tso_segs' type-id='8af06487' visibility='default' filepath='include/net/tcp.h' line='1088' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='sndbuf_expand' type-id='8af06487' visibility='default' filepath='include/net/tcp.h' line='1089' column='1'/>
+          <var-decl name='sndbuf_expand' type-id='8af06487' visibility='default' filepath='include/net/tcp.h' line='1090' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='cong_control' type-id='636d3a20' visibility='default' filepath='include/net/tcp.h' line='1093' column='1'/>
+          <var-decl name='cong_control' type-id='636d3a20' visibility='default' filepath='include/net/tcp.h' line='1094' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='get_info' type-id='14ca5c08' visibility='default' filepath='include/net/tcp.h' line='1095' column='1'/>
+          <var-decl name='get_info' type-id='14ca5c08' visibility='default' filepath='include/net/tcp.h' line='1096' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='name' type-id='ac1fa8c0' visibility='default' filepath='include/net/tcp.h' line='1098' column='1'/>
+          <var-decl name='name' type-id='ac1fa8c0' visibility='default' filepath='include/net/tcp.h' line='1099' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='owner' type-id='2730d015' visibility='default' filepath='include/net/tcp.h' line='1099' column='1'/>
+          <var-decl name='owner' type-id='2730d015' visibility='default' filepath='include/net/tcp.h' line='1100' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='673937f2' size-in-bits='64' id='5474f420'/>
@@ -39922,8 +40060,8 @@
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='54faec06'>
-        <parameter type-id='723d4d79'/>
-        <parameter type-id='c21baddd'/>
+        <parameter type-id='723d4d79' name='bdev'/>
+        <parameter type-id='c21baddd' name='ttm'/>
         <return type-id='48b5725f'/>
       </function-type>
       <class-decl name='i3c_ccc_cmd_dest' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/i3c/ccc.h' line='361' column='1' id='55059246'>
@@ -39944,12 +40082,12 @@
         <enumerator name='VB2_BUF_STATE_DONE' value='5'/>
         <enumerator name='VB2_BUF_STATE_ERROR' value='6'/>
       </enum-decl>
-      <class-decl name='ipv6_opt_hdr' size-in-bits='16' is-struct='yes' visibility='default' filepath='include/uapi/linux/ipv6.h' line='62' column='1' id='5510bbdb'>
+      <class-decl name='ipv6_opt_hdr' size-in-bits='16' is-struct='yes' visibility='default' filepath='include/uapi/linux/ipv6.h' line='63' column='1' id='5510bbdb'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='nexthdr' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ipv6.h' line='63' column='1'/>
+          <var-decl name='nexthdr' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ipv6.h' line='64' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8'>
-          <var-decl name='hdrlen' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ipv6.h' line='64' column='1'/>
+          <var-decl name='hdrlen' type-id='8f048e17' visibility='default' filepath='include/uapi/linux/ipv6.h' line='65' column='1'/>
         </data-member>
       </class-decl>
       <enum-decl name='typec_cc_polarity' filepath='include/linux/usb/tcpm.h' line='26' column='1' id='551eebc9'>
@@ -40652,7 +40790,7 @@
         <enumerator name='REF_CLK_FREQ_52_MHZ' value='3'/>
         <enumerator name='REF_CLK_FREQ_INVAL' value='-1'/>
       </enum-decl>
-      <enum-decl name='dwc3_ep0_next' filepath='drivers/usb/dwc3/core.h' line='774' column='1' id='56e3bcb9'>
+      <enum-decl name='dwc3_ep0_next' filepath='drivers/usb/dwc3/core.h' line='775' column='1' id='56e3bcb9'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='DWC3_EP0_UNKNOWN' value='0'/>
         <enumerator name='DWC3_EP0_COMPLETE' value='1'/>
@@ -40892,18 +41030,18 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='fa35cea9' size-in-bits='64' id='57b94931'/>
-      <class-decl name='usb_pd_identity' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/usb/typec.h' line='102' column='1' id='57bfbe05'>
+      <class-decl name='usb_pd_identity' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/usb/typec.h' line='103' column='1' id='57bfbe05'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='id_header' type-id='19c2251e' visibility='default' filepath='include/linux/usb/typec.h' line='103' column='1'/>
+          <var-decl name='id_header' type-id='19c2251e' visibility='default' filepath='include/linux/usb/typec.h' line='104' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='cert_stat' type-id='19c2251e' visibility='default' filepath='include/linux/usb/typec.h' line='104' column='1'/>
+          <var-decl name='cert_stat' type-id='19c2251e' visibility='default' filepath='include/linux/usb/typec.h' line='105' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='product' type-id='19c2251e' visibility='default' filepath='include/linux/usb/typec.h' line='105' column='1'/>
+          <var-decl name='product' type-id='19c2251e' visibility='default' filepath='include/linux/usb/typec.h' line='106' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='vdo' type-id='1c745afe' visibility='default' filepath='include/linux/usb/typec.h' line='106' column='1'/>
+          <var-decl name='vdo' type-id='1c745afe' visibility='default' filepath='include/linux/usb/typec.h' line='107' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='92a295b4' size-in-bits='64' id='57c9915e'/>
@@ -41227,21 +41365,21 @@
         <return type-id='48b5725f'/>
       </function-type>
       <pointer-type-def type-id='25dc4075' size-in-bits='64' id='58ed56f5'/>
-      <class-decl name='irq_affinity_notify' size-in-bits='576' is-struct='yes' visibility='default' filepath='include/linux/interrupt.h' line='270' column='1' id='58f5058a'>
+      <class-decl name='irq_affinity_notify' size-in-bits='576' is-struct='yes' visibility='default' filepath='include/linux/interrupt.h' line='274' column='1' id='58f5058a'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='irq' type-id='f0981eeb' visibility='default' filepath='include/linux/interrupt.h' line='271' column='1'/>
+          <var-decl name='irq' type-id='f0981eeb' visibility='default' filepath='include/linux/interrupt.h' line='275' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='kref' type-id='400fb07b' visibility='default' filepath='include/linux/interrupt.h' line='272' column='1'/>
+          <var-decl name='kref' type-id='400fb07b' visibility='default' filepath='include/linux/interrupt.h' line='276' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='work' type-id='ef9025d0' visibility='default' filepath='include/linux/interrupt.h' line='273' column='1'/>
+          <var-decl name='work' type-id='ef9025d0' visibility='default' filepath='include/linux/interrupt.h' line='277' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='notify' type-id='c1d52f61' visibility='default' filepath='include/linux/interrupt.h' line='274' column='1'/>
+          <var-decl name='notify' type-id='c1d52f61' visibility='default' filepath='include/linux/interrupt.h' line='278' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='release' type-id='16575f26' visibility='default' filepath='include/linux/interrupt.h' line='275' column='1'/>
+          <var-decl name='release' type-id='16575f26' visibility='default' filepath='include/linux/interrupt.h' line='279' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='c3b2916f' size-in-bits='64' id='58f84083'/>
@@ -42180,435 +42318,435 @@
       </enum-decl>
       <pointer-type-def type-id='90220a52' size-in-bits='64' id='5a92c1cc'/>
       <pointer-type-def type-id='89e92d83' size-in-bits='64' id='5a92dd37'/>
-      <class-decl name='net_device' size-in-bits='19968' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='1912' column='1' id='5a9929eb'>
+      <class-decl name='net_device' size-in-bits='19968' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='1916' column='1' id='5a9929eb'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='name' type-id='ac1fa8c0' visibility='default' filepath='include/linux/netdevice.h' line='1913' column='1'/>
+          <var-decl name='name' type-id='ac1fa8c0' visibility='default' filepath='include/linux/netdevice.h' line='1917' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='name_node' type-id='e02e2a9e' visibility='default' filepath='include/linux/netdevice.h' line='1914' column='1'/>
+          <var-decl name='name_node' type-id='e02e2a9e' visibility='default' filepath='include/linux/netdevice.h' line='1918' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='ifalias' type-id='d81cf24c' visibility='default' filepath='include/linux/netdevice.h' line='1915' column='1'/>
+          <var-decl name='ifalias' type-id='d81cf24c' visibility='default' filepath='include/linux/netdevice.h' line='1919' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='mem_end' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='1920' column='1'/>
+          <var-decl name='mem_end' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='1924' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='mem_start' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='1921' column='1'/>
+          <var-decl name='mem_start' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='1925' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='base_addr' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='1922' column='1'/>
+          <var-decl name='base_addr' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='1926' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='irq' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='1923' column='1'/>
+          <var-decl name='irq' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='1927' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='state' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='1931' column='1'/>
+          <var-decl name='state' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='1935' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='dev_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1933' column='1'/>
+          <var-decl name='dev_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1937' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='napi_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1934' column='1'/>
+          <var-decl name='napi_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1938' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='unreg_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1935' column='1'/>
+          <var-decl name='unreg_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1939' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='close_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1936' column='1'/>
+          <var-decl name='close_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1940' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1088'>
-          <var-decl name='ptype_all' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1937' column='1'/>
+          <var-decl name='ptype_all' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1941' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='ptype_specific' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1938' column='1'/>
+          <var-decl name='ptype_specific' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='1942' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1344'>
-          <var-decl name='adj_list' type-id='19245258' visibility='default' filepath='include/linux/netdevice.h' line='1943' column='1'/>
+          <var-decl name='adj_list' type-id='19245258' visibility='default' filepath='include/linux/netdevice.h' line='1947' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1600'>
-          <var-decl name='features' type-id='f9f4b16f' visibility='default' filepath='include/linux/netdevice.h' line='1945' column='1'/>
+          <var-decl name='features' type-id='f9f4b16f' visibility='default' filepath='include/linux/netdevice.h' line='1949' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1664'>
-          <var-decl name='hw_features' type-id='f9f4b16f' visibility='default' filepath='include/linux/netdevice.h' line='1946' column='1'/>
+          <var-decl name='hw_features' type-id='f9f4b16f' visibility='default' filepath='include/linux/netdevice.h' line='1950' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1728'>
-          <var-decl name='wanted_features' type-id='f9f4b16f' visibility='default' filepath='include/linux/netdevice.h' line='1947' column='1'/>
+          <var-decl name='wanted_features' type-id='f9f4b16f' visibility='default' filepath='include/linux/netdevice.h' line='1951' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1792'>
-          <var-decl name='vlan_features' type-id='f9f4b16f' visibility='default' filepath='include/linux/netdevice.h' line='1948' column='1'/>
+          <var-decl name='vlan_features' type-id='f9f4b16f' visibility='default' filepath='include/linux/netdevice.h' line='1952' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1856'>
-          <var-decl name='hw_enc_features' type-id='f9f4b16f' visibility='default' filepath='include/linux/netdevice.h' line='1949' column='1'/>
+          <var-decl name='hw_enc_features' type-id='f9f4b16f' visibility='default' filepath='include/linux/netdevice.h' line='1953' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1920'>
-          <var-decl name='mpls_features' type-id='f9f4b16f' visibility='default' filepath='include/linux/netdevice.h' line='1950' column='1'/>
+          <var-decl name='mpls_features' type-id='f9f4b16f' visibility='default' filepath='include/linux/netdevice.h' line='1954' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1984'>
-          <var-decl name='gso_partial_features' type-id='f9f4b16f' visibility='default' filepath='include/linux/netdevice.h' line='1951' column='1'/>
+          <var-decl name='gso_partial_features' type-id='f9f4b16f' visibility='default' filepath='include/linux/netdevice.h' line='1955' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2048'>
-          <var-decl name='ifindex' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='1953' column='1'/>
+          <var-decl name='ifindex' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='1957' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2080'>
-          <var-decl name='group' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='1954' column='1'/>
+          <var-decl name='group' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='1958' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2112'>
-          <var-decl name='stats' type-id='a3566137' visibility='default' filepath='include/linux/netdevice.h' line='1956' column='1'/>
+          <var-decl name='stats' type-id='a3566137' visibility='default' filepath='include/linux/netdevice.h' line='1960' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3584'>
-          <var-decl name='rx_dropped' type-id='f22a8abb' visibility='default' filepath='include/linux/netdevice.h' line='1958' column='1'/>
+          <var-decl name='rx_dropped' type-id='f22a8abb' visibility='default' filepath='include/linux/netdevice.h' line='1962' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3648'>
-          <var-decl name='tx_dropped' type-id='f22a8abb' visibility='default' filepath='include/linux/netdevice.h' line='1959' column='1'/>
+          <var-decl name='tx_dropped' type-id='f22a8abb' visibility='default' filepath='include/linux/netdevice.h' line='1963' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3712'>
-          <var-decl name='rx_nohandler' type-id='f22a8abb' visibility='default' filepath='include/linux/netdevice.h' line='1960' column='1'/>
+          <var-decl name='rx_nohandler' type-id='f22a8abb' visibility='default' filepath='include/linux/netdevice.h' line='1964' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3776'>
-          <var-decl name='carrier_up_count' type-id='49178f86' visibility='default' filepath='include/linux/netdevice.h' line='1963' column='1'/>
+          <var-decl name='carrier_up_count' type-id='49178f86' visibility='default' filepath='include/linux/netdevice.h' line='1967' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3808'>
-          <var-decl name='carrier_down_count' type-id='49178f86' visibility='default' filepath='include/linux/netdevice.h' line='1964' column='1'/>
+          <var-decl name='carrier_down_count' type-id='49178f86' visibility='default' filepath='include/linux/netdevice.h' line='1968' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3840'>
-          <var-decl name='wireless_handlers' type-id='3e2bb973' visibility='default' filepath='include/linux/netdevice.h' line='1967' column='1'/>
+          <var-decl name='wireless_handlers' type-id='3e2bb973' visibility='default' filepath='include/linux/netdevice.h' line='1971' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3904'>
-          <var-decl name='wireless_data' type-id='e40f7bda' visibility='default' filepath='include/linux/netdevice.h' line='1968' column='1'/>
+          <var-decl name='wireless_data' type-id='e40f7bda' visibility='default' filepath='include/linux/netdevice.h' line='1972' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3968'>
-          <var-decl name='netdev_ops' type-id='a84ec761' visibility='default' filepath='include/linux/netdevice.h' line='1970' column='1'/>
+          <var-decl name='netdev_ops' type-id='a84ec761' visibility='default' filepath='include/linux/netdevice.h' line='1974' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4032'>
-          <var-decl name='ethtool_ops' type-id='bdf901f8' visibility='default' filepath='include/linux/netdevice.h' line='1971' column='1'/>
+          <var-decl name='ethtool_ops' type-id='bdf901f8' visibility='default' filepath='include/linux/netdevice.h' line='1975' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4096'>
-          <var-decl name='ndisc_ops' type-id='a2e418a6' visibility='default' filepath='include/linux/netdevice.h' line='1976' column='1'/>
+          <var-decl name='ndisc_ops' type-id='a2e418a6' visibility='default' filepath='include/linux/netdevice.h' line='1980' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4160'>
-          <var-decl name='header_ops' type-id='2d747e78' visibility='default' filepath='include/linux/netdevice.h' line='1987' column='1'/>
+          <var-decl name='header_ops' type-id='2d747e78' visibility='default' filepath='include/linux/netdevice.h' line='1991' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4224'>
-          <var-decl name='flags' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='1989' column='1'/>
+          <var-decl name='flags' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='1993' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4256'>
-          <var-decl name='priv_flags' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='1990' column='1'/>
+          <var-decl name='priv_flags' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='1994' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4288'>
-          <var-decl name='gflags' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='1992' column='1'/>
+          <var-decl name='gflags' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='1996' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4304'>
-          <var-decl name='padded' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='1993' column='1'/>
+          <var-decl name='padded' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='1997' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4320'>
-          <var-decl name='operstate' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='1995' column='1'/>
+          <var-decl name='operstate' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='1999' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4328'>
-          <var-decl name='link_mode' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='1996' column='1'/>
+          <var-decl name='link_mode' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='2000' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4336'>
-          <var-decl name='if_port' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='1998' column='1'/>
+          <var-decl name='if_port' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='2002' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4344'>
-          <var-decl name='dma' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='1999' column='1'/>
+          <var-decl name='dma' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='2003' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4352'>
-          <var-decl name='mtu' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2006' column='1'/>
+          <var-decl name='mtu' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2010' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4384'>
-          <var-decl name='min_mtu' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2007' column='1'/>
+          <var-decl name='min_mtu' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2011' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4416'>
-          <var-decl name='max_mtu' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2008' column='1'/>
+          <var-decl name='max_mtu' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2012' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4448'>
-          <var-decl name='type' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='2009' column='1'/>
+          <var-decl name='type' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='2013' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4464'>
-          <var-decl name='hard_header_len' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='2010' column='1'/>
+          <var-decl name='hard_header_len' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='2014' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4480'>
-          <var-decl name='min_header_len' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='2011' column='1'/>
+          <var-decl name='min_header_len' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='2015' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4488'>
-          <var-decl name='name_assign_type' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='2012' column='1'/>
+          <var-decl name='name_assign_type' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='2016' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4496'>
-          <var-decl name='needed_headroom' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='2014' column='1'/>
+          <var-decl name='needed_headroom' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='2018' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4512'>
-          <var-decl name='needed_tailroom' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='2015' column='1'/>
+          <var-decl name='needed_tailroom' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='2019' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4528'>
-          <var-decl name='perm_addr' type-id='fc872715' visibility='default' filepath='include/linux/netdevice.h' line='2018' column='1'/>
+          <var-decl name='perm_addr' type-id='fc872715' visibility='default' filepath='include/linux/netdevice.h' line='2022' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4784'>
-          <var-decl name='addr_assign_type' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='2019' column='1'/>
+          <var-decl name='addr_assign_type' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='2023' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4792'>
-          <var-decl name='addr_len' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='2020' column='1'/>
+          <var-decl name='addr_len' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='2024' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4800'>
-          <var-decl name='upper_level' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='2021' column='1'/>
+          <var-decl name='upper_level' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='2025' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4808'>
-          <var-decl name='lower_level' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='2022' column='1'/>
+          <var-decl name='lower_level' type-id='002ac4a6' visibility='default' filepath='include/linux/netdevice.h' line='2026' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4816'>
-          <var-decl name='neigh_priv_len' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='2024' column='1'/>
+          <var-decl name='neigh_priv_len' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='2028' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4832'>
-          <var-decl name='dev_id' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='2025' column='1'/>
+          <var-decl name='dev_id' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='2029' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4848'>
-          <var-decl name='dev_port' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='2026' column='1'/>
+          <var-decl name='dev_port' type-id='8efea9e5' visibility='default' filepath='include/linux/netdevice.h' line='2030' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4864'>
-          <var-decl name='addr_list_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/netdevice.h' line='2027' column='1'/>
+          <var-decl name='addr_list_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/netdevice.h' line='2031' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4928'>
-          <var-decl name='uc' type-id='44a1ec32' visibility='default' filepath='include/linux/netdevice.h' line='2029' column='1'/>
+          <var-decl name='uc' type-id='44a1ec32' visibility='default' filepath='include/linux/netdevice.h' line='2033' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5120'>
-          <var-decl name='mc' type-id='44a1ec32' visibility='default' filepath='include/linux/netdevice.h' line='2030' column='1'/>
+          <var-decl name='mc' type-id='44a1ec32' visibility='default' filepath='include/linux/netdevice.h' line='2034' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5312'>
-          <var-decl name='dev_addrs' type-id='44a1ec32' visibility='default' filepath='include/linux/netdevice.h' line='2031' column='1'/>
+          <var-decl name='dev_addrs' type-id='44a1ec32' visibility='default' filepath='include/linux/netdevice.h' line='2035' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5504'>
-          <var-decl name='queues_kset' type-id='89b70200' visibility='default' filepath='include/linux/netdevice.h' line='2034' column='1'/>
+          <var-decl name='queues_kset' type-id='89b70200' visibility='default' filepath='include/linux/netdevice.h' line='2038' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5568'>
-          <var-decl name='promiscuity' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2039' column='1'/>
+          <var-decl name='promiscuity' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2043' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5600'>
-          <var-decl name='allmulti' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2040' column='1'/>
+          <var-decl name='allmulti' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2044' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5632'>
-          <var-decl name='uc_promisc' type-id='b50a4934' visibility='default' filepath='include/linux/netdevice.h' line='2041' column='1'/>
+          <var-decl name='uc_promisc' type-id='b50a4934' visibility='default' filepath='include/linux/netdevice.h' line='2045' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5696'>
-          <var-decl name='tipc_ptr' type-id='eeaf504d' visibility='default' filepath='include/linux/netdevice.h' line='2056' column='1'/>
+          <var-decl name='tipc_ptr' type-id='eeaf504d' visibility='default' filepath='include/linux/netdevice.h' line='2060' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5760'>
-          <var-decl name='ip_ptr' type-id='fc6f14a9' visibility='default' filepath='include/linux/netdevice.h' line='2061' column='1'/>
+          <var-decl name='ip_ptr' type-id='fc6f14a9' visibility='default' filepath='include/linux/netdevice.h' line='2065' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5824'>
-          <var-decl name='ip6_ptr' type-id='f026b16b' visibility='default' filepath='include/linux/netdevice.h' line='2065' column='1'/>
+          <var-decl name='ip6_ptr' type-id='f026b16b' visibility='default' filepath='include/linux/netdevice.h' line='2066' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5888'>
-          <var-decl name='ieee80211_ptr' type-id='63c7e8e1' visibility='default' filepath='include/linux/netdevice.h' line='2069' column='1'/>
+          <var-decl name='ieee80211_ptr' type-id='63c7e8e1' visibility='default' filepath='include/linux/netdevice.h' line='2070' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5952'>
-          <var-decl name='ieee802154_ptr' type-id='165146ad' visibility='default' filepath='include/linux/netdevice.h' line='2070' column='1'/>
+          <var-decl name='ieee802154_ptr' type-id='165146ad' visibility='default' filepath='include/linux/netdevice.h' line='2071' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6016'>
-          <var-decl name='dev_addr' type-id='cf536864' visibility='default' filepath='include/linux/netdevice.h' line='2079' column='1'/>
+          <var-decl name='dev_addr' type-id='cf536864' visibility='default' filepath='include/linux/netdevice.h' line='2080' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6080'>
-          <var-decl name='_rx' type-id='31094274' visibility='default' filepath='include/linux/netdevice.h' line='2081' column='1'/>
+          <var-decl name='_rx' type-id='31094274' visibility='default' filepath='include/linux/netdevice.h' line='2082' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6144'>
-          <var-decl name='num_rx_queues' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2082' column='1'/>
+          <var-decl name='num_rx_queues' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2083' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6176'>
-          <var-decl name='real_num_rx_queues' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2083' column='1'/>
+          <var-decl name='real_num_rx_queues' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2084' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6208'>
-          <var-decl name='xdp_prog' type-id='bdcee7ae' visibility='default' filepath='include/linux/netdevice.h' line='2085' column='1'/>
+          <var-decl name='xdp_prog' type-id='bdcee7ae' visibility='default' filepath='include/linux/netdevice.h' line='2086' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6272'>
-          <var-decl name='gro_flush_timeout' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='2086' column='1'/>
+          <var-decl name='gro_flush_timeout' type-id='7359adad' visibility='default' filepath='include/linux/netdevice.h' line='2087' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6336'>
-          <var-decl name='napi_defer_hard_irqs' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='2087' column='1'/>
+          <var-decl name='napi_defer_hard_irqs' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='2088' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6400'>
-          <var-decl name='rx_handler' type-id='da1cb816' visibility='default' filepath='include/linux/netdevice.h' line='2088' column='1'/>
+          <var-decl name='rx_handler' type-id='da1cb816' visibility='default' filepath='include/linux/netdevice.h' line='2089' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6464'>
-          <var-decl name='rx_handler_data' type-id='eaa32e2f' visibility='default' filepath='include/linux/netdevice.h' line='2089' column='1'/>
+          <var-decl name='rx_handler_data' type-id='eaa32e2f' visibility='default' filepath='include/linux/netdevice.h' line='2090' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6528'>
-          <var-decl name='miniq_ingress' type-id='b70f37f7' visibility='default' filepath='include/linux/netdevice.h' line='2092' column='1'/>
+          <var-decl name='miniq_ingress' type-id='b70f37f7' visibility='default' filepath='include/linux/netdevice.h' line='2093' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6592'>
-          <var-decl name='ingress_queue' type-id='35b28c4f' visibility='default' filepath='include/linux/netdevice.h' line='2094' column='1'/>
+          <var-decl name='ingress_queue' type-id='35b28c4f' visibility='default' filepath='include/linux/netdevice.h' line='2095' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6656'>
-          <var-decl name='nf_hooks_ingress' type-id='39a43b40' visibility='default' filepath='include/linux/netdevice.h' line='2096' column='1'/>
+          <var-decl name='nf_hooks_ingress' type-id='39a43b40' visibility='default' filepath='include/linux/netdevice.h' line='2097' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6720'>
-          <var-decl name='broadcast' type-id='fc872715' visibility='default' filepath='include/linux/netdevice.h' line='2099' column='1'/>
+          <var-decl name='broadcast' type-id='fc872715' visibility='default' filepath='include/linux/netdevice.h' line='2100' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6976'>
-          <var-decl name='rx_cpu_rmap' type-id='52baee64' visibility='default' filepath='include/linux/netdevice.h' line='2101' column='1'/>
+          <var-decl name='rx_cpu_rmap' type-id='52baee64' visibility='default' filepath='include/linux/netdevice.h' line='2102' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7040'>
-          <var-decl name='index_hlist' type-id='03a4a074' visibility='default' filepath='include/linux/netdevice.h' line='2103' column='1'/>
+          <var-decl name='index_hlist' type-id='03a4a074' visibility='default' filepath='include/linux/netdevice.h' line='2104' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7168'>
-          <var-decl name='_tx' type-id='35b28c4f' visibility='default' filepath='include/linux/netdevice.h' line='2108' column='1'/>
+          <var-decl name='_tx' type-id='35b28c4f' visibility='default' filepath='include/linux/netdevice.h' line='2109' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7232'>
-          <var-decl name='num_tx_queues' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2109' column='1'/>
+          <var-decl name='num_tx_queues' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2110' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7264'>
-          <var-decl name='real_num_tx_queues' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2110' column='1'/>
+          <var-decl name='real_num_tx_queues' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2111' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7296'>
-          <var-decl name='qdisc' type-id='ee406209' visibility='default' filepath='include/linux/netdevice.h' line='2111' column='1'/>
+          <var-decl name='qdisc' type-id='ee406209' visibility='default' filepath='include/linux/netdevice.h' line='2112' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7360'>
-          <var-decl name='tx_queue_len' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2112' column='1'/>
+          <var-decl name='tx_queue_len' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2113' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7392'>
-          <var-decl name='tx_global_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/netdevice.h' line='2113' column='1'/>
+          <var-decl name='tx_global_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/netdevice.h' line='2114' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7424'>
-          <var-decl name='xdp_bulkq' type-id='dc52084e' visibility='default' filepath='include/linux/netdevice.h' line='2115' column='1'/>
+          <var-decl name='xdp_bulkq' type-id='dc52084e' visibility='default' filepath='include/linux/netdevice.h' line='2116' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7488'>
-          <var-decl name='xps_cpus_map' type-id='bf237056' visibility='default' filepath='include/linux/netdevice.h' line='2118' column='1'/>
+          <var-decl name='xps_cpus_map' type-id='bf237056' visibility='default' filepath='include/linux/netdevice.h' line='2119' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7552'>
-          <var-decl name='xps_rxqs_map' type-id='bf237056' visibility='default' filepath='include/linux/netdevice.h' line='2119' column='1'/>
+          <var-decl name='xps_rxqs_map' type-id='bf237056' visibility='default' filepath='include/linux/netdevice.h' line='2120' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7616'>
-          <var-decl name='miniq_egress' type-id='b70f37f7' visibility='default' filepath='include/linux/netdevice.h' line='2122' column='1'/>
+          <var-decl name='miniq_egress' type-id='b70f37f7' visibility='default' filepath='include/linux/netdevice.h' line='2123' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7680'>
-          <var-decl name='qdisc_hash' type-id='ccfd385f' visibility='default' filepath='include/linux/netdevice.h' line='2126' column='1'/>
+          <var-decl name='qdisc_hash' type-id='ccfd385f' visibility='default' filepath='include/linux/netdevice.h' line='2127' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8704'>
-          <var-decl name='watchdog_timer' type-id='abe41e67' visibility='default' filepath='include/linux/netdevice.h' line='2129' column='1'/>
+          <var-decl name='watchdog_timer' type-id='abe41e67' visibility='default' filepath='include/linux/netdevice.h' line='2130' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9152'>
-          <var-decl name='watchdog_timeo' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='2130' column='1'/>
+          <var-decl name='watchdog_timeo' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='2131' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9184'>
-          <var-decl name='proto_down_reason' type-id='19c2251e' visibility='default' filepath='include/linux/netdevice.h' line='2132' column='1'/>
+          <var-decl name='proto_down_reason' type-id='19c2251e' visibility='default' filepath='include/linux/netdevice.h' line='2133' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9216'>
-          <var-decl name='todo_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='2134' column='1'/>
+          <var-decl name='todo_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='2135' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9344'>
-          <var-decl name='pcpu_refcnt' type-id='7292109c' visibility='default' filepath='include/linux/netdevice.h' line='2135' column='1'/>
+          <var-decl name='pcpu_refcnt' type-id='7292109c' visibility='default' filepath='include/linux/netdevice.h' line='2136' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9408'>
-          <var-decl name='link_watch_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='2137' column='1'/>
+          <var-decl name='link_watch_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='2138' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='reg_state' type-id='08f5ca17' visibility='default' filepath='include/linux/netdevice.h' line='2145' column='1'/>
+          <var-decl name='reg_state' type-id='08f5ca17' visibility='default' filepath='include/linux/netdevice.h' line='2146' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9544'>
-          <var-decl name='dismantle' type-id='b50a4934' visibility='default' filepath='include/linux/netdevice.h' line='2147' column='1'/>
+          <var-decl name='dismantle' type-id='b50a4934' visibility='default' filepath='include/linux/netdevice.h' line='2148' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='16'>
-          <var-decl name='rtnl_link_state' type-id='08f5ca18' visibility='default' filepath='include/linux/netdevice.h' line='2152' column='1'/>
+          <var-decl name='rtnl_link_state' type-id='08f5ca18' visibility='default' filepath='include/linux/netdevice.h' line='2153' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9568'>
-          <var-decl name='needs_free_netdev' type-id='b50a4934' visibility='default' filepath='include/linux/netdevice.h' line='2154' column='1'/>
+          <var-decl name='needs_free_netdev' type-id='b50a4934' visibility='default' filepath='include/linux/netdevice.h' line='2155' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9600'>
-          <var-decl name='priv_destructor' type-id='548eee3a' visibility='default' filepath='include/linux/netdevice.h' line='2155' column='1'/>
+          <var-decl name='priv_destructor' type-id='548eee3a' visibility='default' filepath='include/linux/netdevice.h' line='2156' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9664'>
-          <var-decl name='nd_net' type-id='c9df1e6c' visibility='default' filepath='include/linux/netdevice.h' line='2161' column='1'/>
+          <var-decl name='nd_net' type-id='c9df1e6c' visibility='default' filepath='include/linux/netdevice.h' line='2162' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9728'>
-          <var-decl name='ml_priv' type-id='eaa32e2f' visibility='default' filepath='include/linux/netdevice.h' line='2164' column='1'/>
+          <var-decl name='ml_priv' type-id='eaa32e2f' visibility='default' filepath='include/linux/netdevice.h' line='2165' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9792'>
-          <var-decl name='ml_priv_type' type-id='9c6bf017' visibility='default' filepath='include/linux/netdevice.h' line='2165' column='1'/>
+          <var-decl name='ml_priv_type' type-id='9c6bf017' visibility='default' filepath='include/linux/netdevice.h' line='2166' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9856'>
-          <var-decl name='' type-id='ca29cb68' visibility='default' filepath='include/linux/netdevice.h' line='2167' column='1'/>
+          <var-decl name='' type-id='ca29cb68' visibility='default' filepath='include/linux/netdevice.h' line='2168' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9920'>
-          <var-decl name='dev' type-id='66e487eb' visibility='default' filepath='include/linux/netdevice.h' line='2180' column='1'/>
+          <var-decl name='dev' type-id='66e487eb' visibility='default' filepath='include/linux/netdevice.h' line='2181' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='17088'>
-          <var-decl name='sysfs_groups' type-id='db1b7234' visibility='default' filepath='include/linux/netdevice.h' line='2181' column='1'/>
+          <var-decl name='sysfs_groups' type-id='db1b7234' visibility='default' filepath='include/linux/netdevice.h' line='2182' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='17344'>
-          <var-decl name='sysfs_rx_queue_group' type-id='8ff9530e' visibility='default' filepath='include/linux/netdevice.h' line='2182' column='1'/>
+          <var-decl name='sysfs_rx_queue_group' type-id='8ff9530e' visibility='default' filepath='include/linux/netdevice.h' line='2183' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='17408'>
-          <var-decl name='rtnl_link_ops' type-id='999c8d90' visibility='default' filepath='include/linux/netdevice.h' line='2184' column='1'/>
+          <var-decl name='rtnl_link_ops' type-id='999c8d90' visibility='default' filepath='include/linux/netdevice.h' line='2185' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='17472'>
-          <var-decl name='gso_max_size' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2188' column='1'/>
+          <var-decl name='gso_max_size' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2189' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='17504'>
-          <var-decl name='gso_max_segs' type-id='1dc6a898' visibility='default' filepath='include/linux/netdevice.h' line='2190' column='1'/>
+          <var-decl name='gso_max_segs' type-id='1dc6a898' visibility='default' filepath='include/linux/netdevice.h' line='2191' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='17520'>
-          <var-decl name='num_tc' type-id='9b7e9486' visibility='default' filepath='include/linux/netdevice.h' line='2195' column='1'/>
+          <var-decl name='num_tc' type-id='9b7e9486' visibility='default' filepath='include/linux/netdevice.h' line='2196' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='17536'>
-          <var-decl name='tc_to_txq' type-id='b5839634' visibility='default' filepath='include/linux/netdevice.h' line='2196' column='1'/>
+          <var-decl name='tc_to_txq' type-id='b5839634' visibility='default' filepath='include/linux/netdevice.h' line='2197' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='18048'>
-          <var-decl name='prio_tc_map' type-id='0d8415b5' visibility='default' filepath='include/linux/netdevice.h' line='2197' column='1'/>
+          <var-decl name='prio_tc_map' type-id='0d8415b5' visibility='default' filepath='include/linux/netdevice.h' line='2198' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='18176'>
-          <var-decl name='priomap' type-id='ac9d827b' visibility='default' filepath='include/linux/netdevice.h' line='2203' column='1'/>
+          <var-decl name='priomap' type-id='ac9d827b' visibility='default' filepath='include/linux/netdevice.h' line='2204' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='18240'>
-          <var-decl name='phydev' type-id='7efbcaaf' visibility='default' filepath='include/linux/netdevice.h' line='2205' column='1'/>
+          <var-decl name='phydev' type-id='7efbcaaf' visibility='default' filepath='include/linux/netdevice.h' line='2206' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='18304'>
-          <var-decl name='sfp_bus' type-id='6daf6abd' visibility='default' filepath='include/linux/netdevice.h' line='2206' column='1'/>
+          <var-decl name='sfp_bus' type-id='6daf6abd' visibility='default' filepath='include/linux/netdevice.h' line='2207' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='18368'>
-          <var-decl name='qdisc_tx_busylock' type-id='a57283f9' visibility='default' filepath='include/linux/netdevice.h' line='2207' column='1'/>
+          <var-decl name='qdisc_tx_busylock' type-id='a57283f9' visibility='default' filepath='include/linux/netdevice.h' line='2208' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='18432'>
-          <var-decl name='qdisc_running_key' type-id='a57283f9' visibility='default' filepath='include/linux/netdevice.h' line='2208' column='1'/>
+          <var-decl name='qdisc_running_key' type-id='a57283f9' visibility='default' filepath='include/linux/netdevice.h' line='2209' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='18496'>
-          <var-decl name='proto_down' type-id='b50a4934' visibility='default' filepath='include/linux/netdevice.h' line='2209' column='1'/>
+          <var-decl name='proto_down' type-id='b50a4934' visibility='default' filepath='include/linux/netdevice.h' line='2210' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8'>
-          <var-decl name='wol_enabled' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2210' column='1'/>
+          <var-decl name='wol_enabled' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='2211' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='18560'>
-          <var-decl name='net_notifier_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='2212' column='1'/>
+          <var-decl name='net_notifier_list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='2213' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='18688'>
-          <var-decl name='udp_tunnel_nic_info' type-id='6c660a22' visibility='default' filepath='include/linux/netdevice.h' line='2218' column='1'/>
+          <var-decl name='udp_tunnel_nic_info' type-id='6c660a22' visibility='default' filepath='include/linux/netdevice.h' line='2219' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='18752'>
-          <var-decl name='udp_tunnel_nic' type-id='08662768' visibility='default' filepath='include/linux/netdevice.h' line='2219' column='1'/>
+          <var-decl name='udp_tunnel_nic' type-id='08662768' visibility='default' filepath='include/linux/netdevice.h' line='2220' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='18816'>
-          <var-decl name='xdp_state' type-id='74482e87' visibility='default' filepath='include/linux/netdevice.h' line='2222' column='1'/>
+          <var-decl name='xdp_state' type-id='74482e87' visibility='default' filepath='include/linux/netdevice.h' line='2223' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='19200'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2224' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2225' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='19264'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2225' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2226' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='19328'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2226' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2227' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='19392'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2227' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2228' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='19456'>
-          <var-decl name='android_kabi_reserved5' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2228' column='1'/>
+          <var-decl name='android_kabi_reserved5' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2229' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='19520'>
-          <var-decl name='android_kabi_reserved6' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2229' column='1'/>
+          <var-decl name='android_kabi_reserved6' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2230' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='19584'>
-          <var-decl name='android_kabi_reserved7' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2230' column='1'/>
+          <var-decl name='android_kabi_reserved7' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2231' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='19648'>
-          <var-decl name='android_kabi_reserved8' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2231' column='1'/>
+          <var-decl name='android_kabi_reserved8' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='2232' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='5a9e3f68'>
@@ -42691,24 +42829,24 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='615707ca' size-in-bits='64' id='5ad57c34'/>
-      <class-decl name='delayed_work' size-in-bits='1088' is-struct='yes' visibility='default' filepath='include/linux/workqueue.h' line='118' column='1' id='5ad6e0ef'>
+      <class-decl name='delayed_work' size-in-bits='1088' is-struct='yes' visibility='default' filepath='include/linux/workqueue.h' line='119' column='1' id='5ad6e0ef'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='work' type-id='ef9025d0' visibility='default' filepath='include/linux/workqueue.h' line='119' column='1'/>
+          <var-decl name='work' type-id='ef9025d0' visibility='default' filepath='include/linux/workqueue.h' line='120' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='timer' type-id='abe41e67' visibility='default' filepath='include/linux/workqueue.h' line='120' column='1'/>
+          <var-decl name='timer' type-id='abe41e67' visibility='default' filepath='include/linux/workqueue.h' line='121' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='wq' type-id='242e3d19' visibility='default' filepath='include/linux/workqueue.h' line='123' column='1'/>
+          <var-decl name='wq' type-id='242e3d19' visibility='default' filepath='include/linux/workqueue.h' line='124' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='cpu' type-id='95e97e5e' visibility='default' filepath='include/linux/workqueue.h' line='124' column='1'/>
+          <var-decl name='cpu' type-id='95e97e5e' visibility='default' filepath='include/linux/workqueue.h' line='125' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/workqueue.h' line='126' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/workqueue.h' line='127' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/workqueue.h' line='127' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/workqueue.h' line='128' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='cd5d79f4' size-in-bits='64' id='5ad9edb6'/>
@@ -42928,6 +43066,13 @@
       </function-type>
       <pointer-type-def type-id='8d8b68e8' size-in-bits='64' id='5bc4fd6a'/>
       <pointer-type-def type-id='14a30316' size-in-bits='64' id='5bc7662c'/>
+      <enum-decl name='oom_constraint' filepath='include/linux/oom.h' line='18' column='1' id='5bc89d69'>
+        <underlying-type type-id='9cac1fee'/>
+        <enumerator name='CONSTRAINT_NONE' value='0'/>
+        <enumerator name='CONSTRAINT_CPUSET' value='1'/>
+        <enumerator name='CONSTRAINT_MEMORY_POLICY' value='2'/>
+        <enumerator name='CONSTRAINT_MEMCG' value='3'/>
+      </enum-decl>
       <class-decl name='hlist_nulls_node' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/list_nulls.h' line='25' column='1' id='5bd248e7'>
         <data-member access='public' layout-offset-in-bits='0'>
           <var-decl name='next' type-id='6cf6468f' visibility='default' filepath='include/linux/list_nulls.h' line='26' column='1'/>
@@ -43082,7 +43227,7 @@
         </data-member>
       </class-decl>
       <typedef-decl name='async_func_t' type-id='56ccc407' filepath='include/linux/async.h' line='17' column='1' id='5c19cb0c'/>
-      <typedef-decl name='sk_buff_data_t' type-id='f0981eeb' filepath='include/linux/skbuff.h' line='610' column='1' id='5c1abc34'/>
+      <typedef-decl name='sk_buff_data_t' type-id='f0981eeb' filepath='include/linux/skbuff.h' line='611' column='1' id='5c1abc34'/>
       <pointer-type-def type-id='979d5bbb' size-in-bits='64' id='5c218f2b'/>
       <class-decl name='ieee80211_regdomain' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/net/regulatory.h' line='226' column='1' id='5c28f25e'>
         <data-member access='public' layout-offset-in-bits='0'>
@@ -43833,7 +43978,7 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='4a19d21e' size-in-bits='64' id='5da77304'/>
-      <enum-decl name='lockdep_ok' filepath='include/linux/kernel.h' line='561' column='1' id='5da9c47b'>
+      <enum-decl name='lockdep_ok' filepath='include/linux/kernel.h' line='417' column='1' id='5da9c47b'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='LOCKDEP_STILL_OK' value='0'/>
         <enumerator name='LOCKDEP_NOW_UNRELIABLE' value='1'/>
@@ -44536,23 +44681,7 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='538b7809' size-in-bits='64' id='5f0d472d'/>
-      <class-decl name='fsverity_operations' size-in-bits='320' is-struct='yes' visibility='default' filepath='include/linux/fsverity.h' line='18' column='1' id='5f0d764c'>
-        <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='begin_enable_verity' type-id='4da4101d' visibility='default' filepath='include/linux/fsverity.h' line='33' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='end_enable_verity' type-id='f3a5c46a' visibility='default' filepath='include/linux/fsverity.h' line='55' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='get_verity_descriptor' type-id='c60354f3' visibility='default' filepath='include/linux/fsverity.h' line='72' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='read_merkle_tree_page' type-id='68b31938' visibility='default' filepath='include/linux/fsverity.h' line='93' column='1'/>
-        </data-member>
-        <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='write_merkle_tree_block' type-id='c748f227' visibility='default' filepath='include/linux/fsverity.h' line='110' column='1'/>
-        </data-member>
-      </class-decl>
+      <class-decl name='fsverity_operations' is-struct='yes' visibility='default' is-declaration-only='yes' id='5f0d764c'/>
       <pointer-type-def type-id='0caa7082' size-in-bits='64' id='5f29549c'/>
       <class-decl name='configfs_attribute' size-in-bits='320' is-struct='yes' visibility='default' filepath='include/linux/configfs.h' line='117' column='1' id='5f2e9b8f'>
         <data-member access='public' layout-offset-in-bits='0'>
@@ -44614,7 +44743,7 @@
         <return type-id='95e97e5e'/>
       </function-type>
       <pointer-type-def type-id='4fb62cb0' size-in-bits='64' id='5f493a9f'/>
-      <enum-decl name='tcp_ca_event' filepath='include/net/tcp.h' line='999' column='1' id='5f51e977'>
+      <enum-decl name='tcp_ca_event' filepath='include/net/tcp.h' line='1000' column='1' id='5f51e977'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='CA_EVENT_TX_START' value='0'/>
         <enumerator name='CA_EVENT_CWND_RESTART' value='1'/>
@@ -44624,81 +44753,81 @@
         <enumerator name='CA_EVENT_ECN_IS_CE' value='5'/>
       </enum-decl>
       <pointer-type-def type-id='ebcc73dc' size-in-bits='64' id='5f5506f6'/>
-      <class-decl name='inode_operations' size-in-bits='2048' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='1925' column='1' id='5f5aa1ff'>
+      <class-decl name='inode_operations' size-in-bits='2048' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='1932' column='1' id='5f5aa1ff'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='lookup' type-id='02f90a61' visibility='default' filepath='include/linux/fs.h' line='1926' column='1'/>
+          <var-decl name='lookup' type-id='02f90a61' visibility='default' filepath='include/linux/fs.h' line='1933' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='get_link' type-id='76ae8e1d' visibility='default' filepath='include/linux/fs.h' line='1927' column='1'/>
+          <var-decl name='get_link' type-id='76ae8e1d' visibility='default' filepath='include/linux/fs.h' line='1934' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='permission' type-id='f4f91b99' visibility='default' filepath='include/linux/fs.h' line='1928' column='1'/>
+          <var-decl name='permission' type-id='f4f91b99' visibility='default' filepath='include/linux/fs.h' line='1935' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='get_acl' type-id='7f30b822' visibility='default' filepath='include/linux/fs.h' line='1929' column='1'/>
+          <var-decl name='get_acl' type-id='7f30b822' visibility='default' filepath='include/linux/fs.h' line='1936' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='readlink' type-id='a57bd028' visibility='default' filepath='include/linux/fs.h' line='1931' column='1'/>
+          <var-decl name='readlink' type-id='a57bd028' visibility='default' filepath='include/linux/fs.h' line='1938' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='create' type-id='c9cd0e09' visibility='default' filepath='include/linux/fs.h' line='1933' column='1'/>
+          <var-decl name='create' type-id='c9cd0e09' visibility='default' filepath='include/linux/fs.h' line='1940' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='link' type-id='4b872e00' visibility='default' filepath='include/linux/fs.h' line='1934' column='1'/>
+          <var-decl name='link' type-id='4b872e00' visibility='default' filepath='include/linux/fs.h' line='1941' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='unlink' type-id='7f5be7f6' visibility='default' filepath='include/linux/fs.h' line='1935' column='1'/>
+          <var-decl name='unlink' type-id='7f5be7f6' visibility='default' filepath='include/linux/fs.h' line='1942' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='symlink' type-id='234843b5' visibility='default' filepath='include/linux/fs.h' line='1936' column='1'/>
+          <var-decl name='symlink' type-id='234843b5' visibility='default' filepath='include/linux/fs.h' line='1943' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='mkdir' type-id='98c2d938' visibility='default' filepath='include/linux/fs.h' line='1937' column='1'/>
+          <var-decl name='mkdir' type-id='98c2d938' visibility='default' filepath='include/linux/fs.h' line='1944' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='rmdir' type-id='7f5be7f6' visibility='default' filepath='include/linux/fs.h' line='1938' column='1'/>
+          <var-decl name='rmdir' type-id='7f5be7f6' visibility='default' filepath='include/linux/fs.h' line='1945' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='mknod' type-id='f9e0c0e5' visibility='default' filepath='include/linux/fs.h' line='1939' column='1'/>
+          <var-decl name='mknod' type-id='f9e0c0e5' visibility='default' filepath='include/linux/fs.h' line='1946' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='rename' type-id='7733ef81' visibility='default' filepath='include/linux/fs.h' line='1940' column='1'/>
+          <var-decl name='rename' type-id='7733ef81' visibility='default' filepath='include/linux/fs.h' line='1947' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='setattr' type-id='c237e829' visibility='default' filepath='include/linux/fs.h' line='1942' column='1'/>
+          <var-decl name='setattr' type-id='c237e829' visibility='default' filepath='include/linux/fs.h' line='1949' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='getattr' type-id='0b787edf' visibility='default' filepath='include/linux/fs.h' line='1943' column='1'/>
+          <var-decl name='getattr' type-id='0b787edf' visibility='default' filepath='include/linux/fs.h' line='1950' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='listxattr' type-id='3494e4bb' visibility='default' filepath='include/linux/fs.h' line='1944' column='1'/>
+          <var-decl name='listxattr' type-id='3494e4bb' visibility='default' filepath='include/linux/fs.h' line='1951' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='fiemap' type-id='0508acce' visibility='default' filepath='include/linux/fs.h' line='1945' column='1'/>
+          <var-decl name='fiemap' type-id='0508acce' visibility='default' filepath='include/linux/fs.h' line='1952' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1088'>
-          <var-decl name='update_time' type-id='64ecf6a5' visibility='default' filepath='include/linux/fs.h' line='1947' column='1'/>
+          <var-decl name='update_time' type-id='64ecf6a5' visibility='default' filepath='include/linux/fs.h' line='1954' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='atomic_open' type-id='d3807eb0' visibility='default' filepath='include/linux/fs.h' line='1948' column='1'/>
+          <var-decl name='atomic_open' type-id='d3807eb0' visibility='default' filepath='include/linux/fs.h' line='1955' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='tmpfile' type-id='98c2d938' visibility='default' filepath='include/linux/fs.h' line='1951' column='1'/>
+          <var-decl name='tmpfile' type-id='98c2d938' visibility='default' filepath='include/linux/fs.h' line='1958' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1280'>
-          <var-decl name='set_acl' type-id='820976ef' visibility='default' filepath='include/linux/fs.h' line='1952' column='1'/>
+          <var-decl name='set_acl' type-id='820976ef' visibility='default' filepath='include/linux/fs.h' line='1959' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1344'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1954' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1961' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1408'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1955' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1962' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1472'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1956' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1963' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1957' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1964' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='5f5b9bdb'>
@@ -45018,12 +45147,12 @@
         <subrange length='2' type-id='7ff19f0f' id='52efc4ef'/>
       </array-type-def>
       <pointer-type-def type-id='e5f6c4d2' size-in-bits='64' id='5fe73d20'/>
-      <class-decl name='event_filter' size-in-bits='128' is-struct='yes' visibility='default' filepath='kernel/trace/trace.h' line='1428' column='1' id='5ff1273a'>
+      <class-decl name='event_filter' size-in-bits='128' is-struct='yes' visibility='default' filepath='kernel/trace/trace.h' line='1429' column='1' id='5ff1273a'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='prog' type-id='efd0fdec' visibility='default' filepath='kernel/trace/trace.h' line='1429' column='1'/>
+          <var-decl name='prog' type-id='efd0fdec' visibility='default' filepath='kernel/trace/trace.h' line='1430' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='filter_string' type-id='26a90f95' visibility='default' filepath='kernel/trace/trace.h' line='1430' column='1'/>
+          <var-decl name='filter_string' type-id='26a90f95' visibility='default' filepath='kernel/trace/trace.h' line='1431' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='5ff29c2c'>
@@ -45255,15 +45384,15 @@
         <parameter type-id='f0981eeb'/>
         <return type-id='48b5725f'/>
       </function-type>
-      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='924' column='1' id='607684dc'>
+      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='930' column='1' id='607684dc'>
         <data-member access='public'>
-          <var-decl name='' type-id='51db537c' visibility='default' filepath='include/linux/skbuff.h' line='924' column='1'/>
+          <var-decl name='' type-id='51db537c' visibility='default' filepath='include/linux/skbuff.h' line='930' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='' type-id='156952c4' visibility='default' filepath='include/linux/skbuff.h' line='924' column='1'/>
+          <var-decl name='' type-id='156952c4' visibility='default' filepath='include/linux/skbuff.h' line='930' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='' type-id='2a125a28' visibility='default' filepath='include/linux/skbuff.h' line='924' column='1'/>
+          <var-decl name='' type-id='2a125a28' visibility='default' filepath='include/linux/skbuff.h' line='930' column='1'/>
         </data-member>
       </union-decl>
       <function-type size-in-bits='64' id='607834f2'>
@@ -46748,21 +46877,21 @@
       <pointer-type-def type-id='eaa32e2f' size-in-bits='64' id='63e171df'/>
       <typedef-decl name='__kernel_pid_t' type-id='95e97e5e' filepath='include/uapi/asm-generic/posix_types.h' line='28' column='1' id='63eb2bf2'/>
       <pointer-type-def type-id='e29a2892' size-in-bits='64' id='63faaa44'/>
-      <class-decl name='filename' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='2591' column='1' id='63fc6210'>
+      <class-decl name='filename' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='2598' column='1' id='63fc6210'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='name' type-id='80f4b756' visibility='default' filepath='include/linux/fs.h' line='2592' column='1'/>
+          <var-decl name='name' type-id='80f4b756' visibility='default' filepath='include/linux/fs.h' line='2599' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='uptr' type-id='80f4b756' visibility='default' filepath='include/linux/fs.h' line='2593' column='1'/>
+          <var-decl name='uptr' type-id='80f4b756' visibility='default' filepath='include/linux/fs.h' line='2600' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='refcnt' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='2594' column='1'/>
+          <var-decl name='refcnt' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='2601' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='aname' type-id='5acb442f' visibility='default' filepath='include/linux/fs.h' line='2595' column='1'/>
+          <var-decl name='aname' type-id='5acb442f' visibility='default' filepath='include/linux/fs.h' line='2602' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='iname' type-id='0904d1cc' visibility='default' filepath='include/linux/fs.h' line='2596' column='1'/>
+          <var-decl name='iname' type-id='0904d1cc' visibility='default' filepath='include/linux/fs.h' line='2603' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='1aafc68e' size-in-bits='64' id='64015654'/>
@@ -47449,7 +47578,7 @@
         <return type-id='48b5725f'/>
       </function-type>
       <pointer-type-def type-id='7a7796b6' size-in-bits='64' id='66421794'/>
-      <enum-decl name='usb_pd_svdm_ver' filepath='include/linux/usb/typec.h' line='222' column='1' id='664a29a4'>
+      <enum-decl name='usb_pd_svdm_ver' filepath='include/linux/usb/typec.h' line='228' column='1' id='664a29a4'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='SVDM_VER_1_0' value='0'/>
         <enumerator name='SVDM_VER_2_0' value='1'/>
@@ -48245,6 +48374,16 @@
         <parameter type-id='19c2251e'/>
         <return type-id='95e97e5e'/>
       </function-type>
+      <enum-decl name='psi_states' filepath='include/linux/psi_types.h' line='47' column='1' id='6797a017'>
+        <underlying-type type-id='9cac1fee'/>
+        <enumerator name='PSI_IO_SOME' value='0'/>
+        <enumerator name='PSI_IO_FULL' value='1'/>
+        <enumerator name='PSI_MEM_SOME' value='2'/>
+        <enumerator name='PSI_MEM_FULL' value='3'/>
+        <enumerator name='PSI_CPU_SOME' value='4'/>
+        <enumerator name='PSI_NONIDLE' value='5'/>
+        <enumerator name='NR_PSI_STATES' value='6'/>
+      </enum-decl>
       <typedef-decl name='bh_end_io_t' type-id='e1740daa' filepath='include/linux/buffer_head.h' line='49' column='1' id='6797a3ea'/>
       <qualified-type-def type-id='cd7d3c9d' const='yes' id='67a1c23c'/>
       <pointer-type-def type-id='a80d6b6e' size-in-bits='64' id='67a2c0c8'/>
@@ -48442,7 +48581,7 @@
       </union-decl>
       <pointer-type-def type-id='514fe525' size-in-bits='64' id='67f526b5'/>
       <pointer-type-def type-id='02ee425a' size-in-bits='64' id='67f66cfc'/>
-      <typedef-decl name='xhci_get_quirks_t' type-id='da11b16a' filepath='drivers/usb/host/xhci.h' line='2104' column='1' id='67f831c0'/>
+      <typedef-decl name='xhci_get_quirks_t' type-id='da11b16a' filepath='drivers/usb/host/xhci.h' line='2106' column='1' id='67f831c0'/>
       <typedef-decl name='snd_pcm_format_t' type-id='95e97e5e' filepath='include/uapi/sound/asound.h' line='194' column='1' id='67fa9bd5'/>
       <pointer-type-def type-id='70e959e4' size-in-bits='64' id='68074686'/>
       <pointer-type-def type-id='b5d4a6d2' size-in-bits='64' id='680bf43c'/>
@@ -48882,7 +49021,6 @@
         <parameter type-id='5d6479ae'/>
         <return type-id='95e97e5e'/>
       </function-type>
-      <pointer-type-def type-id='e151e1f6' size-in-bits='64' id='68b31938'/>
       <class-decl name='module_layout' size-in-bits='640' is-struct='yes' visibility='default' filepath='include/linux/module.h' line='327' column='1' id='68b3d9a8'>
         <data-member access='public' layout-offset-in-bits='0'>
           <var-decl name='base' type-id='eaa32e2f' visibility='default' filepath='include/linux/module.h' line='329' column='1'/>
@@ -48917,7 +49055,7 @@
           <var-decl name='prefix' type-id='80f4b756' visibility='default' filepath='include/drm/drm_print.h' line='80' column='1'/>
         </data-member>
       </class-decl>
-      <enum-decl name='snd_soc_dapm_type' filepath='include/sound/soc-dapm.h' line='517' column='1' id='68bb1ec5'>
+      <enum-decl name='snd_soc_dapm_type' filepath='include/sound/soc-dapm.h' line='518' column='1' id='68bb1ec5'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='snd_soc_dapm_input' value='0'/>
         <enumerator name='snd_soc_dapm_output' value='1'/>
@@ -48988,27 +49126,27 @@
         <parameter type-id='85d57723'/>
         <return type-id='48b5725f'/>
       </function-type>
-      <class-decl name='pernet_operations' size-in-bits='512' is-struct='yes' visibility='default' filepath='include/net/net_namespace.h' line='368' column='1' id='68f5a646'>
+      <class-decl name='pernet_operations' size-in-bits='512' is-struct='yes' visibility='default' filepath='include/net/net_namespace.h' line='366' column='1' id='68f5a646'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/net/net_namespace.h' line='369' column='1'/>
+          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/net/net_namespace.h' line='367' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='init' type-id='e83d6bbe' visibility='default' filepath='include/net/net_namespace.h' line='392' column='1'/>
+          <var-decl name='init' type-id='e83d6bbe' visibility='default' filepath='include/net/net_namespace.h' line='390' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='pre_exit' type-id='9b92b29b' visibility='default' filepath='include/net/net_namespace.h' line='393' column='1'/>
+          <var-decl name='pre_exit' type-id='9b92b29b' visibility='default' filepath='include/net/net_namespace.h' line='391' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='exit' type-id='9b92b29b' visibility='default' filepath='include/net/net_namespace.h' line='394' column='1'/>
+          <var-decl name='exit' type-id='9b92b29b' visibility='default' filepath='include/net/net_namespace.h' line='392' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='exit_batch' type-id='29f83363' visibility='default' filepath='include/net/net_namespace.h' line='395' column='1'/>
+          <var-decl name='exit_batch' type-id='29f83363' visibility='default' filepath='include/net/net_namespace.h' line='393' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='id' type-id='807869d3' visibility='default' filepath='include/net/net_namespace.h' line='396' column='1'/>
+          <var-decl name='id' type-id='807869d3' visibility='default' filepath='include/net/net_namespace.h' line='394' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='size' type-id='b59d7dce' visibility='default' filepath='include/net/net_namespace.h' line='397' column='1'/>
+          <var-decl name='size' type-id='b59d7dce' visibility='default' filepath='include/net/net_namespace.h' line='395' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='bae213e3' size-in-bits='64' id='68f92bd7'/>
@@ -49776,42 +49914,42 @@
       </class-decl>
       <pointer-type-def type-id='3e1d184a' size-in-bits='64' id='6aee814c'/>
       <pointer-type-def type-id='74e7a035' size-in-bits='64' id='6af64a09'/>
-      <class-decl name='uncached_list' size-in-bits='192' is-struct='yes' visibility='default' filepath='net/ipv4/route.c' line='1543' column='1' id='6b1203e5'>
+      <class-decl name='uncached_list' size-in-bits='192' is-struct='yes' visibility='default' filepath='net/ipv4/route.c' line='1545' column='1' id='6b1203e5'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='lock' type-id='fb4018a0' visibility='default' filepath='net/ipv4/route.c' line='1544' column='1'/>
+          <var-decl name='lock' type-id='fb4018a0' visibility='default' filepath='net/ipv4/route.c' line='1546' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='head' type-id='72f469ec' visibility='default' filepath='net/ipv4/route.c' line='1545' column='1'/>
+          <var-decl name='head' type-id='72f469ec' visibility='default' filepath='net/ipv4/route.c' line='1547' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='bfbf7968' size-in-bits='64' id='6b1642ae'/>
-      <class-decl name='tty_bufhead' size-in-bits='1344' is-struct='yes' visibility='default' filepath='include/linux/tty.h' line='86' column='1' id='6b1bde38'>
+      <class-decl name='tty_bufhead' size-in-bits='1344' is-struct='yes' visibility='default' filepath='include/linux/tty.h' line='62' column='1' id='6b1bde38'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='head' type-id='a150e667' visibility='default' filepath='include/linux/tty.h' line='87' column='1'/>
+          <var-decl name='head' type-id='a150e667' visibility='default' filepath='include/linux/tty.h' line='63' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='work' type-id='ef9025d0' visibility='default' filepath='include/linux/tty.h' line='88' column='1'/>
+          <var-decl name='work' type-id='ef9025d0' visibility='default' filepath='include/linux/tty.h' line='64' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='lock' type-id='925167dc' visibility='default' filepath='include/linux/tty.h' line='89' column='1'/>
+          <var-decl name='lock' type-id='925167dc' visibility='default' filepath='include/linux/tty.h' line='65' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='priority' type-id='49178f86' visibility='default' filepath='include/linux/tty.h' line='90' column='1'/>
+          <var-decl name='priority' type-id='49178f86' visibility='default' filepath='include/linux/tty.h' line='66' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='sentinel' type-id='2f351d1f' visibility='default' filepath='include/linux/tty.h' line='91' column='1'/>
+          <var-decl name='sentinel' type-id='2f351d1f' visibility='default' filepath='include/linux/tty.h' line='67' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='free' type-id='77df194e' visibility='default' filepath='include/linux/tty.h' line='92' column='1'/>
+          <var-decl name='free' type-id='77df194e' visibility='default' filepath='include/linux/tty.h' line='68' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='mem_used' type-id='49178f86' visibility='default' filepath='include/linux/tty.h' line='93' column='1'/>
+          <var-decl name='mem_used' type-id='49178f86' visibility='default' filepath='include/linux/tty.h' line='69' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1248'>
-          <var-decl name='mem_limit' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='94' column='1'/>
+          <var-decl name='mem_limit' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='70' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1280'>
-          <var-decl name='tail' type-id='a150e667' visibility='default' filepath='include/linux/tty.h' line='95' column='1'/>
+          <var-decl name='tail' type-id='a150e667' visibility='default' filepath='include/linux/tty.h' line='71' column='1'/>
         </data-member>
       </class-decl>
       <union-decl name='__anonymous_union__' size-in-bits='128' is-anonymous='yes' visibility='default' filepath='include/linux/bpf.h' line='773' column='1' id='6b217604'>
@@ -51410,15 +51548,15 @@
           <var-decl name='tx_stopped' type-id='f0981eeb' visibility='default' filepath='include/linux/serial_8250.h' line='84' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='rps_map' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='690' column='1' id='6f8d5f55'>
+      <class-decl name='rps_map' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='692' column='1' id='6f8d5f55'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='len' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='691' column='1'/>
+          <var-decl name='len' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='693' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/netdevice.h' line='692' column='1'/>
+          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/netdevice.h' line='694' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='cpus' type-id='0f300383' visibility='default' filepath='include/linux/netdevice.h' line='693' column='1'/>
+          <var-decl name='cpus' type-id='0f300383' visibility='default' filepath='include/linux/netdevice.h' line='695' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='61062930' size-in-bits='64' id='6fa26802'/>
@@ -51741,18 +51879,18 @@
           <var-decl name='head' type-id='d504f73d' visibility='default' filepath='include/linux/notifier.h' line='67' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='dwc3_trb' size-in-bits='128' is-struct='yes' visibility='default' filepath='drivers/usb/dwc3/core.h' line='846' column='1' id='70923669'>
+      <class-decl name='dwc3_trb' size-in-bits='128' is-struct='yes' visibility='default' filepath='drivers/usb/dwc3/core.h' line='847' column='1' id='70923669'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='bpl' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='847' column='1'/>
+          <var-decl name='bpl' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='848' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='bph' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='848' column='1'/>
+          <var-decl name='bph' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='849' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='size' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='849' column='1'/>
+          <var-decl name='size' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='850' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='ctrl' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='850' column='1'/>
+          <var-decl name='ctrl' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='851' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='pci_error_handlers' size-in-bits='448' is-struct='yes' visibility='default' filepath='include/linux/pci.h' line='814' column='1' id='709bf5ba'>
@@ -51833,24 +51971,24 @@
           <var-decl name='queue_ctx' type-id='9a335021' visibility='default' filepath='block/blk-mq.h' line='12' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='fasync_struct' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='1348' column='1' id='70c545cd'>
+      <class-decl name='fasync_struct' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='1354' column='1' id='70c545cd'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='fa_lock' type-id='ac16795b' visibility='default' filepath='include/linux/fs.h' line='1349' column='1'/>
+          <var-decl name='fa_lock' type-id='ac16795b' visibility='default' filepath='include/linux/fs.h' line='1355' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='magic' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='1350' column='1'/>
+          <var-decl name='magic' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='1356' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='fa_fd' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='1351' column='1'/>
+          <var-decl name='fa_fd' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='1357' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='fa_next' type-id='5bb9c75d' visibility='default' filepath='include/linux/fs.h' line='1352' column='1'/>
+          <var-decl name='fa_next' type-id='5bb9c75d' visibility='default' filepath='include/linux/fs.h' line='1358' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='fa_file' type-id='77e79a4b' visibility='default' filepath='include/linux/fs.h' line='1353' column='1'/>
+          <var-decl name='fa_file' type-id='77e79a4b' visibility='default' filepath='include/linux/fs.h' line='1359' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='fa_rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/fs.h' line='1354' column='1'/>
+          <var-decl name='fa_rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/fs.h' line='1360' column='1'/>
         </data-member>
       </class-decl>
       <array-type-def dimensions='1' type-id='95e97e5e' size-in-bits='1536' id='70cd8d02'>
@@ -51875,12 +52013,12 @@
         <return type-id='48b5725f'/>
       </function-type>
       <pointer-type-def type-id='81d3e1dd' size-in-bits='64' id='710bea3d'/>
-      <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='756' column='1' id='710cec71'>
+      <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='758' column='1' id='710cec71'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='_skb_refdst' type-id='7359adad' visibility='default' filepath='include/linux/skbuff.h' line='757' column='1'/>
+          <var-decl name='_skb_refdst' type-id='7359adad' visibility='default' filepath='include/linux/skbuff.h' line='759' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='destructor' type-id='0ef96694' visibility='default' filepath='include/linux/skbuff.h' line='758' column='1'/>
+          <var-decl name='destructor' type-id='0ef96694' visibility='default' filepath='include/linux/skbuff.h' line='760' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='clk_parent_map' size-in-bits='320' is-struct='yes' visibility='default' filepath='drivers/clk/clk.c' line='48' column='1' id='710f82fd'>
@@ -52255,162 +52393,162 @@
           <var-decl name='type' type-id='9ff1dafd' visibility='default' filepath='include/linux/quota.h' line='74' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='proto' size-in-bits='3328' is-struct='yes' visibility='default' filepath='include/net/sock.h' line='1175' column='1' id='7203ee09'>
+      <class-decl name='proto' size-in-bits='3328' is-struct='yes' visibility='default' filepath='include/net/sock.h' line='1183' column='1' id='7203ee09'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='close' type-id='09f3a86b' visibility='default' filepath='include/net/sock.h' line='1176' column='1'/>
+          <var-decl name='close' type-id='09f3a86b' visibility='default' filepath='include/net/sock.h' line='1184' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='pre_connect' type-id='c25ed103' visibility='default' filepath='include/net/sock.h' line='1178' column='1'/>
+          <var-decl name='pre_connect' type-id='c25ed103' visibility='default' filepath='include/net/sock.h' line='1186' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='connect' type-id='c25ed103' visibility='default' filepath='include/net/sock.h' line='1181' column='1'/>
+          <var-decl name='connect' type-id='c25ed103' visibility='default' filepath='include/net/sock.h' line='1189' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='disconnect' type-id='95208a5e' visibility='default' filepath='include/net/sock.h' line='1184' column='1'/>
+          <var-decl name='disconnect' type-id='95208a5e' visibility='default' filepath='include/net/sock.h' line='1192' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='accept' type-id='67adf9a9' visibility='default' filepath='include/net/sock.h' line='1186' column='1'/>
+          <var-decl name='accept' type-id='67adf9a9' visibility='default' filepath='include/net/sock.h' line='1194' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='ioctl' type-id='08113f0a' visibility='default' filepath='include/net/sock.h' line='1189' column='1'/>
+          <var-decl name='ioctl' type-id='08113f0a' visibility='default' filepath='include/net/sock.h' line='1197' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='init' type-id='55530c47' visibility='default' filepath='include/net/sock.h' line='1191' column='1'/>
+          <var-decl name='init' type-id='55530c47' visibility='default' filepath='include/net/sock.h' line='1199' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='destroy' type-id='841969d0' visibility='default' filepath='include/net/sock.h' line='1192' column='1'/>
+          <var-decl name='destroy' type-id='841969d0' visibility='default' filepath='include/net/sock.h' line='1200' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='shutdown' type-id='e937debf' visibility='default' filepath='include/net/sock.h' line='1193' column='1'/>
+          <var-decl name='shutdown' type-id='e937debf' visibility='default' filepath='include/net/sock.h' line='1201' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='setsockopt' type-id='df9e6665' visibility='default' filepath='include/net/sock.h' line='1194' column='1'/>
+          <var-decl name='setsockopt' type-id='df9e6665' visibility='default' filepath='include/net/sock.h' line='1202' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='getsockopt' type-id='e0fadd76' visibility='default' filepath='include/net/sock.h' line='1197' column='1'/>
+          <var-decl name='getsockopt' type-id='e0fadd76' visibility='default' filepath='include/net/sock.h' line='1205' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='keepalive' type-id='e937debf' visibility='default' filepath='include/net/sock.h' line='1200' column='1'/>
+          <var-decl name='keepalive' type-id='e937debf' visibility='default' filepath='include/net/sock.h' line='1208' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='compat_ioctl' type-id='20da830b' visibility='default' filepath='include/net/sock.h' line='1202' column='1'/>
+          <var-decl name='compat_ioctl' type-id='20da830b' visibility='default' filepath='include/net/sock.h' line='1210' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='sendmsg' type-id='1df08751' visibility='default' filepath='include/net/sock.h' line='1205' column='1'/>
+          <var-decl name='sendmsg' type-id='1df08751' visibility='default' filepath='include/net/sock.h' line='1213' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='recvmsg' type-id='74e71fae' visibility='default' filepath='include/net/sock.h' line='1207' column='1'/>
+          <var-decl name='recvmsg' type-id='74e71fae' visibility='default' filepath='include/net/sock.h' line='1215' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='sendpage' type-id='65399e23' visibility='default' filepath='include/net/sock.h' line='1210' column='1'/>
+          <var-decl name='sendpage' type-id='65399e23' visibility='default' filepath='include/net/sock.h' line='1218' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='bind' type-id='c25ed103' visibility='default' filepath='include/net/sock.h' line='1212' column='1'/>
+          <var-decl name='bind' type-id='c25ed103' visibility='default' filepath='include/net/sock.h' line='1220' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1088'>
-          <var-decl name='bind_add' type-id='c25ed103' visibility='default' filepath='include/net/sock.h' line='1214' column='1'/>
+          <var-decl name='bind_add' type-id='c25ed103' visibility='default' filepath='include/net/sock.h' line='1222' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='backlog_rcv' type-id='a0f5247f' visibility='default' filepath='include/net/sock.h' line='1217' column='1'/>
+          <var-decl name='backlog_rcv' type-id='a0f5247f' visibility='default' filepath='include/net/sock.h' line='1225' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='release_cb' type-id='841969d0' visibility='default' filepath='include/net/sock.h' line='1220' column='1'/>
+          <var-decl name='release_cb' type-id='841969d0' visibility='default' filepath='include/net/sock.h' line='1228' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1280'>
-          <var-decl name='hash' type-id='55530c47' visibility='default' filepath='include/net/sock.h' line='1223' column='1'/>
+          <var-decl name='hash' type-id='55530c47' visibility='default' filepath='include/net/sock.h' line='1231' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1344'>
-          <var-decl name='unhash' type-id='841969d0' visibility='default' filepath='include/net/sock.h' line='1224' column='1'/>
+          <var-decl name='unhash' type-id='841969d0' visibility='default' filepath='include/net/sock.h' line='1232' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1408'>
-          <var-decl name='rehash' type-id='841969d0' visibility='default' filepath='include/net/sock.h' line='1225' column='1'/>
+          <var-decl name='rehash' type-id='841969d0' visibility='default' filepath='include/net/sock.h' line='1233' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1472'>
-          <var-decl name='get_port' type-id='078de3a3' visibility='default' filepath='include/net/sock.h' line='1226' column='1'/>
+          <var-decl name='get_port' type-id='078de3a3' visibility='default' filepath='include/net/sock.h' line='1234' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='inuse_idx' type-id='f0981eeb' visibility='default' filepath='include/net/sock.h' line='1230' column='1'/>
+          <var-decl name='inuse_idx' type-id='f0981eeb' visibility='default' filepath='include/net/sock.h' line='1238' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1600'>
-          <var-decl name='stream_memory_free' type-id='bf751261' visibility='default' filepath='include/net/sock.h' line='1233' column='1'/>
+          <var-decl name='stream_memory_free' type-id='bf751261' visibility='default' filepath='include/net/sock.h' line='1241' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1664'>
-          <var-decl name='stream_memory_read' type-id='3d4d3aba' visibility='default' filepath='include/net/sock.h' line='1234' column='1'/>
+          <var-decl name='stream_memory_read' type-id='3d4d3aba' visibility='default' filepath='include/net/sock.h' line='1242' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1728'>
-          <var-decl name='enter_memory_pressure' type-id='841969d0' visibility='default' filepath='include/net/sock.h' line='1236' column='1'/>
+          <var-decl name='enter_memory_pressure' type-id='841969d0' visibility='default' filepath='include/net/sock.h' line='1244' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1792'>
-          <var-decl name='leave_memory_pressure' type-id='841969d0' visibility='default' filepath='include/net/sock.h' line='1237' column='1'/>
+          <var-decl name='leave_memory_pressure' type-id='841969d0' visibility='default' filepath='include/net/sock.h' line='1245' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1856'>
-          <var-decl name='memory_allocated' type-id='5403cb36' visibility='default' filepath='include/net/sock.h' line='1238' column='1'/>
+          <var-decl name='memory_allocated' type-id='5403cb36' visibility='default' filepath='include/net/sock.h' line='1246' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1920'>
-          <var-decl name='sockets_allocated' type-id='84c6078d' visibility='default' filepath='include/net/sock.h' line='1239' column='1'/>
+          <var-decl name='sockets_allocated' type-id='84c6078d' visibility='default' filepath='include/net/sock.h' line='1247' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1984'>
-          <var-decl name='memory_pressure' type-id='1d2c2b85' visibility='default' filepath='include/net/sock.h' line='1246' column='1'/>
+          <var-decl name='memory_pressure' type-id='1d2c2b85' visibility='default' filepath='include/net/sock.h' line='1254' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2048'>
-          <var-decl name='sysctl_mem' type-id='3ccc2590' visibility='default' filepath='include/net/sock.h' line='1247' column='1'/>
+          <var-decl name='sysctl_mem' type-id='3ccc2590' visibility='default' filepath='include/net/sock.h' line='1255' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2112'>
-          <var-decl name='sysctl_wmem' type-id='7292109c' visibility='default' filepath='include/net/sock.h' line='1249' column='1'/>
+          <var-decl name='sysctl_wmem' type-id='7292109c' visibility='default' filepath='include/net/sock.h' line='1257' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2176'>
-          <var-decl name='sysctl_rmem' type-id='7292109c' visibility='default' filepath='include/net/sock.h' line='1250' column='1'/>
+          <var-decl name='sysctl_rmem' type-id='7292109c' visibility='default' filepath='include/net/sock.h' line='1258' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2240'>
-          <var-decl name='sysctl_wmem_offset' type-id='19c2251e' visibility='default' filepath='include/net/sock.h' line='1251' column='1'/>
+          <var-decl name='sysctl_wmem_offset' type-id='19c2251e' visibility='default' filepath='include/net/sock.h' line='1259' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2272'>
-          <var-decl name='sysctl_rmem_offset' type-id='19c2251e' visibility='default' filepath='include/net/sock.h' line='1252' column='1'/>
+          <var-decl name='sysctl_rmem_offset' type-id='19c2251e' visibility='default' filepath='include/net/sock.h' line='1260' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2304'>
-          <var-decl name='max_header' type-id='95e97e5e' visibility='default' filepath='include/net/sock.h' line='1254' column='1'/>
+          <var-decl name='max_header' type-id='95e97e5e' visibility='default' filepath='include/net/sock.h' line='1262' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2336'>
-          <var-decl name='no_autobind' type-id='b50a4934' visibility='default' filepath='include/net/sock.h' line='1255' column='1'/>
+          <var-decl name='no_autobind' type-id='b50a4934' visibility='default' filepath='include/net/sock.h' line='1263' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2368'>
-          <var-decl name='slab' type-id='f3b4aca8' visibility='default' filepath='include/net/sock.h' line='1257' column='1'/>
+          <var-decl name='slab' type-id='f3b4aca8' visibility='default' filepath='include/net/sock.h' line='1265' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2432'>
-          <var-decl name='obj_size' type-id='f0981eeb' visibility='default' filepath='include/net/sock.h' line='1258' column='1'/>
+          <var-decl name='obj_size' type-id='f0981eeb' visibility='default' filepath='include/net/sock.h' line='1266' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2464'>
-          <var-decl name='slab_flags' type-id='f7fe96cb' visibility='default' filepath='include/net/sock.h' line='1259' column='1'/>
+          <var-decl name='slab_flags' type-id='f7fe96cb' visibility='default' filepath='include/net/sock.h' line='1267' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2496'>
-          <var-decl name='useroffset' type-id='f0981eeb' visibility='default' filepath='include/net/sock.h' line='1260' column='1'/>
+          <var-decl name='useroffset' type-id='f0981eeb' visibility='default' filepath='include/net/sock.h' line='1268' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2528'>
-          <var-decl name='usersize' type-id='f0981eeb' visibility='default' filepath='include/net/sock.h' line='1261' column='1'/>
+          <var-decl name='usersize' type-id='f0981eeb' visibility='default' filepath='include/net/sock.h' line='1269' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2560'>
-          <var-decl name='orphan_count' type-id='84c6078d' visibility='default' filepath='include/net/sock.h' line='1263' column='1'/>
+          <var-decl name='orphan_count' type-id='84c6078d' visibility='default' filepath='include/net/sock.h' line='1271' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2624'>
-          <var-decl name='rsk_prot' type-id='db994912' visibility='default' filepath='include/net/sock.h' line='1265' column='1'/>
+          <var-decl name='rsk_prot' type-id='db994912' visibility='default' filepath='include/net/sock.h' line='1273' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2688'>
-          <var-decl name='twsk_prot' type-id='d68ad8b5' visibility='default' filepath='include/net/sock.h' line='1266' column='1'/>
+          <var-decl name='twsk_prot' type-id='d68ad8b5' visibility='default' filepath='include/net/sock.h' line='1274' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2752'>
-          <var-decl name='h' type-id='adf5bf47' visibility='default' filepath='include/net/sock.h' line='1273' column='1'/>
+          <var-decl name='h' type-id='adf5bf47' visibility='default' filepath='include/net/sock.h' line='1281' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2816'>
-          <var-decl name='owner' type-id='2730d015' visibility='default' filepath='include/net/sock.h' line='1275' column='1'/>
+          <var-decl name='owner' type-id='2730d015' visibility='default' filepath='include/net/sock.h' line='1283' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2880'>
-          <var-decl name='name' type-id='16dc656a' visibility='default' filepath='include/net/sock.h' line='1277' column='1'/>
+          <var-decl name='name' type-id='16dc656a' visibility='default' filepath='include/net/sock.h' line='1285' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3136'>
-          <var-decl name='node' type-id='72f469ec' visibility='default' filepath='include/net/sock.h' line='1279' column='1'/>
+          <var-decl name='node' type-id='72f469ec' visibility='default' filepath='include/net/sock.h' line='1287' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3264'>
-          <var-decl name='diag_destroy' type-id='95208a5e' visibility='default' filepath='include/net/sock.h' line='1283' column='1'/>
+          <var-decl name='diag_destroy' type-id='95208a5e' visibility='default' filepath='include/net/sock.h' line='1291' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='trace_buffer' is-struct='yes' visibility='default' is-declaration-only='yes' id='72093c11'/>
@@ -52442,6 +52580,20 @@
         <return type-id='95e97e5e'/>
       </function-type>
       <pointer-type-def type-id='dd72818d' size-in-bits='64' id='722604ad'/>
+      <class-decl name='psi_window' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/psi_types.h' line='90' column='1' id='722d6f6c'>
+        <data-member access='public' layout-offset-in-bits='0'>
+          <var-decl name='size' type-id='91ce1af9' visibility='default' filepath='include/linux/psi_types.h' line='92' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='64'>
+          <var-decl name='start_time' type-id='91ce1af9' visibility='default' filepath='include/linux/psi_types.h' line='95' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='128'>
+          <var-decl name='start_value' type-id='91ce1af9' visibility='default' filepath='include/linux/psi_types.h' line='98' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='192'>
+          <var-decl name='prev_growth' type-id='91ce1af9' visibility='default' filepath='include/linux/psi_types.h' line='101' column='1'/>
+        </data-member>
+      </class-decl>
       <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/net/flow_offload.h' line='210' column='1' id='722ea479'>
         <data-member access='public' layout-offset-in-bits='0'>
           <var-decl name='htype' type-id='c3972c2e' visibility='default' filepath='include/net/flow_offload.h' line='212' column='1'/>
@@ -53826,13 +53978,6 @@
         <parameter type-id='4db02c58'/>
         <return type-id='c91d1bf1'/>
       </function-type>
-      <function-type size-in-bits='64' id='74fec388'>
-        <parameter type-id='77e79a4b'/>
-        <parameter type-id='eaa32e2f'/>
-        <parameter type-id='b59d7dce'/>
-        <parameter type-id='91ce1af9'/>
-        <return type-id='95e97e5e'/>
-      </function-type>
       <function-type size-in-bits='64' id='7506f11b'>
         <parameter type-id='b7c1d7d5'/>
         <parameter type-id='99baf115'/>
@@ -53892,45 +54037,45 @@
           <var-decl name='zone_device_data' type-id='eaa32e2f' visibility='default' filepath='include/linux/mm_types.h' line='165' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='irqaction' size-in-bits='1024' is-struct='yes' visibility='default' filepath='include/linux/interrupt.h' line='110' column='1' id='754d1c63'>
+      <class-decl name='irqaction' size-in-bits='1024' is-struct='yes' visibility='default' filepath='include/linux/interrupt.h' line='114' column='1' id='754d1c63'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='handler' type-id='29591c9a' visibility='default' filepath='include/linux/interrupt.h' line='111' column='1'/>
+          <var-decl name='handler' type-id='29591c9a' visibility='default' filepath='include/linux/interrupt.h' line='115' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='dev_id' type-id='eaa32e2f' visibility='default' filepath='include/linux/interrupt.h' line='112' column='1'/>
+          <var-decl name='dev_id' type-id='eaa32e2f' visibility='default' filepath='include/linux/interrupt.h' line='116' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='percpu_dev_id' type-id='eaa32e2f' visibility='default' filepath='include/linux/interrupt.h' line='113' column='1'/>
+          <var-decl name='percpu_dev_id' type-id='eaa32e2f' visibility='default' filepath='include/linux/interrupt.h' line='117' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='next' type-id='ba361e53' visibility='default' filepath='include/linux/interrupt.h' line='114' column='1'/>
+          <var-decl name='next' type-id='ba361e53' visibility='default' filepath='include/linux/interrupt.h' line='118' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='thread_fn' type-id='29591c9a' visibility='default' filepath='include/linux/interrupt.h' line='115' column='1'/>
+          <var-decl name='thread_fn' type-id='29591c9a' visibility='default' filepath='include/linux/interrupt.h' line='119' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='thread' type-id='f23e2572' visibility='default' filepath='include/linux/interrupt.h' line='116' column='1'/>
+          <var-decl name='thread' type-id='f23e2572' visibility='default' filepath='include/linux/interrupt.h' line='120' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='secondary' type-id='ba361e53' visibility='default' filepath='include/linux/interrupt.h' line='117' column='1'/>
+          <var-decl name='secondary' type-id='ba361e53' visibility='default' filepath='include/linux/interrupt.h' line='121' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='irq' type-id='f0981eeb' visibility='default' filepath='include/linux/interrupt.h' line='118' column='1'/>
+          <var-decl name='irq' type-id='f0981eeb' visibility='default' filepath='include/linux/interrupt.h' line='122' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='480'>
-          <var-decl name='flags' type-id='f0981eeb' visibility='default' filepath='include/linux/interrupt.h' line='119' column='1'/>
+          <var-decl name='flags' type-id='f0981eeb' visibility='default' filepath='include/linux/interrupt.h' line='123' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='thread_flags' type-id='7359adad' visibility='default' filepath='include/linux/interrupt.h' line='120' column='1'/>
+          <var-decl name='thread_flags' type-id='7359adad' visibility='default' filepath='include/linux/interrupt.h' line='124' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='thread_mask' type-id='7359adad' visibility='default' filepath='include/linux/interrupt.h' line='121' column='1'/>
+          <var-decl name='thread_mask' type-id='7359adad' visibility='default' filepath='include/linux/interrupt.h' line='125' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='name' type-id='80f4b756' visibility='default' filepath='include/linux/interrupt.h' line='122' column='1'/>
+          <var-decl name='name' type-id='80f4b756' visibility='default' filepath='include/linux/interrupt.h' line='126' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='dir' type-id='d077e928' visibility='default' filepath='include/linux/interrupt.h' line='123' column='1'/>
+          <var-decl name='dir' type-id='d077e928' visibility='default' filepath='include/linux/interrupt.h' line='127' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='0627f2fd' size-in-bits='64' id='754d9fe1'/>
@@ -54117,12 +54262,12 @@
       <pointer-type-def type-id='f22fb39c' size-in-bits='64' id='75f1eb36'/>
       <pointer-type-def type-id='8696da2b' size-in-bits='64' id='75f3cc0b'/>
       <pointer-type-def type-id='5e09ca8a' size-in-bits='64' id='75f72758'/>
-      <class-decl name='__anonymous_struct__' size-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/netdevice.h' line='3288' column='1' id='75fc4829'>
+      <class-decl name='__anonymous_struct__' size-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/netdevice.h' line='3289' column='1' id='75fc4829'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='recursion' type-id='1dc6a898' visibility='default' filepath='include/linux/netdevice.h' line='3289' column='1'/>
+          <var-decl name='recursion' type-id='1dc6a898' visibility='default' filepath='include/linux/netdevice.h' line='3290' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='16'>
-          <var-decl name='more' type-id='f9b06939' visibility='default' filepath='include/linux/netdevice.h' line='3290' column='1'/>
+          <var-decl name='more' type-id='f9b06939' visibility='default' filepath='include/linux/netdevice.h' line='3291' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='f0966d3d' size-in-bits='64' id='7604ff1d'/>
@@ -54565,24 +54710,24 @@
       <pointer-type-def type-id='2e3fb70e' size-in-bits='64' id='776946b4'/>
       <pointer-type-def type-id='4af8a458' size-in-bits='64' id='776adf76'/>
       <pointer-type-def type-id='1fbf855f' size-in-bits='64' id='776fd487'/>
-      <class-decl name='tty_port_operations' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/tty.h' line='206' column='1' id='7778009d'>
+      <class-decl name='tty_port_operations' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/tty.h' line='182' column='1' id='7778009d'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='carrier_raised' type-id='5626e636' visibility='default' filepath='include/linux/tty.h' line='208' column='1'/>
+          <var-decl name='carrier_raised' type-id='5626e636' visibility='default' filepath='include/linux/tty.h' line='184' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='dtr_rts' type-id='21b6f944' visibility='default' filepath='include/linux/tty.h' line='210' column='1'/>
+          <var-decl name='dtr_rts' type-id='21b6f944' visibility='default' filepath='include/linux/tty.h' line='186' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='shutdown' type-id='7e5b379d' visibility='default' filepath='include/linux/tty.h' line='214' column='1'/>
+          <var-decl name='shutdown' type-id='7e5b379d' visibility='default' filepath='include/linux/tty.h' line='190' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='activate' type-id='62d26ff9' visibility='default' filepath='include/linux/tty.h' line='219' column='1'/>
+          <var-decl name='activate' type-id='62d26ff9' visibility='default' filepath='include/linux/tty.h' line='195' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='destruct' type-id='7e5b379d' visibility='default' filepath='include/linux/tty.h' line='221' column='1'/>
+          <var-decl name='destruct' type-id='7e5b379d' visibility='default' filepath='include/linux/tty.h' line='197' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/tty.h' line='223' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/tty.h' line='199' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='77780344'>
@@ -55834,24 +55979,24 @@
       <qualified-type-def type-id='e726245b' const='yes' id='7a773bd0'/>
       <qualified-type-def type-id='7fe6c639' const='yes' id='7a7796b6'/>
       <qualified-type-def type-id='0647d262' const='yes' id='7a78fb67'/>
-      <class-decl name='tasklet_struct' size-in-bits='320' is-struct='yes' visibility='default' filepath='include/linux/interrupt.h' line='616' column='1' id='7a7ea727'>
+      <class-decl name='tasklet_struct' size-in-bits='320' is-struct='yes' visibility='default' filepath='include/linux/interrupt.h' line='620' column='1' id='7a7ea727'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='next' type-id='59f1923f' visibility='default' filepath='include/linux/interrupt.h' line='618' column='1'/>
+          <var-decl name='next' type-id='59f1923f' visibility='default' filepath='include/linux/interrupt.h' line='622' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='state' type-id='7359adad' visibility='default' filepath='include/linux/interrupt.h' line='619' column='1'/>
+          <var-decl name='state' type-id='7359adad' visibility='default' filepath='include/linux/interrupt.h' line='623' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='count' type-id='49178f86' visibility='default' filepath='include/linux/interrupt.h' line='620' column='1'/>
+          <var-decl name='count' type-id='49178f86' visibility='default' filepath='include/linux/interrupt.h' line='624' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='160'>
-          <var-decl name='use_callback' type-id='b50a4934' visibility='default' filepath='include/linux/interrupt.h' line='621' column='1'/>
+          <var-decl name='use_callback' type-id='b50a4934' visibility='default' filepath='include/linux/interrupt.h' line='625' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='' type-id='eae5c421' visibility='default' filepath='include/linux/interrupt.h' line='622' column='1'/>
+          <var-decl name='' type-id='eae5c421' visibility='default' filepath='include/linux/interrupt.h' line='626' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='data' type-id='7359adad' visibility='default' filepath='include/linux/interrupt.h' line='626' column='1'/>
+          <var-decl name='data' type-id='7359adad' visibility='default' filepath='include/linux/interrupt.h' line='630' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='vsock_transport' size-in-bits='1920' is-struct='yes' visibility='default' filepath='include/net/af_vsock.h' line='104' column='1' id='7a801157'>
@@ -56258,21 +56403,21 @@
           <var-decl name='bus' type-id='a37ee787' visibility='default' filepath='include/linux/i3c/master.h' line='232' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='sd_flow_limit' size-in-bits='2176' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='3253' column='1' id='7ba771af'>
+      <class-decl name='sd_flow_limit' size-in-bits='2176' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='3254' column='1' id='7ba771af'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='count' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='3254' column='1'/>
+          <var-decl name='count' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='3255' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='num_buckets' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3255' column='1'/>
+          <var-decl name='num_buckets' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3256' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='history_head' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3256' column='1'/>
+          <var-decl name='history_head' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='3257' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='history' type-id='13faf778' visibility='default' filepath='include/linux/netdevice.h' line='3257' column='1'/>
+          <var-decl name='history' type-id='13faf778' visibility='default' filepath='include/linux/netdevice.h' line='3258' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2176'>
-          <var-decl name='buckets' type-id='29c3368c' visibility='default' filepath='include/linux/netdevice.h' line='3258' column='1'/>
+          <var-decl name='buckets' type-id='29c3368c' visibility='default' filepath='include/linux/netdevice.h' line='3259' column='1'/>
         </data-member>
       </class-decl>
       <qualified-type-def type-id='c4601f87' const='yes' id='7bacac96'/>
@@ -56484,15 +56629,15 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='cd5ad9b0' size-in-bits='64' id='7c07671a'/>
-      <class-decl name='rcu_work' size-in-bits='576' is-struct='yes' visibility='default' filepath='include/linux/workqueue.h' line='130' column='1' id='7c0b9fdb'>
+      <class-decl name='rcu_work' size-in-bits='576' is-struct='yes' visibility='default' filepath='include/linux/workqueue.h' line='131' column='1' id='7c0b9fdb'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='work' type-id='ef9025d0' visibility='default' filepath='include/linux/workqueue.h' line='131' column='1'/>
+          <var-decl name='work' type-id='ef9025d0' visibility='default' filepath='include/linux/workqueue.h' line='132' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/workqueue.h' line='132' column='1'/>
+          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/workqueue.h' line='133' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='wq' type-id='242e3d19' visibility='default' filepath='include/linux/workqueue.h' line='135' column='1'/>
+          <var-decl name='wq' type-id='242e3d19' visibility='default' filepath='include/linux/workqueue.h' line='136' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='6daa74bb' size-in-bits='64' id='7c0fed0f'/>
@@ -56764,12 +56909,12 @@
         <subrange length='infinite' type-id='7ff19f0f' id='031f2035'/>
       </array-type-def>
       <qualified-type-def type-id='d53c2eb5' const='yes' id='7c7c6daa'/>
-      <class-decl name='ctl_dir' size-in-bits='704' is-struct='yes' visibility='default' filepath='include/linux/sysctl.h' line='150' column='1' id='7c7d6006'>
+      <class-decl name='ctl_dir' size-in-bits='704' is-struct='yes' visibility='default' filepath='include/linux/sysctl.h' line='160' column='1' id='7c7d6006'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='header' type-id='ed51618b' visibility='default' filepath='include/linux/sysctl.h' line='152' column='1'/>
+          <var-decl name='header' type-id='ed51618b' visibility='default' filepath='include/linux/sysctl.h' line='162' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='root' type-id='dec44472' visibility='default' filepath='include/linux/sysctl.h' line='153' column='1'/>
+          <var-decl name='root' type-id='dec44472' visibility='default' filepath='include/linux/sysctl.h' line='163' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='4a1729fc' size-in-bits='64' id='7c7fffd6'/>
@@ -57148,39 +57293,39 @@
         <parameter type-id='c60ba652'/>
         <return type-id='48b5725f'/>
       </function-type>
-      <class-decl name='usb_tt' size-in-bits='1024' is-struct='yes' visibility='default' filepath='include/linux/usb/hcd.h' line='566' column='1' id='7dda8bf2'>
+      <class-decl name='usb_tt' size-in-bits='1024' is-struct='yes' visibility='default' filepath='include/linux/usb/hcd.h' line='571' column='1' id='7dda8bf2'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='hub' type-id='25e60cb2' visibility='default' filepath='include/linux/usb/hcd.h' line='567' column='1'/>
+          <var-decl name='hub' type-id='25e60cb2' visibility='default' filepath='include/linux/usb/hcd.h' line='572' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='multi' type-id='95e97e5e' visibility='default' filepath='include/linux/usb/hcd.h' line='568' column='1'/>
+          <var-decl name='multi' type-id='95e97e5e' visibility='default' filepath='include/linux/usb/hcd.h' line='573' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='think_time' type-id='f0981eeb' visibility='default' filepath='include/linux/usb/hcd.h' line='569' column='1'/>
+          <var-decl name='think_time' type-id='f0981eeb' visibility='default' filepath='include/linux/usb/hcd.h' line='574' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='hcpriv' type-id='eaa32e2f' visibility='default' filepath='include/linux/usb/hcd.h' line='570' column='1'/>
+          <var-decl name='hcpriv' type-id='eaa32e2f' visibility='default' filepath='include/linux/usb/hcd.h' line='575' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='lock' type-id='fb4018a0' visibility='default' filepath='include/linux/usb/hcd.h' line='573' column='1'/>
+          <var-decl name='lock' type-id='fb4018a0' visibility='default' filepath='include/linux/usb/hcd.h' line='578' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='clear_list' type-id='72f469ec' visibility='default' filepath='include/linux/usb/hcd.h' line='574' column='1'/>
+          <var-decl name='clear_list' type-id='72f469ec' visibility='default' filepath='include/linux/usb/hcd.h' line='579' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='clear_work' type-id='ef9025d0' visibility='default' filepath='include/linux/usb/hcd.h' line='575' column='1'/>
+          <var-decl name='clear_work' type-id='ef9025d0' visibility='default' filepath='include/linux/usb/hcd.h' line='580' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb/hcd.h' line='577' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb/hcd.h' line='582' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/usb/hcd.h' line='578' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/usb/hcd.h' line='583' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/usb/hcd.h' line='579' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/usb/hcd.h' line='584' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/usb/hcd.h' line='580' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/usb/hcd.h' line='585' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='ccc6c30b' size-in-bits='64' id='7de52cf3'/>
@@ -57303,114 +57448,114 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='c551f1b5' size-in-bits='64' id='7dfe7cd1'/>
-      <class-decl name='file_operations' size-in-bits='2304' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='1878' column='1' id='7dffcde2'>
+      <class-decl name='file_operations' size-in-bits='2304' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='1885' column='1' id='7dffcde2'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='owner' type-id='2730d015' visibility='default' filepath='include/linux/fs.h' line='1879' column='1'/>
+          <var-decl name='owner' type-id='2730d015' visibility='default' filepath='include/linux/fs.h' line='1886' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='llseek' type-id='07ebb4cd' visibility='default' filepath='include/linux/fs.h' line='1880' column='1'/>
+          <var-decl name='llseek' type-id='07ebb4cd' visibility='default' filepath='include/linux/fs.h' line='1887' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='read' type-id='4d8f5625' visibility='default' filepath='include/linux/fs.h' line='1881' column='1'/>
+          <var-decl name='read' type-id='4d8f5625' visibility='default' filepath='include/linux/fs.h' line='1888' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='write' type-id='5f29549c' visibility='default' filepath='include/linux/fs.h' line='1882' column='1'/>
+          <var-decl name='write' type-id='5f29549c' visibility='default' filepath='include/linux/fs.h' line='1889' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='read_iter' type-id='227e209d' visibility='default' filepath='include/linux/fs.h' line='1883' column='1'/>
+          <var-decl name='read_iter' type-id='227e209d' visibility='default' filepath='include/linux/fs.h' line='1890' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='write_iter' type-id='227e209d' visibility='default' filepath='include/linux/fs.h' line='1884' column='1'/>
+          <var-decl name='write_iter' type-id='227e209d' visibility='default' filepath='include/linux/fs.h' line='1891' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='iopoll' type-id='6c4618be' visibility='default' filepath='include/linux/fs.h' line='1885' column='1'/>
+          <var-decl name='iopoll' type-id='6c4618be' visibility='default' filepath='include/linux/fs.h' line='1892' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='iterate' type-id='42beb73a' visibility='default' filepath='include/linux/fs.h' line='1886' column='1'/>
+          <var-decl name='iterate' type-id='42beb73a' visibility='default' filepath='include/linux/fs.h' line='1893' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='iterate_shared' type-id='42beb73a' visibility='default' filepath='include/linux/fs.h' line='1887' column='1'/>
+          <var-decl name='iterate_shared' type-id='42beb73a' visibility='default' filepath='include/linux/fs.h' line='1894' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='poll' type-id='4d01ede7' visibility='default' filepath='include/linux/fs.h' line='1888' column='1'/>
+          <var-decl name='poll' type-id='4d01ede7' visibility='default' filepath='include/linux/fs.h' line='1895' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='unlocked_ioctl' type-id='fc7daf55' visibility='default' filepath='include/linux/fs.h' line='1889' column='1'/>
+          <var-decl name='unlocked_ioctl' type-id='fc7daf55' visibility='default' filepath='include/linux/fs.h' line='1896' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='compat_ioctl' type-id='fc7daf55' visibility='default' filepath='include/linux/fs.h' line='1890' column='1'/>
+          <var-decl name='compat_ioctl' type-id='fc7daf55' visibility='default' filepath='include/linux/fs.h' line='1897' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='mmap' type-id='8ea2626c' visibility='default' filepath='include/linux/fs.h' line='1891' column='1'/>
+          <var-decl name='mmap' type-id='8ea2626c' visibility='default' filepath='include/linux/fs.h' line='1898' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='mmap_supported_flags' type-id='7359adad' visibility='default' filepath='include/linux/fs.h' line='1892' column='1'/>
+          <var-decl name='mmap_supported_flags' type-id='7359adad' visibility='default' filepath='include/linux/fs.h' line='1899' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='open' type-id='47800058' visibility='default' filepath='include/linux/fs.h' line='1893' column='1'/>
+          <var-decl name='open' type-id='47800058' visibility='default' filepath='include/linux/fs.h' line='1900' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='flush' type-id='5ddef2dd' visibility='default' filepath='include/linux/fs.h' line='1894' column='1'/>
+          <var-decl name='flush' type-id='5ddef2dd' visibility='default' filepath='include/linux/fs.h' line='1901' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='release' type-id='47800058' visibility='default' filepath='include/linux/fs.h' line='1895' column='1'/>
+          <var-decl name='release' type-id='47800058' visibility='default' filepath='include/linux/fs.h' line='1902' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1088'>
-          <var-decl name='fsync' type-id='31cc9254' visibility='default' filepath='include/linux/fs.h' line='1896' column='1'/>
+          <var-decl name='fsync' type-id='31cc9254' visibility='default' filepath='include/linux/fs.h' line='1903' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='fasync' type-id='b94ac371' visibility='default' filepath='include/linux/fs.h' line='1897' column='1'/>
+          <var-decl name='fasync' type-id='b94ac371' visibility='default' filepath='include/linux/fs.h' line='1904' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='lock' type-id='12f0ff82' visibility='default' filepath='include/linux/fs.h' line='1898' column='1'/>
+          <var-decl name='lock' type-id='12f0ff82' visibility='default' filepath='include/linux/fs.h' line='1905' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1280'>
-          <var-decl name='sendpage' type-id='40da47a8' visibility='default' filepath='include/linux/fs.h' line='1899' column='1'/>
+          <var-decl name='sendpage' type-id='40da47a8' visibility='default' filepath='include/linux/fs.h' line='1906' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1344'>
-          <var-decl name='get_unmapped_area' type-id='d44a8cec' visibility='default' filepath='include/linux/fs.h' line='1900' column='1'/>
+          <var-decl name='get_unmapped_area' type-id='d44a8cec' visibility='default' filepath='include/linux/fs.h' line='1907' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1408'>
-          <var-decl name='check_flags' type-id='7f416e10' visibility='default' filepath='include/linux/fs.h' line='1901' column='1'/>
+          <var-decl name='check_flags' type-id='7f416e10' visibility='default' filepath='include/linux/fs.h' line='1908' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1472'>
-          <var-decl name='flock' type-id='12f0ff82' visibility='default' filepath='include/linux/fs.h' line='1902' column='1'/>
+          <var-decl name='flock' type-id='12f0ff82' visibility='default' filepath='include/linux/fs.h' line='1909' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='splice_write' type-id='b22f4610' visibility='default' filepath='include/linux/fs.h' line='1903' column='1'/>
+          <var-decl name='splice_write' type-id='b22f4610' visibility='default' filepath='include/linux/fs.h' line='1910' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1600'>
-          <var-decl name='splice_read' type-id='72cd68b0' visibility='default' filepath='include/linux/fs.h' line='1904' column='1'/>
+          <var-decl name='splice_read' type-id='72cd68b0' visibility='default' filepath='include/linux/fs.h' line='1911' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1664'>
-          <var-decl name='setlease' type-id='87e3d3e2' visibility='default' filepath='include/linux/fs.h' line='1905' column='1'/>
+          <var-decl name='setlease' type-id='87e3d3e2' visibility='default' filepath='include/linux/fs.h' line='1912' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1728'>
-          <var-decl name='fallocate' type-id='a53e2328' visibility='default' filepath='include/linux/fs.h' line='1906' column='1'/>
+          <var-decl name='fallocate' type-id='a53e2328' visibility='default' filepath='include/linux/fs.h' line='1913' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1792'>
-          <var-decl name='show_fdinfo' type-id='eda08098' visibility='default' filepath='include/linux/fs.h' line='1908' column='1'/>
+          <var-decl name='show_fdinfo' type-id='eda08098' visibility='default' filepath='include/linux/fs.h' line='1915' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1856'>
-          <var-decl name='copy_file_range' type-id='d0882d6b' visibility='default' filepath='include/linux/fs.h' line='1912' column='1'/>
+          <var-decl name='copy_file_range' type-id='d0882d6b' visibility='default' filepath='include/linux/fs.h' line='1919' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1920'>
-          <var-decl name='remap_file_range' type-id='c1de1086' visibility='default' filepath='include/linux/fs.h' line='1914' column='1'/>
+          <var-decl name='remap_file_range' type-id='c1de1086' visibility='default' filepath='include/linux/fs.h' line='1921' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1984'>
-          <var-decl name='fadvise' type-id='31cc9254' visibility='default' filepath='include/linux/fs.h' line='1917' column='1'/>
+          <var-decl name='fadvise' type-id='31cc9254' visibility='default' filepath='include/linux/fs.h' line='1924' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2048'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1919' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1926' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2112'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1920' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1927' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2176'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1921' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1928' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2240'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1922' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1929' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='7e019027'>
@@ -57437,75 +57582,75 @@
       </class-decl>
       <pointer-type-def type-id='f85fb8c6' size-in-bits='64' id='7e17c1b8'/>
       <pointer-type-def type-id='7f15b08a' size-in-bits='64' id='7e1d5dd4'/>
-      <class-decl name='tty_port' size-in-bits='3392' is-struct='yes' visibility='default' filepath='include/linux/tty.h' line='233' column='1' id='7e1e521a'>
+      <class-decl name='tty_port' size-in-bits='3392' is-struct='yes' visibility='default' filepath='include/linux/tty.h' line='209' column='1' id='7e1e521a'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='buf' type-id='6b1bde38' visibility='default' filepath='include/linux/tty.h' line='234' column='1'/>
+          <var-decl name='buf' type-id='6b1bde38' visibility='default' filepath='include/linux/tty.h' line='210' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1344'>
-          <var-decl name='tty' type-id='572fbdca' visibility='default' filepath='include/linux/tty.h' line='235' column='1'/>
+          <var-decl name='tty' type-id='572fbdca' visibility='default' filepath='include/linux/tty.h' line='211' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1408'>
-          <var-decl name='itty' type-id='572fbdca' visibility='default' filepath='include/linux/tty.h' line='236' column='1'/>
+          <var-decl name='itty' type-id='572fbdca' visibility='default' filepath='include/linux/tty.h' line='212' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1472'>
-          <var-decl name='ops' type-id='103756a0' visibility='default' filepath='include/linux/tty.h' line='237' column='1'/>
+          <var-decl name='ops' type-id='103756a0' visibility='default' filepath='include/linux/tty.h' line='213' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='client_ops' type-id='8cd9dbc0' visibility='default' filepath='include/linux/tty.h' line='238' column='1'/>
+          <var-decl name='client_ops' type-id='8cd9dbc0' visibility='default' filepath='include/linux/tty.h' line='214' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1600'>
-          <var-decl name='lock' type-id='fb4018a0' visibility='default' filepath='include/linux/tty.h' line='239' column='1'/>
+          <var-decl name='lock' type-id='fb4018a0' visibility='default' filepath='include/linux/tty.h' line='215' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1632'>
-          <var-decl name='blocked_open' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='240' column='1'/>
+          <var-decl name='blocked_open' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='216' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1664'>
-          <var-decl name='count' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='241' column='1'/>
+          <var-decl name='count' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='217' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1728'>
-          <var-decl name='open_wait' type-id='b5ab048f' visibility='default' filepath='include/linux/tty.h' line='242' column='1'/>
+          <var-decl name='open_wait' type-id='b5ab048f' visibility='default' filepath='include/linux/tty.h' line='218' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1920'>
-          <var-decl name='delta_msr_wait' type-id='b5ab048f' visibility='default' filepath='include/linux/tty.h' line='243' column='1'/>
+          <var-decl name='delta_msr_wait' type-id='b5ab048f' visibility='default' filepath='include/linux/tty.h' line='219' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2112'>
-          <var-decl name='flags' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='244' column='1'/>
+          <var-decl name='flags' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='220' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2176'>
-          <var-decl name='iflags' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='245' column='1'/>
+          <var-decl name='iflags' type-id='7359adad' visibility='default' filepath='include/linux/tty.h' line='221' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='console' type-id='002ac4a6' visibility='default' filepath='include/linux/tty.h' line='246' column='1'/>
+          <var-decl name='console' type-id='002ac4a6' visibility='default' filepath='include/linux/tty.h' line='222' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1'>
-          <var-decl name='low_latency' type-id='002ac4a6' visibility='default' filepath='include/linux/tty.h' line='247' column='1'/>
+          <var-decl name='low_latency' type-id='002ac4a6' visibility='default' filepath='include/linux/tty.h' line='223' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2304'>
-          <var-decl name='mutex' type-id='925167dc' visibility='default' filepath='include/linux/tty.h' line='248' column='1'/>
+          <var-decl name='mutex' type-id='925167dc' visibility='default' filepath='include/linux/tty.h' line='224' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2688'>
-          <var-decl name='buf_mutex' type-id='925167dc' visibility='default' filepath='include/linux/tty.h' line='249' column='1'/>
+          <var-decl name='buf_mutex' type-id='925167dc' visibility='default' filepath='include/linux/tty.h' line='225' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3072'>
-          <var-decl name='xmit_buf' type-id='cf536864' visibility='default' filepath='include/linux/tty.h' line='250' column='1'/>
+          <var-decl name='xmit_buf' type-id='cf536864' visibility='default' filepath='include/linux/tty.h' line='226' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3136'>
-          <var-decl name='close_delay' type-id='f0981eeb' visibility='default' filepath='include/linux/tty.h' line='251' column='1'/>
+          <var-decl name='close_delay' type-id='f0981eeb' visibility='default' filepath='include/linux/tty.h' line='227' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3168'>
-          <var-decl name='closing_wait' type-id='f0981eeb' visibility='default' filepath='include/linux/tty.h' line='252' column='1'/>
+          <var-decl name='closing_wait' type-id='f0981eeb' visibility='default' filepath='include/linux/tty.h' line='228' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3200'>
-          <var-decl name='drain_delay' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='253' column='1'/>
+          <var-decl name='drain_delay' type-id='95e97e5e' visibility='default' filepath='include/linux/tty.h' line='229' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3232'>
-          <var-decl name='kref' type-id='400fb07b' visibility='default' filepath='include/linux/tty.h' line='256' column='1'/>
+          <var-decl name='kref' type-id='400fb07b' visibility='default' filepath='include/linux/tty.h' line='232' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3264'>
-          <var-decl name='client_data' type-id='eaa32e2f' visibility='default' filepath='include/linux/tty.h' line='257' column='1'/>
+          <var-decl name='client_data' type-id='eaa32e2f' visibility='default' filepath='include/linux/tty.h' line='233' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3328'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/tty.h' line='259' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/tty.h' line='235' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='7e1ff049'>
@@ -58460,390 +58605,390 @@
       <pointer-type-def type-id='9ba86a44' size-in-bits='64' id='807b7702'/>
       <pointer-type-def type-id='a82c7e12' size-in-bits='64' id='807c842c'/>
       <pointer-type-def type-id='5f81edee' size-in-bits='64' id='807f0070'/>
-      <class-decl name='dwc3' size-in-bits='10432' is-struct='yes' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1108' column='1' id='80824a72'>
+      <class-decl name='dwc3' size-in-bits='10432' is-struct='yes' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1109' column='1' id='80824a72'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='drd_work' type-id='ef9025d0' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1109' column='1'/>
+          <var-decl name='drd_work' type-id='ef9025d0' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1110' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='ep0_trb' type-id='0d6a59e1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1110' column='1'/>
+          <var-decl name='ep0_trb' type-id='0d6a59e1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1111' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='bounce' type-id='eaa32e2f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1111' column='1'/>
+          <var-decl name='bounce' type-id='eaa32e2f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1112' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='scratchbuf' type-id='eaa32e2f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1112' column='1'/>
+          <var-decl name='scratchbuf' type-id='eaa32e2f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1113' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='setup_buf' type-id='8bff8096' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1113' column='1'/>
+          <var-decl name='setup_buf' type-id='8bff8096' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1114' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='ep0_trb_addr' type-id='cf29c9b3' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1114' column='1'/>
+          <var-decl name='ep0_trb_addr' type-id='cf29c9b3' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1115' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='bounce_addr' type-id='cf29c9b3' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1115' column='1'/>
+          <var-decl name='bounce_addr' type-id='cf29c9b3' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1116' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='scratch_addr' type-id='cf29c9b3' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1116' column='1'/>
+          <var-decl name='scratch_addr' type-id='cf29c9b3' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1117' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='ep0_usb_req' type-id='48288128' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1117' column='1'/>
+          <var-decl name='ep0_usb_req' type-id='48288128' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1118' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2496'>
-          <var-decl name='ep0_in_setup' type-id='f9fef04f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1118' column='1'/>
+          <var-decl name='ep0_in_setup' type-id='f9fef04f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1119' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2752'>
-          <var-decl name='lock' type-id='fb4018a0' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1121' column='1'/>
+          <var-decl name='lock' type-id='fb4018a0' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1122' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2816'>
-          <var-decl name='mutex' type-id='925167dc' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1124' column='1'/>
+          <var-decl name='mutex' type-id='925167dc' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1125' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3200'>
-          <var-decl name='dev' type-id='fa0b179b' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1126' column='1'/>
+          <var-decl name='dev' type-id='fa0b179b' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1127' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3264'>
-          <var-decl name='sysdev' type-id='fa0b179b' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1127' column='1'/>
+          <var-decl name='sysdev' type-id='fa0b179b' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1128' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3328'>
-          <var-decl name='xhci' type-id='db362995' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1129' column='1'/>
+          <var-decl name='xhci' type-id='db362995' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1130' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3392'>
-          <var-decl name='xhci_resources' type-id='05e8efcf' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1130' column='1'/>
+          <var-decl name='xhci_resources' type-id='05e8efcf' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1131' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4928'>
-          <var-decl name='ev_buf' type-id='c4c1659e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1132' column='1'/>
+          <var-decl name='ev_buf' type-id='c4c1659e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1133' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4992'>
-          <var-decl name='eps' type-id='21edd5c3' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1133' column='1'/>
+          <var-decl name='eps' type-id='21edd5c3' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1134' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7040'>
-          <var-decl name='gadget' type-id='49a58c0c' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1135' column='1'/>
+          <var-decl name='gadget' type-id='49a58c0c' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1136' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7104'>
-          <var-decl name='gadget_driver' type-id='9762ede1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1136' column='1'/>
+          <var-decl name='gadget_driver' type-id='9762ede1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1137' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7168'>
-          <var-decl name='clks' type-id='2942e355' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1138' column='1'/>
+          <var-decl name='clks' type-id='2942e355' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1139' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7232'>
-          <var-decl name='num_clks' type-id='95e97e5e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1139' column='1'/>
+          <var-decl name='num_clks' type-id='95e97e5e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1140' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7296'>
-          <var-decl name='reset' type-id='9f9b8114' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1141' column='1'/>
+          <var-decl name='reset' type-id='9f9b8114' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1142' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7360'>
-          <var-decl name='usb2_phy' type-id='ca9354d1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1143' column='1'/>
+          <var-decl name='usb2_phy' type-id='ca9354d1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1144' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7424'>
-          <var-decl name='usb3_phy' type-id='ca9354d1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1144' column='1'/>
+          <var-decl name='usb3_phy' type-id='ca9354d1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1145' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7488'>
-          <var-decl name='usb2_generic_phy' type-id='503ff1ba' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1146' column='1'/>
+          <var-decl name='usb2_generic_phy' type-id='503ff1ba' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1147' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7552'>
-          <var-decl name='usb3_generic_phy' type-id='503ff1ba' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1147' column='1'/>
+          <var-decl name='usb3_generic_phy' type-id='503ff1ba' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1148' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7616'>
-          <var-decl name='phys_ready' type-id='b50a4934' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1149' column='1'/>
+          <var-decl name='phys_ready' type-id='b50a4934' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1150' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7680'>
-          <var-decl name='ulpi' type-id='144a094f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1151' column='1'/>
+          <var-decl name='ulpi' type-id='144a094f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1152' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7744'>
-          <var-decl name='ulpi_ready' type-id='b50a4934' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1152' column='1'/>
+          <var-decl name='ulpi_ready' type-id='b50a4934' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1153' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7808'>
-          <var-decl name='regs' type-id='eaa32e2f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1154' column='1'/>
+          <var-decl name='regs' type-id='eaa32e2f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1155' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7872'>
-          <var-decl name='regs_size' type-id='b59d7dce' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1155' column='1'/>
+          <var-decl name='regs_size' type-id='b59d7dce' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1156' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7936'>
-          <var-decl name='dr_mode' type-id='d291aaf1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1157' column='1'/>
+          <var-decl name='dr_mode' type-id='d291aaf1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1158' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7968'>
-          <var-decl name='current_dr_role' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1158' column='1'/>
+          <var-decl name='current_dr_role' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1159' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8000'>
-          <var-decl name='desired_dr_role' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1159' column='1'/>
+          <var-decl name='desired_dr_role' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1160' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8064'>
-          <var-decl name='edev' type-id='c0d6fada' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1160' column='1'/>
+          <var-decl name='edev' type-id='c0d6fada' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1161' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8128'>
-          <var-decl name='edev_nb' type-id='9b08f7cd' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1161' column='1'/>
+          <var-decl name='edev_nb' type-id='9b08f7cd' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1162' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8320'>
-          <var-decl name='hsphy_mode' type-id='46b5771e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1162' column='1'/>
+          <var-decl name='hsphy_mode' type-id='46b5771e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1163' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8384'>
-          <var-decl name='role_sw' type-id='3e3cd44f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1163' column='1'/>
+          <var-decl name='role_sw' type-id='3e3cd44f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1164' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8448'>
-          <var-decl name='role_switch_default_mode' type-id='d291aaf1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1164' column='1'/>
+          <var-decl name='role_switch_default_mode' type-id='d291aaf1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1165' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8512'>
-          <var-decl name='usb_psy' type-id='c0c93c9e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1166' column='1'/>
+          <var-decl name='usb_psy' type-id='c0c93c9e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1167' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8576'>
-          <var-decl name='fladj' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1168' column='1'/>
+          <var-decl name='fladj' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1169' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8608'>
-          <var-decl name='irq_gadget' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1169' column='1'/>
+          <var-decl name='irq_gadget' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1170' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8640'>
-          <var-decl name='otg_irq' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1170' column='1'/>
+          <var-decl name='otg_irq' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1171' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8672'>
-          <var-decl name='current_otg_role' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1171' column='1'/>
+          <var-decl name='current_otg_role' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1172' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8704'>
-          <var-decl name='desired_otg_role' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1172' column='1'/>
+          <var-decl name='desired_otg_role' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1173' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8736'>
-          <var-decl name='otg_restart_host' type-id='b50a4934' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1173' column='1'/>
+          <var-decl name='otg_restart_host' type-id='b50a4934' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1174' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8768'>
-          <var-decl name='nr_scratch' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1174' column='1'/>
+          <var-decl name='nr_scratch' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1175' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8800'>
-          <var-decl name='u1u2' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1175' column='1'/>
+          <var-decl name='u1u2' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1176' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8832'>
-          <var-decl name='maximum_speed' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1176' column='1'/>
+          <var-decl name='maximum_speed' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1177' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8864'>
-          <var-decl name='gadget_max_speed' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1177' column='1'/>
+          <var-decl name='gadget_max_speed' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1178' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8896'>
-          <var-decl name='max_ssp_rate' type-id='a9ea967a' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1178' column='1'/>
+          <var-decl name='max_ssp_rate' type-id='a9ea967a' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1179' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8928'>
-          <var-decl name='gadget_ssp_rate' type-id='a9ea967a' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1179' column='1'/>
+          <var-decl name='gadget_ssp_rate' type-id='a9ea967a' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1180' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8960'>
-          <var-decl name='ip' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1181' column='1'/>
+          <var-decl name='ip' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1182' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8992'>
-          <var-decl name='revision' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1187' column='1'/>
+          <var-decl name='revision' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1188' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9024'>
-          <var-decl name='version_type' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1225' column='1'/>
+          <var-decl name='version_type' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1226' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9056'>
-          <var-decl name='ep0_next_event' type-id='56e3bcb9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1235' column='1'/>
+          <var-decl name='ep0_next_event' type-id='56e3bcb9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1236' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9088'>
-          <var-decl name='ep0state' type-id='045093ad' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1236' column='1'/>
+          <var-decl name='ep0state' type-id='045093ad' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1237' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9120'>
-          <var-decl name='link_state' type-id='9775e40e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1237' column='1'/>
+          <var-decl name='link_state' type-id='9775e40e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1238' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9152'>
-          <var-decl name='u2sel' type-id='1dc6a898' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1239' column='1'/>
+          <var-decl name='u2sel' type-id='1dc6a898' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1240' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9168'>
-          <var-decl name='u2pel' type-id='1dc6a898' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1240' column='1'/>
+          <var-decl name='u2pel' type-id='1dc6a898' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1241' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9184'>
-          <var-decl name='u1sel' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1241' column='1'/>
+          <var-decl name='u1sel' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1242' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9192'>
-          <var-decl name='u1pel' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1242' column='1'/>
+          <var-decl name='u1pel' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1243' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9200'>
-          <var-decl name='speed' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1244' column='1'/>
+          <var-decl name='speed' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1245' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9208'>
-          <var-decl name='num_eps' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1246' column='1'/>
+          <var-decl name='num_eps' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1247' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9216'>
-          <var-decl name='hwparams' type-id='2d79d174' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1248' column='1'/>
+          <var-decl name='hwparams' type-id='2d79d174' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1249' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9664'>
-          <var-decl name='root' type-id='27675065' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1249' column='1'/>
+          <var-decl name='root' type-id='27675065' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1250' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9728'>
-          <var-decl name='regset' type-id='62fa2ea7' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1250' column='1'/>
+          <var-decl name='regset' type-id='62fa2ea7' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1251' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9792'>
-          <var-decl name='dbg_lsp_select' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1252' column='1'/>
+          <var-decl name='dbg_lsp_select' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1253' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9824'>
-          <var-decl name='test_mode' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1254' column='1'/>
+          <var-decl name='test_mode' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1255' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9832'>
-          <var-decl name='test_mode_nr' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1255' column='1'/>
+          <var-decl name='test_mode_nr' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1256' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9840'>
-          <var-decl name='lpm_nyet_threshold' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1256' column='1'/>
+          <var-decl name='lpm_nyet_threshold' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1257' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9848'>
-          <var-decl name='hird_threshold' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1257' column='1'/>
+          <var-decl name='hird_threshold' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1258' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9856'>
-          <var-decl name='rx_thr_num_pkt_prd' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1258' column='1'/>
+          <var-decl name='rx_thr_num_pkt_prd' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1259' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9864'>
-          <var-decl name='rx_max_burst_prd' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1259' column='1'/>
+          <var-decl name='rx_max_burst_prd' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1260' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9872'>
-          <var-decl name='tx_thr_num_pkt_prd' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1260' column='1'/>
+          <var-decl name='tx_thr_num_pkt_prd' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1261' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9880'>
-          <var-decl name='tx_max_burst_prd' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1261' column='1'/>
+          <var-decl name='tx_max_burst_prd' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1262' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9888'>
-          <var-decl name='tx_fifo_resize_max_num' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1262' column='1'/>
+          <var-decl name='tx_fifo_resize_max_num' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1263' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9920'>
-          <var-decl name='hsphy_interface' type-id='80f4b756' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1264' column='1'/>
+          <var-decl name='hsphy_interface' type-id='80f4b756' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1265' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='connected' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1266' column='1'/>
+          <var-decl name='connected' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1267' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1'>
-          <var-decl name='delayed_status' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1267' column='1'/>
+          <var-decl name='delayed_status' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1268' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2'>
-          <var-decl name='ep0_bounced' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1268' column='1'/>
+          <var-decl name='ep0_bounced' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1269' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3'>
-          <var-decl name='ep0_expect_in' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1269' column='1'/>
+          <var-decl name='ep0_expect_in' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1270' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4'>
-          <var-decl name='has_hibernation' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1270' column='1'/>
+          <var-decl name='has_hibernation' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1271' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5'>
-          <var-decl name='sysdev_is_parent' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1271' column='1'/>
+          <var-decl name='sysdev_is_parent' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1272' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6'>
-          <var-decl name='has_lpm_erratum' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1272' column='1'/>
+          <var-decl name='has_lpm_erratum' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1273' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7'>
-          <var-decl name='is_utmi_l1_suspend' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1273' column='1'/>
+          <var-decl name='is_utmi_l1_suspend' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1274' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8'>
-          <var-decl name='is_fpga' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1274' column='1'/>
+          <var-decl name='is_fpga' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1275' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9'>
-          <var-decl name='pending_events' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1275' column='1'/>
+          <var-decl name='pending_events' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1276' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10'>
-          <var-decl name='do_fifo_resize' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1276' column='1'/>
+          <var-decl name='do_fifo_resize' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1277' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11'>
-          <var-decl name='pullups_connected' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1277' column='1'/>
+          <var-decl name='pullups_connected' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1278' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='12'>
-          <var-decl name='setup_packet_pending' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1278' column='1'/>
+          <var-decl name='setup_packet_pending' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1279' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='13'>
-          <var-decl name='three_stage_setup' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1279' column='1'/>
+          <var-decl name='three_stage_setup' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1280' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='14'>
-          <var-decl name='dis_start_transfer_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1280' column='1'/>
+          <var-decl name='dis_start_transfer_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1281' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='15'>
-          <var-decl name='usb3_lpm_capable' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1281' column='1'/>
+          <var-decl name='usb3_lpm_capable' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1282' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='16'>
-          <var-decl name='usb2_lpm_disable' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1282' column='1'/>
+          <var-decl name='usb2_lpm_disable' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1283' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='17'>
-          <var-decl name='usb2_gadget_lpm_disable' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1283' column='1'/>
+          <var-decl name='usb2_gadget_lpm_disable' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1284' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='18'>
-          <var-decl name='disable_scramble_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1285' column='1'/>
+          <var-decl name='disable_scramble_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1286' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='19'>
-          <var-decl name='u2exit_lfps_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1286' column='1'/>
+          <var-decl name='u2exit_lfps_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1287' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='20'>
-          <var-decl name='u2ss_inp3_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1287' column='1'/>
+          <var-decl name='u2ss_inp3_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1288' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='21'>
-          <var-decl name='req_p1p2p3_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1288' column='1'/>
+          <var-decl name='req_p1p2p3_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1289' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='22'>
-          <var-decl name='del_p1p2p3_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1289' column='1'/>
+          <var-decl name='del_p1p2p3_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1290' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='23'>
-          <var-decl name='del_phy_power_chg_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1290' column='1'/>
+          <var-decl name='del_phy_power_chg_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1291' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='24'>
-          <var-decl name='lfps_filter_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1291' column='1'/>
+          <var-decl name='lfps_filter_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1292' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='25'>
-          <var-decl name='rx_detect_poll_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1292' column='1'/>
+          <var-decl name='rx_detect_poll_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1293' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='26'>
-          <var-decl name='dis_u3_susphy_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1293' column='1'/>
+          <var-decl name='dis_u3_susphy_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1294' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='27'>
-          <var-decl name='dis_u2_susphy_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1294' column='1'/>
+          <var-decl name='dis_u2_susphy_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1295' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='28'>
-          <var-decl name='dis_enblslpm_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1295' column='1'/>
+          <var-decl name='dis_enblslpm_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1296' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='29'>
-          <var-decl name='dis_u1_entry_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1296' column='1'/>
+          <var-decl name='dis_u1_entry_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1297' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='30'>
-          <var-decl name='dis_u2_entry_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1297' column='1'/>
+          <var-decl name='dis_u2_entry_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1298' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='31'>
-          <var-decl name='dis_rxdet_inp3_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1298' column='1'/>
+          <var-decl name='dis_rxdet_inp3_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1299' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='dis_u2_freeclk_exists_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1299' column='1'/>
+          <var-decl name='dis_u2_freeclk_exists_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1300' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1'>
-          <var-decl name='dis_del_phy_power_chg_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1300' column='1'/>
+          <var-decl name='dis_del_phy_power_chg_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1301' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2'>
-          <var-decl name='dis_tx_ipgap_linecheck_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1301' column='1'/>
+          <var-decl name='dis_tx_ipgap_linecheck_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1302' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3'>
-          <var-decl name='parkmode_disable_ss_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1302' column='1'/>
+          <var-decl name='parkmode_disable_ss_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1303' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4'>
-          <var-decl name='tx_de_emphasis_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1304' column='1'/>
+          <var-decl name='tx_de_emphasis_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1305' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5'>
-          <var-decl name='tx_de_emphasis' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1305' column='1'/>
+          <var-decl name='tx_de_emphasis' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1306' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7'>
-          <var-decl name='dis_metastability_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1307' column='1'/>
+          <var-decl name='dis_metastability_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1308' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8'>
-          <var-decl name='dis_split_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1309' column='1'/>
+          <var-decl name='dis_split_quirk' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1310' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9'>
-          <var-decl name='async_callbacks' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1310' column='1'/>
+          <var-decl name='async_callbacks' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1311' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10032'>
-          <var-decl name='imod_interval' type-id='1dc6a898' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1312' column='1'/>
+          <var-decl name='imod_interval' type-id='1dc6a898' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1313' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10048'>
-          <var-decl name='max_cfg_eps' type-id='95e97e5e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1314' column='1'/>
+          <var-decl name='max_cfg_eps' type-id='95e97e5e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1315' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10080'>
-          <var-decl name='last_fifo_depth' type-id='95e97e5e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1315' column='1'/>
+          <var-decl name='last_fifo_depth' type-id='95e97e5e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1316' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10112'>
-          <var-decl name='num_ep_resized' type-id='95e97e5e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1316' column='1'/>
+          <var-decl name='num_ep_resized' type-id='95e97e5e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1317' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10176'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1318' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1319' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10240'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1319' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1320' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10304'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1320' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1321' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10368'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1321' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1322' column='1'/>
         </data-member>
       </class-decl>
       <enum-decl name='irqreturn' filepath='include/linux/irqreturn.h' line='11' column='1' id='8086ea38'>
@@ -58886,6 +59031,11 @@
       <function-type size-in-bits='64' id='80b3d6aa'>
         <parameter type-id='8898134d'/>
         <parameter type-id='9e99ecc1'/>
+        <return type-id='48b5725f'/>
+      </function-type>
+      <function-type size-in-bits='64' id='80b5c3cd'>
+        <parameter type-id='42c8f564'/>
+        <parameter type-id='eaa32e2f'/>
         <return type-id='48b5725f'/>
       </function-type>
       <class-decl name='nf_conntrack_tuple_hash' size-in-bits='448' is-struct='yes' visibility='default' filepath='include/net/netfilter/nf_conntrack_tuple.h' line='119' column='1' id='80b664d7'>
@@ -59017,15 +59167,15 @@
         <enumerator name='UFS_PM_LVL_5' value='5'/>
         <enumerator name='UFS_PM_LVL_MAX' value='6'/>
       </enum-decl>
-      <union-decl name='__anonymous_union__' size-in-bits='192' is-anonymous='yes' visibility='default' filepath='include/linux/netdevice.h' line='929' column='1' id='814b2a03'>
+      <union-decl name='__anonymous_union__' size-in-bits='192' is-anonymous='yes' visibility='default' filepath='include/linux/netdevice.h' line='934' column='1' id='814b2a03'>
         <data-member access='public'>
-          <var-decl name='' type-id='33bba89f' visibility='default' filepath='include/linux/netdevice.h' line='931' column='1'/>
+          <var-decl name='' type-id='33bba89f' visibility='default' filepath='include/linux/netdevice.h' line='936' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='' type-id='f7a2361f' visibility='default' filepath='include/linux/netdevice.h' line='937' column='1'/>
+          <var-decl name='' type-id='f7a2361f' visibility='default' filepath='include/linux/netdevice.h' line='942' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='xsk' type-id='ed254a3d' visibility='default' filepath='include/linux/netdevice.h' line='944' column='1'/>
+          <var-decl name='xsk' type-id='ed254a3d' visibility='default' filepath='include/linux/netdevice.h' line='949' column='1'/>
         </data-member>
       </union-decl>
       <typedef-decl name='__sigrestore_t' type-id='5d3a884e' filepath='include/uapi/asm-generic/signal-defs.h' line='85' column='1' id='81564178'/>
@@ -59392,36 +59542,36 @@
       <pointer-type-def type-id='1e0c0ad9' size-in-bits='64' id='825b5cd1'/>
       <pointer-type-def type-id='09f0c826' size-in-bits='64' id='825ef190'/>
       <typedef-decl name='dma_async_tx_callback_result' type-id='31316b61' filepath='include/linux/dmaengine.h' line='551' column='1' id='82615040'/>
-      <class-decl name='xhci_driver_overrides' size-in-bits='640' is-struct='yes' visibility='default' filepath='drivers/usb/host/xhci.h' line='1952' column='1' id='8264b0e6'>
+      <class-decl name='xhci_driver_overrides' size-in-bits='640' is-struct='yes' visibility='default' filepath='drivers/usb/host/xhci.h' line='1954' column='1' id='8264b0e6'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='extra_priv_size' type-id='b59d7dce' visibility='default' filepath='drivers/usb/host/xhci.h' line='1953' column='1'/>
+          <var-decl name='extra_priv_size' type-id='b59d7dce' visibility='default' filepath='drivers/usb/host/xhci.h' line='1955' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='reset' type-id='3d4f6569' visibility='default' filepath='drivers/usb/host/xhci.h' line='1954' column='1'/>
+          <var-decl name='reset' type-id='3d4f6569' visibility='default' filepath='drivers/usb/host/xhci.h' line='1956' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='start' type-id='3d4f6569' visibility='default' filepath='drivers/usb/host/xhci.h' line='1955' column='1'/>
+          <var-decl name='start' type-id='3d4f6569' visibility='default' filepath='drivers/usb/host/xhci.h' line='1957' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='add_endpoint' type-id='2c3372f7' visibility='default' filepath='drivers/usb/host/xhci.h' line='1956' column='1'/>
+          <var-decl name='add_endpoint' type-id='2c3372f7' visibility='default' filepath='drivers/usb/host/xhci.h' line='1958' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='drop_endpoint' type-id='2c3372f7' visibility='default' filepath='drivers/usb/host/xhci.h' line='1958' column='1'/>
+          <var-decl name='drop_endpoint' type-id='2c3372f7' visibility='default' filepath='drivers/usb/host/xhci.h' line='1960' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='check_bandwidth' type-id='530cb308' visibility='default' filepath='drivers/usb/host/xhci.h' line='1960' column='1'/>
+          <var-decl name='check_bandwidth' type-id='530cb308' visibility='default' filepath='drivers/usb/host/xhci.h' line='1962' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='reset_bandwidth' type-id='b48dadb7' visibility='default' filepath='drivers/usb/host/xhci.h' line='1961' column='1'/>
+          <var-decl name='reset_bandwidth' type-id='b48dadb7' visibility='default' filepath='drivers/usb/host/xhci.h' line='1963' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='address_device' type-id='530cb308' visibility='default' filepath='drivers/usb/host/xhci.h' line='1962' column='1'/>
+          <var-decl name='address_device' type-id='530cb308' visibility='default' filepath='drivers/usb/host/xhci.h' line='1964' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='bus_suspend' type-id='3d4f6569' visibility='default' filepath='drivers/usb/host/xhci.h' line='1963' column='1'/>
+          <var-decl name='bus_suspend' type-id='3d4f6569' visibility='default' filepath='drivers/usb/host/xhci.h' line='1965' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='bus_resume' type-id='3d4f6569' visibility='default' filepath='drivers/usb/host/xhci.h' line='1964' column='1'/>
+          <var-decl name='bus_resume' type-id='3d4f6569' visibility='default' filepath='drivers/usb/host/xhci.h' line='1966' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='99f32926' size-in-bits='64' id='82683cec'/>
@@ -61250,12 +61400,12 @@
         <parameter type-id='f0981eeb'/>
         <return type-id='95e97e5e'/>
       </function-type>
-      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/uapi/linux/ip.h' line='104' column='1' id='86910b4e'>
+      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/uapi/linux/ip.h' line='105' column='1' id='86910b4e'>
         <data-member access='public'>
-          <var-decl name='' type-id='d1615c58' visibility='default' filepath='include/uapi/linux/ip.h' line='104' column='1'/>
+          <var-decl name='' type-id='d1615c58' visibility='default' filepath='include/uapi/linux/ip.h' line='105' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='addrs' type-id='d1615c58' visibility='default' filepath='include/uapi/linux/ip.h' line='104' column='1'/>
+          <var-decl name='addrs' type-id='d1615c58' visibility='default' filepath='include/uapi/linux/ip.h' line='105' column='1'/>
         </data-member>
       </union-decl>
       <function-type size-in-bits='64' id='86933835'>
@@ -61482,96 +61632,96 @@
         <parameter type-id='231422bf'/>
         <return type-id='95e97e5e'/>
       </function-type>
-      <class-decl name='super_operations' size-in-bits='1920' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='2001' column='1' id='874691ab'>
+      <class-decl name='super_operations' size-in-bits='1920' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='2008' column='1' id='874691ab'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='alloc_inode' type-id='e8c4dba4' visibility='default' filepath='include/linux/fs.h' line='2002' column='1'/>
+          <var-decl name='alloc_inode' type-id='e8c4dba4' visibility='default' filepath='include/linux/fs.h' line='2009' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='destroy_inode' type-id='4f3d95df' visibility='default' filepath='include/linux/fs.h' line='2003' column='1'/>
+          <var-decl name='destroy_inode' type-id='4f3d95df' visibility='default' filepath='include/linux/fs.h' line='2010' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='free_inode' type-id='4f3d95df' visibility='default' filepath='include/linux/fs.h' line='2004' column='1'/>
+          <var-decl name='free_inode' type-id='4f3d95df' visibility='default' filepath='include/linux/fs.h' line='2011' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='dirty_inode' type-id='5f5506f6' visibility='default' filepath='include/linux/fs.h' line='2006' column='1'/>
+          <var-decl name='dirty_inode' type-id='5f5506f6' visibility='default' filepath='include/linux/fs.h' line='2013' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='write_inode' type-id='fd780be6' visibility='default' filepath='include/linux/fs.h' line='2007' column='1'/>
+          <var-decl name='write_inode' type-id='fd780be6' visibility='default' filepath='include/linux/fs.h' line='2014' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='drop_inode' type-id='28ba4492' visibility='default' filepath='include/linux/fs.h' line='2008' column='1'/>
+          <var-decl name='drop_inode' type-id='28ba4492' visibility='default' filepath='include/linux/fs.h' line='2015' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='evict_inode' type-id='4f3d95df' visibility='default' filepath='include/linux/fs.h' line='2009' column='1'/>
+          <var-decl name='evict_inode' type-id='4f3d95df' visibility='default' filepath='include/linux/fs.h' line='2016' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='put_super' type-id='1ff54a45' visibility='default' filepath='include/linux/fs.h' line='2010' column='1'/>
+          <var-decl name='put_super' type-id='1ff54a45' visibility='default' filepath='include/linux/fs.h' line='2017' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='sync_fs' type-id='dcab5203' visibility='default' filepath='include/linux/fs.h' line='2011' column='1'/>
+          <var-decl name='sync_fs' type-id='dcab5203' visibility='default' filepath='include/linux/fs.h' line='2018' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='freeze_super' type-id='d2f4c704' visibility='default' filepath='include/linux/fs.h' line='2012' column='1'/>
+          <var-decl name='freeze_super' type-id='d2f4c704' visibility='default' filepath='include/linux/fs.h' line='2019' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='freeze_fs' type-id='d2f4c704' visibility='default' filepath='include/linux/fs.h' line='2013' column='1'/>
+          <var-decl name='freeze_fs' type-id='d2f4c704' visibility='default' filepath='include/linux/fs.h' line='2020' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='thaw_super' type-id='d2f4c704' visibility='default' filepath='include/linux/fs.h' line='2014' column='1'/>
+          <var-decl name='thaw_super' type-id='d2f4c704' visibility='default' filepath='include/linux/fs.h' line='2021' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='unfreeze_fs' type-id='d2f4c704' visibility='default' filepath='include/linux/fs.h' line='2015' column='1'/>
+          <var-decl name='unfreeze_fs' type-id='d2f4c704' visibility='default' filepath='include/linux/fs.h' line='2022' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='statfs' type-id='35646c79' visibility='default' filepath='include/linux/fs.h' line='2016' column='1'/>
+          <var-decl name='statfs' type-id='35646c79' visibility='default' filepath='include/linux/fs.h' line='2023' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='remount_fs' type-id='552c8f87' visibility='default' filepath='include/linux/fs.h' line='2017' column='1'/>
+          <var-decl name='remount_fs' type-id='552c8f87' visibility='default' filepath='include/linux/fs.h' line='2024' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='umount_begin' type-id='1ff54a45' visibility='default' filepath='include/linux/fs.h' line='2018' column='1'/>
+          <var-decl name='umount_begin' type-id='1ff54a45' visibility='default' filepath='include/linux/fs.h' line='2025' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='show_options' type-id='c94f6b13' visibility='default' filepath='include/linux/fs.h' line='2020' column='1'/>
+          <var-decl name='show_options' type-id='c94f6b13' visibility='default' filepath='include/linux/fs.h' line='2027' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1088'>
-          <var-decl name='show_devname' type-id='c94f6b13' visibility='default' filepath='include/linux/fs.h' line='2021' column='1'/>
+          <var-decl name='show_devname' type-id='c94f6b13' visibility='default' filepath='include/linux/fs.h' line='2028' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='show_path' type-id='c94f6b13' visibility='default' filepath='include/linux/fs.h' line='2022' column='1'/>
+          <var-decl name='show_path' type-id='c94f6b13' visibility='default' filepath='include/linux/fs.h' line='2029' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='show_stats' type-id='c94f6b13' visibility='default' filepath='include/linux/fs.h' line='2023' column='1'/>
+          <var-decl name='show_stats' type-id='c94f6b13' visibility='default' filepath='include/linux/fs.h' line='2030' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1280'>
-          <var-decl name='quota_read' type-id='e295c77c' visibility='default' filepath='include/linux/fs.h' line='2025' column='1'/>
+          <var-decl name='quota_read' type-id='e295c77c' visibility='default' filepath='include/linux/fs.h' line='2032' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1344'>
-          <var-decl name='quota_write' type-id='a9b95107' visibility='default' filepath='include/linux/fs.h' line='2026' column='1'/>
+          <var-decl name='quota_write' type-id='a9b95107' visibility='default' filepath='include/linux/fs.h' line='2033' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1408'>
-          <var-decl name='get_dquots' type-id='ae02292a' visibility='default' filepath='include/linux/fs.h' line='2027' column='1'/>
+          <var-decl name='get_dquots' type-id='ae02292a' visibility='default' filepath='include/linux/fs.h' line='2034' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1472'>
-          <var-decl name='bdev_try_to_free_page' type-id='ea44f8d2' visibility='default' filepath='include/linux/fs.h' line='2029' column='1'/>
+          <var-decl name='bdev_try_to_free_page' type-id='ea44f8d2' visibility='default' filepath='include/linux/fs.h' line='2036' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='nr_cached_objects' type-id='c4facf61' visibility='default' filepath='include/linux/fs.h' line='2030' column='1'/>
+          <var-decl name='nr_cached_objects' type-id='c4facf61' visibility='default' filepath='include/linux/fs.h' line='2037' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1600'>
-          <var-decl name='free_cached_objects' type-id='c4facf61' visibility='default' filepath='include/linux/fs.h' line='2032' column='1'/>
+          <var-decl name='free_cached_objects' type-id='c4facf61' visibility='default' filepath='include/linux/fs.h' line='2039' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1664'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2035' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2042' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1728'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2036' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2043' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1792'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2037' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2044' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1856'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2038' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='2045' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='drm_agp_head' is-struct='yes' visibility='default' is-declaration-only='yes' id='874fb8c0'/>
@@ -61625,7 +61775,7 @@
           <var-decl name='size' type-id='acc63fdf' visibility='default' filepath='include/linux/fb.h' line='499' column='1'/>
         </data-member>
       </class-decl>
-      <enum-decl name='schedutil_type' filepath='kernel/sched/sched.h' line='2594' column='1' id='8769acd0'>
+      <enum-decl name='schedutil_type' filepath='kernel/sched/sched.h' line='2639' column='1' id='8769acd0'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='FREQUENCY_UTIL' value='0'/>
         <enumerator name='ENERGY_UTIL' value='1'/>
@@ -62402,15 +62552,15 @@
         <return type-id='48b5725f'/>
       </function-type>
       <typedef-decl name='u_int8_t' type-id='f9b06939' filepath='include/linux/types.h' line='93' column='1' id='892641a4'/>
-      <class-decl name='net_proto_family' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/net.h' line='217' column='1' id='89303496'>
+      <class-decl name='net_proto_family' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/net.h' line='216' column='1' id='89303496'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='family' type-id='95e97e5e' visibility='default' filepath='include/linux/net.h' line='218' column='1'/>
+          <var-decl name='family' type-id='95e97e5e' visibility='default' filepath='include/linux/net.h' line='217' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='create' type-id='d128cc8f' visibility='default' filepath='include/linux/net.h' line='219' column='1'/>
+          <var-decl name='create' type-id='d128cc8f' visibility='default' filepath='include/linux/net.h' line='218' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='owner' type-id='2730d015' visibility='default' filepath='include/linux/net.h' line='221' column='1'/>
+          <var-decl name='owner' type-id='2730d015' visibility='default' filepath='include/linux/net.h' line='220' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='802097e5' size-in-bits='64' id='8930de61'/>
@@ -62588,7 +62738,7 @@
       </class-decl>
       <pointer-type-def type-id='dbf3947c' size-in-bits='64' id='89a2612a'/>
       <pointer-type-def type-id='bf77b476' size-in-bits='64' id='89a8217c'/>
-      <enum-decl name='typec_port_data' filepath='include/linux/usb/typec.h' line='31' column='1' id='89aae82e'>
+      <enum-decl name='typec_port_data' filepath='include/linux/usb/typec.h' line='32' column='1' id='89aae82e'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='TYPEC_PORT_DFP' value='0'/>
         <enumerator name='TYPEC_PORT_UFP' value='1'/>
@@ -62844,7 +62994,6 @@
           <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/sound/core.h' line='66' column='1'/>
         </data-member>
       </class-decl>
-      <pointer-type-def type-id='50ac43c8' size-in-bits='64' id='8a1be3fe'/>
       <function-type size-in-bits='64' id='8a1ce1f9'>
         <parameter type-id='10216dc5'/>
         <parameter type-id='f0981eeb'/>
@@ -63076,21 +63225,21 @@
           <var-decl name='_pkey' type-id='3f1a6b60' visibility='default' filepath='include/uapi/asm-generic/siginfo.h' line='92' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='tcp_fastopen_request' size-in-bits='448' is-struct='yes' visibility='default' filepath='include/net/tcp.h' line='1674' column='1' id='8a4245ed'>
+      <class-decl name='tcp_fastopen_request' size-in-bits='448' is-struct='yes' visibility='default' filepath='include/net/tcp.h' line='1688' column='1' id='8a4245ed'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='cookie' type-id='98fc5aa2' visibility='default' filepath='include/net/tcp.h' line='1676' column='1'/>
+          <var-decl name='cookie' type-id='98fc5aa2' visibility='default' filepath='include/net/tcp.h' line='1690' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='data' type-id='6b9b777a' visibility='default' filepath='include/net/tcp.h' line='1677' column='1'/>
+          <var-decl name='data' type-id='6b9b777a' visibility='default' filepath='include/net/tcp.h' line='1691' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='size' type-id='b59d7dce' visibility='default' filepath='include/net/tcp.h' line='1678' column='1'/>
+          <var-decl name='size' type-id='b59d7dce' visibility='default' filepath='include/net/tcp.h' line='1692' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='copied' type-id='95e97e5e' visibility='default' filepath='include/net/tcp.h' line='1679' column='1'/>
+          <var-decl name='copied' type-id='95e97e5e' visibility='default' filepath='include/net/tcp.h' line='1693' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='uarg' type-id='73789784' visibility='default' filepath='include/net/tcp.h' line='1680' column='1'/>
+          <var-decl name='uarg' type-id='73789784' visibility='default' filepath='include/net/tcp.h' line='1694' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='snd_soc_tplg_vendor_array' size-in-bits='96' is-struct='yes' visibility='default' filepath='include/uapi/sound/asoc.h' line='218' column='1' id='8a4504f5'>
@@ -63603,18 +63752,18 @@
         <parameter type-id='8212a608'/>
         <return type-id='95e97e5e'/>
       </function-type>
-      <class-decl name='socket_wq' size-in-bits='512' is-struct='yes' visibility='default' filepath='include/linux/net.h' line='99' column='1' id='8bd06fd9'>
+      <class-decl name='socket_wq' size-in-bits='512' is-struct='yes' visibility='default' filepath='include/linux/net.h' line='97' column='1' id='8bd06fd9'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='wait' type-id='b5ab048f' visibility='default' filepath='include/linux/net.h' line='101' column='1'/>
+          <var-decl name='wait' type-id='b5ab048f' visibility='default' filepath='include/linux/net.h' line='99' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='fasync_list' type-id='5bb9c75d' visibility='default' filepath='include/linux/net.h' line='102' column='1'/>
+          <var-decl name='fasync_list' type-id='5bb9c75d' visibility='default' filepath='include/linux/net.h' line='100' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='flags' type-id='7359adad' visibility='default' filepath='include/linux/net.h' line='103' column='1'/>
+          <var-decl name='flags' type-id='7359adad' visibility='default' filepath='include/linux/net.h' line='101' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/net.h' line='104' column='1'/>
+          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/net.h' line='102' column='1'/>
         </data-member>
       </class-decl>
       <qualified-type-def type-id='a3e4c395' const='yes' id='8bd3aaa6'/>
@@ -63742,12 +63891,12 @@
         </data-member>
       </class-decl>
       <qualified-type-def type-id='af73fe5b' const='yes' id='8c2c98d8'/>
-      <union-decl name='__anonymous_union__' size-in-bits='32' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='884' column='1' id='8c3ee840'>
+      <union-decl name='__anonymous_union__' size-in-bits='32' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='886' column='1' id='8c3ee840'>
         <data-member access='public'>
-          <var-decl name='napi_id' type-id='f0981eeb' visibility='default' filepath='include/linux/skbuff.h' line='885' column='1'/>
+          <var-decl name='napi_id' type-id='f0981eeb' visibility='default' filepath='include/linux/skbuff.h' line='887' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='sender_cpu' type-id='f0981eeb' visibility='default' filepath='include/linux/skbuff.h' line='886' column='1'/>
+          <var-decl name='sender_cpu' type-id='f0981eeb' visibility='default' filepath='include/linux/skbuff.h' line='888' column='1'/>
         </data-member>
       </union-decl>
       <pointer-type-def type-id='a0776e3c' size-in-bits='64' id='8c46546a'/>
@@ -64061,7 +64210,7 @@
           <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/kobject.h' line='212' column='1'/>
         </data-member>
       </class-decl>
-      <typedef-decl name='proc_handler' type-id='99803d40' filepath='include/linux/sysctl.h' line='47' column='1' id='8cf4128f'/>
+      <typedef-decl name='proc_handler' type-id='99803d40' filepath='include/linux/sysctl.h' line='55' column='1' id='8cf4128f'/>
       <function-type size-in-bits='64' id='8cfd5cb8'>
         <parameter type-id='352b95f6'/>
         <parameter type-id='95e97e5e'/>
@@ -64254,6 +64403,7 @@
       </array-type-def>
       <pointer-type-def type-id='baf016ef' size-in-bits='64' id='8d4ac8c3'/>
       <pointer-type-def type-id='a6f56593' size-in-bits='64' id='8d4f223b'/>
+      <pointer-type-def type-id='459f31a7' size-in-bits='64' id='8d55c7ff'/>
       <function-type size-in-bits='64' id='8d57fbd1'>
         <parameter type-id='dd575c43'/>
         <return type-id='95e97e5e'/>
@@ -66433,7 +66583,7 @@
           <var-decl name='data' type-id='bcad3902' visibility='default' filepath='include/uapi/linux/android/binder.h' line='357' column='1'/>
         </data-member>
       </class-decl>
-      <typedef-decl name='rx_handler_func_t' type-id='77c9a241' filepath='include/linux/netdevice.h' line='439' column='1' id='9193647b'/>
+      <typedef-decl name='rx_handler_func_t' type-id='77c9a241' filepath='include/linux/netdevice.h' line='441' column='1' id='9193647b'/>
       <pointer-type-def type-id='db4c9bf7' size-in-bits='64' id='9194e9f3'/>
       <array-type-def dimensions='1' type-id='a9d5f761' size-in-bits='infinite' id='9195bab1'>
         <subrange length='infinite' type-id='7ff19f0f' id='031f2035'/>
@@ -66445,33 +66595,33 @@
       </function-type>
       <pointer-type-def type-id='dc2316e7' size-in-bits='64' id='919b335b'/>
       <pointer-type-def type-id='138d3c05' size-in-bits='64' id='919f23a5'/>
-      <class-decl name='ctl_table' size-in-bits='512' is-struct='yes' visibility='default' filepath='include/linux/sysctl.h' line='112' column='1' id='91a515f9'>
+      <class-decl name='ctl_table' size-in-bits='512' is-struct='yes' visibility='default' filepath='include/linux/sysctl.h' line='122' column='1' id='91a515f9'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='procname' type-id='80f4b756' visibility='default' filepath='include/linux/sysctl.h' line='113' column='1'/>
+          <var-decl name='procname' type-id='80f4b756' visibility='default' filepath='include/linux/sysctl.h' line='123' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='data' type-id='eaa32e2f' visibility='default' filepath='include/linux/sysctl.h' line='114' column='1'/>
+          <var-decl name='data' type-id='eaa32e2f' visibility='default' filepath='include/linux/sysctl.h' line='124' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='maxlen' type-id='95e97e5e' visibility='default' filepath='include/linux/sysctl.h' line='115' column='1'/>
+          <var-decl name='maxlen' type-id='95e97e5e' visibility='default' filepath='include/linux/sysctl.h' line='125' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='160'>
-          <var-decl name='mode' type-id='2594b00f' visibility='default' filepath='include/linux/sysctl.h' line='116' column='1'/>
+          <var-decl name='mode' type-id='2594b00f' visibility='default' filepath='include/linux/sysctl.h' line='126' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='child' type-id='631dc3c1' visibility='default' filepath='include/linux/sysctl.h' line='117' column='1'/>
+          <var-decl name='child' type-id='631dc3c1' visibility='default' filepath='include/linux/sysctl.h' line='127' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='proc_handler' type-id='66032958' visibility='default' filepath='include/linux/sysctl.h' line='118' column='1'/>
+          <var-decl name='proc_handler' type-id='66032958' visibility='default' filepath='include/linux/sysctl.h' line='128' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='poll' type-id='4dec003b' visibility='default' filepath='include/linux/sysctl.h' line='119' column='1'/>
+          <var-decl name='poll' type-id='4dec003b' visibility='default' filepath='include/linux/sysctl.h' line='129' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='extra1' type-id='eaa32e2f' visibility='default' filepath='include/linux/sysctl.h' line='120' column='1'/>
+          <var-decl name='extra1' type-id='eaa32e2f' visibility='default' filepath='include/linux/sysctl.h' line='130' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='extra2' type-id='eaa32e2f' visibility='default' filepath='include/linux/sysctl.h' line='121' column='1'/>
+          <var-decl name='extra2' type-id='eaa32e2f' visibility='default' filepath='include/linux/sysctl.h' line='131' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='91b0693b'>
@@ -66482,24 +66632,17 @@
         <return type-id='95e97e5e'/>
       </function-type>
       <pointer-type-def type-id='7dac1e36' size-in-bits='64' id='91b10e59'/>
-      <class-decl name='in6_pktinfo' size-in-bits='160' is-struct='yes' visibility='default' filepath='include/uapi/linux/ipv6.h' line='21' column='1' id='91b426fc'>
+      <class-decl name='in6_pktinfo' size-in-bits='160' is-struct='yes' visibility='default' filepath='include/uapi/linux/ipv6.h' line='22' column='1' id='91b426fc'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='ipi6_addr' type-id='f6ed712a' visibility='default' filepath='include/uapi/linux/ipv6.h' line='22' column='1'/>
+          <var-decl name='ipi6_addr' type-id='f6ed712a' visibility='default' filepath='include/uapi/linux/ipv6.h' line='23' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='ipi6_ifindex' type-id='95e97e5e' visibility='default' filepath='include/uapi/linux/ipv6.h' line='23' column='1'/>
+          <var-decl name='ipi6_ifindex' type-id='95e97e5e' visibility='default' filepath='include/uapi/linux/ipv6.h' line='24' column='1'/>
         </data-member>
       </class-decl>
       <typedef-decl name='u64' type-id='d3130597' filepath='include/asm-generic/int-ll64.h' line='23' column='1' id='91ce1af9'/>
       <pointer-type-def type-id='d7c60ba9' size-in-bits='64' id='91d0de51'/>
       <pointer-type-def type-id='d0fea0bb' size-in-bits='64' id='91d6c443'/>
-      <function-type size-in-bits='64' id='91dc7ea3'>
-        <parameter type-id='7e666abe'/>
-        <parameter type-id='eaa32e2f'/>
-        <parameter type-id='91ce1af9'/>
-        <parameter type-id='95e97e5e'/>
-        <return type-id='95e97e5e'/>
-      </function-type>
       <function-type size-in-bits='64' id='91de15a8'>
         <parameter type-id='7e666abe'/>
         <parameter type-id='cd1b45ab'/>
@@ -67768,39 +67911,39 @@
         <return type-id='48b5725f'/>
       </function-type>
       <pointer-type-def type-id='37688d8e' size-in-bits='64' id='950eceb8'/>
-      <class-decl name='snd_soc_dapm_context' size-in-bits='640' is-struct='yes' visibility='default' filepath='include/sound/soc-dapm.h' line='687' column='1' id='95201ae5'>
+      <class-decl name='snd_soc_dapm_context' size-in-bits='640' is-struct='yes' visibility='default' filepath='include/sound/soc-dapm.h' line='688' column='1' id='95201ae5'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='bias_level' type-id='f078c744' visibility='default' filepath='include/sound/soc-dapm.h' line='688' column='1'/>
+          <var-decl name='bias_level' type-id='f078c744' visibility='default' filepath='include/sound/soc-dapm.h' line='689' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='idle_bias_off' type-id='f0981eeb' visibility='default' filepath='include/sound/soc-dapm.h' line='689' column='1'/>
+          <var-decl name='idle_bias_off' type-id='f0981eeb' visibility='default' filepath='include/sound/soc-dapm.h' line='690' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1'>
-          <var-decl name='suspend_bias_off' type-id='f0981eeb' visibility='default' filepath='include/sound/soc-dapm.h' line='691' column='1'/>
+          <var-decl name='suspend_bias_off' type-id='f0981eeb' visibility='default' filepath='include/sound/soc-dapm.h' line='692' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='dev' type-id='fa0b179b' visibility='default' filepath='include/sound/soc-dapm.h' line='693' column='1'/>
+          <var-decl name='dev' type-id='fa0b179b' visibility='default' filepath='include/sound/soc-dapm.h' line='694' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='component' type-id='807b7702' visibility='default' filepath='include/sound/soc-dapm.h' line='694' column='1'/>
+          <var-decl name='component' type-id='807b7702' visibility='default' filepath='include/sound/soc-dapm.h' line='695' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='card' type-id='3059cd0b' visibility='default' filepath='include/sound/soc-dapm.h' line='695' column='1'/>
+          <var-decl name='card' type-id='3059cd0b' visibility='default' filepath='include/sound/soc-dapm.h' line='696' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='target_bias_level' type-id='f078c744' visibility='default' filepath='include/sound/soc-dapm.h' line='698' column='1'/>
+          <var-decl name='target_bias_level' type-id='f078c744' visibility='default' filepath='include/sound/soc-dapm.h' line='699' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/sound/soc-dapm.h' line='699' column='1'/>
+          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/sound/soc-dapm.h' line='700' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='path_sink_cache' type-id='27dc472b' visibility='default' filepath='include/sound/soc-dapm.h' line='701' column='1'/>
+          <var-decl name='path_sink_cache' type-id='27dc472b' visibility='default' filepath='include/sound/soc-dapm.h' line='702' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='path_source_cache' type-id='27dc472b' visibility='default' filepath='include/sound/soc-dapm.h' line='702' column='1'/>
+          <var-decl name='path_source_cache' type-id='27dc472b' visibility='default' filepath='include/sound/soc-dapm.h' line='703' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='debugfs_dapm' type-id='27675065' visibility='default' filepath='include/sound/soc-dapm.h' line='705' column='1'/>
+          <var-decl name='debugfs_dapm' type-id='27675065' visibility='default' filepath='include/sound/soc-dapm.h' line='706' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='ca0a6184' size-in-bits='64' id='95208a5e'/>
@@ -68169,18 +68312,18 @@
       <pointer-type-def type-id='9f5a4f22' size-in-bits='64' id='9682fd8c'/>
       <pointer-type-def type-id='699ab992' size-in-bits='64' id='96846df4'/>
       <pointer-type-def type-id='56e9279b' size-in-bits='64' id='9689f21b'/>
-      <class-decl name='typec_altmode_desc' size-in-bits='96' is-struct='yes' visibility='default' filepath='include/linux/usb/typec.h' line='122' column='1' id='968d5b5b'>
+      <class-decl name='typec_altmode_desc' size-in-bits='96' is-struct='yes' visibility='default' filepath='include/linux/usb/typec.h' line='123' column='1' id='968d5b5b'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='svid' type-id='1dc6a898' visibility='default' filepath='include/linux/usb/typec.h' line='123' column='1'/>
+          <var-decl name='svid' type-id='1dc6a898' visibility='default' filepath='include/linux/usb/typec.h' line='124' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='16'>
-          <var-decl name='mode' type-id='f9b06939' visibility='default' filepath='include/linux/usb/typec.h' line='124' column='1'/>
+          <var-decl name='mode' type-id='f9b06939' visibility='default' filepath='include/linux/usb/typec.h' line='125' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='vdo' type-id='19c2251e' visibility='default' filepath='include/linux/usb/typec.h' line='125' column='1'/>
+          <var-decl name='vdo' type-id='19c2251e' visibility='default' filepath='include/linux/usb/typec.h' line='126' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='roles' type-id='89aae82e' visibility='default' filepath='include/linux/usb/typec.h' line='127' column='1'/>
+          <var-decl name='roles' type-id='89aae82e' visibility='default' filepath='include/linux/usb/typec.h' line='128' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='f3cb01e4' size-in-bits='64' id='9693d74a'/>
@@ -68465,7 +68608,7 @@
         <return type-id='f9f4b16f'/>
       </function-type>
       <pointer-type-def type-id='b718d3f9' size-in-bits='64' id='9762ede1'/>
-      <enum-decl name='dwc3_link_state' filepath='drivers/usb/dwc3/core.h' line='788' column='1' id='9775e40e'>
+      <enum-decl name='dwc3_link_state' filepath='drivers/usb/dwc3/core.h' line='789' column='1' id='9775e40e'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='DWC3_LINK_STATE_U0' value='0'/>
         <enumerator name='DWC3_LINK_STATE_U1' value='1'/>
@@ -69809,7 +69952,20 @@
           <var-decl name='private_value' type-id='7359adad' visibility='default' filepath='include/sound/control.h' line='56' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='udp_table' is-struct='yes' visibility='default' is-declaration-only='yes' id='9a516b13'/>
+      <class-decl name='udp_table' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/net/udp.h' line='72' column='1' id='9a516b13'>
+        <data-member access='public' layout-offset-in-bits='0'>
+          <var-decl name='hash' type-id='9cc41107' visibility='default' filepath='include/net/udp.h' line='73' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='64'>
+          <var-decl name='hash2' type-id='9cc41107' visibility='default' filepath='include/net/udp.h' line='74' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='128'>
+          <var-decl name='mask' type-id='f0981eeb' visibility='default' filepath='include/net/udp.h' line='75' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='160'>
+          <var-decl name='log' type-id='f0981eeb' visibility='default' filepath='include/net/udp.h' line='76' column='1'/>
+        </data-member>
+      </class-decl>
       <pointer-type-def type-id='6661a698' size-in-bits='64' id='9a537bbe'/>
       <pointer-type-def type-id='2bc6669b' size-in-bits='64' id='9a53a8a3'/>
       <function-type size-in-bits='64' id='9a54e634'>
@@ -70085,18 +70241,18 @@
       <pointer-type-def type-id='26a90f95' size-in-bits='64' id='9b23c9ad'/>
       <pointer-type-def type-id='71598d38' size-in-bits='64' id='9b25216e'/>
       <class-decl name='fib6_result' is-struct='yes' visibility='default' is-declaration-only='yes' id='9b266dc4'/>
-      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/uio.h' line='38' column='1' id='9b26deed'>
+      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/uio.h' line='44' column='1' id='9b26deed'>
         <data-member access='public'>
-          <var-decl name='iov' type-id='2c556848' visibility='default' filepath='include/linux/uio.h' line='39' column='1'/>
+          <var-decl name='iov' type-id='2c556848' visibility='default' filepath='include/linux/uio.h' line='45' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='kvec' type-id='5199c30d' visibility='default' filepath='include/linux/uio.h' line='40' column='1'/>
+          <var-decl name='kvec' type-id='5199c30d' visibility='default' filepath='include/linux/uio.h' line='46' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='bvec' type-id='15c9a01b' visibility='default' filepath='include/linux/uio.h' line='41' column='1'/>
+          <var-decl name='bvec' type-id='15c9a01b' visibility='default' filepath='include/linux/uio.h' line='47' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='pipe' type-id='15d29710' visibility='default' filepath='include/linux/uio.h' line='42' column='1'/>
+          <var-decl name='pipe' type-id='15d29710' visibility='default' filepath='include/linux/uio.h' line='48' column='1'/>
         </data-member>
       </union-decl>
       <class-decl name='tty_driver' size-in-bits='1600' is-struct='yes' visibility='default' filepath='include/linux/tty_driver.h' line='301' column='1' id='9b27c78b'>
@@ -70536,7 +70692,7 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='77d12c79' size-in-bits='64' id='9bdc8381'/>
-      <enum-decl name='ftrace_dump_mode' filepath='include/linux/kernel.h' line='668' column='1' id='9be0e7e4'>
+      <enum-decl name='ftrace_dump_mode' filepath='include/linux/kernel.h' line='524' column='1' id='9be0e7e4'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='DUMP_NONE' value='0'/>
         <enumerator name='DUMP_ALL' value='1'/>
@@ -70624,7 +70780,7 @@
       <pointer-type-def type-id='202c5914' size-in-bits='64' id='9c5c88be'/>
       <pointer-type-def type-id='cd5915d8' size-in-bits='64' id='9c68341e'/>
       <pointer-type-def type-id='fdcd3504' size-in-bits='64' id='9c688f4e'/>
-      <enum-decl name='netdev_ml_priv_type' filepath='include/linux/netdevice.h' line='1651' column='1' id='9c6bf017'>
+      <enum-decl name='netdev_ml_priv_type' filepath='include/linux/netdevice.h' line='1656' column='1' id='9c6bf017'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='ML_PRIV_NONE' value='0'/>
         <enumerator name='ML_PRIV_CAN' value='1'/>
@@ -70656,12 +70812,12 @@
         <parameter type-id='19c2251e'/>
         <return type-id='95e97e5e'/>
       </function-type>
-      <union-decl name='__anonymous_union__' size-in-bits='32' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='893' column='1' id='9c81e675'>
+      <union-decl name='__anonymous_union__' size-in-bits='32' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='895' column='1' id='9c81e675'>
         <data-member access='public'>
-          <var-decl name='mark' type-id='3f1a6b60' visibility='default' filepath='include/linux/skbuff.h' line='894' column='1'/>
+          <var-decl name='mark' type-id='3f1a6b60' visibility='default' filepath='include/linux/skbuff.h' line='896' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='reserved_tailroom' type-id='3f1a6b60' visibility='default' filepath='include/linux/skbuff.h' line='895' column='1'/>
+          <var-decl name='reserved_tailroom' type-id='3f1a6b60' visibility='default' filepath='include/linux/skbuff.h' line='897' column='1'/>
         </data-member>
       </union-decl>
       <enum-decl name='snd_device_state' filepath='include/sound/core.h' line='53' column='1' id='9c857434'>
@@ -70711,6 +70867,7 @@
       <array-type-def dimensions='1' type-id='00205383' size-in-bits='3072' id='9cc39ce1'>
         <subrange length='24' type-id='7ff19f0f' id='fdd3342b'/>
       </array-type-def>
+      <pointer-type-def type-id='fa07ab8f' size-in-bits='64' id='9cc41107'/>
       <class-decl name='snd_kcontrol_volatile' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/sound/control.h' line='59' column='1' id='9cd807f4'>
         <data-member access='public' layout-offset-in-bits='0'>
           <var-decl name='owner' type-id='ed27ccc9' visibility='default' filepath='include/sound/control.h' line='60' column='1'/>
@@ -72265,15 +72422,15 @@
         <enumerator name='GRPQUOTA' value='1'/>
         <enumerator name='PRJQUOTA' value='2'/>
       </enum-decl>
-      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='drivers/usb/host/xhci.h' line='1941' column='1' id='9ff2562c'>
+      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='drivers/usb/host/xhci.h' line='1943' column='1' id='9ff2562c'>
         <data-member access='public'>
-          <var-decl name='vendor_ops' type-id='1e9ca7e3' visibility='default' filepath='drivers/usb/host/xhci.h' line='1941' column='1'/>
+          <var-decl name='vendor_ops' type-id='1e9ca7e3' visibility='default' filepath='drivers/usb/host/xhci.h' line='1943' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='' type-id='156952c4' visibility='default' filepath='drivers/usb/host/xhci.h' line='1941' column='1'/>
+          <var-decl name='' type-id='156952c4' visibility='default' filepath='drivers/usb/host/xhci.h' line='1943' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='' type-id='2a125a28' visibility='default' filepath='drivers/usb/host/xhci.h' line='1941' column='1'/>
+          <var-decl name='' type-id='2a125a28' visibility='default' filepath='drivers/usb/host/xhci.h' line='1943' column='1'/>
         </data-member>
       </union-decl>
       <pointer-type-def type-id='2bf16f59' size-in-bits='64' id='a0127209'/>
@@ -72360,45 +72517,45 @@
         <parameter type-id='95e97e5e'/>
         <return type-id='95e97e5e'/>
       </function-type>
-      <class-decl name='rate_sample' size-in-bits='448' is-struct='yes' visibility='default' filepath='include/net/tcp.h' line='1046' column='1' id='a084c932'>
+      <class-decl name='rate_sample' size-in-bits='448' is-struct='yes' visibility='default' filepath='include/net/tcp.h' line='1047' column='1' id='a084c932'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='prior_mstamp' type-id='91ce1af9' visibility='default' filepath='include/net/tcp.h' line='1047' column='1'/>
+          <var-decl name='prior_mstamp' type-id='91ce1af9' visibility='default' filepath='include/net/tcp.h' line='1048' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='prior_delivered' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1048' column='1'/>
+          <var-decl name='prior_delivered' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1049' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='delivered' type-id='a7832498' visibility='default' filepath='include/net/tcp.h' line='1049' column='1'/>
+          <var-decl name='delivered' type-id='a7832498' visibility='default' filepath='include/net/tcp.h' line='1050' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='interval_us' type-id='bd54fe1a' visibility='default' filepath='include/net/tcp.h' line='1050' column='1'/>
+          <var-decl name='interval_us' type-id='bd54fe1a' visibility='default' filepath='include/net/tcp.h' line='1051' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='snd_interval_us' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1051' column='1'/>
+          <var-decl name='snd_interval_us' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1052' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='224'>
-          <var-decl name='rcv_interval_us' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1052' column='1'/>
+          <var-decl name='rcv_interval_us' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1053' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='rtt_us' type-id='bd54fe1a' visibility='default' filepath='include/net/tcp.h' line='1053' column='1'/>
+          <var-decl name='rtt_us' type-id='bd54fe1a' visibility='default' filepath='include/net/tcp.h' line='1054' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='losses' type-id='95e97e5e' visibility='default' filepath='include/net/tcp.h' line='1054' column='1'/>
+          <var-decl name='losses' type-id='95e97e5e' visibility='default' filepath='include/net/tcp.h' line='1055' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='352'>
-          <var-decl name='acked_sacked' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1055' column='1'/>
+          <var-decl name='acked_sacked' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1056' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='prior_in_flight' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1056' column='1'/>
+          <var-decl name='prior_in_flight' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1057' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='416'>
-          <var-decl name='is_app_limited' type-id='b50a4934' visibility='default' filepath='include/net/tcp.h' line='1057' column='1'/>
+          <var-decl name='is_app_limited' type-id='b50a4934' visibility='default' filepath='include/net/tcp.h' line='1058' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='424'>
-          <var-decl name='is_retrans' type-id='b50a4934' visibility='default' filepath='include/net/tcp.h' line='1058' column='1'/>
+          <var-decl name='is_retrans' type-id='b50a4934' visibility='default' filepath='include/net/tcp.h' line='1059' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='432'>
-          <var-decl name='is_ack_delayed' type-id='b50a4934' visibility='default' filepath='include/net/tcp.h' line='1059' column='1'/>
+          <var-decl name='is_ack_delayed' type-id='b50a4934' visibility='default' filepath='include/net/tcp.h' line='1060' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='a08a663b'>
@@ -72478,7 +72635,7 @@
       <qualified-type-def type-id='e9bb2749' const='yes' id='a0ef5328'/>
       <pointer-type-def type-id='0be333ab' size-in-bits='64' id='a0f5247f'/>
       <pointer-type-def type-id='0fbf3cfd' size-in-bits='64' id='a10cc675'/>
-      <typedef-decl name='rx_handler_result_t' type-id='aee6711b' filepath='include/linux/netdevice.h' line='438' column='1' id='a110acfc'/>
+      <typedef-decl name='rx_handler_result_t' type-id='aee6711b' filepath='include/linux/netdevice.h' line='440' column='1' id='a110acfc'/>
       <array-type-def dimensions='2' type-id='8f048e17' size-in-bits='3072' id='a112b67c'>
         <subrange length='6' type-id='7ff19f0f' id='52fa524b'/>
         <subrange length='64' type-id='7ff19f0f' id='b10be967'/>
@@ -73340,12 +73497,12 @@
           <var-decl name='classid' type-id='19c2251e' visibility='default' filepath='include/net/sch_generic.h' line='317' column='1'/>
         </data-member>
       </class-decl>
-      <union-decl name='__anonymous_union__' size-in-bits='128' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='467' column='1' id='a27049de'>
+      <union-decl name='__anonymous_union__' size-in-bits='128' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='468' column='1' id='a27049de'>
         <data-member access='public'>
-          <var-decl name='' type-id='3ee84947' visibility='default' filepath='include/linux/skbuff.h' line='468' column='1'/>
+          <var-decl name='' type-id='3ee84947' visibility='default' filepath='include/linux/skbuff.h' line='469' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='' type-id='0efb3709' visibility='default' filepath='include/linux/skbuff.h' line='472' column='1'/>
+          <var-decl name='' type-id='0efb3709' visibility='default' filepath='include/linux/skbuff.h' line='473' column='1'/>
         </data-member>
       </union-decl>
       <typedef-decl name='swap_func_t' type-id='97c3bf57' filepath='include/linux/types.h' line='225' column='1' id='a271c445'/>
@@ -75066,12 +75223,12 @@
         <parameter type-id='6614aa5e'/>
         <return type-id='e5411c2c'/>
       </function-type>
-      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='738' column='1' id='a6d66544'>
+      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='740' column='1' id='a6d66544'>
         <data-member access='public'>
-          <var-decl name='sk' type-id='f772df6d' visibility='default' filepath='include/linux/skbuff.h' line='739' column='1'/>
+          <var-decl name='sk' type-id='f772df6d' visibility='default' filepath='include/linux/skbuff.h' line='741' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='ip_defrag_offset' type-id='95e97e5e' visibility='default' filepath='include/linux/skbuff.h' line='740' column='1'/>
+          <var-decl name='ip_defrag_offset' type-id='95e97e5e' visibility='default' filepath='include/linux/skbuff.h' line='742' column='1'/>
         </data-member>
       </union-decl>
       <qualified-type-def type-id='9d8e7276' const='yes' id='a6d8bab7'/>
@@ -75700,6 +75857,9 @@
         </data-member>
       </union-decl>
       <typedef-decl name='iova_flush_cb' type-id='53072f48' filepath='include/linux/iova.h' line='41' column='1' id='a7bae79c'/>
+      <array-type-def dimensions='1' type-id='e151255a' size-in-bits='16384' id='a7c26c7b'>
+        <subrange length='256' type-id='7ff19f0f' id='36e5b9fa'/>
+      </array-type-def>
       <function-type size-in-bits='64' id='a7c3e9e0'>
         <parameter type-id='0c65b409'/>
         <parameter type-id='19c2251e'/>
@@ -76338,12 +76498,12 @@
         </data-member>
       </class-decl>
       <qualified-type-def type-id='4e0399c2' const='yes' id='a87d8ed1'/>
-      <class-decl name='wq_device' size-in-bits='7232' is-struct='yes' visibility='default' filepath='kernel/workqueue.c' line='5406' column='1' id='a88ecfc8'>
+      <class-decl name='wq_device' size-in-bits='7232' is-struct='yes' visibility='default' filepath='kernel/workqueue.c' line='5409' column='1' id='a88ecfc8'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='wq' type-id='242e3d19' visibility='default' filepath='kernel/workqueue.c' line='5407' column='1'/>
+          <var-decl name='wq' type-id='242e3d19' visibility='default' filepath='kernel/workqueue.c' line='5410' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='dev' type-id='66e487eb' visibility='default' filepath='kernel/workqueue.c' line='5408' column='1'/>
+          <var-decl name='dev' type-id='66e487eb' visibility='default' filepath='kernel/workqueue.c' line='5411' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='_ddebug' size-in-bits='448' is-struct='yes' visibility='default' filepath='include/linux/dynamic_debug.h' line='14' column='1' id='a88f76f1'>
@@ -76434,18 +76594,18 @@
         <parameter type-id='84bbda06'/>
         <return type-id='95e97e5e'/>
       </function-type>
-      <class-decl name='skb_ext' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/linux/skbuff.h' line='4226' column='1' id='a8c69bdf'>
+      <class-decl name='skb_ext' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/linux/skbuff.h' line='4229' column='1' id='a8c69bdf'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='refcnt' type-id='64615833' visibility='default' filepath='include/linux/skbuff.h' line='4227' column='1'/>
+          <var-decl name='refcnt' type-id='64615833' visibility='default' filepath='include/linux/skbuff.h' line='4230' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='offset' type-id='cf08f83f' visibility='default' filepath='include/linux/skbuff.h' line='4228' column='1'/>
+          <var-decl name='offset' type-id='cf08f83f' visibility='default' filepath='include/linux/skbuff.h' line='4231' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='40'>
-          <var-decl name='chunks' type-id='f9b06939' visibility='default' filepath='include/linux/skbuff.h' line='4229' column='1'/>
+          <var-decl name='chunks' type-id='f9b06939' visibility='default' filepath='include/linux/skbuff.h' line='4232' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='data' type-id='e84913bd' visibility='default' filepath='include/linux/skbuff.h' line='4230' column='1'/>
+          <var-decl name='data' type-id='e84913bd' visibility='default' filepath='include/linux/skbuff.h' line='4233' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='ethtool_rx_flow_spec' size-in-bits='1344' is-struct='yes' visibility='default' filepath='include/uapi/linux/ethtool.h' line='992' column='1' id='a8ce468c'>
@@ -77163,15 +77323,15 @@
         <enumerator name='DEVFREQ_TIMER_NUM' value='2'/>
       </enum-decl>
       <pointer-type-def type-id='644441a6' size-in-bits='64' id='aae3718c'/>
-      <class-decl name='dwc3_gadget_ep_cmd_params' size-in-bits='96' is-struct='yes' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1481' column='1' id='aaf4c449'>
+      <class-decl name='dwc3_gadget_ep_cmd_params' size-in-bits='96' is-struct='yes' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1482' column='1' id='aaf4c449'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='param2' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1482' column='1'/>
+          <var-decl name='param2' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1483' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='param1' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1483' column='1'/>
+          <var-decl name='param1' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1484' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='param0' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1484' column='1'/>
+          <var-decl name='param0' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='1485' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='173cc5a0' size-in-bits='64' id='ab05e282'/>
@@ -77774,9 +77934,9 @@
       <pointer-type-def type-id='512ac7cc' size-in-bits='64' id='ac58af12'/>
       <pointer-type-def type-id='b254b8db' size-in-bits='64' id='ac5f2363'/>
       <pointer-type-def type-id='49a0ad34' size-in-bits='64' id='ac6963b2'/>
-      <class-decl name='prot_inuse' size-in-bits='2048' is-struct='yes' visibility='default' filepath='net/core/sock.c' line='3325' column='1' id='ac763c5d'>
+      <class-decl name='prot_inuse' size-in-bits='2048' is-struct='yes' visibility='default' filepath='net/core/sock.c' line='3352' column='1' id='ac763c5d'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='val' type-id='93e41790' visibility='default' filepath='net/core/sock.c' line='3326' column='1'/>
+          <var-decl name='val' type-id='93e41790' visibility='default' filepath='net/core/sock.c' line='3353' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='ac765b39'>
@@ -77834,15 +77994,15 @@
       <pointer-type-def type-id='ec9f1e6a' size-in-bits='64' id='ac9d10e4'/>
       <pointer-type-def type-id='153d6bdb' size-in-bits='64' id='ac9d827b'/>
       <typedef-decl name='pud_t' type-id='e5bf4bd5' filepath='include/asm-generic/pgtable-nopud.h' line='16' column='1' id='ac9f3c7e'/>
-      <class-decl name='rps_dev_flow_table' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='712' column='1' id='aca51d4a'>
+      <class-decl name='rps_dev_flow_table' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='714' column='1' id='aca51d4a'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='mask' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='713' column='1'/>
+          <var-decl name='mask' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='715' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/netdevice.h' line='714' column='1'/>
+          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/netdevice.h' line='716' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='flows' type-id='11d66d65' visibility='default' filepath='include/linux/netdevice.h' line='715' column='1'/>
+          <var-decl name='flows' type-id='11d66d65' visibility='default' filepath='include/linux/netdevice.h' line='717' column='1'/>
         </data-member>
       </class-decl>
       <array-type-def dimensions='1' type-id='b92c8d0d' size-in-bits='1280' id='aca5b9e5'>
@@ -78082,7 +78242,7 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='7e1ff049' size-in-bits='64' id='ad60bf5d'/>
-      <enum-decl name='typec_role' filepath='include/linux/usb/typec.h' line='50' column='1' id='ad61830a'>
+      <enum-decl name='typec_role' filepath='include/linux/usb/typec.h' line='51' column='1' id='ad61830a'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='TYPEC_SINK' value='0'/>
         <enumerator name='TYPEC_SOURCE' value='1'/>
@@ -78192,18 +78352,18 @@
       <pointer-type-def type-id='476ef610' size-in-bits='64' id='addd4a1a'/>
       <pointer-type-def type-id='1302297b' size-in-bits='64' id='adec6207'/>
       <pointer-type-def type-id='51bb592e' size-in-bits='64' id='aded214c'/>
-      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/net/sock.h' line='1268' column='1' id='adf5bf47'>
+      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/net/sock.h' line='1276' column='1' id='adf5bf47'>
         <data-member access='public'>
-          <var-decl name='hashinfo' type-id='d7a1e3c2' visibility='default' filepath='include/net/sock.h' line='1269' column='1'/>
+          <var-decl name='hashinfo' type-id='d7a1e3c2' visibility='default' filepath='include/net/sock.h' line='1277' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='udp_table' type-id='115daa23' visibility='default' filepath='include/net/sock.h' line='1270' column='1'/>
+          <var-decl name='udp_table' type-id='115daa23' visibility='default' filepath='include/net/sock.h' line='1278' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='raw_hash' type-id='eb2c56dc' visibility='default' filepath='include/net/sock.h' line='1271' column='1'/>
+          <var-decl name='raw_hash' type-id='eb2c56dc' visibility='default' filepath='include/net/sock.h' line='1279' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='smc_hash' type-id='aa8162a3' visibility='default' filepath='include/net/sock.h' line='1272' column='1'/>
+          <var-decl name='smc_hash' type-id='aa8162a3' visibility='default' filepath='include/net/sock.h' line='1280' column='1'/>
         </data-member>
       </union-decl>
       <qualified-type-def type-id='014e0a24' const='yes' id='adff645d'/>
@@ -78582,234 +78742,234 @@
           <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/kernfs.h' line='285' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='sk_buff' size-in-bits='1920' is-struct='yes' visibility='default' filepath='include/linux/skbuff.h' line='718' column='1' id='ae8bfcdd'>
+      <class-decl name='sk_buff' size-in-bits='1920' is-struct='yes' visibility='default' filepath='include/linux/skbuff.h' line='720' column='1' id='ae8bfcdd'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='' type-id='da6f1b1a' visibility='default' filepath='include/linux/skbuff.h' line='719' column='1'/>
+          <var-decl name='' type-id='da6f1b1a' visibility='default' filepath='include/linux/skbuff.h' line='721' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='' type-id='a6d66544' visibility='default' filepath='include/linux/skbuff.h' line='738' column='1'/>
+          <var-decl name='' type-id='a6d66544' visibility='default' filepath='include/linux/skbuff.h' line='740' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='' type-id='b24a5a7e' visibility='default' filepath='include/linux/skbuff.h' line='743' column='1'/>
+          <var-decl name='' type-id='b24a5a7e' visibility='default' filepath='include/linux/skbuff.h' line='745' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='cb' type-id='36d7f119' visibility='default' filepath='include/linux/skbuff.h' line='753' column='1'/>
+          <var-decl name='cb' type-id='36d7f119' visibility='default' filepath='include/linux/skbuff.h' line='755' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='' type-id='271a40b8' visibility='default' filepath='include/linux/skbuff.h' line='755' column='1'/>
+          <var-decl name='' type-id='271a40b8' visibility='default' filepath='include/linux/skbuff.h' line='757' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='_nfct' type-id='7359adad' visibility='default' filepath='include/linux/skbuff.h' line='764' column='1'/>
+          <var-decl name='_nfct' type-id='7359adad' visibility='default' filepath='include/linux/skbuff.h' line='766' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='len' type-id='f0981eeb' visibility='default' filepath='include/linux/skbuff.h' line='766' column='1'/>
+          <var-decl name='len' type-id='f0981eeb' visibility='default' filepath='include/linux/skbuff.h' line='768' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='928'>
-          <var-decl name='data_len' type-id='f0981eeb' visibility='default' filepath='include/linux/skbuff.h' line='767' column='1'/>
+          <var-decl name='data_len' type-id='f0981eeb' visibility='default' filepath='include/linux/skbuff.h' line='769' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='mac_len' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='768' column='1'/>
+          <var-decl name='mac_len' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='770' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='976'>
-          <var-decl name='hdr_len' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='769' column='1'/>
+          <var-decl name='hdr_len' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='771' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='992'>
-          <var-decl name='queue_mapping' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='774' column='1'/>
+          <var-decl name='queue_mapping' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='776' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1008'>
-          <var-decl name='__cloned_offset' type-id='167619f6' visibility='default' filepath='include/linux/skbuff.h' line='785' column='1'/>
+          <var-decl name='__cloned_offset' type-id='167619f6' visibility='default' filepath='include/linux/skbuff.h' line='787' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='cloned' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='787' column='1'/>
+          <var-decl name='cloned' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='789' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1'>
-          <var-decl name='nohdr' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='788' column='1'/>
+          <var-decl name='nohdr' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='790' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2'>
-          <var-decl name='fclone' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='789' column='1'/>
+          <var-decl name='fclone' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='791' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4'>
-          <var-decl name='peeked' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='790' column='1'/>
+          <var-decl name='peeked' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='792' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5'>
-          <var-decl name='head_frag' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='791' column='1'/>
+          <var-decl name='head_frag' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='793' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6'>
-          <var-decl name='pfmemalloc' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='792' column='1'/>
+          <var-decl name='pfmemalloc' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='794' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1016'>
-          <var-decl name='active_extensions' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='794' column='1'/>
+          <var-decl name='active_extensions' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='796' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='headers_start' type-id='d5016f6f' visibility='default' filepath='include/linux/skbuff.h' line='800' column='1'/>
+          <var-decl name='headers_start' type-id='d5016f6f' visibility='default' filepath='include/linux/skbuff.h' line='802' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='__pkt_type_offset' type-id='167619f6' visibility='default' filepath='include/linux/skbuff.h' line='812' column='1'/>
+          <var-decl name='__pkt_type_offset' type-id='167619f6' visibility='default' filepath='include/linux/skbuff.h' line='814' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='pkt_type' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='814' column='1'/>
+          <var-decl name='pkt_type' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='816' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3'>
-          <var-decl name='ignore_df' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='815' column='1'/>
+          <var-decl name='ignore_df' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='817' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4'>
-          <var-decl name='nf_trace' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='816' column='1'/>
+          <var-decl name='nf_trace' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='818' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5'>
-          <var-decl name='ip_summed' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='817' column='1'/>
+          <var-decl name='ip_summed' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='819' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7'>
-          <var-decl name='ooo_okay' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='818' column='1'/>
+          <var-decl name='ooo_okay' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='820' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='l4_hash' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='820' column='1'/>
+          <var-decl name='l4_hash' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='822' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1'>
-          <var-decl name='sw_hash' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='821' column='1'/>
+          <var-decl name='sw_hash' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='823' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2'>
-          <var-decl name='wifi_acked_valid' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='822' column='1'/>
+          <var-decl name='wifi_acked_valid' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='824' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3'>
-          <var-decl name='wifi_acked' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='823' column='1'/>
+          <var-decl name='wifi_acked' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='825' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4'>
-          <var-decl name='no_fcs' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='824' column='1'/>
+          <var-decl name='no_fcs' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='826' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5'>
-          <var-decl name='encapsulation' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='826' column='1'/>
+          <var-decl name='encapsulation' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='828' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6'>
-          <var-decl name='encap_hdr_csum' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='827' column='1'/>
+          <var-decl name='encap_hdr_csum' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='829' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7'>
-          <var-decl name='csum_valid' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='828' column='1'/>
+          <var-decl name='csum_valid' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='830' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1040'>
-          <var-decl name='__pkt_vlan_present_offset' type-id='167619f6' visibility='default' filepath='include/linux/skbuff.h' line='837' column='1'/>
+          <var-decl name='__pkt_vlan_present_offset' type-id='167619f6' visibility='default' filepath='include/linux/skbuff.h' line='839' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='vlan_present' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='839' column='1'/>
+          <var-decl name='vlan_present' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='841' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1'>
-          <var-decl name='csum_complete_sw' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='840' column='1'/>
+          <var-decl name='csum_complete_sw' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='842' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2'>
-          <var-decl name='csum_level' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='841' column='1'/>
+          <var-decl name='csum_level' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='843' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4'>
-          <var-decl name='csum_not_inet' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='842' column='1'/>
+          <var-decl name='csum_not_inet' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='844' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5'>
-          <var-decl name='dst_pending_confirm' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='843' column='1'/>
+          <var-decl name='dst_pending_confirm' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='845' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6'>
-          <var-decl name='ndisc_nodetype' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='845' column='1'/>
+          <var-decl name='ndisc_nodetype' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='847' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='ipvs_property' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='848' column='1'/>
+          <var-decl name='ipvs_property' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='850' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1'>
-          <var-decl name='inner_protocol_type' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='849' column='1'/>
+          <var-decl name='inner_protocol_type' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='851' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2'>
-          <var-decl name='remcsum_offload' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='850' column='1'/>
+          <var-decl name='remcsum_offload' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='852' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3'>
-          <var-decl name='tc_skip_classify' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='856' column='1'/>
+          <var-decl name='tc_skip_classify' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='858' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4'>
-          <var-decl name='tc_at_ingress' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='857' column='1'/>
+          <var-decl name='tc_at_ingress' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='859' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5'>
-          <var-decl name='redirected' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='860' column='1'/>
+          <var-decl name='redirected' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='862' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6'>
-          <var-decl name='from_ingress' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='861' column='1'/>
+          <var-decl name='from_ingress' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='863' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1056'>
-          <var-decl name='tc_index' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='868' column='1'/>
+          <var-decl name='tc_index' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='870' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1088'>
-          <var-decl name='' type-id='b4fc55b7' visibility='default' filepath='include/linux/skbuff.h' line='871' column='1'/>
+          <var-decl name='' type-id='b4fc55b7' visibility='default' filepath='include/linux/skbuff.h' line='873' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1120'>
-          <var-decl name='priority' type-id='3f1a6b60' visibility='default' filepath='include/linux/skbuff.h' line='878' column='1'/>
+          <var-decl name='priority' type-id='3f1a6b60' visibility='default' filepath='include/linux/skbuff.h' line='880' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='skb_iif' type-id='95e97e5e' visibility='default' filepath='include/linux/skbuff.h' line='879' column='1'/>
+          <var-decl name='skb_iif' type-id='95e97e5e' visibility='default' filepath='include/linux/skbuff.h' line='881' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1184'>
-          <var-decl name='hash' type-id='3f1a6b60' visibility='default' filepath='include/linux/skbuff.h' line='880' column='1'/>
+          <var-decl name='hash' type-id='3f1a6b60' visibility='default' filepath='include/linux/skbuff.h' line='882' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='vlan_proto' type-id='84a5c3d4' visibility='default' filepath='include/linux/skbuff.h' line='881' column='1'/>
+          <var-decl name='vlan_proto' type-id='84a5c3d4' visibility='default' filepath='include/linux/skbuff.h' line='883' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1232'>
-          <var-decl name='vlan_tci' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='882' column='1'/>
+          <var-decl name='vlan_tci' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='884' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1248'>
-          <var-decl name='' type-id='8c3ee840' visibility='default' filepath='include/linux/skbuff.h' line='884' column='1'/>
+          <var-decl name='' type-id='8c3ee840' visibility='default' filepath='include/linux/skbuff.h' line='886' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1280'>
-          <var-decl name='secmark' type-id='3f1a6b60' visibility='default' filepath='include/linux/skbuff.h' line='890' column='1'/>
+          <var-decl name='secmark' type-id='3f1a6b60' visibility='default' filepath='include/linux/skbuff.h' line='892' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1312'>
-          <var-decl name='' type-id='9c81e675' visibility='default' filepath='include/linux/skbuff.h' line='893' column='1'/>
+          <var-decl name='' type-id='9c81e675' visibility='default' filepath='include/linux/skbuff.h' line='895' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1344'>
-          <var-decl name='' type-id='b97daab4' visibility='default' filepath='include/linux/skbuff.h' line='898' column='1'/>
+          <var-decl name='' type-id='b97daab4' visibility='default' filepath='include/linux/skbuff.h' line='900' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1360'>
-          <var-decl name='inner_transport_header' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='903' column='1'/>
+          <var-decl name='inner_transport_header' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='905' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1376'>
-          <var-decl name='inner_network_header' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='904' column='1'/>
+          <var-decl name='inner_network_header' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='906' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1392'>
-          <var-decl name='inner_mac_header' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='905' column='1'/>
+          <var-decl name='inner_mac_header' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='907' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1408'>
-          <var-decl name='protocol' type-id='84a5c3d4' visibility='default' filepath='include/linux/skbuff.h' line='907' column='1'/>
+          <var-decl name='protocol' type-id='84a5c3d4' visibility='default' filepath='include/linux/skbuff.h' line='909' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1424'>
-          <var-decl name='transport_header' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='908' column='1'/>
+          <var-decl name='transport_header' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='910' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1440'>
-          <var-decl name='network_header' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='909' column='1'/>
+          <var-decl name='network_header' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='911' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1456'>
-          <var-decl name='mac_header' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='910' column='1'/>
+          <var-decl name='mac_header' type-id='d315442e' visibility='default' filepath='include/linux/skbuff.h' line='912' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1472'>
-          <var-decl name='headers_end' type-id='d5016f6f' visibility='default' filepath='include/linux/skbuff.h' line='913' column='1'/>
+          <var-decl name='headers_end' type-id='d5016f6f' visibility='default' filepath='include/linux/skbuff.h' line='919' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1472'>
-          <var-decl name='' type-id='607684dc' visibility='default' filepath='include/linux/skbuff.h' line='924' column='1'/>
+          <var-decl name='' type-id='607684dc' visibility='default' filepath='include/linux/skbuff.h' line='930' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/skbuff.h' line='931' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/skbuff.h' line='937' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1600'>
-          <var-decl name='tail' type-id='5c1abc34' visibility='default' filepath='include/linux/skbuff.h' line='934' column='1'/>
+          <var-decl name='tail' type-id='5c1abc34' visibility='default' filepath='include/linux/skbuff.h' line='940' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1632'>
-          <var-decl name='end' type-id='5c1abc34' visibility='default' filepath='include/linux/skbuff.h' line='935' column='1'/>
+          <var-decl name='end' type-id='5c1abc34' visibility='default' filepath='include/linux/skbuff.h' line='941' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1664'>
-          <var-decl name='head' type-id='cf536864' visibility='default' filepath='include/linux/skbuff.h' line='936' column='1'/>
+          <var-decl name='head' type-id='cf536864' visibility='default' filepath='include/linux/skbuff.h' line='942' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1728'>
-          <var-decl name='data' type-id='cf536864' visibility='default' filepath='include/linux/skbuff.h' line='937' column='1'/>
+          <var-decl name='data' type-id='cf536864' visibility='default' filepath='include/linux/skbuff.h' line='943' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1792'>
-          <var-decl name='truesize' type-id='f0981eeb' visibility='default' filepath='include/linux/skbuff.h' line='938' column='1'/>
+          <var-decl name='truesize' type-id='f0981eeb' visibility='default' filepath='include/linux/skbuff.h' line='944' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1824'>
-          <var-decl name='users' type-id='64615833' visibility='default' filepath='include/linux/skbuff.h' line='939' column='1'/>
+          <var-decl name='users' type-id='64615833' visibility='default' filepath='include/linux/skbuff.h' line='945' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1856'>
-          <var-decl name='extensions' type-id='374692c7' visibility='default' filepath='include/linux/skbuff.h' line='943' column='1'/>
+          <var-decl name='extensions' type-id='374692c7' visibility='default' filepath='include/linux/skbuff.h' line='949' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='0286989c' size-in-bits='64' id='ae9790c6'/>
@@ -79059,7 +79219,7 @@
         <parameter type-id='f0981eeb'/>
         <return type-id='48b5725f'/>
       </function-type>
-      <enum-decl name='rx_handler_result' filepath='include/linux/netdevice.h' line='432' column='1' id='aee6711b'>
+      <enum-decl name='rx_handler_result' filepath='include/linux/netdevice.h' line='434' column='1' id='aee6711b'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='RX_HANDLER_CONSUMED' value='0'/>
         <enumerator name='RX_HANDLER_ANOTHER' value='1'/>
@@ -80295,108 +80455,108 @@
       <pointer-type-def type-id='1af55526' size-in-bits='64' id='b201adb8'/>
       <pointer-type-def type-id='0cdc58b8' size-in-bits='64' id='b20461b2'/>
       <pointer-type-def type-id='6c99ab8f' size-in-bits='64' id='b20722ab'/>
-      <class-decl name='urb' size-in-bits='1728' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='1589' column='1' id='b209b4e4'>
+      <class-decl name='urb' size-in-bits='1728' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='1597' column='1' id='b209b4e4'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='kref' type-id='400fb07b' visibility='default' filepath='include/linux/usb.h' line='1591' column='1'/>
+          <var-decl name='kref' type-id='400fb07b' visibility='default' filepath='include/linux/usb.h' line='1599' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='unlinked' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1592' column='1'/>
+          <var-decl name='unlinked' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1600' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='hcpriv' type-id='eaa32e2f' visibility='default' filepath='include/linux/usb.h' line='1593' column='1'/>
+          <var-decl name='hcpriv' type-id='eaa32e2f' visibility='default' filepath='include/linux/usb.h' line='1601' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='use_count' type-id='49178f86' visibility='default' filepath='include/linux/usb.h' line='1594' column='1'/>
+          <var-decl name='use_count' type-id='49178f86' visibility='default' filepath='include/linux/usb.h' line='1602' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='160'>
-          <var-decl name='reject' type-id='49178f86' visibility='default' filepath='include/linux/usb.h' line='1595' column='1'/>
+          <var-decl name='reject' type-id='49178f86' visibility='default' filepath='include/linux/usb.h' line='1603' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='urb_list' type-id='72f469ec' visibility='default' filepath='include/linux/usb.h' line='1598' column='1'/>
+          <var-decl name='urb_list' type-id='72f469ec' visibility='default' filepath='include/linux/usb.h' line='1606' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='anchor_list' type-id='72f469ec' visibility='default' filepath='include/linux/usb.h' line='1600' column='1'/>
+          <var-decl name='anchor_list' type-id='72f469ec' visibility='default' filepath='include/linux/usb.h' line='1608' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='anchor' type-id='bd300bf3' visibility='default' filepath='include/linux/usb.h' line='1601' column='1'/>
+          <var-decl name='anchor' type-id='bd300bf3' visibility='default' filepath='include/linux/usb.h' line='1609' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='dev' type-id='25e60cb2' visibility='default' filepath='include/linux/usb.h' line='1602' column='1'/>
+          <var-decl name='dev' type-id='25e60cb2' visibility='default' filepath='include/linux/usb.h' line='1610' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='ep' type-id='15adb516' visibility='default' filepath='include/linux/usb.h' line='1603' column='1'/>
+          <var-decl name='ep' type-id='15adb516' visibility='default' filepath='include/linux/usb.h' line='1611' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='pipe' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1604' column='1'/>
+          <var-decl name='pipe' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1612' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='672'>
-          <var-decl name='stream_id' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1605' column='1'/>
+          <var-decl name='stream_id' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1613' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='status' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1606' column='1'/>
+          <var-decl name='status' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1614' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='736'>
-          <var-decl name='transfer_flags' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1607' column='1'/>
+          <var-decl name='transfer_flags' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1615' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='transfer_buffer' type-id='eaa32e2f' visibility='default' filepath='include/linux/usb.h' line='1608' column='1'/>
+          <var-decl name='transfer_buffer' type-id='eaa32e2f' visibility='default' filepath='include/linux/usb.h' line='1616' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='transfer_dma' type-id='cf29c9b3' visibility='default' filepath='include/linux/usb.h' line='1609' column='1'/>
+          <var-decl name='transfer_dma' type-id='cf29c9b3' visibility='default' filepath='include/linux/usb.h' line='1617' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='sg' type-id='bf3ef905' visibility='default' filepath='include/linux/usb.h' line='1610' column='1'/>
+          <var-decl name='sg' type-id='bf3ef905' visibility='default' filepath='include/linux/usb.h' line='1618' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='num_mapped_sgs' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1611' column='1'/>
+          <var-decl name='num_mapped_sgs' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1619' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='992'>
-          <var-decl name='num_sgs' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1612' column='1'/>
+          <var-decl name='num_sgs' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1620' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='transfer_buffer_length' type-id='19c2251e' visibility='default' filepath='include/linux/usb.h' line='1613' column='1'/>
+          <var-decl name='transfer_buffer_length' type-id='19c2251e' visibility='default' filepath='include/linux/usb.h' line='1621' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1056'>
-          <var-decl name='actual_length' type-id='19c2251e' visibility='default' filepath='include/linux/usb.h' line='1614' column='1'/>
+          <var-decl name='actual_length' type-id='19c2251e' visibility='default' filepath='include/linux/usb.h' line='1622' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1088'>
-          <var-decl name='setup_packet' type-id='cf536864' visibility='default' filepath='include/linux/usb.h' line='1615' column='1'/>
+          <var-decl name='setup_packet' type-id='cf536864' visibility='default' filepath='include/linux/usb.h' line='1623' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='setup_dma' type-id='cf29c9b3' visibility='default' filepath='include/linux/usb.h' line='1616' column='1'/>
+          <var-decl name='setup_dma' type-id='cf29c9b3' visibility='default' filepath='include/linux/usb.h' line='1624' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='start_frame' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1617' column='1'/>
+          <var-decl name='start_frame' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1625' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1248'>
-          <var-decl name='number_of_packets' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1618' column='1'/>
+          <var-decl name='number_of_packets' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1626' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1280'>
-          <var-decl name='interval' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1619' column='1'/>
+          <var-decl name='interval' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1627' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1312'>
-          <var-decl name='error_count' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1621' column='1'/>
+          <var-decl name='error_count' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1629' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1344'>
-          <var-decl name='context' type-id='eaa32e2f' visibility='default' filepath='include/linux/usb.h' line='1622' column='1'/>
+          <var-decl name='context' type-id='eaa32e2f' visibility='default' filepath='include/linux/usb.h' line='1630' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1408'>
-          <var-decl name='complete' type-id='4086973b' visibility='default' filepath='include/linux/usb.h' line='1623' column='1'/>
+          <var-decl name='complete' type-id='4086973b' visibility='default' filepath='include/linux/usb.h' line='1631' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1472'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1625' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1633' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1626' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1634' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1600'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1627' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1635' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1664'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1628' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='1636' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1728'>
-          <var-decl name='iso_frame_desc' type-id='b585dd30' visibility='default' filepath='include/linux/usb.h' line='1630' column='1'/>
+          <var-decl name='iso_frame_desc' type-id='b585dd30' visibility='default' filepath='include/linux/usb.h' line='1638' column='1'/>
         </data-member>
       </class-decl>
       <array-type-def dimensions='1' type-id='02f11ed4' size-in-bits='960' id='b210041a'>
@@ -80443,12 +80603,12 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='22814d90' size-in-bits='64' id='b249945a'/>
-      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='743' column='1' id='b24a5a7e'>
+      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='745' column='1' id='b24a5a7e'>
         <data-member access='public'>
-          <var-decl name='tstamp' type-id='fbc017ef' visibility='default' filepath='include/linux/skbuff.h' line='744' column='1'/>
+          <var-decl name='tstamp' type-id='fbc017ef' visibility='default' filepath='include/linux/skbuff.h' line='746' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='skb_mstamp_ns' type-id='91ce1af9' visibility='default' filepath='include/linux/skbuff.h' line='745' column='1'/>
+          <var-decl name='skb_mstamp_ns' type-id='91ce1af9' visibility='default' filepath='include/linux/skbuff.h' line='747' column='1'/>
         </data-member>
       </union-decl>
       <pointer-type-def type-id='3df0f7af' size-in-bits='64' id='b25391b7'/>
@@ -81048,21 +81208,21 @@
         <parameter type-id='031224de'/>
         <return type-id='b50a4934'/>
       </function-type>
-      <class-decl name='usb_anchor' size-in-bits='448' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='1388' column='1' id='b3bcc053'>
+      <class-decl name='usb_anchor' size-in-bits='448' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='1396' column='1' id='b3bcc053'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='urb_list' type-id='72f469ec' visibility='default' filepath='include/linux/usb.h' line='1389' column='1'/>
+          <var-decl name='urb_list' type-id='72f469ec' visibility='default' filepath='include/linux/usb.h' line='1397' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='wait' type-id='b5ab048f' visibility='default' filepath='include/linux/usb.h' line='1390' column='1'/>
+          <var-decl name='wait' type-id='b5ab048f' visibility='default' filepath='include/linux/usb.h' line='1398' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='lock' type-id='fb4018a0' visibility='default' filepath='include/linux/usb.h' line='1391' column='1'/>
+          <var-decl name='lock' type-id='fb4018a0' visibility='default' filepath='include/linux/usb.h' line='1399' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='352'>
-          <var-decl name='suspend_wakeups' type-id='49178f86' visibility='default' filepath='include/linux/usb.h' line='1392' column='1'/>
+          <var-decl name='suspend_wakeups' type-id='49178f86' visibility='default' filepath='include/linux/usb.h' line='1400' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='poisoned' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1393' column='1'/>
+          <var-decl name='poisoned' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1401' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='b3bf9ca3'>
@@ -81085,7 +81245,7 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='c85f87a7' size-in-bits='64' id='b3e04083'/>
-      <enum-decl name='tc_setup_type' filepath='include/linux/netdevice.h' line='869' column='1' id='b3e12f1c'>
+      <enum-decl name='tc_setup_type' filepath='include/linux/netdevice.h' line='874' column='1' id='b3e12f1c'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='TC_SETUP_QDISC_MQPRIO' value='0'/>
         <enumerator name='TC_SETUP_CLSU32' value='1'/>
@@ -81575,12 +81735,12 @@
       <pointer-type-def type-id='876d3bbc' size-in-bits='64' id='b4de78ea'/>
       <class-decl name='fib6_config' is-struct='yes' visibility='default' is-declaration-only='yes' id='b4ee5e67'/>
       <pointer-type-def type-id='02f1c4a9' size-in-bits='64' id='b4fb1c55'/>
-      <union-decl name='__anonymous_union__' size-in-bits='32' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='871' column='1' id='b4fc55b7'>
+      <union-decl name='__anonymous_union__' size-in-bits='32' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='873' column='1' id='b4fc55b7'>
         <data-member access='public'>
-          <var-decl name='csum' type-id='fbd88bba' visibility='default' filepath='include/linux/skbuff.h' line='872' column='1'/>
+          <var-decl name='csum' type-id='fbd88bba' visibility='default' filepath='include/linux/skbuff.h' line='874' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='' type-id='358587ec' visibility='default' filepath='include/linux/skbuff.h' line='873' column='1'/>
+          <var-decl name='' type-id='358587ec' visibility='default' filepath='include/linux/skbuff.h' line='875' column='1'/>
         </data-member>
       </union-decl>
       <pointer-type-def type-id='2eb8da02' size-in-bits='64' id='b4ff6cf8'/>
@@ -82135,15 +82295,15 @@
         <parameter type-id='aa9ea333'/>
         <return type-id='48b5725f'/>
       </function-type>
-      <class-decl name='rps_dev_flow' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='702' column='1' id='b65a052d'>
+      <class-decl name='rps_dev_flow' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='704' column='1' id='b65a052d'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='cpu' type-id='1dc6a898' visibility='default' filepath='include/linux/netdevice.h' line='703' column='1'/>
+          <var-decl name='cpu' type-id='1dc6a898' visibility='default' filepath='include/linux/netdevice.h' line='705' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='16'>
-          <var-decl name='filter' type-id='1dc6a898' visibility='default' filepath='include/linux/netdevice.h' line='704' column='1'/>
+          <var-decl name='filter' type-id='1dc6a898' visibility='default' filepath='include/linux/netdevice.h' line='706' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='last_qtail' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='705' column='1'/>
+          <var-decl name='last_qtail' type-id='f0981eeb' visibility='default' filepath='include/linux/netdevice.h' line='707' column='1'/>
         </data-member>
       </class-decl>
       <typedef-decl name='dr_release_t' type-id='680bf43c' filepath='include/linux/device.h' line='166' column='1' id='b6609e5b'/>
@@ -82235,30 +82395,30 @@
         <return type-id='95e97e5e'/>
       </function-type>
       <pointer-type-def type-id='0ad68707' size-in-bits='64' id='b6a33eaf'/>
-      <class-decl name='snd_soc_dapm_update' size-in-bits='320' is-struct='yes' visibility='default' filepath='include/sound/soc-dapm.h' line='671' column='1' id='b6a3f4d3'>
+      <class-decl name='snd_soc_dapm_update' size-in-bits='320' is-struct='yes' visibility='default' filepath='include/sound/soc-dapm.h' line='672' column='1' id='b6a3f4d3'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='kcontrol' type-id='7a5054b7' visibility='default' filepath='include/sound/soc-dapm.h' line='672' column='1'/>
+          <var-decl name='kcontrol' type-id='7a5054b7' visibility='default' filepath='include/sound/soc-dapm.h' line='673' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='reg' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='673' column='1'/>
+          <var-decl name='reg' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='674' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='mask' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='674' column='1'/>
+          <var-decl name='mask' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='675' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='val' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='675' column='1'/>
+          <var-decl name='val' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='676' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='160'>
-          <var-decl name='reg2' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='676' column='1'/>
+          <var-decl name='reg2' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='677' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='mask2' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='677' column='1'/>
+          <var-decl name='mask2' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='678' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='224'>
-          <var-decl name='val2' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='678' column='1'/>
+          <var-decl name='val2' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='679' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='has_second_set' type-id='b50a4934' visibility='default' filepath='include/sound/soc-dapm.h' line='679' column='1'/>
+          <var-decl name='has_second_set' type-id='b50a4934' visibility='default' filepath='include/sound/soc-dapm.h' line='680' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='d15eade2' size-in-bits='64' id='b6a6ca60'/>
@@ -82447,15 +82607,15 @@
           <var-decl name='match_existing_only' type-id='f0981eeb' visibility='default' filepath='include/linux/usb/gadget.h' line='750' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='pcpu_lstats' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='2636' column='1' id='b71b307b'>
+      <class-decl name='pcpu_lstats' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='2637' column='1' id='b71b307b'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='packets' type-id='0f413d2a' visibility='default' filepath='include/linux/netdevice.h' line='2637' column='1'/>
+          <var-decl name='packets' type-id='0f413d2a' visibility='default' filepath='include/linux/netdevice.h' line='2638' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='bytes' type-id='0f413d2a' visibility='default' filepath='include/linux/netdevice.h' line='2638' column='1'/>
+          <var-decl name='bytes' type-id='0f413d2a' visibility='default' filepath='include/linux/netdevice.h' line='2639' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='syncp' type-id='e4d85780' visibility='default' filepath='include/linux/netdevice.h' line='2639' column='1'/>
+          <var-decl name='syncp' type-id='e4d85780' visibility='default' filepath='include/linux/netdevice.h' line='2640' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='b7290258'>
@@ -83409,73 +83569,73 @@
           <var-decl name='quirks' type-id='3a47d82b' visibility='default' filepath='drivers/usb/host/xhci.h' line='1855' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='21120'>
-          <var-decl name='num_active_eps' type-id='f0981eeb' visibility='default' filepath='drivers/usb/host/xhci.h' line='1912' column='1'/>
+          <var-decl name='num_active_eps' type-id='f0981eeb' visibility='default' filepath='drivers/usb/host/xhci.h' line='1914' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='21152'>
-          <var-decl name='limit_active_eps' type-id='f0981eeb' visibility='default' filepath='drivers/usb/host/xhci.h' line='1913' column='1'/>
+          <var-decl name='limit_active_eps' type-id='f0981eeb' visibility='default' filepath='drivers/usb/host/xhci.h' line='1915' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='21184'>
-          <var-decl name='hw_ports' type-id='4add39c5' visibility='default' filepath='drivers/usb/host/xhci.h' line='1914' column='1'/>
+          <var-decl name='hw_ports' type-id='4add39c5' visibility='default' filepath='drivers/usb/host/xhci.h' line='1916' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='21248'>
-          <var-decl name='usb2_rhub' type-id='d2c7a2c1' visibility='default' filepath='drivers/usb/host/xhci.h' line='1915' column='1'/>
+          <var-decl name='usb2_rhub' type-id='d2c7a2c1' visibility='default' filepath='drivers/usb/host/xhci.h' line='1917' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='39744'>
-          <var-decl name='usb3_rhub' type-id='d2c7a2c1' visibility='default' filepath='drivers/usb/host/xhci.h' line='1916' column='1'/>
+          <var-decl name='usb3_rhub' type-id='d2c7a2c1' visibility='default' filepath='drivers/usb/host/xhci.h' line='1918' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='hw_lpm_support' type-id='f0981eeb' visibility='default' filepath='drivers/usb/host/xhci.h' line='1918' column='1'/>
+          <var-decl name='hw_lpm_support' type-id='f0981eeb' visibility='default' filepath='drivers/usb/host/xhci.h' line='1920' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1'>
-          <var-decl name='broken_suspend' type-id='f0981eeb' visibility='default' filepath='drivers/usb/host/xhci.h' line='1920' column='1'/>
+          <var-decl name='broken_suspend' type-id='f0981eeb' visibility='default' filepath='drivers/usb/host/xhci.h' line='1922' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='58304'>
-          <var-decl name='ext_caps' type-id='f9409001' visibility='default' filepath='drivers/usb/host/xhci.h' line='1922' column='1'/>
+          <var-decl name='ext_caps' type-id='f9409001' visibility='default' filepath='drivers/usb/host/xhci.h' line='1924' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='58368'>
-          <var-decl name='num_ext_caps' type-id='f0981eeb' visibility='default' filepath='drivers/usb/host/xhci.h' line='1923' column='1'/>
+          <var-decl name='num_ext_caps' type-id='f0981eeb' visibility='default' filepath='drivers/usb/host/xhci.h' line='1925' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='58432'>
-          <var-decl name='port_caps' type-id='aae3718c' visibility='default' filepath='drivers/usb/host/xhci.h' line='1925' column='1'/>
+          <var-decl name='port_caps' type-id='aae3718c' visibility='default' filepath='drivers/usb/host/xhci.h' line='1927' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='58496'>
-          <var-decl name='num_port_caps' type-id='f0981eeb' visibility='default' filepath='drivers/usb/host/xhci.h' line='1926' column='1'/>
+          <var-decl name='num_port_caps' type-id='f0981eeb' visibility='default' filepath='drivers/usb/host/xhci.h' line='1928' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='58560'>
-          <var-decl name='comp_mode_recovery_timer' type-id='abe41e67' visibility='default' filepath='drivers/usb/host/xhci.h' line='1928' column='1'/>
+          <var-decl name='comp_mode_recovery_timer' type-id='abe41e67' visibility='default' filepath='drivers/usb/host/xhci.h' line='1930' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='59008'>
-          <var-decl name='port_status_u0' type-id='19c2251e' visibility='default' filepath='drivers/usb/host/xhci.h' line='1929' column='1'/>
+          <var-decl name='port_status_u0' type-id='19c2251e' visibility='default' filepath='drivers/usb/host/xhci.h' line='1931' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='59040'>
-          <var-decl name='test_mode' type-id='1dc6a898' visibility='default' filepath='drivers/usb/host/xhci.h' line='1930' column='1'/>
+          <var-decl name='test_mode' type-id='1dc6a898' visibility='default' filepath='drivers/usb/host/xhci.h' line='1932' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='59072'>
-          <var-decl name='debugfs_root' type-id='27675065' visibility='default' filepath='drivers/usb/host/xhci.h' line='1934' column='1'/>
+          <var-decl name='debugfs_root' type-id='27675065' visibility='default' filepath='drivers/usb/host/xhci.h' line='1936' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='59136'>
-          <var-decl name='debugfs_slots' type-id='27675065' visibility='default' filepath='drivers/usb/host/xhci.h' line='1935' column='1'/>
+          <var-decl name='debugfs_slots' type-id='27675065' visibility='default' filepath='drivers/usb/host/xhci.h' line='1937' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='59200'>
-          <var-decl name='regset_list' type-id='72f469ec' visibility='default' filepath='drivers/usb/host/xhci.h' line='1936' column='1'/>
+          <var-decl name='regset_list' type-id='72f469ec' visibility='default' filepath='drivers/usb/host/xhci.h' line='1938' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='59328'>
-          <var-decl name='dbc' type-id='eaa32e2f' visibility='default' filepath='drivers/usb/host/xhci.h' line='1938' column='1'/>
+          <var-decl name='dbc' type-id='eaa32e2f' visibility='default' filepath='drivers/usb/host/xhci.h' line='1940' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='59392'>
-          <var-decl name='' type-id='9ff2562c' visibility='default' filepath='drivers/usb/host/xhci.h' line='1941' column='1'/>
+          <var-decl name='' type-id='9ff2562c' visibility='default' filepath='drivers/usb/host/xhci.h' line='1943' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='59456'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='drivers/usb/host/xhci.h' line='1943' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='drivers/usb/host/xhci.h' line='1945' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='59520'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='drivers/usb/host/xhci.h' line='1944' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='drivers/usb/host/xhci.h' line='1946' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='59584'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='drivers/usb/host/xhci.h' line='1945' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='drivers/usb/host/xhci.h' line='1947' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='59648'>
-          <var-decl name='priv' type-id='c99b5ecd' visibility='default' filepath='drivers/usb/host/xhci.h' line='1948' column='1'/>
+          <var-decl name='priv' type-id='c99b5ecd' visibility='default' filepath='drivers/usb/host/xhci.h' line='1950' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='439a4d86' size-in-bits='64' id='b8fa1170'/>
@@ -83596,12 +83756,12 @@
       <pointer-type-def type-id='3e7a7dc5' size-in-bits='64' id='b94ac371'/>
       <pointer-type-def type-id='d10e968a' size-in-bits='64' id='b94e5398'/>
       <pointer-type-def type-id='1f8bced9' size-in-bits='64' id='b9526cc1'/>
-      <class-decl name='gro_list' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='314' column='1' id='b9535066'>
+      <class-decl name='gro_list' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='316' column='1' id='b9535066'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='315' column='1'/>
+          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='317' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='count' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='316' column='1'/>
+          <var-decl name='count' type-id='95e97e5e' visibility='default' filepath='include/linux/netdevice.h' line='318' column='1'/>
         </data-member>
       </class-decl>
       <qualified-type-def type-id='ac76d92d' const='yes' id='b954583a'/>
@@ -83689,15 +83849,15 @@
       <pointer-type-def type-id='08cd0705' size-in-bits='64' id='b97350f1'/>
       <pointer-type-def type-id='e7ff163c' size-in-bits='64' id='b975d8ee'/>
       <pointer-type-def type-id='1b0b5250' size-in-bits='64' id='b977ca56'/>
-      <union-decl name='__anonymous_union__' size-in-bits='16' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='898' column='1' id='b97daab4'>
+      <union-decl name='__anonymous_union__' size-in-bits='16' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='900' column='1' id='b97daab4'>
         <data-member access='public'>
-          <var-decl name='inner_protocol' type-id='84a5c3d4' visibility='default' filepath='include/linux/skbuff.h' line='899' column='1'/>
+          <var-decl name='inner_protocol' type-id='84a5c3d4' visibility='default' filepath='include/linux/skbuff.h' line='901' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='inner_ipproto' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='900' column='1'/>
+          <var-decl name='inner_ipproto' type-id='8f048e17' visibility='default' filepath='include/linux/skbuff.h' line='902' column='1'/>
         </data-member>
       </union-decl>
-      <enum-decl name='usb_device_removable' filepath='include/linux/usb.h' line='492' column='1' id='b9886e9f'>
+      <enum-decl name='usb_device_removable' filepath='include/linux/usb.h' line='497' column='1' id='b9886e9f'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='USB_DEVICE_REMOVABLE_UNKNOWN' value='0'/>
         <enumerator name='USB_DEVICE_REMOVABLE' value='1'/>
@@ -83895,254 +84055,254 @@
           <var-decl name='mask' type-id='69281b5f' visibility='default' filepath='include/net/flow_offload.h' line='48' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='event_subsystem' size-in-bits='320' is-struct='yes' visibility='default' filepath='kernel/trace/trace.h' line='1433' column='1' id='ba400603'>
+      <class-decl name='event_subsystem' size-in-bits='320' is-struct='yes' visibility='default' filepath='kernel/trace/trace.h' line='1434' column='1' id='ba400603'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='kernel/trace/trace.h' line='1434' column='1'/>
+          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='kernel/trace/trace.h' line='1435' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='name' type-id='80f4b756' visibility='default' filepath='kernel/trace/trace.h' line='1435' column='1'/>
+          <var-decl name='name' type-id='80f4b756' visibility='default' filepath='kernel/trace/trace.h' line='1436' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='filter' type-id='26461068' visibility='default' filepath='kernel/trace/trace.h' line='1436' column='1'/>
+          <var-decl name='filter' type-id='26461068' visibility='default' filepath='kernel/trace/trace.h' line='1437' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='ref_count' type-id='95e97e5e' visibility='default' filepath='kernel/trace/trace.h' line='1437' column='1'/>
+          <var-decl name='ref_count' type-id='95e97e5e' visibility='default' filepath='kernel/trace/trace.h' line='1438' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='net_device_ops' size-in-bits='4992' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='1321' column='1' id='ba44c7d8'>
+      <class-decl name='net_device_ops' size-in-bits='4992' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='1326' column='1' id='ba44c7d8'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='ndo_init' type-id='2555df59' visibility='default' filepath='include/linux/netdevice.h' line='1322' column='1'/>
+          <var-decl name='ndo_init' type-id='2555df59' visibility='default' filepath='include/linux/netdevice.h' line='1327' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='ndo_uninit' type-id='548eee3a' visibility='default' filepath='include/linux/netdevice.h' line='1323' column='1'/>
+          <var-decl name='ndo_uninit' type-id='548eee3a' visibility='default' filepath='include/linux/netdevice.h' line='1328' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='ndo_open' type-id='2555df59' visibility='default' filepath='include/linux/netdevice.h' line='1324' column='1'/>
+          <var-decl name='ndo_open' type-id='2555df59' visibility='default' filepath='include/linux/netdevice.h' line='1329' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='ndo_stop' type-id='2555df59' visibility='default' filepath='include/linux/netdevice.h' line='1325' column='1'/>
+          <var-decl name='ndo_stop' type-id='2555df59' visibility='default' filepath='include/linux/netdevice.h' line='1330' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='ndo_start_xmit' type-id='bd3f3f93' visibility='default' filepath='include/linux/netdevice.h' line='1326' column='1'/>
+          <var-decl name='ndo_start_xmit' type-id='bd3f3f93' visibility='default' filepath='include/linux/netdevice.h' line='1331' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='ndo_features_check' type-id='7a0ed254' visibility='default' filepath='include/linux/netdevice.h' line='1328' column='1'/>
+          <var-decl name='ndo_features_check' type-id='7a0ed254' visibility='default' filepath='include/linux/netdevice.h' line='1333' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='ndo_select_queue' type-id='de36db77' visibility='default' filepath='include/linux/netdevice.h' line='1331' column='1'/>
+          <var-decl name='ndo_select_queue' type-id='de36db77' visibility='default' filepath='include/linux/netdevice.h' line='1336' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='ndo_change_rx_flags' type-id='c7c94ce1' visibility='default' filepath='include/linux/netdevice.h' line='1334' column='1'/>
+          <var-decl name='ndo_change_rx_flags' type-id='c7c94ce1' visibility='default' filepath='include/linux/netdevice.h' line='1339' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='ndo_set_rx_mode' type-id='548eee3a' visibility='default' filepath='include/linux/netdevice.h' line='1336' column='1'/>
+          <var-decl name='ndo_set_rx_mode' type-id='548eee3a' visibility='default' filepath='include/linux/netdevice.h' line='1341' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='ndo_set_mac_address' type-id='f4dd5cc5' visibility='default' filepath='include/linux/netdevice.h' line='1337' column='1'/>
+          <var-decl name='ndo_set_mac_address' type-id='f4dd5cc5' visibility='default' filepath='include/linux/netdevice.h' line='1342' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='ndo_validate_addr' type-id='2555df59' visibility='default' filepath='include/linux/netdevice.h' line='1339' column='1'/>
+          <var-decl name='ndo_validate_addr' type-id='2555df59' visibility='default' filepath='include/linux/netdevice.h' line='1344' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='ndo_do_ioctl' type-id='cc325be7' visibility='default' filepath='include/linux/netdevice.h' line='1340' column='1'/>
+          <var-decl name='ndo_do_ioctl' type-id='cc325be7' visibility='default' filepath='include/linux/netdevice.h' line='1345' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='ndo_set_config' type-id='bd2d1eba' visibility='default' filepath='include/linux/netdevice.h' line='1342' column='1'/>
+          <var-decl name='ndo_set_config' type-id='bd2d1eba' visibility='default' filepath='include/linux/netdevice.h' line='1347' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='ndo_change_mtu' type-id='d6762aa0' visibility='default' filepath='include/linux/netdevice.h' line='1344' column='1'/>
+          <var-decl name='ndo_change_mtu' type-id='d6762aa0' visibility='default' filepath='include/linux/netdevice.h' line='1349' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='ndo_neigh_setup' type-id='5c9f2a92' visibility='default' filepath='include/linux/netdevice.h' line='1346' column='1'/>
+          <var-decl name='ndo_neigh_setup' type-id='5c9f2a92' visibility='default' filepath='include/linux/netdevice.h' line='1351' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='ndo_tx_timeout' type-id='06cd5b60' visibility='default' filepath='include/linux/netdevice.h' line='1348' column='1'/>
+          <var-decl name='ndo_tx_timeout' type-id='06cd5b60' visibility='default' filepath='include/linux/netdevice.h' line='1353' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='ndo_get_stats64' type-id='cb4c6db1' visibility='default' filepath='include/linux/netdevice.h' line='1351' column='1'/>
+          <var-decl name='ndo_get_stats64' type-id='cb4c6db1' visibility='default' filepath='include/linux/netdevice.h' line='1356' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1088'>
-          <var-decl name='ndo_has_offload_stats' type-id='e95fd96b' visibility='default' filepath='include/linux/netdevice.h' line='1353' column='1'/>
+          <var-decl name='ndo_has_offload_stats' type-id='e95fd96b' visibility='default' filepath='include/linux/netdevice.h' line='1358' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='ndo_get_offload_stats' type-id='f98694f9' visibility='default' filepath='include/linux/netdevice.h' line='1354' column='1'/>
+          <var-decl name='ndo_get_offload_stats' type-id='f98694f9' visibility='default' filepath='include/linux/netdevice.h' line='1359' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='ndo_get_stats' type-id='3217f9ba' visibility='default' filepath='include/linux/netdevice.h' line='1357' column='1'/>
+          <var-decl name='ndo_get_stats' type-id='3217f9ba' visibility='default' filepath='include/linux/netdevice.h' line='1362' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1280'>
-          <var-decl name='ndo_vlan_rx_add_vid' type-id='4fcb4c39' visibility='default' filepath='include/linux/netdevice.h' line='1359' column='1'/>
+          <var-decl name='ndo_vlan_rx_add_vid' type-id='4fcb4c39' visibility='default' filepath='include/linux/netdevice.h' line='1364' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1344'>
-          <var-decl name='ndo_vlan_rx_kill_vid' type-id='4fcb4c39' visibility='default' filepath='include/linux/netdevice.h' line='1361' column='1'/>
+          <var-decl name='ndo_vlan_rx_kill_vid' type-id='4fcb4c39' visibility='default' filepath='include/linux/netdevice.h' line='1366' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1408'>
-          <var-decl name='ndo_set_vf_mac' type-id='bae60bcf' visibility='default' filepath='include/linux/netdevice.h' line='1369' column='1'/>
+          <var-decl name='ndo_set_vf_mac' type-id='bae60bcf' visibility='default' filepath='include/linux/netdevice.h' line='1374' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1472'>
-          <var-decl name='ndo_set_vf_vlan' type-id='699131d0' visibility='default' filepath='include/linux/netdevice.h' line='1371' column='1'/>
+          <var-decl name='ndo_set_vf_vlan' type-id='699131d0' visibility='default' filepath='include/linux/netdevice.h' line='1376' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='ndo_set_vf_rate' type-id='7cd466e6' visibility='default' filepath='include/linux/netdevice.h' line='1374' column='1'/>
+          <var-decl name='ndo_set_vf_rate' type-id='7cd466e6' visibility='default' filepath='include/linux/netdevice.h' line='1379' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1600'>
-          <var-decl name='ndo_set_vf_spoofchk' type-id='0c16aca1' visibility='default' filepath='include/linux/netdevice.h' line='1377' column='1'/>
+          <var-decl name='ndo_set_vf_spoofchk' type-id='0c16aca1' visibility='default' filepath='include/linux/netdevice.h' line='1382' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1664'>
-          <var-decl name='ndo_set_vf_trust' type-id='0c16aca1' visibility='default' filepath='include/linux/netdevice.h' line='1379' column='1'/>
+          <var-decl name='ndo_set_vf_trust' type-id='0c16aca1' visibility='default' filepath='include/linux/netdevice.h' line='1384' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1728'>
-          <var-decl name='ndo_get_vf_config' type-id='d22f8cbe' visibility='default' filepath='include/linux/netdevice.h' line='1381' column='1'/>
+          <var-decl name='ndo_get_vf_config' type-id='d22f8cbe' visibility='default' filepath='include/linux/netdevice.h' line='1386' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1792'>
-          <var-decl name='ndo_set_vf_link_state' type-id='b54cfa0f' visibility='default' filepath='include/linux/netdevice.h' line='1384' column='1'/>
+          <var-decl name='ndo_set_vf_link_state' type-id='b54cfa0f' visibility='default' filepath='include/linux/netdevice.h' line='1389' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1856'>
-          <var-decl name='ndo_get_vf_stats' type-id='eee971fd' visibility='default' filepath='include/linux/netdevice.h' line='1386' column='1'/>
+          <var-decl name='ndo_get_vf_stats' type-id='eee971fd' visibility='default' filepath='include/linux/netdevice.h' line='1391' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1920'>
-          <var-decl name='ndo_set_vf_port' type-id='af60ef81' visibility='default' filepath='include/linux/netdevice.h' line='1390' column='1'/>
+          <var-decl name='ndo_set_vf_port' type-id='af60ef81' visibility='default' filepath='include/linux/netdevice.h' line='1395' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1984'>
-          <var-decl name='ndo_get_vf_port' type-id='be55abd8' visibility='default' filepath='include/linux/netdevice.h' line='1393' column='1'/>
+          <var-decl name='ndo_get_vf_port' type-id='be55abd8' visibility='default' filepath='include/linux/netdevice.h' line='1398' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2048'>
-          <var-decl name='ndo_get_vf_guid' type-id='cba114b6' visibility='default' filepath='include/linux/netdevice.h' line='1395' column='1'/>
+          <var-decl name='ndo_get_vf_guid' type-id='cba114b6' visibility='default' filepath='include/linux/netdevice.h' line='1400' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2112'>
-          <var-decl name='ndo_set_vf_guid' type-id='0617ad2b' visibility='default' filepath='include/linux/netdevice.h' line='1399' column='1'/>
+          <var-decl name='ndo_set_vf_guid' type-id='0617ad2b' visibility='default' filepath='include/linux/netdevice.h' line='1404' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2176'>
-          <var-decl name='ndo_set_vf_rss_query_en' type-id='0c16aca1' visibility='default' filepath='include/linux/netdevice.h' line='1402' column='1'/>
+          <var-decl name='ndo_set_vf_rss_query_en' type-id='0c16aca1' visibility='default' filepath='include/linux/netdevice.h' line='1407' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2240'>
-          <var-decl name='ndo_setup_tc' type-id='06b83346' visibility='default' filepath='include/linux/netdevice.h' line='1405' column='1'/>
+          <var-decl name='ndo_setup_tc' type-id='06b83346' visibility='default' filepath='include/linux/netdevice.h' line='1410' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2304'>
-          <var-decl name='ndo_rx_flow_steer' type-id='47498e6c' visibility='default' filepath='include/linux/netdevice.h' line='1433' column='1'/>
+          <var-decl name='ndo_rx_flow_steer' type-id='47498e6c' visibility='default' filepath='include/linux/netdevice.h' line='1438' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2368'>
-          <var-decl name='ndo_add_slave' type-id='031fe454' visibility='default' filepath='include/linux/netdevice.h' line='1438' column='1'/>
+          <var-decl name='ndo_add_slave' type-id='031fe454' visibility='default' filepath='include/linux/netdevice.h' line='1443' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2432'>
-          <var-decl name='ndo_del_slave' type-id='ed3019e9' visibility='default' filepath='include/linux/netdevice.h' line='1441' column='1'/>
+          <var-decl name='ndo_del_slave' type-id='ed3019e9' visibility='default' filepath='include/linux/netdevice.h' line='1446' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2496'>
-          <var-decl name='ndo_get_xmit_slave' type-id='5a1f42f3' visibility='default' filepath='include/linux/netdevice.h' line='1443' column='1'/>
+          <var-decl name='ndo_get_xmit_slave' type-id='5a1f42f3' visibility='default' filepath='include/linux/netdevice.h' line='1448' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2560'>
-          <var-decl name='ndo_fix_features' type-id='4a028f44' visibility='default' filepath='include/linux/netdevice.h' line='1446' column='1'/>
+          <var-decl name='ndo_fix_features' type-id='4a028f44' visibility='default' filepath='include/linux/netdevice.h' line='1451' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2624'>
-          <var-decl name='ndo_set_features' type-id='10dae4c5' visibility='default' filepath='include/linux/netdevice.h' line='1448' column='1'/>
+          <var-decl name='ndo_set_features' type-id='10dae4c5' visibility='default' filepath='include/linux/netdevice.h' line='1453' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2688'>
-          <var-decl name='ndo_neigh_construct' type-id='92446276' visibility='default' filepath='include/linux/netdevice.h' line='1450' column='1'/>
+          <var-decl name='ndo_neigh_construct' type-id='92446276' visibility='default' filepath='include/linux/netdevice.h' line='1455' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2752'>
-          <var-decl name='ndo_neigh_destroy' type-id='11e89fb9' visibility='default' filepath='include/linux/netdevice.h' line='1452' column='1'/>
+          <var-decl name='ndo_neigh_destroy' type-id='11e89fb9' visibility='default' filepath='include/linux/netdevice.h' line='1457' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2816'>
-          <var-decl name='ndo_fdb_add' type-id='5ffcd66c' visibility='default' filepath='include/linux/netdevice.h' line='1455' column='1'/>
+          <var-decl name='ndo_fdb_add' type-id='5ffcd66c' visibility='default' filepath='include/linux/netdevice.h' line='1460' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2880'>
-          <var-decl name='ndo_fdb_del' type-id='e6032f80' visibility='default' filepath='include/linux/netdevice.h' line='1462' column='1'/>
+          <var-decl name='ndo_fdb_del' type-id='e6032f80' visibility='default' filepath='include/linux/netdevice.h' line='1467' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2944'>
-          <var-decl name='ndo_fdb_dump' type-id='147cd5a7' visibility='default' filepath='include/linux/netdevice.h' line='1467' column='1'/>
+          <var-decl name='ndo_fdb_dump' type-id='147cd5a7' visibility='default' filepath='include/linux/netdevice.h' line='1472' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3008'>
-          <var-decl name='ndo_fdb_get' type-id='6537d478' visibility='default' filepath='include/linux/netdevice.h' line='1472' column='1'/>
+          <var-decl name='ndo_fdb_get' type-id='6537d478' visibility='default' filepath='include/linux/netdevice.h' line='1477' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3072'>
-          <var-decl name='ndo_bridge_setlink' type-id='50756496' visibility='default' filepath='include/linux/netdevice.h' line='1478' column='1'/>
+          <var-decl name='ndo_bridge_setlink' type-id='50756496' visibility='default' filepath='include/linux/netdevice.h' line='1483' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3136'>
-          <var-decl name='ndo_bridge_getlink' type-id='e78e01a9' visibility='default' filepath='include/linux/netdevice.h' line='1482' column='1'/>
+          <var-decl name='ndo_bridge_getlink' type-id='e78e01a9' visibility='default' filepath='include/linux/netdevice.h' line='1487' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3200'>
-          <var-decl name='ndo_bridge_dellink' type-id='1223555b' visibility='default' filepath='include/linux/netdevice.h' line='1487' column='1'/>
+          <var-decl name='ndo_bridge_dellink' type-id='1223555b' visibility='default' filepath='include/linux/netdevice.h' line='1492' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3264'>
-          <var-decl name='ndo_change_carrier' type-id='e36088ec' visibility='default' filepath='include/linux/netdevice.h' line='1490' column='1'/>
+          <var-decl name='ndo_change_carrier' type-id='e36088ec' visibility='default' filepath='include/linux/netdevice.h' line='1495' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3328'>
-          <var-decl name='ndo_get_phys_port_id' type-id='98252144' visibility='default' filepath='include/linux/netdevice.h' line='1492' column='1'/>
+          <var-decl name='ndo_get_phys_port_id' type-id='98252144' visibility='default' filepath='include/linux/netdevice.h' line='1497' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3392'>
-          <var-decl name='ndo_get_port_parent_id' type-id='98252144' visibility='default' filepath='include/linux/netdevice.h' line='1494' column='1'/>
+          <var-decl name='ndo_get_port_parent_id' type-id='98252144' visibility='default' filepath='include/linux/netdevice.h' line='1499' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3456'>
-          <var-decl name='ndo_get_phys_port_name' type-id='5139dd84' visibility='default' filepath='include/linux/netdevice.h' line='1496' column='1'/>
+          <var-decl name='ndo_get_phys_port_name' type-id='5139dd84' visibility='default' filepath='include/linux/netdevice.h' line='1501' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3520'>
-          <var-decl name='ndo_udp_tunnel_add' type-id='a43821b9' visibility='default' filepath='include/linux/netdevice.h' line='1498' column='1'/>
+          <var-decl name='ndo_udp_tunnel_add' type-id='a43821b9' visibility='default' filepath='include/linux/netdevice.h' line='1503' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3584'>
-          <var-decl name='ndo_udp_tunnel_del' type-id='a43821b9' visibility='default' filepath='include/linux/netdevice.h' line='1500' column='1'/>
+          <var-decl name='ndo_udp_tunnel_del' type-id='a43821b9' visibility='default' filepath='include/linux/netdevice.h' line='1505' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3648'>
-          <var-decl name='ndo_dfwd_add_station' type-id='e2d7f258' visibility='default' filepath='include/linux/netdevice.h' line='1502' column='1'/>
+          <var-decl name='ndo_dfwd_add_station' type-id='e2d7f258' visibility='default' filepath='include/linux/netdevice.h' line='1507' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3712'>
-          <var-decl name='ndo_dfwd_del_station' type-id='5ac7baf4' visibility='default' filepath='include/linux/netdevice.h' line='1504' column='1'/>
+          <var-decl name='ndo_dfwd_del_station' type-id='5ac7baf4' visibility='default' filepath='include/linux/netdevice.h' line='1509' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3776'>
-          <var-decl name='ndo_set_tx_maxrate' type-id='c1e0b02f' visibility='default' filepath='include/linux/netdevice.h' line='1507' column='1'/>
+          <var-decl name='ndo_set_tx_maxrate' type-id='c1e0b02f' visibility='default' filepath='include/linux/netdevice.h' line='1512' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3840'>
-          <var-decl name='ndo_get_iflink' type-id='4753b592' visibility='default' filepath='include/linux/netdevice.h' line='1510' column='1'/>
+          <var-decl name='ndo_get_iflink' type-id='4753b592' visibility='default' filepath='include/linux/netdevice.h' line='1515' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3904'>
-          <var-decl name='ndo_change_proto_down' type-id='e36088ec' visibility='default' filepath='include/linux/netdevice.h' line='1511' column='1'/>
+          <var-decl name='ndo_change_proto_down' type-id='e36088ec' visibility='default' filepath='include/linux/netdevice.h' line='1516' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3968'>
-          <var-decl name='ndo_fill_metadata_dst' type-id='2cc5a575' visibility='default' filepath='include/linux/netdevice.h' line='1513' column='1'/>
+          <var-decl name='ndo_fill_metadata_dst' type-id='2cc5a575' visibility='default' filepath='include/linux/netdevice.h' line='1518' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4032'>
-          <var-decl name='ndo_set_rx_headroom' type-id='c7c94ce1' visibility='default' filepath='include/linux/netdevice.h' line='1515' column='1'/>
+          <var-decl name='ndo_set_rx_headroom' type-id='c7c94ce1' visibility='default' filepath='include/linux/netdevice.h' line='1520' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4096'>
-          <var-decl name='ndo_bpf' type-id='49f84764' visibility='default' filepath='include/linux/netdevice.h' line='1517' column='1'/>
+          <var-decl name='ndo_bpf' type-id='49f84764' visibility='default' filepath='include/linux/netdevice.h' line='1522' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4160'>
-          <var-decl name='ndo_xdp_xmit' type-id='0c7d25ff' visibility='default' filepath='include/linux/netdevice.h' line='1519' column='1'/>
+          <var-decl name='ndo_xdp_xmit' type-id='0c7d25ff' visibility='default' filepath='include/linux/netdevice.h' line='1524' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4224'>
-          <var-decl name='ndo_xsk_wakeup' type-id='149f0e1f' visibility='default' filepath='include/linux/netdevice.h' line='1522' column='1'/>
+          <var-decl name='ndo_xsk_wakeup' type-id='149f0e1f' visibility='default' filepath='include/linux/netdevice.h' line='1527' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4288'>
-          <var-decl name='ndo_get_devlink_port' type-id='cd97030f' visibility='default' filepath='include/linux/netdevice.h' line='1524' column='1'/>
+          <var-decl name='ndo_get_devlink_port' type-id='cd97030f' visibility='default' filepath='include/linux/netdevice.h' line='1529' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4352'>
-          <var-decl name='ndo_tunnel_ctl' type-id='2fc899e9' visibility='default' filepath='include/linux/netdevice.h' line='1525' column='1'/>
+          <var-decl name='ndo_tunnel_ctl' type-id='2fc899e9' visibility='default' filepath='include/linux/netdevice.h' line='1530' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4416'>
-          <var-decl name='ndo_get_peer_dev' type-id='f1b37e8e' visibility='default' filepath='include/linux/netdevice.h' line='1527' column='1'/>
+          <var-decl name='ndo_get_peer_dev' type-id='f1b37e8e' visibility='default' filepath='include/linux/netdevice.h' line='1532' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4480'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1529' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1534' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4544'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1530' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1535' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4608'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1531' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1536' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4672'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1532' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1537' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4736'>
-          <var-decl name='android_kabi_reserved5' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1533' column='1'/>
+          <var-decl name='android_kabi_reserved5' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1538' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4800'>
-          <var-decl name='android_kabi_reserved6' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1534' column='1'/>
+          <var-decl name='android_kabi_reserved6' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1539' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4864'>
-          <var-decl name='android_kabi_reserved7' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1535' column='1'/>
+          <var-decl name='android_kabi_reserved7' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1540' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4928'>
-          <var-decl name='android_kabi_reserved8' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1536' column='1'/>
+          <var-decl name='android_kabi_reserved8' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='1541' column='1'/>
         </data-member>
       </class-decl>
       <array-type-def dimensions='1' type-id='8f048e17' size-in-bits='272' id='ba592c87'>
@@ -84268,12 +84428,12 @@
           <var-decl name='height' type-id='3f1a6b60' visibility='default' filepath='include/uapi/linux/videodev2.h' line='428' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='irq_affinity_desc' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/interrupt.h' line='308' column='1' id='bab69d9a'>
+      <class-decl name='irq_affinity_desc' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/interrupt.h' line='312' column='1' id='bab69d9a'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='mask' type-id='1354385d' visibility='default' filepath='include/linux/interrupt.h' line='309' column='1'/>
+          <var-decl name='mask' type-id='1354385d' visibility='default' filepath='include/linux/interrupt.h' line='313' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='is_managed' type-id='f0981eeb' visibility='default' filepath='include/linux/interrupt.h' line='310' column='1'/>
+          <var-decl name='is_managed' type-id='f0981eeb' visibility='default' filepath='include/linux/interrupt.h' line='314' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='__anonymous_struct__' size-in-bits='32' is-struct='yes' is-anonymous='yes' naming-typedef-id='094d8048' visibility='default' filepath='include/linux/uidgid.h' line='26' column='1' id='bac1227a'>
@@ -84491,6 +84651,32 @@
         <parameter type-id='d61bf978'/>
         <return type-id='95e97e5e'/>
       </function-type>
+      <class-decl name='psi_trigger' size-in-bits='896' is-struct='yes' visibility='default' filepath='include/linux/psi_types.h' line='104' column='1' id='bb5ec78c'>
+        <data-member access='public' layout-offset-in-bits='0'>
+          <var-decl name='state' type-id='6797a017' visibility='default' filepath='include/linux/psi_types.h' line='106' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='64'>
+          <var-decl name='threshold' type-id='91ce1af9' visibility='default' filepath='include/linux/psi_types.h' line='109' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='128'>
+          <var-decl name='node' type-id='72f469ec' visibility='default' filepath='include/linux/psi_types.h' line='112' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='256'>
+          <var-decl name='group' type-id='316cdcd3' visibility='default' filepath='include/linux/psi_types.h' line='115' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='320'>
+          <var-decl name='event_wait' type-id='b5ab048f' visibility='default' filepath='include/linux/psi_types.h' line='118' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='512'>
+          <var-decl name='event' type-id='95e97e5e' visibility='default' filepath='include/linux/psi_types.h' line='121' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='576'>
+          <var-decl name='win' type-id='722d6f6c' visibility='default' filepath='include/linux/psi_types.h' line='124' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='832'>
+          <var-decl name='last_event_time' type-id='91ce1af9' visibility='default' filepath='include/linux/psi_types.h' line='130' column='1'/>
+        </data-member>
+      </class-decl>
       <pointer-type-def type-id='170bab5e' size-in-bits='64' id='bb5ee79c'/>
       <pointer-type-def type-id='602fd1a9' size-in-bits='64' id='bb6de7e1'/>
       <class-decl name='__call_single_data' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/smp.h' line='23' column='1' id='bb75ea85'>
@@ -84628,18 +84814,18 @@
         <return type-id='4bdecfd7'/>
       </function-type>
       <pointer-type-def type-id='c83cb72c' size-in-bits='64' id='bc0ca82e'/>
-      <class-decl name='ubuf_info' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/skbuff.h' line='465' column='1' id='bc0d33fe'>
+      <class-decl name='ubuf_info' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/skbuff.h' line='466' column='1' id='bc0d33fe'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='callback' type-id='fc30e234' visibility='default' filepath='include/linux/skbuff.h' line='466' column='1'/>
+          <var-decl name='callback' type-id='fc30e234' visibility='default' filepath='include/linux/skbuff.h' line='467' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='' type-id='a27049de' visibility='default' filepath='include/linux/skbuff.h' line='467' column='1'/>
+          <var-decl name='' type-id='a27049de' visibility='default' filepath='include/linux/skbuff.h' line='468' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='refcnt' type-id='64615833' visibility='default' filepath='include/linux/skbuff.h' line='479' column='1'/>
+          <var-decl name='refcnt' type-id='64615833' visibility='default' filepath='include/linux/skbuff.h' line='480' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='mmp' type-id='0009269e' visibility='default' filepath='include/linux/skbuff.h' line='484' column='1'/>
+          <var-decl name='mmp' type-id='0009269e' visibility='default' filepath='include/linux/skbuff.h' line='485' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='075857e5' size-in-bits='64' id='bc155125'/>
@@ -84658,213 +84844,213 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='bca91994' size-in-bits='64' id='bc33861a'/>
-      <class-decl name='super_block' size-in-bits='12800' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='1450' column='1' id='bc39a8be'>
+      <class-decl name='super_block' size-in-bits='12800' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='1456' column='1' id='bc39a8be'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='s_list' type-id='72f469ec' visibility='default' filepath='include/linux/fs.h' line='1451' column='1'/>
+          <var-decl name='s_list' type-id='72f469ec' visibility='default' filepath='include/linux/fs.h' line='1457' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='s_dev' type-id='8504f260' visibility='default' filepath='include/linux/fs.h' line='1452' column='1'/>
+          <var-decl name='s_dev' type-id='8504f260' visibility='default' filepath='include/linux/fs.h' line='1458' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='160'>
-          <var-decl name='s_blocksize_bits' type-id='002ac4a6' visibility='default' filepath='include/linux/fs.h' line='1453' column='1'/>
+          <var-decl name='s_blocksize_bits' type-id='002ac4a6' visibility='default' filepath='include/linux/fs.h' line='1459' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='s_blocksize' type-id='7359adad' visibility='default' filepath='include/linux/fs.h' line='1454' column='1'/>
+          <var-decl name='s_blocksize' type-id='7359adad' visibility='default' filepath='include/linux/fs.h' line='1460' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='s_maxbytes' type-id='69bf7bee' visibility='default' filepath='include/linux/fs.h' line='1455' column='1'/>
+          <var-decl name='s_maxbytes' type-id='69bf7bee' visibility='default' filepath='include/linux/fs.h' line='1461' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='s_type' type-id='21e53d44' visibility='default' filepath='include/linux/fs.h' line='1456' column='1'/>
+          <var-decl name='s_type' type-id='21e53d44' visibility='default' filepath='include/linux/fs.h' line='1462' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='s_op' type-id='f7c6dcac' visibility='default' filepath='include/linux/fs.h' line='1457' column='1'/>
+          <var-decl name='s_op' type-id='f7c6dcac' visibility='default' filepath='include/linux/fs.h' line='1463' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='dq_op' type-id='85741a2a' visibility='default' filepath='include/linux/fs.h' line='1458' column='1'/>
+          <var-decl name='dq_op' type-id='85741a2a' visibility='default' filepath='include/linux/fs.h' line='1464' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='s_qcop' type-id='2cb49514' visibility='default' filepath='include/linux/fs.h' line='1459' column='1'/>
+          <var-decl name='s_qcop' type-id='2cb49514' visibility='default' filepath='include/linux/fs.h' line='1465' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='s_export_op' type-id='ab932c45' visibility='default' filepath='include/linux/fs.h' line='1460' column='1'/>
+          <var-decl name='s_export_op' type-id='ab932c45' visibility='default' filepath='include/linux/fs.h' line='1466' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='s_flags' type-id='7359adad' visibility='default' filepath='include/linux/fs.h' line='1461' column='1'/>
+          <var-decl name='s_flags' type-id='7359adad' visibility='default' filepath='include/linux/fs.h' line='1467' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='s_iflags' type-id='7359adad' visibility='default' filepath='include/linux/fs.h' line='1462' column='1'/>
+          <var-decl name='s_iflags' type-id='7359adad' visibility='default' filepath='include/linux/fs.h' line='1468' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='s_magic' type-id='7359adad' visibility='default' filepath='include/linux/fs.h' line='1463' column='1'/>
+          <var-decl name='s_magic' type-id='7359adad' visibility='default' filepath='include/linux/fs.h' line='1469' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='s_root' type-id='27675065' visibility='default' filepath='include/linux/fs.h' line='1464' column='1'/>
+          <var-decl name='s_root' type-id='27675065' visibility='default' filepath='include/linux/fs.h' line='1470' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='s_umount' type-id='f19fdb93' visibility='default' filepath='include/linux/fs.h' line='1465' column='1'/>
+          <var-decl name='s_umount' type-id='f19fdb93' visibility='default' filepath='include/linux/fs.h' line='1471' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1408'>
-          <var-decl name='s_count' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='1466' column='1'/>
+          <var-decl name='s_count' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='1472' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1440'>
-          <var-decl name='s_active' type-id='49178f86' visibility='default' filepath='include/linux/fs.h' line='1467' column='1'/>
+          <var-decl name='s_active' type-id='49178f86' visibility='default' filepath='include/linux/fs.h' line='1473' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1472'>
-          <var-decl name='s_security' type-id='eaa32e2f' visibility='default' filepath='include/linux/fs.h' line='1469' column='1'/>
+          <var-decl name='s_security' type-id='eaa32e2f' visibility='default' filepath='include/linux/fs.h' line='1475' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='s_xattr' type-id='cb49d4b8' visibility='default' filepath='include/linux/fs.h' line='1471' column='1'/>
+          <var-decl name='s_xattr' type-id='cb49d4b8' visibility='default' filepath='include/linux/fs.h' line='1477' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1600'>
-          <var-decl name='s_cop' type-id='8d31a8d6' visibility='default' filepath='include/linux/fs.h' line='1473' column='1'/>
+          <var-decl name='s_cop' type-id='8d31a8d6' visibility='default' filepath='include/linux/fs.h' line='1479' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1664'>
-          <var-decl name='s_master_keys' type-id='c14b7eb6' visibility='default' filepath='include/linux/fs.h' line='1482' column='1'/>
+          <var-decl name='s_master_keys' type-id='c14b7eb6' visibility='default' filepath='include/linux/fs.h' line='1488' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1728'>
-          <var-decl name='s_vop' type-id='e3008443' visibility='default' filepath='include/linux/fs.h' line='1486' column='1'/>
+          <var-decl name='s_vop' type-id='e3008443' visibility='default' filepath='include/linux/fs.h' line='1492' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1792'>
-          <var-decl name='s_encoding' type-id='72835629' visibility='default' filepath='include/linux/fs.h' line='1489' column='1'/>
+          <var-decl name='s_encoding' type-id='72835629' visibility='default' filepath='include/linux/fs.h' line='1495' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1856'>
-          <var-decl name='s_encoding_flags' type-id='d315442e' visibility='default' filepath='include/linux/fs.h' line='1490' column='1'/>
+          <var-decl name='s_encoding_flags' type-id='d315442e' visibility='default' filepath='include/linux/fs.h' line='1496' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1920'>
-          <var-decl name='s_roots' type-id='def98e71' visibility='default' filepath='include/linux/fs.h' line='1492' column='1'/>
+          <var-decl name='s_roots' type-id='def98e71' visibility='default' filepath='include/linux/fs.h' line='1498' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1984'>
-          <var-decl name='s_mounts' type-id='72f469ec' visibility='default' filepath='include/linux/fs.h' line='1493' column='1'/>
+          <var-decl name='s_mounts' type-id='72f469ec' visibility='default' filepath='include/linux/fs.h' line='1499' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2112'>
-          <var-decl name='s_bdev' type-id='b88dd945' visibility='default' filepath='include/linux/fs.h' line='1494' column='1'/>
+          <var-decl name='s_bdev' type-id='b88dd945' visibility='default' filepath='include/linux/fs.h' line='1500' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2176'>
-          <var-decl name='s_bdi' type-id='ef4fae1b' visibility='default' filepath='include/linux/fs.h' line='1495' column='1'/>
+          <var-decl name='s_bdi' type-id='ef4fae1b' visibility='default' filepath='include/linux/fs.h' line='1501' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2240'>
-          <var-decl name='s_mtd' type-id='58ed56f5' visibility='default' filepath='include/linux/fs.h' line='1496' column='1'/>
+          <var-decl name='s_mtd' type-id='58ed56f5' visibility='default' filepath='include/linux/fs.h' line='1502' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2304'>
-          <var-decl name='s_instances' type-id='03a4a074' visibility='default' filepath='include/linux/fs.h' line='1497' column='1'/>
+          <var-decl name='s_instances' type-id='03a4a074' visibility='default' filepath='include/linux/fs.h' line='1503' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2432'>
-          <var-decl name='s_quota_types' type-id='f0981eeb' visibility='default' filepath='include/linux/fs.h' line='1498' column='1'/>
+          <var-decl name='s_quota_types' type-id='f0981eeb' visibility='default' filepath='include/linux/fs.h' line='1504' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2496'>
-          <var-decl name='s_dquot' type-id='c26e4ad8' visibility='default' filepath='include/linux/fs.h' line='1499' column='1'/>
+          <var-decl name='s_dquot' type-id='c26e4ad8' visibility='default' filepath='include/linux/fs.h' line='1505' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5184'>
-          <var-decl name='s_writers' type-id='fb476a2b' visibility='default' filepath='include/linux/fs.h' line='1501' column='1'/>
+          <var-decl name='s_writers' type-id='fb476a2b' visibility='default' filepath='include/linux/fs.h' line='1507' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7744'>
-          <var-decl name='s_fs_info' type-id='eaa32e2f' visibility='default' filepath='include/linux/fs.h' line='1508' column='1'/>
+          <var-decl name='s_fs_info' type-id='eaa32e2f' visibility='default' filepath='include/linux/fs.h' line='1514' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7808'>
-          <var-decl name='s_time_gran' type-id='19c2251e' visibility='default' filepath='include/linux/fs.h' line='1511' column='1'/>
+          <var-decl name='s_time_gran' type-id='19c2251e' visibility='default' filepath='include/linux/fs.h' line='1517' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7872'>
-          <var-decl name='s_time_min' type-id='1afd27ac' visibility='default' filepath='include/linux/fs.h' line='1513' column='1'/>
+          <var-decl name='s_time_min' type-id='1afd27ac' visibility='default' filepath='include/linux/fs.h' line='1519' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7936'>
-          <var-decl name='s_time_max' type-id='1afd27ac' visibility='default' filepath='include/linux/fs.h' line='1514' column='1'/>
+          <var-decl name='s_time_max' type-id='1afd27ac' visibility='default' filepath='include/linux/fs.h' line='1520' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8000'>
-          <var-decl name='s_fsnotify_mask' type-id='3f1a6b60' visibility='default' filepath='include/linux/fs.h' line='1516' column='1'/>
+          <var-decl name='s_fsnotify_mask' type-id='3f1a6b60' visibility='default' filepath='include/linux/fs.h' line='1522' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8064'>
-          <var-decl name='s_fsnotify_marks' type-id='994d9d61' visibility='default' filepath='include/linux/fs.h' line='1517' column='1'/>
+          <var-decl name='s_fsnotify_marks' type-id='994d9d61' visibility='default' filepath='include/linux/fs.h' line='1523' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8128'>
-          <var-decl name='s_id' type-id='16dc656a' visibility='default' filepath='include/linux/fs.h' line='1520' column='1'/>
+          <var-decl name='s_id' type-id='16dc656a' visibility='default' filepath='include/linux/fs.h' line='1526' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8384'>
-          <var-decl name='s_uuid' type-id='ec55eb74' visibility='default' filepath='include/linux/fs.h' line='1521' column='1'/>
+          <var-decl name='s_uuid' type-id='ec55eb74' visibility='default' filepath='include/linux/fs.h' line='1527' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8512'>
-          <var-decl name='s_max_links' type-id='f0981eeb' visibility='default' filepath='include/linux/fs.h' line='1523' column='1'/>
+          <var-decl name='s_max_links' type-id='f0981eeb' visibility='default' filepath='include/linux/fs.h' line='1529' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8544'>
-          <var-decl name='s_mode' type-id='2665334e' visibility='default' filepath='include/linux/fs.h' line='1524' column='1'/>
+          <var-decl name='s_mode' type-id='2665334e' visibility='default' filepath='include/linux/fs.h' line='1530' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8576'>
-          <var-decl name='s_vfs_rename_mutex' type-id='925167dc' visibility='default' filepath='include/linux/fs.h' line='1530' column='1'/>
+          <var-decl name='s_vfs_rename_mutex' type-id='925167dc' visibility='default' filepath='include/linux/fs.h' line='1536' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='8960'>
-          <var-decl name='s_subtype' type-id='80f4b756' visibility='default' filepath='include/linux/fs.h' line='1536' column='1'/>
+          <var-decl name='s_subtype' type-id='80f4b756' visibility='default' filepath='include/linux/fs.h' line='1542' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9024'>
-          <var-decl name='s_d_op' type-id='1ee57353' visibility='default' filepath='include/linux/fs.h' line='1538' column='1'/>
+          <var-decl name='s_d_op' type-id='1ee57353' visibility='default' filepath='include/linux/fs.h' line='1544' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9088'>
-          <var-decl name='cleancache_poolid' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='1543' column='1'/>
+          <var-decl name='cleancache_poolid' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='1549' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9152'>
-          <var-decl name='s_shrink' type-id='27cb404f' visibility='default' filepath='include/linux/fs.h' line='1545' column='1'/>
+          <var-decl name='s_shrink' type-id='27cb404f' visibility='default' filepath='include/linux/fs.h' line='1551' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9664'>
-          <var-decl name='s_remove_count' type-id='f22a8abb' visibility='default' filepath='include/linux/fs.h' line='1548' column='1'/>
+          <var-decl name='s_remove_count' type-id='f22a8abb' visibility='default' filepath='include/linux/fs.h' line='1554' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9728'>
-          <var-decl name='s_fsnotify_inode_refs' type-id='f22a8abb' visibility='default' filepath='include/linux/fs.h' line='1551' column='1'/>
+          <var-decl name='s_fsnotify_inode_refs' type-id='f22a8abb' visibility='default' filepath='include/linux/fs.h' line='1557' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9792'>
-          <var-decl name='s_readonly_remount' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='1554' column='1'/>
+          <var-decl name='s_readonly_remount' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='1560' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9824'>
-          <var-decl name='s_wb_err' type-id='1da55f79' visibility='default' filepath='include/linux/fs.h' line='1557' column='1'/>
+          <var-decl name='s_wb_err' type-id='1da55f79' visibility='default' filepath='include/linux/fs.h' line='1563' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9856'>
-          <var-decl name='s_dio_done_wq' type-id='242e3d19' visibility='default' filepath='include/linux/fs.h' line='1560' column='1'/>
+          <var-decl name='s_dio_done_wq' type-id='242e3d19' visibility='default' filepath='include/linux/fs.h' line='1566' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9920'>
-          <var-decl name='s_pins' type-id='e151255a' visibility='default' filepath='include/linux/fs.h' line='1561' column='1'/>
+          <var-decl name='s_pins' type-id='e151255a' visibility='default' filepath='include/linux/fs.h' line='1567' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='9984'>
-          <var-decl name='s_user_ns' type-id='c0ced320' visibility='default' filepath='include/linux/fs.h' line='1568' column='1'/>
+          <var-decl name='s_user_ns' type-id='c0ced320' visibility='default' filepath='include/linux/fs.h' line='1574' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10048'>
-          <var-decl name='s_dentry_lru' type-id='c653aac7' visibility='default' filepath='include/linux/fs.h' line='1575' column='1'/>
+          <var-decl name='s_dentry_lru' type-id='c653aac7' visibility='default' filepath='include/linux/fs.h' line='1581' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10304'>
-          <var-decl name='s_inode_lru' type-id='c653aac7' visibility='default' filepath='include/linux/fs.h' line='1576' column='1'/>
+          <var-decl name='s_inode_lru' type-id='c653aac7' visibility='default' filepath='include/linux/fs.h' line='1582' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10560'>
-          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/fs.h' line='1577' column='1'/>
+          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/linux/fs.h' line='1583' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='10688'>
-          <var-decl name='destroy_work' type-id='ef9025d0' visibility='default' filepath='include/linux/fs.h' line='1578' column='1'/>
+          <var-decl name='destroy_work' type-id='ef9025d0' visibility='default' filepath='include/linux/fs.h' line='1584' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11072'>
-          <var-decl name='s_sync_lock' type-id='925167dc' visibility='default' filepath='include/linux/fs.h' line='1580' column='1'/>
+          <var-decl name='s_sync_lock' type-id='925167dc' visibility='default' filepath='include/linux/fs.h' line='1586' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11456'>
-          <var-decl name='s_stack_depth' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='1585' column='1'/>
+          <var-decl name='s_stack_depth' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='1591' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11776'>
-          <var-decl name='s_inode_list_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/fs.h' line='1588' column='1'/>
+          <var-decl name='s_inode_list_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/fs.h' line='1594' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11840'>
-          <var-decl name='s_inodes' type-id='72f469ec' visibility='default' filepath='include/linux/fs.h' line='1589' column='1'/>
+          <var-decl name='s_inodes' type-id='72f469ec' visibility='default' filepath='include/linux/fs.h' line='1595' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='11968'>
-          <var-decl name='s_inode_wblist_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/fs.h' line='1591' column='1'/>
+          <var-decl name='s_inode_wblist_lock' type-id='fb4018a0' visibility='default' filepath='include/linux/fs.h' line='1597' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='12032'>
-          <var-decl name='s_inodes_wb' type-id='72f469ec' visibility='default' filepath='include/linux/fs.h' line='1592' column='1'/>
+          <var-decl name='s_inodes_wb' type-id='72f469ec' visibility='default' filepath='include/linux/fs.h' line='1598' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='12160'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1594' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1600' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='12224'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1595' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1601' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='12288'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1596' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1602' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='12352'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1597' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/fs.h' line='1603' column='1'/>
         </data-member>
       </class-decl>
       <array-type-def dimensions='1' type-id='7359adad' size-in-bits='2048' id='bc3af5fa'>
@@ -85457,31 +85643,31 @@
           <var-decl name='android_oem_data1' type-id='ef7c8fe9' visibility='default' filepath='include/linux/sched.h' line='1377' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='28416'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1379' column='1'/>
+          <var-decl name='' type-id='2ee593e9' visibility='default' filepath='include/linux/sched.h' line='1380' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='28480'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1380' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1382' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='28544'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1381' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1383' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='28608'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1382' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1384' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='28672'>
-          <var-decl name='android_kabi_reserved5' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1383' column='1'/>
+          <var-decl name='android_kabi_reserved5' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1385' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='28736'>
-          <var-decl name='android_kabi_reserved6' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1384' column='1'/>
+          <var-decl name='android_kabi_reserved6' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1386' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='28800'>
-          <var-decl name='android_kabi_reserved7' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1385' column='1'/>
+          <var-decl name='android_kabi_reserved7' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1387' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='28864'>
-          <var-decl name='android_kabi_reserved8' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1386' column='1'/>
+          <var-decl name='android_kabi_reserved8' type-id='91ce1af9' visibility='default' filepath='include/linux/sched.h' line='1388' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='28928'>
-          <var-decl name='thread' type-id='0c8a83c7' visibility='default' filepath='include/linux/sched.h' line='1395' column='1'/>
+          <var-decl name='thread' type-id='0c8a83c7' visibility='default' filepath='include/linux/sched.h' line='1397' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='bc51cf2c'>
@@ -86938,12 +87124,12 @@
         <return type-id='95e97e5e'/>
       </function-type>
       <pointer-type-def type-id='7e5d36fb' size-in-bits='64' id='bdbd4b03'/>
-      <class-decl name='pci_saved_state' size-in-bits='512' is-struct='yes' visibility='default' filepath='drivers/pci/pci.c' line='1704' column='1' id='bdbf2231'>
+      <class-decl name='pci_saved_state' size-in-bits='512' is-struct='yes' visibility='default' filepath='drivers/pci/pci.c' line='1701' column='1' id='bdbf2231'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='config_space' type-id='02fdec64' visibility='default' filepath='drivers/pci/pci.c' line='1705' column='1'/>
+          <var-decl name='config_space' type-id='02fdec64' visibility='default' filepath='drivers/pci/pci.c' line='1702' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='cap' type-id='5f7bfbc1' visibility='default' filepath='drivers/pci/pci.c' line='1706' column='1'/>
+          <var-decl name='cap' type-id='5f7bfbc1' visibility='default' filepath='drivers/pci/pci.c' line='1703' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='facd5338' size-in-bits='64' id='bdcee7ae'/>
@@ -87366,12 +87552,12 @@
         <return type-id='95e97e5e'/>
       </function-type>
       <pointer-type-def type-id='59bcd074' size-in-bits='64' id='bea4d586'/>
-      <class-decl name='ctl_node' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/sysctl.h' line='124' column='1' id='beafd747'>
+      <class-decl name='ctl_node' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/sysctl.h' line='134' column='1' id='beafd747'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='node' type-id='2a8a6332' visibility='default' filepath='include/linux/sysctl.h' line='125' column='1'/>
+          <var-decl name='node' type-id='2a8a6332' visibility='default' filepath='include/linux/sysctl.h' line='135' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='header' type-id='11b101bb' visibility='default' filepath='include/linux/sysctl.h' line='126' column='1'/>
+          <var-decl name='header' type-id='11b101bb' visibility='default' filepath='include/linux/sysctl.h' line='136' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='5fffc559' size-in-bits='64' id='beb4f24d'/>
@@ -87537,24 +87723,24 @@
         <parameter type-id='2f9b8041'/>
         <return type-id='eaa32e2f'/>
       </function-type>
-      <class-decl name='irq_affinity' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/interrupt.h' line='294' column='1' id='bf33c00a'>
+      <class-decl name='irq_affinity' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/interrupt.h' line='298' column='1' id='bf33c00a'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='pre_vectors' type-id='f0981eeb' visibility='default' filepath='include/linux/interrupt.h' line='295' column='1'/>
+          <var-decl name='pre_vectors' type-id='f0981eeb' visibility='default' filepath='include/linux/interrupt.h' line='299' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='post_vectors' type-id='f0981eeb' visibility='default' filepath='include/linux/interrupt.h' line='296' column='1'/>
+          <var-decl name='post_vectors' type-id='f0981eeb' visibility='default' filepath='include/linux/interrupt.h' line='300' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='nr_sets' type-id='f0981eeb' visibility='default' filepath='include/linux/interrupt.h' line='297' column='1'/>
+          <var-decl name='nr_sets' type-id='f0981eeb' visibility='default' filepath='include/linux/interrupt.h' line='301' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='set_size' type-id='49580a63' visibility='default' filepath='include/linux/interrupt.h' line='298' column='1'/>
+          <var-decl name='set_size' type-id='49580a63' visibility='default' filepath='include/linux/interrupt.h' line='302' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='calc_sets' type-id='887112a7' visibility='default' filepath='include/linux/interrupt.h' line='299' column='1'/>
+          <var-decl name='calc_sets' type-id='887112a7' visibility='default' filepath='include/linux/interrupt.h' line='303' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='priv' type-id='eaa32e2f' visibility='default' filepath='include/linux/interrupt.h' line='300' column='1'/>
+          <var-decl name='priv' type-id='eaa32e2f' visibility='default' filepath='include/linux/interrupt.h' line='304' column='1'/>
         </data-member>
       </class-decl>
       <qualified-type-def type-id='69bf7bee' const='yes' id='bf352dfe'/>
@@ -88236,9 +88422,9 @@
           <var-decl name='memattr' type-id='91ce1af9' visibility='default' filepath='include/linux/io-pgtable.h' line='132' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='skb_shared_hwtstamps' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/linux/skbuff.h' line='420' column='1' id='c148e595'>
+      <class-decl name='skb_shared_hwtstamps' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/linux/skbuff.h' line='421' column='1' id='c148e595'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='hwtstamp' type-id='fbc017ef' visibility='default' filepath='include/linux/skbuff.h' line='421' column='1'/>
+          <var-decl name='hwtstamp' type-id='fbc017ef' visibility='default' filepath='include/linux/skbuff.h' line='422' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='b048e68e' size-in-bits='64' id='c149fe34'/>
@@ -91248,7 +91434,6 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='e9ec35ef' size-in-bits='64' id='c7432356'/>
-      <pointer-type-def type-id='91dc7ea3' size-in-bits='64' id='c748f227'/>
       <union-decl name='__anonymous_union__' size-in-bits='4096' is-anonymous='yes' visibility='default' filepath='include/uapi/sound/asound.h' line='1054' column='1' id='c74bfd7b'>
         <data-member access='public'>
           <var-decl name='value' type-id='1fd26250' visibility='default' filepath='include/uapi/sound/asound.h' line='1055' column='1'/>
@@ -92024,7 +92209,7 @@
       <pointer-type-def type-id='f3601a85' size-in-bits='64' id='c9cd0e09'/>
       <pointer-type-def type-id='da194c5e' size-in-bits='64' id='c9d35a9c'/>
       <pointer-type-def type-id='5218160d' size-in-bits='64' id='c9d64c0d'/>
-      <typedef-decl name='possible_net_t' type-id='0a0aec0a' filepath='include/net/net_namespace.h' line='325' column='1' id='c9df1e6c'/>
+      <typedef-decl name='possible_net_t' type-id='0a0aec0a' filepath='include/net/net_namespace.h' line='323' column='1' id='c9df1e6c'/>
       <class-decl name='__anonymous_struct__' size-in-bits='320' is-struct='yes' is-anonymous='yes' naming-typedef-id='0eb9c3fd' visibility='default' filepath='arch/arm64/include/asm/mmu.h' line='19' column='1' id='c9e2b4ad'>
         <data-member access='public' layout-offset-in-bits='0'>
           <var-decl name='id' type-id='28ee064c' visibility='default' filepath='arch/arm64/include/asm/mmu.h' line='20' column='1'/>
@@ -92130,15 +92315,15 @@
           <var-decl name='' type-id='cbb4664d' visibility='default' filepath='include/linux/moduleparam.h' line='76' column='1'/>
         </data-member>
       </class-decl>
-      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/netdevice.h' line='2167' column='1' id='ca29cb68'>
+      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/netdevice.h' line='2168' column='1' id='ca29cb68'>
         <data-member access='public'>
-          <var-decl name='lstats' type-id='a42934eb' visibility='default' filepath='include/linux/netdevice.h' line='2168' column='1'/>
+          <var-decl name='lstats' type-id='a42934eb' visibility='default' filepath='include/linux/netdevice.h' line='2169' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='tstats' type-id='90cd86e5' visibility='default' filepath='include/linux/netdevice.h' line='2169' column='1'/>
+          <var-decl name='tstats' type-id='90cd86e5' visibility='default' filepath='include/linux/netdevice.h' line='2170' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='dstats' type-id='f59f5033' visibility='default' filepath='include/linux/netdevice.h' line='2170' column='1'/>
+          <var-decl name='dstats' type-id='f59f5033' visibility='default' filepath='include/linux/netdevice.h' line='2171' column='1'/>
         </data-member>
       </union-decl>
       <pointer-type-def type-id='0e085d99' size-in-bits='64' id='ca2b80c9'/>
@@ -92582,12 +92767,12 @@
       <array-type-def dimensions='1' type-id='1851ab9f' size-in-bits='4096' id='cb01bf4b'>
         <subrange length='8' type-id='7ff19f0f' id='56e0c0b1'/>
       </array-type-def>
-      <class-decl name='usb_dynids' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='1114' column='1' id='cb08bae1'>
+      <class-decl name='usb_dynids' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='1122' column='1' id='cb08bae1'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='lock' type-id='fb4018a0' visibility='default' filepath='include/linux/usb.h' line='1115' column='1'/>
+          <var-decl name='lock' type-id='fb4018a0' visibility='default' filepath='include/linux/usb.h' line='1123' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/linux/usb.h' line='1116' column='1'/>
+          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/linux/usb.h' line='1124' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='96658a93' size-in-bits='64' id='cb0ca137'/>
@@ -93534,15 +93719,15 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='cfe4f8a2' size-in-bits='64' id='cd733e18'/>
-      <class-decl name='ack_sample' size-in-bits='96' is-struct='yes' visibility='default' filepath='include/net/tcp.h' line='1032' column='1' id='cd7d3c9d'>
+      <class-decl name='ack_sample' size-in-bits='96' is-struct='yes' visibility='default' filepath='include/net/tcp.h' line='1033' column='1' id='cd7d3c9d'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='pkts_acked' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1033' column='1'/>
+          <var-decl name='pkts_acked' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1034' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='rtt_us' type-id='a7832498' visibility='default' filepath='include/net/tcp.h' line='1034' column='1'/>
+          <var-decl name='rtt_us' type-id='a7832498' visibility='default' filepath='include/net/tcp.h' line='1035' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='in_flight' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1035' column='1'/>
+          <var-decl name='in_flight' type-id='19c2251e' visibility='default' filepath='include/net/tcp.h' line='1036' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='phylink_link_state' size-in-bits='448' is-struct='yes' visibility='default' filepath='include/linux/phylink.h' line='43' column='1' id='cd8ce92b'>
@@ -94250,18 +94435,18 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='c184e101' size-in-bits='64' id='cf2e76b1'/>
-      <class-decl name='netdev_name_node' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='976' column='1' id='cf2e8db8'>
+      <class-decl name='netdev_name_node' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='981' column='1' id='cf2e8db8'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='hlist' type-id='03a4a074' visibility='default' filepath='include/linux/netdevice.h' line='977' column='1'/>
+          <var-decl name='hlist' type-id='03a4a074' visibility='default' filepath='include/linux/netdevice.h' line='982' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='978' column='1'/>
+          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/linux/netdevice.h' line='983' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='dev' type-id='68a2d05b' visibility='default' filepath='include/linux/netdevice.h' line='979' column='1'/>
+          <var-decl name='dev' type-id='68a2d05b' visibility='default' filepath='include/linux/netdevice.h' line='984' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='name' type-id='80f4b756' visibility='default' filepath='include/linux/netdevice.h' line='980' column='1'/>
+          <var-decl name='name' type-id='80f4b756' visibility='default' filepath='include/linux/netdevice.h' line='985' column='1'/>
         </data-member>
       </class-decl>
       <qualified-type-def type-id='e07b5dbe' const='yes' id='cf3752f1'/>
@@ -95094,12 +95279,12 @@
         <return type-id='95e97e5e'/>
       </function-type>
       <pointer-type-def type-id='a363caa5' size-in-bits='64' id='d15edd25'/>
-      <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/uapi/linux/ip.h' line='104' column='1' id='d1615c58'>
+      <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/uapi/linux/ip.h' line='105' column='1' id='d1615c58'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='saddr' type-id='78a133c2' visibility='default' filepath='include/uapi/linux/ip.h' line='104' column='1'/>
+          <var-decl name='saddr' type-id='78a133c2' visibility='default' filepath='include/uapi/linux/ip.h' line='105' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='daddr' type-id='78a133c2' visibility='default' filepath='include/uapi/linux/ip.h' line='104' column='1'/>
+          <var-decl name='daddr' type-id='78a133c2' visibility='default' filepath='include/uapi/linux/ip.h' line='105' column='1'/>
         </data-member>
       </class-decl>
       <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='2048' id='d1617432'>
@@ -95421,6 +95606,7 @@
           <var-decl name='compound_nr' type-id='f0981eeb' visibility='default' filepath='include/linux/mm_types.h' line='140' column='1'/>
         </data-member>
       </class-decl>
+      <pointer-type-def type-id='08b65638' size-in-bits='64' id='d20b5f3e'/>
       <pointer-type-def type-id='b8dcddba' size-in-bits='64' id='d2188e4c'/>
       <pointer-type-def type-id='3c21941b' size-in-bits='64' id='d21964af'/>
       <class-decl name='devfreq_simple_ondemand_data' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/linux/devfreq.h' line='277' column='1' id='d21d90ad'>
@@ -96079,24 +96265,24 @@
         <parameter type-id='b9af02c3'/>
         <return type-id='48b5725f'/>
       </function-type>
-      <class-decl name='typec_operations' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/usb/typec.h' line='212' column='1' id='d3860975'>
+      <class-decl name='typec_operations' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/usb/typec.h' line='218' column='1' id='d3860975'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='try_role' type-id='d7a90e3b' visibility='default' filepath='include/linux/usb/typec.h' line='213' column='1'/>
+          <var-decl name='try_role' type-id='d7a90e3b' visibility='default' filepath='include/linux/usb/typec.h' line='219' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='dr_set' type-id='55ebe352' visibility='default' filepath='include/linux/usb/typec.h' line='214' column='1'/>
+          <var-decl name='dr_set' type-id='55ebe352' visibility='default' filepath='include/linux/usb/typec.h' line='220' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='pr_set' type-id='331e3ac7' visibility='default' filepath='include/linux/usb/typec.h' line='215' column='1'/>
+          <var-decl name='pr_set' type-id='331e3ac7' visibility='default' filepath='include/linux/usb/typec.h' line='221' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='vconn_set' type-id='331e3ac7' visibility='default' filepath='include/linux/usb/typec.h' line='216' column='1'/>
+          <var-decl name='vconn_set' type-id='331e3ac7' visibility='default' filepath='include/linux/usb/typec.h' line='222' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='port_type_set' type-id='6507da23' visibility='default' filepath='include/linux/usb/typec.h' line='217' column='1'/>
+          <var-decl name='port_type_set' type-id='6507da23' visibility='default' filepath='include/linux/usb/typec.h' line='223' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb/typec.h' line='219' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb/typec.h' line='225' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='bpf_local_storage_map_bucket' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/bpf_local_storage.h' line='19' column='1' id='d38c200b'>
@@ -96119,12 +96305,12 @@
           <var-decl name='xa_head' type-id='eaa32e2f' visibility='default' filepath='include/linux/xarray.h' line='296' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='ctl_table_poll' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/sysctl.h' line='94' column='1' id='d39c42ab'>
+      <class-decl name='ctl_table_poll' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/sysctl.h' line='104' column='1' id='d39c42ab'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='event' type-id='49178f86' visibility='default' filepath='include/linux/sysctl.h' line='95' column='1'/>
+          <var-decl name='event' type-id='49178f86' visibility='default' filepath='include/linux/sysctl.h' line='105' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='wait' type-id='b5ab048f' visibility='default' filepath='include/linux/sysctl.h' line='96' column='1'/>
+          <var-decl name='wait' type-id='b5ab048f' visibility='default' filepath='include/linux/sysctl.h' line='106' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='ld_semaphore' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/tty_ldisc.h' line='134' column='1' id='d3aa38f0'>
@@ -96769,12 +96955,12 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='db362995' size-in-bits='64' id='d543b7ad'/>
-      <class-decl name='dir_context' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='1824' column='1' id='d5476b80'>
+      <class-decl name='dir_context' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='1831' column='1' id='d5476b80'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='actor' type-id='262124ef' visibility='default' filepath='include/linux/fs.h' line='1825' column='1'/>
+          <var-decl name='actor' type-id='262124ef' visibility='default' filepath='include/linux/fs.h' line='1832' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='pos' type-id='69bf7bee' visibility='default' filepath='include/linux/fs.h' line='1826' column='1'/>
+          <var-decl name='pos' type-id='69bf7bee' visibility='default' filepath='include/linux/fs.h' line='1833' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='i2c_bus_recovery_info' size-in-bits='832' is-struct='yes' visibility='default' filepath='include/linux/i2c.h' line='618' column='1' id='d5526a99'>
@@ -97741,6 +97927,7 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='5985c13a' size-in-bits='64' id='d6f1846c'/>
+      <pointer-type-def type-id='38664924' size-in-bits='64' id='d705010a'/>
       <class-decl name='virtio_config_ops' size-in-bits='896' is-struct='yes' visibility='default' filepath='include/linux/virtio_config.h' line='78' column='1' id='d70a473a'>
         <data-member access='public' layout-offset-in-bits='0'>
           <var-decl name='get' type-id='b22e78ee' visibility='default' filepath='include/linux/virtio_config.h' line='79' column='1'/>
@@ -97889,9 +98076,9 @@
         <return type-id='48b5725f'/>
       </function-type>
       <pointer-type-def type-id='b7da17bb' size-in-bits='64' id='d77ebcbf'/>
-      <class-decl name='usb_devmap' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='428' column='1' id='d78885c5'>
+      <class-decl name='usb_devmap' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='433' column='1' id='d78885c5'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='devicemap' type-id='f05e8e77' visibility='default' filepath='include/linux/usb.h' line='429' column='1'/>
+          <var-decl name='devicemap' type-id='f05e8e77' visibility='default' filepath='include/linux/usb.h' line='434' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='182ef894' size-in-bits='64' id='d78909c6'/>
@@ -98156,18 +98343,18 @@
       </array-type-def>
       <pointer-type-def type-id='c90a6da1' size-in-bits='64' id='d8378d75'/>
       <pointer-type-def type-id='41df3a6f' size-in-bits='64' id='d8385083'/>
-      <class-decl name='ctl_table_root' size-in-bits='960' is-struct='yes' visibility='default' filepath='include/linux/sysctl.h' line='161' column='1' id='d83969a6'>
+      <class-decl name='ctl_table_root' size-in-bits='960' is-struct='yes' visibility='default' filepath='include/linux/sysctl.h' line='171' column='1' id='d83969a6'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='default_set' type-id='3fc3d262' visibility='default' filepath='include/linux/sysctl.h' line='162' column='1'/>
+          <var-decl name='default_set' type-id='3fc3d262' visibility='default' filepath='include/linux/sysctl.h' line='172' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='lookup' type-id='50abd760' visibility='default' filepath='include/linux/sysctl.h' line='163' column='1'/>
+          <var-decl name='lookup' type-id='50abd760' visibility='default' filepath='include/linux/sysctl.h' line='173' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='set_ownership' type-id='47727520' visibility='default' filepath='include/linux/sysctl.h' line='164' column='1'/>
+          <var-decl name='set_ownership' type-id='47727520' visibility='default' filepath='include/linux/sysctl.h' line='174' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='permissions' type-id='7bada959' visibility='default' filepath='include/linux/sysctl.h' line='167' column='1'/>
+          <var-decl name='permissions' type-id='7bada959' visibility='default' filepath='include/linux/sysctl.h' line='177' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='4322685c' size-in-bits='64' id='d839e3f6'/>
@@ -98953,15 +99140,15 @@
       <array-type-def dimensions='1' type-id='094d8048' size-in-bits='infinite' id='da6e2919'>
         <subrange length='infinite' type-id='7ff19f0f' id='031f2035'/>
       </array-type-def>
-      <union-decl name='__anonymous_union__' size-in-bits='192' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='719' column='1' id='da6f1b1a'>
+      <union-decl name='__anonymous_union__' size-in-bits='192' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='721' column='1' id='da6f1b1a'>
         <data-member access='public'>
-          <var-decl name='' type-id='fe3b99ac' visibility='default' filepath='include/linux/skbuff.h' line='720' column='1'/>
+          <var-decl name='' type-id='fe3b99ac' visibility='default' filepath='include/linux/skbuff.h' line='722' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='rbnode' type-id='2a8a6332' visibility='default' filepath='include/linux/skbuff.h' line='734' column='1'/>
+          <var-decl name='rbnode' type-id='2a8a6332' visibility='default' filepath='include/linux/skbuff.h' line='736' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/linux/skbuff.h' line='735' column='1'/>
+          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/linux/skbuff.h' line='737' column='1'/>
         </data-member>
       </union-decl>
       <array-type-def dimensions='1' type-id='2c5bcc28' size-in-bits='1024' id='da6f4a25'>
@@ -99099,27 +99286,27 @@
         <subrange length='38' type-id='7ff19f0f' id='aa4ccdac'/>
       </array-type-def>
       <pointer-type-def type-id='2a275b06' size-in-bits='64' id='dae07608'/>
-      <class-decl name='page_vma_mapped_walk' size-in-bits='448' is-struct='yes' visibility='default' filepath='include/linux/rmap.h' line='227' column='1' id='dae3142b'>
+      <class-decl name='page_vma_mapped_walk' size-in-bits='448' is-struct='yes' visibility='default' filepath='include/linux/rmap.h' line='240' column='1' id='dae3142b'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='page' type-id='02f11ed4' visibility='default' filepath='include/linux/rmap.h' line='228' column='1'/>
+          <var-decl name='page' type-id='02f11ed4' visibility='default' filepath='include/linux/rmap.h' line='241' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='vma' type-id='2ae08426' visibility='default' filepath='include/linux/rmap.h' line='229' column='1'/>
+          <var-decl name='vma' type-id='2ae08426' visibility='default' filepath='include/linux/rmap.h' line='242' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='address' type-id='7359adad' visibility='default' filepath='include/linux/rmap.h' line='230' column='1'/>
+          <var-decl name='address' type-id='7359adad' visibility='default' filepath='include/linux/rmap.h' line='243' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='pmd' type-id='6d5994d5' visibility='default' filepath='include/linux/rmap.h' line='231' column='1'/>
+          <var-decl name='pmd' type-id='6d5994d5' visibility='default' filepath='include/linux/rmap.h' line='244' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='pte' type-id='e8d572d7' visibility='default' filepath='include/linux/rmap.h' line='232' column='1'/>
+          <var-decl name='pte' type-id='e8d572d7' visibility='default' filepath='include/linux/rmap.h' line='245' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='ptl' type-id='cff2d845' visibility='default' filepath='include/linux/rmap.h' line='233' column='1'/>
+          <var-decl name='ptl' type-id='cff2d845' visibility='default' filepath='include/linux/rmap.h' line='246' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='flags' type-id='f0981eeb' visibility='default' filepath='include/linux/rmap.h' line='234' column='1'/>
+          <var-decl name='flags' type-id='f0981eeb' visibility='default' filepath='include/linux/rmap.h' line='247' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='dae66efd'>
@@ -99915,15 +100102,15 @@
         <subrange length='256' type-id='7ff19f0f' id='36e5b9fa'/>
       </array-type-def>
       <pointer-type-def type-id='8b1bf035' size-in-bits='64' id='dbb91d59'/>
-      <class-decl name='usb_interface_cache' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='328' column='1' id='dbbc1900'>
+      <class-decl name='usb_interface_cache' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='333' column='1' id='dbbc1900'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='num_altsetting' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='329' column='1'/>
+          <var-decl name='num_altsetting' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='334' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='ref' type-id='400fb07b' visibility='default' filepath='include/linux/usb.h' line='330' column='1'/>
+          <var-decl name='ref' type-id='400fb07b' visibility='default' filepath='include/linux/usb.h' line='335' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='altsetting' type-id='26179f78' visibility='default' filepath='include/linux/usb.h' line='334' column='1'/>
+          <var-decl name='altsetting' type-id='26179f78' visibility='default' filepath='include/linux/usb.h' line='339' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='cbbffc65' size-in-bits='64' id='dbc22931'/>
@@ -100336,79 +100523,79 @@
         <return type-id='95e97e5e'/>
       </function-type>
       <pointer-type-def type-id='e0ed16c6' size-in-bits='64' id='dc18a9b0'/>
-      <typedef-decl name='gro_result_t' type-id='3facc5aa' filepath='include/linux/netdevice.h' line='389' column='1' id='dc1b1685'/>
-      <class-decl name='dwc3_ep' size-in-bits='1856' is-struct='yes' visibility='default' filepath='drivers/usb/dwc3/core.h' line='705' column='1' id='dc1b9a32'>
+      <typedef-decl name='gro_result_t' type-id='3facc5aa' filepath='include/linux/netdevice.h' line='391' column='1' id='dc1b1685'/>
+      <class-decl name='dwc3_ep' size-in-bits='1856' is-struct='yes' visibility='default' filepath='drivers/usb/dwc3/core.h' line='706' column='1' id='dc1b9a32'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='endpoint' type-id='8005701f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='706' column='1'/>
+          <var-decl name='endpoint' type-id='8005701f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='707' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='cancelled_list' type-id='72f469ec' visibility='default' filepath='drivers/usb/dwc3/core.h' line='707' column='1'/>
+          <var-decl name='cancelled_list' type-id='72f469ec' visibility='default' filepath='drivers/usb/dwc3/core.h' line='708' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='pending_list' type-id='72f469ec' visibility='default' filepath='drivers/usb/dwc3/core.h' line='708' column='1'/>
+          <var-decl name='pending_list' type-id='72f469ec' visibility='default' filepath='drivers/usb/dwc3/core.h' line='709' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='started_list' type-id='72f469ec' visibility='default' filepath='drivers/usb/dwc3/core.h' line='709' column='1'/>
+          <var-decl name='started_list' type-id='72f469ec' visibility='default' filepath='drivers/usb/dwc3/core.h' line='710' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='regs' type-id='eaa32e2f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='711' column='1'/>
+          <var-decl name='regs' type-id='eaa32e2f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='712' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1088'>
-          <var-decl name='trb_pool' type-id='0d6a59e1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='713' column='1'/>
+          <var-decl name='trb_pool' type-id='0d6a59e1' visibility='default' filepath='drivers/usb/dwc3/core.h' line='714' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='trb_pool_dma' type-id='cf29c9b3' visibility='default' filepath='drivers/usb/dwc3/core.h' line='714' column='1'/>
+          <var-decl name='trb_pool_dma' type-id='cf29c9b3' visibility='default' filepath='drivers/usb/dwc3/core.h' line='715' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='dwc' type-id='5ac4ba20' visibility='default' filepath='drivers/usb/dwc3/core.h' line='715' column='1'/>
+          <var-decl name='dwc' type-id='5ac4ba20' visibility='default' filepath='drivers/usb/dwc3/core.h' line='716' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1280'>
-          <var-decl name='saved_state' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='717' column='1'/>
+          <var-decl name='saved_state' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='718' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1312'>
-          <var-decl name='flags' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='718' column='1'/>
+          <var-decl name='flags' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='719' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1344'>
-          <var-decl name='trb_enqueue' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='746' column='1'/>
+          <var-decl name='trb_enqueue' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='747' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1352'>
-          <var-decl name='trb_dequeue' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='747' column='1'/>
+          <var-decl name='trb_dequeue' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='748' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1360'>
-          <var-decl name='number' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='749' column='1'/>
+          <var-decl name='number' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='750' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1368'>
-          <var-decl name='type' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='750' column='1'/>
+          <var-decl name='type' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='751' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1376'>
-          <var-decl name='resource_index' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='751' column='1'/>
+          <var-decl name='resource_index' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='752' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1408'>
-          <var-decl name='frame_number' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='752' column='1'/>
+          <var-decl name='frame_number' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='753' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1440'>
-          <var-decl name='interval' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='753' column='1'/>
+          <var-decl name='interval' type-id='19c2251e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='754' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1472'>
-          <var-decl name='name' type-id='664ac0b7' visibility='default' filepath='drivers/usb/dwc3/core.h' line='755' column='1'/>
+          <var-decl name='name' type-id='664ac0b7' visibility='default' filepath='drivers/usb/dwc3/core.h' line='756' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='direction' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='757' column='1'/>
+          <var-decl name='direction' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='758' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1'>
-          <var-decl name='stream_capable' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='758' column='1'/>
+          <var-decl name='stream_capable' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='759' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1640'>
-          <var-decl name='combo_num' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='761' column='1'/>
+          <var-decl name='combo_num' type-id='f9b06939' visibility='default' filepath='drivers/usb/dwc3/core.h' line='762' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1664'>
-          <var-decl name='start_cmd_status' type-id='95e97e5e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='762' column='1'/>
+          <var-decl name='start_cmd_status' type-id='95e97e5e' visibility='default' filepath='drivers/usb/dwc3/core.h' line='763' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1728'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='764' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='765' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1792'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='765' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='766' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='a9559bf8' size-in-bits='64' id='dc1e097e'/>
@@ -100994,12 +101181,12 @@
       </union-decl>
       <pointer-type-def type-id='ebe3ac70' size-in-bits='64' id='ddcd89c6'/>
       <pointer-type-def type-id='1f90162b' size-in-bits='64' id='ddd0a58b'/>
-      <class-decl name='dev_ifalias' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='968' column='1' id='ddd212e6'>
+      <class-decl name='dev_ifalias' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='973' column='1' id='ddd212e6'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='rcuhead' type-id='e3d8ce29' visibility='default' filepath='include/linux/netdevice.h' line='969' column='1'/>
+          <var-decl name='rcuhead' type-id='e3d8ce29' visibility='default' filepath='include/linux/netdevice.h' line='974' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='ifalias' type-id='e84913bd' visibility='default' filepath='include/linux/netdevice.h' line='970' column='1'/>
+          <var-decl name='ifalias' type-id='e84913bd' visibility='default' filepath='include/linux/netdevice.h' line='975' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='92e8f939' size-in-bits='64' id='ddd322c1'/>
@@ -101408,18 +101595,18 @@
         <parameter type-id='b50a4934'/>
         <return type-id='48b5725f'/>
       </function-type>
-      <class-decl name='usb_class_driver' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='1302' column='1' id='de68658d'>
+      <class-decl name='usb_class_driver' size-in-bits='256' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='1310' column='1' id='de68658d'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='name' type-id='26a90f95' visibility='default' filepath='include/linux/usb.h' line='1303' column='1'/>
+          <var-decl name='name' type-id='26a90f95' visibility='default' filepath='include/linux/usb.h' line='1311' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='devnode' type-id='8cd77b5f' visibility='default' filepath='include/linux/usb.h' line='1304' column='1'/>
+          <var-decl name='devnode' type-id='8cd77b5f' visibility='default' filepath='include/linux/usb.h' line='1312' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='fops' type-id='61758ee5' visibility='default' filepath='include/linux/usb.h' line='1305' column='1'/>
+          <var-decl name='fops' type-id='61758ee5' visibility='default' filepath='include/linux/usb.h' line='1313' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='minor_base' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1306' column='1'/>
+          <var-decl name='minor_base' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1314' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='e85fe596' size-in-bits='64' id='de6b64d0'/>
@@ -103015,12 +103202,6 @@
           <var-decl name='first' type-id='08cbad52' visibility='default' filepath='include/linux/types.h' line='183' column='1'/>
         </data-member>
       </class-decl>
-      <function-type size-in-bits='64' id='e151e1f6'>
-        <parameter type-id='7e666abe'/>
-        <parameter type-id='7359adad'/>
-        <parameter type-id='7359adad'/>
-        <return type-id='02f11ed4'/>
-      </function-type>
       <pointer-type-def type-id='20b17040' size-in-bits='64' id='e153f6de'/>
       <pointer-type-def type-id='4d94804e' size-in-bits='64' id='e15671b8'/>
       <pointer-type-def type-id='59aa7dba' size-in-bits='64' id='e15aece4'/>
@@ -103748,12 +103929,12 @@
         <subrange length='128' type-id='7ff19f0f' id='1eb1687a'/>
       </array-type-def>
       <pointer-type-def type-id='59f9f35d' size-in-bits='64' id='e324928d'/>
-      <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/uio.h' line='46' column='1' id='e328d99e'>
+      <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/uio.h' line='52' column='1' id='e328d99e'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='head' type-id='f0981eeb' visibility='default' filepath='include/linux/uio.h' line='47' column='1'/>
+          <var-decl name='head' type-id='f0981eeb' visibility='default' filepath='include/linux/uio.h' line='53' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='start_head' type-id='f0981eeb' visibility='default' filepath='include/linux/uio.h' line='48' column='1'/>
+          <var-decl name='start_head' type-id='f0981eeb' visibility='default' filepath='include/linux/uio.h' line='54' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='gpio_device' size-in-bits='9600' is-struct='yes' visibility='default' filepath='drivers/pinctrl/../gpio/gpiolib.h' line='46' column='1' id='e32a05ed'>
@@ -104637,7 +104818,7 @@
           <var-decl name='driver' type-id='00c7b870' visibility='default' filepath='drivers/base/base.h' line='63' column='1'/>
         </data-member>
       </class-decl>
-      <enum-decl name='typec_data_role' filepath='include/linux/usb/typec.h' line='45' column='1' id='e453a0cb'>
+      <enum-decl name='typec_data_role' filepath='include/linux/usb/typec.h' line='46' column='1' id='e453a0cb'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='TYPEC_DEVICE' value='0'/>
         <enumerator name='TYPEC_HOST' value='1'/>
@@ -105592,18 +105773,18 @@
         <parameter type-id='f0981eeb'/>
         <return type-id='95e97e5e'/>
       </function-type>
-      <class-decl name='sk_buff_head' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/skbuff.h' line='293' column='1' id='e61c85d0'>
+      <class-decl name='sk_buff_head' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/skbuff.h' line='294' column='1' id='e61c85d0'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='next' type-id='0fbf3cfd' visibility='default' filepath='include/linux/skbuff.h' line='295' column='1'/>
+          <var-decl name='next' type-id='0fbf3cfd' visibility='default' filepath='include/linux/skbuff.h' line='296' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='prev' type-id='0fbf3cfd' visibility='default' filepath='include/linux/skbuff.h' line='296' column='1'/>
+          <var-decl name='prev' type-id='0fbf3cfd' visibility='default' filepath='include/linux/skbuff.h' line='297' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='qlen' type-id='3f1a6b60' visibility='default' filepath='include/linux/skbuff.h' line='298' column='1'/>
+          <var-decl name='qlen' type-id='3f1a6b60' visibility='default' filepath='include/linux/skbuff.h' line='299' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='160'>
-          <var-decl name='lock' type-id='fb4018a0' visibility='default' filepath='include/linux/skbuff.h' line='299' column='1'/>
+          <var-decl name='lock' type-id='fb4018a0' visibility='default' filepath='include/linux/skbuff.h' line='300' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='35213710' size-in-bits='64' id='e61cb0da'/>
@@ -105763,33 +105944,33 @@
           <var-decl name='sysfs_groups' type-id='9f18d529' visibility='default' filepath='include/linux/led-class-flash.h' line='79' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='dwc3_event_buffer' size-in-bits='448' is-struct='yes' visibility='default' filepath='drivers/usb/dwc3/core.h' line='653' column='1' id='e6ab9148'>
+      <class-decl name='dwc3_event_buffer' size-in-bits='448' is-struct='yes' visibility='default' filepath='drivers/usb/dwc3/core.h' line='654' column='1' id='e6ab9148'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='buf' type-id='eaa32e2f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='654' column='1'/>
+          <var-decl name='buf' type-id='eaa32e2f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='655' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='cache' type-id='eaa32e2f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='655' column='1'/>
+          <var-decl name='cache' type-id='eaa32e2f' visibility='default' filepath='drivers/usb/dwc3/core.h' line='656' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='length' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='656' column='1'/>
+          <var-decl name='length' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='657' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='160'>
-          <var-decl name='lpos' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='657' column='1'/>
+          <var-decl name='lpos' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='658' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='count' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='658' column='1'/>
+          <var-decl name='count' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='659' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='224'>
-          <var-decl name='flags' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='659' column='1'/>
+          <var-decl name='flags' type-id='f0981eeb' visibility='default' filepath='drivers/usb/dwc3/core.h' line='660' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='dma' type-id='cf29c9b3' visibility='default' filepath='drivers/usb/dwc3/core.h' line='663' column='1'/>
+          <var-decl name='dma' type-id='cf29c9b3' visibility='default' filepath='drivers/usb/dwc3/core.h' line='664' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='dwc' type-id='5ac4ba20' visibility='default' filepath='drivers/usb/dwc3/core.h' line='665' column='1'/>
+          <var-decl name='dwc' type-id='5ac4ba20' visibility='default' filepath='drivers/usb/dwc3/core.h' line='666' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='667' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='drivers/usb/dwc3/core.h' line='668' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='e6af544d'>
@@ -105848,12 +106029,12 @@
         <subrange length='4' type-id='7ff19f0f' id='16fe7105'/>
       </array-type-def>
       <qualified-type-def type-id='40af3608' const='yes' id='e70f1c73'/>
-      <class-decl name='posix_cputimer_base' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/posix-timers.h' line='108' column='1' id='e710f78e'>
+      <class-decl name='posix_cputimer_base' size-in-bits='192' is-struct='yes' visibility='default' filepath='include/linux/posix-timers.h' line='111' column='1' id='e710f78e'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='nextevt' type-id='91ce1af9' visibility='default' filepath='include/linux/posix-timers.h' line='109' column='1'/>
+          <var-decl name='nextevt' type-id='91ce1af9' visibility='default' filepath='include/linux/posix-timers.h' line='112' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='tqhead' type-id='ff3c7f20' visibility='default' filepath='include/linux/posix-timers.h' line='110' column='1'/>
+          <var-decl name='tqhead' type-id='ff3c7f20' visibility='default' filepath='include/linux/posix-timers.h' line='113' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='e7176377'>
@@ -106527,12 +106708,12 @@
       </class-decl>
       <pointer-type-def type-id='72c0e160' size-in-bits='64' id='e90f4666'/>
       <pointer-type-def type-id='55fcdb4f' size-in-bits='64' id='e90fa847'/>
-      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/uio.h' line='44' column='1' id='e91837c2'>
+      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/uio.h' line='50' column='1' id='e91837c2'>
         <data-member access='public'>
-          <var-decl name='nr_segs' type-id='7359adad' visibility='default' filepath='include/linux/uio.h' line='45' column='1'/>
+          <var-decl name='nr_segs' type-id='7359adad' visibility='default' filepath='include/linux/uio.h' line='51' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='' type-id='e328d99e' visibility='default' filepath='include/linux/uio.h' line='46' column='1'/>
+          <var-decl name='' type-id='e328d99e' visibility='default' filepath='include/linux/uio.h' line='52' column='1'/>
         </data-member>
       </union-decl>
       <function-type size-in-bits='64' id='e91cb1f0'>
@@ -107362,12 +107543,12 @@
       </function-type>
       <pointer-type-def type-id='328ded65' size-in-bits='64' id='ead4b779'/>
       <pointer-type-def type-id='a38ff96f' size-in-bits='64' id='eadc8303'/>
-      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/interrupt.h' line='622' column='1' id='eae5c421'>
+      <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/interrupt.h' line='626' column='1' id='eae5c421'>
         <data-member access='public'>
-          <var-decl name='func' type-id='08b16374' visibility='default' filepath='include/linux/interrupt.h' line='623' column='1'/>
+          <var-decl name='func' type-id='08b16374' visibility='default' filepath='include/linux/interrupt.h' line='627' column='1'/>
         </data-member>
         <data-member access='public'>
-          <var-decl name='callback' type-id='02da239e' visibility='default' filepath='include/linux/interrupt.h' line='624' column='1'/>
+          <var-decl name='callback' type-id='02da239e' visibility='default' filepath='include/linux/interrupt.h' line='628' column='1'/>
         </data-member>
       </union-decl>
       <pointer-type-def type-id='abbbeccc' size-in-bits='64' id='eaeee79a'/>
@@ -108585,12 +108766,12 @@
         </data-member>
       </class-decl>
       <qualified-type-def type-id='c058e0bd' const='yes' id='ed1a1b22'/>
-      <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/netdevice.h' line='941' column='1' id='ed254a3d'>
+      <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/netdevice.h' line='946' column='1' id='ed254a3d'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='pool' type-id='81e0c1b8' visibility='default' filepath='include/linux/netdevice.h' line='942' column='1'/>
+          <var-decl name='pool' type-id='81e0c1b8' visibility='default' filepath='include/linux/netdevice.h' line='947' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='queue_id' type-id='1dc6a898' visibility='default' filepath='include/linux/netdevice.h' line='943' column='1'/>
+          <var-decl name='queue_id' type-id='1dc6a898' visibility='default' filepath='include/linux/netdevice.h' line='948' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='7c055541' size-in-bits='64' id='ed27ccc9'/>
@@ -108635,30 +108816,30 @@
         <subrange length='64' type-id='7ff19f0f' id='b10be967'/>
       </array-type-def>
       <pointer-type-def type-id='f6ed712a' size-in-bits='64' id='ed512028'/>
-      <class-decl name='ctl_table_header' size-in-bits='640' is-struct='yes' visibility='default' filepath='include/linux/sysctl.h' line='131' column='1' id='ed51618b'>
+      <class-decl name='ctl_table_header' size-in-bits='640' is-struct='yes' visibility='default' filepath='include/linux/sysctl.h' line='141' column='1' id='ed51618b'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='' type-id='201d54e5' visibility='default' filepath='include/linux/sysctl.h' line='132' column='1'/>
+          <var-decl name='' type-id='201d54e5' visibility='default' filepath='include/linux/sysctl.h' line='142' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='unregistering' type-id='389faaf7' visibility='default' filepath='include/linux/sysctl.h' line='141' column='1'/>
+          <var-decl name='unregistering' type-id='389faaf7' visibility='default' filepath='include/linux/sysctl.h' line='151' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='ctl_table_arg' type-id='631dc3c1' visibility='default' filepath='include/linux/sysctl.h' line='142' column='1'/>
+          <var-decl name='ctl_table_arg' type-id='631dc3c1' visibility='default' filepath='include/linux/sysctl.h' line='152' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='root' type-id='2993adbc' visibility='default' filepath='include/linux/sysctl.h' line='143' column='1'/>
+          <var-decl name='root' type-id='2993adbc' visibility='default' filepath='include/linux/sysctl.h' line='153' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='set' type-id='42988600' visibility='default' filepath='include/linux/sysctl.h' line='144' column='1'/>
+          <var-decl name='set' type-id='42988600' visibility='default' filepath='include/linux/sysctl.h' line='154' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='parent' type-id='1c66bddc' visibility='default' filepath='include/linux/sysctl.h' line='145' column='1'/>
+          <var-decl name='parent' type-id='1c66bddc' visibility='default' filepath='include/linux/sysctl.h' line='155' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='node' type-id='a586bbcf' visibility='default' filepath='include/linux/sysctl.h' line='146' column='1'/>
+          <var-decl name='node' type-id='a586bbcf' visibility='default' filepath='include/linux/sysctl.h' line='156' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='inodes' type-id='e151255a' visibility='default' filepath='include/linux/sysctl.h' line='147' column='1'/>
+          <var-decl name='inodes' type-id='e151255a' visibility='default' filepath='include/linux/sysctl.h' line='157' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='mii_bus' size-in-bits='22528' is-struct='yes' visibility='default' filepath='include/linux/phy.h' line='302' column='1' id='ed5381db'>
@@ -109037,27 +109218,27 @@
           <var-decl name='data_ptr' type-id='cf536864' visibility='default' filepath='include/uapi/sound/asound.h' line='1064' column='1'/>
         </data-member>
       </union-decl>
-      <class-decl name='socket' size-in-bits='1024' is-struct='yes' visibility='default' filepath='include/linux/net.h' line='117' column='1' id='ee14fd94'>
+      <class-decl name='socket' size-in-bits='1024' is-struct='yes' visibility='default' filepath='include/linux/net.h' line='115' column='1' id='ee14fd94'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='state' type-id='ee2ecafb' visibility='default' filepath='include/linux/net.h' line='118' column='1'/>
+          <var-decl name='state' type-id='ee2ecafb' visibility='default' filepath='include/linux/net.h' line='116' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='type' type-id='a2185560' visibility='default' filepath='include/linux/net.h' line='120' column='1'/>
+          <var-decl name='type' type-id='a2185560' visibility='default' filepath='include/linux/net.h' line='118' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='flags' type-id='7359adad' visibility='default' filepath='include/linux/net.h' line='122' column='1'/>
+          <var-decl name='flags' type-id='7359adad' visibility='default' filepath='include/linux/net.h' line='120' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='file' type-id='77e79a4b' visibility='default' filepath='include/linux/net.h' line='124' column='1'/>
+          <var-decl name='file' type-id='77e79a4b' visibility='default' filepath='include/linux/net.h' line='122' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='sk' type-id='f772df6d' visibility='default' filepath='include/linux/net.h' line='125' column='1'/>
+          <var-decl name='sk' type-id='f772df6d' visibility='default' filepath='include/linux/net.h' line='123' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='ops' type-id='38a81521' visibility='default' filepath='include/linux/net.h' line='126' column='1'/>
+          <var-decl name='ops' type-id='38a81521' visibility='default' filepath='include/linux/net.h' line='124' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='wq' type-id='8bd06fd9' visibility='default' filepath='include/linux/net.h' line='128' column='1'/>
+          <var-decl name='wq' type-id='8bd06fd9' visibility='default' filepath='include/linux/net.h' line='126' column='1'/>
         </data-member>
       </class-decl>
       <qualified-type-def type-id='8596da29' const='yes' id='ee15d052'/>
@@ -109628,21 +109809,21 @@
         <return type-id='48b5725f'/>
       </function-type>
       <pointer-type-def type-id='5900d865' size-in-bits='64' id='ef872b61'/>
-      <class-decl name='work_struct' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/workqueue.h' line='103' column='1' id='ef9025d0'>
+      <class-decl name='work_struct' size-in-bits='384' is-struct='yes' visibility='default' filepath='include/linux/workqueue.h' line='104' column='1' id='ef9025d0'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='data' type-id='f22a8abb' visibility='default' filepath='include/linux/workqueue.h' line='104' column='1'/>
+          <var-decl name='data' type-id='f22a8abb' visibility='default' filepath='include/linux/workqueue.h' line='105' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='entry' type-id='72f469ec' visibility='default' filepath='include/linux/workqueue.h' line='105' column='1'/>
+          <var-decl name='entry' type-id='72f469ec' visibility='default' filepath='include/linux/workqueue.h' line='106' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='func' type-id='72666d3f' visibility='default' filepath='include/linux/workqueue.h' line='106' column='1'/>
+          <var-decl name='func' type-id='72666d3f' visibility='default' filepath='include/linux/workqueue.h' line='107' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/workqueue.h' line='110' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/workqueue.h' line='111' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/workqueue.h' line='111' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/workqueue.h' line='112' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='0112baf0' size-in-bits='64' id='ef9eae4d'/>
@@ -110027,7 +110208,7 @@
         <subrange length='5' type-id='7ff19f0f' id='53010e10'/>
       </array-type-def>
       <pointer-type-def type-id='effb3702' size-in-bits='64' id='f077d3f8'/>
-      <enum-decl name='snd_soc_bias_level' filepath='include/sound/soc-dapm.h' line='392' column='1' id='f078c744'>
+      <enum-decl name='snd_soc_bias_level' filepath='include/sound/soc-dapm.h' line='393' column='1' id='f078c744'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='SND_SOC_BIAS_OFF' value='0'/>
         <enumerator name='SND_SOC_BIAS_STANDBY' value='1'/>
@@ -110333,36 +110514,36 @@
           <var-decl name='' type-id='7eabe5fc' visibility='default' filepath='include/net/sock.h' line='167' column='1'/>
         </data-member>
       </union-decl>
-      <class-decl name='netdev_rx_queue' size-in-bits='2048' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='764' column='1' id='f12ac4ae'>
+      <class-decl name='netdev_rx_queue' size-in-bits='2048' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='769' column='1' id='f12ac4ae'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='rps_map' type-id='f30dbff5' visibility='default' filepath='include/linux/netdevice.h' line='766' column='1'/>
+          <var-decl name='rps_map' type-id='f30dbff5' visibility='default' filepath='include/linux/netdevice.h' line='771' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='rps_flow_table' type-id='deff2378' visibility='default' filepath='include/linux/netdevice.h' line='767' column='1'/>
+          <var-decl name='rps_flow_table' type-id='deff2378' visibility='default' filepath='include/linux/netdevice.h' line='772' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='kobj' type-id='b6ab8849' visibility='default' filepath='include/linux/netdevice.h' line='769' column='1'/>
+          <var-decl name='kobj' type-id='b6ab8849' visibility='default' filepath='include/linux/netdevice.h' line='774' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='dev' type-id='68a2d05b' visibility='default' filepath='include/linux/netdevice.h' line='770' column='1'/>
+          <var-decl name='dev' type-id='68a2d05b' visibility='default' filepath='include/linux/netdevice.h' line='775' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='xdp_rxq' type-id='eb0d6f26' visibility='default' filepath='include/linux/netdevice.h' line='771' column='1'/>
+          <var-decl name='xdp_rxq' type-id='eb0d6f26' visibility='default' filepath='include/linux/netdevice.h' line='776' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1536'>
-          <var-decl name='pool' type-id='81e0c1b8' visibility='default' filepath='include/linux/netdevice.h' line='773' column='1'/>
+          <var-decl name='pool' type-id='81e0c1b8' visibility='default' filepath='include/linux/netdevice.h' line='778' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1600'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='776' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='781' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1664'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='777' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='782' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1728'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='778' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='783' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1792'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='779' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='784' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='97f95e6a' size-in-bits='64' id='f12b668c'/>
@@ -110601,12 +110782,12 @@
       </function-type>
       <pointer-type-def type-id='1027eea9' size-in-bits='64' id='f1dc7839'/>
       <pointer-type-def type-id='783f5582' size-in-bits='64' id='f1e196e0'/>
-      <class-decl name='netdev_tc_txq' size-in-bits='32' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='826' column='1' id='f1e1eb79'>
+      <class-decl name='netdev_tc_txq' size-in-bits='32' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='831' column='1' id='f1e1eb79'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='count' type-id='1dc6a898' visibility='default' filepath='include/linux/netdevice.h' line='827' column='1'/>
+          <var-decl name='count' type-id='1dc6a898' visibility='default' filepath='include/linux/netdevice.h' line='832' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='16'>
-          <var-decl name='offset' type-id='1dc6a898' visibility='default' filepath='include/linux/netdevice.h' line='828' column='1'/>
+          <var-decl name='offset' type-id='1dc6a898' visibility='default' filepath='include/linux/netdevice.h' line='833' column='1'/>
         </data-member>
       </class-decl>
       <enum-decl name='ethtool_link_ext_substate_link_training' filepath='include/uapi/linux/ethtool.h' line='615' column='1' id='f1e6b980'>
@@ -110765,21 +110946,21 @@
           <var-decl name='filter' type-id='e1ea11f6' visibility='default' filepath='include/linux/filter.h' line='529' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='iov_iter' size-in-bits='320' is-struct='yes' visibility='default' filepath='include/linux/uio.h' line='29' column='1' id='f2b4d088'>
+      <class-decl name='iov_iter' size-in-bits='320' is-struct='yes' visibility='default' filepath='include/linux/uio.h' line='35' column='1' id='f2b4d088'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='type' type-id='f0981eeb' visibility='default' filepath='include/linux/uio.h' line='35' column='1'/>
+          <var-decl name='type' type-id='f0981eeb' visibility='default' filepath='include/linux/uio.h' line='41' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='iov_offset' type-id='b59d7dce' visibility='default' filepath='include/linux/uio.h' line='36' column='1'/>
+          <var-decl name='iov_offset' type-id='b59d7dce' visibility='default' filepath='include/linux/uio.h' line='42' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='count' type-id='b59d7dce' visibility='default' filepath='include/linux/uio.h' line='37' column='1'/>
+          <var-decl name='count' type-id='b59d7dce' visibility='default' filepath='include/linux/uio.h' line='43' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='' type-id='9b26deed' visibility='default' filepath='include/linux/uio.h' line='38' column='1'/>
+          <var-decl name='' type-id='9b26deed' visibility='default' filepath='include/linux/uio.h' line='44' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='' type-id='e91837c2' visibility='default' filepath='include/linux/uio.h' line='44' column='1'/>
+          <var-decl name='' type-id='e91837c2' visibility='default' filepath='include/linux/uio.h' line='50' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='b5fdec5e' size-in-bits='64' id='f2bb3a9c'/>
@@ -111169,6 +111350,7 @@
         <parameter type-id='7e666abe'/>
         <return type-id='95e97e5e'/>
       </function-type>
+      <pointer-type-def type-id='bb5ec78c' size-in-bits='64' id='f34906ca'/>
       <pointer-type-def type-id='41cb24b3' size-in-bits='64' id='f3496bd3'/>
       <pointer-type-def type-id='5329c4da' size-in-bits='64' id='f34c7de4'/>
       <pointer-type-def type-id='4b8eb833' size-in-bits='64' id='f34cc61f'/>
@@ -111266,7 +111448,6 @@
           <var-decl name='memsw' type-id='635c3685' visibility='default' filepath='include/linux/memcontrol.h' line='222' column='1'/>
         </data-member>
       </union-decl>
-      <pointer-type-def type-id='74fec388' size-in-bits='64' id='f3a5c46a'/>
       <class-decl name='rc_scancode_filter' size-in-bits='64' is-struct='yes' visibility='default' filepath='include/media/rc-core.h' line='38' column='1' id='f3a6417e'>
         <data-member access='public' layout-offset-in-bits='0'>
           <var-decl name='data' type-id='19c2251e' visibility='default' filepath='include/media/rc-core.h' line='39' column='1'/>
@@ -112369,30 +112550,30 @@
       <array-type-def dimensions='1' type-id='fa0b179b' size-in-bits='512' id='f6e5abef'>
         <subrange length='8' type-id='7ff19f0f' id='56e0c0b1'/>
       </array-type-def>
-      <class-decl name='header_ops' size-in-bits='512' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='271' column='1' id='f6e7855b'>
+      <class-decl name='header_ops' size-in-bits='512' is-struct='yes' visibility='default' filepath='include/linux/netdevice.h' line='273' column='1' id='f6e7855b'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='create' type-id='e82aa0fb' visibility='default' filepath='include/linux/netdevice.h' line='272' column='1'/>
+          <var-decl name='create' type-id='e82aa0fb' visibility='default' filepath='include/linux/netdevice.h' line='274' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='parse' type-id='35b37061' visibility='default' filepath='include/linux/netdevice.h' line='275' column='1'/>
+          <var-decl name='parse' type-id='35b37061' visibility='default' filepath='include/linux/netdevice.h' line='277' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='cache' type-id='464a4247' visibility='default' filepath='include/linux/netdevice.h' line='276' column='1'/>
+          <var-decl name='cache' type-id='464a4247' visibility='default' filepath='include/linux/netdevice.h' line='278' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='cache_update' type-id='b713d448' visibility='default' filepath='include/linux/netdevice.h' line='277' column='1'/>
+          <var-decl name='cache_update' type-id='b713d448' visibility='default' filepath='include/linux/netdevice.h' line='279' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='validate' type-id='5a60e638' visibility='default' filepath='include/linux/netdevice.h' line='280' column='1'/>
+          <var-decl name='validate' type-id='5a60e638' visibility='default' filepath='include/linux/netdevice.h' line='282' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='parse_protocol' type-id='98c4c95a' visibility='default' filepath='include/linux/netdevice.h' line='281' column='1'/>
+          <var-decl name='parse_protocol' type-id='98c4c95a' visibility='default' filepath='include/linux/netdevice.h' line='283' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='283' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='285' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='284' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/netdevice.h' line='286' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='in6_addr' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/uapi/linux/in6.h' line='33' column='1' id='f6ed712a'>
@@ -112470,132 +112651,132 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='cdd79d4e' size-in-bits='64' id='f77c2568'/>
-      <class-decl name='tcp_fastopen_context' size-in-bits='448' is-struct='yes' visibility='default' filepath='include/net/tcp.h' line='1704' column='1' id='f77d4717'>
+      <class-decl name='tcp_fastopen_context' size-in-bits='448' is-struct='yes' visibility='default' filepath='include/net/tcp.h' line='1718' column='1' id='f77d4717'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='key' type-id='5b02a6fc' visibility='default' filepath='include/net/tcp.h' line='1705' column='1'/>
+          <var-decl name='key' type-id='5b02a6fc' visibility='default' filepath='include/net/tcp.h' line='1719' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='num' type-id='95e97e5e' visibility='default' filepath='include/net/tcp.h' line='1706' column='1'/>
+          <var-decl name='num' type-id='95e97e5e' visibility='default' filepath='include/net/tcp.h' line='1720' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/net/tcp.h' line='1707' column='1'/>
+          <var-decl name='rcu' type-id='e3d8ce29' visibility='default' filepath='include/net/tcp.h' line='1721' column='1'/>
         </data-member>
       </class-decl>
       <qualified-type-def type-id='e0584be6' const='yes' id='f7803e3d'/>
-      <class-decl name='snd_soc_dapm_widget' size-in-bits='2560' is-struct='yes' visibility='default' filepath='include/sound/soc-dapm.h' line='616' column='1' id='f780d556'>
+      <class-decl name='snd_soc_dapm_widget' size-in-bits='2560' is-struct='yes' visibility='default' filepath='include/sound/soc-dapm.h' line='617' column='1' id='f780d556'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='id' type-id='68bb1ec5' visibility='default' filepath='include/sound/soc-dapm.h' line='617' column='1'/>
+          <var-decl name='id' type-id='68bb1ec5' visibility='default' filepath='include/sound/soc-dapm.h' line='618' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='name' type-id='80f4b756' visibility='default' filepath='include/sound/soc-dapm.h' line='618' column='1'/>
+          <var-decl name='name' type-id='80f4b756' visibility='default' filepath='include/sound/soc-dapm.h' line='619' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='sname' type-id='80f4b756' visibility='default' filepath='include/sound/soc-dapm.h' line='619' column='1'/>
+          <var-decl name='sname' type-id='80f4b756' visibility='default' filepath='include/sound/soc-dapm.h' line='620' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/sound/soc-dapm.h' line='620' column='1'/>
+          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/sound/soc-dapm.h' line='621' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='dapm' type-id='70d004a5' visibility='default' filepath='include/sound/soc-dapm.h' line='621' column='1'/>
+          <var-decl name='dapm' type-id='70d004a5' visibility='default' filepath='include/sound/soc-dapm.h' line='622' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='priv' type-id='eaa32e2f' visibility='default' filepath='include/sound/soc-dapm.h' line='623' column='1'/>
+          <var-decl name='priv' type-id='eaa32e2f' visibility='default' filepath='include/sound/soc-dapm.h' line='624' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='regulator' type-id='850c13f6' visibility='default' filepath='include/sound/soc-dapm.h' line='624' column='1'/>
+          <var-decl name='regulator' type-id='850c13f6' visibility='default' filepath='include/sound/soc-dapm.h' line='625' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='pinctrl' type-id='73ea90c5' visibility='default' filepath='include/sound/soc-dapm.h' line='625' column='1'/>
+          <var-decl name='pinctrl' type-id='73ea90c5' visibility='default' filepath='include/sound/soc-dapm.h' line='626' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='576'>
-          <var-decl name='reg' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='628' column='1'/>
+          <var-decl name='reg' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='629' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='608'>
-          <var-decl name='shift' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='629' column='1'/>
+          <var-decl name='shift' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='630' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='mask' type-id='f0981eeb' visibility='default' filepath='include/sound/soc-dapm.h' line='630' column='1'/>
+          <var-decl name='mask' type-id='f0981eeb' visibility='default' filepath='include/sound/soc-dapm.h' line='631' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='672'>
-          <var-decl name='on_val' type-id='f0981eeb' visibility='default' filepath='include/sound/soc-dapm.h' line='631' column='1'/>
+          <var-decl name='on_val' type-id='f0981eeb' visibility='default' filepath='include/sound/soc-dapm.h' line='632' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='704'>
-          <var-decl name='off_val' type-id='f0981eeb' visibility='default' filepath='include/sound/soc-dapm.h' line='632' column='1'/>
+          <var-decl name='off_val' type-id='f0981eeb' visibility='default' filepath='include/sound/soc-dapm.h' line='633' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='power' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='633' column='1'/>
+          <var-decl name='power' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='634' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1'>
-          <var-decl name='active' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='634' column='1'/>
+          <var-decl name='active' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='635' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2'>
-          <var-decl name='connected' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='635' column='1'/>
+          <var-decl name='connected' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='636' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='3'>
-          <var-decl name='new' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='636' column='1'/>
+          <var-decl name='new' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='637' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='4'>
-          <var-decl name='force' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='637' column='1'/>
+          <var-decl name='force' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='638' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='5'>
-          <var-decl name='ignore_suspend' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='638' column='1'/>
+          <var-decl name='ignore_suspend' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='639' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='6'>
-          <var-decl name='new_power' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='639' column='1'/>
+          <var-decl name='new_power' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='640' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='7'>
-          <var-decl name='power_checked' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='640' column='1'/>
+          <var-decl name='power_checked' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='641' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='is_supply' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='641' column='1'/>
+          <var-decl name='is_supply' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='642' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1'>
-          <var-decl name='is_ep' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='642' column='1'/>
+          <var-decl name='is_ep' type-id='002ac4a6' visibility='default' filepath='include/sound/soc-dapm.h' line='643' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='subseq' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='643' column='1'/>
+          <var-decl name='subseq' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='644' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='832'>
-          <var-decl name='power_check' type-id='3fccea10' visibility='default' filepath='include/sound/soc-dapm.h' line='645' column='1'/>
+          <var-decl name='power_check' type-id='3fccea10' visibility='default' filepath='include/sound/soc-dapm.h' line='646' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='event_flags' type-id='8efea9e5' visibility='default' filepath='include/sound/soc-dapm.h' line='648' column='1'/>
+          <var-decl name='event_flags' type-id='8efea9e5' visibility='default' filepath='include/sound/soc-dapm.h' line='649' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='event' type-id='af92413d' visibility='default' filepath='include/sound/soc-dapm.h' line='649' column='1'/>
+          <var-decl name='event' type-id='af92413d' visibility='default' filepath='include/sound/soc-dapm.h' line='650' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='num_kcontrols' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='652' column='1'/>
+          <var-decl name='num_kcontrols' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='653' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1088'>
-          <var-decl name='kcontrol_news' type-id='31e035f7' visibility='default' filepath='include/sound/soc-dapm.h' line='653' column='1'/>
+          <var-decl name='kcontrol_news' type-id='31e035f7' visibility='default' filepath='include/sound/soc-dapm.h' line='654' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='kcontrols' type-id='29753327' visibility='default' filepath='include/sound/soc-dapm.h' line='654' column='1'/>
+          <var-decl name='kcontrols' type-id='29753327' visibility='default' filepath='include/sound/soc-dapm.h' line='655' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='dobj' type-id='01edcafc' visibility='default' filepath='include/sound/soc-dapm.h' line='655' column='1'/>
+          <var-decl name='dobj' type-id='01edcafc' visibility='default' filepath='include/sound/soc-dapm.h' line='656' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1728'>
-          <var-decl name='edges' type-id='e4f16420' visibility='default' filepath='include/sound/soc-dapm.h' line='658' column='1'/>
+          <var-decl name='edges' type-id='e4f16420' visibility='default' filepath='include/sound/soc-dapm.h' line='659' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1984'>
-          <var-decl name='work_list' type-id='72f469ec' visibility='default' filepath='include/sound/soc-dapm.h' line='661' column='1'/>
+          <var-decl name='work_list' type-id='72f469ec' visibility='default' filepath='include/sound/soc-dapm.h' line='662' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2112'>
-          <var-decl name='power_list' type-id='72f469ec' visibility='default' filepath='include/sound/soc-dapm.h' line='662' column='1'/>
+          <var-decl name='power_list' type-id='72f469ec' visibility='default' filepath='include/sound/soc-dapm.h' line='663' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2240'>
-          <var-decl name='dirty' type-id='72f469ec' visibility='default' filepath='include/sound/soc-dapm.h' line='663' column='1'/>
+          <var-decl name='dirty' type-id='72f469ec' visibility='default' filepath='include/sound/soc-dapm.h' line='664' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2368'>
-          <var-decl name='endpoints' type-id='e4266c7e' visibility='default' filepath='include/sound/soc-dapm.h' line='664' column='1'/>
+          <var-decl name='endpoints' type-id='e4266c7e' visibility='default' filepath='include/sound/soc-dapm.h' line='665' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2432'>
-          <var-decl name='clk' type-id='7d0bc0eb' visibility='default' filepath='include/sound/soc-dapm.h' line='666' column='1'/>
+          <var-decl name='clk' type-id='7d0bc0eb' visibility='default' filepath='include/sound/soc-dapm.h' line='667' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='2496'>
-          <var-decl name='channel' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='668' column='1'/>
+          <var-decl name='channel' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='669' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='769f1ed1' size-in-bits='64' id='f79a6dd9'/>
@@ -112628,9 +112809,9 @@
           <var-decl name='compare' type-id='bfc146e4' visibility='default' filepath='include/linux/netlink.h' line='51' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/netdevice.h' line='937' column='1' id='f7a2361f'>
+      <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/netdevice.h' line='942' column='1' id='f7a2361f'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='offmap' type-id='366d2695' visibility='default' filepath='include/linux/netdevice.h' line='938' column='1'/>
+          <var-decl name='offmap' type-id='366d2695' visibility='default' filepath='include/linux/netdevice.h' line='943' column='1'/>
         </data-member>
       </class-decl>
       <array-type-def dimensions='1' type-id='84dc82b7' size-in-bits='infinite' id='f7aeb09b'>
@@ -113611,6 +113792,17 @@
       </class-decl>
       <pointer-type-def type-id='12506762' size-in-bits='64' id='fa013de0'/>
       <pointer-type-def type-id='91f77fa3' size-in-bits='64' id='fa058983'/>
+      <class-decl name='udp_hslot' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/net/udp.h' line='58' column='1' id='fa07ab8f'>
+        <data-member access='public' layout-offset-in-bits='0'>
+          <var-decl name='head' type-id='e151255a' visibility='default' filepath='include/net/udp.h' line='59' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='64'>
+          <var-decl name='count' type-id='95e97e5e' visibility='default' filepath='include/net/udp.h' line='60' column='1'/>
+        </data-member>
+        <data-member access='public' layout-offset-in-bits='96'>
+          <var-decl name='lock' type-id='fb4018a0' visibility='default' filepath='include/net/udp.h' line='61' column='1'/>
+        </data-member>
+      </class-decl>
       <array-type-def dimensions='2' type-id='8f048e17' size-in-bits='304' id='fa0a1f4c'>
         <subrange length='2' type-id='7ff19f0f' id='52efc4ef'/>
         <subrange length='19' type-id='7ff19f0f' id='448ee30f'/>
@@ -113743,78 +113935,78 @@
       <pointer-type-def type-id='7d43ac00' size-in-bits='64' id='fa3ed3a2'/>
       <pointer-type-def type-id='038d05bd' size-in-bits='64' id='fa43ef1d'/>
       <pointer-type-def type-id='4e0b8246' size-in-bits='64' id='fa4d54c3'/>
-      <class-decl name='usb_bus' size-in-bits='1408' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='435' column='1' id='fa4d7704'>
+      <class-decl name='usb_bus' size-in-bits='1408' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='440' column='1' id='fa4d7704'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='controller' type-id='fa0b179b' visibility='default' filepath='include/linux/usb.h' line='436' column='1'/>
+          <var-decl name='controller' type-id='fa0b179b' visibility='default' filepath='include/linux/usb.h' line='441' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='sysdev' type-id='fa0b179b' visibility='default' filepath='include/linux/usb.h' line='437' column='1'/>
+          <var-decl name='sysdev' type-id='fa0b179b' visibility='default' filepath='include/linux/usb.h' line='442' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='busnum' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='438' column='1'/>
+          <var-decl name='busnum' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='443' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='bus_name' type-id='80f4b756' visibility='default' filepath='include/linux/usb.h' line='439' column='1'/>
+          <var-decl name='bus_name' type-id='80f4b756' visibility='default' filepath='include/linux/usb.h' line='444' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='uses_pio_for_control' type-id='f9b06939' visibility='default' filepath='include/linux/usb.h' line='440' column='1'/>
+          <var-decl name='uses_pio_for_control' type-id='f9b06939' visibility='default' filepath='include/linux/usb.h' line='445' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='264'>
-          <var-decl name='otg_port' type-id='f9b06939' visibility='default' filepath='include/linux/usb.h' line='444' column='1'/>
+          <var-decl name='otg_port' type-id='f9b06939' visibility='default' filepath='include/linux/usb.h' line='449' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='16'>
-          <var-decl name='is_b_host' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='445' column='1'/>
+          <var-decl name='is_b_host' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='450' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='17'>
-          <var-decl name='b_hnp_enable' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='446' column='1'/>
+          <var-decl name='b_hnp_enable' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='451' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='18'>
-          <var-decl name='no_stop_on_short' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='447' column='1'/>
+          <var-decl name='no_stop_on_short' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='452' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='19'>
-          <var-decl name='no_sg_constraint' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='452' column='1'/>
+          <var-decl name='no_sg_constraint' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='457' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='288'>
-          <var-decl name='sg_tablesize' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='453' column='1'/>
+          <var-decl name='sg_tablesize' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='458' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='devnum_next' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='455' column='1'/>
+          <var-decl name='devnum_next' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='460' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='devnum_next_mutex' type-id='925167dc' visibility='default' filepath='include/linux/usb.h' line='457' column='1'/>
+          <var-decl name='devnum_next_mutex' type-id='925167dc' visibility='default' filepath='include/linux/usb.h' line='462' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='768'>
-          <var-decl name='devmap' type-id='d78885c5' visibility='default' filepath='include/linux/usb.h' line='459' column='1'/>
+          <var-decl name='devmap' type-id='d78885c5' visibility='default' filepath='include/linux/usb.h' line='464' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='896'>
-          <var-decl name='root_hub' type-id='25e60cb2' visibility='default' filepath='include/linux/usb.h' line='460' column='1'/>
+          <var-decl name='root_hub' type-id='25e60cb2' visibility='default' filepath='include/linux/usb.h' line='465' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='960'>
-          <var-decl name='hs_companion' type-id='3ab7d422' visibility='default' filepath='include/linux/usb.h' line='461' column='1'/>
+          <var-decl name='hs_companion' type-id='3ab7d422' visibility='default' filepath='include/linux/usb.h' line='466' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1024'>
-          <var-decl name='bandwidth_allocated' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='463' column='1'/>
+          <var-decl name='bandwidth_allocated' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='468' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1056'>
-          <var-decl name='bandwidth_int_reqs' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='470' column='1'/>
+          <var-decl name='bandwidth_int_reqs' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='475' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1088'>
-          <var-decl name='bandwidth_isoc_reqs' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='471' column='1'/>
+          <var-decl name='bandwidth_isoc_reqs' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='476' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1120'>
-          <var-decl name='resuming_ports' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='473' column='1'/>
+          <var-decl name='resuming_ports' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='478' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1152'>
-          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='480' column='1'/>
+          <var-decl name='android_kabi_reserved1' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='485' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1216'>
-          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='481' column='1'/>
+          <var-decl name='android_kabi_reserved2' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='486' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1280'>
-          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='482' column='1'/>
+          <var-decl name='android_kabi_reserved3' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='487' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='1344'>
-          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='483' column='1'/>
+          <var-decl name='android_kabi_reserved4' type-id='91ce1af9' visibility='default' filepath='include/linux/usb.h' line='488' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='fa5149d8'>
@@ -113833,7 +114025,7 @@
         <enumerator name='ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE' value='1'/>
         <enumerator name='ETHTOOL_LINK_EXT_SUBSTATE_CI_CABLE_TEST_FAILURE' value='2'/>
       </enum-decl>
-      <enum-decl name='bpf_netdev_command' filepath='include/linux/netdevice.h' line='893' column='1' id='fa64b30d'>
+      <enum-decl name='bpf_netdev_command' filepath='include/linux/netdevice.h' line='898' column='1' id='fa64b30d'>
         <underlying-type type-id='9cac1fee'/>
         <enumerator name='XDP_SETUP_PROG' value='0'/>
         <enumerator name='XDP_SETUP_PROG_HW' value='1'/>
@@ -114301,15 +114493,15 @@
         <return type-id='95e97e5e'/>
       </function-type>
       <typedef-decl name='spinlock_t' type-id='53fb272e' filepath='include/linux/spinlock_types.h' line='83' column='1' id='fb4018a0'/>
-      <class-decl name='sb_writers' size-in-bits='2560' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='1444' column='1' id='fb476a2b'>
+      <class-decl name='sb_writers' size-in-bits='2560' is-struct='yes' visibility='default' filepath='include/linux/fs.h' line='1450' column='1' id='fb476a2b'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='frozen' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='1445' column='1'/>
+          <var-decl name='frozen' type-id='95e97e5e' visibility='default' filepath='include/linux/fs.h' line='1451' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='wait_unfrozen' type-id='b5ab048f' visibility='default' filepath='include/linux/fs.h' line='1446' column='1'/>
+          <var-decl name='wait_unfrozen' type-id='b5ab048f' visibility='default' filepath='include/linux/fs.h' line='1452' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='rw_sem' type-id='a09ef5a6' visibility='default' filepath='include/linux/fs.h' line='1447' column='1'/>
+          <var-decl name='rw_sem' type-id='a09ef5a6' visibility='default' filepath='include/linux/fs.h' line='1453' column='1'/>
         </data-member>
       </class-decl>
       <qualified-type-def type-id='0f042891' const='yes' id='fb4943b2'/>
@@ -114642,18 +114834,18 @@
       </class-decl>
       <pointer-type-def type-id='392af4e9' size-in-bits='64' id='fc4f83c1'/>
       <pointer-type-def type-id='58dbb714' size-in-bits='64' id='fc616182'/>
-      <class-decl name='usb_iso_packet_descriptor' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='1379' column='1' id='fc6d031c'>
+      <class-decl name='usb_iso_packet_descriptor' size-in-bits='128' is-struct='yes' visibility='default' filepath='include/linux/usb.h' line='1387' column='1' id='fc6d031c'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='offset' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1380' column='1'/>
+          <var-decl name='offset' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1388' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='length' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1381' column='1'/>
+          <var-decl name='length' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1389' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='actual_length' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1382' column='1'/>
+          <var-decl name='actual_length' type-id='f0981eeb' visibility='default' filepath='include/linux/usb.h' line='1390' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='96'>
-          <var-decl name='status' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1383' column='1'/>
+          <var-decl name='status' type-id='95e97e5e' visibility='default' filepath='include/linux/usb.h' line='1391' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='4234e231' size-in-bits='64' id='fc6f14a9'/>
@@ -114762,33 +114954,33 @@
       </class-decl>
       <pointer-type-def type-id='1f54f780' size-in-bits='64' id='fcc1e09e'/>
       <pointer-type-def type-id='37d5ca21' size-in-bits='64' id='fcca6c75'/>
-      <class-decl name='tcp_ulp_ops' size-in-bits='704' is-struct='yes' visibility='default' filepath='include/net/tcp.h' line='2198' column='1' id='fccb029f'>
+      <class-decl name='tcp_ulp_ops' size-in-bits='704' is-struct='yes' visibility='default' filepath='include/net/tcp.h' line='2216' column='1' id='fccb029f'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/net/tcp.h' line='2199' column='1'/>
+          <var-decl name='list' type-id='72f469ec' visibility='default' filepath='include/net/tcp.h' line='2217' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='init' type-id='55530c47' visibility='default' filepath='include/net/tcp.h' line='2202' column='1'/>
+          <var-decl name='init' type-id='55530c47' visibility='default' filepath='include/net/tcp.h' line='2220' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='192'>
-          <var-decl name='update' type-id='58220cf1' visibility='default' filepath='include/net/tcp.h' line='2204' column='1'/>
+          <var-decl name='update' type-id='58220cf1' visibility='default' filepath='include/net/tcp.h' line='2222' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='256'>
-          <var-decl name='release' type-id='841969d0' visibility='default' filepath='include/net/tcp.h' line='2207' column='1'/>
+          <var-decl name='release' type-id='841969d0' visibility='default' filepath='include/net/tcp.h' line='2225' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='320'>
-          <var-decl name='get_info' type-id='684afc90' visibility='default' filepath='include/net/tcp.h' line='2209' column='1'/>
+          <var-decl name='get_info' type-id='684afc90' visibility='default' filepath='include/net/tcp.h' line='2227' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='384'>
-          <var-decl name='get_info_size' type-id='08a11828' visibility='default' filepath='include/net/tcp.h' line='2210' column='1'/>
+          <var-decl name='get_info_size' type-id='08a11828' visibility='default' filepath='include/net/tcp.h' line='2228' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='448'>
-          <var-decl name='clone' type-id='e9e8c0f8' visibility='default' filepath='include/net/tcp.h' line='2212' column='1'/>
+          <var-decl name='clone' type-id='e9e8c0f8' visibility='default' filepath='include/net/tcp.h' line='2230' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='512'>
-          <var-decl name='name' type-id='ac1fa8c0' visibility='default' filepath='include/net/tcp.h' line='2215' column='1'/>
+          <var-decl name='name' type-id='ac1fa8c0' visibility='default' filepath='include/net/tcp.h' line='2233' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='640'>
-          <var-decl name='owner' type-id='2730d015' visibility='default' filepath='include/net/tcp.h' line='2216' column='1'/>
+          <var-decl name='owner' type-id='2730d015' visibility='default' filepath='include/net/tcp.h' line='2234' column='1'/>
         </data-member>
       </class-decl>
       <pointer-type-def type-id='c12c58ce' size-in-bits='64' id='fccfeeec'/>
@@ -115481,15 +115673,15 @@
         </data-member>
       </class-decl>
       <pointer-type-def type-id='e32cf39f' size-in-bits='64' id='fe3af88b'/>
-      <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='720' column='1' id='fe3b99ac'>
+      <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='include/linux/skbuff.h' line='722' column='1' id='fe3b99ac'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='next' type-id='0fbf3cfd' visibility='default' filepath='include/linux/skbuff.h' line='722' column='1'/>
+          <var-decl name='next' type-id='0fbf3cfd' visibility='default' filepath='include/linux/skbuff.h' line='724' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='prev' type-id='0fbf3cfd' visibility='default' filepath='include/linux/skbuff.h' line='723' column='1'/>
+          <var-decl name='prev' type-id='0fbf3cfd' visibility='default' filepath='include/linux/skbuff.h' line='725' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='128'>
-          <var-decl name='' type-id='1285aa79' visibility='default' filepath='include/linux/skbuff.h' line='725' column='1'/>
+          <var-decl name='' type-id='1285aa79' visibility='default' filepath='include/linux/skbuff.h' line='727' column='1'/>
         </data-member>
       </class-decl>
       <function-type size-in-bits='64' id='fe3cfa56'>
@@ -115929,15 +116121,15 @@
           <var-decl name='domain_free_irqs' type-id='1b27c119' visibility='default' filepath='include/linux/msi.h' line='322' column='1'/>
         </data-member>
       </class-decl>
-      <class-decl name='snd_soc_dapm_stats' size-in-bits='96' is-struct='yes' visibility='default' filepath='include/sound/soc-dapm.h' line='720' column='1' id='fef29e19'>
+      <class-decl name='snd_soc_dapm_stats' size-in-bits='96' is-struct='yes' visibility='default' filepath='include/sound/soc-dapm.h' line='721' column='1' id='fef29e19'>
         <data-member access='public' layout-offset-in-bits='0'>
-          <var-decl name='power_checks' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='721' column='1'/>
+          <var-decl name='power_checks' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='722' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='32'>
-          <var-decl name='path_checks' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='722' column='1'/>
+          <var-decl name='path_checks' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='723' column='1'/>
         </data-member>
         <data-member access='public' layout-offset-in-bits='64'>
-          <var-decl name='neighbour_checks' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='723' column='1'/>
+          <var-decl name='neighbour_checks' type-id='95e97e5e' visibility='default' filepath='include/sound/soc-dapm.h' line='724' column='1'/>
         </data-member>
       </class-decl>
       <class-decl name='snd_enc_wma' size-in-bits='32' is-struct='yes' visibility='default' filepath='include/uapi/sound/compress_params.h' line='247' column='1' id='fef670ff'>
@@ -116329,25 +116521,25 @@
       </function-type>
       <pointer-type-def type-id='46f53066' size-in-bits='64' id='fffb07a4'/>
       <qualified-type-def type-id='55efd1a3' const='yes' id='fffdaf52'/>
-      <var-decl name='GKI_struct_gic_chip_data' type-id='d3100295' mangled-name='GKI_struct_gic_chip_data' visibility='default' filepath='drivers/android/vendor_hooks.c' line='481' column='1' elf-symbol-id='GKI_struct_gic_chip_data'/>
+      <var-decl name='GKI_struct_gic_chip_data' type-id='d3100295' mangled-name='GKI_struct_gic_chip_data' visibility='default' filepath='drivers/android/vendor_hooks.c' line='507' column='1' elf-symbol-id='GKI_struct_gic_chip_data'/>
       <var-decl name='GKI_struct_selinux_state' type-id='4ae52763' mangled-name='GKI_struct_selinux_state' visibility='default' filepath='security/selinux/vendor_hooks.c' line='21' column='1' elf-symbol-id='GKI_struct_selinux_state'/>
-      <var-decl name='GKI_struct_swap_slots_cache' type-id='30eaa112' mangled-name='GKI_struct_swap_slots_cache' visibility='default' filepath='drivers/android/vendor_hooks.c' line='486' column='1' elf-symbol-id='GKI_struct_swap_slots_cache'/>
+      <var-decl name='GKI_struct_swap_slots_cache' type-id='30eaa112' mangled-name='GKI_struct_swap_slots_cache' visibility='default' filepath='drivers/android/vendor_hooks.c' line='512' column='1' elf-symbol-id='GKI_struct_swap_slots_cache'/>
       <function-decl name='PDE_DATA' mangled-name='PDE_DATA' filepath='fs/proc/generic.c' line='802' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PDE_DATA'>
         <parameter type-id='c5a4eb7f' name='inode' filepath='fs/proc/generic.c' line='802' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='__ClearPageMovable' mangled-name='__ClearPageMovable' filepath='mm/compaction.c' line='138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__ClearPageMovable'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/compaction.c' line='138' column='1'/>
+      <function-decl name='__ClearPageMovable' mangled-name='__ClearPageMovable' filepath='mm/compaction.c' line='143' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__ClearPageMovable'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/compaction.c' line='143' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__SetPageMovable' mangled-name='__SetPageMovable' filepath='mm/compaction.c' line='130' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__SetPageMovable'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/compaction.c' line='130' column='1'/>
-        <parameter type-id='f57039f0' name='mapping' filepath='mm/compaction.c' line='130' column='1'/>
+      <function-decl name='__SetPageMovable' mangled-name='__SetPageMovable' filepath='mm/compaction.c' line='135' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__SetPageMovable'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/compaction.c' line='135' column='1'/>
+        <parameter type-id='f57039f0' name='mapping' filepath='mm/compaction.c' line='135' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='___pskb_trim' mangled-name='___pskb_trim' filepath='net/core/skbuff.c' line='1967' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='___pskb_trim'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1967' column='1'/>
-        <parameter type-id='f0981eeb' name='len' filepath='net/core/skbuff.c' line='1967' column='1'/>
+      <function-decl name='___pskb_trim' mangled-name='___pskb_trim' filepath='net/core/skbuff.c' line='1966' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='___pskb_trim'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1966' column='1'/>
+        <parameter type-id='f0981eeb' name='len' filepath='net/core/skbuff.c' line='1966' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='___ratelimit' mangled-name='___ratelimit' filepath='lib/ratelimit.c' line='27' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='___ratelimit'>
@@ -116360,11 +116552,11 @@
         <parameter type-id='95e97e5e' name='node_id' filepath='block/genhd.c' line='1715' column='1'/>
         <return type-id='33c599da'/>
       </function-decl>
-      <function-decl name='__alloc_pages_nodemask' mangled-name='__alloc_pages_nodemask' filepath='mm/page_alloc.c' line='5142' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__alloc_pages_nodemask'>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/page_alloc.c' line='5142' column='1'/>
-        <parameter type-id='f0981eeb' name='order' filepath='mm/page_alloc.c' line='5142' column='1'/>
-        <parameter type-id='95e97e5e' name='preferred_nid' filepath='mm/page_alloc.c' line='5142' column='1'/>
-        <parameter type-id='f461c050' name='nodemask' filepath='mm/page_alloc.c' line='5143' column='1'/>
+      <function-decl name='__alloc_pages_nodemask' mangled-name='__alloc_pages_nodemask' filepath='mm/page_alloc.c' line='5171' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__alloc_pages_nodemask'>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/page_alloc.c' line='5171' column='1'/>
+        <parameter type-id='f0981eeb' name='order' filepath='mm/page_alloc.c' line='5171' column='1'/>
+        <parameter type-id='95e97e5e' name='preferred_nid' filepath='mm/page_alloc.c' line='5171' column='1'/>
+        <parameter type-id='f461c050' name='nodemask' filepath='mm/page_alloc.c' line='5172' column='1'/>
         <return type-id='02f11ed4'/>
       </function-decl>
       <function-decl name='__alloc_percpu' mangled-name='__alloc_percpu' filepath='mm/percpu.c' line='1904' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__alloc_percpu'>
@@ -116389,10 +116581,10 @@
         <parameter type-id='c485c22c' name='bh' filepath='fs/buffer.c' line='1185' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__bio_crypt_clone' mangled-name='__bio_crypt_clone' filepath='block/blk-crypto.c' line='107' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__bio_crypt_clone'>
-        <parameter type-id='fb55efa1' name='dst' filepath='block/blk-crypto.c' line='107' column='1'/>
-        <parameter type-id='fb55efa1' name='src' filepath='block/blk-crypto.c' line='107' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='block/blk-crypto.c' line='107' column='1'/>
+      <function-decl name='__bio_crypt_clone' mangled-name='__bio_crypt_clone' filepath='block/blk-crypto.c' line='108' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__bio_crypt_clone'>
+        <parameter type-id='fb55efa1' name='dst' filepath='block/blk-crypto.c' line='108' column='1'/>
+        <parameter type-id='fb55efa1' name='src' filepath='block/blk-crypto.c' line='108' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='block/blk-crypto.c' line='108' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__bitmap_and' mangled-name='__bitmap_and' filepath='lib/bitmap.c' line='240' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__bitmap_and'>
@@ -116465,9 +116657,9 @@
         <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq-debugfs.c' line='331' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__blk_mq_end_request' mangled-name='__blk_mq_end_request' filepath='block/blk-mq.c' line='541' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__blk_mq_end_request'>
-        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='541' column='1'/>
-        <parameter type-id='f4e2facd' name='error' filepath='block/blk-mq.c' line='541' column='1'/>
+      <function-decl name='__blk_mq_end_request' mangled-name='__blk_mq_end_request' filepath='block/blk-mq.c' line='542' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__blk_mq_end_request'>
+        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='542' column='1'/>
+        <parameter type-id='f4e2facd' name='error' filepath='block/blk-mq.c' line='542' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='__blk_rq_map_sg' mangled-name='__blk_rq_map_sg' filepath='block/blk-merge.c' line='525' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__blk_rq_map_sg'>
@@ -116539,10 +116731,10 @@
         <parameter type-id='b50a4934' name='to_user' filepath='mm/usercopy.c' line='256' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__class_create' mangled-name='__class_create' filepath='drivers/base/class.c' line='226' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__class_create'>
-        <parameter type-id='2730d015' name='owner' filepath='drivers/base/class.c' line='226' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='drivers/base/class.c' line='226' column='1'/>
-        <parameter type-id='a57283f9' name='key' filepath='drivers/base/class.c' line='227' column='1'/>
+      <function-decl name='__class_create' mangled-name='__class_create' filepath='drivers/base/class.c' line='231' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__class_create'>
+        <parameter type-id='2730d015' name='owner' filepath='drivers/base/class.c' line='231' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='drivers/base/class.c' line='231' column='1'/>
+        <parameter type-id='a57283f9' name='key' filepath='drivers/base/class.c' line='232' column='1'/>
         <return type-id='67aca04f'/>
       </function-decl>
       <function-decl name='__class_register' mangled-name='__class_register' filepath='drivers/base/class.c' line='153' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__class_register'>
@@ -116558,17 +116750,17 @@
         <parameter type-id='f57039f0' name='mapping' filepath='mm/cleancache.c' line='273' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__clk_determine_rate' mangled-name='__clk_determine_rate' filepath='drivers/clk/clk.c' line='1445' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__clk_determine_rate'>
-        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='1445' column='1'/>
-        <parameter type-id='23a0ad0a' name='req' filepath='drivers/clk/clk.c' line='1445' column='1'/>
+      <function-decl name='__clk_determine_rate' mangled-name='__clk_determine_rate' filepath='drivers/clk/clk.c' line='1456' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__clk_determine_rate'>
+        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='1456' column='1'/>
+        <parameter type-id='23a0ad0a' name='req' filepath='drivers/clk/clk.c' line='1456' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__clk_get_hw' mangled-name='__clk_get_hw' filepath='drivers/clk/clk.c' line='278' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__clk_get_hw'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='278' column='1'/>
+      <function-decl name='__clk_get_hw' mangled-name='__clk_get_hw' filepath='drivers/clk/clk.c' line='289' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__clk_get_hw'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='289' column='1'/>
         <return type-id='3aaeef89'/>
       </function-decl>
-      <function-decl name='__clk_get_name' mangled-name='__clk_get_name' filepath='drivers/clk/clk.c' line='266' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__clk_get_name'>
-        <parameter type-id='10f66866' name='clk' filepath='drivers/clk/clk.c' line='266' column='1'/>
+      <function-decl name='__clk_get_name' mangled-name='__clk_get_name' filepath='drivers/clk/clk.c' line='277' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__clk_get_name'>
+        <parameter type-id='10f66866' name='clk' filepath='drivers/clk/clk.c' line='277' column='1'/>
         <return type-id='80f4b756'/>
       </function-decl>
       <function-decl name='__clk_hw_register_divider' mangled-name='__clk_hw_register_divider' filepath='drivers/clk/clk-divider.c' line='466' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__clk_hw_register_divider'>
@@ -116631,18 +116823,18 @@
         <parameter type-id='cff2d845' name='lock' filepath='drivers/clk/clk-mux.c' line='154' column='1'/>
         <return type-id='3aaeef89'/>
       </function-decl>
-      <function-decl name='__clk_is_enabled' mangled-name='__clk_is_enabled' filepath='drivers/clk/clk.c' line='529' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__clk_is_enabled'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='529' column='1'/>
+      <function-decl name='__clk_is_enabled' mangled-name='__clk_is_enabled' filepath='drivers/clk/clk.c' line='540' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__clk_is_enabled'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='540' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='__clk_mux_determine_rate' mangled-name='__clk_mux_determine_rate' filepath='drivers/clk/clk.c' line='673' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__clk_mux_determine_rate'>
-        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='673' column='1'/>
-        <parameter type-id='23a0ad0a' name='req' filepath='drivers/clk/clk.c' line='674' column='1'/>
+      <function-decl name='__clk_mux_determine_rate' mangled-name='__clk_mux_determine_rate' filepath='drivers/clk/clk.c' line='684' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__clk_mux_determine_rate'>
+        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='684' column='1'/>
+        <parameter type-id='23a0ad0a' name='req' filepath='drivers/clk/clk.c' line='685' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__clk_mux_determine_rate_closest' mangled-name='__clk_mux_determine_rate_closest' filepath='drivers/clk/clk.c' line='680' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__clk_mux_determine_rate_closest'>
-        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='680' column='1'/>
-        <parameter type-id='23a0ad0a' name='req' filepath='drivers/clk/clk.c' line='681' column='1'/>
+      <function-decl name='__clk_mux_determine_rate_closest' mangled-name='__clk_mux_determine_rate_closest' filepath='drivers/clk/clk.c' line='691' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__clk_mux_determine_rate_closest'>
+        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='691' column='1'/>
+        <parameter type-id='23a0ad0a' name='req' filepath='drivers/clk/clk.c' line='692' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__clocksource_register_scale' mangled-name='__clocksource_register_scale' filepath='kernel/time/clocksource.c' line='1026' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__clocksource_register_scale'>
@@ -116651,19 +116843,19 @@
         <parameter type-id='19c2251e' name='freq' filepath='kernel/time/clocksource.c' line='1026' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__close_fd' mangled-name='__close_fd' filepath='fs/file.c' line='692' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__close_fd'>
-        <parameter type-id='16c53416' name='files' filepath='fs/file.c' line='692' column='1'/>
-        <parameter type-id='f0981eeb' name='fd' filepath='fs/file.c' line='692' column='1'/>
+      <function-decl name='__close_fd' mangled-name='__close_fd' filepath='fs/file.c' line='695' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__close_fd'>
+        <parameter type-id='16c53416' name='files' filepath='fs/file.c' line='695' column='1'/>
+        <parameter type-id='f0981eeb' name='fd' filepath='fs/file.c' line='695' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__const_udelay' mangled-name='__const_udelay' filepath='arch/arm64/lib/delay.c' line='43' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__const_udelay'>
         <parameter type-id='7359adad' name='xloops' filepath='arch/arm64/lib/delay.c' line='43' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <var-decl name='__cpu_active_mask' type-id='1354385d' mangled-name='__cpu_active_mask' visibility='default' filepath='kernel/cpu.c' line='2820' column='1' elf-symbol-id='__cpu_active_mask'/>
-      <var-decl name='__cpu_online_mask' type-id='1354385d' mangled-name='__cpu_online_mask' visibility='default' filepath='kernel/cpu.c' line='2814' column='1' elf-symbol-id='__cpu_online_mask'/>
-      <var-decl name='__cpu_possible_mask' type-id='1354385d' mangled-name='__cpu_possible_mask' visibility='default' filepath='kernel/cpu.c' line='2810' column='1' elf-symbol-id='__cpu_possible_mask'/>
-      <var-decl name='__cpu_present_mask' type-id='1354385d' mangled-name='__cpu_present_mask' visibility='default' filepath='kernel/cpu.c' line='2817' column='1' elf-symbol-id='__cpu_present_mask'/>
+      <var-decl name='__cpu_active_mask' type-id='1354385d' mangled-name='__cpu_active_mask' visibility='default' filepath='kernel/cpu.c' line='2822' column='1' elf-symbol-id='__cpu_active_mask'/>
+      <var-decl name='__cpu_online_mask' type-id='1354385d' mangled-name='__cpu_online_mask' visibility='default' filepath='kernel/cpu.c' line='2816' column='1' elf-symbol-id='__cpu_online_mask'/>
+      <var-decl name='__cpu_possible_mask' type-id='1354385d' mangled-name='__cpu_possible_mask' visibility='default' filepath='kernel/cpu.c' line='2812' column='1' elf-symbol-id='__cpu_possible_mask'/>
+      <var-decl name='__cpu_present_mask' type-id='1354385d' mangled-name='__cpu_present_mask' visibility='default' filepath='kernel/cpu.c' line='2819' column='1' elf-symbol-id='__cpu_present_mask'/>
       <function-decl name='__cpufreq_driver_target' mangled-name='__cpufreq_driver_target' filepath='drivers/cpufreq/cpufreq.c' line='2208' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__cpufreq_driver_target'>
         <parameter type-id='343c3ae4' name='policy' filepath='drivers/cpufreq/cpufreq.c' line='2208' column='1'/>
         <parameter type-id='f0981eeb' name='target_freq' filepath='drivers/cpufreq/cpufreq.c' line='2209' column='1'/>
@@ -116711,16 +116903,16 @@
         <parameter type-id='b59d7dce' name='size' filepath='lib/memneq.c' line='157' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='__crypto_xor' mangled-name='__crypto_xor' filepath='crypto/algapi.c' line='994' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__crypto_xor'>
-        <parameter type-id='8bff8096' name='dst' filepath='crypto/algapi.c' line='994' column='1'/>
-        <parameter type-id='bbaf3419' name='src1' filepath='crypto/algapi.c' line='994' column='1'/>
-        <parameter type-id='bbaf3419' name='src2' filepath='crypto/algapi.c' line='994' column='1'/>
-        <parameter type-id='f0981eeb' name='len' filepath='crypto/algapi.c' line='994' column='1'/>
+      <function-decl name='__crypto_xor' mangled-name='__crypto_xor' filepath='crypto/algapi.c' line='996' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__crypto_xor'>
+        <parameter type-id='8bff8096' name='dst' filepath='crypto/algapi.c' line='996' column='1'/>
+        <parameter type-id='bbaf3419' name='src1' filepath='crypto/algapi.c' line='996' column='1'/>
+        <parameter type-id='bbaf3419' name='src2' filepath='crypto/algapi.c' line='996' column='1'/>
+        <parameter type-id='f0981eeb' name='len' filepath='crypto/algapi.c' line='996' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__dev_direct_xmit' mangled-name='__dev_direct_xmit' filepath='net/core/dev.c' line='4219' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__dev_direct_xmit'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='4219' column='1'/>
-        <parameter type-id='1dc6a898' name='queue_id' filepath='net/core/dev.c' line='4219' column='1'/>
+      <function-decl name='__dev_direct_xmit' mangled-name='__dev_direct_xmit' filepath='net/core/dev.c' line='4223' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__dev_direct_xmit'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='4223' column='1'/>
+        <parameter type-id='1dc6a898' name='queue_id' filepath='net/core/dev.c' line='4223' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__dev_get_by_index' mangled-name='__dev_get_by_index' filepath='net/core/dev.c' line='935' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__dev_get_by_index'>
@@ -116728,14 +116920,14 @@
         <parameter type-id='95e97e5e' name='ifindex' filepath='net/core/dev.c' line='935' column='1'/>
         <return type-id='68a2d05b'/>
       </function-decl>
-      <function-decl name='__dev_kfree_skb_any' mangled-name='__dev_kfree_skb_any' filepath='net/core/dev.c' line='3123' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__dev_kfree_skb_any'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='3123' column='1'/>
-        <parameter type-id='1f17c6b4' name='reason' filepath='net/core/dev.c' line='3123' column='1'/>
+      <function-decl name='__dev_kfree_skb_any' mangled-name='__dev_kfree_skb_any' filepath='net/core/dev.c' line='3125' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__dev_kfree_skb_any'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='3125' column='1'/>
+        <parameter type-id='1f17c6b4' name='reason' filepath='net/core/dev.c' line='3125' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__dev_kfree_skb_irq' mangled-name='__dev_kfree_skb_irq' filepath='net/core/dev.c' line='3101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__dev_kfree_skb_irq'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='3101' column='1'/>
-        <parameter type-id='1f17c6b4' name='reason' filepath='net/core/dev.c' line='3101' column='1'/>
+      <function-decl name='__dev_kfree_skb_irq' mangled-name='__dev_kfree_skb_irq' filepath='net/core/dev.c' line='3103' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__dev_kfree_skb_irq'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='3103' column='1'/>
+        <parameter type-id='1f17c6b4' name='reason' filepath='net/core/dev.c' line='3103' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='__device_reset' mangled-name='__device_reset' filepath='drivers/reset/core.c' line='817' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__device_reset'>
@@ -116811,19 +117003,19 @@
         <parameter type-id='80f4b756' name='lock_name' filepath='drivers/base/regmap/regmap-spi.c' line='125' column='1'/>
         <return type-id='29af9a71'/>
       </function-decl>
-      <function-decl name='__devm_release_region' mangled-name='__devm_release_region' filepath='kernel/resource.c' line='1545' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__devm_release_region'>
-        <parameter type-id='fa0b179b' name='dev' filepath='kernel/resource.c' line='1545' column='1'/>
-        <parameter type-id='c9d64c0d' name='parent' filepath='kernel/resource.c' line='1545' column='1'/>
-        <parameter type-id='acc63fdf' name='start' filepath='kernel/resource.c' line='1546' column='1'/>
-        <parameter type-id='acc63fdf' name='n' filepath='kernel/resource.c' line='1546' column='1'/>
+      <function-decl name='__devm_release_region' mangled-name='__devm_release_region' filepath='kernel/resource.c' line='1531' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__devm_release_region'>
+        <parameter type-id='fa0b179b' name='dev' filepath='kernel/resource.c' line='1531' column='1'/>
+        <parameter type-id='c9d64c0d' name='parent' filepath='kernel/resource.c' line='1531' column='1'/>
+        <parameter type-id='acc63fdf' name='start' filepath='kernel/resource.c' line='1532' column='1'/>
+        <parameter type-id='acc63fdf' name='n' filepath='kernel/resource.c' line='1532' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__devm_request_region' mangled-name='__devm_request_region' filepath='kernel/resource.c' line='1520' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__devm_request_region'>
-        <parameter type-id='fa0b179b' name='dev' filepath='kernel/resource.c' line='1520' column='1'/>
-        <parameter type-id='c9d64c0d' name='parent' filepath='kernel/resource.c' line='1520' column='1'/>
-        <parameter type-id='acc63fdf' name='start' filepath='kernel/resource.c' line='1521' column='1'/>
-        <parameter type-id='acc63fdf' name='n' filepath='kernel/resource.c' line='1521' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='kernel/resource.c' line='1521' column='1'/>
+      <function-decl name='__devm_request_region' mangled-name='__devm_request_region' filepath='kernel/resource.c' line='1506' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__devm_request_region'>
+        <parameter type-id='fa0b179b' name='dev' filepath='kernel/resource.c' line='1506' column='1'/>
+        <parameter type-id='c9d64c0d' name='parent' filepath='kernel/resource.c' line='1506' column='1'/>
+        <parameter type-id='acc63fdf' name='start' filepath='kernel/resource.c' line='1507' column='1'/>
+        <parameter type-id='acc63fdf' name='n' filepath='kernel/resource.c' line='1507' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='kernel/resource.c' line='1507' column='1'/>
         <return type-id='c9d64c0d'/>
       </function-decl>
       <function-decl name='__devm_reset_control_get' mangled-name='__devm_reset_control_get' filepath='drivers/reset/core.c' line='783' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__devm_reset_control_get'>
@@ -116841,11 +117033,11 @@
         <parameter type-id='b50a4934' name='slave' filepath='drivers/spi/spi.c' line='2494' column='1'/>
         <return type-id='f22e4524'/>
       </function-decl>
-      <function-decl name='__dma_request_channel' mangled-name='__dma_request_channel' filepath='drivers/dma/dmaengine.c' line='755' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__dma_request_channel'>
-        <parameter type-id='d2b9f7d5' name='mask' filepath='drivers/dma/dmaengine.c' line='755' column='1'/>
-        <parameter type-id='55f53546' name='fn' filepath='drivers/dma/dmaengine.c' line='756' column='1'/>
-        <parameter type-id='eaa32e2f' name='fn_param' filepath='drivers/dma/dmaengine.c' line='756' column='1'/>
-        <parameter type-id='9a537bbe' name='np' filepath='drivers/dma/dmaengine.c' line='757' column='1'/>
+      <function-decl name='__dma_request_channel' mangled-name='__dma_request_channel' filepath='drivers/dma/dmaengine.c' line='756' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__dma_request_channel'>
+        <parameter type-id='d2b9f7d5' name='mask' filepath='drivers/dma/dmaengine.c' line='756' column='1'/>
+        <parameter type-id='55f53546' name='fn' filepath='drivers/dma/dmaengine.c' line='757' column='1'/>
+        <parameter type-id='eaa32e2f' name='fn_param' filepath='drivers/dma/dmaengine.c' line='757' column='1'/>
+        <parameter type-id='9a537bbe' name='np' filepath='drivers/dma/dmaengine.c' line='758' column='1'/>
         <return type-id='27f3f5d8'/>
       </function-decl>
       <function-decl name='__do_once_done' mangled-name='__do_once_done' filepath='lib/once.c' line='55' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__do_once_done'>
@@ -116904,9 +117096,9 @@
         <parameter type-id='35078cb9' name='crtc_state' filepath='drivers/gpu/drm/drm_atomic_state_helper.c' line='92' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__drm_atomic_helper_disable_plane' mangled-name='__drm_atomic_helper_disable_plane' filepath='drivers/gpu/drm/drm_atomic.c' line='1379' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__drm_atomic_helper_disable_plane'>
-        <parameter type-id='a6711537' name='plane' filepath='drivers/gpu/drm/drm_atomic.c' line='1379' column='1'/>
-        <parameter type-id='d0835005' name='plane_state' filepath='drivers/gpu/drm/drm_atomic.c' line='1380' column='1'/>
+      <function-decl name='__drm_atomic_helper_disable_plane' mangled-name='__drm_atomic_helper_disable_plane' filepath='drivers/gpu/drm/drm_atomic.c' line='1389' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__drm_atomic_helper_disable_plane'>
+        <parameter type-id='a6711537' name='plane' filepath='drivers/gpu/drm/drm_atomic.c' line='1389' column='1'/>
+        <parameter type-id='d0835005' name='plane_state' filepath='drivers/gpu/drm/drm_atomic.c' line='1390' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__drm_atomic_helper_plane_destroy_state' mangled-name='__drm_atomic_helper_plane_destroy_state' filepath='drivers/gpu/drm/drm_atomic_state_helper.c' line='348' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__drm_atomic_helper_plane_destroy_state'>
@@ -116928,8 +117120,8 @@
         <parameter type-id='4ea020ae' name='state' filepath='drivers/gpu/drm/drm_atomic_state_helper.c' line='554' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__drm_atomic_state_free' mangled-name='__drm_atomic_state_free' filepath='drivers/gpu/drm/drm_atomic.c' line='257' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__drm_atomic_state_free'>
-        <parameter type-id='aa29ecab' name='ref' filepath='drivers/gpu/drm/drm_atomic.c' line='257' column='1'/>
+      <function-decl name='__drm_atomic_state_free' mangled-name='__drm_atomic_state_free' filepath='drivers/gpu/drm/drm_atomic.c' line='263' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__drm_atomic_state_free'>
+        <parameter type-id='aa29ecab' name='ref' filepath='drivers/gpu/drm/drm_atomic.c' line='263' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='__drm_crtc_commit_free' mangled-name='__drm_crtc_commit_free' filepath='drivers/gpu/drm/drm_atomic.c' line='46' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__drm_crtc_commit_free'>
@@ -116991,8 +117183,8 @@
         <parameter type-id='70de91e2' name='link_ksettings' filepath='net/ethtool/ioctl.c' line='428' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__fdget' mangled-name='__fdget' filepath='fs/file.c' line='984' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__fdget'>
-        <parameter type-id='f0981eeb' name='fd' filepath='fs/file.c' line='984' column='1'/>
+      <function-decl name='__fdget' mangled-name='__fdget' filepath='fs/file.c' line='999' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__fdget'>
+        <parameter type-id='f0981eeb' name='fd' filepath='fs/file.c' line='999' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
       <function-decl name='__filemap_set_wb_err' mangled-name='__filemap_set_wb_err' filepath='mm/filemap.c' line='684' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__filemap_set_wb_err'>
@@ -117000,9 +117192,9 @@
         <parameter type-id='95e97e5e' name='err' filepath='mm/filemap.c' line='684' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__free_pages' mangled-name='__free_pages' filepath='mm/page_alloc.c' line='5235' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__free_pages'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/page_alloc.c' line='5235' column='1'/>
-        <parameter type-id='f0981eeb' name='order' filepath='mm/page_alloc.c' line='5235' column='1'/>
+      <function-decl name='__free_pages' mangled-name='__free_pages' filepath='mm/page_alloc.c' line='5264' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__free_pages'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/page_alloc.c' line='5264' column='1'/>
+        <parameter type-id='f0981eeb' name='order' filepath='mm/page_alloc.c' line='5264' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='__fscrypt_encrypt_symlink' mangled-name='__fscrypt_encrypt_symlink' filepath='fs/crypto/hooks.c' line='238' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__fscrypt_encrypt_symlink'>
@@ -117045,9 +117237,9 @@
         <parameter type-id='ab7bbd67' name='attr' filepath='fs/crypto/hooks.c' line='120' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__generic_file_write_iter' mangled-name='__generic_file_write_iter' filepath='mm/filemap.c' line='3565' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__generic_file_write_iter'>
-        <parameter type-id='80f25feb' name='iocb' filepath='mm/filemap.c' line='3565' column='1'/>
-        <parameter type-id='4fa10f9e' name='from' filepath='mm/filemap.c' line='3565' column='1'/>
+      <function-decl name='__generic_file_write_iter' mangled-name='__generic_file_write_iter' filepath='mm/filemap.c' line='3572' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__generic_file_write_iter'>
+        <parameter type-id='80f25feb' name='iocb' filepath='mm/filemap.c' line='3572' column='1'/>
+        <parameter type-id='4fa10f9e' name='from' filepath='mm/filemap.c' line='3572' column='1'/>
         <return type-id='79a0948f'/>
       </function-decl>
       <function-decl name='__genphy_config_aneg' mangled-name='__genphy_config_aneg' filepath='drivers/net/phy/phy_device.c' line='2092' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__genphy_config_aneg'>
@@ -117055,9 +117247,9 @@
         <parameter type-id='b50a4934' name='changed' filepath='drivers/net/phy/phy_device.c' line='2092' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__get_free_pages' mangled-name='__get_free_pages' filepath='mm/page_alloc.c' line='5210' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__get_free_pages'>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/page_alloc.c' line='5210' column='1'/>
-        <parameter type-id='f0981eeb' name='order' filepath='mm/page_alloc.c' line='5210' column='1'/>
+      <function-decl name='__get_free_pages' mangled-name='__get_free_pages' filepath='mm/page_alloc.c' line='5239' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__get_free_pages'>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/page_alloc.c' line='5239' column='1'/>
+        <parameter type-id='f0981eeb' name='order' filepath='mm/page_alloc.c' line='5239' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
       <function-decl name='__get_task_comm' mangled-name='__get_task_comm' filepath='fs/exec.c' line='1217' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__get_task_comm'>
@@ -117066,12 +117258,12 @@
         <parameter type-id='f23e2572' name='tsk' filepath='fs/exec.c' line='1217' column='1'/>
         <return type-id='26a90f95'/>
       </function-decl>
-      <function-decl name='__get_vm_area_caller' mangled-name='__get_vm_area_caller' filepath='mm/vmalloc.c' line='2097' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__get_vm_area_caller'>
-        <parameter type-id='7359adad' name='size' filepath='mm/vmalloc.c' line='2097' column='1'/>
-        <parameter type-id='7359adad' name='flags' filepath='mm/vmalloc.c' line='2097' column='1'/>
-        <parameter type-id='7359adad' name='start' filepath='mm/vmalloc.c' line='2098' column='1'/>
-        <parameter type-id='7359adad' name='end' filepath='mm/vmalloc.c' line='2098' column='1'/>
-        <parameter type-id='eaa32e2f' name='caller' filepath='mm/vmalloc.c' line='2099' column='1'/>
+      <function-decl name='__get_vm_area_caller' mangled-name='__get_vm_area_caller' filepath='mm/vmalloc.c' line='2101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__get_vm_area_caller'>
+        <parameter type-id='7359adad' name='size' filepath='mm/vmalloc.c' line='2101' column='1'/>
+        <parameter type-id='7359adad' name='flags' filepath='mm/vmalloc.c' line='2101' column='1'/>
+        <parameter type-id='7359adad' name='start' filepath='mm/vmalloc.c' line='2102' column='1'/>
+        <parameter type-id='7359adad' name='end' filepath='mm/vmalloc.c' line='2102' column='1'/>
+        <parameter type-id='eaa32e2f' name='caller' filepath='mm/vmalloc.c' line='2103' column='1'/>
         <return type-id='d295dab2'/>
       </function-decl>
       <function-decl name='__getblk_gfp' mangled-name='__getblk_gfp' filepath='fs/buffer.c' line='1356' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__getblk_gfp'>
@@ -117098,16 +117290,16 @@
         <parameter type-id='19c2251e' name='timeout' filepath='net/bluetooth/hci_request.c' line='128' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
-      <function-decl name='__hid_register_driver' mangled-name='__hid_register_driver' filepath='drivers/hid/hid-core.c' line='2545' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__hid_register_driver'>
-        <parameter type-id='cbd2074d' name='hdrv' filepath='drivers/hid/hid-core.c' line='2545' column='1'/>
-        <parameter type-id='2730d015' name='owner' filepath='drivers/hid/hid-core.c' line='2545' column='1'/>
-        <parameter type-id='80f4b756' name='mod_name' filepath='drivers/hid/hid-core.c' line='2546' column='1'/>
+      <function-decl name='__hid_register_driver' mangled-name='__hid_register_driver' filepath='drivers/hid/hid-core.c' line='2557' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__hid_register_driver'>
+        <parameter type-id='cbd2074d' name='hdrv' filepath='drivers/hid/hid-core.c' line='2557' column='1'/>
+        <parameter type-id='2730d015' name='owner' filepath='drivers/hid/hid-core.c' line='2557' column='1'/>
+        <parameter type-id='80f4b756' name='mod_name' filepath='drivers/hid/hid-core.c' line='2558' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__hid_request' mangled-name='__hid_request' filepath='drivers/hid/hid-core.c' line='1712' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__hid_request'>
-        <parameter type-id='37175e4d' name='hid' filepath='drivers/hid/hid-core.c' line='1712' column='1'/>
-        <parameter type-id='5b4284d1' name='report' filepath='drivers/hid/hid-core.c' line='1712' column='1'/>
-        <parameter type-id='95e97e5e' name='reqtype' filepath='drivers/hid/hid-core.c' line='1713' column='1'/>
+      <function-decl name='__hid_request' mangled-name='__hid_request' filepath='drivers/hid/hid-core.c' line='1720' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__hid_request'>
+        <parameter type-id='37175e4d' name='hid' filepath='drivers/hid/hid-core.c' line='1720' column='1'/>
+        <parameter type-id='5b4284d1' name='report' filepath='drivers/hid/hid-core.c' line='1720' column='1'/>
+        <parameter type-id='95e97e5e' name='reqtype' filepath='drivers/hid/hid-core.c' line='1721' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__hrtimer_get_remaining' mangled-name='__hrtimer_get_remaining' filepath='kernel/time/hrtimer.c' line='1355' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__hrtimer_get_remaining'>
@@ -117168,6 +117360,11 @@
       <function-decl name='__iio_device_register' mangled-name='__iio_device_register' filepath='drivers/iio/industrialio-core.c' line='1721' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__iio_device_register'>
         <parameter type-id='226853d2' name='indio_dev' filepath='drivers/iio/industrialio-core.c' line='1721' column='1'/>
         <parameter type-id='2730d015' name='this_mod' filepath='drivers/iio/industrialio-core.c' line='1721' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__iio_trigger_register' mangled-name='__iio_trigger_register' filepath='drivers/iio/industrialio-trigger.c' line='66' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__iio_trigger_register'>
+        <parameter type-id='54e54fbb' name='trig_info' filepath='drivers/iio/industrialio-trigger.c' line='66' column='1'/>
+        <parameter type-id='2730d015' name='this_mod' filepath='drivers/iio/industrialio-trigger.c' line='67' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__inet6_lookup_established' mangled-name='__inet6_lookup_established' filepath='net/ipv6/inet6_hashtables.c' line='51' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__inet6_lookup_established'>
@@ -117237,13 +117434,13 @@
         <parameter type-id='fea9c20b' name='addr' filepath='net/ipv6/addrconf_core.c' line='38' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__irq_alloc_descs' mangled-name='__irq_alloc_descs' filepath='kernel/irq/irqdesc.c' line='781' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__irq_alloc_descs'>
-        <parameter type-id='95e97e5e' name='irq' filepath='kernel/irq/irqdesc.c' line='781' column='1'/>
-        <parameter type-id='f0981eeb' name='from' filepath='kernel/irq/irqdesc.c' line='781' column='1'/>
-        <parameter type-id='f0981eeb' name='cnt' filepath='kernel/irq/irqdesc.c' line='781' column='1'/>
-        <parameter type-id='95e97e5e' name='node' filepath='kernel/irq/irqdesc.c' line='781' column='1'/>
-        <parameter type-id='2730d015' name='owner' filepath='kernel/irq/irqdesc.c' line='782' column='1'/>
-        <parameter type-id='07779cd9' name='affinity' filepath='kernel/irq/irqdesc.c' line='782' column='1'/>
+      <function-decl name='__irq_alloc_descs' mangled-name='__irq_alloc_descs' filepath='kernel/irq/irqdesc.c' line='784' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__irq_alloc_descs'>
+        <parameter type-id='95e97e5e' name='irq' filepath='kernel/irq/irqdesc.c' line='784' column='1'/>
+        <parameter type-id='f0981eeb' name='from' filepath='kernel/irq/irqdesc.c' line='784' column='1'/>
+        <parameter type-id='f0981eeb' name='cnt' filepath='kernel/irq/irqdesc.c' line='784' column='1'/>
+        <parameter type-id='95e97e5e' name='node' filepath='kernel/irq/irqdesc.c' line='784' column='1'/>
+        <parameter type-id='2730d015' name='owner' filepath='kernel/irq/irqdesc.c' line='785' column='1'/>
+        <parameter type-id='07779cd9' name='affinity' filepath='kernel/irq/irqdesc.c' line='785' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__irq_alloc_domain_generic_chips' mangled-name='__irq_alloc_domain_generic_chips' filepath='kernel/irq/generic-chip.c' line='283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__irq_alloc_domain_generic_chips'>
@@ -117257,13 +117454,13 @@
         <parameter type-id='7a1ec3b1' name='gcflags' filepath='kernel/irq/generic-chip.c' line='287' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__irq_domain_add' mangled-name='__irq_domain_add' filepath='kernel/irq/irqdomain.c' line='130' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__irq_domain_add'>
-        <parameter type-id='4a935625' name='fwnode' filepath='kernel/irq/irqdomain.c' line='130' column='1'/>
-        <parameter type-id='95e97e5e' name='size' filepath='kernel/irq/irqdomain.c' line='130' column='1'/>
-        <parameter type-id='88370ce9' name='hwirq_max' filepath='kernel/irq/irqdomain.c' line='131' column='1'/>
-        <parameter type-id='95e97e5e' name='direct_max' filepath='kernel/irq/irqdomain.c' line='131' column='1'/>
-        <parameter type-id='2c202856' name='ops' filepath='kernel/irq/irqdomain.c' line='132' column='1'/>
-        <parameter type-id='eaa32e2f' name='host_data' filepath='kernel/irq/irqdomain.c' line='133' column='1'/>
+      <function-decl name='__irq_domain_add' mangled-name='__irq_domain_add' filepath='kernel/irq/irqdomain.c' line='229' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__irq_domain_add'>
+        <parameter type-id='4a935625' name='fwnode' filepath='kernel/irq/irqdomain.c' line='229' column='1'/>
+        <parameter type-id='f0981eeb' name='size' filepath='kernel/irq/irqdomain.c' line='229' column='1'/>
+        <parameter type-id='88370ce9' name='hwirq_max' filepath='kernel/irq/irqdomain.c' line='230' column='1'/>
+        <parameter type-id='95e97e5e' name='direct_max' filepath='kernel/irq/irqdomain.c' line='230' column='1'/>
+        <parameter type-id='2c202856' name='ops' filepath='kernel/irq/irqdomain.c' line='231' column='1'/>
+        <parameter type-id='eaa32e2f' name='host_data' filepath='kernel/irq/irqdomain.c' line='232' column='1'/>
         <return type-id='7544e824'/>
       </function-decl>
       <function-decl name='__irq_set_handler' mangled-name='__irq_set_handler' filepath='kernel/irq/chip.c' line='1088' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__irq_set_handler'>
@@ -117316,8 +117513,8 @@
         <parameter type-id='807869d3' name='copied' filepath='lib/kfifo.c' line='271' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__kfree_skb' mangled-name='__kfree_skb' filepath='net/core/skbuff.c' line='692' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__kfree_skb'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='692' column='1'/>
+      <function-decl name='__kfree_skb' mangled-name='__kfree_skb' filepath='net/core/skbuff.c' line='691' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__kfree_skb'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='691' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='__kmalloc' mangled-name='__kmalloc' filepath='mm/slub.c' line='4025' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__kmalloc'>
@@ -117371,27 +117568,27 @@
         <parameter type-id='fe09dd29' name='addr' filepath='kernel/trace/trace_readwrite.c' line='18' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__mark_inode_dirty' mangled-name='__mark_inode_dirty' filepath='fs/fs-writeback.c' line='2234' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__mark_inode_dirty'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/fs-writeback.c' line='2234' column='1'/>
-        <parameter type-id='95e97e5e' name='flags' filepath='fs/fs-writeback.c' line='2234' column='1'/>
+      <function-decl name='__mark_inode_dirty' mangled-name='__mark_inode_dirty' filepath='fs/fs-writeback.c' line='2237' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__mark_inode_dirty'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/fs-writeback.c' line='2237' column='1'/>
+        <parameter type-id='95e97e5e' name='flags' filepath='fs/fs-writeback.c' line='2237' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__mdiobus_read' mangled-name='__mdiobus_read' filepath='drivers/net/phy/mdio_bus.c' line='746' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__mdiobus_read'>
-        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='746' column='1'/>
-        <parameter type-id='95e97e5e' name='addr' filepath='drivers/net/phy/mdio_bus.c' line='746' column='1'/>
-        <parameter type-id='19c2251e' name='regnum' filepath='drivers/net/phy/mdio_bus.c' line='746' column='1'/>
+      <function-decl name='__mdiobus_read' mangled-name='__mdiobus_read' filepath='drivers/net/phy/mdio_bus.c' line='751' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__mdiobus_read'>
+        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='751' column='1'/>
+        <parameter type-id='95e97e5e' name='addr' filepath='drivers/net/phy/mdio_bus.c' line='751' column='1'/>
+        <parameter type-id='19c2251e' name='regnum' filepath='drivers/net/phy/mdio_bus.c' line='751' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__mdiobus_register' mangled-name='__mdiobus_register' filepath='drivers/net/phy/mdio_bus.c' line='518' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__mdiobus_register'>
-        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='518' column='1'/>
-        <parameter type-id='2730d015' name='owner' filepath='drivers/net/phy/mdio_bus.c' line='518' column='1'/>
+      <function-decl name='__mdiobus_register' mangled-name='__mdiobus_register' filepath='drivers/net/phy/mdio_bus.c' line='523' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__mdiobus_register'>
+        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='523' column='1'/>
+        <parameter type-id='2730d015' name='owner' filepath='drivers/net/phy/mdio_bus.c' line='523' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__mdiobus_write' mangled-name='__mdiobus_write' filepath='drivers/net/phy/mdio_bus.c' line='772' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__mdiobus_write'>
-        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='772' column='1'/>
-        <parameter type-id='95e97e5e' name='addr' filepath='drivers/net/phy/mdio_bus.c' line='772' column='1'/>
-        <parameter type-id='19c2251e' name='regnum' filepath='drivers/net/phy/mdio_bus.c' line='772' column='1'/>
-        <parameter type-id='1dc6a898' name='val' filepath='drivers/net/phy/mdio_bus.c' line='772' column='1'/>
+      <function-decl name='__mdiobus_write' mangled-name='__mdiobus_write' filepath='drivers/net/phy/mdio_bus.c' line='777' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__mdiobus_write'>
+        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='777' column='1'/>
+        <parameter type-id='95e97e5e' name='addr' filepath='drivers/net/phy/mdio_bus.c' line='777' column='1'/>
+        <parameter type-id='19c2251e' name='regnum' filepath='drivers/net/phy/mdio_bus.c' line='777' column='1'/>
+        <parameter type-id='1dc6a898' name='val' filepath='drivers/net/phy/mdio_bus.c' line='777' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__media_device_register' mangled-name='__media_device_register' filepath='drivers/media/mc/mc-device.c' line='738' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__media_device_register'>
@@ -117439,8 +117636,14 @@
         <parameter type-id='f0981eeb' name='retries' filepath='drivers/mmc/core/mmc_ops.c' line='56' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__mmdrop' mangled-name='__mmdrop' filepath='kernel/fork.c' line='712' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__mmdrop'>
-        <parameter type-id='df4b7819' name='mm' filepath='kernel/fork.c' line='712' column='1'/>
+      <function-decl name='__mmdrop' mangled-name='__mmdrop' filepath='kernel/fork.c' line='715' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__mmdrop'>
+        <parameter type-id='df4b7819' name='mm' filepath='kernel/fork.c' line='715' column='1'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
+      <function-decl name='__mod_lruvec_state' mangled-name='__mod_lruvec_state' filepath='mm/memcontrol.c' line='852' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__mod_lruvec_state'>
+        <parameter type-id='71480a3e' name='lruvec' filepath='mm/memcontrol.c' line='852' column='1'/>
+        <parameter type-id='93f9c3d3' name='idx' filepath='mm/memcontrol.c' line='852' column='1'/>
+        <parameter type-id='95e97e5e' name='val' filepath='mm/memcontrol.c' line='853' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='__mod_node_page_state' mangled-name='__mod_node_page_state' filepath='mm/vmstat.c' line='336' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__mod_node_page_state'>
@@ -117475,21 +117678,21 @@
         <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='507' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
-      <function-decl name='__napi_schedule' mangled-name='__napi_schedule' filepath='net/core/dev.c' line='6425' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__napi_schedule'>
-        <parameter type-id='c50361c5' name='n' filepath='net/core/dev.c' line='6425' column='1'/>
+      <function-decl name='__napi_schedule' mangled-name='__napi_schedule' filepath='net/core/dev.c' line='6432' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__napi_schedule'>
+        <parameter type-id='c50361c5' name='n' filepath='net/core/dev.c' line='6432' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__napi_schedule_irqoff' mangled-name='__napi_schedule_irqoff' filepath='net/core/dev.c' line='6478' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__napi_schedule_irqoff'>
-        <parameter type-id='c50361c5' name='n' filepath='net/core/dev.c' line='6478' column='1'/>
+      <function-decl name='__napi_schedule_irqoff' mangled-name='__napi_schedule_irqoff' filepath='net/core/dev.c' line='6485' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__napi_schedule_irqoff'>
+        <parameter type-id='c50361c5' name='n' filepath='net/core/dev.c' line='6485' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='__ndelay' mangled-name='__ndelay' filepath='arch/arm64/lib/delay.c' line='55' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__ndelay'>
         <parameter type-id='7359adad' name='nsecs' filepath='arch/arm64/lib/delay.c' line='55' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__neigh_event_send' mangled-name='__neigh_event_send' filepath='net/core/neighbour.c' line='1126' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__neigh_event_send'>
-        <parameter type-id='3c330066' name='neigh' filepath='net/core/neighbour.c' line='1126' column='1'/>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/neighbour.c' line='1126' column='1'/>
+      <function-decl name='__neigh_event_send' mangled-name='__neigh_event_send' filepath='net/core/neighbour.c' line='1107' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__neigh_event_send'>
+        <parameter type-id='3c330066' name='neigh' filepath='net/core/neighbour.c' line='1107' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/neighbour.c' line='1107' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__netdev_alloc_skb' mangled-name='__netdev_alloc_skb' filepath='net/core/skbuff.c' line='431' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__netdev_alloc_skb'>
@@ -117498,8 +117701,8 @@
         <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='432' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
-      <function-decl name='__netif_napi_del' mangled-name='__netif_napi_del' filepath='net/core/dev.c' line='6804' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__netif_napi_del'>
-        <parameter type-id='c50361c5' name='napi' filepath='net/core/dev.c' line='6804' column='1'/>
+      <function-decl name='__netif_napi_del' mangled-name='__netif_napi_del' filepath='net/core/dev.c' line='6811' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__netif_napi_del'>
+        <parameter type-id='c50361c5' name='napi' filepath='net/core/dev.c' line='6811' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='__netif_set_xps_queue' mangled-name='__netif_set_xps_queue' filepath='net/core/dev.c' line='2627' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__netif_set_xps_queue'>
@@ -117509,11 +117712,11 @@
         <parameter type-id='b50a4934' name='is_rxqs_map' filepath='net/core/dev.c' line='2628' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__netlink_kernel_create' mangled-name='__netlink_kernel_create' filepath='net/netlink/af_netlink.c' line='2041' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__netlink_kernel_create'>
-        <parameter type-id='a2bff676' name='net' filepath='net/netlink/af_netlink.c' line='2041' column='1'/>
-        <parameter type-id='95e97e5e' name='unit' filepath='net/netlink/af_netlink.c' line='2041' column='1'/>
-        <parameter type-id='2730d015' name='module' filepath='net/netlink/af_netlink.c' line='2041' column='1'/>
-        <parameter type-id='8438f281' name='cfg' filepath='net/netlink/af_netlink.c' line='2042' column='1'/>
+      <function-decl name='__netlink_kernel_create' mangled-name='__netlink_kernel_create' filepath='net/netlink/af_netlink.c' line='2023' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__netlink_kernel_create'>
+        <parameter type-id='a2bff676' name='net' filepath='net/netlink/af_netlink.c' line='2023' column='1'/>
+        <parameter type-id='95e97e5e' name='unit' filepath='net/netlink/af_netlink.c' line='2023' column='1'/>
+        <parameter type-id='2730d015' name='module' filepath='net/netlink/af_netlink.c' line='2023' column='1'/>
+        <parameter type-id='8438f281' name='cfg' filepath='net/netlink/af_netlink.c' line='2024' column='1'/>
         <return type-id='f772df6d'/>
       </function-decl>
       <function-decl name='__next_zones_zonelist' mangled-name='__next_zones_zonelist' filepath='mm/mmzone.c' line='57' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__next_zones_zonelist'>
@@ -117522,35 +117725,35 @@
         <parameter type-id='f461c050' name='nodes' filepath='mm/mmzone.c' line='59' column='1'/>
         <return type-id='71278586'/>
       </function-decl>
-      <function-decl name='__nla_parse' mangled-name='__nla_parse' filepath='lib/nlattr.c' line='680' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__nla_parse'>
-        <parameter type-id='30864cdc' name='tb' filepath='lib/nlattr.c' line='680' column='1'/>
-        <parameter type-id='95e97e5e' name='maxtype' filepath='lib/nlattr.c' line='680' column='1'/>
-        <parameter type-id='0f2a7ce5' name='head' filepath='lib/nlattr.c' line='681' column='1'/>
-        <parameter type-id='95e97e5e' name='len' filepath='lib/nlattr.c' line='681' column='1'/>
-        <parameter type-id='109cdb66' name='policy' filepath='lib/nlattr.c' line='682' column='1'/>
-        <parameter type-id='f0981eeb' name='validate' filepath='lib/nlattr.c' line='682' column='1'/>
-        <parameter type-id='5799dc94' name='extack' filepath='lib/nlattr.c' line='683' column='1'/>
+      <function-decl name='__nla_parse' mangled-name='__nla_parse' filepath='lib/nlattr.c' line='683' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__nla_parse'>
+        <parameter type-id='30864cdc' name='tb' filepath='lib/nlattr.c' line='683' column='1'/>
+        <parameter type-id='95e97e5e' name='maxtype' filepath='lib/nlattr.c' line='683' column='1'/>
+        <parameter type-id='0f2a7ce5' name='head' filepath='lib/nlattr.c' line='684' column='1'/>
+        <parameter type-id='95e97e5e' name='len' filepath='lib/nlattr.c' line='684' column='1'/>
+        <parameter type-id='109cdb66' name='policy' filepath='lib/nlattr.c' line='685' column='1'/>
+        <parameter type-id='f0981eeb' name='validate' filepath='lib/nlattr.c' line='685' column='1'/>
+        <parameter type-id='5799dc94' name='extack' filepath='lib/nlattr.c' line='686' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__nla_validate' mangled-name='__nla_validate' filepath='lib/nlattr.c' line='626' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__nla_validate'>
-        <parameter type-id='0f2a7ce5' name='head' filepath='lib/nlattr.c' line='626' column='1'/>
-        <parameter type-id='95e97e5e' name='len' filepath='lib/nlattr.c' line='626' column='1'/>
-        <parameter type-id='95e97e5e' name='maxtype' filepath='lib/nlattr.c' line='626' column='1'/>
-        <parameter type-id='109cdb66' name='policy' filepath='lib/nlattr.c' line='627' column='1'/>
-        <parameter type-id='f0981eeb' name='validate' filepath='lib/nlattr.c' line='627' column='1'/>
-        <parameter type-id='5799dc94' name='extack' filepath='lib/nlattr.c' line='628' column='1'/>
+      <function-decl name='__nla_validate' mangled-name='__nla_validate' filepath='lib/nlattr.c' line='629' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__nla_validate'>
+        <parameter type-id='0f2a7ce5' name='head' filepath='lib/nlattr.c' line='629' column='1'/>
+        <parameter type-id='95e97e5e' name='len' filepath='lib/nlattr.c' line='629' column='1'/>
+        <parameter type-id='95e97e5e' name='maxtype' filepath='lib/nlattr.c' line='629' column='1'/>
+        <parameter type-id='109cdb66' name='policy' filepath='lib/nlattr.c' line='630' column='1'/>
+        <parameter type-id='f0981eeb' name='validate' filepath='lib/nlattr.c' line='630' column='1'/>
+        <parameter type-id='5799dc94' name='extack' filepath='lib/nlattr.c' line='631' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__nlmsg_put' mangled-name='__nlmsg_put' filepath='net/netlink/af_netlink.c' line='2181' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__nlmsg_put'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/netlink/af_netlink.c' line='2181' column='1'/>
-        <parameter type-id='19c2251e' name='portid' filepath='net/netlink/af_netlink.c' line='2181' column='1'/>
-        <parameter type-id='19c2251e' name='seq' filepath='net/netlink/af_netlink.c' line='2181' column='1'/>
-        <parameter type-id='95e97e5e' name='type' filepath='net/netlink/af_netlink.c' line='2181' column='1'/>
-        <parameter type-id='95e97e5e' name='len' filepath='net/netlink/af_netlink.c' line='2181' column='1'/>
-        <parameter type-id='95e97e5e' name='flags' filepath='net/netlink/af_netlink.c' line='2181' column='1'/>
+      <function-decl name='__nlmsg_put' mangled-name='__nlmsg_put' filepath='net/netlink/af_netlink.c' line='2163' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__nlmsg_put'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/netlink/af_netlink.c' line='2163' column='1'/>
+        <parameter type-id='19c2251e' name='portid' filepath='net/netlink/af_netlink.c' line='2163' column='1'/>
+        <parameter type-id='19c2251e' name='seq' filepath='net/netlink/af_netlink.c' line='2163' column='1'/>
+        <parameter type-id='95e97e5e' name='type' filepath='net/netlink/af_netlink.c' line='2163' column='1'/>
+        <parameter type-id='95e97e5e' name='len' filepath='net/netlink/af_netlink.c' line='2163' column='1'/>
+        <parameter type-id='95e97e5e' name='flags' filepath='net/netlink/af_netlink.c' line='2163' column='1'/>
         <return type-id='c2074578'/>
       </function-decl>
-      <var-decl name='__num_online_cpus' type-id='49178f86' mangled-name='__num_online_cpus' visibility='default' filepath='kernel/cpu.c' line='2823' column='1' elf-symbol-id='__num_online_cpus'/>
+      <var-decl name='__num_online_cpus' type-id='49178f86' mangled-name='__num_online_cpus' visibility='default' filepath='kernel/cpu.c' line='2825' column='1' elf-symbol-id='__num_online_cpus'/>
       <function-decl name='__of_reset_control_get' mangled-name='__of_reset_control_get' filepath='drivers/reset/core.c' line='605' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__of_reset_control_get'>
         <parameter type-id='9a537bbe' name='node' filepath='drivers/reset/core.c' line='605' column='1'/>
         <parameter type-id='80f4b756' name='id' filepath='drivers/reset/core.c' line='606' column='1'/>
@@ -117560,25 +117763,25 @@
         <parameter type-id='b50a4934' name='acquired' filepath='drivers/reset/core.c' line='607' column='1'/>
         <return type-id='9f9b8114'/>
       </function-decl>
-      <function-decl name='__page_file_index' mangled-name='__page_file_index' filepath='mm/swapfile.c' line='3608' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__page_file_index'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/swapfile.c' line='3608' column='1'/>
+      <function-decl name='__page_file_index' mangled-name='__page_file_index' filepath='mm/swapfile.c' line='3623' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__page_file_index'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/swapfile.c' line='3623' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='__page_file_mapping' mangled-name='__page_file_mapping' filepath='mm/swapfile.c' line='3602' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__page_file_mapping'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/swapfile.c' line='3602' column='1'/>
+      <function-decl name='__page_file_mapping' mangled-name='__page_file_mapping' filepath='mm/swapfile.c' line='3617' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__page_file_mapping'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/swapfile.c' line='3617' column='1'/>
         <return type-id='f57039f0'/>
       </function-decl>
-      <function-decl name='__page_frag_cache_drain' mangled-name='__page_frag_cache_drain' filepath='mm/page_alloc.c' line='5288' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__page_frag_cache_drain'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/page_alloc.c' line='5288' column='1'/>
-        <parameter type-id='f0981eeb' name='count' filepath='mm/page_alloc.c' line='5288' column='1'/>
+      <function-decl name='__page_frag_cache_drain' mangled-name='__page_frag_cache_drain' filepath='mm/page_alloc.c' line='5320' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__page_frag_cache_drain'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/page_alloc.c' line='5320' column='1'/>
+        <parameter type-id='f0981eeb' name='count' filepath='mm/page_alloc.c' line='5320' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__page_mapcount' mangled-name='__page_mapcount' filepath='mm/util.c' line='771' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__page_mapcount'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/util.c' line='771' column='1'/>
+      <function-decl name='__page_mapcount' mangled-name='__page_mapcount' filepath='mm/util.c' line='778' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__page_mapcount'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/util.c' line='778' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__page_pinner_migration_failed' mangled-name='__page_pinner_migration_failed' filepath='mm/page_pinner.c' line='333' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__page_pinner_migration_failed'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/page_pinner.c' line='333' column='1'/>
+      <function-decl name='__page_pinner_migration_failed' mangled-name='__page_pinner_migration_failed' filepath='mm/page_pinner.c' line='334' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__page_pinner_migration_failed'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/page_pinner.c' line='334' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='__pagevec_release' mangled-name='__pagevec_release' filepath='mm/swap.c' line='1096' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pagevec_release'>
@@ -117603,9 +117806,9 @@
         <parameter type-id='84c6078d' name='fbc' filepath='lib/percpu_counter.c' line='124' column='1'/>
         <return type-id='9b7c55ef'/>
       </function-decl>
-      <function-decl name='__percpu_down_read' mangled-name='__percpu_down_read' filepath='kernel/locking/percpu-rwsem.c' line='181' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__percpu_down_read'>
-        <parameter type-id='652d9ef9' name='sem' filepath='kernel/locking/percpu-rwsem.c' line='181' column='1'/>
-        <parameter type-id='b50a4934' name='try' filepath='kernel/locking/percpu-rwsem.c' line='181' column='1'/>
+      <function-decl name='__percpu_down_read' mangled-name='__percpu_down_read' filepath='kernel/locking/percpu-rwsem.c' line='182' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__percpu_down_read'>
+        <parameter type-id='652d9ef9' name='sem' filepath='kernel/locking/percpu-rwsem.c' line='182' column='1'/>
+        <parameter type-id='b50a4934' name='try' filepath='kernel/locking/percpu-rwsem.c' line='182' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='__percpu_init_rwsem' mangled-name='__percpu_init_rwsem' filepath='kernel/locking/percpu-rwsem.c' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__percpu_init_rwsem'>
@@ -117642,34 +117845,34 @@
         <parameter type-id='1ea237a6' name='ws' filepath='drivers/base/power/wakeup.c' line='757' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__pm_runtime_disable' mangled-name='__pm_runtime_disable' filepath='drivers/base/power/runtime.c' line='1401' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pm_runtime_disable'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1401' column='1'/>
-        <parameter type-id='b50a4934' name='check_resume' filepath='drivers/base/power/runtime.c' line='1401' column='1'/>
+      <function-decl name='__pm_runtime_disable' mangled-name='__pm_runtime_disable' filepath='drivers/base/power/runtime.c' line='1411' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pm_runtime_disable'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1411' column='1'/>
+        <parameter type-id='b50a4934' name='check_resume' filepath='drivers/base/power/runtime.c' line='1411' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__pm_runtime_idle' mangled-name='__pm_runtime_idle' filepath='drivers/base/power/runtime.c' line='1049' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pm_runtime_idle'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1049' column='1'/>
-        <parameter type-id='95e97e5e' name='rpmflags' filepath='drivers/base/power/runtime.c' line='1049' column='1'/>
+      <function-decl name='__pm_runtime_idle' mangled-name='__pm_runtime_idle' filepath='drivers/base/power/runtime.c' line='1059' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pm_runtime_idle'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1059' column='1'/>
+        <parameter type-id='95e97e5e' name='rpmflags' filepath='drivers/base/power/runtime.c' line='1059' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__pm_runtime_resume' mangled-name='__pm_runtime_resume' filepath='drivers/base/power/runtime.c' line='1116' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pm_runtime_resume'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1116' column='1'/>
-        <parameter type-id='95e97e5e' name='rpmflags' filepath='drivers/base/power/runtime.c' line='1116' column='1'/>
+      <function-decl name='__pm_runtime_resume' mangled-name='__pm_runtime_resume' filepath='drivers/base/power/runtime.c' line='1126' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pm_runtime_resume'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1126' column='1'/>
+        <parameter type-id='95e97e5e' name='rpmflags' filepath='drivers/base/power/runtime.c' line='1126' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__pm_runtime_set_status' mangled-name='__pm_runtime_set_status' filepath='drivers/base/power/runtime.c' line='1204' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pm_runtime_set_status'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1204' column='1'/>
-        <parameter type-id='f0981eeb' name='status' filepath='drivers/base/power/runtime.c' line='1204' column='1'/>
+      <function-decl name='__pm_runtime_set_status' mangled-name='__pm_runtime_set_status' filepath='drivers/base/power/runtime.c' line='1214' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pm_runtime_set_status'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1214' column='1'/>
+        <parameter type-id='f0981eeb' name='status' filepath='drivers/base/power/runtime.c' line='1214' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__pm_runtime_suspend' mangled-name='__pm_runtime_suspend' filepath='drivers/base/power/runtime.c' line='1083' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pm_runtime_suspend'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1083' column='1'/>
-        <parameter type-id='95e97e5e' name='rpmflags' filepath='drivers/base/power/runtime.c' line='1083' column='1'/>
+      <function-decl name='__pm_runtime_suspend' mangled-name='__pm_runtime_suspend' filepath='drivers/base/power/runtime.c' line='1093' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pm_runtime_suspend'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1093' column='1'/>
+        <parameter type-id='95e97e5e' name='rpmflags' filepath='drivers/base/power/runtime.c' line='1093' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__pm_runtime_use_autosuspend' mangled-name='__pm_runtime_use_autosuspend' filepath='drivers/base/power/runtime.c' line='1624' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pm_runtime_use_autosuspend'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1624' column='1'/>
-        <parameter type-id='b50a4934' name='use' filepath='drivers/base/power/runtime.c' line='1624' column='1'/>
+      <function-decl name='__pm_runtime_use_autosuspend' mangled-name='__pm_runtime_use_autosuspend' filepath='drivers/base/power/runtime.c' line='1634' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pm_runtime_use_autosuspend'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1634' column='1'/>
+        <parameter type-id='b50a4934' name='use' filepath='drivers/base/power/runtime.c' line='1634' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='__pm_stay_awake' mangled-name='__pm_stay_awake' filepath='drivers/base/power/wakeup.c' line='640' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pm_stay_awake'>
@@ -117680,28 +117883,28 @@
         <parameter type-id='80f4b756' name='func' filepath='kernel/printk/printk.c' line='3136' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__pskb_copy_fclone' mangled-name='__pskb_copy_fclone' filepath='net/core/skbuff.c' line='1559' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pskb_copy_fclone'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1559' column='1'/>
-        <parameter type-id='95e97e5e' name='headroom' filepath='net/core/skbuff.c' line='1559' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='1560' column='1'/>
-        <parameter type-id='b50a4934' name='fclone' filepath='net/core/skbuff.c' line='1560' column='1'/>
+      <function-decl name='__pskb_copy_fclone' mangled-name='__pskb_copy_fclone' filepath='net/core/skbuff.c' line='1558' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pskb_copy_fclone'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1558' column='1'/>
+        <parameter type-id='95e97e5e' name='headroom' filepath='net/core/skbuff.c' line='1558' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='1559' column='1'/>
+        <parameter type-id='b50a4934' name='fclone' filepath='net/core/skbuff.c' line='1559' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
-      <function-decl name='__pskb_pull_tail' mangled-name='__pskb_pull_tail' filepath='net/core/skbuff.c' line='2098' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pskb_pull_tail'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='2098' column='1'/>
-        <parameter type-id='95e97e5e' name='delta' filepath='net/core/skbuff.c' line='2098' column='1'/>
+      <function-decl name='__pskb_pull_tail' mangled-name='__pskb_pull_tail' filepath='net/core/skbuff.c' line='2097' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__pskb_pull_tail'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='2097' column='1'/>
+        <parameter type-id='95e97e5e' name='delta' filepath='net/core/skbuff.c' line='2097' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='__put_net' mangled-name='__put_net' filepath='net/core/net_namespace.c' line='658' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__put_net'>
-        <parameter type-id='a2bff676' name='net' filepath='net/core/net_namespace.c' line='658' column='1'/>
+      <function-decl name='__put_net' mangled-name='__put_net' filepath='net/core/net_namespace.c' line='649' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__put_net'>
+        <parameter type-id='a2bff676' name='net' filepath='net/core/net_namespace.c' line='649' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='__put_page' mangled-name='__put_page' filepath='mm/swap.c' line='118' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__put_page'>
         <parameter type-id='02f11ed4' name='page' filepath='mm/swap.c' line='118' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__put_task_struct' mangled-name='__put_task_struct' filepath='kernel/fork.c' line='761' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__put_task_struct'>
-        <parameter type-id='f23e2572' name='tsk' filepath='kernel/fork.c' line='761' column='1'/>
+      <function-decl name='__put_task_struct' mangled-name='__put_task_struct' filepath='kernel/fork.c' line='764' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__put_task_struct'>
+        <parameter type-id='f23e2572' name='tsk' filepath='kernel/fork.c' line='764' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='__rb_erase_color' mangled-name='__rb_erase_color' filepath='lib/rbtree.c' line='410' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__rb_erase_color'>
@@ -117773,12 +117976,12 @@
         <parameter is-variadic='yes'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__request_percpu_irq' mangled-name='__request_percpu_irq' filepath='kernel/irq/manage.c' line='2489' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__request_percpu_irq'>
-        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2489' column='1'/>
-        <parameter type-id='29591c9a' name='handler' filepath='kernel/irq/manage.c' line='2489' column='1'/>
-        <parameter type-id='7359adad' name='flags' filepath='kernel/irq/manage.c' line='2490' column='1'/>
-        <parameter type-id='80f4b756' name='devname' filepath='kernel/irq/manage.c' line='2490' column='1'/>
-        <parameter type-id='eaa32e2f' name='dev_id' filepath='kernel/irq/manage.c' line='2491' column='1'/>
+      <function-decl name='__request_percpu_irq' mangled-name='__request_percpu_irq' filepath='kernel/irq/manage.c' line='2496' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__request_percpu_irq'>
+        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2496' column='1'/>
+        <parameter type-id='29591c9a' name='handler' filepath='kernel/irq/manage.c' line='2496' column='1'/>
+        <parameter type-id='7359adad' name='flags' filepath='kernel/irq/manage.c' line='2497' column='1'/>
+        <parameter type-id='80f4b756' name='devname' filepath='kernel/irq/manage.c' line='2497' column='1'/>
+        <parameter type-id='eaa32e2f' name='dev_id' filepath='kernel/irq/manage.c' line='2498' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__request_region' mangled-name='__request_region' filepath='kernel/resource.c' line='1126' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__request_region'>
@@ -117826,12 +118029,12 @@
         <parameter type-id='75396bad' name='sbq' filepath='lib/sbitmap.c' line='424' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__scsi_add_device' mangled-name='__scsi_add_device' filepath='drivers/scsi/scsi_scan.c' line='1460' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__scsi_add_device'>
-        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi_scan.c' line='1460' column='1'/>
-        <parameter type-id='6e160b14' name='channel' filepath='drivers/scsi/scsi_scan.c' line='1460' column='1'/>
-        <parameter type-id='6e160b14' name='id' filepath='drivers/scsi/scsi_scan.c' line='1461' column='1'/>
-        <parameter type-id='91ce1af9' name='lun' filepath='drivers/scsi/scsi_scan.c' line='1461' column='1'/>
-        <parameter type-id='eaa32e2f' name='hostdata' filepath='drivers/scsi/scsi_scan.c' line='1461' column='1'/>
+      <function-decl name='__scsi_add_device' mangled-name='__scsi_add_device' filepath='drivers/scsi/scsi_scan.c' line='1459' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__scsi_add_device'>
+        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi_scan.c' line='1459' column='1'/>
+        <parameter type-id='6e160b14' name='channel' filepath='drivers/scsi/scsi_scan.c' line='1459' column='1'/>
+        <parameter type-id='6e160b14' name='id' filepath='drivers/scsi/scsi_scan.c' line='1460' column='1'/>
+        <parameter type-id='91ce1af9' name='lun' filepath='drivers/scsi/scsi_scan.c' line='1460' column='1'/>
+        <parameter type-id='eaa32e2f' name='hostdata' filepath='drivers/scsi/scsi_scan.c' line='1460' column='1'/>
         <return type-id='eb572b74'/>
       </function-decl>
       <function-decl name='__scsi_execute' mangled-name='__scsi_execute' filepath='drivers/scsi/scsi_lib.c' line='240' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__scsi_execute'>
@@ -117849,9 +118052,9 @@
         <parameter type-id='7292109c' name='resid' filepath='drivers/scsi/scsi_lib.c' line='244' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__scsi_iterate_devices' mangled-name='__scsi_iterate_devices' filepath='drivers/scsi/scsi.c' line='556' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__scsi_iterate_devices'>
-        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi.c' line='556' column='1'/>
-        <parameter type-id='eb572b74' name='prev' filepath='drivers/scsi/scsi.c' line='557' column='1'/>
+      <function-decl name='__scsi_iterate_devices' mangled-name='__scsi_iterate_devices' filepath='drivers/scsi/scsi.c' line='563' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__scsi_iterate_devices'>
+        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi.c' line='563' column='1'/>
+        <parameter type-id='eb572b74' name='prev' filepath='drivers/scsi/scsi.c' line='564' column='1'/>
         <return type-id='eb572b74'/>
       </function-decl>
       <function-decl name='__scsi_print_sense' mangled-name='__scsi_print_sense' filepath='drivers/scsi/scsi_logging.c' line='366' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__scsi_print_sense'>
@@ -117895,6 +118098,12 @@
         <parameter type-id='02f11ed4' name='page' filepath='mm/page-writeback.c' line='2479' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
+      <function-decl name='__set_page_owner' mangled-name='__set_page_owner' filepath='mm/page_owner.c' line='212' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__set_page_owner'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/page_owner.c' line='212' column='1'/>
+        <parameter type-id='f0981eeb' name='order' filepath='mm/page_owner.c' line='212' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/page_owner.c' line='213' column='1'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
       <function-decl name='__sg_page_iter_dma_next' mangled-name='__sg_page_iter_dma_next' filepath='lib/scatterlist.c' line='722' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__sg_page_iter_dma_next'>
         <parameter type-id='f1397bef' name='dma_iter' filepath='lib/scatterlist.c' line='722' column='1'/>
         <return type-id='b50a4934'/>
@@ -117910,12 +118119,12 @@
         <parameter type-id='7359adad' name='pgoffset' filepath='lib/scatterlist.c' line='683' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__skb_checksum_complete' mangled-name='__skb_checksum_complete' filepath='net/core/skbuff.c' line='2885' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__skb_checksum_complete'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='2885' column='1'/>
+      <function-decl name='__skb_checksum_complete' mangled-name='__skb_checksum_complete' filepath='net/core/skbuff.c' line='2887' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__skb_checksum_complete'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='2887' column='1'/>
         <return type-id='7dac1e36'/>
       </function-decl>
-      <function-decl name='__skb_ext_put' mangled-name='__skb_ext_put' filepath='net/core/skbuff.c' line='6380' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__skb_ext_put'>
-        <parameter type-id='374692c7' name='ext' filepath='net/core/skbuff.c' line='6380' column='1'/>
+      <function-decl name='__skb_ext_put' mangled-name='__skb_ext_put' filepath='net/core/skbuff.c' line='6385' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__skb_ext_put'>
+        <parameter type-id='374692c7' name='ext' filepath='net/core/skbuff.c' line='6385' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='__skb_flow_dissect' mangled-name='__skb_flow_dissect' filepath='net/core/flow_dissector.c' line='904' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__skb_flow_dissect'>
@@ -117934,16 +118143,16 @@
         <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/flow_dissector.c' line='1608' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__skb_gso_segment' mangled-name='__skb_gso_segment' filepath='net/core/dev.c' line='3387' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__skb_gso_segment'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='3387' column='1'/>
-        <parameter type-id='f9f4b16f' name='features' filepath='net/core/dev.c' line='3388' column='1'/>
-        <parameter type-id='b50a4934' name='tx_path' filepath='net/core/dev.c' line='3388' column='1'/>
+      <function-decl name='__skb_gso_segment' mangled-name='__skb_gso_segment' filepath='net/core/dev.c' line='3391' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__skb_gso_segment'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='3391' column='1'/>
+        <parameter type-id='f9f4b16f' name='features' filepath='net/core/dev.c' line='3392' column='1'/>
+        <parameter type-id='b50a4934' name='tx_path' filepath='net/core/dev.c' line='3392' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
-      <function-decl name='__skb_pad' mangled-name='__skb_pad' filepath='net/core/skbuff.c' line='1834' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__skb_pad'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1834' column='1'/>
-        <parameter type-id='95e97e5e' name='pad' filepath='net/core/skbuff.c' line='1834' column='1'/>
-        <parameter type-id='b50a4934' name='free_on_error' filepath='net/core/skbuff.c' line='1834' column='1'/>
+      <function-decl name='__skb_pad' mangled-name='__skb_pad' filepath='net/core/skbuff.c' line='1833' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__skb_pad'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1833' column='1'/>
+        <parameter type-id='95e97e5e' name='pad' filepath='net/core/skbuff.c' line='1833' column='1'/>
+        <parameter type-id='b50a4934' name='free_on_error' filepath='net/core/skbuff.c' line='1833' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__sock_create' mangled-name='__sock_create' filepath='net/socket.c' line='1346' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__sock_create'>
@@ -117972,9 +118181,9 @@
         <parameter type-id='05903717' name='actor' filepath='fs/splice.c' line='553' column='1'/>
         <return type-id='79a0948f'/>
       </function-decl>
-      <function-decl name='__spmi_driver_register' mangled-name='__spmi_driver_register' filepath='drivers/spmi/spmi.c' line='566' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__spmi_driver_register'>
-        <parameter type-id='34066f8f' name='sdrv' filepath='drivers/spmi/spmi.c' line='566' column='1'/>
-        <parameter type-id='2730d015' name='owner' filepath='drivers/spmi/spmi.c' line='566' column='1'/>
+      <function-decl name='__spmi_driver_register' mangled-name='__spmi_driver_register' filepath='drivers/spmi/spmi.c' line='567' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__spmi_driver_register'>
+        <parameter type-id='34066f8f' name='sdrv' filepath='drivers/spmi/spmi.c' line='567' column='1'/>
+        <parameter type-id='2730d015' name='owner' filepath='drivers/spmi/spmi.c' line='567' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__srcu_read_lock' mangled-name='__srcu_read_lock' filepath='kernel/rcu/srcutree.c' line='406' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__srcu_read_lock'>
@@ -117986,7 +118195,7 @@
         <parameter type-id='95e97e5e' name='idx' filepath='kernel/rcu/srcutree.c' line='422' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__stack_chk_fail' mangled-name='__stack_chk_fail' filepath='kernel/panic.c' line='684' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__stack_chk_fail'>
+      <function-decl name='__stack_chk_fail' mangled-name='__stack_chk_fail' filepath='kernel/panic.c' line='752' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__stack_chk_fail'>
         <return type-id='48b5725f'/>
       </function-decl>
       <var-decl name='__stack_chk_guard' type-id='7359adad' mangled-name='__stack_chk_guard' visibility='default' filepath='arch/arm64/kernel/process.c' line='64' column='1' elf-symbol-id='__stack_chk_guard'/>
@@ -118083,17 +118292,30 @@
         <parameter type-id='f23e2572' name='p' filepath='include/trace/hooks/sched.h' line='336' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_rvh_alloc_si' mangled-name='__traceiter_android_rvh_alloc_si' filepath='include/trace/hooks/mm.h' line='275' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_alloc_si'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='275' column='1'/>
-        <parameter type-id='705c6411' name='p' filepath='include/trace/hooks/mm.h' line='275' column='1'/>
-        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='275' column='1'/>
+      <function-decl name='__traceiter_android_rvh_alloc_si' mangled-name='__traceiter_android_rvh_alloc_si' filepath='include/trace/hooks/mm.h' line='323' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_alloc_si'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='323' column='1'/>
+        <parameter type-id='705c6411' name='p' filepath='include/trace/hooks/mm.h' line='323' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='323' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_rvh_alloc_swap_slot_cache' mangled-name='__traceiter_android_rvh_alloc_swap_slot_cache' filepath='include/trace/hooks/mm.h' line='237' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_alloc_swap_slot_cache'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='237' column='1'/>
-        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='237' column='1'/>
-        <parameter type-id='7292109c' name='ret' filepath='include/trace/hooks/mm.h' line='237' column='1'/>
-        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='237' column='1'/>
+      <function-decl name='__traceiter_android_rvh_alloc_swap_slot_cache' mangled-name='__traceiter_android_rvh_alloc_swap_slot_cache' filepath='include/trace/hooks/mm.h' line='270' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_alloc_swap_slot_cache'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='270' column='1'/>
+        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='270' column='1'/>
+        <parameter type-id='7292109c' name='ret' filepath='include/trace/hooks/mm.h' line='270' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='270' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_rvh_arm64_serror_panic' mangled-name='__traceiter_android_rvh_arm64_serror_panic' filepath='include/trace/hooks/traps.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_arm64_serror_panic'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/traps.h' line='34' column='1'/>
+        <parameter type-id='4616a179' name='regs' filepath='include/trace/hooks/traps.h' line='34' column='1'/>
+        <parameter type-id='f0981eeb' name='esr' filepath='include/trace/hooks/traps.h' line='34' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_rvh_bad_mode' mangled-name='__traceiter_android_rvh_bad_mode' filepath='include/trace/hooks/traps.h' line='30' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_bad_mode'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/traps.h' line='30' column='1'/>
+        <parameter type-id='4616a179' name='regs' filepath='include/trace/hooks/traps.h' line='30' column='1'/>
+        <parameter type-id='f0981eeb' name='esr' filepath='include/trace/hooks/traps.h' line='30' column='1'/>
+        <parameter type-id='95e97e5e' name='reason' filepath='include/trace/hooks/traps.h' line='30' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_rvh_binder_transaction' mangled-name='__traceiter_android_rvh_binder_transaction' filepath='include/trace/hooks/binder.h' line='71' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_binder_transaction'>
@@ -118200,6 +118422,11 @@
         <parameter type-id='95e97e5e' name='flags' filepath='include/trace/hooks/sched.h' line='358' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
+      <function-decl name='__traceiter_android_rvh_dequeue_task_idle' mangled-name='__traceiter_android_rvh_dequeue_task_idle' filepath='include/trace/hooks/sched.h' line='259' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_dequeue_task_idle'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/sched.h' line='259' column='1'/>
+        <parameter type-id='f23e2572' name='p' filepath='include/trace/hooks/sched.h' line='259' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
       <function-decl name='__traceiter_android_rvh_die_kernel_fault' mangled-name='__traceiter_android_rvh_die_kernel_fault' filepath='include/trace/hooks/fault.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_die_kernel_fault'>
         <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/fault.h' line='20' column='1'/>
         <parameter type-id='4616a179' name='regs' filepath='include/trace/hooks/fault.h' line='20' column='1'/>
@@ -118222,9 +118449,24 @@
         <parameter type-id='80f4b756' name='msg' filepath='include/trace/hooks/fault.h' line='28' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
+      <function-decl name='__traceiter_android_rvh_do_ptrauth_fault' mangled-name='__traceiter_android_rvh_do_ptrauth_fault' filepath='include/trace/hooks/traps.h' line='25' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_do_ptrauth_fault'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/traps.h' line='25' column='1'/>
+        <parameter type-id='4616a179' name='regs' filepath='include/trace/hooks/traps.h' line='25' column='1'/>
+        <parameter type-id='f0981eeb' name='esr' filepath='include/trace/hooks/traps.h' line='25' column='1'/>
+        <parameter type-id='b50a4934' name='user' filepath='include/trace/hooks/traps.h' line='25' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
       <function-decl name='__traceiter_android_rvh_do_sched_yield' mangled-name='__traceiter_android_rvh_do_sched_yield' filepath='include/trace/hooks/sched.h' line='304' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_do_sched_yield'>
         <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/sched.h' line='304' column='1'/>
         <parameter type-id='6ed6b432' name='rq' filepath='include/trace/hooks/sched.h' line='304' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_rvh_do_sea' mangled-name='__traceiter_android_rvh_do_sea' filepath='include/trace/hooks/fault.h' line='24' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_do_sea'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/fault.h' line='24' column='1'/>
+        <parameter type-id='4616a179' name='regs' filepath='include/trace/hooks/fault.h' line='24' column='1'/>
+        <parameter type-id='f0981eeb' name='esr' filepath='include/trace/hooks/fault.h' line='24' column='1'/>
+        <parameter type-id='7359adad' name='addr' filepath='include/trace/hooks/fault.h' line='24' column='1'/>
+        <parameter type-id='80f4b756' name='msg' filepath='include/trace/hooks/fault.h' line='24' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_rvh_do_sp_pc_abort' mangled-name='__traceiter_android_rvh_do_sp_pc_abort' filepath='include/trace/hooks/fault.h' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_do_sp_pc_abort'>
@@ -118235,12 +118477,18 @@
         <parameter type-id='b50a4934' name='user' filepath='include/trace/hooks/fault.h' line='32' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_rvh_drain_slots_cache_cpu' mangled-name='__traceiter_android_rvh_drain_slots_cache_cpu' filepath='include/trace/hooks/mm.h' line='229' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_drain_slots_cache_cpu'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='229' column='1'/>
-        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='229' column='1'/>
-        <parameter type-id='f0981eeb' name='type' filepath='include/trace/hooks/mm.h' line='229' column='1'/>
-        <parameter type-id='b50a4934' name='free_slots' filepath='include/trace/hooks/mm.h' line='229' column='1'/>
-        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='229' column='1'/>
+      <function-decl name='__traceiter_android_rvh_do_undefinstr' mangled-name='__traceiter_android_rvh_do_undefinstr' filepath='include/trace/hooks/traps.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_do_undefinstr'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/traps.h' line='20' column='1'/>
+        <parameter type-id='4616a179' name='regs' filepath='include/trace/hooks/traps.h' line='20' column='1'/>
+        <parameter type-id='b50a4934' name='user' filepath='include/trace/hooks/traps.h' line='20' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_rvh_drain_slots_cache_cpu' mangled-name='__traceiter_android_rvh_drain_slots_cache_cpu' filepath='include/trace/hooks/mm.h' line='262' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_drain_slots_cache_cpu'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='262' column='1'/>
+        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='262' column='1'/>
+        <parameter type-id='f0981eeb' name='type' filepath='include/trace/hooks/mm.h' line='262' column='1'/>
+        <parameter type-id='b50a4934' name='free_slots' filepath='include/trace/hooks/mm.h' line='262' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='262' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_rvh_enqueue_entity' mangled-name='__traceiter_android_rvh_enqueue_entity' filepath='include/trace/hooks/sched.h' line='346' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_enqueue_entity'>
@@ -118321,19 +118569,19 @@
         <parameter type-id='eaa32e2f' name='unused' filepath='include/trace/hooks/sched.h' line='382' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_rvh_free_swap_slot' mangled-name='__traceiter_android_rvh_free_swap_slot' filepath='include/trace/hooks/mm.h' line='243' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_free_swap_slot'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='243' column='1'/>
-        <parameter type-id='e0c6ffc2' name='entry' filepath='include/trace/hooks/mm.h' line='243' column='1'/>
-        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='243' column='1'/>
-        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='243' column='1'/>
+      <function-decl name='__traceiter_android_rvh_free_swap_slot' mangled-name='__traceiter_android_rvh_free_swap_slot' filepath='include/trace/hooks/mm.h' line='276' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_free_swap_slot'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='276' column='1'/>
+        <parameter type-id='e0c6ffc2' name='entry' filepath='include/trace/hooks/mm.h' line='276' column='1'/>
+        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='276' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='276' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_rvh_get_swap_page' mangled-name='__traceiter_android_rvh_get_swap_page' filepath='include/trace/hooks/mm.h' line='249' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_get_swap_page'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='249' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='249' column='1'/>
-        <parameter type-id='57d7488d' name='entry' filepath='include/trace/hooks/mm.h' line='249' column='1'/>
-        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='249' column='1'/>
-        <parameter type-id='d8e6b335' name='found' filepath='include/trace/hooks/mm.h' line='249' column='1'/>
+      <function-decl name='__traceiter_android_rvh_get_swap_page' mangled-name='__traceiter_android_rvh_get_swap_page' filepath='include/trace/hooks/mm.h' line='282' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_get_swap_page'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='282' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='282' column='1'/>
+        <parameter type-id='57d7488d' name='entry' filepath='include/trace/hooks/mm.h' line='282' column='1'/>
+        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='282' column='1'/>
+        <parameter type-id='d8e6b335' name='found' filepath='include/trace/hooks/mm.h' line='282' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_rvh_gic_v3_set_affinity' mangled-name='__traceiter_android_rvh_gic_v3_set_affinity' filepath='include/trace/hooks/gic_v3.h' line='22' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_gic_v3_set_affinity'>
@@ -118345,10 +118593,10 @@
         <parameter type-id='eaa32e2f' name='base' filepath='include/trace/hooks/gic_v3.h' line='22' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_rvh_handle_pte_fault_end' mangled-name='__traceiter_android_rvh_handle_pte_fault_end' filepath='include/trace/hooks/mm.h' line='196' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_handle_pte_fault_end'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='196' column='1'/>
-        <parameter type-id='d02f4143' name='vmf' filepath='include/trace/hooks/mm.h' line='196' column='1'/>
-        <parameter type-id='7359adad' name='highest_memmap_pfn' filepath='include/trace/hooks/mm.h' line='196' column='1'/>
+      <function-decl name='__traceiter_android_rvh_handle_pte_fault_end' mangled-name='__traceiter_android_rvh_handle_pte_fault_end' filepath='include/trace/hooks/mm.h' line='229' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_handle_pte_fault_end'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='229' column='1'/>
+        <parameter type-id='d02f4143' name='vmf' filepath='include/trace/hooks/mm.h' line='229' column='1'/>
+        <parameter type-id='7359adad' name='highest_memmap_pfn' filepath='include/trace/hooks/mm.h' line='229' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_rvh_iommu_setup_dma_ops' mangled-name='__traceiter_android_rvh_iommu_setup_dma_ops' filepath='include/trace/hooks/iommu.h' line='21' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_iommu_setup_dma_ops'>
@@ -118433,6 +118681,11 @@
       <function-decl name='__traceiter_android_rvh_prepare_prio_fork' mangled-name='__traceiter_android_rvh_prepare_prio_fork' filepath='include/trace/hooks/sched.h' line='66' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_prepare_prio_fork'>
         <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/sched.h' line='66' column='1'/>
         <parameter type-id='f23e2572' name='p' filepath='include/trace/hooks/sched.h' line='66' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_rvh_refrigerator' mangled-name='__traceiter_android_rvh_refrigerator' filepath='include/trace/hooks/cgroup.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_refrigerator'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/cgroup.h' line='34' column='1'/>
+        <parameter type-id='b50a4934' name='f' filepath='include/trace/hooks/cgroup.h' line='34' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_rvh_replace_next_task_fair' mangled-name='__traceiter_android_rvh_replace_next_task_fair' filepath='include/trace/hooks/sched.h' line='299' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_replace_next_task_fair'>
@@ -118617,6 +118870,23 @@
         <parameter type-id='807869d3' name='max_freq' filepath='include/trace/hooks/cpufreq.h' line='14' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
+      <function-decl name='__traceiter_android_rvh_tcp_recvmsg' mangled-name='__traceiter_android_rvh_tcp_recvmsg' filepath='include/trace/hooks/ipv4.h' line='16' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_tcp_recvmsg'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/ipv4.h' line='16' column='1'/>
+        <parameter type-id='f772df6d' name='sk' filepath='include/trace/hooks/ipv4.h' line='16' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_rvh_tcp_recvmsg_stat' mangled-name='__traceiter_android_rvh_tcp_recvmsg_stat' filepath='include/trace/hooks/ipv4.h' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_tcp_recvmsg_stat'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/ipv4.h' line='28' column='1'/>
+        <parameter type-id='f772df6d' name='sk' filepath='include/trace/hooks/ipv4.h' line='28' column='1'/>
+        <parameter type-id='95e97e5e' name='size' filepath='include/trace/hooks/ipv4.h' line='28' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_rvh_tcp_sendmsg_locked' mangled-name='__traceiter_android_rvh_tcp_sendmsg_locked' filepath='include/trace/hooks/ipv4.h' line='12' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_tcp_sendmsg_locked'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/ipv4.h' line='12' column='1'/>
+        <parameter type-id='f772df6d' name='sk' filepath='include/trace/hooks/ipv4.h' line='12' column='1'/>
+        <parameter type-id='95e97e5e' name='size' filepath='include/trace/hooks/ipv4.h' line='12' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
       <function-decl name='__traceiter_android_rvh_tick_entry' mangled-name='__traceiter_android_rvh_tick_entry' filepath='include/trace/hooks/sched.h' line='179' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_tick_entry'>
         <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/sched.h' line='179' column='1'/>
         <parameter type-id='6ed6b432' name='rq' filepath='include/trace/hooks/sched.h' line='179' column='1'/>
@@ -118659,6 +118929,16 @@
         <parameter type-id='a1ac03ea' name='uclamp_max' filepath='include/trace/hooks/sched.h' line='286' column='1'/>
         <parameter type-id='a1ac03ea' name='uclamp_eff' filepath='include/trace/hooks/sched.h' line='286' column='1'/>
         <parameter type-id='7292109c' name='ret' filepath='include/trace/hooks/sched.h' line='286' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_rvh_udp_recvmsg' mangled-name='__traceiter_android_rvh_udp_recvmsg' filepath='include/trace/hooks/ipv4.h' line='24' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_udp_recvmsg'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/ipv4.h' line='24' column='1'/>
+        <parameter type-id='f772df6d' name='sk' filepath='include/trace/hooks/ipv4.h' line='24' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_rvh_udp_sendmsg' mangled-name='__traceiter_android_rvh_udp_sendmsg' filepath='include/trace/hooks/ipv4.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_udp_sendmsg'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/ipv4.h' line='20' column='1'/>
+        <parameter type-id='f772df6d' name='sk' filepath='include/trace/hooks/ipv4.h' line='20' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_rvh_ufs_complete_init' mangled-name='__traceiter_android_rvh_ufs_complete_init' filepath='include/trace/hooks/ufshcd.h' line='33' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_rvh_ufs_complete_init'>
@@ -118729,10 +119009,16 @@
         <parameter type-id='f23e2572' name='p' filepath='include/trace/hooks/sched.h' line='167' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_account_swap_pages' mangled-name='__traceiter_android_vh_account_swap_pages' filepath='include/trace/hooks/mm.h' line='263' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_account_swap_pages'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='263' column='1'/>
-        <parameter type-id='11e11a61' name='si' filepath='include/trace/hooks/mm.h' line='263' column='1'/>
-        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='263' column='1'/>
+      <function-decl name='__traceiter_android_vh___cgroup_throttle_swaprate' mangled-name='__traceiter_android_vh___cgroup_throttle_swaprate' filepath='include/trace/hooks/mm.h' line='296' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh___cgroup_throttle_swaprate'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='296' column='1'/>
+        <parameter type-id='95e97e5e' name='nid' filepath='include/trace/hooks/mm.h' line='296' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='296' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_account_swap_pages' mangled-name='__traceiter_android_vh_account_swap_pages' filepath='include/trace/hooks/mm.h' line='308' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_account_swap_pages'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='308' column='1'/>
+        <parameter type-id='11e11a61' name='si' filepath='include/trace/hooks/mm.h' line='308' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='308' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_account_task_time' mangled-name='__traceiter_android_vh_account_task_time' filepath='include/trace/hooks/sched.h' line='312' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_account_task_time'>
@@ -118742,11 +119028,17 @@
         <parameter type-id='95e97e5e' name='user_tick' filepath='include/trace/hooks/sched.h' line='312' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_add_page_to_lrulist' mangled-name='__traceiter_android_vh_add_page_to_lrulist' filepath='include/trace/hooks/mm.h' line='166' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_add_page_to_lrulist'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='166' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='166' column='1'/>
-        <parameter type-id='b50a4934' name='compound' filepath='include/trace/hooks/mm.h' line='166' column='1'/>
-        <parameter type-id='04110eaa' name='lru' filepath='include/trace/hooks/mm.h' line='166' column='1'/>
+      <function-decl name='__traceiter_android_vh_add_page_to_lrulist' mangled-name='__traceiter_android_vh_add_page_to_lrulist' filepath='include/trace/hooks/mm.h' line='174' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_add_page_to_lrulist'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='174' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='174' column='1'/>
+        <parameter type-id='b50a4934' name='compound' filepath='include/trace/hooks/mm.h' line='174' column='1'/>
+        <parameter type-id='04110eaa' name='lru' filepath='include/trace/hooks/mm.h' line='174' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_add_to_avail_list' mangled-name='__traceiter_android_vh_add_to_avail_list' filepath='include/trace/hooks/mm.h' line='290' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_add_to_avail_list'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='290' column='1'/>
+        <parameter type-id='11e11a61' name='p' filepath='include/trace/hooks/mm.h' line='290' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='290' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_aes_decrypt' mangled-name='__traceiter_android_vh_aes_decrypt' filepath='include/trace/hooks/fips140.h' line='46' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_aes_decrypt'>
@@ -118773,22 +119065,22 @@
         <parameter type-id='7292109c' name='err' filepath='include/trace/hooks/fips140.h' line='32' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_alloc_pages_failure_bypass' mangled-name='__traceiter_android_vh_alloc_pages_failure_bypass' filepath='include/trace/hooks/mm.h' line='294' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_alloc_pages_failure_bypass'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='294' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='include/trace/hooks/mm.h' line='294' column='1'/>
-        <parameter type-id='95e97e5e' name='order' filepath='include/trace/hooks/mm.h' line='294' column='1'/>
-        <parameter type-id='95e97e5e' name='alloc_flags' filepath='include/trace/hooks/mm.h' line='294' column='1'/>
-        <parameter type-id='95e97e5e' name='migratetype' filepath='include/trace/hooks/mm.h' line='294' column='1'/>
-        <parameter type-id='9f93c9da' name='page' filepath='include/trace/hooks/mm.h' line='294' column='1'/>
+      <function-decl name='__traceiter_android_vh_alloc_pages_failure_bypass' mangled-name='__traceiter_android_vh_alloc_pages_failure_bypass' filepath='include/trace/hooks/mm.h' line='342' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_alloc_pages_failure_bypass'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='342' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='include/trace/hooks/mm.h' line='342' column='1'/>
+        <parameter type-id='95e97e5e' name='order' filepath='include/trace/hooks/mm.h' line='342' column='1'/>
+        <parameter type-id='95e97e5e' name='alloc_flags' filepath='include/trace/hooks/mm.h' line='342' column='1'/>
+        <parameter type-id='95e97e5e' name='migratetype' filepath='include/trace/hooks/mm.h' line='342' column='1'/>
+        <parameter type-id='9f93c9da' name='page' filepath='include/trace/hooks/mm.h' line='342' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_alloc_pages_reclaim_bypass' mangled-name='__traceiter_android_vh_alloc_pages_reclaim_bypass' filepath='include/trace/hooks/mm.h' line='290' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_alloc_pages_reclaim_bypass'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='290' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='include/trace/hooks/mm.h' line='290' column='1'/>
-        <parameter type-id='95e97e5e' name='order' filepath='include/trace/hooks/mm.h' line='290' column='1'/>
-        <parameter type-id='95e97e5e' name='alloc_flags' filepath='include/trace/hooks/mm.h' line='290' column='1'/>
-        <parameter type-id='95e97e5e' name='migratetype' filepath='include/trace/hooks/mm.h' line='290' column='1'/>
-        <parameter type-id='9f93c9da' name='page' filepath='include/trace/hooks/mm.h' line='290' column='1'/>
+      <function-decl name='__traceiter_android_vh_alloc_pages_reclaim_bypass' mangled-name='__traceiter_android_vh_alloc_pages_reclaim_bypass' filepath='include/trace/hooks/mm.h' line='338' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_alloc_pages_reclaim_bypass'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='338' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='include/trace/hooks/mm.h' line='338' column='1'/>
+        <parameter type-id='95e97e5e' name='order' filepath='include/trace/hooks/mm.h' line='338' column='1'/>
+        <parameter type-id='95e97e5e' name='alloc_flags' filepath='include/trace/hooks/mm.h' line='338' column='1'/>
+        <parameter type-id='95e97e5e' name='migratetype' filepath='include/trace/hooks/mm.h' line='338' column='1'/>
+        <parameter type-id='9f93c9da' name='page' filepath='include/trace/hooks/mm.h' line='338' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_alloc_pages_slowpath_begin' mangled-name='__traceiter_android_vh_alloc_pages_slowpath_begin' filepath='include/trace/hooks/mm.h' line='101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_alloc_pages_slowpath_begin'>
@@ -118805,17 +119097,17 @@
         <parameter type-id='7359adad' name='data' filepath='include/trace/hooks/mm.h' line='104' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_alloc_si' mangled-name='__traceiter_android_vh_alloc_si' filepath='include/trace/hooks/mm.h' line='278' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_alloc_si'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='278' column='1'/>
-        <parameter type-id='705c6411' name='p' filepath='include/trace/hooks/mm.h' line='278' column='1'/>
-        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='278' column='1'/>
+      <function-decl name='__traceiter_android_vh_alloc_si' mangled-name='__traceiter_android_vh_alloc_si' filepath='include/trace/hooks/mm.h' line='326' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_alloc_si'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='326' column='1'/>
+        <parameter type-id='705c6411' name='p' filepath='include/trace/hooks/mm.h' line='326' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='326' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_alloc_swap_slot_cache' mangled-name='__traceiter_android_vh_alloc_swap_slot_cache' filepath='include/trace/hooks/mm.h' line='240' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_alloc_swap_slot_cache'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='240' column='1'/>
-        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='240' column='1'/>
-        <parameter type-id='7292109c' name='ret' filepath='include/trace/hooks/mm.h' line='240' column='1'/>
-        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='240' column='1'/>
+      <function-decl name='__traceiter_android_vh_alloc_swap_slot_cache' mangled-name='__traceiter_android_vh_alloc_swap_slot_cache' filepath='include/trace/hooks/mm.h' line='273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_alloc_swap_slot_cache'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='273' column='1'/>
+        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='273' column='1'/>
+        <parameter type-id='7292109c' name='ret' filepath='include/trace/hooks/mm.h' line='273' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='273' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_allow_domain_state' mangled-name='__traceiter_android_vh_allow_domain_state' filepath='include/trace/hooks/pm_domain.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_allow_domain_state'>
@@ -118832,12 +119124,12 @@
         <parameter type-id='d8e6b335' name='already_on_hb' filepath='include/trace/hooks/futex.h' line='19' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_alter_mutex_list_add' mangled-name='__traceiter_android_vh_alter_mutex_list_add' filepath='include/trace/hooks/dtask.h' line='59' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_alter_mutex_list_add'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='59' column='1'/>
-        <parameter type-id='e0ea832a' name='lock' filepath='include/trace/hooks/dtask.h' line='59' column='1'/>
-        <parameter type-id='3ca21ae3' name='waiter' filepath='include/trace/hooks/dtask.h' line='59' column='1'/>
-        <parameter type-id='e84b031a' name='list' filepath='include/trace/hooks/dtask.h' line='59' column='1'/>
-        <parameter type-id='d8e6b335' name='already_on_list' filepath='include/trace/hooks/dtask.h' line='59' column='1'/>
+      <function-decl name='__traceiter_android_vh_alter_mutex_list_add' mangled-name='__traceiter_android_vh_alter_mutex_list_add' filepath='include/trace/hooks/dtask.h' line='77' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_alter_mutex_list_add'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='77' column='1'/>
+        <parameter type-id='e0ea832a' name='lock' filepath='include/trace/hooks/dtask.h' line='77' column='1'/>
+        <parameter type-id='3ca21ae3' name='waiter' filepath='include/trace/hooks/dtask.h' line='77' column='1'/>
+        <parameter type-id='e84b031a' name='list' filepath='include/trace/hooks/dtask.h' line='77' column='1'/>
+        <parameter type-id='d8e6b335' name='already_on_list' filepath='include/trace/hooks/dtask.h' line='77' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_alter_rwsem_list_add' mangled-name='__traceiter_android_vh_alter_rwsem_list_add' filepath='include/trace/hooks/rwsem.h' line='29' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_alter_rwsem_list_add'>
@@ -119069,6 +119361,13 @@
         <parameter type-id='eaa32e2f' name='unused' filepath='include/trace/hooks/hung_task.h' line='18' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
+      <function-decl name='__traceiter_android_vh_cleanup_old_buffers_bypass' mangled-name='__traceiter_android_vh_cleanup_old_buffers_bypass' filepath='include/trace/hooks/mm.h' line='132' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_cleanup_old_buffers_bypass'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='132' column='1'/>
+        <parameter type-id='7359adad' name='dm_bufio_current_allocated' filepath='include/trace/hooks/mm.h' line='132' column='1'/>
+        <parameter type-id='1d2c2b85' name='max_age_hz' filepath='include/trace/hooks/mm.h' line='132' column='1'/>
+        <parameter type-id='d8e6b335' name='bypass' filepath='include/trace/hooks/mm.h' line='132' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
       <function-decl name='__traceiter_android_vh_clear_mask_adjust' mangled-name='__traceiter_android_vh_clear_mask_adjust' filepath='include/trace/hooks/v4l2core.h' line='37' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_clear_mask_adjust'>
         <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/v4l2core.h' line='37' column='1'/>
         <parameter type-id='f0981eeb' name='ctrl' filepath='include/trace/hooks/v4l2core.h' line='37' column='1'/>
@@ -119096,10 +119395,10 @@
         <parameter type-id='842ac8d6' name='ts' filepath='include/trace/hooks/mm.h' line='58' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_cma_drain_all_pages_bypass' mangled-name='__traceiter_android_vh_cma_drain_all_pages_bypass' filepath='include/trace/hooks/mm.h' line='184' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_cma_drain_all_pages_bypass'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='184' column='1'/>
-        <parameter type-id='f0981eeb' name='migratetype' filepath='include/trace/hooks/mm.h' line='184' column='1'/>
-        <parameter type-id='d8e6b335' name='bypass' filepath='include/trace/hooks/mm.h' line='184' column='1'/>
+      <function-decl name='__traceiter_android_vh_cma_drain_all_pages_bypass' mangled-name='__traceiter_android_vh_cma_drain_all_pages_bypass' filepath='include/trace/hooks/mm.h' line='192' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_cma_drain_all_pages_bypass'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='192' column='1'/>
+        <parameter type-id='f0981eeb' name='migratetype' filepath='include/trace/hooks/mm.h' line='192' column='1'/>
+        <parameter type-id='d8e6b335' name='bypass' filepath='include/trace/hooks/mm.h' line='192' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_commit_creds' mangled-name='__traceiter_android_vh_commit_creds' filepath='include/trace/hooks/creds.h' line='23' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_commit_creds'>
@@ -119108,27 +119407,32 @@
         <parameter type-id='bc33861a' name='new' filepath='include/trace/hooks/creds.h' line='23' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_count_pswpin' mangled-name='__traceiter_android_vh_count_pswpin' filepath='include/trace/hooks/mm.h' line='217' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_count_pswpin'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='217' column='1'/>
-        <parameter type-id='11e11a61' name='sis' filepath='include/trace/hooks/mm.h' line='217' column='1'/>
+      <function-decl name='__traceiter_android_vh_compact_finished' mangled-name='__traceiter_android_vh_compact_finished' filepath='include/trace/hooks/mm.h' line='356' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_compact_finished'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='356' column='1'/>
+        <parameter type-id='d8e6b335' name='abort_compact' filepath='include/trace/hooks/mm.h' line='356' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_count_pswpout' mangled-name='__traceiter_android_vh_count_pswpout' filepath='include/trace/hooks/mm.h' line='220' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_count_pswpout'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='220' column='1'/>
-        <parameter type-id='11e11a61' name='sis' filepath='include/trace/hooks/mm.h' line='220' column='1'/>
+      <function-decl name='__traceiter_android_vh_count_pswpin' mangled-name='__traceiter_android_vh_count_pswpin' filepath='include/trace/hooks/mm.h' line='250' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_count_pswpin'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='250' column='1'/>
+        <parameter type-id='11e11a61' name='sis' filepath='include/trace/hooks/mm.h' line='250' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_count_swpout_vm_event' mangled-name='__traceiter_android_vh_count_swpout_vm_event' filepath='include/trace/hooks/mm.h' line='223' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_count_swpout_vm_event'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='223' column='1'/>
-        <parameter type-id='11e11a61' name='sis' filepath='include/trace/hooks/mm.h' line='223' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='223' column='1'/>
-        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='223' column='1'/>
+      <function-decl name='__traceiter_android_vh_count_pswpout' mangled-name='__traceiter_android_vh_count_pswpout' filepath='include/trace/hooks/mm.h' line='253' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_count_pswpout'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='253' column='1'/>
+        <parameter type-id='11e11a61' name='sis' filepath='include/trace/hooks/mm.h' line='253' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_cow_user_page' mangled-name='__traceiter_android_vh_cow_user_page' filepath='include/trace/hooks/mm.h' line='202' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_cow_user_page'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='202' column='1'/>
-        <parameter type-id='d02f4143' name='vmf' filepath='include/trace/hooks/mm.h' line='202' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='202' column='1'/>
+      <function-decl name='__traceiter_android_vh_count_swpout_vm_event' mangled-name='__traceiter_android_vh_count_swpout_vm_event' filepath='include/trace/hooks/mm.h' line='256' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_count_swpout_vm_event'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='256' column='1'/>
+        <parameter type-id='11e11a61' name='sis' filepath='include/trace/hooks/mm.h' line='256' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='256' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='256' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_cow_user_page' mangled-name='__traceiter_android_vh_cow_user_page' filepath='include/trace/hooks/mm.h' line='235' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_cow_user_page'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='235' column='1'/>
+        <parameter type-id='d02f4143' name='vmf' filepath='include/trace/hooks/mm.h' line='235' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='235' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_cpu_idle_enter' mangled-name='__traceiter_android_vh_cpu_idle_enter' filepath='include/trace/hooks/cpuidle.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_cpu_idle_enter'>
@@ -119188,11 +119492,29 @@
         <parameter type-id='b50a4934' name='s2idle' filepath='include/trace/hooks/cpuidle_psci.h' line='24' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_del_page_from_lrulist' mangled-name='__traceiter_android_vh_del_page_from_lrulist' filepath='include/trace/hooks/mm.h' line='169' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_del_page_from_lrulist'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='169' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='169' column='1'/>
-        <parameter type-id='b50a4934' name='compound' filepath='include/trace/hooks/mm.h' line='169' column='1'/>
-        <parameter type-id='04110eaa' name='lru' filepath='include/trace/hooks/mm.h' line='169' column='1'/>
+      <function-decl name='__traceiter_android_vh_del_from_avail_list' mangled-name='__traceiter_android_vh_del_from_avail_list' filepath='include/trace/hooks/mm.h' line='293' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_del_from_avail_list'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='293' column='1'/>
+        <parameter type-id='11e11a61' name='p' filepath='include/trace/hooks/mm.h' line='293' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='293' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_del_page_from_lrulist' mangled-name='__traceiter_android_vh_del_page_from_lrulist' filepath='include/trace/hooks/mm.h' line='177' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_del_page_from_lrulist'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='177' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='177' column='1'/>
+        <parameter type-id='b50a4934' name='compound' filepath='include/trace/hooks/mm.h' line='177' column='1'/>
+        <parameter type-id='04110eaa' name='lru' filepath='include/trace/hooks/mm.h' line='177' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_disable_thermal_cooling_stats' mangled-name='__traceiter_android_vh_disable_thermal_cooling_stats' filepath='include/trace/hooks/thermal.h' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_disable_thermal_cooling_stats'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/thermal.h' line='28' column='1'/>
+        <parameter type-id='2feec21f' name='cdev' filepath='include/trace/hooks/thermal.h' line='28' column='1'/>
+        <parameter type-id='d8e6b335' name='disable_stats' filepath='include/trace/hooks/thermal.h' line='28' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_dm_bufio_shrink_scan_bypass' mangled-name='__traceiter_android_vh_dm_bufio_shrink_scan_bypass' filepath='include/trace/hooks/mm.h' line='129' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_dm_bufio_shrink_scan_bypass'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='129' column='1'/>
+        <parameter type-id='7359adad' name='dm_bufio_current_allocated' filepath='include/trace/hooks/mm.h' line='129' column='1'/>
+        <parameter type-id='d8e6b335' name='bypass' filepath='include/trace/hooks/mm.h' line='129' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_do_futex' mangled-name='__traceiter_android_vh_do_futex' filepath='include/trace/hooks/futex.h' line='29' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_do_futex'>
@@ -119202,12 +119524,12 @@
         <parameter type-id='f9409001' name='uaddr2' filepath='include/trace/hooks/futex.h' line='29' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_do_page_trylock' mangled-name='__traceiter_android_vh_do_page_trylock' filepath='include/trace/hooks/mm.h' line='153' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_do_page_trylock'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='153' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='153' column='1'/>
-        <parameter type-id='9b58df93' name='sem' filepath='include/trace/hooks/mm.h' line='153' column='1'/>
-        <parameter type-id='d8e6b335' name='got_lock' filepath='include/trace/hooks/mm.h' line='153' column='1'/>
-        <parameter type-id='d8e6b335' name='success' filepath='include/trace/hooks/mm.h' line='153' column='1'/>
+      <function-decl name='__traceiter_android_vh_do_page_trylock' mangled-name='__traceiter_android_vh_do_page_trylock' filepath='include/trace/hooks/mm.h' line='161' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_do_page_trylock'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='161' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='161' column='1'/>
+        <parameter type-id='9b58df93' name='sem' filepath='include/trace/hooks/mm.h' line='161' column='1'/>
+        <parameter type-id='d8e6b335' name='got_lock' filepath='include/trace/hooks/mm.h' line='161' column='1'/>
+        <parameter type-id='d8e6b335' name='success' filepath='include/trace/hooks/mm.h' line='161' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_do_send_sig_info' mangled-name='__traceiter_android_vh_do_send_sig_info' filepath='include/trace/hooks/signal.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_do_send_sig_info'>
@@ -119217,9 +119539,9 @@
         <parameter type-id='f23e2572' name='dst' filepath='include/trace/hooks/signal.h' line='17' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_do_traversal_lruvec' mangled-name='__traceiter_android_vh_do_traversal_lruvec' filepath='include/trace/hooks/mm.h' line='175' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_do_traversal_lruvec'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='175' column='1'/>
-        <parameter type-id='71480a3e' name='lruvec' filepath='include/trace/hooks/mm.h' line='175' column='1'/>
+      <function-decl name='__traceiter_android_vh_do_traversal_lruvec' mangled-name='__traceiter_android_vh_do_traversal_lruvec' filepath='include/trace/hooks/mm.h' line='183' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_do_traversal_lruvec'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='183' column='1'/>
+        <parameter type-id='71480a3e' name='lruvec' filepath='include/trace/hooks/mm.h' line='183' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_do_wake_up_sync' mangled-name='__traceiter_android_vh_do_wake_up_sync' filepath='include/trace/hooks/sched.h' line='276' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_do_wake_up_sync'>
@@ -119228,22 +119550,22 @@
         <parameter type-id='7292109c' name='done' filepath='include/trace/hooks/sched.h' line='276' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_drain_all_pages_bypass' mangled-name='__traceiter_android_vh_drain_all_pages_bypass' filepath='include/trace/hooks/mm.h' line='157' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_drain_all_pages_bypass'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='157' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='include/trace/hooks/mm.h' line='157' column='1'/>
-        <parameter type-id='f0981eeb' name='order' filepath='include/trace/hooks/mm.h' line='157' column='1'/>
-        <parameter type-id='7359adad' name='alloc_flags' filepath='include/trace/hooks/mm.h' line='157' column='1'/>
-        <parameter type-id='95e97e5e' name='migratetype' filepath='include/trace/hooks/mm.h' line='157' column='1'/>
-        <parameter type-id='7359adad' name='did_some_progress' filepath='include/trace/hooks/mm.h' line='157' column='1'/>
-        <parameter type-id='d8e6b335' name='bypass' filepath='include/trace/hooks/mm.h' line='157' column='1'/>
+      <function-decl name='__traceiter_android_vh_drain_all_pages_bypass' mangled-name='__traceiter_android_vh_drain_all_pages_bypass' filepath='include/trace/hooks/mm.h' line='165' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_drain_all_pages_bypass'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='165' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='include/trace/hooks/mm.h' line='165' column='1'/>
+        <parameter type-id='f0981eeb' name='order' filepath='include/trace/hooks/mm.h' line='165' column='1'/>
+        <parameter type-id='7359adad' name='alloc_flags' filepath='include/trace/hooks/mm.h' line='165' column='1'/>
+        <parameter type-id='95e97e5e' name='migratetype' filepath='include/trace/hooks/mm.h' line='165' column='1'/>
+        <parameter type-id='7359adad' name='did_some_progress' filepath='include/trace/hooks/mm.h' line='165' column='1'/>
+        <parameter type-id='d8e6b335' name='bypass' filepath='include/trace/hooks/mm.h' line='165' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_drain_slots_cache_cpu' mangled-name='__traceiter_android_vh_drain_slots_cache_cpu' filepath='include/trace/hooks/mm.h' line='233' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_drain_slots_cache_cpu'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='233' column='1'/>
-        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='233' column='1'/>
-        <parameter type-id='f0981eeb' name='type' filepath='include/trace/hooks/mm.h' line='233' column='1'/>
-        <parameter type-id='b50a4934' name='free_slots' filepath='include/trace/hooks/mm.h' line='233' column='1'/>
-        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='233' column='1'/>
+      <function-decl name='__traceiter_android_vh_drain_slots_cache_cpu' mangled-name='__traceiter_android_vh_drain_slots_cache_cpu' filepath='include/trace/hooks/mm.h' line='266' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_drain_slots_cache_cpu'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='266' column='1'/>
+        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='266' column='1'/>
+        <parameter type-id='f0981eeb' name='type' filepath='include/trace/hooks/mm.h' line='266' column='1'/>
+        <parameter type-id='b50a4934' name='free_slots' filepath='include/trace/hooks/mm.h' line='266' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='266' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_dump_throttled_rt_tasks' mangled-name='__traceiter_android_vh_dump_throttled_rt_tasks' filepath='include/trace/hooks/sched.h' line='91' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_dump_throttled_rt_tasks'>
@@ -119253,6 +119575,12 @@
         <parameter type-id='fbc017ef' name='rt_period' filepath='include/trace/hooks/sched.h' line='91' column='1'/>
         <parameter type-id='91ce1af9' name='rt_runtime' filepath='include/trace/hooks/sched.h' line='91' column='1'/>
         <parameter type-id='9b7c55ef' name='rt_period_timer_expires' filepath='include/trace/hooks/sched.h' line='91' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_dup_task_struct' mangled-name='__traceiter_android_vh_dup_task_struct' filepath='include/trace/hooks/sched.h' line='374' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_dup_task_struct'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/sched.h' line='374' column='1'/>
+        <parameter type-id='f23e2572' name='tsk' filepath='include/trace/hooks/sched.h' line='374' column='1'/>
+        <parameter type-id='f23e2572' name='orig' filepath='include/trace/hooks/sched.h' line='374' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_em_cpu_energy' mangled-name='__traceiter_android_vh_em_cpu_energy' filepath='include/trace/hooks/sched.h' line='249' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_em_cpu_energy'>
@@ -119318,22 +119646,30 @@
         <parameter type-id='95e97e5e' name='flags' filepath='include/trace/hooks/sched.h' line='370' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_free_pages' mangled-name='__traceiter_android_vh_free_pages' filepath='include/trace/hooks/mm.h' line='281' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_free_pages'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='281' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='281' column='1'/>
-        <parameter type-id='f0981eeb' name='order' filepath='include/trace/hooks/mm.h' line='281' column='1'/>
+      <function-decl name='__traceiter_android_vh_free_pages' mangled-name='__traceiter_android_vh_free_pages' filepath='include/trace/hooks/mm.h' line='329' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_free_pages'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='329' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='329' column='1'/>
+        <parameter type-id='f0981eeb' name='order' filepath='include/trace/hooks/mm.h' line='329' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_free_swap_slot' mangled-name='__traceiter_android_vh_free_swap_slot' filepath='include/trace/hooks/mm.h' line='246' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_free_swap_slot'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='246' column='1'/>
-        <parameter type-id='e0c6ffc2' name='entry' filepath='include/trace/hooks/mm.h' line='246' column='1'/>
-        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='246' column='1'/>
-        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='246' column='1'/>
+      <function-decl name='__traceiter_android_vh_free_swap_slot' mangled-name='__traceiter_android_vh_free_swap_slot' filepath='include/trace/hooks/mm.h' line='279' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_free_swap_slot'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='279' column='1'/>
+        <parameter type-id='e0c6ffc2' name='entry' filepath='include/trace/hooks/mm.h' line='279' column='1'/>
+        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='279' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='279' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_free_task' mangled-name='__traceiter_android_vh_free_task' filepath='include/trace/hooks/sched.h' line='332' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_free_task'>
         <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/sched.h' line='332' column='1'/>
         <parameter type-id='f23e2572' name='p' filepath='include/trace/hooks/sched.h' line='332' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_free_unref_page_bypass' mangled-name='__traceiter_android_vh_free_unref_page_bypass' filepath='include/trace/hooks/mm.h' line='195' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_free_unref_page_bypass'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='195' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='195' column='1'/>
+        <parameter type-id='95e97e5e' name='order' filepath='include/trace/hooks/mm.h' line='195' column='1'/>
+        <parameter type-id='95e97e5e' name='migratetype' filepath='include/trace/hooks/mm.h' line='195' column='1'/>
+        <parameter type-id='d8e6b335' name='bypass' filepath='include/trace/hooks/mm.h' line='195' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_freq_qos_add_request' mangled-name='__traceiter_android_vh_freq_qos_add_request' filepath='include/trace/hooks/power.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_freq_qos_add_request'>
@@ -119436,12 +119772,12 @@
         <parameter type-id='1d2c2b85' name='addr' filepath='include/trace/hooks/mm.h' line='87' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_get_swap_page' mangled-name='__traceiter_android_vh_get_swap_page' filepath='include/trace/hooks/mm.h' line='253' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_get_swap_page'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='253' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='253' column='1'/>
-        <parameter type-id='57d7488d' name='entry' filepath='include/trace/hooks/mm.h' line='253' column='1'/>
-        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='253' column='1'/>
-        <parameter type-id='d8e6b335' name='found' filepath='include/trace/hooks/mm.h' line='253' column='1'/>
+      <function-decl name='__traceiter_android_vh_get_swap_page' mangled-name='__traceiter_android_vh_get_swap_page' filepath='include/trace/hooks/mm.h' line='286' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_get_swap_page'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='286' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='286' column='1'/>
+        <parameter type-id='57d7488d' name='entry' filepath='include/trace/hooks/mm.h' line='286' column='1'/>
+        <parameter type-id='c41495f1' name='cache' filepath='include/trace/hooks/mm.h' line='286' column='1'/>
+        <parameter type-id='d8e6b335' name='found' filepath='include/trace/hooks/mm.h' line='286' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_gic_resume' mangled-name='__traceiter_android_vh_gic_resume' filepath='include/trace/hooks/gic.h' line='15' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_gic_resume'>
@@ -119460,10 +119796,17 @@
         <parameter type-id='e84b031a' name='page_list' filepath='include/trace/hooks/vmscan.h' line='34' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_handle_pte_fault_end' mangled-name='__traceiter_android_vh_handle_pte_fault_end' filepath='include/trace/hooks/mm.h' line='199' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_handle_pte_fault_end'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='199' column='1'/>
-        <parameter type-id='d02f4143' name='vmf' filepath='include/trace/hooks/mm.h' line='199' column='1'/>
-        <parameter type-id='7359adad' name='highest_memmap_pfn' filepath='include/trace/hooks/mm.h' line='199' column='1'/>
+      <function-decl name='__traceiter_android_vh_handle_pte_fault_end' mangled-name='__traceiter_android_vh_handle_pte_fault_end' filepath='include/trace/hooks/mm.h' line='232' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_handle_pte_fault_end'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='232' column='1'/>
+        <parameter type-id='d02f4143' name='vmf' filepath='include/trace/hooks/mm.h' line='232' column='1'/>
+        <parameter type-id='7359adad' name='highest_memmap_pfn' filepath='include/trace/hooks/mm.h' line='232' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_handle_tlb_conf' mangled-name='__traceiter_android_vh_handle_tlb_conf' filepath='include/trace/hooks/fault.h' line='37' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_handle_tlb_conf'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/fault.h' line='37' column='1'/>
+        <parameter type-id='7359adad' name='addr' filepath='include/trace/hooks/fault.h' line='37' column='1'/>
+        <parameter type-id='f0981eeb' name='esr' filepath='include/trace/hooks/fault.h' line='37' column='1'/>
+        <parameter type-id='7292109c' name='ret' filepath='include/trace/hooks/fault.h' line='37' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_inactive_is_low' mangled-name='__traceiter_android_vh_inactive_is_low' filepath='include/trace/hooks/vmscan.h' line='46' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_inactive_is_low'>
@@ -119481,10 +119824,10 @@
         <parameter type-id='1d2c2b85' name='addr' filepath='include/trace/hooks/mm.h' line='94' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_init_swap_info_struct' mangled-name='__traceiter_android_vh_init_swap_info_struct' filepath='include/trace/hooks/mm.h' line='269' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_init_swap_info_struct'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='269' column='1'/>
-        <parameter type-id='11e11a61' name='p' filepath='include/trace/hooks/mm.h' line='269' column='1'/>
-        <parameter type-id='63de1ba0' name='swap_avail_heads' filepath='include/trace/hooks/mm.h' line='269' column='1'/>
+      <function-decl name='__traceiter_android_vh_init_swap_info_struct' mangled-name='__traceiter_android_vh_init_swap_info_struct' filepath='include/trace/hooks/mm.h' line='317' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_init_swap_info_struct'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='317' column='1'/>
+        <parameter type-id='11e11a61' name='p' filepath='include/trace/hooks/mm.h' line='317' column='1'/>
+        <parameter type-id='63de1ba0' name='swap_avail_heads' filepath='include/trace/hooks/mm.h' line='317' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_iommu_alloc_iova' mangled-name='__traceiter_android_vh_iommu_alloc_iova' filepath='include/trace/hooks/iommu.h' line='29' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_iommu_alloc_iova'>
@@ -119533,6 +119876,14 @@
         <parameter type-id='d8e6b335' name='ret' filepath='include/trace/hooks/ipv6.h' line='14' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
+      <function-decl name='__traceiter_android_vh_irqtime_account_process_tick' mangled-name='__traceiter_android_vh_irqtime_account_process_tick' filepath='include/trace/hooks/sched.h' line='316' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_irqtime_account_process_tick'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/sched.h' line='316' column='1'/>
+        <parameter type-id='f23e2572' name='p' filepath='include/trace/hooks/sched.h' line='316' column='1'/>
+        <parameter type-id='6ed6b432' name='rq' filepath='include/trace/hooks/sched.h' line='316' column='1'/>
+        <parameter type-id='95e97e5e' name='user_tick' filepath='include/trace/hooks/sched.h' line='316' column='1'/>
+        <parameter type-id='95e97e5e' name='ticks' filepath='include/trace/hooks/sched.h' line='316' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
       <function-decl name='__traceiter_android_vh_is_fpsimd_save' mangled-name='__traceiter_android_vh_is_fpsimd_save' filepath='include/trace/hooks/fpsimd.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_is_fpsimd_save'>
         <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/fpsimd.h' line='20' column='1'/>
         <parameter type-id='f23e2572' name='prev' filepath='include/trace/hooks/fpsimd.h' line='20' column='1'/>
@@ -119556,11 +119907,18 @@
         <parameter type-id='d8e6b335' name='reap' filepath='include/trace/hooks/signal.h' line='23' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_kmalloc_slab' mangled-name='__traceiter_android_vh_kmalloc_slab' filepath='include/trace/hooks/mm.h' line='144' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_kmalloc_slab'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='144' column='1'/>
-        <parameter type-id='f0981eeb' name='index' filepath='include/trace/hooks/mm.h' line='144' column='1'/>
-        <parameter type-id='3eb7c31c' name='flags' filepath='include/trace/hooks/mm.h' line='144' column='1'/>
-        <parameter type-id='276b90a6' name='s' filepath='include/trace/hooks/mm.h' line='144' column='1'/>
+      <function-decl name='__traceiter_android_vh_kmalloc_slab' mangled-name='__traceiter_android_vh_kmalloc_slab' filepath='include/trace/hooks/mm.h' line='152' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_kmalloc_slab'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='152' column='1'/>
+        <parameter type-id='f0981eeb' name='index' filepath='include/trace/hooks/mm.h' line='152' column='1'/>
+        <parameter type-id='3eb7c31c' name='flags' filepath='include/trace/hooks/mm.h' line='152' column='1'/>
+        <parameter type-id='276b90a6' name='s' filepath='include/trace/hooks/mm.h' line='152' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_kvmalloc_node_use_vmalloc' mangled-name='__traceiter_android_vh_kvmalloc_node_use_vmalloc' filepath='include/trace/hooks/mm.h' line='198' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_kvmalloc_node_use_vmalloc'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='198' column='1'/>
+        <parameter type-id='b59d7dce' name='size' filepath='include/trace/hooks/mm.h' line='198' column='1'/>
+        <parameter type-id='831e6e93' name='kmalloc_flags' filepath='include/trace/hooks/mm.h' line='198' column='1'/>
+        <parameter type-id='d8e6b335' name='use_vmalloc' filepath='include/trace/hooks/mm.h' line='198' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_logbuf' mangled-name='__traceiter_android_vh_logbuf' filepath='include/trace/hooks/logbuf.h' line='21' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_logbuf'>
@@ -119575,18 +119933,30 @@
         <parameter type-id='b59d7dce' name='text_len' filepath='include/trace/hooks/logbuf.h' line='25' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_look_around' mangled-name='__traceiter_android_vh_look_around' filepath='include/trace/hooks/mm.h' line='304' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_look_around'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='304' column='1'/>
-        <parameter type-id='d132145b' name='pvmw' filepath='include/trace/hooks/mm.h' line='304' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='304' column='1'/>
-        <parameter type-id='2ae08426' name='vma' filepath='include/trace/hooks/mm.h' line='304' column='1'/>
-        <parameter type-id='7292109c' name='referenced' filepath='include/trace/hooks/mm.h' line='304' column='1'/>
+      <function-decl name='__traceiter_android_vh_look_around' mangled-name='__traceiter_android_vh_look_around' filepath='include/trace/hooks/mm.h' line='352' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_look_around'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='352' column='1'/>
+        <parameter type-id='d132145b' name='pvmw' filepath='include/trace/hooks/mm.h' line='352' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='352' column='1'/>
+        <parameter type-id='2ae08426' name='vma' filepath='include/trace/hooks/mm.h' line='352' column='1'/>
+        <parameter type-id='7292109c' name='referenced' filepath='include/trace/hooks/mm.h' line='352' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_look_around_migrate_page' mangled-name='__traceiter_android_vh_look_around_migrate_page' filepath='include/trace/hooks/mm.h' line='301' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_look_around_migrate_page'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='301' column='1'/>
-        <parameter type-id='02f11ed4' name='old_page' filepath='include/trace/hooks/mm.h' line='301' column='1'/>
-        <parameter type-id='02f11ed4' name='new_page' filepath='include/trace/hooks/mm.h' line='301' column='1'/>
+      <function-decl name='__traceiter_android_vh_look_around_migrate_page' mangled-name='__traceiter_android_vh_look_around_migrate_page' filepath='include/trace/hooks/mm.h' line='349' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_look_around_migrate_page'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='349' column='1'/>
+        <parameter type-id='02f11ed4' name='old_page' filepath='include/trace/hooks/mm.h' line='349' column='1'/>
+        <parameter type-id='02f11ed4' name='new_page' filepath='include/trace/hooks/mm.h' line='349' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_madvise_cold_or_pageout' mangled-name='__traceiter_android_vh_madvise_cold_or_pageout' filepath='include/trace/hooks/mm.h' line='299' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_madvise_cold_or_pageout'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='299' column='1'/>
+        <parameter type-id='2ae08426' name='vma' filepath='include/trace/hooks/mm.h' line='299' column='1'/>
+        <parameter type-id='d8e6b335' name='allow_shared' filepath='include/trace/hooks/mm.h' line='299' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_madvise_cold_or_pageout_abort' mangled-name='__traceiter_android_vh_madvise_cold_or_pageout_abort' filepath='include/trace/hooks/mm.h' line='359' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_madvise_cold_or_pageout_abort'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='359' column='1'/>
+        <parameter type-id='2ae08426' name='vma' filepath='include/trace/hooks/mm.h' line='359' column='1'/>
+        <parameter type-id='d8e6b335' name='abort_madvise' filepath='include/trace/hooks/mm.h' line='359' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_map_util_freq' mangled-name='__traceiter_android_vh_map_util_freq' filepath='include/trace/hooks/sched.h' line='243' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_map_util_freq'>
@@ -119599,9 +119969,9 @@
         <parameter type-id='d8e6b335' name='need_freq_update' filepath='include/trace/hooks/sched.h' line='243' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_mark_page_accessed' mangled-name='__traceiter_android_vh_mark_page_accessed' filepath='include/trace/hooks/mm.h' line='181' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mark_page_accessed'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='181' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='181' column='1'/>
+      <function-decl name='__traceiter_android_vh_mark_page_accessed' mangled-name='__traceiter_android_vh_mark_page_accessed' filepath='include/trace/hooks/mm.h' line='189' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mark_page_accessed'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='189' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='189' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_media_device_setup_link' mangled-name='__traceiter_android_vh_media_device_setup_link' filepath='include/trace/hooks/v4l2mc.h' line='22' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_media_device_setup_link'>
@@ -119611,31 +119981,31 @@
         <parameter type-id='7292109c' name='ret' filepath='include/trace/hooks/v4l2mc.h' line='22' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_mem_cgroup_alloc' mangled-name='__traceiter_android_vh_mem_cgroup_alloc' filepath='include/trace/hooks/mm.h' line='129' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mem_cgroup_alloc'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='129' column='1'/>
-        <parameter type-id='223696fb' name='memcg' filepath='include/trace/hooks/mm.h' line='129' column='1'/>
+      <function-decl name='__traceiter_android_vh_mem_cgroup_alloc' mangled-name='__traceiter_android_vh_mem_cgroup_alloc' filepath='include/trace/hooks/mm.h' line='137' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mem_cgroup_alloc'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='137' column='1'/>
+        <parameter type-id='223696fb' name='memcg' filepath='include/trace/hooks/mm.h' line='137' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_mem_cgroup_css_offline' mangled-name='__traceiter_android_vh_mem_cgroup_css_offline' filepath='include/trace/hooks/mm.h' line='141' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mem_cgroup_css_offline'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='141' column='1'/>
-        <parameter type-id='cfff5953' name='css' filepath='include/trace/hooks/mm.h' line='141' column='1'/>
-        <parameter type-id='223696fb' name='memcg' filepath='include/trace/hooks/mm.h' line='141' column='1'/>
+      <function-decl name='__traceiter_android_vh_mem_cgroup_css_offline' mangled-name='__traceiter_android_vh_mem_cgroup_css_offline' filepath='include/trace/hooks/mm.h' line='149' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mem_cgroup_css_offline'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='149' column='1'/>
+        <parameter type-id='cfff5953' name='css' filepath='include/trace/hooks/mm.h' line='149' column='1'/>
+        <parameter type-id='223696fb' name='memcg' filepath='include/trace/hooks/mm.h' line='149' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_mem_cgroup_css_online' mangled-name='__traceiter_android_vh_mem_cgroup_css_online' filepath='include/trace/hooks/mm.h' line='138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mem_cgroup_css_online'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='138' column='1'/>
-        <parameter type-id='cfff5953' name='css' filepath='include/trace/hooks/mm.h' line='138' column='1'/>
-        <parameter type-id='223696fb' name='memcg' filepath='include/trace/hooks/mm.h' line='138' column='1'/>
+      <function-decl name='__traceiter_android_vh_mem_cgroup_css_online' mangled-name='__traceiter_android_vh_mem_cgroup_css_online' filepath='include/trace/hooks/mm.h' line='146' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mem_cgroup_css_online'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='146' column='1'/>
+        <parameter type-id='cfff5953' name='css' filepath='include/trace/hooks/mm.h' line='146' column='1'/>
+        <parameter type-id='223696fb' name='memcg' filepath='include/trace/hooks/mm.h' line='146' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_mem_cgroup_free' mangled-name='__traceiter_android_vh_mem_cgroup_free' filepath='include/trace/hooks/mm.h' line='132' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mem_cgroup_free'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='132' column='1'/>
-        <parameter type-id='223696fb' name='memcg' filepath='include/trace/hooks/mm.h' line='132' column='1'/>
+      <function-decl name='__traceiter_android_vh_mem_cgroup_free' mangled-name='__traceiter_android_vh_mem_cgroup_free' filepath='include/trace/hooks/mm.h' line='140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mem_cgroup_free'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='140' column='1'/>
+        <parameter type-id='223696fb' name='memcg' filepath='include/trace/hooks/mm.h' line='140' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_mem_cgroup_id_remove' mangled-name='__traceiter_android_vh_mem_cgroup_id_remove' filepath='include/trace/hooks/mm.h' line='135' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mem_cgroup_id_remove'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='135' column='1'/>
-        <parameter type-id='223696fb' name='memcg' filepath='include/trace/hooks/mm.h' line='135' column='1'/>
+      <function-decl name='__traceiter_android_vh_mem_cgroup_id_remove' mangled-name='__traceiter_android_vh_mem_cgroup_id_remove' filepath='include/trace/hooks/mm.h' line='143' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mem_cgroup_id_remove'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='143' column='1'/>
+        <parameter type-id='223696fb' name='memcg' filepath='include/trace/hooks/mm.h' line='143' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_meminfo_proc_show' mangled-name='__traceiter_android_vh_meminfo_proc_show' filepath='include/trace/hooks/mm.h' line='81' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_meminfo_proc_show'>
@@ -119643,10 +120013,10 @@
         <parameter type-id='f8dc9def' name='m' filepath='include/trace/hooks/mm.h' line='81' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_migrate_page_states' mangled-name='__traceiter_android_vh_migrate_page_states' filepath='include/trace/hooks/mm.h' line='211' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_migrate_page_states'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='211' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='211' column='1'/>
-        <parameter type-id='02f11ed4' name='newpage' filepath='include/trace/hooks/mm.h' line='211' column='1'/>
+      <function-decl name='__traceiter_android_vh_migrate_page_states' mangled-name='__traceiter_android_vh_migrate_page_states' filepath='include/trace/hooks/mm.h' line='244' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_migrate_page_states'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='244' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='244' column='1'/>
+        <parameter type-id='02f11ed4' name='newpage' filepath='include/trace/hooks/mm.h' line='244' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_mm_dirty_limits' mangled-name='__traceiter_android_vh_mm_dirty_limits' filepath='include/trace/hooks/mm.h' line='108' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mm_dirty_limits'>
@@ -119659,10 +120029,10 @@
         <parameter type-id='7359adad' name='pages_dirtied' filepath='include/trace/hooks/mm.h' line='108' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_mmap_region' mangled-name='__traceiter_android_vh_mmap_region' filepath='include/trace/hooks/mm.h' line='147' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mmap_region'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='147' column='1'/>
-        <parameter type-id='2ae08426' name='vma' filepath='include/trace/hooks/mm.h' line='147' column='1'/>
-        <parameter type-id='7359adad' name='addr' filepath='include/trace/hooks/mm.h' line='147' column='1'/>
+      <function-decl name='__traceiter_android_vh_mmap_region' mangled-name='__traceiter_android_vh_mmap_region' filepath='include/trace/hooks/mm.h' line='155' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mmap_region'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='155' column='1'/>
+        <parameter type-id='2ae08426' name='vma' filepath='include/trace/hooks/mm.h' line='155' column='1'/>
+        <parameter type-id='7359adad' name='addr' filepath='include/trace/hooks/mm.h' line='155' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_mmc_attach_sd' mangled-name='__traceiter_android_vh_mmc_attach_sd' filepath='include/trace/hooks/mmc_core.h' line='39' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mmc_attach_sd'>
@@ -119695,15 +120065,34 @@
         <parameter type-id='eaa32e2f' name='unused' filepath='include/trace/hooks/sched.h' line='394' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_mutex_unlock_slowpath' mangled-name='__traceiter_android_vh_mutex_unlock_slowpath' filepath='include/trace/hooks/dtask.h' line='65' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mutex_unlock_slowpath'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='65' column='1'/>
-        <parameter type-id='e0ea832a' name='lock' filepath='include/trace/hooks/dtask.h' line='65' column='1'/>
+      <function-decl name='__traceiter_android_vh_mutex_can_spin_on_owner' mangled-name='__traceiter_android_vh_mutex_can_spin_on_owner' filepath='include/trace/hooks/dtask.h' line='41' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mutex_can_spin_on_owner'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='41' column='1'/>
+        <parameter type-id='e0ea832a' name='lock' filepath='include/trace/hooks/dtask.h' line='41' column='1'/>
+        <parameter type-id='7292109c' name='retval' filepath='include/trace/hooks/dtask.h' line='41' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_mutex_unlock_slowpath_end' mangled-name='__traceiter_android_vh_mutex_unlock_slowpath_end' filepath='include/trace/hooks/dtask.h' line='68' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mutex_unlock_slowpath_end'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='68' column='1'/>
-        <parameter type-id='e0ea832a' name='lock' filepath='include/trace/hooks/dtask.h' line='68' column='1'/>
-        <parameter type-id='f23e2572' name='next' filepath='include/trace/hooks/dtask.h' line='68' column='1'/>
+      <function-decl name='__traceiter_android_vh_mutex_opt_spin_finish' mangled-name='__traceiter_android_vh_mutex_opt_spin_finish' filepath='include/trace/hooks/dtask.h' line='38' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mutex_opt_spin_finish'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='38' column='1'/>
+        <parameter type-id='e0ea832a' name='lock' filepath='include/trace/hooks/dtask.h' line='38' column='1'/>
+        <parameter type-id='b50a4934' name='taken' filepath='include/trace/hooks/dtask.h' line='38' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_mutex_opt_spin_start' mangled-name='__traceiter_android_vh_mutex_opt_spin_start' filepath='include/trace/hooks/dtask.h' line='35' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mutex_opt_spin_start'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='35' column='1'/>
+        <parameter type-id='e0ea832a' name='lock' filepath='include/trace/hooks/dtask.h' line='35' column='1'/>
+        <parameter type-id='d8e6b335' name='time_out' filepath='include/trace/hooks/dtask.h' line='35' column='1'/>
+        <parameter type-id='7292109c' name='cnt' filepath='include/trace/hooks/dtask.h' line='35' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_mutex_unlock_slowpath' mangled-name='__traceiter_android_vh_mutex_unlock_slowpath' filepath='include/trace/hooks/dtask.h' line='83' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mutex_unlock_slowpath'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='83' column='1'/>
+        <parameter type-id='e0ea832a' name='lock' filepath='include/trace/hooks/dtask.h' line='83' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_mutex_unlock_slowpath_end' mangled-name='__traceiter_android_vh_mutex_unlock_slowpath_end' filepath='include/trace/hooks/dtask.h' line='86' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mutex_unlock_slowpath_end'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='86' column='1'/>
+        <parameter type-id='e0ea832a' name='lock' filepath='include/trace/hooks/dtask.h' line='86' column='1'/>
+        <parameter type-id='f23e2572' name='next' filepath='include/trace/hooks/dtask.h' line='86' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_mutex_wait_finish' mangled-name='__traceiter_android_vh_mutex_wait_finish' filepath='include/trace/hooks/dtask.h' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_mutex_wait_finish'>
@@ -119722,16 +120111,22 @@
         <parameter type-id='7d3cd834' name='dev_name' filepath='include/trace/hooks/i2c.h' line='13' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
+      <function-decl name='__traceiter_android_vh_oom_check_panic' mangled-name='__traceiter_android_vh_oom_check_panic' filepath='include/trace/hooks/mm.h' line='114' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_oom_check_panic'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='114' column='1'/>
+        <parameter type-id='d20b5f3e' name='oc' filepath='include/trace/hooks/mm.h' line='114' column='1'/>
+        <parameter type-id='7292109c' name='ret' filepath='include/trace/hooks/mm.h' line='114' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
       <function-decl name='__traceiter_android_vh_override_creds' mangled-name='__traceiter_android_vh_override_creds' filepath='include/trace/hooks/creds.h' line='31' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_override_creds'>
         <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/creds.h' line='31' column='1'/>
         <parameter type-id='b42ffb57' name='task' filepath='include/trace/hooks/creds.h' line='31' column='1'/>
         <parameter type-id='bc33861a' name='new' filepath='include/trace/hooks/creds.h' line='31' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_page_isolated_for_reclaim' mangled-name='__traceiter_android_vh_page_isolated_for_reclaim' filepath='include/trace/hooks/mm.h' line='260' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_page_isolated_for_reclaim'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='260' column='1'/>
-        <parameter type-id='df4b7819' name='mm' filepath='include/trace/hooks/mm.h' line='260' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='260' column='1'/>
+      <function-decl name='__traceiter_android_vh_page_isolated_for_reclaim' mangled-name='__traceiter_android_vh_page_isolated_for_reclaim' filepath='include/trace/hooks/mm.h' line='302' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_page_isolated_for_reclaim'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='302' column='1'/>
+        <parameter type-id='df4b7819' name='mm' filepath='include/trace/hooks/mm.h' line='302' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='302' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_page_referenced_check_bypass' mangled-name='__traceiter_android_vh_page_referenced_check_bypass' filepath='include/trace/hooks/vmscan.h' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_page_referenced_check_bypass'>
@@ -119742,17 +120137,17 @@
         <parameter type-id='d8e6b335' name='bypass' filepath='include/trace/hooks/vmscan.h' line='28' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_page_referenced_one_end' mangled-name='__traceiter_android_vh_page_referenced_one_end' filepath='include/trace/hooks/mm.h' line='214' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_page_referenced_one_end'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='214' column='1'/>
-        <parameter type-id='2ae08426' name='vma' filepath='include/trace/hooks/mm.h' line='214' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='214' column='1'/>
-        <parameter type-id='95e97e5e' name='referenced' filepath='include/trace/hooks/mm.h' line='214' column='1'/>
+      <function-decl name='__traceiter_android_vh_page_referenced_one_end' mangled-name='__traceiter_android_vh_page_referenced_one_end' filepath='include/trace/hooks/mm.h' line='247' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_page_referenced_one_end'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='247' column='1'/>
+        <parameter type-id='2ae08426' name='vma' filepath='include/trace/hooks/mm.h' line='247' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='247' column='1'/>
+        <parameter type-id='95e97e5e' name='referenced' filepath='include/trace/hooks/mm.h' line='247' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_page_should_be_protected' mangled-name='__traceiter_android_vh_page_should_be_protected' filepath='include/trace/hooks/mm.h' line='178' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_page_should_be_protected'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='178' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='178' column='1'/>
-        <parameter type-id='d8e6b335' name='should_protect' filepath='include/trace/hooks/mm.h' line='178' column='1'/>
+      <function-decl name='__traceiter_android_vh_page_should_be_protected' mangled-name='__traceiter_android_vh_page_should_be_protected' filepath='include/trace/hooks/mm.h' line='186' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_page_should_be_protected'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='186' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='186' column='1'/>
+        <parameter type-id='d8e6b335' name='should_protect' filepath='include/trace/hooks/mm.h' line='186' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_page_trylock_clear' mangled-name='__traceiter_android_vh_page_trylock_clear' filepath='include/trace/hooks/vmscan.h' line='40' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_page_trylock_clear'>
@@ -119780,10 +120175,22 @@
         <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='71' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_pcplist_add_cma_pages_bypass' mangled-name='__traceiter_android_vh_pcplist_add_cma_pages_bypass' filepath='include/trace/hooks/mm.h' line='187' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_pcplist_add_cma_pages_bypass'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='187' column='1'/>
-        <parameter type-id='95e97e5e' name='migratetype' filepath='include/trace/hooks/mm.h' line='187' column='1'/>
-        <parameter type-id='d8e6b335' name='bypass' filepath='include/trace/hooks/mm.h' line='187' column='1'/>
+      <function-decl name='__traceiter_android_vh_pageset_update' mangled-name='__traceiter_android_vh_pageset_update' filepath='include/trace/hooks/mm.h' line='209' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_pageset_update'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='209' column='1'/>
+        <parameter type-id='1d2c2b85' name='high' filepath='include/trace/hooks/mm.h' line='209' column='1'/>
+        <parameter type-id='1d2c2b85' name='batch' filepath='include/trace/hooks/mm.h' line='209' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_pcplist_add_cma_pages_bypass' mangled-name='__traceiter_android_vh_pcplist_add_cma_pages_bypass' filepath='include/trace/hooks/mm.h' line='216' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_pcplist_add_cma_pages_bypass'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='216' column='1'/>
+        <parameter type-id='95e97e5e' name='migratetype' filepath='include/trace/hooks/mm.h' line='216' column='1'/>
+        <parameter type-id='d8e6b335' name='bypass' filepath='include/trace/hooks/mm.h' line='216' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_percpu_rwsem_wq_add' mangled-name='__traceiter_android_vh_percpu_rwsem_wq_add' filepath='include/trace/hooks/dtask.h' line='103' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_percpu_rwsem_wq_add'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='103' column='1'/>
+        <parameter type-id='652d9ef9' name='sem' filepath='include/trace/hooks/dtask.h' line='103' column='1'/>
+        <parameter type-id='b50a4934' name='reader' filepath='include/trace/hooks/dtask.h' line='103' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_prepare_update_load_avg_se' mangled-name='__traceiter_android_vh_prepare_update_load_avg_se' filepath='include/trace/hooks/sched.h' line='362' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_prepare_update_load_avg_se'>
@@ -119803,45 +120210,55 @@
         <parameter type-id='d8e6b335' name='reap' filepath='include/trace/hooks/signal.h' line='20' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
+      <function-decl name='__traceiter_android_vh_psi_event' mangled-name='__traceiter_android_vh_psi_event' filepath='include/trace/hooks/psi.h' line='22' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_psi_event'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/psi.h' line='22' column='1'/>
+        <parameter type-id='f34906ca' name='t' filepath='include/trace/hooks/psi.h' line='22' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_psi_group' mangled-name='__traceiter_android_vh_psi_group' filepath='include/trace/hooks/psi.h' line='26' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_psi_group'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/psi.h' line='26' column='1'/>
+        <parameter type-id='316cdcd3' name='group' filepath='include/trace/hooks/psi.h' line='26' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
       <function-decl name='__traceiter_android_vh_ptype_head' mangled-name='__traceiter_android_vh_ptype_head' filepath='include/trace/hooks/net.h' line='24' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_ptype_head'>
         <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/net.h' line='24' column='1'/>
         <parameter type-id='90532519' name='pt' filepath='include/trace/hooks/net.h' line='24' column='1'/>
         <parameter type-id='e84b031a' name='vendor_pt' filepath='include/trace/hooks/net.h' line='24' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_ra_tuning_max_page' mangled-name='__traceiter_android_vh_ra_tuning_max_page' filepath='include/trace/hooks/mm.h' line='193' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_ra_tuning_max_page'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='193' column='1'/>
-        <parameter type-id='a6cdca2a' name='ractl' filepath='include/trace/hooks/mm.h' line='193' column='1'/>
-        <parameter type-id='1d2c2b85' name='max_page' filepath='include/trace/hooks/mm.h' line='193' column='1'/>
+      <function-decl name='__traceiter_android_vh_ra_tuning_max_page' mangled-name='__traceiter_android_vh_ra_tuning_max_page' filepath='include/trace/hooks/mm.h' line='222' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_ra_tuning_max_page'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='222' column='1'/>
+        <parameter type-id='a6cdca2a' name='ractl' filepath='include/trace/hooks/mm.h' line='222' column='1'/>
+        <parameter type-id='1d2c2b85' name='max_page' filepath='include/trace/hooks/mm.h' line='222' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_record_mutex_lock_starttime' mangled-name='__traceiter_android_vh_record_mutex_lock_starttime' filepath='include/trace/hooks/dtask.h' line='71' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_record_mutex_lock_starttime'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='71' column='1'/>
-        <parameter type-id='f23e2572' name='tsk' filepath='include/trace/hooks/dtask.h' line='71' column='1'/>
-        <parameter type-id='7359adad' name='settime_jiffies' filepath='include/trace/hooks/dtask.h' line='71' column='1'/>
+      <function-decl name='__traceiter_android_vh_record_mutex_lock_starttime' mangled-name='__traceiter_android_vh_record_mutex_lock_starttime' filepath='include/trace/hooks/dtask.h' line='89' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_record_mutex_lock_starttime'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='89' column='1'/>
+        <parameter type-id='f23e2572' name='tsk' filepath='include/trace/hooks/dtask.h' line='89' column='1'/>
+        <parameter type-id='7359adad' name='settime_jiffies' filepath='include/trace/hooks/dtask.h' line='89' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_record_pcpu_rwsem_starttime' mangled-name='__traceiter_android_vh_record_pcpu_rwsem_starttime' filepath='include/trace/hooks/dtask.h' line='80' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_record_pcpu_rwsem_starttime'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='80' column='1'/>
-        <parameter type-id='f23e2572' name='tsk' filepath='include/trace/hooks/dtask.h' line='80' column='1'/>
-        <parameter type-id='7359adad' name='settime_jiffies' filepath='include/trace/hooks/dtask.h' line='80' column='1'/>
+      <function-decl name='__traceiter_android_vh_record_pcpu_rwsem_starttime' mangled-name='__traceiter_android_vh_record_pcpu_rwsem_starttime' filepath='include/trace/hooks/dtask.h' line='98' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_record_pcpu_rwsem_starttime'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='98' column='1'/>
+        <parameter type-id='f23e2572' name='tsk' filepath='include/trace/hooks/dtask.h' line='98' column='1'/>
+        <parameter type-id='7359adad' name='settime_jiffies' filepath='include/trace/hooks/dtask.h' line='98' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_record_rtmutex_lock_starttime' mangled-name='__traceiter_android_vh_record_rtmutex_lock_starttime' filepath='include/trace/hooks/dtask.h' line='74' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_record_rtmutex_lock_starttime'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='74' column='1'/>
-        <parameter type-id='f23e2572' name='tsk' filepath='include/trace/hooks/dtask.h' line='74' column='1'/>
-        <parameter type-id='7359adad' name='settime_jiffies' filepath='include/trace/hooks/dtask.h' line='74' column='1'/>
+      <function-decl name='__traceiter_android_vh_record_rtmutex_lock_starttime' mangled-name='__traceiter_android_vh_record_rtmutex_lock_starttime' filepath='include/trace/hooks/dtask.h' line='92' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_record_rtmutex_lock_starttime'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='92' column='1'/>
+        <parameter type-id='f23e2572' name='tsk' filepath='include/trace/hooks/dtask.h' line='92' column='1'/>
+        <parameter type-id='7359adad' name='settime_jiffies' filepath='include/trace/hooks/dtask.h' line='92' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_record_rwsem_lock_starttime' mangled-name='__traceiter_android_vh_record_rwsem_lock_starttime' filepath='include/trace/hooks/dtask.h' line='77' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_record_rwsem_lock_starttime'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='77' column='1'/>
-        <parameter type-id='f23e2572' name='tsk' filepath='include/trace/hooks/dtask.h' line='77' column='1'/>
-        <parameter type-id='7359adad' name='settime_jiffies' filepath='include/trace/hooks/dtask.h' line='77' column='1'/>
+      <function-decl name='__traceiter_android_vh_record_rwsem_lock_starttime' mangled-name='__traceiter_android_vh_record_rwsem_lock_starttime' filepath='include/trace/hooks/dtask.h' line='95' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_record_rwsem_lock_starttime'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='95' column='1'/>
+        <parameter type-id='f23e2572' name='tsk' filepath='include/trace/hooks/dtask.h' line='95' column='1'/>
+        <parameter type-id='7359adad' name='settime_jiffies' filepath='include/trace/hooks/dtask.h' line='95' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_remove_vmalloc_stack' mangled-name='__traceiter_android_vh_remove_vmalloc_stack' filepath='include/trace/hooks/mm.h' line='287' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_remove_vmalloc_stack'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='287' column='1'/>
-        <parameter type-id='d295dab2' name='vm' filepath='include/trace/hooks/mm.h' line='287' column='1'/>
+      <function-decl name='__traceiter_android_vh_remove_vmalloc_stack' mangled-name='__traceiter_android_vh_remove_vmalloc_stack' filepath='include/trace/hooks/mm.h' line='335' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_remove_vmalloc_stack'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='335' column='1'/>
+        <parameter type-id='d295dab2' name='vm' filepath='include/trace/hooks/mm.h' line='335' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_revert_creds' mangled-name='__traceiter_android_vh_revert_creds' filepath='include/trace/hooks/creds.h' line='35' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_revert_creds'>
@@ -119860,6 +120277,14 @@
         <parameter type-id='95e97e5e' name='migratetype' filepath='include/trace/hooks/mm.h' line='65' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
+      <function-decl name='__traceiter_android_vh_rmqueue_bulk_bypass' mangled-name='__traceiter_android_vh_rmqueue_bulk_bypass' filepath='include/trace/hooks/mm.h' line='212' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_rmqueue_bulk_bypass'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='212' column='1'/>
+        <parameter type-id='f0981eeb' name='order' filepath='include/trace/hooks/mm.h' line='212' column='1'/>
+        <parameter type-id='0e64a118' name='pcp' filepath='include/trace/hooks/mm.h' line='212' column='1'/>
+        <parameter type-id='95e97e5e' name='migratetype' filepath='include/trace/hooks/mm.h' line='212' column='1'/>
+        <parameter type-id='e84b031a' name='list' filepath='include/trace/hooks/mm.h' line='212' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
       <function-decl name='__traceiter_android_vh_rproc_recovery' mangled-name='__traceiter_android_vh_rproc_recovery' filepath='include/trace/hooks/remoteproc.h' line='21' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_rproc_recovery'>
         <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/remoteproc.h' line='21' column='1'/>
         <parameter type-id='5771c601' name='rproc' filepath='include/trace/hooks/remoteproc.h' line='21' column='1'/>
@@ -119868,6 +120293,23 @@
       <function-decl name='__traceiter_android_vh_rproc_recovery_set' mangled-name='__traceiter_android_vh_rproc_recovery_set' filepath='include/trace/hooks/remoteproc.h' line='26' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_rproc_recovery_set'>
         <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/remoteproc.h' line='26' column='1'/>
         <parameter type-id='5771c601' name='rproc' filepath='include/trace/hooks/remoteproc.h' line='26' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_rtmutex_wait_finish' mangled-name='__traceiter_android_vh_rtmutex_wait_finish' filepath='include/trace/hooks/dtask.h' line='48' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_rtmutex_wait_finish'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='48' column='1'/>
+        <parameter type-id='3992a90f' name='lock' filepath='include/trace/hooks/dtask.h' line='48' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_rtmutex_wait_start' mangled-name='__traceiter_android_vh_rtmutex_wait_start' filepath='include/trace/hooks/dtask.h' line='45' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_rtmutex_wait_start'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='45' column='1'/>
+        <parameter type-id='3992a90f' name='lock' filepath='include/trace/hooks/dtask.h' line='45' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_rwsem_can_spin_on_owner' mangled-name='__traceiter_android_vh_rwsem_can_spin_on_owner' filepath='include/trace/hooks/dtask.h' line='70' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_rwsem_can_spin_on_owner'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='70' column='1'/>
+        <parameter type-id='9b58df93' name='sem' filepath='include/trace/hooks/dtask.h' line='70' column='1'/>
+        <parameter type-id='d8e6b335' name='ret' filepath='include/trace/hooks/dtask.h' line='70' column='1'/>
+        <parameter type-id='b50a4934' name='wlock' filepath='include/trace/hooks/dtask.h' line='70' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_rwsem_init' mangled-name='__traceiter_android_vh_rwsem_init' filepath='include/trace/hooks/rwsem.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_rwsem_init'>
@@ -119879,6 +120321,31 @@
         <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/rwsem.h' line='49' column='1'/>
         <parameter type-id='9b58df93' name='sem' filepath='include/trace/hooks/rwsem.h' line='49' column='1'/>
         <parameter type-id='a48f20d2' name='waiter' filepath='include/trace/hooks/rwsem.h' line='49' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_rwsem_opt_spin_finish' mangled-name='__traceiter_android_vh_rwsem_opt_spin_finish' filepath='include/trace/hooks/dtask.h' line='67' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_rwsem_opt_spin_finish'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='67' column='1'/>
+        <parameter type-id='9b58df93' name='sem' filepath='include/trace/hooks/dtask.h' line='67' column='1'/>
+        <parameter type-id='b50a4934' name='taken' filepath='include/trace/hooks/dtask.h' line='67' column='1'/>
+        <parameter type-id='b50a4934' name='wlock' filepath='include/trace/hooks/dtask.h' line='67' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_rwsem_opt_spin_start' mangled-name='__traceiter_android_vh_rwsem_opt_spin_start' filepath='include/trace/hooks/dtask.h' line='64' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_rwsem_opt_spin_start'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='64' column='1'/>
+        <parameter type-id='9b58df93' name='sem' filepath='include/trace/hooks/dtask.h' line='64' column='1'/>
+        <parameter type-id='d8e6b335' name='time_out' filepath='include/trace/hooks/dtask.h' line='64' column='1'/>
+        <parameter type-id='7292109c' name='cnt' filepath='include/trace/hooks/dtask.h' line='64' column='1'/>
+        <parameter type-id='b50a4934' name='chk_only' filepath='include/trace/hooks/dtask.h' line='64' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_rwsem_read_wait_finish' mangled-name='__traceiter_android_vh_rwsem_read_wait_finish' filepath='include/trace/hooks/dtask.h' line='55' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_rwsem_read_wait_finish'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='55' column='1'/>
+        <parameter type-id='9b58df93' name='sem' filepath='include/trace/hooks/dtask.h' line='55' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_rwsem_read_wait_start' mangled-name='__traceiter_android_vh_rwsem_read_wait_start' filepath='include/trace/hooks/dtask.h' line='52' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_rwsem_read_wait_start'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='52' column='1'/>
+        <parameter type-id='9b58df93' name='sem' filepath='include/trace/hooks/dtask.h' line='52' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_rwsem_set_owner' mangled-name='__traceiter_android_vh_rwsem_set_owner' filepath='include/trace/hooks/rwsem.h' line='37' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_rwsem_set_owner'>
@@ -119916,6 +120383,16 @@
         <parameter type-id='9b58df93' name='sem' filepath='include/trace/hooks/rwsem.h' line='26' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
+      <function-decl name='__traceiter_android_vh_rwsem_write_wait_finish' mangled-name='__traceiter_android_vh_rwsem_write_wait_finish' filepath='include/trace/hooks/dtask.h' line='61' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_rwsem_write_wait_finish'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='61' column='1'/>
+        <parameter type-id='9b58df93' name='sem' filepath='include/trace/hooks/dtask.h' line='61' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_rwsem_write_wait_start' mangled-name='__traceiter_android_vh_rwsem_write_wait_start' filepath='include/trace/hooks/dtask.h' line='58' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_rwsem_write_wait_start'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='58' column='1'/>
+        <parameter type-id='9b58df93' name='sem' filepath='include/trace/hooks/dtask.h' line='58' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
       <function-decl name='__traceiter_android_vh_save_track_hash' mangled-name='__traceiter_android_vh_save_track_hash' filepath='include/trace/hooks/mm.h' line='123' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_save_track_hash'>
         <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='123' column='1'/>
         <parameter type-id='b50a4934' name='alloc' filepath='include/trace/hooks/mm.h' line='123' column='1'/>
@@ -119940,6 +120417,11 @@
         <parameter type-id='f23e2572' name='p' filepath='include/trace/hooks/sched.h' line='328' column='1'/>
         <parameter type-id='5f8a1ac4' name='new_mask' filepath='include/trace/hooks/sched.h' line='328' column='1'/>
         <parameter type-id='7292109c' name='retval' filepath='include/trace/hooks/sched.h' line='328' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_sched_show_task' mangled-name='__traceiter_android_vh_sched_show_task' filepath='include/trace/hooks/dtask.h' line='74' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_sched_show_task'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/dtask.h' line='74' column='1'/>
+        <parameter type-id='f23e2572' name='task' filepath='include/trace/hooks/dtask.h' line='74' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_sched_stat_runtime_rt' mangled-name='__traceiter_android_vh_sched_stat_runtime_rt' filepath='include/trace/hooks/sched.h' line='366' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_sched_stat_runtime_rt'>
@@ -120032,9 +120514,9 @@
         <parameter type-id='efc8cc9a' name='mod' filepath='include/trace/hooks/module.h' line='20' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_set_shmem_page_flag' mangled-name='__traceiter_android_vh_set_shmem_page_flag' filepath='include/trace/hooks/mm.h' line='284' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_set_shmem_page_flag'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='284' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='284' column='1'/>
+      <function-decl name='__traceiter_android_vh_set_shmem_page_flag' mangled-name='__traceiter_android_vh_set_shmem_page_flag' filepath='include/trace/hooks/mm.h' line='332' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_set_shmem_page_flag'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='332' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='332' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_set_wake_flags' mangled-name='__traceiter_android_vh_set_wake_flags' filepath='include/trace/hooks/sched.h' line='280' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_set_wake_flags'>
@@ -120058,9 +120540,32 @@
         <parameter type-id='7292109c' name='hook_inuse' filepath='include/trace/hooks/fips140.h' line='25' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_show_mapcount_pages' mangled-name='__traceiter_android_vh_show_mapcount_pages' filepath='include/trace/hooks/mm.h' line='172' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_show_mapcount_pages'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='172' column='1'/>
-        <parameter type-id='eaa32e2f' name='unused' filepath='include/trace/hooks/mm.h' line='172' column='1'/>
+      <function-decl name='__traceiter_android_vh_shmem_alloc_page' mangled-name='__traceiter_android_vh_shmem_alloc_page' filepath='include/trace/hooks/shmem_fs.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_shmem_alloc_page'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/shmem_fs.h' line='17' column='1'/>
+        <parameter type-id='9f93c9da' name='page' filepath='include/trace/hooks/shmem_fs.h' line='17' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_should_alloc_pages_retry' mangled-name='__traceiter_android_vh_should_alloc_pages_retry' filepath='include/trace/hooks/mm.h' line='201' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_should_alloc_pages_retry'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='201' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='include/trace/hooks/mm.h' line='201' column='1'/>
+        <parameter type-id='95e97e5e' name='order' filepath='include/trace/hooks/mm.h' line='201' column='1'/>
+        <parameter type-id='7292109c' name='alloc_flags' filepath='include/trace/hooks/mm.h' line='201' column='1'/>
+        <parameter type-id='95e97e5e' name='migratetype' filepath='include/trace/hooks/mm.h' line='201' column='1'/>
+        <parameter type-id='0a0aff97' name='preferred_zone' filepath='include/trace/hooks/mm.h' line='201' column='1'/>
+        <parameter type-id='9f93c9da' name='page' filepath='include/trace/hooks/mm.h' line='201' column='1'/>
+        <parameter type-id='d8e6b335' name='should_alloc_retry' filepath='include/trace/hooks/mm.h' line='201' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_should_end_madvise' mangled-name='__traceiter_android_vh_should_end_madvise' filepath='include/trace/hooks/mm.h' line='305' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_should_end_madvise'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='305' column='1'/>
+        <parameter type-id='df4b7819' name='mm' filepath='include/trace/hooks/mm.h' line='305' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='305' column='1'/>
+        <parameter type-id='d8e6b335' name='pageout' filepath='include/trace/hooks/mm.h' line='305' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_show_mapcount_pages' mangled-name='__traceiter_android_vh_show_mapcount_pages' filepath='include/trace/hooks/mm.h' line='180' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_show_mapcount_pages'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='180' column='1'/>
+        <parameter type-id='eaa32e2f' name='unused' filepath='include/trace/hooks/mm.h' line='180' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_show_max_freq' mangled-name='__traceiter_android_vh_show_max_freq' filepath='include/trace/hooks/cpufreq.h' line='18' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_show_max_freq'>
@@ -120107,10 +120612,16 @@
         <parameter type-id='d8e6b335' name='bypass' filepath='include/trace/hooks/vmscan.h' line='19' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_si_swapinfo' mangled-name='__traceiter_android_vh_si_swapinfo' filepath='include/trace/hooks/mm.h' line='272' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_si_swapinfo'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='272' column='1'/>
-        <parameter type-id='11e11a61' name='si' filepath='include/trace/hooks/mm.h' line='272' column='1'/>
-        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='272' column='1'/>
+      <function-decl name='__traceiter_android_vh_si_swapinfo' mangled-name='__traceiter_android_vh_si_swapinfo' filepath='include/trace/hooks/mm.h' line='320' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_si_swapinfo'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='320' column='1'/>
+        <parameter type-id='11e11a61' name='si' filepath='include/trace/hooks/mm.h' line='320' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='320' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_skip_swapcache' mangled-name='__traceiter_android_vh_skip_swapcache' filepath='include/trace/hooks/mm.h' line='362' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_skip_swapcache'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='362' column='1'/>
+        <parameter type-id='e0c6ffc2' name='entry' filepath='include/trace/hooks/mm.h' line='362' column='1'/>
+        <parameter type-id='d8e6b335' name='skip' filepath='include/trace/hooks/mm.h' line='362' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_snapshot_refaults' mangled-name='__traceiter_android_vh_snapshot_refaults' filepath='include/trace/hooks/vmscan.h' line='50' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_snapshot_refaults'>
@@ -120136,15 +120647,27 @@
         <parameter type-id='d8e6b335' name='is_support' filepath='include/trace/hooks/sound.h' line='12' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_swap_slot_cache_active' mangled-name='__traceiter_android_vh_swap_slot_cache_active' filepath='include/trace/hooks/mm.h' line='226' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_swap_slot_cache_active'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='226' column='1'/>
-        <parameter type-id='b50a4934' name='swap_slot_cache_active' filepath='include/trace/hooks/mm.h' line='226' column='1'/>
+      <function-decl name='__traceiter_android_vh_subpage_dma_contig_alloc' mangled-name='__traceiter_android_vh_subpage_dma_contig_alloc' filepath='include/trace/hooks/mm.h' line='219' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_subpage_dma_contig_alloc'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='219' column='1'/>
+        <parameter type-id='d8e6b335' name='allow_subpage_alloc' filepath='include/trace/hooks/mm.h' line='219' column='1'/>
+        <parameter type-id='fa0b179b' name='dev' filepath='include/trace/hooks/mm.h' line='219' column='1'/>
+        <parameter type-id='78c01427' name='size' filepath='include/trace/hooks/mm.h' line='219' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_swapin_add_anon_rmap' mangled-name='__traceiter_android_vh_swapin_add_anon_rmap' filepath='include/trace/hooks/mm.h' line='205' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_swapin_add_anon_rmap'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='205' column='1'/>
-        <parameter type-id='d02f4143' name='vmf' filepath='include/trace/hooks/mm.h' line='205' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='205' column='1'/>
+      <function-decl name='__traceiter_android_vh_swap_avail_heads_init' mangled-name='__traceiter_android_vh_swap_avail_heads_init' filepath='include/trace/hooks/mm.h' line='314' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_swap_avail_heads_init'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='314' column='1'/>
+        <parameter type-id='63de1ba0' name='swap_avail_heads' filepath='include/trace/hooks/mm.h' line='314' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_swap_slot_cache_active' mangled-name='__traceiter_android_vh_swap_slot_cache_active' filepath='include/trace/hooks/mm.h' line='259' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_swap_slot_cache_active'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='259' column='1'/>
+        <parameter type-id='b50a4934' name='swap_slot_cache_active' filepath='include/trace/hooks/mm.h' line='259' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_swapin_add_anon_rmap' mangled-name='__traceiter_android_vh_swapin_add_anon_rmap' filepath='include/trace/hooks/mm.h' line='238' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_swapin_add_anon_rmap'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='238' column='1'/>
+        <parameter type-id='d02f4143' name='vmf' filepath='include/trace/hooks/mm.h' line='238' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='238' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_sync_txn_recvd' mangled-name='__traceiter_android_vh_sync_txn_recvd' filepath='include/trace/hooks/binder.h' line='57' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_sync_txn_recvd'>
@@ -120159,9 +120682,9 @@
         <parameter type-id='f23e2572' name='task' filepath='include/trace/hooks/sys.h' line='17' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_test_clear_look_around_ref' mangled-name='__traceiter_android_vh_test_clear_look_around_ref' filepath='include/trace/hooks/mm.h' line='298' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_test_clear_look_around_ref'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='298' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='298' column='1'/>
+      <function-decl name='__traceiter_android_vh_test_clear_look_around_ref' mangled-name='__traceiter_android_vh_test_clear_look_around_ref' filepath='include/trace/hooks/mm.h' line='346' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_test_clear_look_around_ref'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='346' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='346' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_thermal_pm_notify_suspend' mangled-name='__traceiter_android_vh_thermal_pm_notify_suspend' filepath='include/trace/hooks/thermal.h' line='23' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_thermal_pm_notify_suspend'>
@@ -120182,18 +120705,39 @@
         <parameter type-id='95e97e5e' name='len' filepath='include/trace/hooks/fs.h' line='17' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_try_to_unmap_one' mangled-name='__traceiter_android_vh_try_to_unmap_one' filepath='include/trace/hooks/mm.h' line='150' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_try_to_unmap_one'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='150' column='1'/>
-        <parameter type-id='2ae08426' name='vma' filepath='include/trace/hooks/mm.h' line='150' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='150' column='1'/>
-        <parameter type-id='7359adad' name='addr' filepath='include/trace/hooks/mm.h' line='150' column='1'/>
-        <parameter type-id='b50a4934' name='ret' filepath='include/trace/hooks/mm.h' line='150' column='1'/>
+      <function-decl name='__traceiter_android_vh_try_to_freeze_todo' mangled-name='__traceiter_android_vh_try_to_freeze_todo' filepath='include/trace/hooks/power.h' line='25' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_try_to_freeze_todo'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/power.h' line='25' column='1'/>
+        <parameter type-id='f0981eeb' name='todo' filepath='include/trace/hooks/power.h' line='25' column='1'/>
+        <parameter type-id='f0981eeb' name='elapsed_msecs' filepath='include/trace/hooks/power.h' line='25' column='1'/>
+        <parameter type-id='b50a4934' name='wq_busy' filepath='include/trace/hooks/power.h' line='25' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_try_to_freeze_todo_unfrozen' mangled-name='__traceiter_android_vh_try_to_freeze_todo_unfrozen' filepath='include/trace/hooks/power.h' line='29' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_try_to_freeze_todo_unfrozen'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/power.h' line='29' column='1'/>
+        <parameter type-id='f23e2572' name='p' filepath='include/trace/hooks/power.h' line='29' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_try_to_unmap_one' mangled-name='__traceiter_android_vh_try_to_unmap_one' filepath='include/trace/hooks/mm.h' line='158' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_try_to_unmap_one'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='158' column='1'/>
+        <parameter type-id='2ae08426' name='vma' filepath='include/trace/hooks/mm.h' line='158' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='158' column='1'/>
+        <parameter type-id='7359adad' name='addr' filepath='include/trace/hooks/mm.h' line='158' column='1'/>
+        <parameter type-id='b50a4934' name='ret' filepath='include/trace/hooks/mm.h' line='158' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_tune_inactive_ratio' mangled-name='__traceiter_android_vh_tune_inactive_ratio' filepath='include/trace/hooks/vmscan.h' line='22' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_tune_inactive_ratio'>
         <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/vmscan.h' line='22' column='1'/>
         <parameter type-id='1d2c2b85' name='inactive_ratio' filepath='include/trace/hooks/vmscan.h' line='22' column='1'/>
         <parameter type-id='95e97e5e' name='file' filepath='include/trace/hooks/vmscan.h' line='22' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_tune_mmap_readaround' mangled-name='__traceiter_android_vh_tune_mmap_readaround' filepath='include/trace/hooks/mm.h' line='225' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_tune_mmap_readaround'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='225' column='1'/>
+        <parameter type-id='f0981eeb' name='ra_pages' filepath='include/trace/hooks/mm.h' line='225' column='1'/>
+        <parameter type-id='7359adad' name='pgoff' filepath='include/trace/hooks/mm.h' line='225' column='1'/>
+        <parameter type-id='1d2c2b85' name='start' filepath='include/trace/hooks/mm.h' line='225' column='1'/>
+        <parameter type-id='807869d3' name='size' filepath='include/trace/hooks/mm.h' line='225' column='1'/>
+        <parameter type-id='807869d3' name='async_size' filepath='include/trace/hooks/mm.h' line='225' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_tune_scan_type' mangled-name='__traceiter_android_vh_tune_scan_type' filepath='include/trace/hooks/vmscan.h' line='13' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_tune_scan_type'>
@@ -120309,19 +120853,26 @@
         <parameter type-id='442b8d89' name='hba' filepath='include/trace/hooks/ufshcd.h' line='46' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_unuse_swap_page' mangled-name='__traceiter_android_vh_unuse_swap_page' filepath='include/trace/hooks/mm.h' line='266' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_unuse_swap_page'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='266' column='1'/>
-        <parameter type-id='11e11a61' name='si' filepath='include/trace/hooks/mm.h' line='266' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='266' column='1'/>
+      <function-decl name='__traceiter_android_vh_unreserve_highatomic_bypass' mangled-name='__traceiter_android_vh_unreserve_highatomic_bypass' filepath='include/trace/hooks/mm.h' line='206' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_unreserve_highatomic_bypass'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='206' column='1'/>
+        <parameter type-id='b50a4934' name='force' filepath='include/trace/hooks/mm.h' line='206' column='1'/>
+        <parameter type-id='0a0aff97' name='zone' filepath='include/trace/hooks/mm.h' line='206' column='1'/>
+        <parameter type-id='d8e6b335' name='skip_unreserve_highatomic' filepath='include/trace/hooks/mm.h' line='206' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_update_page_mapcount' mangled-name='__traceiter_android_vh_update_page_mapcount' filepath='include/trace/hooks/mm.h' line='162' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_update_page_mapcount'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='162' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='162' column='1'/>
-        <parameter type-id='b50a4934' name='inc_size' filepath='include/trace/hooks/mm.h' line='162' column='1'/>
-        <parameter type-id='b50a4934' name='compound' filepath='include/trace/hooks/mm.h' line='162' column='1'/>
-        <parameter type-id='d8e6b335' name='first_mapping' filepath='include/trace/hooks/mm.h' line='162' column='1'/>
-        <parameter type-id='d8e6b335' name='success' filepath='include/trace/hooks/mm.h' line='162' column='1'/>
+      <function-decl name='__traceiter_android_vh_unuse_swap_page' mangled-name='__traceiter_android_vh_unuse_swap_page' filepath='include/trace/hooks/mm.h' line='311' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_unuse_swap_page'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='311' column='1'/>
+        <parameter type-id='11e11a61' name='si' filepath='include/trace/hooks/mm.h' line='311' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='311' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_update_page_mapcount' mangled-name='__traceiter_android_vh_update_page_mapcount' filepath='include/trace/hooks/mm.h' line='170' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_update_page_mapcount'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='170' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='170' column='1'/>
+        <parameter type-id='b50a4934' name='inc_size' filepath='include/trace/hooks/mm.h' line='170' column='1'/>
+        <parameter type-id='b50a4934' name='compound' filepath='include/trace/hooks/mm.h' line='170' column='1'/>
+        <parameter type-id='d8e6b335' name='first_mapping' filepath='include/trace/hooks/mm.h' line='170' column='1'/>
+        <parameter type-id='d8e6b335' name='success' filepath='include/trace/hooks/mm.h' line='170' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_android_vh_update_topology_flags_workfn' mangled-name='__traceiter_android_vh_update_topology_flags_workfn' filepath='include/trace/hooks/topology.h' line='19' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_update_topology_flags_workfn'>
@@ -120366,9 +120917,33 @@
         <parameter type-id='7292109c' name='ret' filepath='include/trace/hooks/v4l2core.h' line='41' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_android_vh_waiting_for_page_migration' mangled-name='__traceiter_android_vh_waiting_for_page_migration' filepath='include/trace/hooks/mm.h' line='208' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_waiting_for_page_migration'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='208' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='208' column='1'/>
+      <function-decl name='__traceiter_android_vh_vmpressure' mangled-name='__traceiter_android_vh_vmpressure' filepath='include/trace/hooks/mm.h' line='126' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_vmpressure'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='126' column='1'/>
+        <parameter type-id='223696fb' name='memcg' filepath='include/trace/hooks/mm.h' line='126' column='1'/>
+        <parameter type-id='d8e6b335' name='bypass' filepath='include/trace/hooks/mm.h' line='126' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_waiting_for_page_migration' mangled-name='__traceiter_android_vh_waiting_for_page_migration' filepath='include/trace/hooks/mm.h' line='241' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_waiting_for_page_migration'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/mm.h' line='241' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='include/trace/hooks/mm.h' line='241' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_wakeup_bypass' mangled-name='__traceiter_android_vh_wakeup_bypass' filepath='include/trace/hooks/wakeupbypass.h' line='11' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_wakeup_bypass'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/wakeupbypass.h' line='11' column='1'/>
+        <parameter type-id='7292109c' name='is_wakeup_bypassed' filepath='include/trace/hooks/wakeupbypass.h' line='11' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_watchdog_timer_softlockup' mangled-name='__traceiter_android_vh_watchdog_timer_softlockup' filepath='include/trace/hooks/softlockup.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_watchdog_timer_softlockup'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/softlockup.h' line='20' column='1'/>
+        <parameter type-id='95e97e5e' name='duration' filepath='include/trace/hooks/softlockup.h' line='20' column='1'/>
+        <parameter type-id='4616a179' name='regs' filepath='include/trace/hooks/softlockup.h' line='20' column='1'/>
+        <parameter type-id='b50a4934' name='is_panic' filepath='include/trace/hooks/softlockup.h' line='20' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_android_vh_wq_lockup_pool' mangled-name='__traceiter_android_vh_wq_lockup_pool' filepath='include/trace/hooks/wqlockup.h' line='14' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_android_vh_wq_lockup_pool'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/hooks/wqlockup.h' line='14' column='1'/>
+        <parameter type-id='95e97e5e' name='cpu' filepath='include/trace/hooks/wqlockup.h' line='14' column='1'/>
+        <parameter type-id='7359adad' name='pool_ts' filepath='include/trace/hooks/wqlockup.h' line='14' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_binder_transaction_received' mangled-name='__traceiter_binder_transaction_received' filepath='drivers/android/./binder_trace.h' line='150' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_binder_transaction_received'>
@@ -120526,15 +121101,15 @@
         <parameter type-id='9c313c2d' name='size' filepath='include/trace/events/gpu_mem.h' line='30' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_hrtimer_expire_entry' mangled-name='__traceiter_hrtimer_expire_entry' filepath='include/trace/events/timer.h' line='232' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_hrtimer_expire_entry'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/events/timer.h' line='232' column='1'/>
-        <parameter type-id='08c8d0fa' name='hrtimer' filepath='include/trace/events/timer.h' line='232' column='1'/>
-        <parameter type-id='44372936' name='now' filepath='include/trace/events/timer.h' line='232' column='1'/>
+      <function-decl name='__traceiter_hrtimer_expire_entry' mangled-name='__traceiter_hrtimer_expire_entry' filepath='include/trace/events/timer.h' line='236' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_hrtimer_expire_entry'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/events/timer.h' line='236' column='1'/>
+        <parameter type-id='08c8d0fa' name='hrtimer' filepath='include/trace/events/timer.h' line='236' column='1'/>
+        <parameter type-id='44372936' name='now' filepath='include/trace/events/timer.h' line='236' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_hrtimer_expire_exit' mangled-name='__traceiter_hrtimer_expire_exit' filepath='include/trace/events/timer.h' line='279' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_hrtimer_expire_exit'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/events/timer.h' line='279' column='1'/>
-        <parameter type-id='08c8d0fa' name='hrtimer' filepath='include/trace/events/timer.h' line='279' column='1'/>
+      <function-decl name='__traceiter_hrtimer_expire_exit' mangled-name='__traceiter_hrtimer_expire_exit' filepath='include/trace/events/timer.h' line='283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_hrtimer_expire_exit'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/events/timer.h' line='283' column='1'/>
+        <parameter type-id='08c8d0fa' name='hrtimer' filepath='include/trace/events/timer.h' line='283' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_ipi_entry' mangled-name='__traceiter_ipi_entry' filepath='include/trace/events/ipi.h' line='64' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_ipi_entry'>
@@ -120588,6 +121163,29 @@
       <function-decl name='__traceiter_mm_vmscan_direct_reclaim_end' mangled-name='__traceiter_mm_vmscan_direct_reclaim_end' filepath='include/trace/events/vmscan.h' line='162' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_mm_vmscan_direct_reclaim_end'>
         <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/events/vmscan.h' line='162' column='1'/>
         <parameter type-id='7359adad' name='nr_reclaimed' filepath='include/trace/events/vmscan.h' line='162' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_net_dev_queue' mangled-name='__traceiter_net_dev_queue' filepath='include/trace/events/net.h' line='143' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_net_dev_queue'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/events/net.h' line='143' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='include/trace/events/net.h' line='143' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_net_dev_xmit' mangled-name='__traceiter_net_dev_xmit' filepath='include/trace/events/net.h' line='71' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_net_dev_xmit'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/events/net.h' line='71' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='include/trace/events/net.h' line='71' column='1'/>
+        <parameter type-id='95e97e5e' name='rc' filepath='include/trace/events/net.h' line='71' column='1'/>
+        <parameter type-id='68a2d05b' name='dev' filepath='include/trace/events/net.h' line='71' column='1'/>
+        <parameter type-id='f0981eeb' name='skb_len' filepath='include/trace/events/net.h' line='71' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_netif_receive_skb' mangled-name='__traceiter_netif_receive_skb' filepath='include/trace/events/net.h' line='150' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_netif_receive_skb'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/events/net.h' line='150' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='include/trace/events/net.h' line='150' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__traceiter_netif_rx' mangled-name='__traceiter_netif_rx' filepath='include/trace/events/net.h' line='157' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_netif_rx'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='include/trace/events/net.h' line='157' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='include/trace/events/net.h' line='157' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__traceiter_pelt_cfs_tp' mangled-name='__traceiter_pelt_cfs_tp' filepath='include/trace/events/sched.h' line='636' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_pelt_cfs_tp'>
@@ -120764,16 +121362,16 @@
         <parameter type-id='19c2251e' name='act' filepath='include/trace/events/xdp.h' line='28' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__traceiter_xhci_urb_giveback' mangled-name='__traceiter_xhci_urb_giveback' filepath='drivers/usb/host/./xhci-trace.h' line='307' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_xhci_urb_giveback'>
-        <parameter type-id='eaa32e2f' name='__data' filepath='drivers/usb/host/./xhci-trace.h' line='307' column='1'/>
-        <parameter type-id='ab85b8f2' name='urb' filepath='drivers/usb/host/./xhci-trace.h' line='307' column='1'/>
+      <function-decl name='__traceiter_xhci_urb_giveback' mangled-name='__traceiter_xhci_urb_giveback' filepath='drivers/usb/host/./xhci-trace.h' line='303' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__traceiter_xhci_urb_giveback'>
+        <parameter type-id='eaa32e2f' name='__data' filepath='drivers/usb/host/./xhci-trace.h' line='303' column='1'/>
+        <parameter type-id='ab85b8f2' name='urb' filepath='drivers/usb/host/./xhci-trace.h' line='303' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <var-decl name='__tracepoint_android_rvh_account_irq' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_account_irq' visibility='default' filepath='include/trace/hooks/sched.h' line='195' column='1' elf-symbol-id='__tracepoint_android_rvh_account_irq'/>
       <var-decl name='__tracepoint_android_rvh_after_dequeue_task' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_after_dequeue_task' visibility='default' filepath='include/trace/hooks/sched.h' line='340' column='1' elf-symbol-id='__tracepoint_android_rvh_after_dequeue_task'/>
       <var-decl name='__tracepoint_android_rvh_after_enqueue_task' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_after_enqueue_task' visibility='default' filepath='include/trace/hooks/sched.h' line='336' column='1' elf-symbol-id='__tracepoint_android_rvh_after_enqueue_task'/>
-      <var-decl name='__tracepoint_android_rvh_alloc_si' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_alloc_si' visibility='default' filepath='include/trace/hooks/mm.h' line='275' column='1' elf-symbol-id='__tracepoint_android_rvh_alloc_si'/>
-      <var-decl name='__tracepoint_android_rvh_alloc_swap_slot_cache' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_alloc_swap_slot_cache' visibility='default' filepath='include/trace/hooks/mm.h' line='237' column='1' elf-symbol-id='__tracepoint_android_rvh_alloc_swap_slot_cache'/>
+      <var-decl name='__tracepoint_android_rvh_alloc_si' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_alloc_si' visibility='default' filepath='include/trace/hooks/mm.h' line='323' column='1' elf-symbol-id='__tracepoint_android_rvh_alloc_si'/>
+      <var-decl name='__tracepoint_android_rvh_alloc_swap_slot_cache' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_alloc_swap_slot_cache' visibility='default' filepath='include/trace/hooks/mm.h' line='270' column='1' elf-symbol-id='__tracepoint_android_rvh_alloc_swap_slot_cache'/>
       <var-decl name='__tracepoint_android_rvh_arm64_serror_panic' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_arm64_serror_panic' visibility='default' filepath='include/trace/hooks/traps.h' line='34' column='1' elf-symbol-id='__tracepoint_android_rvh_arm64_serror_panic'/>
       <var-decl name='__tracepoint_android_rvh_bad_mode' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_bad_mode' visibility='default' filepath='include/trace/hooks/traps.h' line='30' column='1' elf-symbol-id='__tracepoint_android_rvh_bad_mode'/>
       <var-decl name='__tracepoint_android_rvh_binder_transaction' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_binder_transaction' visibility='default' filepath='include/trace/hooks/binder.h' line='71' column='1' elf-symbol-id='__tracepoint_android_rvh_binder_transaction'/>
@@ -120800,7 +121398,7 @@
       <var-decl name='__tracepoint_android_rvh_do_sea' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_do_sea' visibility='default' filepath='include/trace/hooks/fault.h' line='24' column='1' elf-symbol-id='__tracepoint_android_rvh_do_sea'/>
       <var-decl name='__tracepoint_android_rvh_do_sp_pc_abort' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_do_sp_pc_abort' visibility='default' filepath='include/trace/hooks/fault.h' line='32' column='1' elf-symbol-id='__tracepoint_android_rvh_do_sp_pc_abort'/>
       <var-decl name='__tracepoint_android_rvh_do_undefinstr' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_do_undefinstr' visibility='default' filepath='include/trace/hooks/traps.h' line='20' column='1' elf-symbol-id='__tracepoint_android_rvh_do_undefinstr'/>
-      <var-decl name='__tracepoint_android_rvh_drain_slots_cache_cpu' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_drain_slots_cache_cpu' visibility='default' filepath='include/trace/hooks/mm.h' line='229' column='1' elf-symbol-id='__tracepoint_android_rvh_drain_slots_cache_cpu'/>
+      <var-decl name='__tracepoint_android_rvh_drain_slots_cache_cpu' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_drain_slots_cache_cpu' visibility='default' filepath='include/trace/hooks/mm.h' line='262' column='1' elf-symbol-id='__tracepoint_android_rvh_drain_slots_cache_cpu'/>
       <var-decl name='__tracepoint_android_rvh_enqueue_entity' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_enqueue_entity' visibility='default' filepath='include/trace/hooks/sched.h' line='346' column='1' elf-symbol-id='__tracepoint_android_rvh_enqueue_entity'/>
       <var-decl name='__tracepoint_android_rvh_enqueue_task' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_enqueue_task' visibility='default' filepath='include/trace/hooks/sched.h' line='49' column='1' elf-symbol-id='__tracepoint_android_rvh_enqueue_task'/>
       <var-decl name='__tracepoint_android_rvh_enqueue_task_fair' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_enqueue_task_fair' visibility='default' filepath='include/trace/hooks/sched.h' line='354' column='1' elf-symbol-id='__tracepoint_android_rvh_enqueue_task_fair'/>
@@ -120813,10 +121411,10 @@
       <var-decl name='__tracepoint_android_rvh_flush_task' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_flush_task' visibility='default' filepath='include/trace/hooks/sched.h' line='175' column='1' elf-symbol-id='__tracepoint_android_rvh_flush_task'/>
       <var-decl name='__tracepoint_android_rvh_force_compatible_post' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_force_compatible_post' visibility='default' filepath='include/trace/hooks/sched.h' line='386' column='1' elf-symbol-id='__tracepoint_android_rvh_force_compatible_post'/>
       <var-decl name='__tracepoint_android_rvh_force_compatible_pre' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_force_compatible_pre' visibility='default' filepath='include/trace/hooks/sched.h' line='382' column='1' elf-symbol-id='__tracepoint_android_rvh_force_compatible_pre'/>
-      <var-decl name='__tracepoint_android_rvh_free_swap_slot' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_free_swap_slot' visibility='default' filepath='include/trace/hooks/mm.h' line='243' column='1' elf-symbol-id='__tracepoint_android_rvh_free_swap_slot'/>
-      <var-decl name='__tracepoint_android_rvh_get_swap_page' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_get_swap_page' visibility='default' filepath='include/trace/hooks/mm.h' line='249' column='1' elf-symbol-id='__tracepoint_android_rvh_get_swap_page'/>
+      <var-decl name='__tracepoint_android_rvh_free_swap_slot' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_free_swap_slot' visibility='default' filepath='include/trace/hooks/mm.h' line='276' column='1' elf-symbol-id='__tracepoint_android_rvh_free_swap_slot'/>
+      <var-decl name='__tracepoint_android_rvh_get_swap_page' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_get_swap_page' visibility='default' filepath='include/trace/hooks/mm.h' line='282' column='1' elf-symbol-id='__tracepoint_android_rvh_get_swap_page'/>
       <var-decl name='__tracepoint_android_rvh_gic_v3_set_affinity' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_gic_v3_set_affinity' visibility='default' filepath='include/trace/hooks/gic_v3.h' line='22' column='1' elf-symbol-id='__tracepoint_android_rvh_gic_v3_set_affinity'/>
-      <var-decl name='__tracepoint_android_rvh_handle_pte_fault_end' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_handle_pte_fault_end' visibility='default' filepath='include/trace/hooks/mm.h' line='196' column='1' elf-symbol-id='__tracepoint_android_rvh_handle_pte_fault_end'/>
+      <var-decl name='__tracepoint_android_rvh_handle_pte_fault_end' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_handle_pte_fault_end' visibility='default' filepath='include/trace/hooks/mm.h' line='229' column='1' elf-symbol-id='__tracepoint_android_rvh_handle_pte_fault_end'/>
       <var-decl name='__tracepoint_android_rvh_iommu_setup_dma_ops' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_iommu_setup_dma_ops' visibility='default' filepath='include/trace/hooks/iommu.h' line='21' column='1' elf-symbol-id='__tracepoint_android_rvh_iommu_setup_dma_ops'/>
       <var-decl name='__tracepoint_android_rvh_irqs_disable' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_irqs_disable' visibility='default' filepath='include/trace/hooks/preemptirq.h' line='22' column='1' elf-symbol-id='__tracepoint_android_rvh_irqs_disable'/>
       <var-decl name='__tracepoint_android_rvh_irqs_enable' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_irqs_enable' visibility='default' filepath='include/trace/hooks/preemptirq.h' line='26' column='1' elf-symbol-id='__tracepoint_android_rvh_irqs_enable'/>
@@ -120882,21 +121480,23 @@
       <var-decl name='__tracepoint_android_rvh_v4l2subdev_set_frame_interval' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_v4l2subdev_set_frame_interval' visibility='default' filepath='include/trace/hooks/v4l2core.h' line='66' column='1' elf-symbol-id='__tracepoint_android_rvh_v4l2subdev_set_frame_interval'/>
       <var-decl name='__tracepoint_android_rvh_v4l2subdev_set_selection' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_v4l2subdev_set_selection' visibility='default' filepath='include/trace/hooks/v4l2core.h' line='56' column='1' elf-symbol-id='__tracepoint_android_rvh_v4l2subdev_set_selection'/>
       <var-decl name='__tracepoint_android_rvh_wake_up_new_task' type-id='4ca0c298' mangled-name='__tracepoint_android_rvh_wake_up_new_task' visibility='default' filepath='include/trace/hooks/sched.h' line='167' column='1' elf-symbol-id='__tracepoint_android_rvh_wake_up_new_task'/>
-      <var-decl name='__tracepoint_android_vh_account_swap_pages' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_account_swap_pages' visibility='default' filepath='include/trace/hooks/mm.h' line='263' column='1' elf-symbol-id='__tracepoint_android_vh_account_swap_pages'/>
+      <var-decl name='__tracepoint_android_vh___cgroup_throttle_swaprate' type-id='4ca0c298' mangled-name='__tracepoint_android_vh___cgroup_throttle_swaprate' visibility='default' filepath='include/trace/hooks/mm.h' line='296' column='1' elf-symbol-id='__tracepoint_android_vh___cgroup_throttle_swaprate'/>
+      <var-decl name='__tracepoint_android_vh_account_swap_pages' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_account_swap_pages' visibility='default' filepath='include/trace/hooks/mm.h' line='308' column='1' elf-symbol-id='__tracepoint_android_vh_account_swap_pages'/>
       <var-decl name='__tracepoint_android_vh_account_task_time' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_account_task_time' visibility='default' filepath='include/trace/hooks/sched.h' line='312' column='1' elf-symbol-id='__tracepoint_android_vh_account_task_time'/>
-      <var-decl name='__tracepoint_android_vh_add_page_to_lrulist' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_add_page_to_lrulist' visibility='default' filepath='include/trace/hooks/mm.h' line='166' column='1' elf-symbol-id='__tracepoint_android_vh_add_page_to_lrulist'/>
+      <var-decl name='__tracepoint_android_vh_add_page_to_lrulist' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_add_page_to_lrulist' visibility='default' filepath='include/trace/hooks/mm.h' line='174' column='1' elf-symbol-id='__tracepoint_android_vh_add_page_to_lrulist'/>
+      <var-decl name='__tracepoint_android_vh_add_to_avail_list' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_add_to_avail_list' visibility='default' filepath='include/trace/hooks/mm.h' line='290' column='1' elf-symbol-id='__tracepoint_android_vh_add_to_avail_list'/>
       <var-decl name='__tracepoint_android_vh_aes_decrypt' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_aes_decrypt' visibility='default' filepath='include/trace/hooks/fips140.h' line='46' column='1' elf-symbol-id='__tracepoint_android_vh_aes_decrypt'/>
       <var-decl name='__tracepoint_android_vh_aes_encrypt' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_aes_encrypt' visibility='default' filepath='include/trace/hooks/fips140.h' line='39' column='1' elf-symbol-id='__tracepoint_android_vh_aes_encrypt'/>
       <var-decl name='__tracepoint_android_vh_aes_expandkey' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_aes_expandkey' visibility='default' filepath='include/trace/hooks/fips140.h' line='32' column='1' elf-symbol-id='__tracepoint_android_vh_aes_expandkey'/>
-      <var-decl name='__tracepoint_android_vh_alloc_pages_failure_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_alloc_pages_failure_bypass' visibility='default' filepath='include/trace/hooks/mm.h' line='294' column='1' elf-symbol-id='__tracepoint_android_vh_alloc_pages_failure_bypass'/>
-      <var-decl name='__tracepoint_android_vh_alloc_pages_reclaim_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_alloc_pages_reclaim_bypass' visibility='default' filepath='include/trace/hooks/mm.h' line='290' column='1' elf-symbol-id='__tracepoint_android_vh_alloc_pages_reclaim_bypass'/>
+      <var-decl name='__tracepoint_android_vh_alloc_pages_failure_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_alloc_pages_failure_bypass' visibility='default' filepath='include/trace/hooks/mm.h' line='342' column='1' elf-symbol-id='__tracepoint_android_vh_alloc_pages_failure_bypass'/>
+      <var-decl name='__tracepoint_android_vh_alloc_pages_reclaim_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_alloc_pages_reclaim_bypass' visibility='default' filepath='include/trace/hooks/mm.h' line='338' column='1' elf-symbol-id='__tracepoint_android_vh_alloc_pages_reclaim_bypass'/>
       <var-decl name='__tracepoint_android_vh_alloc_pages_slowpath_begin' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_alloc_pages_slowpath_begin' visibility='default' filepath='include/trace/hooks/mm.h' line='101' column='1' elf-symbol-id='__tracepoint_android_vh_alloc_pages_slowpath_begin'/>
       <var-decl name='__tracepoint_android_vh_alloc_pages_slowpath_end' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_alloc_pages_slowpath_end' visibility='default' filepath='include/trace/hooks/mm.h' line='104' column='1' elf-symbol-id='__tracepoint_android_vh_alloc_pages_slowpath_end'/>
-      <var-decl name='__tracepoint_android_vh_alloc_si' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_alloc_si' visibility='default' filepath='include/trace/hooks/mm.h' line='278' column='1' elf-symbol-id='__tracepoint_android_vh_alloc_si'/>
-      <var-decl name='__tracepoint_android_vh_alloc_swap_slot_cache' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_alloc_swap_slot_cache' visibility='default' filepath='include/trace/hooks/mm.h' line='240' column='1' elf-symbol-id='__tracepoint_android_vh_alloc_swap_slot_cache'/>
+      <var-decl name='__tracepoint_android_vh_alloc_si' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_alloc_si' visibility='default' filepath='include/trace/hooks/mm.h' line='326' column='1' elf-symbol-id='__tracepoint_android_vh_alloc_si'/>
+      <var-decl name='__tracepoint_android_vh_alloc_swap_slot_cache' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_alloc_swap_slot_cache' visibility='default' filepath='include/trace/hooks/mm.h' line='273' column='1' elf-symbol-id='__tracepoint_android_vh_alloc_swap_slot_cache'/>
       <var-decl name='__tracepoint_android_vh_allow_domain_state' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_allow_domain_state' visibility='default' filepath='include/trace/hooks/pm_domain.h' line='20' column='1' elf-symbol-id='__tracepoint_android_vh_allow_domain_state'/>
       <var-decl name='__tracepoint_android_vh_alter_futex_plist_add' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_alter_futex_plist_add' visibility='default' filepath='include/trace/hooks/futex.h' line='19' column='1' elf-symbol-id='__tracepoint_android_vh_alter_futex_plist_add'/>
-      <var-decl name='__tracepoint_android_vh_alter_mutex_list_add' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_alter_mutex_list_add' visibility='default' filepath='include/trace/hooks/dtask.h' line='59' column='1' elf-symbol-id='__tracepoint_android_vh_alter_mutex_list_add'/>
+      <var-decl name='__tracepoint_android_vh_alter_mutex_list_add' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_alter_mutex_list_add' visibility='default' filepath='include/trace/hooks/dtask.h' line='77' column='1' elf-symbol-id='__tracepoint_android_vh_alter_mutex_list_add'/>
       <var-decl name='__tracepoint_android_vh_alter_rwsem_list_add' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_alter_rwsem_list_add' visibility='default' filepath='include/trace/hooks/rwsem.h' line='29' column='1' elf-symbol-id='__tracepoint_android_vh_alter_rwsem_list_add'/>
       <var-decl name='__tracepoint_android_vh_arch_set_freq_scale' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_arch_set_freq_scale' visibility='default' filepath='include/trace/hooks/topology.h' line='14' column='1' elf-symbol-id='__tracepoint_android_vh_arch_set_freq_scale'/>
       <var-decl name='__tracepoint_android_vh_binder_alloc_new_buf_locked' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_binder_alloc_new_buf_locked' visibility='default' filepath='include/trace/hooks/binder.h' line='60' column='1' elf-symbol-id='__tracepoint_android_vh_binder_alloc_new_buf_locked'/>
@@ -120931,16 +121531,18 @@
       <var-decl name='__tracepoint_android_vh_check_page_look_around_ref' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_check_page_look_around_ref' visibility='default' filepath='include/trace/hooks/vmscan.h' line='53' column='1' elf-symbol-id='__tracepoint_android_vh_check_page_look_around_ref'/>
       <var-decl name='__tracepoint_android_vh_check_uninterruptible_tasks' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_check_uninterruptible_tasks' visibility='default' filepath='include/trace/hooks/hung_task.h' line='13' column='1' elf-symbol-id='__tracepoint_android_vh_check_uninterruptible_tasks'/>
       <var-decl name='__tracepoint_android_vh_check_uninterruptible_tasks_dn' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_check_uninterruptible_tasks_dn' visibility='default' filepath='include/trace/hooks/hung_task.h' line='18' column='1' elf-symbol-id='__tracepoint_android_vh_check_uninterruptible_tasks_dn'/>
+      <var-decl name='__tracepoint_android_vh_cleanup_old_buffers_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_cleanup_old_buffers_bypass' visibility='default' filepath='include/trace/hooks/mm.h' line='132' column='1' elf-symbol-id='__tracepoint_android_vh_cleanup_old_buffers_bypass'/>
       <var-decl name='__tracepoint_android_vh_clear_mask_adjust' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_clear_mask_adjust' visibility='default' filepath='include/trace/hooks/v4l2core.h' line='37' column='1' elf-symbol-id='__tracepoint_android_vh_clear_mask_adjust'/>
       <var-decl name='__tracepoint_android_vh_clear_reserved_fmt_fields' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_clear_reserved_fmt_fields' visibility='default' filepath='include/trace/hooks/v4l2core.h' line='29' column='1' elf-symbol-id='__tracepoint_android_vh_clear_reserved_fmt_fields'/>
       <var-decl name='__tracepoint_android_vh_cma_alloc_finish' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_cma_alloc_finish' visibility='default' filepath='include/trace/hooks/mm.h' line='61' column='1' elf-symbol-id='__tracepoint_android_vh_cma_alloc_finish'/>
       <var-decl name='__tracepoint_android_vh_cma_alloc_start' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_cma_alloc_start' visibility='default' filepath='include/trace/hooks/mm.h' line='58' column='1' elf-symbol-id='__tracepoint_android_vh_cma_alloc_start'/>
-      <var-decl name='__tracepoint_android_vh_cma_drain_all_pages_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_cma_drain_all_pages_bypass' visibility='default' filepath='include/trace/hooks/mm.h' line='184' column='1' elf-symbol-id='__tracepoint_android_vh_cma_drain_all_pages_bypass'/>
+      <var-decl name='__tracepoint_android_vh_cma_drain_all_pages_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_cma_drain_all_pages_bypass' visibility='default' filepath='include/trace/hooks/mm.h' line='192' column='1' elf-symbol-id='__tracepoint_android_vh_cma_drain_all_pages_bypass'/>
       <var-decl name='__tracepoint_android_vh_commit_creds' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_commit_creds' visibility='default' filepath='include/trace/hooks/creds.h' line='23' column='1' elf-symbol-id='__tracepoint_android_vh_commit_creds'/>
-      <var-decl name='__tracepoint_android_vh_count_pswpin' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_count_pswpin' visibility='default' filepath='include/trace/hooks/mm.h' line='217' column='1' elf-symbol-id='__tracepoint_android_vh_count_pswpin'/>
-      <var-decl name='__tracepoint_android_vh_count_pswpout' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_count_pswpout' visibility='default' filepath='include/trace/hooks/mm.h' line='220' column='1' elf-symbol-id='__tracepoint_android_vh_count_pswpout'/>
-      <var-decl name='__tracepoint_android_vh_count_swpout_vm_event' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_count_swpout_vm_event' visibility='default' filepath='include/trace/hooks/mm.h' line='223' column='1' elf-symbol-id='__tracepoint_android_vh_count_swpout_vm_event'/>
-      <var-decl name='__tracepoint_android_vh_cow_user_page' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_cow_user_page' visibility='default' filepath='include/trace/hooks/mm.h' line='202' column='1' elf-symbol-id='__tracepoint_android_vh_cow_user_page'/>
+      <var-decl name='__tracepoint_android_vh_compact_finished' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_compact_finished' visibility='default' filepath='include/trace/hooks/mm.h' line='356' column='1' elf-symbol-id='__tracepoint_android_vh_compact_finished'/>
+      <var-decl name='__tracepoint_android_vh_count_pswpin' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_count_pswpin' visibility='default' filepath='include/trace/hooks/mm.h' line='250' column='1' elf-symbol-id='__tracepoint_android_vh_count_pswpin'/>
+      <var-decl name='__tracepoint_android_vh_count_pswpout' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_count_pswpout' visibility='default' filepath='include/trace/hooks/mm.h' line='253' column='1' elf-symbol-id='__tracepoint_android_vh_count_pswpout'/>
+      <var-decl name='__tracepoint_android_vh_count_swpout_vm_event' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_count_swpout_vm_event' visibility='default' filepath='include/trace/hooks/mm.h' line='256' column='1' elf-symbol-id='__tracepoint_android_vh_count_swpout_vm_event'/>
+      <var-decl name='__tracepoint_android_vh_cow_user_page' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_cow_user_page' visibility='default' filepath='include/trace/hooks/mm.h' line='235' column='1' elf-symbol-id='__tracepoint_android_vh_cow_user_page'/>
       <var-decl name='__tracepoint_android_vh_cpu_idle_enter' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_cpu_idle_enter' visibility='default' filepath='include/trace/hooks/cpuidle.h' line='20' column='1' elf-symbol-id='__tracepoint_android_vh_cpu_idle_enter'/>
       <var-decl name='__tracepoint_android_vh_cpu_idle_exit' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_cpu_idle_exit' visibility='default' filepath='include/trace/hooks/cpuidle.h' line='23' column='1' elf-symbol-id='__tracepoint_android_vh_cpu_idle_exit'/>
       <var-decl name='__tracepoint_android_vh_cpu_up' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_cpu_up' visibility='default' filepath='include/trace/hooks/cpu.h' line='13' column='1' elf-symbol-id='__tracepoint_android_vh_cpu_up'/>
@@ -120950,15 +121552,17 @@
       <var-decl name='__tracepoint_android_vh_cpufreq_target' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_cpufreq_target' visibility='default' filepath='include/trace/hooks/cpufreq.h' line='45' column='1' elf-symbol-id='__tracepoint_android_vh_cpufreq_target'/>
       <var-decl name='__tracepoint_android_vh_cpuidle_psci_enter' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_cpuidle_psci_enter' visibility='default' filepath='include/trace/hooks/cpuidle_psci.h' line='20' column='1' elf-symbol-id='__tracepoint_android_vh_cpuidle_psci_enter'/>
       <var-decl name='__tracepoint_android_vh_cpuidle_psci_exit' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_cpuidle_psci_exit' visibility='default' filepath='include/trace/hooks/cpuidle_psci.h' line='24' column='1' elf-symbol-id='__tracepoint_android_vh_cpuidle_psci_exit'/>
-      <var-decl name='__tracepoint_android_vh_del_page_from_lrulist' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_del_page_from_lrulist' visibility='default' filepath='include/trace/hooks/mm.h' line='169' column='1' elf-symbol-id='__tracepoint_android_vh_del_page_from_lrulist'/>
+      <var-decl name='__tracepoint_android_vh_del_from_avail_list' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_del_from_avail_list' visibility='default' filepath='include/trace/hooks/mm.h' line='293' column='1' elf-symbol-id='__tracepoint_android_vh_del_from_avail_list'/>
+      <var-decl name='__tracepoint_android_vh_del_page_from_lrulist' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_del_page_from_lrulist' visibility='default' filepath='include/trace/hooks/mm.h' line='177' column='1' elf-symbol-id='__tracepoint_android_vh_del_page_from_lrulist'/>
       <var-decl name='__tracepoint_android_vh_disable_thermal_cooling_stats' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_disable_thermal_cooling_stats' visibility='default' filepath='include/trace/hooks/thermal.h' line='28' column='1' elf-symbol-id='__tracepoint_android_vh_disable_thermal_cooling_stats'/>
+      <var-decl name='__tracepoint_android_vh_dm_bufio_shrink_scan_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_dm_bufio_shrink_scan_bypass' visibility='default' filepath='include/trace/hooks/mm.h' line='129' column='1' elf-symbol-id='__tracepoint_android_vh_dm_bufio_shrink_scan_bypass'/>
       <var-decl name='__tracepoint_android_vh_do_futex' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_do_futex' visibility='default' filepath='include/trace/hooks/futex.h' line='29' column='1' elf-symbol-id='__tracepoint_android_vh_do_futex'/>
-      <var-decl name='__tracepoint_android_vh_do_page_trylock' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_do_page_trylock' visibility='default' filepath='include/trace/hooks/mm.h' line='153' column='1' elf-symbol-id='__tracepoint_android_vh_do_page_trylock'/>
+      <var-decl name='__tracepoint_android_vh_do_page_trylock' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_do_page_trylock' visibility='default' filepath='include/trace/hooks/mm.h' line='161' column='1' elf-symbol-id='__tracepoint_android_vh_do_page_trylock'/>
       <var-decl name='__tracepoint_android_vh_do_send_sig_info' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_do_send_sig_info' visibility='default' filepath='include/trace/hooks/signal.h' line='17' column='1' elf-symbol-id='__tracepoint_android_vh_do_send_sig_info'/>
-      <var-decl name='__tracepoint_android_vh_do_traversal_lruvec' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_do_traversal_lruvec' visibility='default' filepath='include/trace/hooks/mm.h' line='175' column='1' elf-symbol-id='__tracepoint_android_vh_do_traversal_lruvec'/>
+      <var-decl name='__tracepoint_android_vh_do_traversal_lruvec' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_do_traversal_lruvec' visibility='default' filepath='include/trace/hooks/mm.h' line='183' column='1' elf-symbol-id='__tracepoint_android_vh_do_traversal_lruvec'/>
       <var-decl name='__tracepoint_android_vh_do_wake_up_sync' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_do_wake_up_sync' visibility='default' filepath='include/trace/hooks/sched.h' line='276' column='1' elf-symbol-id='__tracepoint_android_vh_do_wake_up_sync'/>
-      <var-decl name='__tracepoint_android_vh_drain_all_pages_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_drain_all_pages_bypass' visibility='default' filepath='include/trace/hooks/mm.h' line='157' column='1' elf-symbol-id='__tracepoint_android_vh_drain_all_pages_bypass'/>
-      <var-decl name='__tracepoint_android_vh_drain_slots_cache_cpu' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_drain_slots_cache_cpu' visibility='default' filepath='include/trace/hooks/mm.h' line='233' column='1' elf-symbol-id='__tracepoint_android_vh_drain_slots_cache_cpu'/>
+      <var-decl name='__tracepoint_android_vh_drain_all_pages_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_drain_all_pages_bypass' visibility='default' filepath='include/trace/hooks/mm.h' line='165' column='1' elf-symbol-id='__tracepoint_android_vh_drain_all_pages_bypass'/>
+      <var-decl name='__tracepoint_android_vh_drain_slots_cache_cpu' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_drain_slots_cache_cpu' visibility='default' filepath='include/trace/hooks/mm.h' line='266' column='1' elf-symbol-id='__tracepoint_android_vh_drain_slots_cache_cpu'/>
       <var-decl name='__tracepoint_android_vh_dump_throttled_rt_tasks' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_dump_throttled_rt_tasks' visibility='default' filepath='include/trace/hooks/sched.h' line='91' column='1' elf-symbol-id='__tracepoint_android_vh_dump_throttled_rt_tasks'/>
       <var-decl name='__tracepoint_android_vh_dup_task_struct' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_dup_task_struct' visibility='default' filepath='include/trace/hooks/sched.h' line='374' column='1' elf-symbol-id='__tracepoint_android_vh_dup_task_struct'/>
       <var-decl name='__tracepoint_android_vh_em_cpu_energy' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_em_cpu_energy' visibility='default' filepath='include/trace/hooks/sched.h' line='249' column='1' elf-symbol-id='__tracepoint_android_vh_em_cpu_energy'/>
@@ -120971,9 +121575,10 @@
       <var-decl name='__tracepoint_android_vh_filemap_fault_get_page' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_filemap_fault_get_page' visibility='default' filepath='include/trace/hooks/mm.h' line='75' column='1' elf-symbol-id='__tracepoint_android_vh_filemap_fault_get_page'/>
       <var-decl name='__tracepoint_android_vh_fill_ext_fmtdesc' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_fill_ext_fmtdesc' visibility='default' filepath='include/trace/hooks/v4l2core.h' line='33' column='1' elf-symbol-id='__tracepoint_android_vh_fill_ext_fmtdesc'/>
       <var-decl name='__tracepoint_android_vh_finish_update_load_avg_se' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_finish_update_load_avg_se' visibility='default' filepath='include/trace/hooks/sched.h' line='370' column='1' elf-symbol-id='__tracepoint_android_vh_finish_update_load_avg_se'/>
-      <var-decl name='__tracepoint_android_vh_free_pages' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_free_pages' visibility='default' filepath='include/trace/hooks/mm.h' line='281' column='1' elf-symbol-id='__tracepoint_android_vh_free_pages'/>
-      <var-decl name='__tracepoint_android_vh_free_swap_slot' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_free_swap_slot' visibility='default' filepath='include/trace/hooks/mm.h' line='246' column='1' elf-symbol-id='__tracepoint_android_vh_free_swap_slot'/>
+      <var-decl name='__tracepoint_android_vh_free_pages' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_free_pages' visibility='default' filepath='include/trace/hooks/mm.h' line='329' column='1' elf-symbol-id='__tracepoint_android_vh_free_pages'/>
+      <var-decl name='__tracepoint_android_vh_free_swap_slot' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_free_swap_slot' visibility='default' filepath='include/trace/hooks/mm.h' line='279' column='1' elf-symbol-id='__tracepoint_android_vh_free_swap_slot'/>
       <var-decl name='__tracepoint_android_vh_free_task' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_free_task' visibility='default' filepath='include/trace/hooks/sched.h' line='332' column='1' elf-symbol-id='__tracepoint_android_vh_free_task'/>
+      <var-decl name='__tracepoint_android_vh_free_unref_page_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_free_unref_page_bypass' visibility='default' filepath='include/trace/hooks/mm.h' line='195' column='1' elf-symbol-id='__tracepoint_android_vh_free_unref_page_bypass'/>
       <var-decl name='__tracepoint_android_vh_freq_qos_add_request' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_freq_qos_add_request' visibility='default' filepath='include/trace/hooks/power.h' line='34' column='1' elf-symbol-id='__tracepoint_android_vh_freq_qos_add_request'/>
       <var-decl name='__tracepoint_android_vh_freq_qos_remove_request' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_freq_qos_remove_request' visibility='default' filepath='include/trace/hooks/power.h' line='43' column='1' elf-symbol-id='__tracepoint_android_vh_freq_qos_remove_request'/>
       <var-decl name='__tracepoint_android_vh_freq_qos_update_request' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_freq_qos_update_request' visibility='default' filepath='include/trace/hooks/power.h' line='39' column='1' elf-symbol-id='__tracepoint_android_vh_freq_qos_update_request'/>
@@ -120990,15 +121595,15 @@
       <var-decl name='__tracepoint_android_vh_futex_wake_traverse_plist' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_futex_wake_traverse_plist' visibility='default' filepath='include/trace/hooks/futex.h' line='45' column='1' elf-symbol-id='__tracepoint_android_vh_futex_wake_traverse_plist'/>
       <var-decl name='__tracepoint_android_vh_futex_wake_up_q_finish' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_futex_wake_up_q_finish' visibility='default' filepath='include/trace/hooks/futex.h' line='55' column='1' elf-symbol-id='__tracepoint_android_vh_futex_wake_up_q_finish'/>
       <var-decl name='__tracepoint_android_vh_get_from_fragment_pool' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_get_from_fragment_pool' visibility='default' filepath='include/trace/hooks/mm.h' line='87' column='1' elf-symbol-id='__tracepoint_android_vh_get_from_fragment_pool'/>
-      <var-decl name='__tracepoint_android_vh_get_swap_page' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_get_swap_page' visibility='default' filepath='include/trace/hooks/mm.h' line='253' column='1' elf-symbol-id='__tracepoint_android_vh_get_swap_page'/>
+      <var-decl name='__tracepoint_android_vh_get_swap_page' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_get_swap_page' visibility='default' filepath='include/trace/hooks/mm.h' line='286' column='1' elf-symbol-id='__tracepoint_android_vh_get_swap_page'/>
       <var-decl name='__tracepoint_android_vh_gic_resume' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_gic_resume' visibility='default' filepath='include/trace/hooks/gic.h' line='15' column='1' elf-symbol-id='__tracepoint_android_vh_gic_resume'/>
       <var-decl name='__tracepoint_android_vh_gpio_block_read' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_gpio_block_read' visibility='default' filepath='include/trace/hooks/gpiolib.h' line='15' column='1' elf-symbol-id='__tracepoint_android_vh_gpio_block_read'/>
       <var-decl name='__tracepoint_android_vh_handle_failed_page_trylock' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_handle_failed_page_trylock' visibility='default' filepath='include/trace/hooks/vmscan.h' line='34' column='1' elf-symbol-id='__tracepoint_android_vh_handle_failed_page_trylock'/>
-      <var-decl name='__tracepoint_android_vh_handle_pte_fault_end' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_handle_pte_fault_end' visibility='default' filepath='include/trace/hooks/mm.h' line='199' column='1' elf-symbol-id='__tracepoint_android_vh_handle_pte_fault_end'/>
+      <var-decl name='__tracepoint_android_vh_handle_pte_fault_end' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_handle_pte_fault_end' visibility='default' filepath='include/trace/hooks/mm.h' line='232' column='1' elf-symbol-id='__tracepoint_android_vh_handle_pte_fault_end'/>
       <var-decl name='__tracepoint_android_vh_handle_tlb_conf' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_handle_tlb_conf' visibility='default' filepath='include/trace/hooks/fault.h' line='37' column='1' elf-symbol-id='__tracepoint_android_vh_handle_tlb_conf'/>
       <var-decl name='__tracepoint_android_vh_inactive_is_low' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_inactive_is_low' visibility='default' filepath='include/trace/hooks/vmscan.h' line='46' column='1' elf-symbol-id='__tracepoint_android_vh_inactive_is_low'/>
       <var-decl name='__tracepoint_android_vh_include_reserved_zone' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_include_reserved_zone' visibility='default' filepath='include/trace/hooks/mm.h' line='94' column='1' elf-symbol-id='__tracepoint_android_vh_include_reserved_zone'/>
-      <var-decl name='__tracepoint_android_vh_init_swap_info_struct' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_init_swap_info_struct' visibility='default' filepath='include/trace/hooks/mm.h' line='269' column='1' elf-symbol-id='__tracepoint_android_vh_init_swap_info_struct'/>
+      <var-decl name='__tracepoint_android_vh_init_swap_info_struct' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_init_swap_info_struct' visibility='default' filepath='include/trace/hooks/mm.h' line='317' column='1' elf-symbol-id='__tracepoint_android_vh_init_swap_info_struct'/>
       <var-decl name='__tracepoint_android_vh_iommu_alloc_iova' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_iommu_alloc_iova' visibility='default' filepath='include/trace/hooks/iommu.h' line='29' column='1' elf-symbol-id='__tracepoint_android_vh_iommu_alloc_iova'/>
       <var-decl name='__tracepoint_android_vh_iommu_free_iova' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_iommu_free_iova' visibility='default' filepath='include/trace/hooks/iommu.h' line='38' column='1' elf-symbol-id='__tracepoint_android_vh_iommu_free_iova'/>
       <var-decl name='__tracepoint_android_vh_iommu_iovad_alloc_iova' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_iommu_iovad_alloc_iova' visibility='default' filepath='include/trace/hooks/iommu.h' line='34' column='1' elf-symbol-id='__tracepoint_android_vh_iommu_iovad_alloc_iova'/>
@@ -121011,67 +121616,78 @@
       <var-decl name='__tracepoint_android_vh_jiffies_update' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_jiffies_update' visibility='default' filepath='include/trace/hooks/sched.h' line='96' column='1' elf-symbol-id='__tracepoint_android_vh_jiffies_update'/>
       <var-decl name='__tracepoint_android_vh_kfree_skb' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_kfree_skb' visibility='default' filepath='include/trace/hooks/net.h' line='27' column='1' elf-symbol-id='__tracepoint_android_vh_kfree_skb'/>
       <var-decl name='__tracepoint_android_vh_killed_process' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_killed_process' visibility='default' filepath='include/trace/hooks/signal.h' line='23' column='1' elf-symbol-id='__tracepoint_android_vh_killed_process'/>
-      <var-decl name='__tracepoint_android_vh_kmalloc_slab' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_kmalloc_slab' visibility='default' filepath='include/trace/hooks/mm.h' line='144' column='1' elf-symbol-id='__tracepoint_android_vh_kmalloc_slab'/>
+      <var-decl name='__tracepoint_android_vh_kmalloc_slab' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_kmalloc_slab' visibility='default' filepath='include/trace/hooks/mm.h' line='152' column='1' elf-symbol-id='__tracepoint_android_vh_kmalloc_slab'/>
+      <var-decl name='__tracepoint_android_vh_kvmalloc_node_use_vmalloc' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_kvmalloc_node_use_vmalloc' visibility='default' filepath='include/trace/hooks/mm.h' line='198' column='1' elf-symbol-id='__tracepoint_android_vh_kvmalloc_node_use_vmalloc'/>
       <var-decl name='__tracepoint_android_vh_logbuf' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_logbuf' visibility='default' filepath='include/trace/hooks/logbuf.h' line='21' column='1' elf-symbol-id='__tracepoint_android_vh_logbuf'/>
       <var-decl name='__tracepoint_android_vh_logbuf_pr_cont' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_logbuf_pr_cont' visibility='default' filepath='include/trace/hooks/logbuf.h' line='25' column='1' elf-symbol-id='__tracepoint_android_vh_logbuf_pr_cont'/>
-      <var-decl name='__tracepoint_android_vh_look_around' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_look_around' visibility='default' filepath='include/trace/hooks/mm.h' line='304' column='1' elf-symbol-id='__tracepoint_android_vh_look_around'/>
-      <var-decl name='__tracepoint_android_vh_look_around_migrate_page' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_look_around_migrate_page' visibility='default' filepath='include/trace/hooks/mm.h' line='301' column='1' elf-symbol-id='__tracepoint_android_vh_look_around_migrate_page'/>
-      <var-decl name='__tracepoint_android_vh_madvise_cold_or_pageout' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_madvise_cold_or_pageout' visibility='default' filepath='include/trace/hooks/mm.h' line='257' column='1' elf-symbol-id='__tracepoint_android_vh_madvise_cold_or_pageout'/>
+      <var-decl name='__tracepoint_android_vh_look_around' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_look_around' visibility='default' filepath='include/trace/hooks/mm.h' line='352' column='1' elf-symbol-id='__tracepoint_android_vh_look_around'/>
+      <var-decl name='__tracepoint_android_vh_look_around_migrate_page' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_look_around_migrate_page' visibility='default' filepath='include/trace/hooks/mm.h' line='349' column='1' elf-symbol-id='__tracepoint_android_vh_look_around_migrate_page'/>
+      <var-decl name='__tracepoint_android_vh_madvise_cold_or_pageout' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_madvise_cold_or_pageout' visibility='default' filepath='include/trace/hooks/mm.h' line='299' column='1' elf-symbol-id='__tracepoint_android_vh_madvise_cold_or_pageout'/>
+      <var-decl name='__tracepoint_android_vh_madvise_cold_or_pageout_abort' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_madvise_cold_or_pageout_abort' visibility='default' filepath='include/trace/hooks/mm.h' line='359' column='1' elf-symbol-id='__tracepoint_android_vh_madvise_cold_or_pageout_abort'/>
       <var-decl name='__tracepoint_android_vh_map_util_freq' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_map_util_freq' visibility='default' filepath='include/trace/hooks/sched.h' line='243' column='1' elf-symbol-id='__tracepoint_android_vh_map_util_freq'/>
-      <var-decl name='__tracepoint_android_vh_mark_page_accessed' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mark_page_accessed' visibility='default' filepath='include/trace/hooks/mm.h' line='181' column='1' elf-symbol-id='__tracepoint_android_vh_mark_page_accessed'/>
+      <var-decl name='__tracepoint_android_vh_mark_page_accessed' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mark_page_accessed' visibility='default' filepath='include/trace/hooks/mm.h' line='189' column='1' elf-symbol-id='__tracepoint_android_vh_mark_page_accessed'/>
       <var-decl name='__tracepoint_android_vh_media_device_setup_link' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_media_device_setup_link' visibility='default' filepath='include/trace/hooks/v4l2mc.h' line='22' column='1' elf-symbol-id='__tracepoint_android_vh_media_device_setup_link'/>
-      <var-decl name='__tracepoint_android_vh_mem_cgroup_alloc' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mem_cgroup_alloc' visibility='default' filepath='include/trace/hooks/mm.h' line='129' column='1' elf-symbol-id='__tracepoint_android_vh_mem_cgroup_alloc'/>
-      <var-decl name='__tracepoint_android_vh_mem_cgroup_css_offline' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mem_cgroup_css_offline' visibility='default' filepath='include/trace/hooks/mm.h' line='141' column='1' elf-symbol-id='__tracepoint_android_vh_mem_cgroup_css_offline'/>
-      <var-decl name='__tracepoint_android_vh_mem_cgroup_css_online' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mem_cgroup_css_online' visibility='default' filepath='include/trace/hooks/mm.h' line='138' column='1' elf-symbol-id='__tracepoint_android_vh_mem_cgroup_css_online'/>
-      <var-decl name='__tracepoint_android_vh_mem_cgroup_free' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mem_cgroup_free' visibility='default' filepath='include/trace/hooks/mm.h' line='132' column='1' elf-symbol-id='__tracepoint_android_vh_mem_cgroup_free'/>
-      <var-decl name='__tracepoint_android_vh_mem_cgroup_id_remove' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mem_cgroup_id_remove' visibility='default' filepath='include/trace/hooks/mm.h' line='135' column='1' elf-symbol-id='__tracepoint_android_vh_mem_cgroup_id_remove'/>
+      <var-decl name='__tracepoint_android_vh_mem_cgroup_alloc' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mem_cgroup_alloc' visibility='default' filepath='include/trace/hooks/mm.h' line='137' column='1' elf-symbol-id='__tracepoint_android_vh_mem_cgroup_alloc'/>
+      <var-decl name='__tracepoint_android_vh_mem_cgroup_css_offline' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mem_cgroup_css_offline' visibility='default' filepath='include/trace/hooks/mm.h' line='149' column='1' elf-symbol-id='__tracepoint_android_vh_mem_cgroup_css_offline'/>
+      <var-decl name='__tracepoint_android_vh_mem_cgroup_css_online' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mem_cgroup_css_online' visibility='default' filepath='include/trace/hooks/mm.h' line='146' column='1' elf-symbol-id='__tracepoint_android_vh_mem_cgroup_css_online'/>
+      <var-decl name='__tracepoint_android_vh_mem_cgroup_free' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mem_cgroup_free' visibility='default' filepath='include/trace/hooks/mm.h' line='140' column='1' elf-symbol-id='__tracepoint_android_vh_mem_cgroup_free'/>
+      <var-decl name='__tracepoint_android_vh_mem_cgroup_id_remove' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mem_cgroup_id_remove' visibility='default' filepath='include/trace/hooks/mm.h' line='143' column='1' elf-symbol-id='__tracepoint_android_vh_mem_cgroup_id_remove'/>
       <var-decl name='__tracepoint_android_vh_meminfo_proc_show' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_meminfo_proc_show' visibility='default' filepath='include/trace/hooks/mm.h' line='81' column='1' elf-symbol-id='__tracepoint_android_vh_meminfo_proc_show'/>
-      <var-decl name='__tracepoint_android_vh_migrate_page_states' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_migrate_page_states' visibility='default' filepath='include/trace/hooks/mm.h' line='211' column='1' elf-symbol-id='__tracepoint_android_vh_migrate_page_states'/>
+      <var-decl name='__tracepoint_android_vh_migrate_page_states' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_migrate_page_states' visibility='default' filepath='include/trace/hooks/mm.h' line='244' column='1' elf-symbol-id='__tracepoint_android_vh_migrate_page_states'/>
       <var-decl name='__tracepoint_android_vh_mm_dirty_limits' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mm_dirty_limits' visibility='default' filepath='include/trace/hooks/mm.h' line='108' column='1' elf-symbol-id='__tracepoint_android_vh_mm_dirty_limits'/>
-      <var-decl name='__tracepoint_android_vh_mmap_region' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mmap_region' visibility='default' filepath='include/trace/hooks/mm.h' line='147' column='1' elf-symbol-id='__tracepoint_android_vh_mmap_region'/>
+      <var-decl name='__tracepoint_android_vh_mmap_region' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mmap_region' visibility='default' filepath='include/trace/hooks/mm.h' line='155' column='1' elf-symbol-id='__tracepoint_android_vh_mmap_region'/>
       <var-decl name='__tracepoint_android_vh_mmc_attach_sd' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mmc_attach_sd' visibility='default' filepath='include/trace/hooks/mmc_core.h' line='39' column='1' elf-symbol-id='__tracepoint_android_vh_mmc_attach_sd'/>
       <var-decl name='__tracepoint_android_vh_mmc_blk_mq_rw_recovery' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mmc_blk_mq_rw_recovery' visibility='default' filepath='include/trace/hooks/mmc_core.h' line='33' column='1' elf-symbol-id='__tracepoint_android_vh_mmc_blk_mq_rw_recovery'/>
       <var-decl name='__tracepoint_android_vh_mmc_blk_reset' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mmc_blk_reset' visibility='default' filepath='include/trace/hooks/mmc_core.h' line='30' column='1' elf-symbol-id='__tracepoint_android_vh_mmc_blk_reset'/>
       <var-decl name='__tracepoint_android_vh_mmc_gpio_cd_irqt' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mmc_gpio_cd_irqt' visibility='default' filepath='include/trace/hooks/mmc_core.h' line='45' column='1' elf-symbol-id='__tracepoint_android_vh_mmc_gpio_cd_irqt'/>
       <var-decl name='__tracepoint_android_vh_mmput' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mmput' visibility='default' filepath='include/trace/hooks/sched.h' line='394' column='1' elf-symbol-id='__tracepoint_android_vh_mmput'/>
-      <var-decl name='__tracepoint_android_vh_mutex_unlock_slowpath' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mutex_unlock_slowpath' visibility='default' filepath='include/trace/hooks/dtask.h' line='65' column='1' elf-symbol-id='__tracepoint_android_vh_mutex_unlock_slowpath'/>
-      <var-decl name='__tracepoint_android_vh_mutex_unlock_slowpath_end' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mutex_unlock_slowpath_end' visibility='default' filepath='include/trace/hooks/dtask.h' line='68' column='1' elf-symbol-id='__tracepoint_android_vh_mutex_unlock_slowpath_end'/>
+      <var-decl name='__tracepoint_android_vh_mutex_can_spin_on_owner' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mutex_can_spin_on_owner' visibility='default' filepath='include/trace/hooks/dtask.h' line='41' column='1' elf-symbol-id='__tracepoint_android_vh_mutex_can_spin_on_owner'/>
+      <var-decl name='__tracepoint_android_vh_mutex_opt_spin_finish' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mutex_opt_spin_finish' visibility='default' filepath='include/trace/hooks/dtask.h' line='38' column='1' elf-symbol-id='__tracepoint_android_vh_mutex_opt_spin_finish'/>
+      <var-decl name='__tracepoint_android_vh_mutex_opt_spin_start' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mutex_opt_spin_start' visibility='default' filepath='include/trace/hooks/dtask.h' line='35' column='1' elf-symbol-id='__tracepoint_android_vh_mutex_opt_spin_start'/>
+      <var-decl name='__tracepoint_android_vh_mutex_unlock_slowpath' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mutex_unlock_slowpath' visibility='default' filepath='include/trace/hooks/dtask.h' line='83' column='1' elf-symbol-id='__tracepoint_android_vh_mutex_unlock_slowpath'/>
+      <var-decl name='__tracepoint_android_vh_mutex_unlock_slowpath_end' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mutex_unlock_slowpath_end' visibility='default' filepath='include/trace/hooks/dtask.h' line='86' column='1' elf-symbol-id='__tracepoint_android_vh_mutex_unlock_slowpath_end'/>
       <var-decl name='__tracepoint_android_vh_mutex_wait_finish' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mutex_wait_finish' visibility='default' filepath='include/trace/hooks/dtask.h' line='32' column='1' elf-symbol-id='__tracepoint_android_vh_mutex_wait_finish'/>
       <var-decl name='__tracepoint_android_vh_mutex_wait_start' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_mutex_wait_start' visibility='default' filepath='include/trace/hooks/dtask.h' line='29' column='1' elf-symbol-id='__tracepoint_android_vh_mutex_wait_start'/>
       <var-decl name='__tracepoint_android_vh_of_i2c_get_board_info' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_of_i2c_get_board_info' visibility='default' filepath='include/trace/hooks/i2c.h' line='13' column='1' elf-symbol-id='__tracepoint_android_vh_of_i2c_get_board_info'/>
       <var-decl name='__tracepoint_android_vh_oom_check_panic' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_oom_check_panic' visibility='default' filepath='include/trace/hooks/mm.h' line='114' column='1' elf-symbol-id='__tracepoint_android_vh_oom_check_panic'/>
       <var-decl name='__tracepoint_android_vh_override_creds' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_override_creds' visibility='default' filepath='include/trace/hooks/creds.h' line='31' column='1' elf-symbol-id='__tracepoint_android_vh_override_creds'/>
-      <var-decl name='__tracepoint_android_vh_page_isolated_for_reclaim' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_page_isolated_for_reclaim' visibility='default' filepath='include/trace/hooks/mm.h' line='260' column='1' elf-symbol-id='__tracepoint_android_vh_page_isolated_for_reclaim'/>
+      <var-decl name='__tracepoint_android_vh_page_isolated_for_reclaim' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_page_isolated_for_reclaim' visibility='default' filepath='include/trace/hooks/mm.h' line='302' column='1' elf-symbol-id='__tracepoint_android_vh_page_isolated_for_reclaim'/>
       <var-decl name='__tracepoint_android_vh_page_referenced_check_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_page_referenced_check_bypass' visibility='default' filepath='include/trace/hooks/vmscan.h' line='28' column='1' elf-symbol-id='__tracepoint_android_vh_page_referenced_check_bypass'/>
-      <var-decl name='__tracepoint_android_vh_page_referenced_one_end' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_page_referenced_one_end' visibility='default' filepath='include/trace/hooks/mm.h' line='214' column='1' elf-symbol-id='__tracepoint_android_vh_page_referenced_one_end'/>
-      <var-decl name='__tracepoint_android_vh_page_should_be_protected' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_page_should_be_protected' visibility='default' filepath='include/trace/hooks/mm.h' line='178' column='1' elf-symbol-id='__tracepoint_android_vh_page_should_be_protected'/>
+      <var-decl name='__tracepoint_android_vh_page_referenced_one_end' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_page_referenced_one_end' visibility='default' filepath='include/trace/hooks/mm.h' line='247' column='1' elf-symbol-id='__tracepoint_android_vh_page_referenced_one_end'/>
+      <var-decl name='__tracepoint_android_vh_page_should_be_protected' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_page_should_be_protected' visibility='default' filepath='include/trace/hooks/mm.h' line='186' column='1' elf-symbol-id='__tracepoint_android_vh_page_should_be_protected'/>
       <var-decl name='__tracepoint_android_vh_page_trylock_clear' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_page_trylock_clear' visibility='default' filepath='include/trace/hooks/vmscan.h' line='40' column='1' elf-symbol-id='__tracepoint_android_vh_page_trylock_clear'/>
       <var-decl name='__tracepoint_android_vh_page_trylock_get_result' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_page_trylock_get_result' visibility='default' filepath='include/trace/hooks/vmscan.h' line='31' column='1' elf-symbol-id='__tracepoint_android_vh_page_trylock_get_result'/>
       <var-decl name='__tracepoint_android_vh_page_trylock_set' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_page_trylock_set' visibility='default' filepath='include/trace/hooks/vmscan.h' line='37' column='1' elf-symbol-id='__tracepoint_android_vh_page_trylock_set'/>
       <var-decl name='__tracepoint_android_vh_pagecache_get_page' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_pagecache_get_page' visibility='default' filepath='include/trace/hooks/mm.h' line='71' column='1' elf-symbol-id='__tracepoint_android_vh_pagecache_get_page'/>
-      <var-decl name='__tracepoint_android_vh_pcplist_add_cma_pages_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_pcplist_add_cma_pages_bypass' visibility='default' filepath='include/trace/hooks/mm.h' line='187' column='1' elf-symbol-id='__tracepoint_android_vh_pcplist_add_cma_pages_bypass'/>
+      <var-decl name='__tracepoint_android_vh_pageset_update' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_pageset_update' visibility='default' filepath='include/trace/hooks/mm.h' line='209' column='1' elf-symbol-id='__tracepoint_android_vh_pageset_update'/>
+      <var-decl name='__tracepoint_android_vh_pcplist_add_cma_pages_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_pcplist_add_cma_pages_bypass' visibility='default' filepath='include/trace/hooks/mm.h' line='216' column='1' elf-symbol-id='__tracepoint_android_vh_pcplist_add_cma_pages_bypass'/>
+      <var-decl name='__tracepoint_android_vh_percpu_rwsem_wq_add' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_percpu_rwsem_wq_add' visibility='default' filepath='include/trace/hooks/dtask.h' line='103' column='1' elf-symbol-id='__tracepoint_android_vh_percpu_rwsem_wq_add'/>
       <var-decl name='__tracepoint_android_vh_prepare_update_load_avg_se' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_prepare_update_load_avg_se' visibility='default' filepath='include/trace/hooks/sched.h' line='362' column='1' elf-symbol-id='__tracepoint_android_vh_prepare_update_load_avg_se'/>
       <var-decl name='__tracepoint_android_vh_printk_hotplug' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_printk_hotplug' visibility='default' filepath='include/trace/hooks/printk.h' line='13' column='1' elf-symbol-id='__tracepoint_android_vh_printk_hotplug'/>
       <var-decl name='__tracepoint_android_vh_process_killed' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_process_killed' visibility='default' filepath='include/trace/hooks/signal.h' line='20' column='1' elf-symbol-id='__tracepoint_android_vh_process_killed'/>
       <var-decl name='__tracepoint_android_vh_psi_event' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_psi_event' visibility='default' filepath='include/trace/hooks/psi.h' line='22' column='1' elf-symbol-id='__tracepoint_android_vh_psi_event'/>
       <var-decl name='__tracepoint_android_vh_psi_group' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_psi_group' visibility='default' filepath='include/trace/hooks/psi.h' line='26' column='1' elf-symbol-id='__tracepoint_android_vh_psi_group'/>
       <var-decl name='__tracepoint_android_vh_ptype_head' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_ptype_head' visibility='default' filepath='include/trace/hooks/net.h' line='24' column='1' elf-symbol-id='__tracepoint_android_vh_ptype_head'/>
-      <var-decl name='__tracepoint_android_vh_ra_tuning_max_page' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_ra_tuning_max_page' visibility='default' filepath='include/trace/hooks/mm.h' line='193' column='1' elf-symbol-id='__tracepoint_android_vh_ra_tuning_max_page'/>
-      <var-decl name='__tracepoint_android_vh_record_mutex_lock_starttime' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_record_mutex_lock_starttime' visibility='default' filepath='include/trace/hooks/dtask.h' line='71' column='1' elf-symbol-id='__tracepoint_android_vh_record_mutex_lock_starttime'/>
-      <var-decl name='__tracepoint_android_vh_record_pcpu_rwsem_starttime' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_record_pcpu_rwsem_starttime' visibility='default' filepath='include/trace/hooks/dtask.h' line='80' column='1' elf-symbol-id='__tracepoint_android_vh_record_pcpu_rwsem_starttime'/>
-      <var-decl name='__tracepoint_android_vh_record_rtmutex_lock_starttime' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_record_rtmutex_lock_starttime' visibility='default' filepath='include/trace/hooks/dtask.h' line='74' column='1' elf-symbol-id='__tracepoint_android_vh_record_rtmutex_lock_starttime'/>
-      <var-decl name='__tracepoint_android_vh_record_rwsem_lock_starttime' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_record_rwsem_lock_starttime' visibility='default' filepath='include/trace/hooks/dtask.h' line='77' column='1' elf-symbol-id='__tracepoint_android_vh_record_rwsem_lock_starttime'/>
-      <var-decl name='__tracepoint_android_vh_remove_vmalloc_stack' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_remove_vmalloc_stack' visibility='default' filepath='include/trace/hooks/mm.h' line='287' column='1' elf-symbol-id='__tracepoint_android_vh_remove_vmalloc_stack'/>
+      <var-decl name='__tracepoint_android_vh_ra_tuning_max_page' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_ra_tuning_max_page' visibility='default' filepath='include/trace/hooks/mm.h' line='222' column='1' elf-symbol-id='__tracepoint_android_vh_ra_tuning_max_page'/>
+      <var-decl name='__tracepoint_android_vh_record_mutex_lock_starttime' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_record_mutex_lock_starttime' visibility='default' filepath='include/trace/hooks/dtask.h' line='89' column='1' elf-symbol-id='__tracepoint_android_vh_record_mutex_lock_starttime'/>
+      <var-decl name='__tracepoint_android_vh_record_pcpu_rwsem_starttime' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_record_pcpu_rwsem_starttime' visibility='default' filepath='include/trace/hooks/dtask.h' line='98' column='1' elf-symbol-id='__tracepoint_android_vh_record_pcpu_rwsem_starttime'/>
+      <var-decl name='__tracepoint_android_vh_record_rtmutex_lock_starttime' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_record_rtmutex_lock_starttime' visibility='default' filepath='include/trace/hooks/dtask.h' line='92' column='1' elf-symbol-id='__tracepoint_android_vh_record_rtmutex_lock_starttime'/>
+      <var-decl name='__tracepoint_android_vh_record_rwsem_lock_starttime' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_record_rwsem_lock_starttime' visibility='default' filepath='include/trace/hooks/dtask.h' line='95' column='1' elf-symbol-id='__tracepoint_android_vh_record_rwsem_lock_starttime'/>
+      <var-decl name='__tracepoint_android_vh_remove_vmalloc_stack' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_remove_vmalloc_stack' visibility='default' filepath='include/trace/hooks/mm.h' line='335' column='1' elf-symbol-id='__tracepoint_android_vh_remove_vmalloc_stack'/>
       <var-decl name='__tracepoint_android_vh_revert_creds' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_revert_creds' visibility='default' filepath='include/trace/hooks/creds.h' line='35' column='1' elf-symbol-id='__tracepoint_android_vh_revert_creds'/>
       <var-decl name='__tracepoint_android_vh_rmqueue' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rmqueue' visibility='default' filepath='include/trace/hooks/mm.h' line='65' column='1' elf-symbol-id='__tracepoint_android_vh_rmqueue'/>
+      <var-decl name='__tracepoint_android_vh_rmqueue_bulk_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rmqueue_bulk_bypass' visibility='default' filepath='include/trace/hooks/mm.h' line='212' column='1' elf-symbol-id='__tracepoint_android_vh_rmqueue_bulk_bypass'/>
       <var-decl name='__tracepoint_android_vh_rproc_recovery' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rproc_recovery' visibility='default' filepath='include/trace/hooks/remoteproc.h' line='21' column='1' elf-symbol-id='__tracepoint_android_vh_rproc_recovery'/>
       <var-decl name='__tracepoint_android_vh_rproc_recovery_set' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rproc_recovery_set' visibility='default' filepath='include/trace/hooks/remoteproc.h' line='26' column='1' elf-symbol-id='__tracepoint_android_vh_rproc_recovery_set'/>
-      <var-decl name='__tracepoint_android_vh_rtmutex_wait_finish' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rtmutex_wait_finish' visibility='default' filepath='include/trace/hooks/dtask.h' line='39' column='1' elf-symbol-id='__tracepoint_android_vh_rtmutex_wait_finish'/>
-      <var-decl name='__tracepoint_android_vh_rtmutex_wait_start' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rtmutex_wait_start' visibility='default' filepath='include/trace/hooks/dtask.h' line='36' column='1' elf-symbol-id='__tracepoint_android_vh_rtmutex_wait_start'/>
+      <var-decl name='__tracepoint_android_vh_rtmutex_wait_finish' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rtmutex_wait_finish' visibility='default' filepath='include/trace/hooks/dtask.h' line='48' column='1' elf-symbol-id='__tracepoint_android_vh_rtmutex_wait_finish'/>
+      <var-decl name='__tracepoint_android_vh_rtmutex_wait_start' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rtmutex_wait_start' visibility='default' filepath='include/trace/hooks/dtask.h' line='45' column='1' elf-symbol-id='__tracepoint_android_vh_rtmutex_wait_start'/>
+      <var-decl name='__tracepoint_android_vh_rwsem_can_spin_on_owner' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_can_spin_on_owner' visibility='default' filepath='include/trace/hooks/dtask.h' line='70' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_can_spin_on_owner'/>
       <var-decl name='__tracepoint_android_vh_rwsem_init' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_init' visibility='default' filepath='include/trace/hooks/rwsem.h' line='20' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_init'/>
       <var-decl name='__tracepoint_android_vh_rwsem_mark_wake_readers' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_mark_wake_readers' visibility='default' filepath='include/trace/hooks/rwsem.h' line='49' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_mark_wake_readers'/>
-      <var-decl name='__tracepoint_android_vh_rwsem_read_wait_finish' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_read_wait_finish' visibility='default' filepath='include/trace/hooks/dtask.h' line='46' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_read_wait_finish'/>
-      <var-decl name='__tracepoint_android_vh_rwsem_read_wait_start' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_read_wait_start' visibility='default' filepath='include/trace/hooks/dtask.h' line='43' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_read_wait_start'/>
+      <var-decl name='__tracepoint_android_vh_rwsem_opt_spin_finish' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_opt_spin_finish' visibility='default' filepath='include/trace/hooks/dtask.h' line='67' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_opt_spin_finish'/>
+      <var-decl name='__tracepoint_android_vh_rwsem_opt_spin_start' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_opt_spin_start' visibility='default' filepath='include/trace/hooks/dtask.h' line='64' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_opt_spin_start'/>
+      <var-decl name='__tracepoint_android_vh_rwsem_read_wait_finish' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_read_wait_finish' visibility='default' filepath='include/trace/hooks/dtask.h' line='55' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_read_wait_finish'/>
+      <var-decl name='__tracepoint_android_vh_rwsem_read_wait_start' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_read_wait_start' visibility='default' filepath='include/trace/hooks/dtask.h' line='52' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_read_wait_start'/>
       <var-decl name='__tracepoint_android_vh_rwsem_set_owner' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_set_owner' visibility='default' filepath='include/trace/hooks/rwsem.h' line='37' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_set_owner'/>
       <var-decl name='__tracepoint_android_vh_rwsem_set_reader_owned' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_set_reader_owned' visibility='default' filepath='include/trace/hooks/rwsem.h' line='40' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_set_reader_owned'/>
       <var-decl name='__tracepoint_android_vh_rwsem_up_read_end' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_up_read_end' visibility='default' filepath='include/trace/hooks/rwsem.h' line='46' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_up_read_end'/>
@@ -121079,13 +121695,13 @@
       <var-decl name='__tracepoint_android_vh_rwsem_wake' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_wake' visibility='default' filepath='include/trace/hooks/rwsem.h' line='23' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_wake'/>
       <var-decl name='__tracepoint_android_vh_rwsem_wake_finish' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_wake_finish' visibility='default' filepath='include/trace/hooks/rwsem.h' line='34' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_wake_finish'/>
       <var-decl name='__tracepoint_android_vh_rwsem_write_finished' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_write_finished' visibility='default' filepath='include/trace/hooks/rwsem.h' line='26' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_write_finished'/>
-      <var-decl name='__tracepoint_android_vh_rwsem_write_wait_finish' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_write_wait_finish' visibility='default' filepath='include/trace/hooks/dtask.h' line='52' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_write_wait_finish'/>
-      <var-decl name='__tracepoint_android_vh_rwsem_write_wait_start' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_write_wait_start' visibility='default' filepath='include/trace/hooks/dtask.h' line='49' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_write_wait_start'/>
+      <var-decl name='__tracepoint_android_vh_rwsem_write_wait_finish' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_write_wait_finish' visibility='default' filepath='include/trace/hooks/dtask.h' line='61' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_write_wait_finish'/>
+      <var-decl name='__tracepoint_android_vh_rwsem_write_wait_start' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_rwsem_write_wait_start' visibility='default' filepath='include/trace/hooks/dtask.h' line='58' column='1' elf-symbol-id='__tracepoint_android_vh_rwsem_write_wait_start'/>
       <var-decl name='__tracepoint_android_vh_save_track_hash' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_save_track_hash' visibility='default' filepath='include/trace/hooks/mm.h' line='123' column='1' elf-symbol-id='__tracepoint_android_vh_save_track_hash'/>
       <var-decl name='__tracepoint_android_vh_save_vmalloc_stack' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_save_vmalloc_stack' visibility='default' filepath='include/trace/hooks/mm.h' line='117' column='1' elf-symbol-id='__tracepoint_android_vh_save_vmalloc_stack'/>
       <var-decl name='__tracepoint_android_vh_sched_pelt_multiplier' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_sched_pelt_multiplier' visibility='default' filepath='include/trace/hooks/sched.h' line='398' column='1' elf-symbol-id='__tracepoint_android_vh_sched_pelt_multiplier'/>
       <var-decl name='__tracepoint_android_vh_sched_setaffinity_early' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_sched_setaffinity_early' visibility='default' filepath='include/trace/hooks/sched.h' line='328' column='1' elf-symbol-id='__tracepoint_android_vh_sched_setaffinity_early'/>
-      <var-decl name='__tracepoint_android_vh_sched_show_task' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_sched_show_task' visibility='default' filepath='include/trace/hooks/dtask.h' line='56' column='1' elf-symbol-id='__tracepoint_android_vh_sched_show_task'/>
+      <var-decl name='__tracepoint_android_vh_sched_show_task' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_sched_show_task' visibility='default' filepath='include/trace/hooks/dtask.h' line='74' column='1' elf-symbol-id='__tracepoint_android_vh_sched_show_task'/>
       <var-decl name='__tracepoint_android_vh_sched_stat_runtime_rt' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_sched_stat_runtime_rt' visibility='default' filepath='include/trace/hooks/sched.h' line='366' column='1' elf-symbol-id='__tracepoint_android_vh_sched_stat_runtime_rt'/>
       <var-decl name='__tracepoint_android_vh_scheduler_tick' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_scheduler_tick' visibility='default' filepath='include/trace/hooks/sched.h' line='45' column='1' elf-symbol-id='__tracepoint_android_vh_scheduler_tick'/>
       <var-decl name='__tracepoint_android_vh_scmi_timeout_sync' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_scmi_timeout_sync' visibility='default' filepath='include/trace/hooks/scmi.h' line='13' column='1' elf-symbol-id='__tracepoint_android_vh_scmi_timeout_sync'/>
@@ -121102,12 +121718,14 @@
       <var-decl name='__tracepoint_android_vh_set_memory_x' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_set_memory_x' visibility='default' filepath='include/trace/hooks/memory.h' line='14' column='1' elf-symbol-id='__tracepoint_android_vh_set_memory_x'/>
       <var-decl name='__tracepoint_android_vh_set_module_permit_after_init' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_set_module_permit_after_init' visibility='default' filepath='include/trace/hooks/module.h' line='24' column='1' elf-symbol-id='__tracepoint_android_vh_set_module_permit_after_init'/>
       <var-decl name='__tracepoint_android_vh_set_module_permit_before_init' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_set_module_permit_before_init' visibility='default' filepath='include/trace/hooks/module.h' line='20' column='1' elf-symbol-id='__tracepoint_android_vh_set_module_permit_before_init'/>
-      <var-decl name='__tracepoint_android_vh_set_shmem_page_flag' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_set_shmem_page_flag' visibility='default' filepath='include/trace/hooks/mm.h' line='284' column='1' elf-symbol-id='__tracepoint_android_vh_set_shmem_page_flag'/>
+      <var-decl name='__tracepoint_android_vh_set_shmem_page_flag' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_set_shmem_page_flag' visibility='default' filepath='include/trace/hooks/mm.h' line='332' column='1' elf-symbol-id='__tracepoint_android_vh_set_shmem_page_flag'/>
       <var-decl name='__tracepoint_android_vh_set_wake_flags' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_set_wake_flags' visibility='default' filepath='include/trace/hooks/sched.h' line='280' column='1' elf-symbol-id='__tracepoint_android_vh_set_wake_flags'/>
       <var-decl name='__tracepoint_android_vh_setscheduler_uclamp' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_setscheduler_uclamp' visibility='default' filepath='include/trace/hooks/sched.h' line='390' column='1' elf-symbol-id='__tracepoint_android_vh_setscheduler_uclamp'/>
       <var-decl name='__tracepoint_android_vh_sha256' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_sha256' visibility='default' filepath='include/trace/hooks/fips140.h' line='25' column='1' elf-symbol-id='__tracepoint_android_vh_sha256'/>
       <var-decl name='__tracepoint_android_vh_shmem_alloc_page' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_shmem_alloc_page' visibility='default' filepath='include/trace/hooks/shmem_fs.h' line='17' column='1' elf-symbol-id='__tracepoint_android_vh_shmem_alloc_page'/>
-      <var-decl name='__tracepoint_android_vh_show_mapcount_pages' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_show_mapcount_pages' visibility='default' filepath='include/trace/hooks/mm.h' line='172' column='1' elf-symbol-id='__tracepoint_android_vh_show_mapcount_pages'/>
+      <var-decl name='__tracepoint_android_vh_should_alloc_pages_retry' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_should_alloc_pages_retry' visibility='default' filepath='include/trace/hooks/mm.h' line='201' column='1' elf-symbol-id='__tracepoint_android_vh_should_alloc_pages_retry'/>
+      <var-decl name='__tracepoint_android_vh_should_end_madvise' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_should_end_madvise' visibility='default' filepath='include/trace/hooks/mm.h' line='305' column='1' elf-symbol-id='__tracepoint_android_vh_should_end_madvise'/>
+      <var-decl name='__tracepoint_android_vh_show_mapcount_pages' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_show_mapcount_pages' visibility='default' filepath='include/trace/hooks/mm.h' line='180' column='1' elf-symbol-id='__tracepoint_android_vh_show_mapcount_pages'/>
       <var-decl name='__tracepoint_android_vh_show_max_freq' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_show_max_freq' visibility='default' filepath='include/trace/hooks/cpufreq.h' line='18' column='1' elf-symbol-id='__tracepoint_android_vh_show_max_freq'/>
       <var-decl name='__tracepoint_android_vh_show_mem' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_show_mem' visibility='default' filepath='include/trace/hooks/mm.h' line='98' column='1' elf-symbol-id='__tracepoint_android_vh_show_mem'/>
       <var-decl name='__tracepoint_android_vh_show_resume_epoch_val' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_show_resume_epoch_val' visibility='default' filepath='include/trace/hooks/epoch.h' line='17' column='1' elf-symbol-id='__tracepoint_android_vh_show_resume_epoch_val'/>
@@ -121115,24 +121733,27 @@
       <var-decl name='__tracepoint_android_vh_show_suspend_epoch_val' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_show_suspend_epoch_val' visibility='default' filepath='include/trace/hooks/epoch.h' line='13' column='1' elf-symbol-id='__tracepoint_android_vh_show_suspend_epoch_val'/>
       <var-decl name='__tracepoint_android_vh_shrink_node_memcgs' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_shrink_node_memcgs' visibility='default' filepath='include/trace/hooks/vmscan.h' line='43' column='1' elf-symbol-id='__tracepoint_android_vh_shrink_node_memcgs'/>
       <var-decl name='__tracepoint_android_vh_shrink_slab_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_shrink_slab_bypass' visibility='default' filepath='include/trace/hooks/vmscan.h' line='19' column='1' elf-symbol-id='__tracepoint_android_vh_shrink_slab_bypass'/>
-      <var-decl name='__tracepoint_android_vh_si_swapinfo' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_si_swapinfo' visibility='default' filepath='include/trace/hooks/mm.h' line='272' column='1' elf-symbol-id='__tracepoint_android_vh_si_swapinfo'/>
+      <var-decl name='__tracepoint_android_vh_si_swapinfo' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_si_swapinfo' visibility='default' filepath='include/trace/hooks/mm.h' line='320' column='1' elf-symbol-id='__tracepoint_android_vh_si_swapinfo'/>
+      <var-decl name='__tracepoint_android_vh_skip_swapcache' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_skip_swapcache' visibility='default' filepath='include/trace/hooks/mm.h' line='362' column='1' elf-symbol-id='__tracepoint_android_vh_skip_swapcache'/>
       <var-decl name='__tracepoint_android_vh_snapshot_refaults' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_snapshot_refaults' visibility='default' filepath='include/trace/hooks/vmscan.h' line='50' column='1' elf-symbol-id='__tracepoint_android_vh_snapshot_refaults'/>
       <var-decl name='__tracepoint_android_vh_snd_compr_use_pause_in_drain' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_snd_compr_use_pause_in_drain' visibility='default' filepath='include/trace/hooks/snd_compr.h' line='18' column='1' elf-symbol-id='__tracepoint_android_vh_snd_compr_use_pause_in_drain'/>
       <var-decl name='__tracepoint_android_vh_snd_soc_card_get_comp_chain' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_snd_soc_card_get_comp_chain' visibility='default' filepath='include/trace/hooks/sound.h' line='18' column='1' elf-symbol-id='__tracepoint_android_vh_snd_soc_card_get_comp_chain'/>
       <var-decl name='__tracepoint_android_vh_sound_usb_support_cpu_suspend' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_sound_usb_support_cpu_suspend' visibility='default' filepath='include/trace/hooks/sound.h' line='12' column='1' elf-symbol-id='__tracepoint_android_vh_sound_usb_support_cpu_suspend'/>
-      <var-decl name='__tracepoint_android_vh_subpage_dma_contig_alloc' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_subpage_dma_contig_alloc' visibility='default' filepath='include/trace/hooks/mm.h' line='190' column='1' elf-symbol-id='__tracepoint_android_vh_subpage_dma_contig_alloc'/>
-      <var-decl name='__tracepoint_android_vh_swap_slot_cache_active' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_swap_slot_cache_active' visibility='default' filepath='include/trace/hooks/mm.h' line='226' column='1' elf-symbol-id='__tracepoint_android_vh_swap_slot_cache_active'/>
-      <var-decl name='__tracepoint_android_vh_swapin_add_anon_rmap' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_swapin_add_anon_rmap' visibility='default' filepath='include/trace/hooks/mm.h' line='205' column='1' elf-symbol-id='__tracepoint_android_vh_swapin_add_anon_rmap'/>
+      <var-decl name='__tracepoint_android_vh_subpage_dma_contig_alloc' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_subpage_dma_contig_alloc' visibility='default' filepath='include/trace/hooks/mm.h' line='219' column='1' elf-symbol-id='__tracepoint_android_vh_subpage_dma_contig_alloc'/>
+      <var-decl name='__tracepoint_android_vh_swap_avail_heads_init' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_swap_avail_heads_init' visibility='default' filepath='include/trace/hooks/mm.h' line='314' column='1' elf-symbol-id='__tracepoint_android_vh_swap_avail_heads_init'/>
+      <var-decl name='__tracepoint_android_vh_swap_slot_cache_active' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_swap_slot_cache_active' visibility='default' filepath='include/trace/hooks/mm.h' line='259' column='1' elf-symbol-id='__tracepoint_android_vh_swap_slot_cache_active'/>
+      <var-decl name='__tracepoint_android_vh_swapin_add_anon_rmap' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_swapin_add_anon_rmap' visibility='default' filepath='include/trace/hooks/mm.h' line='238' column='1' elf-symbol-id='__tracepoint_android_vh_swapin_add_anon_rmap'/>
       <var-decl name='__tracepoint_android_vh_sync_txn_recvd' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_sync_txn_recvd' visibility='default' filepath='include/trace/hooks/binder.h' line='57' column='1' elf-symbol-id='__tracepoint_android_vh_sync_txn_recvd'/>
       <var-decl name='__tracepoint_android_vh_syscall_prctl_finished' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_syscall_prctl_finished' visibility='default' filepath='include/trace/hooks/sys.h' line='17' column='1' elf-symbol-id='__tracepoint_android_vh_syscall_prctl_finished'/>
-      <var-decl name='__tracepoint_android_vh_test_clear_look_around_ref' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_test_clear_look_around_ref' visibility='default' filepath='include/trace/hooks/mm.h' line='298' column='1' elf-symbol-id='__tracepoint_android_vh_test_clear_look_around_ref'/>
+      <var-decl name='__tracepoint_android_vh_test_clear_look_around_ref' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_test_clear_look_around_ref' visibility='default' filepath='include/trace/hooks/mm.h' line='346' column='1' elf-symbol-id='__tracepoint_android_vh_test_clear_look_around_ref'/>
       <var-decl name='__tracepoint_android_vh_thermal_pm_notify_suspend' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_thermal_pm_notify_suspend' visibility='default' filepath='include/trace/hooks/thermal.h' line='23' column='1' elf-symbol-id='__tracepoint_android_vh_thermal_pm_notify_suspend'/>
       <var-decl name='__tracepoint_android_vh_timer_calc_index' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_timer_calc_index' visibility='default' filepath='include/trace/hooks/timer.h' line='13' column='1' elf-symbol-id='__tracepoint_android_vh_timer_calc_index'/>
       <var-decl name='__tracepoint_android_vh_timerfd_create' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_timerfd_create' visibility='default' filepath='include/trace/hooks/fs.h' line='17' column='1' elf-symbol-id='__tracepoint_android_vh_timerfd_create'/>
       <var-decl name='__tracepoint_android_vh_try_to_freeze_todo' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_try_to_freeze_todo' visibility='default' filepath='include/trace/hooks/power.h' line='25' column='1' elf-symbol-id='__tracepoint_android_vh_try_to_freeze_todo'/>
       <var-decl name='__tracepoint_android_vh_try_to_freeze_todo_unfrozen' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_try_to_freeze_todo_unfrozen' visibility='default' filepath='include/trace/hooks/power.h' line='29' column='1' elf-symbol-id='__tracepoint_android_vh_try_to_freeze_todo_unfrozen'/>
-      <var-decl name='__tracepoint_android_vh_try_to_unmap_one' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_try_to_unmap_one' visibility='default' filepath='include/trace/hooks/mm.h' line='150' column='1' elf-symbol-id='__tracepoint_android_vh_try_to_unmap_one'/>
+      <var-decl name='__tracepoint_android_vh_try_to_unmap_one' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_try_to_unmap_one' visibility='default' filepath='include/trace/hooks/mm.h' line='158' column='1' elf-symbol-id='__tracepoint_android_vh_try_to_unmap_one'/>
       <var-decl name='__tracepoint_android_vh_tune_inactive_ratio' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_tune_inactive_ratio' visibility='default' filepath='include/trace/hooks/vmscan.h' line='22' column='1' elf-symbol-id='__tracepoint_android_vh_tune_inactive_ratio'/>
+      <var-decl name='__tracepoint_android_vh_tune_mmap_readaround' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_tune_mmap_readaround' visibility='default' filepath='include/trace/hooks/mm.h' line='225' column='1' elf-symbol-id='__tracepoint_android_vh_tune_mmap_readaround'/>
       <var-decl name='__tracepoint_android_vh_tune_scan_type' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_tune_scan_type' visibility='default' filepath='include/trace/hooks/vmscan.h' line='13' column='1' elf-symbol-id='__tracepoint_android_vh_tune_scan_type'/>
       <var-decl name='__tracepoint_android_vh_tune_swappiness' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_tune_swappiness' visibility='default' filepath='include/trace/hooks/vmscan.h' line='16' column='1' elf-symbol-id='__tracepoint_android_vh_tune_swappiness'/>
       <var-decl name='__tracepoint_android_vh_typec_store_partner_src_caps' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_typec_store_partner_src_caps' visibility='default' filepath='include/trace/hooks/typec.h' line='57' column='1' elf-symbol-id='__tracepoint_android_vh_typec_store_partner_src_caps'/>
@@ -121150,8 +121771,9 @@
       <var-decl name='__tracepoint_android_vh_ufs_send_uic_command' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_ufs_send_uic_command' visibility='default' filepath='include/trace/hooks/ufshcd.h' line='58' column='1' elf-symbol-id='__tracepoint_android_vh_ufs_send_uic_command'/>
       <var-decl name='__tracepoint_android_vh_ufs_update_sdev' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_ufs_update_sdev' visibility='default' filepath='include/trace/hooks/ufshcd.h' line='71' column='1' elf-symbol-id='__tracepoint_android_vh_ufs_update_sdev'/>
       <var-decl name='__tracepoint_android_vh_ufs_update_sysfs' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_ufs_update_sysfs' visibility='default' filepath='include/trace/hooks/ufshcd.h' line='46' column='1' elf-symbol-id='__tracepoint_android_vh_ufs_update_sysfs'/>
-      <var-decl name='__tracepoint_android_vh_unuse_swap_page' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_unuse_swap_page' visibility='default' filepath='include/trace/hooks/mm.h' line='266' column='1' elf-symbol-id='__tracepoint_android_vh_unuse_swap_page'/>
-      <var-decl name='__tracepoint_android_vh_update_page_mapcount' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_update_page_mapcount' visibility='default' filepath='include/trace/hooks/mm.h' line='162' column='1' elf-symbol-id='__tracepoint_android_vh_update_page_mapcount'/>
+      <var-decl name='__tracepoint_android_vh_unreserve_highatomic_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_unreserve_highatomic_bypass' visibility='default' filepath='include/trace/hooks/mm.h' line='206' column='1' elf-symbol-id='__tracepoint_android_vh_unreserve_highatomic_bypass'/>
+      <var-decl name='__tracepoint_android_vh_unuse_swap_page' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_unuse_swap_page' visibility='default' filepath='include/trace/hooks/mm.h' line='311' column='1' elf-symbol-id='__tracepoint_android_vh_unuse_swap_page'/>
+      <var-decl name='__tracepoint_android_vh_update_page_mapcount' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_update_page_mapcount' visibility='default' filepath='include/trace/hooks/mm.h' line='170' column='1' elf-symbol-id='__tracepoint_android_vh_update_page_mapcount'/>
       <var-decl name='__tracepoint_android_vh_update_topology_flags_workfn' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_update_topology_flags_workfn' visibility='default' filepath='include/trace/hooks/topology.h' line='19' column='1' elf-symbol-id='__tracepoint_android_vh_update_topology_flags_workfn'/>
       <var-decl name='__tracepoint_android_vh_usb_dev_resume' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_usb_dev_resume' visibility='default' filepath='include/trace/hooks/usb.h' line='20' column='1' elf-symbol-id='__tracepoint_android_vh_usb_dev_resume'/>
       <var-decl name='__tracepoint_android_vh_usb_dev_suspend' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_usb_dev_suspend' visibility='default' filepath='include/trace/hooks/usb.h' line='16' column='1' elf-symbol-id='__tracepoint_android_vh_usb_dev_suspend'/>
@@ -121159,7 +121781,8 @@
       <var-decl name='__tracepoint_android_vh_v4l2subdev_set_frame_interval' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_v4l2subdev_set_frame_interval' visibility='default' filepath='include/trace/hooks/v4l2core.h' line='51' column='1' elf-symbol-id='__tracepoint_android_vh_v4l2subdev_set_frame_interval'/>
       <var-decl name='__tracepoint_android_vh_v4l2subdev_set_selection' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_v4l2subdev_set_selection' visibility='default' filepath='include/trace/hooks/v4l2core.h' line='41' column='1' elf-symbol-id='__tracepoint_android_vh_v4l2subdev_set_selection'/>
       <var-decl name='__tracepoint_android_vh_vmpressure' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_vmpressure' visibility='default' filepath='include/trace/hooks/mm.h' line='126' column='1' elf-symbol-id='__tracepoint_android_vh_vmpressure'/>
-      <var-decl name='__tracepoint_android_vh_waiting_for_page_migration' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_waiting_for_page_migration' visibility='default' filepath='include/trace/hooks/mm.h' line='208' column='1' elf-symbol-id='__tracepoint_android_vh_waiting_for_page_migration'/>
+      <var-decl name='__tracepoint_android_vh_waiting_for_page_migration' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_waiting_for_page_migration' visibility='default' filepath='include/trace/hooks/mm.h' line='241' column='1' elf-symbol-id='__tracepoint_android_vh_waiting_for_page_migration'/>
+      <var-decl name='__tracepoint_android_vh_wakeup_bypass' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_wakeup_bypass' visibility='default' filepath='include/trace/hooks/wakeupbypass.h' line='11' column='1' elf-symbol-id='__tracepoint_android_vh_wakeup_bypass'/>
       <var-decl name='__tracepoint_android_vh_watchdog_timer_softlockup' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_watchdog_timer_softlockup' visibility='default' filepath='include/trace/hooks/softlockup.h' line='20' column='1' elf-symbol-id='__tracepoint_android_vh_watchdog_timer_softlockup'/>
       <var-decl name='__tracepoint_android_vh_wq_lockup_pool' type-id='4ca0c298' mangled-name='__tracepoint_android_vh_wq_lockup_pool' visibility='default' filepath='include/trace/hooks/wqlockup.h' line='14' column='1' elf-symbol-id='__tracepoint_android_vh_wq_lockup_pool'/>
       <var-decl name='__tracepoint_binder_transaction_received' type-id='4ca0c298' mangled-name='__tracepoint_binder_transaction_received' visibility='default' filepath='drivers/android/./binder_trace.h' line='150' column='1' elf-symbol-id='__tracepoint_binder_transaction_received'/>
@@ -121187,8 +121810,8 @@
       <var-decl name='__tracepoint_dwc3_readl' type-id='4ca0c298' mangled-name='__tracepoint_dwc3_readl' visibility='default' filepath='drivers/usb/dwc3/./trace.h' line='39' column='1' elf-symbol-id='__tracepoint_dwc3_readl'/>
       <var-decl name='__tracepoint_dwc3_writel' type-id='4ca0c298' mangled-name='__tracepoint_dwc3_writel' visibility='default' filepath='drivers/usb/dwc3/./trace.h' line='44' column='1' elf-symbol-id='__tracepoint_dwc3_writel'/>
       <var-decl name='__tracepoint_gpu_mem_total' type-id='4ca0c298' mangled-name='__tracepoint_gpu_mem_total' visibility='default' filepath='include/trace/events/gpu_mem.h' line='30' column='1' elf-symbol-id='__tracepoint_gpu_mem_total'/>
-      <var-decl name='__tracepoint_hrtimer_expire_entry' type-id='4ca0c298' mangled-name='__tracepoint_hrtimer_expire_entry' visibility='default' filepath='include/trace/events/timer.h' line='232' column='1' elf-symbol-id='__tracepoint_hrtimer_expire_entry'/>
-      <var-decl name='__tracepoint_hrtimer_expire_exit' type-id='4ca0c298' mangled-name='__tracepoint_hrtimer_expire_exit' visibility='default' filepath='include/trace/events/timer.h' line='279' column='1' elf-symbol-id='__tracepoint_hrtimer_expire_exit'/>
+      <var-decl name='__tracepoint_hrtimer_expire_entry' type-id='4ca0c298' mangled-name='__tracepoint_hrtimer_expire_entry' visibility='default' filepath='include/trace/events/timer.h' line='236' column='1' elf-symbol-id='__tracepoint_hrtimer_expire_entry'/>
+      <var-decl name='__tracepoint_hrtimer_expire_exit' type-id='4ca0c298' mangled-name='__tracepoint_hrtimer_expire_exit' visibility='default' filepath='include/trace/events/timer.h' line='283' column='1' elf-symbol-id='__tracepoint_hrtimer_expire_exit'/>
       <var-decl name='__tracepoint_ipi_entry' type-id='4ca0c298' mangled-name='__tracepoint_ipi_entry' visibility='default' filepath='include/trace/events/ipi.h' line='64' column='1' elf-symbol-id='__tracepoint_ipi_entry'/>
       <var-decl name='__tracepoint_ipi_exit' type-id='4ca0c298' mangled-name='__tracepoint_ipi_exit' visibility='default' filepath='include/trace/events/ipi.h' line='80' column='1' elf-symbol-id='__tracepoint_ipi_exit'/>
       <var-decl name='__tracepoint_ipi_raise' type-id='4ca0c298' mangled-name='__tracepoint_ipi_raise' visibility='default' filepath='include/trace/events/ipi.h' line='19' column='1' elf-symbol-id='__tracepoint_ipi_raise'/>
@@ -121231,11 +121854,11 @@
       <var-decl name='__tracepoint_workqueue_execute_end' type-id='4ca0c298' mangled-name='__tracepoint_workqueue_execute_end' visibility='default' filepath='include/trace/events/workqueue.h' line='108' column='1' elf-symbol-id='__tracepoint_workqueue_execute_end'/>
       <var-decl name='__tracepoint_workqueue_execute_start' type-id='4ca0c298' mangled-name='__tracepoint_workqueue_execute_start' visibility='default' filepath='include/trace/events/workqueue.h' line='82' column='1' elf-symbol-id='__tracepoint_workqueue_execute_start'/>
       <var-decl name='__tracepoint_xdp_exception' type-id='4ca0c298' mangled-name='__tracepoint_xdp_exception' visibility='default' filepath='include/trace/events/xdp.h' line='28' column='1' elf-symbol-id='__tracepoint_xdp_exception'/>
-      <var-decl name='__tracepoint_xhci_urb_giveback' type-id='4ca0c298' mangled-name='__tracepoint_xhci_urb_giveback' visibility='default' filepath='drivers/usb/host/./xhci-trace.h' line='307' column='1' elf-symbol-id='__tracepoint_xhci_urb_giveback'/>
-      <function-decl name='__tty_alloc_driver' mangled-name='__tty_alloc_driver' filepath='drivers/tty/tty_io.c' line='3299' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__tty_alloc_driver'>
-        <parameter type-id='f0981eeb' name='lines' filepath='drivers/tty/tty_io.c' line='3299' column='1'/>
-        <parameter type-id='2730d015' name='owner' filepath='drivers/tty/tty_io.c' line='3299' column='1'/>
-        <parameter type-id='7359adad' name='flags' filepath='drivers/tty/tty_io.c' line='3300' column='1'/>
+      <var-decl name='__tracepoint_xhci_urb_giveback' type-id='4ca0c298' mangled-name='__tracepoint_xhci_urb_giveback' visibility='default' filepath='drivers/usb/host/./xhci-trace.h' line='303' column='1' elf-symbol-id='__tracepoint_xhci_urb_giveback'/>
+      <function-decl name='__tty_alloc_driver' mangled-name='__tty_alloc_driver' filepath='drivers/tty/tty_io.c' line='3302' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__tty_alloc_driver'>
+        <parameter type-id='f0981eeb' name='lines' filepath='drivers/tty/tty_io.c' line='3302' column='1'/>
+        <parameter type-id='2730d015' name='owner' filepath='drivers/tty/tty_io.c' line='3302' column='1'/>
+        <parameter type-id='7359adad' name='flags' filepath='drivers/tty/tty_io.c' line='3303' column='1'/>
         <return type-id='c2b4b27b'/>
       </function-decl>
       <function-decl name='__tty_insert_flip_char' mangled-name='__tty_insert_flip_char' filepath='drivers/tty/tty_buffer.c' line='380' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__tty_insert_flip_char'>
@@ -121252,6 +121875,30 @@
       <function-decl name='__udelay' mangled-name='__udelay' filepath='arch/arm64/lib/delay.c' line='49' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__udelay'>
         <parameter type-id='7359adad' name='usecs' filepath='arch/arm64/lib/delay.c' line='49' column='1'/>
         <return type-id='48b5725f'/>
+      </function-decl>
+      <function-decl name='__udp4_lib_lookup' mangled-name='__udp4_lib_lookup' filepath='net/ipv4/udp.c' line='486' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__udp4_lib_lookup'>
+        <parameter type-id='a2bff676' name='net' filepath='net/ipv4/udp.c' line='486' column='1'/>
+        <parameter type-id='78a133c2' name='saddr' filepath='net/ipv4/udp.c' line='486' column='1'/>
+        <parameter type-id='84a5c3d4' name='sport' filepath='net/ipv4/udp.c' line='487' column='1'/>
+        <parameter type-id='78a133c2' name='daddr' filepath='net/ipv4/udp.c' line='487' column='1'/>
+        <parameter type-id='84a5c3d4' name='dport' filepath='net/ipv4/udp.c' line='487' column='1'/>
+        <parameter type-id='95e97e5e' name='dif' filepath='net/ipv4/udp.c' line='487' column='1'/>
+        <parameter type-id='95e97e5e' name='sdif' filepath='net/ipv4/udp.c' line='488' column='1'/>
+        <parameter type-id='115daa23' name='udptable' filepath='net/ipv4/udp.c' line='488' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/ipv4/udp.c' line='488' column='1'/>
+        <return type-id='f772df6d'/>
+      </function-decl>
+      <function-decl name='__udp6_lib_lookup' mangled-name='__udp6_lib_lookup' filepath='net/ipv6/udp.c' line='231' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__udp6_lib_lookup'>
+        <parameter type-id='a2bff676' name='net' filepath='net/ipv6/udp.c' line='231' column='1'/>
+        <parameter type-id='fea9c20b' name='saddr' filepath='net/ipv6/udp.c' line='232' column='1'/>
+        <parameter type-id='84a5c3d4' name='sport' filepath='net/ipv6/udp.c' line='232' column='1'/>
+        <parameter type-id='fea9c20b' name='daddr' filepath='net/ipv6/udp.c' line='233' column='1'/>
+        <parameter type-id='84a5c3d4' name='dport' filepath='net/ipv6/udp.c' line='233' column='1'/>
+        <parameter type-id='95e97e5e' name='dif' filepath='net/ipv6/udp.c' line='234' column='1'/>
+        <parameter type-id='95e97e5e' name='sdif' filepath='net/ipv6/udp.c' line='234' column='1'/>
+        <parameter type-id='115daa23' name='udptable' filepath='net/ipv6/udp.c' line='234' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/ipv6/udp.c' line='235' column='1'/>
+        <return type-id='f772df6d'/>
       </function-decl>
       <function-decl name='__uio_register_device' mangled-name='__uio_register_device' filepath='drivers/uio/uio.c' line='916' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__uio_register_device'>
         <parameter type-id='2730d015' name='owner' filepath='drivers/uio/uio.c' line='916' column='1'/>
@@ -121279,12 +121926,12 @@
         <parameter type-id='fc4f83c1' name='primary_hcd' filepath='drivers/usb/core/hcd.c' line='2439' column='1'/>
         <return type-id='fc4f83c1'/>
       </function-decl>
-      <function-decl name='__usb_get_extra_descriptor' mangled-name='__usb_get_extra_descriptor' filepath='drivers/usb/core/usb.c' line='872' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__usb_get_extra_descriptor'>
-        <parameter type-id='26a90f95' name='buffer' filepath='drivers/usb/core/usb.c' line='872' column='1'/>
-        <parameter type-id='f0981eeb' name='size' filepath='drivers/usb/core/usb.c' line='872' column='1'/>
-        <parameter type-id='002ac4a6' name='type' filepath='drivers/usb/core/usb.c' line='873' column='1'/>
-        <parameter type-id='63e171df' name='ptr' filepath='drivers/usb/core/usb.c' line='873' column='1'/>
-        <parameter type-id='b59d7dce' name='minsize' filepath='drivers/usb/core/usb.c' line='873' column='1'/>
+      <function-decl name='__usb_get_extra_descriptor' mangled-name='__usb_get_extra_descriptor' filepath='drivers/usb/core/usb.c' line='948' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__usb_get_extra_descriptor'>
+        <parameter type-id='26a90f95' name='buffer' filepath='drivers/usb/core/usb.c' line='948' column='1'/>
+        <parameter type-id='f0981eeb' name='size' filepath='drivers/usb/core/usb.c' line='948' column='1'/>
+        <parameter type-id='002ac4a6' name='type' filepath='drivers/usb/core/usb.c' line='949' column='1'/>
+        <parameter type-id='63e171df' name='ptr' filepath='drivers/usb/core/usb.c' line='949' column='1'/>
+        <parameter type-id='b59d7dce' name='minsize' filepath='drivers/usb/core/usb.c' line='949' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__usecs_to_jiffies' mangled-name='__usecs_to_jiffies' filepath='kernel/time/time.c' line='563' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__usecs_to_jiffies'>
@@ -121342,9 +121989,9 @@
         <parameter type-id='2730d015' name='owner' filepath='drivers/media/v4l2-core/v4l2-dev.c' line='879' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__vmalloc' mangled-name='__vmalloc' filepath='mm/vmalloc.c' line='2621' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__vmalloc'>
-        <parameter type-id='7359adad' name='size' filepath='mm/vmalloc.c' line='2621' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/vmalloc.c' line='2621' column='1'/>
+      <function-decl name='__vmalloc' mangled-name='__vmalloc' filepath='mm/vmalloc.c' line='2625' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__vmalloc'>
+        <parameter type-id='7359adad' name='size' filepath='mm/vmalloc.c' line='2625' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/vmalloc.c' line='2625' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
       <function-decl name='__wait_on_buffer' mangled-name='__wait_on_buffer' filepath='fs/buffer.c' line='120' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__wait_on_buffer'>
@@ -121388,8 +122035,8 @@
         <parameter type-id='eaa32e2f' name='key' filepath='kernel/sched/wait.c' line='186' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='__warn_printk' mangled-name='__warn_printk' filepath='kernel/panic.c' line='640' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__warn_printk'>
-        <parameter type-id='80f4b756' name='fmt' filepath='kernel/panic.c' line='640' column='1'/>
+      <function-decl name='__warn_printk' mangled-name='__warn_printk' filepath='kernel/panic.c' line='708' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__warn_printk'>
+        <parameter type-id='80f4b756' name='fmt' filepath='kernel/panic.c' line='708' column='1'/>
         <parameter is-variadic='yes'/>
         <return type-id='48b5725f'/>
       </function-decl>
@@ -121399,6 +122046,15 @@
         <parameter type-id='eaa32e2f' name='entry' filepath='lib/xarray.c' line='1808' column='1'/>
         <parameter type-id='5066733a' name='limit' filepath='lib/xarray.c' line='1809' column='1'/>
         <parameter type-id='3eb7c31c' name='gfp' filepath='lib/xarray.c' line='1809' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='__xa_alloc_cyclic' mangled-name='__xa_alloc_cyclic' filepath='lib/xarray.c' line='1857' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__xa_alloc_cyclic'>
+        <parameter type-id='60075f2a' name='xa' filepath='lib/xarray.c' line='1857' column='1'/>
+        <parameter type-id='f9409001' name='id' filepath='lib/xarray.c' line='1857' column='1'/>
+        <parameter type-id='eaa32e2f' name='entry' filepath='lib/xarray.c' line='1857' column='1'/>
+        <parameter type-id='5066733a' name='limit' filepath='lib/xarray.c' line='1858' column='1'/>
+        <parameter type-id='f9409001' name='next' filepath='lib/xarray.c' line='1858' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp' filepath='lib/xarray.c' line='1858' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__xa_clear_mark' mangled-name='__xa_clear_mark' filepath='lib/xarray.c' line='1914' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__xa_clear_mark'>
@@ -121414,11 +122070,11 @@
         <parameter type-id='3eb7c31c' name='gfp' filepath='lib/xarray.c' line='1639' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='__xfrm_decode_session' mangled-name='__xfrm_decode_session' filepath='net/xfrm/xfrm_policy.c' line='3515' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__xfrm_decode_session'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/xfrm/xfrm_policy.c' line='3515' column='1'/>
-        <parameter type-id='b1fd62ba' name='fl' filepath='net/xfrm/xfrm_policy.c' line='3515' column='1'/>
-        <parameter type-id='f0981eeb' name='family' filepath='net/xfrm/xfrm_policy.c' line='3516' column='1'/>
-        <parameter type-id='95e97e5e' name='reverse' filepath='net/xfrm/xfrm_policy.c' line='3516' column='1'/>
+      <function-decl name='__xfrm_decode_session' mangled-name='__xfrm_decode_session' filepath='net/xfrm/xfrm_policy.c' line='3523' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__xfrm_decode_session'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/xfrm/xfrm_policy.c' line='3523' column='1'/>
+        <parameter type-id='b1fd62ba' name='fl' filepath='net/xfrm/xfrm_policy.c' line='3523' column='1'/>
+        <parameter type-id='f0981eeb' name='family' filepath='net/xfrm/xfrm_policy.c' line='3524' column='1'/>
+        <parameter type-id='95e97e5e' name='reverse' filepath='net/xfrm/xfrm_policy.c' line='3524' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='__xfrm_state_destroy' mangled-name='__xfrm_state_destroy' filepath='net/xfrm/xfrm_state.c' line='640' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='__xfrm_state_destroy'>
@@ -121439,22 +122095,22 @@
         <parameter type-id='f0981eeb' name='val' filepath='lib/bcd.c' line='11' column='1'/>
         <return type-id='002ac4a6'/>
       </function-decl>
-      <function-decl name='_copy_from_iter' mangled-name='_copy_from_iter' filepath='lib/iov_iter.c' line='767' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_copy_from_iter'>
-        <parameter type-id='eaa32e2f' name='addr' filepath='lib/iov_iter.c' line='767' column='1'/>
-        <parameter type-id='b59d7dce' name='bytes' filepath='lib/iov_iter.c' line='767' column='1'/>
-        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='767' column='1'/>
+      <function-decl name='_copy_from_iter' mangled-name='_copy_from_iter' filepath='lib/iov_iter.c' line='753' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_copy_from_iter'>
+        <parameter type-id='eaa32e2f' name='addr' filepath='lib/iov_iter.c' line='753' column='1'/>
+        <parameter type-id='b59d7dce' name='bytes' filepath='lib/iov_iter.c' line='753' column='1'/>
+        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='753' column='1'/>
         <return type-id='b59d7dce'/>
       </function-decl>
-      <function-decl name='_copy_from_iter_full' mangled-name='_copy_from_iter_full' filepath='lib/iov_iter.c' line='787' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_copy_from_iter_full'>
-        <parameter type-id='eaa32e2f' name='addr' filepath='lib/iov_iter.c' line='787' column='1'/>
-        <parameter type-id='b59d7dce' name='bytes' filepath='lib/iov_iter.c' line='787' column='1'/>
-        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='787' column='1'/>
+      <function-decl name='_copy_from_iter_full' mangled-name='_copy_from_iter_full' filepath='lib/iov_iter.c' line='773' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_copy_from_iter_full'>
+        <parameter type-id='eaa32e2f' name='addr' filepath='lib/iov_iter.c' line='773' column='1'/>
+        <parameter type-id='b59d7dce' name='bytes' filepath='lib/iov_iter.c' line='773' column='1'/>
+        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='773' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='_copy_to_iter' mangled-name='_copy_to_iter' filepath='lib/iov_iter.c' line='632' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_copy_to_iter'>
-        <parameter type-id='eaa32e2f' name='addr' filepath='lib/iov_iter.c' line='632' column='1'/>
-        <parameter type-id='b59d7dce' name='bytes' filepath='lib/iov_iter.c' line='632' column='1'/>
-        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='632' column='1'/>
+      <function-decl name='_copy_to_iter' mangled-name='_copy_to_iter' filepath='lib/iov_iter.c' line='618' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_copy_to_iter'>
+        <parameter type-id='eaa32e2f' name='addr' filepath='lib/iov_iter.c' line='618' column='1'/>
+        <parameter type-id='b59d7dce' name='bytes' filepath='lib/iov_iter.c' line='618' column='1'/>
+        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='618' column='1'/>
         <return type-id='b59d7dce'/>
       </function-decl>
       <function-decl name='_dev_alert' mangled-name='_dev_alert' filepath='drivers/base/core.c' line='4504' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_dev_alert'>
@@ -121499,10 +122155,10 @@
         <parameter is-variadic='yes'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='_kstrtoul' mangled-name='_kstrtoul' filepath='lib/kstrtox.c' line='175' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_kstrtoul'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='175' column='1'/>
-        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='175' column='1'/>
-        <parameter type-id='1d2c2b85' name='res' filepath='lib/kstrtox.c' line='175' column='1'/>
+      <function-decl name='_kstrtoul' mangled-name='_kstrtoul' filepath='lib/kstrtox.c' line='176' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_kstrtoul'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='176' column='1'/>
+        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='176' column='1'/>
+        <parameter type-id='1d2c2b85' name='res' filepath='lib/kstrtox.c' line='176' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='_raw_read_lock' mangled-name='_raw_read_lock' filepath='kernel/locking/spinlock.c' line='221' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_raw_read_lock'>
@@ -121645,12 +122301,12 @@
         <parameter type-id='e0ea832a' name='lock' filepath='drivers/media/common/videobuf2/videobuf2-v4l2.c' line='1109' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='access_process_vm' mangled-name='access_process_vm' filepath='mm/memory.c' line='5644' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='access_process_vm'>
-        <parameter type-id='f23e2572' name='tsk' filepath='mm/memory.c' line='5644' column='1'/>
-        <parameter type-id='7359adad' name='addr' filepath='mm/memory.c' line='5644' column='1'/>
-        <parameter type-id='eaa32e2f' name='buf' filepath='mm/memory.c' line='5645' column='1'/>
-        <parameter type-id='95e97e5e' name='len' filepath='mm/memory.c' line='5645' column='1'/>
-        <parameter type-id='f0981eeb' name='gup_flags' filepath='mm/memory.c' line='5645' column='1'/>
+      <function-decl name='access_process_vm' mangled-name='access_process_vm' filepath='mm/memory.c' line='5658' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='access_process_vm'>
+        <parameter type-id='f23e2572' name='tsk' filepath='mm/memory.c' line='5658' column='1'/>
+        <parameter type-id='7359adad' name='addr' filepath='mm/memory.c' line='5658' column='1'/>
+        <parameter type-id='eaa32e2f' name='buf' filepath='mm/memory.c' line='5659' column='1'/>
+        <parameter type-id='95e97e5e' name='len' filepath='mm/memory.c' line='5659' column='1'/>
+        <parameter type-id='f0981eeb' name='gup_flags' filepath='mm/memory.c' line='5659' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='ack_all_badblocks' mangled-name='ack_all_badblocks' filepath='block/badblocks.c' line='433' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ack_all_badblocks'>
@@ -121689,16 +122345,16 @@
         <parameter type-id='b47c553a' name='rdy' filepath='drivers/char/random.c' line='1553' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='add_swap_extent' mangled-name='add_swap_extent' filepath='mm/swapfile.c' line='2374' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='add_swap_extent'>
-        <parameter type-id='11e11a61' name='sis' filepath='mm/swapfile.c' line='2374' column='1'/>
-        <parameter type-id='7359adad' name='start_page' filepath='mm/swapfile.c' line='2374' column='1'/>
-        <parameter type-id='7359adad' name='nr_pages' filepath='mm/swapfile.c' line='2375' column='1'/>
-        <parameter type-id='a42536cd' name='start_block' filepath='mm/swapfile.c' line='2375' column='1'/>
+      <function-decl name='add_swap_extent' mangled-name='add_swap_extent' filepath='mm/swapfile.c' line='2387' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='add_swap_extent'>
+        <parameter type-id='11e11a61' name='sis' filepath='mm/swapfile.c' line='2387' column='1'/>
+        <parameter type-id='7359adad' name='start_page' filepath='mm/swapfile.c' line='2387' column='1'/>
+        <parameter type-id='7359adad' name='nr_pages' filepath='mm/swapfile.c' line='2388' column='1'/>
+        <parameter type-id='a42536cd' name='start_block' filepath='mm/swapfile.c' line='2388' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='add_taint' mangled-name='add_taint' filepath='kernel/panic.c' line='441' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='add_taint'>
-        <parameter type-id='f0981eeb' name='flag' filepath='kernel/panic.c' line='441' column='1'/>
-        <parameter type-id='5da9c47b' name='lockdep_ok' filepath='kernel/panic.c' line='441' column='1'/>
+      <function-decl name='add_taint' mangled-name='add_taint' filepath='kernel/panic.c' line='518' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='add_taint'>
+        <parameter type-id='f0981eeb' name='flag' filepath='kernel/panic.c' line='518' column='1'/>
+        <parameter type-id='5da9c47b' name='lockdep_ok' filepath='kernel/panic.c' line='518' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='add_timer' mangled-name='add_timer' filepath='kernel/time/timer.c' line='1147' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='add_timer'>
@@ -121739,9 +122395,9 @@
         <parameter type-id='f57039f0' name='mapping' filepath='fs/inode.c' line='378' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='adjust_managed_page_count' mangled-name='adjust_managed_page_count' filepath='mm/page_alloc.c' line='7828' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='adjust_managed_page_count'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/page_alloc.c' line='7828' column='1'/>
-        <parameter type-id='bd54fe1a' name='count' filepath='mm/page_alloc.c' line='7828' column='1'/>
+      <function-decl name='adjust_managed_page_count' mangled-name='adjust_managed_page_count' filepath='mm/page_alloc.c' line='7877' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='adjust_managed_page_count'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/page_alloc.c' line='7877' column='1'/>
+        <parameter type-id='bd54fe1a' name='count' filepath='mm/page_alloc.c' line='7877' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='aead_register_instance' mangled-name='aead_register_instance' filepath='crypto/aead.c' line='286' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='aead_register_instance'>
@@ -121772,39 +122428,39 @@
         <parameter type-id='4e602d14' name='inst' filepath='crypto/ahash.c' line='633' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='alarm_cancel' mangled-name='alarm_cancel' filepath='kernel/time/alarmtimer.c' line='429' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alarm_cancel'>
-        <parameter type-id='be65fdd0' name='alarm' filepath='kernel/time/alarmtimer.c' line='429' column='1'/>
+      <function-decl name='alarm_cancel' mangled-name='alarm_cancel' filepath='kernel/time/alarmtimer.c' line='436' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alarm_cancel'>
+        <parameter type-id='be65fdd0' name='alarm' filepath='kernel/time/alarmtimer.c' line='436' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='alarm_init' mangled-name='alarm_init' filepath='kernel/time/alarmtimer.c' line='342' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alarm_init'>
-        <parameter type-id='be65fdd0' name='alarm' filepath='kernel/time/alarmtimer.c' line='342' column='1'/>
-        <parameter type-id='6b8d4b77' name='type' filepath='kernel/time/alarmtimer.c' line='342' column='1'/>
-        <parameter type-id='7432d5be' name='function' filepath='kernel/time/alarmtimer.c' line='343' column='1'/>
+      <function-decl name='alarm_init' mangled-name='alarm_init' filepath='kernel/time/alarmtimer.c' line='349' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alarm_init'>
+        <parameter type-id='be65fdd0' name='alarm' filepath='kernel/time/alarmtimer.c' line='349' column='1'/>
+        <parameter type-id='6b8d4b77' name='type' filepath='kernel/time/alarmtimer.c' line='349' column='1'/>
+        <parameter type-id='7432d5be' name='function' filepath='kernel/time/alarmtimer.c' line='350' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='alarm_start' mangled-name='alarm_start' filepath='kernel/time/alarmtimer.c' line='356' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alarm_start'>
-        <parameter type-id='be65fdd0' name='alarm' filepath='kernel/time/alarmtimer.c' line='356' column='1'/>
-        <parameter type-id='fbc017ef' name='start' filepath='kernel/time/alarmtimer.c' line='356' column='1'/>
+      <function-decl name='alarm_start' mangled-name='alarm_start' filepath='kernel/time/alarmtimer.c' line='363' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alarm_start'>
+        <parameter type-id='be65fdd0' name='alarm' filepath='kernel/time/alarmtimer.c' line='363' column='1'/>
+        <parameter type-id='fbc017ef' name='start' filepath='kernel/time/alarmtimer.c' line='363' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='alarm_start_relative' mangled-name='alarm_start_relative' filepath='kernel/time/alarmtimer.c' line='376' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alarm_start_relative'>
-        <parameter type-id='be65fdd0' name='alarm' filepath='kernel/time/alarmtimer.c' line='376' column='1'/>
-        <parameter type-id='fbc017ef' name='start' filepath='kernel/time/alarmtimer.c' line='376' column='1'/>
+      <function-decl name='alarm_start_relative' mangled-name='alarm_start_relative' filepath='kernel/time/alarmtimer.c' line='383' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alarm_start_relative'>
+        <parameter type-id='be65fdd0' name='alarm' filepath='kernel/time/alarmtimer.c' line='383' column='1'/>
+        <parameter type-id='fbc017ef' name='start' filepath='kernel/time/alarmtimer.c' line='383' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='alarm_try_to_cancel' mangled-name='alarm_try_to_cancel' filepath='kernel/time/alarmtimer.c' line='405' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alarm_try_to_cancel'>
-        <parameter type-id='be65fdd0' name='alarm' filepath='kernel/time/alarmtimer.c' line='405' column='1'/>
+      <function-decl name='alarm_try_to_cancel' mangled-name='alarm_try_to_cancel' filepath='kernel/time/alarmtimer.c' line='412' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alarm_try_to_cancel'>
+        <parameter type-id='be65fdd0' name='alarm' filepath='kernel/time/alarmtimer.c' line='412' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='alarmtimer_get_rtcdev' mangled-name='alarmtimer_get_rtcdev' filepath='kernel/time/alarmtimer.c' line='71' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alarmtimer_get_rtcdev'>
+      <function-decl name='alarmtimer_get_rtcdev' mangled-name='alarmtimer_get_rtcdev' filepath='kernel/time/alarmtimer.c' line='73' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alarmtimer_get_rtcdev'>
         <return type-id='5992ae83'/>
       </function-decl>
       <function-decl name='all_vm_events' mangled-name='all_vm_events' filepath='mm/vmstat.c' line='131' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='all_vm_events'>
         <parameter type-id='1d2c2b85' name='ret' filepath='mm/vmstat.c' line='131' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='alloc_anon_inode' mangled-name='alloc_anon_inode' filepath='fs/libfs.c' line='1217' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alloc_anon_inode'>
-        <parameter type-id='42c8f564' name='s' filepath='fs/libfs.c' line='1217' column='1'/>
+      <function-decl name='alloc_anon_inode' mangled-name='alloc_anon_inode' filepath='fs/libfs.c' line='1233' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alloc_anon_inode'>
+        <parameter type-id='42c8f564' name='s' filepath='fs/libfs.c' line='1233' column='1'/>
         <return type-id='7e666abe'/>
       </function-decl>
       <function-decl name='alloc_can_err_skb' mangled-name='alloc_can_err_skb' filepath='drivers/net/can/dev/dev.c' line='731' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alloc_can_err_skb'>
@@ -121850,13 +122506,13 @@
         <parameter type-id='b50a4934' name='flush_rcache' filepath='drivers/iommu/iova.c' line='512' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='alloc_netdev_mqs' mangled-name='alloc_netdev_mqs' filepath='net/core/dev.c' line='10461' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alloc_netdev_mqs'>
-        <parameter type-id='95e97e5e' name='sizeof_priv' filepath='net/core/dev.c' line='10461' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='net/core/dev.c' line='10461' column='1'/>
-        <parameter type-id='002ac4a6' name='name_assign_type' filepath='net/core/dev.c' line='10462' column='1'/>
-        <parameter type-id='548eee3a' name='setup' filepath='net/core/dev.c' line='10463' column='1'/>
-        <parameter type-id='f0981eeb' name='txqs' filepath='net/core/dev.c' line='10464' column='1'/>
-        <parameter type-id='f0981eeb' name='rxqs' filepath='net/core/dev.c' line='10464' column='1'/>
+      <function-decl name='alloc_netdev_mqs' mangled-name='alloc_netdev_mqs' filepath='net/core/dev.c' line='10466' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alloc_netdev_mqs'>
+        <parameter type-id='95e97e5e' name='sizeof_priv' filepath='net/core/dev.c' line='10466' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='net/core/dev.c' line='10466' column='1'/>
+        <parameter type-id='002ac4a6' name='name_assign_type' filepath='net/core/dev.c' line='10467' column='1'/>
+        <parameter type-id='548eee3a' name='setup' filepath='net/core/dev.c' line='10468' column='1'/>
+        <parameter type-id='f0981eeb' name='txqs' filepath='net/core/dev.c' line='10469' column='1'/>
+        <parameter type-id='f0981eeb' name='rxqs' filepath='net/core/dev.c' line='10469' column='1'/>
         <return type-id='68a2d05b'/>
       </function-decl>
       <function-decl name='alloc_page_buffers' mangled-name='alloc_page_buffers' filepath='fs/buffer.c' line='839' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alloc_page_buffers'>
@@ -121865,23 +122521,23 @@
         <parameter type-id='b50a4934' name='retry' filepath='fs/buffer.c' line='840' column='1'/>
         <return type-id='c485c22c'/>
       </function-decl>
-      <function-decl name='alloc_pages_exact' mangled-name='alloc_pages_exact' filepath='mm/page_alloc.c' line='5411' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alloc_pages_exact'>
-        <parameter type-id='b59d7dce' name='size' filepath='mm/page_alloc.c' line='5411' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/page_alloc.c' line='5411' column='1'/>
+      <function-decl name='alloc_pages_exact' mangled-name='alloc_pages_exact' filepath='mm/page_alloc.c' line='5443' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alloc_pages_exact'>
+        <parameter type-id='b59d7dce' name='size' filepath='mm/page_alloc.c' line='5443' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/page_alloc.c' line='5443' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='alloc_skb_with_frags' mangled-name='alloc_skb_with_frags' filepath='net/core/skbuff.c' line='5899' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alloc_skb_with_frags'>
-        <parameter type-id='7359adad' name='header_len' filepath='net/core/skbuff.c' line='5899' column='1'/>
-        <parameter type-id='7359adad' name='data_len' filepath='net/core/skbuff.c' line='5900' column='1'/>
-        <parameter type-id='95e97e5e' name='max_page_order' filepath='net/core/skbuff.c' line='5901' column='1'/>
-        <parameter type-id='7292109c' name='errcode' filepath='net/core/skbuff.c' line='5902' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='5903' column='1'/>
+      <function-decl name='alloc_skb_with_frags' mangled-name='alloc_skb_with_frags' filepath='net/core/skbuff.c' line='5904' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alloc_skb_with_frags'>
+        <parameter type-id='7359adad' name='header_len' filepath='net/core/skbuff.c' line='5904' column='1'/>
+        <parameter type-id='7359adad' name='data_len' filepath='net/core/skbuff.c' line='5905' column='1'/>
+        <parameter type-id='95e97e5e' name='max_page_order' filepath='net/core/skbuff.c' line='5906' column='1'/>
+        <parameter type-id='7292109c' name='errcode' filepath='net/core/skbuff.c' line='5907' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='5908' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
-      <function-decl name='alloc_workqueue' mangled-name='alloc_workqueue' filepath='kernel/workqueue.c' line='4276' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alloc_workqueue'>
-        <parameter type-id='80f4b756' name='fmt' filepath='kernel/workqueue.c' line='4276' column='1'/>
-        <parameter type-id='f0981eeb' name='flags' filepath='kernel/workqueue.c' line='4277' column='1'/>
-        <parameter type-id='95e97e5e' name='max_active' filepath='kernel/workqueue.c' line='4278' column='1'/>
+      <function-decl name='alloc_workqueue' mangled-name='alloc_workqueue' filepath='kernel/workqueue.c' line='4279' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='alloc_workqueue'>
+        <parameter type-id='80f4b756' name='fmt' filepath='kernel/workqueue.c' line='4279' column='1'/>
+        <parameter type-id='f0981eeb' name='flags' filepath='kernel/workqueue.c' line='4280' column='1'/>
+        <parameter type-id='95e97e5e' name='max_active' filepath='kernel/workqueue.c' line='4281' column='1'/>
         <parameter is-variadic='yes'/>
         <return type-id='242e3d19'/>
       </function-decl>
@@ -121903,9 +122559,9 @@
         <parameter type-id='80f4b756' name='name' filepath='drivers/amba/bus.c' line='794' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='android_debug_for_each_module' mangled-name='android_debug_for_each_module' filepath='kernel/module.c' line='4785' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='android_debug_for_each_module'>
-        <parameter type-id='841286fc' name='fn' filepath='kernel/module.c' line='4785' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='kernel/module.c' line='4786' column='1'/>
+      <function-decl name='android_debug_for_each_module' mangled-name='android_debug_for_each_module' filepath='kernel/module.c' line='4801' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='android_debug_for_each_module'>
+        <parameter type-id='841286fc' name='fn' filepath='kernel/module.c' line='4801' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='kernel/module.c' line='4802' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='android_debug_per_cpu_symbol' mangled-name='android_debug_per_cpu_symbol' filepath='drivers/android/debug_symbols.c' line='110' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='android_debug_per_cpu_symbol'>
@@ -121949,7 +122605,7 @@
         <parameter type-id='f0981eeb' name='key_len' filepath='lib/crypto/arc4.c' line='13' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='arch_mmap_rnd' mangled-name='arch_mmap_rnd' filepath='mm/util.c' line='379' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='arch_mmap_rnd'>
+      <function-decl name='arch_mmap_rnd' mangled-name='arch_mmap_rnd' filepath='mm/util.c' line='380' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='arch_mmap_rnd'>
         <return type-id='7359adad'/>
       </function-decl>
       <var-decl name='arch_timer_read_counter' type-id='0e70db3e' mangled-name='arch_timer_read_counter' visibility='default' filepath='drivers/clocksource/arm_arch_timer.c' line='179' column='1' elf-symbol-id='arch_timer_read_counter'/>
@@ -121964,6 +122620,10 @@
         <return type-id='9b23c9ad'/>
       </function-decl>
       <var-decl name='arm64_const_caps_ready' type-id='237c0d27' mangled-name='arm64_const_caps_ready' visibility='default' filepath='arch/arm64/kernel/cpufeature.c' line='143' column='1' elf-symbol-id='arm64_const_caps_ready'/>
+      <function-decl name='arm64_noalias_setup_dma_ops' mangled-name='arm64_noalias_setup_dma_ops' filepath='arch/arm64/mm/dma-mapping-noalias.c' line='550' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='arm64_noalias_setup_dma_ops'>
+        <parameter type-id='fa0b179b' name='dev' filepath='arch/arm64/mm/dma-mapping-noalias.c' line='550' column='1'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
       <var-decl name='arm64_use_ng_mappings' type-id='b50a4934' mangled-name='arm64_use_ng_mappings' visibility='default' filepath='arch/arm64/kernel/cpufeature.c' line='111' column='1' elf-symbol-id='arm64_use_ng_mappings'/>
       <var-decl name='arp_tbl' type-id='aebe1cff' mangled-name='arp_tbl' visibility='default' filepath='net/ipv4/arp.c' line='152' column='1' elf-symbol-id='arp_tbl'/>
       <function-decl name='async_schedule_node' mangled-name='async_schedule_node' filepath='kernel/async.c' line='228' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='async_schedule_node'>
@@ -122006,8 +122666,8 @@
         <parameter type-id='eaa32e2f' name='key' filepath='kernel/sched/wait.c' line='404' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='available_idle_cpu' mangled-name='available_idle_cpu' filepath='kernel/sched/core.c' line='5383' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='available_idle_cpu'>
-        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/sched/core.c' line='5383' column='1'/>
+      <function-decl name='available_idle_cpu' mangled-name='available_idle_cpu' filepath='kernel/sched/core.c' line='5385' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='available_idle_cpu'>
+        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/sched/core.c' line='5385' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <var-decl name='avenrun' type-id='3461381a' mangled-name='avenrun' visibility='default' filepath='kernel/sched/loadavg.c' line='61' column='1' elf-symbol-id='avenrun'/>
@@ -122123,17 +122783,17 @@
         <parameter type-id='95e97e5e' name='partno' filepath='block/genhd.c' line='1048' column='1'/>
         <return type-id='b88dd945'/>
       </function-decl>
-      <function-decl name='bdi_alloc' mangled-name='bdi_alloc' filepath='mm/backing-dev.c' line='734' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bdi_alloc'>
-        <parameter type-id='95e97e5e' name='node_id' filepath='mm/backing-dev.c' line='734' column='1'/>
+      <function-decl name='bdi_alloc' mangled-name='bdi_alloc' filepath='mm/backing-dev.c' line='742' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bdi_alloc'>
+        <parameter type-id='95e97e5e' name='node_id' filepath='mm/backing-dev.c' line='742' column='1'/>
         <return type-id='ef4fae1b'/>
       </function-decl>
-      <function-decl name='bdi_put' mangled-name='bdi_put' filepath='mm/backing-dev.c' line='906' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bdi_put'>
-        <parameter type-id='ef4fae1b' name='bdi' filepath='mm/backing-dev.c' line='906' column='1'/>
+      <function-decl name='bdi_put' mangled-name='bdi_put' filepath='mm/backing-dev.c' line='914' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bdi_put'>
+        <parameter type-id='ef4fae1b' name='bdi' filepath='mm/backing-dev.c' line='914' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bdi_register' mangled-name='bdi_register' filepath='mm/backing-dev.c' line='836' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bdi_register'>
-        <parameter type-id='ef4fae1b' name='bdi' filepath='mm/backing-dev.c' line='836' column='1'/>
-        <parameter type-id='80f4b756' name='fmt' filepath='mm/backing-dev.c' line='836' column='1'/>
+      <function-decl name='bdi_register' mangled-name='bdi_register' filepath='mm/backing-dev.c' line='844' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bdi_register'>
+        <parameter type-id='ef4fae1b' name='bdi' filepath='mm/backing-dev.c' line='844' column='1'/>
+        <parameter type-id='80f4b756' name='fmt' filepath='mm/backing-dev.c' line='844' column='1'/>
         <parameter is-variadic='yes'/>
         <return type-id='95e97e5e'/>
       </function-decl>
@@ -122180,13 +122840,13 @@
         <parameter type-id='38b1e3a0' name='bs' filepath='block/bio.c' line='438' column='1'/>
         <return type-id='fb55efa1'/>
       </function-decl>
-      <function-decl name='bio_associate_blkg' mangled-name='bio_associate_blkg' filepath='block/blk-cgroup.c' line='1877' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bio_associate_blkg'>
-        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-cgroup.c' line='1877' column='1'/>
+      <function-decl name='bio_associate_blkg' mangled-name='bio_associate_blkg' filepath='block/blk-cgroup.c' line='1882' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bio_associate_blkg'>
+        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-cgroup.c' line='1882' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bio_associate_blkg_from_css' mangled-name='bio_associate_blkg_from_css' filepath='block/blk-cgroup.c' line='1853' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bio_associate_blkg_from_css'>
-        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-cgroup.c' line='1853' column='1'/>
-        <parameter type-id='cfff5953' name='css' filepath='block/blk-cgroup.c' line='1854' column='1'/>
+      <function-decl name='bio_associate_blkg_from_css' mangled-name='bio_associate_blkg_from_css' filepath='block/blk-cgroup.c' line='1858' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bio_associate_blkg_from_css'>
+        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-cgroup.c' line='1858' column='1'/>
+        <parameter type-id='cfff5953' name='css' filepath='block/blk-cgroup.c' line='1859' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='bio_chain' mangled-name='bio_chain' filepath='block/bio.c' line='338' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bio_chain'>
@@ -122194,16 +122854,16 @@
         <parameter type-id='fb55efa1' name='parent' filepath='block/bio.c' line='338' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bio_clone_blkg_association' mangled-name='bio_clone_blkg_association' filepath='block/blk-cgroup.c' line='1899' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bio_clone_blkg_association'>
-        <parameter type-id='fb55efa1' name='dst' filepath='block/blk-cgroup.c' line='1899' column='1'/>
-        <parameter type-id='fb55efa1' name='src' filepath='block/blk-cgroup.c' line='1899' column='1'/>
+      <function-decl name='bio_clone_blkg_association' mangled-name='bio_clone_blkg_association' filepath='block/blk-cgroup.c' line='1904' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bio_clone_blkg_association'>
+        <parameter type-id='fb55efa1' name='dst' filepath='block/blk-cgroup.c' line='1904' column='1'/>
+        <parameter type-id='fb55efa1' name='src' filepath='block/blk-cgroup.c' line='1904' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bio_crypt_set_ctx' mangled-name='bio_crypt_set_ctx' filepath='block/blk-crypto.c' line='81' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bio_crypt_set_ctx'>
-        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-crypto.c' line='81' column='1'/>
-        <parameter type-id='9baaf905' name='key' filepath='block/blk-crypto.c' line='81' column='1'/>
-        <parameter type-id='c8fec899' name='dun' filepath='block/blk-crypto.c' line='82' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='block/blk-crypto.c' line='82' column='1'/>
+      <function-decl name='bio_crypt_set_ctx' mangled-name='bio_crypt_set_ctx' filepath='block/blk-crypto.c' line='82' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bio_crypt_set_ctx'>
+        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-crypto.c' line='82' column='1'/>
+        <parameter type-id='9baaf905' name='key' filepath='block/blk-crypto.c' line='82' column='1'/>
+        <parameter type-id='c8fec899' name='dun' filepath='block/blk-crypto.c' line='83' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='block/blk-crypto.c' line='83' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='bio_endio' mangled-name='bio_endio' filepath='block/bio.c' line='1426' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bio_endio'>
@@ -122336,17 +122996,17 @@
         <parameter type-id='95e97e5e' name='node_id' filepath='block/blk-core.c' line='523' column='1'/>
         <return type-id='e7d2a5fc'/>
       </function-decl>
-      <function-decl name='blk_bio_list_merge' mangled-name='blk_bio_list_merge' filepath='block/blk-merge.c' line='1092' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_bio_list_merge'>
-        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-merge.c' line='1092' column='1'/>
-        <parameter type-id='e84b031a' name='list' filepath='block/blk-merge.c' line='1092' column='1'/>
-        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-merge.c' line='1093' column='1'/>
-        <parameter type-id='f0981eeb' name='nr_segs' filepath='block/blk-merge.c' line='1093' column='1'/>
+      <function-decl name='blk_bio_list_merge' mangled-name='blk_bio_list_merge' filepath='block/blk-merge.c' line='1094' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_bio_list_merge'>
+        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-merge.c' line='1094' column='1'/>
+        <parameter type-id='e84b031a' name='list' filepath='block/blk-merge.c' line='1094' column='1'/>
+        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-merge.c' line='1095' column='1'/>
+        <parameter type-id='f0981eeb' name='nr_segs' filepath='block/blk-merge.c' line='1095' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='blk_check_plugged' mangled-name='blk_check_plugged' filepath='block/blk-core.c' line='1734' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_check_plugged'>
-        <parameter type-id='f31816b5' name='unplug' filepath='block/blk-core.c' line='1734' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='block/blk-core.c' line='1734' column='1'/>
-        <parameter type-id='95e97e5e' name='size' filepath='block/blk-core.c' line='1735' column='1'/>
+      <function-decl name='blk_check_plugged' mangled-name='blk_check_plugged' filepath='block/blk-core.c' line='1739' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_check_plugged'>
+        <parameter type-id='f31816b5' name='unplug' filepath='block/blk-core.c' line='1739' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='block/blk-core.c' line='1739' column='1'/>
+        <parameter type-id='95e97e5e' name='size' filepath='block/blk-core.c' line='1740' column='1'/>
         <return type-id='39914f13'/>
       </function-decl>
       <function-decl name='blk_cleanup_queue' mangled-name='blk_cleanup_queue' filepath='block/blk-core.c' line='376' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_cleanup_queue'>
@@ -122368,8 +123028,8 @@
         <parameter type-id='5afdaa66' name='done' filepath='block/blk-exec.c' line='50' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_finish_plug' mangled-name='blk_finish_plug' filepath='block/blk-core.c' line='1777' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_finish_plug'>
-        <parameter type-id='39944481' name='plug' filepath='block/blk-core.c' line='1777' column='1'/>
+      <function-decl name='blk_finish_plug' mangled-name='blk_finish_plug' filepath='block/blk-core.c' line='1782' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_finish_plug'>
+        <parameter type-id='39944481' name='plug' filepath='block/blk-core.c' line='1782' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='blk_freeze_queue_start' mangled-name='blk_freeze_queue_start' filepath='block/blk-mq.c' line='136' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_freeze_queue_start'>
@@ -122386,9 +123046,9 @@
         <parameter type-id='346d62be' name='flags' filepath='block/blk-core.c' line='634' column='1'/>
         <return type-id='3dad1a48'/>
       </function-decl>
-      <function-decl name='blk_insert_cloned_request' mangled-name='blk_insert_cloned_request' filepath='block/blk-core.c' line='1199' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_insert_cloned_request'>
-        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-core.c' line='1199' column='1'/>
-        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-core.c' line='1199' column='1'/>
+      <function-decl name='blk_insert_cloned_request' mangled-name='blk_insert_cloned_request' filepath='block/blk-core.c' line='1197' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_insert_cloned_request'>
+        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-core.c' line='1197' column='1'/>
+        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-core.c' line='1197' column='1'/>
         <return type-id='f4e2facd'/>
       </function-decl>
       <function-decl name='blk_ksm_get_slot_idx' mangled-name='blk_ksm_get_slot_idx' filepath='block/keyslot-manager.c' line='211' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_ksm_get_slot_idx'>
@@ -122400,17 +123060,17 @@
         <parameter type-id='f0981eeb' name='num_slots' filepath='block/keyslot-manager.c' line='81' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='blk_ksm_init_passthrough' mangled-name='blk_ksm_init_passthrough' filepath='block/keyslot-manager.c' line='625' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_ksm_init_passthrough'>
-        <parameter type-id='bf8a20d2' name='ksm' filepath='block/keyslot-manager.c' line='625' column='1'/>
+      <function-decl name='blk_ksm_init_passthrough' mangled-name='blk_ksm_init_passthrough' filepath='block/keyslot-manager.c' line='624' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_ksm_init_passthrough'>
+        <parameter type-id='bf8a20d2' name='ksm' filepath='block/keyslot-manager.c' line='624' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_ksm_register' mangled-name='blk_ksm_register' filepath='block/keyslot-manager.c' line='447' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_ksm_register'>
-        <parameter type-id='bf8a20d2' name='ksm' filepath='block/keyslot-manager.c' line='447' column='1'/>
-        <parameter type-id='e7d2a5fc' name='q' filepath='block/keyslot-manager.c' line='447' column='1'/>
+      <function-decl name='blk_ksm_register' mangled-name='blk_ksm_register' filepath='block/keyslot-manager.c' line='446' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_ksm_register'>
+        <parameter type-id='bf8a20d2' name='ksm' filepath='block/keyslot-manager.c' line='446' column='1'/>
+        <parameter type-id='e7d2a5fc' name='q' filepath='block/keyslot-manager.c' line='446' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='blk_ksm_reprogram_all_keys' mangled-name='blk_ksm_reprogram_all_keys' filepath='block/keyslot-manager.c' line='414' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_ksm_reprogram_all_keys'>
-        <parameter type-id='bf8a20d2' name='ksm' filepath='block/keyslot-manager.c' line='414' column='1'/>
+      <function-decl name='blk_ksm_reprogram_all_keys' mangled-name='blk_ksm_reprogram_all_keys' filepath='block/keyslot-manager.c' line='413' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_ksm_reprogram_all_keys'>
+        <parameter type-id='bf8a20d2' name='ksm' filepath='block/keyslot-manager.c' line='413' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='blk_mq_alloc_request' mangled-name='blk_mq_alloc_request' filepath='block/blk-mq.c' line='403' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_alloc_request'>
@@ -122426,16 +123086,16 @@
         <parameter type-id='f0981eeb' name='hctx_idx' filepath='block/blk-mq.c' line='432' column='1'/>
         <return type-id='3dad1a48'/>
       </function-decl>
-      <function-decl name='blk_mq_alloc_tag_set' mangled-name='blk_mq_alloc_tag_set' filepath='block/blk-mq.c' line='3513' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_alloc_tag_set'>
-        <parameter type-id='cc26d15f' name='set' filepath='block/blk-mq.c' line='3513' column='1'/>
+      <function-decl name='blk_mq_alloc_tag_set' mangled-name='blk_mq_alloc_tag_set' filepath='block/blk-mq.c' line='3514' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_alloc_tag_set'>
+        <parameter type-id='cc26d15f' name='set' filepath='block/blk-mq.c' line='3514' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='blk_mq_complete_request' mangled-name='blk_mq_complete_request' filepath='block/blk-mq.c' line='701' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_complete_request'>
-        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='701' column='1'/>
+      <function-decl name='blk_mq_complete_request' mangled-name='blk_mq_complete_request' filepath='block/blk-mq.c' line='702' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_complete_request'>
+        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='702' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_mq_complete_request_remote' mangled-name='blk_mq_complete_request_remote' filepath='block/blk-mq.c' line='668' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_complete_request_remote'>
-        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='668' column='1'/>
+      <function-decl name='blk_mq_complete_request_remote' mangled-name='blk_mq_complete_request_remote' filepath='block/blk-mq.c' line='669' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_complete_request_remote'>
+        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='669' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='blk_mq_debugfs_rq_show' mangled-name='blk_mq_debugfs_rq_show' filepath='block/blk-mq-debugfs.c' line='358' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_debugfs_rq_show'>
@@ -122443,22 +123103,22 @@
         <parameter type-id='eaa32e2f' name='v' filepath='block/blk-mq-debugfs.c' line='358' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='blk_mq_delay_kick_requeue_list' mangled-name='blk_mq_delay_kick_requeue_list' filepath='block/blk-mq.c' line='855' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_delay_kick_requeue_list'>
-        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-mq.c' line='855' column='1'/>
-        <parameter type-id='7359adad' name='msecs' filepath='block/blk-mq.c' line='856' column='1'/>
+      <function-decl name='blk_mq_delay_kick_requeue_list' mangled-name='blk_mq_delay_kick_requeue_list' filepath='block/blk-mq.c' line='856' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_delay_kick_requeue_list'>
+        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-mq.c' line='856' column='1'/>
+        <parameter type-id='7359adad' name='msecs' filepath='block/blk-mq.c' line='857' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_mq_end_request' mangled-name='blk_mq_end_request' filepath='block/blk-mq.c' line='566' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_end_request'>
-        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='566' column='1'/>
-        <parameter type-id='f4e2facd' name='error' filepath='block/blk-mq.c' line='566' column='1'/>
+      <function-decl name='blk_mq_end_request' mangled-name='blk_mq_end_request' filepath='block/blk-mq.c' line='567' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_end_request'>
+        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='567' column='1'/>
+        <parameter type-id='f4e2facd' name='error' filepath='block/blk-mq.c' line='567' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_mq_free_request' mangled-name='blk_mq_free_request' filepath='block/blk-mq.c' line='510' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_free_request'>
-        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='510' column='1'/>
+      <function-decl name='blk_mq_free_request' mangled-name='blk_mq_free_request' filepath='block/blk-mq.c' line='511' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_free_request'>
+        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='511' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_mq_free_tag_set' mangled-name='blk_mq_free_tag_set' filepath='block/blk-mq.c' line='3609' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_free_tag_set'>
-        <parameter type-id='cc26d15f' name='set' filepath='block/blk-mq.c' line='3609' column='1'/>
+      <function-decl name='blk_mq_free_tag_set' mangled-name='blk_mq_free_tag_set' filepath='block/blk-mq.c' line='3610' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_free_tag_set'>
+        <parameter type-id='cc26d15f' name='set' filepath='block/blk-mq.c' line='3610' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='blk_mq_freeze_queue' mangled-name='blk_mq_freeze_queue' filepath='block/blk-mq.c' line='182' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_freeze_queue'>
@@ -122474,15 +123134,15 @@
         <parameter type-id='7359adad' name='timeout' filepath='block/blk-mq.c' line='157' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='blk_mq_init_queue' mangled-name='blk_mq_init_queue' filepath='block/blk-mq.c' line='3160' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_init_queue'>
-        <parameter type-id='cc26d15f' name='set' filepath='block/blk-mq.c' line='3160' column='1'/>
+      <function-decl name='blk_mq_init_queue' mangled-name='blk_mq_init_queue' filepath='block/blk-mq.c' line='3161' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_init_queue'>
+        <parameter type-id='cc26d15f' name='set' filepath='block/blk-mq.c' line='3161' column='1'/>
         <return type-id='e7d2a5fc'/>
       </function-decl>
-      <function-decl name='blk_mq_init_sq_queue' mangled-name='blk_mq_init_sq_queue' filepath='block/blk-mq.c' line='3170' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_init_sq_queue'>
-        <parameter type-id='cc26d15f' name='set' filepath='block/blk-mq.c' line='3170' column='1'/>
-        <parameter type-id='e1962c5d' name='ops' filepath='block/blk-mq.c' line='3171' column='1'/>
-        <parameter type-id='f0981eeb' name='queue_depth' filepath='block/blk-mq.c' line='3172' column='1'/>
-        <parameter type-id='f0981eeb' name='set_flags' filepath='block/blk-mq.c' line='3173' column='1'/>
+      <function-decl name='blk_mq_init_sq_queue' mangled-name='blk_mq_init_sq_queue' filepath='block/blk-mq.c' line='3171' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_init_sq_queue'>
+        <parameter type-id='cc26d15f' name='set' filepath='block/blk-mq.c' line='3171' column='1'/>
+        <parameter type-id='e1962c5d' name='ops' filepath='block/blk-mq.c' line='3172' column='1'/>
+        <parameter type-id='f0981eeb' name='queue_depth' filepath='block/blk-mq.c' line='3173' column='1'/>
+        <parameter type-id='f0981eeb' name='set_flags' filepath='block/blk-mq.c' line='3174' column='1'/>
         <return type-id='e7d2a5fc'/>
       </function-decl>
       <function-decl name='blk_mq_map_queues' mangled-name='blk_mq_map_queues' filepath='block/blk-mq-cpumap.c' line='35' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_map_queues'>
@@ -122495,69 +123155,69 @@
         <parameter type-id='95e97e5e' name='offset' filepath='block/blk-mq-pci.c' line='27' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='blk_mq_queue_inflight' mangled-name='blk_mq_queue_inflight' filepath='block/blk-mq.c' line='891' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_queue_inflight'>
-        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-mq.c' line='891' column='1'/>
+      <function-decl name='blk_mq_queue_inflight' mangled-name='blk_mq_queue_inflight' filepath='block/blk-mq.c' line='892' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_queue_inflight'>
+        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-mq.c' line='892' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='blk_mq_quiesce_queue' mangled-name='blk_mq_quiesce_queue' filepath='block/blk-mq.c' line='224' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_quiesce_queue'>
         <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-mq.c' line='224' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_mq_requeue_request' mangled-name='blk_mq_requeue_request' filepath='block/blk-mq.c' line='776' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_requeue_request'>
-        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='776' column='1'/>
-        <parameter type-id='b50a4934' name='kick_requeue_list' filepath='block/blk-mq.c' line='776' column='1'/>
+      <function-decl name='blk_mq_requeue_request' mangled-name='blk_mq_requeue_request' filepath='block/blk-mq.c' line='777' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_requeue_request'>
+        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='777' column='1'/>
+        <parameter type-id='b50a4934' name='kick_requeue_list' filepath='block/blk-mq.c' line='777' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_mq_rq_cpu' mangled-name='blk_mq_rq_cpu' filepath='block/blk-mq.c' line='4030' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_rq_cpu'>
-        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='4030' column='1'/>
+      <function-decl name='blk_mq_rq_cpu' mangled-name='blk_mq_rq_cpu' filepath='block/blk-mq.c' line='4031' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_rq_cpu'>
+        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='4031' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='blk_mq_run_hw_queue' mangled-name='blk_mq_run_hw_queue' filepath='block/blk-mq.c' line='1635' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_run_hw_queue'>
-        <parameter type-id='a47d3467' name='hctx' filepath='block/blk-mq.c' line='1635' column='1'/>
-        <parameter type-id='b50a4934' name='async' filepath='block/blk-mq.c' line='1635' column='1'/>
+      <function-decl name='blk_mq_run_hw_queue' mangled-name='blk_mq_run_hw_queue' filepath='block/blk-mq.c' line='1636' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_run_hw_queue'>
+        <parameter type-id='a47d3467' name='hctx' filepath='block/blk-mq.c' line='1636' column='1'/>
+        <parameter type-id='b50a4934' name='async' filepath='block/blk-mq.c' line='1636' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_mq_run_hw_queues' mangled-name='blk_mq_run_hw_queues' filepath='block/blk-mq.c' line='1698' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_run_hw_queues'>
-        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-mq.c' line='1698' column='1'/>
-        <parameter type-id='b50a4934' name='async' filepath='block/blk-mq.c' line='1698' column='1'/>
+      <function-decl name='blk_mq_run_hw_queues' mangled-name='blk_mq_run_hw_queues' filepath='block/blk-mq.c' line='1699' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_run_hw_queues'>
+        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-mq.c' line='1699' column='1'/>
+        <parameter type-id='b50a4934' name='async' filepath='block/blk-mq.c' line='1699' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_mq_sched_mark_restart_hctx' mangled-name='blk_mq_sched_mark_restart_hctx' filepath='block/blk-mq-sched.c' line='51' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_sched_mark_restart_hctx'>
-        <parameter type-id='a47d3467' name='hctx' filepath='block/blk-mq-sched.c' line='51' column='1'/>
+      <function-decl name='blk_mq_sched_mark_restart_hctx' mangled-name='blk_mq_sched_mark_restart_hctx' filepath='block/blk-mq-sched.c' line='50' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_sched_mark_restart_hctx'>
+        <parameter type-id='a47d3467' name='hctx' filepath='block/blk-mq-sched.c' line='50' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_mq_sched_request_inserted' mangled-name='blk_mq_sched_request_inserted' filepath='block/blk-mq-sched.c' line='396' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_sched_request_inserted'>
-        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq-sched.c' line='396' column='1'/>
+      <function-decl name='blk_mq_sched_request_inserted' mangled-name='blk_mq_sched_request_inserted' filepath='block/blk-mq-sched.c' line='395' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_sched_request_inserted'>
+        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq-sched.c' line='395' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_mq_sched_try_insert_merge' mangled-name='blk_mq_sched_try_insert_merge' filepath='block/blk-mq-sched.c' line='390' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_sched_try_insert_merge'>
-        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-mq-sched.c' line='390' column='1'/>
-        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq-sched.c' line='390' column='1'/>
+      <function-decl name='blk_mq_sched_try_insert_merge' mangled-name='blk_mq_sched_try_insert_merge' filepath='block/blk-mq-sched.c' line='389' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_sched_try_insert_merge'>
+        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-mq-sched.c' line='389' column='1'/>
+        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq-sched.c' line='389' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='blk_mq_sched_try_merge' mangled-name='blk_mq_sched_try_merge' filepath='block/blk-merge.c' line='1117' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_sched_try_merge'>
-        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-merge.c' line='1117' column='1'/>
-        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-merge.c' line='1117' column='1'/>
-        <parameter type-id='f0981eeb' name='nr_segs' filepath='block/blk-merge.c' line='1118' column='1'/>
-        <parameter type-id='79808846' name='merged_request' filepath='block/blk-merge.c' line='1118' column='1'/>
+      <function-decl name='blk_mq_sched_try_merge' mangled-name='blk_mq_sched_try_merge' filepath='block/blk-merge.c' line='1119' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_sched_try_merge'>
+        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-merge.c' line='1119' column='1'/>
+        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-merge.c' line='1119' column='1'/>
+        <parameter type-id='f0981eeb' name='nr_segs' filepath='block/blk-merge.c' line='1120' column='1'/>
+        <parameter type-id='79808846' name='merged_request' filepath='block/blk-merge.c' line='1120' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='blk_mq_start_request' mangled-name='blk_mq_start_request' filepath='block/blk-mq.c' line='736' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_start_request'>
-        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='736' column='1'/>
+      <function-decl name='blk_mq_start_request' mangled-name='blk_mq_start_request' filepath='block/blk-mq.c' line='737' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_start_request'>
+        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-mq.c' line='737' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_mq_start_stopped_hw_queues' mangled-name='blk_mq_start_stopped_hw_queues' filepath='block/blk-mq.c' line='1833' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_start_stopped_hw_queues'>
-        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-mq.c' line='1833' column='1'/>
-        <parameter type-id='b50a4934' name='async' filepath='block/blk-mq.c' line='1833' column='1'/>
+      <function-decl name='blk_mq_start_stopped_hw_queues' mangled-name='blk_mq_start_stopped_hw_queues' filepath='block/blk-mq.c' line='1834' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_start_stopped_hw_queues'>
+        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-mq.c' line='1834' column='1'/>
+        <parameter type-id='b50a4934' name='async' filepath='block/blk-mq.c' line='1834' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_mq_stop_hw_queue' mangled-name='blk_mq_stop_hw_queue' filepath='block/blk-mq.c' line='1778' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_stop_hw_queue'>
-        <parameter type-id='a47d3467' name='hctx' filepath='block/blk-mq.c' line='1778' column='1'/>
+      <function-decl name='blk_mq_stop_hw_queue' mangled-name='blk_mq_stop_hw_queue' filepath='block/blk-mq.c' line='1779' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_stop_hw_queue'>
+        <parameter type-id='a47d3467' name='hctx' filepath='block/blk-mq.c' line='1779' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_mq_tag_to_rq' mangled-name='blk_mq_tag_to_rq' filepath='block/blk-mq.c' line='863' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_tag_to_rq'>
-        <parameter type-id='0461ecf5' name='tags' filepath='block/blk-mq.c' line='863' column='1'/>
-        <parameter type-id='f0981eeb' name='tag' filepath='block/blk-mq.c' line='863' column='1'/>
+      <function-decl name='blk_mq_tag_to_rq' mangled-name='blk_mq_tag_to_rq' filepath='block/blk-mq.c' line='864' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_tag_to_rq'>
+        <parameter type-id='0461ecf5' name='tags' filepath='block/blk-mq.c' line='864' column='1'/>
+        <parameter type-id='f0981eeb' name='tag' filepath='block/blk-mq.c' line='864' column='1'/>
         <return type-id='3dad1a48'/>
       </function-decl>
       <function-decl name='blk_mq_tagset_busy_iter' mangled-name='blk_mq_tagset_busy_iter' filepath='block/blk-mq-tag.c' line='378' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_tagset_busy_iter'>
@@ -122582,9 +123242,9 @@
         <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-mq.c' line='250' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_mq_update_nr_hw_queues' mangled-name='blk_mq_update_nr_hw_queues' filepath='block/blk-mq.c' line='3812' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_update_nr_hw_queues'>
-        <parameter type-id='cc26d15f' name='set' filepath='block/blk-mq.c' line='3812' column='1'/>
-        <parameter type-id='95e97e5e' name='nr_hw_queues' filepath='block/blk-mq.c' line='3812' column='1'/>
+      <function-decl name='blk_mq_update_nr_hw_queues' mangled-name='blk_mq_update_nr_hw_queues' filepath='block/blk-mq.c' line='3813' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_update_nr_hw_queues'>
+        <parameter type-id='cc26d15f' name='set' filepath='block/blk-mq.c' line='3813' column='1'/>
+        <parameter type-id='95e97e5e' name='nr_hw_queues' filepath='block/blk-mq.c' line='3813' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='blk_mq_virtio_map_queues' mangled-name='blk_mq_virtio_map_queues' filepath='block/blk-mq-virtio.c' line='24' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_mq_virtio_map_queues'>
@@ -122597,10 +123257,10 @@
         <parameter type-id='f0981eeb' name='op' filepath='block/blk-core.c' line='164' column='1'/>
         <return type-id='80f4b756'/>
       </function-decl>
-      <function-decl name='blk_poll' mangled-name='blk_poll' filepath='block/blk-mq.c' line='3976' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_poll'>
-        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-mq.c' line='3976' column='1'/>
-        <parameter type-id='041bc907' name='cookie' filepath='block/blk-mq.c' line='3976' column='1'/>
-        <parameter type-id='b50a4934' name='spin' filepath='block/blk-mq.c' line='3976' column='1'/>
+      <function-decl name='blk_poll' mangled-name='blk_poll' filepath='block/blk-mq.c' line='3977' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_poll'>
+        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-mq.c' line='3977' column='1'/>
+        <parameter type-id='041bc907' name='cookie' filepath='block/blk-mq.c' line='3977' column='1'/>
+        <parameter type-id='b50a4934' name='spin' filepath='block/blk-mq.c' line='3977' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='blk_put_queue' mangled-name='blk_put_queue' filepath='block/blk-core.c' line='342' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_put_queue'>
@@ -122787,8 +123447,8 @@
         <parameter type-id='7604ff1d' name='lim' filepath='block/blk-settings.c' line='74' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_start_plug' mangled-name='blk_start_plug' filepath='block/blk-core.c' line='1693' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_start_plug'>
-        <parameter type-id='39944481' name='plug' filepath='block/blk-core.c' line='1693' column='1'/>
+      <function-decl name='blk_start_plug' mangled-name='blk_start_plug' filepath='block/blk-core.c' line='1698' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_start_plug'>
+        <parameter type-id='39944481' name='plug' filepath='block/blk-core.c' line='1698' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='blk_stat_enable_accounting' mangled-name='blk_stat_enable_accounting' filepath='block/blk-stat.c' line='187' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_stat_enable_accounting'>
@@ -122808,10 +123468,10 @@
         <parameter type-id='7359adad' name='range' filepath='block/genhd.c' line='659' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blk_update_request' mangled-name='blk_update_request' filepath='block/blk-core.c' line='1439' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_update_request'>
-        <parameter type-id='3dad1a48' name='req' filepath='block/blk-core.c' line='1439' column='1'/>
-        <parameter type-id='f4e2facd' name='error' filepath='block/blk-core.c' line='1439' column='1'/>
-        <parameter type-id='f0981eeb' name='nr_bytes' filepath='block/blk-core.c' line='1440' column='1'/>
+      <function-decl name='blk_update_request' mangled-name='blk_update_request' filepath='block/blk-core.c' line='1437' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_update_request'>
+        <parameter type-id='3dad1a48' name='req' filepath='block/blk-core.c' line='1437' column='1'/>
+        <parameter type-id='f4e2facd' name='error' filepath='block/blk-core.c' line='1437' column='1'/>
+        <parameter type-id='f0981eeb' name='nr_bytes' filepath='block/blk-core.c' line='1438' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='blk_verify_command' mangled-name='blk_verify_command' filepath='block/scsi_ioctl.c' line='200' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blk_verify_command'>
@@ -122824,20 +123484,25 @@
         <parameter type-id='0d87d4f6' name='pol' filepath='block/blk-cgroup.c' line='1317' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='blkcg_deactivate_policy' mangled-name='blkcg_deactivate_policy' filepath='block/blk-cgroup.c' line='1419' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blkcg_deactivate_policy'>
-        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-cgroup.c' line='1419' column='1'/>
-        <parameter type-id='0d87d4f6' name='pol' filepath='block/blk-cgroup.c' line='1420' column='1'/>
+      <function-decl name='blkcg_deactivate_policy' mangled-name='blkcg_deactivate_policy' filepath='block/blk-cgroup.c' line='1423' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blkcg_deactivate_policy'>
+        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-cgroup.c' line='1423' column='1'/>
+        <parameter type-id='0d87d4f6' name='pol' filepath='block/blk-cgroup.c' line='1424' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='blkcg_policy_register' mangled-name='blkcg_policy_register' filepath='block/blk-cgroup.c' line='1461' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blkcg_policy_register'>
-        <parameter type-id='b31a5ea1' name='pol' filepath='block/blk-cgroup.c' line='1461' column='1'/>
+      <function-decl name='blkcg_policy_register' mangled-name='blkcg_policy_register' filepath='block/blk-cgroup.c' line='1465' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blkcg_policy_register'>
+        <parameter type-id='b31a5ea1' name='pol' filepath='block/blk-cgroup.c' line='1465' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='blkcg_policy_unregister' mangled-name='blkcg_policy_unregister' filepath='block/blk-cgroup.c' line='1540' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blkcg_policy_unregister'>
-        <parameter type-id='b31a5ea1' name='pol' filepath='block/blk-cgroup.c' line='1540' column='1'/>
+      <function-decl name='blkcg_policy_unregister' mangled-name='blkcg_policy_unregister' filepath='block/blk-cgroup.c' line='1544' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blkcg_policy_unregister'>
+        <parameter type-id='b31a5ea1' name='pol' filepath='block/blk-cgroup.c' line='1544' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <var-decl name='blkcg_root' type-id='19b26952' mangled-name='blkcg_root' visibility='default' filepath='block/blk-cgroup.c' line='48' column='1' elf-symbol-id='blkcg_root'/>
+      <function-decl name='blkcg_schedule_throttle' mangled-name='blkcg_schedule_throttle' filepath='block/blk-cgroup.c' line='1782' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blkcg_schedule_throttle'>
+        <parameter type-id='e7d2a5fc' name='q' filepath='block/blk-cgroup.c' line='1782' column='1'/>
+        <parameter type-id='b50a4934' name='use_memdelay' filepath='block/blk-cgroup.c' line='1782' column='1'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
       <function-decl name='blkdev_fsync' mangled-name='blkdev_fsync' filepath='fs/block_dev.c' line='691' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='blkdev_fsync'>
         <parameter type-id='77e79a4b' name='filp' filepath='fs/block_dev.c' line='691' column='1'/>
         <parameter type-id='69bf7bee' name='start' filepath='fs/block_dev.c' line='691' column='1'/>
@@ -122917,15 +123582,15 @@
         <parameter type-id='d504f73d' name='n' filepath='kernel/notifier.c' line='271' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='bmap' mangled-name='bmap' filepath='fs/inode.c' line='1701' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bmap'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='1701' column='1'/>
-        <parameter type-id='5c39fc92' name='block' filepath='fs/inode.c' line='1701' column='1'/>
+      <function-decl name='bmap' mangled-name='bmap' filepath='fs/inode.c' line='1743' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bmap'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='1743' column='1'/>
+        <parameter type-id='5c39fc92' name='block' filepath='fs/inode.c' line='1743' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='bpf_dispatcher_xdp_func' mangled-name='bpf_dispatcher_xdp_func' filepath='net/core/filter.c' line='10331' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_dispatcher_xdp_func'>
-        <parameter type-id='eaa32e2f' name='ctx' filepath='net/core/filter.c' line='10331' column='1'/>
-        <parameter type-id='acada613' name='insnsi' filepath='net/core/filter.c' line='10331' column='1'/>
-        <parameter type-id='531a7450' name='bpf_func' filepath='net/core/filter.c' line='10331' column='1'/>
+      <function-decl name='bpf_dispatcher_xdp_func' mangled-name='bpf_dispatcher_xdp_func' filepath='net/core/filter.c' line='10341' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_dispatcher_xdp_func'>
+        <parameter type-id='eaa32e2f' name='ctx' filepath='net/core/filter.c' line='10341' column='1'/>
+        <parameter type-id='acada613' name='insnsi' filepath='net/core/filter.c' line='10341' column='1'/>
+        <parameter type-id='531a7450' name='bpf_func' filepath='net/core/filter.c' line='10341' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
       <function-decl name='bpf_prog_add' mangled-name='bpf_prog_add' filepath='kernel/bpf/syscall.c' line='1878' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_prog_add'>
@@ -122942,135 +123607,135 @@
         <parameter type-id='95e97e5e' name='i' filepath='kernel/bpf/syscall.c' line='1884' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <var-decl name='bpf_stats_enabled_key' type-id='237c0d27' mangled-name='bpf_stats_enabled_key' visibility='default' filepath='kernel/bpf/core.c' line='2345' column='1' elf-symbol-id='bpf_stats_enabled_key'/>
-      <function-decl name='bpf_trace_run1' mangled-name='bpf_trace_run1' filepath='kernel/trace/bpf_trace.c' line='2079' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run1'>
-        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2079' column='1'/>
-        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2079' column='1'/>
+      <var-decl name='bpf_stats_enabled_key' type-id='237c0d27' mangled-name='bpf_stats_enabled_key' visibility='default' filepath='kernel/bpf/core.c' line='2344' column='1' elf-symbol-id='bpf_stats_enabled_key'/>
+      <function-decl name='bpf_trace_run1' mangled-name='bpf_trace_run1' filepath='kernel/trace/bpf_trace.c' line='2093' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run1'>
+        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2093' column='1'/>
+        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2093' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bpf_trace_run10' mangled-name='bpf_trace_run10' filepath='kernel/trace/bpf_trace.c' line='2088' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run10'>
-        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2088' column='1'/>
-        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2088' column='1'/>
-        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2088' column='1'/>
-        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2088' column='1'/>
-        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2088' column='1'/>
-        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2088' column='1'/>
-        <parameter type-id='91ce1af9' name='arg5' filepath='kernel/trace/bpf_trace.c' line='2088' column='1'/>
-        <parameter type-id='91ce1af9' name='arg6' filepath='kernel/trace/bpf_trace.c' line='2088' column='1'/>
-        <parameter type-id='91ce1af9' name='arg7' filepath='kernel/trace/bpf_trace.c' line='2088' column='1'/>
-        <parameter type-id='91ce1af9' name='arg8' filepath='kernel/trace/bpf_trace.c' line='2088' column='1'/>
-        <parameter type-id='91ce1af9' name='arg9' filepath='kernel/trace/bpf_trace.c' line='2088' column='1'/>
+      <function-decl name='bpf_trace_run10' mangled-name='bpf_trace_run10' filepath='kernel/trace/bpf_trace.c' line='2102' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run10'>
+        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2102' column='1'/>
+        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2102' column='1'/>
+        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2102' column='1'/>
+        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2102' column='1'/>
+        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2102' column='1'/>
+        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2102' column='1'/>
+        <parameter type-id='91ce1af9' name='arg5' filepath='kernel/trace/bpf_trace.c' line='2102' column='1'/>
+        <parameter type-id='91ce1af9' name='arg6' filepath='kernel/trace/bpf_trace.c' line='2102' column='1'/>
+        <parameter type-id='91ce1af9' name='arg7' filepath='kernel/trace/bpf_trace.c' line='2102' column='1'/>
+        <parameter type-id='91ce1af9' name='arg8' filepath='kernel/trace/bpf_trace.c' line='2102' column='1'/>
+        <parameter type-id='91ce1af9' name='arg9' filepath='kernel/trace/bpf_trace.c' line='2102' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bpf_trace_run11' mangled-name='bpf_trace_run11' filepath='kernel/trace/bpf_trace.c' line='2089' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run11'>
-        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2089' column='1'/>
-        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2089' column='1'/>
-        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2089' column='1'/>
-        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2089' column='1'/>
-        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2089' column='1'/>
-        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2089' column='1'/>
-        <parameter type-id='91ce1af9' name='arg5' filepath='kernel/trace/bpf_trace.c' line='2089' column='1'/>
-        <parameter type-id='91ce1af9' name='arg6' filepath='kernel/trace/bpf_trace.c' line='2089' column='1'/>
-        <parameter type-id='91ce1af9' name='arg7' filepath='kernel/trace/bpf_trace.c' line='2089' column='1'/>
-        <parameter type-id='91ce1af9' name='arg8' filepath='kernel/trace/bpf_trace.c' line='2089' column='1'/>
-        <parameter type-id='91ce1af9' name='arg9' filepath='kernel/trace/bpf_trace.c' line='2089' column='1'/>
-        <parameter type-id='91ce1af9' name='arg10' filepath='kernel/trace/bpf_trace.c' line='2089' column='1'/>
+      <function-decl name='bpf_trace_run11' mangled-name='bpf_trace_run11' filepath='kernel/trace/bpf_trace.c' line='2103' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run11'>
+        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2103' column='1'/>
+        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2103' column='1'/>
+        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2103' column='1'/>
+        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2103' column='1'/>
+        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2103' column='1'/>
+        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2103' column='1'/>
+        <parameter type-id='91ce1af9' name='arg5' filepath='kernel/trace/bpf_trace.c' line='2103' column='1'/>
+        <parameter type-id='91ce1af9' name='arg6' filepath='kernel/trace/bpf_trace.c' line='2103' column='1'/>
+        <parameter type-id='91ce1af9' name='arg7' filepath='kernel/trace/bpf_trace.c' line='2103' column='1'/>
+        <parameter type-id='91ce1af9' name='arg8' filepath='kernel/trace/bpf_trace.c' line='2103' column='1'/>
+        <parameter type-id='91ce1af9' name='arg9' filepath='kernel/trace/bpf_trace.c' line='2103' column='1'/>
+        <parameter type-id='91ce1af9' name='arg10' filepath='kernel/trace/bpf_trace.c' line='2103' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bpf_trace_run12' mangled-name='bpf_trace_run12' filepath='kernel/trace/bpf_trace.c' line='2090' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run12'>
-        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2090' column='1'/>
-        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2090' column='1'/>
-        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2090' column='1'/>
-        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2090' column='1'/>
-        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2090' column='1'/>
-        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2090' column='1'/>
-        <parameter type-id='91ce1af9' name='arg5' filepath='kernel/trace/bpf_trace.c' line='2090' column='1'/>
-        <parameter type-id='91ce1af9' name='arg6' filepath='kernel/trace/bpf_trace.c' line='2090' column='1'/>
-        <parameter type-id='91ce1af9' name='arg7' filepath='kernel/trace/bpf_trace.c' line='2090' column='1'/>
-        <parameter type-id='91ce1af9' name='arg8' filepath='kernel/trace/bpf_trace.c' line='2090' column='1'/>
-        <parameter type-id='91ce1af9' name='arg9' filepath='kernel/trace/bpf_trace.c' line='2090' column='1'/>
-        <parameter type-id='91ce1af9' name='arg10' filepath='kernel/trace/bpf_trace.c' line='2090' column='1'/>
-        <parameter type-id='91ce1af9' name='arg11' filepath='kernel/trace/bpf_trace.c' line='2090' column='1'/>
+      <function-decl name='bpf_trace_run12' mangled-name='bpf_trace_run12' filepath='kernel/trace/bpf_trace.c' line='2104' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run12'>
+        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2104' column='1'/>
+        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2104' column='1'/>
+        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2104' column='1'/>
+        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2104' column='1'/>
+        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2104' column='1'/>
+        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2104' column='1'/>
+        <parameter type-id='91ce1af9' name='arg5' filepath='kernel/trace/bpf_trace.c' line='2104' column='1'/>
+        <parameter type-id='91ce1af9' name='arg6' filepath='kernel/trace/bpf_trace.c' line='2104' column='1'/>
+        <parameter type-id='91ce1af9' name='arg7' filepath='kernel/trace/bpf_trace.c' line='2104' column='1'/>
+        <parameter type-id='91ce1af9' name='arg8' filepath='kernel/trace/bpf_trace.c' line='2104' column='1'/>
+        <parameter type-id='91ce1af9' name='arg9' filepath='kernel/trace/bpf_trace.c' line='2104' column='1'/>
+        <parameter type-id='91ce1af9' name='arg10' filepath='kernel/trace/bpf_trace.c' line='2104' column='1'/>
+        <parameter type-id='91ce1af9' name='arg11' filepath='kernel/trace/bpf_trace.c' line='2104' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bpf_trace_run2' mangled-name='bpf_trace_run2' filepath='kernel/trace/bpf_trace.c' line='2080' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run2'>
-        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2080' column='1'/>
-        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2080' column='1'/>
-        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2080' column='1'/>
+      <function-decl name='bpf_trace_run2' mangled-name='bpf_trace_run2' filepath='kernel/trace/bpf_trace.c' line='2094' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run2'>
+        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2094' column='1'/>
+        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2094' column='1'/>
+        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2094' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bpf_trace_run3' mangled-name='bpf_trace_run3' filepath='kernel/trace/bpf_trace.c' line='2081' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run3'>
-        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2081' column='1'/>
-        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2081' column='1'/>
-        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2081' column='1'/>
-        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2081' column='1'/>
+      <function-decl name='bpf_trace_run3' mangled-name='bpf_trace_run3' filepath='kernel/trace/bpf_trace.c' line='2095' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run3'>
+        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2095' column='1'/>
+        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2095' column='1'/>
+        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2095' column='1'/>
+        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2095' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bpf_trace_run4' mangled-name='bpf_trace_run4' filepath='kernel/trace/bpf_trace.c' line='2082' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run4'>
-        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2082' column='1'/>
-        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2082' column='1'/>
-        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2082' column='1'/>
-        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2082' column='1'/>
-        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2082' column='1'/>
+      <function-decl name='bpf_trace_run4' mangled-name='bpf_trace_run4' filepath='kernel/trace/bpf_trace.c' line='2096' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run4'>
+        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2096' column='1'/>
+        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2096' column='1'/>
+        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2096' column='1'/>
+        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2096' column='1'/>
+        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2096' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bpf_trace_run5' mangled-name='bpf_trace_run5' filepath='kernel/trace/bpf_trace.c' line='2083' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run5'>
-        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2083' column='1'/>
-        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2083' column='1'/>
-        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2083' column='1'/>
-        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2083' column='1'/>
-        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2083' column='1'/>
-        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2083' column='1'/>
+      <function-decl name='bpf_trace_run5' mangled-name='bpf_trace_run5' filepath='kernel/trace/bpf_trace.c' line='2097' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run5'>
+        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2097' column='1'/>
+        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2097' column='1'/>
+        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2097' column='1'/>
+        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2097' column='1'/>
+        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2097' column='1'/>
+        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2097' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bpf_trace_run6' mangled-name='bpf_trace_run6' filepath='kernel/trace/bpf_trace.c' line='2084' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run6'>
-        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2084' column='1'/>
-        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2084' column='1'/>
-        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2084' column='1'/>
-        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2084' column='1'/>
-        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2084' column='1'/>
-        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2084' column='1'/>
-        <parameter type-id='91ce1af9' name='arg5' filepath='kernel/trace/bpf_trace.c' line='2084' column='1'/>
+      <function-decl name='bpf_trace_run6' mangled-name='bpf_trace_run6' filepath='kernel/trace/bpf_trace.c' line='2098' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run6'>
+        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2098' column='1'/>
+        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2098' column='1'/>
+        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2098' column='1'/>
+        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2098' column='1'/>
+        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2098' column='1'/>
+        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2098' column='1'/>
+        <parameter type-id='91ce1af9' name='arg5' filepath='kernel/trace/bpf_trace.c' line='2098' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bpf_trace_run7' mangled-name='bpf_trace_run7' filepath='kernel/trace/bpf_trace.c' line='2085' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run7'>
-        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2085' column='1'/>
-        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2085' column='1'/>
-        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2085' column='1'/>
-        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2085' column='1'/>
-        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2085' column='1'/>
-        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2085' column='1'/>
-        <parameter type-id='91ce1af9' name='arg5' filepath='kernel/trace/bpf_trace.c' line='2085' column='1'/>
-        <parameter type-id='91ce1af9' name='arg6' filepath='kernel/trace/bpf_trace.c' line='2085' column='1'/>
+      <function-decl name='bpf_trace_run7' mangled-name='bpf_trace_run7' filepath='kernel/trace/bpf_trace.c' line='2099' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run7'>
+        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2099' column='1'/>
+        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2099' column='1'/>
+        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2099' column='1'/>
+        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2099' column='1'/>
+        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2099' column='1'/>
+        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2099' column='1'/>
+        <parameter type-id='91ce1af9' name='arg5' filepath='kernel/trace/bpf_trace.c' line='2099' column='1'/>
+        <parameter type-id='91ce1af9' name='arg6' filepath='kernel/trace/bpf_trace.c' line='2099' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bpf_trace_run8' mangled-name='bpf_trace_run8' filepath='kernel/trace/bpf_trace.c' line='2086' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run8'>
-        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2086' column='1'/>
-        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2086' column='1'/>
-        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2086' column='1'/>
-        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2086' column='1'/>
-        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2086' column='1'/>
-        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2086' column='1'/>
-        <parameter type-id='91ce1af9' name='arg5' filepath='kernel/trace/bpf_trace.c' line='2086' column='1'/>
-        <parameter type-id='91ce1af9' name='arg6' filepath='kernel/trace/bpf_trace.c' line='2086' column='1'/>
-        <parameter type-id='91ce1af9' name='arg7' filepath='kernel/trace/bpf_trace.c' line='2086' column='1'/>
+      <function-decl name='bpf_trace_run8' mangled-name='bpf_trace_run8' filepath='kernel/trace/bpf_trace.c' line='2100' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run8'>
+        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2100' column='1'/>
+        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2100' column='1'/>
+        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2100' column='1'/>
+        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2100' column='1'/>
+        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2100' column='1'/>
+        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2100' column='1'/>
+        <parameter type-id='91ce1af9' name='arg5' filepath='kernel/trace/bpf_trace.c' line='2100' column='1'/>
+        <parameter type-id='91ce1af9' name='arg6' filepath='kernel/trace/bpf_trace.c' line='2100' column='1'/>
+        <parameter type-id='91ce1af9' name='arg7' filepath='kernel/trace/bpf_trace.c' line='2100' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bpf_trace_run9' mangled-name='bpf_trace_run9' filepath='kernel/trace/bpf_trace.c' line='2087' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run9'>
-        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2087' column='1'/>
-        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2087' column='1'/>
-        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2087' column='1'/>
-        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2087' column='1'/>
-        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2087' column='1'/>
-        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2087' column='1'/>
-        <parameter type-id='91ce1af9' name='arg5' filepath='kernel/trace/bpf_trace.c' line='2087' column='1'/>
-        <parameter type-id='91ce1af9' name='arg6' filepath='kernel/trace/bpf_trace.c' line='2087' column='1'/>
-        <parameter type-id='91ce1af9' name='arg7' filepath='kernel/trace/bpf_trace.c' line='2087' column='1'/>
-        <parameter type-id='91ce1af9' name='arg8' filepath='kernel/trace/bpf_trace.c' line='2087' column='1'/>
+      <function-decl name='bpf_trace_run9' mangled-name='bpf_trace_run9' filepath='kernel/trace/bpf_trace.c' line='2101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_trace_run9'>
+        <parameter type-id='bdcee7ae' name='prog' filepath='kernel/trace/bpf_trace.c' line='2101' column='1'/>
+        <parameter type-id='91ce1af9' name='arg0' filepath='kernel/trace/bpf_trace.c' line='2101' column='1'/>
+        <parameter type-id='91ce1af9' name='arg1' filepath='kernel/trace/bpf_trace.c' line='2101' column='1'/>
+        <parameter type-id='91ce1af9' name='arg2' filepath='kernel/trace/bpf_trace.c' line='2101' column='1'/>
+        <parameter type-id='91ce1af9' name='arg3' filepath='kernel/trace/bpf_trace.c' line='2101' column='1'/>
+        <parameter type-id='91ce1af9' name='arg4' filepath='kernel/trace/bpf_trace.c' line='2101' column='1'/>
+        <parameter type-id='91ce1af9' name='arg5' filepath='kernel/trace/bpf_trace.c' line='2101' column='1'/>
+        <parameter type-id='91ce1af9' name='arg6' filepath='kernel/trace/bpf_trace.c' line='2101' column='1'/>
+        <parameter type-id='91ce1af9' name='arg7' filepath='kernel/trace/bpf_trace.c' line='2101' column='1'/>
+        <parameter type-id='91ce1af9' name='arg8' filepath='kernel/trace/bpf_trace.c' line='2101' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='bpf_warn_invalid_xdp_action' mangled-name='bpf_warn_invalid_xdp_action' filepath='net/core/filter.c' line='7944' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_warn_invalid_xdp_action'>
-        <parameter type-id='19c2251e' name='act' filepath='net/core/filter.c' line='7944' column='1'/>
+      <function-decl name='bpf_warn_invalid_xdp_action' mangled-name='bpf_warn_invalid_xdp_action' filepath='net/core/filter.c' line='7954' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bpf_warn_invalid_xdp_action'>
+        <parameter type-id='19c2251e' name='act' filepath='net/core/filter.c' line='7954' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='bsearch' mangled-name='bsearch' filepath='lib/bsearch.c' line='31' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bsearch'>
@@ -123118,17 +123783,17 @@
         <parameter is-variadic='yes'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='btbcm_set_bdaddr' mangled-name='btbcm_set_bdaddr' filepath='drivers/bluetooth/btbcm.c' line='99' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='btbcm_set_bdaddr'>
-        <parameter type-id='9ad862e7' name='hdev' filepath='drivers/bluetooth/btbcm.c' line='99' column='1'/>
-        <parameter type-id='c3e18af8' name='bdaddr' filepath='drivers/bluetooth/btbcm.c' line='99' column='1'/>
+      <function-decl name='btbcm_set_bdaddr' mangled-name='btbcm_set_bdaddr' filepath='drivers/bluetooth/btbcm.c' line='142' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='btbcm_set_bdaddr'>
+        <parameter type-id='9ad862e7' name='hdev' filepath='drivers/bluetooth/btbcm.c' line='142' column='1'/>
+        <parameter type-id='c3e18af8' name='bdaddr' filepath='drivers/bluetooth/btbcm.c' line='142' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='btbcm_setup_apple' mangled-name='btbcm_setup_apple' filepath='drivers/bluetooth/btbcm.c' line='571' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='btbcm_setup_apple'>
-        <parameter type-id='9ad862e7' name='hdev' filepath='drivers/bluetooth/btbcm.c' line='571' column='1'/>
+      <function-decl name='btbcm_setup_apple' mangled-name='btbcm_setup_apple' filepath='drivers/bluetooth/btbcm.c' line='614' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='btbcm_setup_apple'>
+        <parameter type-id='9ad862e7' name='hdev' filepath='drivers/bluetooth/btbcm.c' line='614' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='btbcm_setup_patchram' mangled-name='btbcm_setup_patchram' filepath='drivers/bluetooth/btbcm.c' line='556' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='btbcm_setup_patchram'>
-        <parameter type-id='9ad862e7' name='hdev' filepath='drivers/bluetooth/btbcm.c' line='556' column='1'/>
+      <function-decl name='btbcm_setup_patchram' mangled-name='btbcm_setup_patchram' filepath='drivers/bluetooth/btbcm.c' line='599' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='btbcm_setup_patchram'>
+        <parameter type-id='9ad862e7' name='hdev' filepath='drivers/bluetooth/btbcm.c' line='599' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='buffer_migrate_page' mangled-name='buffer_migrate_page' filepath='mm/migrate.c' line='825' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='buffer_migrate_page'>
@@ -123173,9 +123838,9 @@
         <parameter type-id='d504f73d' name='nb' filepath='drivers/base/bus.c' line='903' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='bus_set_iommu' mangled-name='bus_set_iommu' filepath='drivers/iommu/iommu.c' line='1843' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bus_set_iommu'>
-        <parameter type-id='5e2671f8' name='bus' filepath='drivers/iommu/iommu.c' line='1843' column='1'/>
-        <parameter type-id='f1ac64d0' name='ops' filepath='drivers/iommu/iommu.c' line='1843' column='1'/>
+      <function-decl name='bus_set_iommu' mangled-name='bus_set_iommu' filepath='drivers/iommu/iommu.c' line='1859' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bus_set_iommu'>
+        <parameter type-id='5e2671f8' name='bus' filepath='drivers/iommu/iommu.c' line='1859' column='1'/>
+        <parameter type-id='f1ac64d0' name='ops' filepath='drivers/iommu/iommu.c' line='1859' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='bus_unregister' mangled-name='bus_unregister' filepath='drivers/base/bus.c' line='889' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bus_unregister'>
@@ -123195,19 +123860,19 @@
         <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='2078' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='call_rcu' mangled-name='call_rcu' filepath='kernel/rcu/tree.c' line='3039' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='call_rcu'>
-        <parameter type-id='69c138b1' name='head' filepath='kernel/rcu/tree.c' line='3039' column='1'/>
-        <parameter type-id='4edd56e3' name='func' filepath='kernel/rcu/tree.c' line='3039' column='1'/>
+      <function-decl name='call_rcu' mangled-name='call_rcu' filepath='kernel/rcu/tree.c' line='3047' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='call_rcu'>
+        <parameter type-id='69c138b1' name='head' filepath='kernel/rcu/tree.c' line='3047' column='1'/>
+        <parameter type-id='4edd56e3' name='func' filepath='kernel/rcu/tree.c' line='3047' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='call_rcu_tasks' mangled-name='call_rcu_tasks' filepath='kernel/rcu/tasks.h' line='516' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='call_rcu_tasks'>
-        <parameter type-id='69c138b1' name='rhp' filepath='kernel/rcu/tasks.h' line='516' column='1'/>
-        <parameter type-id='4edd56e3' name='func' filepath='kernel/rcu/tasks.h' line='516' column='1'/>
+      <function-decl name='call_rcu_tasks' mangled-name='call_rcu_tasks' filepath='kernel/rcu/tasks.h' line='530' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='call_rcu_tasks'>
+        <parameter type-id='69c138b1' name='rhp' filepath='kernel/rcu/tasks.h' line='530' column='1'/>
+        <parameter type-id='4edd56e3' name='func' filepath='kernel/rcu/tasks.h' line='530' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='call_rcu_tasks_trace' mangled-name='call_rcu_tasks_trace' filepath='kernel/rcu/tasks.h' line='1142' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='call_rcu_tasks_trace'>
-        <parameter type-id='69c138b1' name='rhp' filepath='kernel/rcu/tasks.h' line='1142' column='1'/>
-        <parameter type-id='4edd56e3' name='func' filepath='kernel/rcu/tasks.h' line='1142' column='1'/>
+      <function-decl name='call_rcu_tasks_trace' mangled-name='call_rcu_tasks_trace' filepath='kernel/rcu/tasks.h' line='1155' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='call_rcu_tasks_trace'>
+        <parameter type-id='69c138b1' name='rhp' filepath='kernel/rcu/tasks.h' line='1155' column='1'/>
+        <parameter type-id='4edd56e3' name='func' filepath='kernel/rcu/tasks.h' line='1155' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='call_srcu' mangled-name='call_srcu' filepath='kernel/rcu/srcutree.c' line='909' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='call_srcu'>
@@ -123237,16 +123902,16 @@
         <parameter type-id='f0981eeb' name='idx' filepath='drivers/net/can/dev/dev.c' line='461' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='cancel_delayed_work' mangled-name='cancel_delayed_work' filepath='kernel/workqueue.c' line='3273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cancel_delayed_work'>
-        <parameter type-id='1a7ee447' name='dwork' filepath='kernel/workqueue.c' line='3273' column='1'/>
+      <function-decl name='cancel_delayed_work' mangled-name='cancel_delayed_work' filepath='kernel/workqueue.c' line='3276' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cancel_delayed_work'>
+        <parameter type-id='1a7ee447' name='dwork' filepath='kernel/workqueue.c' line='3276' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='cancel_delayed_work_sync' mangled-name='cancel_delayed_work_sync' filepath='kernel/workqueue.c' line='3288' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cancel_delayed_work_sync'>
-        <parameter type-id='1a7ee447' name='dwork' filepath='kernel/workqueue.c' line='3288' column='1'/>
+      <function-decl name='cancel_delayed_work_sync' mangled-name='cancel_delayed_work_sync' filepath='kernel/workqueue.c' line='3291' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cancel_delayed_work_sync'>
+        <parameter type-id='1a7ee447' name='dwork' filepath='kernel/workqueue.c' line='3291' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='cancel_work_sync' mangled-name='cancel_work_sync' filepath='kernel/workqueue.c' line='3192' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cancel_work_sync'>
-        <parameter type-id='83c1bde6' name='work' filepath='kernel/workqueue.c' line='3192' column='1'/>
+      <function-decl name='cancel_work_sync' mangled-name='cancel_work_sync' filepath='kernel/workqueue.c' line='3195' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cancel_work_sync'>
+        <parameter type-id='83c1bde6' name='work' filepath='kernel/workqueue.c' line='3195' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='capable' mangled-name='capable' filepath='kernel/capability.c' line='447' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='capable'>
@@ -123258,41 +123923,41 @@
         <parameter type-id='95e97e5e' name='cap' filepath='kernel/capability.c' line='502' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='cdc_ncm_bind_common' mangled-name='cdc_ncm_bind_common' filepath='drivers/net/usb/cdc_ncm.c' line='804' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cdc_ncm_bind_common'>
-        <parameter type-id='12884b9a' name='dev' filepath='drivers/net/usb/cdc_ncm.c' line='804' column='1'/>
-        <parameter type-id='8bf48c31' name='intf' filepath='drivers/net/usb/cdc_ncm.c' line='804' column='1'/>
-        <parameter type-id='f9b06939' name='data_altsetting' filepath='drivers/net/usb/cdc_ncm.c' line='804' column='1'/>
-        <parameter type-id='95e97e5e' name='drvflags' filepath='drivers/net/usb/cdc_ncm.c' line='804' column='1'/>
+      <function-decl name='cdc_ncm_bind_common' mangled-name='cdc_ncm_bind_common' filepath='drivers/net/usb/cdc_ncm.c' line='807' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cdc_ncm_bind_common'>
+        <parameter type-id='12884b9a' name='dev' filepath='drivers/net/usb/cdc_ncm.c' line='807' column='1'/>
+        <parameter type-id='8bf48c31' name='intf' filepath='drivers/net/usb/cdc_ncm.c' line='807' column='1'/>
+        <parameter type-id='f9b06939' name='data_altsetting' filepath='drivers/net/usb/cdc_ncm.c' line='807' column='1'/>
+        <parameter type-id='95e97e5e' name='drvflags' filepath='drivers/net/usb/cdc_ncm.c' line='807' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='cdc_ncm_change_mtu' mangled-name='cdc_ncm_change_mtu' filepath='drivers/net/usb/cdc_ncm.c' line='781' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cdc_ncm_change_mtu'>
-        <parameter type-id='68a2d05b' name='net' filepath='drivers/net/usb/cdc_ncm.c' line='781' column='1'/>
-        <parameter type-id='95e97e5e' name='new_mtu' filepath='drivers/net/usb/cdc_ncm.c' line='781' column='1'/>
+      <function-decl name='cdc_ncm_change_mtu' mangled-name='cdc_ncm_change_mtu' filepath='drivers/net/usb/cdc_ncm.c' line='784' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cdc_ncm_change_mtu'>
+        <parameter type-id='68a2d05b' name='net' filepath='drivers/net/usb/cdc_ncm.c' line='784' column='1'/>
+        <parameter type-id='95e97e5e' name='new_mtu' filepath='drivers/net/usb/cdc_ncm.c' line='784' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='cdc_ncm_fill_tx_frame' mangled-name='cdc_ncm_fill_tx_frame' filepath='drivers/net/usb/cdc_ncm.c' line='1183' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cdc_ncm_fill_tx_frame'>
-        <parameter type-id='12884b9a' name='dev' filepath='drivers/net/usb/cdc_ncm.c' line='1183' column='1'/>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='drivers/net/usb/cdc_ncm.c' line='1183' column='1'/>
-        <parameter type-id='2f162548' name='sign' filepath='drivers/net/usb/cdc_ncm.c' line='1183' column='1'/>
+      <function-decl name='cdc_ncm_fill_tx_frame' mangled-name='cdc_ncm_fill_tx_frame' filepath='drivers/net/usb/cdc_ncm.c' line='1186' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cdc_ncm_fill_tx_frame'>
+        <parameter type-id='12884b9a' name='dev' filepath='drivers/net/usb/cdc_ncm.c' line='1186' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='drivers/net/usb/cdc_ncm.c' line='1186' column='1'/>
+        <parameter type-id='2f162548' name='sign' filepath='drivers/net/usb/cdc_ncm.c' line='1186' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
-      <function-decl name='cdc_ncm_rx_verify_ndp16' mangled-name='cdc_ncm_rx_verify_ndp16' filepath='drivers/net/usb/cdc_ncm.c' line='1630' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cdc_ncm_rx_verify_ndp16'>
-        <parameter type-id='0fbf3cfd' name='skb_in' filepath='drivers/net/usb/cdc_ncm.c' line='1630' column='1'/>
-        <parameter type-id='95e97e5e' name='ndpoffset' filepath='drivers/net/usb/cdc_ncm.c' line='1630' column='1'/>
+      <function-decl name='cdc_ncm_rx_verify_ndp16' mangled-name='cdc_ncm_rx_verify_ndp16' filepath='drivers/net/usb/cdc_ncm.c' line='1636' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cdc_ncm_rx_verify_ndp16'>
+        <parameter type-id='0fbf3cfd' name='skb_in' filepath='drivers/net/usb/cdc_ncm.c' line='1636' column='1'/>
+        <parameter type-id='95e97e5e' name='ndpoffset' filepath='drivers/net/usb/cdc_ncm.c' line='1636' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='cdc_ncm_rx_verify_nth16' mangled-name='cdc_ncm_rx_verify_nth16' filepath='drivers/net/usb/cdc_ncm.c' line='1533' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cdc_ncm_rx_verify_nth16'>
-        <parameter type-id='c786c422' name='ctx' filepath='drivers/net/usb/cdc_ncm.c' line='1533' column='1'/>
-        <parameter type-id='0fbf3cfd' name='skb_in' filepath='drivers/net/usb/cdc_ncm.c' line='1533' column='1'/>
+      <function-decl name='cdc_ncm_rx_verify_nth16' mangled-name='cdc_ncm_rx_verify_nth16' filepath='drivers/net/usb/cdc_ncm.c' line='1539' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cdc_ncm_rx_verify_nth16'>
+        <parameter type-id='c786c422' name='ctx' filepath='drivers/net/usb/cdc_ncm.c' line='1539' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb_in' filepath='drivers/net/usb/cdc_ncm.c' line='1539' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='cdc_ncm_select_altsetting' mangled-name='cdc_ncm_select_altsetting' filepath='drivers/net/usb/cdc_ncm.c' line='1015' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cdc_ncm_select_altsetting'>
-        <parameter type-id='8bf48c31' name='intf' filepath='drivers/net/usb/cdc_ncm.c' line='1015' column='1'/>
+      <function-decl name='cdc_ncm_select_altsetting' mangled-name='cdc_ncm_select_altsetting' filepath='drivers/net/usb/cdc_ncm.c' line='1018' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cdc_ncm_select_altsetting'>
+        <parameter type-id='8bf48c31' name='intf' filepath='drivers/net/usb/cdc_ncm.c' line='1018' column='1'/>
         <return type-id='f9b06939'/>
       </function-decl>
-      <function-decl name='cdc_ncm_unbind' mangled-name='cdc_ncm_unbind' filepath='drivers/net/usb/cdc_ncm.c' line='977' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cdc_ncm_unbind'>
-        <parameter type-id='12884b9a' name='dev' filepath='drivers/net/usb/cdc_ncm.c' line='977' column='1'/>
-        <parameter type-id='8bf48c31' name='intf' filepath='drivers/net/usb/cdc_ncm.c' line='977' column='1'/>
+      <function-decl name='cdc_ncm_unbind' mangled-name='cdc_ncm_unbind' filepath='drivers/net/usb/cdc_ncm.c' line='980' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cdc_ncm_unbind'>
+        <parameter type-id='12884b9a' name='dev' filepath='drivers/net/usb/cdc_ncm.c' line='980' column='1'/>
+        <parameter type-id='8bf48c31' name='intf' filepath='drivers/net/usb/cdc_ncm.c' line='980' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='cdc_parse_cdc_header' mangled-name='cdc_parse_cdc_header' filepath='drivers/usb/core/message.c' line='2279' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cdc_parse_cdc_header'>
@@ -123401,21 +124066,21 @@
         <parameter type-id='fa0b179b' name='parent' filepath='drivers/media/cec/core/cec-core.c' line='319' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='cec_s_log_addrs' mangled-name='cec_s_log_addrs' filepath='drivers/media/cec/core/cec-adap.c' line='1816' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cec_s_log_addrs'>
-        <parameter type-id='b94a2f7c' name='adap' filepath='drivers/media/cec/core/cec-adap.c' line='1816' column='1'/>
-        <parameter type-id='ebc04a66' name='log_addrs' filepath='drivers/media/cec/core/cec-adap.c' line='1817' column='1'/>
-        <parameter type-id='b50a4934' name='block' filepath='drivers/media/cec/core/cec-adap.c' line='1817' column='1'/>
+      <function-decl name='cec_s_log_addrs' mangled-name='cec_s_log_addrs' filepath='drivers/media/cec/core/cec-adap.c' line='1817' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cec_s_log_addrs'>
+        <parameter type-id='b94a2f7c' name='adap' filepath='drivers/media/cec/core/cec-adap.c' line='1817' column='1'/>
+        <parameter type-id='ebc04a66' name='log_addrs' filepath='drivers/media/cec/core/cec-adap.c' line='1818' column='1'/>
+        <parameter type-id='b50a4934' name='block' filepath='drivers/media/cec/core/cec-adap.c' line='1818' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='cec_s_phys_addr' mangled-name='cec_s_phys_addr' filepath='drivers/media/cec/core/cec-adap.c' line='1612' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cec_s_phys_addr'>
-        <parameter type-id='b94a2f7c' name='adap' filepath='drivers/media/cec/core/cec-adap.c' line='1612' column='1'/>
-        <parameter type-id='1dc6a898' name='phys_addr' filepath='drivers/media/cec/core/cec-adap.c' line='1612' column='1'/>
-        <parameter type-id='b50a4934' name='block' filepath='drivers/media/cec/core/cec-adap.c' line='1612' column='1'/>
+      <function-decl name='cec_s_phys_addr' mangled-name='cec_s_phys_addr' filepath='drivers/media/cec/core/cec-adap.c' line='1613' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cec_s_phys_addr'>
+        <parameter type-id='b94a2f7c' name='adap' filepath='drivers/media/cec/core/cec-adap.c' line='1613' column='1'/>
+        <parameter type-id='1dc6a898' name='phys_addr' filepath='drivers/media/cec/core/cec-adap.c' line='1613' column='1'/>
+        <parameter type-id='b50a4934' name='block' filepath='drivers/media/cec/core/cec-adap.c' line='1613' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='cec_s_phys_addr_from_edid' mangled-name='cec_s_phys_addr_from_edid' filepath='drivers/media/cec/core/cec-adap.c' line='1623' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cec_s_phys_addr_from_edid'>
-        <parameter type-id='b94a2f7c' name='adap' filepath='drivers/media/cec/core/cec-adap.c' line='1623' column='1'/>
-        <parameter type-id='776adf76' name='edid' filepath='drivers/media/cec/core/cec-adap.c' line='1624' column='1'/>
+      <function-decl name='cec_s_phys_addr_from_edid' mangled-name='cec_s_phys_addr_from_edid' filepath='drivers/media/cec/core/cec-adap.c' line='1624' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cec_s_phys_addr_from_edid'>
+        <parameter type-id='b94a2f7c' name='adap' filepath='drivers/media/cec/core/cec-adap.c' line='1624' column='1'/>
+        <parameter type-id='776adf76' name='edid' filepath='drivers/media/cec/core/cec-adap.c' line='1625' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='cec_transmit_attempt_done_ts' mangled-name='cec_transmit_attempt_done_ts' filepath='drivers/media/cec/core/cec-adap.c' line='690' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cec_transmit_attempt_done_ts'>
@@ -123438,44 +124103,49 @@
         <parameter type-id='b94a2f7c' name='adap' filepath='drivers/media/cec/core/cec-core.c' line='377' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='cgroup_add_legacy_cftypes' mangled-name='cgroup_add_legacy_cftypes' filepath='kernel/cgroup/cgroup.c' line='4231' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cgroup_add_legacy_cftypes'>
-        <parameter type-id='dc91d125' name='ss' filepath='kernel/cgroup/cgroup.c' line='4231' column='1'/>
-        <parameter type-id='03054cfa' name='cfts' filepath='kernel/cgroup/cgroup.c' line='4231' column='1'/>
+      <function-decl name='cgroup_add_dfl_cftypes' mangled-name='cgroup_add_dfl_cftypes' filepath='kernel/cgroup/cgroup.c' line='4228' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cgroup_add_dfl_cftypes'>
+        <parameter type-id='dc91d125' name='ss' filepath='kernel/cgroup/cgroup.c' line='4228' column='1'/>
+        <parameter type-id='03054cfa' name='cfts' filepath='kernel/cgroup/cgroup.c' line='4228' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='cgroup_path_ns' mangled-name='cgroup_path_ns' filepath='kernel/cgroup/cgroup.c' line='2275' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cgroup_path_ns'>
-        <parameter type-id='46ff135d' name='cgrp' filepath='kernel/cgroup/cgroup.c' line='2275' column='1'/>
-        <parameter type-id='26a90f95' name='buf' filepath='kernel/cgroup/cgroup.c' line='2275' column='1'/>
-        <parameter type-id='b59d7dce' name='buflen' filepath='kernel/cgroup/cgroup.c' line='2275' column='1'/>
-        <parameter type-id='f774a955' name='ns' filepath='kernel/cgroup/cgroup.c' line='2276' column='1'/>
+      <function-decl name='cgroup_add_legacy_cftypes' mangled-name='cgroup_add_legacy_cftypes' filepath='kernel/cgroup/cgroup.c' line='4246' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cgroup_add_legacy_cftypes'>
+        <parameter type-id='dc91d125' name='ss' filepath='kernel/cgroup/cgroup.c' line='4246' column='1'/>
+        <parameter type-id='03054cfa' name='cfts' filepath='kernel/cgroup/cgroup.c' line='4246' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='cgroup_taskset_first' mangled-name='cgroup_taskset_first' filepath='kernel/cgroup/cgroup.c' line='2418' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cgroup_taskset_first'>
-        <parameter type-id='8cffa561' name='tset' filepath='kernel/cgroup/cgroup.c' line='2418' column='1'/>
-        <parameter type-id='e7f9d97b' name='dst_cssp' filepath='kernel/cgroup/cgroup.c' line='2419' column='1'/>
+      <function-decl name='cgroup_path_ns' mangled-name='cgroup_path_ns' filepath='kernel/cgroup/cgroup.c' line='2289' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cgroup_path_ns'>
+        <parameter type-id='46ff135d' name='cgrp' filepath='kernel/cgroup/cgroup.c' line='2289' column='1'/>
+        <parameter type-id='26a90f95' name='buf' filepath='kernel/cgroup/cgroup.c' line='2289' column='1'/>
+        <parameter type-id='b59d7dce' name='buflen' filepath='kernel/cgroup/cgroup.c' line='2289' column='1'/>
+        <parameter type-id='f774a955' name='ns' filepath='kernel/cgroup/cgroup.c' line='2290' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='cgroup_taskset_first' mangled-name='cgroup_taskset_first' filepath='kernel/cgroup/cgroup.c' line='2432' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cgroup_taskset_first'>
+        <parameter type-id='8cffa561' name='tset' filepath='kernel/cgroup/cgroup.c' line='2432' column='1'/>
+        <parameter type-id='e7f9d97b' name='dst_cssp' filepath='kernel/cgroup/cgroup.c' line='2433' column='1'/>
         <return type-id='f23e2572'/>
       </function-decl>
-      <function-decl name='cgroup_taskset_next' mangled-name='cgroup_taskset_next' filepath='kernel/cgroup/cgroup.c' line='2436' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cgroup_taskset_next'>
-        <parameter type-id='8cffa561' name='tset' filepath='kernel/cgroup/cgroup.c' line='2436' column='1'/>
-        <parameter type-id='e7f9d97b' name='dst_cssp' filepath='kernel/cgroup/cgroup.c' line='2437' column='1'/>
+      <function-decl name='cgroup_taskset_next' mangled-name='cgroup_taskset_next' filepath='kernel/cgroup/cgroup.c' line='2450' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cgroup_taskset_next'>
+        <parameter type-id='8cffa561' name='tset' filepath='kernel/cgroup/cgroup.c' line='2450' column='1'/>
+        <parameter type-id='e7f9d97b' name='dst_cssp' filepath='kernel/cgroup/cgroup.c' line='2451' column='1'/>
         <return type-id='f23e2572'/>
       </function-decl>
       <function-decl name='check_cache_active' mangled-name='check_cache_active' filepath='mm/swap_slots.c' line='101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='check_cache_active'>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='check_move_unevictable_pages' mangled-name='check_move_unevictable_pages' filepath='mm/vmscan.c' line='4413' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='check_move_unevictable_pages'>
-        <parameter type-id='f7d3421a' name='pvec' filepath='mm/vmscan.c' line='4413' column='1'/>
+      <function-decl name='check_move_unevictable_pages' mangled-name='check_move_unevictable_pages' filepath='mm/vmscan.c' line='4426' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='check_move_unevictable_pages'>
+        <parameter type-id='f7d3421a' name='pvec' filepath='mm/vmscan.c' line='4426' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='check_preempt_curr' mangled-name='check_preempt_curr' filepath='kernel/sched/core.c' line='1778' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='check_preempt_curr'>
-        <parameter type-id='6ed6b432' name='rq' filepath='kernel/sched/core.c' line='1778' column='1'/>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='1778' column='1'/>
-        <parameter type-id='95e97e5e' name='flags' filepath='kernel/sched/core.c' line='1778' column='1'/>
+      <function-decl name='check_preempt_curr' mangled-name='check_preempt_curr' filepath='kernel/sched/core.c' line='1781' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='check_preempt_curr'>
+        <parameter type-id='6ed6b432' name='rq' filepath='kernel/sched/core.c' line='1781' column='1'/>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='1781' column='1'/>
+        <parameter type-id='95e97e5e' name='flags' filepath='kernel/sched/core.c' line='1781' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='check_zeroed_user' mangled-name='check_zeroed_user' filepath='lib/usercopy.c' line='54' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='check_zeroed_user'>
-        <parameter type-id='eaa32e2f' name='from' filepath='lib/usercopy.c' line='54' column='1'/>
-        <parameter type-id='b59d7dce' name='size' filepath='lib/usercopy.c' line='54' column='1'/>
+      <function-decl name='check_zeroed_user' mangled-name='check_zeroed_user' filepath='lib/usercopy.c' line='61' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='check_zeroed_user'>
+        <parameter type-id='eaa32e2f' name='from' filepath='lib/usercopy.c' line='61' column='1'/>
+        <parameter type-id='b59d7dce' name='size' filepath='lib/usercopy.c' line='61' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='class_create_file_ns' mangled-name='class_create_file_ns' filepath='drivers/base/class.c' line='88' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='class_create_file_ns'>
@@ -123484,26 +124154,26 @@
         <parameter type-id='eaa32e2f' name='ns' filepath='drivers/base/class.c' line='89' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='class_destroy' mangled-name='class_destroy' filepath='drivers/base/class.c' line='261' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='class_destroy'>
-        <parameter type-id='67aca04f' name='cls' filepath='drivers/base/class.c' line='261' column='1'/>
+      <function-decl name='class_destroy' mangled-name='class_destroy' filepath='drivers/base/class.c' line='266' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='class_destroy'>
+        <parameter type-id='67aca04f' name='cls' filepath='drivers/base/class.c' line='266' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='class_find_device' mangled-name='class_find_device' filepath='drivers/base/class.c' line='399' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='class_find_device'>
-        <parameter type-id='67aca04f' name='class' filepath='drivers/base/class.c' line='399' column='1'/>
-        <parameter type-id='fa0b179b' name='start' filepath='drivers/base/class.c' line='399' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/base/class.c' line='400' column='1'/>
-        <parameter type-id='92d15ae9' name='match' filepath='drivers/base/class.c' line='401' column='1'/>
+      <function-decl name='class_find_device' mangled-name='class_find_device' filepath='drivers/base/class.c' line='404' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='class_find_device'>
+        <parameter type-id='67aca04f' name='class' filepath='drivers/base/class.c' line='404' column='1'/>
+        <parameter type-id='fa0b179b' name='start' filepath='drivers/base/class.c' line='404' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/base/class.c' line='405' column='1'/>
+        <parameter type-id='92d15ae9' name='match' filepath='drivers/base/class.c' line='406' column='1'/>
         <return type-id='fa0b179b'/>
       </function-decl>
-      <function-decl name='class_for_each_device' mangled-name='class_for_each_device' filepath='drivers/base/class.c' line='352' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='class_for_each_device'>
-        <parameter type-id='67aca04f' name='class' filepath='drivers/base/class.c' line='352' column='1'/>
-        <parameter type-id='fa0b179b' name='start' filepath='drivers/base/class.c' line='352' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/base/class.c' line='353' column='1'/>
-        <parameter type-id='92d15ae9' name='fn' filepath='drivers/base/class.c' line='353' column='1'/>
+      <function-decl name='class_for_each_device' mangled-name='class_for_each_device' filepath='drivers/base/class.c' line='357' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='class_for_each_device'>
+        <parameter type-id='67aca04f' name='class' filepath='drivers/base/class.c' line='357' column='1'/>
+        <parameter type-id='fa0b179b' name='start' filepath='drivers/base/class.c' line='357' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/base/class.c' line='358' column='1'/>
+        <parameter type-id='92d15ae9' name='fn' filepath='drivers/base/class.c' line='358' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='class_interface_unregister' mangled-name='class_interface_unregister' filepath='drivers/base/class.c' line='453' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='class_interface_unregister'>
-        <parameter type-id='ec167ceb' name='class_intf' filepath='drivers/base/class.c' line='453' column='1'/>
+      <function-decl name='class_interface_unregister' mangled-name='class_interface_unregister' filepath='drivers/base/class.c' line='458' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='class_interface_unregister'>
+        <parameter type-id='ec167ceb' name='class_intf' filepath='drivers/base/class.c' line='458' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='class_remove_file_ns' mangled-name='class_remove_file_ns' filepath='drivers/base/class.c' line='101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='class_remove_file_ns'>
@@ -123512,8 +124182,8 @@
         <parameter type-id='eaa32e2f' name='ns' filepath='drivers/base/class.c' line='102' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='class_unregister' mangled-name='class_unregister' filepath='drivers/base/class.c' line='199' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='class_unregister'>
-        <parameter type-id='67aca04f' name='cls' filepath='drivers/base/class.c' line='199' column='1'/>
+      <function-decl name='class_unregister' mangled-name='class_unregister' filepath='drivers/base/class.c' line='204' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='class_unregister'>
+        <parameter type-id='67aca04f' name='cls' filepath='drivers/base/class.c' line='204' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='clean_bdev_aliases' mangled-name='clean_bdev_aliases' filepath='fs/buffer.c' line='1634' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clean_bdev_aliases'>
@@ -123583,14 +124253,14 @@
         <parameter type-id='f034b024' name='clks' filepath='drivers/clk/clk-bulk.c' line='161' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='clk_disable' mangled-name='clk_disable' filepath='drivers/clk/clk.c' line='1012' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_disable'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='1012' column='1'/>
+      <function-decl name='clk_disable' mangled-name='clk_disable' filepath='drivers/clk/clk.c' line='1023' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_disable'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='1023' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <var-decl name='clk_divider_ops' type-id='92072f8b' mangled-name='clk_divider_ops' visibility='default' filepath='drivers/clk/clk-divider.c' line='453' column='1' elf-symbol-id='clk_divider_ops'/>
       <var-decl name='clk_divider_ro_ops' type-id='92072f8b' mangled-name='clk_divider_ro_ops' visibility='default' filepath='drivers/clk/clk-divider.c' line='460' column='1' elf-symbol-id='clk_divider_ro_ops'/>
-      <function-decl name='clk_enable' mangled-name='clk_enable' filepath='drivers/clk/clk.c' line='1177' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_enable'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='1177' column='1'/>
+      <function-decl name='clk_enable' mangled-name='clk_enable' filepath='drivers/clk/clk.c' line='1188' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_enable'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='1188' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <var-decl name='clk_fixed_factor_ops' type-id='92072f8b' mangled-name='clk_fixed_factor_ops' visibility='default' filepath='drivers/clk/clk-fixed-factor.c' line='60' column='1' elf-symbol-id='clk_fixed_factor_ops'/>
@@ -123602,54 +124272,59 @@
         <parameter type-id='80f4b756' name='con_id' filepath='drivers/clk/clkdev.c' line='100' column='1'/>
         <return type-id='7d0bc0eb'/>
       </function-decl>
-      <function-decl name='clk_get_parent' mangled-name='clk_get_parent' filepath='drivers/clk/clk.c' line='2512' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_get_parent'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='2512' column='1'/>
+      <function-decl name='clk_get_parent' mangled-name='clk_get_parent' filepath='drivers/clk/clk.c' line='2523' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_get_parent'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='2523' column='1'/>
         <return type-id='7d0bc0eb'/>
       </function-decl>
-      <function-decl name='clk_get_phase' mangled-name='clk_get_phase' filepath='drivers/clk/clk.c' line='2796' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_get_phase'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='2796' column='1'/>
+      <function-decl name='clk_get_phase' mangled-name='clk_get_phase' filepath='drivers/clk/clk.c' line='2807' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_get_phase'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='2807' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='clk_get_rate' mangled-name='clk_get_rate' filepath='drivers/clk/clk.c' line='1690' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_get_rate'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='1690' column='1'/>
+      <function-decl name='clk_get_rate' mangled-name='clk_get_rate' filepath='drivers/clk/clk.c' line='1701' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_get_rate'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='1701' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='clk_hw_get_flags' mangled-name='clk_hw_get_flags' filepath='drivers/clk/clk.c' line='505' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_get_flags'>
-        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='505' column='1'/>
+      <function-decl name='clk_has_parent' mangled-name='clk_has_parent' filepath='drivers/clk/clk.c' line='2575' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_has_parent'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='2575' column='1'/>
+        <parameter type-id='7d0bc0eb' name='parent' filepath='drivers/clk/clk.c' line='2575' column='1'/>
+        <return type-id='b50a4934'/>
+      </function-decl>
+      <function-decl name='clk_hw_get_flags' mangled-name='clk_hw_get_flags' filepath='drivers/clk/clk.c' line='516' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_get_flags'>
+        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='516' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='clk_hw_get_name' mangled-name='clk_hw_get_name' filepath='drivers/clk/clk.c' line='272' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_get_name'>
-        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='272' column='1'/>
+      <function-decl name='clk_hw_get_name' mangled-name='clk_hw_get_name' filepath='drivers/clk/clk.c' line='283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_get_name'>
+        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='283' column='1'/>
         <return type-id='80f4b756'/>
       </function-decl>
-      <function-decl name='clk_hw_get_num_parents' mangled-name='clk_hw_get_num_parents' filepath='drivers/clk/clk.c' line='284' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_get_num_parents'>
-        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='284' column='1'/>
+      <function-decl name='clk_hw_get_num_parents' mangled-name='clk_hw_get_num_parents' filepath='drivers/clk/clk.c' line='295' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_get_num_parents'>
+        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='295' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='clk_hw_get_parent' mangled-name='clk_hw_get_parent' filepath='drivers/clk/clk.c' line='290' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_get_parent'>
-        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='290' column='1'/>
+      <function-decl name='clk_hw_get_parent' mangled-name='clk_hw_get_parent' filepath='drivers/clk/clk.c' line='301' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_get_parent'>
+        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='301' column='1'/>
         <return type-id='3aaeef89'/>
       </function-decl>
-      <function-decl name='clk_hw_get_parent_by_index' mangled-name='clk_hw_get_parent_by_index' filepath='drivers/clk/clk.c' line='460' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_get_parent_by_index'>
-        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='460' column='1'/>
-        <parameter type-id='f0981eeb' name='index' filepath='drivers/clk/clk.c' line='460' column='1'/>
+      <function-decl name='clk_hw_get_parent_by_index' mangled-name='clk_hw_get_parent_by_index' filepath='drivers/clk/clk.c' line='471' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_get_parent_by_index'>
+        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='471' column='1'/>
+        <parameter type-id='f0981eeb' name='index' filepath='drivers/clk/clk.c' line='471' column='1'/>
         <return type-id='3aaeef89'/>
       </function-decl>
-      <function-decl name='clk_hw_get_rate' mangled-name='clk_hw_get_rate' filepath='drivers/clk/clk.c' line='491' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_get_rate'>
-        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='491' column='1'/>
+      <function-decl name='clk_hw_get_rate' mangled-name='clk_hw_get_rate' filepath='drivers/clk/clk.c' line='502' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_get_rate'>
+        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='502' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='clk_hw_is_enabled' mangled-name='clk_hw_is_enabled' filepath='drivers/clk/clk.c' line='523' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_is_enabled'>
-        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='523' column='1'/>
+      <function-decl name='clk_hw_is_enabled' mangled-name='clk_hw_is_enabled' filepath='drivers/clk/clk.c' line='534' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_is_enabled'>
+        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='534' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='clk_hw_is_prepared' mangled-name='clk_hw_is_prepared' filepath='drivers/clk/clk.c' line='511' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_is_prepared'>
-        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='511' column='1'/>
+      <function-decl name='clk_hw_is_prepared' mangled-name='clk_hw_is_prepared' filepath='drivers/clk/clk.c' line='522' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_is_prepared'>
+        <parameter type-id='9e6d4b4e' name='hw' filepath='drivers/clk/clk.c' line='522' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='clk_hw_register' mangled-name='clk_hw_register' filepath='drivers/clk/clk.c' line='4065' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_register'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk.c' line='4065' column='1'/>
-        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='4065' column='1'/>
+      <function-decl name='clk_hw_register' mangled-name='clk_hw_register' filepath='drivers/clk/clk.c' line='4076' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_register'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk.c' line='4076' column='1'/>
+        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='4076' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='clk_hw_register_composite' mangled-name='clk_hw_register_composite' filepath='drivers/clk/clk-composite.c' line='319' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_register_composite'>
@@ -123675,24 +124350,24 @@
         <parameter type-id='f0981eeb' name='div' filepath='drivers/clk/clk-fixed-factor.c' line='111' column='1'/>
         <return type-id='3aaeef89'/>
       </function-decl>
-      <function-decl name='clk_hw_round_rate' mangled-name='clk_hw_round_rate' filepath='drivers/clk/clk.c' line='1471' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_round_rate'>
-        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='1471' column='1'/>
-        <parameter type-id='7359adad' name='rate' filepath='drivers/clk/clk.c' line='1471' column='1'/>
+      <function-decl name='clk_hw_round_rate' mangled-name='clk_hw_round_rate' filepath='drivers/clk/clk.c' line='1482' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_round_rate'>
+        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='1482' column='1'/>
+        <parameter type-id='7359adad' name='rate' filepath='drivers/clk/clk.c' line='1482' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='clk_hw_set_parent' mangled-name='clk_hw_set_parent' filepath='drivers/clk/clk.c' line='2653' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_set_parent'>
-        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='2653' column='1'/>
-        <parameter type-id='3aaeef89' name='parent' filepath='drivers/clk/clk.c' line='2653' column='1'/>
+      <function-decl name='clk_hw_set_parent' mangled-name='clk_hw_set_parent' filepath='drivers/clk/clk.c' line='2664' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_set_parent'>
+        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='2664' column='1'/>
+        <parameter type-id='3aaeef89' name='parent' filepath='drivers/clk/clk.c' line='2664' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='clk_hw_set_rate_range' mangled-name='clk_hw_set_rate_range' filepath='drivers/clk/clk.c' line='654' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_set_rate_range'>
-        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='654' column='1'/>
-        <parameter type-id='7359adad' name='min_rate' filepath='drivers/clk/clk.c' line='654' column='1'/>
-        <parameter type-id='7359adad' name='max_rate' filepath='drivers/clk/clk.c' line='655' column='1'/>
+      <function-decl name='clk_hw_set_rate_range' mangled-name='clk_hw_set_rate_range' filepath='drivers/clk/clk.c' line='665' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_set_rate_range'>
+        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='665' column='1'/>
+        <parameter type-id='7359adad' name='min_rate' filepath='drivers/clk/clk.c' line='665' column='1'/>
+        <parameter type-id='7359adad' name='max_rate' filepath='drivers/clk/clk.c' line='666' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='clk_hw_unregister' mangled-name='clk_hw_unregister' filepath='drivers/clk/clk.c' line='4230' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_unregister'>
-        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='4230' column='1'/>
+      <function-decl name='clk_hw_unregister' mangled-name='clk_hw_unregister' filepath='drivers/clk/clk.c' line='4241' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_unregister'>
+        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='4241' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='clk_hw_unregister_divider' mangled-name='clk_hw_unregister_divider' filepath='drivers/clk/clk-divider.c' line='576' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_hw_unregister_divider'>
@@ -123711,9 +124386,9 @@
         <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk-mux.c' line='241' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='clk_is_match' mangled-name='clk_is_match' filepath='drivers/clk/clk.c' line='2988' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_is_match'>
-        <parameter type-id='10f66866' name='p' filepath='drivers/clk/clk.c' line='2988' column='1'/>
-        <parameter type-id='10f66866' name='q' filepath='drivers/clk/clk.c' line='2988' column='1'/>
+      <function-decl name='clk_is_match' mangled-name='clk_is_match' filepath='drivers/clk/clk.c' line='2999' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_is_match'>
+        <parameter type-id='10f66866' name='p' filepath='drivers/clk/clk.c' line='2999' column='1'/>
+        <parameter type-id='10f66866' name='q' filepath='drivers/clk/clk.c' line='2999' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='clk_mux_index_to_val' mangled-name='clk_mux_index_to_val' filepath='drivers/clk/clk-mux.c' line='69' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_mux_index_to_val'>
@@ -123724,27 +124399,27 @@
       </function-decl>
       <var-decl name='clk_mux_ops' type-id='92072f8b' mangled-name='clk_mux_ops' visibility='default' filepath='drivers/clk/clk-mux.c' line='136' column='1' elf-symbol-id='clk_mux_ops'/>
       <var-decl name='clk_mux_ro_ops' type-id='92072f8b' mangled-name='clk_mux_ro_ops' visibility='default' filepath='drivers/clk/clk-mux.c' line='143' column='1' elf-symbol-id='clk_mux_ro_ops'/>
-      <function-decl name='clk_notifier_register' mangled-name='clk_notifier_register' filepath='drivers/clk/clk.c' line='4460' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_notifier_register'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='4460' column='1'/>
-        <parameter type-id='d504f73d' name='nb' filepath='drivers/clk/clk.c' line='4460' column='1'/>
+      <function-decl name='clk_notifier_register' mangled-name='clk_notifier_register' filepath='drivers/clk/clk.c' line='4471' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_notifier_register'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='4471' column='1'/>
+        <parameter type-id='d504f73d' name='nb' filepath='drivers/clk/clk.c' line='4471' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='clk_notifier_unregister' mangled-name='clk_notifier_unregister' filepath='drivers/clk/clk.c' line='4508' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_notifier_unregister'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='4508' column='1'/>
-        <parameter type-id='d504f73d' name='nb' filepath='drivers/clk/clk.c' line='4508' column='1'/>
+      <function-decl name='clk_notifier_unregister' mangled-name='clk_notifier_unregister' filepath='drivers/clk/clk.c' line='4519' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_notifier_unregister'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='4519' column='1'/>
+        <parameter type-id='d504f73d' name='nb' filepath='drivers/clk/clk.c' line='4519' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='clk_prepare' mangled-name='clk_prepare' filepath='drivers/clk/clk.c' line='955' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_prepare'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='955' column='1'/>
+      <function-decl name='clk_prepare' mangled-name='clk_prepare' filepath='drivers/clk/clk.c' line='966' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_prepare'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='966' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='clk_put' mangled-name='clk_put' filepath='drivers/clk/clkdev.c' line='115' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_put'>
         <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clkdev.c' line='115' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='clk_register' mangled-name='clk_register' filepath='drivers/clk/clk.c' line='4049' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_register'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk.c' line='4049' column='1'/>
-        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='4049' column='1'/>
+      <function-decl name='clk_register' mangled-name='clk_register' filepath='drivers/clk/clk.c' line='4060' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_register'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk.c' line='4060' column='1'/>
+        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='4060' column='1'/>
         <return type-id='7d0bc0eb'/>
       </function-decl>
       <function-decl name='clk_register_clkdev' mangled-name='clk_register_clkdev' filepath='drivers/clk/clkdev.c' line='341' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_register_clkdev'>
@@ -123822,42 +124497,42 @@
         <parameter type-id='cff2d845' name='lock' filepath='drivers/clk/clk-mux.c' line='212' column='1'/>
         <return type-id='7d0bc0eb'/>
       </function-decl>
-      <function-decl name='clk_round_rate' mangled-name='clk_round_rate' filepath='drivers/clk/clk.c' line='1496' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_round_rate'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='1496' column='1'/>
-        <parameter type-id='7359adad' name='rate' filepath='drivers/clk/clk.c' line='1496' column='1'/>
+      <function-decl name='clk_round_rate' mangled-name='clk_round_rate' filepath='drivers/clk/clk.c' line='1507' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_round_rate'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='1507' column='1'/>
+        <parameter type-id='7359adad' name='rate' filepath='drivers/clk/clk.c' line='1507' column='1'/>
         <return type-id='bd54fe1a'/>
       </function-decl>
-      <function-decl name='clk_set_duty_cycle' mangled-name='clk_set_duty_cycle' filepath='drivers/clk/clk.c' line='2912' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_set_duty_cycle'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='2912' column='1'/>
-        <parameter type-id='f0981eeb' name='num' filepath='drivers/clk/clk.c' line='2912' column='1'/>
-        <parameter type-id='f0981eeb' name='den' filepath='drivers/clk/clk.c' line='2912' column='1'/>
+      <function-decl name='clk_set_duty_cycle' mangled-name='clk_set_duty_cycle' filepath='drivers/clk/clk.c' line='2923' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_set_duty_cycle'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='2923' column='1'/>
+        <parameter type-id='f0981eeb' name='num' filepath='drivers/clk/clk.c' line='2923' column='1'/>
+        <parameter type-id='f0981eeb' name='den' filepath='drivers/clk/clk.c' line='2923' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='clk_set_parent' mangled-name='clk_set_parent' filepath='drivers/clk/clk.c' line='2676' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_set_parent'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='2676' column='1'/>
-        <parameter type-id='7d0bc0eb' name='parent' filepath='drivers/clk/clk.c' line='2676' column='1'/>
+      <function-decl name='clk_set_parent' mangled-name='clk_set_parent' filepath='drivers/clk/clk.c' line='2687' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_set_parent'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='2687' column='1'/>
+        <parameter type-id='7d0bc0eb' name='parent' filepath='drivers/clk/clk.c' line='2687' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='clk_set_phase' mangled-name='clk_set_phase' filepath='drivers/clk/clk.c' line='2745' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_set_phase'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='2745' column='1'/>
-        <parameter type-id='95e97e5e' name='degrees' filepath='drivers/clk/clk.c' line='2745' column='1'/>
+      <function-decl name='clk_set_phase' mangled-name='clk_set_phase' filepath='drivers/clk/clk.c' line='2756' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_set_phase'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='2756' column='1'/>
+        <parameter type-id='95e97e5e' name='degrees' filepath='drivers/clk/clk.c' line='2756' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='clk_set_rate' mangled-name='clk_set_rate' filepath='drivers/clk/clk.c' line='2326' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_set_rate'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='2326' column='1'/>
-        <parameter type-id='7359adad' name='rate' filepath='drivers/clk/clk.c' line='2326' column='1'/>
+      <function-decl name='clk_set_rate' mangled-name='clk_set_rate' filepath='drivers/clk/clk.c' line='2337' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_set_rate'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='2337' column='1'/>
+        <parameter type-id='7359adad' name='rate' filepath='drivers/clk/clk.c' line='2337' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='clk_sync_state' mangled-name='clk_sync_state' filepath='drivers/clk/clk.c' line='1344' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_sync_state'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk.c' line='1344' column='1'/>
+      <function-decl name='clk_sync_state' mangled-name='clk_sync_state' filepath='drivers/clk/clk.c' line='1355' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_sync_state'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk.c' line='1355' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='clk_unprepare' mangled-name='clk_unprepare' filepath='drivers/clk/clk.c' line='874' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_unprepare'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='874' column='1'/>
+      <function-decl name='clk_unprepare' mangled-name='clk_unprepare' filepath='drivers/clk/clk.c' line='885' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_unprepare'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='885' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='clk_unregister' mangled-name='clk_unregister' filepath='drivers/clk/clk.c' line='4168' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_unregister'>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='4168' column='1'/>
+      <function-decl name='clk_unregister' mangled-name='clk_unregister' filepath='drivers/clk/clk.c' line='4179' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clk_unregister'>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk.c' line='4179' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='clockevents_config_and_register' mangled-name='clockevents_config_and_register' filepath='kernel/time/clockevents.c' line='505' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='clockevents_config_and_register'>
@@ -123939,9 +124614,9 @@
         <parameter type-id='389faaf7' name='x' filepath='kernel/sched/completion.c' line='57' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='complete_and_exit' mangled-name='complete_and_exit' filepath='kernel/exit.c' line='868' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='complete_and_exit'>
-        <parameter type-id='389faaf7' name='comp' filepath='kernel/exit.c' line='868' column='1'/>
-        <parameter type-id='bd54fe1a' name='code' filepath='kernel/exit.c' line='868' column='1'/>
+      <function-decl name='complete_and_exit' mangled-name='complete_and_exit' filepath='kernel/exit.c' line='940' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='complete_and_exit'>
+        <parameter type-id='389faaf7' name='comp' filepath='kernel/exit.c' line='940' column='1'/>
+        <parameter type-id='bd54fe1a' name='code' filepath='kernel/exit.c' line='940' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='completion_done' mangled-name='completion_done' filepath='kernel/sched/completion.c' line='315' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='completion_done'>
@@ -124000,8 +124675,8 @@
         <parameter type-id='eaa32e2f' name='data' filepath='drivers/base/component.c' line='549' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='cond_synchronize_rcu' mangled-name='cond_synchronize_rcu' filepath='kernel/rcu/tree.c' line='3719' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cond_synchronize_rcu'>
-        <parameter type-id='7359adad' name='oldstate' filepath='kernel/rcu/tree.c' line='3719' column='1'/>
+      <function-decl name='cond_synchronize_rcu' mangled-name='cond_synchronize_rcu' filepath='kernel/rcu/tree.c' line='3748' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cond_synchronize_rcu'>
+        <parameter type-id='7359adad' name='oldstate' filepath='kernel/rcu/tree.c' line='3748' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='config_ep_by_speed' mangled-name='config_ep_by_speed' filepath='drivers/usb/gadget/composite.c' line='292' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='config_ep_by_speed'>
@@ -124028,17 +124703,17 @@
         <parameter type-id='7a29ff27' name='item' filepath='fs/configfs/item.c' line='148' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='configfs_register_subsystem' mangled-name='configfs_register_subsystem' filepath='fs/configfs/dir.c' line='1887' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='configfs_register_subsystem'>
-        <parameter type-id='598755ca' name='subsys' filepath='fs/configfs/dir.c' line='1887' column='1'/>
+      <function-decl name='configfs_register_subsystem' mangled-name='configfs_register_subsystem' filepath='fs/configfs/dir.c' line='1889' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='configfs_register_subsystem'>
+        <parameter type-id='598755ca' name='subsys' filepath='fs/configfs/dir.c' line='1889' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='configfs_unregister_subsystem' mangled-name='configfs_unregister_subsystem' filepath='fs/configfs/dir.c' line='1947' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='configfs_unregister_subsystem'>
-        <parameter type-id='598755ca' name='subsys' filepath='fs/configfs/dir.c' line='1947' column='1'/>
+      <function-decl name='configfs_unregister_subsystem' mangled-name='configfs_unregister_subsystem' filepath='fs/configfs/dir.c' line='1949' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='configfs_unregister_subsystem'>
+        <parameter type-id='598755ca' name='subsys' filepath='fs/configfs/dir.c' line='1949' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='congestion_wait' mangled-name='congestion_wait' filepath='mm/backing-dev.c' line='959' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='congestion_wait'>
-        <parameter type-id='95e97e5e' name='sync' filepath='mm/backing-dev.c' line='959' column='1'/>
-        <parameter type-id='bd54fe1a' name='timeout' filepath='mm/backing-dev.c' line='959' column='1'/>
+      <function-decl name='congestion_wait' mangled-name='congestion_wait' filepath='mm/backing-dev.c' line='967' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='congestion_wait'>
+        <parameter type-id='95e97e5e' name='sync' filepath='mm/backing-dev.c' line='967' column='1'/>
+        <parameter type-id='bd54fe1a' name='timeout' filepath='mm/backing-dev.c' line='967' column='1'/>
         <return type-id='bd54fe1a'/>
       </function-decl>
       <var-decl name='console_drivers' type-id='b9aa0100' mangled-name='console_drivers' visibility='default' filepath='kernel/printk/printk.c' line='90' column='1' elf-symbol-id='console_drivers'/>
@@ -124057,8 +124732,8 @@
       <function-decl name='console_unlock' mangled-name='console_unlock' filepath='kernel/printk/printk.c' line='2442' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='console_unlock'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='consume_skb' mangled-name='consume_skb' filepath='net/core/skbuff.c' line='845' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='consume_skb'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='845' column='1'/>
+      <function-decl name='consume_skb' mangled-name='consume_skb' filepath='net/core/skbuff.c' line='844' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='consume_skb'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='844' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <var-decl name='contig_page_data' type-id='54406315' mangled-name='contig_page_data' visibility='default' filepath='mm/memblock.c' line='96' column='1' elf-symbol-id='contig_page_data'/>
@@ -124068,16 +124743,21 @@
         <parameter type-id='b59d7dce' name='size' filepath='mm/maccess.c' line='25' column='1'/>
         <return type-id='bd54fe1a'/>
       </function-decl>
+      <function-decl name='copy_highpage' mangled-name='copy_highpage' filepath='arch/arm64/mm/copypage.c' line='17' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='copy_highpage'>
+        <parameter type-id='02f11ed4' name='to' filepath='arch/arm64/mm/copypage.c' line='17' column='1'/>
+        <parameter type-id='02f11ed4' name='from' filepath='arch/arm64/mm/copypage.c' line='17' column='1'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
       <function-decl name='copy_to_user_fromio' mangled-name='copy_to_user_fromio' filepath='sound/core/memory.c' line='23' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='copy_to_user_fromio'>
         <parameter type-id='eaa32e2f' name='dst' filepath='sound/core/memory.c' line='23' column='1'/>
         <parameter type-id='60f8eab0' name='src' filepath='sound/core/memory.c' line='23' column='1'/>
         <parameter type-id='b59d7dce' name='count' filepath='sound/core/memory.c' line='23' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <var-decl name='cpu_all_bits' type-id='afe549fd' mangled-name='cpu_all_bits' visibility='default' filepath='kernel/cpu.c' line='2803' column='1' elf-symbol-id='cpu_all_bits'/>
-      <var-decl name='cpu_bit_bitmap' type-id='f959706c' mangled-name='cpu_bit_bitmap' visibility='default' filepath='kernel/cpu.c' line='2792' column='1' elf-symbol-id='cpu_bit_bitmap'/>
-      <function-decl name='cpu_have_feature' mangled-name='cpu_have_feature' filepath='arch/arm64/kernel/cpufeature.c' line='2892' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cpu_have_feature'>
-        <parameter type-id='f0981eeb' name='num' filepath='arch/arm64/kernel/cpufeature.c' line='2892' column='1'/>
+      <var-decl name='cpu_all_bits' type-id='afe549fd' mangled-name='cpu_all_bits' visibility='default' filepath='kernel/cpu.c' line='2805' column='1' elf-symbol-id='cpu_all_bits'/>
+      <var-decl name='cpu_bit_bitmap' type-id='f959706c' mangled-name='cpu_bit_bitmap' visibility='default' filepath='kernel/cpu.c' line='2794' column='1' elf-symbol-id='cpu_bit_bitmap'/>
+      <function-decl name='cpu_have_feature' mangled-name='cpu_have_feature' filepath='arch/arm64/kernel/cpufeature.c' line='2893' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cpu_have_feature'>
+        <parameter type-id='f0981eeb' name='num' filepath='arch/arm64/kernel/cpufeature.c' line='2893' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='cpu_hotplug_disable' mangled-name='cpu_hotplug_disable' filepath='kernel/cpu.c' line='360' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cpu_hotplug_disable'>
@@ -124371,9 +125051,9 @@
       <function-decl name='cpus_read_unlock' mangled-name='cpus_read_unlock' filepath='kernel/cpu.c' line='313' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cpus_read_unlock'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='cpuset_cpus_allowed' mangled-name='cpuset_cpus_allowed' filepath='kernel/cgroup/cpuset.c' line='3367' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cpuset_cpus_allowed'>
-        <parameter type-id='f23e2572' name='tsk' filepath='kernel/cgroup/cpuset.c' line='3367' column='1'/>
-        <parameter type-id='74bccedd' name='pmask' filepath='kernel/cgroup/cpuset.c' line='3367' column='1'/>
+      <function-decl name='cpuset_cpus_allowed' mangled-name='cpuset_cpus_allowed' filepath='kernel/cgroup/cpuset.c' line='3371' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cpuset_cpus_allowed'>
+        <parameter type-id='f23e2572' name='tsk' filepath='kernel/cgroup/cpuset.c' line='3371' column='1'/>
+        <parameter type-id='74bccedd' name='pmask' filepath='kernel/cgroup/cpuset.c' line='3371' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='crc16' mangled-name='crc16' filepath='lib/crc16.c' line='55' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crc16'>
@@ -124509,14 +125189,14 @@
         <parameter type-id='19c2251e' name='mask' filepath='crypto/skcipher.c' line='767' column='1'/>
         <return type-id='2e6a2f40'/>
       </function-decl>
-      <function-decl name='crypto_attr_alg_name' mangled-name='crypto_attr_alg_name' filepath='crypto/algapi.c' line='853' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_attr_alg_name'>
-        <parameter type-id='f28646d2' name='rta' filepath='crypto/algapi.c' line='853' column='1'/>
+      <function-decl name='crypto_attr_alg_name' mangled-name='crypto_attr_alg_name' filepath='crypto/algapi.c' line='855' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_attr_alg_name'>
+        <parameter type-id='f28646d2' name='rta' filepath='crypto/algapi.c' line='855' column='1'/>
         <return type-id='80f4b756'/>
       </function-decl>
-      <function-decl name='crypto_check_attr_type' mangled-name='crypto_check_attr_type' filepath='crypto/algapi.c' line='837' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_check_attr_type'>
-        <parameter type-id='c161b868' name='tb' filepath='crypto/algapi.c' line='837' column='1'/>
-        <parameter type-id='19c2251e' name='type' filepath='crypto/algapi.c' line='837' column='1'/>
-        <parameter type-id='f9409001' name='mask_ret' filepath='crypto/algapi.c' line='837' column='1'/>
+      <function-decl name='crypto_check_attr_type' mangled-name='crypto_check_attr_type' filepath='crypto/algapi.c' line='839' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_check_attr_type'>
+        <parameter type-id='c161b868' name='tb' filepath='crypto/algapi.c' line='839' column='1'/>
+        <parameter type-id='19c2251e' name='type' filepath='crypto/algapi.c' line='839' column='1'/>
+        <parameter type-id='f9409001' name='mask_ret' filepath='crypto/algapi.c' line='839' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='crypto_cipher_decrypt_one' mangled-name='crypto_cipher_decrypt_one' filepath='crypto/cipher.c' line='87' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_cipher_decrypt_one'>
@@ -124553,8 +125233,8 @@
         <parameter type-id='807869d3' name='dlen' filepath='crypto/compress.c' line='25' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='crypto_dequeue_request' mangled-name='crypto_dequeue_request' filepath='crypto/algapi.c' line='944' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_dequeue_request'>
-        <parameter type-id='1a8fddbe' name='queue' filepath='crypto/algapi.c' line='944' column='1'/>
+      <function-decl name='crypto_dequeue_request' mangled-name='crypto_dequeue_request' filepath='crypto/algapi.c' line='946' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_dequeue_request'>
+        <parameter type-id='1a8fddbe' name='queue' filepath='crypto/algapi.c' line='946' column='1'/>
         <return type-id='af5eeab9'/>
       </function-decl>
       <function-decl name='crypto_destroy_tfm' mangled-name='crypto_destroy_tfm' filepath='crypto/api.c' line='561' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_destroy_tfm'>
@@ -124562,13 +125242,13 @@
         <parameter type-id='dfeb7f6c' name='tfm' filepath='crypto/api.c' line='561' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='crypto_drop_spawn' mangled-name='crypto_drop_spawn' filepath='crypto/algapi.c' line='704' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_drop_spawn'>
-        <parameter type-id='5f880e0e' name='spawn' filepath='crypto/algapi.c' line='704' column='1'/>
+      <function-decl name='crypto_drop_spawn' mangled-name='crypto_drop_spawn' filepath='crypto/algapi.c' line='706' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_drop_spawn'>
+        <parameter type-id='5f880e0e' name='spawn' filepath='crypto/algapi.c' line='706' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='crypto_enqueue_request' mangled-name='crypto_enqueue_request' filepath='crypto/algapi.c' line='913' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_enqueue_request'>
-        <parameter type-id='1a8fddbe' name='queue' filepath='crypto/algapi.c' line='913' column='1'/>
-        <parameter type-id='af5eeab9' name='request' filepath='crypto/algapi.c' line='914' column='1'/>
+      <function-decl name='crypto_enqueue_request' mangled-name='crypto_enqueue_request' filepath='crypto/algapi.c' line='915' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_enqueue_request'>
+        <parameter type-id='1a8fddbe' name='queue' filepath='crypto/algapi.c' line='915' column='1'/>
+        <parameter type-id='af5eeab9' name='request' filepath='crypto/algapi.c' line='916' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <var-decl name='crypto_ft_tab' type-id='350bcc55' mangled-name='crypto_ft_tab' visibility='default' filepath='crypto/aes_generic.c' line='65' column='1' elf-symbol-id='crypto_ft_tab'/>
@@ -124607,12 +125287,12 @@
         <parameter type-id='19c2251e' name='mask' filepath='crypto/skcipher.c' line='752' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='crypto_grab_spawn' mangled-name='crypto_grab_spawn' filepath='crypto/algapi.c' line='669' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_grab_spawn'>
-        <parameter type-id='5f880e0e' name='spawn' filepath='crypto/algapi.c' line='669' column='1'/>
-        <parameter type-id='708ae4d0' name='inst' filepath='crypto/algapi.c' line='669' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='crypto/algapi.c' line='670' column='1'/>
-        <parameter type-id='19c2251e' name='type' filepath='crypto/algapi.c' line='670' column='1'/>
-        <parameter type-id='19c2251e' name='mask' filepath='crypto/algapi.c' line='670' column='1'/>
+      <function-decl name='crypto_grab_spawn' mangled-name='crypto_grab_spawn' filepath='crypto/algapi.c' line='671' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_grab_spawn'>
+        <parameter type-id='5f880e0e' name='spawn' filepath='crypto/algapi.c' line='671' column='1'/>
+        <parameter type-id='708ae4d0' name='inst' filepath='crypto/algapi.c' line='671' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='crypto/algapi.c' line='672' column='1'/>
+        <parameter type-id='19c2251e' name='type' filepath='crypto/algapi.c' line='672' column='1'/>
+        <parameter type-id='19c2251e' name='mask' filepath='crypto/algapi.c' line='672' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='crypto_has_alg' mangled-name='crypto_has_alg' filepath='crypto/api.c' line='578' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_has_alg'>
@@ -124621,20 +125301,20 @@
         <parameter type-id='19c2251e' name='mask' filepath='crypto/api.c' line='578' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='crypto_inc' mangled-name='crypto_inc' filepath='crypto/algapi.c' line='976' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_inc'>
-        <parameter type-id='8bff8096' name='a' filepath='crypto/algapi.c' line='976' column='1'/>
-        <parameter type-id='f0981eeb' name='size' filepath='crypto/algapi.c' line='976' column='1'/>
+      <function-decl name='crypto_inc' mangled-name='crypto_inc' filepath='crypto/algapi.c' line='978' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_inc'>
+        <parameter type-id='8bff8096' name='a' filepath='crypto/algapi.c' line='978' column='1'/>
+        <parameter type-id='f0981eeb' name='size' filepath='crypto/algapi.c' line='978' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='crypto_init_queue' mangled-name='crypto_init_queue' filepath='crypto/algapi.c' line='904' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_init_queue'>
-        <parameter type-id='1a8fddbe' name='queue' filepath='crypto/algapi.c' line='904' column='1'/>
-        <parameter type-id='f0981eeb' name='max_qlen' filepath='crypto/algapi.c' line='904' column='1'/>
+      <function-decl name='crypto_init_queue' mangled-name='crypto_init_queue' filepath='crypto/algapi.c' line='906' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_init_queue'>
+        <parameter type-id='1a8fddbe' name='queue' filepath='crypto/algapi.c' line='906' column='1'/>
+        <parameter type-id='f0981eeb' name='max_qlen' filepath='crypto/algapi.c' line='906' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='crypto_inst_setname' mangled-name='crypto_inst_setname' filepath='crypto/algapi.c' line='889' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_inst_setname'>
-        <parameter type-id='708ae4d0' name='inst' filepath='crypto/algapi.c' line='889' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='crypto/algapi.c' line='889' column='1'/>
-        <parameter type-id='67f526b5' name='alg' filepath='crypto/algapi.c' line='890' column='1'/>
+      <function-decl name='crypto_inst_setname' mangled-name='crypto_inst_setname' filepath='crypto/algapi.c' line='891' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_inst_setname'>
+        <parameter type-id='708ae4d0' name='inst' filepath='crypto/algapi.c' line='891' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='crypto/algapi.c' line='891' column='1'/>
+        <parameter type-id='67f526b5' name='alg' filepath='crypto/algapi.c' line='892' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <var-decl name='crypto_it_tab' type-id='350bcc55' mangled-name='crypto_it_tab' visibility='default' filepath='crypto/aes_generic.c' line='593' column='1' elf-symbol-id='crypto_it_tab'/>
@@ -124667,9 +125347,9 @@
         <parameter type-id='67f526b5' name='alg' filepath='crypto/algapi.c' line='412' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='crypto_register_algs' mangled-name='crypto_register_algs' filepath='crypto/algapi.c' line='467' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_register_algs'>
-        <parameter type-id='67f526b5' name='algs' filepath='crypto/algapi.c' line='467' column='1'/>
-        <parameter type-id='95e97e5e' name='count' filepath='crypto/algapi.c' line='467' column='1'/>
+      <function-decl name='crypto_register_algs' mangled-name='crypto_register_algs' filepath='crypto/algapi.c' line='469' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_register_algs'>
+        <parameter type-id='67f526b5' name='algs' filepath='crypto/algapi.c' line='469' column='1'/>
+        <parameter type-id='95e97e5e' name='count' filepath='crypto/algapi.c' line='469' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='crypto_register_rng' mangled-name='crypto_register_rng' filepath='crypto/rng.c' line='177' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_register_rng'>
@@ -124703,13 +125383,13 @@
         <parameter type-id='95e97e5e' name='count' filepath='crypto/skcipher.c' line='835' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='crypto_register_template' mangled-name='crypto_register_template' filepath='crypto/algapi.c' line='496' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_register_template'>
-        <parameter type-id='f0f856cb' name='tmpl' filepath='crypto/algapi.c' line='496' column='1'/>
+      <function-decl name='crypto_register_template' mangled-name='crypto_register_template' filepath='crypto/algapi.c' line='498' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_register_template'>
+        <parameter type-id='f0f856cb' name='tmpl' filepath='crypto/algapi.c' line='498' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='crypto_register_templates' mangled-name='crypto_register_templates' filepath='crypto/algapi.c' line='518' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_register_templates'>
-        <parameter type-id='f0f856cb' name='tmpls' filepath='crypto/algapi.c' line='518' column='1'/>
-        <parameter type-id='95e97e5e' name='count' filepath='crypto/algapi.c' line='518' column='1'/>
+      <function-decl name='crypto_register_templates' mangled-name='crypto_register_templates' filepath='crypto/algapi.c' line='520' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_register_templates'>
+        <parameter type-id='f0f856cb' name='tmpls' filepath='crypto/algapi.c' line='520' column='1'/>
+        <parameter type-id='95e97e5e' name='count' filepath='crypto/algapi.c' line='520' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='crypto_remove_final' mangled-name='crypto_remove_final' filepath='crypto/algapi.c' line='380' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_remove_final'>
@@ -124802,14 +125482,14 @@
         <parameter type-id='f0981eeb' name='keylen' filepath='crypto/skcipher.c' line='601' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='crypto_spawn_tfm' mangled-name='crypto_spawn_tfm' filepath='crypto/algapi.c' line='744' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_spawn_tfm'>
-        <parameter type-id='5f880e0e' name='spawn' filepath='crypto/algapi.c' line='744' column='1'/>
-        <parameter type-id='19c2251e' name='type' filepath='crypto/algapi.c' line='744' column='1'/>
-        <parameter type-id='19c2251e' name='mask' filepath='crypto/algapi.c' line='745' column='1'/>
+      <function-decl name='crypto_spawn_tfm' mangled-name='crypto_spawn_tfm' filepath='crypto/algapi.c' line='746' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_spawn_tfm'>
+        <parameter type-id='5f880e0e' name='spawn' filepath='crypto/algapi.c' line='746' column='1'/>
+        <parameter type-id='19c2251e' name='type' filepath='crypto/algapi.c' line='746' column='1'/>
+        <parameter type-id='19c2251e' name='mask' filepath='crypto/algapi.c' line='747' column='1'/>
         <return type-id='dfeb7f6c'/>
       </function-decl>
-      <function-decl name='crypto_spawn_tfm2' mangled-name='crypto_spawn_tfm2' filepath='crypto/algapi.c' line='770' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_spawn_tfm2'>
-        <parameter type-id='5f880e0e' name='spawn' filepath='crypto/algapi.c' line='770' column='1'/>
+      <function-decl name='crypto_spawn_tfm2' mangled-name='crypto_spawn_tfm2' filepath='crypto/algapi.c' line='772' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_spawn_tfm2'>
+        <parameter type-id='5f880e0e' name='spawn' filepath='crypto/algapi.c' line='772' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
       <function-decl name='crypto_unregister_aead' mangled-name='crypto_unregister_aead' filepath='crypto/aead.c' line='251' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_unregister_aead'>
@@ -124828,9 +125508,9 @@
         <parameter type-id='67f526b5' name='alg' filepath='crypto/algapi.c' line='447' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='crypto_unregister_algs' mangled-name='crypto_unregister_algs' filepath='crypto/algapi.c' line='487' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_unregister_algs'>
-        <parameter type-id='67f526b5' name='algs' filepath='crypto/algapi.c' line='487' column='1'/>
-        <parameter type-id='95e97e5e' name='count' filepath='crypto/algapi.c' line='487' column='1'/>
+      <function-decl name='crypto_unregister_algs' mangled-name='crypto_unregister_algs' filepath='crypto/algapi.c' line='489' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_unregister_algs'>
+        <parameter type-id='67f526b5' name='algs' filepath='crypto/algapi.c' line='489' column='1'/>
+        <parameter type-id='95e97e5e' name='count' filepath='crypto/algapi.c' line='489' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='crypto_unregister_rng' mangled-name='crypto_unregister_rng' filepath='crypto/rng.c' line='192' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_unregister_rng'>
@@ -124864,23 +125544,23 @@
         <parameter type-id='95e97e5e' name='count' filepath='crypto/skcipher.c' line='855' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='crypto_unregister_template' mangled-name='crypto_unregister_template' filepath='crypto/algapi.c' line='536' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_unregister_template'>
-        <parameter type-id='f0f856cb' name='tmpl' filepath='crypto/algapi.c' line='536' column='1'/>
+      <function-decl name='crypto_unregister_template' mangled-name='crypto_unregister_template' filepath='crypto/algapi.c' line='538' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_unregister_template'>
+        <parameter type-id='f0f856cb' name='tmpl' filepath='crypto/algapi.c' line='538' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='crypto_unregister_templates' mangled-name='crypto_unregister_templates' filepath='crypto/algapi.c' line='565' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_unregister_templates'>
-        <parameter type-id='f0f856cb' name='tmpls' filepath='crypto/algapi.c' line='565' column='1'/>
-        <parameter type-id='95e97e5e' name='count' filepath='crypto/algapi.c' line='565' column='1'/>
+      <function-decl name='crypto_unregister_templates' mangled-name='crypto_unregister_templates' filepath='crypto/algapi.c' line='567' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crypto_unregister_templates'>
+        <parameter type-id='f0f856cb' name='tmpls' filepath='crypto/algapi.c' line='567' column='1'/>
+        <parameter type-id='95e97e5e' name='count' filepath='crypto/algapi.c' line='567' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='css_next_child' mangled-name='css_next_child' filepath='kernel/cgroup/cgroup.c' line='4283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='css_next_child'>
-        <parameter type-id='cfff5953' name='pos' filepath='kernel/cgroup/cgroup.c' line='4283' column='1'/>
-        <parameter type-id='cfff5953' name='parent' filepath='kernel/cgroup/cgroup.c' line='4284' column='1'/>
+      <function-decl name='css_next_child' mangled-name='css_next_child' filepath='kernel/cgroup/cgroup.c' line='4298' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='css_next_child'>
+        <parameter type-id='cfff5953' name='pos' filepath='kernel/cgroup/cgroup.c' line='4298' column='1'/>
+        <parameter type-id='cfff5953' name='parent' filepath='kernel/cgroup/cgroup.c' line='4299' column='1'/>
         <return type-id='cfff5953'/>
       </function-decl>
-      <function-decl name='css_next_descendant_pre' mangled-name='css_next_descendant_pre' filepath='kernel/cgroup/cgroup.c' line='4353' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='css_next_descendant_pre'>
-        <parameter type-id='cfff5953' name='pos' filepath='kernel/cgroup/cgroup.c' line='4353' column='1'/>
-        <parameter type-id='cfff5953' name='root' filepath='kernel/cgroup/cgroup.c' line='4354' column='1'/>
+      <function-decl name='css_next_descendant_pre' mangled-name='css_next_descendant_pre' filepath='kernel/cgroup/cgroup.c' line='4368' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='css_next_descendant_pre'>
+        <parameter type-id='cfff5953' name='pos' filepath='kernel/cgroup/cgroup.c' line='4368' column='1'/>
+        <parameter type-id='cfff5953' name='root' filepath='kernel/cgroup/cgroup.c' line='4369' column='1'/>
         <return type-id='cfff5953'/>
       </function-decl>
       <function-decl name='csum_ipv6_magic' mangled-name='csum_ipv6_magic' filepath='arch/arm64/lib/csum.c' line='132' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='csum_ipv6_magic'>
@@ -124905,14 +125585,14 @@
         <parameter type-id='fbd88bba' name='sum' filepath='lib/checksum.c' line='159' column='1'/>
         <return type-id='fbd88bba'/>
       </function-decl>
-      <function-decl name='current_time' mangled-name='current_time' filepath='fs/inode.c' line='2285' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='current_time'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2285' column='1'/>
+      <function-decl name='current_time' mangled-name='current_time' filepath='fs/inode.c' line='2294' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='current_time'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2294' column='1'/>
         <return type-id='40a816ad'/>
       </function-decl>
       <function-decl name='current_umask' mangled-name='current_umask' filepath='fs/fs_struct.c' line='156' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='current_umask'>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='current_work' mangled-name='current_work' filepath='kernel/workqueue.c' line='4522' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='current_work'>
+      <function-decl name='current_work' mangled-name='current_work' filepath='kernel/workqueue.c' line='4525' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='current_work'>
         <return type-id='83c1bde6'/>
       </function-decl>
       <function-decl name='d_add' mangled-name='d_add' filepath='fs/dcache.c' line='2695' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='d_add'>
@@ -125013,10 +125693,10 @@
         <parameter type-id='42c8f564' name='s' filepath='fs/super.c' line='329' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='deactivate_task' mangled-name='deactivate_task' filepath='kernel/sched/core.c' line='1693' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='deactivate_task'>
-        <parameter type-id='6ed6b432' name='rq' filepath='kernel/sched/core.c' line='1693' column='1'/>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='1693' column='1'/>
-        <parameter type-id='95e97e5e' name='flags' filepath='kernel/sched/core.c' line='1693' column='1'/>
+      <function-decl name='deactivate_task' mangled-name='deactivate_task' filepath='kernel/sched/core.c' line='1696' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='deactivate_task'>
+        <parameter type-id='6ed6b432' name='rq' filepath='kernel/sched/core.c' line='1696' column='1'/>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='1696' column='1'/>
+        <parameter type-id='95e97e5e' name='flags' filepath='kernel/sched/core.c' line='1696' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='debug_locks_off' mangled-name='debug_locks_off' filepath='lib/debug_locks.c' line='39' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debug_locks_off'>
@@ -125029,39 +125709,39 @@
         <parameter type-id='b53e8dbb' name='ppos' filepath='fs/debugfs/file.c' line='367' column='1'/>
         <return type-id='79a0948f'/>
       </function-decl>
-      <function-decl name='debugfs_attr_write' mangled-name='debugfs_attr_write' filepath='fs/debugfs/file.c' line='381' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_attr_write'>
-        <parameter type-id='77e79a4b' name='file' filepath='fs/debugfs/file.c' line='381' column='1'/>
-        <parameter type-id='80f4b756' name='buf' filepath='fs/debugfs/file.c' line='381' column='1'/>
-        <parameter type-id='b59d7dce' name='len' filepath='fs/debugfs/file.c' line='382' column='1'/>
-        <parameter type-id='b53e8dbb' name='ppos' filepath='fs/debugfs/file.c' line='382' column='1'/>
+      <function-decl name='debugfs_attr_write' mangled-name='debugfs_attr_write' filepath='fs/debugfs/file.c' line='398' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_attr_write'>
+        <parameter type-id='77e79a4b' name='file' filepath='fs/debugfs/file.c' line='398' column='1'/>
+        <parameter type-id='80f4b756' name='buf' filepath='fs/debugfs/file.c' line='398' column='1'/>
+        <parameter type-id='b59d7dce' name='len' filepath='fs/debugfs/file.c' line='399' column='1'/>
+        <parameter type-id='b53e8dbb' name='ppos' filepath='fs/debugfs/file.c' line='399' column='1'/>
         <return type-id='79a0948f'/>
       </function-decl>
-      <function-decl name='debugfs_create_atomic_t' mangled-name='debugfs_create_atomic_t' filepath='fs/debugfs/file.c' line='769' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_atomic_t'>
-        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='769' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='769' column='1'/>
-        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='770' column='1'/>
-        <parameter type-id='8a47abc3' name='value' filepath='fs/debugfs/file.c' line='770' column='1'/>
+      <function-decl name='debugfs_create_atomic_t' mangled-name='debugfs_create_atomic_t' filepath='fs/debugfs/file.c' line='785' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_atomic_t'>
+        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='785' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='785' column='1'/>
+        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='786' column='1'/>
+        <parameter type-id='8a47abc3' name='value' filepath='fs/debugfs/file.c' line='786' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='debugfs_create_blob' mangled-name='debugfs_create_blob' filepath='fs/debugfs/file.c' line='917' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_blob'>
-        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='917' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='917' column='1'/>
-        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='918' column='1'/>
-        <parameter type-id='3a843513' name='blob' filepath='fs/debugfs/file.c' line='919' column='1'/>
+      <function-decl name='debugfs_create_blob' mangled-name='debugfs_create_blob' filepath='fs/debugfs/file.c' line='933' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_blob'>
+        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='933' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='933' column='1'/>
+        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='934' column='1'/>
+        <parameter type-id='3a843513' name='blob' filepath='fs/debugfs/file.c' line='935' column='1'/>
         <return type-id='27675065'/>
       </function-decl>
-      <function-decl name='debugfs_create_bool' mangled-name='debugfs_create_bool' filepath='fs/debugfs/file.c' line='864' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_bool'>
-        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='864' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='864' column='1'/>
-        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='865' column='1'/>
-        <parameter type-id='d8e6b335' name='value' filepath='fs/debugfs/file.c' line='865' column='1'/>
+      <function-decl name='debugfs_create_bool' mangled-name='debugfs_create_bool' filepath='fs/debugfs/file.c' line='880' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_bool'>
+        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='880' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='880' column='1'/>
+        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='881' column='1'/>
+        <parameter type-id='d8e6b335' name='value' filepath='fs/debugfs/file.c' line='881' column='1'/>
         <return type-id='27675065'/>
       </function-decl>
-      <function-decl name='debugfs_create_devm_seqfile' mangled-name='debugfs_create_devm_seqfile' filepath='fs/debugfs/file.c' line='1134' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_devm_seqfile'>
-        <parameter type-id='fa0b179b' name='dev' filepath='fs/debugfs/file.c' line='1134' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='1134' column='1'/>
-        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='1135' column='1'/>
-        <parameter type-id='0131eb61' name='read_fn' filepath='fs/debugfs/file.c' line='1136' column='1'/>
+      <function-decl name='debugfs_create_devm_seqfile' mangled-name='debugfs_create_devm_seqfile' filepath='fs/debugfs/file.c' line='1150' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_devm_seqfile'>
+        <parameter type-id='fa0b179b' name='dev' filepath='fs/debugfs/file.c' line='1150' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='1150' column='1'/>
+        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='1151' column='1'/>
+        <parameter type-id='0131eb61' name='read_fn' filepath='fs/debugfs/file.c' line='1152' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='debugfs_create_dir' mangled-name='debugfs_create_dir' filepath='fs/debugfs/inode.c' line='551' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_dir'>
@@ -125094,18 +125774,18 @@
         <parameter type-id='61758ee5' name='fops' filepath='fs/debugfs/inode.c' line='491' column='1'/>
         <return type-id='27675065'/>
       </function-decl>
-      <function-decl name='debugfs_create_regset32' mangled-name='debugfs_create_regset32' filepath='fs/debugfs/file.c' line='1094' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_regset32'>
-        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='1094' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='1094' column='1'/>
-        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='1095' column='1'/>
-        <parameter type-id='62fa2ea7' name='regset' filepath='fs/debugfs/file.c' line='1096' column='1'/>
+      <function-decl name='debugfs_create_regset32' mangled-name='debugfs_create_regset32' filepath='fs/debugfs/file.c' line='1110' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_regset32'>
+        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='1110' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='1110' column='1'/>
+        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='1111' column='1'/>
+        <parameter type-id='62fa2ea7' name='regset' filepath='fs/debugfs/file.c' line='1112' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='debugfs_create_size_t' mangled-name='debugfs_create_size_t' filepath='fs/debugfs/file.c' line='733' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_size_t'>
-        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='733' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='733' column='1'/>
-        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='734' column='1'/>
-        <parameter type-id='78c01427' name='value' filepath='fs/debugfs/file.c' line='734' column='1'/>
+      <function-decl name='debugfs_create_size_t' mangled-name='debugfs_create_size_t' filepath='fs/debugfs/file.c' line='749' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_size_t'>
+        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='749' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='749' column='1'/>
+        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='750' column='1'/>
+        <parameter type-id='78c01427' name='value' filepath='fs/debugfs/file.c' line='750' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='debugfs_create_symlink' mangled-name='debugfs_create_symlink' filepath='fs/debugfs/inode.c' line='654' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_symlink'>
@@ -125114,60 +125794,60 @@
         <parameter type-id='80f4b756' name='target' filepath='fs/debugfs/inode.c' line='655' column='1'/>
         <return type-id='27675065'/>
       </function-decl>
-      <function-decl name='debugfs_create_u16' mangled-name='debugfs_create_u16' filepath='fs/debugfs/file.c' line='478' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_u16'>
-        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='478' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='478' column='1'/>
-        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='478' column='1'/>
-        <parameter type-id='26d4d46f' name='value' filepath='fs/debugfs/file.c' line='479' column='1'/>
+      <function-decl name='debugfs_create_u16' mangled-name='debugfs_create_u16' filepath='fs/debugfs/file.c' line='494' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_u16'>
+        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='494' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='494' column='1'/>
+        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='494' column='1'/>
+        <parameter type-id='26d4d46f' name='value' filepath='fs/debugfs/file.c' line='495' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='debugfs_create_u32' mangled-name='debugfs_create_u32' filepath='fs/debugfs/file.c' line='514' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_u32'>
-        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='514' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='514' column='1'/>
-        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='514' column='1'/>
-        <parameter type-id='f9409001' name='value' filepath='fs/debugfs/file.c' line='515' column='1'/>
+      <function-decl name='debugfs_create_u32' mangled-name='debugfs_create_u32' filepath='fs/debugfs/file.c' line='530' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_u32'>
+        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='530' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='530' column='1'/>
+        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='530' column='1'/>
+        <parameter type-id='f9409001' name='value' filepath='fs/debugfs/file.c' line='531' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='debugfs_create_u64' mangled-name='debugfs_create_u64' filepath='fs/debugfs/file.c' line='551' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_u64'>
-        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='551' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='551' column='1'/>
-        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='551' column='1'/>
-        <parameter type-id='3df9fd28' name='value' filepath='fs/debugfs/file.c' line='552' column='1'/>
+      <function-decl name='debugfs_create_u64' mangled-name='debugfs_create_u64' filepath='fs/debugfs/file.c' line='567' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_u64'>
+        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='567' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='567' column='1'/>
+        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='567' column='1'/>
+        <parameter type-id='3df9fd28' name='value' filepath='fs/debugfs/file.c' line='568' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='debugfs_create_u8' mangled-name='debugfs_create_u8' filepath='fs/debugfs/file.c' line='442' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_u8'>
-        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='442' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='442' column='1'/>
-        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='442' column='1'/>
-        <parameter type-id='8bff8096' name='value' filepath='fs/debugfs/file.c' line='443' column='1'/>
+      <function-decl name='debugfs_create_u8' mangled-name='debugfs_create_u8' filepath='fs/debugfs/file.c' line='458' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_u8'>
+        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='458' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='458' column='1'/>
+        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='458' column='1'/>
+        <parameter type-id='8bff8096' name='value' filepath='fs/debugfs/file.c' line='459' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='debugfs_create_ulong' mangled-name='debugfs_create_ulong' filepath='fs/debugfs/file.c' line='599' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_ulong'>
-        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='599' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='599' column='1'/>
-        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='600' column='1'/>
-        <parameter type-id='1d2c2b85' name='value' filepath='fs/debugfs/file.c' line='600' column='1'/>
+      <function-decl name='debugfs_create_ulong' mangled-name='debugfs_create_ulong' filepath='fs/debugfs/file.c' line='615' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_ulong'>
+        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='615' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='615' column='1'/>
+        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='616' column='1'/>
+        <parameter type-id='1d2c2b85' name='value' filepath='fs/debugfs/file.c' line='616' column='1'/>
         <return type-id='27675065'/>
       </function-decl>
-      <function-decl name='debugfs_create_x32' mangled-name='debugfs_create_x32' filepath='fs/debugfs/file.c' line='681' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_x32'>
-        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='681' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='681' column='1'/>
-        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='681' column='1'/>
-        <parameter type-id='f9409001' name='value' filepath='fs/debugfs/file.c' line='682' column='1'/>
+      <function-decl name='debugfs_create_x32' mangled-name='debugfs_create_x32' filepath='fs/debugfs/file.c' line='697' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_x32'>
+        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='697' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='697' column='1'/>
+        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='697' column='1'/>
+        <parameter type-id='f9409001' name='value' filepath='fs/debugfs/file.c' line='698' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='debugfs_create_x64' mangled-name='debugfs_create_x64' filepath='fs/debugfs/file.c' line='699' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_x64'>
-        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='699' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='699' column='1'/>
-        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='699' column='1'/>
-        <parameter type-id='3df9fd28' name='value' filepath='fs/debugfs/file.c' line='700' column='1'/>
+      <function-decl name='debugfs_create_x64' mangled-name='debugfs_create_x64' filepath='fs/debugfs/file.c' line='715' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_x64'>
+        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='715' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='715' column='1'/>
+        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='715' column='1'/>
+        <parameter type-id='3df9fd28' name='value' filepath='fs/debugfs/file.c' line='716' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='debugfs_create_x8' mangled-name='debugfs_create_x8' filepath='fs/debugfs/file.c' line='645' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_x8'>
-        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='645' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='645' column='1'/>
-        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='645' column='1'/>
-        <parameter type-id='8bff8096' name='value' filepath='fs/debugfs/file.c' line='646' column='1'/>
+      <function-decl name='debugfs_create_x8' mangled-name='debugfs_create_x8' filepath='fs/debugfs/file.c' line='661' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_create_x8'>
+        <parameter type-id='80f4b756' name='name' filepath='fs/debugfs/file.c' line='661' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/debugfs/file.c' line='661' column='1'/>
+        <parameter type-id='27675065' name='parent' filepath='fs/debugfs/file.c' line='661' column='1'/>
+        <parameter type-id='8bff8096' name='value' filepath='fs/debugfs/file.c' line='662' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='debugfs_file_get' mangled-name='debugfs_file_get' filepath='fs/debugfs/file.c' line='82' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_file_get'>
@@ -125183,12 +125863,12 @@
         <parameter type-id='27675065' name='parent' filepath='fs/debugfs/inode.c' line='296' column='1'/>
         <return type-id='27675065'/>
       </function-decl>
-      <function-decl name='debugfs_print_regs32' mangled-name='debugfs_print_regs32' filepath='fs/debugfs/file.c' line='1036' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_print_regs32'>
-        <parameter type-id='f8dc9def' name='s' filepath='fs/debugfs/file.c' line='1036' column='1'/>
-        <parameter type-id='ec73f122' name='regs' filepath='fs/debugfs/file.c' line='1036' column='1'/>
-        <parameter type-id='95e97e5e' name='nregs' filepath='fs/debugfs/file.c' line='1037' column='1'/>
-        <parameter type-id='eaa32e2f' name='base' filepath='fs/debugfs/file.c' line='1037' column='1'/>
-        <parameter type-id='26a90f95' name='prefix' filepath='fs/debugfs/file.c' line='1037' column='1'/>
+      <function-decl name='debugfs_print_regs32' mangled-name='debugfs_print_regs32' filepath='fs/debugfs/file.c' line='1052' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_print_regs32'>
+        <parameter type-id='f8dc9def' name='s' filepath='fs/debugfs/file.c' line='1052' column='1'/>
+        <parameter type-id='ec73f122' name='regs' filepath='fs/debugfs/file.c' line='1052' column='1'/>
+        <parameter type-id='95e97e5e' name='nregs' filepath='fs/debugfs/file.c' line='1053' column='1'/>
+        <parameter type-id='eaa32e2f' name='base' filepath='fs/debugfs/file.c' line='1053' column='1'/>
+        <parameter type-id='26a90f95' name='prefix' filepath='fs/debugfs/file.c' line='1053' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='debugfs_remove' mangled-name='debugfs_remove' filepath='fs/debugfs/inode.c' line='722' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='debugfs_remove'>
@@ -125213,11 +125893,11 @@
         <parameter type-id='95e97e5e' name='whence' filepath='fs/read_write.c' line='236' column='1'/>
         <return type-id='69bf7bee'/>
       </function-decl>
-      <function-decl name='default_wake_function' mangled-name='default_wake_function' filepath='kernel/sched/core.c' line='5065' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='default_wake_function'>
-        <parameter type-id='ba9aa326' name='curr' filepath='kernel/sched/core.c' line='5065' column='1'/>
-        <parameter type-id='f0981eeb' name='mode' filepath='kernel/sched/core.c' line='5065' column='1'/>
-        <parameter type-id='95e97e5e' name='wake_flags' filepath='kernel/sched/core.c' line='5065' column='1'/>
-        <parameter type-id='eaa32e2f' name='key' filepath='kernel/sched/core.c' line='5066' column='1'/>
+      <function-decl name='default_wake_function' mangled-name='default_wake_function' filepath='kernel/sched/core.c' line='5067' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='default_wake_function'>
+        <parameter type-id='ba9aa326' name='curr' filepath='kernel/sched/core.c' line='5067' column='1'/>
+        <parameter type-id='f0981eeb' name='mode' filepath='kernel/sched/core.c' line='5067' column='1'/>
+        <parameter type-id='95e97e5e' name='wake_flags' filepath='kernel/sched/core.c' line='5067' column='1'/>
+        <parameter type-id='eaa32e2f' name='key' filepath='kernel/sched/core.c' line='5068' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='deferred_free' mangled-name='deferred_free' filepath='drivers/dma-buf/heaps/deferred-free-helper.c' line='25' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='deferred_free'>
@@ -125242,8 +125922,8 @@
         <parameter type-id='9248e67f' name='timer' filepath='kernel/time/timer.c' line='1358' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='delayed_work_timer_fn' mangled-name='delayed_work_timer_fn' filepath='kernel/workqueue.c' line='1634' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='delayed_work_timer_fn'>
-        <parameter type-id='9248e67f' name='t' filepath='kernel/workqueue.c' line='1634' column='1'/>
+      <function-decl name='delayed_work_timer_fn' mangled-name='delayed_work_timer_fn' filepath='kernel/workqueue.c' line='1637' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='delayed_work_timer_fn'>
+        <parameter type-id='9248e67f' name='t' filepath='kernel/workqueue.c' line='1637' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='delete_from_page_cache' mangled-name='delete_from_page_cache' filepath='mm/filemap.c' line='272' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='delete_from_page_cache'>
@@ -125266,8 +125946,8 @@
         <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='164' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='destroy_workqueue' mangled-name='destroy_workqueue' filepath='kernel/workqueue.c' line='4395' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='destroy_workqueue'>
-        <parameter type-id='242e3d19' name='wq' filepath='kernel/workqueue.c' line='4395' column='1'/>
+      <function-decl name='destroy_workqueue' mangled-name='destroy_workqueue' filepath='kernel/workqueue.c' line='4398' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='destroy_workqueue'>
+        <parameter type-id='242e3d19' name='wq' filepath='kernel/workqueue.c' line='4398' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='dev_alloc_name' mangled-name='dev_alloc_name' filepath='net/core/dev.c' line='1271' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_alloc_name'>
@@ -125276,16 +125956,16 @@
         <return type-id='95e97e5e'/>
       </function-decl>
       <var-decl name='dev_base_lock' type-id='ac16795b' mangled-name='dev_base_lock' visibility='default' filepath='net/core/dev.c' line='191' column='1' elf-symbol-id='dev_base_lock'/>
-      <function-decl name='dev_change_flags' mangled-name='dev_change_flags' filepath='net/core/dev.c' line='8562' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_change_flags'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='8562' column='1'/>
-        <parameter type-id='f0981eeb' name='flags' filepath='net/core/dev.c' line='8562' column='1'/>
-        <parameter type-id='5799dc94' name='extack' filepath='net/core/dev.c' line='8563' column='1'/>
+      <function-decl name='dev_change_flags' mangled-name='dev_change_flags' filepath='net/core/dev.c' line='8569' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_change_flags'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='8569' column='1'/>
+        <parameter type-id='f0981eeb' name='flags' filepath='net/core/dev.c' line='8569' column='1'/>
+        <parameter type-id='5799dc94' name='extack' filepath='net/core/dev.c' line='8570' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dev_change_net_namespace' mangled-name='dev_change_net_namespace' filepath='net/core/dev.c' line='10809' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_change_net_namespace'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10809' column='1'/>
-        <parameter type-id='a2bff676' name='net' filepath='net/core/dev.c' line='10809' column='1'/>
-        <parameter type-id='80f4b756' name='pat' filepath='net/core/dev.c' line='10809' column='1'/>
+      <function-decl name='dev_change_net_namespace' mangled-name='dev_change_net_namespace' filepath='net/core/dev.c' line='10814' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_change_net_namespace'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10814' column='1'/>
+        <parameter type-id='a2bff676' name='net' filepath='net/core/dev.c' line='10814' column='1'/>
+        <parameter type-id='80f4b756' name='pat' filepath='net/core/dev.c' line='10814' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='dev_close' mangled-name='dev_close' filepath='net/core/dev.c' line='1671' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_close'>
@@ -125320,9 +126000,9 @@
         <parameter is-variadic='yes'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dev_fetch_sw_netstats' mangled-name='dev_fetch_sw_netstats' filepath='net/core/dev.c' line='10386' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_fetch_sw_netstats'>
-        <parameter type-id='bd3860fe' name='s' filepath='net/core/dev.c' line='10386' column='1'/>
-        <parameter type-id='069eeb9e' name='netstats' filepath='net/core/dev.c' line='10387' column='1'/>
+      <function-decl name='dev_fetch_sw_netstats' mangled-name='dev_fetch_sw_netstats' filepath='net/core/dev.c' line='10391' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_fetch_sw_netstats'>
+        <parameter type-id='bd3860fe' name='s' filepath='net/core/dev.c' line='10391' column='1'/>
+        <parameter type-id='069eeb9e' name='netstats' filepath='net/core/dev.c' line='10392' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='dev_fwnode' mangled-name='dev_fwnode' filepath='drivers/base/property.c' line='21' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_fwnode'>
@@ -125354,9 +126034,9 @@
         <parameter type-id='80f4b756' name='name' filepath='drivers/base/regmap/regmap.c' line='1531' column='1'/>
         <return type-id='29af9a71'/>
       </function-decl>
-      <function-decl name='dev_get_stats' mangled-name='dev_get_stats' filepath='net/core/dev.c' line='10359' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_get_stats'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10359' column='1'/>
-        <parameter type-id='bd3860fe' name='storage' filepath='net/core/dev.c' line='10360' column='1'/>
+      <function-decl name='dev_get_stats' mangled-name='dev_get_stats' filepath='net/core/dev.c' line='10364' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_get_stats'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10364' column='1'/>
+        <parameter type-id='bd3860fe' name='storage' filepath='net/core/dev.c' line='10365' column='1'/>
         <return type-id='bd3860fe'/>
       </function-decl>
       <function-decl name='dev_mc_sync_multiple' mangled-name='dev_mc_sync_multiple' filepath='net/core/dev_addr_lists.c' line='893' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_mc_sync_multiple'>
@@ -125700,19 +126380,19 @@
         <parameter is-variadic='yes'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dev_queue_xmit' mangled-name='dev_queue_xmit' filepath='net/core/dev.c' line='4207' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_queue_xmit'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='4207' column='1'/>
+      <function-decl name='dev_queue_xmit' mangled-name='dev_queue_xmit' filepath='net/core/dev.c' line='4211' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_queue_xmit'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='4211' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dev_set_mac_address' mangled-name='dev_set_mac_address' filepath='net/core/dev.c' line='8739' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_set_mac_address'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='8739' column='1'/>
-        <parameter type-id='5c0abad8' name='sa' filepath='net/core/dev.c' line='8739' column='1'/>
-        <parameter type-id='5799dc94' name='extack' filepath='net/core/dev.c' line='8740' column='1'/>
+      <function-decl name='dev_set_mac_address' mangled-name='dev_set_mac_address' filepath='net/core/dev.c' line='8746' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_set_mac_address'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='8746' column='1'/>
+        <parameter type-id='5c0abad8' name='sa' filepath='net/core/dev.c' line='8746' column='1'/>
+        <parameter type-id='5799dc94' name='extack' filepath='net/core/dev.c' line='8747' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dev_set_mtu' mangled-name='dev_set_mtu' filepath='net/core/dev.c' line='8654' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_set_mtu'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='8654' column='1'/>
-        <parameter type-id='95e97e5e' name='new_mtu' filepath='net/core/dev.c' line='8654' column='1'/>
+      <function-decl name='dev_set_mtu' mangled-name='dev_set_mtu' filepath='net/core/dev.c' line='8661' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_set_mtu'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='8661' column='1'/>
+        <parameter type-id='95e97e5e' name='new_mtu' filepath='net/core/dev.c' line='8661' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='dev_set_name' mangled-name='dev_set_name' filepath='drivers/base/core.c' line='3028' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dev_set_name'>
@@ -125859,8 +126539,8 @@
         <parameter type-id='c97de1ac' name='groups' filepath='drivers/base/core.c' line='2341' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='device_attach' mangled-name='device_attach' filepath='drivers/base/dd.c' line='968' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='device_attach'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/dd.c' line='968' column='1'/>
+      <function-decl name='device_attach' mangled-name='device_attach' filepath='drivers/base/dd.c' line='973' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='device_attach'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/dd.c' line='973' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='device_bind_driver' mangled-name='device_bind_driver' filepath='drivers/base/dd.c' line='458' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='device_bind_driver'>
@@ -125973,19 +126653,19 @@
         <parameter type-id='fa0b179b' name='supplier' filepath='drivers/base/core.c' line='914' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='device_match_fwnode' mangled-name='device_match_fwnode' filepath='drivers/base/core.c' line='4650' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='device_match_fwnode'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/core.c' line='4650' column='1'/>
-        <parameter type-id='eaa32e2f' name='fwnode' filepath='drivers/base/core.c' line='4650' column='1'/>
+      <function-decl name='device_match_fwnode' mangled-name='device_match_fwnode' filepath='drivers/base/core.c' line='4657' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='device_match_fwnode'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/core.c' line='4657' column='1'/>
+        <parameter type-id='eaa32e2f' name='fwnode' filepath='drivers/base/core.c' line='4657' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='device_match_name' mangled-name='device_match_name' filepath='drivers/base/core.c' line='4638' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='device_match_name'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/core.c' line='4638' column='1'/>
-        <parameter type-id='eaa32e2f' name='name' filepath='drivers/base/core.c' line='4638' column='1'/>
+      <function-decl name='device_match_name' mangled-name='device_match_name' filepath='drivers/base/core.c' line='4645' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='device_match_name'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/core.c' line='4645' column='1'/>
+        <parameter type-id='eaa32e2f' name='name' filepath='drivers/base/core.c' line='4645' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='device_match_of_node' mangled-name='device_match_of_node' filepath='drivers/base/core.c' line='4644' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='device_match_of_node'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/core.c' line='4644' column='1'/>
-        <parameter type-id='eaa32e2f' name='np' filepath='drivers/base/core.c' line='4644' column='1'/>
+      <function-decl name='device_match_of_node' mangled-name='device_match_of_node' filepath='drivers/base/core.c' line='4651' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='device_match_of_node'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/core.c' line='4651' column='1'/>
+        <parameter type-id='eaa32e2f' name='np' filepath='drivers/base/core.c' line='4651' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='device_node_to_regmap' mangled-name='device_node_to_regmap' filepath='drivers/mfd/syscon.c' line='177' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='device_node_to_regmap'>
@@ -126035,8 +126715,8 @@
         <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/core.c' line='3318' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='device_release_driver' mangled-name='device_release_driver' filepath='drivers/base/dd.c' line='1228' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='device_release_driver'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/dd.c' line='1228' column='1'/>
+      <function-decl name='device_release_driver' mangled-name='device_release_driver' filepath='drivers/base/dd.c' line='1237' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='device_release_driver'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/dd.c' line='1237' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='device_remove_bin_file' mangled-name='device_remove_bin_file' filepath='drivers/base/core.c' line='2680' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='device_remove_bin_file'>
@@ -126150,36 +126830,36 @@
         <parameter type-id='f0981eeb' name='num_slots' filepath='block/keyslot-manager.c' line='153' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='devm_clk_bulk_get' mangled-name='devm_clk_bulk_get' filepath='drivers/clk/clk-devres.c' line='81' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_bulk_get'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk-devres.c' line='81' column='1'/>
-        <parameter type-id='95e97e5e' name='num_clks' filepath='drivers/clk/clk-devres.c' line='81' column='1'/>
-        <parameter type-id='2942e355' name='clks' filepath='drivers/clk/clk-devres.c' line='82' column='1'/>
+      <function-decl name='devm_clk_bulk_get' mangled-name='devm_clk_bulk_get' filepath='drivers/clk/clk-devres.c' line='140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_bulk_get'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk-devres.c' line='140' column='1'/>
+        <parameter type-id='95e97e5e' name='num_clks' filepath='drivers/clk/clk-devres.c' line='140' column='1'/>
+        <parameter type-id='2942e355' name='clks' filepath='drivers/clk/clk-devres.c' line='141' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='devm_clk_bulk_get_all' mangled-name='devm_clk_bulk_get_all' filepath='drivers/clk/clk-devres.c' line='102' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_bulk_get_all'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk-devres.c' line='102' column='1'/>
-        <parameter type-id='734c20ed' name='clks' filepath='drivers/clk/clk-devres.c' line='103' column='1'/>
+      <function-decl name='devm_clk_bulk_get_all' mangled-name='devm_clk_bulk_get_all' filepath='drivers/clk/clk-devres.c' line='161' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_bulk_get_all'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk-devres.c' line='161' column='1'/>
+        <parameter type-id='734c20ed' name='clks' filepath='drivers/clk/clk-devres.c' line='162' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='devm_clk_bulk_get_optional' mangled-name='devm_clk_bulk_get_optional' filepath='drivers/clk/clk-devres.c' line='88' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_bulk_get_optional'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk-devres.c' line='88' column='1'/>
-        <parameter type-id='95e97e5e' name='num_clks' filepath='drivers/clk/clk-devres.c' line='88' column='1'/>
-        <parameter type-id='2942e355' name='clks' filepath='drivers/clk/clk-devres.c' line='89' column='1'/>
+      <function-decl name='devm_clk_bulk_get_optional' mangled-name='devm_clk_bulk_get_optional' filepath='drivers/clk/clk-devres.c' line='147' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_bulk_get_optional'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk-devres.c' line='147' column='1'/>
+        <parameter type-id='95e97e5e' name='num_clks' filepath='drivers/clk/clk-devres.c' line='147' column='1'/>
+        <parameter type-id='2942e355' name='clks' filepath='drivers/clk/clk-devres.c' line='148' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='devm_clk_get' mangled-name='devm_clk_get' filepath='drivers/clk/clk-devres.c' line='12' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_get'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk-devres.c' line='12' column='1'/>
-        <parameter type-id='80f4b756' name='id' filepath='drivers/clk/clk-devres.c' line='12' column='1'/>
+      <function-decl name='devm_clk_get' mangled-name='devm_clk_get' filepath='drivers/clk/clk-devres.c' line='63' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_get'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk-devres.c' line='63' column='1'/>
+        <parameter type-id='80f4b756' name='id' filepath='drivers/clk/clk-devres.c' line='63' column='1'/>
         <return type-id='7d0bc0eb'/>
       </function-decl>
-      <function-decl name='devm_clk_get_optional' mangled-name='devm_clk_get_optional' filepath='drivers/clk/clk-devres.c' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_get_optional'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk-devres.c' line='32' column='1'/>
-        <parameter type-id='80f4b756' name='id' filepath='drivers/clk/clk-devres.c' line='32' column='1'/>
+      <function-decl name='devm_clk_get_optional' mangled-name='devm_clk_get_optional' filepath='drivers/clk/clk-devres.c' line='82' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_get_optional'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk-devres.c' line='82' column='1'/>
+        <parameter type-id='80f4b756' name='id' filepath='drivers/clk/clk-devres.c' line='82' column='1'/>
         <return type-id='7d0bc0eb'/>
       </function-decl>
-      <function-decl name='devm_clk_hw_register' mangled-name='devm_clk_hw_register' filepath='drivers/clk/clk.c' line='4286' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_hw_register'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk.c' line='4286' column='1'/>
-        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='4286' column='1'/>
+      <function-decl name='devm_clk_hw_register' mangled-name='devm_clk_hw_register' filepath='drivers/clk/clk.c' line='4297' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_hw_register'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk.c' line='4297' column='1'/>
+        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='4297' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='devm_clk_hw_register_clkdev' mangled-name='devm_clk_hw_register_clkdev' filepath='drivers/clk/clkdev.c' line='431' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_hw_register_clkdev'>
@@ -126189,14 +126869,14 @@
         <parameter type-id='80f4b756' name='dev_id' filepath='drivers/clk/clkdev.c' line='432' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='devm_clk_put' mangled-name='devm_clk_put' filepath='drivers/clk/clk-devres.c' line='136' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_put'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk-devres.c' line='136' column='1'/>
-        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk-devres.c' line='136' column='1'/>
+      <function-decl name='devm_clk_put' mangled-name='devm_clk_put' filepath='drivers/clk/clk-devres.c' line='195' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_put'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk-devres.c' line='195' column='1'/>
+        <parameter type-id='7d0bc0eb' name='clk' filepath='drivers/clk/clk-devres.c' line='195' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='devm_clk_register' mangled-name='devm_clk_register' filepath='drivers/clk/clk.c' line='4256' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_register'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk.c' line='4256' column='1'/>
-        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='4256' column='1'/>
+      <function-decl name='devm_clk_register' mangled-name='devm_clk_register' filepath='drivers/clk/clk.c' line='4267' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_clk_register'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk.c' line='4267' column='1'/>
+        <parameter type-id='3aaeef89' name='hw' filepath='drivers/clk/clk.c' line='4267' column='1'/>
         <return type-id='7d0bc0eb'/>
       </function-decl>
       <function-decl name='devm_devfreq_add_device' mangled-name='devm_devfreq_add_device' filepath='drivers/devfreq/devfreq.c' line='963' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_devfreq_add_device'>
@@ -126316,10 +126996,10 @@
         <parameter type-id='80f4b756' name='name' filepath='lib/genalloc.c' line='824' column='1'/>
         <return type-id='75b9415a'/>
       </function-decl>
-      <function-decl name='devm_get_clk_from_child' mangled-name='devm_get_clk_from_child' filepath='drivers/clk/clk-devres.c' line='146' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_get_clk_from_child'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk-devres.c' line='146' column='1'/>
-        <parameter type-id='9a537bbe' name='np' filepath='drivers/clk/clk-devres.c' line='147' column='1'/>
-        <parameter type-id='80f4b756' name='con_id' filepath='drivers/clk/clk-devres.c' line='147' column='1'/>
+      <function-decl name='devm_get_clk_from_child' mangled-name='devm_get_clk_from_child' filepath='drivers/clk/clk-devres.c' line='205' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_get_clk_from_child'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk-devres.c' line='205' column='1'/>
+        <parameter type-id='9a537bbe' name='np' filepath='drivers/clk/clk-devres.c' line='206' column='1'/>
+        <parameter type-id='80f4b756' name='con_id' filepath='drivers/clk/clk-devres.c' line='206' column='1'/>
         <return type-id='7d0bc0eb'/>
       </function-decl>
       <function-decl name='devm_get_free_pages' mangled-name='devm_get_free_pages' filepath='drivers/base/devres.c' line='1127' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_get_free_pages'>
@@ -126535,15 +127215,15 @@
         <parameter type-id='eebb8ee8' name='init_data' filepath='drivers/leds/led-class-flash.c' line='337' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='devm_led_classdev_register_ext' mangled-name='devm_led_classdev_register_ext' filepath='drivers/leds/led-class.c' line='477' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_led_classdev_register_ext'>
-        <parameter type-id='fa0b179b' name='parent' filepath='drivers/leds/led-class.c' line='477' column='1'/>
-        <parameter type-id='bd1c8eb6' name='led_cdev' filepath='drivers/leds/led-class.c' line='478' column='1'/>
-        <parameter type-id='eebb8ee8' name='init_data' filepath='drivers/leds/led-class.c' line='479' column='1'/>
+      <function-decl name='devm_led_classdev_register_ext' mangled-name='devm_led_classdev_register_ext' filepath='drivers/leds/led-class.c' line='481' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_led_classdev_register_ext'>
+        <parameter type-id='fa0b179b' name='parent' filepath='drivers/leds/led-class.c' line='481' column='1'/>
+        <parameter type-id='bd1c8eb6' name='led_cdev' filepath='drivers/leds/led-class.c' line='482' column='1'/>
+        <parameter type-id='eebb8ee8' name='init_data' filepath='drivers/leds/led-class.c' line='483' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='devm_led_classdev_unregister' mangled-name='devm_led_classdev_unregister' filepath='drivers/leds/led-class.c' line='516' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_led_classdev_unregister'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/leds/led-class.c' line='516' column='1'/>
-        <parameter type-id='bd1c8eb6' name='led_cdev' filepath='drivers/leds/led-class.c' line='517' column='1'/>
+      <function-decl name='devm_led_classdev_unregister' mangled-name='devm_led_classdev_unregister' filepath='drivers/leds/led-class.c' line='520' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_led_classdev_unregister'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/leds/led-class.c' line='520' column='1'/>
+        <parameter type-id='bd1c8eb6' name='led_cdev' filepath='drivers/leds/led-class.c' line='521' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='devm_mbox_controller_register' mangled-name='devm_mbox_controller_register' filepath='drivers/mailbox/mailbox.c' line='579' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_mbox_controller_register'>
@@ -126573,25 +127253,25 @@
         <parameter type-id='7544e824' name='domain' filepath='drivers/mfd/mfd-core.c' line='422' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='devm_nvmem_cell_get' mangled-name='devm_nvmem_cell_get' filepath='drivers/nvmem/core.c' line='1144' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_nvmem_cell_get'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='1144' column='1'/>
-        <parameter type-id='80f4b756' name='id' filepath='drivers/nvmem/core.c' line='1144' column='1'/>
+      <function-decl name='devm_nvmem_cell_get' mangled-name='devm_nvmem_cell_get' filepath='drivers/nvmem/core.c' line='1150' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_nvmem_cell_get'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='1150' column='1'/>
+        <parameter type-id='80f4b756' name='id' filepath='drivers/nvmem/core.c' line='1150' column='1'/>
         <return type-id='4a4ce85f'/>
       </function-decl>
-      <function-decl name='devm_nvmem_device_get' mangled-name='devm_nvmem_device_get' filepath='drivers/nvmem/core.c' line='973' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_nvmem_device_get'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='973' column='1'/>
-        <parameter type-id='80f4b756' name='id' filepath='drivers/nvmem/core.c' line='973' column='1'/>
+      <function-decl name='devm_nvmem_device_get' mangled-name='devm_nvmem_device_get' filepath='drivers/nvmem/core.c' line='979' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_nvmem_device_get'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='979' column='1'/>
+        <parameter type-id='80f4b756' name='id' filepath='drivers/nvmem/core.c' line='979' column='1'/>
         <return type-id='8179bc49'/>
       </function-decl>
-      <function-decl name='devm_nvmem_register' mangled-name='devm_nvmem_register' filepath='drivers/nvmem/core.c' line='768' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_nvmem_register'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='768' column='1'/>
-        <parameter type-id='7bb280fa' name='config' filepath='drivers/nvmem/core.c' line='769' column='1'/>
+      <function-decl name='devm_nvmem_register' mangled-name='devm_nvmem_register' filepath='drivers/nvmem/core.c' line='774' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_nvmem_register'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='774' column='1'/>
+        <parameter type-id='7bb280fa' name='config' filepath='drivers/nvmem/core.c' line='775' column='1'/>
         <return type-id='8179bc49'/>
       </function-decl>
-      <function-decl name='devm_of_clk_add_hw_provider' mangled-name='devm_of_clk_add_hw_provider' filepath='drivers/clk/clk.c' line='4774' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_of_clk_add_hw_provider'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk.c' line='4774' column='1'/>
-        <parameter type-id='a5186342' name='get' filepath='drivers/clk/clk.c' line='4775' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/clk/clk.c' line='4777' column='1'/>
+      <function-decl name='devm_of_clk_add_hw_provider' mangled-name='devm_of_clk_add_hw_provider' filepath='drivers/clk/clk.c' line='4785' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_of_clk_add_hw_provider'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/clk/clk.c' line='4785' column='1'/>
+        <parameter type-id='a5186342' name='get' filepath='drivers/clk/clk.c' line='4786' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/clk/clk.c' line='4788' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='devm_of_icc_get' mangled-name='devm_of_icc_get' filepath='drivers/interconnect/core.c' line='402' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_of_icc_get'>
@@ -126639,9 +127319,9 @@
         <parameter type-id='b59d7dce' name='priv' filepath='drivers/pci/probe.c' line='622' column='1'/>
         <return type-id='cb0dbc3c'/>
       </function-decl>
-      <function-decl name='devm_pci_remap_cfg_resource' mangled-name='devm_pci_remap_cfg_resource' filepath='drivers/pci/pci.c' line='4214' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_pci_remap_cfg_resource'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/pci/pci.c' line='4214' column='1'/>
-        <parameter type-id='c9d64c0d' name='res' filepath='drivers/pci/pci.c' line='4215' column='1'/>
+      <function-decl name='devm_pci_remap_cfg_resource' mangled-name='devm_pci_remap_cfg_resource' filepath='drivers/pci/pci.c' line='4211' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_pci_remap_cfg_resource'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/pci/pci.c' line='4211' column='1'/>
+        <parameter type-id='c9d64c0d' name='res' filepath='drivers/pci/pci.c' line='4212' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
       <function-decl name='devm_phy_create' mangled-name='devm_phy_create' filepath='drivers/phy/phy-core.c' line='943' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_phy_create'>
@@ -126702,15 +127382,15 @@
         <parameter type-id='80f4b756' name='name' filepath='drivers/base/platform.c' line='144' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='devm_power_supply_get_by_phandle' mangled-name='devm_power_supply_get_by_phandle' filepath='drivers/power/supply/power_supply_core.c' line='623' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_power_supply_get_by_phandle'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/power/supply/power_supply_core.c' line='623' column='1'/>
-        <parameter type-id='80f4b756' name='property' filepath='drivers/power/supply/power_supply_core.c' line='624' column='1'/>
+      <function-decl name='devm_power_supply_get_by_phandle' mangled-name='devm_power_supply_get_by_phandle' filepath='drivers/power/supply/power_supply_core.c' line='630' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_power_supply_get_by_phandle'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/power/supply/power_supply_core.c' line='630' column='1'/>
+        <parameter type-id='80f4b756' name='property' filepath='drivers/power/supply/power_supply_core.c' line='631' column='1'/>
         <return type-id='c0c93c9e'/>
       </function-decl>
-      <function-decl name='devm_power_supply_register' mangled-name='devm_power_supply_register' filepath='drivers/power/supply/power_supply_core.c' line='1362' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_power_supply_register'>
-        <parameter type-id='fa0b179b' name='parent' filepath='drivers/power/supply/power_supply_core.c' line='1362' column='1'/>
-        <parameter type-id='cb9cd99f' name='desc' filepath='drivers/power/supply/power_supply_core.c' line='1363' column='1'/>
-        <parameter type-id='048b3ad6' name='cfg' filepath='drivers/power/supply/power_supply_core.c' line='1364' column='1'/>
+      <function-decl name='devm_power_supply_register' mangled-name='devm_power_supply_register' filepath='drivers/power/supply/power_supply_core.c' line='1374' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_power_supply_register'>
+        <parameter type-id='fa0b179b' name='parent' filepath='drivers/power/supply/power_supply_core.c' line='1374' column='1'/>
+        <parameter type-id='cb9cd99f' name='desc' filepath='drivers/power/supply/power_supply_core.c' line='1375' column='1'/>
+        <parameter type-id='048b3ad6' name='cfg' filepath='drivers/power/supply/power_supply_core.c' line='1376' column='1'/>
         <return type-id='c0c93c9e'/>
       </function-decl>
       <function-decl name='devm_pwm_get' mangled-name='devm_pwm_get' filepath='drivers/pwm/core.c' line='1153' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_pwm_get'>
@@ -126845,17 +127525,17 @@
         <parameter type-id='775147d9' name='rcdev' filepath='drivers/reset/core.c' line='143' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='devm_rproc_add' mangled-name='devm_rproc_add' filepath='drivers/remoteproc/remoteproc_core.c' line='2133' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_rproc_add'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/remoteproc/remoteproc_core.c' line='2133' column='1'/>
-        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2133' column='1'/>
+      <function-decl name='devm_rproc_add' mangled-name='devm_rproc_add' filepath='drivers/remoteproc/remoteproc_core.c' line='2140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_rproc_add'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/remoteproc/remoteproc_core.c' line='2140' column='1'/>
+        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2140' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='devm_rproc_alloc' mangled-name='devm_rproc_alloc' filepath='drivers/remoteproc/remoteproc_core.c' line='2406' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_rproc_alloc'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/remoteproc/remoteproc_core.c' line='2406' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='drivers/remoteproc/remoteproc_core.c' line='2406' column='1'/>
-        <parameter type-id='48daa4cd' name='ops' filepath='drivers/remoteproc/remoteproc_core.c' line='2407' column='1'/>
-        <parameter type-id='80f4b756' name='firmware' filepath='drivers/remoteproc/remoteproc_core.c' line='2408' column='1'/>
-        <parameter type-id='95e97e5e' name='len' filepath='drivers/remoteproc/remoteproc_core.c' line='2408' column='1'/>
+      <function-decl name='devm_rproc_alloc' mangled-name='devm_rproc_alloc' filepath='drivers/remoteproc/remoteproc_core.c' line='2413' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_rproc_alloc'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/remoteproc/remoteproc_core.c' line='2413' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='drivers/remoteproc/remoteproc_core.c' line='2413' column='1'/>
+        <parameter type-id='48daa4cd' name='ops' filepath='drivers/remoteproc/remoteproc_core.c' line='2414' column='1'/>
+        <parameter type-id='80f4b756' name='firmware' filepath='drivers/remoteproc/remoteproc_core.c' line='2415' column='1'/>
+        <parameter type-id='95e97e5e' name='len' filepath='drivers/remoteproc/remoteproc_core.c' line='2415' column='1'/>
         <return type-id='5771c601'/>
       </function-decl>
       <function-decl name='devm_rtc_allocate_device' mangled-name='devm_rtc_allocate_device' filepath='drivers/rtc/class.c' line='359' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_rtc_allocate_device'>
@@ -126982,14 +127662,14 @@
         <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='619' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='disable_percpu_irq' mangled-name='disable_percpu_irq' filepath='kernel/irq/manage.c' line='2327' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='disable_percpu_irq'>
-        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2327' column='1'/>
+      <function-decl name='disable_percpu_irq' mangled-name='disable_percpu_irq' filepath='kernel/irq/manage.c' line='2334' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='disable_percpu_irq'>
+        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2334' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='disk_end_io_acct' mangled-name='disk_end_io_acct' filepath='block/blk-core.c' line='1385' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='disk_end_io_acct'>
-        <parameter type-id='33c599da' name='disk' filepath='block/blk-core.c' line='1385' column='1'/>
-        <parameter type-id='f0981eeb' name='op' filepath='block/blk-core.c' line='1385' column='1'/>
-        <parameter type-id='7359adad' name='start_time' filepath='block/blk-core.c' line='1386' column='1'/>
+      <function-decl name='disk_end_io_acct' mangled-name='disk_end_io_acct' filepath='block/blk-core.c' line='1383' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='disk_end_io_acct'>
+        <parameter type-id='33c599da' name='disk' filepath='block/blk-core.c' line='1383' column='1'/>
+        <parameter type-id='f0981eeb' name='op' filepath='block/blk-core.c' line='1383' column='1'/>
+        <parameter type-id='7359adad' name='start_time' filepath='block/blk-core.c' line='1384' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='disk_stack_limits' mangled-name='disk_stack_limits' filepath='block/blk-settings.c' line='648' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='disk_stack_limits'>
@@ -126998,10 +127678,10 @@
         <parameter type-id='a42536cd' name='offset' filepath='block/blk-settings.c' line='649' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='disk_start_io_acct' mangled-name='disk_start_io_acct' filepath='block/blk-core.c' line='1356' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='disk_start_io_acct'>
-        <parameter type-id='33c599da' name='disk' filepath='block/blk-core.c' line='1356' column='1'/>
-        <parameter type-id='f0981eeb' name='sectors' filepath='block/blk-core.c' line='1356' column='1'/>
-        <parameter type-id='f0981eeb' name='op' filepath='block/blk-core.c' line='1357' column='1'/>
+      <function-decl name='disk_start_io_acct' mangled-name='disk_start_io_acct' filepath='block/blk-core.c' line='1354' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='disk_start_io_acct'>
+        <parameter type-id='33c599da' name='disk' filepath='block/blk-core.c' line='1354' column='1'/>
+        <parameter type-id='f0981eeb' name='sectors' filepath='block/blk-core.c' line='1354' column='1'/>
+        <parameter type-id='f0981eeb' name='op' filepath='block/blk-core.c' line='1355' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
       <function-decl name='display_timings_release' mangled-name='display_timings_release' filepath='drivers/video/display_timing.c' line='12' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='display_timings_release'>
@@ -127062,17 +127742,17 @@
         <parameter type-id='3eb7c31c' name='gfp' filepath='kernel/dma/mapping.c' line='518' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='dma_async_device_register' mangled-name='dma_async_device_register' filepath='drivers/dma/dmaengine.c' line='1140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_async_device_register'>
-        <parameter type-id='c60ba652' name='device' filepath='drivers/dma/dmaengine.c' line='1140' column='1'/>
+      <function-decl name='dma_async_device_register' mangled-name='dma_async_device_register' filepath='drivers/dma/dmaengine.c' line='1141' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_async_device_register'>
+        <parameter type-id='c60ba652' name='device' filepath='drivers/dma/dmaengine.c' line='1141' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dma_async_device_unregister' mangled-name='dma_async_device_unregister' filepath='drivers/dma/dmaengine.c' line='1311' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_async_device_unregister'>
-        <parameter type-id='c60ba652' name='device' filepath='drivers/dma/dmaengine.c' line='1311' column='1'/>
+      <function-decl name='dma_async_device_unregister' mangled-name='dma_async_device_unregister' filepath='drivers/dma/dmaengine.c' line='1312' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_async_device_unregister'>
+        <parameter type-id='c60ba652' name='device' filepath='drivers/dma/dmaengine.c' line='1312' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='dma_async_tx_descriptor_init' mangled-name='dma_async_tx_descriptor_init' filepath='drivers/dma/dmaengine.c' line='1497' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_async_tx_descriptor_init'>
-        <parameter type-id='0e3f80d9' name='tx' filepath='drivers/dma/dmaengine.c' line='1497' column='1'/>
-        <parameter type-id='27f3f5d8' name='chan' filepath='drivers/dma/dmaengine.c' line='1498' column='1'/>
+      <function-decl name='dma_async_tx_descriptor_init' mangled-name='dma_async_tx_descriptor_init' filepath='drivers/dma/dmaengine.c' line='1498' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_async_tx_descriptor_init'>
+        <parameter type-id='0e3f80d9' name='tx' filepath='drivers/dma/dmaengine.c' line='1498' column='1'/>
+        <parameter type-id='27f3f5d8' name='chan' filepath='drivers/dma/dmaengine.c' line='1499' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='dma_buf_attach' mangled-name='dma_buf_attach' filepath='drivers/dma-buf/dma-buf.c' line='839' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_attach'>
@@ -127299,13 +127979,13 @@
         <parameter type-id='7359adad' name='attrs' filepath='kernel/dma/mapping.c' line='323' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dma_get_slave_caps' mangled-name='dma_get_slave_caps' filepath='drivers/dma/dmaengine.c' line='570' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_get_slave_caps'>
-        <parameter type-id='27f3f5d8' name='chan' filepath='drivers/dma/dmaengine.c' line='570' column='1'/>
-        <parameter type-id='d9f19b23' name='caps' filepath='drivers/dma/dmaengine.c' line='570' column='1'/>
+      <function-decl name='dma_get_slave_caps' mangled-name='dma_get_slave_caps' filepath='drivers/dma/dmaengine.c' line='571' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_get_slave_caps'>
+        <parameter type-id='27f3f5d8' name='chan' filepath='drivers/dma/dmaengine.c' line='571' column='1'/>
+        <parameter type-id='d9f19b23' name='caps' filepath='drivers/dma/dmaengine.c' line='571' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dma_get_slave_channel' mangled-name='dma_get_slave_channel' filepath='drivers/dma/dmaengine.c' line='696' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_get_slave_channel'>
-        <parameter type-id='27f3f5d8' name='chan' filepath='drivers/dma/dmaengine.c' line='696' column='1'/>
+      <function-decl name='dma_get_slave_channel' mangled-name='dma_get_slave_channel' filepath='drivers/dma/dmaengine.c' line='697' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_get_slave_channel'>
+        <parameter type-id='27f3f5d8' name='chan' filepath='drivers/dma/dmaengine.c' line='697' column='1'/>
         <return type-id='27f3f5d8'/>
       </function-decl>
       <function-decl name='dma_heap_add' mangled-name='dma_heap_add' filepath='drivers/dma-buf/dma-heap.c' line='298' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_heap_add'>
@@ -127412,13 +128092,13 @@
         <parameter type-id='cf29c9b3' name='dma' filepath='mm/dmapool.c' line='404' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='dma_release_channel' mangled-name='dma_release_channel' filepath='drivers/dma/dmaengine.c' line='903' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_release_channel'>
-        <parameter type-id='27f3f5d8' name='chan' filepath='drivers/dma/dmaengine.c' line='903' column='1'/>
+      <function-decl name='dma_release_channel' mangled-name='dma_release_channel' filepath='drivers/dma/dmaengine.c' line='904' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_release_channel'>
+        <parameter type-id='27f3f5d8' name='chan' filepath='drivers/dma/dmaengine.c' line='904' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='dma_request_chan' mangled-name='dma_request_chan' filepath='drivers/dma/dmaengine.c' line='813' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_request_chan'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/dma/dmaengine.c' line='813' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='drivers/dma/dmaengine.c' line='813' column='1'/>
+      <function-decl name='dma_request_chan' mangled-name='dma_request_chan' filepath='drivers/dma/dmaengine.c' line='814' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_request_chan'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/dma/dmaengine.c' line='814' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='drivers/dma/dmaengine.c' line='814' column='1'/>
         <return type-id='27f3f5d8'/>
       </function-decl>
       <function-decl name='dma_resv_add_excl_fence' mangled-name='dma_resv_add_excl_fence' filepath='drivers/dma-buf/dma-resv.c' line='308' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_resv_add_excl_fence'>
@@ -127463,8 +128143,8 @@
         <parameter type-id='7359adad' name='timeout' filepath='drivers/dma-buf/dma-resv.c' line='534' column='1'/>
         <return type-id='bd54fe1a'/>
       </function-decl>
-      <function-decl name='dma_run_dependencies' mangled-name='dma_run_dependencies' filepath='drivers/dma/dmaengine.c' line='1612' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_run_dependencies'>
-        <parameter type-id='0e3f80d9' name='tx' filepath='drivers/dma/dmaengine.c' line='1612' column='1'/>
+      <function-decl name='dma_run_dependencies' mangled-name='dma_run_dependencies' filepath='drivers/dma/dmaengine.c' line='1613' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_run_dependencies'>
+        <parameter type-id='0e3f80d9' name='tx' filepath='drivers/dma/dmaengine.c' line='1613' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='dma_set_coherent_mask' mangled-name='dma_set_coherent_mask' filepath='kernel/dma/mapping.c' line='597' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_set_coherent_mask'>
@@ -127505,9 +128185,9 @@
         <parameter type-id='eea6b025' name='dir' filepath='kernel/dma/mapping.c' line='269' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='dma_sync_wait' mangled-name='dma_sync_wait' filepath='drivers/dma/dmaengine.c' line='519' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_sync_wait'>
-        <parameter type-id='27f3f5d8' name='chan' filepath='drivers/dma/dmaengine.c' line='519' column='1'/>
-        <parameter type-id='6478ea0a' name='cookie' filepath='drivers/dma/dmaengine.c' line='519' column='1'/>
+      <function-decl name='dma_sync_wait' mangled-name='dma_sync_wait' filepath='drivers/dma/dmaengine.c' line='520' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_sync_wait'>
+        <parameter type-id='27f3f5d8' name='chan' filepath='drivers/dma/dmaengine.c' line='520' column='1'/>
+        <parameter type-id='6478ea0a' name='cookie' filepath='drivers/dma/dmaengine.c' line='520' column='1'/>
         <return type-id='02ac9d9d'/>
       </function-decl>
       <function-decl name='dma_unmap_page_attrs' mangled-name='dma_unmap_page_attrs' filepath='kernel/dma/mapping.c' line='162' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_unmap_page_attrs'>
@@ -127543,8 +128223,8 @@
         <parameter type-id='f0981eeb' name='order' filepath='drivers/dma-buf/heaps/page_pool.c' line='127' column='1'/>
         <return type-id='586a9713'/>
       </function-decl>
-      <function-decl name='dmabuf_page_pool_destroy' mangled-name='dmabuf_page_pool_destroy' filepath='drivers/dma-buf/heaps/page_pool.c' line='157' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dmabuf_page_pool_destroy'>
-        <parameter type-id='586a9713' name='pool' filepath='drivers/dma-buf/heaps/page_pool.c' line='157' column='1'/>
+      <function-decl name='dmabuf_page_pool_destroy' mangled-name='dmabuf_page_pool_destroy' filepath='drivers/dma-buf/heaps/page_pool.c' line='156' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dmabuf_page_pool_destroy'>
+        <parameter type-id='586a9713' name='pool' filepath='drivers/dma-buf/heaps/page_pool.c' line='156' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='dmabuf_page_pool_free' mangled-name='dmabuf_page_pool_free' filepath='drivers/dma-buf/heaps/page_pool.c' line='108' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dmabuf_page_pool_free'>
@@ -127552,18 +128232,18 @@
         <parameter type-id='02f11ed4' name='page' filepath='drivers/dma-buf/heaps/page_pool.c' line='108' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='dmaengine_get_unmap_data' mangled-name='dmaengine_get_unmap_data' filepath='drivers/dma/dmaengine.c' line='1480' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dmaengine_get_unmap_data'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/dma/dmaengine.c' line='1480' column='1'/>
-        <parameter type-id='95e97e5e' name='nr' filepath='drivers/dma/dmaengine.c' line='1480' column='1'/>
-        <parameter type-id='3eb7c31c' name='flags' filepath='drivers/dma/dmaengine.c' line='1480' column='1'/>
+      <function-decl name='dmaengine_get_unmap_data' mangled-name='dmaengine_get_unmap_data' filepath='drivers/dma/dmaengine.c' line='1481' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dmaengine_get_unmap_data'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/dma/dmaengine.c' line='1481' column='1'/>
+        <parameter type-id='95e97e5e' name='nr' filepath='drivers/dma/dmaengine.c' line='1481' column='1'/>
+        <parameter type-id='3eb7c31c' name='flags' filepath='drivers/dma/dmaengine.c' line='1481' column='1'/>
         <return type-id='e220a5e2'/>
       </function-decl>
-      <function-decl name='dmaengine_unmap_put' mangled-name='dmaengine_unmap_put' filepath='drivers/dma/dmaengine.c' line='1431' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dmaengine_unmap_put'>
-        <parameter type-id='e220a5e2' name='unmap' filepath='drivers/dma/dmaengine.c' line='1431' column='1'/>
+      <function-decl name='dmaengine_unmap_put' mangled-name='dmaengine_unmap_put' filepath='drivers/dma/dmaengine.c' line='1432' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dmaengine_unmap_put'>
+        <parameter type-id='e220a5e2' name='unmap' filepath='drivers/dma/dmaengine.c' line='1432' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='dmaenginem_async_device_register' mangled-name='dmaenginem_async_device_register' filepath='drivers/dma/dmaengine.c' line='1347' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dmaenginem_async_device_register'>
-        <parameter type-id='c60ba652' name='device' filepath='drivers/dma/dmaengine.c' line='1347' column='1'/>
+      <function-decl name='dmaenginem_async_device_register' mangled-name='dmaenginem_async_device_register' filepath='drivers/dma/dmaengine.c' line='1348' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dmaenginem_async_device_register'>
+        <parameter type-id='c60ba652' name='device' filepath='drivers/dma/dmaengine.c' line='1348' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='dmam_alloc_attrs' mangled-name='dmam_alloc_attrs' filepath='kernel/dma/mapping.c' line='82' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dmam_alloc_attrs'>
@@ -127589,12 +128269,12 @@
         <parameter type-id='b59d7dce' name='allocation' filepath='mm/dmapool.c' line='499' column='1'/>
         <return type-id='ab33c616'/>
       </function-decl>
-      <function-decl name='do_SAK' mangled-name='do_SAK' filepath='drivers/tty/tty_io.c' line='3042' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='do_SAK'>
-        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_io.c' line='3042' column='1'/>
+      <function-decl name='do_SAK' mangled-name='do_SAK' filepath='drivers/tty/tty_io.c' line='3045' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='do_SAK'>
+        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_io.c' line='3045' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='do_exit' mangled-name='do_exit' filepath='kernel/exit.c' line='715' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='do_exit'>
-        <parameter type-id='bd54fe1a' name='code' filepath='kernel/exit.c' line='715' column='1'/>
+      <function-decl name='do_exit' mangled-name='do_exit' filepath='kernel/exit.c' line='762' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='do_exit'>
+        <parameter type-id='bd54fe1a' name='code' filepath='kernel/exit.c' line='762' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='do_trace_rcu_torture_read' mangled-name='do_trace_rcu_torture_read' filepath='kernel/rcu/update.c' line='467' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='do_trace_rcu_torture_read'>
@@ -127605,7 +128285,7 @@
         <parameter type-id='7359adad' name='c' filepath='kernel/rcu/update.c' line='469' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='do_traversal_all_lruvec' mangled-name='do_traversal_all_lruvec' filepath='mm/memcontrol.c' line='1385' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='do_traversal_all_lruvec'>
+      <function-decl name='do_traversal_all_lruvec' mangled-name='do_traversal_all_lruvec' filepath='mm/memcontrol.c' line='1387' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='do_traversal_all_lruvec'>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='do_wait_intr' mangled-name='do_wait_intr' filepath='kernel/sched/wait.c' line='334' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='do_wait_intr'>
@@ -127630,16 +128310,16 @@
         <parameter type-id='a965a5b5' name='sem' filepath='kernel/locking/semaphore.c' line='101' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='down_read' mangled-name='down_read' filepath='kernel/locking/rwsem.c' line='1531' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='down_read'>
-        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1531' column='1'/>
+      <function-decl name='down_read' mangled-name='down_read' filepath='kernel/locking/rwsem.c' line='1546' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='down_read'>
+        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1546' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='down_read_killable' mangled-name='down_read_killable' filepath='kernel/locking/rwsem.c' line='1554' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='down_read_killable'>
-        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1554' column='1'/>
+      <function-decl name='down_read_killable' mangled-name='down_read_killable' filepath='kernel/locking/rwsem.c' line='1569' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='down_read_killable'>
+        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1569' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='down_read_trylock' mangled-name='down_read_trylock' filepath='kernel/locking/rwsem.c' line='1571' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='down_read_trylock'>
-        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1571' column='1'/>
+      <function-decl name='down_read_trylock' mangled-name='down_read_trylock' filepath='kernel/locking/rwsem.c' line='1586' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='down_read_trylock'>
+        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1586' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='down_timeout' mangled-name='down_timeout' filepath='kernel/locking/semaphore.c' line='155' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='down_timeout'>
@@ -127651,16 +128331,16 @@
         <parameter type-id='a965a5b5' name='sem' filepath='kernel/locking/semaphore.c' line='130' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='down_write' mangled-name='down_write' filepath='kernel/locking/rwsem.c' line='1584' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='down_write'>
-        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1584' column='1'/>
+      <function-decl name='down_write' mangled-name='down_write' filepath='kernel/locking/rwsem.c' line='1599' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='down_write'>
+        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1599' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='down_write_trylock' mangled-name='down_write_trylock' filepath='kernel/locking/rwsem.c' line='1613' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='down_write_trylock'>
-        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1613' column='1'/>
+      <function-decl name='down_write_trylock' mangled-name='down_write_trylock' filepath='kernel/locking/rwsem.c' line='1628' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='down_write_trylock'>
+        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1628' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='downgrade_write' mangled-name='downgrade_write' filepath='kernel/locking/rwsem.c' line='1648' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='downgrade_write'>
-        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1648' column='1'/>
+      <function-decl name='downgrade_write' mangled-name='downgrade_write' filepath='kernel/locking/rwsem.c' line='1663' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='downgrade_write'>
+        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1663' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='dput' mangled-name='dput' filepath='fs/dcache.c' line='859' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dput'>
@@ -127735,16 +128415,16 @@
         <parameter type-id='7e666abe' name='inode' filepath='fs/quota/dquot.c' line='1919' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='dquot_get_dqblk' mangled-name='dquot_get_dqblk' filepath='fs/quota/dquot.c' line='2625' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_get_dqblk'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2625' column='1'/>
-        <parameter type-id='72028e1c' name='qid' filepath='fs/quota/dquot.c' line='2625' column='1'/>
-        <parameter type-id='39341f7e' name='di' filepath='fs/quota/dquot.c' line='2626' column='1'/>
+      <function-decl name='dquot_get_dqblk' mangled-name='dquot_get_dqblk' filepath='fs/quota/dquot.c' line='2627' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_get_dqblk'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2627' column='1'/>
+        <parameter type-id='72028e1c' name='qid' filepath='fs/quota/dquot.c' line='2627' column='1'/>
+        <parameter type-id='39341f7e' name='di' filepath='fs/quota/dquot.c' line='2628' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dquot_get_next_dqblk' mangled-name='dquot_get_next_dqblk' filepath='fs/quota/dquot.c' line='2640' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_get_next_dqblk'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2640' column='1'/>
-        <parameter type-id='cc8d835a' name='qid' filepath='fs/quota/dquot.c' line='2640' column='1'/>
-        <parameter type-id='39341f7e' name='di' filepath='fs/quota/dquot.c' line='2641' column='1'/>
+      <function-decl name='dquot_get_next_dqblk' mangled-name='dquot_get_next_dqblk' filepath='fs/quota/dquot.c' line='2642' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_get_next_dqblk'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2642' column='1'/>
+        <parameter type-id='cc8d835a' name='qid' filepath='fs/quota/dquot.c' line='2642' column='1'/>
+        <parameter type-id='39341f7e' name='di' filepath='fs/quota/dquot.c' line='2643' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='dquot_get_next_id' mangled-name='dquot_get_next_id' filepath='fs/quota/dquot.c' line='2140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_get_next_id'>
@@ -127752,9 +128432,9 @@
         <parameter type-id='cc8d835a' name='qid' filepath='fs/quota/dquot.c' line='2140' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dquot_get_state' mangled-name='dquot_get_state' filepath='fs/quota/dquot.c' line='2777' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_get_state'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2777' column='1'/>
-        <parameter type-id='6dcf57f3' name='state' filepath='fs/quota/dquot.c' line='2777' column='1'/>
+      <function-decl name='dquot_get_state' mangled-name='dquot_get_state' filepath='fs/quota/dquot.c' line='2779' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_get_state'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2779' column='1'/>
+        <parameter type-id='6dcf57f3' name='state' filepath='fs/quota/dquot.c' line='2779' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='dquot_initialize' mangled-name='dquot_initialize' filepath='fs/quota/dquot.c' line='1550' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_initialize'>
@@ -127765,11 +128445,11 @@
         <parameter type-id='7e666abe' name='inode' filepath='fs/quota/dquot.c' line='1556' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='dquot_load_quota_inode' mangled-name='dquot_load_quota_inode' filepath='fs/quota/dquot.c' line='2430' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_load_quota_inode'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/quota/dquot.c' line='2430' column='1'/>
-        <parameter type-id='95e97e5e' name='type' filepath='fs/quota/dquot.c' line='2430' column='1'/>
-        <parameter type-id='95e97e5e' name='format_id' filepath='fs/quota/dquot.c' line='2430' column='1'/>
-        <parameter type-id='f0981eeb' name='flags' filepath='fs/quota/dquot.c' line='2431' column='1'/>
+      <function-decl name='dquot_load_quota_inode' mangled-name='dquot_load_quota_inode' filepath='fs/quota/dquot.c' line='2432' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_load_quota_inode'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/quota/dquot.c' line='2432' column='1'/>
+        <parameter type-id='95e97e5e' name='type' filepath='fs/quota/dquot.c' line='2432' column='1'/>
+        <parameter type-id='95e97e5e' name='format_id' filepath='fs/quota/dquot.c' line='2432' column='1'/>
+        <parameter type-id='f0981eeb' name='flags' filepath='fs/quota/dquot.c' line='2433' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='dquot_mark_dquot_dirty' mangled-name='dquot_mark_dquot_dirty' filepath='fs/quota/dquot.c' line='352' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_mark_dquot_dirty'>
@@ -127781,39 +128461,39 @@
         <parameter type-id='95e97e5e' name='type' filepath='fs/quota/dquot.c' line='2306' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dquot_quota_on' mangled-name='dquot_quota_on' filepath='fs/quota/dquot.c' line='2480' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_quota_on'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2480' column='1'/>
-        <parameter type-id='95e97e5e' name='type' filepath='fs/quota/dquot.c' line='2480' column='1'/>
-        <parameter type-id='95e97e5e' name='format_id' filepath='fs/quota/dquot.c' line='2480' column='1'/>
-        <parameter type-id='a77efac3' name='path' filepath='fs/quota/dquot.c' line='2481' column='1'/>
+      <function-decl name='dquot_quota_on' mangled-name='dquot_quota_on' filepath='fs/quota/dquot.c' line='2482' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_quota_on'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2482' column='1'/>
+        <parameter type-id='95e97e5e' name='type' filepath='fs/quota/dquot.c' line='2482' column='1'/>
+        <parameter type-id='95e97e5e' name='format_id' filepath='fs/quota/dquot.c' line='2482' column='1'/>
+        <parameter type-id='a77efac3' name='path' filepath='fs/quota/dquot.c' line='2483' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dquot_quota_on_mount' mangled-name='dquot_quota_on_mount' filepath='fs/quota/dquot.c' line='2501' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_quota_on_mount'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2501' column='1'/>
-        <parameter type-id='26a90f95' name='qf_name' filepath='fs/quota/dquot.c' line='2501' column='1'/>
-        <parameter type-id='95e97e5e' name='format_id' filepath='fs/quota/dquot.c' line='2502' column='1'/>
-        <parameter type-id='95e97e5e' name='type' filepath='fs/quota/dquot.c' line='2502' column='1'/>
+      <function-decl name='dquot_quota_on_mount' mangled-name='dquot_quota_on_mount' filepath='fs/quota/dquot.c' line='2503' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_quota_on_mount'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2503' column='1'/>
+        <parameter type-id='26a90f95' name='qf_name' filepath='fs/quota/dquot.c' line='2503' column='1'/>
+        <parameter type-id='95e97e5e' name='format_id' filepath='fs/quota/dquot.c' line='2504' column='1'/>
+        <parameter type-id='95e97e5e' name='type' filepath='fs/quota/dquot.c' line='2504' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='dquot_release' mangled-name='dquot_release' filepath='fs/quota/dquot.c' line='501' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_release'>
         <parameter type-id='e9a4c848' name='dquot' filepath='fs/quota/dquot.c' line='501' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dquot_resume' mangled-name='dquot_resume' filepath='fs/quota/dquot.c' line='2446' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_resume'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2446' column='1'/>
-        <parameter type-id='95e97e5e' name='type' filepath='fs/quota/dquot.c' line='2446' column='1'/>
+      <function-decl name='dquot_resume' mangled-name='dquot_resume' filepath='fs/quota/dquot.c' line='2448' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_resume'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2448' column='1'/>
+        <parameter type-id='95e97e5e' name='type' filepath='fs/quota/dquot.c' line='2448' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dquot_set_dqblk' mangled-name='dquot_set_dqblk' filepath='fs/quota/dquot.c' line='2758' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_set_dqblk'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2758' column='1'/>
-        <parameter type-id='72028e1c' name='qid' filepath='fs/quota/dquot.c' line='2758' column='1'/>
-        <parameter type-id='39341f7e' name='di' filepath='fs/quota/dquot.c' line='2759' column='1'/>
+      <function-decl name='dquot_set_dqblk' mangled-name='dquot_set_dqblk' filepath='fs/quota/dquot.c' line='2760' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_set_dqblk'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2760' column='1'/>
+        <parameter type-id='72028e1c' name='qid' filepath='fs/quota/dquot.c' line='2760' column='1'/>
+        <parameter type-id='39341f7e' name='di' filepath='fs/quota/dquot.c' line='2761' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dquot_set_dqinfo' mangled-name='dquot_set_dqinfo' filepath='fs/quota/dquot.c' line='2812' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_set_dqinfo'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2812' column='1'/>
-        <parameter type-id='95e97e5e' name='type' filepath='fs/quota/dquot.c' line='2812' column='1'/>
-        <parameter type-id='66b0cee4' name='ii' filepath='fs/quota/dquot.c' line='2812' column='1'/>
+      <function-decl name='dquot_set_dqinfo' mangled-name='dquot_set_dqinfo' filepath='fs/quota/dquot.c' line='2814' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_set_dqinfo'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/quota/dquot.c' line='2814' column='1'/>
+        <parameter type-id='95e97e5e' name='type' filepath='fs/quota/dquot.c' line='2814' column='1'/>
+        <parameter type-id='66b0cee4' name='ii' filepath='fs/quota/dquot.c' line='2814' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='dquot_transfer' mangled-name='dquot_transfer' filepath='fs/quota/dquot.c' line='2090' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dquot_transfer'>
@@ -127826,12 +128506,12 @@
         <parameter type-id='95e97e5e' name='type' filepath='fs/quota/dquot.c' line='634' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drain_workqueue' mangled-name='drain_workqueue' filepath='kernel/workqueue.c' line='2957' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drain_workqueue'>
-        <parameter type-id='242e3d19' name='wq' filepath='kernel/workqueue.c' line='2957' column='1'/>
+      <function-decl name='drain_workqueue' mangled-name='drain_workqueue' filepath='kernel/workqueue.c' line='2960' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drain_workqueue'>
+        <parameter type-id='242e3d19' name='wq' filepath='kernel/workqueue.c' line='2960' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='driver_attach' mangled-name='driver_attach' filepath='drivers/base/dd.c' line='1129' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='driver_attach'>
-        <parameter type-id='00c7b870' name='drv' filepath='drivers/base/dd.c' line='1129' column='1'/>
+      <function-decl name='driver_attach' mangled-name='driver_attach' filepath='drivers/base/dd.c' line='1138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='driver_attach'>
+        <parameter type-id='00c7b870' name='drv' filepath='drivers/base/dd.c' line='1138' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='driver_create_file' mangled-name='driver_create_file' filepath='drivers/base/driver.c' line='101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='driver_create_file'>
@@ -127870,14 +128550,14 @@
         <parameter type-id='95e97e5e' name='vdisplay' filepath='drivers/gpu/drm/drm_edid.c' line='5400' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_add_affected_connectors' mangled-name='drm_atomic_add_affected_connectors' filepath='drivers/gpu/drm/drm_atomic.c' line='1156' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_add_affected_connectors'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='1156' column='1'/>
-        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic.c' line='1157' column='1'/>
+      <function-decl name='drm_atomic_add_affected_connectors' mangled-name='drm_atomic_add_affected_connectors' filepath='drivers/gpu/drm/drm_atomic.c' line='1166' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_add_affected_connectors'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='1166' column='1'/>
+        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic.c' line='1167' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_add_affected_planes' mangled-name='drm_atomic_add_affected_planes' filepath='drivers/gpu/drm/drm_atomic.c' line='1219' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_add_affected_planes'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='1219' column='1'/>
-        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic.c' line='1220' column='1'/>
+      <function-decl name='drm_atomic_add_affected_planes' mangled-name='drm_atomic_add_affected_planes' filepath='drivers/gpu/drm/drm_atomic.c' line='1229' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_add_affected_planes'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='1229' column='1'/>
+        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic.c' line='1230' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='drm_atomic_bridge_chain_enable' mangled-name='drm_atomic_bridge_chain_enable' filepath='drivers/gpu/drm/drm_bridge.c' line='697' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_bridge_chain_enable'>
@@ -127890,43 +128570,43 @@
         <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_bridge.c' line='655' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_commit' mangled-name='drm_atomic_commit' filepath='drivers/gpu/drm/drm_atomic.c' line='1334' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_commit'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='1334' column='1'/>
+      <function-decl name='drm_atomic_commit' mangled-name='drm_atomic_commit' filepath='drivers/gpu/drm/drm_atomic.c' line='1344' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_commit'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='1344' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_get_connector_state' mangled-name='drm_atomic_get_connector_state' filepath='drivers/gpu/drm/drm_atomic.c' line='944' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_get_connector_state'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='944' column='1'/>
-        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_atomic.c' line='945' column='1'/>
+      <function-decl name='drm_atomic_get_connector_state' mangled-name='drm_atomic_get_connector_state' filepath='drivers/gpu/drm/drm_atomic.c' line='953' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_get_connector_state'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='953' column='1'/>
+        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_atomic.c' line='954' column='1'/>
         <return type-id='249ef586'/>
       </function-decl>
-      <function-decl name='drm_atomic_get_crtc_state' mangled-name='drm_atomic_get_crtc_state' filepath='drivers/gpu/drm/drm_atomic.c' line='291' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_get_crtc_state'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='291' column='1'/>
-        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic.c' line='292' column='1'/>
+      <function-decl name='drm_atomic_get_crtc_state' mangled-name='drm_atomic_get_crtc_state' filepath='drivers/gpu/drm/drm_atomic.c' line='300' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_get_crtc_state'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='300' column='1'/>
+        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic.c' line='301' column='1'/>
         <return type-id='35078cb9'/>
       </function-decl>
-      <function-decl name='drm_atomic_get_new_bridge_state' mangled-name='drm_atomic_get_new_bridge_state' filepath='drivers/gpu/drm/drm_atomic.c' line='1082' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_get_new_bridge_state'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='1082' column='1'/>
-        <parameter type-id='8582e5ec' name='bridge' filepath='drivers/gpu/drm/drm_atomic.c' line='1083' column='1'/>
+      <function-decl name='drm_atomic_get_new_bridge_state' mangled-name='drm_atomic_get_new_bridge_state' filepath='drivers/gpu/drm/drm_atomic.c' line='1092' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_get_new_bridge_state'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='1092' column='1'/>
+        <parameter type-id='8582e5ec' name='bridge' filepath='drivers/gpu/drm/drm_atomic.c' line='1093' column='1'/>
         <return type-id='67bbaeda'/>
       </function-decl>
-      <function-decl name='drm_atomic_get_new_connector_for_encoder' mangled-name='drm_atomic_get_new_connector_for_encoder' filepath='drivers/gpu/drm/drm_atomic.c' line='912' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_get_new_connector_for_encoder'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='912' column='1'/>
-        <parameter type-id='74d89ebd' name='encoder' filepath='drivers/gpu/drm/drm_atomic.c' line='913' column='1'/>
+      <function-decl name='drm_atomic_get_new_connector_for_encoder' mangled-name='drm_atomic_get_new_connector_for_encoder' filepath='drivers/gpu/drm/drm_atomic.c' line='921' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_get_new_connector_for_encoder'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='921' column='1'/>
+        <parameter type-id='74d89ebd' name='encoder' filepath='drivers/gpu/drm/drm_atomic.c' line='922' column='1'/>
         <return type-id='4db02c58'/>
       </function-decl>
-      <function-decl name='drm_atomic_get_old_connector_for_encoder' mangled-name='drm_atomic_get_old_connector_for_encoder' filepath='drivers/gpu/drm/drm_atomic.c' line='878' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_get_old_connector_for_encoder'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='878' column='1'/>
-        <parameter type-id='74d89ebd' name='encoder' filepath='drivers/gpu/drm/drm_atomic.c' line='879' column='1'/>
+      <function-decl name='drm_atomic_get_old_connector_for_encoder' mangled-name='drm_atomic_get_old_connector_for_encoder' filepath='drivers/gpu/drm/drm_atomic.c' line='887' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_get_old_connector_for_encoder'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='887' column='1'/>
+        <parameter type-id='74d89ebd' name='encoder' filepath='drivers/gpu/drm/drm_atomic.c' line='888' column='1'/>
         <return type-id='4db02c58'/>
       </function-decl>
-      <function-decl name='drm_atomic_get_plane_state' mangled-name='drm_atomic_get_plane_state' filepath='drivers/gpu/drm/drm_atomic.c' line='464' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_get_plane_state'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='464' column='1'/>
-        <parameter type-id='a6711537' name='plane' filepath='drivers/gpu/drm/drm_atomic.c' line='465' column='1'/>
+      <function-decl name='drm_atomic_get_plane_state' mangled-name='drm_atomic_get_plane_state' filepath='drivers/gpu/drm/drm_atomic.c' line='473' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_get_plane_state'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='473' column='1'/>
+        <parameter type-id='a6711537' name='plane' filepath='drivers/gpu/drm/drm_atomic.c' line='474' column='1'/>
         <return type-id='d0835005'/>
       </function-decl>
-      <function-decl name='drm_atomic_get_private_obj_state' mangled-name='drm_atomic_get_private_obj_state' filepath='drivers/gpu/drm/drm_atomic.c' line='770' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_get_private_obj_state'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='770' column='1'/>
-        <parameter type-id='11c98e9a' name='obj' filepath='drivers/gpu/drm/drm_atomic.c' line='771' column='1'/>
+      <function-decl name='drm_atomic_get_private_obj_state' mangled-name='drm_atomic_get_private_obj_state' filepath='drivers/gpu/drm/drm_atomic.c' line='779' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_get_private_obj_state'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='779' column='1'/>
+        <parameter type-id='11c98e9a' name='obj' filepath='drivers/gpu/drm/drm_atomic.c' line='780' column='1'/>
         <return type-id='4ea020ae'/>
       </function-decl>
       <function-decl name='drm_atomic_helper_bridge_destroy_state' mangled-name='drm_atomic_helper_bridge_destroy_state' filepath='drivers/gpu/drm/drm_atomic_state_helper.c' line='613' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_bridge_destroy_state'>
@@ -127938,13 +128618,13 @@
         <parameter type-id='8582e5ec' name='bridge' filepath='drivers/gpu/drm/drm_atomic_state_helper.c' line='587' column='1'/>
         <return type-id='67bbaeda'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_bridge_propagate_bus_fmt' mangled-name='drm_atomic_helper_bridge_propagate_bus_fmt' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3588' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_bridge_propagate_bus_fmt'>
-        <parameter type-id='8582e5ec' name='bridge' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3588' column='1'/>
-        <parameter type-id='67bbaeda' name='bridge_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3589' column='1'/>
-        <parameter type-id='35078cb9' name='crtc_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3590' column='1'/>
-        <parameter type-id='249ef586' name='conn_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3591' column='1'/>
-        <parameter type-id='19c2251e' name='output_fmt' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3592' column='1'/>
-        <parameter type-id='807869d3' name='num_input_fmts' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3593' column='1'/>
+      <function-decl name='drm_atomic_helper_bridge_propagate_bus_fmt' mangled-name='drm_atomic_helper_bridge_propagate_bus_fmt' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3597' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_bridge_propagate_bus_fmt'>
+        <parameter type-id='8582e5ec' name='bridge' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3597' column='1'/>
+        <parameter type-id='67bbaeda' name='bridge_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3598' column='1'/>
+        <parameter type-id='35078cb9' name='crtc_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3599' column='1'/>
+        <parameter type-id='249ef586' name='conn_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3600' column='1'/>
+        <parameter type-id='19c2251e' name='output_fmt' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3601' column='1'/>
+        <parameter type-id='807869d3' name='num_input_fmts' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3602' column='1'/>
         <return type-id='f9409001'/>
       </function-decl>
       <function-decl name='drm_atomic_helper_bridge_reset' mangled-name='drm_atomic_helper_bridge_reset' filepath='drivers/gpu/drm/drm_atomic_state_helper.c' line='648' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_bridge_reset'>
@@ -127975,52 +128655,52 @@
         <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='883' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_cleanup_planes' mangled-name='drm_atomic_helper_cleanup_planes' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2703' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_cleanup_planes'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2703' column='1'/>
-        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2704' column='1'/>
+      <function-decl name='drm_atomic_helper_cleanup_planes' mangled-name='drm_atomic_helper_cleanup_planes' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2712' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_cleanup_planes'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2712' column='1'/>
+        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2713' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_commit' mangled-name='drm_atomic_helper_commit' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1822' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1822' column='1'/>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1823' column='1'/>
-        <parameter type-id='b50a4934' name='nonblock' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1824' column='1'/>
+      <function-decl name='drm_atomic_helper_commit' mangled-name='drm_atomic_helper_commit' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1831' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1831' column='1'/>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1832' column='1'/>
+        <parameter type-id='b50a4934' name='nonblock' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1833' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_commit_cleanup_done' mangled-name='drm_atomic_helper_commit_cleanup_done' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2362' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_cleanup_done'>
-        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2362' column='1'/>
+      <function-decl name='drm_atomic_helper_commit_cleanup_done' mangled-name='drm_atomic_helper_commit_cleanup_done' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2371' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_cleanup_done'>
+        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2371' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_commit_duplicated_state' mangled-name='drm_atomic_helper_commit_duplicated_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3299' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_duplicated_state'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3299' column='1'/>
-        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3300' column='1'/>
+      <function-decl name='drm_atomic_helper_commit_duplicated_state' mangled-name='drm_atomic_helper_commit_duplicated_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3308' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_duplicated_state'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3308' column='1'/>
+        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3309' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_commit_hw_done' mangled-name='drm_atomic_helper_commit_hw_done' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2317' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_hw_done'>
-        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2317' column='1'/>
+      <function-decl name='drm_atomic_helper_commit_hw_done' mangled-name='drm_atomic_helper_commit_hw_done' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2326' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_hw_done'>
+        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2326' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_commit_modeset_disables' mangled-name='drm_atomic_helper_commit_modeset_disables' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1298' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_modeset_disables'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1298' column='1'/>
-        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1299' column='1'/>
+      <function-decl name='drm_atomic_helper_commit_modeset_disables' mangled-name='drm_atomic_helper_commit_modeset_disables' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1307' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_modeset_disables'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1307' column='1'/>
+        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1308' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_commit_modeset_enables' mangled-name='drm_atomic_helper_commit_modeset_enables' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1345' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_modeset_enables'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1345' column='1'/>
-        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1346' column='1'/>
+      <function-decl name='drm_atomic_helper_commit_modeset_enables' mangled-name='drm_atomic_helper_commit_modeset_enables' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1354' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_modeset_enables'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1354' column='1'/>
+        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1355' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_commit_planes' mangled-name='drm_atomic_helper_commit_planes' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2497' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_planes'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2497' column='1'/>
-        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2498' column='1'/>
-        <parameter type-id='8f92235e' name='flags' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2499' column='1'/>
+      <function-decl name='drm_atomic_helper_commit_planes' mangled-name='drm_atomic_helper_commit_planes' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2506' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_planes'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2506' column='1'/>
+        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2507' column='1'/>
+        <parameter type-id='8f92235e' name='flags' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2508' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_commit_tail' mangled-name='drm_atomic_helper_commit_tail' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1584' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_tail'>
-        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1584' column='1'/>
+      <function-decl name='drm_atomic_helper_commit_tail' mangled-name='drm_atomic_helper_commit_tail' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1593' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_tail'>
+        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1593' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_commit_tail_rpm' mangled-name='drm_atomic_helper_commit_tail_rpm' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1614' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_tail_rpm'>
-        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1614' column='1'/>
+      <function-decl name='drm_atomic_helper_commit_tail_rpm' mangled-name='drm_atomic_helper_commit_tail_rpm' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1623' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_commit_tail_rpm'>
+        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1623' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='drm_atomic_helper_connector_destroy_state' mangled-name='drm_atomic_helper_connector_destroy_state' filepath='drivers/gpu/drm/drm_atomic_state_helper.c' line='537' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_connector_destroy_state'>
@@ -128064,45 +128744,45 @@
         <parameter type-id='f0981eeb' name='num_clips' filepath='drivers/gpu/drm/drm_damage_helper.c' line='163' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_disable_all' mangled-name='drm_atomic_helper_disable_all' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3053' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_disable_all'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3053' column='1'/>
-        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3054' column='1'/>
+      <function-decl name='drm_atomic_helper_disable_all' mangled-name='drm_atomic_helper_disable_all' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3062' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_disable_all'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3062' column='1'/>
+        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3063' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_disable_plane' mangled-name='drm_atomic_helper_disable_plane' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2954' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_disable_plane'>
-        <parameter type-id='a6711537' name='plane' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2954' column='1'/>
-        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2955' column='1'/>
+      <function-decl name='drm_atomic_helper_disable_plane' mangled-name='drm_atomic_helper_disable_plane' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2963' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_disable_plane'>
+        <parameter type-id='a6711537' name='plane' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2963' column='1'/>
+        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2964' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_disable_planes_on_crtc' mangled-name='drm_atomic_helper_disable_planes_on_crtc' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2663' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_disable_planes_on_crtc'>
-        <parameter type-id='35078cb9' name='old_crtc_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2663' column='1'/>
-        <parameter type-id='b50a4934' name='atomic' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2664' column='1'/>
+      <function-decl name='drm_atomic_helper_disable_planes_on_crtc' mangled-name='drm_atomic_helper_disable_planes_on_crtc' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2672' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_disable_planes_on_crtc'>
+        <parameter type-id='35078cb9' name='old_crtc_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2672' column='1'/>
+        <parameter type-id='b50a4934' name='atomic' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2673' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_duplicate_state' mangled-name='drm_atomic_helper_duplicate_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3165' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_duplicate_state'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3165' column='1'/>
-        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3166' column='1'/>
+      <function-decl name='drm_atomic_helper_duplicate_state' mangled-name='drm_atomic_helper_duplicate_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3174' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_duplicate_state'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3174' column='1'/>
+        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3175' column='1'/>
         <return type-id='e3dd029e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_fake_vblank' mangled-name='drm_atomic_helper_fake_vblank' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2279' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_fake_vblank'>
-        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2279' column='1'/>
+      <function-decl name='drm_atomic_helper_fake_vblank' mangled-name='drm_atomic_helper_fake_vblank' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2288' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_fake_vblank'>
+        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2288' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_legacy_gamma_set' mangled-name='drm_atomic_helper_legacy_gamma_set' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3512' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_legacy_gamma_set'>
-        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3512' column='1'/>
-        <parameter type-id='26d4d46f' name='red' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3513' column='1'/>
-        <parameter type-id='26d4d46f' name='green' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3513' column='1'/>
-        <parameter type-id='26d4d46f' name='blue' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3513' column='1'/>
-        <parameter type-id='8f92235e' name='size' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3514' column='1'/>
-        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3515' column='1'/>
+      <function-decl name='drm_atomic_helper_legacy_gamma_set' mangled-name='drm_atomic_helper_legacy_gamma_set' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3521' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_legacy_gamma_set'>
+        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3521' column='1'/>
+        <parameter type-id='26d4d46f' name='red' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3522' column='1'/>
+        <parameter type-id='26d4d46f' name='green' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3522' column='1'/>
+        <parameter type-id='26d4d46f' name='blue' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3522' column='1'/>
+        <parameter type-id='8f92235e' name='size' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3523' column='1'/>
+        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3524' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_page_flip' mangled-name='drm_atomic_helper_page_flip' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3419' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_page_flip'>
-        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3419' column='1'/>
-        <parameter type-id='7b332e1c' name='fb' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3420' column='1'/>
-        <parameter type-id='6301fad2' name='event' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3421' column='1'/>
-        <parameter type-id='8f92235e' name='flags' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3422' column='1'/>
-        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3423' column='1'/>
+      <function-decl name='drm_atomic_helper_page_flip' mangled-name='drm_atomic_helper_page_flip' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3428' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_page_flip'>
+        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3428' column='1'/>
+        <parameter type-id='7b332e1c' name='fb' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3429' column='1'/>
+        <parameter type-id='6301fad2' name='event' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3430' column='1'/>
+        <parameter type-id='8f92235e' name='flags' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3431' column='1'/>
+        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3432' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='drm_atomic_helper_plane_destroy_state' mangled-name='drm_atomic_helper_plane_destroy_state' filepath='drivers/gpu/drm/drm_atomic_state_helper.c' line='371' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_plane_destroy_state'>
@@ -128118,81 +128798,81 @@
         <parameter type-id='a6711537' name='plane' filepath='drivers/gpu/drm/drm_atomic_state_helper.c' line='283' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_prepare_planes' mangled-name='drm_atomic_helper_prepare_planes' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2402' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_prepare_planes'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2402' column='1'/>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2403' column='1'/>
+      <function-decl name='drm_atomic_helper_prepare_planes' mangled-name='drm_atomic_helper_prepare_planes' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2411' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_prepare_planes'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2411' column='1'/>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2412' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_resume' mangled-name='drm_atomic_helper_resume' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3345' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_resume'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3345' column='1'/>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3346' column='1'/>
+      <function-decl name='drm_atomic_helper_resume' mangled-name='drm_atomic_helper_resume' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3354' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_resume'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3354' column='1'/>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3355' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_set_config' mangled-name='drm_atomic_helper_set_config' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3002' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_set_config'>
-        <parameter type-id='8106240b' name='set' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3002' column='1'/>
-        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3003' column='1'/>
+      <function-decl name='drm_atomic_helper_set_config' mangled-name='drm_atomic_helper_set_config' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3011' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_set_config'>
+        <parameter type-id='8106240b' name='set' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3011' column='1'/>
+        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3012' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_setup_commit' mangled-name='drm_atomic_helper_setup_commit' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2080' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_setup_commit'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2080' column='1'/>
-        <parameter type-id='b50a4934' name='nonblock' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2081' column='1'/>
+      <function-decl name='drm_atomic_helper_setup_commit' mangled-name='drm_atomic_helper_setup_commit' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2089' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_setup_commit'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2089' column='1'/>
+        <parameter type-id='b50a4934' name='nonblock' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2090' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_shutdown' mangled-name='drm_atomic_helper_shutdown' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3125' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_shutdown'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3125' column='1'/>
+      <function-decl name='drm_atomic_helper_shutdown' mangled-name='drm_atomic_helper_shutdown' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3134' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_shutdown'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3134' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_suspend' mangled-name='drm_atomic_helper_suspend' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3253' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_suspend'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3253' column='1'/>
+      <function-decl name='drm_atomic_helper_suspend' mangled-name='drm_atomic_helper_suspend' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3262' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_suspend'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='3262' column='1'/>
         <return type-id='e3dd029e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_swap_state' mangled-name='drm_atomic_helper_swap_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2766' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_swap_state'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2766' column='1'/>
-        <parameter type-id='b50a4934' name='stall' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2767' column='1'/>
+      <function-decl name='drm_atomic_helper_swap_state' mangled-name='drm_atomic_helper_swap_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2775' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_swap_state'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2775' column='1'/>
+        <parameter type-id='b50a4934' name='stall' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2776' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_update_legacy_modeset_state' mangled-name='drm_atomic_helper_update_legacy_modeset_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_update_legacy_modeset_state'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1140' column='1'/>
-        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1141' column='1'/>
+      <function-decl name='drm_atomic_helper_update_legacy_modeset_state' mangled-name='drm_atomic_helper_update_legacy_modeset_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1149' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_update_legacy_modeset_state'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1149' column='1'/>
+        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1150' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_update_plane' mangled-name='drm_atomic_helper_update_plane' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2897' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_update_plane'>
-        <parameter type-id='a6711537' name='plane' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2897' column='1'/>
-        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2898' column='1'/>
-        <parameter type-id='7b332e1c' name='fb' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2899' column='1'/>
-        <parameter type-id='95e97e5e' name='crtc_x' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2900' column='1'/>
-        <parameter type-id='95e97e5e' name='crtc_y' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2900' column='1'/>
-        <parameter type-id='f0981eeb' name='crtc_w' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2901' column='1'/>
-        <parameter type-id='f0981eeb' name='crtc_h' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2901' column='1'/>
-        <parameter type-id='8f92235e' name='src_x' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2902' column='1'/>
-        <parameter type-id='8f92235e' name='src_y' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2902' column='1'/>
-        <parameter type-id='8f92235e' name='src_w' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2903' column='1'/>
-        <parameter type-id='8f92235e' name='src_h' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2903' column='1'/>
-        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2904' column='1'/>
+      <function-decl name='drm_atomic_helper_update_plane' mangled-name='drm_atomic_helper_update_plane' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2906' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_update_plane'>
+        <parameter type-id='a6711537' name='plane' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2906' column='1'/>
+        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2907' column='1'/>
+        <parameter type-id='7b332e1c' name='fb' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2908' column='1'/>
+        <parameter type-id='95e97e5e' name='crtc_x' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2909' column='1'/>
+        <parameter type-id='95e97e5e' name='crtc_y' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2909' column='1'/>
+        <parameter type-id='f0981eeb' name='crtc_w' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2910' column='1'/>
+        <parameter type-id='f0981eeb' name='crtc_h' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2910' column='1'/>
+        <parameter type-id='8f92235e' name='src_x' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2911' column='1'/>
+        <parameter type-id='8f92235e' name='src_y' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2911' column='1'/>
+        <parameter type-id='8f92235e' name='src_w' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2912' column='1'/>
+        <parameter type-id='8f92235e' name='src_h' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2912' column='1'/>
+        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2913' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_wait_for_dependencies' mangled-name='drm_atomic_helper_wait_for_dependencies' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2184' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_wait_for_dependencies'>
-        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2184' column='1'/>
+      <function-decl name='drm_atomic_helper_wait_for_dependencies' mangled-name='drm_atomic_helper_wait_for_dependencies' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2193' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_wait_for_dependencies'>
+        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='2193' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_wait_for_fences' mangled-name='drm_atomic_helper_wait_for_fences' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1439' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_wait_for_fences'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1439' column='1'/>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1440' column='1'/>
-        <parameter type-id='b50a4934' name='pre_swap' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1441' column='1'/>
+      <function-decl name='drm_atomic_helper_wait_for_fences' mangled-name='drm_atomic_helper_wait_for_fences' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1448' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_wait_for_fences'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1448' column='1'/>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1449' column='1'/>
+        <parameter type-id='b50a4934' name='pre_swap' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1450' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_wait_for_flip_done' mangled-name='drm_atomic_helper_wait_for_flip_done' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1545' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_wait_for_flip_done'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1545' column='1'/>
-        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1546' column='1'/>
+      <function-decl name='drm_atomic_helper_wait_for_flip_done' mangled-name='drm_atomic_helper_wait_for_flip_done' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1554' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_wait_for_flip_done'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1554' column='1'/>
+        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1555' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_helper_wait_for_vblanks' mangled-name='drm_atomic_helper_wait_for_vblanks' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1486' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_wait_for_vblanks'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1486' column='1'/>
-        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1487' column='1'/>
+      <function-decl name='drm_atomic_helper_wait_for_vblanks' mangled-name='drm_atomic_helper_wait_for_vblanks' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1495' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_helper_wait_for_vblanks'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1495' column='1'/>
+        <parameter type-id='e3dd029e' name='old_state' filepath='drivers/gpu/drm/drm_atomic_helper.c' line='1496' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_nonblocking_commit' mangled-name='drm_atomic_nonblocking_commit' filepath='drivers/gpu/drm/drm_atomic.c' line='1363' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_nonblocking_commit'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='1363' column='1'/>
+      <function-decl name='drm_atomic_nonblocking_commit' mangled-name='drm_atomic_nonblocking_commit' filepath='drivers/gpu/drm/drm_atomic.c' line='1373' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_nonblocking_commit'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='1373' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='drm_atomic_normalize_zpos' mangled-name='drm_atomic_normalize_zpos' filepath='drivers/gpu/drm/drm_blend.c' line='504' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_normalize_zpos'>
@@ -128200,35 +128880,35 @@
         <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_blend.c' line='505' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_private_obj_fini' mangled-name='drm_atomic_private_obj_fini' filepath='drivers/gpu/drm/drm_atomic.c' line='748' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_private_obj_fini'>
-        <parameter type-id='11c98e9a' name='obj' filepath='drivers/gpu/drm/drm_atomic.c' line='748' column='1'/>
+      <function-decl name='drm_atomic_private_obj_fini' mangled-name='drm_atomic_private_obj_fini' filepath='drivers/gpu/drm/drm_atomic.c' line='757' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_private_obj_fini'>
+        <parameter type-id='11c98e9a' name='obj' filepath='drivers/gpu/drm/drm_atomic.c' line='757' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_private_obj_init' mangled-name='drm_atomic_private_obj_init' filepath='drivers/gpu/drm/drm_atomic.c' line='726' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_private_obj_init'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic.c' line='726' column='1'/>
-        <parameter type-id='11c98e9a' name='obj' filepath='drivers/gpu/drm/drm_atomic.c' line='727' column='1'/>
-        <parameter type-id='4ea020ae' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='728' column='1'/>
-        <parameter type-id='515fa1af' name='funcs' filepath='drivers/gpu/drm/drm_atomic.c' line='729' column='1'/>
+      <function-decl name='drm_atomic_private_obj_init' mangled-name='drm_atomic_private_obj_init' filepath='drivers/gpu/drm/drm_atomic.c' line='735' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_private_obj_init'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic.c' line='735' column='1'/>
+        <parameter type-id='11c98e9a' name='obj' filepath='drivers/gpu/drm/drm_atomic.c' line='736' column='1'/>
+        <parameter type-id='4ea020ae' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='737' column='1'/>
+        <parameter type-id='515fa1af' name='funcs' filepath='drivers/gpu/drm/drm_atomic.c' line='738' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_set_crtc_for_connector' mangled-name='drm_atomic_set_crtc_for_connector' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='296' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_set_crtc_for_connector'>
-        <parameter type-id='249ef586' name='conn_state' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='296' column='1'/>
-        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='297' column='1'/>
+      <function-decl name='drm_atomic_set_crtc_for_connector' mangled-name='drm_atomic_set_crtc_for_connector' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='298' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_set_crtc_for_connector'>
+        <parameter type-id='249ef586' name='conn_state' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='298' column='1'/>
+        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='299' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_set_crtc_for_plane' mangled-name='drm_atomic_set_crtc_for_plane' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='177' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_set_crtc_for_plane'>
-        <parameter type-id='d0835005' name='plane_state' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='177' column='1'/>
-        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='178' column='1'/>
+      <function-decl name='drm_atomic_set_crtc_for_plane' mangled-name='drm_atomic_set_crtc_for_plane' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='179' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_set_crtc_for_plane'>
+        <parameter type-id='d0835005' name='plane_state' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='179' column='1'/>
+        <parameter type-id='b64ad7cb' name='crtc' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='180' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_set_fb_for_plane' mangled-name='drm_atomic_set_fb_for_plane' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='227' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_set_fb_for_plane'>
-        <parameter type-id='d0835005' name='plane_state' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='227' column='1'/>
-        <parameter type-id='7b332e1c' name='fb' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='228' column='1'/>
+      <function-decl name='drm_atomic_set_fb_for_plane' mangled-name='drm_atomic_set_fb_for_plane' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='229' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_set_fb_for_plane'>
+        <parameter type-id='d0835005' name='plane_state' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='229' column='1'/>
+        <parameter type-id='7b332e1c' name='fb' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='230' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_set_fence_for_plane' mangled-name='drm_atomic_set_fence_for_plane' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='269' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_set_fence_for_plane'>
-        <parameter type-id='d0835005' name='plane_state' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='269' column='1'/>
-        <parameter type-id='28271da3' name='fence' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='270' column='1'/>
+      <function-decl name='drm_atomic_set_fence_for_plane' mangled-name='drm_atomic_set_fence_for_plane' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='271' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_set_fence_for_plane'>
+        <parameter type-id='d0835005' name='plane_state' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='271' column='1'/>
+        <parameter type-id='28271da3' name='fence' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='272' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='drm_atomic_set_mode_for_crtc' mangled-name='drm_atomic_set_mode_for_crtc' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='64' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_set_mode_for_crtc'>
@@ -128236,21 +128916,21 @@
         <parameter type-id='745b39e8' name='mode' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='65' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_set_mode_prop_for_crtc' mangled-name='drm_atomic_set_mode_prop_for_crtc' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='114' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_set_mode_prop_for_crtc'>
-        <parameter type-id='35078cb9' name='state' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='114' column='1'/>
-        <parameter type-id='c4126d52' name='blob' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='115' column='1'/>
+      <function-decl name='drm_atomic_set_mode_prop_for_crtc' mangled-name='drm_atomic_set_mode_prop_for_crtc' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='116' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_set_mode_prop_for_crtc'>
+        <parameter type-id='35078cb9' name='state' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='116' column='1'/>
+        <parameter type-id='c4126d52' name='blob' filepath='drivers/gpu/drm/drm_atomic_uapi.c' line='117' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_atomic_state_alloc' mangled-name='drm_atomic_state_alloc' filepath='drivers/gpu/drm/drm_atomic.c' line='119' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_state_alloc'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic.c' line='119' column='1'/>
+      <function-decl name='drm_atomic_state_alloc' mangled-name='drm_atomic_state_alloc' filepath='drivers/gpu/drm/drm_atomic.c' line='125' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_state_alloc'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic.c' line='125' column='1'/>
         <return type-id='e3dd029e'/>
       </function-decl>
-      <function-decl name='drm_atomic_state_clear' mangled-name='drm_atomic_state_clear' filepath='drivers/gpu/drm/drm_atomic.c' line='238' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_state_clear'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='238' column='1'/>
+      <function-decl name='drm_atomic_state_clear' mangled-name='drm_atomic_state_clear' filepath='drivers/gpu/drm/drm_atomic.c' line='244' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_state_clear'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='244' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_atomic_state_default_clear' mangled-name='drm_atomic_state_default_clear' filepath='drivers/gpu/drm/drm_atomic.c' line='148' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_state_default_clear'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='148' column='1'/>
+      <function-decl name='drm_atomic_state_default_clear' mangled-name='drm_atomic_state_default_clear' filepath='drivers/gpu/drm/drm_atomic.c' line='154' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_state_default_clear'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_atomic.c' line='154' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='drm_atomic_state_default_release' mangled-name='drm_atomic_state_default_release' filepath='drivers/gpu/drm/drm_atomic.c' line='64' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_atomic_state_default_release'>
@@ -128348,8 +129028,8 @@
         <parameter type-id='67ede465' name='funcs' filepath='drivers/gpu/drm/drm_client.c' line='79' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_client_modeset_commit_locked' mangled-name='drm_client_modeset_commit_locked' filepath='drivers/gpu/drm/drm_client_modeset.c' line='1138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_client_modeset_commit_locked'>
-        <parameter type-id='cc1804ea' name='client' filepath='drivers/gpu/drm/drm_client_modeset.c' line='1138' column='1'/>
+      <function-decl name='drm_client_modeset_commit_locked' mangled-name='drm_client_modeset_commit_locked' filepath='drivers/gpu/drm/drm_client_modeset.c' line='1144' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_client_modeset_commit_locked'>
+        <parameter type-id='cc1804ea' name='client' filepath='drivers/gpu/drm/drm_client_modeset.c' line='1144' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='drm_client_register' mangled-name='drm_client_register' filepath='drivers/gpu/drm/drm_client.c' line='125' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_client_register'>
@@ -128367,8 +129047,8 @@
         <parameter type-id='b50a4934' name='hdcp_content_type' filepath='drivers/gpu/drm/drm_hdcp.c' line='358' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_connector_attach_dp_subconnector_property' mangled-name='drm_connector_attach_dp_subconnector_property' filepath='drivers/gpu/drm/drm_connector.c' line='1335' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_attach_dp_subconnector_property'>
-        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='1335' column='1'/>
+      <function-decl name='drm_connector_attach_dp_subconnector_property' mangled-name='drm_connector_attach_dp_subconnector_property' filepath='drivers/gpu/drm/drm_connector.c' line='1338' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_attach_dp_subconnector_property'>
+        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='1338' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='drm_connector_attach_edid_property' mangled-name='drm_connector_attach_edid_property' filepath='drivers/gpu/drm/drm_connector.c' line='367' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_attach_edid_property'>
@@ -128380,10 +129060,10 @@
         <parameter type-id='74d89ebd' name='encoder' filepath='drivers/gpu/drm/drm_connector.c' line='390' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_connector_attach_max_bpc_property' mangled-name='drm_connector_attach_max_bpc_property' filepath='drivers/gpu/drm/drm_connector.c' line='2123' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_attach_max_bpc_property'>
-        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='2123' column='1'/>
-        <parameter type-id='95e97e5e' name='min' filepath='drivers/gpu/drm/drm_connector.c' line='2124' column='1'/>
-        <parameter type-id='95e97e5e' name='max' filepath='drivers/gpu/drm/drm_connector.c' line='2124' column='1'/>
+      <function-decl name='drm_connector_attach_max_bpc_property' mangled-name='drm_connector_attach_max_bpc_property' filepath='drivers/gpu/drm/drm_connector.c' line='2126' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_attach_max_bpc_property'>
+        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='2126' column='1'/>
+        <parameter type-id='95e97e5e' name='min' filepath='drivers/gpu/drm/drm_connector.c' line='2127' column='1'/>
+        <parameter type-id='95e97e5e' name='max' filepath='drivers/gpu/drm/drm_connector.c' line='2127' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='drm_connector_cleanup' mangled-name='drm_connector_cleanup' filepath='drivers/gpu/drm/drm_connector.c' line='441' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_cleanup'>
@@ -128410,48 +129090,48 @@
         <parameter type-id='b9af02c3' name='ddc' filepath='drivers/gpu/drm/drm_connector.c' line='344' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_connector_list_iter_begin' mangled-name='drm_connector_list_iter_begin' filepath='drivers/gpu/drm/drm_connector.c' line='657' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_list_iter_begin'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_connector.c' line='657' column='1'/>
-        <parameter type-id='40a902ec' name='iter' filepath='drivers/gpu/drm/drm_connector.c' line='658' column='1'/>
+      <function-decl name='drm_connector_list_iter_begin' mangled-name='drm_connector_list_iter_begin' filepath='drivers/gpu/drm/drm_connector.c' line='660' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_list_iter_begin'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_connector.c' line='660' column='1'/>
+        <parameter type-id='40a902ec' name='iter' filepath='drivers/gpu/drm/drm_connector.c' line='661' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_connector_list_iter_end' mangled-name='drm_connector_list_iter_end' filepath='drivers/gpu/drm/drm_connector.c' line='732' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_list_iter_end'>
-        <parameter type-id='40a902ec' name='iter' filepath='drivers/gpu/drm/drm_connector.c' line='732' column='1'/>
+      <function-decl name='drm_connector_list_iter_end' mangled-name='drm_connector_list_iter_end' filepath='drivers/gpu/drm/drm_connector.c' line='735' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_list_iter_end'>
+        <parameter type-id='40a902ec' name='iter' filepath='drivers/gpu/drm/drm_connector.c' line='735' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_connector_list_iter_next' mangled-name='drm_connector_list_iter_next' filepath='drivers/gpu/drm/drm_connector.c' line='693' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_list_iter_next'>
-        <parameter type-id='40a902ec' name='iter' filepath='drivers/gpu/drm/drm_connector.c' line='693' column='1'/>
+      <function-decl name='drm_connector_list_iter_next' mangled-name='drm_connector_list_iter_next' filepath='drivers/gpu/drm/drm_connector.c' line='696' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_list_iter_next'>
+        <parameter type-id='40a902ec' name='iter' filepath='drivers/gpu/drm/drm_connector.c' line='696' column='1'/>
         <return type-id='4db02c58'/>
       </function-decl>
       <function-decl name='drm_connector_list_update' mangled-name='drm_connector_list_update' filepath='drivers/gpu/drm/drm_modes.c' line='1338' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_list_update'>
         <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_modes.c' line='1338' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_connector_register' mangled-name='drm_connector_register' filepath='drivers/gpu/drm/drm_connector.c' line='502' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_register'>
-        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='502' column='1'/>
+      <function-decl name='drm_connector_register' mangled-name='drm_connector_register' filepath='drivers/gpu/drm/drm_connector.c' line='505' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_register'>
+        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='505' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_connector_set_panel_orientation' mangled-name='drm_connector_set_panel_orientation' filepath='drivers/gpu/drm/drm_connector.c' line='2185' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_set_panel_orientation'>
-        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='2186' column='1'/>
-        <parameter type-id='59f3d325' name='panel_orientation' filepath='drivers/gpu/drm/drm_connector.c' line='2187' column='1'/>
+      <function-decl name='drm_connector_set_panel_orientation' mangled-name='drm_connector_set_panel_orientation' filepath='drivers/gpu/drm/drm_connector.c' line='2188' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_set_panel_orientation'>
+        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='2189' column='1'/>
+        <parameter type-id='59f3d325' name='panel_orientation' filepath='drivers/gpu/drm/drm_connector.c' line='2190' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_connector_set_path_property' mangled-name='drm_connector_set_path_property' filepath='drivers/gpu/drm/drm_connector.c' line='1947' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_set_path_property'>
-        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='1947' column='1'/>
-        <parameter type-id='80f4b756' name='path' filepath='drivers/gpu/drm/drm_connector.c' line='1948' column='1'/>
+      <function-decl name='drm_connector_set_path_property' mangled-name='drm_connector_set_path_property' filepath='drivers/gpu/drm/drm_connector.c' line='1950' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_set_path_property'>
+        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='1950' column='1'/>
+        <parameter type-id='80f4b756' name='path' filepath='drivers/gpu/drm/drm_connector.c' line='1951' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_connector_set_tile_property' mangled-name='drm_connector_set_tile_property' filepath='drivers/gpu/drm/drm_connector.c' line='1976' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_set_tile_property'>
-        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='1976' column='1'/>
+      <function-decl name='drm_connector_set_tile_property' mangled-name='drm_connector_set_tile_property' filepath='drivers/gpu/drm/drm_connector.c' line='1979' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_set_tile_property'>
+        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='1979' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_connector_unregister' mangled-name='drm_connector_unregister' filepath='drivers/gpu/drm/drm_connector.c' line='552' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_unregister'>
-        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='552' column='1'/>
+      <function-decl name='drm_connector_unregister' mangled-name='drm_connector_unregister' filepath='drivers/gpu/drm/drm_connector.c' line='555' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_unregister'>
+        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='555' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_connector_update_edid_property' mangled-name='drm_connector_update_edid_property' filepath='drivers/gpu/drm/drm_connector.c' line='2022' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_update_edid_property'>
-        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='2022' column='1'/>
-        <parameter type-id='776adf76' name='edid' filepath='drivers/gpu/drm/drm_connector.c' line='2023' column='1'/>
+      <function-decl name='drm_connector_update_edid_property' mangled-name='drm_connector_update_edid_property' filepath='drivers/gpu/drm/drm_connector.c' line='2025' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_connector_update_edid_property'>
+        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='2025' column='1'/>
+        <parameter type-id='776adf76' name='edid' filepath='drivers/gpu/drm/drm_connector.c' line='2026' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='drm_crtc_arm_vblank_event' mangled-name='drm_crtc_arm_vblank_event' filepath='drivers/gpu/drm/drm_vblank.c' line='1051' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_crtc_arm_vblank_event'>
@@ -128645,10 +129325,10 @@
         <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_drv.c' line='933' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_display_info_set_bus_formats' mangled-name='drm_display_info_set_bus_formats' filepath='drivers/gpu/drm/drm_connector.c' line='792' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_display_info_set_bus_formats'>
-        <parameter type-id='939a8d9a' name='info' filepath='drivers/gpu/drm/drm_connector.c' line='792' column='1'/>
-        <parameter type-id='aded214c' name='formats' filepath='drivers/gpu/drm/drm_connector.c' line='793' column='1'/>
-        <parameter type-id='f0981eeb' name='num_formats' filepath='drivers/gpu/drm/drm_connector.c' line='794' column='1'/>
+      <function-decl name='drm_display_info_set_bus_formats' mangled-name='drm_display_info_set_bus_formats' filepath='drivers/gpu/drm/drm_connector.c' line='795' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_display_info_set_bus_formats'>
+        <parameter type-id='939a8d9a' name='info' filepath='drivers/gpu/drm/drm_connector.c' line='795' column='1'/>
+        <parameter type-id='aded214c' name='formats' filepath='drivers/gpu/drm/drm_connector.c' line='796' column='1'/>
+        <parameter type-id='f0981eeb' name='num_formats' filepath='drivers/gpu/drm/drm_connector.c' line='797' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='drm_display_mode_from_videomode' mangled-name='drm_display_mode_from_videomode' filepath='drivers/gpu/drm/drm_modes.c' line='588' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_display_mode_from_videomode'>
@@ -128667,18 +129347,18 @@
         <parameter type-id='eaa32e2f' name='data' filepath='drivers/gpu/drm/drm_edid.c' line='1941' column='1'/>
         <return type-id='c91d1bf1'/>
       </function-decl>
-      <function-decl name='drm_dp_atomic_find_vcpi_slots' mangled-name='drm_dp_atomic_find_vcpi_slots' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4374' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_atomic_find_vcpi_slots'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4374' column='1'/>
-        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4375' column='1'/>
-        <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4376' column='1'/>
-        <parameter type-id='95e97e5e' name='pbn' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4376' column='1'/>
-        <parameter type-id='95e97e5e' name='pbn_div' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4377' column='1'/>
+      <function-decl name='drm_dp_atomic_find_vcpi_slots' mangled-name='drm_dp_atomic_find_vcpi_slots' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4377' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_atomic_find_vcpi_slots'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4377' column='1'/>
+        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4378' column='1'/>
+        <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4379' column='1'/>
+        <parameter type-id='95e97e5e' name='pbn' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4379' column='1'/>
+        <parameter type-id='95e97e5e' name='pbn_div' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4380' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_dp_atomic_release_vcpi_slots' mangled-name='drm_dp_atomic_release_vcpi_slots' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4468' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_atomic_release_vcpi_slots'>
-        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4468' column='1'/>
-        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4469' column='1'/>
-        <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4470' column='1'/>
+      <function-decl name='drm_dp_atomic_release_vcpi_slots' mangled-name='drm_dp_atomic_release_vcpi_slots' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4471' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_atomic_release_vcpi_slots'>
+        <parameter type-id='e3dd029e' name='state' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4471' column='1'/>
+        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4472' column='1'/>
+        <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4473' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='drm_dp_aux_init' mangled-name='drm_dp_aux_init' filepath='drivers/gpu/drm/drm_dp_helper.c' line='1634' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_aux_init'>
@@ -128697,10 +129377,10 @@
         <parameter type-id='f9b06939' name='link_bw' filepath='drivers/gpu/drm/drm_dp_helper.c' line='178' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_dp_calc_pbn_mode' mangled-name='drm_dp_calc_pbn_mode' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4719' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_calc_pbn_mode'>
-        <parameter type-id='95e97e5e' name='clock' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4719' column='1'/>
-        <parameter type-id='95e97e5e' name='bpp' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4719' column='1'/>
-        <parameter type-id='b50a4934' name='dsc' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4719' column='1'/>
+      <function-decl name='drm_dp_calc_pbn_mode' mangled-name='drm_dp_calc_pbn_mode' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4722' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_calc_pbn_mode'>
+        <parameter type-id='95e97e5e' name='clock' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4722' column='1'/>
+        <parameter type-id='95e97e5e' name='bpp' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4722' column='1'/>
+        <parameter type-id='b50a4934' name='dsc' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4722' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='drm_dp_channel_eq_ok' mangled-name='drm_dp_channel_eq_ok' filepath='drivers/gpu/drm/drm_dp_helper.c' line='64' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_channel_eq_ok'>
@@ -128708,8 +129388,8 @@
         <parameter type-id='95e97e5e' name='lane_count' filepath='drivers/gpu/drm/drm_dp_helper.c' line='65' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='drm_dp_check_act_status' mangled-name='drm_dp_check_act_status' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4679' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_check_act_status'>
-        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4679' column='1'/>
+      <function-decl name='drm_dp_check_act_status' mangled-name='drm_dp_check_act_status' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4682' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_check_act_status'>
+        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4682' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='drm_dp_clock_recovery_ok' mangled-name='drm_dp_clock_recovery_ok' filepath='drivers/gpu/drm/drm_dp_helper.c' line='84' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_clock_recovery_ok'>
@@ -128753,9 +129433,9 @@
         <parameter type-id='b50a4934' name='is_edp' filepath='drivers/gpu/drm/drm_dp_helper.c' line='1993' column='1'/>
         <return type-id='f9b06939'/>
       </function-decl>
-      <function-decl name='drm_dp_find_vcpi_slots' mangled-name='drm_dp_find_vcpi_slots' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4310' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_find_vcpi_slots'>
-        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4310' column='1'/>
-        <parameter type-id='95e97e5e' name='pbn' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4311' column='1'/>
+      <function-decl name='drm_dp_find_vcpi_slots' mangled-name='drm_dp_find_vcpi_slots' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4313' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_find_vcpi_slots'>
+        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4313' column='1'/>
+        <parameter type-id='95e97e5e' name='pbn' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4314' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='drm_dp_get_adjust_request_pre_emphasis' mangled-name='drm_dp_get_adjust_request_pre_emphasis' filepath='drivers/gpu/drm/drm_dp_helper.c' line='112' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_get_adjust_request_pre_emphasis'>
@@ -128789,66 +129469,66 @@
         <parameter type-id='bbaf3419' name='dpcd' filepath='drivers/gpu/drm/drm_dp_helper.c' line='135' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_dp_mst_allocate_vcpi' mangled-name='drm_dp_mst_allocate_vcpi' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4510' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_allocate_vcpi'>
-        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4510' column='1'/>
-        <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4511' column='1'/>
-        <parameter type-id='95e97e5e' name='pbn' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4511' column='1'/>
-        <parameter type-id='95e97e5e' name='slots' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4511' column='1'/>
+      <function-decl name='drm_dp_mst_allocate_vcpi' mangled-name='drm_dp_mst_allocate_vcpi' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4513' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_allocate_vcpi'>
+        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4513' column='1'/>
+        <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4514' column='1'/>
+        <parameter type-id='95e97e5e' name='pbn' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4514' column='1'/>
+        <parameter type-id='95e97e5e' name='slots' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4514' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='drm_dp_mst_deallocate_vcpi' mangled-name='drm_dp_mst_deallocate_vcpi' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4590' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_deallocate_vcpi'>
-        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4590' column='1'/>
-        <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4591' column='1'/>
+      <function-decl name='drm_dp_mst_deallocate_vcpi' mangled-name='drm_dp_mst_deallocate_vcpi' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4593' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_deallocate_vcpi'>
+        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4593' column='1'/>
+        <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4594' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_dp_mst_detect_port' mangled-name='drm_dp_mst_detect_port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4221' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_detect_port'>
-        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4221' column='1'/>
-        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4222' column='1'/>
-        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4223' column='1'/>
-        <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4224' column='1'/>
+      <function-decl name='drm_dp_mst_detect_port' mangled-name='drm_dp_mst_detect_port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4224' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_detect_port'>
+        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4224' column='1'/>
+        <parameter type-id='d1499e71' name='ctx' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4225' column='1'/>
+        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4226' column='1'/>
+        <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4227' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_dp_mst_dump_topology' mangled-name='drm_dp_mst_dump_topology' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4805' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_dump_topology'>
-        <parameter type-id='f8dc9def' name='m' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4805' column='1'/>
-        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4806' column='1'/>
+      <function-decl name='drm_dp_mst_dump_topology' mangled-name='drm_dp_mst_dump_topology' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4808' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_dump_topology'>
+        <parameter type-id='f8dc9def' name='m' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4808' column='1'/>
+        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4809' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_dp_mst_get_edid' mangled-name='drm_dp_mst_get_edid' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4278' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_get_edid'>
-        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4278' column='1'/>
-        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4278' column='1'/>
-        <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4278' column='1'/>
+      <function-decl name='drm_dp_mst_get_edid' mangled-name='drm_dp_mst_get_edid' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4281' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_get_edid'>
+        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4281' column='1'/>
+        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4281' column='1'/>
+        <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4281' column='1'/>
         <return type-id='c91d1bf1'/>
       </function-decl>
       <function-decl name='drm_dp_mst_get_port_malloc' mangled-name='drm_dp_mst_get_port_malloc' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='1539' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_get_port_malloc'>
         <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='1539' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_dp_mst_hpd_irq' mangled-name='drm_dp_mst_hpd_irq' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4184' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_hpd_irq'>
-        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4184' column='1'/>
-        <parameter type-id='8bff8096' name='esi' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4184' column='1'/>
-        <parameter type-id='d8e6b335' name='handled' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4184' column='1'/>
+      <function-decl name='drm_dp_mst_hpd_irq' mangled-name='drm_dp_mst_hpd_irq' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4187' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_hpd_irq'>
+        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4187' column='1'/>
+        <parameter type-id='8bff8096' name='esi' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4187' column='1'/>
+        <parameter type-id='d8e6b335' name='handled' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4187' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='drm_dp_mst_put_port_malloc' mangled-name='drm_dp_mst_put_port_malloc' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='1557' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_put_port_malloc'>
         <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='1557' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_dp_mst_reset_vcpi_slots' mangled-name='drm_dp_mst_reset_vcpi_slots' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4571' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_reset_vcpi_slots'>
-        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4571' column='1'/>
-        <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4571' column='1'/>
+      <function-decl name='drm_dp_mst_reset_vcpi_slots' mangled-name='drm_dp_mst_reset_vcpi_slots' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4574' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_reset_vcpi_slots'>
+        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4574' column='1'/>
+        <parameter type-id='c45d1018' name='port' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='4574' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_dp_mst_topology_mgr_destroy' mangled-name='drm_dp_mst_topology_mgr_destroy' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5495' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_topology_mgr_destroy'>
-        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5495' column='1'/>
+      <function-decl name='drm_dp_mst_topology_mgr_destroy' mangled-name='drm_dp_mst_topology_mgr_destroy' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5498' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_topology_mgr_destroy'>
+        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5498' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_dp_mst_topology_mgr_init' mangled-name='drm_dp_mst_topology_mgr_init' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5426' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_topology_mgr_init'>
-        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5426' column='1'/>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5427' column='1'/>
-        <parameter type-id='7c5f8cd8' name='aux' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5427' column='1'/>
-        <parameter type-id='95e97e5e' name='max_dpcd_transaction_bytes' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5428' column='1'/>
-        <parameter type-id='95e97e5e' name='max_payloads' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5429' column='1'/>
-        <parameter type-id='95e97e5e' name='conn_base_id' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5429' column='1'/>
+      <function-decl name='drm_dp_mst_topology_mgr_init' mangled-name='drm_dp_mst_topology_mgr_init' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5429' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_topology_mgr_init'>
+        <parameter type-id='88a6d23d' name='mgr' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5429' column='1'/>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5430' column='1'/>
+        <parameter type-id='7c5f8cd8' name='aux' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5430' column='1'/>
+        <parameter type-id='95e97e5e' name='max_dpcd_transaction_bytes' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5431' column='1'/>
+        <parameter type-id='95e97e5e' name='max_payloads' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5432' column='1'/>
+        <parameter type-id='95e97e5e' name='conn_base_id' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='5432' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='drm_dp_mst_topology_mgr_set_mst' mangled-name='drm_dp_mst_topology_mgr_set_mst' filepath='drivers/gpu/drm/drm_dp_mst_topology.c' line='3700' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_dp_mst_topology_mgr_set_mst'>
@@ -129008,14 +129688,14 @@
         <parameter type-id='eaa32e2f' name='val' filepath='drivers/gpu/drm/drm_flip_work.c' line='76' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_format_info' mangled-name='drm_format_info' filepath='drivers/gpu/drm/drm_fourcc.c' line='312' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_format_info'>
-        <parameter type-id='19c2251e' name='format' filepath='drivers/gpu/drm/drm_fourcc.c' line='312' column='1'/>
+      <function-decl name='drm_format_info' mangled-name='drm_format_info' filepath='drivers/gpu/drm/drm_fourcc.c' line='319' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_format_info'>
+        <parameter type-id='19c2251e' name='format' filepath='drivers/gpu/drm/drm_fourcc.c' line='319' column='1'/>
         <return type-id='f10b2208'/>
       </function-decl>
-      <function-decl name='drm_format_info_min_pitch' mangled-name='drm_format_info_min_pitch' filepath='drivers/gpu/drm/drm_fourcc.c' line='397' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_format_info_min_pitch'>
-        <parameter type-id='f10b2208' name='info' filepath='drivers/gpu/drm/drm_fourcc.c' line='397' column='1'/>
-        <parameter type-id='95e97e5e' name='plane' filepath='drivers/gpu/drm/drm_fourcc.c' line='398' column='1'/>
-        <parameter type-id='f0981eeb' name='buffer_width' filepath='drivers/gpu/drm/drm_fourcc.c' line='398' column='1'/>
+      <function-decl name='drm_format_info_min_pitch' mangled-name='drm_format_info_min_pitch' filepath='drivers/gpu/drm/drm_fourcc.c' line='404' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_format_info_min_pitch'>
+        <parameter type-id='f10b2208' name='info' filepath='drivers/gpu/drm/drm_fourcc.c' line='404' column='1'/>
+        <parameter type-id='95e97e5e' name='plane' filepath='drivers/gpu/drm/drm_fourcc.c' line='405' column='1'/>
+        <parameter type-id='f0981eeb' name='buffer_width' filepath='drivers/gpu/drm/drm_fourcc.c' line='405' column='1'/>
         <return type-id='9c313c2d'/>
       </function-decl>
       <function-decl name='drm_framebuffer_cleanup' mangled-name='drm_framebuffer_cleanup' filepath='drivers/gpu/drm/drm_framebuffer.c' line='942' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_framebuffer_cleanup'>
@@ -129310,8 +129990,8 @@
         <parameter type-id='abd62a96' name='obj' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='119' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_gem_shmem_get_sg_table' mangled-name='drm_gem_shmem_get_sg_table' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='675' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_gem_shmem_get_sg_table'>
-        <parameter type-id='abd62a96' name='obj' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='675' column='1'/>
+      <function-decl name='drm_gem_shmem_get_sg_table' mangled-name='drm_gem_shmem_get_sg_table' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='678' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_gem_shmem_get_sg_table'>
+        <parameter type-id='abd62a96' name='obj' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='678' column='1'/>
         <return type-id='4adb0e6a'/>
       </function-decl>
       <function-decl name='drm_gem_shmem_mmap' mangled-name='drm_gem_shmem_mmap' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='611' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_gem_shmem_mmap'>
@@ -129323,10 +130003,10 @@
         <parameter type-id='abd62a96' name='obj' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='234' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_gem_shmem_print_info' mangled-name='drm_gem_shmem_print_info' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='648' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_gem_shmem_print_info'>
-        <parameter type-id='7ac48c21' name='p' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='648' column='1'/>
-        <parameter type-id='f0981eeb' name='indent' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='648' column='1'/>
-        <parameter type-id='e8a41089' name='obj' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='649' column='1'/>
+      <function-decl name='drm_gem_shmem_print_info' mangled-name='drm_gem_shmem_print_info' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='651' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_gem_shmem_print_info'>
+        <parameter type-id='7ac48c21' name='p' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='651' column='1'/>
+        <parameter type-id='f0981eeb' name='indent' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='651' column='1'/>
+        <parameter type-id='e8a41089' name='obj' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='652' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='drm_gem_shmem_unpin' mangled-name='drm_gem_shmem_unpin' filepath='drivers/gpu/drm/drm_gem_shmem_helper.c' line='251' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_gem_shmem_unpin'>
@@ -129362,8 +130042,8 @@
         <parameter type-id='2ae08426' name='vma' filepath='drivers/gpu/drm/drm_gem.c' line='1008' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_get_connector_status_name' mangled-name='drm_get_connector_status_name' filepath='drivers/gpu/drm/drm_connector.c' line='608' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_get_connector_status_name'>
-        <parameter type-id='f7b0e1b4' name='status' filepath='drivers/gpu/drm/drm_connector.c' line='608' column='1'/>
+      <function-decl name='drm_get_connector_status_name' mangled-name='drm_get_connector_status_name' filepath='drivers/gpu/drm/drm_connector.c' line='611' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_get_connector_status_name'>
+        <parameter type-id='f7b0e1b4' name='status' filepath='drivers/gpu/drm/drm_connector.c' line='611' column='1'/>
         <return type-id='80f4b756'/>
       </function-decl>
       <function-decl name='drm_get_connector_type_name' mangled-name='drm_get_connector_type_name' filepath='drivers/gpu/drm/drm_connector.c' line='121' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_get_connector_type_name'>
@@ -129375,9 +130055,9 @@
         <parameter type-id='b9af02c3' name='adapter' filepath='drivers/gpu/drm/drm_edid.c' line='2057' column='1'/>
         <return type-id='c91d1bf1'/>
       </function-decl>
-      <function-decl name='drm_get_format_info' mangled-name='drm_get_format_info' filepath='drivers/gpu/drm/drm_fourcc.c' line='332' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_get_format_info'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_fourcc.c' line='332' column='1'/>
-        <parameter type-id='92ed24a5' name='mode_cmd' filepath='drivers/gpu/drm/drm_fourcc.c' line='333' column='1'/>
+      <function-decl name='drm_get_format_info' mangled-name='drm_get_format_info' filepath='drivers/gpu/drm/drm_fourcc.c' line='339' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_get_format_info'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_fourcc.c' line='339' column='1'/>
+        <parameter type-id='92ed24a5' name='mode_cmd' filepath='drivers/gpu/drm/drm_fourcc.c' line='340' column='1'/>
         <return type-id='f10b2208'/>
       </function-decl>
       <function-decl name='drm_get_format_name' mangled-name='drm_get_format_name' filepath='drivers/gpu/drm/drm_fourcc.c' line='138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_get_format_name'>
@@ -129401,22 +130081,22 @@
         <parameter type-id='91ce1af9' name='val' filepath='drivers/gpu/drm/drm_hdcp.c' line='410' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_hdmi_avi_infoframe_colorspace' mangled-name='drm_hdmi_avi_infoframe_colorspace' filepath='drivers/gpu/drm/drm_edid.c' line='5714' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_hdmi_avi_infoframe_colorspace'>
-        <parameter type-id='19ddc3a6' name='frame' filepath='drivers/gpu/drm/drm_edid.c' line='5714' column='1'/>
-        <parameter type-id='c9ecdb13' name='conn_state' filepath='drivers/gpu/drm/drm_edid.c' line='5715' column='1'/>
+      <function-decl name='drm_hdmi_avi_infoframe_colorspace' mangled-name='drm_hdmi_avi_infoframe_colorspace' filepath='drivers/gpu/drm/drm_edid.c' line='5717' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_hdmi_avi_infoframe_colorspace'>
+        <parameter type-id='19ddc3a6' name='frame' filepath='drivers/gpu/drm/drm_edid.c' line='5717' column='1'/>
+        <parameter type-id='c9ecdb13' name='conn_state' filepath='drivers/gpu/drm/drm_edid.c' line='5718' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_hdmi_avi_infoframe_from_display_mode' mangled-name='drm_hdmi_avi_infoframe_from_display_mode' filepath='drivers/gpu/drm/drm_edid.c' line='5597' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_hdmi_avi_infoframe_from_display_mode'>
-        <parameter type-id='19ddc3a6' name='frame' filepath='drivers/gpu/drm/drm_edid.c' line='5597' column='1'/>
-        <parameter type-id='0e1f87e5' name='connector' filepath='drivers/gpu/drm/drm_edid.c' line='5598' column='1'/>
-        <parameter type-id='745b39e8' name='mode' filepath='drivers/gpu/drm/drm_edid.c' line='5599' column='1'/>
+      <function-decl name='drm_hdmi_avi_infoframe_from_display_mode' mangled-name='drm_hdmi_avi_infoframe_from_display_mode' filepath='drivers/gpu/drm/drm_edid.c' line='5600' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_hdmi_avi_infoframe_from_display_mode'>
+        <parameter type-id='19ddc3a6' name='frame' filepath='drivers/gpu/drm/drm_edid.c' line='5600' column='1'/>
+        <parameter type-id='0e1f87e5' name='connector' filepath='drivers/gpu/drm/drm_edid.c' line='5601' column='1'/>
+        <parameter type-id='745b39e8' name='mode' filepath='drivers/gpu/drm/drm_edid.c' line='5602' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_hdmi_avi_infoframe_quant_range' mangled-name='drm_hdmi_avi_infoframe_quant_range' filepath='drivers/gpu/drm/drm_edid.c' line='5744' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_hdmi_avi_infoframe_quant_range'>
-        <parameter type-id='19ddc3a6' name='frame' filepath='drivers/gpu/drm/drm_edid.c' line='5744' column='1'/>
-        <parameter type-id='0e1f87e5' name='connector' filepath='drivers/gpu/drm/drm_edid.c' line='5745' column='1'/>
-        <parameter type-id='745b39e8' name='mode' filepath='drivers/gpu/drm/drm_edid.c' line='5746' column='1'/>
-        <parameter type-id='5c444b2c' name='rgb_quant_range' filepath='drivers/gpu/drm/drm_edid.c' line='5747' column='1'/>
+      <function-decl name='drm_hdmi_avi_infoframe_quant_range' mangled-name='drm_hdmi_avi_infoframe_quant_range' filepath='drivers/gpu/drm/drm_edid.c' line='5747' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_hdmi_avi_infoframe_quant_range'>
+        <parameter type-id='19ddc3a6' name='frame' filepath='drivers/gpu/drm/drm_edid.c' line='5747' column='1'/>
+        <parameter type-id='0e1f87e5' name='connector' filepath='drivers/gpu/drm/drm_edid.c' line='5748' column='1'/>
+        <parameter type-id='745b39e8' name='mode' filepath='drivers/gpu/drm/drm_edid.c' line='5749' column='1'/>
+        <parameter type-id='5c444b2c' name='rgb_quant_range' filepath='drivers/gpu/drm/drm_edid.c' line='5750' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='drm_hdmi_infoframe_set_hdr_metadata' mangled-name='drm_hdmi_infoframe_set_hdr_metadata' filepath='drivers/gpu/drm/drm_edid.c' line='5486' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_hdmi_infoframe_set_hdr_metadata'>
@@ -129424,10 +130104,10 @@
         <parameter type-id='c9ecdb13' name='conn_state' filepath='drivers/gpu/drm/drm_edid.c' line='5487' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_hdmi_vendor_infoframe_from_display_mode' mangled-name='drm_hdmi_vendor_infoframe_from_display_mode' filepath='drivers/gpu/drm/drm_edid.c' line='5848' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_hdmi_vendor_infoframe_from_display_mode'>
-        <parameter type-id='8ba5499a' name='frame' filepath='drivers/gpu/drm/drm_edid.c' line='5848' column='1'/>
-        <parameter type-id='0e1f87e5' name='connector' filepath='drivers/gpu/drm/drm_edid.c' line='5849' column='1'/>
-        <parameter type-id='745b39e8' name='mode' filepath='drivers/gpu/drm/drm_edid.c' line='5850' column='1'/>
+      <function-decl name='drm_hdmi_vendor_infoframe_from_display_mode' mangled-name='drm_hdmi_vendor_infoframe_from_display_mode' filepath='drivers/gpu/drm/drm_edid.c' line='5851' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_hdmi_vendor_infoframe_from_display_mode'>
+        <parameter type-id='8ba5499a' name='frame' filepath='drivers/gpu/drm/drm_edid.c' line='5851' column='1'/>
+        <parameter type-id='0e1f87e5' name='connector' filepath='drivers/gpu/drm/drm_edid.c' line='5852' column='1'/>
+        <parameter type-id='745b39e8' name='mode' filepath='drivers/gpu/drm/drm_edid.c' line='5853' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='drm_helper_connector_dpms' mangled-name='drm_helper_connector_dpms' filepath='drivers/gpu/drm/drm_crtc_helper.c' line='867' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_helper_connector_dpms'>
@@ -129443,8 +130123,8 @@
         <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_crtc_helper.c' line='1002' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_helper_hpd_irq_event' mangled-name='drm_helper_hpd_irq_event' filepath='drivers/gpu/drm/drm_probe_helper.c' line='820' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_helper_hpd_irq_event'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_probe_helper.c' line='820' column='1'/>
+      <function-decl name='drm_helper_hpd_irq_event' mangled-name='drm_helper_hpd_irq_event' filepath='drivers/gpu/drm/drm_probe_helper.c' line='821' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_helper_hpd_irq_event'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_probe_helper.c' line='821' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='drm_helper_mode_fill_fb_struct' mangled-name='drm_helper_mode_fill_fb_struct' filepath='drivers/gpu/drm/drm_modeset_helper.c' line='79' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_helper_mode_fill_fb_struct'>
@@ -129488,27 +130168,27 @@
         <parameter type-id='9e99ecc1' name='fpriv' filepath='drivers/gpu/drm/drm_auth.c' line='355' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='drm_kms_helper_hotplug_event' mangled-name='drm_kms_helper_hotplug_event' filepath='drivers/gpu/drm/drm_probe_helper.c' line='607' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_kms_helper_hotplug_event'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_probe_helper.c' line='607' column='1'/>
+      <function-decl name='drm_kms_helper_hotplug_event' mangled-name='drm_kms_helper_hotplug_event' filepath='drivers/gpu/drm/drm_probe_helper.c' line='608' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_kms_helper_hotplug_event'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_probe_helper.c' line='608' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_kms_helper_is_poll_worker' mangled-name='drm_kms_helper_is_poll_worker' filepath='drivers/gpu/drm/drm_probe_helper.c' line='725' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_kms_helper_is_poll_worker'>
+      <function-decl name='drm_kms_helper_is_poll_worker' mangled-name='drm_kms_helper_is_poll_worker' filepath='drivers/gpu/drm/drm_probe_helper.c' line='726' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_kms_helper_is_poll_worker'>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='drm_kms_helper_poll_disable' mangled-name='drm_kms_helper_poll_disable' filepath='drivers/gpu/drm/drm_probe_helper.c' line='747' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_kms_helper_poll_disable'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_probe_helper.c' line='747' column='1'/>
+      <function-decl name='drm_kms_helper_poll_disable' mangled-name='drm_kms_helper_poll_disable' filepath='drivers/gpu/drm/drm_probe_helper.c' line='748' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_kms_helper_poll_disable'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_probe_helper.c' line='748' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='drm_kms_helper_poll_enable' mangled-name='drm_kms_helper_poll_enable' filepath='drivers/gpu/drm/drm_probe_helper.c' line='242' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_kms_helper_poll_enable'>
         <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_probe_helper.c' line='242' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_kms_helper_poll_fini' mangled-name='drm_kms_helper_poll_fini' filepath='drivers/gpu/drm/drm_probe_helper.c' line='787' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_kms_helper_poll_fini'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_probe_helper.c' line='787' column='1'/>
+      <function-decl name='drm_kms_helper_poll_fini' mangled-name='drm_kms_helper_poll_fini' filepath='drivers/gpu/drm/drm_probe_helper.c' line='788' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_kms_helper_poll_fini'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_probe_helper.c' line='788' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_kms_helper_poll_init' mangled-name='drm_kms_helper_poll_init' filepath='drivers/gpu/drm/drm_probe_helper.c' line='774' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_kms_helper_poll_init'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_probe_helper.c' line='774' column='1'/>
+      <function-decl name='drm_kms_helper_poll_init' mangled-name='drm_kms_helper_poll_init' filepath='drivers/gpu/drm/drm_probe_helper.c' line='775' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_kms_helper_poll_init'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_probe_helper.c' line='775' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='drm_match_cea_mode' mangled-name='drm_match_cea_mode' filepath='drivers/gpu/drm/drm_edid.c' line='3456' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_match_cea_mode'>
@@ -129550,8 +130230,8 @@
         <parameter type-id='0ee978f1' name='mm' filepath='drivers/gpu/drm/drm_mm.c' line='996' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='drm_mode_config_cleanup' mangled-name='drm_mode_config_cleanup' filepath='drivers/gpu/drm/drm_mode_config.c' line='477' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_config_cleanup'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_mode_config.c' line='477' column='1'/>
+      <function-decl name='drm_mode_config_cleanup' mangled-name='drm_mode_config_cleanup' filepath='drivers/gpu/drm/drm_mode_config.c' line='483' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_config_cleanup'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_mode_config.c' line='483' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='drm_mode_config_helper_resume' mangled-name='drm_mode_config_helper_resume' filepath='drivers/gpu/drm/drm_modeset_helper.c' line='231' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_config_helper_resume'>
@@ -129586,27 +130266,27 @@
         <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_modes.c' line='70' column='1'/>
         <return type-id='11e02f83'/>
       </function-decl>
-      <function-decl name='drm_mode_create_dp_colorspace_property' mangled-name='drm_mode_create_dp_colorspace_property' filepath='drivers/gpu/drm/drm_connector.c' line='1864' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_create_dp_colorspace_property'>
-        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='1864' column='1'/>
+      <function-decl name='drm_mode_create_dp_colorspace_property' mangled-name='drm_mode_create_dp_colorspace_property' filepath='drivers/gpu/drm/drm_connector.c' line='1867' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_create_dp_colorspace_property'>
+        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='1867' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_mode_create_hdmi_colorspace_property' mangled-name='drm_mode_create_hdmi_colorspace_property' filepath='drivers/gpu/drm/drm_connector.c' line='1835' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_create_hdmi_colorspace_property'>
-        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='1835' column='1'/>
+      <function-decl name='drm_mode_create_hdmi_colorspace_property' mangled-name='drm_mode_create_hdmi_colorspace_property' filepath='drivers/gpu/drm/drm_connector.c' line='1838' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_create_hdmi_colorspace_property'>
+        <parameter type-id='4db02c58' name='connector' filepath='drivers/gpu/drm/drm_connector.c' line='1838' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_mode_create_scaling_mode_property' mangled-name='drm_mode_create_scaling_mode_property' filepath='drivers/gpu/drm/drm_connector.c' line='1599' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_create_scaling_mode_property'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_connector.c' line='1599' column='1'/>
+      <function-decl name='drm_mode_create_scaling_mode_property' mangled-name='drm_mode_create_scaling_mode_property' filepath='drivers/gpu/drm/drm_connector.c' line='1602' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_create_scaling_mode_property'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_connector.c' line='1602' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_mode_create_tile_group' mangled-name='drm_mode_create_tile_group' filepath='drivers/gpu/drm/drm_connector.c' line='2541' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_create_tile_group'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_connector.c' line='2541' column='1'/>
-        <parameter type-id='80f4b756' name='topology' filepath='drivers/gpu/drm/drm_connector.c' line='2542' column='1'/>
+      <function-decl name='drm_mode_create_tile_group' mangled-name='drm_mode_create_tile_group' filepath='drivers/gpu/drm/drm_connector.c' line='2544' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_create_tile_group'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_connector.c' line='2544' column='1'/>
+        <parameter type-id='80f4b756' name='topology' filepath='drivers/gpu/drm/drm_connector.c' line='2545' column='1'/>
         <return type-id='c6c44b9f'/>
       </function-decl>
-      <function-decl name='drm_mode_create_tv_properties' mangled-name='drm_mode_create_tv_properties' filepath='drivers/gpu/drm/drm_connector.c' line='1504' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_create_tv_properties'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_connector.c' line='1504' column='1'/>
-        <parameter type-id='f0981eeb' name='num_modes' filepath='drivers/gpu/drm/drm_connector.c' line='1505' column='1'/>
-        <parameter type-id='13956559' name='modes' filepath='drivers/gpu/drm/drm_connector.c' line='1506' column='1'/>
+      <function-decl name='drm_mode_create_tv_properties' mangled-name='drm_mode_create_tv_properties' filepath='drivers/gpu/drm/drm_connector.c' line='1507' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_create_tv_properties'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_connector.c' line='1507' column='1'/>
+        <parameter type-id='f0981eeb' name='num_modes' filepath='drivers/gpu/drm/drm_connector.c' line='1508' column='1'/>
+        <parameter type-id='13956559' name='modes' filepath='drivers/gpu/drm/drm_connector.c' line='1509' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='drm_mode_crtc_set_gamma_size' mangled-name='drm_mode_crtc_set_gamma_size' filepath='drivers/gpu/drm/drm_color_mgmt.c' line='205' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_crtc_set_gamma_size'>
@@ -129646,9 +130326,9 @@
         <parameter type-id='b50a4934' name='rb' filepath='drivers/gpu/drm/drm_edid.c' line='2228' column='1'/>
         <return type-id='11e02f83'/>
       </function-decl>
-      <function-decl name='drm_mode_get_tile_group' mangled-name='drm_mode_get_tile_group' filepath='drivers/gpu/drm/drm_connector.c' line='2510' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_get_tile_group'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_connector.c' line='2510' column='1'/>
-        <parameter type-id='80f4b756' name='topology' filepath='drivers/gpu/drm/drm_connector.c' line='2511' column='1'/>
+      <function-decl name='drm_mode_get_tile_group' mangled-name='drm_mode_get_tile_group' filepath='drivers/gpu/drm/drm_connector.c' line='2513' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_get_tile_group'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_connector.c' line='2513' column='1'/>
+        <parameter type-id='80f4b756' name='topology' filepath='drivers/gpu/drm/drm_connector.c' line='2514' column='1'/>
         <return type-id='c6c44b9f'/>
       </function-decl>
       <function-decl name='drm_mode_is_420' mangled-name='drm_mode_is_420' filepath='drivers/gpu/drm/drm_modes.c' line='2071' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_mode_is_420'>
@@ -130155,9 +130835,9 @@
         <parameter type-id='95e97e5e' name='encoder_type' filepath='drivers/gpu/drm/drm_simple_kms_helper.c' line='66' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='drm_state_dump' mangled-name='drm_state_dump' filepath='drivers/gpu/drm/drm_atomic.c' line='1622' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_state_dump'>
-        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic.c' line='1622' column='1'/>
-        <parameter type-id='7ac48c21' name='p' filepath='drivers/gpu/drm/drm_atomic.c' line='1622' column='1'/>
+      <function-decl name='drm_state_dump' mangled-name='drm_state_dump' filepath='drivers/gpu/drm/drm_atomic.c' line='1632' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_state_dump'>
+        <parameter type-id='8898134d' name='dev' filepath='drivers/gpu/drm/drm_atomic.c' line='1632' column='1'/>
+        <parameter type-id='7ac48c21' name='p' filepath='drivers/gpu/drm/drm_atomic.c' line='1632' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='drm_syncobj_add_point' mangled-name='drm_syncobj_add_point' filepath='drivers/gpu/drm/drm_syncobj.c' line='285' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='drm_syncobj_add_point'>
@@ -130306,10 +130986,10 @@
       <function-decl name='dump_stack' mangled-name='dump_stack' filepath='lib/dump_stack.c' line='133' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dump_stack'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='dup_iter' mangled-name='dup_iter' filepath='lib/iov_iter.c' line='1643' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dup_iter'>
-        <parameter type-id='4fa10f9e' name='new' filepath='lib/iov_iter.c' line='1643' column='1'/>
-        <parameter type-id='4fa10f9e' name='old' filepath='lib/iov_iter.c' line='1643' column='1'/>
-        <parameter type-id='3eb7c31c' name='flags' filepath='lib/iov_iter.c' line='1643' column='1'/>
+      <function-decl name='dup_iter' mangled-name='dup_iter' filepath='lib/iov_iter.c' line='1629' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dup_iter'>
+        <parameter type-id='4fa10f9e' name='new' filepath='lib/iov_iter.c' line='1629' column='1'/>
+        <parameter type-id='4fa10f9e' name='old' filepath='lib/iov_iter.c' line='1629' column='1'/>
+        <parameter type-id='3eb7c31c' name='flags' filepath='lib/iov_iter.c' line='1629' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
       <function-decl name='dw_handle_msi_irq' mangled-name='dw_handle_msi_irq' filepath='drivers/pci/controller/dwc/pcie-designware-host.c' line='56' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dw_handle_msi_irq'>
@@ -130403,59 +131083,59 @@
         <parameter type-id='19c2251e' name='val' filepath='drivers/pci/controller/dwc/pcie-designware.c' line='155' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='dwc3_send_gadget_ep_cmd' mangled-name='dwc3_send_gadget_ep_cmd' filepath='drivers/usb/dwc3/gadget.c' line='272' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dwc3_send_gadget_ep_cmd'>
-        <parameter type-id='b31af340' name='dep' filepath='drivers/usb/dwc3/gadget.c' line='272' column='1'/>
-        <parameter type-id='f0981eeb' name='cmd' filepath='drivers/usb/dwc3/gadget.c' line='272' column='1'/>
-        <parameter type-id='f9841541' name='params' filepath='drivers/usb/dwc3/gadget.c' line='273' column='1'/>
+      <function-decl name='dwc3_send_gadget_ep_cmd' mangled-name='dwc3_send_gadget_ep_cmd' filepath='drivers/usb/dwc3/gadget.c' line='273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dwc3_send_gadget_ep_cmd'>
+        <parameter type-id='b31af340' name='dep' filepath='drivers/usb/dwc3/gadget.c' line='273' column='1'/>
+        <parameter type-id='f0981eeb' name='cmd' filepath='drivers/usb/dwc3/gadget.c' line='273' column='1'/>
+        <parameter type-id='f9841541' name='params' filepath='drivers/usb/dwc3/gadget.c' line='274' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='dwc3_stop_active_transfer' mangled-name='dwc3_stop_active_transfer' filepath='drivers/usb/dwc3/gadget.c' line='3672' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dwc3_stop_active_transfer'>
-        <parameter type-id='b31af340' name='dep' filepath='drivers/usb/dwc3/gadget.c' line='3672' column='1'/>
-        <parameter type-id='b50a4934' name='force' filepath='drivers/usb/dwc3/gadget.c' line='3672' column='1'/>
-        <parameter type-id='b50a4934' name='interrupt' filepath='drivers/usb/dwc3/gadget.c' line='3673' column='1'/>
+      <function-decl name='dwc3_stop_active_transfer' mangled-name='dwc3_stop_active_transfer' filepath='drivers/usb/dwc3/gadget.c' line='3743' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dwc3_stop_active_transfer'>
+        <parameter type-id='b31af340' name='dep' filepath='drivers/usb/dwc3/gadget.c' line='3743' column='1'/>
+        <parameter type-id='b50a4934' name='force' filepath='drivers/usb/dwc3/gadget.c' line='3743' column='1'/>
+        <parameter type-id='b50a4934' name='interrupt' filepath='drivers/usb/dwc3/gadget.c' line='3744' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='edac_device_add_device' mangled-name='edac_device_add_device' filepath='drivers/edac/edac_device.c' line='448' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='edac_device_add_device'>
-        <parameter type-id='b7d8b860' name='edac_dev' filepath='drivers/edac/edac_device.c' line='448' column='1'/>
+      <function-decl name='edac_device_add_device' mangled-name='edac_device_add_device' filepath='drivers/edac/edac_device.c' line='450' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='edac_device_add_device'>
+        <parameter type-id='b7d8b860' name='edac_dev' filepath='drivers/edac/edac_device.c' line='450' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='edac_device_alloc_ctl_info' mangled-name='edac_device_alloc_ctl_info' filepath='drivers/edac/edac_device.c' line='50' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='edac_device_alloc_ctl_info'>
-        <parameter type-id='f0981eeb' name='sz_private' filepath='drivers/edac/edac_device.c' line='51' column='1'/>
-        <parameter type-id='26a90f95' name='edac_device_name' filepath='drivers/edac/edac_device.c' line='52' column='1'/>
-        <parameter type-id='f0981eeb' name='nr_instances' filepath='drivers/edac/edac_device.c' line='52' column='1'/>
-        <parameter type-id='26a90f95' name='edac_block_name' filepath='drivers/edac/edac_device.c' line='53' column='1'/>
-        <parameter type-id='f0981eeb' name='nr_blocks' filepath='drivers/edac/edac_device.c' line='53' column='1'/>
-        <parameter type-id='f0981eeb' name='offset_value' filepath='drivers/edac/edac_device.c' line='54' column='1'/>
-        <parameter type-id='b52eac2e' name='attrib_spec' filepath='drivers/edac/edac_device.c' line='55' column='1'/>
-        <parameter type-id='f0981eeb' name='nr_attrib' filepath='drivers/edac/edac_device.c' line='55' column='1'/>
-        <parameter type-id='95e97e5e' name='device_index' filepath='drivers/edac/edac_device.c' line='56' column='1'/>
+      <function-decl name='edac_device_alloc_ctl_info' mangled-name='edac_device_alloc_ctl_info' filepath='drivers/edac/edac_device.c' line='53' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='edac_device_alloc_ctl_info'>
+        <parameter type-id='f0981eeb' name='sz_private' filepath='drivers/edac/edac_device.c' line='54' column='1'/>
+        <parameter type-id='26a90f95' name='edac_device_name' filepath='drivers/edac/edac_device.c' line='55' column='1'/>
+        <parameter type-id='f0981eeb' name='nr_instances' filepath='drivers/edac/edac_device.c' line='55' column='1'/>
+        <parameter type-id='26a90f95' name='edac_block_name' filepath='drivers/edac/edac_device.c' line='56' column='1'/>
+        <parameter type-id='f0981eeb' name='nr_blocks' filepath='drivers/edac/edac_device.c' line='56' column='1'/>
+        <parameter type-id='f0981eeb' name='offset_value' filepath='drivers/edac/edac_device.c' line='57' column='1'/>
+        <parameter type-id='b52eac2e' name='attrib_spec' filepath='drivers/edac/edac_device.c' line='58' column='1'/>
+        <parameter type-id='f0981eeb' name='nr_attrib' filepath='drivers/edac/edac_device.c' line='58' column='1'/>
+        <parameter type-id='95e97e5e' name='device_index' filepath='drivers/edac/edac_device.c' line='59' column='1'/>
         <return type-id='b7d8b860'/>
       </function-decl>
-      <function-decl name='edac_device_alloc_index' mangled-name='edac_device_alloc_index' filepath='drivers/edac/edac_device.c' line='440' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='edac_device_alloc_index'>
+      <function-decl name='edac_device_alloc_index' mangled-name='edac_device_alloc_index' filepath='drivers/edac/edac_device.c' line='442' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='edac_device_alloc_index'>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='edac_device_del_device' mangled-name='edac_device_del_device' filepath='drivers/edac/edac_device.c' line='504' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='edac_device_del_device'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/edac/edac_device.c' line='504' column='1'/>
+      <function-decl name='edac_device_del_device' mangled-name='edac_device_del_device' filepath='drivers/edac/edac_device.c' line='502' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='edac_device_del_device'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/edac/edac_device.c' line='502' column='1'/>
         <return type-id='b7d8b860'/>
       </function-decl>
-      <function-decl name='edac_device_free_ctl_info' mangled-name='edac_device_free_ctl_info' filepath='drivers/edac/edac_device.c' line='229' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='edac_device_free_ctl_info'>
-        <parameter type-id='b7d8b860' name='ctl_info' filepath='drivers/edac/edac_device.c' line='229' column='1'/>
+      <function-decl name='edac_device_free_ctl_info' mangled-name='edac_device_free_ctl_info' filepath='drivers/edac/edac_device.c' line='232' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='edac_device_free_ctl_info'>
+        <parameter type-id='b7d8b860' name='ctl_info' filepath='drivers/edac/edac_device.c' line='232' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='edac_device_handle_ce_count' mangled-name='edac_device_handle_ce_count' filepath='drivers/edac/edac_device.c' line='558' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='edac_device_handle_ce_count'>
-        <parameter type-id='b7d8b860' name='edac_dev' filepath='drivers/edac/edac_device.c' line='558' column='1'/>
-        <parameter type-id='f0981eeb' name='count' filepath='drivers/edac/edac_device.c' line='559' column='1'/>
-        <parameter type-id='95e97e5e' name='inst_nr' filepath='drivers/edac/edac_device.c' line='559' column='1'/>
-        <parameter type-id='95e97e5e' name='block_nr' filepath='drivers/edac/edac_device.c' line='559' column='1'/>
-        <parameter type-id='80f4b756' name='msg' filepath='drivers/edac/edac_device.c' line='560' column='1'/>
+      <function-decl name='edac_device_handle_ce_count' mangled-name='edac_device_handle_ce_count' filepath='drivers/edac/edac_device.c' line='556' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='edac_device_handle_ce_count'>
+        <parameter type-id='b7d8b860' name='edac_dev' filepath='drivers/edac/edac_device.c' line='556' column='1'/>
+        <parameter type-id='f0981eeb' name='count' filepath='drivers/edac/edac_device.c' line='557' column='1'/>
+        <parameter type-id='95e97e5e' name='inst_nr' filepath='drivers/edac/edac_device.c' line='557' column='1'/>
+        <parameter type-id='95e97e5e' name='block_nr' filepath='drivers/edac/edac_device.c' line='557' column='1'/>
+        <parameter type-id='80f4b756' name='msg' filepath='drivers/edac/edac_device.c' line='558' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='edac_device_handle_ue_count' mangled-name='edac_device_handle_ue_count' filepath='drivers/edac/edac_device.c' line='604' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='edac_device_handle_ue_count'>
-        <parameter type-id='b7d8b860' name='edac_dev' filepath='drivers/edac/edac_device.c' line='604' column='1'/>
-        <parameter type-id='f0981eeb' name='count' filepath='drivers/edac/edac_device.c' line='605' column='1'/>
-        <parameter type-id='95e97e5e' name='inst_nr' filepath='drivers/edac/edac_device.c' line='605' column='1'/>
-        <parameter type-id='95e97e5e' name='block_nr' filepath='drivers/edac/edac_device.c' line='605' column='1'/>
-        <parameter type-id='80f4b756' name='msg' filepath='drivers/edac/edac_device.c' line='606' column='1'/>
+      <function-decl name='edac_device_handle_ue_count' mangled-name='edac_device_handle_ue_count' filepath='drivers/edac/edac_device.c' line='602' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='edac_device_handle_ue_count'>
+        <parameter type-id='b7d8b860' name='edac_dev' filepath='drivers/edac/edac_device.c' line='602' column='1'/>
+        <parameter type-id='f0981eeb' name='count' filepath='drivers/edac/edac_device.c' line='603' column='1'/>
+        <parameter type-id='95e97e5e' name='inst_nr' filepath='drivers/edac/edac_device.c' line='603' column='1'/>
+        <parameter type-id='95e97e5e' name='block_nr' filepath='drivers/edac/edac_device.c' line='603' column='1'/>
+        <parameter type-id='80f4b756' name='msg' filepath='drivers/edac/edac_device.c' line='604' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <var-decl name='efi' type-id='f7bdefe9' mangled-name='efi' visibility='default' filepath='drivers/firmware/efi/efi.c' line='37' column='1' elf-symbol-id='efi'/>
@@ -130539,16 +131219,16 @@
         <parameter type-id='4a89adae' name='e' filepath='block/elevator.c' line='556' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='em_cpu_get' mangled-name='em_cpu_get' filepath='kernel/power/energy_model.c' line='241' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='em_cpu_get'>
-        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/power/energy_model.c' line='241' column='1'/>
+      <function-decl name='em_cpu_get' mangled-name='em_cpu_get' filepath='kernel/power/energy_model.c' line='238' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='em_cpu_get'>
+        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/power/energy_model.c' line='238' column='1'/>
         <return type-id='ce714046'/>
       </function-decl>
-      <function-decl name='em_dev_register_perf_domain' mangled-name='em_dev_register_perf_domain' filepath='kernel/power/energy_model.c' line='276' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='em_dev_register_perf_domain'>
-        <parameter type-id='fa0b179b' name='dev' filepath='kernel/power/energy_model.c' line='276' column='1'/>
-        <parameter type-id='f0981eeb' name='nr_states' filepath='kernel/power/energy_model.c' line='276' column='1'/>
-        <parameter type-id='8ab4431c' name='cb' filepath='kernel/power/energy_model.c' line='277' column='1'/>
-        <parameter type-id='3ca207ec' name='cpus' filepath='kernel/power/energy_model.c' line='277' column='1'/>
-        <parameter type-id='b50a4934' name='milliwatts' filepath='kernel/power/energy_model.c' line='278' column='1'/>
+      <function-decl name='em_dev_register_perf_domain' mangled-name='em_dev_register_perf_domain' filepath='kernel/power/energy_model.c' line='273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='em_dev_register_perf_domain'>
+        <parameter type-id='fa0b179b' name='dev' filepath='kernel/power/energy_model.c' line='273' column='1'/>
+        <parameter type-id='f0981eeb' name='nr_states' filepath='kernel/power/energy_model.c' line='273' column='1'/>
+        <parameter type-id='8ab4431c' name='cb' filepath='kernel/power/energy_model.c' line='274' column='1'/>
+        <parameter type-id='3ca207ec' name='cpus' filepath='kernel/power/energy_model.c' line='274' column='1'/>
+        <parameter type-id='b50a4934' name='milliwatts' filepath='kernel/power/energy_model.c' line='275' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='emergency_restart' mangled-name='emergency_restart' filepath='kernel/reboot.c' line='66' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='emergency_restart'>
@@ -130558,9 +131238,9 @@
         <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='724' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='enable_percpu_irq' mangled-name='enable_percpu_irq' filepath='kernel/irq/manage.c' line='2263' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='enable_percpu_irq'>
-        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2263' column='1'/>
-        <parameter type-id='f0981eeb' name='type' filepath='kernel/irq/manage.c' line='2263' column='1'/>
+      <function-decl name='enable_percpu_irq' mangled-name='enable_percpu_irq' filepath='kernel/irq/manage.c' line='2270' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='enable_percpu_irq'>
+        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2270' column='1'/>
+        <parameter type-id='f0981eeb' name='type' filepath='kernel/irq/manage.c' line='2270' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='end_buffer_read_sync' mangled-name='end_buffer_read_sync' filepath='fs/buffer.c' line='157' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='end_buffer_read_sync'>
@@ -130685,111 +131365,111 @@
         <parameter type-id='3275e929' name='event' filepath='kernel/trace/trace_events_trigger.c' line='57' column='1'/>
         <return type-id='21b4096c'/>
       </function-decl>
-      <function-decl name='eventfd_ctx_fdget' mangled-name='eventfd_ctx_fdget' filepath='fs/eventfd.c' line='370' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='eventfd_ctx_fdget'>
-        <parameter type-id='95e97e5e' name='fd' filepath='fs/eventfd.c' line='370' column='1'/>
+      <function-decl name='eventfd_ctx_fdget' mangled-name='eventfd_ctx_fdget' filepath='fs/eventfd.c' line='375' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='eventfd_ctx_fdget'>
+        <parameter type-id='95e97e5e' name='fd' filepath='fs/eventfd.c' line='375' column='1'/>
         <return type-id='71f2e203'/>
       </function-decl>
-      <function-decl name='eventfd_ctx_fileget' mangled-name='eventfd_ctx_fileget' filepath='fs/eventfd.c' line='391' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='eventfd_ctx_fileget'>
-        <parameter type-id='77e79a4b' name='file' filepath='fs/eventfd.c' line='391' column='1'/>
+      <function-decl name='eventfd_ctx_fileget' mangled-name='eventfd_ctx_fileget' filepath='fs/eventfd.c' line='396' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='eventfd_ctx_fileget'>
+        <parameter type-id='77e79a4b' name='file' filepath='fs/eventfd.c' line='396' column='1'/>
         <return type-id='71f2e203'/>
       </function-decl>
-      <function-decl name='eventfd_ctx_put' mangled-name='eventfd_ctx_put' filepath='fs/eventfd.c' line='112' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='eventfd_ctx_put'>
-        <parameter type-id='71f2e203' name='ctx' filepath='fs/eventfd.c' line='112' column='1'/>
+      <function-decl name='eventfd_ctx_put' mangled-name='eventfd_ctx_put' filepath='fs/eventfd.c' line='117' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='eventfd_ctx_put'>
+        <parameter type-id='71f2e203' name='ctx' filepath='fs/eventfd.c' line='117' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='eventfd_ctx_remove_wait_queue' mangled-name='eventfd_ctx_remove_wait_queue' filepath='fs/eventfd.c' line='204' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='eventfd_ctx_remove_wait_queue'>
-        <parameter type-id='71f2e203' name='ctx' filepath='fs/eventfd.c' line='204' column='1'/>
-        <parameter type-id='ba9aa326' name='wait' filepath='fs/eventfd.c' line='204' column='1'/>
-        <parameter type-id='30dcd536' name='cnt' filepath='fs/eventfd.c' line='205' column='1'/>
+      <function-decl name='eventfd_ctx_remove_wait_queue' mangled-name='eventfd_ctx_remove_wait_queue' filepath='fs/eventfd.c' line='209' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='eventfd_ctx_remove_wait_queue'>
+        <parameter type-id='71f2e203' name='ctx' filepath='fs/eventfd.c' line='209' column='1'/>
+        <parameter type-id='ba9aa326' name='wait' filepath='fs/eventfd.c' line='209' column='1'/>
+        <parameter type-id='30dcd536' name='cnt' filepath='fs/eventfd.c' line='210' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='eventfd_signal' mangled-name='eventfd_signal' filepath='fs/eventfd.c' line='62' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='eventfd_signal'>
-        <parameter type-id='71f2e203' name='ctx' filepath='fs/eventfd.c' line='62' column='1'/>
-        <parameter type-id='d3130597' name='n' filepath='fs/eventfd.c' line='62' column='1'/>
+      <function-decl name='eventfd_signal' mangled-name='eventfd_signal' filepath='fs/eventfd.c' line='90' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='eventfd_signal'>
+        <parameter type-id='71f2e203' name='ctx' filepath='fs/eventfd.c' line='90' column='1'/>
+        <parameter type-id='d3130597' name='n' filepath='fs/eventfd.c' line='90' column='1'/>
         <return type-id='d3130597'/>
       </function-decl>
       <function-decl name='evict_inodes' mangled-name='evict_inodes' filepath='fs/inode.c' line='626' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='evict_inodes'>
         <parameter type-id='42c8f564' name='sb' filepath='fs/inode.c' line='626' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='extcon_find_edev_by_node' mangled-name='extcon_find_edev_by_node' filepath='drivers/extcon/extcon.c' line='1342' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_find_edev_by_node'>
-        <parameter type-id='9a537bbe' name='node' filepath='drivers/extcon/extcon.c' line='1342' column='1'/>
+      <function-decl name='extcon_find_edev_by_node' mangled-name='extcon_find_edev_by_node' filepath='drivers/extcon/extcon.c' line='1350' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_find_edev_by_node'>
+        <parameter type-id='9a537bbe' name='node' filepath='drivers/extcon/extcon.c' line='1350' column='1'/>
         <return type-id='c0d6fada'/>
       </function-decl>
-      <function-decl name='extcon_get_edev_by_phandle' mangled-name='extcon_get_edev_by_phandle' filepath='drivers/extcon/extcon.c' line='1364' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_get_edev_by_phandle'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/extcon/extcon.c' line='1364' column='1'/>
-        <parameter type-id='95e97e5e' name='index' filepath='drivers/extcon/extcon.c' line='1364' column='1'/>
+      <function-decl name='extcon_get_edev_by_phandle' mangled-name='extcon_get_edev_by_phandle' filepath='drivers/extcon/extcon.c' line='1372' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_get_edev_by_phandle'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/extcon/extcon.c' line='1372' column='1'/>
+        <parameter type-id='95e97e5e' name='index' filepath='drivers/extcon/extcon.c' line='1372' column='1'/>
         <return type-id='c0d6fada'/>
       </function-decl>
-      <function-decl name='extcon_get_edev_name' mangled-name='extcon_get_edev_name' filepath='drivers/extcon/extcon.c' line='1411' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_get_edev_name'>
-        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='1411' column='1'/>
+      <function-decl name='extcon_get_edev_name' mangled-name='extcon_get_edev_name' filepath='drivers/extcon/extcon.c' line='1419' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_get_edev_name'>
+        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='1419' column='1'/>
         <return type-id='80f4b756'/>
       </function-decl>
-      <function-decl name='extcon_get_extcon_dev' mangled-name='extcon_get_extcon_dev' filepath='drivers/extcon/extcon.c' line='867' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_get_extcon_dev'>
-        <parameter type-id='80f4b756' name='extcon_name' filepath='drivers/extcon/extcon.c' line='867' column='1'/>
+      <function-decl name='extcon_get_extcon_dev' mangled-name='extcon_get_extcon_dev' filepath='drivers/extcon/extcon.c' line='875' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_get_extcon_dev'>
+        <parameter type-id='80f4b756' name='extcon_name' filepath='drivers/extcon/extcon.c' line='875' column='1'/>
         <return type-id='c0d6fada'/>
       </function-decl>
-      <function-decl name='extcon_get_property' mangled-name='extcon_get_property' filepath='drivers/extcon/extcon.c' line='615' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_get_property'>
-        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='615' column='1'/>
-        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='615' column='1'/>
-        <parameter type-id='f0981eeb' name='prop' filepath='drivers/extcon/extcon.c' line='616' column='1'/>
-        <parameter type-id='50842338' name='prop_val' filepath='drivers/extcon/extcon.c' line='617' column='1'/>
+      <function-decl name='extcon_get_property' mangled-name='extcon_get_property' filepath='drivers/extcon/extcon.c' line='623' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_get_property'>
+        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='623' column='1'/>
+        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='623' column='1'/>
+        <parameter type-id='f0981eeb' name='prop' filepath='drivers/extcon/extcon.c' line='624' column='1'/>
+        <parameter type-id='50842338' name='prop_val' filepath='drivers/extcon/extcon.c' line='625' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='extcon_get_property_capability' mangled-name='extcon_get_property_capability' filepath='drivers/extcon/extcon.c' line='782' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_get_property_capability'>
-        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='782' column='1'/>
-        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='782' column='1'/>
-        <parameter type-id='f0981eeb' name='prop' filepath='drivers/extcon/extcon.c' line='783' column='1'/>
+      <function-decl name='extcon_get_property_capability' mangled-name='extcon_get_property_capability' filepath='drivers/extcon/extcon.c' line='790' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_get_property_capability'>
+        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='790' column='1'/>
+        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='790' column='1'/>
+        <parameter type-id='f0981eeb' name='prop' filepath='drivers/extcon/extcon.c' line='791' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='extcon_get_state' mangled-name='extcon_get_state' filepath='drivers/extcon/extcon.c' line='489' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_get_state'>
-        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='489' column='1'/>
-        <parameter type-id='20f5f452' name='id' filepath='drivers/extcon/extcon.c' line='489' column='1'/>
+      <function-decl name='extcon_get_state' mangled-name='extcon_get_state' filepath='drivers/extcon/extcon.c' line='497' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_get_state'>
+        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='497' column='1'/>
+        <parameter type-id='20f5f452' name='id' filepath='drivers/extcon/extcon.c' line='497' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='extcon_register_notifier' mangled-name='extcon_register_notifier' filepath='drivers/extcon/extcon.c' line='899' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_register_notifier'>
-        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='899' column='1'/>
-        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='899' column='1'/>
-        <parameter type-id='d504f73d' name='nb' filepath='drivers/extcon/extcon.c' line='900' column='1'/>
+      <function-decl name='extcon_register_notifier' mangled-name='extcon_register_notifier' filepath='drivers/extcon/extcon.c' line='907' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_register_notifier'>
+        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='907' column='1'/>
+        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='907' column='1'/>
+        <parameter type-id='d504f73d' name='nb' filepath='drivers/extcon/extcon.c' line='908' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='extcon_set_property' mangled-name='extcon_set_property' filepath='drivers/extcon/extcon.c' line='694' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_set_property'>
-        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='694' column='1'/>
-        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='694' column='1'/>
-        <parameter type-id='f0981eeb' name='prop' filepath='drivers/extcon/extcon.c' line='695' column='1'/>
-        <parameter type-id='282b2805' name='prop_val' filepath='drivers/extcon/extcon.c' line='696' column='1'/>
+      <function-decl name='extcon_set_property' mangled-name='extcon_set_property' filepath='drivers/extcon/extcon.c' line='702' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_set_property'>
+        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='702' column='1'/>
+        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='702' column='1'/>
+        <parameter type-id='f0981eeb' name='prop' filepath='drivers/extcon/extcon.c' line='703' column='1'/>
+        <parameter type-id='282b2805' name='prop_val' filepath='drivers/extcon/extcon.c' line='704' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='extcon_set_property_capability' mangled-name='extcon_set_property_capability' filepath='drivers/extcon/extcon.c' line='816' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_set_property_capability'>
-        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='816' column='1'/>
-        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='816' column='1'/>
-        <parameter type-id='f0981eeb' name='prop' filepath='drivers/extcon/extcon.c' line='817' column='1'/>
+      <function-decl name='extcon_set_property_capability' mangled-name='extcon_set_property_capability' filepath='drivers/extcon/extcon.c' line='824' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_set_property_capability'>
+        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='824' column='1'/>
+        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='824' column='1'/>
+        <parameter type-id='f0981eeb' name='prop' filepath='drivers/extcon/extcon.c' line='825' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='extcon_set_state' mangled-name='extcon_set_state' filepath='drivers/extcon/extcon.c' line='522' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_set_state'>
-        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='522' column='1'/>
-        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='522' column='1'/>
-        <parameter type-id='b50a4934' name='state' filepath='drivers/extcon/extcon.c' line='522' column='1'/>
+      <function-decl name='extcon_set_state' mangled-name='extcon_set_state' filepath='drivers/extcon/extcon.c' line='530' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_set_state'>
+        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='530' column='1'/>
+        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='530' column='1'/>
+        <parameter type-id='b50a4934' name='state' filepath='drivers/extcon/extcon.c' line='530' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='extcon_set_state_sync' mangled-name='extcon_set_state_sync' filepath='drivers/extcon/extcon.c' line='577' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_set_state_sync'>
-        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='577' column='1'/>
-        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='577' column='1'/>
-        <parameter type-id='b50a4934' name='state' filepath='drivers/extcon/extcon.c' line='577' column='1'/>
+      <function-decl name='extcon_set_state_sync' mangled-name='extcon_set_state_sync' filepath='drivers/extcon/extcon.c' line='585' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_set_state_sync'>
+        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='585' column='1'/>
+        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='585' column='1'/>
+        <parameter type-id='b50a4934' name='state' filepath='drivers/extcon/extcon.c' line='585' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='extcon_sync' mangled-name='extcon_sync' filepath='drivers/extcon/extcon.c' line='408' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_sync'>
-        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='408' column='1'/>
-        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='408' column='1'/>
+      <function-decl name='extcon_sync' mangled-name='extcon_sync' filepath='drivers/extcon/extcon.c' line='416' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_sync'>
+        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='416' column='1'/>
+        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='416' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='extcon_unregister_notifier' mangled-name='extcon_unregister_notifier' filepath='drivers/extcon/extcon.c' line='928' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_unregister_notifier'>
-        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='928' column='1'/>
-        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='928' column='1'/>
-        <parameter type-id='d504f73d' name='nb' filepath='drivers/extcon/extcon.c' line='929' column='1'/>
+      <function-decl name='extcon_unregister_notifier' mangled-name='extcon_unregister_notifier' filepath='drivers/extcon/extcon.c' line='936' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='extcon_unregister_notifier'>
+        <parameter type-id='c0d6fada' name='edev' filepath='drivers/extcon/extcon.c' line='936' column='1'/>
+        <parameter type-id='f0981eeb' name='id' filepath='drivers/extcon/extcon.c' line='936' column='1'/>
+        <parameter type-id='d504f73d' name='nb' filepath='drivers/extcon/extcon.c' line='937' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <var-decl name='failure_tracking' type-id='49a0ad34' mangled-name='failure_tracking' visibility='default' filepath='mm/page_pinner.c' line='61' column='1' elf-symbol-id='failure_tracking'/>
+      <var-decl name='failure_tracking' type-id='49a0ad34' mangled-name='failure_tracking' visibility='default' filepath='mm/page_pinner.c' line='62' column='1' elf-symbol-id='failure_tracking'/>
       <function-decl name='fasync_helper' mangled-name='fasync_helper' filepath='fs/fcntl.c' line='990' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fasync_helper'>
         <parameter type-id='95e97e5e' name='fd' filepath='fs/fcntl.c' line='990' column='1'/>
         <parameter type-id='77e79a4b' name='filp' filepath='fs/fcntl.c' line='990' column='1'/>
@@ -130802,13 +131482,13 @@
         <parameter type-id='9b23c9ad' name='option' filepath='drivers/video/fbdev/core/fb_cmdline.c' line='35' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='fd_install' mangled-name='fd_install' filepath='fs/file.c' line='662' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fd_install'>
-        <parameter type-id='f0981eeb' name='fd' filepath='fs/file.c' line='662' column='1'/>
-        <parameter type-id='77e79a4b' name='file' filepath='fs/file.c' line='662' column='1'/>
+      <function-decl name='fd_install' mangled-name='fd_install' filepath='fs/file.c' line='664' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fd_install'>
+        <parameter type-id='f0981eeb' name='fd' filepath='fs/file.c' line='664' column='1'/>
+        <parameter type-id='77e79a4b' name='file' filepath='fs/file.c' line='664' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='fget' mangled-name='fget' filepath='fs/file.c' line='927' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fget'>
-        <parameter type-id='f0981eeb' name='fd' filepath='fs/file.c' line='927' column='1'/>
+      <function-decl name='fget' mangled-name='fget' filepath='fs/file.c' line='942' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fget'>
+        <parameter type-id='f0981eeb' name='fd' filepath='fs/file.c' line='942' column='1'/>
         <return type-id='77e79a4b'/>
       </function-decl>
       <function-decl name='fiemap_fill_next_extent' mangled-name='fiemap_fill_next_extent' filepath='fs/ioctl.c' line='112' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fiemap_fill_next_extent'>
@@ -130838,12 +131518,12 @@
         <parameter type-id='f57039f0' name='mapping' filepath='mm/readahead.c' line='35' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='file_remove_privs' mangled-name='file_remove_privs' filepath='fs/inode.c' line='1925' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='file_remove_privs'>
-        <parameter type-id='77e79a4b' name='file' filepath='fs/inode.c' line='1925' column='1'/>
+      <function-decl name='file_remove_privs' mangled-name='file_remove_privs' filepath='fs/inode.c' line='1938' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='file_remove_privs'>
+        <parameter type-id='77e79a4b' name='file' filepath='fs/inode.c' line='1938' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='file_update_time' mangled-name='file_update_time' filepath='fs/inode.c' line='1966' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='file_update_time'>
-        <parameter type-id='77e79a4b' name='file' filepath='fs/inode.c' line='1966' column='1'/>
+      <function-decl name='file_update_time' mangled-name='file_update_time' filepath='fs/inode.c' line='1979' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='file_update_time'>
+        <parameter type-id='77e79a4b' name='file' filepath='fs/inode.c' line='1979' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='file_write_and_wait_range' mangled-name='file_write_and_wait_range' filepath='mm/filemap.c' line='760' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='file_write_and_wait_range'>
@@ -130852,15 +131532,15 @@
         <parameter type-id='69bf7bee' name='lend' filepath='mm/filemap.c' line='760' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='filemap_allow_speculation' mangled-name='filemap_allow_speculation' filepath='mm/filemap.c' line='2999' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='filemap_allow_speculation'>
+      <function-decl name='filemap_allow_speculation' mangled-name='filemap_allow_speculation' filepath='mm/filemap.c' line='3006' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='filemap_allow_speculation'>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='filemap_check_errors' mangled-name='filemap_check_errors' filepath='mm/filemap.c' line='370' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='filemap_check_errors'>
         <parameter type-id='f57039f0' name='mapping' filepath='mm/filemap.c' line='370' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='filemap_fault' mangled-name='filemap_fault' filepath='mm/filemap.c' line='2723' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='filemap_fault'>
-        <parameter type-id='d02f4143' name='vmf' filepath='mm/filemap.c' line='2723' column='1'/>
+      <function-decl name='filemap_fault' mangled-name='filemap_fault' filepath='mm/filemap.c' line='2725' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='filemap_fault'>
+        <parameter type-id='d02f4143' name='vmf' filepath='mm/filemap.c' line='2725' column='1'/>
         <return type-id='e9265215'/>
       </function-decl>
       <function-decl name='filemap_fdatawait_range' mangled-name='filemap_fdatawait_range' filepath='mm/filemap.c' line='556' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='filemap_fdatawait_range'>
@@ -130877,10 +131557,10 @@
         <parameter type-id='f57039f0' name='mapping' filepath='mm/filemap.c' line='460' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='filemap_map_pages' mangled-name='filemap_map_pages' filepath='mm/filemap.c' line='3006' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='filemap_map_pages'>
-        <parameter type-id='d02f4143' name='vmf' filepath='mm/filemap.c' line='3006' column='1'/>
-        <parameter type-id='7359adad' name='start_pgoff' filepath='mm/filemap.c' line='3007' column='1'/>
-        <parameter type-id='7359adad' name='end_pgoff' filepath='mm/filemap.c' line='3007' column='1'/>
+      <function-decl name='filemap_map_pages' mangled-name='filemap_map_pages' filepath='mm/filemap.c' line='3013' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='filemap_map_pages'>
+        <parameter type-id='d02f4143' name='vmf' filepath='mm/filemap.c' line='3013' column='1'/>
+        <parameter type-id='7359adad' name='start_pgoff' filepath='mm/filemap.c' line='3014' column='1'/>
+        <parameter type-id='7359adad' name='end_pgoff' filepath='mm/filemap.c' line='3014' column='1'/>
         <return type-id='e9265215'/>
       </function-decl>
       <function-decl name='filemap_write_and_wait_range' mangled-name='filemap_write_and_wait_range' filepath='mm/filemap.c' line='654' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='filemap_write_and_wait_range'>
@@ -130889,21 +131569,21 @@
         <parameter type-id='69bf7bee' name='lend' filepath='mm/filemap.c' line='655' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='filp_close' mangled-name='filp_close' filepath='fs/open.c' line='1309' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='filp_close'>
-        <parameter type-id='77e79a4b' name='filp' filepath='fs/open.c' line='1309' column='1'/>
-        <parameter type-id='bc5666d5' name='id' filepath='fs/open.c' line='1309' column='1'/>
+      <function-decl name='filp_close' mangled-name='filp_close' filepath='fs/open.c' line='1315' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='filp_close'>
+        <parameter type-id='77e79a4b' name='filp' filepath='fs/open.c' line='1315' column='1'/>
+        <parameter type-id='bc5666d5' name='id' filepath='fs/open.c' line='1315' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='filp_open' mangled-name='filp_open' filepath='fs/open.c' line='1150' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='filp_open'>
-        <parameter type-id='80f4b756' name='filename' filepath='fs/open.c' line='1150' column='1'/>
-        <parameter type-id='95e97e5e' name='flags' filepath='fs/open.c' line='1150' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/open.c' line='1150' column='1'/>
+      <function-decl name='filp_open' mangled-name='filp_open' filepath='fs/open.c' line='1156' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='filp_open'>
+        <parameter type-id='80f4b756' name='filename' filepath='fs/open.c' line='1156' column='1'/>
+        <parameter type-id='95e97e5e' name='flags' filepath='fs/open.c' line='1156' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/open.c' line='1156' column='1'/>
         <return type-id='77e79a4b'/>
       </function-decl>
-      <function-decl name='filp_open_block' mangled-name='filp_open_block' filepath='fs/open.c' line='1164' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='filp_open_block'>
-        <parameter type-id='80f4b756' name='filename' filepath='fs/open.c' line='1164' column='1'/>
-        <parameter type-id='95e97e5e' name='flags' filepath='fs/open.c' line='1164' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/open.c' line='1164' column='1'/>
+      <function-decl name='filp_open_block' mangled-name='filp_open_block' filepath='fs/open.c' line='1170' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='filp_open_block'>
+        <parameter type-id='80f4b756' name='filename' filepath='fs/open.c' line='1170' column='1'/>
+        <parameter type-id='95e97e5e' name='flags' filepath='fs/open.c' line='1170' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/open.c' line='1170' column='1'/>
         <return type-id='77e79a4b'/>
       </function-decl>
       <function-decl name='find_extend_vma' mangled-name='find_extend_vma' filepath='mm/mmap.c' line='2729' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='find_extend_vma'>
@@ -130915,11 +131595,11 @@
         <parameter type-id='587f89d2' name='nr' filepath='kernel/pid.c' line='461' column='1'/>
         <return type-id='b94e5398'/>
       </function-decl>
-      <function-decl name='find_inode_nowait' mangled-name='find_inode_nowait' filepath='fs/inode.c' line='1430' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='find_inode_nowait'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/inode.c' line='1430' column='1'/>
-        <parameter type-id='7359adad' name='hashval' filepath='fs/inode.c' line='1431' column='1'/>
-        <parameter type-id='16e253c0' name='match' filepath='fs/inode.c' line='1432' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='fs/inode.c' line='1434' column='1'/>
+      <function-decl name='find_inode_nowait' mangled-name='find_inode_nowait' filepath='fs/inode.c' line='1472' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='find_inode_nowait'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/inode.c' line='1472' column='1'/>
+        <parameter type-id='7359adad' name='hashval' filepath='fs/inode.c' line='1473' column='1'/>
+        <parameter type-id='16e253c0' name='match' filepath='fs/inode.c' line='1474' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='fs/inode.c' line='1476' column='1'/>
         <return type-id='7e666abe'/>
       </function-decl>
       <function-decl name='find_last_bit' mangled-name='find_last_bit' filepath='lib/find_bit.c' line='140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='find_last_bit'>
@@ -131029,26 +131709,26 @@
       <function-decl name='flush_delayed_fput' mangled-name='flush_delayed_fput' filepath='fs/file_table.c' line='327' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='flush_delayed_fput'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='flush_delayed_work' mangled-name='flush_delayed_work' filepath='kernel/workqueue.c' line='3210' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='flush_delayed_work'>
-        <parameter type-id='1a7ee447' name='dwork' filepath='kernel/workqueue.c' line='3210' column='1'/>
+      <function-decl name='flush_delayed_work' mangled-name='flush_delayed_work' filepath='kernel/workqueue.c' line='3213' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='flush_delayed_work'>
+        <parameter type-id='1a7ee447' name='dwork' filepath='kernel/workqueue.c' line='3213' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='flush_signals' mangled-name='flush_signals' filepath='kernel/signal.c' line='479' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='flush_signals'>
         <parameter type-id='f23e2572' name='t' filepath='kernel/signal.c' line='479' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='flush_work' mangled-name='flush_work' filepath='kernel/workqueue.c' line='3090' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='flush_work'>
-        <parameter type-id='83c1bde6' name='work' filepath='kernel/workqueue.c' line='3090' column='1'/>
+      <function-decl name='flush_work' mangled-name='flush_work' filepath='kernel/workqueue.c' line='3093' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='flush_work'>
+        <parameter type-id='83c1bde6' name='work' filepath='kernel/workqueue.c' line='3093' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='flush_workqueue' mangled-name='flush_workqueue' filepath='kernel/workqueue.c' line='2795' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='flush_workqueue'>
-        <parameter type-id='242e3d19' name='wq' filepath='kernel/workqueue.c' line='2795' column='1'/>
+      <function-decl name='flush_workqueue' mangled-name='flush_workqueue' filepath='kernel/workqueue.c' line='2798' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='flush_workqueue'>
+        <parameter type-id='242e3d19' name='wq' filepath='kernel/workqueue.c' line='2798' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='follow_pfn' mangled-name='follow_pfn' filepath='mm/memory.c' line='5480' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='follow_pfn'>
-        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='5480' column='1'/>
-        <parameter type-id='7359adad' name='address' filepath='mm/memory.c' line='5480' column='1'/>
-        <parameter type-id='1d2c2b85' name='pfn' filepath='mm/memory.c' line='5481' column='1'/>
+      <function-decl name='follow_pfn' mangled-name='follow_pfn' filepath='mm/memory.c' line='5494' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='follow_pfn'>
+        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='5494' column='1'/>
+        <parameter type-id='7359adad' name='address' filepath='mm/memory.c' line='5494' column='1'/>
+        <parameter type-id='1d2c2b85' name='pfn' filepath='mm/memory.c' line='5495' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <var-decl name='font_vga_8x16' type-id='d2d06e23' mangled-name='font_vga_8x16' visibility='default' filepath='lib/fonts/font_8x16.c' line='4625' column='1' elf-symbol-id='font_vga_8x16'/>
@@ -131096,32 +131776,32 @@
         <parameter type-id='7359adad' name='size' filepath='drivers/iommu/iova.c' line='550' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='free_irq' mangled-name='free_irq' filepath='kernel/irq/manage.c' line='1921' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='free_irq'>
-        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='1921' column='1'/>
-        <parameter type-id='eaa32e2f' name='dev_id' filepath='kernel/irq/manage.c' line='1921' column='1'/>
+      <function-decl name='free_irq' mangled-name='free_irq' filepath='kernel/irq/manage.c' line='1922' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='free_irq'>
+        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='1922' column='1'/>
+        <parameter type-id='eaa32e2f' name='dev_id' filepath='kernel/irq/manage.c' line='1922' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='free_netdev' mangled-name='free_netdev' filepath='net/core/dev.c' line='10580' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='free_netdev'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10580' column='1'/>
+      <function-decl name='free_netdev' mangled-name='free_netdev' filepath='net/core/dev.c' line='10585' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='free_netdev'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10585' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='free_pages' mangled-name='free_pages' filepath='mm/page_alloc.c' line='5246' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='free_pages'>
-        <parameter type-id='7359adad' name='addr' filepath='mm/page_alloc.c' line='5246' column='1'/>
-        <parameter type-id='f0981eeb' name='order' filepath='mm/page_alloc.c' line='5246' column='1'/>
+      <function-decl name='free_pages' mangled-name='free_pages' filepath='mm/page_alloc.c' line='5278' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='free_pages'>
+        <parameter type-id='7359adad' name='addr' filepath='mm/page_alloc.c' line='5278' column='1'/>
+        <parameter type-id='f0981eeb' name='order' filepath='mm/page_alloc.c' line='5278' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='free_pages_exact' mangled-name='free_pages_exact' filepath='mm/page_alloc.c' line='5457' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='free_pages_exact'>
-        <parameter type-id='eaa32e2f' name='virt' filepath='mm/page_alloc.c' line='5457' column='1'/>
-        <parameter type-id='b59d7dce' name='size' filepath='mm/page_alloc.c' line='5457' column='1'/>
+      <function-decl name='free_pages_exact' mangled-name='free_pages_exact' filepath='mm/page_alloc.c' line='5489' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='free_pages_exact'>
+        <parameter type-id='eaa32e2f' name='virt' filepath='mm/page_alloc.c' line='5489' column='1'/>
+        <parameter type-id='b59d7dce' name='size' filepath='mm/page_alloc.c' line='5489' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='free_percpu' mangled-name='free_percpu' filepath='mm/percpu.c' line='2080' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='free_percpu'>
         <parameter type-id='eaa32e2f' name='ptr' filepath='mm/percpu.c' line='2080' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='free_percpu_irq' mangled-name='free_percpu_irq' filepath='kernel/irq/manage.c' line='2419' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='free_percpu_irq'>
-        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2419' column='1'/>
-        <parameter type-id='eaa32e2f' name='dev_id' filepath='kernel/irq/manage.c' line='2419' column='1'/>
+      <function-decl name='free_percpu_irq' mangled-name='free_percpu_irq' filepath='kernel/irq/manage.c' line='2426' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='free_percpu_irq'>
+        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2426' column='1'/>
+        <parameter type-id='eaa32e2f' name='dev_id' filepath='kernel/irq/manage.c' line='2426' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='free_uid' mangled-name='free_uid' filepath='kernel/user.c' line='165' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='free_uid'>
@@ -131424,14 +132104,14 @@
         <parameter type-id='b88dd945' name='bdev' filepath='fs/block_dev.c' line='548' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ftrace_dump' mangled-name='ftrace_dump' filepath='kernel/trace/trace.c' line='9360' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ftrace_dump'>
-        <parameter type-id='9be0e7e4' name='oops_dump_mode' filepath='kernel/trace/trace.c' line='9360' column='1'/>
+      <function-decl name='ftrace_dump' mangled-name='ftrace_dump' filepath='kernel/trace/trace.c' line='9383' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ftrace_dump'>
+        <parameter type-id='9be0e7e4' name='oops_dump_mode' filepath='kernel/trace/trace.c' line='9383' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='full_name_hash' mangled-name='full_name_hash' filepath='fs/namei.c' line='2057' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='full_name_hash'>
-        <parameter type-id='eaa32e2f' name='salt' filepath='fs/namei.c' line='2057' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='fs/namei.c' line='2057' column='1'/>
-        <parameter type-id='f0981eeb' name='len' filepath='fs/namei.c' line='2057' column='1'/>
+      <function-decl name='full_name_hash' mangled-name='full_name_hash' filepath='fs/namei.c' line='2067' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='full_name_hash'>
+        <parameter type-id='eaa32e2f' name='salt' filepath='fs/namei.c' line='2067' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='fs/namei.c' line='2067' column='1'/>
+        <parameter type-id='f0981eeb' name='len' filepath='fs/namei.c' line='2067' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
       <function-decl name='fwnode_create_software_node' mangled-name='fwnode_create_software_node' filepath='drivers/base/swnode.c' line='824' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fwnode_create_software_node'>
@@ -131463,12 +132143,12 @@
         <parameter type-id='4a935625' name='child' filepath='drivers/base/property.c' line='722' column='1'/>
         <return type-id='4a935625'/>
       </function-decl>
-      <function-decl name='fwnode_gpiod_get_index' mangled-name='fwnode_gpiod_get_index' filepath='drivers/gpio/gpiolib.c' line='3812' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fwnode_gpiod_get_index'>
-        <parameter type-id='4a935625' name='fwnode' filepath='drivers/gpio/gpiolib.c' line='3812' column='1'/>
-        <parameter type-id='80f4b756' name='con_id' filepath='drivers/gpio/gpiolib.c' line='3813' column='1'/>
-        <parameter type-id='95e97e5e' name='index' filepath='drivers/gpio/gpiolib.c' line='3813' column='1'/>
-        <parameter type-id='38d4936d' name='flags' filepath='drivers/gpio/gpiolib.c' line='3814' column='1'/>
-        <parameter type-id='80f4b756' name='label' filepath='drivers/gpio/gpiolib.c' line='3815' column='1'/>
+      <function-decl name='fwnode_gpiod_get_index' mangled-name='fwnode_gpiod_get_index' filepath='drivers/gpio/gpiolib.c' line='3810' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fwnode_gpiod_get_index'>
+        <parameter type-id='4a935625' name='fwnode' filepath='drivers/gpio/gpiolib.c' line='3810' column='1'/>
+        <parameter type-id='80f4b756' name='con_id' filepath='drivers/gpio/gpiolib.c' line='3811' column='1'/>
+        <parameter type-id='95e97e5e' name='index' filepath='drivers/gpio/gpiolib.c' line='3811' column='1'/>
+        <parameter type-id='38d4936d' name='flags' filepath='drivers/gpio/gpiolib.c' line='3812' column='1'/>
+        <parameter type-id='80f4b756' name='label' filepath='drivers/gpio/gpiolib.c' line='3813' column='1'/>
         <return type-id='26760480'/>
       </function-decl>
       <function-decl name='fwnode_graph_get_next_endpoint' mangled-name='fwnode_graph_get_next_endpoint' filepath='drivers/base/property.c' line='1030' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fwnode_graph_get_next_endpoint'>
@@ -131535,8 +132215,8 @@
         <parameter type-id='b59d7dce' name='nval' filepath='drivers/base/property.c' line='344' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='fwnode_usb_role_switch_get' mangled-name='fwnode_usb_role_switch_get' filepath='drivers/usb/roles/class.c' line='146' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fwnode_usb_role_switch_get'>
-        <parameter type-id='4a935625' name='fwnode' filepath='drivers/usb/roles/class.c' line='146' column='1'/>
+      <function-decl name='fwnode_usb_role_switch_get' mangled-name='fwnode_usb_role_switch_get' filepath='drivers/usb/roles/class.c' line='149' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fwnode_usb_role_switch_get'>
+        <parameter type-id='4a935625' name='fwnode' filepath='drivers/usb/roles/class.c' line='149' column='1'/>
         <return type-id='3e3cd44f'/>
       </function-decl>
       <function-decl name='gcd' mangled-name='gcd' filepath='lib/math/gcd.c' line='23' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gcd'>
@@ -131656,12 +132336,12 @@
         <parameter type-id='cf536864' name='uuid' filepath='lib/uuid.c' line='33' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='generic_delete_inode' mangled-name='generic_delete_inode' filepath='fs/inode.c' line='1599' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_delete_inode'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='1599' column='1'/>
+      <function-decl name='generic_delete_inode' mangled-name='generic_delete_inode' filepath='fs/inode.c' line='1641' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_delete_inode'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='1641' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='generic_device_group' mangled-name='generic_device_group' filepath='drivers/iommu/iommu.c' line='1387' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_device_group'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='1387' column='1'/>
+      <function-decl name='generic_device_group' mangled-name='generic_device_group' filepath='drivers/iommu/iommu.c' line='1403' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_device_group'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='1403' column='1'/>
         <return type-id='0b19fc54'/>
       </function-decl>
       <function-decl name='generic_error_remove_page' mangled-name='generic_error_remove_page' filepath='mm/truncate.c' line='232' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_error_remove_page'>
@@ -131669,25 +132349,25 @@
         <parameter type-id='02f11ed4' name='page' filepath='mm/truncate.c' line='232' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='generic_fh_to_dentry' mangled-name='generic_fh_to_dentry' filepath='fs/libfs.c' line='1004' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_fh_to_dentry'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/libfs.c' line='1004' column='1'/>
-        <parameter type-id='f7d748c2' name='fid' filepath='fs/libfs.c' line='1004' column='1'/>
-        <parameter type-id='95e97e5e' name='fh_len' filepath='fs/libfs.c' line='1005' column='1'/>
-        <parameter type-id='95e97e5e' name='fh_type' filepath='fs/libfs.c' line='1005' column='1'/>
-        <parameter type-id='14a7c87f' name='get_inode' filepath='fs/libfs.c' line='1005' column='1'/>
+      <function-decl name='generic_fh_to_dentry' mangled-name='generic_fh_to_dentry' filepath='fs/libfs.c' line='1020' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_fh_to_dentry'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/libfs.c' line='1020' column='1'/>
+        <parameter type-id='f7d748c2' name='fid' filepath='fs/libfs.c' line='1020' column='1'/>
+        <parameter type-id='95e97e5e' name='fh_len' filepath='fs/libfs.c' line='1021' column='1'/>
+        <parameter type-id='95e97e5e' name='fh_type' filepath='fs/libfs.c' line='1021' column='1'/>
+        <parameter type-id='14a7c87f' name='get_inode' filepath='fs/libfs.c' line='1021' column='1'/>
         <return type-id='27675065'/>
       </function-decl>
-      <function-decl name='generic_fh_to_parent' mangled-name='generic_fh_to_parent' filepath='fs/libfs.c' line='1037' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_fh_to_parent'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/libfs.c' line='1037' column='1'/>
-        <parameter type-id='f7d748c2' name='fid' filepath='fs/libfs.c' line='1037' column='1'/>
-        <parameter type-id='95e97e5e' name='fh_len' filepath='fs/libfs.c' line='1038' column='1'/>
-        <parameter type-id='95e97e5e' name='fh_type' filepath='fs/libfs.c' line='1038' column='1'/>
-        <parameter type-id='14a7c87f' name='get_inode' filepath='fs/libfs.c' line='1038' column='1'/>
+      <function-decl name='generic_fh_to_parent' mangled-name='generic_fh_to_parent' filepath='fs/libfs.c' line='1053' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_fh_to_parent'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/libfs.c' line='1053' column='1'/>
+        <parameter type-id='f7d748c2' name='fid' filepath='fs/libfs.c' line='1053' column='1'/>
+        <parameter type-id='95e97e5e' name='fh_len' filepath='fs/libfs.c' line='1054' column='1'/>
+        <parameter type-id='95e97e5e' name='fh_type' filepath='fs/libfs.c' line='1054' column='1'/>
+        <parameter type-id='14a7c87f' name='get_inode' filepath='fs/libfs.c' line='1054' column='1'/>
         <return type-id='27675065'/>
       </function-decl>
-      <function-decl name='generic_file_direct_write' mangled-name='generic_file_direct_write' filepath='mm/filemap.c' line='3357' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_file_direct_write'>
-        <parameter type-id='80f25feb' name='iocb' filepath='mm/filemap.c' line='3357' column='1'/>
-        <parameter type-id='4fa10f9e' name='from' filepath='mm/filemap.c' line='3357' column='1'/>
+      <function-decl name='generic_file_direct_write' mangled-name='generic_file_direct_write' filepath='mm/filemap.c' line='3364' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_file_direct_write'>
+        <parameter type-id='80f25feb' name='iocb' filepath='mm/filemap.c' line='3364' column='1'/>
+        <parameter type-id='4fa10f9e' name='from' filepath='mm/filemap.c' line='3364' column='1'/>
         <return type-id='79a0948f'/>
       </function-decl>
       <function-decl name='generic_file_llseek' mangled-name='generic_file_llseek' filepath='fs/read_write.c' line='144' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_file_llseek'>
@@ -131704,14 +132384,14 @@
         <parameter type-id='69bf7bee' name='eof' filepath='fs/read_write.c' line='87' column='1'/>
         <return type-id='69bf7bee'/>
       </function-decl>
-      <function-decl name='generic_file_mmap' mangled-name='generic_file_mmap' filepath='mm/filemap.c' line='3111' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_file_mmap'>
-        <parameter type-id='77e79a4b' name='file' filepath='mm/filemap.c' line='3111' column='1'/>
-        <parameter type-id='2ae08426' name='vma' filepath='mm/filemap.c' line='3111' column='1'/>
+      <function-decl name='generic_file_mmap' mangled-name='generic_file_mmap' filepath='mm/filemap.c' line='3118' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_file_mmap'>
+        <parameter type-id='77e79a4b' name='file' filepath='mm/filemap.c' line='3118' column='1'/>
+        <parameter type-id='2ae08426' name='vma' filepath='mm/filemap.c' line='3118' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='generic_file_open' mangled-name='generic_file_open' filepath='fs/open.c' line='1386' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_file_open'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/open.c' line='1386' column='1'/>
-        <parameter type-id='77e79a4b' name='filp' filepath='fs/open.c' line='1386' column='1'/>
+      <function-decl name='generic_file_open' mangled-name='generic_file_open' filepath='fs/open.c' line='1392' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_file_open'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/open.c' line='1392' column='1'/>
+        <parameter type-id='77e79a4b' name='filp' filepath='fs/open.c' line='1392' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='generic_file_read_iter' mangled-name='generic_file_read_iter' filepath='mm/filemap.c' line='2515' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_file_read_iter'>
@@ -131732,13 +132412,13 @@
         <parameter type-id='0e87f9be' name='stat' filepath='fs/stat.c' line='36' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='generic_handle_irq' mangled-name='generic_handle_irq' filepath='kernel/irq/irqdesc.c' line='640' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_handle_irq'>
-        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/irqdesc.c' line='640' column='1'/>
+      <function-decl name='generic_handle_irq' mangled-name='generic_handle_irq' filepath='kernel/irq/irqdesc.c' line='643' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_handle_irq'>
+        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/irqdesc.c' line='643' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='generic_iommu_put_resv_regions' mangled-name='generic_iommu_put_resv_regions' filepath='drivers/iommu/iommu.c' line='2819' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_iommu_put_resv_regions'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='2819' column='1'/>
-        <parameter type-id='e84b031a' name='list' filepath='drivers/iommu/iommu.c' line='2819' column='1'/>
+      <function-decl name='generic_iommu_put_resv_regions' mangled-name='generic_iommu_put_resv_regions' filepath='drivers/iommu/iommu.c' line='2835' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_iommu_put_resv_regions'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='2835' column='1'/>
+        <parameter type-id='e84b031a' name='list' filepath='drivers/iommu/iommu.c' line='2835' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='generic_mii_ioctl' mangled-name='generic_mii_ioctl' filepath='drivers/net/mii.c' line='584' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_mii_ioctl'>
@@ -131748,10 +132428,10 @@
         <parameter type-id='807869d3' name='duplex_chg_out' filepath='drivers/net/mii.c' line='586' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='generic_perform_write' mangled-name='generic_perform_write' filepath='mm/filemap.c' line='3460' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_perform_write'>
-        <parameter type-id='77e79a4b' name='file' filepath='mm/filemap.c' line='3460' column='1'/>
-        <parameter type-id='4fa10f9e' name='i' filepath='mm/filemap.c' line='3461' column='1'/>
-        <parameter type-id='69bf7bee' name='pos' filepath='mm/filemap.c' line='3461' column='1'/>
+      <function-decl name='generic_perform_write' mangled-name='generic_perform_write' filepath='mm/filemap.c' line='3467' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_perform_write'>
+        <parameter type-id='77e79a4b' name='file' filepath='mm/filemap.c' line='3467' column='1'/>
+        <parameter type-id='4fa10f9e' name='i' filepath='mm/filemap.c' line='3468' column='1'/>
+        <parameter type-id='69bf7bee' name='pos' filepath='mm/filemap.c' line='3468' column='1'/>
         <return type-id='79a0948f'/>
       </function-decl>
       <function-decl name='generic_read_dir' mangled-name='generic_read_dir' filepath='fs/libfs.c' line='224' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_read_dir'>
@@ -131761,8 +132441,8 @@
         <parameter type-id='b53e8dbb' name='ppos' filepath='fs/libfs.c' line='224' column='1'/>
         <return type-id='79a0948f'/>
       </function-decl>
-      <function-decl name='generic_set_encrypted_ci_d_ops' mangled-name='generic_set_encrypted_ci_d_ops' filepath='fs/libfs.c' line='1490' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_set_encrypted_ci_d_ops'>
-        <parameter type-id='27675065' name='dentry' filepath='fs/libfs.c' line='1490' column='1'/>
+      <function-decl name='generic_set_encrypted_ci_d_ops' mangled-name='generic_set_encrypted_ci_d_ops' filepath='fs/libfs.c' line='1506' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_set_encrypted_ci_d_ops'>
+        <parameter type-id='27675065' name='dentry' filepath='fs/libfs.c' line='1506' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='generic_shutdown_super' mangled-name='generic_shutdown_super' filepath='fs/super.c' line='442' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='generic_shutdown_super'>
@@ -131866,14 +132546,14 @@
         <parameter type-id='95e97e5e' name='io_busy' filepath='drivers/cpufreq/cpufreq.c' line='152' column='1'/>
         <return type-id='91ce1af9'/>
       </function-decl>
-      <function-decl name='get_cpu_idle_time_us' mangled-name='get_cpu_idle_time_us' filepath='kernel/time/tick-sched.c' line='593' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_cpu_idle_time_us'>
-        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/time/tick-sched.c' line='593' column='1'/>
-        <parameter type-id='3df9fd28' name='last_update_time' filepath='kernel/time/tick-sched.c' line='593' column='1'/>
+      <function-decl name='get_cpu_idle_time_us' mangled-name='get_cpu_idle_time_us' filepath='kernel/time/tick-sched.c' line='632' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_cpu_idle_time_us'>
+        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/time/tick-sched.c' line='632' column='1'/>
+        <parameter type-id='3df9fd28' name='last_update_time' filepath='kernel/time/tick-sched.c' line='632' column='1'/>
         <return type-id='91ce1af9'/>
       </function-decl>
-      <function-decl name='get_cpu_iowait_time_us' mangled-name='get_cpu_iowait_time_us' filepath='kernel/time/tick-sched.c' line='634' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_cpu_iowait_time_us'>
-        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/time/tick-sched.c' line='634' column='1'/>
-        <parameter type-id='3df9fd28' name='last_update_time' filepath='kernel/time/tick-sched.c' line='634' column='1'/>
+      <function-decl name='get_cpu_iowait_time_us' mangled-name='get_cpu_iowait_time_us' filepath='kernel/time/tick-sched.c' line='673' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_cpu_iowait_time_us'>
+        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/time/tick-sched.c' line='673' column='1'/>
+        <parameter type-id='3df9fd28' name='last_update_time' filepath='kernel/time/tick-sched.c' line='673' column='1'/>
         <return type-id='91ce1af9'/>
       </function-decl>
       <function-decl name='get_device' mangled-name='get_device' filepath='drivers/base/core.c' line='3333' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_device'>
@@ -131903,6 +132583,10 @@
       <function-decl name='get_freelist_nr_pages' mangled-name='get_freelist_nr_pages' filepath='drivers/dma-buf/heaps/deferred-free-helper.c' line='65' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_freelist_nr_pages'>
         <return type-id='7359adad'/>
       </function-decl>
+      <function-decl name='get_fs_type' mangled-name='get_fs_type' filepath='fs/filesystems.c' line='266' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_fs_type'>
+        <parameter type-id='80f4b756' name='name' filepath='fs/filesystems.c' line='266' column='1'/>
+        <return type-id='21e53d44'/>
+      </function-decl>
       <function-decl name='get_governor_parent_kobj' mangled-name='get_governor_parent_kobj' filepath='drivers/cpufreq/cpufreq.c' line='118' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_governor_parent_kobj'>
         <parameter type-id='343c3ae4' name='policy' filepath='drivers/cpufreq/cpufreq.c' line='118' column='1'/>
         <return type-id='d30bdc51'/>
@@ -131914,16 +132598,16 @@
         <parameter type-id='9f93c9da' name='pages' filepath='mm/swap.c' line='170' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='get_mem_cgroup_from_mm' mangled-name='get_mem_cgroup_from_mm' filepath='mm/memcontrol.c' line='1023' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_mem_cgroup_from_mm'>
-        <parameter type-id='df4b7819' name='mm' filepath='mm/memcontrol.c' line='1023' column='1'/>
+      <function-decl name='get_mem_cgroup_from_mm' mangled-name='get_mem_cgroup_from_mm' filepath='mm/memcontrol.c' line='1025' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_mem_cgroup_from_mm'>
+        <parameter type-id='df4b7819' name='mm' filepath='mm/memcontrol.c' line='1025' column='1'/>
         <return type-id='223696fb'/>
       </function-decl>
-      <function-decl name='get_net_ns_by_fd' mangled-name='get_net_ns_by_fd' filepath='net/core/net_namespace.c' line='678' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_net_ns_by_fd'>
-        <parameter type-id='95e97e5e' name='fd' filepath='net/core/net_namespace.c' line='678' column='1'/>
+      <function-decl name='get_net_ns_by_fd' mangled-name='get_net_ns_by_fd' filepath='net/core/net_namespace.c' line='669' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_net_ns_by_fd'>
+        <parameter type-id='95e97e5e' name='fd' filepath='net/core/net_namespace.c' line='669' column='1'/>
         <return type-id='a2bff676'/>
       </function-decl>
-      <function-decl name='get_net_ns_by_pid' mangled-name='get_net_ns_by_pid' filepath='net/core/net_namespace.c' line='706' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_net_ns_by_pid'>
-        <parameter type-id='587f89d2' name='pid' filepath='net/core/net_namespace.c' line='706' column='1'/>
+      <function-decl name='get_net_ns_by_pid' mangled-name='get_net_ns_by_pid' filepath='net/core/net_namespace.c' line='697' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_net_ns_by_pid'>
+        <parameter type-id='587f89d2' name='pid' filepath='net/core/net_namespace.c' line='697' column='1'/>
         <return type-id='a2bff676'/>
       </function-decl>
       <function-decl name='get_next_ino' mangled-name='get_next_ino' filepath='fs/inode.c' line='893' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_next_ino'>
@@ -131940,9 +132624,9 @@
         <parameter type-id='7292109c' name='ints' filepath='lib/cmdline.c' line='87' column='1'/>
         <return type-id='26a90f95'/>
       </function-decl>
-      <function-decl name='get_page_owner_handle' mangled-name='get_page_owner_handle' filepath='mm/page_owner.c' line='108' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_page_owner_handle'>
-        <parameter type-id='459ae684' name='page_ext' filepath='mm/page_owner.c' line='108' column='1'/>
-        <parameter type-id='7359adad' name='pfn' filepath='mm/page_owner.c' line='108' column='1'/>
+      <function-decl name='get_page_owner_handle' mangled-name='get_page_owner_handle' filepath='mm/page_owner.c' line='109' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_page_owner_handle'>
+        <parameter type-id='459ae684' name='page_ext' filepath='mm/page_owner.c' line='109' column='1'/>
+        <parameter type-id='7359adad' name='pfn' filepath='mm/page_owner.c' line='109' column='1'/>
         <return type-id='613ae993'/>
       </function-decl>
       <function-decl name='get_pelt_halflife' mangled-name='get_pelt_halflife' filepath='kernel/sched/pelt.c' line='35' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_pelt_halflife'>
@@ -131985,15 +132669,15 @@
         <parameter type-id='d225de01' name='sinfo' filepath='mm/slub.c' line='5911' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='get_state_synchronize_rcu' mangled-name='get_state_synchronize_rcu' filepath='kernel/rcu/tree.c' line='3694' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_state_synchronize_rcu'>
+      <function-decl name='get_state_synchronize_rcu' mangled-name='get_state_synchronize_rcu' filepath='kernel/rcu/tree.c' line='3723' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_state_synchronize_rcu'>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='get_task_exe_file' mangled-name='get_task_exe_file' filepath='kernel/fork.c' line='1234' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_task_exe_file'>
-        <parameter type-id='f23e2572' name='task' filepath='kernel/fork.c' line='1234' column='1'/>
+      <function-decl name='get_task_exe_file' mangled-name='get_task_exe_file' filepath='kernel/fork.c' line='1238' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_task_exe_file'>
+        <parameter type-id='f23e2572' name='task' filepath='kernel/fork.c' line='1238' column='1'/>
         <return type-id='77e79a4b'/>
       </function-decl>
-      <function-decl name='get_task_mm' mangled-name='get_task_mm' filepath='kernel/fork.c' line='1259' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_task_mm'>
-        <parameter type-id='f23e2572' name='task' filepath='kernel/fork.c' line='1259' column='1'/>
+      <function-decl name='get_task_mm' mangled-name='get_task_mm' filepath='kernel/fork.c' line='1263' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_task_mm'>
+        <parameter type-id='f23e2572' name='task' filepath='kernel/fork.c' line='1263' column='1'/>
         <return type-id='df4b7819'/>
       </function-decl>
       <function-decl name='get_task_pid' mangled-name='get_task_pid' filepath='kernel/pid.c' line='439' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_task_pid'>
@@ -132020,8 +132704,8 @@
         <parameter type-id='7359adad' name='flags' filepath='mm/mmap.c' line='2336' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='get_unused_fd_flags' mangled-name='get_unused_fd_flags' filepath='fs/file.c' line='590' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_unused_fd_flags'>
-        <parameter type-id='f0981eeb' name='flags' filepath='fs/file.c' line='590' column='1'/>
+      <function-decl name='get_unused_fd_flags' mangled-name='get_unused_fd_flags' filepath='fs/file.c' line='592' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_unused_fd_flags'>
+        <parameter type-id='f0981eeb' name='flags' filepath='fs/file.c' line='592' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='get_user_pages' mangled-name='get_user_pages' filepath='mm/gup.c' line='1906' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_user_pages'>
@@ -132060,8 +132744,8 @@
         <parameter type-id='f23e2572' name='p' filepath='arch/arm64/kernel/process.c' line='593' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='get_zeroed_page' mangled-name='get_zeroed_page' filepath='mm/page_alloc.c' line='5221' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_zeroed_page'>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/page_alloc.c' line='5221' column='1'/>
+      <function-decl name='get_zeroed_page' mangled-name='get_zeroed_page' filepath='mm/page_alloc.c' line='5250' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_zeroed_page'>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/page_alloc.c' line='5250' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
       <function-decl name='getboottime64' mangled-name='getboottime64' filepath='kernel/time/timekeeping.c' line='2227' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getboottime64'>
@@ -132077,8 +132761,8 @@
         <parameter type-id='3eb7c31c' name='flags' filepath='mm/mmzone.c' line='105' column='1'/>
         <return type-id='d278ff03'/>
       </function-decl>
-      <var-decl name='gic_nonsecure_priorities' type-id='237c0d27' mangled-name='gic_nonsecure_priorities' visibility='default' filepath='drivers/irqchip/irq-gic-v3.c' line='92' column='1' elf-symbol-id='gic_nonsecure_priorities'/>
-      <function-decl name='gic_resume' mangled-name='gic_resume' filepath='drivers/irqchip/irq-gic-v3.c' line='1323' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gic_resume'>
+      <var-decl name='gic_nonsecure_priorities' type-id='237c0d27' mangled-name='gic_nonsecure_priorities' visibility='default' filepath='drivers/irqchip/irq-gic-v3.c' line='95' column='1' elf-symbol-id='gic_nonsecure_priorities'/>
+      <function-decl name='gic_resume' mangled-name='gic_resume' filepath='drivers/irqchip/irq-gic-v3.c' line='1360' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gic_resume'>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='glob_match' mangled-name='glob_match' filepath='lib/glob.c' line='40' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='glob_match'>
@@ -132157,194 +132841,194 @@
         <parameter type-id='f0981eeb' name='gpio' filepath='drivers/gpio/gpiolib.c' line='108' column='1'/>
         <return type-id='26760480'/>
       </function-decl>
-      <function-decl name='gpiochip_add_data_with_key' mangled-name='gpiochip_add_data_with_key' filepath='drivers/gpio/gpiolib.c' line='571' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_add_data_with_key'>
-        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='571' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/gpio/gpiolib.c' line='571' column='1'/>
-        <parameter type-id='a57283f9' name='lock_key' filepath='drivers/gpio/gpiolib.c' line='572' column='1'/>
-        <parameter type-id='a57283f9' name='request_key' filepath='drivers/gpio/gpiolib.c' line='573' column='1'/>
+      <function-decl name='gpiochip_add_data_with_key' mangled-name='gpiochip_add_data_with_key' filepath='drivers/gpio/gpiolib.c' line='570' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_add_data_with_key'>
+        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='570' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/gpio/gpiolib.c' line='570' column='1'/>
+        <parameter type-id='a57283f9' name='lock_key' filepath='drivers/gpio/gpiolib.c' line='571' column='1'/>
+        <parameter type-id='a57283f9' name='request_key' filepath='drivers/gpio/gpiolib.c' line='572' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiochip_add_pin_range' mangled-name='gpiochip_add_pin_range' filepath='drivers/gpio/gpiolib.c' line='1937' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_add_pin_range'>
-        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='1937' column='1'/>
-        <parameter type-id='80f4b756' name='pinctl_name' filepath='drivers/gpio/gpiolib.c' line='1937' column='1'/>
-        <parameter type-id='f0981eeb' name='gpio_offset' filepath='drivers/gpio/gpiolib.c' line='1938' column='1'/>
-        <parameter type-id='f0981eeb' name='pin_offset' filepath='drivers/gpio/gpiolib.c' line='1938' column='1'/>
-        <parameter type-id='f0981eeb' name='npins' filepath='drivers/gpio/gpiolib.c' line='1939' column='1'/>
+      <function-decl name='gpiochip_add_pin_range' mangled-name='gpiochip_add_pin_range' filepath='drivers/gpio/gpiolib.c' line='1936' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_add_pin_range'>
+        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='1936' column='1'/>
+        <parameter type-id='80f4b756' name='pinctl_name' filepath='drivers/gpio/gpiolib.c' line='1936' column='1'/>
+        <parameter type-id='f0981eeb' name='gpio_offset' filepath='drivers/gpio/gpiolib.c' line='1937' column='1'/>
+        <parameter type-id='f0981eeb' name='pin_offset' filepath='drivers/gpio/gpiolib.c' line='1937' column='1'/>
+        <parameter type-id='f0981eeb' name='npins' filepath='drivers/gpio/gpiolib.c' line='1938' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiochip_find' mangled-name='gpiochip_find' filepath='drivers/gpio/gpiolib.c' line='870' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_find'>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/gpio/gpiolib.c' line='870' column='1'/>
-        <parameter type-id='7a52b9cd' name='match' filepath='drivers/gpio/gpiolib.c' line='871' column='1'/>
+      <function-decl name='gpiochip_find' mangled-name='gpiochip_find' filepath='drivers/gpio/gpiolib.c' line='869' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_find'>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/gpio/gpiolib.c' line='869' column='1'/>
+        <parameter type-id='7a52b9cd' name='match' filepath='drivers/gpio/gpiolib.c' line='870' column='1'/>
         <return type-id='e324928d'/>
       </function-decl>
-      <function-decl name='gpiochip_generic_config' mangled-name='gpiochip_generic_config' filepath='drivers/gpio/gpiolib.c' line='1858' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_generic_config'>
-        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='1858' column='1'/>
-        <parameter type-id='f0981eeb' name='offset' filepath='drivers/gpio/gpiolib.c' line='1858' column='1'/>
-        <parameter type-id='7359adad' name='config' filepath='drivers/gpio/gpiolib.c' line='1859' column='1'/>
+      <function-decl name='gpiochip_generic_config' mangled-name='gpiochip_generic_config' filepath='drivers/gpio/gpiolib.c' line='1857' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_generic_config'>
+        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='1857' column='1'/>
+        <parameter type-id='f0981eeb' name='offset' filepath='drivers/gpio/gpiolib.c' line='1857' column='1'/>
+        <parameter type-id='7359adad' name='config' filepath='drivers/gpio/gpiolib.c' line='1858' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiochip_generic_free' mangled-name='gpiochip_generic_free' filepath='drivers/gpio/gpiolib.c' line='1841' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_generic_free'>
-        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='1841' column='1'/>
-        <parameter type-id='f0981eeb' name='offset' filepath='drivers/gpio/gpiolib.c' line='1841' column='1'/>
+      <function-decl name='gpiochip_generic_free' mangled-name='gpiochip_generic_free' filepath='drivers/gpio/gpiolib.c' line='1840' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_generic_free'>
+        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='1840' column='1'/>
+        <parameter type-id='f0981eeb' name='offset' filepath='drivers/gpio/gpiolib.c' line='1840' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='gpiochip_generic_request' mangled-name='gpiochip_generic_request' filepath='drivers/gpio/gpiolib.c' line='1825' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_generic_request'>
-        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='1825' column='1'/>
-        <parameter type-id='f0981eeb' name='offset' filepath='drivers/gpio/gpiolib.c' line='1825' column='1'/>
+      <function-decl name='gpiochip_generic_request' mangled-name='gpiochip_generic_request' filepath='drivers/gpio/gpiolib.c' line='1824' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_generic_request'>
+        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='1824' column='1'/>
+        <parameter type-id='f0981eeb' name='offset' filepath='drivers/gpio/gpiolib.c' line='1824' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiochip_get_data' mangled-name='gpiochip_get_data' filepath='drivers/gpio/gpiolib.c' line='803' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_get_data'>
-        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='803' column='1'/>
+      <function-decl name='gpiochip_get_data' mangled-name='gpiochip_get_data' filepath='drivers/gpio/gpiolib.c' line='802' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_get_data'>
+        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='802' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='gpiochip_irqchip_add_key' mangled-name='gpiochip_irqchip_add_key' filepath='drivers/gpio/gpiolib.c' line='1711' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_irqchip_add_key'>
-        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='1711' column='1'/>
-        <parameter type-id='8846a616' name='irqchip' filepath='drivers/gpio/gpiolib.c' line='1712' column='1'/>
-        <parameter type-id='f0981eeb' name='first_irq' filepath='drivers/gpio/gpiolib.c' line='1713' column='1'/>
-        <parameter type-id='cdb741d3' name='handler' filepath='drivers/gpio/gpiolib.c' line='1714' column='1'/>
-        <parameter type-id='f0981eeb' name='type' filepath='drivers/gpio/gpiolib.c' line='1715' column='1'/>
-        <parameter type-id='b50a4934' name='threaded' filepath='drivers/gpio/gpiolib.c' line='1716' column='1'/>
-        <parameter type-id='a57283f9' name='lock_key' filepath='drivers/gpio/gpiolib.c' line='1717' column='1'/>
-        <parameter type-id='a57283f9' name='request_key' filepath='drivers/gpio/gpiolib.c' line='1718' column='1'/>
+      <function-decl name='gpiochip_irqchip_add_key' mangled-name='gpiochip_irqchip_add_key' filepath='drivers/gpio/gpiolib.c' line='1710' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_irqchip_add_key'>
+        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='1710' column='1'/>
+        <parameter type-id='8846a616' name='irqchip' filepath='drivers/gpio/gpiolib.c' line='1711' column='1'/>
+        <parameter type-id='f0981eeb' name='first_irq' filepath='drivers/gpio/gpiolib.c' line='1712' column='1'/>
+        <parameter type-id='cdb741d3' name='handler' filepath='drivers/gpio/gpiolib.c' line='1713' column='1'/>
+        <parameter type-id='f0981eeb' name='type' filepath='drivers/gpio/gpiolib.c' line='1714' column='1'/>
+        <parameter type-id='b50a4934' name='threaded' filepath='drivers/gpio/gpiolib.c' line='1715' column='1'/>
+        <parameter type-id='a57283f9' name='lock_key' filepath='drivers/gpio/gpiolib.c' line='1716' column='1'/>
+        <parameter type-id='a57283f9' name='request_key' filepath='drivers/gpio/gpiolib.c' line='1717' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiochip_line_is_valid' mangled-name='gpiochip_line_is_valid' filepath='drivers/gpio/gpiolib.c' line='462' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_line_is_valid'>
-        <parameter type-id='a171e66c' name='gc' filepath='drivers/gpio/gpiolib.c' line='462' column='1'/>
-        <parameter type-id='f0981eeb' name='offset' filepath='drivers/gpio/gpiolib.c' line='463' column='1'/>
+      <function-decl name='gpiochip_line_is_valid' mangled-name='gpiochip_line_is_valid' filepath='drivers/gpio/gpiolib.c' line='461' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_line_is_valid'>
+        <parameter type-id='a171e66c' name='gc' filepath='drivers/gpio/gpiolib.c' line='461' column='1'/>
+        <parameter type-id='f0981eeb' name='offset' filepath='drivers/gpio/gpiolib.c' line='462' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='gpiochip_lock_as_irq' mangled-name='gpiochip_lock_as_irq' filepath='drivers/gpio/gpiolib.c' line='3260' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_lock_as_irq'>
-        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='3260' column='1'/>
-        <parameter type-id='f0981eeb' name='offset' filepath='drivers/gpio/gpiolib.c' line='3260' column='1'/>
+      <function-decl name='gpiochip_lock_as_irq' mangled-name='gpiochip_lock_as_irq' filepath='drivers/gpio/gpiolib.c' line='3258' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_lock_as_irq'>
+        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='3258' column='1'/>
+        <parameter type-id='f0981eeb' name='offset' filepath='drivers/gpio/gpiolib.c' line='3258' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiochip_populate_parent_fwspec_fourcell' mangled-name='gpiochip_populate_parent_fwspec_fourcell' filepath='drivers/gpio/gpiolib.c' line='1266' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_populate_parent_fwspec_fourcell'>
-        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='1266' column='1'/>
-        <parameter type-id='f0981eeb' name='parent_hwirq' filepath='drivers/gpio/gpiolib.c' line='1267' column='1'/>
-        <parameter type-id='f0981eeb' name='parent_type' filepath='drivers/gpio/gpiolib.c' line='1268' column='1'/>
+      <function-decl name='gpiochip_populate_parent_fwspec_fourcell' mangled-name='gpiochip_populate_parent_fwspec_fourcell' filepath='drivers/gpio/gpiolib.c' line='1265' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_populate_parent_fwspec_fourcell'>
+        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='1265' column='1'/>
+        <parameter type-id='f0981eeb' name='parent_hwirq' filepath='drivers/gpio/gpiolib.c' line='1266' column='1'/>
+        <parameter type-id='f0981eeb' name='parent_type' filepath='drivers/gpio/gpiolib.c' line='1267' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='gpiochip_remove' mangled-name='gpiochip_remove' filepath='drivers/gpio/gpiolib.c' line='815' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_remove'>
-        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='815' column='1'/>
+      <function-decl name='gpiochip_remove' mangled-name='gpiochip_remove' filepath='drivers/gpio/gpiolib.c' line='814' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_remove'>
+        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='814' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='gpiochip_set_nested_irqchip' mangled-name='gpiochip_set_nested_irqchip' filepath='drivers/gpio/gpiolib.c' line='1006' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_set_nested_irqchip'>
-        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='1006' column='1'/>
-        <parameter type-id='8846a616' name='irqchip' filepath='drivers/gpio/gpiolib.c' line='1007' column='1'/>
-        <parameter type-id='f0981eeb' name='parent_irq' filepath='drivers/gpio/gpiolib.c' line='1008' column='1'/>
+      <function-decl name='gpiochip_set_nested_irqchip' mangled-name='gpiochip_set_nested_irqchip' filepath='drivers/gpio/gpiolib.c' line='1005' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_set_nested_irqchip'>
+        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='1005' column='1'/>
+        <parameter type-id='8846a616' name='irqchip' filepath='drivers/gpio/gpiolib.c' line='1006' column='1'/>
+        <parameter type-id='f0981eeb' name='parent_irq' filepath='drivers/gpio/gpiolib.c' line='1007' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='gpiochip_unlock_as_irq' mangled-name='gpiochip_unlock_as_irq' filepath='drivers/gpio/gpiolib.c' line='3314' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_unlock_as_irq'>
-        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='3314' column='1'/>
-        <parameter type-id='f0981eeb' name='offset' filepath='drivers/gpio/gpiolib.c' line='3314' column='1'/>
+      <function-decl name='gpiochip_unlock_as_irq' mangled-name='gpiochip_unlock_as_irq' filepath='drivers/gpio/gpiolib.c' line='3312' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiochip_unlock_as_irq'>
+        <parameter type-id='e324928d' name='gc' filepath='drivers/gpio/gpiolib.c' line='3312' column='1'/>
+        <parameter type-id='f0981eeb' name='offset' filepath='drivers/gpio/gpiolib.c' line='3312' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='gpiod_cansleep' mangled-name='gpiod_cansleep' filepath='drivers/gpio/gpiolib.c' line='3179' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_cansleep'>
-        <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='3179' column='1'/>
+      <function-decl name='gpiod_cansleep' mangled-name='gpiod_cansleep' filepath='drivers/gpio/gpiolib.c' line='3177' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_cansleep'>
+        <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='3177' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiod_count' mangled-name='gpiod_count' filepath='drivers/gpio/gpiolib.c' line='3845' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_count'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/gpio/gpiolib.c' line='3845' column='1'/>
-        <parameter type-id='80f4b756' name='con_id' filepath='drivers/gpio/gpiolib.c' line='3845' column='1'/>
+      <function-decl name='gpiod_count' mangled-name='gpiod_count' filepath='drivers/gpio/gpiolib.c' line='3843' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_count'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/gpio/gpiolib.c' line='3843' column='1'/>
+        <parameter type-id='80f4b756' name='con_id' filepath='drivers/gpio/gpiolib.c' line='3843' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiod_direction_input' mangled-name='gpiod_direction_input' filepath='drivers/gpio/gpiolib.c' line='2337' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_direction_input'>
-        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='2337' column='1'/>
+      <function-decl name='gpiod_direction_input' mangled-name='gpiod_direction_input' filepath='drivers/gpio/gpiolib.c' line='2336' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_direction_input'>
+        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='2336' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiod_direction_output' mangled-name='gpiod_direction_output' filepath='drivers/gpio/gpiolib.c' line='2456' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_direction_output'>
-        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='2456' column='1'/>
-        <parameter type-id='95e97e5e' name='value' filepath='drivers/gpio/gpiolib.c' line='2456' column='1'/>
+      <function-decl name='gpiod_direction_output' mangled-name='gpiod_direction_output' filepath='drivers/gpio/gpiolib.c' line='2455' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_direction_output'>
+        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='2455' column='1'/>
+        <parameter type-id='95e97e5e' name='value' filepath='drivers/gpio/gpiolib.c' line='2455' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiod_direction_output_raw' mangled-name='gpiod_direction_output_raw' filepath='drivers/gpio/gpiolib.c' line='2437' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_direction_output_raw'>
-        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='2437' column='1'/>
-        <parameter type-id='95e97e5e' name='value' filepath='drivers/gpio/gpiolib.c' line='2437' column='1'/>
+      <function-decl name='gpiod_direction_output_raw' mangled-name='gpiod_direction_output_raw' filepath='drivers/gpio/gpiolib.c' line='2436' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_direction_output_raw'>
+        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='2436' column='1'/>
+        <parameter type-id='95e97e5e' name='value' filepath='drivers/gpio/gpiolib.c' line='2436' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiod_get_direction' mangled-name='gpiod_get_direction' filepath='drivers/gpio/gpiolib.c' line='215' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_get_direction'>
-        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='215' column='1'/>
+      <function-decl name='gpiod_get_direction' mangled-name='gpiod_get_direction' filepath='drivers/gpio/gpiolib.c' line='214' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_get_direction'>
+        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='214' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiod_get_optional' mangled-name='gpiod_get_optional' filepath='drivers/gpio/gpiolib.c' line='3888' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_get_optional'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/gpio/gpiolib.c' line='3888' column='1'/>
-        <parameter type-id='80f4b756' name='con_id' filepath='drivers/gpio/gpiolib.c' line='3889' column='1'/>
-        <parameter type-id='38d4936d' name='flags' filepath='drivers/gpio/gpiolib.c' line='3890' column='1'/>
+      <function-decl name='gpiod_get_optional' mangled-name='gpiod_get_optional' filepath='drivers/gpio/gpiolib.c' line='3886' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_get_optional'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/gpio/gpiolib.c' line='3886' column='1'/>
+        <parameter type-id='80f4b756' name='con_id' filepath='drivers/gpio/gpiolib.c' line='3887' column='1'/>
+        <parameter type-id='38d4936d' name='flags' filepath='drivers/gpio/gpiolib.c' line='3888' column='1'/>
         <return type-id='26760480'/>
       </function-decl>
-      <function-decl name='gpiod_get_raw_value' mangled-name='gpiod_get_raw_value' filepath='drivers/gpio/gpiolib.c' line='2788' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_get_raw_value'>
-        <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='2788' column='1'/>
+      <function-decl name='gpiod_get_raw_value' mangled-name='gpiod_get_raw_value' filepath='drivers/gpio/gpiolib.c' line='2786' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_get_raw_value'>
+        <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='2786' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiod_get_raw_value_cansleep' mangled-name='gpiod_get_raw_value_cansleep' filepath='drivers/gpio/gpiolib.c' line='3427' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_get_raw_value_cansleep'>
-        <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='3427' column='1'/>
+      <function-decl name='gpiod_get_raw_value_cansleep' mangled-name='gpiod_get_raw_value_cansleep' filepath='drivers/gpio/gpiolib.c' line='3425' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_get_raw_value_cansleep'>
+        <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='3425' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiod_get_value' mangled-name='gpiod_get_value' filepath='drivers/gpio/gpiolib.c' line='2807' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_get_value'>
-        <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='2807' column='1'/>
+      <function-decl name='gpiod_get_value' mangled-name='gpiod_get_value' filepath='drivers/gpio/gpiolib.c' line='2805' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_get_value'>
+        <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='2805' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiod_get_value_cansleep' mangled-name='gpiod_get_value_cansleep' filepath='drivers/gpio/gpiolib.c' line='3444' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_get_value_cansleep'>
-        <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='3444' column='1'/>
+      <function-decl name='gpiod_get_value_cansleep' mangled-name='gpiod_get_value_cansleep' filepath='drivers/gpio/gpiolib.c' line='3442' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_get_value_cansleep'>
+        <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='3442' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiod_is_active_low' mangled-name='gpiod_is_active_low' filepath='drivers/gpio/gpiolib.c' line='2603' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_is_active_low'>
-        <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='2603' column='1'/>
+      <function-decl name='gpiod_is_active_low' mangled-name='gpiod_is_active_low' filepath='drivers/gpio/gpiolib.c' line='2601' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_is_active_low'>
+        <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='2601' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiod_put' mangled-name='gpiod_put' filepath='drivers/gpio/gpiolib.c' line='4360' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_put'>
-        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='4360' column='1'/>
+      <function-decl name='gpiod_put' mangled-name='gpiod_put' filepath='drivers/gpio/gpiolib.c' line='4358' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_put'>
+        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='4358' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='gpiod_set_array_value_cansleep' mangled-name='gpiod_set_array_value_cansleep' filepath='drivers/gpio/gpiolib.c' line='3604' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_set_array_value_cansleep'>
-        <parameter type-id='f0981eeb' name='array_size' filepath='drivers/gpio/gpiolib.c' line='3604' column='1'/>
-        <parameter type-id='35c9579e' name='desc_array' filepath='drivers/gpio/gpiolib.c' line='3605' column='1'/>
-        <parameter type-id='ae0aa6a2' name='array_info' filepath='drivers/gpio/gpiolib.c' line='3606' column='1'/>
-        <parameter type-id='1d2c2b85' name='value_bitmap' filepath='drivers/gpio/gpiolib.c' line='3607' column='1'/>
+      <function-decl name='gpiod_set_array_value_cansleep' mangled-name='gpiod_set_array_value_cansleep' filepath='drivers/gpio/gpiolib.c' line='3602' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_set_array_value_cansleep'>
+        <parameter type-id='f0981eeb' name='array_size' filepath='drivers/gpio/gpiolib.c' line='3602' column='1'/>
+        <parameter type-id='35c9579e' name='desc_array' filepath='drivers/gpio/gpiolib.c' line='3603' column='1'/>
+        <parameter type-id='ae0aa6a2' name='array_info' filepath='drivers/gpio/gpiolib.c' line='3604' column='1'/>
+        <parameter type-id='1d2c2b85' name='value_bitmap' filepath='drivers/gpio/gpiolib.c' line='3605' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiod_set_consumer_name' mangled-name='gpiod_set_consumer_name' filepath='drivers/gpio/gpiolib.c' line='3191' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_set_consumer_name'>
-        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='3191' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='drivers/gpio/gpiolib.c' line='3191' column='1'/>
+      <function-decl name='gpiod_set_consumer_name' mangled-name='gpiod_set_consumer_name' filepath='drivers/gpio/gpiolib.c' line='3189' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_set_consumer_name'>
+        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='3189' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='drivers/gpio/gpiolib.c' line='3189' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiod_set_debounce' mangled-name='gpiod_set_debounce' filepath='drivers/gpio/gpiolib.c' line='2547' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_set_debounce'>
-        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='2547' column='1'/>
-        <parameter type-id='f0981eeb' name='debounce' filepath='drivers/gpio/gpiolib.c' line='2547' column='1'/>
+      <function-decl name='gpiod_set_debounce' mangled-name='gpiod_set_debounce' filepath='drivers/gpio/gpiolib.c' line='2545' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_set_debounce'>
+        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='2545' column='1'/>
+        <parameter type-id='f0981eeb' name='debounce' filepath='drivers/gpio/gpiolib.c' line='2545' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gpiod_set_raw_value' mangled-name='gpiod_set_raw_value' filepath='drivers/gpio/gpiolib.c' line='3073' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_set_raw_value'>
-        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='3073' column='1'/>
-        <parameter type-id='95e97e5e' name='value' filepath='drivers/gpio/gpiolib.c' line='3073' column='1'/>
+      <function-decl name='gpiod_set_raw_value' mangled-name='gpiod_set_raw_value' filepath='drivers/gpio/gpiolib.c' line='3071' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_set_raw_value'>
+        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='3071' column='1'/>
+        <parameter type-id='95e97e5e' name='value' filepath='drivers/gpio/gpiolib.c' line='3071' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='gpiod_set_raw_value_cansleep' mangled-name='gpiod_set_raw_value_cansleep' filepath='drivers/gpio/gpiolib.c' line='3524' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_set_raw_value_cansleep'>
-        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='3524' column='1'/>
-        <parameter type-id='95e97e5e' name='value' filepath='drivers/gpio/gpiolib.c' line='3524' column='1'/>
+      <function-decl name='gpiod_set_raw_value_cansleep' mangled-name='gpiod_set_raw_value_cansleep' filepath='drivers/gpio/gpiolib.c' line='3522' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_set_raw_value_cansleep'>
+        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='3522' column='1'/>
+        <parameter type-id='95e97e5e' name='value' filepath='drivers/gpio/gpiolib.c' line='3522' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='gpiod_set_value' mangled-name='gpiod_set_value' filepath='drivers/gpio/gpiolib.c' line='3114' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_set_value'>
-        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='3114' column='1'/>
-        <parameter type-id='95e97e5e' name='value' filepath='drivers/gpio/gpiolib.c' line='3114' column='1'/>
+      <function-decl name='gpiod_set_value' mangled-name='gpiod_set_value' filepath='drivers/gpio/gpiolib.c' line='3112' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_set_value'>
+        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='3112' column='1'/>
+        <parameter type-id='95e97e5e' name='value' filepath='drivers/gpio/gpiolib.c' line='3112' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='gpiod_set_value_cansleep' mangled-name='gpiod_set_value_cansleep' filepath='drivers/gpio/gpiolib.c' line='3542' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_set_value_cansleep'>
-        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='3542' column='1'/>
-        <parameter type-id='95e97e5e' name='value' filepath='drivers/gpio/gpiolib.c' line='3542' column='1'/>
+      <function-decl name='gpiod_set_value_cansleep' mangled-name='gpiod_set_value_cansleep' filepath='drivers/gpio/gpiolib.c' line='3540' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_set_value_cansleep'>
+        <parameter type-id='26760480' name='desc' filepath='drivers/gpio/gpiolib.c' line='3540' column='1'/>
+        <parameter type-id='95e97e5e' name='value' filepath='drivers/gpio/gpiolib.c' line='3540' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='gpiod_to_chip' mangled-name='gpiod_to_chip' filepath='drivers/gpio/gpiolib.c' line='175' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_to_chip'>
         <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='175' column='1'/>
         <return type-id='e324928d'/>
       </function-decl>
-      <function-decl name='gpiod_to_irq' mangled-name='gpiod_to_irq' filepath='drivers/gpio/gpiolib.c' line='3214' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_to_irq'>
-        <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='3214' column='1'/>
+      <function-decl name='gpiod_to_irq' mangled-name='gpiod_to_irq' filepath='drivers/gpio/gpiolib.c' line='3212' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gpiod_to_irq'>
+        <parameter type-id='5bed570d' name='desc' filepath='drivers/gpio/gpiolib.c' line='3212' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='grab_cache_page_write_begin' mangled-name='grab_cache_page_write_begin' filepath='mm/filemap.c' line='3442' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='grab_cache_page_write_begin'>
-        <parameter type-id='f57039f0' name='mapping' filepath='mm/filemap.c' line='3442' column='1'/>
-        <parameter type-id='7359adad' name='index' filepath='mm/filemap.c' line='3443' column='1'/>
-        <parameter type-id='f0981eeb' name='flags' filepath='mm/filemap.c' line='3443' column='1'/>
+      <function-decl name='grab_cache_page_write_begin' mangled-name='grab_cache_page_write_begin' filepath='mm/filemap.c' line='3449' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='grab_cache_page_write_begin'>
+        <parameter type-id='f57039f0' name='mapping' filepath='mm/filemap.c' line='3449' column='1'/>
+        <parameter type-id='7359adad' name='index' filepath='mm/filemap.c' line='3450' column='1'/>
+        <parameter type-id='f0981eeb' name='flags' filepath='mm/filemap.c' line='3450' column='1'/>
         <return type-id='02f11ed4'/>
       </function-decl>
       <function-decl name='gro_cells_destroy' mangled-name='gro_cells_destroy' filepath='net/core/gro_cells.c' line='92' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gro_cells_destroy'>
@@ -132361,40 +133045,40 @@
         <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/gro_cells.c' line='12' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gs_alloc_req' mangled-name='gs_alloc_req' filepath='drivers/usb/gadget/function/u_serial.c' line='162' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gs_alloc_req'>
-        <parameter type-id='63a08bf7' name='ep' filepath='drivers/usb/gadget/function/u_serial.c' line='162' column='1'/>
-        <parameter type-id='f0981eeb' name='len' filepath='drivers/usb/gadget/function/u_serial.c' line='162' column='1'/>
-        <parameter type-id='3eb7c31c' name='kmalloc_flags' filepath='drivers/usb/gadget/function/u_serial.c' line='162' column='1'/>
+      <function-decl name='gs_alloc_req' mangled-name='gs_alloc_req' filepath='drivers/usb/gadget/function/u_serial.c' line='165' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gs_alloc_req'>
+        <parameter type-id='63a08bf7' name='ep' filepath='drivers/usb/gadget/function/u_serial.c' line='165' column='1'/>
+        <parameter type-id='f0981eeb' name='len' filepath='drivers/usb/gadget/function/u_serial.c' line='165' column='1'/>
+        <parameter type-id='3eb7c31c' name='kmalloc_flags' filepath='drivers/usb/gadget/function/u_serial.c' line='165' column='1'/>
         <return type-id='1a494567'/>
       </function-decl>
-      <function-decl name='gs_free_req' mangled-name='gs_free_req' filepath='drivers/usb/gadget/function/u_serial.c' line='186' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gs_free_req'>
-        <parameter type-id='63a08bf7' name='ep' filepath='drivers/usb/gadget/function/u_serial.c' line='186' column='1'/>
-        <parameter type-id='1a494567' name='req' filepath='drivers/usb/gadget/function/u_serial.c' line='186' column='1'/>
+      <function-decl name='gs_free_req' mangled-name='gs_free_req' filepath='drivers/usb/gadget/function/u_serial.c' line='189' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gs_free_req'>
+        <parameter type-id='63a08bf7' name='ep' filepath='drivers/usb/gadget/function/u_serial.c' line='189' column='1'/>
+        <parameter type-id='1a494567' name='req' filepath='drivers/usb/gadget/function/u_serial.c' line='189' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='gserial_alloc_line' mangled-name='gserial_alloc_line' filepath='drivers/usb/gadget/function/u_serial.c' line='1261' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gserial_alloc_line'>
-        <parameter type-id='cf536864' name='line_num' filepath='drivers/usb/gadget/function/u_serial.c' line='1261' column='1'/>
+      <function-decl name='gserial_alloc_line' mangled-name='gserial_alloc_line' filepath='drivers/usb/gadget/function/u_serial.c' line='1264' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gserial_alloc_line'>
+        <parameter type-id='cf536864' name='line_num' filepath='drivers/usb/gadget/function/u_serial.c' line='1264' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gserial_connect' mangled-name='gserial_connect' filepath='drivers/usb/gadget/function/u_serial.c' line='1293' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gserial_connect'>
-        <parameter type-id='3921c1a0' name='gser' filepath='drivers/usb/gadget/function/u_serial.c' line='1293' column='1'/>
-        <parameter type-id='f9b06939' name='port_num' filepath='drivers/usb/gadget/function/u_serial.c' line='1293' column='1'/>
+      <function-decl name='gserial_connect' mangled-name='gserial_connect' filepath='drivers/usb/gadget/function/u_serial.c' line='1296' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gserial_connect'>
+        <parameter type-id='3921c1a0' name='gser' filepath='drivers/usb/gadget/function/u_serial.c' line='1296' column='1'/>
+        <parameter type-id='f9b06939' name='port_num' filepath='drivers/usb/gadget/function/u_serial.c' line='1296' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='gserial_disconnect' mangled-name='gserial_disconnect' filepath='drivers/usb/gadget/function/u_serial.c' line='1369' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gserial_disconnect'>
-        <parameter type-id='3921c1a0' name='gser' filepath='drivers/usb/gadget/function/u_serial.c' line='1369' column='1'/>
+      <function-decl name='gserial_disconnect' mangled-name='gserial_disconnect' filepath='drivers/usb/gadget/function/u_serial.c' line='1372' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gserial_disconnect'>
+        <parameter type-id='3921c1a0' name='gser' filepath='drivers/usb/gadget/function/u_serial.c' line='1372' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='gserial_free_line' mangled-name='gserial_free_line' filepath='drivers/usb/gadget/function/u_serial.c' line='1196' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gserial_free_line'>
-        <parameter type-id='002ac4a6' name='port_num' filepath='drivers/usb/gadget/function/u_serial.c' line='1196' column='1'/>
+      <function-decl name='gserial_free_line' mangled-name='gserial_free_line' filepath='drivers/usb/gadget/function/u_serial.c' line='1199' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gserial_free_line'>
+        <parameter type-id='002ac4a6' name='port_num' filepath='drivers/usb/gadget/function/u_serial.c' line='1199' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='gserial_resume' mangled-name='gserial_resume' filepath='drivers/usb/gadget/function/u_serial.c' line='1425' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gserial_resume'>
-        <parameter type-id='3921c1a0' name='gser' filepath='drivers/usb/gadget/function/u_serial.c' line='1425' column='1'/>
+      <function-decl name='gserial_resume' mangled-name='gserial_resume' filepath='drivers/usb/gadget/function/u_serial.c' line='1440' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gserial_resume'>
+        <parameter type-id='3921c1a0' name='gser' filepath='drivers/usb/gadget/function/u_serial.c' line='1440' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='gserial_suspend' mangled-name='gserial_suspend' filepath='drivers/usb/gadget/function/u_serial.c' line='1414' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gserial_suspend'>
-        <parameter type-id='3921c1a0' name='gser' filepath='drivers/usb/gadget/function/u_serial.c' line='1414' column='1'/>
+      <function-decl name='gserial_suspend' mangled-name='gserial_suspend' filepath='drivers/usb/gadget/function/u_serial.c' line='1420' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='gserial_suspend'>
+        <parameter type-id='3921c1a0' name='gser' filepath='drivers/usb/gadget/function/u_serial.c' line='1420' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='guid_gen' mangled-name='guid_gen' filepath='lib/uuid.c' line='60' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='guid_gen'>
@@ -132434,45 +133118,45 @@
         <return type-id='48b5725f'/>
       </function-decl>
       <var-decl name='hash_digest_size' type-id='9208c5df' mangled-name='hash_digest_size' visibility='default' filepath='crypto/hash_info.c' line='35' column='1' elf-symbol-id='hash_digest_size'/>
-      <function-decl name='hashlen_string' mangled-name='hashlen_string' filepath='fs/namei.c' line='2078' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hashlen_string'>
-        <parameter type-id='eaa32e2f' name='salt' filepath='fs/namei.c' line='2078' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='fs/namei.c' line='2078' column='1'/>
+      <function-decl name='hashlen_string' mangled-name='hashlen_string' filepath='fs/namei.c' line='2088' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hashlen_string'>
+        <parameter type-id='eaa32e2f' name='salt' filepath='fs/namei.c' line='2088' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='fs/namei.c' line='2088' column='1'/>
         <return type-id='91ce1af9'/>
       </function-decl>
       <function-decl name='have_governor_per_policy' mangled-name='have_governor_per_policy' filepath='drivers/cpufreq/cpufreq.c' line='110' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='have_governor_per_policy'>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='hci_alloc_dev' mangled-name='hci_alloc_dev' filepath='net/bluetooth/hci_core.c' line='3589' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hci_alloc_dev'>
+      <function-decl name='hci_alloc_dev' mangled-name='hci_alloc_dev' filepath='net/bluetooth/hci_core.c' line='3590' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hci_alloc_dev'>
         <return type-id='9ad862e7'/>
       </function-decl>
-      <function-decl name='hci_cmd_sync' mangled-name='hci_cmd_sync' filepath='net/bluetooth/hci_core.c' line='4136' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hci_cmd_sync'>
-        <parameter type-id='9ad862e7' name='hdev' filepath='net/bluetooth/hci_core.c' line='4136' column='1'/>
-        <parameter type-id='1dc6a898' name='opcode' filepath='net/bluetooth/hci_core.c' line='4136' column='1'/>
-        <parameter type-id='19c2251e' name='plen' filepath='net/bluetooth/hci_core.c' line='4136' column='1'/>
-        <parameter type-id='eaa32e2f' name='param' filepath='net/bluetooth/hci_core.c' line='4137' column='1'/>
-        <parameter type-id='19c2251e' name='timeout' filepath='net/bluetooth/hci_core.c' line='4137' column='1'/>
+      <function-decl name='hci_cmd_sync' mangled-name='hci_cmd_sync' filepath='net/bluetooth/hci_core.c' line='4137' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hci_cmd_sync'>
+        <parameter type-id='9ad862e7' name='hdev' filepath='net/bluetooth/hci_core.c' line='4137' column='1'/>
+        <parameter type-id='1dc6a898' name='opcode' filepath='net/bluetooth/hci_core.c' line='4137' column='1'/>
+        <parameter type-id='19c2251e' name='plen' filepath='net/bluetooth/hci_core.c' line='4137' column='1'/>
+        <parameter type-id='eaa32e2f' name='param' filepath='net/bluetooth/hci_core.c' line='4138' column='1'/>
+        <parameter type-id='19c2251e' name='timeout' filepath='net/bluetooth/hci_core.c' line='4138' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
-      <function-decl name='hci_free_dev' mangled-name='hci_free_dev' filepath='net/bluetooth/hci_core.c' line='3701' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hci_free_dev'>
-        <parameter type-id='9ad862e7' name='hdev' filepath='net/bluetooth/hci_core.c' line='3701' column='1'/>
+      <function-decl name='hci_free_dev' mangled-name='hci_free_dev' filepath='net/bluetooth/hci_core.c' line='3702' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hci_free_dev'>
+        <parameter type-id='9ad862e7' name='hdev' filepath='net/bluetooth/hci_core.c' line='3702' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='hci_recv_diag' mangled-name='hci_recv_diag' filepath='net/bluetooth/hci_core.c' line='3965' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hci_recv_diag'>
-        <parameter type-id='9ad862e7' name='hdev' filepath='net/bluetooth/hci_core.c' line='3965' column='1'/>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/bluetooth/hci_core.c' line='3965' column='1'/>
+      <function-decl name='hci_recv_diag' mangled-name='hci_recv_diag' filepath='net/bluetooth/hci_core.c' line='3966' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hci_recv_diag'>
+        <parameter type-id='9ad862e7' name='hdev' filepath='net/bluetooth/hci_core.c' line='3966' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/bluetooth/hci_core.c' line='3966' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='hci_recv_frame' mangled-name='hci_recv_frame' filepath='net/bluetooth/hci_core.c' line='3935' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hci_recv_frame'>
-        <parameter type-id='9ad862e7' name='hdev' filepath='net/bluetooth/hci_core.c' line='3935' column='1'/>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/bluetooth/hci_core.c' line='3935' column='1'/>
+      <function-decl name='hci_recv_frame' mangled-name='hci_recv_frame' filepath='net/bluetooth/hci_core.c' line='3936' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hci_recv_frame'>
+        <parameter type-id='9ad862e7' name='hdev' filepath='net/bluetooth/hci_core.c' line='3936' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/bluetooth/hci_core.c' line='3936' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='hci_register_dev' mangled-name='hci_register_dev' filepath='net/bluetooth/hci_core.c' line='3709' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hci_register_dev'>
-        <parameter type-id='9ad862e7' name='hdev' filepath='net/bluetooth/hci_core.c' line='3709' column='1'/>
+      <function-decl name='hci_register_dev' mangled-name='hci_register_dev' filepath='net/bluetooth/hci_core.c' line='3710' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hci_register_dev'>
+        <parameter type-id='9ad862e7' name='hdev' filepath='net/bluetooth/hci_core.c' line='3710' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='hci_unregister_dev' mangled-name='hci_unregister_dev' filepath='net/bluetooth/hci_core.c' line='3825' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hci_unregister_dev'>
-        <parameter type-id='9ad862e7' name='hdev' filepath='net/bluetooth/hci_core.c' line='3825' column='1'/>
+      <function-decl name='hci_unregister_dev' mangled-name='hci_unregister_dev' filepath='net/bluetooth/hci_core.c' line='3826' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hci_unregister_dev'>
+        <parameter type-id='9ad862e7' name='hdev' filepath='net/bluetooth/hci_core.c' line='3826' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='hdmi_audio_infoframe_init' mangled-name='hdmi_audio_infoframe_init' filepath='drivers/video/hdmi.c' line='349' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hdmi_audio_infoframe_init'>
@@ -132551,71 +133235,71 @@
         <parameter type-id='002ac4a6' name='ch' filepath='lib/hexdump.c' line='53' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='hid_add_device' mangled-name='hid_add_device' filepath='drivers/hid/hid-core.c' line='2391' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_add_device'>
-        <parameter type-id='37175e4d' name='hdev' filepath='drivers/hid/hid-core.c' line='2391' column='1'/>
+      <function-decl name='hid_add_device' mangled-name='hid_add_device' filepath='drivers/hid/hid-core.c' line='2403' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_add_device'>
+        <parameter type-id='37175e4d' name='hdev' filepath='drivers/hid/hid-core.c' line='2403' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='hid_allocate_device' mangled-name='hid_allocate_device' filepath='drivers/hid/hid-core.c' line='2461' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_allocate_device'>
+      <function-decl name='hid_allocate_device' mangled-name='hid_allocate_device' filepath='drivers/hid/hid-core.c' line='2473' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_allocate_device'>
         <return type-id='37175e4d'/>
       </function-decl>
-      <var-decl name='hid_debug' type-id='95e97e5e' mangled-name='hid_debug' visibility='default' filepath='drivers/hid/hid-core.c' line='44' column='1' elf-symbol-id='hid_debug'/>
-      <function-decl name='hid_destroy_device' mangled-name='hid_destroy_device' filepath='drivers/hid/hid-core.c' line='2507' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_destroy_device'>
-        <parameter type-id='37175e4d' name='hdev' filepath='drivers/hid/hid-core.c' line='2507' column='1'/>
+      <var-decl name='hid_debug' type-id='95e97e5e' mangled-name='hid_debug' visibility='default' filepath='drivers/hid/hid-core.c' line='45' column='1' elf-symbol-id='hid_debug'/>
+      <function-decl name='hid_destroy_device' mangled-name='hid_destroy_device' filepath='drivers/hid/hid-core.c' line='2519' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_destroy_device'>
+        <parameter type-id='37175e4d' name='hdev' filepath='drivers/hid/hid-core.c' line='2519' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='hid_hw_close' mangled-name='hid_hw_close' filepath='drivers/hid/hid-core.c' line='2123' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_hw_close'>
-        <parameter type-id='37175e4d' name='hdev' filepath='drivers/hid/hid-core.c' line='2123' column='1'/>
+      <function-decl name='hid_hw_close' mangled-name='hid_hw_close' filepath='drivers/hid/hid-core.c' line='2135' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_hw_close'>
+        <parameter type-id='37175e4d' name='hdev' filepath='drivers/hid/hid-core.c' line='2135' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='hid_hw_open' mangled-name='hid_hw_open' filepath='drivers/hid/hid-core.c' line='2095' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_hw_open'>
-        <parameter type-id='37175e4d' name='hdev' filepath='drivers/hid/hid-core.c' line='2095' column='1'/>
+      <function-decl name='hid_hw_open' mangled-name='hid_hw_open' filepath='drivers/hid/hid-core.c' line='2107' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_hw_open'>
+        <parameter type-id='37175e4d' name='hdev' filepath='drivers/hid/hid-core.c' line='2107' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='hid_hw_start' mangled-name='hid_hw_start' filepath='drivers/hid/hid-core.c' line='2053' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_hw_start'>
-        <parameter type-id='37175e4d' name='hdev' filepath='drivers/hid/hid-core.c' line='2053' column='1'/>
-        <parameter type-id='f0981eeb' name='connect_mask' filepath='drivers/hid/hid-core.c' line='2053' column='1'/>
+      <function-decl name='hid_hw_start' mangled-name='hid_hw_start' filepath='drivers/hid/hid-core.c' line='2065' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_hw_start'>
+        <parameter type-id='37175e4d' name='hdev' filepath='drivers/hid/hid-core.c' line='2065' column='1'/>
+        <parameter type-id='f0981eeb' name='connect_mask' filepath='drivers/hid/hid-core.c' line='2065' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='hid_hw_stop' mangled-name='hid_hw_stop' filepath='drivers/hid/hid-core.c' line='2080' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_hw_stop'>
-        <parameter type-id='37175e4d' name='hdev' filepath='drivers/hid/hid-core.c' line='2080' column='1'/>
+      <function-decl name='hid_hw_stop' mangled-name='hid_hw_stop' filepath='drivers/hid/hid-core.c' line='2092' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_hw_stop'>
+        <parameter type-id='37175e4d' name='hdev' filepath='drivers/hid/hid-core.c' line='2092' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='hid_input_report' mangled-name='hid_input_report' filepath='drivers/hid/hid-core.c' line='1813' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_input_report'>
-        <parameter type-id='37175e4d' name='hid' filepath='drivers/hid/hid-core.c' line='1813' column='1'/>
-        <parameter type-id='95e97e5e' name='type' filepath='drivers/hid/hid-core.c' line='1813' column='1'/>
-        <parameter type-id='8bff8096' name='data' filepath='drivers/hid/hid-core.c' line='1813' column='1'/>
-        <parameter type-id='19c2251e' name='size' filepath='drivers/hid/hid-core.c' line='1813' column='1'/>
-        <parameter type-id='95e97e5e' name='interrupt' filepath='drivers/hid/hid-core.c' line='1813' column='1'/>
+      <function-decl name='hid_input_report' mangled-name='hid_input_report' filepath='drivers/hid/hid-core.c' line='1825' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_input_report'>
+        <parameter type-id='37175e4d' name='hid' filepath='drivers/hid/hid-core.c' line='1825' column='1'/>
+        <parameter type-id='95e97e5e' name='type' filepath='drivers/hid/hid-core.c' line='1825' column='1'/>
+        <parameter type-id='8bff8096' name='data' filepath='drivers/hid/hid-core.c' line='1825' column='1'/>
+        <parameter type-id='19c2251e' name='size' filepath='drivers/hid/hid-core.c' line='1825' column='1'/>
+        <parameter type-id='95e97e5e' name='interrupt' filepath='drivers/hid/hid-core.c' line='1825' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='hid_open_report' mangled-name='hid_open_report' filepath='drivers/hid/hid-core.c' line='1190' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_open_report'>
-        <parameter type-id='37175e4d' name='device' filepath='drivers/hid/hid-core.c' line='1190' column='1'/>
+      <function-decl name='hid_open_report' mangled-name='hid_open_report' filepath='drivers/hid/hid-core.c' line='1195' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_open_report'>
+        <parameter type-id='37175e4d' name='device' filepath='drivers/hid/hid-core.c' line='1195' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='hid_parse_report' mangled-name='hid_parse_report' filepath='drivers/hid/hid-core.c' line='937' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_parse_report'>
-        <parameter type-id='37175e4d' name='hid' filepath='drivers/hid/hid-core.c' line='937' column='1'/>
-        <parameter type-id='474e5dcc' name='start' filepath='drivers/hid/hid-core.c' line='937' column='1'/>
-        <parameter type-id='f0981eeb' name='size' filepath='drivers/hid/hid-core.c' line='937' column='1'/>
+      <function-decl name='hid_parse_report' mangled-name='hid_parse_report' filepath='drivers/hid/hid-core.c' line='942' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_parse_report'>
+        <parameter type-id='37175e4d' name='hid' filepath='drivers/hid/hid-core.c' line='942' column='1'/>
+        <parameter type-id='474e5dcc' name='start' filepath='drivers/hid/hid-core.c' line='942' column='1'/>
+        <parameter type-id='f0981eeb' name='size' filepath='drivers/hid/hid-core.c' line='942' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='hid_report_raw_event' mangled-name='hid_report_raw_event' filepath='drivers/hid/hid-core.c' line='1746' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_report_raw_event'>
-        <parameter type-id='37175e4d' name='hid' filepath='drivers/hid/hid-core.c' line='1746' column='1'/>
-        <parameter type-id='95e97e5e' name='type' filepath='drivers/hid/hid-core.c' line='1746' column='1'/>
-        <parameter type-id='8bff8096' name='data' filepath='drivers/hid/hid-core.c' line='1746' column='1'/>
-        <parameter type-id='19c2251e' name='size' filepath='drivers/hid/hid-core.c' line='1746' column='1'/>
-        <parameter type-id='95e97e5e' name='interrupt' filepath='drivers/hid/hid-core.c' line='1747' column='1'/>
+      <function-decl name='hid_report_raw_event' mangled-name='hid_report_raw_event' filepath='drivers/hid/hid-core.c' line='1754' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_report_raw_event'>
+        <parameter type-id='37175e4d' name='hid' filepath='drivers/hid/hid-core.c' line='1754' column='1'/>
+        <parameter type-id='95e97e5e' name='type' filepath='drivers/hid/hid-core.c' line='1754' column='1'/>
+        <parameter type-id='8bff8096' name='data' filepath='drivers/hid/hid-core.c' line='1754' column='1'/>
+        <parameter type-id='19c2251e' name='size' filepath='drivers/hid/hid-core.c' line='1754' column='1'/>
+        <parameter type-id='95e97e5e' name='interrupt' filepath='drivers/hid/hid-core.c' line='1755' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='hid_unregister_driver' mangled-name='hid_unregister_driver' filepath='drivers/hid/hid-core.c' line='2568' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_unregister_driver'>
-        <parameter type-id='cbd2074d' name='hdrv' filepath='drivers/hid/hid-core.c' line='2568' column='1'/>
+      <function-decl name='hid_unregister_driver' mangled-name='hid_unregister_driver' filepath='drivers/hid/hid-core.c' line='2580' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_unregister_driver'>
+        <parameter type-id='cbd2074d' name='hdrv' filepath='drivers/hid/hid-core.c' line='2580' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='hid_validate_values' mangled-name='hid_validate_values' filepath='drivers/hid/hid-core.c' line='964' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_validate_values'>
-        <parameter type-id='37175e4d' name='hid' filepath='drivers/hid/hid-core.c' line='964' column='1'/>
-        <parameter type-id='f0981eeb' name='type' filepath='drivers/hid/hid-core.c' line='965' column='1'/>
-        <parameter type-id='f0981eeb' name='id' filepath='drivers/hid/hid-core.c' line='965' column='1'/>
-        <parameter type-id='f0981eeb' name='field_index' filepath='drivers/hid/hid-core.c' line='966' column='1'/>
-        <parameter type-id='f0981eeb' name='report_counts' filepath='drivers/hid/hid-core.c' line='967' column='1'/>
+      <function-decl name='hid_validate_values' mangled-name='hid_validate_values' filepath='drivers/hid/hid-core.c' line='969' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='hid_validate_values'>
+        <parameter type-id='37175e4d' name='hid' filepath='drivers/hid/hid-core.c' line='969' column='1'/>
+        <parameter type-id='f0981eeb' name='type' filepath='drivers/hid/hid-core.c' line='970' column='1'/>
+        <parameter type-id='f0981eeb' name='id' filepath='drivers/hid/hid-core.c' line='970' column='1'/>
+        <parameter type-id='f0981eeb' name='field_index' filepath='drivers/hid/hid-core.c' line='971' column='1'/>
+        <parameter type-id='f0981eeb' name='report_counts' filepath='drivers/hid/hid-core.c' line='972' column='1'/>
         <return type-id='5b4284d1'/>
       </function-decl>
       <var-decl name='high_memory' type-id='eaa32e2f' mangled-name='high_memory' visibility='default' filepath='mm/memory.c' line='114' column='1' elf-symbol-id='high_memory'/>
@@ -133033,38 +133717,38 @@
         <parameter type-id='2448a865' name='dst_id' filepath='drivers/interconnect/core.c' line='724' column='1'/>
         <return type-id='b5fdec5e'/>
       </function-decl>
-      <function-decl name='icc_link_create' mangled-name='icc_link_create' filepath='drivers/interconnect/core.c' line='870' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_link_create'>
-        <parameter type-id='18d76f87' name='node' filepath='drivers/interconnect/core.c' line='870' column='1'/>
-        <parameter type-id='2448a865' name='dst_id' filepath='drivers/interconnect/core.c' line='870' column='1'/>
+      <function-decl name='icc_link_create' mangled-name='icc_link_create' filepath='drivers/interconnect/core.c' line='874' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_link_create'>
+        <parameter type-id='18d76f87' name='node' filepath='drivers/interconnect/core.c' line='874' column='1'/>
+        <parameter type-id='2448a865' name='dst_id' filepath='drivers/interconnect/core.c' line='874' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='icc_node_add' mangled-name='icc_node_add' filepath='drivers/interconnect/core.c' line='960' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_node_add'>
-        <parameter type-id='18d76f87' name='node' filepath='drivers/interconnect/core.c' line='960' column='1'/>
-        <parameter type-id='e68dc824' name='provider' filepath='drivers/interconnect/core.c' line='960' column='1'/>
+      <function-decl name='icc_node_add' mangled-name='icc_node_add' filepath='drivers/interconnect/core.c' line='964' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_node_add'>
+        <parameter type-id='18d76f87' name='node' filepath='drivers/interconnect/core.c' line='964' column='1'/>
+        <parameter type-id='e68dc824' name='provider' filepath='drivers/interconnect/core.c' line='964' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='icc_node_create' mangled-name='icc_node_create' filepath='drivers/interconnect/core.c' line='821' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_node_create'>
         <parameter type-id='95e97e5e' name='id' filepath='drivers/interconnect/core.c' line='821' column='1'/>
         <return type-id='18d76f87'/>
       </function-decl>
-      <function-decl name='icc_node_del' mangled-name='icc_node_del' filepath='drivers/interconnect/core.c' line='996' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_node_del'>
-        <parameter type-id='18d76f87' name='node' filepath='drivers/interconnect/core.c' line='996' column='1'/>
+      <function-decl name='icc_node_del' mangled-name='icc_node_del' filepath='drivers/interconnect/core.c' line='1000' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_node_del'>
+        <parameter type-id='18d76f87' name='node' filepath='drivers/interconnect/core.c' line='1000' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='icc_node_destroy' mangled-name='icc_node_destroy' filepath='drivers/interconnect/core.c' line='839' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_node_destroy'>
         <parameter type-id='95e97e5e' name='id' filepath='drivers/interconnect/core.c' line='839' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='icc_nodes_remove' mangled-name='icc_nodes_remove' filepath='drivers/interconnect/core.c' line='1012' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_nodes_remove'>
-        <parameter type-id='e68dc824' name='provider' filepath='drivers/interconnect/core.c' line='1012' column='1'/>
+      <function-decl name='icc_nodes_remove' mangled-name='icc_nodes_remove' filepath='drivers/interconnect/core.c' line='1016' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_nodes_remove'>
+        <parameter type-id='e68dc824' name='provider' filepath='drivers/interconnect/core.c' line='1016' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='icc_provider_add' mangled-name='icc_provider_add' filepath='drivers/interconnect/core.c' line='1034' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_provider_add'>
-        <parameter type-id='e68dc824' name='provider' filepath='drivers/interconnect/core.c' line='1034' column='1'/>
+      <function-decl name='icc_provider_add' mangled-name='icc_provider_add' filepath='drivers/interconnect/core.c' line='1038' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_provider_add'>
+        <parameter type-id='e68dc824' name='provider' filepath='drivers/interconnect/core.c' line='1038' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='icc_provider_del' mangled-name='icc_provider_del' filepath='drivers/interconnect/core.c' line='1060' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_provider_del'>
-        <parameter type-id='e68dc824' name='provider' filepath='drivers/interconnect/core.c' line='1060' column='1'/>
+      <function-decl name='icc_provider_del' mangled-name='icc_provider_del' filepath='drivers/interconnect/core.c' line='1064' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_provider_del'>
+        <parameter type-id='e68dc824' name='provider' filepath='drivers/interconnect/core.c' line='1064' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='icc_put' mangled-name='icc_put' filepath='drivers/interconnect/core.c' line='763' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_put'>
@@ -133091,8 +133775,8 @@
         <parameter type-id='f9409001' name='agg_peak' filepath='drivers/interconnect/core.c' line='312' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='icc_sync_state' mangled-name='icc_sync_state' filepath='drivers/interconnect/core.c' line='1102' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_sync_state'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/interconnect/core.c' line='1102' column='1'/>
+      <function-decl name='icc_sync_state' mangled-name='icc_sync_state' filepath='drivers/interconnect/core.c' line='1106' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='icc_sync_state'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/interconnect/core.c' line='1106' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='ida_alloc_range' mangled-name='ida_alloc_range' filepath='lib/idr.c' line='380' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ida_alloc_range'>
@@ -133203,26 +133887,26 @@
         <parameter type-id='b50a4934' name='ifs_handling' filepath='net/mac802154/util.c' line='59' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='iget5_locked' mangled-name='iget5_locked' filepath='fs/inode.c' line='1142' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iget5_locked'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/inode.c' line='1142' column='1'/>
-        <parameter type-id='7359adad' name='hashval' filepath='fs/inode.c' line='1142' column='1'/>
-        <parameter type-id='1b7a05dc' name='test' filepath='fs/inode.c' line='1143' column='1'/>
-        <parameter type-id='1b7a05dc' name='set' filepath='fs/inode.c' line='1144' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='fs/inode.c' line='1144' column='1'/>
+      <function-decl name='iget5_locked' mangled-name='iget5_locked' filepath='fs/inode.c' line='1184' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iget5_locked'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/inode.c' line='1184' column='1'/>
+        <parameter type-id='7359adad' name='hashval' filepath='fs/inode.c' line='1184' column='1'/>
+        <parameter type-id='1b7a05dc' name='test' filepath='fs/inode.c' line='1185' column='1'/>
+        <parameter type-id='1b7a05dc' name='set' filepath='fs/inode.c' line='1186' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='fs/inode.c' line='1186' column='1'/>
         <return type-id='7e666abe'/>
       </function-decl>
       <function-decl name='iget_failed' mangled-name='iget_failed' filepath='fs/bad_inode.c' line='238' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iget_failed'>
         <parameter type-id='7e666abe' name='inode' filepath='fs/bad_inode.c' line='238' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='iget_locked' mangled-name='iget_locked' filepath='fs/inode.c' line='1175' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iget_locked'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/inode.c' line='1175' column='1'/>
-        <parameter type-id='7359adad' name='ino' filepath='fs/inode.c' line='1175' column='1'/>
+      <function-decl name='iget_locked' mangled-name='iget_locked' filepath='fs/inode.c' line='1217' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iget_locked'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/inode.c' line='1217' column='1'/>
+        <parameter type-id='7359adad' name='ino' filepath='fs/inode.c' line='1217' column='1'/>
         <return type-id='7e666abe'/>
       </function-decl>
       <var-decl name='ignore_console_lock_warning' type-id='49178f86' mangled-name='ignore_console_lock_warning' visibility='default' filepath='kernel/printk/printk.c' line='74' column='1' elf-symbol-id='ignore_console_lock_warning'/>
-      <function-decl name='igrab' mangled-name='igrab' filepath='fs/inode.c' line='1294' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='igrab'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='1294' column='1'/>
+      <function-decl name='igrab' mangled-name='igrab' filepath='fs/inode.c' line='1336' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='igrab'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='1336' column='1'/>
         <return type-id='7e666abe'/>
       </function-decl>
       <function-decl name='ihold' mangled-name='ihold' filepath='fs/inode.c' line='421' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ihold'>
@@ -133356,8 +134040,21 @@
         <parameter type-id='26a90f95' name='buf' filepath='drivers/iio/industrialio-core.c' line='538' column='1'/>
         <return type-id='79a0948f'/>
       </function-decl>
+      <function-decl name='iio_trigger_alloc' mangled-name='iio_trigger_alloc' filepath='drivers/iio/industrialio-trigger.c' line='563' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iio_trigger_alloc'>
+        <parameter type-id='80f4b756' name='fmt' filepath='drivers/iio/industrialio-trigger.c' line='563' column='1'/>
+        <parameter is-variadic='yes'/>
+        <return type-id='54e54fbb'/>
+      </function-decl>
+      <function-decl name='iio_trigger_free' mangled-name='iio_trigger_free' filepath='drivers/iio/industrialio-trigger.c' line='576' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iio_trigger_free'>
+        <parameter type-id='54e54fbb' name='trig' filepath='drivers/iio/industrialio-trigger.c' line='576' column='1'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
       <function-decl name='iio_trigger_notify_done' mangled-name='iio_trigger_notify_done' filepath='drivers/iio/industrialio-trigger.c' line='203' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iio_trigger_notify_done'>
         <parameter type-id='54e54fbb' name='trig' filepath='drivers/iio/industrialio-trigger.c' line='203' column='1'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
+      <function-decl name='iio_trigger_unregister' mangled-name='iio_trigger_unregister' filepath='drivers/iio/industrialio-trigger.c' line='106' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iio_trigger_unregister'>
+        <parameter type-id='54e54fbb' name='trig_info' filepath='drivers/iio/industrialio-trigger.c' line='106' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='iio_update_buffers' mangled-name='iio_update_buffers' filepath='drivers/iio/industrialio-buffer.c' line='1113' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iio_update_buffers'>
@@ -133371,25 +134068,25 @@
         <parameter type-id='95e97e5e' name='val' filepath='drivers/iio/inkern.c' line='878' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ilookup' mangled-name='ilookup' filepath='fs/inode.c' line='1385' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ilookup'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/inode.c' line='1385' column='1'/>
-        <parameter type-id='7359adad' name='ino' filepath='fs/inode.c' line='1385' column='1'/>
+      <function-decl name='ilookup' mangled-name='ilookup' filepath='fs/inode.c' line='1427' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ilookup'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/inode.c' line='1427' column='1'/>
+        <parameter type-id='7359adad' name='ino' filepath='fs/inode.c' line='1427' column='1'/>
         <return type-id='7e666abe'/>
       </function-decl>
-      <function-decl name='ilookup5' mangled-name='ilookup5' filepath='fs/inode.c' line='1360' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ilookup5'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/inode.c' line='1360' column='1'/>
-        <parameter type-id='7359adad' name='hashval' filepath='fs/inode.c' line='1360' column='1'/>
-        <parameter type-id='1b7a05dc' name='test' filepath='fs/inode.c' line='1361' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='fs/inode.c' line='1361' column='1'/>
+      <function-decl name='ilookup5' mangled-name='ilookup5' filepath='fs/inode.c' line='1402' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ilookup5'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/inode.c' line='1402' column='1'/>
+        <parameter type-id='7359adad' name='hashval' filepath='fs/inode.c' line='1402' column='1'/>
+        <parameter type-id='1b7a05dc' name='test' filepath='fs/inode.c' line='1403' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='fs/inode.c' line='1403' column='1'/>
         <return type-id='7e666abe'/>
       </function-decl>
-      <function-decl name='import_iovec' mangled-name='import_iovec' filepath='lib/iov_iter.c' line='1815' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='import_iovec'>
-        <parameter type-id='95e97e5e' name='type' filepath='lib/iov_iter.c' line='1815' column='1'/>
-        <parameter type-id='2c556848' name='uvec' filepath='lib/iov_iter.c' line='1815' column='1'/>
-        <parameter type-id='f0981eeb' name='nr_segs' filepath='lib/iov_iter.c' line='1816' column='1'/>
-        <parameter type-id='f0981eeb' name='fast_segs' filepath='lib/iov_iter.c' line='1816' column='1'/>
-        <parameter type-id='5d3cb3f9' name='iovp' filepath='lib/iov_iter.c' line='1817' column='1'/>
-        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='1817' column='1'/>
+      <function-decl name='import_iovec' mangled-name='import_iovec' filepath='lib/iov_iter.c' line='1801' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='import_iovec'>
+        <parameter type-id='95e97e5e' name='type' filepath='lib/iov_iter.c' line='1801' column='1'/>
+        <parameter type-id='2c556848' name='uvec' filepath='lib/iov_iter.c' line='1801' column='1'/>
+        <parameter type-id='f0981eeb' name='nr_segs' filepath='lib/iov_iter.c' line='1802' column='1'/>
+        <parameter type-id='f0981eeb' name='fast_segs' filepath='lib/iov_iter.c' line='1802' column='1'/>
+        <parameter type-id='5d3cb3f9' name='iovp' filepath='lib/iov_iter.c' line='1803' column='1'/>
+        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='1803' column='1'/>
         <return type-id='79a0948f'/>
       </function-decl>
       <function-decl name='in4_pton' mangled-name='in4_pton' filepath='net/core/utils.c' line='118' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='in4_pton'>
@@ -133438,9 +134135,9 @@
         <parameter type-id='a1f2d9a1' name='item' filepath='mm/vmstat.c' line='534' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='inet_csk_get_port' mangled-name='inet_csk_get_port' filepath='net/ipv4/inet_connection_sock.c' line='354' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inet_csk_get_port'>
-        <parameter type-id='f772df6d' name='sk' filepath='net/ipv4/inet_connection_sock.c' line='354' column='1'/>
-        <parameter type-id='8efea9e5' name='snum' filepath='net/ipv4/inet_connection_sock.c' line='354' column='1'/>
+      <function-decl name='inet_csk_get_port' mangled-name='inet_csk_get_port' filepath='net/ipv4/inet_connection_sock.c' line='358' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inet_csk_get_port'>
+        <parameter type-id='f772df6d' name='sk' filepath='net/ipv4/inet_connection_sock.c' line='358' column='1'/>
+        <parameter type-id='8efea9e5' name='snum' filepath='net/ipv4/inet_connection_sock.c' line='358' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='inet_proto_csum_replace4' mangled-name='inet_proto_csum_replace4' filepath='net/core/utils.c' line='425' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inet_proto_csum_replace4'>
@@ -133451,8 +134148,8 @@
         <parameter type-id='b50a4934' name='pseudohdr' filepath='net/core/utils.c' line='426' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='init_dummy_netdev' mangled-name='init_dummy_netdev' filepath='net/core/dev.c' line='10090' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='init_dummy_netdev'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10090' column='1'/>
+      <function-decl name='init_dummy_netdev' mangled-name='init_dummy_netdev' filepath='net/core/dev.c' line='10097' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='init_dummy_netdev'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10097' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='init_iova_domain' mangled-name='init_iova_domain' filepath='drivers/iommu/iova.c' line='30' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='init_iova_domain'>
@@ -133469,10 +134166,10 @@
         <parameter type-id='7359adad' name='magic' filepath='fs/libfs.c' line='369' column='1'/>
         <return type-id='79f85ebf'/>
       </function-decl>
-      <function-decl name='init_special_inode' mangled-name='init_special_inode' filepath='fs/inode.c' line='2114' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='init_special_inode'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2114' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/inode.c' line='2114' column='1'/>
-        <parameter type-id='8504f260' name='rdev' filepath='fs/inode.c' line='2114' column='1'/>
+      <function-decl name='init_special_inode' mangled-name='init_special_inode' filepath='fs/inode.c' line='2127' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='init_special_inode'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2127' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/inode.c' line='2127' column='1'/>
+        <parameter type-id='8504f260' name='rdev' filepath='fs/inode.c' line='2127' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='init_srcu_struct' mangled-name='init_srcu_struct' filepath='kernel/rcu/srcutree.c' line='213' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='init_srcu_struct'>
@@ -133494,31 +134191,31 @@
         <parameter type-id='95e97e5e' name='flags' filepath='kernel/sched/wait.c' line='282' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='inode_dio_wait' mangled-name='inode_dio_wait' filepath='fs/inode.c' line='2207' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inode_dio_wait'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2207' column='1'/>
+      <function-decl name='inode_dio_wait' mangled-name='inode_dio_wait' filepath='fs/inode.c' line='2216' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inode_dio_wait'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2216' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='inode_init_once' mangled-name='inode_init_once' filepath='fs/inode.c' line='390' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inode_init_once'>
         <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='390' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='inode_init_owner' mangled-name='inode_init_owner' filepath='fs/inode.c' line='2140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inode_init_owner'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2140' column='1'/>
-        <parameter type-id='c5a4eb7f' name='dir' filepath='fs/inode.c' line='2140' column='1'/>
-        <parameter type-id='2594b00f' name='mode' filepath='fs/inode.c' line='2141' column='1'/>
+      <function-decl name='inode_init_owner' mangled-name='inode_init_owner' filepath='fs/inode.c' line='2153' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inode_init_owner'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2153' column='1'/>
+        <parameter type-id='c5a4eb7f' name='dir' filepath='fs/inode.c' line='2153' column='1'/>
+        <parameter type-id='2594b00f' name='mode' filepath='fs/inode.c' line='2154' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='inode_newsize_ok' mangled-name='inode_newsize_ok' filepath='fs/attr.c' line='135' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inode_newsize_ok'>
-        <parameter type-id='c5a4eb7f' name='inode' filepath='fs/attr.c' line='135' column='1'/>
-        <parameter type-id='69bf7bee' name='offset' filepath='fs/attr.c' line='135' column='1'/>
+      <function-decl name='inode_newsize_ok' mangled-name='inode_newsize_ok' filepath='fs/attr.c' line='193' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inode_newsize_ok'>
+        <parameter type-id='c5a4eb7f' name='inode' filepath='fs/attr.c' line='193' column='1'/>
+        <parameter type-id='69bf7bee' name='offset' filepath='fs/attr.c' line='193' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='inode_nohighmem' mangled-name='inode_nohighmem' filepath='fs/inode.c' line='2238' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inode_nohighmem'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2238' column='1'/>
+      <function-decl name='inode_nohighmem' mangled-name='inode_nohighmem' filepath='fs/inode.c' line='2247' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inode_nohighmem'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2247' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='inode_owner_or_capable' mangled-name='inode_owner_or_capable' filepath='fs/inode.c' line='2167' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inode_owner_or_capable'>
-        <parameter type-id='c5a4eb7f' name='inode' filepath='fs/inode.c' line='2167' column='1'/>
+      <function-decl name='inode_owner_or_capable' mangled-name='inode_owner_or_capable' filepath='fs/inode.c' line='2176' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inode_owner_or_capable'>
+        <parameter type-id='c5a4eb7f' name='inode' filepath='fs/inode.c' line='2176' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='inode_permission' mangled-name='inode_permission' filepath='fs/namei.c' line='442' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inode_permission'>
@@ -133526,10 +134223,10 @@
         <parameter type-id='95e97e5e' name='mask' filepath='fs/namei.c' line='442' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='inode_set_flags' mangled-name='inode_set_flags' filepath='fs/inode.c' line='2230' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inode_set_flags'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2230' column='1'/>
-        <parameter type-id='f0981eeb' name='flags' filepath='fs/inode.c' line='2230' column='1'/>
-        <parameter type-id='f0981eeb' name='mask' filepath='fs/inode.c' line='2231' column='1'/>
+      <function-decl name='inode_set_flags' mangled-name='inode_set_flags' filepath='fs/inode.c' line='2239' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='inode_set_flags'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2239' column='1'/>
+        <parameter type-id='f0981eeb' name='flags' filepath='fs/inode.c' line='2239' column='1'/>
+        <parameter type-id='f0981eeb' name='mask' filepath='fs/inode.c' line='2240' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='input_alloc_absinfo' mangled-name='input_alloc_absinfo' filepath='drivers/input/input.c' line='497' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='input_alloc_absinfo'>
@@ -133669,8 +134366,8 @@
         <parameter type-id='4938abae' name='handler' filepath='drivers/input/input.c' line='2336' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='insert_inode_locked' mangled-name='insert_inode_locked' filepath='fs/inode.c' line='1535' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='insert_inode_locked'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='1535' column='1'/>
+      <function-decl name='insert_inode_locked' mangled-name='insert_inode_locked' filepath='fs/inode.c' line='1577' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='insert_inode_locked'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='1577' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='int_pow' mangled-name='int_pow' filepath='lib/math/int_pow.c' line='19' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='int_pow'>
@@ -133714,64 +134411,64 @@
         <parameter type-id='7359adad' name='end' filepath='mm/truncate.c' line='630' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='io_schedule' mangled-name='io_schedule' filepath='kernel/sched/core.c' line='6557' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='io_schedule'>
+      <function-decl name='io_schedule' mangled-name='io_schedule' filepath='kernel/sched/core.c' line='6559' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='io_schedule'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='io_schedule_timeout' mangled-name='io_schedule_timeout' filepath='kernel/sched/core.c' line='6544' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='io_schedule_timeout'>
-        <parameter type-id='bd54fe1a' name='timeout' filepath='kernel/sched/core.c' line='6544' column='1'/>
+      <function-decl name='io_schedule_timeout' mangled-name='io_schedule_timeout' filepath='kernel/sched/core.c' line='6546' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='io_schedule_timeout'>
+        <parameter type-id='bd54fe1a' name='timeout' filepath='kernel/sched/core.c' line='6546' column='1'/>
         <return type-id='bd54fe1a'/>
       </function-decl>
       <var-decl name='iomem_resource' type-id='5218160d' mangled-name='iomem_resource' visibility='default' filepath='kernel/resource.c' line='38' column='1' elf-symbol-id='iomem_resource'/>
-      <function-decl name='iommu_alloc_resv_region' mangled-name='iommu_alloc_resv_region' filepath='drivers/iommu/iommu.c' line='2828' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_alloc_resv_region'>
-        <parameter type-id='2522883d' name='start' filepath='drivers/iommu/iommu.c' line='2828' column='1'/>
-        <parameter type-id='b59d7dce' name='length' filepath='drivers/iommu/iommu.c' line='2829' column='1'/>
-        <parameter type-id='95e97e5e' name='prot' filepath='drivers/iommu/iommu.c' line='2829' column='1'/>
-        <parameter type-id='256c2037' name='type' filepath='drivers/iommu/iommu.c' line='2830' column='1'/>
+      <function-decl name='iommu_alloc_resv_region' mangled-name='iommu_alloc_resv_region' filepath='drivers/iommu/iommu.c' line='2844' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_alloc_resv_region'>
+        <parameter type-id='2522883d' name='start' filepath='drivers/iommu/iommu.c' line='2844' column='1'/>
+        <parameter type-id='b59d7dce' name='length' filepath='drivers/iommu/iommu.c' line='2845' column='1'/>
+        <parameter type-id='95e97e5e' name='prot' filepath='drivers/iommu/iommu.c' line='2845' column='1'/>
+        <parameter type-id='256c2037' name='type' filepath='drivers/iommu/iommu.c' line='2846' column='1'/>
         <return type-id='24b0cc5e'/>
       </function-decl>
-      <function-decl name='iommu_attach_device' mangled-name='iommu_attach_device' filepath='drivers/iommu/iommu.c' line='1950' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_attach_device'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='1950' column='1'/>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='1950' column='1'/>
+      <function-decl name='iommu_attach_device' mangled-name='iommu_attach_device' filepath='drivers/iommu/iommu.c' line='1966' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_attach_device'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='1966' column='1'/>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='1966' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_attach_group' mangled-name='iommu_attach_group' filepath='drivers/iommu/iommu.c' line='2282' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_attach_group'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2282' column='1'/>
-        <parameter type-id='0b19fc54' name='group' filepath='drivers/iommu/iommu.c' line='2282' column='1'/>
+      <function-decl name='iommu_attach_group' mangled-name='iommu_attach_group' filepath='drivers/iommu/iommu.c' line='2298' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_attach_group'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2298' column='1'/>
+        <parameter type-id='0b19fc54' name='group' filepath='drivers/iommu/iommu.c' line='2298' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_aux_attach_device' mangled-name='iommu_aux_attach_device' filepath='drivers/iommu/iommu.c' line='3014' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_aux_attach_device'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='3014' column='1'/>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='3014' column='1'/>
+      <function-decl name='iommu_aux_attach_device' mangled-name='iommu_aux_attach_device' filepath='drivers/iommu/iommu.c' line='3030' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_aux_attach_device'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='3030' column='1'/>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='3030' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_aux_detach_device' mangled-name='iommu_aux_detach_device' filepath='drivers/iommu/iommu.c' line='3028' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_aux_detach_device'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='3028' column='1'/>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='3028' column='1'/>
+      <function-decl name='iommu_aux_detach_device' mangled-name='iommu_aux_detach_device' filepath='drivers/iommu/iommu.c' line='3044' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_aux_detach_device'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='3044' column='1'/>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='3044' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='iommu_aux_get_pasid' mangled-name='iommu_aux_get_pasid' filepath='drivers/iommu/iommu.c' line='3037' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_aux_get_pasid'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='3037' column='1'/>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='3037' column='1'/>
+      <function-decl name='iommu_aux_get_pasid' mangled-name='iommu_aux_get_pasid' filepath='drivers/iommu/iommu.c' line='3053' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_aux_get_pasid'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='3053' column='1'/>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='3053' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_detach_device' mangled-name='iommu_detach_device' filepath='drivers/iommu/iommu.c' line='2201' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_detach_device'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2201' column='1'/>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='2201' column='1'/>
+      <function-decl name='iommu_detach_device' mangled-name='iommu_detach_device' filepath='drivers/iommu/iommu.c' line='2217' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_detach_device'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2217' column='1'/>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='2217' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='iommu_detach_group' mangled-name='iommu_detach_group' filepath='drivers/iommu/iommu.c' line='2327' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_detach_group'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2327' column='1'/>
-        <parameter type-id='0b19fc54' name='group' filepath='drivers/iommu/iommu.c' line='2327' column='1'/>
+      <function-decl name='iommu_detach_group' mangled-name='iommu_detach_group' filepath='drivers/iommu/iommu.c' line='2343' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_detach_group'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2343' column='1'/>
+        <parameter type-id='0b19fc54' name='group' filepath='drivers/iommu/iommu.c' line='2343' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='iommu_dev_enable_feature' mangled-name='iommu_dev_enable_feature' filepath='drivers/iommu/iommu.c' line='2960' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_dev_enable_feature'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='2960' column='1'/>
-        <parameter type-id='29d28711' name='feat' filepath='drivers/iommu/iommu.c' line='2960' column='1'/>
+      <function-decl name='iommu_dev_enable_feature' mangled-name='iommu_dev_enable_feature' filepath='drivers/iommu/iommu.c' line='2976' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_dev_enable_feature'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='2976' column='1'/>
+        <parameter type-id='29d28711' name='feat' filepath='drivers/iommu/iommu.c' line='2976' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_dev_feature_enabled' mangled-name='iommu_dev_feature_enabled' filepath='drivers/iommu/iommu.c' line='2991' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_dev_feature_enabled'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='2991' column='1'/>
-        <parameter type-id='29d28711' name='feat' filepath='drivers/iommu/iommu.c' line='2991' column='1'/>
+      <function-decl name='iommu_dev_feature_enabled' mangled-name='iommu_dev_feature_enabled' filepath='drivers/iommu/iommu.c' line='3007' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_dev_feature_enabled'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='3007' column='1'/>
+        <parameter type-id='29d28711' name='feat' filepath='drivers/iommu/iommu.c' line='3007' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='iommu_device_register' mangled-name='iommu_device_register' filepath='drivers/iommu/iommu.c' line='154' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_device_register'>
@@ -133814,42 +134511,42 @@
         <parameter type-id='91ce1af9' name='size' filepath='drivers/iommu/dma-iommu.c' line='398' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_domain_alloc' mangled-name='iommu_domain_alloc' filepath='drivers/iommu/iommu.c' line='1924' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_domain_alloc'>
-        <parameter type-id='5e2671f8' name='bus' filepath='drivers/iommu/iommu.c' line='1924' column='1'/>
+      <function-decl name='iommu_domain_alloc' mangled-name='iommu_domain_alloc' filepath='drivers/iommu/iommu.c' line='1940' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_domain_alloc'>
+        <parameter type-id='5e2671f8' name='bus' filepath='drivers/iommu/iommu.c' line='1940' column='1'/>
         <return type-id='bff05edb'/>
       </function-decl>
-      <function-decl name='iommu_domain_free' mangled-name='iommu_domain_free' filepath='drivers/iommu/iommu.c' line='1930' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_domain_free'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='1930' column='1'/>
+      <function-decl name='iommu_domain_free' mangled-name='iommu_domain_free' filepath='drivers/iommu/iommu.c' line='1946' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_domain_free'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='1946' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='iommu_domain_get_attr' mangled-name='iommu_domain_get_attr' filepath='drivers/iommu/iommu.c' line='2748' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_domain_get_attr'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2748' column='1'/>
-        <parameter type-id='e176cc45' name='attr' filepath='drivers/iommu/iommu.c' line='2749' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/iommu/iommu.c' line='2749' column='1'/>
+      <function-decl name='iommu_domain_get_attr' mangled-name='iommu_domain_get_attr' filepath='drivers/iommu/iommu.c' line='2764' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_domain_get_attr'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2764' column='1'/>
+        <parameter type-id='e176cc45' name='attr' filepath='drivers/iommu/iommu.c' line='2765' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/iommu/iommu.c' line='2765' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_domain_set_attr' mangled-name='iommu_domain_set_attr' filepath='drivers/iommu/iommu.c' line='2776' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_domain_set_attr'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2776' column='1'/>
-        <parameter type-id='e176cc45' name='attr' filepath='drivers/iommu/iommu.c' line='2777' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/iommu/iommu.c' line='2777' column='1'/>
+      <function-decl name='iommu_domain_set_attr' mangled-name='iommu_domain_set_attr' filepath='drivers/iommu/iommu.c' line='2792' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_domain_set_attr'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2792' column='1'/>
+        <parameter type-id='e176cc45' name='attr' filepath='drivers/iommu/iommu.c' line='2793' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/iommu/iommu.c' line='2793' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_fwspec_add_ids' mangled-name='iommu_fwspec_add_ids' filepath='drivers/iommu/iommu.c' line='2920' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_fwspec_add_ids'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='2920' column='1'/>
-        <parameter type-id='f9409001' name='ids' filepath='drivers/iommu/iommu.c' line='2920' column='1'/>
-        <parameter type-id='95e97e5e' name='num_ids' filepath='drivers/iommu/iommu.c' line='2920' column='1'/>
+      <function-decl name='iommu_fwspec_add_ids' mangled-name='iommu_fwspec_add_ids' filepath='drivers/iommu/iommu.c' line='2936' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_fwspec_add_ids'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='2936' column='1'/>
+        <parameter type-id='f9409001' name='ids' filepath='drivers/iommu/iommu.c' line='2936' column='1'/>
+        <parameter type-id='95e97e5e' name='num_ids' filepath='drivers/iommu/iommu.c' line='2936' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_fwspec_free' mangled-name='iommu_fwspec_free' filepath='drivers/iommu/iommu.c' line='2908' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_fwspec_free'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='2908' column='1'/>
+      <function-decl name='iommu_fwspec_free' mangled-name='iommu_fwspec_free' filepath='drivers/iommu/iommu.c' line='2924' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_fwspec_free'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='2924' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='iommu_get_dma_cookie' mangled-name='iommu_get_dma_cookie' filepath='drivers/iommu/dma-iommu.c' line='85' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_get_dma_cookie'>
         <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/dma-iommu.c' line='85' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_get_domain_for_dev' mangled-name='iommu_get_domain_for_dev' filepath='drivers/iommu/iommu.c' line='2223' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_get_domain_for_dev'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='2223' column='1'/>
+      <function-decl name='iommu_get_domain_for_dev' mangled-name='iommu_get_domain_for_dev' filepath='drivers/iommu/iommu.c' line='2239' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_get_domain_for_dev'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='2239' column='1'/>
         <return type-id='bff05edb'/>
       </function-decl>
       <function-decl name='iommu_get_msi_cookie' mangled-name='iommu_get_msi_cookie' filepath='drivers/iommu/dma-iommu.c' line='110' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_get_msi_cookie'>
@@ -133857,100 +134554,100 @@
         <parameter type-id='cf29c9b3' name='base' filepath='drivers/iommu/dma-iommu.c' line='110' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_group_alloc' mangled-name='iommu_group_alloc' filepath='drivers/iommu/iommu.c' line='575' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_alloc'>
+      <function-decl name='iommu_group_alloc' mangled-name='iommu_group_alloc' filepath='drivers/iommu/iommu.c' line='591' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_alloc'>
         <return type-id='0b19fc54'/>
       </function-decl>
-      <function-decl name='iommu_group_for_each_dev' mangled-name='iommu_group_for_each_dev' filepath='drivers/iommu/iommu.c' line='962' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_for_each_dev'>
-        <parameter type-id='0b19fc54' name='group' filepath='drivers/iommu/iommu.c' line='962' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/iommu/iommu.c' line='962' column='1'/>
-        <parameter type-id='92d15ae9' name='fn' filepath='drivers/iommu/iommu.c' line='963' column='1'/>
+      <function-decl name='iommu_group_for_each_dev' mangled-name='iommu_group_for_each_dev' filepath='drivers/iommu/iommu.c' line='978' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_for_each_dev'>
+        <parameter type-id='0b19fc54' name='group' filepath='drivers/iommu/iommu.c' line='978' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/iommu/iommu.c' line='978' column='1'/>
+        <parameter type-id='92d15ae9' name='fn' filepath='drivers/iommu/iommu.c' line='979' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_group_get' mangled-name='iommu_group_get' filepath='drivers/iommu/iommu.c' line='983' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_get'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='983' column='1'/>
+      <function-decl name='iommu_group_get' mangled-name='iommu_group_get' filepath='drivers/iommu/iommu.c' line='999' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_get'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='999' column='1'/>
         <return type-id='0b19fc54'/>
       </function-decl>
-      <function-decl name='iommu_group_get_iommudata' mangled-name='iommu_group_get_iommudata' filepath='drivers/iommu/iommu.c' line='670' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_get_iommudata'>
-        <parameter type-id='0b19fc54' name='group' filepath='drivers/iommu/iommu.c' line='670' column='1'/>
+      <function-decl name='iommu_group_get_iommudata' mangled-name='iommu_group_get_iommudata' filepath='drivers/iommu/iommu.c' line='686' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_get_iommudata'>
+        <parameter type-id='0b19fc54' name='group' filepath='drivers/iommu/iommu.c' line='686' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='iommu_group_put' mangled-name='iommu_group_put' filepath='drivers/iommu/iommu.c' line='1015' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_put'>
-        <parameter type-id='0b19fc54' name='group' filepath='drivers/iommu/iommu.c' line='1015' column='1'/>
+      <function-decl name='iommu_group_put' mangled-name='iommu_group_put' filepath='drivers/iommu/iommu.c' line='1031' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_put'>
+        <parameter type-id='0b19fc54' name='group' filepath='drivers/iommu/iommu.c' line='1031' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='iommu_group_ref_get' mangled-name='iommu_group_ref_get' filepath='drivers/iommu/iommu.c' line='1001' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_ref_get'>
-        <parameter type-id='0b19fc54' name='group' filepath='drivers/iommu/iommu.c' line='1001' column='1'/>
+      <function-decl name='iommu_group_ref_get' mangled-name='iommu_group_ref_get' filepath='drivers/iommu/iommu.c' line='1017' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_ref_get'>
+        <parameter type-id='0b19fc54' name='group' filepath='drivers/iommu/iommu.c' line='1017' column='1'/>
         <return type-id='0b19fc54'/>
       </function-decl>
-      <function-decl name='iommu_group_remove_device' mangled-name='iommu_group_remove_device' filepath='drivers/iommu/iommu.c' line='886' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_remove_device'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='886' column='1'/>
+      <function-decl name='iommu_group_remove_device' mangled-name='iommu_group_remove_device' filepath='drivers/iommu/iommu.c' line='902' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_remove_device'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='902' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='iommu_group_set_iommudata' mangled-name='iommu_group_set_iommudata' filepath='drivers/iommu/iommu.c' line='686' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_set_iommudata'>
-        <parameter type-id='0b19fc54' name='group' filepath='drivers/iommu/iommu.c' line='686' column='1'/>
-        <parameter type-id='eaa32e2f' name='iommu_data' filepath='drivers/iommu/iommu.c' line='686' column='1'/>
-        <parameter type-id='b7f9d8e6' name='release' filepath='drivers/iommu/iommu.c' line='687' column='1'/>
-        <return type-id='48b5725f'/>
-      </function-decl>
-      <function-decl name='iommu_group_set_name' mangled-name='iommu_group_set_name' filepath='drivers/iommu/iommu.c' line='702' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_set_name'>
+      <function-decl name='iommu_group_set_iommudata' mangled-name='iommu_group_set_iommudata' filepath='drivers/iommu/iommu.c' line='702' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_set_iommudata'>
         <parameter type-id='0b19fc54' name='group' filepath='drivers/iommu/iommu.c' line='702' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='drivers/iommu/iommu.c' line='702' column='1'/>
+        <parameter type-id='eaa32e2f' name='iommu_data' filepath='drivers/iommu/iommu.c' line='702' column='1'/>
+        <parameter type-id='b7f9d8e6' name='release' filepath='drivers/iommu/iommu.c' line='703' column='1'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
+      <function-decl name='iommu_group_set_name' mangled-name='iommu_group_set_name' filepath='drivers/iommu/iommu.c' line='718' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_group_set_name'>
+        <parameter type-id='0b19fc54' name='group' filepath='drivers/iommu/iommu.c' line='718' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='drivers/iommu/iommu.c' line='718' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_iova_to_phys' mangled-name='iommu_iova_to_phys' filepath='drivers/iommu/iommu.c' line='2335' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_iova_to_phys'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2335' column='1'/>
-        <parameter type-id='cf29c9b3' name='iova' filepath='drivers/iommu/iommu.c' line='2335' column='1'/>
+      <function-decl name='iommu_iova_to_phys' mangled-name='iommu_iova_to_phys' filepath='drivers/iommu/iommu.c' line='2351' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_iova_to_phys'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2351' column='1'/>
+        <parameter type-id='cf29c9b3' name='iova' filepath='drivers/iommu/iommu.c' line='2351' column='1'/>
         <return type-id='2522883d'/>
       </function-decl>
-      <function-decl name='iommu_map' mangled-name='iommu_map' filepath='drivers/iommu/iommu.c' line='2496' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_map'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2496' column='1'/>
-        <parameter type-id='7359adad' name='iova' filepath='drivers/iommu/iommu.c' line='2496' column='1'/>
-        <parameter type-id='2522883d' name='paddr' filepath='drivers/iommu/iommu.c' line='2497' column='1'/>
-        <parameter type-id='b59d7dce' name='size' filepath='drivers/iommu/iommu.c' line='2497' column='1'/>
-        <parameter type-id='95e97e5e' name='prot' filepath='drivers/iommu/iommu.c' line='2497' column='1'/>
+      <function-decl name='iommu_map' mangled-name='iommu_map' filepath='drivers/iommu/iommu.c' line='2512' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_map'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2512' column='1'/>
+        <parameter type-id='7359adad' name='iova' filepath='drivers/iommu/iommu.c' line='2512' column='1'/>
+        <parameter type-id='2522883d' name='paddr' filepath='drivers/iommu/iommu.c' line='2513' column='1'/>
+        <parameter type-id='b59d7dce' name='size' filepath='drivers/iommu/iommu.c' line='2513' column='1'/>
+        <parameter type-id='95e97e5e' name='prot' filepath='drivers/iommu/iommu.c' line='2513' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_map_sg' mangled-name='iommu_map_sg' filepath='drivers/iommu/iommu.c' line='2659' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_map_sg'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2659' column='1'/>
-        <parameter type-id='7359adad' name='iova' filepath='drivers/iommu/iommu.c' line='2659' column='1'/>
-        <parameter type-id='bf3ef905' name='sg' filepath='drivers/iommu/iommu.c' line='2660' column='1'/>
-        <parameter type-id='f0981eeb' name='nents' filepath='drivers/iommu/iommu.c' line='2660' column='1'/>
-        <parameter type-id='95e97e5e' name='prot' filepath='drivers/iommu/iommu.c' line='2660' column='1'/>
+      <function-decl name='iommu_map_sg' mangled-name='iommu_map_sg' filepath='drivers/iommu/iommu.c' line='2675' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_map_sg'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2675' column='1'/>
+        <parameter type-id='7359adad' name='iova' filepath='drivers/iommu/iommu.c' line='2675' column='1'/>
+        <parameter type-id='bf3ef905' name='sg' filepath='drivers/iommu/iommu.c' line='2676' column='1'/>
+        <parameter type-id='f0981eeb' name='nents' filepath='drivers/iommu/iommu.c' line='2676' column='1'/>
+        <parameter type-id='95e97e5e' name='prot' filepath='drivers/iommu/iommu.c' line='2676' column='1'/>
         <return type-id='b59d7dce'/>
       </function-decl>
-      <function-decl name='iommu_present' mangled-name='iommu_present' filepath='drivers/iommu/iommu.c' line='1866' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_present'>
-        <parameter type-id='5e2671f8' name='bus' filepath='drivers/iommu/iommu.c' line='1866' column='1'/>
+      <function-decl name='iommu_present' mangled-name='iommu_present' filepath='drivers/iommu/iommu.c' line='1882' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_present'>
+        <parameter type-id='5e2671f8' name='bus' filepath='drivers/iommu/iommu.c' line='1882' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='iommu_put_dma_cookie' mangled-name='iommu_put_dma_cookie' filepath='drivers/iommu/dma-iommu.c' line='137' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_put_dma_cookie'>
         <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/dma-iommu.c' line='137' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='iommu_register_device_fault_handler' mangled-name='iommu_register_device_fault_handler' filepath='drivers/iommu/iommu.c' line='1070' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_register_device_fault_handler'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='1070' column='1'/>
-        <parameter type-id='a84f5b46' name='handler' filepath='drivers/iommu/iommu.c' line='1071' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/iommu/iommu.c' line='1072' column='1'/>
+      <function-decl name='iommu_register_device_fault_handler' mangled-name='iommu_register_device_fault_handler' filepath='drivers/iommu/iommu.c' line='1086' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_register_device_fault_handler'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='1086' column='1'/>
+        <parameter type-id='a84f5b46' name='handler' filepath='drivers/iommu/iommu.c' line='1087' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/iommu/iommu.c' line='1088' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_report_device_fault' mangled-name='iommu_report_device_fault' filepath='drivers/iommu/iommu.c' line='1155' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_report_device_fault'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='1155' column='1'/>
-        <parameter type-id='af233abc' name='evt' filepath='drivers/iommu/iommu.c' line='1155' column='1'/>
+      <function-decl name='iommu_report_device_fault' mangled-name='iommu_report_device_fault' filepath='drivers/iommu/iommu.c' line='1171' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_report_device_fault'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='1171' column='1'/>
+        <parameter type-id='af233abc' name='evt' filepath='drivers/iommu/iommu.c' line='1171' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iommu_set_fault_handler' mangled-name='iommu_set_fault_handler' filepath='drivers/iommu/iommu.c' line='1893' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_set_fault_handler'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='1893' column='1'/>
-        <parameter type-id='a01c3626' name='handler' filepath='drivers/iommu/iommu.c' line='1894' column='1'/>
-        <parameter type-id='eaa32e2f' name='token' filepath='drivers/iommu/iommu.c' line='1895' column='1'/>
+      <function-decl name='iommu_set_fault_handler' mangled-name='iommu_set_fault_handler' filepath='drivers/iommu/iommu.c' line='1909' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_set_fault_handler'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='1909' column='1'/>
+        <parameter type-id='a01c3626' name='handler' filepath='drivers/iommu/iommu.c' line='1910' column='1'/>
+        <parameter type-id='eaa32e2f' name='token' filepath='drivers/iommu/iommu.c' line='1911' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='iommu_unmap' mangled-name='iommu_unmap' filepath='drivers/iommu/iommu.c' line='2578' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_unmap'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2578' column='1'/>
-        <parameter type-id='7359adad' name='iova' filepath='drivers/iommu/iommu.c' line='2579' column='1'/>
-        <parameter type-id='b59d7dce' name='size' filepath='drivers/iommu/iommu.c' line='2579' column='1'/>
+      <function-decl name='iommu_unmap' mangled-name='iommu_unmap' filepath='drivers/iommu/iommu.c' line='2594' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_unmap'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2594' column='1'/>
+        <parameter type-id='7359adad' name='iova' filepath='drivers/iommu/iommu.c' line='2595' column='1'/>
+        <parameter type-id='b59d7dce' name='size' filepath='drivers/iommu/iommu.c' line='2595' column='1'/>
         <return type-id='b59d7dce'/>
       </function-decl>
-      <function-decl name='iommu_unregister_device_fault_handler' mangled-name='iommu_unregister_device_fault_handler' filepath='drivers/iommu/iommu.c' line='1115' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_unregister_device_fault_handler'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='1115' column='1'/>
+      <function-decl name='iommu_unregister_device_fault_handler' mangled-name='iommu_unregister_device_fault_handler' filepath='drivers/iommu/iommu.c' line='1131' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iommu_unregister_device_fault_handler'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='1131' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='ioremap_cache' mangled-name='ioremap_cache' filepath='arch/arm64/mm/ioremap.c' line='85' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ioremap_cache'>
@@ -133962,28 +134659,28 @@
         <parameter type-id='fe09dd29' name='io_addr' filepath='arch/arm64/mm/ioremap.c' line='72' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='iov_iter_advance' mangled-name='iov_iter_advance' filepath='lib/iov_iter.c' line='1077' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iov_iter_advance'>
-        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='1077' column='1'/>
-        <parameter type-id='b59d7dce' name='size' filepath='lib/iov_iter.c' line='1077' column='1'/>
+      <function-decl name='iov_iter_advance' mangled-name='iov_iter_advance' filepath='lib/iov_iter.c' line='1063' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iov_iter_advance'>
+        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='1063' column='1'/>
+        <parameter type-id='b59d7dce' name='size' filepath='lib/iov_iter.c' line='1063' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='iov_iter_alignment' mangled-name='iov_iter_alignment' filepath='lib/iov_iter.c' line='1236' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iov_iter_alignment'>
-        <parameter type-id='ab3e2665' name='i' filepath='lib/iov_iter.c' line='1236' column='1'/>
+      <function-decl name='iov_iter_alignment' mangled-name='iov_iter_alignment' filepath='lib/iov_iter.c' line='1222' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iov_iter_alignment'>
+        <parameter type-id='ab3e2665' name='i' filepath='lib/iov_iter.c' line='1222' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='iov_iter_bvec' mangled-name='iov_iter_bvec' filepath='lib/iov_iter.c' line='1190' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iov_iter_bvec'>
-        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='1190' column='1'/>
-        <parameter type-id='f0981eeb' name='direction' filepath='lib/iov_iter.c' line='1190' column='1'/>
-        <parameter type-id='15c9a01b' name='bvec' filepath='lib/iov_iter.c' line='1191' column='1'/>
-        <parameter type-id='7359adad' name='nr_segs' filepath='lib/iov_iter.c' line='1191' column='1'/>
-        <parameter type-id='b59d7dce' name='count' filepath='lib/iov_iter.c' line='1192' column='1'/>
+      <function-decl name='iov_iter_bvec' mangled-name='iov_iter_bvec' filepath='lib/iov_iter.c' line='1176' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iov_iter_bvec'>
+        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='1176' column='1'/>
+        <parameter type-id='f0981eeb' name='direction' filepath='lib/iov_iter.c' line='1176' column='1'/>
+        <parameter type-id='15c9a01b' name='bvec' filepath='lib/iov_iter.c' line='1177' column='1'/>
+        <parameter type-id='7359adad' name='nr_segs' filepath='lib/iov_iter.c' line='1177' column='1'/>
+        <parameter type-id='b59d7dce' name='count' filepath='lib/iov_iter.c' line='1178' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='iov_iter_copy_from_user_atomic' mangled-name='iov_iter_copy_from_user_atomic' filepath='lib/iov_iter.c' line='999' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iov_iter_copy_from_user_atomic'>
-        <parameter type-id='02f11ed4' name='page' filepath='lib/iov_iter.c' line='999' column='1'/>
-        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='1000' column='1'/>
-        <parameter type-id='7359adad' name='offset' filepath='lib/iov_iter.c' line='1000' column='1'/>
-        <parameter type-id='b59d7dce' name='bytes' filepath='lib/iov_iter.c' line='1000' column='1'/>
+      <function-decl name='iov_iter_copy_from_user_atomic' mangled-name='iov_iter_copy_from_user_atomic' filepath='lib/iov_iter.c' line='985' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iov_iter_copy_from_user_atomic'>
+        <parameter type-id='02f11ed4' name='page' filepath='lib/iov_iter.c' line='985' column='1'/>
+        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='986' column='1'/>
+        <parameter type-id='7359adad' name='offset' filepath='lib/iov_iter.c' line='986' column='1'/>
+        <parameter type-id='b59d7dce' name='bytes' filepath='lib/iov_iter.c' line='986' column='1'/>
         <return type-id='b59d7dce'/>
       </function-decl>
       <function-decl name='iov_iter_fault_in_readable' mangled-name='iov_iter_fault_in_readable' filepath='lib/iov_iter.c' line='431' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iov_iter_fault_in_readable'>
@@ -133991,24 +134688,24 @@
         <parameter type-id='b59d7dce' name='bytes' filepath='lib/iov_iter.c' line='431' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iov_iter_get_pages' mangled-name='iov_iter_get_pages' filepath='lib/iov_iter.c' line='1323' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iov_iter_get_pages'>
-        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='1323' column='1'/>
-        <parameter type-id='9f93c9da' name='pages' filepath='lib/iov_iter.c' line='1324' column='1'/>
-        <parameter type-id='b59d7dce' name='maxsize' filepath='lib/iov_iter.c' line='1324' column='1'/>
-        <parameter type-id='f0981eeb' name='maxpages' filepath='lib/iov_iter.c' line='1324' column='1'/>
-        <parameter type-id='78c01427' name='start' filepath='lib/iov_iter.c' line='1325' column='1'/>
+      <function-decl name='iov_iter_get_pages' mangled-name='iov_iter_get_pages' filepath='lib/iov_iter.c' line='1309' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iov_iter_get_pages'>
+        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='1309' column='1'/>
+        <parameter type-id='9f93c9da' name='pages' filepath='lib/iov_iter.c' line='1310' column='1'/>
+        <parameter type-id='b59d7dce' name='maxsize' filepath='lib/iov_iter.c' line='1310' column='1'/>
+        <parameter type-id='f0981eeb' name='maxpages' filepath='lib/iov_iter.c' line='1310' column='1'/>
+        <parameter type-id='78c01427' name='start' filepath='lib/iov_iter.c' line='1311' column='1'/>
         <return type-id='79a0948f'/>
       </function-decl>
-      <function-decl name='iov_iter_kvec' mangled-name='iov_iter_kvec' filepath='lib/iov_iter.c' line='1177' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iov_iter_kvec'>
-        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='1177' column='1'/>
-        <parameter type-id='f0981eeb' name='direction' filepath='lib/iov_iter.c' line='1177' column='1'/>
-        <parameter type-id='5199c30d' name='kvec' filepath='lib/iov_iter.c' line='1178' column='1'/>
-        <parameter type-id='7359adad' name='nr_segs' filepath='lib/iov_iter.c' line='1178' column='1'/>
-        <parameter type-id='b59d7dce' name='count' filepath='lib/iov_iter.c' line='1179' column='1'/>
+      <function-decl name='iov_iter_kvec' mangled-name='iov_iter_kvec' filepath='lib/iov_iter.c' line='1163' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iov_iter_kvec'>
+        <parameter type-id='4fa10f9e' name='i' filepath='lib/iov_iter.c' line='1163' column='1'/>
+        <parameter type-id='f0981eeb' name='direction' filepath='lib/iov_iter.c' line='1163' column='1'/>
+        <parameter type-id='5199c30d' name='kvec' filepath='lib/iov_iter.c' line='1164' column='1'/>
+        <parameter type-id='7359adad' name='nr_segs' filepath='lib/iov_iter.c' line='1164' column='1'/>
+        <parameter type-id='b59d7dce' name='count' filepath='lib/iov_iter.c' line='1165' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='iov_iter_single_seg_count' mangled-name='iov_iter_single_seg_count' filepath='lib/iov_iter.c' line='1162' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iov_iter_single_seg_count'>
-        <parameter type-id='ab3e2665' name='i' filepath='lib/iov_iter.c' line='1162' column='1'/>
+      <function-decl name='iov_iter_single_seg_count' mangled-name='iov_iter_single_seg_count' filepath='lib/iov_iter.c' line='1148' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iov_iter_single_seg_count'>
+        <parameter type-id='ab3e2665' name='i' filepath='lib/iov_iter.c' line='1148' column='1'/>
         <return type-id='b59d7dce'/>
       </function-decl>
       <function-decl name='ip6_local_out' mangled-name='ip6_local_out' filepath='net/ipv6/output_core.c' line='155' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ip6_local_out'>
@@ -134041,10 +134738,10 @@
         <parameter type-id='f0981eeb' name='addr_type' filepath='net/ipv4/netfilter.c' line='20' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ip_route_output_flow' mangled-name='ip_route_output_flow' filepath='net/ipv4/route.c' line='2782' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ip_route_output_flow'>
-        <parameter type-id='a2bff676' name='net' filepath='net/ipv4/route.c' line='2782' column='1'/>
-        <parameter type-id='a198549e' name='flp4' filepath='net/ipv4/route.c' line='2782' column='1'/>
-        <parameter type-id='78e7cf52' name='sk' filepath='net/ipv4/route.c' line='2783' column='1'/>
+      <function-decl name='ip_route_output_flow' mangled-name='ip_route_output_flow' filepath='net/ipv4/route.c' line='2784' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ip_route_output_flow'>
+        <parameter type-id='a2bff676' name='net' filepath='net/ipv4/route.c' line='2784' column='1'/>
+        <parameter type-id='a198549e' name='flp4' filepath='net/ipv4/route.c' line='2784' column='1'/>
+        <parameter type-id='78e7cf52' name='sk' filepath='net/ipv4/route.c' line='2785' column='1'/>
         <return type-id='c8f5869f'/>
       </function-decl>
       <function-decl name='ip_send_check' mangled-name='ip_send_check' filepath='net/ipv4/ip_output.c' line='92' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ip_send_check'>
@@ -134054,20 +134751,20 @@
       <function-decl name='ipi_desc_get' mangled-name='ipi_desc_get' filepath='arch/arm64/kernel/smp.c' line='1153' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ipi_desc_get'>
         <return type-id='9d9a0573'/>
       </function-decl>
-      <function-decl name='iput' mangled-name='iput' filepath='fs/inode.c' line='1667' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iput'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='1667' column='1'/>
+      <function-decl name='iput' mangled-name='iput' filepath='fs/inode.c' line='1709' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iput'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='1709' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='ipv6_ext_hdr' mangled-name='ipv6_ext_hdr' filepath='net/ipv6/exthdrs_core.c' line='13' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ipv6_ext_hdr'>
         <parameter type-id='f9b06939' name='nexthdr' filepath='net/ipv6/exthdrs_core.c' line='13' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='ipv6_find_hdr' mangled-name='ipv6_find_hdr' filepath='net/ipv6/exthdrs_core.c' line='186' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ipv6_find_hdr'>
-        <parameter type-id='11f4a000' name='skb' filepath='net/ipv6/exthdrs_core.c' line='186' column='1'/>
-        <parameter type-id='807869d3' name='offset' filepath='net/ipv6/exthdrs_core.c' line='186' column='1'/>
-        <parameter type-id='95e97e5e' name='target' filepath='net/ipv6/exthdrs_core.c' line='187' column='1'/>
-        <parameter type-id='e9e550dd' name='fragoff' filepath='net/ipv6/exthdrs_core.c' line='187' column='1'/>
-        <parameter type-id='7292109c' name='flags' filepath='net/ipv6/exthdrs_core.c' line='187' column='1'/>
+      <function-decl name='ipv6_find_hdr' mangled-name='ipv6_find_hdr' filepath='net/ipv6/exthdrs_core.c' line='188' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ipv6_find_hdr'>
+        <parameter type-id='11f4a000' name='skb' filepath='net/ipv6/exthdrs_core.c' line='188' column='1'/>
+        <parameter type-id='807869d3' name='offset' filepath='net/ipv6/exthdrs_core.c' line='188' column='1'/>
+        <parameter type-id='95e97e5e' name='target' filepath='net/ipv6/exthdrs_core.c' line='189' column='1'/>
+        <parameter type-id='e9e550dd' name='fragoff' filepath='net/ipv6/exthdrs_core.c' line='189' column='1'/>
+        <parameter type-id='7292109c' name='flags' filepath='net/ipv6/exthdrs_core.c' line='189' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='ipv6_skip_exthdr' mangled-name='ipv6_skip_exthdr' filepath='net/ipv6/exthdrs_core.c' line='72' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ipv6_skip_exthdr'>
@@ -134144,22 +134841,22 @@
         <parameter type-id='1c475548' name='data' filepath='kernel/irq/chip.c' line='1451' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='irq_create_fwspec_mapping' mangled-name='irq_create_fwspec_mapping' filepath='kernel/irq/irqdomain.c' line='752' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_create_fwspec_mapping'>
-        <parameter type-id='2869bb38' name='fwspec' filepath='kernel/irq/irqdomain.c' line='752' column='1'/>
+      <function-decl name='irq_create_fwspec_mapping' mangled-name='irq_create_fwspec_mapping' filepath='kernel/irq/irqdomain.c' line='802' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_create_fwspec_mapping'>
+        <parameter type-id='2869bb38' name='fwspec' filepath='kernel/irq/irqdomain.c' line='802' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='irq_create_mapping_affinity' mangled-name='irq_create_mapping_affinity' filepath='kernel/irq/irqdomain.c' line='639' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_create_mapping_affinity'>
-        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='639' column='1'/>
-        <parameter type-id='88370ce9' name='hwirq' filepath='kernel/irq/irqdomain.c' line='640' column='1'/>
-        <parameter type-id='07779cd9' name='affinity' filepath='kernel/irq/irqdomain.c' line='641' column='1'/>
+      <function-decl name='irq_create_mapping_affinity' mangled-name='irq_create_mapping_affinity' filepath='kernel/irq/irqdomain.c' line='705' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_create_mapping_affinity'>
+        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='705' column='1'/>
+        <parameter type-id='88370ce9' name='hwirq' filepath='kernel/irq/irqdomain.c' line='706' column='1'/>
+        <parameter type-id='07779cd9' name='affinity' filepath='kernel/irq/irqdomain.c' line='707' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='irq_create_of_mapping' mangled-name='irq_create_of_mapping' filepath='kernel/irq/irqdomain.c' line='843' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_create_of_mapping'>
-        <parameter type-id='51a94113' name='irq_data' filepath='kernel/irq/irqdomain.c' line='843' column='1'/>
+      <function-decl name='irq_create_of_mapping' mangled-name='irq_create_of_mapping' filepath='kernel/irq/irqdomain.c' line='900' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_create_of_mapping'>
+        <parameter type-id='51a94113' name='irq_data' filepath='kernel/irq/irqdomain.c' line='900' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='irq_dispose_mapping' mangled-name='irq_dispose_mapping' filepath='kernel/irq/irqdomain.c' line='858' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_dispose_mapping'>
-        <parameter type-id='f0981eeb' name='virq' filepath='kernel/irq/irqdomain.c' line='858' column='1'/>
+      <function-decl name='irq_dispose_mapping' mangled-name='irq_dispose_mapping' filepath='kernel/irq/irqdomain.c' line='915' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_dispose_mapping'>
+        <parameter type-id='f0981eeb' name='virq' filepath='kernel/irq/irqdomain.c' line='915' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='irq_do_set_affinity' mangled-name='irq_do_set_affinity' filepath='kernel/irq/manage.c' line='221' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_do_set_affinity'>
@@ -134168,125 +134865,125 @@
         <parameter type-id='b50a4934' name='force' filepath='kernel/irq/manage.c' line='222' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='irq_domain_add_legacy' mangled-name='irq_domain_add_legacy' filepath='kernel/irq/irqdomain.c' line='349' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_add_legacy'>
-        <parameter type-id='9a537bbe' name='of_node' filepath='kernel/irq/irqdomain.c' line='349' column='1'/>
-        <parameter type-id='f0981eeb' name='size' filepath='kernel/irq/irqdomain.c' line='350' column='1'/>
-        <parameter type-id='f0981eeb' name='first_irq' filepath='kernel/irq/irqdomain.c' line='351' column='1'/>
-        <parameter type-id='88370ce9' name='first_hwirq' filepath='kernel/irq/irqdomain.c' line='352' column='1'/>
-        <parameter type-id='2c202856' name='ops' filepath='kernel/irq/irqdomain.c' line='353' column='1'/>
-        <parameter type-id='eaa32e2f' name='host_data' filepath='kernel/irq/irqdomain.c' line='354' column='1'/>
+      <function-decl name='irq_domain_add_legacy' mangled-name='irq_domain_add_legacy' filepath='kernel/irq/irqdomain.c' line='373' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_add_legacy'>
+        <parameter type-id='9a537bbe' name='of_node' filepath='kernel/irq/irqdomain.c' line='373' column='1'/>
+        <parameter type-id='f0981eeb' name='size' filepath='kernel/irq/irqdomain.c' line='374' column='1'/>
+        <parameter type-id='f0981eeb' name='first_irq' filepath='kernel/irq/irqdomain.c' line='375' column='1'/>
+        <parameter type-id='88370ce9' name='first_hwirq' filepath='kernel/irq/irqdomain.c' line='376' column='1'/>
+        <parameter type-id='2c202856' name='ops' filepath='kernel/irq/irqdomain.c' line='377' column='1'/>
+        <parameter type-id='eaa32e2f' name='host_data' filepath='kernel/irq/irqdomain.c' line='378' column='1'/>
         <return type-id='7544e824'/>
       </function-decl>
-      <function-decl name='irq_domain_add_simple' mangled-name='irq_domain_add_simple' filepath='kernel/irq/irqdomain.c' line='306' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_add_simple'>
-        <parameter type-id='9a537bbe' name='of_node' filepath='kernel/irq/irqdomain.c' line='306' column='1'/>
-        <parameter type-id='f0981eeb' name='size' filepath='kernel/irq/irqdomain.c' line='307' column='1'/>
-        <parameter type-id='f0981eeb' name='first_irq' filepath='kernel/irq/irqdomain.c' line='308' column='1'/>
-        <parameter type-id='2c202856' name='ops' filepath='kernel/irq/irqdomain.c' line='309' column='1'/>
-        <parameter type-id='eaa32e2f' name='host_data' filepath='kernel/irq/irqdomain.c' line='310' column='1'/>
+      <function-decl name='irq_domain_add_simple' mangled-name='irq_domain_add_simple' filepath='kernel/irq/irqdomain.c' line='330' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_add_simple'>
+        <parameter type-id='9a537bbe' name='of_node' filepath='kernel/irq/irqdomain.c' line='330' column='1'/>
+        <parameter type-id='f0981eeb' name='size' filepath='kernel/irq/irqdomain.c' line='331' column='1'/>
+        <parameter type-id='f0981eeb' name='first_irq' filepath='kernel/irq/irqdomain.c' line='332' column='1'/>
+        <parameter type-id='2c202856' name='ops' filepath='kernel/irq/irqdomain.c' line='333' column='1'/>
+        <parameter type-id='eaa32e2f' name='host_data' filepath='kernel/irq/irqdomain.c' line='334' column='1'/>
         <return type-id='7544e824'/>
       </function-decl>
-      <function-decl name='irq_domain_alloc_irqs_parent' mangled-name='irq_domain_alloc_irqs_parent' filepath='kernel/irq/irqdomain.c' line='1685' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_alloc_irqs_parent'>
-        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='1685' column='1'/>
-        <parameter type-id='f0981eeb' name='irq_base' filepath='kernel/irq/irqdomain.c' line='1686' column='1'/>
-        <parameter type-id='f0981eeb' name='nr_irqs' filepath='kernel/irq/irqdomain.c' line='1686' column='1'/>
-        <parameter type-id='eaa32e2f' name='arg' filepath='kernel/irq/irqdomain.c' line='1687' column='1'/>
+      <function-decl name='irq_domain_alloc_irqs_parent' mangled-name='irq_domain_alloc_irqs_parent' filepath='kernel/irq/irqdomain.c' line='1753' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_alloc_irqs_parent'>
+        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='1753' column='1'/>
+        <parameter type-id='f0981eeb' name='irq_base' filepath='kernel/irq/irqdomain.c' line='1754' column='1'/>
+        <parameter type-id='f0981eeb' name='nr_irqs' filepath='kernel/irq/irqdomain.c' line='1754' column='1'/>
+        <parameter type-id='eaa32e2f' name='arg' filepath='kernel/irq/irqdomain.c' line='1755' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='irq_domain_create_hierarchy' mangled-name='irq_domain_create_hierarchy' filepath='kernel/irq/irqdomain.c' line='1069' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_create_hierarchy'>
-        <parameter type-id='7544e824' name='parent' filepath='kernel/irq/irqdomain.c' line='1069' column='1'/>
-        <parameter type-id='f0981eeb' name='flags' filepath='kernel/irq/irqdomain.c' line='1070' column='1'/>
-        <parameter type-id='f0981eeb' name='size' filepath='kernel/irq/irqdomain.c' line='1071' column='1'/>
-        <parameter type-id='4a935625' name='fwnode' filepath='kernel/irq/irqdomain.c' line='1072' column='1'/>
-        <parameter type-id='2c202856' name='ops' filepath='kernel/irq/irqdomain.c' line='1073' column='1'/>
-        <parameter type-id='eaa32e2f' name='host_data' filepath='kernel/irq/irqdomain.c' line='1074' column='1'/>
+      <function-decl name='irq_domain_create_hierarchy' mangled-name='irq_domain_create_hierarchy' filepath='kernel/irq/irqdomain.c' line='1126' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_create_hierarchy'>
+        <parameter type-id='7544e824' name='parent' filepath='kernel/irq/irqdomain.c' line='1126' column='1'/>
+        <parameter type-id='f0981eeb' name='flags' filepath='kernel/irq/irqdomain.c' line='1127' column='1'/>
+        <parameter type-id='f0981eeb' name='size' filepath='kernel/irq/irqdomain.c' line='1128' column='1'/>
+        <parameter type-id='4a935625' name='fwnode' filepath='kernel/irq/irqdomain.c' line='1129' column='1'/>
+        <parameter type-id='2c202856' name='ops' filepath='kernel/irq/irqdomain.c' line='1130' column='1'/>
+        <parameter type-id='eaa32e2f' name='host_data' filepath='kernel/irq/irqdomain.c' line='1131' column='1'/>
         <return type-id='7544e824'/>
       </function-decl>
-      <function-decl name='irq_domain_disconnect_hierarchy' mangled-name='irq_domain_disconnect_hierarchy' filepath='kernel/irq/irqdomain.c' line='1183' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_disconnect_hierarchy'>
-        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='1183' column='1'/>
-        <parameter type-id='f0981eeb' name='virq' filepath='kernel/irq/irqdomain.c' line='1184' column='1'/>
+      <function-decl name='irq_domain_disconnect_hierarchy' mangled-name='irq_domain_disconnect_hierarchy' filepath='kernel/irq/irqdomain.c' line='1243' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_disconnect_hierarchy'>
+        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='1243' column='1'/>
+        <parameter type-id='f0981eeb' name='virq' filepath='kernel/irq/irqdomain.c' line='1244' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='irq_domain_free_irqs_common' mangled-name='irq_domain_free_irqs_common' filepath='kernel/irq/irqdomain.c' line='1342' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_free_irqs_common'>
-        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='1342' column='1'/>
-        <parameter type-id='f0981eeb' name='virq' filepath='kernel/irq/irqdomain.c' line='1342' column='1'/>
-        <parameter type-id='f0981eeb' name='nr_irqs' filepath='kernel/irq/irqdomain.c' line='1343' column='1'/>
+      <function-decl name='irq_domain_free_irqs_common' mangled-name='irq_domain_free_irqs_common' filepath='kernel/irq/irqdomain.c' line='1402' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_free_irqs_common'>
+        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='1402' column='1'/>
+        <parameter type-id='f0981eeb' name='virq' filepath='kernel/irq/irqdomain.c' line='1402' column='1'/>
+        <parameter type-id='f0981eeb' name='nr_irqs' filepath='kernel/irq/irqdomain.c' line='1403' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='irq_domain_free_irqs_parent' mangled-name='irq_domain_free_irqs_parent' filepath='kernel/irq/irqdomain.c' line='1705' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_free_irqs_parent'>
-        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='1705' column='1'/>
-        <parameter type-id='f0981eeb' name='irq_base' filepath='kernel/irq/irqdomain.c' line='1706' column='1'/>
-        <parameter type-id='f0981eeb' name='nr_irqs' filepath='kernel/irq/irqdomain.c' line='1706' column='1'/>
+      <function-decl name='irq_domain_free_irqs_parent' mangled-name='irq_domain_free_irqs_parent' filepath='kernel/irq/irqdomain.c' line='1773' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_free_irqs_parent'>
+        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='1773' column='1'/>
+        <parameter type-id='f0981eeb' name='irq_base' filepath='kernel/irq/irqdomain.c' line='1774' column='1'/>
+        <parameter type-id='f0981eeb' name='nr_irqs' filepath='kernel/irq/irqdomain.c' line='1774' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='irq_domain_get_irq_data' mangled-name='irq_domain_get_irq_data' filepath='kernel/irq/irqdomain.c' line='1275' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_get_irq_data'>
-        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='1275' column='1'/>
-        <parameter type-id='f0981eeb' name='virq' filepath='kernel/irq/irqdomain.c' line='1276' column='1'/>
+      <function-decl name='irq_domain_get_irq_data' mangled-name='irq_domain_get_irq_data' filepath='kernel/irq/irqdomain.c' line='1335' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_get_irq_data'>
+        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='1335' column='1'/>
+        <parameter type-id='f0981eeb' name='virq' filepath='kernel/irq/irqdomain.c' line='1336' column='1'/>
         <return type-id='1c475548'/>
       </function-decl>
-      <function-decl name='irq_domain_remove' mangled-name='irq_domain_remove' filepath='kernel/irq/irqdomain.c' line='229' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_remove'>
-        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='229' column='1'/>
+      <function-decl name='irq_domain_remove' mangled-name='irq_domain_remove' filepath='kernel/irq/irqdomain.c' line='253' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_remove'>
+        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='253' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='irq_domain_set_hwirq_and_chip' mangled-name='irq_domain_set_hwirq_and_chip' filepath='kernel/irq/irqdomain.c' line='1297' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_set_hwirq_and_chip'>
-        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='1297' column='1'/>
-        <parameter type-id='f0981eeb' name='virq' filepath='kernel/irq/irqdomain.c' line='1297' column='1'/>
-        <parameter type-id='88370ce9' name='hwirq' filepath='kernel/irq/irqdomain.c' line='1298' column='1'/>
-        <parameter type-id='8846a616' name='chip' filepath='kernel/irq/irqdomain.c' line='1298' column='1'/>
-        <parameter type-id='eaa32e2f' name='chip_data' filepath='kernel/irq/irqdomain.c' line='1299' column='1'/>
+      <function-decl name='irq_domain_set_hwirq_and_chip' mangled-name='irq_domain_set_hwirq_and_chip' filepath='kernel/irq/irqdomain.c' line='1357' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_set_hwirq_and_chip'>
+        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='1357' column='1'/>
+        <parameter type-id='f0981eeb' name='virq' filepath='kernel/irq/irqdomain.c' line='1357' column='1'/>
+        <parameter type-id='88370ce9' name='hwirq' filepath='kernel/irq/irqdomain.c' line='1358' column='1'/>
+        <parameter type-id='8846a616' name='chip' filepath='kernel/irq/irqdomain.c' line='1358' column='1'/>
+        <parameter type-id='eaa32e2f' name='chip_data' filepath='kernel/irq/irqdomain.c' line='1359' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='irq_domain_set_info' mangled-name='irq_domain_set_info' filepath='kernel/irq/irqdomain.c' line='1325' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_set_info'>
-        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='1325' column='1'/>
-        <parameter type-id='f0981eeb' name='virq' filepath='kernel/irq/irqdomain.c' line='1325' column='1'/>
-        <parameter type-id='88370ce9' name='hwirq' filepath='kernel/irq/irqdomain.c' line='1326' column='1'/>
-        <parameter type-id='8846a616' name='chip' filepath='kernel/irq/irqdomain.c' line='1326' column='1'/>
-        <parameter type-id='eaa32e2f' name='chip_data' filepath='kernel/irq/irqdomain.c' line='1327' column='1'/>
-        <parameter type-id='cdb741d3' name='handler' filepath='kernel/irq/irqdomain.c' line='1327' column='1'/>
-        <parameter type-id='eaa32e2f' name='handler_data' filepath='kernel/irq/irqdomain.c' line='1328' column='1'/>
-        <parameter type-id='80f4b756' name='handler_name' filepath='kernel/irq/irqdomain.c' line='1328' column='1'/>
+      <function-decl name='irq_domain_set_info' mangled-name='irq_domain_set_info' filepath='kernel/irq/irqdomain.c' line='1385' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_set_info'>
+        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='1385' column='1'/>
+        <parameter type-id='f0981eeb' name='virq' filepath='kernel/irq/irqdomain.c' line='1385' column='1'/>
+        <parameter type-id='88370ce9' name='hwirq' filepath='kernel/irq/irqdomain.c' line='1386' column='1'/>
+        <parameter type-id='8846a616' name='chip' filepath='kernel/irq/irqdomain.c' line='1386' column='1'/>
+        <parameter type-id='eaa32e2f' name='chip_data' filepath='kernel/irq/irqdomain.c' line='1387' column='1'/>
+        <parameter type-id='cdb741d3' name='handler' filepath='kernel/irq/irqdomain.c' line='1387' column='1'/>
+        <parameter type-id='eaa32e2f' name='handler_data' filepath='kernel/irq/irqdomain.c' line='1388' column='1'/>
+        <parameter type-id='80f4b756' name='handler_name' filepath='kernel/irq/irqdomain.c' line='1388' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <var-decl name='irq_domain_simple_ops' type-id='a4974438' mangled-name='irq_domain_simple_ops' visibility='default' filepath='kernel/irq/irqdomain.c' line='975' column='1' elf-symbol-id='irq_domain_simple_ops'/>
-      <function-decl name='irq_domain_update_bus_token' mangled-name='irq_domain_update_bus_token' filepath='kernel/irq/irqdomain.c' line='256' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_update_bus_token'>
-        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='256' column='1'/>
-        <parameter type-id='385b8018' name='bus_token' filepath='kernel/irq/irqdomain.c' line='257' column='1'/>
+      <var-decl name='irq_domain_simple_ops' type-id='a4974438' mangled-name='irq_domain_simple_ops' visibility='default' filepath='kernel/irq/irqdomain.c' line='1032' column='1' elf-symbol-id='irq_domain_simple_ops'/>
+      <function-decl name='irq_domain_update_bus_token' mangled-name='irq_domain_update_bus_token' filepath='kernel/irq/irqdomain.c' line='280' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_update_bus_token'>
+        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='280' column='1'/>
+        <parameter type-id='385b8018' name='bus_token' filepath='kernel/irq/irqdomain.c' line='281' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='irq_domain_xlate_onecell' mangled-name='irq_domain_xlate_onecell' filepath='kernel/irq/irqdomain.c' line='918' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_xlate_onecell'>
-        <parameter type-id='7544e824' name='d' filepath='kernel/irq/irqdomain.c' line='918' column='1'/>
-        <parameter type-id='9a537bbe' name='ctrlr' filepath='kernel/irq/irqdomain.c' line='918' column='1'/>
-        <parameter type-id='aded214c' name='intspec' filepath='kernel/irq/irqdomain.c' line='919' column='1'/>
-        <parameter type-id='f0981eeb' name='intsize' filepath='kernel/irq/irqdomain.c' line='919' column='1'/>
-        <parameter type-id='1d2c2b85' name='out_hwirq' filepath='kernel/irq/irqdomain.c' line='920' column='1'/>
-        <parameter type-id='807869d3' name='out_type' filepath='kernel/irq/irqdomain.c' line='920' column='1'/>
+      <function-decl name='irq_domain_xlate_onecell' mangled-name='irq_domain_xlate_onecell' filepath='kernel/irq/irqdomain.c' line='975' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_xlate_onecell'>
+        <parameter type-id='7544e824' name='d' filepath='kernel/irq/irqdomain.c' line='975' column='1'/>
+        <parameter type-id='9a537bbe' name='ctrlr' filepath='kernel/irq/irqdomain.c' line='975' column='1'/>
+        <parameter type-id='aded214c' name='intspec' filepath='kernel/irq/irqdomain.c' line='976' column='1'/>
+        <parameter type-id='f0981eeb' name='intsize' filepath='kernel/irq/irqdomain.c' line='976' column='1'/>
+        <parameter type-id='1d2c2b85' name='out_hwirq' filepath='kernel/irq/irqdomain.c' line='977' column='1'/>
+        <parameter type-id='807869d3' name='out_type' filepath='kernel/irq/irqdomain.c' line='977' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='irq_domain_xlate_onetwocell' mangled-name='irq_domain_xlate_onetwocell' filepath='kernel/irq/irqdomain.c' line='959' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_xlate_onetwocell'>
-        <parameter type-id='7544e824' name='d' filepath='kernel/irq/irqdomain.c' line='959' column='1'/>
-        <parameter type-id='9a537bbe' name='ctrlr' filepath='kernel/irq/irqdomain.c' line='960' column='1'/>
-        <parameter type-id='aded214c' name='intspec' filepath='kernel/irq/irqdomain.c' line='961' column='1'/>
-        <parameter type-id='f0981eeb' name='intsize' filepath='kernel/irq/irqdomain.c' line='961' column='1'/>
-        <parameter type-id='1d2c2b85' name='out_hwirq' filepath='kernel/irq/irqdomain.c' line='962' column='1'/>
-        <parameter type-id='807869d3' name='out_type' filepath='kernel/irq/irqdomain.c' line='962' column='1'/>
+      <function-decl name='irq_domain_xlate_onetwocell' mangled-name='irq_domain_xlate_onetwocell' filepath='kernel/irq/irqdomain.c' line='1016' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_xlate_onetwocell'>
+        <parameter type-id='7544e824' name='d' filepath='kernel/irq/irqdomain.c' line='1016' column='1'/>
+        <parameter type-id='9a537bbe' name='ctrlr' filepath='kernel/irq/irqdomain.c' line='1017' column='1'/>
+        <parameter type-id='aded214c' name='intspec' filepath='kernel/irq/irqdomain.c' line='1018' column='1'/>
+        <parameter type-id='f0981eeb' name='intsize' filepath='kernel/irq/irqdomain.c' line='1018' column='1'/>
+        <parameter type-id='1d2c2b85' name='out_hwirq' filepath='kernel/irq/irqdomain.c' line='1019' column='1'/>
+        <parameter type-id='807869d3' name='out_type' filepath='kernel/irq/irqdomain.c' line='1019' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='irq_domain_xlate_twocell' mangled-name='irq_domain_xlate_twocell' filepath='kernel/irq/irqdomain.c' line='937' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_xlate_twocell'>
-        <parameter type-id='7544e824' name='d' filepath='kernel/irq/irqdomain.c' line='937' column='1'/>
-        <parameter type-id='9a537bbe' name='ctrlr' filepath='kernel/irq/irqdomain.c' line='937' column='1'/>
-        <parameter type-id='aded214c' name='intspec' filepath='kernel/irq/irqdomain.c' line='938' column='1'/>
-        <parameter type-id='f0981eeb' name='intsize' filepath='kernel/irq/irqdomain.c' line='938' column='1'/>
-        <parameter type-id='ebc26324' name='out_hwirq' filepath='kernel/irq/irqdomain.c' line='939' column='1'/>
-        <parameter type-id='807869d3' name='out_type' filepath='kernel/irq/irqdomain.c' line='939' column='1'/>
+      <function-decl name='irq_domain_xlate_twocell' mangled-name='irq_domain_xlate_twocell' filepath='kernel/irq/irqdomain.c' line='994' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_domain_xlate_twocell'>
+        <parameter type-id='7544e824' name='d' filepath='kernel/irq/irqdomain.c' line='994' column='1'/>
+        <parameter type-id='9a537bbe' name='ctrlr' filepath='kernel/irq/irqdomain.c' line='994' column='1'/>
+        <parameter type-id='aded214c' name='intspec' filepath='kernel/irq/irqdomain.c' line='995' column='1'/>
+        <parameter type-id='f0981eeb' name='intsize' filepath='kernel/irq/irqdomain.c' line='995' column='1'/>
+        <parameter type-id='ebc26324' name='out_hwirq' filepath='kernel/irq/irqdomain.c' line='996' column='1'/>
+        <parameter type-id='807869d3' name='out_type' filepath='kernel/irq/irqdomain.c' line='996' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='irq_find_mapping' mangled-name='irq_find_mapping' filepath='kernel/irq/irqdomain.c' line='884' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_find_mapping'>
-        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='884' column='1'/>
-        <parameter type-id='88370ce9' name='hwirq' filepath='kernel/irq/irqdomain.c' line='885' column='1'/>
+      <function-decl name='irq_find_mapping' mangled-name='irq_find_mapping' filepath='kernel/irq/irqdomain.c' line='941' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_find_mapping'>
+        <parameter type-id='7544e824' name='domain' filepath='kernel/irq/irqdomain.c' line='941' column='1'/>
+        <parameter type-id='88370ce9' name='hwirq' filepath='kernel/irq/irqdomain.c' line='942' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='irq_find_matching_fwspec' mangled-name='irq_find_matching_fwspec' filepath='kernel/irq/irqdomain.c' line='372' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_find_matching_fwspec'>
-        <parameter type-id='2869bb38' name='fwspec' filepath='kernel/irq/irqdomain.c' line='372' column='1'/>
-        <parameter type-id='385b8018' name='bus_token' filepath='kernel/irq/irqdomain.c' line='373' column='1'/>
+      <function-decl name='irq_find_matching_fwspec' mangled-name='irq_find_matching_fwspec' filepath='kernel/irq/irqdomain.c' line='396' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_find_matching_fwspec'>
+        <parameter type-id='2869bb38' name='fwspec' filepath='kernel/irq/irqdomain.c' line='396' column='1'/>
+        <parameter type-id='385b8018' name='bus_token' filepath='kernel/irq/irqdomain.c' line='397' column='1'/>
         <return type-id='7544e824'/>
       </function-decl>
       <function-decl name='irq_gc_ack_set_bit' mangled-name='irq_gc_ack_set_bit' filepath='kernel/irq/generic-chip.c' line='111' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_gc_ack_set_bit'>
@@ -134316,10 +135013,10 @@
         <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/chip.c' line='159' column='1'/>
         <return type-id='1c475548'/>
       </function-decl>
-      <function-decl name='irq_get_irqchip_state' mangled-name='irq_get_irqchip_state' filepath='kernel/irq/manage.c' line='2723' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_get_irqchip_state'>
-        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2723' column='1'/>
-        <parameter type-id='0187da1b' name='which' filepath='kernel/irq/manage.c' line='2723' column='1'/>
-        <parameter type-id='d8e6b335' name='state' filepath='kernel/irq/manage.c' line='2724' column='1'/>
+      <function-decl name='irq_get_irqchip_state' mangled-name='irq_get_irqchip_state' filepath='kernel/irq/manage.c' line='2730' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_get_irqchip_state'>
+        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2730' column='1'/>
+        <parameter type-id='0187da1b' name='which' filepath='kernel/irq/manage.c' line='2730' column='1'/>
+        <parameter type-id='d8e6b335' name='state' filepath='kernel/irq/manage.c' line='2731' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='irq_modify_status' mangled-name='irq_modify_status' filepath='kernel/irq/chip.c' line='1169' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_modify_status'>
@@ -134381,10 +135078,10 @@
         <parameter type-id='f0981eeb' name='on' filepath='kernel/irq/manage.c' line='788' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='irq_set_irqchip_state' mangled-name='irq_set_irqchip_state' filepath='kernel/irq/manage.c' line='2756' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_set_irqchip_state'>
-        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2756' column='1'/>
-        <parameter type-id='0187da1b' name='which' filepath='kernel/irq/manage.c' line='2756' column='1'/>
-        <parameter type-id='b50a4934' name='val' filepath='kernel/irq/manage.c' line='2757' column='1'/>
+      <function-decl name='irq_set_irqchip_state' mangled-name='irq_set_irqchip_state' filepath='kernel/irq/manage.c' line='2763' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_set_irqchip_state'>
+        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2763' column='1'/>
+        <parameter type-id='0187da1b' name='which' filepath='kernel/irq/manage.c' line='2763' column='1'/>
+        <parameter type-id='b50a4934' name='val' filepath='kernel/irq/manage.c' line='2764' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='irq_set_parent' mangled-name='irq_set_parent' filepath='kernel/irq/manage.c' line='911' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_set_parent'>
@@ -134393,8 +135090,8 @@
         <return type-id='95e97e5e'/>
       </function-decl>
       <var-decl name='irq_stat' type-id='715fcff2' mangled-name='irq_stat' visibility='default' filepath='kernel/softirq.c' line='54' column='1' elf-symbol-id='irq_stat'/>
-      <function-decl name='irq_to_desc' mangled-name='irq_to_desc' filepath='kernel/irq/irqdesc.c' line='351' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_to_desc'>
-        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/irqdesc.c' line='351' column='1'/>
+      <function-decl name='irq_to_desc' mangled-name='irq_to_desc' filepath='kernel/irq/irqdesc.c' line='354' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_to_desc'>
+        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/irqdesc.c' line='354' column='1'/>
         <return type-id='76c7d88b'/>
       </function-decl>
       <function-decl name='irq_work_queue' mangled-name='irq_work_queue' filepath='kernel/irq_work.c' line='67' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_work_queue'>
@@ -134412,6 +135109,10 @@
       <function-decl name='irq_work_sync' mangled-name='irq_work_sync' filepath='kernel/irq_work.c' line='197' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='irq_work_sync'>
         <parameter type-id='44bef697' name='work' filepath='kernel/irq_work.c' line='197' column='1'/>
         <return type-id='48b5725f'/>
+      </function-decl>
+      <function-decl name='is_ashmem_file' mangled-name='is_ashmem_file' filepath='drivers/staging/android/ashmem.c' line='921' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='is_ashmem_file'>
+        <parameter type-id='77e79a4b' name='file' filepath='drivers/staging/android/ashmem.c' line='921' column='1'/>
+        <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='is_bad_inode' mangled-name='is_bad_inode' filepath='fs/bad_inode.c' line='225' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='is_bad_inode'>
         <parameter type-id='7e666abe' name='inode' filepath='fs/bad_inode.c' line='225' column='1'/>
@@ -134431,9 +135132,9 @@
         <parameter type-id='eaa32e2f' name='x' filepath='mm/vmalloc.c' line='46' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='isolate_and_split_free_page' mangled-name='isolate_and_split_free_page' filepath='mm/compaction.c' line='767' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='isolate_and_split_free_page'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/compaction.c' line='767' column='1'/>
-        <parameter type-id='e84b031a' name='list' filepath='mm/compaction.c' line='768' column='1'/>
+      <function-decl name='isolate_and_split_free_page' mangled-name='isolate_and_split_free_page' filepath='mm/compaction.c' line='772' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='isolate_and_split_free_page'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/compaction.c' line='772' column='1'/>
+        <parameter type-id='e84b031a' name='list' filepath='mm/compaction.c' line='773' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
       <function-decl name='isolate_anon_lru_page' mangled-name='isolate_anon_lru_page' filepath='mm/page_alloc.c' line='539' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='isolate_anon_lru_page'>
@@ -134448,16 +135149,22 @@
         <parameter type-id='f0981eeb' name='flags' filepath='fs/splice.c' line='619' column='1'/>
         <return type-id='79a0948f'/>
       </function-decl>
-      <function-decl name='iterate_fd' mangled-name='iterate_fd' filepath='fs/file.c' line='1249' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iterate_fd'>
-        <parameter type-id='16c53416' name='files' filepath='fs/file.c' line='1249' column='1'/>
-        <parameter type-id='f0981eeb' name='n' filepath='fs/file.c' line='1249' column='1'/>
-        <parameter type-id='d092647b' name='f' filepath='fs/file.c' line='1250' column='1'/>
-        <parameter type-id='eaa32e2f' name='p' filepath='fs/file.c' line='1251' column='1'/>
+      <function-decl name='iterate_fd' mangled-name='iterate_fd' filepath='fs/file.c' line='1264' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iterate_fd'>
+        <parameter type-id='16c53416' name='files' filepath='fs/file.c' line='1264' column='1'/>
+        <parameter type-id='f0981eeb' name='n' filepath='fs/file.c' line='1264' column='1'/>
+        <parameter type-id='d092647b' name='f' filepath='fs/file.c' line='1265' column='1'/>
+        <parameter type-id='eaa32e2f' name='p' filepath='fs/file.c' line='1266' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iunique' mangled-name='iunique' filepath='fs/inode.c' line='1269' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iunique'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/inode.c' line='1269' column='1'/>
-        <parameter type-id='2aa75eef' name='max_reserved' filepath='fs/inode.c' line='1269' column='1'/>
+      <function-decl name='iterate_supers_type' mangled-name='iterate_supers_type' filepath='fs/super.c' line='717' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iterate_supers_type'>
+        <parameter type-id='21e53d44' name='type' filepath='fs/super.c' line='717' column='1'/>
+        <parameter type-id='46530b39' name='f' filepath='fs/super.c' line='718' column='1'/>
+        <parameter type-id='eaa32e2f' name='arg' filepath='fs/super.c' line='718' column='1'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
+      <function-decl name='iunique' mangled-name='iunique' filepath='fs/inode.c' line='1311' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iunique'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/inode.c' line='1311' column='1'/>
+        <parameter type-id='2aa75eef' name='max_reserved' filepath='fs/inode.c' line='1311' column='1'/>
         <return type-id='2aa75eef'/>
       </function-decl>
       <function-decl name='iw_handler_get_spy' mangled-name='iw_handler_get_spy' filepath='net/wireless/wext-spy.c' line='74' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iw_handler_get_spy'>
@@ -134488,29 +135195,29 @@
         <parameter type-id='26a90f95' name='extra' filepath='net/wireless/wext-spy.c' line='113' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='iwe_stream_add_event' mangled-name='iwe_stream_add_event' filepath='net/wireless/wext-core.c' line='1124' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iwe_stream_add_event'>
-        <parameter type-id='4780e252' name='info' filepath='net/wireless/wext-core.c' line='1124' column='1'/>
-        <parameter type-id='26a90f95' name='stream' filepath='net/wireless/wext-core.c' line='1124' column='1'/>
-        <parameter type-id='26a90f95' name='ends' filepath='net/wireless/wext-core.c' line='1125' column='1'/>
-        <parameter type-id='4f46bd9c' name='iwe' filepath='net/wireless/wext-core.c' line='1125' column='1'/>
-        <parameter type-id='95e97e5e' name='event_len' filepath='net/wireless/wext-core.c' line='1125' column='1'/>
+      <function-decl name='iwe_stream_add_event' mangled-name='iwe_stream_add_event' filepath='net/wireless/wext-core.c' line='1130' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iwe_stream_add_event'>
+        <parameter type-id='4780e252' name='info' filepath='net/wireless/wext-core.c' line='1130' column='1'/>
+        <parameter type-id='26a90f95' name='stream' filepath='net/wireless/wext-core.c' line='1130' column='1'/>
+        <parameter type-id='26a90f95' name='ends' filepath='net/wireless/wext-core.c' line='1131' column='1'/>
+        <parameter type-id='4f46bd9c' name='iwe' filepath='net/wireless/wext-core.c' line='1131' column='1'/>
+        <parameter type-id='95e97e5e' name='event_len' filepath='net/wireless/wext-core.c' line='1131' column='1'/>
         <return type-id='26a90f95'/>
       </function-decl>
-      <function-decl name='iwe_stream_add_point' mangled-name='iwe_stream_add_point' filepath='net/wireless/wext-core.c' line='1145' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iwe_stream_add_point'>
-        <parameter type-id='4780e252' name='info' filepath='net/wireless/wext-core.c' line='1145' column='1'/>
-        <parameter type-id='26a90f95' name='stream' filepath='net/wireless/wext-core.c' line='1145' column='1'/>
-        <parameter type-id='26a90f95' name='ends' filepath='net/wireless/wext-core.c' line='1146' column='1'/>
-        <parameter type-id='4f46bd9c' name='iwe' filepath='net/wireless/wext-core.c' line='1146' column='1'/>
-        <parameter type-id='26a90f95' name='extra' filepath='net/wireless/wext-core.c' line='1146' column='1'/>
+      <function-decl name='iwe_stream_add_point' mangled-name='iwe_stream_add_point' filepath='net/wireless/wext-core.c' line='1151' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iwe_stream_add_point'>
+        <parameter type-id='4780e252' name='info' filepath='net/wireless/wext-core.c' line='1151' column='1'/>
+        <parameter type-id='26a90f95' name='stream' filepath='net/wireless/wext-core.c' line='1151' column='1'/>
+        <parameter type-id='26a90f95' name='ends' filepath='net/wireless/wext-core.c' line='1152' column='1'/>
+        <parameter type-id='4f46bd9c' name='iwe' filepath='net/wireless/wext-core.c' line='1152' column='1'/>
+        <parameter type-id='26a90f95' name='extra' filepath='net/wireless/wext-core.c' line='1152' column='1'/>
         <return type-id='26a90f95'/>
       </function-decl>
-      <function-decl name='iwe_stream_add_value' mangled-name='iwe_stream_add_value' filepath='net/wireless/wext-core.c' line='1168' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iwe_stream_add_value'>
-        <parameter type-id='4780e252' name='info' filepath='net/wireless/wext-core.c' line='1168' column='1'/>
-        <parameter type-id='26a90f95' name='event' filepath='net/wireless/wext-core.c' line='1168' column='1'/>
-        <parameter type-id='26a90f95' name='value' filepath='net/wireless/wext-core.c' line='1169' column='1'/>
-        <parameter type-id='26a90f95' name='ends' filepath='net/wireless/wext-core.c' line='1169' column='1'/>
-        <parameter type-id='4f46bd9c' name='iwe' filepath='net/wireless/wext-core.c' line='1169' column='1'/>
-        <parameter type-id='95e97e5e' name='event_len' filepath='net/wireless/wext-core.c' line='1170' column='1'/>
+      <function-decl name='iwe_stream_add_value' mangled-name='iwe_stream_add_value' filepath='net/wireless/wext-core.c' line='1174' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='iwe_stream_add_value'>
+        <parameter type-id='4780e252' name='info' filepath='net/wireless/wext-core.c' line='1174' column='1'/>
+        <parameter type-id='26a90f95' name='event' filepath='net/wireless/wext-core.c' line='1174' column='1'/>
+        <parameter type-id='26a90f95' name='value' filepath='net/wireless/wext-core.c' line='1175' column='1'/>
+        <parameter type-id='26a90f95' name='ends' filepath='net/wireless/wext-core.c' line='1175' column='1'/>
+        <parameter type-id='4f46bd9c' name='iwe' filepath='net/wireless/wext-core.c' line='1175' column='1'/>
+        <parameter type-id='95e97e5e' name='event_len' filepath='net/wireless/wext-core.c' line='1176' column='1'/>
         <return type-id='26a90f95'/>
       </function-decl>
       <function-decl name='jiffies64_to_msecs' mangled-name='jiffies64_to_msecs' filepath='kernel/time/time.c' line='701' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='jiffies64_to_msecs'>
@@ -134541,36 +135248,36 @@
         <parameter type-id='21e53d44' name='type' filepath='fs/namespace.c' line='3881' column='1'/>
         <return type-id='549da823'/>
       </function-decl>
-      <function-decl name='kern_path' mangled-name='kern_path' filepath='fs/namei.c' line='2533' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kern_path'>
-        <parameter type-id='80f4b756' name='name' filepath='fs/namei.c' line='2533' column='1'/>
-        <parameter type-id='f0981eeb' name='flags' filepath='fs/namei.c' line='2533' column='1'/>
-        <parameter type-id='bcfe6314' name='path' filepath='fs/namei.c' line='2533' column='1'/>
+      <function-decl name='kern_path' mangled-name='kern_path' filepath='fs/namei.c' line='2545' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kern_path'>
+        <parameter type-id='80f4b756' name='name' filepath='fs/namei.c' line='2545' column='1'/>
+        <parameter type-id='f0981eeb' name='flags' filepath='fs/namei.c' line='2545' column='1'/>
+        <parameter type-id='bcfe6314' name='path' filepath='fs/namei.c' line='2545' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='kern_unmount' mangled-name='kern_unmount' filepath='fs/namespace.c' line='3896' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kern_unmount'>
         <parameter type-id='549da823' name='mnt' filepath='fs/namespace.c' line='3896' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='kernel_bind' mangled-name='kernel_bind' filepath='net/socket.c' line='3392' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kernel_bind'>
-        <parameter type-id='13103032' name='sock' filepath='net/socket.c' line='3392' column='1'/>
-        <parameter type-id='5c0abad8' name='addr' filepath='net/socket.c' line='3392' column='1'/>
-        <parameter type-id='95e97e5e' name='addrlen' filepath='net/socket.c' line='3392' column='1'/>
+      <function-decl name='kernel_bind' mangled-name='kernel_bind' filepath='net/socket.c' line='3396' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kernel_bind'>
+        <parameter type-id='13103032' name='sock' filepath='net/socket.c' line='3396' column='1'/>
+        <parameter type-id='5c0abad8' name='addr' filepath='net/socket.c' line='3396' column='1'/>
+        <parameter type-id='95e97e5e' name='addrlen' filepath='net/socket.c' line='3396' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='kernel_connect' mangled-name='kernel_connect' filepath='net/socket.c' line='3461' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kernel_connect'>
-        <parameter type-id='13103032' name='sock' filepath='net/socket.c' line='3461' column='1'/>
-        <parameter type-id='5c0abad8' name='addr' filepath='net/socket.c' line='3461' column='1'/>
-        <parameter type-id='95e97e5e' name='addrlen' filepath='net/socket.c' line='3461' column='1'/>
-        <parameter type-id='95e97e5e' name='flags' filepath='net/socket.c' line='3462' column='1'/>
+      <function-decl name='kernel_connect' mangled-name='kernel_connect' filepath='net/socket.c' line='3465' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kernel_connect'>
+        <parameter type-id='13103032' name='sock' filepath='net/socket.c' line='3465' column='1'/>
+        <parameter type-id='5c0abad8' name='addr' filepath='net/socket.c' line='3465' column='1'/>
+        <parameter type-id='95e97e5e' name='addrlen' filepath='net/socket.c' line='3465' column='1'/>
+        <parameter type-id='95e97e5e' name='flags' filepath='net/socket.c' line='3466' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <var-decl name='kernel_cpustat' type-id='7b5f27b3' mangled-name='kernel_cpustat' visibility='default' filepath='kernel/sched/core.c' line='4175' column='1' elf-symbol-id='kernel_cpustat'/>
-      <function-decl name='kernel_getsockname' mangled-name='kernel_getsockname' filepath='net/socket.c' line='3477' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kernel_getsockname'>
-        <parameter type-id='13103032' name='sock' filepath='net/socket.c' line='3477' column='1'/>
-        <parameter type-id='5c0abad8' name='addr' filepath='net/socket.c' line='3477' column='1'/>
+      <var-decl name='kernel_cpustat' type-id='7b5f27b3' mangled-name='kernel_cpustat' visibility='default' filepath='kernel/sched/core.c' line='4178' column='1' elf-symbol-id='kernel_cpustat'/>
+      <function-decl name='kernel_getsockname' mangled-name='kernel_getsockname' filepath='net/socket.c' line='3481' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kernel_getsockname'>
+        <parameter type-id='13103032' name='sock' filepath='net/socket.c' line='3481' column='1'/>
+        <parameter type-id='5c0abad8' name='addr' filepath='net/socket.c' line='3481' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <var-decl name='kernel_kobj' type-id='d30bdc51' mangled-name='kernel_kobj' visibility='default' filepath='kernel/ksysfs.c' line='208' column='1' elf-symbol-id='kernel_kobj'/>
+      <var-decl name='kernel_kobj' type-id='d30bdc51' mangled-name='kernel_kobj' visibility='default' filepath='kernel/ksysfs.c' line='213' column='1' elf-symbol-id='kernel_kobj'/>
       <function-decl name='kernel_neon_begin' mangled-name='kernel_neon_begin' filepath='arch/arm64/kernel/fpsimd.c' line='1268' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kernel_neon_begin'>
         <return type-id='48b5725f'/>
       </function-decl>
@@ -134609,20 +135316,20 @@
         <parameter type-id='b59d7dce' name='size' filepath='net/socket.c' line='689' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='kernel_sigaction' mangled-name='kernel_sigaction' filepath='kernel/signal.c' line='3976' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kernel_sigaction'>
-        <parameter type-id='95e97e5e' name='sig' filepath='kernel/signal.c' line='3976' column='1'/>
-        <parameter type-id='8cdd9566' name='action' filepath='kernel/signal.c' line='3976' column='1'/>
+      <function-decl name='kernel_sigaction' mangled-name='kernel_sigaction' filepath='kernel/signal.c' line='3979' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kernel_sigaction'>
+        <parameter type-id='95e97e5e' name='sig' filepath='kernel/signal.c' line='3979' column='1'/>
+        <parameter type-id='8cdd9566' name='action' filepath='kernel/signal.c' line='3979' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='kernel_sock_shutdown' mangled-name='kernel_sock_shutdown' filepath='net/socket.c' line='3554' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kernel_sock_shutdown'>
-        <parameter type-id='13103032' name='sock' filepath='net/socket.c' line='3554' column='1'/>
-        <parameter type-id='45c08bac' name='how' filepath='net/socket.c' line='3554' column='1'/>
+      <function-decl name='kernel_sock_shutdown' mangled-name='kernel_sock_shutdown' filepath='net/socket.c' line='3558' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kernel_sock_shutdown'>
+        <parameter type-id='13103032' name='sock' filepath='net/socket.c' line='3558' column='1'/>
+        <parameter type-id='45c08bac' name='how' filepath='net/socket.c' line='3558' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='kernfs_find_and_get_ns' mangled-name='kernfs_find_and_get_ns' filepath='fs/kernfs/dir.c' line='907' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kernfs_find_and_get_ns'>
-        <parameter type-id='150efd3f' name='parent' filepath='fs/kernfs/dir.c' line='907' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='fs/kernfs/dir.c' line='908' column='1'/>
-        <parameter type-id='eaa32e2f' name='ns' filepath='fs/kernfs/dir.c' line='908' column='1'/>
+      <function-decl name='kernfs_find_and_get_ns' mangled-name='kernfs_find_and_get_ns' filepath='fs/kernfs/dir.c' line='909' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kernfs_find_and_get_ns'>
+        <parameter type-id='150efd3f' name='parent' filepath='fs/kernfs/dir.c' line='909' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='fs/kernfs/dir.c' line='910' column='1'/>
+        <parameter type-id='eaa32e2f' name='ns' filepath='fs/kernfs/dir.c' line='910' column='1'/>
         <return type-id='150efd3f'/>
       </function-decl>
       <function-decl name='kernfs_notify' mangled-name='kernfs_notify' filepath='fs/kernfs/file.c' line='913' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kernfs_notify'>
@@ -134669,20 +135376,20 @@
         <parameter type-id='eaa32e2f' name='x' filepath='mm/slub.c' line='4179' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='kfree_const' mangled-name='kfree_const' filepath='mm/util.c' line='40' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kfree_const'>
-        <parameter type-id='eaa32e2f' name='x' filepath='mm/util.c' line='40' column='1'/>
+      <function-decl name='kfree_const' mangled-name='kfree_const' filepath='mm/util.c' line='41' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kfree_const'>
+        <parameter type-id='eaa32e2f' name='x' filepath='mm/util.c' line='41' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='kfree_sensitive' mangled-name='kfree_sensitive' filepath='mm/slab_common.c' line='1160' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kfree_sensitive'>
         <parameter type-id='eaa32e2f' name='p' filepath='mm/slab_common.c' line='1160' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='kfree_skb' mangled-name='kfree_skb' filepath='net/core/skbuff.c' line='706' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kfree_skb'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='706' column='1'/>
+      <function-decl name='kfree_skb' mangled-name='kfree_skb' filepath='net/core/skbuff.c' line='705' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kfree_skb'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='705' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='kfree_skb_list' mangled-name='kfree_skb_list' filepath='net/core/skbuff.c' line='717' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kfree_skb_list'>
-        <parameter type-id='0fbf3cfd' name='segs' filepath='net/core/skbuff.c' line='717' column='1'/>
+      <function-decl name='kfree_skb_list' mangled-name='kfree_skb_list' filepath='net/core/skbuff.c' line='716' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kfree_skb_list'>
+        <parameter type-id='0fbf3cfd' name='segs' filepath='net/core/skbuff.c' line='716' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='kick_all_cpus_sync' mangled-name='kick_all_cpus_sync' filepath='kernel/smp.c' line='938' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kick_all_cpus_sync'>
@@ -134713,9 +135420,9 @@
         <return type-id='95e97e5e'/>
       </function-decl>
       <var-decl name='kimage_voffset' type-id='91ce1af9' mangled-name='kimage_voffset' visibility='default' filepath='arch/arm64/mm/mmu.c' line='49' column='1' elf-symbol-id='kimage_voffset'/>
-      <function-decl name='kiocb_set_cancel_fn' mangled-name='kiocb_set_cancel_fn' filepath='fs/aio.c' line='562' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kiocb_set_cancel_fn'>
-        <parameter type-id='80f25feb' name='iocb' filepath='fs/aio.c' line='562' column='1'/>
-        <parameter type-id='09896a23' name='cancel' filepath='fs/aio.c' line='562' column='1'/>
+      <function-decl name='kiocb_set_cancel_fn' mangled-name='kiocb_set_cancel_fn' filepath='fs/aio.c' line='566' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kiocb_set_cancel_fn'>
+        <parameter type-id='80f25feb' name='iocb' filepath='fs/aio.c' line='566' column='1'/>
+        <parameter type-id='09896a23' name='cancel' filepath='fs/aio.c' line='566' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <var-decl name='kmalloc_caches' type-id='5a527497' mangled-name='kmalloc_caches' visibility='default' filepath='mm/slab_common.c' line='603' column='1' elf-symbol-id='kmalloc_caches'/>
@@ -134769,16 +135476,16 @@
         <parameter type-id='eaa32e2f' name='x' filepath='mm/slub.c' line='3223' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='kmemdup' mangled-name='kmemdup' filepath='mm/util.c' line='127' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmemdup'>
-        <parameter type-id='eaa32e2f' name='src' filepath='mm/util.c' line='127' column='1'/>
-        <parameter type-id='b59d7dce' name='len' filepath='mm/util.c' line='127' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp' filepath='mm/util.c' line='127' column='1'/>
+      <function-decl name='kmemdup' mangled-name='kmemdup' filepath='mm/util.c' line='128' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmemdup'>
+        <parameter type-id='eaa32e2f' name='src' filepath='mm/util.c' line='128' column='1'/>
+        <parameter type-id='b59d7dce' name='len' filepath='mm/util.c' line='128' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp' filepath='mm/util.c' line='128' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='kmemdup_nul' mangled-name='kmemdup_nul' filepath='mm/util.c' line='147' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmemdup_nul'>
-        <parameter type-id='80f4b756' name='s' filepath='mm/util.c' line='147' column='1'/>
-        <parameter type-id='b59d7dce' name='len' filepath='mm/util.c' line='147' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp' filepath='mm/util.c' line='147' column='1'/>
+      <function-decl name='kmemdup_nul' mangled-name='kmemdup_nul' filepath='mm/util.c' line='148' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmemdup_nul'>
+        <parameter type-id='80f4b756' name='s' filepath='mm/util.c' line='148' column='1'/>
+        <parameter type-id='b59d7dce' name='len' filepath='mm/util.c' line='148' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp' filepath='mm/util.c' line='148' column='1'/>
         <return type-id='26a90f95'/>
       </function-decl>
       <function-decl name='kmsg_dump_get_buffer' mangled-name='kmsg_dump_get_buffer' filepath='kernel/printk/printk.c' line='3393' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmsg_dump_get_buffer'>
@@ -134894,24 +135601,24 @@
         <return type-id='b59d7dce'/>
       </function-decl>
       <var-decl name='ksoftirqd' type-id='f23e2572' mangled-name='ksoftirqd' visibility='default' filepath='kernel/softirq.c' line='60' column='1' elf-symbol-id='ksoftirqd'/>
-      <var-decl name='kstat' type-id='153750ef' mangled-name='kstat' visibility='default' filepath='kernel/sched/core.c' line='4174' column='1' elf-symbol-id='kstat'/>
-      <function-decl name='kstat_irqs_cpu' mangled-name='kstat_irqs_cpu' filepath='kernel/irq/irqdesc.c' line='974' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstat_irqs_cpu'>
-        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/irqdesc.c' line='974' column='1'/>
-        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/irq/irqdesc.c' line='974' column='1'/>
+      <var-decl name='kstat' type-id='153750ef' mangled-name='kstat' visibility='default' filepath='kernel/sched/core.c' line='4177' column='1' elf-symbol-id='kstat'/>
+      <function-decl name='kstat_irqs_cpu' mangled-name='kstat_irqs_cpu' filepath='kernel/irq/irqdesc.c' line='977' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstat_irqs_cpu'>
+        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/irqdesc.c' line='977' column='1'/>
+        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/irq/irqdesc.c' line='977' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='kstat_irqs_usr' mangled-name='kstat_irqs_usr' filepath='kernel/irq/irqdesc.c' line='1023' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstat_irqs_usr'>
-        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/irqdesc.c' line='1023' column='1'/>
+      <function-decl name='kstat_irqs_usr' mangled-name='kstat_irqs_usr' filepath='kernel/irq/irqdesc.c' line='1026' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstat_irqs_usr'>
+        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/irqdesc.c' line='1026' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='kstrdup' mangled-name='kstrdup' filepath='mm/util.c' line='54' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrdup'>
-        <parameter type-id='80f4b756' name='s' filepath='mm/util.c' line='54' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp' filepath='mm/util.c' line='54' column='1'/>
+      <function-decl name='kstrdup' mangled-name='kstrdup' filepath='mm/util.c' line='55' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrdup'>
+        <parameter type-id='80f4b756' name='s' filepath='mm/util.c' line='55' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp' filepath='mm/util.c' line='55' column='1'/>
         <return type-id='26a90f95'/>
       </function-decl>
-      <function-decl name='kstrdup_const' mangled-name='kstrdup_const' filepath='mm/util.c' line='81' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrdup_const'>
-        <parameter type-id='80f4b756' name='s' filepath='mm/util.c' line='81' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp' filepath='mm/util.c' line='81' column='1'/>
+      <function-decl name='kstrdup_const' mangled-name='kstrdup_const' filepath='mm/util.c' line='82' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrdup_const'>
+        <parameter type-id='80f4b756' name='s' filepath='mm/util.c' line='82' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp' filepath='mm/util.c' line='82' column='1'/>
         <return type-id='80f4b756'/>
       </function-decl>
       <function-decl name='kstrdup_quotable_cmdline' mangled-name='kstrdup_quotable_cmdline' filepath='lib/string_helpers.c' line='597' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrdup_quotable_cmdline'>
@@ -134919,125 +135626,125 @@
         <parameter type-id='3eb7c31c' name='gfp' filepath='lib/string_helpers.c' line='597' column='1'/>
         <return type-id='26a90f95'/>
       </function-decl>
-      <function-decl name='kstrndup' mangled-name='kstrndup' filepath='mm/util.c' line='100' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrndup'>
-        <parameter type-id='80f4b756' name='s' filepath='mm/util.c' line='100' column='1'/>
-        <parameter type-id='b59d7dce' name='max' filepath='mm/util.c' line='100' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp' filepath='mm/util.c' line='100' column='1'/>
+      <function-decl name='kstrndup' mangled-name='kstrndup' filepath='mm/util.c' line='101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrndup'>
+        <parameter type-id='80f4b756' name='s' filepath='mm/util.c' line='101' column='1'/>
+        <parameter type-id='b59d7dce' name='max' filepath='mm/util.c' line='101' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp' filepath='mm/util.c' line='101' column='1'/>
         <return type-id='26a90f95'/>
       </function-decl>
-      <function-decl name='kstrtobool' mangled-name='kstrtobool' filepath='lib/kstrtox.c' line='335' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtobool'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='335' column='1'/>
-        <parameter type-id='d8e6b335' name='res' filepath='lib/kstrtox.c' line='335' column='1'/>
+      <function-decl name='kstrtobool' mangled-name='kstrtobool' filepath='lib/kstrtox.c' line='336' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtobool'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='336' column='1'/>
+        <parameter type-id='d8e6b335' name='res' filepath='lib/kstrtox.c' line='336' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='kstrtobool_from_user' mangled-name='kstrtobool_from_user' filepath='lib/kstrtox.c' line='377' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtobool_from_user'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='377' column='1'/>
-        <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='377' column='1'/>
-        <parameter type-id='d8e6b335' name='res' filepath='lib/kstrtox.c' line='377' column='1'/>
+      <function-decl name='kstrtobool_from_user' mangled-name='kstrtobool_from_user' filepath='lib/kstrtox.c' line='378' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtobool_from_user'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='378' column='1'/>
+        <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='378' column='1'/>
+        <parameter type-id='d8e6b335' name='res' filepath='lib/kstrtox.c' line='378' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='kstrtoint' mangled-name='kstrtoint' filepath='lib/kstrtox.c' line='251' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtoint'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='251' column='1'/>
-        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='251' column='1'/>
-        <parameter type-id='7292109c' name='res' filepath='lib/kstrtox.c' line='251' column='1'/>
+      <function-decl name='kstrtoint' mangled-name='kstrtoint' filepath='lib/kstrtox.c' line='252' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtoint'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='252' column='1'/>
+        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='252' column='1'/>
+        <parameter type-id='7292109c' name='res' filepath='lib/kstrtox.c' line='252' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='kstrtoint_from_user' mangled-name='kstrtoint_from_user' filepath='lib/kstrtox.c' line='409' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtoint_from_user'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='409' column='1'/>
-        <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='409' column='1'/>
-        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='409' column='1'/>
-        <parameter type-id='7292109c' name='res' filepath='lib/kstrtox.c' line='409' column='1'/>
-        <return type-id='95e97e5e'/>
-      </function-decl>
-      <function-decl name='kstrtol_from_user' mangled-name='kstrtol_from_user' filepath='lib/kstrtox.c' line='407' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtol_from_user'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='407' column='1'/>
-        <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='407' column='1'/>
-        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='407' column='1'/>
-        <parameter type-id='3ccc2590' name='res' filepath='lib/kstrtox.c' line='407' column='1'/>
-        <return type-id='95e97e5e'/>
-      </function-decl>
-      <function-decl name='kstrtoll' mangled-name='kstrtoll' filepath='lib/kstrtox.c' line='150' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtoll'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='150' column='1'/>
-        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='150' column='1'/>
-        <parameter type-id='8b97c2dc' name='res' filepath='lib/kstrtox.c' line='150' column='1'/>
-        <return type-id='95e97e5e'/>
-      </function-decl>
-      <function-decl name='kstrtos16' mangled-name='kstrtos16' filepath='lib/kstrtox.c' line='281' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtos16'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='281' column='1'/>
-        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='281' column='1'/>
-        <parameter type-id='81ac2ac5' name='res' filepath='lib/kstrtox.c' line='281' column='1'/>
-        <return type-id='95e97e5e'/>
-      </function-decl>
-      <function-decl name='kstrtos8' mangled-name='kstrtos8' filepath='lib/kstrtox.c' line='311' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtos8'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='311' column='1'/>
-        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='311' column='1'/>
-        <parameter type-id='01b75fec' name='res' filepath='lib/kstrtox.c' line='311' column='1'/>
-        <return type-id='95e97e5e'/>
-      </function-decl>
-      <function-decl name='kstrtos8_from_user' mangled-name='kstrtos8_from_user' filepath='lib/kstrtox.c' line='413' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtos8_from_user'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='413' column='1'/>
-        <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='413' column='1'/>
-        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='413' column='1'/>
-        <parameter type-id='01b75fec' name='res' filepath='lib/kstrtox.c' line='413' column='1'/>
-        <return type-id='95e97e5e'/>
-      </function-decl>
-      <function-decl name='kstrtou16' mangled-name='kstrtou16' filepath='lib/kstrtox.c' line='266' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtou16'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='266' column='1'/>
-        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='266' column='1'/>
-        <parameter type-id='26d4d46f' name='res' filepath='lib/kstrtox.c' line='266' column='1'/>
-        <return type-id='95e97e5e'/>
-      </function-decl>
-      <function-decl name='kstrtou16_from_user' mangled-name='kstrtou16_from_user' filepath='lib/kstrtox.c' line='410' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtou16_from_user'>
+      <function-decl name='kstrtoint_from_user' mangled-name='kstrtoint_from_user' filepath='lib/kstrtox.c' line='410' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtoint_from_user'>
         <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='410' column='1'/>
         <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='410' column='1'/>
         <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='410' column='1'/>
-        <parameter type-id='26d4d46f' name='res' filepath='lib/kstrtox.c' line='410' column='1'/>
+        <parameter type-id='7292109c' name='res' filepath='lib/kstrtox.c' line='410' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='kstrtou8' mangled-name='kstrtou8' filepath='lib/kstrtox.c' line='296' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtou8'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='296' column='1'/>
-        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='296' column='1'/>
-        <parameter type-id='8bff8096' name='res' filepath='lib/kstrtox.c' line='296' column='1'/>
-        <return type-id='95e97e5e'/>
-      </function-decl>
-      <function-decl name='kstrtou8_from_user' mangled-name='kstrtou8_from_user' filepath='lib/kstrtox.c' line='412' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtou8_from_user'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='412' column='1'/>
-        <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='412' column='1'/>
-        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='412' column='1'/>
-        <parameter type-id='8bff8096' name='res' filepath='lib/kstrtox.c' line='412' column='1'/>
-        <return type-id='95e97e5e'/>
-      </function-decl>
-      <function-decl name='kstrtouint' mangled-name='kstrtouint' filepath='lib/kstrtox.c' line='221' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtouint'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='221' column='1'/>
-        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='221' column='1'/>
-        <parameter type-id='807869d3' name='res' filepath='lib/kstrtox.c' line='221' column='1'/>
-        <return type-id='95e97e5e'/>
-      </function-decl>
-      <function-decl name='kstrtouint_from_user' mangled-name='kstrtouint_from_user' filepath='lib/kstrtox.c' line='408' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtouint_from_user'>
+      <function-decl name='kstrtol_from_user' mangled-name='kstrtol_from_user' filepath='lib/kstrtox.c' line='408' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtol_from_user'>
         <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='408' column='1'/>
         <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='408' column='1'/>
         <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='408' column='1'/>
-        <parameter type-id='807869d3' name='res' filepath='lib/kstrtox.c' line='408' column='1'/>
+        <parameter type-id='3ccc2590' name='res' filepath='lib/kstrtox.c' line='408' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='kstrtoul_from_user' mangled-name='kstrtoul_from_user' filepath='lib/kstrtox.c' line='406' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtoul_from_user'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='406' column='1'/>
-        <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='406' column='1'/>
-        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='406' column='1'/>
-        <parameter type-id='1d2c2b85' name='res' filepath='lib/kstrtox.c' line='406' column='1'/>
+      <function-decl name='kstrtoll' mangled-name='kstrtoll' filepath='lib/kstrtox.c' line='151' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtoll'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='151' column='1'/>
+        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='151' column='1'/>
+        <parameter type-id='8b97c2dc' name='res' filepath='lib/kstrtox.c' line='151' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='kstrtoull' mangled-name='kstrtoull' filepath='lib/kstrtox.c' line='127' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtoull'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='127' column='1'/>
-        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='127' column='1'/>
-        <parameter type-id='c0190993' name='res' filepath='lib/kstrtox.c' line='127' column='1'/>
+      <function-decl name='kstrtos16' mangled-name='kstrtos16' filepath='lib/kstrtox.c' line='282' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtos16'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='282' column='1'/>
+        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='282' column='1'/>
+        <parameter type-id='81ac2ac5' name='res' filepath='lib/kstrtox.c' line='282' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='kstrtoull_from_user' mangled-name='kstrtoull_from_user' filepath='lib/kstrtox.c' line='404' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtoull_from_user'>
-        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='404' column='1'/>
-        <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='404' column='1'/>
-        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='404' column='1'/>
-        <parameter type-id='c0190993' name='res' filepath='lib/kstrtox.c' line='404' column='1'/>
+      <function-decl name='kstrtos8' mangled-name='kstrtos8' filepath='lib/kstrtox.c' line='312' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtos8'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='312' column='1'/>
+        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='312' column='1'/>
+        <parameter type-id='01b75fec' name='res' filepath='lib/kstrtox.c' line='312' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='kstrtos8_from_user' mangled-name='kstrtos8_from_user' filepath='lib/kstrtox.c' line='414' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtos8_from_user'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='414' column='1'/>
+        <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='414' column='1'/>
+        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='414' column='1'/>
+        <parameter type-id='01b75fec' name='res' filepath='lib/kstrtox.c' line='414' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='kstrtou16' mangled-name='kstrtou16' filepath='lib/kstrtox.c' line='267' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtou16'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='267' column='1'/>
+        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='267' column='1'/>
+        <parameter type-id='26d4d46f' name='res' filepath='lib/kstrtox.c' line='267' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='kstrtou16_from_user' mangled-name='kstrtou16_from_user' filepath='lib/kstrtox.c' line='411' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtou16_from_user'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='411' column='1'/>
+        <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='411' column='1'/>
+        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='411' column='1'/>
+        <parameter type-id='26d4d46f' name='res' filepath='lib/kstrtox.c' line='411' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='kstrtou8' mangled-name='kstrtou8' filepath='lib/kstrtox.c' line='297' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtou8'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='297' column='1'/>
+        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='297' column='1'/>
+        <parameter type-id='8bff8096' name='res' filepath='lib/kstrtox.c' line='297' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='kstrtou8_from_user' mangled-name='kstrtou8_from_user' filepath='lib/kstrtox.c' line='413' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtou8_from_user'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='413' column='1'/>
+        <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='413' column='1'/>
+        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='413' column='1'/>
+        <parameter type-id='8bff8096' name='res' filepath='lib/kstrtox.c' line='413' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='kstrtouint' mangled-name='kstrtouint' filepath='lib/kstrtox.c' line='222' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtouint'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='222' column='1'/>
+        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='222' column='1'/>
+        <parameter type-id='807869d3' name='res' filepath='lib/kstrtox.c' line='222' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='kstrtouint_from_user' mangled-name='kstrtouint_from_user' filepath='lib/kstrtox.c' line='409' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtouint_from_user'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='409' column='1'/>
+        <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='409' column='1'/>
+        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='409' column='1'/>
+        <parameter type-id='807869d3' name='res' filepath='lib/kstrtox.c' line='409' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='kstrtoul_from_user' mangled-name='kstrtoul_from_user' filepath='lib/kstrtox.c' line='407' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtoul_from_user'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='407' column='1'/>
+        <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='407' column='1'/>
+        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='407' column='1'/>
+        <parameter type-id='1d2c2b85' name='res' filepath='lib/kstrtox.c' line='407' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='kstrtoull' mangled-name='kstrtoull' filepath='lib/kstrtox.c' line='128' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtoull'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='128' column='1'/>
+        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='128' column='1'/>
+        <parameter type-id='c0190993' name='res' filepath='lib/kstrtox.c' line='128' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='kstrtoull_from_user' mangled-name='kstrtoull_from_user' filepath='lib/kstrtox.c' line='405' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstrtoull_from_user'>
+        <parameter type-id='80f4b756' name='s' filepath='lib/kstrtox.c' line='405' column='1'/>
+        <parameter type-id='b59d7dce' name='count' filepath='lib/kstrtox.c' line='405' column='1'/>
+        <parameter type-id='f0981eeb' name='base' filepath='lib/kstrtox.c' line='405' column='1'/>
+        <parameter type-id='c0190993' name='res' filepath='lib/kstrtox.c' line='405' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='ksys_sync_helper' mangled-name='ksys_sync_helper' filepath='kernel/power/main.c' line='54' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ksys_sync_helper'>
@@ -135206,19 +135913,19 @@
         <parameter type-id='2aee9912' name='ap' filepath='lib/kasprintf.c' line='15' column='1'/>
         <return type-id='26a90f95'/>
       </function-decl>
-      <function-decl name='kvfree' mangled-name='kvfree' filepath='mm/util.c' line='642' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kvfree'>
-        <parameter type-id='eaa32e2f' name='addr' filepath='mm/util.c' line='642' column='1'/>
+      <function-decl name='kvfree' mangled-name='kvfree' filepath='mm/util.c' line='649' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kvfree'>
+        <parameter type-id='eaa32e2f' name='addr' filepath='mm/util.c' line='649' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='kvfree_call_rcu' mangled-name='kvfree_call_rcu' filepath='kernel/rcu/tree.c' line='3471' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kvfree_call_rcu'>
-        <parameter type-id='69c138b1' name='head' filepath='kernel/rcu/tree.c' line='3471' column='1'/>
-        <parameter type-id='4edd56e3' name='func' filepath='kernel/rcu/tree.c' line='3471' column='1'/>
+      <function-decl name='kvfree_call_rcu' mangled-name='kvfree_call_rcu' filepath='kernel/rcu/tree.c' line='3500' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kvfree_call_rcu'>
+        <parameter type-id='69c138b1' name='head' filepath='kernel/rcu/tree.c' line='3500' column='1'/>
+        <parameter type-id='4edd56e3' name='func' filepath='kernel/rcu/tree.c' line='3500' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='kvmalloc_node' mangled-name='kvmalloc_node' filepath='mm/util.c' line='586' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kvmalloc_node'>
-        <parameter type-id='b59d7dce' name='size' filepath='mm/util.c' line='586' column='1'/>
-        <parameter type-id='3eb7c31c' name='flags' filepath='mm/util.c' line='586' column='1'/>
-        <parameter type-id='95e97e5e' name='node' filepath='mm/util.c' line='586' column='1'/>
+      <function-decl name='kvmalloc_node' mangled-name='kvmalloc_node' filepath='mm/util.c' line='587' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kvmalloc_node'>
+        <parameter type-id='b59d7dce' name='size' filepath='mm/util.c' line='587' column='1'/>
+        <parameter type-id='3eb7c31c' name='flags' filepath='mm/util.c' line='587' column='1'/>
+        <parameter type-id='95e97e5e' name='node' filepath='mm/util.c' line='587' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
       <function-decl name='led_classdev_flash_register_ext' mangled-name='led_classdev_flash_register_ext' filepath='drivers/leds/led-class-flash.c' line='285' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='led_classdev_flash_register_ext'>
@@ -135231,14 +135938,14 @@
         <parameter type-id='26deddb9' name='fled_cdev' filepath='drivers/leds/led-class-flash.c' line='321' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='led_classdev_register_ext' mangled-name='led_classdev_register_ext' filepath='drivers/leds/led-class.c' line='336' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='led_classdev_register_ext'>
-        <parameter type-id='fa0b179b' name='parent' filepath='drivers/leds/led-class.c' line='336' column='1'/>
-        <parameter type-id='bd1c8eb6' name='led_cdev' filepath='drivers/leds/led-class.c' line='337' column='1'/>
-        <parameter type-id='eebb8ee8' name='init_data' filepath='drivers/leds/led-class.c' line='338' column='1'/>
+      <function-decl name='led_classdev_register_ext' mangled-name='led_classdev_register_ext' filepath='drivers/leds/led-class.c' line='340' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='led_classdev_register_ext'>
+        <parameter type-id='fa0b179b' name='parent' filepath='drivers/leds/led-class.c' line='340' column='1'/>
+        <parameter type-id='bd1c8eb6' name='led_cdev' filepath='drivers/leds/led-class.c' line='341' column='1'/>
+        <parameter type-id='eebb8ee8' name='init_data' filepath='drivers/leds/led-class.c' line='342' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='led_classdev_unregister' mangled-name='led_classdev_unregister' filepath='drivers/leds/led-class.c' line='431' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='led_classdev_unregister'>
-        <parameter type-id='bd1c8eb6' name='led_cdev' filepath='drivers/leds/led-class.c' line='431' column='1'/>
+      <function-decl name='led_classdev_unregister' mangled-name='led_classdev_unregister' filepath='drivers/leds/led-class.c' line='435' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='led_classdev_unregister'>
+        <parameter type-id='bd1c8eb6' name='led_cdev' filepath='drivers/leds/led-class.c' line='435' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <var-decl name='led_colors' type-id='80c2a296' mangled-name='led_colors' visibility='default' filepath='drivers/leds/led-core.c' line='28' column='1' elf-symbol-id='led_colors'/>
@@ -135361,13 +136068,13 @@
       <function-decl name='load_nls_default' mangled-name='load_nls_default' filepath='fs/nls/nls_base.c' line='532' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='load_nls_default'>
         <return type-id='b084f8bb'/>
       </function-decl>
-      <function-decl name='lock_sock_nested' mangled-name='lock_sock_nested' filepath='net/core/sock.c' line='3065' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lock_sock_nested'>
-        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='3065' column='1'/>
-        <parameter type-id='95e97e5e' name='subclass' filepath='net/core/sock.c' line='3065' column='1'/>
+      <function-decl name='lock_sock_nested' mangled-name='lock_sock_nested' filepath='net/core/sock.c' line='3092' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lock_sock_nested'>
+        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='3092' column='1'/>
+        <parameter type-id='95e97e5e' name='subclass' filepath='net/core/sock.c' line='3092' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='lockref_get' mangled-name='lockref_get' filepath='lib/lockref.c' line='44' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lockref_get'>
-        <parameter type-id='5bfdb453' name='lockref' filepath='lib/lockref.c' line='44' column='1'/>
+      <function-decl name='lockref_get' mangled-name='lockref_get' filepath='lib/lockref.c' line='43' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lockref_get'>
+        <parameter type-id='5bfdb453' name='lockref' filepath='lib/lockref.c' line='43' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='log_abnormal_wakeup_reason' mangled-name='log_abnormal_wakeup_reason' filepath='kernel/power/wakeup_reason.c' line='249' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='log_abnormal_wakeup_reason'>
@@ -135402,7 +136109,7 @@
         <parameter type-id='b72f2447' name='page' filepath='mm/page_ext.c' line='256' column='1'/>
         <return type-id='459ae684'/>
       </function-decl>
-      <var-decl name='loops_per_jiffy' type-id='7359adad' mangled-name='loops_per_jiffy' visibility='default' filepath='init/main.c' line='231' column='1' elf-symbol-id='loops_per_jiffy'/>
+      <var-decl name='loops_per_jiffy' type-id='7359adad' mangled-name='loops_per_jiffy' visibility='default' filepath='init/main.c' line='229' column='1' elf-symbol-id='loops_per_jiffy'/>
       <function-decl name='lru_cache_add' mangled-name='lru_cache_add' filepath='mm/swap.c' line='477' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lru_cache_add'>
         <parameter type-id='02f11ed4' name='page' filepath='mm/swap.c' line='477' column='1'/>
         <return type-id='48b5725f'/>
@@ -135468,18 +136175,18 @@
         <parameter type-id='02f11ed4' name='page' filepath='mm/swap.c' line='436' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='match_hex' mangled-name='match_hex' filepath='lib/parser.c' line='232' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='match_hex'>
-        <parameter type-id='4d03589b' name='s' filepath='lib/parser.c' line='232' column='1'/>
-        <parameter type-id='7292109c' name='result' filepath='lib/parser.c' line='232' column='1'/>
+      <function-decl name='match_hex' mangled-name='match_hex' filepath='lib/parser.c' line='233' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='match_hex'>
+        <parameter type-id='4d03589b' name='s' filepath='lib/parser.c' line='233' column='1'/>
+        <parameter type-id='7292109c' name='result' filepath='lib/parser.c' line='233' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='match_int' mangled-name='match_int' filepath='lib/parser.c' line='185' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='match_int'>
-        <parameter type-id='4d03589b' name='s' filepath='lib/parser.c' line='185' column='1'/>
-        <parameter type-id='7292109c' name='result' filepath='lib/parser.c' line='185' column='1'/>
+      <function-decl name='match_int' mangled-name='match_int' filepath='lib/parser.c' line='186' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='match_int'>
+        <parameter type-id='4d03589b' name='s' filepath='lib/parser.c' line='186' column='1'/>
+        <parameter type-id='7292109c' name='result' filepath='lib/parser.c' line='186' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='match_strdup' mangled-name='match_strdup' filepath='lib/parser.c' line='320' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='match_strdup'>
-        <parameter type-id='aade06e2' name='s' filepath='lib/parser.c' line='320' column='1'/>
+      <function-decl name='match_strdup' mangled-name='match_strdup' filepath='lib/parser.c' line='321' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='match_strdup'>
+        <parameter type-id='aade06e2' name='s' filepath='lib/parser.c' line='321' column='1'/>
         <return type-id='26a90f95'/>
       </function-decl>
       <function-decl name='match_string' mangled-name='match_string' filepath='lib/string.c' line='737' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='match_string'>
@@ -135488,10 +136195,10 @@
         <parameter type-id='80f4b756' name='string' filepath='lib/string.c' line='737' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='match_token' mangled-name='match_token' filepath='lib/parser.c' line='105' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='match_token'>
-        <parameter type-id='26a90f95' name='s' filepath='lib/parser.c' line='105' column='1'/>
-        <parameter type-id='a58c17e3' name='table' filepath='lib/parser.c' line='105' column='1'/>
-        <parameter type-id='4d03589b' name='args' filepath='lib/parser.c' line='105' column='1'/>
+      <function-decl name='match_token' mangled-name='match_token' filepath='lib/parser.c' line='106' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='match_token'>
+        <parameter type-id='26a90f95' name='s' filepath='lib/parser.c' line='106' column='1'/>
+        <parameter type-id='a58c17e3' name='table' filepath='lib/parser.c' line='106' column='1'/>
+        <parameter type-id='4d03589b' name='args' filepath='lib/parser.c' line='106' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='mbox_chan_received_data' mangled-name='mbox_chan_received_data' filepath='drivers/mailbox/mailbox.c' line='152' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mbox_chan_received_data'>
@@ -135564,12 +136271,12 @@
         <parameter type-id='95e97e5e' name='value' filepath='drivers/net/phy/mdio_device.c' line='116' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='mdiobus_alloc_size' mangled-name='mdiobus_alloc_size' filepath='drivers/net/phy/mdio_bus.c' line='137' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mdiobus_alloc_size'>
-        <parameter type-id='b59d7dce' name='size' filepath='drivers/net/phy/mdio_bus.c' line='137' column='1'/>
+      <function-decl name='mdiobus_alloc_size' mangled-name='mdiobus_alloc_size' filepath='drivers/net/phy/mdio_bus.c' line='142' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mdiobus_alloc_size'>
+        <parameter type-id='b59d7dce' name='size' filepath='drivers/net/phy/mdio_bus.c' line='142' column='1'/>
         <return type-id='ff47b24b'/>
       </function-decl>
-      <function-decl name='mdiobus_free' mangled-name='mdiobus_free' filepath='drivers/net/phy/mdio_bus.c' line='650' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mdiobus_free'>
-        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='650' column='1'/>
+      <function-decl name='mdiobus_free' mangled-name='mdiobus_free' filepath='drivers/net/phy/mdio_bus.c' line='655' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mdiobus_free'>
+        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='655' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='mdiobus_get_phy' mangled-name='mdiobus_get_phy' filepath='drivers/net/phy/mdio_bus.c' line='109' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mdiobus_get_phy'>
@@ -135577,26 +136284,26 @@
         <parameter type-id='95e97e5e' name='addr' filepath='drivers/net/phy/mdio_bus.c' line='109' column='1'/>
         <return type-id='7efbcaaf'/>
       </function-decl>
-      <function-decl name='mdiobus_is_registered_device' mangled-name='mdiobus_is_registered_device' filepath='drivers/net/phy/mdio_bus.c' line='123' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mdiobus_is_registered_device'>
-        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='123' column='1'/>
-        <parameter type-id='95e97e5e' name='addr' filepath='drivers/net/phy/mdio_bus.c' line='123' column='1'/>
+      <function-decl name='mdiobus_is_registered_device' mangled-name='mdiobus_is_registered_device' filepath='drivers/net/phy/mdio_bus.c' line='128' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mdiobus_is_registered_device'>
+        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='128' column='1'/>
+        <parameter type-id='95e97e5e' name='addr' filepath='drivers/net/phy/mdio_bus.c' line='128' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='mdiobus_read' mangled-name='mdiobus_read' filepath='drivers/net/phy/mdio_bus.c' line='854' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mdiobus_read'>
-        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='854' column='1'/>
-        <parameter type-id='95e97e5e' name='addr' filepath='drivers/net/phy/mdio_bus.c' line='854' column='1'/>
-        <parameter type-id='19c2251e' name='regnum' filepath='drivers/net/phy/mdio_bus.c' line='854' column='1'/>
+      <function-decl name='mdiobus_read' mangled-name='mdiobus_read' filepath='drivers/net/phy/mdio_bus.c' line='859' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mdiobus_read'>
+        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='859' column='1'/>
+        <parameter type-id='95e97e5e' name='addr' filepath='drivers/net/phy/mdio_bus.c' line='859' column='1'/>
+        <parameter type-id='19c2251e' name='regnum' filepath='drivers/net/phy/mdio_bus.c' line='859' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='mdiobus_unregister' mangled-name='mdiobus_unregister' filepath='drivers/net/phy/mdio_bus.c' line='613' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mdiobus_unregister'>
-        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='613' column='1'/>
+      <function-decl name='mdiobus_unregister' mangled-name='mdiobus_unregister' filepath='drivers/net/phy/mdio_bus.c' line='618' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mdiobus_unregister'>
+        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='618' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='mdiobus_write' mangled-name='mdiobus_write' filepath='drivers/net/phy/mdio_bus.c' line='903' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mdiobus_write'>
-        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='903' column='1'/>
-        <parameter type-id='95e97e5e' name='addr' filepath='drivers/net/phy/mdio_bus.c' line='903' column='1'/>
-        <parameter type-id='19c2251e' name='regnum' filepath='drivers/net/phy/mdio_bus.c' line='903' column='1'/>
-        <parameter type-id='1dc6a898' name='val' filepath='drivers/net/phy/mdio_bus.c' line='903' column='1'/>
+      <function-decl name='mdiobus_write' mangled-name='mdiobus_write' filepath='drivers/net/phy/mdio_bus.c' line='908' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mdiobus_write'>
+        <parameter type-id='ff47b24b' name='bus' filepath='drivers/net/phy/mdio_bus.c' line='908' column='1'/>
+        <parameter type-id='95e97e5e' name='addr' filepath='drivers/net/phy/mdio_bus.c' line='908' column='1'/>
+        <parameter type-id='19c2251e' name='regnum' filepath='drivers/net/phy/mdio_bus.c' line='908' column='1'/>
+        <parameter type-id='1dc6a898' name='val' filepath='drivers/net/phy/mdio_bus.c' line='908' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='media_create_intf_link' mangled-name='media_create_intf_link' filepath='drivers/media/mc/mc-entity.c' line='967' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='media_create_intf_link'>
@@ -135701,9 +136408,16 @@
         <parameter type-id='ac429605' name='req' filepath='drivers/media/mc/mc-request.c' line='79' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='mem_cgroup_from_id' mangled-name='mem_cgroup_from_id' filepath='mm/memcontrol.c' line='5225' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mem_cgroup_from_id'>
-        <parameter type-id='8efea9e5' name='id' filepath='mm/memcontrol.c' line='5225' column='1'/>
+      <function-decl name='mem_cgroup_from_id' mangled-name='mem_cgroup_from_id' filepath='mm/memcontrol.c' line='5232' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mem_cgroup_from_id'>
+        <parameter type-id='8efea9e5' name='id' filepath='mm/memcontrol.c' line='5232' column='1'/>
         <return type-id='223696fb'/>
+      </function-decl>
+      <function-decl name='mem_cgroup_update_lru_size' mangled-name='mem_cgroup_update_lru_size' filepath='mm/memcontrol.c' line='1420' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mem_cgroup_update_lru_size'>
+        <parameter type-id='71480a3e' name='lruvec' filepath='mm/memcontrol.c' line='1420' column='1'/>
+        <parameter type-id='04110eaa' name='lru' filepath='mm/memcontrol.c' line='1420' column='1'/>
+        <parameter type-id='95e97e5e' name='zid' filepath='mm/memcontrol.c' line='1421' column='1'/>
+        <parameter type-id='95e97e5e' name='nr_pages' filepath='mm/memcontrol.c' line='1421' column='1'/>
+        <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='memblock_end_of_DRAM' mangled-name='memblock_end_of_DRAM' filepath='mm/memblock.c' line='1632' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='memblock_end_of_DRAM'>
         <return type-id='2522883d'/>
@@ -135713,27 +136427,27 @@
         <parameter type-id='2522883d' name='size' filepath='mm/memblock.c' line='808' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <var-decl name='memcg_kmem_enabled_key' type-id='237c0d27' mangled-name='memcg_kmem_enabled_key' visibility='default' filepath='mm/memcontrol.c' line='394' column='1' elf-symbol-id='memcg_kmem_enabled_key'/>
+      <var-decl name='memcg_kmem_enabled_key' type-id='237c0d27' mangled-name='memcg_kmem_enabled_key' visibility='default' filepath='mm/memcontrol.c' line='395' column='1' elf-symbol-id='memcg_kmem_enabled_key'/>
       <function-decl name='memchr_inv' mangled-name='memchr_inv' filepath='lib/string.c' line='1087' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='memchr_inv'>
         <parameter type-id='eaa32e2f' name='start' filepath='lib/string.c' line='1087' column='1'/>
         <parameter type-id='95e97e5e' name='c' filepath='lib/string.c' line='1087' column='1'/>
         <parameter type-id='b59d7dce' name='bytes' filepath='lib/string.c' line='1087' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='memdup_user' mangled-name='memdup_user' filepath='mm/util.c' line='172' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='memdup_user'>
-        <parameter type-id='eaa32e2f' name='src' filepath='mm/util.c' line='172' column='1'/>
-        <parameter type-id='b59d7dce' name='len' filepath='mm/util.c' line='172' column='1'/>
+      <function-decl name='memdup_user' mangled-name='memdup_user' filepath='mm/util.c' line='173' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='memdup_user'>
+        <parameter type-id='eaa32e2f' name='src' filepath='mm/util.c' line='173' column='1'/>
+        <parameter type-id='b59d7dce' name='len' filepath='mm/util.c' line='173' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='memdup_user_nul' mangled-name='memdup_user_nul' filepath='mm/util.c' line='254' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='memdup_user_nul'>
-        <parameter type-id='eaa32e2f' name='src' filepath='mm/util.c' line='254' column='1'/>
-        <parameter type-id='b59d7dce' name='len' filepath='mm/util.c' line='254' column='1'/>
+      <function-decl name='memdup_user_nul' mangled-name='memdup_user_nul' filepath='mm/util.c' line='255' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='memdup_user_nul'>
+        <parameter type-id='eaa32e2f' name='src' filepath='mm/util.c' line='255' column='1'/>
+        <parameter type-id='b59d7dce' name='len' filepath='mm/util.c' line='255' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
       <function-decl name='memory_block_size_bytes' mangled-name='memory_block_size_bytes' filepath='drivers/base/memory.c' line='106' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='memory_block_size_bytes'>
         <return type-id='7359adad'/>
       </function-decl>
-      <var-decl name='memory_cgrp_subsys' type-id='1d115fd5' mangled-name='memory_cgrp_subsys' visibility='default' filepath='mm/memcontrol.c' line='6613' column='1' elf-symbol-id='memory_cgrp_subsys'/>
+      <var-decl name='memory_cgrp_subsys' type-id='1d115fd5' mangled-name='memory_cgrp_subsys' visibility='default' filepath='mm/memcontrol.c' line='6620' column='1' elf-symbol-id='memory_cgrp_subsys'/>
       <var-decl name='memory_cgrp_subsys_enabled_key' type-id='49a0ad34' mangled-name='memory_cgrp_subsys_enabled_key' visibility='default' filepath='include/linux/cgroup_subsys.h' line='29' column='1' elf-symbol-id='memory_cgrp_subsys_enabled_key'/>
       <function-decl name='memory_read_from_buffer' mangled-name='memory_read_from_buffer' filepath='fs/libfs.c' line='787' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='memory_read_from_buffer'>
         <parameter type-id='eaa32e2f' name='to' filepath='fs/libfs.c' line='787' column='1'/>
@@ -135882,11 +136596,11 @@
         <parameter type-id='95e97e5e' name='reason' filepath='mm/migrate.c' line='1403' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='migrate_swap' mangled-name='migrate_swap' filepath='kernel/sched/core.c' line='2285' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='migrate_swap'>
-        <parameter type-id='f23e2572' name='cur' filepath='kernel/sched/core.c' line='2285' column='1'/>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='2285' column='1'/>
-        <parameter type-id='95e97e5e' name='target_cpu' filepath='kernel/sched/core.c' line='2286' column='1'/>
-        <parameter type-id='95e97e5e' name='curr_cpu' filepath='kernel/sched/core.c' line='2286' column='1'/>
+      <function-decl name='migrate_swap' mangled-name='migrate_swap' filepath='kernel/sched/core.c' line='2288' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='migrate_swap'>
+        <parameter type-id='f23e2572' name='cur' filepath='kernel/sched/core.c' line='2288' column='1'/>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='2288' column='1'/>
+        <parameter type-id='95e97e5e' name='target_cpu' filepath='kernel/sched/core.c' line='2289' column='1'/>
+        <parameter type-id='95e97e5e' name='curr_cpu' filepath='kernel/sched/core.c' line='2289' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='mii_check_media' mangled-name='mii_check_media' filepath='drivers/net/mii.c' line='504' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mii_check_media'>
@@ -136026,13 +136740,13 @@
         <parameter type-id='182be7cc' name='dsi' filepath='drivers/gpu/drm/drm_mipi_dsi.c' line='243' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='mipi_dsi_driver_register_full' mangled-name='mipi_dsi_driver_register_full' filepath='drivers/gpu/drm/drm_mipi_dsi.c' line='1178' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mipi_dsi_driver_register_full'>
-        <parameter type-id='0588e2f0' name='drv' filepath='drivers/gpu/drm/drm_mipi_dsi.c' line='1178' column='1'/>
-        <parameter type-id='2730d015' name='owner' filepath='drivers/gpu/drm/drm_mipi_dsi.c' line='1179' column='1'/>
+      <function-decl name='mipi_dsi_driver_register_full' mangled-name='mipi_dsi_driver_register_full' filepath='drivers/gpu/drm/drm_mipi_dsi.c' line='1230' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mipi_dsi_driver_register_full'>
+        <parameter type-id='0588e2f0' name='drv' filepath='drivers/gpu/drm/drm_mipi_dsi.c' line='1230' column='1'/>
+        <parameter type-id='2730d015' name='owner' filepath='drivers/gpu/drm/drm_mipi_dsi.c' line='1231' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='mipi_dsi_driver_unregister' mangled-name='mipi_dsi_driver_unregister' filepath='drivers/gpu/drm/drm_mipi_dsi.c' line='1201' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mipi_dsi_driver_unregister'>
-        <parameter type-id='0588e2f0' name='drv' filepath='drivers/gpu/drm/drm_mipi_dsi.c' line='1201' column='1'/>
+      <function-decl name='mipi_dsi_driver_unregister' mangled-name='mipi_dsi_driver_unregister' filepath='drivers/gpu/drm/drm_mipi_dsi.c' line='1253' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mipi_dsi_driver_unregister'>
+        <parameter type-id='0588e2f0' name='drv' filepath='drivers/gpu/drm/drm_mipi_dsi.c' line='1253' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='mipi_dsi_generic_read' mangled-name='mipi_dsi_generic_read' filepath='drivers/gpu/drm/drm_mipi_dsi.c' line='660' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mipi_dsi_generic_read'>
@@ -136358,6 +137072,11 @@
         <parameter type-id='7292109c' name='cmd_error' filepath='drivers/mmc/core/mmc_ops.c' line='640' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
+      <function-decl name='mmc_set_blocklen' mangled-name='mmc_set_blocklen' filepath='drivers/mmc/core/core.c' line='2062' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mmc_set_blocklen'>
+        <parameter type-id='13d38dcb' name='card' filepath='drivers/mmc/core/core.c' line='2062' column='1'/>
+        <parameter type-id='f0981eeb' name='blocklen' filepath='drivers/mmc/core/core.c' line='2062' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
       <function-decl name='mmc_set_clock' mangled-name='mmc_set_clock' filepath='drivers/mmc/core/core.c' line='910' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mmc_set_clock'>
         <parameter type-id='dd575c43' name='host' filepath='drivers/mmc/core/core.c' line='910' column='1'/>
         <parameter type-id='f0981eeb' name='hz' filepath='drivers/mmc/core/core.c' line='910' column='1'/>
@@ -136409,8 +137128,8 @@
         <parameter type-id='47f117d4' name='mrq' filepath='drivers/mmc/core/core.c' line='603' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='mmput' mangled-name='mmput' filepath='kernel/fork.c' line='1149' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mmput'>
-        <parameter type-id='df4b7819' name='mm' filepath='kernel/fork.c' line='1149' column='1'/>
+      <function-decl name='mmput' mangled-name='mmput' filepath='kernel/fork.c' line='1153' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mmput'>
+        <parameter type-id='df4b7819' name='mm' filepath='kernel/fork.c' line='1153' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='mmu_interval_notifier_insert' mangled-name='mmu_interval_notifier_insert' filepath='mm/mmu_notifier.c' line='1040' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mmu_interval_notifier_insert'>
@@ -136440,11 +137159,11 @@
         <parameter type-id='77e79a4b' name='file' filepath='fs/namespace.c' line='408' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='mod_delayed_work_on' mangled-name='mod_delayed_work_on' filepath='kernel/workqueue.c' line='1731' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mod_delayed_work_on'>
-        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/workqueue.c' line='1731' column='1'/>
-        <parameter type-id='242e3d19' name='wq' filepath='kernel/workqueue.c' line='1731' column='1'/>
-        <parameter type-id='1a7ee447' name='dwork' filepath='kernel/workqueue.c' line='1732' column='1'/>
-        <parameter type-id='7359adad' name='delay' filepath='kernel/workqueue.c' line='1732' column='1'/>
+      <function-decl name='mod_delayed_work_on' mangled-name='mod_delayed_work_on' filepath='kernel/workqueue.c' line='1734' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mod_delayed_work_on'>
+        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/workqueue.c' line='1734' column='1'/>
+        <parameter type-id='242e3d19' name='wq' filepath='kernel/workqueue.c' line='1734' column='1'/>
+        <parameter type-id='1a7ee447' name='dwork' filepath='kernel/workqueue.c' line='1735' column='1'/>
+        <parameter type-id='7359adad' name='delay' filepath='kernel/workqueue.c' line='1735' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='mod_node_page_state' mangled-name='mod_node_page_state' filepath='mm/vmstat.c' line='589' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mod_node_page_state'>
@@ -136463,12 +137182,12 @@
         <parameter type-id='7359adad' name='expires' filepath='kernel/time/timer.c' line='1086' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='module_layout' mangled-name='module_layout' filepath='kernel/module.c' line='4804' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='module_layout'>
-        <parameter type-id='2730d015' name='mod' filepath='kernel/module.c' line='4804' column='1'/>
-        <parameter type-id='3a498c74' name='ver' filepath='kernel/module.c' line='4805' column='1'/>
-        <parameter type-id='a7c6e908' name='kp' filepath='kernel/module.c' line='4806' column='1'/>
-        <parameter type-id='eefd7061' name='ks' filepath='kernel/module.c' line='4807' column='1'/>
-        <parameter type-id='e525e121' name='tp' filepath='kernel/module.c' line='4808' column='1'/>
+      <function-decl name='module_layout' mangled-name='module_layout' filepath='kernel/module.c' line='4820' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='module_layout'>
+        <parameter type-id='2730d015' name='mod' filepath='kernel/module.c' line='4820' column='1'/>
+        <parameter type-id='3a498c74' name='ver' filepath='kernel/module.c' line='4821' column='1'/>
+        <parameter type-id='a7c6e908' name='kp' filepath='kernel/module.c' line='4822' column='1'/>
+        <parameter type-id='eefd7061' name='ks' filepath='kernel/module.c' line='4823' column='1'/>
+        <parameter type-id='e525e121' name='tp' filepath='kernel/module.c' line='4824' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='module_put' mangled-name='module_put' filepath='kernel/module.c' line='1158' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='module_put'>
@@ -136509,31 +137228,31 @@
         <parameter type-id='e0ea832a' name='lock' filepath='kernel/locking/mutex.c' line='296' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='mutex_lock_interruptible' mangled-name='mutex_lock_interruptible' filepath='kernel/locking/mutex.c' line='1327' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_lock_interruptible'>
-        <parameter type-id='e0ea832a' name='lock' filepath='kernel/locking/mutex.c' line='1327' column='1'/>
+      <function-decl name='mutex_lock_interruptible' mangled-name='mutex_lock_interruptible' filepath='kernel/locking/mutex.c' line='1339' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_lock_interruptible'>
+        <parameter type-id='e0ea832a' name='lock' filepath='kernel/locking/mutex.c' line='1339' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='mutex_lock_killable' mangled-name='mutex_lock_killable' filepath='kernel/locking/mutex.c' line='1351' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_lock_killable'>
-        <parameter type-id='e0ea832a' name='lock' filepath='kernel/locking/mutex.c' line='1351' column='1'/>
+      <function-decl name='mutex_lock_killable' mangled-name='mutex_lock_killable' filepath='kernel/locking/mutex.c' line='1363' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_lock_killable'>
+        <parameter type-id='e0ea832a' name='lock' filepath='kernel/locking/mutex.c' line='1363' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='mutex_trylock' mangled-name='mutex_trylock' filepath='kernel/locking/mutex.c' line='1431' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_trylock'>
-        <parameter type-id='e0ea832a' name='lock' filepath='kernel/locking/mutex.c' line='1431' column='1'/>
+      <function-decl name='mutex_trylock' mangled-name='mutex_trylock' filepath='kernel/locking/mutex.c' line='1443' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_trylock'>
+        <parameter type-id='e0ea832a' name='lock' filepath='kernel/locking/mutex.c' line='1443' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='mutex_trylock_recursive' mangled-name='mutex_trylock_recursive' filepath='kernel/locking/mutex.c' line='92' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_trylock_recursive'>
         <parameter type-id='e0ea832a' name='lock' filepath='kernel/locking/mutex.c' line='92' column='1'/>
         <return type-id='9a6ea243'/>
       </function-decl>
-      <function-decl name='mutex_unlock' mangled-name='mutex_unlock' filepath='kernel/locking/mutex.c' line='751' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_unlock'>
-        <parameter type-id='e0ea832a' name='lock' filepath='kernel/locking/mutex.c' line='751' column='1'/>
+      <function-decl name='mutex_unlock' mangled-name='mutex_unlock' filepath='kernel/locking/mutex.c' line='761' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_unlock'>
+        <parameter type-id='e0ea832a' name='lock' filepath='kernel/locking/mutex.c' line='761' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='n_tty_ioctl_helper' mangled-name='n_tty_ioctl_helper' filepath='drivers/tty/tty_ioctl.c' line='837' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='n_tty_ioctl_helper'>
-        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_ioctl.c' line='837' column='1'/>
-        <parameter type-id='77e79a4b' name='file' filepath='drivers/tty/tty_ioctl.c' line='837' column='1'/>
-        <parameter type-id='f0981eeb' name='cmd' filepath='drivers/tty/tty_ioctl.c' line='838' column='1'/>
-        <parameter type-id='7359adad' name='arg' filepath='drivers/tty/tty_ioctl.c' line='838' column='1'/>
+      <function-decl name='n_tty_ioctl_helper' mangled-name='n_tty_ioctl_helper' filepath='drivers/tty/tty_ioctl.c' line='859' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='n_tty_ioctl_helper'>
+        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_ioctl.c' line='859' column='1'/>
+        <parameter type-id='77e79a4b' name='file' filepath='drivers/tty/tty_ioctl.c' line='859' column='1'/>
+        <parameter type-id='f0981eeb' name='cmd' filepath='drivers/tty/tty_ioctl.c' line='860' column='1'/>
+        <parameter type-id='7359adad' name='arg' filepath='drivers/tty/tty_ioctl.c' line='860' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='name_to_dev_t' mangled-name='name_to_dev_t' filepath='init/do_mounts.c' line='222' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='name_to_dev_t'>
@@ -136541,55 +137260,55 @@
         <return type-id='8504f260'/>
       </function-decl>
       <var-decl name='names_cachep' type-id='f3b4aca8' mangled-name='names_cachep' visibility='default' filepath='fs/dcache.c' line='3211' column='1' elf-symbol-id='names_cachep'/>
-      <function-decl name='napi_complete_done' mangled-name='napi_complete_done' filepath='net/core/dev.c' line='6487' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='napi_complete_done'>
-        <parameter type-id='c50361c5' name='n' filepath='net/core/dev.c' line='6487' column='1'/>
-        <parameter type-id='95e97e5e' name='work_done' filepath='net/core/dev.c' line='6487' column='1'/>
+      <function-decl name='napi_complete_done' mangled-name='napi_complete_done' filepath='net/core/dev.c' line='6494' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='napi_complete_done'>
+        <parameter type-id='c50361c5' name='n' filepath='net/core/dev.c' line='6494' column='1'/>
+        <parameter type-id='95e97e5e' name='work_done' filepath='net/core/dev.c' line='6494' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='napi_consume_skb' mangled-name='napi_consume_skb' filepath='net/core/skbuff.c' line='909' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='napi_consume_skb'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='909' column='1'/>
-        <parameter type-id='95e97e5e' name='budget' filepath='net/core/skbuff.c' line='909' column='1'/>
+      <function-decl name='napi_consume_skb' mangled-name='napi_consume_skb' filepath='net/core/skbuff.c' line='908' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='napi_consume_skb'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='908' column='1'/>
+        <parameter type-id='95e97e5e' name='budget' filepath='net/core/skbuff.c' line='908' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='napi_disable' mangled-name='napi_disable' filepath='net/core/dev.c' line='6774' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='napi_disable'>
-        <parameter type-id='c50361c5' name='n' filepath='net/core/dev.c' line='6774' column='1'/>
+      <function-decl name='napi_disable' mangled-name='napi_disable' filepath='net/core/dev.c' line='6781' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='napi_disable'>
+        <parameter type-id='c50361c5' name='n' filepath='net/core/dev.c' line='6781' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='napi_gro_flush' mangled-name='napi_gro_flush' filepath='net/core/dev.c' line='5850' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='napi_gro_flush'>
-        <parameter type-id='c50361c5' name='napi' filepath='net/core/dev.c' line='5850' column='1'/>
-        <parameter type-id='b50a4934' name='flush_old' filepath='net/core/dev.c' line='5850' column='1'/>
+      <function-decl name='napi_gro_flush' mangled-name='napi_gro_flush' filepath='net/core/dev.c' line='5856' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='napi_gro_flush'>
+        <parameter type-id='c50361c5' name='napi' filepath='net/core/dev.c' line='5856' column='1'/>
+        <parameter type-id='b50a4934' name='flush_old' filepath='net/core/dev.c' line='5856' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='napi_gro_receive' mangled-name='napi_gro_receive' filepath='net/core/dev.c' line='6151' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='napi_gro_receive'>
-        <parameter type-id='c50361c5' name='napi' filepath='net/core/dev.c' line='6151' column='1'/>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='6151' column='1'/>
+      <function-decl name='napi_gro_receive' mangled-name='napi_gro_receive' filepath='net/core/dev.c' line='6158' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='napi_gro_receive'>
+        <parameter type-id='c50361c5' name='napi' filepath='net/core/dev.c' line='6158' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='6158' column='1'/>
         <return type-id='dc1b1685'/>
       </function-decl>
-      <function-decl name='napi_schedule_prep' mangled-name='napi_schedule_prep' filepath='net/core/dev.c' line='6444' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='napi_schedule_prep'>
-        <parameter type-id='c50361c5' name='n' filepath='net/core/dev.c' line='6444' column='1'/>
+      <function-decl name='napi_schedule_prep' mangled-name='napi_schedule_prep' filepath='net/core/dev.c' line='6451' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='napi_schedule_prep'>
+        <parameter type-id='c50361c5' name='n' filepath='net/core/dev.c' line='6451' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <var-decl name='nd_tbl' type-id='aebe1cff' mangled-name='nd_tbl' visibility='default' filepath='net/ipv6/ndisc.c' line='109' column='1' elf-symbol-id='nd_tbl'/>
-      <function-decl name='neigh_destroy' mangled-name='neigh_destroy' filepath='net/core/neighbour.c' line='849' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='neigh_destroy'>
-        <parameter type-id='3c330066' name='neigh' filepath='net/core/neighbour.c' line='849' column='1'/>
+      <function-decl name='neigh_destroy' mangled-name='neigh_destroy' filepath='net/core/neighbour.c' line='828' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='neigh_destroy'>
+        <parameter type-id='3c330066' name='neigh' filepath='net/core/neighbour.c' line='828' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='neigh_lookup' mangled-name='neigh_lookup' filepath='net/core/neighbour.c' line='544' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='neigh_lookup'>
-        <parameter type-id='6bbe39a7' name='tbl' filepath='net/core/neighbour.c' line='544' column='1'/>
-        <parameter type-id='eaa32e2f' name='pkey' filepath='net/core/neighbour.c' line='544' column='1'/>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/neighbour.c' line='545' column='1'/>
+      <function-decl name='neigh_lookup' mangled-name='neigh_lookup' filepath='net/core/neighbour.c' line='554' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='neigh_lookup'>
+        <parameter type-id='6bbe39a7' name='tbl' filepath='net/core/neighbour.c' line='554' column='1'/>
+        <parameter type-id='eaa32e2f' name='pkey' filepath='net/core/neighbour.c' line='554' column='1'/>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/neighbour.c' line='555' column='1'/>
         <return type-id='3c330066'/>
       </function-decl>
-      <function-decl name='neigh_resolve_output' mangled-name='neigh_resolve_output' filepath='net/core/neighbour.c' line='1497' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='neigh_resolve_output'>
-        <parameter type-id='3c330066' name='neigh' filepath='net/core/neighbour.c' line='1497' column='1'/>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/neighbour.c' line='1497' column='1'/>
+      <function-decl name='neigh_resolve_output' mangled-name='neigh_resolve_output' filepath='net/core/neighbour.c' line='1478' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='neigh_resolve_output'>
+        <parameter type-id='3c330066' name='neigh' filepath='net/core/neighbour.c' line='1478' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/neighbour.c' line='1478' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='neigh_xmit' mangled-name='neigh_xmit' filepath='net/core/neighbour.c' line='3014' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='neigh_xmit'>
-        <parameter type-id='95e97e5e' name='index' filepath='net/core/neighbour.c' line='3014' column='1'/>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/neighbour.c' line='3014' column='1'/>
-        <parameter type-id='eaa32e2f' name='addr' filepath='net/core/neighbour.c' line='3015' column='1'/>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/neighbour.c' line='3015' column='1'/>
+      <function-decl name='neigh_xmit' mangled-name='neigh_xmit' filepath='net/core/neighbour.c' line='2992' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='neigh_xmit'>
+        <parameter type-id='95e97e5e' name='index' filepath='net/core/neighbour.c' line='2992' column='1'/>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/neighbour.c' line='2992' column='1'/>
+        <parameter type-id='eaa32e2f' name='addr' filepath='net/core/neighbour.c' line='2993' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/neighbour.c' line='2993' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <var-decl name='net_namespace_list' type-id='72f469ec' mangled-name='net_namespace_list' visibility='default' filepath='net/core/net_namespace.c' line='36' column='1' elf-symbol-id='net_namespace_list'/>
@@ -136597,9 +137316,9 @@
       <function-decl name='net_ratelimit' mangled-name='net_ratelimit' filepath='net/core/utils.c' line='38' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='net_ratelimit'>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='netdev_alert' mangled-name='netdev_alert' filepath='net/core/dev.c' line='11138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_alert'>
-        <parameter type-id='2ce52478' name='dev' filepath='net/core/dev.c' line='11138' column='1'/>
-        <parameter type-id='80f4b756' name='fmt' filepath='net/core/dev.c' line='11138' column='1'/>
+      <function-decl name='netdev_alert' mangled-name='netdev_alert' filepath='net/core/dev.c' line='11143' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_alert'>
+        <parameter type-id='2ce52478' name='dev' filepath='net/core/dev.c' line='11143' column='1'/>
+        <parameter type-id='80f4b756' name='fmt' filepath='net/core/dev.c' line='11143' column='1'/>
         <parameter is-variadic='yes'/>
         <return type-id='48b5725f'/>
       </function-decl>
@@ -136607,49 +137326,55 @@
         <parameter type-id='f0981eeb' name='fragsz' filepath='net/core/skbuff.c' line='400' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='netdev_change_features' mangled-name='netdev_change_features' filepath='net/core/dev.c' line='9762' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_change_features'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='9762' column='1'/>
+      <function-decl name='netdev_change_features' mangled-name='netdev_change_features' filepath='net/core/dev.c' line='9769' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_change_features'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='9769' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netdev_err' mangled-name='netdev_err' filepath='net/core/dev.c' line='11140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_err'>
-        <parameter type-id='2ce52478' name='dev' filepath='net/core/dev.c' line='11140' column='1'/>
-        <parameter type-id='80f4b756' name='fmt' filepath='net/core/dev.c' line='11140' column='1'/>
+      <function-decl name='netdev_err' mangled-name='netdev_err' filepath='net/core/dev.c' line='11145' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_err'>
+        <parameter type-id='2ce52478' name='dev' filepath='net/core/dev.c' line='11145' column='1'/>
+        <parameter type-id='80f4b756' name='fmt' filepath='net/core/dev.c' line='11145' column='1'/>
         <parameter is-variadic='yes'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netdev_increment_features' mangled-name='netdev_increment_features' filepath='net/core/dev.c' line='11004' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_increment_features'>
-        <parameter type-id='f9f4b16f' name='all' filepath='net/core/dev.c' line='11004' column='1'/>
-        <parameter type-id='f9f4b16f' name='one' filepath='net/core/dev.c' line='11005' column='1'/>
-        <parameter type-id='f9f4b16f' name='mask' filepath='net/core/dev.c' line='11005' column='1'/>
+      <function-decl name='netdev_increment_features' mangled-name='netdev_increment_features' filepath='net/core/dev.c' line='11009' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_increment_features'>
+        <parameter type-id='f9f4b16f' name='all' filepath='net/core/dev.c' line='11009' column='1'/>
+        <parameter type-id='f9f4b16f' name='one' filepath='net/core/dev.c' line='11010' column='1'/>
+        <parameter type-id='f9f4b16f' name='mask' filepath='net/core/dev.c' line='11010' column='1'/>
         <return type-id='f9f4b16f'/>
       </function-decl>
-      <function-decl name='netdev_info' mangled-name='netdev_info' filepath='net/core/dev.c' line='11143' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_info'>
-        <parameter type-id='2ce52478' name='dev' filepath='net/core/dev.c' line='11143' column='1'/>
-        <parameter type-id='80f4b756' name='fmt' filepath='net/core/dev.c' line='11143' column='1'/>
+      <function-decl name='netdev_info' mangled-name='netdev_info' filepath='net/core/dev.c' line='11148' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_info'>
+        <parameter type-id='2ce52478' name='dev' filepath='net/core/dev.c' line='11148' column='1'/>
+        <parameter type-id='80f4b756' name='fmt' filepath='net/core/dev.c' line='11148' column='1'/>
         <parameter is-variadic='yes'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netdev_lower_state_changed' mangled-name='netdev_lower_state_changed' filepath='net/core/dev.c' line='8241' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_lower_state_changed'>
-        <parameter type-id='68a2d05b' name='lower_dev' filepath='net/core/dev.c' line='8241' column='1'/>
-        <parameter type-id='eaa32e2f' name='lower_state_info' filepath='net/core/dev.c' line='8242' column='1'/>
+      <function-decl name='netdev_lower_state_changed' mangled-name='netdev_lower_state_changed' filepath='net/core/dev.c' line='8248' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_lower_state_changed'>
+        <parameter type-id='68a2d05b' name='lower_dev' filepath='net/core/dev.c' line='8248' column='1'/>
+        <parameter type-id='eaa32e2f' name='lower_state_info' filepath='net/core/dev.c' line='8249' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netdev_master_upper_dev_link' mangled-name='netdev_master_upper_dev_link' filepath='net/core/dev.c' line='7936' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_master_upper_dev_link'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='7936' column='1'/>
-        <parameter type-id='68a2d05b' name='upper_dev' filepath='net/core/dev.c' line='7937' column='1'/>
-        <parameter type-id='eaa32e2f' name='upper_priv' filepath='net/core/dev.c' line='7938' column='1'/>
-        <parameter type-id='eaa32e2f' name='upper_info' filepath='net/core/dev.c' line='7938' column='1'/>
-        <parameter type-id='5799dc94' name='extack' filepath='net/core/dev.c' line='7939' column='1'/>
+      <function-decl name='netdev_master_upper_dev_link' mangled-name='netdev_master_upper_dev_link' filepath='net/core/dev.c' line='7943' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_master_upper_dev_link'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='7943' column='1'/>
+        <parameter type-id='68a2d05b' name='upper_dev' filepath='net/core/dev.c' line='7944' column='1'/>
+        <parameter type-id='eaa32e2f' name='upper_priv' filepath='net/core/dev.c' line='7945' column='1'/>
+        <parameter type-id='eaa32e2f' name='upper_info' filepath='net/core/dev.c' line='7945' column='1'/>
+        <parameter type-id='5799dc94' name='extack' filepath='net/core/dev.c' line='7946' column='1'/>
         <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='netdev_notice' mangled-name='netdev_notice' filepath='net/core/dev.c' line='11147' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_notice'>
+        <parameter type-id='2ce52478' name='dev' filepath='net/core/dev.c' line='11147' column='1'/>
+        <parameter type-id='80f4b756' name='fmt' filepath='net/core/dev.c' line='11147' column='1'/>
+        <parameter is-variadic='yes'/>
+        <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='netdev_notify_peers' mangled-name='netdev_notify_peers' filepath='net/core/dev.c' line='1501' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_notify_peers'>
         <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='1501' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netdev_pick_tx' mangled-name='netdev_pick_tx' filepath='net/core/dev.c' line='4015' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_pick_tx'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='4015' column='1'/>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='4015' column='1'/>
-        <parameter type-id='68a2d05b' name='sb_dev' filepath='net/core/dev.c' line='4016' column='1'/>
+      <function-decl name='netdev_pick_tx' mangled-name='netdev_pick_tx' filepath='net/core/dev.c' line='4019' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_pick_tx'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='4019' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='4019' column='1'/>
+        <parameter type-id='68a2d05b' name='sb_dev' filepath='net/core/dev.c' line='4020' column='1'/>
         <return type-id='1dc6a898'/>
       </function-decl>
       <function-decl name='netdev_rss_key_fill' mangled-name='netdev_rss_key_fill' filepath='net/ethtool/ioctl.c' line='1037' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_rss_key_fill'>
@@ -136657,43 +137382,43 @@
         <parameter type-id='b59d7dce' name='len' filepath='net/ethtool/ioctl.c' line='1037' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netdev_rx_handler_register' mangled-name='netdev_rx_handler_register' filepath='net/core/dev.c' line='5077' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_rx_handler_register'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='5077' column='1'/>
-        <parameter type-id='da1cb816' name='rx_handler' filepath='net/core/dev.c' line='5078' column='1'/>
-        <parameter type-id='eaa32e2f' name='rx_handler_data' filepath='net/core/dev.c' line='5079' column='1'/>
+      <function-decl name='netdev_rx_handler_register' mangled-name='netdev_rx_handler_register' filepath='net/core/dev.c' line='5083' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_rx_handler_register'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='5083' column='1'/>
+        <parameter type-id='da1cb816' name='rx_handler' filepath='net/core/dev.c' line='5084' column='1'/>
+        <parameter type-id='eaa32e2f' name='rx_handler_data' filepath='net/core/dev.c' line='5085' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='netdev_rx_handler_unregister' mangled-name='netdev_rx_handler_unregister' filepath='net/core/dev.c' line='5103' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_rx_handler_unregister'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='5103' column='1'/>
+      <function-decl name='netdev_rx_handler_unregister' mangled-name='netdev_rx_handler_unregister' filepath='net/core/dev.c' line='5109' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_rx_handler_unregister'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='5109' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netdev_set_default_ethtool_ops' mangled-name='netdev_set_default_ethtool_ops' filepath='net/core/dev.c' line='10433' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_set_default_ethtool_ops'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10433' column='1'/>
-        <parameter type-id='bdf901f8' name='ops' filepath='net/core/dev.c' line='10434' column='1'/>
+      <function-decl name='netdev_set_default_ethtool_ops' mangled-name='netdev_set_default_ethtool_ops' filepath='net/core/dev.c' line='10438' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_set_default_ethtool_ops'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10438' column='1'/>
+        <parameter type-id='bdf901f8' name='ops' filepath='net/core/dev.c' line='10439' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='netdev_state_change' mangled-name='netdev_state_change' filepath='net/core/dev.c' line='1477' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_state_change'>
         <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='1477' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netdev_update_features' mangled-name='netdev_update_features' filepath='net/core/dev.c' line='9745' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_update_features'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='9745' column='1'/>
+      <function-decl name='netdev_update_features' mangled-name='netdev_update_features' filepath='net/core/dev.c' line='9752' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_update_features'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='9752' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netdev_upper_dev_link' mangled-name='netdev_upper_dev_link' filepath='net/core/dev.c' line='7908' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_upper_dev_link'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='7908' column='1'/>
-        <parameter type-id='68a2d05b' name='upper_dev' filepath='net/core/dev.c' line='7909' column='1'/>
-        <parameter type-id='5799dc94' name='extack' filepath='net/core/dev.c' line='7910' column='1'/>
+      <function-decl name='netdev_upper_dev_link' mangled-name='netdev_upper_dev_link' filepath='net/core/dev.c' line='7915' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_upper_dev_link'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='7915' column='1'/>
+        <parameter type-id='68a2d05b' name='upper_dev' filepath='net/core/dev.c' line='7916' column='1'/>
+        <parameter type-id='5799dc94' name='extack' filepath='net/core/dev.c' line='7917' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='netdev_upper_dev_unlink' mangled-name='netdev_upper_dev_unlink' filepath='net/core/dev.c' line='7991' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_upper_dev_unlink'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='7991' column='1'/>
-        <parameter type-id='68a2d05b' name='upper_dev' filepath='net/core/dev.c' line='7992' column='1'/>
+      <function-decl name='netdev_upper_dev_unlink' mangled-name='netdev_upper_dev_unlink' filepath='net/core/dev.c' line='7998' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_upper_dev_unlink'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='7998' column='1'/>
+        <parameter type-id='68a2d05b' name='upper_dev' filepath='net/core/dev.c' line='7999' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netdev_warn' mangled-name='netdev_warn' filepath='net/core/dev.c' line='11141' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_warn'>
-        <parameter type-id='2ce52478' name='dev' filepath='net/core/dev.c' line='11141' column='1'/>
-        <parameter type-id='80f4b756' name='fmt' filepath='net/core/dev.c' line='11141' column='1'/>
+      <function-decl name='netdev_warn' mangled-name='netdev_warn' filepath='net/core/dev.c' line='11146' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netdev_warn'>
+        <parameter type-id='2ce52478' name='dev' filepath='net/core/dev.c' line='11146' column='1'/>
+        <parameter type-id='80f4b756' name='fmt' filepath='net/core/dev.c' line='11146' column='1'/>
         <parameter is-variadic='yes'/>
         <return type-id='48b5725f'/>
       </function-decl>
@@ -136705,129 +137430,129 @@
         <parameter type-id='68a2d05b' name='dev' filepath='net/sched/sch_generic.c' line='513' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netif_device_attach' mangled-name='netif_device_attach' filepath='net/core/dev.c' line='3154' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_device_attach'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='3154' column='1'/>
+      <function-decl name='netif_device_attach' mangled-name='netif_device_attach' filepath='net/core/dev.c' line='3158' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_device_attach'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='3158' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netif_device_detach' mangled-name='netif_device_detach' filepath='net/core/dev.c' line='3139' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_device_detach'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='3139' column='1'/>
+      <function-decl name='netif_device_detach' mangled-name='netif_device_detach' filepath='net/core/dev.c' line='3143' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_device_detach'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='3143' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netif_napi_add' mangled-name='netif_napi_add' filepath='net/core/dev.c' line='6744' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_napi_add'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='6744' column='1'/>
-        <parameter type-id='c50361c5' name='napi' filepath='net/core/dev.c' line='6744' column='1'/>
-        <parameter type-id='f07d90b4' name='poll' filepath='net/core/dev.c' line='6745' column='1'/>
-        <parameter type-id='95e97e5e' name='weight' filepath='net/core/dev.c' line='6745' column='1'/>
+      <function-decl name='netif_napi_add' mangled-name='netif_napi_add' filepath='net/core/dev.c' line='6751' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_napi_add'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='6751' column='1'/>
+        <parameter type-id='c50361c5' name='napi' filepath='net/core/dev.c' line='6751' column='1'/>
+        <parameter type-id='f07d90b4' name='poll' filepath='net/core/dev.c' line='6752' column='1'/>
+        <parameter type-id='95e97e5e' name='weight' filepath='net/core/dev.c' line='6752' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netif_receive_skb' mangled-name='netif_receive_skb' filepath='net/core/dev.c' line='5638' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_receive_skb'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='5638' column='1'/>
+      <function-decl name='netif_receive_skb' mangled-name='netif_receive_skb' filepath='net/core/dev.c' line='5644' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_receive_skb'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='5644' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='netif_receive_skb_core' mangled-name='netif_receive_skb_core' filepath='net/core/dev.c' line='5386' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_receive_skb_core'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='5386' column='1'/>
+      <function-decl name='netif_receive_skb_core' mangled-name='netif_receive_skb_core' filepath='net/core/dev.c' line='5392' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_receive_skb_core'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='5392' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='netif_receive_skb_list' mangled-name='netif_receive_skb_list' filepath='net/core/dev.c' line='5661' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_receive_skb_list'>
-        <parameter type-id='e84b031a' name='head' filepath='net/core/dev.c' line='5661' column='1'/>
+      <function-decl name='netif_receive_skb_list' mangled-name='netif_receive_skb_list' filepath='net/core/dev.c' line='5667' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_receive_skb_list'>
+        <parameter type-id='e84b031a' name='head' filepath='net/core/dev.c' line='5667' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netif_rx' mangled-name='netif_rx' filepath='net/core/dev.c' line='4850' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_rx'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='4850' column='1'/>
+      <function-decl name='netif_rx' mangled-name='netif_rx' filepath='net/core/dev.c' line='4856' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_rx'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='4856' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='netif_rx_ni' mangled-name='netif_rx_ni' filepath='net/core/dev.c' line='4863' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_rx_ni'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='4863' column='1'/>
+      <function-decl name='netif_rx_ni' mangled-name='netif_rx_ni' filepath='net/core/dev.c' line='4869' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_rx_ni'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='4869' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='netif_schedule_queue' mangled-name='netif_schedule_queue' filepath='net/core/dev.c' line='3076' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_schedule_queue'>
-        <parameter type-id='35b28c4f' name='txq' filepath='net/core/dev.c' line='3076' column='1'/>
+      <function-decl name='netif_schedule_queue' mangled-name='netif_schedule_queue' filepath='net/core/dev.c' line='3078' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_schedule_queue'>
+        <parameter type-id='35b28c4f' name='txq' filepath='net/core/dev.c' line='3078' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netif_set_real_num_rx_queues' mangled-name='netif_set_real_num_rx_queues' filepath='net/core/dev.c' line='3011' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_set_real_num_rx_queues'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='3011' column='1'/>
-        <parameter type-id='f0981eeb' name='rxq' filepath='net/core/dev.c' line='3011' column='1'/>
+      <function-decl name='netif_set_real_num_rx_queues' mangled-name='netif_set_real_num_rx_queues' filepath='net/core/dev.c' line='3013' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_set_real_num_rx_queues'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='3013' column='1'/>
+        <parameter type-id='f0981eeb' name='rxq' filepath='net/core/dev.c' line='3013' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='netif_set_real_num_tx_queues' mangled-name='netif_set_real_num_tx_queues' filepath='net/core/dev.c' line='2961' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_set_real_num_tx_queues'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='2961' column='1'/>
-        <parameter type-id='f0981eeb' name='txq' filepath='net/core/dev.c' line='2961' column='1'/>
+      <function-decl name='netif_set_real_num_tx_queues' mangled-name='netif_set_real_num_tx_queues' filepath='net/core/dev.c' line='2963' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_set_real_num_tx_queues'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='2963' column='1'/>
+        <parameter type-id='f0981eeb' name='txq' filepath='net/core/dev.c' line='2963' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='netif_set_xps_queue' mangled-name='netif_set_xps_queue' filepath='net/core/dev.c' line='2825' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_set_xps_queue'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='2825' column='1'/>
-        <parameter type-id='5f8a1ac4' name='mask' filepath='net/core/dev.c' line='2825' column='1'/>
-        <parameter type-id='1dc6a898' name='index' filepath='net/core/dev.c' line='2826' column='1'/>
+      <function-decl name='netif_set_xps_queue' mangled-name='netif_set_xps_queue' filepath='net/core/dev.c' line='2827' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_set_xps_queue'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='2827' column='1'/>
+        <parameter type-id='5f8a1ac4' name='mask' filepath='net/core/dev.c' line='2827' column='1'/>
+        <parameter type-id='1dc6a898' name='index' filepath='net/core/dev.c' line='2828' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='netif_stacked_transfer_operstate' mangled-name='netif_stacked_transfer_operstate' filepath='net/core/dev.c' line='9778' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_stacked_transfer_operstate'>
-        <parameter type-id='2ce52478' name='rootdev' filepath='net/core/dev.c' line='9778' column='1'/>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='9779' column='1'/>
+      <function-decl name='netif_stacked_transfer_operstate' mangled-name='netif_stacked_transfer_operstate' filepath='net/core/dev.c' line='9785' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_stacked_transfer_operstate'>
+        <parameter type-id='2ce52478' name='rootdev' filepath='net/core/dev.c' line='9785' column='1'/>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='9786' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netif_tx_stop_all_queues' mangled-name='netif_tx_stop_all_queues' filepath='net/core/dev.c' line='9886' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_tx_stop_all_queues'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='9886' column='1'/>
+      <function-decl name='netif_tx_stop_all_queues' mangled-name='netif_tx_stop_all_queues' filepath='net/core/dev.c' line='9893' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_tx_stop_all_queues'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='9893' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netif_tx_wake_queue' mangled-name='netif_tx_wake_queue' filepath='net/core/dev.c' line='3088' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_tx_wake_queue'>
-        <parameter type-id='35b28c4f' name='dev_queue' filepath='net/core/dev.c' line='3088' column='1'/>
+      <function-decl name='netif_tx_wake_queue' mangled-name='netif_tx_wake_queue' filepath='net/core/dev.c' line='3090' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netif_tx_wake_queue'>
+        <parameter type-id='35b28c4f' name='dev_queue' filepath='net/core/dev.c' line='3090' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netlink_ack' mangled-name='netlink_ack' filepath='net/netlink/af_netlink.c' line='2417' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_ack'>
-        <parameter type-id='0fbf3cfd' name='in_skb' filepath='net/netlink/af_netlink.c' line='2417' column='1'/>
-        <parameter type-id='c2074578' name='nlh' filepath='net/netlink/af_netlink.c' line='2417' column='1'/>
-        <parameter type-id='95e97e5e' name='err' filepath='net/netlink/af_netlink.c' line='2417' column='1'/>
-        <parameter type-id='f1dc7839' name='extack' filepath='net/netlink/af_netlink.c' line='2418' column='1'/>
+      <function-decl name='netlink_ack' mangled-name='netlink_ack' filepath='net/netlink/af_netlink.c' line='2399' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_ack'>
+        <parameter type-id='0fbf3cfd' name='in_skb' filepath='net/netlink/af_netlink.c' line='2399' column='1'/>
+        <parameter type-id='c2074578' name='nlh' filepath='net/netlink/af_netlink.c' line='2399' column='1'/>
+        <parameter type-id='95e97e5e' name='err' filepath='net/netlink/af_netlink.c' line='2399' column='1'/>
+        <parameter type-id='f1dc7839' name='extack' filepath='net/netlink/af_netlink.c' line='2400' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netlink_broadcast' mangled-name='netlink_broadcast' filepath='net/netlink/af_netlink.c' line='1542' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_broadcast'>
-        <parameter type-id='f772df6d' name='ssk' filepath='net/netlink/af_netlink.c' line='1542' column='1'/>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/netlink/af_netlink.c' line='1542' column='1'/>
-        <parameter type-id='19c2251e' name='portid' filepath='net/netlink/af_netlink.c' line='1542' column='1'/>
-        <parameter type-id='19c2251e' name='group' filepath='net/netlink/af_netlink.c' line='1543' column='1'/>
-        <parameter type-id='3eb7c31c' name='allocation' filepath='net/netlink/af_netlink.c' line='1543' column='1'/>
+      <function-decl name='netlink_broadcast' mangled-name='netlink_broadcast' filepath='net/netlink/af_netlink.c' line='1551' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_broadcast'>
+        <parameter type-id='f772df6d' name='ssk' filepath='net/netlink/af_netlink.c' line='1551' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/netlink/af_netlink.c' line='1551' column='1'/>
+        <parameter type-id='19c2251e' name='portid' filepath='net/netlink/af_netlink.c' line='1551' column='1'/>
+        <parameter type-id='19c2251e' name='group' filepath='net/netlink/af_netlink.c' line='1552' column='1'/>
+        <parameter type-id='3eb7c31c' name='allocation' filepath='net/netlink/af_netlink.c' line='1552' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='netlink_capable' mangled-name='netlink_capable' filepath='net/netlink/af_netlink.c' line='895' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_capable'>
-        <parameter type-id='11f4a000' name='skb' filepath='net/netlink/af_netlink.c' line='895' column='1'/>
-        <parameter type-id='95e97e5e' name='cap' filepath='net/netlink/af_netlink.c' line='895' column='1'/>
+      <function-decl name='netlink_capable' mangled-name='netlink_capable' filepath='net/netlink/af_netlink.c' line='897' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_capable'>
+        <parameter type-id='11f4a000' name='skb' filepath='net/netlink/af_netlink.c' line='897' column='1'/>
+        <parameter type-id='95e97e5e' name='cap' filepath='net/netlink/af_netlink.c' line='897' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='netlink_has_listeners' mangled-name='netlink_has_listeners' filepath='net/netlink/af_netlink.c' line='1358' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_has_listeners'>
-        <parameter type-id='f772df6d' name='sk' filepath='net/netlink/af_netlink.c' line='1358' column='1'/>
-        <parameter type-id='f0981eeb' name='group' filepath='net/netlink/af_netlink.c' line='1358' column='1'/>
+      <function-decl name='netlink_has_listeners' mangled-name='netlink_has_listeners' filepath='net/netlink/af_netlink.c' line='1367' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_has_listeners'>
+        <parameter type-id='f772df6d' name='sk' filepath='net/netlink/af_netlink.c' line='1367' column='1'/>
+        <parameter type-id='f0981eeb' name='group' filepath='net/netlink/af_netlink.c' line='1367' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='netlink_kernel_release' mangled-name='netlink_kernel_release' filepath='net/netlink/af_netlink.c' line='2116' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_kernel_release'>
-        <parameter type-id='f772df6d' name='sk' filepath='net/netlink/af_netlink.c' line='2116' column='1'/>
+      <function-decl name='netlink_kernel_release' mangled-name='netlink_kernel_release' filepath='net/netlink/af_netlink.c' line='2098' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_kernel_release'>
+        <parameter type-id='f772df6d' name='sk' filepath='net/netlink/af_netlink.c' line='2098' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='netlink_register_notifier' mangled-name='netlink_register_notifier' filepath='net/netlink/af_netlink.c' line='2755' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_register_notifier'>
-        <parameter type-id='d504f73d' name='nb' filepath='net/netlink/af_netlink.c' line='2755' column='1'/>
+      <function-decl name='netlink_register_notifier' mangled-name='netlink_register_notifier' filepath='net/netlink/af_netlink.c' line='2737' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_register_notifier'>
+        <parameter type-id='d504f73d' name='nb' filepath='net/netlink/af_netlink.c' line='2737' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='netlink_unicast' mangled-name='netlink_unicast' filepath='net/netlink/af_netlink.c' line='1322' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_unicast'>
-        <parameter type-id='f772df6d' name='ssk' filepath='net/netlink/af_netlink.c' line='1322' column='1'/>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/netlink/af_netlink.c' line='1322' column='1'/>
-        <parameter type-id='19c2251e' name='portid' filepath='net/netlink/af_netlink.c' line='1323' column='1'/>
-        <parameter type-id='95e97e5e' name='nonblock' filepath='net/netlink/af_netlink.c' line='1323' column='1'/>
+      <function-decl name='netlink_unicast' mangled-name='netlink_unicast' filepath='net/netlink/af_netlink.c' line='1331' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_unicast'>
+        <parameter type-id='f772df6d' name='ssk' filepath='net/netlink/af_netlink.c' line='1331' column='1'/>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/netlink/af_netlink.c' line='1331' column='1'/>
+        <parameter type-id='19c2251e' name='portid' filepath='net/netlink/af_netlink.c' line='1332' column='1'/>
+        <parameter type-id='95e97e5e' name='nonblock' filepath='net/netlink/af_netlink.c' line='1332' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='netlink_unregister_notifier' mangled-name='netlink_unregister_notifier' filepath='net/netlink/af_netlink.c' line='2761' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_unregister_notifier'>
-        <parameter type-id='d504f73d' name='nb' filepath='net/netlink/af_netlink.c' line='2761' column='1'/>
+      <function-decl name='netlink_unregister_notifier' mangled-name='netlink_unregister_notifier' filepath='net/netlink/af_netlink.c' line='2743' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='netlink_unregister_notifier'>
+        <parameter type-id='d504f73d' name='nb' filepath='net/netlink/af_netlink.c' line='2743' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='new_inode' mangled-name='new_inode' filepath='fs/inode.c' line='952' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='new_inode'>
         <parameter type-id='42c8f564' name='sb' filepath='fs/inode.c' line='952' column='1'/>
         <return type-id='7e666abe'/>
       </function-decl>
-      <function-decl name='nf_conntrack_destroy' mangled-name='nf_conntrack_destroy' filepath='net/netfilter/core.c' line='671' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nf_conntrack_destroy'>
-        <parameter type-id='96b07343' name='nfct' filepath='net/netfilter/core.c' line='671' column='1'/>
+      <function-decl name='nf_conntrack_destroy' mangled-name='nf_conntrack_destroy' filepath='net/netfilter/core.c' line='665' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nf_conntrack_destroy'>
+        <parameter type-id='96b07343' name='nfct' filepath='net/netfilter/core.c' line='665' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='nf_ct_attach' mangled-name='nf_ct_attach' filepath='net/netfilter/core.c' line='657' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nf_ct_attach'>
-        <parameter type-id='0fbf3cfd' name='new' filepath='net/netfilter/core.c' line='657' column='1'/>
-        <parameter type-id='11f4a000' name='skb' filepath='net/netfilter/core.c' line='657' column='1'/>
+      <function-decl name='nf_ct_attach' mangled-name='nf_ct_attach' filepath='net/netfilter/core.c' line='651' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nf_ct_attach'>
+        <parameter type-id='0fbf3cfd' name='new' filepath='net/netfilter/core.c' line='651' column='1'/>
+        <parameter type-id='11f4a000' name='skb' filepath='net/netfilter/core.c' line='651' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='nf_ct_delete' mangled-name='nf_ct_delete' filepath='net/netfilter/nf_conntrack_core.c' line='655' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nf_ct_delete'>
@@ -136836,84 +137561,84 @@
         <parameter type-id='95e97e5e' name='report' filepath='net/netfilter/nf_conntrack_core.c' line='655' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='nf_register_net_hook' mangled-name='nf_register_net_hook' filepath='net/netfilter/core.c' line='521' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nf_register_net_hook'>
-        <parameter type-id='a2bff676' name='net' filepath='net/netfilter/core.c' line='521' column='1'/>
-        <parameter type-id='27db53a1' name='reg' filepath='net/netfilter/core.c' line='521' column='1'/>
+      <function-decl name='nf_register_net_hook' mangled-name='nf_register_net_hook' filepath='net/netfilter/core.c' line='515' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nf_register_net_hook'>
+        <parameter type-id='a2bff676' name='net' filepath='net/netfilter/core.c' line='515' column='1'/>
+        <parameter type-id='27db53a1' name='reg' filepath='net/netfilter/core.c' line='515' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='nf_register_net_hooks' mangled-name='nf_register_net_hooks' filepath='net/netfilter/core.c' line='551' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nf_register_net_hooks'>
-        <parameter type-id='a2bff676' name='net' filepath='net/netfilter/core.c' line='551' column='1'/>
-        <parameter type-id='27db53a1' name='reg' filepath='net/netfilter/core.c' line='551' column='1'/>
-        <parameter type-id='f0981eeb' name='n' filepath='net/netfilter/core.c' line='552' column='1'/>
+      <function-decl name='nf_register_net_hooks' mangled-name='nf_register_net_hooks' filepath='net/netfilter/core.c' line='545' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nf_register_net_hooks'>
+        <parameter type-id='a2bff676' name='net' filepath='net/netfilter/core.c' line='545' column='1'/>
+        <parameter type-id='27db53a1' name='reg' filepath='net/netfilter/core.c' line='545' column='1'/>
+        <parameter type-id='f0981eeb' name='n' filepath='net/netfilter/core.c' line='546' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='nf_unregister_net_hook' mangled-name='nf_unregister_net_hook' filepath='net/netfilter/core.c' line='493' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nf_unregister_net_hook'>
-        <parameter type-id='a2bff676' name='net' filepath='net/netfilter/core.c' line='493' column='1'/>
-        <parameter type-id='27db53a1' name='reg' filepath='net/netfilter/core.c' line='493' column='1'/>
+      <function-decl name='nf_unregister_net_hook' mangled-name='nf_unregister_net_hook' filepath='net/netfilter/core.c' line='487' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nf_unregister_net_hook'>
+        <parameter type-id='a2bff676' name='net' filepath='net/netfilter/core.c' line='487' column='1'/>
+        <parameter type-id='27db53a1' name='reg' filepath='net/netfilter/core.c' line='487' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='nf_unregister_net_hooks' mangled-name='nf_unregister_net_hooks' filepath='net/netfilter/core.c' line='571' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nf_unregister_net_hooks'>
-        <parameter type-id='a2bff676' name='net' filepath='net/netfilter/core.c' line='571' column='1'/>
-        <parameter type-id='27db53a1' name='reg' filepath='net/netfilter/core.c' line='571' column='1'/>
-        <parameter type-id='f0981eeb' name='hookcount' filepath='net/netfilter/core.c' line='572' column='1'/>
+      <function-decl name='nf_unregister_net_hooks' mangled-name='nf_unregister_net_hooks' filepath='net/netfilter/core.c' line='565' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nf_unregister_net_hooks'>
+        <parameter type-id='a2bff676' name='net' filepath='net/netfilter/core.c' line='565' column='1'/>
+        <parameter type-id='27db53a1' name='reg' filepath='net/netfilter/core.c' line='565' column='1'/>
+        <parameter type-id='f0981eeb' name='hookcount' filepath='net/netfilter/core.c' line='566' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='nla_append' mangled-name='nla_append' filepath='lib/nlattr.c' line='1101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_append'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='lib/nlattr.c' line='1101' column='1'/>
-        <parameter type-id='95e97e5e' name='attrlen' filepath='lib/nlattr.c' line='1101' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='lib/nlattr.c' line='1101' column='1'/>
+      <function-decl name='nla_append' mangled-name='nla_append' filepath='lib/nlattr.c' line='1104' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_append'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='lib/nlattr.c' line='1104' column='1'/>
+        <parameter type-id='95e97e5e' name='attrlen' filepath='lib/nlattr.c' line='1104' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='lib/nlattr.c' line='1104' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='nla_find' mangled-name='nla_find' filepath='lib/nlattr.c' line='698' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_find'>
-        <parameter type-id='0f2a7ce5' name='head' filepath='lib/nlattr.c' line='698' column='1'/>
-        <parameter type-id='95e97e5e' name='len' filepath='lib/nlattr.c' line='698' column='1'/>
-        <parameter type-id='95e97e5e' name='attrtype' filepath='lib/nlattr.c' line='698' column='1'/>
+      <function-decl name='nla_find' mangled-name='nla_find' filepath='lib/nlattr.c' line='701' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_find'>
+        <parameter type-id='0f2a7ce5' name='head' filepath='lib/nlattr.c' line='701' column='1'/>
+        <parameter type-id='95e97e5e' name='len' filepath='lib/nlattr.c' line='701' column='1'/>
+        <parameter type-id='95e97e5e' name='attrtype' filepath='lib/nlattr.c' line='701' column='1'/>
         <return type-id='6fcaf91e'/>
       </function-decl>
-      <function-decl name='nla_memcpy' mangled-name='nla_memcpy' filepath='lib/nlattr.c' line='777' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_memcpy'>
-        <parameter type-id='eaa32e2f' name='dest' filepath='lib/nlattr.c' line='777' column='1'/>
-        <parameter type-id='0f2a7ce5' name='src' filepath='lib/nlattr.c' line='777' column='1'/>
-        <parameter type-id='95e97e5e' name='count' filepath='lib/nlattr.c' line='777' column='1'/>
+      <function-decl name='nla_memcpy' mangled-name='nla_memcpy' filepath='lib/nlattr.c' line='780' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_memcpy'>
+        <parameter type-id='eaa32e2f' name='dest' filepath='lib/nlattr.c' line='780' column='1'/>
+        <parameter type-id='0f2a7ce5' name='src' filepath='lib/nlattr.c' line='780' column='1'/>
+        <parameter type-id='95e97e5e' name='count' filepath='lib/nlattr.c' line='780' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='nla_put' mangled-name='nla_put' filepath='lib/nlattr.c' line='1035' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_put'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='lib/nlattr.c' line='1035' column='1'/>
-        <parameter type-id='95e97e5e' name='attrtype' filepath='lib/nlattr.c' line='1035' column='1'/>
-        <parameter type-id='95e97e5e' name='attrlen' filepath='lib/nlattr.c' line='1035' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='lib/nlattr.c' line='1035' column='1'/>
+      <function-decl name='nla_put' mangled-name='nla_put' filepath='lib/nlattr.c' line='1038' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_put'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='lib/nlattr.c' line='1038' column='1'/>
+        <parameter type-id='95e97e5e' name='attrtype' filepath='lib/nlattr.c' line='1038' column='1'/>
+        <parameter type-id='95e97e5e' name='attrlen' filepath='lib/nlattr.c' line='1038' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='lib/nlattr.c' line='1038' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='nla_put_64bit' mangled-name='nla_put_64bit' filepath='lib/nlattr.c' line='1056' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_put_64bit'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='lib/nlattr.c' line='1056' column='1'/>
-        <parameter type-id='95e97e5e' name='attrtype' filepath='lib/nlattr.c' line='1056' column='1'/>
-        <parameter type-id='95e97e5e' name='attrlen' filepath='lib/nlattr.c' line='1056' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='lib/nlattr.c' line='1057' column='1'/>
-        <parameter type-id='95e97e5e' name='padattr' filepath='lib/nlattr.c' line='1057' column='1'/>
+      <function-decl name='nla_put_64bit' mangled-name='nla_put_64bit' filepath='lib/nlattr.c' line='1059' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_put_64bit'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='lib/nlattr.c' line='1059' column='1'/>
+        <parameter type-id='95e97e5e' name='attrtype' filepath='lib/nlattr.c' line='1059' column='1'/>
+        <parameter type-id='95e97e5e' name='attrlen' filepath='lib/nlattr.c' line='1059' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='lib/nlattr.c' line='1060' column='1'/>
+        <parameter type-id='95e97e5e' name='padattr' filepath='lib/nlattr.c' line='1060' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='nla_put_nohdr' mangled-name='nla_put_nohdr' filepath='lib/nlattr.c' line='1082' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_put_nohdr'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='lib/nlattr.c' line='1082' column='1'/>
-        <parameter type-id='95e97e5e' name='attrlen' filepath='lib/nlattr.c' line='1082' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='lib/nlattr.c' line='1082' column='1'/>
+      <function-decl name='nla_put_nohdr' mangled-name='nla_put_nohdr' filepath='lib/nlattr.c' line='1085' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_put_nohdr'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='lib/nlattr.c' line='1085' column='1'/>
+        <parameter type-id='95e97e5e' name='attrlen' filepath='lib/nlattr.c' line='1085' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='lib/nlattr.c' line='1085' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='nla_reserve' mangled-name='nla_reserve' filepath='lib/nlattr.c' line='908' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_reserve'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='lib/nlattr.c' line='908' column='1'/>
-        <parameter type-id='95e97e5e' name='attrtype' filepath='lib/nlattr.c' line='908' column='1'/>
-        <parameter type-id='95e97e5e' name='attrlen' filepath='lib/nlattr.c' line='908' column='1'/>
+      <function-decl name='nla_reserve' mangled-name='nla_reserve' filepath='lib/nlattr.c' line='911' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_reserve'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='lib/nlattr.c' line='911' column='1'/>
+        <parameter type-id='95e97e5e' name='attrtype' filepath='lib/nlattr.c' line='911' column='1'/>
+        <parameter type-id='95e97e5e' name='attrlen' filepath='lib/nlattr.c' line='911' column='1'/>
         <return type-id='6fcaf91e'/>
       </function-decl>
-      <function-decl name='nla_reserve_64bit' mangled-name='nla_reserve_64bit' filepath='lib/nlattr.c' line='931' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_reserve_64bit'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='lib/nlattr.c' line='931' column='1'/>
-        <parameter type-id='95e97e5e' name='attrtype' filepath='lib/nlattr.c' line='931' column='1'/>
-        <parameter type-id='95e97e5e' name='attrlen' filepath='lib/nlattr.c' line='931' column='1'/>
-        <parameter type-id='95e97e5e' name='padattr' filepath='lib/nlattr.c' line='932' column='1'/>
+      <function-decl name='nla_reserve_64bit' mangled-name='nla_reserve_64bit' filepath='lib/nlattr.c' line='934' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_reserve_64bit'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='lib/nlattr.c' line='934' column='1'/>
+        <parameter type-id='95e97e5e' name='attrtype' filepath='lib/nlattr.c' line='934' column='1'/>
+        <parameter type-id='95e97e5e' name='attrlen' filepath='lib/nlattr.c' line='934' column='1'/>
+        <parameter type-id='95e97e5e' name='padattr' filepath='lib/nlattr.c' line='935' column='1'/>
         <return type-id='6fcaf91e'/>
       </function-decl>
-      <function-decl name='nla_strlcpy' mangled-name='nla_strlcpy' filepath='lib/nlattr.c' line='723' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_strlcpy'>
-        <parameter type-id='26a90f95' name='dst' filepath='lib/nlattr.c' line='723' column='1'/>
-        <parameter type-id='0f2a7ce5' name='nla' filepath='lib/nlattr.c' line='723' column='1'/>
-        <parameter type-id='b59d7dce' name='dstsize' filepath='lib/nlattr.c' line='723' column='1'/>
+      <function-decl name='nla_strlcpy' mangled-name='nla_strlcpy' filepath='lib/nlattr.c' line='726' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nla_strlcpy'>
+        <parameter type-id='26a90f95' name='dst' filepath='lib/nlattr.c' line='726' column='1'/>
+        <parameter type-id='0f2a7ce5' name='nla' filepath='lib/nlattr.c' line='726' column='1'/>
+        <parameter type-id='b59d7dce' name='dstsize' filepath='lib/nlattr.c' line='726' column='1'/>
         <return type-id='b59d7dce'/>
       </function-decl>
       <function-decl name='no_llseek' mangled-name='no_llseek' filepath='fs/read_write.c' line='230' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='no_llseek'>
@@ -136928,9 +137653,9 @@
         <parameter type-id='95e97e5e' name='whence' filepath='fs/read_write.c' line='181' column='1'/>
         <return type-id='69bf7bee'/>
       </function-decl>
-      <function-decl name='nonseekable_open' mangled-name='nonseekable_open' filepath='fs/open.c' line='1401' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nonseekable_open'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/open.c' line='1401' column='1'/>
-        <parameter type-id='77e79a4b' name='filp' filepath='fs/open.c' line='1401' column='1'/>
+      <function-decl name='nonseekable_open' mangled-name='nonseekable_open' filepath='fs/open.c' line='1407' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nonseekable_open'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/open.c' line='1407' column='1'/>
+        <parameter type-id='77e79a4b' name='filp' filepath='fs/open.c' line='1407' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='noop_llseek' mangled-name='noop_llseek' filepath='fs/read_write.c' line='224' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='noop_llseek'>
@@ -136939,13 +137664,16 @@
         <parameter type-id='95e97e5e' name='whence' filepath='fs/read_write.c' line='224' column='1'/>
         <return type-id='69bf7bee'/>
       </function-decl>
-      <function-decl name='notify_change' mangled-name='notify_change' filepath='fs/attr.c' line='225' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='notify_change'>
-        <parameter type-id='27675065' name='dentry' filepath='fs/attr.c' line='225' column='1'/>
-        <parameter type-id='ab7bbd67' name='attr' filepath='fs/attr.c' line='225' column='1'/>
-        <parameter type-id='8f39c6fc' name='delegated_inode' filepath='fs/attr.c' line='225' column='1'/>
+      <function-decl name='notify_change' mangled-name='notify_change' filepath='fs/attr.c' line='281' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='notify_change'>
+        <parameter type-id='27675065' name='dentry' filepath='fs/attr.c' line='281' column='1'/>
+        <parameter type-id='ab7bbd67' name='attr' filepath='fs/attr.c' line='281' column='1'/>
+        <parameter type-id='8f39c6fc' name='delegated_inode' filepath='fs/attr.c' line='281' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <var-decl name='nr_cpu_ids' type-id='f0981eeb' mangled-name='nr_cpu_ids' visibility='default' filepath='kernel/smp.c' line='796' column='1' elf-symbol-id='nr_cpu_ids'/>
+      <function-decl name='nr_free_buffer_pages' mangled-name='nr_free_buffer_pages' filepath='mm/page_alloc.c' line='5542' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nr_free_buffer_pages'>
+        <return type-id='7359adad'/>
+      </function-decl>
       <function-decl name='nr_ipi_get' mangled-name='nr_ipi_get' filepath='arch/arm64/kernel/smp.c' line='1147' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nr_ipi_get'>
         <return type-id='95e97e5e'/>
       </function-decl>
@@ -136986,61 +137714,61 @@
         <parameter type-id='22ab35e2' name='ndr_desc' filepath='drivers/nvdimm/region_devs.c' line='1154' column='1'/>
         <return type-id='14dc741a'/>
       </function-decl>
-      <function-decl name='nvmem_cell_get' mangled-name='nvmem_cell_get' filepath='drivers/nvmem/core.c' line='1111' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_cell_get'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='1111' column='1'/>
-        <parameter type-id='80f4b756' name='id' filepath='drivers/nvmem/core.c' line='1111' column='1'/>
+      <function-decl name='nvmem_cell_get' mangled-name='nvmem_cell_get' filepath='drivers/nvmem/core.c' line='1117' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_cell_get'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='1117' column='1'/>
+        <parameter type-id='80f4b756' name='id' filepath='drivers/nvmem/core.c' line='1117' column='1'/>
         <return type-id='4a4ce85f'/>
       </function-decl>
-      <function-decl name='nvmem_cell_put' mangled-name='nvmem_cell_put' filepath='drivers/nvmem/core.c' line='1197' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_cell_put'>
-        <parameter type-id='4a4ce85f' name='cell' filepath='drivers/nvmem/core.c' line='1197' column='1'/>
+      <function-decl name='nvmem_cell_put' mangled-name='nvmem_cell_put' filepath='drivers/nvmem/core.c' line='1203' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_cell_put'>
+        <parameter type-id='4a4ce85f' name='cell' filepath='drivers/nvmem/core.c' line='1203' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='nvmem_cell_read' mangled-name='nvmem_cell_read' filepath='drivers/nvmem/core.c' line='1269' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_cell_read'>
-        <parameter type-id='4a4ce85f' name='cell' filepath='drivers/nvmem/core.c' line='1269' column='1'/>
-        <parameter type-id='78c01427' name='len' filepath='drivers/nvmem/core.c' line='1269' column='1'/>
+      <function-decl name='nvmem_cell_read' mangled-name='nvmem_cell_read' filepath='drivers/nvmem/core.c' line='1275' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_cell_read'>
+        <parameter type-id='4a4ce85f' name='cell' filepath='drivers/nvmem/core.c' line='1275' column='1'/>
+        <parameter type-id='78c01427' name='len' filepath='drivers/nvmem/core.c' line='1275' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='nvmem_cell_read_u32' mangled-name='nvmem_cell_read_u32' filepath='drivers/nvmem/core.c' line='1449' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_cell_read_u32'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='1449' column='1'/>
-        <parameter type-id='80f4b756' name='cell_id' filepath='drivers/nvmem/core.c' line='1449' column='1'/>
-        <parameter type-id='f9409001' name='val' filepath='drivers/nvmem/core.c' line='1449' column='1'/>
+      <function-decl name='nvmem_cell_read_u32' mangled-name='nvmem_cell_read_u32' filepath='drivers/nvmem/core.c' line='1455' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_cell_read_u32'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='1455' column='1'/>
+        <parameter type-id='80f4b756' name='cell_id' filepath='drivers/nvmem/core.c' line='1455' column='1'/>
+        <parameter type-id='f9409001' name='val' filepath='drivers/nvmem/core.c' line='1455' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='nvmem_cell_write' mangled-name='nvmem_cell_write' filepath='drivers/nvmem/core.c' line='1354' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_cell_write'>
-        <parameter type-id='4a4ce85f' name='cell' filepath='drivers/nvmem/core.c' line='1354' column='1'/>
-        <parameter type-id='eaa32e2f' name='buf' filepath='drivers/nvmem/core.c' line='1354' column='1'/>
-        <parameter type-id='b59d7dce' name='len' filepath='drivers/nvmem/core.c' line='1354' column='1'/>
+      <function-decl name='nvmem_cell_write' mangled-name='nvmem_cell_write' filepath='drivers/nvmem/core.c' line='1360' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_cell_write'>
+        <parameter type-id='4a4ce85f' name='cell' filepath='drivers/nvmem/core.c' line='1360' column='1'/>
+        <parameter type-id='eaa32e2f' name='buf' filepath='drivers/nvmem/core.c' line='1360' column='1'/>
+        <parameter type-id='b59d7dce' name='len' filepath='drivers/nvmem/core.c' line='1360' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='nvmem_device_get' mangled-name='nvmem_device_get' filepath='drivers/nvmem/core.c' line='887' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_device_get'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='887' column='1'/>
-        <parameter type-id='80f4b756' name='dev_name' filepath='drivers/nvmem/core.c' line='887' column='1'/>
+      <function-decl name='nvmem_device_get' mangled-name='nvmem_device_get' filepath='drivers/nvmem/core.c' line='893' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_device_get'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='893' column='1'/>
+        <parameter type-id='80f4b756' name='dev_name' filepath='drivers/nvmem/core.c' line='893' column='1'/>
         <return type-id='8179bc49'/>
       </function-decl>
-      <function-decl name='nvmem_device_put' mangled-name='nvmem_device_put' filepath='drivers/nvmem/core.c' line='957' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_device_put'>
-        <parameter type-id='8179bc49' name='nvmem' filepath='drivers/nvmem/core.c' line='957' column='1'/>
+      <function-decl name='nvmem_device_put' mangled-name='nvmem_device_put' filepath='drivers/nvmem/core.c' line='963' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_device_put'>
+        <parameter type-id='8179bc49' name='nvmem' filepath='drivers/nvmem/core.c' line='963' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='nvmem_device_read' mangled-name='nvmem_device_read' filepath='drivers/nvmem/core.c' line='1539' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_device_read'>
-        <parameter type-id='8179bc49' name='nvmem' filepath='drivers/nvmem/core.c' line='1539' column='1'/>
-        <parameter type-id='f0981eeb' name='offset' filepath='drivers/nvmem/core.c' line='1540' column='1'/>
-        <parameter type-id='b59d7dce' name='bytes' filepath='drivers/nvmem/core.c' line='1541' column='1'/>
-        <parameter type-id='eaa32e2f' name='buf' filepath='drivers/nvmem/core.c' line='1541' column='1'/>
+      <function-decl name='nvmem_device_read' mangled-name='nvmem_device_read' filepath='drivers/nvmem/core.c' line='1545' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_device_read'>
+        <parameter type-id='8179bc49' name='nvmem' filepath='drivers/nvmem/core.c' line='1545' column='1'/>
+        <parameter type-id='f0981eeb' name='offset' filepath='drivers/nvmem/core.c' line='1546' column='1'/>
+        <parameter type-id='b59d7dce' name='bytes' filepath='drivers/nvmem/core.c' line='1547' column='1'/>
+        <parameter type-id='eaa32e2f' name='buf' filepath='drivers/nvmem/core.c' line='1547' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='nvmem_device_write' mangled-name='nvmem_device_write' filepath='drivers/nvmem/core.c' line='1567' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_device_write'>
-        <parameter type-id='8179bc49' name='nvmem' filepath='drivers/nvmem/core.c' line='1567' column='1'/>
-        <parameter type-id='f0981eeb' name='offset' filepath='drivers/nvmem/core.c' line='1568' column='1'/>
-        <parameter type-id='b59d7dce' name='bytes' filepath='drivers/nvmem/core.c' line='1569' column='1'/>
-        <parameter type-id='eaa32e2f' name='buf' filepath='drivers/nvmem/core.c' line='1569' column='1'/>
+      <function-decl name='nvmem_device_write' mangled-name='nvmem_device_write' filepath='drivers/nvmem/core.c' line='1573' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_device_write'>
+        <parameter type-id='8179bc49' name='nvmem' filepath='drivers/nvmem/core.c' line='1573' column='1'/>
+        <parameter type-id='f0981eeb' name='offset' filepath='drivers/nvmem/core.c' line='1574' column='1'/>
+        <parameter type-id='b59d7dce' name='bytes' filepath='drivers/nvmem/core.c' line='1575' column='1'/>
+        <parameter type-id='eaa32e2f' name='buf' filepath='drivers/nvmem/core.c' line='1575' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='nvmem_register' mangled-name='nvmem_register' filepath='drivers/nvmem/core.c' line='607' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_register'>
         <parameter type-id='7bb280fa' name='config' filepath='drivers/nvmem/core.c' line='607' column='1'/>
         <return type-id='8179bc49'/>
       </function-decl>
-      <function-decl name='nvmem_unregister' mangled-name='nvmem_unregister' filepath='drivers/nvmem/core.c' line='746' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_unregister'>
-        <parameter type-id='8179bc49' name='nvmem' filepath='drivers/nvmem/core.c' line='746' column='1'/>
+      <function-decl name='nvmem_unregister' mangled-name='nvmem_unregister' filepath='drivers/nvmem/core.c' line='752' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_unregister'>
+        <parameter type-id='8179bc49' name='nvmem' filepath='drivers/nvmem/core.c' line='752' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='of_address_to_resource' mangled-name='of_address_to_resource' filepath='drivers/of/address.c' line='866' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_address_to_resource'>
@@ -137049,83 +137777,89 @@
         <parameter type-id='c9d64c0d' name='r' filepath='drivers/of/address.c' line='867' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='of_alias_get_highest_id' mangled-name='of_alias_get_highest_id' filepath='drivers/of/base.c' line='2113' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_alias_get_highest_id'>
-        <parameter type-id='80f4b756' name='stem' filepath='drivers/of/base.c' line='2113' column='1'/>
+      <function-decl name='of_alias_get_highest_id' mangled-name='of_alias_get_highest_id' filepath='drivers/of/base.c' line='2140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_alias_get_highest_id'>
+        <parameter type-id='80f4b756' name='stem' filepath='drivers/of/base.c' line='2140' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='of_alias_get_id' mangled-name='of_alias_get_id' filepath='drivers/of/base.c' line='2032' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_alias_get_id'>
-        <parameter type-id='9a537bbe' name='np' filepath='drivers/of/base.c' line='2032' column='1'/>
-        <parameter type-id='80f4b756' name='stem' filepath='drivers/of/base.c' line='2032' column='1'/>
+      <function-decl name='of_alias_get_id' mangled-name='of_alias_get_id' filepath='drivers/of/base.c' line='2059' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_alias_get_id'>
+        <parameter type-id='9a537bbe' name='np' filepath='drivers/of/base.c' line='2059' column='1'/>
+        <parameter type-id='80f4b756' name='stem' filepath='drivers/of/base.c' line='2059' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='of_clk_add_hw_provider' mangled-name='of_clk_add_hw_provider' filepath='drivers/clk/clk.c' line='4702' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_add_hw_provider'>
-        <parameter type-id='9a537bbe' name='np' filepath='drivers/clk/clk.c' line='4702' column='1'/>
-        <parameter type-id='a5186342' name='get' filepath='drivers/clk/clk.c' line='4703' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/clk/clk.c' line='4705' column='1'/>
+      <function-decl name='of_clk_add_hw_provider' mangled-name='of_clk_add_hw_provider' filepath='drivers/clk/clk.c' line='4713' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_add_hw_provider'>
+        <parameter type-id='9a537bbe' name='np' filepath='drivers/clk/clk.c' line='4713' column='1'/>
+        <parameter type-id='a5186342' name='get' filepath='drivers/clk/clk.c' line='4714' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/clk/clk.c' line='4716' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='of_clk_add_provider' mangled-name='of_clk_add_provider' filepath='drivers/clk/clk.c' line='4660' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_add_provider'>
-        <parameter type-id='9a537bbe' name='np' filepath='drivers/clk/clk.c' line='4660' column='1'/>
-        <parameter type-id='f1c652ac' name='clk_src_get' filepath='drivers/clk/clk.c' line='4661' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/clk/clk.c' line='4663' column='1'/>
+      <function-decl name='of_clk_add_provider' mangled-name='of_clk_add_provider' filepath='drivers/clk/clk.c' line='4671' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_add_provider'>
+        <parameter type-id='9a537bbe' name='np' filepath='drivers/clk/clk.c' line='4671' column='1'/>
+        <parameter type-id='f1c652ac' name='clk_src_get' filepath='drivers/clk/clk.c' line='4672' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/clk/clk.c' line='4674' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='of_clk_del_provider' mangled-name='of_clk_del_provider' filepath='drivers/clk/clk.c' line='4804' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_del_provider'>
-        <parameter type-id='9a537bbe' name='np' filepath='drivers/clk/clk.c' line='4804' column='1'/>
+      <function-decl name='of_clk_del_provider' mangled-name='of_clk_del_provider' filepath='drivers/clk/clk.c' line='4815' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_del_provider'>
+        <parameter type-id='9a537bbe' name='np' filepath='drivers/clk/clk.c' line='4815' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='of_clk_get' mangled-name='of_clk_get' filepath='drivers/clk/clk.c' line='5004' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_get'>
-        <parameter type-id='9a537bbe' name='np' filepath='drivers/clk/clk.c' line='5004' column='1'/>
-        <parameter type-id='95e97e5e' name='index' filepath='drivers/clk/clk.c' line='5004' column='1'/>
+      <function-decl name='of_clk_get' mangled-name='of_clk_get' filepath='drivers/clk/clk.c' line='5015' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_get'>
+        <parameter type-id='9a537bbe' name='np' filepath='drivers/clk/clk.c' line='5015' column='1'/>
+        <parameter type-id='95e97e5e' name='index' filepath='drivers/clk/clk.c' line='5015' column='1'/>
         <return type-id='7d0bc0eb'/>
       </function-decl>
-      <function-decl name='of_clk_get_by_name' mangled-name='of_clk_get_by_name' filepath='drivers/clk/clk.c' line='5019' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_get_by_name'>
-        <parameter type-id='9a537bbe' name='np' filepath='drivers/clk/clk.c' line='5019' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='drivers/clk/clk.c' line='5019' column='1'/>
+      <function-decl name='of_clk_get_by_name' mangled-name='of_clk_get_by_name' filepath='drivers/clk/clk.c' line='5030' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_get_by_name'>
+        <parameter type-id='9a537bbe' name='np' filepath='drivers/clk/clk.c' line='5030' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='drivers/clk/clk.c' line='5030' column='1'/>
         <return type-id='7d0bc0eb'/>
       </function-decl>
-      <function-decl name='of_clk_get_from_provider' mangled-name='of_clk_get_from_provider' filepath='drivers/clk/clk.c' line='4970' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_get_from_provider'>
-        <parameter type-id='51a94113' name='clkspec' filepath='drivers/clk/clk.c' line='4970' column='1'/>
+      <function-decl name='of_clk_get_from_provider' mangled-name='of_clk_get_from_provider' filepath='drivers/clk/clk.c' line='4981' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_get_from_provider'>
+        <parameter type-id='51a94113' name='clkspec' filepath='drivers/clk/clk.c' line='4981' column='1'/>
         <return type-id='7d0bc0eb'/>
       </function-decl>
-      <function-decl name='of_clk_get_parent_count' mangled-name='of_clk_get_parent_count' filepath='drivers/clk/clk.c' line='5034' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_get_parent_count'>
-        <parameter type-id='0afa6ea3' name='np' filepath='drivers/clk/clk.c' line='5034' column='1'/>
+      <function-decl name='of_clk_get_parent_count' mangled-name='of_clk_get_parent_count' filepath='drivers/clk/clk.c' line='5045' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_get_parent_count'>
+        <parameter type-id='0afa6ea3' name='np' filepath='drivers/clk/clk.c' line='5045' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='of_clk_get_parent_name' mangled-name='of_clk_get_parent_name' filepath='drivers/clk/clk.c' line='5046' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_get_parent_name'>
-        <parameter type-id='0afa6ea3' name='np' filepath='drivers/clk/clk.c' line='5046' column='1'/>
-        <parameter type-id='95e97e5e' name='index' filepath='drivers/clk/clk.c' line='5046' column='1'/>
+      <function-decl name='of_clk_get_parent_name' mangled-name='of_clk_get_parent_name' filepath='drivers/clk/clk.c' line='5057' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_get_parent_name'>
+        <parameter type-id='0afa6ea3' name='np' filepath='drivers/clk/clk.c' line='5057' column='1'/>
+        <parameter type-id='95e97e5e' name='index' filepath='drivers/clk/clk.c' line='5057' column='1'/>
         <return type-id='80f4b756'/>
       </function-decl>
-      <function-decl name='of_clk_hw_onecell_get' mangled-name='of_clk_hw_onecell_get' filepath='drivers/clk/clk.c' line='4638' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_hw_onecell_get'>
-        <parameter type-id='51a94113' name='clkspec' filepath='drivers/clk/clk.c' line='4638' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/clk/clk.c' line='4638' column='1'/>
+      <function-decl name='of_clk_hw_onecell_get' mangled-name='of_clk_hw_onecell_get' filepath='drivers/clk/clk.c' line='4649' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_hw_onecell_get'>
+        <parameter type-id='51a94113' name='clkspec' filepath='drivers/clk/clk.c' line='4649' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/clk/clk.c' line='4649' column='1'/>
         <return type-id='3aaeef89'/>
       </function-decl>
-      <function-decl name='of_clk_hw_simple_get' mangled-name='of_clk_hw_simple_get' filepath='drivers/clk/clk.c' line='4617' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_hw_simple_get'>
-        <parameter type-id='51a94113' name='clkspec' filepath='drivers/clk/clk.c' line='4617' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/clk/clk.c' line='4617' column='1'/>
+      <function-decl name='of_clk_hw_simple_get' mangled-name='of_clk_hw_simple_get' filepath='drivers/clk/clk.c' line='4628' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_hw_simple_get'>
+        <parameter type-id='51a94113' name='clkspec' filepath='drivers/clk/clk.c' line='4628' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/clk/clk.c' line='4628' column='1'/>
         <return type-id='3aaeef89'/>
       </function-decl>
-      <function-decl name='of_clk_set_defaults' mangled-name='of_clk_set_defaults' filepath='drivers/clk/clk-conf.c' line='131' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_set_defaults'>
-        <parameter type-id='9a537bbe' name='node' filepath='drivers/clk/clk-conf.c' line='131' column='1'/>
-        <parameter type-id='b50a4934' name='clk_supplier' filepath='drivers/clk/clk-conf.c' line='131' column='1'/>
+      <function-decl name='of_clk_parent_fill' mangled-name='of_clk_parent_fill' filepath='drivers/clk/clk.c' line='5126' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_parent_fill'>
+        <parameter type-id='9a537bbe' name='np' filepath='drivers/clk/clk.c' line='5126' column='1'/>
+        <parameter type-id='7d3cd834' name='parents' filepath='drivers/clk/clk.c' line='5126' column='1'/>
+        <parameter type-id='f0981eeb' name='size' filepath='drivers/clk/clk.c' line='5127' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='of_clk_src_onecell_get' mangled-name='of_clk_src_onecell_get' filepath='drivers/clk/clk.c' line='4623' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_src_onecell_get'>
-        <parameter type-id='51a94113' name='clkspec' filepath='drivers/clk/clk.c' line='4623' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/clk/clk.c' line='4623' column='1'/>
+      <function-decl name='of_clk_set_defaults' mangled-name='of_clk_set_defaults' filepath='drivers/clk/clk-conf.c' line='139' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_set_defaults'>
+        <parameter type-id='9a537bbe' name='node' filepath='drivers/clk/clk-conf.c' line='139' column='1'/>
+        <parameter type-id='b50a4934' name='clk_supplier' filepath='drivers/clk/clk-conf.c' line='139' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='of_clk_src_onecell_get' mangled-name='of_clk_src_onecell_get' filepath='drivers/clk/clk.c' line='4634' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_src_onecell_get'>
+        <parameter type-id='51a94113' name='clkspec' filepath='drivers/clk/clk.c' line='4634' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/clk/clk.c' line='4634' column='1'/>
         <return type-id='7d0bc0eb'/>
       </function-decl>
-      <function-decl name='of_clk_src_simple_get' mangled-name='of_clk_src_simple_get' filepath='drivers/clk/clk.c' line='4610' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_src_simple_get'>
-        <parameter type-id='51a94113' name='clkspec' filepath='drivers/clk/clk.c' line='4610' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/clk/clk.c' line='4611' column='1'/>
+      <function-decl name='of_clk_src_simple_get' mangled-name='of_clk_src_simple_get' filepath='drivers/clk/clk.c' line='4621' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_clk_src_simple_get'>
+        <parameter type-id='51a94113' name='clkspec' filepath='drivers/clk/clk.c' line='4621' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/clk/clk.c' line='4622' column='1'/>
         <return type-id='7d0bc0eb'/>
       </function-decl>
-      <function-decl name='of_count_phandle_with_args' mangled-name='of_count_phandle_with_args' filepath='drivers/of/base.c' line='1743' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_count_phandle_with_args'>
-        <parameter type-id='0afa6ea3' name='np' filepath='drivers/of/base.c' line='1743' column='1'/>
-        <parameter type-id='80f4b756' name='list_name' filepath='drivers/of/base.c' line='1743' column='1'/>
-        <parameter type-id='80f4b756' name='cells_name' filepath='drivers/of/base.c' line='1744' column='1'/>
+      <function-decl name='of_count_phandle_with_args' mangled-name='of_count_phandle_with_args' filepath='drivers/of/base.c' line='1770' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_count_phandle_with_args'>
+        <parameter type-id='0afa6ea3' name='np' filepath='drivers/of/base.c' line='1770' column='1'/>
+        <parameter type-id='80f4b756' name='list_name' filepath='drivers/of/base.c' line='1770' column='1'/>
+        <parameter type-id='80f4b756' name='cells_name' filepath='drivers/of/base.c' line='1771' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='of_cpu_node_to_id' mangled-name='of_cpu_node_to_id' filepath='drivers/of/base.c' line='400' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_cpu_node_to_id'>
@@ -137165,8 +137899,8 @@
         <parameter type-id='0afa6ea3' name='device' filepath='drivers/of/base.c' line='617' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='of_device_is_big_endian' mangled-name='of_device_is_big_endian' filepath='drivers/of/base.c' line='642' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_device_is_big_endian'>
-        <parameter type-id='0afa6ea3' name='device' filepath='drivers/of/base.c' line='642' column='1'/>
+      <function-decl name='of_device_is_big_endian' mangled-name='of_device_is_big_endian' filepath='drivers/of/base.c' line='664' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_device_is_big_endian'>
+        <parameter type-id='0afa6ea3' name='device' filepath='drivers/of/base.c' line='664' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='of_device_is_compatible' mangled-name='of_device_is_compatible' filepath='drivers/of/base.c' line='525' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_device_is_compatible'>
@@ -137174,19 +137908,19 @@
         <parameter type-id='80f4b756' name='compat' filepath='drivers/of/base.c' line='526' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='of_device_modalias' mangled-name='of_device_modalias' filepath='drivers/of/device.c' line='283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_device_modalias'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/of/device.c' line='283' column='1'/>
-        <parameter type-id='26a90f95' name='str' filepath='drivers/of/device.c' line='283' column='1'/>
-        <parameter type-id='79a0948f' name='len' filepath='drivers/of/device.c' line='283' column='1'/>
+      <function-decl name='of_device_modalias' mangled-name='of_device_modalias' filepath='drivers/of/device.c' line='286' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_device_modalias'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/of/device.c' line='286' column='1'/>
+        <parameter type-id='26a90f95' name='str' filepath='drivers/of/device.c' line='286' column='1'/>
+        <parameter type-id='79a0948f' name='len' filepath='drivers/of/device.c' line='286' column='1'/>
         <return type-id='79a0948f'/>
       </function-decl>
       <function-decl name='of_device_request_module' mangled-name='of_device_request_module' filepath='drivers/of/device.c' line='257' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_device_request_module'>
         <parameter type-id='fa0b179b' name='dev' filepath='drivers/of/device.c' line='257' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='of_device_uevent_modalias' mangled-name='of_device_uevent_modalias' filepath='drivers/of/device.c' line='337' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_device_uevent_modalias'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/of/device.c' line='337' column='1'/>
-        <parameter type-id='d9d65b21' name='env' filepath='drivers/of/device.c' line='337' column='1'/>
+      <function-decl name='of_device_uevent_modalias' mangled-name='of_device_uevent_modalias' filepath='drivers/of/device.c' line='340' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_device_uevent_modalias'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/of/device.c' line='340' column='1'/>
+        <parameter type-id='d9d65b21' name='env' filepath='drivers/of/device.c' line='340' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='of_dma_configure_id' mangled-name='of_dma_configure_id' filepath='drivers/of/device.c' line='91' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_dma_configure_id'>
@@ -137206,8 +137940,8 @@
         <parameter type-id='eaa32e2f' name='data' filepath='drivers/dma/of-dma.c' line='111' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='of_dma_is_coherent' mangled-name='of_dma_is_coherent' filepath='drivers/of/address.c' line='1077' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_dma_is_coherent'>
-        <parameter type-id='9a537bbe' name='np' filepath='drivers/of/address.c' line='1077' column='1'/>
+      <function-decl name='of_dma_is_coherent' mangled-name='of_dma_is_coherent' filepath='drivers/of/address.c' line='1086' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_dma_is_coherent'>
+        <parameter type-id='9a537bbe' name='np' filepath='drivers/of/address.c' line='1086' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='of_dma_simple_xlate' mangled-name='of_dma_simple_xlate' filepath='drivers/dma/of-dma.c' line='311' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_dma_simple_xlate'>
@@ -137241,10 +137975,10 @@
         <parameter type-id='9a537bbe' name='node' filepath='drivers/video/backlight/backlight.c' line='665' column='1'/>
         <return type-id='7a76d041'/>
       </function-decl>
-      <function-decl name='of_find_compatible_node' mangled-name='of_find_compatible_node' filepath='drivers/of/base.c' line='1029' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_compatible_node'>
-        <parameter type-id='9a537bbe' name='from' filepath='drivers/of/base.c' line='1029' column='1'/>
-        <parameter type-id='80f4b756' name='type' filepath='drivers/of/base.c' line='1030' column='1'/>
-        <parameter type-id='80f4b756' name='compatible' filepath='drivers/of/base.c' line='1030' column='1'/>
+      <function-decl name='of_find_compatible_node' mangled-name='of_find_compatible_node' filepath='drivers/of/base.c' line='1056' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_compatible_node'>
+        <parameter type-id='9a537bbe' name='from' filepath='drivers/of/base.c' line='1056' column='1'/>
+        <parameter type-id='80f4b756' name='type' filepath='drivers/of/base.c' line='1057' column='1'/>
+        <parameter type-id='80f4b756' name='compatible' filepath='drivers/of/base.c' line='1057' column='1'/>
         <return type-id='9a537bbe'/>
       </function-decl>
       <function-decl name='of_find_device_by_node' mangled-name='of_find_device_by_node' filepath='drivers/of/platform.c' line='49' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_device_by_node'>
@@ -137259,38 +137993,38 @@
         <parameter type-id='9a537bbe' name='node' filepath='drivers/i2c/i2c-core-of.c' line='131' column='1'/>
         <return type-id='3e31633b'/>
       </function-decl>
-      <function-decl name='of_find_matching_node_and_match' mangled-name='of_find_matching_node_and_match' filepath='drivers/of/base.c' line='1136' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_matching_node_and_match'>
-        <parameter type-id='9a537bbe' name='from' filepath='drivers/of/base.c' line='1136' column='1'/>
-        <parameter type-id='e5ce629e' name='matches' filepath='drivers/of/base.c' line='1137' column='1'/>
-        <parameter type-id='77e5615c' name='match' filepath='drivers/of/base.c' line='1138' column='1'/>
+      <function-decl name='of_find_matching_node_and_match' mangled-name='of_find_matching_node_and_match' filepath='drivers/of/base.c' line='1163' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_matching_node_and_match'>
+        <parameter type-id='9a537bbe' name='from' filepath='drivers/of/base.c' line='1163' column='1'/>
+        <parameter type-id='e5ce629e' name='matches' filepath='drivers/of/base.c' line='1164' column='1'/>
+        <parameter type-id='77e5615c' name='match' filepath='drivers/of/base.c' line='1165' column='1'/>
         <return type-id='9a537bbe'/>
       </function-decl>
       <function-decl name='of_find_mipi_dsi_host_by_node' mangled-name='of_find_mipi_dsi_host_by_node' filepath='drivers/gpu/drm/drm_mipi_dsi.c' line='261' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_mipi_dsi_host_by_node'>
         <parameter type-id='9a537bbe' name='node' filepath='drivers/gpu/drm/drm_mipi_dsi.c' line='261' column='1'/>
         <return type-id='c149fe34'/>
       </function-decl>
-      <function-decl name='of_find_node_by_name' mangled-name='of_find_node_by_name' filepath='drivers/of/base.c' line='971' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_node_by_name'>
-        <parameter type-id='9a537bbe' name='from' filepath='drivers/of/base.c' line='971' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='drivers/of/base.c' line='972' column='1'/>
+      <function-decl name='of_find_node_by_name' mangled-name='of_find_node_by_name' filepath='drivers/of/base.c' line='998' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_node_by_name'>
+        <parameter type-id='9a537bbe' name='from' filepath='drivers/of/base.c' line='998' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='drivers/of/base.c' line='999' column='1'/>
         <return type-id='9a537bbe'/>
       </function-decl>
-      <function-decl name='of_find_node_by_phandle' mangled-name='of_find_node_by_phandle' filepath='drivers/of/base.c' line='1196' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_node_by_phandle'>
-        <parameter type-id='6e394fba' name='handle' filepath='drivers/of/base.c' line='1196' column='1'/>
+      <function-decl name='of_find_node_by_phandle' mangled-name='of_find_node_by_phandle' filepath='drivers/of/base.c' line='1223' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_node_by_phandle'>
+        <parameter type-id='6e394fba' name='handle' filepath='drivers/of/base.c' line='1223' column='1'/>
         <return type-id='9a537bbe'/>
       </function-decl>
-      <function-decl name='of_find_node_by_type' mangled-name='of_find_node_by_type' filepath='drivers/of/base.c' line='999' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_node_by_type'>
-        <parameter type-id='9a537bbe' name='from' filepath='drivers/of/base.c' line='999' column='1'/>
-        <parameter type-id='80f4b756' name='type' filepath='drivers/of/base.c' line='1000' column='1'/>
+      <function-decl name='of_find_node_by_type' mangled-name='of_find_node_by_type' filepath='drivers/of/base.c' line='1026' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_node_by_type'>
+        <parameter type-id='9a537bbe' name='from' filepath='drivers/of/base.c' line='1026' column='1'/>
+        <parameter type-id='80f4b756' name='type' filepath='drivers/of/base.c' line='1027' column='1'/>
         <return type-id='9a537bbe'/>
       </function-decl>
-      <function-decl name='of_find_node_opts_by_path' mangled-name='of_find_node_opts_by_path' filepath='drivers/of/base.c' line='913' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_node_opts_by_path'>
-        <parameter type-id='80f4b756' name='path' filepath='drivers/of/base.c' line='913' column='1'/>
-        <parameter type-id='7d3cd834' name='opts' filepath='drivers/of/base.c' line='913' column='1'/>
+      <function-decl name='of_find_node_opts_by_path' mangled-name='of_find_node_opts_by_path' filepath='drivers/of/base.c' line='940' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_node_opts_by_path'>
+        <parameter type-id='80f4b756' name='path' filepath='drivers/of/base.c' line='940' column='1'/>
+        <parameter type-id='7d3cd834' name='opts' filepath='drivers/of/base.c' line='940' column='1'/>
         <return type-id='9a537bbe'/>
       </function-decl>
-      <function-decl name='of_find_node_with_property' mangled-name='of_find_node_with_property' filepath='drivers/of/base.c' line='1058' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_node_with_property'>
-        <parameter type-id='9a537bbe' name='from' filepath='drivers/of/base.c' line='1058' column='1'/>
-        <parameter type-id='80f4b756' name='prop_name' filepath='drivers/of/base.c' line='1059' column='1'/>
+      <function-decl name='of_find_node_with_property' mangled-name='of_find_node_with_property' filepath='drivers/of/base.c' line='1085' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_node_with_property'>
+        <parameter type-id='9a537bbe' name='from' filepath='drivers/of/base.c' line='1085' column='1'/>
+        <parameter type-id='80f4b756' name='prop_name' filepath='drivers/of/base.c' line='1086' column='1'/>
         <return type-id='9a537bbe'/>
       </function-decl>
       <function-decl name='of_find_property' mangled-name='of_find_property' filepath='drivers/of/base.c' line='210' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_find_property'>
@@ -137337,14 +138071,14 @@
         <parameter type-id='807869d3' name='flags' filepath='drivers/of/address.c' line='675' column='1'/>
         <return type-id='90144368'/>
       </function-decl>
-      <function-decl name='of_get_child_by_name' mangled-name='of_get_child_by_name' filepath='drivers/of/base.c' line='847' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_get_child_by_name'>
-        <parameter type-id='0afa6ea3' name='node' filepath='drivers/of/base.c' line='847' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='drivers/of/base.c' line='848' column='1'/>
+      <function-decl name='of_get_child_by_name' mangled-name='of_get_child_by_name' filepath='drivers/of/base.c' line='874' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_get_child_by_name'>
+        <parameter type-id='0afa6ea3' name='node' filepath='drivers/of/base.c' line='874' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='drivers/of/base.c' line='875' column='1'/>
         <return type-id='9a537bbe'/>
       </function-decl>
-      <function-decl name='of_get_compatible_child' mangled-name='of_get_compatible_child' filepath='drivers/of/base.c' line='822' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_get_compatible_child'>
-        <parameter type-id='0afa6ea3' name='parent' filepath='drivers/of/base.c' line='822' column='1'/>
-        <parameter type-id='80f4b756' name='compatible' filepath='drivers/of/base.c' line='823' column='1'/>
+      <function-decl name='of_get_compatible_child' mangled-name='of_get_compatible_child' filepath='drivers/of/base.c' line='849' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_get_compatible_child'>
+        <parameter type-id='0afa6ea3' name='parent' filepath='drivers/of/base.c' line='849' column='1'/>
+        <parameter type-id='80f4b756' name='compatible' filepath='drivers/of/base.c' line='850' column='1'/>
         <return type-id='9a537bbe'/>
       </function-decl>
       <function-decl name='of_get_cpu_node' mangled-name='of_get_cpu_node' filepath='drivers/of/base.c' line='380' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_get_cpu_node'>
@@ -137393,23 +138127,27 @@
         <parameter type-id='38fe9344' name='flags' filepath='drivers/gpio/gpiolib-of.c' line='279' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='of_get_next_available_child' mangled-name='of_get_next_available_child' filepath='drivers/of/base.c' line='751' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_get_next_available_child'>
-        <parameter type-id='0afa6ea3' name='node' filepath='drivers/of/base.c' line='751' column='1'/>
-        <parameter type-id='9a537bbe' name='prev' filepath='drivers/of/base.c' line='752' column='1'/>
+      <function-decl name='of_get_next_available_child' mangled-name='of_get_next_available_child' filepath='drivers/of/base.c' line='773' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_get_next_available_child'>
+        <parameter type-id='0afa6ea3' name='node' filepath='drivers/of/base.c' line='773' column='1'/>
+        <parameter type-id='9a537bbe' name='prev' filepath='drivers/of/base.c' line='774' column='1'/>
         <return type-id='9a537bbe'/>
       </function-decl>
-      <function-decl name='of_get_next_child' mangled-name='of_get_next_child' filepath='drivers/of/base.c' line='730' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_get_next_child'>
-        <parameter type-id='0afa6ea3' name='node' filepath='drivers/of/base.c' line='730' column='1'/>
-        <parameter type-id='9a537bbe' name='prev' filepath='drivers/of/base.c' line='731' column='1'/>
+      <function-decl name='of_get_next_child' mangled-name='of_get_next_child' filepath='drivers/of/base.c' line='752' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_get_next_child'>
+        <parameter type-id='0afa6ea3' name='node' filepath='drivers/of/base.c' line='752' column='1'/>
+        <parameter type-id='9a537bbe' name='prev' filepath='drivers/of/base.c' line='753' column='1'/>
         <return type-id='9a537bbe'/>
       </function-decl>
-      <function-decl name='of_get_next_parent' mangled-name='of_get_next_parent' filepath='drivers/of/base.c' line='686' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_get_next_parent'>
-        <parameter type-id='9a537bbe' name='node' filepath='drivers/of/base.c' line='686' column='1'/>
+      <function-decl name='of_get_next_parent' mangled-name='of_get_next_parent' filepath='drivers/of/base.c' line='708' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_get_next_parent'>
+        <parameter type-id='9a537bbe' name='node' filepath='drivers/of/base.c' line='708' column='1'/>
         <return type-id='9a537bbe'/>
       </function-decl>
-      <function-decl name='of_get_parent' mangled-name='of_get_parent' filepath='drivers/of/base.c' line='660' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_get_parent'>
-        <parameter type-id='0afa6ea3' name='node' filepath='drivers/of/base.c' line='660' column='1'/>
+      <function-decl name='of_get_parent' mangled-name='of_get_parent' filepath='drivers/of/base.c' line='682' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_get_parent'>
+        <parameter type-id='0afa6ea3' name='node' filepath='drivers/of/base.c' line='682' column='1'/>
         <return type-id='9a537bbe'/>
+      </function-decl>
+      <function-decl name='of_get_pci_domain_nr' mangled-name='of_get_pci_domain_nr' filepath='drivers/pci/of.c' line='201' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_get_pci_domain_nr'>
+        <parameter type-id='9a537bbe' name='node' filepath='drivers/pci/of.c' line='201' column='1'/>
+        <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='of_get_phy_mode' mangled-name='of_get_phy_mode' filepath='drivers/of/of_net.c' line='25' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_get_phy_mode'>
         <parameter type-id='9a537bbe' name='np' filepath='drivers/of/of_net.c' line='25' column='1'/>
@@ -137546,9 +138284,9 @@
         <parameter type-id='8df61054' name='dev' filepath='drivers/of/device.c' line='28' column='1'/>
         <return type-id='e5ce629e'/>
       </function-decl>
-      <function-decl name='of_match_node' mangled-name='of_match_node' filepath='drivers/of/base.c' line='1110' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_match_node'>
-        <parameter type-id='e5ce629e' name='matches' filepath='drivers/of/base.c' line='1110' column='1'/>
-        <parameter type-id='0afa6ea3' name='node' filepath='drivers/of/base.c' line='1111' column='1'/>
+      <function-decl name='of_match_node' mangled-name='of_match_node' filepath='drivers/of/base.c' line='1137' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_match_node'>
+        <parameter type-id='e5ce629e' name='matches' filepath='drivers/of/base.c' line='1137' column='1'/>
+        <parameter type-id='0afa6ea3' name='node' filepath='drivers/of/base.c' line='1138' column='1'/>
         <return type-id='e5ce629e'/>
       </function-decl>
       <function-decl name='of_mdiobus_register' mangled-name='of_mdiobus_register' filepath='drivers/net/mdio/of_mdio.c' line='248' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_mdiobus_register'>
@@ -137556,10 +138294,10 @@
         <parameter type-id='9a537bbe' name='np' filepath='drivers/net/mdio/of_mdio.c' line='248' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='of_modalias_node' mangled-name='of_modalias_node' filepath='drivers/of/base.c' line='1175' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_modalias_node'>
-        <parameter type-id='9a537bbe' name='node' filepath='drivers/of/base.c' line='1175' column='1'/>
-        <parameter type-id='26a90f95' name='modalias' filepath='drivers/of/base.c' line='1175' column='1'/>
-        <parameter type-id='95e97e5e' name='len' filepath='drivers/of/base.c' line='1175' column='1'/>
+      <function-decl name='of_modalias_node' mangled-name='of_modalias_node' filepath='drivers/of/base.c' line='1202' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_modalias_node'>
+        <parameter type-id='9a537bbe' name='node' filepath='drivers/of/base.c' line='1202' column='1'/>
+        <parameter type-id='26a90f95' name='modalias' filepath='drivers/of/base.c' line='1202' column='1'/>
+        <parameter type-id='95e97e5e' name='len' filepath='drivers/of/base.c' line='1202' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='of_n_addr_cells' mangled-name='of_n_addr_cells' filepath='drivers/of/base.c' line='101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_n_addr_cells'>
@@ -137575,52 +138313,52 @@
         <parameter type-id='80f4b756' name='name' filepath='drivers/of/base.c' line='58' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='of_nvmem_cell_get' mangled-name='of_nvmem_cell_get' filepath='drivers/nvmem/core.c' line='1064' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_nvmem_cell_get'>
-        <parameter type-id='9a537bbe' name='np' filepath='drivers/nvmem/core.c' line='1064' column='1'/>
-        <parameter type-id='80f4b756' name='id' filepath='drivers/nvmem/core.c' line='1064' column='1'/>
+      <function-decl name='of_nvmem_cell_get' mangled-name='of_nvmem_cell_get' filepath='drivers/nvmem/core.c' line='1070' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_nvmem_cell_get'>
+        <parameter type-id='9a537bbe' name='np' filepath='drivers/nvmem/core.c' line='1070' column='1'/>
+        <parameter type-id='80f4b756' name='id' filepath='drivers/nvmem/core.c' line='1070' column='1'/>
         <return type-id='4a4ce85f'/>
       </function-decl>
-      <function-decl name='of_nvmem_device_get' mangled-name='of_nvmem_device_get' filepath='drivers/nvmem/core.c' line='857' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_nvmem_device_get'>
-        <parameter type-id='9a537bbe' name='np' filepath='drivers/nvmem/core.c' line='857' column='1'/>
-        <parameter type-id='80f4b756' name='id' filepath='drivers/nvmem/core.c' line='857' column='1'/>
+      <function-decl name='of_nvmem_device_get' mangled-name='of_nvmem_device_get' filepath='drivers/nvmem/core.c' line='863' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_nvmem_device_get'>
+        <parameter type-id='9a537bbe' name='np' filepath='drivers/nvmem/core.c' line='863' column='1'/>
+        <parameter type-id='80f4b756' name='id' filepath='drivers/nvmem/core.c' line='863' column='1'/>
         <return type-id='8179bc49'/>
       </function-decl>
-      <function-decl name='of_parse_phandle' mangled-name='of_parse_phandle' filepath='drivers/of/base.c' line='1437' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_parse_phandle'>
-        <parameter type-id='0afa6ea3' name='np' filepath='drivers/of/base.c' line='1437' column='1'/>
-        <parameter type-id='80f4b756' name='phandle_name' filepath='drivers/of/base.c' line='1438' column='1'/>
-        <parameter type-id='95e97e5e' name='index' filepath='drivers/of/base.c' line='1438' column='1'/>
+      <function-decl name='of_parse_phandle' mangled-name='of_parse_phandle' filepath='drivers/of/base.c' line='1464' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_parse_phandle'>
+        <parameter type-id='0afa6ea3' name='np' filepath='drivers/of/base.c' line='1464' column='1'/>
+        <parameter type-id='80f4b756' name='phandle_name' filepath='drivers/of/base.c' line='1465' column='1'/>
+        <parameter type-id='95e97e5e' name='index' filepath='drivers/of/base.c' line='1465' column='1'/>
         <return type-id='9a537bbe'/>
       </function-decl>
-      <function-decl name='of_parse_phandle_with_args' mangled-name='of_parse_phandle_with_args' filepath='drivers/of/base.c' line='1485' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_parse_phandle_with_args'>
-        <parameter type-id='0afa6ea3' name='np' filepath='drivers/of/base.c' line='1485' column='1'/>
-        <parameter type-id='80f4b756' name='list_name' filepath='drivers/of/base.c' line='1485' column='1'/>
-        <parameter type-id='80f4b756' name='cells_name' filepath='drivers/of/base.c' line='1486' column='1'/>
-        <parameter type-id='95e97e5e' name='index' filepath='drivers/of/base.c' line='1486' column='1'/>
-        <parameter type-id='51a94113' name='out_args' filepath='drivers/of/base.c' line='1487' column='1'/>
+      <function-decl name='of_parse_phandle_with_args' mangled-name='of_parse_phandle_with_args' filepath='drivers/of/base.c' line='1512' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_parse_phandle_with_args'>
+        <parameter type-id='0afa6ea3' name='np' filepath='drivers/of/base.c' line='1512' column='1'/>
+        <parameter type-id='80f4b756' name='list_name' filepath='drivers/of/base.c' line='1512' column='1'/>
+        <parameter type-id='80f4b756' name='cells_name' filepath='drivers/of/base.c' line='1513' column='1'/>
+        <parameter type-id='95e97e5e' name='index' filepath='drivers/of/base.c' line='1513' column='1'/>
+        <parameter type-id='51a94113' name='out_args' filepath='drivers/of/base.c' line='1514' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='of_parse_phandle_with_fixed_args' mangled-name='of_parse_phandle_with_fixed_args' filepath='drivers/of/base.c' line='1717' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_parse_phandle_with_fixed_args'>
-        <parameter type-id='0afa6ea3' name='np' filepath='drivers/of/base.c' line='1717' column='1'/>
-        <parameter type-id='80f4b756' name='list_name' filepath='drivers/of/base.c' line='1718' column='1'/>
-        <parameter type-id='95e97e5e' name='cell_count' filepath='drivers/of/base.c' line='1718' column='1'/>
-        <parameter type-id='95e97e5e' name='index' filepath='drivers/of/base.c' line='1719' column='1'/>
-        <parameter type-id='51a94113' name='out_args' filepath='drivers/of/base.c' line='1719' column='1'/>
+      <function-decl name='of_parse_phandle_with_fixed_args' mangled-name='of_parse_phandle_with_fixed_args' filepath='drivers/of/base.c' line='1744' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_parse_phandle_with_fixed_args'>
+        <parameter type-id='0afa6ea3' name='np' filepath='drivers/of/base.c' line='1744' column='1'/>
+        <parameter type-id='80f4b756' name='list_name' filepath='drivers/of/base.c' line='1745' column='1'/>
+        <parameter type-id='95e97e5e' name='cell_count' filepath='drivers/of/base.c' line='1745' column='1'/>
+        <parameter type-id='95e97e5e' name='index' filepath='drivers/of/base.c' line='1746' column='1'/>
+        <parameter type-id='51a94113' name='out_args' filepath='drivers/of/base.c' line='1746' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='of_pci_get_max_link_speed' mangled-name='of_pci_get_max_link_speed' filepath='drivers/pci/of.c' line='591' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_pci_get_max_link_speed'>
         <parameter type-id='9a537bbe' name='node' filepath='drivers/pci/of.c' line='591' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='of_phandle_iterator_init' mangled-name='of_phandle_iterator_init' filepath='drivers/of/base.c' line='1240' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_phandle_iterator_init'>
-        <parameter type-id='58cfaa0e' name='it' filepath='drivers/of/base.c' line='1240' column='1'/>
-        <parameter type-id='0afa6ea3' name='np' filepath='drivers/of/base.c' line='1241' column='1'/>
-        <parameter type-id='80f4b756' name='list_name' filepath='drivers/of/base.c' line='1242' column='1'/>
-        <parameter type-id='80f4b756' name='cells_name' filepath='drivers/of/base.c' line='1243' column='1'/>
-        <parameter type-id='95e97e5e' name='cell_count' filepath='drivers/of/base.c' line='1244' column='1'/>
+      <function-decl name='of_phandle_iterator_init' mangled-name='of_phandle_iterator_init' filepath='drivers/of/base.c' line='1267' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_phandle_iterator_init'>
+        <parameter type-id='58cfaa0e' name='it' filepath='drivers/of/base.c' line='1267' column='1'/>
+        <parameter type-id='0afa6ea3' name='np' filepath='drivers/of/base.c' line='1268' column='1'/>
+        <parameter type-id='80f4b756' name='list_name' filepath='drivers/of/base.c' line='1269' column='1'/>
+        <parameter type-id='80f4b756' name='cells_name' filepath='drivers/of/base.c' line='1270' column='1'/>
+        <parameter type-id='95e97e5e' name='cell_count' filepath='drivers/of/base.c' line='1271' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='of_phandle_iterator_next' mangled-name='of_phandle_iterator_next' filepath='drivers/of/base.c' line='1273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_phandle_iterator_next'>
-        <parameter type-id='58cfaa0e' name='it' filepath='drivers/of/base.c' line='1273' column='1'/>
+      <function-decl name='of_phandle_iterator_next' mangled-name='of_phandle_iterator_next' filepath='drivers/of/base.c' line='1300' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_phandle_iterator_next'>
+        <parameter type-id='58cfaa0e' name='it' filepath='drivers/of/base.c' line='1300' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='of_phy_connect' mangled-name='of_phy_connect' filepath='drivers/net/mdio/of_mdio.c' line='400' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_phy_connect'>
@@ -137779,9 +138517,9 @@
         <parameter type-id='f0981eeb' name='num_matches' filepath='drivers/regulator/of_regulator.c' line='331' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='of_remove_property' mangled-name='of_remove_property' filepath='drivers/of/base.c' line='1854' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_remove_property'>
-        <parameter type-id='9a537bbe' name='np' filepath='drivers/of/base.c' line='1854' column='1'/>
-        <parameter type-id='ddcd89c6' name='prop' filepath='drivers/of/base.c' line='1854' column='1'/>
+      <function-decl name='of_remove_property' mangled-name='of_remove_property' filepath='drivers/of/base.c' line='1881' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_remove_property'>
+        <parameter type-id='9a537bbe' name='np' filepath='drivers/of/base.c' line='1881' column='1'/>
+        <parameter type-id='ddcd89c6' name='prop' filepath='drivers/of/base.c' line='1881' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='of_reserved_mem_device_init_by_idx' mangled-name='of_reserved_mem_device_init_by_idx' filepath='drivers/of/of_reserved_mem.c' line='321' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='of_reserved_mem_device_init_by_idx'>
@@ -137903,34 +138641,36 @@
         <parameter type-id='95e97e5e' name='err' filepath='mm/filemap.c' line='1516' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='page_frag_alloc' mangled-name='page_frag_alloc' filepath='mm/page_alloc.c' line='5297' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_frag_alloc'>
-        <parameter type-id='34e4f518' name='nc' filepath='mm/page_alloc.c' line='5297' column='1'/>
-        <parameter type-id='f0981eeb' name='fragsz' filepath='mm/page_alloc.c' line='5298' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/page_alloc.c' line='5298' column='1'/>
+      <function-decl name='page_frag_alloc' mangled-name='page_frag_alloc' filepath='mm/page_alloc.c' line='5329' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_frag_alloc'>
+        <parameter type-id='34e4f518' name='nc' filepath='mm/page_alloc.c' line='5329' column='1'/>
+        <parameter type-id='f0981eeb' name='fragsz' filepath='mm/page_alloc.c' line='5330' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/page_alloc.c' line='5330' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='page_frag_free' mangled-name='page_frag_free' filepath='mm/page_alloc.c' line='5371' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_frag_free'>
-        <parameter type-id='eaa32e2f' name='addr' filepath='mm/page_alloc.c' line='5371' column='1'/>
+      <function-decl name='page_frag_free' mangled-name='page_frag_free' filepath='mm/page_alloc.c' line='5403' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_frag_free'>
+        <parameter type-id='eaa32e2f' name='addr' filepath='mm/page_alloc.c' line='5403' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='page_get_link' mangled-name='page_get_link' filepath='fs/namei.c' line='4667' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_get_link'>
-        <parameter type-id='27675065' name='dentry' filepath='fs/namei.c' line='4667' column='1'/>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/namei.c' line='4667' column='1'/>
-        <parameter type-id='26cad514' name='callback' filepath='fs/namei.c' line='4668' column='1'/>
+      <function-decl name='page_get_link' mangled-name='page_get_link' filepath='fs/namei.c' line='4742' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_get_link'>
+        <parameter type-id='27675065' name='dentry' filepath='fs/namei.c' line='4742' column='1'/>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/namei.c' line='4742' column='1'/>
+        <parameter type-id='26cad514' name='callback' filepath='fs/namei.c' line='4743' column='1'/>
         <return type-id='80f4b756'/>
       </function-decl>
-      <function-decl name='page_mapped' mangled-name='page_mapped' filepath='mm/util.c' line='705' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_mapped'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/util.c' line='705' column='1'/>
+      <function-decl name='page_mapped' mangled-name='page_mapped' filepath='mm/util.c' line='712' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_mapped'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/util.c' line='712' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='page_mapping' mangled-name='page_mapping' filepath='mm/util.c' line='735' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_mapping'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/util.c' line='735' column='1'/>
+      <function-decl name='page_mapping' mangled-name='page_mapping' filepath='mm/util.c' line='742' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_mapping'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/util.c' line='742' column='1'/>
         <return type-id='f57039f0'/>
       </function-decl>
-      <function-decl name='page_mkclean' mangled-name='page_mkclean' filepath='mm/rmap.c' line='997' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_mkclean'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/rmap.c' line='997' column='1'/>
+      <function-decl name='page_mkclean' mangled-name='page_mkclean' filepath='mm/rmap.c' line='1002' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_mkclean'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/rmap.c' line='1002' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
+      <var-decl name='page_owner_inited' type-id='237c0d27' mangled-name='page_owner_inited' visibility='default' filepath='mm/page_owner.c' line='35' column='1' elf-symbol-id='page_owner_inited'/>
+      <var-decl name='page_pinner_inited' type-id='237c0d27' mangled-name='page_pinner_inited' visibility='default' filepath='mm/page_pinner.c' line='59' column='1' elf-symbol-id='page_pinner_inited'/>
       <function-decl name='page_pool_alloc_pages' mangled-name='page_pool_alloc_pages' filepath='net/core/page_pool.c' line='247' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_pool_alloc_pages'>
         <parameter type-id='a832c6b9' name='pool' filepath='net/core/page_pool.c' line='247' column='1'/>
         <parameter type-id='3eb7c31c' name='gfp' filepath='net/core/page_pool.c' line='247' column='1'/>
@@ -137956,6 +138696,13 @@
         <parameter type-id='02f11ed4' name='page' filepath='net/core/page_pool.c' line='286' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
+      <function-decl name='page_referenced' mangled-name='page_referenced' filepath='mm/rmap.c' line='871' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_referenced'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/rmap.c' line='871' column='1'/>
+        <parameter type-id='95e97e5e' name='is_locked' filepath='mm/rmap.c' line='872' column='1'/>
+        <parameter type-id='223696fb' name='memcg' filepath='mm/rmap.c' line='873' column='1'/>
+        <parameter type-id='1d2c2b85' name='vm_flags' filepath='mm/rmap.c' line='874' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
       <function-decl name='page_reporting_register' mangled-name='page_reporting_register' filepath='mm/page_reporting.c' line='315' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_reporting_register'>
         <parameter type-id='b99d5f36' name='prdev' filepath='mm/page_reporting.c' line='315' column='1'/>
         <return type-id='95e97e5e'/>
@@ -137964,15 +138711,15 @@
         <parameter type-id='b99d5f36' name='prdev' filepath='mm/page_reporting.c' line='349' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='page_symlink' mangled-name='page_symlink' filepath='fs/namei.c' line='4748' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_symlink'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/namei.c' line='4748' column='1'/>
-        <parameter type-id='80f4b756' name='symname' filepath='fs/namei.c' line='4748' column='1'/>
-        <parameter type-id='95e97e5e' name='len' filepath='fs/namei.c' line='4748' column='1'/>
+      <function-decl name='page_symlink' mangled-name='page_symlink' filepath='fs/namei.c' line='4823' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_symlink'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/namei.c' line='4823' column='1'/>
+        <parameter type-id='80f4b756' name='symname' filepath='fs/namei.c' line='4823' column='1'/>
+        <parameter type-id='95e97e5e' name='len' filepath='fs/namei.c' line='4823' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='page_to_lruvec' mangled-name='page_to_lruvec' filepath='mm/memcontrol.c' line='1375' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_to_lruvec'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/memcontrol.c' line='1375' column='1'/>
-        <parameter type-id='8845292c' name='pgdat' filepath='mm/memcontrol.c' line='1375' column='1'/>
+      <function-decl name='page_to_lruvec' mangled-name='page_to_lruvec' filepath='mm/memcontrol.c' line='1377' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_to_lruvec'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/memcontrol.c' line='1377' column='1'/>
+        <parameter type-id='8845292c' name='pgdat' filepath='mm/memcontrol.c' line='1377' column='1'/>
         <return type-id='71480a3e'/>
       </function-decl>
       <function-decl name='page_zero_new_buffers' mangled-name='page_zero_new_buffers' filepath='fs/buffer.c' line='1909' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='page_zero_new_buffers'>
@@ -137988,24 +138735,24 @@
         <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/filemap.c' line='1797' column='1'/>
         <return type-id='02f11ed4'/>
       </function-decl>
-      <function-decl name='pagecache_write_begin' mangled-name='pagecache_write_begin' filepath='mm/filemap.c' line='3314' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pagecache_write_begin'>
-        <parameter type-id='77e79a4b' name='file' filepath='mm/filemap.c' line='3314' column='1'/>
-        <parameter type-id='f57039f0' name='mapping' filepath='mm/filemap.c' line='3314' column='1'/>
-        <parameter type-id='69bf7bee' name='pos' filepath='mm/filemap.c' line='3315' column='1'/>
-        <parameter type-id='f0981eeb' name='len' filepath='mm/filemap.c' line='3315' column='1'/>
-        <parameter type-id='f0981eeb' name='flags' filepath='mm/filemap.c' line='3315' column='1'/>
-        <parameter type-id='9f93c9da' name='pagep' filepath='mm/filemap.c' line='3316' column='1'/>
-        <parameter type-id='63e171df' name='fsdata' filepath='mm/filemap.c' line='3316' column='1'/>
+      <function-decl name='pagecache_write_begin' mangled-name='pagecache_write_begin' filepath='mm/filemap.c' line='3321' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pagecache_write_begin'>
+        <parameter type-id='77e79a4b' name='file' filepath='mm/filemap.c' line='3321' column='1'/>
+        <parameter type-id='f57039f0' name='mapping' filepath='mm/filemap.c' line='3321' column='1'/>
+        <parameter type-id='69bf7bee' name='pos' filepath='mm/filemap.c' line='3322' column='1'/>
+        <parameter type-id='f0981eeb' name='len' filepath='mm/filemap.c' line='3322' column='1'/>
+        <parameter type-id='f0981eeb' name='flags' filepath='mm/filemap.c' line='3322' column='1'/>
+        <parameter type-id='9f93c9da' name='pagep' filepath='mm/filemap.c' line='3323' column='1'/>
+        <parameter type-id='63e171df' name='fsdata' filepath='mm/filemap.c' line='3323' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pagecache_write_end' mangled-name='pagecache_write_end' filepath='mm/filemap.c' line='3325' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pagecache_write_end'>
-        <parameter type-id='77e79a4b' name='file' filepath='mm/filemap.c' line='3325' column='1'/>
-        <parameter type-id='f57039f0' name='mapping' filepath='mm/filemap.c' line='3325' column='1'/>
-        <parameter type-id='69bf7bee' name='pos' filepath='mm/filemap.c' line='3326' column='1'/>
-        <parameter type-id='f0981eeb' name='len' filepath='mm/filemap.c' line='3326' column='1'/>
-        <parameter type-id='f0981eeb' name='copied' filepath='mm/filemap.c' line='3326' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/filemap.c' line='3327' column='1'/>
-        <parameter type-id='eaa32e2f' name='fsdata' filepath='mm/filemap.c' line='3327' column='1'/>
+      <function-decl name='pagecache_write_end' mangled-name='pagecache_write_end' filepath='mm/filemap.c' line='3332' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pagecache_write_end'>
+        <parameter type-id='77e79a4b' name='file' filepath='mm/filemap.c' line='3332' column='1'/>
+        <parameter type-id='f57039f0' name='mapping' filepath='mm/filemap.c' line='3332' column='1'/>
+        <parameter type-id='69bf7bee' name='pos' filepath='mm/filemap.c' line='3333' column='1'/>
+        <parameter type-id='f0981eeb' name='len' filepath='mm/filemap.c' line='3333' column='1'/>
+        <parameter type-id='f0981eeb' name='copied' filepath='mm/filemap.c' line='3333' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/filemap.c' line='3334' column='1'/>
+        <parameter type-id='eaa32e2f' name='fsdata' filepath='mm/filemap.c' line='3334' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='pagevec_lookup_range' mangled-name='pagevec_lookup_range' filepath='mm/swap.c' line='1278' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pagevec_lookup_range'>
@@ -138023,13 +138770,13 @@
         <parameter type-id='933bf462' name='tag' filepath='mm/swap.c' line='1289' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='panic' mangled-name='panic' filepath='kernel/panic.c' line='177' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='panic'>
-        <parameter type-id='80f4b756' name='fmt' filepath='kernel/panic.c' line='177' column='1'/>
+      <function-decl name='panic' mangled-name='panic' filepath='kernel/panic.c' line='244' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='panic'>
+        <parameter type-id='80f4b756' name='fmt' filepath='kernel/panic.c' line='244' column='1'/>
         <parameter is-variadic='yes'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <var-decl name='panic_notifier_list' type-id='dbd58f6e' mangled-name='panic_notifier_list' visibility='default' filepath='kernel/panic.c' line='69' column='1' elf-symbol-id='panic_notifier_list'/>
-      <var-decl name='panic_timeout' type-id='95e97e5e' mangled-name='panic_timeout' visibility='default' filepath='kernel/panic.c' line='58' column='1' elf-symbol-id='panic_timeout'/>
+      <var-decl name='panic_notifier_list' type-id='dbd58f6e' mangled-name='panic_notifier_list' visibility='default' filepath='kernel/panic.c' line='73' column='1' elf-symbol-id='panic_notifier_list'/>
+      <var-decl name='panic_timeout' type-id='95e97e5e' mangled-name='panic_timeout' visibility='default' filepath='kernel/panic.c' line='62' column='1' elf-symbol-id='panic_timeout'/>
       <var-decl name='param_array_ops' type-id='95d0d4e8' mangled-name='param_array_ops' visibility='default' filepath='kernel/params.c' line='485' column='1' elf-symbol-id='param_array_ops'/>
       <function-decl name='param_get_bool' mangled-name='param_get_bool' filepath='kernel/params.c' line='299' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='param_get_bool'>
         <parameter type-id='26a90f95' name='buffer' filepath='kernel/params.c' line='299' column='1'/>
@@ -138109,22 +138856,22 @@
         <parameter type-id='edcbd723' name='kp' filepath='kernel/params.c' line='242' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='part_end_io_acct' mangled-name='part_end_io_acct' filepath='block/blk-core.c' line='1377' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='part_end_io_acct'>
-        <parameter type-id='84dc82b7' name='part' filepath='block/blk-core.c' line='1377' column='1'/>
-        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-core.c' line='1377' column='1'/>
-        <parameter type-id='7359adad' name='start_time' filepath='block/blk-core.c' line='1378' column='1'/>
+      <function-decl name='part_end_io_acct' mangled-name='part_end_io_acct' filepath='block/blk-core.c' line='1375' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='part_end_io_acct'>
+        <parameter type-id='84dc82b7' name='part' filepath='block/blk-core.c' line='1375' column='1'/>
+        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-core.c' line='1375' column='1'/>
+        <parameter type-id='7359adad' name='start_time' filepath='block/blk-core.c' line='1376' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='part_start_io_acct' mangled-name='part_start_io_acct' filepath='block/blk-core.c' line='1347' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='part_start_io_acct'>
-        <parameter type-id='33c599da' name='disk' filepath='block/blk-core.c' line='1347' column='1'/>
-        <parameter type-id='c4219d27' name='part' filepath='block/blk-core.c' line='1347' column='1'/>
-        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-core.c' line='1348' column='1'/>
+      <function-decl name='part_start_io_acct' mangled-name='part_start_io_acct' filepath='block/blk-core.c' line='1345' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='part_start_io_acct'>
+        <parameter type-id='33c599da' name='disk' filepath='block/blk-core.c' line='1345' column='1'/>
+        <parameter type-id='c4219d27' name='part' filepath='block/blk-core.c' line='1345' column='1'/>
+        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-core.c' line='1346' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='passthru_features_check' mangled-name='passthru_features_check' filepath='net/core/dev.c' line='3503' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='passthru_features_check'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='3503' column='1'/>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='3504' column='1'/>
-        <parameter type-id='f9f4b16f' name='features' filepath='net/core/dev.c' line='3505' column='1'/>
+      <function-decl name='passthru_features_check' mangled-name='passthru_features_check' filepath='net/core/dev.c' line='3507' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='passthru_features_check'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='3507' column='1'/>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='3508' column='1'/>
+        <parameter type-id='f9f4b16f' name='features' filepath='net/core/dev.c' line='3509' column='1'/>
         <return type-id='f9f4b16f'/>
       </function-decl>
       <function-decl name='path_put' mangled-name='path_put' filepath='fs/namei.c' line='497' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='path_put'>
@@ -138152,8 +138899,8 @@
         <parameter type-id='95e97e5e' name='resno' filepath='drivers/pci/setup-res.c' line='321' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_assign_unassigned_bus_resources' mangled-name='pci_assign_unassigned_bus_resources' filepath='drivers/pci/setup-bus.c' line='2228' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_assign_unassigned_bus_resources'>
-        <parameter type-id='d1feb554' name='bus' filepath='drivers/pci/setup-bus.c' line='2228' column='1'/>
+      <function-decl name='pci_assign_unassigned_bus_resources' mangled-name='pci_assign_unassigned_bus_resources' filepath='drivers/pci/setup-bus.c' line='2277' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_assign_unassigned_bus_resources'>
+        <parameter type-id='d1feb554' name='bus' filepath='drivers/pci/setup-bus.c' line='2277' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='pci_bus_resource_n' mangled-name='pci_bus_resource_n' filepath='drivers/pci/bus.c' line='63' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_bus_resource_n'>
@@ -138162,17 +138909,17 @@
         <return type-id='c9d64c0d'/>
       </function-decl>
       <var-decl name='pci_bus_type' type-id='b31bfc8a' mangled-name='pci_bus_type' visibility='default' filepath='drivers/pci/pci-driver.c' line='1598' column='1' elf-symbol-id='pci_bus_type'/>
-      <function-decl name='pci_choose_state' mangled-name='pci_choose_state' filepath='drivers/pci/pci.c' line='1373' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_choose_state'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1373' column='1'/>
-        <parameter type-id='08496218' name='state' filepath='drivers/pci/pci.c' line='1373' column='1'/>
+      <function-decl name='pci_choose_state' mangled-name='pci_choose_state' filepath='drivers/pci/pci.c' line='1370' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_choose_state'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1370' column='1'/>
+        <parameter type-id='08496218' name='state' filepath='drivers/pci/pci.c' line='1370' column='1'/>
         <return type-id='49c32219'/>
       </function-decl>
-      <function-decl name='pci_clear_master' mangled-name='pci_clear_master' filepath='drivers/pci/pci.c' line='4321' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_clear_master'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='4321' column='1'/>
+      <function-decl name='pci_clear_master' mangled-name='pci_clear_master' filepath='drivers/pci/pci.c' line='4318' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_clear_master'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='4318' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pci_d3cold_disable' mangled-name='pci_d3cold_disable' filepath='drivers/pci/pci.c' line='3013' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_d3cold_disable'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='3013' column='1'/>
+      <function-decl name='pci_d3cold_disable' mangled-name='pci_d3cold_disable' filepath='drivers/pci/pci.c' line='3010' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_d3cold_disable'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='3010' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='pci_dev_present' mangled-name='pci_dev_present' filepath='drivers/pci/search.c' line='380' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_dev_present'>
@@ -138183,21 +138930,21 @@
         <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci-driver.c' line='1491' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pci_device_group' mangled-name='pci_device_group' filepath='drivers/iommu/iommu.c' line='1397' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_device_group'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='1397' column='1'/>
+      <function-decl name='pci_device_group' mangled-name='pci_device_group' filepath='drivers/iommu/iommu.c' line='1413' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_device_group'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='1413' column='1'/>
         <return type-id='0b19fc54'/>
       </function-decl>
-      <function-decl name='pci_device_is_present' mangled-name='pci_device_is_present' filepath='drivers/pci/pci.c' line='6158' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_device_is_present'>
-        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='6158' column='1'/>
+      <function-decl name='pci_device_is_present' mangled-name='pci_device_is_present' filepath='drivers/pci/pci.c' line='6149' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_device_is_present'>
+        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='6149' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='pci_disable_device' mangled-name='pci_disable_device' filepath='drivers/pci/pci.c' line='2145' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_disable_device'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='2145' column='1'/>
+      <function-decl name='pci_disable_device' mangled-name='pci_disable_device' filepath='drivers/pci/pci.c' line='2142' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_disable_device'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='2142' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pci_disable_link_state' mangled-name='pci_disable_link_state' filepath='drivers/pci/pcie/aspm.c' line='1137' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_disable_link_state'>
-        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pcie/aspm.c' line='1137' column='1'/>
-        <parameter type-id='95e97e5e' name='state' filepath='drivers/pci/pcie/aspm.c' line='1137' column='1'/>
+      <function-decl name='pci_disable_link_state' mangled-name='pci_disable_link_state' filepath='drivers/pci/pcie/aspm.c' line='1140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_disable_link_state'>
+        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pcie/aspm.c' line='1140' column='1'/>
+        <parameter type-id='95e97e5e' name='state' filepath='drivers/pci/pcie/aspm.c' line='1140' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='pci_disable_msi' mangled-name='pci_disable_msi' filepath='drivers/pci/msi.c' line='984' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_disable_msi'>
@@ -138216,17 +138963,17 @@
         <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/iov.c' line='943' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pci_enable_atomic_ops_to_root' mangled-name='pci_enable_atomic_ops_to_root' filepath='drivers/pci/pci.c' line='3675' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_enable_atomic_ops_to_root'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='3675' column='1'/>
-        <parameter type-id='19c2251e' name='cap_mask' filepath='drivers/pci/pci.c' line='3675' column='1'/>
+      <function-decl name='pci_enable_atomic_ops_to_root' mangled-name='pci_enable_atomic_ops_to_root' filepath='drivers/pci/pci.c' line='3672' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_enable_atomic_ops_to_root'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='3672' column='1'/>
+        <parameter type-id='19c2251e' name='cap_mask' filepath='drivers/pci/pci.c' line='3672' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_enable_device' mangled-name='pci_enable_device' filepath='drivers/pci/pci.c' line='1952' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_enable_device'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1952' column='1'/>
+      <function-decl name='pci_enable_device' mangled-name='pci_enable_device' filepath='drivers/pci/pci.c' line='1949' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_enable_device'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1949' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_enable_device_mem' mangled-name='pci_enable_device_mem' filepath='drivers/pci/pci.c' line='1935' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_enable_device_mem'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1935' column='1'/>
+      <function-decl name='pci_enable_device_mem' mangled-name='pci_enable_device_mem' filepath='drivers/pci/pci.c' line='1932' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_enable_device_mem'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1932' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='pci_enable_msi' mangled-name='pci_enable_msi' filepath='drivers/pci/msi.c' line='1149' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_enable_msi'>
@@ -138249,10 +138996,10 @@
         <parameter type-id='95e97e5e' name='nr_virtfn' filepath='drivers/pci/iov.c' line='928' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_enable_wake' mangled-name='pci_enable_wake' filepath='drivers/pci/pci.c' line='2509' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_enable_wake'>
-        <parameter type-id='85196e3f' name='pci_dev' filepath='drivers/pci/pci.c' line='2509' column='1'/>
-        <parameter type-id='49c32219' name='state' filepath='drivers/pci/pci.c' line='2509' column='1'/>
-        <parameter type-id='b50a4934' name='enable' filepath='drivers/pci/pci.c' line='2509' column='1'/>
+      <function-decl name='pci_enable_wake' mangled-name='pci_enable_wake' filepath='drivers/pci/pci.c' line='2506' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_enable_wake'>
+        <parameter type-id='85196e3f' name='pci_dev' filepath='drivers/pci/pci.c' line='2506' column='1'/>
+        <parameter type-id='49c32219' name='state' filepath='drivers/pci/pci.c' line='2506' column='1'/>
+        <parameter type-id='b50a4934' name='enable' filepath='drivers/pci/pci.c' line='2506' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='pci_epc_clear_bar' mangled-name='pci_epc_clear_bar' filepath='drivers/pci/endpoint/pci-epc-core.c' line='411' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_epc_clear_bar'>
@@ -138299,26 +139046,26 @@
         <parameter type-id='95e97e5e' name='busnr' filepath='drivers/pci/search.c' line='141' column='1'/>
         <return type-id='d1feb554'/>
       </function-decl>
-      <function-decl name='pci_find_capability' mangled-name='pci_find_capability' filepath='drivers/pci/pci.c' line='487' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_find_capability'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='487' column='1'/>
-        <parameter type-id='95e97e5e' name='cap' filepath='drivers/pci/pci.c' line='487' column='1'/>
+      <function-decl name='pci_find_capability' mangled-name='pci_find_capability' filepath='drivers/pci/pci.c' line='484' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_find_capability'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='484' column='1'/>
+        <parameter type-id='95e97e5e' name='cap' filepath='drivers/pci/pci.c' line='484' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_find_ext_capability' mangled-name='pci_find_ext_capability' filepath='drivers/pci/pci.c' line='593' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_find_ext_capability'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='593' column='1'/>
-        <parameter type-id='95e97e5e' name='cap' filepath='drivers/pci/pci.c' line='593' column='1'/>
+      <function-decl name='pci_find_ext_capability' mangled-name='pci_find_ext_capability' filepath='drivers/pci/pci.c' line='590' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_find_ext_capability'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='590' column='1'/>
+        <parameter type-id='95e97e5e' name='cap' filepath='drivers/pci/pci.c' line='590' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_find_next_capability' mangled-name='pci_find_next_capability' filepath='drivers/pci/pci.c' line='441' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_find_next_capability'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='441' column='1'/>
-        <parameter type-id='f9b06939' name='pos' filepath='drivers/pci/pci.c' line='441' column='1'/>
-        <parameter type-id='95e97e5e' name='cap' filepath='drivers/pci/pci.c' line='441' column='1'/>
+      <function-decl name='pci_find_next_capability' mangled-name='pci_find_next_capability' filepath='drivers/pci/pci.c' line='438' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_find_next_capability'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='438' column='1'/>
+        <parameter type-id='f9b06939' name='pos' filepath='drivers/pci/pci.c' line='438' column='1'/>
+        <parameter type-id='95e97e5e' name='cap' filepath='drivers/pci/pci.c' line='438' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_free_irq' mangled-name='pci_free_irq' filepath='drivers/pci/irq.c' line='70' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_free_irq'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/irq.c' line='70' column='1'/>
-        <parameter type-id='f0981eeb' name='nr' filepath='drivers/pci/irq.c' line='70' column='1'/>
-        <parameter type-id='eaa32e2f' name='dev_id' filepath='drivers/pci/irq.c' line='70' column='1'/>
+      <function-decl name='pci_free_irq' mangled-name='pci_free_irq' filepath='drivers/pci/irq.c' line='72' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_free_irq'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/irq.c' line='72' column='1'/>
+        <parameter type-id='f0981eeb' name='nr' filepath='drivers/pci/irq.c' line='72' column='1'/>
+        <parameter type-id='eaa32e2f' name='dev_id' filepath='drivers/pci/irq.c' line='72' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='pci_free_irq_vectors' mangled-name='pci_free_irq_vectors' filepath='drivers/pci/msi.c' line='1284' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_free_irq_vectors'>
@@ -138333,12 +139080,28 @@
         <parameter type-id='f9409001' name='val' filepath='drivers/pci/access.c' line='78' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
+      <function-decl name='pci_generic_config_read32' mangled-name='pci_generic_config_read32' filepath='drivers/pci/access.c' line='119' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_generic_config_read32'>
+        <parameter type-id='d1feb554' name='bus' filepath='drivers/pci/access.c' line='119' column='1'/>
+        <parameter type-id='f0981eeb' name='devfn' filepath='drivers/pci/access.c' line='119' column='1'/>
+        <parameter type-id='95e97e5e' name='where' filepath='drivers/pci/access.c' line='120' column='1'/>
+        <parameter type-id='95e97e5e' name='size' filepath='drivers/pci/access.c' line='120' column='1'/>
+        <parameter type-id='f9409001' name='val' filepath='drivers/pci/access.c' line='120' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
       <function-decl name='pci_generic_config_write' mangled-name='pci_generic_config_write' filepath='drivers/pci/access.c' line='99' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_generic_config_write'>
         <parameter type-id='d1feb554' name='bus' filepath='drivers/pci/access.c' line='99' column='1'/>
         <parameter type-id='f0981eeb' name='devfn' filepath='drivers/pci/access.c' line='99' column='1'/>
         <parameter type-id='95e97e5e' name='where' filepath='drivers/pci/access.c' line='100' column='1'/>
         <parameter type-id='95e97e5e' name='size' filepath='drivers/pci/access.c' line='100' column='1'/>
         <parameter type-id='19c2251e' name='val' filepath='drivers/pci/access.c' line='100' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='pci_generic_config_write32' mangled-name='pci_generic_config_write32' filepath='drivers/pci/access.c' line='139' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_generic_config_write32'>
+        <parameter type-id='d1feb554' name='bus' filepath='drivers/pci/access.c' line='139' column='1'/>
+        <parameter type-id='f0981eeb' name='devfn' filepath='drivers/pci/access.c' line='139' column='1'/>
+        <parameter type-id='95e97e5e' name='where' filepath='drivers/pci/access.c' line='140' column='1'/>
+        <parameter type-id='95e97e5e' name='size' filepath='drivers/pci/access.c' line='140' column='1'/>
+        <parameter type-id='19c2251e' name='val' filepath='drivers/pci/access.c' line='140' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='pci_get_device' mangled-name='pci_get_device' filepath='drivers/pci/search.c' line='333' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_get_device'>
@@ -138362,9 +139125,9 @@
         <parameter type-id='cb0dbc3c' name='bridge' filepath='drivers/pci/probe.c' line='3005' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_intx' mangled-name='pci_intx' filepath='drivers/pci/pci.c' line='4463' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_intx'>
-        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='4463' column='1'/>
-        <parameter type-id='95e97e5e' name='enable' filepath='drivers/pci/pci.c' line='4463' column='1'/>
+      <function-decl name='pci_intx' mangled-name='pci_intx' filepath='drivers/pci/pci.c' line='4460' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_intx'>
+        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='4460' column='1'/>
+        <parameter type-id='95e97e5e' name='enable' filepath='drivers/pci/pci.c' line='4460' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='pci_iomap' mangled-name='pci_iomap' filepath='lib/pci_iomap.c' line='111' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_iomap'>
@@ -138380,9 +139143,9 @@
         <parameter type-id='7359adad' name='maxlen' filepath='lib/pci_iomap.c' line='31' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='pci_ioremap_bar' mangled-name='pci_ioremap_bar' filepath='drivers/pci/pci.c' line='216' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_ioremap_bar'>
-        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='216' column='1'/>
-        <parameter type-id='95e97e5e' name='bar' filepath='drivers/pci/pci.c' line='216' column='1'/>
+      <function-decl name='pci_ioremap_bar' mangled-name='pci_ioremap_bar' filepath='drivers/pci/pci.c' line='213' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_ioremap_bar'>
+        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='213' column='1'/>
+        <parameter type-id='95e97e5e' name='bar' filepath='drivers/pci/pci.c' line='213' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
       <function-decl name='pci_irq_get_affinity' mangled-name='pci_irq_get_affinity' filepath='drivers/pci/msi.c' line='1342' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_irq_get_affinity'>
@@ -138395,15 +139158,18 @@
         <parameter type-id='f0981eeb' name='nr' filepath='drivers/pci/msi.c' line='1303' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_load_and_free_saved_state' mangled-name='pci_load_and_free_saved_state' filepath='drivers/pci/pci.c' line='1792' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_load_and_free_saved_state'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1792' column='1'/>
-        <parameter type-id='6efc6709' name='state' filepath='drivers/pci/pci.c' line='1793' column='1'/>
+      <function-decl name='pci_load_and_free_saved_state' mangled-name='pci_load_and_free_saved_state' filepath='drivers/pci/pci.c' line='1789' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_load_and_free_saved_state'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1789' column='1'/>
+        <parameter type-id='6efc6709' name='state' filepath='drivers/pci/pci.c' line='1790' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_load_saved_state' mangled-name='pci_load_saved_state' filepath='drivers/pci/pci.c' line='1755' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_load_saved_state'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1755' column='1'/>
-        <parameter type-id='e4acc659' name='state' filepath='drivers/pci/pci.c' line='1756' column='1'/>
+      <function-decl name='pci_load_saved_state' mangled-name='pci_load_saved_state' filepath='drivers/pci/pci.c' line='1752' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_load_saved_state'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1752' column='1'/>
+        <parameter type-id='e4acc659' name='state' filepath='drivers/pci/pci.c' line='1753' column='1'/>
         <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='pci_lock_rescan_remove' mangled-name='pci_lock_rescan_remove' filepath='drivers/pci/probe.c' line='3244' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_lock_rescan_remove'>
+        <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='pci_map_rom' mangled-name='pci_map_rom' filepath='drivers/pci/rom.c' line='136' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_map_rom'>
         <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/rom.c' line='136' column='1'/>
@@ -138440,6 +139206,14 @@
         <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/iov.c' line='960' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
+      <function-decl name='pci_pio_to_address' mangled-name='pci_pio_to_address' filepath='drivers/pci/pci.c' line='4045' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_pio_to_address'>
+        <parameter type-id='7359adad' name='pio' filepath='drivers/pci/pci.c' line='4045' column='1'/>
+        <return type-id='2522883d'/>
+      </function-decl>
+      <function-decl name='pci_prepare_to_sleep' mangled-name='pci_prepare_to_sleep' filepath='drivers/pci/pci.c' line='2611' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_prepare_to_sleep'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='2611' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
       <function-decl name='pci_read_config_byte' mangled-name='pci_read_config_byte' filepath='drivers/pci/access.c' line='523' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_read_config_byte'>
         <parameter type-id='947f31e6' name='dev' filepath='drivers/pci/access.c' line='523' column='1'/>
         <parameter type-id='95e97e5e' name='where' filepath='drivers/pci/access.c' line='523' column='1'/>
@@ -138458,13 +139232,13 @@
         <parameter type-id='26d4d46f' name='val' filepath='drivers/pci/access.c' line='533' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_release_region' mangled-name='pci_release_region' filepath='drivers/pci/pci.c' line='3807' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_release_region'>
-        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='3807' column='1'/>
-        <parameter type-id='95e97e5e' name='bar' filepath='drivers/pci/pci.c' line='3807' column='1'/>
+      <function-decl name='pci_release_region' mangled-name='pci_release_region' filepath='drivers/pci/pci.c' line='3804' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_release_region'>
+        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='3804' column='1'/>
+        <parameter type-id='95e97e5e' name='bar' filepath='drivers/pci/pci.c' line='3804' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pci_release_regions' mangled-name='pci_release_regions' filepath='drivers/pci/pci.c' line='3965' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_release_regions'>
-        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='3965' column='1'/>
+      <function-decl name='pci_release_regions' mangled-name='pci_release_regions' filepath='drivers/pci/pci.c' line='3962' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_release_regions'>
+        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='3962' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='pci_release_resource' mangled-name='pci_release_resource' filepath='drivers/pci/setup-res.c' line='405' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_release_resource'>
@@ -138472,9 +139246,9 @@
         <parameter type-id='95e97e5e' name='resno' filepath='drivers/pci/setup-res.c' line='405' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pci_release_selected_regions' mangled-name='pci_release_selected_regions' filepath='drivers/pci/pci.c' line='3904' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_release_selected_regions'>
-        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='3904' column='1'/>
-        <parameter type-id='95e97e5e' name='bars' filepath='drivers/pci/pci.c' line='3904' column='1'/>
+      <function-decl name='pci_release_selected_regions' mangled-name='pci_release_selected_regions' filepath='drivers/pci/pci.c' line='3901' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_release_selected_regions'>
+        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='3901' column='1'/>
+        <parameter type-id='95e97e5e' name='bars' filepath='drivers/pci/pci.c' line='3901' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='pci_remove_root_bus' mangled-name='pci_remove_root_bus' filepath='drivers/pci/remove.c' line='147' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_remove_root_bus'>
@@ -138491,29 +139265,29 @@
         <parameter is-variadic='yes'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_request_region' mangled-name='pci_request_region' filepath='drivers/pci/pci.c' line='3890' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_request_region'>
-        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='3890' column='1'/>
-        <parameter type-id='95e97e5e' name='bar' filepath='drivers/pci/pci.c' line='3890' column='1'/>
-        <parameter type-id='80f4b756' name='res_name' filepath='drivers/pci/pci.c' line='3890' column='1'/>
+      <function-decl name='pci_request_region' mangled-name='pci_request_region' filepath='drivers/pci/pci.c' line='3887' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_request_region'>
+        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='3887' column='1'/>
+        <parameter type-id='95e97e5e' name='bar' filepath='drivers/pci/pci.c' line='3887' column='1'/>
+        <parameter type-id='80f4b756' name='res_name' filepath='drivers/pci/pci.c' line='3887' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_request_regions' mangled-name='pci_request_regions' filepath='drivers/pci/pci.c' line='3984' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_request_regions'>
-        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='3984' column='1'/>
-        <parameter type-id='80f4b756' name='res_name' filepath='drivers/pci/pci.c' line='3984' column='1'/>
+      <function-decl name='pci_request_regions' mangled-name='pci_request_regions' filepath='drivers/pci/pci.c' line='3981' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_request_regions'>
+        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='3981' column='1'/>
+        <parameter type-id='80f4b756' name='res_name' filepath='drivers/pci/pci.c' line='3981' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_request_selected_regions' mangled-name='pci_request_selected_regions' filepath='drivers/pci/pci.c' line='3940' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_request_selected_regions'>
-        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='3940' column='1'/>
-        <parameter type-id='95e97e5e' name='bars' filepath='drivers/pci/pci.c' line='3940' column='1'/>
-        <parameter type-id='80f4b756' name='res_name' filepath='drivers/pci/pci.c' line='3941' column='1'/>
+      <function-decl name='pci_request_selected_regions' mangled-name='pci_request_selected_regions' filepath='drivers/pci/pci.c' line='3937' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_request_selected_regions'>
+        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='3937' column='1'/>
+        <parameter type-id='95e97e5e' name='bars' filepath='drivers/pci/pci.c' line='3937' column='1'/>
+        <parameter type-id='80f4b756' name='res_name' filepath='drivers/pci/pci.c' line='3938' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='pci_rescan_bus' mangled-name='pci_rescan_bus' filepath='drivers/pci/probe.c' line='3226' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_rescan_bus'>
         <parameter type-id='d1feb554' name='bus' filepath='drivers/pci/probe.c' line='3226' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='pci_reset_function' mangled-name='pci_reset_function' filepath='drivers/pci/pci.c' line='5163' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_reset_function'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='5163' column='1'/>
+      <function-decl name='pci_reset_function' mangled-name='pci_reset_function' filepath='drivers/pci/pci.c' line='5154' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_reset_function'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='5154' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='pci_resize_resource' mangled-name='pci_resize_resource' filepath='drivers/pci/setup-res.c' line='421' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_resize_resource'>
@@ -138526,30 +139300,30 @@
         <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/msi.c' line='475' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pci_restore_state' mangled-name='pci_restore_state' filepath='drivers/pci/pci.c' line='1669' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_restore_state'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1669' column='1'/>
+      <function-decl name='pci_restore_state' mangled-name='pci_restore_state' filepath='drivers/pci/pci.c' line='1666' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_restore_state'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1666' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pci_save_state' mangled-name='pci_save_state' filepath='drivers/pci/pci.c' line='1554' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_save_state'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1554' column='1'/>
+      <function-decl name='pci_save_state' mangled-name='pci_save_state' filepath='drivers/pci/pci.c' line='1551' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_save_state'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1551' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_select_bars' mangled-name='pci_select_bars' filepath='drivers/pci/pci.c' line='6005' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_select_bars'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='6005' column='1'/>
-        <parameter type-id='7359adad' name='flags' filepath='drivers/pci/pci.c' line='6005' column='1'/>
+      <function-decl name='pci_select_bars' mangled-name='pci_select_bars' filepath='drivers/pci/pci.c' line='5996' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_select_bars'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='5996' column='1'/>
+        <parameter type-id='7359adad' name='flags' filepath='drivers/pci/pci.c' line='5996' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_set_master' mangled-name='pci_set_master' filepath='drivers/pci/pci.c' line='4310' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_set_master'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='4310' column='1'/>
+      <function-decl name='pci_set_master' mangled-name='pci_set_master' filepath='drivers/pci/pci.c' line='4307' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_set_master'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='4307' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pci_set_mwi' mangled-name='pci_set_mwi' filepath='drivers/pci/pci.c' line='4373' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_set_mwi'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='4373' column='1'/>
+      <function-decl name='pci_set_mwi' mangled-name='pci_set_mwi' filepath='drivers/pci/pci.c' line='4370' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_set_mwi'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='4370' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_set_power_state' mangled-name='pci_set_power_state' filepath='drivers/pci/pci.c' line='1313' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_set_power_state'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1313' column='1'/>
-        <parameter type-id='49c32219' name='state' filepath='drivers/pci/pci.c' line='1313' column='1'/>
+      <function-decl name='pci_set_power_state' mangled-name='pci_set_power_state' filepath='drivers/pci/pci.c' line='1310' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_set_power_state'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1310' column='1'/>
+        <parameter type-id='49c32219' name='state' filepath='drivers/pci/pci.c' line='1310' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='pci_sriov_configure_simple' mangled-name='pci_sriov_configure_simple' filepath='drivers/pci/iov.c' line='1066' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_sriov_configure_simple'>
@@ -138561,13 +139335,16 @@
         <parameter type-id='d1feb554' name='bus' filepath='drivers/pci/remove.c' line='129' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pci_store_saved_state' mangled-name='pci_store_saved_state' filepath='drivers/pci/pci.c' line='1716' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_store_saved_state'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1716' column='1'/>
+      <function-decl name='pci_store_saved_state' mangled-name='pci_store_saved_state' filepath='drivers/pci/pci.c' line='1713' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_store_saved_state'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='1713' column='1'/>
         <return type-id='e4acc659'/>
       </function-decl>
-      <function-decl name='pci_try_set_mwi' mangled-name='pci_try_set_mwi' filepath='drivers/pci/pci.c' line='4426' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_try_set_mwi'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='4426' column='1'/>
+      <function-decl name='pci_try_set_mwi' mangled-name='pci_try_set_mwi' filepath='drivers/pci/pci.c' line='4423' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_try_set_mwi'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='4423' column='1'/>
         <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='pci_unlock_rescan_remove' mangled-name='pci_unlock_rescan_remove' filepath='drivers/pci/probe.c' line='3250' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_unlock_rescan_remove'>
+        <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='pci_unmap_rom' mangled-name='pci_unmap_rom' filepath='drivers/pci/rom.c' line='187' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_unmap_rom'>
         <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/rom.c' line='187' column='1'/>
@@ -138582,9 +139359,9 @@
         <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/iov.c' line='976' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pci_wake_from_d3' mangled-name='pci_wake_from_d3' filepath='drivers/pci/pci.c' line='2532' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_wake_from_d3'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='2532' column='1'/>
-        <parameter type-id='b50a4934' name='enable' filepath='drivers/pci/pci.c' line='2532' column='1'/>
+      <function-decl name='pci_wake_from_d3' mangled-name='pci_wake_from_d3' filepath='drivers/pci/pci.c' line='2529' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_wake_from_d3'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='2529' column='1'/>
+        <parameter type-id='b50a4934' name='enable' filepath='drivers/pci/pci.c' line='2529' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='pci_walk_bus' mangled-name='pci_walk_bus' filepath='drivers/pci/bus.c' line='374' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pci_walk_bus'>
@@ -138617,15 +139394,15 @@
         <parameter type-id='c9d64c0d' name='res' filepath='drivers/pci/host-bridge.c' line='51' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pcie_aspm_enabled' mangled-name='pcie_aspm_enabled' filepath='drivers/pci/pcie/aspm.c' line='1193' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pcie_aspm_enabled'>
-        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pcie/aspm.c' line='1193' column='1'/>
+      <function-decl name='pcie_aspm_enabled' mangled-name='pcie_aspm_enabled' filepath='drivers/pci/pcie/aspm.c' line='1196' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pcie_aspm_enabled'>
+        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pcie/aspm.c' line='1196' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='pcie_bandwidth_available' mangled-name='pcie_bandwidth_available' filepath='drivers/pci/pci.c' line='5832' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pcie_bandwidth_available'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='5832' column='1'/>
-        <parameter type-id='9c084b0f' name='limiting_dev' filepath='drivers/pci/pci.c' line='5832' column='1'/>
-        <parameter type-id='982c1b74' name='speed' filepath='drivers/pci/pci.c' line='5833' column='1'/>
-        <parameter type-id='d3ffb002' name='width' filepath='drivers/pci/pci.c' line='5834' column='1'/>
+      <function-decl name='pcie_bandwidth_available' mangled-name='pcie_bandwidth_available' filepath='drivers/pci/pci.c' line='5823' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pcie_bandwidth_available'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='5823' column='1'/>
+        <parameter type-id='9c084b0f' name='limiting_dev' filepath='drivers/pci/pci.c' line='5823' column='1'/>
+        <parameter type-id='982c1b74' name='speed' filepath='drivers/pci/pci.c' line='5824' column='1'/>
+        <parameter type-id='d3ffb002' name='width' filepath='drivers/pci/pci.c' line='5825' column='1'/>
         <return type-id='19c2251e'/>
       </function-decl>
       <function-decl name='pcie_capability_clear_and_set_word' mangled-name='pcie_capability_clear_and_set_word' filepath='drivers/pci/access.c' line='489' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pcie_capability_clear_and_set_word'>
@@ -138647,21 +139424,21 @@
         <parameter type-id='1dc6a898' name='val' filepath='drivers/pci/access.c' line='465' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pcie_get_mps' mangled-name='pcie_get_mps' filepath='drivers/pci/pci.c' line='5780' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pcie_get_mps'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='5780' column='1'/>
+      <function-decl name='pcie_get_mps' mangled-name='pcie_get_mps' filepath='drivers/pci/pci.c' line='5771' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pcie_get_mps'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='5771' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pcie_get_speed_cap' mangled-name='pcie_get_speed_cap' filepath='drivers/pci/pci.c' line='5883' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pcie_get_speed_cap'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='5883' column='1'/>
+      <function-decl name='pcie_get_speed_cap' mangled-name='pcie_get_speed_cap' filepath='drivers/pci/pci.c' line='5874' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pcie_get_speed_cap'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='5874' column='1'/>
         <return type-id='f290f4ed'/>
       </function-decl>
-      <function-decl name='pcie_set_mps' mangled-name='pcie_set_mps' filepath='drivers/pci/pci.c' line='5798' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pcie_set_mps'>
-        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='5798' column='1'/>
-        <parameter type-id='95e97e5e' name='mps' filepath='drivers/pci/pci.c' line='5798' column='1'/>
+      <function-decl name='pcie_set_mps' mangled-name='pcie_set_mps' filepath='drivers/pci/pci.c' line='5789' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pcie_set_mps'>
+        <parameter type-id='85196e3f' name='dev' filepath='drivers/pci/pci.c' line='5789' column='1'/>
+        <parameter type-id='95e97e5e' name='mps' filepath='drivers/pci/pci.c' line='5789' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pcim_enable_device' mangled-name='pcim_enable_device' filepath='drivers/pci/pci.c' line='2025' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pcim_enable_device'>
-        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='2025' column='1'/>
+      <function-decl name='pcim_enable_device' mangled-name='pcim_enable_device' filepath='drivers/pci/pci.c' line='2022' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pcim_enable_device'>
+        <parameter type-id='85196e3f' name='pdev' filepath='drivers/pci/pci.c' line='2022' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='pcpu_nr_pages' mangled-name='pcpu_nr_pages' filepath='mm/percpu.c' line='3167' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pcpu_nr_pages'>
@@ -138686,8 +139463,8 @@
         <parameter type-id='9b7c55ef' name='amount' filepath='lib/percpu_counter.c' line='60' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='percpu_down_write' mangled-name='percpu_down_write' filepath='kernel/locking/percpu-rwsem.c' line='230' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='percpu_down_write'>
-        <parameter type-id='652d9ef9' name='sem' filepath='kernel/locking/percpu-rwsem.c' line='230' column='1'/>
+      <function-decl name='percpu_down_write' mangled-name='percpu_down_write' filepath='kernel/locking/percpu-rwsem.c' line='231' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='percpu_down_write'>
+        <parameter type-id='652d9ef9' name='sem' filepath='kernel/locking/percpu-rwsem.c' line='231' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='percpu_ref_exit' mangled-name='percpu_ref_exit' filepath='lib/percpu-refcount.c' line='129' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='percpu_ref_exit'>
@@ -138718,8 +139495,8 @@
         <parameter type-id='60219102' name='ref' filepath='lib/percpu-refcount.c' line='346' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='percpu_up_write' mangled-name='percpu_up_write' filepath='kernel/locking/percpu-rwsem.c' line='259' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='percpu_up_write'>
-        <parameter type-id='652d9ef9' name='sem' filepath='kernel/locking/percpu-rwsem.c' line='259' column='1'/>
+      <function-decl name='percpu_up_write' mangled-name='percpu_up_write' filepath='kernel/locking/percpu-rwsem.c' line='260' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='percpu_up_write'>
+        <parameter type-id='652d9ef9' name='sem' filepath='kernel/locking/percpu-rwsem.c' line='260' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='perf_aux_output_begin' mangled-name='perf_aux_output_begin' filepath='kernel/events/ring_buffer.c' line='361' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='perf_aux_output_begin'>
@@ -138741,12 +139518,12 @@
         <parameter type-id='2bf16f59' name='event' filepath='kernel/events/core.c' line='3124' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='perf_event_create_kernel_counter' mangled-name='perf_event_create_kernel_counter' filepath='kernel/events/core.c' line='12186' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='perf_event_create_kernel_counter'>
-        <parameter type-id='20862e61' name='attr' filepath='kernel/events/core.c' line='12186' column='1'/>
-        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/events/core.c' line='12186' column='1'/>
-        <parameter type-id='f23e2572' name='task' filepath='kernel/events/core.c' line='12187' column='1'/>
-        <parameter type-id='20a2e4e6' name='overflow_handler' filepath='kernel/events/core.c' line='12188' column='1'/>
-        <parameter type-id='eaa32e2f' name='context' filepath='kernel/events/core.c' line='12189' column='1'/>
+      <function-decl name='perf_event_create_kernel_counter' mangled-name='perf_event_create_kernel_counter' filepath='kernel/events/core.c' line='12188' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='perf_event_create_kernel_counter'>
+        <parameter type-id='20862e61' name='attr' filepath='kernel/events/core.c' line='12188' column='1'/>
+        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/events/core.c' line='12188' column='1'/>
+        <parameter type-id='f23e2572' name='task' filepath='kernel/events/core.c' line='12189' column='1'/>
+        <parameter type-id='20a2e4e6' name='overflow_handler' filepath='kernel/events/core.c' line='12190' column='1'/>
+        <parameter type-id='eaa32e2f' name='context' filepath='kernel/events/core.c' line='12191' column='1'/>
         <return type-id='2bf16f59'/>
       </function-decl>
       <function-decl name='perf_event_disable' mangled-name='perf_event_disable' filepath='kernel/events/core.c' line='2453' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='perf_event_disable'>
@@ -138790,20 +139567,20 @@
       <function-decl name='perf_num_counters' mangled-name='perf_num_counters' filepath='drivers/perf/arm_pmu.c' line='598' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='perf_num_counters'>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='perf_pmu_migrate_context' mangled-name='perf_pmu_migrate_context' filepath='kernel/events/core.c' line='12265' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='perf_pmu_migrate_context'>
-        <parameter type-id='0906f5b9' name='pmu' filepath='kernel/events/core.c' line='12265' column='1'/>
-        <parameter type-id='95e97e5e' name='src_cpu' filepath='kernel/events/core.c' line='12265' column='1'/>
-        <parameter type-id='95e97e5e' name='dst_cpu' filepath='kernel/events/core.c' line='12265' column='1'/>
+      <function-decl name='perf_pmu_migrate_context' mangled-name='perf_pmu_migrate_context' filepath='kernel/events/core.c' line='12267' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='perf_pmu_migrate_context'>
+        <parameter type-id='0906f5b9' name='pmu' filepath='kernel/events/core.c' line='12267' column='1'/>
+        <parameter type-id='95e97e5e' name='src_cpu' filepath='kernel/events/core.c' line='12267' column='1'/>
+        <parameter type-id='95e97e5e' name='dst_cpu' filepath='kernel/events/core.c' line='12267' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='perf_pmu_register' mangled-name='perf_pmu_register' filepath='kernel/events/core.c' line='10806' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='perf_pmu_register'>
-        <parameter type-id='0906f5b9' name='pmu' filepath='kernel/events/core.c' line='10806' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='kernel/events/core.c' line='10806' column='1'/>
-        <parameter type-id='95e97e5e' name='type' filepath='kernel/events/core.c' line='10806' column='1'/>
+      <function-decl name='perf_pmu_register' mangled-name='perf_pmu_register' filepath='kernel/events/core.c' line='10808' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='perf_pmu_register'>
+        <parameter type-id='0906f5b9' name='pmu' filepath='kernel/events/core.c' line='10808' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='kernel/events/core.c' line='10808' column='1'/>
+        <parameter type-id='95e97e5e' name='type' filepath='kernel/events/core.c' line='10808' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='perf_pmu_unregister' mangled-name='perf_pmu_unregister' filepath='kernel/events/core.c' line='10942' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='perf_pmu_unregister'>
-        <parameter type-id='0906f5b9' name='pmu' filepath='kernel/events/core.c' line='10942' column='1'/>
+      <function-decl name='perf_pmu_unregister' mangled-name='perf_pmu_unregister' filepath='kernel/events/core.c' line='10944' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='perf_pmu_unregister'>
+        <parameter type-id='0906f5b9' name='pmu' filepath='kernel/events/core.c' line='10944' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='perf_trace_buf_alloc' mangled-name='perf_trace_buf_alloc' filepath='kernel/trace/trace_event_perf.c' line='395' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='perf_trace_buf_alloc'>
@@ -138858,60 +139635,65 @@
         <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy_device.c' line='1045' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='phy_do_ioctl_running' mangled-name='phy_do_ioctl_running' filepath='drivers/net/phy/phy.c' line='425' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_do_ioctl_running'>
-        <parameter type-id='68a2d05b' name='dev' filepath='drivers/net/phy/phy.c' line='425' column='1'/>
-        <parameter type-id='d494b97c' name='ifr' filepath='drivers/net/phy/phy.c' line='425' column='1'/>
-        <parameter type-id='95e97e5e' name='cmd' filepath='drivers/net/phy/phy.c' line='425' column='1'/>
+      <function-decl name='phy_do_ioctl_running' mangled-name='phy_do_ioctl_running' filepath='drivers/net/phy/phy.c' line='437' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_do_ioctl_running'>
+        <parameter type-id='68a2d05b' name='dev' filepath='drivers/net/phy/phy.c' line='437' column='1'/>
+        <parameter type-id='d494b97c' name='ifr' filepath='drivers/net/phy/phy.c' line='437' column='1'/>
+        <parameter type-id='95e97e5e' name='cmd' filepath='drivers/net/phy/phy.c' line='437' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='phy_drivers_register' mangled-name='phy_drivers_register' filepath='drivers/net/phy/phy_device.c' line='2979' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_drivers_register'>
-        <parameter type-id='e812884b' name='new_driver' filepath='drivers/net/phy/phy_device.c' line='2979' column='1'/>
-        <parameter type-id='95e97e5e' name='n' filepath='drivers/net/phy/phy_device.c' line='2979' column='1'/>
-        <parameter type-id='2730d015' name='owner' filepath='drivers/net/phy/phy_device.c' line='2980' column='1'/>
+      <function-decl name='phy_drivers_register' mangled-name='phy_drivers_register' filepath='drivers/net/phy/phy_device.c' line='2973' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_drivers_register'>
+        <parameter type-id='e812884b' name='new_driver' filepath='drivers/net/phy/phy_device.c' line='2973' column='1'/>
+        <parameter type-id='95e97e5e' name='n' filepath='drivers/net/phy/phy_device.c' line='2973' column='1'/>
+        <parameter type-id='2730d015' name='owner' filepath='drivers/net/phy/phy_device.c' line='2974' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='phy_drivers_unregister' mangled-name='phy_drivers_unregister' filepath='drivers/net/phy/phy_device.c' line='3002' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_drivers_unregister'>
-        <parameter type-id='e812884b' name='drv' filepath='drivers/net/phy/phy_device.c' line='3002' column='1'/>
-        <parameter type-id='95e97e5e' name='n' filepath='drivers/net/phy/phy_device.c' line='3002' column='1'/>
+      <function-decl name='phy_drivers_unregister' mangled-name='phy_drivers_unregister' filepath='drivers/net/phy/phy_device.c' line='2996' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_drivers_unregister'>
+        <parameter type-id='e812884b' name='drv' filepath='drivers/net/phy/phy_device.c' line='2996' column='1'/>
+        <parameter type-id='95e97e5e' name='n' filepath='drivers/net/phy/phy_device.c' line='2996' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='phy_ethtool_get_eee' mangled-name='phy_ethtool_get_eee' filepath='drivers/net/phy/phy.c' line='1400' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_get_eee'>
-        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1400' column='1'/>
-        <parameter type-id='eced47f6' name='data' filepath='drivers/net/phy/phy.c' line='1400' column='1'/>
+      <function-decl name='phy_ethtool_get_eee' mangled-name='phy_ethtool_get_eee' filepath='drivers/net/phy/phy.c' line='1409' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_get_eee'>
+        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1409' column='1'/>
+        <parameter type-id='eced47f6' name='data' filepath='drivers/net/phy/phy.c' line='1409' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='phy_ethtool_get_link_ksettings' mangled-name='phy_ethtool_get_link_ksettings' filepath='drivers/net/phy/phy.c' line='1509' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_get_link_ksettings'>
-        <parameter type-id='68a2d05b' name='ndev' filepath='drivers/net/phy/phy.c' line='1509' column='1'/>
-        <parameter type-id='70de91e2' name='cmd' filepath='drivers/net/phy/phy.c' line='1510' column='1'/>
+      <function-decl name='phy_ethtool_get_link_ksettings' mangled-name='phy_ethtool_get_link_ksettings' filepath='drivers/net/phy/phy.c' line='1518' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_get_link_ksettings'>
+        <parameter type-id='68a2d05b' name='ndev' filepath='drivers/net/phy/phy.c' line='1518' column='1'/>
+        <parameter type-id='70de91e2' name='cmd' filepath='drivers/net/phy/phy.c' line='1519' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='phy_ethtool_ksettings_get' mangled-name='phy_ethtool_ksettings_get' filepath='drivers/net/phy/phy.c' line='268' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_ksettings_get'>
-        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='268' column='1'/>
-        <parameter type-id='70de91e2' name='cmd' filepath='drivers/net/phy/phy.c' line='269' column='1'/>
+      <function-decl name='phy_ethtool_get_wol' mangled-name='phy_ethtool_get_wol' filepath='drivers/net/phy/phy.c' line='1511' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_get_wol'>
+        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1511' column='1'/>
+        <parameter type-id='fde1bbcb' name='wol' filepath='drivers/net/phy/phy.c' line='1511' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='phy_ethtool_ksettings_set' mangled-name='phy_ethtool_ksettings_set' filepath='drivers/net/phy/phy.c' line='791' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_ksettings_set'>
-        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='791' column='1'/>
-        <parameter type-id='b2c34f11' name='cmd' filepath='drivers/net/phy/phy.c' line='792' column='1'/>
+      <function-decl name='phy_ethtool_ksettings_get' mangled-name='phy_ethtool_ksettings_get' filepath='drivers/net/phy/phy.c' line='280' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_ksettings_get'>
+        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='280' column='1'/>
+        <parameter type-id='70de91e2' name='cmd' filepath='drivers/net/phy/phy.c' line='281' column='1'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
+      <function-decl name='phy_ethtool_ksettings_set' mangled-name='phy_ethtool_ksettings_set' filepath='drivers/net/phy/phy.c' line='803' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_ksettings_set'>
+        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='803' column='1'/>
+        <parameter type-id='b2c34f11' name='cmd' filepath='drivers/net/phy/phy.c' line='804' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='phy_ethtool_nway_reset' mangled-name='phy_ethtool_nway_reset' filepath='drivers/net/phy/phy.c' line='1539' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_nway_reset'>
-        <parameter type-id='68a2d05b' name='ndev' filepath='drivers/net/phy/phy.c' line='1539' column='1'/>
+      <function-decl name='phy_ethtool_nway_reset' mangled-name='phy_ethtool_nway_reset' filepath='drivers/net/phy/phy.c' line='1548' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_nway_reset'>
+        <parameter type-id='68a2d05b' name='ndev' filepath='drivers/net/phy/phy.c' line='1548' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='phy_ethtool_set_eee' mangled-name='phy_ethtool_set_eee' filepath='drivers/net/phy/phy.c' line='1439' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_set_eee'>
-        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1439' column='1'/>
-        <parameter type-id='eced47f6' name='data' filepath='drivers/net/phy/phy.c' line='1439' column='1'/>
+      <function-decl name='phy_ethtool_set_eee' mangled-name='phy_ethtool_set_eee' filepath='drivers/net/phy/phy.c' line='1448' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_set_eee'>
+        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1448' column='1'/>
+        <parameter type-id='eced47f6' name='data' filepath='drivers/net/phy/phy.c' line='1448' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='phy_ethtool_set_link_ksettings' mangled-name='phy_ethtool_set_link_ksettings' filepath='drivers/net/phy/phy.c' line='1523' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_set_link_ksettings'>
-        <parameter type-id='68a2d05b' name='ndev' filepath='drivers/net/phy/phy.c' line='1523' column='1'/>
-        <parameter type-id='b2c34f11' name='cmd' filepath='drivers/net/phy/phy.c' line='1524' column='1'/>
+      <function-decl name='phy_ethtool_set_link_ksettings' mangled-name='phy_ethtool_set_link_ksettings' filepath='drivers/net/phy/phy.c' line='1532' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_set_link_ksettings'>
+        <parameter type-id='68a2d05b' name='ndev' filepath='drivers/net/phy/phy.c' line='1532' column='1'/>
+        <parameter type-id='b2c34f11' name='cmd' filepath='drivers/net/phy/phy.c' line='1533' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='phy_ethtool_set_wol' mangled-name='phy_ethtool_set_wol' filepath='drivers/net/phy/phy.c' line='1487' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_set_wol'>
-        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1487' column='1'/>
-        <parameter type-id='fde1bbcb' name='wol' filepath='drivers/net/phy/phy.c' line='1487' column='1'/>
+      <function-decl name='phy_ethtool_set_wol' mangled-name='phy_ethtool_set_wol' filepath='drivers/net/phy/phy.c' line='1496' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_ethtool_set_wol'>
+        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1496' column='1'/>
+        <parameter type-id='fde1bbcb' name='wol' filepath='drivers/net/phy/phy.c' line='1496' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='phy_exit' mangled-name='phy_exit' filepath='drivers/phy/phy-core.c' line='261' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_exit'>
@@ -138927,8 +139709,8 @@
         <parameter type-id='80f4b756' name='string' filepath='drivers/phy/phy-core.c' line='664' column='1'/>
         <return type-id='503ff1ba'/>
       </function-decl>
-      <function-decl name='phy_get_eee_err' mangled-name='phy_get_eee_err' filepath='drivers/net/phy/phy.c' line='1383' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_get_eee_err'>
-        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1383' column='1'/>
+      <function-decl name='phy_get_eee_err' mangled-name='phy_get_eee_err' filepath='drivers/net/phy/phy.c' line='1392' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_get_eee_err'>
+        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1392' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='phy_get_pause' mangled-name='phy_get_pause' filepath='drivers/net/phy/phy_device.c' line='2693' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_get_pause'>
@@ -138941,23 +139723,23 @@
         <parameter type-id='503ff1ba' name='phy' filepath='drivers/phy/phy-core.c' line='232' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='phy_init_eee' mangled-name='phy_init_eee' filepath='drivers/net/phy/phy.c' line='1315' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_init_eee'>
-        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1315' column='1'/>
-        <parameter type-id='b50a4934' name='clk_stop_enable' filepath='drivers/net/phy/phy.c' line='1315' column='1'/>
+      <function-decl name='phy_init_eee' mangled-name='phy_init_eee' filepath='drivers/net/phy/phy.c' line='1324' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_init_eee'>
+        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1324' column='1'/>
+        <parameter type-id='b50a4934' name='clk_stop_enable' filepath='drivers/net/phy/phy.c' line='1324' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='phy_init_hw' mangled-name='phy_init_hw' filepath='drivers/net/phy/phy_device.c' line='1093' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_init_hw'>
         <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy_device.c' line='1093' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='phy_mac_interrupt' mangled-name='phy_mac_interrupt' filepath='drivers/net/phy/phy.c' line='1274' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_mac_interrupt'>
-        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1274' column='1'/>
+      <function-decl name='phy_mac_interrupt' mangled-name='phy_mac_interrupt' filepath='drivers/net/phy/phy.c' line='1283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_mac_interrupt'>
+        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1283' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='phy_mii_ioctl' mangled-name='phy_mii_ioctl' filepath='drivers/net/phy/phy.c' line='304' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_mii_ioctl'>
-        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='304' column='1'/>
-        <parameter type-id='d494b97c' name='ifr' filepath='drivers/net/phy/phy.c' line='304' column='1'/>
-        <parameter type-id='95e97e5e' name='cmd' filepath='drivers/net/phy/phy.c' line='304' column='1'/>
+      <function-decl name='phy_mii_ioctl' mangled-name='phy_mii_ioctl' filepath='drivers/net/phy/phy.c' line='316' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_mii_ioctl'>
+        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='316' column='1'/>
+        <parameter type-id='d494b97c' name='ifr' filepath='drivers/net/phy/phy.c' line='316' column='1'/>
+        <parameter type-id='95e97e5e' name='cmd' filepath='drivers/net/phy/phy.c' line='316' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='phy_mipi_dphy_config_validate' mangled-name='phy_mipi_dphy_config_validate' filepath='drivers/phy/phy-core-mipi-dphy.c' line='86' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_mipi_dphy_config_validate'>
@@ -139025,8 +139807,8 @@
         <parameter type-id='503ff1ba' name='phy' filepath='drivers/phy/phy-core.c' line='290' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='phy_print_status' mangled-name='phy_print_status' filepath='drivers/net/phy/phy.c' line='101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_print_status'>
-        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='101' column='1'/>
+      <function-decl name='phy_print_status' mangled-name='phy_print_status' filepath='drivers/net/phy/phy.c' line='113' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_print_status'>
+        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='113' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='phy_put' mangled-name='phy_put' filepath='drivers/phy/phy-core.c' line='596' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_put'>
@@ -139106,16 +139888,20 @@
         <parameter type-id='b50a4934' name='autoneg' filepath='drivers/net/phy/phy_device.c' line='2620' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='phy_start' mangled-name='phy_start' filepath='drivers/net/phy/phy.c' line='1154' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_start'>
-        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1154' column='1'/>
+      <function-decl name='phy_start' mangled-name='phy_start' filepath='drivers/net/phy/phy.c' line='1169' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_start'>
+        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1169' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='phy_start_aneg' mangled-name='phy_start_aneg' filepath='drivers/net/phy/phy.c' line='763' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_start_aneg'>
-        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='763' column='1'/>
+      <function-decl name='phy_start_aneg' mangled-name='phy_start_aneg' filepath='drivers/net/phy/phy.c' line='775' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_start_aneg'>
+        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='775' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='phy_stop' mangled-name='phy_stop' filepath='drivers/net/phy/phy.c' line='1110' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_stop'>
-        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1110' column='1'/>
+      <function-decl name='phy_stop' mangled-name='phy_stop' filepath='drivers/net/phy/phy.c' line='1122' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_stop'>
+        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy.c' line='1122' column='1'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
+      <function-decl name='phy_support_asym_pause' mangled-name='phy_support_asym_pause' filepath='drivers/net/phy/phy_device.c' line='2602' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_support_asym_pause'>
+        <parameter type-id='7efbcaaf' name='phydev' filepath='drivers/net/phy/phy_device.c' line='2602' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='phy_support_sym_pause' mangled-name='phy_support_sym_pause' filepath='drivers/net/phy/phy_device.c' line='2589' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='phy_support_sym_pause'>
@@ -139258,9 +140044,9 @@
         <parameter type-id='56f3c6ca' name='pl' filepath='drivers/net/phy/phylink.c' line='1279' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pick_highest_pushable_task' mangled-name='pick_highest_pushable_task' filepath='kernel/sched/rt.c' line='1772' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pick_highest_pushable_task'>
-        <parameter type-id='6ed6b432' name='rq' filepath='kernel/sched/rt.c' line='1772' column='1'/>
-        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/sched/rt.c' line='1772' column='1'/>
+      <function-decl name='pick_highest_pushable_task' mangled-name='pick_highest_pushable_task' filepath='kernel/sched/rt.c' line='1774' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pick_highest_pushable_task'>
+        <parameter type-id='6ed6b432' name='rq' filepath='kernel/sched/rt.c' line='1774' column='1'/>
+        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/sched/rt.c' line='1774' column='1'/>
         <return type-id='f23e2572'/>
       </function-decl>
       <function-decl name='pid_nr_ns' mangled-name='pid_nr_ns' filepath='kernel/pid.c' line='473' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pid_nr_ns'>
@@ -139303,10 +140089,10 @@
         <parameter type-id='7292109c' name='locked' filepath='mm/gup.c' line='2930' column='1'/>
         <return type-id='bd54fe1a'/>
       </function-decl>
-      <function-decl name='pinconf_generic_dt_free_map' mangled-name='pinconf_generic_dt_free_map' filepath='drivers/pinctrl/pinconf-generic.c' line='407' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pinconf_generic_dt_free_map'>
-        <parameter type-id='10216dc5' name='pctldev' filepath='drivers/pinctrl/pinconf-generic.c' line='407' column='1'/>
-        <parameter type-id='9638d26e' name='map' filepath='drivers/pinctrl/pinconf-generic.c' line='408' column='1'/>
-        <parameter type-id='f0981eeb' name='num_maps' filepath='drivers/pinctrl/pinconf-generic.c' line='409' column='1'/>
+      <function-decl name='pinconf_generic_dt_free_map' mangled-name='pinconf_generic_dt_free_map' filepath='drivers/pinctrl/pinconf-generic.c' line='409' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pinconf_generic_dt_free_map'>
+        <parameter type-id='10216dc5' name='pctldev' filepath='drivers/pinctrl/pinconf-generic.c' line='409' column='1'/>
+        <parameter type-id='9638d26e' name='map' filepath='drivers/pinctrl/pinconf-generic.c' line='410' column='1'/>
+        <parameter type-id='f0981eeb' name='num_maps' filepath='drivers/pinctrl/pinconf-generic.c' line='411' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='pinconf_generic_dt_node_to_map' mangled-name='pinconf_generic_dt_node_to_map' filepath='drivers/pinctrl/pinconf-generic.c' line='376' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pinconf_generic_dt_node_to_map'>
@@ -139721,50 +140507,50 @@
         <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/wakeup.c' line='777' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pm_runtime_allow' mangled-name='pm_runtime_allow' filepath='drivers/base/power/runtime.c' line='1499' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_allow'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1499' column='1'/>
+      <function-decl name='pm_runtime_allow' mangled-name='pm_runtime_allow' filepath='drivers/base/power/runtime.c' line='1509' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_allow'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1509' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='pm_runtime_autosuspend_expiration' mangled-name='pm_runtime_autosuspend_expiration' filepath='drivers/base/power/runtime.c' line='163' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_autosuspend_expiration'>
         <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='163' column='1'/>
         <return type-id='91ce1af9'/>
       </function-decl>
-      <function-decl name='pm_runtime_barrier' mangled-name='pm_runtime_barrier' filepath='drivers/base/power/runtime.c' line='1365' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_barrier'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1365' column='1'/>
+      <function-decl name='pm_runtime_barrier' mangled-name='pm_runtime_barrier' filepath='drivers/base/power/runtime.c' line='1375' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_barrier'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1375' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pm_runtime_enable' mangled-name='pm_runtime_enable' filepath='drivers/base/power/runtime.c' line='1443' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_enable'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1443' column='1'/>
+      <function-decl name='pm_runtime_enable' mangled-name='pm_runtime_enable' filepath='drivers/base/power/runtime.c' line='1453' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_enable'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1453' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pm_runtime_forbid' mangled-name='pm_runtime_forbid' filepath='drivers/base/power/runtime.c' line='1478' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_forbid'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1478' column='1'/>
+      <function-decl name='pm_runtime_forbid' mangled-name='pm_runtime_forbid' filepath='drivers/base/power/runtime.c' line='1488' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_forbid'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1488' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pm_runtime_force_resume' mangled-name='pm_runtime_force_resume' filepath='drivers/base/power/runtime.c' line='1852' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_force_resume'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1852' column='1'/>
+      <function-decl name='pm_runtime_force_resume' mangled-name='pm_runtime_force_resume' filepath='drivers/base/power/runtime.c' line='1862' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_force_resume'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1862' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pm_runtime_force_suspend' mangled-name='pm_runtime_force_suspend' filepath='drivers/base/power/runtime.c' line='1804' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_force_suspend'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1804' column='1'/>
+      <function-decl name='pm_runtime_force_suspend' mangled-name='pm_runtime_force_suspend' filepath='drivers/base/power/runtime.c' line='1814' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_force_suspend'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1814' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pm_runtime_get_if_active' mangled-name='pm_runtime_get_if_active' filepath='drivers/base/power/runtime.c' line='1157' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_get_if_active'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1157' column='1'/>
-        <parameter type-id='b50a4934' name='ign_usage_count' filepath='drivers/base/power/runtime.c' line='1157' column='1'/>
+      <function-decl name='pm_runtime_get_if_active' mangled-name='pm_runtime_get_if_active' filepath='drivers/base/power/runtime.c' line='1167' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_get_if_active'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1167' column='1'/>
+        <parameter type-id='b50a4934' name='ign_usage_count' filepath='drivers/base/power/runtime.c' line='1167' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pm_runtime_irq_safe' mangled-name='pm_runtime_irq_safe' filepath='drivers/base/power/runtime.c' line='1545' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_irq_safe'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1545' column='1'/>
+      <function-decl name='pm_runtime_irq_safe' mangled-name='pm_runtime_irq_safe' filepath='drivers/base/power/runtime.c' line='1555' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_irq_safe'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1555' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pm_runtime_no_callbacks' mangled-name='pm_runtime_no_callbacks' filepath='drivers/base/power/runtime.c' line='1524' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_no_callbacks'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1524' column='1'/>
+      <function-decl name='pm_runtime_no_callbacks' mangled-name='pm_runtime_no_callbacks' filepath='drivers/base/power/runtime.c' line='1534' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_no_callbacks'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1534' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='pm_runtime_set_autosuspend_delay' mangled-name='pm_runtime_set_autosuspend_delay' filepath='drivers/base/power/runtime.c' line='1603' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_set_autosuspend_delay'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1603' column='1'/>
-        <parameter type-id='95e97e5e' name='delay' filepath='drivers/base/power/runtime.c' line='1603' column='1'/>
+      <function-decl name='pm_runtime_set_autosuspend_delay' mangled-name='pm_runtime_set_autosuspend_delay' filepath='drivers/base/power/runtime.c' line='1613' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_runtime_set_autosuspend_delay'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/base/power/runtime.c' line='1613' column='1'/>
+        <parameter type-id='95e97e5e' name='delay' filepath='drivers/base/power/runtime.c' line='1613' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='pm_stay_awake' mangled-name='pm_stay_awake' filepath='drivers/base/power/wakeup.c' line='668' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pm_stay_awake'>
@@ -139828,95 +140614,95 @@
         <return type-id='48b5725f'/>
       </function-decl>
       <var-decl name='power_supply_class' type-id='67aca04f' mangled-name='power_supply_class' visibility='default' filepath='drivers/power/supply/power_supply_core.c' line='27' column='1' elf-symbol-id='power_supply_class'/>
-      <function-decl name='power_supply_find_ocv2cap_table' mangled-name='power_supply_find_ocv2cap_table' filepath='drivers/power/supply/power_supply_core.c' line='909' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_find_ocv2cap_table'>
-        <parameter type-id='78ba63ff' name='info' filepath='drivers/power/supply/power_supply_core.c' line='909' column='1'/>
-        <parameter type-id='95e97e5e' name='temp' filepath='drivers/power/supply/power_supply_core.c' line='910' column='1'/>
-        <parameter type-id='7292109c' name='table_len' filepath='drivers/power/supply/power_supply_core.c' line='910' column='1'/>
+      <function-decl name='power_supply_find_ocv2cap_table' mangled-name='power_supply_find_ocv2cap_table' filepath='drivers/power/supply/power_supply_core.c' line='921' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_find_ocv2cap_table'>
+        <parameter type-id='78ba63ff' name='info' filepath='drivers/power/supply/power_supply_core.c' line='921' column='1'/>
+        <parameter type-id='95e97e5e' name='temp' filepath='drivers/power/supply/power_supply_core.c' line='922' column='1'/>
+        <parameter type-id='7292109c' name='table_len' filepath='drivers/power/supply/power_supply_core.c' line='922' column='1'/>
         <return type-id='be6833bc'/>
       </function-decl>
-      <function-decl name='power_supply_get_battery_info' mangled-name='power_supply_get_battery_info' filepath='drivers/power/supply/power_supply_core.c' line='647' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_get_battery_info'>
-        <parameter type-id='c0c93c9e' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='647' column='1'/>
-        <parameter type-id='78ba63ff' name='info' filepath='drivers/power/supply/power_supply_core.c' line='648' column='1'/>
+      <function-decl name='power_supply_get_battery_info' mangled-name='power_supply_get_battery_info' filepath='drivers/power/supply/power_supply_core.c' line='654' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_get_battery_info'>
+        <parameter type-id='c0c93c9e' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='654' column='1'/>
+        <parameter type-id='78ba63ff' name='info' filepath='drivers/power/supply/power_supply_core.c' line='655' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='power_supply_get_by_name' mangled-name='power_supply_get_by_name' filepath='drivers/power/supply/power_supply_core.c' line='462' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_get_by_name'>
-        <parameter type-id='80f4b756' name='name' filepath='drivers/power/supply/power_supply_core.c' line='462' column='1'/>
+      <function-decl name='power_supply_get_by_name' mangled-name='power_supply_get_by_name' filepath='drivers/power/supply/power_supply_core.c' line='469' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_get_by_name'>
+        <parameter type-id='80f4b756' name='name' filepath='drivers/power/supply/power_supply_core.c' line='469' column='1'/>
         <return type-id='c0c93c9e'/>
       </function-decl>
-      <function-decl name='power_supply_get_by_phandle' mangled-name='power_supply_get_by_phandle' filepath='drivers/power/supply/power_supply_core.c' line='511' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_get_by_phandle'>
-        <parameter type-id='9a537bbe' name='np' filepath='drivers/power/supply/power_supply_core.c' line='511' column='1'/>
-        <parameter type-id='80f4b756' name='property' filepath='drivers/power/supply/power_supply_core.c' line='512' column='1'/>
+      <function-decl name='power_supply_get_by_phandle' mangled-name='power_supply_get_by_phandle' filepath='drivers/power/supply/power_supply_core.c' line='518' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_get_by_phandle'>
+        <parameter type-id='9a537bbe' name='np' filepath='drivers/power/supply/power_supply_core.c' line='518' column='1'/>
+        <parameter type-id='80f4b756' name='property' filepath='drivers/power/supply/power_supply_core.c' line='519' column='1'/>
         <return type-id='c0c93c9e'/>
       </function-decl>
-      <function-decl name='power_supply_get_by_phandle_array' mangled-name='power_supply_get_by_phandle_array' filepath='drivers/power/supply/power_supply_core.c' line='578' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_get_by_phandle_array'>
-        <parameter type-id='9a537bbe' name='np' filepath='drivers/power/supply/power_supply_core.c' line='578' column='1'/>
-        <parameter type-id='80f4b756' name='property' filepath='drivers/power/supply/power_supply_core.c' line='579' column='1'/>
-        <parameter type-id='30ca8f5c' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='580' column='1'/>
-        <parameter type-id='79a0948f' name='size' filepath='drivers/power/supply/power_supply_core.c' line='581' column='1'/>
+      <function-decl name='power_supply_get_by_phandle_array' mangled-name='power_supply_get_by_phandle_array' filepath='drivers/power/supply/power_supply_core.c' line='585' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_get_by_phandle_array'>
+        <parameter type-id='9a537bbe' name='np' filepath='drivers/power/supply/power_supply_core.c' line='585' column='1'/>
+        <parameter type-id='80f4b756' name='property' filepath='drivers/power/supply/power_supply_core.c' line='586' column='1'/>
+        <parameter type-id='30ca8f5c' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='587' column='1'/>
+        <parameter type-id='79a0948f' name='size' filepath='drivers/power/supply/power_supply_core.c' line='588' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='power_supply_get_drvdata' mangled-name='power_supply_get_drvdata' filepath='drivers/power/supply/power_supply_core.c' line='1442' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_get_drvdata'>
-        <parameter type-id='c0c93c9e' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='1442' column='1'/>
+      <function-decl name='power_supply_get_drvdata' mangled-name='power_supply_get_drvdata' filepath='drivers/power/supply/power_supply_core.c' line='1454' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_get_drvdata'>
+        <parameter type-id='c0c93c9e' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='1454' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='power_supply_get_property' mangled-name='power_supply_get_property' filepath='drivers/power/supply/power_supply_core.c' line='950' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_get_property'>
-        <parameter type-id='c0c93c9e' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='950' column='1'/>
-        <parameter type-id='5f78aa17' name='psp' filepath='drivers/power/supply/power_supply_core.c' line='951' column='1'/>
-        <parameter type-id='2e53d20f' name='val' filepath='drivers/power/supply/power_supply_core.c' line='952' column='1'/>
+      <function-decl name='power_supply_get_property' mangled-name='power_supply_get_property' filepath='drivers/power/supply/power_supply_core.c' line='962' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_get_property'>
+        <parameter type-id='c0c93c9e' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='962' column='1'/>
+        <parameter type-id='5f78aa17' name='psp' filepath='drivers/power/supply/power_supply_core.c' line='963' column='1'/>
+        <parameter type-id='2e53d20f' name='val' filepath='drivers/power/supply/power_supply_core.c' line='964' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='power_supply_is_system_supplied' mangled-name='power_supply_is_system_supplied' filepath='drivers/power/supply/power_supply_core.c' line='370' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_is_system_supplied'>
+      <function-decl name='power_supply_is_system_supplied' mangled-name='power_supply_is_system_supplied' filepath='drivers/power/supply/power_supply_core.c' line='374' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_is_system_supplied'>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='power_supply_ocv2cap_simple' mangled-name='power_supply_ocv2cap_simple' filepath='drivers/power/supply/power_supply_core.c' line='884' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_ocv2cap_simple'>
-        <parameter type-id='be6833bc' name='table' filepath='drivers/power/supply/power_supply_core.c' line='884' column='1'/>
-        <parameter type-id='95e97e5e' name='table_len' filepath='drivers/power/supply/power_supply_core.c' line='885' column='1'/>
-        <parameter type-id='95e97e5e' name='ocv' filepath='drivers/power/supply/power_supply_core.c' line='885' column='1'/>
+      <function-decl name='power_supply_ocv2cap_simple' mangled-name='power_supply_ocv2cap_simple' filepath='drivers/power/supply/power_supply_core.c' line='896' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_ocv2cap_simple'>
+        <parameter type-id='be6833bc' name='table' filepath='drivers/power/supply/power_supply_core.c' line='896' column='1'/>
+        <parameter type-id='95e97e5e' name='table_len' filepath='drivers/power/supply/power_supply_core.c' line='897' column='1'/>
+        <parameter type-id='95e97e5e' name='ocv' filepath='drivers/power/supply/power_supply_core.c' line='897' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='power_supply_put' mangled-name='power_supply_put' filepath='drivers/power/supply/power_supply_core.c' line='484' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_put'>
-        <parameter type-id='c0c93c9e' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='484' column='1'/>
+      <function-decl name='power_supply_put' mangled-name='power_supply_put' filepath='drivers/power/supply/power_supply_core.c' line='491' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_put'>
+        <parameter type-id='c0c93c9e' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='491' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='power_supply_put_battery_info' mangled-name='power_supply_put_battery_info' filepath='drivers/power/supply/power_supply_core.c' line='817' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_put_battery_info'>
-        <parameter type-id='c0c93c9e' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='817' column='1'/>
-        <parameter type-id='78ba63ff' name='info' filepath='drivers/power/supply/power_supply_core.c' line='818' column='1'/>
+      <function-decl name='power_supply_put_battery_info' mangled-name='power_supply_put_battery_info' filepath='drivers/power/supply/power_supply_core.c' line='829' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_put_battery_info'>
+        <parameter type-id='c0c93c9e' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='829' column='1'/>
+        <parameter type-id='78ba63ff' name='info' filepath='drivers/power/supply/power_supply_core.c' line='830' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='power_supply_reg_notifier' mangled-name='power_supply_reg_notifier' filepath='drivers/power/supply/power_supply_core.c' line='1009' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_reg_notifier'>
-        <parameter type-id='d504f73d' name='nb' filepath='drivers/power/supply/power_supply_core.c' line='1009' column='1'/>
+      <function-decl name='power_supply_reg_notifier' mangled-name='power_supply_reg_notifier' filepath='drivers/power/supply/power_supply_core.c' line='1021' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_reg_notifier'>
+        <parameter type-id='d504f73d' name='nb' filepath='drivers/power/supply/power_supply_core.c' line='1021' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='power_supply_register' mangled-name='power_supply_register' filepath='drivers/power/supply/power_supply_core.c' line='1309' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_register'>
-        <parameter type-id='fa0b179b' name='parent' filepath='drivers/power/supply/power_supply_core.c' line='1309' column='1'/>
-        <parameter type-id='cb9cd99f' name='desc' filepath='drivers/power/supply/power_supply_core.c' line='1310' column='1'/>
-        <parameter type-id='048b3ad6' name='cfg' filepath='drivers/power/supply/power_supply_core.c' line='1311' column='1'/>
+      <function-decl name='power_supply_register' mangled-name='power_supply_register' filepath='drivers/power/supply/power_supply_core.c' line='1321' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_register'>
+        <parameter type-id='fa0b179b' name='parent' filepath='drivers/power/supply/power_supply_core.c' line='1321' column='1'/>
+        <parameter type-id='cb9cd99f' name='desc' filepath='drivers/power/supply/power_supply_core.c' line='1322' column='1'/>
+        <parameter type-id='048b3ad6' name='cfg' filepath='drivers/power/supply/power_supply_core.c' line='1323' column='1'/>
         <return type-id='c0c93c9e'/>
       </function-decl>
-      <function-decl name='power_supply_register_no_ws' mangled-name='power_supply_register_no_ws' filepath='drivers/power/supply/power_supply_core.c' line='1332' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_register_no_ws'>
-        <parameter type-id='fa0b179b' name='parent' filepath='drivers/power/supply/power_supply_core.c' line='1332' column='1'/>
-        <parameter type-id='cb9cd99f' name='desc' filepath='drivers/power/supply/power_supply_core.c' line='1333' column='1'/>
-        <parameter type-id='048b3ad6' name='cfg' filepath='drivers/power/supply/power_supply_core.c' line='1334' column='1'/>
+      <function-decl name='power_supply_register_no_ws' mangled-name='power_supply_register_no_ws' filepath='drivers/power/supply/power_supply_core.c' line='1344' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_register_no_ws'>
+        <parameter type-id='fa0b179b' name='parent' filepath='drivers/power/supply/power_supply_core.c' line='1344' column='1'/>
+        <parameter type-id='cb9cd99f' name='desc' filepath='drivers/power/supply/power_supply_core.c' line='1345' column='1'/>
+        <parameter type-id='048b3ad6' name='cfg' filepath='drivers/power/supply/power_supply_core.c' line='1346' column='1'/>
         <return type-id='c0c93c9e'/>
       </function-decl>
-      <function-decl name='power_supply_set_property' mangled-name='power_supply_set_property' filepath='drivers/power/supply/power_supply_core.c' line='964' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_set_property'>
-        <parameter type-id='c0c93c9e' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='964' column='1'/>
-        <parameter type-id='5f78aa17' name='psp' filepath='drivers/power/supply/power_supply_core.c' line='965' column='1'/>
-        <parameter type-id='f3abafd4' name='val' filepath='drivers/power/supply/power_supply_core.c' line='966' column='1'/>
+      <function-decl name='power_supply_set_property' mangled-name='power_supply_set_property' filepath='drivers/power/supply/power_supply_core.c' line='976' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_set_property'>
+        <parameter type-id='c0c93c9e' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='976' column='1'/>
+        <parameter type-id='5f78aa17' name='psp' filepath='drivers/power/supply/power_supply_core.c' line='977' column='1'/>
+        <parameter type-id='f3abafd4' name='val' filepath='drivers/power/supply/power_supply_core.c' line='978' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='power_supply_temp2resist_simple' mangled-name='power_supply_temp2resist_simple' filepath='drivers/power/supply/power_supply_core.c' line='846' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_temp2resist_simple'>
-        <parameter type-id='1fba25e2' name='table' filepath='drivers/power/supply/power_supply_core.c' line='846' column='1'/>
-        <parameter type-id='95e97e5e' name='table_len' filepath='drivers/power/supply/power_supply_core.c' line='847' column='1'/>
-        <parameter type-id='95e97e5e' name='temp' filepath='drivers/power/supply/power_supply_core.c' line='847' column='1'/>
+      <function-decl name='power_supply_temp2resist_simple' mangled-name='power_supply_temp2resist_simple' filepath='drivers/power/supply/power_supply_core.c' line='858' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_temp2resist_simple'>
+        <parameter type-id='1fba25e2' name='table' filepath='drivers/power/supply/power_supply_core.c' line='858' column='1'/>
+        <parameter type-id='95e97e5e' name='table_len' filepath='drivers/power/supply/power_supply_core.c' line='859' column='1'/>
+        <parameter type-id='95e97e5e' name='temp' filepath='drivers/power/supply/power_supply_core.c' line='859' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='power_supply_unreg_notifier' mangled-name='power_supply_unreg_notifier' filepath='drivers/power/supply/power_supply_core.c' line='1015' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_unreg_notifier'>
-        <parameter type-id='d504f73d' name='nb' filepath='drivers/power/supply/power_supply_core.c' line='1015' column='1'/>
+      <function-decl name='power_supply_unreg_notifier' mangled-name='power_supply_unreg_notifier' filepath='drivers/power/supply/power_supply_core.c' line='1027' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_unreg_notifier'>
+        <parameter type-id='d504f73d' name='nb' filepath='drivers/power/supply/power_supply_core.c' line='1027' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='power_supply_unregister' mangled-name='power_supply_unregister' filepath='drivers/power/supply/power_supply_core.c' line='1426' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_unregister'>
-        <parameter type-id='c0c93c9e' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='1426' column='1'/>
+      <function-decl name='power_supply_unregister' mangled-name='power_supply_unregister' filepath='drivers/power/supply/power_supply_core.c' line='1438' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='power_supply_unregister'>
+        <parameter type-id='c0c93c9e' name='psy' filepath='drivers/power/supply/power_supply_core.c' line='1438' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='prandom_bytes' mangled-name='prandom_bytes' filepath='lib/random32.c' line='400' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='prandom_bytes'>
@@ -139927,10 +140713,10 @@
       <function-decl name='prandom_u32' mangled-name='prandom_u32' filepath='lib/random32.c' line='385' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='prandom_u32'>
         <return type-id='19c2251e'/>
       </function-decl>
-      <function-decl name='preempt_schedule' mangled-name='preempt_schedule' filepath='kernel/sched/core.c' line='4971' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='preempt_schedule'>
+      <function-decl name='preempt_schedule' mangled-name='preempt_schedule' filepath='kernel/sched/core.c' line='4973' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='preempt_schedule'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='preempt_schedule_notrace' mangled-name='preempt_schedule_notrace' filepath='kernel/sched/core.c' line='4999' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='preempt_schedule_notrace'>
+      <function-decl name='preempt_schedule_notrace' mangled-name='preempt_schedule_notrace' filepath='kernel/sched/core.c' line='5001' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='preempt_schedule_notrace'>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='prepare_to_wait' mangled-name='prepare_to_wait' filepath='kernel/sched/wait.c' line='250' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='prepare_to_wait'>
@@ -140009,36 +140795,36 @@
         <parameter type-id='eaa32e2f' name='data' filepath='fs/proc/generic.c' line='654' column='1'/>
         <return type-id='d077e928'/>
       </function-decl>
-      <function-decl name='proc_dointvec' mangled-name='proc_dointvec' filepath='kernel/sysctl.c' line='830' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='proc_dointvec'>
-        <parameter type-id='631dc3c1' name='table' filepath='kernel/sysctl.c' line='830' column='1'/>
-        <parameter type-id='95e97e5e' name='write' filepath='kernel/sysctl.c' line='830' column='1'/>
-        <parameter type-id='eaa32e2f' name='buffer' filepath='kernel/sysctl.c' line='830' column='1'/>
-        <parameter type-id='78c01427' name='lenp' filepath='kernel/sysctl.c' line='831' column='1'/>
-        <parameter type-id='b53e8dbb' name='ppos' filepath='kernel/sysctl.c' line='831' column='1'/>
+      <function-decl name='proc_dointvec' mangled-name='proc_dointvec' filepath='kernel/sysctl.c' line='824' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='proc_dointvec'>
+        <parameter type-id='631dc3c1' name='table' filepath='kernel/sysctl.c' line='824' column='1'/>
+        <parameter type-id='95e97e5e' name='write' filepath='kernel/sysctl.c' line='824' column='1'/>
+        <parameter type-id='eaa32e2f' name='buffer' filepath='kernel/sysctl.c' line='824' column='1'/>
+        <parameter type-id='78c01427' name='lenp' filepath='kernel/sysctl.c' line='825' column='1'/>
+        <parameter type-id='b53e8dbb' name='ppos' filepath='kernel/sysctl.c' line='825' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='proc_dointvec_minmax' mangled-name='proc_dointvec_minmax' filepath='kernel/sysctl.c' line='987' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='proc_dointvec_minmax'>
-        <parameter type-id='631dc3c1' name='table' filepath='kernel/sysctl.c' line='987' column='1'/>
-        <parameter type-id='95e97e5e' name='write' filepath='kernel/sysctl.c' line='987' column='1'/>
-        <parameter type-id='eaa32e2f' name='buffer' filepath='kernel/sysctl.c' line='988' column='1'/>
-        <parameter type-id='78c01427' name='lenp' filepath='kernel/sysctl.c' line='988' column='1'/>
-        <parameter type-id='b53e8dbb' name='ppos' filepath='kernel/sysctl.c' line='988' column='1'/>
+      <function-decl name='proc_dointvec_minmax' mangled-name='proc_dointvec_minmax' filepath='kernel/sysctl.c' line='981' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='proc_dointvec_minmax'>
+        <parameter type-id='631dc3c1' name='table' filepath='kernel/sysctl.c' line='981' column='1'/>
+        <parameter type-id='95e97e5e' name='write' filepath='kernel/sysctl.c' line='981' column='1'/>
+        <parameter type-id='eaa32e2f' name='buffer' filepath='kernel/sysctl.c' line='982' column='1'/>
+        <parameter type-id='78c01427' name='lenp' filepath='kernel/sysctl.c' line='982' column='1'/>
+        <parameter type-id='b53e8dbb' name='ppos' filepath='kernel/sysctl.c' line='982' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='proc_dostring' mangled-name='proc_dostring' filepath='kernel/sysctl.c' line='387' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='proc_dostring'>
-        <parameter type-id='631dc3c1' name='table' filepath='kernel/sysctl.c' line='387' column='1'/>
-        <parameter type-id='95e97e5e' name='write' filepath='kernel/sysctl.c' line='387' column='1'/>
-        <parameter type-id='eaa32e2f' name='buffer' filepath='kernel/sysctl.c' line='388' column='1'/>
-        <parameter type-id='78c01427' name='lenp' filepath='kernel/sysctl.c' line='388' column='1'/>
-        <parameter type-id='b53e8dbb' name='ppos' filepath='kernel/sysctl.c' line='388' column='1'/>
+      <function-decl name='proc_dostring' mangled-name='proc_dostring' filepath='kernel/sysctl.c' line='381' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='proc_dostring'>
+        <parameter type-id='631dc3c1' name='table' filepath='kernel/sysctl.c' line='381' column='1'/>
+        <parameter type-id='95e97e5e' name='write' filepath='kernel/sysctl.c' line='381' column='1'/>
+        <parameter type-id='eaa32e2f' name='buffer' filepath='kernel/sysctl.c' line='382' column='1'/>
+        <parameter type-id='78c01427' name='lenp' filepath='kernel/sysctl.c' line='382' column='1'/>
+        <parameter type-id='b53e8dbb' name='ppos' filepath='kernel/sysctl.c' line='382' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='proc_douintvec_minmax' mangled-name='proc_douintvec_minmax' filepath='kernel/sysctl.c' line='1056' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='proc_douintvec_minmax'>
-        <parameter type-id='631dc3c1' name='table' filepath='kernel/sysctl.c' line='1056' column='1'/>
-        <parameter type-id='95e97e5e' name='write' filepath='kernel/sysctl.c' line='1056' column='1'/>
-        <parameter type-id='eaa32e2f' name='buffer' filepath='kernel/sysctl.c' line='1057' column='1'/>
-        <parameter type-id='78c01427' name='lenp' filepath='kernel/sysctl.c' line='1057' column='1'/>
-        <parameter type-id='b53e8dbb' name='ppos' filepath='kernel/sysctl.c' line='1057' column='1'/>
+      <function-decl name='proc_douintvec_minmax' mangled-name='proc_douintvec_minmax' filepath='kernel/sysctl.c' line='1050' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='proc_douintvec_minmax'>
+        <parameter type-id='631dc3c1' name='table' filepath='kernel/sysctl.c' line='1050' column='1'/>
+        <parameter type-id='95e97e5e' name='write' filepath='kernel/sysctl.c' line='1050' column='1'/>
+        <parameter type-id='eaa32e2f' name='buffer' filepath='kernel/sysctl.c' line='1051' column='1'/>
+        <parameter type-id='78c01427' name='lenp' filepath='kernel/sysctl.c' line='1051' column='1'/>
+        <parameter type-id='b53e8dbb' name='ppos' filepath='kernel/sysctl.c' line='1051' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='proc_mkdir' mangled-name='proc_mkdir' filepath='fs/proc/generic.c' line='523' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='proc_mkdir'>
@@ -140084,13 +140870,13 @@
         <parameter type-id='d504f73d' name='n' filepath='kernel/profile.c' line='197' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='proto_register' mangled-name='proto_register' filepath='net/core/sock.c' line='3482' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='proto_register'>
-        <parameter type-id='d2524501' name='prot' filepath='net/core/sock.c' line='3482' column='1'/>
-        <parameter type-id='95e97e5e' name='alloc_slab' filepath='net/core/sock.c' line='3482' column='1'/>
+      <function-decl name='proto_register' mangled-name='proto_register' filepath='net/core/sock.c' line='3509' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='proto_register'>
+        <parameter type-id='d2524501' name='prot' filepath='net/core/sock.c' line='3509' column='1'/>
+        <parameter type-id='95e97e5e' name='alloc_slab' filepath='net/core/sock.c' line='3509' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='proto_unregister' mangled-name='proto_unregister' filepath='net/core/sock.c' line='3546' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='proto_unregister'>
-        <parameter type-id='d2524501' name='prot' filepath='net/core/sock.c' line='3546' column='1'/>
+      <function-decl name='proto_unregister' mangled-name='proto_unregister' filepath='net/core/sock.c' line='3573' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='proto_unregister'>
+        <parameter type-id='d2524501' name='prot' filepath='net/core/sock.c' line='3573' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='ps2_begin_command' mangled-name='ps2_begin_command' filepath='drivers/input/serio/libps2.c' line='101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ps2_begin_command'>
@@ -140143,11 +140929,11 @@
         <parameter type-id='f9b06939' name='command' filepath='drivers/input/serio/libps2.c' line='347' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='pskb_expand_head' mangled-name='pskb_expand_head' filepath='net/core/skbuff.c' line='1623' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pskb_expand_head'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1623' column='1'/>
-        <parameter type-id='95e97e5e' name='nhead' filepath='net/core/skbuff.c' line='1623' column='1'/>
-        <parameter type-id='95e97e5e' name='ntail' filepath='net/core/skbuff.c' line='1623' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='1624' column='1'/>
+      <function-decl name='pskb_expand_head' mangled-name='pskb_expand_head' filepath='net/core/skbuff.c' line='1622' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pskb_expand_head'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1622' column='1'/>
+        <parameter type-id='95e97e5e' name='nhead' filepath='net/core/skbuff.c' line='1622' column='1'/>
+        <parameter type-id='95e97e5e' name='ntail' filepath='net/core/skbuff.c' line='1622' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='1623' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='pstore_register' mangled-name='pstore_register' filepath='fs/pstore/platform.c' line='561' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pstore_register'>
@@ -140192,12 +140978,12 @@
         <parameter type-id='f23e2572' name='tsk' filepath='kernel/fork.c' line='441' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='put_tty_driver' mangled-name='put_tty_driver' filepath='drivers/tty/tty_io.c' line='3397' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='put_tty_driver'>
-        <parameter type-id='c2b4b27b' name='d' filepath='drivers/tty/tty_io.c' line='3397' column='1'/>
+      <function-decl name='put_tty_driver' mangled-name='put_tty_driver' filepath='drivers/tty/tty_io.c' line='3400' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='put_tty_driver'>
+        <parameter type-id='c2b4b27b' name='d' filepath='drivers/tty/tty_io.c' line='3400' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='put_unused_fd' mangled-name='put_unused_fd' filepath='fs/file.c' line='604' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='put_unused_fd'>
-        <parameter type-id='f0981eeb' name='fd' filepath='fs/file.c' line='604' column='1'/>
+      <function-decl name='put_unused_fd' mangled-name='put_unused_fd' filepath='fs/file.c' line='606' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='put_unused_fd'>
+        <parameter type-id='f0981eeb' name='fd' filepath='fs/file.c' line='606' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='put_vaddr_frames' mangled-name='put_vaddr_frames' filepath='mm/frame_vector.c' line='104' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='put_vaddr_frames'>
@@ -140269,17 +141055,17 @@
         <parameter type-id='ee406209' name='qdisc' filepath='net/sched/sch_generic.c' line='943' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='queue_delayed_work_on' mangled-name='queue_delayed_work_on' filepath='kernel/workqueue.c' line='1693' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='queue_delayed_work_on'>
-        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/workqueue.c' line='1693' column='1'/>
-        <parameter type-id='242e3d19' name='wq' filepath='kernel/workqueue.c' line='1693' column='1'/>
-        <parameter type-id='1a7ee447' name='dwork' filepath='kernel/workqueue.c' line='1694' column='1'/>
-        <parameter type-id='7359adad' name='delay' filepath='kernel/workqueue.c' line='1694' column='1'/>
+      <function-decl name='queue_delayed_work_on' mangled-name='queue_delayed_work_on' filepath='kernel/workqueue.c' line='1696' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='queue_delayed_work_on'>
+        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/workqueue.c' line='1696' column='1'/>
+        <parameter type-id='242e3d19' name='wq' filepath='kernel/workqueue.c' line='1696' column='1'/>
+        <parameter type-id='1a7ee447' name='dwork' filepath='kernel/workqueue.c' line='1697' column='1'/>
+        <parameter type-id='7359adad' name='delay' filepath='kernel/workqueue.c' line='1697' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='queue_work_on' mangled-name='queue_work_on' filepath='kernel/workqueue.c' line='1532' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='queue_work_on'>
-        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/workqueue.c' line='1532' column='1'/>
-        <parameter type-id='242e3d19' name='wq' filepath='kernel/workqueue.c' line='1532' column='1'/>
-        <parameter type-id='83c1bde6' name='work' filepath='kernel/workqueue.c' line='1533' column='1'/>
+      <function-decl name='queue_work_on' mangled-name='queue_work_on' filepath='kernel/workqueue.c' line='1535' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='queue_work_on'>
+        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/workqueue.c' line='1535' column='1'/>
+        <parameter type-id='242e3d19' name='wq' filepath='kernel/workqueue.c' line='1535' column='1'/>
+        <parameter type-id='83c1bde6' name='work' filepath='kernel/workqueue.c' line='1536' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='radix_tree_delete' mangled-name='radix_tree_delete' filepath='lib/radix-tree.c' line='1443' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='radix_tree_delete'>
@@ -140417,13 +141203,13 @@
         <parameter type-id='c5bcc2c0' name='root' filepath='lib/rbtree.c' line='554' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='rcu_barrier' mangled-name='rcu_barrier' filepath='kernel/rcu/tree.c' line='3842' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_barrier'>
+      <function-decl name='rcu_barrier' mangled-name='rcu_barrier' filepath='kernel/rcu/tree.c' line='3871' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_barrier'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='rcu_barrier_tasks' mangled-name='rcu_barrier_tasks' filepath='kernel/rcu/tasks.h' line='552' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_barrier_tasks'>
+      <function-decl name='rcu_barrier_tasks' mangled-name='rcu_barrier_tasks' filepath='kernel/rcu/tasks.h' line='566' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_barrier_tasks'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='rcu_barrier_tasks_trace' mangled-name='rcu_barrier_tasks_trace' filepath='kernel/rcu/tasks.h' line='1178' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_barrier_tasks_trace'>
+      <function-decl name='rcu_barrier_tasks_trace' mangled-name='rcu_barrier_tasks_trace' filepath='kernel/rcu/tasks.h' line='1191' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_barrier_tasks_trace'>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='rcu_bind_current_to_nocb' mangled-name='rcu_bind_current_to_nocb' filepath='kernel/rcu/tree_plugin.h' line='2387' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_bind_current_to_nocb'>
@@ -140434,7 +141220,7 @@
       <function-decl name='rcu_expedite_gp' mangled-name='rcu_expedite_gp' filepath='kernel/rcu/update.c' line='167' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_expedite_gp'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='rcu_force_quiescent_state' mangled-name='rcu_force_quiescent_state' filepath='kernel/rcu/tree.c' line='2645' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_force_quiescent_state'>
+      <function-decl name='rcu_force_quiescent_state' mangled-name='rcu_force_quiescent_state' filepath='kernel/rcu/tree.c' line='2653' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_force_quiescent_state'>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='rcu_fwd_progress_check' mangled-name='rcu_fwd_progress_check' filepath='kernel/rcu/tree_stall.h' line='806' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_fwd_progress_check'>
@@ -140453,8 +141239,8 @@
       <function-decl name='rcu_gp_is_normal' mangled-name='rcu_gp_is_normal' filepath='kernel/rcu/update.c' line='138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_gp_is_normal'>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='rcu_gp_set_torture_wait' mangled-name='rcu_gp_set_torture_wait' filepath='kernel/rcu/tree.c' line='1691' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_gp_set_torture_wait'>
-        <parameter type-id='95e97e5e' name='duration' filepath='kernel/rcu/tree.c' line='1691' column='1'/>
+      <function-decl name='rcu_gp_set_torture_wait' mangled-name='rcu_gp_set_torture_wait' filepath='kernel/rcu/tree.c' line='1692' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_gp_set_torture_wait'>
+        <parameter type-id='95e97e5e' name='duration' filepath='kernel/rcu/tree.c' line='1692' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='rcu_idle_enter' mangled-name='rcu_idle_enter' filepath='kernel/rcu/tree.c' line='664' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_idle_enter'>
@@ -140466,15 +141252,15 @@
       <function-decl name='rcu_inkernel_boot_has_ended' mangled-name='rcu_inkernel_boot_has_ended' filepath='kernel/rcu/update.c' line='204' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_inkernel_boot_has_ended'>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='rcu_is_watching' mangled-name='rcu_is_watching' filepath='kernel/rcu/tree.c' line='1105' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_is_watching'>
+      <function-decl name='rcu_is_watching' mangled-name='rcu_is_watching' filepath='kernel/rcu/tree.c' line='1106' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_is_watching'>
         <return type-id='b50a4934'/>
       </function-decl>
       <function-decl name='rcu_jiffies_till_stall_check' mangled-name='rcu_jiffies_till_stall_check' filepath='kernel/rcu/tree_stall.h' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_jiffies_till_stall_check'>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='rcu_read_unlock_trace_special' mangled-name='rcu_read_unlock_trace_special' filepath='kernel/rcu/tasks.h' line='776' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_read_unlock_trace_special'>
-        <parameter type-id='f23e2572' name='t' filepath='kernel/rcu/tasks.h' line='776' column='1'/>
-        <parameter type-id='95e97e5e' name='nesting' filepath='kernel/rcu/tasks.h' line='776' column='1'/>
+      <function-decl name='rcu_read_unlock_trace_special' mangled-name='rcu_read_unlock_trace_special' filepath='kernel/rcu/tasks.h' line='802' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_read_unlock_trace_special'>
+        <parameter type-id='f23e2572' name='t' filepath='kernel/rcu/tasks.h' line='802' column='1'/>
+        <parameter type-id='95e97e5e' name='nesting' filepath='kernel/rcu/tasks.h' line='802' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='rcu_unexpedite_gp' mangled-name='rcu_unexpedite_gp' filepath='kernel/rcu/update.c' line='182' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcu_unexpedite_gp'>
@@ -140486,37 +141272,37 @@
         <parameter type-id='1d2c2b85' name='gp_seq' filepath='kernel/rcu/tree.c' line='599' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='rcuwait_wake_up' mangled-name='rcuwait_wake_up' filepath='kernel/exit.c' line='233' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcuwait_wake_up'>
-        <parameter type-id='9b25216e' name='w' filepath='kernel/exit.c' line='233' column='1'/>
+      <function-decl name='rcuwait_wake_up' mangled-name='rcuwait_wake_up' filepath='kernel/exit.c' line='280' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rcuwait_wake_up'>
+        <parameter type-id='9b25216e' name='w' filepath='kernel/exit.c' line='280' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='rdev_get_dev' mangled-name='rdev_get_dev' filepath='drivers/regulator/core.c' line='5589' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rdev_get_dev'>
-        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='5589' column='1'/>
+      <function-decl name='rdev_get_dev' mangled-name='rdev_get_dev' filepath='drivers/regulator/core.c' line='5670' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rdev_get_dev'>
+        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='5670' column='1'/>
         <return type-id='fa0b179b'/>
       </function-decl>
-      <function-decl name='rdev_get_drvdata' mangled-name='rdev_get_drvdata' filepath='drivers/regulator/core.c' line='5549' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rdev_get_drvdata'>
-        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='5549' column='1'/>
+      <function-decl name='rdev_get_drvdata' mangled-name='rdev_get_drvdata' filepath='drivers/regulator/core.c' line='5630' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rdev_get_drvdata'>
+        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='5630' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='rdev_get_id' mangled-name='rdev_get_id' filepath='drivers/regulator/core.c' line='5583' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rdev_get_id'>
-        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='5583' column='1'/>
+      <function-decl name='rdev_get_id' mangled-name='rdev_get_id' filepath='drivers/regulator/core.c' line='5664' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rdev_get_id'>
+        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='5664' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='rdev_get_regmap' mangled-name='rdev_get_regmap' filepath='drivers/regulator/core.c' line='5595' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rdev_get_regmap'>
-        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='5595' column='1'/>
+      <function-decl name='rdev_get_regmap' mangled-name='rdev_get_regmap' filepath='drivers/regulator/core.c' line='5676' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rdev_get_regmap'>
+        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='5676' column='1'/>
         <return type-id='29af9a71'/>
       </function-decl>
-      <function-decl name='read_cache_page' mangled-name='read_cache_page' filepath='mm/filemap.c' line='3283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='read_cache_page'>
-        <parameter type-id='f57039f0' name='mapping' filepath='mm/filemap.c' line='3283' column='1'/>
-        <parameter type-id='7359adad' name='index' filepath='mm/filemap.c' line='3284' column='1'/>
-        <parameter type-id='83ac4446' name='filler' filepath='mm/filemap.c' line='3285' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='mm/filemap.c' line='3286' column='1'/>
+      <function-decl name='read_cache_page' mangled-name='read_cache_page' filepath='mm/filemap.c' line='3290' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='read_cache_page'>
+        <parameter type-id='f57039f0' name='mapping' filepath='mm/filemap.c' line='3290' column='1'/>
+        <parameter type-id='7359adad' name='index' filepath='mm/filemap.c' line='3291' column='1'/>
+        <parameter type-id='83ac4446' name='filler' filepath='mm/filemap.c' line='3292' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='mm/filemap.c' line='3293' column='1'/>
         <return type-id='02f11ed4'/>
       </function-decl>
-      <function-decl name='read_cache_page_gfp' mangled-name='read_cache_page_gfp' filepath='mm/filemap.c' line='3306' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='read_cache_page_gfp'>
-        <parameter type-id='f57039f0' name='mapping' filepath='mm/filemap.c' line='3306' column='1'/>
-        <parameter type-id='7359adad' name='index' filepath='mm/filemap.c' line='3307' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp' filepath='mm/filemap.c' line='3308' column='1'/>
+      <function-decl name='read_cache_page_gfp' mangled-name='read_cache_page_gfp' filepath='mm/filemap.c' line='3313' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='read_cache_page_gfp'>
+        <parameter type-id='f57039f0' name='mapping' filepath='mm/filemap.c' line='3313' column='1'/>
+        <parameter type-id='7359adad' name='index' filepath='mm/filemap.c' line='3314' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp' filepath='mm/filemap.c' line='3315' column='1'/>
         <return type-id='02f11ed4'/>
       </function-decl>
       <function-decl name='readahead_gfp_mask' mangled-name='readahead_gfp_mask' filepath='mm/readahead.c' line='118' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='readahead_gfp_mask'>
@@ -140528,8 +141314,8 @@
         <parameter type-id='19c2251e' name='d' filepath='lib/math/reciprocal_div.c' line='14' column='1'/>
         <return type-id='80ebe7f7'/>
       </function-decl>
-      <function-decl name='reclaim_pages' mangled-name='reclaim_pages' filepath='mm/vmscan.c' line='2174' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='reclaim_pages'>
-        <parameter type-id='e84b031a' name='page_list' filepath='mm/vmscan.c' line='2174' column='1'/>
+      <function-decl name='reclaim_pages' mangled-name='reclaim_pages' filepath='mm/vmscan.c' line='2187' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='reclaim_pages'>
+        <parameter type-id='e84b031a' name='page_list' filepath='mm/vmscan.c' line='2187' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
       <function-decl name='reclaim_shmem_address_space' mangled-name='reclaim_shmem_address_space' filepath='mm/shmem.c' line='4310' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='reclaim_shmem_address_space'>
@@ -140564,34 +141350,34 @@
         <parameter type-id='343c3ae4' name='policy' filepath='drivers/cpufreq/cpufreq.c' line='1146' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='regcache_cache_bypass' mangled-name='regcache_cache_bypass' filepath='drivers/base/regmap/regcache.c' line='538' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regcache_cache_bypass'>
-        <parameter type-id='29af9a71' name='map' filepath='drivers/base/regmap/regcache.c' line='538' column='1'/>
-        <parameter type-id='b50a4934' name='enable' filepath='drivers/base/regmap/regcache.c' line='538' column='1'/>
+      <function-decl name='regcache_cache_bypass' mangled-name='regcache_cache_bypass' filepath='drivers/base/regmap/regcache.c' line='544' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regcache_cache_bypass'>
+        <parameter type-id='29af9a71' name='map' filepath='drivers/base/regmap/regcache.c' line='544' column='1'/>
+        <parameter type-id='b50a4934' name='enable' filepath='drivers/base/regmap/regcache.c' line='544' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='regcache_cache_only' mangled-name='regcache_cache_only' filepath='drivers/base/regmap/regcache.c' line='495' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regcache_cache_only'>
-        <parameter type-id='29af9a71' name='map' filepath='drivers/base/regmap/regcache.c' line='495' column='1'/>
-        <parameter type-id='b50a4934' name='enable' filepath='drivers/base/regmap/regcache.c' line='495' column='1'/>
+      <function-decl name='regcache_cache_only' mangled-name='regcache_cache_only' filepath='drivers/base/regmap/regcache.c' line='501' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regcache_cache_only'>
+        <parameter type-id='29af9a71' name='map' filepath='drivers/base/regmap/regcache.c' line='501' column='1'/>
+        <parameter type-id='b50a4934' name='enable' filepath='drivers/base/regmap/regcache.c' line='501' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='regcache_drop_region' mangled-name='regcache_drop_region' filepath='drivers/base/regmap/regcache.c' line='463' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regcache_drop_region'>
-        <parameter type-id='29af9a71' name='map' filepath='drivers/base/regmap/regcache.c' line='463' column='1'/>
-        <parameter type-id='f0981eeb' name='min' filepath='drivers/base/regmap/regcache.c' line='463' column='1'/>
-        <parameter type-id='f0981eeb' name='max' filepath='drivers/base/regmap/regcache.c' line='464' column='1'/>
+      <function-decl name='regcache_drop_region' mangled-name='regcache_drop_region' filepath='drivers/base/regmap/regcache.c' line='469' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regcache_drop_region'>
+        <parameter type-id='29af9a71' name='map' filepath='drivers/base/regmap/regcache.c' line='469' column='1'/>
+        <parameter type-id='f0981eeb' name='min' filepath='drivers/base/regmap/regcache.c' line='469' column='1'/>
+        <parameter type-id='f0981eeb' name='max' filepath='drivers/base/regmap/regcache.c' line='470' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regcache_mark_dirty' mangled-name='regcache_mark_dirty' filepath='drivers/base/regmap/regcache.c' line='518' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regcache_mark_dirty'>
-        <parameter type-id='29af9a71' name='map' filepath='drivers/base/regmap/regcache.c' line='518' column='1'/>
+      <function-decl name='regcache_mark_dirty' mangled-name='regcache_mark_dirty' filepath='drivers/base/regmap/regcache.c' line='524' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regcache_mark_dirty'>
+        <parameter type-id='29af9a71' name='map' filepath='drivers/base/regmap/regcache.c' line='524' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='regcache_sync' mangled-name='regcache_sync' filepath='drivers/base/regmap/regcache.c' line='339' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regcache_sync'>
         <parameter type-id='29af9a71' name='map' filepath='drivers/base/regmap/regcache.c' line='339' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regcache_sync_region' mangled-name='regcache_sync_region' filepath='drivers/base/regmap/regcache.c' line='408' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regcache_sync_region'>
-        <parameter type-id='29af9a71' name='map' filepath='drivers/base/regmap/regcache.c' line='408' column='1'/>
-        <parameter type-id='f0981eeb' name='min' filepath='drivers/base/regmap/regcache.c' line='408' column='1'/>
-        <parameter type-id='f0981eeb' name='max' filepath='drivers/base/regmap/regcache.c' line='409' column='1'/>
+      <function-decl name='regcache_sync_region' mangled-name='regcache_sync_region' filepath='drivers/base/regmap/regcache.c' line='411' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regcache_sync_region'>
+        <parameter type-id='29af9a71' name='map' filepath='drivers/base/regmap/regcache.c' line='411' column='1'/>
+        <parameter type-id='f0981eeb' name='min' filepath='drivers/base/regmap/regcache.c' line='411' column='1'/>
+        <parameter type-id='f0981eeb' name='max' filepath='drivers/base/regmap/regcache.c' line='412' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='register_blkdev' mangled-name='register_blkdev' filepath='block/genhd.c' line='440' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_blkdev'>
@@ -140659,12 +141445,12 @@
         <parameter type-id='631dc3c1' name='table' filepath='net/sysctl_net.c' line='119' column='1'/>
         <return type-id='11b101bb'/>
       </function-decl>
-      <function-decl name='register_netdev' mangled-name='register_netdev' filepath='net/core/dev.c' line='10137' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_netdev'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10137' column='1'/>
+      <function-decl name='register_netdev' mangled-name='register_netdev' filepath='net/core/dev.c' line='10144' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_netdev'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10144' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='register_netdevice' mangled-name='register_netdevice' filepath='net/core/dev.c' line='9915' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_netdevice'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='9915' column='1'/>
+      <function-decl name='register_netdevice' mangled-name='register_netdevice' filepath='net/core/dev.c' line='9922' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_netdevice'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='9922' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='register_netdevice_notifier' mangled-name='register_netdevice_notifier' filepath='net/core/dev.c' line='1829' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_netdevice_notifier'>
@@ -140679,12 +141465,12 @@
         <parameter type-id='d504f73d' name='nb' filepath='mm/oom_kill.c' line='1075' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='register_pernet_device' mangled-name='register_pernet_device' filepath='net/core/net_namespace.c' line='1329' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_pernet_device'>
-        <parameter type-id='d6907f4c' name='ops' filepath='net/core/net_namespace.c' line='1329' column='1'/>
+      <function-decl name='register_pernet_device' mangled-name='register_pernet_device' filepath='net/core/net_namespace.c' line='1316' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_pernet_device'>
+        <parameter type-id='d6907f4c' name='ops' filepath='net/core/net_namespace.c' line='1316' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='register_pernet_subsys' mangled-name='register_pernet_subsys' filepath='net/core/net_namespace.c' line='1283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_pernet_subsys'>
-        <parameter type-id='d6907f4c' name='ops' filepath='net/core/net_namespace.c' line='1283' column='1'/>
+      <function-decl name='register_pernet_subsys' mangled-name='register_pernet_subsys' filepath='net/core/net_namespace.c' line='1270' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_pernet_subsys'>
+        <parameter type-id='d6907f4c' name='ops' filepath='net/core/net_namespace.c' line='1270' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='register_pm_notifier' mangled-name='register_pm_notifier' filepath='kernel/power/main.c' line='71' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_pm_notifier'>
@@ -140711,17 +141497,17 @@
         <parameter type-id='cbd24a98' name='ops' filepath='drivers/base/syscore.c' line='22' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='register_sysctl' mangled-name='register_sysctl' filepath='fs/proc/proc_sysctl.c' line='1376' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_sysctl'>
-        <parameter type-id='80f4b756' name='path' filepath='fs/proc/proc_sysctl.c' line='1376' column='1'/>
-        <parameter type-id='631dc3c1' name='table' filepath='fs/proc/proc_sysctl.c' line='1376' column='1'/>
+      <function-decl name='register_sysctl' mangled-name='register_sysctl' filepath='fs/proc/proc_sysctl.c' line='1385' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_sysctl'>
+        <parameter type-id='80f4b756' name='path' filepath='fs/proc/proc_sysctl.c' line='1385' column='1'/>
+        <parameter type-id='631dc3c1' name='table' filepath='fs/proc/proc_sysctl.c' line='1385' column='1'/>
         <return type-id='11b101bb'/>
       </function-decl>
-      <function-decl name='register_sysctl_table' mangled-name='register_sysctl_table' filepath='fs/proc/proc_sysctl.c' line='1588' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_sysctl_table'>
-        <parameter type-id='631dc3c1' name='table' filepath='fs/proc/proc_sysctl.c' line='1588' column='1'/>
+      <function-decl name='register_sysctl_table' mangled-name='register_sysctl_table' filepath='fs/proc/proc_sysctl.c' line='1629' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_sysctl_table'>
+        <parameter type-id='631dc3c1' name='table' filepath='fs/proc/proc_sysctl.c' line='1629' column='1'/>
         <return type-id='11b101bb'/>
       </function-decl>
-      <function-decl name='register_tcf_proto_ops' mangled-name='register_tcf_proto_ops' filepath='net/sched/cls_api.c' line='160' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_tcf_proto_ops'>
-        <parameter type-id='84c1f5fe' name='ops' filepath='net/sched/cls_api.c' line='160' column='1'/>
+      <function-decl name='register_tcf_proto_ops' mangled-name='register_tcf_proto_ops' filepath='net/sched/cls_api.c' line='158' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_tcf_proto_ops'>
+        <parameter type-id='84c1f5fe' name='ops' filepath='net/sched/cls_api.c' line='158' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='register_virtio_device' mangled-name='register_virtio_device' filepath='drivers/virtio/virtio.c' line='344' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='register_virtio_device'>
@@ -140882,29 +141668,29 @@
         <parameter type-id='f0981eeb' name='val' filepath='drivers/base/regmap/regmap.c' line='1946' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_allow_bypass' mangled-name='regulator_allow_bypass' filepath='drivers/regulator/core.c' line='4489' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_allow_bypass'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4489' column='1'/>
-        <parameter type-id='b50a4934' name='enable' filepath='drivers/regulator/core.c' line='4489' column='1'/>
+      <function-decl name='regulator_allow_bypass' mangled-name='regulator_allow_bypass' filepath='drivers/regulator/core.c' line='4571' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_allow_bypass'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4571' column='1'/>
+        <parameter type-id='b50a4934' name='enable' filepath='drivers/regulator/core.c' line='4571' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_bulk_disable' mangled-name='regulator_bulk_disable' filepath='drivers/regulator/core.c' line='4697' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_bulk_disable'>
-        <parameter type-id='95e97e5e' name='num_consumers' filepath='drivers/regulator/core.c' line='4697' column='1'/>
-        <parameter type-id='776946b4' name='consumers' filepath='drivers/regulator/core.c' line='4698' column='1'/>
+      <function-decl name='regulator_bulk_disable' mangled-name='regulator_bulk_disable' filepath='drivers/regulator/core.c' line='4779' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_bulk_disable'>
+        <parameter type-id='95e97e5e' name='num_consumers' filepath='drivers/regulator/core.c' line='4779' column='1'/>
+        <parameter type-id='776946b4' name='consumers' filepath='drivers/regulator/core.c' line='4780' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_bulk_enable' mangled-name='regulator_bulk_enable' filepath='drivers/regulator/core.c' line='4648' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_bulk_enable'>
-        <parameter type-id='95e97e5e' name='num_consumers' filepath='drivers/regulator/core.c' line='4648' column='1'/>
-        <parameter type-id='776946b4' name='consumers' filepath='drivers/regulator/core.c' line='4649' column='1'/>
+      <function-decl name='regulator_bulk_enable' mangled-name='regulator_bulk_enable' filepath='drivers/regulator/core.c' line='4730' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_bulk_enable'>
+        <parameter type-id='95e97e5e' name='num_consumers' filepath='drivers/regulator/core.c' line='4730' column='1'/>
+        <parameter type-id='776946b4' name='consumers' filepath='drivers/regulator/core.c' line='4731' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_bulk_get' mangled-name='regulator_bulk_get' filepath='drivers/regulator/core.c' line='4593' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_bulk_get'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/regulator/core.c' line='4593' column='1'/>
-        <parameter type-id='95e97e5e' name='num_consumers' filepath='drivers/regulator/core.c' line='4593' column='1'/>
-        <parameter type-id='776946b4' name='consumers' filepath='drivers/regulator/core.c' line='4594' column='1'/>
+      <function-decl name='regulator_bulk_get' mangled-name='regulator_bulk_get' filepath='drivers/regulator/core.c' line='4675' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_bulk_get'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/regulator/core.c' line='4675' column='1'/>
+        <parameter type-id='95e97e5e' name='num_consumers' filepath='drivers/regulator/core.c' line='4675' column='1'/>
+        <parameter type-id='776946b4' name='consumers' filepath='drivers/regulator/core.c' line='4676' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_count_voltages' mangled-name='regulator_count_voltages' filepath='drivers/regulator/core.c' line='3054' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_count_voltages'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='3054' column='1'/>
+      <function-decl name='regulator_count_voltages' mangled-name='regulator_count_voltages' filepath='drivers/regulator/core.c' line='3136' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_count_voltages'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='3136' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='regulator_desc_list_voltage_linear_range' mangled-name='regulator_desc_list_voltage_linear_range' filepath='drivers/regulator/helpers.c' line='597' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_desc_list_voltage_linear_range'>
@@ -140912,34 +141698,34 @@
         <parameter type-id='f0981eeb' name='selector' filepath='drivers/regulator/helpers.c' line='598' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_disable' mangled-name='regulator_disable' filepath='drivers/regulator/core.c' line='2824' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_disable'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='2824' column='1'/>
+      <function-decl name='regulator_disable' mangled-name='regulator_disable' filepath='drivers/regulator/core.c' line='2906' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_disable'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='2906' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_disable_deferred' mangled-name='regulator_disable_deferred' filepath='drivers/regulator/core.c' line='2955' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_disable_deferred'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='2955' column='1'/>
-        <parameter type-id='95e97e5e' name='ms' filepath='drivers/regulator/core.c' line='2955' column='1'/>
+      <function-decl name='regulator_disable_deferred' mangled-name='regulator_disable_deferred' filepath='drivers/regulator/core.c' line='3037' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_disable_deferred'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='3037' column='1'/>
+        <parameter type-id='95e97e5e' name='ms' filepath='drivers/regulator/core.c' line='3037' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='regulator_disable_regmap' mangled-name='regulator_disable_regmap' filepath='drivers/regulator/helpers.c' line='85' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_disable_regmap'>
         <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/helpers.c' line='85' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_enable' mangled-name='regulator_enable' filepath='drivers/regulator/core.c' line='2714' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_enable'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='2714' column='1'/>
+      <function-decl name='regulator_enable' mangled-name='regulator_enable' filepath='drivers/regulator/core.c' line='2796' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_enable'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='2796' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='regulator_enable_regmap' mangled-name='regulator_enable_regmap' filepath='drivers/regulator/helpers.c' line='59' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_enable_regmap'>
         <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/helpers.c' line='59' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_force_disable' mangled-name='regulator_force_disable' filepath='drivers/regulator/core.c' line='2873' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_force_disable'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='2873' column='1'/>
+      <function-decl name='regulator_force_disable' mangled-name='regulator_force_disable' filepath='drivers/regulator/core.c' line='2955' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_force_disable'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='2955' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_get' mangled-name='regulator_get' filepath='drivers/regulator/core.c' line='2059' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/regulator/core.c' line='2059' column='1'/>
-        <parameter type-id='80f4b756' name='id' filepath='drivers/regulator/core.c' line='2059' column='1'/>
+      <function-decl name='regulator_get' mangled-name='regulator_get' filepath='drivers/regulator/core.c' line='2141' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/regulator/core.c' line='2141' column='1'/>
+        <parameter type-id='80f4b756' name='id' filepath='drivers/regulator/core.c' line='2141' column='1'/>
         <return type-id='850c13f6'/>
       </function-decl>
       <function-decl name='regulator_get_bypass_regmap' mangled-name='regulator_get_bypass_regmap' filepath='drivers/regulator/helpers.c' line='722' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_bypass_regmap'>
@@ -140947,60 +141733,60 @@
         <parameter type-id='d8e6b335' name='enable' filepath='drivers/regulator/helpers.c' line='722' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_get_current_limit' mangled-name='regulator_get_current_limit' filepath='drivers/regulator/core.c' line='4307' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_current_limit'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4307' column='1'/>
+      <function-decl name='regulator_get_current_limit' mangled-name='regulator_get_current_limit' filepath='drivers/regulator/core.c' line='4389' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_current_limit'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4389' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='regulator_get_current_limit_regmap' mangled-name='regulator_get_current_limit_regmap' filepath='drivers/regulator/helpers.c' line='827' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_current_limit_regmap'>
         <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/helpers.c' line='827' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_get_drvdata' mangled-name='regulator_get_drvdata' filepath='drivers/regulator/core.c' line='5562' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_drvdata'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='5562' column='1'/>
+      <function-decl name='regulator_get_drvdata' mangled-name='regulator_get_drvdata' filepath='drivers/regulator/core.c' line='5643' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_drvdata'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='5643' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='regulator_get_linear_step' mangled-name='regulator_get_linear_step' filepath='drivers/regulator/core.c' line='3162' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_linear_step'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='3162' column='1'/>
+      <function-decl name='regulator_get_linear_step' mangled-name='regulator_get_linear_step' filepath='drivers/regulator/core.c' line='3244' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_linear_step'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='3244' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='regulator_get_mode' mangled-name='regulator_get_mode' filepath='drivers/regulator/core.c' line='4385' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_mode'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4385' column='1'/>
+      <function-decl name='regulator_get_mode' mangled-name='regulator_get_mode' filepath='drivers/regulator/core.c' line='4467' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_mode'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4467' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='regulator_get_optional' mangled-name='regulator_get_optional' filepath='drivers/regulator/core.c' line='2112' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_optional'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/regulator/core.c' line='2112' column='1'/>
-        <parameter type-id='80f4b756' name='id' filepath='drivers/regulator/core.c' line='2112' column='1'/>
+      <function-decl name='regulator_get_optional' mangled-name='regulator_get_optional' filepath='drivers/regulator/core.c' line='2194' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_optional'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/regulator/core.c' line='2194' column='1'/>
+        <parameter type-id='80f4b756' name='id' filepath='drivers/regulator/core.c' line='2194' column='1'/>
         <return type-id='850c13f6'/>
       </function-decl>
-      <function-decl name='regulator_get_voltage' mangled-name='regulator_get_voltage' filepath='drivers/regulator/core.c' line='4223' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_voltage'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4223' column='1'/>
+      <function-decl name='regulator_get_voltage' mangled-name='regulator_get_voltage' filepath='drivers/regulator/core.c' line='4305' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_voltage'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4305' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_get_voltage_rdev' mangled-name='regulator_get_voltage_rdev' filepath='drivers/regulator/core.c' line='4168' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_voltage_rdev'>
-        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='4168' column='1'/>
+      <function-decl name='regulator_get_voltage_rdev' mangled-name='regulator_get_voltage_rdev' filepath='drivers/regulator/core.c' line='4250' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_voltage_rdev'>
+        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='4250' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='regulator_get_voltage_sel_regmap' mangled-name='regulator_get_voltage_sel_regmap' filepath='drivers/regulator/helpers.c' line='235' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_get_voltage_sel_regmap'>
         <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/helpers.c' line='235' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_is_enabled' mangled-name='regulator_is_enabled' filepath='drivers/regulator/core.c' line='3031' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_is_enabled'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='3031' column='1'/>
+      <function-decl name='regulator_is_enabled' mangled-name='regulator_is_enabled' filepath='drivers/regulator/core.c' line='3113' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_is_enabled'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='3113' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='regulator_is_enabled_regmap' mangled-name='regulator_is_enabled_regmap' filepath='drivers/regulator/helpers.c' line='27' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_is_enabled_regmap'>
         <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/helpers.c' line='27' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_is_supported_voltage' mangled-name='regulator_is_supported_voltage' filepath='drivers/regulator/core.c' line='3179' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_is_supported_voltage'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='3179' column='1'/>
-        <parameter type-id='95e97e5e' name='min_uV' filepath='drivers/regulator/core.c' line='3180' column='1'/>
-        <parameter type-id='95e97e5e' name='max_uV' filepath='drivers/regulator/core.c' line='3180' column='1'/>
+      <function-decl name='regulator_is_supported_voltage' mangled-name='regulator_is_supported_voltage' filepath='drivers/regulator/core.c' line='3261' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_is_supported_voltage'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='3261' column='1'/>
+        <parameter type-id='95e97e5e' name='min_uV' filepath='drivers/regulator/core.c' line='3262' column='1'/>
+        <parameter type-id='95e97e5e' name='max_uV' filepath='drivers/regulator/core.c' line='3262' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_list_voltage' mangled-name='regulator_list_voltage' filepath='drivers/regulator/core.c' line='3078' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_list_voltage'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='3078' column='1'/>
-        <parameter type-id='f0981eeb' name='selector' filepath='drivers/regulator/core.c' line='3078' column='1'/>
+      <function-decl name='regulator_list_voltage' mangled-name='regulator_list_voltage' filepath='drivers/regulator/core.c' line='3160' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_list_voltage'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='3160' column='1'/>
+        <parameter type-id='f0981eeb' name='selector' filepath='drivers/regulator/core.c' line='3160' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='regulator_list_voltage_linear' mangled-name='regulator_list_voltage_linear' filepath='drivers/regulator/helpers.c' line='521' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_list_voltage_linear'>
@@ -141042,24 +141828,24 @@
         <parameter type-id='95e97e5e' name='max_uV' filepath='drivers/regulator/helpers.c' line='408' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_notifier_call_chain' mangled-name='regulator_notifier_call_chain' filepath='drivers/regulator/core.c' line='4787' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_notifier_call_chain'>
-        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='4787' column='1'/>
-        <parameter type-id='7359adad' name='event' filepath='drivers/regulator/core.c' line='4788' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/regulator/core.c' line='4788' column='1'/>
+      <function-decl name='regulator_notifier_call_chain' mangled-name='regulator_notifier_call_chain' filepath='drivers/regulator/core.c' line='4869' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_notifier_call_chain'>
+        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='4869' column='1'/>
+        <parameter type-id='7359adad' name='event' filepath='drivers/regulator/core.c' line='4870' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/regulator/core.c' line='4870' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_put' mangled-name='regulator_put' filepath='drivers/regulator/core.c' line='2172' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_put'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='2172' column='1'/>
+      <function-decl name='regulator_put' mangled-name='regulator_put' filepath='drivers/regulator/core.c' line='2254' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_put'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='2254' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='regulator_register' mangled-name='regulator_register' filepath='drivers/regulator/core.c' line='5181' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_register'>
-        <parameter type-id='5629bd41' name='regulator_desc' filepath='drivers/regulator/core.c' line='5181' column='1'/>
-        <parameter type-id='661ccd0c' name='cfg' filepath='drivers/regulator/core.c' line='5182' column='1'/>
+      <function-decl name='regulator_register' mangled-name='regulator_register' filepath='drivers/regulator/core.c' line='5261' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_register'>
+        <parameter type-id='5629bd41' name='regulator_desc' filepath='drivers/regulator/core.c' line='5261' column='1'/>
+        <parameter type-id='661ccd0c' name='cfg' filepath='drivers/regulator/core.c' line='5262' column='1'/>
         <return type-id='43c38462'/>
       </function-decl>
-      <function-decl name='regulator_register_notifier' mangled-name='regulator_register_notifier' filepath='drivers/regulator/core.c' line='4546' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_register_notifier'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4546' column='1'/>
-        <parameter type-id='d504f73d' name='nb' filepath='drivers/regulator/core.c' line='4547' column='1'/>
+      <function-decl name='regulator_register_notifier' mangled-name='regulator_register_notifier' filepath='drivers/regulator/core.c' line='4628' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_register_notifier'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4628' column='1'/>
+        <parameter type-id='d504f73d' name='nb' filepath='drivers/regulator/core.c' line='4629' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='regulator_set_active_discharge_regmap' mangled-name='regulator_set_active_discharge_regmap' filepath='drivers/regulator/helpers.c' line='748' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_active_discharge_regmap'>
@@ -141072,10 +141858,10 @@
         <parameter type-id='b50a4934' name='enable' filepath='drivers/regulator/helpers.c' line='663' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_set_current_limit' mangled-name='regulator_set_current_limit' filepath='drivers/regulator/core.c' line='4252' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_current_limit'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4252' column='1'/>
-        <parameter type-id='95e97e5e' name='min_uA' filepath='drivers/regulator/core.c' line='4253' column='1'/>
-        <parameter type-id='95e97e5e' name='max_uA' filepath='drivers/regulator/core.c' line='4253' column='1'/>
+      <function-decl name='regulator_set_current_limit' mangled-name='regulator_set_current_limit' filepath='drivers/regulator/core.c' line='4334' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_current_limit'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4334' column='1'/>
+        <parameter type-id='95e97e5e' name='min_uA' filepath='drivers/regulator/core.c' line='4335' column='1'/>
+        <parameter type-id='95e97e5e' name='max_uA' filepath='drivers/regulator/core.c' line='4335' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='regulator_set_current_limit_regmap' mangled-name='regulator_set_current_limit_regmap' filepath='drivers/regulator/helpers.c' line='775' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_current_limit_regmap'>
@@ -141084,24 +141870,24 @@
         <parameter type-id='95e97e5e' name='max_uA' filepath='drivers/regulator/helpers.c' line='776' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_set_load' mangled-name='regulator_set_load' filepath='drivers/regulator/core.c' line='4458' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_load'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4458' column='1'/>
-        <parameter type-id='95e97e5e' name='uA_load' filepath='drivers/regulator/core.c' line='4458' column='1'/>
+      <function-decl name='regulator_set_load' mangled-name='regulator_set_load' filepath='drivers/regulator/core.c' line='4540' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_load'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4540' column='1'/>
+        <parameter type-id='95e97e5e' name='uA_load' filepath='drivers/regulator/core.c' line='4540' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_set_mode' mangled-name='regulator_set_mode' filepath='drivers/regulator/core.c' line='4324' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_mode'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4324' column='1'/>
-        <parameter type-id='f0981eeb' name='mode' filepath='drivers/regulator/core.c' line='4324' column='1'/>
+      <function-decl name='regulator_set_mode' mangled-name='regulator_set_mode' filepath='drivers/regulator/core.c' line='4406' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_mode'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4406' column='1'/>
+        <parameter type-id='f0981eeb' name='mode' filepath='drivers/regulator/core.c' line='4406' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='regulator_set_pull_down_regmap' mangled-name='regulator_set_pull_down_regmap' filepath='drivers/regulator/helpers.c' line='703' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_pull_down_regmap'>
         <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/helpers.c' line='703' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_set_voltage' mangled-name='regulator_set_voltage' filepath='drivers/regulator/core.c' line='3938' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_voltage'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='3938' column='1'/>
-        <parameter type-id='95e97e5e' name='min_uV' filepath='drivers/regulator/core.c' line='3938' column='1'/>
-        <parameter type-id='95e97e5e' name='max_uV' filepath='drivers/regulator/core.c' line='3938' column='1'/>
+      <function-decl name='regulator_set_voltage' mangled-name='regulator_set_voltage' filepath='drivers/regulator/core.c' line='4020' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_voltage'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4020' column='1'/>
+        <parameter type-id='95e97e5e' name='min_uV' filepath='drivers/regulator/core.c' line='4020' column='1'/>
+        <parameter type-id='95e97e5e' name='max_uV' filepath='drivers/regulator/core.c' line='4020' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='regulator_set_voltage_sel_regmap' mangled-name='regulator_set_voltage_sel_regmap' filepath='drivers/regulator/helpers.c' line='261' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_voltage_sel_regmap'>
@@ -141109,34 +141895,34 @@
         <parameter type-id='f0981eeb' name='sel' filepath='drivers/regulator/helpers.c' line='261' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_set_voltage_time' mangled-name='regulator_set_voltage_time' filepath='drivers/regulator/core.c' line='4048' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_voltage_time'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4048' column='1'/>
-        <parameter type-id='95e97e5e' name='old_uV' filepath='drivers/regulator/core.c' line='4049' column='1'/>
-        <parameter type-id='95e97e5e' name='new_uV' filepath='drivers/regulator/core.c' line='4049' column='1'/>
+      <function-decl name='regulator_set_voltage_time' mangled-name='regulator_set_voltage_time' filepath='drivers/regulator/core.c' line='4130' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_voltage_time'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4130' column='1'/>
+        <parameter type-id='95e97e5e' name='old_uV' filepath='drivers/regulator/core.c' line='4131' column='1'/>
+        <parameter type-id='95e97e5e' name='new_uV' filepath='drivers/regulator/core.c' line='4131' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_set_voltage_time_sel' mangled-name='regulator_set_voltage_time_sel' filepath='drivers/regulator/core.c' line='4099' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_voltage_time_sel'>
-        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='4099' column='1'/>
-        <parameter type-id='f0981eeb' name='old_selector' filepath='drivers/regulator/core.c' line='4100' column='1'/>
-        <parameter type-id='f0981eeb' name='new_selector' filepath='drivers/regulator/core.c' line='4101' column='1'/>
+      <function-decl name='regulator_set_voltage_time_sel' mangled-name='regulator_set_voltage_time_sel' filepath='drivers/regulator/core.c' line='4181' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_set_voltage_time_sel'>
+        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='4181' column='1'/>
+        <parameter type-id='f0981eeb' name='old_selector' filepath='drivers/regulator/core.c' line='4182' column='1'/>
+        <parameter type-id='f0981eeb' name='new_selector' filepath='drivers/regulator/core.c' line='4183' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_suspend_enable' mangled-name='regulator_suspend_enable' filepath='drivers/regulator/core.c' line='3971' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_suspend_enable'>
-        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='3971' column='1'/>
-        <parameter type-id='e884daa5' name='state' filepath='drivers/regulator/core.c' line='3972' column='1'/>
+      <function-decl name='regulator_suspend_enable' mangled-name='regulator_suspend_enable' filepath='drivers/regulator/core.c' line='4053' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_suspend_enable'>
+        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='4053' column='1'/>
+        <parameter type-id='e884daa5' name='state' filepath='drivers/regulator/core.c' line='4054' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_sync_voltage' mangled-name='regulator_sync_voltage' filepath='drivers/regulator/core.c' line='4128' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_sync_voltage'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4128' column='1'/>
+      <function-decl name='regulator_sync_voltage' mangled-name='regulator_sync_voltage' filepath='drivers/regulator/core.c' line='4210' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_sync_voltage'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4210' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='regulator_unregister' mangled-name='regulator_unregister' filepath='drivers/regulator/core.c' line='5427' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_unregister'>
-        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='5427' column='1'/>
+      <function-decl name='regulator_unregister' mangled-name='regulator_unregister' filepath='drivers/regulator/core.c' line='5508' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_unregister'>
+        <parameter type-id='43c38462' name='rdev' filepath='drivers/regulator/core.c' line='5508' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='regulator_unregister_notifier' mangled-name='regulator_unregister_notifier' filepath='drivers/regulator/core.c' line='4561' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_unregister_notifier'>
-        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4561' column='1'/>
-        <parameter type-id='d504f73d' name='nb' filepath='drivers/regulator/core.c' line='4562' column='1'/>
+      <function-decl name='regulator_unregister_notifier' mangled-name='regulator_unregister_notifier' filepath='drivers/regulator/core.c' line='4643' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='regulator_unregister_notifier'>
+        <parameter type-id='850c13f6' name='regulator' filepath='drivers/regulator/core.c' line='4643' column='1'/>
+        <parameter type-id='d504f73d' name='nb' filepath='drivers/regulator/core.c' line='4644' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='release_firmware' mangled-name='release_firmware' filepath='drivers/base/firmware_loader/main.c' line='1050' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='release_firmware'>
@@ -141148,22 +141934,22 @@
         <parameter type-id='95e97e5e' name='nr' filepath='mm/swap.c' line='1000' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='release_sock' mangled-name='release_sock' filepath='net/core/sock.c' line='3081' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='release_sock'>
-        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='3081' column='1'/>
+      <function-decl name='release_sock' mangled-name='release_sock' filepath='net/core/sock.c' line='3108' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='release_sock'>
+        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='3108' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='remap_pfn_range' mangled-name='remap_pfn_range' filepath='mm/memory.c' line='2346' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='remap_pfn_range'>
-        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='2346' column='1'/>
-        <parameter type-id='7359adad' name='addr' filepath='mm/memory.c' line='2346' column='1'/>
-        <parameter type-id='7359adad' name='pfn' filepath='mm/memory.c' line='2347' column='1'/>
-        <parameter type-id='7359adad' name='size' filepath='mm/memory.c' line='2347' column='1'/>
-        <parameter type-id='2e2dcbd3' name='prot' filepath='mm/memory.c' line='2347' column='1'/>
+      <function-decl name='remap_pfn_range' mangled-name='remap_pfn_range' filepath='mm/memory.c' line='2356' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='remap_pfn_range'>
+        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='2356' column='1'/>
+        <parameter type-id='7359adad' name='addr' filepath='mm/memory.c' line='2356' column='1'/>
+        <parameter type-id='7359adad' name='pfn' filepath='mm/memory.c' line='2357' column='1'/>
+        <parameter type-id='7359adad' name='size' filepath='mm/memory.c' line='2357' column='1'/>
+        <parameter type-id='2e2dcbd3' name='prot' filepath='mm/memory.c' line='2357' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='remap_vmalloc_range' mangled-name='remap_vmalloc_range' filepath='mm/vmalloc.c' line='3081' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='remap_vmalloc_range'>
-        <parameter type-id='2ae08426' name='vma' filepath='mm/vmalloc.c' line='3081' column='1'/>
-        <parameter type-id='eaa32e2f' name='addr' filepath='mm/vmalloc.c' line='3081' column='1'/>
-        <parameter type-id='7359adad' name='pgoff' filepath='mm/vmalloc.c' line='3082' column='1'/>
+      <function-decl name='remap_vmalloc_range' mangled-name='remap_vmalloc_range' filepath='mm/vmalloc.c' line='3085' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='remap_vmalloc_range'>
+        <parameter type-id='2ae08426' name='vma' filepath='mm/vmalloc.c' line='3085' column='1'/>
+        <parameter type-id='eaa32e2f' name='addr' filepath='mm/vmalloc.c' line='3085' column='1'/>
+        <parameter type-id='7359adad' name='pgoff' filepath='mm/vmalloc.c' line='3086' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='remove_cpu' mangled-name='remove_cpu' filepath='kernel/cpu.c' line='1150' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='remove_cpu'>
@@ -141191,19 +141977,19 @@
         <parameter type-id='db9d03e3' name='wq_entry' filepath='kernel/sched/wait.c' line='41' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='report_iommu_fault' mangled-name='report_iommu_fault' filepath='drivers/iommu/iommu.c' line='2718' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='report_iommu_fault'>
-        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2718' column='1'/>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='2718' column='1'/>
-        <parameter type-id='7359adad' name='iova' filepath='drivers/iommu/iommu.c' line='2719' column='1'/>
-        <parameter type-id='95e97e5e' name='flags' filepath='drivers/iommu/iommu.c' line='2719' column='1'/>
+      <function-decl name='report_iommu_fault' mangled-name='report_iommu_fault' filepath='drivers/iommu/iommu.c' line='2734' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='report_iommu_fault'>
+        <parameter type-id='bff05edb' name='domain' filepath='drivers/iommu/iommu.c' line='2734' column='1'/>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/iommu/iommu.c' line='2734' column='1'/>
+        <parameter type-id='7359adad' name='iova' filepath='drivers/iommu/iommu.c' line='2735' column='1'/>
+        <parameter type-id='95e97e5e' name='flags' filepath='drivers/iommu/iommu.c' line='2735' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='request_any_context_irq' mangled-name='request_any_context_irq' filepath='kernel/irq/manage.c' line='2144' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='request_any_context_irq'>
-        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2144' column='1'/>
-        <parameter type-id='29591c9a' name='handler' filepath='kernel/irq/manage.c' line='2144' column='1'/>
-        <parameter type-id='7359adad' name='flags' filepath='kernel/irq/manage.c' line='2145' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='kernel/irq/manage.c' line='2145' column='1'/>
-        <parameter type-id='eaa32e2f' name='dev_id' filepath='kernel/irq/manage.c' line='2145' column='1'/>
+      <function-decl name='request_any_context_irq' mangled-name='request_any_context_irq' filepath='kernel/irq/manage.c' line='2150' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='request_any_context_irq'>
+        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2150' column='1'/>
+        <parameter type-id='29591c9a' name='handler' filepath='kernel/irq/manage.c' line='2150' column='1'/>
+        <parameter type-id='7359adad' name='flags' filepath='kernel/irq/manage.c' line='2151' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='kernel/irq/manage.c' line='2151' column='1'/>
+        <parameter type-id='eaa32e2f' name='dev_id' filepath='kernel/irq/manage.c' line='2151' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='request_firmware' mangled-name='request_firmware' filepath='drivers/base/firmware_loader/main.c' line='869' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='request_firmware'>
@@ -141236,13 +142022,13 @@
         <parameter type-id='c8e4e392' name='cont' filepath='drivers/base/firmware_loader/main.c' line='1115' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='request_threaded_irq' mangled-name='request_threaded_irq' filepath='kernel/irq/manage.c' line='2041' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='request_threaded_irq'>
-        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2041' column='1'/>
-        <parameter type-id='29591c9a' name='handler' filepath='kernel/irq/manage.c' line='2041' column='1'/>
-        <parameter type-id='29591c9a' name='thread_fn' filepath='kernel/irq/manage.c' line='2042' column='1'/>
-        <parameter type-id='7359adad' name='irqflags' filepath='kernel/irq/manage.c' line='2042' column='1'/>
-        <parameter type-id='80f4b756' name='devname' filepath='kernel/irq/manage.c' line='2043' column='1'/>
-        <parameter type-id='eaa32e2f' name='dev_id' filepath='kernel/irq/manage.c' line='2043' column='1'/>
+      <function-decl name='request_threaded_irq' mangled-name='request_threaded_irq' filepath='kernel/irq/manage.c' line='2042' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='request_threaded_irq'>
+        <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='2042' column='1'/>
+        <parameter type-id='29591c9a' name='handler' filepath='kernel/irq/manage.c' line='2042' column='1'/>
+        <parameter type-id='29591c9a' name='thread_fn' filepath='kernel/irq/manage.c' line='2043' column='1'/>
+        <parameter type-id='7359adad' name='irqflags' filepath='kernel/irq/manage.c' line='2043' column='1'/>
+        <parameter type-id='80f4b756' name='devname' filepath='kernel/irq/manage.c' line='2044' column='1'/>
+        <parameter type-id='eaa32e2f' name='dev_id' filepath='kernel/irq/manage.c' line='2044' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='resched_curr' mangled-name='resched_curr' filepath='kernel/sched/core.c' line='627' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='resched_curr'>
@@ -141433,7 +142219,8 @@
       <function-decl name='rng_is_initialized' mangled-name='rng_is_initialized' filepath='drivers/char/random.c' line='110' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rng_is_initialized'>
         <return type-id='b50a4934'/>
       </function-decl>
-      <var-decl name='root_task_group' type-id='2d863538' mangled-name='root_task_group' visibility='default' filepath='kernel/sched/core.c' line='7442' column='1' elf-symbol-id='root_task_group'/>
+      <var-decl name='root_mem_cgroup' type-id='223696fb' mangled-name='root_mem_cgroup' visibility='default' filepath='mm/memcontrol.c' line='75' column='1' elf-symbol-id='root_mem_cgroup'/>
+      <var-decl name='root_task_group' type-id='2d863538' mangled-name='root_task_group' visibility='default' filepath='kernel/sched/core.c' line='7444' column='1' elf-symbol-id='root_task_group'/>
       <function-decl name='round_jiffies' mangled-name='round_jiffies' filepath='kernel/time/timer.c' line='390' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='round_jiffies'>
         <parameter type-id='7359adad' name='j' filepath='kernel/time/timer.c' line='390' column='1'/>
         <return type-id='7359adad'/>
@@ -141513,8 +142300,8 @@
         <parameter type-id='cc769659' name='chinfo' filepath='drivers/rpmsg/rpmsg_core.c' line='593' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='rproc_add' mangled-name='rproc_add' filepath='drivers/remoteproc/remoteproc_core.c' line='2069' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_add'>
-        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2069' column='1'/>
+      <function-decl name='rproc_add' mangled-name='rproc_add' filepath='drivers/remoteproc/remoteproc_core.c' line='2076' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_add'>
+        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2076' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='rproc_add_carveout' mangled-name='rproc_add_carveout' filepath='drivers/remoteproc/remoteproc_core.c' line='994' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_add_carveout'>
@@ -141522,21 +142309,21 @@
         <parameter type-id='abf87da2' name='mem' filepath='drivers/remoteproc/remoteproc_core.c' line='994' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='rproc_add_subdev' mangled-name='rproc_add_subdev' filepath='drivers/remoteproc/remoteproc_core.c' line='2435' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_add_subdev'>
-        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2435' column='1'/>
-        <parameter type-id='3591079f' name='subdev' filepath='drivers/remoteproc/remoteproc_core.c' line='2435' column='1'/>
+      <function-decl name='rproc_add_subdev' mangled-name='rproc_add_subdev' filepath='drivers/remoteproc/remoteproc_core.c' line='2442' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_add_subdev'>
+        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2442' column='1'/>
+        <parameter type-id='3591079f' name='subdev' filepath='drivers/remoteproc/remoteproc_core.c' line='2442' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='rproc_alloc' mangled-name='rproc_alloc' filepath='drivers/remoteproc/remoteproc_core.c' line='2244' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_alloc'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/remoteproc/remoteproc_core.c' line='2244' column='1'/>
-        <parameter type-id='80f4b756' name='name' filepath='drivers/remoteproc/remoteproc_core.c' line='2244' column='1'/>
-        <parameter type-id='48daa4cd' name='ops' filepath='drivers/remoteproc/remoteproc_core.c' line='2245' column='1'/>
-        <parameter type-id='80f4b756' name='firmware' filepath='drivers/remoteproc/remoteproc_core.c' line='2246' column='1'/>
-        <parameter type-id='95e97e5e' name='len' filepath='drivers/remoteproc/remoteproc_core.c' line='2246' column='1'/>
+      <function-decl name='rproc_alloc' mangled-name='rproc_alloc' filepath='drivers/remoteproc/remoteproc_core.c' line='2251' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_alloc'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/remoteproc/remoteproc_core.c' line='2251' column='1'/>
+        <parameter type-id='80f4b756' name='name' filepath='drivers/remoteproc/remoteproc_core.c' line='2251' column='1'/>
+        <parameter type-id='48daa4cd' name='ops' filepath='drivers/remoteproc/remoteproc_core.c' line='2252' column='1'/>
+        <parameter type-id='80f4b756' name='firmware' filepath='drivers/remoteproc/remoteproc_core.c' line='2253' column='1'/>
+        <parameter type-id='95e97e5e' name='len' filepath='drivers/remoteproc/remoteproc_core.c' line='2253' column='1'/>
         <return type-id='5771c601'/>
       </function-decl>
-      <function-decl name='rproc_boot' mangled-name='rproc_boot' filepath='drivers/remoteproc/remoteproc_core.c' line='1783' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_boot'>
-        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='1783' column='1'/>
+      <function-decl name='rproc_boot' mangled-name='rproc_boot' filepath='drivers/remoteproc/remoteproc_core.c' line='1790' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_boot'>
+        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='1790' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='rproc_coredump' mangled-name='rproc_coredump' filepath='drivers/remoteproc/remoteproc_coredump.c' line='235' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_coredump'>
@@ -141578,8 +142365,8 @@
         <parameter type-id='d8e6b335' name='is_iomem' filepath='drivers/remoteproc/remoteproc_core.c' line='194' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='rproc_del' mangled-name='rproc_del' filepath='drivers/remoteproc/remoteproc_core.c' line='2357' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_del'>
-        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2357' column='1'/>
+      <function-decl name='rproc_del' mangled-name='rproc_del' filepath='drivers/remoteproc/remoteproc_core.c' line='2364' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_del'>
+        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2364' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='rproc_elf_find_loaded_rsc_table' mangled-name='rproc_elf_find_loaded_rsc_table' filepath='drivers/remoteproc/remoteproc_elf_loader.c' line='368' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_elf_find_loaded_rsc_table'>
@@ -141607,16 +142394,16 @@
         <parameter type-id='fce0537d' name='fw' filepath='drivers/remoteproc/remoteproc_elf_loader.c' line='35' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='rproc_free' mangled-name='rproc_free' filepath='drivers/remoteproc/remoteproc_core.c' line='2320' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_free'>
-        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2320' column='1'/>
+      <function-decl name='rproc_free' mangled-name='rproc_free' filepath='drivers/remoteproc/remoteproc_core.c' line='2327' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_free'>
+        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2327' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='rproc_get_by_child' mangled-name='rproc_get_by_child' filepath='drivers/remoteproc/remoteproc_core.c' line='2458' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_get_by_child'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/remoteproc/remoteproc_core.c' line='2458' column='1'/>
+      <function-decl name='rproc_get_by_child' mangled-name='rproc_get_by_child' filepath='drivers/remoteproc/remoteproc_core.c' line='2465' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_get_by_child'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/remoteproc/remoteproc_core.c' line='2465' column='1'/>
         <return type-id='5771c601'/>
       </function-decl>
-      <function-decl name='rproc_get_by_phandle' mangled-name='rproc_get_by_phandle' filepath='drivers/remoteproc/remoteproc_core.c' line='1912' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_get_by_phandle'>
-        <parameter type-id='6e394fba' name='phandle' filepath='drivers/remoteproc/remoteproc_core.c' line='1912' column='1'/>
+      <function-decl name='rproc_get_by_phandle' mangled-name='rproc_get_by_phandle' filepath='drivers/remoteproc/remoteproc_core.c' line='1919' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_get_by_phandle'>
+        <parameter type-id='6e394fba' name='phandle' filepath='drivers/remoteproc/remoteproc_core.c' line='1919' column='1'/>
         <return type-id='5771c601'/>
       </function-decl>
       <function-decl name='rproc_mem_entry_init' mangled-name='rproc_mem_entry_init' filepath='drivers/remoteproc/remoteproc_core.c' line='1016' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_mem_entry_init'>
@@ -141637,27 +142424,27 @@
         <parameter type-id='7d3cd834' name='fw_name' filepath='drivers/remoteproc/remoteproc_core.c' line='1096' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='rproc_put' mangled-name='rproc_put' filepath='drivers/remoteproc/remoteproc_core.c' line='2335' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_put'>
-        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2335' column='1'/>
+      <function-decl name='rproc_put' mangled-name='rproc_put' filepath='drivers/remoteproc/remoteproc_core.c' line='2342' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_put'>
+        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2342' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='rproc_remove_subdev' mangled-name='rproc_remove_subdev' filepath='drivers/remoteproc/remoteproc_core.c' line='2446' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_remove_subdev'>
-        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2446' column='1'/>
-        <parameter type-id='3591079f' name='subdev' filepath='drivers/remoteproc/remoteproc_core.c' line='2446' column='1'/>
+      <function-decl name='rproc_remove_subdev' mangled-name='rproc_remove_subdev' filepath='drivers/remoteproc/remoteproc_core.c' line='2453' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_remove_subdev'>
+        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2453' column='1'/>
+        <parameter type-id='3591079f' name='subdev' filepath='drivers/remoteproc/remoteproc_core.c' line='2453' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='rproc_report_crash' mangled-name='rproc_report_crash' filepath='drivers/remoteproc/remoteproc_core.c' line='2480' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_report_crash'>
-        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2480' column='1'/>
-        <parameter type-id='25751b8f' name='type' filepath='drivers/remoteproc/remoteproc_core.c' line='2480' column='1'/>
+      <function-decl name='rproc_report_crash' mangled-name='rproc_report_crash' filepath='drivers/remoteproc/remoteproc_core.c' line='2487' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_report_crash'>
+        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='2487' column='1'/>
+        <parameter type-id='25751b8f' name='type' filepath='drivers/remoteproc/remoteproc_core.c' line='2487' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='rproc_set_firmware' mangled-name='rproc_set_firmware' filepath='drivers/remoteproc/remoteproc_core.c' line='1967' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_set_firmware'>
-        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='1967' column='1'/>
-        <parameter type-id='80f4b756' name='fw_name' filepath='drivers/remoteproc/remoteproc_core.c' line='1967' column='1'/>
+      <function-decl name='rproc_set_firmware' mangled-name='rproc_set_firmware' filepath='drivers/remoteproc/remoteproc_core.c' line='1974' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_set_firmware'>
+        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='1974' column='1'/>
+        <parameter type-id='80f4b756' name='fw_name' filepath='drivers/remoteproc/remoteproc_core.c' line='1974' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='rproc_shutdown' mangled-name='rproc_shutdown' filepath='drivers/remoteproc/remoteproc_core.c' line='1861' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_shutdown'>
-        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='1861' column='1'/>
+      <function-decl name='rproc_shutdown' mangled-name='rproc_shutdown' filepath='drivers/remoteproc/remoteproc_core.c' line='1868' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_shutdown'>
+        <parameter type-id='5771c601' name='rproc' filepath='drivers/remoteproc/remoteproc_core.c' line='1868' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='rproc_vq_interrupt' mangled-name='rproc_vq_interrupt' filepath='drivers/remoteproc/remoteproc_virtio.c' line='51' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rproc_vq_interrupt'>
@@ -141665,9 +142452,9 @@
         <parameter type-id='95e97e5e' name='notifyid' filepath='drivers/remoteproc/remoteproc_virtio.c' line='51' column='1'/>
         <return type-id='4bdecfd7'/>
       </function-decl>
-      <var-decl name='rps_needed' type-id='237c0d27' mangled-name='rps_needed' visibility='default' filepath='net/core/dev.c' line='4292' column='1' elf-symbol-id='rps_needed'/>
-      <function-decl name='rq_flush_dcache_pages' mangled-name='rq_flush_dcache_pages' filepath='block/blk-core.c' line='1531' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rq_flush_dcache_pages'>
-        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-core.c' line='1531' column='1'/>
+      <var-decl name='rps_needed' type-id='237c0d27' mangled-name='rps_needed' visibility='default' filepath='net/core/dev.c' line='4296' column='1' elf-symbol-id='rps_needed'/>
+      <function-decl name='rq_flush_dcache_pages' mangled-name='rq_flush_dcache_pages' filepath='block/blk-core.c' line='1536' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rq_flush_dcache_pages'>
+        <parameter type-id='3dad1a48' name='rq' filepath='block/blk-core.c' line='1536' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='rsa_parse_priv_key' mangled-name='rsa_parse_priv_key' filepath='crypto/rsa_helper.c' line='181' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rsa_parse_priv_key'>
@@ -141868,11 +142655,11 @@
         <parameter type-id='f8dc9def' name='m' filepath='lib/sbitmap.c' line='613' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='scan_swap_map_slots' mangled-name='scan_swap_map_slots' filepath='mm/swapfile.c' line='775' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scan_swap_map_slots'>
-        <parameter type-id='11e11a61' name='si' filepath='mm/swapfile.c' line='775' column='1'/>
-        <parameter type-id='002ac4a6' name='usage' filepath='mm/swapfile.c' line='776' column='1'/>
-        <parameter type-id='95e97e5e' name='nr' filepath='mm/swapfile.c' line='776' column='1'/>
-        <parameter type-id='57d7488d' name='slots' filepath='mm/swapfile.c' line='777' column='1'/>
+      <function-decl name='scan_swap_map_slots' mangled-name='scan_swap_map_slots' filepath='mm/swapfile.c' line='787' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scan_swap_map_slots'>
+        <parameter type-id='11e11a61' name='si' filepath='mm/swapfile.c' line='787' column='1'/>
+        <parameter type-id='002ac4a6' name='usage' filepath='mm/swapfile.c' line='788' column='1'/>
+        <parameter type-id='95e97e5e' name='nr' filepath='mm/swapfile.c' line='788' column='1'/>
+        <parameter type-id='57d7488d' name='slots' filepath='mm/swapfile.c' line='789' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='scatterwalk_ffwd' mangled-name='scatterwalk_ffwd' filepath='crypto/scatterwalk.c' line='72' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scatterwalk_ffwd'>
@@ -141900,86 +142687,86 @@
       </function-decl>
       <var-decl name='sched_feat_keys' type-id='9cc39ce1' mangled-name='sched_feat_keys' visibility='default' filepath='kernel/sched/debug.c' line='80' column='1' elf-symbol-id='sched_feat_keys'/>
       <var-decl name='sched_feat_names' type-id='3604aecf' mangled-name='sched_feat_names' visibility='default' filepath='kernel/sched/debug.c' line='51' column='1' elf-symbol-id='sched_feat_names'/>
-      <function-decl name='sched_set_fifo' mangled-name='sched_set_fifo' filepath='kernel/sched/core.c' line='5816' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_set_fifo'>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5816' column='1'/>
+      <function-decl name='sched_set_fifo' mangled-name='sched_set_fifo' filepath='kernel/sched/core.c' line='5818' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_set_fifo'>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5818' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='sched_set_fifo_low' mangled-name='sched_set_fifo_low' filepath='kernel/sched/core.c' line='5826' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_set_fifo_low'>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5826' column='1'/>
+      <function-decl name='sched_set_fifo_low' mangled-name='sched_set_fifo_low' filepath='kernel/sched/core.c' line='5828' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_set_fifo_low'>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5828' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='sched_set_normal' mangled-name='sched_set_normal' filepath='kernel/sched/core.c' line='5833' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_set_normal'>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5833' column='1'/>
-        <parameter type-id='95e97e5e' name='nice' filepath='kernel/sched/core.c' line='5833' column='1'/>
+      <function-decl name='sched_set_normal' mangled-name='sched_set_normal' filepath='kernel/sched/core.c' line='5835' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_set_normal'>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5835' column='1'/>
+        <parameter type-id='95e97e5e' name='nice' filepath='kernel/sched/core.c' line='5835' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='sched_setattr' mangled-name='sched_setattr' filepath='kernel/sched/core.c' line='5766' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_setattr'>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5766' column='1'/>
-        <parameter type-id='8abbb6c3' name='attr' filepath='kernel/sched/core.c' line='5766' column='1'/>
+      <function-decl name='sched_setattr' mangled-name='sched_setattr' filepath='kernel/sched/core.c' line='5768' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_setattr'>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5768' column='1'/>
+        <parameter type-id='8abbb6c3' name='attr' filepath='kernel/sched/core.c' line='5768' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sched_setattr_nocheck' mangled-name='sched_setattr_nocheck' filepath='kernel/sched/core.c' line='5772' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_setattr_nocheck'>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5772' column='1'/>
-        <parameter type-id='8abbb6c3' name='attr' filepath='kernel/sched/core.c' line='5772' column='1'/>
+      <function-decl name='sched_setattr_nocheck' mangled-name='sched_setattr_nocheck' filepath='kernel/sched/core.c' line='5774' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_setattr_nocheck'>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5774' column='1'/>
+        <parameter type-id='8abbb6c3' name='attr' filepath='kernel/sched/core.c' line='5774' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sched_setscheduler' mangled-name='sched_setscheduler' filepath='kernel/sched/core.c' line='5759' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_setscheduler'>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5759' column='1'/>
-        <parameter type-id='95e97e5e' name='policy' filepath='kernel/sched/core.c' line='5759' column='1'/>
-        <parameter type-id='36fca399' name='param' filepath='kernel/sched/core.c' line='5760' column='1'/>
+      <function-decl name='sched_setscheduler' mangled-name='sched_setscheduler' filepath='kernel/sched/core.c' line='5761' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_setscheduler'>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5761' column='1'/>
+        <parameter type-id='95e97e5e' name='policy' filepath='kernel/sched/core.c' line='5761' column='1'/>
+        <parameter type-id='36fca399' name='param' filepath='kernel/sched/core.c' line='5762' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sched_setscheduler_nocheck' mangled-name='sched_setscheduler_nocheck' filepath='kernel/sched/core.c' line='5791' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_setscheduler_nocheck'>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5791' column='1'/>
-        <parameter type-id='95e97e5e' name='policy' filepath='kernel/sched/core.c' line='5791' column='1'/>
-        <parameter type-id='36fca399' name='param' filepath='kernel/sched/core.c' line='5792' column='1'/>
+      <function-decl name='sched_setscheduler_nocheck' mangled-name='sched_setscheduler_nocheck' filepath='kernel/sched/core.c' line='5793' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_setscheduler_nocheck'>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5793' column='1'/>
+        <parameter type-id='95e97e5e' name='policy' filepath='kernel/sched/core.c' line='5793' column='1'/>
+        <parameter type-id='36fca399' name='param' filepath='kernel/sched/core.c' line='5794' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sched_show_task' mangled-name='sched_show_task' filepath='kernel/sched/core.c' line='6692' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_show_task'>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='6692' column='1'/>
+      <function-decl name='sched_show_task' mangled-name='sched_show_task' filepath='kernel/sched/core.c' line='6694' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_show_task'>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='6694' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='sched_trace_cfs_rq_avg' mangled-name='sched_trace_cfs_rq_avg' filepath='kernel/sched/fair.c' line='11519' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_cfs_rq_avg'>
-        <parameter type-id='a6892387' name='cfs_rq' filepath='kernel/sched/fair.c' line='11519' column='1'/>
+      <function-decl name='sched_trace_cfs_rq_avg' mangled-name='sched_trace_cfs_rq_avg' filepath='kernel/sched/fair.c' line='11737' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_cfs_rq_avg'>
+        <parameter type-id='a6892387' name='cfs_rq' filepath='kernel/sched/fair.c' line='11737' column='1'/>
         <return type-id='847e6fee'/>
       </function-decl>
-      <function-decl name='sched_trace_cfs_rq_cpu' mangled-name='sched_trace_cfs_rq_cpu' filepath='kernel/sched/fair.c' line='11543' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_cfs_rq_cpu'>
-        <parameter type-id='a6892387' name='cfs_rq' filepath='kernel/sched/fair.c' line='11543' column='1'/>
+      <function-decl name='sched_trace_cfs_rq_cpu' mangled-name='sched_trace_cfs_rq_cpu' filepath='kernel/sched/fair.c' line='11761' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_cfs_rq_cpu'>
+        <parameter type-id='a6892387' name='cfs_rq' filepath='kernel/sched/fair.c' line='11761' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sched_trace_cfs_rq_path' mangled-name='sched_trace_cfs_rq_path' filepath='kernel/sched/fair.c' line='11529' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_cfs_rq_path'>
-        <parameter type-id='a6892387' name='cfs_rq' filepath='kernel/sched/fair.c' line='11529' column='1'/>
-        <parameter type-id='26a90f95' name='str' filepath='kernel/sched/fair.c' line='11529' column='1'/>
-        <parameter type-id='95e97e5e' name='len' filepath='kernel/sched/fair.c' line='11529' column='1'/>
+      <function-decl name='sched_trace_cfs_rq_path' mangled-name='sched_trace_cfs_rq_path' filepath='kernel/sched/fair.c' line='11747' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_cfs_rq_path'>
+        <parameter type-id='a6892387' name='cfs_rq' filepath='kernel/sched/fair.c' line='11747' column='1'/>
+        <parameter type-id='26a90f95' name='str' filepath='kernel/sched/fair.c' line='11747' column='1'/>
+        <parameter type-id='95e97e5e' name='len' filepath='kernel/sched/fair.c' line='11747' column='1'/>
         <return type-id='26a90f95'/>
       </function-decl>
-      <function-decl name='sched_trace_rd_span' mangled-name='sched_trace_rd_span' filepath='kernel/sched/fair.c' line='11597' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_rd_span'>
-        <parameter type-id='c13bca88' name='rd' filepath='kernel/sched/fair.c' line='11597' column='1'/>
+      <function-decl name='sched_trace_rd_span' mangled-name='sched_trace_rd_span' filepath='kernel/sched/fair.c' line='11815' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_rd_span'>
+        <parameter type-id='c13bca88' name='rd' filepath='kernel/sched/fair.c' line='11815' column='1'/>
         <return type-id='5f8a1ac4'/>
       </function-decl>
-      <function-decl name='sched_trace_rq_avg_dl' mangled-name='sched_trace_rq_avg_dl' filepath='kernel/sched/fair.c' line='11559' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_rq_avg_dl'>
-        <parameter type-id='6ed6b432' name='rq' filepath='kernel/sched/fair.c' line='11559' column='1'/>
+      <function-decl name='sched_trace_rq_avg_dl' mangled-name='sched_trace_rq_avg_dl' filepath='kernel/sched/fair.c' line='11777' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_rq_avg_dl'>
+        <parameter type-id='6ed6b432' name='rq' filepath='kernel/sched/fair.c' line='11777' column='1'/>
         <return type-id='847e6fee'/>
       </function-decl>
-      <function-decl name='sched_trace_rq_avg_irq' mangled-name='sched_trace_rq_avg_irq' filepath='kernel/sched/fair.c' line='11569' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_rq_avg_irq'>
-        <parameter type-id='6ed6b432' name='rq' filepath='kernel/sched/fair.c' line='11569' column='1'/>
+      <function-decl name='sched_trace_rq_avg_irq' mangled-name='sched_trace_rq_avg_irq' filepath='kernel/sched/fair.c' line='11787' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_rq_avg_irq'>
+        <parameter type-id='6ed6b432' name='rq' filepath='kernel/sched/fair.c' line='11787' column='1'/>
         <return type-id='847e6fee'/>
       </function-decl>
-      <function-decl name='sched_trace_rq_avg_rt' mangled-name='sched_trace_rq_avg_rt' filepath='kernel/sched/fair.c' line='11549' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_rq_avg_rt'>
-        <parameter type-id='6ed6b432' name='rq' filepath='kernel/sched/fair.c' line='11549' column='1'/>
+      <function-decl name='sched_trace_rq_avg_rt' mangled-name='sched_trace_rq_avg_rt' filepath='kernel/sched/fair.c' line='11767' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_rq_avg_rt'>
+        <parameter type-id='6ed6b432' name='rq' filepath='kernel/sched/fair.c' line='11767' column='1'/>
         <return type-id='847e6fee'/>
       </function-decl>
-      <function-decl name='sched_trace_rq_cpu' mangled-name='sched_trace_rq_cpu' filepath='kernel/sched/fair.c' line='11579' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_rq_cpu'>
-        <parameter type-id='6ed6b432' name='rq' filepath='kernel/sched/fair.c' line='11579' column='1'/>
+      <function-decl name='sched_trace_rq_cpu' mangled-name='sched_trace_rq_cpu' filepath='kernel/sched/fair.c' line='11797' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_trace_rq_cpu'>
+        <parameter type-id='6ed6b432' name='rq' filepath='kernel/sched/fair.c' line='11797' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <var-decl name='sched_uclamp_used' type-id='237c0d27' mangled-name='sched_uclamp_used' visibility='default' filepath='kernel/sched/core.c' line='968' column='1' elf-symbol-id='sched_uclamp_used'/>
-      <function-decl name='schedule' mangled-name='schedule' filepath='kernel/sched/core.c' line='4867' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='schedule'>
+      <function-decl name='schedule' mangled-name='schedule' filepath='kernel/sched/core.c' line='4869' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='schedule'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='schedule_hrtimeout' mangled-name='schedule_hrtimeout' filepath='kernel/time/hrtimer.c' line='2280' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='schedule_hrtimeout'>
-        <parameter type-id='44372936' name='expires' filepath='kernel/time/hrtimer.c' line='2280' column='1'/>
-        <parameter type-id='9bedc94f' name='mode' filepath='kernel/time/hrtimer.c' line='2281' column='1'/>
+      <function-decl name='schedule_hrtimeout' mangled-name='schedule_hrtimeout' filepath='kernel/time/hrtimer.c' line='2282' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='schedule_hrtimeout'>
+        <parameter type-id='44372936' name='expires' filepath='kernel/time/hrtimer.c' line='2282' column='1'/>
+        <parameter type-id='9bedc94f' name='mode' filepath='kernel/time/hrtimer.c' line='2283' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='schedule_timeout' mangled-name='schedule_timeout' filepath='kernel/time/timer.c' line='1844' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='schedule_timeout'>
@@ -142027,10 +142814,10 @@
         <parameter is-variadic='yes'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='scsi_add_host_with_dma' mangled-name='scsi_add_host_with_dma' filepath='drivers/scsi/hosts.c' line='208' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_add_host_with_dma'>
-        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/hosts.c' line='208' column='1'/>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/scsi/hosts.c' line='208' column='1'/>
-        <parameter type-id='fa0b179b' name='dma_dev' filepath='drivers/scsi/hosts.c' line='209' column='1'/>
+      <function-decl name='scsi_add_host_with_dma' mangled-name='scsi_add_host_with_dma' filepath='drivers/scsi/hosts.c' line='209' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_add_host_with_dma'>
+        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/hosts.c' line='209' column='1'/>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/scsi/hosts.c' line='209' column='1'/>
+        <parameter type-id='fa0b179b' name='dma_dev' filepath='drivers/scsi/hosts.c' line='210' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='scsi_autopm_get_device' mangled-name='scsi_autopm_get_device' filepath='drivers/scsi/scsi_pm.c' line='298' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_autopm_get_device'>
@@ -142041,12 +142828,12 @@
         <parameter type-id='eb572b74' name='sdev' filepath='drivers/scsi/scsi_pm.c' line='311' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='scsi_block_requests' mangled-name='scsi_block_requests' filepath='drivers/scsi/scsi_lib.c' line='1955' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_block_requests'>
-        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi_lib.c' line='1955' column='1'/>
+      <function-decl name='scsi_block_requests' mangled-name='scsi_block_requests' filepath='drivers/scsi/scsi_lib.c' line='1957' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_block_requests'>
+        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi_lib.c' line='1957' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='scsi_block_when_processing_errors' mangled-name='scsi_block_when_processing_errors' filepath='drivers/scsi/scsi_error.c' line='342' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_block_when_processing_errors'>
-        <parameter type-id='eb572b74' name='sdev' filepath='drivers/scsi/scsi_error.c' line='342' column='1'/>
+      <function-decl name='scsi_block_when_processing_errors' mangled-name='scsi_block_when_processing_errors' filepath='drivers/scsi/scsi_error.c' line='334' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_block_when_processing_errors'>
+        <parameter type-id='eb572b74' name='sdev' filepath='drivers/scsi/scsi_error.c' line='334' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='scsi_change_queue_depth' mangled-name='scsi_change_queue_depth' filepath='drivers/scsi/scsi.c' line='224' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_change_queue_depth'>
@@ -142061,23 +142848,23 @@
         <parameter type-id='eaa32e2f' name='arg' filepath='drivers/scsi/scsi_ioctl.c' line='288' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='scsi_device_get' mangled-name='scsi_device_get' filepath='drivers/scsi/scsi.c' line='521' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_device_get'>
-        <parameter type-id='eb572b74' name='sdev' filepath='drivers/scsi/scsi.c' line='521' column='1'/>
+      <function-decl name='scsi_device_get' mangled-name='scsi_device_get' filepath='drivers/scsi/scsi.c' line='528' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_device_get'>
+        <parameter type-id='eb572b74' name='sdev' filepath='drivers/scsi/scsi.c' line='528' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='scsi_device_lookup' mangled-name='scsi_device_lookup' filepath='drivers/scsi/scsi.c' line='733' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_device_lookup'>
-        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi.c' line='733' column='1'/>
-        <parameter type-id='6e160b14' name='channel' filepath='drivers/scsi/scsi.c' line='734' column='1'/>
-        <parameter type-id='6e160b14' name='id' filepath='drivers/scsi/scsi.c' line='734' column='1'/>
-        <parameter type-id='91ce1af9' name='lun' filepath='drivers/scsi/scsi.c' line='734' column='1'/>
+      <function-decl name='scsi_device_lookup' mangled-name='scsi_device_lookup' filepath='drivers/scsi/scsi.c' line='740' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_device_lookup'>
+        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi.c' line='740' column='1'/>
+        <parameter type-id='6e160b14' name='channel' filepath='drivers/scsi/scsi.c' line='741' column='1'/>
+        <parameter type-id='6e160b14' name='id' filepath='drivers/scsi/scsi.c' line='741' column='1'/>
+        <parameter type-id='91ce1af9' name='lun' filepath='drivers/scsi/scsi.c' line='741' column='1'/>
         <return type-id='eb572b74'/>
       </function-decl>
-      <function-decl name='scsi_device_put' mangled-name='scsi_device_put' filepath='drivers/scsi/scsi.c' line='546' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_device_put'>
-        <parameter type-id='eb572b74' name='sdev' filepath='drivers/scsi/scsi.c' line='546' column='1'/>
+      <function-decl name='scsi_device_put' mangled-name='scsi_device_put' filepath='drivers/scsi/scsi.c' line='553' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_device_put'>
+        <parameter type-id='eb572b74' name='sdev' filepath='drivers/scsi/scsi.c' line='553' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='scsi_device_quiesce' mangled-name='scsi_device_quiesce' filepath='drivers/scsi/scsi_lib.c' line='2528' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_device_quiesce'>
-        <parameter type-id='eb572b74' name='sdev' filepath='drivers/scsi/scsi_lib.c' line='2528' column='1'/>
+      <function-decl name='scsi_device_quiesce' mangled-name='scsi_device_quiesce' filepath='drivers/scsi/scsi_lib.c' line='2530' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_device_quiesce'>
+        <parameter type-id='eb572b74' name='sdev' filepath='drivers/scsi/scsi_lib.c' line='2530' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='scsi_dma_map' mangled-name='scsi_dma_map' filepath='drivers/scsi/scsi_lib_dma.c' line='23' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_dma_map'>
@@ -142088,23 +142875,23 @@
         <parameter type-id='0b8718c0' name='cmd' filepath='drivers/scsi/scsi_lib_dma.c' line='43' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='scsi_eh_ready_devs' mangled-name='scsi_eh_ready_devs' filepath='drivers/scsi/scsi_error.c' line='2083' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_eh_ready_devs'>
-        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi_error.c' line='2083' column='1'/>
-        <parameter type-id='e84b031a' name='work_q' filepath='drivers/scsi/scsi_error.c' line='2084' column='1'/>
-        <parameter type-id='e84b031a' name='done_q' filepath='drivers/scsi/scsi_error.c' line='2085' column='1'/>
+      <function-decl name='scsi_eh_ready_devs' mangled-name='scsi_eh_ready_devs' filepath='drivers/scsi/scsi_error.c' line='2075' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_eh_ready_devs'>
+        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi_error.c' line='2075' column='1'/>
+        <parameter type-id='e84b031a' name='work_q' filepath='drivers/scsi/scsi_error.c' line='2076' column='1'/>
+        <parameter type-id='e84b031a' name='done_q' filepath='drivers/scsi/scsi_error.c' line='2077' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='scsi_host_alloc' mangled-name='scsi_host_alloc' filepath='drivers/scsi/hosts.c' line='377' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_host_alloc'>
-        <parameter type-id='36265581' name='sht' filepath='drivers/scsi/hosts.c' line='377' column='1'/>
-        <parameter type-id='95e97e5e' name='privsize' filepath='drivers/scsi/hosts.c' line='377' column='1'/>
+      <function-decl name='scsi_host_alloc' mangled-name='scsi_host_alloc' filepath='drivers/scsi/hosts.c' line='376' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_host_alloc'>
+        <parameter type-id='36265581' name='sht' filepath='drivers/scsi/hosts.c' line='376' column='1'/>
+        <parameter type-id='95e97e5e' name='privsize' filepath='drivers/scsi/hosts.c' line='376' column='1'/>
         <return type-id='a970a64c'/>
       </function-decl>
-      <function-decl name='scsi_host_lookup' mangled-name='scsi_host_lookup' filepath='drivers/scsi/hosts.c' line='543' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_host_lookup'>
-        <parameter type-id='8efea9e5' name='hostnum' filepath='drivers/scsi/hosts.c' line='543' column='1'/>
+      <function-decl name='scsi_host_lookup' mangled-name='scsi_host_lookup' filepath='drivers/scsi/hosts.c' line='542' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_host_lookup'>
+        <parameter type-id='8efea9e5' name='hostnum' filepath='drivers/scsi/hosts.c' line='542' column='1'/>
         <return type-id='a970a64c'/>
       </function-decl>
-      <function-decl name='scsi_host_put' mangled-name='scsi_host_put' filepath='drivers/scsi/hosts.c' line='601' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_host_put'>
-        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/hosts.c' line='601' column='1'/>
+      <function-decl name='scsi_host_put' mangled-name='scsi_host_put' filepath='drivers/scsi/hosts.c' line='600' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_host_put'>
+        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/hosts.c' line='600' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='scsi_ioctl' mangled-name='scsi_ioctl' filepath='drivers/scsi/scsi_ioctl.c' line='273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_ioctl'>
@@ -142119,8 +142906,8 @@
         <parameter type-id='b50a4934' name='ndelay' filepath='drivers/scsi/scsi_ioctl.c' line='307' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='scsi_is_host_device' mangled-name='scsi_is_host_device' filepath='drivers/scsi/hosts.c' line='618' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_is_host_device'>
-        <parameter type-id='8df61054' name='dev' filepath='drivers/scsi/hosts.c' line='618' column='1'/>
+      <function-decl name='scsi_is_host_device' mangled-name='scsi_is_host_device' filepath='drivers/scsi/hosts.c' line='617' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_is_host_device'>
+        <parameter type-id='8df61054' name='dev' filepath='drivers/scsi/hosts.c' line='617' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='scsi_normalize_sense' mangled-name='scsi_normalize_sense' filepath='drivers/scsi/scsi_common.c' line='138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_normalize_sense'>
@@ -142155,17 +142942,17 @@
         <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/hosts.c' line='164' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='scsi_report_bus_reset' mangled-name='scsi_report_bus_reset' filepath='drivers/scsi/scsi_error.c' line='2287' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_report_bus_reset'>
-        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi_error.c' line='2287' column='1'/>
-        <parameter type-id='95e97e5e' name='channel' filepath='drivers/scsi/scsi_error.c' line='2287' column='1'/>
+      <function-decl name='scsi_report_bus_reset' mangled-name='scsi_report_bus_reset' filepath='drivers/scsi/scsi_error.c' line='2279' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_report_bus_reset'>
+        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi_error.c' line='2279' column='1'/>
+        <parameter type-id='95e97e5e' name='channel' filepath='drivers/scsi/scsi_error.c' line='2279' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='scsi_scan_host' mangled-name='scsi_scan_host' filepath='drivers/scsi/scsi_scan.c' line='1836' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_scan_host'>
-        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi_scan.c' line='1836' column='1'/>
+      <function-decl name='scsi_scan_host' mangled-name='scsi_scan_host' filepath='drivers/scsi/scsi_scan.c' line='1835' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_scan_host'>
+        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi_scan.c' line='1835' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='scsi_unblock_requests' mangled-name='scsi_unblock_requests' filepath='drivers/scsi/scsi_lib.c' line='1971' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_unblock_requests'>
-        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi_lib.c' line='1971' column='1'/>
+      <function-decl name='scsi_unblock_requests' mangled-name='scsi_unblock_requests' filepath='drivers/scsi/scsi_lib.c' line='1973' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='scsi_unblock_requests'>
+        <parameter type-id='a970a64c' name='shost' filepath='drivers/scsi/scsi_lib.c' line='1973' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='sdev_prefix_printk' mangled-name='sdev_prefix_printk' filepath='drivers/scsi/scsi_logging.c' line='53' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sdev_prefix_printk'>
@@ -142647,49 +143434,49 @@
         <parameter type-id='97fbef77' name='serdev' filepath='drivers/tty/serdev/core.c' line='237' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='serial8250_clear_and_reinit_fifos' mangled-name='serial8250_clear_and_reinit_fifos' filepath='drivers/tty/serial/8250/8250_port.c' line='548' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_clear_and_reinit_fifos'>
-        <parameter type-id='b26c7631' name='p' filepath='drivers/tty/serial/8250/8250_port.c' line='548' column='1'/>
+      <function-decl name='serial8250_clear_and_reinit_fifos' mangled-name='serial8250_clear_and_reinit_fifos' filepath='drivers/tty/serial/8250/8250_port.c' line='549' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_clear_and_reinit_fifos'>
+        <parameter type-id='b26c7631' name='p' filepath='drivers/tty/serial/8250/8250_port.c' line='549' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='serial8250_do_pm' mangled-name='serial8250_do_pm' filepath='drivers/tty/serial/8250/8250_port.c' line='2879' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_do_pm'>
-        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='2879' column='1'/>
-        <parameter type-id='f0981eeb' name='state' filepath='drivers/tty/serial/8250/8250_port.c' line='2879' column='1'/>
-        <parameter type-id='f0981eeb' name='oldstate' filepath='drivers/tty/serial/8250/8250_port.c' line='2880' column='1'/>
+      <function-decl name='serial8250_do_pm' mangled-name='serial8250_do_pm' filepath='drivers/tty/serial/8250/8250_port.c' line='2889' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_do_pm'>
+        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='2889' column='1'/>
+        <parameter type-id='f0981eeb' name='state' filepath='drivers/tty/serial/8250/8250_port.c' line='2889' column='1'/>
+        <parameter type-id='f0981eeb' name='oldstate' filepath='drivers/tty/serial/8250/8250_port.c' line='2890' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='serial8250_do_set_divisor' mangled-name='serial8250_do_set_divisor' filepath='drivers/tty/serial/8250/8250_port.c' line='2582' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_do_set_divisor'>
-        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='2582' column='1'/>
-        <parameter type-id='f0981eeb' name='baud' filepath='drivers/tty/serial/8250/8250_port.c' line='2582' column='1'/>
-        <parameter type-id='f0981eeb' name='quot' filepath='drivers/tty/serial/8250/8250_port.c' line='2583' column='1'/>
-        <parameter type-id='f0981eeb' name='quot_frac' filepath='drivers/tty/serial/8250/8250_port.c' line='2583' column='1'/>
+      <function-decl name='serial8250_do_set_divisor' mangled-name='serial8250_do_set_divisor' filepath='drivers/tty/serial/8250/8250_port.c' line='2592' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_do_set_divisor'>
+        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='2592' column='1'/>
+        <parameter type-id='f0981eeb' name='baud' filepath='drivers/tty/serial/8250/8250_port.c' line='2592' column='1'/>
+        <parameter type-id='f0981eeb' name='quot' filepath='drivers/tty/serial/8250/8250_port.c' line='2593' column='1'/>
+        <parameter type-id='f0981eeb' name='quot_frac' filepath='drivers/tty/serial/8250/8250_port.c' line='2593' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='serial8250_do_set_ldisc' mangled-name='serial8250_do_set_ldisc' filepath='drivers/tty/serial/8250/8250_port.c' line='2852' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_do_set_ldisc'>
-        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='2852' column='1'/>
-        <parameter type-id='e55856e5' name='termios' filepath='drivers/tty/serial/8250/8250_port.c' line='2852' column='1'/>
+      <function-decl name='serial8250_do_set_ldisc' mangled-name='serial8250_do_set_ldisc' filepath='drivers/tty/serial/8250/8250_port.c' line='2862' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_do_set_ldisc'>
+        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='2862' column='1'/>
+        <parameter type-id='e55856e5' name='termios' filepath='drivers/tty/serial/8250/8250_port.c' line='2862' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='serial8250_do_set_termios' mangled-name='serial8250_do_set_termios' filepath='drivers/tty/serial/8250/8250_port.c' line='2705' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_do_set_termios'>
-        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='2705' column='1'/>
-        <parameter type-id='e55856e5' name='termios' filepath='drivers/tty/serial/8250/8250_port.c' line='2705' column='1'/>
-        <parameter type-id='e55856e5' name='old' filepath='drivers/tty/serial/8250/8250_port.c' line='2706' column='1'/>
+      <function-decl name='serial8250_do_set_termios' mangled-name='serial8250_do_set_termios' filepath='drivers/tty/serial/8250/8250_port.c' line='2715' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_do_set_termios'>
+        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='2715' column='1'/>
+        <parameter type-id='e55856e5' name='termios' filepath='drivers/tty/serial/8250/8250_port.c' line='2715' column='1'/>
+        <parameter type-id='e55856e5' name='old' filepath='drivers/tty/serial/8250/8250_port.c' line='2716' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='serial8250_do_shutdown' mangled-name='serial8250_do_shutdown' filepath='drivers/tty/serial/8250/8250_port.c' line='2430' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_do_shutdown'>
-        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='2430' column='1'/>
+      <function-decl name='serial8250_do_shutdown' mangled-name='serial8250_do_shutdown' filepath='drivers/tty/serial/8250/8250_port.c' line='2440' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_do_shutdown'>
+        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='2440' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='serial8250_do_startup' mangled-name='serial8250_do_startup' filepath='drivers/tty/serial/8250/8250_port.c' line='2144' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_do_startup'>
-        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='2144' column='1'/>
+      <function-decl name='serial8250_do_startup' mangled-name='serial8250_do_startup' filepath='drivers/tty/serial/8250/8250_port.c' line='2154' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_do_startup'>
+        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='2154' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='serial8250_get_port' mangled-name='serial8250_get_port' filepath='drivers/tty/serial/8250/8250_core.c' line='412' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_get_port'>
         <parameter type-id='95e97e5e' name='line' filepath='drivers/tty/serial/8250/8250_core.c' line='412' column='1'/>
         <return type-id='b26c7631'/>
       </function-decl>
-      <function-decl name='serial8250_handle_irq' mangled-name='serial8250_handle_irq' filepath='drivers/tty/serial/8250/8250_port.c' line='1886' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_handle_irq'>
-        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='1886' column='1'/>
-        <parameter type-id='f0981eeb' name='iir' filepath='drivers/tty/serial/8250/8250_port.c' line='1886' column='1'/>
+      <function-decl name='serial8250_handle_irq' mangled-name='serial8250_handle_irq' filepath='drivers/tty/serial/8250/8250_port.c' line='1887' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_handle_irq'>
+        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='1887' column='1'/>
+        <parameter type-id='f0981eeb' name='iir' filepath='drivers/tty/serial/8250/8250_port.c' line='1887' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='serial8250_register_8250_port' mangled-name='serial8250_register_8250_port' filepath='drivers/tty/serial/8250/8250_core.c' line='988' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_register_8250_port'>
@@ -142700,12 +143487,12 @@
         <parameter type-id='95e97e5e' name='line' filepath='drivers/tty/serial/8250/8250_core.c' line='785' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='serial8250_rpm_get' mangled-name='serial8250_rpm_get' filepath='drivers/tty/serial/8250/8250_port.c' line='555' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_rpm_get'>
-        <parameter type-id='b26c7631' name='p' filepath='drivers/tty/serial/8250/8250_port.c' line='555' column='1'/>
+      <function-decl name='serial8250_rpm_get' mangled-name='serial8250_rpm_get' filepath='drivers/tty/serial/8250/8250_port.c' line='556' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_rpm_get'>
+        <parameter type-id='b26c7631' name='p' filepath='drivers/tty/serial/8250/8250_port.c' line='556' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='serial8250_rpm_put' mangled-name='serial8250_rpm_put' filepath='drivers/tty/serial/8250/8250_port.c' line='563' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_rpm_put'>
-        <parameter type-id='b26c7631' name='p' filepath='drivers/tty/serial/8250/8250_port.c' line='563' column='1'/>
+      <function-decl name='serial8250_rpm_put' mangled-name='serial8250_rpm_put' filepath='drivers/tty/serial/8250/8250_port.c' line='564' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_rpm_put'>
+        <parameter type-id='b26c7631' name='p' filepath='drivers/tty/serial/8250/8250_port.c' line='564' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='serial8250_suspend_port' mangled-name='serial8250_suspend_port' filepath='drivers/tty/serial/8250/8250_core.c' line='761' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_suspend_port'>
@@ -142716,9 +143503,9 @@
         <parameter type-id='95e97e5e' name='line' filepath='drivers/tty/serial/8250/8250_core.c' line='1142' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='serial8250_update_uartclk' mangled-name='serial8250_update_uartclk' filepath='drivers/tty/serial/8250/8250_port.c' line='2653' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_update_uartclk'>
-        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='2653' column='1'/>
-        <parameter type-id='f0981eeb' name='uartclk' filepath='drivers/tty/serial/8250/8250_port.c' line='2653' column='1'/>
+      <function-decl name='serial8250_update_uartclk' mangled-name='serial8250_update_uartclk' filepath='drivers/tty/serial/8250/8250_port.c' line='2663' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serial8250_update_uartclk'>
+        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/8250/8250_port.c' line='2663' column='1'/>
+        <parameter type-id='f0981eeb' name='uartclk' filepath='drivers/tty/serial/8250/8250_port.c' line='2663' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='serio_close' mangled-name='serio_close' filepath='drivers/input/serio/serio.c' line='984' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='serio_close'>
@@ -142773,9 +143560,9 @@
         <parameter type-id='b50a4934' name='update_bdev' filepath='block/genhd.c' line='53' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='set_cpus_allowed_ptr' mangled-name='set_cpus_allowed_ptr' filepath='kernel/sched/core.c' line='2078' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='set_cpus_allowed_ptr'>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='2078' column='1'/>
-        <parameter type-id='5f8a1ac4' name='new_mask' filepath='kernel/sched/core.c' line='2078' column='1'/>
+      <function-decl name='set_cpus_allowed_ptr' mangled-name='set_cpus_allowed_ptr' filepath='kernel/sched/core.c' line='2081' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='set_cpus_allowed_ptr'>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='2081' column='1'/>
+        <parameter type-id='5f8a1ac4' name='new_mask' filepath='kernel/sched/core.c' line='2081' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='set_disk_ro' mangled-name='set_disk_ro' filepath='block/genhd.c' line='1857' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='set_disk_ro'>
@@ -142805,9 +143592,9 @@
         <parameter type-id='02f11ed4' name='page' filepath='mm/page-writeback.c' line='2606' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='set_task_cpu' mangled-name='set_task_cpu' filepath='kernel/sched/core.c' line='2152' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='set_task_cpu'>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='2152' column='1'/>
-        <parameter type-id='f0981eeb' name='new_cpu' filepath='kernel/sched/core.c' line='2152' column='1'/>
+      <function-decl name='set_task_cpu' mangled-name='set_task_cpu' filepath='kernel/sched/core.c' line='2155' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='set_task_cpu'>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='2155' column='1'/>
+        <parameter type-id='f0981eeb' name='new_cpu' filepath='kernel/sched/core.c' line='2155' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='set_task_ioprio' mangled-name='set_task_ioprio' filepath='block/ioprio.c' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='set_task_ioprio'>
@@ -142815,14 +143602,14 @@
         <parameter type-id='95e97e5e' name='ioprio' filepath='block/ioprio.c' line='36' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='set_user_nice' mangled-name='set_user_nice' filepath='kernel/sched/core.c' line='5236' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='set_user_nice'>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5236' column='1'/>
-        <parameter type-id='bd54fe1a' name='nice' filepath='kernel/sched/core.c' line='5236' column='1'/>
+      <function-decl name='set_user_nice' mangled-name='set_user_nice' filepath='kernel/sched/core.c' line='5238' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='set_user_nice'>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5238' column='1'/>
+        <parameter type-id='bd54fe1a' name='nice' filepath='kernel/sched/core.c' line='5238' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='setattr_prepare' mangled-name='setattr_prepare' filepath='fs/attr.c' line='61' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='setattr_prepare'>
-        <parameter type-id='27675065' name='dentry' filepath='fs/attr.c' line='61' column='1'/>
-        <parameter type-id='ab7bbd67' name='attr' filepath='fs/attr.c' line='61' column='1'/>
+      <function-decl name='setattr_prepare' mangled-name='setattr_prepare' filepath='fs/attr.c' line='120' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='setattr_prepare'>
+        <parameter type-id='27675065' name='dentry' filepath='fs/attr.c' line='120' column='1'/>
+        <parameter type-id='ab7bbd67' name='attr' filepath='fs/attr.c' line='120' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='sg_alloc_table' mangled-name='sg_alloc_table' filepath='lib/scatterlist.c' line='355' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sg_alloc_table'>
@@ -143035,21 +143822,21 @@
         <parameter type-id='95e97e5e' name='priority' filepath='mm/vmscan.c' line='675' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='si_mem_available' mangled-name='si_mem_available' filepath='mm/page_alloc.c' line='5522' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='si_mem_available'>
+      <function-decl name='si_mem_available' mangled-name='si_mem_available' filepath='mm/page_alloc.c' line='5554' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='si_mem_available'>
         <return type-id='bd54fe1a'/>
       </function-decl>
-      <function-decl name='si_meminfo' mangled-name='si_meminfo' filepath='mm/page_alloc.c' line='5568' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='si_meminfo'>
-        <parameter type-id='0f561784' name='val' filepath='mm/page_alloc.c' line='5568' column='1'/>
+      <function-decl name='si_meminfo' mangled-name='si_meminfo' filepath='mm/page_alloc.c' line='5600' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='si_meminfo'>
+        <parameter type-id='0f561784' name='val' filepath='mm/page_alloc.c' line='5600' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='si_swapinfo' mangled-name='si_swapinfo' filepath='mm/swapfile.c' line='3454' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='si_swapinfo'>
-        <parameter type-id='0f561784' name='val' filepath='mm/swapfile.c' line='3454' column='1'/>
+      <function-decl name='si_swapinfo' mangled-name='si_swapinfo' filepath='mm/swapfile.c' line='3469' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='si_swapinfo'>
+        <parameter type-id='0f561784' name='val' filepath='mm/swapfile.c' line='3469' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='sigprocmask' mangled-name='sigprocmask' filepath='kernel/signal.c' line='2977' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sigprocmask'>
-        <parameter type-id='95e97e5e' name='how' filepath='kernel/signal.c' line='2977' column='1'/>
-        <parameter type-id='9e80f729' name='set' filepath='kernel/signal.c' line='2977' column='1'/>
-        <parameter type-id='9e80f729' name='oldset' filepath='kernel/signal.c' line='2977' column='1'/>
+      <function-decl name='sigprocmask' mangled-name='sigprocmask' filepath='kernel/signal.c' line='2980' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sigprocmask'>
+        <parameter type-id='95e97e5e' name='how' filepath='kernel/signal.c' line='2980' column='1'/>
+        <parameter type-id='9e80f729' name='set' filepath='kernel/signal.c' line='2980' column='1'/>
+        <parameter type-id='9e80f729' name='oldset' filepath='kernel/signal.c' line='2980' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='simple_attr_open' mangled-name='simple_attr_open' filepath='fs/libfs.c' line='890' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='simple_attr_open'>
@@ -143072,11 +143859,11 @@
         <parameter type-id='77e79a4b' name='file' filepath='fs/libfs.c' line='912' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='simple_attr_write' mangled-name='simple_attr_write' filepath='fs/libfs.c' line='958' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='simple_attr_write'>
-        <parameter type-id='77e79a4b' name='file' filepath='fs/libfs.c' line='958' column='1'/>
-        <parameter type-id='80f4b756' name='buf' filepath='fs/libfs.c' line='958' column='1'/>
-        <parameter type-id='b59d7dce' name='len' filepath='fs/libfs.c' line='959' column='1'/>
-        <parameter type-id='b53e8dbb' name='ppos' filepath='fs/libfs.c' line='959' column='1'/>
+      <function-decl name='simple_attr_write' mangled-name='simple_attr_write' filepath='fs/libfs.c' line='994' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='simple_attr_write'>
+        <parameter type-id='77e79a4b' name='file' filepath='fs/libfs.c' line='994' column='1'/>
+        <parameter type-id='80f4b756' name='buf' filepath='fs/libfs.c' line='994' column='1'/>
+        <parameter type-id='b59d7dce' name='len' filepath='fs/libfs.c' line='995' column='1'/>
+        <parameter type-id='b53e8dbb' name='ppos' filepath='fs/libfs.c' line='995' column='1'/>
         <return type-id='79a0948f'/>
       </function-decl>
       <var-decl name='simple_dir_inode_operations' type-id='c8e0fb8e' mangled-name='simple_dir_inode_operations' visibility='default' filepath='fs/libfs.c' line='240' column='1' elf-symbol-id='simple_dir_inode_operations'/>
@@ -143099,7 +143886,7 @@
         <parameter type-id='087d687b' name='buf' filepath='fs/libfs.c' line='40' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='simple_strtol' mangled-name='simple_strtol' filepath='include/linux/kernel.h' line='467' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='simple_strtol'>
+      <function-decl name='simple_strtol' mangled-name='simple_strtol' filepath='include/linux/kstrtox.h' line='146' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='simple_strtol'>
         <parameter type-id='80f4b756'/>
         <parameter type-id='9b23c9ad'/>
         <parameter type-id='f0981eeb'/>
@@ -143117,7 +143904,7 @@
         <parameter type-id='f0981eeb' name='base' filepath='lib/vsprintf.c' line='107' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='simple_strtoull' mangled-name='simple_strtoull' filepath='include/linux/kernel.h' line='468' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='simple_strtoull'>
+      <function-decl name='simple_strtoull' mangled-name='simple_strtoull' filepath='include/linux/kstrtox.h' line='147' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='simple_strtoull'>
         <parameter type-id='80f4b756'/>
         <parameter type-id='9b23c9ad'/>
         <parameter type-id='f0981eeb'/>
@@ -143149,16 +143936,16 @@
         <parameter type-id='77e79a4b' name='file' filepath='fs/seq_file.c' line='600' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sk_alloc' mangled-name='sk_alloc' filepath='net/core/sock.c' line='1741' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sk_alloc'>
-        <parameter type-id='a2bff676' name='net' filepath='net/core/sock.c' line='1741' column='1'/>
-        <parameter type-id='95e97e5e' name='family' filepath='net/core/sock.c' line='1741' column='1'/>
-        <parameter type-id='3eb7c31c' name='priority' filepath='net/core/sock.c' line='1741' column='1'/>
-        <parameter type-id='d2524501' name='prot' filepath='net/core/sock.c' line='1742' column='1'/>
-        <parameter type-id='95e97e5e' name='kern' filepath='net/core/sock.c' line='1742' column='1'/>
+      <function-decl name='sk_alloc' mangled-name='sk_alloc' filepath='net/core/sock.c' line='1748' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sk_alloc'>
+        <parameter type-id='a2bff676' name='net' filepath='net/core/sock.c' line='1748' column='1'/>
+        <parameter type-id='95e97e5e' name='family' filepath='net/core/sock.c' line='1748' column='1'/>
+        <parameter type-id='3eb7c31c' name='priority' filepath='net/core/sock.c' line='1748' column='1'/>
+        <parameter type-id='d2524501' name='prot' filepath='net/core/sock.c' line='1749' column='1'/>
+        <parameter type-id='95e97e5e' name='kern' filepath='net/core/sock.c' line='1749' column='1'/>
         <return type-id='f772df6d'/>
       </function-decl>
-      <function-decl name='sk_free' mangled-name='sk_free' filepath='net/core/sock.c' line='1844' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sk_free'>
-        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='1844' column='1'/>
+      <function-decl name='sk_free' mangled-name='sk_free' filepath='net/core/sock.c' line='1851' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sk_free'>
+        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='1851' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='skb_add_rx_frag' mangled-name='skb_add_rx_frag' filepath='net/core/skbuff.c' line='557' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_add_rx_frag'>
@@ -143170,27 +143957,27 @@
         <parameter type-id='f0981eeb' name='truesize' filepath='net/core/skbuff.c' line='558' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='skb_append_pagefrags' mangled-name='skb_append_pagefrags' filepath='net/core/skbuff.c' line='3640' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_append_pagefrags'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='3640' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='net/core/skbuff.c' line='3640' column='1'/>
-        <parameter type-id='95e97e5e' name='offset' filepath='net/core/skbuff.c' line='3641' column='1'/>
-        <parameter type-id='b59d7dce' name='size' filepath='net/core/skbuff.c' line='3641' column='1'/>
+      <function-decl name='skb_append_pagefrags' mangled-name='skb_append_pagefrags' filepath='net/core/skbuff.c' line='3642' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_append_pagefrags'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='3642' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='net/core/skbuff.c' line='3642' column='1'/>
+        <parameter type-id='95e97e5e' name='offset' filepath='net/core/skbuff.c' line='3643' column='1'/>
+        <parameter type-id='b59d7dce' name='size' filepath='net/core/skbuff.c' line='3643' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='skb_checksum' mangled-name='skb_checksum' filepath='net/core/skbuff.c' line='2760' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_checksum'>
-        <parameter type-id='11f4a000' name='skb' filepath='net/core/skbuff.c' line='2760' column='1'/>
-        <parameter type-id='95e97e5e' name='offset' filepath='net/core/skbuff.c' line='2760' column='1'/>
-        <parameter type-id='95e97e5e' name='len' filepath='net/core/skbuff.c' line='2761' column='1'/>
-        <parameter type-id='fbd88bba' name='csum' filepath='net/core/skbuff.c' line='2761' column='1'/>
+      <function-decl name='skb_checksum' mangled-name='skb_checksum' filepath='net/core/skbuff.c' line='2762' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_checksum'>
+        <parameter type-id='11f4a000' name='skb' filepath='net/core/skbuff.c' line='2762' column='1'/>
+        <parameter type-id='95e97e5e' name='offset' filepath='net/core/skbuff.c' line='2762' column='1'/>
+        <parameter type-id='95e97e5e' name='len' filepath='net/core/skbuff.c' line='2763' column='1'/>
+        <parameter type-id='fbd88bba' name='csum' filepath='net/core/skbuff.c' line='2763' column='1'/>
         <return type-id='fbd88bba'/>
       </function-decl>
-      <function-decl name='skb_checksum_help' mangled-name='skb_checksum_help' filepath='net/core/dev.c' line='3226' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_checksum_help'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='3226' column='1'/>
+      <function-decl name='skb_checksum_help' mangled-name='skb_checksum_help' filepath='net/core/dev.c' line='3230' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_checksum_help'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/dev.c' line='3230' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='skb_clone' mangled-name='skb_clone' filepath='net/core/skbuff.c' line='1441' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_clone'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1441' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='1441' column='1'/>
+      <function-decl name='skb_clone' mangled-name='skb_clone' filepath='net/core/skbuff.c' line='1440' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_clone'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1440' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='1440' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
       <function-decl name='skb_clone_sk' mangled-name='skb_clone_sk' filepath='net/core/skbuff.c' line='4663' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_clone_sk'>
@@ -143204,21 +143991,21 @@
         <parameter type-id='f0981eeb' name='truesize' filepath='net/core/skbuff.c' line='568' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='skb_complete_wifi_ack' mangled-name='skb_complete_wifi_ack' filepath='net/core/skbuff.c' line='4808' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_complete_wifi_ack'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='4808' column='1'/>
-        <parameter type-id='b50a4934' name='acked' filepath='net/core/skbuff.c' line='4808' column='1'/>
+      <function-decl name='skb_complete_wifi_ack' mangled-name='skb_complete_wifi_ack' filepath='net/core/skbuff.c' line='4813' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_complete_wifi_ack'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='4813' column='1'/>
+        <parameter type-id='b50a4934' name='acked' filepath='net/core/skbuff.c' line='4813' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='skb_copy' mangled-name='skb_copy' filepath='net/core/skbuff.c' line='1520' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_copy'>
-        <parameter type-id='11f4a000' name='skb' filepath='net/core/skbuff.c' line='1520' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='1520' column='1'/>
+      <function-decl name='skb_copy' mangled-name='skb_copy' filepath='net/core/skbuff.c' line='1519' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_copy'>
+        <parameter type-id='11f4a000' name='skb' filepath='net/core/skbuff.c' line='1519' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='1519' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
-      <function-decl name='skb_copy_bits' mangled-name='skb_copy_bits' filepath='net/core/skbuff.c' line='2236' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_copy_bits'>
-        <parameter type-id='11f4a000' name='skb' filepath='net/core/skbuff.c' line='2236' column='1'/>
-        <parameter type-id='95e97e5e' name='offset' filepath='net/core/skbuff.c' line='2236' column='1'/>
-        <parameter type-id='eaa32e2f' name='to' filepath='net/core/skbuff.c' line='2236' column='1'/>
-        <parameter type-id='95e97e5e' name='len' filepath='net/core/skbuff.c' line='2236' column='1'/>
+      <function-decl name='skb_copy_bits' mangled-name='skb_copy_bits' filepath='net/core/skbuff.c' line='2238' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_copy_bits'>
+        <parameter type-id='11f4a000' name='skb' filepath='net/core/skbuff.c' line='2238' column='1'/>
+        <parameter type-id='95e97e5e' name='offset' filepath='net/core/skbuff.c' line='2238' column='1'/>
+        <parameter type-id='eaa32e2f' name='to' filepath='net/core/skbuff.c' line='2238' column='1'/>
+        <parameter type-id='95e97e5e' name='len' filepath='net/core/skbuff.c' line='2238' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='skb_copy_datagram_from_iter' mangled-name='skb_copy_datagram_from_iter' filepath='net/core/datagram.c' line='547' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_copy_datagram_from_iter'>
@@ -143235,35 +144022,35 @@
         <parameter type-id='95e97e5e' name='len' filepath='net/core/datagram.c' line='530' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='skb_copy_expand' mangled-name='skb_copy_expand' filepath='net/core/skbuff.c' line='1780' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_copy_expand'>
-        <parameter type-id='11f4a000' name='skb' filepath='net/core/skbuff.c' line='1780' column='1'/>
-        <parameter type-id='95e97e5e' name='newheadroom' filepath='net/core/skbuff.c' line='1781' column='1'/>
-        <parameter type-id='95e97e5e' name='newtailroom' filepath='net/core/skbuff.c' line='1781' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='1782' column='1'/>
+      <function-decl name='skb_copy_expand' mangled-name='skb_copy_expand' filepath='net/core/skbuff.c' line='1779' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_copy_expand'>
+        <parameter type-id='11f4a000' name='skb' filepath='net/core/skbuff.c' line='1779' column='1'/>
+        <parameter type-id='95e97e5e' name='newheadroom' filepath='net/core/skbuff.c' line='1780' column='1'/>
+        <parameter type-id='95e97e5e' name='newtailroom' filepath='net/core/skbuff.c' line='1780' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='1781' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
-      <function-decl name='skb_copy_ubufs' mangled-name='skb_copy_ubufs' filepath='net/core/skbuff.c' line='1353' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_copy_ubufs'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1353' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='1353' column='1'/>
+      <function-decl name='skb_copy_ubufs' mangled-name='skb_copy_ubufs' filepath='net/core/skbuff.c' line='1352' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_copy_ubufs'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1352' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='net/core/skbuff.c' line='1352' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='skb_dequeue' mangled-name='skb_dequeue' filepath='net/core/skbuff.c' line='3086' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_dequeue'>
-        <parameter type-id='03c386c6' name='list' filepath='net/core/skbuff.c' line='3086' column='1'/>
+      <function-decl name='skb_dequeue' mangled-name='skb_dequeue' filepath='net/core/skbuff.c' line='3088' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_dequeue'>
+        <parameter type-id='03c386c6' name='list' filepath='net/core/skbuff.c' line='3088' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
-      <function-decl name='skb_dequeue_tail' mangled-name='skb_dequeue_tail' filepath='net/core/skbuff.c' line='3106' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_dequeue_tail'>
-        <parameter type-id='03c386c6' name='list' filepath='net/core/skbuff.c' line='3106' column='1'/>
+      <function-decl name='skb_dequeue_tail' mangled-name='skb_dequeue_tail' filepath='net/core/skbuff.c' line='3108' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_dequeue_tail'>
+        <parameter type-id='03c386c6' name='list' filepath='net/core/skbuff.c' line='3108' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
-      <function-decl name='skb_dump' mangled-name='skb_dump' filepath='net/core/skbuff.c' line='734' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_dump'>
-        <parameter type-id='80f4b756' name='level' filepath='net/core/skbuff.c' line='734' column='1'/>
-        <parameter type-id='11f4a000' name='skb' filepath='net/core/skbuff.c' line='734' column='1'/>
-        <parameter type-id='b50a4934' name='full_pkt' filepath='net/core/skbuff.c' line='734' column='1'/>
+      <function-decl name='skb_dump' mangled-name='skb_dump' filepath='net/core/skbuff.c' line='733' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_dump'>
+        <parameter type-id='80f4b756' name='level' filepath='net/core/skbuff.c' line='733' column='1'/>
+        <parameter type-id='11f4a000' name='skb' filepath='net/core/skbuff.c' line='733' column='1'/>
+        <parameter type-id='b50a4934' name='full_pkt' filepath='net/core/skbuff.c' line='733' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='skb_ensure_writable' mangled-name='skb_ensure_writable' filepath='net/core/skbuff.c' line='5528' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_ensure_writable'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='5528' column='1'/>
-        <parameter type-id='95e97e5e' name='write_len' filepath='net/core/skbuff.c' line='5528' column='1'/>
+      <function-decl name='skb_ensure_writable' mangled-name='skb_ensure_writable' filepath='net/core/skbuff.c' line='5533' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_ensure_writable'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='5533' column='1'/>
+        <parameter type-id='95e97e5e' name='write_len' filepath='net/core/skbuff.c' line='5533' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='skb_free_datagram' mangled-name='skb_free_datagram' filepath='net/core/datagram.c' line='323' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_free_datagram'>
@@ -143271,55 +144058,55 @@
         <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/datagram.c' line='323' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='skb_page_frag_refill' mangled-name='skb_page_frag_refill' filepath='net/core/sock.c' line='2464' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_page_frag_refill'>
-        <parameter type-id='f0981eeb' name='sz' filepath='net/core/sock.c' line='2464' column='1'/>
-        <parameter type-id='a8d434b7' name='pfrag' filepath='net/core/sock.c' line='2464' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp' filepath='net/core/sock.c' line='2464' column='1'/>
+      <function-decl name='skb_page_frag_refill' mangled-name='skb_page_frag_refill' filepath='net/core/sock.c' line='2482' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_page_frag_refill'>
+        <parameter type-id='f0981eeb' name='sz' filepath='net/core/sock.c' line='2482' column='1'/>
+        <parameter type-id='a8d434b7' name='pfrag' filepath='net/core/sock.c' line='2482' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp' filepath='net/core/sock.c' line='2482' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='skb_partial_csum_set' mangled-name='skb_partial_csum_set' filepath='net/core/skbuff.c' line='4846' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_partial_csum_set'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='4846' column='1'/>
-        <parameter type-id='1dc6a898' name='start' filepath='net/core/skbuff.c' line='4846' column='1'/>
-        <parameter type-id='1dc6a898' name='off' filepath='net/core/skbuff.c' line='4846' column='1'/>
+      <function-decl name='skb_partial_csum_set' mangled-name='skb_partial_csum_set' filepath='net/core/skbuff.c' line='4851' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_partial_csum_set'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='4851' column='1'/>
+        <parameter type-id='1dc6a898' name='start' filepath='net/core/skbuff.c' line='4851' column='1'/>
+        <parameter type-id='1dc6a898' name='off' filepath='net/core/skbuff.c' line='4851' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='skb_pull' mangled-name='skb_pull' filepath='net/core/skbuff.c' line='1942' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_pull'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1942' column='1'/>
-        <parameter type-id='f0981eeb' name='len' filepath='net/core/skbuff.c' line='1942' column='1'/>
+      <function-decl name='skb_pull' mangled-name='skb_pull' filepath='net/core/skbuff.c' line='1941' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_pull'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1941' column='1'/>
+        <parameter type-id='f0981eeb' name='len' filepath='net/core/skbuff.c' line='1941' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='skb_pull_rcsum' mangled-name='skb_pull_rcsum' filepath='net/core/skbuff.c' line='3669' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_pull_rcsum'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='3669' column='1'/>
-        <parameter type-id='f0981eeb' name='len' filepath='net/core/skbuff.c' line='3669' column='1'/>
+      <function-decl name='skb_pull_rcsum' mangled-name='skb_pull_rcsum' filepath='net/core/skbuff.c' line='3671' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_pull_rcsum'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='3671' column='1'/>
+        <parameter type-id='f0981eeb' name='len' filepath='net/core/skbuff.c' line='3671' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='skb_push' mangled-name='skb_push' filepath='net/core/skbuff.c' line='1922' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_push'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1922' column='1'/>
-        <parameter type-id='f0981eeb' name='len' filepath='net/core/skbuff.c' line='1922' column='1'/>
+      <function-decl name='skb_push' mangled-name='skb_push' filepath='net/core/skbuff.c' line='1921' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_push'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1921' column='1'/>
+        <parameter type-id='f0981eeb' name='len' filepath='net/core/skbuff.c' line='1921' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='skb_put' mangled-name='skb_put' filepath='net/core/skbuff.c' line='1901' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_put'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1901' column='1'/>
-        <parameter type-id='f0981eeb' name='len' filepath='net/core/skbuff.c' line='1901' column='1'/>
+      <function-decl name='skb_put' mangled-name='skb_put' filepath='net/core/skbuff.c' line='1900' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_put'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1900' column='1'/>
+        <parameter type-id='f0981eeb' name='len' filepath='net/core/skbuff.c' line='1900' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='skb_queue_head' mangled-name='skb_queue_head' filepath='net/core/skbuff.c' line='3171' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_queue_head'>
-        <parameter type-id='03c386c6' name='list' filepath='net/core/skbuff.c' line='3171' column='1'/>
-        <parameter type-id='0fbf3cfd' name='newsk' filepath='net/core/skbuff.c' line='3171' column='1'/>
+      <function-decl name='skb_queue_head' mangled-name='skb_queue_head' filepath='net/core/skbuff.c' line='3173' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_queue_head'>
+        <parameter type-id='03c386c6' name='list' filepath='net/core/skbuff.c' line='3173' column='1'/>
+        <parameter type-id='0fbf3cfd' name='newsk' filepath='net/core/skbuff.c' line='3173' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='skb_queue_purge' mangled-name='skb_queue_purge' filepath='net/core/skbuff.c' line='3126' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_queue_purge'>
-        <parameter type-id='03c386c6' name='list' filepath='net/core/skbuff.c' line='3126' column='1'/>
+      <function-decl name='skb_queue_purge' mangled-name='skb_queue_purge' filepath='net/core/skbuff.c' line='3128' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_queue_purge'>
+        <parameter type-id='03c386c6' name='list' filepath='net/core/skbuff.c' line='3128' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='skb_queue_tail' mangled-name='skb_queue_tail' filepath='net/core/skbuff.c' line='3192' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_queue_tail'>
-        <parameter type-id='03c386c6' name='list' filepath='net/core/skbuff.c' line='3192' column='1'/>
-        <parameter type-id='0fbf3cfd' name='newsk' filepath='net/core/skbuff.c' line='3192' column='1'/>
+      <function-decl name='skb_queue_tail' mangled-name='skb_queue_tail' filepath='net/core/skbuff.c' line='3194' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_queue_tail'>
+        <parameter type-id='03c386c6' name='list' filepath='net/core/skbuff.c' line='3194' column='1'/>
+        <parameter type-id='0fbf3cfd' name='newsk' filepath='net/core/skbuff.c' line='3194' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='skb_realloc_headroom' mangled-name='skb_realloc_headroom' filepath='net/core/skbuff.c' line='1711' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_realloc_headroom'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1711' column='1'/>
-        <parameter type-id='f0981eeb' name='headroom' filepath='net/core/skbuff.c' line='1711' column='1'/>
+      <function-decl name='skb_realloc_headroom' mangled-name='skb_realloc_headroom' filepath='net/core/skbuff.c' line='1710' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_realloc_headroom'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1710' column='1'/>
+        <parameter type-id='f0981eeb' name='headroom' filepath='net/core/skbuff.c' line='1710' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
       <function-decl name='skb_recv_datagram' mangled-name='skb_recv_datagram' filepath='net/core/datagram.c' line='312' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_recv_datagram'>
@@ -143329,16 +144116,16 @@
         <parameter type-id='7292109c' name='err' filepath='net/core/datagram.c' line='313' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
-      <function-decl name='skb_set_owner_w' mangled-name='skb_set_owner_w' filepath='net/core/sock.c' line='2080' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_set_owner_w'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/sock.c' line='2080' column='1'/>
-        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='2080' column='1'/>
+      <function-decl name='skb_set_owner_w' mangled-name='skb_set_owner_w' filepath='net/core/sock.c' line='2087' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_set_owner_w'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/sock.c' line='2087' column='1'/>
+        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='2087' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='skb_store_bits' mangled-name='skb_store_bits' filepath='net/core/skbuff.c' line='2598' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_store_bits'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='2598' column='1'/>
-        <parameter type-id='95e97e5e' name='offset' filepath='net/core/skbuff.c' line='2598' column='1'/>
-        <parameter type-id='eaa32e2f' name='from' filepath='net/core/skbuff.c' line='2598' column='1'/>
-        <parameter type-id='95e97e5e' name='len' filepath='net/core/skbuff.c' line='2598' column='1'/>
+      <function-decl name='skb_store_bits' mangled-name='skb_store_bits' filepath='net/core/skbuff.c' line='2600' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_store_bits'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='2600' column='1'/>
+        <parameter type-id='95e97e5e' name='offset' filepath='net/core/skbuff.c' line='2600' column='1'/>
+        <parameter type-id='eaa32e2f' name='from' filepath='net/core/skbuff.c' line='2600' column='1'/>
+        <parameter type-id='95e97e5e' name='len' filepath='net/core/skbuff.c' line='2600' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='skb_to_sgvec' mangled-name='skb_to_sgvec' filepath='net/core/skbuff.c' line='4426' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_to_sgvec'>
@@ -143348,19 +144135,19 @@
         <parameter type-id='95e97e5e' name='len' filepath='net/core/skbuff.c' line='4426' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='skb_trim' mangled-name='skb_trim' filepath='net/core/skbuff.c' line='1957' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_trim'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1957' column='1'/>
-        <parameter type-id='f0981eeb' name='len' filepath='net/core/skbuff.c' line='1957' column='1'/>
+      <function-decl name='skb_trim' mangled-name='skb_trim' filepath='net/core/skbuff.c' line='1956' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_trim'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='1956' column='1'/>
+        <parameter type-id='f0981eeb' name='len' filepath='net/core/skbuff.c' line='1956' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='skb_tstamp_tx' mangled-name='skb_tstamp_tx' filepath='net/core/skbuff.c' line='4800' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_tstamp_tx'>
-        <parameter type-id='0fbf3cfd' name='orig_skb' filepath='net/core/skbuff.c' line='4800' column='1'/>
-        <parameter type-id='68197365' name='hwtstamps' filepath='net/core/skbuff.c' line='4801' column='1'/>
+      <function-decl name='skb_tstamp_tx' mangled-name='skb_tstamp_tx' filepath='net/core/skbuff.c' line='4805' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_tstamp_tx'>
+        <parameter type-id='0fbf3cfd' name='orig_skb' filepath='net/core/skbuff.c' line='4805' column='1'/>
+        <parameter type-id='68197365' name='hwtstamps' filepath='net/core/skbuff.c' line='4806' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='skb_unlink' mangled-name='skb_unlink' filepath='net/core/skbuff.c' line='3212' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_unlink'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='3212' column='1'/>
-        <parameter type-id='03c386c6' name='list' filepath='net/core/skbuff.c' line='3212' column='1'/>
+      <function-decl name='skb_unlink' mangled-name='skb_unlink' filepath='net/core/skbuff.c' line='3214' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skb_unlink'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/skbuff.c' line='3214' column='1'/>
+        <parameter type-id='03c386c6' name='list' filepath='net/core/skbuff.c' line='3214' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='skcipher_alloc_instance_simple' mangled-name='skcipher_alloc_instance_simple' filepath='crypto/skcipher.c' line='935' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skcipher_alloc_instance_simple'>
@@ -143396,7 +144183,7 @@
         <parameter type-id='b50a4934' name='atomic' filepath='crypto/skcipher.c' line='478' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='skip_spaces' mangled-name='skip_spaces' filepath='include/linux/string.h' line='72' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skip_spaces'>
+      <function-decl name='skip_spaces' mangled-name='skip_spaces' filepath='include/linux/string.h' line='71' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='skip_spaces'>
         <parameter type-id='80f4b756'/>
         <return type-id='26a90f95'/>
       </function-decl>
@@ -143824,15 +144611,15 @@
         <parameter is-variadic='yes'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='snd_pcm_kernel_ioctl' mangled-name='snd_pcm_kernel_ioctl' filepath='sound/core/pcm_native.c' line='3385' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_kernel_ioctl'>
-        <parameter type-id='06b2cd14' name='substream' filepath='sound/core/pcm_native.c' line='3385' column='1'/>
-        <parameter type-id='f0981eeb' name='cmd' filepath='sound/core/pcm_native.c' line='3386' column='1'/>
-        <parameter type-id='eaa32e2f' name='arg' filepath='sound/core/pcm_native.c' line='3386' column='1'/>
+      <function-decl name='snd_pcm_kernel_ioctl' mangled-name='snd_pcm_kernel_ioctl' filepath='sound/core/pcm_native.c' line='3387' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_kernel_ioctl'>
+        <parameter type-id='06b2cd14' name='substream' filepath='sound/core/pcm_native.c' line='3387' column='1'/>
+        <parameter type-id='f0981eeb' name='cmd' filepath='sound/core/pcm_native.c' line='3388' column='1'/>
+        <parameter type-id='eaa32e2f' name='arg' filepath='sound/core/pcm_native.c' line='3388' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='snd_pcm_lib_default_mmap' mangled-name='snd_pcm_lib_default_mmap' filepath='sound/core/pcm_native.c' line='3780' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_lib_default_mmap'>
-        <parameter type-id='06b2cd14' name='substream' filepath='sound/core/pcm_native.c' line='3780' column='1'/>
-        <parameter type-id='2ae08426' name='area' filepath='sound/core/pcm_native.c' line='3781' column='1'/>
+      <function-decl name='snd_pcm_lib_default_mmap' mangled-name='snd_pcm_lib_default_mmap' filepath='sound/core/pcm_native.c' line='3782' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_lib_default_mmap'>
+        <parameter type-id='06b2cd14' name='substream' filepath='sound/core/pcm_native.c' line='3782' column='1'/>
+        <parameter type-id='2ae08426' name='area' filepath='sound/core/pcm_native.c' line='3783' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='snd_pcm_lib_free_pages' mangled-name='snd_pcm_lib_free_pages' filepath='sound/core/pcm_memory.c' line='435' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_lib_free_pages'>
@@ -143879,11 +144666,11 @@
         <parameter type-id='0f9dfae3' name='rpcm' filepath='sound/core/pcm.c' line='774' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='snd_pcm_open_substream' mangled-name='snd_pcm_open_substream' filepath='sound/core/pcm_native.c' line='2704' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_open_substream'>
-        <parameter type-id='4c9f335b' name='pcm' filepath='sound/core/pcm_native.c' line='2704' column='1'/>
-        <parameter type-id='95e97e5e' name='stream' filepath='sound/core/pcm_native.c' line='2704' column='1'/>
-        <parameter type-id='77e79a4b' name='file' filepath='sound/core/pcm_native.c' line='2705' column='1'/>
-        <parameter type-id='c979189a' name='rsubstream' filepath='sound/core/pcm_native.c' line='2706' column='1'/>
+      <function-decl name='snd_pcm_open_substream' mangled-name='snd_pcm_open_substream' filepath='sound/core/pcm_native.c' line='2706' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_open_substream'>
+        <parameter type-id='4c9f335b' name='pcm' filepath='sound/core/pcm_native.c' line='2706' column='1'/>
+        <parameter type-id='95e97e5e' name='stream' filepath='sound/core/pcm_native.c' line='2706' column='1'/>
+        <parameter type-id='77e79a4b' name='file' filepath='sound/core/pcm_native.c' line='2707' column='1'/>
+        <parameter type-id='c979189a' name='rsubstream' filepath='sound/core/pcm_native.c' line='2708' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='snd_pcm_period_elapsed' mangled-name='snd_pcm_period_elapsed' filepath='sound/core/pcm_lib.c' line='1791' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_period_elapsed'>
@@ -143895,8 +144682,8 @@
         <parameter type-id='f0981eeb' name='rate_max' filepath='sound/core/pcm_misc.c' line='596' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='snd_pcm_release_substream' mangled-name='snd_pcm_release_substream' filepath='sound/core/pcm_native.c' line='2681' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_release_substream'>
-        <parameter type-id='06b2cd14' name='substream' filepath='sound/core/pcm_native.c' line='2681' column='1'/>
+      <function-decl name='snd_pcm_release_substream' mangled-name='snd_pcm_release_substream' filepath='sound/core/pcm_native.c' line='2683' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_release_substream'>
+        <parameter type-id='06b2cd14' name='substream' filepath='sound/core/pcm_native.c' line='2683' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='snd_pcm_set_managed_buffer_all' mangled-name='snd_pcm_set_managed_buffer_all' filepath='sound/core/pcm_memory.c' line='341' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_set_managed_buffer_all'>
@@ -143918,13 +144705,13 @@
         <return type-id='48b5725f'/>
       </function-decl>
       <var-decl name='snd_pcm_std_chmaps' type-id='93f82aba' mangled-name='snd_pcm_std_chmaps' visibility='default' filepath='sound/core/pcm_lib.c' line='2271' column='1' elf-symbol-id='snd_pcm_std_chmaps'/>
-      <function-decl name='snd_pcm_stop' mangled-name='snd_pcm_stop' filepath='sound/core/pcm_native.c' line='1514' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_stop'>
-        <parameter type-id='06b2cd14' name='substream' filepath='sound/core/pcm_native.c' line='1514' column='1'/>
-        <parameter type-id='33158de9' name='state' filepath='sound/core/pcm_native.c' line='1514' column='1'/>
+      <function-decl name='snd_pcm_stop' mangled-name='snd_pcm_stop' filepath='sound/core/pcm_native.c' line='1516' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_stop'>
+        <parameter type-id='06b2cd14' name='substream' filepath='sound/core/pcm_native.c' line='1516' column='1'/>
+        <parameter type-id='33158de9' name='state' filepath='sound/core/pcm_native.c' line='1516' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='snd_pcm_stop_xrun' mangled-name='snd_pcm_stop_xrun' filepath='sound/core/pcm_native.c' line='1544' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_stop_xrun'>
-        <parameter type-id='06b2cd14' name='substream' filepath='sound/core/pcm_native.c' line='1544' column='1'/>
+      <function-decl name='snd_pcm_stop_xrun' mangled-name='snd_pcm_stop_xrun' filepath='sound/core/pcm_native.c' line='1546' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_stop_xrun'>
+        <parameter type-id='06b2cd14' name='substream' filepath='sound/core/pcm_native.c' line='1546' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='snd_pcm_stream_lock' mangled-name='snd_pcm_stream_lock' filepath='sound/core/pcm_native.c' line='108' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_pcm_stream_lock'>
@@ -144272,9 +145059,9 @@
         <parameter type-id='95e97e5e' name='num' filepath='sound/soc/soc-dapm.c' line='3210' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='snd_soc_dpcm_get_substream' mangled-name='snd_soc_dpcm_get_substream' filepath='sound/soc/soc-pcm.c' line='2909' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_soc_dpcm_get_substream'>
-        <parameter type-id='95316552' name='be' filepath='sound/soc/soc-pcm.c' line='2909' column='1'/>
-        <parameter type-id='95e97e5e' name='stream' filepath='sound/soc/soc-pcm.c' line='2909' column='1'/>
+      <function-decl name='snd_soc_dpcm_get_substream' mangled-name='snd_soc_dpcm_get_substream' filepath='sound/soc/soc-pcm.c' line='2912' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_soc_dpcm_get_substream'>
+        <parameter type-id='95316552' name='be' filepath='sound/soc/soc-pcm.c' line='2912' column='1'/>
+        <parameter type-id='95e97e5e' name='stream' filepath='sound/soc/soc-pcm.c' line='2912' column='1'/>
         <return type-id='06b2cd14'/>
       </function-decl>
       <function-decl name='snd_soc_find_dai' mangled-name='snd_soc_find_dai' filepath='sound/soc/soc-core.c' line='810' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snd_soc_find_dai'>
@@ -144563,7 +145350,7 @@
         <parameter type-id='39c41052' name='ops' filepath='sound/usb/card.c' line='117' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='snprintf' mangled-name='snprintf' filepath='include/linux/kernel.h' line='479' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snprintf'>
+      <function-decl name='snprintf' mangled-name='snprintf' filepath='include/linux/kernel.h' line='341' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snprintf'>
         <parameter type-id='26a90f95'/>
         <parameter type-id='7359adad'/>
         <parameter type-id='80f4b756'/>
@@ -144582,20 +145369,20 @@
         <parameter type-id='97eb1967' name='soc_dev' filepath='drivers/base/soc.c' line='172' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='sock_alloc_send_pskb' mangled-name='sock_alloc_send_pskb' filepath='net/core/sock.c' line='2319' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_alloc_send_pskb'>
-        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='2319' column='1'/>
-        <parameter type-id='7359adad' name='header_len' filepath='net/core/sock.c' line='2319' column='1'/>
-        <parameter type-id='7359adad' name='data_len' filepath='net/core/sock.c' line='2320' column='1'/>
-        <parameter type-id='95e97e5e' name='noblock' filepath='net/core/sock.c' line='2320' column='1'/>
-        <parameter type-id='7292109c' name='errcode' filepath='net/core/sock.c' line='2321' column='1'/>
-        <parameter type-id='95e97e5e' name='max_page_order' filepath='net/core/sock.c' line='2321' column='1'/>
+      <function-decl name='sock_alloc_send_pskb' mangled-name='sock_alloc_send_pskb' filepath='net/core/sock.c' line='2337' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_alloc_send_pskb'>
+        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='2337' column='1'/>
+        <parameter type-id='7359adad' name='header_len' filepath='net/core/sock.c' line='2337' column='1'/>
+        <parameter type-id='7359adad' name='data_len' filepath='net/core/sock.c' line='2338' column='1'/>
+        <parameter type-id='95e97e5e' name='noblock' filepath='net/core/sock.c' line='2338' column='1'/>
+        <parameter type-id='7292109c' name='errcode' filepath='net/core/sock.c' line='2339' column='1'/>
+        <parameter type-id='95e97e5e' name='max_page_order' filepath='net/core/sock.c' line='2339' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
-      <function-decl name='sock_alloc_send_skb' mangled-name='sock_alloc_send_skb' filepath='net/core/sock.c' line='2363' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_alloc_send_skb'>
-        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='2363' column='1'/>
-        <parameter type-id='7359adad' name='size' filepath='net/core/sock.c' line='2363' column='1'/>
-        <parameter type-id='95e97e5e' name='noblock' filepath='net/core/sock.c' line='2364' column='1'/>
-        <parameter type-id='7292109c' name='errcode' filepath='net/core/sock.c' line='2364' column='1'/>
+      <function-decl name='sock_alloc_send_skb' mangled-name='sock_alloc_send_skb' filepath='net/core/sock.c' line='2381' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_alloc_send_skb'>
+        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='2381' column='1'/>
+        <parameter type-id='7359adad' name='size' filepath='net/core/sock.c' line='2381' column='1'/>
+        <parameter type-id='95e97e5e' name='noblock' filepath='net/core/sock.c' line='2382' column='1'/>
+        <parameter type-id='7292109c' name='errcode' filepath='net/core/sock.c' line='2382' column='1'/>
         <return type-id='0fbf3cfd'/>
       </function-decl>
       <function-decl name='sock_create_kern' mangled-name='sock_create_kern' filepath='net/socket.c' line='1484' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_create_kern'>
@@ -144606,60 +145393,60 @@
         <parameter type-id='1a7bb5c8' name='res' filepath='net/socket.c' line='1484' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sock_efree' mangled-name='sock_efree' filepath='net/core/sock.c' line='2150' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_efree'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/sock.c' line='2150' column='1'/>
+      <function-decl name='sock_efree' mangled-name='sock_efree' filepath='net/core/sock.c' line='2157' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_efree'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/sock.c' line='2157' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='sock_gettstamp' mangled-name='sock_gettstamp' filepath='net/core/sock.c' line='3136' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_gettstamp'>
-        <parameter type-id='13103032' name='sock' filepath='net/core/sock.c' line='3136' column='1'/>
-        <parameter type-id='eaa32e2f' name='userstamp' filepath='net/core/sock.c' line='3136' column='1'/>
-        <parameter type-id='b50a4934' name='timeval' filepath='net/core/sock.c' line='3137' column='1'/>
-        <parameter type-id='b50a4934' name='time32' filepath='net/core/sock.c' line='3137' column='1'/>
+      <function-decl name='sock_gettstamp' mangled-name='sock_gettstamp' filepath='net/core/sock.c' line='3163' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_gettstamp'>
+        <parameter type-id='13103032' name='sock' filepath='net/core/sock.c' line='3163' column='1'/>
+        <parameter type-id='eaa32e2f' name='userstamp' filepath='net/core/sock.c' line='3163' column='1'/>
+        <parameter type-id='b50a4934' name='timeval' filepath='net/core/sock.c' line='3164' column='1'/>
+        <parameter type-id='b50a4934' name='time32' filepath='net/core/sock.c' line='3164' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sock_i_uid' mangled-name='sock_i_uid' filepath='net/core/sock.c' line='2168' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_i_uid'>
-        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='2168' column='1'/>
+      <function-decl name='sock_i_uid' mangled-name='sock_i_uid' filepath='net/core/sock.c' line='2175' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_i_uid'>
+        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='2175' column='1'/>
         <return type-id='d80b72e6'/>
       </function-decl>
-      <function-decl name='sock_init_data' mangled-name='sock_init_data' filepath='net/core/sock.c' line='2982' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_init_data'>
-        <parameter type-id='13103032' name='sock' filepath='net/core/sock.c' line='2982' column='1'/>
-        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='2982' column='1'/>
+      <function-decl name='sock_init_data' mangled-name='sock_init_data' filepath='net/core/sock.c' line='3082' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_init_data'>
+        <parameter type-id='13103032' name='sock' filepath='net/core/sock.c' line='3082' column='1'/>
+        <parameter type-id='f772df6d' name='sk' filepath='net/core/sock.c' line='3082' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='sock_no_accept' mangled-name='sock_no_accept' filepath='net/core/sock.c' line='2766' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_no_accept'>
-        <parameter type-id='13103032' name='sock' filepath='net/core/sock.c' line='2766' column='1'/>
-        <parameter type-id='13103032' name='newsock' filepath='net/core/sock.c' line='2766' column='1'/>
-        <parameter type-id='95e97e5e' name='flags' filepath='net/core/sock.c' line='2766' column='1'/>
-        <parameter type-id='b50a4934' name='kern' filepath='net/core/sock.c' line='2767' column='1'/>
+      <function-decl name='sock_no_accept' mangled-name='sock_no_accept' filepath='net/core/sock.c' line='2784' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_no_accept'>
+        <parameter type-id='13103032' name='sock' filepath='net/core/sock.c' line='2784' column='1'/>
+        <parameter type-id='13103032' name='newsock' filepath='net/core/sock.c' line='2784' column='1'/>
+        <parameter type-id='95e97e5e' name='flags' filepath='net/core/sock.c' line='2784' column='1'/>
+        <parameter type-id='b50a4934' name='kern' filepath='net/core/sock.c' line='2785' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sock_no_listen' mangled-name='sock_no_listen' filepath='net/core/sock.c' line='2786' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_no_listen'>
-        <parameter type-id='13103032' name='sock' filepath='net/core/sock.c' line='2786' column='1'/>
-        <parameter type-id='95e97e5e' name='backlog' filepath='net/core/sock.c' line='2786' column='1'/>
+      <function-decl name='sock_no_listen' mangled-name='sock_no_listen' filepath='net/core/sock.c' line='2804' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_no_listen'>
+        <parameter type-id='13103032' name='sock' filepath='net/core/sock.c' line='2804' column='1'/>
+        <parameter type-id='95e97e5e' name='backlog' filepath='net/core/sock.c' line='2804' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sock_no_mmap' mangled-name='sock_no_mmap' filepath='net/core/sock.c' line='2817' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_no_mmap'>
-        <parameter type-id='77e79a4b' name='file' filepath='net/core/sock.c' line='2817' column='1'/>
-        <parameter type-id='13103032' name='sock' filepath='net/core/sock.c' line='2817' column='1'/>
-        <parameter type-id='2ae08426' name='vma' filepath='net/core/sock.c' line='2817' column='1'/>
+      <function-decl name='sock_no_mmap' mangled-name='sock_no_mmap' filepath='net/core/sock.c' line='2835' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_no_mmap'>
+        <parameter type-id='77e79a4b' name='file' filepath='net/core/sock.c' line='2835' column='1'/>
+        <parameter type-id='13103032' name='sock' filepath='net/core/sock.c' line='2835' column='1'/>
+        <parameter type-id='2ae08426' name='vma' filepath='net/core/sock.c' line='2835' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sock_no_sendpage' mangled-name='sock_no_sendpage' filepath='net/core/sock.c' line='2845' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_no_sendpage'>
-        <parameter type-id='13103032' name='sock' filepath='net/core/sock.c' line='2845' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='net/core/sock.c' line='2845' column='1'/>
-        <parameter type-id='95e97e5e' name='offset' filepath='net/core/sock.c' line='2845' column='1'/>
-        <parameter type-id='b59d7dce' name='size' filepath='net/core/sock.c' line='2845' column='1'/>
-        <parameter type-id='95e97e5e' name='flags' filepath='net/core/sock.c' line='2845' column='1'/>
+      <function-decl name='sock_no_sendpage' mangled-name='sock_no_sendpage' filepath='net/core/sock.c' line='2863' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_no_sendpage'>
+        <parameter type-id='13103032' name='sock' filepath='net/core/sock.c' line='2863' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='net/core/sock.c' line='2863' column='1'/>
+        <parameter type-id='95e97e5e' name='offset' filepath='net/core/sock.c' line='2863' column='1'/>
+        <parameter type-id='b59d7dce' name='size' filepath='net/core/sock.c' line='2863' column='1'/>
+        <parameter type-id='95e97e5e' name='flags' filepath='net/core/sock.c' line='2863' column='1'/>
         <return type-id='79a0948f'/>
       </function-decl>
-      <function-decl name='sock_no_shutdown' mangled-name='sock_no_shutdown' filepath='net/core/sock.c' line='2792' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_no_shutdown'>
-        <parameter type-id='13103032' name='sock' filepath='net/core/sock.c' line='2792' column='1'/>
-        <parameter type-id='95e97e5e' name='how' filepath='net/core/sock.c' line='2792' column='1'/>
+      <function-decl name='sock_no_shutdown' mangled-name='sock_no_shutdown' filepath='net/core/sock.c' line='2810' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_no_shutdown'>
+        <parameter type-id='13103032' name='sock' filepath='net/core/sock.c' line='2810' column='1'/>
+        <parameter type-id='95e97e5e' name='how' filepath='net/core/sock.c' line='2810' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sock_no_socketpair' mangled-name='sock_no_socketpair' filepath='net/core/sock.c' line='2760' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_no_socketpair'>
-        <parameter type-id='13103032' name='sock1' filepath='net/core/sock.c' line='2760' column='1'/>
-        <parameter type-id='13103032' name='sock2' filepath='net/core/sock.c' line='2760' column='1'/>
+      <function-decl name='sock_no_socketpair' mangled-name='sock_no_socketpair' filepath='net/core/sock.c' line='2778' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_no_socketpair'>
+        <parameter type-id='13103032' name='sock1' filepath='net/core/sock.c' line='2778' column='1'/>
+        <parameter type-id='13103032' name='sock2' filepath='net/core/sock.c' line='2778' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='sock_queue_rcv_skb' mangled-name='sock_queue_rcv_skb' filepath='net/core/sock.c' line='474' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_queue_rcv_skb'>
@@ -144673,8 +145460,8 @@
         <parameter type-id='95e97e5e' name='flags' filepath='net/socket.c' line='900' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sock_register' mangled-name='sock_register' filepath='net/socket.c' line='2975' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_register'>
-        <parameter type-id='81a51edb' name='ops' filepath='net/socket.c' line='2975' column='1'/>
+      <function-decl name='sock_register' mangled-name='sock_register' filepath='net/socket.c' line='2979' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_register'>
+        <parameter type-id='81a51edb' name='ops' filepath='net/socket.c' line='2979' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='sock_release' mangled-name='sock_release' filepath='net/socket.c' line='623' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_release'>
@@ -144689,12 +145476,12 @@
         <parameter type-id='f0981eeb' name='optlen' filepath='net/core/sock.c' line='833' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sock_unregister' mangled-name='sock_unregister' filepath='net/socket.c' line='3012' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_unregister'>
-        <parameter type-id='95e97e5e' name='family' filepath='net/socket.c' line='3012' column='1'/>
+      <function-decl name='sock_unregister' mangled-name='sock_unregister' filepath='net/socket.c' line='3016' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_unregister'>
+        <parameter type-id='95e97e5e' name='family' filepath='net/socket.c' line='3016' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='sock_wfree' mangled-name='sock_wfree' filepath='net/core/sock.c' line='2046' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_wfree'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/sock.c' line='2046' column='1'/>
+      <function-decl name='sock_wfree' mangled-name='sock_wfree' filepath='net/core/sock.c' line='2053' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sock_wfree'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/core/sock.c' line='2053' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='sockfd_lookup' mangled-name='sockfd_lookup' filepath='net/socket.c' line='477' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sockfd_lookup'>
@@ -144831,22 +145618,22 @@
         <parameter type-id='f0981eeb' name='n_rx' filepath='drivers/spi/spi.c' line='4002' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='split_page' mangled-name='split_page' filepath='mm/page_alloc.c' line='3401' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='split_page'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/page_alloc.c' line='3401' column='1'/>
-        <parameter type-id='f0981eeb' name='order' filepath='mm/page_alloc.c' line='3401' column='1'/>
+      <function-decl name='split_page' mangled-name='split_page' filepath='mm/page_alloc.c' line='3423' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='split_page'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/page_alloc.c' line='3423' column='1'/>
+        <parameter type-id='f0981eeb' name='order' filepath='mm/page_alloc.c' line='3423' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='spmi_controller_add' mangled-name='spmi_controller_add' filepath='drivers/spmi/spmi.c' line='508' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='spmi_controller_add'>
-        <parameter type-id='d5cbf711' name='ctrl' filepath='drivers/spmi/spmi.c' line='508' column='1'/>
+      <function-decl name='spmi_controller_add' mangled-name='spmi_controller_add' filepath='drivers/spmi/spmi.c' line='509' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='spmi_controller_add'>
+        <parameter type-id='d5cbf711' name='ctrl' filepath='drivers/spmi/spmi.c' line='509' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='spmi_controller_alloc' mangled-name='spmi_controller_alloc' filepath='drivers/spmi/spmi.c' line='413' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='spmi_controller_alloc'>
-        <parameter type-id='fa0b179b' name='parent' filepath='drivers/spmi/spmi.c' line='413' column='1'/>
-        <parameter type-id='b59d7dce' name='size' filepath='drivers/spmi/spmi.c' line='414' column='1'/>
+      <function-decl name='spmi_controller_alloc' mangled-name='spmi_controller_alloc' filepath='drivers/spmi/spmi.c' line='414' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='spmi_controller_alloc'>
+        <parameter type-id='fa0b179b' name='parent' filepath='drivers/spmi/spmi.c' line='414' column='1'/>
+        <parameter type-id='b59d7dce' name='size' filepath='drivers/spmi/spmi.c' line='415' column='1'/>
         <return type-id='d5cbf711'/>
       </function-decl>
-      <function-decl name='spmi_controller_remove' mangled-name='spmi_controller_remove' filepath='drivers/spmi/spmi.c' line='546' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='spmi_controller_remove'>
-        <parameter type-id='d5cbf711' name='ctrl' filepath='drivers/spmi/spmi.c' line='546' column='1'/>
+      <function-decl name='spmi_controller_remove' mangled-name='spmi_controller_remove' filepath='drivers/spmi/spmi.c' line='547' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='spmi_controller_remove'>
+        <parameter type-id='d5cbf711' name='ctrl' filepath='drivers/spmi/spmi.c' line='547' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='spmi_ext_register_read' mangled-name='spmi_ext_register_read' filepath='drivers/spmi/spmi.c' line='161' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='spmi_ext_register_read'>
@@ -145057,9 +145844,9 @@
         <parameter type-id='80f4b756' name='reject' filepath='lib/string.c' line='625' column='1'/>
         <return type-id='9e19ad6e'/>
       </function-decl>
-      <function-decl name='stream_open' mangled-name='stream_open' filepath='fs/open.c' line='1419' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='stream_open'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/open.c' line='1419' column='1'/>
-        <parameter type-id='77e79a4b' name='filp' filepath='fs/open.c' line='1419' column='1'/>
+      <function-decl name='stream_open' mangled-name='stream_open' filepath='fs/open.c' line='1425' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='stream_open'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/open.c' line='1425' column='1'/>
+        <parameter type-id='77e79a4b' name='filp' filepath='fs/open.c' line='1425' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='strim' mangled-name='strim' filepath='lib/string.c' line='541' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='strim'>
@@ -145116,9 +145903,9 @@
         <parameter type-id='bd54fe1a' name='count' filepath='lib/strncpy_from_user.c' line='113' column='1'/>
         <return type-id='bd54fe1a'/>
       </function-decl>
-      <function-decl name='strndup_user' mangled-name='strndup_user' filepath='mm/util.c' line='222' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='strndup_user'>
-        <parameter type-id='80f4b756' name='s' filepath='mm/util.c' line='222' column='1'/>
-        <parameter type-id='bd54fe1a' name='n' filepath='mm/util.c' line='222' column='1'/>
+      <function-decl name='strndup_user' mangled-name='strndup_user' filepath='mm/util.c' line='223' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='strndup_user'>
+        <parameter type-id='80f4b756' name='s' filepath='mm/util.c' line='223' column='1'/>
+        <parameter type-id='bd54fe1a' name='n' filepath='mm/util.c' line='223' column='1'/>
         <return type-id='26a90f95'/>
       </function-decl>
       <function-decl name='strnlen_user' mangled-name='strnlen_user' filepath='lib/strnlen_user.c' line='92' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='strnlen_user'>
@@ -145165,7 +145952,7 @@
         <parameter type-id='80f4b756' name='accept' filepath='lib/string.c' line='598' column='1'/>
         <return type-id='9e19ad6e'/>
       </function-decl>
-      <function-decl name='strstr' mangled-name='strstr' filepath='include/linux/string.h' line='82' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='strstr'>
+      <function-decl name='strstr' mangled-name='strstr' filepath='include/linux/string.h' line='81' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='strstr'>
         <parameter type-id='80f4b756'/>
         <parameter type-id='80f4b756'/>
         <return type-id='26a90f95'/>
@@ -145176,12 +145963,12 @@
         <parameter type-id='c485c22c' name='bh' filepath='fs/buffer.c' line='3086' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='submit_bio' mangled-name='submit_bio' filepath='block/blk-core.c' line='1081' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='submit_bio'>
-        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-core.c' line='1081' column='1'/>
+      <function-decl name='submit_bio' mangled-name='submit_bio' filepath='block/blk-core.c' line='1079' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='submit_bio'>
+        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-core.c' line='1079' column='1'/>
         <return type-id='041bc907'/>
       </function-decl>
-      <function-decl name='submit_bio_noacct' mangled-name='submit_bio_noacct' filepath='block/blk-core.c' line='1046' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='submit_bio_noacct'>
-        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-core.c' line='1046' column='1'/>
+      <function-decl name='submit_bio_noacct' mangled-name='submit_bio_noacct' filepath='block/blk-core.c' line='1044' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='submit_bio_noacct'>
+        <parameter type-id='fb55efa1' name='bio' filepath='block/blk-core.c' line='1044' column='1'/>
         <return type-id='041bc907'/>
       </function-decl>
       <function-decl name='submit_bio_wait' mangled-name='submit_bio_wait' filepath='block/bio.c' line='1155' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='submit_bio_wait'>
@@ -145197,18 +145984,18 @@
         <parameter type-id='9d109fcf' name='ops' filepath='kernel/power/suspend.c' line='203' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='swap_alloc_cluster' mangled-name='swap_alloc_cluster' filepath='mm/swapfile.c' line='993' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='swap_alloc_cluster'>
-        <parameter type-id='11e11a61' name='si' filepath='mm/swapfile.c' line='993' column='1'/>
-        <parameter type-id='57d7488d' name='slot' filepath='mm/swapfile.c' line='993' column='1'/>
+      <function-decl name='swap_alloc_cluster' mangled-name='swap_alloc_cluster' filepath='mm/swapfile.c' line='1005' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='swap_alloc_cluster'>
+        <parameter type-id='11e11a61' name='si' filepath='mm/swapfile.c' line='1005' column='1'/>
+        <parameter type-id='57d7488d' name='slot' filepath='mm/swapfile.c' line='1005' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='swap_type_to_swap_info' mangled-name='swap_type_to_swap_info' filepath='mm/swapfile.c' line='102' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='swap_type_to_swap_info'>
         <parameter type-id='95e97e5e' name='type' filepath='mm/swapfile.c' line='102' column='1'/>
         <return type-id='11e11a61'/>
       </function-decl>
-      <function-decl name='swapcache_free_entries' mangled-name='swapcache_free_entries' filepath='mm/swapfile.c' line='1464' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='swapcache_free_entries'>
-        <parameter type-id='57d7488d' name='entries' filepath='mm/swapfile.c' line='1464' column='1'/>
-        <parameter type-id='95e97e5e' name='n' filepath='mm/swapfile.c' line='1464' column='1'/>
+      <function-decl name='swapcache_free_entries' mangled-name='swapcache_free_entries' filepath='mm/swapfile.c' line='1477' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='swapcache_free_entries'>
+        <parameter type-id='57d7488d' name='entries' filepath='mm/swapfile.c' line='1477' column='1'/>
+        <parameter type-id='95e97e5e' name='n' filepath='mm/swapfile.c' line='1477' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='swiotlb_max_segment' mangled-name='swiotlb_max_segment' filepath='kernel/dma/swiotlb.c' line='138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='swiotlb_max_segment'>
@@ -145217,8 +146004,8 @@
       <function-decl name='swiotlb_nr_tbl' mangled-name='swiotlb_nr_tbl' filepath='kernel/dma/swiotlb.c' line='132' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='swiotlb_nr_tbl'>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='swp_swap_info' mangled-name='swp_swap_info' filepath='mm/swapfile.c' line='3587' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='swp_swap_info'>
-        <parameter type-id='e0c6ffc2' name='entry' filepath='mm/swapfile.c' line='3587' column='1'/>
+      <function-decl name='swp_swap_info' mangled-name='swp_swap_info' filepath='mm/swapfile.c' line='3602' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='swp_swap_info'>
+        <parameter type-id='e0c6ffc2' name='entry' filepath='mm/swapfile.c' line='3602' column='1'/>
         <return type-id='11e11a61'/>
       </function-decl>
       <function-decl name='sync_blockdev' mangled-name='sync_blockdev' filepath='fs/block_dev.c' line='537' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sync_blockdev'>
@@ -145241,32 +146028,32 @@
         <parameter type-id='42c8f564' name='sb' filepath='fs/sync.c' line='29' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sync_inode_metadata' mangled-name='sync_inode_metadata' filepath='fs/fs-writeback.c' line='2605' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sync_inode_metadata'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/fs-writeback.c' line='2605' column='1'/>
-        <parameter type-id='95e97e5e' name='wait' filepath='fs/fs-writeback.c' line='2605' column='1'/>
+      <function-decl name='sync_inode_metadata' mangled-name='sync_inode_metadata' filepath='fs/fs-writeback.c' line='2608' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sync_inode_metadata'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/fs-writeback.c' line='2608' column='1'/>
+        <parameter type-id='95e97e5e' name='wait' filepath='fs/fs-writeback.c' line='2608' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='sync_inodes_sb' mangled-name='sync_inodes_sb' filepath='fs/fs-writeback.c' line='2519' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sync_inodes_sb'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/fs-writeback.c' line='2519' column='1'/>
+      <function-decl name='sync_inodes_sb' mangled-name='sync_inodes_sb' filepath='fs/fs-writeback.c' line='2522' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sync_inodes_sb'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/fs-writeback.c' line='2522' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='synchronize_irq' mangled-name='synchronize_irq' filepath='kernel/irq/manage.c' line='127' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='synchronize_irq'>
         <parameter type-id='f0981eeb' name='irq' filepath='kernel/irq/manage.c' line='127' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='synchronize_net' mangled-name='synchronize_net' filepath='net/core/dev.c' line='10632' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='synchronize_net'>
+      <function-decl name='synchronize_net' mangled-name='synchronize_net' filepath='net/core/dev.c' line='10637' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='synchronize_net'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='synchronize_rcu' mangled-name='synchronize_rcu' filepath='kernel/rcu/tree.c' line='3672' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='synchronize_rcu'>
+      <function-decl name='synchronize_rcu' mangled-name='synchronize_rcu' filepath='kernel/rcu/tree.c' line='3701' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='synchronize_rcu'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='synchronize_rcu_expedited' mangled-name='synchronize_rcu_expedited' filepath='kernel/rcu/tree_exp.h' line='814' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='synchronize_rcu_expedited'>
+      <function-decl name='synchronize_rcu_expedited' mangled-name='synchronize_rcu_expedited' filepath='kernel/rcu/tree_exp.h' line='818' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='synchronize_rcu_expedited'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='synchronize_rcu_tasks' mangled-name='synchronize_rcu_tasks' filepath='kernel/rcu/tasks.h' line='540' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='synchronize_rcu_tasks'>
+      <function-decl name='synchronize_rcu_tasks' mangled-name='synchronize_rcu_tasks' filepath='kernel/rcu/tasks.h' line='554' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='synchronize_rcu_tasks'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='synchronize_rcu_tasks_trace' mangled-name='synchronize_rcu_tasks_trace' filepath='kernel/rcu/tasks.h' line='1165' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='synchronize_rcu_tasks_trace'>
+      <function-decl name='synchronize_rcu_tasks_trace' mangled-name='synchronize_rcu_tasks_trace' filepath='kernel/rcu/tasks.h' line='1178' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='synchronize_rcu_tasks_trace'>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='synchronize_srcu' mangled-name='synchronize_srcu' filepath='kernel/rcu/srcutree.c' line='1009' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='synchronize_srcu'>
@@ -145310,7 +146097,7 @@
       </function-decl>
       <var-decl name='sysctl_sched_features' type-id='f0981eeb' mangled-name='sysctl_sched_features' visibility='default' filepath='kernel/sched/core.c' line='70' column='1' elf-symbol-id='sysctl_sched_features'/>
       <var-decl name='sysctl_sched_latency' type-id='f0981eeb' mangled-name='sysctl_sched_latency' visibility='default' filepath='kernel/sched/fair.c' line='42' column='1' elf-symbol-id='sysctl_sched_latency'/>
-      <var-decl name='sysctl_vals' type-id='1fc64662' mangled-name='sysctl_vals' visibility='default' filepath='fs/proc/proc_sysctl.c' line='28' column='1' elf-symbol-id='sysctl_vals'/>
+      <var-decl name='sysctl_vals' type-id='1fc64662' mangled-name='sysctl_vals' visibility='default' filepath='fs/proc/proc_sysctl.c' line='29' column='1' elf-symbol-id='sysctl_vals'/>
       <function-decl name='sysfs_add_file_to_group' mangled-name='sysfs_add_file_to_group' filepath='fs/sysfs/file.c' line='358' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sysfs_add_file_to_group'>
         <parameter type-id='d30bdc51' name='kobj' filepath='fs/sysfs/file.c' line='358' column='1'/>
         <parameter type-id='cfe4f8a2' name='attr' filepath='fs/sysfs/file.c' line='359' column='1'/>
@@ -145449,7 +146236,7 @@
       <var-decl name='system_highpri_wq' type-id='242e3d19' mangled-name='system_highpri_wq' visibility='default' filepath='kernel/workqueue.c' line='349' column='1' elf-symbol-id='system_highpri_wq'/>
       <var-decl name='system_long_wq' type-id='242e3d19' mangled-name='system_long_wq' visibility='default' filepath='kernel/workqueue.c' line='351' column='1' elf-symbol-id='system_long_wq'/>
       <var-decl name='system_power_efficient_wq' type-id='242e3d19' mangled-name='system_power_efficient_wq' visibility='default' filepath='kernel/workqueue.c' line='357' column='1' elf-symbol-id='system_power_efficient_wq'/>
-      <var-decl name='system_state' type-id='2ead22b4' mangled-name='system_state' visibility='default' filepath='init/main.c' line='129' column='1' elf-symbol-id='system_state'/>
+      <var-decl name='system_state' type-id='2ead22b4' mangled-name='system_state' visibility='default' filepath='init/main.c' line='127' column='1' elf-symbol-id='system_state'/>
       <var-decl name='system_unbound_wq' type-id='242e3d19' mangled-name='system_unbound_wq' visibility='default' filepath='kernel/workqueue.c' line='353' column='1' elf-symbol-id='system_unbound_wq'/>
       <var-decl name='system_wq' type-id='242e3d19' mangled-name='system_wq' visibility='default' filepath='kernel/workqueue.c' line='347' column='1' elf-symbol-id='system_wq'/>
       <function-decl name='tag_pages_for_writeback' mangled-name='tag_pages_for_writeback' filepath='mm/page-writeback.c' line='2121' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tag_pages_for_writeback'>
@@ -145462,7 +146249,7 @@
         <parameter type-id='f23e2572' name='tsk' filepath='kernel/pid.c' line='508' column='1'/>
         <return type-id='b816e1d0'/>
       </function-decl>
-      <var-decl name='task_groups' type-id='72f469ec' mangled-name='task_groups' visibility='default' filepath='kernel/sched/core.c' line='7444' column='1' elf-symbol-id='task_groups'/>
+      <var-decl name='task_groups' type-id='72f469ec' mangled-name='task_groups' visibility='default' filepath='kernel/sched/core.c' line='7446' column='1' elf-symbol-id='task_groups'/>
       <function-decl name='task_may_not_preempt' mangled-name='task_may_not_preempt' filepath='kernel/sched/rt.c' line='1484' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='task_may_not_preempt'>
         <parameter type-id='f23e2572' name='task' filepath='kernel/sched/rt.c' line='1484' column='1'/>
         <parameter type-id='95e97e5e' name='cpu' filepath='kernel/sched/rt.c' line='1484' column='1'/>
@@ -145473,8 +146260,8 @@
         <parameter type-id='d0163a5e' name='rf' filepath='kernel/sched/core.c' line='219' column='1'/>
         <return type-id='6ed6b432'/>
       </function-decl>
-      <function-decl name='task_sched_runtime' mangled-name='task_sched_runtime' filepath='kernel/sched/core.c' line='4202' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='task_sched_runtime'>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='4202' column='1'/>
+      <function-decl name='task_sched_runtime' mangled-name='task_sched_runtime' filepath='kernel/sched/core.c' line='4205' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='task_sched_runtime'>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='4205' column='1'/>
         <return type-id='3a47d82b'/>
       </function-decl>
       <function-decl name='tasklet_init' mangled-name='tasklet_init' filepath='kernel/softirq.c' line='612' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tasklet_init'>
@@ -145500,43 +146287,43 @@
         <parameter type-id='e638cd0c' name='res' filepath='net/sched/act_api.c' line='676' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='tcf_exts_destroy' mangled-name='tcf_exts_destroy' filepath='net/sched/cls_api.c' line='3041' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcf_exts_destroy'>
-        <parameter type-id='6c257353' name='exts' filepath='net/sched/cls_api.c' line='3041' column='1'/>
+      <function-decl name='tcf_exts_destroy' mangled-name='tcf_exts_destroy' filepath='net/sched/cls_api.c' line='3043' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcf_exts_destroy'>
+        <parameter type-id='6c257353' name='exts' filepath='net/sched/cls_api.c' line='3043' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tcf_exts_dump' mangled-name='tcf_exts_dump' filepath='net/sched/cls_api.c' line='3126' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcf_exts_dump'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/sched/cls_api.c' line='3126' column='1'/>
-        <parameter type-id='6c257353' name='exts' filepath='net/sched/cls_api.c' line='3126' column='1'/>
+      <function-decl name='tcf_exts_dump' mangled-name='tcf_exts_dump' filepath='net/sched/cls_api.c' line='3128' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcf_exts_dump'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/sched/cls_api.c' line='3128' column='1'/>
+        <parameter type-id='6c257353' name='exts' filepath='net/sched/cls_api.c' line='3128' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='tcf_exts_dump_stats' mangled-name='tcf_exts_dump_stats' filepath='net/sched/cls_api.c' line='3193' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcf_exts_dump_stats'>
-        <parameter type-id='0fbf3cfd' name='skb' filepath='net/sched/cls_api.c' line='3193' column='1'/>
-        <parameter type-id='6c257353' name='exts' filepath='net/sched/cls_api.c' line='3193' column='1'/>
+      <function-decl name='tcf_exts_dump_stats' mangled-name='tcf_exts_dump_stats' filepath='net/sched/cls_api.c' line='3195' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcf_exts_dump_stats'>
+        <parameter type-id='0fbf3cfd' name='skb' filepath='net/sched/cls_api.c' line='3195' column='1'/>
+        <parameter type-id='6c257353' name='exts' filepath='net/sched/cls_api.c' line='3195' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='tcf_exts_validate' mangled-name='tcf_exts_validate' filepath='net/sched/cls_api.c' line='3053' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcf_exts_validate'>
-        <parameter type-id='a2bff676' name='net' filepath='net/sched/cls_api.c' line='3053' column='1'/>
-        <parameter type-id='6dca061b' name='tp' filepath='net/sched/cls_api.c' line='3053' column='1'/>
-        <parameter type-id='30864cdc' name='tb' filepath='net/sched/cls_api.c' line='3053' column='1'/>
-        <parameter type-id='6fcaf91e' name='rate_tlv' filepath='net/sched/cls_api.c' line='3054' column='1'/>
-        <parameter type-id='6c257353' name='exts' filepath='net/sched/cls_api.c' line='3054' column='1'/>
-        <parameter type-id='b50a4934' name='ovr' filepath='net/sched/cls_api.c' line='3054' column='1'/>
-        <parameter type-id='b50a4934' name='rtnl_held' filepath='net/sched/cls_api.c' line='3055' column='1'/>
-        <parameter type-id='5799dc94' name='extack' filepath='net/sched/cls_api.c' line='3055' column='1'/>
+      <function-decl name='tcf_exts_validate' mangled-name='tcf_exts_validate' filepath='net/sched/cls_api.c' line='3055' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcf_exts_validate'>
+        <parameter type-id='a2bff676' name='net' filepath='net/sched/cls_api.c' line='3055' column='1'/>
+        <parameter type-id='6dca061b' name='tp' filepath='net/sched/cls_api.c' line='3055' column='1'/>
+        <parameter type-id='30864cdc' name='tb' filepath='net/sched/cls_api.c' line='3055' column='1'/>
+        <parameter type-id='6fcaf91e' name='rate_tlv' filepath='net/sched/cls_api.c' line='3056' column='1'/>
+        <parameter type-id='6c257353' name='exts' filepath='net/sched/cls_api.c' line='3056' column='1'/>
+        <parameter type-id='b50a4934' name='ovr' filepath='net/sched/cls_api.c' line='3056' column='1'/>
+        <parameter type-id='b50a4934' name='rtnl_held' filepath='net/sched/cls_api.c' line='3057' column='1'/>
+        <parameter type-id='5799dc94' name='extack' filepath='net/sched/cls_api.c' line='3057' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='tcf_queue_work' mangled-name='tcf_queue_work' filepath='net/sched/cls_api.c' line='204' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcf_queue_work'>
-        <parameter type-id='b325c82b' name='rwork' filepath='net/sched/cls_api.c' line='204' column='1'/>
-        <parameter type-id='72666d3f' name='func' filepath='net/sched/cls_api.c' line='204' column='1'/>
+      <function-decl name='tcf_queue_work' mangled-name='tcf_queue_work' filepath='net/sched/cls_api.c' line='202' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcf_queue_work'>
+        <parameter type-id='b325c82b' name='rwork' filepath='net/sched/cls_api.c' line='202' column='1'/>
+        <parameter type-id='72666d3f' name='func' filepath='net/sched/cls_api.c' line='202' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
       <var-decl name='tcp_hashinfo' type-id='3482ac54' mangled-name='tcp_hashinfo' visibility='default' filepath='net/ipv4/tcp_ipv4.c' line='91' column='1' elf-symbol-id='tcp_hashinfo'/>
-      <function-decl name='tcp_parse_options' mangled-name='tcp_parse_options' filepath='net/ipv4/tcp_input.c' line='4003' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcp_parse_options'>
-        <parameter type-id='f91cf277' name='net' filepath='net/ipv4/tcp_input.c' line='4003' column='1'/>
-        <parameter type-id='11f4a000' name='skb' filepath='net/ipv4/tcp_input.c' line='4004' column='1'/>
-        <parameter type-id='61b9151d' name='opt_rx' filepath='net/ipv4/tcp_input.c' line='4005' column='1'/>
-        <parameter type-id='95e97e5e' name='estab' filepath='net/ipv4/tcp_input.c' line='4005' column='1'/>
-        <parameter type-id='f3a16a60' name='foc' filepath='net/ipv4/tcp_input.c' line='4006' column='1'/>
+      <function-decl name='tcp_parse_options' mangled-name='tcp_parse_options' filepath='net/ipv4/tcp_input.c' line='4009' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcp_parse_options'>
+        <parameter type-id='f91cf277' name='net' filepath='net/ipv4/tcp_input.c' line='4009' column='1'/>
+        <parameter type-id='11f4a000' name='skb' filepath='net/ipv4/tcp_input.c' line='4010' column='1'/>
+        <parameter type-id='61b9151d' name='opt_rx' filepath='net/ipv4/tcp_input.c' line='4011' column='1'/>
+        <parameter type-id='95e97e5e' name='estab' filepath='net/ipv4/tcp_input.c' line='4011' column='1'/>
+        <parameter type-id='f3a16a60' name='foc' filepath='net/ipv4/tcp_input.c' line='4012' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='tcp_register_congestion_control' mangled-name='tcp_register_congestion_control' filepath='net/ipv4/tcp_cong.c' line='70' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcp_register_congestion_control'>
@@ -145579,25 +146366,25 @@
         <parameter type-id='b6733265' name='data' filepath='drivers/usb/typec/tcpm/tcpci.c' line='799' column='1'/>
         <return type-id='eefe253e'/>
       </function-decl>
-      <function-decl name='tcpci_unregister_port' mangled-name='tcpci_unregister_port' filepath='drivers/usb/typec/tcpm/tcpci.c' line='854' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpci_unregister_port'>
-        <parameter type-id='eefe253e' name='tcpci' filepath='drivers/usb/typec/tcpm/tcpci.c' line='854' column='1'/>
+      <function-decl name='tcpci_unregister_port' mangled-name='tcpci_unregister_port' filepath='drivers/usb/typec/tcpm/tcpci.c' line='856' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpci_unregister_port'>
+        <parameter type-id='eefe253e' name='tcpci' filepath='drivers/usb/typec/tcpm/tcpci.c' line='856' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tcpm_cc_change' mangled-name='tcpm_cc_change' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5458' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_cc_change'>
-        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5458' column='1'/>
+      <function-decl name='tcpm_cc_change' mangled-name='tcpm_cc_change' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5483' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_cc_change'>
+        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5483' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tcpm_is_toggling' mangled-name='tcpm_is_toggling' filepath='drivers/usb/typec/tcpm/tcpm.c' line='3815' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_is_toggling'>
-        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='3815' column='1'/>
+      <function-decl name='tcpm_is_toggling' mangled-name='tcpm_is_toggling' filepath='drivers/usb/typec/tcpm/tcpm.c' line='3840' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_is_toggling'>
+        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='3840' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='tcpm_pd_hard_reset' mangled-name='tcpm_pd_hard_reset' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5476' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_pd_hard_reset'>
-        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5476' column='1'/>
+      <function-decl name='tcpm_pd_hard_reset' mangled-name='tcpm_pd_hard_reset' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5501' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_pd_hard_reset'>
+        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5501' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tcpm_pd_receive' mangled-name='tcpm_pd_receive' filepath='drivers/usb/typec/tcpm/tcpm.c' line='2937' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_pd_receive'>
-        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='2937' column='1'/>
-        <parameter type-id='d7f1fb72' name='msg' filepath='drivers/usb/typec/tcpm/tcpm.c' line='2937' column='1'/>
+      <function-decl name='tcpm_pd_receive' mangled-name='tcpm_pd_receive' filepath='drivers/usb/typec/tcpm/tcpm.c' line='2962' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_pd_receive'>
+        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='2962' column='1'/>
+        <parameter type-id='d7f1fb72' name='msg' filepath='drivers/usb/typec/tcpm/tcpm.c' line='2962' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='tcpm_pd_transmit_complete' mangled-name='tcpm_pd_transmit_complete' filepath='drivers/usb/typec/tcpm/tcpm.c' line='919' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_pd_transmit_complete'>
@@ -145605,36 +146392,36 @@
         <parameter type-id='a2f9e316' name='status' filepath='drivers/usb/typec/tcpm/tcpm.c' line='920' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tcpm_register_port' mangled-name='tcpm_register_port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6443' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_register_port'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6443' column='1'/>
-        <parameter type-id='15b1f129' name='tcpc' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6443' column='1'/>
+      <function-decl name='tcpm_register_port' mangled-name='tcpm_register_port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6468' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_register_port'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6468' column='1'/>
+        <parameter type-id='15b1f129' name='tcpc' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6468' column='1'/>
         <return type-id='426e425b'/>
       </function-decl>
-      <function-decl name='tcpm_sink_frs' mangled-name='tcpm_sink_frs' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5485' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_sink_frs'>
-        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5485' column='1'/>
+      <function-decl name='tcpm_sink_frs' mangled-name='tcpm_sink_frs' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5510' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_sink_frs'>
+        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5510' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tcpm_sourcing_vbus' mangled-name='tcpm_sourcing_vbus' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5494' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_sourcing_vbus'>
-        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5494' column='1'/>
+      <function-decl name='tcpm_sourcing_vbus' mangled-name='tcpm_sourcing_vbus' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5519' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_sourcing_vbus'>
+        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5519' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tcpm_tcpc_reset' mangled-name='tcpm_tcpc_reset' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6008' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_tcpc_reset'>
-        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6008' column='1'/>
+      <function-decl name='tcpm_tcpc_reset' mangled-name='tcpm_tcpc_reset' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6033' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_tcpc_reset'>
+        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6033' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tcpm_unregister_port' mangled-name='tcpm_unregister_port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6540' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_unregister_port'>
-        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6540' column='1'/>
+      <function-decl name='tcpm_unregister_port' mangled-name='tcpm_unregister_port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6569' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_unregister_port'>
+        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6569' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tcpm_update_sink_capabilities' mangled-name='tcpm_update_sink_capabilities' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6146' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_update_sink_capabilities'>
-        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6146' column='1'/>
-        <parameter type-id='aded214c' name='pdo' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6146' column='1'/>
-        <parameter type-id='f0981eeb' name='nr_pdo' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6146' column='1'/>
-        <parameter type-id='f0981eeb' name='operating_snk_mw' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6147' column='1'/>
+      <function-decl name='tcpm_update_sink_capabilities' mangled-name='tcpm_update_sink_capabilities' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6171' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_update_sink_capabilities'>
+        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6171' column='1'/>
+        <parameter type-id='aded214c' name='pdo' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6171' column='1'/>
+        <parameter type-id='f0981eeb' name='nr_pdo' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6171' column='1'/>
+        <parameter type-id='f0981eeb' name='operating_snk_mw' filepath='drivers/usb/typec/tcpm/tcpm.c' line='6172' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='tcpm_vbus_change' mangled-name='tcpm_vbus_change' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5467' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_vbus_change'>
-        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5467' column='1'/>
+      <function-decl name='tcpm_vbus_change' mangled-name='tcpm_vbus_change' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5492' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tcpm_vbus_change'>
+        <parameter type-id='426e425b' name='port' filepath='drivers/usb/typec/tcpm/tcpm.c' line='5492' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='thaw_bdev' mangled-name='thaw_bdev' filepath='fs/block_dev.c' line='610' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='thaw_bdev'>
@@ -145745,12 +146532,12 @@
         <parameter type-id='3df9fd28' name='st' filepath='kernel/sched/cputime.c' line='639' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tick_nohz_get_idle_calls_cpu' mangled-name='tick_nohz_get_idle_calls_cpu' filepath='kernel/time/tick-sched.c' line='1123' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tick_nohz_get_idle_calls_cpu'>
-        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/time/tick-sched.c' line='1123' column='1'/>
+      <function-decl name='tick_nohz_get_idle_calls_cpu' mangled-name='tick_nohz_get_idle_calls_cpu' filepath='kernel/time/tick-sched.c' line='1162' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tick_nohz_get_idle_calls_cpu'>
+        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/time/tick-sched.c' line='1162' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='tick_nohz_get_sleep_length' mangled-name='tick_nohz_get_sleep_length' filepath='kernel/time/tick-sched.c' line='1083' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tick_nohz_get_sleep_length'>
-        <parameter type-id='44372936' name='delta_next' filepath='kernel/time/tick-sched.c' line='1083' column='1'/>
+      <function-decl name='tick_nohz_get_sleep_length' mangled-name='tick_nohz_get_sleep_length' filepath='kernel/time/tick-sched.c' line='1122' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tick_nohz_get_sleep_length'>
+        <parameter type-id='44372936' name='delta_next' filepath='kernel/time/tick-sched.c' line='1122' column='1'/>
         <return type-id='fbc017ef'/>
       </function-decl>
       <function-decl name='time64_to_tm' mangled-name='time64_to_tm' filepath='kernel/time/timeconv.c' line='78' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='time64_to_tm'>
@@ -145789,9 +146576,9 @@
         <parameter type-id='0817f042' name='value' filepath='kernel/time/time.c' line='588' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='timestamp_truncate' mangled-name='timestamp_truncate' filepath='fs/inode.c' line='2253' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='timestamp_truncate'>
-        <parameter type-id='40a816ad' name='t' filepath='fs/inode.c' line='2253' column='1'/>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2253' column='1'/>
+      <function-decl name='timestamp_truncate' mangled-name='timestamp_truncate' filepath='fs/inode.c' line='2262' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='timestamp_truncate'>
+        <parameter type-id='40a816ad' name='t' filepath='fs/inode.c' line='2262' column='1'/>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2262' column='1'/>
         <return type-id='40a816ad'/>
       </function-decl>
       <function-decl name='topology_set_thermal_pressure' mangled-name='topology_set_thermal_pressure' filepath='drivers/base/arch_topology.c' line='74' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='topology_set_thermal_pressure'>
@@ -145802,8 +146589,8 @@
       <function-decl name='total_swapcache_pages' mangled-name='total_swapcache_pages' filepath='mm/swap_state.c' line='71' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='total_swapcache_pages'>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='touch_atime' mangled-name='touch_atime' filepath='fs/inode.c' line='1826' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='touch_atime'>
-        <parameter type-id='a77efac3' name='path' filepath='fs/inode.c' line='1826' column='1'/>
+      <function-decl name='touch_atime' mangled-name='touch_atime' filepath='fs/inode.c' line='1868' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='touch_atime'>
+        <parameter type-id='a77efac3' name='path' filepath='fs/inode.c' line='1868' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='touchscreen_parse_properties' mangled-name='touchscreen_parse_properties' filepath='drivers/input/touchscreen/of_touchscreen.c' line='64' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='touchscreen_parse_properties'>
@@ -145820,8 +146607,8 @@
         <parameter type-id='b50a4934' name='multitouch' filepath='drivers/input/touchscreen/of_touchscreen.c' line='197' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='trace_array_get_by_name' mangled-name='trace_array_get_by_name' filepath='kernel/trace/trace.c' line='8838' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='trace_array_get_by_name'>
-        <parameter type-id='80f4b756' name='name' filepath='kernel/trace/trace.c' line='8838' column='1'/>
+      <function-decl name='trace_array_get_by_name' mangled-name='trace_array_get_by_name' filepath='kernel/trace/trace.c' line='8860' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='trace_array_get_by_name'>
+        <parameter type-id='80f4b756' name='name' filepath='kernel/trace/trace.c' line='8860' column='1'/>
         <return type-id='898c1076'/>
       </function-decl>
       <function-decl name='trace_array_put' mangled-name='trace_array_put' filepath='kernel/trace/trace.c' line='468' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='trace_array_put'>
@@ -145838,8 +146625,8 @@
       <function-decl name='trace_clock_local' mangled-name='trace_clock_local' filepath='kernel/trace/trace_clock.c' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='trace_clock_local'>
         <return type-id='91ce1af9'/>
       </function-decl>
-      <function-decl name='trace_event_buffer_commit' mangled-name='trace_event_buffer_commit' filepath='kernel/trace/trace.c' line='2874' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='trace_event_buffer_commit'>
-        <parameter type-id='9f548f9a' name='fbuffer' filepath='kernel/trace/trace.c' line='2874' column='1'/>
+      <function-decl name='trace_event_buffer_commit' mangled-name='trace_event_buffer_commit' filepath='kernel/trace/trace.c' line='2883' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='trace_event_buffer_commit'>
+        <parameter type-id='9f548f9a' name='fbuffer' filepath='kernel/trace/trace.c' line='2883' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='trace_event_buffer_reserve' mangled-name='trace_event_buffer_reserve' filepath='kernel/trace/trace_events.c' line='252' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='trace_event_buffer_reserve'>
@@ -145868,8 +146655,8 @@
         <parameter type-id='80f4b756' name='event' filepath='kernel/trace/trace_events.c' line='2768' column='1'/>
         <return type-id='3d4ca6d2'/>
       </function-decl>
-      <function-decl name='trace_handle_return' mangled-name='trace_handle_return' filepath='kernel/trace/trace.c' line='2610' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='trace_handle_return'>
-        <parameter type-id='fc932690' name='s' filepath='kernel/trace/trace.c' line='2610' column='1'/>
+      <function-decl name='trace_handle_return' mangled-name='trace_handle_return' filepath='kernel/trace/trace.c' line='2619' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='trace_handle_return'>
+        <parameter type-id='fc932690' name='s' filepath='kernel/trace/trace.c' line='2619' column='1'/>
         <return type-id='b1a0a119'/>
       </function-decl>
       <function-decl name='trace_output_call' mangled-name='trace_output_call' filepath='kernel/trace/trace_output.c' line='326' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='trace_output_call'>
@@ -145999,21 +146786,21 @@
         <parameter type-id='9248e67f' name='timer' filepath='kernel/time/timer.c' line='1229' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='try_to_free_mem_cgroup_pages' mangled-name='try_to_free_mem_cgroup_pages' filepath='mm/vmscan.c' line='3414' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='try_to_free_mem_cgroup_pages'>
-        <parameter type-id='223696fb' name='memcg' filepath='mm/vmscan.c' line='3414' column='1'/>
-        <parameter type-id='7359adad' name='nr_pages' filepath='mm/vmscan.c' line='3415' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/vmscan.c' line='3416' column='1'/>
-        <parameter type-id='b50a4934' name='may_swap' filepath='mm/vmscan.c' line='3417' column='1'/>
+      <function-decl name='try_to_free_mem_cgroup_pages' mangled-name='try_to_free_mem_cgroup_pages' filepath='mm/vmscan.c' line='3427' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='try_to_free_mem_cgroup_pages'>
+        <parameter type-id='223696fb' name='memcg' filepath='mm/vmscan.c' line='3427' column='1'/>
+        <parameter type-id='7359adad' name='nr_pages' filepath='mm/vmscan.c' line='3428' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/vmscan.c' line='3429' column='1'/>
+        <parameter type-id='b50a4934' name='may_swap' filepath='mm/vmscan.c' line='3430' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='try_to_release_page' mangled-name='try_to_release_page' filepath='mm/filemap.c' line='3688' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='try_to_release_page'>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/filemap.c' line='3688' column='1'/>
-        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/filemap.c' line='3688' column='1'/>
+      <function-decl name='try_to_release_page' mangled-name='try_to_release_page' filepath='mm/filemap.c' line='3695' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='try_to_release_page'>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/filemap.c' line='3695' column='1'/>
+        <parameter type-id='3eb7c31c' name='gfp_mask' filepath='mm/filemap.c' line='3695' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='try_to_writeback_inodes_sb' mangled-name='try_to_writeback_inodes_sb' filepath='fs/fs-writeback.c' line='2502' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='try_to_writeback_inodes_sb'>
-        <parameter type-id='42c8f564' name='sb' filepath='fs/fs-writeback.c' line='2502' column='1'/>
-        <parameter type-id='c1602c7a' name='reason' filepath='fs/fs-writeback.c' line='2502' column='1'/>
+      <function-decl name='try_to_writeback_inodes_sb' mangled-name='try_to_writeback_inodes_sb' filepath='fs/fs-writeback.c' line='2505' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='try_to_writeback_inodes_sb'>
+        <parameter type-id='42c8f564' name='sb' filepath='fs/fs-writeback.c' line='2505' column='1'/>
+        <parameter type-id='c1602c7a' name='reason' filepath='fs/fs-writeback.c' line='2505' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='try_wait_for_completion' mangled-name='try_wait_for_completion' filepath='kernel/sched/completion.c' line='282' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='try_wait_for_completion'>
@@ -146157,10 +146944,20 @@
         <parameter type-id='95e97e5e' name='resched' filepath='drivers/gpu/drm/ttm/ttm_bo.c' line='590' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
+      <function-decl name='ttm_bo_unmap_virtual' mangled-name='ttm_bo_unmap_virtual' filepath='drivers/gpu/drm/ttm/ttm_bo.c' line='1473' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ttm_bo_unmap_virtual'>
+        <parameter type-id='9d57e433' name='bo' filepath='drivers/gpu/drm/ttm/ttm_bo.c' line='1473' column='1'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
       <function-decl name='ttm_bo_validate' mangled-name='ttm_bo_validate' filepath='drivers/gpu/drm/ttm/ttm_bo.c' line='1078' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ttm_bo_validate'>
         <parameter type-id='9d57e433' name='bo' filepath='drivers/gpu/drm/ttm/ttm_bo.c' line='1078' column='1'/>
         <parameter type-id='1d36520e' name='placement' filepath='drivers/gpu/drm/ttm/ttm_bo.c' line='1079' column='1'/>
         <parameter type-id='7c3e509a' name='ctx' filepath='drivers/gpu/drm/ttm/ttm_bo.c' line='1080' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='ttm_bo_wait' mangled-name='ttm_bo_wait' filepath='drivers/gpu/drm/ttm/ttm_bo.c' line='1482' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ttm_bo_wait'>
+        <parameter type-id='9d57e433' name='bo' filepath='drivers/gpu/drm/ttm/ttm_bo.c' line='1482' column='1'/>
+        <parameter type-id='b50a4934' name='interruptible' filepath='drivers/gpu/drm/ttm/ttm_bo.c' line='1483' column='1'/>
+        <parameter type-id='b50a4934' name='no_wait' filepath='drivers/gpu/drm/ttm/ttm_bo.c' line='1483' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='ttm_dma_page_alloc_debugfs' mangled-name='ttm_dma_page_alloc_debugfs' filepath='drivers/gpu/drm/ttm/ttm_page_alloc_dma.c' line='1214' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ttm_dma_page_alloc_debugfs'>
@@ -146261,27 +147058,32 @@
         <parameter type-id='8f92235e' name='placement' filepath='drivers/gpu/drm/ttm/ttm_tt.c' line='195' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
+      <function-decl name='ttm_tt_unpopulate' mangled-name='ttm_tt_unpopulate' filepath='drivers/gpu/drm/ttm/ttm_tt.c' line='457' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ttm_tt_unpopulate'>
+        <parameter type-id='723d4d79' name='bdev' filepath='drivers/gpu/drm/ttm/ttm_tt.c' line='457' column='1'/>
+        <parameter type-id='c21baddd' name='ttm' filepath='drivers/gpu/drm/ttm/ttm_tt.c' line='458' column='1'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
       <function-decl name='ttm_unmap_and_unpopulate_pages' mangled-name='ttm_unmap_and_unpopulate_pages' filepath='drivers/gpu/drm/ttm/ttm_page_alloc.c' line='1140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ttm_unmap_and_unpopulate_pages'>
         <parameter type-id='fa0b179b' name='dev' filepath='drivers/gpu/drm/ttm/ttm_page_alloc.c' line='1140' column='1'/>
         <parameter type-id='6621f500' name='tt' filepath='drivers/gpu/drm/ttm/ttm_page_alloc.c' line='1140' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tty_driver_flush_buffer' mangled-name='tty_driver_flush_buffer' filepath='drivers/tty/tty_ioctl.c' line='92' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_driver_flush_buffer'>
-        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_ioctl.c' line='92' column='1'/>
+      <function-decl name='tty_driver_flush_buffer' mangled-name='tty_driver_flush_buffer' filepath='drivers/tty/tty_ioctl.c' line='93' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_driver_flush_buffer'>
+        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_ioctl.c' line='93' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tty_encode_baud_rate' mangled-name='tty_encode_baud_rate' filepath='drivers/tty/tty_baudrate.c' line='233' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_encode_baud_rate'>
-        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_baudrate.c' line='233' column='1'/>
-        <parameter type-id='6a8e8a14' name='ibaud' filepath='drivers/tty/tty_baudrate.c' line='233' column='1'/>
-        <parameter type-id='6a8e8a14' name='obaud' filepath='drivers/tty/tty_baudrate.c' line='233' column='1'/>
+      <function-decl name='tty_encode_baud_rate' mangled-name='tty_encode_baud_rate' filepath='drivers/tty/tty_baudrate.c' line='234' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_encode_baud_rate'>
+        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_baudrate.c' line='234' column='1'/>
+        <parameter type-id='6a8e8a14' name='ibaud' filepath='drivers/tty/tty_baudrate.c' line='234' column='1'/>
+        <parameter type-id='6a8e8a14' name='obaud' filepath='drivers/tty/tty_baudrate.c' line='234' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='tty_flip_buffer_push' mangled-name='tty_flip_buffer_push' filepath='drivers/tty/tty_buffer.c' line='546' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_flip_buffer_push'>
         <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_buffer.c' line='546' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tty_hangup' mangled-name='tty_hangup' filepath='drivers/tty/tty_io.c' line='677' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_hangup'>
-        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_io.c' line='677' column='1'/>
+      <function-decl name='tty_hangup' mangled-name='tty_hangup' filepath='drivers/tty/tty_io.c' line='678' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_hangup'>
+        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_io.c' line='678' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='tty_insert_flip_string_fixed_flag' mangled-name='tty_insert_flip_string_fixed_flag' filepath='drivers/tty/tty_buffer.c' line='312' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_insert_flip_string_fixed_flag'>
@@ -146291,114 +147093,119 @@
         <parameter type-id='b59d7dce' name='size' filepath='drivers/tty/tty_buffer.c' line='313' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='tty_kref_put' mangled-name='tty_kref_put' filepath='drivers/tty/tty_io.c' line='1570' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_kref_put'>
-        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_io.c' line='1570' column='1'/>
+      <function-decl name='tty_kref_put' mangled-name='tty_kref_put' filepath='drivers/tty/tty_io.c' line='1573' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_kref_put'>
+        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_io.c' line='1573' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tty_ldisc_deref' mangled-name='tty_ldisc_deref' filepath='drivers/tty/tty_ldisc.c' line='304' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_ldisc_deref'>
-        <parameter type-id='e0bbd59c' name='ld' filepath='drivers/tty/tty_ldisc.c' line='304' column='1'/>
+      <function-decl name='tty_ldisc_deref' mangled-name='tty_ldisc_deref' filepath='drivers/tty/tty_ldisc.c' line='305' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_ldisc_deref'>
+        <parameter type-id='e0bbd59c' name='ld' filepath='drivers/tty/tty_ldisc.c' line='305' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tty_ldisc_ref' mangled-name='tty_ldisc_ref' filepath='drivers/tty/tty_ldisc.c' line='283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_ldisc_ref'>
-        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_ldisc.c' line='283' column='1'/>
+      <function-decl name='tty_ldisc_ref' mangled-name='tty_ldisc_ref' filepath='drivers/tty/tty_ldisc.c' line='284' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_ldisc_ref'>
+        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_ldisc.c' line='284' column='1'/>
         <return type-id='e0bbd59c'/>
       </function-decl>
-      <function-decl name='tty_mode_ioctl' mangled-name='tty_mode_ioctl' filepath='drivers/tty/tty_ioctl.c' line='663' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_mode_ioctl'>
-        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_ioctl.c' line='663' column='1'/>
-        <parameter type-id='77e79a4b' name='file' filepath='drivers/tty/tty_ioctl.c' line='663' column='1'/>
-        <parameter type-id='f0981eeb' name='cmd' filepath='drivers/tty/tty_ioctl.c' line='664' column='1'/>
-        <parameter type-id='7359adad' name='arg' filepath='drivers/tty/tty_ioctl.c' line='664' column='1'/>
+      <function-decl name='tty_mode_ioctl' mangled-name='tty_mode_ioctl' filepath='drivers/tty/tty_ioctl.c' line='685' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_mode_ioctl'>
+        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_ioctl.c' line='685' column='1'/>
+        <parameter type-id='77e79a4b' name='file' filepath='drivers/tty/tty_ioctl.c' line='685' column='1'/>
+        <parameter type-id='f0981eeb' name='cmd' filepath='drivers/tty/tty_ioctl.c' line='686' column='1'/>
+        <parameter type-id='7359adad' name='arg' filepath='drivers/tty/tty_ioctl.c' line='686' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='tty_port_close' mangled-name='tty_port_close' filepath='drivers/tty/tty_port.c' line='631' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_close'>
-        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='631' column='1'/>
-        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_port.c' line='631' column='1'/>
-        <parameter type-id='77e79a4b' name='filp' filepath='drivers/tty/tty_port.c' line='632' column='1'/>
+      <function-decl name='tty_port_close' mangled-name='tty_port_close' filepath='drivers/tty/tty_port.c' line='632' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_close'>
+        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='632' column='1'/>
+        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_port.c' line='632' column='1'/>
+        <parameter type-id='77e79a4b' name='filp' filepath='drivers/tty/tty_port.c' line='633' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tty_port_destroy' mangled-name='tty_port_destroy' filepath='drivers/tty/tty_port.c' line='246' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_destroy'>
-        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='246' column='1'/>
+      <function-decl name='tty_port_destroy' mangled-name='tty_port_destroy' filepath='drivers/tty/tty_port.c' line='247' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_destroy'>
+        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='247' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tty_port_hangup' mangled-name='tty_port_hangup' filepath='drivers/tty/tty_port.c' line='345' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_hangup'>
-        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='345' column='1'/>
+      <function-decl name='tty_port_hangup' mangled-name='tty_port_hangup' filepath='drivers/tty/tty_port.c' line='346' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_hangup'>
+        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='346' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tty_port_init' mangled-name='tty_port_init' filepath='drivers/tty/tty_port.c' line='61' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_init'>
-        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='61' column='1'/>
+      <function-decl name='tty_port_init' mangled-name='tty_port_init' filepath='drivers/tty/tty_port.c' line='62' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_init'>
+        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='62' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tty_port_open' mangled-name='tty_port_open' filepath='drivers/tty/tty_port.c' line='670' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_open'>
-        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='670' column='1'/>
-        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_port.c' line='670' column='1'/>
-        <parameter type-id='77e79a4b' name='filp' filepath='drivers/tty/tty_port.c' line='671' column='1'/>
+      <function-decl name='tty_port_open' mangled-name='tty_port_open' filepath='drivers/tty/tty_port.c' line='671' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_open'>
+        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='671' column='1'/>
+        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_port.c' line='671' column='1'/>
+        <parameter type-id='77e79a4b' name='filp' filepath='drivers/tty/tty_port.c' line='672' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='tty_port_register_device' mangled-name='tty_port_register_device' filepath='drivers/tty/tty_port.c' line='108' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_register_device'>
-        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='108' column='1'/>
-        <parameter type-id='c2b4b27b' name='driver' filepath='drivers/tty/tty_port.c' line='109' column='1'/>
-        <parameter type-id='f0981eeb' name='index' filepath='drivers/tty/tty_port.c' line='109' column='1'/>
-        <parameter type-id='fa0b179b' name='device' filepath='drivers/tty/tty_port.c' line='110' column='1'/>
+      <function-decl name='tty_port_register_device' mangled-name='tty_port_register_device' filepath='drivers/tty/tty_port.c' line='109' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_register_device'>
+        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='109' column='1'/>
+        <parameter type-id='c2b4b27b' name='driver' filepath='drivers/tty/tty_port.c' line='110' column='1'/>
+        <parameter type-id='f0981eeb' name='index' filepath='drivers/tty/tty_port.c' line='110' column='1'/>
+        <parameter type-id='fa0b179b' name='device' filepath='drivers/tty/tty_port.c' line='111' column='1'/>
         <return type-id='fa0b179b'/>
       </function-decl>
-      <function-decl name='tty_port_tty_get' mangled-name='tty_port_tty_get' filepath='drivers/tty/tty_port.c' line='283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_tty_get'>
-        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='283' column='1'/>
+      <function-decl name='tty_port_tty_get' mangled-name='tty_port_tty_get' filepath='drivers/tty/tty_port.c' line='284' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_tty_get'>
+        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='284' column='1'/>
         <return type-id='572fbdca'/>
       </function-decl>
-      <function-decl name='tty_port_tty_wakeup' mangled-name='tty_port_tty_wakeup' filepath='drivers/tty/tty_port.c' line='386' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_tty_wakeup'>
-        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='386' column='1'/>
+      <function-decl name='tty_port_tty_wakeup' mangled-name='tty_port_tty_wakeup' filepath='drivers/tty/tty_port.c' line='387' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_port_tty_wakeup'>
+        <parameter type-id='ec77b5b8' name='port' filepath='drivers/tty/tty_port.c' line='387' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tty_register_driver' mangled-name='tty_register_driver' filepath='drivers/tty/tty_io.c' line='3406' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_register_driver'>
-        <parameter type-id='c2b4b27b' name='driver' filepath='drivers/tty/tty_io.c' line='3406' column='1'/>
+      <function-decl name='tty_register_driver' mangled-name='tty_register_driver' filepath='drivers/tty/tty_io.c' line='3409' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_register_driver'>
+        <parameter type-id='c2b4b27b' name='driver' filepath='drivers/tty/tty_io.c' line='3409' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='tty_register_ldisc' mangled-name='tty_register_ldisc' filepath='drivers/tty/tty_ldisc.c' line='61' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_register_ldisc'>
-        <parameter type-id='95e97e5e' name='disc' filepath='drivers/tty/tty_ldisc.c' line='61' column='1'/>
-        <parameter type-id='9d632ac5' name='new_ldisc' filepath='drivers/tty/tty_ldisc.c' line='61' column='1'/>
+      <function-decl name='tty_register_ldisc' mangled-name='tty_register_ldisc' filepath='drivers/tty/tty_ldisc.c' line='62' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_register_ldisc'>
+        <parameter type-id='95e97e5e' name='disc' filepath='drivers/tty/tty_ldisc.c' line='62' column='1'/>
+        <parameter type-id='9d632ac5' name='new_ldisc' filepath='drivers/tty/tty_ldisc.c' line='62' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='tty_set_operations' mangled-name='tty_set_operations' filepath='drivers/tty/tty_io.c' line='3390' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_set_operations'>
-        <parameter type-id='c2b4b27b' name='driver' filepath='drivers/tty/tty_io.c' line='3390' column='1'/>
-        <parameter type-id='f2c18b44' name='op' filepath='drivers/tty/tty_io.c' line='3391' column='1'/>
+      <function-decl name='tty_set_operations' mangled-name='tty_set_operations' filepath='drivers/tty/tty_io.c' line='3393' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_set_operations'>
+        <parameter type-id='c2b4b27b' name='driver' filepath='drivers/tty/tty_io.c' line='3393' column='1'/>
+        <parameter type-id='f2c18b44' name='op' filepath='drivers/tty/tty_io.c' line='3394' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tty_standard_install' mangled-name='tty_standard_install' filepath='drivers/tty/tty_io.c' line='1283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_standard_install'>
-        <parameter type-id='c2b4b27b' name='driver' filepath='drivers/tty/tty_io.c' line='1283' column='1'/>
-        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_io.c' line='1283' column='1'/>
+      <function-decl name='tty_standard_install' mangled-name='tty_standard_install' filepath='drivers/tty/tty_io.c' line='1286' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_standard_install'>
+        <parameter type-id='c2b4b27b' name='driver' filepath='drivers/tty/tty_io.c' line='1286' column='1'/>
+        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_io.c' line='1286' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <var-decl name='tty_std_termios' type-id='2f8662b5' mangled-name='tty_std_termios' visibility='default' filepath='drivers/tty/tty_io.c' line='122' column='1' elf-symbol-id='tty_std_termios'/>
-      <function-decl name='tty_termios_baud_rate' mangled-name='tty_termios_baud_rate' filepath='drivers/tty/tty_baudrate.c' line='57' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_termios_baud_rate'>
-        <parameter type-id='e55856e5' name='termios' filepath='drivers/tty/tty_baudrate.c' line='57' column='1'/>
+      <var-decl name='tty_std_termios' type-id='2f8662b5' mangled-name='tty_std_termios' visibility='default' filepath='drivers/tty/tty_io.c' line='123' column='1' elf-symbol-id='tty_std_termios'/>
+      <function-decl name='tty_termios_baud_rate' mangled-name='tty_termios_baud_rate' filepath='drivers/tty/tty_baudrate.c' line='58' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_termios_baud_rate'>
+        <parameter type-id='e55856e5' name='termios' filepath='drivers/tty/tty_baudrate.c' line='58' column='1'/>
         <return type-id='6a8e8a14'/>
       </function-decl>
-      <function-decl name='tty_termios_copy_hw' mangled-name='tty_termios_copy_hw' filepath='drivers/tty/tty_ioctl.c' line='273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_termios_copy_hw'>
-        <parameter type-id='e55856e5' name='new' filepath='drivers/tty/tty_ioctl.c' line='273' column='1'/>
-        <parameter type-id='e55856e5' name='old' filepath='drivers/tty/tty_ioctl.c' line='273' column='1'/>
+      <function-decl name='tty_termios_copy_hw' mangled-name='tty_termios_copy_hw' filepath='drivers/tty/tty_ioctl.c' line='274' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_termios_copy_hw'>
+        <parameter type-id='e55856e5' name='new' filepath='drivers/tty/tty_ioctl.c' line='274' column='1'/>
+        <parameter type-id='e55856e5' name='old' filepath='drivers/tty/tty_ioctl.c' line='274' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tty_termios_encode_baud_rate' mangled-name='tty_termios_encode_baud_rate' filepath='drivers/tty/tty_baudrate.c' line='141' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_termios_encode_baud_rate'>
-        <parameter type-id='e55856e5' name='termios' filepath='drivers/tty/tty_baudrate.c' line='141' column='1'/>
-        <parameter type-id='6a8e8a14' name='ibaud' filepath='drivers/tty/tty_baudrate.c' line='142' column='1'/>
-        <parameter type-id='6a8e8a14' name='obaud' filepath='drivers/tty/tty_baudrate.c' line='142' column='1'/>
+      <function-decl name='tty_termios_encode_baud_rate' mangled-name='tty_termios_encode_baud_rate' filepath='drivers/tty/tty_baudrate.c' line='142' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_termios_encode_baud_rate'>
+        <parameter type-id='e55856e5' name='termios' filepath='drivers/tty/tty_baudrate.c' line='142' column='1'/>
+        <parameter type-id='6a8e8a14' name='ibaud' filepath='drivers/tty/tty_baudrate.c' line='143' column='1'/>
+        <parameter type-id='6a8e8a14' name='obaud' filepath='drivers/tty/tty_baudrate.c' line='143' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='tty_unregister_device' mangled-name='tty_unregister_device' filepath='drivers/tty/tty_io.c' line='3279' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_unregister_device'>
-        <parameter type-id='c2b4b27b' name='driver' filepath='drivers/tty/tty_io.c' line='3279' column='1'/>
-        <parameter type-id='f0981eeb' name='index' filepath='drivers/tty/tty_io.c' line='3279' column='1'/>
-        <return type-id='48b5725f'/>
-      </function-decl>
-      <function-decl name='tty_unregister_driver' mangled-name='tty_unregister_driver' filepath='drivers/tty/tty_io.c' line='3468' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_unregister_driver'>
-        <parameter type-id='c2b4b27b' name='driver' filepath='drivers/tty/tty_io.c' line='3468' column='1'/>
+      <function-decl name='tty_termios_hw_change' mangled-name='tty_termios_hw_change' filepath='drivers/tty/tty_ioctl.c' line='294' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_termios_hw_change'>
+        <parameter type-id='d705010a' name='a' filepath='drivers/tty/tty_ioctl.c' line='294' column='1'/>
+        <parameter type-id='d705010a' name='b' filepath='drivers/tty/tty_ioctl.c' line='294' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='tty_unregister_ldisc' mangled-name='tty_unregister_ldisc' filepath='drivers/tty/tty_ldisc.c' line='90' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_unregister_ldisc'>
-        <parameter type-id='95e97e5e' name='disc' filepath='drivers/tty/tty_ldisc.c' line='90' column='1'/>
+      <function-decl name='tty_unregister_device' mangled-name='tty_unregister_device' filepath='drivers/tty/tty_io.c' line='3282' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_unregister_device'>
+        <parameter type-id='c2b4b27b' name='driver' filepath='drivers/tty/tty_io.c' line='3282' column='1'/>
+        <parameter type-id='f0981eeb' name='index' filepath='drivers/tty/tty_io.c' line='3282' column='1'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
+      <function-decl name='tty_unregister_driver' mangled-name='tty_unregister_driver' filepath='drivers/tty/tty_io.c' line='3471' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_unregister_driver'>
+        <parameter type-id='c2b4b27b' name='driver' filepath='drivers/tty/tty_io.c' line='3471' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='tty_vhangup' mangled-name='tty_vhangup' filepath='drivers/tty/tty_io.c' line='694' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_vhangup'>
-        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_io.c' line='694' column='1'/>
+      <function-decl name='tty_unregister_ldisc' mangled-name='tty_unregister_ldisc' filepath='drivers/tty/tty_ldisc.c' line='91' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_unregister_ldisc'>
+        <parameter type-id='95e97e5e' name='disc' filepath='drivers/tty/tty_ldisc.c' line='91' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='tty_vhangup' mangled-name='tty_vhangup' filepath='drivers/tty/tty_io.c' line='695' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tty_vhangup'>
+        <parameter type-id='572fbdca' name='tty' filepath='drivers/tty/tty_io.c' line='695' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='typec_altmode2port' mangled-name='typec_altmode2port' filepath='drivers/usb/typec/class.c' line='377' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='typec_altmode2port'>
@@ -146485,9 +147292,9 @@
         <parameter type-id='a5263fbd' name='desc' filepath='drivers/usb/typec/class.c' line='858' column='1'/>
         <return type-id='33ca4bbb'/>
       </function-decl>
-      <function-decl name='typec_register_port' mangled-name='typec_register_port' filepath='drivers/usb/typec/class.c' line='1996' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='typec_register_port'>
-        <parameter type-id='fa0b179b' name='parent' filepath='drivers/usb/typec/class.c' line='1996' column='1'/>
-        <parameter type-id='287e28ea' name='cap' filepath='drivers/usb/typec/class.c' line='1997' column='1'/>
+      <function-decl name='typec_register_port' mangled-name='typec_register_port' filepath='drivers/usb/typec/class.c' line='2050' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='typec_register_port'>
+        <parameter type-id='fa0b179b' name='parent' filepath='drivers/usb/typec/class.c' line='2050' column='1'/>
+        <parameter type-id='287e28ea' name='cap' filepath='drivers/usb/typec/class.c' line='2051' column='1'/>
         <return type-id='b977ca56'/>
       </function-decl>
       <function-decl name='typec_set_data_role' mangled-name='typec_set_data_role' filepath='drivers/usb/typec/class.c' line='1690' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='typec_set_data_role'>
@@ -146536,18 +147343,18 @@
         <parameter type-id='33ca4bbb' name='partner' filepath='drivers/usb/typec/class.c' line='905' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='typec_unregister_port' mangled-name='typec_unregister_port' filepath='drivers/usb/typec/class.c' line='2098' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='typec_unregister_port'>
-        <parameter type-id='b977ca56' name='port' filepath='drivers/usb/typec/class.c' line='2098' column='1'/>
+      <function-decl name='typec_unregister_port' mangled-name='typec_unregister_port' filepath='drivers/usb/typec/class.c' line='2152' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='typec_unregister_port'>
+        <parameter type-id='b977ca56' name='port' filepath='drivers/usb/typec/class.c' line='2152' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='uart_add_one_port' mangled-name='uart_add_one_port' filepath='drivers/tty/serial/serial_core.c' line='2914' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_add_one_port'>
-        <parameter type-id='04a219de' name='drv' filepath='drivers/tty/serial/serial_core.c' line='2914' column='1'/>
-        <parameter type-id='af051c69' name='uport' filepath='drivers/tty/serial/serial_core.c' line='2914' column='1'/>
+      <function-decl name='uart_add_one_port' mangled-name='uart_add_one_port' filepath='drivers/tty/serial/serial_core.c' line='2915' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_add_one_port'>
+        <parameter type-id='04a219de' name='drv' filepath='drivers/tty/serial/serial_core.c' line='2915' column='1'/>
+        <parameter type-id='af051c69' name='uport' filepath='drivers/tty/serial/serial_core.c' line='2915' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='uart_console_device' mangled-name='uart_console_device' filepath='drivers/tty/serial/serial_core.c' line='2673' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_console_device'>
-        <parameter type-id='b9aa0100' name='co' filepath='drivers/tty/serial/serial_core.c' line='2673' column='1'/>
-        <parameter type-id='7292109c' name='index' filepath='drivers/tty/serial/serial_core.c' line='2673' column='1'/>
+      <function-decl name='uart_console_device' mangled-name='uart_console_device' filepath='drivers/tty/serial/serial_core.c' line='2674' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_console_device'>
+        <parameter type-id='b9aa0100' name='co' filepath='drivers/tty/serial/serial_core.c' line='2674' column='1'/>
+        <parameter type-id='7292109c' name='index' filepath='drivers/tty/serial/serial_core.c' line='2674' column='1'/>
         <return type-id='c2b4b27b'/>
       </function-decl>
       <function-decl name='uart_console_write' mangled-name='uart_console_write' filepath='drivers/tty/serial/serial_core.c' line='1984' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_console_write'>
@@ -146570,26 +147377,26 @@
         <parameter type-id='f0981eeb' name='baud' filepath='drivers/tty/serial/serial_core.c' line='476' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='uart_get_rs485_mode' mangled-name='uart_get_rs485_mode' filepath='drivers/tty/serial/serial_core.c' line='3275' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_get_rs485_mode'>
-        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/serial_core.c' line='3275' column='1'/>
+      <function-decl name='uart_get_rs485_mode' mangled-name='uart_get_rs485_mode' filepath='drivers/tty/serial/serial_core.c' line='3276' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_get_rs485_mode'>
+        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/serial_core.c' line='3276' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='uart_handle_cts_change' mangled-name='uart_handle_cts_change' filepath='drivers/tty/serial/serial_core.c' line='3155' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_handle_cts_change'>
-        <parameter type-id='af051c69' name='uport' filepath='drivers/tty/serial/serial_core.c' line='3155' column='1'/>
-        <parameter type-id='f0981eeb' name='status' filepath='drivers/tty/serial/serial_core.c' line='3155' column='1'/>
+      <function-decl name='uart_handle_cts_change' mangled-name='uart_handle_cts_change' filepath='drivers/tty/serial/serial_core.c' line='3156' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_handle_cts_change'>
+        <parameter type-id='af051c69' name='uport' filepath='drivers/tty/serial/serial_core.c' line='3156' column='1'/>
+        <parameter type-id='f0981eeb' name='status' filepath='drivers/tty/serial/serial_core.c' line='3156' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='uart_handle_dcd_change' mangled-name='uart_handle_dcd_change' filepath='drivers/tty/serial/serial_core.c' line='3120' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_handle_dcd_change'>
-        <parameter type-id='af051c69' name='uport' filepath='drivers/tty/serial/serial_core.c' line='3120' column='1'/>
-        <parameter type-id='f0981eeb' name='status' filepath='drivers/tty/serial/serial_core.c' line='3120' column='1'/>
+      <function-decl name='uart_handle_dcd_change' mangled-name='uart_handle_dcd_change' filepath='drivers/tty/serial/serial_core.c' line='3121' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_handle_dcd_change'>
+        <parameter type-id='af051c69' name='uport' filepath='drivers/tty/serial/serial_core.c' line='3121' column='1'/>
+        <parameter type-id='f0981eeb' name='status' filepath='drivers/tty/serial/serial_core.c' line='3121' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='uart_insert_char' mangled-name='uart_insert_char' filepath='drivers/tty/serial/serial_core.c' line='3191' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_insert_char'>
-        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/serial_core.c' line='3191' column='1'/>
-        <parameter type-id='f0981eeb' name='status' filepath='drivers/tty/serial/serial_core.c' line='3191' column='1'/>
-        <parameter type-id='f0981eeb' name='overrun' filepath='drivers/tty/serial/serial_core.c' line='3192' column='1'/>
-        <parameter type-id='f0981eeb' name='ch' filepath='drivers/tty/serial/serial_core.c' line='3192' column='1'/>
-        <parameter type-id='f0981eeb' name='flag' filepath='drivers/tty/serial/serial_core.c' line='3192' column='1'/>
+      <function-decl name='uart_insert_char' mangled-name='uart_insert_char' filepath='drivers/tty/serial/serial_core.c' line='3192' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_insert_char'>
+        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/serial_core.c' line='3192' column='1'/>
+        <parameter type-id='f0981eeb' name='status' filepath='drivers/tty/serial/serial_core.c' line='3192' column='1'/>
+        <parameter type-id='f0981eeb' name='overrun' filepath='drivers/tty/serial/serial_core.c' line='3193' column='1'/>
+        <parameter type-id='f0981eeb' name='ch' filepath='drivers/tty/serial/serial_core.c' line='3193' column='1'/>
+        <parameter type-id='f0981eeb' name='flag' filepath='drivers/tty/serial/serial_core.c' line='3193' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='uart_parse_options' mangled-name='uart_parse_options' filepath='drivers/tty/serial/serial_core.c' line='2095' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_parse_options'>
@@ -146600,18 +147407,18 @@
         <parameter type-id='7292109c' name='flow' filepath='drivers/tty/serial/serial_core.c' line='2096' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='uart_register_driver' mangled-name='uart_register_driver' filepath='drivers/tty/serial/serial_core.c' line='2592' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_register_driver'>
-        <parameter type-id='04a219de' name='drv' filepath='drivers/tty/serial/serial_core.c' line='2592' column='1'/>
+      <function-decl name='uart_register_driver' mangled-name='uart_register_driver' filepath='drivers/tty/serial/serial_core.c' line='2593' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_register_driver'>
+        <parameter type-id='04a219de' name='drv' filepath='drivers/tty/serial/serial_core.c' line='2593' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='uart_remove_one_port' mangled-name='uart_remove_one_port' filepath='drivers/tty/serial/serial_core.c' line='3016' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_remove_one_port'>
-        <parameter type-id='04a219de' name='drv' filepath='drivers/tty/serial/serial_core.c' line='3016' column='1'/>
-        <parameter type-id='af051c69' name='uport' filepath='drivers/tty/serial/serial_core.c' line='3016' column='1'/>
+      <function-decl name='uart_remove_one_port' mangled-name='uart_remove_one_port' filepath='drivers/tty/serial/serial_core.c' line='3017' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_remove_one_port'>
+        <parameter type-id='04a219de' name='drv' filepath='drivers/tty/serial/serial_core.c' line='3017' column='1'/>
+        <parameter type-id='af051c69' name='uport' filepath='drivers/tty/serial/serial_core.c' line='3017' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='uart_resume_port' mangled-name='uart_resume_port' filepath='drivers/tty/serial/serial_core.c' line='2276' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_resume_port'>
-        <parameter type-id='04a219de' name='drv' filepath='drivers/tty/serial/serial_core.c' line='2276' column='1'/>
-        <parameter type-id='af051c69' name='uport' filepath='drivers/tty/serial/serial_core.c' line='2276' column='1'/>
+      <function-decl name='uart_resume_port' mangled-name='uart_resume_port' filepath='drivers/tty/serial/serial_core.c' line='2277' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_resume_port'>
+        <parameter type-id='04a219de' name='drv' filepath='drivers/tty/serial/serial_core.c' line='2277' column='1'/>
+        <parameter type-id='af051c69' name='uport' filepath='drivers/tty/serial/serial_core.c' line='2277' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='uart_set_options' mangled-name='uart_set_options' filepath='drivers/tty/serial/serial_core.c' line='2122' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_set_options'>
@@ -146628,13 +147435,13 @@
         <parameter type-id='af051c69' name='uport' filepath='drivers/tty/serial/serial_core.c' line='2214' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='uart_try_toggle_sysrq' mangled-name='uart_try_toggle_sysrq' filepath='drivers/tty/serial/serial_core.c' line='3234' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_try_toggle_sysrq'>
-        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/serial_core.c' line='3234' column='1'/>
-        <parameter type-id='f0981eeb' name='ch' filepath='drivers/tty/serial/serial_core.c' line='3234' column='1'/>
+      <function-decl name='uart_try_toggle_sysrq' mangled-name='uart_try_toggle_sysrq' filepath='drivers/tty/serial/serial_core.c' line='3235' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_try_toggle_sysrq'>
+        <parameter type-id='af051c69' name='port' filepath='drivers/tty/serial/serial_core.c' line='3235' column='1'/>
+        <parameter type-id='f0981eeb' name='ch' filepath='drivers/tty/serial/serial_core.c' line='3235' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='uart_unregister_driver' mangled-name='uart_unregister_driver' filepath='drivers/tty/serial/serial_core.c' line='2659' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_unregister_driver'>
-        <parameter type-id='04a219de' name='drv' filepath='drivers/tty/serial/serial_core.c' line='2659' column='1'/>
+      <function-decl name='uart_unregister_driver' mangled-name='uart_unregister_driver' filepath='drivers/tty/serial/serial_core.c' line='2660' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_unregister_driver'>
+        <parameter type-id='04a219de' name='drv' filepath='drivers/tty/serial/serial_core.c' line='2660' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='uart_update_timeout' mangled-name='uart_update_timeout' filepath='drivers/tty/serial/serial_core.c' line='326' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uart_update_timeout'>
@@ -146657,21 +147464,21 @@
         <parameter type-id='f9b06939' name='num' filepath='drivers/usb/typec/ucsi/ucsi.c' line='848' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='ucsi_create' mangled-name='ucsi_create' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1320' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ucsi_create'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1320' column='1'/>
-        <parameter type-id='0749da8f' name='ops' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1320' column='1'/>
+      <function-decl name='ucsi_create' mangled-name='ucsi_create' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1321' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ucsi_create'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1321' column='1'/>
+        <parameter type-id='0749da8f' name='ops' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1321' column='1'/>
         <return type-id='2c25e09d'/>
       </function-decl>
-      <function-decl name='ucsi_destroy' mangled-name='ucsi_destroy' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1346' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ucsi_destroy'>
-        <parameter type-id='2c25e09d' name='ucsi' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1346' column='1'/>
+      <function-decl name='ucsi_destroy' mangled-name='ucsi_destroy' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1347' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ucsi_destroy'>
+        <parameter type-id='2c25e09d' name='ucsi' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1347' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='ucsi_get_drvdata' mangled-name='ucsi_get_drvdata' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1298' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ucsi_get_drvdata'>
-        <parameter type-id='2c25e09d' name='ucsi' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1298' column='1'/>
+      <function-decl name='ucsi_get_drvdata' mangled-name='ucsi_get_drvdata' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1299' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ucsi_get_drvdata'>
+        <parameter type-id='2c25e09d' name='ucsi' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1299' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='ucsi_register' mangled-name='ucsi_register' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1358' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ucsi_register'>
-        <parameter type-id='2c25e09d' name='ucsi' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1358' column='1'/>
+      <function-decl name='ucsi_register' mangled-name='ucsi_register' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1359' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ucsi_register'>
+        <parameter type-id='2c25e09d' name='ucsi' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1359' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='ucsi_send_command' mangled-name='ucsi_send_command' filepath='drivers/usb/typec/ucsi/ucsi.c' line='153' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ucsi_send_command'>
@@ -146681,13 +147488,13 @@
         <parameter type-id='b59d7dce' name='size' filepath='drivers/usb/typec/ucsi/ucsi.c' line='154' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ucsi_set_drvdata' mangled-name='ucsi_set_drvdata' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1309' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ucsi_set_drvdata'>
-        <parameter type-id='2c25e09d' name='ucsi' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1309' column='1'/>
-        <parameter type-id='eaa32e2f' name='data' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1309' column='1'/>
+      <function-decl name='ucsi_set_drvdata' mangled-name='ucsi_set_drvdata' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1310' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ucsi_set_drvdata'>
+        <parameter type-id='2c25e09d' name='ucsi' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1310' column='1'/>
+        <parameter type-id='eaa32e2f' name='data' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1310' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='ucsi_unregister' mangled-name='ucsi_unregister' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1384' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ucsi_unregister'>
-        <parameter type-id='2c25e09d' name='ucsi' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1384' column='1'/>
+      <function-decl name='ucsi_unregister' mangled-name='ucsi_unregister' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1385' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ucsi_unregister'>
+        <parameter type-id='2c25e09d' name='ucsi' filepath='drivers/usb/typec/ucsi/ucsi.c' line='1385' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='udp4_hwcsum' mangled-name='udp4_hwcsum' filepath='net/ipv4/udp.c' line='814' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='udp4_hwcsum'>
@@ -146696,28 +147503,29 @@
         <parameter type-id='78a133c2' name='dst' filepath='net/ipv4/udp.c' line='814' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='ufshcd_alloc_host' mangled-name='ufshcd_alloc_host' filepath='drivers/scsi/ufs/ufshcd.c' line='9196' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_alloc_host'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/scsi/ufs/ufshcd.c' line='9196' column='1'/>
-        <parameter type-id='f38ff799' name='hba_handle' filepath='drivers/scsi/ufs/ufshcd.c' line='9196' column='1'/>
+      <var-decl name='udp_table' type-id='9a516b13' mangled-name='udp_table' visibility='default' filepath='net/ipv4/udp.c' line='121' column='1' elf-symbol-id='udp_table'/>
+      <function-decl name='ufshcd_alloc_host' mangled-name='ufshcd_alloc_host' filepath='drivers/scsi/ufs/ufshcd.c' line='9225' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_alloc_host'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/scsi/ufs/ufshcd.c' line='9225' column='1'/>
+        <parameter type-id='f38ff799' name='hba_handle' filepath='drivers/scsi/ufs/ufshcd.c' line='9225' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_auto_hibern8_update' mangled-name='ufshcd_auto_hibern8_update' filepath='drivers/scsi/ufs/ufshcd.c' line='4134' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_auto_hibern8_update'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4134' column='1'/>
-        <parameter type-id='19c2251e' name='ahit' filepath='drivers/scsi/ufs/ufshcd.c' line='4134' column='1'/>
+      <function-decl name='ufshcd_auto_hibern8_update' mangled-name='ufshcd_auto_hibern8_update' filepath='drivers/scsi/ufs/ufshcd.c' line='4163' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_auto_hibern8_update'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4163' column='1'/>
+        <parameter type-id='19c2251e' name='ahit' filepath='drivers/scsi/ufs/ufshcd.c' line='4163' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='ufshcd_bkops_ctrl' mangled-name='ufshcd_bkops_ctrl' filepath='drivers/scsi/ufs/ufshcd.c' line='5467' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_bkops_ctrl'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='5467' column='1'/>
-        <parameter type-id='462d2624' name='status' filepath='drivers/scsi/ufs/ufshcd.c' line='5468' column='1'/>
+      <function-decl name='ufshcd_bkops_ctrl' mangled-name='ufshcd_bkops_ctrl' filepath='drivers/scsi/ufs/ufshcd.c' line='5496' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_bkops_ctrl'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='5496' column='1'/>
+        <parameter type-id='462d2624' name='status' filepath='drivers/scsi/ufs/ufshcd.c' line='5497' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_config_pwr_mode' mangled-name='ufshcd_config_pwr_mode' filepath='drivers/scsi/ufs/ufshcd.c' line='4343' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_config_pwr_mode'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4343' column='1'/>
-        <parameter type-id='35f4156d' name='desired_pwr_mode' filepath='drivers/scsi/ufs/ufshcd.c' line='4344' column='1'/>
+      <function-decl name='ufshcd_config_pwr_mode' mangled-name='ufshcd_config_pwr_mode' filepath='drivers/scsi/ufs/ufshcd.c' line='4372' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_config_pwr_mode'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4372' column='1'/>
+        <parameter type-id='35f4156d' name='desired_pwr_mode' filepath='drivers/scsi/ufs/ufshcd.c' line='4373' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_dealloc_host' mangled-name='ufshcd_dealloc_host' filepath='drivers/scsi/ufs/ufshcd.c' line='9168' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_dealloc_host'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='9168' column='1'/>
+      <function-decl name='ufshcd_dealloc_host' mangled-name='ufshcd_dealloc_host' filepath='drivers/scsi/ufs/ufshcd.c' line='9197' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_dealloc_host'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='9197' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='ufshcd_delay_us' mangled-name='ufshcd_delay_us' filepath='drivers/scsi/ufs/ufshcd.c' line='593' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_delay_us'>
@@ -146725,19 +147533,19 @@
         <parameter type-id='7359adad' name='tolerance' filepath='drivers/scsi/ufs/ufshcd.c' line='593' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='ufshcd_dme_get_attr' mangled-name='ufshcd_dme_get_attr' filepath='drivers/scsi/ufs/ufshcd.c' line='3854' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_dme_get_attr'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3854' column='1'/>
-        <parameter type-id='19c2251e' name='attr_sel' filepath='drivers/scsi/ufs/ufshcd.c' line='3854' column='1'/>
-        <parameter type-id='f9409001' name='mib_val' filepath='drivers/scsi/ufs/ufshcd.c' line='3855' column='1'/>
-        <parameter type-id='f9b06939' name='peer' filepath='drivers/scsi/ufs/ufshcd.c' line='3855' column='1'/>
+      <function-decl name='ufshcd_dme_get_attr' mangled-name='ufshcd_dme_get_attr' filepath='drivers/scsi/ufs/ufshcd.c' line='3883' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_dme_get_attr'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3883' column='1'/>
+        <parameter type-id='19c2251e' name='attr_sel' filepath='drivers/scsi/ufs/ufshcd.c' line='3883' column='1'/>
+        <parameter type-id='f9409001' name='mib_val' filepath='drivers/scsi/ufs/ufshcd.c' line='3884' column='1'/>
+        <parameter type-id='f9b06939' name='peer' filepath='drivers/scsi/ufs/ufshcd.c' line='3884' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_dme_set_attr' mangled-name='ufshcd_dme_set_attr' filepath='drivers/scsi/ufs/ufshcd.c' line='3810' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_dme_set_attr'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3810' column='1'/>
-        <parameter type-id='19c2251e' name='attr_sel' filepath='drivers/scsi/ufs/ufshcd.c' line='3810' column='1'/>
-        <parameter type-id='f9b06939' name='attr_set' filepath='drivers/scsi/ufs/ufshcd.c' line='3811' column='1'/>
-        <parameter type-id='19c2251e' name='mib_val' filepath='drivers/scsi/ufs/ufshcd.c' line='3811' column='1'/>
-        <parameter type-id='f9b06939' name='peer' filepath='drivers/scsi/ufs/ufshcd.c' line='3811' column='1'/>
+      <function-decl name='ufshcd_dme_set_attr' mangled-name='ufshcd_dme_set_attr' filepath='drivers/scsi/ufs/ufshcd.c' line='3839' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_dme_set_attr'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3839' column='1'/>
+        <parameter type-id='19c2251e' name='attr_sel' filepath='drivers/scsi/ufs/ufshcd.c' line='3839' column='1'/>
+        <parameter type-id='f9b06939' name='attr_set' filepath='drivers/scsi/ufs/ufshcd.c' line='3840' column='1'/>
+        <parameter type-id='19c2251e' name='mib_val' filepath='drivers/scsi/ufs/ufshcd.c' line='3840' column='1'/>
+        <parameter type-id='f9b06939' name='peer' filepath='drivers/scsi/ufs/ufshcd.c' line='3840' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='ufshcd_dump_regs' mangled-name='ufshcd_dump_regs' filepath='drivers/scsi/ufs/ufshcd.c' line='103' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_dump_regs'>
@@ -146747,13 +147555,13 @@
         <parameter type-id='80f4b756' name='prefix' filepath='drivers/scsi/ufs/ufshcd.c' line='104' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_fixup_dev_quirks' mangled-name='ufshcd_fixup_dev_quirks' filepath='drivers/scsi/ufs/ufshcd.c' line='7410' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_fixup_dev_quirks'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='7410' column='1'/>
-        <parameter type-id='c5251c27' name='fixups' filepath='drivers/scsi/ufs/ufshcd.c' line='7410' column='1'/>
+      <function-decl name='ufshcd_fixup_dev_quirks' mangled-name='ufshcd_fixup_dev_quirks' filepath='drivers/scsi/ufs/ufshcd.c' line='7439' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_fixup_dev_quirks'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='7439' column='1'/>
+        <parameter type-id='c5251c27' name='fixups' filepath='drivers/scsi/ufs/ufshcd.c' line='7439' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='ufshcd_get_local_unipro_ver' mangled-name='ufshcd_get_local_unipro_ver' filepath='drivers/scsi/ufs/ufshcd.c' line='907' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_get_local_unipro_ver'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='907' column='1'/>
+      <function-decl name='ufshcd_get_local_unipro_ver' mangled-name='ufshcd_get_local_unipro_ver' filepath='drivers/scsi/ufs/ufshcd.c' line='897' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_get_local_unipro_ver'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='897' column='1'/>
         <return type-id='19c2251e'/>
       </function-decl>
       <function-decl name='ufshcd_get_pwr_dev_param' mangled-name='ufshcd_get_pwr_dev_param' filepath='drivers/scsi/ufs/ufshcd-pltfrm.c' line='270' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_get_pwr_dev_param'>
@@ -146762,31 +147570,31 @@
         <parameter type-id='35f4156d' name='agreed_pwr' filepath='drivers/scsi/ufs/ufshcd-pltfrm.c' line='272' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_hba_enable' mangled-name='ufshcd_hba_enable' filepath='drivers/scsi/ufs/ufshcd.c' line='4554' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_hba_enable'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4554' column='1'/>
+      <function-decl name='ufshcd_hba_enable' mangled-name='ufshcd_hba_enable' filepath='drivers/scsi/ufs/ufshcd.c' line='4583' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_hba_enable'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4583' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_hba_stop' mangled-name='ufshcd_hba_stop' filepath='drivers/scsi/ufs/ufshcd.c' line='4468' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_hba_stop'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4468' column='1'/>
+      <function-decl name='ufshcd_hba_stop' mangled-name='ufshcd_hba_stop' filepath='drivers/scsi/ufs/ufshcd.c' line='4497' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_hba_stop'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4497' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='ufshcd_hold' mangled-name='ufshcd_hold' filepath='drivers/scsi/ufs/ufshcd.c' line='1658' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_hold'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='1658' column='1'/>
-        <parameter type-id='b50a4934' name='async' filepath='drivers/scsi/ufs/ufshcd.c' line='1658' column='1'/>
+      <function-decl name='ufshcd_hold' mangled-name='ufshcd_hold' filepath='drivers/scsi/ufs/ufshcd.c' line='1648' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_hold'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='1648' column='1'/>
+        <parameter type-id='b50a4934' name='async' filepath='drivers/scsi/ufs/ufshcd.c' line='1648' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_link_recovery' mangled-name='ufshcd_link_recovery' filepath='drivers/scsi/ufs/ufshcd.c' line='4054' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_link_recovery'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4054' column='1'/>
+      <function-decl name='ufshcd_link_recovery' mangled-name='ufshcd_link_recovery' filepath='drivers/scsi/ufs/ufshcd.c' line='4083' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_link_recovery'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4083' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_make_hba_operational' mangled-name='ufshcd_make_hba_operational' filepath='drivers/scsi/ufs/ufshcd.c' line='4418' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_make_hba_operational'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4418' column='1'/>
+      <function-decl name='ufshcd_make_hba_operational' mangled-name='ufshcd_make_hba_operational' filepath='drivers/scsi/ufs/ufshcd.c' line='4447' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_make_hba_operational'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4447' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_map_desc_id_to_length' mangled-name='ufshcd_map_desc_id_to_length' filepath='drivers/scsi/ufs/ufshcd.c' line='3286' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_map_desc_id_to_length'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3286' column='1'/>
-        <parameter type-id='32c9d5cb' name='desc_id' filepath='drivers/scsi/ufs/ufshcd.c' line='3286' column='1'/>
-        <parameter type-id='7292109c' name='desc_len' filepath='drivers/scsi/ufs/ufshcd.c' line='3287' column='1'/>
+      <function-decl name='ufshcd_map_desc_id_to_length' mangled-name='ufshcd_map_desc_id_to_length' filepath='drivers/scsi/ufs/ufshcd.c' line='3315' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_map_desc_id_to_length'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3315' column='1'/>
+        <parameter type-id='32c9d5cb' name='desc_id' filepath='drivers/scsi/ufs/ufshcd.c' line='3315' column='1'/>
+        <parameter type-id='7292109c' name='desc_len' filepath='drivers/scsi/ufs/ufshcd.c' line='3316' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='ufshcd_pltfrm_init' mangled-name='ufshcd_pltfrm_init' filepath='drivers/scsi/ufs/ufshcd-pltfrm.c' line='365' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_pltfrm_init'>
@@ -146818,91 +147626,91 @@
         <parameter type-id='fa0b179b' name='dev' filepath='drivers/scsi/ufs/ufshcd-pltfrm.c' line='201' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_query_attr' mangled-name='ufshcd_query_attr' filepath='drivers/scsi/ufs/ufshcd.c' line='3093' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_query_attr'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3093' column='1'/>
-        <parameter type-id='5f757f13' name='opcode' filepath='drivers/scsi/ufs/ufshcd.c' line='3093' column='1'/>
-        <parameter type-id='75eb1735' name='idn' filepath='drivers/scsi/ufs/ufshcd.c' line='3094' column='1'/>
-        <parameter type-id='f9b06939' name='index' filepath='drivers/scsi/ufs/ufshcd.c' line='3094' column='1'/>
-        <parameter type-id='f9b06939' name='selector' filepath='drivers/scsi/ufs/ufshcd.c' line='3094' column='1'/>
-        <parameter type-id='f9409001' name='attr_val' filepath='drivers/scsi/ufs/ufshcd.c' line='3094' column='1'/>
+      <function-decl name='ufshcd_query_attr' mangled-name='ufshcd_query_attr' filepath='drivers/scsi/ufs/ufshcd.c' line='3122' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_query_attr'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3122' column='1'/>
+        <parameter type-id='5f757f13' name='opcode' filepath='drivers/scsi/ufs/ufshcd.c' line='3122' column='1'/>
+        <parameter type-id='75eb1735' name='idn' filepath='drivers/scsi/ufs/ufshcd.c' line='3123' column='1'/>
+        <parameter type-id='f9b06939' name='index' filepath='drivers/scsi/ufs/ufshcd.c' line='3123' column='1'/>
+        <parameter type-id='f9b06939' name='selector' filepath='drivers/scsi/ufs/ufshcd.c' line='3123' column='1'/>
+        <parameter type-id='f9409001' name='attr_val' filepath='drivers/scsi/ufs/ufshcd.c' line='3123' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_query_attr_retry' mangled-name='ufshcd_query_attr_retry' filepath='drivers/scsi/ufs/ufshcd.c' line='3159' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_query_attr_retry'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3159' column='1'/>
-        <parameter type-id='5f757f13' name='opcode' filepath='drivers/scsi/ufs/ufshcd.c' line='3160' column='1'/>
-        <parameter type-id='75eb1735' name='idn' filepath='drivers/scsi/ufs/ufshcd.c' line='3160' column='1'/>
-        <parameter type-id='f9b06939' name='index' filepath='drivers/scsi/ufs/ufshcd.c' line='3160' column='1'/>
-        <parameter type-id='f9b06939' name='selector' filepath='drivers/scsi/ufs/ufshcd.c' line='3160' column='1'/>
-        <parameter type-id='f9409001' name='attr_val' filepath='drivers/scsi/ufs/ufshcd.c' line='3161' column='1'/>
+      <function-decl name='ufshcd_query_attr_retry' mangled-name='ufshcd_query_attr_retry' filepath='drivers/scsi/ufs/ufshcd.c' line='3188' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_query_attr_retry'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3188' column='1'/>
+        <parameter type-id='5f757f13' name='opcode' filepath='drivers/scsi/ufs/ufshcd.c' line='3189' column='1'/>
+        <parameter type-id='75eb1735' name='idn' filepath='drivers/scsi/ufs/ufshcd.c' line='3189' column='1'/>
+        <parameter type-id='f9b06939' name='index' filepath='drivers/scsi/ufs/ufshcd.c' line='3189' column='1'/>
+        <parameter type-id='f9b06939' name='selector' filepath='drivers/scsi/ufs/ufshcd.c' line='3189' column='1'/>
+        <parameter type-id='f9409001' name='attr_val' filepath='drivers/scsi/ufs/ufshcd.c' line='3190' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_query_descriptor_retry' mangled-name='ufshcd_query_descriptor_retry' filepath='drivers/scsi/ufs/ufshcd.c' line='3260' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_query_descriptor_retry'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3260' column='1'/>
-        <parameter type-id='5f757f13' name='opcode' filepath='drivers/scsi/ufs/ufshcd.c' line='3261' column='1'/>
-        <parameter type-id='32c9d5cb' name='idn' filepath='drivers/scsi/ufs/ufshcd.c' line='3262' column='1'/>
-        <parameter type-id='f9b06939' name='index' filepath='drivers/scsi/ufs/ufshcd.c' line='3262' column='1'/>
-        <parameter type-id='f9b06939' name='selector' filepath='drivers/scsi/ufs/ufshcd.c' line='3263' column='1'/>
-        <parameter type-id='8bff8096' name='desc_buf' filepath='drivers/scsi/ufs/ufshcd.c' line='3264' column='1'/>
-        <parameter type-id='7292109c' name='buf_len' filepath='drivers/scsi/ufs/ufshcd.c' line='3264' column='1'/>
+      <function-decl name='ufshcd_query_descriptor_retry' mangled-name='ufshcd_query_descriptor_retry' filepath='drivers/scsi/ufs/ufshcd.c' line='3289' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_query_descriptor_retry'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3289' column='1'/>
+        <parameter type-id='5f757f13' name='opcode' filepath='drivers/scsi/ufs/ufshcd.c' line='3290' column='1'/>
+        <parameter type-id='32c9d5cb' name='idn' filepath='drivers/scsi/ufs/ufshcd.c' line='3291' column='1'/>
+        <parameter type-id='f9b06939' name='index' filepath='drivers/scsi/ufs/ufshcd.c' line='3291' column='1'/>
+        <parameter type-id='f9b06939' name='selector' filepath='drivers/scsi/ufs/ufshcd.c' line='3292' column='1'/>
+        <parameter type-id='8bff8096' name='desc_buf' filepath='drivers/scsi/ufs/ufshcd.c' line='3293' column='1'/>
+        <parameter type-id='7292109c' name='buf_len' filepath='drivers/scsi/ufs/ufshcd.c' line='3293' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_query_flag' mangled-name='ufshcd_query_flag' filepath='drivers/scsi/ufs/ufshcd.c' line='3023' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_query_flag'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3023' column='1'/>
-        <parameter type-id='5f757f13' name='opcode' filepath='drivers/scsi/ufs/ufshcd.c' line='3023' column='1'/>
-        <parameter type-id='92ace17c' name='idn' filepath='drivers/scsi/ufs/ufshcd.c' line='3024' column='1'/>
-        <parameter type-id='f9b06939' name='index' filepath='drivers/scsi/ufs/ufshcd.c' line='3024' column='1'/>
-        <parameter type-id='d8e6b335' name='flag_res' filepath='drivers/scsi/ufs/ufshcd.c' line='3024' column='1'/>
+      <function-decl name='ufshcd_query_flag' mangled-name='ufshcd_query_flag' filepath='drivers/scsi/ufs/ufshcd.c' line='3052' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_query_flag'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3052' column='1'/>
+        <parameter type-id='5f757f13' name='opcode' filepath='drivers/scsi/ufs/ufshcd.c' line='3052' column='1'/>
+        <parameter type-id='92ace17c' name='idn' filepath='drivers/scsi/ufs/ufshcd.c' line='3053' column='1'/>
+        <parameter type-id='f9b06939' name='index' filepath='drivers/scsi/ufs/ufshcd.c' line='3053' column='1'/>
+        <parameter type-id='d8e6b335' name='flag_res' filepath='drivers/scsi/ufs/ufshcd.c' line='3053' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_query_flag_retry' mangled-name='ufshcd_query_flag_retry' filepath='drivers/scsi/ufs/ufshcd.c' line='2989' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_query_flag_retry'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='2989' column='1'/>
-        <parameter type-id='5f757f13' name='opcode' filepath='drivers/scsi/ufs/ufshcd.c' line='2990' column='1'/>
-        <parameter type-id='92ace17c' name='idn' filepath='drivers/scsi/ufs/ufshcd.c' line='2990' column='1'/>
-        <parameter type-id='f9b06939' name='index' filepath='drivers/scsi/ufs/ufshcd.c' line='2990' column='1'/>
-        <parameter type-id='d8e6b335' name='flag_res' filepath='drivers/scsi/ufs/ufshcd.c' line='2990' column='1'/>
+      <function-decl name='ufshcd_query_flag_retry' mangled-name='ufshcd_query_flag_retry' filepath='drivers/scsi/ufs/ufshcd.c' line='3018' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_query_flag_retry'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3018' column='1'/>
+        <parameter type-id='5f757f13' name='opcode' filepath='drivers/scsi/ufs/ufshcd.c' line='3019' column='1'/>
+        <parameter type-id='92ace17c' name='idn' filepath='drivers/scsi/ufs/ufshcd.c' line='3019' column='1'/>
+        <parameter type-id='f9b06939' name='index' filepath='drivers/scsi/ufs/ufshcd.c' line='3019' column='1'/>
+        <parameter type-id='d8e6b335' name='flag_res' filepath='drivers/scsi/ufs/ufshcd.c' line='3019' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_read_desc_param' mangled-name='ufshcd_read_desc_param' filepath='drivers/scsi/ufs/ufshcd.c' line='3322' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_read_desc_param'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3322' column='1'/>
-        <parameter type-id='32c9d5cb' name='desc_id' filepath='drivers/scsi/ufs/ufshcd.c' line='3323' column='1'/>
-        <parameter type-id='95e97e5e' name='desc_index' filepath='drivers/scsi/ufs/ufshcd.c' line='3324' column='1'/>
-        <parameter type-id='f9b06939' name='param_offset' filepath='drivers/scsi/ufs/ufshcd.c' line='3325' column='1'/>
-        <parameter type-id='8bff8096' name='param_read_buf' filepath='drivers/scsi/ufs/ufshcd.c' line='3326' column='1'/>
-        <parameter type-id='f9b06939' name='param_size' filepath='drivers/scsi/ufs/ufshcd.c' line='3327' column='1'/>
+      <function-decl name='ufshcd_read_desc_param' mangled-name='ufshcd_read_desc_param' filepath='drivers/scsi/ufs/ufshcd.c' line='3351' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_read_desc_param'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='3351' column='1'/>
+        <parameter type-id='32c9d5cb' name='desc_id' filepath='drivers/scsi/ufs/ufshcd.c' line='3352' column='1'/>
+        <parameter type-id='95e97e5e' name='desc_index' filepath='drivers/scsi/ufs/ufshcd.c' line='3353' column='1'/>
+        <parameter type-id='f9b06939' name='param_offset' filepath='drivers/scsi/ufs/ufshcd.c' line='3354' column='1'/>
+        <parameter type-id='8bff8096' name='param_read_buf' filepath='drivers/scsi/ufs/ufshcd.c' line='3355' column='1'/>
+        <parameter type-id='f9b06939' name='param_size' filepath='drivers/scsi/ufs/ufshcd.c' line='3356' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_release' mangled-name='ufshcd_release' filepath='drivers/scsi/ufs/ufshcd.c' line='1836' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_release'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='1836' column='1'/>
+      <function-decl name='ufshcd_release' mangled-name='ufshcd_release' filepath='drivers/scsi/ufs/ufshcd.c' line='1826' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_release'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='1826' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='ufshcd_remove' mangled-name='ufshcd_remove' filepath='drivers/scsi/ufs/ufshcd.c' line='9148' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_remove'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='9148' column='1'/>
+      <function-decl name='ufshcd_remove' mangled-name='ufshcd_remove' filepath='drivers/scsi/ufs/ufshcd.c' line='9177' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_remove'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='9177' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='ufshcd_shutdown' mangled-name='ufshcd_shutdown' filepath='drivers/scsi/ufs/ufshcd.c' line='9117' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_shutdown'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='9117' column='1'/>
+      <function-decl name='ufshcd_shutdown' mangled-name='ufshcd_shutdown' filepath='drivers/scsi/ufs/ufshcd.c' line='9146' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_shutdown'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='9146' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_system_resume' mangled-name='ufshcd_system_resume' filepath='drivers/scsi/ufs/ufshcd.c' line='9016' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_system_resume'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='9016' column='1'/>
+      <function-decl name='ufshcd_system_resume' mangled-name='ufshcd_system_resume' filepath='drivers/scsi/ufs/ufshcd.c' line='9045' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_system_resume'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='9045' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_system_suspend' mangled-name='ufshcd_system_suspend' filepath='drivers/scsi/ufs/ufshcd.c' line='8962' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_system_suspend'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='8962' column='1'/>
+      <function-decl name='ufshcd_system_suspend' mangled-name='ufshcd_system_suspend' filepath='drivers/scsi/ufs/ufshcd.c' line='8991' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_system_suspend'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='8991' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_uic_hibern8_enter' mangled-name='ufshcd_uic_hibern8_enter' filepath='drivers/scsi/ufs/ufshcd.c' line='4083' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_uic_hibern8_enter'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4083' column='1'/>
+      <function-decl name='ufshcd_uic_hibern8_enter' mangled-name='ufshcd_uic_hibern8_enter' filepath='drivers/scsi/ufs/ufshcd.c' line='4112' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_uic_hibern8_enter'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4112' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_uic_hibern8_exit' mangled-name='ufshcd_uic_hibern8_exit' filepath='drivers/scsi/ufs/ufshcd.c' line='4107' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_uic_hibern8_exit'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4107' column='1'/>
+      <function-decl name='ufshcd_uic_hibern8_exit' mangled-name='ufshcd_uic_hibern8_exit' filepath='drivers/scsi/ufs/ufshcd.c' line='4136' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_uic_hibern8_exit'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4136' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ufshcd_update_evt_hist' mangled-name='ufshcd_update_evt_hist' filepath='drivers/scsi/ufs/ufshcd.c' line='4617' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_update_evt_hist'>
-        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4617' column='1'/>
-        <parameter type-id='19c2251e' name='id' filepath='drivers/scsi/ufs/ufshcd.c' line='4617' column='1'/>
-        <parameter type-id='19c2251e' name='val' filepath='drivers/scsi/ufs/ufshcd.c' line='4617' column='1'/>
+      <function-decl name='ufshcd_update_evt_hist' mangled-name='ufshcd_update_evt_hist' filepath='drivers/scsi/ufs/ufshcd.c' line='4646' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ufshcd_update_evt_hist'>
+        <parameter type-id='442b8d89' name='hba' filepath='drivers/scsi/ufs/ufshcd.c' line='4646' column='1'/>
+        <parameter type-id='19c2251e' name='id' filepath='drivers/scsi/ufs/ufshcd.c' line='4646' column='1'/>
+        <parameter type-id='19c2251e' name='val' filepath='drivers/scsi/ufs/ufshcd.c' line='4646' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='uio_unregister_device' mangled-name='uio_unregister_device' filepath='drivers/uio/uio.c' line='1042' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='uio_unregister_device'>
@@ -146925,11 +147733,11 @@
         <parameter type-id='02f11ed4' name='page' filepath='mm/filemap.c' line='1468' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='unmap_mapping_range' mangled-name='unmap_mapping_range' filepath='mm/memory.c' line='3576' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unmap_mapping_range'>
-        <parameter type-id='f57039f0' name='mapping' filepath='mm/memory.c' line='3576' column='1'/>
-        <parameter type-id='bf352dfe' name='holebegin' filepath='mm/memory.c' line='3577' column='1'/>
-        <parameter type-id='bf352dfe' name='holelen' filepath='mm/memory.c' line='3577' column='1'/>
-        <parameter type-id='95e97e5e' name='even_cows' filepath='mm/memory.c' line='3577' column='1'/>
+      <function-decl name='unmap_mapping_range' mangled-name='unmap_mapping_range' filepath='mm/memory.c' line='3588' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unmap_mapping_range'>
+        <parameter type-id='f57039f0' name='mapping' filepath='mm/memory.c' line='3588' column='1'/>
+        <parameter type-id='bf352dfe' name='holebegin' filepath='mm/memory.c' line='3589' column='1'/>
+        <parameter type-id='bf352dfe' name='holelen' filepath='mm/memory.c' line='3589' column='1'/>
+        <parameter type-id='95e97e5e' name='even_cows' filepath='mm/memory.c' line='3589' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='unpin_user_page' mangled-name='unpin_user_page' filepath='mm/gup.c' line='252' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unpin_user_page'>
@@ -146999,21 +147807,21 @@
         <parameter type-id='11b101bb' name='header' filepath='net/sysctl_net.c' line='125' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='unregister_netdev' mangled-name='unregister_netdev' filepath='net/core/dev.c' line='10787' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_netdev'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10787' column='1'/>
+      <function-decl name='unregister_netdev' mangled-name='unregister_netdev' filepath='net/core/dev.c' line='10792' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_netdev'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10792' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='unregister_netdevice_many' mangled-name='unregister_netdevice_many' filepath='net/core/dev.c' line='10677' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_netdevice_many'>
-        <parameter type-id='e84b031a' name='head' filepath='net/core/dev.c' line='10677' column='1'/>
+      <function-decl name='unregister_netdevice_many' mangled-name='unregister_netdevice_many' filepath='net/core/dev.c' line='10682' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_netdevice_many'>
+        <parameter type-id='e84b031a' name='head' filepath='net/core/dev.c' line='10682' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='unregister_netdevice_notifier' mangled-name='unregister_netdevice_notifier' filepath='net/core/dev.c' line='1876' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_netdevice_notifier'>
         <parameter type-id='d504f73d' name='nb' filepath='net/core/dev.c' line='1876' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='unregister_netdevice_queue' mangled-name='unregister_netdevice_queue' filepath='net/core/dev.c' line='10655' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_netdevice_queue'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10655' column='1'/>
-        <parameter type-id='e84b031a' name='head' filepath='net/core/dev.c' line='10655' column='1'/>
+      <function-decl name='unregister_netdevice_queue' mangled-name='unregister_netdevice_queue' filepath='net/core/dev.c' line='10660' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_netdevice_queue'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/dev.c' line='10660' column='1'/>
+        <parameter type-id='e84b031a' name='head' filepath='net/core/dev.c' line='10660' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='unregister_netevent_notifier' mangled-name='unregister_netevent_notifier' filepath='net/core/netevent.c' line='44' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_netevent_notifier'>
@@ -147024,12 +147832,12 @@
         <parameter type-id='d504f73d' name='nb' filepath='mm/oom_kill.c' line='1081' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='unregister_pernet_device' mangled-name='unregister_pernet_device' filepath='net/core/net_namespace.c' line='1350' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_pernet_device'>
-        <parameter type-id='d6907f4c' name='ops' filepath='net/core/net_namespace.c' line='1350' column='1'/>
+      <function-decl name='unregister_pernet_device' mangled-name='unregister_pernet_device' filepath='net/core/net_namespace.c' line='1337' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_pernet_device'>
+        <parameter type-id='d6907f4c' name='ops' filepath='net/core/net_namespace.c' line='1337' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='unregister_pernet_subsys' mangled-name='unregister_pernet_subsys' filepath='net/core/net_namespace.c' line='1302' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_pernet_subsys'>
-        <parameter type-id='d6907f4c' name='ops' filepath='net/core/net_namespace.c' line='1302' column='1'/>
+      <function-decl name='unregister_pernet_subsys' mangled-name='unregister_pernet_subsys' filepath='net/core/net_namespace.c' line='1289' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_pernet_subsys'>
+        <parameter type-id='d6907f4c' name='ops' filepath='net/core/net_namespace.c' line='1289' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='unregister_pm_notifier' mangled-name='unregister_pm_notifier' filepath='kernel/power/main.c' line='77' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_pm_notifier'>
@@ -147060,12 +147868,12 @@
         <parameter type-id='cbd24a98' name='ops' filepath='drivers/base/syscore.c' line='34' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='unregister_sysctl_table' mangled-name='unregister_sysctl_table' filepath='fs/proc/proc_sysctl.c' line='1656' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_sysctl_table'>
-        <parameter type-id='11b101bb' name='header' filepath='fs/proc/proc_sysctl.c' line='1656' column='1'/>
+      <function-decl name='unregister_sysctl_table' mangled-name='unregister_sysctl_table' filepath='fs/proc/proc_sysctl.c' line='1697' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_sysctl_table'>
+        <parameter type-id='11b101bb' name='header' filepath='fs/proc/proc_sysctl.c' line='1697' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='unregister_tcf_proto_ops' mangled-name='unregister_tcf_proto_ops' filepath='net/sched/cls_api.c' line='180' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_tcf_proto_ops'>
-        <parameter type-id='84c1f5fe' name='ops' filepath='net/sched/cls_api.c' line='180' column='1'/>
+      <function-decl name='unregister_tcf_proto_ops' mangled-name='unregister_tcf_proto_ops' filepath='net/sched/cls_api.c' line='178' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_tcf_proto_ops'>
+        <parameter type-id='84c1f5fe' name='ops' filepath='net/sched/cls_api.c' line='178' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='unregister_virtio_device' mangled-name='unregister_virtio_device' filepath='drivers/virtio/virtio.c' line='392' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='unregister_virtio_device'>
@@ -147084,12 +147892,12 @@
         <parameter type-id='a965a5b5' name='sem' filepath='kernel/locking/semaphore.c' line='178' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='up_read' mangled-name='up_read' filepath='kernel/locking/rwsem.c' line='1627' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='up_read'>
-        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1627' column='1'/>
+      <function-decl name='up_read' mangled-name='up_read' filepath='kernel/locking/rwsem.c' line='1642' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='up_read'>
+        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1642' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='up_write' mangled-name='up_write' filepath='kernel/locking/rwsem.c' line='1637' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='up_write'>
-        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1637' column='1'/>
+      <function-decl name='up_write' mangled-name='up_write' filepath='kernel/locking/rwsem.c' line='1652' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='up_write'>
+        <parameter type-id='9b58df93' name='sem' filepath='kernel/locking/rwsem.c' line='1652' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='update_devfreq' mangled-name='update_devfreq' filepath='drivers/devfreq/devfreq.c' line='394' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='update_devfreq'>
@@ -147111,13 +147919,13 @@
         <parameter type-id='e5411c2c' name='function' filepath='drivers/usb/gadget/composite.c' line='315' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='usb_add_gadget' mangled-name='usb_add_gadget' filepath='drivers/usb/gadget/udc/core.c' line='1293' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_add_gadget'>
-        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='1293' column='1'/>
+      <function-decl name='usb_add_gadget' mangled-name='usb_add_gadget' filepath='drivers/usb/gadget/udc/core.c' line='1298' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_add_gadget'>
+        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='1298' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='usb_add_gadget_udc' mangled-name='usb_add_gadget_udc' filepath='drivers/usb/gadget/udc/core.c' line='1419' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_add_gadget_udc'>
-        <parameter type-id='fa0b179b' name='parent' filepath='drivers/usb/gadget/udc/core.c' line='1419' column='1'/>
-        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='1419' column='1'/>
+      <function-decl name='usb_add_gadget_udc' mangled-name='usb_add_gadget_udc' filepath='drivers/usb/gadget/udc/core.c' line='1424' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_add_gadget_udc'>
+        <parameter type-id='fa0b179b' name='parent' filepath='drivers/usb/gadget/udc/core.c' line='1424' column='1'/>
+        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='1424' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='usb_add_hcd' mangled-name='usb_add_hcd' filepath='drivers/usb/core/hcd.c' line='2659' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_add_hcd'>
@@ -147135,17 +147943,17 @@
         <parameter type-id='ca9354d1' name='x' filepath='drivers/usb/phy/phy.c' line='672' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='usb_alloc_coherent' mangled-name='usb_alloc_coherent' filepath='drivers/usb/core/usb.c' line='924' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_alloc_coherent'>
-        <parameter type-id='25e60cb2' name='dev' filepath='drivers/usb/core/usb.c' line='924' column='1'/>
-        <parameter type-id='b59d7dce' name='size' filepath='drivers/usb/core/usb.c' line='924' column='1'/>
-        <parameter type-id='3eb7c31c' name='mem_flags' filepath='drivers/usb/core/usb.c' line='924' column='1'/>
-        <parameter type-id='e835b5d8' name='dma' filepath='drivers/usb/core/usb.c' line='925' column='1'/>
+      <function-decl name='usb_alloc_coherent' mangled-name='usb_alloc_coherent' filepath='drivers/usb/core/usb.c' line='1000' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_alloc_coherent'>
+        <parameter type-id='25e60cb2' name='dev' filepath='drivers/usb/core/usb.c' line='1000' column='1'/>
+        <parameter type-id='b59d7dce' name='size' filepath='drivers/usb/core/usb.c' line='1000' column='1'/>
+        <parameter type-id='3eb7c31c' name='mem_flags' filepath='drivers/usb/core/usb.c' line='1000' column='1'/>
+        <parameter type-id='e835b5d8' name='dma' filepath='drivers/usb/core/usb.c' line='1001' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='usb_alloc_dev' mangled-name='usb_alloc_dev' filepath='drivers/usb/core/usb.c' line='574' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_alloc_dev'>
-        <parameter type-id='25e60cb2' name='parent' filepath='drivers/usb/core/usb.c' line='574' column='1'/>
-        <parameter type-id='3ab7d422' name='bus' filepath='drivers/usb/core/usb.c' line='575' column='1'/>
-        <parameter type-id='f0981eeb' name='port1' filepath='drivers/usb/core/usb.c' line='575' column='1'/>
+      <function-decl name='usb_alloc_dev' mangled-name='usb_alloc_dev' filepath='drivers/usb/core/usb.c' line='650' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_alloc_dev'>
+        <parameter type-id='25e60cb2' name='parent' filepath='drivers/usb/core/usb.c' line='650' column='1'/>
+        <parameter type-id='3ab7d422' name='bus' filepath='drivers/usb/core/usb.c' line='651' column='1'/>
+        <parameter type-id='f0981eeb' name='port1' filepath='drivers/usb/core/usb.c' line='651' column='1'/>
         <return type-id='25e60cb2'/>
       </function-decl>
       <function-decl name='usb_alloc_urb' mangled-name='usb_alloc_urb' filepath='drivers/usb/core/urb.c' line='70' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_alloc_urb'>
@@ -147235,16 +148043,16 @@
         <parameter type-id='95e97e5e' name='pipe' filepath='drivers/usb/core/message.c' line='1205' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='usb_composite_probe' mangled-name='usb_composite_probe' filepath='drivers/usb/gadget/composite.c' line='2489' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_composite_probe'>
-        <parameter type-id='c64e62ba' name='driver' filepath='drivers/usb/gadget/composite.c' line='2489' column='1'/>
+      <function-decl name='usb_composite_probe' mangled-name='usb_composite_probe' filepath='drivers/usb/gadget/composite.c' line='2493' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_composite_probe'>
+        <parameter type-id='c64e62ba' name='driver' filepath='drivers/usb/gadget/composite.c' line='2493' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='usb_composite_setup_continue' mangled-name='usb_composite_setup_continue' filepath='drivers/usb/gadget/composite.c' line='2533' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_composite_setup_continue'>
-        <parameter type-id='2a895c01' name='cdev' filepath='drivers/usb/gadget/composite.c' line='2533' column='1'/>
+      <function-decl name='usb_composite_setup_continue' mangled-name='usb_composite_setup_continue' filepath='drivers/usb/gadget/composite.c' line='2537' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_composite_setup_continue'>
+        <parameter type-id='2a895c01' name='cdev' filepath='drivers/usb/gadget/composite.c' line='2537' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='usb_composite_unregister' mangled-name='usb_composite_unregister' filepath='drivers/usb/gadget/composite.c' line='2517' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_composite_unregister'>
-        <parameter type-id='c64e62ba' name='driver' filepath='drivers/usb/gadget/composite.c' line='2517' column='1'/>
+      <function-decl name='usb_composite_unregister' mangled-name='usb_composite_unregister' filepath='drivers/usb/gadget/composite.c' line='2521' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_composite_unregister'>
+        <parameter type-id='c64e62ba' name='driver' filepath='drivers/usb/gadget/composite.c' line='2521' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='usb_control_msg' mangled-name='usb_control_msg' filepath='drivers/usb/core/message.c' line='136' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_control_msg'>
@@ -147286,8 +148094,8 @@
         <parameter type-id='d315442e' name='wLength' filepath='drivers/usb/common/debug.c' line='301' column='1'/>
         <return type-id='80f4b756'/>
       </function-decl>
-      <function-decl name='usb_del_gadget_udc' mangled-name='usb_del_gadget_udc' filepath='drivers/usb/gadget/udc/core.c' line='1484' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_del_gadget_udc'>
-        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='1484' column='1'/>
+      <function-decl name='usb_del_gadget_udc' mangled-name='usb_del_gadget_udc' filepath='drivers/usb/gadget/udc/core.c' line='1489' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_del_gadget_udc'>
+        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='1489' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='usb_deregister' mangled-name='usb_deregister' filepath='drivers/usb/core/driver.c' line='1100' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_deregister'>
@@ -147317,12 +148125,21 @@
         <parameter type-id='8bf48c31' name='iface' filepath='drivers/usb/core/driver.c' line='615' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
+      <function-decl name='usb_driver_set_configuration' mangled-name='usb_driver_set_configuration' filepath='drivers/usb/core/message.c' line='2243' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_driver_set_configuration'>
+        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/core/message.c' line='2243' column='1'/>
+        <parameter type-id='95e97e5e' name='config' filepath='drivers/usb/core/message.c' line='2243' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
       <function-decl name='usb_enable_autosuspend' mangled-name='usb_enable_autosuspend' filepath='drivers/usb/core/driver.c' line='1649' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_enable_autosuspend'>
         <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/core/driver.c' line='1649' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='usb_enable_intel_xhci_ports' mangled-name='usb_enable_intel_xhci_ports' filepath='drivers/usb/host/pci-quirks.c' line='1039' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_enable_intel_xhci_ports'>
         <parameter type-id='85196e3f' name='xhci_pdev' filepath='drivers/usb/host/pci-quirks.c' line='1039' column='1'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
+      <function-decl name='usb_enable_lpm' mangled-name='usb_enable_lpm' filepath='drivers/usb/core/hub.c' line='4298' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_enable_lpm'>
+        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/core/hub.c' line='4298' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='usb_ep_alloc_request' mangled-name='usb_ep_alloc_request' filepath='drivers/usb/gadget/udc/core.c' line='175' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_ep_alloc_request'>
@@ -147388,20 +148205,20 @@
         <parameter type-id='5fce7261' name='int_out' filepath='drivers/usb/core/usb.c' line='139' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='usb_find_interface' mangled-name='usb_find_interface' filepath='drivers/usb/core/usb.c' line='352' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_find_interface'>
-        <parameter type-id='46ae908a' name='drv' filepath='drivers/usb/core/usb.c' line='352' column='1'/>
-        <parameter type-id='95e97e5e' name='minor' filepath='drivers/usb/core/usb.c' line='352' column='1'/>
+      <function-decl name='usb_find_interface' mangled-name='usb_find_interface' filepath='drivers/usb/core/usb.c' line='428' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_find_interface'>
+        <parameter type-id='46ae908a' name='drv' filepath='drivers/usb/core/usb.c' line='428' column='1'/>
+        <parameter type-id='95e97e5e' name='minor' filepath='drivers/usb/core/usb.c' line='428' column='1'/>
         <return type-id='8bf48c31'/>
       </function-decl>
       <function-decl name='usb_free_all_descriptors' mangled-name='usb_free_all_descriptors' filepath='drivers/usb/gadget/config.c' line='202' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_free_all_descriptors'>
         <parameter type-id='e5411c2c' name='f' filepath='drivers/usb/gadget/config.c' line='202' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='usb_free_coherent' mangled-name='usb_free_coherent' filepath='drivers/usb/core/usb.c' line='944' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_free_coherent'>
-        <parameter type-id='25e60cb2' name='dev' filepath='drivers/usb/core/usb.c' line='944' column='1'/>
-        <parameter type-id='b59d7dce' name='size' filepath='drivers/usb/core/usb.c' line='944' column='1'/>
-        <parameter type-id='eaa32e2f' name='addr' filepath='drivers/usb/core/usb.c' line='944' column='1'/>
-        <parameter type-id='cf29c9b3' name='dma' filepath='drivers/usb/core/usb.c' line='945' column='1'/>
+      <function-decl name='usb_free_coherent' mangled-name='usb_free_coherent' filepath='drivers/usb/core/usb.c' line='1020' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_free_coherent'>
+        <parameter type-id='25e60cb2' name='dev' filepath='drivers/usb/core/usb.c' line='1020' column='1'/>
+        <parameter type-id='b59d7dce' name='size' filepath='drivers/usb/core/usb.c' line='1020' column='1'/>
+        <parameter type-id='eaa32e2f' name='addr' filepath='drivers/usb/core/usb.c' line='1020' column='1'/>
+        <parameter type-id='cf29c9b3' name='dma' filepath='drivers/usb/core/usb.c' line='1021' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='usb_free_urb' mangled-name='usb_free_urb' filepath='drivers/usb/core/urb.c' line='93' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_free_urb'>
@@ -147424,55 +148241,55 @@
         <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='711' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='usb_gadget_giveback_request' mangled-name='usb_gadget_giveback_request' filepath='drivers/usb/gadget/udc/core.c' line='907' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_giveback_request'>
-        <parameter type-id='63a08bf7' name='ep' filepath='drivers/usb/gadget/udc/core.c' line='907' column='1'/>
-        <parameter type-id='1a494567' name='req' filepath='drivers/usb/gadget/udc/core.c' line='908' column='1'/>
+      <function-decl name='usb_gadget_giveback_request' mangled-name='usb_gadget_giveback_request' filepath='drivers/usb/gadget/udc/core.c' line='908' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_giveback_request'>
+        <parameter type-id='63a08bf7' name='ep' filepath='drivers/usb/gadget/udc/core.c' line='908' column='1'/>
+        <parameter type-id='1a494567' name='req' filepath='drivers/usb/gadget/udc/core.c' line='909' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='usb_gadget_map_request' mangled-name='usb_gadget_map_request' filepath='drivers/usb/gadget/udc/core.c' line='860' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_map_request'>
-        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='860' column='1'/>
-        <parameter type-id='1a494567' name='req' filepath='drivers/usb/gadget/udc/core.c' line='861' column='1'/>
-        <parameter type-id='95e97e5e' name='is_in' filepath='drivers/usb/gadget/udc/core.c' line='861' column='1'/>
+      <function-decl name='usb_gadget_map_request' mangled-name='usb_gadget_map_request' filepath='drivers/usb/gadget/udc/core.c' line='861' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_map_request'>
+        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='861' column='1'/>
+        <parameter type-id='1a494567' name='req' filepath='drivers/usb/gadget/udc/core.c' line='862' column='1'/>
+        <parameter type-id='95e97e5e' name='is_in' filepath='drivers/usb/gadget/udc/core.c' line='862' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='usb_gadget_map_request_by_dev' mangled-name='usb_gadget_map_request_by_dev' filepath='drivers/usb/gadget/udc/core.c' line='819' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_map_request_by_dev'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/usb/gadget/udc/core.c' line='819' column='1'/>
-        <parameter type-id='1a494567' name='req' filepath='drivers/usb/gadget/udc/core.c' line='820' column='1'/>
-        <parameter type-id='95e97e5e' name='is_in' filepath='drivers/usb/gadget/udc/core.c' line='820' column='1'/>
+      <function-decl name='usb_gadget_map_request_by_dev' mangled-name='usb_gadget_map_request_by_dev' filepath='drivers/usb/gadget/udc/core.c' line='820' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_map_request_by_dev'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/usb/gadget/udc/core.c' line='820' column='1'/>
+        <parameter type-id='1a494567' name='req' filepath='drivers/usb/gadget/udc/core.c' line='821' column='1'/>
+        <parameter type-id='95e97e5e' name='is_in' filepath='drivers/usb/gadget/udc/core.c' line='821' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='usb_gadget_probe_driver' mangled-name='usb_gadget_probe_driver' filepath='drivers/usb/gadget/udc/core.c' line='1527' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_probe_driver'>
-        <parameter type-id='9762ede1' name='driver' filepath='drivers/usb/gadget/udc/core.c' line='1527' column='1'/>
+      <function-decl name='usb_gadget_probe_driver' mangled-name='usb_gadget_probe_driver' filepath='drivers/usb/gadget/udc/core.c' line='1543' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_probe_driver'>
+        <parameter type-id='9762ede1' name='driver' filepath='drivers/usb/gadget/udc/core.c' line='1543' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='usb_gadget_set_selfpowered' mangled-name='usb_gadget_set_selfpowered' filepath='drivers/usb/gadget/udc/core.c' line='520' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_set_selfpowered'>
         <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='520' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='usb_gadget_set_state' mangled-name='usb_gadget_set_state' filepath='drivers/usb/gadget/udc/core.c' line='1039' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_set_state'>
-        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='1039' column='1'/>
-        <parameter type-id='901a91cb' name='state' filepath='drivers/usb/gadget/udc/core.c' line='1040' column='1'/>
+      <function-decl name='usb_gadget_set_state' mangled-name='usb_gadget_set_state' filepath='drivers/usb/gadget/udc/core.c' line='1040' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_set_state'>
+        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='1040' column='1'/>
+        <parameter type-id='901a91cb' name='state' filepath='drivers/usb/gadget/udc/core.c' line='1041' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='usb_gadget_udc_reset' mangled-name='usb_gadget_udc_reset' filepath='drivers/usb/gadget/udc/core.c' line='1086' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_udc_reset'>
-        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='1086' column='1'/>
-        <parameter type-id='9762ede1' name='driver' filepath='drivers/usb/gadget/udc/core.c' line='1087' column='1'/>
+      <function-decl name='usb_gadget_udc_reset' mangled-name='usb_gadget_udc_reset' filepath='drivers/usb/gadget/udc/core.c' line='1091' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_udc_reset'>
+        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='1091' column='1'/>
+        <parameter type-id='9762ede1' name='driver' filepath='drivers/usb/gadget/udc/core.c' line='1092' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='usb_gadget_unmap_request' mangled-name='usb_gadget_unmap_request' filepath='drivers/usb/gadget/udc/core.c' line='886' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_unmap_request'>
-        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='886' column='1'/>
-        <parameter type-id='1a494567' name='req' filepath='drivers/usb/gadget/udc/core.c' line='887' column='1'/>
-        <parameter type-id='95e97e5e' name='is_in' filepath='drivers/usb/gadget/udc/core.c' line='887' column='1'/>
+      <function-decl name='usb_gadget_unmap_request' mangled-name='usb_gadget_unmap_request' filepath='drivers/usb/gadget/udc/core.c' line='887' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_unmap_request'>
+        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='887' column='1'/>
+        <parameter type-id='1a494567' name='req' filepath='drivers/usb/gadget/udc/core.c' line='888' column='1'/>
+        <parameter type-id='95e97e5e' name='is_in' filepath='drivers/usb/gadget/udc/core.c' line='888' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='usb_gadget_unmap_request_by_dev' mangled-name='usb_gadget_unmap_request_by_dev' filepath='drivers/usb/gadget/udc/core.c' line='867' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_unmap_request_by_dev'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/usb/gadget/udc/core.c' line='867' column='1'/>
-        <parameter type-id='1a494567' name='req' filepath='drivers/usb/gadget/udc/core.c' line='868' column='1'/>
-        <parameter type-id='95e97e5e' name='is_in' filepath='drivers/usb/gadget/udc/core.c' line='868' column='1'/>
+      <function-decl name='usb_gadget_unmap_request_by_dev' mangled-name='usb_gadget_unmap_request_by_dev' filepath='drivers/usb/gadget/udc/core.c' line='868' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_unmap_request_by_dev'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/usb/gadget/udc/core.c' line='868' column='1'/>
+        <parameter type-id='1a494567' name='req' filepath='drivers/usb/gadget/udc/core.c' line='869' column='1'/>
+        <parameter type-id='95e97e5e' name='is_in' filepath='drivers/usb/gadget/udc/core.c' line='869' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='usb_gadget_unregister_driver' mangled-name='usb_gadget_unregister_driver' filepath='drivers/usb/gadget/udc/core.c' line='1574' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_unregister_driver'>
-        <parameter type-id='9762ede1' name='driver' filepath='drivers/usb/gadget/udc/core.c' line='1574' column='1'/>
+      <function-decl name='usb_gadget_unregister_driver' mangled-name='usb_gadget_unregister_driver' filepath='drivers/usb/gadget/udc/core.c' line='1590' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_unregister_driver'>
+        <parameter type-id='9762ede1' name='driver' filepath='drivers/usb/gadget/udc/core.c' line='1590' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='usb_gadget_vbus_connect' mangled-name='usb_gadget_vbus_connect' filepath='drivers/usb/gadget/udc/core.c' line='579' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_gadget_vbus_connect'>
@@ -147492,8 +148309,8 @@
         <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='493' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='usb_get_dev' mangled-name='usb_get_dev' filepath='drivers/usb/core/usb.c' line='694' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_get_dev'>
-        <parameter type-id='25e60cb2' name='dev' filepath='drivers/usb/core/usb.c' line='694' column='1'/>
+      <function-decl name='usb_get_dev' mangled-name='usb_get_dev' filepath='drivers/usb/core/usb.c' line='770' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_get_dev'>
+        <parameter type-id='25e60cb2' name='dev' filepath='drivers/usb/core/usb.c' line='770' column='1'/>
         <return type-id='25e60cb2'/>
       </function-decl>
       <function-decl name='usb_get_dr_mode' mangled-name='usb_get_dr_mode' filepath='drivers/usb/common/common.c' line='190' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_get_dr_mode'>
@@ -147512,11 +148329,11 @@
         <parameter type-id='80f4b756' name='name' filepath='drivers/usb/gadget/functions.c' line='39' column='1'/>
         <return type-id='6614aa5e'/>
       </function-decl>
-      <function-decl name='usb_get_gadget_udc_name' mangled-name='usb_get_gadget_udc_name' filepath='drivers/usb/gadget/udc/core.c' line='1393' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_get_gadget_udc_name'>
+      <function-decl name='usb_get_gadget_udc_name' mangled-name='usb_get_gadget_udc_name' filepath='drivers/usb/gadget/udc/core.c' line='1398' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_get_gadget_udc_name'>
         <return type-id='26a90f95'/>
       </function-decl>
-      <function-decl name='usb_get_intf' mangled-name='usb_get_intf' filepath='drivers/usb/core/usb.c' line='728' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_get_intf'>
-        <parameter type-id='8bf48c31' name='intf' filepath='drivers/usb/core/usb.c' line='728' column='1'/>
+      <function-decl name='usb_get_intf' mangled-name='usb_get_intf' filepath='drivers/usb/core/usb.c' line='804' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_get_intf'>
+        <parameter type-id='8bf48c31' name='intf' filepath='drivers/usb/core/usb.c' line='804' column='1'/>
         <return type-id='8bf48c31'/>
       </function-decl>
       <function-decl name='usb_get_maximum_speed' mangled-name='usb_get_maximum_speed' filepath='drivers/usb/common/common.c' line='107' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_get_maximum_speed'>
@@ -147618,24 +148435,24 @@
       </function-decl>
       <var-decl name='usb_hcds_loaded' type-id='7359adad' mangled-name='usb_hcds_loaded' visibility='default' filepath='drivers/usb/core/hcd.c' line='81' column='1' elf-symbol-id='usb_hcds_loaded'/>
       <var-decl name='usb_hid_driver' type-id='0e5e2ca6' mangled-name='usb_hid_driver' visibility='default' filepath='drivers/hid/usbhid/hid-core.c' line='1316' column='1' elf-symbol-id='usb_hid_driver'/>
-      <function-decl name='usb_hub_clear_tt_buffer' mangled-name='usb_hub_clear_tt_buffer' filepath='drivers/usb/core/hub.c' line='864' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_hub_clear_tt_buffer'>
-        <parameter type-id='ab85b8f2' name='urb' filepath='drivers/usb/core/hub.c' line='864' column='1'/>
+      <function-decl name='usb_hub_clear_tt_buffer' mangled-name='usb_hub_clear_tt_buffer' filepath='drivers/usb/core/hub.c' line='867' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_hub_clear_tt_buffer'>
+        <parameter type-id='ab85b8f2' name='urb' filepath='drivers/usb/core/hub.c' line='867' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='usb_hub_find_child' mangled-name='usb_hub_find_child' filepath='drivers/usb/core/hub.c' line='6120' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_hub_find_child'>
-        <parameter type-id='25e60cb2' name='hdev' filepath='drivers/usb/core/hub.c' line='6120' column='1'/>
-        <parameter type-id='95e97e5e' name='port1' filepath='drivers/usb/core/hub.c' line='6121' column='1'/>
+      <function-decl name='usb_hub_find_child' mangled-name='usb_hub_find_child' filepath='drivers/usb/core/hub.c' line='6132' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_hub_find_child'>
+        <parameter type-id='25e60cb2' name='hdev' filepath='drivers/usb/core/hub.c' line='6132' column='1'/>
+        <parameter type-id='95e97e5e' name='port1' filepath='drivers/usb/core/hub.c' line='6133' column='1'/>
         <return type-id='25e60cb2'/>
       </function-decl>
-      <function-decl name='usb_ifnum_to_if' mangled-name='usb_ifnum_to_if' filepath='drivers/usb/core/usb.c' line='272' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_ifnum_to_if'>
-        <parameter type-id='ca2b80c9' name='dev' filepath='drivers/usb/core/usb.c' line='272' column='1'/>
-        <parameter type-id='f0981eeb' name='ifnum' filepath='drivers/usb/core/usb.c' line='273' column='1'/>
+      <function-decl name='usb_ifnum_to_if' mangled-name='usb_ifnum_to_if' filepath='drivers/usb/core/usb.c' line='348' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_ifnum_to_if'>
+        <parameter type-id='ca2b80c9' name='dev' filepath='drivers/usb/core/usb.c' line='348' column='1'/>
+        <parameter type-id='f0981eeb' name='ifnum' filepath='drivers/usb/core/usb.c' line='349' column='1'/>
         <return type-id='8bf48c31'/>
       </function-decl>
-      <function-decl name='usb_initialize_gadget' mangled-name='usb_initialize_gadget' filepath='drivers/usb/gadget/udc/core.c' line='1270' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_initialize_gadget'>
-        <parameter type-id='fa0b179b' name='parent' filepath='drivers/usb/gadget/udc/core.c' line='1270' column='1'/>
-        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='1270' column='1'/>
-        <parameter type-id='dd787f72' name='release' filepath='drivers/usb/gadget/udc/core.c' line='1271' column='1'/>
+      <function-decl name='usb_initialize_gadget' mangled-name='usb_initialize_gadget' filepath='drivers/usb/gadget/udc/core.c' line='1275' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_initialize_gadget'>
+        <parameter type-id='fa0b179b' name='parent' filepath='drivers/usb/gadget/udc/core.c' line='1275' column='1'/>
+        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='1275' column='1'/>
+        <parameter type-id='dd787f72' name='release' filepath='drivers/usb/gadget/udc/core.c' line='1276' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='usb_interface_id' mangled-name='usb_interface_id' filepath='drivers/usb/gadget/composite.c' line='479' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_interface_id'>
@@ -147670,12 +148487,12 @@
         <parameter type-id='bc57058f' name='id' filepath='drivers/usb/core/driver.c' line='715' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='usb_os_desc_prepare_interf_dir' mangled-name='usb_os_desc_prepare_interf_dir' filepath='drivers/usb/gadget/configfs.c' line='1228' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_os_desc_prepare_interf_dir'>
-        <parameter type-id='97aff453' name='parent' filepath='drivers/usb/gadget/configfs.c' line='1229' column='1'/>
-        <parameter type-id='95e97e5e' name='n_interf' filepath='drivers/usb/gadget/configfs.c' line='1230' column='1'/>
-        <parameter type-id='b6338998' name='desc' filepath='drivers/usb/gadget/configfs.c' line='1231' column='1'/>
-        <parameter type-id='9b23c9ad' name='names' filepath='drivers/usb/gadget/configfs.c' line='1232' column='1'/>
-        <parameter type-id='2730d015' name='owner' filepath='drivers/usb/gadget/configfs.c' line='1233' column='1'/>
+      <function-decl name='usb_os_desc_prepare_interf_dir' mangled-name='usb_os_desc_prepare_interf_dir' filepath='drivers/usb/gadget/configfs.c' line='1234' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_os_desc_prepare_interf_dir'>
+        <parameter type-id='97aff453' name='parent' filepath='drivers/usb/gadget/configfs.c' line='1235' column='1'/>
+        <parameter type-id='95e97e5e' name='n_interf' filepath='drivers/usb/gadget/configfs.c' line='1236' column='1'/>
+        <parameter type-id='b6338998' name='desc' filepath='drivers/usb/gadget/configfs.c' line='1237' column='1'/>
+        <parameter type-id='9b23c9ad' name='names' filepath='drivers/usb/gadget/configfs.c' line='1238' column='1'/>
+        <parameter type-id='2730d015' name='owner' filepath='drivers/usb/gadget/configfs.c' line='1239' column='1'/>
         <return type-id='97aff453'/>
       </function-decl>
       <function-decl name='usb_otg_state_string' mangled-name='usb_otg_state_string' filepath='drivers/usb/common/common.c' line='43' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_otg_state_string'>
@@ -147711,8 +148528,8 @@
         <parameter type-id='ab85b8f2' name='urb' filepath='drivers/usb/core/urb.c' line='750' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='usb_put_dev' mangled-name='usb_put_dev' filepath='drivers/usb/core/usb.c' line='709' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_put_dev'>
-        <parameter type-id='25e60cb2' name='dev' filepath='drivers/usb/core/usb.c' line='709' column='1'/>
+      <function-decl name='usb_put_dev' mangled-name='usb_put_dev' filepath='drivers/usb/core/usb.c' line='785' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_put_dev'>
+        <parameter type-id='25e60cb2' name='dev' filepath='drivers/usb/core/usb.c' line='785' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='usb_put_function' mangled-name='usb_put_function' filepath='drivers/usb/gadget/functions.c' line='82' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_put_function'>
@@ -147727,12 +148544,12 @@
         <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/core/hcd.c' line='2578' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='usb_put_intf' mangled-name='usb_put_intf' filepath='drivers/usb/core/usb.c' line='744' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_put_intf'>
-        <parameter type-id='8bf48c31' name='intf' filepath='drivers/usb/core/usb.c' line='744' column='1'/>
+      <function-decl name='usb_put_intf' mangled-name='usb_put_intf' filepath='drivers/usb/core/usb.c' line='820' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_put_intf'>
+        <parameter type-id='8bf48c31' name='intf' filepath='drivers/usb/core/usb.c' line='820' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='usb_queue_reset_device' mangled-name='usb_queue_reset_device' filepath='drivers/usb/core/hub.c' line='6100' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_queue_reset_device'>
-        <parameter type-id='8bf48c31' name='iface' filepath='drivers/usb/core/hub.c' line='6100' column='1'/>
+      <function-decl name='usb_queue_reset_device' mangled-name='usb_queue_reset_device' filepath='drivers/usb/core/hub.c' line='6112' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_queue_reset_device'>
+        <parameter type-id='8bf48c31' name='iface' filepath='drivers/usb/core/hub.c' line='6112' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='usb_register_dev' mangled-name='usb_register_dev' filepath='drivers/usb/core/file.c' line='156' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_register_dev'>
@@ -147763,29 +148580,33 @@
         <parameter type-id='ca9354d1' name='x' filepath='drivers/usb/phy/phy.c' line='703' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='usb_role_switch_find_by_fwnode' mangled-name='usb_role_switch_find_by_fwnode' filepath='drivers/usb/roles/class.c' line='184' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_role_switch_find_by_fwnode'>
-        <parameter type-id='7837cd88' name='fwnode' filepath='drivers/usb/roles/class.c' line='184' column='1'/>
+      <function-decl name='usb_reset_device' mangled-name='usb_reset_device' filepath='drivers/usb/core/hub.c' line='5994' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_reset_device'>
+        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/core/hub.c' line='5994' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='usb_role_switch_find_by_fwnode' mangled-name='usb_role_switch_find_by_fwnode' filepath='drivers/usb/roles/class.c' line='187' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_role_switch_find_by_fwnode'>
+        <parameter type-id='7837cd88' name='fwnode' filepath='drivers/usb/roles/class.c' line='187' column='1'/>
         <return type-id='3e3cd44f'/>
       </function-decl>
-      <function-decl name='usb_role_switch_get' mangled-name='usb_role_switch_get' filepath='drivers/usb/roles/class.c' line='123' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_role_switch_get'>
-        <parameter type-id='fa0b179b' name='dev' filepath='drivers/usb/roles/class.c' line='123' column='1'/>
+      <function-decl name='usb_role_switch_get' mangled-name='usb_role_switch_get' filepath='drivers/usb/roles/class.c' line='126' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_role_switch_get'>
+        <parameter type-id='fa0b179b' name='dev' filepath='drivers/usb/roles/class.c' line='126' column='1'/>
         <return type-id='3e3cd44f'/>
       </function-decl>
-      <function-decl name='usb_role_switch_get_drvdata' mangled-name='usb_role_switch_get_drvdata' filepath='drivers/usb/roles/class.c' line='376' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_role_switch_get_drvdata'>
-        <parameter type-id='3e3cd44f' name='sw' filepath='drivers/usb/roles/class.c' line='376' column='1'/>
+      <function-decl name='usb_role_switch_get_drvdata' mangled-name='usb_role_switch_get_drvdata' filepath='drivers/usb/roles/class.c' line='379' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_role_switch_get_drvdata'>
+        <parameter type-id='3e3cd44f' name='sw' filepath='drivers/usb/roles/class.c' line='379' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
       <function-decl name='usb_role_switch_get_role' mangled-name='usb_role_switch_get_role' filepath='drivers/usb/roles/class.c' line='70' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_role_switch_get_role'>
         <parameter type-id='3e3cd44f' name='sw' filepath='drivers/usb/roles/class.c' line='70' column='1'/>
         <return type-id='c675b073'/>
       </function-decl>
-      <function-decl name='usb_role_switch_put' mangled-name='usb_role_switch_put' filepath='drivers/usb/roles/class.c' line='167' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_role_switch_put'>
-        <parameter type-id='3e3cd44f' name='sw' filepath='drivers/usb/roles/class.c' line='167' column='1'/>
+      <function-decl name='usb_role_switch_put' mangled-name='usb_role_switch_put' filepath='drivers/usb/roles/class.c' line='170' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_role_switch_put'>
+        <parameter type-id='3e3cd44f' name='sw' filepath='drivers/usb/roles/class.c' line='170' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='usb_role_switch_register' mangled-name='usb_role_switch_register' filepath='drivers/usb/roles/class.c' line='306' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_role_switch_register'>
-        <parameter type-id='fa0b179b' name='parent' filepath='drivers/usb/roles/class.c' line='306' column='1'/>
-        <parameter type-id='143d32b2' name='desc' filepath='drivers/usb/roles/class.c' line='307' column='1'/>
+      <function-decl name='usb_role_switch_register' mangled-name='usb_role_switch_register' filepath='drivers/usb/roles/class.c' line='309' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_role_switch_register'>
+        <parameter type-id='fa0b179b' name='parent' filepath='drivers/usb/roles/class.c' line='309' column='1'/>
+        <parameter type-id='143d32b2' name='desc' filepath='drivers/usb/roles/class.c' line='310' column='1'/>
         <return type-id='3e3cd44f'/>
       </function-decl>
       <function-decl name='usb_role_switch_set_role' mangled-name='usb_role_switch_set_role' filepath='drivers/usb/roles/class.c' line='42' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_role_switch_set_role'>
@@ -147793,21 +148614,21 @@
         <parameter type-id='c675b073' name='role' filepath='drivers/usb/roles/class.c' line='42' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='usb_role_switch_unregister' mangled-name='usb_role_switch_unregister' filepath='drivers/usb/roles/class.c' line='354' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_role_switch_unregister'>
-        <parameter type-id='3e3cd44f' name='sw' filepath='drivers/usb/roles/class.c' line='354' column='1'/>
+      <function-decl name='usb_role_switch_unregister' mangled-name='usb_role_switch_unregister' filepath='drivers/usb/roles/class.c' line='357' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_role_switch_unregister'>
+        <parameter type-id='3e3cd44f' name='sw' filepath='drivers/usb/roles/class.c' line='357' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='usb_root_hub_lost_power' mangled-name='usb_root_hub_lost_power' filepath='drivers/usb/core/hub.c' line='3848' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_root_hub_lost_power'>
-        <parameter type-id='25e60cb2' name='rhdev' filepath='drivers/usb/core/hub.c' line='3848' column='1'/>
+      <function-decl name='usb_root_hub_lost_power' mangled-name='usb_root_hub_lost_power' filepath='drivers/usb/core/hub.c' line='3850' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_root_hub_lost_power'>
+        <parameter type-id='25e60cb2' name='rhdev' filepath='drivers/usb/core/hub.c' line='3850' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='usb_scuttle_anchored_urbs' mangled-name='usb_scuttle_anchored_urbs' filepath='drivers/usb/core/urb.c' line='1009' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_scuttle_anchored_urbs'>
         <parameter type-id='bd300bf3' name='anchor' filepath='drivers/usb/core/urb.c' line='1009' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='usb_set_device_state' mangled-name='usb_set_device_state' filepath='drivers/usb/core/hub.c' line='2045' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_set_device_state'>
-        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/core/hub.c' line='2045' column='1'/>
-        <parameter type-id='901a91cb' name='new_state' filepath='drivers/usb/core/hub.c' line='2046' column='1'/>
+      <function-decl name='usb_set_device_state' mangled-name='usb_set_device_state' filepath='drivers/usb/core/hub.c' line='2048' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_set_device_state'>
+        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/core/hub.c' line='2048' column='1'/>
+        <parameter type-id='901a91cb' name='new_state' filepath='drivers/usb/core/hub.c' line='2049' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='usb_set_interface' mangled-name='usb_set_interface' filepath='drivers/usb/core/message.c' line='1523' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_set_interface'>
@@ -147842,9 +148663,9 @@
         <parameter type-id='3eb7c31c' name='mem_flags' filepath='drivers/usb/core/urb.c' line='367' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='usb_udc_vbus_handler' mangled-name='usb_udc_vbus_handler' filepath='drivers/usb/gadget/udc/core.c' line='1066' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_udc_vbus_handler'>
-        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='1066' column='1'/>
-        <parameter type-id='b50a4934' name='status' filepath='drivers/usb/gadget/udc/core.c' line='1066' column='1'/>
+      <function-decl name='usb_udc_vbus_handler' mangled-name='usb_udc_vbus_handler' filepath='drivers/usb/gadget/udc/core.c' line='1071' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_udc_vbus_handler'>
+        <parameter type-id='49a58c0c' name='gadget' filepath='drivers/usb/gadget/udc/core.c' line='1071' column='1'/>
+        <parameter type-id='b50a4934' name='status' filepath='drivers/usb/gadget/udc/core.c' line='1071' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='usb_unanchor_urb' mangled-name='usb_unanchor_urb' filepath='drivers/usb/core/urb.c' line='164' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_unanchor_urb'>
@@ -147863,13 +148684,18 @@
         <parameter type-id='d504f73d' name='nb' filepath='drivers/usb/core/notify.c' line='42' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='usb_wakeup_enabled_descendants' mangled-name='usb_wakeup_enabled_descendants' filepath='drivers/usb/core/hub.c' line='3230' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_wakeup_enabled_descendants'>
-        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/core/hub.c' line='3230' column='1'/>
+      <function-decl name='usb_wait_anchor_empty_timeout' mangled-name='usb_wait_anchor_empty_timeout' filepath='drivers/usb/core/urb.c' line='963' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_wait_anchor_empty_timeout'>
+        <parameter type-id='bd300bf3' name='anchor' filepath='drivers/usb/core/urb.c' line='963' column='1'/>
+        <parameter type-id='f0981eeb' name='timeout' filepath='drivers/usb/core/urb.c' line='964' column='1'/>
+        <return type-id='95e97e5e'/>
+      </function-decl>
+      <function-decl name='usb_wakeup_enabled_descendants' mangled-name='usb_wakeup_enabled_descendants' filepath='drivers/usb/core/hub.c' line='3232' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_wakeup_enabled_descendants'>
+        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/core/hub.c' line='3232' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='usb_wakeup_notification' mangled-name='usb_wakeup_notification' filepath='drivers/usb/core/hub.c' line='695' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_wakeup_notification'>
-        <parameter type-id='25e60cb2' name='hdev' filepath='drivers/usb/core/hub.c' line='695' column='1'/>
-        <parameter type-id='f0981eeb' name='portnum' filepath='drivers/usb/core/hub.c' line='696' column='1'/>
+      <function-decl name='usb_wakeup_notification' mangled-name='usb_wakeup_notification' filepath='drivers/usb/core/hub.c' line='698' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_wakeup_notification'>
+        <parameter type-id='25e60cb2' name='hdev' filepath='drivers/usb/core/hub.c' line='698' column='1'/>
+        <parameter type-id='f0981eeb' name='portnum' filepath='drivers/usb/core/hub.c' line='699' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='usbnet_cdc_unbind' mangled-name='usbnet_cdc_unbind' filepath='drivers/net/usb/cdc_ether.c' line='345' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usbnet_cdc_unbind'>
@@ -148914,8 +149740,8 @@
         <parameter type-id='eaa32e2f' name='ctx' filepath='certs/system_keyring.c' line='252' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='vfree' mangled-name='vfree' filepath='mm/vmalloc.c' line='2344' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vfree'>
-        <parameter type-id='eaa32e2f' name='addr' filepath='mm/vmalloc.c' line='2344' column='1'/>
+      <function-decl name='vfree' mangled-name='vfree' filepath='mm/vmalloc.c' line='2348' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vfree'>
+        <parameter type-id='eaa32e2f' name='addr' filepath='mm/vmalloc.c' line='2348' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='vfs_fallocate' mangled-name='vfs_fallocate' filepath='fs/open.c' line='230' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vfs_fallocate'>
@@ -148944,16 +149770,16 @@
         <parameter type-id='f0981eeb' name='query_flags' filepath='fs/stat.c' line='125' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='vfs_ioc_fssetxattr_check' mangled-name='vfs_ioc_fssetxattr_check' filepath='fs/inode.c' line='2331' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vfs_ioc_fssetxattr_check'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2331' column='1'/>
-        <parameter type-id='62561e90' name='old_fa' filepath='fs/inode.c' line='2331' column='1'/>
-        <parameter type-id='a1405a51' name='fa' filepath='fs/inode.c' line='2332' column='1'/>
+      <function-decl name='vfs_ioc_fssetxattr_check' mangled-name='vfs_ioc_fssetxattr_check' filepath='fs/inode.c' line='2340' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vfs_ioc_fssetxattr_check'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2340' column='1'/>
+        <parameter type-id='62561e90' name='old_fa' filepath='fs/inode.c' line='2340' column='1'/>
+        <parameter type-id='a1405a51' name='fa' filepath='fs/inode.c' line='2341' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='vfs_ioc_setflags_prepare' mangled-name='vfs_ioc_setflags_prepare' filepath='fs/inode.c' line='2307' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vfs_ioc_setflags_prepare'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2307' column='1'/>
-        <parameter type-id='f0981eeb' name='oldflags' filepath='fs/inode.c' line='2307' column='1'/>
-        <parameter type-id='f0981eeb' name='flags' filepath='fs/inode.c' line='2308' column='1'/>
+      <function-decl name='vfs_ioc_setflags_prepare' mangled-name='vfs_ioc_setflags_prepare' filepath='fs/inode.c' line='2316' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vfs_ioc_setflags_prepare'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/inode.c' line='2316' column='1'/>
+        <parameter type-id='f0981eeb' name='oldflags' filepath='fs/inode.c' line='2316' column='1'/>
+        <parameter type-id='f0981eeb' name='flags' filepath='fs/inode.c' line='2317' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='vfs_llseek' mangled-name='vfs_llseek' filepath='fs/read_write.c' line='291' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vfs_llseek'>
@@ -149293,40 +150119,40 @@
         <parameter type-id='7359adad' name='vm_flags' filepath='mm/mmap.c' line='110' column='1'/>
         <return type-id='2e2dcbd3'/>
       </function-decl>
-      <function-decl name='vm_insert_page' mangled-name='vm_insert_page' filepath='mm/memory.c' line='1897' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_insert_page'>
-        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='1897' column='1'/>
-        <parameter type-id='7359adad' name='addr' filepath='mm/memory.c' line='1897' column='1'/>
-        <parameter type-id='02f11ed4' name='page' filepath='mm/memory.c' line='1898' column='1'/>
+      <function-decl name='vm_insert_page' mangled-name='vm_insert_page' filepath='mm/memory.c' line='1907' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_insert_page'>
+        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='1907' column='1'/>
+        <parameter type-id='7359adad' name='addr' filepath='mm/memory.c' line='1907' column='1'/>
+        <parameter type-id='02f11ed4' name='page' filepath='mm/memory.c' line='1908' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='vm_iomap_memory' mangled-name='vm_iomap_memory' filepath='mm/memory.c' line='2423' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_iomap_memory'>
-        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='2423' column='1'/>
-        <parameter type-id='2522883d' name='start' filepath='mm/memory.c' line='2423' column='1'/>
-        <parameter type-id='7359adad' name='len' filepath='mm/memory.c' line='2423' column='1'/>
+      <function-decl name='vm_iomap_memory' mangled-name='vm_iomap_memory' filepath='mm/memory.c' line='2433' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_iomap_memory'>
+        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='2433' column='1'/>
+        <parameter type-id='2522883d' name='start' filepath='mm/memory.c' line='2433' column='1'/>
+        <parameter type-id='7359adad' name='len' filepath='mm/memory.c' line='2433' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='vm_map_pages' mangled-name='vm_map_pages' filepath='mm/memory.c' line='1967' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_map_pages'>
-        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='1967' column='1'/>
-        <parameter type-id='9f93c9da' name='pages' filepath='mm/memory.c' line='1967' column='1'/>
-        <parameter type-id='7359adad' name='num' filepath='mm/memory.c' line='1968' column='1'/>
+      <function-decl name='vm_map_pages' mangled-name='vm_map_pages' filepath='mm/memory.c' line='1977' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_map_pages'>
+        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='1977' column='1'/>
+        <parameter type-id='9f93c9da' name='pages' filepath='mm/memory.c' line='1977' column='1'/>
+        <parameter type-id='7359adad' name='num' filepath='mm/memory.c' line='1978' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='vm_map_ram' mangled-name='vm_map_ram' filepath='mm/vmalloc.c' line='1845' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_map_ram'>
-        <parameter type-id='9f93c9da' name='pages' filepath='mm/vmalloc.c' line='1845' column='1'/>
-        <parameter type-id='f0981eeb' name='count' filepath='mm/vmalloc.c' line='1845' column='1'/>
-        <parameter type-id='95e97e5e' name='node' filepath='mm/vmalloc.c' line='1845' column='1'/>
+      <function-decl name='vm_map_ram' mangled-name='vm_map_ram' filepath='mm/vmalloc.c' line='1849' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_map_ram'>
+        <parameter type-id='9f93c9da' name='pages' filepath='mm/vmalloc.c' line='1849' column='1'/>
+        <parameter type-id='f0981eeb' name='count' filepath='mm/vmalloc.c' line='1849' column='1'/>
+        <parameter type-id='95e97e5e' name='node' filepath='mm/vmalloc.c' line='1849' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='vm_memory_committed' mangled-name='vm_memory_committed' filepath='mm/util.c' line='896' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_memory_committed'>
+      <function-decl name='vm_memory_committed' mangled-name='vm_memory_committed' filepath='mm/util.c' line='903' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_memory_committed'>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='vm_mmap' mangled-name='vm_mmap' filepath='mm/util.c' line='554' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_mmap'>
-        <parameter type-id='77e79a4b' name='file' filepath='mm/util.c' line='554' column='1'/>
-        <parameter type-id='7359adad' name='addr' filepath='mm/util.c' line='554' column='1'/>
-        <parameter type-id='7359adad' name='len' filepath='mm/util.c' line='555' column='1'/>
-        <parameter type-id='7359adad' name='prot' filepath='mm/util.c' line='555' column='1'/>
-        <parameter type-id='7359adad' name='flag' filepath='mm/util.c' line='556' column='1'/>
-        <parameter type-id='7359adad' name='offset' filepath='mm/util.c' line='556' column='1'/>
+      <function-decl name='vm_mmap' mangled-name='vm_mmap' filepath='mm/util.c' line='555' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_mmap'>
+        <parameter type-id='77e79a4b' name='file' filepath='mm/util.c' line='555' column='1'/>
+        <parameter type-id='7359adad' name='addr' filepath='mm/util.c' line='555' column='1'/>
+        <parameter type-id='7359adad' name='len' filepath='mm/util.c' line='556' column='1'/>
+        <parameter type-id='7359adad' name='prot' filepath='mm/util.c' line='556' column='1'/>
+        <parameter type-id='7359adad' name='flag' filepath='mm/util.c' line='557' column='1'/>
+        <parameter type-id='7359adad' name='offset' filepath='mm/util.c' line='557' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
       <function-decl name='vm_munmap' mangled-name='vm_munmap' filepath='mm/mmap.c' line='3080' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_munmap'>
@@ -149335,12 +150161,12 @@
         <return type-id='95e97e5e'/>
       </function-decl>
       <var-decl name='vm_node_stat' type-id='9dc2293d' mangled-name='vm_node_stat' visibility='default' filepath='mm/vmstat.c' line='165' column='1' elf-symbol-id='vm_node_stat'/>
-      <function-decl name='vm_unmap_aliases' mangled-name='vm_unmap_aliases' filepath='mm/vmalloc.c' line='1789' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_unmap_aliases'>
+      <function-decl name='vm_unmap_aliases' mangled-name='vm_unmap_aliases' filepath='mm/vmalloc.c' line='1793' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_unmap_aliases'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='vm_unmap_ram' mangled-name='vm_unmap_ram' filepath='mm/vmalloc.c' line='1803' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_unmap_ram'>
-        <parameter type-id='eaa32e2f' name='mem' filepath='mm/vmalloc.c' line='1803' column='1'/>
-        <parameter type-id='f0981eeb' name='count' filepath='mm/vmalloc.c' line='1803' column='1'/>
+      <function-decl name='vm_unmap_ram' mangled-name='vm_unmap_ram' filepath='mm/vmalloc.c' line='1807' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_unmap_ram'>
+        <parameter type-id='eaa32e2f' name='mem' filepath='mm/vmalloc.c' line='1807' column='1'/>
+        <parameter type-id='f0981eeb' name='count' filepath='mm/vmalloc.c' line='1807' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='vm_unmapped_area' mangled-name='vm_unmapped_area' filepath='mm/mmap.c' line='2213' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vm_unmapped_area'>
@@ -149348,8 +150174,8 @@
         <return type-id='7359adad'/>
       </function-decl>
       <var-decl name='vm_zone_stat' type-id='84ab35b9' mangled-name='vm_zone_stat' visibility='default' filepath='mm/vmstat.c' line='163' column='1' elf-symbol-id='vm_zone_stat'/>
-      <function-decl name='vmalloc' mangled-name='vmalloc' filepath='mm/vmalloc.c' line='2640' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vmalloc'>
-        <parameter type-id='7359adad' name='size' filepath='mm/vmalloc.c' line='2640' column='1'/>
+      <function-decl name='vmalloc' mangled-name='vmalloc' filepath='mm/vmalloc.c' line='2644' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vmalloc'>
+        <parameter type-id='7359adad' name='size' filepath='mm/vmalloc.c' line='2644' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
       <function-decl name='vmalloc_nr_pages' mangled-name='vmalloc_nr_pages' filepath='mm/vmalloc.c' line='490' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vmalloc_nr_pages'>
@@ -149363,39 +150189,39 @@
         <parameter type-id='eaa32e2f' name='vmalloc_addr' filepath='mm/vmalloc.c' line='401' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='vmalloc_user' mangled-name='vmalloc_user' filepath='mm/vmalloc.c' line='2676' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vmalloc_user'>
-        <parameter type-id='7359adad' name='size' filepath='mm/vmalloc.c' line='2676' column='1'/>
+      <function-decl name='vmalloc_user' mangled-name='vmalloc_user' filepath='mm/vmalloc.c' line='2680' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vmalloc_user'>
+        <parameter type-id='7359adad' name='size' filepath='mm/vmalloc.c' line='2680' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='vmap' mangled-name='vmap' filepath='mm/vmalloc.c' line='2392' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vmap'>
-        <parameter type-id='9f93c9da' name='pages' filepath='mm/vmalloc.c' line='2392' column='1'/>
-        <parameter type-id='f0981eeb' name='count' filepath='mm/vmalloc.c' line='2392' column='1'/>
-        <parameter type-id='7359adad' name='flags' filepath='mm/vmalloc.c' line='2393' column='1'/>
-        <parameter type-id='2e2dcbd3' name='prot' filepath='mm/vmalloc.c' line='2393' column='1'/>
+      <function-decl name='vmap' mangled-name='vmap' filepath='mm/vmalloc.c' line='2396' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vmap'>
+        <parameter type-id='9f93c9da' name='pages' filepath='mm/vmalloc.c' line='2396' column='1'/>
+        <parameter type-id='f0981eeb' name='count' filepath='mm/vmalloc.c' line='2396' column='1'/>
+        <parameter type-id='7359adad' name='flags' filepath='mm/vmalloc.c' line='2397' column='1'/>
+        <parameter type-id='2e2dcbd3' name='prot' filepath='mm/vmalloc.c' line='2397' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='vmemdup_user' mangled-name='vmemdup_user' filepath='mm/util.c' line='198' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vmemdup_user'>
-        <parameter type-id='eaa32e2f' name='src' filepath='mm/util.c' line='198' column='1'/>
-        <parameter type-id='b59d7dce' name='len' filepath='mm/util.c' line='198' column='1'/>
+      <function-decl name='vmemdup_user' mangled-name='vmemdup_user' filepath='mm/util.c' line='199' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vmemdup_user'>
+        <parameter type-id='eaa32e2f' name='src' filepath='mm/util.c' line='199' column='1'/>
+        <parameter type-id='b59d7dce' name='len' filepath='mm/util.c' line='199' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='vmf_insert_mixed' mangled-name='vmf_insert_mixed' filepath='mm/memory.c' line='2217' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vmf_insert_mixed'>
-        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='2217' column='1'/>
-        <parameter type-id='7359adad' name='addr' filepath='mm/memory.c' line='2217' column='1'/>
-        <parameter type-id='abe59ef3' name='pfn' filepath='mm/memory.c' line='2218' column='1'/>
+      <function-decl name='vmf_insert_mixed' mangled-name='vmf_insert_mixed' filepath='mm/memory.c' line='2227' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vmf_insert_mixed'>
+        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='2227' column='1'/>
+        <parameter type-id='7359adad' name='addr' filepath='mm/memory.c' line='2227' column='1'/>
+        <parameter type-id='abe59ef3' name='pfn' filepath='mm/memory.c' line='2228' column='1'/>
         <return type-id='e9265215'/>
       </function-decl>
-      <function-decl name='vmf_insert_pfn' mangled-name='vmf_insert_pfn' filepath='mm/memory.c' line='2117' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vmf_insert_pfn'>
-        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='2117' column='1'/>
-        <parameter type-id='7359adad' name='addr' filepath='mm/memory.c' line='2117' column='1'/>
-        <parameter type-id='7359adad' name='pfn' filepath='mm/memory.c' line='2118' column='1'/>
+      <function-decl name='vmf_insert_pfn' mangled-name='vmf_insert_pfn' filepath='mm/memory.c' line='2127' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vmf_insert_pfn'>
+        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='2127' column='1'/>
+        <parameter type-id='7359adad' name='addr' filepath='mm/memory.c' line='2127' column='1'/>
+        <parameter type-id='7359adad' name='pfn' filepath='mm/memory.c' line='2128' column='1'/>
         <return type-id='e9265215'/>
       </function-decl>
-      <function-decl name='vmf_insert_pfn_prot' mangled-name='vmf_insert_pfn_prot' filepath='mm/memory.c' line='2069' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vmf_insert_pfn_prot'>
-        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='2069' column='1'/>
-        <parameter type-id='7359adad' name='addr' filepath='mm/memory.c' line='2069' column='1'/>
-        <parameter type-id='7359adad' name='pfn' filepath='mm/memory.c' line='2070' column='1'/>
-        <parameter type-id='2e2dcbd3' name='pgprot' filepath='mm/memory.c' line='2070' column='1'/>
+      <function-decl name='vmf_insert_pfn_prot' mangled-name='vmf_insert_pfn_prot' filepath='mm/memory.c' line='2079' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vmf_insert_pfn_prot'>
+        <parameter type-id='2ae08426' name='vma' filepath='mm/memory.c' line='2079' column='1'/>
+        <parameter type-id='7359adad' name='addr' filepath='mm/memory.c' line='2079' column='1'/>
+        <parameter type-id='7359adad' name='pfn' filepath='mm/memory.c' line='2080' column='1'/>
+        <parameter type-id='2e2dcbd3' name='pgprot' filepath='mm/memory.c' line='2080' column='1'/>
         <return type-id='e9265215'/>
       </function-decl>
       <function-decl name='vprintk' mangled-name='vprintk' filepath='kernel/printk/printk.c' line='2072' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vprintk'>
@@ -149457,7 +150283,7 @@
         <parameter type-id='2aee9912' name='args' filepath='lib/vsprintf.c' line='2783' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='vsnprintf' mangled-name='vsnprintf' filepath='include/linux/kernel.h' line='481' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vsnprintf'>
+      <function-decl name='vsnprintf' mangled-name='vsnprintf' filepath='include/linux/kernel.h' line='343' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vsnprintf'>
         <parameter type-id='26a90f95'/>
         <parameter type-id='7359adad'/>
         <parameter type-id='80f4b756'/>
@@ -149499,17 +150325,17 @@
         <parameter type-id='2aee9912' name='args' filepath='lib/vsprintf.c' line='3296' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='vunmap' mangled-name='vunmap' filepath='mm/vmalloc.c' line='2368' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vunmap'>
-        <parameter type-id='eaa32e2f' name='addr' filepath='mm/vmalloc.c' line='2368' column='1'/>
+      <function-decl name='vunmap' mangled-name='vunmap' filepath='mm/vmalloc.c' line='2372' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vunmap'>
+        <parameter type-id='eaa32e2f' name='addr' filepath='mm/vmalloc.c' line='2372' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='vzalloc' mangled-name='vzalloc' filepath='mm/vmalloc.c' line='2660' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vzalloc'>
-        <parameter type-id='7359adad' name='size' filepath='mm/vmalloc.c' line='2660' column='1'/>
+      <function-decl name='vzalloc' mangled-name='vzalloc' filepath='mm/vmalloc.c' line='2664' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vzalloc'>
+        <parameter type-id='7359adad' name='size' filepath='mm/vmalloc.c' line='2664' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
-      <function-decl name='vzalloc_node' mangled-name='vzalloc_node' filepath='mm/vmalloc.c' line='2716' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vzalloc_node'>
-        <parameter type-id='7359adad' name='size' filepath='mm/vmalloc.c' line='2716' column='1'/>
-        <parameter type-id='95e97e5e' name='node' filepath='mm/vmalloc.c' line='2716' column='1'/>
+      <function-decl name='vzalloc_node' mangled-name='vzalloc_node' filepath='mm/vmalloc.c' line='2720' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vzalloc_node'>
+        <parameter type-id='7359adad' name='size' filepath='mm/vmalloc.c' line='2720' column='1'/>
+        <parameter type-id='95e97e5e' name='node' filepath='mm/vmalloc.c' line='2720' column='1'/>
         <return type-id='eaa32e2f'/>
       </function-decl>
       <function-decl name='wait_for_completion' mangled-name='wait_for_completion' filepath='kernel/sched/completion.c' line='136' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='wait_for_completion'>
@@ -149548,7 +150374,7 @@
         <parameter type-id='7359adad' name='timeout' filepath='kernel/sched/completion.c' line='155' column='1'/>
         <return type-id='7359adad'/>
       </function-decl>
-      <function-decl name='wait_for_device_probe' mangled-name='wait_for_device_probe' filepath='drivers/base/dd.c' line='705' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='wait_for_device_probe'>
+      <function-decl name='wait_for_device_probe' mangled-name='wait_for_device_probe' filepath='drivers/base/dd.c' line='710' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='wait_for_device_probe'>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='wait_for_stable_page' mangled-name='wait_for_stable_page' filepath='mm/page-writeback.c' line='2850' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='wait_for_stable_page'>
@@ -149582,12 +150408,12 @@
         <parameter type-id='95e97e5e' name='bit' filepath='kernel/sched/wait_bit.c' line='147' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='wake_up_if_idle' mangled-name='wake_up_if_idle' filepath='kernel/sched/core.c' line='2821' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='wake_up_if_idle'>
-        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/sched/core.c' line='2821' column='1'/>
+      <function-decl name='wake_up_if_idle' mangled-name='wake_up_if_idle' filepath='kernel/sched/core.c' line='2824' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='wake_up_if_idle'>
+        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/sched/core.c' line='2824' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='wake_up_process' mangled-name='wake_up_process' filepath='kernel/sched/core.c' line='3282' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='wake_up_process'>
-        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='3282' column='1'/>
+      <function-decl name='wake_up_process' mangled-name='wake_up_process' filepath='kernel/sched/core.c' line='3285' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='wake_up_process'>
+        <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='3285' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='wakeup_source_add' mangled-name='wakeup_source_add' filepath='drivers/base/power/wakeup.c' line='175' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='wakeup_source_add'>
@@ -149679,43 +150505,43 @@
         <parameter type-id='eaa32e2f' name='key' filepath='kernel/sched/wait.c' line='466' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='work_busy' mangled-name='work_busy' filepath='kernel/workqueue.c' line='4598' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='work_busy'>
-        <parameter type-id='83c1bde6' name='work' filepath='kernel/workqueue.c' line='4598' column='1'/>
+      <function-decl name='work_busy' mangled-name='work_busy' filepath='kernel/workqueue.c' line='4601' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='work_busy'>
+        <parameter type-id='83c1bde6' name='work' filepath='kernel/workqueue.c' line='4601' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
-      <function-decl name='work_on_cpu' mangled-name='work_on_cpu' filepath='kernel/workqueue.c' line='5155' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='work_on_cpu'>
-        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/workqueue.c' line='5155' column='1'/>
-        <parameter type-id='68883d61' name='fn' filepath='kernel/workqueue.c' line='5155' column='1'/>
-        <parameter type-id='eaa32e2f' name='arg' filepath='kernel/workqueue.c' line='5155' column='1'/>
+      <function-decl name='work_on_cpu' mangled-name='work_on_cpu' filepath='kernel/workqueue.c' line='5158' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='work_on_cpu'>
+        <parameter type-id='95e97e5e' name='cpu' filepath='kernel/workqueue.c' line='5158' column='1'/>
+        <parameter type-id='68883d61' name='fn' filepath='kernel/workqueue.c' line='5158' column='1'/>
+        <parameter type-id='eaa32e2f' name='arg' filepath='kernel/workqueue.c' line='5158' column='1'/>
         <return type-id='bd54fe1a'/>
       </function-decl>
-      <function-decl name='wq_worker_comm' mangled-name='wq_worker_comm' filepath='kernel/workqueue.c' line='4869' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='wq_worker_comm'>
-        <parameter type-id='26a90f95' name='buf' filepath='kernel/workqueue.c' line='4869' column='1'/>
-        <parameter type-id='b59d7dce' name='size' filepath='kernel/workqueue.c' line='4869' column='1'/>
-        <parameter type-id='f23e2572' name='task' filepath='kernel/workqueue.c' line='4869' column='1'/>
+      <function-decl name='wq_worker_comm' mangled-name='wq_worker_comm' filepath='kernel/workqueue.c' line='4872' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='wq_worker_comm'>
+        <parameter type-id='26a90f95' name='buf' filepath='kernel/workqueue.c' line='4872' column='1'/>
+        <parameter type-id='b59d7dce' name='size' filepath='kernel/workqueue.c' line='4872' column='1'/>
+        <parameter type-id='f23e2572' name='task' filepath='kernel/workqueue.c' line='4872' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='write_inode_now' mangled-name='write_inode_now' filepath='fs/fs-writeback.c' line='2562' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='write_inode_now'>
-        <parameter type-id='7e666abe' name='inode' filepath='fs/fs-writeback.c' line='2562' column='1'/>
-        <parameter type-id='95e97e5e' name='sync' filepath='fs/fs-writeback.c' line='2562' column='1'/>
+      <function-decl name='write_inode_now' mangled-name='write_inode_now' filepath='fs/fs-writeback.c' line='2565' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='write_inode_now'>
+        <parameter type-id='7e666abe' name='inode' filepath='fs/fs-writeback.c' line='2565' column='1'/>
+        <parameter type-id='95e97e5e' name='sync' filepath='fs/fs-writeback.c' line='2565' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='write_one_page' mangled-name='write_one_page' filepath='mm/page-writeback.c' line='2380' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='write_one_page'>
         <parameter type-id='02f11ed4' name='page' filepath='mm/page-writeback.c' line='2380' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ww_mutex_lock' mangled-name='ww_mutex_lock' filepath='kernel/locking/mutex.c' line='1451' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ww_mutex_lock'>
-        <parameter type-id='7533ba6f' name='lock' filepath='kernel/locking/mutex.c' line='1451' column='1'/>
-        <parameter type-id='c1d02a64' name='ctx' filepath='kernel/locking/mutex.c' line='1451' column='1'/>
+      <function-decl name='ww_mutex_lock' mangled-name='ww_mutex_lock' filepath='kernel/locking/mutex.c' line='1463' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ww_mutex_lock'>
+        <parameter type-id='7533ba6f' name='lock' filepath='kernel/locking/mutex.c' line='1463' column='1'/>
+        <parameter type-id='c1d02a64' name='ctx' filepath='kernel/locking/mutex.c' line='1463' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ww_mutex_lock_interruptible' mangled-name='ww_mutex_lock_interruptible' filepath='kernel/locking/mutex.c' line='1466' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ww_mutex_lock_interruptible'>
-        <parameter type-id='7533ba6f' name='lock' filepath='kernel/locking/mutex.c' line='1466' column='1'/>
-        <parameter type-id='c1d02a64' name='ctx' filepath='kernel/locking/mutex.c' line='1466' column='1'/>
+      <function-decl name='ww_mutex_lock_interruptible' mangled-name='ww_mutex_lock_interruptible' filepath='kernel/locking/mutex.c' line='1478' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ww_mutex_lock_interruptible'>
+        <parameter type-id='7533ba6f' name='lock' filepath='kernel/locking/mutex.c' line='1478' column='1'/>
+        <parameter type-id='c1d02a64' name='ctx' filepath='kernel/locking/mutex.c' line='1478' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='ww_mutex_unlock' mangled-name='ww_mutex_unlock' filepath='kernel/locking/mutex.c' line='773' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ww_mutex_unlock'>
-        <parameter type-id='7533ba6f' name='lock' filepath='kernel/locking/mutex.c' line='773' column='1'/>
+      <function-decl name='ww_mutex_unlock' mangled-name='ww_mutex_unlock' filepath='kernel/locking/mutex.c' line='785' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ww_mutex_unlock'>
+        <parameter type-id='7533ba6f' name='lock' filepath='kernel/locking/mutex.c' line='785' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='xa_destroy' mangled-name='xa_destroy' filepath='lib/xarray.c' line='2203' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xa_destroy'>
@@ -149763,13 +150589,13 @@
         <parameter type-id='38ed603d' name='xdp' filepath='net/core/xdp.c' line='417' column='1'/>
         <return type-id='cb1c5129'/>
       </function-decl>
-      <function-decl name='xdp_do_flush' mangled-name='xdp_do_flush' filepath='net/core/filter.c' line='3922' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xdp_do_flush'>
+      <function-decl name='xdp_do_flush' mangled-name='xdp_do_flush' filepath='net/core/filter.c' line='3934' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xdp_do_flush'>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='xdp_do_redirect' mangled-name='xdp_do_redirect' filepath='net/core/filter.c' line='3963' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xdp_do_redirect'>
-        <parameter type-id='68a2d05b' name='dev' filepath='net/core/filter.c' line='3963' column='1'/>
-        <parameter type-id='38ed603d' name='xdp' filepath='net/core/filter.c' line='3963' column='1'/>
-        <parameter type-id='bdcee7ae' name='xdp_prog' filepath='net/core/filter.c' line='3964' column='1'/>
+      <function-decl name='xdp_do_redirect' mangled-name='xdp_do_redirect' filepath='net/core/filter.c' line='3975' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xdp_do_redirect'>
+        <parameter type-id='68a2d05b' name='dev' filepath='net/core/filter.c' line='3975' column='1'/>
+        <parameter type-id='38ed603d' name='xdp' filepath='net/core/filter.c' line='3975' column='1'/>
+        <parameter type-id='bdcee7ae' name='xdp_prog' filepath='net/core/filter.c' line='3976' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='xdp_return_frame' mangled-name='xdp_return_frame' filepath='net/core/xdp.c' line='375' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xdp_return_frame'>
@@ -149833,15 +150659,15 @@
         <parameter type-id='19c2251e' name='reqid' filepath='net/xfrm/xfrm_state.c' line='1192' column='1'/>
         <return type-id='328dda6e'/>
       </function-decl>
-      <function-decl name='xhci_add_endpoint' mangled-name='xhci_add_endpoint' filepath='drivers/usb/host/xhci.c' line='1859' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_add_endpoint'>
-        <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/host/xhci.c' line='1859' column='1'/>
-        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/host/xhci.c' line='1859' column='1'/>
-        <parameter type-id='15adb516' name='ep' filepath='drivers/usb/host/xhci.c' line='1860' column='1'/>
+      <function-decl name='xhci_add_endpoint' mangled-name='xhci_add_endpoint' filepath='drivers/usb/host/xhci.c' line='1867' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_add_endpoint'>
+        <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/host/xhci.c' line='1867' column='1'/>
+        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/host/xhci.c' line='1867' column='1'/>
+        <parameter type-id='15adb516' name='ep' filepath='drivers/usb/host/xhci.c' line='1868' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='xhci_address_device' mangled-name='xhci_address_device' filepath='drivers/usb/host/xhci.c' line='4257' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_address_device'>
-        <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/host/xhci.c' line='4257' column='1'/>
-        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/host/xhci.c' line='4257' column='1'/>
+      <function-decl name='xhci_address_device' mangled-name='xhci_address_device' filepath='drivers/usb/host/xhci.c' line='4270' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_address_device'>
+        <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/host/xhci.c' line='4270' column='1'/>
+        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/host/xhci.c' line='4270' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='xhci_alloc_command' mangled-name='xhci_alloc_command' filepath='drivers/usb/host/xhci-mem.c' line='1823' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_alloc_command'>
@@ -149865,19 +150691,19 @@
         <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/host/xhci-hub.c' line='1604' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='xhci_check_bandwidth' mangled-name='xhci_check_bandwidth' filepath='drivers/usb/host/xhci.c' line='2903' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_check_bandwidth'>
-        <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/host/xhci.c' line='2903' column='1'/>
-        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/host/xhci.c' line='2903' column='1'/>
+      <function-decl name='xhci_check_bandwidth' mangled-name='xhci_check_bandwidth' filepath='drivers/usb/host/xhci.c' line='2911' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_check_bandwidth'>
+        <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/host/xhci.c' line='2911' column='1'/>
+        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/host/xhci.c' line='2911' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='xhci_check_trb_in_td_math' mangled-name='xhci_check_trb_in_td_math' filepath='drivers/usb/host/xhci-mem.c' line='2088' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_check_trb_in_td_math'>
         <parameter type-id='0c65b409' name='xhci' filepath='drivers/usb/host/xhci-mem.c' line='2088' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='xhci_drop_endpoint' mangled-name='xhci_drop_endpoint' filepath='drivers/usb/host/xhci.c' line='1776' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_drop_endpoint'>
-        <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/host/xhci.c' line='1776' column='1'/>
-        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/host/xhci.c' line='1776' column='1'/>
-        <parameter type-id='15adb516' name='ep' filepath='drivers/usb/host/xhci.c' line='1777' column='1'/>
+      <function-decl name='xhci_drop_endpoint' mangled-name='xhci_drop_endpoint' filepath='drivers/usb/host/xhci.c' line='1784' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_drop_endpoint'>
+        <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/host/xhci.c' line='1784' column='1'/>
+        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/host/xhci.c' line='1784' column='1'/>
+        <parameter type-id='15adb516' name='ep' filepath='drivers/usb/host/xhci.c' line='1785' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='xhci_free_command' mangled-name='xhci_free_command' filepath='drivers/usb/host/xhci-mem.c' line='1874' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_free_command'>
@@ -149890,13 +150716,13 @@
         <parameter type-id='d7409d08' name='erst' filepath='drivers/usb/host/xhci-mem.c' line='1915' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='xhci_gen_setup' mangled-name='xhci_gen_setup' filepath='drivers/usb/host/xhci.c' line='5190' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_gen_setup'>
-        <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/host/xhci.c' line='5190' column='1'/>
-        <parameter type-id='67f831c0' name='get_quirks' filepath='drivers/usb/host/xhci.c' line='5190' column='1'/>
+      <function-decl name='xhci_gen_setup' mangled-name='xhci_gen_setup' filepath='drivers/usb/host/xhci.c' line='5203' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_gen_setup'>
+        <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/host/xhci.c' line='5203' column='1'/>
+        <parameter type-id='67f831c0' name='get_quirks' filepath='drivers/usb/host/xhci.c' line='5203' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='xhci_get_endpoint_index' mangled-name='xhci_get_endpoint_index' filepath='drivers/usb/host/xhci.c' line='1323' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_get_endpoint_index'>
-        <parameter type-id='a07d0491' name='desc' filepath='drivers/usb/host/xhci.c' line='1323' column='1'/>
+      <function-decl name='xhci_get_endpoint_index' mangled-name='xhci_get_endpoint_index' filepath='drivers/usb/host/xhci.c' line='1331' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_get_endpoint_index'>
+        <parameter type-id='a07d0491' name='desc' filepath='drivers/usb/host/xhci.c' line='1331' column='1'/>
         <return type-id='f0981eeb'/>
       </function-decl>
       <function-decl name='xhci_get_ep_ctx' mangled-name='xhci_get_ep_ctx' filepath='drivers/usb/host/xhci-mem.c' line='594' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_get_ep_ctx'>
@@ -149910,13 +150736,13 @@
         <parameter type-id='971e404f' name='ctx' filepath='drivers/usb/host/xhci-mem.c' line='584' column='1'/>
         <return type-id='e42579ca'/>
       </function-decl>
-      <function-decl name='xhci_handle_event' mangled-name='xhci_handle_event' filepath='drivers/usb/host/xhci-ring.c' line='2969' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_handle_event'>
-        <parameter type-id='0c65b409' name='xhci' filepath='drivers/usb/host/xhci-ring.c' line='2969' column='1'/>
+      <function-decl name='xhci_handle_event' mangled-name='xhci_handle_event' filepath='drivers/usb/host/xhci-ring.c' line='2999' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_handle_event'>
+        <parameter type-id='0c65b409' name='xhci' filepath='drivers/usb/host/xhci-ring.c' line='2999' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='xhci_init_driver' mangled-name='xhci_init_driver' filepath='drivers/usb/host/xhci.c' line='5434' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_init_driver'>
-        <parameter type-id='c07d5ba3' name='drv' filepath='drivers/usb/host/xhci.c' line='5434' column='1'/>
-        <parameter type-id='9a55ba3d' name='over' filepath='drivers/usb/host/xhci.c' line='5435' column='1'/>
+      <function-decl name='xhci_init_driver' mangled-name='xhci_init_driver' filepath='drivers/usb/host/xhci.c' line='5447' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_init_driver'>
+        <parameter type-id='c07d5ba3' name='drv' filepath='drivers/usb/host/xhci.c' line='5447' column='1'/>
+        <parameter type-id='9a55ba3d' name='over' filepath='drivers/usb/host/xhci.c' line='5448' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='xhci_initialize_ring_info' mangled-name='xhci_initialize_ring_info' filepath='drivers/usb/host/xhci-mem.c' line='299' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_initialize_ring_info'>
@@ -149931,22 +150757,22 @@
         <parameter type-id='b50a4934' name='chain_links' filepath='drivers/usb/host/xhci-mem.c' line='102' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='xhci_queue_stop_endpoint' mangled-name='xhci_queue_stop_endpoint' filepath='drivers/usb/host/xhci-ring.c' line='4425' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_queue_stop_endpoint'>
-        <parameter type-id='0c65b409' name='xhci' filepath='drivers/usb/host/xhci-ring.c' line='4425' column='1'/>
-        <parameter type-id='5a32bd4b' name='cmd' filepath='drivers/usb/host/xhci-ring.c' line='4425' column='1'/>
-        <parameter type-id='95e97e5e' name='slot_id' filepath='drivers/usb/host/xhci-ring.c' line='4426' column='1'/>
-        <parameter type-id='f0981eeb' name='ep_index' filepath='drivers/usb/host/xhci-ring.c' line='4426' column='1'/>
-        <parameter type-id='95e97e5e' name='suspend' filepath='drivers/usb/host/xhci-ring.c' line='4426' column='1'/>
+      <function-decl name='xhci_queue_stop_endpoint' mangled-name='xhci_queue_stop_endpoint' filepath='drivers/usb/host/xhci-ring.c' line='4455' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_queue_stop_endpoint'>
+        <parameter type-id='0c65b409' name='xhci' filepath='drivers/usb/host/xhci-ring.c' line='4455' column='1'/>
+        <parameter type-id='5a32bd4b' name='cmd' filepath='drivers/usb/host/xhci-ring.c' line='4455' column='1'/>
+        <parameter type-id='95e97e5e' name='slot_id' filepath='drivers/usb/host/xhci-ring.c' line='4456' column='1'/>
+        <parameter type-id='f0981eeb' name='ep_index' filepath='drivers/usb/host/xhci-ring.c' line='4456' column='1'/>
+        <parameter type-id='95e97e5e' name='suspend' filepath='drivers/usb/host/xhci-ring.c' line='4456' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='xhci_reset_bandwidth' mangled-name='xhci_reset_bandwidth' filepath='drivers/usb/host/xhci.c' line='3002' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_reset_bandwidth'>
-        <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/host/xhci.c' line='3002' column='1'/>
-        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/host/xhci.c' line='3002' column='1'/>
+      <function-decl name='xhci_reset_bandwidth' mangled-name='xhci_reset_bandwidth' filepath='drivers/usb/host/xhci.c' line='3010' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_reset_bandwidth'>
+        <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/host/xhci.c' line='3010' column='1'/>
+        <parameter type-id='25e60cb2' name='udev' filepath='drivers/usb/host/xhci.c' line='3010' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='xhci_resume' mangled-name='xhci_resume' filepath='drivers/usb/host/xhci.c' line='1101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_resume'>
-        <parameter type-id='0c65b409' name='xhci' filepath='drivers/usb/host/xhci.c' line='1101' column='1'/>
-        <parameter type-id='b50a4934' name='hibernated' filepath='drivers/usb/host/xhci.c' line='1101' column='1'/>
+      <function-decl name='xhci_resume' mangled-name='xhci_resume' filepath='drivers/usb/host/xhci.c' line='1109' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_resume'>
+        <parameter type-id='0c65b409' name='xhci' filepath='drivers/usb/host/xhci.c' line='1109' column='1'/>
+        <parameter type-id='b50a4934' name='hibernated' filepath='drivers/usb/host/xhci.c' line='1109' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='xhci_ring_alloc' mangled-name='xhci_ring_alloc' filepath='drivers/usb/host/xhci-mem.c' line='423' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_ring_alloc'>
@@ -149958,8 +150784,8 @@
         <parameter type-id='3eb7c31c' name='flags' filepath='drivers/usb/host/xhci-mem.c' line='425' column='1'/>
         <return type-id='52a50596'/>
       </function-decl>
-      <function-decl name='xhci_ring_cmd_db' mangled-name='xhci_ring_cmd_db' filepath='drivers/usb/host/xhci-ring.c' line='302' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_ring_cmd_db'>
-        <parameter type-id='0c65b409' name='xhci' filepath='drivers/usb/host/xhci-ring.c' line='302' column='1'/>
+      <function-decl name='xhci_ring_cmd_db' mangled-name='xhci_ring_cmd_db' filepath='drivers/usb/host/xhci-ring.c' line='322' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_ring_cmd_db'>
+        <parameter type-id='0c65b409' name='xhci' filepath='drivers/usb/host/xhci-ring.c' line='322' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
       <function-decl name='xhci_ring_free' mangled-name='xhci_ring_free' filepath='drivers/usb/host/xhci-mem.c' line='282' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_ring_free'>
@@ -149967,8 +150793,8 @@
         <parameter type-id='52a50596' name='ring' filepath='drivers/usb/host/xhci-mem.c' line='282' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='xhci_run' mangled-name='xhci_run' filepath='drivers/usb/host/xhci.c' line='635' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_run'>
-        <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/host/xhci.c' line='635' column='1'/>
+      <function-decl name='xhci_run' mangled-name='xhci_run' filepath='drivers/usb/host/xhci.c' line='641' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_run'>
+        <parameter type-id='fc4f83c1' name='hcd' filepath='drivers/usb/host/xhci.c' line='641' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='xhci_segment_free' mangled-name='xhci_segment_free' filepath='drivers/usb/host/xhci-mem.c' line='68' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_segment_free'>
@@ -149976,9 +150802,9 @@
         <parameter type-id='9689f21b' name='seg' filepath='drivers/usb/host/xhci-mem.c' line='68' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='xhci_suspend' mangled-name='xhci_suspend' filepath='drivers/usb/host/xhci.c' line='986' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_suspend'>
-        <parameter type-id='0c65b409' name='xhci' filepath='drivers/usb/host/xhci.c' line='986' column='1'/>
-        <parameter type-id='b50a4934' name='do_wakeup' filepath='drivers/usb/host/xhci.c' line='986' column='1'/>
+      <function-decl name='xhci_suspend' mangled-name='xhci_suspend' filepath='drivers/usb/host/xhci.c' line='994' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_suspend'>
+        <parameter type-id='0c65b409' name='xhci' filepath='drivers/usb/host/xhci.c' line='994' column='1'/>
+        <parameter type-id='b50a4934' name='do_wakeup' filepath='drivers/usb/host/xhci.c' line='994' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
       <function-decl name='xhci_trb_virt_to_dma' mangled-name='xhci_trb_virt_to_dma' filepath='drivers/usb/host/xhci-ring.c' line='69' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_trb_virt_to_dma'>
@@ -149986,13 +150812,13 @@
         <parameter type-id='2e0bb6d4' name='trb' filepath='drivers/usb/host/xhci-ring.c' line='70' column='1'/>
         <return type-id='cf29c9b3'/>
       </function-decl>
-      <function-decl name='xhci_update_erst_dequeue' mangled-name='xhci_update_erst_dequeue' filepath='drivers/usb/host/xhci-ring.c' line='3045' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_update_erst_dequeue'>
-        <parameter type-id='0c65b409' name='xhci' filepath='drivers/usb/host/xhci-ring.c' line='3045' column='1'/>
-        <parameter type-id='2e0bb6d4' name='event_ring_deq' filepath='drivers/usb/host/xhci-ring.c' line='3046' column='1'/>
+      <function-decl name='xhci_update_erst_dequeue' mangled-name='xhci_update_erst_dequeue' filepath='drivers/usb/host/xhci-ring.c' line='3075' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_update_erst_dequeue'>
+        <parameter type-id='0c65b409' name='xhci' filepath='drivers/usb/host/xhci-ring.c' line='3075' column='1'/>
+        <parameter type-id='2e0bb6d4' name='event_ring_deq' filepath='drivers/usb/host/xhci-ring.c' line='3076' column='1'/>
         <return type-id='48b5725f'/>
       </function-decl>
-      <function-decl name='xhci_vendor_get_ops' mangled-name='xhci_vendor_get_ops' filepath='drivers/usb/host/xhci.c' line='4353' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_vendor_get_ops'>
-        <parameter type-id='0c65b409' name='xhci' filepath='drivers/usb/host/xhci.c' line='4353' column='1'/>
+      <function-decl name='xhci_vendor_get_ops' mangled-name='xhci_vendor_get_ops' filepath='drivers/usb/host/xhci.c' line='4366' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='xhci_vendor_get_ops'>
+        <parameter type-id='0c65b409' name='xhci' filepath='drivers/usb/host/xhci.c' line='4366' column='1'/>
         <return type-id='1e9ca7e3'/>
       </function-decl>
       <var-decl name='zero_pfn' type-id='7359adad' mangled-name='zero_pfn' visibility='default' filepath='mm/memory.c' line='161' column='1' elf-symbol-id='zero_pfn'/>
@@ -150023,19 +150849,19 @@
         <parameter type-id='95e97e5e' name='memLevel' filepath='lib/zlib_deflate/deflate.c' line='1127' column='1'/>
         <return type-id='95e97e5e'/>
       </function-decl>
-      <function-decl name='zone_watermark_ok' mangled-name='zone_watermark_ok' filepath='mm/page_alloc.c' line='3819' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zone_watermark_ok'>
-        <parameter type-id='0a0aff97' name='z' filepath='mm/page_alloc.c' line='3819' column='1'/>
-        <parameter type-id='f0981eeb' name='order' filepath='mm/page_alloc.c' line='3819' column='1'/>
-        <parameter type-id='7359adad' name='mark' filepath='mm/page_alloc.c' line='3819' column='1'/>
-        <parameter type-id='95e97e5e' name='highest_zoneidx' filepath='mm/page_alloc.c' line='3820' column='1'/>
-        <parameter type-id='f0981eeb' name='alloc_flags' filepath='mm/page_alloc.c' line='3820' column='1'/>
+      <function-decl name='zone_watermark_ok' mangled-name='zone_watermark_ok' filepath='mm/page_alloc.c' line='3841' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zone_watermark_ok'>
+        <parameter type-id='0a0aff97' name='z' filepath='mm/page_alloc.c' line='3841' column='1'/>
+        <parameter type-id='f0981eeb' name='order' filepath='mm/page_alloc.c' line='3841' column='1'/>
+        <parameter type-id='7359adad' name='mark' filepath='mm/page_alloc.c' line='3841' column='1'/>
+        <parameter type-id='95e97e5e' name='highest_zoneidx' filepath='mm/page_alloc.c' line='3842' column='1'/>
+        <parameter type-id='f0981eeb' name='alloc_flags' filepath='mm/page_alloc.c' line='3842' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
-      <function-decl name='zone_watermark_ok_safe' mangled-name='zone_watermark_ok_safe' filepath='mm/page_alloc.c' line='3871' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zone_watermark_ok_safe'>
-        <parameter type-id='0a0aff97' name='z' filepath='mm/page_alloc.c' line='3871' column='1'/>
-        <parameter type-id='f0981eeb' name='order' filepath='mm/page_alloc.c' line='3871' column='1'/>
-        <parameter type-id='7359adad' name='mark' filepath='mm/page_alloc.c' line='3872' column='1'/>
-        <parameter type-id='95e97e5e' name='highest_zoneidx' filepath='mm/page_alloc.c' line='3872' column='1'/>
+      <function-decl name='zone_watermark_ok_safe' mangled-name='zone_watermark_ok_safe' filepath='mm/page_alloc.c' line='3893' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zone_watermark_ok_safe'>
+        <parameter type-id='0a0aff97' name='z' filepath='mm/page_alloc.c' line='3893' column='1'/>
+        <parameter type-id='f0981eeb' name='order' filepath='mm/page_alloc.c' line='3893' column='1'/>
+        <parameter type-id='7359adad' name='mark' filepath='mm/page_alloc.c' line='3894' column='1'/>
+        <parameter type-id='95e97e5e' name='highest_zoneidx' filepath='mm/page_alloc.c' line='3894' column='1'/>
         <return type-id='b50a4934'/>
       </function-decl>
     </abi-instr>
diff --git a/kernel/android/abi_gki_aarch64_asus b/kernel/android/abi_gki_aarch64_asus
index a44e7e6..0c3159d 100644
--- a/kernel/android/abi_gki_aarch64_asus
+++ b/kernel/android/abi_gki_aarch64_asus
@@ -265,8 +265,8 @@
 up_write
 vfree
 vfs_fsync_range
-vmalloc
 __vmalloc
+vmalloc
 vsnprintf
 vzalloc
 __wait_on_buffer
diff --git a/kernel/android/abi_gki_aarch64_exynos b/kernel/android/abi_gki_aarch64_exynos
index 0b37ab5..ef69e40 100644
--- a/kernel/android/abi_gki_aarch64_exynos
+++ b/kernel/android/abi_gki_aarch64_exynos
@@ -73,9 +73,9 @@
   blocking_notifier_call_chain
   blocking_notifier_chain_register
   blocking_notifier_chain_unregister
-  bpf_trace_run1
   bpf_trace_run10
   bpf_trace_run12
+  bpf_trace_run1
   bpf_trace_run2
   bpf_trace_run3
   bpf_trace_run4
@@ -172,6 +172,7 @@
   __const_udelay
   consume_skb
   contig_page_data
+  copy_highpage
   __cpu_active_mask
   cpu_all_bits
   cpu_bit_bitmap
@@ -1044,9 +1045,9 @@
   is_dma_buf_file
   is_vmalloc_addr
   iterate_fd
-  jiffies
   jiffies_64_to_clock_t
   jiffies64_to_msecs
+  jiffies
   jiffies_to_msecs
   jiffies_to_usecs
   kasan_flag_enabled
@@ -1167,8 +1168,8 @@
   memory_read_from_buffer
   memparse
   memremap
-  memset
   memset64
+  memset
   __memset_io
   memstart_addr
   memunmap
@@ -1262,8 +1263,8 @@
   nla_find
   nla_memcpy
   __nla_parse
-  nla_put
   nla_put_64bit
+  nla_put
   nla_put_nohdr
   nla_reserve
   __nla_validate
@@ -2114,7 +2115,9 @@
   ttm_bo_move_ttm
   ttm_bo_put
   ttm_bo_unlock_delayed_workqueue
+  ttm_bo_unmap_virtual
   ttm_bo_validate
+  ttm_bo_wait
   ttm_dma_page_alloc_debugfs
   ttm_dma_populate
   ttm_dma_tt_fini
@@ -2133,6 +2136,7 @@
   ttm_tt_destroy_common
   ttm_tt_populate
   ttm_tt_set_placement_caching
+  ttm_tt_unpopulate
   ttm_unmap_and_unpopulate_pages
   tty_flip_buffer_push
   tty_insert_flip_string_fixed_flag
diff --git a/kernel/android/abi_gki_aarch64_galaxy b/kernel/android/abi_gki_aarch64_galaxy
index 7ba5f74..db5abff 100644
--- a/kernel/android/abi_gki_aarch64_galaxy
+++ b/kernel/android/abi_gki_aarch64_galaxy
@@ -1,121 +1,1948 @@
 [abi_symbol_list]
-  PDE_DATA
-  __ClearPageMovable
-  __SetPageMovable
-  ___pskb_trim
-  ___ratelimit
+  access_process_vm
+  ack_all_badblocks
+  activate_task
+  add_cpu
+  add_device_randomness
+  add_memory
+  add_memory_subsection
+  add_taint
+  add_timer
+  add_timer_on
+  add_uevent_var
+  add_wait_queue
+  adjust_managed_page_count
+  alarm_cancel
+  alarm_init
+  alarm_start
+  alarm_start_relative
+  alarmtimer_get_rtcdev
+  alarm_try_to_cancel
+  alloc_anon_inode
+  alloc_chrdev_region
   __alloc_disk_node
+  alloc_etherdev_mqs
+  alloc_io_pgtable_ops
+  alloc_netdev_mqs
+  alloc_page_buffers
+  alloc_pages_exact
   __alloc_pages_nodemask
   __alloc_percpu
   __alloc_percpu_gfp
   __alloc_skb
+  alloc_skb_with_frags
+  alloc_workqueue
+  all_vm_events
+  amba_bustype
+  amba_driver_register
+  amba_driver_unregister
+  amba_release_regions
+  amba_request_regions
+  android_debug_per_cpu_symbol
+  android_debug_symbol
+  android_rvh_probe_register
+  anon_inode_getfd
+  anon_inode_getfile
   __arch_clear_user
   __arch_copy_from_user
   __arch_copy_in_user
   __arch_copy_to_user
+  arch_timer_read_counter
+  argv_free
+  argv_split
+  arm64_const_caps_ready
+  arm64_use_ng_mappings
   __arm_smccc_hvc
   __arm_smccc_smc
+  async_schedule_node
+  async_schedule_node_domain
+  async_synchronize_full_domain
+  _atomic_dec_and_lock
+  atomic_notifier_call_chain
+  atomic_notifier_chain_register
+  atomic_notifier_chain_unregister
+  autoremove_wake_function
+  available_idle_cpu
+  backlight_device_get_by_type
+  backlight_device_register
+  backlight_device_set_brightness
+  backlight_device_unregister
+  badblocks_clear
+  badblocks_exit
+  badblocks_init
+  badblocks_set
+  badblocks_show
+  badblocks_store
+  balloon_aops
+  balloon_page_alloc
+  balloon_page_dequeue
+  balloon_page_enqueue
+  bcmp
+  bdev_check_media_change
+  bdevname
+  bdev_read_only
+  bdget_disk
+  bd_link_disk_holder
+  bdput
+  bd_set_nr_sectors
+  bd_unlink_disk_holder
+  bgpio_init
+  bin2hex
+  bio_add_page
+  bio_alloc_bioset
+  bio_associate_blkg
+  bio_chain
+  bio_clone_blkg_association
+  bio_endio
+  bio_init
+  bio_put
+  bioset_exit
+  bioset_init
+  bitmap_allocate_region
   __bitmap_andnot
   __bitmap_clear
   __bitmap_complement
+  bitmap_find_next_zero_area_off
+  bitmap_from_arr32
   __bitmap_or
+  bitmap_parse
+  bitmap_parselist
+  bitmap_parselist_user
+  bitmap_print_to_pagebuf
+  bitmap_release_region
   __bitmap_set
+  bitmap_to_arr32
   __bitmap_weight
   __bitmap_xor
-  __blk_mq_debugfs_rq_show
-  __blk_mq_end_request
-  __blk_rq_map_sg
+  bitmap_zalloc
+  blk_alloc_queue
+  blkcg_activate_policy
+  blkcg_deactivate_policy
+  blkcg_policy_register
+  blkcg_policy_unregister
+  blkcg_root
+  blk_cleanup_queue
+  blkdev_fsync
+  blkdev_get_by_dev
+  blkdev_get_by_path
   __blkdev_issue_discard
+  blkdev_issue_flush
   __blkdev_issue_zeroout
+  blkdev_put
+  blk_execute_rq
+  blk_execute_rq_nowait
+  blk_finish_plug
+  blk_freeze_queue_start
+  blk_get_queue
+  blk_get_request
+  blkg_lookup_slowpath
+  blk_mq_alloc_request
+  blk_mq_alloc_request_hctx
+  blk_mq_alloc_tag_set
+  blk_mq_complete_request
+  blk_mq_complete_request_remote
+  __blk_mq_debugfs_rq_show
+  blk_mq_debugfs_rq_show
+  blk_mq_delay_kick_requeue_list
+  __blk_mq_end_request
+  blk_mq_end_request
+  blk_mq_free_request
+  blk_mq_free_tag_set
+  blk_mq_freeze_queue
+  blk_mq_freeze_queue_wait
+  blk_mq_freeze_queue_wait_timeout
+  blk_mq_init_queue
+  blk_mq_map_queues
+  blk_mq_pci_map_queues
+  blk_mq_quiesce_queue
+  blk_mq_requeue_request
+  blk_mq_rq_cpu
+  blk_mq_run_hw_queues
+  blk_mq_sched_request_inserted
+  blk_mq_sched_try_insert_merge
+  blk_mq_sched_try_merge
+  blk_mq_start_request
+  blk_mq_start_stopped_hw_queues
+  blk_mq_stop_hw_queue
+  blk_mq_tagset_busy_iter
+  blk_mq_tagset_wait_completed_request
+  blk_mq_tag_to_rq
+  blk_mq_unfreeze_queue
+  blk_mq_unique_tag
+  blk_mq_unquiesce_queue
+  blk_mq_update_nr_hw_queues
+  blk_mq_virtio_map_queues
+  blk_poll
+  blk_put_queue
+  blk_put_request
+  blk_queue_alignment_offset
+  blk_queue_bounce_limit
+  blk_queue_can_use_dma_map_merging
+  blk_queue_chunk_sectors
+  blk_queue_dma_alignment
+  blk_queue_flag_clear
+  blk_queue_flag_set
+  blk_queue_flag_test_and_set
+  blk_queue_io_min
+  blk_queue_io_opt
+  blk_queue_logical_block_size
+  blk_queue_max_discard_sectors
+  blk_queue_max_discard_segments
+  blk_queue_max_hw_sectors
+  blk_queue_max_segments
+  blk_queue_max_segment_size
+  blk_queue_max_write_zeroes_sectors
+  blk_queue_physical_block_size
+  blk_queue_rq_timeout
+  blk_queue_split
+  blk_queue_virt_boundary
+  blk_queue_write_cache
+  blk_register_region
+  blk_rq_map_kern
+  __blk_rq_map_sg
+  blk_rq_map_user
+  blk_rq_map_user_iov
+  blk_rq_unmap_user
+  blk_set_queue_dying
+  blk_set_stacking_limits
+  blk_start_plug
+  blk_status_to_errno
+  blk_sync_queue
+  blk_unregister_region
+  blk_update_request
+  blk_verify_command
+  blocking_notifier_call_chain
+  blocking_notifier_chain_register
+  blocking_notifier_chain_unregister
+  bmap
+  bpf_dispatcher_xdp_func
+  bpf_prog_add
+  bpf_prog_put
+  bpf_prog_sub
+  bpf_stats_enabled_key
+  bpf_trace_run10
+  bpf_trace_run11
+  bpf_trace_run12
+  bpf_trace_run1
+  bpf_trace_run2
+  bpf_trace_run3
+  bpf_trace_run4
+  bpf_trace_run5
+  bpf_trace_run6
+  bpf_trace_run7
+  bpf_trace_run8
+  bpf_trace_run9
+  bpf_warn_invalid_xdp_action
+  bsearch
+  bt_err
+  bt_info
+  build_skb
+  bus_find_device
+  bus_for_each_dev
+  bus_for_each_drv
+  bus_register
+  bus_register_notifier
+  bus_set_iommu
+  bus_unregister
+  bus_unregister_notifier
+  cache_line_size
+  call_netdevice_notifiers
+  call_rcu
+  call_rcu_tasks
+  call_rcu_tasks_trace
+  call_srcu
+  cancel_delayed_work
+  cancel_delayed_work_sync
+  cancel_work_sync
+  capable
+  cdc_ncm_bind_common
+  cdc_ncm_change_mtu
+  cdc_ncm_fill_tx_frame
+  cdc_ncm_rx_verify_ndp16
+  cdc_ncm_rx_verify_nth16
+  cdc_ncm_select_altsetting
+  cdc_ncm_unbind
+  cdc_parse_cdc_header
+  cdev_add
+  cdev_alloc
+  cdev_del
+  cdev_device_add
+  cdev_device_del
+  cdev_init
+  cec_allocate_adapter
+  cec_delete_adapter
+  cec_received_msg_ts
+  cec_register_adapter
+  cec_s_log_addrs
+  cec_s_phys_addr
+  cec_s_phys_addr_from_edid
+  cec_transmit_attempt_done_ts
+  cec_transmit_done_ts
+  cec_unregister_adapter
   __cfi_slowpath
+  cgroup_path_ns
+  cgroup_taskset_first
+  cgroup_taskset_next
   __check_object_size
+  check_preempt_curr
+  check_zeroed_user
   __class_create
+  class_create_file_ns
+  class_destroy
+  class_find_device
+  class_for_each_device
+  class_interface_unregister
   __class_register
+  class_remove_file_ns
+  class_unregister
+  cleancache_register_ops
+  cleanup_srcu_struct
+  clear_page
+  __ClearPageMovable
+  clk_bulk_disable
+  clk_bulk_enable
+  clk_bulk_get_all
+  clk_bulk_prepare
+  clk_bulk_put_all
+  clk_bulk_unprepare
   __clk_determine_rate
+  clk_disable
+  clk_enable
+  clk_fixed_factor_ops
+  clk_fixed_rate_ops
+  clk_get
   __clk_get_hw
   __clk_get_name
+  clk_get_parent
+  clk_get_rate
+  clk_hw_get_flags
+  clk_hw_get_name
+  clk_hw_get_num_parents
+  clk_hw_get_parent
+  clk_hw_get_parent_by_index
+  clk_hw_get_rate
+  clk_hw_is_enabled
+  clk_hw_is_prepared
+  clk_hw_register
   __clk_hw_register_divider
+  clk_hw_register_fixed_factor
   __clk_hw_register_gate
   __clk_hw_register_mux
+  clk_hw_round_rate
+  clk_hw_set_rate_range
+  clk_hw_unregister
+  clk_hw_unregister_divider
+  clk_hw_unregister_fixed_factor
+  clk_hw_unregister_gate
+  clk_hw_unregister_mux
   __clk_is_enabled
   __clk_mux_determine_rate_closest
+  clk_notifier_register
+  clk_notifier_unregister
+  clk_prepare
+  clk_put
+  clk_register
+  clk_register_clkdev
+  clk_register_fixed_factor
+  clk_register_fixed_rate
+  clk_register_gate
+  clk_round_rate
+  clk_set_parent
+  clk_set_rate
+  clk_sync_state
+  clk_unprepare
+  clk_unregister
+  clockevents_config_and_register
+  clocks_calc_mult_shift
   __clocksource_register_scale
   __close_fd
+  cma_alloc
+  cma_for_each_area
+  cma_get_name
+  cma_release
+  compat_alloc_user_space
+  compat_only_sysfs_link_entry_to_kobj
+  compat_ptr_ioctl
+  complete
+  complete_all
+  complete_and_exit
+  completion_done
+  component_add
+  component_bind_all
+  component_del
+  component_master_add_with_match
+  component_master_del
+  component_match_add_release
+  component_unbind_all
+  cond_synchronize_rcu
+  config_ep_by_speed
+  configfs_register_subsystem
+  configfs_unregister_subsystem
+  config_group_init
+  config_group_init_type_name
+  config_item_get
+  config_item_put
+  console_drivers
+  console_printk
+  console_stop
+  console_suspend_enabled
+  console_trylock
+  console_unlock
   __const_udelay
+  consume_skb
+  contig_page_data
+  _copy_from_iter
+  _copy_from_iter_full
+  copy_from_kernel_nofault
+  copy_page
+  _copy_to_iter
   __cpu_active_mask
-  __cpu_online_mask
-  __cpu_possible_mask
-  __cpu_present_mask
+  cpu_all_bits
+  cpu_bit_bitmap
+  cpufreq_add_update_util_hook
+  cpufreq_cpu_get
+  cpufreq_cpu_get_raw
+  cpufreq_cpu_put
+  cpufreq_disable_fast_switch
+  cpufreq_driver_fast_switch
+  cpufreq_driver_resolve_freq
   __cpufreq_driver_target
+  cpufreq_enable_boost_support
+  cpufreq_enable_fast_switch
+  cpufreq_freq_attr_scaling_available_freqs
+  cpufreq_freq_attr_scaling_boost_freqs
+  cpufreq_freq_transition_begin
+  cpufreq_freq_transition_end
+  cpufreq_frequency_table_verify
+  cpufreq_generic_attr
+  cpufreq_generic_frequency_table_verify
+  cpufreq_generic_get
+  cpufreq_generic_suspend
+  cpufreq_get_driver_data
+  cpufreq_get_policy
+  cpufreq_policy_transition_delay_us
+  cpufreq_quick_get
+  cpufreq_quick_get_max
+  cpufreq_register_driver
+  cpufreq_register_governor
+  cpufreq_register_notifier
+  cpufreq_remove_update_util_hook
+  cpufreq_table_index_unsorted
+  cpufreq_this_cpu_can_update
+  cpufreq_unregister_driver
+  cpufreq_unregister_notifier
+  cpufreq_update_policy
+  cpu_hotplug_disable
+  cpu_hotplug_enable
   __cpuhp_remove_state
   __cpuhp_setup_state
   __cpuhp_setup_state_cpuslocked
   __cpuhp_state_add_instance
   __cpuhp_state_remove_instance
+  cpuhp_tasks_frozen
+  cpu_hwcap_keys
+  cpu_hwcaps
+  cpuidle_governor_latency_req
+  cpuidle_register_governor
+  cpu_irqtime
+  cpu_is_hotpluggable
+  cpu_latency_qos_add_request
+  cpu_latency_qos_remove_request
+  cpu_latency_qos_request_active
+  cpu_latency_qos_update_request
+  cpumask_any_but
+  cpumask_next
+  cpumask_next_and
+  cpumask_next_wrap
+  cpu_number
+  __cpu_online_mask
+  cpu_pm_register_notifier
+  cpu_pm_unregister_notifier
+  __cpu_possible_mask
+  __cpu_present_mask
+  cpupri_find_fitness
+  cpu_scale
+  cpus_read_lock
+  cpus_read_unlock
+  cpu_subsys
+  cpu_topology
+  crc16
+  crc32_le
+  crc8
+  crc8_populate_msb
+  create_function_device
+  crypto_aead_encrypt
+  crypto_aead_setauthsize
+  crypto_aead_setkey
+  crypto_alloc_aead
+  crypto_alloc_base
+  crypto_alloc_shash
+  crypto_alloc_skcipher
+  crypto_cipher_encrypt_one
+  crypto_cipher_setkey
+  crypto_comp_compress
+  crypto_comp_decompress
+  crypto_destroy_tfm
+  crypto_has_alg
+  crypto_register_alg
+  crypto_register_rngs
+  crypto_register_scomp
+  crypto_shash_digest
+  crypto_shash_final
+  crypto_shash_setkey
+  crypto_shash_update
+  crypto_skcipher_decrypt
+  crypto_skcipher_encrypt
+  crypto_skcipher_setkey
+  crypto_unregister_alg
+  crypto_unregister_rngs
+  crypto_unregister_scomp
+  css_next_child
+  css_next_descendant_pre
+  csum_ipv6_magic
+  csum_partial
+  csum_tcpudp_nofold
+  _ctype
+  current_time
+  current_work
+  d_add
+  d_alloc_name
+  dapm_pinctrl_event
+  dapm_regulator_event
+  datagram_poll
+  d_delete
+  deactivate_task
+  debugfs_attr_read
+  debugfs_attr_write
+  debugfs_create_atomic_t
+  debugfs_create_blob
+  debugfs_create_bool
+  debugfs_create_dir
+  debugfs_create_file
+  debugfs_create_file_unsafe
+  debugfs_create_regset32
+  debugfs_create_size_t
+  debugfs_create_symlink
+  debugfs_create_u16
+  debugfs_create_u32
+  debugfs_create_u64
+  debugfs_create_u8
+  debugfs_create_ulong
+  debugfs_create_x32
+  debugfs_create_x64
+  debugfs_create_x8
+  debugfs_file_get
+  debugfs_file_put
+  debugfs_lookup
+  debugfs_print_regs32
+  debugfs_remove
+  dec_zone_page_state
+  default_llseek
+  deferred_free
+  delayed_work_timer_fn
+  del_gendisk
+  del_timer
+  del_timer_sync
+  desc_to_gpio
+  destroy_workqueue
+  _dev_alert
+  dev_alloc_name
+  dev_close
+  dev_coredumpm
+  dev_coredumpv
+  _dev_crit
+  dev_driver_string
+  _dev_emerg
+  _dev_err
+  dev_err_probe
+  devfreq_add_device
+  devfreq_add_governor
+  devfreq_cooling_unregister
+  devfreq_get_devfreq_by_phandle
+  devfreq_monitor_resume
+  devfreq_monitor_start
+  devfreq_monitor_stop
+  devfreq_monitor_suspend
+  devfreq_recommended_opp
+  devfreq_register_opp_notifier
+  devfreq_remove_device
+  devfreq_remove_governor
+  devfreq_resume_device
+  devfreq_suspend_device
+  devfreq_unregister_opp_notifier
+  devfreq_update_interval
+  dev_fwnode
   __dev_get_by_index
+  dev_get_by_index
+  dev_get_by_name
+  dev_get_regmap
+  dev_get_stats
+  device_add
+  device_add_disk
+  device_add_groups
+  device_attach
+  device_bind_driver
+  device_create
+  device_create_bin_file
+  device_create_file
+  device_create_with_groups
+  device_del
+  device_destroy
+  device_find_child
+  device_for_each_child
+  device_get_child_node_count
+  device_get_dma_attr
+  device_get_mac_address
+  device_get_match_data
+  device_get_named_child_node
+  device_get_next_child_node
+  device_initialize
+  device_init_wakeup
+  device_link_add
+  device_link_del
+  device_match_fwnode
+  device_match_name
+  device_match_of_node
+  device_property_present
+  device_property_read_string
+  device_property_read_string_array
+  device_property_read_u16_array
+  device_property_read_u32_array
+  device_property_read_u8_array
+  device_register
+  device_release_driver
+  device_remove_bin_file
+  device_remove_file
+  device_remove_file_self
+  device_remove_groups
+  device_set_wakeup_capable
+  device_set_wakeup_enable
+  device_show_bool
+  device_show_int
+  device_store_bool
+  device_store_int
+  device_unregister
+  device_wakeup_disable
+  device_wakeup_enable
+  _dev_info
   __dev_kfree_skb_any
+  devm_add_action
   __devm_alloc_percpu
+  devm_backlight_device_register
+  devm_backlight_device_unregister
+  devm_blk_ksm_init
+  devm_clk_bulk_get
+  devm_clk_bulk_get_all
+  devm_clk_bulk_get_optional
+  devm_clk_get
+  devm_clk_get_optional
+  devm_clk_hw_register
+  devm_clk_hw_register_clkdev
+  devm_clk_put
+  devm_clk_register
+  dev_mc_sync_multiple
+  dev_mc_unsync
+  devm_devfreq_add_device
+  devm_devfreq_register_notifier
+  devm_devfreq_unregister_notifier
+  devm_device_add_group
+  devm_device_add_groups
+  devm_device_remove_group
   __devm_drm_dev_alloc
+  devm_drm_panel_bridge_add_typed
+  devm_extcon_dev_allocate
+  devm_extcon_dev_register
+  devm_extcon_dev_unregister
+  devm_extcon_register_notifier
+  devm_free_irq
+  devm_free_percpu
+  devm_gen_pool_create
+  devm_get_clk_from_child
+  devm_gpiochip_add_data_with_key
+  devm_gpiod_get
+  devm_gpiod_get_array
+  devm_gpiod_get_index
+  devm_gpiod_get_optional
+  devm_gpiod_put_array
+  devm_gpio_free
+  devm_gpio_request
+  devm_gpio_request_one
+  devm_hwrng_register
+  devm_hwspin_lock_register
+  devm_i2c_new_dummy_device
+  devm_iio_channel_get
+  devm_iio_device_alloc
   __devm_iio_device_register
+  devm_input_allocate_device
+  devm_ioremap
+  devm_ioremap_resource
+  devm_ioremap_wc
+  devm_iounmap
   __devm_irq_alloc_descs
+  devm_kasprintf
+  devm_kfree
+  devm_kmalloc
+  devm_kmemdup
+  devm_kstrdup
+  devm_kstrdup_const
+  devm_kvasprintf
+  devm_led_classdev_register_ext
+  devm_mbox_controller_register
+  devm_memremap
+  devm_mfd_add_devices
+  devm_nvmem_cell_get
+  devm_nvmem_device_get
+  devm_nvmem_register
+  devm_of_clk_add_hw_provider
+  devm_of_icc_get
+  devm_of_iomap
   __devm_of_phy_provider_register
+  devm_of_platform_populate
+  devm_of_pwm_get
+  devm_pci_alloc_host_bridge
+  devm_phy_create
+  devm_phy_get
+  devm_phy_put
+  devm_pinctrl_get
+  devm_pinctrl_put
+  devm_pinctrl_register
+  devm_pinctrl_register_and_init
+  devm_platform_get_and_ioremap_resource
+  devm_platform_ioremap_resource
+  devm_platform_ioremap_resource_byname
+  devm_power_supply_register
+  devm_pwm_put
+  devm_regmap_add_irq_chip
+  devm_regmap_del_irq_chip
+  devm_regmap_field_alloc
   __devm_regmap_init
   __devm_regmap_init_i2c
   __devm_regmap_init_mmio_clk
   __devm_regmap_init_spi
+  devm_regulator_bulk_get
+  devm_regulator_get
+  devm_regulator_get_exclusive
+  devm_regulator_get_optional
+  devm_regulator_put
+  devm_regulator_register
+  devm_regulator_register_notifier
   __devm_release_region
+  devm_request_any_context_irq
   __devm_request_region
+  devm_request_threaded_irq
+  devm_reset_control_array_get
   __devm_reset_control_get
+  devm_reset_controller_register
+  devm_rtc_allocate_device
+  devm_rtc_device_register
+  devm_snd_dmaengine_pcm_register
+  devm_snd_soc_register_card
+  devm_snd_soc_register_component
   __devm_spi_alloc_controller
+  devm_spi_register_controller
+  devm_thermal_of_cooling_device_register
+  devm_thermal_zone_of_sensor_register
+  devm_thermal_zone_of_sensor_unregister
+  devm_usb_get_phy
+  devm_usb_get_phy_by_node
+  devm_usb_get_phy_by_phandle
+  devm_watchdog_register_device
+  _dev_notice
+  dev_open
+  dev_pm_clear_wake_irq
+  dev_pm_domain_attach
+  dev_pm_domain_attach_by_name
+  dev_pm_domain_detach
+  dev_pm_genpd_add_notifier
+  dev_pm_genpd_remove_notifier
+  dev_pm_genpd_set_next_wakeup
+  dev_pm_genpd_set_performance_state
+  dev_pm_opp_add
+  dev_pm_opp_adjust_voltage
+  dev_pm_opp_disable
+  dev_pm_opp_enable
+  dev_pm_opp_find_freq_ceil
+  dev_pm_opp_find_freq_ceil_by_volt
+  dev_pm_opp_find_freq_exact
+  dev_pm_opp_find_freq_floor
+  dev_pm_opp_free_cpufreq_table
+  dev_pm_opp_get_freq
+  dev_pm_opp_get_level
+  dev_pm_opp_get_max_transition_latency
+  dev_pm_opp_get_opp_count
+  dev_pm_opp_get_opp_table
+  dev_pm_opp_get_sharing_cpus
+  dev_pm_opp_get_suspend_opp_freq
+  dev_pm_opp_get_voltage
+  dev_pm_opp_init_cpufreq_table
+  dev_pm_opp_of_add_table
+  dev_pm_opp_of_cpumask_add_table
+  dev_pm_opp_of_cpumask_remove_table
+  dev_pm_opp_of_find_icc_paths
+  dev_pm_opp_of_get_sharing_cpus
+  dev_pm_opp_of_register_em
+  dev_pm_opp_of_remove_table
+  dev_pm_opp_put
+  dev_pm_opp_put_clkname
+  dev_pm_opp_put_opp_table
+  dev_pm_opp_put_regulators
+  dev_pm_opp_register_notifier
+  dev_pm_opp_remove_all_dynamic
+  dev_pm_opp_set_bw
+  dev_pm_opp_set_clkname
+  dev_pm_opp_set_rate
+  dev_pm_opp_set_regulators
+  dev_pm_opp_set_sharing_cpus
+  dev_pm_opp_set_supported_hw
+  dev_pm_opp_unregister_notifier
+  dev_pm_qos_add_notifier
+  dev_pm_qos_add_request
+  dev_pm_qos_expose_latency_tolerance
+  dev_pm_qos_hide_latency_tolerance
+  dev_pm_qos_read_value
+  dev_pm_qos_remove_notifier
+  dev_pm_qos_remove_request
+  dev_pm_qos_update_request
+  dev_pm_qos_update_user_latency_tolerance
+  dev_pm_set_dedicated_wake_irq
+  dev_printk
+  dev_printk_emit
+  dev_queue_xmit
+  devres_add
+  devres_alloc_node
+  devres_free
+  devres_release
+  dev_set_mtu
+  dev_set_name
+  dev_uc_sync_multiple
+  dev_uc_unsync
+  _dev_warn
+  disable_irq
+  disable_irq_nosync
+  disable_percpu_irq
+  disk_end_io_acct
+  disk_start_io_acct
+  divider_get_val
+  divider_recalc_rate
+  divider_ro_round_rate_parent
+  divider_round_rate_parent
+  dma_alloc_attrs
+  dma_async_device_register
+  dma_async_device_unregister
+  dma_async_tx_descriptor_init
+  dma_buf_attach
+  dma_buf_begin_cpu_access
+  dma_buf_begin_cpu_access_partial
+  dma_buf_detach
+  dma_buf_dynamic_attach
+  dma_buf_end_cpu_access
+  dma_buf_end_cpu_access_partial
+  dma_buf_export
+  dma_buf_fd
+  dma_buf_get
+  dma_buf_get_flags
+  dma_buf_map_attachment
+  dma_buf_mmap
+  dma_buf_move_notify
+  dmabuf_page_pool_alloc
+  dmabuf_page_pool_create
+  dmabuf_page_pool_destroy
+  dmabuf_page_pool_free
+  dma_buf_pin
+  dma_buf_put
+  dma_buf_unmap_attachment
+  dma_buf_unpin
+  dma_buf_vmap
+  dma_buf_vunmap
+  dma_contiguous_default_area
+  dmaengine_unmap_put
+  dma_fence_add_callback
+  dma_fence_array_create
+  dma_fence_array_ops
+  dma_fence_context_alloc
+  dma_fence_default_wait
+  dma_fence_enable_sw_signaling
+  dma_fence_free
+  dma_fence_get_status
+  dma_fence_get_stub
+  dma_fence_init
+  dma_fence_match_context
+  dma_fence_release
+  dma_fence_remove_callback
+  dma_fence_signal
+  dma_fence_signal_locked
+  dma_fence_wait_any_timeout
+  dma_fence_wait_timeout
+  dma_free_attrs
+  dma_get_merge_boundary
+  dma_get_required_mask
+  dma_get_sgtable_attrs
+  dma_get_slave_caps
+  dma_get_slave_channel
+  dma_heap_add
+  dma_heap_buffer_alloc
+  dma_heap_buffer_free
+  dma_heap_find
+  dma_heap_get_dev
+  dma_heap_get_drvdata
+  dma_heap_get_name
+  dma_heap_put
+  d_make_root
+  dmam_alloc_attrs
+  dma_map_page_attrs
+  dma_map_resource
+  dma_map_sg_attrs
+  dma_max_mapping_size
+  dmam_free_coherent
+  dma_mmap_attrs
+  dmam_pool_create
+  dma_pool_alloc
+  dma_pool_create
+  dma_pool_destroy
+  dma_pool_free
+  dma_release_channel
+  dma_request_chan
   __dma_request_channel
+  dma_resv_add_excl_fence
+  dma_resv_add_shared_fence
+  dma_resv_fini
+  dma_resv_get_fences_rcu
+  dma_resv_init
+  dma_resv_reserve_shared
+  dma_resv_test_signaled_rcu
+  dma_resv_wait_timeout_rcu
+  dma_set_coherent_mask
+  dma_set_mask
+  dma_sync_sg_for_cpu
+  dma_sync_sg_for_device
+  dma_sync_single_for_cpu
+  dma_sync_single_for_device
+  dma_unmap_page_attrs
+  dma_unmap_resource
+  dma_unmap_sg_attrs
+  do_exit
   __do_once_done
   __do_once_start
+  do_SAK
+  do_trace_rcu_torture_read
+  do_wait_intr
+  do_wait_intr_irq
+  down
+  downgrade_write
+  down_interruptible
+  down_read
+  down_read_killable
+  down_read_trylock
+  down_timeout
+  down_trylock
+  down_write
+  d_path
+  dput
+  drain_workqueue
+  driver_attach
+  driver_create_file
+  driver_find_device
+  driver_register
+  driver_remove_file
+  driver_unregister
+  drm_add_edid_modes
+  drm_add_modes_noedid
+  drm_atomic_add_affected_connectors
+  drm_atomic_add_affected_planes
+  drm_atomic_commit
+  drm_atomic_get_connector_state
+  drm_atomic_get_crtc_state
+  drm_atomic_get_new_connector_for_encoder
+  drm_atomic_get_plane_state
+  drm_atomic_get_private_obj_state
+  drm_atomic_helper_bridge_destroy_state
+  drm_atomic_helper_bridge_duplicate_state
+  drm_atomic_helper_bridge_reset
+  drm_atomic_helper_check
+  drm_atomic_helper_check_modeset
+  drm_atomic_helper_check_planes
+  drm_atomic_helper_check_plane_state
+  drm_atomic_helper_cleanup_planes
+  drm_atomic_helper_commit
+  drm_atomic_helper_commit_cleanup_done
+  drm_atomic_helper_commit_duplicated_state
+  drm_atomic_helper_commit_hw_done
+  drm_atomic_helper_commit_modeset_disables
+  drm_atomic_helper_commit_modeset_enables
+  drm_atomic_helper_commit_planes
+  drm_atomic_helper_commit_tail
   __drm_atomic_helper_connector_destroy_state
+  drm_atomic_helper_connector_destroy_state
   __drm_atomic_helper_connector_duplicate_state
+  drm_atomic_helper_connector_duplicate_state
   __drm_atomic_helper_connector_reset
+  drm_atomic_helper_connector_reset
   __drm_atomic_helper_crtc_destroy_state
+  drm_atomic_helper_crtc_destroy_state
   __drm_atomic_helper_crtc_duplicate_state
+  drm_atomic_helper_crtc_duplicate_state
   __drm_atomic_helper_crtc_reset
+  drm_atomic_helper_crtc_reset
+  drm_atomic_helper_damage_merged
+  drm_atomic_helper_dirtyfb
+  drm_atomic_helper_disable_plane
+  drm_atomic_helper_disable_planes_on_crtc
+  drm_atomic_helper_duplicate_state
+  drm_atomic_helper_fake_vblank
+  drm_atomic_helper_page_flip
   __drm_atomic_helper_plane_destroy_state
+  drm_atomic_helper_plane_destroy_state
   __drm_atomic_helper_plane_duplicate_state
+  drm_atomic_helper_plane_duplicate_state
+  drm_atomic_helper_plane_reset
+  drm_atomic_helper_prepare_planes
   __drm_atomic_helper_private_obj_duplicate_state
+  drm_atomic_helper_set_config
+  drm_atomic_helper_setup_commit
+  drm_atomic_helper_shutdown
+  drm_atomic_helper_swap_state
+  drm_atomic_helper_update_legacy_modeset_state
+  drm_atomic_helper_update_plane
+  drm_atomic_helper_wait_for_dependencies
+  drm_atomic_helper_wait_for_fences
+  drm_atomic_helper_wait_for_flip_done
+  drm_atomic_helper_wait_for_vblanks
+  drm_atomic_normalize_zpos
+  drm_atomic_private_obj_fini
+  drm_atomic_private_obj_init
+  drm_atomic_set_crtc_for_connector
+  drm_atomic_set_crtc_for_plane
+  drm_atomic_set_fb_for_plane
+  drm_atomic_set_fence_for_plane
+  drm_atomic_set_mode_for_crtc
+  drm_atomic_state_alloc
+  drm_atomic_state_clear
+  drm_atomic_state_default_clear
+  drm_atomic_state_default_release
   __drm_atomic_state_free
+  drm_atomic_state_init
+  drm_bridge_add
+  drm_bridge_attach
+  drm_bridge_chain_disable
+  drm_bridge_chain_enable
+  drm_bridge_chain_mode_set
+  drm_bridge_chain_post_disable
+  drm_bridge_chain_pre_enable
+  drm_bridge_hpd_notify
+  drm_bridge_remove
+  drm_client_init
+  drm_client_modeset_commit_locked
+  drm_client_register
+  drm_compat_ioctl
+  drm_connector_attach_dp_subconnector_property
+  drm_connector_attach_edid_property
+  drm_connector_attach_encoder
+  drm_connector_cleanup
+  drm_connector_has_possible_encoder
+  drm_connector_init
+  drm_connector_init_with_ddc
+  drm_connector_list_iter_begin
+  drm_connector_list_iter_end
+  drm_connector_list_iter_next
+  drm_connector_register
+  drm_connector_set_tile_property
+  drm_connector_unregister
+  drm_connector_update_edid_property
+  drm_crtc_arm_vblank_event
+  drm_crtc_cleanup
+  drm_crtc_enable_color_mgmt
+  drm_crtc_from_index
+  drm_crtc_handle_vblank
+  drm_crtc_helper_set_config
+  drm_crtc_helper_set_mode
+  drm_crtc_init
+  drm_crtc_init_with_planes
+  drm_crtc_send_vblank_event
+  drm_crtc_set_max_vblank_count
+  drm_crtc_vblank_count
+  drm_crtc_vblank_count_and_time
+  drm_crtc_vblank_get
+  drm_crtc_vblank_helper_get_vblank_timestamp
+  drm_crtc_vblank_off
+  drm_crtc_vblank_on
+  drm_crtc_vblank_put
+  drm_crtc_vblank_reset
+  drm_crtc_wait_one_vblank
+  drm_cvt_mode
   __drm_dbg
   __drm_debug
+  drm_debugfs_create_files
+  drm_detect_hdmi_monitor
+  drm_detect_monitor_audio
+  drm_dev_alloc
+  drm_dev_dbg
+  drm_dev_enter
+  drm_dev_exit
+  drm_dev_get
+  drm_dev_printk
+  drm_dev_put
+  drm_dev_register
+  drm_dev_set_unique
+  drm_dev_unplug
+  drm_dev_unregister
+  drm_display_mode_to_videomode
+  drm_do_get_edid
+  drm_dp_atomic_find_vcpi_slots
+  drm_dp_atomic_release_vcpi_slots
+  drm_dp_aux_init
+  drm_dp_aux_register
+  drm_dp_aux_unregister
+  drm_dp_bw_code_to_link_rate
+  drm_dp_calc_pbn_mode
+  drm_dp_channel_eq_ok
+  drm_dp_check_act_status
+  drm_dp_clock_recovery_ok
+  drm_dp_dpcd_read
+  drm_dp_dpcd_read_link_status
+  drm_dp_dpcd_write
+  drm_dp_find_vcpi_slots
+  drm_dp_get_adjust_request_pre_emphasis
+  drm_dp_get_adjust_request_voltage
+  drm_dp_get_edid_quirks
+  drm_dp_link_rate_to_bw_code
+  drm_dp_link_train_channel_eq_delay
+  drm_dp_link_train_clock_recovery_delay
+  drm_dp_mst_allocate_vcpi
+  drm_dp_mst_deallocate_vcpi
+  drm_dp_mst_detect_port
+  drm_dp_mst_get_edid
+  drm_dp_mst_get_port_malloc
+  drm_dp_mst_hpd_irq
+  drm_dp_mst_put_port_malloc
+  drm_dp_mst_reset_vcpi_slots
+  drm_dp_mst_topology_mgr_destroy
+  drm_dp_mst_topology_mgr_init
+  drm_dp_mst_topology_mgr_set_mst
+  drm_dp_send_power_updown_phy
+  drm_dp_set_subconnector_property
+  drm_dp_update_payload_part1
+  drm_dp_update_payload_part2
+  drm_edid_block_valid
+  drm_edid_duplicate
+  drm_edid_get_monitor_name
+  drm_edid_header_is_valid
+  drm_edid_is_valid
+  drm_edid_to_sad
+  drm_edid_to_speaker_allocation
+  drm_encoder_cleanup
+  drm_encoder_init
   __drm_err
+  drm_event_cancel_free
+  drm_event_reserve_init
+  drm_event_reserve_init_locked
+  drm_fb_cma_get_gem_obj
+  drm_flip_work_cleanup
+  drm_flip_work_commit
+  drm_flip_work_init
+  drm_flip_work_queue
+  drm_format_info
+  drm_framebuffer_cleanup
+  drm_framebuffer_init
+  drm_framebuffer_lookup
+  drm_framebuffer_remove
+  drm_framebuffer_unregister_private
+  drm_gem_cma_dumb_create_internal
+  drm_gem_cma_free_object
+  drm_gem_cma_mmap
+  drm_gem_cma_prime_get_sg_table
+  drm_gem_cma_prime_import_sg_table
+  drm_gem_cma_prime_mmap
+  drm_gem_cma_prime_vmap
+  drm_gem_cma_prime_vunmap
+  drm_gem_cma_vm_ops
+  drm_gem_create_mmap_offset
+  drm_gem_dmabuf_mmap
+  drm_gem_dmabuf_release
+  drm_gem_dmabuf_vmap
+  drm_gem_dmabuf_vunmap
+  drm_gem_fb_create
+  drm_gem_fb_create_handle
+  drm_gem_fb_destroy
+  drm_gem_fb_get_obj
+  drm_gem_fb_prepare_fb
+  drm_gem_free_mmap_offset
+  drm_gem_get_pages
+  drm_gem_handle_create
+  drm_gem_lock_reservations
+  drm_gem_map_attach
+  drm_gem_map_detach
+  drm_gem_map_dma_buf
+  drm_gem_mmap
+  drm_gem_mmap_obj
+  drm_gem_object_free
+  drm_gem_object_init
+  drm_gem_object_lookup
+  drm_gem_object_put_locked
+  drm_gem_object_release
+  drm_gem_prime_export
+  drm_gem_prime_fd_to_handle
+  drm_gem_prime_handle_to_fd
+  drm_gem_prime_import
+  drm_gem_prime_import_dev
+  drm_gem_prime_mmap
+  drm_gem_private_object_init
+  drm_gem_put_pages
+  drm_gem_shmem_create
+  drm_gem_shmem_free_object
+  drm_gem_shmem_get_sg_table
+  drm_gem_shmem_mmap
+  drm_gem_shmem_pin
+  drm_gem_shmem_print_info
+  drm_gem_shmem_unpin
+  drm_gem_shmem_vmap
+  drm_gem_shmem_vunmap
+  drm_gem_unlock_reservations
+  drm_gem_unmap_dma_buf
+  drm_gem_vm_close
+  drm_gem_vm_open
+  drm_get_connector_status_name
+  drm_get_edid
+  drm_get_format_info
+  drm_get_format_name
+  drm_handle_vblank
+  drm_hdmi_avi_infoframe_from_display_mode
+  drm_helper_connector_dpms
+  drm_helper_disable_unused_functions
+  drm_helper_force_disable_all
+  drm_helper_hpd_irq_event
+  drm_helper_mode_fill_fb_struct
+  drm_helper_probe_single_connector_modes
+  drm_helper_resume_force_mode
+  drm_ioctl
+  drm_irq_install
+  drm_irq_uninstall
+  drm_is_current_master
+  drm_kms_helper_hotplug_event
+  drm_kms_helper_is_poll_worker
+  drm_kms_helper_poll_disable
+  drm_kms_helper_poll_enable
+  drm_kms_helper_poll_fini
+  drm_kms_helper_poll_init
+  drm_match_cea_mode
+  drmm_kmalloc
+  drm_mm_init
+  drm_mm_insert_node_in_range
+  drmm_mode_config_init
+  drm_mm_print
+  drm_mm_remove_node
+  drm_mm_takedown
+  drm_mode_config_cleanup
+  drm_mode_config_helper_resume
+  drm_mode_config_helper_suspend
+  drm_mode_config_reset
+  drm_mode_convert_to_umode
+  drm_mode_convert_umode
+  drm_mode_copy
+  drm_mode_create
+  drm_mode_create_dp_colorspace_property
+  drm_mode_create_scaling_mode_property
+  drm_mode_create_tile_group
+  drm_mode_crtc_set_gamma_size
+  drm_mode_debug_printmodeline
+  drm_mode_destroy
+  drm_mode_duplicate
+  drm_mode_equal
+  drm_mode_equal_no_clocks
+  drm_mode_get_tile_group
+  drm_mode_is_420_only
+  drm_mode_match
+  drm_mode_object_find
+  drm_mode_object_get
+  drm_mode_object_put
+  drm_mode_probed_add
+  drm_modeset_acquire_fini
+  drm_modeset_acquire_init
+  drm_modeset_backoff
+  drm_mode_set_crtcinfo
+  drm_modeset_drop_locks
+  drm_modeset_lock
+  drm_modeset_lock_all
+  drm_modeset_lock_all_ctx
+  drm_modeset_lock_init
+  drm_mode_set_name
+  drm_modeset_unlock
+  drm_modeset_unlock_all
+  drm_mode_sort
+  drm_mode_vrefresh
+  drm_need_swiotlb
+  drm_object_attach_property
+  drm_object_property_set_value
+  drm_of_component_match_add
+  drm_of_find_possible_crtcs
+  drm_open
+  drm_panel_add
+  drm_panel_disable
+  drm_panel_enable
+  drm_panel_get_modes
+  drm_panel_init
+  drm_panel_prepare
+  drm_panel_remove
+  drm_panel_unprepare
+  drm_plane_cleanup
+  drm_plane_create_alpha_property
+  drm_plane_create_blend_mode_property
+  drm_plane_create_rotation_property
+  drm_plane_create_zpos_property
+  drm_plane_enable_fb_damage_clips
+  drm_poll
+  drm_prime_gem_destroy
+  drm_prime_pages_to_sg
+  drm_prime_sg_to_page_addr_arrays
+  drm_printf
   __drm_printfn_coredump
   __drm_printfn_info
   __drm_printfn_seq_file
+  drm_property_blob_get
+  drm_property_blob_put
+  drm_property_create
+  drm_property_create_bitmask
+  drm_property_create_blob
+  drm_property_create_bool
+  drm_property_create_enum
+  drm_property_create_range
+  drm_property_create_signed_range
+  drm_property_lookup_blob
+  drm_property_replace_blob
+  drm_puts
   __drm_puts_coredump
   __drm_puts_seq_file
+  drm_read
+  drm_rect_calc_hscale
+  drm_rect_calc_vscale
+  drm_rect_clip_scaled
+  drm_rect_intersect
+  drm_release
+  drm_rotation_simplify
+  drm_send_event
+  drm_send_event_locked
+  drm_set_preferred_mode
+  drm_simple_encoder_init
+  drm_state_dump
+  drm_syncobj_add_point
+  drm_syncobj_create
+  drm_syncobj_find
+  drm_syncobj_find_fence
+  drm_syncobj_free
+  drm_syncobj_get_fd
+  drm_syncobj_get_handle
+  drm_syncobj_replace_fence
+  drm_sysfs_hotplug_event
+  drm_universal_plane_init
+  drm_vblank_init
+  drm_vma_node_allow
+  drm_vma_node_is_allowed
+  drm_vma_node_revoke
+  drm_wait_one_vblank
+  drm_writeback_connector_init
+  drm_writeback_queue_job
+  drm_writeback_signal_completion
+  dst_release
+  dump_align
+  dump_backtrace
+  dump_emit
+  dump_stack
+  dup_iter
+  dwc3_send_gadget_ep_cmd
+  dwc3_stop_active_transfer
+  dw_handle_msi_irq
+  dw_pcie_host_init
+  dw_pcie_msi_init
+  dw_pcie_own_conf_map_bus
+  dw_pcie_read
+  dw_pcie_setup_rc
+  dw_pcie_write
   __dynamic_dev_dbg
   __dynamic_pr_debug
+  edac_device_add_device
+  edac_device_alloc_ctl_info
+  edac_device_alloc_index
+  edac_device_del_device
+  edac_device_free_ctl_info
+  edac_device_handle_ce_count
+  edac_device_handle_ue_count
+  efi
+  efi_tpm_final_log_size
+  elevator_alloc
+  elv_bio_merge_ok
+  elv_rb_add
+  elv_rb_del
+  elv_rb_find
+  elv_rb_former_request
+  elv_rb_latter_request
+  elv_register
+  elv_rqhash_add
+  elv_rqhash_del
+  elv_unregister
+  emergency_restart
+  enable_irq
+  enable_percpu_irq
+  eth_commit_mac_addr_change
+  ether_setup
+  eth_mac_addr
+  eth_platform_get_mac_address
+  eth_prepare_mac_addr_change
   __ethtool_get_link_ksettings
+  ethtool_op_get_link
+  ethtool_op_get_ts_info
+  ethtool_virtdev_set_link_ksettings
+  eth_type_trans
+  eth_validate_addr
+  eventfd_ctx_fdget
+  eventfd_ctx_fileget
+  eventfd_ctx_put
+  eventfd_ctx_remove_wait_queue
+  eventfd_signal
+  event_triggers_call
+  extcon_find_edev_by_node
+  extcon_get_edev_by_phandle
+  extcon_get_edev_name
+  extcon_get_extcon_dev
+  extcon_get_property
+  extcon_get_state
+  extcon_register_notifier
+  extcon_set_property
+  extcon_set_property_capability
+  extcon_set_state_sync
+  extcon_unregister_notifier
+  fasync_helper
   __fdget
+  fd_install
+  fget
+  file_path
+  file_ra_state_init
+  filp_close
+  filp_open_block
+  find_get_pid
+  find_last_bit
+  find_next_bit
+  find_next_zero_bit
+  find_snd_usb_substream
+  find_task_by_vpid
+  find_vma
+  find_vpid
+  finish_wait
+  firmware_request_nowarn
+  fixed_phy_register
+  fixed_phy_unregister
+  fixed_size_llseek
+  flow_keys_basic_dissector
+  flush_dcache_page
+  flush_delayed_work
   __flush_icache_range
+  flush_signals
+  flush_work
+  flush_workqueue
+  fput
+  frame_vector_create
+  frame_vector_destroy
+  frame_vector_to_pages
+  free_buffer_head
+  free_io_pgtable_ops
+  free_irq
+  free_netdev
   __free_pages
+  free_pages
+  free_pages_exact
+  free_percpu
+  free_percpu_irq
+  freezing_slow_path
+  freq_qos_add_request
+  freq_qos_remove_request
+  freq_qos_update_request
+  freq_scale
+  fs_bio_set
+  fsync_bdev
+  ftrace_dump
+  full_name_hash
+  fwnode_find_reference
+  fwnode_get_name
+  fwnode_get_named_child_node
+  fwnode_get_next_child_node
+  fwnode_gpiod_get_index
+  fwnode_handle_get
+  fwnode_handle_put
+  fwnode_property_present
+  fwnode_property_read_string
+  fwnode_property_read_u32_array
+  fwnode_usb_role_switch_get
+  gcd
+  generic_delete_inode
+  generic_device_group
+  generic_file_llseek
+  generic_file_read_iter
+  generic_handle_irq
+  generic_iommu_put_resv_regions
+  generic_mii_ioctl
+  generic_perform_write
+  generic_write_checks
+  genlmsg_put
+  genl_notify
+  genl_register_family
+  genl_unregister_family
   __genphy_config_aneg
+  genphy_read_status
+  genphy_resume
+  genphy_soft_reset
+  genphy_suspend
+  gen_pool_add_owner
+  gen_pool_alloc_algo_owner
+  gen_pool_avail
+  gen_pool_best_fit
+  gen_pool_create
+  gen_pool_destroy
+  gen_pool_dma_alloc_align
+  gen_pool_dma_zalloc_align
+  gen_pool_first_fit_align
+  gen_pool_first_fit_order_align
+  gen_pool_free_owner
+  gen_pool_has_addr
+  gen_pool_set_algo
+  gen_pool_size
+  gen_pool_virt_to_phys
+  getboottime64
+  get_cpu_device
+  get_cpu_idle_time
+  get_cpu_idle_time_us
+  get_cpu_iowait_time_us
+  get_device
+  get_device_system_crosststamp
   __get_free_pages
+  get_governor_parent_kobj
+  get_next_ino
+  get_option
+  get_options
+  get_pid_task
+  get_random_bytes
+  get_random_bytes_arch
+  get_random_u32
+  get_random_u64
+  get_sg_io_hdr
+  get_state_synchronize_rcu
   __get_task_comm
+  get_task_exe_file
+  get_task_mm
+  get_task_pid
+  get_thermal_instance
+  get_tree_single
+  get_unmapped_area
+  get_unused_fd_flags
+  get_user_pages
+  get_user_pages_fast
+  get_user_pages_remote
+  get_vaddr_frames
+  get_zeroed_page
+  gfp_zone
+  gic_nonsecure_priorities
+  glob_match
+  gnss_allocate_device
+  gnss_deregister_device
+  gnss_insert_raw
+  gnss_put_device
+  gnss_register_device
+  gov_attr_set_get
+  gov_attr_set_init
+  gov_attr_set_put
+  governor_sysfs_ops
+  gpiochip_add_data_with_key
+  gpiochip_add_pin_range
+  gpiochip_find
+  gpiochip_generic_config
+  gpiochip_generic_free
+  gpiochip_generic_request
+  gpiochip_get_data
+  gpiochip_irqchip_add_key
+  gpiochip_line_is_valid
+  gpiochip_lock_as_irq
+  gpiochip_populate_parent_fwspec_fourcell
+  gpiochip_remove
+  gpiochip_set_nested_irqchip
+  gpiochip_unlock_as_irq
+  gpiod_cansleep
+  gpiod_count
+  gpiod_direction_input
+  gpiod_direction_output
+  gpiod_direction_output_raw
+  gpiod_get_optional
+  gpiod_get_raw_value
+  gpiod_get_raw_value_cansleep
+  gpiod_get_value
+  gpiod_get_value_cansleep
+  gpiod_set_consumer_name
+  gpiod_set_debounce
+  gpiod_set_raw_value
+  gpiod_set_raw_value_cansleep
+  gpiod_set_value
+  gpiod_set_value_cansleep
+  gpiod_to_chip
+  gpiod_to_irq
+  gpio_free
+  gpio_free_array
+  gpio_request
+  gpio_request_one
+  gpio_to_desc
+  gro_cells_destroy
+  gro_cells_init
+  gro_cells_receive
+  gs_alloc_req
+  gserial_alloc_line
+  gserial_connect
+  gserial_disconnect
+  gserial_free_line
+  gserial_resume
+  gserial_suspend
+  gs_free_req
+  guid_gen
+  handle_bad_irq
+  handle_edge_irq
+  handle_fasteoi_ack_irq
+  handle_fasteoi_irq
+  handle_level_irq
+  handle_nested_irq
+  handle_simple_irq
+  handle_sysrq
+  hash_digest_size
+  hashlen_string
+  have_governor_per_policy
+  hci_alloc_dev
+  hci_free_dev
+  hci_recv_frame
+  hci_register_dev
+  hci_unregister_dev
+  hdmi_audio_infoframe_init
+  hdmi_audio_infoframe_pack
+  hdmi_avi_infoframe_init
+  hdmi_avi_infoframe_pack
+  hdmi_infoframe_pack
+  hex2bin
+  hex_dump_to_buffer
+  hex_to_bin
+  hid_hw_close
+  hid_hw_open
+  hid_hw_start
+  hid_hw_stop
+  hid_open_report
   __hid_register_driver
+  hid_report_raw_event
   __hid_request
+  hid_unregister_driver
+  hmm_range_fault
+  hrtimer_active
+  hrtimer_cancel
+  hrtimer_forward
   __hrtimer_get_remaining
+  hrtimer_init
+  hrtimer_init_sleeper
+  hrtimer_sleeper_start_expires
+  hrtimer_start_range_ns
+  hrtimer_try_to_cancel
+  hvc_alloc
+  hvc_instantiate
+  hvc_kick
+  hvc_poll
+  hvc_remove
   __hvc_resize
+  hwrng_register
+  hwrng_unregister
+  hwspin_lock_free
+  hwspin_lock_request_specific
   __hwspin_lock_timeout
   __hwspin_unlock
+  hypervisor_kobj
+  i2c_adapter_type
+  i2c_add_adapter
+  i2c_add_numbered_adapter
+  i2c_bit_add_bus
+  i2c_bit_add_numbered_bus
+  i2c_bus_type
+  i2c_client_type
+  i2c_del_adapter
+  i2c_del_driver
+  i2c_for_each_dev
+  i2c_generic_scl_recovery
+  i2c_get_adapter
+  i2c_get_device_id
+  i2c_get_dma_safe_msg_buf
+  i2c_match_id
+  i2c_new_ancillary_device
+  i2c_new_client_device
+  i2c_new_dummy_device
+  i2c_new_scanned_device
+  i2c_parse_fw_timings
+  i2c_put_adapter
+  i2c_put_dma_safe_msg_buf
+  i2c_recover_bus
+  i2c_register_driver
+  i2c_smbus_read_byte
+  i2c_smbus_read_byte_data
+  i2c_smbus_read_i2c_block_data
+  i2c_smbus_read_word_data
+  i2c_smbus_write_byte
+  i2c_smbus_write_byte_data
+  i2c_smbus_write_i2c_block_data
+  i2c_smbus_write_word_data
   __i2c_smbus_xfer
+  i2c_smbus_xfer
   __i2c_transfer
+  i2c_transfer
+  i2c_transfer_buffer_flags
+  i2c_unregister_device
+  i2c_verify_adapter
+  i2c_verify_client
+  icc_disable
+  icc_enable
+  icc_get
+  icc_link_create
+  icc_node_add
+  icc_node_create
+  icc_node_del
+  icc_node_destroy
+  icc_nodes_remove
+  icc_provider_add
+  icc_provider_del
+  icc_put
+  icc_set_bw
+  icc_set_tag
+  icc_std_aggregate
+  icc_sync_state
+  ida_alloc_range
+  ida_destroy
+  ida_free
+  idr_alloc
+  idr_alloc_cyclic
+  idr_alloc_u32
+  idr_destroy
+  idr_find
+  idr_for_each
+  idr_get_next
+  idr_preload
+  idr_remove
+  idr_replace
+  ieee802154_alloc_hw
+  ieee802154_free_hw
+  ieee802154_register_hw
+  ieee802154_rx_irqsafe
+  ieee802154_unregister_hw
+  ieee802154_wake_queue
+  ieee802154_xmit_complete
+  iio_buffer_init
+  iio_buffer_put
+  iio_channel_get
+  iio_channel_get_all
+  iio_channel_release
+  iio_device_alloc
+  iio_device_attach_buffer
+  iio_device_free
   __iio_device_register
+  iio_device_unregister
+  iio_push_to_buffers
+  iio_read_channel_processed
+  iio_read_channel_raw
+  import_iovec
+  in4_pton
+  in6_dev_finish_destroy
+  in6_pton
+  in_aton
+  inc_zone_page_state
+  in_egroup_p
+  inet_proto_csum_replace4
+  init_dummy_netdev
+  init_iova_domain
+  init_net
+  init_on_free
+  init_pid_ns
+  init_pseudo
   __init_rwsem
+  init_srcu_struct
   __init_swait_queue_head
+  init_task
+  init_timer_key
+  init_uts_ns
+  init_wait_entry
   __init_waitqueue_head
+  input_alloc_absinfo
+  input_allocate_device
+  input_close_device
+  input_event
+  input_ff_create
+  input_ff_create_memless
+  input_ff_destroy
+  input_free_device
+  input_mt_assign_slots
+  input_mt_destroy_slots
+  input_mt_drop_unused
+  input_mt_init_slots
+  input_mt_report_finger_count
+  input_mt_report_pointer_emulation
+  input_mt_report_slot_state
+  input_mt_sync_frame
+  input_open_device
+  input_register_device
+  input_register_handle
+  input_register_handler
+  input_set_abs_params
+  input_set_capability
+  input_set_timestamp
+  input_unregister_device
+  input_unregister_handle
+  input_unregister_handler
+  interval_tree_insert
+  interval_tree_iter_first
+  interval_tree_iter_next
+  interval_tree_remove
+  int_pow
+  int_sqrt
+  invalidate_bdev
+  invalidate_mapping_pages
+  iomem_resource
+  iommu_alloc_resv_region
+  iommu_attach_device
+  iommu_attach_group
+  iommu_aux_attach_device
+  iommu_aux_detach_device
+  iommu_aux_get_pasid
+  iommu_detach_device
+  iommu_detach_group
+  iommu_dev_enable_feature
+  iommu_dev_feature_enabled
+  iommu_device_register
+  iommu_device_sysfs_add
+  iommu_device_sysfs_remove
+  iommu_device_unlink
+  iommu_device_unregister
+  iommu_dma_enable_best_fit_algo
+  iommu_dma_get_resv_regions
+  iommu_dma_reserve_iova
+  iommu_domain_alloc
+  iommu_domain_free
+  iommu_domain_get_attr
+  iommu_domain_set_attr
+  iommu_fwspec_add_ids
+  iommu_fwspec_free
+  iommu_get_dma_cookie
+  iommu_get_domain_for_dev
+  iommu_get_msi_cookie
+  iommu_group_alloc
+  iommu_group_for_each_dev
+  iommu_group_get
+  iommu_group_get_iommudata
+  iommu_group_put
+  iommu_group_ref_get
+  iommu_group_set_iommudata
+  iommu_group_set_name
+  iommu_iova_to_phys
+  iommu_map
+  iommu_map_sg
+  iommu_present
+  iommu_put_dma_cookie
+  iommu_register_device_fault_handler
+  iommu_report_device_fault
+  iommu_set_fault_handler
+  iommu_unmap
+  iommu_unregister_device_fault_handler
   __ioread32_copy
   __ioremap
+  io_schedule_timeout
+  iounmap
+  iov_iter_bvec
+  iov_iter_kvec
   __iowrite32_copy
+  ip_compute_csum
+  ipi_desc_get
+  ip_send_check
+  iput
   __ipv6_addr_type
+  ipv6_ext_hdr
+  ipv6_find_hdr
+  ipv6_skip_exthdr
   __irq_alloc_descs
+  irq_chip_ack_parent
+  irq_chip_disable_parent
+  irq_chip_enable_parent
+  irq_chip_eoi_parent
+  irq_chip_get_parent_state
+  irq_chip_mask_parent
+  irq_chip_retrigger_hierarchy
+  irq_chip_set_affinity_parent
+  irq_chip_set_parent_state
+  irq_chip_set_type_parent
+  irq_chip_set_vcpu_affinity_parent
+  irq_chip_set_wake_parent
+  irq_chip_unmask_parent
+  irq_create_fwspec_mapping
+  irq_create_mapping_affinity
+  irq_create_of_mapping
+  irq_dispose_mapping
   __irq_domain_add
+  irq_domain_add_simple
+  irq_domain_alloc_irqs_parent
+  irq_domain_create_hierarchy
+  irq_domain_free_irqs_common
+  irq_domain_free_irqs_parent
+  irq_domain_get_irq_data
+  irq_domain_remove
+  irq_domain_set_hwirq_and_chip
+  irq_domain_set_info
+  irq_domain_simple_ops
+  irq_domain_update_bus_token
+  irq_domain_xlate_onecell
+  irq_domain_xlate_onetwocell
+  irq_domain_xlate_twocell
+  irq_find_mapping
+  irq_find_matching_fwspec
+  irq_get_irqchip_state
+  irq_get_irq_data
+  irq_modify_status
+  irq_of_parse_and_map
+  irq_set_affinity_hint
+  irq_set_affinity_notifier
+  irq_set_chained_handler_and_data
+  irq_set_chip
+  irq_set_chip_and_handler_name
+  irq_set_chip_data
   __irq_set_handler
+  irq_set_handler_data
+  irq_set_irqchip_state
+  irq_set_irq_type
+  irq_set_irq_wake
+  irq_set_parent
+  irq_to_desc
+  irq_work_queue
+  irq_work_queue_on
+  irq_work_sync
+  is_dma_buf_file
+  is_vmalloc_addr
+  iwe_stream_add_event
+  iwe_stream_add_point
+  iwe_stream_add_value
+  jiffies_64_to_clock_t
+  jiffies64_to_msecs
+  jiffies
+  jiffies_to_msecs
+  jiffies_to_usecs
+  kasan_flag_enabled
+  kasprintf
+  kernel_bind
+  kernel_connect
+  kernel_cpustat
+  kernel_getsockname
+  kernel_kobj
+  kernel_power_off
+  kernel_recvmsg
+  kernel_restart
+  kernel_sendmsg
+  kernel_sigaction
+  kernfs_find_and_get_ns
+  kernfs_notify
+  kernfs_path_from_node
+  kernfs_put
+  kern_mount
+  kern_path
+  kern_unmount
   __kfifo_alloc
   __kfifo_free
   __kfifo_in
@@ -123,122 +1950,1785 @@
   __kfifo_out
   __kfifo_out_peek
   __kfifo_to_user
+  kfree
+  kfree_const
+  kfree_sensitive
   __kfree_skb
+  kfree_skb
+  kick_all_cpus_sync
+  kill_anon_super
+  kill_fasync
+  kill_litter_super
+  kimage_vaddr
+  kimage_voffset
+  kiocb_set_cancel_fn
   __kmalloc
+  kmalloc_caches
+  kmalloc_order
+  kmalloc_order_trace
+  kmem_cache_alloc
+  kmem_cache_alloc_trace
+  kmem_cache_create
+  kmem_cache_create_usercopy
+  kmem_cache_destroy
+  kmem_cache_free
+  kmemdup
+  kmemdup_nul
+  kmsg_dump_get_line
+  kmsg_dump_rewind
+  kobject_add
+  kobject_create_and_add
+  kobject_del
+  kobject_get
+  kobject_init
+  kobject_init_and_add
+  kobject_put
+  kobject_set_name
+  kobject_uevent
+  kobject_uevent_env
+  kobj_sysfs_ops
+  krealloc
+  kset_create_and_add
+  kset_unregister
+  ksize
+  ksoftirqd
+  kstat
+  kstat_irqs_cpu
+  kstat_irqs_usr
+  kstrdup
+  kstrdup_const
+  kstrdup_quotable_cmdline
+  kstrndup
+  kstrtobool
+  kstrtobool_from_user
+  kstrtoint
+  kstrtoint_from_user
+  kstrtol_from_user
+  kstrtoll
+  kstrtos16
+  kstrtos8
+  kstrtos8_from_user
+  kstrtou16
+  kstrtou16_from_user
+  kstrtou8
+  kstrtou8_from_user
+  kstrtouint
+  kstrtouint_from_user
+  kstrtoul_from_user
+  kstrtoull
+  kstrtoull_from_user
+  ksys_sync_helper
+  kthread_bind
+  kthread_bind_mask
+  kthread_blkcg
+  kthread_cancel_delayed_work_sync
+  kthread_cancel_work_sync
+  kthread_create_on_node
+  kthread_create_worker
+  kthread_delayed_work_timer_fn
+  kthread_destroy_worker
+  kthread_flush_work
+  kthread_flush_worker
   __kthread_init_worker
+  kthread_mod_delayed_work
+  kthread_park
+  kthread_parkme
+  kthread_queue_delayed_work
+  kthread_queue_work
+  kthread_should_park
+  kthread_should_stop
+  kthread_stop
+  kthread_unpark
+  kthread_unuse_mm
+  kthread_use_mm
+  kthread_worker_fn
+  ktime_add_safe
+  ktime_get
+  ktime_get_coarse_with_offset
+  ktime_get_mono_fast_ns
+  ktime_get_raw
+  ktime_get_raw_ts64
+  ktime_get_real_seconds
+  ktime_get_real_ts64
+  ktime_get_seconds
+  ktime_get_ts64
+  ktime_get_with_offset
+  kvasprintf
+  kvfree
+  kvfree_call_rcu
+  kvmalloc_node
+  led_classdev_flash_register_ext
+  led_classdev_flash_unregister
+  led_classdev_register_ext
+  led_classdev_unregister
+  led_trigger_event
+  led_trigger_register_simple
+  led_trigger_unregister_simple
   __list_add_valid
   __list_del_entry_valid
+  list_sort
+  llist_add_batch
+  llist_reverse_order
   __local_bh_enable_ip
   __lock_page
+  lock_sock_nested
+  log_abnormal_wakeup_reason
+  log_buf_addr_get
+  log_buf_len_get
   __log_post_read_mmio
   __log_read_mmio
+  log_threaded_irq_wakeup_reason
   __log_write_mmio
+  loops_per_jiffy
+  lzo1x_1_compress
+  lzo1x_decompress_safe
+  lzorle1x_1_compress
+  mac_pton
+  match_string
+  mbox_chan_received_data
+  mbox_chan_txdone
+  mbox_client_txdone
+  mbox_controller_register
+  mbox_controller_unregister
+  mbox_free_channel
+  mbox_request_channel
+  mbox_send_message
+  mdiobus_alloc_size
+  mdiobus_free
+  mdiobus_read
   __mdiobus_register
+  mdiobus_unregister
+  mdiobus_write
+  media_device_cleanup
+  media_device_init
   __media_device_register
+  media_device_unregister
+  media_entity_pads_init
+  memblock_end_of_DRAM
+  memblock_free
   __memcat_p
+  memchr
+  memchr_inv
+  memcmp
+  memcpy
   __memcpy_fromio
   __memcpy_toio
+  memdup_user
+  memdup_user_nul
+  memmove
+  memory_block_size_bytes
+  memory_read_from_buffer
+  memparse
+  mempool_alloc
+  mempool_alloc_slab
+  mempool_create
+  mempool_create_node
+  mempool_destroy
+  mempool_exit
+  mempool_free
+  mempool_free_slab
+  mempool_init
+  mempool_kfree
+  mempool_kmalloc
+  memremap
+  memset64
+  memset
   __memset_io
+  memstart_addr
+  memunmap
+  mfd_add_devices
+  mfd_remove_devices
+  migrate_swap
+  mii_check_media
+  mii_ethtool_get_link_ksettings
+  mii_ethtool_gset
+  mii_ethtool_set_link_ksettings
+  mii_link_ok
+  mii_nway_restart
+  mipi_dsi_attach
+  mipi_dsi_compression_mode
+  mipi_dsi_create_packet
+  mipi_dsi_dcs_read
+  mipi_dsi_dcs_set_column_address
+  mipi_dsi_dcs_set_display_brightness
+  mipi_dsi_dcs_set_page_address
+  mipi_dsi_dcs_set_tear_off
+  mipi_dsi_dcs_write_buffer
+  mipi_dsi_detach
+  mipi_dsi_device_register_full
+  mipi_dsi_device_unregister
+  mipi_dsi_driver_register_full
+  mipi_dsi_driver_unregister
+  mipi_dsi_host_register
+  mipi_dsi_host_unregister
+  mipi_dsi_packet_format_is_long
+  mipi_dsi_picture_parameter_set
+  misc_deregister
+  misc_register
+  mktime64
+  mmc_add_host
+  mmc_alloc_host
+  mmc_app_cmd
+  mmc_calc_max_discard
+  mmc_can_erase
+  mmc_can_gpio_cd
+  mmc_can_secure_erase_trim
+  mmc_can_trim
   __mmc_claim_host
+  mmc_cmdq_disable
+  mmc_cmdq_enable
+  mmc_cqe_post_req
+  mmc_cqe_recovery
+  mmc_cqe_request_done
+  mmc_cqe_start_req
+  mmc_detect_card_removed
+  mmc_detect_change
+  mmc_erase
+  mmc_erase_group_aligned
+  mmc_flush_cache
+  mmc_free_host
+  mmc_get_card
+  mmc_get_ext_csd
+  mmc_gpiod_request_cd
+  mmc_gpiod_request_cd_irq
+  mmc_gpiod_request_ro
+  mmc_gpio_get_cd
+  mmc_gpio_get_ro
+  mmc_hw_reset
+  mmc_of_parse
+  mmc_of_parse_voltage
+  mmc_put_card
+  mmc_register_driver
+  mmc_regulator_get_supply
+  mmc_regulator_set_ocr
+  mmc_regulator_set_vqmmc
+  mmc_release_host
+  mmc_remove_host
+  mmc_request_done
+  mmc_retune_pause
+  mmc_retune_release
+  mmc_retune_unpause
+  mmc_run_bkops
+  mmc_sanitize
   __mmc_send_status
+  mmc_send_status
+  mmc_send_tuning
+  mmc_set_data_timeout
+  mmc_start_request
+  mmc_switch
+  mmc_unregister_driver
+  mmc_wait_for_cmd
+  mmc_wait_for_req
   __mmdrop
+  mmput
+  mm_trace_rss_stat
+  mmu_interval_notifier_insert
+  mmu_interval_notifier_remove
+  mmu_interval_read_begin
+  mmu_notifier_synchronize
+  mod_delayed_work_on
+  mod_node_page_state
+  mod_timer
   __module_get
+  module_layout
+  module_put
   __msecs_to_jiffies
+  msleep
+  msleep_interruptible
   __mutex_init
+  mutex_is_locked
+  mutex_lock
+  mutex_lock_interruptible
+  mutex_trylock
+  mutex_trylock_recursive
+  mutex_unlock
+  names_cachep
+  name_to_dev_t
   __napi_alloc_skb
+  napi_complete_done
+  napi_consume_skb
+  napi_disable
+  napi_gro_flush
+  napi_gro_receive
   __napi_schedule
+  napi_schedule_prep
   __ndelay
   __netdev_alloc_skb
+  netdev_change_features
+  netdev_err
+  netdev_increment_features
+  netdev_info
+  netdev_lower_state_changed
+  netdev_master_upper_dev_link
+  netdev_notify_peers
+  netdev_pick_tx
+  netdev_rx_handler_register
+  netdev_rx_handler_unregister
+  netdev_state_change
+  netdev_update_features
+  netdev_upper_dev_link
+  netdev_upper_dev_unlink
+  netdev_warn
+  netif_carrier_off
+  netif_carrier_on
+  netif_device_attach
+  netif_device_detach
+  netif_napi_add
   __netif_napi_del
+  netif_receive_skb
+  netif_receive_skb_list
+  netif_rx
+  netif_rx_ni
+  netif_schedule_queue
+  netif_set_real_num_rx_queues
+  netif_set_real_num_tx_queues
   __netif_set_xps_queue
+  netif_stacked_transfer_operstate
+  netif_tx_stop_all_queues
+  netif_tx_wake_queue
+  netlink_ack
+  netlink_broadcast
+  netlink_capable
+  netlink_has_listeners
   __netlink_kernel_create
+  netlink_kernel_release
+  netlink_register_notifier
+  netlink_unicast
+  netlink_unregister_notifier
+  net_namespace_list
+  net_ratelimit
+  new_inode
   __next_zones_zonelist
+  nf_conntrack_destroy
+  nla_append
+  nla_find
+  nla_memcpy
   __nla_parse
+  nla_put_64bit
+  nla_put
+  nla_put_nohdr
+  nla_reserve_64bit
+  nla_reserve
+  nla_strlcpy
   __nla_validate
   __nlmsg_put
+  no_llseek
+  nonseekable_open
+  noop_llseek
+  no_seek_end_llseek
+  nr_cpu_ids
+  nr_ipi_get
+  nr_irqs
+  ns_capable
+  nsecs_to_jiffies
+  nsec_to_clock_t
+  ns_to_timespec64
   __num_online_cpus
+  nvdimm_bus_register
+  nvdimm_bus_unregister
+  nvdimm_pmem_region_create
+  nvmem_cell_get
+  nvmem_cell_put
+  nvmem_cell_read
+  nvmem_cell_read_u32
+  nvmem_cell_write
+  nvmem_device_put
+  nvmem_device_read
+  nvmem_device_write
+  of_address_to_resource
+  of_alias_get_highest_id
+  of_alias_get_id
+  of_clk_add_hw_provider
+  of_clk_add_provider
+  of_clk_del_provider
+  of_clk_get
+  of_clk_get_by_name
+  of_clk_get_from_provider
+  of_clk_get_parent_count
+  of_clk_get_parent_name
+  of_clk_hw_onecell_get
+  of_clk_hw_simple_get
+  of_clk_set_defaults
+  of_clk_src_onecell_get
+  of_clk_src_simple_get
+  of_count_phandle_with_args
+  of_cpufreq_cooling_register
+  of_cpu_node_to_id
+  of_css
+  of_devfreq_cooling_register
+  of_devfreq_cooling_register_power
+  of_device_get_match_data
+  of_device_is_available
+  of_device_is_compatible
+  of_device_modalias
+  of_device_request_module
+  of_device_uevent_modalias
+  of_dma_configure_id
+  of_dma_controller_free
+  of_dma_controller_register
+  of_dma_is_coherent
+  of_drm_find_bridge
+  of_drm_find_panel
+  of_find_all_nodes
+  of_find_compatible_node
+  of_find_device_by_node
+  of_find_i2c_adapter_by_node
+  of_find_i2c_device_by_node
+  of_find_matching_node_and_match
+  of_find_mipi_dsi_host_by_node
+  of_find_node_by_name
+  of_find_node_by_phandle
+  of_find_node_by_type
+  of_find_node_opts_by_path
+  of_find_node_with_property
+  of_find_property
+  of_fwnode_ops
+  of_genpd_add_provider_onecell
+  of_genpd_add_provider_simple
+  of_genpd_del_provider
+  of_get_address
+  of_get_child_by_name
+  of_get_compatible_child
+  of_get_cpu_node
+  of_get_dma_window
+  of_get_named_gpio_flags
+  of_get_next_available_child
+  of_get_next_child
+  of_get_next_parent
+  of_get_parent
+  of_get_property
+  of_get_regulator_init_data
+  of_graph_get_endpoint_by_regs
+  of_graph_get_next_endpoint
+  of_graph_get_port_parent
+  of_graph_get_remote_endpoint
+  of_graph_get_remote_node
+  of_graph_get_remote_port
+  of_graph_get_remote_port_parent
+  of_graph_is_present
+  of_graph_parse_endpoint
+  of_hwspin_lock_get_id
+  of_i2c_get_board_info
+  of_icc_get
+  of_icc_xlate_onecell
+  of_iomap
+  of_irq_find_parent
+  of_irq_get
+  of_irq_get_byname
+  of_irq_parse_one
+  of_machine_is_compatible
+  of_match_device
+  of_match_node
+  of_modalias_node
+  of_n_addr_cells
+  of_node_name_eq
+  of_n_size_cells
+  of_nvmem_device_get
+  of_parse_phandle
+  of_parse_phandle_with_args
+  of_parse_phandle_with_fixed_args
+  of_phandle_iterator_init
+  of_phandle_iterator_next
+  of_phy_simple_xlate
+  of_platform_depopulate
+  of_platform_device_create
+  of_platform_device_destroy
+  of_platform_populate
+  of_property_count_elems_of_size
+  of_property_match_string
+  of_property_read_string
+  of_property_read_string_helper
+  of_property_read_u32_index
+  of_property_read_u64
+  of_property_read_u64_index
+  of_property_read_variable_u16_array
+  of_property_read_variable_u32_array
+  of_property_read_variable_u64_array
+  of_property_read_variable_u8_array
+  of_prop_next_string
+  of_prop_next_u32
+  of_pwm_xlate_with_flags
+  of_reserved_mem_device_init_by_idx
+  of_reserved_mem_device_release
+  of_reserved_mem_lookup
+  of_reset_control_array_get
   __of_reset_control_get
+  of_root
+  of_thermal_get_ntrips
+  of_thermal_get_trip_points
+  of_thermal_is_trip_valid
+  of_translate_address
+  of_usb_get_phy_mode
+  of_usb_host_tpl_support
+  on_each_cpu
+  oops_in_progress
+  orderly_poweroff
+  overflowuid
+  page_endio
+  page_mapping
+  page_reporting_register
+  page_reporting_unregister
+  panic
+  panic_notifier_list
+  panic_timeout
+  param_array_ops
+  param_get_int
+  param_get_string
+  param_get_uint
+  param_get_ullong
+  param_ops_bint
+  param_ops_bool
+  param_ops_byte
+  param_ops_charp
+  param_ops_hexint
+  param_ops_int
+  param_ops_long
+  param_ops_short
+  param_ops_string
+  param_ops_uint
+  param_ops_ullong
+  param_ops_ulong
+  param_ops_ushort
+  param_set_bool
+  param_set_copystring
+  param_set_int
+  param_set_uint
+  part_end_io_acct
+  part_start_io_acct
+  passthru_features_check
+  path_put
+  pause_cpus
+  pci_alloc_irq_vectors_affinity
+  pci_assign_resource
+  pci_assign_unassigned_bus_resources
+  pcibios_resource_to_bus
+  pci_bus_resource_n
+  pci_bus_type
+  pci_clear_master
+  pci_d3cold_disable
+  pci_device_group
+  pci_device_is_present
+  pci_dev_present
+  pci_dev_put
+  pci_disable_device
+  pci_disable_msi
+  pcie_aspm_enabled
+  pcie_bandwidth_available
+  pcie_capability_read_word
+  pcie_capability_write_word
+  pcie_get_mps
+  pcie_get_speed_cap
+  pci_enable_atomic_ops_to_root
+  pci_enable_device
+  pci_enable_device_mem
+  pci_enable_msi
+  pci_enable_wake
+  pci_find_bus
+  pci_find_capability
+  pci_find_ext_capability
+  pci_find_next_capability
+  pci_free_irq
+  pci_free_irq_vectors
+  pci_generic_config_read
+  pci_generic_config_write
+  pci_get_device
+  pci_get_domain_bus_and_slot
+  pci_get_slot
+  pci_host_probe
+  pci_intx
+  pci_iomap
+  pci_iomap_range
+  pci_ioremap_bar
+  pci_irq_get_affinity
+  pci_irq_vector
+  pci_load_and_free_saved_state
+  pci_load_saved_state
+  pci_map_rom
+  pci_match_id
+  pcim_enable_device
+  pci_msi_create_irq_domain
+  pci_msi_mask_irq
+  pci_msi_unmask_irq
+  pci_msix_vec_count
+  pci_read_config_byte
+  pci_read_config_dword
+  pci_read_config_word
   __pci_register_driver
-  __per_cpu_offset
+  pci_release_region
+  pci_release_regions
+  pci_release_resource
+  pci_release_selected_regions
+  pci_request_irq
+  pci_request_region
+  pci_request_regions
+  pci_request_selected_regions
+  pci_rescan_bus
+  pci_resize_resource
+  pci_restore_msi_state
+  pci_restore_state
+  pci_save_state
+  pci_select_bars
+  pci_set_master
+  pci_set_mwi
+  pci_set_power_state
+  pci_store_saved_state
+  pci_unmap_rom
+  pci_unregister_driver
+  pci_wake_from_d3
+  pci_walk_bus
+  pci_write_config_byte
+  pci_write_config_dword
+  pci_write_config_word
+  PDE_DATA
   __percpu_down_read
+  percpu_down_write
   __percpu_init_rwsem
+  __per_cpu_offset
+  per_cpu_ptr_to_phys
+  percpu_ref_exit
+  percpu_ref_init
+  percpu_ref_is_zero
+  percpu_ref_kill_and_confirm
+  percpu_ref_switch_to_atomic_sync
+  percpu_ref_switch_to_percpu
+  percpu_up_write
+  perf_aux_output_begin
+  perf_aux_output_end
+  perf_aux_output_flag
+  perf_event_addr_filters_sync
+  perf_event_create_kernel_counter
+  perf_event_disable
+  perf_event_enable
+  perf_event_pause
+  perf_event_read_local
+  perf_event_read_value
+  perf_event_release_kernel
+  perf_event_update_userpage
+  perf_get_aux
+  perf_pmu_migrate_context
+  perf_pmu_register
+  perf_pmu_unregister
+  perf_trace_buf_alloc
+  perf_trace_run_bpf_submit
+  pfn_valid
+  phy_attached_info
+  phy_calibrate
+  phy_configure
+  phy_connect
+  phy_connect_direct
+  phy_disconnect
+  phy_do_ioctl_running
+  phy_drivers_register
+  phy_drivers_unregister
+  phy_ethtool_get_link_ksettings
+  phy_ethtool_nway_reset
+  phy_ethtool_set_link_ksettings
+  phy_ethtool_set_wol
+  phy_exit
+  phy_find_first
+  phy_get_pause
+  phy_init
+  phy_init_hw
+  phy_mii_ioctl
+  phy_pm_runtime_get_sync
+  phy_pm_runtime_put_sync
+  phy_power_off
+  phy_power_on
+  phy_print_status
+  phy_register_fixup_for_uid
+  phy_save_page
+  phy_set_mode_ext
+  phy_start
+  phy_stop
+  phy_unregister_fixup_for_uid
+  pick_highest_pushable_task
+  pid_nr_ns
+  pid_task
+  pinconf_generic_dt_free_map
+  pinconf_generic_dt_node_to_map
+  pinctrl_add_gpio_range
+  pinctrl_dev_get_drvdata
+  pinctrl_enable
+  pinctrl_force_default
+  pinctrl_force_sleep
+  pinctrl_get
+  pinctrl_lookup_state
+  pinctrl_pm_select_default_state
+  pinctrl_pm_select_idle_state
+  pinctrl_pm_select_sleep_state
+  pinctrl_put
+  pinctrl_remove_gpio_range
+  pinctrl_select_default_state
+  pinctrl_select_state
+  pinctrl_utils_free_map
+  pin_get_name
+  pin_user_pages
+  pin_user_pages_fast
+  pin_user_pages_remote
+  pipe_lock
+  pipe_unlock
+  pktgen_xfrm_outer_mode_output
+  platform_add_devices
+  platform_bus_type
+  platform_device_add
+  platform_device_add_data
+  platform_device_add_properties
+  platform_device_add_resources
+  platform_device_alloc
+  platform_device_del
+  platform_device_put
+  platform_device_register
+  platform_device_register_full
+  platform_device_unregister
   __platform_driver_probe
   __platform_driver_register
+  platform_driver_unregister
+  platform_find_device_by_driver
+  platform_get_irq
+  platform_get_irq_byname
+  platform_get_irq_byname_optional
+  platform_get_irq_optional
+  platform_get_resource
+  platform_get_resource_byname
+  platform_irq_count
   __platform_register_drivers
+  pm_clk_add
+  pm_clk_create
+  pm_clk_destroy
+  pm_clk_resume
+  pm_clk_suspend
+  pm_generic_resume
+  pm_generic_runtime_resume
+  pm_generic_runtime_suspend
+  pm_generic_suspend
+  pm_genpd_add_subdomain
+  pm_genpd_init
+  pm_genpd_remove
+  pm_genpd_remove_subdomain
+  pm_power_off
   __pm_relax
+  pm_relax
+  pm_runtime_allow
+  pm_runtime_autosuspend_expiration
+  pm_runtime_barrier
   __pm_runtime_disable
+  pm_runtime_enable
+  pm_runtime_forbid
+  pm_runtime_force_resume
+  pm_runtime_force_suspend
+  pm_runtime_get_if_active
   __pm_runtime_idle
+  pm_runtime_irq_safe
+  pm_runtime_no_callbacks
   __pm_runtime_resume
+  pm_runtime_set_autosuspend_delay
   __pm_runtime_set_status
   __pm_runtime_suspend
   __pm_runtime_use_autosuspend
   __pm_stay_awake
+  pm_stay_awake
+  pm_suspend_global_flags
+  pm_system_wakeup
+  pm_wakeup_dev_event
+  pm_wakeup_ws_event
+  policy_has_boost_freq
+  power_supply_changed
+  power_supply_get_by_name
+  power_supply_get_by_phandle_array
+  power_supply_get_drvdata
+  power_supply_get_property
+  power_supply_is_system_supplied
+  power_supply_put
+  power_supply_register
+  power_supply_reg_notifier
+  power_supply_set_property
+  power_supply_unregister
+  power_supply_unreg_notifier
+  prandom_bytes
+  prandom_u32
+  preempt_schedule
+  preempt_schedule_notrace
+  prepare_to_wait
+  prepare_to_wait_event
+  print_hex_dump
+  printk
+  printk_deferred
   __printk_ratelimit
+  printk_timed_ratelimit
+  proc_create
+  proc_create_data
+  proc_create_single_data
+  proc_dointvec
+  proc_dointvec_minmax
+  proc_dostring
+  proc_douintvec_minmax
+  proc_mkdir
+  proc_mkdir_data
+  proc_remove
+  proc_set_size
+  proc_set_user
+  proc_symlink
+  proto_register
+  proto_unregister
+  ps2_begin_command
+  ps2_cmd_aborted
+  ps2_command
+  ps2_drain
+  ps2_end_command
+  ps2_handle_ack
+  ps2_handle_response
+  ps2_init
+  ps2_sendbyte
+  ps2_sliced_command
+  pskb_expand_head
   __pskb_pull_tail
+  ___pskb_trim
+  pstore_register
+  pstore_unregister
+  public_key_verify_signature
+  put_device
+  put_disk
+  put_iova_domain
   __put_page
+  put_pid
+  put_sg_io_hdr
   __put_task_struct
+  put_tty_driver
+  put_unused_fd
+  put_vaddr_frames
+  pwm_apply_state
+  pwmchip_add
+  pwmchip_remove
+  pwm_get_chip_data
+  pwm_set_chip_data
+  qcom_smem_state_get
+  qcom_smem_state_register
+  qcom_smem_state_unregister
+  qcom_smem_state_update_bits
+  qdisc_reset
+  queue_delayed_work_on
+  queue_work_on
+  radix_tree_delete
+  radix_tree_insert
+  radix_tree_iter_delete
+  radix_tree_iter_resume
+  radix_tree_lookup
+  radix_tree_maybe_preload
+  radix_tree_next_chunk
+  radix_tree_tagged
+  ___ratelimit
+  rational_best_approximation
+  raw_notifier_call_chain
+  raw_notifier_chain_register
+  raw_notifier_chain_unregister
+  _raw_read_lock
+  _raw_read_lock_bh
+  _raw_read_lock_irq
+  _raw_read_lock_irqsave
+  _raw_read_unlock
+  _raw_read_unlock_bh
+  _raw_read_unlock_irq
+  _raw_read_unlock_irqrestore
+  _raw_spin_lock
+  _raw_spin_lock_bh
+  _raw_spin_lock_irq
+  _raw_spin_lock_irqsave
+  _raw_spin_trylock
+  _raw_spin_trylock_bh
+  _raw_spin_unlock
+  _raw_spin_unlock_bh
+  _raw_spin_unlock_irq
+  _raw_spin_unlock_irqrestore
+  _raw_write_lock
+  _raw_write_lock_bh
+  _raw_write_lock_irq
+  _raw_write_lock_irqsave
+  _raw_write_unlock
+  _raw_write_unlock_bh
+  _raw_write_unlock_irq
+  _raw_write_unlock_irqrestore
+  rb_erase
   __rb_erase_color
+  rb_first
+  rb_first_postorder
   __rb_insert_augmented
+  rb_insert_color
+  rb_last
+  rb_next
+  rb_next_postorder
+  rb_prev
+  rb_replace_node
+  rcu_barrier
+  rcu_barrier_tasks
+  rcu_barrier_tasks_trace
+  rcu_bind_current_to_nocb
+  rcu_cpu_stall_suppress
+  rcu_cpu_stall_suppress_at_boot
+  rcu_expedite_gp
+  rcu_force_quiescent_state
+  rcu_fwd_progress_check
+  rcu_get_gp_kthreads_prio
+  rcu_get_gp_seq
+  rcu_gp_is_expedited
+  rcu_gp_is_normal
+  rcu_gp_set_torture_wait
+  rcu_inkernel_boot_has_ended
+  rcu_is_watching
+  rcu_jiffies_till_stall_check
   __rcu_read_lock
   __rcu_read_unlock
+  rcu_read_unlock_trace_special
+  rcutorture_get_gp_data
+  rcu_unexpedite_gp
+  rcuwait_wake_up
+  rdev_get_drvdata
+  rdev_get_id
+  reboot_mode
+  reciprocal_value
+  refcount_dec_and_lock
+  refcount_dec_and_mutex_lock
+  refcount_dec_not_one
+  refcount_warn_saturate
+  refresh_frequency_limits
   __refrigerator
+  regcache_cache_bypass
+  regcache_cache_only
+  regcache_drop_region
+  regcache_mark_dirty
+  regcache_sync
+  regcache_sync_region
+  register_blkdev
   __register_chrdev
+  register_chrdev_region
+  register_console
+  register_die_notifier
+  register_filesystem
+  register_ftrace_export
+  register_inet6addr_notifier
+  register_inetaddr_notifier
+  register_kernel_break_hook
+  register_kprobe
+  register_kretprobe
+  register_memory_notifier
+  register_module_notifier
+  register_netdev
+  register_netdevice
+  register_netdevice_notifier
+  register_netevent_notifier
+  register_net_sysctl
+  register_oom_notifier
+  register_pernet_device
+  register_pernet_subsys
+  register_pm_notifier
+  register_reboot_notifier
+  register_restart_handler
   __register_rpmsg_driver
+  register_shrinker
+  register_syscore_ops
+  register_sysctl
+  register_sysctl_table
+  register_virtio_device
+  register_virtio_driver
+  register_vmap_purge_notifier
+  regmap_add_irq_chip
+  regmap_async_complete
+  regmap_bulk_read
+  regmap_bulk_write
+  regmap_check_range_table
+  regmap_del_irq_chip
+  regmap_exit
+  regmap_field_read
+  regmap_field_update_bits_base
+  regmap_get_device
   __regmap_init
+  regmap_irq_get_domain
+  regmap_irq_get_virq
+  regmap_mmio_detach_clk
+  regmap_multi_reg_write
+  regmap_multi_reg_write_bypassed
+  regmap_raw_read
+  regmap_raw_write
+  regmap_raw_write_async
+  regmap_read
+  regmap_register_patch
+  regmap_update_bits_base
+  regmap_write
+  regulator_allow_bypass
+  regulator_bulk_disable
+  regulator_bulk_enable
+  regulator_bulk_get
+  regulator_count_voltages
+  regulator_disable
+  regulator_disable_deferred
+  regulator_disable_regmap
+  regulator_enable
+  regulator_enable_regmap
+  regulator_force_disable
+  regulator_get
+  regulator_get_current_limit
+  regulator_get_drvdata
+  regulator_get_mode
+  regulator_get_optional
+  regulator_get_voltage
+  regulator_get_voltage_rdev
+  regulator_get_voltage_sel_regmap
+  regulator_is_enabled
+  regulator_is_enabled_regmap
+  regulator_is_supported_voltage
+  regulator_list_voltage_linear
+  regulator_list_voltage_linear_range
+  regulator_list_voltage_table
+  regulator_map_voltage_ascend
+  regulator_map_voltage_linear
+  regulator_notifier_call_chain
+  regulator_put
+  regulator_register
+  regulator_register_notifier
+  regulator_set_current_limit
+  regulator_set_load
+  regulator_set_mode
+  regulator_set_voltage
+  regulator_set_voltage_sel_regmap
+  regulator_unregister
+  regulator_unregister_notifier
+  release_firmware
+  release_pages
   __release_region
+  release_sock
+  remap_pfn_range
+  remap_vmalloc_range
+  remove_cpu
+  remove_memory_subsection
+  remove_proc_entry
+  remove_wait_queue
+  report_iommu_fault
+  request_any_context_irq
+  request_firmware
+  request_firmware_direct
+  request_firmware_into_buf
+  request_firmware_nowait
   __request_module
   __request_percpu_irq
   __request_region
+  request_threaded_irq
+  resched_curr
+  reservation_ww_class
+  reset_control_assert
+  reset_control_deassert
+  reset_control_put
+  reset_control_reset
+  resume_cpus
+  return_address
+  revalidate_disk_size
+  rfkill_alloc
+  rfkill_destroy
+  rfkill_find_type
+  rfkill_init_sw_state
+  rfkill_register
+  rfkill_set_sw_state
+  rfkill_unregister
+  rhashtable_destroy
+  rhashtable_init
+  rhashtable_insert_slow
   __rht_bucket_nested
+  rht_bucket_nested
+  rht_bucket_nested_insert
+  rndis_deregister
+  rndis_free_response
+  rndis_get_next_response
+  rndis_msg_parser
+  rndis_register
+  rndis_set_host_mac
+  rndis_set_param_dev
+  rndis_set_param_medium
+  rndis_set_param_vendor
+  rndis_signal_connect
+  rndis_uninit
+  root_task_group
+  round_jiffies_relative
+  round_jiffies_up
+  rpmsg_get_signals
+  rpmsg_poll
+  rpmsg_register_device
+  rpmsg_send
+  rpmsg_set_signals
+  rpmsg_trysend
+  rpmsg_unregister_device
+  rproc_add
+  rproc_add_subdev
+  rproc_alloc
+  rproc_boot
+  rproc_coredump_add_custom_segment
+  rproc_coredump_add_segment
+  rproc_coredump_set_elf_info
+  rproc_coredump_using_sections
+  rproc_del
+  rproc_elf_get_boot_addr
+  rproc_free
+  rproc_get_by_child
+  rproc_get_by_phandle
+  rproc_put
+  rproc_remove_subdev
+  rproc_report_crash
+  rproc_shutdown
+  rps_needed
+  rtc_class_close
+  rtc_class_open
+  rtc_read_time
   __rtc_register_device
+  rtc_set_time
+  rtc_time64_to_tm
+  rtc_tm_to_time64
+  rtc_update_irq
+  rtc_valid_tm
+  rtc_year_days
+  rt_mutex_lock
+  rt_mutex_trylock
+  rt_mutex_unlock
+  rtnl_is_locked
+  rtnl_link_register
+  rtnl_link_unregister
+  rtnl_lock
+  rtnl_register_module
+  rtnl_trylock
+  rtnl_unicast
+  rtnl_unlock
+  rtnl_unregister
+  runqueues
+  sb800_prefetch
+  sbitmap_queue_min_shallow_depth
+  sched_clock
+  sched_feat_keys
+  sched_feat_names
+  sched_setattr
+  sched_setattr_nocheck
+  sched_set_fifo
+  sched_set_fifo_low
+  sched_set_normal
+  sched_setscheduler
+  sched_setscheduler_nocheck
+  sched_show_task
+  sched_trace_cfs_rq_avg
+  sched_trace_cfs_rq_cpu
+  sched_trace_cfs_rq_path
+  sched_trace_rd_span
+  sched_trace_rq_avg_dl
+  sched_trace_rq_avg_irq
+  sched_trace_rq_avg_rt
+  sched_trace_rq_cpu
+  sched_uclamp_used
+  schedule
+  schedule_hrtimeout
+  schedule_timeout
+  schedule_timeout_interruptible
+  schedule_timeout_uninterruptible
+  scnprintf
+  scsi_autopm_get_device
+  scsi_autopm_put_device
+  scsi_block_requests
+  scsi_block_when_processing_errors
+  scsi_command_size_tbl
+  scsi_compat_ioctl
+  scsi_device_get
+  scsi_device_put
+  scsi_device_quiesce
+  scsi_dma_unmap
+  scsi_eh_ready_devs
   __scsi_execute
+  scsi_ioctl
+  scsi_ioctl_block_when_processing_errors
   __scsi_iterate_devices
+  scsi_normalize_sense
   __scsi_print_sense
+  scsi_print_sense_hdr
+  scsi_register_interface
+  scsi_remove_device
+  scsi_unblock_requests
+  sdev_prefix_printk
   __sdhci_add_host
+  sdhci_add_host
+  sdhci_cleanup_host
+  sdhci_cqe_disable
+  sdhci_cqe_enable
+  sdhci_cqe_irq
+  sdhci_enable_clk
+  sdhci_get_property
+  sdhci_pltfm_free
+  sdhci_pltfm_init
+  sdhci_remove_host
+  sdhci_reset
+  sdhci_set_bus_width
+  sdhci_set_power_noreg
+  sdhci_setup_host
+  sdio_claim_host
+  sdio_disable_func
+  sdio_enable_func
+  sdio_f0_readb
+  sdio_f0_writeb
+  sdio_get_host_pm_caps
+  sdio_memcpy_fromio
+  sdio_memcpy_toio
+  sdio_readsb
+  sdio_register_driver
+  sdio_release_host
+  sdio_set_block_size
+  sdio_set_host_pm_flags
+  sdio_signal_irq
+  sdio_unregister_driver
+  sdio_writesb
+  securityfs_create_dir
+  securityfs_create_file
+  securityfs_remove
+  send_sig_info
+  seq_buf_printf
+  seq_file_path
+  seq_hex_dump
+  seq_list_next
+  seq_list_start
+  seq_lseek
+  seq_open
   __seq_open_private
+  seq_printf
+  seq_putc
+  seq_puts
+  seq_read
+  seq_release
+  seq_release_private
+  seq_vprintf
+  seq_write
+  serdev_device_close
+  serdev_device_open
+  serdev_device_set_baudrate
+  serdev_device_set_flow_control
+  serdev_device_wait_until_sent
+  serdev_device_write
+  serdev_device_write_wakeup
+  serio_close
+  serio_interrupt
+  serio_open
+  serio_reconnect
   __serio_register_driver
   __serio_register_port
+  serio_rescan
+  serio_unregister_child_port
+  serio_unregister_driver
+  serio_unregister_port
+  set_blocksize
+  set_capacity_revalidate_and_notify
+  set_cpus_allowed_ptr
+  set_disk_ro
+  set_freezable
+  set_normalized_timespec64
+  set_page_dirty
+  set_page_dirty_lock
+  __SetPageMovable
+  set_task_cpu
+  set_user_nice
+  sg_alloc_table
+  sg_alloc_table_from_pages
+  sg_free_table
+  sg_init_one
+  sg_init_table
+  sgl_alloc
+  sgl_free
+  sg_miter_next
+  sg_miter_start
+  sg_miter_stop
+  sg_nents_for_len
+  sg_next
   __sg_page_iter_dma_next
   __sg_page_iter_next
   __sg_page_iter_start
+  sg_pcopy_from_buffer
+  sg_pcopy_to_buffer
+  sg_scsi_ioctl
+  sg_zero_buffer
+  shmem_truncate_range
+  show_rcu_gp_kthreads
+  show_regs
+  sigprocmask
+  si_mem_available
+  si_meminfo
+  simple_attr_open
+  simple_attr_read
+  simple_attr_release
+  simple_attr_write
+  simple_dir_inode_operations
+  simple_dir_operations
+  simple_open
+  simple_read_from_buffer
+  simple_statfs
+  simple_strtol
+  simple_strtoll
+  simple_strtoul
+  simple_strtoull
+  simple_write_to_buffer
+  single_open
+  single_open_size
+  single_release
+  si_swapinfo
+  sk_alloc
+  skb_add_rx_frag
+  skb_append_pagefrags
+  skb_checksum
+  skb_clone
+  skb_coalesce_rx_frag
+  skb_copy
+  skb_copy_bits
+  skb_copy_datagram_iter
+  skb_copy_expand
+  skb_copy_ubufs
+  skb_dequeue
+  skb_dequeue_tail
+  skb_ensure_writable
   __skb_ext_put
   __skb_flow_dissect
+  skb_free_datagram
   __skb_get_hash
   __skb_gso_segment
   __skb_pad
+  skb_page_frag_refill
+  skb_partial_csum_set
+  skb_pull
+  skb_push
+  skb_put
+  skb_queue_head
+  skb_queue_purge
+  skb_queue_tail
+  skb_realloc_headroom
+  skb_recv_datagram
+  skb_set_owner_w
+  skb_store_bits
+  skb_to_sgvec
+  skb_trim
+  skb_tstamp_tx
+  skb_unlink
+  sk_free
+  skip_spaces
+  smpboot_register_percpu_thread
+  smpboot_unregister_percpu_thread
+  smp_call_function
+  smp_call_function_any
+  smp_call_function_many
+  smp_call_function_single
+  smp_call_function_single_async
+  smp_call_on_cpu
+  snd_card_disconnect
+  snd_card_free
+  snd_card_new
+  snd_card_register
+  snd_card_rw_proc_new
+  snd_component_add
+  snd_compr_stop_error
+  snd_ctl_add
+  _snd_ctl_add_follower
+  snd_ctl_add_vmaster_hook
+  snd_ctl_apply_vmaster_followers
+  snd_ctl_boolean_mono_info
+  snd_ctl_boolean_stereo_info
+  snd_ctl_enum_info
+  snd_ctl_find_id
+  snd_ctl_make_virtual_master
+  snd_ctl_new1
+  snd_ctl_notify
+  snd_ctl_remove
+  snd_ctl_remove_id
+  snd_ctl_sync_vmaster
+  snd_device_disconnect
+  snd_device_free
+  snd_device_new
+  snd_dma_alloc_pages
+  snd_dmaengine_pcm_prepare_slave_config
+  snd_dma_free_pages
+  snd_hwdep_new
+  snd_info_create_card_entry
+  snd_info_create_module_entry
+  snd_info_free_entry
+  snd_info_register
+  snd_interval_refine
+  snd_jack_new
+  snd_jack_report
+  snd_jack_set_key
+  snd_pci_quirk_lookup
+  snd_pcm_add_chmap_ctls
+  snd_pcm_alt_chmaps
+  snd_pcm_create_iec958_consumer_hw_params
+  snd_pcm_format_physical_width
+  snd_pcm_format_width
+  snd_pcm_hw_constraint_eld
+  snd_pcm_hw_constraint_integer
+  snd_pcm_hw_constraint_list
+  snd_pcm_hw_constraint_minmax
+  snd_pcm_hw_constraint_msbits
+  snd_pcm_hw_constraint_step
+  snd_pcm_hw_limit_rates
+  snd_pcm_hw_rule_add
+  snd_pcm_lib_default_mmap
+  snd_pcm_lib_free_pages
+  snd_pcm_lib_ioctl
+  snd_pcm_lib_malloc_pages
+  snd_pcm_lib_preallocate_free_for_all
+  snd_pcm_lib_preallocate_pages
+  snd_pcm_new
+  snd_pcm_period_elapsed
+  snd_pcm_rate_range_to_bits
+  snd_pcm_set_managed_buffer_all
+  snd_pcm_set_ops
+  snd_pcm_set_sync
+  snd_pcm_std_chmaps
+  snd_pcm_stream_lock
+  _snd_pcm_stream_lock_irqsave
+  snd_pcm_stream_unlock
+  snd_pcm_stream_unlock_irqrestore
+  snd_soc_add_card_controls
+  snd_soc_add_component_controls
+  snd_soc_add_dai_controls
+  snd_soc_bytes_info_ext
+  snd_soc_bytes_tlv_callback
+  snd_soc_card_get_kcontrol
+  snd_soc_card_jack_new
+  snd_soc_component_async_complete
+  snd_soc_component_disable_pin
+  snd_soc_component_exit_regmap
+  snd_soc_component_force_enable_pin
+  snd_soc_component_init_regmap
+  snd_soc_component_read
+  snd_soc_component_set_jack
+  snd_soc_component_set_pll
+  snd_soc_component_set_sysclk
+  snd_soc_component_update_bits
+  snd_soc_component_update_bits_async
+  snd_soc_component_write
+  snd_soc_dai_get_channel_map
+  snd_soc_dai_link_set_capabilities
+  snd_soc_dai_set_bclk_ratio
+  snd_soc_dai_set_channel_map
+  snd_soc_dai_set_fmt
+  snd_soc_dai_set_pll
+  snd_soc_dai_set_sysclk
+  snd_soc_dai_set_tdm_slot
+  snd_soc_dapm_add_routes
+  snd_soc_dapm_disable_pin
+  snd_soc_dapm_disable_pin_unlocked
+  snd_soc_dapm_enable_pin
+  snd_soc_dapm_force_enable_pin
+  snd_soc_dapm_force_enable_pin_unlocked
+  snd_soc_dapm_get_enum_double
+  snd_soc_dapm_get_pin_status
+  snd_soc_dapm_get_pin_switch
+  snd_soc_dapm_get_volsw
+  snd_soc_dapm_ignore_suspend
+  snd_soc_dapm_info_pin_switch
+  snd_soc_dapm_kcontrol_dapm
+  snd_soc_dapm_kcontrol_widget
+  snd_soc_dapm_mixer_update_power
+  snd_soc_dapm_mux_update_power
+  snd_soc_dapm_new_control
+  snd_soc_dapm_new_controls
+  snd_soc_dapm_new_widgets
+  snd_soc_dapm_put_enum_double
+  snd_soc_dapm_put_pin_switch
+  snd_soc_dapm_put_volsw
+  snd_soc_dapm_sync
+  snd_soc_dapm_sync_unlocked
+  snd_soc_dapm_weak_routes
+  snd_soc_find_dai
+  snd_soc_get_enum_double
+  snd_soc_get_pcm_runtime
+  snd_soc_get_volsw
+  snd_soc_get_volsw_range
+  snd_soc_get_volsw_sx
+  snd_soc_get_xr_sx
+  snd_soc_info_enum_double
+  snd_soc_info_multi_ext
+  snd_soc_info_volsw
+  snd_soc_info_volsw_range
+  snd_soc_info_volsw_sx
+  snd_soc_info_xr_sx
+  snd_soc_jack_add_gpios
+  snd_soc_jack_report
+  snd_soc_lookup_component
+  snd_soc_new_compress
+  snd_soc_of_get_dai_link_codecs
+  snd_soc_of_get_dai_name
+  snd_soc_of_parse_audio_routing
+  snd_soc_of_parse_audio_simple_widgets
+  snd_soc_of_parse_aux_devs
+  snd_soc_of_parse_card_name
+  snd_soc_of_parse_daifmt
+  snd_soc_of_parse_node_prefix
+  snd_soc_of_parse_tdm_slot
+  snd_soc_of_put_dai_link_codecs
+  snd_soc_params_to_bclk
+  snd_soc_params_to_frame_size
+  snd_soc_pm_ops
+  snd_soc_put_enum_double
+  snd_soc_put_volsw
+  snd_soc_put_volsw_range
+  snd_soc_put_volsw_sx
+  snd_soc_put_xr_sx
+  snd_soc_register_card
+  snd_soc_register_component
+  snd_soc_rtdcom_lookup
+  snd_soc_runtime_calc_hw
+  snd_soc_runtime_set_dai_fmt
+  snd_soc_set_runtime_hwparams
+  snd_soc_tplg_component_load
+  snd_soc_tplg_component_remove
+  snd_soc_tplg_widget_bind_event
+  snd_soc_unregister_card
+  snd_soc_unregister_component
+  snd_usb_enable_audio_stream
+  snd_vendor_set_ops
+  snprintf
+  soc_device_register
+  soc_device_unregister
+  sock_alloc_send_skb
+  sock_create_kern
+  sock_gettstamp
+  sock_init_data
+  sock_i_uid
+  sock_no_accept
+  sock_no_listen
+  sock_no_mmap
+  sock_no_sendpage
+  sock_no_shutdown
+  sock_no_socketpair
+  sock_queue_rcv_skb
+  sock_register
+  sock_release
+  sock_setsockopt
+  sock_unregister
+  sock_wfree
+  softnet_data
+  sort
   __spi_alloc_controller
+  spi_bus_lock
+  spi_bus_type
+  spi_bus_unlock
+  spi_controller_resume
+  spi_controller_suspend
+  spi_delay_exec
+  spi_finalize_current_message
+  spi_finalize_current_transfer
+  spi_get_next_queued_message
+  spi_register_controller
   __spi_register_driver
+  spi_setup
+  spi_sync
+  spi_sync_locked
+  spi_unregister_controller
   __splice_from_pipe
+  split_page
+  spmi_controller_add
+  spmi_controller_alloc
+  spmi_controller_remove
   __spmi_driver_register
+  spmi_ext_register_read
+  spmi_ext_register_readl
+  spmi_ext_register_write
+  spmi_ext_register_writel
+  spmi_register_read
+  spmi_register_write
+  spmi_register_zero_write
+  sprintf
+  sprint_symbol
+  sprint_symbol_no_offset
+  srcu_barrier
+  srcu_batches_completed
+  srcu_init_notifier_head
+  srcu_notifier_call_chain
+  srcu_notifier_chain_register
+  srcu_notifier_chain_unregister
   __srcu_read_lock
   __srcu_read_unlock
+  srcutorture_get_gp_data
+  srcu_torture_stats_print
+  sscanf
   __stack_chk_fail
   __stack_chk_guard
+  stack_trace_print
+  stack_trace_save
+  stack_trace_save_regs
+  stack_trace_save_tsk
+  static_key_disable
+  static_key_disable_cpuslocked
+  static_key_slow_dec
+  static_key_slow_inc
+  stop_machine
+  stop_one_cpu_nowait
+  stpcpy
+  strcasecmp
+  strcat
+  strchr
+  strchrnul
+  strcmp
+  strcpy
+  strcspn
+  stream_open
+  strim
+  string_get_size
+  strlcat
+  strlcpy
+  strlen
+  strncasecmp
+  strncat
+  strnchr
+  strncmp
+  strncpy
+  strncpy_from_user
+  strndup_user
+  strnlen
+  strnstr
+  strpbrk
+  strrchr
+  strreplace
+  strscpy
+  strsep
+  strspn
+  strstr
+  submit_bh
+  submit_bio
+  submit_bio_wait
+  subsys_system_register
   __sw_hweight16
   __sw_hweight32
   __sw_hweight64
   __sw_hweight8
+  swiotlb_nr_tbl
+  sync_blockdev
+  sync_file_create
+  sync_file_get_fence
+  synchronize_irq
+  synchronize_net
+  synchronize_rcu
+  synchronize_rcu_expedited
+  synchronize_rcu_tasks
+  synchronize_rcu_tasks_trace
+  synchronize_srcu
+  synchronize_srcu_expedited
+  syscon_node_to_regmap
+  syscon_regmap_lookup_by_phandle
+  sysctl_sched_features
+  sysctl_sched_latency
+  sysctl_vals
+  sysfs_add_file_to_group
+  sysfs_add_link_to_group
+  sysfs_create_bin_file
+  sysfs_create_file_ns
+  sysfs_create_files
+  sysfs_create_group
+  sysfs_create_groups
+  sysfs_create_link
+  sysfs_emit
+  sysfs_emit_at
   __sysfs_match_string
+  sysfs_notify
+  sysfs_remove_bin_file
+  sysfs_remove_file_from_group
+  sysfs_remove_file_ns
+  sysfs_remove_files
+  sysfs_remove_group
+  sysfs_remove_groups
+  sysfs_remove_link
+  sysfs_remove_link_from_group
+  sysfs_streq
+  sysfs_update_group
+  sysrq_mask
+  system_freezable_wq
+  system_freezing_cnt
+  system_highpri_wq
+  system_long_wq
+  system_power_efficient_wq
+  system_state
+  system_unbound_wq
+  system_wq
+  sys_tz
+  task_active_pid_ns
+  task_groups
+  __tasklet_hi_schedule
+  tasklet_init
+  tasklet_kill
+  __tasklet_schedule
+  tasklet_setup
+  tasklist_lock
+  task_may_not_preempt
   __task_pid_nr_ns
   __task_rq_lock
-  __tasklet_hi_schedule
-  __tasklet_schedule
+  task_rq_lock
+  tcpci_get_tcpm_port
+  tcpci_irq
+  tcpci_register_port
+  tcpci_unregister_port
+  tcpm_cc_change
+  tcpm_is_toggling
+  tcpm_pd_hard_reset
+  tcpm_pd_receive
+  tcpm_pd_transmit_complete
+  tcpm_sink_frs
+  tcpm_sourcing_vbus
+  tcpm_update_sink_capabilities
+  tcpm_vbus_change
+  tcp_register_congestion_control
+  tcp_reno_cong_avoid
+  tcp_reno_ssthresh
+  tcp_reno_undo_cwnd
+  tcp_slow_start
+  tcp_unregister_congestion_control
+  thermal_cdev_update
+  thermal_cooling_device_register
+  thermal_cooling_device_unregister
+  thermal_of_cooling_device_register
+  thermal_pressure
+  thermal_zone_device_disable
+  thermal_zone_device_enable
+  thermal_zone_device_is_enabled
+  thermal_zone_device_register
+  thermal_zone_device_unregister
+  thermal_zone_device_update
+  thermal_zone_get_slope
+  thermal_zone_get_temp
+  thermal_zone_get_zone_by_name
+  thermal_zone_of_sensor_register
+  thermal_zone_of_sensor_unregister
+  thread_group_cputime_adjusted
+  tick_nohz_get_idle_calls_cpu
+  tick_nohz_get_sleep_length
+  time64_to_tm
+  timecounter_init
+  timecounter_read
+  timer_unstable_counter_workaround
+  topology_set_thermal_pressure
+  _totalram_pages
+  total_swapcache_pages
+  _trace_android_vh_record_pcpu_rwsem_starttime
   __trace_bprintk
   __trace_bputs
-  __trace_printk
+  trace_clock_local
+  trace_event_buffer_commit
+  trace_event_buffer_reserve
+  trace_event_ignore_this_pid
+  trace_event_raw_init
+  trace_event_reg
+  trace_handle_return
   __traceiter_android_rvh_account_irq
+  __traceiter_android_rvh_arm64_serror_panic
+  __traceiter_android_rvh_bad_mode
   __traceiter_android_rvh_build_perf_domains
   __traceiter_android_rvh_can_migrate_task
   __traceiter_android_rvh_check_preempt_wakeup
   __traceiter_android_rvh_cpu_cgroup_attach
   __traceiter_android_rvh_cpu_cgroup_can_attach
   __traceiter_android_rvh_cpu_cgroup_online
-  __traceiter_android_rvh_cpu_overutilized
   __traceiter_android_rvh_cpufreq_transition
+  __traceiter_android_rvh_cpu_overutilized
   __traceiter_android_rvh_dequeue_task
+  __traceiter_android_rvh_dequeue_task_idle
   __traceiter_android_rvh_die_kernel_fault
   __traceiter_android_rvh_do_mem_abort
+  __traceiter_android_rvh_do_sea
   __traceiter_android_rvh_do_sp_pc_abort
+  __traceiter_android_rvh_do_undefinstr
   __traceiter_android_rvh_enqueue_task
   __traceiter_android_rvh_find_busiest_queue
   __traceiter_android_rvh_find_energy_efficient_cpu
@@ -292,6 +3782,7 @@
   __traceiter_android_vh_binder_set_priority
   __traceiter_android_vh_binder_transaction_init
   __traceiter_android_vh_binder_wakeup_ilocked
+  __traceiter_android_vh_cgroup_attach
   __traceiter_android_vh_cma_alloc_finish
   __traceiter_android_vh_cma_alloc_start
   __traceiter_android_vh_cpu_idle_enter
@@ -313,10 +3804,19 @@
   __traceiter_android_vh_logbuf
   __traceiter_android_vh_logbuf_pr_cont
   __traceiter_android_vh_meminfo_proc_show
+  __traceiter_android_vh_mutex_wait_finish
+  __traceiter_android_vh_mutex_wait_start
   __traceiter_android_vh_pagecache_get_page
   __traceiter_android_vh_printk_hotplug
   __traceiter_android_vh_ptype_head
   __traceiter_android_vh_rmqueue
+  __traceiter_android_vh_rtmutex_wait_finish
+  __traceiter_android_vh_rtmutex_wait_start
+  __traceiter_android_vh_rwsem_read_wait_finish
+  __traceiter_android_vh_rwsem_read_wait_start
+  __traceiter_android_vh_rwsem_write_wait_finish
+  __traceiter_android_vh_rwsem_write_wait_start
+  __traceiter_android_vh_sched_show_task
   __traceiter_android_vh_scheduler_tick
   __traceiter_android_vh_show_max_freq
   __traceiter_android_vh_show_mem
@@ -324,6 +3824,8 @@
   __traceiter_android_vh_show_suspend_epoch_val
   __traceiter_android_vh_timer_calc_index
   __traceiter_android_vh_timerfd_create
+  __traceiter_android_vh_try_to_freeze_todo
+  __traceiter_android_vh_try_to_freeze_todo_unfrozen
   __traceiter_android_vh_typec_store_partner_src_caps
   __traceiter_android_vh_typec_tcpci_override_toggling
   __traceiter_android_vh_typec_tcpm_adj_current_limit
@@ -337,15 +3839,46 @@
   __traceiter_android_vh_ufs_send_uic_command
   __traceiter_android_vh_ufs_update_sdev
   __traceiter_android_vh_ufs_update_sysfs
+  __traceiter_android_vh_watchdog_timer_softlockup
+  __traceiter_android_vh_wq_lockup_pool
+  __traceiter_binder_transaction_received
   __traceiter_clock_set_rate
   __traceiter_cpu_frequency
+  __traceiter_cpu_frequency_limits
+  __traceiter_cpu_idle
+  __traceiter_device_pm_callback_end
+  __traceiter_device_pm_callback_start
   __traceiter_dma_fence_emit
+  __traceiter_dwc3_ep_queue
   __traceiter_dwc3_readl
   __traceiter_dwc3_writel
   __traceiter_gpu_mem_total
+  __traceiter_hrtimer_expire_entry
+  __traceiter_hrtimer_expire_exit
+  __traceiter_ipi_entry
+  __traceiter_ipi_exit
+  __traceiter_ipi_raise
+  __traceiter_irq_handler_entry
+  __traceiter_irq_handler_exit
   __traceiter_kfree_skb
+  __traceiter_pelt_cfs_tp
+  __traceiter_pelt_dl_tp
+  __traceiter_pelt_irq_tp
+  __traceiter_pelt_rt_tp
+  __traceiter_pelt_se_tp
+  __traceiter_rwmmio_post_read
+  __traceiter_rwmmio_read
+  __traceiter_rwmmio_write
+  __traceiter_sched_cpu_capacity_tp
+  __traceiter_sched_overutilized_tp
+  __traceiter_sched_switch
+  __traceiter_sched_util_est_cfs_tp
   __traceiter_sched_util_est_se_tp
+  __traceiter_suspend_resume
+  __traceiter_workqueue_execute_end
+  __traceiter_workqueue_execute_start
   __traceiter_xdp_exception
+  trace_output_call
   __tracepoint_android_rvh_account_irq
   __tracepoint_android_rvh_arm64_serror_panic
   __tracepoint_android_rvh_bad_mode
@@ -355,8 +3888,8 @@
   __tracepoint_android_rvh_cpu_cgroup_attach
   __tracepoint_android_rvh_cpu_cgroup_can_attach
   __tracepoint_android_rvh_cpu_cgroup_online
-  __tracepoint_android_rvh_cpu_overutilized
   __tracepoint_android_rvh_cpufreq_transition
+  __tracepoint_android_rvh_cpu_overutilized
   __tracepoint_android_rvh_dequeue_task
   __tracepoint_android_rvh_dequeue_task_idle
   __tracepoint_android_rvh_die_kernel_fault
@@ -501,6 +4034,9 @@
   __tracepoint_pelt_irq_tp
   __tracepoint_pelt_rt_tp
   __tracepoint_pelt_se_tp
+  tracepoint_probe_register
+  tracepoint_probe_register_prio
+  tracepoint_probe_unregister
   __tracepoint_rwmmio_post_read
   __tracepoint_rwmmio_read
   __tracepoint_rwmmio_write
@@ -513,3523 +4049,14 @@
   __tracepoint_workqueue_execute_end
   __tracepoint_workqueue_execute_start
   __tracepoint_xdp_exception
-  __tty_alloc_driver
-  __tty_insert_flip_char
-  __udelay
-  __uio_register_device
-  __unregister_chrdev
-  __update_load_avg_blocked_se
-  __usb_create_hcd
-  __usb_get_extra_descriptor
-  __usecs_to_jiffies
-  __v4l2_device_register_subdev_nodes
-  __video_register_device
-  __wait_rcu_gp
-  __wake_up
-  __wake_up_locked
-  __wake_up_locked_key
-  __wake_up_sync
-  __warn_printk
-  __xa_alloc
-  __xa_insert
-  __xfrm_state_destroy
-  _atomic_dec_and_lock
-  _copy_from_iter
-  _copy_from_iter_full
-  _copy_to_iter
-  _ctype
-  _dev_alert
-  _dev_crit
-  _dev_emerg
-  _dev_err
-  _dev_info
-  _dev_notice
-  _dev_warn
-  _raw_read_lock
-  _raw_read_lock_bh
-  _raw_read_lock_irq
-  _raw_read_lock_irqsave
-  _raw_read_unlock
-  _raw_read_unlock_bh
-  _raw_read_unlock_irq
-  _raw_read_unlock_irqrestore
-  _raw_spin_lock
-  _raw_spin_lock_bh
-  _raw_spin_lock_irq
-  _raw_spin_lock_irqsave
-  _raw_spin_trylock
-  _raw_spin_trylock_bh
-  _raw_spin_unlock
-  _raw_spin_unlock_bh
-  _raw_spin_unlock_irq
-  _raw_spin_unlock_irqrestore
-  _raw_write_lock
-  _raw_write_lock_bh
-  _raw_write_lock_irq
-  _raw_write_lock_irqsave
-  _raw_write_unlock
-  _raw_write_unlock_bh
-  _raw_write_unlock_irq
-  _raw_write_unlock_irqrestore
-  _snd_ctl_add_follower
-  _snd_pcm_stream_lock_irqsave
-  _totalram_pages
-  _trace_android_vh_record_pcpu_rwsem_starttime
-  access_process_vm
-  ack_all_badblocks
-  activate_task
-  add_cpu
-  add_device_randomness
-  add_memory
-  add_memory_subsection
-  add_taint
-  add_timer
-  add_timer_on
-  add_uevent_var
-  add_wait_queue
-  adjust_managed_page_count
-  alarm_cancel
-  alarm_init
-  alarm_start
-  alarm_start_relative
-  alarm_try_to_cancel
-  alarmtimer_get_rtcdev
-  all_vm_events
-  alloc_anon_inode
-  alloc_chrdev_region
-  alloc_etherdev_mqs
-  alloc_io_pgtable_ops
-  alloc_netdev_mqs
-  alloc_page_buffers
-  alloc_pages_exact
-  alloc_skb_with_frags
-  alloc_workqueue
-  amba_bustype
-  amba_driver_register
-  amba_driver_unregister
-  amba_release_regions
-  amba_request_regions
-  android_debug_per_cpu_symbol
-  android_debug_symbol
-  android_rvh_probe_register
-  anon_inode_getfd
-  anon_inode_getfile
-  arch_timer_read_counter
-  argv_free
-  argv_split
-  arm64_const_caps_ready
-  arm64_use_ng_mappings
-  async_schedule_node
-  async_schedule_node_domain
-  async_synchronize_full_domain
-  atomic_notifier_call_chain
-  atomic_notifier_chain_register
-  atomic_notifier_chain_unregister
-  autoremove_wake_function
-  available_idle_cpu
-  backlight_device_get_by_type
-  backlight_device_register
-  backlight_device_set_brightness
-  backlight_device_unregister
-  badblocks_clear
-  badblocks_exit
-  badblocks_init
-  badblocks_set
-  badblocks_show
-  badblocks_store
-  balloon_aops
-  balloon_page_alloc
-  balloon_page_dequeue
-  balloon_page_enqueue
-  bcmp
-  bd_link_disk_holder
-  bd_set_nr_sectors
-  bd_unlink_disk_holder
-  bdev_check_media_change
-  bdev_read_only
-  bdevname
-  bdget_disk
-  bdput
-  bgpio_init
-  bin2hex
-  bio_add_page
-  bio_alloc_bioset
-  bio_associate_blkg
-  bio_chain
-  bio_clone_blkg_association
-  bio_endio
-  bio_init
-  bio_put
-  bioset_exit
-  bioset_init
-  bitmap_allocate_region
-  bitmap_find_next_zero_area_off
-  bitmap_from_arr32
-  bitmap_parse
-  bitmap_parselist
-  bitmap_parselist_user
-  bitmap_print_to_pagebuf
-  bitmap_release_region
-  bitmap_to_arr32
-  bitmap_zalloc
-  blk_alloc_queue
-  blk_cleanup_queue
-  blk_execute_rq
-  blk_execute_rq_nowait
-  blk_finish_plug
-  blk_freeze_queue_start
-  blk_get_queue
-  blk_get_request
-  blk_mq_alloc_request
-  blk_mq_alloc_request_hctx
-  blk_mq_alloc_tag_set
-  blk_mq_complete_request
-  blk_mq_complete_request_remote
-  blk_mq_debugfs_rq_show
-  blk_mq_delay_kick_requeue_list
-  blk_mq_end_request
-  blk_mq_free_request
-  blk_mq_free_tag_set
-  blk_mq_freeze_queue
-  blk_mq_freeze_queue_wait
-  blk_mq_freeze_queue_wait_timeout
-  blk_mq_init_queue
-  blk_mq_map_queues
-  blk_mq_pci_map_queues
-  blk_mq_quiesce_queue
-  blk_mq_requeue_request
-  blk_mq_rq_cpu
-  blk_mq_run_hw_queues
-  blk_mq_sched_request_inserted
-  blk_mq_sched_try_insert_merge
-  blk_mq_sched_try_merge
-  blk_mq_start_request
-  blk_mq_start_stopped_hw_queues
-  blk_mq_stop_hw_queue
-  blk_mq_tag_to_rq
-  blk_mq_tagset_busy_iter
-  blk_mq_tagset_wait_completed_request
-  blk_mq_unfreeze_queue
-  blk_mq_unique_tag
-  blk_mq_unquiesce_queue
-  blk_mq_update_nr_hw_queues
-  blk_mq_virtio_map_queues
-  blk_poll
-  blk_put_queue
-  blk_put_request
-  blk_queue_alignment_offset
-  blk_queue_bounce_limit
-  blk_queue_can_use_dma_map_merging
-  blk_queue_chunk_sectors
-  blk_queue_dma_alignment
-  blk_queue_flag_clear
-  blk_queue_flag_set
-  blk_queue_flag_test_and_set
-  blk_queue_io_min
-  blk_queue_io_opt
-  blk_queue_logical_block_size
-  blk_queue_max_discard_sectors
-  blk_queue_max_discard_segments
-  blk_queue_max_hw_sectors
-  blk_queue_max_segment_size
-  blk_queue_max_segments
-  blk_queue_max_write_zeroes_sectors
-  blk_queue_physical_block_size
-  blk_queue_rq_timeout
-  blk_queue_split
-  blk_queue_virt_boundary
-  blk_queue_write_cache
-  blk_register_region
-  blk_rq_map_kern
-  blk_rq_map_user
-  blk_rq_map_user_iov
-  blk_rq_unmap_user
-  blk_set_queue_dying
-  blk_set_stacking_limits
-  blk_start_plug
-  blk_status_to_errno
-  blk_sync_queue
-  blk_unregister_region
-  blk_update_request
-  blk_verify_command
-  blkcg_activate_policy
-  blkcg_deactivate_policy
-  blkcg_policy_register
-  blkcg_policy_unregister
-  blkcg_root
-  blkdev_fsync
-  blkdev_get_by_dev
-  blkdev_get_by_path
-  blkdev_issue_flush
-  blkdev_put
-  blkg_lookup_slowpath
-  blocking_notifier_call_chain
-  blocking_notifier_chain_register
-  blocking_notifier_chain_unregister
-  bmap
-  bpf_dispatcher_xdp_func
-  bpf_prog_add
-  bpf_prog_put
-  bpf_prog_sub
-  bpf_stats_enabled_key
-  bpf_trace_run1
-  bpf_trace_run10
-  bpf_trace_run11
-  bpf_trace_run12
-  bpf_trace_run2
-  bpf_trace_run3
-  bpf_trace_run4
-  bpf_trace_run5
-  bpf_trace_run6
-  bpf_trace_run7
-  bpf_trace_run8
-  bpf_trace_run9
-  bpf_warn_invalid_xdp_action
-  bsearch
-  bt_err
-  bt_info
-  build_skb
-  bus_find_device
-  bus_for_each_dev
-  bus_for_each_drv
-  bus_register
-  bus_register_notifier
-  bus_set_iommu
-  bus_unregister
-  bus_unregister_notifier
-  cache_line_size
-  call_netdevice_notifiers
-  call_rcu
-  call_rcu_tasks
-  call_rcu_tasks_trace
-  call_srcu
-  cancel_delayed_work
-  cancel_delayed_work_sync
-  cancel_work_sync
-  capable
-  cdc_ncm_bind_common
-  cdc_ncm_change_mtu
-  cdc_ncm_fill_tx_frame
-  cdc_ncm_rx_verify_ndp16
-  cdc_ncm_rx_verify_nth16
-  cdc_ncm_select_altsetting
-  cdc_ncm_unbind
-  cdc_parse_cdc_header
-  cdev_add
-  cdev_alloc
-  cdev_del
-  cdev_device_add
-  cdev_device_del
-  cdev_init
-  cec_allocate_adapter
-  cec_delete_adapter
-  cec_received_msg_ts
-  cec_register_adapter
-  cec_s_log_addrs
-  cec_s_phys_addr
-  cec_s_phys_addr_from_edid
-  cec_transmit_attempt_done_ts
-  cec_transmit_done_ts
-  cec_unregister_adapter
-  cgroup_path_ns
-  cgroup_taskset_first
-  cgroup_taskset_next
-  check_preempt_curr
-  check_zeroed_user
-  class_create_file_ns
-  class_destroy
-  class_find_device
-  class_for_each_device
-  class_interface_unregister
-  class_remove_file_ns
-  class_unregister
-  cleancache_register_ops
-  cleanup_srcu_struct
-  clear_page
-  clk_bulk_disable
-  clk_bulk_enable
-  clk_bulk_get_all
-  clk_bulk_prepare
-  clk_bulk_put_all
-  clk_bulk_unprepare
-  clk_disable
-  clk_enable
-  clk_fixed_factor_ops
-  clk_fixed_rate_ops
-  clk_get
-  clk_get_parent
-  clk_get_rate
-  clk_hw_get_flags
-  clk_hw_get_name
-  clk_hw_get_num_parents
-  clk_hw_get_parent
-  clk_hw_get_parent_by_index
-  clk_hw_get_rate
-  clk_hw_is_enabled
-  clk_hw_is_prepared
-  clk_hw_register
-  clk_hw_register_fixed_factor
-  clk_hw_round_rate
-  clk_hw_set_rate_range
-  clk_hw_unregister
-  clk_hw_unregister_divider
-  clk_hw_unregister_fixed_factor
-  clk_hw_unregister_gate
-  clk_hw_unregister_mux
-  clk_notifier_register
-  clk_notifier_unregister
-  clk_prepare
-  clk_put
-  clk_register
-  clk_register_clkdev
-  clk_register_fixed_factor
-  clk_register_fixed_rate
-  clk_register_gate
-  clk_round_rate
-  clk_set_parent
-  clk_set_rate
-  clk_sync_state
-  clk_unprepare
-  clk_unregister
-  clockevents_config_and_register
-  clocks_calc_mult_shift
-  cma_alloc
-  cma_for_each_area
-  cma_get_name
-  cma_release
-  compat_alloc_user_space
-  compat_only_sysfs_link_entry_to_kobj
-  compat_ptr_ioctl
-  complete
-  complete_all
-  complete_and_exit
-  completion_done
-  component_add
-  component_bind_all
-  component_del
-  component_master_add_with_match
-  component_master_del
-  component_match_add_release
-  component_unbind_all
-  cond_synchronize_rcu
-  config_ep_by_speed
-  config_group_init
-  config_group_init_type_name
-  config_item_get
-  config_item_put
-  configfs_register_subsystem
-  configfs_unregister_subsystem
-  console_drivers
-  console_printk
-  console_stop
-  console_suspend_enabled
-  console_trylock
-  console_unlock
-  consume_skb
-  contig_page_data
-  copy_from_kernel_nofault
-  copy_page
-  cpu_all_bits
-  cpu_bit_bitmap
-  cpu_hotplug_disable
-  cpu_hotplug_enable
-  cpu_hwcap_keys
-  cpu_hwcaps
-  cpu_irqtime
-  cpu_is_hotpluggable
-  cpu_latency_qos_add_request
-  cpu_latency_qos_remove_request
-  cpu_latency_qos_request_active
-  cpu_latency_qos_update_request
-  cpu_number
-  cpu_pm_register_notifier
-  cpu_pm_unregister_notifier
-  cpu_scale
-  cpu_subsys
-  cpu_topology
-  cpufreq_add_update_util_hook
-  cpufreq_cpu_get
-  cpufreq_cpu_get_raw
-  cpufreq_cpu_put
-  cpufreq_disable_fast_switch
-  cpufreq_driver_fast_switch
-  cpufreq_driver_resolve_freq
-  cpufreq_enable_boost_support
-  cpufreq_enable_fast_switch
-  cpufreq_freq_attr_scaling_available_freqs
-  cpufreq_freq_attr_scaling_boost_freqs
-  cpufreq_freq_transition_begin
-  cpufreq_freq_transition_end
-  cpufreq_frequency_table_verify
-  cpufreq_generic_attr
-  cpufreq_generic_frequency_table_verify
-  cpufreq_generic_get
-  cpufreq_generic_suspend
-  cpufreq_get_driver_data
-  cpufreq_get_policy
-  cpufreq_policy_transition_delay_us
-  cpufreq_quick_get
-  cpufreq_quick_get_max
-  cpufreq_register_driver
-  cpufreq_register_governor
-  cpufreq_register_notifier
-  cpufreq_remove_update_util_hook
-  cpufreq_table_index_unsorted
-  cpufreq_this_cpu_can_update
-  cpufreq_unregister_driver
-  cpufreq_unregister_notifier
-  cpufreq_update_policy
-  cpuhp_tasks_frozen
-  cpuidle_governor_latency_req
-  cpuidle_register_governor
-  cpumask_any_but
-  cpumask_next
-  cpumask_next_and
-  cpumask_next_wrap
-  cpupri_find_fitness
-  cpus_read_lock
-  cpus_read_unlock
-  crc16
-  crc32_le
-  crc8
-  crc8_populate_msb
-  create_function_device
-  crypto_aead_encrypt
-  crypto_aead_setauthsize
-  crypto_aead_setkey
-  crypto_alloc_aead
-  crypto_alloc_base
-  crypto_alloc_shash
-  crypto_alloc_skcipher
-  crypto_cipher_encrypt_one
-  crypto_cipher_setkey
-  crypto_comp_compress
-  crypto_comp_decompress
-  crypto_destroy_tfm
-  crypto_has_alg
-  crypto_register_alg
-  crypto_register_rngs
-  crypto_register_scomp
-  crypto_shash_digest
-  crypto_shash_final
-  crypto_shash_setkey
-  crypto_shash_update
-  crypto_skcipher_decrypt
-  crypto_skcipher_encrypt
-  crypto_skcipher_setkey
-  crypto_unregister_alg
-  crypto_unregister_rngs
-  crypto_unregister_scomp
-  css_next_child
-  css_next_descendant_pre
-  csum_ipv6_magic
-  csum_partial
-  csum_tcpudp_nofold
-  current_time
-  current_work
-  d_add
-  d_alloc_name
-  d_delete
-  d_make_root
-  d_path
-  dapm_pinctrl_event
-  dapm_regulator_event
-  datagram_poll
-  deactivate_task
-  debugfs_attr_read
-  debugfs_attr_write
-  debugfs_create_atomic_t
-  debugfs_create_blob
-  debugfs_create_bool
-  debugfs_create_dir
-  debugfs_create_file
-  debugfs_create_file_unsafe
-  debugfs_create_regset32
-  debugfs_create_size_t
-  debugfs_create_symlink
-  debugfs_create_u16
-  debugfs_create_u32
-  debugfs_create_u64
-  debugfs_create_u8
-  debugfs_create_ulong
-  debugfs_create_x32
-  debugfs_create_x64
-  debugfs_create_x8
-  debugfs_file_get
-  debugfs_file_put
-  debugfs_lookup
-  debugfs_print_regs32
-  debugfs_remove
-  dec_zone_page_state
-  default_llseek
-  deferred_free
-  del_gendisk
-  del_timer
-  del_timer_sync
-  delayed_work_timer_fn
-  desc_to_gpio
-  destroy_workqueue
-  dev_alloc_name
-  dev_close
-  dev_coredumpm
-  dev_coredumpv
-  dev_driver_string
-  dev_err_probe
-  dev_fwnode
-  dev_get_by_index
-  dev_get_by_name
-  dev_get_regmap
-  dev_get_stats
-  dev_mc_sync_multiple
-  dev_mc_unsync
-  dev_open
-  dev_pm_clear_wake_irq
-  dev_pm_domain_attach
-  dev_pm_domain_attach_by_name
-  dev_pm_domain_detach
-  dev_pm_genpd_add_notifier
-  dev_pm_genpd_remove_notifier
-  dev_pm_genpd_set_next_wakeup
-  dev_pm_genpd_set_performance_state
-  dev_pm_opp_add
-  dev_pm_opp_adjust_voltage
-  dev_pm_opp_disable
-  dev_pm_opp_enable
-  dev_pm_opp_find_freq_ceil
-  dev_pm_opp_find_freq_ceil_by_volt
-  dev_pm_opp_find_freq_exact
-  dev_pm_opp_find_freq_floor
-  dev_pm_opp_free_cpufreq_table
-  dev_pm_opp_get_freq
-  dev_pm_opp_get_level
-  dev_pm_opp_get_max_transition_latency
-  dev_pm_opp_get_opp_count
-  dev_pm_opp_get_opp_table
-  dev_pm_opp_get_sharing_cpus
-  dev_pm_opp_get_suspend_opp_freq
-  dev_pm_opp_get_voltage
-  dev_pm_opp_init_cpufreq_table
-  dev_pm_opp_of_add_table
-  dev_pm_opp_of_cpumask_add_table
-  dev_pm_opp_of_cpumask_remove_table
-  dev_pm_opp_of_find_icc_paths
-  dev_pm_opp_of_get_sharing_cpus
-  dev_pm_opp_of_register_em
-  dev_pm_opp_of_remove_table
-  dev_pm_opp_put
-  dev_pm_opp_put_clkname
-  dev_pm_opp_put_opp_table
-  dev_pm_opp_put_regulators
-  dev_pm_opp_register_notifier
-  dev_pm_opp_remove_all_dynamic
-  dev_pm_opp_set_bw
-  dev_pm_opp_set_clkname
-  dev_pm_opp_set_rate
-  dev_pm_opp_set_regulators
-  dev_pm_opp_set_sharing_cpus
-  dev_pm_opp_set_supported_hw
-  dev_pm_opp_unregister_notifier
-  dev_pm_qos_add_notifier
-  dev_pm_qos_add_request
-  dev_pm_qos_expose_latency_tolerance
-  dev_pm_qos_hide_latency_tolerance
-  dev_pm_qos_read_value
-  dev_pm_qos_remove_notifier
-  dev_pm_qos_remove_request
-  dev_pm_qos_update_request
-  dev_pm_qos_update_user_latency_tolerance
-  dev_pm_set_dedicated_wake_irq
-  dev_printk
-  dev_printk_emit
-  dev_queue_xmit
-  dev_set_mtu
-  dev_set_name
-  dev_uc_sync_multiple
-  dev_uc_unsync
-  devfreq_add_device
-  devfreq_add_governor
-  devfreq_cooling_unregister
-  devfreq_get_devfreq_by_phandle
-  devfreq_monitor_resume
-  devfreq_monitor_start
-  devfreq_monitor_stop
-  devfreq_monitor_suspend
-  devfreq_recommended_opp
-  devfreq_register_opp_notifier
-  devfreq_remove_device
-  devfreq_remove_governor
-  devfreq_resume_device
-  devfreq_suspend_device
-  devfreq_unregister_opp_notifier
-  devfreq_update_interval
-  device_add
-  device_add_disk
-  device_add_groups
-  device_attach
-  device_bind_driver
-  device_create
-  device_create_bin_file
-  device_create_file
-  device_create_with_groups
-  device_del
-  device_destroy
-  device_find_child
-  device_for_each_child
-  device_get_child_node_count
-  device_get_dma_attr
-  device_get_mac_address
-  device_get_match_data
-  device_get_named_child_node
-  device_get_next_child_node
-  device_init_wakeup
-  device_initialize
-  device_link_add
-  device_link_del
-  device_match_fwnode
-  device_match_name
-  device_match_of_node
-  device_property_present
-  device_property_read_string
-  device_property_read_string_array
-  device_property_read_u16_array
-  device_property_read_u32_array
-  device_property_read_u8_array
-  device_register
-  device_release_driver
-  device_remove_bin_file
-  device_remove_file
-  device_remove_file_self
-  device_remove_groups
-  device_set_wakeup_capable
-  device_set_wakeup_enable
-  device_show_bool
-  device_show_int
-  device_store_bool
-  device_store_int
-  device_unregister
-  device_wakeup_disable
-  device_wakeup_enable
-  devm_add_action
-  devm_backlight_device_register
-  devm_backlight_device_unregister
-  devm_blk_ksm_init
-  devm_clk_bulk_get
-  devm_clk_bulk_get_all
-  devm_clk_bulk_get_optional
-  devm_clk_get
-  devm_clk_get_optional
-  devm_clk_hw_register
-  devm_clk_hw_register_clkdev
-  devm_clk_put
-  devm_clk_register
-  devm_devfreq_add_device
-  devm_devfreq_register_notifier
-  devm_devfreq_unregister_notifier
-  devm_device_add_group
-  devm_device_add_groups
-  devm_device_remove_group
-  devm_drm_panel_bridge_add_typed
-  devm_extcon_dev_allocate
-  devm_extcon_dev_register
-  devm_extcon_dev_unregister
-  devm_extcon_register_notifier
-  devm_free_irq
-  devm_free_percpu
-  devm_gen_pool_create
-  devm_get_clk_from_child
-  devm_gpio_free
-  devm_gpio_request
-  devm_gpio_request_one
-  devm_gpiochip_add_data_with_key
-  devm_gpiod_get
-  devm_gpiod_get_array
-  devm_gpiod_get_index
-  devm_gpiod_get_optional
-  devm_gpiod_put_array
-  devm_hwrng_register
-  devm_hwspin_lock_register
-  devm_i2c_new_dummy_device
-  devm_iio_channel_get
-  devm_iio_device_alloc
-  devm_input_allocate_device
-  devm_ioremap
-  devm_ioremap_resource
-  devm_ioremap_wc
-  devm_iounmap
-  devm_kasprintf
-  devm_kfree
-  devm_kmalloc
-  devm_kmemdup
-  devm_kstrdup
-  devm_kstrdup_const
-  devm_kvasprintf
-  devm_led_classdev_register_ext
-  devm_mbox_controller_register
-  devm_memremap
-  devm_mfd_add_devices
-  devm_nvmem_cell_get
-  devm_nvmem_device_get
-  devm_nvmem_register
-  devm_of_clk_add_hw_provider
-  devm_of_icc_get
-  devm_of_iomap
-  devm_of_platform_populate
-  devm_of_pwm_get
-  devm_pci_alloc_host_bridge
-  devm_phy_create
-  devm_phy_get
-  devm_phy_put
-  devm_pinctrl_get
-  devm_pinctrl_put
-  devm_pinctrl_register
-  devm_pinctrl_register_and_init
-  devm_platform_get_and_ioremap_resource
-  devm_platform_ioremap_resource
-  devm_platform_ioremap_resource_byname
-  devm_power_supply_register
-  devm_pwm_put
-  devm_regmap_add_irq_chip
-  devm_regmap_del_irq_chip
-  devm_regmap_field_alloc
-  devm_regulator_bulk_get
-  devm_regulator_get
-  devm_regulator_get_exclusive
-  devm_regulator_get_optional
-  devm_regulator_put
-  devm_regulator_register
-  devm_regulator_register_notifier
-  devm_request_any_context_irq
-  devm_request_threaded_irq
-  devm_reset_control_array_get
-  devm_reset_controller_register
-  devm_rtc_allocate_device
-  devm_rtc_device_register
-  devm_snd_dmaengine_pcm_register
-  devm_snd_soc_register_card
-  devm_snd_soc_register_component
-  devm_spi_register_controller
-  devm_thermal_of_cooling_device_register
-  devm_thermal_zone_of_sensor_register
-  devm_thermal_zone_of_sensor_unregister
-  devm_usb_get_phy
-  devm_usb_get_phy_by_node
-  devm_usb_get_phy_by_phandle
-  devm_watchdog_register_device
-  devres_add
-  devres_alloc_node
-  devres_free
-  devres_release
-  disable_irq
-  disable_irq_nosync
-  disable_percpu_irq
-  disk_end_io_acct
-  disk_start_io_acct
-  divider_get_val
-  divider_recalc_rate
-  divider_ro_round_rate_parent
-  divider_round_rate_parent
-  dma_alloc_attrs
-  dma_async_device_register
-  dma_async_device_unregister
-  dma_async_tx_descriptor_init
-  dma_buf_attach
-  dma_buf_begin_cpu_access
-  dma_buf_begin_cpu_access_partial
-  dma_buf_detach
-  dma_buf_dynamic_attach
-  dma_buf_end_cpu_access
-  dma_buf_end_cpu_access_partial
-  dma_buf_export
-  dma_buf_fd
-  dma_buf_get
-  dma_buf_get_flags
-  dma_buf_map_attachment
-  dma_buf_mmap
-  dma_buf_move_notify
-  dma_buf_pin
-  dma_buf_put
-  dma_buf_unmap_attachment
-  dma_buf_unpin
-  dma_buf_vmap
-  dma_buf_vunmap
-  dma_contiguous_default_area
-  dma_fence_add_callback
-  dma_fence_array_create
-  dma_fence_array_ops
-  dma_fence_context_alloc
-  dma_fence_default_wait
-  dma_fence_enable_sw_signaling
-  dma_fence_free
-  dma_fence_get_status
-  dma_fence_get_stub
-  dma_fence_init
-  dma_fence_match_context
-  dma_fence_release
-  dma_fence_remove_callback
-  dma_fence_signal
-  dma_fence_signal_locked
-  dma_fence_wait_any_timeout
-  dma_fence_wait_timeout
-  dma_free_attrs
-  dma_get_merge_boundary
-  dma_get_required_mask
-  dma_get_sgtable_attrs
-  dma_get_slave_caps
-  dma_get_slave_channel
-  dma_heap_add
-  dma_heap_buffer_alloc
-  dma_heap_buffer_free
-  dma_heap_find
-  dma_heap_get_dev
-  dma_heap_get_drvdata
-  dma_heap_get_name
-  dma_heap_put
-  dma_map_page_attrs
-  dma_map_resource
-  dma_map_sg_attrs
-  dma_max_mapping_size
-  dma_mmap_attrs
-  dma_pool_alloc
-  dma_pool_create
-  dma_pool_destroy
-  dma_pool_free
-  dma_release_channel
-  dma_request_chan
-  dma_resv_add_excl_fence
-  dma_resv_add_shared_fence
-  dma_resv_fini
-  dma_resv_get_fences_rcu
-  dma_resv_init
-  dma_resv_reserve_shared
-  dma_resv_test_signaled_rcu
-  dma_resv_wait_timeout_rcu
-  dma_set_coherent_mask
-  dma_set_mask
-  dma_sync_sg_for_cpu
-  dma_sync_sg_for_device
-  dma_sync_single_for_cpu
-  dma_sync_single_for_device
-  dma_unmap_page_attrs
-  dma_unmap_resource
-  dma_unmap_sg_attrs
-  dmabuf_page_pool_alloc
-  dmabuf_page_pool_create
-  dmabuf_page_pool_destroy
-  dmabuf_page_pool_free
-  dmaengine_unmap_put
-  dmam_alloc_attrs
-  dmam_free_coherent
-  dmam_pool_create
-  do_SAK
-  do_exit
-  do_trace_rcu_torture_read
-  do_wait_intr
-  do_wait_intr_irq
-  down
-  down_interruptible
-  down_read
-  down_read_killable
-  down_read_trylock
-  down_timeout
-  down_trylock
-  down_write
-  downgrade_write
-  dput
-  drain_workqueue
-  driver_attach
-  driver_create_file
-  driver_find_device
-  driver_register
-  driver_remove_file
-  driver_unregister
-  drm_add_edid_modes
-  drm_add_modes_noedid
-  drm_atomic_add_affected_connectors
-  drm_atomic_add_affected_planes
-  drm_atomic_commit
-  drm_atomic_get_connector_state
-  drm_atomic_get_crtc_state
-  drm_atomic_get_new_connector_for_encoder
-  drm_atomic_get_plane_state
-  drm_atomic_get_private_obj_state
-  drm_atomic_helper_bridge_destroy_state
-  drm_atomic_helper_bridge_duplicate_state
-  drm_atomic_helper_bridge_reset
-  drm_atomic_helper_check
-  drm_atomic_helper_check_modeset
-  drm_atomic_helper_check_plane_state
-  drm_atomic_helper_check_planes
-  drm_atomic_helper_cleanup_planes
-  drm_atomic_helper_commit
-  drm_atomic_helper_commit_cleanup_done
-  drm_atomic_helper_commit_duplicated_state
-  drm_atomic_helper_commit_hw_done
-  drm_atomic_helper_commit_modeset_disables
-  drm_atomic_helper_commit_modeset_enables
-  drm_atomic_helper_commit_planes
-  drm_atomic_helper_commit_tail
-  drm_atomic_helper_connector_destroy_state
-  drm_atomic_helper_connector_duplicate_state
-  drm_atomic_helper_connector_reset
-  drm_atomic_helper_crtc_destroy_state
-  drm_atomic_helper_crtc_duplicate_state
-  drm_atomic_helper_crtc_reset
-  drm_atomic_helper_damage_merged
-  drm_atomic_helper_dirtyfb
-  drm_atomic_helper_disable_plane
-  drm_atomic_helper_disable_planes_on_crtc
-  drm_atomic_helper_duplicate_state
-  drm_atomic_helper_fake_vblank
-  drm_atomic_helper_page_flip
-  drm_atomic_helper_plane_destroy_state
-  drm_atomic_helper_plane_duplicate_state
-  drm_atomic_helper_plane_reset
-  drm_atomic_helper_prepare_planes
-  drm_atomic_helper_set_config
-  drm_atomic_helper_setup_commit
-  drm_atomic_helper_shutdown
-  drm_atomic_helper_swap_state
-  drm_atomic_helper_update_legacy_modeset_state
-  drm_atomic_helper_update_plane
-  drm_atomic_helper_wait_for_dependencies
-  drm_atomic_helper_wait_for_fences
-  drm_atomic_helper_wait_for_flip_done
-  drm_atomic_helper_wait_for_vblanks
-  drm_atomic_normalize_zpos
-  drm_atomic_private_obj_fini
-  drm_atomic_private_obj_init
-  drm_atomic_set_crtc_for_connector
-  drm_atomic_set_crtc_for_plane
-  drm_atomic_set_fb_for_plane
-  drm_atomic_set_fence_for_plane
-  drm_atomic_set_mode_for_crtc
-  drm_atomic_state_alloc
-  drm_atomic_state_clear
-  drm_atomic_state_default_clear
-  drm_atomic_state_default_release
-  drm_atomic_state_init
-  drm_bridge_add
-  drm_bridge_attach
-  drm_bridge_chain_disable
-  drm_bridge_chain_enable
-  drm_bridge_chain_mode_set
-  drm_bridge_chain_post_disable
-  drm_bridge_chain_pre_enable
-  drm_bridge_hpd_notify
-  drm_bridge_remove
-  drm_client_init
-  drm_client_modeset_commit_locked
-  drm_client_register
-  drm_compat_ioctl
-  drm_connector_attach_dp_subconnector_property
-  drm_connector_attach_edid_property
-  drm_connector_attach_encoder
-  drm_connector_cleanup
-  drm_connector_has_possible_encoder
-  drm_connector_init
-  drm_connector_init_with_ddc
-  drm_connector_list_iter_begin
-  drm_connector_list_iter_end
-  drm_connector_list_iter_next
-  drm_connector_register
-  drm_connector_set_tile_property
-  drm_connector_unregister
-  drm_connector_update_edid_property
-  drm_crtc_arm_vblank_event
-  drm_crtc_cleanup
-  drm_crtc_enable_color_mgmt
-  drm_crtc_from_index
-  drm_crtc_handle_vblank
-  drm_crtc_helper_set_config
-  drm_crtc_helper_set_mode
-  drm_crtc_init
-  drm_crtc_init_with_planes
-  drm_crtc_send_vblank_event
-  drm_crtc_set_max_vblank_count
-  drm_crtc_vblank_count
-  drm_crtc_vblank_count_and_time
-  drm_crtc_vblank_get
-  drm_crtc_vblank_helper_get_vblank_timestamp
-  drm_crtc_vblank_off
-  drm_crtc_vblank_on
-  drm_crtc_vblank_put
-  drm_crtc_vblank_reset
-  drm_crtc_wait_one_vblank
-  drm_cvt_mode
-  drm_debugfs_create_files
-  drm_detect_hdmi_monitor
-  drm_detect_monitor_audio
-  drm_dev_alloc
-  drm_dev_dbg
-  drm_dev_enter
-  drm_dev_exit
-  drm_dev_get
-  drm_dev_printk
-  drm_dev_put
-  drm_dev_register
-  drm_dev_set_unique
-  drm_dev_unplug
-  drm_dev_unregister
-  drm_display_mode_to_videomode
-  drm_do_get_edid
-  drm_dp_atomic_find_vcpi_slots
-  drm_dp_atomic_release_vcpi_slots
-  drm_dp_aux_init
-  drm_dp_aux_register
-  drm_dp_aux_unregister
-  drm_dp_bw_code_to_link_rate
-  drm_dp_calc_pbn_mode
-  drm_dp_channel_eq_ok
-  drm_dp_check_act_status
-  drm_dp_clock_recovery_ok
-  drm_dp_dpcd_read
-  drm_dp_dpcd_read_link_status
-  drm_dp_dpcd_write
-  drm_dp_find_vcpi_slots
-  drm_dp_get_adjust_request_pre_emphasis
-  drm_dp_get_adjust_request_voltage
-  drm_dp_get_edid_quirks
-  drm_dp_link_rate_to_bw_code
-  drm_dp_link_train_channel_eq_delay
-  drm_dp_link_train_clock_recovery_delay
-  drm_dp_mst_allocate_vcpi
-  drm_dp_mst_deallocate_vcpi
-  drm_dp_mst_detect_port
-  drm_dp_mst_get_edid
-  drm_dp_mst_get_port_malloc
-  drm_dp_mst_hpd_irq
-  drm_dp_mst_put_port_malloc
-  drm_dp_mst_reset_vcpi_slots
-  drm_dp_mst_topology_mgr_destroy
-  drm_dp_mst_topology_mgr_init
-  drm_dp_mst_topology_mgr_set_mst
-  drm_dp_send_power_updown_phy
-  drm_dp_set_subconnector_property
-  drm_dp_update_payload_part1
-  drm_dp_update_payload_part2
-  drm_edid_block_valid
-  drm_edid_duplicate
-  drm_edid_get_monitor_name
-  drm_edid_header_is_valid
-  drm_edid_is_valid
-  drm_edid_to_sad
-  drm_edid_to_speaker_allocation
-  drm_encoder_cleanup
-  drm_encoder_init
-  drm_event_cancel_free
-  drm_event_reserve_init
-  drm_event_reserve_init_locked
-  drm_fb_cma_get_gem_obj
-  drm_flip_work_cleanup
-  drm_flip_work_commit
-  drm_flip_work_init
-  drm_flip_work_queue
-  drm_format_info
-  drm_framebuffer_cleanup
-  drm_framebuffer_init
-  drm_framebuffer_lookup
-  drm_framebuffer_remove
-  drm_framebuffer_unregister_private
-  drm_gem_cma_dumb_create_internal
-  drm_gem_cma_free_object
-  drm_gem_cma_mmap
-  drm_gem_cma_prime_get_sg_table
-  drm_gem_cma_prime_import_sg_table
-  drm_gem_cma_prime_mmap
-  drm_gem_cma_prime_vmap
-  drm_gem_cma_prime_vunmap
-  drm_gem_cma_vm_ops
-  drm_gem_create_mmap_offset
-  drm_gem_dmabuf_mmap
-  drm_gem_dmabuf_release
-  drm_gem_dmabuf_vmap
-  drm_gem_dmabuf_vunmap
-  drm_gem_fb_create
-  drm_gem_fb_create_handle
-  drm_gem_fb_destroy
-  drm_gem_fb_get_obj
-  drm_gem_fb_prepare_fb
-  drm_gem_free_mmap_offset
-  drm_gem_get_pages
-  drm_gem_handle_create
-  drm_gem_lock_reservations
-  drm_gem_map_attach
-  drm_gem_map_detach
-  drm_gem_map_dma_buf
-  drm_gem_mmap
-  drm_gem_mmap_obj
-  drm_gem_object_free
-  drm_gem_object_init
-  drm_gem_object_lookup
-  drm_gem_object_put_locked
-  drm_gem_object_release
-  drm_gem_prime_export
-  drm_gem_prime_fd_to_handle
-  drm_gem_prime_handle_to_fd
-  drm_gem_prime_import
-  drm_gem_prime_import_dev
-  drm_gem_prime_mmap
-  drm_gem_private_object_init
-  drm_gem_put_pages
-  drm_gem_shmem_create
-  drm_gem_shmem_free_object
-  drm_gem_shmem_get_sg_table
-  drm_gem_shmem_mmap
-  drm_gem_shmem_pin
-  drm_gem_shmem_print_info
-  drm_gem_shmem_unpin
-  drm_gem_shmem_vmap
-  drm_gem_shmem_vunmap
-  drm_gem_unlock_reservations
-  drm_gem_unmap_dma_buf
-  drm_gem_vm_close
-  drm_gem_vm_open
-  drm_get_connector_status_name
-  drm_get_edid
-  drm_get_format_info
-  drm_get_format_name
-  drm_handle_vblank
-  drm_hdmi_avi_infoframe_from_display_mode
-  drm_helper_connector_dpms
-  drm_helper_disable_unused_functions
-  drm_helper_force_disable_all
-  drm_helper_hpd_irq_event
-  drm_helper_mode_fill_fb_struct
-  drm_helper_probe_single_connector_modes
-  drm_helper_resume_force_mode
-  drm_ioctl
-  drm_irq_install
-  drm_irq_uninstall
-  drm_is_current_master
-  drm_kms_helper_hotplug_event
-  drm_kms_helper_is_poll_worker
-  drm_kms_helper_poll_disable
-  drm_kms_helper_poll_enable
-  drm_kms_helper_poll_fini
-  drm_kms_helper_poll_init
-  drm_match_cea_mode
-  drm_mm_init
-  drm_mm_insert_node_in_range
-  drm_mm_print
-  drm_mm_remove_node
-  drm_mm_takedown
-  drm_mode_config_cleanup
-  drm_mode_config_helper_resume
-  drm_mode_config_helper_suspend
-  drm_mode_config_reset
-  drm_mode_convert_to_umode
-  drm_mode_convert_umode
-  drm_mode_copy
-  drm_mode_create
-  drm_mode_create_dp_colorspace_property
-  drm_mode_create_scaling_mode_property
-  drm_mode_create_tile_group
-  drm_mode_crtc_set_gamma_size
-  drm_mode_debug_printmodeline
-  drm_mode_destroy
-  drm_mode_duplicate
-  drm_mode_equal
-  drm_mode_equal_no_clocks
-  drm_mode_get_tile_group
-  drm_mode_is_420_only
-  drm_mode_match
-  drm_mode_object_find
-  drm_mode_object_get
-  drm_mode_object_put
-  drm_mode_probed_add
-  drm_mode_set_crtcinfo
-  drm_mode_set_name
-  drm_mode_sort
-  drm_mode_vrefresh
-  drm_modeset_acquire_fini
-  drm_modeset_acquire_init
-  drm_modeset_backoff
-  drm_modeset_drop_locks
-  drm_modeset_lock
-  drm_modeset_lock_all
-  drm_modeset_lock_all_ctx
-  drm_modeset_lock_init
-  drm_modeset_unlock
-  drm_modeset_unlock_all
-  drm_need_swiotlb
-  drm_object_attach_property
-  drm_object_property_set_value
-  drm_of_component_match_add
-  drm_of_find_possible_crtcs
-  drm_open
-  drm_panel_add
-  drm_panel_disable
-  drm_panel_enable
-  drm_panel_get_modes
-  drm_panel_init
-  drm_panel_prepare
-  drm_panel_remove
-  drm_panel_unprepare
-  drm_plane_cleanup
-  drm_plane_create_alpha_property
-  drm_plane_create_blend_mode_property
-  drm_plane_create_rotation_property
-  drm_plane_create_zpos_property
-  drm_plane_enable_fb_damage_clips
-  drm_poll
-  drm_prime_gem_destroy
-  drm_prime_pages_to_sg
-  drm_prime_sg_to_page_addr_arrays
-  drm_printf
-  drm_property_blob_get
-  drm_property_blob_put
-  drm_property_create
-  drm_property_create_bitmask
-  drm_property_create_blob
-  drm_property_create_bool
-  drm_property_create_enum
-  drm_property_create_range
-  drm_property_create_signed_range
-  drm_property_lookup_blob
-  drm_property_replace_blob
-  drm_puts
-  drm_read
-  drm_rect_calc_hscale
-  drm_rect_calc_vscale
-  drm_rect_clip_scaled
-  drm_rect_intersect
-  drm_release
-  drm_rotation_simplify
-  drm_send_event
-  drm_send_event_locked
-  drm_set_preferred_mode
-  drm_simple_encoder_init
-  drm_state_dump
-  drm_syncobj_add_point
-  drm_syncobj_create
-  drm_syncobj_find
-  drm_syncobj_find_fence
-  drm_syncobj_free
-  drm_syncobj_get_fd
-  drm_syncobj_get_handle
-  drm_syncobj_replace_fence
-  drm_sysfs_hotplug_event
-  drm_universal_plane_init
-  drm_vblank_init
-  drm_vma_node_allow
-  drm_vma_node_is_allowed
-  drm_vma_node_revoke
-  drm_wait_one_vblank
-  drm_writeback_connector_init
-  drm_writeback_queue_job
-  drm_writeback_signal_completion
-  drmm_kmalloc
-  drmm_mode_config_init
-  dst_release
-  dump_align
-  dump_backtrace
-  dump_emit
-  dump_stack
-  dup_iter
-  dw_handle_msi_irq
-  dw_pcie_host_init
-  dw_pcie_msi_init
-  dw_pcie_own_conf_map_bus
-  dw_pcie_read
-  dw_pcie_setup_rc
-  dw_pcie_write
-  dwc3_send_gadget_ep_cmd
-  dwc3_stop_active_transfer
-  edac_device_add_device
-  edac_device_alloc_ctl_info
-  edac_device_alloc_index
-  edac_device_del_device
-  edac_device_free_ctl_info
-  edac_device_handle_ce_count
-  edac_device_handle_ue_count
-  efi
-  efi_tpm_final_log_size
-  elevator_alloc
-  elv_bio_merge_ok
-  elv_rb_add
-  elv_rb_del
-  elv_rb_find
-  elv_rb_former_request
-  elv_rb_latter_request
-  elv_register
-  elv_rqhash_add
-  elv_rqhash_del
-  elv_unregister
-  emergency_restart
-  enable_irq
-  enable_percpu_irq
-  eth_commit_mac_addr_change
-  eth_mac_addr
-  eth_platform_get_mac_address
-  eth_prepare_mac_addr_change
-  eth_type_trans
-  eth_validate_addr
-  ether_setup
-  ethtool_op_get_link
-  ethtool_op_get_ts_info
-  ethtool_virtdev_set_link_ksettings
-  event_triggers_call
-  eventfd_ctx_fdget
-  eventfd_ctx_fileget
-  eventfd_ctx_put
-  eventfd_ctx_remove_wait_queue
-  eventfd_signal
-  extcon_find_edev_by_node
-  extcon_get_edev_by_phandle
-  extcon_get_edev_name
-  extcon_get_extcon_dev
-  extcon_get_property
-  extcon_get_state
-  extcon_register_notifier
-  extcon_set_property
-  extcon_set_property_capability
-  extcon_set_state_sync
-  extcon_unregister_notifier
-  fasync_helper
-  fd_install
-  fget
-  file_path
-  file_ra_state_init
-  filp_close
-  filp_open_block
-  find_get_pid
-  find_last_bit
-  find_next_bit
-  find_next_zero_bit
-  find_snd_usb_substream
-  find_task_by_vpid
-  find_vma
-  find_vpid
-  finish_wait
-  firmware_request_nowarn
-  fixed_phy_register
-  fixed_phy_unregister
-  fixed_size_llseek
-  flow_keys_basic_dissector
-  flush_dcache_page
-  flush_delayed_work
-  flush_signals
-  flush_work
-  flush_workqueue
-  fput
-  frame_vector_create
-  frame_vector_destroy
-  frame_vector_to_pages
-  free_buffer_head
-  free_io_pgtable_ops
-  free_irq
-  free_netdev
-  free_pages
-  free_pages_exact
-  free_percpu
-  free_percpu_irq
-  freezing_slow_path
-  freq_qos_add_request
-  freq_qos_remove_request
-  freq_qos_update_request
-  freq_scale
-  fs_bio_set
-  fsync_bdev
-  ftrace_dump
-  full_name_hash
-  fwnode_find_reference
-  fwnode_get_name
-  fwnode_get_named_child_node
-  fwnode_get_next_child_node
-  fwnode_gpiod_get_index
-  fwnode_handle_get
-  fwnode_handle_put
-  fwnode_property_present
-  fwnode_property_read_string
-  fwnode_property_read_u32_array
-  fwnode_usb_role_switch_get
-  gcd
-  gen_pool_add_owner
-  gen_pool_alloc_algo_owner
-  gen_pool_avail
-  gen_pool_best_fit
-  gen_pool_create
-  gen_pool_destroy
-  gen_pool_dma_alloc_align
-  gen_pool_dma_zalloc_align
-  gen_pool_first_fit_align
-  gen_pool_first_fit_order_align
-  gen_pool_free_owner
-  gen_pool_has_addr
-  gen_pool_set_algo
-  gen_pool_size
-  gen_pool_virt_to_phys
-  generic_delete_inode
-  generic_device_group
-  generic_file_llseek
-  generic_file_read_iter
-  generic_handle_irq
-  generic_iommu_put_resv_regions
-  generic_mii_ioctl
-  generic_perform_write
-  generic_write_checks
-  genl_notify
-  genl_register_family
-  genl_unregister_family
-  genlmsg_put
-  genphy_read_status
-  genphy_resume
-  genphy_soft_reset
-  genphy_suspend
-  get_cpu_device
-  get_cpu_idle_time
-  get_cpu_idle_time_us
-  get_cpu_iowait_time_us
-  get_device
-  get_device_system_crosststamp
-  get_governor_parent_kobj
-  get_next_ino
-  get_option
-  get_options
-  get_pid_task
-  get_random_bytes
-  get_random_bytes_arch
-  get_random_u32
-  get_random_u64
-  get_sg_io_hdr
-  get_state_synchronize_rcu
-  get_task_exe_file
-  get_task_mm
-  get_task_pid
-  get_thermal_instance
-  get_tree_single
-  get_unmapped_area
-  get_unused_fd_flags
-  get_user_pages
-  get_user_pages_fast
-  get_user_pages_remote
-  get_vaddr_frames
-  get_zeroed_page
-  getboottime64
-  gfp_zone
-  gic_nonsecure_priorities
-  glob_match
-  gnss_allocate_device
-  gnss_deregister_device
-  gnss_insert_raw
-  gnss_put_device
-  gnss_register_device
-  gov_attr_set_get
-  gov_attr_set_init
-  gov_attr_set_put
-  governor_sysfs_ops
-  gpio_free
-  gpio_free_array
-  gpio_request
-  gpio_request_one
-  gpio_to_desc
-  gpiochip_add_data_with_key
-  gpiochip_add_pin_range
-  gpiochip_find
-  gpiochip_generic_config
-  gpiochip_generic_free
-  gpiochip_generic_request
-  gpiochip_get_data
-  gpiochip_irqchip_add_key
-  gpiochip_line_is_valid
-  gpiochip_lock_as_irq
-  gpiochip_populate_parent_fwspec_fourcell
-  gpiochip_remove
-  gpiochip_set_nested_irqchip
-  gpiochip_unlock_as_irq
-  gpiod_cansleep
-  gpiod_count
-  gpiod_direction_input
-  gpiod_direction_output
-  gpiod_direction_output_raw
-  gpiod_get_optional
-  gpiod_get_raw_value
-  gpiod_get_raw_value_cansleep
-  gpiod_get_value
-  gpiod_get_value_cansleep
-  gpiod_set_consumer_name
-  gpiod_set_debounce
-  gpiod_set_raw_value
-  gpiod_set_raw_value_cansleep
-  gpiod_set_value
-  gpiod_set_value_cansleep
-  gpiod_to_chip
-  gpiod_to_irq
-  gro_cells_destroy
-  gro_cells_init
-  gro_cells_receive
-  gs_alloc_req
-  gs_free_req
-  gserial_alloc_line
-  gserial_connect
-  gserial_disconnect
-  gserial_free_line
-  gserial_resume
-  gserial_suspend
-  guid_gen
-  handle_bad_irq
-  handle_edge_irq
-  handle_fasteoi_ack_irq
-  handle_fasteoi_irq
-  handle_level_irq
-  handle_nested_irq
-  handle_simple_irq
-  handle_sysrq
-  hash_digest_size
-  hashlen_string
-  have_governor_per_policy
-  hci_alloc_dev
-  hci_free_dev
-  hci_recv_frame
-  hci_register_dev
-  hci_unregister_dev
-  hdmi_audio_infoframe_init
-  hdmi_audio_infoframe_pack
-  hdmi_avi_infoframe_init
-  hdmi_avi_infoframe_pack
-  hdmi_infoframe_pack
-  hex2bin
-  hex_dump_to_buffer
-  hex_to_bin
-  hid_hw_close
-  hid_hw_open
-  hid_hw_start
-  hid_hw_stop
-  hid_open_report
-  hid_report_raw_event
-  hid_unregister_driver
-  hmm_range_fault
-  hrtimer_active
-  hrtimer_cancel
-  hrtimer_forward
-  hrtimer_init
-  hrtimer_init_sleeper
-  hrtimer_sleeper_start_expires
-  hrtimer_start_range_ns
-  hrtimer_try_to_cancel
-  hvc_alloc
-  hvc_instantiate
-  hvc_kick
-  hvc_poll
-  hvc_remove
-  hwrng_register
-  hwrng_unregister
-  hwspin_lock_free
-  hwspin_lock_request_specific
-  hypervisor_kobj
-  i2c_adapter_type
-  i2c_add_adapter
-  i2c_add_numbered_adapter
-  i2c_bit_add_bus
-  i2c_bit_add_numbered_bus
-  i2c_bus_type
-  i2c_client_type
-  i2c_del_adapter
-  i2c_del_driver
-  i2c_for_each_dev
-  i2c_generic_scl_recovery
-  i2c_get_adapter
-  i2c_get_device_id
-  i2c_get_dma_safe_msg_buf
-  i2c_match_id
-  i2c_new_ancillary_device
-  i2c_new_client_device
-  i2c_new_dummy_device
-  i2c_new_scanned_device
-  i2c_parse_fw_timings
-  i2c_put_adapter
-  i2c_put_dma_safe_msg_buf
-  i2c_recover_bus
-  i2c_register_driver
-  i2c_smbus_read_byte
-  i2c_smbus_read_byte_data
-  i2c_smbus_read_i2c_block_data
-  i2c_smbus_read_word_data
-  i2c_smbus_write_byte
-  i2c_smbus_write_byte_data
-  i2c_smbus_write_i2c_block_data
-  i2c_smbus_write_word_data
-  i2c_smbus_xfer
-  i2c_transfer
-  i2c_transfer_buffer_flags
-  i2c_unregister_device
-  i2c_verify_adapter
-  i2c_verify_client
-  icc_disable
-  icc_enable
-  icc_get
-  icc_link_create
-  icc_node_add
-  icc_node_create
-  icc_node_del
-  icc_node_destroy
-  icc_nodes_remove
-  icc_provider_add
-  icc_provider_del
-  icc_put
-  icc_set_bw
-  icc_set_tag
-  icc_std_aggregate
-  icc_sync_state
-  ida_alloc_range
-  ida_destroy
-  ida_free
-  idr_alloc
-  idr_alloc_cyclic
-  idr_alloc_u32
-  idr_destroy
-  idr_find
-  idr_for_each
-  idr_get_next
-  idr_preload
-  idr_remove
-  idr_replace
-  ieee802154_alloc_hw
-  ieee802154_free_hw
-  ieee802154_register_hw
-  ieee802154_rx_irqsafe
-  ieee802154_unregister_hw
-  ieee802154_wake_queue
-  ieee802154_xmit_complete
-  iio_buffer_init
-  iio_buffer_put
-  iio_channel_get
-  iio_channel_get_all
-  iio_channel_release
-  iio_device_alloc
-  iio_device_attach_buffer
-  iio_device_free
-  iio_device_unregister
-  iio_push_to_buffers
-  iio_read_channel_processed
-  iio_read_channel_raw
-  import_iovec
-  in4_pton
-  in6_dev_finish_destroy
-  in6_pton
-  in_aton
-  in_egroup_p
-  inc_zone_page_state
-  inet_proto_csum_replace4
-  init_dummy_netdev
-  init_iova_domain
-  init_net
-  init_on_free
-  init_pid_ns
-  init_pseudo
-  init_srcu_struct
-  init_task
-  init_timer_key
-  init_uts_ns
-  init_wait_entry
-  input_alloc_absinfo
-  input_allocate_device
-  input_close_device
-  input_event
-  input_ff_create
-  input_ff_create_memless
-  input_ff_destroy
-  input_free_device
-  input_mt_assign_slots
-  input_mt_destroy_slots
-  input_mt_drop_unused
-  input_mt_init_slots
-  input_mt_report_finger_count
-  input_mt_report_pointer_emulation
-  input_mt_report_slot_state
-  input_mt_sync_frame
-  input_open_device
-  input_register_device
-  input_register_handle
-  input_register_handler
-  input_set_abs_params
-  input_set_capability
-  input_set_timestamp
-  input_unregister_device
-  input_unregister_handle
-  input_unregister_handler
-  int_pow
-  int_sqrt
-  interval_tree_insert
-  interval_tree_iter_first
-  interval_tree_iter_next
-  interval_tree_remove
-  invalidate_bdev
-  invalidate_mapping_pages
-  io_schedule_timeout
-  iomem_resource
-  iommu_alloc_resv_region
-  iommu_attach_device
-  iommu_attach_group
-  iommu_aux_attach_device
-  iommu_aux_detach_device
-  iommu_aux_get_pasid
-  iommu_detach_device
-  iommu_detach_group
-  iommu_dev_enable_feature
-  iommu_dev_feature_enabled
-  iommu_device_register
-  iommu_device_sysfs_add
-  iommu_device_sysfs_remove
-  iommu_device_unlink
-  iommu_device_unregister
-  iommu_dma_enable_best_fit_algo
-  iommu_dma_get_resv_regions
-  iommu_dma_reserve_iova
-  iommu_domain_alloc
-  iommu_domain_free
-  iommu_domain_get_attr
-  iommu_domain_set_attr
-  iommu_fwspec_add_ids
-  iommu_fwspec_free
-  iommu_get_dma_cookie
-  iommu_get_domain_for_dev
-  iommu_get_msi_cookie
-  iommu_group_alloc
-  iommu_group_for_each_dev
-  iommu_group_get
-  iommu_group_get_iommudata
-  iommu_group_put
-  iommu_group_ref_get
-  iommu_group_set_iommudata
-  iommu_group_set_name
-  iommu_iova_to_phys
-  iommu_map
-  iommu_map_sg
-  iommu_present
-  iommu_put_dma_cookie
-  iommu_register_device_fault_handler
-  iommu_report_device_fault
-  iommu_set_fault_handler
-  iommu_unmap
-  iommu_unregister_device_fault_handler
-  iounmap
-  iov_iter_bvec
-  iov_iter_kvec
-  ip_compute_csum
-  ip_send_check
-  ipi_desc_get
-  iput
-  ipv6_ext_hdr
-  ipv6_find_hdr
-  ipv6_skip_exthdr
-  irq_chip_ack_parent
-  irq_chip_disable_parent
-  irq_chip_enable_parent
-  irq_chip_eoi_parent
-  irq_chip_get_parent_state
-  irq_chip_mask_parent
-  irq_chip_retrigger_hierarchy
-  irq_chip_set_affinity_parent
-  irq_chip_set_parent_state
-  irq_chip_set_type_parent
-  irq_chip_set_vcpu_affinity_parent
-  irq_chip_set_wake_parent
-  irq_chip_unmask_parent
-  irq_create_fwspec_mapping
-  irq_create_mapping_affinity
-  irq_create_of_mapping
-  irq_dispose_mapping
-  irq_domain_add_simple
-  irq_domain_alloc_irqs_parent
-  irq_domain_create_hierarchy
-  irq_domain_free_irqs_common
-  irq_domain_free_irqs_parent
-  irq_domain_get_irq_data
-  irq_domain_remove
-  irq_domain_set_hwirq_and_chip
-  irq_domain_set_info
-  irq_domain_simple_ops
-  irq_domain_update_bus_token
-  irq_domain_xlate_onecell
-  irq_domain_xlate_onetwocell
-  irq_domain_xlate_twocell
-  irq_find_mapping
-  irq_find_matching_fwspec
-  irq_get_irq_data
-  irq_get_irqchip_state
-  irq_modify_status
-  irq_of_parse_and_map
-  irq_set_affinity_hint
-  irq_set_affinity_notifier
-  irq_set_chained_handler_and_data
-  irq_set_chip
-  irq_set_chip_and_handler_name
-  irq_set_chip_data
-  irq_set_handler_data
-  irq_set_irq_type
-  irq_set_irq_wake
-  irq_set_irqchip_state
-  irq_set_parent
-  irq_to_desc
-  irq_work_queue
-  irq_work_queue_on
-  irq_work_sync
-  is_dma_buf_file
-  is_vmalloc_addr
-  iwe_stream_add_event
-  iwe_stream_add_point
-  iwe_stream_add_value
-  jiffies
-  jiffies64_to_msecs
-  jiffies_64_to_clock_t
-  jiffies_to_msecs
-  jiffies_to_usecs
-  kasan_flag_enabled
-  kasprintf
-  kern_mount
-  kern_path
-  kern_unmount
-  kernel_bind
-  kernel_connect
-  kernel_cpustat
-  kernel_getsockname
-  kernel_kobj
-  kernel_power_off
-  kernel_recvmsg
-  kernel_restart
-  kernel_sendmsg
-  kernel_sigaction
-  kernfs_find_and_get_ns
-  kernfs_notify
-  kernfs_path_from_node
-  kernfs_put
-  kfree
-  kfree_const
-  kfree_sensitive
-  kfree_skb
-  kick_all_cpus_sync
-  kill_anon_super
-  kill_fasync
-  kill_litter_super
-  kimage_vaddr
-  kimage_voffset
-  kiocb_set_cancel_fn
-  kmalloc_caches
-  kmalloc_order
-  kmalloc_order_trace
-  kmem_cache_alloc
-  kmem_cache_alloc_trace
-  kmem_cache_create
-  kmem_cache_create_usercopy
-  kmem_cache_destroy
-  kmem_cache_free
-  kmemdup
-  kmemdup_nul
-  kmsg_dump_get_line
-  kmsg_dump_rewind
-  kobj_sysfs_ops
-  kobject_add
-  kobject_create_and_add
-  kobject_del
-  kobject_get
-  kobject_init
-  kobject_init_and_add
-  kobject_put
-  kobject_set_name
-  kobject_uevent
-  kobject_uevent_env
-  krealloc
-  kset_create_and_add
-  kset_unregister
-  ksize
-  ksoftirqd
-  kstat
-  kstat_irqs_cpu
-  kstat_irqs_usr
-  kstrdup
-  kstrdup_const
-  kstrdup_quotable_cmdline
-  kstrndup
-  kstrtobool
-  kstrtobool_from_user
-  kstrtoint
-  kstrtoint_from_user
-  kstrtol_from_user
-  kstrtoll
-  kstrtos16
-  kstrtos8
-  kstrtos8_from_user
-  kstrtou16
-  kstrtou16_from_user
-  kstrtou8
-  kstrtou8_from_user
-  kstrtouint
-  kstrtouint_from_user
-  kstrtoul_from_user
-  kstrtoull
-  kstrtoull_from_user
-  ksys_sync_helper
-  kthread_bind
-  kthread_bind_mask
-  kthread_blkcg
-  kthread_cancel_delayed_work_sync
-  kthread_cancel_work_sync
-  kthread_create_on_node
-  kthread_create_worker
-  kthread_delayed_work_timer_fn
-  kthread_destroy_worker
-  kthread_flush_work
-  kthread_flush_worker
-  kthread_mod_delayed_work
-  kthread_park
-  kthread_parkme
-  kthread_queue_delayed_work
-  kthread_queue_work
-  kthread_should_park
-  kthread_should_stop
-  kthread_stop
-  kthread_unpark
-  kthread_unuse_mm
-  kthread_use_mm
-  kthread_worker_fn
-  ktime_add_safe
-  ktime_get
-  ktime_get_coarse_with_offset
-  ktime_get_mono_fast_ns
-  ktime_get_raw
-  ktime_get_raw_ts64
-  ktime_get_real_seconds
-  ktime_get_real_ts64
-  ktime_get_seconds
-  ktime_get_ts64
-  ktime_get_with_offset
-  kvasprintf
-  kvfree
-  kvfree_call_rcu
-  kvmalloc_node
-  led_classdev_flash_register_ext
-  led_classdev_flash_unregister
-  led_classdev_register_ext
-  led_classdev_unregister
-  led_trigger_event
-  led_trigger_register_simple
-  led_trigger_unregister_simple
-  list_sort
-  llist_add_batch
-  llist_reverse_order
-  lock_sock_nested
-  log_abnormal_wakeup_reason
-  log_buf_addr_get
-  log_buf_len_get
-  log_threaded_irq_wakeup_reason
-  loops_per_jiffy
-  lzo1x_1_compress
-  lzo1x_decompress_safe
-  lzorle1x_1_compress
-  mac_pton
-  match_string
-  mbox_chan_received_data
-  mbox_chan_txdone
-  mbox_client_txdone
-  mbox_controller_register
-  mbox_controller_unregister
-  mbox_free_channel
-  mbox_request_channel
-  mbox_send_message
-  mdiobus_alloc_size
-  mdiobus_free
-  mdiobus_read
-  mdiobus_unregister
-  mdiobus_write
-  media_device_cleanup
-  media_device_init
-  media_device_unregister
-  media_entity_pads_init
-  memblock_end_of_DRAM
-  memblock_free
-  memchr
-  memchr_inv
-  memcmp
-  memcpy
-  memdup_user
-  memdup_user_nul
-  memmove
-  memory_block_size_bytes
-  memory_read_from_buffer
-  memparse
-  mempool_alloc
-  mempool_alloc_slab
-  mempool_create
-  mempool_create_node
-  mempool_destroy
-  mempool_exit
-  mempool_free
-  mempool_free_slab
-  mempool_init
-  mempool_kfree
-  mempool_kmalloc
-  memremap
-  memset
-  memset64
-  memstart_addr
-  memunmap
-  mfd_add_devices
-  mfd_remove_devices
-  migrate_swap
-  mii_check_media
-  mii_ethtool_get_link_ksettings
-  mii_ethtool_gset
-  mii_ethtool_set_link_ksettings
-  mii_link_ok
-  mii_nway_restart
-  mipi_dsi_attach
-  mipi_dsi_compression_mode
-  mipi_dsi_create_packet
-  mipi_dsi_dcs_read
-  mipi_dsi_dcs_set_column_address
-  mipi_dsi_dcs_set_display_brightness
-  mipi_dsi_dcs_set_page_address
-  mipi_dsi_dcs_set_tear_off
-  mipi_dsi_dcs_write_buffer
-  mipi_dsi_detach
-  mipi_dsi_device_register_full
-  mipi_dsi_device_unregister
-  mipi_dsi_driver_register_full
-  mipi_dsi_driver_unregister
-  mipi_dsi_host_register
-  mipi_dsi_host_unregister
-  mipi_dsi_packet_format_is_long
-  mipi_dsi_picture_parameter_set
-  misc_deregister
-  misc_register
-  mktime64
-  mm_trace_rss_stat
-  mmc_add_host
-  mmc_alloc_host
-  mmc_app_cmd
-  mmc_calc_max_discard
-  mmc_can_erase
-  mmc_can_gpio_cd
-  mmc_can_secure_erase_trim
-  mmc_can_trim
-  mmc_cmdq_disable
-  mmc_cmdq_enable
-  mmc_cqe_post_req
-  mmc_cqe_recovery
-  mmc_cqe_request_done
-  mmc_cqe_start_req
-  mmc_detect_card_removed
-  mmc_detect_change
-  mmc_erase
-  mmc_erase_group_aligned
-  mmc_flush_cache
-  mmc_free_host
-  mmc_get_card
-  mmc_get_ext_csd
-  mmc_gpio_get_cd
-  mmc_gpio_get_ro
-  mmc_gpiod_request_cd
-  mmc_gpiod_request_cd_irq
-  mmc_gpiod_request_ro
-  mmc_hw_reset
-  mmc_of_parse
-  mmc_of_parse_voltage
-  mmc_put_card
-  mmc_register_driver
-  mmc_regulator_get_supply
-  mmc_regulator_set_ocr
-  mmc_regulator_set_vqmmc
-  mmc_release_host
-  mmc_remove_host
-  mmc_request_done
-  mmc_retune_pause
-  mmc_retune_release
-  mmc_retune_unpause
-  mmc_run_bkops
-  mmc_sanitize
-  mmc_send_status
-  mmc_send_tuning
-  mmc_set_data_timeout
-  mmc_start_request
-  mmc_switch
-  mmc_unregister_driver
-  mmc_wait_for_cmd
-  mmc_wait_for_req
-  mmput
-  mmu_interval_notifier_insert
-  mmu_interval_notifier_remove
-  mmu_interval_read_begin
-  mmu_notifier_synchronize
-  mod_delayed_work_on
-  mod_node_page_state
-  mod_timer
-  module_layout
-  module_put
-  msleep
-  msleep_interruptible
-  mutex_is_locked
-  mutex_lock
-  mutex_lock_interruptible
-  mutex_trylock
-  mutex_trylock_recursive
-  mutex_unlock
-  name_to_dev_t
-  names_cachep
-  napi_complete_done
-  napi_consume_skb
-  napi_disable
-  napi_gro_flush
-  napi_gro_receive
-  napi_schedule_prep
-  net_namespace_list
-  net_ratelimit
-  netdev_change_features
-  netdev_err
-  netdev_increment_features
-  netdev_info
-  netdev_lower_state_changed
-  netdev_master_upper_dev_link
-  netdev_notify_peers
-  netdev_pick_tx
-  netdev_rx_handler_register
-  netdev_rx_handler_unregister
-  netdev_state_change
-  netdev_update_features
-  netdev_upper_dev_link
-  netdev_upper_dev_unlink
-  netdev_warn
-  netif_carrier_off
-  netif_carrier_on
-  netif_device_attach
-  netif_device_detach
-  netif_napi_add
-  netif_receive_skb
-  netif_receive_skb_list
-  netif_rx
-  netif_rx_ni
-  netif_schedule_queue
-  netif_set_real_num_rx_queues
-  netif_set_real_num_tx_queues
-  netif_stacked_transfer_operstate
-  netif_tx_stop_all_queues
-  netif_tx_wake_queue
-  netlink_ack
-  netlink_broadcast
-  netlink_capable
-  netlink_has_listeners
-  netlink_kernel_release
-  netlink_register_notifier
-  netlink_unicast
-  netlink_unregister_notifier
-  new_inode
-  nf_conntrack_destroy
-  nla_append
-  nla_find
-  nla_memcpy
-  nla_put
-  nla_put_64bit
-  nla_put_nohdr
-  nla_reserve
-  nla_reserve_64bit
-  nla_strlcpy
-  no_llseek
-  no_seek_end_llseek
-  nonseekable_open
-  noop_llseek
-  nr_cpu_ids
-  nr_ipi_get
-  nr_irqs
-  ns_capable
-  ns_to_timespec64
-  nsec_to_clock_t
-  nsecs_to_jiffies
-  nvdimm_bus_register
-  nvdimm_bus_unregister
-  nvdimm_pmem_region_create
-  nvmem_cell_get
-  nvmem_cell_put
-  nvmem_cell_read
-  nvmem_cell_read_u32
-  nvmem_cell_write
-  nvmem_device_put
-  nvmem_device_read
-  nvmem_device_write
-  of_address_to_resource
-  of_alias_get_highest_id
-  of_alias_get_id
-  of_clk_add_hw_provider
-  of_clk_add_provider
-  of_clk_del_provider
-  of_clk_get
-  of_clk_get_by_name
-  of_clk_get_from_provider
-  of_clk_get_parent_count
-  of_clk_get_parent_name
-  of_clk_hw_onecell_get
-  of_clk_hw_simple_get
-  of_clk_set_defaults
-  of_clk_src_onecell_get
-  of_clk_src_simple_get
-  of_count_phandle_with_args
-  of_cpu_node_to_id
-  of_cpufreq_cooling_register
-  of_css
-  of_devfreq_cooling_register
-  of_devfreq_cooling_register_power
-  of_device_get_match_data
-  of_device_is_available
-  of_device_is_compatible
-  of_device_modalias
-  of_device_request_module
-  of_device_uevent_modalias
-  of_dma_configure_id
-  of_dma_controller_free
-  of_dma_controller_register
-  of_dma_is_coherent
-  of_drm_find_bridge
-  of_drm_find_panel
-  of_find_all_nodes
-  of_find_compatible_node
-  of_find_device_by_node
-  of_find_i2c_adapter_by_node
-  of_find_i2c_device_by_node
-  of_find_matching_node_and_match
-  of_find_mipi_dsi_host_by_node
-  of_find_node_by_name
-  of_find_node_by_phandle
-  of_find_node_by_type
-  of_find_node_opts_by_path
-  of_find_node_with_property
-  of_find_property
-  of_fwnode_ops
-  of_genpd_add_provider_onecell
-  of_genpd_add_provider_simple
-  of_genpd_del_provider
-  of_get_address
-  of_get_child_by_name
-  of_get_compatible_child
-  of_get_cpu_node
-  of_get_dma_window
-  of_get_named_gpio_flags
-  of_get_next_available_child
-  of_get_next_child
-  of_get_next_parent
-  of_get_parent
-  of_get_property
-  of_get_regulator_init_data
-  of_graph_get_endpoint_by_regs
-  of_graph_get_next_endpoint
-  of_graph_get_port_parent
-  of_graph_get_remote_endpoint
-  of_graph_get_remote_node
-  of_graph_get_remote_port
-  of_graph_get_remote_port_parent
-  of_graph_is_present
-  of_graph_parse_endpoint
-  of_hwspin_lock_get_id
-  of_i2c_get_board_info
-  of_icc_get
-  of_icc_xlate_onecell
-  of_iomap
-  of_irq_find_parent
-  of_irq_get
-  of_irq_get_byname
-  of_irq_parse_one
-  of_machine_is_compatible
-  of_match_device
-  of_match_node
-  of_modalias_node
-  of_n_addr_cells
-  of_n_size_cells
-  of_node_name_eq
-  of_nvmem_device_get
-  of_parse_phandle
-  of_parse_phandle_with_args
-  of_parse_phandle_with_fixed_args
-  of_phandle_iterator_init
-  of_phandle_iterator_next
-  of_phy_simple_xlate
-  of_platform_depopulate
-  of_platform_device_create
-  of_platform_device_destroy
-  of_platform_populate
-  of_prop_next_string
-  of_prop_next_u32
-  of_property_count_elems_of_size
-  of_property_match_string
-  of_property_read_string
-  of_property_read_string_helper
-  of_property_read_u32_index
-  of_property_read_u64
-  of_property_read_u64_index
-  of_property_read_variable_u16_array
-  of_property_read_variable_u32_array
-  of_property_read_variable_u64_array
-  of_property_read_variable_u8_array
-  of_pwm_xlate_with_flags
-  of_reserved_mem_device_init_by_idx
-  of_reserved_mem_device_release
-  of_reserved_mem_lookup
-  of_reset_control_array_get
-  of_root
-  of_thermal_get_ntrips
-  of_thermal_get_trip_points
-  of_thermal_is_trip_valid
-  of_translate_address
-  of_usb_get_phy_mode
-  of_usb_host_tpl_support
-  on_each_cpu
-  oops_in_progress
-  orderly_poweroff
-  overflowuid
-  page_endio
-  page_mapping
-  page_reporting_register
-  page_reporting_unregister
-  panic
-  panic_notifier_list
-  panic_timeout
-  param_array_ops
-  param_get_int
-  param_get_string
-  param_get_uint
-  param_get_ullong
-  param_ops_bint
-  param_ops_bool
-  param_ops_byte
-  param_ops_charp
-  param_ops_hexint
-  param_ops_int
-  param_ops_long
-  param_ops_short
-  param_ops_string
-  param_ops_uint
-  param_ops_ullong
-  param_ops_ulong
-  param_ops_ushort
-  param_set_bool
-  param_set_copystring
-  param_set_int
-  param_set_uint
-  part_end_io_acct
-  part_start_io_acct
-  passthru_features_check
-  path_put
-  pause_cpus
-  pci_alloc_irq_vectors_affinity
-  pci_assign_resource
-  pci_assign_unassigned_bus_resources
-  pci_bus_resource_n
-  pci_bus_type
-  pci_clear_master
-  pci_d3cold_disable
-  pci_dev_present
-  pci_dev_put
-  pci_device_group
-  pci_device_is_present
-  pci_disable_device
-  pci_disable_msi
-  pci_enable_atomic_ops_to_root
-  pci_enable_device
-  pci_enable_device_mem
-  pci_enable_msi
-  pci_enable_wake
-  pci_find_bus
-  pci_find_capability
-  pci_find_ext_capability
-  pci_find_next_capability
-  pci_free_irq
-  pci_free_irq_vectors
-  pci_generic_config_read
-  pci_generic_config_write
-  pci_get_device
-  pci_get_domain_bus_and_slot
-  pci_get_slot
-  pci_host_probe
-  pci_intx
-  pci_iomap
-  pci_iomap_range
-  pci_ioremap_bar
-  pci_irq_get_affinity
-  pci_irq_vector
-  pci_load_and_free_saved_state
-  pci_load_saved_state
-  pci_map_rom
-  pci_match_id
-  pci_msi_create_irq_domain
-  pci_msi_mask_irq
-  pci_msi_unmask_irq
-  pci_msix_vec_count
-  pci_read_config_byte
-  pci_read_config_dword
-  pci_read_config_word
-  pci_release_region
-  pci_release_regions
-  pci_release_resource
-  pci_release_selected_regions
-  pci_request_irq
-  pci_request_region
-  pci_request_regions
-  pci_request_selected_regions
-  pci_rescan_bus
-  pci_resize_resource
-  pci_restore_msi_state
-  pci_restore_state
-  pci_save_state
-  pci_select_bars
-  pci_set_master
-  pci_set_mwi
-  pci_set_power_state
-  pci_store_saved_state
-  pci_unmap_rom
-  pci_unregister_driver
-  pci_wake_from_d3
-  pci_walk_bus
-  pci_write_config_byte
-  pci_write_config_dword
-  pci_write_config_word
-  pcibios_resource_to_bus
-  pcie_aspm_enabled
-  pcie_bandwidth_available
-  pcie_capability_read_word
-  pcie_capability_write_word
-  pcie_get_mps
-  pcie_get_speed_cap
-  pcim_enable_device
-  per_cpu_ptr_to_phys
-  percpu_down_write
-  percpu_ref_exit
-  percpu_ref_init
-  percpu_ref_is_zero
-  percpu_ref_kill_and_confirm
-  percpu_ref_switch_to_atomic_sync
-  percpu_ref_switch_to_percpu
-  percpu_up_write
-  perf_aux_output_begin
-  perf_aux_output_end
-  perf_aux_output_flag
-  perf_event_addr_filters_sync
-  perf_event_create_kernel_counter
-  perf_event_disable
-  perf_event_enable
-  perf_event_pause
-  perf_event_read_local
-  perf_event_read_value
-  perf_event_release_kernel
-  perf_event_update_userpage
-  perf_get_aux
-  perf_pmu_migrate_context
-  perf_pmu_register
-  perf_pmu_unregister
-  perf_trace_buf_alloc
-  perf_trace_run_bpf_submit
-  pfn_valid
-  phy_attached_info
-  phy_calibrate
-  phy_configure
-  phy_connect
-  phy_connect_direct
-  phy_disconnect
-  phy_do_ioctl_running
-  phy_drivers_register
-  phy_drivers_unregister
-  phy_ethtool_get_link_ksettings
-  phy_ethtool_nway_reset
-  phy_ethtool_set_link_ksettings
-  phy_ethtool_set_wol
-  phy_exit
-  phy_find_first
-  phy_get_pause
-  phy_init
-  phy_init_hw
-  phy_mii_ioctl
-  phy_pm_runtime_get_sync
-  phy_pm_runtime_put_sync
-  phy_power_off
-  phy_power_on
-  phy_print_status
-  phy_register_fixup_for_uid
-  phy_save_page
-  phy_set_mode_ext
-  phy_start
-  phy_stop
-  phy_unregister_fixup_for_uid
-  pick_highest_pushable_task
-  pid_nr_ns
-  pid_task
-  pin_get_name
-  pin_user_pages
-  pin_user_pages_fast
-  pin_user_pages_remote
-  pinconf_generic_dt_free_map
-  pinconf_generic_dt_node_to_map
-  pinctrl_add_gpio_range
-  pinctrl_dev_get_drvdata
-  pinctrl_enable
-  pinctrl_force_default
-  pinctrl_force_sleep
-  pinctrl_get
-  pinctrl_lookup_state
-  pinctrl_pm_select_default_state
-  pinctrl_pm_select_idle_state
-  pinctrl_pm_select_sleep_state
-  pinctrl_put
-  pinctrl_remove_gpio_range
-  pinctrl_select_default_state
-  pinctrl_select_state
-  pinctrl_utils_free_map
-  pipe_lock
-  pipe_unlock
-  pktgen_xfrm_outer_mode_output
-  platform_add_devices
-  platform_bus_type
-  platform_device_add
-  platform_device_add_data
-  platform_device_add_properties
-  platform_device_add_resources
-  platform_device_alloc
-  platform_device_del
-  platform_device_put
-  platform_device_register
-  platform_device_register_full
-  platform_device_unregister
-  platform_driver_unregister
-  platform_find_device_by_driver
-  platform_get_irq
-  platform_get_irq_byname
-  platform_get_irq_byname_optional
-  platform_get_irq_optional
-  platform_get_resource
-  platform_get_resource_byname
-  platform_irq_count
-  pm_clk_add
-  pm_clk_create
-  pm_clk_destroy
-  pm_clk_resume
-  pm_clk_suspend
-  pm_generic_resume
-  pm_generic_runtime_resume
-  pm_generic_runtime_suspend
-  pm_generic_suspend
-  pm_genpd_add_subdomain
-  pm_genpd_init
-  pm_genpd_remove
-  pm_genpd_remove_subdomain
-  pm_power_off
-  pm_relax
-  pm_runtime_allow
-  pm_runtime_autosuspend_expiration
-  pm_runtime_barrier
-  pm_runtime_enable
-  pm_runtime_forbid
-  pm_runtime_force_resume
-  pm_runtime_force_suspend
-  pm_runtime_get_if_active
-  pm_runtime_irq_safe
-  pm_runtime_no_callbacks
-  pm_runtime_set_autosuspend_delay
-  pm_stay_awake
-  pm_suspend_global_flags
-  pm_system_wakeup
-  pm_wakeup_dev_event
-  pm_wakeup_ws_event
-  policy_has_boost_freq
-  power_supply_changed
-  power_supply_get_by_name
-  power_supply_get_by_phandle_array
-  power_supply_get_drvdata
-  power_supply_get_property
-  power_supply_is_system_supplied
-  power_supply_put
-  power_supply_reg_notifier
-  power_supply_register
-  power_supply_set_property
-  power_supply_unreg_notifier
-  power_supply_unregister
-  prandom_bytes
-  prandom_u32
-  preempt_schedule
-  preempt_schedule_notrace
-  prepare_to_wait
-  prepare_to_wait_event
-  print_hex_dump
-  printk
-  printk_deferred
-  printk_timed_ratelimit
-  proc_create
-  proc_create_data
-  proc_create_single_data
-  proc_dointvec
-  proc_dointvec_minmax
-  proc_dostring
-  proc_douintvec_minmax
-  proc_mkdir
-  proc_mkdir_data
-  proc_remove
-  proc_set_size
-  proc_set_user
-  proc_symlink
-  proto_register
-  proto_unregister
-  ps2_begin_command
-  ps2_cmd_aborted
-  ps2_command
-  ps2_drain
-  ps2_end_command
-  ps2_handle_ack
-  ps2_handle_response
-  ps2_init
-  ps2_sendbyte
-  ps2_sliced_command
-  pskb_expand_head
-  pstore_register
-  pstore_unregister
-  public_key_verify_signature
-  put_device
-  put_disk
-  put_iova_domain
-  put_pid
-  put_sg_io_hdr
-  put_tty_driver
-  put_unused_fd
-  put_vaddr_frames
-  pwm_apply_state
-  pwm_get_chip_data
-  pwm_set_chip_data
-  pwmchip_add
-  pwmchip_remove
-  qcom_smem_state_get
-  qcom_smem_state_register
-  qcom_smem_state_unregister
-  qcom_smem_state_update_bits
-  qdisc_reset
-  queue_delayed_work_on
-  queue_work_on
-  radix_tree_delete
-  radix_tree_insert
-  radix_tree_iter_delete
-  radix_tree_iter_resume
-  radix_tree_lookup
-  radix_tree_maybe_preload
-  radix_tree_next_chunk
-  radix_tree_tagged
-  rational_best_approximation
-  raw_notifier_call_chain
-  raw_notifier_chain_register
-  raw_notifier_chain_unregister
-  rb_erase
-  rb_first
-  rb_first_postorder
-  rb_insert_color
-  rb_last
-  rb_next
-  rb_next_postorder
-  rb_prev
-  rb_replace_node
-  rcu_barrier
-  rcu_barrier_tasks
-  rcu_barrier_tasks_trace
-  rcu_bind_current_to_nocb
-  rcu_cpu_stall_suppress
-  rcu_cpu_stall_suppress_at_boot
-  rcu_expedite_gp
-  rcu_force_quiescent_state
-  rcu_fwd_progress_check
-  rcu_get_gp_kthreads_prio
-  rcu_get_gp_seq
-  rcu_gp_is_expedited
-  rcu_gp_is_normal
-  rcu_gp_set_torture_wait
-  rcu_inkernel_boot_has_ended
-  rcu_is_watching
-  rcu_jiffies_till_stall_check
-  rcu_read_unlock_trace_special
-  rcu_unexpedite_gp
-  rcutorture_get_gp_data
-  rcuwait_wake_up
-  rdev_get_drvdata
-  rdev_get_id
-  reboot_mode
-  reciprocal_value
-  refcount_dec_and_lock
-  refcount_dec_and_mutex_lock
-  refcount_dec_not_one
-  refcount_warn_saturate
-  refresh_frequency_limits
-  regcache_cache_bypass
-  regcache_cache_only
-  regcache_drop_region
-  regcache_mark_dirty
-  regcache_sync
-  regcache_sync_region
-  register_blkdev
-  register_chrdev_region
-  register_console
-  register_die_notifier
-  register_filesystem
-  register_ftrace_export
-  register_inet6addr_notifier
-  register_inetaddr_notifier
-  register_kernel_break_hook
-  register_kprobe
-  register_kretprobe
-  register_memory_notifier
-  register_module_notifier
-  register_net_sysctl
-  register_netdev
-  register_netdevice
-  register_netdevice_notifier
-  register_netevent_notifier
-  register_oom_notifier
-  register_pernet_device
-  register_pernet_subsys
-  register_pm_notifier
-  register_reboot_notifier
-  register_restart_handler
-  register_shrinker
-  register_syscore_ops
-  register_sysctl
-  register_sysctl_table
-  register_virtio_device
-  register_virtio_driver
-  register_vmap_purge_notifier
-  regmap_add_irq_chip
-  regmap_async_complete
-  regmap_bulk_read
-  regmap_bulk_write
-  regmap_check_range_table
-  regmap_del_irq_chip
-  regmap_exit
-  regmap_field_read
-  regmap_field_update_bits_base
-  regmap_get_device
-  regmap_irq_get_domain
-  regmap_irq_get_virq
-  regmap_mmio_detach_clk
-  regmap_multi_reg_write
-  regmap_multi_reg_write_bypassed
-  regmap_raw_read
-  regmap_raw_write
-  regmap_raw_write_async
-  regmap_read
-  regmap_register_patch
-  regmap_update_bits_base
-  regmap_write
-  regulator_allow_bypass
-  regulator_bulk_disable
-  regulator_bulk_enable
-  regulator_bulk_get
-  regulator_count_voltages
-  regulator_disable
-  regulator_disable_deferred
-  regulator_disable_regmap
-  regulator_enable
-  regulator_enable_regmap
-  regulator_force_disable
-  regulator_get
-  regulator_get_current_limit
-  regulator_get_drvdata
-  regulator_get_mode
-  regulator_get_optional
-  regulator_get_voltage
-  regulator_get_voltage_rdev
-  regulator_get_voltage_sel_regmap
-  regulator_is_enabled
-  regulator_is_enabled_regmap
-  regulator_is_supported_voltage
-  regulator_list_voltage_linear
-  regulator_list_voltage_linear_range
-  regulator_list_voltage_table
-  regulator_map_voltage_ascend
-  regulator_map_voltage_linear
-  regulator_notifier_call_chain
-  regulator_put
-  regulator_register
-  regulator_register_notifier
-  regulator_set_current_limit
-  regulator_set_load
-  regulator_set_mode
-  regulator_set_voltage
-  regulator_set_voltage_sel_regmap
-  regulator_unregister
-  regulator_unregister_notifier
-  release_firmware
-  release_pages
-  release_sock
-  remap_pfn_range
-  remap_vmalloc_range
-  remove_cpu
-  remove_memory_subsection
-  remove_proc_entry
-  remove_wait_queue
-  report_iommu_fault
-  request_any_context_irq
-  request_firmware
-  request_firmware_direct
-  request_firmware_into_buf
-  request_firmware_nowait
-  request_threaded_irq
-  resched_curr
-  reservation_ww_class
-  reset_control_assert
-  reset_control_deassert
-  reset_control_put
-  reset_control_reset
-  resume_cpus
-  return_address
-  revalidate_disk_size
-  rfkill_alloc
-  rfkill_destroy
-  rfkill_find_type
-  rfkill_init_sw_state
-  rfkill_register
-  rfkill_set_sw_state
-  rfkill_unregister
-  rhashtable_destroy
-  rhashtable_init
-  rhashtable_insert_slow
-  rht_bucket_nested
-  rht_bucket_nested_insert
-  rndis_deregister
-  rndis_free_response
-  rndis_get_next_response
-  rndis_msg_parser
-  rndis_register
-  rndis_set_host_mac
-  rndis_set_param_dev
-  rndis_set_param_medium
-  rndis_set_param_vendor
-  rndis_signal_connect
-  rndis_uninit
-  root_task_group
-  round_jiffies_relative
-  round_jiffies_up
-  rpmsg_get_signals
-  rpmsg_poll
-  rpmsg_register_device
-  rpmsg_send
-  rpmsg_set_signals
-  rpmsg_trysend
-  rpmsg_unregister_device
-  rproc_add
-  rproc_add_subdev
-  rproc_alloc
-  rproc_boot
-  rproc_coredump_add_custom_segment
-  rproc_coredump_add_segment
-  rproc_coredump_set_elf_info
-  rproc_coredump_using_sections
-  rproc_del
-  rproc_elf_get_boot_addr
-  rproc_free
-  rproc_get_by_child
-  rproc_get_by_phandle
-  rproc_put
-  rproc_remove_subdev
-  rproc_report_crash
-  rproc_shutdown
-  rps_needed
-  rt_mutex_lock
-  rt_mutex_trylock
-  rt_mutex_unlock
-  rtc_class_close
-  rtc_class_open
-  rtc_read_time
-  rtc_set_time
-  rtc_time64_to_tm
-  rtc_tm_to_time64
-  rtc_update_irq
-  rtc_valid_tm
-  rtc_year_days
-  rtnl_is_locked
-  rtnl_link_register
-  rtnl_link_unregister
-  rtnl_lock
-  rtnl_register_module
-  rtnl_trylock
-  rtnl_unicast
-  rtnl_unlock
-  rtnl_unregister
-  runqueues
-  sb800_prefetch
-  sbitmap_queue_min_shallow_depth
-  sched_clock
-  sched_feat_keys
-  sched_feat_names
-  sched_set_fifo
-  sched_set_fifo_low
-  sched_set_normal
-  sched_setattr
-  sched_setattr_nocheck
-  sched_setscheduler
-  sched_setscheduler_nocheck
-  sched_show_task
-  sched_trace_cfs_rq_avg
-  sched_trace_cfs_rq_cpu
-  sched_trace_cfs_rq_path
-  sched_trace_rd_span
-  sched_trace_rq_avg_dl
-  sched_trace_rq_avg_irq
-  sched_trace_rq_avg_rt
-  sched_trace_rq_cpu
-  sched_uclamp_used
-  schedule
-  schedule_hrtimeout
-  schedule_timeout
-  schedule_timeout_interruptible
-  schedule_timeout_uninterruptible
-  scnprintf
-  scsi_autopm_get_device
-  scsi_autopm_put_device
-  scsi_block_requests
-  scsi_block_when_processing_errors
-  scsi_command_size_tbl
-  scsi_compat_ioctl
-  scsi_device_get
-  scsi_device_put
-  scsi_device_quiesce
-  scsi_dma_unmap
-  scsi_eh_ready_devs
-  scsi_ioctl
-  scsi_ioctl_block_when_processing_errors
-  scsi_normalize_sense
-  scsi_print_sense_hdr
-  scsi_register_interface
-  scsi_remove_device
-  scsi_unblock_requests
-  sdev_prefix_printk
-  sdhci_add_host
-  sdhci_cleanup_host
-  sdhci_cqe_disable
-  sdhci_cqe_enable
-  sdhci_cqe_irq
-  sdhci_enable_clk
-  sdhci_get_property
-  sdhci_pltfm_free
-  sdhci_pltfm_init
-  sdhci_remove_host
-  sdhci_reset
-  sdhci_set_bus_width
-  sdhci_set_power_noreg
-  sdhci_setup_host
-  sdio_claim_host
-  sdio_disable_func
-  sdio_enable_func
-  sdio_f0_readb
-  sdio_f0_writeb
-  sdio_get_host_pm_caps
-  sdio_memcpy_fromio
-  sdio_memcpy_toio
-  sdio_readsb
-  sdio_register_driver
-  sdio_release_host
-  sdio_set_block_size
-  sdio_set_host_pm_flags
-  sdio_signal_irq
-  sdio_unregister_driver
-  sdio_writesb
-  securityfs_create_dir
-  securityfs_create_file
-  securityfs_remove
-  send_sig_info
-  seq_buf_printf
-  seq_file_path
-  seq_hex_dump
-  seq_list_next
-  seq_list_start
-  seq_lseek
-  seq_open
-  seq_printf
-  seq_putc
-  seq_puts
-  seq_read
-  seq_release
-  seq_release_private
-  seq_vprintf
-  seq_write
-  serdev_device_close
-  serdev_device_open
-  serdev_device_set_baudrate
-  serdev_device_set_flow_control
-  serdev_device_wait_until_sent
-  serdev_device_write
-  serdev_device_write_wakeup
-  serio_close
-  serio_interrupt
-  serio_open
-  serio_reconnect
-  serio_rescan
-  serio_unregister_child_port
-  serio_unregister_driver
-  serio_unregister_port
-  set_blocksize
-  set_capacity_revalidate_and_notify
-  set_cpus_allowed_ptr
-  set_disk_ro
-  set_freezable
-  set_normalized_timespec64
-  set_page_dirty
-  set_page_dirty_lock
-  set_task_cpu
-  set_user_nice
-  sg_alloc_table
-  sg_alloc_table_from_pages
-  sg_free_table
-  sg_init_one
-  sg_init_table
-  sg_miter_next
-  sg_miter_start
-  sg_miter_stop
-  sg_nents_for_len
-  sg_next
-  sg_pcopy_from_buffer
-  sg_pcopy_to_buffer
-  sg_scsi_ioctl
-  sg_zero_buffer
-  sgl_alloc
-  sgl_free
-  shmem_truncate_range
-  show_rcu_gp_kthreads
-  show_regs
-  si_mem_available
-  si_meminfo
-  si_swapinfo
-  sigprocmask
-  simple_attr_open
-  simple_attr_read
-  simple_attr_release
-  simple_attr_write
-  simple_dir_inode_operations
-  simple_dir_operations
-  simple_open
-  simple_read_from_buffer
-  simple_statfs
-  simple_strtol
-  simple_strtoll
-  simple_strtoul
-  simple_strtoull
-  simple_write_to_buffer
-  single_open
-  single_open_size
-  single_release
-  sk_alloc
-  sk_free
-  skb_add_rx_frag
-  skb_append_pagefrags
-  skb_checksum
-  skb_clone
-  skb_coalesce_rx_frag
-  skb_copy
-  skb_copy_bits
-  skb_copy_datagram_iter
-  skb_copy_expand
-  skb_copy_ubufs
-  skb_dequeue
-  skb_dequeue_tail
-  skb_ensure_writable
-  skb_free_datagram
-  skb_page_frag_refill
-  skb_partial_csum_set
-  skb_pull
-  skb_push
-  skb_put
-  skb_queue_head
-  skb_queue_purge
-  skb_queue_tail
-  skb_realloc_headroom
-  skb_recv_datagram
-  skb_set_owner_w
-  skb_store_bits
-  skb_to_sgvec
-  skb_trim
-  skb_tstamp_tx
-  skb_unlink
-  skip_spaces
-  smp_call_function
-  smp_call_function_any
-  smp_call_function_many
-  smp_call_function_single
-  smp_call_function_single_async
-  smp_call_on_cpu
-  smpboot_register_percpu_thread
-  smpboot_unregister_percpu_thread
-  snd_card_disconnect
-  snd_card_free
-  snd_card_new
-  snd_card_register
-  snd_card_rw_proc_new
-  snd_component_add
-  snd_compr_stop_error
-  snd_ctl_add
-  snd_ctl_add_vmaster_hook
-  snd_ctl_apply_vmaster_followers
-  snd_ctl_boolean_mono_info
-  snd_ctl_boolean_stereo_info
-  snd_ctl_enum_info
-  snd_ctl_find_id
-  snd_ctl_make_virtual_master
-  snd_ctl_new1
-  snd_ctl_notify
-  snd_ctl_remove
-  snd_ctl_remove_id
-  snd_ctl_sync_vmaster
-  snd_device_disconnect
-  snd_device_free
-  snd_device_new
-  snd_dma_alloc_pages
-  snd_dma_free_pages
-  snd_dmaengine_pcm_prepare_slave_config
-  snd_hwdep_new
-  snd_info_create_card_entry
-  snd_info_create_module_entry
-  snd_info_free_entry
-  snd_info_register
-  snd_interval_refine
-  snd_jack_new
-  snd_jack_report
-  snd_jack_set_key
-  snd_pci_quirk_lookup
-  snd_pcm_add_chmap_ctls
-  snd_pcm_alt_chmaps
-  snd_pcm_create_iec958_consumer_hw_params
-  snd_pcm_format_physical_width
-  snd_pcm_format_width
-  snd_pcm_hw_constraint_eld
-  snd_pcm_hw_constraint_integer
-  snd_pcm_hw_constraint_list
-  snd_pcm_hw_constraint_minmax
-  snd_pcm_hw_constraint_msbits
-  snd_pcm_hw_constraint_step
-  snd_pcm_hw_limit_rates
-  snd_pcm_hw_rule_add
-  snd_pcm_lib_default_mmap
-  snd_pcm_lib_free_pages
-  snd_pcm_lib_ioctl
-  snd_pcm_lib_malloc_pages
-  snd_pcm_lib_preallocate_free_for_all
-  snd_pcm_lib_preallocate_pages
-  snd_pcm_new
-  snd_pcm_period_elapsed
-  snd_pcm_rate_range_to_bits
-  snd_pcm_set_managed_buffer_all
-  snd_pcm_set_ops
-  snd_pcm_set_sync
-  snd_pcm_std_chmaps
-  snd_pcm_stream_lock
-  snd_pcm_stream_unlock
-  snd_pcm_stream_unlock_irqrestore
-  snd_soc_add_card_controls
-  snd_soc_add_component_controls
-  snd_soc_add_dai_controls
-  snd_soc_bytes_info_ext
-  snd_soc_bytes_tlv_callback
-  snd_soc_card_get_kcontrol
-  snd_soc_card_jack_new
-  snd_soc_component_async_complete
-  snd_soc_component_disable_pin
-  snd_soc_component_exit_regmap
-  snd_soc_component_force_enable_pin
-  snd_soc_component_init_regmap
-  snd_soc_component_read
-  snd_soc_component_set_jack
-  snd_soc_component_set_pll
-  snd_soc_component_set_sysclk
-  snd_soc_component_update_bits
-  snd_soc_component_update_bits_async
-  snd_soc_component_write
-  snd_soc_dai_get_channel_map
-  snd_soc_dai_link_set_capabilities
-  snd_soc_dai_set_bclk_ratio
-  snd_soc_dai_set_channel_map
-  snd_soc_dai_set_fmt
-  snd_soc_dai_set_pll
-  snd_soc_dai_set_sysclk
-  snd_soc_dai_set_tdm_slot
-  snd_soc_dapm_add_routes
-  snd_soc_dapm_disable_pin
-  snd_soc_dapm_disable_pin_unlocked
-  snd_soc_dapm_enable_pin
-  snd_soc_dapm_force_enable_pin
-  snd_soc_dapm_force_enable_pin_unlocked
-  snd_soc_dapm_get_enum_double
-  snd_soc_dapm_get_pin_status
-  snd_soc_dapm_get_pin_switch
-  snd_soc_dapm_get_volsw
-  snd_soc_dapm_ignore_suspend
-  snd_soc_dapm_info_pin_switch
-  snd_soc_dapm_kcontrol_dapm
-  snd_soc_dapm_kcontrol_widget
-  snd_soc_dapm_mixer_update_power
-  snd_soc_dapm_mux_update_power
-  snd_soc_dapm_new_control
-  snd_soc_dapm_new_controls
-  snd_soc_dapm_new_widgets
-  snd_soc_dapm_put_enum_double
-  snd_soc_dapm_put_pin_switch
-  snd_soc_dapm_put_volsw
-  snd_soc_dapm_sync
-  snd_soc_dapm_sync_unlocked
-  snd_soc_dapm_weak_routes
-  snd_soc_find_dai
-  snd_soc_get_enum_double
-  snd_soc_get_pcm_runtime
-  snd_soc_get_volsw
-  snd_soc_get_volsw_range
-  snd_soc_get_volsw_sx
-  snd_soc_get_xr_sx
-  snd_soc_info_enum_double
-  snd_soc_info_multi_ext
-  snd_soc_info_volsw
-  snd_soc_info_volsw_range
-  snd_soc_info_volsw_sx
-  snd_soc_info_xr_sx
-  snd_soc_jack_add_gpios
-  snd_soc_jack_report
-  snd_soc_lookup_component
-  snd_soc_new_compress
-  snd_soc_of_get_dai_link_codecs
-  snd_soc_of_get_dai_name
-  snd_soc_of_parse_audio_routing
-  snd_soc_of_parse_audio_simple_widgets
-  snd_soc_of_parse_aux_devs
-  snd_soc_of_parse_card_name
-  snd_soc_of_parse_daifmt
-  snd_soc_of_parse_node_prefix
-  snd_soc_of_parse_tdm_slot
-  snd_soc_of_put_dai_link_codecs
-  snd_soc_params_to_bclk
-  snd_soc_params_to_frame_size
-  snd_soc_pm_ops
-  snd_soc_put_enum_double
-  snd_soc_put_volsw
-  snd_soc_put_volsw_range
-  snd_soc_put_volsw_sx
-  snd_soc_put_xr_sx
-  snd_soc_register_card
-  snd_soc_register_component
-  snd_soc_rtdcom_lookup
-  snd_soc_runtime_calc_hw
-  snd_soc_runtime_set_dai_fmt
-  snd_soc_set_runtime_hwparams
-  snd_soc_tplg_component_load
-  snd_soc_tplg_component_remove
-  snd_soc_tplg_widget_bind_event
-  snd_soc_unregister_card
-  snd_soc_unregister_component
-  snd_usb_enable_audio_stream
-  snd_vendor_set_ops
-  snprintf
-  soc_device_register
-  soc_device_unregister
-  sock_alloc_send_skb
-  sock_create_kern
-  sock_gettstamp
-  sock_i_uid
-  sock_init_data
-  sock_no_accept
-  sock_no_listen
-  sock_no_mmap
-  sock_no_sendpage
-  sock_no_shutdown
-  sock_no_socketpair
-  sock_queue_rcv_skb
-  sock_register
-  sock_release
-  sock_setsockopt
-  sock_unregister
-  sock_wfree
-  softnet_data
-  sort
-  spi_bus_lock
-  spi_bus_type
-  spi_bus_unlock
-  spi_controller_resume
-  spi_controller_suspend
-  spi_delay_exec
-  spi_finalize_current_message
-  spi_finalize_current_transfer
-  spi_get_next_queued_message
-  spi_register_controller
-  spi_setup
-  spi_sync
-  spi_sync_locked
-  spi_unregister_controller
-  split_page
-  spmi_controller_add
-  spmi_controller_alloc
-  spmi_controller_remove
-  spmi_ext_register_read
-  spmi_ext_register_readl
-  spmi_ext_register_write
-  spmi_ext_register_writel
-  spmi_register_read
-  spmi_register_write
-  spmi_register_zero_write
-  sprint_symbol
-  sprint_symbol_no_offset
-  sprintf
-  srcu_barrier
-  srcu_batches_completed
-  srcu_init_notifier_head
-  srcu_notifier_call_chain
-  srcu_notifier_chain_register
-  srcu_notifier_chain_unregister
-  srcu_torture_stats_print
-  srcutorture_get_gp_data
-  sscanf
-  stack_trace_print
-  stack_trace_save
-  stack_trace_save_regs
-  stack_trace_save_tsk
-  static_key_disable
-  static_key_disable_cpuslocked
-  static_key_slow_dec
-  static_key_slow_inc
-  stop_machine
-  stop_one_cpu_nowait
-  stpcpy
-  strcasecmp
-  strcat
-  strchr
-  strchrnul
-  strcmp
-  strcpy
-  strcspn
-  stream_open
-  strim
-  string_get_size
-  strlcat
-  strlcpy
-  strlen
-  strncasecmp
-  strncat
-  strnchr
-  strncmp
-  strncpy
-  strncpy_from_user
-  strndup_user
-  strnlen
-  strnstr
-  strpbrk
-  strrchr
-  strreplace
-  strscpy
-  strsep
-  strspn
-  strstr
-  submit_bh
-  submit_bio
-  submit_bio_wait
-  subsys_system_register
-  swiotlb_nr_tbl
-  sync_blockdev
-  sync_file_create
-  sync_file_get_fence
-  synchronize_irq
-  synchronize_net
-  synchronize_rcu
-  synchronize_rcu_expedited
-  synchronize_rcu_tasks
-  synchronize_rcu_tasks_trace
-  synchronize_srcu
-  synchronize_srcu_expedited
-  sys_tz
-  syscon_node_to_regmap
-  syscon_regmap_lookup_by_phandle
-  sysctl_sched_features
-  sysctl_sched_latency
-  sysctl_vals
-  sysfs_add_file_to_group
-  sysfs_add_link_to_group
-  sysfs_create_bin_file
-  sysfs_create_file_ns
-  sysfs_create_files
-  sysfs_create_group
-  sysfs_create_groups
-  sysfs_create_link
-  sysfs_emit
-  sysfs_emit_at
-  sysfs_notify
-  sysfs_remove_bin_file
-  sysfs_remove_file_from_group
-  sysfs_remove_file_ns
-  sysfs_remove_files
-  sysfs_remove_group
-  sysfs_remove_groups
-  sysfs_remove_link
-  sysfs_remove_link_from_group
-  sysfs_streq
-  sysfs_update_group
-  sysrq_mask
-  system_freezable_wq
-  system_freezing_cnt
-  system_highpri_wq
-  system_long_wq
-  system_power_efficient_wq
-  system_state
-  system_unbound_wq
-  system_wq
-  task_active_pid_ns
-  task_groups
-  task_may_not_preempt
-  task_rq_lock
-  tasklet_init
-  tasklet_kill
-  tasklet_setup
-  tasklist_lock
-  tcp_register_congestion_control
-  tcp_reno_cong_avoid
-  tcp_reno_ssthresh
-  tcp_reno_undo_cwnd
-  tcp_slow_start
-  tcp_unregister_congestion_control
-  tcpci_get_tcpm_port
-  tcpci_irq
-  tcpci_register_port
-  tcpci_unregister_port
-  tcpm_cc_change
-  tcpm_is_toggling
-  tcpm_pd_hard_reset
-  tcpm_pd_receive
-  tcpm_pd_transmit_complete
-  tcpm_sink_frs
-  tcpm_sourcing_vbus
-  tcpm_update_sink_capabilities
-  tcpm_vbus_change
-  thermal_cdev_update
-  thermal_cooling_device_register
-  thermal_cooling_device_unregister
-  thermal_of_cooling_device_register
-  thermal_pressure
-  thermal_zone_device_disable
-  thermal_zone_device_enable
-  thermal_zone_device_is_enabled
-  thermal_zone_device_register
-  thermal_zone_device_unregister
-  thermal_zone_device_update
-  thermal_zone_get_slope
-  thermal_zone_get_temp
-  thermal_zone_get_zone_by_name
-  thermal_zone_of_sensor_register
-  thermal_zone_of_sensor_unregister
-  thread_group_cputime_adjusted
-  tick_nohz_get_idle_calls_cpu
-  tick_nohz_get_sleep_length
-  time64_to_tm
-  timecounter_init
-  timecounter_read
-  timer_unstable_counter_workaround
-  topology_set_thermal_pressure
-  total_swapcache_pages
-  trace_clock_local
-  trace_event_buffer_commit
-  trace_event_buffer_reserve
-  trace_event_ignore_this_pid
-  trace_event_raw_init
-  trace_event_reg
-  trace_handle_return
-  trace_output_call
   trace_print_array_seq
   trace_print_flags_seq
   trace_print_hex_seq
+  __trace_printk
   trace_print_symbols_seq
   trace_raw_output_prep
   trace_seq_printf
   trace_seq_putc
-  tracepoint_probe_register
-  tracepoint_probe_register_prio
-  tracepoint_probe_unregister
   tracing_off
   try_module_get
   try_to_del_timer_sync
@@ -4038,8 +4065,8 @@
   ttm_bo_device_init
   ttm_bo_device_release
   ttm_bo_dma_acc_size
-  ttm_bo_evict_mm
   ttm_bo_eviction_valuable
+  ttm_bo_evict_mm
   ttm_bo_glob
   ttm_bo_init_reserved
   ttm_bo_kmap
@@ -4074,8 +4101,10 @@
   ttm_tt_populate
   ttm_tt_set_placement_caching
   ttm_unmap_and_unpopulate_pages
+  __tty_alloc_driver
   tty_encode_baud_rate
   tty_flip_buffer_push
+  __tty_insert_flip_char
   tty_insert_flip_string_fixed_flag
   tty_kref_put
   tty_ldisc_deref
@@ -4137,6 +4166,7 @@
   ucsi_register
   ucsi_set_drvdata
   ucsi_unregister
+  __udelay
   udp4_hwcsum
   ufshcd_auto_hibern8_update
   ufshcd_bkops_ctrl
@@ -4168,11 +4198,13 @@
   ufshcd_system_suspend
   ufshcd_uic_hibern8_enter
   ufshcd_uic_hibern8_exit
+  __uio_register_device
   uio_unregister_device
   unlock_page
   unmap_mapping_range
   unpin_user_page
   unregister_blkdev
+  __unregister_chrdev
   unregister_chrdev_region
   unregister_console
   unregister_die_notifier
@@ -4202,10 +4234,11 @@
   unregister_virtio_driver
   unregister_vmap_purge_notifier
   up
+  update_devfreq
+  __update_load_avg_blocked_se
+  update_rq_clock
   up_read
   up_write
-  update_devfreq
-  update_rq_clock
   usb_add_function
   usb_add_gadget
   usb_add_gadget_udc
@@ -4233,14 +4266,15 @@
   usb_composite_setup_continue
   usb_control_msg
   usb_copy_descriptors
+  __usb_create_hcd
   usb_create_hcd
   usb_debug_root
   usb_decode_ctrl
   usb_del_gadget_udc
   usb_deregister
   usb_deregister_dev
-  usb_disable_xhci_ports
   usb_disabled
+  usb_disable_xhci_ports
   usb_enable_autosuspend
   usb_enable_intel_xhci_ports
   usb_ep_alloc_request
@@ -4275,15 +4309,16 @@
   usb_gadget_wakeup
   usb_get_dev
   usb_get_dr_mode
+  __usb_get_extra_descriptor
   usb_get_gadget_udc_name
   usb_get_intf
   usb_get_maximum_speed
   usb_get_urb
   usb_gstrings_attach
-  usb_hc_died
   usb_hcd_check_unlink_urb
   usb_hcd_end_port_resume
   usb_hcd_giveback_urb
+  usb_hc_died
   usb_hcd_irq
   usb_hcd_is_primary_hcd
   usb_hcd_link_urb_to_ep
@@ -4295,9 +4330,9 @@
   usb_hcd_platform_shutdown
   usb_hcd_poll_rh_status
   usb_hcd_resume_root_hub
+  usb_hcds_loaded
   usb_hcd_start_port_resume
   usb_hcd_unlink_urb_from_ep
-  usb_hcds_loaded
   usb_hid_driver
   usb_hub_clear_tt_buffer
   usb_hub_find_child
@@ -4308,6 +4343,36 @@
   usb_kill_urb
   usb_match_id
   usb_match_one_id
+  usbnet_cdc_unbind
+  usbnet_change_mtu
+  usbnet_defer_kevent
+  usbnet_disconnect
+  usbnet_generic_cdc_bind
+  usbnet_get_drvinfo
+  usbnet_get_endpoints
+  usbnet_get_link
+  usbnet_get_link_ksettings
+  usbnet_get_msglevel
+  usbnet_get_stats64
+  usbnet_link_change
+  usbnet_nway_reset
+  usbnet_open
+  usbnet_probe
+  usbnet_read_cmd
+  usbnet_read_cmd_nopm
+  usbnet_resume
+  usbnet_set_link_ksettings
+  usbnet_set_msglevel
+  usbnet_skb_return
+  usbnet_start_xmit
+  usbnet_stop
+  usbnet_suspend
+  usbnet_tx_timeout
+  usbnet_unlink_rx_urbs
+  usbnet_update_max_qlen
+  usbnet_write_cmd
+  usbnet_write_cmd_async
+  usbnet_write_cmd_nopm
   usb_otg_state_string
   usb_phy_set_charger_current
   usb_poison_anchored_urbs
@@ -4339,36 +4404,7 @@
   usb_unpoison_urb
   usb_unregister_notify
   usb_wakeup_notification
-  usbnet_cdc_unbind
-  usbnet_change_mtu
-  usbnet_defer_kevent
-  usbnet_disconnect
-  usbnet_generic_cdc_bind
-  usbnet_get_drvinfo
-  usbnet_get_endpoints
-  usbnet_get_link
-  usbnet_get_link_ksettings
-  usbnet_get_msglevel
-  usbnet_get_stats64
-  usbnet_link_change
-  usbnet_nway_reset
-  usbnet_open
-  usbnet_probe
-  usbnet_read_cmd
-  usbnet_read_cmd_nopm
-  usbnet_resume
-  usbnet_set_link_ksettings
-  usbnet_set_msglevel
-  usbnet_skb_return
-  usbnet_start_xmit
-  usbnet_stop
-  usbnet_suspend
-  usbnet_tx_timeout
-  usbnet_unlink_rx_urbs
-  usbnet_update_max_qlen
-  usbnet_write_cmd
-  usbnet_write_cmd_async
-  usbnet_write_cmd_nopm
+  __usecs_to_jiffies
   usleep_range
   uuid_gen
   uuid_null
@@ -4384,6 +4420,7 @@
   v4l2_ctrl_new_std_menu
   v4l2_device_register
   v4l2_device_register_subdev
+  __v4l2_device_register_subdev_nodes
   v4l2_device_set_name
   v4l2_device_unregister
   v4l2_device_unregister_subdev
@@ -4476,6 +4513,7 @@
   video_device_release
   video_device_release_empty
   video_ioctl2
+  __video_register_device
   video_unregister_device
   virtio_check_driver_offered_feature
   virtio_config_changed
@@ -4532,7 +4570,17 @@
   virtqueue_kick_prepare
   virtqueue_notify
   virtqueue_poll
+  vmalloc
+  vmalloc_nr_pages
+  vmalloc_to_page
+  vmalloc_to_pfn
+  vmalloc_user
+  vmap
+  vmemdup_user
   vm_event_states
+  vmf_insert_mixed
+  vmf_insert_pfn
+  vmf_insert_pfn_prot
   vm_get_page_prot
   vm_insert_page
   vm_iomap_memory
@@ -4543,16 +4591,6 @@
   vm_node_stat
   vm_unmap_ram
   vm_zone_stat
-  vmalloc
-  vmalloc_nr_pages
-  vmalloc_to_page
-  vmalloc_to_pfn
-  vmalloc_user
-  vmap
-  vmemdup_user
-  vmf_insert_mixed
-  vmf_insert_pfn
-  vmf_insert_pfn_prot
   vprintk
   vring_create_virtqueue
   vring_del_virtqueue
@@ -4575,8 +4613,12 @@
   wait_for_completion_killable
   wait_for_completion_killable_timeout
   wait_for_completion_timeout
+  __wait_rcu_gp
   wait_woken
+  __wake_up
   wake_up_if_idle
+  __wake_up_locked
+  __wake_up_locked_key
   wake_up_process
   wakeup_source_add
   wakeup_source_create
@@ -4584,6 +4626,8 @@
   wakeup_source_register
   wakeup_source_remove
   wakeup_source_unregister
+  __wake_up_sync
+  __warn_printk
   watchdog_init_timeout
   watchdog_register_device
   watchdog_set_restart_priority
@@ -4594,10 +4638,12 @@
   ww_mutex_lock
   ww_mutex_lock_interruptible
   ww_mutex_unlock
+  __xa_alloc
   xa_destroy
   xa_erase
   xa_find
   xa_find_after
+  __xa_insert
   xa_load
   xa_store
   xdp_convert_zc_to_xdp_frame
@@ -4609,6 +4655,7 @@
   xdp_rxq_info_reg_mem_model
   xdp_rxq_info_unreg
   xdp_warn
+  __xfrm_state_destroy
   xfrm_state_lookup_byspi
   xfrm_stateonly_find
   xhci_add_endpoint
diff --git a/kernel/android/abi_gki_aarch64_generic b/kernel/android/abi_gki_aarch64_generic
index cc8edfd..f0808ba 100644
--- a/kernel/android/abi_gki_aarch64_generic
+++ b/kernel/android/abi_gki_aarch64_generic
@@ -87,10 +87,10 @@
   blocking_notifier_call_chain
   blocking_notifier_chain_register
   blocking_notifier_chain_unregister
-  bpf_trace_run1
   bpf_trace_run10
   bpf_trace_run11
   bpf_trace_run12
+  bpf_trace_run1
   bpf_trace_run2
   bpf_trace_run3
   bpf_trace_run4
@@ -993,8 +993,8 @@
   irq_work_queue
   irq_work_sync
   is_vmalloc_addr
-  jiffies
   jiffies64_to_msecs
+  jiffies
   jiffies_to_msecs
   jiffies_to_usecs
   kasan_flag_enabled
@@ -1123,8 +1123,8 @@
   memmove
   memparse
   memremap
-  memset
   memset64
+  memset
   memstart_addr
   memunmap
   mfd_add_devices
@@ -1198,8 +1198,8 @@
   nla_find
   nla_memcpy
   __nla_parse
-  nla_put
   nla_put_64bit
+  nla_put
   nla_put_nohdr
   nla_reserve
   nla_strlcpy
@@ -1294,6 +1294,7 @@
   of_usb_host_tpl_support
   page_endio
   page_mapping
+  page_pinner_inited
   __page_pinner_migration_failed
   panic
   panic_notifier_list
diff --git a/kernel/android/abi_gki_aarch64_lenovo b/kernel/android/abi_gki_aarch64_lenovo
index 0049535..6815423 100644
--- a/kernel/android/abi_gki_aarch64_lenovo
+++ b/kernel/android/abi_gki_aarch64_lenovo
@@ -1,10 +1,10 @@
 [abi_symbol_list]
 # required by raid0.ko
-    __tracepoint_block_bio_remap
-    disk_stack_limits
-    blk_queue_max_write_same_sectors
-    __traceiter_block_bio_remap
-    submit_bio_noacct
     bio_split
+    blk_queue_max_write_same_sectors
+    disk_stack_limits
+    submit_bio_noacct
+    __traceiter_block_bio_remap
+    __tracepoint_block_bio_remap
 # required by lenovo-fan.ko
     clk_set_duty_cycle
diff --git a/kernel/android/abi_gki_aarch64_moto b/kernel/android/abi_gki_aarch64_moto
new file mode 100644
index 0000000..71a0d1b
--- /dev/null
+++ b/kernel/android/abi_gki_aarch64_moto
@@ -0,0 +1,6 @@
+[abi_symbol_list]
+  swp_swap_info
+  __traceiter_android_vh_skip_swapcache
+  __traceiter_android_vh_tune_mmap_readaround
+  __tracepoint_android_vh_skip_swapcache
+  __tracepoint_android_vh_tune_mmap_readaround
diff --git a/kernel/android/abi_gki_aarch64_mtk b/kernel/android/abi_gki_aarch64_mtk
index 8d2c956..c27c6a7 100644
--- a/kernel/android/abi_gki_aarch64_mtk
+++ b/kernel/android/abi_gki_aarch64_mtk
@@ -34,6 +34,7 @@
   __arch_copy_to_user
   arch_timer_read_counter
   arm64_const_caps_ready
+  arm64_noalias_setup_dma_ops
   arm64_use_ng_mappings
   __arm_smccc_hvc
   __arm_smccc_smc
@@ -198,8 +199,8 @@
   cpufreq_disable_fast_switch
   cpufreq_driver_fast_switch
   cpufreq_driver_resolve_freq
-  cpufreq_driver_target
   __cpufreq_driver_target
+  cpufreq_driver_target
   cpufreq_enable_fast_switch
   cpufreq_frequency_table_get_index
   cpufreq_generic_attr
@@ -373,8 +374,8 @@
   __dev_kfree_skb_any
   __dev_kfree_skb_irq
   devm_add_action
-  __devm_alloc_percpu
   devm_alloc_etherdev_mqs
+  __devm_alloc_percpu
   devm_blk_ksm_init
   devm_clk_bulk_get
   devm_clk_bulk_get_optional
@@ -1309,6 +1310,7 @@
   __netdev_alloc_skb
   netdev_err
   netdev_info
+  netdev_notice
   netdev_set_default_ethtool_ops
   netdev_warn
   netif_carrier_off
@@ -1399,6 +1401,7 @@
   of_get_next_child
   of_get_next_parent
   of_get_parent
+  of_get_pci_domain_nr
   of_get_phy_mode
   of_get_property
   of_get_regulator_init_data
@@ -1471,6 +1474,12 @@
   param_set_ulong
   pause_cpus
   pci_bus_type
+  pci_generic_config_read32
+  pci_generic_config_write32
+  pci_lock_rescan_remove
+  pci_pio_to_address
+  pci_prepare_to_sleep
+  pci_unlock_rescan_remove
   PDE_DATA
   __per_cpu_offset
   perf_event_create_kernel_counter
@@ -1491,6 +1500,7 @@
   phy_drivers_register
   phy_drivers_unregister
   phy_ethtool_get_link_ksettings
+  phy_ethtool_get_wol
   phy_ethtool_nway_reset
   phy_ethtool_set_link_ksettings
   phy_exit
@@ -1510,6 +1520,7 @@
   phy_set_mode_ext
   phy_start
   phy_stop
+  phy_support_asym_pause
   phy_write_paged
   pid_task
   pinconf_generic_parse_dt_config
@@ -2421,6 +2432,8 @@
   usb_add_hcd
   usb_add_phy_dev
   usb_assign_descriptors
+  usb_autopm_get_interface_async
+  usb_autopm_put_interface_async
   usb_composite_probe
   usb_composite_unregister
   usb_copy_descriptors
@@ -2430,6 +2443,8 @@
   usb_del_gadget_udc
   usb_deregister
   usb_disabled
+  usb_driver_set_configuration
+  usb_enable_lpm
   usb_ep_alloc_request
   usb_ep_autoconfig
   usb_ep_dequeue
@@ -2501,6 +2516,7 @@
   usb_remove_function
   usb_remove_hcd
   usb_remove_phy
+  usb_reset_device
   usb_role_switch_get
   usb_role_switch_get_drvdata
   usb_role_switch_get_role
@@ -2509,6 +2525,7 @@
   usb_role_switch_unregister
   usb_speed_string
   usb_string_id
+  usb_wait_anchor_empty_timeout
   __usecs_to_jiffies
   usleep_range
   uuid_null
@@ -3128,6 +3145,7 @@
   __traceiter_android_vh_snd_soc_card_get_comp_chain
   __traceiter_android_vh_sound_usb_support_cpu_suspend
   __traceiter_android_vh_syscall_prctl_finished
+  __traceiter_android_vh_ufs_update_sdev
   __traceiter_android_vh_v4l2subdev_set_fmt
   __traceiter_android_vh_v4l2subdev_set_frame_interval
   __traceiter_android_vh_v4l2subdev_set_selection
@@ -3145,10 +3163,10 @@
   __tracepoint_android_rvh_select_task_rq_rt
   __tracepoint_android_rvh_setscheduler
   __tracepoint_android_rvh_set_user_nice
+  __tracepoint_android_rvh_uclamp_eff_get
   __tracepoint_android_rvh_v4l2subdev_set_fmt
   __tracepoint_android_rvh_v4l2subdev_set_frame_interval
   __tracepoint_android_rvh_v4l2subdev_set_selection
-  __tracepoint_android_rvh_uclamp_eff_get
   __tracepoint_android_vh_alter_futex_plist_add
   __tracepoint_android_vh_alter_rwsem_list_add
   __tracepoint_android_vh_arch_set_freq_scale
diff --git a/kernel/android/abi_gki_aarch64_nothing b/kernel/android/abi_gki_aarch64_nothing
new file mode 100644
index 0000000..5960f2b
--- /dev/null
+++ b/kernel/android/abi_gki_aarch64_nothing
@@ -0,0 +1,4 @@
+[abi_symbol_list]
+# required by mount_state.ko
+  iterate_supers_type
+  get_fs_type
\ No newline at end of file
diff --git a/kernel/android/abi_gki_aarch64_oplus b/kernel/android/abi_gki_aarch64_oplus
index d1c65a2..aef23e8 100644
--- a/kernel/android/abi_gki_aarch64_oplus
+++ b/kernel/android/abi_gki_aarch64_oplus
@@ -115,9 +115,9 @@
   blocking_notifier_call_chain
   blocking_notifier_chain_register
   blocking_notifier_chain_unregister
-  bpf_trace_run1
   bpf_trace_run10
   bpf_trace_run12
+  bpf_trace_run1
   bpf_trace_run2
   bpf_trace_run3
   bpf_trace_run4
@@ -143,6 +143,7 @@
   cdev_device_del
   cdev_init
   __cfi_slowpath
+  cgroup_add_dfl_cftypes
   cgroup_add_legacy_cftypes
   cgroup_path_ns
   cgroup_taskset_first
@@ -685,8 +686,8 @@
   dma_unmap_resource
   dma_unmap_sg_attrs
   do_exit
-  do_wait_intr_irq
   do_traversal_all_lruvec
+  do_wait_intr_irq
   down
   down_interruptible
   down_read
@@ -1356,6 +1357,7 @@
   irq_work_queue
   irq_work_queue_on
   irq_work_sync
+  is_ashmem_file
   is_dma_buf_file
   isolate_and_split_free_page
   isolate_anon_lru_page
@@ -1548,6 +1550,7 @@
   __memcat_p
   memcg_kmem_enabled_key
   mem_cgroup_from_id
+  mem_cgroup_update_lru_size
   memchr
   memchr_inv
   memcmp
@@ -1568,8 +1571,8 @@
   mempool_free
   mempool_free_slab
   memremap
-  memset
   memset64
+  memset
   __memset_io
   memstart_addr
   memunmap
@@ -1615,6 +1618,7 @@
   mmc_send_tuning
   mmput
   mod_delayed_work_on
+  __mod_lruvec_state
   mod_node_page_state
   mod_timer
   mod_timer_pending
@@ -1670,10 +1674,10 @@
   nla_find
   nla_memcpy
   __nla_parse
-  nla_put
   nla_put_64bit
-  nla_reserve
+  nla_put
   nla_reserve_64bit
+  nla_reserve
   __nla_validate
   __nlmsg_put
   no_llseek
@@ -1810,10 +1814,11 @@
   page_endio
   __page_file_index
   __page_file_mapping
-  __page_mapcount
   page_get_link
+  __page_mapcount
   page_mapping
   __page_pinner_migration_failed
+  page_referenced
   page_symlink
   page_to_lruvec
   panic
@@ -2059,8 +2064,8 @@
   radix_tree_lookup
   radix_tree_lookup_slot
   radix_tree_next_chunk
-  radix_tree_replace_slot
   radix_tree_preload
+  radix_tree_replace_slot
   ___ratelimit
   rational_best_approximation
   raw_notifier_call_chain
@@ -2252,6 +2257,7 @@
   rndis_set_param_vendor
   rndis_signal_connect
   rndis_uninit
+  root_mem_cgroup
   root_task_group
   round_jiffies
   round_jiffies_relative
@@ -2696,8 +2702,8 @@
   __traceiter_android_rvh_after_enqueue_task
   __traceiter_android_rvh_build_perf_domains
   __traceiter_android_rvh_can_migrate_task
-  __traceiter_android_rvh_check_preempt_wakeup
   __traceiter_android_rvh_check_preempt_tick
+  __traceiter_android_rvh_check_preempt_wakeup
   __traceiter_android_rvh_cpu_cgroup_attach
   __traceiter_android_rvh_cpu_cgroup_online
   __traceiter_android_rvh_cpu_overutilized
@@ -2754,6 +2760,9 @@
   __traceiter_android_rvh_v4l2subdev_set_selection
   __traceiter_android_rvh_wake_up_new_task
   __traceiter_android_vh_account_task_time
+  __traceiter_android_vh_add_page_to_lrulist
+  __traceiter_android_vh_alloc_pages_slowpath_begin
+  __traceiter_android_vh_alloc_pages_slowpath_end
   __traceiter_android_vh_allow_domain_state
   __traceiter_android_vh_alter_futex_plist_add
   __traceiter_android_vh_alter_mutex_list_add
@@ -2784,11 +2793,23 @@
   __traceiter_android_vh_check_bpf_syscall
   __traceiter_android_vh_check_file_open
   __traceiter_android_vh_check_mmap_file
+  __traceiter_android_vh_check_page_look_around_ref
   __traceiter_android_vh_check_uninterruptible_tasks
   __traceiter_android_vh_check_uninterruptible_tasks_dn
   __traceiter_android_vh_clear_mask_adjust
   __traceiter_android_vh_clear_reserved_fmt_fields
   __traceiter_android_vh_cma_drain_all_pages_bypass
+  __traceiter_android_vh_compact_finished
+  __traceiter_android_vh_alloc_pages_reclaim_bypass
+  __traceiter_android_vh_free_unref_page_bypass
+  __traceiter_android_vh_kvmalloc_node_use_vmalloc
+  __traceiter_android_vh_should_alloc_pages_retry
+  __traceiter_android_vh_unreserve_highatomic_bypass
+  __traceiter_android_vh_pageset_update
+  __traceiter_android_vh_rmqueue_bulk_bypass
+  __traceiter_android_vh_tune_mmap_readaround
+  __traceiter_android_vh_ra_tuning_max_page
+  __traceiter_android_vh_cleanup_old_buffers_bypass
   __traceiter_android_vh_commit_creds
   __traceiter_android_vh_cpufreq_acct_update_power
   __traceiter_android_vh_cpufreq_fast_switch
@@ -2797,9 +2818,12 @@
   __traceiter_android_vh_cpu_idle_enter
   __traceiter_android_vh_cpu_idle_exit
   __traceiter_android_vh_cpu_up
-  __traceiter_android_vh_check_page_look_around_ref
+  __traceiter_android_vh_del_page_from_lrulist
   __traceiter_android_vh_do_futex
+  __traceiter_android_vh_do_page_trylock
   __traceiter_android_vh_do_send_sig_info
+  __traceiter_android_vh_do_traversal_lruvec
+  __traceiter_android_vh_dm_bufio_shrink_scan_bypass
   __traceiter_android_vh_drain_all_pages_bypass
   __traceiter_android_vh_em_cpu_energy
   __traceiter_android_vh_exclude_reserved_zone
@@ -2833,14 +2857,17 @@
   __traceiter_android_vh_logbuf
   __traceiter_android_vh_look_around
   __traceiter_android_vh_look_around_migrate_page
+  __traceiter_android_vh_madvise_cold_or_pageout_abort
+  __traceiter_android_vh_mark_page_accessed
   __traceiter_android_vh_mem_cgroup_alloc
   __traceiter_android_vh_mem_cgroup_css_offline
   __traceiter_android_vh_mem_cgroup_css_online
   __traceiter_android_vh_mem_cgroup_free
   __traceiter_android_vh_mem_cgroup_id_remove
   __traceiter_android_vh_meminfo_proc_show
-  __traceiter_android_vh_alloc_pages_slowpath_begin
-  __traceiter_android_vh_alloc_pages_slowpath_end
+  __traceiter_android_vh_mutex_can_spin_on_owner
+  __traceiter_android_vh_mutex_opt_spin_finish
+  __traceiter_android_vh_mutex_opt_spin_start
   __traceiter_android_vh_mutex_unlock_slowpath
   __traceiter_android_vh_mutex_unlock_slowpath_end
   __traceiter_android_vh_mutex_wait_finish
@@ -2848,28 +2875,26 @@
   __traceiter_android_vh_override_creds
   __traceiter_android_vh_page_referenced_check_bypass
   __traceiter_android_vh_page_should_be_protected
-  __traceiter_android_vh_page_trylock_set
   __traceiter_android_vh_page_trylock_clear
   __traceiter_android_vh_page_trylock_get_result
-  __traceiter_android_vh_mark_page_accessed
-  __traceiter_android_vh_show_mapcount_pages
-  __traceiter_android_vh_do_traversal_lruvec
-  __traceiter_android_vh_do_page_trylock
-  __traceiter_android_vh_update_page_mapcount
-  __traceiter_android_vh_add_page_to_lrulist
-  __traceiter_android_vh_del_page_from_lrulist
+  __traceiter_android_vh_page_trylock_set
   __traceiter_android_vh_pcplist_add_cma_pages_bypass
   __traceiter_android_vh_prepare_update_load_avg_se
   __traceiter_android_vh_printk_hotplug
   __traceiter_android_vh_process_killed
-  __traceiter_android_vh_revert_creds
   __traceiter_android_vh_record_mutex_lock_starttime
+  __traceiter_android_vh_record_pcpu_rwsem_starttime
+  __traceiter_android_vh_percpu_rwsem_wq_add
   __traceiter_android_vh_record_rtmutex_lock_starttime
   __traceiter_android_vh_record_rwsem_lock_starttime
-  __traceiter_android_vh_record_pcpu_rwsem_starttime
+  __traceiter_android_vh_remove_vmalloc_stack
+  __traceiter_android_vh_revert_creds
   __traceiter_android_vh_rmqueue
+  __traceiter_android_vh_rwsem_can_spin_on_owner
   __traceiter_android_vh_rwsem_init
   __traceiter_android_vh_rwsem_mark_wake_readers
+  __traceiter_android_vh_rwsem_opt_spin_finish
+  __traceiter_android_vh_rwsem_opt_spin_start
   __traceiter_android_vh_rwsem_set_owner
   __traceiter_android_vh_rwsem_set_reader_owned
   __traceiter_android_vh_rwsem_up_read_end
@@ -2879,7 +2904,6 @@
   __traceiter_android_vh_rwsem_write_finished
   __traceiter_android_vh_save_track_hash
   __traceiter_android_vh_save_vmalloc_stack
-  __traceiter_android_vh_remove_vmalloc_stack
   __traceiter_android_vh_sched_stat_runtime_rt
   __traceiter_android_vh_scheduler_tick
   __traceiter_android_vh_selinux_avc_insert
@@ -2895,6 +2919,7 @@
   __traceiter_android_vh_set_module_permit_before_init
   __traceiter_android_vh_setscheduler_uclamp
   __traceiter_android_vh_set_wake_flags
+  __traceiter_android_vh_show_mapcount_pages
   __traceiter_android_vh_show_max_freq
   __traceiter_android_vh_show_resume_epoch_val
   __traceiter_android_vh_show_stack_hash
@@ -2902,6 +2927,7 @@
   __traceiter_android_vh_shrink_node_memcgs
   __traceiter_android_vh_sync_txn_recvd
   __traceiter_android_vh_syscall_prctl_finished
+  __traceiter_android_vh_test_clear_look_around_ref
   __traceiter_android_vh_timer_calc_index
   __traceiter_android_vh_tune_inactive_ratio
   __traceiter_android_vh_tune_scan_type
@@ -2909,6 +2935,7 @@
   __traceiter_android_vh_ufs_compl_command
   __traceiter_android_vh_ufs_send_command
   __traceiter_android_vh_ufs_send_tm_command
+  __traceiter_android_vh_update_page_mapcount
   __traceiter_android_vh_update_topology_flags_workfn
   __traceiter_binder_transaction_received
   __traceiter_cpu_frequency
@@ -2918,6 +2945,10 @@
   __traceiter_ipi_entry
   __traceiter_ipi_raise
   __traceiter_irq_handler_entry
+  __traceiter_net_dev_queue
+  __traceiter_net_dev_xmit
+  __traceiter_netif_receive_skb
+  __traceiter_netif_rx
   __traceiter_pelt_se_tp
   __traceiter_rwmmio_post_read
   __traceiter_rwmmio_read
@@ -2934,14 +2965,13 @@
   __traceiter_suspend_resume
   __traceiter_task_newtask
   __traceiter_task_rename
-  __traceiter_android_vh_test_clear_look_around_ref
   __traceiter_xhci_urb_giveback
   __tracepoint_android_rvh_account_irq
   __tracepoint_android_rvh_after_enqueue_task
   __tracepoint_android_rvh_build_perf_domains
   __tracepoint_android_rvh_can_migrate_task
-  __tracepoint_android_rvh_check_preempt_wakeup
   __tracepoint_android_rvh_check_preempt_tick
+  __tracepoint_android_rvh_check_preempt_wakeup
   __tracepoint_android_rvh_cpu_cgroup_attach
   __tracepoint_android_rvh_cpu_cgroup_online
   __tracepoint_android_rvh_cpu_overutilized
@@ -2998,6 +3028,9 @@
   __tracepoint_android_rvh_v4l2subdev_set_selection
   __tracepoint_android_rvh_wake_up_new_task
   __tracepoint_android_vh_account_task_time
+  __tracepoint_android_vh_add_page_to_lrulist
+  __tracepoint_android_vh_alloc_pages_slowpath_begin
+  __tracepoint_android_vh_alloc_pages_slowpath_end
   __tracepoint_android_vh_allow_domain_state
   __tracepoint_android_vh_alter_futex_plist_add
   __tracepoint_android_vh_alter_mutex_list_add
@@ -3028,11 +3061,23 @@
   __tracepoint_android_vh_check_bpf_syscall
   __tracepoint_android_vh_check_file_open
   __tracepoint_android_vh_check_mmap_file
+  __tracepoint_android_vh_check_page_look_around_ref
   __tracepoint_android_vh_check_uninterruptible_tasks
   __tracepoint_android_vh_check_uninterruptible_tasks_dn
   __tracepoint_android_vh_clear_mask_adjust
   __tracepoint_android_vh_clear_reserved_fmt_fields
   __tracepoint_android_vh_cma_drain_all_pages_bypass
+  __tracepoint_android_vh_compact_finished
+  __tracepoint_android_vh_alloc_pages_reclaim_bypass
+  __tracepoint_android_vh_free_unref_page_bypass
+  __tracepoint_android_vh_kvmalloc_node_use_vmalloc
+  __tracepoint_android_vh_should_alloc_pages_retry
+  __tracepoint_android_vh_unreserve_highatomic_bypass
+  __tracepoint_android_vh_pageset_update
+  __tracepoint_android_vh_rmqueue_bulk_bypass
+  __tracepoint_android_vh_tune_mmap_readaround
+  __tracepoint_android_vh_ra_tuning_max_page
+  __tracepoint_android_vh_cleanup_old_buffers_bypass
   __tracepoint_android_vh_commit_creds
   __tracepoint_android_vh_cpufreq_acct_update_power
   __tracepoint_android_vh_cpufreq_fast_switch
@@ -3041,9 +3086,12 @@
   __tracepoint_android_vh_cpu_idle_enter
   __tracepoint_android_vh_cpu_idle_exit
   __tracepoint_android_vh_cpu_up
-  __tracepoint_android_vh_check_page_look_around_ref
+  __tracepoint_android_vh_del_page_from_lrulist
+  __tracepoint_android_vh_dm_bufio_shrink_scan_bypass
   __tracepoint_android_vh_do_futex
+  __tracepoint_android_vh_do_page_trylock
   __tracepoint_android_vh_do_send_sig_info
+  __tracepoint_android_vh_do_traversal_lruvec
   __tracepoint_android_vh_drain_all_pages_bypass
   __tracepoint_android_vh_em_cpu_energy
   __tracepoint_android_vh_exclude_reserved_zone
@@ -3077,14 +3125,17 @@
   __tracepoint_android_vh_logbuf
   __tracepoint_android_vh_look_around
   __tracepoint_android_vh_look_around_migrate_page
+  __tracepoint_android_vh_madvise_cold_or_pageout_abort
+  __tracepoint_android_vh_mark_page_accessed
   __tracepoint_android_vh_mem_cgroup_alloc
   __tracepoint_android_vh_mem_cgroup_css_offline
   __tracepoint_android_vh_mem_cgroup_css_online
   __tracepoint_android_vh_mem_cgroup_free
   __tracepoint_android_vh_mem_cgroup_id_remove
   __tracepoint_android_vh_meminfo_proc_show
-  __tracepoint_android_vh_alloc_pages_slowpath_begin
-  __tracepoint_android_vh_alloc_pages_slowpath_end
+  __tracepoint_android_vh_mutex_can_spin_on_owner
+  __tracepoint_android_vh_mutex_opt_spin_finish
+  __tracepoint_android_vh_mutex_opt_spin_start
   __tracepoint_android_vh_mutex_unlock_slowpath
   __tracepoint_android_vh_mutex_unlock_slowpath_end
   __tracepoint_android_vh_mutex_wait_finish
@@ -3092,28 +3143,26 @@
   __tracepoint_android_vh_override_creds
   __tracepoint_android_vh_page_referenced_check_bypass
   __tracepoint_android_vh_page_should_be_protected
-  __tracepoint_android_vh_page_trylock_set
   __tracepoint_android_vh_page_trylock_clear
   __tracepoint_android_vh_page_trylock_get_result
-  __tracepoint_android_vh_mark_page_accessed
-  __tracepoint_android_vh_show_mapcount_pages
-  __tracepoint_android_vh_do_traversal_lruvec
-  __tracepoint_android_vh_do_page_trylock
-  __tracepoint_android_vh_update_page_mapcount
-  __tracepoint_android_vh_add_page_to_lrulist
-  __tracepoint_android_vh_del_page_from_lrulist
+  __tracepoint_android_vh_page_trylock_set
   __tracepoint_android_vh_pcplist_add_cma_pages_bypass
   __tracepoint_android_vh_prepare_update_load_avg_se
   __tracepoint_android_vh_printk_hotplug
   __tracepoint_android_vh_process_killed
-  __tracepoint_android_vh_revert_creds
   __tracepoint_android_vh_record_mutex_lock_starttime
+  __tracepoint_android_vh_record_pcpu_rwsem_starttime
+  __tracepoint_android_vh_percpu_rwsem_wq_add
   __tracepoint_android_vh_record_rtmutex_lock_starttime
   __tracepoint_android_vh_record_rwsem_lock_starttime
-  __tracepoint_android_vh_record_pcpu_rwsem_starttime
+  __tracepoint_android_vh_remove_vmalloc_stack
+  __tracepoint_android_vh_revert_creds
   __tracepoint_android_vh_rmqueue
+  __tracepoint_android_vh_rwsem_can_spin_on_owner
   __tracepoint_android_vh_rwsem_init
   __tracepoint_android_vh_rwsem_mark_wake_readers
+  __tracepoint_android_vh_rwsem_opt_spin_finish
+  __tracepoint_android_vh_rwsem_opt_spin_start
   __tracepoint_android_vh_rwsem_set_owner
   __tracepoint_android_vh_rwsem_set_reader_owned
   __tracepoint_android_vh_rwsem_up_read_end
@@ -3123,7 +3172,6 @@
   __tracepoint_android_vh_rwsem_write_finished
   __tracepoint_android_vh_save_track_hash
   __tracepoint_android_vh_save_vmalloc_stack
-  __tracepoint_android_vh_remove_vmalloc_stack
   __tracepoint_android_vh_sched_stat_runtime_rt
   __tracepoint_android_vh_scheduler_tick
   __tracepoint_android_vh_selinux_avc_insert
@@ -3139,6 +3187,7 @@
   __tracepoint_android_vh_set_module_permit_before_init
   __tracepoint_android_vh_setscheduler_uclamp
   __tracepoint_android_vh_set_wake_flags
+  __tracepoint_android_vh_show_mapcount_pages
   __tracepoint_android_vh_show_max_freq
   __tracepoint_android_vh_show_resume_epoch_val
   __tracepoint_android_vh_show_stack_hash
@@ -3146,14 +3195,15 @@
   __tracepoint_android_vh_shrink_node_memcgs
   __tracepoint_android_vh_sync_txn_recvd
   __tracepoint_android_vh_syscall_prctl_finished
+  __tracepoint_android_vh_test_clear_look_around_ref
   __tracepoint_android_vh_timer_calc_index
   __tracepoint_android_vh_tune_inactive_ratio
   __tracepoint_android_vh_tune_scan_type
   __tracepoint_android_vh_tune_swappiness
-  __tracepoint_android_vh_test_clear_look_around_ref
   __tracepoint_android_vh_ufs_compl_command
   __tracepoint_android_vh_ufs_send_command
   __tracepoint_android_vh_ufs_send_tm_command
+  __tracepoint_android_vh_update_page_mapcount
   __tracepoint_android_vh_update_topology_flags_workfn
   __tracepoint_binder_transaction_received
   __tracepoint_cpu_frequency
@@ -3250,6 +3300,9 @@
   ucsi_set_drvdata
   ucsi_unregister
   __udelay
+  __udp4_lib_lookup
+  __udp6_lib_lookup
+  udp_table
   ufshcd_auto_hibern8_update
   ufshcd_delay_us
   ufshcd_dme_get_attr
diff --git a/kernel/android/abi_gki_aarch64_qcom b/kernel/android/abi_gki_aarch64_qcom
index f3e6515..9079fc8 100644
--- a/kernel/android/abi_gki_aarch64_qcom
+++ b/kernel/android/abi_gki_aarch64_qcom
@@ -93,10 +93,10 @@
   blocking_notifier_call_chain
   blocking_notifier_chain_register
   blocking_notifier_chain_unregister
-  bpf_trace_run1
   bpf_trace_run10
   bpf_trace_run11
   bpf_trace_run12
+  bpf_trace_run1
   bpf_trace_run2
   bpf_trace_run3
   bpf_trace_run4
@@ -1431,8 +1431,8 @@
   mempool_free
   mempool_free_slab
   memremap
-  memset
   memset64
+  memset
   __memset_io
   memstart_addr
   memunmap
@@ -1453,8 +1453,8 @@
   mmc_regulator_set_ocr
   mmc_regulator_set_vqmmc
   mmc_select_bus_width
-  mmc_select_hs
   mmc_select_hs400
+  mmc_select_hs
   mmc_select_hs_ddr
   mmc_select_timing
   mmc_send_tuning
@@ -1524,10 +1524,10 @@
   nla_find
   nla_memcpy
   __nla_parse
-  nla_put
   nla_put_64bit
-  nla_reserve
+  nla_put
   nla_reserve_64bit
+  nla_reserve
   __nla_validate
   __nlmsg_put
   no_llseek
@@ -1659,6 +1659,7 @@
   overflowuid
   page_endio
   page_mapping
+  page_owner_inited
   __page_pinner_migration_failed
   __pagevec_release
   panic
@@ -2187,6 +2188,7 @@
   set_normalized_timespec64
   set_page_dirty_lock
   __SetPageMovable
+  __set_page_owner
   set_task_cpu
   set_user_nice
   sg_alloc_table
@@ -2514,6 +2516,7 @@
   __traceiter_android_rvh_cpu_cgroup_online
   __traceiter_android_rvh_cpufreq_transition
   __traceiter_android_rvh_dequeue_task
+  __traceiter_android_rvh_do_ptrauth_fault
   __traceiter_android_rvh_do_sched_yield
   __traceiter_android_rvh_enqueue_task
   __traceiter_android_rvh_find_busiest_queue
@@ -2561,14 +2564,18 @@
   __traceiter_android_rvh_update_misfit_status
   __traceiter_android_rvh_wake_up_new_task
   __traceiter_android_vh_allow_domain_state
+  __traceiter_android_vh_alter_rwsem_list_add
   __traceiter_android_vh_binder_restore_priority
   __traceiter_android_vh_binder_set_priority
   __traceiter_android_vh_binder_transaction_init
   __traceiter_android_vh_binder_wakeup_ilocked
+  __traceiter_android_vh_check_uninterruptible_tasks
+  __traceiter_android_vh_check_uninterruptible_tasks_dn
   __traceiter_android_vh_cpu_idle_enter
   __traceiter_android_vh_cpu_idle_exit
   __traceiter_android_vh_cpuidle_psci_enter
   __traceiter_android_vh_cpuidle_psci_exit
+  __traceiter_android_vh_disable_thermal_cooling_stats
   __traceiter_android_vh_dump_throttled_rt_tasks
   __traceiter_android_vh_freq_table_limits
   __traceiter_android_vh_ftrace_dump_buffer
@@ -2578,18 +2585,26 @@
   __traceiter_android_vh_ftrace_size_check
   __traceiter_android_vh_gic_resume
   __traceiter_android_vh_gpio_block_read
+  __traceiter_android_vh_handle_tlb_conf
   __traceiter_android_vh_iommu_setup_dma_ops
   __traceiter_android_vh_ipi_stop
   __traceiter_android_vh_jiffies_update
   __traceiter_android_vh_logbuf
   __traceiter_android_vh_logbuf_pr_cont
+  __traceiter_android_vh_madvise_cold_or_pageout
+  __traceiter_android_vh_oom_check_panic
   __traceiter_android_vh_printk_hotplug
+  __traceiter_android_vh_process_killed
+  __traceiter_android_vh_psi_event
+  __traceiter_android_vh_psi_group
   __traceiter_android_vh_rproc_recovery
   __traceiter_android_vh_rproc_recovery_set
   __traceiter_android_vh_scheduler_tick
+  __traceiter_android_vh_shmem_alloc_page
   __traceiter_android_vh_show_max_freq
   __traceiter_android_vh_show_resume_epoch_val
   __traceiter_android_vh_show_suspend_epoch_val
+  __traceiter_android_vh_subpage_dma_contig_alloc
   __traceiter_android_vh_timer_calc_index
   __traceiter_android_vh_ufs_check_int_errors
   __traceiter_android_vh_ufs_clock_scaling
@@ -3028,6 +3043,7 @@
   wait_for_completion_interruptible_timeout
   wait_for_completion_killable
   wait_for_completion_timeout
+  wait_for_device_probe
   wait_on_page_bit
   __wait_rcu_gp
   wait_woken
@@ -3045,6 +3061,7 @@
   ww_mutex_lock
   ww_mutex_unlock
   __xa_alloc
+  __xa_alloc_cyclic
   xa_destroy
   xa_erase
   xa_find
diff --git a/kernel/android/abi_gki_aarch64_rockchip b/kernel/android/abi_gki_aarch64_rockchip
index aabe57e..205db14 100644
--- a/kernel/android/abi_gki_aarch64_rockchip
+++ b/kernel/android/abi_gki_aarch64_rockchip
@@ -1638,6 +1638,10 @@
   of_clk_add_hw_provider
   of_clk_hw_simple_get
 
+# required by clk-out.ko
+  __clk_hw_register_gate
+  of_clk_parent_fill
+
 # required by clk-rk628.ko
   devm_reset_controller_register
 
@@ -2705,6 +2709,7 @@
   snd_soc_dapm_new_widgets
 
 # required by snd-soc-rockchip-i2s-tdm.ko
+  clk_has_parent
   clk_is_match
   pm_runtime_forbid
   snd_pcm_stop_xrun
diff --git a/kernel/android/abi_gki_aarch64_transsion b/kernel/android/abi_gki_aarch64_transsion
index 83e28c1..d238c72 100644
--- a/kernel/android/abi_gki_aarch64_transsion
+++ b/kernel/android/abi_gki_aarch64_transsion
@@ -1,74 +1,85 @@
 [abi_symbol_list]
+  check_cache_active
   get_mem_cgroup_from_mm
   is_swap_slot_cache_enabled
-  swapcache_free_entries
-  swap_type_to_swap_info
+  nr_swap_pages
+  plist_del
+  plist_requeue
   scan_swap_map_slots
   swap_alloc_cluster
-  check_cache_active
-  zero_pfn
-  nr_swap_pages
-  plist_requeue
-  plist_del
+  swapcache_free_entries
+  swap_type_to_swap_info
+  blkcg_schedule_throttle
+  __traceiter_android_rvh_alloc_si
+  __traceiter_android_rvh_alloc_swap_slot_cache
+  __traceiter_android_rvh_drain_slots_cache_cpu
+  __traceiter_android_rvh_free_swap_slot
+  __traceiter_android_rvh_get_swap_page
   __traceiter_android_rvh_handle_pte_fault_end
-  __traceiter_android_vh_handle_pte_fault_end
-  __traceiter_android_vh_cow_user_page
-  __traceiter_android_vh_swapin_add_anon_rmap
-  __traceiter_android_vh_waiting_for_page_migration
-  __traceiter_android_vh_migrate_page_states
-  __traceiter_android_vh_page_referenced_one_end
+  __traceiter_android_vh_add_to_avail_list
+  __traceiter_android_vh_del_from_avail_list
+  __traceiter_android_vh___cgroup_throttle_swaprate
+  __traceiter_android_vh_account_swap_pages
+  __traceiter_android_vh_alloc_si
+  __traceiter_android_vh_alloc_swap_slot_cache
   __traceiter_android_vh_count_pswpin
   __traceiter_android_vh_count_pswpout
   __traceiter_android_vh_count_swpout_vm_event
-  __traceiter_android_vh_swap_slot_cache_active
-  __traceiter_android_rvh_drain_slots_cache_cpu
+  __traceiter_android_vh_cow_user_page
   __traceiter_android_vh_drain_slots_cache_cpu
-  __traceiter_android_rvh_alloc_swap_slot_cache
-  __traceiter_android_vh_alloc_swap_slot_cache
-  __traceiter_android_rvh_free_swap_slot
-  __traceiter_android_vh_free_swap_slot
-  __traceiter_android_rvh_get_swap_page
-  __traceiter_android_vh_get_swap_page
-  __traceiter_android_vh_page_isolated_for_reclaim
-  __traceiter_android_vh_inactive_is_low
-  __traceiter_android_vh_snapshot_refaults
-  __traceiter_android_vh_account_swap_pages
-  __traceiter_android_vh_unuse_swap_page
-  __traceiter_android_vh_init_swap_info_struct
-  __traceiter_android_vh_si_swapinfo
-  __traceiter_android_rvh_alloc_si
-  __traceiter_android_vh_alloc_si
   __traceiter_android_vh_free_pages
-  __traceiter_android_vh_set_shmem_page_flag
+  __traceiter_android_vh_free_swap_slot
+  __traceiter_android_vh_get_swap_page
+  __traceiter_android_vh_handle_pte_fault_end
+  __traceiter_android_vh_inactive_is_low
+  __traceiter_android_vh_swap_avail_heads_init
+  __traceiter_android_vh_init_swap_info_struct
+  __traceiter_android_vh_migrate_page_states
+  __traceiter_android_vh_page_isolated_for_reclaim
+  __traceiter_android_vh_page_referenced_one_end
   __traceiter_android_vh_ra_tuning_max_page
+  __traceiter_android_vh_set_shmem_page_flag
+  __traceiter_android_vh_si_swapinfo
+  __traceiter_android_vh_snapshot_refaults
+  __traceiter_android_vh_swapin_add_anon_rmap
+  __traceiter_android_vh_swap_slot_cache_active
+  __traceiter_android_vh_unuse_swap_page
+  __traceiter_android_vh_waiting_for_page_migration
+  __traceiter_android_vh_should_end_madvise
+  __tracepoint_android_rvh_alloc_si
+  __tracepoint_android_rvh_alloc_swap_slot_cache
+  __tracepoint_android_rvh_drain_slots_cache_cpu
+  __tracepoint_android_rvh_free_swap_slot
+  __tracepoint_android_rvh_get_swap_page
   __tracepoint_android_rvh_handle_pte_fault_end
-  __tracepoint_android_vh_handle_pte_fault_end
-  __tracepoint_android_vh_cow_user_page
-  __tracepoint_android_vh_swapin_add_anon_rmap
-  __tracepoint_android_vh_waiting_for_page_migration
-  __tracepoint_android_vh_migrate_page_states
-  __tracepoint_android_vh_page_referenced_one_end
+  __tracepoint_android_vh_add_to_avail_list
+  __tracepoint_android_vh_del_from_avail_list
+  __tracepoint_android_vh___cgroup_throttle_swaprate
+  __tracepoint_android_vh_account_swap_pages
+  __tracepoint_android_vh_alloc_si
+  __tracepoint_android_vh_alloc_swap_slot_cache
   __tracepoint_android_vh_count_pswpin
   __tracepoint_android_vh_count_pswpout
   __tracepoint_android_vh_count_swpout_vm_event
-  __tracepoint_android_vh_swap_slot_cache_active
-  __tracepoint_android_rvh_drain_slots_cache_cpu
+  __tracepoint_android_vh_cow_user_page
   __tracepoint_android_vh_drain_slots_cache_cpu
-  __tracepoint_android_rvh_alloc_swap_slot_cache
-  __tracepoint_android_vh_alloc_swap_slot_cache
-  __tracepoint_android_rvh_free_swap_slot
-  __tracepoint_android_vh_free_swap_slot
-  __tracepoint_android_rvh_get_swap_page
-  __tracepoint_android_vh_get_swap_page
-  __tracepoint_android_vh_page_isolated_for_reclaim
-  __tracepoint_android_vh_inactive_is_low
-  __tracepoint_android_vh_snapshot_refaults
-  __tracepoint_android_vh_account_swap_pages
-  __tracepoint_android_vh_unuse_swap_page
-  __tracepoint_android_vh_init_swap_info_struct
-  __tracepoint_android_vh_si_swapinfo
-  __tracepoint_android_rvh_alloc_si
-  __tracepoint_android_vh_alloc_si
   __tracepoint_android_vh_free_pages
-  __tracepoint_android_vh_set_shmem_page_flag
+  __tracepoint_android_vh_free_swap_slot
+  __tracepoint_android_vh_get_swap_page
+  __tracepoint_android_vh_handle_pte_fault_end
+  __tracepoint_android_vh_inactive_is_low
+  __tracepoint_android_vh_swap_avail_heads_init
+  __tracepoint_android_vh_init_swap_info_struct
+  __tracepoint_android_vh_migrate_page_states
+  __tracepoint_android_vh_page_isolated_for_reclaim
+  __tracepoint_android_vh_page_referenced_one_end
   __tracepoint_android_vh_ra_tuning_max_page
+  __tracepoint_android_vh_set_shmem_page_flag
+  __tracepoint_android_vh_si_swapinfo
+  __tracepoint_android_vh_snapshot_refaults
+  __tracepoint_android_vh_swapin_add_anon_rmap
+  __tracepoint_android_vh_swap_slot_cache_active
+  __tracepoint_android_vh_unuse_swap_page
+  __tracepoint_android_vh_waiting_for_page_migration
+  __tracepoint_android_vh_should_end_madvise
+  zero_pfn
diff --git a/kernel/android/abi_gki_aarch64_type_visibility b/kernel/android/abi_gki_aarch64_type_visibility
index 705bf55..97a077f 100644
--- a/kernel/android/abi_gki_aarch64_type_visibility
+++ b/kernel/android/abi_gki_aarch64_type_visibility
@@ -1,6 +1,6 @@
 [abi_symbol_list]
 
 # for type visibility
-  GKI_struct_selinux_state
   GKI_struct_gic_chip_data
+  GKI_struct_selinux_state
   GKI_struct_swap_slots_cache
diff --git a/kernel/android/abi_gki_aarch64_unisoc b/kernel/android/abi_gki_aarch64_unisoc
index d065398..ec06183 100644
--- a/kernel/android/abi_gki_aarch64_unisoc
+++ b/kernel/android/abi_gki_aarch64_unisoc
@@ -254,6 +254,9 @@
   __tasklet_schedule
   thermal_zone_device_disable
   thermal_zone_device_enable
+  __traceiter_rwmmio_post_read
+  __traceiter_rwmmio_read
+  __traceiter_rwmmio_write
   __tracepoint_rwmmio_post_read
   __tracepoint_rwmmio_read
   __tracepoint_rwmmio_write
diff --git a/kernel/android/abi_gki_aarch64_virtual_device b/kernel/android/abi_gki_aarch64_virtual_device
index 6929833..034100b 100644
--- a/kernel/android/abi_gki_aarch64_virtual_device
+++ b/kernel/android/abi_gki_aarch64_virtual_device
@@ -211,8 +211,12 @@
   kstrndup
   kstrtobool
   kstrtoint
+  kstrtoll
   kstrtouint
   kstrtoull
+  kthread_create_on_node
+  kthread_should_stop
+  kthread_stop
   ktime_get
   ktime_get_mono_fast_ns
   ktime_get_raw_ts64
@@ -307,6 +311,10 @@
   __per_cpu_offset
   perf_trace_buf_alloc
   perf_trace_run_bpf_submit
+  platform_device_add
+  platform_device_alloc
+  platform_device_del
+  platform_device_put
   platform_device_register_full
   platform_device_unregister
   __platform_driver_register
@@ -350,7 +358,6 @@
   __rcu_read_unlock
   refcount_warn_saturate
   register_blkdev
-  register_netdev
   register_netdevice
   register_netdevice_notifier
   register_pernet_device
@@ -448,12 +455,14 @@
   sscanf
   __stack_chk_fail
   __stack_chk_guard
+  strchr
   strcmp
   strcpy
   strlcpy
   strlen
   strncmp
   strncpy
+  strscpy
   strsep
   submit_bio
   __sw_hweight16
@@ -465,7 +474,6 @@
   synchronize_rcu
   sysfs_create_group
   sysfs_create_link
-  __sysfs_match_string
   sysfs_remove_group
   sysfs_remove_link
   system_freezable_wq
@@ -514,8 +522,11 @@
   usleep_range
   vabits_actual
   vfree
+  virtio_break_device
   virtio_check_driver_offered_feature
   virtio_config_changed
+  virtio_device_freeze
+  virtio_device_restore
   virtqueue_add_inbuf
   virtqueue_add_outbuf
   virtqueue_add_sgs
@@ -531,12 +542,14 @@
   virtqueue_kick
   virtqueue_kick_prepare
   virtqueue_notify
+  vmalloc_to_page
   vring_create_virtqueue
   vring_del_virtqueue
   vring_interrupt
   vring_transport_features
   wait_for_completion
   __wake_up
+  wake_up_process
   __warn_printk
 
 # required by ambakmi.ko
@@ -711,7 +724,6 @@
   set_page_dirty
 
 # required by goldfish_sync.ko
-  __close_fd
   dma_fence_default_wait
   dma_fence_free
 
@@ -821,7 +833,6 @@
   simple_attr_open
   simple_attr_release
   __skb_ext_put
-  skb_unlink
 
 # required by md-mod.ko
   ack_all_badblocks
@@ -867,22 +878,12 @@
   kernfs_put
   kobject_del
   kobject_get
-  kstrtoll
-  kthread_create_on_node
   kthread_parkme
   kthread_should_park
-  kthread_should_stop
-  kthread_stop
-  mempool_alloc
   mempool_create
   mempool_destroy
-  mempool_exit
-  mempool_free
-  mempool_init
   mempool_kfree
   mempool_kmalloc
-  part_end_io_acct
-  part_start_io_acct
   percpu_ref_exit
   percpu_ref_init
   percpu_ref_is_zero
@@ -902,7 +903,6 @@
   unregister_reboot_notifier
   unregister_sysctl_table
   vfs_fsync
-  wake_up_process
 
 # required by nd_virtio.ko
   bio_chain
@@ -923,6 +923,7 @@
   netdev_lower_state_changed
   netdev_pick_tx
   pci_bus_type
+  register_netdev
 
 # required by psmouse.ko
   bus_register_notifier
@@ -969,16 +970,11 @@
   cec_s_phys_addr
   cec_transmit_attempt_done_ts
   cec_unregister_adapter
-  strscpy
   wait_for_completion_timeout
 
 # required by rtc-test.ko
   add_timer
   devm_rtc_allocate_device
-  platform_device_add
-  platform_device_alloc
-  platform_device_del
-  platform_device_put
   __rtc_register_device
   rtc_time64_to_tm
   rtc_tm_to_time64
@@ -1002,9 +998,9 @@
   strcat
 
 # required by snd-hda-codec-generic.ko
-  devm_led_classdev_register_ext
+  led_classdev_register_ext
+  led_classdev_unregister
   snd_ctl_boolean_stereo_info
-  strchr
   strlcat
 
 # required by snd-hda-codec.ko
@@ -1106,6 +1102,9 @@
   compat_ptr_ioctl
 
 # required by usbip-core.ko
+  iov_iter_kvec
+  param_ops_ulong
+  print_hex_dump
   sock_recvmsg
 
 # required by vcan.ko
@@ -1128,9 +1127,27 @@
   devm_mfd_add_devices
 
 # required by vhci-hcd.ko
+  kernel_sendmsg
   kernel_sock_shutdown
   platform_bus
+  platform_device_add_data
   sockfd_lookup
+  usb_add_hcd
+  usb_create_hcd
+  usb_create_shared_hcd
+  usb_disabled
+  usb_get_dev
+  usb_hcd_check_unlink_urb
+  usb_hcd_giveback_urb
+  usb_hcd_is_primary_hcd
+  usb_hcd_link_urb_to_ep
+  usb_hcd_poll_rh_status
+  usb_hcd_resume_root_hub
+  usb_hcd_unlink_urb_from_ep
+  usb_put_dev
+  usb_put_hcd
+  usb_remove_hcd
+  usb_speed_string
 
 # required by virt_wifi.ko
   __module_get
@@ -1259,7 +1276,6 @@
   __traceiter_gpu_mem_total
   __tracepoint_dma_fence_emit
   __tracepoint_gpu_mem_total
-  vmalloc_to_page
   vmemdup_user
   vm_get_page_prot
   ww_mutex_lock_interruptible
@@ -1309,6 +1325,7 @@
   __blk_rq_map_sg
   set_capacity_revalidate_and_notify
   string_get_size
+  __sysfs_match_string
   virtio_max_dma_size
 
 # required by virtio_console.ko
@@ -1412,9 +1429,6 @@
   pci_request_selected_regions
   pci_vfs_assigned
   synchronize_irq
-  virtio_break_device
-  virtio_device_freeze
-  virtio_device_restore
 
 # required by virtio_pmem.ko
   nvdimm_bus_register
@@ -1422,14 +1436,8 @@
   nvdimm_pmem_region_create
 
 # required by virtio_snd.ko
-  snd_ctl_notify
   snd_pcm_format_physical_width
-  snd_pcm_lib_free_pages
   snd_pcm_lib_ioctl
-  snd_pcm_lib_malloc_pages
-  snd_pcm_lib_preallocate_pages
-  _snd_pcm_stream_lock_irqsave
-  snd_pcm_stream_unlock_irqrestore
   wait_for_completion_interruptible_timeout
 
 # required by vmw_vsock_virtio_transport.ko
@@ -1489,9 +1497,27 @@
 # required by zsmalloc.ko
   dec_zone_page_state
   inc_zone_page_state
-  __lock_page
   page_mapping
   _raw_read_lock
   _raw_read_unlock
   _raw_write_lock
   _raw_write_unlock
+  wait_on_page_bit
+
+# preserved by --additions-only
+  __close_fd
+  devm_led_classdev_register_ext
+  __lock_page
+  mempool_alloc
+  mempool_exit
+  mempool_free
+  mempool_init
+  part_end_io_acct
+  part_start_io_acct
+  skb_unlink
+  snd_ctl_notify
+  snd_pcm_lib_free_pages
+  snd_pcm_lib_malloc_pages
+  snd_pcm_lib_preallocate_pages
+  _snd_pcm_stream_lock_irqsave
+  snd_pcm_stream_unlock_irqrestore
diff --git a/kernel/android/abi_gki_aarch64_vivo b/kernel/android/abi_gki_aarch64_vivo
index 28c4b05..9143afa 100644
--- a/kernel/android/abi_gki_aarch64_vivo
+++ b/kernel/android/abi_gki_aarch64_vivo
@@ -84,9 +84,9 @@
   blocking_notifier_call_chain
   blocking_notifier_chain_register
   blocking_notifier_chain_unregister
-  bpf_trace_run1
   bpf_trace_run10
   bpf_trace_run12
+  bpf_trace_run1
   bpf_trace_run2
   bpf_trace_run3
   bpf_trace_run4
@@ -938,8 +938,8 @@
   mempool_free
   mempool_free_slab
   memremap
-  memset
   memset64
+  memset
   __memset_io
   memstart_addr
   memunmap
@@ -975,8 +975,8 @@
   __next_zones_zonelist
   nla_find
   nla_put
-  nla_reserve
   nla_reserve_64bit
+  nla_reserve
   __nla_validate
   __nlmsg_put
   no_llseek
@@ -1687,6 +1687,7 @@
   __traceiter_android_rvh_flush_task
   __traceiter_android_rvh_migrate_queued_task
   __traceiter_android_rvh_new_task_stats
+  __traceiter_android_rvh_refrigerator
   __traceiter_android_rvh_replace_next_task_fair
   __traceiter_android_rvh_resume_cpus
   __traceiter_android_rvh_sched_cpu_dying
@@ -1704,22 +1705,30 @@
   __traceiter_android_rvh_set_readahead_gfp_mask
   __traceiter_android_rvh_set_skip_swapcache_flags
   __traceiter_android_rvh_set_task_cpu
+  __traceiter_android_rvh_tcp_recvmsg
+  __traceiter_android_rvh_tcp_recvmsg_stat
+  __traceiter_android_rvh_tcp_sendmsg_locked
   __traceiter_android_rvh_tick_entry
   __traceiter_android_rvh_try_to_wake_up
   __traceiter_android_rvh_try_to_wake_up_success
   __traceiter_android_rvh_ttwu_cond
+  __traceiter_android_rvh_udp_recvmsg
+  __traceiter_android_rvh_udp_sendmsg
   __traceiter_android_rvh_update_cpu_capacity
   __traceiter_android_rvh_update_cpus_allowed
   __traceiter_android_rvh_update_misfit_status
   __traceiter_android_rvh_wake_up_new_task
+  __traceiter_android_vh_account_task_time
   __traceiter_android_vh_allow_domain_state
   __traceiter_android_vh_binder_restore_priority
   __traceiter_android_vh_binder_set_priority
+  __traceiter_android_vh_binder_trans
   __traceiter_android_vh_binder_wakeup_ilocked
   __traceiter_android_vh_blk_alloc_rqs
   __traceiter_android_vh_blk_rq_ctx_init
   __traceiter_android_vh_cpu_idle_enter
   __traceiter_android_vh_cpu_idle_exit
+  __traceiter_android_vh_dup_task_struct
   __traceiter_android_vh_filemap_fault_cache_page
   __traceiter_android_vh_filemap_fault_get_page
   __traceiter_android_vh_ftrace_dump_buffer
@@ -1729,6 +1738,7 @@
   __traceiter_android_vh_ftrace_size_check
   __traceiter_android_vh_iommu_setup_dma_ops
   __traceiter_android_vh_ipi_stop
+  __traceiter_android_vh_irqtime_account_process_tick
   __traceiter_android_vh_jiffies_update
   __traceiter_android_vh_mmap_region
   __traceiter_android_vh_mmc_attach_sd
@@ -1746,10 +1756,13 @@
   __traceiter_android_vh_shrink_slab_bypass
   __traceiter_android_vh_timer_calc_index
   __traceiter_android_vh_try_to_unmap_one
+  __traceiter_android_vh_tune_scan_type
+  __traceiter_android_vh_tune_swappiness
   __traceiter_android_vh_ufs_check_int_errors
   __traceiter_android_vh_ufs_compl_command
   __traceiter_android_vh_ufs_send_command
   __traceiter_android_vh_ufs_update_sdev
+  __traceiter_android_vh_vmpressure
   __traceiter_binder_transaction_received
   __traceiter_block_bio_complete
   __traceiter_block_bio_queue
diff --git a/kernel/android/abi_gki_aarch64_xiaomi b/kernel/android/abi_gki_aarch64_xiaomi
index ebbbb0e..b3b2d86 100644
--- a/kernel/android/abi_gki_aarch64_xiaomi
+++ b/kernel/android/abi_gki_aarch64_xiaomi
@@ -2,8 +2,8 @@
 # commonly used symbols
 
 # required by touch module
-  proc_mkdir_data
   proc_create_seq_private
+  proc_mkdir_data
 
 # required by aw8697-haptic.ko
   devm_gpio_free
@@ -11,36 +11,43 @@
   i2c_smbus_write_byte_data
 
 #required by memory module
-  blk_execute_rq
-  blk_rq_map_kern
-  scsi_device_lookup
-  scsi_host_lookup
-  scsi_host_put
-  ufshcd_read_desc_param
-  utf16s_to_utf8s
   async_schedule_node
+  blk_execute_rq
+  blk_ksm_get_slot_idx
   blk_ksm_register
   blk_ksm_reprogram_all_keys
   blk_mq_alloc_tag_set
+  blk_mq_free_tag_set
   blk_mq_init_queue
   blk_mq_tagset_busy_iter
+  blk_queue_update_dma_alignment
+  blk_queue_update_dma_pad
+  blk_rq_map_kern
   bsg_job_done
   bsg_remove_queue
   bsg_setup_queue
   dev_pm_opp_remove
+  mempool_alloc_pages
+  mempool_free_pages
+  mempool_resize
+  __scsi_add_device
   scsi_add_host_with_dma
   scsi_block_requests
+  scsi_change_queue_depth
+  scsi_device_lookup
+  scsi_dma_map
   scsi_dma_unmap
+  __scsi_execute
+  scsi_host_alloc
+  scsi_host_lookup
+  scsi_host_put
   scsi_is_host_device
+  scsi_normalize_sense
+  scsi_print_command
   scsi_remove_host
   scsi_report_bus_reset
   scsi_scan_host
   scsi_unblock_requests
-  scsi_change_queue_depth
-  scsi_print_command
-  scsi_dma_map
-  scsi_host_alloc
-  scsi_normalize_sense
   sg_copy_from_buffer
   sg_copy_to_buffer
   ufshcd_alloc_host
@@ -51,44 +58,48 @@
   ufshcd_map_desc_id_to_length
   ufshcd_query_attr_retry
   ufshcd_query_flag_retry
+  ufshcd_read_desc_param
   ufshcd_update_evt_hist
+  utf16s_to_utf8s
   wait_for_completion_io_timeout
-  __scsi_add_device
-  __scsi_execute
-  blk_mq_free_tag_set
-  blk_queue_update_dma_alignment
-  blk_queue_update_dma_pad
-  blk_ksm_get_slot_idx
-  mempool_resize
-  mempool_alloc_pages
-  mempool_free_pages
+  nr_free_buffer_pages
+  mmc_set_blocklen
+
+#required by mq-deadline module
+  blk_mq_debugfs_rq_show
+  seq_list_start
+  seq_list_next
+  __blk_mq_debugfs_rq_show
 
 #required by cs35l41 module
-  regmap_raw_write_async
-  snd_soc_bytes_tlv_callback
+  regcache_drop_region
   regmap_async_complete
+  regmap_multi_reg_write
+  regmap_multi_reg_write_bypassed
+  regmap_raw_read
+  regmap_raw_write
+  regmap_raw_write_async
+  regulator_bulk_enable
   snd_compr_stop_error
-  snd_soc_component_disable_pin
-  snd_soc_component_force_enable_pin
+  snd_ctl_boolean_mono_info
   snd_pcm_format_physical_width
   snd_pcm_hw_constraint_list
-  regmap_multi_reg_write_bypassed
-  snd_ctl_boolean_mono_info
-  snd_soc_put_volsw_range
+  snd_soc_bytes_tlv_callback
+  snd_soc_component_disable_pin
+  snd_soc_component_force_enable_pin
   snd_soc_get_volsw_range
   snd_soc_info_volsw_range
-  regmap_raw_write
-  regcache_drop_region
-  regmap_raw_read
-  regmap_multi_reg_write
-  regulator_bulk_enable
+  snd_soc_put_volsw_range
 
 #required by mtd module
-  __blk_mq_end_request
   balance_dirty_pages_ratelimited
   bdi_alloc
   bdi_put
   bdi_register
+  blkdev_get_by_dev
+  blkdev_get_by_path
+  blkdev_put
+  __blk_mq_end_request
   blk_mq_freeze_queue
   blk_mq_init_sq_queue
   blk_mq_quiesce_queue
@@ -97,9 +108,6 @@
   blk_mq_unquiesce_queue
   blk_queue_write_cache
   blk_update_request
-  blkdev_get_by_dev
-  blkdev_get_by_path
-  blkdev_put
   deactivate_locked_super
   fixed_size_llseek
   generic_shutdown_super
@@ -126,42 +134,42 @@
 
 #required by millet.ko
   freezer_cgrp_subsys
-  __traceiter_android_vh_do_send_sig_info
-  __traceiter_android_vh_binder_preset
-  __traceiter_android_vh_binder_wait_for_work
-  __traceiter_android_vh_binder_trans
-  __traceiter_android_vh_binder_reply
   __traceiter_android_vh_binder_alloc_new_buf_locked
-  __tracepoint_android_vh_do_send_sig_info
-  __tracepoint_android_vh_binder_preset
-  __tracepoint_android_vh_binder_wait_for_work
-  __tracepoint_android_vh_binder_trans
-  __tracepoint_android_vh_binder_reply
+  __traceiter_android_vh_binder_preset
+  __traceiter_android_vh_binder_reply
+  __traceiter_android_vh_binder_trans
+  __traceiter_android_vh_binder_wait_for_work
+  __traceiter_android_vh_do_send_sig_info
   __tracepoint_android_vh_binder_alloc_new_buf_locked
+  __tracepoint_android_vh_binder_preset
+  __tracepoint_android_vh_binder_reply
+  __tracepoint_android_vh_binder_trans
+  __tracepoint_android_vh_binder_wait_for_work
+  __tracepoint_android_vh_do_send_sig_info
 
 #required by mi_sched.ko
+  find_user
+  free_uid
+  jiffies_64
   __traceiter_android_vh_free_task
   __tracepoint_android_vh_free_task
-  jiffies_64
-  free_uid
-  find_user
 
 #required by migt.ko
-  __traceiter_android_rvh_after_enqueue_task
   __traceiter_android_rvh_after_dequeue_task
+  __traceiter_android_rvh_after_enqueue_task
   __traceiter_android_vh_map_util_freq
-  __tracepoint_android_rvh_after_enqueue_task
   __tracepoint_android_rvh_after_dequeue_task
+  __tracepoint_android_rvh_after_enqueue_task
   __tracepoint_android_vh_map_util_freq
 
 #required by turbo.ko
+  cpuset_cpus_allowed
+  __traceiter_android_rvh_cpuset_fork
   __traceiter_android_rvh_set_cpus_allowed_comm
   __traceiter_android_vh_sched_setaffinity_early
-  __traceiter_android_rvh_cpuset_fork
+  __tracepoint_android_rvh_cpuset_fork
   __tracepoint_android_rvh_set_cpus_allowed_comm
   __tracepoint_android_vh_sched_setaffinity_early
-  __tracepoint_android_rvh_cpuset_fork
-  cpuset_cpus_allowed
 
 #required by fas.ko
   __traceiter_android_rvh_check_preempt_tick
@@ -175,15 +183,15 @@
   console_printk
 
 #required by binderinfo.ko module
-  __traceiter_android_vh_binder_transaction_init
   __traceiter_android_vh_binder_print_transaction_info
-  __tracepoint_android_vh_binder_transaction_init
+  __traceiter_android_vh_binder_transaction_init
   __tracepoint_android_vh_binder_print_transaction_info
+  __tracepoint_android_vh_binder_transaction_init
 
 #required by reclaim module
   __traceiter_android_vh_tune_scan_type
-  __tracepoint_android_vh_tune_scan_type
   __traceiter_android_vh_tune_swappiness
+  __tracepoint_android_vh_tune_scan_type
   __tracepoint_android_vh_tune_swappiness
 
 #required by msm_drm.ko module
@@ -198,13 +206,19 @@
 ##required by xm_power_debug.ko module
   wakeup_sources_read_lock
   wakeup_sources_read_unlock
-  wakeup_sources_walk_start
   wakeup_sources_walk_next
+  wakeup_sources_walk_start
 
 #required by mi_mempool.ko module
-  __traceiter_android_vh_mmput
-  __tracepoint_android_vh_mmput
-  __traceiter_android_vh_alloc_pages_reclaim_bypass
-  __tracepoint_android_vh_alloc_pages_reclaim_bypass
   __traceiter_android_vh_alloc_pages_failure_bypass
+  __traceiter_android_vh_alloc_pages_reclaim_bypass
+  __traceiter_android_vh_mmput
   __tracepoint_android_vh_alloc_pages_failure_bypass
+  __tracepoint_android_vh_alloc_pages_reclaim_bypass
+  __tracepoint_android_vh_mmput
+
+#required by us_prox.ko module
+  iio_trigger_alloc
+  iio_trigger_free
+  __iio_trigger_register
+  iio_trigger_unregister
diff --git a/kernel/android/abi_gki_aarch64_zebra b/kernel/android/abi_gki_aarch64_zebra
new file mode 100644
index 0000000..59367a2
--- /dev/null
+++ b/kernel/android/abi_gki_aarch64_zebra
@@ -0,0 +1,4 @@
+[abi_symbol_list]
+  __traceiter_android_vh_wakeup_bypass
+  __tracepoint_android_vh_wakeup_bypass
+  tty_termios_hw_change
diff --git a/kernel/arch/Kconfig b/kernel/arch/Kconfig
index c3a40c5..3ca6e93 100644
--- a/kernel/arch/Kconfig
+++ b/kernel/arch/Kconfig
@@ -290,6 +290,9 @@
 config ARCH_HAS_DMA_CLEAR_UNCACHED
 	bool
 
+config ARCH_HAS_CPU_FINALIZE_INIT
+	bool
+
 # Select if arch init_task must go in the __init_task_data section
 config ARCH_TASK_STRUCT_ON_STACK
 	bool
diff --git a/kernel/arch/alpha/boot/tools/objstrip.c b/kernel/arch/alpha/boot/tools/objstrip.c
index 08b430d..7cf92d1 100644
--- a/kernel/arch/alpha/boot/tools/objstrip.c
+++ b/kernel/arch/alpha/boot/tools/objstrip.c
@@ -148,7 +148,7 @@
 #ifdef __ELF__
     elf = (struct elfhdr *) buf;
 
-    if (elf->e_ident[0] == 0x7f && str_has_prefix((char *)elf->e_ident + 1, "ELF")) {
+    if (memcmp(&elf->e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0) {
 	if (elf->e_type != ET_EXEC) {
 	    fprintf(stderr, "%s: %s is not an ELF executable\n",
 		    prog_name, inname);
diff --git a/kernel/arch/alpha/include/asm/bugs.h b/kernel/arch/alpha/include/asm/bugs.h
deleted file mode 100644
index 78030d1..0000000
--- a/kernel/arch/alpha/include/asm/bugs.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *  include/asm-alpha/bugs.h
- *
- *  Copyright (C) 1994  Linus Torvalds
- */
-
-/*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Needs:
- *	void check_bugs(void);
- */
-
-/*
- * I don't know of any alpha bugs yet.. Nice chip
- */
-
-static void check_bugs(void)
-{
-}
diff --git a/kernel/arch/alpha/include/asm/pgtable.h b/kernel/arch/alpha/include/asm/pgtable.h
index 660b14c..12c120e 100644
--- a/kernel/arch/alpha/include/asm/pgtable.h
+++ b/kernel/arch/alpha/include/asm/pgtable.h
@@ -241,8 +241,10 @@
 #define pud_page(pud)	(mem_map + ((pud_val(pud) & _PFN_MASK) >> 32))
 #endif
 
-extern inline unsigned long pud_page_vaddr(pud_t pgd)
-{ return PAGE_OFFSET + ((pud_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT)); }
+extern inline pmd_t *pud_pgtable(pud_t pgd)
+{
+	return (pmd_t *)(PAGE_OFFSET + ((pud_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT)));
+}
 
 extern inline int pte_none(pte_t pte)		{ return !pte_val(pte); }
 extern inline int pte_present(pte_t pte)	{ return pte_val(pte) & _PAGE_VALID; }
@@ -292,7 +294,7 @@
 /* Find an entry in the second-level page table.. */
 extern inline pmd_t * pmd_offset(pud_t * dir, unsigned long address)
 {
-	pmd_t *ret = (pmd_t *) pud_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
+	pmd_t *ret = pud_pgtable(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
 	smp_rmb(); /* see above */
 	return ret;
 }
diff --git a/kernel/arch/alpha/include/uapi/asm/socket.h b/kernel/arch/alpha/include/uapi/asm/socket.h
index de6c4df..d033d3f 100644
--- a/kernel/arch/alpha/include/uapi/asm/socket.h
+++ b/kernel/arch/alpha/include/uapi/asm/socket.h
@@ -124,6 +124,8 @@
 
 #define SO_DETACH_REUSEPORT_BPF 68
 
+#define SO_NETNS_COOKIE		71
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64
diff --git a/kernel/arch/alpha/kernel/entry.S b/kernel/arch/alpha/kernel/entry.S
index e227f3a..c41a5a9 100644
--- a/kernel/arch/alpha/kernel/entry.S
+++ b/kernel/arch/alpha/kernel/entry.S
@@ -469,8 +469,10 @@
 #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
diff --git a/kernel/arch/alpha/kernel/module.c b/kernel/arch/alpha/kernel/module.c
index 5b60c24..cbefa5a 100644
--- a/kernel/arch/alpha/kernel/module.c
+++ b/kernel/arch/alpha/kernel/module.c
@@ -146,10 +146,8 @@
 	base = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr;
 	symtab = (Elf64_Sym *)sechdrs[symindex].sh_addr;
 
-	/* The small sections were sorted to the end of the segment.
-	   The following should definitely cover them.  */
-	gp = (u64)me->core_layout.base + me->core_layout.size - 0x8000;
 	got = sechdrs[me->arch.gotsecindex].sh_addr;
+	gp = got + 0x8000;
 
 	for (i = 0; i < n; i++) {
 		unsigned long r_sym = ELF64_R_SYM (rela[i].r_info);
diff --git a/kernel/arch/alpha/kernel/setup.c b/kernel/arch/alpha/kernel/setup.c
index 7eea28d..490a161 100644
--- a/kernel/arch/alpha/kernel/setup.c
+++ b/kernel/arch/alpha/kernel/setup.c
@@ -394,8 +394,7 @@
 extern void setup_memory(void *);
 #endif /* !CONFIG_DISCONTIGMEM */
 
-int __init
-page_is_ram(unsigned long pfn)
+int page_is_ram(unsigned long pfn)
 {
 	struct memclust_struct * cluster;
 	struct memdesc_struct * memdesc;
diff --git a/kernel/arch/alpha/kernel/traps.c b/kernel/arch/alpha/kernel/traps.c
index 921d4b6..751d319 100644
--- a/kernel/arch/alpha/kernel/traps.c
+++ b/kernel/arch/alpha/kernel/traps.c
@@ -192,7 +192,7 @@
 		local_irq_enable();
 		while (1);
 	}
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
 
 #ifndef CONFIG_MATHEMU
@@ -235,7 +235,21 @@
 {
 	int signo, code;
 
-	if ((regs->ps & ~IPL_MAX) == 0) {
+	if (type == 3) { /* FEN fault */
+		/* Irritating users can call PAL_clrfen to disable the
+		   FPU for the process.  The kernel will then trap in
+		   do_switch_stack and undo_switch_stack when we try
+		   to save and restore the FP registers.
+
+		   Given that GCC by default generates code that uses the
+		   FP registers, PAL_clrfen is not useful except for DoS
+		   attacks.  So turn the bleeding FPU back on and be done
+		   with it.  */
+		current_thread_info()->pcb.flags |= 1;
+		__reload_thread(&current_thread_info()->pcb);
+		return;
+	}
+	if (!user_mode(regs)) {
 		if (type == 1) {
 			const unsigned int *data
 			  = (const unsigned int *) regs->pc;
@@ -367,20 +381,6 @@
 			}
 		}
 		break;
-
-	      case 3: /* FEN fault */
-		/* Irritating users can call PAL_clrfen to disable the
-		   FPU for the process.  The kernel will then trap in
-		   do_switch_stack and undo_switch_stack when we try
-		   to save and restore the FP registers.
-
-		   Given that GCC by default generates code that uses the
-		   FP registers, PAL_clrfen is not useful except for DoS
-		   attacks.  So turn the bleeding FPU back on and be done
-		   with it.  */
-		current_thread_info()->pcb.flags |= 1;
-		__reload_thread(&current_thread_info()->pcb);
-		return;
 
 	      case 5: /* illoc */
 	      default: /* unexpected instruction-fault type */
@@ -577,7 +577,7 @@
 
 	printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n",
 		pc, va, opcode, reg);
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 
 got_exception:
 	/* Ok, we caught the exception, but we don't want it.  Is there
@@ -632,7 +632,7 @@
 		local_irq_enable();
 		while (1);
 	}
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
 
 /*
diff --git a/kernel/arch/alpha/mm/fault.c b/kernel/arch/alpha/mm/fault.c
index 09172f0..5d42f94 100644
--- a/kernel/arch/alpha/mm/fault.c
+++ b/kernel/arch/alpha/mm/fault.c
@@ -204,7 +204,7 @@
 	printk(KERN_ALERT "Unable to handle kernel paging request at "
 	       "virtual address %016lx\n", address);
 	die_if_kernel("Oops", regs, cause, (unsigned long*)regs - 16);
-	do_exit(SIGKILL);
+	make_task_dead(SIGKILL);
 
 	/* We ran out of memory, or some other thing happened to us that
 	   made us unable to handle the page fault gracefully.  */
diff --git a/kernel/arch/arc/include/asm/linkage.h b/kernel/arch/arc/include/asm/linkage.h
index c9434ff..8a3fb71 100644
--- a/kernel/arch/arc/include/asm/linkage.h
+++ b/kernel/arch/arc/include/asm/linkage.h
@@ -8,6 +8,10 @@
 
 #include <asm/dwarf.h>
 
+#define ASM_NL		 `	/* use '`' to mark new line in macro */
+#define __ALIGN		.align 4
+#define __ALIGN_STR	__stringify(__ALIGN)
+
 #ifdef __ASSEMBLY__
 
 .macro ST2 e, o, off
@@ -27,10 +31,6 @@
 	ld	\o, [sp, \off+4]
 #endif
 .endm
-
-#define ASM_NL		 `	/* use '`' to mark new line in macro */
-#define __ALIGN		.align 4
-#define __ALIGN_STR	__stringify(__ALIGN)
 
 /* annotation for data we want in DCCM - if enabled in .config */
 .macro ARCFP_DATA nm
diff --git a/kernel/arch/arm/Kconfig b/kernel/arch/arm/Kconfig
index f6ce22c..bb6621c 100644
--- a/kernel/arch/arm/Kconfig
+++ b/kernel/arch/arm/Kconfig
@@ -4,6 +4,7 @@
 	default y
 	select ARCH_32BIT_OFF_T
 	select ARCH_HAS_BINFMT_FLAT
+	select ARCH_HAS_CPU_FINALIZE_INIT if MMU
 	select ARCH_HAS_DEBUG_VIRTUAL if MMU
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
diff --git a/kernel/arch/arm/boot/dts/Makefile b/kernel/arch/arm/boot/dts/Makefile
index 36464dc..2151bee 100644
--- a/kernel/arch/arm/boot/dts/Makefile
+++ b/kernel/arch/arm/boot/dts/Makefile
@@ -979,6 +979,7 @@
 	rv1103g-evb-v10.dtb \
 	rv1103g-evb-v11.dtb \
 	rv1103g-evb-v11-sii902x-bt6562hdmi.dtb \
+	rv1103g-evb2-v10.dtb \
 	rv1103g-rmsl311-dloc-sl-v10.dtb \
 	rv1103g-scaner-v10.dtb \
 	rv1106g-38x38-ipc-v10.dtb \
@@ -988,6 +989,7 @@
 	rv1106g-evb1-rgb-display-v11.dtb \
 	rv1106g-evb1-v10.dtb \
 	rv1106g-evb1-v11.dtb \
+	rv1106g-evb1-v11-4k.dtb \
 	rv1106g-evb1-v11-cvr.dtb \
 	rv1106g-evb1-v11-cvr-dual-cam.dtb \
 	rv1106g-evb1-v11-spi-nand-cvr.dtb \
@@ -1000,10 +1002,13 @@
 	rv1106g-evb1-v10-spi-nand.dtb \
 	rv1106g-evb1-v10-spi-nor.dtb \
 	rv1106g-evb1-v11-nofastae-spi-nand.dtb \
+	rv1106g-evb1-v11-cvr-ext-dual-cam.dtb \
 	rv1106g-evb2-v10.dtb \
 	rv1106g-evb2-v10-dual-camera.dtb \
 	rv1106g-evb2-v11-emmc.dtb \
 	rv1106g-evb2-v11-trailcam-emmc.dtb \
+	rv1106g-evb2-v12-aov-spi-nor.dtb \
+	rv1106g-evb2-v12-dual-camera-avs.dtb \
 	rv1106g-evb2-v12-nofastae-emmc.dtb \
 	rv1106g-evb2-v12-nofastae-spi-nand.dtb \
 	rv1106g-evb2-v12-nofastae-spi-nor.dtb \
@@ -1060,6 +1065,7 @@
 	rk3288-veyron-speedy.dtb \
 	rk3288-veyron-tiger.dtb \
 	rk3288-vyasa.dtb \
+	rk3308-evb-audio-v10-display-rgb-aarch32.dtb \
 	rk3308bs-evb-amic-v11-aarch32.dtb \
 	rk3308bs-evb-dmic-pdm-v11-aarch32.dtb \
 	rk3308bs-evb-mipi-display-v11-aarch32.dtb \
diff --git a/kernel/arch/arm/boot/dts/am335x-guardian.dts b/kernel/arch/arm/boot/dts/am335x-guardian.dts
index 1918766..9594276a 100644
--- a/kernel/arch/arm/boot/dts/am335x-guardian.dts
+++ b/kernel/arch/arm/boot/dts/am335x-guardian.dts
@@ -100,11 +100,12 @@
 
 	};
 
-	pwm7: dmtimer-pwm {
+	guardian_beeper: pwm-7 {
 		compatible = "ti,omap-dmtimer-pwm";
+		#pwm-cells = <3>;
 		ti,timers = <&timer7>;
 		pinctrl-names = "default";
-		pinctrl-0 = <&dmtimer7_pins>;
+		pinctrl-0 = <&guardian_beeper_pins>;
 		ti,clock-source = <0x01>;
 	};
 
@@ -343,9 +344,9 @@
 		>;
 	};
 
-	dmtimer7_pins: pinmux_dmtimer7_pins {
+	guardian_beeper_pins: pinmux_dmtimer7_pins {
 		pinctrl-single,pins = <
-			AM33XX_IOPAD(0x968, PIN_OUTPUT | MUX_MODE5)
+			AM33XX_IOPAD(0x968, PIN_OUTPUT | MUX_MODE5) /* (E18) timer7 */
 		>;
 	};
 
diff --git a/kernel/arch/arm/boot/dts/am3517-evm.dts b/kernel/arch/arm/boot/dts/am3517-evm.dts
index c8b80f1..9cc1ae3 100644
--- a/kernel/arch/arm/boot/dts/am3517-evm.dts
+++ b/kernel/arch/arm/boot/dts/am3517-evm.dts
@@ -150,7 +150,7 @@
 		enable-gpios = <&gpio6 22 GPIO_ACTIVE_HIGH>; /* gpio_182 */
 	};
 
-	pwm11: dmtimer-pwm@11 {
+	pwm11: pwm-11 {
 		compatible = "ti,omap-dmtimer-pwm";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pwm_pins>;
diff --git a/kernel/arch/arm/boot/dts/am57xx-cl-som-am57x.dts b/kernel/arch/arm/boot/dts/am57xx-cl-som-am57x.dts
index aed8156..d783d1f 100644
--- a/kernel/arch/arm/boot/dts/am57xx-cl-som-am57x.dts
+++ b/kernel/arch/arm/boot/dts/am57xx-cl-som-am57x.dts
@@ -527,7 +527,7 @@
 
 		interrupt-parent = <&gpio1>;
 		interrupts = <31 0>;
-		pendown-gpio = <&gpio1 31 0>;
+		pendown-gpio = <&gpio1 31 GPIO_ACTIVE_LOW>;
 
 
 		ti,x-min = /bits/ 16 <0x0>;
diff --git a/kernel/arch/arm/boot/dts/armada-370.dtsi b/kernel/arch/arm/boot/dts/armada-370.dtsi
index 46e6d3e..c042c41 100644
--- a/kernel/arch/arm/boot/dts/armada-370.dtsi
+++ b/kernel/arch/arm/boot/dts/armada-370.dtsi
@@ -74,7 +74,7 @@
 
 			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>;
diff --git a/kernel/arch/arm/boot/dts/armada-375.dtsi b/kernel/arch/arm/boot/dts/armada-375.dtsi
index 9805e50..d117fc4 100644
--- a/kernel/arch/arm/boot/dts/armada-375.dtsi
+++ b/kernel/arch/arm/boot/dts/armada-375.dtsi
@@ -582,7 +582,7 @@
 
 			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>;
diff --git a/kernel/arch/arm/boot/dts/armada-380.dtsi b/kernel/arch/arm/boot/dts/armada-380.dtsi
index cff1269..7146cc8 100644
--- a/kernel/arch/arm/boot/dts/armada-380.dtsi
+++ b/kernel/arch/arm/boot/dts/armada-380.dtsi
@@ -79,7 +79,7 @@
 			/* 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 @@
 			/* 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/kernel/arch/arm/boot/dts/armada-385-turris-omnia.dts b/kernel/arch/arm/boot/dts/armada-385-turris-omnia.dts
index 92e0848..320c759 100644
--- a/kernel/arch/arm/boot/dts/armada-385-turris-omnia.dts
+++ b/kernel/arch/arm/boot/dts/armada-385-turris-omnia.dts
@@ -22,6 +22,12 @@
 		stdout-path = &uart0;
 	};
 
+	aliases {
+		ethernet0 = &eth0;
+		ethernet1 = &eth1;
+		ethernet2 = &eth2;
+	};
+
 	memory {
 		device_type = "memory";
 		reg = <0x00000000 0x40000000>; /* 1024 MB */
@@ -291,7 +297,17 @@
 				};
 			};
 
-			/* port 6 is connected to eth0 */
+			ports@6 {
+				reg = <6>;
+				label = "cpu";
+				ethernet = <&eth0>;
+				phy-mode = "rgmii-id";
+
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
 		};
 	};
 };
diff --git a/kernel/arch/arm/boot/dts/armada-385.dtsi b/kernel/arch/arm/boot/dts/armada-385.dtsi
index f0022d1..f081f7c 100644
--- a/kernel/arch/arm/boot/dts/armada-385.dtsi
+++ b/kernel/arch/arm/boot/dts/armada-385.dtsi
@@ -84,7 +84,7 @@
 			/* 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 @@
 			/* 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 @@
 			 */
 			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>;
diff --git a/kernel/arch/arm/boot/dts/armada-39x.dtsi b/kernel/arch/arm/boot/dts/armada-39x.dtsi
index e0b7c20..9525e7b 100644
--- a/kernel/arch/arm/boot/dts/armada-39x.dtsi
+++ b/kernel/arch/arm/boot/dts/armada-39x.dtsi
@@ -453,7 +453,7 @@
 			/* 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 @@
 			/* 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@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>;
diff --git a/kernel/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/kernel/arch/arm/boot/dts/armada-xp-mv78230.dtsi
index 8558bf6..d55fe16 100644
--- a/kernel/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+++ b/kernel/arch/arm/boot/dts/armada-xp-mv78230.dtsi
@@ -97,7 +97,7 @@
 
 			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 @@
 
 			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 @@
 
 			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 @@
 
 			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/kernel/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/kernel/arch/arm/boot/dts/armada-xp-mv78260.dtsi
index 2d85fe8..fdcc818 100644
--- a/kernel/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+++ b/kernel/arch/arm/boot/dts/armada-xp-mv78260.dtsi
@@ -112,7 +112,7 @@
 
 			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 @@
 
 			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 @@
 
 			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 @@
 
 			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 @@
 
 			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 @@
 
 			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 @@
 
 			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 @@
 
 			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>;
diff --git a/kernel/arch/arm/boot/dts/at91sam9261ek.dts b/kernel/arch/arm/boot/dts/at91sam9261ek.dts
index beed819..8f3b483 100644
--- a/kernel/arch/arm/boot/dts/at91sam9261ek.dts
+++ b/kernel/arch/arm/boot/dts/at91sam9261ek.dts
@@ -156,7 +156,7 @@
 					compatible = "ti,ads7843";
 					interrupts-extended = <&pioC 2 IRQ_TYPE_EDGE_BOTH>;
 					spi-max-frequency = <3000000>;
-					pendown-gpio = <&pioC 2 GPIO_ACTIVE_HIGH>;
+					pendown-gpio = <&pioC 2 GPIO_ACTIVE_LOW>;
 
 					ti,x-min = /bits/ 16 <150>;
 					ti,x-max = /bits/ 16 <3830>;
diff --git a/kernel/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts b/kernel/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
index cd797b4..01c48fa 100644
--- a/kernel/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
+++ b/kernel/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
@@ -19,7 +19,8 @@
 
 	memory@0 {
 		device_type = "memory";
-		reg = <0x00000000 0x08000000>;
+		reg = <0x00000000 0x08000000>,
+		      <0x88000000 0x08000000>;
 	};
 
 	gpio-keys {
diff --git a/kernel/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts b/kernel/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
index 57ca1cf..00e688b 100644
--- a/kernel/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
+++ b/kernel/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
@@ -46,3 +46,16 @@
 		};
 	};
 };
+
+&gmac0 {
+	phy-mode = "rgmii";
+	phy-handle = <&bcm54210e>;
+
+	mdio {
+		/delete-node/ switch@1e;
+
+		bcm54210e: ethernet-phy@0 {
+			reg = <0>;
+		};
+	};
+};
diff --git a/kernel/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts b/kernel/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
index 2e1a7e3..78c80a5 100644
--- a/kernel/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
+++ b/kernel/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
@@ -83,3 +83,16 @@
 		};
 	};
 };
+
+&gmac0 {
+	phy-mode = "rgmii";
+	phy-handle = <&bcm54210e>;
+
+	mdio {
+		/delete-node/ switch@1e;
+
+		bcm54210e: ethernet-phy@0 {
+			reg = <0>;
+		};
+	};
+};
diff --git a/kernel/arch/arm/boot/dts/bcm53015-meraki-mr26.dts b/kernel/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
index 14f5803..ca2266b 100644
--- a/kernel/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
+++ b/kernel/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
@@ -128,7 +128,7 @@
 
 			fixed-link {
 				speed = <1000>;
-				duplex-full;
+				full-duplex;
 			};
 		};
 	};
diff --git a/kernel/arch/arm/boot/dts/bcm53016-meraki-mr32.dts b/kernel/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
index 577a4dc..edf9910 100644
--- a/kernel/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
+++ b/kernel/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
@@ -212,7 +212,7 @@
 
 			fixed-link {
 				speed = <1000>;
-				duplex-full;
+				full-duplex;
 			};
 		};
 	};
diff --git a/kernel/arch/arm/boot/dts/bcm5301x.dtsi b/kernel/arch/arm/boot/dts/bcm5301x.dtsi
index 9fdad20..9189a94 100644
--- a/kernel/arch/arm/boot/dts/bcm5301x.dtsi
+++ b/kernel/arch/arm/boot/dts/bcm5301x.dtsi
@@ -267,7 +267,7 @@
 
 			interrupt-parent = <&gic>;
 
-			ehci: ehci@21000 {
+			ehci: usb@21000 {
 				#usb-cells = <0>;
 
 				compatible = "generic-ehci";
@@ -289,7 +289,7 @@
 				};
 			};
 
-			ohci: ohci@22000 {
+			ohci: usb@22000 {
 				#usb-cells = <0>;
 
 				compatible = "generic-ohci";
@@ -532,7 +532,6 @@
 				  "spi_lr_session_done",
 				  "spi_lr_overread";
 		clocks = <&iprocmed>;
-		clock-names = "iprocmed";
 		num-cs = <2>;
 		#address-cells = <1>;
 		#size-cells = <0>;
diff --git a/kernel/arch/arm/boot/dts/bcm53573.dtsi b/kernel/arch/arm/boot/dts/bcm53573.dtsi
index 4af8e32..eed1a61 100644
--- a/kernel/arch/arm/boot/dts/bcm53573.dtsi
+++ b/kernel/arch/arm/boot/dts/bcm53573.dtsi
@@ -127,6 +127,9 @@
 
 		pcie0: pcie@2000 {
 			reg = <0x00002000 0x1000>;
+
+			#address-cells = <3>;
+			#size-cells = <2>;
 		};
 
 		usb2: usb2@4000 {
@@ -135,7 +138,7 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 
-			ehci: ehci@4000 {
+			ehci: usb@4000 {
 				compatible = "generic-ehci";
 				reg = <0x4000 0x1000>;
 				interrupt-parent = <&gic>;
@@ -155,9 +158,7 @@
 				};
 			};
 
-			ohci: ohci@d000 {
-				#usb-cells = <0>;
-
+			ohci: usb@d000 {
 				compatible = "generic-ohci";
 				reg = <0xd000 0x1000>;
 				interrupt-parent = <&gic>;
@@ -180,6 +181,24 @@
 
 		gmac0: ethernet@5000 {
 			reg = <0x5000 0x1000>;
+
+			mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				switch: switch@1e {
+					compatible = "brcm,bcm53125";
+					reg = <0x1e>;
+
+					status = "disabled";
+
+					/* ports are defined in board DTS */
+					ports {
+						#address-cells = <1>;
+						#size-cells = <0>;
+					};
+				};
+			};
 		};
 
 		gmac1: ethernet@b000 {
diff --git a/kernel/arch/arm/boot/dts/bcm947189acdbmr.dts b/kernel/arch/arm/boot/dts/bcm947189acdbmr.dts
index b0b8c77..1f0be30 100644
--- a/kernel/arch/arm/boot/dts/bcm947189acdbmr.dts
+++ b/kernel/arch/arm/boot/dts/bcm947189acdbmr.dts
@@ -60,9 +60,9 @@
 	spi {
 		compatible = "spi-gpio";
 		num-chipselects = <1>;
-		gpio-sck = <&chipcommon 21 0>;
-		gpio-miso = <&chipcommon 22 0>;
-		gpio-mosi = <&chipcommon 23 0>;
+		sck-gpios = <&chipcommon 21 0>;
+		miso-gpios = <&chipcommon 22 0>;
+		mosi-gpios = <&chipcommon 23 0>;
 		cs-gpios = <&chipcommon 24 0>;
 		#address-cells = <1>;
 		#size-cells = <0>;
diff --git a/kernel/arch/arm/boot/dts/dove.dtsi b/kernel/arch/arm/boot/dts/dove.dtsi
index 89e0bda..726d353 100644
--- a/kernel/arch/arm/boot/dts/dove.dtsi
+++ b/kernel/arch/arm/boot/dts/dove.dtsi
@@ -129,7 +129,7 @@
 			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>;
diff --git a/kernel/arch/arm/boot/dts/e60k02.dtsi b/kernel/arch/arm/boot/dts/e60k02.dtsi
index 3af1ab4..bd1f58a 100644
--- a/kernel/arch/arm/boot/dts/e60k02.dtsi
+++ b/kernel/arch/arm/boot/dts/e60k02.dtsi
@@ -296,6 +296,7 @@
 
 &usbotg1 {
 	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usbotg1>;
 	disable-over-current;
 	srp-disable;
 	hnp-disable;
diff --git a/kernel/arch/arm/boot/dts/exynos3250-rinato.dts b/kernel/arch/arm/boot/dts/exynos3250-rinato.dts
index f9e3b13..bbf01f7 100644
--- a/kernel/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/kernel/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -249,7 +249,7 @@
 	i80-if-timings {
 		cs-setup = <0>;
 		wr-setup = <0>;
-		wr-act = <1>;
+		wr-active = <1>;
 		wr-hold = <0>;
 	};
 };
diff --git a/kernel/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi b/kernel/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi
index 021d9fc..27a1a89 100644
--- a/kernel/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi
+++ b/kernel/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi
@@ -10,7 +10,7 @@
 / {
 thermal-zones {
 	cpu_thermal: cpu-thermal {
-		thermal-sensors = <&tmu 0>;
+		thermal-sensors = <&tmu>;
 		polling-delay-passive = <0>;
 		polling-delay = <0>;
 		trips {
diff --git a/kernel/arch/arm/boot/dts/exynos4.dtsi b/kernel/arch/arm/boot/dts/exynos4.dtsi
index a1e5444..41f0e64 100644
--- a/kernel/arch/arm/boot/dts/exynos4.dtsi
+++ b/kernel/arch/arm/boot/dts/exynos4.dtsi
@@ -605,7 +605,7 @@
 			status = "disabled";
 
 			hdmi_i2c_phy: hdmiphy@38 {
-				compatible = "exynos4210-hdmiphy";
+				compatible = "samsung,exynos4210-hdmiphy";
 				reg = <0x38>;
 			};
 		};
diff --git a/kernel/arch/arm/boot/dts/exynos4210-i9100.dts b/kernel/arch/arm/boot/dts/exynos4210-i9100.dts
index ecc9d4d..d186b93 100644
--- a/kernel/arch/arm/boot/dts/exynos4210-i9100.dts
+++ b/kernel/arch/arm/boot/dts/exynos4210-i9100.dts
@@ -170,8 +170,8 @@
 			power-on-delay = <10>;
 			reset-delay = <10>;
 
-			panel-width-mm = <90>;
-			panel-height-mm = <154>;
+			panel-width-mm = <56>;
+			panel-height-mm = <93>;
 
 			display-timings {
 				timing {
diff --git a/kernel/arch/arm/boot/dts/exynos4210.dtsi b/kernel/arch/arm/boot/dts/exynos4210.dtsi
index fddc661..448e1b1 100644
--- a/kernel/arch/arm/boot/dts/exynos4210.dtsi
+++ b/kernel/arch/arm/boot/dts/exynos4210.dtsi
@@ -382,7 +382,6 @@
 &cpu_thermal {
 	polling-delay-passive = <0>;
 	polling-delay = <0>;
-	thermal-sensors = <&tmu 0>;
 };
 
 &gic {
diff --git a/kernel/arch/arm/boot/dts/exynos4412-itop-elite.dts b/kernel/arch/arm/boot/dts/exynos4412-itop-elite.dts
index f6d0a5f..9a2a494 100644
--- a/kernel/arch/arm/boot/dts/exynos4412-itop-elite.dts
+++ b/kernel/arch/arm/boot/dts/exynos4412-itop-elite.dts
@@ -179,7 +179,7 @@
 		compatible = "wlf,wm8960";
 		reg = <0x1a>;
 		clocks = <&pmu_system_controller 0>;
-		clock-names = "MCLK1";
+		clock-names = "mclk";
 		wlf,shared-lrclk;
 		#sound-dai-cells = <0>;
 	};
diff --git a/kernel/arch/arm/boot/dts/exynos5250.dtsi b/kernel/arch/arm/boot/dts/exynos5250.dtsi
index bd2d883..62051e6 100644
--- a/kernel/arch/arm/boot/dts/exynos5250.dtsi
+++ b/kernel/arch/arm/boot/dts/exynos5250.dtsi
@@ -1109,7 +1109,7 @@
 &cpu_thermal {
 	polling-delay-passive = <0>;
 	polling-delay = <0>;
-	thermal-sensors = <&tmu 0>;
+	thermal-sensors = <&tmu>;
 
 	cooling-maps {
 		map0 {
diff --git a/kernel/arch/arm/boot/dts/exynos5410-odroidxu.dts b/kernel/arch/arm/boot/dts/exynos5410-odroidxu.dts
index bd1d849..147c077 100644
--- a/kernel/arch/arm/boot/dts/exynos5410-odroidxu.dts
+++ b/kernel/arch/arm/boot/dts/exynos5410-odroidxu.dts
@@ -116,7 +116,6 @@
 };
 
 &cpu0_thermal {
-	thermal-sensors = <&tmu_cpu0 0>;
 	polling-delay-passive = <0>;
 	polling-delay = <0>;
 
diff --git a/kernel/arch/arm/boot/dts/exynos5420.dtsi b/kernel/arch/arm/boot/dts/exynos5420.dtsi
index 83580f0..3488653 100644
--- a/kernel/arch/arm/boot/dts/exynos5420.dtsi
+++ b/kernel/arch/arm/boot/dts/exynos5420.dtsi
@@ -605,7 +605,7 @@
 		};
 
 		mipi_phy: mipi-video-phy {
-			compatible = "samsung,s5pv210-mipi-video-phy";
+			compatible = "samsung,exynos5420-mipi-video-phy";
 			syscon = <&pmu_system_controller>;
 			#phy-cells = <1>;
 		};
diff --git a/kernel/arch/arm/boot/dts/exynos5422-odroidhc1.dts b/kernel/arch/arm/boot/dts/exynos5422-odroidhc1.dts
index 88f5c15..a1871d4 100644
--- a/kernel/arch/arm/boot/dts/exynos5422-odroidhc1.dts
+++ b/kernel/arch/arm/boot/dts/exynos5422-odroidhc1.dts
@@ -29,7 +29,7 @@
 
 	thermal-zones {
 		cpu0_thermal: cpu0-thermal {
-			thermal-sensors = <&tmu_cpu0 0>;
+			thermal-sensors = <&tmu_cpu0>;
 			trips {
 				cpu0_alert0: cpu-alert-0 {
 					temperature = <70000>; /* millicelsius */
@@ -84,7 +84,7 @@
 			};
 		};
 		cpu1_thermal: cpu1-thermal {
-			thermal-sensors = <&tmu_cpu1 0>;
+			thermal-sensors = <&tmu_cpu1>;
 			trips {
 				cpu1_alert0: cpu-alert-0 {
 					temperature = <70000>;
@@ -128,7 +128,7 @@
 			};
 		};
 		cpu2_thermal: cpu2-thermal {
-			thermal-sensors = <&tmu_cpu2 0>;
+			thermal-sensors = <&tmu_cpu2>;
 			trips {
 				cpu2_alert0: cpu-alert-0 {
 					temperature = <70000>;
@@ -172,7 +172,7 @@
 			};
 		};
 		cpu3_thermal: cpu3-thermal {
-			thermal-sensors = <&tmu_cpu3 0>;
+			thermal-sensors = <&tmu_cpu3>;
 			trips {
 				cpu3_alert0: cpu-alert-0 {
 					temperature = <70000>;
@@ -216,7 +216,7 @@
 			};
 		};
 		gpu_thermal: gpu-thermal {
-			thermal-sensors = <&tmu_gpu 0>;
+			thermal-sensors = <&tmu_gpu>;
 			trips {
 				gpu_alert0: gpu-alert-0 {
 					temperature = <70000>;
diff --git a/kernel/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/kernel/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
index 5da2d81..099ed43 100644
--- a/kernel/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
+++ b/kernel/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
@@ -50,7 +50,7 @@
 
 	thermal-zones {
 		cpu0_thermal: cpu0-thermal {
-			thermal-sensors = <&tmu_cpu0 0>;
+			thermal-sensors = <&tmu_cpu0>;
 			polling-delay-passive = <250>;
 			polling-delay = <0>;
 			trips {
@@ -139,7 +139,7 @@
 			};
 		};
 		cpu1_thermal: cpu1-thermal {
-			thermal-sensors = <&tmu_cpu1 0>;
+			thermal-sensors = <&tmu_cpu1>;
 			polling-delay-passive = <250>;
 			polling-delay = <0>;
 			trips {
@@ -212,7 +212,7 @@
 			};
 		};
 		cpu2_thermal: cpu2-thermal {
-			thermal-sensors = <&tmu_cpu2 0>;
+			thermal-sensors = <&tmu_cpu2>;
 			polling-delay-passive = <250>;
 			polling-delay = <0>;
 			trips {
@@ -285,7 +285,7 @@
 			};
 		};
 		cpu3_thermal: cpu3-thermal {
-			thermal-sensors = <&tmu_cpu3 0>;
+			thermal-sensors = <&tmu_cpu3>;
 			polling-delay-passive = <250>;
 			polling-delay = <0>;
 			trips {
@@ -358,7 +358,7 @@
 			};
 		};
 		gpu_thermal: gpu-thermal {
-			thermal-sensors = <&tmu_gpu 0>;
+			thermal-sensors = <&tmu_gpu>;
 			polling-delay-passive = <250>;
 			polling-delay = <0>;
 			trips {
diff --git a/kernel/arch/arm/boot/dts/imx23.dtsi b/kernel/arch/arm/boot/dts/imx23.dtsi
index 7f4c602..ce3d636 100644
--- a/kernel/arch/arm/boot/dts/imx23.dtsi
+++ b/kernel/arch/arm/boot/dts/imx23.dtsi
@@ -59,7 +59,7 @@
 				reg = <0x80000000 0x2000>;
 			};
 
-			dma_apbh: dma-apbh@80004000 {
+			dma_apbh: dma-controller@80004000 {
 				compatible = "fsl,imx23-dma-apbh";
 				reg = <0x80004000 0x2000>;
 				interrupts = <0 14 20 0
diff --git a/kernel/arch/arm/boot/dts/imx25.dtsi b/kernel/arch/arm/boot/dts/imx25.dtsi
index 1ab19f1..d24b1da 100644
--- a/kernel/arch/arm/boot/dts/imx25.dtsi
+++ b/kernel/arch/arm/boot/dts/imx25.dtsi
@@ -515,7 +515,7 @@
 				#interrupt-cells = <2>;
 			};
 
-			sdma: sdma@53fd4000 {
+			sdma: dma-controller@53fd4000 {
 				compatible = "fsl,imx25-sdma";
 				reg = <0x53fd4000 0x4000>;
 				clocks = <&clks 112>, <&clks 68>;
diff --git a/kernel/arch/arm/boot/dts/imx28.dtsi b/kernel/arch/arm/boot/dts/imx28.dtsi
index 94dfbf5..6cab8b6 100644
--- a/kernel/arch/arm/boot/dts/imx28.dtsi
+++ b/kernel/arch/arm/boot/dts/imx28.dtsi
@@ -78,7 +78,7 @@
 				status = "disabled";
 			};
 
-			dma_apbh: dma-apbh@80004000 {
+			dma_apbh: dma-controller@80004000 {
 				compatible = "fsl,imx28-dma-apbh";
 				reg = <0x80004000 0x2000>;
 				interrupts = <82 83 84 85
diff --git a/kernel/arch/arm/boot/dts/imx31.dtsi b/kernel/arch/arm/boot/dts/imx31.dtsi
index 45333f7..0ee7e55 100644
--- a/kernel/arch/arm/boot/dts/imx31.dtsi
+++ b/kernel/arch/arm/boot/dts/imx31.dtsi
@@ -297,7 +297,7 @@
 				#interrupt-cells = <2>;
 			};
 
-			sdma: sdma@53fd4000 {
+			sdma: dma-controller@53fd4000 {
 				compatible = "fsl,imx31-sdma";
 				reg = <0x53fd4000 0x4000>;
 				interrupts = <34>;
diff --git a/kernel/arch/arm/boot/dts/imx35.dtsi b/kernel/arch/arm/boot/dts/imx35.dtsi
index aba1625..e7c4803 100644
--- a/kernel/arch/arm/boot/dts/imx35.dtsi
+++ b/kernel/arch/arm/boot/dts/imx35.dtsi
@@ -284,7 +284,7 @@
 				#interrupt-cells = <2>;
 			};
 
-			sdma: sdma@53fd4000 {
+			sdma: dma-controller@53fd4000 {
 				compatible = "fsl,imx35-sdma";
 				reg = <0x53fd4000 0x4000>;
 				clocks = <&clks 9>, <&clks 65>;
diff --git a/kernel/arch/arm/boot/dts/imx50.dtsi b/kernel/arch/arm/boot/dts/imx50.dtsi
index b6b2e6a..ae51333 100644
--- a/kernel/arch/arm/boot/dts/imx50.dtsi
+++ b/kernel/arch/arm/boot/dts/imx50.dtsi
@@ -421,7 +421,7 @@
 				status = "disabled";
 			};
 
-			sdma: sdma@63fb0000 {
+			sdma: dma-controller@63fb0000 {
 				compatible = "fsl,imx50-sdma", "fsl,imx35-sdma";
 				reg = <0x63fb0000 0x4000>;
 				interrupts = <6>;
diff --git a/kernel/arch/arm/boot/dts/imx51.dtsi b/kernel/arch/arm/boot/dts/imx51.dtsi
index 985e1be..d800635 100644
--- a/kernel/arch/arm/boot/dts/imx51.dtsi
+++ b/kernel/arch/arm/boot/dts/imx51.dtsi
@@ -498,7 +498,7 @@
 				status = "disabled";
 			};
 
-			sdma: sdma@83fb0000 {
+			sdma: dma-controller@83fb0000 {
 				compatible = "fsl,imx51-sdma", "fsl,imx35-sdma";
 				reg = <0x83fb0000 0x4000>;
 				interrupts = <6>;
diff --git a/kernel/arch/arm/boot/dts/imx53-ppd.dts b/kernel/arch/arm/boot/dts/imx53-ppd.dts
index 006fbd7..54e39db 100644
--- a/kernel/arch/arm/boot/dts/imx53-ppd.dts
+++ b/kernel/arch/arm/boot/dts/imx53-ppd.dts
@@ -487,7 +487,7 @@
 	scl-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
 	status = "okay";
 
-	i2c-switch@70 {
+	i2c-mux@70 {
 		compatible = "nxp,pca9547";
 		#address-cells = <1>;
 		#size-cells = <0>;
diff --git a/kernel/arch/arm/boot/dts/imx53.dtsi b/kernel/arch/arm/boot/dts/imx53.dtsi
index 500eeaa..f4e7f43 100644
--- a/kernel/arch/arm/boot/dts/imx53.dtsi
+++ b/kernel/arch/arm/boot/dts/imx53.dtsi
@@ -710,7 +710,7 @@
 				status = "disabled";
 			};
 
-			sdma: sdma@63fb0000 {
+			sdma: dma-controller@63fb0000 {
 				compatible = "fsl,imx53-sdma", "fsl,imx35-sdma";
 				reg = <0x63fb0000 0x4000>;
 				interrupts = <6>;
diff --git a/kernel/arch/arm/boot/dts/imx6dl-prtrvt.dts b/kernel/arch/arm/boot/dts/imx6dl-prtrvt.dts
index 5ac8444..90e01de 100644
--- a/kernel/arch/arm/boot/dts/imx6dl-prtrvt.dts
+++ b/kernel/arch/arm/boot/dts/imx6dl-prtrvt.dts
@@ -126,6 +126,10 @@
 	status = "disabled";
 };
 
+&usbotg {
+	disable-over-current;
+};
+
 &vpu {
 	status = "disabled";
 };
diff --git a/kernel/arch/arm/boot/dts/imx6qdl-gw560x.dtsi b/kernel/arch/arm/boot/dts/imx6qdl-gw560x.dtsi
index 093a219..f520e33 100644
--- a/kernel/arch/arm/boot/dts/imx6qdl-gw560x.dtsi
+++ b/kernel/arch/arm/boot/dts/imx6qdl-gw560x.dtsi
@@ -634,7 +634,6 @@
 &uart1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart1>;
-	uart-has-rtscts;
 	rts-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
 	status = "okay";
 };
diff --git a/kernel/arch/arm/boot/dts/imx6qdl-prti6q.dtsi b/kernel/arch/arm/boot/dts/imx6qdl-prti6q.dtsi
index 19578f6..70dfa07 100644
--- a/kernel/arch/arm/boot/dts/imx6qdl-prti6q.dtsi
+++ b/kernel/arch/arm/boot/dts/imx6qdl-prti6q.dtsi
@@ -69,6 +69,7 @@
 	vbus-supply = <&reg_usb_h1_vbus>;
 	phy_type = "utmi";
 	dr_mode = "host";
+	disable-over-current;
 	status = "okay";
 };
 
@@ -78,10 +79,18 @@
 	pinctrl-0 = <&pinctrl_usbotg>;
 	phy_type = "utmi";
 	dr_mode = "host";
-	disable-over-current;
+	over-current-active-low;
 	status = "okay";
 };
 
+&usbphynop1 {
+	status = "disabled";
+};
+
+&usbphynop2 {
+	status = "disabled";
+};
+
 &usdhc1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_usdhc1>;
diff --git a/kernel/arch/arm/boot/dts/imx6qdl.dtsi b/kernel/arch/arm/boot/dts/imx6qdl.dtsi
index 7858ae5..e67d8df 100644
--- a/kernel/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/kernel/arch/arm/boot/dts/imx6qdl.dtsi
@@ -45,6 +45,10 @@
 		spi1 = &ecspi2;
 		spi2 = &ecspi3;
 		spi3 = &ecspi4;
+		usb0 = &usbotg;
+		usb1 = &usbh1;
+		usb2 = &usbh2;
+		usb3 = &usbh3;
 		usbphy0 = &usbphy1;
 		usbphy1 = &usbphy2;
 	};
@@ -146,7 +150,7 @@
 		interrupt-parent = <&gpc>;
 		ranges;
 
-		dma_apbh: dma-apbh@110000 {
+		dma_apbh: dma-controller@110000 {
 			compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
 			reg = <0x00110000 0x2000>;
 			interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>,
@@ -923,7 +927,7 @@
 				interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>;
 			};
 
-			sdma: sdma@20ec000 {
+			sdma: dma-controller@20ec000 {
 				compatible = "fsl,imx6q-sdma", "fsl,imx35-sdma";
 				reg = <0x020ec000 0x4000>;
 				interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/kernel/arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts b/kernel/arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts
index caa2796..0fd126d 100644
--- a/kernel/arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts
+++ b/kernel/arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts
@@ -580,6 +580,7 @@
 
 &usbotg1 {
 	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usbotg1>;
 	disable-over-current;
 	srp-disable;
 	hnp-disable;
diff --git a/kernel/arch/arm/boot/dts/imx6sl.dtsi b/kernel/arch/arm/boot/dts/imx6sl.dtsi
index c184a6d..0e01392 100644
--- a/kernel/arch/arm/boot/dts/imx6sl.dtsi
+++ b/kernel/arch/arm/boot/dts/imx6sl.dtsi
@@ -39,6 +39,9 @@
 		spi1 = &ecspi2;
 		spi2 = &ecspi3;
 		spi3 = &ecspi4;
+		usb0 = &usbotg1;
+		usb1 = &usbotg2;
+		usb2 = &usbh;
 		usbphy0 = &usbphy1;
 		usbphy1 = &usbphy2;
 	};
@@ -749,7 +752,7 @@
 				interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
 			};
 
-			sdma: sdma@20ec000 {
+			sdma: dma-controller@20ec000 {
 				compatible = "fsl,imx6sl-sdma", "fsl,imx6q-sdma";
 				reg = <0x020ec000 0x4000>;
 				interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/kernel/arch/arm/boot/dts/imx6sll.dtsi b/kernel/arch/arm/boot/dts/imx6sll.dtsi
index bf5b262..3659fd5 100644
--- a/kernel/arch/arm/boot/dts/imx6sll.dtsi
+++ b/kernel/arch/arm/boot/dts/imx6sll.dtsi
@@ -36,6 +36,8 @@
 		spi1 = &ecspi2;
 		spi3 = &ecspi3;
 		spi4 = &ecspi4;
+		usb0 = &usbotg1;
+		usb1 = &usbotg2;
 		usbphy0 = &usbphy1;
 		usbphy1 = &usbphy2;
 	};
@@ -49,20 +51,18 @@
 			device_type = "cpu";
 			reg = <0>;
 			next-level-cache = <&L2>;
-			operating-points = <
+			operating-points =
 				/* kHz    uV */
-				996000  1275000
-				792000  1175000
-				396000  1075000
-				198000	975000
-			>;
-			fsl,soc-operating-points = <
+				<996000  1275000>,
+				<792000  1175000>,
+				<396000  1075000>,
+				<198000	  975000>;
+			fsl,soc-operating-points =
 				/* ARM kHz      SOC-PU uV */
-				996000          1175000
-				792000          1175000
-				396000          1175000
-				198000		1175000
-			>;
+				<996000         1175000>,
+				<792000         1175000>,
+				<396000         1175000>,
+				<198000		1175000>;
 			clock-latency = <61036>; /* two CLK32 periods */
 			#cooling-cells = <2>;
 			clocks = <&clks IMX6SLL_CLK_ARM>,
@@ -552,7 +552,7 @@
 				reg = <0x020ca000 0x1000>;
 				interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6SLL_CLK_USBPHY2>;
-				phy-reg_3p0-supply = <&reg_3p0>;
+				phy-3p0-supply = <&reg_3p0>;
 				fsl,anatop = <&anatop>;
 			};
 
diff --git a/kernel/arch/arm/boot/dts/imx6sx.dtsi b/kernel/arch/arm/boot/dts/imx6sx.dtsi
index c399919..08332f7 100644
--- a/kernel/arch/arm/boot/dts/imx6sx.dtsi
+++ b/kernel/arch/arm/boot/dts/imx6sx.dtsi
@@ -49,6 +49,9 @@
 		spi2 = &ecspi3;
 		spi3 = &ecspi4;
 		spi4 = &ecspi5;
+		usb0 = &usbotg1;
+		usb1 = &usbotg2;
+		usb2 = &usbh;
 		usbphy0 = &usbphy1;
 		usbphy1 = &usbphy2;
 	};
@@ -206,7 +209,7 @@
 			power-domains = <&pd_pu>;
 		};
 
-		dma_apbh: dma-apbh@1804000 {
+		dma_apbh: dma-controller@1804000 {
 			compatible = "fsl,imx6sx-dma-apbh", "fsl,imx28-dma-apbh";
 			reg = <0x01804000 0x2000>;
 			interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
@@ -845,7 +848,7 @@
 				reg = <0x020e4000 0x4000>;
 			};
 
-			sdma: sdma@20ec000 {
+			sdma: dma-controller@20ec000 {
 				compatible = "fsl,imx6sx-sdma", "fsl,imx6q-sdma";
 				reg = <0x020ec000 0x4000>;
 				interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/kernel/arch/arm/boot/dts/imx6ul-pico-dwarf.dts b/kernel/arch/arm/boot/dts/imx6ul-pico-dwarf.dts
index 162dc25..5a74c7f 100644
--- a/kernel/arch/arm/boot/dts/imx6ul-pico-dwarf.dts
+++ b/kernel/arch/arm/boot/dts/imx6ul-pico-dwarf.dts
@@ -32,7 +32,7 @@
 };
 
 &i2c2 {
-	clock_frequency = <100000>;
+	clock-frequency = <100000>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_i2c2>;
 	status = "okay";
diff --git a/kernel/arch/arm/boot/dts/imx6ul.dtsi b/kernel/arch/arm/boot/dts/imx6ul.dtsi
index c40684a..c374fe2 100644
--- a/kernel/arch/arm/boot/dts/imx6ul.dtsi
+++ b/kernel/arch/arm/boot/dts/imx6ul.dtsi
@@ -47,6 +47,8 @@
 		spi1 = &ecspi2;
 		spi2 = &ecspi3;
 		spi3 = &ecspi4;
+		usb0 = &usbotg1;
+		usb1 = &usbotg2;
 		usbphy0 = &usbphy1;
 		usbphy1 = &usbphy2;
 	};
@@ -162,7 +164,7 @@
 			      <0x00a06000 0x2000>;
 		};
 
-		dma_apbh: dma-apbh@1804000 {
+		dma_apbh: dma-controller@1804000 {
 			compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
 			reg = <0x01804000 0x2000>;
 			interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>,
@@ -741,7 +743,7 @@
 				status = "disabled";
 			};
 
-			sdma: sdma@20ec000 {
+			sdma: dma-controller@20ec000 {
 				compatible = "fsl,imx6ul-sdma", "fsl,imx6q-sdma",
 					     "fsl,imx35-sdma";
 				reg = <0x020ec000 0x4000>;
diff --git a/kernel/arch/arm/boot/dts/imx7d-pico-dwarf.dts b/kernel/arch/arm/boot/dts/imx7d-pico-dwarf.dts
index 5162fe2..fdc1056 100644
--- a/kernel/arch/arm/boot/dts/imx7d-pico-dwarf.dts
+++ b/kernel/arch/arm/boot/dts/imx7d-pico-dwarf.dts
@@ -32,7 +32,7 @@
 };
 
 &i2c1 {
-	clock_frequency = <100000>;
+	clock-frequency = <100000>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_i2c1>;
 	status = "okay";
@@ -52,7 +52,7 @@
 };
 
 &i2c4 {
-	clock_frequency = <100000>;
+	clock-frequency = <100000>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_i2c1>;
 	status = "okay";
diff --git a/kernel/arch/arm/boot/dts/imx7d-pico-hobbit.dts b/kernel/arch/arm/boot/dts/imx7d-pico-hobbit.dts
index d917dc4..6ad39dc 100644
--- a/kernel/arch/arm/boot/dts/imx7d-pico-hobbit.dts
+++ b/kernel/arch/arm/boot/dts/imx7d-pico-hobbit.dts
@@ -64,7 +64,7 @@
 		interrupt-parent = <&gpio2>;
 		interrupts = <7 0>;
 		spi-max-frequency = <1000000>;
-		pendown-gpio = <&gpio2 7 0>;
+		pendown-gpio = <&gpio2 7 GPIO_ACTIVE_LOW>;
 		vcc-supply = <&reg_3p3v>;
 		ti,x-min = /bits/ 16 <0>;
 		ti,x-max = /bits/ 16 <4095>;
diff --git a/kernel/arch/arm/boot/dts/imx7d-pico-nymph.dts b/kernel/arch/arm/boot/dts/imx7d-pico-nymph.dts
index 104a852..5afb167 100644
--- a/kernel/arch/arm/boot/dts/imx7d-pico-nymph.dts
+++ b/kernel/arch/arm/boot/dts/imx7d-pico-nymph.dts
@@ -43,7 +43,7 @@
 };
 
 &i2c1 {
-	clock_frequency = <100000>;
+	clock-frequency = <100000>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_i2c1>;
 	status = "okay";
@@ -64,7 +64,7 @@
 };
 
 &i2c2 {
-	clock_frequency = <100000>;
+	clock-frequency = <100000>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_i2c2>;
 	status = "okay";
diff --git a/kernel/arch/arm/boot/dts/imx7d-sdb.dts b/kernel/arch/arm/boot/dts/imx7d-sdb.dts
index 6d562eb..d3b49a5 100644
--- a/kernel/arch/arm/boot/dts/imx7d-sdb.dts
+++ b/kernel/arch/arm/boot/dts/imx7d-sdb.dts
@@ -198,7 +198,7 @@
 		pinctrl-0 = <&pinctrl_tsc2046_pendown>;
 		interrupt-parent = <&gpio2>;
 		interrupts = <29 0>;
-		pendown-gpio = <&gpio2 29 GPIO_ACTIVE_HIGH>;
+		pendown-gpio = <&gpio2 29 GPIO_ACTIVE_LOW>;
 		touchscreen-max-pressure = <255>;
 		wakeup-source;
 	};
diff --git a/kernel/arch/arm/boot/dts/imx7d.dtsi b/kernel/arch/arm/boot/dts/imx7d.dtsi
index cff875b..b0bcfa9 100644
--- a/kernel/arch/arm/boot/dts/imx7d.dtsi
+++ b/kernel/arch/arm/boot/dts/imx7d.dtsi
@@ -7,6 +7,12 @@
 #include <dt-bindings/reset/imx7-reset.h>
 
 / {
+	aliases {
+		usb0 = &usbotg1;
+		usb1 = &usbotg2;
+		usb2 = &usbh;
+	};
+
 	cpus {
 		cpu0: cpu@0 {
 			clock-frequency = <996000000>;
diff --git a/kernel/arch/arm/boot/dts/imx7s.dtsi b/kernel/arch/arm/boot/dts/imx7s.dtsi
index 9e1b0af..854c380 100644
--- a/kernel/arch/arm/boot/dts/imx7s.dtsi
+++ b/kernel/arch/arm/boot/dts/imx7s.dtsi
@@ -47,6 +47,8 @@
 		spi1 = &ecspi2;
 		spi2 = &ecspi3;
 		spi3 = &ecspi4;
+		usb0 = &usbotg1;
+		usb1 = &usbh;
 	};
 
 	cpus {
@@ -494,7 +496,7 @@
 
 				mux: mux-controller {
 					compatible = "mmio-mux";
-					#mux-control-cells = <0>;
+					#mux-control-cells = <1>;
 					mux-reg-masks = <0x14 0x00000010>;
 				};
 
@@ -1135,6 +1137,8 @@
 					<&clks IMX7D_USDHC1_ROOT_CLK>;
 				clock-names = "ipg", "ahb", "per";
 				bus-width = <4>;
+				fsl,tuning-step = <2>;
+				fsl,tuning-start-tap = <20>;
 				status = "disabled";
 			};
 
@@ -1147,6 +1151,8 @@
 					<&clks IMX7D_USDHC2_ROOT_CLK>;
 				clock-names = "ipg", "ahb", "per";
 				bus-width = <4>;
+				fsl,tuning-step = <2>;
+				fsl,tuning-start-tap = <20>;
 				status = "disabled";
 			};
 
@@ -1159,6 +1165,8 @@
 					<&clks IMX7D_USDHC3_ROOT_CLK>;
 				clock-names = "ipg", "ahb", "per";
 				bus-width = <4>;
+				fsl,tuning-step = <2>;
+				fsl,tuning-start-tap = <20>;
 				status = "disabled";
 			};
 
@@ -1175,7 +1183,7 @@
 				status = "disabled";
 			};
 
-			sdma: sdma@30bd0000 {
+			sdma: dma-controller@30bd0000 {
 				compatible = "fsl,imx7d-sdma", "fsl,imx35-sdma";
 				reg = <0x30bd0000 0x10000>;
 				interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
@@ -1208,14 +1216,13 @@
 			};
 		};
 
-		dma_apbh: dma-apbh@33000000 {
+		dma_apbh: dma-controller@33000000 {
 			compatible = "fsl,imx7d-dma-apbh", "fsl,imx28-dma-apbh";
 			reg = <0x33000000 0x2000>;
 			interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
 			#dma-cells = <1>;
 			dma-channels = <4>;
 			clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>;
diff --git a/kernel/arch/arm/boot/dts/iwg20d-q7-common.dtsi b/kernel/arch/arm/boot/dts/iwg20d-q7-common.dtsi
index 63cafd2..358f547 100644
--- a/kernel/arch/arm/boot/dts/iwg20d-q7-common.dtsi
+++ b/kernel/arch/arm/boot/dts/iwg20d-q7-common.dtsi
@@ -49,7 +49,7 @@
 	lcd_backlight: backlight {
 		compatible = "pwm-backlight";
 
-		pwms = <&pwm3 0 5000000 0>;
+		pwms = <&pwm3 0 5000000>;
 		brightness-levels = <0 4 8 16 32 64 128 255>;
 		default-brightness-level = <7>;
 		enable-gpios = <&gpio5 14 GPIO_ACTIVE_HIGH>;
diff --git a/kernel/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi b/kernel/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
index 533a47b..1386a5e 100644
--- a/kernel/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
+++ b/kernel/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
@@ -59,7 +59,7 @@
 		};
 	};
 
-	pwm10: dmtimer-pwm {
+	pwm10: pwm-10 {
 		compatible = "ti,omap-dmtimer-pwm";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pwm_pins>;
diff --git a/kernel/arch/arm/boot/dts/meson8.dtsi b/kernel/arch/arm/boot/dts/meson8.dtsi
index 0853311..0d045ad 100644
--- a/kernel/arch/arm/boot/dts/meson8.dtsi
+++ b/kernel/arch/arm/boot/dts/meson8.dtsi
@@ -611,13 +611,13 @@
 
 &uart_B {
 	compatible = "amlogic,meson8-uart";
-	clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+	clocks = <&xtal>, <&clkc CLKID_UART1>, <&clkc CLKID_CLK81>;
 	clock-names = "xtal", "pclk", "baud";
 };
 
 &uart_C {
 	compatible = "amlogic,meson8-uart";
-	clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+	clocks = <&xtal>, <&clkc CLKID_UART2>, <&clkc CLKID_CLK81>;
 	clock-names = "xtal", "pclk", "baud";
 };
 
diff --git a/kernel/arch/arm/boot/dts/meson8b.dtsi b/kernel/arch/arm/boot/dts/meson8b.dtsi
index f6eb7c8..af2454c 100644
--- a/kernel/arch/arm/boot/dts/meson8b.dtsi
+++ b/kernel/arch/arm/boot/dts/meson8b.dtsi
@@ -599,13 +599,13 @@
 
 &uart_B {
 	compatible = "amlogic,meson8b-uart";
-	clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+	clocks = <&xtal>, <&clkc CLKID_UART1>, <&clkc CLKID_CLK81>;
 	clock-names = "xtal", "pclk", "baud";
 };
 
 &uart_C {
 	compatible = "amlogic,meson8b-uart";
-	clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+	clocks = <&xtal>, <&clkc CLKID_UART2>, <&clkc CLKID_CLK81>;
 	clock-names = "xtal", "pclk", "baud";
 };
 
diff --git a/kernel/arch/arm/boot/dts/motorola-mapphone-common.dtsi b/kernel/arch/arm/boot/dts/motorola-mapphone-common.dtsi
index 5f8f77c..8cb26b9 100644
--- a/kernel/arch/arm/boot/dts/motorola-mapphone-common.dtsi
+++ b/kernel/arch/arm/boot/dts/motorola-mapphone-common.dtsi
@@ -156,7 +156,7 @@
 		dais = <&mcbsp2_port>, <&mcbsp3_port>;
 	};
 
-	pwm8: dmtimer-pwm-8 {
+	pwm8: pwm-8 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&vibrator_direction_pin>;
 
@@ -166,7 +166,7 @@
 		ti,clock-source = <0x01>;
 	};
 
-	pwm9: dmtimer-pwm-9 {
+	pwm9: pwm-9 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&vibrator_enable_pin>;
 
@@ -190,6 +190,29 @@
 		brightness-levels = <31 63 95 127 159 191 223 255>;
 		default-brightness-level = <6>;
 	};
+};
+
+&cpu_thermal {
+	polling-delay = <10000>; /* milliseconds */
+};
+
+&cpu_alert0 {
+        temperature = <80000>; /* millicelsius */
+};
+
+&cpu0 {
+        /*
+	 * Note that the 1.2GiHz mode is enabled for all SoC variants for
+	 * the Motorola Android Linux v3.0.8 based kernel.
+	 */
+        operating-points = <
+	        /* kHz    uV */
+	        300000  1025000
+	        600000  1200000
+	        800000  1313000
+	        1008000 1375000
+		1200000 1375000
+        >;
 };
 
 &dss {
@@ -384,7 +407,7 @@
 	#address-cells = <1>;
 	#size-cells = <0>;
 	wlcore: wlcore@2 {
-		compatible = "ti,wl1285", "ti,wl1283";
+		compatible = "ti,wl1285";
 		reg = <2>;
 		/* gpio_100 with gpmc_wait2 pad as wakeirq */
 		interrupts-extended = <&gpio4 4 IRQ_TYPE_LEVEL_HIGH>,
@@ -716,12 +739,12 @@
 /* Configure pwm clock source for timers 8 & 9 */
 &timer8 {
 	assigned-clocks = <&abe_clkctrl OMAP4_TIMER8_CLKCTRL 24>;
-	assigned-clock-parents = <&sys_clkin_ck>;
+	assigned-clock-parents = <&sys_32k_ck>;
 };
 
 &timer9 {
 	assigned-clocks = <&l4_per_clkctrl OMAP4_TIMER9_CLKCTRL 24>;
-	assigned-clock-parents = <&sys_clkin_ck>;
+	assigned-clock-parents = <&sys_32k_ck>;
 };
 
 /*
diff --git a/kernel/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi b/kernel/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
index ded7e8f..9cf5265 100644
--- a/kernel/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
+++ b/kernel/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
@@ -8,9 +8,9 @@
 
 / {
 	vddvario: regulator-vddvario {
-		  compatible = "regulator-fixed";
-		  regulator-name = "vddvario";
-		  regulator-always-on;
+		compatible = "regulator-fixed";
+		regulator-name = "vddvario";
+		regulator-always-on;
 	};
 
 	vdd33a: regulator-vdd33a {
diff --git a/kernel/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi b/kernel/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
index e7534fe..bc8961f 100644
--- a/kernel/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
+++ b/kernel/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
@@ -12,9 +12,9 @@
 
 / {
 	vddvario: regulator-vddvario {
-		  compatible = "regulator-fixed";
-		  regulator-name = "vddvario";
-		  regulator-always-on;
+		compatible = "regulator-fixed";
+		regulator-name = "vddvario";
+		regulator-always-on;
 	};
 
 	vdd33a: regulator-vdd33a {
diff --git a/kernel/arch/arm/boot/dts/omap3-cm-t3517.dts b/kernel/arch/arm/boot/dts/omap3-cm-t3517.dts
index 3b83490..f25c0a8 100644
--- a/kernel/arch/arm/boot/dts/omap3-cm-t3517.dts
+++ b/kernel/arch/arm/boot/dts/omap3-cm-t3517.dts
@@ -11,12 +11,12 @@
 	model = "CompuLab CM-T3517";
 	compatible = "compulab,omap3-cm-t3517", "ti,am3517", "ti,omap3";
 
-	vmmc:  regulator-vmmc {
-                compatible = "regulator-fixed";
-                regulator-name = "vmmc";
-                regulator-min-microvolt = <3300000>;
-                regulator-max-microvolt = <3300000>;
-        };
+	vmmc: regulator-vmmc {
+		compatible = "regulator-fixed";
+		regulator-name = "vmmc";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
 
 	wl12xx_vmmc2: wl12xx_vmmc2 {
 		compatible = "regulator-fixed";
diff --git a/kernel/arch/arm/boot/dts/omap3-cm-t3x.dtsi b/kernel/arch/arm/boot/dts/omap3-cm-t3x.dtsi
index e61b8a2..51baedf 100644
--- a/kernel/arch/arm/boot/dts/omap3-cm-t3x.dtsi
+++ b/kernel/arch/arm/boot/dts/omap3-cm-t3x.dtsi
@@ -227,7 +227,7 @@
 
 		interrupt-parent = <&gpio2>;
 		interrupts = <25 0>;		/* gpio_57 */
-		pendown-gpio = <&gpio2 25 GPIO_ACTIVE_HIGH>;
+		pendown-gpio = <&gpio2 25 GPIO_ACTIVE_LOW>;
 
 		ti,x-min = /bits/ 16 <0x0>;
 		ti,x-max = /bits/ 16 <0x0fff>;
diff --git a/kernel/arch/arm/boot/dts/omap3-cpu-thermal.dtsi b/kernel/arch/arm/boot/dts/omap3-cpu-thermal.dtsi
index 1ed8378..51e6c2d 100644
--- a/kernel/arch/arm/boot/dts/omap3-cpu-thermal.dtsi
+++ b/kernel/arch/arm/boot/dts/omap3-cpu-thermal.dtsi
@@ -15,8 +15,7 @@
 	polling-delay = <1000>; /* milliseconds */
 	coefficients = <0 20000>;
 
-			/* sensor       ID */
-	thermal-sensors = <&bandgap     0>;
+	thermal-sensors = <&bandgap>;
 
 	cpu_trips: trips {
 		cpu_alert0: cpu_alert {
diff --git a/kernel/arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi b/kernel/arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi
index 3decc2d..a7f99ae 100644
--- a/kernel/arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi
+++ b/kernel/arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi
@@ -54,7 +54,7 @@
 
 		interrupt-parent = <&gpio1>;
 		interrupts = <27 0>;		/* gpio_27 */
-		pendown-gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>;
+		pendown-gpio = <&gpio1 27 GPIO_ACTIVE_LOW>;
 
 		ti,x-min = /bits/ 16 <0x0>;
 		ti,x-max = /bits/ 16 <0x0fff>;
diff --git a/kernel/arch/arm/boot/dts/omap3-gta04.dtsi b/kernel/arch/arm/boot/dts/omap3-gta04.dtsi
index cc8a378..68e56b5 100644
--- a/kernel/arch/arm/boot/dts/omap3-gta04.dtsi
+++ b/kernel/arch/arm/boot/dts/omap3-gta04.dtsi
@@ -147,7 +147,7 @@
 		pinctrl-0 = <&backlight_pins>;
 	};
 
-	pwm11: dmtimer-pwm {
+	pwm11: pwm-11 {
 		compatible = "ti,omap-dmtimer-pwm";
 		ti,timers = <&timer11>;
 		#pwm-cells = <3>;
@@ -332,7 +332,7 @@
 			OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE0)   /* dss_data22.dss_data22 */
 			OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE0)   /* dss_data23.dss_data23 */
 		>;
-       };
+	};
 
 	gps_pins: pinmux_gps_pins {
 		pinctrl-single,pins = <
@@ -609,6 +609,22 @@
 	clock-frequency = <100000>;
 };
 
+&mcspi1 {
+	status = "disabled";
+};
+
+&mcspi2 {
+	status = "disabled";
+};
+
+&mcspi3 {
+	status = "disabled";
+};
+
+&mcspi4 {
+	status = "disabled";
+};
+
 &usb_otg_hs {
 	interface-type = <0>;
 	usb-phy = <&usb2_phy>;
@@ -850,8 +866,8 @@
 };
 
 &hdqw1w {
-        pinctrl-names = "default";
-        pinctrl-0 = <&hdq_pins>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&hdq_pins>;
 };
 
 /* image signal processor within OMAP3 SoC */
diff --git a/kernel/arch/arm/boot/dts/omap3-gta04a5one.dts b/kernel/arch/arm/boot/dts/omap3-gta04a5one.dts
index 9db9fe6..95df45c 100644
--- a/kernel/arch/arm/boot/dts/omap3-gta04a5one.dts
+++ b/kernel/arch/arm/boot/dts/omap3-gta04a5one.dts
@@ -5,9 +5,11 @@
 
 #include "omap3-gta04a5.dts"
 
-&omap3_pmx_core {
+/ {
 	model = "Goldelico GTA04A5/Letux 2804 with OneNAND";
+};
 
+&omap3_pmx_core {
 	gpmc_pins: pinmux_gpmc_pins {
 		pinctrl-single,pins = <
 
diff --git a/kernel/arch/arm/boot/dts/omap3-ldp.dts b/kernel/arch/arm/boot/dts/omap3-ldp.dts
index 9c6a927..b898e2f 100644
--- a/kernel/arch/arm/boot/dts/omap3-ldp.dts
+++ b/kernel/arch/arm/boot/dts/omap3-ldp.dts
@@ -301,5 +301,5 @@
 
 &vaux1 {
 	/* Needed for ads7846 */
-        regulator-name = "vcc";
+	regulator-name = "vcc";
 };
diff --git a/kernel/arch/arm/boot/dts/omap3-lilly-a83x.dtsi b/kernel/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
index 73d4778..06e7cf9 100644
--- a/kernel/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
+++ b/kernel/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
@@ -311,7 +311,7 @@
 		interrupt-parent = <&gpio1>;
 		interrupts = <8 0>;   /* boot6 / gpio_8 */
 		spi-max-frequency = <1000000>;
-		pendown-gpio = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+		pendown-gpio = <&gpio1 8 GPIO_ACTIVE_LOW>;
 		vcc-supply = <&reg_vcc3>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&tsc2048_pins>;
diff --git a/kernel/arch/arm/boot/dts/omap3-n900.dts b/kernel/arch/arm/boot/dts/omap3-n900.dts
index d40c3d2..7dafd69 100644
--- a/kernel/arch/arm/boot/dts/omap3-n900.dts
+++ b/kernel/arch/arm/boot/dts/omap3-n900.dts
@@ -156,7 +156,7 @@
 		io-channel-names = "temp", "bsi", "vbat";
 	};
 
-	pwm9: dmtimer-pwm {
+	pwm9: pwm-9 {
 		compatible = "ti,omap-dmtimer-pwm";
 		#pwm-cells = <3>;
 		ti,timers = <&timer9>;
@@ -236,27 +236,27 @@
 		pinctrl-single,pins = <
 
 			/* address lines */
-                        OMAP3_CORE1_IOPAD(0x207a, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a1.gpmc_a1 */
-                        OMAP3_CORE1_IOPAD(0x207c, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a2.gpmc_a2 */
-                        OMAP3_CORE1_IOPAD(0x207e, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a3.gpmc_a3 */
+			OMAP3_CORE1_IOPAD(0x207a, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a1.gpmc_a1 */
+			OMAP3_CORE1_IOPAD(0x207c, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a2.gpmc_a2 */
+			OMAP3_CORE1_IOPAD(0x207e, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a3.gpmc_a3 */
 
 			/* data lines, gpmc_d0..d7 not muxable according to TRM */
-                        OMAP3_CORE1_IOPAD(0x209e, PIN_INPUT | MUX_MODE0)        /* gpmc_d8.gpmc_d8 */
-                        OMAP3_CORE1_IOPAD(0x20a0, PIN_INPUT | MUX_MODE0)        /* gpmc_d9.gpmc_d9 */
-                        OMAP3_CORE1_IOPAD(0x20a2, PIN_INPUT | MUX_MODE0)        /* gpmc_d10.gpmc_d10 */
-                        OMAP3_CORE1_IOPAD(0x20a4, PIN_INPUT | MUX_MODE0)        /* gpmc_d11.gpmc_d11 */
-                        OMAP3_CORE1_IOPAD(0x20a6, PIN_INPUT | MUX_MODE0)        /* gpmc_d12.gpmc_d12 */
-                        OMAP3_CORE1_IOPAD(0x20a8, PIN_INPUT | MUX_MODE0)        /* gpmc_d13.gpmc_d13 */
-                        OMAP3_CORE1_IOPAD(0x20aa, PIN_INPUT | MUX_MODE0)        /* gpmc_d14.gpmc_d14 */
-                        OMAP3_CORE1_IOPAD(0x20ac, PIN_INPUT | MUX_MODE0)        /* gpmc_d15.gpmc_d15 */
+			OMAP3_CORE1_IOPAD(0x209e, PIN_INPUT | MUX_MODE0)        /* gpmc_d8.gpmc_d8 */
+			OMAP3_CORE1_IOPAD(0x20a0, PIN_INPUT | MUX_MODE0)        /* gpmc_d9.gpmc_d9 */
+			OMAP3_CORE1_IOPAD(0x20a2, PIN_INPUT | MUX_MODE0)        /* gpmc_d10.gpmc_d10 */
+			OMAP3_CORE1_IOPAD(0x20a4, PIN_INPUT | MUX_MODE0)        /* gpmc_d11.gpmc_d11 */
+			OMAP3_CORE1_IOPAD(0x20a6, PIN_INPUT | MUX_MODE0)        /* gpmc_d12.gpmc_d12 */
+			OMAP3_CORE1_IOPAD(0x20a8, PIN_INPUT | MUX_MODE0)        /* gpmc_d13.gpmc_d13 */
+			OMAP3_CORE1_IOPAD(0x20aa, PIN_INPUT | MUX_MODE0)        /* gpmc_d14.gpmc_d14 */
+			OMAP3_CORE1_IOPAD(0x20ac, PIN_INPUT | MUX_MODE0)        /* gpmc_d15.gpmc_d15 */
 
 			/*
 			 * gpmc_ncs0, gpmc_nadv_ale, gpmc_noe, gpmc_nwe, gpmc_wait0 not muxable
 			 * according to TRM. OneNAND seems to require PIN_INPUT on clock.
 			 */
-                        OMAP3_CORE1_IOPAD(0x20b0, PIN_OUTPUT | MUX_MODE0)       /* gpmc_ncs1.gpmc_ncs1 */
-                        OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0)        /* gpmc_clk.gpmc_clk */
-		>;
+			OMAP3_CORE1_IOPAD(0x20b0, PIN_OUTPUT | MUX_MODE0)       /* gpmc_ncs1.gpmc_ncs1 */
+			OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0)        /* gpmc_clk.gpmc_clk */
+			>;
 	};
 
 	i2c1_pins: pinmux_i2c1_pins {
@@ -738,12 +738,12 @@
 
 	si4713: si4713@63 {
 		compatible = "silabs,si4713";
-                reg = <0x63>;
+		reg = <0x63>;
 
-                interrupts-extended = <&gpio2 21 IRQ_TYPE_EDGE_FALLING>; /* 53 */
-                reset-gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>; /* 163 */
-                vio-supply = <&vio>;
-                vdd-supply = <&vaux1>;
+		interrupts-extended = <&gpio2 21 IRQ_TYPE_EDGE_FALLING>; /* 53 */
+		reset-gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>; /* 163 */
+		vio-supply = <&vio>;
+		vdd-supply = <&vaux1>;
 	};
 
 	bq24150a: bq24150a@6b {
diff --git a/kernel/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi b/kernel/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi
index 1d6e88f..c3570ac 100644
--- a/kernel/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi
+++ b/kernel/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi
@@ -149,7 +149,7 @@
 
 		interrupt-parent = <&gpio4>;
 		interrupts = <18 0>;			/* gpio_114 */
-		pendown-gpio = <&gpio4 18 GPIO_ACTIVE_HIGH>;
+		pendown-gpio = <&gpio4 18 GPIO_ACTIVE_LOW>;
 
 		ti,x-min = /bits/ 16 <0x0>;
 		ti,x-max = /bits/ 16 <0x0fff>;
diff --git a/kernel/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi b/kernel/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi
index 7e30f9d..d95a0e1 100644
--- a/kernel/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi
+++ b/kernel/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi
@@ -160,7 +160,7 @@
 
 		interrupt-parent = <&gpio4>;
 		interrupts = <18 0>;			/* gpio_114 */
-		pendown-gpio = <&gpio4 18 GPIO_ACTIVE_HIGH>;
+		pendown-gpio = <&gpio4 18 GPIO_ACTIVE_LOW>;
 
 		ti,x-min = /bits/ 16 <0x0>;
 		ti,x-max = /bits/ 16 <0x0fff>;
diff --git a/kernel/arch/arm/boot/dts/omap3-pandora-common.dtsi b/kernel/arch/arm/boot/dts/omap3-pandora-common.dtsi
index 37608af..ca6d777 100644
--- a/kernel/arch/arm/boot/dts/omap3-pandora-common.dtsi
+++ b/kernel/arch/arm/boot/dts/omap3-pandora-common.dtsi
@@ -651,7 +651,7 @@
 		pinctrl-0 = <&penirq_pins>;
 		interrupt-parent = <&gpio3>;
 		interrupts = <30 IRQ_TYPE_NONE>;	/* GPIO_94 */
-		pendown-gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>;
+		pendown-gpio = <&gpio3 30 GPIO_ACTIVE_LOW>;
 		vcc-supply = <&vaux4>;
 
 		ti,x-min = /bits/ 16 <0>;
diff --git a/kernel/arch/arm/boot/dts/omap3-zoom3.dts b/kernel/arch/arm/boot/dts/omap3-zoom3.dts
index 0482676..ce58b1f 100644
--- a/kernel/arch/arm/boot/dts/omap3-zoom3.dts
+++ b/kernel/arch/arm/boot/dts/omap3-zoom3.dts
@@ -23,9 +23,9 @@
 	};
 
 	vddvario: regulator-vddvario {
-		  compatible = "regulator-fixed";
-		  regulator-name = "vddvario";
-		  regulator-always-on;
+		compatible = "regulator-fixed";
+		regulator-name = "vddvario";
+		regulator-always-on;
 	};
 
 	vdd33a: regulator-vdd33a {
@@ -84,28 +84,28 @@
 
 	uart1_pins: pinmux_uart1_pins {
 		pinctrl-single,pins = <
-                        OMAP3_CORE1_IOPAD(0x2180, PIN_INPUT | MUX_MODE0)		/* uart1_cts.uart1_cts */
-                        OMAP3_CORE1_IOPAD(0x217e, PIN_OUTPUT | MUX_MODE0)		/* uart1_rts.uart1_rts */
-                        OMAP3_CORE1_IOPAD(0x2182, WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */
-                        OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE0)		/* uart1_tx.uart1_tx */
+			OMAP3_CORE1_IOPAD(0x2180, PIN_INPUT | MUX_MODE0)		/* uart1_cts.uart1_cts */
+			OMAP3_CORE1_IOPAD(0x217e, PIN_OUTPUT | MUX_MODE0)		/* uart1_rts.uart1_rts */
+			OMAP3_CORE1_IOPAD(0x2182, WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */
+			OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE0)		/* uart1_tx.uart1_tx */
 		>;
 	};
 
 	uart2_pins: pinmux_uart2_pins {
 		pinctrl-single,pins = <
-                        OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT_PULLUP | MUX_MODE0)	/* uart2_cts.uart2_cts */
-                        OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0)		/* uart2_rts.uart2_rts */
-                        OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0)		/* uart2_rx.uart2_rx */
-                        OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0)		/* uart2_tx.uart2_tx */
+			OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT_PULLUP | MUX_MODE0)	/* uart2_cts.uart2_cts */
+			OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0)		/* uart2_rts.uart2_rts */
+			OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0)		/* uart2_rx.uart2_rx */
+			OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0)		/* uart2_tx.uart2_tx */
 		>;
 	};
 
 	uart3_pins: pinmux_uart3_pins {
 		pinctrl-single,pins = <
-                        OMAP3_CORE1_IOPAD(0x219a, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* uart3_cts_rctx.uart3_cts_rctx */
-                        OMAP3_CORE1_IOPAD(0x219c, PIN_OUTPUT | MUX_MODE0)		/* uart3_rts_sd.uart3_rts_sd */
-                        OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0)		/* uart3_rx_irrx.uart3_rx_irrx */
-                        OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0)		/* uart3_tx_irtx.uart3_tx_irtx */
+			OMAP3_CORE1_IOPAD(0x219a, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* uart3_cts_rctx.uart3_cts_rctx */
+			OMAP3_CORE1_IOPAD(0x219c, PIN_OUTPUT | MUX_MODE0)		/* uart3_rts_sd.uart3_rts_sd */
+			OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0)		/* uart3_rx_irrx.uart3_rx_irrx */
+			OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0)		/* uart3_tx_irtx.uart3_tx_irtx */
 		>;
 	};
 
@@ -205,22 +205,22 @@
 };
 
 &uart1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart1_pins>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
 };
 
 &uart2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart2_pins>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_pins>;
 };
 
 &uart3 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart3_pins>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3_pins>;
 };
 
 &uart4 {
-       status = "disabled";
+	status = "disabled";
 };
 
 &usb_otg_hs {
diff --git a/kernel/arch/arm/boot/dts/omap4-cpu-thermal.dtsi b/kernel/arch/arm/boot/dts/omap4-cpu-thermal.dtsi
index 03d054b..4b3afe2 100644
--- a/kernel/arch/arm/boot/dts/omap4-cpu-thermal.dtsi
+++ b/kernel/arch/arm/boot/dts/omap4-cpu-thermal.dtsi
@@ -15,21 +15,24 @@
 	polling-delay-passive = <250>; /* milliseconds */
 	polling-delay = <1000>; /* milliseconds */
 
-			/* sensor       ID */
-        thermal-sensors = <&bandgap     0>;
+	/*
+	 * See 44xx files for single sensor addressing, omap5 and dra7 need
+	 * also sensor ID for addressing.
+	 */
+	thermal-sensors = <&bandgap     0>;
 
 	cpu_trips: trips {
-                cpu_alert0: cpu_alert {
-                        temperature = <100000>; /* millicelsius */
-                        hysteresis = <2000>; /* millicelsius */
-                        type = "passive";
-                };
-                cpu_crit: cpu_crit {
-                        temperature = <125000>; /* millicelsius */
-                        hysteresis = <2000>; /* millicelsius */
-                        type = "critical";
-                };
-        };
+		cpu_alert0: cpu_alert {
+			temperature = <100000>; /* millicelsius */
+			hysteresis = <2000>; /* millicelsius */
+			type = "passive";
+		};
+		cpu_crit: cpu_crit {
+			temperature = <125000>; /* millicelsius */
+			hysteresis = <2000>; /* millicelsius */
+			type = "critical";
+		};
+	};
 
 	cpu_cooling_maps: cooling-maps {
 		map0 {
diff --git a/kernel/arch/arm/boot/dts/omap443x.dtsi b/kernel/arch/arm/boot/dts/omap443x.dtsi
index dd8ef58..cce39dc 100644
--- a/kernel/arch/arm/boot/dts/omap443x.dtsi
+++ b/kernel/arch/arm/boot/dts/omap443x.dtsi
@@ -72,6 +72,7 @@
 };
 
 &cpu_thermal {
+	thermal-sensors = <&bandgap>;
 	coefficients = <0 20000>;
 };
 
diff --git a/kernel/arch/arm/boot/dts/omap4460.dtsi b/kernel/arch/arm/boot/dts/omap4460.dtsi
index 2d3e549..d62e2ba 100644
--- a/kernel/arch/arm/boot/dts/omap4460.dtsi
+++ b/kernel/arch/arm/boot/dts/omap4460.dtsi
@@ -89,6 +89,7 @@
 };
 
 &cpu_thermal {
+	thermal-sensors = <&bandgap>;
 	coefficients = <348 (-9301)>;
 };
 
diff --git a/kernel/arch/arm/boot/dts/omap5-cm-t54.dts b/kernel/arch/arm/boot/dts/omap5-cm-t54.dts
index ca759b7..af288d6 100644
--- a/kernel/arch/arm/boot/dts/omap5-cm-t54.dts
+++ b/kernel/arch/arm/boot/dts/omap5-cm-t54.dts
@@ -84,36 +84,36 @@
 	};
 
 	lcd0: display {
-                compatible = "startek,startek-kd050c", "panel-dpi";
-                label = "lcd";
+		compatible = "startek,startek-kd050c", "panel-dpi";
+		label = "lcd";
 
-                pinctrl-names = "default";
-                pinctrl-0 = <&lcd_pins>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&lcd_pins>;
 
-                enable-gpios = <&gpio8 3 GPIO_ACTIVE_HIGH>;
+		enable-gpios = <&gpio8 3 GPIO_ACTIVE_HIGH>;
 
-                panel-timing {
-                        clock-frequency = <33000000>;
-                        hactive = <800>;
-                        vactive = <480>;
-                        hfront-porch = <40>;
-                        hback-porch = <40>;
-                        hsync-len = <43>;
-                        vback-porch = <29>;
-                        vfront-porch = <13>;
-                        vsync-len = <3>;
-                        hsync-active = <0>;
-                        vsync-active = <0>;
-                        de-active = <1>;
-                        pixelclk-active = <1>;
-                };
+		panel-timing {
+			clock-frequency = <33000000>;
+			hactive = <800>;
+			vactive = <480>;
+			hfront-porch = <40>;
+			hback-porch = <40>;
+			hsync-len = <43>;
+			vback-porch = <29>;
+			vfront-porch = <13>;
+			vsync-len = <3>;
+			hsync-active = <0>;
+			vsync-active = <0>;
+			de-active = <1>;
+			pixelclk-active = <1>;
+		};
 
-                port {
-                        lcd_in: endpoint {
-                                remote-endpoint = <&dpi_lcd_out>;
-                        };
-                };
-        };
+		port {
+			lcd_in: endpoint {
+				remote-endpoint = <&dpi_lcd_out>;
+			};
+		};
+	};
 
 	hdmi0: connector0 {
 		compatible = "hdmi-connector";
@@ -354,7 +354,7 @@
 
 		interrupt-parent = <&gpio1>;
 		interrupts = <15 0>;			/* gpio1_wk15 */
-		pendown-gpio = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+		pendown-gpio = <&gpio1 15 GPIO_ACTIVE_LOW>;
 
 
 		ti,x-min = /bits/ 16 <0x0>;
@@ -644,8 +644,8 @@
 };
 
 &usb3 {
-       extcon = <&extcon_usb3>;
-       vbus-supply = <&smps10_out1_reg>;
+	extcon = <&extcon_usb3>;
+	vbus-supply = <&smps10_out1_reg>;
 };
 
 &cpu0 {
diff --git a/kernel/arch/arm/boot/dts/qcom-apq8064.dtsi b/kernel/arch/arm/boot/dts/qcom-apq8064.dtsi
index 72c4a9f..fb25ede 100644
--- a/kernel/arch/arm/boot/dts/qcom-apq8064.dtsi
+++ b/kernel/arch/arm/boot/dts/qcom-apq8064.dtsi
@@ -1571,7 +1571,7 @@
 		};
 
 		etb@1a01000 {
-			compatible = "coresight-etb10", "arm,primecell";
+			compatible = "arm,coresight-etb10", "arm,primecell";
 			reg = <0x1a01000 0x1000>;
 
 			clocks = <&rpmcc RPM_QDSS_CLK>;
diff --git a/kernel/arch/arm/boot/dts/qcom-ipq4019.dtsi b/kernel/arch/arm/boot/dts/qcom-ipq4019.dtsi
index 3defd47..037bb8a 100644
--- a/kernel/arch/arm/boot/dts/qcom-ipq4019.dtsi
+++ b/kernel/arch/arm/boot/dts/qcom-ipq4019.dtsi
@@ -414,8 +414,8 @@
 			#address-cells = <3>;
 			#size-cells = <2>;
 
-			ranges = <0x81000000 0 0x40200000 0x40200000 0 0x00100000>,
-				 <0x82000000 0 0x40300000 0x40300000 0 0x00d00000>;
+			ranges = <0x81000000 0x0 0x00000000 0x40200000 0x0 0x00100000>,
+				 <0x82000000 0x0 0x40300000 0x40300000 0x0 0x00d00000>;
 
 			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "msi";
diff --git a/kernel/arch/arm/boot/dts/qcom-ipq8064.dtsi b/kernel/arch/arm/boot/dts/qcom-ipq8064.dtsi
index c514814..dca0ed6 100644
--- a/kernel/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/kernel/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -465,8 +465,8 @@
 			#address-cells = <3>;
 			#size-cells = <2>;
 
-			ranges = <0x81000000 0 0x0fe00000 0x0fe00000 0 0x00100000   /* downstream I/O */
-				  0x82000000 0 0x08000000 0x08000000 0 0x07e00000>; /* non-prefetchable memory */
+			ranges = <0x81000000 0x0 0x00000000 0x0fe00000 0x0 0x00010000   /* I/O */
+				  0x82000000 0x0 0x08000000 0x08000000 0x0 0x07e00000>; /* MEM */
 
 			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "msi";
@@ -516,8 +516,8 @@
 			#address-cells = <3>;
 			#size-cells = <2>;
 
-			ranges = <0x81000000 0 0x31e00000 0x31e00000 0 0x00100000   /* downstream I/O */
-				  0x82000000 0 0x2e000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */
+			ranges = <0x81000000 0x0 0x00000000 0x31e00000 0x0 0x00010000   /* I/O */
+				  0x82000000 0x0 0x2e000000 0x2e000000 0x0 0x03e00000>; /* MEM */
 
 			interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "msi";
@@ -567,8 +567,8 @@
 			#address-cells = <3>;
 			#size-cells = <2>;
 
-			ranges = <0x81000000 0 0x35e00000 0x35e00000 0 0x00100000   /* downstream I/O */
-				  0x82000000 0 0x32000000 0x32000000 0 0x03e00000>; /* non-prefetchable memory */
+			ranges = <0x81000000 0x0 0x00000000 0x35e00000 0x0 0x00010000   /* I/O */
+				  0x82000000 0x0 0x32000000 0x32000000 0x0 0x03e00000>; /* MEM */
 
 			interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "msi";
diff --git a/kernel/arch/arm/boot/dts/rk3288-evb-android-rk808-edp.dtsi b/kernel/arch/arm/boot/dts/rk3288-evb-android-rk808-edp.dtsi
index e8e3890..f0eea2f 100644
--- a/kernel/arch/arm/boot/dts/rk3288-evb-android-rk808-edp.dtsi
+++ b/kernel/arch/arm/boot/dts/rk3288-evb-android-rk808-edp.dtsi
@@ -15,6 +15,8 @@
 		backlight = <&backlight>;
 		enable-gpios = <&gpio7 RK_PA4 GPIO_ACTIVE_HIGH>;
 		prepare-delay-ms = <120>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		display-timings {
 			native-mode = <&timing0>;
diff --git a/kernel/arch/arm/boot/dts/rk3288-evb.dtsi b/kernel/arch/arm/boot/dts/rk3288-evb.dtsi
index f3b2325..d211a76 100644
--- a/kernel/arch/arm/boot/dts/rk3288-evb.dtsi
+++ b/kernel/arch/arm/boot/dts/rk3288-evb.dtsi
@@ -148,6 +148,8 @@
 		pinctrl-names = "default";
 		pinctrl-0 = <&lcd_cs>;
 		prepare-delay-ms = <120>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		panel-timing {
 			clock-frequency = <200000000>;
diff --git a/kernel/arch/arm/boot/dts/rk3308-evb-audio-v10-display-rgb-aarch32.dts b/kernel/arch/arm/boot/dts/rk3308-evb-audio-v10-display-rgb-aarch32.dts
new file mode 100644
index 0000000..e2f36bc
--- /dev/null
+++ b/kernel/arch/arm/boot/dts/rk3308-evb-audio-v10-display-rgb-aarch32.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+#include "arm64/rockchip/rk3308-evb-audio-v10-display-rgb.dts"
+
+/ {
+	model = "Rockchip RK3308 evb audio display rgb  board (AArch32)";
+	compatible = "rockchip,rk3308-evb-audio-v10-display-rgb-aarch32", "rockchip,rk3308";
+};
+
+&ramoops {
+	reg = <0x0 0x30000 0x0 0x20000>;
+	record-size = <0x00000>;
+	console-size = <0x20000>;
+};
diff --git a/kernel/arch/arm/boot/dts/rv1103g-evb2-v10.dts b/kernel/arch/arm/boot/dts/rv1103g-evb2-v10.dts
new file mode 100644
index 0000000..daffecc
--- /dev/null
+++ b/kernel/arch/arm/boot/dts/rv1103g-evb2-v10.dts
@@ -0,0 +1,304 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+/dts-v1/;
+
+#include "rv1103.dtsi"
+#include "rv1103-evb-v10.dtsi"
+#include "rv1106-thunder-boot-spi-nor.dtsi"
+
+/ {
+	model = "Rockchip RV1103G EVB2 IPC V10 Board";
+	compatible = "rockchip,rv1103g-evb2-v10", "rockchip,rv1103";
+
+	chosen {
+		bootargs = "loglevel=0 rootfstype=erofs rootflags=dax console=ttyFIQ0 root=/dev/rd0 snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=0 driver_async_probe=dwmmc_rockchip storagemedia=mtd androidboot.storagemedia=mtd androidboot.mode=normal";
+	};
+
+	vcc_1v8: vcc-1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v8";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	vcc_3v3: vcc-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_3v3";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vcc3v3_sd: vcc3v3-sd {
+		compatible = "regulator-fixed";
+		gpio = <&gpio1 RK_PC6 GPIO_ACTIVE_LOW>;
+		regulator-name = "vcc3v3_sd";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-low;
+		regulator-always-on;
+		regulator-boot-on;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdmmc_pwren>;
+	};
+
+	vcc3v3_wifi: vcc3v3-wifi {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_wifi";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-low;
+		regulator-always-on;
+		regulator-boot-on;
+		gpio = <&gpio1 RK_PC7 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_pwren>;
+	};
+
+	vdd_arm: vdd-arm {
+		compatible = "pwm-regulator";
+		pwms = <&pwm0 0 5000 1>;
+		regulator-name = "vdd_arm";
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <1000000>;
+		regulator-init-microvolt = <900000>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-settling-time-up-us = <250>;
+	};
+
+};
+
+&acodec {
+	#sound-dai-cells = <0>;
+	pa-ctl-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&csi2_dphy_hw {
+	status = "okay";
+};
+
+&csi2_dphy0 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			csi_dphy_input0: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&sc3338_out>;
+				data-lanes = <1 2>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			csi_dphy_output: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&mipi_csi2_input>;
+			};
+		};
+	};
+};
+
+&fiq_debugger {
+	rockchip,baudrate = <1500000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2m1_xfer>;
+};
+
+&i2c4 {
+	rockchip,amp-shared;
+	clock-frequency = <400000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c4m2_xfer>;
+	status = "okay";
+
+	sc3338: sc3338@30 {
+		compatible = "smartsens,sc3338";
+		status = "okay";
+		reg = <0x30>;
+		clocks = <&cru MCLK_REF_MIPI0>;
+		clock-names = "xvclk";
+		pwdn-gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mipi_refclk_out0>;
+		rockchip,camera-module-index = <0>;
+		rockchip,camera-module-facing = "back";
+		rockchip,camera-module-name = "FKO1";
+		rockchip,camera-module-lens-name = "30IRC-F16";
+		port {
+			sc3338_out: endpoint {
+				remote-endpoint = <&csi_dphy_input0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&mailbox {
+	status = "okay";
+};
+
+&memory {
+	reg = <0x00000000 0x04000000>;
+};
+
+&mipi0_csi2 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi_csi2_input: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&csi_dphy_output>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi_csi2_output: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&cif_mipi_in>;
+			};
+		};
+	};
+};
+
+&pinctrl {
+	sdmmc {
+		/omit-if-no-ref/
+		sdmmc_pwren: sdmmc-pwren {
+			rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	wifi {
+		wifi_pwren: wifi-pwren {
+			rockchip,pins = <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pwm10 {
+	status = "okay";
+};
+
+&pwm11 {
+	status = "okay";
+	pinctrl-0 = <&pwm11m1_pins>;
+};
+
+&rkcif {
+	status = "okay";
+};
+
+&rkcif_mipi_lvds {
+	status = "okay";
+
+	memory-region-thunderboot = <&rkisp_thunderboot>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mipi_pins>;
+	port {
+		/* MIPI CSI-2 endpoint */
+		cif_mipi_in: endpoint {
+			remote-endpoint = <&mipi_csi2_output>;
+		};
+	};
+};
+
+&rkcif_mipi_lvds_sditf {
+	status = "okay";
+
+	port {
+		/* MIPI CSI-2 endpoint */
+		mipi_lvds_sditf: endpoint {
+			remote-endpoint = <&isp_in>;
+		};
+	};
+};
+
+&rkisp {
+	status = "okay";
+};
+
+&rkisp_vir0 {
+	status = "okay";
+	memory-region-thunderboot = <&rkisp_thunderboot>;
+
+	port@0 {
+		isp_in: endpoint {
+			remote-endpoint = <&mipi_lvds_sditf>;
+		};
+	};
+};
+
+&rkisp_thunderboot {
+	/* reg's offset MUST match with RTOS */
+	/*
+	 * vicap, capture raw10, ceil(w*10/8/256)*256*h *4(buf num)
+	 * e.g. 2304x1296: 0xf30000
+	 */
+	reg = <0x00860000 0xf30000>;
+};
+
+&ramdisk_r {
+	reg = <0x1790000 (10 * 0x00100000)>;
+};
+
+&ramdisk_c {
+	reg = <0x2190000 (5 * 0x00100000)>;
+};
+
+&saradc {
+	status = "okay";
+	vref-supply = <&vcc_1v8>;
+};
+
+&sfc {
+	assigned-clocks = <&cru SCLK_SFC>;
+	assigned-clock-rates = <125000000>;
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <125000000>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <1>;
+	};
+};
+
+&thunder_boot_service {
+	status = "okay";
+};
+
+&usbdrd_dwc3 {
+	dr_mode = "host";
+};
diff --git a/kernel/arch/arm/boot/dts/rv1106-evb-cam.dtsi b/kernel/arch/arm/boot/dts/rv1106-evb-cam.dtsi
index 9bc4ef9..7d6793a 100644
--- a/kernel/arch/arm/boot/dts/rv1106-evb-cam.dtsi
+++ b/kernel/arch/arm/boot/dts/rv1106-evb-cam.dtsi
@@ -50,6 +50,26 @@
 				remote-endpoint = <&sc3338_out>;
 				data-lanes = <1 2>;
 			};
+			csi_dphy_input6: endpoint@6 {
+				reg = <6>;
+				remote-endpoint = <&imx415_out>;
+				data-lanes = <1 2>;
+			};
+			csi_dphy_input7: endpoint@7 {
+				reg = <7>;
+				remote-endpoint = <&sc450ai_out>;
+				data-lanes = <1 2>;
+			};
+			csi_dphy_input8: endpoint@8 {
+				reg = <8>;
+				remote-endpoint = <&sc401ai_out>;
+				data-lanes = <1 2>;
+			};
+			csi_dphy_input9: endpoint@9 {
+				reg = <9>;
+				remote-endpoint = <&sc200ai_out>;
+				data-lanes = <1 2>;
+			};
 		};
 
 		port@1 {
@@ -202,6 +222,94 @@
 			};
 		};
 	};
+
+	imx415: imx415@1a {
+		compatible = "sony,imx415";
+		status = "okay";
+		reg = <0x1a>;
+		clocks = <&cru MCLK_REF_MIPI0>;
+		clock-names = "xvclk";
+		reset-gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_LOW>;
+		pwdn-gpios = <&gpio3 RK_PD2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mipi_refclk_out0>;
+		rockchip,camera-module-index = <0>;
+		rockchip,camera-module-facing = "back";
+		rockchip,camera-module-name = "CMK-OT2022-PX1";
+		rockchip,camera-module-lens-name = "IR0147-36IRC-8M-F20";
+		port {
+			imx415_out: endpoint {
+				remote-endpoint = <&csi_dphy_input6>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+
+	sc450ai: sc450ai@30 {
+		compatible = "smartsens,sc450ai";
+		status = "okay";
+		reg = <0x30>;
+		clocks = <&cru MCLK_REF_MIPI0>;
+		clock-names = "xvclk";
+		reset-gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
+		pwdn-gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mipi_refclk_out0>;
+		rockchip,camera-module-index = <0>;
+		rockchip,camera-module-facing = "back";
+		rockchip,camera-module-name = "CMK-OT2119-PC1";
+		rockchip,camera-module-lens-name = "30IRC-F16";
+		port {
+			sc450ai_out: endpoint {
+				remote-endpoint = <&csi_dphy_input7>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+
+	sc401ai: sc401ai@30 {
+		compatible = "smartsens,sc401ai";
+		status = "okay";
+		reg = <0x30>;
+		clocks = <&cru MCLK_REF_MIPI0>;
+		clock-names = "xvclk";
+		reset-gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
+		pwdn-gpios = <&gpio3 RK_PD2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mipi_refclk_out0>;
+		rockchip,camera-module-index = <0>;
+		rockchip,camera-module-facing = "back";
+		rockchip,camera-module-name = "CMK-OT2115-PC1";
+		rockchip,camera-module-lens-name = "30IRC-F16";
+		port {
+			sc401ai_out: endpoint {
+				remote-endpoint = <&csi_dphy_input8>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+
+	sc200ai: sc200ai@30 {
+		compatible = "smartsens,sc200ai";
+		status = "okay";
+		reg = <0x30>;
+		clocks = <&cru MCLK_REF_MIPI0>;
+		clock-names = "xvclk";
+		reset-gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
+		pwdn-gpios = <&gpio3 RK_PD2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mipi_refclk_out0>;
+		rockchip,camera-module-index = <0>;
+		rockchip,camera-module-facing = "back";
+		rockchip,camera-module-name = "CMK-OT2115-PC1";
+		rockchip,camera-module-lens-name = "30IRC-F16";
+		port {
+			sc200ai_out: endpoint {
+				remote-endpoint = <&csi_dphy_input9>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
 };
 
 &mipi0_csi2 {
diff --git a/kernel/arch/arm/boot/dts/rv1106-evb-ext-mcu-v20.dtsi b/kernel/arch/arm/boot/dts/rv1106-evb-ext-mcu-v20.dtsi
new file mode 100644
index 0000000..6346ba8
--- /dev/null
+++ b/kernel/arch/arm/boot/dts/rv1106-evb-ext-mcu-v20.dtsi
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ */
+#include <dt-bindings/display/media-bus-format.h>
+
+/ {
+	backlight: backlight {
+		status = "okay";
+		compatible = "pwm-backlight";
+		pwms = <&pwm3 0 25000 0>;
+		brightness-levels = <
+			  0   1   2   3   4   5   6   7
+			  8   9  10  11  12  13  14  15
+			 16  17  18  19  20  21  22  23
+			 24  25  26  27  28  29  30  31
+			 32  33  34  35  36  37  38  39
+			 40  41  42  43  44  45  46  47
+			 48  49  50  51  52  53  54  55
+			 56  57  58  59  60  61  62  63
+			 64  65  66  67  68  69  70  71
+			 72  73  74  75  76  77  78  79
+			 80  81  82  83  84  85  86  87
+			 88  89  90  91  92  93  94  95
+			 96  97  98  99 100 101 102 103
+			104 105 106 107 108 109 110 111
+			112 113 114 115 116 117 118 119
+			120 121 122 123 124 125 126 127
+			128 129 130 131 132 133 134 135
+			136 137 138 139 140 141 142 143
+			144 145 146 147 148 149 150 151
+			152 153 154 155 156 157 158 159
+			160 161 162 163 164 165 166 167
+			168 169 170 171 172 173 174 175
+			176 177 178 179 180 181 182 183
+			184 185 186 187 188 189 190 191
+			192 193 194 195 196 197 198 199
+			200 201 202 203 204 205 206 207
+			208 209 210 211 212 213 214 215
+			216 217 218 219 220 221 222 223
+			224 225 226 227 228 229 230 231
+			232 233 234 235 236 237 238 239
+			240 241 242 243 244 245 246 247
+			248 249 250 251 252 253 254 255>;
+		default-brightness-level = <200>;
+	};
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		drm_logo: drm-logo@00000000 {
+			compatible = "rockchip,drm-logo";
+			reg = <0x0 0x0>;
+		};
+	};
+};
+
+&display_subsystem {
+	status = "okay";
+	logo-memory-region = <&drm_logo>;
+};
+
+&pwm3 {
+	status = "okay";
+	pinctrl-names = "active";
+	pinctrl-0 = <&pwm3m1_pins>;
+};
+
+&rgb {
+	status = "okay";
+	rockchip,data-sync-bypass;
+	pinctrl-names = "default";
+	/*
+	 * rgb3x8_pins for RGB3x8(8bit)
+	 * rgb565_pins for RGB565(16bit)
+	 */
+	pinctrl-0 = <&rgb3x8_pins>;
+	/*
+	 * 320x480 RGB/MCU screen K350C4516T
+	 */
+	mcu_panel: mcu-panel {
+		/*
+		 * MEDIA_BUS_FMT_RGB888_3X8  for RGB3x8(8bit)
+		 * MEDIA_BUS_FMT_RGB565_1X16 for RGB565(16bit)
+		 */
+		bus-format = <MEDIA_BUS_FMT_RGB888_3X8>;
+		backlight = <&backlight>;
+		enable-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>;
+		enable-delay-ms = <20>;
+		reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>;
+		reset-delay-ms = <10>;
+		prepare-delay-ms = <20>;
+		unprepare-delay-ms = <20>;
+		disable-delay-ms = <20>;
+		init-delay-ms = <10>;
+		width-mm = <217>;
+		height-mm = <136>;
+		// type:0 is cmd, 1 is data
+		panel-init-sequence = [
+			//type delay num val1 val2 val3
+			  00   00  01  e0
+			  01   00  01  00
+			  01   00  01  07
+			  01   00  01  0f
+			  01   00  01  0d
+			  01   00  01  1b
+			  01   00  01  0a
+			  01   00  01  3c
+			  01   00  01  78
+			  01   00  01  4a
+			  01   00  01  07
+			  01   00  01  0e
+			  01   00  01  09
+			  01   00  01  1b
+			  01   00  01  1e
+			  01   00  01  0f
+			  00   00  01  e1
+			  01   00  01  00
+			  01   00  01  22
+			  01   00  01  24
+			  01   00  01  06
+			  01   00  01  12
+			  01   00  01  07
+			  01   00  01  36
+			  01   00  01  47
+			  01   00  01  47
+			  01   00  01  06
+			  01   00  01  0a
+			  01   00  01  07
+			  01   00  01  30
+			  01   00  01  37
+			  01   00  01  0f
+			  00   00  01  c0
+			  01   00  01  10
+			  01   00  01  10
+			  00   00  01  c1
+			  01   00  01  41
+			  00   00  01  c5
+			  01   00  01  00
+			  01   00  01  22
+			  01   00  01  80
+			  00   00  01  36
+			  01   00  01  48
+			  00   00  01  3a
+			  01   00  01  66 /*
+					   * interface pixel format:
+					   * 66 for RGB3x8(8bit)
+					   * 55 for RGB565(16bit)
+					   */
+			  00   00  01  b0
+			  01   00  01  00
+			  00   00  01  b1
+			  01   00  01  70 /*
+					   * frame rate control:
+					   * 70 (45hz) for RGB3x8(8bit)
+					   * a0 (60hz) for RGB565(16bit)
+					   */
+			  01   00  01  11
+			  00   00  01  b4
+			  01   00  01  02
+			  00   00  01  B6
+			  01   00  01  02 /*
+					   * display function control:
+					   * 32 for RGB
+					   * 02 for MCU
+					   */
+			  01   00  01  02
+			  00   00  01  b7
+			  01   00  01  c6
+			  00   00  01  be
+			  01   00  01  00
+			  01   00  01  04
+			  00   00  01  e9
+			  01   00  01  00
+			  00   00  01  f7
+			  01   00  01  a9
+			  01   00  01  51
+			  01   00  01  2c
+			  01   00  01  82
+			  00   78  01  11
+			  00   32  01  29
+			  00   00  01  2c
+		];
+
+		panel-exit-sequence = [
+			//type delay num val1 val2 val3
+			00   0a  01  28
+			00   78  01  10
+		];
+
+		display-timings {
+			native-mode = <&kd050fwfba002_timing>;
+			kd050fwfba002_timing: timing0 {
+				/*
+				 * 7840125  for frame rate 45Hz
+				 * 10453500 for frame rate 60Hz
+				 */
+				clock-frequency = <7840125>;
+				hactive = <320>;
+				vactive = <480>;
+				hback-porch = <10>;
+				hfront-porch = <5>;
+				vback-porch = <10>;
+				vfront-porch = <5>;
+				hsync-len = <10>;
+				vsync-len = <10>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <0>;
+				pixelclk-active = <1>;
+			};
+		};
+
+		port {
+			panel_in_rgb: endpoint {
+				remote-endpoint = <&rgb_out_panel>;
+			};
+		};
+	};
+
+	ports {
+		rgb_out: port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			rgb_out_panel: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&panel_in_rgb>;
+			};
+		};
+	};
+};
+
+&rgb_in_vop {
+	status = "okay";
+};
+
+&route_rgb {
+	status = "disabled";
+};
+
+&vop {
+	status = "okay";
+	/*
+	 * Default config is as follows:
+	 *
+	 * mcu-pix-total = <9>;
+	 * mcu-cs-pst = <1>;
+	 * mcu-cs-pend = <8>;
+	 * mcu-rw-pst = <2>;
+	 * mcu-rw-pend = <5>;
+	 * mcu-hold-mode = <0>; // default set to 0
+	 *
+	 * To increase the frame rate, reduce all parameters because
+	 * the max dclk rate of mcu is 150M in rv1103/rv1106.
+	 */
+	mcu-timing {
+		mcu-pix-total = <5>;
+		mcu-cs-pst = <1>;
+		mcu-cs-pend = <4>;
+		mcu-rw-pst = <2>;
+		mcu-rw-pend = <3>;
+		mcu-hold-mode = <0>; // default set to 0
+	};
+};
diff --git a/kernel/arch/arm/boot/dts/rv1106-tb-nofastae-emmc.dtsi b/kernel/arch/arm/boot/dts/rv1106-tb-nofastae-emmc.dtsi
index 1095b35..b9e0c77 100644
--- a/kernel/arch/arm/boot/dts/rv1106-tb-nofastae-emmc.dtsi
+++ b/kernel/arch/arm/boot/dts/rv1106-tb-nofastae-emmc.dtsi
@@ -11,14 +11,16 @@
 			reg = <0x3f000 0x00001000>;
 		};
 
-		mmc_idmac: mmc@100000 {
-			reg = <0x00100000 0x00100000>;
+		mmc_idmac: mmc@80000 {
+			reg = <0x0080000 0x17e000>;
 		};
 	};
 
 	thunder_boot_mmc: thunder-boot-mmc {
 		compatible = "rockchip,thunder-boot-mmc";
 		reg = <0xffa90000 0x4000>;
+		clocks = <&cru HCLK_EMMC>, <&cru CCLK_SRC_EMMC>;
+		clock-names = "biu", "ciu";
 		memory-region-src = <&ramdisk_c>;
 		memory-region-dst = <&ramdisk_r>;
 		memory-region-idmac = <&mmc_idmac>;
diff --git a/kernel/arch/arm/boot/dts/rv1106-thunder-boot-emmc.dtsi b/kernel/arch/arm/boot/dts/rv1106-thunder-boot-emmc.dtsi
index 208cb55..90e7954 100644
--- a/kernel/arch/arm/boot/dts/rv1106-thunder-boot-emmc.dtsi
+++ b/kernel/arch/arm/boot/dts/rv1106-thunder-boot-emmc.dtsi
@@ -11,14 +11,16 @@
 			reg = <0x3f000 0x00001000>;
 		};
 
-		mmc_idmac: mmc@100000 {
-			reg = <0x00100000 0x00100000>;
+		mmc_idmac: mmc@80000 {
+			reg = <0x0080000 0x17e000>;
 		};
 	};
 
 	thunder_boot_mmc: thunder-boot-mmc {
 		compatible = "rockchip,thunder-boot-mmc";
 		reg = <0xffa90000 0x4000>;
+		clocks = <&cru HCLK_EMMC>, <&cru CCLK_SRC_EMMC>;
+		clock-names = "biu", "ciu";
 		memory-region-src = <&ramdisk_c>;
 		memory-region-dst = <&ramdisk_r>;
 		memory-region-idmac = <&mmc_idmac>;
diff --git a/kernel/arch/arm/boot/dts/rv1106-uvc.dtsi b/kernel/arch/arm/boot/dts/rv1106-uvc.dtsi
index cf9404b..8ead68b 100644
--- a/kernel/arch/arm/boot/dts/rv1106-uvc.dtsi
+++ b/kernel/arch/arm/boot/dts/rv1106-uvc.dtsi
@@ -87,6 +87,7 @@
 };
 
 &u2phy_otg {
+	rockchip,dis-u2-susphy;
 	status = "okay";
 };
 
diff --git a/kernel/arch/arm/boot/dts/rv1106.dtsi b/kernel/arch/arm/boot/dts/rv1106.dtsi
index ff475c1..ee3a90b 100644
--- a/kernel/arch/arm/boot/dts/rv1106.dtsi
+++ b/kernel/arch/arm/boot/dts/rv1106.dtsi
@@ -9,6 +9,7 @@
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/soc/rockchip,boot-mode.h>
 #include <dt-bindings/soc/rockchip-system-status.h>
+#include <dt-bindings/suspend/rockchip-rv1106.h>
 #include <dt-bindings/thermal/thermal.h>
 
 / {
@@ -328,6 +329,55 @@
 		status = "disabled";
 	};
 
+	rockchip_suspend: rockchip-suspend {
+		compatible = "rockchip,pm-config";
+		status = "okay";
+		rockchip,sleep-io-config = <
+			(0
+			| RKPM_IO_CFG_IOMUX_GPIO
+			| RKPM_IO_CFG_GPIO_DIR_INPUT
+			| RKPM_IO_CFG_PULL_DOWN
+			| RKPM_IO_CFG_ID(0)
+			)
+			(0
+			| RKPM_IO_CFG_IOMUX_GPIO
+			| RKPM_IO_CFG_GPIO_DIR_INPUT
+			| RKPM_IO_CFG_PULL_DOWN
+			| RKPM_IO_CFG_ID(1)
+			)
+			(0
+			| RKPM_IO_CFG_IOMUX_GPIO
+			| RKPM_IO_CFG_GPIO_DIR_INPUT
+			| RKPM_IO_CFG_PULL_DOWN
+			| RKPM_IO_CFG_ID(2)
+			)
+			(0
+			| RKPM_IO_CFG_IOMUX_GPIO
+			| RKPM_IO_CFG_GPIO_DIR_INPUT
+			| RKPM_IO_CFG_PULL_UP
+			| RKPM_IO_CFG_ID(3)
+			)
+			(0
+			| RKPM_IO_CFG_IOMUX_GPIO
+			| RKPM_IO_CFG_GPIO_DIR_INPUT
+			| RKPM_IO_CFG_PULL_UP
+			| RKPM_IO_CFG_ID(4)
+			)
+			(0
+			| RKPM_IO_CFG_IOMUX_GPIO
+			| RKPM_IO_CFG_GPIO_DIR_INPUT
+			| RKPM_IO_CFG_PULL_NONE
+			| RKPM_IO_CFG_ID(5)
+			)
+			(0
+			| RKPM_IO_CFG_IOMUX_GPIO
+			| RKPM_IO_CFG_GPIO_DIR_INPUT
+			| RKPM_IO_CFG_PULL_NONE
+			| RKPM_IO_CFG_ID(6)
+			)
+		>;
+	};
+
 	rockchip_system_monitor: rockchip-system-monitor {
 		compatible = "rockchip,system-monitor";
 
diff --git a/kernel/arch/arm/boot/dts/rv1106g-dual-sensor-extboard.dtsi b/kernel/arch/arm/boot/dts/rv1106g-dual-sensor-extboard.dtsi
new file mode 100644
index 0000000..d62ccdc
--- /dev/null
+++ b/kernel/arch/arm/boot/dts/rv1106g-dual-sensor-extboard.dtsi
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * Version  Sensor  I2C_ADDR   Lanes
+ * v1.0.0   os04a10   0x36    lane0~1(dphy1)
+ *          sc4336    0x30    lane2~3(dphy2)
+ * v1.1.0   gc2053    0x37    lane0~1(dphy1)
+ *          gc2053    0x3f    lane2~3(dphy2)
+ */
+
+&csi2_dphy_hw {
+	status = "okay";
+};
+
+&csi2_dphy1 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			csi_dphy_input0: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&ahd_out>;
+				data-lanes = <1 2>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			csi_dphy_output: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&mipi_csi2_input>;
+			};
+		};
+	};
+};
+
+&csi2_dphy2 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			csi_dphy_input1: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&sc3336_out>;
+				data-lanes = <1 2>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			csi_dphy_output1: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&mipi1_csi2_input>;
+			};
+		};
+	};
+};
+
+&i2c4 {
+	status = "okay";
+	clock-frequency = <400000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c4m2_xfer>;
+
+	tp9951_00: tp9951@45 {
+		compatible = "techpoint,tp9951";
+		status = "okay";
+		reg = <0x45>;
+		clocks = <&cru MCLK_REF_MIPI0>;
+		clock-names = "xvclk";
+		reset-gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_LOW>;
+		power-gpios = <&gpio3 RK_PD2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mipi_refclk_out0>;
+		rockchip,camera-module-index = <1>;
+		rockchip,camera-module-facing = "back";
+		rockchip,camera-module-name = "tp9951";
+		rockchip,camera-module-lens-name = "tp9951";
+		port {
+			ahd_out: endpoint {
+				remote-endpoint = <&csi_dphy_input0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+
+	sc3336: sc3336@30 {
+		compatible = "smartsens,sc3336";
+		status = "okay";
+		reg = <0x30>;
+		clocks = <&cru MCLK_REF_MIPI1>;
+		clock-names = "xvclk";
+		reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+		// pwdn-gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mipi_refclk_out1>;
+		rockchip,camera-module-index = <0>;
+		rockchip,camera-module-facing = "front";
+		rockchip,camera-module-name = "OT01";
+		rockchip,camera-module-lens-name = "40IRC_F16";
+		port {
+			sc3336_out: endpoint {
+				remote-endpoint = <&csi_dphy_input1>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&mipi0_csi2 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi_csi2_input: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&csi_dphy_output>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi_csi2_output: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&cif_mipi_in>;
+			};
+		};
+	};
+};
+
+&mipi1_csi2 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi1_csi2_input: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&csi_dphy_output1>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi1_csi2_output: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&cif_mipi_in1>;
+			};
+		};
+	};
+};
+
+&rkcif {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mipi_pins>;
+};
+
+&rkcif_mipi_lvds {
+	status = "okay";
+
+	port {
+		/* MIPI CSI-2 endpoint */
+		cif_mipi_in: endpoint {
+			remote-endpoint = <&mipi_csi2_output>;
+		};
+	};
+};
+
+
+&rkcif_mipi_lvds1 {
+	status = "okay";
+
+	port {
+		/* MIPI CSI-2 endpoint */
+		cif_mipi_in1: endpoint {
+			remote-endpoint = <&mipi1_csi2_output>;
+		};
+	};
+};
+
+&rkcif_mipi_lvds1_sditf {
+	status = "okay";
+
+	port {
+		/* MIPI CSI-2 endpoint */
+		mipi_lvds1_sditf: endpoint {
+			remote-endpoint = <&isp_in1>;
+		};
+	};
+};
+
+&rkisp {
+	status = "okay";
+};
+
+
+&rkisp_vir0 {
+	status = "okay";
+
+	port@0 {
+		isp_in1: endpoint {
+			remote-endpoint = <&mipi_lvds1_sditf>;
+		};
+	};
+};
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb1-mcu-display-v20.dts b/kernel/arch/arm/boot/dts/rv1106g-evb1-mcu-display-v20.dts
index 21dbea7..d2c2cd1 100644
--- a/kernel/arch/arm/boot/dts/rv1106g-evb1-mcu-display-v20.dts
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb1-mcu-display-v20.dts
@@ -5,310 +5,10 @@
 
 /dts-v1/;
 
-#include <dt-bindings/display/media-bus-format.h>
 #include "rv1106g-evb1-v11.dts"
+#include "rv1106-evb-ext-mcu-v10.dtsi"
 
 / {
 	model = "Rockchip RV1106G EVB1 V11 Board + RK EVB MCU 8BIT Display V20 Ext Board";
 	compatible = "rockchip,rv1106g-evb1-mcu-display-v20", "rockchip,rv1106";
-
-	backlight: backlight {
-		status = "okay";
-		compatible = "pwm-backlight";
-		pwms = <&pwm3 0 25000 0>;
-		brightness-levels = <
-			  0   1   2   3   4   5   6   7
-			  8   9  10  11  12  13  14  15
-			 16  17  18  19  20  21  22  23
-			 24  25  26  27  28  29  30  31
-			 32  33  34  35  36  37  38  39
-			 40  41  42  43  44  45  46  47
-			 48  49  50  51  52  53  54  55
-			 56  57  58  59  60  61  62  63
-			 64  65  66  67  68  69  70  71
-			 72  73  74  75  76  77  78  79
-			 80  81  82  83  84  85  86  87
-			 88  89  90  91  92  93  94  95
-			 96  97  98  99 100 101 102 103
-			104 105 106 107 108 109 110 111
-			112 113 114 115 116 117 118 119
-			120 121 122 123 124 125 126 127
-			128 129 130 131 132 133 134 135
-			136 137 138 139 140 141 142 143
-			144 145 146 147 148 149 150 151
-			152 153 154 155 156 157 158 159
-			160 161 162 163 164 165 166 167
-			168 169 170 171 172 173 174 175
-			176 177 178 179 180 181 182 183
-			184 185 186 187 188 189 190 191
-			192 193 194 195 196 197 198 199
-			200 201 202 203 204 205 206 207
-			208 209 210 211 212 213 214 215
-			216 217 218 219 220 221 222 223
-			224 225 226 227 228 229 230 231
-			232 233 234 235 236 237 238 239
-			240 241 242 243 244 245 246 247
-			248 249 250 251 252 253 254 255>;
-		default-brightness-level = <200>;
-	};
-
-	reserved-memory {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges;
-
-		linux,cma {
-			compatible = "shared-dma-pool";
-			inactive;
-			reusable;
-			size = <0x1000000>;
-			linux,cma-default;
-		};
-
-		drm_logo: drm-logo@00000000 {
-			compatible = "rockchip,drm-logo";
-			reg = <0x0 0x0>;
-		};
-	};
-};
-
-&display_subsystem {
-	status = "okay";
-	logo-memory-region = <&drm_logo>;
-};
-
-&pwm3 {
-	status = "okay";
-	pinctrl-names = "active";
-	pinctrl-0 = <&pwm3m1_pins>;
-};
-
-&rgb {
-	status = "okay";
-	rockchip,data-sync-bypass;
-	pinctrl-names = "default";
-	/*
-	 * rgb3x8_pins for RGB3x8(8bit)
-	 * rgb565_pins for RGB565(16bit)
-	 */
-	pinctrl-0 = <&rgb3x8_pins>;
-
-	/*
-	 * 320x480 RGB/MCU screen K350C4516T
-	 */
-	mcu_panel: mcu-panel {
-		/*
-		 * MEDIA_BUS_FMT_RGB888_3X8  for RGB3x8(8bit)
-		 * MEDIA_BUS_FMT_RGB565_1X16 for RGB565(16bit)
-		 */
-		bus-format = <MEDIA_BUS_FMT_RGB888_3X8>;
-		backlight = <&backlight>;
-		enable-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>;
-		enable-delay-ms = <20>;
-		reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>;
-		reset-delay-ms = <10>;
-		prepare-delay-ms = <20>;
-		unprepare-delay-ms = <20>;
-		disable-delay-ms = <20>;
-		init-delay-ms = <10>;
-		width-mm = <217>;
-		height-mm = <136>;
-
-		// type:0 is cmd, 1 is data
-		panel-init-sequence = [
-			//type delay num val1 val2 val3
-			  00   00  01  e0
-			  01   00  01  00
-			  01   00  01  07
-			  01   00  01  0f
-			  01   00  01  0d
-			  01   00  01  1b
-			  01   00  01  0a
-			  01   00  01  3c
-
-			  01   00  01  78
-			  01   00  01  4a
-			  01   00  01  07
-			  01   00  01  0e
-			  01   00  01  09
-			  01   00  01  1b
-			  01   00  01  1e
-			  01   00  01  0f
-
-			  00   00  01  e1
-			  01   00  01  00
-			  01   00  01  22
-			  01   00  01  24
-			  01   00  01  06
-			  01   00  01  12
-			  01   00  01  07
-			  01   00  01  36
-
-			  01   00  01  47
-			  01   00  01  47
-			  01   00  01  06
-			  01   00  01  0a
-			  01   00  01  07
-			  01   00  01  30
-			  01   00  01  37
-			  01   00  01  0f
-
-			  00   00  01  c0
-			  01   00  01  10
-			  01   00  01  10
-
-			  00   00  01  c1
-			  01   00  01  41
-
-			  00   00  01  c5
-			  01   00  01  00
-			  01   00  01  22
-			  01   00  01  80
-
-			  00   00  01  36
-			  01   00  01  48
-
-			  00   00  01  3a
-			  01   00  01  66 /*
-					   * interface pixel format:
-					   * 66 for RGB3x8(8bit)
-					   * 55 for RGB565(16bit)
-					   */
-
-			  00   00  01  b0
-			  01   00  01  00
-
-			  00   00  01  b1
-			  01   00  01  70 /*
-					   * frame rate control:
-					   * 70 (45hz) for RGB3x8(8bit)
-					   * a0 (60hz) for RGB565(16bit)
-					   */
-			  01   00  01  11
-			  00   00  01  b4
-			  01   00  01  02
-			  00   00  01  B6
-			  01   00  01  02 /*
-					   * display function control:
-					   * 32 for RGB
-					   * 02 for MCU
-					   */
-			  01   00  01  02
-
-			  00   00  01  b7
-			  01   00  01  c6
-
-			  00   00  01  be
-			  01   00  01  00
-			  01   00  01  04
-
-			  00   00  01  e9
-			  01   00  01  00
-
-			  00   00  01  f7
-			  01   00  01  a9
-			  01   00  01  51
-			  01   00  01  2c
-			  01   00  01  82
-
-			  00   78  01  11
-			  00   32  01  29
-			  00   00  01  2c
-		];
-
-		panel-exit-sequence = [
-			//type delay num val1 val2 val3
-			00   0a  01  28
-			00   78  01  10
-		];
-
-		display-timings {
-			native-mode = <&kd050fwfba002_timing>;
-
-			kd050fwfba002_timing: timing0 {
-				/*
-				 * 7840125  for frame rate 45Hz
-				 * 10453500 for frame rate 60Hz
-				 */
-				clock-frequency = <7840125>;
-				hactive = <320>;
-				vactive = <480>;
-				hback-porch = <10>;
-				hfront-porch = <5>;
-				vback-porch = <10>;
-				vfront-porch = <5>;
-				hsync-len = <10>;
-				vsync-len = <10>;
-				hsync-active = <0>;
-				vsync-active = <0>;
-				de-active = <0>;
-				pixelclk-active = <1>;
-			};
-		};
-
-		port {
-			panel_in_rgb: endpoint {
-				remote-endpoint = <&rgb_out_panel>;
-			};
-		};
-	};
-
-	ports {
-		rgb_out: port@1 {
-			reg = <1>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			rgb_out_panel: endpoint@0 {
-				reg = <0>;
-				remote-endpoint = <&panel_in_rgb>;
-			};
-		};
-	};
-};
-
-&rgb_in_vop {
-	status = "okay";
-};
-
-&route_rgb {
-	status = "disabled";
-};
-
-/*
- * The pins of sdmmc1 and lcd are multiplexed
- */
-&sdio {
-	status = "disabled";
-};
-
-&sdio_pwrseq {
-	status = "disabled";
-};
-
-&vop {
-	status = "okay";
-
-	/*
-	 * Default config is as follows:
-	 *
-	 * mcu-pix-total = <9>;
-	 * mcu-cs-pst = <1>;
-	 * mcu-cs-pend = <8>;
-	 * mcu-rw-pst = <2>;
-	 * mcu-rw-pend = <5>;
-	 * mcu-hold-mode = <0>; // default set to 0
-	 *
-	 * To increase the frame rate, reduce all parameters because
-	 * the max dclk rate of mcu is 150M in rv1103/rv1106.
-	 */
-	mcu-timing {
-		mcu-pix-total = <5>;
-		mcu-cs-pst = <1>;
-		mcu-cs-pend = <4>;
-		mcu-rw-pst = <2>;
-		mcu-rw-pend = <3>;
-
-		mcu-hold-mode = <0>; // default set to 0
-	};
 };
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb1-v11-4k.dts b/kernel/arch/arm/boot/dts/rv1106g-evb1-v11-4k.dts
new file mode 100644
index 0000000..2116496
--- /dev/null
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb1-v11-4k.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+/dts-v1/;
+
+#include "rv1106g-evb1-v11.dts"
+
+/ {
+	model = "Rockchip RV1106G EVB1 V11 Board For RV1106G3 4K Unite";
+	compatible = "rockchip,rv1106g-evb1-v11-4k", "rockchip,rv1106";
+};
+
+&rkisp {
+	rockchip,unite-en;
+};
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb1-v11-cvr-dual-cam.dts b/kernel/arch/arm/boot/dts/rv1106g-evb1-v11-cvr-dual-cam.dts
index 0368b0f..9cb3e3c 100644
--- a/kernel/arch/arm/boot/dts/rv1106g-evb1-v11-cvr-dual-cam.dts
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb1-v11-cvr-dual-cam.dts
@@ -173,7 +173,7 @@
 };
 
 &usbdrd_dwc3 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 };
 
 &saradc {
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb1-v11-cvr-ext-dual-cam.dts b/kernel/arch/arm/boot/dts/rv1106g-evb1-v11-cvr-ext-dual-cam.dts
new file mode 100644
index 0000000..79b0e99
--- /dev/null
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb1-v11-cvr-ext-dual-cam.dts
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+/dts-v1/;
+
+#include "rv1106.dtsi"
+#include "rv1106-evb-v10.dtsi"
+#include "rv1106-evb-ext-mcu-v20.dtsi"
+#include "rv1106g-dual-sensor-extboard.dtsi"
+
+/ {
+	model = "Rockchip RV1106G EVB1 V11 Board For Dual Camera";
+	compatible = "rockchip,rv1106g-evb1-v11-dual-cam", "rockchip,rv1106";
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_enable_h &wifi_vbat>;
+
+		/*
+		 * On the module itself this is one of these (depending
+		 * on the actual card populated):
+		 * - SDIO_RESET_L_WL_REG_ON
+		 * - PDN (power down when low)
+		 */
+		post-power-on-delay-ms = <300>;
+		reset-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>,
+			      <&gpio1 RK_PA0 GPIO_ACTIVE_LOW>;
+	};
+
+	vcc_1v8: vcc-1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v8";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	vcc_3v3: vcc-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_3v3";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vcc3v3_sd: vcc3v3-sd {
+		compatible = "regulator-fixed";
+		gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_LOW>;
+		regulator-name = "vcc3v3_sd";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdmmc_pwren>;
+	};
+
+	vccio_sd: vccio-sd {
+		compatible = "regulator-gpio";
+		regulator-name = "vccio_sd";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>;
+		states = <3300000 1
+			  1800000 0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdmmc_volt>;
+	};
+
+	wireless_wlan: wireless-wlan {
+		compatible = "wlan-platdata";
+		wifi_chip_type = "rtl8189fs";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_host_wake_irq>;
+		WIFI,host_wake_irq = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>;
+		status = "okay";
+	};
+};
+
+&pinctrl {
+	sdio-pwrseq {
+		wifi_enable_h: wifi-enable-h {
+			rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		wifi_vbat: wifi-vbat {
+			rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	sdmmc {
+		/omit-if-no-ref/
+		sdmmc_pwren: sdmmc-pwren {
+			rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		sdmmc_volt: sdmmc-volt {
+			rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	usb {
+		usb_pwren: usb-pwren {
+			rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	wireless-wlan {
+		wifi_host_wake_irq: wifi-host-wake-irq {
+			rockchip,pins = <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&saradc {
+	status = "okay";
+	vref-supply = <&vcc_1v8>;
+};
+
+&sdio {
+	max-frequency = <200000000>;
+	no-sd;
+	no-mmc;
+	bus-width = <4>;
+	cap-sd-highspeed;
+	cap-sdio-irq;
+	keep-power-in-suspend;
+	mmc-pwrseq = <&sdio_pwrseq>;
+	non-removable;
+	sd-uhs-sdr104;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc1m0_cmd &sdmmc1m0_clk &sdmmc1m0_bus4 &clk_32k>;
+	status = "okay";
+};
+
+&sdmmc {
+	max-frequency = <200000000>;
+	no-sdio;
+	no-mmc;
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_det &sdmmc0_bus4>;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc3v3_sd>;
+	vqmmc-supply = <&vccio_sd>;
+	status = "okay";
+};
+
+&sfc {
+	status = "okay";
+
+	flash@0 {
+		compatible = "spi-nand";
+		reg = <0>;
+		spi-max-frequency = <75000000>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <1>;
+	};
+};
+
+&u2phy_otg {
+	/delete-property/ vbus-supply;
+};
+
+&usbdrd_dwc3 {
+	dr_mode = "peripheral";
+};
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb1-v11-dual-cam.dts b/kernel/arch/arm/boot/dts/rv1106g-evb1-v11-dual-cam.dts
index a874f67..ca7a3ee 100644
--- a/kernel/arch/arm/boot/dts/rv1106g-evb1-v11-dual-cam.dts
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb1-v11-dual-cam.dts
@@ -35,5 +35,5 @@
 };
 
 &usbdrd_dwc3 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 };
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb1-v11.dts b/kernel/arch/arm/boot/dts/rv1106g-evb1-v11.dts
index 00faf05..dc61525 100644
--- a/kernel/arch/arm/boot/dts/rv1106g-evb1-v11.dts
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb1-v11.dts
@@ -35,7 +35,7 @@
 };
 
 &usbdrd_dwc3 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 };
 
 &vdd_arm {
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb2-v10-dual-camera.dts b/kernel/arch/arm/boot/dts/rv1106g-evb2-v10-dual-camera.dts
index b24766b..634d6e0 100644
--- a/kernel/arch/arm/boot/dts/rv1106g-evb2-v10-dual-camera.dts
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb2-v10-dual-camera.dts
@@ -416,5 +416,5 @@
 };
 
 &usbdrd_dwc3 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 };
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb2-v10.dts b/kernel/arch/arm/boot/dts/rv1106g-evb2-v10.dts
index 47b5646..43e39b2 100644
--- a/kernel/arch/arm/boot/dts/rv1106g-evb2-v10.dts
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb2-v10.dts
@@ -286,5 +286,5 @@
 };
 
 &usbdrd_dwc3 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 };
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb2-v11-emmc.dts b/kernel/arch/arm/boot/dts/rv1106g-evb2-v11-emmc.dts
index 653c4eb..3f85003 100644
--- a/kernel/arch/arm/boot/dts/rv1106g-evb2-v11-emmc.dts
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb2-v11-emmc.dts
@@ -285,5 +285,5 @@
 };
 
 &usbdrd_dwc3 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 };
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb2-v11-trailcam-emmc.dts b/kernel/arch/arm/boot/dts/rv1106g-evb2-v11-trailcam-emmc.dts
index 0710c27..153a729 100644
--- a/kernel/arch/arm/boot/dts/rv1106g-evb2-v11-trailcam-emmc.dts
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb2-v11-trailcam-emmc.dts
@@ -591,7 +591,7 @@
 };
 
 &usbdrd_dwc3 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 };
 
 &vop {
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-aov-spi-nor.dts b/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-aov-spi-nor.dts
new file mode 100644
index 0000000..7a5daaf
--- /dev/null
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-aov-spi-nor.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+/dts-v1/;
+
+#include "rv1106g-evb2-v10.dts"
+
+/ {
+	model = "Rockchip RV1106G EVB2 V12 Board";
+	compatible = "rockchip,rv1106g-evb2-v12", "rockchip,rv1106";
+};
+
+&rkcif_mipi_lvds {
+	rtt-suspend;
+	status = "okay";
+};
+
+&rkisp_vir0 {
+	memory-region-thunderboot = <&rkisp_thunderboot>;
+	rtt-suspend;
+	status = "okay";
+};
+
+&thunder_boot_service {
+	memory-no-free;
+	status = "okay";
+};
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-dual-camera-avs.dts b/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-dual-camera-avs.dts
new file mode 100644
index 0000000..b2054d7
--- /dev/null
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-dual-camera-avs.dts
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+/dts-v1/;
+
+#include "rv1106g-evb2-v10-dual-camera.dts"
+
+/ {
+	model = "Rockchip RV1106G EVB2 V12 Board With Dual Camera AVS Blend Mode";
+	compatible = "rockchip,rv1106g-evb2-v12-dual-camera-avs", "rockchip,rv1106";
+};
+
+/delete-node/ &sc230ai;
+/delete-node/ &sc301iot;
+
+&csi2_dphy1 {
+	ports {
+		port@0 {
+			csi_dphy_input0: endpoint@0 {
+				remote-endpoint = <&sc230ai_30_out>;
+			};
+		};
+	};
+};
+
+&csi2_dphy2 {
+	ports {
+		port@0 {
+			csi_dphy_input1: endpoint@0 {
+				remote-endpoint = <&sc230ai_32_out>;
+			};
+		};
+	};
+};
+
+&i2c4 {
+	sc230ai_32: sc230ai_32@32 {
+		compatible = "smartsens,sc230ai";
+		status = "okay";
+		reg = <0x32>;
+		clocks = <&cru MCLK_REF_MIPI1>;
+		clock-names = "xvclk";
+		reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mipi_refclk_out1>;
+		rockchip,camera-module-index = <1>;
+		rockchip,camera-module-facing = "back";
+		rockchip,camera-module-name = "CMK-OT2350-PC1";
+		rockchip,camera-module-lens-name = "65IRC-F16";
+		rockchip,camera-module-sync-mode = "slave";
+		port {
+			sc230ai_32_out: endpoint {
+				remote-endpoint = <&csi_dphy_input1>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+
+	sc230ai_30: sc230ai_30@30 {
+		compatible = "smartsens,sc230ai";
+		status = "okay";
+		reg = <0x30>;
+		clocks = <&cru MCLK_REF_MIPI0>;
+		clock-names = "xvclk";
+		reset-gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
+		pwdn-gpios = <&gpio3 RK_PD2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mipi_refclk_out0>;
+		rockchip,camera-module-index = <0>;
+		rockchip,camera-module-facing = "back";
+		rockchip,camera-module-name = "CMK-OT2350-PC1";
+		rockchip,camera-module-lens-name = "65IRC-F16";
+		rockchip,camera-module-sync-mode = "internal_master";
+		port {
+			sc230ai_30_out: endpoint {
+				remote-endpoint = <&csi_dphy_input0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&rkisp_thunderboot {
+	/* reg's offset MUST match with RTOS */
+	/*
+	 * vicap, capture raw10, ceil(w*10/8/256)*256*h *4(buf num)
+	 * e.g. 1920x1080: 0xa8c000
+	 * 0x008b0000 = (meta's reg offset) + (meta's reg size)
+	 *            = 0x00800000 + 0xb0000
+	 */
+	reg = <0x008b0000 0xa8c000>;
+};
+
+&ramdisk_r {
+	/*
+	 * 0x133c000 = (rkisp_thunderboot's reg offset)
+	 *             + (rkisp_thunderboot's reg size)
+	 *           =  0x008b0000 + 0xa8c000
+	 */
+	reg = <0x133c000 (15 * 0x00100000)>;
+};
+
+&ramdisk_c {
+	/*
+	 * 0x223c000 = (ramdisk_r's reg offset)
+	 *             + (ramdisk_r's reg size)
+	 *           =  0x133c000 + (15 * 0x00100000)
+	 */
+	reg = <0x223c000 (6 * 0x00100000)>;
+};
+
+&rkisp1_thunderboot {
+	/*
+	 * vicap, capture raw10, ceil(w*10/8/256)*256*h *4(buf num)
+	 * e.g. 1920x1080: 0xa8c0000
+	 * 0x283c000  = (ramdisk_c's reg offset) + (ramdisk_c's reg size)
+	 *            = 0x223c000 + (6 * 0x00100000)
+	 */
+	reg = <0x283c000 0xa8c000>;
+};
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-nofastae-emmc.dts b/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-nofastae-emmc.dts
index a49f45d..fba0ddb 100644
--- a/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-nofastae-emmc.dts
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-nofastae-emmc.dts
@@ -130,5 +130,5 @@
 };
 
 &usbdrd_dwc3 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 };
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-nofastae-spi-nand.dts b/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-nofastae-spi-nand.dts
index a7b53a7..93c6827 100644
--- a/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-nofastae-spi-nand.dts
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-nofastae-spi-nand.dts
@@ -125,5 +125,5 @@
 };
 
 &usbdrd_dwc3 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 };
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-nofastae-spi-nor.dts b/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-nofastae-spi-nor.dts
index dcc4da3..3871ca9 100644
--- a/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-nofastae-spi-nor.dts
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-nofastae-spi-nor.dts
@@ -130,5 +130,5 @@
 };
 
 &usbdrd_dwc3 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 };
diff --git a/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-wakeup.dts b/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-wakeup.dts
index 0ed1b84..138a446 100644
--- a/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-wakeup.dts
+++ b/kernel/arch/arm/boot/dts/rv1106g-evb2-v12-wakeup.dts
@@ -12,10 +12,6 @@
 	model = "Rockchip RV1106G EVB2 V12 Board";
 	compatible = "rockchip,rv1106g-evb2-v12-wakeup", "rockchip,rv1106";
 
-	chosen {
-		bootargs = "clk_gate.always_on=1";
-	};
-
 	reserved-memory {
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -25,31 +21,6 @@
 			reg = <0x40000 0x3c000>;
 		};
 
-		meta: meta@800000 {
-			/* reg's offset MUST match with RTOS */
-			reg = <0x00800000 0x60000>;
-		};
-
-		rkisp_thunderboot: rkisp@860000 {
-			/* reg's offset MUST match with RTOS */
-			/*
-			 * vicap, capture raw10, ceil(w*10/8/256)*256*h *4(buf num)
-			 * e.g. 1920x1080: 0xa8c000
-			 */
-			reg = <0x00860000 0xa8c000>;
-		};
-	};
-
-	thunder_boot_service: thunder-boot-service {
-		compatible = "rockchip,thunder-boot-service";
-		mbox-names = "amp-rx";
-		mboxes = <&mailbox 1>;
-		resets = <&cru SRST_CORE_MCU>, <&cru SRST_CORE_MCU_PWRUP>,
-			 <&cru SRST_CORE_MCU_CPU>, <&cru SRST_T_CORE_MCU_CPU>;
-		reset-names = "core_mcu", "core_mcu_pwrup",
-			      "core_mcu_cpu", "t_core_mcu_cpu";
-		memory-region = <&rtos>;
-		status = "disabled";
 	};
 
 	vcc_1v8: vcc-1v8 {
@@ -83,7 +54,7 @@
 	wireless_wlan: wireless-wlan {
 		compatible = "wlan-platdata";
 		WIFI,host_wake_irq = <&gpio1 RK_PB0 GPIO_ACTIVE_HIGH>;
-		status = "okay";
+		status = "disabled";
 	};
 
 	gpio-keys {
@@ -129,6 +100,12 @@
 			csi_dphy_input0: endpoint@0 {
 				reg = <0>;
 				remote-endpoint = <&sc3338_out>;
+				data-lanes = <1 2>;
+			};
+
+			csi_dphy_input1: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&sc200ai_out>;
 				data-lanes = <1 2>;
 			};
 		};
@@ -180,6 +157,28 @@
 			};
 		};
 	};
+
+	sc200ai: sc200ai@30 {
+		compatible = "smartsens,sc200ai";
+		status = "okay";
+		reg = <0x30>;
+		clocks = <&cru MCLK_REF_MIPI0>;
+		clock-names = "xvclk";
+		reset-gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
+		pwdn-gpios = <&gpio3 RK_PD2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mipi_refclk_out0>;
+		rockchip,camera-module-index = <0>;
+		rockchip,camera-module-facing = "back";
+		rockchip,camera-module-name = "CMK-OT2115-PC1";
+		rockchip,camera-module-lens-name = "30IRC-F16";
+		port {
+			sc200ai_out: endpoint {
+				remote-endpoint = <&csi_dphy_input1>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
 };
 
 &mipi0_csi2 {
@@ -223,7 +222,6 @@
 
 &rkcif_mipi_lvds {
 	status = "okay";
-	//memory-region-thunderboot = <&rkisp_thunderboot>;
 
 	pinctrl-names = "default";
 	pinctrl-0 = <&mipi_pins>;
@@ -323,5 +321,9 @@
 };
 
 &usbdrd_dwc3 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
+};
+
+&acodec {
+	status = "disabled";
 };
diff --git a/kernel/arch/arm/boot/dts/rv1126.dtsi b/kernel/arch/arm/boot/dts/rv1126.dtsi
index 1a464c3..729345d 100644
--- a/kernel/arch/arm/boot/dts/rv1126.dtsi
+++ b/kernel/arch/arm/boot/dts/rv1126.dtsi
@@ -957,6 +957,7 @@
 	pwm0: pwm@ff430000 {
 		compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
 		reg = <0xff430000 0x10>;
+		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm0m0_pins>;
@@ -968,6 +969,7 @@
 	pwm1: pwm@ff430010 {
 		compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
 		reg = <0xff430010 0x10>;
+		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm1m0_pins>;
@@ -979,6 +981,7 @@
 	pwm2: pwm@ff430020 {
 		compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
 		reg = <0xff430020 0x10>;
+		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm2m0_pins>;
@@ -990,6 +993,8 @@
 	pwm3: pwm@ff430030 {
 		compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
 		reg = <0xff430030 0x10>;
+		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm3m0_pins>;
@@ -1001,6 +1006,7 @@
 	pwm4: pwm@ff440000 {
 		compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
 		reg = <0xff440000 0x10>;
+		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm4m0_pins>;
@@ -1012,6 +1018,7 @@
 	pwm5: pwm@ff440010 {
 		compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
 		reg = <0xff440010 0x10>;
+		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm5m0_pins>;
@@ -1023,6 +1030,7 @@
 	pwm6: pwm@ff440020 {
 		compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
 		reg = <0xff440020 0x10>;
+		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm6m0_pins>;
@@ -1034,6 +1042,8 @@
 	pwm7: pwm@ff440030 {
 		compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
 		reg = <0xff440030 0x10>;
+		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm7m0_pins>;
@@ -1269,6 +1279,7 @@
 	pwm8: pwm@ff550000 {
 		compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
 		reg = <0xff550000 0x10>;
+		interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm8m0_pins>;
@@ -1280,6 +1291,7 @@
 	pwm9: pwm@ff550010 {
 		compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
 		reg = <0xff550010 0x10>;
+		interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm9m0_pins>;
@@ -1291,6 +1303,7 @@
 	pwm10: pwm@ff550020 {
 		compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
 		reg = <0xff550020 0x10>;
+		interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm10m0_pins>;
@@ -1302,6 +1315,8 @@
 	pwm11: pwm@ff550030 {
 		compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
 		reg = <0xff550030 0x10>;
+		interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm11m0_pins>;
@@ -2554,7 +2569,6 @@
 			snps,dis-del-phy-power-chg-quirk;
 			snps,tx-ipgap-linecheck-dis-quirk;
 			snps,tx-fifo-resize;
-			snps,xhci-trb-ent-quirk;
 			snps,usb2-lpm-disable;
 			snps,parkmode-disable-hs-quirk;
 			status = "disabled";
diff --git a/kernel/arch/arm/boot/dts/s3c6410-mini6410.dts b/kernel/arch/arm/boot/dts/s3c6410-mini6410.dts
index 285555b..0b07b3c 100644
--- a/kernel/arch/arm/boot/dts/s3c6410-mini6410.dts
+++ b/kernel/arch/arm/boot/dts/s3c6410-mini6410.dts
@@ -51,7 +51,7 @@
 
 		ethernet@18000000 {
 			compatible = "davicom,dm9000";
-			reg = <0x18000000 0x2 0x18000004 0x2>;
+			reg = <0x18000000 0x2>, <0x18000004 0x2>;
 			interrupt-parent = <&gpn>;
 			interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
 			davicom,no-eeprom;
@@ -193,12 +193,12 @@
 };
 
 &pinctrl0 {
-	gpio_leds: gpio-leds {
+	gpio_leds: gpio-leds-pins {
 		samsung,pins = "gpk-4", "gpk-5", "gpk-6", "gpk-7";
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	gpio_keys: gpio-keys {
+	gpio_keys: gpio-keys-pins {
 		samsung,pins = "gpn-0", "gpn-1", "gpn-2", "gpn-3",
 				"gpn-4", "gpn-5", "gpl-11", "gpl-12";
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
diff --git a/kernel/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi b/kernel/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi
index 8e9594d..0a3186d 100644
--- a/kernel/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi
+++ b/kernel/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi
@@ -16,111 +16,111 @@
 	 * Pin banks
 	 */
 
-	gpa: gpa {
+	gpa: gpa-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpb: gpb {
+	gpb: gpb-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpc: gpc {
+	gpc: gpc-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpd: gpd {
+	gpd: gpd-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpe: gpe {
+	gpe: gpe-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpf: gpf {
+	gpf: gpf-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpg: gpg {
+	gpg: gpg-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gph: gph {
+	gph: gph-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpi: gpi {
+	gpi: gpi-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpj: gpj {
+	gpj: gpj-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpk: gpk {
+	gpk: gpk-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpl: gpl {
+	gpl: gpl-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpm: gpm {
+	gpm: gpm-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpn: gpn {
+	gpn: gpn-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpo: gpo {
+	gpo: gpo-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpp: gpp {
+	gpp: gpp-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpq: gpq {
+	gpq: gpq-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
@@ -131,225 +131,225 @@
 	 * Pin groups
 	 */
 
-	uart0_data: uart0-data {
+	uart0_data: uart0-data-pins {
 		samsung,pins = "gpa-0", "gpa-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	uart0_fctl: uart0-fctl {
+	uart0_fctl: uart0-fctl-pins {
 		samsung,pins = "gpa-2", "gpa-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	uart1_data: uart1-data {
+	uart1_data: uart1-data-pins {
 		samsung,pins = "gpa-4", "gpa-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	uart1_fctl: uart1-fctl {
+	uart1_fctl: uart1-fctl-pins {
 		samsung,pins = "gpa-6", "gpa-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	uart2_data: uart2-data {
+	uart2_data: uart2-data-pins {
 		samsung,pins = "gpb-0", "gpb-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	uart3_data: uart3-data {
+	uart3_data: uart3-data-pins {
 		samsung,pins = "gpb-2", "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	ext_dma_0: ext-dma-0 {
+	ext_dma_0: ext-dma-0-pins {
 		samsung,pins = "gpb-0", "gpb-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	ext_dma_1: ext-dma-1 {
+	ext_dma_1: ext-dma-1-pins {
 		samsung,pins = "gpb-2", "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	irda_data_0: irda-data-0 {
+	irda_data_0: irda-data-0-pins {
 		samsung,pins = "gpb-0", "gpb-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	irda_data_1: irda-data-1 {
+	irda_data_1: irda-data-1-pins {
 		samsung,pins = "gpb-2", "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	irda_sdbw: irda-sdbw {
+	irda_sdbw: irda-sdbw-pins {
 		samsung,pins = "gpb-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	i2c0_bus: i2c0-bus {
+	i2c0_bus: i2c0-bus-pins {
 		samsung,pins = "gpb-5", "gpb-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 	};
 
-	i2c1_bus: i2c1-bus {
+	i2c1_bus: i2c1-bus-pins {
 		/* S3C6410-only */
 		samsung,pins = "gpb-2", "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_6>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 	};
 
-	spi0_bus: spi0-bus {
+	spi0_bus: spi0-bus-pins {
 		samsung,pins = "gpc-0", "gpc-1", "gpc-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 	};
 
-	spi0_cs: spi0-cs {
+	spi0_cs: spi0-cs-pins {
 		samsung,pins = "gpc-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	spi1_bus: spi1-bus {
+	spi1_bus: spi1-bus-pins {
 		samsung,pins = "gpc-4", "gpc-5", "gpc-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 	};
 
-	spi1_cs: spi1-cs {
+	spi1_cs: spi1-cs-pins {
 		samsung,pins = "gpc-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd0_cmd: sd0-cmd {
+	sd0_cmd: sd0-cmd-pins {
 		samsung,pins = "gpg-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd0_clk: sd0-clk {
+	sd0_clk: sd0-clk-pins {
 		samsung,pins = "gpg-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd0_bus1: sd0-bus1 {
+	sd0_bus1: sd0-bus1-pins {
 		samsung,pins = "gpg-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd0_bus4: sd0-bus4 {
+	sd0_bus4: sd0-bus4-pins {
 		samsung,pins = "gpg-2", "gpg-3", "gpg-4", "gpg-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd0_cd: sd0-cd {
+	sd0_cd: sd0-cd-pins {
 		samsung,pins = "gpg-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 	};
 
-	sd1_cmd: sd1-cmd {
+	sd1_cmd: sd1-cmd-pins {
 		samsung,pins = "gph-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd1_clk: sd1-clk {
+	sd1_clk: sd1-clk-pins {
 		samsung,pins = "gph-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd1_bus1: sd1-bus1 {
+	sd1_bus1: sd1-bus1-pins {
 		samsung,pins = "gph-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd1_bus4: sd1-bus4 {
+	sd1_bus4: sd1-bus4-pins {
 		samsung,pins = "gph-2", "gph-3", "gph-4", "gph-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd1_bus8: sd1-bus8 {
+	sd1_bus8: sd1-bus8-pins {
 		samsung,pins = "gph-2", "gph-3", "gph-4", "gph-5",
 				"gph-6", "gph-7", "gph-8", "gph-9";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd1_cd: sd1-cd {
+	sd1_cd: sd1-cd-pins {
 		samsung,pins = "gpg-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 	};
 
-	sd2_cmd: sd2-cmd {
+	sd2_cmd: sd2-cmd-pins {
 		samsung,pins = "gpc-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd2_clk: sd2-clk {
+	sd2_clk: sd2-clk-pins {
 		samsung,pins = "gpc-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd2_bus1: sd2-bus1 {
+	sd2_bus1: sd2-bus1-pins {
 		samsung,pins = "gph-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd2_bus4: sd2-bus4 {
+	sd2_bus4: sd2-bus4-pins {
 		samsung,pins = "gph-6", "gph-7", "gph-8", "gph-9";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	i2s0_bus: i2s0-bus {
+	i2s0_bus: i2s0-bus-pins {
 		samsung,pins = "gpd-0", "gpd-2", "gpd-3", "gpd-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	i2s0_cdclk: i2s0-cdclk {
+	i2s0_cdclk: i2s0-cdclk-pins {
 		samsung,pins = "gpd-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	i2s1_bus: i2s1-bus {
+	i2s1_bus: i2s1-bus-pins {
 		samsung,pins = "gpe-0", "gpe-2", "gpe-3", "gpe-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	i2s1_cdclk: i2s1-cdclk {
+	i2s1_cdclk: i2s1-cdclk-pins {
 		samsung,pins = "gpe-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	i2s2_bus: i2s2-bus {
+	i2s2_bus: i2s2-bus-pins {
 		/* S3C6410-only */
 		samsung,pins = "gpc-4", "gpc-5", "gpc-6", "gph-6",
 				"gph-8", "gph-9";
@@ -357,50 +357,50 @@
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	i2s2_cdclk: i2s2-cdclk {
+	i2s2_cdclk: i2s2-cdclk-pins {
 		/* S3C6410-only */
 		samsung,pins = "gph-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	pcm0_bus: pcm0-bus {
+	pcm0_bus: pcm0-bus-pins {
 		samsung,pins = "gpd-0", "gpd-2", "gpd-3", "gpd-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	pcm0_extclk: pcm0-extclk {
+	pcm0_extclk: pcm0-extclk-pins {
 		samsung,pins = "gpd-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	pcm1_bus: pcm1-bus {
+	pcm1_bus: pcm1-bus-pins {
 		samsung,pins = "gpe-0", "gpe-2", "gpe-3", "gpe-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	pcm1_extclk: pcm1-extclk {
+	pcm1_extclk: pcm1-extclk-pins {
 		samsung,pins = "gpe-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	ac97_bus_0: ac97-bus-0 {
+	ac97_bus_0: ac97-bus-0-pins {
 		samsung,pins = "gpd-0", "gpd-1", "gpd-2", "gpd-3", "gpd-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	ac97_bus_1: ac97-bus-1 {
+	ac97_bus_1: ac97-bus-1-pins {
 		samsung,pins = "gpe-0", "gpe-1", "gpe-2", "gpe-3", "gpe-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	cam_port: cam-port {
+	cam_port: cam-port-pins {
 		samsung,pins = "gpf-0", "gpf-1", "gpf-2", "gpf-4",
 				"gpf-5", "gpf-6", "gpf-7", "gpf-8",
 				"gpf-9", "gpf-10", "gpf-11", "gpf-12";
@@ -408,242 +408,242 @@
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	cam_rst: cam-rst {
+	cam_rst: cam-rst-pins {
 		samsung,pins = "gpf-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	cam_field: cam-field {
+	cam_field: cam-field-pins {
 		/* S3C6410-only */
 		samsung,pins = "gpb-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	pwm_extclk: pwm-extclk {
+	pwm_extclk: pwm-extclk-pins {
 		samsung,pins = "gpf-13";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	pwm0_out: pwm0-out {
+	pwm0_out: pwm0-out-pins {
 		samsung,pins = "gpf-14";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	pwm1_out: pwm1-out {
+	pwm1_out: pwm1-out-pins {
 		samsung,pins = "gpf-15";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	clkout0: clkout-0 {
+	clkout0: clkout-0-pins {
 		samsung,pins = "gpf-14";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col0_0: keypad-col0-0 {
+	keypad_col0_0: keypad-col0-0-pins {
 		samsung,pins = "gph-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col1_0: keypad-col1-0 {
+	keypad_col1_0: keypad-col1-0-pins {
 		samsung,pins = "gph-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col2_0: keypad-col2-0 {
+	keypad_col2_0: keypad-col2-0-pins {
 		samsung,pins = "gph-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col3_0: keypad-col3-0 {
+	keypad_col3_0: keypad-col3-0-pins {
 		samsung,pins = "gph-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col4_0: keypad-col4-0 {
+	keypad_col4_0: keypad-col4-0-pins {
 		samsung,pins = "gph-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col5_0: keypad-col5-0 {
+	keypad_col5_0: keypad-col5-0-pins {
 		samsung,pins = "gph-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col6_0: keypad-col6-0 {
+	keypad_col6_0: keypad-col6-0-pins {
 		samsung,pins = "gph-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col7_0: keypad-col7-0 {
+	keypad_col7_0: keypad-col7-0-pins {
 		samsung,pins = "gph-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col0_1: keypad-col0-1 {
+	keypad_col0_1: keypad-col0-1-pins {
 		samsung,pins = "gpl-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col1_1: keypad-col1-1 {
+	keypad_col1_1: keypad-col1-1-pins {
 		samsung,pins = "gpl-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col2_1: keypad-col2-1 {
+	keypad_col2_1: keypad-col2-1-pins {
 		samsung,pins = "gpl-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col3_1: keypad-col3-1 {
+	keypad_col3_1: keypad-col3-1-pins {
 		samsung,pins = "gpl-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col4_1: keypad-col4-1 {
+	keypad_col4_1: keypad-col4-1-pins {
 		samsung,pins = "gpl-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col5_1: keypad-col5-1 {
+	keypad_col5_1: keypad-col5-1-pins {
 		samsung,pins = "gpl-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col6_1: keypad-col6-1 {
+	keypad_col6_1: keypad-col6-1-pins {
 		samsung,pins = "gpl-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col7_1: keypad-col7-1 {
+	keypad_col7_1: keypad-col7-1-pins {
 		samsung,pins = "gpl-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row0_0: keypad-row0-0 {
+	keypad_row0_0: keypad-row0-0-pins {
 		samsung,pins = "gpk-8";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row1_0: keypad-row1-0 {
+	keypad_row1_0: keypad-row1-0-pins {
 		samsung,pins = "gpk-9";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row2_0: keypad-row2-0 {
+	keypad_row2_0: keypad-row2-0-pins {
 		samsung,pins = "gpk-10";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row3_0: keypad-row3-0 {
+	keypad_row3_0: keypad-row3-0-pins {
 		samsung,pins = "gpk-11";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row4_0: keypad-row4-0 {
+	keypad_row4_0: keypad-row4-0-pins {
 		samsung,pins = "gpk-12";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row5_0: keypad-row5-0 {
+	keypad_row5_0: keypad-row5-0-pins {
 		samsung,pins = "gpk-13";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row6_0: keypad-row6-0 {
+	keypad_row6_0: keypad-row6-0-pins {
 		samsung,pins = "gpk-14";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row7_0: keypad-row7-0 {
+	keypad_row7_0: keypad-row7-0-pins {
 		samsung,pins = "gpk-15";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row0_1: keypad-row0-1 {
+	keypad_row0_1: keypad-row0-1-pins {
 		samsung,pins = "gpn-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row1_1: keypad-row1-1 {
+	keypad_row1_1: keypad-row1-1-pins {
 		samsung,pins = "gpn-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row2_1: keypad-row2-1 {
+	keypad_row2_1: keypad-row2-1-pins {
 		samsung,pins = "gpn-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row3_1: keypad-row3-1 {
+	keypad_row3_1: keypad-row3-1-pins {
 		samsung,pins = "gpn-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row4_1: keypad-row4-1 {
+	keypad_row4_1: keypad-row4-1-pins {
 		samsung,pins = "gpn-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row5_1: keypad-row5-1 {
+	keypad_row5_1: keypad-row5-1-pins {
 		samsung,pins = "gpn-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row6_1: keypad-row6-1 {
+	keypad_row6_1: keypad-row6-1-pins {
 		samsung,pins = "gpn-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row7_1: keypad-row7-1 {
+	keypad_row7_1: keypad-row7-1-pins {
 		samsung,pins = "gpn-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	lcd_ctrl: lcd-ctrl {
+	lcd_ctrl: lcd-ctrl-pins {
 		samsung,pins = "gpj-8", "gpj-9", "gpj-10", "gpj-11";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	lcd_data16: lcd-data-width16 {
+	lcd_data16: lcd-data-width16-pins {
 		samsung,pins = "gpi-3", "gpi-4", "gpi-5", "gpi-6",
 				"gpi-7", "gpi-10", "gpi-11", "gpi-12",
 				"gpi-13", "gpi-14", "gpi-15", "gpj-3",
@@ -652,7 +652,7 @@
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	lcd_data18: lcd-data-width18 {
+	lcd_data18: lcd-data-width18-pins {
 		samsung,pins = "gpi-2", "gpi-3", "gpi-4", "gpi-5",
 				"gpi-6", "gpi-7", "gpi-10", "gpi-11",
 				"gpi-12", "gpi-13", "gpi-14", "gpi-15",
@@ -662,7 +662,7 @@
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	lcd_data24: lcd-data-width24 {
+	lcd_data24: lcd-data-width24-pins {
 		samsung,pins = "gpi-0", "gpi-1", "gpi-2", "gpi-3",
 				"gpi-4", "gpi-5", "gpi-6", "gpi-7",
 				"gpi-8", "gpi-9", "gpi-10", "gpi-11",
@@ -673,7 +673,7 @@
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	hsi_bus: hsi-bus {
+	hsi_bus: hsi-bus-pins {
 		samsung,pins = "gpk-0", "gpk-1", "gpk-2", "gpk-3",
 				"gpk-4", "gpk-5", "gpk-6", "gpk-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
diff --git a/kernel/arch/arm/boot/dts/s5pv210-aquila.dts b/kernel/arch/arm/boot/dts/s5pv210-aquila.dts
index 8e57e5a..6423348 100644
--- a/kernel/arch/arm/boot/dts/s5pv210-aquila.dts
+++ b/kernel/arch/arm/boot/dts/s5pv210-aquila.dts
@@ -277,37 +277,37 @@
 			<&keypad_col0>, <&keypad_col1>, <&keypad_col2>;
 	status = "okay";
 
-	key_1 {
+	key-1 {
 		keypad,row = <0>;
 		keypad,column = <1>;
 		linux,code = <KEY_CONNECT>;
 	};
 
-	key_2 {
+	key-2 {
 		keypad,row = <0>;
 		keypad,column = <2>;
 		linux,code = <KEY_BACK>;
 	};
 
-	key_3 {
+	key-3 {
 		keypad,row = <1>;
 		keypad,column = <1>;
 		linux,code = <KEY_CAMERA_FOCUS>;
 	};
 
-	key_4 {
+	key-4 {
 		keypad,row = <1>;
 		keypad,column = <2>;
 		linux,code = <KEY_VOLUMEUP>;
 	};
 
-	key_5 {
+	key-5 {
 		keypad,row = <2>;
 		keypad,column = <1>;
 		linux,code = <KEY_CAMERA>;
 	};
 
-	key_6 {
+	key-6 {
 		keypad,row = <2>;
 		keypad,column = <2>;
 		linux,code = <KEY_VOLUMEDOWN>;
diff --git a/kernel/arch/arm/boot/dts/s5pv210-aries.dtsi b/kernel/arch/arm/boot/dts/s5pv210-aries.dtsi
index 984bc8d..8f7dcd7 100644
--- a/kernel/arch/arm/boot/dts/s5pv210-aries.dtsi
+++ b/kernel/arch/arm/boot/dts/s5pv210-aries.dtsi
@@ -54,7 +54,7 @@
 		clock-frequency = <32768>;
 	};
 
-	bt_codec: bt_sco {
+	bt_codec: bt-sco {
 		compatible = "linux,bt-sco";
 		#sound-dai-cells = <0>;
 	};
@@ -113,7 +113,7 @@
 		pinctrl-names = "default";
 		pinctrl-0 = <&sound_i2c_pins>;
 
-		wm8994: wm8994@1a {
+		wm8994: audio-codec@1a {
 			compatible = "wlf,wm8994";
 			reg = <0x1a>;
 
diff --git a/kernel/arch/arm/boot/dts/s5pv210-goni.dts b/kernel/arch/arm/boot/dts/s5pv210-goni.dts
index ad8d5d2..5c1e12d 100644
--- a/kernel/arch/arm/boot/dts/s5pv210-goni.dts
+++ b/kernel/arch/arm/boot/dts/s5pv210-goni.dts
@@ -259,37 +259,37 @@
 			<&keypad_col0>, <&keypad_col1>, <&keypad_col2>;
 	status = "okay";
 
-	key_1 {
+	key-1 {
 		keypad,row = <0>;
 		keypad,column = <1>;
 		linux,code = <KEY_CONNECT>;
 	};
 
-	key_2 {
+	key-2 {
 		keypad,row = <0>;
 		keypad,column = <2>;
 		linux,code = <KEY_BACK>;
 	};
 
-	key_3 {
+	key-3 {
 		keypad,row = <1>;
 		keypad,column = <1>;
 		linux,code = <KEY_CAMERA_FOCUS>;
 	};
 
-	key_4 {
+	key-4 {
 		keypad,row = <1>;
 		keypad,column = <2>;
 		linux,code = <KEY_VOLUMEUP>;
 	};
 
-	key_5 {
+	key-5 {
 		keypad,row = <2>;
 		keypad,column = <1>;
 		linux,code = <KEY_CAMERA>;
 	};
 
-	key_6 {
+	key-6 {
 		keypad,row = <2>;
 		keypad,column = <2>;
 		linux,code = <KEY_VOLUMEDOWN>;
@@ -353,7 +353,7 @@
 	samsung,i2c-slave-addr = <0x10>;
 	status = "okay";
 
-	tsp@4a {
+	touchscreen@4a {
 		compatible = "atmel,maxtouch";
 		reg = <0x4a>;
 		interrupt-parent = <&gpj0>;
diff --git a/kernel/arch/arm/boot/dts/s5pv210-smdkv210.dts b/kernel/arch/arm/boot/dts/s5pv210-smdkv210.dts
index 7459e41..901e719 100644
--- a/kernel/arch/arm/boot/dts/s5pv210-smdkv210.dts
+++ b/kernel/arch/arm/boot/dts/s5pv210-smdkv210.dts
@@ -41,7 +41,7 @@
 
 	ethernet@a8000000 {
 		compatible = "davicom,dm9000";
-		reg = <0xA8000000 0x2 0xA8000002 0x2>;
+		reg = <0xa8000000 0x2>, <0xa8000002 0x2>;
 		interrupt-parent = <&gph1>;
 		interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
 		local-mac-address = [00 00 de ad be ef];
@@ -55,6 +55,14 @@
 		default-brightness-level = <6>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pwm3_out>;
+		power-supply = <&dc5v_reg>;
+	};
+
+	dc5v_reg: regulator-0 {
+		compatible = "regulator-fixed";
+		regulator-name = "DC5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
 	};
 };
 
@@ -76,61 +84,61 @@
 			<&keypad_col6>, <&keypad_col7>;
 	status = "okay";
 
-	key_1 {
+	key-1 {
 		keypad,row = <0>;
 		keypad,column = <3>;
 		linux,code = <KEY_1>;
 	};
 
-	key_2 {
+	key-2 {
 		keypad,row = <0>;
 		keypad,column = <4>;
 		linux,code = <KEY_2>;
 	};
 
-	key_3 {
+	key-3 {
 		keypad,row = <0>;
 		keypad,column = <5>;
 		linux,code = <KEY_3>;
 	};
 
-	key_4 {
+	key-4 {
 		keypad,row = <0>;
 		keypad,column = <6>;
 		linux,code = <KEY_4>;
 	};
 
-	key_5 {
+	key-5 {
 		keypad,row = <0
 		>;
 		keypad,column = <7>;
 		linux,code = <KEY_5>;
 	};
 
-	key_6 {
+	key-6 {
 		keypad,row = <1>;
 		keypad,column = <3>;
 		linux,code = <KEY_A>;
 	};
-	key_7 {
+	key-7 {
 		keypad,row = <1>;
 		keypad,column = <4>;
 		linux,code = <KEY_B>;
 	};
 
-	key_8 {
+	key-8 {
 		keypad,row = <1>;
 		keypad,column = <5>;
 		linux,code = <KEY_C>;
 	};
 
-	key_9 {
+	key-9 {
 		keypad,row = <1>;
 		keypad,column = <6>;
 		linux,code = <KEY_D>;
 	};
 
-	key_10 {
+	key-10 {
 		keypad,row = <1>;
 		keypad,column = <7>;
 		linux,code = <KEY_E>;
diff --git a/kernel/arch/arm/boot/dts/s5pv210.dtsi b/kernel/arch/arm/boot/dts/s5pv210.dtsi
index eb7e366..81ab9fe 100644
--- a/kernel/arch/arm/boot/dts/s5pv210.dtsi
+++ b/kernel/arch/arm/boot/dts/s5pv210.dtsi
@@ -583,7 +583,7 @@
 				interrupts = <29>;
 				clocks = <&clocks CLK_CSIS>,
 						<&clocks SCLK_CSIS>;
-				clock-names = "clk_csis",
+				clock-names = "csis",
 						"sclk_csis";
 				bus-width = <4>;
 				status = "disabled";
diff --git a/kernel/arch/arm/boot/dts/sam9x60.dtsi b/kernel/arch/arm/boot/dts/sam9x60.dtsi
index ec45ced..e1e0dec 100644
--- a/kernel/arch/arm/boot/dts/sam9x60.dtsi
+++ b/kernel/arch/arm/boot/dts/sam9x60.dtsi
@@ -567,7 +567,7 @@
 			mpddrc: mpddrc@ffffe800 {
 				compatible = "microchip,sam9x60-ddramc", "atmel,sama5d3-ddramc";
 				reg = <0xffffe800 0x200>;
-				clocks = <&pmc PMC_TYPE_SYSTEM 2>, <&pmc PMC_TYPE_CORE PMC_MCK>;
+				clocks = <&pmc PMC_TYPE_SYSTEM 2>, <&pmc PMC_TYPE_PERIPHERAL 49>;
 				clock-names = "ddrck", "mpddr";
 			};
 
diff --git a/kernel/arch/arm/boot/dts/spear320-hmi.dts b/kernel/arch/arm/boot/dts/spear320-hmi.dts
index 367ba48..5c562fb 100644
--- a/kernel/arch/arm/boot/dts/spear320-hmi.dts
+++ b/kernel/arch/arm/boot/dts/spear320-hmi.dts
@@ -242,7 +242,7 @@
 					irq-trigger = <0x1>;
 
 					stmpegpio: stmpe-gpio {
-						compatible = "stmpe,gpio";
+						compatible = "st,stmpe-gpio";
 						reg = <0>;
 						gpio-controller;
 						#gpio-cells = <2>;
diff --git a/kernel/arch/arm/boot/dts/spear600.dtsi b/kernel/arch/arm/boot/dts/spear600.dtsi
index fd41243..9d5a04a 100644
--- a/kernel/arch/arm/boot/dts/spear600.dtsi
+++ b/kernel/arch/arm/boot/dts/spear600.dtsi
@@ -47,7 +47,7 @@
 			compatible = "arm,pl110", "arm,primecell";
 			reg = <0xfc200000 0x1000>;
 			interrupt-parent = <&vic1>;
-			interrupts = <12>;
+			interrupts = <13>;
 			status = "disabled";
 		};
 
diff --git a/kernel/arch/arm/boot/dts/stm32f7-pinctrl.dtsi b/kernel/arch/arm/boot/dts/stm32f7-pinctrl.dtsi
index fe4cfda..4e1b8b3 100644
--- a/kernel/arch/arm/boot/dts/stm32f7-pinctrl.dtsi
+++ b/kernel/arch/arm/boot/dts/stm32f7-pinctrl.dtsi
@@ -284,6 +284,88 @@
 					slew-rate = <2>;
 				};
 			};
+
+			can1_pins_a: can1-0 {
+				pins1 {
+					pinmux = <STM32_PINMUX('A', 12, AF9)>; /* CAN1_TX */
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('A', 11, AF9)>; /* CAN1_RX */
+					bias-pull-up;
+				};
+			};
+
+			can1_pins_b: can1-1 {
+				pins1 {
+					pinmux = <STM32_PINMUX('B', 9, AF9)>; /* CAN1_TX */
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('B', 8, AF9)>; /* CAN1_RX */
+					bias-pull-up;
+				};
+			};
+
+			can1_pins_c: can1-2 {
+				pins1 {
+					pinmux = <STM32_PINMUX('D', 1, AF9)>; /* CAN1_TX */
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('D', 0, AF9)>; /* CAN1_RX */
+					bias-pull-up;
+
+				};
+			};
+
+			can1_pins_d: can1-3 {
+				pins1 {
+					pinmux = <STM32_PINMUX('H', 13, AF9)>; /* CAN1_TX */
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('H', 14, AF9)>; /* CAN1_RX */
+					bias-pull-up;
+
+				};
+			};
+
+			can2_pins_a: can2-0 {
+				pins1 {
+					pinmux = <STM32_PINMUX('B', 6, AF9)>; /* CAN2_TX */
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('B', 5, AF9)>; /* CAN2_RX */
+					bias-pull-up;
+				};
+			};
+
+			can2_pins_b: can2-1 {
+				pins1 {
+					pinmux = <STM32_PINMUX('B', 13, AF9)>; /* CAN2_TX */
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('B', 12, AF9)>; /* CAN2_RX */
+					bias-pull-up;
+				};
+			};
+
+			can3_pins_a: can3-0 {
+				pins1 {
+					pinmux = <STM32_PINMUX('A', 15, AF11)>; /* CAN3_TX */
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('A', 8, AF11)>; /* CAN3_RX */
+					bias-pull-up;
+				};
+			};
+
+			can3_pins_b: can3-1 {
+				pins1 {
+					pinmux = <STM32_PINMUX('B', 4, AF11)>;  /* CAN3_TX */
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('B', 3, AF11)>; /* CAN3_RX */
+					bias-pull-up;
+				};
+			};
 		};
 	};
 };
diff --git a/kernel/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/kernel/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
index ccf66ad..07c15c1 100644
--- a/kernel/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
+++ b/kernel/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
@@ -1102,7 +1102,7 @@
 		};
 	};
 
-	sai2a_sleep_pins_c: sai2a-2 {
+	sai2a_sleep_pins_c: sai2a-sleep-2 {
 		pins {
 			pinmux = <STM32_PINMUX('D', 13, ANALOG)>, /* SAI2_SCK_A */
 				 <STM32_PINMUX('D', 11, ANALOG)>, /* SAI2_SD_A */
diff --git a/kernel/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts b/kernel/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts
index 2e3c9fb..275167f 100644
--- a/kernel/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts
+++ b/kernel/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"
 
diff --git a/kernel/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi b/kernel/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
index fd0cd10..2c39106 100644
--- a/kernel/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
+++ b/kernel/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
@@ -120,10 +120,13 @@
 
 	sound {
 		compatible = "audio-graph-card";
-		routing =
-			"MIC_IN", "Capture",
-			"Capture", "Mic Bias",
-			"Playback", "HP_OUT";
+		widgets = "Headphone", "Headphone Jack",
+			  "Line", "Line In Jack",
+			  "Microphone", "Microphone Jack";
+		routing = "Headphone Jack", "HP_OUT",
+			  "LINE_IN", "Line In Jack",
+			  "MIC_IN", "Microphone Jack",
+			  "Microphone Jack", "Mic Bias";
 		dais = <&sai2a_port &sai2b_port>;
 		status = "okay";
 	};
diff --git a/kernel/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/kernel/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
index f3e0c79..d854730 100644
--- a/kernel/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+++ b/kernel/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
@@ -88,7 +88,7 @@
 
 	sound {
 		compatible = "audio-graph-card";
-		label = "STM32MP1-AV96-HDMI";
+		label = "STM32-AV96-HDMI";
 		dais = <&sai2a_port>;
 		status = "okay";
 	};
@@ -100,7 +100,7 @@
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 
-		gpios = <&gpioz 3 GPIO_ACTIVE_HIGH>;
+		gpio = <&gpioz 3 GPIO_ACTIVE_HIGH>;
 		enable-active-high;
 	};
 };
@@ -232,6 +232,12 @@
 			};
 		};
 	};
+
+	dh_mac_eeprom: eeprom@53 {
+		compatible = "atmel,24c02";
+		reg = <0x53>;
+		pagesize = <16>;
+	};
 };
 
 &ltdc {
diff --git a/kernel/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi b/kernel/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
index 5af3214..7dba02e 100644
--- a/kernel/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
+++ b/kernel/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
@@ -167,12 +167,6 @@
 			status = "disabled";
 		};
 	};
-
-	eeprom@53 {
-		compatible = "atmel,24c02";
-		reg = <0x53>;
-		pagesize = <16>;
-	};
 };
 
 &iwdg2 {
diff --git a/kernel/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi b/kernel/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
index 47df8ac..75869d6 100644
--- a/kernel/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
+++ b/kernel/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
@@ -406,7 +406,7 @@
 	i2s2_port: port {
 		i2s2_endpoint: endpoint {
 			remote-endpoint = <&sii9022_tx_endpoint>;
-			format = "i2s";
+			dai-format = "i2s";
 			mclk-fs = <256>;
 		};
 	};
diff --git a/kernel/arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts b/kernel/arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts
index 6b14927..8722fdf 100644
--- a/kernel/arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts
+++ b/kernel/arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts
@@ -57,7 +57,7 @@
 		regulator-ramp-delay = <50>; /* 4ms */
 
 		enable-active-high;
-		enable-gpio = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
+		enable-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
 		gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */
 		gpios-states = <0x1>;
 		states = <1100000 0>, <1300000 1>;
diff --git a/kernel/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/kernel/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
index 7aa64ae..6fc4801 100644
--- a/kernel/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
+++ b/kernel/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
@@ -132,6 +132,7 @@
 		reg = <0x2c0f0000 0x1000>;
 		interrupts = <0 84 4>;
 		cache-level = <2>;
+		cache-unified;
 	};
 
 	pmu {
diff --git a/kernel/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts b/kernel/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
index 6f1e0f0..073f5d1 100644
--- a/kernel/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
+++ b/kernel/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
@@ -345,7 +345,7 @@
 };
 
 &i2c2 {
-	tca9548@70 {
+	i2c-mux@70 {
 		compatible = "nxp,pca9548";
 		pinctrl-0 = <&pinctrl_i2c_mux_reset>;
 		pinctrl-names = "default";
diff --git a/kernel/arch/arm/boot/dts/vf610-zii-dev-rev-c.dts b/kernel/arch/arm/boot/dts/vf610-zii-dev-rev-c.dts
index de79dcf..ba2001f 100644
--- a/kernel/arch/arm/boot/dts/vf610-zii-dev-rev-c.dts
+++ b/kernel/arch/arm/boot/dts/vf610-zii-dev-rev-c.dts
@@ -340,7 +340,7 @@
 };
 
 &i2c2 {
-	tca9548@70 {
+	i2c-mux@70 {
 		compatible = "nxp,pca9548";
 		pinctrl-0 = <&pinctrl_i2c_mux_reset>;
 		pinctrl-names = "default";
diff --git a/kernel/arch/arm/configs/multi_v7_defconfig b/kernel/arch/arm/configs/multi_v7_defconfig
index a611b0c..07b7a2b 100644
--- a/kernel/arch/arm/configs/multi_v7_defconfig
+++ b/kernel/arch/arm/configs/multi_v7_defconfig
@@ -672,7 +672,6 @@
 CONFIG_DRM_IMX_HDMI=m
 CONFIG_DRM_ATMEL_HLCDC=m
 CONFIG_DRM_RCAR_DU=m
-CONFIG_DRM_RCAR_LVDS=y
 CONFIG_DRM_SUN4I=m
 CONFIG_DRM_MSM=m
 CONFIG_DRM_FSL_DCU=m
diff --git a/kernel/arch/arm/configs/rk3126_linux.config b/kernel/arch/arm/configs/rk3126_linux.config
index 52f5022..8720e22 100644
--- a/kernel/arch/arm/configs/rk3126_linux.config
+++ b/kernel/arch/arm/configs/rk3126_linux.config
@@ -47,7 +47,6 @@
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DNS_RESOLVER is not set
-# CONFIG_DRM_IGNORE_IOTCL_PERMIT is not set
 # CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
 # CONFIG_ECRYPT_FS is not set
 # CONFIG_ETHERNET is not set
@@ -227,7 +226,9 @@
 # CONFIG_GS_SC7A30 is not set
 # CONFIG_GYROSCOPE_DEVICE is not set
 # CONFIG_HALL_DEVICE is not set
+# CONFIG_IAM20680_ACC is not set
 # CONFIG_ICM2060X_ACC is not set
+# CONFIG_ICM4260X_ACC is not set
 CONFIG_INLINE_READ_UNLOCK=y
 CONFIG_INLINE_READ_UNLOCK_IRQ=y
 CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
diff --git a/kernel/arch/arm/configs/rk3126_linux_slc_nand.config b/kernel/arch/arm/configs/rk3126_linux_slc_nand.config
index 3b427c2..2fb867c 100644
--- a/kernel/arch/arm/configs/rk3126_linux_slc_nand.config
+++ b/kernel/arch/arm/configs/rk3126_linux_slc_nand.config
@@ -46,7 +46,6 @@
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DNS_RESOLVER is not set
-# CONFIG_DRM_IGNORE_IOTCL_PERMIT is not set
 # CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
 # CONFIG_ECRYPT_FS is not set
 # CONFIG_ETHERNET is not set
@@ -232,7 +231,9 @@
 # CONFIG_GS_SC7A30 is not set
 # CONFIG_GYROSCOPE_DEVICE is not set
 # CONFIG_HALL_DEVICE is not set
+# CONFIG_IAM20680_ACC is not set
 # CONFIG_ICM2060X_ACC is not set
+# CONFIG_ICM4260X_ACC is not set
 # CONFIG_INFTL is not set
 CONFIG_INLINE_READ_UNLOCK=y
 CONFIG_INLINE_READ_UNLOCK_IRQ=y
diff --git a/kernel/arch/arm/configs/rk3128_linux.config b/kernel/arch/arm/configs/rk3128_linux.config
index d93cbab..f953797 100644
--- a/kernel/arch/arm/configs/rk3128_linux.config
+++ b/kernel/arch/arm/configs/rk3128_linux.config
@@ -24,7 +24,6 @@
 # CONFIG_DEBUG_LIST is not set
 CONFIG_DETECT_HUNG_TASK=y
 # CONFIG_DNS_RESOLVER is not set
-# CONFIG_DRM_IGNORE_IOTCL_PERMIT is not set
 # CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
 CONFIG_DRM_UDL=y
 # CONFIG_ECRYPT_FS is not set
@@ -56,8 +55,6 @@
 # CONFIG_SCHED_STACK_END_CHECK is not set
 CONFIG_SENSOR_DEVICE=y
 # CONFIG_SERIAL_OF_PLATFORM is not set
-CONFIG_SND_SOC_ROCKCHIP_HDMI=y
-CONFIG_SND_SOC_ROCKCHIP_MULTICODECS=y
 CONFIG_SOFTLOCKUP_DETECTOR=y
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_TEE is not set
@@ -110,7 +107,9 @@
 # CONFIG_GS_SC7A30 is not set
 # CONFIG_GYROSCOPE_DEVICE is not set
 # CONFIG_HALL_DEVICE is not set
+# CONFIG_IAM20680_ACC is not set
 # CONFIG_ICM2060X_ACC is not set
+# CONFIG_ICM4260X_ACC is not set
 # CONFIG_INTERVAL_TREE_TEST is not set
 CONFIG_IPC_NS=y
 # CONFIG_LIGHT_DEVICE is not set
diff --git a/kernel/arch/arm/configs/rk3128_linux_spi_nand.config b/kernel/arch/arm/configs/rk3128_linux_spi_nand.config
index 753c628..4e257f0 100644
--- a/kernel/arch/arm/configs/rk3128_linux_spi_nand.config
+++ b/kernel/arch/arm/configs/rk3128_linux_spi_nand.config
@@ -24,7 +24,6 @@
 # CONFIG_DEBUG_LIST is not set
 CONFIG_DETECT_HUNG_TASK=y
 # CONFIG_DNS_RESOLVER is not set
-# CONFIG_DRM_IGNORE_IOTCL_PERMIT is not set
 # CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
 CONFIG_DRM_UDL=y
 # CONFIG_ECRYPT_FS is not set
@@ -59,7 +58,6 @@
 # CONFIG_SCHED_STACK_END_CHECK is not set
 CONFIG_SENSOR_DEVICE=y
 # CONFIG_SERIAL_OF_PLATFORM is not set
-CONFIG_SND_SOC_ROCKCHIP_MULTICODECS=y
 CONFIG_SOFTLOCKUP_DETECTOR=y
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_TEE is not set
@@ -112,7 +110,9 @@
 # CONFIG_GS_SC7A30 is not set
 # CONFIG_GYROSCOPE_DEVICE is not set
 # CONFIG_HALL_DEVICE is not set
+# CONFIG_IAM20680_ACC is not set
 # CONFIG_ICM2060X_ACC is not set
+# CONFIG_ICM4260X_ACC is not set
 # CONFIG_INTERVAL_TREE_TEST is not set
 CONFIG_IPC_NS=y
 # CONFIG_LIGHT_DEVICE is not set
@@ -134,6 +134,7 @@
 CONFIG_RK_SFTL=y
 CONFIG_ROCKCHIP_FLASH_VENDOR_STORAGE=y
 # CONFIG_ROCKCHIP_MMC_VENDOR_STORAGE is not set
+# CONFIG_ROCKCHIP_RAM_VENDOR_STORAGE is not set
 # CONFIG_ROCKCHIP_RGA2 is not set
 # CONFIG_STK8BAXX_ACC is not set
 # CONFIG_TEMPERATURE_DEVICE is not set
diff --git a/kernel/arch/arm/configs/rk3308_linux_aarch32_defconfig b/kernel/arch/arm/configs/rk3308_linux_aarch32_defconfig
index a24586d..664e4a1 100644
--- a/kernel/arch/arm/configs/rk3308_linux_aarch32_defconfig
+++ b/kernel/arch/arm/configs/rk3308_linux_aarch32_defconfig
@@ -2,9 +2,9 @@
 CONFIG_KERNEL_LZ4=y
 CONFIG_DEFAULT_HOSTNAME="localhost"
 CONFIG_SYSVIPC=y
-CONFIG_FHANDLE=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
 CONFIG_LOG_CPU_MAX_BUF_SHIFT=0
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_RD_BZIP2 is not set
@@ -18,40 +18,25 @@
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
 CONFIG_PROFILING=y
-CONFIG_JUMP_LABEL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_RK_PARTITION is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 CONFIG_ARCH_ROCKCHIP=y
 # CONFIG_CACHE_L2X0 is not set
 # CONFIG_ARM_ERRATA_643719 is not set
 CONFIG_SMP=y
 CONFIG_ARM_PSCI=y
-CONFIG_PREEMPT=y
 CONFIG_HZ_1000=y
 CONFIG_THUMB2_KERNEL=y
 # CONFIG_CPU_SW_DOMAIN_PAN is not set
-# CONFIG_COMPACTION is not set
-CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
-CONFIG_ZSMALLOC=y
 CONFIG_UACCESS_WITH_MEMCPY=y
-# CONFIG_SWIOTLB is not set
 CONFIG_CMDLINE="coherent_pool=4k user_debug=31"
 CONFIG_CMDLINE_EXTEND=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_STAT=y
-# CONFIG_CPU_FREQ_TIMES is not set
 CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_ARM_ROCKCHIP_CPUFREQ=y
 CONFIG_CPU_IDLE=y
-# CONFIG_CPU_IDLE_GOV_LADDER is not set
 CONFIG_ARM_CPUIDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
@@ -59,26 +44,34 @@
 CONFIG_PM_DEBUG=y
 CONFIG_PM_ADVANCED_DEBUG=y
 CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
+CONFIG_ROCKCHIP_SIP=y
+CONFIG_ARM_CRYPTO=y
+CONFIG_CRYPTO_SHA1_ARM_CE=y
+CONFIG_CRYPTO_SHA2_ARM_CE=y
+CONFIG_CRYPTO_AES_ARM_CE=y
+CONFIG_CRYPTO_GHASH_ARM_CE=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_COMPACTION is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
+CONFIG_ZSMALLOC=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
 CONFIG_SYN_COOKIES=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_ANDROID_PARANOID_NETWORK is not set
 CONFIG_BT=y
 CONFIG_BT_RFCOMM=y
 CONFIG_BT_RFCOMM_TTY=y
 CONFIG_BT_HIDP=y
 CONFIG_BT_HCIUART=y
 CONFIG_BT_HCIUART_H4=y
-CONFIG_BT_HCIUART_LL=y
 CONFIG_RFKILL=y
 CONFIG_RFKILL_RK=y
 CONFIG_DEVTMPFS=y
@@ -127,10 +120,7 @@
 # CONFIG_NET_VENDOR_XILINX is not set
 CONFIG_WL_ROCKCHIP=y
 CONFIG_WIFI_BUILD_MODULE=y
-# CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP is not set
 CONFIG_AP6XXX=m
-# CONFIG_RTL_WIRELESS_SOLUTION is not set
-# CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_ADC=y
 # CONFIG_KEYBOARD_ATKBD is not set
@@ -141,7 +131,6 @@
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_8250=y
 # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
 CONFIG_SERIAL_8250_CONSOLE=y
@@ -158,24 +147,24 @@
 CONFIG_SPI_ROCKCHIP=y
 CONFIG_SPI_SPIDEV=y
 CONFIG_GPIO_SYSFS=y
-CONFIG_POWER_SUPPLY=y
 CONFIG_POWER_RESET=y
 CONFIG_SYSCON_REBOOT_MODE=y
-CONFIG_POWER_AVS=y
-CONFIG_ROCKCHIP_IODOMAIN=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_RK816=y
 # CONFIG_HWMON is not set
 CONFIG_THERMAL=y
 CONFIG_THERMAL_WRITABLE_TRIPS=y
-CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR=y
 CONFIG_THERMAL_GOV_USER_SPACE=y
 CONFIG_CPU_THERMAL=y
 CONFIG_DEVFREQ_THERMAL=y
 CONFIG_ROCKCHIP_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_DW_WATCHDOG=y
+CONFIG_MFD_RK808=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_GPIO=y
 CONFIG_REGULATOR_PWM=y
+CONFIG_REGULATOR_RK808=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_SOUND=y
 CONFIG_SND=y
@@ -201,11 +190,10 @@
 CONFIG_USB_GADGET_DEBUG_FILES=y
 CONFIG_USB_GADGET_VBUS_DRAW=500
 CONFIG_USB_CONFIGFS=y
-CONFIG_USB_CONFIGFS_F_FS=y
 CONFIG_USB_CONFIGFS_UEVENT=y
+CONFIG_USB_CONFIGFS_F_FS=y
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=32
-# CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_NEW_LEDS=y
@@ -217,62 +205,48 @@
 CONFIG_LEDS_TRIGGER_ONESHOT=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
-CONFIG_LEDS_TRIGGER_MULTI_CTRL=y
 CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_RK_TIMER=y
+CONFIG_RTC_DRV_RK808=y
 CONFIG_DMADEVICES=y
 CONFIG_PL330_DMA=y
 CONFIG_STAGING=y
-# CONFIG_ANDROID_TIMED_OUTPUT is not set
+CONFIG_COMMON_CLK_RK808=y
+# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_CPU_RK3308=y
+CONFIG_ROCKCHIP_CPUINFO=y
+CONFIG_ROCKCHIP_GRF=y
+CONFIG_ROCKCHIP_IODOMAIN=y
+CONFIG_ROCKCHIP_PM_DOMAINS=y
+CONFIG_ROCKCHIP_PVTM=y
+CONFIG_ROCKCHIP_SUSPEND_MODE=y
 CONFIG_FIQ_DEBUGGER=y
 CONFIG_FIQ_DEBUGGER_NO_SLEEP=y
 CONFIG_FIQ_DEBUGGER_CONSOLE=y
 CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE=y
 CONFIG_FIQ_DEBUGGER_TRUST_ZONE=y
 CONFIG_RK_CONSOLE_THREAD=y
-# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set
-# CONFIG_IOMMU_SUPPORT is not set
-# CONFIG_CPU_RK312X is not set
-# CONFIG_CPU_RK3036 is not set
-# CONFIG_CPU_RK30XX is not set
-# CONFIG_CPU_RK3188 is not set
-# CONFIG_CPU_RK3288 is not set
-# CONFIG_CPU_RK322X is not set
-# CONFIG_CPU_RV1108 is not set
-CONFIG_CPU_RK3308=y
-CONFIG_ROCKCHIP_CPUINFO=y
-CONFIG_ROCKCHIP_GRF=y
-CONFIG_ROCKCHIP_PM_DOMAINS=y
-CONFIG_ROCKCHIP_PVTM=y
-CONFIG_ROCKCHIP_SUSPEND_MODE=y
 CONFIG_PM_DEVFREQ=y
 CONFIG_DEVFREQ_GOV_USERSPACE=y
 CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ=y
-CONFIG_PM_DEVFREQ_EVENT=y
 CONFIG_DEVFREQ_EVENT_ROCKCHIP_NOCP=y
 CONFIG_EXTCON=y
 CONFIG_IIO=y
-CONFIG_IIO_BUFFER=y
-CONFIG_IIO_KFIFO_BUF=y
-CONFIG_IIO_TRIGGER=y
 CONFIG_ROCKCHIP_SARADC=y
 CONFIG_PWM=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_PHY_ROCKCHIP_INNO_USB2=y
 CONFIG_ANDROID=y
-CONFIG_NVMEM=y
 CONFIG_ROCKCHIP_OTP=y
 CONFIG_RK_FLASH=y
 CONFIG_RK_NANDC_NAND=y
 CONFIG_RK_SFC_NAND=y
 CONFIG_RK_SFC_NOR=y
-CONFIG_ROCKCHIP_SIP=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT4_FS=m
 # CONFIG_DNOTIFY is not set
 CONFIG_VFAT_FS=m
 CONFIG_NTFS_FS=m
-# CONFIG_PROC_UID is not set
 CONFIG_TMPFS=y
 CONFIG_SQUASHFS=y
 CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
@@ -282,15 +256,14 @@
 CONFIG_PSTORE_CONSOLE=y
 CONFIG_PSTORE_RAM=y
 # CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_LZ4=y
+# CONFIG_CRYPTO_HW is not set
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_FS=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0
-CONFIG_LOCKUP_DETECTOR=y
-CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
-CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
+CONFIG_DEBUG_FS=y
 CONFIG_PANIC_ON_OOPS=y
 CONFIG_PANIC_TIMEOUT=1
 # CONFIG_SCHED_DEBUG is not set
@@ -299,13 +272,3 @@
 # CONFIG_FTRACE is not set
 CONFIG_STRICT_DEVMEM=y
 CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_SET_MODULE_RONX=y
-# CONFIG_CRYPTO_ECHAINIV is not set
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_LZ4=y
-# CONFIG_CRYPTO_HW is not set
-CONFIG_ARM_CRYPTO=y
-CONFIG_CRYPTO_SHA1_ARM_CE=y
-CONFIG_CRYPTO_SHA2_ARM_CE=y
-CONFIG_CRYPTO_AES_ARM_CE=y
-CONFIG_CRYPTO_GHASH_ARM_CE=y
diff --git a/kernel/arch/arm/configs/rk3308bs_aarch32_mipi_display.config b/kernel/arch/arm/configs/rk3308bs_aarch32_mipi_display.config
index 02e4fba..c92ccbb 100644
--- a/kernel/arch/arm/configs/rk3308bs_aarch32_mipi_display.config
+++ b/kernel/arch/arm/configs/rk3308bs_aarch32_mipi_display.config
@@ -268,6 +268,7 @@
 # CONFIG_TOUCHSCREEN_GSL3673_800X1280 is not set
 # CONFIG_TOUCHSCREEN_GSLX680_PAD is not set
 CONFIG_TOUCHSCREEN_GT1X=y
+CONFIG_TOUCHSCREEN_GT9XX=y
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
 # CONFIG_TOUCHSCREEN_HIDEEP is not set
diff --git a/kernel/arch/arm/configs/rv1106-evb.config b/kernel/arch/arm/configs/rv1106-evb.config
index e32ffeb..5ce66f6 100644
--- a/kernel/arch/arm/configs/rv1106-evb.config
+++ b/kernel/arch/arm/configs/rv1106-evb.config
@@ -37,9 +37,13 @@
 CONFIG_USB_SUPPORT=y
 CONFIG_VFAT_FS=y
 CONFIG_VIDEO_GC2053=m
+CONFIG_VIDEO_IMX415=m
 CONFIG_VIDEO_OS04A10=m
+CONFIG_VIDEO_SC200AI=m
 CONFIG_VIDEO_SC3336=m
+CONFIG_VIDEO_SC401AI=m
 CONFIG_VIDEO_SC4336=m
+CONFIG_VIDEO_SC450AI=m
 CONFIG_VIDEO_SC530AI=m
 CONFIG_WIRELESS=y
 CONFIG_WLAN=y
diff --git a/kernel/arch/arm/configs/rv1106-pm.config b/kernel/arch/arm/configs/rv1106-pm.config
index 5ab8a46..ae75f6d 100644
--- a/kernel/arch/arm/configs/rv1106-pm.config
+++ b/kernel/arch/arm/configs/rv1106-pm.config
@@ -3,3 +3,4 @@
 CONFIG_PM_SLEEP_DEBUG=y
 CONFIG_PM_WAKELOCKS=y
 CONFIG_SUSPEND=y
+CONFIG_ROCKCHIP_SUSPEND_MODE=y
diff --git a/kernel/arch/arm/configs/rv1106-tb-nofastae.config b/kernel/arch/arm/configs/rv1106-tb-nofastae.config
index ec66807..92e443e 100644
--- a/kernel/arch/arm/configs/rv1106-tb-nofastae.config
+++ b/kernel/arch/arm/configs/rv1106-tb-nofastae.config
@@ -312,7 +312,7 @@
 # CONFIG_PL320_MBOX is not set
 # CONFIG_PLATFORM_MHU is not set
 # CONFIG_PWRSEQ_EMMC is not set
-# CONFIG_PWRSEQ_SIMPLE is not set
+CONFIG_PWRSEQ_SIMPLE=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_GZIP is not set
 # CONFIG_RD_LZ4 is not set
diff --git a/kernel/arch/arm/configs/rv1106-wakeup.config b/kernel/arch/arm/configs/rv1106-wakeup.config
index 65f9b60..605fe71 100644
--- a/kernel/arch/arm/configs/rv1106-wakeup.config
+++ b/kernel/arch/arm/configs/rv1106-wakeup.config
@@ -1,5 +1,13 @@
+# CONFIG_ETHERNET is not set
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_INPUT=y
-CONFIG_RV1106_HPMCU_FAST_WAKEUP=y
+# CONFIG_MDIO_DEVICE is not set
+# CONFIG_PHYLIB is not set
+CONFIG_PHY_ROCKCHIP_CSI2_DPHY=y
+CONFIG_RV1106_PMU_WAKEUP_TIMEOUT=y
+CONFIG_VIDEO_CAM_SLEEP_WAKEUP=y
+CONFIG_VIDEO_ROCKCHIP_CIF=y
+CONFIG_VIDEO_SC200AI=y
 CONFIG_VIDEO_SC301IOT=y
 # CONFIG_VIDEO_SC3336 is not set
 CONFIG_VIDEO_SC3338=y
@@ -74,7 +82,7 @@
 # CONFIG_HID_ZYDACRON is not set
 # CONFIG_I2C_HID is not set
 # CONFIG_INPUT_EVBUG is not set
-# CONFIG_INPUT_EVDEV is not set
+CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_JOYDEV is not set
 # CONFIG_INPUT_JOYSTICK is not set
@@ -117,9 +125,11 @@
 # CONFIG_RC_CORE is not set
 # CONFIG_RMI4_CORE is not set
 # CONFIG_ROCKCHIP_REMOTECTL is not set
+CONFIG_SCHED_HRTICK=y
 # CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_SENSORS_LIS3_SPI is not set
 # CONFIG_SENSOR_DEVICE is not set
+# CONFIG_SND_HRTIMER is not set
 CONFIG_SND_JACK_INPUT_DEV=y
 # CONFIG_SND_SOC_CS42L52 is not set
 # CONFIG_SND_SOC_CS42L56 is not set
diff --git a/kernel/arch/arm/include/asm/arch_gicv3.h b/kernel/arch/arm/include/asm/arch_gicv3.h
index 413abfb..59ec3a6 100644
--- a/kernel/arch/arm/include/asm/arch_gicv3.h
+++ b/kernel/arch/arm/include/asm/arch_gicv3.h
@@ -48,6 +48,7 @@
 	return read_sysreg(a32); 		\
 }						\
 
+CPUIF_MAP(ICC_EOIR1, ICC_EOIR1_EL1)
 CPUIF_MAP(ICC_PMR, ICC_PMR_EL1)
 CPUIF_MAP(ICC_AP0R0, ICC_AP0R0_EL1)
 CPUIF_MAP(ICC_AP0R1, ICC_AP0R1_EL1)
diff --git a/kernel/arch/arm/include/asm/bugs.h b/kernel/arch/arm/include/asm/bugs.h
index 97a312b..fe38555 100644
--- a/kernel/arch/arm/include/asm/bugs.h
+++ b/kernel/arch/arm/include/asm/bugs.h
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- *  arch/arm/include/asm/bugs.h
- *
  *  Copyright (C) 1995-2003 Russell King
  */
 #ifndef __ASM_BUGS_H
@@ -10,10 +8,8 @@
 extern void check_writebuffer_bugs(void);
 
 #ifdef CONFIG_MMU
-extern void check_bugs(void);
 extern void check_other_bugs(void);
 #else
-#define check_bugs() do { } while (0)
 #define check_other_bugs() do { } while (0)
 #endif
 
diff --git a/kernel/arch/arm/include/asm/pgtable-3level.h b/kernel/arch/arm/include/asm/pgtable-3level.h
index 2b85d17..4487aea 100644
--- a/kernel/arch/arm/include/asm/pgtable-3level.h
+++ b/kernel/arch/arm/include/asm/pgtable-3level.h
@@ -130,7 +130,7 @@
 		flush_pmd_entry(pudp);	\
 	} while (0)
 
-static inline pmd_t *pud_page_vaddr(pud_t pud)
+static inline pmd_t *pud_pgtable(pud_t pud)
 {
 	return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK);
 }
diff --git a/kernel/arch/arm/include/asm/thread_info.h b/kernel/arch/arm/include/asm/thread_info.h
index eb7ce27..fcccf35 100644
--- a/kernel/arch/arm/include/asm/thread_info.h
+++ b/kernel/arch/arm/include/asm/thread_info.h
@@ -133,15 +133,16 @@
 #define TIF_NEED_RESCHED	1	/* rescheduling necessary */
 #define TIF_NOTIFY_RESUME	2	/* callback before returning to user */
 #define TIF_UPROBE		3	/* breakpointed or singlestepping */
-#define TIF_SYSCALL_TRACE	4	/* syscall trace active */
-#define TIF_SYSCALL_AUDIT	5	/* syscall auditing active */
-#define TIF_SYSCALL_TRACEPOINT	6	/* syscall tracepoint instrumentation */
-#define TIF_SECCOMP		7	/* seccomp syscall filtering active */
-#define TIF_NOTIFY_SIGNAL	8	/* signal notifications exist */
+#define TIF_NOTIFY_SIGNAL	4	/* signal notifications exist */
 
 #define TIF_USING_IWMMXT	17
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
-#define TIF_RESTORE_SIGMASK	20
+#define TIF_RESTORE_SIGMASK	19
+#define TIF_SYSCALL_TRACE	20	/* syscall trace active */
+#define TIF_SYSCALL_AUDIT	21	/* syscall auditing active */
+#define TIF_SYSCALL_TRACEPOINT	22	/* syscall tracepoint instrumentation */
+#define TIF_SECCOMP		23	/* seccomp syscall filtering active */
+
 
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
diff --git a/kernel/arch/arm/kernel/bugs.c b/kernel/arch/arm/kernel/bugs.c
index 14c8dbb..087bce6 100644
--- a/kernel/arch/arm/kernel/bugs.c
+++ b/kernel/arch/arm/kernel/bugs.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/init.h>
+#include <linux/cpu.h>
 #include <asm/bugs.h>
 #include <asm/proc-fns.h>
 
@@ -11,7 +12,7 @@
 #endif
 }
 
-void __init check_bugs(void)
+void __init arch_cpu_finalize_init(void)
 {
 	check_writebuffer_bugs();
 	check_other_bugs();
diff --git a/kernel/arch/arm/kernel/hw_breakpoint.c b/kernel/arch/arm/kernel/hw_breakpoint.c
index b1423fb..8f1fa7a 100644
--- a/kernel/arch/arm/kernel/hw_breakpoint.c
+++ b/kernel/arch/arm/kernel/hw_breakpoint.c
@@ -626,7 +626,7 @@
 	hw->address &= ~alignment_mask;
 	hw->ctrl.len <<= offset;
 
-	if (is_default_overflow_handler(bp)) {
+	if (uses_default_overflow_handler(bp)) {
 		/*
 		 * Mismatch breakpoints are required for single-stepping
 		 * breakpoints.
@@ -798,7 +798,7 @@
 		 * Otherwise, insert a temporary mismatch breakpoint so that
 		 * we can single-step over the watchpoint trigger.
 		 */
-		if (!is_default_overflow_handler(wp))
+		if (!uses_default_overflow_handler(wp))
 			continue;
 step:
 		enable_single_step(wp, instruction_pointer(regs));
@@ -811,7 +811,7 @@
 		info->trigger = addr;
 		pr_debug("watchpoint fired: address = 0x%x\n", info->trigger);
 		perf_bp_event(wp, regs);
-		if (is_default_overflow_handler(wp))
+		if (uses_default_overflow_handler(wp))
 			enable_single_step(wp, instruction_pointer(regs));
 	}
 
@@ -886,7 +886,7 @@
 			info->trigger = addr;
 			pr_debug("breakpoint fired: address = 0x%x\n", addr);
 			perf_bp_event(bp, regs);
-			if (is_default_overflow_handler(bp))
+			if (uses_default_overflow_handler(bp))
 				enable_single_step(bp, addr);
 			goto unlock;
 		}
diff --git a/kernel/arch/arm/kernel/module-plts.c b/kernel/arch/arm/kernel/module-plts.c
index 1fc309b..8d80972 100644
--- a/kernel/arch/arm/kernel/module-plts.c
+++ b/kernel/arch/arm/kernel/module-plts.c
@@ -256,7 +256,7 @@
 		/* sort by type and symbol index */
 		sort(rels, numrels, sizeof(Elf32_Rel), cmp_rel, NULL);
 
-		if (strncmp(secstrings + dstsec->sh_name, ".init", 5) != 0)
+		if (!module_init_layout_section(secstrings + dstsec->sh_name))
 			core_plts += count_plts(syms, dstsec->sh_addr, rels,
 						numrels, s->sh_info);
 		else
diff --git a/kernel/arch/arm/kernel/traps.c b/kernel/arch/arm/kernel/traps.c
index a531afa..7878c33 100644
--- a/kernel/arch/arm/kernel/traps.c
+++ b/kernel/arch/arm/kernel/traps.c
@@ -348,7 +348,7 @@
 	if (panic_on_oops)
 		panic("Fatal exception");
 	if (signr)
-		do_exit(signr);
+		make_task_dead(signr);
 }
 
 /*
diff --git a/kernel/arch/arm/kernel/unwind.c b/kernel/arch/arm/kernel/unwind.c
index d2bd0df..7e90f17 100644
--- a/kernel/arch/arm/kernel/unwind.c
+++ b/kernel/arch/arm/kernel/unwind.c
@@ -300,6 +300,29 @@
 	return URC_OK;
 }
 
+static unsigned long unwind_decode_uleb128(struct unwind_ctrl_block *ctrl)
+{
+	unsigned long bytes = 0;
+	unsigned long insn;
+	unsigned long result = 0;
+
+	/*
+	 * unwind_get_byte() will advance `ctrl` one instruction at a time, so
+	 * loop until we get an instruction byte where bit 7 is not set.
+	 *
+	 * Note: This decodes a maximum of 4 bytes to output 28 bits data where
+	 * max is 0xfffffff: that will cover a vsp increment of 1073742336, hence
+	 * it is sufficient for unwinding the stack.
+	 */
+	do {
+		insn = unwind_get_byte(ctrl);
+		result |= (insn & 0x7f) << (bytes * 7);
+		bytes++;
+	} while (!!(insn & 0x80) && (bytes != sizeof(result)));
+
+	return result;
+}
+
 /*
  * Execute the current unwind instruction.
  */
@@ -353,7 +376,7 @@
 		if (ret)
 			goto error;
 	} else if (insn == 0xb2) {
-		unsigned long uleb128 = unwind_get_byte(ctrl);
+		unsigned long uleb128 = unwind_decode_uleb128(ctrl);
 
 		ctrl->vrs[SP] += 0x204 + (uleb128 << 2);
 	} else {
diff --git a/kernel/arch/arm/mach-ep93xx/timer-ep93xx.c b/kernel/arch/arm/mach-ep93xx/timer-ep93xx.c
index dd4b164..a9efa7b 100644
--- a/kernel/arch/arm/mach-ep93xx/timer-ep93xx.c
+++ b/kernel/arch/arm/mach-ep93xx/timer-ep93xx.c
@@ -9,6 +9,7 @@
 #include <linux/io.h>
 #include <asm/mach/time.h>
 #include "soc.h"
+#include "platform.h"
 
 /*************************************************************************
  * Timer handling for EP93xx
@@ -60,7 +61,7 @@
 	return ret;
 }
 
-u64 ep93xx_clocksource_read(struct clocksource *c)
+static u64 ep93xx_clocksource_read(struct clocksource *c)
 {
 	u64 ret;
 
diff --git a/kernel/arch/arm/mach-imx/cpu-imx25.c b/kernel/arch/arm/mach-imx/cpu-imx25.c
index b2e1963..2ee2d28 100644
--- a/kernel/arch/arm/mach-imx/cpu-imx25.c
+++ b/kernel/arch/arm/mach-imx/cpu-imx25.c
@@ -23,6 +23,7 @@
 
 	np = of_find_compatible_node(NULL, NULL, "fsl,imx25-iim");
 	iim_base = of_iomap(np, 0);
+	of_node_put(np);
 	BUG_ON(!iim_base);
 	rev = readl(iim_base + MXC_IIMSREV);
 	iounmap(iim_base);
diff --git a/kernel/arch/arm/mach-imx/cpu-imx27.c b/kernel/arch/arm/mach-imx/cpu-imx27.c
index bf70e13..1d28939 100644
--- a/kernel/arch/arm/mach-imx/cpu-imx27.c
+++ b/kernel/arch/arm/mach-imx/cpu-imx27.c
@@ -28,6 +28,7 @@
 
 	np = of_find_compatible_node(NULL, NULL, "fsl,imx27-ccm");
 	ccm_base = of_iomap(np, 0);
+	of_node_put(np);
 	BUG_ON(!ccm_base);
 	/*
 	 * now we have access to the IO registers. As we need
diff --git a/kernel/arch/arm/mach-imx/cpu-imx31.c b/kernel/arch/arm/mach-imx/cpu-imx31.c
index b9c24b8..35c5449 100644
--- a/kernel/arch/arm/mach-imx/cpu-imx31.c
+++ b/kernel/arch/arm/mach-imx/cpu-imx31.c
@@ -39,6 +39,7 @@
 
 	np = of_find_compatible_node(NULL, NULL, "fsl,imx31-iim");
 	iim_base = of_iomap(np, 0);
+	of_node_put(np);
 	BUG_ON(!iim_base);
 
 	/* read SREV register from IIM module */
diff --git a/kernel/arch/arm/mach-imx/cpu-imx35.c b/kernel/arch/arm/mach-imx/cpu-imx35.c
index 80e7d8a..1fe75b3 100644
--- a/kernel/arch/arm/mach-imx/cpu-imx35.c
+++ b/kernel/arch/arm/mach-imx/cpu-imx35.c
@@ -21,6 +21,7 @@
 
 	np = of_find_compatible_node(NULL, NULL, "fsl,imx35-iim");
 	iim_base = of_iomap(np, 0);
+	of_node_put(np);
 	BUG_ON(!iim_base);
 
 	rev = imx_readl(iim_base + MXC_IIMSREV);
diff --git a/kernel/arch/arm/mach-imx/cpu-imx5.c b/kernel/arch/arm/mach-imx/cpu-imx5.c
index ad56263..a67c89b 100644
--- a/kernel/arch/arm/mach-imx/cpu-imx5.c
+++ b/kernel/arch/arm/mach-imx/cpu-imx5.c
@@ -28,6 +28,7 @@
 
 	np = of_find_compatible_node(NULL, NULL, compat);
 	iim_base = of_iomap(np, 0);
+	of_node_put(np);
 	WARN_ON(!iim_base);
 
 	srev = readl(iim_base + IIM_SREV) & 0xff;
diff --git a/kernel/arch/arm/mach-imx/mmdc.c b/kernel/arch/arm/mach-imx/mmdc.c
index af12668..b9efe9d 100644
--- a/kernel/arch/arm/mach-imx/mmdc.c
+++ b/kernel/arch/arm/mach-imx/mmdc.c
@@ -99,6 +99,7 @@
 	cpumask_t cpu;
 	struct hrtimer hrtimer;
 	unsigned int active_events;
+	int id;
 	struct device *dev;
 	struct perf_event *mmdc_events[MMDC_NUM_COUNTERS];
 	struct hlist_node node;
@@ -433,8 +434,6 @@
 static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc,
 		void __iomem *mmdc_base, struct device *dev)
 {
-	int mmdc_num;
-
 	*pmu_mmdc = (struct mmdc_pmu) {
 		.pmu = (struct pmu) {
 			.task_ctx_nr    = perf_invalid_context,
@@ -452,15 +451,16 @@
 		.active_events = 0,
 	};
 
-	mmdc_num = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL);
+	pmu_mmdc->id = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL);
 
-	return mmdc_num;
+	return pmu_mmdc->id;
 }
 
 static int imx_mmdc_remove(struct platform_device *pdev)
 {
 	struct mmdc_pmu *pmu_mmdc = platform_get_drvdata(pdev);
 
+	ida_simple_remove(&mmdc_ida, pmu_mmdc->id);
 	cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node);
 	perf_pmu_unregister(&pmu_mmdc->pmu);
 	iounmap(pmu_mmdc->mmdc_base);
@@ -474,7 +474,6 @@
 {
 	struct mmdc_pmu *pmu_mmdc;
 	char *name;
-	int mmdc_num;
 	int ret;
 	const struct of_device_id *of_id =
 		of_match_device(imx_mmdc_dt_ids, &pdev->dev);
@@ -497,14 +496,14 @@
 		cpuhp_mmdc_state = ret;
 	}
 
-	mmdc_num = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev);
-	pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk;
-	if (mmdc_num == 0)
-		name = "mmdc";
-	else
-		name = devm_kasprintf(&pdev->dev,
-				GFP_KERNEL, "mmdc%d", mmdc_num);
+	ret = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev);
+	if (ret < 0)
+		goto  pmu_free;
 
+	name = devm_kasprintf(&pdev->dev,
+				GFP_KERNEL, "mmdc%d", ret);
+
+	pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk;
 	pmu_mmdc->devtype_data = (struct fsl_mmdc_devtype_data *)of_id->data;
 
 	hrtimer_init(&pmu_mmdc->hrtimer, CLOCK_MONOTONIC,
@@ -525,6 +524,7 @@
 
 pmu_register_err:
 	pr_warn("MMDC Perf PMU failed (%d), disabled\n", ret);
+	ida_simple_remove(&mmdc_ida, pmu_mmdc->id);
 	cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node);
 	hrtimer_cancel(&pmu_mmdc->hrtimer);
 pmu_free:
diff --git a/kernel/arch/arm/mach-mmp/time.c b/kernel/arch/arm/mach-mmp/time.c
index 41b2e8a..708816c 100644
--- a/kernel/arch/arm/mach-mmp/time.c
+++ b/kernel/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)
diff --git a/kernel/arch/arm/mach-omap1/timer.c b/kernel/arch/arm/mach-omap1/timer.c
index 97fc209..05f016d 100644
--- a/kernel/arch/arm/mach-omap1/timer.c
+++ b/kernel/arch/arm/mach-omap1/timer.c
@@ -165,7 +165,7 @@
 	kfree(pdata);
 
 err_free_pdev:
-	platform_device_unregister(pdev);
+	platform_device_put(pdev);
 
 	return ret;
 }
diff --git a/kernel/arch/arm/mach-omap2/board-generic.c b/kernel/arch/arm/mach-omap2/board-generic.c
index 1610c56..10d2f07 100644
--- a/kernel/arch/arm/mach-omap2/board-generic.c
+++ b/kernel/arch/arm/mach-omap2/board-generic.c
@@ -13,6 +13,7 @@
 #include <linux/of_platform.h>
 #include <linux/irqdomain.h>
 #include <linux/clocksource.h>
+#include <linux/clockchips.h>
 
 #include <asm/setup.h>
 #include <asm/mach/arch.h>
diff --git a/kernel/arch/arm/mach-omap2/powerdomain.c b/kernel/arch/arm/mach-omap2/powerdomain.c
index 1cbac76..6a10d23 100644
--- a/kernel/arch/arm/mach-omap2/powerdomain.c
+++ b/kernel/arch/arm/mach-omap2/powerdomain.c
@@ -174,7 +174,7 @@
 		break;
 	case PWRDM_STATE_PREV:
 		prev = pwrdm_read_prev_pwrst(pwrdm);
-		if (pwrdm->state != prev)
+		if (prev >= 0 && pwrdm->state != prev)
 			pwrdm->state_counter[prev]++;
 		if (prev == PWRDM_POWER_RET)
 			_update_logic_membank_counters(pwrdm);
diff --git a/kernel/arch/arm/mach-omap2/timer.c b/kernel/arch/arm/mach-omap2/timer.c
index 620ba69..5677c4a 100644
--- a/kernel/arch/arm/mach-omap2/timer.c
+++ b/kernel/arch/arm/mach-omap2/timer.c
@@ -76,6 +76,7 @@
 	}
 
 	rate = clk_get_rate(sys_clk);
+	clk_put(sys_clk);
 
 	if (soc_is_dra7xx()) {
 		/*
diff --git a/kernel/arch/arm/mach-orion5x/board-dt.c b/kernel/arch/arm/mach-orion5x/board-dt.c
index 3d36f1d..3f651df 100644
--- a/kernel/arch/arm/mach-orion5x/board-dt.c
+++ b/kernel/arch/arm/mach-orion5x/board-dt.c
@@ -63,6 +63,9 @@
 	if (of_machine_is_compatible("maxtor,shared-storage-2"))
 		mss2_init();
 
+	if (of_machine_is_compatible("lacie,d2-network"))
+		d2net_init();
+
 	of_platform_default_populate(NULL, orion5x_auxdata_lookup, NULL);
 }
 
diff --git a/kernel/arch/arm/mach-orion5x/common.h b/kernel/arch/arm/mach-orion5x/common.h
index eb96009..b9cfdb4 100644
--- a/kernel/arch/arm/mach-orion5x/common.h
+++ b/kernel/arch/arm/mach-orion5x/common.h
@@ -75,6 +75,12 @@
 static inline void mss2_init(void) {}
 #endif
 
+#ifdef CONFIG_MACH_D2NET_DT
+void d2net_init(void);
+#else
+static inline void d2net_init(void) {}
+#endif
+
 /*****************************************************************************
  * Helpers to access Orion registers
  ****************************************************************************/
diff --git a/kernel/arch/arm/mach-pxa/sharpsl_pm.c b/kernel/arch/arm/mach-pxa/sharpsl_pm.c
index 83cfbb8..7f6bd7f 100644
--- a/kernel/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/kernel/arch/arm/mach-pxa/sharpsl_pm.c
@@ -220,8 +220,6 @@
 {
 	schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125));
 }
-EXPORT_SYMBOL(sharpsl_battery_kick);
-
 
 static void sharpsl_battery_thread(struct work_struct *private_)
 {
diff --git a/kernel/arch/arm/mach-pxa/spitz.c b/kernel/arch/arm/mach-pxa/spitz.c
index 371008e..264de0b 100644
--- a/kernel/arch/arm/mach-pxa/spitz.c
+++ b/kernel/arch/arm/mach-pxa/spitz.c
@@ -9,7 +9,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>	/* symbol_get ; symbol_put */
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/gpio_keys.h>
@@ -514,17 +513,6 @@
 	.gpio_cs		= SPITZ_GPIO_ADS7846_CS,
 };
 
-static void spitz_bl_kick_battery(void)
-{
-	void (*kick_batt)(void);
-
-	kick_batt = symbol_get(sharpsl_battery_kick);
-	if (kick_batt) {
-		kick_batt();
-		symbol_put(sharpsl_battery_kick);
-	}
-}
-
 static struct gpiod_lookup_table spitz_lcdcon_gpio_table = {
 	.dev_id = "spi2.1",
 	.table = {
@@ -552,7 +540,7 @@
 	.max_intensity		= 0x2f,
 	.default_intensity	= 0x1f,
 	.limit_mask		= 0x0b,
-	.kick_battery		= spitz_bl_kick_battery,
+	.kick_battery		= sharpsl_battery_kick,
 };
 
 static struct pxa2xx_spi_chip spitz_lcdcon_chip = {
diff --git a/kernel/arch/arm/mach-rockchip/Kconfig b/kernel/arch/arm/mach-rockchip/Kconfig
index 922b2e7..6313fec 100644
--- a/kernel/arch/arm/mach-rockchip/Kconfig
+++ b/kernel/arch/arm/mach-rockchip/Kconfig
@@ -28,3 +28,9 @@
 	depends on PM_SLEEP && CPU_RV1106
 	help
 	  This config aims to support HPMCU fast wakeup.
+
+config RV1106_PMU_WAKEUP_TIMEOUT
+	bool "Rockchip RV1106 pmu timeout wakeup support"
+	depends on PM_SLEEP && CPU_RV1106
+	help
+	  This config aims to support pmu timeout wakeup.
diff --git a/kernel/arch/arm/mach-rockchip/Makefile b/kernel/arch/arm/mach-rockchip/Makefile
index f3d33d9..ca8883d 100644
--- a/kernel/arch/arm/mach-rockchip/Makefile
+++ b/kernel/arch/arm/mach-rockchip/Makefile
@@ -6,7 +6,7 @@
 ifdef CONFIG_PM_SLEEP
 obj-$(CONFIG_CPU_RK3288) += pm.o sleep.o
 obj-$(CONFIG_CPU_RV1106) += rv1106_pm.o rv1106_sleep.o rkpm_helpers.o	\
-			    rkpm_uart.o rkpm_gicv2.o
+			    rkpm_uart.o rkpm_gicv2.o rockchip_hptimer.o
 endif
 
 obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/kernel/arch/arm/mach-rockchip/rockchip.c b/kernel/arch/arm/mach-rockchip/rockchip.c
index c89db60..3ff8b70 100644
--- a/kernel/arch/arm/mach-rockchip/rockchip.c
+++ b/kernel/arch/arm/mach-rockchip/rockchip.c
@@ -62,6 +62,7 @@
 	"rockchip,rk3188",
 	"rockchip,rk3228",
 	"rockchip,rk3288",
+	"rockchip,rv1103",
 	"rockchip,rv1106",
 	"rockchip,rv1108",
 	NULL,
diff --git a/kernel/arch/arm/mach-rockchip/rockchip_hptimer.c b/kernel/arch/arm/mach-rockchip/rockchip_hptimer.c
new file mode 100644
index 0000000..7cf7e9e
--- /dev/null
+++ b/kernel/arch/arm/mach-rockchip/rockchip_hptimer.c
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+#include <linux/io.h>
+
+#include "rkpm_helpers.h"
+#include "rockchip_hptimer.h"
+
+/* hp timer regs */
+#define TIMER_HP_REVISION		0x0
+#define TIMER_HP_CTRL			0x4
+#define TIMER_HP_INT_EN			0x8
+#define TIMER_HP_T24_GCD		0xc
+#define TIMER_HP_T32_GCD		0x10
+#define TIMER_HP_LOAD_COUNT0		0x14
+#define TIMER_HP_LOAD_COUNT1		0x18
+#define TIMER_HP_T24_DELAT_COUNT0	0x1c
+#define TIMER_HP_T24_DELAT_COUNT1	0x20
+#define TIMER_HP_CURR_32K_VALUE0	0x24
+#define TIMER_HP_CURR_32K_VALUE1	0x28
+#define TIMER_HP_CURR_TIMER_VALUE0	0x2c
+#define TIMER_HP_CURR_TIMER_VALUE1	0x30
+#define TIMER_HP_T24_32BEGIN0		0x34
+#define TIMER_HP_T24_32BEGIN1		0x38
+#define TIMER_HP_T32_24END0		0x3c
+#define TIMER_HP_T32_24END1		0x40
+#define TIMER_HP_BEGIN_END_VALID	0x44
+#define TIMER_HP_SYNC_REQ		0x48
+#define TIMER_HP_INTR_STATUS		0x4c
+
+/* hptimer ctlr */
+enum rk_hptimer_ctlr_reg {
+	RK_HPTIMER_CTRL_EN = 0,
+	RK_HPTIMER_CTRL_MODE = 1,
+	RK_HPTIMER_CTRL_CNT_MODE = 3,
+};
+
+/* hptimer int */
+enum rk_hptimer_int_id_t {
+	RK_HPTIMER_INT_REACH = 0,
+	RK_HPTIMER_INT_ADJ_DONE = 1,
+	RK_HPTIMER_INT_SYNC = 2,
+};
+
+#define T24M_GCD		0xb71b
+#define T32K_GCD		0x40
+
+#define HPTIMER_WAIT_MAX_US	1000000
+
+static void rk_hptimer_clear_int_st(void __iomem *base, enum rk_hptimer_int_id_t id)
+{
+	writel_relaxed(BIT(id), base + TIMER_HP_INTR_STATUS);
+}
+
+static int rk_hptimer_wait_int_st(void __iomem *base,
+				  enum rk_hptimer_int_id_t id,
+				  u64 wait_us)
+{
+	while (!(readl_relaxed(base + TIMER_HP_INTR_STATUS) & BIT(id)) &&
+	       --wait_us > 0)
+		rkpm_raw_udelay(1);
+	dsb();
+
+	if (wait_us == 0) {
+		rkpm_printstr("can't wait hptimer int:");
+		rkpm_printdec(id);
+		rkpm_printch('-');
+		rkpm_printhex(readl_relaxed(base + TIMER_HP_INTR_STATUS));
+		rkpm_printch('\n');
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
+static int rk_hptimer_wait_begin_end_valid(void __iomem *base, u64 wait_us)
+{
+	while ((readl_relaxed(base + TIMER_HP_BEGIN_END_VALID) & 0x3) != 0x3 &&
+	       --wait_us > 0)
+		rkpm_raw_udelay(1);
+	dsb();
+
+	if (wait_us == 0) {
+		rkpm_printstr("can't wait hptimer begin_end valid:");
+		rkpm_printhex(readl_relaxed(base + TIMER_HP_BEGIN_END_VALID));
+		rkpm_printch('\n');
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
+static u64 rk_hptimer_get_soft_adjust_delt_cnt(void __iomem *base)
+{
+	u64 begin, end, delt;
+
+	if (rk_hptimer_wait_begin_end_valid(base, HPTIMER_WAIT_MAX_US))
+		return 0;
+
+	begin = (u64)readl_relaxed(base + TIMER_HP_T24_32BEGIN0) |
+		(u64)readl_relaxed(base + TIMER_HP_T24_32BEGIN1) << 32;
+	end = (u64)readl_relaxed(base + TIMER_HP_T32_24END0) |
+	      (u64)readl_relaxed(base + TIMER_HP_T32_24END1) << 32;
+	delt = (end - begin) * T24M_GCD / T32K_GCD;
+
+	writel_relaxed(0x3, base + TIMER_HP_BEGIN_END_VALID);
+
+	return delt;
+}
+
+static void rk_hptimer_soft_adjust_req(void __iomem *base, u64 delt)
+{
+	if (delt == 0)
+		return;
+
+	writel_relaxed(delt & 0xffffffff, base + TIMER_HP_T24_DELAT_COUNT0);
+	writel_relaxed((delt >> 32) & 0xffffffff, base + TIMER_HP_T24_DELAT_COUNT1);
+	dsb();
+
+	writel_relaxed(0x1, base + TIMER_HP_SYNC_REQ);
+	dsb();
+}
+
+int rk_hptimer_is_enabled(void __iomem *base)
+{
+	return !!(readl_relaxed(base + TIMER_HP_CTRL) & BIT(RK_HPTIMER_CTRL_EN));
+}
+
+int rk_hptimer_get_mode(void __iomem *base)
+{
+	return (readl_relaxed(base + TIMER_HP_CTRL) >> RK_HPTIMER_CTRL_MODE) & 0x3;
+}
+
+u64 rk_hptimer_get_count(void __iomem *base)
+{
+	u64 cnt;
+
+	cnt = (u64)readl_relaxed(base + TIMER_HP_CURR_TIMER_VALUE0) |
+	      (u64)readl_relaxed(base + TIMER_HP_CURR_TIMER_VALUE1) << 32;
+
+	return cnt;
+}
+
+int rk_hptimer_wait_mode(void __iomem *base, enum rk_hptimer_mode_t mode)
+{
+	if (mode == RK_HPTIMER_NORM_MODE)
+		return 0;
+
+	if (mode == RK_HPTIMER_HARD_ADJUST_MODE) {
+		/* wait adjust done if hard_adjust_mode */
+		if (rk_hptimer_wait_int_st(base, RK_HPTIMER_INT_ADJ_DONE,
+					   HPTIMER_WAIT_MAX_US))
+			return -1;
+
+		rk_hptimer_clear_int_st(base, RK_HPTIMER_INT_ADJ_DONE);
+	} else if (mode == RK_HPTIMER_SOFT_ADJUST_MODE) {
+		/* wait 32k sync done */
+		if (rk_hptimer_wait_int_st(base, RK_HPTIMER_INT_SYNC,
+					   HPTIMER_WAIT_MAX_US))
+			return -1;
+
+		rk_hptimer_clear_int_st(base, RK_HPTIMER_INT_SYNC);
+	}
+
+	return 0;
+}
+
+void rk_hptimer_do_soft_adjust(void __iomem *base)
+{
+	u64 delt = rk_hptimer_get_soft_adjust_delt_cnt(base);
+
+	rk_hptimer_soft_adjust_req(base, delt);
+
+	rk_hptimer_wait_mode(base, RK_HPTIMER_SOFT_ADJUST_MODE);
+}
+
+void rk_hptimer_do_soft_adjust_no_wait(void __iomem *base)
+{
+	u64 delt = rk_hptimer_get_soft_adjust_delt_cnt(base);
+
+	rk_hptimer_soft_adjust_req(base, delt);
+}
+
+void rk_hptimer_mode_init(void __iomem *base, enum rk_hptimer_mode_t mode)
+{
+	u64 old_cnt = rk_hptimer_get_count(base);
+	u32 val;
+
+	writel_relaxed(0x0, base + TIMER_HP_CTRL);
+	writel_relaxed(0x0, base + TIMER_HP_INT_EN);
+	writel_relaxed(0x7, base + TIMER_HP_INTR_STATUS);
+	writel_relaxed(0x3, base + TIMER_HP_BEGIN_END_VALID);
+	writel_relaxed(0xffffffff, base + TIMER_HP_LOAD_COUNT0);
+	writel_relaxed(0xffffffff, base + TIMER_HP_LOAD_COUNT1);
+
+	/* config T24/T32 GCD if hard_adjust_mode */
+	if (mode == RK_HPTIMER_HARD_ADJUST_MODE) {
+		writel_relaxed(T24M_GCD, base + TIMER_HP_T24_GCD);
+		writel_relaxed(T32K_GCD, base + TIMER_HP_T32_GCD);
+	}
+	dsb();
+
+	if (mode != RK_HPTIMER_NORM_MODE) {
+		writel_relaxed(0x7, base + TIMER_HP_INT_EN);
+		writel_relaxed(mode << RK_HPTIMER_CTRL_MODE, base + TIMER_HP_CTRL);
+		dsb();
+	}
+
+	val = readl_relaxed(base + TIMER_HP_CTRL);
+	writel_relaxed(val | BIT(RK_HPTIMER_CTRL_EN), base + TIMER_HP_CTRL);
+	dsb();
+
+	/* compensate old_cnt to hptimer if soft_adjust_mode */
+	if (mode == RK_HPTIMER_SOFT_ADJUST_MODE)
+		rk_hptimer_soft_adjust_req(base, old_cnt);
+
+	if (rk_hptimer_wait_mode(base, mode))
+		pr_err("%s: can't wait hptimer mode:%d\n", __func__, mode);
+}
diff --git a/kernel/arch/arm/mach-rockchip/rockchip_hptimer.h b/kernel/arch/arm/mach-rockchip/rockchip_hptimer.h
new file mode 100644
index 0000000..4cf6399
--- /dev/null
+++ b/kernel/arch/arm/mach-rockchip/rockchip_hptimer.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __ROCKCHIP_HPTIEMR_H__
+#define __ROCKCHIP_HPTIEMR_H__
+
+enum rk_hptimer_mode_t {
+	RK_HPTIMER_NORM_MODE = 0,
+	RK_HPTIMER_HARD_ADJUST_MODE = 1,
+	RK_HPTIMER_SOFT_ADJUST_MODE = 2,
+};
+
+int rk_hptimer_is_enabled(void __iomem *base);
+int rk_hptimer_get_mode(void __iomem *base);
+u64 rk_hptimer_get_count(void __iomem *base);
+int rk_hptimer_wait_mode(void __iomem *base, enum rk_hptimer_mode_t mode);
+void rk_hptimer_do_soft_adjust(void __iomem *base);
+void rk_hptimer_do_soft_adjust_no_wait(void __iomem *base);
+void rk_hptimer_mode_init(void __iomem *base, enum rk_hptimer_mode_t mode);
+#endif
diff --git a/kernel/arch/arm/mach-rockchip/rv1106_pm.c b/kernel/arch/arm/mach-rockchip/rv1106_pm.c
index 7767b44..ff26f6b 100644
--- a/kernel/arch/arm/mach-rockchip/rv1106_pm.c
+++ b/kernel/arch/arm/mach-rockchip/rv1106_pm.c
@@ -15,12 +15,14 @@
 #include <asm/fiq_glue.h>
 #include <asm/tlbflush.h>
 #include <asm/suspend.h>
+#include <dt-bindings/suspend/rockchip-rv1106.h>
 #include <linux/irqchip/arm-gic.h>
+#include <linux/rockchip/rockchip_pm_config.h>
 
 #include "rkpm_gicv2.h"
 #include "rkpm_helpers.h"
 #include "rkpm_uart.h"
-
+#include "rockchip_hptimer.h"
 #include "rv1106_pm.h"
 
 #define RV1106_PM_REG_REGION_MEM_SIZE		SZ_4K
@@ -57,8 +59,11 @@
 
 static struct rv1106_sleep_ddr_data ddr_data;
 
+static const struct rk_sleep_config *slp_cfg;
+
 static void __iomem *pmucru_base;
 static void __iomem *cru_base;
+static void __iomem *pvtpllcru_base;
 static void __iomem *pericru_base;
 static void __iomem *vicru_base;
 static void __iomem *npucru_base;
@@ -87,6 +92,7 @@
 static void __iomem *pmu_base;
 static void __iomem *gicd_base;
 static void __iomem *gicc_base;
+static void __iomem *hptimer_base;
 static void __iomem *firewall_ddr_base;
 static void __iomem *firewall_syssram_base;
 static void __iomem *pmu_base;
@@ -104,6 +110,10 @@
 	/* core_cru */
 	{ REG_REGION(0x300, 0x310, 4, &corecru_base, WMSK_VAL)},
 	{ REG_REGION(0x800, 0x804, 4, &corecru_base, WMSK_VAL)},
+
+	/* pvtpll_cru */
+	{ REG_REGION(0x00, 0x24, 4, &pvtpllcru_base, WMSK_VAL)},
+	{ REG_REGION(0x30, 0x54, 4, &pvtpllcru_base, WMSK_VAL)},
 
 	/* core_sgrf */
 	{ REG_REGION(0x004, 0x014, 4, &coresgrf_base, 0)},
@@ -276,6 +286,8 @@
 	{ REG_REGION(0x30, 0x30, 4, &stimer_base, 0)},
 };
 
+static int is_rv1103, is_rv1106;
+
 #define PLL_LOCKED_TIMEOUT		600000U
 
 static void pm_pll_wait_lock(u32 pll_id)
@@ -382,7 +394,7 @@
 	if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_USBDEV_EN))
 		rkpm_printstr("USBDEV detect wakeup\n");
 
-	if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_TIMEROUT_EN))
+	if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_TIMEOUT_EN))
 		rkpm_printstr("TIMEOUT interrupt wakeup\n");
 
 	rkpm_printch('\n');
@@ -646,6 +658,9 @@
 {
 	writel_relaxed(WITH_16BITS_WMSK(ddr_data.pmucru_sel_con7),
 		       pmucru_base + RV1106_PMUCRU_CLKSEL_CON(7));
+
+	if (rk_hptimer_get_mode(hptimer_base) == RK_HPTIMER_SOFT_ADJUST_MODE)
+		rk_hptimer_do_soft_adjust_no_wait(hptimer_base);
 }
 
 static void ddr_sleep_config(void)
@@ -705,8 +720,8 @@
 		/* BIT(RV1106_PMU_WAKEUP_CPU_INT_EN) | */
 		BIT(RV1106_PMU_WAKEUP_GPIO_INT_EN) |
 		0;
-	if (IS_ENABLED(CONFIG_RV1106_HPMCU_FAST_WAKEUP))
-		pmu_wkup_con |= BIT(RV1106_PMU_WAKEUP_TIMEROUT_EN);
+	if (IS_ENABLED(CONFIG_RV1106_PMU_WAKEUP_TIMEOUT))
+		pmu_wkup_con |= BIT(RV1106_PMU_WAKEUP_TIMEOUT_EN);
 
 	pmu_pwr_con =
 		BIT(RV1106_PMU_PWRMODE_EN) |
@@ -772,30 +787,21 @@
 		BIT(RV1106_PMU_GPLL_PD_ENA) |
 		0;
 
-	/* pmic_sleep */
-	/* gpio0_a3 activelow, gpio0_a4 active high */
-	writel_relaxed(BITS_WITH_WMASK(0x4, 0x7, 0), pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
-	/* select sleep func */
-	writel_relaxed(BITS_WITH_WMASK(0x1, 0x1, 0), pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
-	/* gpio0_a3 iomux */
-	writel_relaxed(BITS_WITH_WMASK(0x1, 0xf, 12), ioc_base[0] + 0);
-
 	/* pmu_debug */
 	writel_relaxed(0xffffff01, pmu_base + RV1106_PMU_INFO_TX_CON);
 	writel_relaxed(BITS_WITH_WMASK(0x1, 0xf, 4), ioc_base[1] + 0);
 
 	/* pmu count */
-	writel_relaxed(clk_freq_khz * 32, pmu_base + RV1106_PMU_OSC_STABLE_CNT);
-	writel_relaxed(clk_freq_khz * 32, pmu_base + RV1106_PMU_PMIC_STABLE_CNT);
-	writel_relaxed(clk_freq_khz * 3000, pmu_base + RV1106_PMU_WAKEUP_TIMEOUT_CNT);
+	writel_relaxed(clk_freq_khz * 10, pmu_base + RV1106_PMU_OSC_STABLE_CNT);
+	writel_relaxed(clk_freq_khz * 5, pmu_base + RV1106_PMU_PMIC_STABLE_CNT);
 
 	/* Pmu's clk has switched to 24M back When pmu FSM counts
 	 * the follow counters, so we should use 24M to calculate
 	 * these counters.
 	 */
-	writel_relaxed(24000 * 2, pmu_base + RV1106_PMU_WAKEUP_RSTCLR_CNT);
-	writel_relaxed(24000 * 5, pmu_base + RV1106_PMU_PLL_LOCK_CNT);
-	writel_relaxed(24000 * 5, pmu_base + RV1106_PMU_PWM_SWITCH_CNT);
+	writel_relaxed(12000, pmu_base + RV1106_PMU_WAKEUP_RSTCLR_CNT);
+	writel_relaxed(12000, pmu_base + RV1106_PMU_PLL_LOCK_CNT);
+	writel_relaxed(24000 * 2, pmu_base + RV1106_PMU_PWM_SWITCH_CNT);
 
 	/* pmu reset hold */
 	writel_relaxed(0xffffffff, pmugrf_base + RV1106_PMUGRF_SOC_CON(4));
@@ -918,51 +924,71 @@
 			       gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H);
 }
 
+static void gpio0_set_lvl(u32 pin_id, int lvl)
+{
+	u32 sft = (pin_id % 16);
+
+	if (pin_id < 16)
+		writel_relaxed(BITS_WITH_WMASK(lvl, 0x1, sft),
+			       gpio_base[0] + RV1106_GPIO_SWPORT_DR_L);
+	else
+		writel_relaxed(BITS_WITH_WMASK(lvl, 0x1, sft),
+			       gpio_base[0] + RV1106_GPIO_SWPORT_DR_H);
+}
+
 static void gpio_config(void)
 {
+	u32 iomux, dir, lvl, pull, id;
+	u32 cfg, i;
+
+	if (slp_cfg == NULL)
+		return;
+
 	ddr_data.gpio0a_iomux_l = readl_relaxed(ioc_base[0] + 0);
 	ddr_data.gpio0a_iomux_h = readl_relaxed(ioc_base[0] + 0x4);
 	ddr_data.gpio0a0_pull = readl_relaxed(ioc_base[0] + 0x38);
 	ddr_data.gpio0_ddr_l = readl_relaxed(gpio_base[0] + RV1106_GPIO_SWPORT_DDR_L);
 	ddr_data.gpio0_ddr_h = readl_relaxed(gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H);
 
-	/* gpio0_a0, input, pulldown */
-	gpio0_set_iomux(0, 0);
-	gpio0_set_pull(0, RV1106_GPIO_PULL_DOWN);
-	gpio0_set_direct(0, 0);
+	for (i = 0; i < slp_cfg->sleep_io_config_cnt; i++) {
+		cfg = slp_cfg->sleep_io_config[i];
+		iomux = RKPM_IO_CFG_GET_IOMUX(cfg);
+		dir = RKPM_IO_CFG_GET_GPIO_DIR(cfg);
+		lvl = RKPM_IO_CFG_GET_GPIO_LVL(cfg);
+		pull = RKPM_IO_CFG_GET_PULL(cfg);
+		id = RKPM_IO_CFG_GET_ID(cfg);
 
-#ifdef RV1106_GPIO0_A1_LOWPOWER
-	/* gpio0_a1, input, pulldown */
-	gpio0_set_iomux(1, 0);
-	gpio0_set_pull(1, RV1106_GPIO_PULL_DOWN);
-	gpio0_set_direct(1, 0);
-#endif
-	/* gpio0_a2, input, pulldown */
-	gpio0_set_iomux(2, 0);
-	gpio0_set_pull(2, RV1106_GPIO_PULL_DOWN);
-	gpio0_set_direct(2, 0);
+		if (is_rv1106 && id == 3) {
+			/* gpio0_a3, pullnone */
+			gpio0_set_iomux(3, 1);
+			gpio0_set_pull(3, RV1106_GPIO_PULL_NONE);
+			continue;
+		}
 
-	/* gpio0_a3, pullnone */
-	gpio0_set_pull(3, RV1106_GPIO_PULL_NONE);
+		if (is_rv1103 && id == 4) {
+			/* gpio0_a4, pullnone */
+			gpio0_set_iomux(4, 1);
+			gpio0_set_pull(4, RV1106_GPIO_PULL_NONE);
+			continue;
+		}
 
-	/* gpio0_a4, input, pulldown */
-	gpio0_set_iomux(4, 0);
-	gpio0_set_pull(4, RV1106_GPIO_PULL_DOWN);
-	gpio0_set_direct(4, 0);
+		if (iomux == RKPM_IO_CFG_IOMUX_GPIO_VAL) {
+			if (dir == RKPM_IO_CFG_GPIO_DIR_INPUT_VAL)
+				gpio0_set_lvl(id, lvl);
 
-	/* gpio0_a5, input, pullnone */
-	gpio0_set_iomux(5, 0);
-	gpio0_set_pull(5, RV1106_GPIO_PULL_NONE);
-	gpio0_set_direct(5, 0);
+			gpio0_set_direct(id, dir);
+		}
 
-	/* gpio0_a6, input, pullnone */
-	gpio0_set_iomux(6, 0);
-	gpio0_set_pull(6, RV1106_GPIO_PULL_NONE);
-	gpio0_set_direct(6, 0);
+		gpio0_set_iomux(id, iomux);
+		gpio0_set_pull(id, pull);
+	}
 }
 
 static void gpio_restore(void)
 {
+	if (slp_cfg == NULL)
+		return;
+
 	writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_l), ioc_base[0] + 0);
 	writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_h), ioc_base[0] + 0x4);
 
@@ -1056,6 +1082,8 @@
 {
 	rkpm_printstr("rv1106 enter sleep\n");
 
+	slp_cfg = rockchip_get_cur_sleep_config();
+
 	local_fiq_disable();
 
 	rv1106_dbg_irq_prepare();
@@ -1101,7 +1129,7 @@
 	rkpm_printch('-');
 
 	/* Check whether it's time_out wakeup */
-	if (IS_ENABLED(CONFIG_RV1106_HPMCU_FAST_WAKEUP) && ddr_data.pmu_wkup_int_st == 0) {
+	if (IS_ENABLED(CONFIG_RV1106_HPMCU_FAST_WAKEUP)) {
 		if (hpmcu_fast_wkup()) {
 			rkpm_gicv2_dist_restore(gicd_base, &gicd_ctx_save);
 			goto RE_ENTER_SLEEP;
@@ -1109,6 +1137,12 @@
 			rkpm_gicv2_dist_restore(gicd_base, &gicd_ctx_save);
 			rkpm_gicv2_cpu_restore(gicd_base, gicc_base, &gicc_ctx_save);
 		}
+	}
+
+	if (rk_hptimer_get_mode(hptimer_base) == RK_HPTIMER_SOFT_ADJUST_MODE) {
+		if (rk_hptimer_wait_mode(hptimer_base,
+					 RK_HPTIMER_SOFT_ADJUST_MODE))
+			rkpm_printstr("WARN: can't wait hptimer soft adjust mode!\n");
 	}
 
 	fiq_glue_resume();
@@ -1125,6 +1159,11 @@
 {
 	void __iomem *dev_reg_base;
 
+	if (of_machine_is_compatible("rockchip,rv1103"))
+		is_rv1103 = 1;
+	else if (of_machine_is_compatible("rockchip,rv1106"))
+		is_rv1106 = 1;
+
 	dev_reg_base = ioremap(RV1106_DEV_REG_BASE, RV1106_DEV_REG_SIZE);
 	if (dev_reg_base)
 		pr_info("%s map dev_reg 0x%x -> 0x%x\n",
@@ -1134,6 +1173,8 @@
 
 	gicd_base = dev_reg_base + RV1106_GIC_OFFSET + 0x1000;
 	gicc_base = dev_reg_base + RV1106_GIC_OFFSET + 0x2000;
+
+	hptimer_base = dev_reg_base + RV1106_HPTIMER_OFFSET;
 
 	firewall_ddr_base = dev_reg_base + RV1106_FW_DDR_OFFSET;
 	firewall_syssram_base = dev_reg_base + RV1106_FW_SRAM_OFFSET;
@@ -1166,6 +1207,7 @@
 
 	pmucru_base = dev_reg_base + RV1106_PMUCRU_OFFSET;
 	cru_base = dev_reg_base + RV1106_CRU_OFFSET;
+	pvtpllcru_base = dev_reg_base + RV1106_PVTPLLCRU_OFFSET;
 	pericru_base = dev_reg_base + RV1106_PERICRU_OFFSET;
 	vicru_base = dev_reg_base + RV1106_VICRU_OFFSET;
 	npucru_base = dev_reg_base + RV1106_NPUCRU_OFFSET;
@@ -1203,6 +1245,10 @@
 	/* biu auto con */
 	writel_relaxed(0x07ff07ff, pmu_base + RV1106_PMU_BIU_AUTO_CON);
 
+	/* gpio0_a3 activelow, gpio0_a4 active high, select sleep func */
+	writel_relaxed(BITS_WITH_WMASK(0x5, 0x7, 0),
+		       pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
+
 	rkpm_region_mem_init(RV1106_PM_REG_REGION_MEM_SIZE);
 	rkpm_reg_rgns_init();
 
diff --git a/kernel/arch/arm/mach-rockchip/rv1106_pm.h b/kernel/arch/arm/mach-rockchip/rv1106_pm.h
index da857a5..a3db55d 100644
--- a/kernel/arch/arm/mach-rockchip/rv1106_pm.h
+++ b/kernel/arch/arm/mach-rockchip/rv1106_pm.h
@@ -35,6 +35,7 @@
 
 #define RV1106_PMUCRU_OFFSET		0x3a0000
 #define RV1106_CRU_OFFSET		0x3b0000
+#define RV1106_PVTPLLCRU_OFFSET		0x3b1000
 #define RV1106_PERICRU_OFFSET		0x3b2000
 #define RV1106_VICRU_OFFSET		0x3b4000
 #define RV1106_NPUCRU_OFFSET		0x3b6000
@@ -237,7 +238,7 @@
 
 	RV1106_PMU_WAKEUP_USBDEV_EN,
 	RV1106_PMU_WAKEUP_TIMER_EN,
-	RV1106_PMU_WAKEUP_TIMEROUT_EN,
+	RV1106_PMU_WAKEUP_TIMEOUT_EN,
 	RV1106_PMU_WAKEUP_SFT_WAKEUP_CFG,
 };
 
diff --git a/kernel/arch/arm/mach-s3c/s3c64xx.c b/kernel/arch/arm/mach-s3c/s3c64xx.c
index 4dfb648..17f0065 100644
--- a/kernel/arch/arm/mach-s3c/s3c64xx.c
+++ b/kernel/arch/arm/mach-s3c/s3c64xx.c
@@ -173,7 +173,8 @@
 	.tclk_mask	= (1 << 7) | (1 << 6) | (1 << 5),
 };
 
-void __init s3c64xx_set_timer_source(unsigned int event, unsigned int source)
+void __init s3c64xx_set_timer_source(enum s3c64xx_timer_mode event,
+				     enum s3c64xx_timer_mode source)
 {
 	s3c64xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
 	s3c64xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
diff --git a/kernel/arch/arm/mach-sa1100/jornada720_ssp.c b/kernel/arch/arm/mach-sa1100/jornada720_ssp.c
index 1dbe989..9627c4c 100644
--- a/kernel/arch/arm/mach-sa1100/jornada720_ssp.c
+++ b/kernel/arch/arm/mach-sa1100/jornada720_ssp.c
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/**
+/*
  *  arch/arm/mac-sa1100/jornada720_ssp.c
  *
  *  Copyright (C) 2006/2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
@@ -26,6 +26,7 @@
 
 /**
  * jornada_ssp_reverse - reverses input byte
+ * @byte: input byte to reverse
  *
  * we need to reverse all data we receive from the mcu due to its physical location
  * returns : 01110111 -> 11101110
@@ -46,6 +47,7 @@
 
 /**
  * jornada_ssp_byte - waits for ready ssp bus and sends byte
+ * @byte: input byte to transmit
  *
  * waits for fifo buffer to clear and then transmits, if it doesn't then we will
  * timeout after <timeout> rounds. Needs mcu running before its called.
@@ -77,6 +79,7 @@
 
 /**
  * jornada_ssp_inout - decide if input is command or trading byte
+ * @byte: input byte to send (may be %TXDUMMY)
  *
  * returns : (jornada_ssp_byte(byte)) on success
  *         : %-ETIMEDOUT on timeout failure
diff --git a/kernel/arch/arm/mach-zynq/slcr.c b/kernel/arch/arm/mach-zynq/slcr.c
index 3770761..9765b3f 100644
--- a/kernel/arch/arm/mach-zynq/slcr.c
+++ b/kernel/arch/arm/mach-zynq/slcr.c
@@ -213,6 +213,7 @@
 	zynq_slcr_regmap = syscon_regmap_lookup_by_compatible("xlnx,zynq-slcr");
 	if (IS_ERR(zynq_slcr_regmap)) {
 		pr_err("%s: failed to find zynq-slcr\n", __func__);
+		of_node_put(np);
 		return -ENODEV;
 	}
 
diff --git a/kernel/arch/arm/mm/fault.c b/kernel/arch/arm/mm/fault.c
index efa4020..af51778 100644
--- a/kernel/arch/arm/mm/fault.c
+++ b/kernel/arch/arm/mm/fault.c
@@ -125,7 +125,7 @@
 	show_pte(KERN_ALERT, mm, addr);
 	die("Oops", regs, fsr);
 	bust_spinlocks(0);
-	do_exit(SIGKILL);
+	make_task_dead(SIGKILL);
 }
 
 /*
diff --git a/kernel/arch/arm/mm/nommu.c b/kernel/arch/arm/mm/nommu.c
index 959f057..c4d5b3b 100644
--- a/kernel/arch/arm/mm/nommu.c
+++ b/kernel/arch/arm/mm/nommu.c
@@ -161,7 +161,7 @@
 	mpu_setup();
 
 	/* allocate the zero page. */
-	zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
+	zero_page = (void *)memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 	if (!zero_page)
 		panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
 		      __func__, PAGE_SIZE, PAGE_SIZE);
diff --git a/kernel/arch/arm/nwfpe/Makefile b/kernel/arch/arm/nwfpe/Makefile
index 303400f..2aec85a 100644
--- a/kernel/arch/arm/nwfpe/Makefile
+++ b/kernel/arch/arm/nwfpe/Makefile
@@ -11,3 +11,9 @@
 				   entry.o
 
 nwfpe-$(CONFIG_FPE_NWFPE_XP)	+= extended_cpdo.o
+
+# Try really hard to avoid generating calls to __aeabi_uldivmod() from
+# float64_rem() due to loop elision.
+ifdef CONFIG_CC_IS_CLANG
+CFLAGS_softfloat.o	+= -mllvm -replexitval=never
+endif
diff --git a/kernel/arch/arm/probes/kprobes/checkers-common.c b/kernel/arch/arm/probes/kprobes/checkers-common.c
index 4d72099..eba7ac4 100644
--- a/kernel/arch/arm/probes/kprobes/checkers-common.c
+++ b/kernel/arch/arm/probes/kprobes/checkers-common.c
@@ -40,7 +40,7 @@
  * Different from other insn uses imm8, the real addressing offset of
  * STRD in T32 encoding should be imm8 * 4. See ARMARM description.
  */
-enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn,
+static enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn,
 		struct arch_probes_insn *asi,
 		const struct decode_header *h)
 {
diff --git a/kernel/arch/arm/probes/kprobes/core.c b/kernel/arch/arm/probes/kprobes/core.c
index e513d8a..c0ed172 100644
--- a/kernel/arch/arm/probes/kprobes/core.c
+++ b/kernel/arch/arm/probes/kprobes/core.c
@@ -231,7 +231,7 @@
  * kprobe, and that level is reserved for user kprobe handlers, so we can't
  * risk encountering a new kprobe in an interrupt handler.
  */
-void __kprobes kprobe_handler(struct pt_regs *regs)
+static void __kprobes kprobe_handler(struct pt_regs *regs)
 {
 	struct kprobe *p, *cur;
 	struct kprobe_ctlblk *kcb;
diff --git a/kernel/arch/arm/probes/kprobes/opt-arm.c b/kernel/arch/arm/probes/kprobes/opt-arm.c
index c781801..e20304f 100644
--- a/kernel/arch/arm/probes/kprobes/opt-arm.c
+++ b/kernel/arch/arm/probes/kprobes/opt-arm.c
@@ -145,8 +145,6 @@
 	}
 }
 
-extern void kprobe_handler(struct pt_regs *regs);
-
 static void
 optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
 {
diff --git a/kernel/arch/arm/probes/kprobes/test-core.c b/kernel/arch/arm/probes/kprobes/test-core.c
index c562832..171c707 100644
--- a/kernel/arch/arm/probes/kprobes/test-core.c
+++ b/kernel/arch/arm/probes/kprobes/test-core.c
@@ -720,7 +720,7 @@
 	[REG_TYPE_NOSPPCX]	= COVERAGE_ANY_REG | COVERAGE_SP,
 };
 
-unsigned coverage_start_registers(const struct decode_header *h)
+static unsigned coverage_start_registers(const struct decode_header *h)
 {
 	unsigned regs = 0;
 	int i;
diff --git a/kernel/arch/arm/probes/kprobes/test-core.h b/kernel/arch/arm/probes/kprobes/test-core.h
index f1d5583..7054d9f 100644
--- a/kernel/arch/arm/probes/kprobes/test-core.h
+++ b/kernel/arch/arm/probes/kprobes/test-core.h
@@ -454,3 +454,7 @@
 #else
 void kprobe_arm_test_cases(void);
 #endif
+
+void __kprobes_test_case_start(void);
+void __kprobes_test_case_end_16(void);
+void __kprobes_test_case_end_32(void);
diff --git a/kernel/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/kernel/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
index 46e558a..f0e8af1 100644
--- a/kernel/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
+++ b/kernel/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
@@ -129,7 +129,7 @@
 	status = "okay";
 	clock-frequency = <100000>;
 	i2c-sda-falling-time-ns = <890>;  /* hcnt */
-	i2c-sdl-falling-time-ns = <890>;  /* lcnt */
+	i2c-scl-falling-time-ns = <890>;  /* lcnt */
 
 	adc@14 {
 		compatible = "lltc,ltc2497";
diff --git a/kernel/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts b/kernel/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts
index f9b4a39..92ac3c8 100644
--- a/kernel/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts
+++ b/kernel/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts
@@ -162,7 +162,7 @@
 	status = "okay";
 	clock-frequency = <100000>;
 	i2c-sda-falling-time-ns = <890>;  /* hcnt */
-	i2c-sdl-falling-time-ns = <890>;  /* lcnt */
+	i2c-scl-falling-time-ns = <890>;  /* lcnt */
 
 	adc@14 {
 		compatible = "lltc,ltc2497";
diff --git a/kernel/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/kernel/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index fae48ef..c892b25 100644
--- a/kernel/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/kernel/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -151,7 +151,7 @@
 		scpi_clocks: clocks {
 			compatible = "arm,scpi-clocks";
 
-			scpi_dvfs: clock-controller {
+			scpi_dvfs: clocks-0 {
 				compatible = "arm,scpi-dvfs-clocks";
 				#clock-cells = <1>;
 				clock-indices = <0>;
@@ -160,7 +160,7 @@
 		};
 
 		scpi_sensors: sensors {
-			compatible = "amlogic,meson-gxbb-scpi-sensors";
+			compatible = "amlogic,meson-gxbb-scpi-sensors", "arm,scpi-sensors";
 			#thermal-sensor-cells = <1>;
 		};
 	};
@@ -1754,7 +1754,7 @@
 			sd_emmc_b: sd@5000 {
 				compatible = "amlogic,meson-axg-mmc";
 				reg = <0x0 0x5000 0x0 0x800>;
-				interrupts = <GIC_SPI 217 IRQ_TYPE_EDGE_RISING>;
+				interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>;
 				status = "disabled";
 				clocks = <&clkc CLKID_SD_EMMC_B>,
 					<&clkc CLKID_SD_EMMC_B_CLK0>,
@@ -1766,7 +1766,7 @@
 			sd_emmc_c: mmc@7000 {
 				compatible = "amlogic,meson-axg-mmc";
 				reg = <0x0 0x7000 0x0 0x800>;
-				interrupts = <GIC_SPI 218 IRQ_TYPE_EDGE_RISING>;
+				interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>;
 				status = "disabled";
 				clocks = <&clkc CLKID_SD_EMMC_C>,
 					<&clkc CLKID_SD_EMMC_C_CLK0>,
diff --git a/kernel/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/kernel/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index 075153a..9dd9f77 100644
--- a/kernel/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/kernel/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -1604,10 +1604,9 @@
 
 			dmc: bus@38000 {
 				compatible = "simple-bus";
-				reg = <0x0 0x38000 0x0 0x400>;
 				#address-cells = <2>;
 				#size-cells = <2>;
-				ranges = <0x0 0x0 0x0 0x38000 0x0 0x400>;
+				ranges = <0x0 0x0 0x0 0x38000 0x0 0x2000>;
 
 				canvas: video-lut@48 {
 					compatible = "amlogic,canvas";
@@ -1727,7 +1726,7 @@
 					#address-cells = <1>;
 					#size-cells = <0>;
 
-					internal_ephy: ethernet_phy@8 {
+					internal_ephy: ethernet-phy@8 {
 						compatible = "ethernet-phy-id0180.3301",
 							     "ethernet-phy-ieee802.3-c22";
 						interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
@@ -2317,7 +2316,7 @@
 		sd_emmc_a: sd@ffe03000 {
 			compatible = "amlogic,meson-axg-mmc";
 			reg = <0x0 0xffe03000 0x0 0x800>;
-			interrupts = <GIC_SPI 189 IRQ_TYPE_EDGE_RISING>;
+			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
 			status = "disabled";
 			clocks = <&clkc CLKID_SD_EMMC_A>,
 				 <&clkc CLKID_SD_EMMC_A_CLK0>,
@@ -2329,7 +2328,7 @@
 		sd_emmc_b: sd@ffe05000 {
 			compatible = "amlogic,meson-axg-mmc";
 			reg = <0x0 0xffe05000 0x0 0x800>;
-			interrupts = <GIC_SPI 190 IRQ_TYPE_EDGE_RISING>;
+			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
 			status = "disabled";
 			clocks = <&clkc CLKID_SD_EMMC_B>,
 				 <&clkc CLKID_SD_EMMC_B_CLK0>,
@@ -2341,7 +2340,7 @@
 		sd_emmc_c: mmc@ffe07000 {
 			compatible = "amlogic,meson-axg-mmc";
 			reg = <0x0 0xffe07000 0x0 0x800>;
-			interrupts = <GIC_SPI 191 IRQ_TYPE_EDGE_RISING>;
+			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
 			status = "disabled";
 			clocks = <&clkc CLKID_SD_EMMC_C>,
 				 <&clkc CLKID_SD_EMMC_C_CLK0>,
diff --git a/kernel/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi b/kernel/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
index fb0ab27..6eaceb7 100644
--- a/kernel/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
+++ b/kernel/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
@@ -57,26 +57,6 @@
 		compatible = "operating-points-v2";
 		opp-shared;
 
-		opp-100000000 {
-			opp-hz = /bits/ 64 <100000000>;
-			opp-microvolt = <731000>;
-		};
-
-		opp-250000000 {
-			opp-hz = /bits/ 64 <250000000>;
-			opp-microvolt = <731000>;
-		};
-
-		opp-500000000 {
-			opp-hz = /bits/ 64 <500000000>;
-			opp-microvolt = <731000>;
-		};
-
-		opp-667000000 {
-			opp-hz = /bits/ 64 <666666666>;
-			opp-microvolt = <731000>;
-		};
-
 		opp-1000000000 {
 			opp-hz = /bits/ 64 <1000000000>;
 			opp-microvolt = <731000>;
diff --git a/kernel/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi b/kernel/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
index c2480ba..27e964b 100644
--- a/kernel/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
+++ b/kernel/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
@@ -17,7 +17,7 @@
 		io-channel-names = "buttons";
 		keyup-threshold-microvolt = <1800000>;
 
-		update-button {
+		button-update {
 			label = "update";
 			linux,code = <KEY_VENDOR>;
 			press-threshold-microvolt = <1300000>;
diff --git a/kernel/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/kernel/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 47cbb0a..4c71315 100644
--- a/kernel/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/kernel/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -226,7 +226,7 @@
 			reg = <0x14 0x10>;
 		};
 
-		eth_mac: eth_mac@34 {
+		eth_mac: eth-mac@34 {
 			reg = <0x34 0x10>;
 		};
 
@@ -243,7 +243,7 @@
 		scpi_clocks: clocks {
 			compatible = "arm,scpi-clocks";
 
-			scpi_dvfs: scpi_clocks@0 {
+			scpi_dvfs: clocks-0 {
 				compatible = "arm,scpi-dvfs-clocks";
 				#clock-cells = <1>;
 				clock-indices = <0>;
@@ -524,7 +524,7 @@
 			#size-cells = <2>;
 			ranges = <0x0 0x0 0x0 0xc8834000 0x0 0x2000>;
 
-			hwrng: rng {
+			hwrng: rng@0 {
 				compatible = "amlogic,meson-rng";
 				reg = <0x0 0x0 0x0 0x4>;
 			};
@@ -595,21 +595,21 @@
 			sd_emmc_a: mmc@70000 {
 				compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc";
 				reg = <0x0 0x70000 0x0 0x800>;
-				interrupts = <GIC_SPI 216 IRQ_TYPE_EDGE_RISING>;
+				interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
 				status = "disabled";
 			};
 
 			sd_emmc_b: mmc@72000 {
 				compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc";
 				reg = <0x0 0x72000 0x0 0x800>;
-				interrupts = <GIC_SPI 217 IRQ_TYPE_EDGE_RISING>;
+				interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>;
 				status = "disabled";
 			};
 
 			sd_emmc_c: mmc@74000 {
 				compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc";
 				reg = <0x0 0x74000 0x0 0x800>;
-				interrupts = <GIC_SPI 218 IRQ_TYPE_EDGE_RISING>;
+				interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>;
 				status = "disabled";
 			};
 		};
diff --git a/kernel/arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts b/kernel/arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts
index e8394a8..802faf7 100644
--- a/kernel/arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts
+++ b/kernel/arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts
@@ -16,7 +16,7 @@
 
 	leds {
 		compatible = "gpio-leds";
-		status {
+		led {
 			gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_LOW>;
 			default-state = "off";
 			color = <LED_COLOR_ID_RED>;
diff --git a/kernel/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts b/kernel/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts
index 9ef210f..393d3cb 100644
--- a/kernel/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts
+++ b/kernel/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts
@@ -18,7 +18,7 @@
 	leds {
 		compatible = "gpio-leds";
 
-		status {
+		led {
 			label = "n1:white:status";
 			gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>;
 			default-state = "on";
diff --git a/kernel/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts b/kernel/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts
index 0b95e9e..ca3fd6b 100644
--- a/kernel/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts
+++ b/kernel/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts
@@ -75,6 +75,5 @@
 		enable-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
 		max-speed = <2000000>;
 		clocks = <&wifi32k>;
-		clock-names = "lpo";
 	};
 };
diff --git a/kernel/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/kernel/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
index c3ac531..3500229 100644
--- a/kernel/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ b/kernel/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -759,7 +759,7 @@
 		};
 	};
 
-	eth-phy-mux {
+	eth-phy-mux@55c {
 		compatible = "mdio-mux-mmioreg", "mdio-mux";
 		#address-cells = <1>;
 		#size-cells = <0>;
diff --git a/kernel/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi b/kernel/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi
index 5667009..674a0ab 100644
--- a/kernel/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi
+++ b/kernel/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi
@@ -70,7 +70,7 @@
 &ecspi2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_espi2>;
-	cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
+	cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
 	status = "okay";
 
 	eeprom@0 {
@@ -187,7 +187,7 @@
 			MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK		0x82
 			MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI		0x82
 			MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO		0x82
-			MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9		0x41
+			MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13              0x41
 		>;
 	};
 
diff --git a/kernel/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/kernel/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
index 521eb3a..ed6d296 100644
--- a/kernel/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
+++ b/kernel/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
@@ -128,7 +128,7 @@
 		rohm,reset-snvs-powered;
 
 		#clock-cells = <0>;
-		clocks = <&osc_32k 0>;
+		clocks = <&osc_32k>;
 		clock-output-names = "clk-32k-out";
 
 		regulators {
diff --git a/kernel/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h b/kernel/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
index a003e6a..56271ab 100644
--- a/kernel/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
+++ b/kernel/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
@@ -601,7 +601,7 @@
 #define MX8MM_IOMUXC_UART1_RXD_GPIO5_IO22                                   0x234 0x49C 0x000 0x5 0x0
 #define MX8MM_IOMUXC_UART1_RXD_TPSMP_HDATA24                                0x234 0x49C 0x000 0x7 0x0
 #define MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX                                 0x238 0x4A0 0x000 0x0 0x0
-#define MX8MM_IOMUXC_UART1_TXD_UART1_DTE_RX                                 0x238 0x4A0 0x4F4 0x0 0x0
+#define MX8MM_IOMUXC_UART1_TXD_UART1_DTE_RX                                 0x238 0x4A0 0x4F4 0x0 0x1
 #define MX8MM_IOMUXC_UART1_TXD_ECSPI3_MOSI                                  0x238 0x4A0 0x000 0x1 0x0
 #define MX8MM_IOMUXC_UART1_TXD_GPIO5_IO23                                   0x238 0x4A0 0x000 0x5 0x0
 #define MX8MM_IOMUXC_UART1_TXD_TPSMP_HDATA25                                0x238 0x4A0 0x000 0x7 0x0
diff --git a/kernel/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi b/kernel/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi
index f6287f1..9c6c21c 100644
--- a/kernel/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi
+++ b/kernel/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi
@@ -98,11 +98,17 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		ethphy: ethernet-phy@4 {
+		ethphy: ethernet-phy@4 { /* AR8033 or ADIN1300 */
 			compatible = "ethernet-phy-ieee802.3-c22";
 			reg = <4>;
 			reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
 			reset-assert-us = <10000>;
+			/*
+			 * Deassert delay:
+			 * ADIN1300 requires 5ms.
+			 * AR8033   requires 1ms.
+			 */
+			reset-deassert-us = <20000>;
 		};
 	};
 };
@@ -345,7 +351,7 @@
 			MX8MN_IOMUXC_ENET_RXC_ENET1_RGMII_RXC		0x91
 			MX8MN_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL	0x91
 			MX8MN_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL	0x1f
-			MX8MN_IOMUXC_GPIO1_IO09_GPIO1_IO9		0x19
+			MX8MN_IOMUXC_GPIO1_IO09_GPIO1_IO9		0x159
 		>;
 	};
 
diff --git a/kernel/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts b/kernel/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts
index 5d5aa65..6e61827 100644
--- a/kernel/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts
+++ b/kernel/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts
@@ -339,7 +339,7 @@
 	bus-width = <4>;
 	non-removable;
 	no-sd;
-	no-emmc;
+	no-mmc;
 	status = "okay";
 
 	brcmf: wifi@1 {
@@ -359,7 +359,7 @@
 	cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
 	bus-width = <4>;
 	no-sdio;
-	no-emmc;
+	no-mmc;
 	disable-wp;
 	status = "okay";
 };
diff --git a/kernel/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/kernel/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
index 00e5dbf..eea8d23 100644
--- a/kernel/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
+++ b/kernel/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
@@ -124,9 +124,12 @@
 	/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 */
 	};
 };
 
diff --git a/kernel/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/kernel/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
index 7d369fd..9d20cab 100644
--- a/kernel/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+++ b/kernel/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
@@ -26,14 +26,14 @@
 		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>;
@@ -50,7 +50,7 @@
 		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 @@
 		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 @@
 		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 @@
 		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>;
diff --git a/kernel/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/kernel/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index db17d0a..cc3d1c9 100644
--- a/kernel/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/kernel/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -160,70 +160,70 @@
 		#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>;
@@ -266,7 +266,7 @@
 		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>;
diff --git a/kernel/arch/arm64/boot/dts/mediatek/mt6797.dtsi b/kernel/arch/arm64/boot/dts/mediatek/mt6797.dtsi
index 1561623..c3677d7 100644
--- a/kernel/arch/arm64/boot/dts/mediatek/mt6797.dtsi
+++ b/kernel/arch/arm64/boot/dts/mediatek/mt6797.dtsi
@@ -95,7 +95,7 @@
 		};
 	};
 
-	clk26m: oscillator@0 {
+	clk26m: oscillator-26m {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
 		clock-frequency = <26000000>;
diff --git a/kernel/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/kernel/arch/arm64/boot/dts/mediatek/mt7622.dtsi
index 7c6d871..884930a 100644
--- a/kernel/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/kernel/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -428,6 +428,7 @@
 	pwm: pwm@11006000 {
 		compatible = "mediatek,mt7622-pwm";
 		reg = <0 0x11006000 0 0x1000>;
+		#pwm-cells = <2>;
 		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&topckgen CLK_TOP_PWM_SEL>,
 			 <&pericfg CLK_PERI_PWM_PD>,
diff --git a/kernel/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/kernel/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 08a914d..31bc8ba 100644
--- a/kernel/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/kernel/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -205,6 +205,15 @@
 		method          = "smc";
 	};
 
+	clk13m: fixed-factor-clock-13m {
+		compatible = "fixed-factor-clock";
+		#clock-cells = <0>;
+		clocks = <&clk26m>;
+		clock-div = <2>;
+		clock-mult = <1>;
+		clock-output-names = "clk13m";
+	};
+
 	clk26m: oscillator {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
@@ -355,8 +364,7 @@
 				     "mediatek,mt6765-timer";
 			reg = <0 0x10017000 0 0x1000>;
 			interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&topckgen CLK_TOP_CLK13M>;
-			clock-names = "clk13m";
+			clocks = <&clk13m>;
 		};
 
 		gce: mailbox@10238000 {
diff --git a/kernel/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi b/kernel/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
index 99c2d6f..d505973 100644
--- a/kernel/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
+++ b/kernel/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
@@ -17,7 +17,7 @@
 	};
 
 	firmware {
-		optee: optee@4fd00000 {
+		optee: optee {
 			compatible = "linaro,optee-tz";
 			method = "smc";
 		};
@@ -209,7 +209,7 @@
 		};
 	};
 
-	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 @@
 		};
 	};
 
-	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>;
diff --git a/kernel/arch/arm64/boot/dts/microchip/sparx5.dtsi b/kernel/arch/arm64/boot/dts/microchip/sparx5.dtsi
index 3cb01c3..8dd679f 100644
--- a/kernel/arch/arm64/boot/dts/microchip/sparx5.dtsi
+++ b/kernel/arch/arm64/boot/dts/microchip/sparx5.dtsi
@@ -61,7 +61,7 @@
 		interrupt-affinity = <&cpu0>, <&cpu1>;
 	};
 
-	psci {
+	psci: psci {
 		compatible = "arm,psci-0.2";
 		method = "smc";
 	};
diff --git a/kernel/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi b/kernel/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi
index 9d1a082..32bb76b 100644
--- a/kernel/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi
+++ b/kernel/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi
@@ -6,6 +6,18 @@
 /dts-v1/;
 #include "sparx5.dtsi"
 
+&psci {
+	status = "disabled";
+};
+
+&cpu0 {
+	enable-method = "spin-table";
+};
+
+&cpu1 {
+	enable-method = "spin-table";
+};
+
 &uart0 {
 	status = "okay";
 };
diff --git a/kernel/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts b/kernel/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts
index f6ddf17..861b356 100644
--- a/kernel/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts
+++ b/kernel/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts
@@ -26,7 +26,7 @@
 
 	v1p05: v1p05-regulator {
 		compatible = "regulator-fixed";
-		reglator-name = "v1p05";
+		regulator-name = "v1p05";
 		regulator-always-on;
 		regulator-boot-on;
 
@@ -38,7 +38,7 @@
 
 	v12_poe: v12-poe-regulator {
 		compatible = "regulator-fixed";
-		reglator-name = "v12_poe";
+		regulator-name = "v12_poe";
 		regulator-always-on;
 		regulator-boot-on;
 
diff --git a/kernel/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts b/kernel/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts
index e8eaa95..b867506 100644
--- a/kernel/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts
+++ b/kernel/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts
@@ -37,6 +37,8 @@
 
 &spi_0 {
 	cs-select = <0>;
+	pinctrl-0 = <&spi_0_pins>;
+	pinctrl-names = "default";
 	status = "okay";
 
 	m25p80@0 {
diff --git a/kernel/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts b/kernel/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
index cc08dc4..68698cd 100644
--- a/kernel/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
+++ b/kernel/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
@@ -60,11 +60,11 @@
 	perst-gpio = <&tlmm 58 0x1>;
 };
 
-&pcie_phy0 {
+&pcie_qmp0 {
 	status = "okay";
 };
 
-&pcie_phy1 {
+&pcie_qmp1 {
 	status = "okay";
 };
 
diff --git a/kernel/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/kernel/arch/arm64/boot/dts/qcom/ipq8074.dtsi
index 0b7d4f9..c9ec643 100644
--- a/kernel/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/kernel/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -108,7 +108,7 @@
 				#phy-cells = <0>;
 				clocks = <&gcc GCC_USB1_PIPE_CLK>;
 				clock-names = "pipe0";
-				clock-output-names = "gcc_usb1_pipe_clk_src";
+				clock-output-names = "usb3phy_1_cc_pipe_clk";
 			};
 		};
 
@@ -151,7 +151,7 @@
 				#phy-cells = <0>;
 				clocks = <&gcc GCC_USB0_PIPE_CLK>;
 				clock-names = "pipe0";
-				clock-output-names = "gcc_usb0_pipe_clk_src";
+				clock-output-names = "usb3phy_0_cc_pipe_clk";
 			};
 		};
 
@@ -167,34 +167,61 @@
 			resets = <&gcc GCC_QUSB2_0_PHY_BCR>;
 		};
 
-		pcie_phy0: phy@86000 {
-			compatible = "qcom,ipq8074-qmp-pcie-phy";
-			reg = <0x00086000 0x1000>;
-			#phy-cells = <0>;
-			clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
-			clock-names = "pipe_clk";
-			clock-output-names = "pcie20_phy0_pipe_clk";
+		pcie_qmp0: phy@84000 {
+			compatible = "qcom,ipq8074-qmp-gen3-pcie-phy";
+			reg = <0x00084000 0x1bc>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
 
+			clocks = <&gcc GCC_PCIE0_AUX_CLK>,
+				<&gcc GCC_PCIE0_AHB_CLK>;
+			clock-names = "aux", "cfg_ahb";
 			resets = <&gcc GCC_PCIE0_PHY_BCR>,
 				<&gcc GCC_PCIE0PHY_PHY_BCR>;
 			reset-names = "phy",
 				      "common";
 			status = "disabled";
+
+			pcie_phy0: phy@84200 {
+				reg = <0x84200 0x16c>,
+				      <0x84400 0x200>,
+				      <0x84800 0x1f0>,
+				      <0x84c00 0xf4>;
+				#phy-cells = <0>;
+				#clock-cells = <0>;
+				clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
+				clock-names = "pipe0";
+				clock-output-names = "pcie20_phy0_pipe_clk";
+			};
 		};
 
-		pcie_phy1: phy@8e000 {
+		pcie_qmp1: phy@8e000 {
 			compatible = "qcom,ipq8074-qmp-pcie-phy";
-			reg = <0x0008e000 0x1000>;
-			#phy-cells = <0>;
-			clocks = <&gcc GCC_PCIE1_PIPE_CLK>;
-			clock-names = "pipe_clk";
-			clock-output-names = "pcie20_phy1_pipe_clk";
+			reg = <0x0008e000 0x1c4>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
 
+			clocks = <&gcc GCC_PCIE1_AUX_CLK>,
+				<&gcc GCC_PCIE1_AHB_CLK>;
+			clock-names = "aux", "cfg_ahb";
 			resets = <&gcc GCC_PCIE1_PHY_BCR>,
 				<&gcc GCC_PCIE1PHY_PHY_BCR>;
 			reset-names = "phy",
 				      "common";
 			status = "disabled";
+
+			pcie_phy1: phy@8e200 {
+				reg = <0x8e200 0x130>,
+				      <0x8e400 0x200>,
+				      <0x8e800 0x1f8>;
+				#phy-cells = <0>;
+				#clock-cells = <0>;
+				clocks = <&gcc GCC_PCIE1_PIPE_CLK>;
+				clock-names = "pipe0";
+				clock-output-names = "pcie20_phy1_pipe_clk";
+			};
 		};
 
 		tlmm: pinctrl@1000000 {
@@ -580,10 +607,8 @@
 			phys = <&pcie_phy1>;
 			phy-names = "pciephy";
 
-			ranges = <0x81000000 0 0x10200000 0x10200000
-				  0 0x100000   /* downstream I/O */
-				  0x82000000 0 0x10300000 0x10300000
-				  0 0xd00000>; /* non-prefetchable memory */
+			ranges = <0x81000000 0x0 0x00000000 0x10200000 0x0 0x10000>,   /* I/O */
+				 <0x82000000 0x0 0x10220000 0x10220000 0x0 0xfde0000>; /* MEM */
 
 			interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "msi";
@@ -626,26 +651,26 @@
 		};
 
 		pcie0: pci@20000000 {
-			compatible = "qcom,pcie-ipq8074";
+			compatible = "qcom,pcie-ipq8074-gen3";
 			reg = <0x20000000 0xf1d>,
 			      <0x20000f20 0xa8>,
-			      <0x00080000 0x2000>,
+			      <0x20001000 0x1000>,
+			      <0x00080000 0x4000>,
 			      <0x20100000 0x1000>;
-			reg-names = "dbi", "elbi", "parf", "config";
+			reg-names = "dbi", "elbi", "atu", "parf", "config";
 			device_type = "pci";
 			linux,pci-domain = <0>;
 			bus-range = <0x00 0xff>;
 			num-lanes = <1>;
+			max-link-speed = <3>;
 			#address-cells = <3>;
 			#size-cells = <2>;
 
 			phys = <&pcie_phy0>;
 			phy-names = "pciephy";
 
-			ranges = <0x81000000 0 0x20200000 0x20200000
-				  0 0x100000   /* downstream I/O */
-				  0x82000000 0 0x20300000 0x20300000
-				  0 0xd00000>; /* non-prefetchable memory */
+			ranges = <0x81000000 0x0 0x00000000 0x20200000 0x0 0x10000>,   /* I/O */
+				 <0x82000000 0x0 0x20220000 0x20220000 0x0 0xfde0000>; /* MEM */
 
 			interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "msi";
@@ -663,28 +688,30 @@
 			clocks = <&gcc GCC_SYS_NOC_PCIE0_AXI_CLK>,
 				 <&gcc GCC_PCIE0_AXI_M_CLK>,
 				 <&gcc GCC_PCIE0_AXI_S_CLK>,
-				 <&gcc GCC_PCIE0_AHB_CLK>,
-				 <&gcc GCC_PCIE0_AUX_CLK>;
-
+				 <&gcc GCC_PCIE0_AXI_S_BRIDGE_CLK>,
+				 <&gcc GCC_PCIE0_RCHNG_CLK>;
 			clock-names = "iface",
 				      "axi_m",
 				      "axi_s",
-				      "ahb",
-				      "aux";
+				      "axi_bridge",
+				      "rchng";
+
 			resets = <&gcc GCC_PCIE0_PIPE_ARES>,
 				 <&gcc GCC_PCIE0_SLEEP_ARES>,
 				 <&gcc GCC_PCIE0_CORE_STICKY_ARES>,
 				 <&gcc GCC_PCIE0_AXI_MASTER_ARES>,
 				 <&gcc GCC_PCIE0_AXI_SLAVE_ARES>,
 				 <&gcc GCC_PCIE0_AHB_ARES>,
-				 <&gcc GCC_PCIE0_AXI_MASTER_STICKY_ARES>;
+				 <&gcc GCC_PCIE0_AXI_MASTER_STICKY_ARES>,
+				 <&gcc GCC_PCIE0_AXI_SLAVE_STICKY_ARES>;
 			reset-names = "pipe",
 				      "sleep",
 				      "sticky",
 				      "axi_m",
 				      "axi_s",
 				      "ahb",
-				      "axi_m_sticky";
+				      "axi_m_sticky",
+				      "axi_s_sticky";
 			status = "disabled";
 		};
 	};
diff --git a/kernel/arch/arm64/boot/dts/qcom/msm8916.dtsi b/kernel/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 291276a..5b79e4a 100644
--- a/kernel/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/kernel/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -1006,7 +1006,7 @@
 			};
 		};
 
-		camss: camss@1b00000 {
+		camss: camss@1b0ac00 {
 			compatible = "qcom,msm8916-camss";
 			reg = <0x01b0ac00 0x200>,
 				<0x01b00030 0x4>,
@@ -1249,7 +1249,7 @@
 		};
 
 		mpss: remoteproc@4080000 {
-			compatible = "qcom,msm8916-mss-pil", "qcom,q6v5-pil";
+			compatible = "qcom,msm8916-mss-pil";
 			reg = <0x04080000 0x100>,
 			      <0x04020000 0x040>;
 
diff --git a/kernel/arch/arm64/boot/dts/qcom/msm8994.dtsi b/kernel/arch/arm64/boot/dts/qcom/msm8994.dtsi
index aeb5762..caaf710 100644
--- a/kernel/arch/arm64/boot/dts/qcom/msm8994.dtsi
+++ b/kernel/arch/arm64/boot/dts/qcom/msm8994.dtsi
@@ -489,7 +489,7 @@
 			reg = <0xfc4ab000 0x4>;
 		};
 
-		spmi_bus: spmi@fc4c0000 {
+		spmi_bus: spmi@fc4cf000 {
 			compatible = "qcom,spmi-pmic-arb";
 			reg = <0xfc4cf000 0x1000>,
 			      <0xfc4cb000 0x1000>,
diff --git a/kernel/arch/arm64/boot/dts/qcom/msm8996.dtsi b/kernel/arch/arm64/boot/dts/qcom/msm8996.dtsi
index ef5d03a..0bc5fef 100644
--- a/kernel/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/kernel/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -651,17 +651,17 @@
 				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>;
@@ -744,8 +744,8 @@
 
 				#address-cells = <3>;
 				#size-cells = <2>;
-				ranges = <0x01000000 0x0 0x0c200000 0x0c200000 0x0 0x100000>,
-					<0x02000000 0x0 0x0c300000 0x0c300000 0x0 0xd00000>;
+				ranges = <0x01000000 0x0 0x00000000 0x0c200000 0x0 0x100000>,
+					 <0x02000000 0x0 0x0c300000 0x0c300000 0x0 0xd00000>;
 
 				interrupts = <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-names = "msi";
@@ -796,8 +796,8 @@
 
 				#address-cells = <3>;
 				#size-cells = <2>;
-				ranges = <0x01000000 0x0 0x0d200000 0x0d200000 0x0 0x100000>,
-					<0x02000000 0x0 0x0d300000 0x0d300000 0x0 0xd00000>;
+				ranges = <0x01000000 0x0 0x00000000 0x0d200000 0x0 0x100000>,
+					 <0x02000000 0x0 0x0d300000 0x0d300000 0x0 0xd00000>;
 
 				interrupts = <GIC_SPI 413 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-names = "msi";
@@ -845,8 +845,8 @@
 
 				#address-cells = <3>;
 				#size-cells = <2>;
-				ranges = <0x01000000 0x0 0x0e200000 0x0e200000 0x0 0x100000>,
-					<0x02000000 0x0 0x0e300000 0x0e300000 0x0 0x1d00000>;
+				ranges = <0x01000000 0x0 0x00000000 0x0e200000 0x0 0x100000>,
+					 <0x02000000 0x0 0x0e300000 0x0e300000 0x0 0x1d00000>;
 
 				device_type = "pci";
 
@@ -956,7 +956,7 @@
 			};
 		};
 
-		camss: camss@a00000 {
+		camss: camss@a34000 {
 			compatible = "qcom,msm8996-camss";
 			reg = <0x00a34000 0x1000>,
 			      <0x00a00030 0x4>,
@@ -1771,8 +1771,11 @@
 				interrupts = <0 131 IRQ_TYPE_LEVEL_HIGH>;
 				phys = <&hsusb_phy1>, <&ssusb_phy_0>;
 				phy-names = "usb2-phy", "usb3-phy";
+				snps,hird-threshold = /bits/ 8 <0>;
 				snps,dis_u2_susphy_quirk;
 				snps,dis_enblslpm_quirk;
+				snps,is-utmi-l1-suspend;
+				tx-fifo-resize;
 			};
 		};
 
@@ -1963,6 +1966,9 @@
 			#size-cells = <1>;
 			ranges;
 
+			interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "hs_phy_irq";
+
 			clocks = <&gcc GCC_PERIPH_NOC_USB20_AHB_CLK>,
 				<&gcc GCC_USB20_MASTER_CLK>,
 				<&gcc GCC_USB20_MOCK_UTMI_CLK>,
diff --git a/kernel/arch/arm64/boot/dts/qcom/msm8998.dtsi b/kernel/arch/arm64/boot/dts/qcom/msm8998.dtsi
index 9e04ac3..7c8d69c 100644
--- a/kernel/arch/arm64/boot/dts/qcom/msm8998.dtsi
+++ b/kernel/arch/arm64/boot/dts/qcom/msm8998.dtsi
@@ -942,7 +942,7 @@
 			phys = <&pciephy>;
 			phy-names = "pciephy";
 
-			ranges = <0x01000000 0x0 0x1b200000 0x1b200000 0x0 0x100000>,
+			ranges = <0x01000000 0x0 0x00000000 0x1b200000 0x0 0x100000>,
 				 <0x02000000 0x0 0x1b300000 0x1b300000 0x0 0xd00000>;
 
 			#interrupt-cells = <1>;
@@ -1187,7 +1187,7 @@
 			compatible = "arm,coresight-stm", "arm,primecell";
 			reg = <0x06002000 0x1000>,
 			      <0x16280000 0x180000>;
-			reg-names = "stm-base", "stm-data-base";
+			reg-names = "stm-base", "stm-stimulus-base";
 			status = "disabled";
 
 			clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
diff --git a/kernel/arch/arm64/boot/dts/qcom/qcs404.dtsi b/kernel/arch/arm64/boot/dts/qcom/qcs404.dtsi
index 7bddc5e..d41f068 100644
--- a/kernel/arch/arm64/boot/dts/qcom/qcs404.dtsi
+++ b/kernel/arch/arm64/boot/dts/qcom/qcs404.dtsi
@@ -775,7 +775,7 @@
 
 			clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
 			resets = <&gcc GCC_PCIEPHY_0_PHY_BCR>,
-				 <&gcc 21>;
+				 <&gcc GCC_PCIE_0_PIPE_ARES>;
 			reset-names = "phy", "pipe";
 
 			clock-output-names = "pcie_0_pipe_clk";
@@ -1305,12 +1305,12 @@
 				 <&gcc GCC_PCIE_0_SLV_AXI_CLK>;
 			clock-names = "iface", "aux", "master_bus", "slave_bus";
 
-			resets = <&gcc 18>,
-				 <&gcc 17>,
-				 <&gcc 15>,
-				 <&gcc 19>,
+			resets = <&gcc GCC_PCIE_0_AXI_MASTER_ARES>,
+				 <&gcc GCC_PCIE_0_AXI_SLAVE_ARES>,
+				 <&gcc GCC_PCIE_0_AXI_MASTER_STICKY_ARES>,
+				 <&gcc GCC_PCIE_0_CORE_STICKY_ARES>,
 				 <&gcc GCC_PCIE_0_BCR>,
-				 <&gcc 16>;
+				 <&gcc GCC_PCIE_0_AHB_ARES>;
 			reset-names = "axi_m",
 				      "axi_s",
 				      "axi_m_sticky",
diff --git a/kernel/arch/arm64/boot/dts/qcom/sc7180.dtsi b/kernel/arch/arm64/boot/dts/qcom/sc7180.dtsi
index c71f3af..eb07a88 100644
--- a/kernel/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/kernel/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -3066,8 +3066,8 @@
 			interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>;
 			qcom,ee = <0>;
 			qcom,channel = <0>;
-			#address-cells = <1>;
-			#size-cells = <1>;
+			#address-cells = <2>;
+			#size-cells = <0>;
 			interrupt-controller;
 			#interrupt-cells = <4>;
 			cell-index = <0>;
diff --git a/kernel/arch/arm64/boot/dts/qcom/sdm630.dtsi b/kernel/arch/arm64/boot/dts/qcom/sdm630.dtsi
index f870545..79d260c 100644
--- a/kernel/arch/arm64/boot/dts/qcom/sdm630.dtsi
+++ b/kernel/arch/arm64/boot/dts/qcom/sdm630.dtsi
@@ -593,7 +593,7 @@
 					pins = "gpio17", "gpio18", "gpio19";
 					function = "gpio";
 					drive-strength = <2>;
-					bias-no-pull;
+					bias-disable;
 				};
 			};
 
diff --git a/kernel/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/kernel/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
index 64fc1bf..26f6f19 100644
--- a/kernel/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
+++ b/kernel/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
@@ -1292,7 +1292,7 @@
 		config {
 			pins = "gpio126";
 			function = "gpio";
-			bias-no-pull;
+			bias-disable;
 			drive-strength = <2>;
 			output-low;
 		};
@@ -1302,7 +1302,7 @@
 		config {
 			pins = "gpio126";
 			function = "gpio";
-			bias-no-pull;
+			bias-disable;
 			drive-strength = <2>;
 			output-high;
 		};
diff --git a/kernel/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/kernel/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
index 96d36b3..75731fe 100644
--- a/kernel/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+++ b/kernel/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
@@ -85,6 +85,14 @@
 		};
 	};
 
+	reserved-memory {
+		/* Cont splash region set up by the bootloader */
+		cont_splash_mem: framebuffer@9d400000 {
+			reg = <0x0 0x9d400000 0x0 0x2400000>;
+			no-map;
+		};
+	};
+
 	lt9611_1v8: lt9611-vdd18-regulator {
 		compatible = "regulator-fixed";
 		regulator-name = "LT9611_1V8";
@@ -896,7 +904,7 @@
 	};
 
 	wcd_intr_default: wcd_intr_default {
-		pins = <54>;
+		pins = "gpio54";
 		function = "gpio";
 
 		input-enable;
@@ -1045,7 +1053,10 @@
 
 /* PINCTRL - additions to nodes defined in sdm845.dtsi */
 &qup_spi2_default {
-	drive-strength = <16>;
+	pinconf {
+		pins = "gpio27", "gpio28", "gpio29", "gpio30";
+		drive-strength = <16>;
+	};
 };
 
 &qup_uart3_default{
diff --git a/kernel/arch/arm64/boot/dts/qcom/sdm845.dtsi b/kernel/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 9beb3c3..5c696eb 100644
--- a/kernel/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/kernel/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -196,8 +196,8 @@
 			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
 					   &LITTLE_CPU_SLEEP_1
 					   &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <607>;
-			dynamic-power-coefficient = <100>;
+			capacity-dmips-mhz = <611>;
+			dynamic-power-coefficient = <154>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
 			operating-points-v2 = <&cpu0_opp_table>;
 			interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>,
@@ -221,8 +221,8 @@
 			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
 					   &LITTLE_CPU_SLEEP_1
 					   &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <607>;
-			dynamic-power-coefficient = <100>;
+			capacity-dmips-mhz = <611>;
+			dynamic-power-coefficient = <154>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
 			operating-points-v2 = <&cpu0_opp_table>;
 			interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>,
@@ -243,8 +243,8 @@
 			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
 					   &LITTLE_CPU_SLEEP_1
 					   &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <607>;
-			dynamic-power-coefficient = <100>;
+			capacity-dmips-mhz = <611>;
+			dynamic-power-coefficient = <154>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
 			operating-points-v2 = <&cpu0_opp_table>;
 			interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>,
@@ -265,8 +265,8 @@
 			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
 					   &LITTLE_CPU_SLEEP_1
 					   &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <607>;
-			dynamic-power-coefficient = <100>;
+			capacity-dmips-mhz = <611>;
+			dynamic-power-coefficient = <154>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
 			operating-points-v2 = <&cpu0_opp_table>;
 			interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>,
@@ -288,7 +288,7 @@
 			cpu-idle-states = <&BIG_CPU_SLEEP_0
 					   &BIG_CPU_SLEEP_1
 					   &CLUSTER_SLEEP_0>;
-			dynamic-power-coefficient = <396>;
+			dynamic-power-coefficient = <442>;
 			qcom,freq-domain = <&cpufreq_hw 1>;
 			operating-points-v2 = <&cpu4_opp_table>;
 			interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>,
@@ -310,7 +310,7 @@
 			cpu-idle-states = <&BIG_CPU_SLEEP_0
 					   &BIG_CPU_SLEEP_1
 					   &CLUSTER_SLEEP_0>;
-			dynamic-power-coefficient = <396>;
+			dynamic-power-coefficient = <442>;
 			qcom,freq-domain = <&cpufreq_hw 1>;
 			operating-points-v2 = <&cpu4_opp_table>;
 			interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>,
@@ -332,7 +332,7 @@
 			cpu-idle-states = <&BIG_CPU_SLEEP_0
 					   &BIG_CPU_SLEEP_1
 					   &CLUSTER_SLEEP_0>;
-			dynamic-power-coefficient = <396>;
+			dynamic-power-coefficient = <442>;
 			qcom,freq-domain = <&cpufreq_hw 1>;
 			operating-points-v2 = <&cpu4_opp_table>;
 			interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>,
@@ -354,7 +354,7 @@
 			cpu-idle-states = <&BIG_CPU_SLEEP_0
 					   &BIG_CPU_SLEEP_1
 					   &CLUSTER_SLEEP_0>;
-			dynamic-power-coefficient = <396>;
+			dynamic-power-coefficient = <442>;
 			qcom,freq-domain = <&cpufreq_hw 1>;
 			operating-points-v2 = <&cpu4_opp_table>;
 			interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>,
@@ -1064,6 +1064,7 @@
 			#clock-cells = <1>;
 			#reset-cells = <1>;
 			#power-domain-cells = <1>;
+			power-domains = <&rpmhpd SDM845_CX>;
 		};
 
 		qfprom@784000 {
@@ -1816,8 +1817,8 @@
 			#address-cells = <3>;
 			#size-cells = <2>;
 
-			ranges = <0x01000000 0x0 0x60200000 0 0x60200000 0x0 0x100000>,
-				 <0x02000000 0x0 0x60300000 0 0x60300000 0x0 0xd00000>;
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>,
+				 <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0xd00000>;
 
 			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "msi";
@@ -1920,7 +1921,7 @@
 			#address-cells = <3>;
 			#size-cells = <2>;
 
-			ranges = <0x01000000 0x0 0x40200000 0x0 0x40200000 0x0 0x100000>,
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
 				 <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
 
 			interrupts = <GIC_SPI 307 IRQ_TYPE_EDGE_RISING>;
@@ -2108,7 +2109,7 @@
 				<0 0>,
 				<0 0>,
 				<0 0>,
-				<0 300000000>;
+				<75000000 300000000>;
 
 			status = "disabled";
 		};
diff --git a/kernel/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/kernel/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
index e080c31..4d67f49 100644
--- a/kernel/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+++ b/kernel/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
@@ -322,8 +322,10 @@
 };
 
 &qup_i2c12_default {
-	drive-strength = <2>;
-	bias-disable;
+	pinmux {
+		drive-strength = <2>;
+		bias-disable;
+	};
 };
 
 &qup_uart6_default {
diff --git a/kernel/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi b/kernel/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
index 53e1d43..663adf7 100644
--- a/kernel/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
+++ b/kernel/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
@@ -399,20 +399,6 @@
 		};
 	};
 
-	/* 0 - lcd_reset */
-	/* 1 - lcd_pwr */
-	/* 2 - lcd_select */
-	/* 3 - backlight-enable */
-	/* 4 - Touch_shdwn */
-	/* 5 - LCD_H_pol */
-	/* 6 - lcd_V_pol */
-	gpio_exp1: gpio@20 {
-		compatible = "onnn,pca9654";
-		reg = <0x20>;
-		gpio-controller;
-		#gpio-cells = <2>;
-	};
-
 	touchscreen@26 {
 		compatible = "ilitek,ili2117";
 		reg = <0x26>;
@@ -445,6 +431,16 @@
 			};
 		};
 	};
+
+	gpio_exp1: gpio@70 {
+		compatible = "nxp,pca9538";
+		reg = <0x70>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "lcd_reset", "lcd_pwr", "lcd_select",
+				  "backlight-enable", "Touch_shdwn",
+				  "LCD_H_pol", "lcd_V_pol";
+	};
 };
 
 &lvds0 {
diff --git a/kernel/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/kernel/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
index 4c7d7e8..c4a6dfa 100644
--- a/kernel/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
+++ b/kernel/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
@@ -49,17 +49,14 @@
 		opp-shared;
 		opp-800000000 {
 			opp-hz = /bits/ 64 <800000000>;
-			opp-microvolt = <820000>;
 			clock-latency-ns = <300000>;
 		};
 		opp-1000000000 {
 			opp-hz = /bits/ 64 <1000000000>;
-			opp-microvolt = <820000>;
 			clock-latency-ns = <300000>;
 		};
 		opp-1200000000 {
 			opp-hz = /bits/ 64 <1200000000>;
-			opp-microvolt = <820000>;
 			clock-latency-ns = <300000>;
 			opp-suspend;
 		};
diff --git a/kernel/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/kernel/arch/arm64/boot/dts/renesas/r8a77990.dtsi
index 37159b9..e91d197 100644
--- a/kernel/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+++ b/kernel/arch/arm64/boot/dts/renesas/r8a77990.dtsi
@@ -60,17 +60,14 @@
 		opp-shared;
 		opp-800000000 {
 			opp-hz = /bits/ 64 <800000000>;
-			opp-microvolt = <820000>;
 			clock-latency-ns = <300000>;
 		};
 		opp-1000000000 {
 			opp-hz = /bits/ 64 <1000000000>;
-			opp-microvolt = <820000>;
 			clock-latency-ns = <300000>;
 		};
 		opp-1200000000 {
 			opp-hz = /bits/ 64 <1200000000>;
-			opp-microvolt = <820000>;
 			clock-latency-ns = <300000>;
 			opp-suspend;
 		};
diff --git a/kernel/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/kernel/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
index 05e64bf..24d0a13 100644
--- a/kernel/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+++ b/kernel/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
@@ -270,7 +270,7 @@
 	};
 
 	scif1_pins: scif1 {
-		groups = "scif1_data_b", "scif1_ctrl";
+		groups = "scif1_data_b";
 		function = "scif1";
 	};
 
@@ -330,7 +330,6 @@
 &scif1 {
 	pinctrl-0 = <&scif1_pins>;
 	pinctrl-names = "default";
-	uart-has-rtscts;
 
 	status = "okay";
 };
diff --git a/kernel/arch/arm64/boot/dts/rockchip/Makefile b/kernel/arch/arm64/boot/dts/rockchip/Makefile
index df605b9..5163c44 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/Makefile
+++ b/kernel/arch/arm64/boot/dts/rockchip/Makefile
@@ -11,6 +11,8 @@
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb-amic-v11.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb-amic-v13.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb-audio-amic-v10.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb-audio-v10-display-rgb.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb-dmic-pdm-v11.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb-dmic-pdm-v13.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-roc-cc.dtb
@@ -102,6 +104,7 @@
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3562-evb2-ddr4-v10-dual-camera.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3562-evb2-ddr4-v10-image-reverse.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3562-evb2-ddr4-v10-linux.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3562-evb2-ddr4-v10-linux-amp.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3562-evb2-ddr4-v10-pdm-mic-array.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3562-evb2-ddr4-v10-sii9022-bt1120-to-hdmi.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3562-iotest-lp3-v10.dtb
@@ -134,12 +137,18 @@
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rk817-tablet-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-dual-channel-lvds.dtb
-dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-dual-lvds.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-one-vp-two-single-channel-lvds.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-single-channel-lvds.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-two-vp-two-separate-single-channel-lvds.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-dual-camera.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds-linux.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-linux.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-linux-amp.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-linux-spi-nor.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-single-channel-lvds.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-two-vp-two-separate-single-channel-lvds.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb2-lp4x-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb2-lp4x-v10-bt1120-to-hdmi.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb4-lp3-v10.dtb
@@ -161,6 +170,7 @@
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nvr-demo-v10-linux-spi-nand.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nvr-demo-v12-linux.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nvr-demo-v12-linux-spi-nand.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-pcie-ep-lp4x-v10-linux.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-toybrick-sd0-android.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-toybrick-sd0-linux.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-toybrick-x0-android.dtb
@@ -199,11 +209,14 @@
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568m-serdes-v1-evb-display-super-frame-dsi0-command2lvds0-lp4x-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-dsi-dsc-MV2100UZ1.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-edp-8lanes-M280DCA.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-ipc-6x-linux.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-linux.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-linux-amp.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-linux-ipc.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-lt6911uxe.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-lt6911uxc-dual-mipi.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-rk628-hdmi2csi.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb2-lp4-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb2-lp4-v10-edp.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb2-lp4-v10-edp2dp.dtb
diff --git a/kernel/arch/arm64/boot/dts/rockchip/px30-android.dtsi b/kernel/arch/arm64/boot/dts/rockchip/px30-android.dtsi
index ba3620b..017a170 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/px30-android.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/px30-android.dtsi
@@ -9,6 +9,14 @@
 		bootargs = "earlycon=uart8250,mmio32,0xff160000 console=ttyFIQ0 init=/init kpti=0";
 	};
 
+	debug: debug@ff690000 {
+		compatible = "rockchip,debug";
+		reg = <0x0 0xff690000 0x0 0x1000>,
+		      <0x0 0xff692000 0x0 0x1000>,
+		      <0x0 0xff694000 0x0 0x1000>,
+		      <0x0 0xff696000 0x0 0x1000>;
+	};
+
 	fiq-debugger {
 		compatible = "rockchip,fiq-debugger";
 		rockchip,serial-id = <2>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10-avb.dts b/kernel/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10-avb.dts
index 7b122c5..fd9b6a2 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10-avb.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10-avb.dts
@@ -13,10 +13,6 @@
 	compatible = "rockchip,px30-evb-ddr3-v10-avb", "rockchip,px30";
 };
 
-&chosen {
-	bootargs_ext = "androidboot.boot_devices=ff390000.dwmmc,ff3b0000.nandc";
-};
-
 &dsi {
 	status = "okay";
 
diff --git a/kernel/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10.dtsi b/kernel/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10.dtsi
index bc7d3da..75f624e 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10.dtsi
@@ -18,14 +18,14 @@
 		keyup-threshold-microvolt = <1800000>;
 
 		esc-key {
-			linux,code = <KEY_ESC>;
-			label = "esc";
+			linux,code = <KEY_BACK>;
+			label = "back";
 			press-threshold-microvolt = <1310000>;
 		};
 
 		home-key {
-			linux,code = <KEY_HOME>;
-			label = "home";
+			linux,code = <KEY_HOMEPAGE>;
+			label = "homepage";
 			press-threshold-microvolt = <624000>;
 		};
 
diff --git a/kernel/arch/arm64/boot/dts/rockchip/px30.dtsi b/kernel/arch/arm64/boot/dts/rockchip/px30.dtsi
index 6a0be24..ce921f6 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/px30.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/px30.dtsi
@@ -26,6 +26,10 @@
 
 	aliases {
 		ethernet0 = &gmac;
+		gpio0 = &gpio0;
+		gpio1 = &gpio1;
+		gpio2 = &gpio2;
+		gpio3 = &gpio3;
 		i2c0 = &i2c0;
 		i2c1 = &i2c1;
 		i2c2 = &i2c2;
@@ -1045,6 +1049,7 @@
 	pwm0: pwm@ff200000 {
 		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff200000 0x0 0x10>;
+		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
 		clock-names = "pwm", "pclk";
 		pinctrl-names = "active";
@@ -1056,6 +1061,7 @@
 	pwm1: pwm@ff200010 {
 		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff200010 0x0 0x10>;
+		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
 		clock-names = "pwm", "pclk";
 		pinctrl-names = "active";
@@ -1067,6 +1073,7 @@
 	pwm2: pwm@ff200020 {
 		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff200020 0x0 0x10>;
+		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
 		clock-names = "pwm", "pclk";
 		pinctrl-names = "active";
@@ -1078,6 +1085,8 @@
 	pwm3: pwm@ff200030 {
 		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff200030 0x0 0x10>;
+		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
 		clock-names = "pwm", "pclk";
 		pinctrl-names = "active";
@@ -1089,6 +1098,7 @@
 	pwm4: pwm@ff208000 {
 		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff208000 0x0 0x10>;
+		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
 		clock-names = "pwm", "pclk";
 		pinctrl-names = "active";
@@ -1100,6 +1110,7 @@
 	pwm5: pwm@ff208010 {
 		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff208010 0x0 0x10>;
+		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
 		clock-names = "pwm", "pclk";
 		pinctrl-names = "active";
@@ -1111,6 +1122,7 @@
 	pwm6: pwm@ff208020 {
 		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff208020 0x0 0x10>;
+		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
 		clock-names = "pwm", "pclk";
 		pinctrl-names = "active";
@@ -1122,6 +1134,8 @@
 	pwm7: pwm@ff208030 {
 		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff208030 0x0 0x10>;
+		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
 		clock-names = "pwm", "pclk";
 		pinctrl-names = "active";
@@ -1689,7 +1703,7 @@
 
 	vopb: vop@ff460000 {
 		compatible = "rockchip,px30-vop-big";
-		reg = <0x0 0xff460000 0x0 0x1fc>, <0x0 0xff460a00 0x0 0x400>;
+		reg = <0x0 0xff460000 0x0 0x260>, <0x0 0xff460a00 0x0 0x400>;
 		rockchip,grf = <&grf>;
 		reg-names = "regs", "gamma_lut";
 		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk1808-fpga.dts b/kernel/arch/arm64/boot/dts/rockchip/rk1808-fpga.dts
index d021918..d9aad0f 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk1808-fpga.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk1808-fpga.dts
@@ -31,7 +31,7 @@
 &emmc {
 	max-frequency = <400000>;
 	clocks = <&xin24m>, <&xin24m>, <&xin24m>, <&xin24m>;
-	clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+	clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 	mmc-hs200-1_8v;
 	no-sdio;
 	no-sd;
@@ -46,7 +46,7 @@
 &sdmmc {
 	max-frequency = <400000>;
 	clocks = <&xin24m>, <&xin24m>, <&xin24m>, <&xin24m>;
-	clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+	clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 	no-sdio;
 	no-mmc;
 	status = "okay";
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk1808.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk1808.dtsi
index cf9f850..ed23ddf 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk1808.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk1808.dtsi
@@ -385,7 +385,6 @@
 			snps,dis_u3_susphy_quirk;
 			snps,dis-del-phy-power-chg-quirk;
 			snps,tx-ipgap-linecheck-dis-quirk;
-			snps,xhci-trb-ent-quirk;
 			snps,parkmode-disable-hs-quirk;
 			snps,parkmode-disable-ss-quirk;
 			status = "disabled";
@@ -808,6 +807,7 @@
 	pwm0: pwm@ff3d0000 {
 		compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff3d0000 0x0 0x10>;
+		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm0_pin>;
@@ -819,6 +819,7 @@
 	pwm1: pwm@ff3d0010 {
 		compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff3d0010 0x0 0x10>;
+		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm1_pin>;
@@ -830,6 +831,7 @@
 	pwm2: pwm@ff3d0020 {
 		compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff3d0020 0x0 0x10>;
+		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm2_pin>;
@@ -841,6 +843,8 @@
 	pwm3: pwm@ff3d0030 {
 		compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff3d0030 0x0 0x10>;
+		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm3_pin>;
@@ -852,6 +856,7 @@
 	pwm4: pwm@ff3d8000 {
 		compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff3d8000 0x0 0x10>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm4_pin>;
@@ -863,6 +868,7 @@
 	pwm5: pwm@ff3d8010 {
 		compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff3d8010 0x0 0x10>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm5_pin>;
@@ -874,6 +880,7 @@
 	pwm6: pwm@ff3d8020 {
 		compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff3d8020 0x0 0x10>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm6_pin>;
@@ -885,6 +892,8 @@
 	pwm7: pwm@ff3d8030 {
 		compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff3d8030 0x0 0x10>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm7_pin>;
@@ -1213,6 +1222,7 @@
 	pwm8: pwm@ff5d0000 {
 		compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff5d0000 0x0 0x10>;
+		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm8_pin>;
@@ -1224,6 +1234,7 @@
 	pwm9: pwm@fff5d0010 {
 		compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff5d0010 0x0 0x10>;
+		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm9_pin>;
@@ -1235,6 +1246,7 @@
 	pwm10: pwm@ff5d0020 {
 		compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff5d0020 0x0 0x10>;
+		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm10_pin>;
@@ -1246,6 +1258,8 @@
 	pwm11: pwm@ff5d0030 {
 		compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xff5d0030 0x0 0x10>;
+		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm11_pin>;
@@ -1701,7 +1715,7 @@
 		reg = <0x0 0xffc60000 0x0 0x4000>;
 		clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
 			 <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
-		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		max-frequency = <150000000>;
 		fifo-depth = <0x100>;
 		interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
@@ -1798,7 +1812,7 @@
 		reg = <0x0 0xffcf0000 0x0 0x4000>;
 		clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
 			 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
-		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		max-frequency = <150000000>;
 		fifo-depth = <0x100>;
 		interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
@@ -1812,7 +1826,7 @@
 		reg = <0x0 0xffd00000 0x0 0x4000>;
 		clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
 			 <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
-		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		max-frequency = <150000000>;
 		fifo-depth = <0x100>;
 		interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3308-evb-audio-amic-v10.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3308-evb-audio-amic-v10.dts
new file mode 100644
index 0000000..1f4ad4f
--- /dev/null
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3308-evb-audio-amic-v10.dts
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd
+ */
+
+/dts-v1/;
+
+#include "rk3308-evb-audio-v10.dtsi"
+
+/ {
+	model = "Rockchip RK3308 evb audio analog mic v10 board";
+	compatible = "rockchip,rk3308-evb-audio-amic-v10", "rockchip,rk3308";
+
+	vad_acodec_sound: vad-acodec-sound {
+		status = "okay";
+		compatible = "rockchip,multicodecs-card";
+		rockchip,card-name = "rockchip,rk3308-vad";
+		rockchip,codec-hp-det;
+		rockchip,mclk-fs = <256>;
+		rockchip,cpu = <&i2s_8ch_2>;
+		rockchip,codec = <&acodec>, <&vad>;
+	};
+};
+
+&acodec {
+	rockchip,micbias1;
+	rockchip,micbias2;
+	rockchip,en-always-grps = <1 2 3>;
+	rockchip,adc-grps-route = <1 2 3 0>;
+};
+
+&acodec_sound {
+	status = "disabled";
+};
+
+&bluetooth_sound {
+	status = "okay";
+};
+
+&i2s_2ch_0 {
+	status = "okay";
+	#sound-dai-cells = <0>;
+};
+
+&vad {
+	status = "okay";
+	rockchip,audio-src = <&i2s_8ch_2>;
+	rockchip,det-channel = <0>;
+	rockchip,buffer-time-ms = <200>;
+	rockchip,mode = <1>;
+	#sound-dai-cells = <0>;
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3308-evb-audio-v10-display-rgb.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3308-evb-audio-v10-display-rgb.dts
new file mode 100644
index 0000000..0a44477
--- /dev/null
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3308-evb-audio-v10-display-rgb.dts
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Rockchip Electronics Co., Ltd
+ */
+
+/dts-v1/;
+
+#include "rk3308-evb-audio-amic-v10.dts"
+
+/ {
+	model = "Rockchip RK3308B EVB AUDIO DDR3 V10 Board + Rockchip RK3308 RGB ExtBoard V10";
+	compatible = "rockchip,rk3308-evb-audio-rgb-display-v10", "rockchip,rk3308";
+
+	backlight: backlight {
+		status = "okay";
+		compatible = "pwm-backlight";
+		pwms = <&pwm1 0 25000 0>;
+		brightness-levels = <
+			  0   1   2   3   4   5   6   7
+			  8   9  10  11  12  13  14  15
+			 16  17  18  19  20  21  22  23
+			 24  25  26  27  28  29  30  31
+			 32  33  34  35  36  37  38  39
+			 40  41  42  43  44  45  46  47
+			 48  49  50  51  52  53  54  55
+			 56  57  58  59  60  61  62  63
+			 64  65  66  67  68  69  70  71
+			 72  73  74  75  76  77  78  79
+			 80  81  82  83  84  85  86  87
+			 88  89  90  91  92  93  94  95
+			 96  97  98  99 100 101 102 103
+			104 105 106 107 108 109 110 111
+			112 113 114 115 116 117 118 119
+			120 121 122 123 124 125 126 127
+			128 129 130 131 132 133 134 135
+			136 137 138 139 140 141 142 143
+			144 145 146 147 148 149 150 151
+			152 153 154 155 156 157 158 159
+			160 161 162 163 164 165 166 167
+			168 169 170 171 172 173 174 175
+			176 177 178 179 180 181 182 183
+			184 185 186 187 188 189 190 191
+			192 193 194 195 196 197 198 199
+			200 201 202 203 204 205 206 207
+			208 209 210 211 212 213 214 215
+			216 217 218 219 220 221 222 223
+			224 225 226 227 228 229 230 231
+			232 233 234 235 236 237 238 239
+			240 241 242 243 244 245 246 247
+			248 249 250 251 252 253 254 255>;
+		default-brightness-level = <200>;
+	};
+
+	panel: panel {
+		compatible = "simple-panel";
+		bus-format = <MEDIA_BUS_FMT_RGB666_1X18>;
+		backlight = <&backlight>;
+		enable-gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_LOW>;
+		enable-delay-ms = <20>;
+		reset-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
+		reset-value = <0>;
+		reset-delay-ms = <10>;
+		status = "okay";
+
+		display-timings {
+			native-mode = <&fx070_dhm11boe_timing>;
+
+			fx070_dhm11boe_timing: timing0 {
+				clock-frequency = <50000000>;
+				hactive = <1024>;
+				vactive = <600>;
+				hback-porch = <140>;
+				hfront-porch = <160>;
+				vback-porch = <20>;
+				vfront-porch = <20>;
+				hsync-len = <20>;
+				vsync-len = <2>; //value range <2~22>
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <0>;
+				pixelclk-active = <1>;
+			};
+		};
+
+		port {
+			panel_in_rgb: endpoint {
+				remote-endpoint = <&rgb_out_panel>;
+			};
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x0 0x1000000>;
+			linux,cma-default;
+		};
+	};
+};
+
+&display_subsystem {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+	gt9xx: gt9xx@14 {
+		compatible = "goodix,gt9xx";
+		reg = <0x14>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&tp_int>;
+		touch-gpio = <&gpio0 RK_PA6 IRQ_TYPE_LEVEL_HIGH>;
+		reset-gpio = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
+		max-x = <1024>;
+		max-y = <600>;
+		tp-size = <9110>;
+	};
+};
+
+&pwm1 {
+	status = "okay";
+};
+
+&rgb {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&lcdc_ctl>;
+
+	ports {
+		rgb_out: port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			rgb_out_panel: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&panel_in_rgb>;
+			};
+		};
+	};
+};
+
+&route_rgb {
+	status = "okay";
+};
+
+&vop {
+	status = "okay";
+};
+
+&pinctrl {
+	tp {
+		tp_int: tp-int {
+			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3308-evb-audio-v10.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3308-evb-audio-v10.dtsi
new file mode 100644
index 0000000..28f5aff
--- /dev/null
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3308-evb-audio-v10.dtsi
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd
+ */
+
+#include <dt-bindings/input/input.h>
+#include "rk3308-evb-v11.dtsi"
+
+/ {
+	/delete-node/ wireless-wlan;
+	/delete-node/ wireless-bluetooth;
+	/delete-node/ gpio-keys;
+
+	wireless-wlan {
+		compatible = "wlan-platdata";
+		rockchip,grf = <&grf>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_wake_host>, <&rtc_32k>;
+		wifi_chip_type = "ap6256";
+		WIFI,host_wake_irq = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
+		status = "okay";
+	};
+
+	wireless-bluetooth {
+		compatible = "bluetooth-platdata";
+		uart_rts_gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default", "rts_gpio";
+		pinctrl-0 = <&uart4_rts>;
+		pinctrl-1 = <&uart4_rts_pin>;
+		BT,power_gpio    = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+		BT,wake_host_irq = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>;
+		status = "okay";
+	};
+};
+
+&acodec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hp_det>;
+};
+
+&emmc {
+	status = "okay";
+};
+
+&pinctrl {
+	acodec {
+		hp_det: hp-det {
+			rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_input_high>;
+		};
+	};
+};
+
+&sfc {
+	status = "okay";
+};
+
+&vccio_sd {
+	gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_HIGH>;
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3308b-amp.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3308b-amp.dtsi
index 9b7ec98..5a4548d 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3308b-amp.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3308b-amp.dtsi
@@ -14,8 +14,9 @@
 		pinctrl-names = "default";
 		pinctrl-0 = <&uart1_xfer>;
 		status = "okay";
-		amp-cpu-aff-maskbits = <0x0 0x1 0x1 0x2 0x2 0x4 0x3 0x8>;
-		amp-irqs = <GIC_AMP_IRQ_CFG_ROUTE(51, 0xd0, CPU_GET_AFFINITY(3, 0))>;
+		amp-cpu-aff-maskbits = /bits/ 64 <0x0 0x1 0x1 0x2 0x2 0x4 0x3 0x8>;
+		amp-irqs = /bits/ 64 <GIC_AMP_IRQ_CFG_ROUTE(51, 0xd0, CPU_GET_AFFINITY(3, 0))
+				      GIC_AMP_IRQ_CFG_ROUTE(132, 0xd0, CPU_GET_AFFINITY(3, 0))>;
 	};
 
 	reserved-memory {
@@ -28,6 +29,29 @@
 			reg = <0x0 0x2e00000 0x0 0x1200000>;
 			no-map;
 		};
+
+		rpmsg_reserved: rpmsg@7c00000 {
+			reg = <0x0 0x07c00000 0x0 0x400000>;
+			no-map;
+		};
+
+		rpmsg_dma_reserved: rpmsg-dma@8000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x0 0x08000000 0x0 0x100000>;
+			no-map;
+		};
+	};
+
+	rpmsg: rpmsg@7c00000 {
+		compatible = "rockchip,rpmsg-softirq";
+		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+		rockchip,vdev-nums = <1>;
+		rockchip,link-id = <0x03>;
+		reg = <0x0 0x7c00000 0x0 0x20000>;
+		memory-region = <&rpmsg_dma_reserved>;
+
+		status = "okay";
 	};
 };
 
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3326-863-lp3-v10-rkisp1.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3326-863-lp3-v10-rkisp1.dts
index d80dad6..2d0fa8a 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3326-863-lp3-v10-rkisp1.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3326-863-lp3-v10-rkisp1.dts
@@ -11,10 +11,6 @@
 	compatible = "rockchip,rk3326-863-lp3-v10-rkisp1", "rockchip,rk3326";
 };
 
-&chosen {
-	bootargs_ext = "androidboot.boot_devices=ff390000.dwmmc,ff3b0000.nandc";
-};
-
 &i2c2 {
 	status = "okay";
 
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v10.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v10.dts
index 5a468b6..0c1df28 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v10.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v10.dts
@@ -130,7 +130,7 @@
 	bt-sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "dsp_a";
-		simple-audio-card,bitclock-inversion = <1>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <256>;
 		simple-audio-card,name = "rockchip,bt";
 		simple-audio-card,cpu {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11-i2s-dmic.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11-i2s-dmic.dts
index 38a5c92..6e8f284 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11-i2s-dmic.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11-i2s-dmic.dts
@@ -140,7 +140,7 @@
 		compatible = "simple-audio-card";
 		status = "disabled";
 		simple-audio-card,format = "dsp_a";
-		simple-audio-card,bitclock-inversion = <1>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <256>;
 		simple-audio-card,name = "rockchip,bt";
 		simple-audio-card,cpu {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11.dts
index e098f19..f7af4fc 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11.dts
@@ -130,7 +130,7 @@
 	bt-sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "dsp_a";
-		simple-audio-card,bitclock-inversion = <1>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <256>;
 		simple-audio-card,name = "rockchip,bt";
 		simple-audio-card,cpu {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v12.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v12.dts
index 1d4b811..71024a9 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v12.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v12.dts
@@ -130,7 +130,7 @@
 	bt-sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "dsp_a";
-		simple-audio-card,bitclock-inversion = <1>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <256>;
 		simple-audio-card,name = "rockchip,bt";
 		simple-audio-card,cpu {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-lp3-v10.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-lp3-v10.dtsi
index 676062d..5b9eaf4 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-lp3-v10.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3326-evb-lp3-v10.dtsi
@@ -18,14 +18,14 @@
 		keyup-threshold-microvolt = <1800000>;
 
 		esc-key {
-			linux,code = <KEY_ESC>;
-			label = "esc";
+			linux,code = <KEY_BACK>;
+			label = "back";
 			press-threshold-microvolt = <1310000>;
 		};
 
 		home-key {
-			linux,code = <KEY_HOME>;
-			label = "home";
+			linux,code = <KEY_HOMEPAGE>;
+			label = "homepage";
 			press-threshold-microvolt = <624000>;
 		};
 
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3328-evb.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
index 82d2f01..468a9ae 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
@@ -5,13 +5,46 @@
 
 /dts-v1/;
 #include "rk3328.dtsi"
+#include <dt-bindings/input/input.h>
 
 / {
 	model = "Rockchip RK3328 EVB";
 	compatible = "rockchip,rk3328-evb", "rockchip,rk3328";
 
 	chosen {
-		stdout-path = "serial2:1500000n8";
+		bootargs = "earlycon=uart8250,mmio32,0xff130000 swiotlb=1 kpti=0 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rw rootwait coherent_pool=1m";
+	};
+
+	fiq-debugger {
+		compatible = "rockchip,fiq-debugger";
+		rockchip,serial-id = <2>;
+		rockchip,signal-irq = <159>;
+		rockchip,wake-irq = <0>;
+		/* If enable uart uses irq instead of fiq */
+		rockchip,irq-mode-enable = <1>;
+		rockchip,baudrate = <1500000>;  /* Only 115200 and 1500000 */
+		interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>;
+		status = "okay";
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		drm_logo: drm-logo@00000000 {
+			compatible = "rockchip,drm-logo";
+			reg = <0x0 0x0 0x0 0x0>;
+		};
+
+		ramoops: ramoops@110000 {
+			compatible = "ramoops";
+			reg = <0x0 0x110000 0x0 0xf0000>;
+			record-size = <0x20000>;
+			console-size = <0x80000>;
+			ftrace-size = <0x00000>;
+			pmsg-size = <0x50000>;
+		};
 	};
 
 	dc_12v: dc-12v {
@@ -37,16 +70,22 @@
 		reset-gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
 	};
 
-	fiq-debugger {
-		compatible = "rockchip,fiq-debugger";
-		rockchip,serial-id = <2>;
-		rockchip,signal-irq = <159>;
-		rockchip,wake-irq = <0>;
-		/* If enable uart uses irq instead of fiq */
-		rockchip,irq-mode-enable = <0>;
-		rockchip,baudrate = <1500000>;  /* Only 115200 and 1500000 */
-		interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>;
-		status = "okay";
+	vcc_host_vbus: host-vbus-regulator {
+		compatible = "regulator-fixed";
+		gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&host_vbus_drv>;
+		regulator-name = "vcc_host_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+	};
+
+	vcc_phy: vcc-phy-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_phy";
+		regulator-always-on;
+		regulator-boot-on;
 	};
 
 	vcc_sd: sdmmc-regulator {
@@ -70,54 +109,129 @@
 		vin-supply = <&dc_12v>;
 	};
 
-	vcc_phy: vcc-phy-regulator {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_phy";
-		regulator-always-on;
-		regulator-boot-on;
+	wireless-bluetooth {
+		compatible = "bluetooth-platdata";
+		clocks = <&rk805 1>;
+		clock-names = "ext_clock";
+		uart_rts_gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default", "rts_gpio";
+		pinctrl-0 = <&uart0_rts>;
+		pinctrl-1 = <&uart0_gpios>;
+		BT,power_gpio = <&gpio1 21 GPIO_ACTIVE_HIGH>;
+		BT,wake_host_irq = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+		status = "okay";
 	};
 
-	xin32k: xin32k {
-		compatible = "fixed-clock";
-		clock-frequency = <32768>;
-		clock-output-names = "xin32k";
-		#clock-cells = <0>;
+	wireless-wlan {
+		compatible = "wlan-platdata";
+		rockchip,grf = <&grf>;
+		wifi_chip_type = "ap6354";
+		sdio_vref = <1800>;
+		WIFI,host_wake_irq = <&gpio1 19 GPIO_ACTIVE_HIGH>;
+		status = "okay";
 	};
+};
 
+&avsd {
+	status = "okay";
+};
+
+&cif {
+	status = "disabled";
+};
+
+&codec {
+	mute-gpios = <&grf_gpio 0 GPIO_ACTIVE_LOW>;
+	#sound-dai-cells = <0>;
+	status = "okay";
 };
 
 &cpu0 {
 	cpu-supply = <&vdd_arm>;
 };
 
-&cpu1 {
-	cpu-supply = <&vdd_arm>;
+&dfi {
+	status = "okay";
 };
 
-&cpu2 {
-	cpu-supply = <&vdd_arm>;
+&display_subsystem {
+	logo-memory-region = <&drm_logo>;
+	status = "okay";
+
+	route {
+		route_hdmi: route-hdmi {
+			status = "okay";
+			logo,uboot = "logo.bmp";
+			logo,kernel = "logo_kernel.bmp";
+			logo,mode = "fullscreen";
+			charge_logo,mode = "fullscreen";
+			connect = <&vop_out_hdmi>;
+		};
+	};
 };
 
-&cpu3 {
-	cpu-supply = <&vdd_arm>;
+&dmc {
+	center-supply = <&vdd_logic>;
+	status = "okay";
 };
 
 &emmc {
 	bus-width = <8>;
 	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	supports-emmc;
+	disable-wp;
 	non-removable;
+	num-slots = <1>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
 	status = "okay";
 };
 
+&gmac2io {
+	phy-supply = <&vcc_phy>;
+	phy-mode = "rgmii";
+	clock_in_out = "input";
+	snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 10000 50000>;
+	assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>;
+	assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmiim1_pins>;
+	tx_delay = <0x26>;
+	rx_delay = <0x11>;
+	status = "disabled";
+};
+
 &gmac2phy {
 	phy-supply = <&vcc_phy>;
 	clock_in_out = "output";
+	assigned-clocks = <&cru SCLK_MAC2PHY_SRC>;
 	assigned-clock-rate = <50000000>;
 	assigned-clocks = <&cru SCLK_MAC2PHY>;
 	assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>;
 	status = "okay";
+};
+
+&gpu {
+	mali-supply = <&vdd_logic>;
+	status = "okay";
+};
+
+&hdmi {
+	#sound-dai-cells = <0>;
+	ddc-i2c-scl-high-time-ns = <9625>;
+	ddc-i2c-scl-low-time-ns = <10000>;
+	status = "okay";
+};
+
+&hdmiphy {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "disabled";
 };
 
 &i2c1 {
@@ -136,13 +250,26 @@
 		pinctrl-0 = <&pmic_int_l>;
 		rockchip,system-power-controller;
 		wakeup-source;
+		status = "okay";
 
 		vcc1-supply = <&vcc_sys>;
 		vcc2-supply = <&vcc_sys>;
 		vcc3-supply = <&vcc_sys>;
 		vcc4-supply = <&vcc_sys>;
 		vcc5-supply = <&vcc_io>;
-		vcc6-supply = <&vcc_io>;
+		vcc6-supply = <&vcc_sys>;
+
+		rtc {
+			status = "okay";
+		};
+
+		pwrkey {
+			status = "okay";
+		};
+
+		gpio {
+			status = "okay";
+		};
 
 		regulators {
 			vdd_logic: DCDC_REG1 {
@@ -229,6 +356,33 @@
 	};
 };
 
+&i2s0 {
+	#sound-dai-cells = <0>;
+	rockchip,bclk-fs = <128>;
+	status = "okay";
+};
+
+&i2s1 {
+	#sound-dai-cells = <0>;
+	status = "okay";
+};
+
+&io_domains {
+	status = "okay";
+
+	vccio1-supply = <&vcc_io>;
+	vccio2-supply = <&vcc18_emmc>;
+	vccio3-supply = <&vcc_io>;
+	vccio4-supply = <&vcc_18>;
+	vccio5-supply = <&vcc_io>;
+	vccio6-supply = <&vcc_io>;
+	pmuio-supply = <&vcc_io>;
+};
+
+&mpp_srv {
+	status = "okay";
+};
+
 &pinctrl {
 	pmic {
 		pmic_int_l: pmic-int-l {
@@ -238,10 +392,147 @@
 
 	sdio-pwrseq {
 		wifi_enable_h: wifi-enable-h {
-		rockchip,pins =
-			<1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+			rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 	};
+
+	usb {
+		host_vbus_drv: host-vbus-drv {
+			rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		otg_vbus_drv: otg-vbus-drv {
+			rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	wireless-bluetooth {
+		uart0_gpios: uart0-gpios {
+			rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pwm3 {
+	status = "okay";
+	compatible = "rockchip,remotectl-pwm";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwmir_pin>;
+	remote_pwm_id = <3>;
+	handle_cpu_id = <1>;
+	remote_support_psci = <1>;
+
+	ir_key1 {
+		rockchip,usercode = <0x4040>;
+		rockchip,key_table =
+			<0xf2	KEY_REPLY>,
+			<0xba	KEY_BACK>,
+			<0xf4	KEY_UP>,
+			<0xf1	KEY_DOWN>,
+			<0xef	KEY_LEFT>,
+			<0xee	KEY_RIGHT>,
+			<0xbd	KEY_HOME>,
+			<0xea	KEY_VOLUMEUP>,
+			<0xe3	KEY_VOLUMEDOWN>,
+			<0xe2	KEY_SEARCH>,
+			<0xb2	KEY_POWER>,
+			<0xbc	KEY_MUTE>,
+			<0xec	KEY_MENU>,
+			<0xbf	0x190>,
+			<0xe0	0x191>,
+			<0xe1	0x192>,
+			<0xe9	183>,
+			<0xe6	248>,
+			<0xe8	185>,
+			<0xe7	186>,
+			<0xf0	388>,
+			<0xbe	0x175>;
+	};
+
+	ir_key2 {
+		rockchip,usercode = <0xff00>;
+		rockchip,key_table =
+			<0x39	KEY_POWER>,
+			<0x73	KEY_MUTE>,
+			<0xa4	KEY_PLAYPAUSE>,
+			<0x75	KEY_VOLUMEDOWN>,
+			<0x77	KEY_VOLUMEUP>,
+			<0x7d	KEY_MENU>,
+			<0xf9	KEY_HOME>,
+			<0x5f	KEY_BACK>,
+			<0xb9	KEY_UP>,
+			<0xe9	KEY_DOWN>,
+			<0xb8	KEY_LEFT>,
+			<0xea	KEY_RIGHT>,
+			<0xaa	KEY_REPLY>,
+			<0x55	KEY_1>,
+			<0x5b	KEY_2>,
+			<0xf8	KEY_3>,
+			<0x57	KEY_4>,
+			<0xed	KEY_5>,
+			<0xee	KEY_6>,
+			<0x59	KEY_7>,
+			<0xf1	KEY_8>,
+			<0xf2	KEY_9>,
+			<0xe0	KEY_BACKSPACE>,
+			<0x79	KEY_0>,
+			<0xa4	KEY_SETUP>;
+	};
+
+	ir_key3 {
+		rockchip,usercode = <0x1dcc>;
+		rockchip,key_table =
+			<0xee	KEY_REPLY>,
+			<0xf0	KEY_BACK>,
+			<0xf8	KEY_UP>,
+			<0xbb	KEY_DOWN>,
+			<0xef	KEY_LEFT>,
+			<0xed	KEY_RIGHT>,
+			<0xfc	KEY_HOME>,
+			<0xf1	KEY_VOLUMEUP>,
+			<0xfd	KEY_VOLUMEDOWN>,
+			<0xb7	KEY_SEARCH>,
+			<0xff	KEY_POWER>,
+			<0xf3	KEY_MUTE>,
+			<0xbf	KEY_MENU>,
+			<0xf9	0x191>,
+			<0xf5	0x192>,
+			<0xb3	388>,
+			<0xbe	KEY_1>,
+			<0xba	KEY_2>,
+			<0xb2	KEY_3>,
+			<0xbd	KEY_4>,
+			<0xf9	KEY_5>,
+			<0xb1	KEY_6>,
+			<0xfc	KEY_7>,
+			<0xf8	KEY_8>,
+			<0xb0	KEY_9>,
+			<0xb6	KEY_0>,
+			<0xb5	KEY_BACKSPACE>;
+	};
+};
+
+&rga {
+	status = "okay";
+};
+
+&rkvdec {
+	vcodec-supply = <&vdd_logic>;
+	status = "okay";
+};
+
+&rkvdec_mmu {
+	status = "okay";
+};
+
+&rockchip_suspend {
+	rockchip,virtual-poweroff = <1>;
+	status = "okay";
+};
+
+&saradc {
+	vref-supply = <&vcc_18>;
+	status = "okay";
 };
 
 &sdio {
@@ -254,6 +545,8 @@
 	non-removable;
 	pinctrl-names = "default";
 	pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>;
+	no-mmc;
+	no-sd;
 	status = "okay";
 };
 
@@ -265,15 +558,17 @@
 	max-frequency = <150000000>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>;
+	no-sdio;
+	no-mmc;
 	vmmc-supply = <&vcc_sd>;
 	status = "okay";
 };
 
-&tsadc {
+&spdif {
 	status = "okay";
 };
 
-&uart2 {
+&tsadc {
 	status = "okay";
 };
 
@@ -289,6 +584,25 @@
 	status = "okay";
 };
 
+&u3phy {
+	vbus-supply = <&vcc_host_vbus>;
+	status = "okay";
+};
+
+&u3phy_pipe {
+	status = "okay";
+};
+
+&u3phy_utmi {
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_xfer &uart0_cts>;
+	status = "okay";
+};
+
 &usb20_otg {
 	status = "okay";
 };
@@ -300,3 +614,35 @@
 &usb_host0_ohci {
 	status = "okay";
 };
+
+&usbdrd3 {
+	status = "okay";
+};
+
+&usbdrd_dwc3 {
+	status = "okay";
+};
+
+&vdpu {
+	status = "okay";
+};
+
+&vpu_mmu {
+	status = "okay";
+};
+
+&vepu {
+	status = "okay";
+};
+
+&vepu_mmu {
+	status = "okay";
+};
+
+&vop {
+	status = "okay";
+};
+
+&vop_mmu {
+	status = "okay";
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
index daa9a0c..22ab5e1 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
@@ -91,7 +91,6 @@
 			linux,default-trigger = "heartbeat";
 			gpios = <&rk805 1 GPIO_ACTIVE_LOW>;
 			default-state = "on";
-			mode = <0x23>;
 		};
 
 		user_led: led-1 {
@@ -99,7 +98,6 @@
 			linux,default-trigger = "mmc1";
 			gpios = <&rk805 0 GPIO_ACTIVE_LOW>;
 			default-state = "off";
-			mode = <0x05>;
 		};
 	};
 };
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 0a8357f..7dcf177 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -10,7 +10,10 @@
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/power/rk3328-power.h>
 #include <dt-bindings/soc/rockchip,boot-mode.h>
+#include <dt-bindings/soc/rockchip-system-status.h>
+#include <dt-bindings/suspend/rockchip-rk3328.h>
 #include <dt-bindings/thermal/thermal.h>
+#include "rk3328-dram-default-timing.dtsi"
 
 / {
 	compatible = "rockchip,rk3328";
@@ -20,19 +23,19 @@
 	#size-cells = <2>;
 
 	aliases {
+		ethernet0 = &gmac2io;
+		ethernet1 = &gmac2phy;
 		gpio0 = &gpio0;
 		gpio1 = &gpio1;
 		gpio2 = &gpio2;
 		gpio3 = &gpio3;
-		serial0 = &uart0;
-		serial1 = &uart1;
-		serial2 = &uart2;
 		i2c0 = &i2c0;
 		i2c1 = &i2c1;
 		i2c2 = &i2c2;
 		i2c3 = &i2c3;
-		ethernet0 = &gmac2io;
-		ethernet1 = &gmac2phy;
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
 	};
 
 	cpus {
@@ -109,58 +112,144 @@
 		};
 	};
 
-	cpu0_opp_table: opp_table0 {
+	cpu0_opp_table: cpu0-opp-table {
 		compatible = "operating-points-v2";
 		opp-shared;
 
+		rockchip,video-4k-freq = <1008000>;
+
+		rockchip,leakage-voltage-sel = <
+			1   10    0
+			11  254   1
+		>;
+		nvmem-cells = <&cpu_leakage>;
+		nvmem-cell-names = "cpu_leakage";
+
 		opp-408000000 {
 			opp-hz = /bits/ 64 <408000000>;
-			opp-microvolt = <950000>;
+			opp-microvolt = <950000 950000 1350000>;
+			opp-microvolt-L0 = <950000 950000 1350000>;
+			opp-microvolt-L1 = <950000 950000 1350000>;
 			clock-latency-ns = <40000>;
 			opp-suspend;
 		};
 		opp-600000000 {
 			opp-hz = /bits/ 64 <600000000>;
-			opp-microvolt = <950000>;
+			opp-microvolt = <950000 950000 1350000>;
+			opp-microvolt-L0 = <950000 950000 1350000>;
+			opp-microvolt-L1 = <950000 950000 1350000>;
 			clock-latency-ns = <40000>;
 		};
 		opp-816000000 {
 			opp-hz = /bits/ 64 <816000000>;
-			opp-microvolt = <1000000>;
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-microvolt-L0 = <1050000 1050000 1350000>;
+			opp-microvolt-L1 = <1000000 1000000 1350000>;
 			clock-latency-ns = <40000>;
 		};
 		opp-1008000000 {
 			opp-hz = /bits/ 64 <1008000000>;
-			opp-microvolt = <1100000>;
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-microvolt-L0 = <1150000 1150000 1350000>;
+			opp-microvolt-L1 = <1100000 1100000 1350000>;
 			clock-latency-ns = <40000>;
 		};
 		opp-1200000000 {
 			opp-hz = /bits/ 64 <1200000000>;
-			opp-microvolt = <1225000>;
+			opp-microvolt = <1275000 1275000 1350000>;
+			opp-microvolt-L0 = <1275000 1275000 1350000>;
+			opp-microvolt-L1 = <1225000 1225000 1350000>;
 			clock-latency-ns = <40000>;
 		};
 		opp-1296000000 {
 			opp-hz = /bits/ 64 <1296000000>;
-			opp-microvolt = <1300000>;
+			opp-microvolt = <1350000 1350000 1350000>;
+			opp-microvolt-L0 = <1350000 1350000 1350000>;
+			opp-microvolt-L1 = <1300000 1300000 1350000>;
 			clock-latency-ns = <40000>;
 		};
 	};
 
-	amba: bus {
-		compatible = "simple-bus";
-		#address-cells = <2>;
-		#size-cells = <2>;
-		ranges;
+	dmc: dmc {
+		compatible = "rockchip,rk3328-dmc";
+		devfreq-events = <&dfi>;
+		clocks = <&cru SCLK_DDRCLK>;
+		clock-names = "dmc_clk";
+		operating-points-v2 = <&dmc_opp_table>;
+		ddr_timing = <&ddr_timing>;
+		upthreshold = <40>;
+		downdifferential = <20>;
+		system-status-freq = <
+			/*system status         freq(KHz)*/
+			SYS_STATUS_NORMAL       786000
+			SYS_STATUS_REBOOT       786000
+			SYS_STATUS_SUSPEND      786000
+			SYS_STATUS_VIDEO_1080P  786000
+			SYS_STATUS_VIDEO_4K     786000
+			SYS_STATUS_VIDEO_4K_10B 924000
+			SYS_STATUS_PERFORMANCE  924000
+			SYS_STATUS_BOOST        924000
+		>;
+		auto-min-freq = <786000>;
+		auto-freq-en = <0>;
+		#cooling-cells = <2>;
+		status = "disabled";
+	};
 
-		dmac: dmac@ff1f0000 {
-			compatible = "arm,pl330", "arm,primecell";
-			reg = <0x0 0xff1f0000 0x0 0x4000>;
-			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
-			arm,pl330-periph-burst;
-			clocks = <&cru ACLK_DMAC>;
-			clock-names = "apb_pclk";
-			#dma-cells = <1>;
+	dmc_opp_table: dmc-opp-table {
+		compatible = "operating-points-v2";
+		rockchip,leakage-voltage-sel = <
+			1   10    0
+			11  254   1
+		>;
+		nvmem-cells = <&logic_leakage>;
+		nvmem-cell-names = "ddr_leakage";
+
+		opp-400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-microvolt = <950000>;
+			opp-microvolt-L0 = <950000>;
+			opp-microvolt-L1 = <950000>;
+			status = "disabled";
+		};
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <1025000>;
+			opp-microvolt-L0 = <1025000>;
+			opp-microvolt-L1 = <1000000>;
+			status = "disabled";
+		};
+		opp-786000000 {
+			opp-hz = /bits/ 64 <786000000>;
+			opp-microvolt = <1075000>;
+			opp-microvolt-L0 = <1075000>;
+			opp-microvolt-L1 = <1050000>;
+		};
+		opp-798000000 {
+			opp-hz = /bits/ 64 <798000000>;
+			opp-microvolt = <1075000>;
+			opp-microvolt-L0 = <1075000>;
+			opp-microvolt-L1 = <1050000>;
+		};
+		opp-840000000 {
+			opp-hz = /bits/ 64 <840000000>;
+			opp-microvolt = <1075000>;
+			opp-microvolt-L0 = <1075000>;
+			opp-microvolt-L1 = <1050000>;
+		};
+		opp-924000000 {
+			opp-hz = /bits/ 64 <924000000>;
+			opp-microvolt = <1125000>;
+			opp-microvolt-L0 = <1125000>;
+			opp-microvolt-L1 = <1100000>;
+		};
+		/* 1056M is only for ddr4 */
+		opp-1056000000 {
+			opp-hz = /bits/ 64 <1056000000>;
+			opp-microvolt = <1175000>;
+			opp-microvolt-L0 = <1175000>;
+			opp-microvolt-L1 = <1150000>;
+			status = "disabled";
 		};
 	};
 
@@ -168,8 +257,7 @@
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "i2s";
 		simple-audio-card,mclk-fs = <256>;
-		simple-audio-card,name = "Analog";
-		status = "disabled";
+		simple-audio-card,name = "rockchip,rk3328";
 
 		simple-audio-card,cpu {
 			sound-dai = <&i2s1>;
@@ -189,17 +277,37 @@
 		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
 	};
 
+	cpuinfo {
+		compatible = "rockchip,cpuinfo";
+		nvmem-cells = <&efuse_id>, <&efuse_cpu_version>;
+		nvmem-cell-names = "id", "cpu-version";
+	};
+
 	display_subsystem: display-subsystem {
 		compatible = "rockchip,display-subsystem";
 		ports = <&vop_out>;
+		status = "disabled";
+	};
+
+	firmware {
+		optee {
+			compatible = "linaro,optee-tz";
+			method = "smc";
+		};
+	};
+
+	gmac_clkin: external-gmac-clock {
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+		clock-output-names = "gmac_clkin";
+		#clock-cells = <0>;
 	};
 
 	hdmi_sound: hdmi-sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "i2s";
 		simple-audio-card,mclk-fs = <128>;
-		simple-audio-card,name = "HDMI";
-		status = "disabled";
+		simple-audio-card,name = "rockchip,hdmi";
 
 		simple-audio-card,cpu {
 			sound-dai = <&i2s0>;
@@ -213,6 +321,38 @@
 	psci {
 		compatible = "arm,psci-1.0", "arm,psci-0.2";
 		method = "smc";
+	};
+
+	rockchip_suspend: rockchip-suspend {
+		compatible = "rockchip,pm-rk3328";
+		rockchip,sleep-mode-config = <0>;
+		rockchip,virtual-poweroff = <0>;
+		status = "disabled";
+	};
+
+	rockchip_system_monitor: rockchip-system-monitor {
+		compatible = "rockchip,system-monitor";
+		rockchip,thermal-zone = "soc-thermal";
+		rockchip,polling-delay = <200>; /* milliseconds */
+		rockchip,video-4k-offline-cpus = "3";
+	};
+
+	spdif_out: spdif-out {
+		compatible = "linux,spdif-dit";
+		#sound-dai-cells = <0>;
+	};
+
+	spdif_sound: spdif-sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "rockchip,spdif";
+
+		simple-audio-card,cpu {
+			sound-dai = <&spdif>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&spdif_out>;
+		};
 	};
 
 	timer {
@@ -230,6 +370,13 @@
 		clock-output-names = "xin24m";
 	};
 
+	xin32k: xin32k {
+		compatible = "fixed-clock";
+		clock-frequency = <32768>;
+		clock-output-names = "xin32k";
+		#clock-cells = <0>;
+	};
+
 	i2s0: i2s@ff000000 {
 		compatible = "rockchip,rk3328-i2s", "rockchip,rk3066-i2s";
 		reg = <0x0 0xff000000 0x0 0x1000>;
@@ -238,6 +385,8 @@
 		clock-names = "i2s_clk", "i2s_hclk";
 		dmas = <&dmac 11>, <&dmac 12>;
 		dma-names = "tx", "rx";
+		resets = <&cru SRST_I2S0>, <&cru SRST_I2S0_H>;
+		reset-names = "reset-m", "reset-h";
 		#sound-dai-cells = <0>;
 		status = "disabled";
 	};
@@ -250,6 +399,8 @@
 		clock-names = "i2s_clk", "i2s_hclk";
 		dmas = <&dmac 14>, <&dmac 15>;
 		dma-names = "tx", "rx";
+		resets = <&cru SRST_I2S1>, <&cru SRST_I2S1_H>;
+		reset-names = "reset-m", "reset-h";
 		#sound-dai-cells = <0>;
 		status = "disabled";
 	};
@@ -262,6 +413,16 @@
 		clock-names = "i2s_clk", "i2s_hclk";
 		dmas = <&dmac 0>, <&dmac 1>;
 		dma-names = "tx", "rx";
+		resets = <&cru SRST_I2S2>, <&cru SRST_I2S2_H>;
+		reset-names = "reset-m", "reset-h";
+		pinctrl-names = "default", "sleep";
+		pinctrl-0 = <&i2s2m0_mclk
+			     &i2s2m0_sclk
+			     &i2s2m0_lrcktx
+			     &i2s2m0_lrckrx
+			     &i2s2m0_sdo
+			     &i2s2m0_sdi>;
+		pinctrl-1 = <&i2s2m0_sleep>;
 		#sound-dai-cells = <0>;
 		status = "disabled";
 	};
@@ -275,7 +436,7 @@
 		dmas = <&dmac 10>;
 		dma-names = "tx";
 		pinctrl-names = "default";
-		pinctrl-0 = <&spdifm2_tx>;
+		pinctrl-0 = <&spdifm0_tx>;
 		#sound-dai-cells = <0>;
 		status = "disabled";
 	};
@@ -289,15 +450,52 @@
 		dma-names = "rx";
 		pinctrl-names = "default", "sleep";
 		pinctrl-0 = <&pdmm0_clk
+			     &pdmm0_fsync
 			     &pdmm0_sdi0
 			     &pdmm0_sdi1
 			     &pdmm0_sdi2
 			     &pdmm0_sdi3>;
 		pinctrl-1 = <&pdmm0_clk_sleep
+			     &pdmm0_fsync_sleep
 			     &pdmm0_sdi0_sleep
 			     &pdmm0_sdi1_sleep
 			     &pdmm0_sdi2_sleep
 			     &pdmm0_sdi3_sleep>;
+		status = "disabled";
+	};
+
+	tsp: tsp@ff050000 {
+		compatible = "rockchip,rk3328-tsp";
+		reg = <0x0 0xff050000 0x0 0x10000>;
+		rockchip,grf = <&grf>;
+		interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "irq_tsp";
+		clocks = <&cru SCLK_TSP>, <&cru ACLK_TSP>, <&cru HCLK_TSP>;
+		clock-names = "clk_tsp", "aclk_tsp", "hclk_tsp";
+		pinctrl-names = "default";
+		pinctrl-0 = <&tsp_d0
+			     &tsp_d1
+			     &tsp_d2
+			     &tsp_d3
+			     &tsp_d4
+			     &tsp_d5
+			     &tsp_d6
+			     &tsp_d7
+			     &tsp_sync
+			     &tsp_clk
+			     &tsp_fail
+			     &tsp_valid>;
+		status = "disabled";
+	};
+
+	rng: rng@ff060000 {
+		compatible = "rockchip,cryptov1-rng";
+		reg = <0x0 0xff060000 0x0 0x4000>;
+
+		clocks = <&cru SCLK_CRYPTO>, <&cru HCLK_CRYPTO_SLV>;
+		clock-names = "clk_crypto", "hclk_crypto";
+		assigned-clocks = <&cru SCLK_CRYPTO>, <&cru HCLK_CRYPTO_SLV>;
+		assigned-clock-rates = <150000000>, <100000000>;
 		status = "disabled";
 	};
 
@@ -321,26 +519,88 @@
 			#power-domain-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <0>;
+			status = "okay";
 
 			power-domain@RK3328_PD_HEVC {
 				reg = <RK3328_PD_HEVC>;
 			};
 			power-domain@RK3328_PD_VIDEO {
 				reg = <RK3328_PD_VIDEO>;
+				clocks = <&cru ACLK_RKVDEC>,
+					 <&cru HCLK_RKVDEC>,
+					 <&cru SCLK_VDEC_CABAC>,
+					 <&cru SCLK_VDEC_CORE>;
+				pm_qos = <&qos_rkvdec_r>, <&qos_rkvdec_w>;
 			};
 			power-domain@RK3328_PD_VPU {
 				reg = <RK3328_PD_VPU>;
-				clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+				clocks = <&cru ACLK_VPU>,
+					 <&cru HCLK_VPU>;
+				pm_qos = <&qos_vpu>;
 			};
 		};
 
-		reboot-mode {
+		reboot_mode: reboot-mode {
 			compatible = "syscon-reboot-mode";
 			offset = <0x5c8>;
+			mode-bootloader = <BOOT_BL_DOWNLOAD>;
+			mode-charge = <BOOT_CHARGING>;
+			mode-fastboot = <BOOT_FASTBOOT>;
+			mode-loader = <BOOT_BL_DOWNLOAD>;
 			mode-normal = <BOOT_NORMAL>;
 			mode-recovery = <BOOT_RECOVERY>;
-			mode-bootloader = <BOOT_FASTBOOT>;
-			mode-loader = <BOOT_BL_DOWNLOAD>;
+			mode-ums = <BOOT_UMS>;
+		};
+	};
+
+	thermal-zones {
+		soc_thermal: soc-thermal {
+			polling-delay-passive = <20>; /* milliseconds */
+			polling-delay = <1000>; /* milliseconds */
+			sustainable-power = <1000>; /* milliwatts */
+
+			thermal-sensors = <&tsadc 0>;
+
+			trips {
+				threshold: trip-point-0 {
+					temperature = <70000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "passive";
+				};
+				target: trip-point-1 {
+					temperature = <85000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "passive";
+				};
+				soc_crit: soc-crit {
+					temperature = <115000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&target>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					contribution = <4096>;
+				};
+				map1 {
+					trip = <&target>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					contribution = <4096>;
+				};
+				map2 {
+					trip = <&target>;
+					cooling-device = <&rkvdec THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					contribution = <1024>;
+				};
+				map3 {
+					trip = <&target>;
+					cooling-device = <&dmc THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					contribution = <1024>;
+				};
+			};
 		};
 	};
 
@@ -387,6 +647,11 @@
 		reg-io-width = <4>;
 		reg-shift = <2>;
 		status = "disabled";
+	};
+
+	pmu: power-management@ff140000 {
+		compatible = "rockchip,rk3328-pmu", "syscon", "simple-mfd";
+		reg = <0x0 0xff140000 0x0 0x1000>;
 	};
 
 	i2c0: i2c@ff150000 {
@@ -461,11 +726,13 @@
 		reg = <0x0 0xff1a0000 0x0 0x100>;
 		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru PCLK_BUS_PRE>;
+		status = "disabled";
 	};
 
 	pwm0: pwm@ff1b0000 {
 		compatible = "rockchip,rk3328-pwm";
 		reg = <0x0 0xff1b0000 0x0 0x10>;
+		interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>;
 		clock-names = "pwm", "pclk";
 		pinctrl-names = "active";
@@ -477,6 +744,7 @@
 	pwm1: pwm@ff1b0010 {
 		compatible = "rockchip,rk3328-pwm";
 		reg = <0x0 0xff1b0010 0x0 0x10>;
+		interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>;
 		clock-names = "pwm", "pclk";
 		pinctrl-names = "active";
@@ -488,6 +756,7 @@
 	pwm2: pwm@ff1b0020 {
 		compatible = "rockchip,rk3328-pwm";
 		reg = <0x0 0xff1b0020 0x0 0x10>;
+		interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>;
 		clock-names = "pwm", "pclk";
 		pinctrl-names = "active";
@@ -508,44 +777,15 @@
 		status = "disabled";
 	};
 
-	thermal-zones {
-		soc_thermal: soc-thermal {
-			polling-delay-passive = <20>;
-			polling-delay = <1000>;
-			sustainable-power = <1000>;
-
-			thermal-sensors = <&tsadc 0>;
-
-			trips {
-				threshold: trip-point0 {
-					temperature = <70000>;
-					hysteresis = <2000>;
-					type = "passive";
-				};
-				target: trip-point1 {
-					temperature = <85000>;
-					hysteresis = <2000>;
-					type = "passive";
-				};
-				soc_crit: soc-crit {
-					temperature = <95000>;
-					hysteresis = <2000>;
-					type = "critical";
-				};
-			};
-
-			cooling-maps {
-				map0 {
-					trip = <&target>;
-					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
-					contribution = <4096>;
-				};
-			};
-		};
-
+	dmac: dma-controller@ff1f0000 {
+		compatible = "arm,pl330", "arm,primecell";
+		reg = <0x0 0xff1f0000 0x0 0x4000>;
+		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+		arm,pl330-periph-burst;
+		clocks = <&cru ACLK_DMAC>;
+		clock-names = "apb_pclk";
+		#dma-cells = <1>;
 	};
 
 	tsadc: tsadc@ff250000 {
@@ -605,7 +845,7 @@
 	};
 
 	gpu: gpu@ff300000 {
-		compatible = "rockchip,rk3328-mali", "arm,mali-450";
+		compatible = "arm,mali-450";
 		reg = <0x0 0xff300000 0x0 0x30000>;
 		interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
@@ -614,26 +854,92 @@
 			     <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "gp",
-				  "gpmmu",
-				  "pp",
-				  "pp0",
-				  "ppmmu0",
-				  "pp1",
-				  "ppmmu1";
-		clocks = <&cru ACLK_GPU>, <&cru ACLK_GPU>;
-		clock-names = "bus", "core";
+		interrupt-names = "Mali_GP_IRQ",
+				  "Mali_GP_MMU_IRQ",
+				  "IRQPP",
+				  "Mali_PP0_IRQ",
+				  "Mali_PP0_MMU_IRQ",
+				  "Mali_PP1_IRQ",
+				  "Mali_PP1_MMU_IRQ";
+		clocks = <&cru ACLK_GPU>;
+		clock-names = "clk_mali";
+		#cooling-cells = <2>; /* min followed by max */
+		operating-points-v2 = <&gpu_opp_table>;
 		resets = <&cru SRST_GPU_A>;
+		status = "disabled";
+
+		gpu_power_model: power_model {
+			compatible = "arm,mali-simple-power-model";
+			voltage = <900>;
+			frequency = <500>;
+			static-power = <300>;
+			dynamic-power = <396>;
+			ts = <32000 4700 (-80) 2>;
+			thermal-zone = "soc-thermal";
+		};
 	};
 
-	h265e_mmu: iommu@ff330200 {
-		compatible = "rockchip,iommu";
-		reg = <0x0 0xff330200 0 0x100>;
-		interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "h265e_mmu";
-		clocks = <&cru ACLK_H265>, <&cru PCLK_H265>;
-		clock-names = "aclk", "iface";
-		#iommu-cells = <0>;
+	gpu_opp_table: gpu-opp-table {
+		compatible = "operating-points-v2";
+
+		rockchip,leakage-voltage-sel = <
+			1   10    0
+			11  254   1
+		>;
+		nvmem-cells = <&logic_leakage>;
+		nvmem-cell-names = "gpu_leakage";
+
+		opp-200000000 {
+			opp-hz = /bits/ 64 <200000000>;
+			opp-microvolt = <950000>;
+			opp-microvolt-L0 = <950000>;
+			opp-microvolt-L1 = <950000>;
+		};
+		opp-300000000 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-microvolt = <975000>;
+			opp-microvolt-L0 = <975000>;
+			opp-microvolt-L1 = <950000>;
+		};
+		opp-400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-microvolt = <1050000>;
+			opp-microvolt-L0 = <1050000>;
+			opp-microvolt-L1 = <1025000>;
+		};
+		opp-500000000 {
+			opp-hz = /bits/ 64 <500000000>;
+			opp-microvolt = <1150000>;
+			opp-microvolt-L0 = <1150000>;
+			opp-microvolt-L1 = <1100000>;
+		};
+	};
+
+	mpp_srv: mpp-srv {
+		compatible = "rockchip,mpp-service";
+		rockchip,taskqueue-count = <3>;
+		rockchip,resetgroup-count = <4>;
+		rockchip,grf = <&grf>;
+		rockchip,grf-offset = <0x040c>;
+		rockchip,grf-values = <0x8000000>;
+		rockchip,grf-names = "grf_vepu2";
+		status = "disabled";
+	};
+
+	vepu: vepu@ff340000 {
+		compatible = "rockchip,vpu-encoder-v2";
+		reg = <0x0 0xff340000 0x0 0x400>;
+		interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_H264>, <&cru HCLK_H264>;
+		clock-names = "aclk_vcodec", "hclk_vcodec";
+		resets = <&cru SRST_RKVENC_H264_A>,
+			 <&cru SRST_RKVENC_H264_H>;
+		reset-names = "video_a", "video_h";
+		iommus = <&vepu_mmu>;
+		rockchip,srv = <&mpp_srv>;
+		rockchip,taskqueue-node = <0>;
+		rockchip,resetgroup-node = <3>;
+		power-domains = <&power RK3328_PD_HEVC>;
 		status = "disabled";
 	};
 
@@ -642,21 +948,28 @@
 		reg = <0x0 0xff340800 0x0 0x40>;
 		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "vepu_mmu";
-		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+		clocks = <&cru ACLK_H264>, <&cru HCLK_H264>;
 		clock-names = "aclk", "iface";
+		power-domains = <&power RK3328_PD_HEVC>;
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
 
-	vpu: video-codec@ff350000 {
-		compatible = "rockchip,rk3328-vpu";
-		reg = <0x0 0xff350000 0x0 0x800>;
+	vdpu: vdpu@ff350000 {
+		compatible = "rockchip,vpu-decoder-v2";
+		reg = <0x0 0xff350400 0x0 0x400>;
 		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "vdpu";
+		interrupt-names = "irq_dec";
 		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
-		clock-names = "aclk", "hclk";
+		clock-names = "aclk_vcodec", "hclk_vcodec";
+		resets = <&cru SRST_VCODEC_A>, <&cru SRST_VCODEC_H>;
+		reset-names = "shared_video_a", "shared_video_h";
 		iommus = <&vpu_mmu>;
 		power-domains = <&power RK3328_PD_VPU>;
+		rockchip,srv = <&mpp_srv>;
+		rockchip,taskqueue-node = <0>;
+		rockchip,resetgroup-node = <0>;
+		status = "disabled";
 	};
 
 	vpu_mmu: iommu@ff350800 {
@@ -668,6 +981,90 @@
 		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
 		power-domains = <&power RK3328_PD_VPU>;
+		status = "disabled";
+	};
+
+	avsd: avsd_plus@ff351000 {
+		compatible = "rockchip,avs-plus-decoder";
+		reg = <0x0 0xff351000 0x0 0x200>;
+		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "irq_dec";
+		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+		clock-names = "aclk_vcodec", "hclk_vcodec";
+		resets = <&cru SRST_VCODEC_A>, <&cru SRST_VCODEC_H>;
+		reset-names = "shared_video_a", "shared_video_h";
+		iommus = <&vpu_mmu>;
+		power-domains = <&power RK3328_PD_VPU>;
+		rockchip,srv = <&mpp_srv>;
+		rockchip,taskqueue-node = <0>;
+		rockchip,resetgroup-node = <0>;
+		status = "disabled";
+	};
+
+	rkvdec: rkvdec@ff36000 {
+		compatible = "rockchip,rkv-decoder-rk3328", "rockchip,rkv-decoder-v2";
+		reg = <0x0 0xff360000 0x0 0x400>;
+		interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "irq_dec";
+		clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>,
+			<&cru SCLK_VDEC_CABAC>, <&cru SCLK_VDEC_CORE>;
+		clock-names = "aclk_vcodec", "hclk_vcodec", "clk_cabac",
+			"clk_core";
+		rockchip,normal-rates = <300000000>, <0>, <300000000>, <300000000>;
+		rockchip,advanced-rates = <400000000>, <0>, <400000000>, <300000000>;
+		rockchip,default-max-load = <2088960>;
+		resets = <&cru SRST_VDEC_A>, <&cru SRST_VDEC_H>,
+			<&cru SRST_VDEC_NIU_A>, <&cru SRST_VDEC_NIU_H>,
+			<&cru SRST_VDEC_CABAC>, <&cru SRST_VDEC_CORE>;
+		reset-names = "video_a", "video_h", "niu_a", "niu_h",
+			"video_cabac", "video_core";
+		iommus = <&rkvdec_mmu>;
+		rockchip,srv = <&mpp_srv>;
+		rockchip,taskqueue-node = <1>;
+		rockchip,resetgroup-node = <1>;
+		power-domains = <&power RK3328_PD_VIDEO>;
+		operating-points-v2 = <&rkvdec_opp_table>;
+		#cooling-cells = <2>;
+		devfreq = <&dmc>;
+		status = "disabled";
+
+		vcodec_power_model: vcodec_power_model {
+			compatible = "vcodec_power_model";
+			dynamic-power-coefficient = <120>;
+			static-power-coefficient = <200>;
+			ts = <32000 4700 (-80) 2>;
+			thermal-zone = "soc-thermal";
+		};
+	};
+
+	rkvdec_opp_table: rkvdec-opp-table {
+		compatible = "operating-points-v2";
+
+		rockchip,leakage-voltage-sel = <
+			1   10    0
+			11  254   1
+		>;
+		nvmem-cells = <&logic_leakage>;
+		nvmem-cell-names = "rkvdec_leakage";
+
+		opp-100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+			opp-microvolt = <975000>;
+			opp-microvolt-L0 = <975000>;
+			opp-microvolt-L1 = <950000>;
+		};
+		opp-200000000 {
+			opp-hz = /bits/ 64 <200000000>;
+			opp-microvolt = <975000>;
+			opp-microvolt-L0 = <975000>;
+			opp-microvolt-L1 = <950000>;
+		};
+		opp-500000000 {
+			opp-hz = /bits/ 64 <500000000>;
+			opp-microvolt = <1075000>;
+			opp-microvolt-L0 = <1075000>;
+			opp-microvolt-L1 = <1050000>;
+		};
 	};
 
 	rkvdec_mmu: iommu@ff360480 {
@@ -678,6 +1075,7 @@
 		clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>;
 		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
+		power-domains = <&power RK3328_PD_VIDEO>;
 		status = "disabled";
 	};
 
@@ -687,6 +1085,8 @@
 		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru ACLK_VOP>, <&cru DCLK_LCDC>, <&cru HCLK_VOP>;
 		clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+		assigned-clocks = <&cru DCLK_LCDC>;
+		assigned-clock-parents = <&cru HDMIPHY>;
 		resets = <&cru SRST_VOP_A>, <&cru SRST_VOP_H>, <&cru SRST_VOP_D>;
 		reset-names = "axi", "ahb", "dclk";
 		iommus = <&vop_mmu>;
@@ -700,6 +1100,36 @@
 				reg = <0>;
 				remote-endpoint = <&hdmi_in_vop>;
 			};
+			vop_out_tve: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&tve_in_vop>;
+			};
+		};
+	};
+
+	tve: tve@ff373e00 {
+		compatible = "rockchip,rk3328-tve";
+		reg = <0x0 0xff373e00 0x0 0x100>,
+		      <0x0 0xff420000 0x0 0x10000>;
+		rockchip,saturation = <0x00376749>;
+		rockchip,brightcontrast = <0x0000a305>;
+		rockchip,adjtiming = <0xb6c00880>;
+		rockchip,lumafilter0 = <0x01ff0000>;
+		rockchip,lumafilter1 = <0xf40200fe>;
+		rockchip,lumafilter2 = <0xf332d70c>;
+		rockchip,daclevel = <0x22>;
+		rockchip,dac1level = <0x7>;
+		status = "disabled";
+
+		ports {
+			tve_in: port {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				tve_in_vop: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&vop_out_tve>;
+				};
+			};
 		};
 	};
 
@@ -710,6 +1140,53 @@
 		interrupt-names = "vop_mmu";
 		clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
 		clock-names = "aclk", "iface";
+		#iommu-cells = <0>;
+		status = "disabled";
+	};
+
+	cif: cif@ff380000 {
+		compatible = "rockchip,cif", "rockchip,rk3328-cif";
+		reg = <0x0 0xff380000 0x0 0x400>;
+		interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>;
+		clock-names = "aclk_cif", "hclk_cif";
+		resets = <&cru SRST_CIF_A>, <&cru SRST_CIF_H>, <&cru SRST_CIF_P>;
+		reset-names = "rst_cif_a", "rst_cif_h", "rst_cif_p";
+		status = "disabled";
+	};
+
+	rga: rga@ff3900000 {
+		compatible = "rockchip,rga2";
+		dev_mode = <1>;
+		reg = <0x0 0xff390000 0x0 0x1000>;
+		interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_RGA>, <&cru HCLK_RGA>, <&cru SCLK_RGA>;
+		clock-names = "aclk_rga", "hclk_rga", "clk_rga";
+		status = "disabled";
+	};
+
+	iep: iep@ff3a0000 {
+		compatible = "rockchip,iep";
+		iommu_enabled = <1>;
+		iommus = <&iep_mmu>;
+		reg = <0x0 0xff3a0000 0x0 0x800>;
+		interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
+		clock-names = "aclk_iep", "hclk_iep";
+		power-domains = <&power RK3328_PD_VIDEO>;
+		allocator = <1>;
+		version = <2>;
+		status = "disabled";
+	};
+
+	iep_mmu: iommu@ff3a0800 {
+		compatible = "rockchip,iommu";
+		reg = <0x0 0xff3a0800 0x0 0x40>;
+		interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "iep_mmu";
+		clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
+		clock-names = "aclk", "hclk";
+		power-domains = <&power RK3328_PD_VIDEO>;
 		#iommu-cells = <0>;
 		status = "disabled";
 	};
@@ -728,15 +1205,23 @@
 			      "cec";
 		phys = <&hdmiphy>;
 		phy-names = "hdmi";
-		pinctrl-names = "default";
+		pinctrl-names = "default", "pin";
 		pinctrl-0 = <&hdmi_cec &hdmii2c_xfer &hdmi_hpd>;
+		pinctrl-1 = <&i2c3_pins>;
+		resets = <&cru SRST_HDMI_P>,
+			 <&cru SRST_HDMIPHY>;
+		reset-names = "hdmi",
+			      "hdmiphy";
 		rockchip,grf = <&grf>;
 		#sound-dai-cells = <0>;
 		status = "disabled";
 
 		ports {
 			hdmi_in: port {
-				hdmi_in_vop: endpoint {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				hdmi_in_vop: endpoint@0 {
+					reg = <0>;
 					remote-endpoint = <&vop_out_hdmi>;
 				};
 			};
@@ -758,7 +1243,7 @@
 		reg = <0x0 0xff430000 0x0 0x10000>;
 		interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru PCLK_HDMIPHY>, <&xin24m>, <&cru DCLK_HDMIPHY>;
-		clock-names = "sysclk", "refoclk", "refpclk";
+		clock-names = "sysclk", "refclk", "refpclk";
 		clock-output-names = "hdmi_phy";
 		#clock-cells = <0>;
 		nvmem-cells = <&efuse_cpu_version>;
@@ -856,6 +1341,47 @@
 		};
 	};
 
+	usb3phy_grf: syscon@ff460000 {
+		compatible = "rockchip,usb3phy-grf", "syscon";
+		reg = <0x0 0xff460000 0x0 0x1000>;
+	};
+
+	u3phy: usb3-phy@ff470000 {
+		compatible = "rockchip,rk3328-u3phy";
+		reg = <0x0 0xff470000 0x0 0x0>;
+		rockchip,u3phygrf = <&usb3phy_grf>;
+		rockchip,grf = <&grf>;
+		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "linestate";
+		clocks = <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>;
+		clock-names = "u3phy-otg", "u3phy-pipe";
+		resets = <&cru SRST_USB3PHY_U2>,
+			 <&cru SRST_USB3PHY_U3>,
+			 <&cru SRST_USB3PHY_PIPE>,
+			 <&cru SRST_USB3OTG_UTMI>,
+			 <&cru SRST_USB3PHY_OTG_P>,
+			 <&cru SRST_USB3PHY_PIPE_P>;
+		reset-names = "u3phy-u2-por", "u3phy-u3-por",
+			      "u3phy-pipe-mac", "u3phy-utmi-mac",
+			      "u3phy-utmi-apb", "u3phy-pipe-apb";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		u3phy_utmi: utmi@ff470000 {
+			reg = <0x0 0xff470000 0x0 0x8000>;
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
+		u3phy_pipe: pipe@ff478000 {
+			reg = <0x0 0xff478000 0x0 0x8000>;
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+	};
+
 	sdmmc: mmc@ff500000 {
 		compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc";
 		reg = <0x0 0xff500000 0x0 0x4000>;
@@ -930,8 +1456,6 @@
 		reset-names = "stmmaceth", "mac-phy";
 		phy-mode = "rmii";
 		phy-handle = <&phy>;
-		snps,txpbl = <0x4>;
-		clock_in_out = "output";
 		status = "disabled";
 
 		mdio {
@@ -956,8 +1480,8 @@
 			     "snps,dwc2";
 		reg = <0x0 0xff580000 0x0 0x40000>;
 		interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cru HCLK_OTG>;
-		clock-names = "otg";
+		clocks = <&cru HCLK_OTG>, <&cru HCLK_OTG_PMU>;
+		clock-names = "otg", "otg_pmu";
 		dr_mode = "otg";
 		g-np-tx-fifo-size = <16>;
 		g-rx-fifo-size = <280>;
@@ -971,7 +1495,9 @@
 		compatible = "generic-ehci";
 		reg = <0x0 0xff5c0000 0x0 0x10000>;
 		interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cru HCLK_HOST0>, <&u2phy>;
+		clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>,
+			 <&u2phy>;
+		clock-names = "usbhost", "arbiter", "utmi";
 		phys = <&u2phy_host>;
 		phy-names = "usb";
 		status = "disabled";
@@ -981,30 +1507,76 @@
 		compatible = "generic-ohci";
 		reg = <0x0 0xff5d0000 0x0 0x10000>;
 		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cru HCLK_HOST0>, <&u2phy>;
+		clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>,
+			 <&u2phy>;
+		clock-names = "usbhost", "arbiter", "utmi";
 		phys = <&u2phy_host>;
 		phy-names = "usb";
 		status = "disabled";
 	};
 
-	usbdrd3: usb@ff600000 {
+	sdmmc_ext: mmc@ff5f0000 {
+		compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc";
+		reg = <0x0 0xff5f0000 0x0 0x4000>;
+		clock-freq-min-max = <400000 150000000>;
+		clocks = <&cru HCLK_SDMMC_EXT>, <&cru SCLK_SDMMC_EXT>,
+			 <&cru SCLK_SDMMC_EXT_DRV>, <&cru SCLK_SDMMC_EXT_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	usbdrd3: usbdrd {
 		compatible = "rockchip,rk3328-dwc3", "snps,dwc3";
-		reg = <0x0 0xff600000 0x0 0x100000>;
-		interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru SCLK_USB3OTG_REF>, <&cru SCLK_USB3OTG_SUSPEND>,
 			 <&cru ACLK_USB3OTG>;
 		clock-names = "ref_clk", "suspend_clk",
 			      "bus_clk";
-		dr_mode = "otg";
-		phy_type = "utmi_wide";
-		snps,dis-del-phy-power-chg-quirk;
-		snps,dis_enblslpm_quirk;
-		snps,dis-tx-ipgap-linecheck-quirk;
-		snps,dis-u2-freeclk-exists-quirk;
-		snps,dis_u2_susphy_quirk;
-		snps,dis_u3_susphy_quirk;
-		snps,parkmode-disable-hs-quirk;
-		snps,parkmode-disable-ss-quirk;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		usbdrd_dwc3: dwc3@ff600000 {
+			compatible = "snps,dwc3";
+			reg = <0x0 0xff600000 0x0 0x100000>;
+			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+			dr_mode = "host";
+			phys = <&u3phy_utmi>, <&u3phy_pipe>;
+			phy-names = "usb2-phy", "usb3-phy";
+			phy_type = "utmi_wide";
+			snps,dis-del-phy-power-chg-quirk;
+			snps,dis_enblslpm_quirk;
+			snps,dis-tx-ipgap-linecheck-quirk;
+			snps,dis-u2-freeclk-exists-quirk;
+			snps,dis_u2_susphy_quirk;
+			snps,dis_u3_susphy_quirk;
+			snps,parkmode-disable-hs-quirk;
+			snps,parkmode-disable-ss-quirk;
+			status = "disabled";
+		};
+	};
+
+	qos_rkvdec_r: qos@ff750000 {
+		compatible = "syscon";
+		reg = <0x0 0xff750000 0x0 0x20>;
+	};
+
+	qos_rkvdec_w: qos@ff750080 {
+		compatible = "syscon";
+		reg = <0x0 0xff750080 0x0 0x20>;
+	};
+
+	qos_vpu: qos@ff778000 {
+		compatible = "syscon";
+		reg = <0x0 0xff778000 0x0 0x20>;
+	};
+
+	dfi: dfi@ff790000 {
+		compatible = "rockchip,rk3328-dfi";
+		reg = <0x00 0xff790000 0x00 0x400>;
+		rockchip,grf = <&grf>;
 		status = "disabled";
 	};
 
@@ -1028,7 +1600,7 @@
 		#size-cells = <2>;
 		ranges;
 
-		gpio0: gpio0@ff210000 {
+		gpio0: gpio@ff210000 {
 			compatible = "rockchip,gpio-bank";
 			reg = <0x0 0xff210000 0x0 0x100>;
 			interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
@@ -1041,7 +1613,7 @@
 			#interrupt-cells = <2>;
 		};
 
-		gpio1: gpio1@ff220000 {
+		gpio1: gpio@ff220000 {
 			compatible = "rockchip,gpio-bank";
 			reg = <0x0 0xff220000 0x0 0x100>;
 			interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
@@ -1054,7 +1626,7 @@
 			#interrupt-cells = <2>;
 		};
 
-		gpio2: gpio2@ff230000 {
+		gpio2: gpio@ff230000 {
 			compatible = "rockchip,gpio-bank";
 			reg = <0x0 0xff230000 0x0 0x100>;
 			interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
@@ -1067,7 +1639,7 @@
 			#interrupt-cells = <2>;
 		};
 
-		gpio3: gpio3@ff240000 {
+		gpio3: gpio@ff240000 {
 			compatible = "rockchip,gpio-bank";
 			reg = <0x0 0xff240000 0x0 0x100>;
 			interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
@@ -1187,6 +1759,45 @@
 			};
 		};
 
+		tsp {
+			tsp_d0: tsp-d0 {
+				rockchip,pins = <3 RK_PA4 1 &pcfg_pull_none>;
+			};
+			tsp_d1: tsp-d1 {
+				rockchip,pins = <3 RK_PA5 1 &pcfg_pull_none>;
+			};
+			tsp_d2: tsp-d2 {
+				rockchip,pins = <3 RK_PA6 1 &pcfg_pull_none>;
+			};
+			tsp_d3: tsp-d3 {
+				rockchip,pins = <3 RK_PA7 1 &pcfg_pull_none>;
+			};
+			tsp_d4: tsp-d4 {
+				rockchip,pins = <3 RK_PB0 1 &pcfg_pull_none>;
+			};
+			tsp_d5: tsp-d5 {
+				rockchip,pins = <2 RK_PC0 3 &pcfg_pull_none>;
+			};
+			tsp_d6: tsp-d6 {
+				rockchip,pins = <2 RK_PC1 3 &pcfg_pull_none>;
+			};
+			tsp_d7: tsp-d7 {
+				rockchip,pins = <2 RK_PC2 3 &pcfg_pull_none>;
+			};
+			tsp_sync: tsp-sync {
+				rockchip,pins = <2 RK_PB7 3 &pcfg_pull_none>;
+			};
+			tsp_clk: tsp-clk {
+				rockchip,pins = <3 RK_PA2 1 &pcfg_pull_none>;
+			};
+			tsp_fail: tsp-fail {
+				rockchip,pins = <3 RK_PA1 1 &pcfg_pull_none>;
+			};
+			tsp_valid: tsp-valid {
+				rockchip,pins = <3 RK_PA0 1 &pcfg_pull_none>;
+			};
+		};
+
 		hdmi_i2c {
 			hdmii2c_xfer: hdmii2c-xfer {
 				rockchip,pins = <0 RK_PA5 1 &pcfg_pull_none>,
@@ -1262,7 +1873,7 @@
 
 		uart0 {
 			uart0_xfer: uart0-xfer {
-				rockchip,pins = <1 RK_PB1 1 &pcfg_pull_none>,
+				rockchip,pins = <1 RK_PB1 1 &pcfg_pull_up>,
 						<1 RK_PB0 1 &pcfg_pull_up>;
 			};
 
@@ -1281,7 +1892,7 @@
 
 		uart1 {
 			uart1_xfer: uart1-xfer {
-				rockchip,pins = <3 RK_PA4 4 &pcfg_pull_none>,
+				rockchip,pins = <3 RK_PA4 4 &pcfg_pull_up>,
 						<3 RK_PA6 4 &pcfg_pull_up>;
 			};
 
@@ -1300,14 +1911,14 @@
 
 		uart2-0 {
 			uart2m0_xfer: uart2m0-xfer {
-				rockchip,pins = <1 RK_PA0 2 &pcfg_pull_none>,
+				rockchip,pins = <1 RK_PA0 2 &pcfg_pull_up>,
 						<1 RK_PA1 2 &pcfg_pull_up>;
 			};
 		};
 
 		uart2-1 {
 			uart2m1_xfer: uart2m1-xfer {
-				rockchip,pins = <2 RK_PA0 1 &pcfg_pull_none>,
+				rockchip,pins = <2 RK_PA0 1 &pcfg_pull_up>,
 						<2 RK_PA1 1 &pcfg_pull_up>;
 			};
 		};
@@ -1709,11 +2320,17 @@
 			pwm0_pin: pwm0-pin {
 				rockchip,pins = <2 RK_PA4 1 &pcfg_pull_none>;
 			};
+			pwm0_pin_pull_up: pwm0-pin-pull-up {
+				rockchip,pins = <2 RK_PA4 1 &pcfg_pull_up>;
+			};
 		};
 
 		pwm1 {
 			pwm1_pin: pwm1-pin {
 				rockchip,pins = <2 RK_PA5 1 &pcfg_pull_none>;
+			};
+			pwm1_pin_pull_up: pwm1-pin-pull-up {
+				rockchip,pins = <2 RK_PA5 1 &pcfg_pull_up>;
 			};
 		};
 
@@ -1822,10 +2439,26 @@
 				rockchip,pins = <0 RK_PD6 1 &pcfg_pull_none>;
 			};
 
+			fephyled_speed100: fephyled-speed100 {
+				rockchip,pins = <0 RK_PD7 1 &pcfg_pull_none>;
+			};
+
 			fephyled_duplex: fephyled-duplex {
 				rockchip,pins = <0 RK_PD6 2 &pcfg_pull_none>;
 			};
 
+			fephyled_rxm0: fephyled-rxm0 {
+				rockchip,pins = <0 RK_PD5 1 &pcfg_pull_none>;
+			};
+
+			fephyled_txm0: fephyled-txm0 {
+				rockchip,pins = <0 RK_PD5 2 &pcfg_pull_none>;
+			};
+
+			fephyled_linkm0: fephyled-linkm0 {
+				rockchip,pins = <0 RK_PD4 1 &pcfg_pull_none>;
+			};
+
 			fephyled_rxm1: fephyled-rxm1 {
 				rockchip,pins = <2 RK_PD1 2 &pcfg_pull_none>;
 			};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399-android.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3399-android.dtsi
index 035fb21..231fd6d 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399-android.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399-android.dtsi
@@ -22,6 +22,16 @@
 		nvmem-cell-names = "id";
 	};
 
+	debug: debug {
+		compatible = "rockchip,debug";
+		reg = <0x0 0xfe430000 0x0 0x1000>,
+		      <0x0 0xfe432000 0x0 0x1000>,
+		      <0x0 0xfe434000 0x0 0x1000>,
+		      <0x0 0xfe436000 0x0 0x1000>,
+		      <0x0 0xfe610000 0x0 0x1000>,
+		      <0x0 0xfe710000 0x0 0x1000>;
+	};
+
 	fiq_debugger: fiq-debugger {
 		compatible = "rockchip,fiq-debugger";
 		rockchip,serial-id = <2>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android-avb.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android-avb.dts
index 844a91e..34a9b66 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android-avb.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android-avb.dts
@@ -39,6 +39,8 @@
 		prepare-delay-ms = <20>;
 		reset-delay-ms = <20>;
 		enable-delay-ms = <20>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		display-timings {
 			native-mode = <&timing0>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android.dts
index 72aa97a..bb53e27 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android.dts
@@ -36,6 +36,8 @@
 		reset-gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
 		prepare-delay-ms = <20>;
 		enable-delay-ms = <20>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		display-timings {
 			native-mode = <&timing0>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-linux.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-linux.dts
index b4b3a00..bc82021 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-linux.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-linux.dts
@@ -46,6 +46,8 @@
 		reset-gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
 		prepare-delay-ms = <20>;
 		enable-delay-ms = <20>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		display-timings {
 			native-mode = <&timing0>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-v13-android-avb.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-v13-android-avb.dts
index 18ef511..7509122 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-v13-android-avb.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-v13-android-avb.dts
@@ -50,6 +50,8 @@
 		prepare-delay-ms = <20>;
 		reset-delay-ms = <20>;
 		enable-delay-ms = <20>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		display-timings {
 			native-mode = <&timing0>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
index 64df643..2f52b91 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
@@ -31,6 +31,40 @@
 		reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
 	};
 
+	sound {
+		compatible = "audio-graph-card";
+		label = "Analog";
+		dais = <&i2s0_p0>;
+	};
+
+	sound-dit {
+		compatible = "audio-graph-card";
+		label = "SPDIF";
+		dais = <&spdif_p0>;
+	};
+
+	spdif-dit {
+		compatible = "linux,spdif-dit";
+		#sound-dai-cells = <0>;
+
+		port {
+			dit_p0_0: endpoint {
+				remote-endpoint = <&spdif_p0_0>;
+			};
+		};
+	};
+
+	vbus_typec: vbus-typec-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_typec_en>;
+		regulator-name = "vbus_typec";
+		regulator-always-on;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
 	vcc12v_dcin: dc-12v {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc12v_dcin";
@@ -40,23 +74,13 @@
 		regulator-max-microvolt = <12000000>;
 	};
 
-	vcc5v0_sys: vcc-sys {
+	vcc3v3_lan: vcc3v3-lan-regulator {
 		compatible = "regulator-fixed";
-		regulator-name = "vcc5v0_sys";
+		regulator-name = "vcc3v3_lan";
 		regulator-always-on;
 		regulator-boot-on;
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-		vin-supply = <&vcc12v_dcin>;
-	};
-
-	vcc_0v9: vcc-0v9 {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_0v9";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <900000>;
-		regulator-max-microvolt = <900000>;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
 		vin-supply = <&vcc3v3_sys>;
 	};
 
@@ -93,28 +117,24 @@
 		vin-supply = <&vcc5v0_sys>;
 	};
 
-	vcc5v0_typec: vcc5v0-typec-regulator {
+	vcc5v0_sys: vcc-sys {
 		compatible = "regulator-fixed";
-		enable-active-high;
-		gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&vcc5v0_typec_en>;
-		regulator-name = "vcc5v0_typec";
-		regulator-always-on;
-		vin-supply = <&vcc5v0_sys>;
-	};
-
-	vcc_lan: vcc3v3-phy-regulator {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_lan";
+		regulator-name = "vcc5v0_sys";
 		regulator-always-on;
 		regulator-boot-on;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
 
-		regulator-state-mem {
-			regulator-off-in-suspend;
-		};
+	vcc_0v9: vcc-0v9 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_0v9";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <900000>;
+		regulator-max-microvolt = <900000>;
+		vin-supply = <&vcc3v3_sys>;
 	};
 
 	vdd_log: vdd-log {
@@ -161,7 +181,7 @@
 	assigned-clocks = <&cru SCLK_RMII_SRC>;
 	assigned-clock-parents = <&clkin_gmac>;
 	clock_in_out = "input";
-	phy-supply = <&vcc_lan>;
+	phy-supply = <&vcc3v3_lan>;
 	phy-mode = "rgmii";
 	pinctrl-names = "default";
 	pinctrl-0 = <&rgmii_pins>;
@@ -266,8 +286,8 @@
 				};
 			};
 
-			vcc1v8_codec: LDO_REG1 {
-				regulator-name = "vcc1v8_codec";
+			vcca1v8_codec: LDO_REG1 {
+				regulator-name = "vcca1v8_codec";
 				regulator-always-on;
 				regulator-boot-on;
 				regulator-min-microvolt = <1800000>;
@@ -277,8 +297,8 @@
 				};
 			};
 
-			vcc1v8_hdmi: LDO_REG2 {
-				regulator-name = "vcc1v8_hdmi";
+			vcca1v8_hdmi: LDO_REG2 {
+				regulator-name = "vcca1v8_hdmi";
 				regulator-always-on;
 				regulator-boot-on;
 				regulator-min-microvolt = <1800000>;
@@ -335,8 +355,8 @@
 				};
 			};
 
-			vcc0v9_hdmi: LDO_REG7 {
-				regulator-name = "vcc0v9_hdmi";
+			vcca0v9_hdmi: LDO_REG7 {
+				regulator-name = "vcca0v9_hdmi";
 				regulator-always-on;
 				regulator-boot-on;
 				regulator-min-microvolt = <900000>;
@@ -362,8 +382,6 @@
 				regulator-name = "vcc_cam";
 				regulator-always-on;
 				regulator-boot-on;
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
 				regulator-state-mem {
 					regulator-off-in-suspend;
 				};
@@ -373,8 +391,6 @@
 				regulator-name = "vcc_mipi";
 				regulator-always-on;
 				regulator-boot-on;
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
 				regulator-state-mem {
 					regulator-off-in-suspend;
 				};
@@ -425,6 +441,20 @@
 	i2c-scl-rising-time-ns = <300>;
 	i2c-scl-falling-time-ns = <15>;
 	status = "okay";
+
+	es8316: codec@11 {
+		compatible = "everest,es8316";
+		reg = <0x11>;
+		clocks = <&cru SCLK_I2S_8CH_OUT>;
+		clock-names = "mclk";
+		#sound-dai-cells = <0>;
+
+		port {
+			es8316_p0_0: endpoint {
+				remote-endpoint = <&i2s0_p0_0>;
+			};
+		};
+	};
 };
 
 &i2c3 {
@@ -443,6 +473,14 @@
 	rockchip,playback-channels = <8>;
 	rockchip,capture-channels = <8>;
 	status = "okay";
+
+	i2s0_p0: port {
+		i2s0_p0_0: endpoint {
+			dai-format = "i2s";
+			mclk-fs = <256>;
+			remote-endpoint = <&es8316_p0_0>;
+		};
+	};
 };
 
 &i2s1 {
@@ -455,21 +493,10 @@
 };
 
 &io_domains {
-	status = "okay";
-
+	audio-supply = <&vcca1v8_codec>;
 	bt656-supply = <&vcc_3v0>;
-	audio-supply = <&vcc1v8_codec>;
-	sdmmc-supply = <&vcc_sdio>;
 	gpio1830-supply = <&vcc_3v0>;
-};
-
-&pmu_io_domains {
-	status = "okay";
-
-	pmu1830-supply = <&vcc_3v0>;
-};
-
-&pcie_phy {
+	sdmmc-supply = <&vcc_sdio>;
 	status = "okay";
 };
 
@@ -482,6 +509,10 @@
 	vpcie0v9-supply = <&vcc_0v9>;
 	vpcie1v8-supply = <&vcc_1v8>;
 	vpcie3v3-supply = <&vcc3v3_pcie>;
+	status = "okay";
+};
+
+&pcie_phy {
 	status = "okay";
 };
 
@@ -506,6 +537,20 @@
 		};
 	};
 
+	pmic {
+		pmic_int_l: pmic-int-l {
+			rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		vsel1_pin: vsel1-pin {
+			rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+
+		vsel2_pin: vsel2-pin {
+			rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
+
 	sdio0 {
 		sdio0_bus4: sdio0-bus4 {
 			rockchip,pins = <2 RK_PC4 1 &pcfg_pull_up_20ma>,
@@ -520,20 +565,6 @@
 
 		sdio0_clk: sdio0-clk {
 			rockchip,pins = <2 RK_PD1 1 &pcfg_pull_none_20ma>;
-		};
-	};
-
-	pmic {
-		pmic_int_l: pmic-int-l {
-			rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
-		};
-
-		vsel1_pin: vsel1-pin {
-			rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>;
-		};
-
-		vsel2_pin: vsel2-pin {
-			rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>;
 		};
 	};
 
@@ -560,6 +591,11 @@
 	};
 };
 
+&pmu_io_domains {
+	pmu1830-supply = <&vcc_3v0>;
+	status = "okay";
+};
+
 &pwm2 {
 	status = "okay";
 };
@@ -568,6 +604,14 @@
 	status = "okay";
 
 	vref-supply = <&vcc_1v8>;
+};
+
+&sdhci {
+	max-frequency = <150000000>;
+	bus-width = <8>;
+	mmc-hs200-1_8v;
+	non-removable;
+	status = "okay";
 };
 
 &sdio0 {
@@ -597,12 +641,13 @@
 	status = "okay";
 };
 
-&sdhci {
-	bus-width = <8>;
-	mmc-hs400-1_8v;
-	mmc-hs400-enhanced-strobe;
-	non-removable;
-	status = "okay";
+&spdif {
+
+	spdif_p0: port {
+		spdif_p0_0: endpoint {
+			remote-endpoint = <&dit_p0_0>;
+		};
+	};
 };
 
 &tcphy0 {
@@ -677,15 +722,15 @@
 	status = "okay";
 };
 
-&usbdrd_dwc3_0 {
-	status = "okay";
-	dr_mode = "otg";
-};
-
 &usbdrd3_1 {
 	status = "okay";
 };
 
+&usbdrd_dwc3_0 {
+	status = "okay";
+	dr_mode = "host";
+};
+
 &usbdrd_dwc3_1 {
 	status = "okay";
 	dr_mode = "host";
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dtsi
index 5304f0f..ab2a79b 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dtsi
@@ -70,6 +70,8 @@
 		enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
 		prepare-delay-ms = <20>;
 		enable-delay-ms = <20>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		display-timings {
 			native-mode = <&timing0>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-linux.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-linux.dts
index c0abcf7..0dbe011 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-linux.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-linux.dts
@@ -73,6 +73,8 @@
 		enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
 		prepare-delay-ms = <20>;
 		enable-delay-ms = <20>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		display-timings {
 			native-mode = <&timing0>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-lp4-linux.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-lp4-linux.dts
index 54066ee..5beab0f 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-lp4-linux.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-lp4-linux.dts
@@ -70,6 +70,8 @@
 		enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
 		prepare-delay-ms = <20>;
 		enable-delay-ms = <20>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		display-timings {
 			native-mode = <&timing0>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399-tve1205g.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3399-tve1205g.dts
index bdb18a9..4927686 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399-tve1205g.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399-tve1205g.dts
@@ -166,7 +166,7 @@
 	bt-sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "dsp_b";
-		simple-audio-card,bitclock-inversion = <1>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <256>;
 		simple-audio-card,name = "rockchip,bt";
 		simple-audio-card,cpu {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-lp4-v11-linux.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-lp4-v11-linux.dts
index 4800dbf..0277a18 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-lp4-v11-linux.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-lp4-v11-linux.dts
@@ -136,6 +136,8 @@
 		prepare-delay-ms = <20>;
 		enable-delay-ms = <20>;
 		reset-delay-ms = <20>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		display-timings {
 			native-mode = <&timing0>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10-linux.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10-linux.dts
index 004ccbc..dbcc441 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10-linux.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10-linux.dts
@@ -136,6 +136,8 @@
 		prepare-delay-ms = <20>;
 		enable-delay-ms = <20>;
 		reset-delay-ms = <20>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		display-timings {
 			native-mode = <&timing0>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10.dts
index 8eb9ac1..80663f0 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10.dts
@@ -124,6 +124,8 @@
 		prepare-delay-ms = <20>;
 		enable-delay-ms = <20>;
 		reset-delay-ms = <20>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		display-timings {
 			native-mode = <&timing0>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11-linux.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11-linux.dts
index 1b0f4ff..a1204d2 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11-linux.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11-linux.dts
@@ -136,6 +136,8 @@
 		prepare-delay-ms = <20>;
 		enable-delay-ms = <20>;
 		reset-delay-ms = <20>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		display-timings {
 			native-mode = <&timing0>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11.dts
index 2b14880..32194fe 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11.dts
@@ -126,6 +126,8 @@
 		prepare-delay-ms = <20>;
 		enable-delay-ms = <20>;
 		reset-delay-ms = <20>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		display-timings {
 			native-mode = <&timing0>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-npu.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-npu.dtsi
index 5ad85b1..4e0781e 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-npu.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399pro-npu.dtsi
@@ -156,7 +156,6 @@
 			snps,dis_u3_susphy_quirk;
 			snps,dis-del-phy-power-chg-quirk;
 			snps,tx-ipgap-linecheck-dis-quirk;
-			snps,xhci-trb-ent-quirk;
 			status = "disabled";
 		};
 	};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3528-demo.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3528-demo.dtsi
index aebd946..353e75c 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3528-demo.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3528-demo.dtsi
@@ -50,7 +50,7 @@
 		status = "disabled";
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "dsp_a";
-		simple-audio-card,bitclock-inversion = <0>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <256>;
 		simple-audio-card,name = "rockchip,bt";
 		simple-audio-card,cpu {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3528-evb.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3528-evb.dtsi
index b737c44..5d39986 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3528-evb.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3528-evb.dtsi
@@ -49,7 +49,7 @@
 		status = "disabled";
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "dsp_a";
-		simple-audio-card,bitclock-inversion = <0>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <256>;
 		simple-audio-card,name = "rockchip,bt";
 		simple-audio-card,cpu {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3528.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3528.dtsi
index 029e725..68f2544 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3528.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3528.dtsi
@@ -220,6 +220,9 @@
 		rockchip,pvtm-temp-prop = <0 0>;
 		rockchip,pvtm-thermal-zone = "soc-thermal";
 		rockchip,grf = <&grf>;
+		rockchip,temp-hysteresis = <5000>;
+		rockchip,low-temp = <10000>;
+		rockchip,low-temp-min-volt = <900000>;
 
 		opp-408000000 {
 			opp-hz = /bits/ 64 <408000000>;
@@ -649,7 +652,6 @@
 			snps,dis-u2-freeclk-exists-quirk;
 			snps,dis-del-phy-power-chg-quirk;
 			snps,dis-tx-ipgap-linecheck-quirk;
-			snps,xhci-trb-ent-quirk;
 			snps,dis_rxdet_inp3_quirk;
 			snps,parkmode-disable-hs-quirk;
 			snps,parkmode-disable-ss-quirk;
@@ -1073,6 +1075,9 @@
 		rockchip,pvtm-temp-prop = <0 0>;
 		rockchip,pvtm-thermal-zone = "soc-thermal";
 		rockchip,grf = <&grf>;
+		rockchip,temp-hysteresis = <5000>;
+		rockchip,low-temp = <10000>;
+		rockchip,low-temp-min-volt = <900000>;
 
 		opp-300000000 {
 			opp-hz = /bits/ 64 <300000000>;
@@ -1797,6 +1802,7 @@
 	pwm0: pwm@ffa90000 {
 		compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xffa90000 0x0 0x10>;
+		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm0m0_pins>;
@@ -1808,6 +1814,7 @@
 	pwm1: pwm@ffa90010 {
 		compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xffa90010 0x0 0x10>;
+		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm1m0_pins>;
@@ -1819,6 +1826,7 @@
 	pwm2: pwm@ffa90020 {
 		compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xffa90020 0x0 0x10>;
+		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm2m0_pins>;
@@ -1843,6 +1851,7 @@
 	pwm4: pwm@ffa98000 {
 		compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xffa98000 0x0 0x10>;
+		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm4m0_pins>;
@@ -1854,6 +1863,7 @@
 	pwm5: pwm@ffa98010 {
 		compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xffa98010 0x0 0x10>;
+		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm5m0_pins>;
@@ -1865,6 +1875,7 @@
 	pwm6: pwm@ffa98020 {
 		compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm";
 		reg = <0x0 0xffa98020 0x0 0x10>;
+		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
 		#pwm-cells = <3>;
 		pinctrl-names = "active";
 		pinctrl-0 = <&pwm6m0_pins>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3562-amp.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3562-amp.dtsi
index 25f820c..0cf505c 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3562-amp.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3562-amp.dtsi
@@ -16,8 +16,8 @@
 		pinctrl-names = "default";
 		pinctrl-0 = <&uart7m1_xfer>;
 
-		amp-cpu-aff-maskbits = <0x0 0x1 0x1 0x2 0x2 0x4 0x3 0x8>;
-		amp-irqs = <GIC_AMP_IRQ_CFG_ROUTE(81, 0xd0, CPU_GET_AFFINITY(3, 0))>;
+		amp-cpu-aff-maskbits = /bits/ 64 <0x0 0x1 0x1 0x2 0x2 0x4 0x3 0x8>;
+		amp-irqs = /bits/ 64 <GIC_AMP_IRQ_CFG_ROUTE(147, 0xd0, CPU_GET_AFFINITY(3, 0))>;
 
 		status = "okay";
 	};
@@ -57,7 +57,8 @@
 		mbox-names = "rpmsg-rx", "rpmsg-tx";
 		mboxes = <&mailbox 0 &mailbox 3>;
 		rockchip,vdev-nums = <1>;
-		rockchip,link-id = <0x04>;
+		/* CPU3: link-id 0x03; MCU: link-id 0x04; */
+		rockchip,link-id = <0x03>;
 		reg = <0x0 0x7c00000 0x0 0x20000>;
 		memory-region = <&rpmsg_dma_reserved>;
 
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3562-evb.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3562-evb.dtsi
index 1e5aa02..c9f16a7 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3562-evb.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3562-evb.dtsi
@@ -163,6 +163,8 @@
 		prepare-delay-ms = <60>;
 		unprepare-delay-ms = <60>;
 		disable-delay-ms = <60>;
+		width-mm = <68>;
+		height-mm = <121>;
 		dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
 			MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>;
 		dsi,format = <MIPI_DSI_FMT_RGB888>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3562-evb1-cam.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3562-evb1-cam.dtsi
index b66f45e..492863b 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3562-evb1-cam.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3562-evb1-cam.dtsi
@@ -59,6 +59,7 @@
 		compatible = "dongwoon,dw9714";
 		status = "okay";
 		reg = <0x0c>;
+		avdd-supply = <&vcc2v8_dvp>;
 		rockchip,vcm-start-current = <10>;
 		rockchip,vcm-rated-current = <85>;
 		rockchip,vcm-step-mode = <5>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3562-evb1-lp4x-v10.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3562-evb1-lp4x-v10.dtsi
index 44f2ff7..7fdb055 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3562-evb1-lp4x-v10.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3562-evb1-lp4x-v10.dtsi
@@ -179,18 +179,6 @@
 	};
 };
 
-&bus_soc {
-	rockchip,soc-bus-table = <0 0x00a000a8 0x7001>,
-				 <1 0x00a000a8 0x7c39>,
-				 <2 0x00a000a8 0x7c39>,
-				 <3 0x00a000a8 0x7c39>,
-				 <4 0x00a000a5 0xb007>,
-				 <5 0x00a000a8 0x7034>,
-				 <6 0x00a000a8 0x7034>,
-				 <7 0x00a000a8 0x7034>,
-				 <8 0x00a000a8 0x7001>;
-};
-
 &gmac0 {
 	/* Use rgmii-rxid mode to disable rx delay inside Soc */
 	phy-mode = "rgmii-rxid";
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3562-evb2-ddr4-v10-linux-amp.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3562-evb2-ddr4-v10-linux-amp.dts
new file mode 100644
index 0000000..9938576
--- /dev/null
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3562-evb2-ddr4-v10-linux-amp.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+#include "rk3562-evb2-ddr4-v10.dtsi"
+#include "rk3562-linux.dtsi"
+#include "rk3562-rk809.dtsi"
+#include "rk3562-evb2-cam.dtsi"
+#include "rk3562-amp.dtsi"
+
+/ {
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x02000000 0x0 0x04b80000>,
+		      <0x0 0x0a200000 0x0 0x75e00000>;
+	};
+};
+
+&arm_pmu {
+	interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>;
+};
+
+/delete-node/ &cpu3;
+
+&sdmmc0 {
+	status = "disabled";
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3562-rk817-tablet-v10.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3562-rk817-tablet-v10.dts
index 281b651..4f9edc0 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3562-rk817-tablet-v10.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3562-rk817-tablet-v10.dts
@@ -209,18 +209,6 @@
 	cpu-supply = <&vdd_cpu>;
 };
 
-&bus_soc {
-	rockchip,soc-bus-table = <0 0x00a000a8 0x7001>,
-				 <1 0x00a000a8 0x7c39>,
-				 <2 0x00a000a8 0x7c39>,
-				 <3 0x00a000a8 0x7c39>,
-				 <4 0x00a000a5 0xb007>,
-				 <5 0x00a000a8 0x7034>,
-				 <6 0x00a000a8 0x7034>,
-				 <7 0x00a000a8 0x7034>,
-				 <8 0x00a000a8 0x7001>;
-};
-
 &dfi {
 	status = "okay";
 };
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3562.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3562.dtsi
index 6908ef1..7c15aba 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3562.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3562.dtsi
@@ -9,6 +9,7 @@
 #include <dt-bindings/phy/phy.h>
 #include <dt-bindings/power/rk3562-power.h>
 #include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip-csu.h>
 #include <dt-bindings/soc/rockchip,boot-mode.h>
 #include <dt-bindings/soc/rockchip-system-status.h>
 #include <dt-bindings/suspend/rockchip-rk3562.h>
@@ -361,20 +362,6 @@
 		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
 	};
 
-	bus_soc: bus-soc {
-		compatible = "rockchip,rk3562-bus";
-		rockchip,busfreq-policy = "smc";
-		rockchip,soc-bus-table = <0 0x00a000a8 0x7001>,
-					 <1 0x00a000a8 0x7c39>,
-					 <2 0x00a000a8 0x7c39>,
-					 <3 0x00a000a8 0x7c39>,
-					 <4 0x00a000a4 0xb007>,
-					 <5 0x00a000a8 0x7034>,
-					 <6 0x00a000a8 0x7034>,
-					 <7 0x00a000a8 0x7034>,
-					 <8 0x00a000a8 0x7001>;
-	};
-
 	cpuinfo {
 		compatible = "rockchip,cpuinfo";
 		nvmem-cells = <&otp_id>, <&otp_cpu_version>, <&cpu_code>;
@@ -421,6 +408,23 @@
 		compatible = "rockchip,rk3562-csi2-dphy";
 		rockchip,hw = <&csi2_dphy0_hw>, <&csi2_dphy1_hw>;
 		status = "disabled";
+	};
+
+	csu: csu {
+		compatible = "rockchip,rk3562-csu";
+		rockchip,clock = <CSU_GMAC_ACLK  1>,
+				 <CSU_GMAC_PCLK  3>,
+				 <CSU_VOP_ACLK   4>,
+				 <CSU_MCU_CLK    2>;
+		rockchip,bus = <0 0x00a000a8 0x7001>,
+			       <1 0x00a000a8 0x7c39>,
+			       <2 0x00a000a8 0x7c39>,
+			       <3 0x00a000a8 0x7c39>,
+			       <4 0x00a000a4 0xb007>,
+			       <5 0x00a000a8 0x7034>,
+			       <6 0x00a000a8 0x7034>,
+			       <7 0x00a000a8 0x7034>,
+			       <8 0x00a000a8 0x7001>;
 	};
 
 	display_subsystem: display-subsystem {
@@ -899,9 +903,19 @@
 		reg = <0x0 0xfee03800 0x0 0x20>;
 	};
 
+	shaping_dam2ddr: shaping@fee03888 {
+		compatible = "syscon";
+		reg = <0x0 0xfee03888 0x0 0x4>;
+	};
+
 	qos_mcu: qos@fee10000 {
 		compatible = "syscon";
 		reg = <0x0 0xfee10000 0x0 0x20>;
+	};
+
+	shaping_mcu: shaping@fee10088 {
+		compatible = "syscon";
+		reg = <0x0 0xfee10088 0x0 0x4>;
 	};
 
 	qos_dft_apb: qos@fee10100 {
@@ -909,14 +923,29 @@
 		reg = <0x0 0xfee10100 0x0 0x20>;
 	};
 
+	shaping_dft_apb: shaping@fee10188 {
+		compatible = "syscon";
+		reg = <0x0 0xfee10188 0x0 0x4>;
+	};
+
 	qos_gmac: qos@fee10200 {
 		compatible = "syscon";
 		reg = <0x0 0xfee10200 0x0 0x20>;
 	};
 
+	shaping_gmac: shaping@fee10288 {
+		compatible = "syscon";
+		reg = <0x0 0xfee10288 0x0 0x4>;
+	};
+
 	qos_mac100: qos@fee10300 {
 		compatible = "syscon";
 		reg = <0x0 0xfee10300 0x0 0x20>;
+	};
+
+	shaping_mac100: shaping@fee10388 {
+		compatible = "syscon";
+		reg = <0x0 0xfee10388 0x0 0x4>;
 	};
 
 	qos_dcf: qos@fee10400 {
@@ -929,9 +958,19 @@
 		reg = <0x0 0xfee20000 0x0 0x20>;
 	};
 
+	shaping_cpu: shaping@fee20088 {
+		compatible = "syscon";
+		reg = <0x0 0xfee20088 0x0 0x4>;
+	};
+
 	qos_daplite_apb: qos@fee20100 {
 		compatible = "syscon";
 		reg = <0x0 0xfee20100 0x0 0x20>;
+	};
+
+	shaping_daplite_apb: shaping@fee20188 {
+		compatible = "syscon";
+		reg = <0x0 0xfee20188 0x0 0x4>;
 	};
 
 	qos_gpu: qos@fee30000 {
@@ -940,9 +979,19 @@
 		priority-init = <0x202>;
 	};
 
+	shaping_gpu: shaping@fee30088 {
+		compatible = "syscon";
+		reg = <0x0 0xfee30088 0x0 0x4>;
+	};
+
 	qos_npu: qos@fee40000 {
 		compatible = "syscon";
 		reg = <0x0 0xfee40000 0x0 0x20>;
+	};
+
+	shaping_npu: shaping@fee40088 {
+		compatible = "syscon";
+		reg = <0x0 0xfee40088 0x0 0x4>;
 	};
 
 	qos_rkvdec: qos@fee50000 {
@@ -950,9 +999,19 @@
 		reg = <0x0 0xfee50000 0x0 0x20>;
 	};
 
+	shaping_rkvdec: shaping@fee50088 {
+		compatible = "syscon";
+		reg = <0x0 0xfee50088 0x0 0x4>;
+	};
+
 	qos_vepu: qos@fee60000 {
 		compatible = "syscon";
 		reg = <0x0 0xfee60000 0x0 0x20>;
+	};
+
+	shaping_vepu: shaping@fee60088 {
+		compatible = "syscon";
+		reg = <0x0 0xfee60088 0x0 0x4>;
 	};
 
 	qos_isp: qos@fee70000 {
@@ -960,9 +1019,19 @@
 		reg = <0x0 0xfee70000 0x0 0x20>;
 	};
 
+	shaping_isp: shaping@fee70088 {
+		compatible = "syscon";
+		reg = <0x0 0xfee70088 0x0 0x4>;
+	};
+
 	qos_vicap: qos@fee70100 {
 		compatible = "syscon";
 		reg = <0x0 0xfee70100 0x0 0x20>;
+	};
+
+	shaping_vicap: shaping@fee70188 {
+		compatible = "syscon";
+		reg = <0x0 0xfee70188 0x0 0x4>;
 	};
 
 	qos_vop: qos@fee80000 {
@@ -970,9 +1039,19 @@
 		reg = <0x0 0xfee80000 0x0 0x20>;
 	};
 
+	shaping_vop: shaping@fee80088 {
+		compatible = "syscon";
+		reg = <0x0 0xfee80088 0x0 0x4>;
+	};
+
 	qos_jpeg: qos@fee90000 {
 		compatible = "syscon";
 		reg = <0x0 0xfee90000 0x0 0x20>;
+	};
+
+	shaping_jpeg: shaping@fee90088 {
+		compatible = "syscon";
+		reg = <0x0 0xfee90088 0x0 0x4>;
 	};
 
 	qos_rga_rd: qos@fee90100 {
@@ -980,9 +1059,19 @@
 		reg = <0x0 0xfee90100 0x0 0x20>;
 	};
 
+	shaping_rga_rd: shaping@fee90188 {
+		compatible = "syscon";
+		reg = <0x0 0xfee90188 0x0 0x4>;
+	};
+
 	qos_rga_wr: qos@fee90200 {
 		compatible = "syscon";
 		reg = <0x0 0xfee90200 0x0 0x20>;
+	};
+
+	shaping_rga_wr: shaping@fee90288 {
+		compatible = "syscon";
+		reg = <0x0 0xfee90288 0x0 0x4>;
 	};
 
 	qos_pcie: qos@feea0000 {
@@ -990,9 +1079,20 @@
 		reg = <0x0 0xfeea0000 0x0 0x20>;
 	};
 
+	shaping_pcie: shaping@feea0088 {
+		compatible = "syscon";
+		reg = <0x0 0xfeea0088 0x0 0x4>;
+		shaping-init = <0x5>;
+	};
+
 	qos_usb3: qos@feea0100 {
 		compatible = "syscon";
 		reg = <0x0 0xfeea0100 0x0 0x20>;
+	};
+
+	shaping_usb3: shaping@feea0188 {
+		compatible = "syscon";
+		reg = <0x0 0xfeea0188 0x0 0x4>;
 	};
 
 	qos_crypto_apb: qos@feeb0000 {
@@ -1000,9 +1100,19 @@
 		reg = <0x0 0xfeeb0000 0x0 0x20>;
 	};
 
+	shaping_crypto_apb: shaping@feeb0088 {
+		compatible = "syscon";
+		reg = <0x0 0xfeeb0088 0x0 0x4>;
+	};
+
 	qos_crypto: qos@feeb0100 {
 		compatible = "syscon";
 		reg = <0x0 0xfeeb0100 0x0 0x20>;
+	};
+
+	shaping_crypto: shaping@feeb0188 {
+		compatible = "syscon";
+		reg = <0x0 0xfeeb0188 0x0 0x4>;
 	};
 
 	qos_dmac: qos@feeb0200 {
@@ -1010,9 +1120,19 @@
 		reg = <0x0 0xfeeb0200 0x0 0x20>;
 	};
 
+	shaping_dmac: shaping@feeb0288 {
+		compatible = "syscon";
+		reg = <0x0 0xfeeb0288 0x0 0x4>;
+	};
+
 	qos_emmc: qos@feeb0300 {
 		compatible = "syscon";
 		reg = <0x0 0xfeeb0300 0x0 0x20>;
+	};
+
+	shaping_emmc: shaping@feeb0388 {
+		compatible = "syscon";
+		reg = <0x0 0xfeeb0388 0x0 0x4>;
 	};
 
 	qos_fspi: qos@feeb0400 {
@@ -1020,9 +1140,19 @@
 		reg = <0x0 0xfeeb0400 0x0 0x20>;
 	};
 
+	shaping_fspi: shaping@feeb0488 {
+		compatible = "syscon";
+		reg = <0x0 0xfeeb0488 0x0 0x4>;
+	};
+
 	qos_rkdma: qos@feeb0500 {
 		compatible = "syscon";
 		reg = <0x0 0xfeeb0500 0x0 0x20>;
+	};
+
+	shaping_rkdma: shaping@feeb0588 {
+		compatible = "syscon";
+		reg = <0x0 0xfeeb0588 0x0 0x4>;
 	};
 
 	qos_sdmmc0: qos@feeb0600 {
@@ -1030,14 +1160,29 @@
 		reg = <0x0 0xfeeb0600 0x0 0x20>;
 	};
 
+	shaping_sdmmc0: shaping@feeb0688 {
+		compatible = "syscon";
+		reg = <0x0 0xfeeb0688 0x0 0x4>;
+	};
+
 	qos_sdmmc1: qos@feeb0700 {
 		compatible = "syscon";
 		reg = <0x0 0xfeeb0700 0x0 0x20>;
 	};
 
+	shaping_sdmmc1: shaping@feeb0788 {
+		compatible = "syscon";
+		reg = <0x0 0xfeeb0788 0x0 0x4>;
+	};
+
 	qos_usb2: qos@feeb0800 {
 		compatible = "syscon";
 		reg = <0x0 0xfeeb0800 0x0 0x20>;
+	};
+
+	shaping_usb2: shaping@feeb0888 {
+		compatible = "syscon";
+		reg = <0x0 0xfeeb0888 0x0 0x4>;
 	};
 
 	pmu_grf: syscon@ff010000 {
@@ -1250,16 +1395,19 @@
 			pd_gpu@RK3562_PD_GPU {
 				reg = <RK3562_PD_GPU>;
 				pm_qos = <&qos_gpu>;
+				pm_shaping = <&shaping_gpu>;
 			};
 			/* These power domains are grouped by VD_NPU */
 			pd_npu@RK3562_PD_NPU {
 				reg = <RK3562_PD_NPU>;
 				pm_qos = <&qos_npu>;
+				pm_shaping = <&shaping_npu>;
 			};
 			/* These power domains are grouped by VD_LOGIC */
 			pd_vdpu@RK3562_PD_VDPU {
 				reg = <RK3562_PD_VDPU>;
 				pm_qos = <&qos_rkvdec>;
+				pm_shaping = <&shaping_rkvdec>;
 			};
 			pd_vi@RK3562_PD_VI {
 				reg = <RK3562_PD_VI>;
@@ -1267,10 +1415,13 @@
 				#size-cells = <0>;
 				pm_qos = <&qos_isp>,
 					 <&qos_vicap>;
+				pm_shaping = <&shaping_isp>,
+					     <&shaping_vicap>;
 
 				pd_vepu@RK3562_PD_VEPU {
 					reg = <RK3562_PD_VEPU>;
 					pm_qos = <&qos_vepu>;
+					pm_shaping = <&shaping_vepu>;
 				};
 			};
 			pd_vo@RK3562_PD_VO {
@@ -1278,18 +1429,24 @@
 				#address-cells = <1>;
 				#size-cells = <0>;
 				pm_qos = <&qos_vop>;
+				pm_shaping= <&shaping_vop>;
 
 				pd_rga@RK3562_PD_RGA {
 					reg = <RK3562_PD_RGA>;
 					pm_qos = <&qos_rga_rd>,
 						 <&qos_rga_wr>,
 						 <&qos_jpeg>;
+					pm_shaping = <&shaping_rga_rd>,
+						     <&shaping_rga_wr>,
+						     <&shaping_jpeg>;
 				};
 			};
 			pd_php@RK3562_PD_PHP {
 				reg = <RK3562_PD_PHP>;
 				pm_qos = <&qos_pcie>,
 					 <&qos_usb3>;
+				pm_shaping = <&shaping_pcie>,
+					     <&shaping_usb3>;
 			};
 		};
 	};
@@ -1743,6 +1900,8 @@
 		reset-names = "axi",
 			      "ahb",
 			      "dclk_vp0";
+		rockchip,csu = <&csu CSU_VOP_ACLK>;
+		rockchip,csu-names = "aclk";
 		iommus = <&vop_mmu>;
 		power-domains = <&power RK3562_PD_VO>;
 		rockchip,grf = <&ioc_grf>;
@@ -2684,6 +2843,8 @@
 			      "pclk_mac", "aclk_mac";
 		resets = <&cru SRST_A_GMAC>;
 		reset-names = "stmmaceth";
+		rockchip,csu = <&csu CSU_GMAC_ACLK>, <&csu CSU_GMAC_PCLK>;
+		rockchip,csu-names = "aclk", "pclk";
 
 		snps,mixed-burst;
 		snps,tso;
@@ -2802,6 +2963,8 @@
 			      "pclk_mac", "aclk_mac";
 		resets = <&cru SRST_A_MAC100>;
 		reset-names = "stmmaceth";
+		rockchip,csu = <&csu CSU_GMAC_ACLK>, <&csu CSU_GMAC_PCLK>;
+		rockchip,csu-names = "aclk", "pclk";
 		status = "disabled";
 
 		mdio1: mdio {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3566-box.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3566-box.dtsi
index ae29685..77189ab 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3566-box.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3566-box.dtsi
@@ -42,7 +42,7 @@
 		status = "disabled";
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "dsp_a";
-		simple-audio-card,bitclock-inversion = <0>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <256>;
 		simple-audio-card,name = "rockchip,bt";
 		simple-audio-card,cpu {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3566-evb2-lp4x-v10-edp.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3566-evb2-lp4x-v10-edp.dts
index d9db92b..d441e55 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3566-evb2-lp4x-v10-edp.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3566-evb2-lp4x-v10-edp.dts
@@ -15,6 +15,8 @@
 		enable-delay-ms = <120>;
 		unprepare-delay-ms = <120>;
 		disable-delay-ms = <120>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		panel-timing {
 			clock-frequency = <200000000>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-channel-lvds.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-channel-lvds.dts
index 04043c5..e6972db 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-channel-lvds.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-channel-lvds.dts
@@ -70,68 +70,14 @@
 	};
 };
 
-&backlight1 {
-	status = "okay";
-};
-
 &backlight {
 	status = "okay";
 };
 
-&lvds {
-	status = "okay";
-	dual-channel;
-
-	ports {
-		port@1 {
-			reg = <1>;
-			lvds0_out_panel: endpoint {
-				remote-endpoint = <&panel_in_lvds0>;
-			};
-		};
-	};
-};
-
-&lvds1 {
-	status = "okay";
-
-	ports {
-		port@1 {
-			reg = <1>;
-			lvds1_out_panel: endpoint {
-				remote-endpoint = <&panel_in_lvds1>;
-			};
-		};
-	};
-};
-
-&lvds_in_vp1 {
+&backlight1 {
 	status = "okay";
 };
 
-&lvds1_in_vp1 {
-	status = "disabled";
-};
-
-&lvds1_in_vp2 {
-	status = "okay";
-};
-
-/* enable hdmi */
-&hdmi_in_vp1 {
-	status = "okay";
-};
-
-/* enable video phy */
-&video_phy0 {
-	status = "okay";
-};
-
-&video_phy1 {
-	status = "okay";
-};
-
-/* disable other encoder output */
 &dsi0 {
 	status = "disabled";
 };
@@ -152,10 +98,52 @@
 	status = "disabled";
 };
 
-&rgb_in_vp2 {
+&hdmi_in_vp1 {
+	status = "okay";
+};
+
+&lvds0 {
+	status = "okay";
+	dual-channel;
+
+	ports {
+		port@1 {
+			reg = <1>;
+			lvds0_out_panel: endpoint {
+				remote-endpoint = <&panel_in_lvds0>;
+			};
+		};
+	};
+};
+
+&lvds0_in_vp1 {
+	status = "okay";
+};
+
+&lvds1 {
+	status = "okay";
+
+	ports {
+		port@1 {
+			reg = <1>;
+			lvds1_out_panel: endpoint {
+				remote-endpoint = <&panel_in_lvds1>;
+			};
+		};
+	};
+};
+
+&lvds1_in_vp1 {
+	status = "okay";
+};
+
+&lvds1_in_vp2 {
 	status = "disabled";
 };
 
+&rgb_in_vp2 {
+	status = "disabled";
+};
 
 &vcc3v3_lcd0_n {
 	gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
@@ -166,3 +154,11 @@
 	gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
 	enable-active-high;
 };
+
+&video_phy0 {
+	status = "okay";
+};
+
+&video_phy1 {
+	status = "okay";
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-one-vp-two-single-channel-lvds.dts
similarity index 87%
rename from kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts
rename to kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-one-vp-two-single-channel-lvds.dts
index d50ccd3..30f9109 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-one-vp-two-single-channel-lvds.dts
@@ -13,9 +13,10 @@
 #include "rk3568-android.dtsi"
 
 / {
-	model = "Rockchip RK3567 EVB2 LP4X V10 Board";
-	compatible = "rockchip,rk3567-evb2-lp4x-v10", "rockchip,rk3567";
+	model = "Rockchip RK3567 EVB2 LP4X V10 Board with one vp two single channel lvds";
+	compatible = "rockchip,rk3567-evb2-lp4x-v10-one-vp-two-single-channel-lvds", "rockchip,rk3567";
 
+	/* panel: claa070wp03xg */
 	panel {
 		compatible = "simple-panel";
 		backlight = <&backlight>;
@@ -33,14 +34,14 @@
 
 			timing0: timing0 {
 				clock-frequency = <134000000>;
-				hactive = <1600>;
+				hactive = <1600>; /* each panel show 1600 / 2 = 800 pxiel */
 				vactive = <1280>;
 				hback-porch = <60>;
 				hfront-porch = <60>;
 				vback-porch = <4>;
 				vfront-porch = <2>;
 				hsync-len = <8>;
-				vsync-len = <2>;
+				vsync-len = <8>;
 				hsync-active = <0>;
 				vsync-active = <0>;
 				de-active = <0>;
@@ -74,15 +75,39 @@
 	};
 };
 
-&backlight1 {
-	status = "okay";
-};
-
 &backlight {
 	status = "okay";
 };
 
-&lvds {
+&backlight1 {
+	status = "okay";
+};
+
+&dsi0 {
+	status = "disabled";
+};
+
+&dsi0_in_vp0 {
+	status = "disabled";
+};
+
+&dsi0_in_vp1 {
+	status = "disabled";
+};
+
+&dsi1_in_vp1 {
+	status = "disabled";
+};
+
+&edp_in_vp1 {
+	status = "disabled";
+};
+
+&hdmi_in_vp1 {
+	status = "okay";
+};
+
+&lvds0 {
 	status = "okay";
 	dual-channel;
 
@@ -109,57 +134,21 @@
 	};
 };
 
-&lvds_in_vp1 {
+&lvds0_in_vp1 {
 	status = "okay";
 };
 
 &lvds1_in_vp1 {
-	status = "disabled";
+	status = "okay";
 };
 
 &lvds1_in_vp2 {
-	status = "okay";
-};
-
-/* enable hdmi */
-&hdmi_in_vp1 {
-	status = "okay";
-};
-
-/* enable video phy */
-&video_phy0 {
-	status = "okay";
-};
-
-&video_phy1 {
-	status = "okay";
-};
-
-/* disable other encoder output */
-&dsi0 {
-	status = "disabled";
-};
-
-&dsi0_in_vp0 {
-	status = "disabled";
-};
-
-&dsi0_in_vp1 {
-	status = "disabled";
-};
-
-&dsi1_in_vp1 {
-	status = "disabled";
-};
-
-&edp_in_vp1 {
 	status = "disabled";
 };
 
 &rgb_in_vp2 {
 	status = "disabled";
 };
-
 
 &vcc3v3_lcd0_n {
 	gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
@@ -170,3 +159,11 @@
 	gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
 	enable-active-high;
 };
+
+&video_phy0 {
+	status = "okay";
+};
+
+&video_phy1 {
+	status = "okay";
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-single-channel-lvds.dts
similarity index 71%
copy from kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts
copy to kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-single-channel-lvds.dts
index d50ccd3..85621d5 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-single-channel-lvds.dts
@@ -13,9 +13,10 @@
 #include "rk3568-android.dtsi"
 
 / {
-	model = "Rockchip RK3567 EVB2 LP4X V10 Board";
-	compatible = "rockchip,rk3567-evb2-lp4x-v10", "rockchip,rk3567";
+	model = "Rockchip RK3567 EVB2 LP4X V10 Board with single channel lvds";
+	compatible = "rockchip,rk3567-evb2-lp4x-v10-single-channel-lvds", "rockchip,rk3567";
 
+	/* panel: claa070wp03xg */
 	panel {
 		compatible = "simple-panel";
 		backlight = <&backlight>;
@@ -30,17 +31,16 @@
 
 		display-timings {
 			native-mode = <&timing0>;
-
 			timing0: timing0 {
-				clock-frequency = <134000000>;
-				hactive = <1600>;
+				clock-frequency = <67000000>;
+				hactive = <800>;
 				vactive = <1280>;
 				hback-porch = <60>;
 				hfront-porch = <60>;
 				vback-porch = <4>;
 				vfront-porch = <2>;
 				hsync-len = <8>;
-				vsync-len = <2>;
+				vsync-len = <8>;
 				hsync-active = <0>;
 				vsync-active = <0>;
 				de-active = <0>;
@@ -51,91 +51,24 @@
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
-
-			/**
-			 *  Panel <----> LVDS0
-			 *  Panel <----> LVDS1
-			 */
 			port@0 {
 				reg = <0>;
-				dual-lvds-left-pixels;
 				panel_in_lvds0: endpoint {
 					remote-endpoint = <&lvds0_out_panel>;
 				};
 			};
-			port@1 {
-				reg = <1>;
-				dual-lvds-right-pixels;
-				panel_in_lvds1: endpoint {
-					remote-endpoint = <&lvds1_out_panel>;
-				};
-			};
 		};
 	};
-};
-
-&backlight1 {
-	status = "okay";
 };
 
 &backlight {
 	status = "okay";
 };
 
-&lvds {
-	status = "okay";
-	dual-channel;
-
-	ports {
-		port@1 {
-			reg = <1>;
-			lvds0_out_panel: endpoint {
-				remote-endpoint = <&panel_in_lvds0>;
-			};
-		};
-	};
-};
-
-&lvds1 {
-	status = "okay";
-
-	ports {
-		port@1 {
-			reg = <1>;
-			lvds1_out_panel: endpoint {
-				remote-endpoint = <&panel_in_lvds1>;
-			};
-		};
-	};
-};
-
-&lvds_in_vp1 {
+&backlight1 {
 	status = "okay";
 };
 
-&lvds1_in_vp1 {
-	status = "disabled";
-};
-
-&lvds1_in_vp2 {
-	status = "okay";
-};
-
-/* enable hdmi */
-&hdmi_in_vp1 {
-	status = "okay";
-};
-
-/* enable video phy */
-&video_phy0 {
-	status = "okay";
-};
-
-&video_phy1 {
-	status = "okay";
-};
-
-/* disable other encoder output */
 &dsi0 {
 	status = "disabled";
 };
@@ -156,10 +89,33 @@
 	status = "disabled";
 };
 
-&rgb_in_vp2 {
+&hdmi_in_vp1 {
+	status = "okay";
+};
+
+&lvds0 {
+	status = "okay";
+	ports {
+		port@1 {
+			reg = <1>;
+			lvds0_out_panel: endpoint {
+				remote-endpoint = <&panel_in_lvds0>;
+			};
+		};
+	};
+};
+
+&lvds0_in_vp1 {
+	status = "okay";
+};
+
+&lvds1 {
 	status = "disabled";
 };
 
+&rgb_in_vp2 {
+	status = "disabled";
+};
 
 &vcc3v3_lcd0_n {
 	gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
@@ -170,3 +126,11 @@
 	gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
 	enable-active-high;
 };
+
+&video_phy0 {
+	status = "okay";
+};
+
+&video_phy1 {
+	status = "okay";
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-two-vp-two-separate-single-channel-lvds.dts
similarity index 63%
copy from kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts
copy to kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-two-vp-two-separate-single-channel-lvds.dts
index d50ccd3..9f3e37e 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-two-vp-two-separate-single-channel-lvds.dts
@@ -13,10 +13,16 @@
 #include "rk3568-android.dtsi"
 
 / {
-	model = "Rockchip RK3567 EVB2 LP4X V10 Board";
-	compatible = "rockchip,rk3567-evb2-lp4x-v10", "rockchip,rk3567";
+	model = "Rockchip RK3567 EVB2 LP4X V10 Board with two vp two separate single channel lvds";
+	compatible = "rockchip,rk3567-evb2-lp4x-v10-two-vp-two-separate-single-channel-lvds", "rockchip,rk3567";
 
-	panel {
+	/**
+	 * VP1 -> LVDS0 -> Panel0
+	 * VP2 -> LVDS1 -> Panel1
+	 */
+
+	/* panel: claa070wp03xg */
+	panel-lvds0 {
 		compatible = "simple-panel";
 		backlight = <&backlight>;
 		power-supply = <&vcc3v3_lcd0_n>;
@@ -30,17 +36,16 @@
 
 		display-timings {
 			native-mode = <&timing0>;
-
 			timing0: timing0 {
-				clock-frequency = <134000000>;
-				hactive = <1600>;
+				clock-frequency = <67000000>;
+				hactive = <800>;
 				vactive = <1280>;
 				hback-porch = <60>;
 				hfront-porch = <60>;
 				vback-porch = <4>;
 				vfront-porch = <2>;
 				hsync-len = <8>;
-				vsync-len = <2>;
+				vsync-len = <8>;
 				hsync-active = <0>;
 				vsync-active = <0>;
 				de-active = <0>;
@@ -51,21 +56,52 @@
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
-
-			/**
-			 *  Panel <----> LVDS0
-			 *  Panel <----> LVDS1
-			 */
 			port@0 {
 				reg = <0>;
-				dual-lvds-left-pixels;
 				panel_in_lvds0: endpoint {
 					remote-endpoint = <&lvds0_out_panel>;
 				};
 			};
-			port@1 {
-				reg = <1>;
-				dual-lvds-right-pixels;
+		};
+	};
+
+	/* panel: claa070wp03xg */
+	panel-lvds1 {
+		compatible = "simple-panel";
+		backlight = <&backlight1>;
+		power-supply = <&vcc3v3_lcd1_n>;
+		enable-delay-ms = <20>;
+		prepare-delay-ms = <20>;
+		unprepare-delay-ms = <20>;
+		disable-delay-ms = <20>;
+		bus-format = <MEDIA_BUS_FMT_RGB666_1X7X3_SPWG>;
+		width-mm = <217>;
+		height-mm = <136>;
+
+		display-timings {
+			native-mode = <&timing1>;
+			timing1: timing1 {
+				clock-frequency = <67000000>;
+				hactive = <800>;
+				vactive = <1280>;
+				hback-porch = <60>;
+				hfront-porch = <60>;
+				vback-porch = <4>;
+				vfront-porch = <2>;
+				hsync-len = <8>;
+				vsync-len = <8>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <0>;
+				pixelclk-active = <0>;
+			};
+		};
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
 				panel_in_lvds1: endpoint {
 					remote-endpoint = <&lvds1_out_panel>;
 				};
@@ -74,68 +110,14 @@
 	};
 };
 
-&backlight1 {
-	status = "okay";
-};
-
 &backlight {
 	status = "okay";
 };
 
-&lvds {
-	status = "okay";
-	dual-channel;
-
-	ports {
-		port@1 {
-			reg = <1>;
-			lvds0_out_panel: endpoint {
-				remote-endpoint = <&panel_in_lvds0>;
-			};
-		};
-	};
-};
-
-&lvds1 {
-	status = "okay";
-
-	ports {
-		port@1 {
-			reg = <1>;
-			lvds1_out_panel: endpoint {
-				remote-endpoint = <&panel_in_lvds1>;
-			};
-		};
-	};
-};
-
-&lvds_in_vp1 {
+&backlight1 {
 	status = "okay";
 };
 
-&lvds1_in_vp1 {
-	status = "disabled";
-};
-
-&lvds1_in_vp2 {
-	status = "okay";
-};
-
-/* enable hdmi */
-&hdmi_in_vp1 {
-	status = "okay";
-};
-
-/* enable video phy */
-&video_phy0 {
-	status = "okay";
-};
-
-&video_phy1 {
-	status = "okay";
-};
-
-/* disable other encoder output */
 &dsi0 {
 	status = "disabled";
 };
@@ -156,10 +138,49 @@
 	status = "disabled";
 };
 
-&rgb_in_vp2 {
+&hdmi_in_vp1 {
+	status = "okay";
+};
+
+&lvds0 {
+	status = "okay";
+	ports {
+		port@1 {
+			reg = <1>;
+			lvds0_out_panel: endpoint {
+				remote-endpoint = <&panel_in_lvds0>;
+			};
+		};
+	};
+};
+
+&lvds0_in_vp1 {
+	status = "okay";
+};
+
+&lvds1 {
+	status = "okay";
+	ports {
+		port@1 {
+			reg = <1>;
+			lvds1_out_panel: endpoint {
+				remote-endpoint = <&panel_in_lvds1>;
+			};
+		};
+	};
+};
+
+&lvds1_in_vp1 {
 	status = "disabled";
 };
 
+&lvds1_in_vp2 {
+	status = "okay";
+};
+
+&rgb_in_vp2 {
+	status = "disabled";
+};
 
 &vcc3v3_lcd0_n {
 	gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
@@ -170,3 +191,11 @@
 	gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
 	enable-active-high;
 };
+
+&video_phy0 {
+	status = "okay";
+};
+
+&video_phy1 {
+	status = "okay";
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb.dtsi
old mode 100755
new mode 100644
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds-linux.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds-linux.dts
new file mode 100644
index 0000000..fb33ac5
--- /dev/null
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds-linux.dts
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/display/rockchip_vop.h>
+#include "rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dtsi"
+#include "rk3568-linux.dtsi"
+
+/ {
+	model = "Rockchip RK3568 EVB1 V10 Board with one vp two single channel lvds";
+	compatible = "rockchip,rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds", "rockchip,rk3568";
+};
+
+&vp0 {
+	cursor-win-id = <ROCKCHIP_VOP2_CLUSTER0>;
+};
+
+&vp1 {
+	cursor-win-id = <ROCKCHIP_VOP2_CLUSTER1>;
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dts
new file mode 100644
index 0000000..43b0df3
--- /dev/null
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+/dts-v1/;
+
+#include "rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dtsi"
+#include "rk3568-android.dtsi"
+
+/ {
+	model = "Rockchip RK3568 EVB1 V10 Board with one vp two single channel lvds";
+	compatible = "rockchip,rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds", "rockchip,rk3568";
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dtsi
similarity index 86%
copy from kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts
copy to kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dtsi
index d50ccd3..51e1d19 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dtsi
@@ -3,19 +3,13 @@
  * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
  */
 
-/dts-v1/;
-
 #include <dt-bindings/display/media-bus-format.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/pinctrl/rockchip.h>
-
-#include "rk3567-evb2-lp4x-v10.dtsi"
-#include "rk3568-android.dtsi"
+#include "rk3568-evb1-ddr4-v10.dtsi"
 
 / {
-	model = "Rockchip RK3567 EVB2 LP4X V10 Board";
-	compatible = "rockchip,rk3567-evb2-lp4x-v10", "rockchip,rk3567";
-
+	/* panel: claa070wp03xg */
 	panel {
 		compatible = "simple-panel";
 		backlight = <&backlight>;
@@ -33,14 +27,14 @@
 
 			timing0: timing0 {
 				clock-frequency = <134000000>;
-				hactive = <1600>;
+				hactive = <1600>; /* each panel show 1600 / 2 = 800 pxiel */
 				vactive = <1280>;
 				hback-porch = <60>;
 				hfront-porch = <60>;
 				vback-porch = <4>;
 				vfront-porch = <2>;
 				hsync-len = <8>;
-				vsync-len = <2>;
+				vsync-len = <8>;
 				hsync-active = <0>;
 				vsync-active = <0>;
 				de-active = <0>;
@@ -74,68 +68,14 @@
 	};
 };
 
-&backlight1 {
-	status = "okay";
-};
-
 &backlight {
 	status = "okay";
 };
 
-&lvds {
-	status = "okay";
-	dual-channel;
-
-	ports {
-		port@1 {
-			reg = <1>;
-			lvds0_out_panel: endpoint {
-				remote-endpoint = <&panel_in_lvds0>;
-			};
-		};
-	};
-};
-
-&lvds1 {
-	status = "okay";
-
-	ports {
-		port@1 {
-			reg = <1>;
-			lvds1_out_panel: endpoint {
-				remote-endpoint = <&panel_in_lvds1>;
-			};
-		};
-	};
-};
-
-&lvds_in_vp1 {
+&backlight1 {
 	status = "okay";
 };
 
-&lvds1_in_vp1 {
-	status = "disabled";
-};
-
-&lvds1_in_vp2 {
-	status = "okay";
-};
-
-/* enable hdmi */
-&hdmi_in_vp1 {
-	status = "okay";
-};
-
-/* enable video phy */
-&video_phy0 {
-	status = "okay";
-};
-
-&video_phy1 {
-	status = "okay";
-};
-
-/* disable other encoder output */
 &dsi0 {
 	status = "disabled";
 };
@@ -156,10 +96,52 @@
 	status = "disabled";
 };
 
-&rgb_in_vp2 {
+&hdmi_in_vp1 {
+	status = "okay";
+};
+
+&lvds0 {
+	status = "okay";
+	dual-channel;
+
+	ports {
+		port@1 {
+			reg = <1>;
+			lvds0_out_panel: endpoint {
+				remote-endpoint = <&panel_in_lvds0>;
+			};
+		};
+	};
+};
+
+&lvds0_in_vp1 {
+	status = "okay";
+};
+
+&lvds1 {
+	status = "okay";
+
+	ports {
+		port@1 {
+			reg = <1>;
+			lvds1_out_panel: endpoint {
+				remote-endpoint = <&panel_in_lvds1>;
+			};
+		};
+	};
+};
+
+&lvds1_in_vp1 {
+	status = "okay";
+};
+
+&lvds1_in_vp2 {
 	status = "disabled";
 };
 
+&rgb_in_vp2 {
+	status = "disabled";
+};
 
 &vcc3v3_lcd0_n {
 	gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
@@ -170,3 +152,11 @@
 	gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
 	enable-active-high;
 };
+
+&video_phy0 {
+	status = "okay";
+};
+
+&video_phy1 {
+	status = "okay";
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-single-channel-lvds.dts
similarity index 69%
copy from kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts
copy to kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-single-channel-lvds.dts
index d50ccd3..e0f543a 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-single-channel-lvds.dts
@@ -3,20 +3,18 @@
  * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
  */
 
-/dts-v1/;
-
 #include <dt-bindings/display/media-bus-format.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/pinctrl/rockchip.h>
-
-#include "rk3567-evb2-lp4x-v10.dtsi"
+#include "rk3568-evb1-ddr4-v10.dtsi"
 #include "rk3568-android.dtsi"
 
 / {
-	model = "Rockchip RK3567 EVB2 LP4X V10 Board";
-	compatible = "rockchip,rk3567-evb2-lp4x-v10", "rockchip,rk3567";
+	model = "Rockchip RK3568 EVB1 V10 Board with single channel lvds";
+	compatible = "rockchip,rk3568-evb1-ddr4-v10-single-channel-lvds", "rockchip,rk3568";
 
-	panel {
+	/* panel: claa070wp03xg */
+	panel-lvds0 {
 		compatible = "simple-panel";
 		backlight = <&backlight>;
 		power-supply = <&vcc3v3_lcd0_n>;
@@ -30,17 +28,16 @@
 
 		display-timings {
 			native-mode = <&timing0>;
-
 			timing0: timing0 {
-				clock-frequency = <134000000>;
-				hactive = <1600>;
+				clock-frequency = <67000000>;
+				hactive = <800>;
 				vactive = <1280>;
 				hback-porch = <60>;
 				hfront-porch = <60>;
 				vback-porch = <4>;
 				vfront-porch = <2>;
 				hsync-len = <8>;
-				vsync-len = <2>;
+				vsync-len = <8>;
 				hsync-active = <0>;
 				vsync-active = <0>;
 				de-active = <0>;
@@ -51,91 +48,24 @@
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
-
-			/**
-			 *  Panel <----> LVDS0
-			 *  Panel <----> LVDS1
-			 */
 			port@0 {
 				reg = <0>;
-				dual-lvds-left-pixels;
 				panel_in_lvds0: endpoint {
 					remote-endpoint = <&lvds0_out_panel>;
 				};
 			};
-			port@1 {
-				reg = <1>;
-				dual-lvds-right-pixels;
-				panel_in_lvds1: endpoint {
-					remote-endpoint = <&lvds1_out_panel>;
-				};
-			};
 		};
 	};
-};
-
-&backlight1 {
-	status = "okay";
 };
 
 &backlight {
 	status = "okay";
 };
 
-&lvds {
-	status = "okay";
-	dual-channel;
-
-	ports {
-		port@1 {
-			reg = <1>;
-			lvds0_out_panel: endpoint {
-				remote-endpoint = <&panel_in_lvds0>;
-			};
-		};
-	};
-};
-
-&lvds1 {
-	status = "okay";
-
-	ports {
-		port@1 {
-			reg = <1>;
-			lvds1_out_panel: endpoint {
-				remote-endpoint = <&panel_in_lvds1>;
-			};
-		};
-	};
-};
-
-&lvds_in_vp1 {
+&backlight1 {
 	status = "okay";
 };
 
-&lvds1_in_vp1 {
-	status = "disabled";
-};
-
-&lvds1_in_vp2 {
-	status = "okay";
-};
-
-/* enable hdmi */
-&hdmi_in_vp1 {
-	status = "okay";
-};
-
-/* enable video phy */
-&video_phy0 {
-	status = "okay";
-};
-
-&video_phy1 {
-	status = "okay";
-};
-
-/* disable other encoder output */
 &dsi0 {
 	status = "disabled";
 };
@@ -156,10 +86,33 @@
 	status = "disabled";
 };
 
-&rgb_in_vp2 {
+&hdmi_in_vp1 {
+	status = "okay";
+};
+
+&lvds0 {
+	status = "okay";
+	ports {
+		port@1 {
+			reg = <1>;
+			lvds0_out_panel: endpoint {
+				remote-endpoint = <&panel_in_lvds0>;
+			};
+		};
+	};
+};
+
+&lvds0_in_vp1 {
+	status = "okay";
+};
+
+&lvds1 {
 	status = "disabled";
 };
 
+&rgb_in_vp2 {
+	status = "disabled";
+};
 
 &vcc3v3_lcd0_n {
 	gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
@@ -170,3 +123,11 @@
 	gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
 	enable-active-high;
 };
+
+&video_phy0 {
+	status = "okay";
+};
+
+&video_phy1 {
+	status = "okay";
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-two-vp-two-separate-single-channel-lvds.dts
similarity index 62%
copy from kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts
copy to kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-two-vp-two-separate-single-channel-lvds.dts
index d50ccd3..13d0f91 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-two-vp-two-separate-single-channel-lvds.dts
@@ -3,20 +3,23 @@
  * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
  */
 
-/dts-v1/;
-
 #include <dt-bindings/display/media-bus-format.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/pinctrl/rockchip.h>
-
-#include "rk3567-evb2-lp4x-v10.dtsi"
+#include "rk3568-evb1-ddr4-v10.dtsi"
 #include "rk3568-android.dtsi"
 
 / {
-	model = "Rockchip RK3567 EVB2 LP4X V10 Board";
-	compatible = "rockchip,rk3567-evb2-lp4x-v10", "rockchip,rk3567";
+	model = "Rockchip RK3568 EVB1 V10 Board with two vp two separate single channel lvds";
+	compatible = "rockchip,rk3568-evb1-ddr4-v10-two-vp-two-separate-single-channel-lvds", "rockchip,rk3568";
 
-	panel {
+	/**
+	 * VP1 -> LVDS0 -> Panel0
+	 * VP2 -> LVDS1 -> Panel1
+	 */
+
+	/* panel: claa070wp03xg */
+	panel-lvds0 {
 		compatible = "simple-panel";
 		backlight = <&backlight>;
 		power-supply = <&vcc3v3_lcd0_n>;
@@ -30,17 +33,16 @@
 
 		display-timings {
 			native-mode = <&timing0>;
-
 			timing0: timing0 {
-				clock-frequency = <134000000>;
-				hactive = <1600>;
+				clock-frequency = <67000000>;
+				hactive = <800>;
 				vactive = <1280>;
 				hback-porch = <60>;
 				hfront-porch = <60>;
 				vback-porch = <4>;
 				vfront-porch = <2>;
 				hsync-len = <8>;
-				vsync-len = <2>;
+				vsync-len = <8>;
 				hsync-active = <0>;
 				vsync-active = <0>;
 				de-active = <0>;
@@ -51,21 +53,52 @@
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
-
-			/**
-			 *  Panel <----> LVDS0
-			 *  Panel <----> LVDS1
-			 */
 			port@0 {
 				reg = <0>;
-				dual-lvds-left-pixels;
 				panel_in_lvds0: endpoint {
 					remote-endpoint = <&lvds0_out_panel>;
 				};
 			};
-			port@1 {
-				reg = <1>;
-				dual-lvds-right-pixels;
+		};
+	};
+
+	/* panel: claa070wp03xg */
+	panel-lvds1 {
+		compatible = "simple-panel";
+		backlight = <&backlight1>;
+		power-supply = <&vcc3v3_lcd1_n>;
+		enable-delay-ms = <20>;
+		prepare-delay-ms = <20>;
+		unprepare-delay-ms = <20>;
+		disable-delay-ms = <20>;
+		bus-format = <MEDIA_BUS_FMT_RGB666_1X7X3_SPWG>;
+		width-mm = <217>;
+		height-mm = <136>;
+
+		display-timings {
+			native-mode = <&timing1>;
+			timing1: timing1 {
+				clock-frequency = <67000000>;
+				hactive = <800>;
+				vactive = <1280>;
+				hback-porch = <60>;
+				hfront-porch = <60>;
+				vback-porch = <4>;
+				vfront-porch = <2>;
+				hsync-len = <8>;
+				vsync-len = <8>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <0>;
+				pixelclk-active = <0>;
+			};
+		};
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
 				panel_in_lvds1: endpoint {
 					remote-endpoint = <&lvds1_out_panel>;
 				};
@@ -74,68 +107,14 @@
 	};
 };
 
-&backlight1 {
-	status = "okay";
-};
-
 &backlight {
 	status = "okay";
 };
 
-&lvds {
-	status = "okay";
-	dual-channel;
-
-	ports {
-		port@1 {
-			reg = <1>;
-			lvds0_out_panel: endpoint {
-				remote-endpoint = <&panel_in_lvds0>;
-			};
-		};
-	};
-};
-
-&lvds1 {
-	status = "okay";
-
-	ports {
-		port@1 {
-			reg = <1>;
-			lvds1_out_panel: endpoint {
-				remote-endpoint = <&panel_in_lvds1>;
-			};
-		};
-	};
-};
-
-&lvds_in_vp1 {
+&backlight1 {
 	status = "okay";
 };
 
-&lvds1_in_vp1 {
-	status = "disabled";
-};
-
-&lvds1_in_vp2 {
-	status = "okay";
-};
-
-/* enable hdmi */
-&hdmi_in_vp1 {
-	status = "okay";
-};
-
-/* enable video phy */
-&video_phy0 {
-	status = "okay";
-};
-
-&video_phy1 {
-	status = "okay";
-};
-
-/* disable other encoder output */
 &dsi0 {
 	status = "disabled";
 };
@@ -156,10 +135,49 @@
 	status = "disabled";
 };
 
-&rgb_in_vp2 {
+&hdmi_in_vp1 {
+	status = "okay";
+};
+
+&lvds0 {
+	status = "okay";
+	ports {
+		port@1 {
+			reg = <1>;
+			lvds0_out_panel: endpoint {
+				remote-endpoint = <&panel_in_lvds0>;
+			};
+		};
+	};
+};
+
+&lvds0_in_vp1 {
+	status = "okay";
+};
+
+&lvds1 {
+	status = "okay";
+	ports {
+		port@1 {
+			reg = <1>;
+			lvds1_out_panel: endpoint {
+				remote-endpoint = <&panel_in_lvds1>;
+			};
+		};
+	};
+};
+
+&lvds1_in_vp1 {
 	status = "disabled";
 };
 
+&lvds1_in_vp2 {
+	status = "okay";
+};
+
+&rgb_in_vp2 {
+	status = "disabled";
+};
 
 &vcc3v3_lcd0_n {
 	gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
@@ -170,3 +188,11 @@
 	gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
 	enable-active-high;
 };
+
+&video_phy0 {
+	status = "okay";
+};
+
+&video_phy1 {
+	status = "okay";
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtsi
index 7ef9000..dc9ad42 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtsi
@@ -273,6 +273,7 @@
 		clock-names = "xvclk";
 		pinctrl-names = "default";
 		pinctrl-0 = <&cif_clk>;
+		power-domains = <&power RK3568_PD_VI>;
 		reset-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>;
 		pwdn-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_LOW>;
 		rockchip,grf = <&grf>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb5-ddr4-v10.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb5-ddr4-v10.dtsi
index 4a51275..beba4ab 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb5-ddr4-v10.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3568-evb5-ddr4-v10.dtsi
@@ -304,6 +304,7 @@
 		clock-names = "xvclk";
 		pinctrl-names = "default";
 		pinctrl-0 = <&cif_clk>;
+		power-domains = <&power RK3568_PD_VI>;
 		reset-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>;
 		pwdn-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_LOW>;
 		rockchip,grf = <&grf>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3568-pcie-ep-lp4x-v10-linux.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3568-pcie-ep-lp4x-v10-linux.dts
new file mode 100644
index 0000000..4f255e1
--- /dev/null
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3568-pcie-ep-lp4x-v10-linux.dts
@@ -0,0 +1,641 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/rk-input.h>
+#include "rk3568.dtsi"
+
+/ {
+	model = "Rockchip RK3568 PCIe EP LP4X V10 Board";
+	compatible = "rockchip,rk3568-pcie-ep-lp4x-v10", "rockchip,rk3568";
+
+	adc_keys: adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 0>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		vol-up-key {
+			label = "volume up";
+			linux,code = <KEY_VOLUMEUP>;
+			press-threshold-microvolt = <1750>;
+		};
+	};
+
+	chosen: chosen {
+		bootargs = "earlycon=uart8250,mmio32,0xfe660000 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rw rootwait default_hugepagesz=32M hugepagesz=32M hugepages=1";
+	};
+
+	dc_12v: dc-12v {
+		compatible = "regulator-fixed";
+		regulator-name = "dc_12v";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	fiq-debugger {
+		compatible = "rockchip,fiq-debugger";
+		rockchip,serial-id = <2>;
+		rockchip,wake-irq = <0>;
+		/* If enable uart uses irq instead of fiq */
+		rockchip,irq-mode-enable = <1>;
+		rockchip,baudrate = <1500000>;  /* Only 115200 and 1500000 */
+		interrupts = <GIC_SPI 252 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart2m0_xfer>;
+		status = "okay";
+	};
+
+	hdmi_sound: hdmi-sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,mclk-fs = <128>;
+		simple-audio-card,name = "rockchip,hdmi";
+		status = "disabled";
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s0_8ch>;
+		};
+		simple-audio-card,codec {
+			sound-dai = <&hdmi>;
+		};
+	};
+
+	leds: leds {
+		compatible = "gpio-leds";
+
+		work_led: work {
+			gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		bar0_region: bar0-region@0x3c000000 {
+			reg = <0x0 0x3c000000 0x0 0x00400000>;
+		};
+		bar2_region: bar2-region@0x40000000 {
+			reg = <0x0 0x40000000 0x0 0x04000000>;
+		};
+	};
+
+	test-power {
+		status = "okay";
+	};
+
+	vcc3v3_pcie: gpio-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_pcie";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <5000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vcc5v0_sys: vcc5v0-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vcc5v0_host: vcc5v0-host-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_host";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc5v0_sys>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_host_en>;
+	};
+
+	vcc5v0_otg: vcc5v0-otg-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_otg";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		gpio = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc5v0_sys>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_otg_en>;
+	};
+
+	vcc3v3_sys: vcc3v3-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vccio_1v8: vccio-1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "vccio_1v8";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc3v3_sys>;
+	};
+
+	vccio_3v3: vccio-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vccio_3v3";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vdd_gpu: vdd-gpu {
+		compatible = "pwm-regulator";
+		pwms = <&pwm0 0 5000 1>;
+		regulator-name = "vdd_gpu";
+		regulator-min-microvolt = <810000>;
+		regulator-max-microvolt = <1100000>;
+		regulator-init-microvolt = <920000>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-settling-time-up-us = <250>;
+		pwm-supply = <&vcc3v3_sys>;
+		status = "okay";
+	};
+
+	vdd_logic: vdd-logic {
+		compatible = "pwm-regulator";
+		pwms = <&pwm1 0 5000 1>;
+		regulator-name = "vdd_logic";
+		regulator-min-microvolt = <810000>;
+		regulator-max-microvolt = <1000000>;
+		regulator-init-microvolt = <920000>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-settling-time-up-us = <250>;
+		pwm-supply = <&vcc3v3_sys>;
+		status = "okay";
+	};
+
+	vdd_npu: vdd-npu {
+		compatible = "pwm-regulator";
+		pwms = <&pwm2 0 5000 1>;
+		regulator-name = "vdd_npu";
+		regulator-min-microvolt = <810000>;
+		regulator-max-microvolt = <1100000>;
+		regulator-init-microvolt = <920000>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-settling-time-up-us = <250>;
+		pwm-supply = <&vcc3v3_sys>;
+		status = "okay";
+	};
+};
+
+&bus_npu {
+	bus-supply = <&vdd_logic>;
+	pvtm-supply = <&vdd_cpu>;
+	status = "okay";
+};
+
+&can1 {
+	assigned-clocks = <&cru CLK_CAN0>;
+	assigned-clock-rates = <150000000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&can1m0_pins>;
+	status = "okay";
+};
+
+&combphy0_us {
+	status = "okay";
+};
+
+&combphy1_usq {
+	status = "okay";
+};
+
+&combphy2_psq {
+	 status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&dfi {
+	status = "okay";
+};
+
+&dmc {
+	center-supply = <&vdd_logic>;
+	status = "okay";
+};
+
+&display_subsystem {
+	status = "okay";
+};
+
+&gmac0 {
+	phy-mode = "rgmii";
+	clock_in_out = "output";
+
+	snps,reset-gpio = <&gpio4 RK_PB2 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	/* Reset time is 20ms, 100ms for rtl8211f */
+	snps,reset-delays-us = <0 20000 100000>;
+
+	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
+	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
+	assigned-clock-rates = <0>, <125000000>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac0_miim
+		     &gmac0_tx_bus2
+		     &gmac0_rx_bus2
+		     &gmac0_rgmii_clk
+		     &gmac0_rgmii_bus>;
+
+	tx_delay = <0x3c>;
+	rx_delay = <0x2f>;
+
+	phy-handle = <&rgmii_phy0>;
+	status = "okay";
+};
+
+&gmac1 {
+	phy-mode = "rgmii";
+	clock_in_out = "output";
+
+	snps,reset-gpio = <&gpio4 RK_PC0 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	/* Reset time is 20ms, 100ms for rtl8211f */
+	snps,reset-delays-us = <0 20000 100000>;
+
+	assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
+	assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
+	assigned-clock-rates = <0>, <125000000>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac1m1_miim
+		     &gmac1m1_tx_bus2
+		     &gmac1m1_rx_bus2
+		     &gmac1m1_rgmii_clk
+		     &gmac1m1_rgmii_bus>;
+
+	tx_delay = <0x4f>;
+	rx_delay = <0x26>;
+
+	phy-handle = <&rgmii_phy1>;
+	status = "okay";
+};
+
+&gpu {
+	mali-supply = <&vdd_gpu>;
+	status = "okay";
+};
+
+&hdmi {
+	status = "okay";
+	rockchip,phy-table =
+		<92812500  0x8009 0x0000 0x0270>,
+		<165000000 0x800b 0x0000 0x026d>,
+		<185625000 0x800b 0x0000 0x01ed>,
+		<297000000 0x800b 0x0000 0x01ad>,
+		<594000000 0x8029 0x0000 0x0088>,
+		<000000000 0x0000 0x0000 0x0000>;
+};
+
+&hdmi_in_vp0 {
+	status = "okay";
+};
+
+&hdmi_sound {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+	vdd_cpu: rk8600@40 {
+		compatible = "rockchip,rk8600";
+		reg = <0x40>;
+		vin-supply = <&vcc3v3_sys>;
+		regulator-compatible = "rk860x-reg";
+		regulator-name = "vdd_cpu";
+		regulator-min-microvolt = <712500>;
+		regulator-max-microvolt = <1500000>;
+		regulator-ramp-delay = <2300>;
+		rockchip,suspend-voltage-selector = <1>;
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&i2c2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2m1_xfer>;
+};
+
+&i2c3 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c3m1_xfer>;
+};
+
+&i2s0_8ch {
+	status = "okay";
+};
+
+&iep {
+	status = "okay";
+};
+
+&iep_mmu {
+	status = "okay";
+};
+
+&jpegd {
+	status = "okay";
+};
+
+&jpegd_mmu {
+	status = "okay";
+};
+
+&mdio0 {
+	rgmii_phy0: phy@1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x1>;
+	};
+};
+
+&mdio1 {
+	rgmii_phy1: phy@1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x1>;
+	};
+};
+
+&mpp_srv {
+	status = "okay";
+};
+
+&pcie2x1 {
+	reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
+	vpcie3v3-supply = <&vcc3v3_pcie>;
+	status = "okay";
+};
+
+&pcie30phy {
+	status = "okay";
+};
+
+&pcie3x2 {
+	compatible = "rockchip,rk3568-pcie-std-ep";
+	memory-region = <&bar0_region>, <&bar2_region>;
+	memory-region-names = "bar0", "bar2";
+	status = "okay";
+};
+
+&pinctrl {
+	usb {
+		vcc5v0_host_en: vcc5v0-host-en {
+			rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		vcc5v0_otg_en: vcc5v0-otg-en {
+			rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pmu_io_domains {
+	status = "okay";
+	pmuio2-supply = <&vccio_3v3>;
+	vccio1-supply = <&vccio_3v3>;
+	vccio3-supply = <&vccio_3v3>;
+	vccio4-supply = <&vccio_3v3>;
+	vccio5-supply = <&vccio_3v3>;
+	vccio6-supply = <&vccio_3v3>;
+	vccio7-supply = <&vccio_3v3>;
+};
+
+&pwm0 {
+	status = "okay";
+};
+
+&pwm1 {
+	status = "okay";
+};
+
+&pwm2 {
+	status = "okay";
+};
+
+&rk_rga {
+	status = "okay";
+};
+
+&rkvdec {
+	status = "okay";
+};
+
+&rkvdec_mmu {
+	status = "okay";
+};
+
+&rkvenc {
+	venc-supply = <&vdd_logic>;
+	status = "okay";
+};
+
+&rkvenc_mmu {
+	status = "okay";
+};
+
+&rknpu {
+	rknpu-supply = <&vdd_npu>;
+	status = "okay";
+};
+
+&rknpu_mmu {
+	status = "okay";
+};
+
+&saradc {
+	status = "okay";
+	vref-supply = <&vccio_1v8>;
+};
+
+&sdhci {
+	bus-width = <8>;
+	no-sdio;
+	no-sd;
+	non-removable;
+	max-frequency = <200000000>;
+	status = "okay";
+};
+
+&sdmmc0 {
+	max-frequency = <150000000>;
+	no-sdio;
+	no-mmc;
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	disable-wp;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vccio_3v3>;
+	vqmmc-supply = <&vccio_3v3>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+	status = "okay";
+};
+
+&sdmmc2 {
+	max-frequency = <150000000>;
+	no-sd;
+	no-mmc;
+	bus-width = <4>;
+	disable-wp;
+	cap-sd-highspeed;
+	cap-sdio-irq;
+	keep-power-in-suspend;
+	//mmc-pwrseq = <&sdio_pwrseq>;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>;
+	sd-uhs-sdr104;
+	status = "okay";
+};
+
+&sfc {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <75000000>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <1>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+	pinctrl-names = "default", "high_speed";
+	pinctrl-0 = <&spi0m1_cs0 &spi0m1_pins>;
+	pinctrl-1 = <&spi0m1_cs0 &spi0m1_pins_hs>;
+};
+
+&spi2 {
+	status = "okay";
+	pinctrl-names = "default", "high_speed";
+	pinctrl-0 = <&spi2m1_cs0 &spi2m1_cs1 &spi2m1_pins>;
+	pinctrl-1 = <&spi2m1_cs0 &spi2m1_cs1 &spi2m1_pins_hs>;
+};
+
+&tsadc {
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3m1_xfer>;
+};
+
+/* RS485 */
+&uart4 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart4m0_xfer &uart4m0_ctsn &uart4m0_rtsn>;
+};
+
+&uart7 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart7m1_xfer>;
+};
+
+&u2phy0_host {
+	phy-supply = <&vcc5v0_host>;
+	status = "okay";
+};
+
+&u2phy0_otg {
+	status = "okay";
+	vbus-supply = <&vcc5v0_otg>;
+};
+
+&usb2phy0 {
+	status = "okay";
+};
+
+&usbdrd_dwc3 {
+	dr_mode = "otg";
+	extcon = <&usb2phy0>;
+	status = "okay";
+};
+
+&usbdrd30 {
+	status = "okay";
+};
+
+&usbhost_dwc3 {
+	status = "okay";
+};
+
+&usbhost30 {
+	status = "okay";
+};
+
+&vdpu {
+	status = "okay";
+};
+
+&vdpu_mmu {
+	status = "okay";
+};
+
+&vepu {
+	status = "okay";
+};
+
+&vepu_mmu {
+	status = "okay";
+};
+
+&vop {
+	status = "okay";
+	assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
+	assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+};
+
+&vop_mmu {
+	status = "okay";
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3568-toybrick-sd0.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3568-toybrick-sd0.dtsi
index 6041d1a..7526f29 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3568-toybrick-sd0.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3568-toybrick-sd0.dtsi
@@ -18,7 +18,7 @@
 		status = "okay";
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "dsp_a";
-		simple-audio-card,bitclock-inversion = <1>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <512>;
 		simple-audio-card,name = "rockchip,bt";
 		#simple-audio-card,bitclock-master = <&sound2_master>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3568-toybrick.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3568-toybrick.dtsi
index db4a86d..39a5072 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3568-toybrick.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3568-toybrick.dtsi
@@ -169,7 +169,7 @@
 	bt-sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "dsp_b";
-		simple-audio-card,bitclock-inversion = <1>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <256>;
 		simple-audio-card,name = "rockchip,bt";
 		#simple-audio-card,bitclock-master = <&sound2_master>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-android.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-android.dtsi
index 8901a03..174001f 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-android.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-android.dtsi
@@ -6,7 +6,7 @@
 
 / {
 	chosen: chosen {
-		bootargs = "earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 irqchip.gicv3_pseudo_nmi=0";
+		bootargs = "earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 irqchip.gicv3_pseudo_nmi=0 rcupdate.rcu_expedited=1 rcu_nocbs=all";
 	};
 
 	cspmu: cspmu@fd10c000 {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi
index 14620a8..73ab3e9 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi
@@ -94,7 +94,7 @@
 		status = "disabled";
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "dsp_a";
-		simple-audio-card,bitclock-inversion = <0>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <256>;
 		simple-audio-card,name = "rockchip,bt";
 		simple-audio-card,cpu {
@@ -271,6 +271,8 @@
 		prepare-delay-ms = <10>;
 		unprepare-delay-ms = <10>;
 		disable-delay-ms = <60>;
+		width-mm = <68>;
+		height-mm = <121>;
 		dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
 			MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>;
 		dsi,format = <MIPI_DSI_FMT_RGB888>;
@@ -603,6 +605,8 @@
 		prepare-delay-ms = <10>;
 		unprepare-delay-ms = <10>;
 		disable-delay-ms = <10>;
+		width-mm = <68>;
+		height-mm = <121>;
 		dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
 			MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>;
 		dsi,format = <MIPI_DSI_FMT_RGB888>;
@@ -1072,6 +1076,10 @@
 	status = "okay";
 };
 
+&rkvtunnel {
+	status = "okay";
+};
+
 &rockchip_suspend {
 	status = "okay";
 	rockchip,sleep-debug-en = <1>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-edp-8lanes-M280DCA.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-edp-8lanes-M280DCA.dts
new file mode 100644
index 0000000..65afa35
--- /dev/null
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-edp-8lanes-M280DCA.dts
@@ -0,0 +1,229 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+/dts-v1/;
+
+#include "rk3588-evb1-lp4.dtsi"
+#include "rk3588-evb1-imx415.dtsi"
+#include "rk3588-android.dtsi"
+
+/ {
+	model = "Rockchip RK3588 EVB1 LP4 V10 Board + RK3588 EDP 8LANES V10 Ext Board";
+	compatible = "rockchip,rk3588-evb1-lp4-v10-edp-8lanes-M280DCA", "rockchip,rk3588";
+
+	panel-edp {
+		compatible = "simple-panel";
+		backlight = <&backlight>;
+		power-supply = <&vcc3v3_edp>;
+		enable-gpios = <&gpio4 RK_PC1 GPIO_ACTIVE_HIGH>;
+		prepare-delay-ms = <120>;
+		enable-delay-ms = <120>;
+		unprepare-delay-ms = <120>;
+		disable-delay-ms = <120>;
+
+		display-timings {
+			native-mode = <&timing_4kp144>;
+			timing_4kp144: timing0 {
+				clock-frequency = <1360800000>;
+				hactive = <3840>;
+				vactive = <2160>;
+				hfront-porch = <160>;
+				hsync-len = <40>;
+				hback-porch = <160>;
+				vfront-porch = <40>;
+				vsync-len = <10>;
+				vback-porch = <40>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <0>;
+				pixelclk-active = <0>;
+			};
+
+			timing_4kp120: timing1 {
+				clock-frequency = <1188000000>;
+				hactive = <3840>;
+				vactive = <2160>;
+				hfront-porch = <240>;
+				hsync-len = <80>;
+				hback-porch = <240>;
+				vfront-porch = <40>;
+				vsync-len = <10>;
+				vback-porch = <40>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <0>;
+				pixelclk-active = <0>;
+			};
+		};
+
+		port {
+			panel_in_edp: endpoint {
+				remote-endpoint = <&edp1_out_panel>;
+			};
+		};
+	};
+
+	vcc3v3_edp_bl: vcc3v3-edp-bl {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_edp_bl";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpio = <&gpio4 RK_PC0 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc3v3_edp: vcc3v3-edp {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_edp";
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpio = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+};
+
+&bt_sco {
+	status = "okay";
+};
+
+&bt_sound {
+	status = "okay";
+};
+
+&dsi0 {
+	status = "disabled";
+};
+
+&edp0 {
+	force-hpd;
+	status = "okay";
+};
+
+&edp0_in_vp0 {
+	status = "okay";
+};
+
+&edp0_in_vp1 {
+	status = "disabled";
+};
+
+&edp0_in_vp2 {
+	status = "disabled";
+};
+
+&edp1 {
+	force-hpd;
+	status = "okay";
+	dual-channel;
+
+	ports {
+		port@1 {
+			reg = <1>;
+
+			edp1_out_panel: endpoint {
+				remote-endpoint = <&panel_in_edp>;
+			};
+		};
+	};
+};
+
+&edp1_in_vp0 {
+	status = "okay";
+};
+
+&edp1_in_vp1 {
+	status = "disabled";
+};
+
+&edp1_in_vp2 {
+	status = "disabled";
+};
+
+&hdmi0 {
+	status = "disabled";
+};
+
+&hdmi0_in_vp0 {
+	status = "disabled";
+};
+
+&hdmi0_sound {
+	status = "disabled";
+};
+
+&hdmi1 {
+	status = "disabled";
+};
+
+&hdmi1_in_vp1 {
+	status = "disabled";
+};
+
+&hdmi1_sound {
+	status = "disabled";
+};
+
+&hdptxphy0 {
+	status = "okay";
+};
+
+&hdptxphy1 {
+	status = "okay";
+};
+
+&hdptxphy_hdmi0 {
+	status = "disabled";
+};
+
+&hdptxphy_hdmi1 {
+	status = "disabled";
+};
+
+&i2s2_2ch {
+	status = "okay";
+};
+
+&route_dsi0 {
+	status = "disabled";
+};
+
+&route_edp0 {
+	status = "okay";
+	connect = <&vp0_out_edp0>;
+};
+
+&route_edp1 {
+	status = "okay";
+	connect = <&vp0_out_edp1>;
+};
+
+&route_hdmi0 {
+	status = "disabled";
+};
+
+&route_hdmi1 {
+	status = "disabled";
+};
+
+&vop {
+	assigned-clocks = <&cru ACLK_VOP>;
+	assigned-clock-rates = <800000000>;
+};
+
+&vp0 {
+	assigned-clocks = <&cru DCLK_VOP0_SRC>;
+	assigned-clock-parents = <&cru PLL_V0PLL>;
+};
+
+&vp2 {
+	/delete-property/ assigned-clocks;
+	/delete-property/ assigned-clock-parents;
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-lt6911uxc-dual-mipi.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-lt6911uxc-dual-mipi.dts
new file mode 100644
index 0000000..4894f1b
--- /dev/null
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-lt6911uxc-dual-mipi.dts
@@ -0,0 +1,326 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
+ *
+ */
+/dts-v1/;
+
+#include "rk3588-evb1-lp4.dtsi"
+#include "rk3588-android.dtsi"
+
+/ {
+	model = "Rockchip RK3588 EVB1 LP4 V10 Board + Rockchip RK3588 EVB V10 Extboard";
+	compatible = "rockchip,rk3588-evb1-lp4-lt6911uxc-dual-mipi", "rockchip,rk3588";
+
+	vcc_mipicsi0: vcc-mipicsi0-regulator {
+		compatible = "regulator-fixed";
+		gpio = <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mipicsi0_pwr>;
+		regulator-name = "vcc_mipicsi0";
+		enable-active-high;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	vcc_mipidcphy0: vcc-mipidcphy0-regulator {
+		compatible = "regulator-fixed";
+		gpio = <&gpio2 RK_PC4 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mipidcphy0_pwr>;
+		regulator-name = "vcc_mipidcphy0";
+		enable-active-high;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	ext_cam_clk: external-camera-clock {
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "CLK_CAMERA_24MHZ";
+		#clock-cells = <0>;
+	};
+};
+
+&csi2_dphy0_hw {
+	status = "okay";
+};
+
+&csi2_dphy1_hw {
+	status = "okay";
+};
+
+&csi2_dphy0 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			hdmi_mipi_in: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&lt6911uxc_out0>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			csidphy0_out: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&mipi2_csi2_input>;
+			};
+		};
+	};
+};
+
+&csi2_dphy1 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			hdmi_mipi_in1: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&lt6911uxc_out1>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			csidphy1_out: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&mipi0_csi2_input>;
+			};
+		};
+	};
+};
+
+&i2c3 {
+	status = "okay";
+
+	lt6911uxc: lt6911uxc@2b {
+		compatible = "lontium,lt6911uxc";
+		status = "okay";
+		reg = <0x2b>;
+		clocks = <&ext_cam_clk>;
+		clock-names = "xvclk";
+		power-domains = <&power RK3588_PD_VI>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&lt6911uxc_pin_1>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <RK_PB3 IRQ_TYPE_LEVEL_LOW>;
+		// reset-gpios = <&gpio1 RK_PB1 GPIO_ACTIVE_LOW>;
+		// power-gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_HIGH>;
+		plugin-det-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_HIGH>;
+		rockchip,camera-module-index = <0>;
+		rockchip,camera-module-facing = "back";
+		rockchip,camera-module-name = "HDMI-MIPI2";
+		rockchip,camera-module-lens-name = "LT6911UXC-2";
+
+		multi-dev-info {
+			dev-idx-l = <4>;
+			dev-idx-r = <2>;
+			combine-idx = <2>;
+			pixel-offset = <0>;
+			dev-num = <2>;
+		};
+
+		port {
+			lt6911uxc_out0: endpoint {
+				remote-endpoint = <&hdmi_mipi_in>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+	};
+};
+
+&i2c5 {
+	status = "okay";
+
+	lt6911uxc_1: lt6911uxc_1@2b {
+		compatible = "lontium,lt6911uxc";
+		status = "okay";
+		reg = <0x2b>;
+		clocks = <&ext_cam_clk>;
+		clock-names = "xvclk";
+		power-domains = <&power RK3588_PD_VI>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&lt6911uxc_pin>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <RK_PA0 IRQ_TYPE_LEVEL_LOW>;
+		// reset-gpios = <&gpio1 RK_PB1 GPIO_ACTIVE_LOW>;
+		// power-gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_HIGH>;
+		// plugin-det-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>;
+		plugin-det-gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_HIGH>;
+		rockchip,camera-module-index = <1>;
+		rockchip,camera-module-facing = "front";
+		rockchip,camera-module-name = "HDMI-MIPI0";
+		rockchip,camera-module-lens-name = "LT6911UXC-1";
+
+		multi-dev-info {
+			dev-idx-l = <1>;
+			dev-idx-r = <0>;
+			combine-idx = <0>;
+			pixel-offset = <0>;
+			dev-num = <2>;
+		};
+
+		port {
+			lt6911uxc_out1: endpoint {
+				remote-endpoint = <&hdmi_mipi_in1>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+	};
+};
+
+&mipi_dcphy0 {
+	status = "okay";
+};
+
+&mipi_dcphy1 {
+	status = "okay";
+};
+
+&mipi0_csi2_hw {
+	status = "okay";
+};
+
+&mipi1_csi2_hw {
+	status = "okay";
+};
+
+&mipi2_csi2_hw {
+	status = "okay";
+};
+
+&mipi3_csi2_hw {
+	status = "okay";
+};
+
+&mipi4_csi2_hw {
+	status = "okay";
+};
+
+&mipi5_csi2_hw {
+	status = "okay";
+};
+
+&mipi0_csi2 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi0_csi2_input: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&csidphy1_out>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi0_csi2_output: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&cif_mipi_in0>;
+			};
+		};
+	};
+};
+
+&mipi2_csi2 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi2_csi2_input: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&csidphy0_out>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi2_csi2_output: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&cif_mipi_in2>;
+			};
+		};
+	};
+};
+
+&rkcif_mipi_lvds {
+	status = "okay";
+
+	port {
+		cif_mipi_in0: endpoint {
+			remote-endpoint = <&mipi0_csi2_output>;
+		};
+	};
+};
+
+&rkcif_mipi_lvds2 {
+	status = "okay";
+
+	port {
+		cif_mipi_in2: endpoint {
+			remote-endpoint = <&mipi2_csi2_output>;
+		};
+	};
+};
+
+&rkcif {
+	status = "okay";
+};
+
+&rkcif_mmu {
+	status = "okay";
+};
+
+&pinctrl {
+	hdmiin {
+		lt6911uxc_pin: lt6911uxc-pin {
+			rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>,
+					<1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		lt6911uxc_pin_1: lt6911uxc-pin-1 {
+			rockchip,pins = <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>,
+					<1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-rk628-hdmi2csi.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-rk628-hdmi2csi.dts
new file mode 100644
index 0000000..9922343
--- /dev/null
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-rk628-hdmi2csi.dts
@@ -0,0 +1,264 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
+ *
+ */
+/dts-v1/;
+
+#include "rk3588-evb1-lp4.dtsi"
+#include "rk3588-android.dtsi"
+
+/ {
+	model = "Rockchip RK3588 EVB1 LP4 V10 Board + Rockchip RK628 HDMI to MIPI Extboard";
+	compatible = "rockchip,rk3588-evb1-lp4-v10", "rockchip,rk3588";
+
+	vcc_mipicsi0: vcc-mipicsi0-regulator {
+		/delete-property/ gpio;
+		/delete-property/ pinctrl-0;
+	};
+
+	vcc_mipicsi1: vcc-mipicsi1-regulator {
+		/delete-property/ gpio;
+		/delete-property/ pinctrl-0;
+	};
+
+	vcc_mipidcphy0: vcc-mipidcphy0-regulator {
+		/delete-property/ gpio;
+		/delete-property/ pinctrl-0;
+	};
+};
+
+&csi2_dphy0 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			hdmi_mipi2_in: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&hdmiin_out1>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			csidphy0_out: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&mipi2_csi2_input>;
+			};
+		};
+	};
+};
+
+&csi2_dphy0_hw {
+	status = "okay";
+};
+
+&csi2_dcphy0 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			hdmi_mipi0_in: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&hdmiin_out0>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			csidcphy0_out: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&mipi0_csi2_input>;
+			};
+		};
+	};
+};
+
+&i2c3 {
+	status = "okay";
+
+	rk628_csi_1: rk628_csi_1@50 {
+		reg = <0x50>;
+		compatible = "rockchip,rk628-csi-v4l2";
+		status = "okay";
+		power-domains = <&power RK3588_PD_VI>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rk628_pin_1>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <RK_PB1 IRQ_TYPE_LEVEL_HIGH>;
+		enable-gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
+		plugin-det-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>;
+		continues-clk = <1>;
+
+		rockchip,camera-module-index = <0>;
+		rockchip,camera-module-facing = "back";
+		rockchip,camera-module-name = "HDMI-MIPI2";
+		rockchip,camera-module-lens-name = "RK628-CSI";
+		port {
+			hdmiin_out1: endpoint {
+				remote-endpoint = <&hdmi_mipi2_in>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+	};
+};
+
+&i2c5 {
+	status = "okay";
+
+	rk628_csi: rk628_csi@50 {
+		reg = <0x50>;
+		compatible = "rockchip,rk628-csi-v4l2";
+		status = "okay";
+		power-domains = <&power RK3588_PD_VI>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rk628_pin>;
+		interrupt-parent = <&gpio2>;
+		interrupts = <RK_PC4 IRQ_TYPE_LEVEL_HIGH>;
+		enable-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;
+		plugin-det-gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_LOW>;
+		continues-clk = <1>;
+
+		rockchip,camera-module-index = <0>;
+		rockchip,camera-module-facing = "back";
+		rockchip,camera-module-name = "HDMI-MIPI";
+		rockchip,camera-module-lens-name = "RK628-CSI";
+		port {
+			hdmiin_out0: endpoint {
+				remote-endpoint = <&hdmi_mipi0_in>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+	};
+};
+
+&mipi_dcphy0 {
+	status = "okay";
+};
+
+&mipi0_csi2 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi0_csi2_input: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&csidcphy0_out>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi0_csi2_output: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&cif_mipi_in0>;
+			};
+		};
+	};
+};
+
+&mipi2_csi2 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi2_csi2_input: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&csidphy0_out>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi2_csi2_output: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&cif_mipi_in2>;
+			};
+		};
+	};
+};
+
+&rkcif {
+	status = "okay";
+};
+
+&rkcif_mipi_lvds {
+	status = "okay";
+
+	port {
+		cif_mipi_in0: endpoint {
+			remote-endpoint = <&mipi0_csi2_output>;
+		};
+	};
+};
+
+&rkcif_mipi_lvds2 {
+	status = "okay";
+
+	port {
+		cif_mipi_in2: endpoint {
+			remote-endpoint = <&mipi2_csi2_output>;
+		};
+	};
+};
+
+&rkcif_mmu {
+	status = "okay";
+};
+
+&pinctrl {
+	hdmiin {
+		rk628_pin: rk628-pin {
+			rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>,
+					<2 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>,
+					<1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>,
+					<4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+		rk628_pin_1: rk628-pin-1 {
+			rockchip,pins = <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>,
+					<1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>,
+					<1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>,
+					<1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb2-lp4-v10-edp.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb2-lp4-v10-edp.dts
index a889cc3..9ea5036 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb2-lp4-v10-edp.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb2-lp4-v10-edp.dts
@@ -18,8 +18,8 @@
 		enable-delay-ms = <120>;
 		unprepare-delay-ms = <120>;
 		disable-delay-ms = <120>;
-		width-mm = <129>;
-		height-mm = <171>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		panel-timing {
 			clock-frequency = <200000000>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp-linux.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp-linux.dts
index 964efd9..9d27fbf 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp-linux.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp-linux.dts
@@ -18,8 +18,8 @@
 		enable-delay-ms = <120>;
 		unprepare-delay-ms = <120>;
 		disable-delay-ms = <120>;
-		width-mm = <129>;
-		height-mm = <171>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		panel-timing {
 			clock-frequency = <200000000>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp.dts
index 3890e1d..a5ee38a 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp.dts
@@ -18,8 +18,8 @@
 		enable-delay-ms = <120>;
 		unprepare-delay-ms = <120>;
 		disable-delay-ms = <120>;
-		width-mm = <129>;
-		height-mm = <171>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		panel-timing {
 			clock-frequency = <200000000>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-linux.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-linux.dtsi
index 12b8158..97345c0 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-linux.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-linux.dtsi
@@ -12,7 +12,7 @@
 	};
 
 	chosen: chosen {
-		bootargs = "earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 irqchip.gicv3_pseudo_nmi=0 root=PARTUUID=614e0000-0000 rw rootwait";
+		bootargs = "earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 irqchip.gicv3_pseudo_nmi=0 root=PARTUUID=614e0000-0000 rw rootwait rcupdate.rcu_expedited=1 rcu_nocbs=all";
 	};
 
 	cspmu: cspmu@fd10c000 {
@@ -60,6 +60,13 @@
 		};
 	};
 
+	minidump: minidump {
+		compatible = "rockchip,minidump";
+		smem-region = <&minidump_smem>;
+		minidump-region = <&minidump_mem>;
+		status = "disabled";
+	};
+
 	reserved-memory {
 		#address-cells = <2>;
 		#size-cells = <2>;
@@ -84,12 +91,28 @@
 
 		ramoops: ramoops@110000 {
 			compatible = "ramoops";
-			reg = <0x0 0x110000 0x0 0xf0000>;
-			record-size = <0x20000>;
+			/* 0x110000 to 0x1f0000 is for ramoops */
+			reg = <0x0 0x110000 0x0 0xe0000>;
+			boot-log-size = <0x8000>;	/* do not change */
+			boot-log-count = <0x1>;		/* do not change */
 			console-size = <0x80000>;
+			pmsg-size = <0x30000>;
 			ftrace-size = <0x00000>;
-			pmsg-size = <0x50000>;
+			record-size = <0x14000>;
 		};
+
+		minidump_smem: minidump-smem@1f0000 {
+			reg = <0x0 0x1f0000 0x0 0x100>;		/* do not change */
+			no-map;
+			status = "disabled";
+		};
+
+		minidump_mem: minidump-mem@c000000 {
+			reg = <0x0 0x0c000000 0x0 0x2000000>;	/* changing according to your project */
+			no-map;
+			status = "disabled";
+		};
+
 	};
 };
 
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy0.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy0.dtsi
index 6821fa8..b349599 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy0.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy0.dtsi
@@ -12,6 +12,42 @@
 		clock-frequency = <25000000>;
 		clock-output-names = "max96712-dcphy0-osc";
 	};
+
+	max96712_dcphy0_vcc1v2: max96712-dcphy0-vcc1v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "max96712_dcphy0_vcc1v2";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		startup-delay-us = <850>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	max96712_dcphy0_vcc1v8: max96712-dcphy0-vcc1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "max96712_dcphy0_vcc1v8";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		startup-delay-us = <200>;
+		vin-supply = <&vcc_3v3_s3>;
+	};
+
+	max96712_dcphy0_poc: max96712-dcphy0-poc {
+		compatible = "regulator-fixed";
+		regulator-name = "max96712_dcphy0_poc";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		enable-active-high;
+		gpio = <&gpio3 RK_PA6 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <1050>;
+		off-on-delay-us = <515000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
 };
 
 &mipi_dcphy0 {
@@ -64,8 +100,10 @@
 		power-domains = <&power RK3588_PD_VI>;
 		rockchip,grf = <&sys_grf>;
 		pwdn-gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>;
-		pocen-gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_HIGH>;
 		lock-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
+		vcc1v2-supply = <&max96712_dcphy0_vcc1v2>;
+		vcc1v8-supply = <&max96712_dcphy0_vcc1v8>;
+		poc-supply = <&max96712_dcphy0_poc>;
 
 		rockchip,camera-module-index = <0>;
 		rockchip,camera-module-facing = "back";
@@ -89,7 +127,7 @@
 			max-fps-numerator = <10000>;
 			max-fps-denominator = <300000>;
 			bpp = <16>;
-			link-freq-idx = <12>;
+			link-freq-idx = <24>;
 			vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7
 		};
 		/* support mode config end */
@@ -682,15 +720,15 @@
 &pinctrl {
 	max96712-dcphy0 {
 		max96712_dcphy0_pwdn: max96712-dcphy0-pwdn {
-			rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>;
 		};
 
 		max96712_dcphy0_errb: max96712-dcphy0-errb {
-			rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 
 		max96712_dcphy0_lock: max96712-dcphy0-lock {
-			rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 	};
 };
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy1.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy1.dtsi
index 2b0a04e..6564020 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy1.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy1.dtsi
@@ -12,6 +12,42 @@
 		clock-frequency = <25000000>;
 		clock-output-names = "max96712-dcphy1-osc";
 	};
+
+	max96712_dcphy1_vcc1v2: max96712-dcphy1-vcc1v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "max96712_dcphy1_vcc1v2";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		startup-delay-us = <850>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	max96712_dcphy1_vcc1v8: max96712-dcphy1-vcc1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "max96712_dcphy1_vcc1v8";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		startup-delay-us = <200>;
+		vin-supply = <&vcc_3v3_s3>;
+	};
+
+	max96712_dcphy1_poc: max96712-dcphy1-poc {
+		compatible = "regulator-fixed";
+		regulator-name = "max96712_dcphy1_poc";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		enable-active-high;
+		gpio = <&gpio3 RK_PA7 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <1050>;
+		off-on-delay-us = <515000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
 };
 
 &mipi_dcphy1 {
@@ -64,8 +100,10 @@
 		power-domains = <&power RK3588_PD_VI>;
 		rockchip,grf = <&sys_grf>;
 		pwdn-gpios = <&gpio4 RK_PD1 GPIO_ACTIVE_HIGH>;
-		pocen-gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_HIGH>;
 		lock-gpios = <&gpio4 RK_PD3 GPIO_ACTIVE_HIGH>;
+		vcc1v2-supply = <&max96712_dcphy1_vcc1v2>;
+		vcc1v8-supply = <&max96712_dcphy1_vcc1v8>;
+		poc-supply = <&max96712_dcphy1_poc>;
 
 		rockchip,camera-module-index = <0>;
 		rockchip,camera-module-facing = "back";
@@ -89,7 +127,7 @@
 			max-fps-numerator = <10000>;
 			max-fps-denominator = <300000>;
 			bpp = <16>;
-			link-freq-idx = <20>;
+			link-freq-idx = <24>;
 			vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7
 		};
 		/* support mode config end */
@@ -452,15 +490,15 @@
 &pinctrl {
 	max96712-dcphy1 {
 		max96712_dcphy1_pwdn: max96712-dcphy1-pwdn {
-			rockchip,pins = <4 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <4 RK_PD1 RK_FUNC_GPIO &pcfg_output_low>;
 		};
 
 		max96712_dcphy1_errb: max96712-dcphy1-errb {
-			rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 
 		max96712_dcphy1_lock: max96712-dcphy1-lock {
-			rockchip,pins = <4 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <4 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 	};
 };
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy0.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy0.dtsi
index b68f8f7..d5e2cc8 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy0.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy0.dtsi
@@ -12,6 +12,42 @@
 		clock-frequency = <25000000>;
 		clock-output-names = "max96712-dphy0-osc0";
 	};
+
+	max96712_dphy0_vcc1v2: max96712-dphy0-vcc1v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "max96712_dphy0_vcc1v2";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		startup-delay-us = <850>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	max96712_dphy0_vcc1v8: max96712-dphy0-vcc1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "max96712_dphy0_vcc1v8";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		startup-delay-us = <200>;
+		vin-supply = <&vcc_3v3_s3>;
+	};
+
+	max96712_dphy0_poc: max96712-dphy0-poc {
+		compatible = "regulator-fixed";
+		regulator-name = "max96712_dphy0_poc";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		enable-active-high;
+		gpio = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <1050>;
+		off-on-delay-us = <515000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
 };
 
 &csi2_dphy0_hw {
@@ -64,8 +100,10 @@
 		power-domains = <&power RK3588_PD_VI>;
 		rockchip,grf = <&sys_grf>;
 		pwdn-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
-		pocen-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
 		lock-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
+		vcc1v2-supply = <&max96712_dphy0_vcc1v2>;
+		vcc1v8-supply = <&max96712_dphy0_vcc1v8>;
+		poc-supply = <&max96712_dphy0_poc>;
 
 		rockchip,camera-module-index = <0>;
 		rockchip,camera-module-facing = "back";
@@ -694,15 +732,15 @@
 &pinctrl {
 	max96712-dphy0 {
 		max96712_dphy0_pwdn: max96712-dphy0-pwdn {
-			rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_output_low>;
 		};
 
 		max96712_dphy0_errb: max96712-dphy0-errb {
-			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 
 		max96712_dphy0_lock: max96712-dphy0-lock {
-			rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 	};
 };
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi
index 27ab049..720b3ec 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi
@@ -12,6 +12,41 @@
 		clock-frequency = <25000000>;
 		clock-output-names = "max96712-dphy3-osc0";
 	};
+
+	max96712_dphy3_vcc1v2: max96712-dphy3-vcc1v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "max96712_dphy3_vcc1v2";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		startup-delay-us = <850>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	max96712_dphy3_vcc1v8: max96712-dphy3-vcc1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "max96712_dphy3_vcc1v8";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		startup-delay-us = <200>;
+		vin-supply = <&vcc_3v3_s3>;
+	};
+
+	max96712_dphy3_poc: max96712-dphy3-poc {
+		compatible = "regulator-fixed";
+		regulator-name = "max96712_dphy3_poc";
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		enable-active-high;
+		gpio = <&gpio3 RK_PB1 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <1050>;
+		off-on-delay-us = <515000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
 };
 
 &csi2_dphy1_hw {
@@ -64,8 +99,10 @@
 		power-domains = <&power RK3588_PD_VI>;
 		rockchip,grf = <&sys_grf>;
 		pwdn-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
-		pocen-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_HIGH>;
 		lock-gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_HIGH>;
+		vcc1v2-supply = <&max96712_dphy3_vcc1v2>;
+		vcc1v8-supply = <&max96712_dphy3_vcc1v8>;
+		poc-supply = <&max96712_dphy3_poc>;
 
 		rockchip,camera-module-index = <0>;
 		rockchip,camera-module-facing = "back";
@@ -599,15 +636,15 @@
 &pinctrl {
 	max96712-dphy3 {
 		max96712_dphy3_pwdn: max96712-dphy3-pwdn {
-			rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_output_low>;
 		};
 
 		max96712_dphy3_errb: max96712-dphy3-errb {
-			rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 
 		max96712_dphy3_lock: max96712-dphy3-lock {
-			rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 	};
 };
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712.dtsi
index db774ff..586c869 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712.dtsi
@@ -148,15 +148,15 @@
 &pinctrl {
 	max96712-dphy3 {
 		max96712_dphy3_power: max96712-dphy3-power {
-			rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_output_low>;
 		};
 
 		max96712_dphy3_errb: max96712-dphy3-errb {
-			rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 
 		max96712_dphy3_lock: max96712-dphy3-lock {
-			rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 	};
 };
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy0.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy0.dtsi
index 4544751..d2eedac 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy0.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy0.dtsi
@@ -12,6 +12,42 @@
 		clock-frequency = <25000000>;
 		clock-output-names = "max96722-dphy0-osc0";
 	};
+
+	max96722_dphy0_vcc1v2: max96722-dphy0-vcc1v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "max96722_dphy0_vcc1v2";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		startup-delay-us = <850>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	max96722_dphy0_vcc1v8: max96722-dphy0-vcc1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "max96722_dphy0_vcc1v8";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		startup-delay-us = <200>;
+		vin-supply = <&vcc_3v3_s3>;
+	};
+
+	max96722_dphy0_poc: max96722-dphy0-poc {
+		compatible = "regulator-fixed";
+		regulator-name = "max96722_dphy0_poc";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		enable-active-high;
+		gpio = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <1050>;
+		off-on-delay-us = <515000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
 };
 
 &csi2_dphy0_hw {
@@ -64,8 +100,10 @@
 		power-domains = <&power RK3588_PD_VI>;
 		rockchip,grf = <&sys_grf>;
 		pwdn-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
-		pocen-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
 		lock-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
+		vcc1v2-supply = <&max96722_dphy0_vcc1v2>;
+		vcc1v8-supply = <&max96722_dphy0_vcc1v8>;
+		poc-supply = <&max96722_dphy0_poc>;
 
 		rockchip,camera-module-index = <0>;
 		rockchip,camera-module-facing = "back";
@@ -694,15 +732,15 @@
 &pinctrl {
 	max96722-dphy0 {
 		max96722_dphy0_pwdn: max96722-dphy0-pwdn {
-			rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_output_low>;
 		};
 
 		max96722_dphy0_errb: max96722-dphy0-errb {
-			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 
 		max96722_dphy0_lock: max96722-dphy0-lock {
-			rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 	};
 };
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy3.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy3.dtsi
index ad176da..53dfac5 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy3.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy3.dtsi
@@ -12,6 +12,42 @@
 		clock-frequency = <25000000>;
 		clock-output-names = "max96722-dphy3-osc0";
 	};
+
+	max96722_dphy3_vcc1v2: max96722-dphy3-vcc1v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "max96722_dphy3_vcc1v2";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		startup-delay-us = <850>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	max96722_dphy3_vcc1v8: max96722-dphy3-vcc1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "max96722_dphy3_vcc1v8";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		startup-delay-us = <200>;
+		vin-supply = <&vcc_3v3_s3>;
+	};
+
+	max96722_dphy3_poc: max96722-dphy3-poc {
+		compatible = "regulator-fixed";
+		regulator-name = "max96722_dphy3_poc";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		enable-active-high;
+		gpio = <&gpio3 RK_PB1 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <1050>;
+		off-on-delay-us = <515000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
 };
 
 &csi2_dphy1_hw {
@@ -64,8 +100,10 @@
 		power-domains = <&power RK3588_PD_VI>;
 		rockchip,grf = <&sys_grf>;
 		pwdn-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
-		pocen-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_HIGH>;
 		lock-gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_HIGH>;
+		vcc1v2-supply = <&max96722_dphy3_vcc1v2>;
+		vcc1v8-supply = <&max96722_dphy3_vcc1v8>;
+		poc-supply = <&max96722_dphy3_poc>;
 
 		rockchip,camera-module-index = <0>;
 		rockchip,camera-module-facing = "back";
@@ -464,15 +502,15 @@
 &pinctrl {
 	max96722-dphy3 {
 		max96722_dphy3_pwdn: max96722-dphy3-pwdn {
-			rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_output_low>;
 		};
 
 		max96722_dphy3_errb: max96722-dphy3-errb {
-			rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 
 		max96722_dphy3_lock: max96722-dphy3-lock {
-			rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 	};
 };
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722.dtsi
index 3b655bb..c464e0a 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722.dtsi
@@ -149,15 +149,15 @@
 &pinctrl {
 	max96722-dphy0 {
 		max96722_dphy0_power: max96722-dphy0-power {
-			rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_output_low>;
 		};
 
 		max96722_dphy0_errb: max96722-dphy0-errb {
-			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 
 		max96722_dphy0_lock: max96722-dphy0-lock {
-			rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 	};
 };
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96756-dphy0.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96756-dphy0.dtsi
new file mode 100644
index 0000000..888e426
--- /dev/null
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96756-dphy0.dtsi
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+/ {
+	max96756_dphy0_osc: max96712-dphy0-oscillator@0 {
+		compatible = "fixed-clock";
+		#clock-cells = <1>;
+		clock-frequency  = <25000000>;
+		clock-output-names = "max96756-dphy0-osc";
+	};
+
+	max96756_dphy0_vcc1v2: max96756-dphy0-vcc1v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "max96756_dphy0_vcc1v2";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		startup-delay-us = <850>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	max96756_dphy0_vcc1v8: max96756-dphy0-vcc1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "max96756_dphy0_vcc1v8";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		startup-delay-us = <200>;
+		vin-supply = <&vcc_3v3_s3>;
+	};
+};
+
+/**
+ * ============================================================================
+ * Info DPHY0
+ * ============================================================================
+ */
+&csi2_dphy0_hw {
+	status = "okay";
+};
+
+&csi2_dphy0 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi_dphy0_in_max96756: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&max96756_dphy0_out>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			csidphy0_out: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&mipi2_csi2_input>;
+			};
+		};
+	};
+};
+
+&i2c7 {
+	status = "okay";
+	clock-frequency = <400000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c7m3_xfer>;
+
+	max96756: max96756@48 {
+		compatible = "maxim,max96756";
+		status = "okay";
+		reg = <0x48>;
+
+		clock-names = "xvclk";
+		clocks = <&max96756_dphy0_osc 0>;
+		power-domains = <&power RK3588_PD_VI>;
+		rockchip,grf = <&sys_grf>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&max96756_dphy0_pwdn>, <&max96756_dphy0_errb>, <&max96756_dphy0_lock>;
+
+		pwdn-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
+		lock-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
+
+		vcc1v2-supply = <&max96756_dphy0_vcc1v2>;
+		vcc1v8-supply = <&max96756_dphy0_vcc1v8>;
+
+		rockchip,camera-module-index = <0>;
+		rockchip,camera-module-facing = "back";
+		rockchip,camera-module-name = "max96756";
+		rockchip,camera-module-lens-name = "max96756";
+
+		port {
+			max96756_dphy0_out: endpoint {
+				remote-endpoint = <&mipi_dphy0_in_max96756>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+	};
+};
+
+&mipi2_csi2 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi2_csi2_input: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&csidphy0_out>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi2_csi2_output: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&cif_mipi2_in>;
+			};
+		};
+	};
+};
+
+&rkcif_mipi_lvds2 {
+	status = "okay";
+	/* parameters for do cif reset detecting:
+	 * index0: monitor mode,
+		   0 for idle,
+		   1 for continue,
+		   2 for trigger,
+		   3 for hotplug (for nextchip)
+	 * index1: the frame id to start timer,
+		   min is 2
+	 * index2: frame num of monitoring cycle
+	 * index3: err time for keep monitoring
+		   after finding out err (ms)
+	 * index4: csi2 err reference val for resetting
+	 */
+	rockchip,cif-monitor = <3 2 1 1000 5>;
+
+	port {
+		cif_mipi2_in: endpoint {
+			remote-endpoint = <&mipi2_csi2_output>;
+		};
+	};
+};
+
+/**
+ * =============================================================================
+ * Common
+ * =============================================================================
+ */
+&rkcif {
+	status = "okay";
+	rockchip,android-usb-camerahal-enable;
+};
+
+&rkcif_mmu {
+	status = "okay";
+};
+
+&pinctrl {
+	max96756-dphy0 {
+		max96756_dphy0_pwdn: max96756-dphy0-pwdn {
+			rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_output_low>;
+		};
+
+		max96756_dphy0_errb: max96756-dphy0-errb {
+			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none_smt>;
+		};
+
+		max96756_dphy0_lock: max96756-dphy0-lock {
+			rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none_smt>;
+		};
+	};
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v10.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v10.dts
index 138d67b..e4c9ef6 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v10.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v10.dts
@@ -20,7 +20,7 @@
 	bt-sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "dsp_a";
-		simple-audio-card,bitclock-inversion = <1>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <256>;
 		simple-audio-card,name = "rockchip,bt";
 		simple-audio-card,cpu {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v20.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v20.dts
index 8851802..2dd0381 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v20.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v20.dts
@@ -19,7 +19,7 @@
 	bt-sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "dsp_a";
-		simple-audio-card,bitclock-inversion = <1>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <256>;
 		simple-audio-card,name = "rockchip,bt";
 		simple-audio-card,cpu {
@@ -86,6 +86,77 @@
 	status = "okay";
 };
 
+&pinctrl {
+
+	bl {
+		bl0_enable_pin: bl0-enable-pin {
+			rockchip,pins =
+				<1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>,
+				<4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>,
+				<4 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+
+		};
+
+		bl1_enable_pin: bl1-enable-pin {
+			rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		bl2_enable_pin: bl2-enable-pin {
+			rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		bl3_enable_pin: bl3-enable-pin {
+			rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		bl4_enable_pin: bl4-enable-pin {
+			rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		bl5_enable_pin: bl5-enable-pin {
+			rockchip,pins = <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	serdes {
+		//dsi0
+		ser0_rst_pin: ser0-rst-pin {
+			rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		//dsi1
+		ser1_rst_pin: ser1-rst-pin {
+			rockchip,pins = <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	touch {
+		//dsi0-i2c2
+		touch_gpio_dsi0: touch-gpio-dsi0 {
+			rockchip,pins =
+				<1 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;  //rst
+		};
+		//dsi1-i2c6
+		touch_gpio_dsi1: touch-gpio-dsi1 {
+			rockchip,pins =
+				<1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>,  //rst
+				<1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>;  //int
+		};
+		//dp0-i2c4
+		touch_gpio_dp0: touch-gpio-dp0 {
+			rockchip,pins =
+				<3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>,	//rst
+				<0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>;	//int
+		};
+		//edp0-i2c5
+		touch_gpio_edp0: touch-gpio-edp0 {
+			rockchip,pins =
+				<0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>,  //rst
+				<0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;  //int
+		};
+	};
+};
+
 &rockchip_suspend {
 	rockchip,sleep-mode-config = <
 		(0
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v20.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v20.dtsi
index 9534104..d562124 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v20.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v20.dtsi
@@ -118,14 +118,6 @@
 		status = "okay";
 	};
 
-	dummy_codec: dummy-codec {
-		status = "okay";
-		compatible = "rockchip,dummy-codec";
-		#sound-dai-cells = <0>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&rk3308_reset>;
-	};
-
 	car_rk3308_sound: car-rk3308-sound {
 		status = "okay";
 		compatible = "simple-audio-card";
@@ -140,7 +132,7 @@
 			dai-tdm-slot-width = <32>;
 		};
 		codec_master: simple-audio-card,codec {
-			sound-dai = <&dummy_codec>;
+			sound-dai = <&spi_codec>;
 		};
 	};
 };
@@ -326,6 +318,23 @@
 	status = "disabled";
 };
 
+&spi4 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi4m0_cs1 &spi4m0_pins>;
+
+	spi_codec: spi-codec@1 {
+		compatible ="rockchip,spi-codec";
+		reg = <1>;
+		spi-lsb-first;
+		spi-max-frequency = <5000000>;
+		#sound-dai-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rk3308_reset>;
+		status = "okay";
+	};
+};
+
 &uart9 {
 	status = "okay";
 	pinctrl-names = "default";
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts
index be6ede0..258ec54 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts
@@ -18,7 +18,7 @@
 	bt-sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "dsp_a";
-		simple-audio-card,bitclock-inversion = <1>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <256>;
 		simple-audio-card,name = "rockchip,bt";
 		simple-audio-card,cpu {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dtsi
index d53b247..3624b81 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dtsi
@@ -130,14 +130,6 @@
 		status = "okay";
 	};
 
-	dummy_codec: dummy-codec {
-		status = "okay";
-		compatible = "rockchip,dummy-codec";
-		#sound-dai-cells = <0>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&rk3308_reset>;
-	};
-
 	car_rk3308_sound: car-rk3308-sound {
 		status = "okay";
 		compatible = "simple-audio-card";
@@ -152,7 +144,7 @@
 			dai-tdm-slot-width = <32>;
 		};
 		codec_master: simple-audio-card,codec {
-			sound-dai = <&dummy_codec>;
+			sound-dai = <&spi_codec>;
 		};
 	};
 };
@@ -339,6 +331,23 @@
 	status = "disabled";
 };
 
+&spi4 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi4m0_cs1 &spi4m0_pins>;
+
+	spi_codec: spi-codec@1 {
+		compatible ="rockchip,spi-codec";
+		reg = <1>;
+		spi-lsb-first;
+		spi-max-frequency = <5000000>;
+		#sound-dai-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rk3308_reset>;
+		status = "okay";
+	};
+};
+
 &uart7 {
 	/delete-property/ dmas;
 	status = "okay";
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22.dts
index c298616..c36f02f 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22.dts
@@ -7,7 +7,9 @@
 /dts-v1/;
 
 #include "rk3588-vehicle-evb-v21.dtsi"
+#include "rk3588-vehicle-evb-v22-nca9539-io-expander.dtsi"
 #include "rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi"
+#include "rk3588-vehicle-evb-maxim-max96756-dphy0.dtsi"
 #include "rk3588-vehicle-serdes-mfd-display-rohm.dtsi"
 #include "rk3588-android.dtsi"
 
@@ -27,6 +29,8 @@
 		vin-supply = <&vcc12v_dcin>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&vcc5v0_buck_en>;
+		startup-delay-us = <2500>;
+		off-on-delay-us = <1500>;
 		regulator-state-mem {
 			regulator-on-in-suspend;
 			regulator-suspend-microvolt = <5000000>;
@@ -59,7 +63,7 @@
 		regulator-min-microvolt = <12000000>;
 		regulator-max-microvolt = <12000000>;
 		enable-active-high;
-		gpio = <&i2c5_nca9539_gpio 0 GPIO_ACTIVE_HIGH>;
+		gpio = <&nca9539_gpio 0 GPIO_ACTIVE_HIGH>;
 		vin-supply = <&vcc12v_dcin>;
 		regulator-state-mem {
 			regulator-off-in-suspend;
@@ -75,7 +79,7 @@
 		regulator-min-microvolt = <12000000>;
 		regulator-max-microvolt = <12000000>;
 		enable-active-high;
-		gpio = <&i2c5_nca9539_gpio 1 GPIO_ACTIVE_HIGH>;
+		gpio = <&nca9539_gpio 1 GPIO_ACTIVE_HIGH>;
 		vin-supply = <&vcc12v_dcin>;
 		regulator-state-mem {
 			regulator-off-in-suspend;
@@ -91,7 +95,7 @@
 		regulator-min-microvolt = <12000000>;
 		regulator-max-microvolt = <12000000>;
 		enable-active-high;
-		gpio = <&i2c5_nca9539_gpio 2 GPIO_ACTIVE_HIGH>;
+		gpio = <&nca9539_gpio 2 GPIO_ACTIVE_HIGH>;
 		vin-supply = <&vcc12v_dcin>;
 		regulator-state-mem {
 			regulator-off-in-suspend;
@@ -107,7 +111,7 @@
 		regulator-min-microvolt = <12000000>;
 		regulator-max-microvolt = <12000000>;
 		enable-active-high;
-		gpio = <&i2c5_nca9539_gpio 3 GPIO_ACTIVE_HIGH>;
+		gpio = <&nca9539_gpio 3 GPIO_ACTIVE_HIGH>;
 		vin-supply = <&vcc12v_dcin>;
 		regulator-state-mem {
 			regulator-off-in-suspend;
@@ -123,7 +127,7 @@
 		regulator-min-microvolt = <12000000>;
 		regulator-max-microvolt = <12000000>;
 		enable-active-high;
-		gpio = <&i2c5_nca9539_gpio 4 GPIO_ACTIVE_HIGH>;
+		gpio = <&nca9539_gpio 4 GPIO_ACTIVE_HIGH>;
 		vin-supply = <&vcc12v_dcin>;
 		regulator-state-mem {
 			regulator-off-in-suspend;
@@ -139,7 +143,7 @@
 		regulator-min-microvolt = <12000000>;
 		regulator-max-microvolt = <12000000>;
 		enable-active-high;
-		gpio = <&i2c5_nca9539_gpio 5 GPIO_ACTIVE_HIGH>;
+		gpio = <&nca9539_gpio 5 GPIO_ACTIVE_HIGH>;
 		vin-supply = <&vcc12v_dcin>;
 		regulator-state-mem {
 			regulator-off-in-suspend;
@@ -147,15 +151,16 @@
 		};
 	};
 
-	camera1_vcc12v_buck: camera1_vcc12v-buck {
+	dcphy0_vcc12v_buck: dcphy0_vcc12v-buck {
 		compatible = "regulator-fixed";
-		regulator-name = "camera1_vcc12v_buck";
+		regulator-name = "dcphy0_vcc12v_buck";
 		regulator-boot-on;
-		regulator-always-on;
 		regulator-min-microvolt = <12000000>;
 		regulator-max-microvolt = <12000000>;
 		enable-active-high;
-		gpio = <&i2c5_nca9539_gpio 6 GPIO_ACTIVE_HIGH>;
+		gpio = <&nca9539_gpio 6 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <2000>;
+		off-on-delay-us = <16000>;
 		vin-supply = <&vcc12v_dcin>;
 		regulator-state-mem {
 			regulator-off-in-suspend;
@@ -163,15 +168,16 @@
 		};
 	};
 
-	camera2_vcc12v_buck: camera2_vcc12v-buck {
+	dcphy1_vcc12v_buck: dcphy1_vcc12v-buck {
 		compatible = "regulator-fixed";
-		regulator-name = "camera2_vcc12v_buck";
+		regulator-name = "dcphy1_vcc12v_buck";
 		regulator-boot-on;
-		regulator-always-on;
 		regulator-min-microvolt = <12000000>;
 		regulator-max-microvolt = <12000000>;
 		enable-active-high;
-		gpio = <&i2c5_nca9539_gpio 7 GPIO_ACTIVE_HIGH>;
+		gpio = <&nca9539_gpio 7 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <2000>;
+		off-on-delay-us = <16000>;
 		vin-supply = <&vcc12v_dcin>;
 		regulator-state-mem {
 			regulator-off-in-suspend;
@@ -179,15 +185,16 @@
 		};
 	};
 
-	camera3_vcc12v_buck: camera3_vcc12v-buck {
+	dphy0_vcc12v_buck: dphy0_vcc12v-buck {
 		compatible = "regulator-fixed";
-		regulator-name = "camera3_vcc12v_buck";
+		regulator-name = "dphy0_vcc12v_buck";
 		regulator-boot-on;
-		regulator-always-on;
 		regulator-min-microvolt = <12000000>;
 		regulator-max-microvolt = <12000000>;
 		enable-active-high;
-		gpio = <&i2c5_nca9539_gpio 8 GPIO_ACTIVE_HIGH>;
+		gpio = <&nca9539_gpio 8 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <2000>;
+		off-on-delay-us = <16000>;
 		vin-supply = <&vcc12v_dcin>;
 		regulator-state-mem {
 			regulator-off-in-suspend;
@@ -195,15 +202,16 @@
 		};
 	};
 
-	camera4_vcc12v_buck: camera4_vcc12v-buck {
+	dphy3_vcc12v_buck: dphy3_vcc12v-buck {
 		compatible = "regulator-fixed";
-		regulator-name = "camera4_vcc12v_buck";
+		regulator-name = "dphy3_vcc12v_buck";
 		regulator-boot-on;
-		regulator-always-on;
 		regulator-min-microvolt = <12000000>;
 		regulator-max-microvolt = <12000000>;
 		enable-active-high;
-		gpio = <&i2c5_nca9539_gpio 9 GPIO_ACTIVE_HIGH>;
+		gpio = <&nca9539_gpio 9 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <2000>;
+		off-on-delay-us = <16000>;
 		vin-supply = <&vcc12v_dcin>;
 		regulator-state-mem {
 			regulator-off-in-suspend;
@@ -219,7 +227,9 @@
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
 		enable-active-high;
-		gpio = <&i2c5_nca9539_gpio 10 GPIO_ACTIVE_HIGH>;
+		gpio = <&nca9539_gpio 10 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <2000>;
+		off-on-delay-us = <16000>;
 		vin-supply = <&vcc5v0_usb>;
 	};
 
@@ -231,7 +241,9 @@
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
 		enable-active-high;
-		gpio = <&i2c5_nca9539_gpio 11 GPIO_ACTIVE_HIGH>;
+		gpio = <&nca9539_gpio 11 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <2000>;
+		off-on-delay-us = <16000>;
 		vin-supply = <&vcc5v0_usb>;
 	};
 
@@ -243,7 +255,7 @@
 		regulator-min-microvolt = <12000000>;
 		regulator-max-microvolt = <12000000>;
 		enable-active-high;
-		gpio = <&i2c5_nca9539_gpio 12 GPIO_ACTIVE_HIGH>;
+		gpio = <&nca9539_gpio 12 GPIO_ACTIVE_HIGH>;
 		vin-supply = <&vcc12v_dcin>;
 		regulator-state-mem {
 			regulator-off-in-suspend;
@@ -255,22 +267,22 @@
 		compatible = "regulator-fixed";
 		regulator-name = "minipcie_power_buck";
 		regulator-boot-on;
-		regulator-always-on;
-		regulator-min-microvolt = <12000000>;
-		regulator-max-microvolt = <12000000>;
+		//regulator-always-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
 		enable-active-high;
-		gpio = <&i2c5_nca9539_gpio 13 GPIO_ACTIVE_HIGH>;
-		vin-supply = <&vcc5v0_usb>;
+		gpio = <&nca9539_gpio 13 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc5v0_buck>;
 		regulator-state-mem {
-			regulator-off-in-suspend;
-			regulator-suspend-microvolt = <12000000>;
+			regulator-on-in-suspend;
+			regulator-suspend-microvolt = <3300000>;
 		};
 	};
 
 	bt-sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "dsp_a";
-		simple-audio-card,bitclock-inversion = <1>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <256>;
 		simple-audio-card,name = "rockchip,bt";
 		simple-audio-card,cpu {
@@ -329,6 +341,18 @@
 	};
 };
 
+&max96712_dphy3_vcc1v2 {
+	vin-supply = <&vcc5v0_buck>;
+};
+
+&max96712_dphy3_poc {
+	vin-supply = <&dphy3_vcc12v_buck>;
+};
+
+&max96756_dphy0_vcc1v2 {
+	vin-supply = <&vcc5v0_buck>;
+};
+
 &avdd1v8_ddr_pll_s0 {
 	regulator-state-mem {
 		regulator-on-in-suspend;
@@ -351,12 +375,12 @@
 };
 
 &i2c2_bu18tl82 {
-	//route-enable;
-	use-delay-work;
+	route-enable;
+	//use-delay-work;
 };
 
 &i2c2_bu18rl82 {
-	use-delay-work;
+	//use-delay-work;
 	vpower-supply = <&lcd1_vcc12v_buck>;
 };
 
@@ -367,11 +391,11 @@
 };
 
 &i2c4_bu18tl82 {
-	use-delay-work;
+	//use-delay-work;
 };
 
 &i2c4_bu18rl82 {
-	use-delay-work;
+	//use-delay-work;
 	vpower-supply = <&lcd5_vcc12v_buck>;
 };
 
@@ -380,44 +404,14 @@
 		interrupt-parent = <&gpio1>;
 		interrupts = <RK_PA5 IRQ_TYPE_LEVEL_LOW>;
 	};
-
-	i2c5_nca9539: i2c5-nca9539@74 {
-		compatible = "novo,nca9539";
-		reg = <0x74>;
-		status = "okay";
-
-		/* P00-P07 P10-P17 output HIGH level default*/
-		serdes-init-sequence = [
-			0002 00ff
-			0003 00ff
-			0004 0000
-			0005 0000
-			0006 0000
-			0007 0000
-		];
-
-		i2c5_nca9539_pinctrl: i2c5-nca9539-pinctrl {
-			compatible = "novo,nca9539-pinctrl";
-			status = "okay";
-
-			i2c5_nca9539_gpio: i2c5-nca9539-gpio {
-				compatible = "novo,nca9539-gpio";
-				status = "okay";
-
-				gpio-controller;
-				#gpio-cells = <2>;
-				gpio-ranges = <&i2c5_nca9539_pinctrl 0 256 16>;
-			};
-		};
-	};
 };
 
 &i2c5_bu18tl82 {
-	use-delay-work;
+	//use-delay-work;
 };
 
 &i2c5_bu18rl82 {
-	use-delay-work;
+	//use-delay-work;
 	vpower-supply = <&lcd3_vcc12v_buck>;
 };
 
@@ -428,8 +422,8 @@
 };
 
 &i2c6_bu18tl82 {
-	//route-enable;
-	use-delay-work;
+	route-enable;
+	//use-delay-work;
 };
 
 &i2c6_bu18rl82 {
@@ -438,6 +432,10 @@
 };
 
 &pinctrl {
+	pinctrl-names = "init";
+	pinctrl-0 = <&max96712_dphy3_pwdn
+			&max96712_dphy3_errb
+			&max96712_dphy3_lock>;
 
 	bl {
 		bl0_enable_pin: bl0-enable-pin {
@@ -471,15 +469,15 @@
 
 	max96712-dphy3 {
 		max96712_dphy3_pwdn: max96712-dphy3-pwdn {
-			rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_output_low>;
 		};
 
 		max96712_dphy3_errb: max96712-dphy3-errb {
-			rockchip,pins = <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 
 		max96712_dphy3_lock: max96712-dphy3-lock {
-			rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 	};
 
@@ -543,11 +541,11 @@
 };
 
 &route_dsi0 {
-	status = "disabled";
+	status = "okay";
 };
 
 &route_dsi1 {
-	status = "disabled";
+	status = "okay";
 };
 
 &u2phy1_otg {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-maxim-cameras-s66.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-maxim-cameras-s66.dtsi
index c4fe0cb..c9a6c4e 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-maxim-cameras-s66.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-maxim-cameras-s66.dtsi
@@ -1151,27 +1151,27 @@
 &pinctrl {
 	maxim-cameras {
 		max96712_dphy0_pwdn: max96712-dphy0-pwdn {
-			rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_output_low>;
 		};
 
 		max96712_dphy0_errb: max96712-dphy0-errb {
-			rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 
 		max96712_dphy0_lock: max96712-dphy0-lock {
-			rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 
 		max96722_dphy3_pwdn: max96722-dphy3-pwdn {
-			rockchip,pins = <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <1 RK_PC7 RK_FUNC_GPIO &pcfg_output_low>;
 		};
 
 		max96722_dphy3_errb: max96722-dphy3-errb {
-			rockchip,pins = <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 
 		max96722_dphy3_lock: max96722-dphy3-lock {
-			rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none_smt>;
 		};
 	};
 };
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-s66-v10.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-s66-v10.dts
index e27ee51..59abe8d 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-s66-v10.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-s66-v10.dts
@@ -87,3 +87,13 @@
 		regulator-on-in-suspend;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "init";
+	pinctrl-0 = <&max96712_dphy0_pwdn
+			&max96712_dphy0_errb
+			&max96712_dphy0_lock
+			&max96722_dphy3_pwdn
+			&max96722_dphy3_errb
+			&max96722_dphy3_lock>;
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-display-v20.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-display-v20.dtsi
index dabfc3d..c51d5eb 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-display-v20.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-display-v20.dtsi
@@ -200,14 +200,14 @@
 		default-brightness-level = <200>;
 	};
 
-	dsi2lvds_panel0 {
+	dsi2lvds_panel0: dsi2lvds-panel0 {
 		compatible = "simple-panel";
 		backlight = <&backlight>;
 
 		display-timings {
 			native-mode = <&dsi2lvds0>;
 			dsi2lvds0: timing0 {
-				clock-frequency = <88208000>;
+				clock-frequency = <87381333>;
 				hactive = <1920>;
 				vactive = <720>;
 				hfront-porch = <32>;
@@ -236,14 +236,14 @@
 		};
 	};
 
-	dsi2lvds_panel1 {
+	dsi2lvds_panel1: dsi2lvds-panel1 {
 		compatible = "simple-panel";
 		backlight = <&dsi2lvds_backlight1>;
 
 		display-timings {
 			native-mode = <&dsi2lvds1>;
 			dsi2lvds1: timing0 {
-				clock-frequency = <88208000>;
+				clock-frequency = <87381333>;
 				hactive = <1920>;
 				vactive = <720>;
 				hfront-porch = <32>;
@@ -272,12 +272,12 @@
 		};
 	};
 
-	dp2lvds_panel0 {
+	dp2lvds_panel0: dp2lvds-panel0 {
 		compatible = "simple-panel";
 		backlight = <&dp2lvds_backlight0>;
 		status = "okay";
 
-		panel-timing {
+		dp2lvds0_panel_timing: panel-timing {
 			clock-frequency = <148500000>;
 			hactive = <1920>;
 			vactive = <1080>;
@@ -300,12 +300,12 @@
 		};
 	};
 
-	dp2lvds_panel1 {
+	dp2lvds_panel1: dp2lvds-panel1 {
 		compatible = "simple-panel";
 		backlight = <&dp2lvds_backlight1>;
 		status = "okay";
 
-		panel-timing {
+		dp2lvds1_panel_timing: panel-timing {
 			clock-frequency = <148500000>;
 			hactive = <1920>;
 			vactive = <1080>;
@@ -328,12 +328,12 @@
 		};
 	};
 
-	edp2lvds_panel0 {
+	edp2lvds_panel0: edp2lvds-panel0 {
 		compatible = "simple-panel";
 		backlight = <&edp2lvds_backlight0>;
 		status = "okay";
 
-		panel-timing {
+		edp2lvds0_panel_timing: panel-timing {
 			clock-frequency = <148500000>;
 			hactive = <1920>;
 			vactive = <1080>;
@@ -356,12 +356,12 @@
 		};
 	};
 
-	edp2lvds_panel1 {
+	edp2lvds_panel1: edp2lvds-panel1 {
 		compatible = "simple-panel";
 		backlight = <&edp2lvds_backlight1>;
 		status = "okay";
 
-		panel-timing {
+		edp2lvds1_panel_timing: panel-timing {
 			clock-frequency = <148500000>;
 			hactive = <1920>;
 			vactive = <1080>;
@@ -631,12 +631,9 @@
 	pinctrl-0 = <&i2c2m4_xfer>;
 	clock-frequency = <400000>;
 
-	bu18tl82: bu18tl82@10 {
+	i2c2_bu18tl82: i2c2-bu18tl82@10 {
 		compatible = "rohm,bu18tl82";
 		reg = <0x10>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&ser0_rst_pin>;
-		reset-gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_LOW>;
 		sel-mipi;
 		status = "okay";
 
@@ -723,6 +720,50 @@
 			0446 001f
 		];
 
+		i2c2_bu18tl82_pinctrl: i2c2-bu18tl82-pinctrl {
+			compatible = "rohm,bu18tl82-pinctrl";
+			pinctrl-names = "default","sleep";
+			pinctrl-0 = <&i2c2_bu18tl82_panel_pins>;
+			pinctrl-1 = <&i2c2_bu18tl82_panel_pins>;
+			status = "okay";
+
+			i2c2_bu18tl82_panel_pins: panel-pins {
+				lcd-bl-pwm {
+					pins = "BU18TL82_GPIO0";
+					function = "SER_TO_DES_GPIO0";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18TL82_GPIO1";
+					function = "SER_TO_DES_GPIO1";
+				};
+
+				ser-irq {
+					pins = "BU18TL82_GPIO2";
+					function = "DES_GPIO2_TO_SER";
+				};
+
+				tp-int {
+					pins = "BU18TL82_GPIO3";
+					function = "DES_GPIO4_TO_SER";
+				};
+			};
+
+			i2c2_bu18tl82_gpio: i2c2-bu18tl82-gpio {
+				compatible = "rohm,bu18tl82-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c2_bu18tl82_pinctrl 0 160 8>;
+			};
+		};
+
+		i2c2_bu18tl82_bridge: i2c2-bu18tl82-bridge {
+			compatible = "rohm,bu18tl82-bridge";
+			status = "okay";
+		};
+
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -745,7 +786,7 @@
 		};
 	};
 
-	bu18rl82: bu18rl82@30 {
+	i2c2_bu18rl82: i2c2-bu18rl82@30 {
 		compatible = "rohm,bu18rl82";
 		reg = <0x30>;
 		status = "okay";
@@ -810,6 +851,83 @@
 			0646 001f
 		];
 
+		i2c2_bu18rl82_pinctrl: i2c2-bu18rl82-pinctrl {
+			compatible = "rohm,bu18rl82-pinctrl";
+			pinctrl-names = "default","init","sleep";
+			pinctrl-0 = <&i2c2_bu18rl82_panel_pins>;
+			pinctrl-1 = <&i2c2_bu18rl82_panel_pins>;
+			pinctrl-2 = <&i2c2_bu18rl82_panel_sleep_pins>;
+			status = "okay";
+
+			i2c2_bu18rl82_panel_pins: panel-pins {
+				lcd-otp-pin {
+					pins = "BU18RL82_GPIO5";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				tp-rst {
+					pins = "BU18RL82_GPIO3";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				lcd-rst {
+					pins = "BU18RL82_GPIO2";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				tp-int {
+					pins = "BU18RL82_GPIO4";
+					function = "DES_TO_SER_GPIO3";
+				};
+
+				100ms-delay {
+					pins = "BU18RL82_GPIO1";
+					function = "DELAY_100MS";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18RL82_GPIO1";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				lcd-bl-pwm {
+					pins = "BU18RL82_GPIO0";
+					function = "SER_GPIO0_TO_DES";
+				};
+			};
+
+			i2c2_bu18rl82_panel_sleep_pins: panel-sleep-pins {
+				lcd-rst-sleep {
+					pins = "BU18RL82_GPIO2";
+					function = "DES_GPIO_OUTPUT_LOW";
+				};
+
+				tp-rst-sleep {
+					pins = "BU18RL82_GPIO3";
+					function = "DES_GPIO_OUTPUT_LOW";
+				};
+
+				lcd-otp-pin-sleep {
+					pins = "BU18RL82_GPIO5";
+					function = "DES_GPIO_OUTPUT_LOW";
+				};
+			};
+
+			i2c2_bu18rl82_gpio: i2c2-bu18rl82-gpio {
+				compatible = "rohm,bu18rl82-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c2_bu18rl82_pinctrl 0 169 8>;
+			};
+		};
+
+		i2c2_bu18rl82_bridge: i2c2-bu18rl82-bridge {
+			compatible = "rohm,bu18rl82-bridge";
+			status = "okay";
+		};
+
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -839,7 +957,7 @@
 	clock-frequency = <400000>;
 	status = "okay";
 
-	bu18tl82@10 {
+	i2c4_bu18tl82: i2c4-bu18tl82@10 {
 		compatible = "rohm,bu18tl82";
 		reg = <0x10>;
 		status = "okay";
@@ -904,6 +1022,51 @@
 			0446 001f
 		];
 
+		i2c4_bu18tl82_pinctrl: i2c4-bu18tl82-pinctrl {
+			compatible = "rohm,bu18tl82-pinctrl";
+			pinctrl-names = "default","sleep";
+			pinctrl-0 = <&i2c4_bu18tl82_panel_pins>;
+			pinctrl-1 = <&i2c4_bu18tl82_panel_pins>;
+			status = "okay";
+
+			i2c4_bu18tl82_panel_pins: panel-pins {
+				lcd-bl-pwm {
+					pins = "BU18TL82_GPIO0";
+					function = "SER_TO_DES_GPIO0";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18TL82_GPIO1";
+					function = "SER_TO_DES_GPIO1";
+				};
+
+				ser-irq {
+					pins = "BU18TL82_GPIO2";
+					function = "DES_GPIO2_TO_SER";
+				};
+
+				tp-int {
+					pins = "BU18TL82_GPIO3";
+					function = "DES_GPIO4_TO_SER";
+				};
+
+			};
+
+			i2c4_bu18tl82_gpio: i2c4-bu18tl82-gpio {
+				compatible = "rohm,bu18tl82-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c4_bu18tl82_pinctrl 0 178 8>;
+			};
+		};
+
+		i2c4_bu18tl82_bridge: i2c4-bu18tl82-bridge {
+			compatible = "rohm,bu18tl82-bridge";
+			status = "okay";
+		};
+
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -926,7 +1089,7 @@
 		};
 	};
 
-	bu18rl82@30 {
+	i2c4_bu18rl82: i2c4-bu18rl82@30 {
 		compatible = "rohm,bu18rl82";
 		reg = <0x30>;
 		status = "okay";
@@ -986,6 +1149,83 @@
 			0646 001f
 		];
 
+		i2c4_bu18rl82_pinctrl: i2c4-bu18rl82-pinctrl {
+			compatible = "rohm,bu18rl82-pinctrl";
+			pinctrl-names = "default","init","sleep";
+			pinctrl-0 = <&i2c4_bu18rl82_panel_pins>;
+			pinctrl-1 = <&i2c4_bu18rl82_panel_pins>;
+			pinctrl-2 = <&i2c4_bu18rl82_panel_sleep_pins>;
+			status = "okay";
+
+			i2c4_bu18rl82_panel_pins: panel-pins {
+				lcd-otp-pin {
+					pins = "BU18RL82_GPIO5";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				tp-rst {
+					pins = "BU18RL82_GPIO3";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				lcd-rst {
+					pins = "BU18RL82_GPIO2";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				tp-int {
+					pins = "BU18RL82_GPIO4";
+					function = "DES_TO_SER_GPIO3";
+				};
+
+				100ms-delay {
+					pins = "BU18RL82_GPIO1";
+					function = "DELAY_100MS";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18RL82_GPIO1";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				lcd-bl-pwm {
+					pins = "BU18RL82_GPIO0";
+					function = "SER_GPIO0_TO_DES";
+				};
+			};
+
+			i2c4_bu18rl82_panel_sleep_pins: panel-sleep-pins {
+				lcd-rst-sleep {
+					pins = "BU18RL82_GPIO2";
+					function = "DES_GPIO_OUTPUT_LOW";
+				};
+
+				tp-rst-sleep {
+					pins = "BU18RL82_GPIO3";
+					function = "DES_GPIO_OUTPUT_LOW";
+				};
+
+				lcd-otp-pin-sleep {
+					pins = "BU18RL82_GPIO5";
+					function = "DES_GPIO_OUTPUT_LOW";
+				};
+			};
+
+			i2c4_bu18rl82_gpio: i2c4-bu18rl82-gpio {
+				compatible = "rohm,bu18rl82-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c4_bu18rl82_pinctrl 0 187 8>;
+			};
+		};
+
+		i2c4_bu18rl82_bridge: i2c4-bu18rl82-bridge {
+			compatible = "rohm,bu18rl82-bridge";
+			status = "okay";
+		};
+
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -1020,7 +1260,7 @@
 	clock-frequency = <400000>;
 	status = "okay";
 
-	bu18tl82@10 {
+	i2c5_bu18tl82: i2c5-bu18tl82@10 {
 		compatible = "rohm,bu18tl82";
 		reg = <0x10>;
 		status = "okay";
@@ -1088,6 +1328,51 @@
 			0446 001f
 		];
 
+		i2c5_bu18tl82_pinctrl: i2c5-bu18tl82-pinctrl {
+			compatible = "rohm,bu18tl82-pinctrl";
+			pinctrl-names = "default","sleep";
+			pinctrl-0 = <&i2c5_bu18tl82_panel_pins>;
+			pinctrl-1 = <&i2c5_bu18tl82_panel_pins>;
+			status = "okay";
+
+			i2c5_bu18tl82_panel_pins: panel-pins {
+				lcd-bl-pwm {
+					pins = "BU18TL82_GPIO0";
+					function = "SER_TO_DES_GPIO0";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18TL82_GPIO1";
+					function = "SER_TO_DES_GPIO1";
+				};
+
+				ser-irq {
+					pins = "BU18TL82_GPIO2";
+					function = "DES_GPIO2_TO_SER";
+				};
+
+				tp-int {
+					pins = "BU18TL82_GPIO3";
+					function = "DES_GPIO3_TO_SER";
+				};
+			};
+
+
+			i2c5_bu18tl82_gpio: i2c5-bu18tl82-gpio {
+				compatible = "rohm,bu18tl82-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c5_bu18tl82_pinctrl 0 196 8>;
+			};
+		};
+
+		i2c5_bu18tl82_bridge: i2c5-bu18tl82-bridge {
+			compatible = "rohm,bu18tl82-bridge";
+			status = "okay";
+		};
+
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -1110,7 +1395,7 @@
 		};
 	};
 
-	bu18rl82@30 {
+	i2c5_bu18rl82: i2c5-bu18rl82@30 {
 		compatible = "rohm,bu18rl82";
 		reg = <0x30>;
 		status = "okay";
@@ -1173,6 +1458,83 @@
 			0646 001f
 		];
 
+		i2c5_bu18rl82_pinctrl: i2c5-bu18rl82-pinctrl {
+			compatible = "rohm,bu18rl82-pinctrl";
+			pinctrl-names = "default","init","sleep";
+			pinctrl-0 = <&i2c5_bu18rl82_panel_pins>;
+			pinctrl-1 = <&i2c5_bu18rl82_panel_pins>;
+			pinctrl-2 = <&i2c5_bu18rl82_panel_sleep_pins>;
+			status = "okay";
+
+			i2c5_bu18rl82_panel_pins: panel-pins {
+				lcd-otp-pin {
+					pins = "BU18RL82_GPIO5";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				tp-rst {
+					pins = "BU18RL82_GPIO3";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				lcd-rst {
+					pins = "BU18RL82_GPIO2";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				tp-int {
+					pins = "BU18RL82_GPIO4";
+					function = "DES_TO_SER_GPIO3";
+				};
+
+				100ms-delay {
+					pins = "BU18RL82_GPIO1";
+					function = "DELAY_100MS";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18RL82_GPIO1";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				lcd-bl-pwm {
+					pins = "BU18RL82_GPIO0";
+					function = "SER_GPIO0_TO_DES";
+				};
+			};
+
+			i2c5_bu18rl82_panel_sleep_pins: panel-sleep-pins {
+				lcd-rst-sleep {
+					pins = "BU18RL82_GPIO2";
+					function = "DES_GPIO_OUTPUT_LOW";
+				};
+
+				tp-rst-sleep {
+					pins = "BU18RL82_GPIO4";
+					function = "DES_GPIO_OUTPUT_LOW";
+				};
+
+				lcd-otp-pin-sleep {
+					pins = "BU18RL82_GPIO5";
+					function = "DES_GPIO_OUTPUT_LOW";
+				};
+			};
+
+			i2c5_bu18rl82_gpio: i2c5-bu18rl82-gpio {
+				compatible = "rohm,bu18rl82-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c5_bu18rl82_pinctrl 0 205 8>;
+			};
+		};
+
+		i2c5_bu18rl82_bridge: i2c5-bu18rl82-bridge {
+			compatible = "rohm,bu18rl82-bridge";
+			status = "okay";
+		};
+
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -1195,16 +1557,7 @@
 		};
 	};
 
-	ilitek@41 {
-		compatible = "ilitek,ili251x";
-		reg = <0x41>;
-		interrupt-parent = <&gpio0>;
-		interrupts = <RK_PD1 IRQ_TYPE_LEVEL_LOW>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&touch_pin>;
-		reset-gpio = <&gpio0 RK_PD4 GPIO_ACTIVE_LOW>;
-		ilitek,name = "ilitek_i2c";
-	};
+
 
 	lt7911d@2b {
 		compatible = "lontium,lt7911d-fb-notifier";
@@ -1220,12 +1573,9 @@
 	pinctrl-0 = <&i2c6m3_xfer>;
 	clock-frequency = <400000>;
 
-	bu18tl82@10 {
+	i2c6_bu18tl82: i2c6-bu18tl82@10 {
 		compatible = "rohm,bu18tl82";
 		reg = <0x10>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&ser1_rst_pin>;
-		reset-gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>;
 		sel-mipi;
 		status = "okay";
 		serdes-init-sequence = [
@@ -1313,6 +1663,51 @@
 			0446 001f
 		];
 
+		i2c6_bu18tl82_pinctrl: i2c6-bu18tl82-pinctrl {
+			compatible = "rohm,bu18tl82-pinctrl";
+			pinctrl-names = "default","sleep";
+			pinctrl-0 = <&i2c6_bu18tl82_panel_pins>;
+			pinctrl-1 = <&i2c6_bu18tl82_panel_pins>;
+			status = "okay";
+
+			i2c6_bu18tl82_panel_pins: panel-pins {
+				lcd-bl-pwm {
+					pins = "BU18TL82_GPIO0";
+					function = "SER_TO_DES_GPIO0";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18TL82_GPIO1";
+					function = "SER_TO_DES_GPIO1";
+				};
+
+				ser-irq {
+					pins = "BU18TL82_GPIO2";
+					function = "DES_GPIO2_TO_SER";
+				};
+
+				tp-int {
+					pins = "BU18TL82_GPIO3";
+					function = "DES_GPIO4_TO_SER";
+				};
+			};
+
+
+			i2c6_bu18tl82_gpio: i2c6-bu18tl82-gpio {
+				compatible = "rohm,bu18tl82-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c6_bu18tl82_pinctrl 0 214 8>;
+			};
+		};
+
+		i2c6_bu18tl82_bridge: i2c6-bu18tl82-bridge {
+			compatible = "rohm,bu18tl82-bridge";
+			status = "okay";
+		};
+
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -1335,7 +1730,7 @@
 		};
 	};
 
-	bu18rl82@30 {
+	i2c6_bu18rl82: i2c6-bu18rl82@30 {
 		compatible = "rohm,bu18rl82";
 		reg = <0x30>;
 		status = "okay";
@@ -1402,6 +1797,83 @@
 			0646 001f
 		];
 
+		i2c6_bu18rl82_pinctrl: i2c6-bu18rl82-pinctrl {
+			compatible = "rohm,bu18rl82-pinctrl";
+			pinctrl-names = "default","init","sleep";
+			pinctrl-0 = <&i2c6_bu18rl82_panel_pins>;
+			pinctrl-1 = <&i2c6_bu18rl82_panel_pins>;
+			pinctrl-2 = <&i2c6_bu18rl82_panel_sleep_pins>;
+			status = "okay";
+
+			i2c6_bu18rl82_panel_pins: panel-pins {
+				lcd-otp-pin {
+					pins = "BU18RL82_GPIO5";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				tp-rst {
+					pins = "BU18RL82_GPIO3";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				lcd-rst {
+					pins = "BU18RL82_GPIO2";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				tp-int {
+					pins = "BU18RL82_GPIO4";
+					function = "DES_TO_SER_GPIO3";
+				};
+
+				100ms-delay {
+					pins = "BU18RL82_GPIO1";
+					function = "DELAY_100MS";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18RL82_GPIO1";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				lcd-bl-pwm {
+					pins = "BU18RL82_GPIO0";
+					function = "SER_GPIO0_TO_DES";
+				};
+			};
+
+			i2c6_bu18rl82_panel_sleep_pins: panel-sleep-pins {
+				lcd-rst-sleep {
+					pins = "BU18RL82_GPIO2";
+					function = "DES_GPIO_OUTPUT_LOW";
+				};
+
+				tp-rst-sleep {
+					pins = "BU18RL82_GPIO3";
+					function = "DES_GPIO_OUTPUT_LOW";
+				};
+
+				lcd-otp-pin-sleep {
+					pins = "BU18RL82_GPIO5";
+					function = "DES_GPIO_OUTPUT_LOW";
+				};
+			};
+
+			i2c6_bu18rl82_gpio: i2c6-bu18rl82-gpio {
+				compatible = "rohm,bu18rl82-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c6_bu18rl82_pinctrl 0 223 8>;
+			};
+		};
+
+		i2c6_bu18rl82_bridge: i2c6-bu18rl82-bridge {
+			compatible = "rohm,bu18rl82-bridge";
+			status = "okay";
+		};
+
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -1431,7 +1903,7 @@
 	clock-frequency = <400000>;
 	status = "okay";
 
-	bu18tl82@10 {
+	i2c7_bu18tl82: i2c7-bu18tl82@10 {
 		compatible = "rohm,bu18tl82";
 		reg = <0x10>;
 		status = "okay";
@@ -1496,6 +1968,49 @@
 			0446 001f
 		];
 
+		i2c7_bu18tl82_pinctrl: i2c7-bu18tl82-pinctrl {
+			compatible = "rohm,bu18tl82-pinctrl";
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c7_bu18tl82_panel_pins>;
+			status = "okay";
+
+			i2c7_bu18tl82_panel_pins: panel-pins {
+				lcd-bl-pwm {
+					pins = "BU18TL82_GPIO0";
+					function = "SER_TO_DES_GPIO0";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18TL82_GPIO1";
+					function = "SER_TO_DES_GPIO1";
+				};
+
+				ser-irq {
+					pins = "BU18TL82_GPIO2";
+					function = "DES_GPIO2_TO_SER";
+				};
+
+				tp-int {
+					pins = "BU18TL82_GPIO3";
+					function = "DES_GPIO4_TO_SER";
+				};
+			};
+
+
+			i2c7_bu18tl82_gpio: i2c7-bu18tl82-gpio {
+				compatible = "rohm,bu18tl82-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c7_bu18tl82_pinctrl 0 232 8>;
+			};
+		};
+
+		i2c7_bu18tl82_bridge: i2c7-bu18tl82-bridge {
+			compatible = "rohm,bu18tl82-bridge";
+			status = "okay";
+		};
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -1518,7 +2033,7 @@
 		};
 	};
 
-	bu18rl82@30 {
+	i2c7_bu18rl82: i2c7-bu18rl82@30 {
 		compatible = "rohm,bu18rl82";
 		reg = <0x30>;
 		status = "okay";
@@ -1577,6 +2092,59 @@
 			0645 0020
 			0646 001f
 		];
+
+		i2c7_bu18rl82_pinctrl: i2c7-bu18rl82-pinctrl {
+			compatible = "rohm,bu18rl82-pinctrl";
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c7_bu18rl82_panel_pins>;
+			status = "okay";
+
+			i2c7_bu18rl82_panel_pins: panel-pins {
+				lcd-bl-pwm {
+					pins = "BU18RL82_GPIO0";
+					function = "SER_GPIO0_TO_DES";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18RL82_GPIO1";
+					function = "SER_GPIO1_TO_DES";
+				};
+
+				lcd-rst {
+					pins = "BU18RL82_GPIO2";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				tp-rst {
+					pins = "BU18RL82_GPIO3";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				tp-int {
+					pins = "BU18RL82_GPIO4";
+					function = "DES_TO_SER_GPIO3";
+				};
+
+				lcd-otp-pin {
+					pins = "BU18RL82_GPIO5";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+			};
+
+			i2c7_bu18rl82_gpio: i2c7-bu18rl82-gpio {
+				compatible = "rohm,bu18rl82-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c7_bu18rl82_pinctrl 0 241 8>;
+			};
+		};
+
+		i2c7_bu18rl82_bridge: i2c7-bu18rl82-bridge {
+			compatible = "rohm,bu18rl82-bridge";
+			status = "okay";
+		};
 
 		ports {
 			#address-cells = <1>;
@@ -1614,7 +2182,7 @@
 	clock-frequency = <400000>;
 	status = "okay";
 
-	bu18tl82@10 {
+	i2c8_bu18tl82: i2c8-bu18tl82@10 {
 		compatible = "rohm,bu18tl82";
 		reg = <0x10>;
 		status = "okay";
@@ -1679,6 +2247,50 @@
 			0446 001f
 		];
 
+		i2c8_bu18tl82_pinctrl: i2c8-bu18tl82-pinctrl {
+			compatible = "rohm,bu18tl82-pinctrl";
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c8_bu18tl82_panel_pins>;
+			status = "okay";
+
+			i2c8_bu18tl82_panel_pins: panel-pins {
+				lcd-bl-pwm {
+					pins = "BU18TL82_GPIO0";
+					function = "SER_TO_DES_GPIO0";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18TL82_GPIO1";
+					function = "SER_TO_DES_GPIO1";
+				};
+
+				ser-irq {
+					pins = "BU18TL82_GPIO2";
+					function = "DES_GPIO2_TO_SER";
+				};
+
+				tp-int {
+					pins = "BU18TL82_GPIO3";
+					function = "DES_GPIO4_TO_SER";
+				};
+			};
+
+
+			i2c8_bu18tl82_gpio: i2c8-bu18tl82-gpio {
+				compatible = "rohm,bu18tl82-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c8_bu18tl82_pinctrl 0 250 8>;
+			};
+		};
+
+		i2c8_bu18tl82_bridge: i2c8-bu18tl82-bridge {
+			compatible = "rohm,bu18tl82-bridge";
+			status = "okay";
+		};
+
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -1701,7 +2313,7 @@
 		};
 	};
 
-	bu18rl82@30 {
+	i2c8_bu18rl82: i2c8-bu18rl82@30 {
 		compatible = "rohm,bu18rl82";
 		reg = <0x30>;
 		status = "okay";
@@ -1761,6 +2373,59 @@
 			0646 001f
 		];
 
+		i2c8_bu18rl82_pinctrl: i2c8-bu18rl82-pinctrl {
+			compatible = "rohm,bu18rl82-pinctrl";
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c8_bu18rl82_panel_pins>;
+			status = "okay";
+
+			i2c8_bu18rl82_panel_pins: panel-pins {
+				lcd-bl-pwm {
+					pins = "BU18RL82_GPIO0";
+					function = "SER_GPIO0_TO_DES";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18RL82_GPIO1";
+					function = "SER_GPIO1_TO_DES";
+				};
+
+				lcd-rst {
+					pins = "BU18RL82_GPIO2";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				tp-rst {
+					pins = "BU18RL82_GPIO3";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				tp-int {
+					pins = "BU18RL82_GPIO4";
+					function = "DES_TO_SER_GPIO3";
+				};
+
+				lcd-otp-pin {
+					pins = "BU18RL82_GPIO5";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+			};
+
+			i2c8_bu18rl82_gpio: i2c8-bu18rl82-gpio {
+				compatible = "rohm,bu18rl82-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c8_bu18rl82_pinctrl 0 259 8>;
+			};
+		};
+
+		i2c8_bu18rl82_bridge: i2c8-bu18rl82-bridge {
+			compatible = "rohm,bu18rl82-bridge";
+			status = "okay";
+		};
+
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -1797,56 +2462,6 @@
 
 &mipi_dcphy1 {
 	status = "okay";
-};
-
-
-&pinctrl {
-
-	bl {
-		bl0_enable_pin: bl0-enable-pin {
-			rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
-
-		bl1_enable_pin: bl1-enable-pin {
-			rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
-
-		bl2_enable_pin: bl2-enable-pin {
-			rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
-
-		bl3_enable_pin: bl3-enable-pin {
-			rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
-
-		bl4_enable_pin: bl4-enable-pin {
-			rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
-
-		bl5_enable_pin: bl5-enable-pin {
-			rockchip,pins = <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
-	};
-
-	serdes {
-		//dsi0
-		ser0_rst_pin: ser0-rst-pin {
-			rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
-
-		//dsi1
-		ser1_rst_pin: ser1-rst-pin {
-			rockchip,pins = <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
-	};
-
-	touch {
-		touch_pin: touch-pin {
-			rockchip,pins =
-				<0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>,  //INT
-				<0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;  //RST
-			};
-	};
 };
 
 /* dsi0->serdes->lvds_panel */
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-maxim-split.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-maxim-split.dtsi
new file mode 100644
index 0000000..11754d8
--- /dev/null
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-maxim-split.dtsi
@@ -0,0 +1,2438 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+/ {
+	dsi2lvds_backlight1: dsi2lvds_backlight1 {
+		compatible = "pwm-backlight";
+		brightness-levels = <
+			  0  20  20  21  21  22  22  23
+			 23  24  24  25  25  26  26  27
+			 27  28  28  29  29  30  30  31
+			 31  32  32  33  33  34  34  35
+			 35  36  36  37  37  38  38  39
+			 40  41  42  43  44  45  46  47
+			 48  49  50  51  52  53  54  55
+			 56  57  58  59  60  61  62  63
+			 64  65  66  67  68  69  70  71
+			 72  73  74  75  76  77  78  79
+			 80  81  82  83  84  85  86  87
+			 88  89  90  91  92  93  94  95
+			 96  97  98  99 100 101 102 103
+			104 105 106 107 108 109 110 111
+			112 113 114 115 116 117 118 119
+			120 121 122 123 124 125 126 127
+			128 129 130 131 132 133 134 135
+			136 137 138 139 140 141 142 143
+			144 145 146 147 148 149 150 151
+			152 153 154 155 156 157 158 159
+			160 161 162 163 164 165 166 167
+			168 169 170 171 172 173 174 175
+			176 177 178 179 180 181 182 183
+			184 185 186 187 188 189 190 191
+			192 193 194 195 196 197 198 199
+			200 201 202 203 204 205 206 207
+			208 209 210 211 212 213 214 215
+			216 217 218 219 220 221 222 223
+			224 225 226 227 228 229 230 231
+			232 233 234 235 236 237 238 239
+			240 241 242 243 244 245 246 247
+			248 249 250 251 252 253 254 255
+		>;
+		default-brightness-level = <200>;
+	};
+
+	dp2lvds_backlight0: dp2lvds_backlight0 {
+		compatible = "pwm-backlight";
+		brightness-levels = <
+			  0  20  20  21  21  22  22  23
+			 23  24  24  25  25  26  26  27
+			 27  28  28  29  29  30  30  31
+			 31  32  32  33  33  34  34  35
+			 35  36  36  37  37  38  38  39
+			 40  41  42  43  44  45  46  47
+			 48  49  50  51  52  53  54  55
+			 56  57  58  59  60  61  62  63
+			 64  65  66  67  68  69  70  71
+			 72  73  74  75  76  77  78  79
+			 80  81  82  83  84  85  86  87
+			 88  89  90  91  92  93  94  95
+			 96  97  98  99 100 101 102 103
+			104 105 106 107 108 109 110 111
+			112 113 114 115 116 117 118 119
+			120 121 122 123 124 125 126 127
+			128 129 130 131 132 133 134 135
+			136 137 138 139 140 141 142 143
+			144 145 146 147 148 149 150 151
+			152 153 154 155 156 157 158 159
+			160 161 162 163 164 165 166 167
+			168 169 170 171 172 173 174 175
+			176 177 178 179 180 181 182 183
+			184 185 186 187 188 189 190 191
+			192 193 194 195 196 197 198 199
+			200 201 202 203 204 205 206 207
+			208 209 210 211 212 213 214 215
+			216 217 218 219 220 221 222 223
+			224 225 226 227 228 229 230 231
+			232 233 234 235 236 237 238 239
+			240 241 242 243 244 245 246 247
+			248 249 250 251 252 253 254 255
+		>;
+		default-brightness-level = <200>;
+	};
+
+	dp2lvds_backlight1: dp2lvds_backlight1 {
+		compatible = "pwm-backlight";
+		brightness-levels = <
+			  0  20  20  21  21  22  22  23
+			 23  24  24  25  25  26  26  27
+			 27  28  28  29  29  30  30  31
+			 31  32  32  33  33  34  34  35
+			 35  36  36  37  37  38  38  39
+			 40  41  42  43  44  45  46  47
+			 48  49  50  51  52  53  54  55
+			 56  57  58  59  60  61  62  63
+			 64  65  66  67  68  69  70  71
+			 72  73  74  75  76  77  78  79
+			 80  81  82  83  84  85  86  87
+			 88  89  90  91  92  93  94  95
+			 96  97  98  99 100 101 102 103
+			104 105 106 107 108 109 110 111
+			112 113 114 115 116 117 118 119
+			120 121 122 123 124 125 126 127
+			128 129 130 131 132 133 134 135
+			136 137 138 139 140 141 142 143
+			144 145 146 147 148 149 150 151
+			152 153 154 155 156 157 158 159
+			160 161 162 163 164 165 166 167
+			168 169 170 171 172 173 174 175
+			176 177 178 179 180 181 182 183
+			184 185 186 187 188 189 190 191
+			192 193 194 195 196 197 198 199
+			200 201 202 203 204 205 206 207
+			208 209 210 211 212 213 214 215
+			216 217 218 219 220 221 222 223
+			224 225 226 227 228 229 230 231
+			232 233 234 235 236 237 238 239
+			240 241 242 243 244 245 246 247
+			248 249 250 251 252 253 254 255
+		>;
+		default-brightness-level = <200>;
+	};
+
+	edp2lvds_backlight0: edp2lvds_backlight0 {
+		compatible = "pwm-backlight";
+		brightness-levels = <
+			  0  20  20  21  21  22  22  23
+			 23  24  24  25  25  26  26  27
+			 27  28  28  29  29  30  30  31
+			 31  32  32  33  33  34  34  35
+			 35  36  36  37  37  38  38  39
+			 40  41  42  43  44  45  46  47
+			 48  49  50  51  52  53  54  55
+			 56  57  58  59  60  61  62  63
+			 64  65  66  67  68  69  70  71
+			 72  73  74  75  76  77  78  79
+			 80  81  82  83  84  85  86  87
+			 88  89  90  91  92  93  94  95
+			 96  97  98  99 100 101 102 103
+			104 105 106 107 108 109 110 111
+			112 113 114 115 116 117 118 119
+			120 121 122 123 124 125 126 127
+			128 129 130 131 132 133 134 135
+			136 137 138 139 140 141 142 143
+			144 145 146 147 148 149 150 151
+			152 153 154 155 156 157 158 159
+			160 161 162 163 164 165 166 167
+			168 169 170 171 172 173 174 175
+			176 177 178 179 180 181 182 183
+			184 185 186 187 188 189 190 191
+			192 193 194 195 196 197 198 199
+			200 201 202 203 204 205 206 207
+			208 209 210 211 212 213 214 215
+			216 217 218 219 220 221 222 223
+			224 225 226 227 228 229 230 231
+			232 233 234 235 236 237 238 239
+			240 241 242 243 244 245 246 247
+			248 249 250 251 252 253 254 255
+		>;
+		default-brightness-level = <200>;
+	};
+
+	edp2lvds_backlight1: edp2lvds_backlight1 {
+		compatible = "pwm-backlight";
+		brightness-levels = <
+			  0  20  20  21  21  22  22  23
+			 23  24  24  25  25  26  26  27
+			 27  28  28  29  29  30  30  31
+			 31  32  32  33  33  34  34  35
+			 35  36  36  37  37  38  38  39
+			 40  41  42  43  44  45  46  47
+			 48  49  50  51  52  53  54  55
+			 56  57  58  59  60  61  62  63
+			 64  65  66  67  68  69  70  71
+			 72  73  74  75  76  77  78  79
+			 80  81  82  83  84  85  86  87
+			 88  89  90  91  92  93  94  95
+			 96  97  98  99 100 101 102 103
+			104 105 106 107 108 109 110 111
+			112 113 114 115 116 117 118 119
+			120 121 122 123 124 125 126 127
+			128 129 130 131 132 133 134 135
+			136 137 138 139 140 141 142 143
+			144 145 146 147 148 149 150 151
+			152 153 154 155 156 157 158 159
+			160 161 162 163 164 165 166 167
+			168 169 170 171 172 173 174 175
+			176 177 178 179 180 181 182 183
+			184 185 186 187 188 189 190 191
+			192 193 194 195 196 197 198 199
+			200 201 202 203 204 205 206 207
+			208 209 210 211 212 213 214 215
+			216 217 218 219 220 221 222 223
+			224 225 226 227 228 229 230 231
+			232 233 234 235 236 237 238 239
+			240 241 242 243 244 245 246 247
+			248 249 250 251 252 253 254 255
+		>;
+		default-brightness-level = <200>;
+	};
+};
+
+&backlight {
+	pwms = <&pwm0 0 25000 0>;
+	//pinctrl-names = "default";
+	//pinctrl-0 = <&bl0_enable_pin>;
+	//enable-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&dsi2lvds_backlight1 {
+	pwms = <&pwm13 0 25000 0>;
+	//pinctrl-names = "default";
+	//pinctrl-0 = <&bl1_enable_pin>;
+	//enable-gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&dp0 {
+	//split-mode;
+	force-hpd;
+	status = "okay";
+
+	ports {
+		port@1 {
+			reg = <1>;
+
+			dp0_out_i2c4_max96745: endpoint {
+				link-frequencies = /bits/ 64 <2700000000>;
+				remote-endpoint = <&i2c4_max96745_from_dp0>;
+			};
+		};
+	};
+};
+
+&dp0_in_vp0 {
+	status = "okay";
+};
+
+&dp0_in_vp1 {
+	status = "disabled";
+};
+
+&dp0_in_vp2 {
+	status = "disabled";
+};
+
+&dp1 {
+	force-hpd;
+	status = "disabled";
+#if 0
+	ports {
+		port@1 {
+			reg = <1>;
+
+			dp1_out_i2c8_bu18tl82: endpoint {
+				remote-endpoint = <&i2c8_bu18tl82_from_dp1>;
+			};
+		};
+	};
+#endif
+};
+
+&dp1_in_vp0 {
+	status = "okay";
+};
+
+&dp1_in_vp1 {
+	status = "disabled";
+};
+
+&dp1_in_vp2 {
+	status = "disabled";
+};
+
+&dp2lvds_backlight0 {
+	pwms = <&pwm10 0 25000 0>;
+	//pinctrl-names = "default";
+	//pinctrl-0 = <&bl2_enable_pin>;
+	//enable-gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&dp2lvds_backlight1 {
+	pwms = <&pwm14 0 25000 0>;
+	//pinctrl-names = "default";
+	//pinctrl-0 = <&bl3_enable_pin>;
+	//enable-gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+/*
+ * mipi_dcphy0 needs to be enabled
+ * when dsi0 is enabled
+ */
+&dsi0 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@1 {
+			reg = <1>;
+
+			dsi0_out_i2c2_max96789: endpoint {
+				remote-endpoint = <&i2c2_max96789_from_dsi0>;
+			};
+		};
+	};
+};
+
+&dsi0_in_vp2 {
+	status = "okay";
+};
+
+&dsi0_in_vp3 {
+	status = "disabled";
+};
+
+/*
+ * mipi_dcphy1 needs to be enabled
+ * when dsi1 is enabled
+ */
+&dsi1 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@1 {
+			reg = <1>;
+
+			dsi1_out_i2c2_max96789: endpoint {
+				remote-endpoint = <&i2c2_max96789_from_dsi1>;
+			};
+		};
+	};
+};
+
+&dsi1_in_vp2 {
+	status = "disabled";
+};
+
+&dsi1_in_vp3 {
+	status = "okay";
+};
+
+&edp0 {
+	//split-mode;
+	force-hpd;
+	status = "okay";
+
+	ports {
+		port@1 {
+			reg = <1>;
+
+			edp0_out_i2c5_max96745: endpoint {
+				remote-endpoint = <&i2c5_max96745_from_edp0>;
+			};
+		};
+	};
+};
+
+&edp0_in_vp0 {
+	status = "disabled";
+};
+
+&edp0_in_vp1 {
+	status = "okay";
+};
+
+&edp0_in_vp2 {
+	status = "disabled";
+};
+
+&edp1 {
+	force-hpd;
+	status = "disabled";
+};
+
+&edp1_in_vp0 {
+	status = "disabled";
+};
+
+&edp1_in_vp1 {
+	status = "okay";
+};
+
+&edp1_in_vp2 {
+	status = "disabled";
+};
+
+&edp2lvds_backlight0 {
+	pwms = <&pwm7 0 25000 0>;
+	//pinctrl-names = "default";
+	//pinctrl-0 = <&bl4_enable_pin>;
+	//enable-gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&edp2lvds_backlight1 {
+	pwms = <&pwm11 0 25000 0>;
+	//pinctrl-names = "default";
+	//pinctrl-0 = <&bl5_enable_pin>;
+	//enable-gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&hdmi0 {
+	status = "disabled";
+};
+
+&hdmi1 {
+	status = "disabled";
+};
+
+&hdptxphy0 {
+	status = "okay";
+};
+
+&hdptxphy1 {
+	status = "okay";
+};
+
+&hdptxphy_hdmi0 {
+	status = "disabled";
+};
+
+&hdptxphy_hdmi1 {
+	status = "disabled";
+};
+
+&i2c2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2m4_xfer>;
+	clock-frequency = <400000>;
+
+	i2c2_max96789: i2c2-max96789@42 {
+		compatible = "maxim,max96789";
+		reg = <0x42>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c2_serdes_pins>;
+		lock-gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>;
+		sel-mipi;
+		id-serdes-bridge-split = <0x01>;
+		status = "okay";
+
+		serdes-init-sequence = [
+			//Independent 11_07_17-56 Using MAX96789/91/F (GMSL-1/2)
+			//Disable Video pipe
+			0002 0003
+			//Address Value of I2C SRC_A
+			0042 008a
+			//Address Value of I2C DST_A
+			0043 008a
+			//Address Value of I2C SRC_B
+			0044 008c
+			//Address Value of I2C DST_B
+			0045 008c
+			//Set Stream for DSI Port A && assign pipeX
+			0053 0010
+			//Set Stream for DSI Port B && assign pipeY
+			0057 0021
+			//Clock Select, X for portA, Y/Z for PortB
+			0308 0076
+			//Start DSI Port
+			0311 0061
+			//Set Port A Lane Mapping
+			0332 004E
+			//Set Port B Lane Mapping
+			0333 00E4
+			//Set GMSL type
+			0004 00F2
+			//Number of Lanes
+			0331 0033
+			//Set phy_config
+			0330 0006
+			//Set soft_dtx_en
+			031C 0098
+			//Set soft_dtx
+			0321 0024
+			//Set soft_dty_en
+			031D 0098
+			//Set soft_dty_
+			0322 0024
+			//Init Default
+			0326 00E4
+			//HSYNC_WIDTH_L
+			0385 0038
+			//VSYNC_WIDTH_L
+			0386 0008
+			//HSYNC_WIDTH_H/VSYNC_WIDTH_H
+			0387 0000
+			//VFP_L
+			03A5 00C8
+			//VBP_H
+			03A7 0000
+			//VFP_H/VBP_L
+			03A6 0020
+			//VRES_L
+			03A8 00D0
+			//VRES_H
+			03A9 0002
+			//HFP_L
+			03AA 0038
+			//HBP_H
+			03AC 0002
+			//HFP_H/HBP_L
+			03AB 0000
+			//HRES_L
+			03AD 0080
+			//HRES_H
+			03AE 0007
+			//Disable FIFO/DESKEW_EN
+			03A4 00C0
+			//HSYNC_WIDTH_L
+			0395 0038
+			//VSYNC_WIDTH_L
+			0396 0008
+			//HSYNC_WIDTH_H/VSYNC_WIDTH_H
+			0397 0000
+			//VFP_L
+			03B1 00C8
+			//VBP_H
+			03B3 0000
+			//VFP_H/VBP_L
+			03B2 0020
+			//VRES_L
+			03B4 00D0
+			//VRES_H
+			03B5 0002
+			//HFP_L
+			03B6 0038
+			//HBP_H
+			03B8 0002
+			//HFP_H/HBP_L
+			03B7 0000
+			//HRES_L
+			03B9 0080
+			//HRES_H
+			03BA 0007
+			//Disable FIFO/DESKEW_EN
+			03B0 00C0
+			//Turn on video pipe
+			0002 0033
+			//Enable splitter mode  reset one shot
+			0010 0023
+			ffff f000	//0xf000 ms delay
+		];
+
+		i2c2_max96789_pinctrl: i2c2-max96789-pinctrl {
+			compatible = "maxim,max96789-pinctrl";
+			pinctrl-names = "default","sleep";
+			pinctrl-0 = <&i2c2_max96789_pinctrl_pins>;
+			pinctrl-1 = <&i2c2_max96789_pinctrl_pins>;
+			status = "okay";
+			i2c2_max96789_pinctrl_pins: pinctrl-pins {
+				i2c {
+					groups = "MAX96789_I2C";
+					function = "MAX96789_I2C";
+				};
+				lcd-bl-pwm {
+					pins = "MAX96789_MFP7";
+					function = "SER_TXID4_TO_DES";
+				};
+				tp-int {
+					pins = "MAX96789_MFP8";
+					function = "DES_RXID8_TO_SER";
+				};
+				lcd-bl-pwm-split {
+					pins = "MAX96789_MFP16";
+					function = "SER_TXID4_TO_DES";
+				};
+				tp-int-split {
+					pins = "MAX96789_MFP14";
+					function = "DES_RXID14_TO_SER";
+				};
+			};
+
+			i2c2_max96789_gpio: i2c2-max96789-gpio {
+				compatible = "maxim,max96789-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c2_max96789_pinctrl 0 160 20>;
+			};
+		};
+
+		i2c2_max96789_bridge: i2c2-max96789-bridge {
+			compatible = "maxim,max96789-bridge";
+			status = "okay";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					i2c2_max96789_from_dsi0: endpoint {
+						remote-endpoint = <&dsi0_out_i2c2_max96789>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					i2c2_max96789_out_i2c2_max96752: endpoint {
+						remote-endpoint = <&i2c2_max96752_from_i2c2_max96789>;
+					};
+				};
+			};
+		};
+
+		i2c2_max96789_bridge_split: i2c2-max96789-bridge-split {
+			compatible = "maxim,max96789-bridge-split";
+			status = "okay";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					i2c2_max96789_from_dsi1: endpoint {
+						remote-endpoint = <&dsi1_out_i2c2_max96789>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					i2c2_max96789_out_i2c2_max96752_split: endpoint {
+						remote-endpoint = <&i2c2_max96752_split_from_i2c2_max96789>;
+					};
+				};
+			};
+		};
+	};
+
+	i2c2_max96752: i2c2-max96752@4a {
+		compatible = "maxim,max96752";
+		reg = <0x4a>;
+		//reg-hw = <0x4a>;
+		id-serdes-panel-split = <0x01>;
+		link = <0x01>;
+		status = "okay";
+
+		serdes-init-sequence = [
+			/*max96752 dual oLDI output*/
+			0002 0043
+			0073 0031
+			007b 0031
+			007d 0038
+			//Address Value of I2C SRC_A
+			0042 008a
+			//Address Value of I2C DST_A
+			0043 0090
+
+			0050 0000
+			01ce 004e
+			01ea 0005
+		];
+
+		i2c2_max96752_pinctrl: i2c2-max96752-pinctrl {
+			compatible = "maxim,max96752-pinctrl";
+			pinctrl-names = "default","init","sleep";
+			pinctrl-0 = <&i2c2_max96752_panel_pins>;
+			pinctrl-1 = <&i2c2_max96752_panel_pins>;
+			pinctrl-2 = <&i2c2_max96752_panel_sleep_pins>;
+			status = "okay";
+
+			i2c2_max96752_panel_pins: panel-pins {
+				lcd-rst-pin {
+					pins = "MAX96752_GPIO10";
+					function = "DES_TXID10_OUTPUT_HIGH";
+				};
+				tp-rst {
+					pins = "MAX96752_GPIO5";
+					function = "DES_TXID5_OUTPUT_HIGH";
+				};
+				lcd-bias-en {
+					pins = "MAX96752_GPIO7";
+					function = "DES_TXID7_OUTPUT_HIGH";
+				};
+				lcd-vdd-en {
+					pins = "MAX96752_GPIO6";
+					function = "DES_TXID6_OUTPUT_HIGH";
+				};
+				tp-int {
+					pins = "MAX96752_GPIO2";
+					function = "DES_TXID8_TO_SER";
+				};
+				100ms-delay {
+					pins = "MAX96752_GPIO15";
+					function = "DELAY_100MS";
+				};
+				lcd-pwr-on {
+					pins = "MAX96752_GPIO3";
+					function = "DES_TXID3_OUTPUT_HIGH";
+				};
+				lcd-bl-pwm {
+					pins = "MAX96752_GPIO4";
+					function = "SER_TO_DES_RXID4";
+				};
+			};
+
+			i2c2_max96752_panel_sleep_pins: panel-sleep-pins {
+				lcd-rst-pin {
+					pins = "MAX96752_GPIO10";
+					function = "DES_TXID10_OUTPUT_LOW";
+				};
+				tp-rst {
+					pins = "MAX96752_GPIO5";
+					function = "DES_TXID5_OUTPUT_LOW";
+				};
+				lcd-pwr-on {
+					pins = "MAX96752_GPIO3";
+					function = "DES_TXID3_OUTPUT_LOW";
+				};
+			};
+
+			i2c2_max96752_gpio: i2c2-max96752-gpio {
+				compatible = "maxim,max96752-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c2_max96752_pinctrl 0 180 15>;
+			};
+		};
+
+		i2c2_max96752_panel: i2c2-max96752-panel {
+			compatible = "maxim,max96752-panel";
+			status = "okay";
+
+			backlight = <&backlight>;
+			panel-size= <346 194>;
+
+			panel-timing {
+				clock-frequency = <115200000>;
+				hactive = <1920>;
+				vactive = <720>;
+				hfront-porch = <56>;
+				hsync-len = <32>;
+				hback-porch = <56>;
+				vfront-porch = <200>;
+				vsync-len = <2>;
+				vback-porch = <8>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <0>;
+				pixelclk-active = <0>;
+			};
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					i2c2_max96752_from_i2c2_max96789: endpoint {
+						remote-endpoint = <&i2c2_max96789_out_i2c2_max96752>;
+					};
+				};
+			};
+		};
+	};
+
+	i2c2_max96752_split: i2c2-max96752-split@4b {
+		compatible = "maxim,max96752";
+		reg = <0x4b>;
+		reg-hw = <0x4a>;
+		id-serdes-panel-split = <0x01>;
+		link = <0x02>;
+		status = "okay";
+
+		serdes-init-sequence = [
+			/*max96752 dual oLDI output*/
+			0002 0043
+			0073 0032
+			007b 0032
+			007d 0038
+
+			//Address Value of I2C SRC_A
+			0042 008c
+			//Address Value of I2C DST_A
+			0043 0090
+			//0140 0020
+			0050 0001
+			01ce 004e
+			01ea 0005
+		];
+
+		i2c2_max96752_split_pinctrl: i2c2-max96752-split-pinctrl {
+			compatible = "maxim,max96752-pinctrl";
+			pinctrl-names = "default","init","sleep";
+			pinctrl-0 = <&i2c2_max96752_split_panel_pins>;
+			pinctrl-1 = <&i2c2_max96752_split_panel_pins>;
+			pinctrl-2 = <&i2c2_max96752_split_panel_sleep_pins>;
+			status = "okay";
+
+			i2c2_max96752_split_panel_pins: panel-pins {
+				lcd-rst-pin {
+					pins = "MAX96752_GPIO10";
+					function = "DES_TXID10_OUTPUT_HIGH";
+				};
+				tp-rst {
+					pins = "MAX96752_GPIO5";
+					function = "DES_TXID5_OUTPUT_HIGH";
+				};
+				lcd-bias-en {
+					pins = "MAX96752_GPIO7";
+					function = "DES_TXID7_OUTPUT_HIGH";
+				};
+				lcd-vdd-en {
+					pins = "MAX96752_GPIO6";
+					function = "DES_TXID6_OUTPUT_HIGH";
+				};
+				tp-int {
+					pins = "MAX96752_GPIO2";
+					function = "DES_TXID14_TO_SER";
+				};
+				100ms-delay {
+					pins = "MAX96752_GPIO15";
+					function = "DELAY_100MS";
+				};
+				lcd-pwr-on {
+					pins = "MAX96752_GPIO3";
+					function = "DES_TXID3_OUTPUT_HIGH";
+				};
+				lcd-bl-pwm {
+					pins = "MAX96752_GPIO4";
+					function = "SER_TO_DES_RXID4";
+				};
+			};
+
+			i2c2_max96752_split_panel_sleep_pins: panel-sleep-pins {
+				lcd-rst-pin {
+					pins = "MAX96752_GPIO10";
+					function = "DES_TXID10_OUTPUT_LOW";
+				};
+				tp-rst {
+					pins = "MAX96752_GPIO5";
+					function = "DES_TXID5_OUTPUT_LOW";
+				};
+				lcd-pwr-on {
+					pins = "MAX96752_GPIO3";
+					function = "DES_TXID3_OUTPUT_LOW";
+				};
+			};
+
+			i2c2_max96752_split_gpio: i2c2-max96752-split-gpio {
+				compatible = "maxim,max96752-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c2_max96752_split_pinctrl 0 200 15>;
+			};
+		};
+
+		i2c2_max96752_split_panel: i2c2-max96752-split-panel {
+			compatible = "maxim,max96752-panel-split";
+			status = "okay";
+
+			backlight = <&dsi2lvds_backlight1>;
+			panel-size= <346 194>;
+
+			panel-timing {
+				clock-frequency = <115200000>;
+				hactive = <1920>;
+				vactive = <720>;
+				hfront-porch = <56>;
+				hsync-len = <32>;
+				hback-porch = <56>;
+				vfront-porch = <200>;
+				vsync-len = <2>;
+				vback-porch = <8>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <0>;
+				pixelclk-active = <0>;
+			};
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					i2c2_max96752_split_from_i2c2_max96789: endpoint {
+						remote-endpoint = <&i2c2_max96789_out_i2c2_max96752_split>;
+					};
+				};
+			};
+		};
+	};
+
+	himax@45 {
+		compatible = "himax,hxcommon";
+		reg = <0x45>;
+		pinctrl-names = "default", "sleep";
+		pinctrl-0 = <&touch_gpio_dsi0>;
+		pinctrl-1 = <&touch_gpio_dsi0>;
+		himax,location = "himax-touch-dsi0";
+		himax,irq-gpio = <&gpio1 RK_PB0 IRQ_TYPE_EDGE_FALLING>;
+		himax,rst-gpio = <&i2c2_max96752_gpio 5 GPIO_ACTIVE_LOW>;
+		himax,panel-coords = <0 1920 0 720>;
+		himax,display-coords = <0 1920 0 720>;
+		status = "okay";
+	};
+
+	himax_split@46 {
+		compatible = "himax,hxcommon";
+		reg = <0x46>;
+		pinctrl-names = "default", "sleep";
+		pinctrl-0 = <&touch_gpio_dsi1>;	//hw change
+		pinctrl-1 = <&touch_gpio_dsi1>;
+		himax,location = "himax-touch-dsi1";
+		himax,irq-gpio = <&gpio1 RK_PB6 IRQ_TYPE_EDGE_FALLING>;
+		himax,rst-gpio = <&i2c2_max96752_split_gpio 5 GPIO_ACTIVE_LOW>;
+		himax,panel-coords = <0 1920 0 720>;
+		himax,display-coords = <0 1920 0 720>;
+		status = "okay";
+	};
+};
+
+&i2c4 {
+	pinctrl-0 = <&i2c4m2_xfer>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	i2c4_max96745: i2c4-max96745@42 {
+		compatible = "maxim,max96745";
+		reg = <0x42>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c4_serdes_pins>;
+		lock-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		id-serdes-bridge-split = <0x02>;
+		status = "okay";
+
+		serdes-init-sequence = [
+			//Address Value of I2C SRC_A
+			0042 008a
+			//Address Value of I2C DST_A
+			0043 008a
+			//Address Value of I2C SRC_B
+			0044 008c
+			//Address Value of I2C DST_B
+			0045 008c
+			//Set TX_STR_SEL_X to 0
+			00A3	0000
+			//Set TX_STR_SEL_Y to 1
+			00A7	0001
+			//Set TX_STR_SEL_Z to 2
+			00AB	0002
+			//Set TX_STR_SEL_U to 3
+			00AF	0003
+
+			//INFOFR TX_SRC_ID0:1:2
+			00C2	0001
+			//CC TX_SRC_ID0:1:2
+			00D2	0002
+			//IIC X TX_SRC_ID0:1:2
+			00EA	0001
+			//IIC Y TX_SRC_ID0:1:2
+			00F2	0002
+
+			00B2	0003
+			00BA	0003
+			00CA	0003
+			00C2	0003
+			00D2	0003
+			00DA	0003
+			00E2	0003
+			00EA	0003
+			00F2	0003
+			//Set X_VID_LINK_SEL to 0
+			0100	0061
+			//Set Y_VID_LINK_SEL to 1
+			0110	0063
+			//Set Z_VID_LINK_SEL to 0
+			0120	0061
+			//Set U_VID_LINK_SEL to 1
+			0130	0063
+			//ASYM_WR_B_MUX_Y of SER will be written 1
+			05CE	003F
+			//ASYM_WAIT_LINE_FOR_READ_X of SER will be written 1
+			04D1	00F8
+			//ASYM_WAIT_LINE_FOR_READ_Y of SER will be written 1
+			05D1	00F8
+			//ASYM_VID_EN_W_VS_X of SER will be written 1
+			04CF	00BF
+			//ASYM_VID_EN_W_VS_Y of SER will be written 1
+			05CF	00BF
+			//ASYM_FR2FR_CTRL_EN_X of SER will be written 1
+			04D1	00FC
+			//ASYM_FR2FR_CTRL_EN_Y of SER will be written 1
+			05D1	00FC
+			//ALT_VTG_EN_X
+			04CE	002F
+			//AUTO_VTG_CFG_X
+			04CE	000F
+			//ALT_VTG_EN_Y
+			05CE	0027
+			//AUTO_VTG_CFG_Y
+			05CE	0007
+			//X_M_l
+			04C0	0020
+			//X_M_m
+			04C1	004A
+			//X_M_h
+			04C2	001D
+			//X_N_l
+			04C3	00C8
+			//X_N_m
+			04C4	0008
+			//X_N_h
+			04C5	0007
+			//X_X_OFFSET_l
+			04C6	0000
+			//X_X_OFFSET_h
+			04C7	0000
+			//X_X_MAX_l
+			04C8    0080
+			//X_X_MAX_h
+			04C9	0007
+			//X_Y_MAX_l
+			04CA	00D0
+			//X_Y_MAX_h
+			04CB	0002
+			//Y_M
+			05C0	0020
+			//Y_M_h
+			05C1	004A
+			//Y_M_h
+			05C2	001D
+			//Y_N_l
+			05C3	00C8
+			//Y_N_m
+			05C4	0008
+			//Y_N_h
+			05C5	0007
+			//Y_X_OFFSET_l
+			05C6	0080
+			//Y_X_OFFSET_h
+			05C7	0007
+			//Y_X_MAX_l
+			05C8	0000
+			//Y_X_MAX_h
+			05C9	000F
+			//Y_Y_MAX_l
+			05CA	00D0
+			//Y_Y_MAX_h
+			05CB	0002
+			//X_LUT_TEMPLATE_SEL
+			04CD	0014
+			//X_vs_dly_l
+			04D8	0080
+			//X_vs_dly_m
+			04D9	00F9
+			//X_vs_dly_h
+			04DA	001C
+			//X_vs_high_l
+			04DB	0080
+			//X_vs_high_m
+			04DC	0040
+			//X_vs_high_h
+			04DD	0000
+			//X_vs_low_l
+			04DE	0020
+			//X_vs_low_m
+			04DF	0010
+			//X_vs_low_h
+			04E0	0000
+			//X_hs_dly_l
+			04E1	0000
+			//X_hs_dly_m
+			04E2	0000
+			//X_hs_dly_h
+			04E3	0000
+			//X_hs_high_l
+			04E4	0038
+			//X_hs_high_h
+			04E5	0000
+			//X_hs_low_l
+			04E6	00D8
+			//X_hs_low_h
+			04E7	0007
+			//X_hs_cnt_l
+			04E8	00A2
+			//X_hs_cnt_h
+			04E9	0003
+			//X_hs_llow_l
+			04EA	0000
+			//X_hs_llow_m
+			04EB	0000
+			//X_hs_llow_h
+			04EC	0000
+			//X_de_dly_l
+			04ED	0058
+			//X_de_dly_m
+			04EE	0000
+			//X_de_dly_h
+			04EF	0000
+			//X_de_high_l
+			04F0	0080
+			//X_de_high_h
+			04F1	0007
+			//X_de_low_l
+			04F2	0090
+			//X_de_low_h
+			04F3	0000
+			//X_de_cnt_l
+			04F4	00D0
+			//X_de_cnt_h
+			04F5	0002
+			//X_de_llow_l
+			04F6	00C8
+			//X_de_llow_m
+			04F7	009C
+			//X_de_llow_h
+			04F8	0006
+			//Y_vs_dly_l
+			05D8	0080
+			//Y_vs_dly_m
+			05D9	00F9
+			//Y_vs_dly_h
+			05DA	001C
+			//Y_vs_high_l
+			05DB	0080
+			//Y_vs_high_m
+			05DC	0040
+			//Y_vs_high_h
+			05DD	0000
+			//Y_vs_low_l
+			05DE	0020
+			//Y_vs_low_m
+			05DF	0010
+			//Y_vs_low_h
+			05E0	0000
+			//Y_hs_dly_l
+			05E1	0000
+			//Y_hs_dly_m
+			05E2	0000
+			//Y_hs_dly_h
+			05E3	0000
+			//Y_hs_high_l
+			05E4	0038
+			//Y_hs_high_h
+			05E5	0000
+			//Y_hs_low_l
+			05E6	00D8
+			//Y_hs_low_h
+			05E7	0007
+			//Y_hs_cnt_l
+			05E8	00A2
+			//Y_hs_cnt_h
+			05E9	0003
+			//Y_hs_llow_l
+			05EA	0000
+			//Y_hs_llow_m
+			05EB	0000
+			//Y_hs_llow_h
+			05EC	0000
+			//Y_de_dly_l
+			05ED	0058
+			//Y_de_dly_m
+			05EE	0000
+			//Y_de_dly_h
+			05EF	0000
+			//Y_de_high_l
+			05F0	0080
+			//Y_de_high_h
+			05F1	0007
+			//Y_de_low_l
+			05F2	0090
+			//Y_de_low_h
+			05F3	0000
+			//Y_de_cnt_l
+			05F4	00D0
+			//Y_de_cnt_h
+			05F5	0002
+			//Y_de_llow_l
+			05F6	00C8
+			//Y_de_llow_m
+			05F7	009C
+			//Y_de_llow_h
+			05F8	0006
+			//Y_LUT_TEMPLATE_SEL
+			05CD	0014
+			//Turn off video
+			6420	0010
+			//Disable MST mode
+			7019	0000
+			//7019	0001	//Set MST_FUNCTION_ENABLE to 1
+			//7904	0001	// Set MST_PAYLOAD_ID_0 to 01
+			//7908	0002	// Set MST_PAYLOAD_ID_1 to 01
+			//Disable MST_VS0_DTG_ENABLE
+			7A14	0000
+			//Disable LINK_ENABLE
+			7000	0000
+			//Reset DPRX core (VIDEO_INPUT_RESET)
+			7054	0001
+			ffff	f000	//delay 0xf000 us
+			//Set MAX_LINK_RATE to 2.7Gb/s
+			7074	000A
+			//Set MAX_LINK_COUNT to 4
+			7070	0004
+			//Set ASYM_CTRL_PROP_GAIN to 000A
+			04D0	000A
+			05D0	000A
+			//Set AEQ time to 16ms
+			6064	0000
+			6065	0000
+			6164	0000
+			6165	0000
+			6264	0000
+			6265	0000
+			6364	0000
+			6365	0000
+			//Enable LINK_ENABLE
+			7000	0001
+			//delay 1000
+			//Disable MSA reset
+			7A18	0005
+			//Adjust VS0_DMA_HSYNC
+			7A28	00FF
+			7A2A	00FF
+			//Adjust VS0_DMA_VSYNC
+			7A24	00FF
+			7A27	000F
+			//Enable MST_VS0_DTG_ENABLE
+			7A14	0001
+			//set EDP Video Control
+			6421	0001
+			//Turn on video
+			6420	0013
+			//delay 100
+			//Turn off video
+			6420	0010
+			//delay 100
+			//Turn on video
+			6420	0013
+			6421	0003
+		];
+
+
+		i2c4_max96745_pinctrl: i2c4-max96745-pinctrl {
+			compatible = "maxim,max96745-pinctrl";
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c4_max96745_pinctrl_pins>;
+			status = "okay";
+
+			i2c4_max96745_pinctrl_pins: pinctrl-pins {
+				i2c {
+					groups = "MAX96745_I2C";
+					function = "MAX96745_I2C";
+				};
+				lcd-bl-pwm {
+					pins = "MAX96745_MFP0";
+					function = "SER_TXID0_TO_DES_LINKA";
+				};
+				tp-int {
+					pins = "MAX96745_MFP1";
+					function = "DES_RXID1_TO_SER_LINKA";
+				};
+				lcd-bl-pwm-split {
+					pins = "MAX96745_MFP4";
+					function = "SER_TXID4_TO_DES_LINKB";
+				};
+				tp-int-split {
+					pins = "MAX96745_MFP5";
+					function = "DES_RXID5_TO_SER_LINKB";
+				};
+			};
+
+			i2c4_max96745_gpio: i2c4-max96745-gpio {
+				compatible = "maxim,max96745-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c4_max96745_pinctrl 0 220 25>;
+			};
+		};
+
+		i2c4_max96745_bridge: i2c4-max96745-bridge {
+			compatible = "maxim,max96745-bridge";
+			status = "okay";
+		};
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				i2c4_max96745_from_dp0: endpoint {
+					remote-endpoint = <&dp0_out_i2c4_max96745>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				i2c4_max96745_out_i2c4_max96752: endpoint {
+					remote-endpoint = <&i2c4_max96752_from_i2c4_max96745>;
+				};
+			};
+			port@2 {
+				reg = <2>;
+				i2c4_max96745_out_i2c4_max96752_split: endpoint {
+					remote-endpoint = <&i2c4_max96752_split_from_i2c4_max96745>;
+				};
+			};
+		};
+	};
+
+	i2c4_max96752: i2c4-max96752@4a {
+		compatible = "maxim,max96752";
+		reg = <0x4a>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		id-serdes-panel-split = <0x02>;
+		link = <0x01>;
+		status = "okay";
+
+		serdes-init-sequence = [
+			/*max96752 dual oLDI output*/
+			0002 0043
+			0073 0031
+			007b 0031
+			007d 0038
+			//Address Value of I2C SRC_A
+			0042 008a
+			//Address Value of I2C DST_A
+			0043 0090
+
+			0050 0000
+			01ce 004e
+			01ea 0005
+		];
+
+		i2c4_max96752_pinctrl: i2c4-max96752-pinctrl {
+			compatible = "maxim,max96752-pinctrl";
+			status = "okay";
+
+			pinctrl-names = "default","init","sleep";
+			pinctrl-0 = <&i2c4_max96752_panel_pins>;
+			pinctrl-1 = <&i2c4_max96752_panel_pins>;
+			pinctrl-2 = <&i2c4_max96752_panel_sleep_pins>;
+
+			i2c4_max96752_panel_pins: panel-pins {
+				lcd-rst-pin {
+					pins = "MAX96752_GPIO10";
+					function = "DES_TXID10_OUTPUT_HIGH";
+				};
+				tp-rst {
+					pins = "MAX96752_GPIO5";
+					function = "DES_TXID5_OUTPUT_HIGH";
+				};
+				tp-int {
+					pins = "MAX96752_GPIO2";
+					function = "DES_TXID1_TO_SER";
+				};
+				100ms-delay {
+					pins = "MAX96752_GPIO15";
+					function = "DELAY_100MS";
+				};
+				lcd-pwr-on {
+					pins = "MAX96752_GPIO3";
+					function = "DES_TXID3_OUTPUT_HIGH";
+				};
+				lcd-bl-pwm {
+					pins = "MAX96752_GPIO4";
+					function = "SER_TO_DES_RXID4";
+				};
+				lcd_bias_en {
+					pins = "MAX96752_GPIO7";
+					function = "DES_TXID7_OUTPUT_HIGH";
+				};
+				lcd_vdd_en {
+					pins = "MAX96752_GPIO6";
+					function = "DES_TXID6_OUTPUT_HIGH";
+				};
+			};
+
+			i2c4_max96752_panel_sleep_pins: panel-sleep-pins {
+				lcd-rst-pin {
+					pins = "MAX96752_GPIO10";
+					function = "DES_TXID10_OUTPUT_LOW";
+				};
+				tp-rst {
+					pins = "MAX96752_GPIO5";
+					function = "DES_TXID5_OUTPUT_LOW";
+				};
+				lcd-pwr-on {
+					pins = "MAX96752_GPIO3";
+					function = "DES_TXID3_OUTPUT_LOW";
+				};
+			};
+
+			i2c4_max96752_gpio: i2c4-max96752-gpio {
+				compatible = "maxim,max96752-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c4_max96752_pinctrl 0 250 15>;
+			};
+		};
+
+		i2c4_max96752_panel: i2c4-max96752-panel {
+			compatible = "maxim,max96752-panel";
+			status = "okay";
+
+			backlight = <&dp2lvds_backlight0>;
+			panel-size= <346 194>;
+
+			panel-timing {
+				clock-frequency = <230400000>;	//4128*930@60
+				hactive = <3840>;
+				vactive = <720>;
+				hfront-porch = <112>;
+				hsync-len = <64>;
+				hback-porch = <112>;
+				vfront-porch = <200>;
+				vsync-len = <2>;
+				vback-porch = <8>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <0>;
+				pixelclk-active = <0>;
+			};
+
+			port {
+				i2c4_max96752_from_i2c4_max96745: endpoint {
+					remote-endpoint = <&i2c4_max96745_out_i2c4_max96752>;
+				};
+			};
+		};
+
+	};
+
+	i2c4_max96752_split: i2c4-max96752-split@4b {
+		compatible = "maxim,max96752";
+		reg = <0x4b>;
+		reg-hw = <0x4a>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		id-serdes-panel-split = <0x02>;
+		link = <0x02>;
+		status = "okay";
+
+		serdes-init-sequence = [
+			/*max96752 dual oLDI output*/
+			0002 0043
+			0073 0032
+			007b 0032
+			007d 0038
+			//Address Value of I2C SRC_A
+			0042 008c
+			//Address Value of I2C DST_A
+			0043 0090
+
+			//0140 0020
+			0050 0001
+			01ce 004e
+			01ea 0005
+		];
+
+		i2c4_max96752_split_pinctrl: i2c4-max96752-split-pinctrl {
+			compatible = "maxim,max96752-pinctrl";
+			status = "okay";
+
+			pinctrl-names = "default","init","sleep";
+			pinctrl-0 = <&i2c4_max96752_split_panel_pins>;
+			pinctrl-1 = <&i2c4_max96752_split_panel_pins>;
+			pinctrl-2 = <&i2c4_max96752_split_panel_sleep_pins>;
+
+			i2c4_max96752_split_panel_pins: i2c4-max96752-split-panel-pins {
+				lcd-rst-pin {
+					pins = "MAX96752_GPIO10";
+					function = "DES_TXID10_OUTPUT_HIGH";
+				};
+				tp-rst {
+					pins = "MAX96752_GPIO5";
+					function = "DES_TXID5_OUTPUT_HIGH";
+				};
+				tp-int {
+					pins = "MAX96752_GPIO2";
+					function = "DES_TXID4_TO_SER";
+				};
+				100ms-delay {
+					pins = "MAX96752_GPIO15";
+					function = "DELAY_100MS";
+				};
+				lcd-pwr-on {
+					pins = "MAX96752_GPIO3";
+					function = "DES_TXID3_OUTPUT_HIGH";
+				};
+				lcd-bl-pwm {
+					pins = "MAX96752_GPIO4";
+					function = "SER_TO_DES_RXID4";
+				};
+				lcd_bias_en {
+					pins = "MAX96752_GPIO7";
+					function = "DES_TXID7_OUTPUT_HIGH";
+				};
+				lcd_vdd_en {
+					pins = "MAX96752_GPIO6";
+					function = "DES_TXID6_OUTPUT_HIGH";
+				};
+			};
+
+			i2c4_max96752_split_panel_sleep_pins: i2c4-max96752-split-panel-sleep-pins {
+				lcd-rst-pin {
+					pins = "MAX96752_GPIO10";
+					function = "DES_TXID10_OUTPUT_LOW";
+				};
+				tp-rst {
+					pins = "MAX96752_GPIO5";
+					function = "DES_TXID5_OUTPUT_LOW";
+				};
+				lcd-pwr-on {
+					pins = "MAX96752_GPIO3";
+					function = "DES_TXID3_OUTPUT_LOW";
+				};
+			};
+
+			i2c4_max96752_split_gpio: i2c4-max96752-split-gpio {
+				compatible = "maxim,max96752-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c4_max96752_split_pinctrl 0 265 15>;
+			};
+		};
+
+		i2c4_max96752_split_panel: i2c4-max96752-split-panel {
+			compatible = "maxim,max96752-panel-split";
+			status = "okay";
+
+			backlight = <&dp2lvds_backlight0>;
+			panel-size= <346 194>;
+
+			panel-timing {
+				clock-frequency = <115200000>;
+				hactive = <1920>;
+				vactive = <720>;
+				hfront-porch = <56>;
+				hsync-len = <32>;
+				hback-porch = <56>;
+				vfront-porch = <200>;
+				vsync-len = <2>;
+				vback-porch = <8>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <0>;
+				pixelclk-active = <0>;
+			};
+
+			port {
+				i2c4_max96752_split_from_i2c4_max96745: endpoint {
+					remote-endpoint = <&i2c4_max96745_out_i2c4_max96752_split>;
+				};
+			};
+		};
+	};
+
+	himax@45 {
+		compatible = "himax,hxcommon";
+		reg = <0x45>;
+		pinctrl-names = "default", "sleep";
+		pinctrl-0 = <&touch_gpio_dp0>;
+		pinctrl-1 = <&touch_gpio_dp0>;
+		himax,location = "himax-touch-dp0";
+		himax,irq-gpio = <&gpio3 RK_PC5 IRQ_TYPE_EDGE_FALLING>;
+		himax,rst-gpio = <&i2c4_max96752_gpio 5 GPIO_ACTIVE_LOW>;
+		himax,panel-coords = <0 1920 0 720>;
+		himax,display-coords = <0 1920 0 720>;
+		status = "okay";
+	};
+
+	himax_split@46 {
+		compatible = "himax,hxcommon";
+		reg = <0x46>;
+		pinctrl-names = "default", "sleep";
+		pinctrl-0 = <&touch_gpio_edp0>;
+		pinctrl-1 = <&touch_gpio_edp0>;
+		himax,location = "himax-touch-dp0-split";
+		//himax,irq-gpio = <&gpio3 RK_PC5 IRQ_TYPE_EDGE_FALLING>;
+		himax,rst-gpio = <&i2c4_max96752_split_gpio 5 GPIO_ACTIVE_LOW>;
+		himax,panel-coords = <0 1920 0 720>;
+		himax,display-coords = <0 1920 0 720>;
+		status = "okay";
+	};
+};
+
+&i2c5 {
+	clock-frequency = <400000>;
+	status = "okay";
+
+	i2c5_max96745: i2c5-max96745@42 {
+		compatible = "maxim,max96745";
+		reg = <0x42>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c5_serdes_pins>;
+		lock-gpios = <&gpio0 RK_PD2 GPIO_ACTIVE_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		id-serdes-bridge-split = <0x02>;
+		status = "disabled";
+
+		serdes-init-sequence = [
+			//Address Value of I2C SRC_A
+			0042 008a
+			//Address Value of I2C DST_A
+			0043 008a
+			//Address Value of I2C SRC_B
+			0044 008c
+			//Address Value of I2C DST_B
+			0045 008c
+			//Set TX_STR_SEL_X to 0
+			00A3	0000
+			//Set TX_STR_SEL_Y to 1
+			00A7	0001
+			//Set TX_STR_SEL_Z to 2
+			00AB	0002
+			//Set TX_STR_SEL_U to 3
+			00AF	0003
+
+			//INFOFR TX_SRC_ID0:1:2
+			00C2	0001
+			//CC TX_SRC_ID0:1:2
+			00D2	0002
+			//IIC X TX_SRC_ID0:1:2
+			00EA	0001
+			//IIC Y TX_SRC_ID0:1:2
+			00F2	0002
+
+			00B2	0003
+			00BA	0003
+			00CA	0003
+			00C2	0003
+			00D2	0003
+			00DA	0003
+			00E2	0003
+			00EA	0003
+			00F2	0003
+			//Set X_VID_LINK_SEL to 0
+			0100	0061
+			//Set Y_VID_LINK_SEL to 1
+			0110	0063
+			//Set Z_VID_LINK_SEL to 0
+			0120	0061
+			//Set U_VID_LINK_SEL to 1
+			0130	0063
+			//ASYM_WR_B_MUX_Y of SER will be written 1
+			05CE	003F
+			//ASYM_WAIT_LINE_FOR_READ_X of SER will be written 1
+			04D1	00F8
+			//ASYM_WAIT_LINE_FOR_READ_Y of SER will be written 1
+			05D1	00F8
+			//ASYM_VID_EN_W_VS_X of SER will be written 1
+			04CF	00BF
+			//ASYM_VID_EN_W_VS_Y of SER will be written 1
+			05CF	00BF
+			//ASYM_FR2FR_CTRL_EN_X of SER will be written 1
+			04D1	00FC
+			//ASYM_FR2FR_CTRL_EN_Y of SER will be written 1
+			05D1	00FC
+			//ALT_VTG_EN_X
+			04CE	002F
+			//AUTO_VTG_CFG_X
+			04CE	000F
+			//ALT_VTG_EN_Y
+			05CE	0027
+			//AUTO_VTG_CFG_Y
+			05CE	0007
+			//X_M_l
+			04C0	0020
+			//X_M_m
+			04C1	004A
+			//X_M_h
+			04C2	001D
+			//X_N_l
+			04C3	00C8
+			//X_N_m
+			04C4	0008
+			//X_N_h
+			04C5	0007
+			//X_X_OFFSET_l
+			04C6	0000
+			//X_X_OFFSET_h
+			04C7	0000
+			//X_X_MAX_l
+			04C8    0080
+			//X_X_MAX_h
+			04C9	0007
+			//X_Y_MAX_l
+			04CA	00D0
+			//X_Y_MAX_h
+			04CB	0002
+			//Y_M
+			05C0	0020
+			//Y_M_h
+			05C1	004A
+			//Y_M_h
+			05C2	001D
+			//Y_N_l
+			05C3	00C8
+			//Y_N_m
+			05C4	0008
+			//Y_N_h
+			05C5	0007
+			//Y_X_OFFSET_l
+			05C6	0080
+			//Y_X_OFFSET_h
+			05C7	0007
+			//Y_X_MAX_l
+			05C8	0000
+			//Y_X_MAX_h
+			05C9	000F
+			//Y_Y_MAX_l
+			05CA	00D0
+			//Y_Y_MAX_h
+			05CB	0002
+			//X_LUT_TEMPLATE_SEL
+			04CD	0014
+			//X_vs_dly_l
+			04D8	0080
+			//X_vs_dly_m
+			04D9	00F9
+			//X_vs_dly_h
+			04DA	001C
+			//X_vs_high_l
+			04DB	0080
+			//X_vs_high_m
+			04DC	0040
+			//X_vs_high_h
+			04DD	0000
+			//X_vs_low_l
+			04DE	0020
+			//X_vs_low_m
+			04DF	0010
+			//X_vs_low_h
+			04E0	0000
+			//X_hs_dly_l
+			04E1	0000
+			//X_hs_dly_m
+			04E2	0000
+			//X_hs_dly_h
+			04E3	0000
+			//X_hs_high_l
+			04E4	0038
+			//X_hs_high_h
+			04E5	0000
+			//X_hs_low_l
+			04E6	00D8
+			//X_hs_low_h
+			04E7	0007
+			//X_hs_cnt_l
+			04E8	00A2
+			//X_hs_cnt_h
+			04E9	0003
+			//X_hs_llow_l
+			04EA	0000
+			//X_hs_llow_m
+			04EB	0000
+			//X_hs_llow_h
+			04EC	0000
+			//X_de_dly_l
+			04ED	0058
+			//X_de_dly_m
+			04EE	0000
+			//X_de_dly_h
+			04EF	0000
+			//X_de_high_l
+			04F0	0080
+			//X_de_high_h
+			04F1	0007
+			//X_de_low_l
+			04F2	0090
+			//X_de_low_h
+			04F3	0000
+			//X_de_cnt_l
+			04F4	00D0
+			//X_de_cnt_h
+			04F5	0002
+			//X_de_llow_l
+			04F6	00C8
+			//X_de_llow_m
+			04F7	009C
+			//X_de_llow_h
+			04F8	0006
+			//Y_vs_dly_l
+			05D8	0080
+			//Y_vs_dly_m
+			05D9	00F9
+			//Y_vs_dly_h
+			05DA	001C
+			//Y_vs_high_l
+			05DB	0080
+			//Y_vs_high_m
+			05DC	0040
+			//Y_vs_high_h
+			05DD	0000
+			//Y_vs_low_l
+			05DE	0020
+			//Y_vs_low_m
+			05DF	0010
+			//Y_vs_low_h
+			05E0	0000
+			//Y_hs_dly_l
+			05E1	0000
+			//Y_hs_dly_m
+			05E2	0000
+			//Y_hs_dly_h
+			05E3	0000
+			//Y_hs_high_l
+			05E4	0038
+			//Y_hs_high_h
+			05E5	0000
+			//Y_hs_low_l
+			05E6	00D8
+			//Y_hs_low_h
+			05E7	0007
+			//Y_hs_cnt_l
+			05E8	00A2
+			//Y_hs_cnt_h
+			05E9	0003
+			//Y_hs_llow_l
+			05EA	0000
+			//Y_hs_llow_m
+			05EB	0000
+			//Y_hs_llow_h
+			05EC	0000
+			//Y_de_dly_l
+			05ED	0058
+			//Y_de_dly_m
+			05EE	0000
+			//Y_de_dly_h
+			05EF	0000
+			//Y_de_high_l
+			05F0	0080
+			//Y_de_high_h
+			05F1	0007
+			//Y_de_low_l
+			05F2	0090
+			//Y_de_low_h
+			05F3	0000
+			//Y_de_cnt_l
+			05F4	00D0
+			//Y_de_cnt_h
+			05F5	0002
+			//Y_de_llow_l
+			05F6	00C8
+			//Y_de_llow_m
+			05F7	009C
+			//Y_de_llow_h
+			05F8	0006
+			//Y_LUT_TEMPLATE_SEL
+			05CD	0014
+			//Turn off video
+			6420	0010
+			//Disable MST mode
+			7019	0000
+			//7019	0001	//Set MST_FUNCTION_ENABLE to 1
+			//7904	0001	// Set MST_PAYLOAD_ID_0 to 01
+			//7908	0002	// Set MST_PAYLOAD_ID_1 to 01
+			//Disable MST_VS0_DTG_ENABLE
+			7A14	0000
+			//Disable LINK_ENABLE
+			7000	0000
+			//Reset DPRX core (VIDEO_INPUT_RESET)
+			7054	0001
+			ffff	f000	//delay 0xf000 us
+			//Set MAX_LINK_RATE to 2.7Gb/s
+			7074	000A
+			//Set MAX_LINK_COUNT to 4
+			7070	0004
+			//Set ASYM_CTRL_PROP_GAIN to 000A
+			04D0	000A
+			05D0	000A
+			//Set AEQ time to 16ms
+			6064	0000
+			6065	0000
+			6164	0000
+			6165	0000
+			6264	0000
+			6265	0000
+			6364	0000
+			6365	0000
+			//Enable LINK_ENABLE
+			7000	0001
+			//delay 1000
+			//Disable MSA reset
+			7A18	0005
+			//Adjust VS0_DMA_HSYNC
+			7A28	00FF
+			7A2A	00FF
+			//Adjust VS0_DMA_VSYNC
+			7A24	00FF
+			7A27	000F
+			//Enable MST_VS0_DTG_ENABLE
+			7A14	0001
+			//set EDP Video Control
+			6421	0001
+			//Turn on video
+			6420	0013
+			//delay 100
+			//Turn off video
+			6420	0010
+			//delay 100
+			//Turn on video
+			6420	0013
+			6421	0003
+		];
+
+		i2c5_max96745_pinctrl: i2c5-max96745-pinctrl {
+			compatible = "maxim,max96745-pinctrl";
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c45_max96745_pinctrl_pins>;
+			status = "disabled";
+
+			i2c45_max96745_pinctrl_pins: pinctrl-pins {
+				i2c {
+					groups = "MAX96745_I2C";
+					function = "MAX96745_I2C";
+				};
+				lcd-bl-pwm {
+					pins = "MAX96745_MFP0";
+					function = "SER_TXID0_TO_DES_LINKA";
+				};
+				tp-int {
+					pins = "MAX96745_MFP1";
+					function = "DES_RXID1_TO_SER_LINKA";
+				};
+				lcd-bl-pwm-split {
+					pins = "MAX96745_MFP4";
+					function = "SER_TXID4_TO_DES_LINKB";
+				};
+				tp-int-split {
+					pins = "MAX96745_MFP5";
+					function = "DES_RXID5_TO_SER_LINKB";
+				};
+			};
+
+			i2c5_max96745_gpio: i2c5-max96745-gpio {
+				compatible = "maxim,max96745-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c5_max96745_pinctrl 0 280 25>;
+			};
+		};
+
+		i2c5_max96745_bridge: i2c5-max96745-bridge {
+			compatible = "maxim,max96745-bridge";
+			status = "disabled";
+		};
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				i2c5_max96745_from_edp0: endpoint {
+					remote-endpoint = <&edp0_out_i2c5_max96745>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				i2c5_max96745_out_i2c5_max96752: endpoint {
+					remote-endpoint = <&i2c5_max96752_from_i2c5_max96745>;
+				};
+			};
+
+			port@2 {
+				reg = <2>;
+
+				i2c5_max96745_out_i2c5_max96752_split: endpoint {
+					remote-endpoint = <&i2c5_max96752_split_from_i2c5_max96745>;
+				};
+			};
+		};
+	};
+
+	i2c5_max96752: i2c5-max96752@4a {
+		compatible = "maxim,max96752";
+		reg = <0x4a>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		id-serdes-panel-split = <0x02>;
+		link = <0x01>;
+		status = "disabled";
+
+		serdes-init-sequence = [
+			/*max96752 dual oLDI output*/
+			0002 0043
+			0073 0031
+			007b 0031
+			007d 0038
+			//Address Value of I2C SRC_A
+			0042 008a
+			//Address Value of I2C DST_A
+			0043 0090
+
+			0050 0000
+			01ce 004e
+			01ea 0005
+		];
+
+		i2c5_max96752_pinctrl: i2c5-max96752-pinctrl {
+			compatible = "maxim,max96752-pinctrl";
+			status = "okay";
+
+			pinctrl-names = "default","init","sleep";
+			pinctrl-0 = <&i2c5_max96752_panel_pins>;
+			pinctrl-1 = <&i2c5_max96752_panel_pins>;
+			pinctrl-2 = <&i2c5_max96752_panel_sleep_pins>;
+
+			i2c5_max96752_panel_pins: panel-pins {
+				lcd-rst-pin {
+					pins = "MAX96752_GPIO10";
+					function = "DES_TXID10_OUTPUT_HIGH";
+				};
+				tp-rst {
+					pins = "MAX96752_GPIO5";
+					function = "DES_TXID5_OUTPUT_HIGH";
+				};
+				tp-int {
+					pins = "MAX96752_GPIO2";
+					function = "DES_TXID1_TO_SER";
+				};
+				100ms-delay {
+					pins = "MAX96752_GPIO15";
+					function = "DELAY_100MS";
+				};
+				lcd-pwr-on {
+					pins = "MAX96752_GPIO3";
+					function = "DES_TXID3_OUTPUT_HIGH";
+				};
+				lcd-bl-pwm {
+					pins = "MAX96752_GPIO4";
+					function = "SER_TO_DES_RXID4";
+				};
+				lcd_bias_en {
+					pins = "MAX96752_GPIO7";
+					function = "DES_TXID7_OUTPUT_HIGH";
+				};
+				lcd_vdd_en {
+					pins = "MAX96752_GPIO6";
+					function = "DES_TXID6_OUTPUT_HIGH";
+				};
+			};
+
+			i2c5_max96752_panel_sleep_pins: panel-sleep-pins {
+				lcd-rst-pin {
+					pins = "MAX96752_GPIO10";
+					function = "DES_TXID10_OUTPUT_LOW";
+				};
+
+				tp-rst {
+					pins = "MAX96752_GPIO5";
+					function = "DES_TXID5_OUTPUT_LOW";
+				};
+
+				lcd-pwr-on {
+					pins = "MAX96752_GPIO3";
+					function = "DES_TXID3_OUTPUT_LOW";
+				};
+			};
+
+			i2c5_max96752_gpio: i2c5-max96752-gpio {
+				compatible = "maxim,max96752-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c5_max96752_pinctrl 0 305 15>;
+			};
+		};
+
+		i2c5_max96752_panel: i2c5-max96752-panel {
+			compatible = "maxim,max96752-panel";
+			status = "disabled";
+
+			backlight = <&edp2lvds_backlight0>;
+			panel-size= <346 194>;
+
+			panel-timing {
+				clock-frequency = <230400000>;	//4128*930@60
+				hactive = <3840>;
+				vactive = <720>;
+				hfront-porch = <112>;
+				hsync-len = <64>;
+				hback-porch = <112>;
+				vfront-porch = <200>;
+				vsync-len = <2>;
+				vback-porch = <8>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <0>;
+				pixelclk-active = <0>;
+			};
+
+			port {
+				i2c5_max96752_from_i2c5_max96745: endpoint {
+					remote-endpoint = <&i2c5_max96745_out_i2c5_max96752>;
+				};
+			};
+		};
+	};
+
+	i2c5_max96752_split: i2c5-max96752-split@4b {
+		compatible = "maxim,max96752";
+		reg = <0x4b>;
+		reg-hw = <0x4a>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		id-serdes-panel-split = <0x02>;
+		link = <0x02>;
+		status = "disabled";
+
+		serdes-init-sequence = [
+			/*max96752 dual oLDI output*/
+			0002 0043
+			0073 0032
+			007b 0032
+			007d 0038
+			//Address Value of I2C SRC_A
+			0042 008c
+			//Address Value of I2C DST_A
+			0043 0090
+
+			//0140 0020
+			0050 0001
+			01ce 004e
+			01ea 0005
+		];
+
+		i2c5_max96752_split_pinctrl: i2c5-max96752-split-pinctrl {
+			compatible = "maxim,max96752-pinctrl";
+			status = "disabled";
+
+			pinctrl-names = "default","init","sleep";
+			pinctrl-0 = <&i2c5_max96752_split_panel_pins>;
+			pinctrl-1 = <&i2c5_max96752_split_panel_pins>;
+			pinctrl-2 = <&i2c5_max96752_split_panel_sleep_pins>;
+
+			i2c5_max96752_split_panel_pins: i2c5-max96752-split-panel-pins {
+				lcd-rst-pin {
+					pins = "MAX96752_GPIO10";
+					function = "DES_TXID10_OUTPUT_HIGH";
+				};
+				tp-rst {
+					pins = "MAX96752_GPIO5";
+					function = "DES_TXID5_OUTPUT_HIGH";
+				};
+				tp-int {
+					pins = "MAX96752_GPIO2";
+					function = "DES_TXID4_TO_SER";
+				};
+				100ms-delay {
+					pins = "MAX96752_GPIO15";
+					function = "DELAY_100MS";
+				};
+				lcd-pwr-on {
+					pins = "MAX96752_GPIO3";
+					function = "DES_TXID3_OUTPUT_HIGH";
+				};
+				lcd-bl-pwm {
+					pins = "MAX96752_GPIO4";
+					function = "SER_TO_DES_RXID4";
+				};
+				lcd_bias_en {
+					pins = "MAX96752_GPIO7";
+					function = "DES_TXID7_OUTPUT_HIGH";
+				};
+				lcd_vdd_en {
+					pins = "MAX96752_GPIO6";
+					function = "DES_TXID6_OUTPUT_HIGH";
+				};
+			};
+
+			i2c5_max96752_split_panel_sleep_pins: i2c5-max96752-split-panel-sleep-pins {
+				lcd-rst-pin {
+					pins = "MAX96752_GPIO10";
+					function = "DES_TXID10_OUTPUT_LOW";
+				};
+
+				tp-rst {
+					pins = "MAX96752_GPIO5";
+					function = "DES_TXID5_OUTPUT_LOW";
+				};
+
+				lcd-pwr-on {
+					pins = "MAX96752_GPIO3";
+					function = "DES_TXID3_OUTPUT_LOW";
+				};
+			};
+
+			i2c5_max96752_split_gpio: i2c5-max96752-split-gpio {
+				compatible = "maxim,max96752-gpio";
+				status = "okay";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-ranges = <&i2c5_max96752_split_pinctrl 0 320 15>;
+			};
+		};
+
+		i2c5_max96752_split_panel: i2c5-max96752-split-panel {
+			compatible = "maxim,max96752-panel-split";
+			status = "disabled";
+
+			backlight = <&edp2lvds_backlight1>;
+			panel-size= <346 194>;
+
+			panel-timing {
+				clock-frequency = <115200000>;
+				hactive = <1920>;
+				vactive = <720>;
+				hfront-porch = <56>;
+				hsync-len = <32>;
+				hback-porch = <56>;
+				vfront-porch = <200>;
+				vsync-len = <2>;
+				vback-porch = <8>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <0>;
+				pixelclk-active = <0>;
+			};
+
+			port {
+				i2c5_max96752_split_from_i2c5_max96745: endpoint {
+					remote-endpoint = <&i2c5_max96745_out_i2c5_max96752_split>;
+				};
+			};
+		};
+	};
+
+	himax@45 {
+		compatible = "himax,hxcommon";
+		reg = <0x45>;
+		pinctrl-names = "default", "sleep";
+		pinctrl-0 = <&touch_gpio_edp0>;
+		pinctrl-1 = <&touch_gpio_edp0>;
+		himax,location = "himax-touch-edp0";
+		himax,irq-gpio = <&gpio1 RK_PA5 IRQ_TYPE_EDGE_FALLING>;
+		himax,rst-gpio = <&i2c5_max96752_gpio 5 GPIO_ACTIVE_LOW>;
+		himax,panel-coords = <0 1920 0 720>;
+		himax,display-coords = <0 1920 0 720>;
+		status = "disabled";
+	};
+
+	himax_split@46 {
+		compatible = "himax,hxcommon";
+		reg = <0x46>;
+		pinctrl-names = "default", "sleep";
+		pinctrl-0 = <&touch_gpio_edp0>;
+		pinctrl-1 = <&touch_gpio_edp0>;
+		himax,location = "himax-touch-edp0-split";
+		//himax,irq-gpio = <&gpio1 RK_PA5 IRQ_TYPE_EDGE_FALLING>;
+		himax,rst-gpio = <&i2c5_max96752_gpio 5 GPIO_ACTIVE_LOW>;
+		himax,panel-coords = <0 1920 0 720>;
+		himax,display-coords = <0 1920 0 720>;
+		status = "disabled";
+	};
+};
+
+&mipi_dcphy0 {
+	status = "okay";
+};
+
+&mipi_dcphy1 {
+	status = "okay";
+};
+
+&pinctrl {
+	serdes {
+		i2c2_serdes_pins: i2c2-serdes-pins {
+			rockchip,pins =
+				<1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		i2c4_serdes_pins: i2c4-serdes-pins {
+			rockchip,pins =
+				<3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		i2c5_serdes_pins: i2c5-serdes-pins {
+			rockchip,pins =
+				<0 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		i2c6_serdes_pins: i2c6-serdes-pins {
+			rockchip,pins =
+				<1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		i2c7_serdes_pins: i2c7-serdes-pins {
+			rockchip,pins =
+				<4 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		i2c8_serdes_pins: i2c8-serdes-pins {
+			rockchip,pins =
+				<3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+/* dsi0->serdes->lvds_panel */
+&pwm0 {
+	status = "okay";
+	pinctrl-0 = <&pwm0m2_pins>;
+};
+
+/* dp0->serdes->lvds_panel */
+&pwm10 {
+	pinctrl-0 = <&pwm10m2_pins>;
+	status = "okay";
+};
+
+/* edp1->serdes->lvds_panel */
+&pwm11 {
+	pinctrl-0 = <&pwm11m3_pins>;
+	status = "okay";
+};
+
+/* edp0->serdes->lvds_panel */
+&pwm7 {
+	pinctrl-0 = <&pwm7m0_pins>;
+	status = "okay";
+};
+
+/* dsi1->serdes->lvds_panel */
+&pwm13 {
+	status = "okay";
+	pinctrl-0 = <&pwm13m2_pins>;	//hw change to PWM13_M2(GPIO1_B7)
+};
+
+/* dp1->serdes->lvds_panel */
+&pwm14 {
+	pinctrl-0 = <&pwm14m0_pins>;
+	status = "okay";
+};
+
+&route_dp0 {
+	status = "disabled";
+	connect = <&vp0_out_dp0>;
+	logo,uboot = "logo34.bmp";
+	logo,kernel = "logo34.bmp";
+};
+
+&route_dp1 {
+	status = "disabled";
+	connect = <&vp0_out_dp1>;
+	logo,uboot = "logo34.bmp";
+	logo,kernel = "logo34.bmp";
+};
+
+&route_dsi0 {
+	status = "disabled";
+	connect = <&vp2_out_dsi0>;
+	logo,uboot = "logo1.bmp";
+	logo,kernel = "logo1.bmp";
+};
+
+&route_dsi1 {
+	status = "disabled";
+	connect = <&vp3_out_dsi1>;
+	logo,uboot = "logo2.bmp";
+	logo,kernel = "logo2.bmp";
+};
+
+&route_edp0 {
+	status = "disabled";
+	connect = <&vp1_out_edp0>;
+	logo,uboot = "logo56.bmp";
+	logo,kernel = "logo56.bmp";
+};
+
+&route_edp1 {
+	status = "disabled";
+	connect = <&vp1_out_edp1>;
+	logo,uboot = "logo56.bmp";
+	logo,kernel = "logo56.bmp";
+};
+
+&usbdp_phy0 {
+	rockchip,dp-lane-mux = <0 1 2 3>;
+	status = "okay";
+};
+
+&usbdp_phy1 {
+	rockchip,dp-lane-mux = <0 1 2 3>;
+	status = "okay";
+};
+
+&vop {
+	assigned-clocks = <&cru PLL_V0PLL>;
+	assigned-clock-rates = <2304000000>;
+};
+
+&vp0 {
+	assigned-clocks = <&cru DCLK_VOP0_SRC>;
+	assigned-clock-parents = <&cru PLL_V0PLL>;
+};
+
+&vp1 {
+	assigned-clocks = <&cru DCLK_VOP1_SRC>;
+	assigned-clock-parents = <&cru PLL_GPLL>;
+};
+
+&vp2 {
+	assigned-clocks = <&cru DCLK_VOP2_SRC>;
+	assigned-clock-parents = <&cru PLL_V0PLL>;
+};
+
+&vp3 {
+	assigned-clocks = <&cru DCLK_VOP3>;
+	assigned-clock-parents = <&cru PLL_V0PLL>;
+};
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-rohm.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-rohm.dtsi
index 1bc6c5e..1df644b 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-rohm.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-rohm.dtsi
@@ -411,6 +411,7 @@
 			reg = <1>;
 
 			dp0_out_i2c4_bu18tl82: endpoint {
+				link-frequencies = /bits/ 64 <1620000000>;
 				remote-endpoint = <&i2c4_bu18tl82_in_dp0>;
 			};
 		};
@@ -796,20 +797,18 @@
 			0424 0000
 			0425 0020
 			0426 0080
-			//0057 0000
-			//0058 0002
-			//0057 0000	//rl gpio0 output	lcd_bl_pwm
-			//0058 0002	//bypass ser gpio0
-			//005a 0000	//rl gpio1 output	lcd_pwr_en
-			//005b 0003	//bypass ser gpio1
-			//005d 0000	//rl gpio2 output	lcd_rst
-			//005e 0004	//bypass ser gpio2
-			//0060 0000	//rl gpio3 output	tp-rst
-			//0061 0005	//bypass ser gpio3
-			//0063 0018	//rl gpio4 input	tp-int
-			//0064 0006	//bypass ser gpio4
-			//0066 0000	//rl gpio5 output
-			//0067 0001	//set gpio5 high
+			0057 0000	//rl gpio0 output	lcd_bl_pwm
+			0058 0000	//bypass ser gpio0
+			005a 0000	//rl gpio1 output	lcd_pwr_en
+			005b 0000	//bypass ser gpio1
+			005d 0000	//rl gpio2 output	lcd_rst
+			005e 0000	//bypass ser gpio2
+			0060 0000	//rl gpio3 output	tp-rst
+			0061 0000	//bypass ser gpio3
+			0063 0018	//rl gpio4 input	tp-int
+			0064 0006	//bypass ser gpio4
+			0066 0000	//rl gpio5 output
+			0067 0000	//set gpio5 high
 
 			0073 0080
 			0074 0007	//0x0780 = 1920
@@ -853,24 +852,15 @@
 
 		i2c2_bu18rl82_pinctrl: i2c2-bu18rl82-pinctrl {
 			compatible = "rohm,bu18rl82-pinctrl";
-			pinctrl-names = "default","sleep";
+			pinctrl-names = "default","init","sleep";
 			pinctrl-0 = <&i2c2_bu18rl82_panel_pins>;
-			pinctrl-1 = <&i2c2_bu18rl82_panel_sleep_pins>;
+			pinctrl-1 = <&i2c2_bu18rl82_panel_pins>;
+			pinctrl-2 = <&i2c2_bu18rl82_panel_sleep_pins>;
 			status = "okay";
 
 			i2c2_bu18rl82_panel_pins: panel-pins {
-				lcd-bl-pwm {
-					pins = "BU18RL82_GPIO0";
-					function = "SER_GPIO0_TO_DES";
-				};
-
-				lcd-pwr-en {
-					pins = "BU18RL82_GPIO1";
-					function = "SER_GPIO1_TO_DES";
-				};
-
-				lcd-rst {
-					pins = "BU18RL82_GPIO2";
+				lcd-otp-pin {
+					pins = "BU18RL82_GPIO5";
 					function = "DES_GPIO_OUTPUT_HIGH";
 				};
 
@@ -879,14 +869,29 @@
 					function = "DES_GPIO_OUTPUT_HIGH";
 				};
 
+				lcd-rst {
+					pins = "BU18RL82_GPIO2";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
 				tp-int {
 					pins = "BU18RL82_GPIO4";
 					function = "DES_TO_SER_GPIO3";
 				};
 
-				lcd-otp-pin {
-					pins = "BU18RL82_GPIO5";
+				100ms-delay {
+					pins = "BU18RL82_GPIO1";
+					function = "DELAY_100MS";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18RL82_GPIO1";
 					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				lcd-bl-pwm {
+					pins = "BU18RL82_GPIO0";
+					function = "SER_GPIO0_TO_DES";
 				};
 			};
 
@@ -1130,20 +1135,18 @@
 			0424 0000
 			0425 0020
 			0426 0080
-			//0057 0000
-			//0058 0002
-			//0057 0000	//rl gpio0 output	lcd_bl_pwm
-			//0058 0002	//bypass ser gpio0
-			//005a 0000	//rl gpio1 output	lcd_pwr_en
-			//005b 0003	//bypass ser gpio1
-			//005d 0000	//rl gpio2 output	lcd_rst
-			//005e 0004	//bypass ser gpio2
-			//0060 0000	//rl gpio3 output	tp-rst
-			//0061 0005	//bypass ser gpio3
-			//0063 0018	//rl gpio4 input	tp-int
-			//0064 0006	//bypass ser gpio4
-			//0066 0000	//rl gpio5 output
-			//0067 0001	//set gpio5 high
+			0057 0000	//rl gpio0 output	lcd_bl_pwm
+			0058 0000	//set gpio0 low
+			005a 0000	//rl gpio1 output	lcd_pwr_en
+			005b 0000	//set gpio1 low
+			005d 0000	//rl gpio2 output	lcd_rst
+			005e 0000	//set gpio2 low
+			0060 0000	//rl gpio3 output	tp-rst
+			0061 0000	//set gpio3 low
+			0063 0018	//rl gpio4 input	tp-int
+			0064 0006	//bypass ser gpio4
+			0066 0000	//rl gpio5 output
+			0067 0000	//set gpio5 low
 
 			0073 0080
 			0074 0007	//0x0780 = 1920
@@ -1187,24 +1190,15 @@
 
 		i2c4_bu18rl82_pinctrl: i2c4-bu18rl82-pinctrl {
 			compatible = "rohm,bu18rl82-pinctrl";
-			pinctrl-names = "default","sleep";
+			pinctrl-names = "default","init","sleep";
 			pinctrl-0 = <&i2c4_bu18rl82_panel_pins>;
-			pinctrl-1 = <&i2c4_bu18rl82_panel_sleep_pins>;
+			pinctrl-1 = <&i2c4_bu18rl82_panel_pins>;
+			pinctrl-2 = <&i2c4_bu18rl82_panel_sleep_pins>;
 			status = "okay";
 
 			i2c4_bu18rl82_panel_pins: panel-pins {
-				lcd-bl-pwm {
-					pins = "BU18RL82_GPIO0";
-					function = "SER_GPIO0_TO_DES";
-				};
-
-				lcd-pwr-en {
-					pins = "BU18RL82_GPIO1";
-					function = "SER_GPIO1_TO_DES";
-				};
-
-				lcd-rst {
-					pins = "BU18RL82_GPIO2";
+				lcd-otp-pin {
+					pins = "BU18RL82_GPIO5";
 					function = "DES_GPIO_OUTPUT_HIGH";
 				};
 
@@ -1213,14 +1207,29 @@
 					function = "DES_GPIO_OUTPUT_HIGH";
 				};
 
+				lcd-rst {
+					pins = "BU18RL82_GPIO2";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
 				tp-int {
 					pins = "BU18RL82_GPIO4";
 					function = "DES_TO_SER_GPIO3";
 				};
 
-				lcd-otp-pin {
-					pins = "BU18RL82_GPIO5";
+				100ms-delay {
+					pins = "BU18RL82_GPIO1";
+					function = "DELAY_100MS";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18RL82_GPIO1";
 					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
+				lcd-bl-pwm {
+					pins = "BU18RL82_GPIO0";
+					function = "SER_GPIO0_TO_DES";
 				};
 			};
 
@@ -1456,20 +1465,18 @@
 			0020 0002
 			0031 0041	//i2c addr 0x41
 			0032 0041	//i2c addr 0x41
-			//0057 0000	//rl gpio0 output	lcd_bl_pwm
-			//0058 0002	//bypass ser gpio0
-			//005a 0000	//rl gpio1 output	lcd_pwr_en
-			//005b 0001	//bypass ser gpio1
-			//005d 0000	//rl gpio2 output	lcd_rst
-			//005e 0004	//bypass ser gpio2
-			//0060 0018	//rl gpio3 input	tp-int
-			//042e 0005	//bypass ser gpio3
-			//0061 0005	//bypass ser gpio3
-			//0063 0000	//rl gpio4 output	tp-rst
-			//042f 0006	//bypass ser gpio4
-			//0064 0006	//bypass ser gpio4
-			//0066 0000	//rl gpio5 output
-			//0067 0007	//bypass ser gpio5
+			0057 0000	//rl gpio0 output	lcd_bl_pwm
+			0058 0000	//set gpio0 low
+			005a 0000	//rl gpio1 output	lcd_pwr_en
+			005b 0000	//set gpio1 low
+			005d 0000	//rl gpio2 output	lcd_rst
+			005e 0000	//set gpio2 low
+			0060 0000	//rl gpio3 output	tp-rst
+			0061 0000	//set gpio3 low
+			0063 0018	//rl gpio4 input	tp-int
+			0064 0006	//bypass ser gpio4
+			0066 0000	//rl gpio5 output
+			0067 0000	//set gpio5 low
 			0073 0080
 			0074 0007
 			0079 000a
@@ -1514,20 +1521,21 @@
 
 		i2c5_bu18rl82_pinctrl: i2c5-bu18rl82-pinctrl {
 			compatible = "rohm,bu18rl82-pinctrl";
-			pinctrl-names = "default","sleep";
+			pinctrl-names = "default","init","sleep";
 			pinctrl-0 = <&i2c5_bu18rl82_panel_pins>;
-			pinctrl-1 = <&i2c5_bu18rl82_panel_sleep_pins>;
+			pinctrl-1 = <&i2c5_bu18rl82_panel_pins>;
+			pinctrl-2 = <&i2c5_bu18rl82_panel_sleep_pins>;
 			status = "okay";
 
 			i2c5_bu18rl82_panel_pins: panel-pins {
-				lcd-bl-pwm {
-					pins = "BU18RL82_GPIO0";
-					function = "SER_GPIO0_TO_DES";
+				lcd-otp-pin {
+					pins = "BU18RL82_GPIO5";
+					function = "DES_GPIO_OUTPUT_HIGH";
 				};
 
-				lcd-pwr-en {
-					pins = "BU18RL82_GPIO1";
-					function = "SER_GPIO1_TO_DES";
+				tp-rst {
+					pins = "BU18RL82_GPIO3";
+					function = "DES_GPIO_OUTPUT_HIGH";
 				};
 
 				lcd-rst {
@@ -1536,18 +1544,23 @@
 				};
 
 				tp-int {
-					pins = "BU18RL82_GPIO3";
+					pins = "BU18RL82_GPIO4";
 					function = "DES_TO_SER_GPIO3";
 				};
 
-				tp-rst {
-					pins = "BU18RL82_GPIO4";
+				100ms-delay {
+					pins = "BU18RL82_GPIO1";
+					function = "DELAY_100MS";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18RL82_GPIO1";
 					function = "DES_GPIO_OUTPUT_HIGH";
 				};
 
-				lcd-otp-pin {
-					pins = "BU18RL82_GPIO5";
-					function = "DES_GPIO_OUTPUT_HIGH";
+				lcd-bl-pwm {
+					pins = "BU18RL82_GPIO0";
+					function = "SER_GPIO0_TO_DES";
 				};
 			};
 
@@ -1799,20 +1812,18 @@
 			0424 0000
 			0425 0020
 			0426 0080
-			//0057 0000
-			//0058 0002
-			//0057 0000	//rl gpio0 output	lcd_bl_pwm
-			//0058 0002	//bypass ser gpio0
-			//005a 0000	//rl gpio1 output	lcd_pwr_en
-			//005b 0003	//bypass ser gpio1
-			//005d 0000	//rl gpio2 output	lcd_rst
-			//005e 0004	//bypass ser gpio2
-			//0060 0000	//rl gpio3 output	tp-rst
-			//0061 0005	//bypass ser gpio3
-			//0063 0018	//rl gpio4 input	tp-int
-			//0064 0006	//bypass ser gpio4
-			//0066 0000	//rl gpio5 output
-			//0067 0001	//set gpio5 high
+			0057 0000	//rl gpio0 output	lcd_bl_pwm
+			0058 0000	//set gpio0 low
+			005a 0000	//rl gpio1 output	lcd_pwr_en
+			005b 0000	//set gpio1 low
+			005d 0000	//rl gpio2 output	lcd_rst
+			005e 0000	//set gpio2 low
+			0060 0000	//rl gpio3 output	tp-rst
+			0061 0000	//set gpio3 low
+			0063 0018	//rl gpio4 input	tp-int
+			0064 0006	//bypass ser gpio4
+			0066 0000	//rl gpio5 output
+			0067 0000	//set gpio5 low
 
 			0073 0080
 			0074 0007	//0x0780 = 1920
@@ -1856,24 +1867,15 @@
 
 		i2c6_bu18rl82_pinctrl: i2c6-bu18rl82-pinctrl {
 			compatible = "rohm,bu18rl82-pinctrl";
-			pinctrl-names = "default","sleep";
+			pinctrl-names = "default","init","sleep";
 			pinctrl-0 = <&i2c6_bu18rl82_panel_pins>;
-			pinctrl-1 = <&i2c6_bu18rl82_panel_sleep_pins>;
+			pinctrl-1 = <&i2c6_bu18rl82_panel_pins>;
+			pinctrl-2 = <&i2c6_bu18rl82_panel_sleep_pins>;
 			status = "okay";
 
 			i2c6_bu18rl82_panel_pins: panel-pins {
-				lcd-bl-pwm {
-					pins = "BU18RL82_GPIO0";
-					function = "SER_GPIO0_TO_DES";
-				};
-
-				lcd-pwr-en {
-					pins = "BU18RL82_GPIO1";
-					function = "SER_GPIO1_TO_DES";
-				};
-
-				lcd-rst {
-					pins = "BU18RL82_GPIO2";
+				lcd-otp-pin {
+					pins = "BU18RL82_GPIO5";
 					function = "DES_GPIO_OUTPUT_HIGH";
 				};
 
@@ -1882,15 +1884,30 @@
 					function = "DES_GPIO_OUTPUT_HIGH";
 				};
 
+				lcd-rst {
+					pins = "BU18RL82_GPIO2";
+					function = "DES_GPIO_OUTPUT_HIGH";
+				};
+
 				tp-int {
 					pins = "BU18RL82_GPIO4";
 					function = "DES_TO_SER_GPIO3";
 				};
 
-				lcd-otp-pin {
-					pins = "BU18RL82_GPIO5";
+				100ms-delay {
+					pins = "BU18RL82_GPIO1";
+					function = "DELAY_100MS";
+				};
+
+				lcd-pwr-en {
+					pins = "BU18RL82_GPIO1";
 					function = "DES_GPIO_OUTPUT_HIGH";
 				};
+
+				lcd-bl-pwm {
+					pins = "BU18RL82_GPIO0";
+					function = "SER_GPIO0_TO_DES";
+				};
 			};
 
 			i2c6_bu18rl82_panel_sleep_pins: panel-sleep-pins {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588s-evb1-lp4x.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588s-evb1-lp4x.dtsi
index 68f17ee..8c1d0f3 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588s-evb1-lp4x.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588s-evb1-lp4x.dtsi
@@ -142,8 +142,8 @@
 		enable-delay-ms = <120>;
 		unprepare-delay-ms = <120>;
 		disable-delay-ms = <120>;
-		width-mm = <129>;
-		height-mm = <171>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		panel-timing {
 			clock-frequency = <200000000>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588s-evb3-lp4x-v10-sii9022-bt1120-to-hdmi.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3588s-evb3-lp4x-v10-sii9022-bt1120-to-hdmi.dts
index e2d5f25..4a03bc6 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588s-evb3-lp4x-v10-sii9022-bt1120-to-hdmi.dts
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588s-evb3-lp4x-v10-sii9022-bt1120-to-hdmi.dts
@@ -19,6 +19,13 @@
 	status = "disabled";
 };
 
+/*
+ * The pins of gt1x and sii9022 are multiplexed
+ */
+&gt1x {
+	status = "disabled";
+};
+
 &i2c4 {
 	clock-frequency = <400000>;
 	status = "okay";
@@ -32,6 +39,10 @@
 		interrupts = <RK_PC0 IRQ_TYPE_LEVEL_HIGH>;
 		reset-gpio = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>;
 		enable-gpio = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>;
+		/*
+		 * MEDIA_BUS_FMT_UYVY8_1X16 for bt1120
+		 * MEDIA_BUS_FMT_UYVY8_2X8  for bt656
+		 */
 		bus-format = <MEDIA_BUS_FMT_UYVY8_1X16>;
 
 		ports {
@@ -60,6 +71,10 @@
 &rgb {
 	status = "okay";
 	pinctrl-names = "default";
+	/*
+	 * <&bt1120_pins> for bt1120
+	 * <&bt656_pins>  for bt656
+	 */
 	pinctrl-0 = <&bt1120_pins>;
 
 	ports {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588s-evb8-lp4x.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588s-evb8-lp4x.dtsi
index 4e0cc72..982461d 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588s-evb8-lp4x.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588s-evb8-lp4x.dtsi
@@ -106,8 +106,8 @@
 		enable-delay-ms = <120>;
 		unprepare-delay-ms = <120>;
 		disable-delay-ms = <120>;
-		width-mm = <129>;
-		height-mm = <171>;
+		width-mm = <120>;
+		height-mm = <160>;
 
 		panel-timing {
 			clock-frequency = <200000000>;
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588s-tablet.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588s-tablet.dtsi
index 008ff6f..6a971d6 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588s-tablet.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588s-tablet.dtsi
@@ -92,7 +92,7 @@
 		status = "disabled";
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "dsp_a";
-		simple-audio-card,bitclock-inversion = <0>;
+		simple-audio-card,bitclock-inversion;
 		simple-audio-card,mclk-fs = <256>;
 		simple-audio-card,name = "rockchip,bt";
 		simple-audio-card,cpu {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
index 6b46d1b..1c24f35 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
@@ -337,6 +337,7 @@
 			clock-output-names = "i2s0_mclkout_to_io";
 			rockchip,bit-shift = <0>;
 			rockchip,bit-set-to-disable;
+			rockchip,clk-ignore-unused; /* for OLD SDK */
 		};
 
 		mclkout_i2s1: mclkout-i2s1@fd58c318 {
@@ -347,6 +348,7 @@
 			clock-output-names = "i2s1_mclkout_to_io";
 			rockchip,bit-shift = <1>;
 			rockchip,bit-set-to-disable;
+			rockchip,clk-ignore-unused; /* for OLD SDK */
 		};
 
 		mclkout_i2s1m1: mclkout-i2s1@fd58a000 {
@@ -356,6 +358,7 @@
 			#clock-cells = <0>;
 			clock-output-names = "i2s1m1_mclkout_to_io";
 			rockchip,bit-shift = <6>;
+			rockchip,clk-ignore-unused; /* for OLD SDK */
 		};
 
 		mclkout_i2s2: mclkout-i2s2@fd58c318 {
@@ -366,6 +369,7 @@
 			clock-output-names = "i2s2_mclkout_to_io";
 			rockchip,bit-shift = <2>;
 			rockchip,bit-set-to-disable;
+			rockchip,clk-ignore-unused; /* for OLD SDK */
 		};
 
 		mclkout_i2s3: mclkout-i2s3@fd58c318 {
@@ -376,6 +380,7 @@
 			clock-output-names = "i2s3_mclkout_to_io";
 			rockchip,bit-shift = <7>;
 			rockchip,bit-set-to-disable;
+			rockchip,clk-ignore-unused; /* for OLD SDK */
 		};
 	};
 
@@ -1744,6 +1749,7 @@
 			SYS_STATUS_PERFORMANCE  DMC_FREQ_LEVEL_HIGH
 			SYS_STATUS_DUALVIEW     DMC_FREQ_LEVEL_HIGH
 			SYS_STATUS_HDMIRX       DMC_FREQ_LEVEL_HIGH
+			SYS_STATUS_DEEP_SUSPEND DMC_FREQ_LEVEL_HIGH
 		>;
 		auto-freq-en = <1>;
 		status = "disabled";
@@ -2163,6 +2169,11 @@
 		status = "disabled";
 	};
 
+	rkvtunnel: rkvtunnel {
+		compatible = "rockchip,video-tunnel";
+		status = "disabled";
+	};
+
 	rockchip_suspend: rockchip-suspend {
 		compatible = "rockchip,pm-rk3588";
 		status = "disabled";
@@ -2354,8 +2365,7 @@
 		rockchip,pvtm-temp-prop = <(-135) (-135)>;
 		rockchip,pvtm-thermal-zone = "gpu-thermal";
 
-		clocks = <&cru CLK_GPU>;
-		clock-names = "clk";
+		rockchip,opp-clocks = <&cru CLK_GPU>;
 		rockchip,grf = <&gpu_grf>;
 		volt-mem-read-margin = <
 			855000	1
@@ -2597,7 +2607,7 @@
 	};
 
 	usb_host0_ohci: usb@fc840000 {
-		compatible = "generic-ohci";
+		compatible = "rockchip,rk3588-ohci", "generic-ohci";
 		reg = <0x0 0xfc840000 0x0 0x40000>;
 		interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&u2phy2>, <&aclk_usb>;
@@ -2622,7 +2632,7 @@
 	};
 
 	usb_host1_ohci: usb@fc8c0000 {
-		compatible = "generic-ohci";
+		compatible = "rockchip,rk3588-ohci", "generic-ohci";
 		reg = <0x0 0xfc8c0000 0x0 0x40000>;
 		interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&u2phy3>, <&aclk_usb>;
@@ -2706,6 +2716,8 @@
 			mode-panic = <BOOT_PANIC>;
 			mode-watchdog = <BOOT_WATCHDOG>;
 			mode-quiescent = <BOOT_QUIESCENT>;
+			/* add a mode to capture the ramdump through usb */
+			mode-winusb = <BOOT_WINUSB>;
 		};
 	};
 
@@ -2965,6 +2977,8 @@
 		interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&i2c0m0_xfer>;
+		resets = <&cru SRST_I2C0>, <&cru SRST_P_I2C0>;
+		reset-names = "i2c", "apb";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -3443,8 +3457,7 @@
 		rockchip,pvtm-temp-prop = <(-113) (-113)>;
 		rockchip,pvtm-thermal-zone = "npu-thermal";
 
-		clocks = <&cru PCLK_NPU_GRF>;
-		clock-names = "pclk";
+		rockchip,opp-clocks = <&cru PCLK_NPU_GRF>, <&cru HCLK_NPU_ROOT>;
 		rockchip,grf = <&npu_grf>;
 		volt-mem-read-margin = <
 			855000	1
@@ -5950,6 +5963,8 @@
 		interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&i2c1m0_xfer>;
+		resets = <&cru SRST_I2C1>, <&cru SRST_P_I2C1>;
+		reset-names = "i2c", "apb";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -5963,6 +5978,8 @@
 		interrupts = <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&i2c2m0_xfer>;
+		resets = <&cru SRST_I2C2>, <&cru SRST_P_I2C2>;
+		reset-names = "i2c", "apb";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -5976,6 +5993,8 @@
 		interrupts = <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&i2c3m0_xfer>;
+		resets = <&cru SRST_I2C3>, <&cru SRST_P_I2C3>;
+		reset-names = "i2c", "apb";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -5989,6 +6008,8 @@
 		interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&i2c4m0_xfer>;
+		resets = <&cru SRST_I2C4>, <&cru SRST_P_I2C4>;
+		reset-names = "i2c", "apb";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -6002,6 +6023,8 @@
 		interrupts = <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&i2c5m0_xfer>;
+		resets = <&cru SRST_I2C5>, <&cru SRST_P_I2C5>;
+		reset-names = "i2c", "apb";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -6429,6 +6452,8 @@
 		interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&i2c6m0_xfer>;
+		resets = <&cru SRST_I2C6>, <&cru SRST_P_I2C6>;
+		reset-names = "i2c", "apb";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -6442,6 +6467,8 @@
 		interrupts = <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&i2c7m0_xfer>;
+		resets = <&cru SRST_I2C7>, <&cru SRST_P_I2C7>;
+		reset-names = "i2c", "apb";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -6455,6 +6482,8 @@
 		interrupts = <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&i2c8m0_xfer>;
+		resets = <&cru SRST_I2C8>, <&cru SRST_P_I2C8>;
+		reset-names = "i2c", "apb";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
diff --git a/kernel/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/kernel/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
index d041897..4265f62 100644
--- a/kernel/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+++ b/kernel/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
@@ -127,7 +127,6 @@
 		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";
diff --git a/kernel/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/kernel/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
index e8a4143..4ec5e95 100644
--- a/kernel/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+++ b/kernel/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
@@ -16,28 +16,28 @@
 	};
 };
 
-&wkup_pmx0 {
+&wkup_pmx2 {
 	mcu_cpsw_pins_default: mcu-cpsw-pins-default {
 		pinctrl-single,pins = <
-			J721E_WKUP_IOPAD(0x0068, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */
-			J721E_WKUP_IOPAD(0x006c, PIN_INPUT, 0) /* MCU_RGMII1_RX_CTL */
-			J721E_WKUP_IOPAD(0x0070, PIN_OUTPUT, 0) /* MCU_RGMII1_TD3 */
-			J721E_WKUP_IOPAD(0x0074, PIN_OUTPUT, 0) /* MCU_RGMII1_TD2 */
-			J721E_WKUP_IOPAD(0x0078, PIN_OUTPUT, 0) /* MCU_RGMII1_TD1 */
-			J721E_WKUP_IOPAD(0x007c, PIN_OUTPUT, 0) /* MCU_RGMII1_TD0 */
-			J721E_WKUP_IOPAD(0x0088, PIN_INPUT, 0) /* MCU_RGMII1_RD3 */
-			J721E_WKUP_IOPAD(0x008c, PIN_INPUT, 0) /* MCU_RGMII1_RD2 */
-			J721E_WKUP_IOPAD(0x0090, PIN_INPUT, 0) /* MCU_RGMII1_RD1 */
-			J721E_WKUP_IOPAD(0x0094, PIN_INPUT, 0) /* MCU_RGMII1_RD0 */
-			J721E_WKUP_IOPAD(0x0080, PIN_OUTPUT, 0) /* MCU_RGMII1_TXC */
-			J721E_WKUP_IOPAD(0x0084, PIN_INPUT, 0) /* MCU_RGMII1_RXC */
+			J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */
+			J721E_WKUP_IOPAD(0x0004, PIN_INPUT, 0) /* MCU_RGMII1_RX_CTL */
+			J721E_WKUP_IOPAD(0x0008, PIN_OUTPUT, 0) /* MCU_RGMII1_TD3 */
+			J721E_WKUP_IOPAD(0x000c, PIN_OUTPUT, 0) /* MCU_RGMII1_TD2 */
+			J721E_WKUP_IOPAD(0x0010, PIN_OUTPUT, 0) /* MCU_RGMII1_TD1 */
+			J721E_WKUP_IOPAD(0x0014, PIN_OUTPUT, 0) /* MCU_RGMII1_TD0 */
+			J721E_WKUP_IOPAD(0x0020, PIN_INPUT, 0) /* MCU_RGMII1_RD3 */
+			J721E_WKUP_IOPAD(0x0024, PIN_INPUT, 0) /* MCU_RGMII1_RD2 */
+			J721E_WKUP_IOPAD(0x0028, PIN_INPUT, 0) /* MCU_RGMII1_RD1 */
+			J721E_WKUP_IOPAD(0x002c, PIN_INPUT, 0) /* MCU_RGMII1_RD0 */
+			J721E_WKUP_IOPAD(0x0018, PIN_OUTPUT, 0) /* MCU_RGMII1_TXC */
+			J721E_WKUP_IOPAD(0x001c, PIN_INPUT, 0) /* MCU_RGMII1_RXC */
 		>;
 	};
 
 	mcu_mdio_pins_default: mcu-mdio1-pins-default {
 		pinctrl-single,pins = <
-			J721E_WKUP_IOPAD(0x009c, PIN_OUTPUT, 0) /* (L1) MCU_MDIO0_MDC */
-			J721E_WKUP_IOPAD(0x0098, PIN_INPUT, 0) /* (L4) MCU_MDIO0_MDIO */
+			J721E_WKUP_IOPAD(0x0034, PIN_OUTPUT, 0) /* (L1) MCU_MDIO0_MDC */
+			J721E_WKUP_IOPAD(0x0030, PIN_INPUT, 0) /* (L4) MCU_MDIO0_MDIO */
 		>;
 	};
 };
diff --git a/kernel/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi b/kernel/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
index eb2a78a..7f252cc 100644
--- a/kernel/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
+++ b/kernel/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
@@ -56,7 +56,34 @@
 	wkup_pmx0: pinctrl@4301c000 {
 		compatible = "pinctrl-single";
 		/* Proxy 0 addressing */
-		reg = <0x00 0x4301c000 0x00 0x178>;
+		reg = <0x00 0x4301c000 0x00 0x34>;
+		#pinctrl-cells = <1>;
+		pinctrl-single,register-width = <32>;
+		pinctrl-single,function-mask = <0xffffffff>;
+	};
+
+	wkup_pmx1: pinctrl@0x4301c038 {
+		compatible = "pinctrl-single";
+		/* Proxy 0 addressing */
+		reg = <0x00 0x4301c038 0x00 0x8>;
+		#pinctrl-cells = <1>;
+		pinctrl-single,register-width = <32>;
+		pinctrl-single,function-mask = <0xffffffff>;
+	};
+
+	wkup_pmx2: pinctrl@0x4301c068 {
+		compatible = "pinctrl-single";
+		/* Proxy 0 addressing */
+		reg = <0x00 0x4301c068 0x00 0xec>;
+		#pinctrl-cells = <1>;
+		pinctrl-single,register-width = <32>;
+		pinctrl-single,function-mask = <0xffffffff>;
+	};
+
+	wkup_pmx3: pinctrl@0x4301c174 {
+		compatible = "pinctrl-single";
+		/* Proxy 0 addressing */
+		reg = <0x00 0x4301c174 0x00 0x20>;
 		#pinctrl-cells = <1>;
 		pinctrl-single,register-width = <32>;
 		pinctrl-single,function-mask = <0xffffffff>;
diff --git a/kernel/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/kernel/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
index 0350ddf..691d73f 100644
--- a/kernel/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+++ b/kernel/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
@@ -367,7 +367,6 @@
 		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";
diff --git a/kernel/arch/arm64/configs/gki_defconfig b/kernel/arch/arm64/configs/gki_defconfig
index d6adcfb..e238ccd 100644
--- a/kernel/arch/arm64/configs/gki_defconfig
+++ b/kernel/arch/arm64/configs/gki_defconfig
@@ -245,7 +245,6 @@
 CONFIG_NET_SCH_FQ=y
 CONFIG_NET_SCH_INGRESS=y
 CONFIG_NET_CLS_BASIC=y
-CONFIG_NET_CLS_TCINDEX=y
 CONFIG_NET_CLS_FW=y
 CONFIG_NET_CLS_U32=y
 CONFIG_CLS_U32_MARK=y
@@ -373,6 +372,7 @@
 # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
 CONFIG_SERIAL_8250_CONSOLE=y
 # CONFIG_SERIAL_8250_EXAR is not set
+CONFIG_SERIAL_8250_NR_UARTS=32
 CONFIG_SERIAL_8250_RUNTIME_UARTS=0
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_SERIAL_AMBA_PL011=y
@@ -591,6 +591,8 @@
 CONFIG_PSTORE_PMSG=y
 CONFIG_PSTORE_RAM=y
 CONFIG_EROFS_FS=y
+CONFIG_EROFS_FS_PCPU_KTHREAD=y
+CONFIG_EROFS_FS_PCPU_KTHREAD_HIPRI=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=y
 CONFIG_NLS_CODEPAGE_775=y
diff --git a/kernel/arch/arm64/configs/px30_linux_defconfig b/kernel/arch/arm64/configs/px30_linux_defconfig
index a15667b..f831933 100644
--- a/kernel/arch/arm64/configs/px30_linux_defconfig
+++ b/kernel/arch/arm64/configs/px30_linux_defconfig
@@ -231,6 +231,7 @@
 # CONFIG_DVB_TUNER_DIB0070 is not set
 # CONFIG_DVB_TUNER_DIB0090 is not set
 CONFIG_DRM=y
+CONFIG_DRM_IGNORE_IOTCL_PERMIT=y
 CONFIG_DRM_LOAD_EDID_FIRMWARE=y
 CONFIG_DRM_ROCKCHIP=y
 CONFIG_ROCKCHIP_ANALOGIX_DP=y
@@ -319,10 +320,6 @@
 CONFIG_DMADEVICES=y
 CONFIG_PL330_DMA=y
 CONFIG_STAGING=y
-CONFIG_FIQ_DEBUGGER=y
-CONFIG_FIQ_DEBUGGER_NO_SLEEP=y
-CONFIG_FIQ_DEBUGGER_CONSOLE=y
-CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE=y
 CONFIG_COMMON_CLK_RK808=y
 CONFIG_COMMON_CLK_SCMI=y
 CONFIG_MAILBOX=y
@@ -337,6 +334,10 @@
 CONFIG_ROCKCHIP_PVTM=y
 CONFIG_ROCKCHIP_SUSPEND_MODE=y
 CONFIG_ROCKCHIP_SYSTEM_MONITOR=y
+CONFIG_FIQ_DEBUGGER=y
+CONFIG_FIQ_DEBUGGER_NO_SLEEP=y
+CONFIG_FIQ_DEBUGGER_CONSOLE=y
+CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE=y
 CONFIG_PM_DEVFREQ=y
 CONFIG_DEVFREQ_GOV_PERFORMANCE=y
 CONFIG_DEVFREQ_GOV_POWERSAVE=y
diff --git a/kernel/arch/arm64/configs/rk3308_linux_defconfig b/kernel/arch/arm64/configs/rk3308_linux_defconfig
index 789e609..c342592 100644
--- a/kernel/arch/arm64/configs/rk3308_linux_defconfig
+++ b/kernel/arch/arm64/configs/rk3308_linux_defconfig
@@ -2,9 +2,9 @@
 CONFIG_DEFAULT_HOSTNAME="localhost"
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
-CONFIG_FHANDLE=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_RD_BZIP2 is not set
@@ -17,14 +17,6 @@
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_PROFILING=y
-CONFIG_JUMP_LABEL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_RK_PARTITION is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 CONFIG_ARCH_ROCKCHIP=y
 # CONFIG_ARM64_ERRATUM_826319 is not set
 # CONFIG_ARM64_ERRATUM_827319 is not set
@@ -38,23 +30,17 @@
 # CONFIG_CAVIUM_ERRATUM_27456 is not set
 CONFIG_SCHED_MC=y
 CONFIG_NR_CPUS=4
-CONFIG_PREEMPT=y
 CONFIG_HZ_1000=y
-# CONFIG_SPARSEMEM_VMEMMAP is not set
-# CONFIG_COMPACTION is not set
-# CONFIG_BOUNCE is not set
-CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
 # CONFIG_UNMAP_KERNEL_AT_EL0 is not set
+CONFIG_COMPAT=y
 # CONFIG_ARM64_HW_AFDBM is not set
 # CONFIG_ARM64_PAN is not set
 # CONFIG_ARM64_UAO is not set
 # CONFIG_EFI is not set
-CONFIG_COMPAT=y
 CONFIG_PM_DEBUG=y
 CONFIG_PM_ADVANCED_DEBUG=y
 CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
 CONFIG_CPU_IDLE=y
-# CONFIG_CPU_IDLE_GOV_LADDER is not set
 CONFIG_ARM_CPUIDLE=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_STAT=y
@@ -64,29 +50,37 @@
 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_ARM_ROCKCHIP_CPUFREQ=y
+CONFIG_ROCKCHIP_SIP=y
+CONFIG_ARM64_CRYPTO=y
+CONFIG_CRYPTO_SHA1_ARM64_CE=y
+CONFIG_CRYPTO_SHA2_ARM64_CE=y
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
+CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_SPARSEMEM_VMEMMAP is not set
+# CONFIG_COMPACTION is not set
+# CONFIG_BOUNCE is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
 CONFIG_SYN_COOKIES=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_BEET is not set
 # CONFIG_IPV6_SIT is not set
-# CONFIG_ANDROID_PARANOID_NETWORK is not set
 CONFIG_BT=y
 CONFIG_BT_RFCOMM=y
 CONFIG_BT_RFCOMM_TTY=y
 CONFIG_BT_HIDP=y
 CONFIG_BT_HCIUART=y
 CONFIG_BT_HCIUART_H4=y
-CONFIG_BT_HCIUART_LL=y
 CONFIG_RFKILL=y
 CONFIG_RFKILL_RK=y
 CONFIG_DEVTMPFS=y
@@ -135,10 +129,7 @@
 # CONFIG_NET_VENDOR_XILINX is not set
 CONFIG_WL_ROCKCHIP=y
 CONFIG_WIFI_BUILD_MODULE=y
-# CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP is not set
 CONFIG_AP6XXX=m
-# CONFIG_RTL_WIRELESS_SOLUTION is not set
-# CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_ADC=y
 # CONFIG_KEYBOARD_ATKBD is not set
@@ -149,7 +140,6 @@
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_8250=y
 # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
 CONFIG_SERIAL_8250_CONSOLE=y
@@ -166,13 +156,10 @@
 CONFIG_SPI_SPIDEV=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_SYSCON_REBOOT_MODE=y
-CONFIG_POWER_AVS=y
-CONFIG_ROCKCHIP_IODOMAIN=y
 CONFIG_BATTERY_RK816=y
 # CONFIG_HWMON is not set
 CONFIG_THERMAL=y
 CONFIG_THERMAL_WRITABLE_TRIPS=y
-CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR=y
 CONFIG_THERMAL_GOV_USER_SPACE=y
 CONFIG_CPU_THERMAL=y
 CONFIG_DEVFREQ_THERMAL=y
@@ -187,13 +174,11 @@
 CONFIG_REGULATOR_RK808=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_DRM=y
+CONFIG_DRM_IGNORE_IOTCL_PERMIT=y
 CONFIG_DRM_ROCKCHIP=y
 CONFIG_ROCKCHIP_RGB=y
 CONFIG_DRM_PANEL_SIMPLE=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-# CONFIG_LCD_CLASS_DEVICE is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_GENERIC is not set
 CONFIG_BACKLIGHT_PWM=y
 CONFIG_SOUND=y
 CONFIG_SND=y
@@ -221,11 +206,10 @@
 CONFIG_USB_GADGET_DEBUG_FILES=y
 CONFIG_USB_GADGET_VBUS_DRAW=500
 CONFIG_USB_CONFIGFS=y
-CONFIG_USB_CONFIGFS_F_FS=y
 CONFIG_USB_CONFIGFS_UEVENT=y
+CONFIG_USB_CONFIGFS_F_FS=y
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=32
-# CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_NEW_LEDS=y
@@ -237,57 +221,46 @@
 CONFIG_LEDS_TRIGGER_ONESHOT=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
-CONFIG_LEDS_TRIGGER_MULTI_CTRL=y
 CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_RK_TIMER=y
 CONFIG_RTC_DRV_RK808=y
 CONFIG_DMADEVICES=y
 CONFIG_PL330_DMA=y
 CONFIG_STAGING=y
-# CONFIG_ANDROID_TIMED_OUTPUT is not set
+CONFIG_COMMON_CLK_RK808=y
+# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_RPMSG_ROCKCHIP_SOFTIRQ=y
+CONFIG_RPMSG_VIRTIO=y
+CONFIG_CPU_RK3308=y
+CONFIG_ROCKCHIP_AMP=y
+CONFIG_ROCKCHIP_CPUINFO=y
+CONFIG_ROCKCHIP_GRF=y
+CONFIG_ROCKCHIP_IODOMAIN=y
+CONFIG_ROCKCHIP_PM_DOMAINS=y
+CONFIG_ROCKCHIP_PVTM=y
+CONFIG_ROCKCHIP_SUSPEND_MODE=y
 CONFIG_FIQ_DEBUGGER=y
 CONFIG_FIQ_DEBUGGER_NO_SLEEP=y
 CONFIG_FIQ_DEBUGGER_CONSOLE=y
 CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE=y
 CONFIG_FIQ_DEBUGGER_TRUST_ZONE=y
 CONFIG_RK_CONSOLE_THREAD=y
-CONFIG_COMMON_CLK_RK808=y
-# CONFIG_COMMON_CLK_XGENE is not set
-# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set
-# CONFIG_IOMMU_SUPPORT is not set
-# CONFIG_CPU_PX30 is not set
-CONFIG_CPU_RK3308=y
-# CONFIG_CPU_RK3328 is not set
-# CONFIG_CPU_RK3368 is not set
-# CONFIG_CPU_RK3399 is not set
-CONFIG_ROCKCHIP_AMP=y
-CONFIG_ROCKCHIP_CPUINFO=y
-CONFIG_ROCKCHIP_GRF=y
-CONFIG_ROCKCHIP_PM_DOMAINS=y
-CONFIG_ROCKCHIP_PVTM=y
-CONFIG_ROCKCHIP_SUSPEND_MODE=y
 CONFIG_PM_DEVFREQ=y
 CONFIG_DEVFREQ_GOV_USERSPACE=y
 CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ=y
-CONFIG_PM_DEVFREQ_EVENT=y
 CONFIG_DEVFREQ_EVENT_ROCKCHIP_NOCP=y
 CONFIG_EXTCON=y
 CONFIG_IIO=y
-CONFIG_IIO_BUFFER=y
-CONFIG_IIO_KFIFO_BUF=y
-CONFIG_IIO_TRIGGER=y
 CONFIG_ROCKCHIP_SARADC=y
 CONFIG_PWM=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_PHY_ROCKCHIP_INNO_USB2=y
 CONFIG_ANDROID=y
-CONFIG_NVMEM=y
 CONFIG_ROCKCHIP_OTP=y
 CONFIG_RK_FLASH=y
 CONFIG_RK_NANDC_NAND=y
 CONFIG_RK_SFC_NAND=y
 CONFIG_RK_SFC_NOR=y
-CONFIG_ROCKCHIP_SIP=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT4_FS=m
 # CONFIG_DNOTIFY is not set
@@ -301,32 +274,16 @@
 CONFIG_PSTORE_CONSOLE=y
 CONFIG_PSTORE_RAM=y
 # CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_HW is not set
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_FS=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0
-CONFIG_LOCKUP_DETECTOR=y
-CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
-CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
+CONFIG_DEBUG_FS=y
 CONFIG_PANIC_ON_OOPS=y
 CONFIG_PANIC_TIMEOUT=1
 # CONFIG_SCHED_DEBUG is not set
 # CONFIG_DEBUG_PREEMPT is not set
 CONFIG_RCU_CPU_STALL_TIMEOUT=60
 # CONFIG_FTRACE is not set
-CONFIG_STRICT_DEVMEM=y
-CONFIG_DEBUG_SET_MODULE_RONX=y
-# CONFIG_CRYPTO_ECHAINIV is not set
-CONFIG_CRYPTO_CRC32C=y
-# CONFIG_CRYPTO_HW is not set
-CONFIG_ARM64_CRYPTO=y
-CONFIG_CRYPTO_SHA1_ARM64_CE=y
-CONFIG_CRYPTO_SHA2_ARM64_CE=y
-CONFIG_CRYPTO_GHASH_ARM64_CE=y
-CONFIG_CRYPTO_POLY_HASH_ARM64_CE=y
-CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
-CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
-CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
-CONFIG_CRYPTO_CRC32_ARM64=y
diff --git a/kernel/arch/arm64/configs/rk3308bs_mipi_display.config b/kernel/arch/arm64/configs/rk3308bs_mipi_display.config
index 24498f0..8a53a10 100644
--- a/kernel/arch/arm64/configs/rk3308bs_mipi_display.config
+++ b/kernel/arch/arm64/configs/rk3308bs_mipi_display.config
@@ -86,6 +86,7 @@
 # CONFIG_TOUCHSCREEN_GSL3673_800X1280 is not set
 # CONFIG_TOUCHSCREEN_GSLX680_PAD is not set
 CONFIG_TOUCHSCREEN_GT1X=y
+CONFIG_TOUCHSCREEN_GT9XX=y
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
 # CONFIG_TOUCHSCREEN_HIDEEP is not set
diff --git a/kernel/arch/arm64/configs/rockchip_defconfig b/kernel/arch/arm64/configs/rockchip_defconfig
index 2e6450c..28340b4 100644
--- a/kernel/arch/arm64/configs/rockchip_defconfig
+++ b/kernel/arch/arm64/configs/rockchip_defconfig
@@ -9,6 +9,10 @@
 CONFIG_TASK_XACCT=y
 CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_PSI=y
+CONFIG_RCU_EXPERT=y
+CONFIG_RCU_FAST_NO_HZ=y
+CONFIG_RCU_BOOST=y
+CONFIG_RCU_NOCB_CPU=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_IKHEADERS=m
@@ -475,6 +479,7 @@
 CONFIG_LSM330_ACC=y
 CONFIG_BMA2XX_ACC=y
 CONFIG_GS_DA223=y
+CONFIG_ICM4260X_ACC=y
 CONFIG_COMPASS_DEVICE=y
 CONFIG_COMPASS_AK8975=y
 CONFIG_COMPASS_AK8963=y
@@ -485,6 +490,7 @@
 CONFIG_GYRO_MPU6500=y
 CONFIG_GYRO_MPU6880=y
 CONFIG_GYRO_LSM330=y
+CONFIG_GYRO_ICM4260X=y
 CONFIG_LIGHT_DEVICE=y
 CONFIG_LS_CM3217=y
 CONFIG_LS_CM3218=y
@@ -520,6 +526,7 @@
 CONFIG_PINCTRL_RK805=y
 CONFIG_PINCTRL_RK806=y
 CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_SYSCON=y
 CONFIG_POWER_RESET_GPIO=y
 CONFIG_SYSCON_REBOOT_MODE=y
 CONFIG_TEST_POWER=y
@@ -552,6 +559,7 @@
 CONFIG_MFD_RK618=y
 CONFIG_MFD_RK628=y
 CONFIG_MFD_RK630_I2C=y
+CONFIG_MFD_RK806_I2C=y
 CONFIG_MFD_RK806_SPI=y
 CONFIG_MFD_RK808=y
 CONFIG_MFD_RKX110_X120=y
@@ -679,6 +687,7 @@
 CONFIG_ROCKCHIP_MPP_JPGDEC=y
 CONFIG_ROCKCHIP_MPP_AV1DEC=y
 CONFIG_ROCKCHIP_MPP_VDPP=y
+CONFIG_ROCKCHIP_VIDEO_TUNNEL=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_DYNAMIC_MINORS=y
@@ -690,6 +699,7 @@
 CONFIG_SND_USB_AUDIO=y
 CONFIG_SND_SOC=y
 CONFIG_SND_SOC_ROCKCHIP=y
+CONFIG_SND_SOC_ROCKCHIP_DLP_PCM=y
 CONFIG_SND_SOC_ROCKCHIP_I2S=y
 CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=y
 CONFIG_SND_SOC_ROCKCHIP_I2S_TDM_MULTI_LANES=y
@@ -716,6 +726,7 @@
 CONFIG_SND_SOC_RK817=y
 CONFIG_SND_SOC_RK_CODEC_DIGITAL=y
 CONFIG_SND_SOC_RK_DSM=y
+CONFIG_SND_SOC_ROCKCHIP_SPI_CODEC=y
 CONFIG_SND_SOC_RT5640=y
 CONFIG_SND_SOC_RT5651=y
 CONFIG_SND_SOC_SPDIF=y
@@ -892,6 +903,7 @@
 CONFIG_CPU_RK3568=y
 CONFIG_CPU_RK3588=y
 CONFIG_ROCKCHIP_CPUINFO=y
+CONFIG_ROCKCHIP_CSU=y
 CONFIG_ROCKCHIP_GRF=y
 CONFIG_ROCKCHIP_IODOMAIN=y
 CONFIG_ROCKCHIP_IPA=y
diff --git a/kernel/arch/arm64/configs/rockchip_gki.config b/kernel/arch/arm64/configs/rockchip_gki.config
index 160bfa2..d1dd1e1 100644
--- a/kernel/arch/arm64/configs/rockchip_gki.config
+++ b/kernel/arch/arm64/configs/rockchip_gki.config
@@ -85,6 +85,7 @@
 CONFIG_GS_SC7A30=m
 CONFIG_GYROSCOPE_DEVICE=m
 CONFIG_GYRO_EWTSA=m
+CONFIG_GYRO_ICM4260X=m
 CONFIG_GYRO_L3G20D=m
 CONFIG_GYRO_L3G4200D=m
 CONFIG_GYRO_LSM330=m
@@ -139,6 +140,7 @@
 CONFIG_I2C_GPIO=m
 CONFIG_I2C_HID=m
 CONFIG_I2C_RK3X=m
+CONFIG_ICM4260X_ACC=m
 CONFIG_IEP=m
 CONFIG_IIO_BUFFER_CB=m
 CONFIG_INPUT_RK805_PWRKEY=m
diff --git a/kernel/arch/arm64/configs/rockchip_linux_pcie_ep.config b/kernel/arch/arm64/configs/rockchip_linux_pcie_ep.config
new file mode 100644
index 0000000..409075c
--- /dev/null
+++ b/kernel/arch/arm64/configs/rockchip_linux_pcie_ep.config
@@ -0,0 +1,7 @@
+CONFIG_HUGETLBFS=y
+CONFIG_PCIE_DW_ROCKCHIP_EP=y
+CONFIG_PCIE_FUNC_RKEP=y
+CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y
+# CONFIG_CGROUP_HUGETLB is not set
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_PCIE_FUNC_RKEP_USERPAGES is not set
diff --git a/kernel/arch/arm64/include/asm/atomic_ll_sc.h b/kernel/arch/arm64/include/asm/atomic_ll_sc.h
index 13869b7..abd302e 100644
--- a/kernel/arch/arm64/include/asm/atomic_ll_sc.h
+++ b/kernel/arch/arm64/include/asm/atomic_ll_sc.h
@@ -12,19 +12,6 @@
 
 #include <linux/stringify.h>
 
-#ifdef CONFIG_ARM64_LSE_ATOMICS
-#define __LL_SC_FALLBACK(asm_ops)					\
-"	b	3f\n"							\
-"	.subsection	1\n"						\
-"3:\n"									\
-asm_ops "\n"								\
-"	b	4f\n"							\
-"	.previous\n"							\
-"4:\n"
-#else
-#define __LL_SC_FALLBACK(asm_ops) asm_ops
-#endif
-
 #ifndef CONFIG_CC_HAS_K_CONSTRAINT
 #define K
 #endif
@@ -43,12 +30,11 @@
 	int result;							\
 									\
 	asm volatile("// atomic_" #op "\n"				\
-	__LL_SC_FALLBACK(						\
-"	prfm	pstl1strm, %2\n"					\
-"1:	ldxr	%w0, %2\n"						\
-"	" #asm_op "	%w0, %w0, %w3\n"				\
-"	stxr	%w1, %w0, %2\n"						\
-"	cbnz	%w1, 1b\n")						\
+	"	prfm	pstl1strm, %2\n"				\
+	"1:	ldxr	%w0, %2\n"					\
+	"	" #asm_op "	%w0, %w0, %w3\n"			\
+	"	stxr	%w1, %w0, %2\n"					\
+	"	cbnz	%w1, 1b\n"					\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
 	: __stringify(constraint) "r" (i));				\
 }
@@ -61,13 +47,12 @@
 	int result;							\
 									\
 	asm volatile("// atomic_" #op "_return" #name "\n"		\
-	__LL_SC_FALLBACK(						\
-"	prfm	pstl1strm, %2\n"					\
-"1:	ld" #acq "xr	%w0, %2\n"					\
-"	" #asm_op "	%w0, %w0, %w3\n"				\
-"	st" #rel "xr	%w1, %w0, %2\n"					\
-"	cbnz	%w1, 1b\n"						\
-"	" #mb )								\
+	"	prfm	pstl1strm, %2\n"				\
+	"1:	ld" #acq "xr	%w0, %2\n"				\
+	"	" #asm_op "	%w0, %w0, %w3\n"			\
+	"	st" #rel "xr	%w1, %w0, %2\n"				\
+	"	cbnz	%w1, 1b\n"					\
+	"	" #mb							\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
 	: __stringify(constraint) "r" (i)				\
 	: cl);								\
@@ -83,13 +68,12 @@
 	int val, result;						\
 									\
 	asm volatile("// atomic_fetch_" #op #name "\n"			\
-	__LL_SC_FALLBACK(						\
-"	prfm	pstl1strm, %3\n"					\
-"1:	ld" #acq "xr	%w0, %3\n"					\
-"	" #asm_op "	%w1, %w0, %w4\n"				\
-"	st" #rel "xr	%w2, %w1, %3\n"					\
-"	cbnz	%w2, 1b\n"						\
-"	" #mb )								\
+	"	prfm	pstl1strm, %3\n"				\
+	"1:	ld" #acq "xr	%w0, %3\n"				\
+	"	" #asm_op "	%w1, %w0, %w4\n"			\
+	"	st" #rel "xr	%w2, %w1, %3\n"				\
+	"	cbnz	%w2, 1b\n"					\
+	"	" #mb							\
 	: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter)	\
 	: __stringify(constraint) "r" (i)				\
 	: cl);								\
@@ -142,12 +126,11 @@
 	unsigned long tmp;						\
 									\
 	asm volatile("// atomic64_" #op "\n"				\
-	__LL_SC_FALLBACK(						\
-"	prfm	pstl1strm, %2\n"					\
-"1:	ldxr	%0, %2\n"						\
-"	" #asm_op "	%0, %0, %3\n"					\
-"	stxr	%w1, %0, %2\n"						\
-"	cbnz	%w1, 1b")						\
+	"	prfm	pstl1strm, %2\n"				\
+	"1:	ldxr	%0, %2\n"					\
+	"	" #asm_op "	%0, %0, %3\n"				\
+	"	stxr	%w1, %0, %2\n"					\
+	"	cbnz	%w1, 1b"					\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
 	: __stringify(constraint) "r" (i));				\
 }
@@ -160,13 +143,12 @@
 	unsigned long tmp;						\
 									\
 	asm volatile("// atomic64_" #op "_return" #name "\n"		\
-	__LL_SC_FALLBACK(						\
-"	prfm	pstl1strm, %2\n"					\
-"1:	ld" #acq "xr	%0, %2\n"					\
-"	" #asm_op "	%0, %0, %3\n"					\
-"	st" #rel "xr	%w1, %0, %2\n"					\
-"	cbnz	%w1, 1b\n"						\
-"	" #mb )								\
+	"	prfm	pstl1strm, %2\n"				\
+	"1:	ld" #acq "xr	%0, %2\n"				\
+	"	" #asm_op "	%0, %0, %3\n"				\
+	"	st" #rel "xr	%w1, %0, %2\n"				\
+	"	cbnz	%w1, 1b\n"					\
+	"	" #mb							\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
 	: __stringify(constraint) "r" (i)				\
 	: cl);								\
@@ -176,19 +158,18 @@
 
 #define ATOMIC64_FETCH_OP(name, mb, acq, rel, cl, op, asm_op, constraint)\
 static inline long							\
-__ll_sc_atomic64_fetch_##op##name(s64 i, atomic64_t *v)		\
+__ll_sc_atomic64_fetch_##op##name(s64 i, atomic64_t *v)			\
 {									\
 	s64 result, val;						\
 	unsigned long tmp;						\
 									\
 	asm volatile("// atomic64_fetch_" #op #name "\n"		\
-	__LL_SC_FALLBACK(						\
-"	prfm	pstl1strm, %3\n"					\
-"1:	ld" #acq "xr	%0, %3\n"					\
-"	" #asm_op "	%1, %0, %4\n"					\
-"	st" #rel "xr	%w2, %1, %3\n"					\
-"	cbnz	%w2, 1b\n"						\
-"	" #mb )								\
+	"	prfm	pstl1strm, %3\n"				\
+	"1:	ld" #acq "xr	%0, %3\n"				\
+	"	" #asm_op "	%1, %0, %4\n"				\
+	"	st" #rel "xr	%w2, %1, %3\n"				\
+	"	cbnz	%w2, 1b\n"					\
+	"	" #mb							\
 	: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter)	\
 	: __stringify(constraint) "r" (i)				\
 	: cl);								\
@@ -240,15 +221,14 @@
 	unsigned long tmp;
 
 	asm volatile("// atomic64_dec_if_positive\n"
-	__LL_SC_FALLBACK(
-"	prfm	pstl1strm, %2\n"
-"1:	ldxr	%0, %2\n"
-"	subs	%0, %0, #1\n"
-"	b.lt	2f\n"
-"	stlxr	%w1, %0, %2\n"
-"	cbnz	%w1, 1b\n"
-"	dmb	ish\n"
-"2:")
+	"	prfm	pstl1strm, %2\n"
+	"1:	ldxr	%0, %2\n"
+	"	subs	%0, %0, #1\n"
+	"	b.lt	2f\n"
+	"	stlxr	%w1, %0, %2\n"
+	"	cbnz	%w1, 1b\n"
+	"	dmb	ish\n"
+	"2:"
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)
 	:
 	: "cc", "memory");
@@ -274,7 +254,6 @@
 		old = (u##sz)old;					\
 									\
 	asm volatile(							\
-	__LL_SC_FALLBACK(						\
 	"	prfm	pstl1strm, %[v]\n"				\
 	"1:	ld" #acq "xr" #sfx "\t%" #w "[oldval], %[v]\n"		\
 	"	eor	%" #w "[tmp], %" #w "[oldval], %" #w "[old]\n"	\
@@ -282,7 +261,7 @@
 	"	st" #rel "xr" #sfx "\t%w[tmp], %" #w "[new], %[v]\n"	\
 	"	cbnz	%w[tmp], 1b\n"					\
 	"	" #mb "\n"						\
-	"2:")								\
+	"2:"								\
 	: [tmp] "=&r" (tmp), [oldval] "=&r" (oldval),			\
 	  [v] "+Q" (*(u##sz *)ptr)					\
 	: [old] __stringify(constraint) "r" (old), [new] "r" (new)	\
@@ -326,7 +305,6 @@
 	unsigned long tmp, ret;						\
 									\
 	asm volatile("// __cmpxchg_double" #name "\n"			\
-	__LL_SC_FALLBACK(						\
 	"	prfm	pstl1strm, %2\n"				\
 	"1:	ldxp	%0, %1, %2\n"					\
 	"	eor	%0, %0, %3\n"					\
@@ -336,8 +314,8 @@
 	"	st" #rel "xp	%w0, %5, %6, %2\n"			\
 	"	cbnz	%w0, 1b\n"					\
 	"	" #mb "\n"						\
-	"2:")								\
-	: "=&r" (tmp), "=&r" (ret), "+Q" (*(unsigned long *)ptr)	\
+	"2:"								\
+	: "=&r" (tmp), "=&r" (ret), "+Q" (*(__uint128_t *)ptr)		\
 	: "r" (old1), "r" (old2), "r" (new1), "r" (new2)		\
 	: cl);								\
 									\
diff --git a/kernel/arch/arm64/include/asm/atomic_lse.h b/kernel/arch/arm64/include/asm/atomic_lse.h
index da3280f..28e9611 100644
--- a/kernel/arch/arm64/include/asm/atomic_lse.h
+++ b/kernel/arch/arm64/include/asm/atomic_lse.h
@@ -11,11 +11,11 @@
 #define __ASM_ATOMIC_LSE_H
 
 #define ATOMIC_OP(op, asm_op)						\
-static inline void __lse_atomic_##op(int i, atomic_t *v)			\
+static inline void __lse_atomic_##op(int i, atomic_t *v)		\
 {									\
 	asm volatile(							\
 	__LSE_PREAMBLE							\
-"	" #asm_op "	%w[i], %[v]\n"					\
+	"	" #asm_op "	%w[i], %[v]\n"				\
 	: [i] "+r" (i), [v] "+Q" (v->counter)				\
 	: "r" (v));							\
 }
@@ -32,7 +32,7 @@
 {									\
 	asm volatile(							\
 	__LSE_PREAMBLE							\
-"	" #asm_op #mb "	%w[i], %w[i], %[v]"				\
+	"	" #asm_op #mb "	%w[i], %w[i], %[v]"			\
 	: [i] "+r" (i), [v] "+Q" (v->counter)				\
 	: "r" (v)							\
 	: cl);								\
@@ -130,7 +130,7 @@
 	"	add	%w[i], %w[i], %w[tmp]"				\
 	: [i] "+&r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)	\
 	: "r" (v)							\
-	: cl);							\
+	: cl);								\
 									\
 	return i;							\
 }
@@ -168,7 +168,7 @@
 {									\
 	asm volatile(							\
 	__LSE_PREAMBLE							\
-"	" #asm_op "	%[i], %[v]\n"					\
+	"	" #asm_op "	%[i], %[v]\n"				\
 	: [i] "+r" (i), [v] "+Q" (v->counter)				\
 	: "r" (v));							\
 }
@@ -185,7 +185,7 @@
 {									\
 	asm volatile(							\
 	__LSE_PREAMBLE							\
-"	" #asm_op #mb "	%[i], %[i], %[v]"				\
+	"	" #asm_op #mb "	%[i], %[i], %[v]"			\
 	: [i] "+r" (i), [v] "+Q" (v->counter)				\
 	: "r" (v)							\
 	: cl);								\
@@ -272,7 +272,7 @@
 }
 
 #define ATOMIC64_OP_SUB_RETURN(name, mb, cl...)				\
-static inline long __lse_atomic64_sub_return##name(s64 i, atomic64_t *v)	\
+static inline long __lse_atomic64_sub_return##name(s64 i, atomic64_t *v)\
 {									\
 	unsigned long tmp;						\
 									\
@@ -403,7 +403,7 @@
 	"	eor	%[old2], %[old2], %[oldval2]\n"			\
 	"	orr	%[old1], %[old1], %[old2]"			\
 	: [old1] "+&r" (x0), [old2] "+&r" (x1),				\
-	  [v] "+Q" (*(unsigned long *)ptr)				\
+	  [v] "+Q" (*(__uint128_t *)ptr)				\
 	: [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4),		\
 	  [oldval1] "r" (oldval1), [oldval2] "r" (oldval2)		\
 	: cl);								\
diff --git a/kernel/arch/arm64/include/asm/cputype.h b/kernel/arch/arm64/include/asm/cputype.h
index 9cf5d95..c2a1ccd 100644
--- a/kernel/arch/arm64/include/asm/cputype.h
+++ b/kernel/arch/arm64/include/asm/cputype.h
@@ -79,6 +79,7 @@
 #define ARM_CPU_PART_CORTEX_A78AE	0xD42
 #define ARM_CPU_PART_CORTEX_X1		0xD44
 #define ARM_CPU_PART_CORTEX_A510	0xD46
+#define ARM_CPU_PART_CORTEX_A520	0xD80
 #define ARM_CPU_PART_CORTEX_A710	0xD47
 #define ARM_CPU_PART_CORTEX_X2		0xD48
 #define ARM_CPU_PART_NEOVERSE_N2	0xD49
@@ -130,6 +131,7 @@
 #define MIDR_CORTEX_A78AE	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78AE)
 #define MIDR_CORTEX_X1	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
 #define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
+#define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520)
 #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
 #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
 #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
diff --git a/kernel/arch/arm64/include/asm/debug-monitors.h b/kernel/arch/arm64/include/asm/debug-monitors.h
index 657c921..c16ed5b 100644
--- a/kernel/arch/arm64/include/asm/debug-monitors.h
+++ b/kernel/arch/arm64/include/asm/debug-monitors.h
@@ -116,6 +116,7 @@
 void kernel_enable_single_step(struct pt_regs *regs);
 void kernel_disable_single_step(void);
 int kernel_active_single_step(void);
+void kernel_rewind_single_step(struct pt_regs *regs);
 
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 int reinstall_suspended_bps(struct pt_regs *regs);
diff --git a/kernel/arch/arm64/include/asm/efi.h b/kernel/arch/arm64/include/asm/efi.h
index 16892f0..538b6a1 100644
--- a/kernel/arch/arm64/include/asm/efi.h
+++ b/kernel/arch/arm64/include/asm/efi.h
@@ -25,7 +25,7 @@
 ({									\
 	efi_virtmap_load();						\
 	__efi_fpsimd_begin();						\
-	spin_lock(&efi_rt_lock);					\
+	raw_spin_lock(&efi_rt_lock);					\
 })
 
 #define arch_efi_call_virt(p, f, args...)				\
@@ -37,12 +37,12 @@
 
 #define arch_efi_call_virt_teardown()					\
 ({									\
-	spin_unlock(&efi_rt_lock);					\
+	raw_spin_unlock(&efi_rt_lock);					\
 	__efi_fpsimd_end();						\
 	efi_virtmap_unload();						\
 })
 
-extern spinlock_t efi_rt_lock;
+extern raw_spinlock_t efi_rt_lock;
 efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...);
 
 #define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT)
diff --git a/kernel/arch/arm64/include/asm/exception.h b/kernel/arch/arm64/include/asm/exception.h
index 7853739..ad45911 100644
--- a/kernel/arch/arm64/include/asm/exception.h
+++ b/kernel/arch/arm64/include/asm/exception.h
@@ -8,16 +8,11 @@
 #define __ASM_EXCEPTION_H
 
 #include <asm/esr.h>
-#include <asm/kprobes.h>
 #include <asm/ptrace.h>
 
 #include <linux/interrupt.h>
 
-#ifdef CONFIG_FUNCTION_GRAPH_TRACER
 #define __exception_irq_entry	__irq_entry
-#else
-#define __exception_irq_entry	__kprobes
-#endif
 
 static inline u32 disr_to_esr(u64 disr)
 {
diff --git a/kernel/arch/arm64/include/asm/kvm_emulate.h b/kernel/arch/arm64/include/asm/kvm_emulate.h
index 01b9857..f47d6fa 100644
--- a/kernel/arch/arm64/include/asm/kvm_emulate.h
+++ b/kernel/arch/arm64/include/asm/kvm_emulate.h
@@ -363,8 +363,26 @@
 
 static inline bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
 {
-	if (kvm_vcpu_abt_iss1tw(vcpu))
-		return true;
+	if (kvm_vcpu_abt_iss1tw(vcpu)) {
+		/*
+		 * Only a permission fault on a S1PTW should be
+		 * considered as a write. Otherwise, page tables baked
+		 * in a read-only memslot will result in an exception
+		 * being delivered in the guest.
+		 *
+		 * The drawback is that we end-up faulting twice if the
+		 * guest is using any of HW AF/DB: a translation fault
+		 * to map the page containing the PT (read only at
+		 * first), then a permission fault to allow the flags
+		 * to be set.
+		 */
+		switch (kvm_vcpu_trap_get_fault_type(vcpu)) {
+		case ESR_ELx_FSC_PERM:
+			return true;
+		default:
+			return false;
+		}
+	}
 
 	if (kvm_vcpu_trap_is_iabt(vcpu))
 		return false;
diff --git a/kernel/arch/arm64/include/asm/kvm_host.h b/kernel/arch/arm64/include/asm/kvm_host.h
index b7fa629..b714f04 100644
--- a/kernel/arch/arm64/include/asm/kvm_host.h
+++ b/kernel/arch/arm64/include/asm/kvm_host.h
@@ -58,6 +58,7 @@
 enum kvm_mode {
 	KVM_MODE_DEFAULT,
 	KVM_MODE_PROTECTED,
+	KVM_MODE_NONE,
 };
 enum kvm_mode kvm_get_mode(void);
 
diff --git a/kernel/arch/arm64/include/asm/mte.h b/kernel/arch/arm64/include/asm/mte.h
index c0857e6..b63efcf 100644
--- a/kernel/arch/arm64/include/asm/mte.h
+++ b/kernel/arch/arm64/include/asm/mte.h
@@ -40,7 +40,9 @@
 void mte_copy_page_tags(void *kto, const void *kfrom);
 void mte_thread_init_user(void);
 void mte_thread_switch(struct task_struct *next);
+void mte_cpu_setup(void);
 void mte_suspend_enter(void);
+void mte_suspend_exit(void);
 long set_mte_ctrl(struct task_struct *task, unsigned long arg);
 long get_mte_ctrl(struct task_struct *task);
 int mte_ptrace_copy_tags(struct task_struct *child, long request,
@@ -69,6 +71,9 @@
 static inline void mte_suspend_enter(void)
 {
 }
+static inline void mte_suspend_exit(void)
+{
+}
 static inline long set_mte_ctrl(struct task_struct *task, unsigned long arg)
 {
 	return 0;
diff --git a/kernel/arch/arm64/include/asm/pgtable.h b/kernel/arch/arm64/include/asm/pgtable.h
index 35fe1ca..44070d0 100644
--- a/kernel/arch/arm64/include/asm/pgtable.h
+++ b/kernel/arch/arm64/include/asm/pgtable.h
@@ -650,9 +650,9 @@
 	return __pud_to_phys(pud);
 }
 
-static inline unsigned long pud_page_vaddr(pud_t pud)
+static inline pmd_t *pud_pgtable(pud_t pud)
 {
-	return (unsigned long)__va(pud_page_paddr(pud));
+	return (pmd_t *)__va(pud_page_paddr(pud));
 }
 
 /* Find an entry in the second-level page table. */
@@ -711,9 +711,9 @@
 	return __p4d_to_phys(p4d);
 }
 
-static inline unsigned long p4d_page_vaddr(p4d_t p4d)
+static inline pud_t *p4d_pgtable(p4d_t p4d)
 {
-	return (unsigned long)__va(p4d_page_paddr(p4d));
+	return (pud_t *)__va(p4d_page_paddr(p4d));
 }
 
 /* Find an entry in the frst-level page table. */
diff --git a/kernel/arch/arm64/include/asm/processor.h b/kernel/arch/arm64/include/asm/processor.h
index a01d40f..3d1df37 100644
--- a/kernel/arch/arm64/include/asm/processor.h
+++ b/kernel/arch/arm64/include/asm/processor.h
@@ -243,13 +243,13 @@
 }
 #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;
diff --git a/kernel/arch/arm64/include/asm/scs.h b/kernel/arch/arm64/include/asm/scs.h
index eaa2cd9..7155055 100644
--- a/kernel/arch/arm64/include/asm/scs.h
+++ b/kernel/arch/arm64/include/asm/scs.h
@@ -9,15 +9,16 @@
 #ifdef CONFIG_SHADOW_CALL_STACK
 	scs_sp	.req	x18
 
-	.macro scs_load tsk, tmp
-	ldr	scs_sp, [\tsk, #TSK_TI_SCS_SP]
+	.macro scs_load_current
+	get_current_task scs_sp
+	ldr	scs_sp, [scs_sp, #TSK_TI_SCS_SP]
 	.endm
 
 	.macro scs_save tsk, tmp
 	str	scs_sp, [\tsk, #TSK_TI_SCS_SP]
 	.endm
 #else
-	.macro scs_load tsk, tmp
+	.macro scs_load_current
 	.endm
 
 	.macro scs_save tsk, tmp
diff --git a/kernel/arch/arm64/include/asm/sdei.h b/kernel/arch/arm64/include/asm/sdei.h
index 63e0b92..5882c0e 100644
--- a/kernel/arch/arm64/include/asm/sdei.h
+++ b/kernel/arch/arm64/include/asm/sdei.h
@@ -17,6 +17,9 @@
 
 #include <asm/virt.h>
 
+DECLARE_PER_CPU(struct sdei_registered_event *, sdei_active_normal_event);
+DECLARE_PER_CPU(struct sdei_registered_event *, sdei_active_critical_event);
+
 extern unsigned long sdei_exit_mode;
 
 /* Software Delegated Exception entry point from firmware*/
@@ -29,6 +32,9 @@
 						   unsigned long pc,
 						   unsigned long pstate);
 
+/* Abort a running handler. Context is discarded. */
+void __sdei_handler_abort(void);
+
 /*
  * The above entry point does the minimum to call C code. This function does
  * anything else, before calling the driver.
diff --git a/kernel/arch/arm64/include/asm/sysreg.h b/kernel/arch/arm64/include/asm/sysreg.h
index b242c81..d0995ee 100644
--- a/kernel/arch/arm64/include/asm/sysreg.h
+++ b/kernel/arch/arm64/include/asm/sysreg.h
@@ -109,8 +109,14 @@
 #define SB_BARRIER_INSN			__SYS_BARRIER_INSN(0, 7, 31)
 
 #define SYS_DC_ISW			sys_insn(1, 0, 7, 6, 2)
+#define SYS_DC_IGSW			sys_insn(1, 0, 7, 6, 4)
+#define SYS_DC_IGDSW			sys_insn(1, 0, 7, 6, 6)
 #define SYS_DC_CSW			sys_insn(1, 0, 7, 10, 2)
+#define SYS_DC_CGSW			sys_insn(1, 0, 7, 10, 4)
+#define SYS_DC_CGDSW			sys_insn(1, 0, 7, 10, 6)
 #define SYS_DC_CISW			sys_insn(1, 0, 7, 14, 2)
+#define SYS_DC_CIGSW			sys_insn(1, 0, 7, 14, 4)
+#define SYS_DC_CIGDSW			sys_insn(1, 0, 7, 14, 6)
 
 /*
  * System registers, organised loosely by encoding but grouped together
diff --git a/kernel/arch/arm64/kernel/cpufeature.c b/kernel/arch/arm64/kernel/cpufeature.c
index 4be4d54..0c17b26 100644
--- a/kernel/arch/arm64/kernel/cpufeature.c
+++ b/kernel/arch/arm64/kernel/cpufeature.c
@@ -1870,7 +1870,8 @@
 static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
 {
 	sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ATA | SCTLR_EL1_ATA0);
-	isb();
+
+	mte_cpu_setup();
 
 	/*
 	 * Clear the tags in the zero page. This needs to be done via the
diff --git a/kernel/arch/arm64/kernel/debug-monitors.c b/kernel/arch/arm64/kernel/debug-monitors.c
index d7f904c..f40c51d 100644
--- a/kernel/arch/arm64/kernel/debug-monitors.c
+++ b/kernel/arch/arm64/kernel/debug-monitors.c
@@ -439,6 +439,11 @@
 }
 NOKPROBE_SYMBOL(kernel_active_single_step);
 
+void kernel_rewind_single_step(struct pt_regs *regs)
+{
+	set_regs_spsr_ss(regs);
+}
+
 /* ptrace API */
 void user_enable_single_step(struct task_struct *task)
 {
diff --git a/kernel/arch/arm64/kernel/efi.c b/kernel/arch/arm64/kernel/efi.c
index 72f432d..3ee3b3d 100644
--- a/kernel/arch/arm64/kernel/efi.c
+++ b/kernel/arch/arm64/kernel/efi.c
@@ -144,7 +144,7 @@
 	return s;
 }
 
-DEFINE_SPINLOCK(efi_rt_lock);
+DEFINE_RAW_SPINLOCK(efi_rt_lock);
 
 asmlinkage u64 *efi_rt_stack_top __ro_after_init;
 
diff --git a/kernel/arch/arm64/kernel/entry.S b/kernel/arch/arm64/kernel/entry.S
index 9f19e6b..0350ea6 100644
--- a/kernel/arch/arm64/kernel/entry.S
+++ b/kernel/arch/arm64/kernel/entry.S
@@ -297,7 +297,7 @@
 alternative_else_nop_endif
 1:
 
-	scs_load tsk, x20
+	scs_load_current
 	.else
 	add	x21, sp, #S_FRAME_SIZE
 	get_current_task tsk
@@ -1122,7 +1122,7 @@
 	msr	sp_el0, x1
 	ptrauth_keys_install_kernel x1, x8, x9, x10
 	scs_save x0, x8
-	scs_load x1, x8
+	scs_load_current
 	ret
 SYM_FUNC_END(cpu_switch_to)
 NOKPROBE(cpu_switch_to)
@@ -1238,9 +1238,13 @@
 
 	mov	x19, x1
 
-#if defined(CONFIG_VMAP_STACK) || defined(CONFIG_SHADOW_CALL_STACK)
+	/* Store the registered-event for crash_smp_send_stop() */
 	ldrb	w4, [x19, #SDEI_EVENT_PRIORITY]
-#endif
+	cbnz	w4, 1f
+	adr_this_cpu dst=x5, sym=sdei_active_normal_event, tmp=x6
+	b	2f
+1:	adr_this_cpu dst=x5, sym=sdei_active_critical_event, tmp=x6
+2:	str	x19, [x5]
 
 #ifdef CONFIG_VMAP_STACK
 	/*
@@ -1305,6 +1309,14 @@
 
 	ldr_l	x2, sdei_exit_mode
 
+	/* Clear the registered-event seen by crash_smp_send_stop() */
+	ldrb	w3, [x4, #SDEI_EVENT_PRIORITY]
+	cbnz	w3, 1f
+	adr_this_cpu dst=x5, sym=sdei_active_normal_event, tmp=x6
+	b	2f
+1:	adr_this_cpu dst=x5, sym=sdei_active_critical_event, tmp=x6
+2:	str	xzr, [x5]
+
 alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0
 	sdei_handler_exit exit_mode=x2
 alternative_else_nop_endif
@@ -1315,4 +1327,15 @@
 #endif
 SYM_CODE_END(__sdei_asm_handler)
 NOKPROBE(__sdei_asm_handler)
+
+SYM_CODE_START(__sdei_handler_abort)
+	mov_q	x0, SDEI_1_0_FN_SDEI_EVENT_COMPLETE_AND_RESUME
+	adr	x1, 1f
+	ldr_l	x2, sdei_exit_mode
+	sdei_handler_exit exit_mode=x2
+	// exit the handler and jump to the next instruction.
+	// Exit will stomp x0-x17, PSTATE, ELR_ELx, and SPSR_ELx.
+1:	ret
+SYM_CODE_END(__sdei_handler_abort)
+NOKPROBE(__sdei_handler_abort)
 #endif /* CONFIG_ARM_SDE_INTERFACE */
diff --git a/kernel/arch/arm64/kernel/head.S b/kernel/arch/arm64/kernel/head.S
index f196eab..87aabf2 100644
--- a/kernel/arch/arm64/kernel/head.S
+++ b/kernel/arch/arm64/kernel/head.S
@@ -621,7 +621,7 @@
 	ldr	x2, [x0, #CPU_BOOT_TASK]
 	cbz	x2, __secondary_too_slow
 	msr	sp_el0, x2
-	scs_load x2, x3
+	scs_load_current
 	mov	x29, #0
 	mov	x30, #0
 
diff --git a/kernel/arch/arm64/kernel/hw_breakpoint.c b/kernel/arch/arm64/kernel/hw_breakpoint.c
index 712e97c..e5a0c38 100644
--- a/kernel/arch/arm64/kernel/hw_breakpoint.c
+++ b/kernel/arch/arm64/kernel/hw_breakpoint.c
@@ -654,7 +654,7 @@
 		perf_bp_event(bp, regs);
 
 		/* Do we need to handle the stepping? */
-		if (is_default_overflow_handler(bp))
+		if (uses_default_overflow_handler(bp))
 			step = 1;
 unlock:
 		rcu_read_unlock();
@@ -733,7 +733,7 @@
 static int watchpoint_report(struct perf_event *wp, unsigned long addr,
 			     struct pt_regs *regs)
 {
-	int step = is_default_overflow_handler(wp);
+	int step = uses_default_overflow_handler(wp);
 	struct arch_hw_breakpoint *info = counter_arch_bp(wp);
 
 	info->trigger = addr;
diff --git a/kernel/arch/arm64/kernel/kgdb.c b/kernel/arch/arm64/kernel/kgdb.c
index 1a157ca..e4e9582 100644
--- a/kernel/arch/arm64/kernel/kgdb.c
+++ b/kernel/arch/arm64/kernel/kgdb.c
@@ -223,6 +223,8 @@
 		 */
 		if (!kernel_active_single_step())
 			kernel_enable_single_step(linux_regs);
+		else
+			kernel_rewind_single_step(linux_regs);
 		err = 0;
 		break;
 	default:
diff --git a/kernel/arch/arm64/kernel/module-plts.c b/kernel/arch/arm64/kernel/module-plts.c
index cee0781..5f8bf77 100644
--- a/kernel/arch/arm64/kernel/module-plts.c
+++ b/kernel/arch/arm64/kernel/module-plts.c
@@ -7,6 +7,7 @@
 #include <linux/ftrace.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/moduleloader.h>
 #include <linux/slab.h>
 #include <linux/sort.h>
 
@@ -376,7 +377,7 @@
 		if (nents)
 			sort(rels, nents, sizeof(Elf64_Rela), cmp_rela, NULL);
 
-		if (!str_has_prefix(secstrings + dstsec->sh_name, ".init"))
+		if (!module_init_layout_section(secstrings + dstsec->sh_name))
 			core_plts += count_plts(syms, rels, numrels,
 						sechdrs[i].sh_info, dstsec);
 		else
diff --git a/kernel/arch/arm64/kernel/mte.c b/kernel/arch/arm64/kernel/mte.c
index c6a37d9..8bb8b67 100644
--- a/kernel/arch/arm64/kernel/mte.c
+++ b/kernel/arch/arm64/kernel/mte.c
@@ -242,6 +242,49 @@
 	mte_check_tfsr_el1();
 }
 
+void mte_cpu_setup(void)
+{
+	u64 rgsr;
+
+	/*
+	 * CnP must be enabled only after the MAIR_EL1 register has been set
+	 * up. Inconsistent MAIR_EL1 between CPUs sharing the same TLB may
+	 * lead to the wrong memory type being used for a brief window during
+	 * CPU power-up.
+	 *
+	 * CnP is not a boot feature so MTE gets enabled before CnP, but let's
+	 * make sure that is the case.
+	 */
+	BUG_ON(read_sysreg(ttbr0_el1) & TTBR_CNP_BIT);
+	BUG_ON(read_sysreg(ttbr1_el1) & TTBR_CNP_BIT);
+
+	/* Normal Tagged memory type at the corresponding MAIR index */
+	sysreg_clear_set(mair_el1,
+			 MAIR_ATTRIDX(MAIR_ATTR_MASK, MT_NORMAL_TAGGED),
+			 MAIR_ATTRIDX(MAIR_ATTR_NORMAL_TAGGED,
+				      MT_NORMAL_TAGGED));
+
+	write_sysreg_s(KERNEL_GCR_EL1, SYS_GCR_EL1);
+
+	/*
+	 * If GCR_EL1.RRND=1 is implemented the same way as RRND=0, then
+	 * RGSR_EL1.SEED must be non-zero for IRG to produce
+	 * pseudorandom numbers. As RGSR_EL1 is UNKNOWN out of reset, we
+	 * must initialize it.
+	 */
+	rgsr = (read_sysreg(CNTVCT_EL0) & SYS_RGSR_EL1_SEED_MASK) <<
+	       SYS_RGSR_EL1_SEED_SHIFT;
+	if (rgsr == 0)
+		rgsr = 1 << SYS_RGSR_EL1_SEED_SHIFT;
+	write_sysreg_s(rgsr, SYS_RGSR_EL1);
+
+	/* clear any pending tag check faults in TFSR*_EL1 */
+	write_sysreg_s(0, SYS_TFSR_EL1);
+	write_sysreg_s(0, SYS_TFSRE0_EL1);
+
+	local_flush_tlb_all();
+}
+
 void mte_suspend_enter(void)
 {
 	if (!system_supports_mte())
@@ -258,6 +301,14 @@
 	mte_check_tfsr_el1();
 }
 
+void mte_suspend_exit(void)
+{
+	if (!system_supports_mte())
+		return;
+
+	mte_cpu_setup();
+}
+
 long set_mte_ctrl(struct task_struct *task, unsigned long arg)
 {
 	u64 mte_ctrl = (~((arg & PR_MTE_TAG_MASK) >> PR_MTE_TAG_SHIFT) &
diff --git a/kernel/arch/arm64/kernel/sdei.c b/kernel/arch/arm64/kernel/sdei.c
index 3f129b4..0b37f7c 100644
--- a/kernel/arch/arm64/kernel/sdei.c
+++ b/kernel/arch/arm64/kernel/sdei.c
@@ -39,6 +39,9 @@
 DEFINE_PER_CPU(unsigned long *, sdei_stack_critical_ptr);
 #endif
 
+DEFINE_PER_CPU(struct sdei_registered_event *, sdei_active_normal_event);
+DEFINE_PER_CPU(struct sdei_registered_event *, sdei_active_critical_event);
+
 DECLARE_PER_CPU(unsigned long *, sdei_shadow_call_stack_normal_ptr);
 DECLARE_PER_CPU(unsigned long *, sdei_shadow_call_stack_critical_ptr);
 
diff --git a/kernel/arch/arm64/kernel/smp.c b/kernel/arch/arm64/kernel/smp.c
index 581defe..ed042bf 100644
--- a/kernel/arch/arm64/kernel/smp.c
+++ b/kernel/arch/arm64/kernel/smp.c
@@ -1097,10 +1097,8 @@
 	 * If this cpu is the only one alive at this point in time, online or
 	 * not, there are no stop messages to be sent around, so just back out.
 	 */
-	if (num_other_online_cpus() == 0) {
-		sdei_mask_local_cpu();
-		return;
-	}
+	if (num_other_online_cpus() == 0)
+		goto skip_ipi;
 
 	cpumask_copy(&mask, cpu_online_mask);
 	cpumask_clear_cpu(smp_processor_id(), &mask);
@@ -1119,7 +1117,9 @@
 		pr_warn("SMP: failed to stop secondary CPUs %*pbl\n",
 			cpumask_pr_args(&mask));
 
+skip_ipi:
 	sdei_mask_local_cpu();
+	sdei_handler_abort();
 }
 
 bool smp_crash_stop_failed(void)
diff --git a/kernel/arch/arm64/kernel/suspend.c b/kernel/arch/arm64/kernel/suspend.c
index ea019a8..ae59fdd 100644
--- a/kernel/arch/arm64/kernel/suspend.c
+++ b/kernel/arch/arm64/kernel/suspend.c
@@ -42,6 +42,8 @@
 {
 	unsigned int cpu = smp_processor_id();
 
+	mte_suspend_exit();
+
 	/*
 	 * We are resuming from reset with the idmap active in TTBR0_EL1.
 	 * We must uninstall the idmap and restore the expected MMU
diff --git a/kernel/arch/arm64/kernel/traps.c b/kernel/arch/arm64/kernel/traps.c
index 49b4b7b..0b457c6 100644
--- a/kernel/arch/arm64/kernel/traps.c
+++ b/kernel/arch/arm64/kernel/traps.c
@@ -153,7 +153,7 @@
 	raw_spin_unlock_irqrestore(&die_lock, flags);
 
 	if (ret != NOTIFY_STOP)
-		do_exit(SIGSEGV);
+		make_task_dead(SIGSEGV);
 }
 
 static void arm64_show_signal(int signo, const char *str)
diff --git a/kernel/arch/arm64/kvm/arm.c b/kernel/arch/arm64/kvm/arm.c
index 78550c8..0470eba 100644
--- a/kernel/arch/arm64/kvm/arm.c
+++ b/kernel/arch/arm64/kvm/arm.c
@@ -2061,6 +2061,11 @@
 		return -ENODEV;
 	}
 
+	if (kvm_get_mode() == KVM_MODE_NONE) {
+		kvm_info("KVM disabled from command line\n");
+		return -ENODEV;
+	}
+
 	in_hyp_mode = is_kernel_in_hyp_mode();
 
 	if (cpus_have_final_cap(ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE) ||
@@ -2093,18 +2098,18 @@
 	err = kvm_init_vector_slots();
 	if (err) {
 		kvm_err("Cannot initialise vector slots\n");
-		goto out_err;
+		goto out_hyp;
 	}
 
 	err = init_subsystems();
 	if (err)
-		goto out_hyp;
+		goto out_subs;
 
 	if (!in_hyp_mode) {
 		err = finalize_hyp_mode();
 		if (err) {
 			kvm_err("Failed to finalize Hyp protection\n");
-			goto out_hyp;
+			goto out_subs;
 		}
 	}
 
@@ -2118,8 +2123,9 @@
 
 	return 0;
 
-out_hyp:
+out_subs:
 	hyp_cpu_pm_exit();
+out_hyp:
 	if (!in_hyp_mode)
 		teardown_hyp_mode();
 out_err:
@@ -2137,13 +2143,25 @@
 	if (!arg)
 		return -EINVAL;
 
+	if (strcmp(arg, "none") == 0) {
+		kvm_mode = KVM_MODE_NONE;
+		return 0;
+	}
+
+	if (!is_hyp_mode_available()) {
+		pr_warn_once("KVM is not available. Ignoring kvm-arm.mode\n");
+		return 0;
+	}
+
 	if (strcmp(arg, "protected") == 0) {
 		kvm_mode = KVM_MODE_PROTECTED;
 		return 0;
 	}
 
-	if (strcmp(arg, "nvhe") == 0 && !WARN_ON(is_kernel_in_hyp_mode()))
+	if (strcmp(arg, "nvhe") == 0 && !WARN_ON(is_kernel_in_hyp_mode())) {
+		kvm_mode = KVM_MODE_DEFAULT;
 		return 0;
+	}
 
 	return -EINVAL;
 }
diff --git a/kernel/arch/arm64/kvm/psci.c b/kernel/arch/arm64/kvm/psci.c
index 20ba513..32bb26b 100644
--- a/kernel/arch/arm64/kvm/psci.c
+++ b/kernel/arch/arm64/kvm/psci.c
@@ -499,6 +499,8 @@
 	u64 val;
 	int wa_level;
 
+	if (KVM_REG_SIZE(reg->id) != sizeof(val))
+		return -ENOENT;
 	if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id)))
 		return -EFAULT;
 
diff --git a/kernel/arch/arm64/lib/csum.c b/kernel/arch/arm64/lib/csum.c
index 78b87a6..2432683 100644
--- a/kernel/arch/arm64/lib/csum.c
+++ b/kernel/arch/arm64/lib/csum.c
@@ -24,7 +24,7 @@
 	const u64 *ptr;
 	u64 data, sum64 = 0;
 
-	if (unlikely(len == 0))
+	if (unlikely(len <= 0))
 		return 0;
 
 	offset = (unsigned long)buff & 7;
diff --git a/kernel/arch/arm64/mm/dma-mapping.c b/kernel/arch/arm64/mm/dma-mapping.c
index 2ee4895..b44bd95 100644
--- a/kernel/arch/arm64/mm/dma-mapping.c
+++ b/kernel/arch/arm64/mm/dma-mapping.c
@@ -11,7 +11,6 @@
 #include <xen/xen.h>
 #include <xen/swiotlb-xen.h>
 #include <trace/hooks/iommu.h>
-#include <trace/hooks/dma_noalias.h>
 
 #include <asm/cacheflush.h>
 
@@ -56,9 +55,6 @@
 		trace_android_vh_iommu_setup_dma_ops(dev, dma_base, size);
 		trace_android_rvh_iommu_setup_dma_ops(dev, dma_base, size);
 	}
-
-	/* Allow vendor modules to opt-in for the 2454944 erratum workaround */
-	trace_android_rvh_setup_dma_ops(dev);
 
 #ifdef CONFIG_XEN
 	if (xen_initial_domain())
diff --git a/kernel/arch/arm64/mm/fault.c b/kernel/arch/arm64/mm/fault.c
index 45e652d..b735d10 100644
--- a/kernel/arch/arm64/mm/fault.c
+++ b/kernel/arch/arm64/mm/fault.c
@@ -299,7 +299,7 @@
 	show_pte(addr);
 	die("Oops", regs, esr);
 	bust_spinlocks(0);
-	do_exit(SIGKILL);
+	make_task_dead(SIGKILL);
 }
 
 #ifdef CONFIG_KASAN_HW_TAGS
@@ -361,6 +361,11 @@
 	return false;
 }
 
+static bool is_translation_fault(unsigned long esr)
+{
+	return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_FAULT;
+}
+
 static void __do_kernel_fault(unsigned long addr, unsigned int esr,
 			      struct pt_regs *regs)
 {
@@ -393,7 +398,8 @@
 	} else if (addr < PAGE_SIZE) {
 		msg = "NULL pointer dereference";
 	} else {
-		if (kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs))
+		if (is_translation_fault(esr) &&
+		    kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs))
 			return;
 
 		msg = "paging request";
@@ -478,8 +484,8 @@
 	}
 }
 
-#define VM_FAULT_BADMAP		0x010000
-#define VM_FAULT_BADACCESS	0x020000
+#define VM_FAULT_BADMAP		((__force vm_fault_t)0x010000)
+#define VM_FAULT_BADACCESS	((__force vm_fault_t)0x020000)
 
 static int __do_page_fault(struct vm_area_struct *vma, unsigned long addr,
 				  unsigned int mm_flags, unsigned long vm_flags,
diff --git a/kernel/arch/arm64/mm/mmu.c b/kernel/arch/arm64/mm/mmu.c
index cce2522..2e0821b 100644
--- a/kernel/arch/arm64/mm/mmu.c
+++ b/kernel/arch/arm64/mm/mmu.c
@@ -421,7 +421,7 @@
 static void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt,
 				  phys_addr_t size, pgprot_t prot)
 {
-	if ((virt >= PAGE_END) && (virt < VMALLOC_START)) {
+	if (virt < PAGE_OFFSET) {
 		pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n",
 			&phys, virt);
 		return;
@@ -448,7 +448,7 @@
 static void update_mapping_prot(phys_addr_t phys, unsigned long virt,
 				phys_addr_t size, pgprot_t prot)
 {
-	if ((virt >= PAGE_END) && (virt < VMALLOC_START)) {
+	if (virt < PAGE_OFFSET) {
 		pr_warn("BUG: not updating mapping for %pa at 0x%016lx - outside kernel range\n",
 			&phys, virt);
 		return;
diff --git a/kernel/arch/arm64/mm/proc.S b/kernel/arch/arm64/mm/proc.S
index c188a9e..ee43c3c 100644
--- a/kernel/arch/arm64/mm/proc.S
+++ b/kernel/arch/arm64/mm/proc.S
@@ -47,17 +47,19 @@
 
 #ifdef CONFIG_KASAN_HW_TAGS
 #define TCR_MTE_FLAGS SYS_TCR_EL1_TCMA1 | TCR_TBI1 | TCR_TBID1
-#else
+#elif defined(CONFIG_ARM64_MTE)
 /*
  * The mte_zero_clear_page_tags() implementation uses DC GZVA, which relies on
  * TBI being enabled at EL1.
  */
 #define TCR_MTE_FLAGS TCR_TBI1 | TCR_TBID1
+#else
+#define TCR_MTE_FLAGS 0
 #endif
 
 /*
  * Default MAIR_EL1. MT_NORMAL_TAGGED is initially mapped as Normal memory and
- * changed during __cpu_setup to Normal Tagged if the system supports MTE.
+ * changed during mte_cpu_setup to Normal Tagged if the system supports MTE.
  */
 #define MAIR_EL1_SET							\
 	(MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRnE, MT_DEVICE_nGnRnE) |	\
@@ -427,47 +429,6 @@
 	 * Memory region attributes
 	 */
 	mov_q	x5, MAIR_EL1_SET
-#ifdef CONFIG_ARM64_MTE
-	mte_tcr	.req	x20
-
-	mov	mte_tcr, #0
-
-	/*
-	 * Update MAIR_EL1, GCR_EL1 and TFSR*_EL1 if MTE is supported
-	 * (ID_AA64PFR1_EL1[11:8] > 1).
-	 */
-	mrs	x10, ID_AA64PFR1_EL1
-	ubfx	x10, x10, #ID_AA64PFR1_MTE_SHIFT, #4
-	cmp	x10, #ID_AA64PFR1_MTE
-	b.lt	1f
-
-	/* Normal Tagged memory type at the corresponding MAIR index */
-	mov	x10, #MAIR_ATTR_NORMAL_TAGGED
-	bfi	x5, x10, #(8 *  MT_NORMAL_TAGGED), #8
-
-	mov	x10, #KERNEL_GCR_EL1
-	msr_s	SYS_GCR_EL1, x10
-
-	/*
-	 * If GCR_EL1.RRND=1 is implemented the same way as RRND=0, then
-	 * RGSR_EL1.SEED must be non-zero for IRG to produce
-	 * pseudorandom numbers. As RGSR_EL1 is UNKNOWN out of reset, we
-	 * must initialize it.
-	 */
-	mrs	x10, CNTVCT_EL0
-	ands	x10, x10, #SYS_RGSR_EL1_SEED_MASK
-	csinc	x10, x10, xzr, ne
-	lsl	x10, x10, #SYS_RGSR_EL1_SEED_SHIFT
-	msr_s	SYS_RGSR_EL1, x10
-
-	/* clear any pending tag check faults in TFSR*_EL1 */
-	msr_s	SYS_TFSR_EL1, xzr
-	msr_s	SYS_TFSRE0_EL1, xzr
-
-	/* set the TCR_EL1 bits */
-	mov_q	mte_tcr, TCR_MTE_FLAGS
-1:
-#endif
 	msr	mair_el1, x5
 	/*
 	 * Set/prepare TCR and TTBR. TCR_EL1.T1SZ gets further
@@ -475,11 +436,8 @@
 	 */
 	mov_q	x10, TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \
 			TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \
-			TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS
-#ifdef CONFIG_ARM64_MTE
-	orr	x10, x10, mte_tcr
-	.unreq	mte_tcr
-#endif
+			TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS | TCR_MTE_FLAGS
+
 	tcr_clear_errata_bits x10, x9, x5
 
 #ifdef CONFIG_ARM64_VA_BITS_52
diff --git a/kernel/arch/csky/abiv1/alignment.c b/kernel/arch/csky/abiv1/alignment.c
index cb2a0d9..2df115d 100644
--- a/kernel/arch/csky/abiv1/alignment.c
+++ b/kernel/arch/csky/abiv1/alignment.c
@@ -294,7 +294,7 @@
 				__func__, opcode, rz, rx, imm, addr);
 		show_regs(regs);
 		bust_spinlocks(0);
-		do_exit(SIGKILL);
+		make_task_dead(SIGKILL);
 	}
 
 	force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr);
diff --git a/kernel/arch/csky/kernel/traps.c b/kernel/arch/csky/kernel/traps.c
index 2272146..15711ef 100644
--- a/kernel/arch/csky/kernel/traps.c
+++ b/kernel/arch/csky/kernel/traps.c
@@ -111,7 +111,7 @@
 	if (panic_on_oops)
 		panic("Fatal exception");
 	if (ret != NOTIFY_STOP)
-		do_exit(SIGSEGV);
+		make_task_dead(SIGSEGV);
 }
 
 void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
diff --git a/kernel/arch/h8300/kernel/traps.c b/kernel/arch/h8300/kernel/traps.c
index 5d8b969..cf23ccb 100644
--- a/kernel/arch/h8300/kernel/traps.c
+++ b/kernel/arch/h8300/kernel/traps.c
@@ -17,6 +17,7 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/sched/debug.h>
+#include <linux/sched/task.h>
 #include <linux/mm_types.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -110,7 +111,7 @@
 	dump(fp);
 
 	spin_unlock_irq(&die_lock);
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
 
 static int kstack_depth_to_print = 24;
diff --git a/kernel/arch/h8300/mm/fault.c b/kernel/arch/h8300/mm/fault.c
index d4bc9c1..b465441 100644
--- a/kernel/arch/h8300/mm/fault.c
+++ b/kernel/arch/h8300/mm/fault.c
@@ -51,7 +51,7 @@
 	printk(" at virtual address %08lx\n", address);
 	if (!user_mode(regs))
 		die("Oops", regs, error_code);
-	do_exit(SIGKILL);
+	make_task_dead(SIGKILL);
 
 	return 1;
 }
diff --git a/kernel/arch/hexagon/kernel/traps.c b/kernel/arch/hexagon/kernel/traps.c
index 904134b..b334e80 100644
--- a/kernel/arch/hexagon/kernel/traps.c
+++ b/kernel/arch/hexagon/kernel/traps.c
@@ -218,7 +218,7 @@
 		panic("Fatal exception");
 
 	oops_exit();
-	do_exit(err);
+	make_task_dead(err);
 	return 0;
 }
 
diff --git a/kernel/arch/ia64/Kconfig b/kernel/arch/ia64/Kconfig
index 39b25a5..975b00b 100644
--- a/kernel/arch/ia64/Kconfig
+++ b/kernel/arch/ia64/Kconfig
@@ -8,6 +8,7 @@
 
 config IA64
 	bool
+	select ARCH_HAS_CPU_FINALIZE_INIT
 	select ARCH_HAS_DMA_MARK_CLEAN
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select ARCH_MIGHT_HAVE_PC_SERIO
@@ -361,7 +362,7 @@
 	depends on PROC_KCORE
 
 config IA64_MCA_RECOVERY
-	tristate "MCA recovery from errors other than TLB."
+	bool "MCA recovery from errors other than TLB."
 
 config IA64_PALINFO
 	tristate "/proc/pal support"
diff --git a/kernel/arch/ia64/include/asm/bugs.h b/kernel/arch/ia64/include/asm/bugs.h
deleted file mode 100644
index 0d6b9bd..0000000
--- a/kernel/arch/ia64/include/asm/bugs.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Needs:
- *	void check_bugs(void);
- *
- * Based on <asm-alpha/bugs.h>.
- *
- * Modified 1998, 1999, 2003
- *	David Mosberger-Tang <davidm@hpl.hp.com>,  Hewlett-Packard Co.
- */
-#ifndef _ASM_IA64_BUGS_H
-#define _ASM_IA64_BUGS_H
-
-#include <asm/processor.h>
-
-extern void check_bugs (void);
-
-#endif /* _ASM_IA64_BUGS_H */
diff --git a/kernel/arch/ia64/include/asm/pgtable.h b/kernel/arch/ia64/include/asm/pgtable.h
index 9f64fdf..6e5c387 100644
--- a/kernel/arch/ia64/include/asm/pgtable.h
+++ b/kernel/arch/ia64/include/asm/pgtable.h
@@ -279,7 +279,7 @@
 #define pud_bad(pud)			(!ia64_phys_addr_valid(pud_val(pud)))
 #define pud_present(pud)		(pud_val(pud) != 0UL)
 #define pud_clear(pudp)			(pud_val(*(pudp)) = 0UL)
-#define pud_page_vaddr(pud)		((unsigned long) __va(pud_val(pud) & _PFN_MASK))
+#define pud_pgtable(pud)		((pmd_t *) __va(pud_val(pud) & _PFN_MASK))
 #define pud_page(pud)			virt_to_page((pud_val(pud) + PAGE_OFFSET))
 
 #if CONFIG_PGTABLE_LEVELS == 4
@@ -287,7 +287,7 @@
 #define p4d_bad(p4d)			(!ia64_phys_addr_valid(p4d_val(p4d)))
 #define p4d_present(p4d)		(p4d_val(p4d) != 0UL)
 #define p4d_clear(p4dp)			(p4d_val(*(p4dp)) = 0UL)
-#define p4d_page_vaddr(p4d)		((unsigned long) __va(p4d_val(p4d) & _PFN_MASK))
+#define p4d_pgtable(p4d)		((pud_t *) __va(p4d_val(p4d) & _PFN_MASK))
 #define p4d_page(p4d)			virt_to_page((p4d_val(p4d) + PAGE_OFFSET))
 #endif
 
diff --git a/kernel/arch/ia64/kernel/mca_drv.c b/kernel/arch/ia64/kernel/mca_drv.c
index 2a40268..d9ee3b1 100644
--- a/kernel/arch/ia64/kernel/mca_drv.c
+++ b/kernel/arch/ia64/kernel/mca_drv.c
@@ -176,7 +176,7 @@
 	spin_unlock(&mca_bh_lock);
 
 	/* This process is about to be killed itself */
-	do_exit(SIGKILL);
+	make_task_dead(SIGKILL);
 }
 
 /**
diff --git a/kernel/arch/ia64/kernel/salinfo.c b/kernel/arch/ia64/kernel/salinfo.c
index a25ab9b..bb99b54 100644
--- a/kernel/arch/ia64/kernel/salinfo.c
+++ b/kernel/arch/ia64/kernel/salinfo.c
@@ -581,7 +581,7 @@
  * 'data' contains an integer that corresponds to the feature we're
  * testing
  */
-static int proc_salinfo_show(struct seq_file *m, void *v)
+static int __maybe_unused proc_salinfo_show(struct seq_file *m, void *v)
 {
 	unsigned long data = (unsigned long)v;
 	seq_puts(m, (sal_platform_features & data) ? "1\n" : "0\n");
diff --git a/kernel/arch/ia64/kernel/setup.c b/kernel/arch/ia64/kernel/setup.c
index dd595fb..e7dd675 100644
--- a/kernel/arch/ia64/kernel/setup.c
+++ b/kernel/arch/ia64/kernel/setup.c
@@ -1071,8 +1071,7 @@
 	}
 }
 
-void __init
-check_bugs (void)
+void __init arch_cpu_finalize_init(void)
 {
 	ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles,
 			       (unsigned long) __end___mckinley_e9_bundles);
diff --git a/kernel/arch/ia64/kernel/traps.c b/kernel/arch/ia64/kernel/traps.c
index e13cb90..7536423 100644
--- a/kernel/arch/ia64/kernel/traps.c
+++ b/kernel/arch/ia64/kernel/traps.c
@@ -85,7 +85,7 @@
 	if (panic_on_oops)
 		panic("Fatal exception");
 
-  	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 	return 0;
 }
 
diff --git a/kernel/arch/ia64/mm/contig.c b/kernel/arch/ia64/mm/contig.c
index e30e360..c638e01 100644
--- a/kernel/arch/ia64/mm/contig.c
+++ b/kernel/arch/ia64/mm/contig.c
@@ -79,7 +79,7 @@
 	return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
 }
 
-static inline void
+static inline __init void
 alloc_per_cpu_data(void)
 {
 	size_t size = PERCPU_PAGE_SIZE * num_possible_cpus();
diff --git a/kernel/arch/ia64/mm/fault.c b/kernel/arch/ia64/mm/fault.c
index cd9766d..8291981 100644
--- a/kernel/arch/ia64/mm/fault.c
+++ b/kernel/arch/ia64/mm/fault.c
@@ -274,7 +274,7 @@
 		regs = NULL;
 	bust_spinlocks(0);
 	if (regs)
-		do_exit(SIGKILL);
+		make_task_dead(SIGKILL);
 	return;
 
   out_of_memory:
diff --git a/kernel/arch/ia64/mm/hugetlbpage.c b/kernel/arch/ia64/mm/hugetlbpage.c
index f993cb3..921db95 100644
--- a/kernel/arch/ia64/mm/hugetlbpage.c
+++ b/kernel/arch/ia64/mm/hugetlbpage.c
@@ -58,7 +58,7 @@
 
 	pgd = pgd_offset(mm, taddr);
 	if (pgd_present(*pgd)) {
-		p4d = p4d_offset(pgd, addr);
+		p4d = p4d_offset(pgd, taddr);
 		if (p4d_present(*p4d)) {
 			pud = pud_offset(p4d, taddr);
 			if (pud_present(*pud)) {
diff --git a/kernel/arch/m68k/68000/entry.S b/kernel/arch/m68k/68000/entry.S
index 259b366..94abf3d 100644
--- a/kernel/arch/m68k/68000/entry.S
+++ b/kernel/arch/m68k/68000/entry.S
@@ -47,6 +47,8 @@
 	jbsr	syscall_trace_enter
 	RESTORE_SWITCH_STACK
 	addql	#4,%sp
+	addql	#1,%d0
+	jeq	ret_from_exception
 	movel	%sp@(PT_OFF_ORIG_D0),%d1
 	movel	#-ENOSYS,%d0
 	cmpl	#NR_syscalls,%d1
diff --git a/kernel/arch/m68k/Kconfig b/kernel/arch/m68k/Kconfig
index 372e4e6..ad7a4ff 100644
--- a/kernel/arch/m68k/Kconfig
+++ b/kernel/arch/m68k/Kconfig
@@ -4,6 +4,7 @@
 	default y
 	select ARCH_32BIT_OFF_T
 	select ARCH_HAS_BINFMT_FLAT
+	select ARCH_HAS_CPU_FINALIZE_INIT if MMU
 	select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE
 	select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
diff --git a/kernel/arch/m68k/Kconfig.devices b/kernel/arch/m68k/Kconfig.devices
index 6a87b4a..e6e3efa 100644
--- a/kernel/arch/m68k/Kconfig.devices
+++ b/kernel/arch/m68k/Kconfig.devices
@@ -19,6 +19,7 @@
 # We have a dedicated heartbeat LED. :-)
 config PROC_HARDWARE
 	bool "/proc/hardware support"
+	depends on PROC_FS
 	help
 	  Say Y here to support the /proc/hardware file, which gives you
 	  access to information about the machine you're running on,
diff --git a/kernel/arch/m68k/coldfire/entry.S b/kernel/arch/m68k/coldfire/entry.S
index d43a027..f1d41a9 100644
--- a/kernel/arch/m68k/coldfire/entry.S
+++ b/kernel/arch/m68k/coldfire/entry.S
@@ -92,6 +92,8 @@
 	jbsr	syscall_trace_enter
 	RESTORE_SWITCH_STACK
 	addql	#4,%sp
+	addql	#1,%d0
+	jeq	ret_from_exception
 	movel	%d3,%a0
 	jbsr	%a0@
 	movel	%d0,%sp@(PT_OFF_D0)		/* save the return value */
diff --git a/kernel/arch/m68k/fpsp040/skeleton.S b/kernel/arch/m68k/fpsp040/skeleton.S
index a8f4161..31a9c63 100644
--- a/kernel/arch/m68k/fpsp040/skeleton.S
+++ b/kernel/arch/m68k/fpsp040/skeleton.S
@@ -499,12 +499,12 @@
 	dbf	%d0,morein
 	rts
 
-	.section .fixup,#alloc,#execinstr
+	.section .fixup,"ax"
 	.even
 1:
 	jbra	fpsp040_die
 
-	.section __ex_table,#alloc
+	.section __ex_table,"a"
 	.align	4
 
 	.long	in_ea,1b
diff --git a/kernel/arch/m68k/ifpsp060/os.S b/kernel/arch/m68k/ifpsp060/os.S
index 7a0d6e4..89e2ec2 100644
--- a/kernel/arch/m68k/ifpsp060/os.S
+++ b/kernel/arch/m68k/ifpsp060/os.S
@@ -379,11 +379,11 @@
 
 
 | Execption handling for movs access to illegal memory
-	.section .fixup,#alloc,#execinstr
+	.section .fixup,"ax"
 	.even
 1:	moveq		#-1,%d1
 	rts
-.section __ex_table,#alloc
+.section __ex_table,"a"
 	.align 4
 	.long	dmrbuae,1b
 	.long	dmrwuae,1b
diff --git a/kernel/arch/m68k/include/asm/bugs.h b/kernel/arch/m68k/include/asm/bugs.h
deleted file mode 100644
index 7455306..0000000
--- a/kernel/arch/m68k/include/asm/bugs.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- *  include/asm-m68k/bugs.h
- *
- *  Copyright (C) 1994  Linus Torvalds
- */
-
-/*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Needs:
- *	void check_bugs(void);
- */
-
-#ifdef CONFIG_MMU
-extern void check_bugs(void);	/* in arch/m68k/kernel/setup.c */
-#else
-static void check_bugs(void)
-{
-}
-#endif
diff --git a/kernel/arch/m68k/include/asm/motorola_pgtable.h b/kernel/arch/m68k/include/asm/motorola_pgtable.h
index 8076467..956c808 100644
--- a/kernel/arch/m68k/include/asm/motorola_pgtable.h
+++ b/kernel/arch/m68k/include/asm/motorola_pgtable.h
@@ -129,7 +129,7 @@
 
 #define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK))
 #define pmd_page_vaddr(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK))
-#define pud_page_vaddr(pud) ((unsigned long)__va(pud_val(pud) & _TABLE_MASK))
+#define pud_pgtable(pud) ((pmd_t *)__va(pud_val(pud) & _TABLE_MASK))
 
 
 #define pte_none(pte)		(!pte_val(pte))
diff --git a/kernel/arch/m68k/kernel/entry.S b/kernel/arch/m68k/kernel/entry.S
index 9dd76fb..546bab6 100644
--- a/kernel/arch/m68k/kernel/entry.S
+++ b/kernel/arch/m68k/kernel/entry.S
@@ -167,9 +167,12 @@
 	jbsr	syscall_trace
 	RESTORE_SWITCH_STACK
 	addql	#4,%sp
+	addql	#1,%d0			| optimization for cmpil #-1,%d0
+	jeq	ret_from_syscall
 	movel	%sp@(PT_OFF_ORIG_D0),%d0
 	cmpl	#NR_syscalls,%d0
 	jcs	syscall
+	jra	ret_from_syscall
 badsys:
 	movel	#-ENOSYS,%sp@(PT_OFF_D0)
 	jra	ret_from_syscall
diff --git a/kernel/arch/m68k/kernel/relocate_kernel.S b/kernel/arch/m68k/kernel/relocate_kernel.S
index ab0f1e7..f766707 100644
--- a/kernel/arch/m68k/kernel/relocate_kernel.S
+++ b/kernel/arch/m68k/kernel/relocate_kernel.S
@@ -26,7 +26,7 @@
 	lea %pc@(.Lcopy),%a4
 2:	addl #0x00000000,%a4		/* virt_to_phys() */
 
-	.section ".m68k_fixup","aw"
+	.section .m68k_fixup,"aw"
 	.long M68K_FIXUP_MEMOFFSET, 2b+2
 	.previous
 
@@ -49,7 +49,7 @@
 	lea %pc@(.Lcont040),%a4
 5:	addl #0x00000000,%a4		/* virt_to_phys() */
 
-	.section ".m68k_fixup","aw"
+	.section .m68k_fixup,"aw"
 	.long M68K_FIXUP_MEMOFFSET, 5b+2
 	.previous
 
diff --git a/kernel/arch/m68k/kernel/setup_mm.c b/kernel/arch/m68k/kernel/setup_mm.c
index ab8aa7b..f811666 100644
--- a/kernel/arch/m68k/kernel/setup_mm.c
+++ b/kernel/arch/m68k/kernel/setup_mm.c
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/cpu.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
@@ -523,7 +524,7 @@
 module_init(proc_hardware_init);
 #endif
 
-void check_bugs(void)
+void __init arch_cpu_finalize_init(void)
 {
 #if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU)
 	if (m68k_fputype == 0) {
diff --git a/kernel/arch/m68k/kernel/signal.c b/kernel/arch/m68k/kernel/signal.c
index 5d12736..131e87a 100644
--- a/kernel/arch/m68k/kernel/signal.c
+++ b/kernel/arch/m68k/kernel/signal.c
@@ -882,11 +882,17 @@
 }
 
 static inline void __user *
-get_sigframe(struct ksignal *ksig, size_t frame_size)
+get_sigframe(struct ksignal *ksig, struct pt_regs *tregs, size_t frame_size)
 {
 	unsigned long usp = sigsp(rdusp(), ksig);
+	unsigned long gap = 0;
 
-	return (void __user *)((usp - frame_size) & -8UL);
+	if (CPU_IS_020_OR_030 && tregs->format == 0xb) {
+		/* USP is unreliable so use worst-case value */
+		gap = 256;
+	}
+
+	return (void __user *)((usp - gap - frame_size) & -8UL);
 }
 
 static int setup_frame(struct ksignal *ksig, sigset_t *set,
@@ -904,7 +910,7 @@
 		return -EFAULT;
 	}
 
-	frame = get_sigframe(ksig, sizeof(*frame) + fsize);
+	frame = get_sigframe(ksig, tregs, sizeof(*frame) + fsize);
 
 	if (fsize)
 		err |= copy_to_user (frame + 1, regs + 1, fsize);
@@ -976,7 +982,7 @@
 		return -EFAULT;
 	}
 
-	frame = get_sigframe(ksig, sizeof(*frame));
+	frame = get_sigframe(ksig, tregs, sizeof(*frame));
 
 	if (fsize)
 		err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
diff --git a/kernel/arch/m68k/kernel/traps.c b/kernel/arch/m68k/kernel/traps.c
index 9e12614..7d42c84 100644
--- a/kernel/arch/m68k/kernel/traps.c
+++ b/kernel/arch/m68k/kernel/traps.c
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/ptrace.h>
 #include <linux/kallsyms.h>
+#include <linux/extable.h>
 
 #include <asm/setup.h>
 #include <asm/fpu.h>
@@ -549,7 +550,8 @@
 			errorcode |= 2;
 
 		if (mmusr & (MMU_I | MMU_WP)) {
-			if (ssw & 4) {
+			/* We might have an exception table for this PC */
+			if (ssw & 4 && !search_exception_tables(fp->ptregs.pc)) {
 				pr_err("Data %s fault at %#010lx in %s (pc=%#lx)\n",
 				       ssw & RW ? "read" : "write",
 				       fp->un.fmtb.daddr,
@@ -1136,7 +1138,7 @@
 	pr_crit("%s: %08x\n", str, nr);
 	show_registers(fp);
 	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
 
 asmlinkage void set_esp0(unsigned long ssp)
diff --git a/kernel/arch/m68k/mm/fault.c b/kernel/arch/m68k/mm/fault.c
index ef46e77..fcb3a0d 100644
--- a/kernel/arch/m68k/mm/fault.c
+++ b/kernel/arch/m68k/mm/fault.c
@@ -48,7 +48,7 @@
 			pr_alert("Unable to handle kernel access");
 		pr_cont(" at virtual address %p\n", addr);
 		die_if_kernel("Oops", regs, 0 /*error_code*/);
-		do_exit(SIGKILL);
+		make_task_dead(SIGKILL);
 	}
 
 	return 1;
diff --git a/kernel/arch/microblaze/kernel/exceptions.c b/kernel/arch/microblaze/kernel/exceptions.c
index cf99c41..6d3a6a6 100644
--- a/kernel/arch/microblaze/kernel/exceptions.c
+++ b/kernel/arch/microblaze/kernel/exceptions.c
@@ -44,10 +44,10 @@
 	pr_warn("Oops: %s, sig: %ld\n", str, err);
 	show_regs(fp);
 	spin_unlock_irq(&die_lock);
-	/* do_exit() should take care of panic'ing from an interrupt
+	/* make_task_dead() should take care of panic'ing from an interrupt
 	 * context so we don't handle it here
 	 */
-	do_exit(err);
+	make_task_dead(err);
 }
 
 /* for user application debugging */
diff --git a/kernel/arch/mips/Kconfig b/kernel/arch/mips/Kconfig
index 3442bdd..57839f6 100644
--- a/kernel/arch/mips/Kconfig
+++ b/kernel/arch/mips/Kconfig
@@ -4,6 +4,7 @@
 	default y
 	select ARCH_32BIT_OFF_T if !64BIT
 	select ARCH_BINFMT_ELF_STATE if MIPS_FP_SUPPORT
+	select ARCH_HAS_CPU_FINALIZE_INIT
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_KCOV
 	select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE if !EVA
diff --git a/kernel/arch/mips/alchemy/devboards/db1000.c b/kernel/arch/mips/alchemy/devboards/db1000.c
index 2c52ee2..3183df6 100644
--- a/kernel/arch/mips/alchemy/devboards/db1000.c
+++ b/kernel/arch/mips/alchemy/devboards/db1000.c
@@ -14,7 +14,6 @@
 #include <linux/interrupt.h>
 #include <linux/leds.h>
 #include <linux/mmc/host.h>
-#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/spi/spi.h>
@@ -165,14 +164,10 @@
 
 /******************************************************************************/
 
+#ifdef CONFIG_MMC_AU1X
 static irqreturn_t db1100_mmc_cd(int irq, void *ptr)
 {
-	void (*mmc_cd)(struct mmc_host *, unsigned long);
-	/* link against CONFIG_MMC=m */
-	mmc_cd = symbol_get(mmc_detect_change);
-	mmc_cd(ptr, msecs_to_jiffies(500));
-	symbol_put(mmc_detect_change);
-
+	mmc_detect_change(ptr, msecs_to_jiffies(500));
 	return IRQ_HANDLED;
 }
 
@@ -375,6 +370,7 @@
 	.num_resources	= ARRAY_SIZE(au1100_mmc1_res),
 	.resource	= au1100_mmc1_res,
 };
+#endif /* CONFIG_MMC_AU1X */
 
 /******************************************************************************/
 
@@ -438,8 +434,10 @@
 
 static struct platform_device *db1100_devs[] = {
 	&au1100_lcd_device,
+#ifdef CONFIG_MMC_AU1X
 	&db1100_mmc0_dev,
 	&db1100_mmc1_dev,
+#endif
 };
 
 int __init db1000_dev_setup(void)
diff --git a/kernel/arch/mips/alchemy/devboards/db1200.c b/kernel/arch/mips/alchemy/devboards/db1200.c
index 421d651..414f92e 100644
--- a/kernel/arch/mips/alchemy/devboards/db1200.c
+++ b/kernel/arch/mips/alchemy/devboards/db1200.c
@@ -10,7 +10,6 @@
 #include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
-#include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/leds.h>
@@ -327,6 +326,7 @@
 
 /**********************************************************************/
 
+#ifdef CONFIG_MMC_AU1X
 /* SD carddetects:  they're supposed to be edge-triggered, but ack
  * doesn't seem to work (CPLD Rev 2).  Instead, the screaming one
  * is disabled and its counterpart enabled.  The 200ms timeout is
@@ -340,14 +340,7 @@
 
 static irqreturn_t db1200_mmc_cdfn(int irq, void *ptr)
 {
-	void (*mmc_cd)(struct mmc_host *, unsigned long);
-
-	/* link against CONFIG_MMC=m */
-	mmc_cd = symbol_get(mmc_detect_change);
-	if (mmc_cd) {
-		mmc_cd(ptr, msecs_to_jiffies(200));
-		symbol_put(mmc_detect_change);
-	}
+	mmc_detect_change(ptr, msecs_to_jiffies(200));
 
 	msleep(100);	/* debounce */
 	if (irq == DB1200_SD0_INSERT_INT)
@@ -431,14 +424,7 @@
 
 static irqreturn_t pb1200_mmc1_cdfn(int irq, void *ptr)
 {
-	void (*mmc_cd)(struct mmc_host *, unsigned long);
-
-	/* link against CONFIG_MMC=m */
-	mmc_cd = symbol_get(mmc_detect_change);
-	if (mmc_cd) {
-		mmc_cd(ptr, msecs_to_jiffies(200));
-		symbol_put(mmc_detect_change);
-	}
+	mmc_detect_change(ptr, msecs_to_jiffies(200));
 
 	msleep(100);	/* debounce */
 	if (irq == PB1200_SD1_INSERT_INT)
@@ -599,6 +585,7 @@
 	.num_resources	= ARRAY_SIZE(au1200_mmc1_res),
 	.resource	= au1200_mmc1_res,
 };
+#endif /* CONFIG_MMC_AU1X */
 
 /**********************************************************************/
 
@@ -766,7 +753,9 @@
 static struct platform_device *db1200_devs[] __initdata = {
 	NULL,		/* PSC0, selected by S6.8 */
 	&db1200_ide_dev,
+#ifdef CONFIG_MMC_AU1X
 	&db1200_mmc0_dev,
+#endif
 	&au1200_lcd_dev,
 	&db1200_eth_dev,
 	&db1200_nand_dev,
@@ -777,7 +766,9 @@
 };
 
 static struct platform_device *pb1200_devs[] __initdata = {
+#ifdef CONFIG_MMC_AU1X
 	&pb1200_mmc1_dev,
+#endif
 };
 
 /* Some peripheral base addresses differ on the PB1200 */
diff --git a/kernel/arch/mips/alchemy/devboards/db1300.c b/kernel/arch/mips/alchemy/devboards/db1300.c
index cd72eaa..c965d00 100644
--- a/kernel/arch/mips/alchemy/devboards/db1300.c
+++ b/kernel/arch/mips/alchemy/devboards/db1300.c
@@ -17,7 +17,6 @@
 #include <linux/interrupt.h>
 #include <linux/ata_platform.h>
 #include <linux/mmc/host.h>
-#include <linux/module.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/platnand.h>
 #include <linux/platform_device.h>
@@ -451,6 +450,7 @@
 
 /**********************************************************************/
 
+#ifdef CONFIG_MMC_AU1X
 static irqreturn_t db1300_mmc_cd(int irq, void *ptr)
 {
 	disable_irq_nosync(irq);
@@ -459,14 +459,7 @@
 
 static irqreturn_t db1300_mmc_cdfn(int irq, void *ptr)
 {
-	void (*mmc_cd)(struct mmc_host *, unsigned long);
-
-	/* link against CONFIG_MMC=m.  We can only be called once MMC core has
-	 * initialized the controller, so symbol_get() should always succeed.
-	 */
-	mmc_cd = symbol_get(mmc_detect_change);
-	mmc_cd(ptr, msecs_to_jiffies(200));
-	symbol_put(mmc_detect_change);
+	mmc_detect_change(ptr, msecs_to_jiffies(200));
 
 	msleep(100);	/* debounce */
 	if (irq == DB1300_SD1_INSERT_INT)
@@ -640,6 +633,7 @@
 	.resource	= au1300_sd0_res,
 	.num_resources	= ARRAY_SIZE(au1300_sd0_res),
 };
+#endif /* CONFIG_MMC_AU1X */
 
 /**********************************************************************/
 
@@ -784,8 +778,10 @@
 	&db1300_5waysw_dev,
 	&db1300_nand_dev,
 	&db1300_ide_dev,
+#ifdef CONFIG_MMC_AU1X
 	&db1300_sd0_dev,
 	&db1300_sd1_dev,
+#endif
 	&db1300_lcd_dev,
 	&db1300_ac97_dev,
 	&db1300_i2s_dev,
diff --git a/kernel/arch/mips/bcm63xx/clk.c b/kernel/arch/mips/bcm63xx/clk.c
index dcfa0ea..f183c45 100644
--- a/kernel/arch/mips/bcm63xx/clk.c
+++ b/kernel/arch/mips/bcm63xx/clk.c
@@ -361,6 +361,8 @@
  */
 int clk_enable(struct clk *clk)
 {
+	if (!clk)
+		return 0;
 	mutex_lock(&clocks_mutex);
 	clk_enable_unlocked(clk);
 	mutex_unlock(&clocks_mutex);
diff --git a/kernel/arch/mips/bmips/dma.c b/kernel/arch/mips/bmips/dma.c
index 49061b8..daef44f 100644
--- a/kernel/arch/mips/bmips/dma.c
+++ b/kernel/arch/mips/bmips/dma.c
@@ -64,6 +64,8 @@
 	return dma_addr;
 }
 
+bool bmips_rac_flush_disable;
+
 void arch_sync_dma_for_cpu_all(void)
 {
 	void __iomem *cbr = BMIPS_GET_CBR();
@@ -74,6 +76,9 @@
 	    boot_cpu_type() != CPU_BMIPS4380)
 		return;
 
+	if (unlikely(bmips_rac_flush_disable))
+		return;
+
 	/* Flush stale data out of the readahead cache */
 	cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG);
 	__raw_writel(cfg | 0x100, cbr + BMIPS_RAC_CONFIG);
diff --git a/kernel/arch/mips/bmips/setup.c b/kernel/arch/mips/bmips/setup.c
index 1b06b25..1606308 100644
--- a/kernel/arch/mips/bmips/setup.c
+++ b/kernel/arch/mips/bmips/setup.c
@@ -34,6 +34,8 @@
 #define REG_BCM6328_OTP		((void __iomem *)CKSEG1ADDR(0x1000062c))
 #define BCM6328_TP1_DISABLED	BIT(9)
 
+extern bool bmips_rac_flush_disable;
+
 static const unsigned long kbase = VMLINUX_LOAD_ADDRESS & 0xfff00000;
 
 struct bmips_quirk {
@@ -103,6 +105,12 @@
 	 * disable SMP for now
 	 */
 	bmips_smp_enabled = 0;
+
+	/*
+	 * RAC flush causes kernel panics on BCM6358 when booting from TP1
+	 * because the bootloader is not initializing it properly.
+	 */
+	bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31));
 }
 
 static void bcm6368_quirks(void)
diff --git a/kernel/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/kernel/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
index abd11b7..9b791cc 100644
--- a/kernel/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
+++ b/kernel/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
@@ -211,7 +211,7 @@
 {
 	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/kernel/arch/mips/cavium-octeon/executive/cvmx-helper.c b/kernel/arch/mips/cavium-octeon/executive/cvmx-helper.c
index 6044ff4..a18ad2d 100644
--- a/kernel/arch/mips/cavium-octeon/executive/cvmx-helper.c
+++ b/kernel/arch/mips/cavium-octeon/executive/cvmx-helper.c
@@ -1100,7 +1100,7 @@
 		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;
diff --git a/kernel/arch/mips/configs/decstation_64_defconfig b/kernel/arch/mips/configs/decstation_64_defconfig
index 85f1955..4a81297 100644
--- a/kernel/arch/mips/configs/decstation_64_defconfig
+++ b/kernel/arch/mips/configs/decstation_64_defconfig
@@ -53,8 +53,6 @@
 CONFIG_NETWORK_SECMARK=y
 CONFIG_IP_SCTP=m
 CONFIG_VLAN_8021Q=m
-CONFIG_DECNET=m
-CONFIG_DECNET_ROUTER=y
 # CONFIG_WIRELESS is not set
 # CONFIG_UEVENT_HELPER is not set
 # CONFIG_FW_LOADER is not set
diff --git a/kernel/arch/mips/configs/decstation_defconfig b/kernel/arch/mips/configs/decstation_defconfig
index 30a6eaf..fd35454 100644
--- a/kernel/arch/mips/configs/decstation_defconfig
+++ b/kernel/arch/mips/configs/decstation_defconfig
@@ -49,8 +49,6 @@
 CONFIG_NETWORK_SECMARK=y
 CONFIG_IP_SCTP=m
 CONFIG_VLAN_8021Q=m
-CONFIG_DECNET=m
-CONFIG_DECNET_ROUTER=y
 # CONFIG_WIRELESS is not set
 # CONFIG_UEVENT_HELPER is not set
 # CONFIG_FW_LOADER is not set
diff --git a/kernel/arch/mips/configs/decstation_r4k_defconfig b/kernel/arch/mips/configs/decstation_r4k_defconfig
index e2b58db..7ed8f4c 100644
--- a/kernel/arch/mips/configs/decstation_r4k_defconfig
+++ b/kernel/arch/mips/configs/decstation_r4k_defconfig
@@ -48,8 +48,6 @@
 CONFIG_NETWORK_SECMARK=y
 CONFIG_IP_SCTP=m
 CONFIG_VLAN_8021Q=m
-CONFIG_DECNET=m
-CONFIG_DECNET_ROUTER=y
 # CONFIG_WIRELESS is not set
 # CONFIG_UEVENT_HELPER is not set
 # CONFIG_FW_LOADER is not set
diff --git a/kernel/arch/mips/configs/gpr_defconfig b/kernel/arch/mips/configs/gpr_defconfig
index 9085f4d..5b9b59a 100644
--- a/kernel/arch/mips/configs/gpr_defconfig
+++ b/kernel/arch/mips/configs/gpr_defconfig
@@ -69,7 +69,6 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_DECNET_NF_GRABULATOR=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -99,7 +98,6 @@
 CONFIG_ATM_BR2684=m
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
-CONFIG_DECNET=m
 CONFIG_LLC2=m
 CONFIG_ATALK=m
 CONFIG_DEV_APPLETALK=m
diff --git a/kernel/arch/mips/configs/mtx1_defconfig b/kernel/arch/mips/configs/mtx1_defconfig
index 914af12..d657853 100644
--- a/kernel/arch/mips/configs/mtx1_defconfig
+++ b/kernel/arch/mips/configs/mtx1_defconfig
@@ -117,7 +117,6 @@
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
-CONFIG_DECNET_NF_GRABULATOR=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -147,7 +146,6 @@
 CONFIG_ATM_BR2684=m
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
-CONFIG_DECNET=m
 CONFIG_LLC2=m
 CONFIG_ATALK=m
 CONFIG_DEV_APPLETALK=m
diff --git a/kernel/arch/mips/configs/nlm_xlp_defconfig b/kernel/arch/mips/configs/nlm_xlp_defconfig
index 72a211d..45421a0 100644
--- a/kernel/arch/mips/configs/nlm_xlp_defconfig
+++ b/kernel/arch/mips/configs/nlm_xlp_defconfig
@@ -200,7 +200,6 @@
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_IP6_NF_SECURITY=m
-CONFIG_DECNET_NF_GRABULATOR=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -234,7 +233,6 @@
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
 CONFIG_VLAN_8021Q_GVRP=y
-CONFIG_DECNET=m
 CONFIG_LLC2=m
 CONFIG_ATALK=m
 CONFIG_DEV_APPLETALK=m
diff --git a/kernel/arch/mips/configs/nlm_xlr_defconfig b/kernel/arch/mips/configs/nlm_xlr_defconfig
index 4ecb157..1081972 100644
--- a/kernel/arch/mips/configs/nlm_xlr_defconfig
+++ b/kernel/arch/mips/configs/nlm_xlr_defconfig
@@ -198,7 +198,6 @@
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_IP6_NF_SECURITY=m
-CONFIG_DECNET_NF_GRABULATOR=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -232,7 +231,6 @@
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
 CONFIG_VLAN_8021Q_GVRP=y
-CONFIG_DECNET=m
 CONFIG_LLC2=m
 CONFIG_ATALK=m
 CONFIG_DEV_APPLETALK=m
diff --git a/kernel/arch/mips/configs/rm200_defconfig b/kernel/arch/mips/configs/rm200_defconfig
index 30d7c3d..2d05061 100644
--- a/kernel/arch/mips/configs/rm200_defconfig
+++ b/kernel/arch/mips/configs/rm200_defconfig
@@ -116,7 +116,6 @@
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
-CONFIG_DECNET_NF_GRABULATOR=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -137,7 +136,6 @@
 CONFIG_BRIDGE_EBT_SNAT=m
 CONFIG_BRIDGE_EBT_LOG=m
 CONFIG_BRIDGE=m
-CONFIG_DECNET=m
 CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_CBQ=m
 CONFIG_NET_SCH_HTB=m
diff --git a/kernel/arch/mips/fw/lib/cmdline.c b/kernel/arch/mips/fw/lib/cmdline.c
index f24cbb4..892765b 100644
--- a/kernel/arch/mips/fw/lib/cmdline.c
+++ b/kernel/arch/mips/fw/lib/cmdline.c
@@ -53,7 +53,7 @@
 {
 	char *result = NULL;
 
-	if (_fw_envp != NULL) {
+	if (_fw_envp != NULL && fw_envp(0) != NULL) {
 		/*
 		 * Return a pointer to the given environment variable.
 		 * YAMON uses "name", "value" pairs, while U-Boot uses
diff --git a/kernel/arch/mips/include/asm/atomic.h b/kernel/arch/mips/include/asm/atomic.h
index 27ad767..fd0e090 100644
--- a/kernel/arch/mips/include/asm/atomic.h
+++ b/kernel/arch/mips/include/asm/atomic.h
@@ -203,7 +203,7 @@
  * The function returns the old value of @v minus @i.
  */
 #define ATOMIC_SIP_OP(pfx, type, op, ll, sc)				\
-static __inline__ int pfx##_sub_if_positive(type i, pfx##_t * v)	\
+static __inline__ type pfx##_sub_if_positive(type i, pfx##_t * v)	\
 {									\
 	type temp, result;						\
 									\
diff --git a/kernel/arch/mips/include/asm/bugs.h b/kernel/arch/mips/include/asm/bugs.h
index d72dc6e..8d4cf29 100644
--- a/kernel/arch/mips/include/asm/bugs.h
+++ b/kernel/arch/mips/include/asm/bugs.h
@@ -1,17 +1,11 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
  * Copyright (C) 2007  Maciej W. Rozycki
- *
- * Needs:
- *	void check_bugs(void);
  */
 #ifndef _ASM_BUGS_H
 #define _ASM_BUGS_H
 
 #include <linux/bug.h>
-#include <linux/delay.h>
 #include <linux/smp.h>
 
 #include <asm/cpu.h>
@@ -28,17 +22,6 @@
 {
 	if (IS_ENABLED(CONFIG_CPU_R4X00_BUGS64))
 		check_bugs64_early();
-}
-
-static inline void check_bugs(void)
-{
-	unsigned int cpu = smp_processor_id();
-
-	cpu_data[cpu].udelay_val = loops_per_jiffy;
-	check_bugs32();
-
-	if (IS_ENABLED(CONFIG_CPU_R4X00_BUGS64))
-		check_bugs64();
 }
 
 static inline int r4k_daddiu_bug(void)
diff --git a/kernel/arch/mips/include/asm/cpu-features.h b/kernel/arch/mips/include/asm/cpu-features.h
index 8294eaa..dd03bc9 100644
--- a/kernel/arch/mips/include/asm/cpu-features.h
+++ b/kernel/arch/mips/include/asm/cpu-features.h
@@ -126,7 +126,24 @@
 #define cpu_has_tx39_cache	__opt(MIPS_CPU_TX39_CACHE)
 #endif
 #ifndef cpu_has_octeon_cache
-#define cpu_has_octeon_cache	0
+#define cpu_has_octeon_cache						\
+({									\
+	int __res;							\
+									\
+	switch (boot_cpu_type()) {					\
+	case CPU_CAVIUM_OCTEON:						\
+	case CPU_CAVIUM_OCTEON_PLUS:					\
+	case CPU_CAVIUM_OCTEON2:					\
+	case CPU_CAVIUM_OCTEON3:					\
+		__res = 1;						\
+		break;							\
+									\
+	default:							\
+		__res = 0;						\
+	}								\
+									\
+	__res;								\
+})
 #endif
 /* Don't override `cpu_has_fpu' to 1 or the "nofpu" option won't work.  */
 #ifndef cpu_has_fpu
@@ -353,7 +370,7 @@
 ({									\
 	int __res;							\
 									\
-	switch (current_cpu_type()) {					\
+	switch (boot_cpu_type()) {					\
 	case CPU_M14KC:							\
 	case CPU_74K:							\
 	case CPU_1074K:							\
diff --git a/kernel/arch/mips/include/asm/dec/prom.h b/kernel/arch/mips/include/asm/dec/prom.h
index 1e1247a..908e96e 100644
--- a/kernel/arch/mips/include/asm/dec/prom.h
+++ b/kernel/arch/mips/include/asm/dec/prom.h
@@ -70,7 +70,7 @@
  */
 typedef struct {
 	int pagesize;
-	unsigned char bitmap[0];
+	unsigned char bitmap[];
 } memmap;
 
 
diff --git a/kernel/arch/mips/include/asm/mach-rc32434/pci.h b/kernel/arch/mips/include/asm/mach-rc32434/pci.h
index 9a6eefd..3eb767c 100644
--- a/kernel/arch/mips/include/asm/mach-rc32434/pci.h
+++ b/kernel/arch/mips/include/asm/mach-rc32434/pci.h
@@ -374,7 +374,7 @@
 				 PCI_CFG04_STAT_SSE | \
 				 PCI_CFG04_STAT_PE)
 
-#define KORINA_CNFG1		((KORINA_STAT<<16)|KORINA_CMD)
+#define KORINA_CNFG1		(KORINA_STAT | KORINA_CMD)
 
 #define KORINA_REVID		0
 #define KORINA_CLASS_CODE	0
diff --git a/kernel/arch/mips/include/asm/pgtable-64.h b/kernel/arch/mips/include/asm/pgtable-64.h
index 1e7d6ce..b865edf 100644
--- a/kernel/arch/mips/include/asm/pgtable-64.h
+++ b/kernel/arch/mips/include/asm/pgtable-64.h
@@ -210,9 +210,9 @@
 	p4d_val(*p4dp) = (unsigned long)invalid_pud_table;
 }
 
-static inline unsigned long p4d_page_vaddr(p4d_t p4d)
+static inline pud_t *p4d_pgtable(p4d_t p4d)
 {
-	return p4d_val(p4d);
+	return (pud_t *)p4d_val(p4d);
 }
 
 #define p4d_phys(p4d)		virt_to_phys((void *)p4d_val(p4d))
@@ -314,9 +314,9 @@
 #endif
 
 #ifndef __PAGETABLE_PMD_FOLDED
-static inline unsigned long pud_page_vaddr(pud_t pud)
+static inline pmd_t *pud_pgtable(pud_t pud)
 {
-	return pud_val(pud);
+	return (pmd_t *)pud_val(pud);
 }
 #define pud_phys(pud)		virt_to_phys((void *)pud_val(pud))
 #define pud_page(pud)		(pfn_to_page(pud_phys(pud) >> PAGE_SHIFT))
diff --git a/kernel/arch/mips/include/asm/syscall.h b/kernel/arch/mips/include/asm/syscall.h
index 25fa651..ebdf4d9 100644
--- a/kernel/arch/mips/include/asm/syscall.h
+++ b/kernel/arch/mips/include/asm/syscall.h
@@ -38,7 +38,7 @@
 static inline long syscall_get_nr(struct task_struct *task,
 				  struct pt_regs *regs)
 {
-	return current_thread_info()->syscall;
+	return task_thread_info(task)->syscall;
 }
 
 static inline void mips_syscall_update_nr(struct task_struct *task,
diff --git a/kernel/arch/mips/include/asm/vpe.h b/kernel/arch/mips/include/asm/vpe.h
index 80e70db..0127315 100644
--- a/kernel/arch/mips/include/asm/vpe.h
+++ b/kernel/arch/mips/include/asm/vpe.h
@@ -104,7 +104,6 @@
 	struct list_head tc_list;       /* Thread contexts */
 };
 
-extern unsigned long physical_memsize;
 extern struct vpe_control vpecontrol;
 extern const struct file_operations vpe_fops;
 
diff --git a/kernel/arch/mips/include/uapi/asm/socket.h b/kernel/arch/mips/include/uapi/asm/socket.h
index d0a9ed2..ff3ab77 100644
--- a/kernel/arch/mips/include/uapi/asm/socket.h
+++ b/kernel/arch/mips/include/uapi/asm/socket.h
@@ -135,6 +135,8 @@
 
 #define SO_DETACH_REUSEPORT_BPF 68
 
+#define SO_NETNS_COOKIE		71
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64
diff --git a/kernel/arch/mips/kernel/cpu-probe.c b/kernel/arch/mips/kernel/cpu-probe.c
index d120201..f8d1933 100644
--- a/kernel/arch/mips/kernel/cpu-probe.c
+++ b/kernel/arch/mips/kernel/cpu-probe.c
@@ -1721,7 +1721,10 @@
 
 static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
 {
+	c->cputype = CPU_LOONGSON64;
+
 	/* All Loongson processors covered here define ExcCode 16 as GSExc. */
+	decode_configs(c);
 	c->options |= MIPS_CPU_GSEXCEX;
 
 	switch (c->processor_id & PRID_IMP_MASK) {
@@ -1731,7 +1734,6 @@
 		case PRID_REV_LOONGSON2K_R1_1:
 		case PRID_REV_LOONGSON2K_R1_2:
 		case PRID_REV_LOONGSON2K_R1_3:
-			c->cputype = CPU_LOONGSON64;
 			__cpu_name[cpu] = "Loongson-2K";
 			set_elf_platform(cpu, "gs264e");
 			set_isa(c, MIPS_CPU_ISA_M64R2);
@@ -1744,14 +1746,12 @@
 		switch (c->processor_id & PRID_REV_MASK) {
 		case PRID_REV_LOONGSON3A_R2_0:
 		case PRID_REV_LOONGSON3A_R2_1:
-			c->cputype = CPU_LOONGSON64;
 			__cpu_name[cpu] = "ICT Loongson-3";
 			set_elf_platform(cpu, "loongson3a");
 			set_isa(c, MIPS_CPU_ISA_M64R2);
 			break;
 		case PRID_REV_LOONGSON3A_R3_0:
 		case PRID_REV_LOONGSON3A_R3_1:
-			c->cputype = CPU_LOONGSON64;
 			__cpu_name[cpu] = "ICT Loongson-3";
 			set_elf_platform(cpu, "loongson3a");
 			set_isa(c, MIPS_CPU_ISA_M64R2);
@@ -1771,7 +1771,6 @@
 		c->ases &= ~MIPS_ASE_VZ; /* VZ of Loongson-3A2000/3000 is incomplete */
 		break;
 	case PRID_IMP_LOONGSON_64G:
-		c->cputype = CPU_LOONGSON64;
 		__cpu_name[cpu] = "ICT Loongson-3";
 		set_elf_platform(cpu, "loongson3a");
 		set_isa(c, MIPS_CPU_ISA_M64R2);
@@ -1781,8 +1780,6 @@
 		panic("Unknown Loongson Processor ID!");
 		break;
 	}
-
-	decode_configs(c);
 }
 #else
 static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) { }
diff --git a/kernel/arch/mips/kernel/setup.c b/kernel/arch/mips/kernel/setup.c
index 9d11f68..b7eb7dd 100644
--- a/kernel/arch/mips/kernel/setup.c
+++ b/kernel/arch/mips/kernel/setup.c
@@ -11,6 +11,8 @@
  * Copyright (C) 2000, 2001, 2002, 2007	 Maciej W. Rozycki
  */
 #include <linux/init.h>
+#include <linux/cpu.h>
+#include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/export.h>
 #include <linux/screen_info.h>
@@ -154,10 +156,6 @@
 		pr_err("initrd start must be page aligned\n");
 		goto disable;
 	}
-	if (initrd_start < PAGE_OFFSET) {
-		pr_err("initrd start < PAGE_OFFSET\n");
-		goto disable;
-	}
 
 	/*
 	 * Sanitize initrd addresses. For example firmware
@@ -169,6 +167,11 @@
 	end = __pa(initrd_end);
 	initrd_end = (unsigned long)__va(end);
 	initrd_start = (unsigned long)__va(__pa(initrd_start));
+
+	if (initrd_start < PAGE_OFFSET) {
+		pr_err("initrd start < PAGE_OFFSET\n");
+		goto disable;
+	}
 
 	ROOT_DEV = Root_RAM0;
 	return PFN_UP(end);
@@ -828,3 +831,14 @@
 }
 early_param("nocoherentio", setnocoherentio);
 #endif
+
+void __init arch_cpu_finalize_init(void)
+{
+	unsigned int cpu = smp_processor_id();
+
+	cpu_data[cpu].udelay_val = loops_per_jiffy;
+	check_bugs32();
+
+	if (IS_ENABLED(CONFIG_CPU_R4X00_BUGS64))
+		check_bugs64();
+}
diff --git a/kernel/arch/mips/kernel/smp-cps.c b/kernel/arch/mips/kernel/smp-cps.c
index dbb3f1f..f659adb 100644
--- a/kernel/arch/mips/kernel/smp-cps.c
+++ b/kernel/arch/mips/kernel/smp-cps.c
@@ -423,9 +423,11 @@
 			wmb();
 		}
 	} else {
-		pr_debug("Gating power to core %d\n", core);
-		/* Power down the core */
-		cps_pm_enter_state(CPS_PM_POWER_GATED);
+		if (IS_ENABLED(CONFIG_HOTPLUG_CPU)) {
+			pr_debug("Gating power to core %d\n", core);
+			/* Power down the core */
+			cps_pm_enter_state(CPS_PM_POWER_GATED);
+		}
 	}
 }
 
diff --git a/kernel/arch/mips/kernel/traps.c b/kernel/arch/mips/kernel/traps.c
index b1fe451..ebd0101 100644
--- a/kernel/arch/mips/kernel/traps.c
+++ b/kernel/arch/mips/kernel/traps.c
@@ -413,7 +413,7 @@
 	if (regs && kexec_should_crash(current))
 		crash_kexec(regs);
 
-	do_exit(sig);
+	make_task_dead(sig);
 }
 
 extern struct exception_table_entry __start___dbe_table[];
diff --git a/kernel/arch/mips/kernel/vmlinux.lds.S b/kernel/arch/mips/kernel/vmlinux.lds.S
index 09fa470..64afe07 100644
--- a/kernel/arch/mips/kernel/vmlinux.lds.S
+++ b/kernel/arch/mips/kernel/vmlinux.lds.S
@@ -15,6 +15,8 @@
 #define EMITS_PT_NOTE
 #endif
 
+#define RUNTIME_DISCARD_EXIT
+
 #include <asm-generic/vmlinux.lds.h>
 
 #undef mips
diff --git a/kernel/arch/mips/kernel/vpe-cmp.c b/kernel/arch/mips/kernel/vpe-cmp.c
index 9268ebc..903c07b 100644
--- a/kernel/arch/mips/kernel/vpe-cmp.c
+++ b/kernel/arch/mips/kernel/vpe-cmp.c
@@ -75,7 +75,6 @@
 
 static void vpe_device_release(struct device *cd)
 {
-	kfree(cd);
 }
 
 static struct class vpe_class = {
@@ -157,6 +156,7 @@
 	device_del(&vpe_device);
 
 out_class:
+	put_device(&vpe_device);
 	class_unregister(&vpe_class);
 
 out_chrdev:
@@ -169,7 +169,7 @@
 {
 	struct vpe *v, *n;
 
-	device_del(&vpe_device);
+	device_unregister(&vpe_device);
 	class_unregister(&vpe_class);
 	unregister_chrdev(major, VPE_MODULE_NAME);
 
diff --git a/kernel/arch/mips/kernel/vpe-mt.c b/kernel/arch/mips/kernel/vpe-mt.c
index 2e003b1..496ed8f 100644
--- a/kernel/arch/mips/kernel/vpe-mt.c
+++ b/kernel/arch/mips/kernel/vpe-mt.c
@@ -92,12 +92,11 @@
 	write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H);
 
 	/*
-	 * The sde-kit passes 'memsize' to __start in $a3, so set something
-	 * here...  Or set $a3 to zero and define DFLT_STACK_SIZE and
-	 * DFLT_HEAP_SIZE when you compile your program
+	 * We don't pass the memsize here, so VPE programs need to be
+	 * compiled with DFLT_STACK_SIZE and DFLT_HEAP_SIZE defined.
 	 */
+	mttgpr(7, 0);
 	mttgpr(6, v->ntcs);
-	mttgpr(7, physical_memsize);
 
 	/* set up VPE1 */
 	/*
@@ -313,7 +312,6 @@
 
 static void vpe_device_release(struct device *cd)
 {
-	kfree(cd);
 }
 
 static struct class vpe_class = {
@@ -497,6 +495,7 @@
 	device_del(&vpe_device);
 
 out_class:
+	put_device(&vpe_device);
 	class_unregister(&vpe_class);
 
 out_chrdev:
@@ -509,7 +508,7 @@
 {
 	struct vpe *v, *n;
 
-	device_del(&vpe_device);
+	device_unregister(&vpe_device);
 	class_unregister(&vpe_class);
 	unregister_chrdev(major, VPE_MODULE_NAME);
 
diff --git a/kernel/arch/mips/lantiq/prom.c b/kernel/arch/mips/lantiq/prom.c
index 3f568f5..2729a4b 100644
--- a/kernel/arch/mips/lantiq/prom.c
+++ b/kernel/arch/mips/lantiq/prom.c
@@ -23,12 +23,6 @@
 EXPORT_SYMBOL_GPL(ebu_lock);
 
 /*
- * This is needed by the VPE loader code, just set it to 0 and assume
- * that the firmware hardcodes this value to something useful.
- */
-unsigned long physical_memsize = 0L;
-
-/*
  * this struct is filled by the soc specific detection code and holds
  * information about the specific soc type, revision and name
  */
diff --git a/kernel/arch/nds32/kernel/fpu.c b/kernel/arch/nds32/kernel/fpu.c
index 9edd7ed..701c09a 100644
--- a/kernel/arch/nds32/kernel/fpu.c
+++ b/kernel/arch/nds32/kernel/fpu.c
@@ -223,7 +223,7 @@
 		}
 	} else if (fpcsr & FPCSR_mskRIT) {
 		if (!user_mode(regs))
-			do_exit(SIGILL);
+			make_task_dead(SIGILL);
 		si_signo = SIGILL;
 	}
 
diff --git a/kernel/arch/nds32/kernel/traps.c b/kernel/arch/nds32/kernel/traps.c
index 6a9772b..12cdd65 100644
--- a/kernel/arch/nds32/kernel/traps.c
+++ b/kernel/arch/nds32/kernel/traps.c
@@ -185,7 +185,7 @@
 
 	bust_spinlocks(0);
 	spin_unlock_irq(&die_lock);
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
 
 EXPORT_SYMBOL(die);
@@ -289,7 +289,7 @@
 	pr_emerg("unhandled_interruption\n");
 	show_regs(regs);
 	if (!user_mode(regs))
-		do_exit(SIGKILL);
+		make_task_dead(SIGKILL);
 	force_sig(SIGKILL);
 }
 
@@ -300,7 +300,7 @@
 		 addr, type);
 	show_regs(regs);
 	if (!user_mode(regs))
-		do_exit(SIGKILL);
+		make_task_dead(SIGKILL);
 	force_sig(SIGKILL);
 }
 
@@ -327,7 +327,7 @@
 	pr_emerg("Reserved Instruction\n");
 	show_regs(regs);
 	if (!user_mode(regs))
-		do_exit(SIGILL);
+		make_task_dead(SIGILL);
 	force_sig(SIGILL);
 }
 
diff --git a/kernel/arch/nios2/boot/dts/10m50_devboard.dts b/kernel/arch/nios2/boot/dts/10m50_devboard.dts
index 56339be..0e7e5b0 100644
--- a/kernel/arch/nios2/boot/dts/10m50_devboard.dts
+++ b/kernel/arch/nios2/boot/dts/10m50_devboard.dts
@@ -97,7 +97,7 @@
 			rx-fifo-depth = <8192>;
 			tx-fifo-depth = <8192>;
 			address-bits = <48>;
-			max-frame-size = <1518>;
+			max-frame-size = <1500>;
 			local-mac-address = [00 00 00 00 00 00];
 			altr,has-supplementary-unicast;
 			altr,enable-sup-addr = <1>;
diff --git a/kernel/arch/nios2/boot/dts/3c120_devboard.dts b/kernel/arch/nios2/boot/dts/3c120_devboard.dts
index d10fb81..3ee3169 100644
--- a/kernel/arch/nios2/boot/dts/3c120_devboard.dts
+++ b/kernel/arch/nios2/boot/dts/3c120_devboard.dts
@@ -106,7 +106,7 @@
 				interrupt-names = "rx_irq", "tx_irq";
 				rx-fifo-depth = <8192>;
 				tx-fifo-depth = <8192>;
-				max-frame-size = <1518>;
+				max-frame-size = <1500>;
 				local-mac-address = [ 00 00 00 00 00 00 ];
 				phy-mode = "rgmii-id";
 				phy-handle = <&phy0>;
diff --git a/kernel/arch/nios2/kernel/traps.c b/kernel/arch/nios2/kernel/traps.c
index b172da4..8620817 100644
--- a/kernel/arch/nios2/kernel/traps.c
+++ b/kernel/arch/nios2/kernel/traps.c
@@ -37,10 +37,10 @@
 	show_regs(regs);
 	spin_unlock_irq(&die_lock);
 	/*
-	 * do_exit() should take care of panic'ing from an interrupt
+	 * make_task_dead() should take care of panic'ing from an interrupt
 	 * context so we don't handle it here
 	 */
-	do_exit(err);
+	make_task_dead(err);
 }
 
 void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr)
diff --git a/kernel/arch/openrisc/kernel/entry.S b/kernel/arch/openrisc/kernel/entry.S
index b42d32d..7257e94 100644
--- a/kernel/arch/openrisc/kernel/entry.S
+++ b/kernel/arch/openrisc/kernel/entry.S
@@ -173,7 +173,6 @@
 	l.sw    PT_GPR28(r1),r28					;\
 	l.sw    PT_GPR29(r1),r29					;\
 	/* r30 already save */					;\
-/*        l.sw    PT_GPR30(r1),r30*/					;\
 	l.sw    PT_GPR31(r1),r31					;\
 	TRACE_IRQS_OFF_ENTRY						;\
 	/* Store -1 in orig_gpr11 for non-syscall exceptions */	;\
@@ -211,9 +210,8 @@
 	l.sw    PT_GPR27(r1),r27					;\
 	l.sw    PT_GPR28(r1),r28					;\
 	l.sw    PT_GPR29(r1),r29					;\
-	/* r31 already saved */					;\
-	l.sw    PT_GPR30(r1),r30					;\
-/*        l.sw    PT_GPR31(r1),r31	*/				;\
+	/* r30 already saved */						;\
+	l.sw    PT_GPR31(r1),r31					;\
 	/* Store -1 in orig_gpr11 for non-syscall exceptions */	;\
 	l.addi	r30,r0,-1					;\
 	l.sw	PT_ORIG_GPR11(r1),r30				;\
diff --git a/kernel/arch/openrisc/kernel/traps.c b/kernel/arch/openrisc/kernel/traps.c
index 206e532..fca5317 100644
--- a/kernel/arch/openrisc/kernel/traps.c
+++ b/kernel/arch/openrisc/kernel/traps.c
@@ -212,7 +212,7 @@
 	__asm__ __volatile__("l.nop   1");
 	do {} while (1);
 #endif
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
 
 /* This is normally the 'Oops' routine */
diff --git a/kernel/arch/parisc/include/asm/bugs.h b/kernel/arch/parisc/include/asm/bugs.h
deleted file mode 100644
index 0a7f9db..0000000
--- a/kernel/arch/parisc/include/asm/bugs.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- *  include/asm-parisc/bugs.h
- *
- *  Copyright (C) 1999	Mike Shaver
- */
-
-/*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Needs:
- *	void check_bugs(void);
- */
-
-#include <asm/processor.h>
-
-static inline void check_bugs(void)
-{
-//	identify_cpu(&boot_cpu_data);
-}
diff --git a/kernel/arch/parisc/include/asm/cacheflush.h b/kernel/arch/parisc/include/asm/cacheflush.h
index 99663fc..cc9d096 100644
--- a/kernel/arch/parisc/include/asm/cacheflush.h
+++ b/kernel/arch/parisc/include/asm/cacheflush.h
@@ -57,6 +57,11 @@
 
 #define flush_dcache_mmap_lock(mapping)		xa_lock_irq(&mapping->i_pages)
 #define flush_dcache_mmap_unlock(mapping)	xa_unlock_irq(&mapping->i_pages)
+#define flush_dcache_mmap_lock_irqsave(mapping, flags)		\
+		xa_lock_irqsave(&mapping->i_pages, flags)
+#define flush_dcache_mmap_unlock_irqrestore(mapping, flags)	\
+		xa_unlock_irqrestore(&mapping->i_pages, flags)
+
 
 #define flush_icache_page(vma,page)	do { 		\
 	flush_kernel_dcache_page(page);			\
diff --git a/kernel/arch/parisc/include/asm/ldcw.h b/kernel/arch/parisc/include/asm/ldcw.h
index 6d28b55..10a061d 100644
--- a/kernel/arch/parisc/include/asm/ldcw.h
+++ b/kernel/arch/parisc/include/asm/ldcw.h
@@ -2,14 +2,28 @@
 #ifndef __PARISC_LDCW_H
 #define __PARISC_LDCW_H
 
-#ifndef CONFIG_PA20
 /* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data,
    and GCC only guarantees 8-byte alignment for stack locals, we can't
    be assured of 16-byte alignment for atomic lock data even if we
    specify "__attribute ((aligned(16)))" in the type declaration.  So,
    we use a struct containing an array of four ints for the atomic lock
    type and dynamically select the 16-byte aligned int from the array
-   for the semaphore.  */
+   for the semaphore. */
+
+/* From: "Jim Hull" <jim.hull of hp.com>
+   I've attached a summary of the change, but basically, for PA 2.0, as
+   long as the ",CO" (coherent operation) completer is implemented, then the
+   16-byte alignment requirement for ldcw and ldcd is relaxed, and instead
+   they only require "natural" alignment (4-byte for ldcw, 8-byte for
+   ldcd).
+
+   Although the cache control hint is accepted by all PA 2.0 processors,
+   it is only implemented on PA8800/PA8900 CPUs. Prior PA8X00 CPUs still
+   require 16-byte alignment. If the address is unaligned, the operation
+   of the instruction is undefined. The ldcw instruction does not generate
+   unaligned data reference traps so misaligned accesses are not detected.
+   This hid the problem for years. So, restore the 16-byte alignment dropped
+   by Kyle McMartin in "Remove __ldcw_align for PA-RISC 2.0 processors". */
 
 #define __PA_LDCW_ALIGNMENT	16
 #define __PA_LDCW_ALIGN_ORDER	4
@@ -19,22 +33,12 @@
 		& ~(__PA_LDCW_ALIGNMENT - 1);			\
 	(volatile unsigned int *) __ret;			\
 })
-#define __LDCW	"ldcw"
 
-#else /*CONFIG_PA20*/
-/* From: "Jim Hull" <jim.hull of hp.com>
-   I've attached a summary of the change, but basically, for PA 2.0, as
-   long as the ",CO" (coherent operation) completer is specified, then the
-   16-byte alignment requirement for ldcw and ldcd is relaxed, and instead
-   they only require "natural" alignment (4-byte for ldcw, 8-byte for
-   ldcd). */
-
-#define __PA_LDCW_ALIGNMENT	4
-#define __PA_LDCW_ALIGN_ORDER	2
-#define __ldcw_align(a) (&(a)->slock)
+#ifdef CONFIG_PA20
 #define __LDCW	"ldcw,co"
-
-#endif /*!CONFIG_PA20*/
+#else
+#define __LDCW	"ldcw"
+#endif
 
 /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*.
    We don't explicitly expose that "*a" may be written as reload
diff --git a/kernel/arch/parisc/include/asm/led.h b/kernel/arch/parisc/include/asm/led.h
index 6de13d0..b70b909 100644
--- a/kernel/arch/parisc/include/asm/led.h
+++ b/kernel/arch/parisc/include/asm/led.h
@@ -11,8 +11,8 @@
 #define	LED1		0x02
 #define	LED0		0x01		/* bottom (or furthest left) LED */
 
-#define	LED_LAN_TX	LED0		/* for LAN transmit activity */
-#define	LED_LAN_RCV	LED1		/* for LAN receive activity */
+#define	LED_LAN_RCV	LED0		/* for LAN receive activity */
+#define	LED_LAN_TX	LED1		/* for LAN transmit activity */
 #define	LED_DISK_IO	LED2		/* for disk activity */
 #define	LED_HEARTBEAT	LED3		/* heartbeat */
 
diff --git a/kernel/arch/parisc/include/asm/pgtable.h b/kernel/arch/parisc/include/asm/pgtable.h
index 8964798..ade5919 100644
--- a/kernel/arch/parisc/include/asm/pgtable.h
+++ b/kernel/arch/parisc/include/asm/pgtable.h
@@ -330,8 +330,8 @@
 
 
 #if CONFIG_PGTABLE_LEVELS == 3
-#define pud_page_vaddr(pud) ((unsigned long) __va(pud_address(pud)))
-#define pud_page(pud)	virt_to_page((void *)pud_page_vaddr(pud))
+#define pud_pgtable(pud) ((pmd_t *) __va(pud_address(pud)))
+#define pud_page(pud)	virt_to_page((void *)pud_pgtable(pud))
 
 /* For 64 bit we have three level tables */
 
diff --git a/kernel/arch/parisc/include/asm/processor.h b/kernel/arch/parisc/include/asm/processor.h
index 6e2a817..40135be 100644
--- a/kernel/arch/parisc/include/asm/processor.h
+++ b/kernel/arch/parisc/include/asm/processor.h
@@ -97,7 +97,6 @@
 	unsigned long cpu_loc;      /* CPU location from PAT firmware */
 	unsigned int state;
 	struct parisc_device *dev;
-	unsigned long loops_per_jiffy;
 };
 
 extern struct system_cpuinfo_parisc boot_cpu_data;
diff --git a/kernel/arch/parisc/include/asm/ropes.h b/kernel/arch/parisc/include/asm/ropes.h
index 8e51c77..62399c7 100644
--- a/kernel/arch/parisc/include/asm/ropes.h
+++ b/kernel/arch/parisc/include/asm/ropes.h
@@ -86,6 +86,9 @@
 	struct ioc		ioc[MAX_IOC];
 };
 
+/* list of SBA's in system, see drivers/parisc/sba_iommu.c */
+extern struct sba_device *sba_list;
+
 #define ASTRO_RUNWAY_PORT	0x582
 #define IKE_MERCED_PORT		0x803
 #define REO_MERCED_PORT		0x804
diff --git a/kernel/arch/parisc/include/asm/spinlock_types.h b/kernel/arch/parisc/include/asm/spinlock_types.h
index ca39ee3..35c5086 100644
--- a/kernel/arch/parisc/include/asm/spinlock_types.h
+++ b/kernel/arch/parisc/include/asm/spinlock_types.h
@@ -3,13 +3,8 @@
 #define __ASM_SPINLOCK_TYPES_H
 
 typedef struct {
-#ifdef CONFIG_PA20
-	volatile unsigned int slock;
-# define __ARCH_SPIN_LOCK_UNLOCKED { 1 }
-#else
 	volatile unsigned int lock[4];
 # define __ARCH_SPIN_LOCK_UNLOCKED	{ { 1, 1, 1, 1 } }
-#endif
 } arch_spinlock_t;
 
 
diff --git a/kernel/arch/parisc/include/uapi/asm/mman.h b/kernel/arch/parisc/include/uapi/asm/mman.h
index ab78cba..ef9b53b 100644
--- a/kernel/arch/parisc/include/uapi/asm/mman.h
+++ b/kernel/arch/parisc/include/uapi/asm/mman.h
@@ -49,28 +49,27 @@
 #define MADV_DONTFORK	10		/* don't inherit across fork */
 #define MADV_DOFORK	11		/* do inherit across fork */
 
+#define MADV_MERGEABLE   12		/* KSM may merge identical pages */
+#define MADV_UNMERGEABLE 13		/* KSM may not merge identical pages */
+
+#define MADV_HUGEPAGE	14		/* Worth backing with hugepages */
+#define MADV_NOHUGEPAGE 15		/* Not worth backing with hugepages */
+
+#define MADV_DONTDUMP   16		/* Explicity exclude from the core dump,
+					   overrides the coredump filter bits */
+#define MADV_DODUMP	17		/* Clear the MADV_NODUMP flag */
+
+#define MADV_WIPEONFORK 18		/* Zero memory on fork, child only */
+#define MADV_KEEPONFORK 19		/* Undo MADV_WIPEONFORK */
+
 #define MADV_COLD	20		/* deactivate these pages */
 #define MADV_PAGEOUT	21		/* reclaim these pages */
-
-#define MADV_MERGEABLE   65		/* KSM may merge identical pages */
-#define MADV_UNMERGEABLE 66		/* KSM may not merge identical pages */
-
-#define MADV_HUGEPAGE	67		/* Worth backing with hugepages */
-#define MADV_NOHUGEPAGE	68		/* Not worth backing with hugepages */
-
-#define MADV_DONTDUMP   69		/* Explicity exclude from the core dump,
-					   overrides the coredump filter bits */
-#define MADV_DODUMP	70		/* Clear the MADV_NODUMP flag */
-
-#define MADV_WIPEONFORK 71		/* Zero memory on fork, child only */
-#define MADV_KEEPONFORK 72		/* Undo MADV_WIPEONFORK */
 
 #define MADV_HWPOISON     100		/* poison a page for testing */
 #define MADV_SOFT_OFFLINE 101		/* soft offline page for testing */
 
 /* compatibility flags */
 #define MAP_FILE	0
-#define MAP_VARIABLE	0
 
 #define PKEY_DISABLE_ACCESS	0x1
 #define PKEY_DISABLE_WRITE	0x2
diff --git a/kernel/arch/parisc/include/uapi/asm/socket.h b/kernel/arch/parisc/include/uapi/asm/socket.h
index 10173c3..1a8ec38 100644
--- a/kernel/arch/parisc/include/uapi/asm/socket.h
+++ b/kernel/arch/parisc/include/uapi/asm/socket.h
@@ -116,6 +116,8 @@
 
 #define SO_DETACH_REUSEPORT_BPF 0x4042
 
+#define SO_NETNS_COOKIE		0x4045
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64
diff --git a/kernel/arch/parisc/kernel/cache.c b/kernel/arch/parisc/kernel/cache.c
index c81ab0c..efa8d2a 100644
--- a/kernel/arch/parisc/kernel/cache.c
+++ b/kernel/arch/parisc/kernel/cache.c
@@ -327,6 +327,7 @@
 	struct vm_area_struct *mpnt;
 	unsigned long offset;
 	unsigned long addr, old_addr = 0;
+	unsigned long flags;
 	pgoff_t pgoff;
 
 	if (mapping && !mapping_mapped(mapping)) {
@@ -346,7 +347,7 @@
 	 * declared as MAP_PRIVATE or MAP_SHARED), so we only need
 	 * to flush one address here for them all to become coherent */
 
-	flush_dcache_mmap_lock(mapping);
+	flush_dcache_mmap_lock_irqsave(mapping, flags);
 	vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) {
 		offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
 		addr = mpnt->vm_start + offset;
@@ -369,7 +370,7 @@
 			old_addr = addr;
 		}
 	}
-	flush_dcache_mmap_unlock(mapping);
+	flush_dcache_mmap_unlock_irqrestore(mapping, flags);
 }
 EXPORT_SYMBOL(flush_dcache_page);
 
diff --git a/kernel/arch/parisc/kernel/drivers.c b/kernel/arch/parisc/kernel/drivers.c
index d951574..d11a312 100644
--- a/kernel/arch/parisc/kernel/drivers.c
+++ b/kernel/arch/parisc/kernel/drivers.c
@@ -925,9 +925,9 @@
 	pr_info("#define PARISC_MODEL \"%s\"\n\n",
 			boot_cpu_data.pdc.sys_model_name);
 
+	#define p ((unsigned long *)&boot_cpu_data.pdc.model)
 	pr_info("#define PARISC_PDC_MODEL 0x%lx, 0x%lx, 0x%lx, "
 		"0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n\n",
-	#define p ((unsigned long *)&boot_cpu_data.pdc.model)
 		p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]);
 	#undef p
 
diff --git a/kernel/arch/parisc/kernel/firmware.c b/kernel/arch/parisc/kernel/firmware.c
index 665b700..7ed28dd 100644
--- a/kernel/arch/parisc/kernel/firmware.c
+++ b/kernel/arch/parisc/kernel/firmware.c
@@ -1230,7 +1230,7 @@
  */
 int pdc_iodc_print(const unsigned char *str, unsigned count)
 {
-	unsigned int i;
+	unsigned int i, found = 0;
 	unsigned long flags;
 
 	for (i = 0; i < count;) {
@@ -1239,6 +1239,7 @@
 			iodc_dbuf[i+0] = '\r';
 			iodc_dbuf[i+1] = '\n';
 			i += 2;
+			found = 1;
 			goto print;
 		default:
 			iodc_dbuf[i] = str[i];
@@ -1255,7 +1256,7 @@
                     __pa(iodc_retbuf), 0, __pa(iodc_dbuf), i, 0);
         spin_unlock_irqrestore(&pdc_lock, flags);
 
-	return i;
+	return i - found;
 }
 
 #if !defined(BOOTLOADER)
diff --git a/kernel/arch/parisc/kernel/irq.c b/kernel/arch/parisc/kernel/irq.c
index 60f5829..2762e85 100644
--- a/kernel/arch/parisc/kernel/irq.c
+++ b/kernel/arch/parisc/kernel/irq.c
@@ -388,7 +388,7 @@
 	volatile unsigned int lock[1];
 };
 
-DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = {
+static DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = {
 		.slock = { 1,1,1,1 },
 	};
 #endif
diff --git a/kernel/arch/parisc/kernel/pci-dma.c b/kernel/arch/parisc/kernel/pci-dma.c
index 36610a5..fc90ccf 100644
--- a/kernel/arch/parisc/kernel/pci-dma.c
+++ b/kernel/arch/parisc/kernel/pci-dma.c
@@ -446,11 +446,27 @@
 void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
 		enum dma_data_direction dir)
 {
+	/*
+	 * fdc: The data cache line is written back to memory, if and only if
+	 * it is dirty, and then invalidated from the data cache.
+	 */
 	flush_kernel_dcache_range((unsigned long)phys_to_virt(paddr), size);
 }
 
 void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 		enum dma_data_direction dir)
 {
-	flush_kernel_dcache_range((unsigned long)phys_to_virt(paddr), size);
+	unsigned long addr = (unsigned long) phys_to_virt(paddr);
+
+	switch (dir) {
+	case DMA_TO_DEVICE:
+	case DMA_BIDIRECTIONAL:
+		flush_kernel_dcache_range(addr, size);
+		return;
+	case DMA_FROM_DEVICE:
+		purge_kernel_dcache_range_asm(addr, addr + size);
+		return;
+	default:
+		BUG();
+	}
 }
diff --git a/kernel/arch/parisc/kernel/process.c b/kernel/arch/parisc/kernel/process.c
index 5e43812..c14ee40 100644
--- a/kernel/arch/parisc/kernel/process.c
+++ b/kernel/arch/parisc/kernel/process.c
@@ -123,13 +123,18 @@
 	/* It seems we have no way to power the system off via
 	 * software. The user has to press the button himself. */
 
-	printk(KERN_EMERG "System shut down completed.\n"
-	       "Please power this system off now.");
+	printk("Power off or press RETURN to reboot.\n");
 
 	/* prevent soft lockup/stalled CPU messages for endless loop. */
 	rcu_sysrq_start();
 	lockup_detector_soft_poweroff();
-	for (;;);
+	while (1) {
+		/* reboot if user presses RETURN key */
+		if (pdc_iodc_getc() == 13) {
+			printk("Rebooting...\n");
+			machine_restart(NULL);
+		}
+	}
 }
 
 void (*pm_power_off)(void);
diff --git a/kernel/arch/parisc/kernel/processor.c b/kernel/arch/parisc/kernel/processor.c
index 176ef00..ccdbcfd 100644
--- a/kernel/arch/parisc/kernel/processor.c
+++ b/kernel/arch/parisc/kernel/processor.c
@@ -163,7 +163,6 @@
 	if (cpuid)
 		memset(p, 0, sizeof(struct cpuinfo_parisc));
 
-	p->loops_per_jiffy = loops_per_jiffy;
 	p->dev = dev;		/* Save IODC data in case we need it */
 	p->hpa = dev->hpa.start;	/* save CPU hpa */
 	p->cpuid = cpuid;	/* save CPU id */
@@ -373,10 +372,18 @@
 show_cpuinfo (struct seq_file *m, void *v)
 {
 	unsigned long cpu;
+	char cpu_name[60], *p;
+
+	/* strip PA path from CPU name to not confuse lscpu */
+	strlcpy(cpu_name, per_cpu(cpu_data, 0).dev->name, sizeof(cpu_name));
+	p = strrchr(cpu_name, '[');
+	if (p)
+		*(--p) = 0;
 
 	for_each_online_cpu(cpu) {
-		const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
 #ifdef CONFIG_SMP
+		const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
+
 		if (0 == cpuinfo->hpa)
 			continue;
 #endif
@@ -421,8 +428,7 @@
 
 		seq_printf(m, "model\t\t: %s - %s\n",
 				 boot_cpu_data.pdc.sys_model_name,
-				 cpuinfo->dev ?
-				 cpuinfo->dev->name : "Unknown");
+				 cpu_name);
 
 		seq_printf(m, "hversion\t: 0x%08x\n"
 			        "sversion\t: 0x%08x\n",
@@ -433,8 +439,8 @@
 		show_cache_info(m);
 
 		seq_printf(m, "bogomips\t: %lu.%02lu\n",
-			     cpuinfo->loops_per_jiffy / (500000 / HZ),
-			     (cpuinfo->loops_per_jiffy / (5000 / HZ)) % 100);
+			     loops_per_jiffy / (500000 / HZ),
+			     loops_per_jiffy / (5000 / HZ) % 100);
 
 		seq_printf(m, "software id\t: %ld\n\n",
 				boot_cpu_data.pdc.model.sw_id);
diff --git a/kernel/arch/parisc/kernel/ptrace.c b/kernel/arch/parisc/kernel/ptrace.c
index 2127974..df9b9f0 100644
--- a/kernel/arch/parisc/kernel/ptrace.c
+++ b/kernel/arch/parisc/kernel/ptrace.c
@@ -127,6 +127,12 @@
 	unsigned long tmp;
 	long ret = -EIO;
 
+	unsigned long user_regs_struct_size = sizeof(struct user_regs_struct);
+#ifdef CONFIG_64BIT
+	if (is_compat_task())
+		user_regs_struct_size /= 2;
+#endif
+
 	switch (request) {
 
 	/* Read the word at location addr in the USER area.  For ptraced
@@ -182,14 +188,14 @@
 		return copy_regset_to_user(child,
 					   task_user_regset_view(current),
 					   REGSET_GENERAL,
-					   0, sizeof(struct user_regs_struct),
+					   0, user_regs_struct_size,
 					   datap);
 
 	case PTRACE_SETREGS:	/* Set all gp regs in the child. */
 		return copy_regset_from_user(child,
 					     task_user_regset_view(current),
 					     REGSET_GENERAL,
-					     0, sizeof(struct user_regs_struct),
+					     0, user_regs_struct_size,
 					     datap);
 
 	case PTRACE_GETFPREGS:	/* Get the child FPU state. */
@@ -303,6 +309,11 @@
 			}
 		}
 		break;
+	case PTRACE_GETREGS:
+	case PTRACE_SETREGS:
+	case PTRACE_GETFPREGS:
+	case PTRACE_SETFPREGS:
+		return arch_ptrace(child, request, addr, data);
 
 	default:
 		ret = compat_ptrace_request(child, request, addr, data);
diff --git a/kernel/arch/parisc/kernel/real2.S b/kernel/arch/parisc/kernel/real2.S
index 2b16d8d..c37010a 100644
--- a/kernel/arch/parisc/kernel/real2.S
+++ b/kernel/arch/parisc/kernel/real2.S
@@ -248,9 +248,6 @@
 	/* save fn */
 	copy	%arg2, %r31
 
-	/* set up the new ap */
-	ldo	64(%arg1), %r29
-
 	/* load up the arg registers from the saved arg area */
 	/* 32-bit calling convention passes first 4 args in registers */
 	ldd	0*REG_SZ(%arg1), %arg0		/* note overwriting arg0 */
@@ -262,7 +259,9 @@
 	ldd	7*REG_SZ(%arg1), %r19
 	ldd	1*REG_SZ(%arg1), %arg1		/* do this one last! */
 
+	/* set up real-mode stack and real-mode ap */
 	tophys_r1 %sp
+	ldo	-16(%sp), %r29			/* Reference param save area */
 
 	b,l	rfi_virt2real,%r2
 	nop
diff --git a/kernel/arch/parisc/kernel/sys_parisc.c b/kernel/arch/parisc/kernel/sys_parisc.c
index 9549496..40f881f 100644
--- a/kernel/arch/parisc/kernel/sys_parisc.c
+++ b/kernel/arch/parisc/kernel/sys_parisc.c
@@ -444,3 +444,30 @@
 	flags = FIX_O_NONBLOCK(flags);
 	return sys_inotify_init1(flags);
 }
+
+/*
+ * madvise() wrapper
+ *
+ * Up to kernel v6.1 parisc has different values than all other
+ * platforms for the MADV_xxx flags listed below.
+ * To keep binary compatibility with existing userspace programs
+ * translate the former values to the new values.
+ *
+ * XXX: Remove this wrapper in year 2025 (or later)
+ */
+
+asmlinkage notrace long parisc_madvise(unsigned long start, size_t len_in, int behavior)
+{
+	switch (behavior) {
+	case 65: behavior = MADV_MERGEABLE;	break;
+	case 66: behavior = MADV_UNMERGEABLE;	break;
+	case 67: behavior = MADV_HUGEPAGE;	break;
+	case 68: behavior = MADV_NOHUGEPAGE;	break;
+	case 69: behavior = MADV_DONTDUMP;	break;
+	case 70: behavior = MADV_DODUMP;	break;
+	case 71: behavior = MADV_WIPEONFORK;	break;
+	case 72: behavior = MADV_KEEPONFORK;	break;
+	}
+
+	return sys_madvise(start, len_in, behavior);
+}
diff --git a/kernel/arch/parisc/kernel/syscalls/syscall.tbl b/kernel/arch/parisc/kernel/syscalls/syscall.tbl
index 4827f18..14fd2a0 100644
--- a/kernel/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/kernel/arch/parisc/kernel/syscalls/syscall.tbl
@@ -131,7 +131,7 @@
 116	common	sysinfo			sys_sysinfo			compat_sys_sysinfo
 117	common	shutdown		sys_shutdown
 118	common	fsync			sys_fsync
-119	common	madvise			sys_madvise
+119	common	madvise			parisc_madvise
 120	common	clone			sys_clone_wrapper
 121	common	setdomainname		sys_setdomainname
 122	common	sendfile		sys_sendfile			compat_sys_sendfile
diff --git a/kernel/arch/parisc/kernel/traps.c b/kernel/arch/parisc/kernel/traps.c
index bce47e0..bd09050 100644
--- a/kernel/arch/parisc/kernel/traps.c
+++ b/kernel/arch/parisc/kernel/traps.c
@@ -268,7 +268,7 @@
 		panic("Fatal exception");
 
 	oops_exit();
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
 
 /* gdb uses break 4,8 */
@@ -305,8 +305,8 @@
 #endif
 
 #ifdef CONFIG_KGDB
-	if (unlikely(iir == PARISC_KGDB_COMPILED_BREAK_INSN ||
-		iir == PARISC_KGDB_BREAK_INSN)) {
+	if (unlikely((iir == PARISC_KGDB_COMPILED_BREAK_INSN ||
+		iir == PARISC_KGDB_BREAK_INSN)) && !user_mode(regs)) {
 		kgdb_handle_exception(9, SIGTRAP, 0, regs);
 		return;
 	}
diff --git a/kernel/arch/powerpc/Kconfig.debug b/kernel/arch/powerpc/Kconfig.debug
index 52abca8..e03fb91 100644
--- a/kernel/arch/powerpc/Kconfig.debug
+++ b/kernel/arch/powerpc/Kconfig.debug
@@ -234,7 +234,7 @@
 
 config PPC_EARLY_DEBUG_CPM
 	bool "Early serial debugging for Freescale CPM-based serial ports"
-	depends on SERIAL_CPM
+	depends on SERIAL_CPM=y
 	help
 	  Select this to enable early debugging for Freescale chips
 	  using a CPM-based serial port.  This assumes that the bootwrapper
diff --git a/kernel/arch/powerpc/Makefile b/kernel/arch/powerpc/Makefile
index 6122541..912e64a 100644
--- a/kernel/arch/powerpc/Makefile
+++ b/kernel/arch/powerpc/Makefile
@@ -92,7 +92,7 @@
 
 ifeq ($(HAS_BIARCH),y)
 KBUILD_CFLAGS	+= -m$(BITS)
-KBUILD_AFLAGS	+= -m$(BITS) -Wl,-a$(BITS)
+KBUILD_AFLAGS	+= -m$(BITS)
 KBUILD_LDFLAGS	+= -m elf$(BITS)$(LDEMULATION)
 endif
 
@@ -429,3 +429,11 @@
 		echo -n '*** Please use a different binutils version.' ; \
 		false ; \
 	fi
+	@if test "x${CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT}" = "xy" -a \
+		"x${CONFIG_LD_IS_BFD}" = "xy" -a \
+		"${CONFIG_LD_VERSION}" = "23700" ; then \
+		echo -n '*** binutils 2.37 drops unused section symbols, which recordmcount ' ; \
+		echo 'is unable to handle.' ; \
+		echo '*** Please use a different binutils version.' ; \
+		false ; \
+	fi
diff --git a/kernel/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi b/kernel/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi
new file mode 100644
index 0000000..437dab3
--- /dev/null
+++ b/kernel/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/kernel/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi b/kernel/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi
new file mode 100644
index 0000000..ad116b1
--- /dev/null
+++ b/kernel/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/kernel/arch/powerpc/boot/dts/fsl/t1040rdb-rev-a.dts b/kernel/arch/powerpc/boot/dts/fsl/t1040rdb-rev-a.dts
index 73f8c99..d4f5f15 100644
--- a/kernel/arch/powerpc/boot/dts/fsl/t1040rdb-rev-a.dts
+++ b/kernel/arch/powerpc/boot/dts/fsl/t1040rdb-rev-a.dts
@@ -10,7 +10,6 @@
 
 / {
 	model = "fsl,T1040RDB-REV-A";
-	compatible = "fsl,T1040RDB-REV-A";
 };
 
 &seville_port0 {
diff --git a/kernel/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi b/kernel/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
index ecbb447..27714dc 100644
--- a/kernel/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
+++ b/kernel/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
@@ -609,8 +609,8 @@
 /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"
@@ -659,3 +659,19 @@
 		interrupts = <16 2 1 9>;
 	};
 };
+
+&fman0_rx_0x08 {
+	/delete-property/ fsl,fman-10g-port;
+};
+
+&fman0_tx_0x28 {
+	/delete-property/ fsl,fman-10g-port;
+};
+
+&fman0_rx_0x09 {
+	/delete-property/ fsl,fman-10g-port;
+};
+
+&fman0_tx_0x29 {
+	/delete-property/ fsl,fman-10g-port;
+};
diff --git a/kernel/arch/powerpc/configs/ppc6xx_defconfig b/kernel/arch/powerpc/configs/ppc6xx_defconfig
index 66e9a0f..021da67 100644
--- a/kernel/arch/powerpc/configs/ppc6xx_defconfig
+++ b/kernel/arch/powerpc/configs/ppc6xx_defconfig
@@ -245,8 +245,6 @@
 CONFIG_ATM_BR2684=m
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
-CONFIG_DECNET=m
-CONFIG_DECNET_ROUTER=y
 CONFIG_ATALK=m
 CONFIG_DEV_APPLETALK=m
 CONFIG_IPDDP=m
diff --git a/kernel/arch/powerpc/include/asm/book3s/64/pgtable.h b/kernel/arch/powerpc/include/asm/book3s/64/pgtable.h
index 71e2c52..2b4af82 100644
--- a/kernel/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/kernel/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -1030,8 +1030,15 @@
 /* Pointers in the page table tree are physical addresses */
 #define __pgtable_ptr_val(ptr)	__pa(ptr)
 
-#define pud_page_vaddr(pud)	__va(pud_val(pud) & ~PUD_MASKED_BITS)
-#define p4d_page_vaddr(p4d)	__va(p4d_val(p4d) & ~P4D_MASKED_BITS)
+static inline pud_t *p4d_pgtable(p4d_t p4d)
+{
+	return (pud_t *)__va(p4d_val(p4d) & ~P4D_MASKED_BITS);
+}
+
+static inline pmd_t *pud_pgtable(pud_t pud)
+{
+	return (pmd_t *)__va(pud_val(pud) & ~PUD_MASKED_BITS);
+}
 
 #define pte_ERROR(e) \
 	pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
diff --git a/kernel/arch/powerpc/include/asm/bugs.h b/kernel/arch/powerpc/include/asm/bugs.h
deleted file mode 100644
index 01b8f6c..0000000
--- a/kernel/arch/powerpc/include/asm/bugs.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef _ASM_POWERPC_BUGS_H
-#define _ASM_POWERPC_BUGS_H
-
-/*
- */
-
-/*
- * This file is included by 'init/main.c' to check for
- * architecture-dependent bugs.
- */
-
-static inline void check_bugs(void) { }
-
-#endif	/* _ASM_POWERPC_BUGS_H */
diff --git a/kernel/arch/powerpc/include/asm/firmware.h b/kernel/arch/powerpc/include/asm/firmware.h
index aa6a5ef..89a31f1 100644
--- a/kernel/arch/powerpc/include/asm/firmware.h
+++ b/kernel/arch/powerpc/include/asm/firmware.h
@@ -44,7 +44,7 @@
 #define FW_FEATURE_OPAL		ASM_CONST(0x0000000010000000)
 #define FW_FEATURE_SET_MODE	ASM_CONST(0x0000000040000000)
 #define FW_FEATURE_BEST_ENERGY	ASM_CONST(0x0000000080000000)
-#define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0000000100000000)
+#define FW_FEATURE_FORM1_AFFINITY ASM_CONST(0x0000000100000000)
 #define FW_FEATURE_PRRN		ASM_CONST(0x0000000200000000)
 #define FW_FEATURE_DRMEM_V2	ASM_CONST(0x0000000400000000)
 #define FW_FEATURE_DRC_INFO	ASM_CONST(0x0000000800000000)
@@ -53,6 +53,7 @@
 #define FW_FEATURE_ULTRAVISOR	ASM_CONST(0x0000004000000000)
 #define FW_FEATURE_STUFF_TCE	ASM_CONST(0x0000008000000000)
 #define FW_FEATURE_RPT_INVALIDATE ASM_CONST(0x0000010000000000)
+#define FW_FEATURE_FORM2_AFFINITY ASM_CONST(0x0000020000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -69,11 +70,11 @@
 		FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
 		FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO |
 		FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY |
-		FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN |
+		FW_FEATURE_FORM1_AFFINITY | FW_FEATURE_PRRN |
 		FW_FEATURE_HPT_RESIZE | FW_FEATURE_DRMEM_V2 |
 		FW_FEATURE_DRC_INFO | FW_FEATURE_BLOCK_REMOVE |
 		FW_FEATURE_PAPR_SCM | FW_FEATURE_ULTRAVISOR |
-		FW_FEATURE_RPT_INVALIDATE,
+		FW_FEATURE_RPT_INVALIDATE | FW_FEATURE_FORM2_AFFINITY,
 	FW_FEATURE_PSERIES_ALWAYS = 0,
 	FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_ULTRAVISOR,
 	FW_FEATURE_POWERNV_ALWAYS = 0,
diff --git a/kernel/arch/powerpc/include/asm/imc-pmu.h b/kernel/arch/powerpc/include/asm/imc-pmu.h
index 4f89799..699a885 100644
--- a/kernel/arch/powerpc/include/asm/imc-pmu.h
+++ b/kernel/arch/powerpc/include/asm/imc-pmu.h
@@ -137,7 +137,7 @@
  * are inited.
  */
 struct imc_pmu_ref {
-	struct mutex lock;
+	spinlock_t lock;
 	unsigned int id;
 	int refc;
 };
diff --git a/kernel/arch/powerpc/include/asm/lppaca.h b/kernel/arch/powerpc/include/asm/lppaca.h
index c390ec3..1412e64 100644
--- a/kernel/arch/powerpc/include/asm/lppaca.h
+++ b/kernel/arch/powerpc/include/asm/lppaca.h
@@ -45,6 +45,7 @@
 #include <asm/types.h>
 #include <asm/mmu.h>
 #include <asm/firmware.h>
+#include <asm/paca.h>
 
 /*
  * The lppaca is the "virtual processor area" registered with the hypervisor,
@@ -123,13 +124,23 @@
  */
 #define LPPACA_OLD_SHARED_PROC		2
 
-static inline bool lppaca_shared_proc(struct lppaca *l)
+#ifdef CONFIG_PPC_PSERIES
+/*
+ * All CPUs should have the same shared proc value, so directly access the PACA
+ * to avoid false positives from DEBUG_PREEMPT.
+ */
+static inline bool lppaca_shared_proc(void)
 {
+	struct lppaca *l = local_paca->lppaca_ptr;
+
 	if (!firmware_has_feature(FW_FEATURE_SPLPAR))
 		return false;
 	return !!(l->__old_status & LPPACA_OLD_SHARED_PROC);
 }
 
+#define get_lppaca()	(get_paca()->lppaca_ptr)
+#endif
+
 /*
  * SLB shadow buffer structure as defined in the PAPR.  The save_area
  * contains adjacent ESID and VSID pairs for each shadowed SLB.  The
diff --git a/kernel/arch/powerpc/include/asm/nohash/64/pgtable-4k.h b/kernel/arch/powerpc/include/asm/nohash/64/pgtable-4k.h
index fe2f4c9..10f5cf4 100644
--- a/kernel/arch/powerpc/include/asm/nohash/64/pgtable-4k.h
+++ b/kernel/arch/powerpc/include/asm/nohash/64/pgtable-4k.h
@@ -56,10 +56,14 @@
 #define p4d_none(p4d)		(!p4d_val(p4d))
 #define p4d_bad(p4d)		(p4d_val(p4d) == 0)
 #define p4d_present(p4d)	(p4d_val(p4d) != 0)
-#define p4d_page_vaddr(p4d)	(p4d_val(p4d) & ~P4D_MASKED_BITS)
 
 #ifndef __ASSEMBLY__
 
+static inline pud_t *p4d_pgtable(p4d_t p4d)
+{
+	return (pud_t *) (p4d_val(p4d) & ~P4D_MASKED_BITS);
+}
+
 static inline void p4d_clear(p4d_t *p4dp)
 {
 	*p4dp = __p4d(0);
diff --git a/kernel/arch/powerpc/include/asm/nohash/64/pgtable.h b/kernel/arch/powerpc/include/asm/nohash/64/pgtable.h
index 1eacff0..a4d475c 100644
--- a/kernel/arch/powerpc/include/asm/nohash/64/pgtable.h
+++ b/kernel/arch/powerpc/include/asm/nohash/64/pgtable.h
@@ -164,7 +164,11 @@
 #define	pud_bad(pud)		(!is_kernel_addr(pud_val(pud)) \
 				 || (pud_val(pud) & PUD_BAD_BITS))
 #define pud_present(pud)	(pud_val(pud) != 0)
-#define pud_page_vaddr(pud)	(pud_val(pud) & ~PUD_MASKED_BITS)
+
+static inline pmd_t *pud_pgtable(pud_t pud)
+{
+	return (pmd_t *)(pud_val(pud) & ~PUD_MASKED_BITS);
+}
 
 extern struct page *pud_page(pud_t pud);
 
diff --git a/kernel/arch/powerpc/include/asm/paca.h b/kernel/arch/powerpc/include/asm/paca.h
index 9454d29..2abced1 100644
--- a/kernel/arch/powerpc/include/asm/paca.h
+++ b/kernel/arch/powerpc/include/asm/paca.h
@@ -12,9 +12,9 @@
 
 #ifdef CONFIG_PPC64
 
+#include <linux/cache.h>
 #include <linux/string.h>
 #include <asm/types.h>
-#include <asm/lppaca.h>
 #include <asm/mmu.h>
 #include <asm/page.h>
 #ifdef CONFIG_PPC_BOOK3E
@@ -45,14 +45,11 @@
 #define get_paca()	local_paca
 #endif
 
-#ifdef CONFIG_PPC_PSERIES
-#define get_lppaca()	(get_paca()->lppaca_ptr)
-#endif
-
 #define get_slb_shadow()	(get_paca()->slb_shadow_ptr)
 
 struct task_struct;
 struct rtas_args;
+struct lppaca;
 
 /*
  * Defines the layout of the paca.
diff --git a/kernel/arch/powerpc/include/asm/paravirt.h b/kernel/arch/powerpc/include/asm/paravirt.h
index 588bfb9..546c725 100644
--- a/kernel/arch/powerpc/include/asm/paravirt.h
+++ b/kernel/arch/powerpc/include/asm/paravirt.h
@@ -6,6 +6,7 @@
 #include <asm/smp.h>
 #ifdef CONFIG_PPC64
 #include <asm/paca.h>
+#include <asm/lppaca.h>
 #include <asm/hvcall.h>
 #endif
 
diff --git a/kernel/arch/powerpc/include/asm/plpar_wrappers.h b/kernel/arch/powerpc/include/asm/plpar_wrappers.h
index ece84a4..7796cc0 100644
--- a/kernel/arch/powerpc/include/asm/plpar_wrappers.h
+++ b/kernel/arch/powerpc/include/asm/plpar_wrappers.h
@@ -9,6 +9,7 @@
 
 #include <asm/hvcall.h>
 #include <asm/paca.h>
+#include <asm/lppaca.h>
 #include <asm/page.h>
 
 static inline long poll_pending(void)
diff --git a/kernel/arch/powerpc/include/asm/prom.h b/kernel/arch/powerpc/include/asm/prom.h
index 324a133..5c80152 100644
--- a/kernel/arch/powerpc/include/asm/prom.h
+++ b/kernel/arch/powerpc/include/asm/prom.h
@@ -147,8 +147,9 @@
 #define OV5_MSI			0x0201	/* PCIe/MSI support */
 #define OV5_CMO			0x0480	/* Cooperative Memory Overcommitment */
 #define OV5_XCMO		0x0440	/* Page Coalescing */
-#define OV5_TYPE1_AFFINITY	0x0580	/* Type 1 NUMA affinity */
+#define OV5_FORM1_AFFINITY	0x0580	/* FORM1 NUMA affinity */
 #define OV5_PRRN		0x0540	/* Platform Resource Reassignment */
+#define OV5_FORM2_AFFINITY	0x0520	/* Form2 NUMA affinity */
 #define OV5_HP_EVT		0x0604	/* Hot Plug Event support */
 #define OV5_RESIZE_HPT		0x0601	/* Hash Page Table resizing */
 #define OV5_PFO_HW_RNG		0x1180	/* PFO Random Number Generator */
diff --git a/kernel/arch/powerpc/include/asm/topology.h b/kernel/arch/powerpc/include/asm/topology.h
index 3beeb03..b239ef5 100644
--- a/kernel/arch/powerpc/include/asm/topology.h
+++ b/kernel/arch/powerpc/include/asm/topology.h
@@ -36,7 +36,7 @@
 				 cpu_all_mask :				\
 				 cpumask_of_node(pcibus_to_node(bus)))
 
-extern int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc);
+int cpu_relative_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc);
 extern int __node_distance(int, int);
 #define node_distance(a, b) __node_distance(a, b)
 
@@ -64,6 +64,7 @@
 }
 
 int of_drconf_to_nid_single(struct drmem_lmb *lmb);
+void update_numa_distance(struct device_node *node);
 
 #else
 
@@ -83,7 +84,7 @@
 
 static inline void update_numa_cpu_lookup_table(unsigned int cpu, int node) {}
 
-static inline int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
+static inline int cpu_relative_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
 {
 	return 0;
 }
@@ -93,6 +94,7 @@
 	return first_online_node;
 }
 
+static inline void update_numa_distance(struct device_node *node) {}
 #endif /* CONFIG_NUMA */
 
 #if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR)
diff --git a/kernel/arch/powerpc/include/asm/word-at-a-time.h b/kernel/arch/powerpc/include/asm/word-at-a-time.h
index f3f4710..99129b0 100644
--- a/kernel/arch/powerpc/include/asm/word-at-a-time.h
+++ b/kernel/arch/powerpc/include/asm/word-at-a-time.h
@@ -34,7 +34,7 @@
 	return leading_zero_bits >> 3;
 }
 
-static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c)
+static inline unsigned long has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c)
 {
 	unsigned long rhs = val | c->low_bits;
 	*data = rhs;
diff --git a/kernel/arch/powerpc/kernel/eeh_driver.c b/kernel/arch/powerpc/kernel/eeh_driver.c
index 3eff6a4..665d847 100644
--- a/kernel/arch/powerpc/kernel/eeh_driver.c
+++ b/kernel/arch/powerpc/kernel/eeh_driver.c
@@ -1054,45 +1054,46 @@
 		}
 
 		pr_info("EEH: Recovery successful.\n");
-	} else  {
-		/*
-		 * About 90% of all real-life EEH failures in the field
-		 * are due to poorly seated PCI cards. Only 10% or so are
-		 * due to actual, failed cards.
-		 */
-		pr_err("EEH: Unable to recover from failure from PHB#%x-PE#%x.\n"
-		       "Please try reseating or replacing it\n",
-			pe->phb->global_number, pe->addr);
+		goto out;
+	}
 
-		eeh_slot_error_detail(pe, EEH_LOG_PERM);
+	/*
+	 * About 90% of all real-life EEH failures in the field
+	 * are due to poorly seated PCI cards. Only 10% or so are
+	 * due to actual, failed cards.
+	 */
+	pr_err("EEH: Unable to recover from failure from PHB#%x-PE#%x.\n"
+		"Please try reseating or replacing it\n",
+		pe->phb->global_number, pe->addr);
 
-		/* Notify all devices that they're about to go down. */
-		eeh_set_channel_state(pe, pci_channel_io_perm_failure);
-		eeh_set_irq_state(pe, false);
-		eeh_pe_report("error_detected(permanent failure)", pe,
-			      eeh_report_failure, NULL);
+	eeh_slot_error_detail(pe, EEH_LOG_PERM);
 
-		/* Mark the PE to be removed permanently */
-		eeh_pe_state_mark(pe, EEH_PE_REMOVED);
+	/* Notify all devices that they're about to go down. */
+	eeh_set_irq_state(pe, false);
+	eeh_pe_report("error_detected(permanent failure)", pe,
+		      eeh_report_failure, NULL);
+	eeh_set_channel_state(pe, pci_channel_io_perm_failure);
 
-		/*
-		 * Shut down the device drivers for good. We mark
-		 * all removed devices correctly to avoid access
-		 * the their PCI config any more.
-		 */
-		if (pe->type & EEH_PE_VF) {
-			eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL);
-			eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
-		} else {
-			eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true);
-			eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
+	/* Mark the PE to be removed permanently */
+	eeh_pe_state_mark(pe, EEH_PE_REMOVED);
 
-			pci_lock_rescan_remove();
-			pci_hp_remove_devices(bus);
-			pci_unlock_rescan_remove();
-			/* The passed PE should no longer be used */
-			return;
-		}
+	/*
+	 * Shut down the device drivers for good. We mark
+	 * all removed devices correctly to avoid access
+	 * the their PCI config any more.
+	 */
+	if (pe->type & EEH_PE_VF) {
+		eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL);
+		eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
+	} else {
+		eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true);
+		eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
+
+		pci_lock_rescan_remove();
+		pci_hp_remove_devices(bus);
+		pci_unlock_rescan_remove();
+		/* The passed PE should no longer be used */
+		return;
 	}
 
 out:
@@ -1188,10 +1189,10 @@
 
 			/* Notify all devices to be down */
 			eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true);
-			eeh_set_channel_state(pe, pci_channel_io_perm_failure);
 			eeh_pe_report(
 				"error_detected(permanent failure)", pe,
 				eeh_report_failure, NULL);
+			eeh_set_channel_state(pe, pci_channel_io_perm_failure);
 
 			pci_lock_rescan_remove();
 			list_for_each_entry(hose, &hose_list, list_node) {
diff --git a/kernel/arch/powerpc/kernel/fadump.c b/kernel/arch/powerpc/kernel/fadump.c
index 1a5ba26..935ce1b 100644
--- a/kernel/arch/powerpc/kernel/fadump.c
+++ b/kernel/arch/powerpc/kernel/fadump.c
@@ -642,6 +642,7 @@
 	return ret;
 error_out:
 	fw_dump.fadump_enabled = 0;
+	fw_dump.reserve_dump_area_size = 0;
 	return 0;
 }
 
diff --git a/kernel/arch/powerpc/kernel/hw_breakpoint.c b/kernel/arch/powerpc/kernel/hw_breakpoint.c
index f4e8f21..6e5bed5 100644
--- a/kernel/arch/powerpc/kernel/hw_breakpoint.c
+++ b/kernel/arch/powerpc/kernel/hw_breakpoint.c
@@ -479,11 +479,13 @@
 	struct arch_hw_breakpoint *info;
 	int i;
 
+	preempt_disable();
+
 	for (i = 0; i < nr_wp_slots(); i++) {
 		if (unlikely(tsk->thread.last_hit_ubp[i]))
 			goto reset;
 	}
-	return;
+	goto out;
 
 reset:
 	regs->msr &= ~MSR_SE;
@@ -492,6 +494,9 @@
 		__set_breakpoint(i, info);
 		tsk->thread.last_hit_ubp[i] = NULL;
 	}
+
+out:
+	preempt_enable();
 }
 
 static bool is_larx_stcx_instr(int type)
diff --git a/kernel/arch/powerpc/kernel/iommu.c b/kernel/arch/powerpc/kernel/iommu.c
index 6806eef..3706351 100644
--- a/kernel/arch/powerpc/kernel/iommu.c
+++ b/kernel/arch/powerpc/kernel/iommu.c
@@ -133,17 +133,28 @@
 	return 0;
 }
 
-static struct notifier_block fail_iommu_bus_notifier = {
+/*
+ * PCI and VIO buses need separate notifier_block structs, since they're linked
+ * list nodes.  Sharing a notifier_block would mean that any notifiers later
+ * registered for PCI buses would also get called by VIO buses and vice versa.
+ */
+static struct notifier_block fail_iommu_pci_bus_notifier = {
 	.notifier_call = fail_iommu_bus_notify
 };
+
+#ifdef CONFIG_IBMVIO
+static struct notifier_block fail_iommu_vio_bus_notifier = {
+	.notifier_call = fail_iommu_bus_notify
+};
+#endif
 
 static int __init fail_iommu_setup(void)
 {
 #ifdef CONFIG_PCI
-	bus_register_notifier(&pci_bus_type, &fail_iommu_bus_notifier);
+	bus_register_notifier(&pci_bus_type, &fail_iommu_pci_bus_notifier);
 #endif
 #ifdef CONFIG_IBMVIO
-	bus_register_notifier(&vio_bus_type, &fail_iommu_bus_notifier);
+	bus_register_notifier(&vio_bus_type, &fail_iommu_vio_bus_notifier);
 #endif
 
 	return 0;
diff --git a/kernel/arch/powerpc/kernel/prom_init.c b/kernel/arch/powerpc/kernel/prom_init.c
index 9e71c07..6f7ad80 100644
--- a/kernel/arch/powerpc/kernel/prom_init.c
+++ b/kernel/arch/powerpc/kernel/prom_init.c
@@ -1069,7 +1069,8 @@
 #else
 		0,
 #endif
-		.associativity = OV5_FEAT(OV5_TYPE1_AFFINITY) | OV5_FEAT(OV5_PRRN),
+		.associativity = OV5_FEAT(OV5_FORM1_AFFINITY) | OV5_FEAT(OV5_PRRN) |
+		OV5_FEAT(OV5_FORM2_AFFINITY),
 		.bin_opts = OV5_FEAT(OV5_RESIZE_HPT) | OV5_FEAT(OV5_HP_EVT),
 		.micro_checkpoint = 0,
 		.reserved0 = 0,
diff --git a/kernel/arch/powerpc/kernel/ptrace/ptrace-view.c b/kernel/arch/powerpc/kernel/ptrace/ptrace-view.c
index 7e6478e..67c126d 100644
--- a/kernel/arch/powerpc/kernel/ptrace/ptrace-view.c
+++ b/kernel/arch/powerpc/kernel/ptrace/ptrace-view.c
@@ -298,6 +298,9 @@
 static int ppr_get(struct task_struct *target, const struct user_regset *regset,
 		   struct membuf to)
 {
+	if (!target->thread.regs)
+		return -EINVAL;
+
 	return membuf_write(&to, &target->thread.regs->ppr, sizeof(u64));
 }
 
@@ -305,6 +308,9 @@
 		   unsigned int pos, unsigned int count, const void *kbuf,
 		   const void __user *ubuf)
 {
+	if (!target->thread.regs)
+		return -EINVAL;
+
 	return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
 				  &target->thread.regs->ppr, 0, sizeof(u64));
 }
diff --git a/kernel/arch/powerpc/kernel/rtas.c b/kernel/arch/powerpc/kernel/rtas.c
index bf96205..5976a25 100644
--- a/kernel/arch/powerpc/kernel/rtas.c
+++ b/kernel/arch/powerpc/kernel/rtas.c
@@ -52,10 +52,10 @@
 EXPORT_SYMBOL(rtas);
 
 DEFINE_SPINLOCK(rtas_data_buf_lock);
-EXPORT_SYMBOL(rtas_data_buf_lock);
+EXPORT_SYMBOL_GPL(rtas_data_buf_lock);
 
-char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned;
-EXPORT_SYMBOL(rtas_data_buf);
+char rtas_data_buf[RTAS_DATA_BUF_SIZE] __aligned(SZ_4K);
+EXPORT_SYMBOL_GPL(rtas_data_buf);
 
 unsigned long rtas_rmo_buf;
 
@@ -64,7 +64,7 @@
  * This is done like this so rtas_flash can be a module.
  */
 void (*rtas_flash_term_hook)(int);
-EXPORT_SYMBOL(rtas_flash_term_hook);
+EXPORT_SYMBOL_GPL(rtas_flash_term_hook);
 
 /* RTAS use home made raw locking instead of spin_lock_irqsave
  * because those can be called from within really nasty contexts
@@ -312,7 +312,7 @@
  
 	spin_unlock(&progress_lock);
 }
-EXPORT_SYMBOL(rtas_progress);		/* needed by rtas_flash module */
+EXPORT_SYMBOL_GPL(rtas_progress);		/* needed by rtas_flash module */
 
 int rtas_token(const char *service)
 {
@@ -322,7 +322,7 @@
 	tokp = of_get_property(rtas.dev, service, NULL);
 	return tokp ? be32_to_cpu(*tokp) : RTAS_UNKNOWN_SERVICE;
 }
-EXPORT_SYMBOL(rtas_token);
+EXPORT_SYMBOL_GPL(rtas_token);
 
 int rtas_service_present(const char *service)
 {
@@ -399,7 +399,7 @@
 				buf = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC);
 		}
 		if (buf)
-			memcpy(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX);
+			memmove(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX);
 	}
 
 	return buf;
@@ -482,7 +482,7 @@
 	}
 	return ret;
 }
-EXPORT_SYMBOL(rtas_call);
+EXPORT_SYMBOL_GPL(rtas_call);
 
 /* For RTAS_BUSY (-2), delay for 1 millisecond.  For an extended busy status
  * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds.
@@ -517,7 +517,7 @@
 
 	return ms;
 }
-EXPORT_SYMBOL(rtas_busy_delay);
+EXPORT_SYMBOL_GPL(rtas_busy_delay);
 
 static int rtas_error_rc(int rtas_rc)
 {
@@ -563,7 +563,7 @@
 		return rtas_error_rc(rc);
 	return rc;
 }
-EXPORT_SYMBOL(rtas_get_power_level);
+EXPORT_SYMBOL_GPL(rtas_get_power_level);
 
 int rtas_set_power_level(int powerdomain, int level, int *setlevel)
 {
@@ -581,7 +581,7 @@
 		return rtas_error_rc(rc);
 	return rc;
 }
-EXPORT_SYMBOL(rtas_set_power_level);
+EXPORT_SYMBOL_GPL(rtas_set_power_level);
 
 int rtas_get_sensor(int sensor, int index, int *state)
 {
@@ -599,7 +599,7 @@
 		return rtas_error_rc(rc);
 	return rc;
 }
-EXPORT_SYMBOL(rtas_get_sensor);
+EXPORT_SYMBOL_GPL(rtas_get_sensor);
 
 int rtas_get_sensor_fast(int sensor, int index, int *state)
 {
@@ -660,7 +660,7 @@
 		return rtas_error_rc(rc);
 	return rc;
 }
-EXPORT_SYMBOL(rtas_set_indicator);
+EXPORT_SYMBOL_GPL(rtas_set_indicator);
 
 /*
  * Ignoring RTAS extended delay
@@ -715,6 +715,7 @@
 
 /* Must be in the RMO region, so we place it here */
 static char rtas_os_term_buf[2048];
+static s32 ibm_os_term_token = RTAS_UNKNOWN_SERVICE;
 
 void rtas_os_term(char *str)
 {
@@ -726,16 +727,20 @@
 	 * this property may terminate the partition which we want to avoid
 	 * since it interferes with panic_timeout.
 	 */
-	if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term") ||
-	    RTAS_UNKNOWN_SERVICE == rtas_token("ibm,extended-os-term"))
+	if (ibm_os_term_token == RTAS_UNKNOWN_SERVICE)
 		return;
 
 	snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str);
 
+	/*
+	 * Keep calling as long as RTAS returns a "try again" status,
+	 * but don't use rtas_busy_delay(), which potentially
+	 * schedules.
+	 */
 	do {
-		status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL,
+		status = rtas_call(ibm_os_term_token, 1, 1, NULL,
 				   __pa(rtas_os_term_buf));
-	} while (rtas_busy_delay(status));
+	} while (rtas_busy_delay_time(status));
 
 	if (status != 0)
 		printk(KERN_EMERG "ibm,os-term call failed %d\n", status);
@@ -1267,6 +1272,13 @@
 	no_entry = of_property_read_u32(rtas.dev, "linux,rtas-entry", &entry);
 	rtas.entry = no_entry ? rtas.base : entry;
 
+	/*
+	 * Discover these now to avoid device tree lookups in the
+	 * panic path.
+	 */
+	if (of_property_read_bool(rtas.dev, "ibm,extended-os-term"))
+		ibm_os_term_token = rtas_token("ibm,os-term");
+
 	/* If RTAS was found, allocate the RMO buffer for it and look for
 	 * the stop-self token if any
 	 */
diff --git a/kernel/arch/powerpc/kernel/rtas_flash.c b/kernel/arch/powerpc/kernel/rtas_flash.c
index a99179d..56bd0aa 100644
--- a/kernel/arch/powerpc/kernel/rtas_flash.c
+++ b/kernel/arch/powerpc/kernel/rtas_flash.c
@@ -710,9 +710,9 @@
 	if (!rtas_validate_flash_data.buf)
 		return -ENOMEM;
 
-	flash_block_cache = kmem_cache_create("rtas_flash_cache",
-					      RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0,
-					      NULL);
+	flash_block_cache = kmem_cache_create_usercopy("rtas_flash_cache",
+						       RTAS_BLK_SIZE, RTAS_BLK_SIZE,
+						       0, 0, RTAS_BLK_SIZE, NULL);
 	if (!flash_block_cache) {
 		printk(KERN_ERR "%s: failed to create block cache\n",
 				__func__);
diff --git a/kernel/arch/powerpc/kernel/time.c b/kernel/arch/powerpc/kernel/time.c
index 1d20f0f..ba9b54d 100644
--- a/kernel/arch/powerpc/kernel/time.c
+++ b/kernel/arch/powerpc/kernel/time.c
@@ -436,7 +436,7 @@
 #define calc_cputime_factors()
 #endif
 
-void __delay(unsigned long loops)
+void __no_kcsan __delay(unsigned long loops)
 {
 	unsigned long start;
 
@@ -457,7 +457,7 @@
 }
 EXPORT_SYMBOL(__delay);
 
-void udelay(unsigned long usecs)
+void __no_kcsan udelay(unsigned long usecs)
 {
 	__delay(tb_ticks_per_usec * usecs);
 }
diff --git a/kernel/arch/powerpc/kernel/traps.c b/kernel/arch/powerpc/kernel/traps.c
index 069d451..5e5a244 100644
--- a/kernel/arch/powerpc/kernel/traps.c
+++ b/kernel/arch/powerpc/kernel/traps.c
@@ -245,7 +245,7 @@
 
 	if (panic_on_oops)
 		panic("Fatal exception");
-	do_exit(signr);
+	make_task_dead(signr);
 }
 NOKPROBE_SYMBOL(oops_end);
 
diff --git a/kernel/arch/powerpc/kernel/vmlinux.lds.S b/kernel/arch/powerpc/kernel/vmlinux.lds.S
index 72fa3c0..b108d24 100644
--- a/kernel/arch/powerpc/kernel/vmlinux.lds.S
+++ b/kernel/arch/powerpc/kernel/vmlinux.lds.S
@@ -8,6 +8,7 @@
 #define BSS_FIRST_SECTIONS *(.bss.prominit)
 #define EMITS_PT_NOTE
 #define RO_EXCEPTION_TABLE_ALIGN	0
+#define RUNTIME_DISCARD_EXIT
 
 #include <asm/page.h>
 #include <asm-generic/vmlinux.lds.h>
@@ -382,9 +383,12 @@
 	DISCARDS
 	/DISCARD/ : {
 		*(*.EMB.apuinfo)
-		*(.glink .iplt .plt .rela* .comment)
+		*(.glink .iplt .plt .comment)
 		*(.gnu.version*)
 		*(.gnu.attributes)
 		*(.eh_frame)
+#ifndef CONFIG_RELOCATABLE
+		*(.rela*)
+#endif
 	}
 }
diff --git a/kernel/arch/powerpc/kvm/book3s_hv_ras.c b/kernel/arch/powerpc/kvm/book3s_hv_ras.c
index 6028628..7c693b3 100644
--- a/kernel/arch/powerpc/kvm/book3s_hv_ras.c
+++ b/kernel/arch/powerpc/kvm/book3s_hv_ras.c
@@ -9,6 +9,7 @@
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
 #include <linux/kernel.h>
+#include <asm/lppaca.h>
 #include <asm/opal.h>
 #include <asm/mce.h>
 #include <asm/machdep.h>
diff --git a/kernel/arch/powerpc/mm/book3s64/radix_pgtable.c b/kernel/arch/powerpc/mm/book3s64/radix_pgtable.c
index ae4ba6a..3728c17 100644
--- a/kernel/arch/powerpc/mm/book3s64/radix_pgtable.c
+++ b/kernel/arch/powerpc/mm/book3s64/radix_pgtable.c
@@ -783,9 +783,9 @@
 }
 
 static void remove_pte_table(pte_t *pte_start, unsigned long addr,
-			     unsigned long end)
+			     unsigned long end, bool direct)
 {
-	unsigned long next;
+	unsigned long next, pages = 0;
 	pte_t *pte;
 
 	pte = pte_start + pte_index(addr);
@@ -807,13 +807,16 @@
 		}
 
 		pte_clear(&init_mm, addr, pte);
+		pages++;
 	}
+	if (direct)
+		update_page_count(mmu_virtual_psize, -pages);
 }
 
 static void __meminit remove_pmd_table(pmd_t *pmd_start, unsigned long addr,
-			     unsigned long end)
+				       unsigned long end, bool direct)
 {
-	unsigned long next;
+	unsigned long next, pages = 0;
 	pte_t *pte_base;
 	pmd_t *pmd;
 
@@ -831,19 +834,22 @@
 				continue;
 			}
 			pte_clear(&init_mm, addr, (pte_t *)pmd);
+			pages++;
 			continue;
 		}
 
 		pte_base = (pte_t *)pmd_page_vaddr(*pmd);
-		remove_pte_table(pte_base, addr, next);
+		remove_pte_table(pte_base, addr, next, direct);
 		free_pte_table(pte_base, pmd);
 	}
+	if (direct)
+		update_page_count(MMU_PAGE_2M, -pages);
 }
 
 static void __meminit remove_pud_table(pud_t *pud_start, unsigned long addr,
-			     unsigned long end)
+				       unsigned long end, bool direct)
 {
-	unsigned long next;
+	unsigned long next, pages = 0;
 	pmd_t *pmd_base;
 	pud_t *pud;
 
@@ -861,16 +867,20 @@
 				continue;
 			}
 			pte_clear(&init_mm, addr, (pte_t *)pud);
+			pages++;
 			continue;
 		}
 
-		pmd_base = (pmd_t *)pud_page_vaddr(*pud);
-		remove_pmd_table(pmd_base, addr, next);
+		pmd_base = pud_pgtable(*pud);
+		remove_pmd_table(pmd_base, addr, next, direct);
 		free_pmd_table(pmd_base, pud);
 	}
+	if (direct)
+		update_page_count(MMU_PAGE_1G, -pages);
 }
 
-static void __meminit remove_pagetable(unsigned long start, unsigned long end)
+static void __meminit remove_pagetable(unsigned long start, unsigned long end,
+				       bool direct)
 {
 	unsigned long addr, next;
 	pud_t *pud_base;
@@ -898,8 +908,8 @@
 			continue;
 		}
 
-		pud_base = (pud_t *)p4d_page_vaddr(*p4d);
-		remove_pud_table(pud_base, addr, next);
+		pud_base = p4d_pgtable(*p4d);
+		remove_pud_table(pud_base, addr, next, direct);
 		free_pud_table(pud_base, p4d);
 	}
 
@@ -922,7 +932,7 @@
 
 int __meminit radix__remove_section_mapping(unsigned long start, unsigned long end)
 {
-	remove_pagetable(start, end);
+	remove_pagetable(start, end, true);
 	return 0;
 }
 #endif /* CONFIG_MEMORY_HOTPLUG */
@@ -958,7 +968,7 @@
 #ifdef CONFIG_MEMORY_HOTPLUG
 void __meminit radix__vmemmap_remove_mapping(unsigned long start, unsigned long page_size)
 {
-	remove_pagetable(start, start + page_size);
+	remove_pagetable(start, start + page_size, false);
 }
 #endif
 #endif
@@ -1064,8 +1074,8 @@
 				  pte_t entry, unsigned long address, int psize)
 {
 	struct mm_struct *mm = vma->vm_mm;
-	unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED |
-					      _PAGE_RW | _PAGE_EXEC);
+	unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_SOFT_DIRTY |
+					      _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
 
 	unsigned long change = pte_val(entry) ^ pte_val(*ptep);
 	/*
@@ -1156,7 +1166,7 @@
 	pmd_t *pmd;
 	int i;
 
-	pmd = (pmd_t *)pud_page_vaddr(*pud);
+	pmd = pud_pgtable(*pud);
 	pud_clear(pud);
 
 	flush_tlb_kernel_range(addr, addr + PUD_SIZE);
diff --git a/kernel/arch/powerpc/mm/book3s64/radix_tlb.c b/kernel/arch/powerpc/mm/book3s64/radix_tlb.c
index 4c2f759..abbfd5c 100644
--- a/kernel/arch/powerpc/mm/book3s64/radix_tlb.c
+++ b/kernel/arch/powerpc/mm/book3s64/radix_tlb.c
@@ -941,15 +941,12 @@
 			}
 		}
 	} else {
-		bool hflush = false;
+		bool hflush;
 		unsigned long hstart, hend;
 
-		if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) {
-			hstart = (start + PMD_SIZE - 1) & PMD_MASK;
-			hend = end & PMD_MASK;
-			if (hstart < hend)
-				hflush = true;
-		}
+		hstart = (start + PMD_SIZE - 1) & PMD_MASK;
+		hend = end & PMD_MASK;
+		hflush = IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && hstart < hend;
 
 		if (local) {
 			asm volatile("ptesync": : :"memory");
diff --git a/kernel/arch/powerpc/mm/book3s64/slb.c b/kernel/arch/powerpc/mm/book3s64/slb.c
index c30fcbf..ccf0a87 100644
--- a/kernel/arch/powerpc/mm/book3s64/slb.c
+++ b/kernel/arch/powerpc/mm/book3s64/slb.c
@@ -13,6 +13,7 @@
 #include <asm/mmu.h>
 #include <asm/mmu_context.h>
 #include <asm/paca.h>
+#include <asm/lppaca.h>
 #include <asm/ppc-opcode.h>
 #include <asm/cputable.h>
 #include <asm/cacheflush.h>
diff --git a/kernel/arch/powerpc/mm/init_64.c b/kernel/arch/powerpc/mm/init_64.c
index 386be13..db040f3 100644
--- a/kernel/arch/powerpc/mm/init_64.c
+++ b/kernel/arch/powerpc/mm/init_64.c
@@ -188,7 +188,7 @@
 	unsigned long nr_pfn = page_size / sizeof(struct page);
 	unsigned long start_pfn = page_to_pfn((struct page *)start);
 
-	if ((start_pfn + nr_pfn) > altmap->end_pfn)
+	if ((start_pfn + nr_pfn - 1) > altmap->end_pfn)
 		return true;
 
 	if (start_pfn < altmap->base_pfn)
@@ -313,8 +313,7 @@
 	start = ALIGN_DOWN(start, page_size);
 	if (altmap) {
 		alt_start = altmap->base_pfn;
-		alt_end = altmap->base_pfn + altmap->reserve +
-			  altmap->free + altmap->alloc + altmap->align;
+		alt_end = altmap->base_pfn + altmap->reserve + altmap->free;
 	}
 
 	pr_debug("vmemmap_free %lx...%lx\n", start, end);
diff --git a/kernel/arch/powerpc/mm/kasan/Makefile b/kernel/arch/powerpc/mm/kasan/Makefile
index bb1a540..8636b17 100644
--- a/kernel/arch/powerpc/mm/kasan/Makefile
+++ b/kernel/arch/powerpc/mm/kasan/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
 KASAN_SANITIZE := n
+KCOV_INSTRUMENT := n
 
 obj-$(CONFIG_PPC32)           += kasan_init_32.o
 obj-$(CONFIG_PPC_8xx)		+= 8xx.o
diff --git a/kernel/arch/powerpc/mm/numa.c b/kernel/arch/powerpc/mm/numa.c
index 275c60f..ce8569e 100644
--- a/kernel/arch/powerpc/mm/numa.c
+++ b/kernel/arch/powerpc/mm/numa.c
@@ -51,14 +51,22 @@
 EXPORT_SYMBOL(node_to_cpumask_map);
 EXPORT_SYMBOL(node_data);
 
-static int min_common_depth;
+static int primary_domain_index;
 static int n_mem_addr_cells, n_mem_size_cells;
-static int form1_affinity;
+
+#define FORM0_AFFINITY 0
+#define FORM1_AFFINITY 1
+#define FORM2_AFFINITY 2
+static int affinity_form;
 
 #define MAX_DISTANCE_REF_POINTS 4
 static int distance_ref_points_depth;
 static const __be32 *distance_ref_points;
 static int distance_lookup_table[MAX_NUMNODES][MAX_DISTANCE_REF_POINTS];
+static int numa_distance_table[MAX_NUMNODES][MAX_NUMNODES] = {
+	[0 ... MAX_NUMNODES - 1] = { [0 ... MAX_NUMNODES - 1] = -1 }
+};
+static int numa_id_index_table[MAX_NUMNODES] = { [0 ... MAX_NUMNODES - 1] = NUMA_NO_NODE };
 
 /*
  * Allocate node_to_cpumask_map based on number of available nodes
@@ -163,7 +171,55 @@
 }
 #endif /* CONFIG_HOTPLUG_CPU || CONFIG_PPC_SPLPAR */
 
-int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
+static int __associativity_to_nid(const __be32 *associativity,
+				  int max_array_sz)
+{
+	int nid;
+	/*
+	 * primary_domain_index is 1 based array index.
+	 */
+	int index = primary_domain_index  - 1;
+
+	if (!numa_enabled || index >= max_array_sz)
+		return NUMA_NO_NODE;
+
+	nid = of_read_number(&associativity[index], 1);
+
+	/* POWER4 LPAR uses 0xffff as invalid node */
+	if (nid == 0xffff || nid >= nr_node_ids)
+		nid = NUMA_NO_NODE;
+	return nid;
+}
+/*
+ * Returns nid in the range [0..nr_node_ids], or -1 if no useful NUMA
+ * info is found.
+ */
+static int associativity_to_nid(const __be32 *associativity)
+{
+	int array_sz = of_read_number(associativity, 1);
+
+	/* Skip the first element in the associativity array */
+	return __associativity_to_nid((associativity + 1), array_sz);
+}
+
+static int __cpu_form2_relative_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
+{
+	int dist;
+	int node1, node2;
+
+	node1 = associativity_to_nid(cpu1_assoc);
+	node2 = associativity_to_nid(cpu2_assoc);
+
+	dist = numa_distance_table[node1][node2];
+	if (dist <= LOCAL_DISTANCE)
+		return 0;
+	else if (dist <= REMOTE_DISTANCE)
+		return 1;
+	else
+		return 2;
+}
+
+static int __cpu_form1_relative_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
 {
 	int dist = 0;
 
@@ -179,6 +235,15 @@
 	return dist;
 }
 
+int cpu_relative_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
+{
+	/* We should not get called with FORM0 */
+	VM_WARN_ON(affinity_form == FORM0_AFFINITY);
+	if (affinity_form == FORM1_AFFINITY)
+		return __cpu_form1_relative_distance(cpu1_assoc, cpu2_assoc);
+	return __cpu_form2_relative_distance(cpu1_assoc, cpu2_assoc);
+}
+
 /* must hold reference to node during call */
 static const __be32 *of_get_associativity(struct device_node *dev)
 {
@@ -190,7 +255,9 @@
 	int i;
 	int distance = LOCAL_DISTANCE;
 
-	if (!form1_affinity)
+	if (affinity_form == FORM2_AFFINITY)
+		return numa_distance_table[a][b];
+	else if (affinity_form == FORM0_AFFINITY)
 		return ((a == b) ? LOCAL_DISTANCE : REMOTE_DISTANCE);
 
 	for (i = 0; i < distance_ref_points_depth; i++) {
@@ -204,52 +271,6 @@
 	return distance;
 }
 EXPORT_SYMBOL(__node_distance);
-
-static void initialize_distance_lookup_table(int nid,
-		const __be32 *associativity)
-{
-	int i;
-
-	if (!form1_affinity)
-		return;
-
-	for (i = 0; i < distance_ref_points_depth; i++) {
-		const __be32 *entry;
-
-		entry = &associativity[be32_to_cpu(distance_ref_points[i]) - 1];
-		distance_lookup_table[nid][i] = of_read_number(entry, 1);
-	}
-}
-
-/*
- * Returns nid in the range [0..nr_node_ids], or -1 if no useful NUMA
- * info is found.
- */
-static int associativity_to_nid(const __be32 *associativity)
-{
-	int nid = NUMA_NO_NODE;
-
-	if (!numa_enabled)
-		goto out;
-
-	if (of_read_number(associativity, 1) >= min_common_depth)
-		nid = of_read_number(&associativity[min_common_depth], 1);
-
-	/* POWER4 LPAR uses 0xffff as invalid node */
-	if (nid == 0xffff || nid >= nr_node_ids)
-		nid = NUMA_NO_NODE;
-
-	if (nid > 0 &&
-		of_read_number(associativity, 1) >= distance_ref_points_depth) {
-		/*
-		 * Skip the length field and send start of associativity array
-		 */
-		initialize_distance_lookup_table(nid, associativity + 1);
-	}
-
-out:
-	return nid;
-}
 
 /* Returns the nid associated with the given device tree node,
  * or -1 if not found.
@@ -284,10 +305,159 @@
 }
 EXPORT_SYMBOL(of_node_to_nid);
 
-static int __init find_min_common_depth(void)
+static void __initialize_form1_numa_distance(const __be32 *associativity,
+					     int max_array_sz)
 {
-	int depth;
+	int i, nid;
+
+	if (affinity_form != FORM1_AFFINITY)
+		return;
+
+	nid = __associativity_to_nid(associativity, max_array_sz);
+	if (nid != NUMA_NO_NODE) {
+		for (i = 0; i < distance_ref_points_depth; i++) {
+			const __be32 *entry;
+			int index = be32_to_cpu(distance_ref_points[i]) - 1;
+
+			/*
+			 * broken hierarchy, return with broken distance table
+			 */
+			if (WARN(index >= max_array_sz, "Broken ibm,associativity property"))
+				return;
+
+			entry = &associativity[index];
+			distance_lookup_table[nid][i] = of_read_number(entry, 1);
+		}
+	}
+}
+
+static void initialize_form1_numa_distance(const __be32 *associativity)
+{
+	int array_sz;
+
+	array_sz = of_read_number(associativity, 1);
+	/* Skip the first element in the associativity array */
+	__initialize_form1_numa_distance(associativity + 1, array_sz);
+}
+
+/*
+ * Used to update distance information w.r.t newly added node.
+ */
+void update_numa_distance(struct device_node *node)
+{
+	int nid;
+
+	if (affinity_form == FORM0_AFFINITY)
+		return;
+	else if (affinity_form == FORM1_AFFINITY) {
+		const __be32 *associativity;
+
+		associativity = of_get_associativity(node);
+		if (!associativity)
+			return;
+
+		initialize_form1_numa_distance(associativity);
+		return;
+	}
+
+	/* FORM2 affinity  */
+	nid = of_node_to_nid_single(node);
+	if (nid == NUMA_NO_NODE)
+		return;
+
+	/*
+	 * With FORM2 we expect NUMA distance of all possible NUMA
+	 * nodes to be provided during boot.
+	 */
+	WARN(numa_distance_table[nid][nid] == -1,
+	     "NUMA distance details for node %d not provided\n", nid);
+}
+EXPORT_SYMBOL_GPL(update_numa_distance);
+
+/*
+ * ibm,numa-lookup-index-table= {N, domainid1, domainid2, ..... domainidN}
+ * ibm,numa-distance-table = { N, 1, 2, 4, 5, 1, 6, .... N elements}
+ */
+static void initialize_form2_numa_distance_lookup_table(void)
+{
+	int i, j;
 	struct device_node *root;
+	const __u8 *numa_dist_table;
+	const __be32 *numa_lookup_index;
+	int numa_dist_table_length;
+	int max_numa_index, distance_index;
+
+	if (firmware_has_feature(FW_FEATURE_OPAL))
+		root = of_find_node_by_path("/ibm,opal");
+	else
+		root = of_find_node_by_path("/rtas");
+	if (!root)
+		root = of_find_node_by_path("/");
+
+	numa_lookup_index = of_get_property(root, "ibm,numa-lookup-index-table", NULL);
+	max_numa_index = of_read_number(&numa_lookup_index[0], 1);
+
+	/* first element of the array is the size and is encode-int */
+	numa_dist_table = of_get_property(root, "ibm,numa-distance-table", NULL);
+	numa_dist_table_length = of_read_number((const __be32 *)&numa_dist_table[0], 1);
+	/* Skip the size which is encoded int */
+	numa_dist_table += sizeof(__be32);
+
+	pr_debug("numa_dist_table_len = %d, numa_dist_indexes_len = %d\n",
+		 numa_dist_table_length, max_numa_index);
+
+	for (i = 0; i < max_numa_index; i++)
+		/* +1 skip the max_numa_index in the property */
+		numa_id_index_table[i] = of_read_number(&numa_lookup_index[i + 1], 1);
+
+
+	if (numa_dist_table_length != max_numa_index * max_numa_index) {
+		WARN(1, "Wrong NUMA distance information\n");
+		/* consider everybody else just remote. */
+		for (i = 0;  i < max_numa_index; i++) {
+			for (j = 0; j < max_numa_index; j++) {
+				int nodeA = numa_id_index_table[i];
+				int nodeB = numa_id_index_table[j];
+
+				if (nodeA == nodeB)
+					numa_distance_table[nodeA][nodeB] = LOCAL_DISTANCE;
+				else
+					numa_distance_table[nodeA][nodeB] = REMOTE_DISTANCE;
+			}
+		}
+	}
+
+	distance_index = 0;
+	for (i = 0;  i < max_numa_index; i++) {
+		for (j = 0; j < max_numa_index; j++) {
+			int nodeA = numa_id_index_table[i];
+			int nodeB = numa_id_index_table[j];
+
+			numa_distance_table[nodeA][nodeB] = numa_dist_table[distance_index++];
+			pr_debug("dist[%d][%d]=%d ", nodeA, nodeB, numa_distance_table[nodeA][nodeB]);
+		}
+	}
+	of_node_put(root);
+}
+
+static int __init find_primary_domain_index(void)
+{
+	int index;
+	struct device_node *root;
+
+	/*
+	 * Check for which form of affinity.
+	 */
+	if (firmware_has_feature(FW_FEATURE_OPAL)) {
+		affinity_form = FORM1_AFFINITY;
+	} else if (firmware_has_feature(FW_FEATURE_FORM2_AFFINITY)) {
+		dbg("Using form 2 affinity\n");
+		affinity_form = FORM2_AFFINITY;
+	} else if (firmware_has_feature(FW_FEATURE_FORM1_AFFINITY)) {
+		dbg("Using form 1 affinity\n");
+		affinity_form = FORM1_AFFINITY;
+	} else
+		affinity_form = FORM0_AFFINITY;
 
 	if (firmware_has_feature(FW_FEATURE_OPAL))
 		root = of_find_node_by_path("/ibm,opal");
@@ -318,25 +488,21 @@
 	}
 
 	distance_ref_points_depth /= sizeof(int);
-
-	if (firmware_has_feature(FW_FEATURE_OPAL) ||
-	    firmware_has_feature(FW_FEATURE_TYPE1_AFFINITY)) {
-		dbg("Using form 1 affinity\n");
-		form1_affinity = 1;
-	}
-
-	if (form1_affinity) {
-		depth = of_read_number(distance_ref_points, 1);
-	} else {
+	if (affinity_form == FORM0_AFFINITY) {
 		if (distance_ref_points_depth < 2) {
 			printk(KERN_WARNING "NUMA: "
-				"short ibm,associativity-reference-points\n");
+			       "short ibm,associativity-reference-points\n");
 			goto err;
 		}
 
-		depth = of_read_number(&distance_ref_points[1], 1);
+		index = of_read_number(&distance_ref_points[1], 1);
+	} else {
+		/*
+		 * Both FORM1 and FORM2 affinity find the primary domain details
+		 * at the same offset.
+		 */
+		index = of_read_number(distance_ref_points, 1);
 	}
-
 	/*
 	 * Warn and cap if the hardware supports more than
 	 * MAX_DISTANCE_REF_POINTS domains.
@@ -348,7 +514,7 @@
 	}
 
 	of_node_put(root);
-	return depth;
+	return index;
 
 err:
 	of_node_put(root);
@@ -426,6 +592,38 @@
 	return 0;
 }
 
+static int get_nid_and_numa_distance(struct drmem_lmb *lmb)
+{
+	struct assoc_arrays aa = { .arrays = NULL };
+	int default_nid = NUMA_NO_NODE;
+	int nid = default_nid;
+	int rc, index;
+
+	if ((primary_domain_index < 0) || !numa_enabled)
+		return default_nid;
+
+	rc = of_get_assoc_arrays(&aa);
+	if (rc)
+		return default_nid;
+
+	if (primary_domain_index <= aa.array_sz &&
+	    !(lmb->flags & DRCONF_MEM_AI_INVALID) && lmb->aa_index < aa.n_arrays) {
+		const __be32 *associativity;
+
+		index = lmb->aa_index * aa.array_sz;
+		associativity = &aa.arrays[index];
+		nid = __associativity_to_nid(associativity, aa.array_sz);
+		if (nid > 0 && affinity_form == FORM1_AFFINITY) {
+			/*
+			 * lookup array associativity entries have
+			 * no length of the array as the first element.
+			 */
+			__initialize_form1_numa_distance(associativity, aa.array_sz);
+		}
+	}
+	return nid;
+}
+
 /*
  * This is like of_node_to_nid_single() for memory represented in the
  * ibm,dynamic-reconfiguration-memory node.
@@ -437,35 +635,28 @@
 	int nid = default_nid;
 	int rc, index;
 
-	if ((min_common_depth < 0) || !numa_enabled)
+	if ((primary_domain_index < 0) || !numa_enabled)
 		return default_nid;
 
 	rc = of_get_assoc_arrays(&aa);
 	if (rc)
 		return default_nid;
 
-	if (min_common_depth <= aa.array_sz &&
+	if (primary_domain_index <= aa.array_sz &&
 	    !(lmb->flags & DRCONF_MEM_AI_INVALID) && lmb->aa_index < aa.n_arrays) {
-		index = lmb->aa_index * aa.array_sz + min_common_depth - 1;
-		nid = of_read_number(&aa.arrays[index], 1);
+		const __be32 *associativity;
 
-		if (nid == 0xffff || nid >= nr_node_ids)
-			nid = default_nid;
-
-		if (nid > 0) {
-			index = lmb->aa_index * aa.array_sz;
-			initialize_distance_lookup_table(nid,
-							&aa.arrays[index]);
-		}
+		index = lmb->aa_index * aa.array_sz;
+		associativity = &aa.arrays[index];
+		nid = __associativity_to_nid(associativity, aa.array_sz);
 	}
-
 	return nid;
 }
 
 #ifdef CONFIG_PPC_SPLPAR
-static int vphn_get_nid(long lcpu)
+
+static int __vphn_get_associativity(long lcpu, __be32 *associativity)
 {
-	__be32 associativity[VPHN_ASSOC_BUFSIZE] = {0};
 	long rc, hwid;
 
 	/*
@@ -485,12 +676,30 @@
 
 		rc = hcall_vphn(hwid, VPHN_FLAG_VCPU, associativity);
 		if (rc == H_SUCCESS)
-			return associativity_to_nid(associativity);
+			return 0;
 	}
 
+	return -1;
+}
+
+static int vphn_get_nid(long lcpu)
+{
+	__be32 associativity[VPHN_ASSOC_BUFSIZE] = {0};
+
+
+	if (!__vphn_get_associativity(lcpu, associativity))
+		return associativity_to_nid(associativity);
+
 	return NUMA_NO_NODE;
+
 }
 #else
+
+static int __vphn_get_associativity(long lcpu, __be32 *associativity)
+{
+	return -1;
+}
+
 static int vphn_get_nid(long unused)
 {
 	return NUMA_NO_NODE;
@@ -685,7 +894,7 @@
 			size = read_n_cells(n_mem_size_cells, usm);
 		}
 
-		nid = of_drconf_to_nid_single(lmb);
+		nid = get_nid_and_numa_distance(lmb);
 		fake_numa_create_new_node(((base + size) >> PAGE_SHIFT),
 					  &nid);
 		node_set_online(nid);
@@ -702,24 +911,31 @@
 	struct device_node *memory;
 	int default_nid = 0;
 	unsigned long i;
+	const __be32 *associativity;
 
 	if (numa_enabled == 0) {
 		printk(KERN_WARNING "NUMA disabled by user\n");
 		return -1;
 	}
 
-	min_common_depth = find_min_common_depth();
+	primary_domain_index = find_primary_domain_index();
 
-	if (min_common_depth < 0) {
+	if (primary_domain_index < 0) {
 		/*
-		 * if we fail to parse min_common_depth from device tree
+		 * if we fail to parse primary_domain_index from device tree
 		 * mark the numa disabled, boot with numa disabled.
 		 */
 		numa_enabled = false;
-		return min_common_depth;
+		return primary_domain_index;
 	}
 
-	dbg("NUMA associativity depth for CPU/Memory: %d\n", min_common_depth);
+	dbg("NUMA associativity depth for CPU/Memory: %d\n", primary_domain_index);
+
+	/*
+	 * If it is FORM2 initialize the distance table here.
+	 */
+	if (affinity_form == FORM2_AFFINITY)
+		initialize_form2_numa_distance_lookup_table();
 
 	/*
 	 * Even though we connect cpus to numa domains later in SMP
@@ -727,18 +943,30 @@
 	 * each node to be onlined must have NODE_DATA etc backing it.
 	 */
 	for_each_present_cpu(i) {
+		__be32 vphn_assoc[VPHN_ASSOC_BUFSIZE];
 		struct device_node *cpu;
-		int nid = vphn_get_nid(i);
+		int nid = NUMA_NO_NODE;
 
-		/*
-		 * Don't fall back to default_nid yet -- we will plug
-		 * cpus into nodes once the memory scan has discovered
-		 * the topology.
-		 */
-		if (nid == NUMA_NO_NODE) {
+		memset(vphn_assoc, 0, VPHN_ASSOC_BUFSIZE * sizeof(__be32));
+
+		if (__vphn_get_associativity(i, vphn_assoc) == 0) {
+			nid = associativity_to_nid(vphn_assoc);
+			initialize_form1_numa_distance(vphn_assoc);
+		} else {
+
+			/*
+			 * Don't fall back to default_nid yet -- we will plug
+			 * cpus into nodes once the memory scan has discovered
+			 * the topology.
+			 */
 			cpu = of_get_cpu_node(i, NULL);
 			BUG_ON(!cpu);
-			nid = of_node_to_nid_single(cpu);
+
+			associativity = of_get_associativity(cpu);
+			if (associativity) {
+				nid = associativity_to_nid(associativity);
+				initialize_form1_numa_distance(associativity);
+			}
 			of_node_put(cpu);
 		}
 
@@ -776,8 +1004,11 @@
 		 * have associativity properties.  If none, then
 		 * everything goes to default_nid.
 		 */
-		nid = of_node_to_nid_single(memory);
-		if (nid < 0)
+		associativity = of_get_associativity(memory);
+		if (associativity) {
+			nid = associativity_to_nid(associativity);
+			initialize_form1_numa_distance(associativity);
+		} else
 			nid = default_nid;
 
 		fake_numa_create_new_node(((start + size) >> PAGE_SHIFT), &nid);
@@ -926,7 +1157,7 @@
 			goto out;
 	}
 
-	max_nodes = of_read_number(&domains[min_common_depth], 1);
+	max_nodes = of_read_number(&domains[primary_domain_index], 1);
 	pr_info("Partition configured for %d NUMA nodes.\n", max_nodes);
 
 	for (i = 0; i < max_nodes; i++) {
@@ -935,7 +1166,7 @@
 	}
 
 	prop_length /= sizeof(int);
-	if (prop_length > min_common_depth + 2)
+	if (prop_length > primary_domain_index + 2)
 		coregroup_enabled = 1;
 
 out:
@@ -1268,7 +1499,7 @@
 		goto out;
 
 	index = of_read_number(associativity, 1);
-	if (index > min_common_depth + 1)
+	if (index > primary_domain_index + 1)
 		return of_read_number(&associativity[index - 1], 1);
 
 out:
diff --git a/kernel/arch/powerpc/mm/pgtable_64.c b/kernel/arch/powerpc/mm/pgtable_64.c
index aefc2bf..175aabf 100644
--- a/kernel/arch/powerpc/mm/pgtable_64.c
+++ b/kernel/arch/powerpc/mm/pgtable_64.c
@@ -106,7 +106,7 @@
 			VM_WARN_ON(!p4d_huge(p4d));
 		return pte_page(p4d_pte(p4d));
 	}
-	return virt_to_page(p4d_page_vaddr(p4d));
+	return virt_to_page(p4d_pgtable(p4d));
 }
 #endif
 
@@ -117,7 +117,7 @@
 			VM_WARN_ON(!pud_huge(pud));
 		return pte_page(pud_pte(pud));
 	}
-	return virt_to_page(pud_page_vaddr(pud));
+	return virt_to_page(pud_pgtable(pud));
 }
 
 /*
diff --git a/kernel/arch/powerpc/perf/callchain.c b/kernel/arch/powerpc/perf/callchain.c
index 6c028ee..99f3c4f 100644
--- a/kernel/arch/powerpc/perf/callchain.c
+++ b/kernel/arch/powerpc/perf/callchain.c
@@ -61,6 +61,7 @@
 		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
diff --git a/kernel/arch/powerpc/perf/core-fsl-emb.c b/kernel/arch/powerpc/perf/core-fsl-emb.c
index ee721f4..1a53ab0 100644
--- a/kernel/arch/powerpc/perf/core-fsl-emb.c
+++ b/kernel/arch/powerpc/perf/core-fsl-emb.c
@@ -645,7 +645,6 @@
 	struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
 	struct perf_event *event;
 	unsigned long val;
-	int found = 0;
 
 	for (i = 0; i < ppmu->n_counter; ++i) {
 		event = cpuhw->event[i];
@@ -654,7 +653,6 @@
 		if ((int)val < 0) {
 			if (event) {
 				/* event has overflowed */
-				found = 1;
 				record_and_restart(event, val, regs);
 			} else {
 				/*
@@ -672,11 +670,13 @@
 	isync();
 }
 
-void hw_perf_event_setup(int cpu)
+static int fsl_emb_pmu_prepare_cpu(unsigned int cpu)
 {
 	struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
 
 	memset(cpuhw, 0, sizeof(*cpuhw));
+
+	return 0;
 }
 
 int register_fsl_emb_pmu(struct fsl_emb_pmu *pmu)
@@ -689,6 +689,8 @@
 		pmu->name);
 
 	perf_pmu_register(&fsl_emb_pmu, "cpu", PERF_TYPE_RAW);
+	cpuhp_setup_state(CPUHP_PERF_POWER, "perf/powerpc:prepare",
+			  fsl_emb_pmu_prepare_cpu, NULL);
 
 	return 0;
 }
diff --git a/kernel/arch/powerpc/perf/hv-24x7.c b/kernel/arch/powerpc/perf/hv-24x7.c
index 6e7e820..61a0874 100644
--- a/kernel/arch/powerpc/perf/hv-24x7.c
+++ b/kernel/arch/powerpc/perf/hv-24x7.c
@@ -79,9 +79,8 @@
  */
 void read_24x7_sys_info(void)
 {
-	int call_status, len, ntypes;
-
-	spin_lock(&rtas_data_buf_lock);
+	const s32 token = rtas_token("ibm,get-system-parameter");
+	int call_status;
 
 	/*
 	 * Making system parameter: chips and sockets and cores per chip
@@ -91,32 +90,27 @@
 	phys_chipspersocket = 1;
 	phys_coresperchip = 1;
 
-	call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
-				NULL,
-				PROCESSOR_MODULE_INFO,
-				__pa(rtas_data_buf),
-				RTAS_DATA_BUF_SIZE);
+	do {
+		spin_lock(&rtas_data_buf_lock);
+		call_status = rtas_call(token, 3, 1, NULL, PROCESSOR_MODULE_INFO,
+					__pa(rtas_data_buf), RTAS_DATA_BUF_SIZE);
+		if (call_status == 0) {
+			int ntypes = be16_to_cpup((__be16 *)&rtas_data_buf[2]);
+			int len = be16_to_cpup((__be16 *)&rtas_data_buf[0]);
+
+			if (len >= 8 && ntypes != 0) {
+				phys_sockets = be16_to_cpup((__be16 *)&rtas_data_buf[4]);
+				phys_chipspersocket = be16_to_cpup((__be16 *)&rtas_data_buf[6]);
+				phys_coresperchip = be16_to_cpup((__be16 *)&rtas_data_buf[8]);
+			}
+		}
+		spin_unlock(&rtas_data_buf_lock);
+	} while (rtas_busy_delay(call_status));
 
 	if (call_status != 0) {
 		pr_err("Error calling get-system-parameter %d\n",
 		       call_status);
-	} else {
-		len = be16_to_cpup((__be16 *)&rtas_data_buf[0]);
-		if (len < 8)
-			goto out;
-
-		ntypes = be16_to_cpup((__be16 *)&rtas_data_buf[2]);
-
-		if (!ntypes)
-			goto out;
-
-		phys_sockets = be16_to_cpup((__be16 *)&rtas_data_buf[4]);
-		phys_chipspersocket = be16_to_cpup((__be16 *)&rtas_data_buf[6]);
-		phys_coresperchip = be16_to_cpup((__be16 *)&rtas_data_buf[8]);
 	}
-
-out:
-	spin_unlock(&rtas_data_buf_lock);
 }
 
 /* Domains for which more than one result element are returned for each event. */
@@ -1416,7 +1410,7 @@
 	}
 
 	domain = event_get_domain(event);
-	if (domain >= HV_PERF_DOMAIN_MAX) {
+	if (domain  == 0 || domain >= HV_PERF_DOMAIN_MAX) {
 		pr_devel("invalid domain %d\n", domain);
 		return -EINVAL;
 	}
diff --git a/kernel/arch/powerpc/perf/hv-gpci-requests.h b/kernel/arch/powerpc/perf/hv-gpci-requests.h
index 8965b44..5e86371 100644
--- a/kernel/arch/powerpc/perf/hv-gpci-requests.h
+++ b/kernel/arch/powerpc/perf/hv-gpci-requests.h
@@ -79,6 +79,7 @@
 )
 #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 @@
 	__count(0x10,	8,	cycles)
 )
 #include I(REQUEST_END)
+#endif
 
 #define REQUEST_NAME system_performance_capabilities
 #define REQUEST_NUM 0x40
@@ -103,6 +105,7 @@
 )
 #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 @@
 	__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/kernel/arch/powerpc/perf/hv-gpci.c b/kernel/arch/powerpc/perf/hv-gpci.c
index c756228..28b770b 100644
--- a/kernel/arch/powerpc/perf/hv-gpci.c
+++ b/kernel/arch/powerpc/perf/hv-gpci.c
@@ -72,7 +72,7 @@
 
 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 @@
 	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 @@
 	/* 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/kernel/arch/powerpc/perf/hv-gpci.h b/kernel/arch/powerpc/perf/hv-gpci.h
index 4d10826..c720209 100644
--- a/kernel/arch/powerpc/perf/hv-gpci.h
+++ b/kernel/arch/powerpc/perf/hv-gpci.h
@@ -26,6 +26,7 @@
 #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/kernel/arch/powerpc/perf/imc-pmu.c b/kernel/arch/powerpc/perf/imc-pmu.c
index e8074d7..b773c41 100644
--- a/kernel/arch/powerpc/perf/imc-pmu.c
+++ b/kernel/arch/powerpc/perf/imc-pmu.c
@@ -13,6 +13,7 @@
 #include <asm/cputhreads.h>
 #include <asm/smp.h>
 #include <linux/string.h>
+#include <linux/spinlock.h>
 
 /* Nest IMC data structures and variables */
 
@@ -49,7 +50,7 @@
  * core and trace-imc
  */
 static struct imc_pmu_ref imc_global_refc = {
-	.lock = __MUTEX_INITIALIZER(imc_global_refc.lock),
+	.lock = __SPIN_LOCK_INITIALIZER(imc_global_refc.lock),
 	.id = 0,
 	.refc = 0,
 };
@@ -393,7 +394,7 @@
 				       get_hard_smp_processor_id(cpu));
 		/*
 		 * If this is the last cpu in this chip then, skip the reference
-		 * count mutex lock and make the reference count on this chip zero.
+		 * count lock and make the reference count on this chip zero.
 		 */
 		ref = get_nest_pmu_ref(cpu);
 		if (!ref)
@@ -455,15 +456,15 @@
 	/*
 	 * See if we need to disable the nest PMU.
 	 * If no events are currently in use, then we have to take a
-	 * mutex to ensure that we don't race with another task doing
+	 * lock to ensure that we don't race with another task doing
 	 * enable or disable the nest counters.
 	 */
 	ref = get_nest_pmu_ref(event->cpu);
 	if (!ref)
 		return;
 
-	/* Take the mutex lock for this node and then decrement the reference count */
-	mutex_lock(&ref->lock);
+	/* Take the lock for this node and then decrement the reference count */
+	spin_lock(&ref->lock);
 	if (ref->refc == 0) {
 		/*
 		 * The scenario where this is true is, when perf session is
@@ -475,7 +476,7 @@
 		 * an OPAL call to disable the engine in that node.
 		 *
 		 */
-		mutex_unlock(&ref->lock);
+		spin_unlock(&ref->lock);
 		return;
 	}
 	ref->refc--;
@@ -483,7 +484,7 @@
 		rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST,
 					    get_hard_smp_processor_id(event->cpu));
 		if (rc) {
-			mutex_unlock(&ref->lock);
+			spin_unlock(&ref->lock);
 			pr_err("nest-imc: Unable to stop the counters for core %d\n", node_id);
 			return;
 		}
@@ -491,7 +492,7 @@
 		WARN(1, "nest-imc: Invalid event reference count\n");
 		ref->refc = 0;
 	}
-	mutex_unlock(&ref->lock);
+	spin_unlock(&ref->lock);
 }
 
 static int nest_imc_event_init(struct perf_event *event)
@@ -550,26 +551,25 @@
 
 	/*
 	 * Get the imc_pmu_ref struct for this node.
-	 * Take the mutex lock and then increment the count of nest pmu events
-	 * inited.
+	 * Take the lock and then increment the count of nest pmu events inited.
 	 */
 	ref = get_nest_pmu_ref(event->cpu);
 	if (!ref)
 		return -EINVAL;
 
-	mutex_lock(&ref->lock);
+	spin_lock(&ref->lock);
 	if (ref->refc == 0) {
 		rc = opal_imc_counters_start(OPAL_IMC_COUNTERS_NEST,
 					     get_hard_smp_processor_id(event->cpu));
 		if (rc) {
-			mutex_unlock(&ref->lock);
+			spin_unlock(&ref->lock);
 			pr_err("nest-imc: Unable to start the counters for node %d\n",
 									node_id);
 			return rc;
 		}
 	}
 	++ref->refc;
-	mutex_unlock(&ref->lock);
+	spin_unlock(&ref->lock);
 
 	event->destroy = nest_imc_counters_release;
 	return 0;
@@ -605,9 +605,8 @@
 		return -ENOMEM;
 	mem_info->vbase = page_address(page);
 
-	/* Init the mutex */
 	core_imc_refc[core_id].id = core_id;
-	mutex_init(&core_imc_refc[core_id].lock);
+	spin_lock_init(&core_imc_refc[core_id].lock);
 
 	rc = opal_imc_counters_init(OPAL_IMC_COUNTERS_CORE,
 				__pa((void *)mem_info->vbase),
@@ -696,9 +695,8 @@
 		perf_pmu_migrate_context(&core_imc_pmu->pmu, cpu, ncpu);
 	} else {
 		/*
-		 * If this is the last cpu in this core then, skip taking refernce
-		 * count mutex lock for this core and directly zero "refc" for
-		 * this core.
+		 * If this is the last cpu in this core then skip taking reference
+		 * count lock for this core and directly zero "refc" for this core.
 		 */
 		opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE,
 				       get_hard_smp_processor_id(cpu));
@@ -713,11 +711,11 @@
 		 * last cpu in this core and core-imc event running
 		 * in this cpu.
 		 */
-		mutex_lock(&imc_global_refc.lock);
+		spin_lock(&imc_global_refc.lock);
 		if (imc_global_refc.id == IMC_DOMAIN_CORE)
 			imc_global_refc.refc--;
 
-		mutex_unlock(&imc_global_refc.lock);
+		spin_unlock(&imc_global_refc.lock);
 	}
 	return 0;
 }
@@ -732,7 +730,7 @@
 
 static void reset_global_refc(struct perf_event *event)
 {
-		mutex_lock(&imc_global_refc.lock);
+		spin_lock(&imc_global_refc.lock);
 		imc_global_refc.refc--;
 
 		/*
@@ -744,7 +742,7 @@
 			imc_global_refc.refc = 0;
 			imc_global_refc.id = 0;
 		}
-		mutex_unlock(&imc_global_refc.lock);
+		spin_unlock(&imc_global_refc.lock);
 }
 
 static void core_imc_counters_release(struct perf_event *event)
@@ -757,17 +755,17 @@
 	/*
 	 * See if we need to disable the IMC PMU.
 	 * If no events are currently in use, then we have to take a
-	 * mutex to ensure that we don't race with another task doing
+	 * lock to ensure that we don't race with another task doing
 	 * enable or disable the core counters.
 	 */
 	core_id = event->cpu / threads_per_core;
 
-	/* Take the mutex lock and decrement the refernce count for this core */
+	/* Take the lock and decrement the refernce count for this core */
 	ref = &core_imc_refc[core_id];
 	if (!ref)
 		return;
 
-	mutex_lock(&ref->lock);
+	spin_lock(&ref->lock);
 	if (ref->refc == 0) {
 		/*
 		 * The scenario where this is true is, when perf session is
@@ -779,7 +777,7 @@
 		 * an OPAL call to disable the engine in that core.
 		 *
 		 */
-		mutex_unlock(&ref->lock);
+		spin_unlock(&ref->lock);
 		return;
 	}
 	ref->refc--;
@@ -787,7 +785,7 @@
 		rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE,
 					    get_hard_smp_processor_id(event->cpu));
 		if (rc) {
-			mutex_unlock(&ref->lock);
+			spin_unlock(&ref->lock);
 			pr_err("IMC: Unable to stop the counters for core %d\n", core_id);
 			return;
 		}
@@ -795,7 +793,7 @@
 		WARN(1, "core-imc: Invalid event reference count\n");
 		ref->refc = 0;
 	}
-	mutex_unlock(&ref->lock);
+	spin_unlock(&ref->lock);
 
 	reset_global_refc(event);
 }
@@ -833,7 +831,6 @@
 	if ((!pcmi->vbase))
 		return -ENODEV;
 
-	/* Get the core_imc mutex for this core */
 	ref = &core_imc_refc[core_id];
 	if (!ref)
 		return -EINVAL;
@@ -841,22 +838,22 @@
 	/*
 	 * Core pmu units are enabled only when it is used.
 	 * See if this is triggered for the first time.
-	 * If yes, take the mutex lock and enable the core counters.
+	 * If yes, take the lock and enable the core counters.
 	 * If not, just increment the count in core_imc_refc struct.
 	 */
-	mutex_lock(&ref->lock);
+	spin_lock(&ref->lock);
 	if (ref->refc == 0) {
 		rc = opal_imc_counters_start(OPAL_IMC_COUNTERS_CORE,
 					     get_hard_smp_processor_id(event->cpu));
 		if (rc) {
-			mutex_unlock(&ref->lock);
+			spin_unlock(&ref->lock);
 			pr_err("core-imc: Unable to start the counters for core %d\n",
 									core_id);
 			return rc;
 		}
 	}
 	++ref->refc;
-	mutex_unlock(&ref->lock);
+	spin_unlock(&ref->lock);
 
 	/*
 	 * Since the system can run either in accumulation or trace-mode
@@ -867,7 +864,7 @@
 	 * to know whether any other trace/thread imc
 	 * events are running.
 	 */
-	mutex_lock(&imc_global_refc.lock);
+	spin_lock(&imc_global_refc.lock);
 	if (imc_global_refc.id == 0 || imc_global_refc.id == IMC_DOMAIN_CORE) {
 		/*
 		 * No other trace/thread imc events are running in
@@ -876,10 +873,10 @@
 		imc_global_refc.id = IMC_DOMAIN_CORE;
 		imc_global_refc.refc++;
 	} else {
-		mutex_unlock(&imc_global_refc.lock);
+		spin_unlock(&imc_global_refc.lock);
 		return -EBUSY;
 	}
-	mutex_unlock(&imc_global_refc.lock);
+	spin_unlock(&imc_global_refc.lock);
 
 	event->hw.event_base = (u64)pcmi->vbase + (config & IMC_EVENT_OFFSET_MASK);
 	event->destroy = core_imc_counters_release;
@@ -951,10 +948,10 @@
 	mtspr(SPRN_LDBAR, (mfspr(SPRN_LDBAR) & (~(1UL << 63))));
 
 	/* Reduce the refc if thread-imc event running on this cpu */
-	mutex_lock(&imc_global_refc.lock);
+	spin_lock(&imc_global_refc.lock);
 	if (imc_global_refc.id == IMC_DOMAIN_THREAD)
 		imc_global_refc.refc--;
-	mutex_unlock(&imc_global_refc.lock);
+	spin_unlock(&imc_global_refc.lock);
 
 	return 0;
 }
@@ -994,7 +991,7 @@
 	if (!target)
 		return -EINVAL;
 
-	mutex_lock(&imc_global_refc.lock);
+	spin_lock(&imc_global_refc.lock);
 	/*
 	 * Check if any other trace/core imc events are running in the
 	 * system, if not set the global id to thread-imc.
@@ -1003,10 +1000,10 @@
 		imc_global_refc.id = IMC_DOMAIN_THREAD;
 		imc_global_refc.refc++;
 	} else {
-		mutex_unlock(&imc_global_refc.lock);
+		spin_unlock(&imc_global_refc.lock);
 		return -EBUSY;
 	}
-	mutex_unlock(&imc_global_refc.lock);
+	spin_unlock(&imc_global_refc.lock);
 
 	event->pmu->task_ctx_nr = perf_sw_context;
 	event->destroy = reset_global_refc;
@@ -1128,25 +1125,25 @@
 	/*
 	 * imc pmus are enabled only when it is used.
 	 * See if this is triggered for the first time.
-	 * If yes, take the mutex lock and enable the counters.
+	 * If yes, take the lock and enable the counters.
 	 * If not, just increment the count in ref count struct.
 	 */
 	ref = &core_imc_refc[core_id];
 	if (!ref)
 		return -EINVAL;
 
-	mutex_lock(&ref->lock);
+	spin_lock(&ref->lock);
 	if (ref->refc == 0) {
 		if (opal_imc_counters_start(OPAL_IMC_COUNTERS_CORE,
 		    get_hard_smp_processor_id(smp_processor_id()))) {
-			mutex_unlock(&ref->lock);
+			spin_unlock(&ref->lock);
 			pr_err("thread-imc: Unable to start the counter\
 				for core %d\n", core_id);
 			return -EINVAL;
 		}
 	}
 	++ref->refc;
-	mutex_unlock(&ref->lock);
+	spin_unlock(&ref->lock);
 	return 0;
 }
 
@@ -1163,12 +1160,12 @@
 		return;
 	}
 
-	mutex_lock(&ref->lock);
+	spin_lock(&ref->lock);
 	ref->refc--;
 	if (ref->refc == 0) {
 		if (opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE,
 		    get_hard_smp_processor_id(smp_processor_id()))) {
-			mutex_unlock(&ref->lock);
+			spin_unlock(&ref->lock);
 			pr_err("thread-imc: Unable to stop the counters\
 				for core %d\n", core_id);
 			return;
@@ -1176,7 +1173,7 @@
 	} else if (ref->refc < 0) {
 		ref->refc = 0;
 	}
-	mutex_unlock(&ref->lock);
+	spin_unlock(&ref->lock);
 
 	/* Set bit 0 of LDBAR to zero, to stop posting updates to memory */
 	mtspr(SPRN_LDBAR, (mfspr(SPRN_LDBAR) & (~(1UL << 63))));
@@ -1217,9 +1214,8 @@
 		}
 	}
 
-	/* Init the mutex, if not already */
 	trace_imc_refc[core_id].id = core_id;
-	mutex_init(&trace_imc_refc[core_id].lock);
+	spin_lock_init(&trace_imc_refc[core_id].lock);
 
 	mtspr(SPRN_LDBAR, 0);
 	return 0;
@@ -1239,10 +1235,10 @@
 	 * Reduce the refc if any trace-imc event running
 	 * on this cpu.
 	 */
-	mutex_lock(&imc_global_refc.lock);
+	spin_lock(&imc_global_refc.lock);
 	if (imc_global_refc.id == IMC_DOMAIN_TRACE)
 		imc_global_refc.refc--;
-	mutex_unlock(&imc_global_refc.lock);
+	spin_unlock(&imc_global_refc.lock);
 
 	return 0;
 }
@@ -1364,17 +1360,17 @@
 	}
 
 	mtspr(SPRN_LDBAR, ldbar_value);
-	mutex_lock(&ref->lock);
+	spin_lock(&ref->lock);
 	if (ref->refc == 0) {
 		if (opal_imc_counters_start(OPAL_IMC_COUNTERS_TRACE,
 				get_hard_smp_processor_id(smp_processor_id()))) {
-			mutex_unlock(&ref->lock);
+			spin_unlock(&ref->lock);
 			pr_err("trace-imc: Unable to start the counters for core %d\n", core_id);
 			return -EINVAL;
 		}
 	}
 	++ref->refc;
-	mutex_unlock(&ref->lock);
+	spin_unlock(&ref->lock);
 	return 0;
 }
 
@@ -1407,19 +1403,19 @@
 		return;
 	}
 
-	mutex_lock(&ref->lock);
+	spin_lock(&ref->lock);
 	ref->refc--;
 	if (ref->refc == 0) {
 		if (opal_imc_counters_stop(OPAL_IMC_COUNTERS_TRACE,
 				get_hard_smp_processor_id(smp_processor_id()))) {
-			mutex_unlock(&ref->lock);
+			spin_unlock(&ref->lock);
 			pr_err("trace-imc: Unable to stop the counters for core %d\n", core_id);
 			return;
 		}
 	} else if (ref->refc < 0) {
 		ref->refc = 0;
 	}
-	mutex_unlock(&ref->lock);
+	spin_unlock(&ref->lock);
 
 	trace_imc_event_stop(event, flags);
 }
@@ -1441,7 +1437,7 @@
 	 * no other thread is running any core/thread imc
 	 * events
 	 */
-	mutex_lock(&imc_global_refc.lock);
+	spin_lock(&imc_global_refc.lock);
 	if (imc_global_refc.id == 0 || imc_global_refc.id == IMC_DOMAIN_TRACE) {
 		/*
 		 * No core/thread imc events are running in the
@@ -1450,10 +1446,10 @@
 		imc_global_refc.id = IMC_DOMAIN_TRACE;
 		imc_global_refc.refc++;
 	} else {
-		mutex_unlock(&imc_global_refc.lock);
+		spin_unlock(&imc_global_refc.lock);
 		return -EBUSY;
 	}
-	mutex_unlock(&imc_global_refc.lock);
+	spin_unlock(&imc_global_refc.lock);
 
 	event->hw.idx = -1;
 
@@ -1525,10 +1521,10 @@
 	i = 0;
 	for_each_node(nid) {
 		/*
-		 * Mutex lock to avoid races while tracking the number of
+		 * Take the lock to avoid races while tracking the number of
 		 * sessions using the chip's nest pmu units.
 		 */
-		mutex_init(&nest_imc_refc[i].lock);
+		spin_lock_init(&nest_imc_refc[i].lock);
 
 		/*
 		 * Loop to init the "id" with the node_id. Variable "i" initialized to
diff --git a/kernel/arch/powerpc/perf/req-gen/perf.h b/kernel/arch/powerpc/perf/req-gen/perf.h
index fa9bc80..6b2a59f 100644
--- a/kernel/arch/powerpc/perf/req-gen/perf.h
+++ b/kernel/arch/powerpc/perf/req-gen/perf.h
@@ -139,6 +139,26 @@
 #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
diff --git a/kernel/arch/powerpc/platforms/512x/clock-commonclk.c b/kernel/arch/powerpc/platforms/512x/clock-commonclk.c
index 30342b6..42c3d40 100644
--- a/kernel/arch/powerpc/platforms/512x/clock-commonclk.c
+++ b/kernel/arch/powerpc/platforms/512x/clock-commonclk.c
@@ -984,7 +984,7 @@
 
 #define NODE_PREP do { \
 	of_address_to_resource(np, 0, &res); \
-	snprintf(devname, sizeof(devname), "%08x.%s", res.start, np->name); \
+	snprintf(devname, sizeof(devname), "%pa.%s", &res.start, np->name); \
 } while (0)
 
 #define NODE_CHK(clkname, clkitem, regnode, regflag) do { \
diff --git a/kernel/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/kernel/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
index 05e1947..22e264b 100644
--- a/kernel/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+++ b/kernel/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
@@ -530,6 +530,7 @@
  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;
diff --git a/kernel/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/kernel/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index 622c625..1114b6a 100644
--- a/kernel/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/kernel/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -106,7 +106,7 @@
 
 		goto next;
 unreg:
-		platform_device_del(pdev);
+		platform_device_put(pdev);
 err:
 		pr_err("%pOF: registration failed\n", np);
 next:
diff --git a/kernel/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/kernel/arch/powerpc/platforms/embedded6xx/flipper-pic.c
index d39a921..7dd2e2f 100644
--- a/kernel/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+++ b/kernel/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -144,7 +144,7 @@
 	}
 	io_base = ioremap(res.start, resource_size(&res));
 
-	pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base);
+	pr_info("controller at 0x%pa mapped to 0x%p\n", &res.start, io_base);
 
 	__flipper_quiesce(io_base);
 
diff --git a/kernel/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/kernel/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index de10c13..c6b492e 100644
--- a/kernel/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/kernel/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -173,7 +173,7 @@
 		return NULL;
 	}
 
-	pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base);
+	pr_info("controller at 0x%pa mapped to 0x%p\n", &res.start, io_base);
 
 	__hlwd_quiesce(io_base);
 
diff --git a/kernel/arch/powerpc/platforms/embedded6xx/wii.c b/kernel/arch/powerpc/platforms/embedded6xx/wii.c
index a802ef9..458a63a 100644
--- a/kernel/arch/powerpc/platforms/embedded6xx/wii.c
+++ b/kernel/arch/powerpc/platforms/embedded6xx/wii.c
@@ -89,8 +89,8 @@
 
 	hw_regs = ioremap(res.start, resource_size(&res));
 	if (hw_regs) {
-		pr_info("%s at 0x%08x mapped to 0x%p\n", name,
-			res.start, hw_regs);
+		pr_info("%s at 0x%pa mapped to 0x%p\n", name,
+			&res.start, hw_regs);
 	}
 
 out_put:
diff --git a/kernel/arch/powerpc/platforms/powernv/pci-ioda.c b/kernel/arch/powerpc/platforms/powernv/pci-ioda.c
index 2b4ceb5..a1e6dd4 100644
--- a/kernel/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/kernel/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2260,7 +2260,8 @@
 	int index;
 	int64_t rc;
 
-	if (!res || !res->flags || res->start > res->end)
+	if (!res || !res->flags || res->start > res->end ||
+	    res->flags & IORESOURCE_UNSET)
 		return;
 
 	if (res->flags & IORESOURCE_IO) {
diff --git a/kernel/arch/powerpc/platforms/powernv/pci-sriov.c b/kernel/arch/powerpc/platforms/powernv/pci-sriov.c
index 28aac93..e3e52ff 100644
--- a/kernel/arch/powerpc/platforms/powernv/pci-sriov.c
+++ b/kernel/arch/powerpc/platforms/powernv/pci-sriov.c
@@ -600,12 +600,12 @@
 	struct pnv_iov_data   *iov;
 
 	iov = pnv_iov_get(pdev);
-	num_vfs = iov->num_vfs;
-	base_pe = iov->vf_pe_arr[0].pe_number;
-
 	if (WARN_ON(!iov))
 		return;
 
+	num_vfs = iov->num_vfs;
+	base_pe = iov->vf_pe_arr[0].pe_number;
+
 	/* Release VF PEs */
 	pnv_ioda_release_vf_PE(pdev);
 
diff --git a/kernel/arch/powerpc/platforms/pseries/eeh_pseries.c b/kernel/arch/powerpc/platforms/pseries/eeh_pseries.c
index 7ed38eb..4601ad1 100644
--- a/kernel/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ b/kernel/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -846,18 +846,8 @@
 		return -EINVAL;
 	}
 
-	/* Initialize error log lock and size */
-	spin_lock_init(&slot_errbuf_lock);
-	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;
-	}
+	/* Initialize error log size */
+	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);
diff --git a/kernel/arch/powerpc/platforms/pseries/firmware.c b/kernel/arch/powerpc/platforms/pseries/firmware.c
index 4c7b7f5..f162156 100644
--- a/kernel/arch/powerpc/platforms/pseries/firmware.c
+++ b/kernel/arch/powerpc/platforms/pseries/firmware.c
@@ -119,10 +119,11 @@
 
 static __initdata struct vec5_fw_feature
 vec5_fw_features_table[] = {
-	{FW_FEATURE_TYPE1_AFFINITY,	OV5_TYPE1_AFFINITY},
+	{FW_FEATURE_FORM1_AFFINITY,	OV5_FORM1_AFFINITY},
 	{FW_FEATURE_PRRN,		OV5_PRRN},
 	{FW_FEATURE_DRMEM_V2,		OV5_DRMEM_V2},
 	{FW_FEATURE_DRC_INFO,		OV5_DRC_INFO},
+	{FW_FEATURE_FORM2_AFFINITY,	OV5_FORM2_AFFINITY},
 };
 
 static void __init fw_vec5_feature_init(const char *vec5, unsigned long len)
diff --git a/kernel/arch/powerpc/platforms/pseries/hotplug-cpu.c b/kernel/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 325f3b2..1f8f972 100644
--- a/kernel/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/kernel/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -484,6 +484,8 @@
 		return saved_rc;
 	}
 
+	update_numa_distance(dn);
+
 	rc = dlpar_online_cpu(dn);
 	if (rc) {
 		saved_rc = rc;
diff --git a/kernel/arch/powerpc/platforms/pseries/hotplug-memory.c b/kernel/arch/powerpc/platforms/pseries/hotplug-memory.c
index 7efe6ec..a5f968b 100644
--- a/kernel/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/kernel/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -180,6 +180,8 @@
 		return -ENODEV;
 	}
 
+	update_numa_distance(lmb_node);
+
 	dr_node = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
 	if (!dr_node) {
 		dlpar_free_cc_nodes(lmb_node);
diff --git a/kernel/arch/powerpc/platforms/pseries/ibmebus.c b/kernel/arch/powerpc/platforms/pseries/ibmebus.c
index 8c6e509..c3cc010 100644
--- a/kernel/arch/powerpc/platforms/pseries/ibmebus.c
+++ b/kernel/arch/powerpc/platforms/pseries/ibmebus.c
@@ -451,6 +451,7 @@
 	if (err) {
 		printk(KERN_WARNING "%s: device_register returned %i\n",
 		       __func__, err);
+		put_device(&ibmebus_bus_device);
 		bus_unregister(&ibmebus_bus_type);
 
 		return err;
diff --git a/kernel/arch/powerpc/platforms/pseries/lpar.c b/kernel/arch/powerpc/platforms/pseries/lpar.c
index 1c3ac0f..68f3b08 100644
--- a/kernel/arch/powerpc/platforms/pseries/lpar.c
+++ b/kernel/arch/powerpc/platforms/pseries/lpar.c
@@ -261,7 +261,7 @@
 	if (!last_disp_cpu_assoc || !cur_disp_cpu_assoc)
 		return -EIO;
 
-	return cpu_distance(last_disp_cpu_assoc, cur_disp_cpu_assoc);
+	return cpu_relative_distance(last_disp_cpu_assoc, cur_disp_cpu_assoc);
 }
 
 static int cpu_home_node_dispatch_distance(int disp_cpu)
@@ -281,7 +281,7 @@
 	if (!disp_cpu_assoc || !vcpu_assoc)
 		return -EIO;
 
-	return cpu_distance(disp_cpu_assoc, vcpu_assoc);
+	return cpu_relative_distance(disp_cpu_assoc, vcpu_assoc);
 }
 
 static void update_vcpu_disp_stat(int disp_cpu)
@@ -637,16 +637,8 @@
 
 static int __init vcpudispatch_stats_procfs_init(void)
 {
-	/*
-	 * Avoid smp_processor_id while preemptible. All CPUs should have
-	 * the same value for lppaca_shared_proc.
-	 */
-	preempt_disable();
-	if (!lppaca_shared_proc(get_lppaca())) {
-		preempt_enable();
+	if (!lppaca_shared_proc())
 		return 0;
-	}
-	preempt_enable();
 
 	if (!proc_create("powerpc/vcpudispatch_stats", 0600, NULL,
 					&vcpudispatch_stats_proc_ops))
@@ -1433,22 +1425,22 @@
 
 void __init pseries_lpar_read_hblkrm_characteristics(void)
 {
+	const s32 token = rtas_token("ibm,get-system-parameter");
 	unsigned char local_buffer[SPLPAR_TLB_BIC_MAXLENGTH];
 	int call_status, len, idx, bpsize;
 
 	if (!firmware_has_feature(FW_FEATURE_BLOCK_REMOVE))
 		return;
 
-	spin_lock(&rtas_data_buf_lock);
-	memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE);
-	call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
-				NULL,
-				SPLPAR_TLB_BIC_TOKEN,
-				__pa(rtas_data_buf),
-				RTAS_DATA_BUF_SIZE);
-	memcpy(local_buffer, rtas_data_buf, SPLPAR_TLB_BIC_MAXLENGTH);
-	local_buffer[SPLPAR_TLB_BIC_MAXLENGTH - 1] = '\0';
-	spin_unlock(&rtas_data_buf_lock);
+	do {
+		spin_lock(&rtas_data_buf_lock);
+		memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE);
+		call_status = rtas_call(token, 3, 1, NULL, SPLPAR_TLB_BIC_TOKEN,
+					__pa(rtas_data_buf), RTAS_DATA_BUF_SIZE);
+		memcpy(local_buffer, rtas_data_buf, SPLPAR_TLB_BIC_MAXLENGTH);
+		local_buffer[SPLPAR_TLB_BIC_MAXLENGTH - 1] = '\0';
+		spin_unlock(&rtas_data_buf_lock);
+	} while (rtas_busy_delay(call_status));
 
 	if (call_status != 0) {
 		pr_warn("%s %s Error calling get-system-parameter (0x%x)\n",
diff --git a/kernel/arch/powerpc/platforms/pseries/lparcfg.c b/kernel/arch/powerpc/platforms/pseries/lparcfg.c
index e278390..a7d4e25 100644
--- a/kernel/arch/powerpc/platforms/pseries/lparcfg.c
+++ b/kernel/arch/powerpc/platforms/pseries/lparcfg.c
@@ -205,7 +205,7 @@
 	           ppp_data.active_system_procs);
 
 	/* pool related entries are appropriate for shared configs */
-	if (lppaca_shared_proc(get_lppaca())) {
+	if (lppaca_shared_proc()) {
 		unsigned long pool_idle_time, pool_procs;
 
 		seq_printf(m, "pool=%d\n", ppp_data.pool_num);
@@ -322,6 +322,7 @@
  */
 static void parse_system_parameter_string(struct seq_file *m)
 {
+	const s32 token = rtas_token("ibm,get-system-parameter");
 	int call_status;
 
 	unsigned char *local_buffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
@@ -331,16 +332,15 @@
 		return;
 	}
 
-	spin_lock(&rtas_data_buf_lock);
-	memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH);
-	call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
-				NULL,
-				SPLPAR_CHARACTERISTICS_TOKEN,
-				__pa(rtas_data_buf),
-				RTAS_DATA_BUF_SIZE);
-	memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH);
-	local_buffer[SPLPAR_MAXLENGTH - 1] = '\0';
-	spin_unlock(&rtas_data_buf_lock);
+	do {
+		spin_lock(&rtas_data_buf_lock);
+		memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH);
+		call_status = rtas_call(token, 3, 1, NULL, SPLPAR_CHARACTERISTICS_TOKEN,
+					__pa(rtas_data_buf), RTAS_DATA_BUF_SIZE);
+		memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH);
+		local_buffer[SPLPAR_MAXLENGTH - 1] = '\0';
+		spin_unlock(&rtas_data_buf_lock);
+	} while (rtas_busy_delay(call_status));
 
 	if (call_status != 0) {
 		printk(KERN_INFO
@@ -529,7 +529,7 @@
 		   partition_potential_processors);
 
 	seq_printf(m, "shared_processor_mode=%d\n",
-		   lppaca_shared_proc(get_lppaca()));
+		   lppaca_shared_proc());
 
 #ifdef CONFIG_PPC_BOOK3S_64
 	seq_printf(m, "slb_size=%d\n", mmu_slb_size);
diff --git a/kernel/arch/powerpc/platforms/pseries/papr_scm.c b/kernel/arch/powerpc/platforms/pseries/papr_scm.c
index 057acbb..e3b7698 100644
--- a/kernel/arch/powerpc/platforms/pseries/papr_scm.c
+++ b/kernel/arch/powerpc/platforms/pseries/papr_scm.c
@@ -1079,6 +1079,13 @@
 		return -ENODEV;
 	}
 
+	/*
+	 * open firmware platform device create won't update the NUMA 
+	 * distance table. For PAPR SCM devices we use numa_map_to_online_node()
+	 * to find the nearest online NUMA node and that requires correct
+	 * distance table information.
+	 */
+	update_numa_distance(dn);
 
 	p = kzalloc(sizeof(*p), GFP_KERNEL);
 	if (!p)
diff --git a/kernel/arch/powerpc/platforms/pseries/setup.c b/kernel/arch/powerpc/platforms/pseries/setup.c
index 0eac9ca..822be26 100644
--- a/kernel/arch/powerpc/platforms/pseries/setup.c
+++ b/kernel/arch/powerpc/platforms/pseries/setup.c
@@ -800,7 +800,7 @@
 	if (firmware_has_feature(FW_FEATURE_LPAR)) {
 		vpa_init(boot_cpuid);
 
-		if (lppaca_shared_proc(get_lppaca())) {
+		if (lppaca_shared_proc()) {
 			static_branch_enable(&shared_processor);
 			pv_spinlocks_init();
 		}
diff --git a/kernel/arch/powerpc/purgatory/Makefile b/kernel/arch/powerpc/purgatory/Makefile
index 348f595..d08239a 100644
--- a/kernel/arch/powerpc/purgatory/Makefile
+++ b/kernel/arch/powerpc/purgatory/Makefile
@@ -4,6 +4,11 @@
 
 targets += trampoline_$(BITS).o purgatory.ro kexec-purgatory.c
 
+# When profile-guided optimization is enabled, llvm emits two different
+# overlapping text sections, which is not supported by kexec. Remove profile
+# optimization flags.
+KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%,$(KBUILD_CFLAGS))
+
 LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined
 
 $(obj)/purgatory.ro: $(obj)/trampoline_$(BITS).o FORCE
diff --git a/kernel/arch/powerpc/sysdev/tsi108_pci.c b/kernel/arch/powerpc/sysdev/tsi108_pci.c
index 49f9541..3664ffc 100644
--- a/kernel/arch/powerpc/sysdev/tsi108_pci.c
+++ b/kernel/arch/powerpc/sysdev/tsi108_pci.c
@@ -216,9 +216,8 @@
 
 	(hose)->ops = &tsi108_direct_pci_ops;
 
-	printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08x. "
-	       "Firmware bus number: %d->%d\n",
-	       rsrc.start, hose->first_busno, hose->last_busno);
+	pr_info("Found tsi108 PCI host bridge at 0x%pa. Firmware bus number: %d->%d\n",
+		&rsrc.start, hose->first_busno, hose->last_busno);
 
 	/* Interpret the "ranges" property */
 	/* This also maps the I/O region and sets isa_io/mem_base */
diff --git a/kernel/arch/powerpc/sysdev/xive/spapr.c b/kernel/arch/powerpc/sysdev/xive/spapr.c
index 38e8b98..53cf143 100644
--- a/kernel/arch/powerpc/sysdev/xive/spapr.c
+++ b/kernel/arch/powerpc/sysdev/xive/spapr.c
@@ -425,6 +425,7 @@
 
 	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;
 	}
diff --git a/kernel/arch/powerpc/xmon/xmon.c b/kernel/arch/powerpc/xmon/xmon.c
index 5559edf..3de2adc 100644
--- a/kernel/arch/powerpc/xmon/xmon.c
+++ b/kernel/arch/powerpc/xmon/xmon.c
@@ -58,6 +58,7 @@
 #ifdef CONFIG_PPC64
 #include <asm/hvcall.h>
 #include <asm/paca.h>
+#include <asm/lppaca.h>
 #endif
 
 #include "nonstdio.h"
@@ -1383,7 +1384,6 @@
 	return 1;
 }
 
-#ifndef CONFIG_PPC_8xx
 static int find_free_data_bpt(void)
 {
 	int i;
@@ -1395,7 +1395,6 @@
 	printf("Couldn't find free breakpoint register\n");
 	return -1;
 }
-#endif
 
 static void print_data_bpts(void)
 {
@@ -1435,10 +1434,9 @@
 	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 */
+	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;
@@ -1471,6 +1469,7 @@
 
 		force_enable_xmon();
 		break;
+	}
 
 	case 'i':	/* bi - hardware instr breakpoint */
 		if (xmon_is_ro) {
@@ -1497,7 +1496,6 @@
 			force_enable_xmon();
 		}
 		break;
-#endif
 
 	case 'c':
 		if (!scanhex(&a)) {
diff --git a/kernel/arch/riscv/Kconfig b/kernel/arch/riscv/Kconfig
index 557c4a8..b28fabf 100644
--- a/kernel/arch/riscv/Kconfig
+++ b/kernel/arch/riscv/Kconfig
@@ -22,6 +22,7 @@
 	select ARCH_HAS_GIGANTIC_PAGE
 	select ARCH_HAS_KCOV
 	select ARCH_HAS_MMIOWB
+	select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
 	select ARCH_HAS_PTE_SPECIAL
 	select ARCH_HAS_SET_DIRECT_MAP
 	select ARCH_HAS_SET_MEMORY
@@ -331,6 +332,28 @@
 
 endmenu
 
+config TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI
+	def_bool y
+	# https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=aed44286efa8ae8717a77d94b51ac3614e2ca6dc
+	depends on AS_IS_GNU && AS_VERSION >= 23800
+	help
+	  Newer binutils versions default to ISA spec version 20191213 which
+	  moves some instructions from the I extension to the Zicsr and Zifencei
+	  extensions.
+
+config TOOLCHAIN_NEEDS_OLD_ISA_SPEC
+	def_bool y
+	depends on TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI
+	# https://github.com/llvm/llvm-project/commit/22e199e6afb1263c943c0c0d4498694e15bf8a16
+	depends on CC_IS_CLANG && CLANG_VERSION < 170000
+	help
+	  Certain versions of clang do not support zicsr and zifencei via -march
+	  but newer versions of binutils require it for the reasons noted in the
+	  help text of CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI. This
+	  option causes an older ISA spec compatible with these older versions
+	  of clang to be passed to GAS, which has the same result as passing zicsr
+	  and zifencei to -march.
+
 config FPU
 	bool "FPU support"
 	default y
diff --git a/kernel/arch/riscv/Makefile b/kernel/arch/riscv/Makefile
index 1bb1bf1..daa6794 100644
--- a/kernel/arch/riscv/Makefile
+++ b/kernel/arch/riscv/Makefile
@@ -40,7 +40,7 @@
 ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 150000; echo $$?),0)
 	KBUILD_CFLAGS += -mno-relax
 	KBUILD_AFLAGS += -mno-relax
-ifneq ($(LLVM_IAS),1)
+ifndef CONFIG_AS_IS_LLVM
 	KBUILD_CFLAGS += -Wa,-mno-relax
 	KBUILD_AFLAGS += -Wa,-mno-relax
 endif
@@ -53,10 +53,12 @@
 riscv-march-$(CONFIG_FPU)		:= $(riscv-march-y)fd
 riscv-march-$(CONFIG_RISCV_ISA_C)	:= $(riscv-march-y)c
 
-# Newer binutils versions default to ISA spec version 20191213 which moves some
-# instructions from the I extension to the Zicsr and Zifencei extensions.
-toolchain-need-zicsr-zifencei := $(call cc-option-yn, -march=$(riscv-march-y)_zicsr_zifencei)
-riscv-march-$(toolchain-need-zicsr-zifencei) := $(riscv-march-y)_zicsr_zifencei
+ifdef CONFIG_TOOLCHAIN_NEEDS_OLD_ISA_SPEC
+KBUILD_CFLAGS += -Wa,-misa-spec=2.2
+KBUILD_AFLAGS += -Wa,-misa-spec=2.2
+else
+riscv-march-$(CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI) := $(riscv-march-y)_zicsr_zifencei
+endif
 
 KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y))
 KBUILD_AFLAGS += -march=$(riscv-march-y)
@@ -74,6 +76,9 @@
         KBUILD_CFLAGS += -fno-omit-frame-pointer
 endif
 
+# Avoid generating .eh_frame sections.
+KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables
+
 KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax)
 KBUILD_AFLAGS_MODULE += $(call as-option,-Wa$(comma)-mno-relax)
 
diff --git a/kernel/arch/riscv/include/asm/ftrace.h b/kernel/arch/riscv/include/asm/ftrace.h
index 04dad33..bc74590 100644
--- a/kernel/arch/riscv/include/asm/ftrace.h
+++ b/kernel/arch/riscv/include/asm/ftrace.h
@@ -83,6 +83,6 @@
 #define ftrace_init_nop ftrace_init_nop
 #endif
 
-#endif
+#endif /* CONFIG_DYNAMIC_FTRACE */
 
 #endif /* _ASM_RISCV_FTRACE_H */
diff --git a/kernel/arch/riscv/include/asm/hugetlb.h b/kernel/arch/riscv/include/asm/hugetlb.h
index a5c2ca1..ec19d6a 100644
--- a/kernel/arch/riscv/include/asm/hugetlb.h
+++ b/kernel/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 */
diff --git a/kernel/arch/riscv/include/asm/jump_label.h b/kernel/arch/riscv/include/asm/jump_label.h
index 38af2ec..729991e 100644
--- a/kernel/arch/riscv/include/asm/jump_label.h
+++ b/kernel/arch/riscv/include/asm/jump_label.h
@@ -18,6 +18,7 @@
 					       bool branch)
 {
 	asm_volatile_goto(
+		"	.align		2			\n\t"
 		"	.option push				\n\t"
 		"	.option norelax				\n\t"
 		"	.option norvc				\n\t"
@@ -39,6 +40,7 @@
 						    bool branch)
 {
 	asm_volatile_goto(
+		"	.align		2			\n\t"
 		"	.option push				\n\t"
 		"	.option norelax				\n\t"
 		"	.option norvc				\n\t"
diff --git a/kernel/arch/riscv/include/asm/mmio.h b/kernel/arch/riscv/include/asm/mmio.h
index aff6c33..4c58ee7 100644
--- a/kernel/arch/riscv/include/asm/mmio.h
+++ b/kernel/arch/riscv/include/asm/mmio.h
@@ -101,9 +101,9 @@
  * Relaxed I/O memory access primitives. These follow the Device memory
  * ordering rules but do not guarantee any ordering relative to Normal memory
  * accesses.  These are defined to order the indicated access (either a read or
- * write) with all other I/O memory accesses. Since the platform specification
- * defines that all I/O regions are strongly ordered on channel 2, no explicit
- * fences are required to enforce this ordering.
+ * write) with all other I/O memory accesses to the same peripheral. Since the
+ * platform specification defines that all I/O regions are strongly ordered on
+ * channel 0, no explicit fences are required to enforce this ordering.
  */
 /* FIXME: These are now the same as asm-generic */
 #define __io_rbr()		do {} while (0)
@@ -125,14 +125,14 @@
 #endif
 
 /*
- * I/O memory access primitives. Reads are ordered relative to any
- * following Normal memory access. Writes are ordered relative to any prior
- * Normal memory access.  The memory barriers here are necessary as RISC-V
+ * I/O memory access primitives.  Reads are ordered relative to any following
+ * Normal memory read and delay() loop.  Writes are ordered relative to any
+ * prior Normal memory write.  The memory barriers here are necessary as RISC-V
  * doesn't define any ordering between the memory space and the I/O space.
  */
 #define __io_br()	do {} while (0)
-#define __io_ar(v)	__asm__ __volatile__ ("fence i,r" : : : "memory")
-#define __io_bw()	__asm__ __volatile__ ("fence w,o" : : : "memory")
+#define __io_ar(v)	({ __asm__ __volatile__ ("fence i,ir" : : : "memory"); })
+#define __io_bw()	({ __asm__ __volatile__ ("fence w,o" : : : "memory"); })
 #define __io_aw()	mmiowb_set_pending()
 
 #define readb(c)	({ u8  __v; __io_br(); __v = readb_cpu(c); __io_ar(__v); __v; })
diff --git a/kernel/arch/riscv/include/asm/parse_asm.h b/kernel/arch/riscv/include/asm/parse_asm.h
index f36368d..ad254da 100644
--- a/kernel/arch/riscv/include/asm/parse_asm.h
+++ b/kernel/arch/riscv/include/asm/parse_asm.h
@@ -3,6 +3,9 @@
  * Copyright (C) 2020 SiFive
  */
 
+#ifndef _ASM_RISCV_INSN_H
+#define _ASM_RISCV_INSN_H
+
 #include <linux/bits.h>
 
 /* The bit field of immediate value in I-type instruction */
@@ -125,7 +128,7 @@
 #define FUNCT3_C_J		0xa000
 #define FUNCT3_C_JAL		0x2000
 #define FUNCT4_C_JR		0x8000
-#define FUNCT4_C_JALR		0xf000
+#define FUNCT4_C_JALR		0x9000
 
 #define FUNCT12_SRET		0x10200000
 
@@ -217,3 +220,5 @@
 	(RVC_X(x_, RVC_B_IMM_5_OPOFF, RVC_B_IMM_5_MASK) << RVC_B_IMM_5_OFF) | \
 	(RVC_X(x_, RVC_B_IMM_7_6_OPOFF, RVC_B_IMM_7_6_MASK) << RVC_B_IMM_7_6_OFF) | \
 	(RVC_IMM_SIGN(x_) << RVC_B_IMM_SIGN_OFF); })
+
+#endif /* _ASM_RISCV_INSN_H */
diff --git a/kernel/arch/riscv/include/asm/patch.h b/kernel/arch/riscv/include/asm/patch.h
index 9a7d734..98d9de0 100644
--- a/kernel/arch/riscv/include/asm/patch.h
+++ b/kernel/arch/riscv/include/asm/patch.h
@@ -9,4 +9,6 @@
 int patch_text_nosync(void *addr, const void *insns, size_t len);
 int patch_text(void *addr, u32 insn);
 
+extern int riscv_patch_in_stop_machine;
+
 #endif /* _ASM_RISCV_PATCH_H */
diff --git a/kernel/arch/riscv/include/asm/pgtable-64.h b/kernel/arch/riscv/include/asm/pgtable-64.h
index f3b0da6..0e863f3 100644
--- a/kernel/arch/riscv/include/asm/pgtable-64.h
+++ b/kernel/arch/riscv/include/asm/pgtable-64.h
@@ -60,9 +60,9 @@
 	set_pud(pudp, __pud(0));
 }
 
-static inline unsigned long pud_page_vaddr(pud_t pud)
+static inline pmd_t *pud_pgtable(pud_t pud)
 {
-	return (unsigned long)pfn_to_virt(pud_val(pud) >> _PAGE_PFN_SHIFT);
+	return (pmd_t *)pfn_to_virt(pud_val(pud) >> _PAGE_PFN_SHIFT);
 }
 
 static inline struct page *pud_page(pud_t pud)
diff --git a/kernel/arch/riscv/include/asm/uaccess.h b/kernel/arch/riscv/include/asm/uaccess.h
index f944062..66af6ab 100644
--- a/kernel/arch/riscv/include/asm/uaccess.h
+++ b/kernel/arch/riscv/include/asm/uaccess.h
@@ -216,7 +216,7 @@
 	might_fault();						\
 	access_ok(__p, sizeof(*__p)) ?		\
 		__get_user((x), __p) :				\
-		((x) = 0, -EFAULT);				\
+		((x) = (__force __typeof__(x))0, -EFAULT);	\
 })
 
 #define __put_user_asm(insn, x, ptr, err)			\
diff --git a/kernel/arch/riscv/include/uapi/asm/setup.h b/kernel/arch/riscv/include/uapi/asm/setup.h
new file mode 100644
index 0000000..66b13a5
--- /dev/null
+++ b/kernel/arch/riscv/include/uapi/asm/setup.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+
+#ifndef _UAPI_ASM_RISCV_SETUP_H
+#define _UAPI_ASM_RISCV_SETUP_H
+
+#define COMMAND_LINE_SIZE	1024
+
+#endif /* _UAPI_ASM_RISCV_SETUP_H */
diff --git a/kernel/arch/riscv/kernel/ftrace.c b/kernel/arch/riscv/kernel/ftrace.c
index 765b624..8693dfc 100644
--- a/kernel/arch/riscv/kernel/ftrace.c
+++ b/kernel/arch/riscv/kernel/ftrace.c
@@ -15,11 +15,21 @@
 int ftrace_arch_code_modify_prepare(void) __acquires(&text_mutex)
 {
 	mutex_lock(&text_mutex);
+
+	/*
+	 * The code sequences we use for ftrace can't be patched while the
+	 * kernel is running, so we need to use stop_machine() to modify them
+	 * for now.  This doesn't play nice with text_mutex, we use this flag
+	 * to elide the check.
+	 */
+	riscv_patch_in_stop_machine = true;
+
 	return 0;
 }
 
 int ftrace_arch_code_modify_post_process(void) __releases(&text_mutex)
 {
+	riscv_patch_in_stop_machine = false;
 	mutex_unlock(&text_mutex);
 	return 0;
 }
@@ -109,9 +119,9 @@
 {
 	int out;
 
-	ftrace_arch_code_modify_prepare();
+	mutex_lock(&text_mutex);
 	out = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
-	ftrace_arch_code_modify_post_process();
+	mutex_unlock(&text_mutex);
 
 	return out;
 }
diff --git a/kernel/arch/riscv/kernel/patch.c b/kernel/arch/riscv/kernel/patch.c
index 1612e11..c3fced4 100644
--- a/kernel/arch/riscv/kernel/patch.c
+++ b/kernel/arch/riscv/kernel/patch.c
@@ -11,6 +11,7 @@
 #include <asm/kprobes.h>
 #include <asm/cacheflush.h>
 #include <asm/fixmap.h>
+#include <asm/ftrace.h>
 #include <asm/patch.h>
 
 struct patch_insn {
@@ -18,6 +19,8 @@
 	u32 insn;
 	atomic_t cpu_count;
 };
+
+int riscv_patch_in_stop_machine = false;
 
 #ifdef CONFIG_MMU
 static void *patch_map(void *addr, int fixmap)
@@ -55,8 +58,15 @@
 	 * Before reaching here, it was expected to lock the text_mutex
 	 * already, so we don't need to give another lock here and could
 	 * ensure that it was safe between each cores.
+	 *
+	 * We're currently using stop_machine() for ftrace & kprobes, and while
+	 * that ensures text_mutex is held before installing the mappings it
+	 * does not ensure text_mutex is held by the calling thread.  That's
+	 * safe but triggers a lockdep failure, so just elide it for that
+	 * specific case.
 	 */
-	lockdep_assert_held(&text_mutex);
+	if (!riscv_patch_in_stop_machine)
+		lockdep_assert_held(&text_mutex);
 
 	if (across_pages)
 		patch_map(addr + len, FIX_TEXT_POKE1);
@@ -117,13 +127,25 @@
 
 int patch_text(void *addr, u32 insn)
 {
+	int ret;
 	struct patch_insn patch = {
 		.addr = addr,
 		.insn = insn,
 		.cpu_count = ATOMIC_INIT(0),
 	};
 
-	return stop_machine_cpuslocked(patch_text_cb,
-				       &patch, cpu_online_mask);
+	/*
+	 * kprobes takes text_mutex, before calling patch_text(), but as we call
+	 * calls stop_machine(), the lockdep assertion in patch_insn_write()
+	 * gets confused by the context in which the lock is taken.
+	 * Instead, ensure the lock is held before calling stop_machine(), and
+	 * set riscv_patch_in_stop_machine to skip the check in
+	 * patch_insn_write().
+	 */
+	lockdep_assert_held(&text_mutex);
+	riscv_patch_in_stop_machine = true;
+	ret = stop_machine_cpuslocked(patch_text_cb, &patch, cpu_online_mask);
+	riscv_patch_in_stop_machine = false;
+	return ret;
 }
 NOKPROBE_SYMBOL(patch_text);
diff --git a/kernel/arch/riscv/kernel/signal.c b/kernel/arch/riscv/kernel/signal.c
index 50a8225..dd63407 100644
--- a/kernel/arch/riscv/kernel/signal.c
+++ b/kernel/arch/riscv/kernel/signal.c
@@ -16,6 +16,7 @@
 #include <asm/vdso.h>
 #include <asm/switch_to.h>
 #include <asm/csr.h>
+#include <asm/cacheflush.h>
 
 extern u32 __user_rt_sigreturn[2];
 
@@ -178,6 +179,7 @@
 {
 	struct rt_sigframe __user *frame;
 	long err = 0;
+	unsigned long __maybe_unused addr;
 
 	frame = get_sigframe(ksig, regs, sizeof(*frame));
 	if (!access_ok(frame, sizeof(*frame)))
@@ -206,7 +208,12 @@
 	if (copy_to_user(&frame->sigreturn_code, __user_rt_sigreturn,
 			 sizeof(frame->sigreturn_code)))
 		return -EFAULT;
-	regs->ra = (unsigned long)&frame->sigreturn_code;
+
+	addr = (unsigned long)&frame->sigreturn_code;
+	/* Make sure the two instructions are pushed to icache. */
+	flush_icache_range(addr, addr + sizeof(frame->sigreturn_code));
+
+	regs->ra = addr;
 #endif /* CONFIG_MMU */
 
 	/*
diff --git a/kernel/arch/riscv/kernel/stacktrace.c b/kernel/arch/riscv/kernel/stacktrace.c
index 5953429..9c34735 100644
--- a/kernel/arch/riscv/kernel/stacktrace.c
+++ b/kernel/arch/riscv/kernel/stacktrace.c
@@ -57,9 +57,15 @@
 		/* Unwind stack frame */
 		frame = (struct stackframe *)fp - 1;
 		sp = fp;
-		fp = frame->fp;
-		pc = ftrace_graph_ret_addr(current, NULL, frame->ra,
-					   (unsigned long *)(fp - 8));
+		if (regs && (regs->epc == pc) && (frame->fp & 0x7)) {
+			fp = frame->ra;
+			pc = regs->ra;
+		} else {
+			fp = frame->fp;
+			pc = ftrace_graph_ret_addr(current, NULL, frame->ra,
+						   &frame->ra);
+		}
+
 	}
 }
 
@@ -90,7 +96,7 @@
 	while (!kstack_end(ksp)) {
 		if (__kernel_text_address(pc) && unlikely(fn(pc, arg)))
 			break;
-		pc = (*ksp++) - 0x4;
+		pc = READ_ONCE_NOCHECK(*ksp++) - 0x4;
 	}
 }
 
diff --git a/kernel/arch/riscv/kernel/time.c b/kernel/arch/riscv/kernel/time.c
index 8a5cf99..303ae47 100644
--- a/kernel/arch/riscv/kernel/time.c
+++ b/kernel/arch/riscv/kernel/time.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/of_clk.h>
+#include <linux/clockchips.h>
 #include <linux/clocksource.h>
 #include <linux/delay.h>
 #include <asm/sbi.h>
@@ -28,6 +29,8 @@
 
 	of_clk_init(NULL);
 	timer_probe();
+
+	tick_setup_hrtimer_broadcast();
 }
 
 void clocksource_arch_init(struct clocksource *cs)
diff --git a/kernel/arch/riscv/kernel/traps.c b/kernel/arch/riscv/kernel/traps.c
index c1a1301..227253f 100644
--- a/kernel/arch/riscv/kernel/traps.c
+++ b/kernel/arch/riscv/kernel/traps.c
@@ -31,25 +31,29 @@
 {
 	static int die_counter;
 	int ret;
+	long cause;
+	unsigned long flags;
 
 	oops_enter();
 
-	spin_lock_irq(&die_lock);
+	spin_lock_irqsave(&die_lock, flags);
 	console_verbose();
 	bust_spinlocks(1);
 
 	pr_emerg("%s [#%d]\n", str, ++die_counter);
 	print_modules();
-	show_regs(regs);
+	if (regs)
+		show_regs(regs);
 
-	ret = notify_die(DIE_OOPS, str, regs, 0, regs->cause, SIGSEGV);
+	cause = regs ? regs->cause : -1;
+	ret = notify_die(DIE_OOPS, str, regs, 0, cause, SIGSEGV);
 
-	if (regs && kexec_should_crash(current))
+	if (kexec_should_crash(current))
 		crash_kexec(regs);
 
 	bust_spinlocks(0);
 	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
-	spin_unlock_irq(&die_lock);
+	spin_unlock_irqrestore(&die_lock, flags);
 	oops_exit();
 
 	if (in_interrupt())
@@ -57,7 +61,7 @@
 	if (panic_on_oops)
 		panic("Fatal exception");
 	if (ret != NOTIFY_STOP)
-		do_exit(SIGSEGV);
+		make_task_dead(SIGSEGV);
 }
 
 void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
diff --git a/kernel/arch/riscv/mm/cacheflush.c b/kernel/arch/riscv/mm/cacheflush.c
index 89f8106..2ae1201 100644
--- a/kernel/arch/riscv/mm/cacheflush.c
+++ b/kernel/arch/riscv/mm/cacheflush.c
@@ -85,7 +85,9 @@
 {
 	struct page *page = pte_page(pte);
 
-	if (!test_and_set_bit(PG_dcache_clean, &page->flags))
+	if (!test_bit(PG_dcache_clean, &page->flags)) {
 		flush_icache_all();
+		set_bit(PG_dcache_clean, &page->flags);
+	}
 }
 #endif /* CONFIG_MMU */
diff --git a/kernel/arch/riscv/mm/fault.c b/kernel/arch/riscv/mm/fault.c
index 8f84bbe..54b1294 100644
--- a/kernel/arch/riscv/mm/fault.c
+++ b/kernel/arch/riscv/mm/fault.c
@@ -34,7 +34,7 @@
 		(addr < PAGE_SIZE) ? "NULL pointer dereference" :
 		"paging request", addr);
 	die(regs, "Oops");
-	do_exit(SIGKILL);
+	make_task_dead(SIGKILL);
 }
 
 static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_fault_t fault)
diff --git a/kernel/arch/riscv/net/bpf_jit.h b/kernel/arch/riscv/net/bpf_jit.h
index 75c1e999..ef336fe 100644
--- a/kernel/arch/riscv/net/bpf_jit.h
+++ b/kernel/arch/riscv/net/bpf_jit.h
@@ -69,6 +69,7 @@
 	struct bpf_prog *prog;
 	u16 *insns;		/* RV insns */
 	int ninsns;
+	int prologue_len;
 	int epilogue_offset;
 	int *offset;		/* BPF to RV */
 	unsigned long flags;
@@ -214,8 +215,8 @@
 	int from, to;
 
 	off++; /* BPF branch is from PC+1, RV is from PC */
-	from = (insn > 0) ? ctx->offset[insn - 1] : 0;
-	to = (insn + off > 0) ? ctx->offset[insn + off - 1] : 0;
+	from = (insn > 0) ? ctx->offset[insn - 1] : ctx->prologue_len;
+	to = (insn + off > 0) ? ctx->offset[insn + off - 1] : ctx->prologue_len;
 	return ninsns_rvoff(to - from);
 }
 
diff --git a/kernel/arch/riscv/net/bpf_jit_comp64.c b/kernel/arch/riscv/net/bpf_jit_comp64.c
index c113ae8..053dc83 100644
--- a/kernel/arch/riscv/net/bpf_jit_comp64.c
+++ b/kernel/arch/riscv/net/bpf_jit_comp64.c
@@ -1144,16 +1144,3 @@
 {
 	__build_epilogue(false, ctx);
 }
-
-void *bpf_jit_alloc_exec(unsigned long size)
-{
-	return __vmalloc_node_range(size, PAGE_SIZE, BPF_JIT_REGION_START,
-				    BPF_JIT_REGION_END, GFP_KERNEL,
-				    PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
-				    __builtin_return_address(0));
-}
-
-void bpf_jit_free_exec(void *addr)
-{
-	return vfree(addr);
-}
diff --git a/kernel/arch/riscv/net/bpf_jit_core.c b/kernel/arch/riscv/net/bpf_jit_core.c
index cbf7d24..ef17bc8 100644
--- a/kernel/arch/riscv/net/bpf_jit_core.c
+++ b/kernel/arch/riscv/net/bpf_jit_core.c
@@ -83,6 +83,12 @@
 		prog = orig_prog;
 		goto out_offset;
 	}
+
+	if (build_body(ctx, extra_pass, NULL)) {
+		prog = orig_prog;
+		goto out_offset;
+	}
+
 	for (i = 0; i < prog->len; i++) {
 		prev_ninsns += 32;
 		ctx->offset[i] = prev_ninsns;
@@ -91,11 +97,15 @@
 	for (i = 0; i < NR_JIT_ITERATIONS; i++) {
 		pass++;
 		ctx->ninsns = 0;
+
+		bpf_jit_build_prologue(ctx);
+		ctx->prologue_len = ctx->ninsns;
+
 		if (build_body(ctx, extra_pass, ctx->offset)) {
 			prog = orig_prog;
 			goto out_offset;
 		}
-		bpf_jit_build_prologue(ctx);
+
 		ctx->epilogue_offset = ctx->ninsns;
 		bpf_jit_build_epilogue(ctx);
 
@@ -153,6 +163,10 @@
 	bpf_flush_icache(jit_data->header, ctx->insns + ctx->ninsns);
 
 	if (!prog->is_func || extra_pass) {
+		bpf_jit_binary_lock_ro(jit_data->header);
+		for (i = 0; i < prog->len; i++)
+			ctx->offset[i] = ninsns_rvoff(ctx->offset[i]);
+		bpf_prog_fill_jited_linfo(prog, ctx->offset);
 out_offset:
 		kfree(ctx->offset);
 		kfree(jit_data);
@@ -165,3 +179,16 @@
 					   tmp : orig_prog);
 	return prog;
 }
+
+void *bpf_jit_alloc_exec(unsigned long size)
+{
+	return __vmalloc_node_range(size, PAGE_SIZE, BPF_JIT_REGION_START,
+				    BPF_JIT_REGION_END, GFP_KERNEL,
+				    PAGE_KERNEL, 0, NUMA_NO_NODE,
+				    __builtin_return_address(0));
+}
+
+void bpf_jit_free_exec(void *addr)
+{
+	return vfree(addr);
+}
diff --git a/kernel/arch/s390/Makefile b/kernel/arch/s390/Makefile
index a8cb00f..39ffcd4 100644
--- a/kernel/arch/s390/Makefile
+++ b/kernel/arch/s390/Makefile
@@ -29,6 +29,7 @@
 KBUILD_CFLAGS_DECOMPRESSOR += -fno-asynchronous-unwind-tables
 KBUILD_CFLAGS_DECOMPRESSOR += -ffreestanding
 KBUILD_CFLAGS_DECOMPRESSOR += -fno-stack-protector
+KBUILD_CFLAGS_DECOMPRESSOR += -fPIE
 KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, address-of-packed-member)
 KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),-g)
 KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option, -gdwarf-4,))
diff --git a/kernel/arch/s390/boot/compressed/decompressor.c b/kernel/arch/s390/boot/compressed/decompressor.c
index 3061b11..8eaa171 100644
--- a/kernel/arch/s390/boot/compressed/decompressor.c
+++ b/kernel/arch/s390/boot/compressed/decompressor.c
@@ -79,6 +79,6 @@
 	void *output = (void *)decompress_offset;
 
 	__decompress(_compressed_start, _compressed_end - _compressed_start,
-		     NULL, NULL, output, 0, NULL, error);
+		     NULL, NULL, output, vmlinux.image_size, NULL, error);
 	return output;
 }
diff --git a/kernel/arch/s390/boot/ipl_report.c b/kernel/arch/s390/boot/ipl_report.c
index 0b49655..88bacf4 100644
--- a/kernel/arch/s390/boot/ipl_report.c
+++ b/kernel/arch/s390/boot/ipl_report.c
@@ -57,11 +57,19 @@
 	if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && INITRD_START && INITRD_SIZE &&
 	    intersects(INITRD_START, INITRD_SIZE, safe_addr, size))
 		safe_addr = INITRD_START + INITRD_SIZE;
+	if (intersects(safe_addr, size, (unsigned long)comps, comps->len)) {
+		safe_addr = (unsigned long)comps + comps->len;
+		goto repeat;
+	}
 	for_each_rb_entry(comp, comps)
 		if (intersects(safe_addr, size, comp->addr, comp->len)) {
 			safe_addr = comp->addr + comp->len;
 			goto repeat;
 		}
+	if (intersects(safe_addr, size, (unsigned long)certs, certs->len)) {
+		safe_addr = (unsigned long)certs + certs->len;
+		goto repeat;
+	}
 	for_each_rb_entry(cert, certs)
 		if (intersects(safe_addr, size, cert->addr, cert->len)) {
 			safe_addr = cert->addr + cert->len;
diff --git a/kernel/arch/s390/crypto/paes_s390.c b/kernel/arch/s390/crypto/paes_s390.c
index f3caeb1..a6727ad 100644
--- a/kernel/arch/s390/crypto/paes_s390.c
+++ b/kernel/arch/s390/crypto/paes_s390.c
@@ -34,7 +34,7 @@
  * and padding is also possible, the limits need to be generous.
  */
 #define PAES_MIN_KEYSIZE 16
-#define PAES_MAX_KEYSIZE 320
+#define PAES_MAX_KEYSIZE MAXEP11AESKEYBLOBSIZE
 
 static u8 *ctrblk;
 static DEFINE_MUTEX(ctrblk_lock);
diff --git a/kernel/arch/s390/include/asm/cpu_mf.h b/kernel/arch/s390/include/asm/cpu_mf.h
index 0d90cbe..a0914bc 100644
--- a/kernel/arch/s390/include/asm/cpu_mf.h
+++ b/kernel/arch/s390/include/asm/cpu_mf.h
@@ -128,19 +128,21 @@
 	struct hws_diag_entry	diag;	/* Diagnostic-sampling data entry */
 } __packed;
 
-struct hws_trailer_entry {
-	union {
-		struct {
-			unsigned int f:1;	/* 0 - Block Full Indicator   */
-			unsigned int a:1;	/* 1 - Alert request control  */
-			unsigned int t:1;	/* 2 - Timestamp format	      */
-			unsigned int :29;	/* 3 - 31: Reserved	      */
-			unsigned int bsdes:16;	/* 32-47: size of basic SDE   */
-			unsigned int dsdes:16;	/* 48-63: size of diagnostic SDE */
-		};
-		unsigned long long flags;	/* 0 - 63: All indicators     */
+union hws_trailer_header {
+	struct {
+		unsigned int f:1;	/* 0 - Block Full Indicator   */
+		unsigned int a:1;	/* 1 - Alert request control  */
+		unsigned int t:1;	/* 2 - Timestamp format	      */
+		unsigned int :29;	/* 3 - 31: Reserved	      */
+		unsigned int bsdes:16;	/* 32-47: size of basic SDE   */
+		unsigned int dsdes:16;	/* 48-63: size of diagnostic SDE */
+		unsigned long long overflow; /* 64 - Overflow Count   */
 	};
-	unsigned long long overflow;	 /* 64 - sample Overflow count	      */
+	__uint128_t val;
+};
+
+struct hws_trailer_entry {
+	union hws_trailer_header header; /* 0 - 15 Flags + Overflow Count     */
 	unsigned char timestamp[16];	 /* 16 - 31 timestamp		      */
 	unsigned long long reserved1;	 /* 32 -Reserved		      */
 	unsigned long long reserved2;	 /*				      */
@@ -287,14 +289,11 @@
 	return USEC_PER_SEC * qsi->cpu_speed / rate;
 }
 
-#define SDB_TE_ALERT_REQ_MASK	0x4000000000000000UL
-#define SDB_TE_BUFFER_FULL_MASK 0x8000000000000000UL
-
 /* Return TOD timestamp contained in an trailer entry */
 static inline unsigned long long trailer_timestamp(struct hws_trailer_entry *te)
 {
 	/* TOD in STCKE format */
-	if (te->t)
+	if (te->header.t)
 		return *((unsigned long long *) &te->timestamp[1]);
 
 	/* TOD in STCK format */
diff --git a/kernel/arch/s390/include/asm/debug.h b/kernel/arch/s390/include/asm/debug.h
index c1b82bc..29a1bad 100644
--- a/kernel/arch/s390/include/asm/debug.h
+++ b/kernel/arch/s390/include/asm/debug.h
@@ -4,8 +4,8 @@
  *
  *    Copyright IBM Corp. 1999, 2020
  */
-#ifndef DEBUG_H
-#define DEBUG_H
+#ifndef _ASM_S390_DEBUG_H
+#define _ASM_S390_DEBUG_H
 
 #include <linux/string.h>
 #include <linux/spinlock.h>
@@ -425,4 +425,4 @@
 #define PRINT_FATAL(x...)	printk(KERN_DEBUG PRINTK_HEADER x)
 #endif /* DASD_DEBUG */
 
-#endif /* DEBUG_H */
+#endif /* _ASM_S390_DEBUG_H */
diff --git a/kernel/arch/s390/include/asm/percpu.h b/kernel/arch/s390/include/asm/percpu.h
index 918f0ba..5e26e2c 100644
--- a/kernel/arch/s390/include/asm/percpu.h
+++ b/kernel/arch/s390/include/asm/percpu.h
@@ -31,7 +31,7 @@
 	pcp_op_T__ *ptr__;						\
 	preempt_disable_notrace();					\
 	ptr__ = raw_cpu_ptr(&(pcp));					\
-	prev__ = *ptr__;						\
+	prev__ = READ_ONCE(*ptr__);					\
 	do {								\
 		old__ = prev__;						\
 		new__ = old__ op (val);					\
diff --git a/kernel/arch/s390/kernel/dumpstack.c b/kernel/arch/s390/kernel/dumpstack.c
index 0dc4b25..763e726 100644
--- a/kernel/arch/s390/kernel/dumpstack.c
+++ b/kernel/arch/s390/kernel/dumpstack.c
@@ -214,5 +214,5 @@
 	if (panic_on_oops)
 		panic("Fatal exception: panic_on_oops");
 	oops_exit();
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
diff --git a/kernel/arch/s390/kernel/ipl.c b/kernel/arch/s390/kernel/ipl.c
index 6da0690..c469e88 100644
--- a/kernel/arch/s390/kernel/ipl.c
+++ b/kernel/arch/s390/kernel/ipl.c
@@ -501,6 +501,8 @@
 
 static struct attribute *ipl_unknown_attrs[] = {
 	&sys_ipl_type_attr.attr,
+	&sys_ipl_secure_attr.attr,
+	&sys_ipl_has_secure_attr.attr,
 	NULL,
 };
 
diff --git a/kernel/arch/s390/kernel/kprobes.c b/kernel/arch/s390/kernel/kprobes.c
index aae24dc..0f7e7a6 100644
--- a/kernel/arch/s390/kernel/kprobes.c
+++ b/kernel/arch/s390/kernel/kprobes.c
@@ -241,6 +241,7 @@
 {
 	__this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
 	kcb->kprobe_status = kcb->prev_kprobe.status;
+	kcb->prev_kprobe.kp = NULL;
 }
 NOKPROBE_SYMBOL(pop_kprobe);
 
@@ -402,12 +403,11 @@
 	if (!p)
 		return 0;
 
+	resume_execution(p, regs);
 	if (kcb->kprobe_status != KPROBE_REENTER && p->post_handler) {
 		kcb->kprobe_status = KPROBE_HIT_SSDONE;
 		p->post_handler(p, regs, 0);
 	}
-
-	resume_execution(p, regs);
 	pop_kprobe(kcb);
 	preempt_enable_no_resched();
 
diff --git a/kernel/arch/s390/kernel/machine_kexec_file.c b/kernel/arch/s390/kernel/machine_kexec_file.c
index 53da174..bf05967 100644
--- a/kernel/arch/s390/kernel/machine_kexec_file.c
+++ b/kernel/arch/s390/kernel/machine_kexec_file.c
@@ -185,8 +185,6 @@
 
 	data->memsz = ALIGN(data->memsz, PAGE_SIZE);
 	buf.mem = data->memsz;
-	if (image->type == KEXEC_TYPE_CRASH)
-		buf.mem += crashk_res.start;
 
 	ptr = (void *)ipl_cert_list_addr;
 	end = ptr + ipl_cert_list_size;
@@ -223,6 +221,9 @@
 		data->kernel_buf + offsetof(struct lowcore, ipl_parmblock_ptr);
 	*lc_ipl_parmblock_ptr = (__u32)buf.mem;
 
+	if (image->type == KEXEC_TYPE_CRASH)
+		buf.mem += crashk_res.start;
+
 	ret = kexec_add_buffer(&buf);
 out:
 	return ret;
diff --git a/kernel/arch/s390/kernel/nmi.c b/kernel/arch/s390/kernel/nmi.c
index 86c8d53..0102376 100644
--- a/kernel/arch/s390/kernel/nmi.c
+++ b/kernel/arch/s390/kernel/nmi.c
@@ -178,7 +178,7 @@
 		       "malfunction (code 0x%016lx).\n", mcck.mcck_code);
 		printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
 		       current->comm, current->pid);
-		do_exit(SIGSEGV);
+		make_task_dead(SIGSEGV);
 	}
 }
 EXPORT_SYMBOL_GPL(s390_handle_mcck);
diff --git a/kernel/arch/s390/kernel/perf_cpum_sf.c b/kernel/arch/s390/kernel/perf_cpum_sf.c
index 19cd7b9..bcd31e0 100644
--- a/kernel/arch/s390/kernel/perf_cpum_sf.c
+++ b/kernel/arch/s390/kernel/perf_cpum_sf.c
@@ -163,14 +163,15 @@
 
 static int alloc_sample_data_block(unsigned long *sdbt, gfp_t gfp_flags)
 {
-	unsigned long sdb, *trailer;
+	struct hws_trailer_entry *te;
+	unsigned long sdb;
 
 	/* Allocate and initialize sample-data-block */
 	sdb = get_zeroed_page(gfp_flags);
 	if (!sdb)
 		return -ENOMEM;
-	trailer = trailer_entry_ptr(sdb);
-	*trailer = SDB_TE_ALERT_REQ_MASK;
+	te = (struct hws_trailer_entry *)trailer_entry_ptr(sdb);
+	te->header.a = 1;
 
 	/* Link SDB into the sample-data-block-table */
 	*sdbt = sdb;
@@ -1206,7 +1207,7 @@
 					    "%s: Found unknown"
 					    " sampling data entry: te->f %i"
 					    " basic.def %#4x (%p)\n", __func__,
-					    te->f, sample->def, sample);
+					    te->header.f, sample->def, sample);
 			/* Sample slot is not yet written or other record.
 			 *
 			 * This condition can occur if the buffer was reused
@@ -1217,7 +1218,7 @@
 			 * that are not full.  Stop processing if the first
 			 * invalid format was detected.
 			 */
-			if (!te->f)
+			if (!te->header.f)
 				break;
 		}
 
@@ -1225,6 +1226,16 @@
 		sample->def = 0;
 		sample++;
 	}
+}
+
+static inline __uint128_t __cdsg(__uint128_t *ptr, __uint128_t old, __uint128_t new)
+{
+	asm volatile(
+		"	cdsg	%[old],%[new],%[ptr]\n"
+		: [old] "+d" (old), [ptr] "+QS" (*ptr)
+		: [new] "d" (new)
+		: "memory", "cc");
+	return old;
 }
 
 /* hw_perf_event_update() - Process sampling buffer
@@ -1243,10 +1254,11 @@
  */
 static void hw_perf_event_update(struct perf_event *event, int flush_all)
 {
+	unsigned long long event_overflow, sampl_overflow, num_sdb;
+	union hws_trailer_header old, prev, new;
 	struct hw_perf_event *hwc = &event->hw;
 	struct hws_trailer_entry *te;
 	unsigned long *sdbt;
-	unsigned long long event_overflow, sampl_overflow, num_sdb, te_flags;
 	int done;
 
 	/*
@@ -1266,25 +1278,25 @@
 		te = (struct hws_trailer_entry *) trailer_entry_ptr(*sdbt);
 
 		/* Leave loop if no more work to do (block full indicator) */
-		if (!te->f) {
+		if (!te->header.f) {
 			done = 1;
 			if (!flush_all)
 				break;
 		}
 
 		/* Check the sample overflow count */
-		if (te->overflow)
+		if (te->header.overflow)
 			/* Account sample overflows and, if a particular limit
 			 * is reached, extend the sampling buffer.
 			 * For details, see sfb_account_overflows().
 			 */
-			sampl_overflow += te->overflow;
+			sampl_overflow += te->header.overflow;
 
 		/* Timestamps are valid for full sample-data-blocks only */
 		debug_sprintf_event(sfdbg, 6, "%s: sdbt %#lx "
 				    "overflow %llu timestamp %#llx\n",
-				    __func__, (unsigned long)sdbt, te->overflow,
-				    (te->f) ? trailer_timestamp(te) : 0ULL);
+				    __func__, (unsigned long)sdbt, te->header.overflow,
+				    (te->header.f) ? trailer_timestamp(te) : 0ULL);
 
 		/* Collect all samples from a single sample-data-block and
 		 * flag if an (perf) event overflow happened.  If so, the PMU
@@ -1294,12 +1306,16 @@
 		num_sdb++;
 
 		/* Reset trailer (using compare-double-and-swap) */
+		/* READ_ONCE() 16 byte header */
+		prev.val = __cdsg(&te->header.val, 0, 0);
 		do {
-			te_flags = te->flags & ~SDB_TE_BUFFER_FULL_MASK;
-			te_flags |= SDB_TE_ALERT_REQ_MASK;
-		} while (!cmpxchg_double(&te->flags, &te->overflow,
-					 te->flags, te->overflow,
-					 te_flags, 0ULL));
+			old.val = prev.val;
+			new.val = prev.val;
+			new.f = 0;
+			new.a = 1;
+			new.overflow = 0;
+			prev.val = __cdsg(&te->header.val, old.val, new.val);
+		} while (prev.val != old.val);
 
 		/* Advance to next sample-data-block */
 		sdbt++;
@@ -1384,7 +1400,7 @@
 	range_scan = AUX_SDB_NUM_ALERT(aux);
 	for (i = 0, idx = aux->head; i < range_scan; i++, idx++) {
 		te = aux_sdb_trailer(aux, idx);
-		if (!(te->flags & SDB_TE_BUFFER_FULL_MASK))
+		if (!te->header.f)
 			break;
 	}
 	/* i is num of SDBs which are full */
@@ -1392,7 +1408,7 @@
 
 	/* Remove alert indicators in the buffer */
 	te = aux_sdb_trailer(aux, aux->alert_mark);
-	te->flags &= ~SDB_TE_ALERT_REQ_MASK;
+	te->header.a = 0;
 
 	debug_sprintf_event(sfdbg, 6, "%s: SDBs %ld range %ld head %ld\n",
 			    __func__, i, range_scan, aux->head);
@@ -1437,9 +1453,9 @@
 		idx = aux->empty_mark + 1;
 		for (i = 0; i < range_scan; i++, idx++) {
 			te = aux_sdb_trailer(aux, idx);
-			te->flags &= ~(SDB_TE_BUFFER_FULL_MASK |
-				       SDB_TE_ALERT_REQ_MASK);
-			te->overflow = 0;
+			te->header.f = 0;
+			te->header.a = 0;
+			te->header.overflow = 0;
 		}
 		/* Save the position of empty SDBs */
 		aux->empty_mark = aux->head + range - 1;
@@ -1448,7 +1464,7 @@
 	/* Set alert indicator */
 	aux->alert_mark = aux->head + range/2 - 1;
 	te = aux_sdb_trailer(aux, aux->alert_mark);
-	te->flags = te->flags | SDB_TE_ALERT_REQ_MASK;
+	te->header.a = 1;
 
 	/* Reset hardware buffer head */
 	head = AUX_SDB_INDEX(aux, aux->head);
@@ -1475,14 +1491,17 @@
 static bool aux_set_alert(struct aux_buffer *aux, unsigned long alert_index,
 			  unsigned long long *overflow)
 {
-	unsigned long long orig_overflow, orig_flags, new_flags;
+	union hws_trailer_header old, prev, new;
 	struct hws_trailer_entry *te;
 
 	te = aux_sdb_trailer(aux, alert_index);
+	/* READ_ONCE() 16 byte header */
+	prev.val = __cdsg(&te->header.val, 0, 0);
 	do {
-		orig_flags = te->flags;
-		*overflow = orig_overflow = te->overflow;
-		if (orig_flags & SDB_TE_BUFFER_FULL_MASK) {
+		old.val = prev.val;
+		new.val = prev.val;
+		*overflow = old.overflow;
+		if (old.f) {
 			/*
 			 * SDB is already set by hardware.
 			 * Abort and try to set somewhere
@@ -1490,10 +1509,10 @@
 			 */
 			return false;
 		}
-		new_flags = orig_flags | SDB_TE_ALERT_REQ_MASK;
-	} while (!cmpxchg_double(&te->flags, &te->overflow,
-				 orig_flags, orig_overflow,
-				 new_flags, 0ULL));
+		new.a = 1;
+		new.overflow = 0;
+		prev.val = __cdsg(&te->header.val, old.val, new.val);
+	} while (prev.val != old.val);
 	return true;
 }
 
@@ -1522,8 +1541,9 @@
 static bool aux_reset_buffer(struct aux_buffer *aux, unsigned long range,
 			     unsigned long long *overflow)
 {
-	unsigned long long orig_overflow, orig_flags, new_flags;
 	unsigned long i, range_scan, idx, idx_old;
+	union hws_trailer_header old, prev, new;
+	unsigned long long orig_overflow;
 	struct hws_trailer_entry *te;
 
 	debug_sprintf_event(sfdbg, 6, "%s: range %ld head %ld alert %ld "
@@ -1554,17 +1574,20 @@
 	idx_old = idx = aux->empty_mark + 1;
 	for (i = 0; i < range_scan; i++, idx++) {
 		te = aux_sdb_trailer(aux, idx);
+		/* READ_ONCE() 16 byte header */
+		prev.val = __cdsg(&te->header.val, 0, 0);
 		do {
-			orig_flags = te->flags;
-			orig_overflow = te->overflow;
-			new_flags = orig_flags & ~SDB_TE_BUFFER_FULL_MASK;
+			old.val = prev.val;
+			new.val = prev.val;
+			orig_overflow = old.overflow;
+			new.f = 0;
+			new.overflow = 0;
 			if (idx == aux->alert_mark)
-				new_flags |= SDB_TE_ALERT_REQ_MASK;
+				new.a = 1;
 			else
-				new_flags &= ~SDB_TE_ALERT_REQ_MASK;
-		} while (!cmpxchg_double(&te->flags, &te->overflow,
-					 orig_flags, orig_overflow,
-					 new_flags, 0ULL));
+				new.a = 0;
+			prev.val = __cdsg(&te->header.val, old.val, new.val);
+		} while (prev.val != old.val);
 		*overflow += orig_overflow;
 	}
 
diff --git a/kernel/arch/s390/kernel/ptrace.c b/kernel/arch/s390/kernel/ptrace.c
index a76dd27..3009bb5 100644
--- a/kernel/arch/s390/kernel/ptrace.c
+++ b/kernel/arch/s390/kernel/ptrace.c
@@ -500,9 +500,7 @@
 		}
 		return 0;
 	case PTRACE_GET_LAST_BREAK:
-		put_user(child->thread.last_break,
-			 (unsigned long __user *) data);
-		return 0;
+		return put_user(child->thread.last_break, (unsigned long __user *)data);
 	case PTRACE_ENABLE_TE:
 		if (!MACHINE_HAS_TE)
 			return -EIO;
@@ -854,9 +852,7 @@
 		}
 		return 0;
 	case PTRACE_GET_LAST_BREAK:
-		put_user(child->thread.last_break,
-			 (unsigned int __user *) data);
-		return 0;
+		return put_user(child->thread.last_break, (unsigned int __user *)data);
 	}
 	return compat_ptrace_request(child, request, addr, data);
 }
diff --git a/kernel/arch/s390/kernel/signal.c b/kernel/arch/s390/kernel/signal.c
index b27b6c1..9e900a8 100644
--- a/kernel/arch/s390/kernel/signal.c
+++ b/kernel/arch/s390/kernel/signal.c
@@ -472,7 +472,7 @@
 	current->thread.system_call =
 		test_pt_regs_flag(regs, PIF_SYSCALL) ? regs->int_code : 0;
 
-	if (test_thread_flag(TIF_SIGPENDING) && get_signal(&ksig)) {
+	if (get_signal(&ksig)) {
 		/* Whee!  Actually deliver the signal.  */
 		if (current->thread.system_call) {
 			regs->int_code = current->thread.system_call;
diff --git a/kernel/arch/s390/kernel/sthyi.c b/kernel/arch/s390/kernel/sthyi.c
index 888cc2f..ce6084e 100644
--- a/kernel/arch/s390/kernel/sthyi.c
+++ b/kernel/arch/s390/kernel/sthyi.c
@@ -460,9 +460,9 @@
  *
  * Fills the destination with system information returned by the STHYI
  * instruction. The data is generated by emulation or execution of STHYI,
- * if available. The return value is the condition code that would be
- * returned, the rc parameter is the return code which is passed in
- * register R2 + 1.
+ * if available. The return value is either a negative error value or
+ * the condition code that would be returned, the rc parameter is the
+ * return code which is passed in register R2 + 1.
  */
 int sthyi_fill(void *dst, u64 *rc)
 {
diff --git a/kernel/arch/s390/kernel/vmlinux.lds.S b/kernel/arch/s390/kernel/vmlinux.lds.S
index 9505bdb..1c65c38 100644
--- a/kernel/arch/s390/kernel/vmlinux.lds.S
+++ b/kernel/arch/s390/kernel/vmlinux.lds.S
@@ -15,6 +15,8 @@
 /* Handle ro_after_init data on our own. */
 #define RO_AFTER_INIT_DATA
 
+#define RUNTIME_DISCARD_EXIT
+
 #define EMITS_PT_NOTE
 
 #include <asm-generic/vmlinux.lds.h>
@@ -188,5 +190,6 @@
 	DISCARDS
 	/DISCARD/ : {
 		*(.eh_frame)
+		*(.interp)
 	}
 }
diff --git a/kernel/arch/s390/kvm/intercept.c b/kernel/arch/s390/kvm/intercept.c
index 77909d3..8bf72a3 100644
--- a/kernel/arch/s390/kvm/intercept.c
+++ b/kernel/arch/s390/kvm/intercept.c
@@ -270,10 +270,18 @@
 /**
  * handle_external_interrupt - used for external interruption interceptions
  *
- * This interception only occurs if the CPUSTAT_EXT_INT bit was set, or if
- * the new PSW does not have external interrupts disabled. In the first case,
- * we've got to deliver the interrupt manually, and in the second case, we
- * drop to userspace to handle the situation there.
+ * This interception occurs if:
+ * - the CPUSTAT_EXT_INT bit was already set when the external interrupt
+ *   occurred. In this case, the interrupt needs to be injected manually to
+ *   preserve interrupt priority.
+ * - the external new PSW has external interrupts enabled, which will cause an
+ *   interruption loop. We drop to userspace in this case.
+ *
+ * The latter case can be detected by inspecting the external mask bit in the
+ * external new psw.
+ *
+ * Under PV, only the latter case can occur, since interrupt priorities are
+ * handled in the ultravisor.
  */
 static int handle_external_interrupt(struct kvm_vcpu *vcpu)
 {
@@ -284,10 +292,18 @@
 
 	vcpu->stat.exit_external_interrupt++;
 
-	rc = read_guest_lc(vcpu, __LC_EXT_NEW_PSW, &newpsw, sizeof(psw_t));
-	if (rc)
-		return rc;
-	/* We can not handle clock comparator or timer interrupt with bad PSW */
+	if (kvm_s390_pv_cpu_is_protected(vcpu)) {
+		newpsw = vcpu->arch.sie_block->gpsw;
+	} else {
+		rc = read_guest_lc(vcpu, __LC_EXT_NEW_PSW, &newpsw, sizeof(psw_t));
+		if (rc)
+			return rc;
+	}
+
+	/*
+	 * Clock comparator or timer interrupt with external interrupt enabled
+	 * will cause interrupt loop. Drop to userspace.
+	 */
 	if ((eic == EXT_IRQ_CLK_COMP || eic == EXT_IRQ_CPU_TIMER) &&
 	    (newpsw.mask & PSW_MASK_EXT))
 		return -EOPNOTSUPP;
@@ -371,8 +387,8 @@
  */
 int handle_sthyi(struct kvm_vcpu *vcpu)
 {
-	int reg1, reg2, r = 0;
-	u64 code, addr, cc = 0, rc = 0;
+	int reg1, reg2, cc = 0, r = 0;
+	u64 code, addr, rc = 0;
 	struct sthyi_sctns *sctns = NULL;
 
 	if (!test_kvm_facility(vcpu->kvm, 74))
@@ -403,7 +419,10 @@
 		return -ENOMEM;
 
 	cc = sthyi_fill(sctns, &rc);
-
+	if (cc < 0) {
+		free_page((unsigned long)sctns);
+		return cc;
+	}
 out:
 	if (!cc) {
 		if (kvm_s390_pv_cpu_is_protected(vcpu)) {
diff --git a/kernel/arch/s390/kvm/interrupt.c b/kernel/arch/s390/kvm/interrupt.c
index b51ab19..64d1dfe 100644
--- a/kernel/arch/s390/kvm/interrupt.c
+++ b/kernel/arch/s390/kvm/interrupt.c
@@ -81,8 +81,9 @@
 		struct esca_block *sca = vcpu->kvm->arch.sca;
 		union esca_sigp_ctrl *sigp_ctrl =
 			&(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
-		union esca_sigp_ctrl new_val = {0}, old_val = *sigp_ctrl;
+		union esca_sigp_ctrl new_val = {0}, old_val;
 
+		old_val = READ_ONCE(*sigp_ctrl);
 		new_val.scn = src_id;
 		new_val.c = 1;
 		old_val.c = 0;
@@ -93,8 +94,9 @@
 		struct bsca_block *sca = vcpu->kvm->arch.sca;
 		union bsca_sigp_ctrl *sigp_ctrl =
 			&(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
-		union bsca_sigp_ctrl new_val = {0}, old_val = *sigp_ctrl;
+		union bsca_sigp_ctrl new_val = {0}, old_val;
 
+		old_val = READ_ONCE(*sigp_ctrl);
 		new_val.scn = src_id;
 		new_val.c = 1;
 		old_val.c = 0;
@@ -124,16 +126,18 @@
 		struct esca_block *sca = vcpu->kvm->arch.sca;
 		union esca_sigp_ctrl *sigp_ctrl =
 			&(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
-		union esca_sigp_ctrl old = *sigp_ctrl;
+		union esca_sigp_ctrl old;
 
+		old = READ_ONCE(*sigp_ctrl);
 		expect = old.value;
 		rc = cmpxchg(&sigp_ctrl->value, old.value, 0);
 	} else {
 		struct bsca_block *sca = vcpu->kvm->arch.sca;
 		union bsca_sigp_ctrl *sigp_ctrl =
 			&(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
-		union bsca_sigp_ctrl old = *sigp_ctrl;
+		union bsca_sigp_ctrl old;
 
+		old = READ_ONCE(*sigp_ctrl);
 		expect = old.value;
 		rc = cmpxchg(&sigp_ctrl->value, old.value, 0);
 	}
diff --git a/kernel/arch/s390/kvm/kvm-s390.c b/kernel/arch/s390/kvm/kvm-s390.c
index 59db85f..7a326d0 100644
--- a/kernel/arch/s390/kvm/kvm-s390.c
+++ b/kernel/arch/s390/kvm/kvm-s390.c
@@ -2005,6 +2005,10 @@
 		ms = slots->memslots + slotidx;
 		ofs = 0;
 	}
+
+	if (cur_gfn < ms->base_gfn)
+		ofs = 0;
+
 	ofs = find_next_bit(kvm_second_dirty_bitmap(ms), ms->npages, ofs);
 	while ((slotidx > 0) && (ofs >= ms->npages)) {
 		slotidx--;
@@ -5012,6 +5016,23 @@
 	/* When we are protected, we should not change the memory slots */
 	if (kvm_s390_pv_get_handle(kvm))
 		return -EINVAL;
+
+	if (!kvm->arch.migration_mode)
+		return 0;
+
+	/*
+	 * Turn off migration mode when:
+	 * - userspace creates a new memslot with dirty logging off,
+	 * - userspace modifies an existing memslot (MOVE or FLAGS_ONLY) and
+	 *   dirty logging is turned off.
+	 * Migration mode expects dirty page logging being enabled to store
+	 * its dirty bitmap.
+	 */
+	if (change != KVM_MR_DELETE &&
+	    !(mem->flags & KVM_MEM_LOG_DIRTY_PAGES))
+		WARN(kvm_s390_vm_stop_migration(kvm),
+		     "Failed to stop migration mode");
+
 	return 0;
 }
 
diff --git a/kernel/arch/s390/kvm/vsie.c b/kernel/arch/s390/kvm/vsie.c
index ff58dec..192eacc 100644
--- a/kernel/arch/s390/kvm/vsie.c
+++ b/kernel/arch/s390/kvm/vsie.c
@@ -168,7 +168,8 @@
 			    sizeof(struct kvm_s390_apcb0)))
 		return -EFAULT;
 
-	bitmap_and(apcb_s, apcb_s, apcb_h, sizeof(struct kvm_s390_apcb0));
+	bitmap_and(apcb_s, apcb_s, apcb_h,
+		   BITS_PER_BYTE * sizeof(struct kvm_s390_apcb0));
 
 	return 0;
 }
@@ -190,7 +191,8 @@
 			    sizeof(struct kvm_s390_apcb1)))
 		return -EFAULT;
 
-	bitmap_and(apcb_s, apcb_s, apcb_h, sizeof(struct kvm_s390_apcb1));
+	bitmap_and(apcb_s, apcb_s, apcb_h,
+		   BITS_PER_BYTE * sizeof(struct kvm_s390_apcb1));
 
 	return 0;
 }
diff --git a/kernel/arch/s390/lib/uaccess.c b/kernel/arch/s390/lib/uaccess.c
index 0267405..fcfd78f 100644
--- a/kernel/arch/s390/lib/uaccess.c
+++ b/kernel/arch/s390/lib/uaccess.c
@@ -339,7 +339,7 @@
 		"4: slgr  %0,%0\n"
 		"5:\n"
 		EX_TABLE(0b,2b) EX_TABLE(3b,5b)
-		: "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2)
+		: "+&a" (size), "+&a" (to), "+a" (tmp1), "=&a" (tmp2)
 		: "a" (empty_zero_page), "d" (reg0) : "cc", "memory");
 	return size;
 }
diff --git a/kernel/arch/s390/mm/extmem.c b/kernel/arch/s390/mm/extmem.c
index 5060956..1bc42ce 100644
--- a/kernel/arch/s390/mm/extmem.c
+++ b/kernel/arch/s390/mm/extmem.c
@@ -289,15 +289,17 @@
 
 /*
  * real segment loading function, called from segment_load
+ * Must return either an error code < 0, or the segment type code >= 0
  */
 static int
 __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long *end)
 {
 	unsigned long start_addr, end_addr, dummy;
 	struct dcss_segment *seg;
-	int rc, diag_cc;
+	int rc, diag_cc, segtype;
 
 	start_addr = end_addr = 0;
+	segtype = -1;
 	seg = kmalloc(sizeof(*seg), GFP_KERNEL | GFP_DMA);
 	if (seg == NULL) {
 		rc = -ENOMEM;
@@ -326,9 +328,9 @@
 	seg->res_name[8] = '\0';
 	strlcat(seg->res_name, " (DCSS)", sizeof(seg->res_name));
 	seg->res->name = seg->res_name;
-	rc = seg->vm_segtype;
-	if (rc == SEG_TYPE_SC ||
-	    ((rc == SEG_TYPE_SR || rc == SEG_TYPE_ER) && !do_nonshared))
+	segtype = seg->vm_segtype;
+	if (segtype == SEG_TYPE_SC ||
+	    ((segtype == SEG_TYPE_SR || segtype == SEG_TYPE_ER) && !do_nonshared))
 		seg->res->flags |= IORESOURCE_READONLY;
 
 	/* Check for overlapping resources before adding the mapping. */
@@ -386,7 +388,7 @@
  out_free:
 	kfree(seg);
  out:
-	return rc;
+	return rc < 0 ? rc : segtype;
 }
 
 /*
diff --git a/kernel/arch/s390/mm/gmap.c b/kernel/arch/s390/mm/gmap.c
index 03e5616..b5a60fb 100644
--- a/kernel/arch/s390/mm/gmap.c
+++ b/kernel/arch/s390/mm/gmap.c
@@ -2786,6 +2786,7 @@
 	page = alloc_pages(GFP_KERNEL_ACCOUNT, CRST_ALLOC_ORDER);
 	if (!page)
 		return -ENOMEM;
+	page->index = 0;
 	table = page_to_virt(page);
 	memcpy(table, gmap->table, 1UL << (CRST_ALLOC_ORDER + PAGE_SHIFT));
 
diff --git a/kernel/arch/s390/mm/vmem.c b/kernel/arch/s390/mm/vmem.c
index b239f2b..cbfff24 100644
--- a/kernel/arch/s390/mm/vmem.c
+++ b/kernel/arch/s390/mm/vmem.c
@@ -296,7 +296,7 @@
 	if (end > VMALLOC_START)
 		return;
 #ifdef CONFIG_KASAN
-	if (start < KASAN_SHADOW_END && KASAN_SHADOW_START > end)
+	if (start < KASAN_SHADOW_END && end > KASAN_SHADOW_START)
 		return;
 #endif
 	pmd = pmd_offset(pud, start);
@@ -371,7 +371,7 @@
 	if (end > VMALLOC_START)
 		return;
 #ifdef CONFIG_KASAN
-	if (start < KASAN_SHADOW_END && KASAN_SHADOW_START > end)
+	if (start < KASAN_SHADOW_END && end > KASAN_SHADOW_START)
 		return;
 #endif
 
@@ -425,7 +425,7 @@
 	if (end > VMALLOC_START)
 		return;
 #ifdef CONFIG_KASAN
-	if (start < KASAN_SHADOW_END && KASAN_SHADOW_START > end)
+	if (start < KASAN_SHADOW_END && end > KASAN_SHADOW_START)
 		return;
 #endif
 
diff --git a/kernel/arch/s390/purgatory/Makefile b/kernel/arch/s390/purgatory/Makefile
index 21c4ebe..a93c9ab 100644
--- a/kernel/arch/s390/purgatory/Makefile
+++ b/kernel/arch/s390/purgatory/Makefile
@@ -25,6 +25,7 @@
 KBUILD_CFLAGS += -fno-zero-initialized-in-bss -fno-builtin -ffreestanding
 KBUILD_CFLAGS += -c -MD -Os -m64 -msoft-float -fno-common
 KBUILD_CFLAGS += -fno-stack-protector
+KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
 KBUILD_CFLAGS += $(CLANG_FLAGS)
 KBUILD_CFLAGS += $(call cc-option,-fno-PIE)
 KBUILD_AFLAGS := $(filter-out -DCC_USING_EXPOLINE,$(KBUILD_AFLAGS))
diff --git a/kernel/arch/sh/Kconfig b/kernel/arch/sh/Kconfig
index b6f3d49..44dffe7 100644
--- a/kernel/arch/sh/Kconfig
+++ b/kernel/arch/sh/Kconfig
@@ -5,6 +5,7 @@
 	select ARCH_HAVE_CUSTOM_GPIO_H
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A)
 	select ARCH_HAS_BINFMT_FLAT if !MMU
+	select ARCH_HAS_CPU_FINALIZE_INIT
 	select ARCH_HAS_GIGANTIC_PAGE
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_PTE_SPECIAL
diff --git a/kernel/arch/sh/Kconfig.debug b/kernel/arch/sh/Kconfig.debug
index 97b0e26..7bc1b10 100644
--- a/kernel/arch/sh/Kconfig.debug
+++ b/kernel/arch/sh/Kconfig.debug
@@ -18,7 +18,7 @@
 
 config STACK_DEBUG
 	bool "Check for stack overflows"
-	depends on DEBUG_KERNEL
+	depends on DEBUG_KERNEL && PRINTK
 	help
 	  This option will cause messages to be printed if free stack space
 	  drops below a certain limit. Saying Y here will add overhead to
diff --git a/kernel/arch/sh/boards/mach-ap325rxa/setup.c b/kernel/arch/sh/boards/mach-ap325rxa/setup.c
index bac8a05..05bd42d 100644
--- a/kernel/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/kernel/arch/sh/boards/mach-ap325rxa/setup.c
@@ -530,7 +530,7 @@
 	device_initialize(&ap325rxa_ceu_device.dev);
 	dma_declare_coherent_memory(&ap325rxa_ceu_device.dev,
 			ceu_dma_membase, ceu_dma_membase,
-			ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1);
+			CEU_BUFFER_MEMORY_SIZE);
 
 	platform_device_add(&ap325rxa_ceu_device);
 
diff --git a/kernel/arch/sh/boards/mach-ecovec24/setup.c b/kernel/arch/sh/boards/mach-ecovec24/setup.c
index bab91a9..9730a99 100644
--- a/kernel/arch/sh/boards/mach-ecovec24/setup.c
+++ b/kernel/arch/sh/boards/mach-ecovec24/setup.c
@@ -1454,15 +1454,13 @@
 	device_initialize(&ecovec_ceu_devices[0]->dev);
 	dma_declare_coherent_memory(&ecovec_ceu_devices[0]->dev,
 				    ceu0_dma_membase, ceu0_dma_membase,
-				    ceu0_dma_membase +
-				    CEU_BUFFER_MEMORY_SIZE - 1);
+				    CEU_BUFFER_MEMORY_SIZE);
 	platform_device_add(ecovec_ceu_devices[0]);
 
 	device_initialize(&ecovec_ceu_devices[1]->dev);
 	dma_declare_coherent_memory(&ecovec_ceu_devices[1]->dev,
 				    ceu1_dma_membase, ceu1_dma_membase,
-				    ceu1_dma_membase +
-				    CEU_BUFFER_MEMORY_SIZE - 1);
+				    CEU_BUFFER_MEMORY_SIZE);
 	platform_device_add(ecovec_ceu_devices[1]);
 
 	gpiod_add_lookup_table(&cn12_power_gpiod_table);
diff --git a/kernel/arch/sh/boards/mach-kfr2r09/setup.c b/kernel/arch/sh/boards/mach-kfr2r09/setup.c
index eeb5ce3..4a1caa3 100644
--- a/kernel/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/kernel/arch/sh/boards/mach-kfr2r09/setup.c
@@ -603,7 +603,7 @@
 	device_initialize(&kfr2r09_ceu_device.dev);
 	dma_declare_coherent_memory(&kfr2r09_ceu_device.dev,
 			ceu_dma_membase, ceu_dma_membase,
-			ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1);
+			CEU_BUFFER_MEMORY_SIZE);
 
 	platform_device_add(&kfr2r09_ceu_device);
 
diff --git a/kernel/arch/sh/boards/mach-migor/setup.c b/kernel/arch/sh/boards/mach-migor/setup.c
index 6703a21..bd4ccd9 100644
--- a/kernel/arch/sh/boards/mach-migor/setup.c
+++ b/kernel/arch/sh/boards/mach-migor/setup.c
@@ -604,7 +604,7 @@
 	device_initialize(&migor_ceu_device.dev);
 	dma_declare_coherent_memory(&migor_ceu_device.dev,
 			ceu_dma_membase, ceu_dma_membase,
-			ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1);
+			CEU_BUFFER_MEMORY_SIZE);
 
 	platform_device_add(&migor_ceu_device);
 
diff --git a/kernel/arch/sh/boards/mach-se/7724/setup.c b/kernel/arch/sh/boards/mach-se/7724/setup.c
index 8d6541b..edc7712 100644
--- a/kernel/arch/sh/boards/mach-se/7724/setup.c
+++ b/kernel/arch/sh/boards/mach-se/7724/setup.c
@@ -940,15 +940,13 @@
 	device_initialize(&ms7724se_ceu_devices[0]->dev);
 	dma_declare_coherent_memory(&ms7724se_ceu_devices[0]->dev,
 				    ceu0_dma_membase, ceu0_dma_membase,
-				    ceu0_dma_membase +
-				    CEU_BUFFER_MEMORY_SIZE - 1);
+				    CEU_BUFFER_MEMORY_SIZE);
 	platform_device_add(ms7724se_ceu_devices[0]);
 
 	device_initialize(&ms7724se_ceu_devices[1]->dev);
 	dma_declare_coherent_memory(&ms7724se_ceu_devices[1]->dev,
 				    ceu1_dma_membase, ceu1_dma_membase,
-				    ceu1_dma_membase +
-				    CEU_BUFFER_MEMORY_SIZE - 1);
+				    CEU_BUFFER_MEMORY_SIZE);
 	platform_device_add(ms7724se_ceu_devices[1]);
 
 	return platform_add_devices(ms7724se_devices,
diff --git a/kernel/arch/sh/drivers/dma/dma-sh.c b/kernel/arch/sh/drivers/dma/dma-sh.c
index 96c626c..306fba1 100644
--- a/kernel/arch/sh/drivers/dma/dma-sh.c
+++ b/kernel/arch/sh/drivers/dma/dma-sh.c
@@ -19,6 +19,18 @@
 #include <cpu/dma.h>
 
 /*
+ * Some of the SoCs feature two DMAC modules. In such a case, the channels are
+ * distributed equally among them.
+ */
+#ifdef	SH_DMAC_BASE1
+#define	SH_DMAC_NR_MD_CH	(CONFIG_NR_ONCHIP_DMA_CHANNELS / 2)
+#else
+#define	SH_DMAC_NR_MD_CH	CONFIG_NR_ONCHIP_DMA_CHANNELS
+#endif
+
+#define	SH_DMAC_CH_SZ		0x10
+
+/*
  * Define the default configuration for dual address memory-memory transfer.
  * The 0x400 value represents auto-request, external->external.
  */
@@ -29,7 +41,7 @@
 	unsigned long base = SH_DMAC_BASE0;
 
 #ifdef SH_DMAC_BASE1
-	if (chan >= 6)
+	if (chan >= SH_DMAC_NR_MD_CH)
 		base = SH_DMAC_BASE1;
 #endif
 
@@ -40,13 +52,13 @@
 {
 	unsigned long base = dma_find_base(chan);
 
-	/* Normalize offset calculation */
-	if (chan >= 9)
-		chan -= 6;
-	if (chan >= 4)
-		base += 0x10;
+	chan = (chan % SH_DMAC_NR_MD_CH) * SH_DMAC_CH_SZ;
 
-	return base + (chan * 0x10);
+	/* DMAOR is placed inside the channel register space. Step over it. */
+	if (chan >= DMAOR)
+		base += SH_DMAC_CH_SZ;
+
+	return base + chan;
 }
 
 #ifdef CONFIG_SH_DMA_IRQ_MULTI
@@ -250,12 +262,11 @@
 #define NR_DMAOR	1
 #endif
 
-/*
- * DMAOR bases are broken out amongst channel groups. DMAOR0 manages
- * channels 0 - 5, DMAOR1 6 - 11 (optional).
- */
-#define dmaor_read_reg(n)		__raw_readw(dma_find_base((n)*6))
-#define dmaor_write_reg(n, data)	__raw_writew(data, dma_find_base(n)*6)
+#define dmaor_read_reg(n)		__raw_readw(dma_find_base((n) * \
+						    SH_DMAC_NR_MD_CH) + DMAOR)
+#define dmaor_write_reg(n, data)	__raw_writew(data, \
+						     dma_find_base((n) * \
+						     SH_DMAC_NR_MD_CH) + DMAOR)
 
 static inline int dmaor_reset(int no)
 {
diff --git a/kernel/arch/sh/include/asm/bugs.h b/kernel/arch/sh/include/asm/bugs.h
deleted file mode 100644
index fe52abb..0000000
--- a/kernel/arch/sh/include/asm/bugs.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_SH_BUGS_H
-#define __ASM_SH_BUGS_H
-
-/*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Needs:
- *	void check_bugs(void);
- */
-
-/*
- * I don't know of any Super-H bugs yet.
- */
-
-#include <asm/processor.h>
-
-extern void select_idle_routine(void);
-
-static void __init check_bugs(void)
-{
-	extern unsigned long loops_per_jiffy;
-	char *p = &init_utsname()->machine[2]; /* "sh" */
-
-	select_idle_routine();
-
-	current_cpu_data.loops_per_jiffy = loops_per_jiffy;
-
-	switch (current_cpu_data.family) {
-	case CPU_FAMILY_SH2:
-		*p++ = '2';
-		break;
-	case CPU_FAMILY_SH2A:
-		*p++ = '2';
-		*p++ = 'a';
-		break;
-	case CPU_FAMILY_SH3:
-		*p++ = '3';
-		break;
-	case CPU_FAMILY_SH4:
-		*p++ = '4';
-		break;
-	case CPU_FAMILY_SH4A:
-		*p++ = '4';
-		*p++ = 'a';
-		break;
-	case CPU_FAMILY_SH4AL_DSP:
-		*p++ = '4';
-		*p++ = 'a';
-		*p++ = 'l';
-		*p++ = '-';
-		*p++ = 'd';
-		*p++ = 's';
-		*p++ = 'p';
-		break;
-	case CPU_FAMILY_UNKNOWN:
-		/*
-		 * Specifically use CPU_FAMILY_UNKNOWN rather than
-		 * default:, so we're able to have the compiler whine
-		 * about unhandled enumerations.
-		 */
-		break;
-	}
-
-	printk("CPU: %s\n", get_cpu_subtype(&current_cpu_data));
-
-#ifndef __LITTLE_ENDIAN__
-	/* 'eb' means 'Endian Big' */
-	*p++ = 'e';
-	*p++ = 'b';
-#endif
-	*p = '\0';
-}
-#endif /* __ASM_SH_BUGS_H */
diff --git a/kernel/arch/sh/include/asm/pgtable-3level.h b/kernel/arch/sh/include/asm/pgtable-3level.h
index 82d7447..cdced80 100644
--- a/kernel/arch/sh/include/asm/pgtable-3level.h
+++ b/kernel/arch/sh/include/asm/pgtable-3level.h
@@ -32,9 +32,9 @@
 #define pmd_val(x)	((x).pmd)
 #define __pmd(x)	((pmd_t) { (x) } )
 
-static inline unsigned long pud_page_vaddr(pud_t pud)
+static inline pmd_t *pud_pgtable(pud_t pud)
 {
-	return pud_val(pud);
+	return (pmd_t *)(unsigned long)pud_val(pud);
 }
 
 /* only used by the stubbed out hugetlb gup code, should never be called */
diff --git a/kernel/arch/sh/include/asm/processor.h b/kernel/arch/sh/include/asm/processor.h
index 3820d69..97af2d9 100644
--- a/kernel/arch/sh/include/asm/processor.h
+++ b/kernel/arch/sh/include/asm/processor.h
@@ -167,6 +167,8 @@
 #define instruction_size(insn)	(2)
 #endif
 
+void select_idle_routine(void);
+
 #endif /* __ASSEMBLY__ */
 
 #include <asm/processor_32.h>
diff --git a/kernel/arch/sh/include/asm/processor_32.h b/kernel/arch/sh/include/asm/processor_32.h
index aa92cc9..6c7966e 100644
--- a/kernel/arch/sh/include/asm/processor_32.h
+++ b/kernel/arch/sh/include/asm/processor_32.h
@@ -50,6 +50,7 @@
 #define SR_FD		0x00008000
 #define SR_MD		0x40000000
 
+#define SR_USER_MASK	0x00000303	// M, Q, S, T bits
 /*
  * DSP structure and data
  */
diff --git a/kernel/arch/sh/kernel/cpu/sh2/probe.c b/kernel/arch/sh/kernel/cpu/sh2/probe.c
index d342ea0..70a07f4 100644
--- a/kernel/arch/sh/kernel/cpu/sh2/probe.c
+++ b/kernel/arch/sh/kernel/cpu/sh2/probe.c
@@ -21,7 +21,7 @@
 	if (!of_flat_dt_is_compatible(node, "jcore,cache"))
 		return 0;
 
-	j2_ccr_base = (u32 __iomem *)of_flat_dt_translate_address(node);
+	j2_ccr_base = ioremap(of_flat_dt_translate_address(node), 4);
 
 	return 1;
 }
diff --git a/kernel/arch/sh/kernel/cpu/sh4/sq.c b/kernel/arch/sh/kernel/cpu/sh4/sq.c
index d432164..c31ec0f 100644
--- a/kernel/arch/sh/kernel/cpu/sh4/sq.c
+++ b/kernel/arch/sh/kernel/cpu/sh4/sq.c
@@ -381,7 +381,7 @@
 	if (unlikely(!sq_cache))
 		return ret;
 
-	sq_bitmap = kzalloc(size, GFP_KERNEL);
+	sq_bitmap = kcalloc(size, sizeof(long), GFP_KERNEL);
 	if (unlikely(!sq_bitmap))
 		goto out;
 
diff --git a/kernel/arch/sh/kernel/head_32.S b/kernel/arch/sh/kernel/head_32.S
index 4adbd4a..b603b79 100644
--- a/kernel/arch/sh/kernel/head_32.S
+++ b/kernel/arch/sh/kernel/head_32.S
@@ -64,7 +64,7 @@
 	ldc	r0, r6_bank
 #endif
 
-#ifdef CONFIG_OF_FLATTREE
+#ifdef CONFIG_OF_EARLY_FLATTREE
 	mov	r4, r12		! Store device tree blob pointer in r12
 #endif
 	
@@ -315,7 +315,7 @@
 10:		
 #endif
 
-#ifdef CONFIG_OF_FLATTREE
+#ifdef CONFIG_OF_EARLY_FLATTREE
 	mov.l	8f, r0		! Make flat device tree available early.
 	jsr	@r0
 	 mov	r12, r4
@@ -346,7 +346,7 @@
 5:	.long	start_kernel
 6:	.long	cpu_init
 7:	.long	init_thread_union
-#if defined(CONFIG_OF_FLATTREE)
+#if defined(CONFIG_OF_EARLY_FLATTREE)
 8:	.long	sh_fdt_init
 #endif
 
diff --git a/kernel/arch/sh/kernel/idle.c b/kernel/arch/sh/kernel/idle.c
index f598149..a80b2a5 100644
--- a/kernel/arch/sh/kernel/idle.c
+++ b/kernel/arch/sh/kernel/idle.c
@@ -14,6 +14,7 @@
 #include <linux/irqflags.h>
 #include <linux/smp.h>
 #include <linux/atomic.h>
+#include <asm/processor.h>
 #include <asm/smp.h>
 #include <asm/bl_bit.h>
 
diff --git a/kernel/arch/sh/kernel/nmi_debug.c b/kernel/arch/sh/kernel/nmi_debug.c
index 1177786..a212b64 100644
--- a/kernel/arch/sh/kernel/nmi_debug.c
+++ b/kernel/arch/sh/kernel/nmi_debug.c
@@ -49,7 +49,7 @@
 	register_die_notifier(&nmi_debug_nb);
 
 	if (*str != '=')
-		return 0;
+		return 1;
 
 	for (p = str + 1; *p; p = sep + 1) {
 		sep = strchr(p, ',');
@@ -70,6 +70,6 @@
 			break;
 	}
 
-	return 0;
+	return 1;
 }
 __setup("nmi_debug", nmi_debug_setup);
diff --git a/kernel/arch/sh/kernel/setup.c b/kernel/arch/sh/kernel/setup.c
index 4144be6..805c02e 100644
--- a/kernel/arch/sh/kernel/setup.c
+++ b/kernel/arch/sh/kernel/setup.c
@@ -43,6 +43,7 @@
 #include <asm/smp.h>
 #include <asm/mmu_context.h>
 #include <asm/mmzone.h>
+#include <asm/processor.h>
 #include <asm/sparsemem.h>
 #include <asm/platform_early.h>
 
@@ -244,7 +245,7 @@
 {
 }
 
-#ifdef CONFIG_OF_FLATTREE
+#ifdef CONFIG_OF_EARLY_FLATTREE
 void __ref sh_fdt_init(phys_addr_t dt_phys)
 {
 	static int done = 0;
@@ -329,7 +330,7 @@
 	/* Let earlyprintk output early console messages */
 	sh_early_platform_driver_probe("earlyprintk", 1, 1);
 
-#ifdef CONFIG_OF_FLATTREE
+#ifdef CONFIG_OF_EARLY_FLATTREE
 #ifdef CONFIG_USE_BUILTIN_DTB
 	unflatten_and_copy_device_tree();
 #else
@@ -357,3 +358,57 @@
 {
 	return sh_mv.mv_mode_pins() & pin;
 }
+
+void __init arch_cpu_finalize_init(void)
+{
+	char *p = &init_utsname()->machine[2]; /* "sh" */
+
+	select_idle_routine();
+
+	current_cpu_data.loops_per_jiffy = loops_per_jiffy;
+
+	switch (current_cpu_data.family) {
+	case CPU_FAMILY_SH2:
+		*p++ = '2';
+		break;
+	case CPU_FAMILY_SH2A:
+		*p++ = '2';
+		*p++ = 'a';
+		break;
+	case CPU_FAMILY_SH3:
+		*p++ = '3';
+		break;
+	case CPU_FAMILY_SH4:
+		*p++ = '4';
+		break;
+	case CPU_FAMILY_SH4A:
+		*p++ = '4';
+		*p++ = 'a';
+		break;
+	case CPU_FAMILY_SH4AL_DSP:
+		*p++ = '4';
+		*p++ = 'a';
+		*p++ = 'l';
+		*p++ = '-';
+		*p++ = 'd';
+		*p++ = 's';
+		*p++ = 'p';
+		break;
+	case CPU_FAMILY_UNKNOWN:
+		/*
+		 * Specifically use CPU_FAMILY_UNKNOWN rather than
+		 * default:, so we're able to have the compiler whine
+		 * about unhandled enumerations.
+		 */
+		break;
+	}
+
+	pr_info("CPU: %s\n", get_cpu_subtype(&current_cpu_data));
+
+#ifndef __LITTLE_ENDIAN__
+	/* 'eb' means 'Endian Big' */
+	*p++ = 'e';
+	*p++ = 'b';
+#endif
+	*p = '\0';
+}
diff --git a/kernel/arch/sh/kernel/signal_32.c b/kernel/arch/sh/kernel/signal_32.c
index dd30929..dc13702 100644
--- a/kernel/arch/sh/kernel/signal_32.c
+++ b/kernel/arch/sh/kernel/signal_32.c
@@ -115,6 +115,7 @@
 restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p)
 {
 	unsigned int err = 0;
+	unsigned int sr = regs->sr & ~SR_USER_MASK;
 
 #define COPY(x)		err |= __get_user(regs->x, &sc->sc_##x)
 			COPY(regs[1]);
@@ -130,6 +131,8 @@
 	COPY(sr);	COPY(pc);
 #undef COPY
 
+	regs->sr = (regs->sr & SR_USER_MASK) | sr;
+
 #ifdef CONFIG_SH_FPU
 	if (boot_cpu_data.flags & CPU_HAS_FPU) {
 		int owned_fp;
diff --git a/kernel/arch/sh/kernel/traps.c b/kernel/arch/sh/kernel/traps.c
index 9c3d32b..4efffc1 100644
--- a/kernel/arch/sh/kernel/traps.c
+++ b/kernel/arch/sh/kernel/traps.c
@@ -57,7 +57,7 @@
 	if (panic_on_oops)
 		panic("Fatal exception");
 
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
 
 void die_if_kernel(const char *str, struct pt_regs *regs, long err)
diff --git a/kernel/arch/sh/kernel/vmlinux.lds.S b/kernel/arch/sh/kernel/vmlinux.lds.S
index 3161b9c..b6276a3 100644
--- a/kernel/arch/sh/kernel/vmlinux.lds.S
+++ b/kernel/arch/sh/kernel/vmlinux.lds.S
@@ -4,6 +4,7 @@
  * Written by Niibe Yutaka and Paul Mundt
  */
 OUTPUT_ARCH(sh)
+#define RUNTIME_DISCARD_EXIT
 #include <asm/thread_info.h>
 #include <asm/cache.h>
 #include <asm/vmlinux.lds.h>
diff --git a/kernel/arch/sh/math-emu/sfp-util.h b/kernel/arch/sh/math-emu/sfp-util.h
index 784f541..bda5076 100644
--- a/kernel/arch/sh/math-emu/sfp-util.h
+++ b/kernel/arch/sh/math-emu/sfp-util.h
@@ -67,7 +67,3 @@
   } while (0)
 
 #define abort()	return 0
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-
diff --git a/kernel/arch/sparc/Kconfig b/kernel/arch/sparc/Kconfig
index 530b7ec..7e2ce4c 100644
--- a/kernel/arch/sparc/Kconfig
+++ b/kernel/arch/sparc/Kconfig
@@ -56,6 +56,7 @@
 config SPARC32
 	def_bool !64BIT
 	select ARCH_32BIT_OFF_T
+	select ARCH_HAS_CPU_FINALIZE_INIT if !SMP
 	select ARCH_HAS_SYNC_DMA_FOR_CPU
 	select GENERIC_ATOMIC64
 	select CLZ_TAB
@@ -293,7 +294,7 @@
 	  This config option is actually maximum order plus one. For example,
 	  a value of 13 means that the largest free memory block is 2^12 pages.
 
-if SPARC64
+if SPARC64 || COMPILE_TEST
 source "kernel/power/Kconfig"
 endif
 
diff --git a/kernel/arch/sparc/include/asm/bugs.h b/kernel/arch/sparc/include/asm/bugs.h
deleted file mode 100644
index 02fa369..0000000
--- a/kernel/arch/sparc/include/asm/bugs.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* include/asm/bugs.h:  Sparc probes for various bugs.
- *
- * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net)
- */
-
-#ifdef CONFIG_SPARC32
-#include <asm/cpudata.h>
-#endif
-
-extern unsigned long loops_per_jiffy;
-
-static void __init check_bugs(void)
-{
-#if defined(CONFIG_SPARC32) && !defined(CONFIG_SMP)
-	cpu_data(0).udelay_val = loops_per_jiffy;
-#endif
-}
diff --git a/kernel/arch/sparc/include/asm/pgtable_32.h b/kernel/arch/sparc/include/asm/pgtable_32.h
index 632cdb9..7d1d10a 100644
--- a/kernel/arch/sparc/include/asm/pgtable_32.h
+++ b/kernel/arch/sparc/include/asm/pgtable_32.h
@@ -152,13 +152,13 @@
 	return (unsigned long)__nocache_va(v << 4);
 }
 
-static inline unsigned long pud_page_vaddr(pud_t pud)
+static inline pmd_t *pud_pgtable(pud_t pud)
 {
 	if (srmmu_device_memory(pud_val(pud))) {
-		return ~0;
+		return (pmd_t *)~0;
 	} else {
 		unsigned long v = pud_val(pud) & SRMMU_PTD_PMASK;
-		return (unsigned long)__nocache_va(v << 4);
+		return (pmd_t *)__nocache_va(v << 4);
 	}
 }
 
diff --git a/kernel/arch/sparc/include/asm/pgtable_64.h b/kernel/arch/sparc/include/asm/pgtable_64.h
index 7ef6aff..5a1efd6 100644
--- a/kernel/arch/sparc/include/asm/pgtable_64.h
+++ b/kernel/arch/sparc/include/asm/pgtable_64.h
@@ -845,23 +845,23 @@
 	return ((unsigned long) __va(pfn << PAGE_SHIFT));
 }
 
-static inline unsigned long pud_page_vaddr(pud_t pud)
+static inline pmd_t *pud_pgtable(pud_t pud)
 {
 	pte_t pte = __pte(pud_val(pud));
 	unsigned long pfn;
 
 	pfn = pte_pfn(pte);
 
-	return ((unsigned long) __va(pfn << PAGE_SHIFT));
+	return ((pmd_t *) __va(pfn << PAGE_SHIFT));
 }
 
 #define pmd_page(pmd) 			virt_to_page((void *)pmd_page_vaddr(pmd))
-#define pud_page(pud) 			virt_to_page((void *)pud_page_vaddr(pud))
+#define pud_page(pud)			virt_to_page((void *)pud_pgtable(pud))
 #define pmd_clear(pmdp)			(pmd_val(*(pmdp)) = 0UL)
 #define pud_present(pud)		(pud_val(pud) != 0U)
 #define pud_clear(pudp)			(pud_val(*(pudp)) = 0UL)
-#define p4d_page_vaddr(p4d)		\
-	((unsigned long) __va(p4d_val(p4d)))
+#define p4d_pgtable(p4d)		\
+	((pud_t *) __va(p4d_val(p4d)))
 #define p4d_present(p4d)		(p4d_val(p4d) != 0U)
 #define p4d_clear(p4dp)			(p4d_val(*(p4dp)) = 0UL)
 
diff --git a/kernel/arch/sparc/include/uapi/asm/socket.h b/kernel/arch/sparc/include/uapi/asm/socket.h
index 8029b68..08f9bbb 100644
--- a/kernel/arch/sparc/include/uapi/asm/socket.h
+++ b/kernel/arch/sparc/include/uapi/asm/socket.h
@@ -117,6 +117,8 @@
 
 #define SO_DETACH_REUSEPORT_BPF  0x0047
 
+#define SO_NETNS_COOKIE          0x0050
+
 #if !defined(__KERNEL__)
 
 
diff --git a/kernel/arch/sparc/kernel/setup_32.c b/kernel/arch/sparc/kernel/setup_32.c
index eea43a1..8e2c7c1 100644
--- a/kernel/arch/sparc/kernel/setup_32.c
+++ b/kernel/arch/sparc/kernel/setup_32.c
@@ -415,3 +415,10 @@
 }
 
 subsys_initcall(topology_init);
+
+#if defined(CONFIG_SPARC32) && !defined(CONFIG_SMP)
+void __init arch_cpu_finalize_init(void)
+{
+	cpu_data(0).udelay_val = loops_per_jiffy;
+}
+#endif
diff --git a/kernel/arch/sparc/kernel/traps_32.c b/kernel/arch/sparc/kernel/traps_32.c
index 247a0d9..5d47f4a 100644
--- a/kernel/arch/sparc/kernel/traps_32.c
+++ b/kernel/arch/sparc/kernel/traps_32.c
@@ -86,9 +86,7 @@
 	}
 	printk("Instruction DUMP:");
 	instruction_dump ((unsigned long *) regs->pc);
-	if(regs->psr & PSR_PS)
-		do_exit(SIGKILL);
-	do_exit(SIGSEGV);
+	make_task_dead((regs->psr & PSR_PS) ? SIGKILL : SIGSEGV);
 }
 
 void do_hw_interrupt(struct pt_regs *regs, unsigned long type)
diff --git a/kernel/arch/sparc/kernel/traps_64.c b/kernel/arch/sparc/kernel/traps_64.c
index a850dcc..814277d 100644
--- a/kernel/arch/sparc/kernel/traps_64.c
+++ b/kernel/arch/sparc/kernel/traps_64.c
@@ -2564,9 +2564,7 @@
 	}
 	if (panic_on_oops)
 		panic("Fatal exception");
-	if (regs->tstate & TSTATE_PRIV)
-		do_exit(SIGKILL);
-	do_exit(SIGSEGV);
+	make_task_dead((regs->tstate & TSTATE_PRIV)? SIGKILL : SIGSEGV);
 }
 EXPORT_SYMBOL(die_if_kernel);
 
diff --git a/kernel/arch/um/Kconfig b/kernel/arch/um/Kconfig
index 1c57599..eb1c688 100644
--- a/kernel/arch/um/Kconfig
+++ b/kernel/arch/um/Kconfig
@@ -5,6 +5,7 @@
 config UML
 	bool
 	default y
+	select ARCH_HAS_CPU_FINALIZE_INIT
 	select ARCH_HAS_KCOV
 	select ARCH_NO_PREEMPT
 	select HAVE_ARCH_AUDITSYSCALL
diff --git a/kernel/arch/um/Makefile b/kernel/arch/um/Makefile
index 7756151..56e5320 100644
--- a/kernel/arch/um/Makefile
+++ b/kernel/arch/um/Makefile
@@ -147,7 +147,7 @@
 # When cleaning we don't include .config, so we don't include
 # TT or skas makefiles and don't clean skas_ptregs.h.
 CLEAN_FILES += linux x.i gmon.out
-MRPROPER_FILES += arch/$(SUBARCH)/include/generated
+MRPROPER_FILES += $(HOST_DIR)/include/generated
 
 archclean:
 	@find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
diff --git a/kernel/arch/um/configs/i386_defconfig b/kernel/arch/um/configs/i386_defconfig
index fb51bd2..4d7f99a 100644
--- a/kernel/arch/um/configs/i386_defconfig
+++ b/kernel/arch/um/configs/i386_defconfig
@@ -35,6 +35,7 @@
 CONFIG_XTERM_CHAN=y
 CONFIG_CON_CHAN="pts"
 CONFIG_SSL_CHAN="pts"
+CONFIG_SOUND=m
 CONFIG_UML_SOUND=m
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
diff --git a/kernel/arch/um/configs/x86_64_defconfig b/kernel/arch/um/configs/x86_64_defconfig
index 477b873..4bdd830 100644
--- a/kernel/arch/um/configs/x86_64_defconfig
+++ b/kernel/arch/um/configs/x86_64_defconfig
@@ -33,6 +33,7 @@
 CONFIG_XTERM_CHAN=y
 CONFIG_CON_CHAN="pts"
 CONFIG_SSL_CHAN="pts"
+CONFIG_SOUND=m
 CONFIG_UML_SOUND=m
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
diff --git a/kernel/arch/um/drivers/Kconfig b/kernel/arch/um/drivers/Kconfig
index 2e7b8e0..01dfbd5 100644
--- a/kernel/arch/um/drivers/Kconfig
+++ b/kernel/arch/um/drivers/Kconfig
@@ -104,23 +104,13 @@
 
 config UML_SOUND
 	tristate "Sound support"
+	depends on SOUND
+	select SOUND_OSS_CORE
 	help
 	  This option enables UML sound support.  If enabled, it will pull in
-	  soundcore and the UML hostaudio relay, which acts as a intermediary
+	  the UML hostaudio relay, which acts as a intermediary
 	  between the host's dsp and mixer devices and the UML sound system.
 	  It is safe to say 'Y' here.
-
-config SOUND
-	tristate
-	default UML_SOUND
-
-config SOUND_OSS_CORE
-	bool
-	default UML_SOUND
-
-config HOSTAUDIO
-	tristate
-	default UML_SOUND
 
 endmenu
 
diff --git a/kernel/arch/um/drivers/Makefile b/kernel/arch/um/drivers/Makefile
index 2a249f6..207d62a 100644
--- a/kernel/arch/um/drivers/Makefile
+++ b/kernel/arch/um/drivers/Makefile
@@ -52,7 +52,7 @@
 obj-$(CONFIG_MCONSOLE) += mconsole.o
 obj-$(CONFIG_MMAPPER) += mmapper_kern.o 
 obj-$(CONFIG_BLK_DEV_UBD) += ubd.o 
-obj-$(CONFIG_HOSTAUDIO) += hostaudio.o
+obj-$(CONFIG_UML_SOUND) += hostaudio.o
 obj-$(CONFIG_NULL_CHAN) += null.o 
 obj-$(CONFIG_PORT_CHAN) += port.o
 obj-$(CONFIG_PTY_CHAN) += pty.o
diff --git a/kernel/arch/um/drivers/vector_kern.c b/kernel/arch/um/drivers/vector_kern.c
index 555203e..fc662f7 100644
--- a/kernel/arch/um/drivers/vector_kern.c
+++ b/kernel/arch/um/drivers/vector_kern.c
@@ -771,6 +771,7 @@
 
 	if (parsed == NULL) {
 		*error_out = "vector_config failed to parse parameters";
+		kfree(params);
 		return -EINVAL;
 	}
 
diff --git a/kernel/arch/um/include/asm/bugs.h b/kernel/arch/um/include/asm/bugs.h
deleted file mode 100644
index 4473942..0000000
--- a/kernel/arch/um/include/asm/bugs.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __UM_BUGS_H
-#define __UM_BUGS_H
-
-void check_bugs(void);
-
-#endif
diff --git a/kernel/arch/um/include/asm/pgtable-3level.h b/kernel/arch/um/include/asm/pgtable-3level.h
index 7e6a418..091bff3 100644
--- a/kernel/arch/um/include/asm/pgtable-3level.h
+++ b/kernel/arch/um/include/asm/pgtable-3level.h
@@ -84,7 +84,7 @@
 }
 
 #define pud_page(pud) phys_to_page(pud_val(pud) & PAGE_MASK)
-#define pud_page_vaddr(pud) ((unsigned long) __va(pud_val(pud) & PAGE_MASK))
+#define pud_pgtable(pud) ((pmd_t *) __va(pud_val(pud) & PAGE_MASK))
 
 static inline unsigned long pte_pfn(pte_t pte)
 {
diff --git a/kernel/arch/um/kernel/um_arch.c b/kernel/arch/um/kernel/um_arch.c
index 00c6dce..ca5383a 100644
--- a/kernel/arch/um/kernel/um_arch.c
+++ b/kernel/arch/um/kernel/um_arch.c
@@ -3,6 +3,7 @@
  * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  */
 
+#include <linux/cpu.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/mm.h>
@@ -353,7 +354,7 @@
 	setup_hostinfo(host_info, sizeof host_info);
 }
 
-void __init check_bugs(void)
+void __init arch_cpu_finalize_init(void)
 {
 	arch_check_bugs();
 	os_check_bugs();
@@ -387,12 +388,12 @@
 {
 }
 
-#ifdef CONFIG_PM_SLEEP
 void uml_pm_wake(void)
 {
 	pm_system_wakeup();
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int init_pm_wake_signal(void)
 {
 	/*
diff --git a/kernel/arch/um/kernel/vmlinux.lds.S b/kernel/arch/um/kernel/vmlinux.lds.S
index 16e49bf..53d719c 100644
--- a/kernel/arch/um/kernel/vmlinux.lds.S
+++ b/kernel/arch/um/kernel/vmlinux.lds.S
@@ -1,4 +1,4 @@
-
+#define RUNTIME_DISCARD_EXIT
 KERNEL_STACK_SIZE = 4096 * (1 << CONFIG_KERNEL_STACK_ORDER);
 
 #ifdef CONFIG_LD_SCRIPT_STATIC
diff --git a/kernel/arch/um/os-Linux/Makefile b/kernel/arch/um/os-Linux/Makefile
index 839915b..77ac50b 100644
--- a/kernel/arch/um/os-Linux/Makefile
+++ b/kernel/arch/um/os-Linux/Makefile
@@ -10,6 +10,8 @@
 	registers.o sigio.o signal.o start_up.o time.o tty.o \
 	umid.o user_syms.o util.o drivers/ skas/
 
+CFLAGS_signal.o += -Wframe-larger-than=4096
+
 obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o
 
 USER_OBJS := $(user-objs-y) elf_aux.o execvp.o file.o helper.o irq.o \
diff --git a/kernel/arch/x86/Kconfig b/kernel/arch/x86/Kconfig
index 32536ff..35ace6d 100644
--- a/kernel/arch/x86/Kconfig
+++ b/kernel/arch/x86/Kconfig
@@ -60,6 +60,7 @@
 	select ARCH_32BIT_OFF_T			if X86_32
 	select ARCH_CLOCKSOURCE_INIT
 	select ARCH_HAS_ACPI_TABLE_UPGRADE	if ACPI
+	select ARCH_HAS_CPU_FINALIZE_INIT
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEBUG_VM_PGTABLE	if !X86_PAE
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
@@ -1336,17 +1337,16 @@
 	  If you select this option, microcode patch loading support for AMD
 	  processors will be enabled.
 
-config MICROCODE_OLD_INTERFACE
-	bool "Ancient loading interface (DEPRECATED)"
+config MICROCODE_LATE_LOADING
+	bool "Late microcode loading (DANGEROUS)"
 	default n
 	depends on MICROCODE
 	help
-	  DO NOT USE THIS! This is the ancient /dev/cpu/microcode interface
-	  which was used by userspace tools like iucode_tool and microcode.ctl.
-	  It is inadequate because it runs too late to be able to properly
-	  load microcode on a machine and it needs special tools. Instead, you
-	  should've switched to the early loading method with the initrd or
-	  builtin microcode by now: Documentation/x86/microcode.rst
+	  Loading microcode late, when the system is up and executing instructions
+	  is a tricky business and should be avoided if possible. Just the sequence
+	  of synchronizing all cores and SMT threads is one fragile dance which does
+	  not guarantee that cores might not softlock after the loading. Therefore,
+	  use this at your own risk. Late loading taints the kernel too.
 
 config X86_MSR
 	tristate "/dev/cpu/*/msr - Model-specific register support"
@@ -2483,6 +2483,13 @@
 	  This mitigates both spectre_v2 and retbleed at great cost to
 	  performance.
 
+config CPU_SRSO
+	bool "Mitigate speculative RAS overflow on AMD"
+	depends on CPU_SUP_AMD && X86_64 && RETHUNK
+	default y
+	help
+	  Enable the SRSO mitigation needed on AMD Zen1-4 machines.
+
 config SLS
 	bool "Mitigate Straight-Line-Speculation"
 	depends on CC_HAS_SLS && X86_64
@@ -2492,6 +2499,25 @@
 	  against straight line speculation. The kernel image might be slightly
 	  larger.
 
+config GDS_FORCE_MITIGATION
+	bool "Force GDS Mitigation"
+	depends on CPU_SUP_INTEL
+	default n
+	help
+	  Gather Data Sampling (GDS) is a hardware vulnerability which allows
+	  unprivileged speculative access to data which was previously stored in
+	  vector registers.
+
+	  This option is equivalent to setting gather_data_sampling=force on the
+	  command line. The microcode mitigation is used if present, otherwise
+	  AVX is disabled as a mitigation. On affected systems that are missing
+	  the microcode any userspace code that unconditionally uses AVX will
+	  break with this option set.
+
+	  Setting this option on systems not vulnerable to GDS has no effect.
+
+	  If in doubt, say N.
+
 endif
 
 config ARCH_HAS_ADD_PAGES
diff --git a/kernel/arch/x86/boot/bioscall.S b/kernel/arch/x86/boot/bioscall.S
index 5521ea1..aa9b964 100644
--- a/kernel/arch/x86/boot/bioscall.S
+++ b/kernel/arch/x86/boot/bioscall.S
@@ -32,7 +32,7 @@
 	movw	%dx, %si
 	movw	%sp, %di
 	movw	$11, %cx
-	rep; movsd
+	rep; movsl
 
 	/* Pop full state from the stack */
 	popal
@@ -67,7 +67,7 @@
 	jz	4f
 	movw	%sp, %si
 	movw	$11, %cx
-	rep; movsd
+	rep; movsl
 4:	addw	$44, %sp
 
 	/* Restore state and return */
diff --git a/kernel/arch/x86/boot/boot.h b/kernel/arch/x86/boot/boot.h
index ca866f1..4d79391 100644
--- a/kernel/arch/x86/boot/boot.h
+++ b/kernel/arch/x86/boot/boot.h
@@ -110,66 +110,78 @@
 
 static inline u8 rdfs8(addr_t addr)
 {
+	u8 *ptr = (u8 *)absolute_pointer(addr);
 	u8 v;
-	asm volatile("movb %%fs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr));
+	asm volatile("movb %%fs:%1,%0" : "=q" (v) : "m" (*ptr));
 	return v;
 }
 static inline u16 rdfs16(addr_t addr)
 {
+	u16 *ptr = (u16 *)absolute_pointer(addr);
 	u16 v;
-	asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
+	asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*ptr));
 	return v;
 }
 static inline u32 rdfs32(addr_t addr)
 {
+	u32 *ptr = (u32 *)absolute_pointer(addr);
 	u32 v;
-	asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
+	asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*ptr));
 	return v;
 }
 
 static inline void wrfs8(u8 v, addr_t addr)
 {
-	asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "qi" (v));
+	u8 *ptr = (u8 *)absolute_pointer(addr);
+	asm volatile("movb %1,%%fs:%0" : "+m" (*ptr) : "qi" (v));
 }
 static inline void wrfs16(u16 v, addr_t addr)
 {
-	asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "ri" (v));
+	u16 *ptr = (u16 *)absolute_pointer(addr);
+	asm volatile("movw %1,%%fs:%0" : "+m" (*ptr) : "ri" (v));
 }
 static inline void wrfs32(u32 v, addr_t addr)
 {
-	asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "ri" (v));
+	u32 *ptr = (u32 *)absolute_pointer(addr);
+	asm volatile("movl %1,%%fs:%0" : "+m" (*ptr) : "ri" (v));
 }
 
 static inline u8 rdgs8(addr_t addr)
 {
+	u8 *ptr = (u8 *)absolute_pointer(addr);
 	u8 v;
-	asm volatile("movb %%gs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr));
+	asm volatile("movb %%gs:%1,%0" : "=q" (v) : "m" (*ptr));
 	return v;
 }
 static inline u16 rdgs16(addr_t addr)
 {
+	u16 *ptr = (u16 *)absolute_pointer(addr);
 	u16 v;
-	asm volatile("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
+	asm volatile("movw %%gs:%1,%0" : "=r" (v) : "m" (*ptr));
 	return v;
 }
 static inline u32 rdgs32(addr_t addr)
 {
+	u32 *ptr = (u32 *)absolute_pointer(addr);
 	u32 v;
-	asm volatile("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
+	asm volatile("movl %%gs:%1,%0" : "=r" (v) : "m" (*ptr));
 	return v;
 }
 
 static inline void wrgs8(u8 v, addr_t addr)
 {
-	asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "qi" (v));
+	u8 *ptr = (u8 *)absolute_pointer(addr);
+	asm volatile("movb %1,%%gs:%0" : "+m" (*ptr) : "qi" (v));
 }
 static inline void wrgs16(u16 v, addr_t addr)
 {
-	asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "ri" (v));
+	u16 *ptr = (u16 *)absolute_pointer(addr);
+	asm volatile("movw %1,%%gs:%0" : "+m" (*ptr) : "ri" (v));
 }
 static inline void wrgs32(u32 v, addr_t addr)
 {
-	asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "ri" (v));
+	u32 *ptr = (u32 *)absolute_pointer(addr);
+	asm volatile("movl %1,%%gs:%0" : "+m" (*ptr) : "ri" (v));
 }
 
 /* Note: these only return true/false, not a signed return value! */
diff --git a/kernel/arch/x86/boot/compressed/head_64.S b/kernel/arch/x86/boot/compressed/head_64.S
index b55e200..473d84e 100644
--- a/kernel/arch/x86/boot/compressed/head_64.S
+++ b/kernel/arch/x86/boot/compressed/head_64.S
@@ -454,11 +454,25 @@
 	/* Save the trampoline address in RCX */
 	movq	%rax, %rcx
 
+	/* Set up 32-bit addressable stack */
+	leaq	TRAMPOLINE_32BIT_STACK_END(%rcx), %rsp
+
 	/*
-	 * Load the address of trampoline_return() into RDI.
-	 * It will be used by the trampoline to return to the main code.
+	 * Preserve live 64-bit registers on the stack: this is necessary
+	 * because the architecture does not guarantee that GPRs will retain
+	 * their full 64-bit values across a 32-bit mode switch.
+	 */
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%rsi
+
+	/*
+	 * Push the 64-bit address of trampoline_return() onto the new stack.
+	 * It will be used by the trampoline to return to the main code. Due to
+	 * the 32-bit mode switch, it cannot be kept it in a register either.
 	 */
 	leaq	trampoline_return(%rip), %rdi
+	pushq	%rdi
 
 	/* Switch to compatibility mode (CS.L = 0 CS.D = 1) via far return */
 	pushq	$__KERNEL32_CS
@@ -466,6 +480,11 @@
 	pushq	%rax
 	lretq
 trampoline_return:
+	/* Restore live 64-bit registers */
+	popq	%rsi
+	popq	%rbx
+	popq	%rbp
+
 	/* Restore the stack, the 32-bit trampoline uses its own stack */
 	leaq	rva(boot_stack_end)(%rbx), %rsp
 
@@ -586,7 +605,7 @@
 /*
  * This is the 32-bit trampoline that will be copied over to low memory.
  *
- * RDI contains the return address (might be above 4G).
+ * Return address is at the top of the stack (might be above 4G).
  * ECX contains the base address of the trampoline memory.
  * Non zero RDX means trampoline needs to enable 5-level paging.
  */
@@ -595,9 +614,6 @@
 	movl	$__KERNEL_DS, %eax
 	movl	%eax, %ds
 	movl	%eax, %ss
-
-	/* Set up new stack */
-	leal	TRAMPOLINE_32BIT_STACK_END(%ecx), %esp
 
 	/* Disable paging */
 	movl	%cr0, %eax
@@ -658,7 +674,7 @@
 	.code64
 SYM_FUNC_START_LOCAL_NOALIGN(.Lpaging_enabled)
 	/* Return from the trampoline */
-	jmp	*%rdi
+	retq
 SYM_FUNC_END(.Lpaging_enabled)
 
 	/*
diff --git a/kernel/arch/x86/boot/compressed/ident_map_64.c b/kernel/arch/x86/boot/compressed/ident_map_64.c
index 39b2ede..f4a2e6d 100644
--- a/kernel/arch/x86/boot/compressed/ident_map_64.c
+++ b/kernel/arch/x86/boot/compressed/ident_map_64.c
@@ -67,6 +67,14 @@
 		return NULL;
 	}
 
+	/* Consumed more tables than expected? */
+	if (pages->pgt_buf_offset == BOOT_PGT_SIZE_WARN) {
+		debug_putstr("pgt_buf running low in " __FILE__ "\n");
+		debug_putstr("Need to raise BOOT_PGT_SIZE?\n");
+		debug_putaddr(pages->pgt_buf_offset);
+		debug_putaddr(pages->pgt_buf_size);
+	}
+
 	entry = pages->pgt_buf + pages->pgt_buf_offset;
 	pages->pgt_buf_offset += PAGE_SIZE;
 
diff --git a/kernel/arch/x86/boot/main.c b/kernel/arch/x86/boot/main.c
index e3add85..c421af5 100644
--- a/kernel/arch/x86/boot/main.c
+++ b/kernel/arch/x86/boot/main.c
@@ -33,7 +33,7 @@
 		u16 cl_offset;
 	};
 	const struct old_cmdline * const oldcmd =
-		(const struct old_cmdline *)OLD_CL_ADDRESS;
+		absolute_pointer(OLD_CL_ADDRESS);
 
 	BUILD_BUG_ON(sizeof(boot_params) != 4096);
 	memcpy(&boot_params.hdr, &hdr, sizeof(hdr));
diff --git a/kernel/arch/x86/configs/gki_defconfig b/kernel/arch/x86/configs/gki_defconfig
index 8c48624..9c6d1a0 100644
--- a/kernel/arch/x86/configs/gki_defconfig
+++ b/kernel/arch/x86/configs/gki_defconfig
@@ -220,7 +220,6 @@
 CONFIG_NET_SCH_FQ=y
 CONFIG_NET_SCH_INGRESS=y
 CONFIG_NET_CLS_BASIC=y
-CONFIG_NET_CLS_TCINDEX=y
 CONFIG_NET_CLS_FW=y
 CONFIG_NET_CLS_U32=y
 CONFIG_CLS_U32_MARK=y
@@ -343,6 +342,7 @@
 CONFIG_SERIAL_8250=y
 # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
 CONFIG_SERIAL_8250_RUNTIME_UARTS=0
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_SERIAL_SAMSUNG=y
@@ -523,6 +523,8 @@
 CONFIG_PSTORE_PMSG=y
 CONFIG_PSTORE_RAM=y
 CONFIG_EROFS_FS=y
+CONFIG_EROFS_FS_PCPU_KTHREAD=y
+CONFIG_EROFS_FS_PCPU_KTHREAD_HIPRI=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=y
 CONFIG_NLS_CODEPAGE_775=y
diff --git a/kernel/arch/x86/crypto/ghash-clmulni-intel_glue.c b/kernel/arch/x86/crypto/ghash-clmulni-intel_glue.c
index 1f1a95f..c0ab0ff 100644
--- a/kernel/arch/x86/crypto/ghash-clmulni-intel_glue.c
+++ b/kernel/arch/x86/crypto/ghash-clmulni-intel_glue.c
@@ -19,6 +19,7 @@
 #include <crypto/internal/simd.h>
 #include <asm/cpu_device_id.h>
 #include <asm/simd.h>
+#include <asm/unaligned.h>
 
 #define GHASH_BLOCK_SIZE	16
 #define GHASH_DIGEST_SIZE	16
@@ -54,15 +55,14 @@
 			const u8 *key, unsigned int keylen)
 {
 	struct ghash_ctx *ctx = crypto_shash_ctx(tfm);
-	be128 *x = (be128 *)key;
 	u64 a, b;
 
 	if (keylen != GHASH_BLOCK_SIZE)
 		return -EINVAL;
 
 	/* perform multiplication by 'x' in GF(2^128) */
-	a = be64_to_cpu(x->a);
-	b = be64_to_cpu(x->b);
+	a = get_unaligned_be64(key);
+	b = get_unaligned_be64(key + 8);
 
 	ctx->shash.a = (b << 1) | (a >> 63);
 	ctx->shash.b = (a << 1) | (b >> 63);
diff --git a/kernel/arch/x86/entry/entry_32.S b/kernel/arch/x86/entry/entry_32.S
index 8fcd6a4..70bd81b 100644
--- a/kernel/arch/x86/entry/entry_32.S
+++ b/kernel/arch/x86/entry/entry_32.S
@@ -1333,14 +1333,14 @@
 SYM_CODE_END(asm_exc_nmi)
 
 .pushsection .text, "ax"
-SYM_CODE_START(rewind_stack_do_exit)
+SYM_CODE_START(rewind_stack_and_make_dead)
 	/* Prevent any naive code from trying to unwind to our caller. */
 	xorl	%ebp, %ebp
 
 	movl	PER_CPU_VAR(cpu_current_top_of_stack), %esi
 	leal	-TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%esi), %esp
 
-	call	do_exit
+	call	make_task_dead
 1:	jmp 1b
-SYM_CODE_END(rewind_stack_do_exit)
+SYM_CODE_END(rewind_stack_and_make_dead)
 .popsection
diff --git a/kernel/arch/x86/entry/entry_64.S b/kernel/arch/x86/entry/entry_64.S
index 559c82b..23212c5 100644
--- a/kernel/arch/x86/entry/entry_64.S
+++ b/kernel/arch/x86/entry/entry_64.S
@@ -1509,7 +1509,7 @@
 #endif
 
 .pushsection .text, "ax"
-SYM_CODE_START(rewind_stack_do_exit)
+SYM_CODE_START(rewind_stack_and_make_dead)
 	UNWIND_HINT_FUNC
 	/* Prevent any naive code from trying to unwind to our caller. */
 	xorl	%ebp, %ebp
@@ -1518,6 +1518,6 @@
 	leaq	-PTREGS_SIZE(%rax), %rsp
 	UNWIND_HINT_REGS
 
-	call	do_exit
-SYM_CODE_END(rewind_stack_do_exit)
+	call	make_task_dead
+SYM_CODE_END(rewind_stack_and_make_dead)
 .popsection
diff --git a/kernel/arch/x86/entry/vdso/vma.c b/kernel/arch/x86/entry/vdso/vma.c
index 5876289..2b5e04c 100644
--- a/kernel/arch/x86/entry/vdso/vma.c
+++ b/kernel/arch/x86/entry/vdso/vma.c
@@ -339,8 +339,8 @@
 
 	/* Round the lowest possible end address up to a PMD boundary. */
 	end = (start + len + PMD_SIZE - 1) & PMD_MASK;
-	if (end >= TASK_SIZE_MAX)
-		end = TASK_SIZE_MAX;
+	if (end >= DEFAULT_MAP_WINDOW)
+		end = DEFAULT_MAP_WINDOW;
 	end -= len;
 
 	if (end > start) {
diff --git a/kernel/arch/x86/events/amd/core.c b/kernel/arch/x86/events/amd/core.c
index 39eb276..afc95534 100644
--- a/kernel/arch/x86/events/amd/core.c
+++ b/kernel/arch/x86/events/amd/core.c
@@ -364,7 +364,7 @@
 
 	/* pass precise event sampling to ibs: */
 	if (event->attr.precise_ip && get_ibs_caps())
-		return -ENOENT;
+		return forward_event_to_ibs(event);
 
 	if (has_branch_stack(event))
 		return -EOPNOTSUPP;
@@ -976,7 +976,7 @@
 		 * numbered counter following it.
 		 */
 		for (i = 0; i < x86_pmu.num_counters - 1; i += 2)
-			even_ctr_mask |= 1 << i;
+			even_ctr_mask |= BIT_ULL(i);
 
 		pair_constraint = (struct event_constraint)
 				    __EVENT_CONSTRAINT(0, even_ctr_mask, 0,
diff --git a/kernel/arch/x86/events/amd/ibs.c b/kernel/arch/x86/events/amd/ibs.c
index 8a85658..354d52e 100644
--- a/kernel/arch/x86/events/amd/ibs.c
+++ b/kernel/arch/x86/events/amd/ibs.c
@@ -202,7 +202,7 @@
 }
 
 /*
- * Use IBS for precise event sampling:
+ * core pmu config -> IBS config
  *
  *  perf record -a -e cpu-cycles:p ...    # use ibs op counting cycle count
  *  perf record -a -e r076:p ...          # same as -e cpu-cycles:p
@@ -211,25 +211,9 @@
  * IbsOpCntCtl (bit 19) of IBS Execution Control Register (IbsOpCtl,
  * MSRC001_1033) is used to select either cycle or micro-ops counting
  * mode.
- *
- * The rip of IBS samples has skid 0. Thus, IBS supports precise
- * levels 1 and 2 and the PERF_EFLAGS_EXACT is set. In rare cases the
- * rip is invalid when IBS was not able to record the rip correctly.
- * We clear PERF_EFLAGS_EXACT and take the rip from pt_regs then.
- *
  */
-static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
+static int core_pmu_ibs_config(struct perf_event *event, u64 *config)
 {
-	switch (event->attr.precise_ip) {
-	case 0:
-		return -ENOENT;
-	case 1:
-	case 2:
-		break;
-	default:
-		return -EOPNOTSUPP;
-	}
-
 	switch (event->attr.type) {
 	case PERF_TYPE_HARDWARE:
 		switch (event->attr.config) {
@@ -255,22 +239,37 @@
 	return -EOPNOTSUPP;
 }
 
+/*
+ * The rip of IBS samples has skid 0. Thus, IBS supports precise
+ * levels 1 and 2 and the PERF_EFLAGS_EXACT is set. In rare cases the
+ * rip is invalid when IBS was not able to record the rip correctly.
+ * We clear PERF_EFLAGS_EXACT and take the rip from pt_regs then.
+ */
+int forward_event_to_ibs(struct perf_event *event)
+{
+	u64 config = 0;
+
+	if (!event->attr.precise_ip || event->attr.precise_ip > 2)
+		return -EOPNOTSUPP;
+
+	if (!core_pmu_ibs_config(event, &config)) {
+		event->attr.type = perf_ibs_op.pmu.type;
+		event->attr.config = config;
+	}
+	return -ENOENT;
+}
+
 static int perf_ibs_init(struct perf_event *event)
 {
 	struct hw_perf_event *hwc = &event->hw;
 	struct perf_ibs *perf_ibs;
 	u64 max_cnt, config;
-	int ret;
 
 	perf_ibs = get_ibs_pmu(event->attr.type);
-	if (perf_ibs) {
-		config = event->attr.config;
-	} else {
-		perf_ibs = &perf_ibs_op;
-		ret = perf_ibs_precise_event(event, &config);
-		if (ret)
-			return ret;
-	}
+	if (!perf_ibs)
+		return -ENOENT;
+
+	config = event->attr.config;
 
 	if (event->pmu != &perf_ibs->pmu)
 		return -ENOENT;
diff --git a/kernel/arch/x86/events/intel/uncore.h b/kernel/arch/x86/events/intel/uncore.h
index 9efea15..4e2953a 100644
--- a/kernel/arch/x86/events/intel/uncore.h
+++ b/kernel/arch/x86/events/intel/uncore.h
@@ -84,6 +84,7 @@
 	/*
 	 * Optional callbacks for managing mapping of Uncore units to PMONs
 	 */
+	int (*get_topology)(struct intel_uncore_type *type);
 	int (*set_mapping)(struct intel_uncore_type *type);
 	void (*cleanup_mapping)(struct intel_uncore_type *type);
 };
diff --git a/kernel/arch/x86/events/intel/uncore_snb.c b/kernel/arch/x86/events/intel/uncore_snb.c
index fa92897..a4c20e3 100644
--- a/kernel/arch/x86/events/intel/uncore_snb.c
+++ b/kernel/arch/x86/events/intel/uncore_snb.c
@@ -1274,6 +1274,7 @@
 	/* 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 @@
 	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 = {
diff --git a/kernel/arch/x86/events/intel/uncore_snbep.c b/kernel/arch/x86/events/intel/uncore_snbep.c
index 03c8047..ad084a5 100644
--- a/kernel/arch/x86/events/intel/uncore_snbep.c
+++ b/kernel/arch/x86/events/intel/uncore_snbep.c
@@ -2828,6 +2828,7 @@
 		return false;
 
 	pci_read_config_dword(dev, HSWEP_PCU_CAPID4_OFFET, &capid4);
+	pci_dev_put(dev);
 	if (!hswep_get_chop(capid4))
 		return true;
 
@@ -3642,12 +3643,19 @@
 }
 
 static umode_t
-skx_iio_mapping_visible(struct kobject *kobj, struct attribute *attr, int die)
+pmu_iio_mapping_visible(struct kobject *kobj, struct attribute *attr,
+			 int die, int zero_bus_pmu)
 {
 	struct intel_uncore_pmu *pmu = dev_to_uncore_pmu(kobj_to_dev(kobj));
 
-	/* Root bus 0x00 is valid only for die 0 AND pmu_idx = 0. */
-	return (!skx_iio_stack(pmu, die) && pmu->pmu_idx) ? 0 : attr->mode;
+	return (!skx_iio_stack(pmu, die) && pmu->pmu_idx != zero_bus_pmu) ? 0 : attr->mode;
+}
+
+static umode_t
+skx_iio_mapping_visible(struct kobject *kobj, struct attribute *attr, int die)
+{
+	/* Root bus 0x00 is valid only for pmu_idx = 0. */
+	return pmu_iio_mapping_visible(kobj, attr, die, 0);
 }
 
 static ssize_t skx_iio_mapping_show(struct device *dev,
@@ -3739,7 +3747,23 @@
 	NULL,
 };
 
-static int skx_iio_set_mapping(struct intel_uncore_type *type)
+static void pmu_clear_mapping_attr(const struct attribute_group **groups,
+				   struct attribute_group *ag)
+{
+	int i;
+
+	for (i = 0; groups[i]; i++) {
+		if (groups[i] == ag) {
+			for (i++; groups[i]; i++)
+				groups[i - 1] = groups[i];
+			groups[i - 1] = NULL;
+			break;
+		}
+	}
+}
+
+static int
+pmu_iio_set_mapping(struct intel_uncore_type *type, struct attribute_group *ag)
 {
 	char buf[64];
 	int ret;
@@ -3747,8 +3771,8 @@
 	struct attribute **attrs = NULL;
 	struct dev_ext_attribute *eas = NULL;
 
-	ret = skx_iio_get_topology(type);
-	if (ret)
+	ret = type->get_topology(type);
+	if (ret < 0)
 		goto clear_attr_update;
 
 	ret = -ENOMEM;
@@ -3774,7 +3798,7 @@
 		eas[die].var = (void *)die;
 		attrs[die] = &eas[die].attr.attr;
 	}
-	skx_iio_mapping_group.attrs = attrs;
+	ag->attrs = attrs;
 
 	return 0;
 err:
@@ -3786,8 +3810,13 @@
 clear_topology:
 	kfree(type->topology);
 clear_attr_update:
-	type->attr_update = NULL;
+	pmu_clear_mapping_attr(type->attr_update, ag);
 	return ret;
+}
+
+static int skx_iio_set_mapping(struct intel_uncore_type *type)
+{
+	return pmu_iio_set_mapping(type, &skx_iio_mapping_group);
 }
 
 static void skx_iio_cleanup_mapping(struct intel_uncore_type *type)
@@ -3820,6 +3849,7 @@
 	.ops			= &skx_uncore_iio_ops,
 	.format_group		= &skx_uncore_iio_format_group,
 	.attr_update		= skx_iio_attr_update,
+	.get_topology		= skx_iio_get_topology,
 	.set_mapping		= skx_iio_set_mapping,
 	.cleanup_mapping	= skx_iio_cleanup_mapping,
 };
@@ -4680,6 +4710,8 @@
 
 	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);
diff --git a/kernel/arch/x86/events/zhaoxin/core.c b/kernel/arch/x86/events/zhaoxin/core.c
index e68827e..e927346 100644
--- a/kernel/arch/x86/events/zhaoxin/core.c
+++ b/kernel/arch/x86/events/zhaoxin/core.c
@@ -541,7 +541,13 @@
 
 	switch (boot_cpu_data.x86) {
 	case 0x06:
-		if (boot_cpu_data.x86_model == 0x0f || boot_cpu_data.x86_model == 0x19) {
+		/*
+		 * Support Zhaoxin CPU from ZXC series, exclude Nano series through FMS.
+		 * Nano FMS: Family=6, Model=F, Stepping=[0-A][C-D]
+		 * ZXC FMS: Family=6, Model=F, Stepping=E-F OR Family=6, Model=0x19, Stepping=0-3
+		 */
+		if ((boot_cpu_data.x86_model == 0x0f && boot_cpu_data.x86_stepping >= 0x0e) ||
+			boot_cpu_data.x86_model == 0x19) {
 
 			x86_pmu.max_period = x86_pmu.cntval_mask >> 1;
 
diff --git a/kernel/arch/x86/hyperv/hv_init.c b/kernel/arch/x86/hyperv/hv_init.c
index 01860c0..70fd21e 100644
--- a/kernel/arch/x86/hyperv/hv_init.c
+++ b/kernel/arch/x86/hyperv/hv_init.c
@@ -453,8 +453,6 @@
 {
 	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);
 
diff --git a/kernel/arch/x86/include/asm/boot.h b/kernel/arch/x86/include/asm/boot.h
index 9191280..215d37f 100644
--- a/kernel/arch/x86/include/asm/boot.h
+++ b/kernel/arch/x86/include/asm/boot.h
@@ -40,23 +40,40 @@
 #ifdef CONFIG_X86_64
 # define BOOT_STACK_SIZE	0x4000
 
-# define BOOT_INIT_PGT_SIZE	(6*4096)
-# ifdef CONFIG_RANDOMIZE_BASE
 /*
- * Assuming all cross the 512GB boundary:
- * 1 page for level4
- * (2+2)*4 pages for kernel, param, cmd_line, and randomized kernel
- * 2 pages for first 2M (video RAM: CONFIG_X86_VERBOSE_BOOTUP).
- * Total is 19 pages.
+ * Used by decompressor's startup_32() to allocate page tables for identity
+ * mapping of the 4G of RAM in 4-level paging mode:
+ * - 1 level4 table;
+ * - 1 level3 table;
+ * - 4 level2 table that maps everything with 2M pages;
+ *
+ * The additional level5 table needed for 5-level paging is allocated from
+ * trampoline_32bit memory.
  */
-#  ifdef CONFIG_X86_VERBOSE_BOOTUP
-#   define BOOT_PGT_SIZE	(19*4096)
-#  else /* !CONFIG_X86_VERBOSE_BOOTUP */
-#   define BOOT_PGT_SIZE	(17*4096)
-#  endif
-# else /* !CONFIG_RANDOMIZE_BASE */
-#  define BOOT_PGT_SIZE		BOOT_INIT_PGT_SIZE
-# endif
+# define BOOT_INIT_PGT_SIZE	(6*4096)
+
+/*
+ * Total number of page tables kernel_add_identity_map() can allocate,
+ * including page tables consumed by startup_32().
+ *
+ * Worst-case scenario:
+ *  - 5-level paging needs 1 level5 table;
+ *  - KASLR needs to map kernel, boot_params, cmdline and randomized kernel,
+ *    assuming all of them cross 256T boundary:
+ *    + 4*2 level4 table;
+ *    + 4*2 level3 table;
+ *    + 4*2 level2 table;
+ *  - X86_VERBOSE_BOOTUP needs to map the first 2M (video RAM):
+ *    + 1 level4 table;
+ *    + 1 level3 table;
+ *    + 1 level2 table;
+ * Total: 28 tables
+ *
+ * Add 4 spare table in case decompressor touches anything beyond what is
+ * accounted above. Warn if it happens.
+ */
+# define BOOT_PGT_SIZE_WARN	(28*4096)
+# define BOOT_PGT_SIZE		(32*4096)
 
 #else /* !CONFIG_X86_64 */
 # define BOOT_STACK_SIZE	0x1000
diff --git a/kernel/arch/x86/include/asm/bugs.h b/kernel/arch/x86/include/asm/bugs.h
index 92ae283..f25ca2d 100644
--- a/kernel/arch/x86/include/asm/bugs.h
+++ b/kernel/arch/x86/include/asm/bugs.h
@@ -4,8 +4,6 @@
 
 #include <asm/processor.h>
 
-extern void check_bugs(void);
-
 #if defined(CONFIG_CPU_SUP_INTEL) && defined(CONFIG_X86_32)
 int ppro_with_ram_bug(void);
 #else
diff --git a/kernel/arch/x86/include/asm/cpufeature.h b/kernel/arch/x86/include/asm/cpufeature.h
index f4cbc01..cc3f62f 100644
--- a/kernel/arch/x86/include/asm/cpufeature.h
+++ b/kernel/arch/x86/include/asm/cpufeature.h
@@ -31,6 +31,8 @@
 	CPUID_7_ECX,
 	CPUID_8000_0007_EBX,
 	CPUID_7_EDX,
+	CPUID_8000_001F_EAX,
+	CPUID_8000_0021_EAX,
 };
 
 #ifdef CONFIG_X86_FEATURE_NAMES
@@ -89,8 +91,10 @@
 	   CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 16, feature_bit) ||	\
 	   CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 17, feature_bit) ||	\
 	   CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) ||	\
+	   CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) ||	\
+	   CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) ||	\
 	   REQUIRED_MASK_CHECK					  ||	\
-	   BUILD_BUG_ON_ZERO(NCAPINTS != 19))
+	   BUILD_BUG_ON_ZERO(NCAPINTS != 21))
 
 #define DISABLED_MASK_BIT_SET(feature_bit)				\
 	 ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK,  0, feature_bit) ||	\
@@ -112,8 +116,10 @@
 	   CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 16, feature_bit) ||	\
 	   CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 17, feature_bit) ||	\
 	   CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) ||	\
+	   CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) ||	\
+	   CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) ||	\
 	   DISABLED_MASK_CHECK					  ||	\
-	   BUILD_BUG_ON_ZERO(NCAPINTS != 19))
+	   BUILD_BUG_ON_ZERO(NCAPINTS != 21))
 
 #define cpu_has(c, bit)							\
 	(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 :	\
diff --git a/kernel/arch/x86/include/asm/cpufeatures.h b/kernel/arch/x86/include/asm/cpufeatures.h
index 1fcda82..5a54c36 100644
--- a/kernel/arch/x86/include/asm/cpufeatures.h
+++ b/kernel/arch/x86/include/asm/cpufeatures.h
@@ -13,8 +13,8 @@
 /*
  * Defines x86 CPU feature bits
  */
-#define NCAPINTS			19	   /* N 32-bit words worth of info */
-#define NBUGINTS			1	   /* N 32-bit bug flags */
+#define NCAPINTS			21	   /* N 32-bit words worth of info */
+#define NBUGINTS			2	   /* N 32-bit bug flags */
 
 /*
  * Note: If the comment begins with a quoted string, that string is used
@@ -96,7 +96,7 @@
 #define X86_FEATURE_SYSCALL32		( 3*32+14) /* "" syscall in IA32 userspace */
 #define X86_FEATURE_SYSENTER32		( 3*32+15) /* "" sysenter in IA32 userspace */
 #define X86_FEATURE_REP_GOOD		( 3*32+16) /* REP microcode works well */
-#define X86_FEATURE_SME_COHERENT	( 3*32+17) /* "" AMD hardware-enforced cache coherency */
+/* FREE!                                ( 3*32+17) */
 #define X86_FEATURE_LFENCE_RDTSC	( 3*32+18) /* "" LFENCE synchronizes RDTSC */
 #define X86_FEATURE_ACC_POWER		( 3*32+19) /* AMD Accumulated Power Mechanism */
 #define X86_FEATURE_NOPL		( 3*32+20) /* The NOPL (0F 1F) instructions */
@@ -201,7 +201,7 @@
 #define X86_FEATURE_INVPCID_SINGLE	( 7*32+ 7) /* Effectively INVPCID && CR4.PCIDE=1 */
 #define X86_FEATURE_HW_PSTATE		( 7*32+ 8) /* AMD HW-PState */
 #define X86_FEATURE_PROC_FEEDBACK	( 7*32+ 9) /* AMD ProcFeedbackInterface */
-#define X86_FEATURE_SME			( 7*32+10) /* AMD Secure Memory Encryption */
+/* FREE!                                ( 7*32+10) */
 #define X86_FEATURE_PTI			( 7*32+11) /* Kernel Page Table Isolation enabled */
 #define X86_FEATURE_KERNEL_IBRS		( 7*32+12) /* "" Set/clear IBRS on kernel entry/exit */
 #define X86_FEATURE_RSB_VMEXIT		( 7*32+13) /* "" Fill RSB on VM-Exit */
@@ -211,7 +211,7 @@
 #define X86_FEATURE_SSBD		( 7*32+17) /* Speculative Store Bypass Disable */
 #define X86_FEATURE_MBA			( 7*32+18) /* Memory Bandwidth Allocation */
 #define X86_FEATURE_RSB_CTXSW		( 7*32+19) /* "" Fill RSB on context switches */
-#define X86_FEATURE_SEV			( 7*32+20) /* AMD Secure Encrypted Virtualization */
+/* FREE!                                ( 7*32+20) */
 #define X86_FEATURE_USE_IBPB		( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */
 #define X86_FEATURE_USE_IBRS_FW		( 7*32+22) /* "" Use IBRS during runtime firmware calls */
 #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE	( 7*32+23) /* "" Disable Speculative Store Bypass. */
@@ -236,7 +236,6 @@
 #define X86_FEATURE_EPT_AD		( 8*32+17) /* Intel Extended Page Table access-dirty bit */
 #define X86_FEATURE_VMCALL		( 8*32+18) /* "" Hypervisor supports the VMCALL instruction */
 #define X86_FEATURE_VMW_VMMCALL		( 8*32+19) /* "" VMware prefers VMMCALL hypercall instruction */
-#define X86_FEATURE_SEV_ES		( 8*32+20) /* AMD Secure Encrypted Virtualization - Encrypted State */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (EBX), word 9 */
 #define X86_FEATURE_FSGSBASE		( 9*32+ 0) /* RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions*/
@@ -301,6 +300,10 @@
 #define X86_FEATURE_USE_IBPB_FW		(11*32+16) /* "" Use IBPB during runtime firmware calls */
 #define X86_FEATURE_RSB_VMEXIT_LITE	(11*32+17) /* "" Fill RSB on VM exit when EIBRS is enabled */
 #define X86_FEATURE_MSR_TSX_CTRL	(11*32+18) /* "" MSR IA32_TSX_CTRL (Intel) implemented */
+
+#define X86_FEATURE_SRSO		(11*32+24) /* "" AMD BTB untrain RETs */
+#define X86_FEATURE_SRSO_ALIAS		(11*32+25) /* "" AMD BTB untrain RETs through aliasing */
+#define X86_FEATURE_IBPB_ON_VMEXIT	(11*32+26) /* "" Issue an IBPB only on VMEXIT */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
 #define X86_FEATURE_AVX512_BF16		(12*32+ 5) /* AVX512 BFLOAT16 instructions */
@@ -393,6 +396,17 @@
 #define X86_FEATURE_CORE_CAPABILITIES	(18*32+30) /* "" IA32_CORE_CAPABILITIES MSR */
 #define X86_FEATURE_SPEC_CTRL_SSBD	(18*32+31) /* "" Speculative Store Bypass Disable */
 
+/* AMD-defined memory encryption features, CPUID level 0x8000001f (EAX), word 19 */
+#define X86_FEATURE_SME			(19*32+ 0) /* AMD Secure Memory Encryption */
+#define X86_FEATURE_SEV			(19*32+ 1) /* AMD Secure Encrypted Virtualization */
+#define X86_FEATURE_VM_PAGE_FLUSH	(19*32+ 2) /* "" VM Page Flush MSR is supported */
+#define X86_FEATURE_SEV_ES		(19*32+ 3) /* AMD Secure Encrypted Virtualization - Encrypted State */
+#define X86_FEATURE_SME_COHERENT	(19*32+10) /* "" AMD hardware-enforced cache coherency */
+
+#define X86_FEATURE_SBPB		(20*32+27) /* "" Selective Branch Prediction Barrier */
+#define X86_FEATURE_IBPB_BRTYPE		(20*32+28) /* "" MSR_PRED_CMD[IBPB] flushes all branch type predictions */
+#define X86_FEATURE_SRSO_NO		(20*32+29) /* "" CPU is not affected by SRSO */
+
 /*
  * BUG word(s)
  */
@@ -433,5 +447,9 @@
 #define X86_BUG_MMIO_UNKNOWN		X86_BUG(26) /* CPU is too old and its MMIO Stale Data status is unknown */
 #define X86_BUG_RETBLEED		X86_BUG(27) /* CPU is affected by RETBleed */
 #define X86_BUG_EIBRS_PBRSB		X86_BUG(28) /* EIBRS is vulnerable to Post Barrier RSB Predictions */
+#define X86_BUG_GDS			X86_BUG(29) /* CPU is affected by Gather Data Sampling */
 
+/* BUG word 2 */
+#define X86_BUG_SRSO			X86_BUG(1*32 + 0) /* AMD SRSO bug */
+#define X86_BUG_DIV0			X86_BUG(1*32 + 1) /* AMD DIV0 speculation bug */
 #endif /* _ASM_X86_CPUFEATURES_H */
diff --git a/kernel/arch/x86/include/asm/debugreg.h b/kernel/arch/x86/include/asm/debugreg.h
index cfdf307..9ed8343 100644
--- a/kernel/arch/x86/include/asm/debugreg.h
+++ b/kernel/arch/x86/include/asm/debugreg.h
@@ -39,7 +39,20 @@
 		asm("mov %%db6, %0" :"=r" (val));
 		break;
 	case 7:
-		asm("mov %%db7, %0" :"=r" (val));
+		/*
+		 * Apply __FORCE_ORDER to DR7 reads to forbid re-ordering them
+		 * with other code.
+		 *
+		 * This is needed because a DR7 access can cause a #VC exception
+		 * when running under SEV-ES. Taking a #VC exception is not a
+		 * safe thing to do just anywhere in the entry code and
+		 * re-ordering might place the access into an unsafe location.
+		 *
+		 * This happened in the NMI handler, where the DR7 read was
+		 * re-ordered to happen before the call to sev_es_ist_enter(),
+		 * causing stack recursion.
+		 */
+		asm volatile("mov %%db7, %0" : "=r" (val) : __FORCE_ORDER);
 		break;
 	default:
 		BUG();
@@ -66,7 +79,16 @@
 		asm("mov %0, %%db6"	::"r" (value));
 		break;
 	case 7:
-		asm("mov %0, %%db7"	::"r" (value));
+		/*
+		 * Apply __FORCE_ORDER to DR7 writes to forbid re-ordering them
+		 * with other code.
+		 *
+		 * While is didn't happen with a DR7 write (see the DR7 read
+		 * comment above which explains where it happened), add the
+		 * __FORCE_ORDER here too to avoid similar problems in the
+		 * future.
+		 */
+		asm volatile("mov %0, %%db7"	::"r" (value), __FORCE_ORDER);
 		break;
 	default:
 		BUG();
diff --git a/kernel/arch/x86/include/asm/disabled-features.h b/kernel/arch/x86/include/asm/disabled-features.h
index 16c2491..3c24378 100644
--- a/kernel/arch/x86/include/asm/disabled-features.h
+++ b/kernel/arch/x86/include/asm/disabled-features.h
@@ -101,6 +101,8 @@
 			 DISABLE_ENQCMD)
 #define DISABLED_MASK17	0
 #define DISABLED_MASK18	0
-#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
+#define DISABLED_MASK19	0
+#define DISABLED_MASK20	0
+#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21)
 
 #endif /* _ASM_X86_DISABLED_FEATURES_H */
diff --git a/kernel/arch/x86/include/asm/entry-common.h b/kernel/arch/x86/include/asm/entry-common.h
index 4a382fb..5443851 100644
--- a/kernel/arch/x86/include/asm/entry-common.h
+++ b/kernel/arch/x86/include/asm/entry-common.h
@@ -78,6 +78,7 @@
 static __always_inline void arch_exit_to_user_mode(void)
 {
 	mds_user_clear_cpu_buffers();
+	amd_clear_divider();
 }
 #define arch_exit_to_user_mode arch_exit_to_user_mode
 
diff --git a/kernel/arch/x86/include/asm/fpu/internal.h b/kernel/arch/x86/include/asm/fpu/internal.h
index 70b9bc5..94c0715 100644
--- a/kernel/arch/x86/include/asm/fpu/internal.h
+++ b/kernel/arch/x86/include/asm/fpu/internal.h
@@ -42,7 +42,7 @@
 extern void fpu__init_cpu(void);
 extern void fpu__init_system_xstate(void);
 extern void fpu__init_cpu_xstate(void);
-extern void fpu__init_system(struct cpuinfo_x86 *c);
+extern void fpu__init_system(void);
 extern void fpu__init_check_bugs(void);
 extern void fpu__resume_cpu(void);
 extern u64 fpu__get_supported_xfeatures_mask(void);
diff --git a/kernel/arch/x86/include/asm/intel-family.h b/kernel/arch/x86/include/asm/intel-family.h
index 9abe842..0de49e3 100644
--- a/kernel/arch/x86/include/asm/intel-family.h
+++ b/kernel/arch/x86/include/asm/intel-family.h
@@ -98,6 +98,13 @@
 #define	INTEL_FAM6_LAKEFIELD		0x8A
 #define INTEL_FAM6_ALDERLAKE		0x97
 #define INTEL_FAM6_ALDERLAKE_L		0x9A
+#define INTEL_FAM6_ALDERLAKE_N		0xBE
+
+#define INTEL_FAM6_RAPTORLAKE		0xB7
+#define INTEL_FAM6_RAPTORLAKE_P		0xBA
+#define INTEL_FAM6_RAPTORLAKE_S		0xBF
+
+#define INTEL_FAM6_RAPTORLAKE		0xB7
 
 /* "Small Core" Processors (Atom) */
 
diff --git a/kernel/arch/x86/include/asm/kprobes.h b/kernel/arch/x86/include/asm/kprobes.h
index 991a7ad..bd7f588 100644
--- a/kernel/arch/x86/include/asm/kprobes.h
+++ b/kernel/arch/x86/include/asm/kprobes.h
@@ -58,14 +58,29 @@
 	/* copy of the original instruction */
 	kprobe_opcode_t *insn;
 	/*
-	 * boostable = false: This instruction type is not boostable.
-	 * boostable = true: This instruction has been boosted: we have
+	 * boostable = 0: This instruction type is not boostable.
+	 * boostable = 1: This instruction has been boosted: we have
 	 * added a relative jump after the instruction copy in insn,
 	 * so no single-step and fixup are needed (unless there's
 	 * a post_handler).
 	 */
-	bool boostable;
-	bool if_modifier;
+	unsigned boostable:1;
+	unsigned char size;	/* The size of insn */
+	union {
+		unsigned char opcode;
+		struct {
+			unsigned char type;
+		} jcc;
+		struct {
+			unsigned char type;
+			unsigned char asize;
+		} loop;
+		struct {
+			unsigned char reg;
+		} indirect;
+	};
+	s32 rel32;	/* relative offset must be s32, s16, or s8 */
+	void (*emulate_op)(struct kprobe *p, struct pt_regs *regs);
 	/* Number of bytes of text poked */
 	int tp_len;
 };
@@ -104,7 +119,6 @@
 extern int kprobe_exceptions_notify(struct notifier_block *self,
 				    unsigned long val, void *data);
 extern int kprobe_int3_handler(struct pt_regs *regs);
-extern int kprobe_debug_handler(struct pt_regs *regs);
 
 #else
 
diff --git a/kernel/arch/x86/include/asm/kvm_host.h b/kernel/arch/x86/include/asm/kvm_host.h
index 660012a..3e9f1c8 100644
--- a/kernel/arch/x86/include/asm/kvm_host.h
+++ b/kernel/arch/x86/include/asm/kvm_host.h
@@ -553,6 +553,7 @@
 	u64 ia32_misc_enable_msr;
 	u64 smbase;
 	u64 smi_count;
+	bool at_instruction_boundary;
 	bool tpr_access_reporting;
 	bool xsaves_enabled;
 	u64 ia32_xss;
@@ -663,7 +664,7 @@
 		u8 preempted;
 		u64 msr_val;
 		u64 last_steal;
-		struct gfn_to_pfn_cache cache;
+		struct gfn_to_hva_cache cache;
 	} st;
 
 	u64 l1_tsc_offset;
@@ -1061,6 +1062,8 @@
 	u64 req_event;
 	u64 halt_poll_success_ns;
 	u64 halt_poll_fail_ns;
+	u64 preemption_reported;
+	u64 preemption_other;
 };
 
 struct x86_instruction_info;
diff --git a/kernel/arch/x86/include/asm/mem_encrypt.h b/kernel/arch/x86/include/asm/mem_encrypt.h
index 8f3fa55..4406d58 100644
--- a/kernel/arch/x86/include/asm/mem_encrypt.h
+++ b/kernel/arch/x86/include/asm/mem_encrypt.h
@@ -47,13 +47,12 @@
 
 void __init mem_encrypt_free_decrypted_mem(void);
 
-/* Architecture __weak replacement functions */
-void __init mem_encrypt_init(void);
-
 void __init sev_es_init_vc_handling(void);
 bool sme_active(void);
 bool sev_active(void);
 bool sev_es_active(void);
+
+void __init mem_encrypt_init(void);
 
 #define __bss_decrypted __section(".bss..decrypted")
 
@@ -86,6 +85,8 @@
 
 static inline void mem_encrypt_free_decrypted_mem(void) { }
 
+static inline void mem_encrypt_init(void) { }
+
 #define __bss_decrypted
 
 #endif	/* CONFIG_AMD_MEM_ENCRYPT */
diff --git a/kernel/arch/x86/include/asm/microcode.h b/kernel/arch/x86/include/asm/microcode.h
index f733273..394605e 100644
--- a/kernel/arch/x86/include/asm/microcode.h
+++ b/kernel/arch/x86/include/asm/microcode.h
@@ -5,6 +5,7 @@
 #include <asm/cpu.h>
 #include <linux/earlycpio.h>
 #include <linux/initrd.h>
+#include <asm/microcode_amd.h>
 
 struct ucode_patch {
 	struct list_head plist;
@@ -131,7 +132,7 @@
 int __init microcode_init(void);
 extern void __init load_ucode_bsp(void);
 extern void load_ucode_ap(void);
-void reload_early_microcode(void);
+void reload_early_microcode(unsigned int cpu);
 extern bool get_builtin_firmware(struct cpio_data *cd, const char *name);
 extern bool initrd_gone;
 void microcode_bsp_resume(void);
@@ -139,7 +140,7 @@
 static inline int __init microcode_init(void)			{ return 0; };
 static inline void __init load_ucode_bsp(void)			{ }
 static inline void load_ucode_ap(void)				{ }
-static inline void reload_early_microcode(void)			{ }
+static inline void reload_early_microcode(unsigned int cpu)	{ }
 static inline void microcode_bsp_resume(void)			{ }
 static inline bool
 get_builtin_firmware(struct cpio_data *cd, const char *name)	{ return false; }
diff --git a/kernel/arch/x86/include/asm/microcode_amd.h b/kernel/arch/x86/include/asm/microcode_amd.h
index 7063b5a..403a8e7 100644
--- a/kernel/arch/x86/include/asm/microcode_amd.h
+++ b/kernel/arch/x86/include/asm/microcode_amd.h
@@ -47,12 +47,14 @@
 extern void __init load_ucode_amd_bsp(unsigned int family);
 extern void load_ucode_amd_ap(unsigned int family);
 extern int __init save_microcode_in_initrd_amd(unsigned int family);
-void reload_ucode_amd(void);
+void reload_ucode_amd(unsigned int cpu);
+extern void amd_check_microcode(void);
 #else
 static inline void __init load_ucode_amd_bsp(unsigned int family) {}
 static inline void load_ucode_amd_ap(unsigned int family) {}
 static inline int __init
 save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; }
-static inline void reload_ucode_amd(void) {}
+static inline void reload_ucode_amd(unsigned int cpu) {}
+static inline void amd_check_microcode(void) {}
 #endif
 #endif /* _ASM_X86_MICROCODE_AMD_H */
diff --git a/kernel/arch/x86/include/asm/msr-index.h b/kernel/arch/x86/include/asm/msr-index.h
index 5a8ee3b..202a52e 100644
--- a/kernel/arch/x86/include/asm/msr-index.h
+++ b/kernel/arch/x86/include/asm/msr-index.h
@@ -54,8 +54,13 @@
 #define SPEC_CTRL_RRSBA_DIS_S_SHIFT	6	   /* Disable RRSBA behavior */
 #define SPEC_CTRL_RRSBA_DIS_S		BIT(SPEC_CTRL_RRSBA_DIS_S_SHIFT)
 
+/* A mask for bits which the kernel toggles when controlling mitigations */
+#define SPEC_CTRL_MITIGATIONS_MASK	(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | SPEC_CTRL_SSBD \
+							| SPEC_CTRL_RRSBA_DIS_S)
+
 #define MSR_IA32_PRED_CMD		0x00000049 /* Prediction Command */
 #define PRED_CMD_IBPB			BIT(0)	   /* Indirect Branch Prediction Barrier */
+#define PRED_CMD_SBPB			BIT(7)	   /* Selective Branch Prediction Barrier */
 
 #define MSR_PPIN_CTL			0x0000004e
 #define MSR_PPIN			0x0000004f
@@ -152,6 +157,15 @@
 						 * Not susceptible to Post-Barrier
 						 * Return Stack Buffer Predictions.
 						 */
+#define ARCH_CAP_GDS_CTRL		BIT(25)	/*
+						 * CPU is vulnerable to Gather
+						 * Data Sampling (GDS) and
+						 * has controls for mitigation.
+						 */
+#define ARCH_CAP_GDS_NO			BIT(26)	/*
+						 * CPU is not vulnerable to Gather
+						 * Data Sampling (GDS).
+						 */
 
 #define MSR_IA32_FLUSH_CMD		0x0000010b
 #define L1D_FLUSH			BIT(0)	/*
@@ -170,6 +184,8 @@
 #define MSR_IA32_MCU_OPT_CTRL		0x00000123
 #define RNGDS_MITG_DIS			BIT(0)
 #define FB_CLEAR_DIS			BIT(3)	/* CPU Fill buffer clear disable */
+#define GDS_MITG_DIS			BIT(4)	/* Disable GDS mitigation */
+#define GDS_MITG_LOCKED			BIT(5)	/* GDS mitigation locked */
 
 #define MSR_IA32_SYSENTER_CS		0x00000174
 #define MSR_IA32_SYSENTER_ESP		0x00000175
@@ -493,6 +509,7 @@
 #define MSR_AMD64_DE_CFG		0xc0011029
 #define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT	 1
 #define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE	BIT_ULL(MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT)
+#define MSR_AMD64_DE_CFG_ZEN2_FP_BACKUP_FIX_BIT 9
 
 #define MSR_AMD64_BU_CFG2		0xc001102a
 #define MSR_AMD64_IBSFETCHCTL		0xc0011030
@@ -514,6 +531,7 @@
 #define MSR_AMD64_ICIBSEXTDCTL		0xc001103c
 #define MSR_AMD64_IBSOPDATA4		0xc001103d
 #define MSR_AMD64_IBS_REG_COUNT_MAX	8 /* includes MSR_AMD64_IBSBRTARGET */
+#define MSR_AMD64_VM_PAGE_FLUSH		0xc001011e
 #define MSR_AMD64_SEV_ES_GHCB		0xc0010130
 #define MSR_AMD64_SEV			0xc0010131
 #define MSR_AMD64_SEV_ENABLED_BIT	0
diff --git a/kernel/arch/x86/include/asm/nospec-branch.h b/kernel/arch/x86/include/asm/nospec-branch.h
index f14cdf9..7b47822 100644
--- a/kernel/arch/x86/include/asm/nospec-branch.h
+++ b/kernel/arch/x86/include/asm/nospec-branch.h
@@ -112,7 +112,7 @@
  * eventually turn into it's own annotation.
  */
 .macro ANNOTATE_UNRET_END
-#ifdef CONFIG_DEBUG_ENTRY
+#if (defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO))
 	ANNOTATE_RETPOLINE_SAFE
 	nop
 #endif
@@ -156,9 +156,9 @@
 .endm
 
 #ifdef CONFIG_CPU_UNRET_ENTRY
-#define CALL_ZEN_UNTRAIN_RET	"call zen_untrain_ret"
+#define CALL_UNTRAIN_RET	"call entry_untrain_ret"
 #else
-#define CALL_ZEN_UNTRAIN_RET	""
+#define CALL_UNTRAIN_RET	""
 #endif
 
 /*
@@ -166,17 +166,18 @@
  * return thunk isn't mapped into the userspace tables (then again, AMD
  * typically has NO_MELTDOWN).
  *
- * While zen_untrain_ret() doesn't clobber anything but requires stack,
+ * While retbleed_untrain_ret() doesn't clobber anything but requires stack,
  * entry_ibpb() will clobber AX, CX, DX.
  *
  * As such, this must be placed after every *SWITCH_TO_KERNEL_CR3 at a point
  * where we have a stack but before any RET instruction.
  */
 .macro UNTRAIN_RET
-#if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_IBPB_ENTRY)
+#if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_IBPB_ENTRY) || \
+	defined(CONFIG_CPU_SRSO)
 	ANNOTATE_UNRET_END
 	ALTERNATIVE_2 "",						\
-	              CALL_ZEN_UNTRAIN_RET, X86_FEATURE_UNRET,		\
+		      CALL_UNTRAIN_RET, X86_FEATURE_UNRET,		\
 		      "call entry_ibpb", X86_FEATURE_ENTRY_IBPB
 #endif
 .endm
@@ -189,8 +190,21 @@
 	_ASM_PTR " 999b\n\t"					\
 	".popsection\n\t"
 
+#ifdef CONFIG_RETHUNK
 extern void __x86_return_thunk(void);
-extern void zen_untrain_ret(void);
+#else
+static inline void __x86_return_thunk(void) {}
+#endif
+
+extern void retbleed_return_thunk(void);
+extern void srso_return_thunk(void);
+extern void srso_alias_return_thunk(void);
+
+extern void retbleed_untrain_ret(void);
+extern void srso_untrain_ret(void);
+extern void srso_alias_untrain_ret(void);
+
+extern void entry_untrain_ret(void);
 extern void entry_ibpb(void);
 
 #ifdef CONFIG_RETPOLINE
@@ -300,11 +314,11 @@
 		: "memory");
 }
 
+extern u64 x86_pred_cmd;
+
 static inline void indirect_branch_prediction_barrier(void)
 {
-	u64 val = PRED_CMD_IBPB;
-
-	alternative_msr_write(MSR_IA32_PRED_CMD, val, X86_FEATURE_USE_IBPB);
+	alternative_msr_write(MSR_IA32_PRED_CMD, x86_pred_cmd, X86_FEATURE_USE_IBPB);
 }
 
 /* The Intel SPEC CTRL MSR base value cache */
diff --git a/kernel/arch/x86/include/asm/perf_event.h b/kernel/arch/x86/include/asm/perf_event.h
index b9a7fd0..a4e4bbb 100644
--- a/kernel/arch/x86/include/asm/perf_event.h
+++ b/kernel/arch/x86/include/asm/perf_event.h
@@ -412,8 +412,10 @@
 
 #ifdef CONFIG_X86_LOCAL_APIC
 extern u32 get_ibs_caps(void);
+extern int forward_event_to_ibs(struct perf_event *event);
 #else
 static inline u32 get_ibs_caps(void) { return 0; }
+static inline int forward_event_to_ibs(struct perf_event *event) { return -ENOENT; }
 #endif
 
 #ifdef CONFIG_PERF_EVENTS
diff --git a/kernel/arch/x86/include/asm/pgtable.h b/kernel/arch/x86/include/asm/pgtable.h
index 87de9f2..9bacde3 100644
--- a/kernel/arch/x86/include/asm/pgtable.h
+++ b/kernel/arch/x86/include/asm/pgtable.h
@@ -865,9 +865,9 @@
 	return pud_flags(pud) & _PAGE_PRESENT;
 }
 
-static inline unsigned long pud_page_vaddr(pud_t pud)
+static inline pmd_t *pud_pgtable(pud_t pud)
 {
-	return (unsigned long)__va(pud_val(pud) & pud_pfn_mask(pud));
+	return (pmd_t *)__va(pud_val(pud) & pud_pfn_mask(pud));
 }
 
 /*
@@ -906,9 +906,9 @@
 	return p4d_flags(p4d) & _PAGE_PRESENT;
 }
 
-static inline unsigned long p4d_page_vaddr(p4d_t p4d)
+static inline pud_t *p4d_pgtable(p4d_t p4d)
 {
-	return (unsigned long)__va(p4d_val(p4d) & p4d_pfn_mask(p4d));
+	return (pud_t *)__va(p4d_val(p4d) & p4d_pfn_mask(p4d));
 }
 
 /*
diff --git a/kernel/arch/x86/include/asm/pgtable_64.h b/kernel/arch/x86/include/asm/pgtable_64.h
index 56d0399..dd520b4 100644
--- a/kernel/arch/x86/include/asm/pgtable_64.h
+++ b/kernel/arch/x86/include/asm/pgtable_64.h
@@ -235,8 +235,8 @@
 
 #define __pte_to_swp_entry(pte)		((swp_entry_t) { pte_val((pte)) })
 #define __pmd_to_swp_entry(pmd)		((swp_entry_t) { pmd_val((pmd)) })
-#define __swp_entry_to_pte(x)		((pte_t) { .pte = (x).val })
-#define __swp_entry_to_pmd(x)		((pmd_t) { .pmd = (x).val })
+#define __swp_entry_to_pte(x)		(__pte((x).val))
+#define __swp_entry_to_pmd(x)		(__pmd((x).val))
 
 extern int kern_addr_valid(unsigned long addr);
 extern void cleanup_highmap(void);
diff --git a/kernel/arch/x86/include/asm/pgtable_types.h b/kernel/arch/x86/include/asm/pgtable_types.h
index 394757e..85baa72 100644
--- a/kernel/arch/x86/include/asm/pgtable_types.h
+++ b/kernel/arch/x86/include/asm/pgtable_types.h
@@ -125,11 +125,12 @@
  * instance, and is *not* included in this mask since
  * pte_modify() does modify it.
  */
-#define _PAGE_CHG_MASK	(PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT |		\
-			 _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY |	\
-			 _PAGE_SOFT_DIRTY | _PAGE_DEVMAP | _PAGE_ENC |  \
-			 _PAGE_UFFD_WP)
-#define _HPAGE_CHG_MASK (_PAGE_CHG_MASK | _PAGE_PSE)
+#define _COMMON_PAGE_CHG_MASK	(PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT |	       \
+				 _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY |\
+				 _PAGE_SOFT_DIRTY | _PAGE_DEVMAP | _PAGE_ENC | \
+				 _PAGE_UFFD_WP)
+#define _PAGE_CHG_MASK	(_COMMON_PAGE_CHG_MASK | _PAGE_PAT)
+#define _HPAGE_CHG_MASK (_COMMON_PAGE_CHG_MASK | _PAGE_PSE | _PAGE_PAT_LARGE)
 
 /*
  * The cache modes defined here are used to translate between pure SW usage
diff --git a/kernel/arch/x86/include/asm/processor.h b/kernel/arch/x86/include/asm/processor.h
index d428d61..d7e017b 100644
--- a/kernel/arch/x86/include/asm/processor.h
+++ b/kernel/arch/x86/include/asm/processor.h
@@ -682,6 +682,7 @@
 extern void load_fixmap_gdt(int);
 extern void load_percpu_segment(int);
 extern void cpu_init(void);
+extern void cpu_init_secondary(void);
 extern void cpu_init_exception_handling(void);
 extern void cr4_init(void);
 
@@ -807,9 +808,13 @@
 #ifdef CONFIG_CPU_SUP_AMD
 extern u16 amd_get_nb_id(int cpu);
 extern u32 amd_get_nodes_per_socket(void);
+extern bool cpu_has_ibpb_brtype_microcode(void);
+extern void amd_clear_divider(void);
 #else
 static inline u16 amd_get_nb_id(int cpu)		{ return 0; }
 static inline u32 amd_get_nodes_per_socket(void)	{ return 0; }
+static inline bool cpu_has_ibpb_brtype_microcode(void)	{ return false; }
+static inline void amd_clear_divider(void)		{ }
 #endif
 
 static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)
@@ -838,8 +843,9 @@
 #define xen_set_default_idle 0
 #endif
 
-void stop_this_cpu(void *dummy);
-void microcode_check(void);
+void __noreturn stop_this_cpu(void *dummy);
+void microcode_check(struct cpuinfo_x86 *prev_info);
+void store_cpu_caps(struct cpuinfo_x86 *info);
 
 enum l1tf_mitigations {
 	L1TF_MITIGATION_OFF,
@@ -858,4 +864,6 @@
 	MDS_MITIGATION_VMWERV,
 };
 
+extern bool gds_ucode_mitigated(void);
+
 #endif /* _ASM_X86_PROCESSOR_H */
diff --git a/kernel/arch/x86/include/asm/reboot.h b/kernel/arch/x86/include/asm/reboot.h
index 04c17be..bc5b4d7 100644
--- a/kernel/arch/x86/include/asm/reboot.h
+++ b/kernel/arch/x86/include/asm/reboot.h
@@ -25,6 +25,8 @@
 #define MRR_BIOS	0
 #define MRR_APM		1
 
+void cpu_emergency_disable_virtualization(void);
+
 typedef void (*nmi_shootdown_cb)(int, struct pt_regs*);
 void nmi_panic_self_stop(struct pt_regs *regs);
 void nmi_shootdown_cpus(nmi_shootdown_cb callback);
diff --git a/kernel/arch/x86/include/asm/required-features.h b/kernel/arch/x86/include/asm/required-features.h
index 3ff0d48..9bf60a8 100644
--- a/kernel/arch/x86/include/asm/required-features.h
+++ b/kernel/arch/x86/include/asm/required-features.h
@@ -101,6 +101,8 @@
 #define REQUIRED_MASK16	0
 #define REQUIRED_MASK17	0
 #define REQUIRED_MASK18	0
-#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
+#define REQUIRED_MASK19	0
+#define REQUIRED_MASK20	0
+#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21)
 
 #endif /* _ASM_X86_REQUIRED_FEATURES_H */
diff --git a/kernel/arch/x86/include/asm/resctrl.h b/kernel/arch/x86/include/asm/resctrl.h
index 0760306..b9ccdf5 100644
--- a/kernel/arch/x86/include/asm/resctrl.h
+++ b/kernel/arch/x86/include/asm/resctrl.h
@@ -51,24 +51,27 @@
  *   simple as possible.
  * Must be called with preemption disabled.
  */
-static void __resctrl_sched_in(void)
+static inline void __resctrl_sched_in(struct task_struct *tsk)
 {
 	struct resctrl_pqr_state *state = this_cpu_ptr(&pqr_state);
 	u32 closid = state->default_closid;
 	u32 rmid = state->default_rmid;
+	u32 tmp;
 
 	/*
 	 * If this task has a closid/rmid assigned, use it.
 	 * Else use the closid/rmid assigned to this cpu.
 	 */
 	if (static_branch_likely(&rdt_alloc_enable_key)) {
-		if (current->closid)
-			closid = current->closid;
+		tmp = READ_ONCE(tsk->closid);
+		if (tmp)
+			closid = tmp;
 	}
 
 	if (static_branch_likely(&rdt_mon_enable_key)) {
-		if (current->rmid)
-			rmid = current->rmid;
+		tmp = READ_ONCE(tsk->rmid);
+		if (tmp)
+			rmid = tmp;
 	}
 
 	if (closid != state->cur_closid || rmid != state->cur_rmid) {
@@ -78,17 +81,17 @@
 	}
 }
 
-static inline void resctrl_sched_in(void)
+static inline void resctrl_sched_in(struct task_struct *tsk)
 {
 	if (static_branch_likely(&rdt_enable_key))
-		__resctrl_sched_in();
+		__resctrl_sched_in(tsk);
 }
 
 void resctrl_cpu_detect(struct cpuinfo_x86 *c);
 
 #else
 
-static inline void resctrl_sched_in(void) {}
+static inline void resctrl_sched_in(struct task_struct *tsk) {}
 static inline void resctrl_cpu_detect(struct cpuinfo_x86 *c) {}
 
 #endif /* CONFIG_X86_CPU_RESCTRL */
diff --git a/kernel/arch/x86/include/asm/virtext.h b/kernel/arch/x86/include/asm/virtext.h
index fda3e77..3314742 100644
--- a/kernel/arch/x86/include/asm/virtext.h
+++ b/kernel/arch/x86/include/asm/virtext.h
@@ -95,12 +95,6 @@
 		return 0;
 	}
 
-	if (boot_cpu_data.extended_cpuid_level < SVM_CPUID_FUNC) {
-		if (msg)
-			*msg = "can't execute cpuid_8000000a";
-		return 0;
-	}
-
 	if (!boot_cpu_has(X86_FEATURE_SVM)) {
 		if (msg)
 			*msg = "svm not available";
@@ -120,7 +114,21 @@
 
 	wrmsrl(MSR_VM_HSAVE_PA, 0);
 	rdmsrl(MSR_EFER, efer);
-	wrmsrl(MSR_EFER, efer & ~EFER_SVME);
+	if (efer & EFER_SVME) {
+		/*
+		 * Force GIF=1 prior to disabling SVM to ensure INIT and NMI
+		 * aren't blocked, e.g. if a fatal error occurred between CLGI
+		 * and STGI.  Note, STGI may #UD if SVM is disabled from NMI
+		 * context between reading EFER and executing STGI.  In that
+		 * case, GIF must already be set, otherwise the NMI would have
+		 * been blocked, so just eat the fault.
+		 */
+		asm_volatile_goto("1: stgi\n\t"
+				  _ASM_EXTABLE(1b, %l[fault])
+				  ::: "memory" : fault);
+fault:
+		wrmsrl(MSR_EFER, efer & ~EFER_SVME);
+	}
 }
 
 /** Makes sure SVM is disabled, if it is supported on the CPU
diff --git a/kernel/arch/x86/kernel/acpi/cstate.c b/kernel/arch/x86/kernel/acpi/cstate.c
index 49ae4e1..d28d43d 100644
--- a/kernel/arch/x86/kernel/acpi/cstate.c
+++ b/kernel/arch/x86/kernel/acpi/cstate.c
@@ -79,6 +79,21 @@
 		 */
 		flags->bm_control = 0;
 	}
+	if (c->x86_vendor == X86_VENDOR_AMD && c->x86 >= 0x17) {
+		/*
+		 * For all AMD Zen or newer CPUs that support C3, caches
+		 * should not be flushed by software while entering C3
+		 * type state. Set bm->check to 1 so that kernel doesn't
+		 * need to execute cache flush operation.
+		 */
+		flags->bm_check = 1;
+		/*
+		 * In current AMD C state implementation ARB_DIS is no longer
+		 * used. So set bm_control to zero to indicate ARB_DIS is not
+		 * required while entering C3 type state.
+		 */
+		flags->bm_control = 0;
+	}
 }
 EXPORT_SYMBOL(acpi_processor_power_init_bm_check);
 
diff --git a/kernel/arch/x86/kernel/apic/apic.c b/kernel/arch/x86/kernel/apic/apic.c
index 1c96f24..25eb69f 100644
--- a/kernel/arch/x86/kernel/apic/apic.c
+++ b/kernel/arch/x86/kernel/apic/apic.c
@@ -410,10 +410,9 @@
 		if (vector && !eilvt_entry_is_changeable(vector, new))
 			/* may not change if vectors are different */
 			return rsvd;
-		rsvd = atomic_cmpxchg(&eilvt_offsets[offset], rsvd, new);
-	} while (rsvd != new);
+	} while (!atomic_try_cmpxchg(&eilvt_offsets[offset], &rsvd, new));
 
-	rsvd &= ~APIC_EILVT_MASKED;
+	rsvd = new & ~APIC_EILVT_MASKED;
 	if (rsvd && rsvd != vector)
 		pr_info("LVT offset %d assigned for vector 0x%02x\n",
 			offset, rsvd);
diff --git a/kernel/arch/x86/kernel/apic/io_apic.c b/kernel/arch/x86/kernel/apic/io_apic.c
index 25b1d5c..7479438 100644
--- a/kernel/arch/x86/kernel/apic/io_apic.c
+++ b/kernel/arch/x86/kernel/apic/io_apic.c
@@ -2442,17 +2442,21 @@
 
 unsigned int arch_dynirq_lower_bound(unsigned int from)
 {
+	unsigned int ret;
+
 	/*
 	 * dmar_alloc_hwirq() may be called before setup_IO_APIC(), so use
 	 * gsi_top if ioapic_dynirq_base hasn't been initialized yet.
 	 */
-	if (!ioapic_initialized)
-		return gsi_top;
+	ret = ioapic_dynirq_base ? : gsi_top;
+
 	/*
-	 * For DT enabled machines ioapic_dynirq_base is irrelevant and not
-	 * updated. So simply return @from if ioapic_dynirq_base == 0.
+	 * For DT enabled machines ioapic_dynirq_base is irrelevant and
+	 * always 0. gsi_top can be 0 if there is no IO/APIC registered.
+	 * 0 is an invalid interrupt number for dynamic allocations. Return
+	 * @from instead.
 	 */
-	return ioapic_dynirq_base ? : from;
+	return ret ? : from;
 }
 
 #ifdef CONFIG_X86_32
diff --git a/kernel/arch/x86/kernel/apic/x2apic_phys.c b/kernel/arch/x86/kernel/apic/x2apic_phys.c
index 032a00e..76c80e1 100644
--- a/kernel/arch/x86/kernel/apic/x2apic_phys.c
+++ b/kernel/arch/x86/kernel/apic/x2apic_phys.c
@@ -97,7 +97,10 @@
 
 static int x2apic_phys_probe(void)
 {
-	if (x2apic_mode && (x2apic_phys || x2apic_fadt_phys()))
+	if (!x2apic_mode)
+		return 0;
+
+	if (x2apic_phys || x2apic_fadt_phys())
 		return 1;
 
 	return apic == &apic_x2apic_phys;
diff --git a/kernel/arch/x86/kernel/apm_32.c b/kernel/arch/x86/kernel/apm_32.c
index 6602703..166d999 100644
--- a/kernel/arch/x86/kernel/apm_32.c
+++ b/kernel/arch/x86/kernel/apm_32.c
@@ -238,12 +238,6 @@
 #endif
 
 /*
- * The apm_bios device is one of the misc char devices.
- * This is its minor number.
- */
-#define	APM_MINOR_DEV	134
-
-/*
  * Various options can be changed at boot time as follows:
  * (We allow underscores for compatibility with the modules code)
  *	apm=on/off			enable/disable APM
diff --git a/kernel/arch/x86/kernel/cpu/amd.c b/kernel/arch/x86/kernel/cpu/amd.c
index ec3fa4d..2bc1c78 100644
--- a/kernel/arch/x86/kernel/cpu/amd.c
+++ b/kernel/arch/x86/kernel/cpu/amd.c
@@ -28,17 +28,89 @@
 
 #include "cpu.h"
 
-static const int amd_erratum_383[];
-static const int amd_erratum_400[];
-static const int amd_erratum_1054[];
-static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum);
-
 /*
  * nodes_per_socket: Stores the number of nodes per socket.
  * Refer to Fam15h Models 00-0fh BKDG - CPUID Fn8000_001E_ECX
  * Node Identifiers[10:8]
  */
 static u32 nodes_per_socket = 1;
+
+/*
+ * AMD errata checking
+ *
+ * Errata are defined as arrays of ints using the AMD_LEGACY_ERRATUM() or
+ * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that
+ * have an OSVW id assigned, which it takes as first argument. Both take a
+ * variable number of family-specific model-stepping ranges created by
+ * AMD_MODEL_RANGE().
+ *
+ * Example:
+ *
+ * const int amd_erratum_319[] =
+ *	AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0x4, 0x2),
+ *			   AMD_MODEL_RANGE(0x10, 0x8, 0x0, 0x8, 0x0),
+ *			   AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0));
+ */
+
+#define AMD_LEGACY_ERRATUM(...)		{ -1, __VA_ARGS__, 0 }
+#define AMD_OSVW_ERRATUM(osvw_id, ...)	{ osvw_id, __VA_ARGS__, 0 }
+#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \
+	((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end))
+#define AMD_MODEL_RANGE_FAMILY(range)	(((range) >> 24) & 0xff)
+#define AMD_MODEL_RANGE_START(range)	(((range) >> 12) & 0xfff)
+#define AMD_MODEL_RANGE_END(range)	((range) & 0xfff)
+
+static const int amd_erratum_400[] =
+	AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf),
+			    AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf));
+
+static const int amd_erratum_383[] =
+	AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf));
+
+/* #1054: Instructions Retired Performance Counter May Be Inaccurate */
+static const int amd_erratum_1054[] =
+	AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf));
+
+static const int amd_zenbleed[] =
+	AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0x30, 0x0, 0x4f, 0xf),
+			   AMD_MODEL_RANGE(0x17, 0x60, 0x0, 0x7f, 0xf),
+			   AMD_MODEL_RANGE(0x17, 0x90, 0x0, 0x91, 0xf),
+			   AMD_MODEL_RANGE(0x17, 0xa0, 0x0, 0xaf, 0xf));
+
+static const int amd_div0[] =
+	AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0x00, 0x0, 0x2f, 0xf),
+			   AMD_MODEL_RANGE(0x17, 0x50, 0x0, 0x5f, 0xf));
+
+static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)
+{
+	int osvw_id = *erratum++;
+	u32 range;
+	u32 ms;
+
+	if (osvw_id >= 0 && osvw_id < 65536 &&
+	    cpu_has(cpu, X86_FEATURE_OSVW)) {
+		u64 osvw_len;
+
+		rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, osvw_len);
+		if (osvw_id < osvw_len) {
+			u64 osvw_bits;
+
+			rdmsrl(MSR_AMD64_OSVW_STATUS + (osvw_id >> 6),
+			    osvw_bits);
+			return osvw_bits & (1ULL << (osvw_id & 0x3f));
+		}
+	}
+
+	/* OSVW unavailable or ID unknown, match family-model-stepping range */
+	ms = (cpu->x86_model << 4) | cpu->x86_stepping;
+	while ((range = *erratum++))
+		if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) &&
+		    (ms >= AMD_MODEL_RANGE_START(range)) &&
+		    (ms <= AMD_MODEL_RANGE_END(range)))
+			return true;
+
+	return false;
+}
 
 static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
 {
@@ -932,6 +1004,15 @@
 		}
 	}
 #endif
+	/*
+	 * Work around Erratum 1386.  The XSAVES instruction malfunctions in
+	 * certain circumstances on Zen1/2 uarch, and not all parts have had
+	 * updated microcode at the time of writing (March 2023).
+	 *
+	 * Affected parts all have no supervisor XSAVE states, meaning that
+	 * the XSAVEC instruction (which works fine) is equivalent.
+	 */
+	clear_cpu_cap(c, X86_FEATURE_XSAVES);
 }
 
 static void init_amd_zn(struct cpuinfo_x86 *c)
@@ -956,6 +1037,47 @@
 		 */
 		if (c->x86 == 0x19 && !cpu_has(c, X86_FEATURE_BTC_NO))
 			set_cpu_cap(c, X86_FEATURE_BTC_NO);
+	}
+}
+
+static bool cpu_has_zenbleed_microcode(void)
+{
+	u32 good_rev = 0;
+
+	switch (boot_cpu_data.x86_model) {
+	case 0x30 ... 0x3f: good_rev = 0x0830107a; break;
+	case 0x60 ... 0x67: good_rev = 0x0860010b; break;
+	case 0x68 ... 0x6f: good_rev = 0x08608105; break;
+	case 0x70 ... 0x7f: good_rev = 0x08701032; break;
+	case 0xa0 ... 0xaf: good_rev = 0x08a00008; break;
+
+	default:
+		return false;
+		break;
+	}
+
+	if (boot_cpu_data.microcode < good_rev)
+		return false;
+
+	return true;
+}
+
+static void zenbleed_check(struct cpuinfo_x86 *c)
+{
+	if (!cpu_has_amd_erratum(c, amd_zenbleed))
+		return;
+
+	if (cpu_has(c, X86_FEATURE_HYPERVISOR))
+		return;
+
+	if (!cpu_has(c, X86_FEATURE_AVX))
+		return;
+
+	if (!cpu_has_zenbleed_microcode()) {
+		pr_notice_once("Zenbleed: please update your microcode for the most optimal fix\n");
+		msr_set_bit(MSR_AMD64_DE_CFG, MSR_AMD64_DE_CFG_ZEN2_FP_BACKUP_FIX_BIT);
+	} else {
+		msr_clear_bit(MSR_AMD64_DE_CFG, MSR_AMD64_DE_CFG_ZEN2_FP_BACKUP_FIX_BIT);
 	}
 }
 
@@ -1049,6 +1171,13 @@
 		msr_set_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT);
 
 	check_null_seg_clears_base(c);
+
+	zenbleed_check(c);
+
+	if (cpu_has_amd_erratum(c, amd_div0)) {
+		pr_notice_once("AMD Zen1 DIV0 bug detected. Disable SMT for full protection.\n");
+		setup_force_cpu_bug(X86_BUG_DIV0);
+	}
 }
 
 #ifdef CONFIG_X86_32
@@ -1144,73 +1273,6 @@
 
 cpu_dev_register(amd_cpu_dev);
 
-/*
- * AMD errata checking
- *
- * Errata are defined as arrays of ints using the AMD_LEGACY_ERRATUM() or
- * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that
- * have an OSVW id assigned, which it takes as first argument. Both take a
- * variable number of family-specific model-stepping ranges created by
- * AMD_MODEL_RANGE().
- *
- * Example:
- *
- * const int amd_erratum_319[] =
- *	AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0x4, 0x2),
- *			   AMD_MODEL_RANGE(0x10, 0x8, 0x0, 0x8, 0x0),
- *			   AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0));
- */
-
-#define AMD_LEGACY_ERRATUM(...)		{ -1, __VA_ARGS__, 0 }
-#define AMD_OSVW_ERRATUM(osvw_id, ...)	{ osvw_id, __VA_ARGS__, 0 }
-#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \
-	((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end))
-#define AMD_MODEL_RANGE_FAMILY(range)	(((range) >> 24) & 0xff)
-#define AMD_MODEL_RANGE_START(range)	(((range) >> 12) & 0xfff)
-#define AMD_MODEL_RANGE_END(range)	((range) & 0xfff)
-
-static const int amd_erratum_400[] =
-	AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf),
-			    AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf));
-
-static const int amd_erratum_383[] =
-	AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf));
-
-/* #1054: Instructions Retired Performance Counter May Be Inaccurate */
-static const int amd_erratum_1054[] =
-	AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf));
-
-static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)
-{
-	int osvw_id = *erratum++;
-	u32 range;
-	u32 ms;
-
-	if (osvw_id >= 0 && osvw_id < 65536 &&
-	    cpu_has(cpu, X86_FEATURE_OSVW)) {
-		u64 osvw_len;
-
-		rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, osvw_len);
-		if (osvw_id < osvw_len) {
-			u64 osvw_bits;
-
-			rdmsrl(MSR_AMD64_OSVW_STATUS + (osvw_id >> 6),
-			    osvw_bits);
-			return osvw_bits & (1ULL << (osvw_id & 0x3f));
-		}
-	}
-
-	/* OSVW unavailable or ID unknown, match family-model-stepping range */
-	ms = (cpu->x86_model << 4) | cpu->x86_stepping;
-	while ((range = *erratum++))
-		if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) &&
-		    (ms >= AMD_MODEL_RANGE_START(range)) &&
-		    (ms <= AMD_MODEL_RANGE_END(range)))
-			return true;
-
-	return false;
-}
-
 void set_dr_addr_mask(unsigned long mask, int dr)
 {
 	if (!boot_cpu_has(X86_FEATURE_BPEXT))
@@ -1229,3 +1291,45 @@
 		break;
 	}
 }
+
+bool cpu_has_ibpb_brtype_microcode(void)
+{
+	switch (boot_cpu_data.x86) {
+	/* Zen1/2 IBPB flushes branch type predictions too. */
+	case 0x17:
+		return boot_cpu_has(X86_FEATURE_AMD_IBPB);
+	case 0x19:
+		/* Poke the MSR bit on Zen3/4 to check its presence. */
+		if (!wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) {
+			setup_force_cpu_cap(X86_FEATURE_SBPB);
+			return true;
+		} else {
+			return false;
+		}
+	default:
+		return false;
+	}
+}
+
+static void zenbleed_check_cpu(void *unused)
+{
+	struct cpuinfo_x86 *c = &cpu_data(smp_processor_id());
+
+	zenbleed_check(c);
+}
+
+void amd_check_microcode(void)
+{
+	on_each_cpu(zenbleed_check_cpu, NULL, 1);
+}
+
+/*
+ * Issue a DIV 0/1 insn to clear any division data from previous DIV
+ * operations.
+ */
+void noinstr amd_clear_divider(void)
+{
+	asm volatile(ALTERNATIVE("", "div %2\n\t", X86_BUG_DIV0)
+		     :: "a" (0), "d" (0), "r" (1));
+}
+EXPORT_SYMBOL_GPL(amd_clear_divider);
diff --git a/kernel/arch/x86/kernel/cpu/bugs.c b/kernel/arch/x86/kernel/cpu/bugs.c
index e2e22a5..ec3ddb9 100644
--- a/kernel/arch/x86/kernel/cpu/bugs.c
+++ b/kernel/arch/x86/kernel/cpu/bugs.c
@@ -9,7 +9,6 @@
  *	- Andrew D. Balsa (code cleanup).
  */
 #include <linux/init.h>
-#include <linux/utsname.h>
 #include <linux/cpu.h>
 #include <linux/module.h>
 #include <linux/nospec.h>
@@ -27,8 +26,6 @@
 #include <asm/msr.h>
 #include <asm/vmx.h>
 #include <asm/paravirt.h>
-#include <asm/alternative.h>
-#include <asm/set_memory.h>
 #include <asm/intel-family.h>
 #include <asm/e820/api.h>
 #include <asm/hypervisor.h>
@@ -48,6 +45,8 @@
 static void __init taa_select_mitigation(void);
 static void __init mmio_select_mitigation(void);
 static void __init srbds_select_mitigation(void);
+static void __init gds_select_mitigation(void);
+static void __init srso_select_mitigation(void);
 
 /* The base value of the SPEC_CTRL MSR without task-specific bits set */
 u64 x86_spec_ctrl_base;
@@ -57,7 +56,12 @@
 DEFINE_PER_CPU(u64, x86_spec_ctrl_current);
 EXPORT_SYMBOL_GPL(x86_spec_ctrl_current);
 
+u64 x86_pred_cmd __ro_after_init = PRED_CMD_IBPB;
+EXPORT_SYMBOL_GPL(x86_pred_cmd);
+
 static DEFINE_MUTEX(spec_ctrl_mutex);
+
+void (*x86_return_thunk)(void) __ro_after_init = &__x86_return_thunk;
 
 /* Update SPEC_CTRL MSR and its cached copy unconditionally */
 static void update_spec_ctrl(u64 val)
@@ -116,28 +120,23 @@
 DEFINE_STATIC_KEY_FALSE(mmio_stale_data_clear);
 EXPORT_SYMBOL_GPL(mmio_stale_data_clear);
 
-void __init check_bugs(void)
+void __init cpu_select_mitigations(void)
 {
-	identify_boot_cpu();
-
-	/*
-	 * identify_boot_cpu() initialized SMT support information, let the
-	 * core code know.
-	 */
-	cpu_smt_check_topology();
-
-	if (!IS_ENABLED(CONFIG_SMP)) {
-		pr_info("CPU: ");
-		print_cpu_info(&boot_cpu_data);
-	}
-
 	/*
 	 * Read the SPEC_CTRL MSR to account for reserved bits which may
 	 * have unknown values. AMD64_LS_CFG MSR is cached in the early AMD
 	 * init code as it is not enumerated and depends on the family.
 	 */
-	if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL))
+	if (cpu_feature_enabled(X86_FEATURE_MSR_SPEC_CTRL)) {
 		rdmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
+
+		/*
+		 * Previously running kernel (kexec), may have some controls
+		 * turned ON. Clear them and let the mitigations setup below
+		 * rediscover them based on configuration.
+		 */
+		x86_spec_ctrl_base &= ~SPEC_CTRL_MITIGATIONS_MASK;
+	}
 
 	/* Select the proper CPU mitigations before patching alternatives: */
 	spectre_v1_select_mitigation();
@@ -159,38 +158,12 @@
 	md_clear_select_mitigation();
 	srbds_select_mitigation();
 
-	arch_smt_update();
-
-#ifdef CONFIG_X86_32
 	/*
-	 * Check whether we are able to run this kernel safely on SMP.
-	 *
-	 * - i386 is no longer supported.
-	 * - In order to run on anything without a TSC, we need to be
-	 *   compiled for a i486.
+	 * srso_select_mitigation() depends and must run after
+	 * retbleed_select_mitigation().
 	 */
-	if (boot_cpu_data.x86 < 4)
-		panic("Kernel requires i486+ for 'invlpg' and other features");
-
-	init_utsname()->machine[1] =
-		'0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86);
-	alternative_instructions();
-
-	fpu__init_check_bugs();
-#else /* CONFIG_X86_64 */
-	alternative_instructions();
-
-	/*
-	 * Make sure the first 2MB area is not mapped by huge pages
-	 * There are typically fixed size MTRRs in there and overlapping
-	 * MTRRs into large pages causes slow downs.
-	 *
-	 * Right now we don't do that with gbpages because there seems
-	 * very little benefit for that case.
-	 */
-	if (!direct_gbpages)
-		set_memory_4k((unsigned long)__va(0), 1);
-#endif
+	srso_select_mitigation();
+	gds_select_mitigation();
 }
 
 /*
@@ -649,6 +622,149 @@
 early_param("srbds", srbds_parse_cmdline);
 
 #undef pr_fmt
+#define pr_fmt(fmt)	"GDS: " fmt
+
+enum gds_mitigations {
+	GDS_MITIGATION_OFF,
+	GDS_MITIGATION_UCODE_NEEDED,
+	GDS_MITIGATION_FORCE,
+	GDS_MITIGATION_FULL,
+	GDS_MITIGATION_FULL_LOCKED,
+	GDS_MITIGATION_HYPERVISOR,
+};
+
+#if IS_ENABLED(CONFIG_GDS_FORCE_MITIGATION)
+static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FORCE;
+#else
+static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FULL;
+#endif
+
+static const char * const gds_strings[] = {
+	[GDS_MITIGATION_OFF]		= "Vulnerable",
+	[GDS_MITIGATION_UCODE_NEEDED]	= "Vulnerable: No microcode",
+	[GDS_MITIGATION_FORCE]		= "Mitigation: AVX disabled, no microcode",
+	[GDS_MITIGATION_FULL]		= "Mitigation: Microcode",
+	[GDS_MITIGATION_FULL_LOCKED]	= "Mitigation: Microcode (locked)",
+	[GDS_MITIGATION_HYPERVISOR]	= "Unknown: Dependent on hypervisor status",
+};
+
+bool gds_ucode_mitigated(void)
+{
+	return (gds_mitigation == GDS_MITIGATION_FULL ||
+		gds_mitigation == GDS_MITIGATION_FULL_LOCKED);
+}
+EXPORT_SYMBOL_GPL(gds_ucode_mitigated);
+
+void update_gds_msr(void)
+{
+	u64 mcu_ctrl_after;
+	u64 mcu_ctrl;
+
+	switch (gds_mitigation) {
+	case GDS_MITIGATION_OFF:
+		rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
+		mcu_ctrl |= GDS_MITG_DIS;
+		break;
+	case GDS_MITIGATION_FULL_LOCKED:
+		/*
+		 * The LOCKED state comes from the boot CPU. APs might not have
+		 * the same state. Make sure the mitigation is enabled on all
+		 * CPUs.
+		 */
+	case GDS_MITIGATION_FULL:
+		rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
+		mcu_ctrl &= ~GDS_MITG_DIS;
+		break;
+	case GDS_MITIGATION_FORCE:
+	case GDS_MITIGATION_UCODE_NEEDED:
+	case GDS_MITIGATION_HYPERVISOR:
+		return;
+	};
+
+	wrmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
+
+	/*
+	 * Check to make sure that the WRMSR value was not ignored. Writes to
+	 * GDS_MITG_DIS will be ignored if this processor is locked but the boot
+	 * processor was not.
+	 */
+	rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl_after);
+	WARN_ON_ONCE(mcu_ctrl != mcu_ctrl_after);
+}
+
+static void __init gds_select_mitigation(void)
+{
+	u64 mcu_ctrl;
+
+	if (!boot_cpu_has_bug(X86_BUG_GDS))
+		return;
+
+	if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) {
+		gds_mitigation = GDS_MITIGATION_HYPERVISOR;
+		goto out;
+	}
+
+	if (cpu_mitigations_off())
+		gds_mitigation = GDS_MITIGATION_OFF;
+	/* Will verify below that mitigation _can_ be disabled */
+
+	/* No microcode */
+	if (!(x86_read_arch_cap_msr() & ARCH_CAP_GDS_CTRL)) {
+		if (gds_mitigation == GDS_MITIGATION_FORCE) {
+			/*
+			 * This only needs to be done on the boot CPU so do it
+			 * here rather than in update_gds_msr()
+			 */
+			setup_clear_cpu_cap(X86_FEATURE_AVX);
+			pr_warn("Microcode update needed! Disabling AVX as mitigation.\n");
+		} else {
+			gds_mitigation = GDS_MITIGATION_UCODE_NEEDED;
+		}
+		goto out;
+	}
+
+	/* Microcode has mitigation, use it */
+	if (gds_mitigation == GDS_MITIGATION_FORCE)
+		gds_mitigation = GDS_MITIGATION_FULL;
+
+	rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
+	if (mcu_ctrl & GDS_MITG_LOCKED) {
+		if (gds_mitigation == GDS_MITIGATION_OFF)
+			pr_warn("Mitigation locked. Disable failed.\n");
+
+		/*
+		 * The mitigation is selected from the boot CPU. All other CPUs
+		 * _should_ have the same state. If the boot CPU isn't locked
+		 * but others are then update_gds_msr() will WARN() of the state
+		 * mismatch. If the boot CPU is locked update_gds_msr() will
+		 * ensure the other CPUs have the mitigation enabled.
+		 */
+		gds_mitigation = GDS_MITIGATION_FULL_LOCKED;
+	}
+
+	update_gds_msr();
+out:
+	pr_info("%s\n", gds_strings[gds_mitigation]);
+}
+
+static int __init gds_parse_cmdline(char *str)
+{
+	if (!str)
+		return -EINVAL;
+
+	if (!boot_cpu_has_bug(X86_BUG_GDS))
+		return 0;
+
+	if (!strcmp(str, "off"))
+		gds_mitigation = GDS_MITIGATION_OFF;
+	else if (!strcmp(str, "force"))
+		gds_mitigation = GDS_MITIGATION_FORCE;
+
+	return 0;
+}
+early_param("gather_data_sampling", gds_parse_cmdline);
+
+#undef pr_fmt
 #define pr_fmt(fmt)     "Spectre V1 : " fmt
 
 enum spectre_v1_mitigation {
@@ -867,6 +983,9 @@
 		setup_force_cpu_cap(X86_FEATURE_RETHUNK);
 		setup_force_cpu_cap(X86_FEATURE_UNRET);
 
+		if (IS_ENABLED(CONFIG_RETHUNK))
+			x86_return_thunk = retbleed_return_thunk;
+
 		if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
 		    boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
 			pr_err(RETBLEED_UNTRAIN_MSG);
@@ -1058,12 +1177,16 @@
 	return SPECTRE_V2_USER_CMD_AUTO;
 }
 
-static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode)
+static inline bool spectre_v2_in_eibrs_mode(enum spectre_v2_mitigation mode)
 {
-	return mode == SPECTRE_V2_IBRS ||
-	       mode == SPECTRE_V2_EIBRS ||
+	return mode == SPECTRE_V2_EIBRS ||
 	       mode == SPECTRE_V2_EIBRS_RETPOLINE ||
 	       mode == SPECTRE_V2_EIBRS_LFENCE;
+}
+
+static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode)
+{
+	return spectre_v2_in_eibrs_mode(mode) || mode == SPECTRE_V2_IBRS;
 }
 
 static void __init
@@ -1128,12 +1251,19 @@
 	}
 
 	/*
-	 * If no STIBP, IBRS or enhanced IBRS is enabled, or SMT impossible,
-	 * STIBP is not required.
+	 * If no STIBP, enhanced IBRS is enabled, or SMT impossible, STIBP
+	 * is not required.
+	 *
+	 * Enhanced IBRS also protects against cross-thread branch target
+	 * injection in user-mode as the IBRS bit remains always set which
+	 * implicitly enables cross-thread protections.  However, in legacy IBRS
+	 * mode, the IBRS bit is set only on kernel entry and cleared on return
+	 * to userspace. This disables the implicit cross-thread protection,
+	 * so allow for STIBP to be selected in that case.
 	 */
 	if (!boot_cpu_has(X86_FEATURE_STIBP) ||
 	    !smt_possible ||
-	    spectre_v2_in_ibrs_mode(spectre_v2_enabled))
+	    spectre_v2_in_eibrs_mode(spectre_v2_enabled))
 		return;
 
 	/*
@@ -1896,6 +2026,8 @@
 		if (ctrl == PR_SPEC_FORCE_DISABLE)
 			task_set_spec_ib_force_disable(task);
 		task_update_spec_tif(task);
+		if (task == current)
+			indirect_branch_prediction_barrier();
 		break;
 	default:
 		return -ERANGE;
@@ -2117,6 +2249,170 @@
 early_param("l1tf", l1tf_cmdline);
 
 #undef pr_fmt
+#define pr_fmt(fmt)	"Speculative Return Stack Overflow: " fmt
+
+enum srso_mitigation {
+	SRSO_MITIGATION_NONE,
+	SRSO_MITIGATION_MICROCODE,
+	SRSO_MITIGATION_SAFE_RET,
+	SRSO_MITIGATION_IBPB,
+	SRSO_MITIGATION_IBPB_ON_VMEXIT,
+};
+
+enum srso_mitigation_cmd {
+	SRSO_CMD_OFF,
+	SRSO_CMD_MICROCODE,
+	SRSO_CMD_SAFE_RET,
+	SRSO_CMD_IBPB,
+	SRSO_CMD_IBPB_ON_VMEXIT,
+};
+
+static const char * const srso_strings[] = {
+	[SRSO_MITIGATION_NONE]           = "Vulnerable",
+	[SRSO_MITIGATION_MICROCODE]      = "Mitigation: microcode",
+	[SRSO_MITIGATION_SAFE_RET]	 = "Mitigation: safe RET",
+	[SRSO_MITIGATION_IBPB]		 = "Mitigation: IBPB",
+	[SRSO_MITIGATION_IBPB_ON_VMEXIT] = "Mitigation: IBPB on VMEXIT only"
+};
+
+static enum srso_mitigation srso_mitigation __ro_after_init = SRSO_MITIGATION_NONE;
+static enum srso_mitigation_cmd srso_cmd __ro_after_init = SRSO_CMD_SAFE_RET;
+
+static int __init srso_parse_cmdline(char *str)
+{
+	if (!str)
+		return -EINVAL;
+
+	if (!strcmp(str, "off"))
+		srso_cmd = SRSO_CMD_OFF;
+	else if (!strcmp(str, "microcode"))
+		srso_cmd = SRSO_CMD_MICROCODE;
+	else if (!strcmp(str, "safe-ret"))
+		srso_cmd = SRSO_CMD_SAFE_RET;
+	else if (!strcmp(str, "ibpb"))
+		srso_cmd = SRSO_CMD_IBPB;
+	else if (!strcmp(str, "ibpb-vmexit"))
+		srso_cmd = SRSO_CMD_IBPB_ON_VMEXIT;
+	else
+		pr_err("Ignoring unknown SRSO option (%s).", str);
+
+	return 0;
+}
+early_param("spec_rstack_overflow", srso_parse_cmdline);
+
+#define SRSO_NOTICE "WARNING: See https://kernel.org/doc/html/latest/admin-guide/hw-vuln/srso.html for mitigation options."
+
+static void __init srso_select_mitigation(void)
+{
+	bool has_microcode;
+
+	if (!boot_cpu_has_bug(X86_BUG_SRSO) || cpu_mitigations_off())
+		goto pred_cmd;
+
+	/*
+	 * The first check is for the kernel running as a guest in order
+	 * for guests to verify whether IBPB is a viable mitigation.
+	 */
+	has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) || cpu_has_ibpb_brtype_microcode();
+	if (!has_microcode) {
+		pr_warn("IBPB-extending microcode not applied!\n");
+		pr_warn(SRSO_NOTICE);
+	} else {
+		/*
+		 * Enable the synthetic (even if in a real CPUID leaf)
+		 * flags for guests.
+		 */
+		setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE);
+
+		/*
+		 * Zen1/2 with SMT off aren't vulnerable after the right
+		 * IBPB microcode has been applied.
+		 */
+		if (boot_cpu_data.x86 < 0x19 && !cpu_smt_possible()) {
+			setup_force_cpu_cap(X86_FEATURE_SRSO_NO);
+			return;
+		}
+	}
+
+	if (retbleed_mitigation == RETBLEED_MITIGATION_IBPB) {
+		if (has_microcode) {
+			pr_err("Retbleed IBPB mitigation enabled, using same for SRSO\n");
+			srso_mitigation = SRSO_MITIGATION_IBPB;
+			goto pred_cmd;
+		}
+	}
+
+	switch (srso_cmd) {
+	case SRSO_CMD_OFF:
+		goto pred_cmd;
+
+	case SRSO_CMD_MICROCODE:
+		if (has_microcode) {
+			srso_mitigation = SRSO_MITIGATION_MICROCODE;
+			pr_warn(SRSO_NOTICE);
+		}
+		break;
+
+	case SRSO_CMD_SAFE_RET:
+		if (IS_ENABLED(CONFIG_CPU_SRSO)) {
+			/*
+			 * Enable the return thunk for generated code
+			 * like ftrace, static_call, etc.
+			 */
+			setup_force_cpu_cap(X86_FEATURE_RETHUNK);
+			setup_force_cpu_cap(X86_FEATURE_UNRET);
+
+			if (boot_cpu_data.x86 == 0x19) {
+				setup_force_cpu_cap(X86_FEATURE_SRSO_ALIAS);
+				x86_return_thunk = srso_alias_return_thunk;
+			} else {
+				setup_force_cpu_cap(X86_FEATURE_SRSO);
+				x86_return_thunk = srso_return_thunk;
+			}
+			srso_mitigation = SRSO_MITIGATION_SAFE_RET;
+		} else {
+			pr_err("WARNING: kernel not compiled with CPU_SRSO.\n");
+			goto pred_cmd;
+		}
+		break;
+
+	case SRSO_CMD_IBPB:
+		if (IS_ENABLED(CONFIG_CPU_IBPB_ENTRY)) {
+			if (has_microcode) {
+				setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB);
+				srso_mitigation = SRSO_MITIGATION_IBPB;
+			}
+		} else {
+			pr_err("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n");
+			goto pred_cmd;
+		}
+		break;
+
+	case SRSO_CMD_IBPB_ON_VMEXIT:
+		if (IS_ENABLED(CONFIG_CPU_SRSO)) {
+			if (!boot_cpu_has(X86_FEATURE_ENTRY_IBPB) && has_microcode) {
+				setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT);
+				srso_mitigation = SRSO_MITIGATION_IBPB_ON_VMEXIT;
+			}
+		} else {
+			pr_err("WARNING: kernel not compiled with CPU_SRSO.\n");
+			goto pred_cmd;
+                }
+		break;
+
+	default:
+		break;
+	}
+
+	pr_info("%s%s\n", srso_strings[srso_mitigation], (has_microcode ? "" : ", no microcode"));
+
+pred_cmd:
+	if ((boot_cpu_has(X86_FEATURE_SRSO_NO) || srso_cmd == SRSO_CMD_OFF) &&
+	     boot_cpu_has(X86_FEATURE_SBPB))
+		x86_pred_cmd = PRED_CMD_SBPB;
+}
+
+#undef pr_fmt
 #define pr_fmt(fmt) fmt
 
 #ifdef CONFIG_SYSFS
@@ -2225,7 +2521,7 @@
 
 static char *stibp_state(void)
 {
-	if (spectre_v2_in_ibrs_mode(spectre_v2_enabled))
+	if (spectre_v2_in_eibrs_mode(spectre_v2_enabled))
 		return "";
 
 	switch (spectre_v2_user_stibp) {
@@ -2314,6 +2610,21 @@
 	return sprintf(buf, "%s\n", retbleed_strings[retbleed_mitigation]);
 }
 
+static ssize_t gds_show_state(char *buf)
+{
+	return sysfs_emit(buf, "%s\n", gds_strings[gds_mitigation]);
+}
+
+static ssize_t srso_show_state(char *buf)
+{
+	if (boot_cpu_has(X86_FEATURE_SRSO_NO))
+		return sysfs_emit(buf, "Mitigation: SMT disabled\n");
+
+	return sysfs_emit(buf, "%s%s\n",
+			  srso_strings[srso_mitigation],
+			  boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) ? "" : ", no microcode");
+}
+
 static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr,
 			       char *buf, unsigned int bug)
 {
@@ -2362,6 +2673,12 @@
 
 	case X86_BUG_RETBLEED:
 		return retbleed_show_state(buf);
+
+	case X86_BUG_GDS:
+		return gds_show_state(buf);
+
+	case X86_BUG_SRSO:
+		return srso_show_state(buf);
 
 	default:
 		break;
@@ -2427,4 +2744,14 @@
 {
 	return cpu_show_common(dev, attr, buf, X86_BUG_RETBLEED);
 }
+
+ssize_t cpu_show_gds(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return cpu_show_common(dev, attr, buf, X86_BUG_GDS);
+}
+
+ssize_t cpu_show_spec_rstack_overflow(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return cpu_show_common(dev, attr, buf, X86_BUG_SRSO);
+}
 #endif
diff --git a/kernel/arch/x86/kernel/cpu/common.c b/kernel/arch/x86/kernel/cpu/common.c
index 5657324..4ecc607 100644
--- a/kernel/arch/x86/kernel/cpu/common.c
+++ b/kernel/arch/x86/kernel/cpu/common.c
@@ -18,11 +18,15 @@
 #include <linux/init.h>
 #include <linux/kprobes.h>
 #include <linux/kgdb.h>
+#include <linux/mem_encrypt.h>
 #include <linux/smp.h>
+#include <linux/cpu.h>
 #include <linux/io.h>
 #include <linux/syscore_ops.h>
 #include <linux/pgtable.h>
+#include <linux/utsname.h>
 
+#include <asm/alternative.h>
 #include <asm/cmdline.h>
 #include <asm/stackprotector.h>
 #include <asm/perf_event.h>
@@ -58,6 +62,7 @@
 #include <asm/intel-family.h>
 #include <asm/cpu_device_id.h>
 #include <asm/uv/uv.h>
+#include <asm/set_memory.h>
 
 #include "cpu.h"
 
@@ -467,8 +472,6 @@
 
 static __always_inline void setup_pku(struct cpuinfo_x86 *c)
 {
-	struct pkru_state *pk;
-
 	/* check the boot processor, plus compile options for PKU: */
 	if (!cpu_feature_enabled(X86_FEATURE_PKU))
 		return;
@@ -479,9 +482,6 @@
 		return;
 
 	cr4_set_bits(X86_CR4_PKE);
-	pk = get_xsave_addr(&init_fpstate.xsave, XFEATURE_PKRU);
-	if (pk)
-		pk->pkru = init_pkru_value;
 	/*
 	 * Seting X86_CR4_PKE will cause the X86_FEATURE_OSPKE
 	 * cpuid bit to be set.  We need to ensure that we
@@ -961,6 +961,12 @@
 	if (c->extended_cpuid_level >= 0x8000000a)
 		c->x86_capability[CPUID_8000_000A_EDX] = cpuid_edx(0x8000000a);
 
+	if (c->extended_cpuid_level >= 0x8000001f)
+		c->x86_capability[CPUID_8000_001F_EAX] = cpuid_eax(0x8000001f);
+
+	if (c->extended_cpuid_level >= 0x80000021)
+		c->x86_capability[CPUID_8000_0021_EAX] = cpuid_eax(0x80000021);
+
 	init_scattered_cpuid_features(c);
 	init_speculation_control(c);
 
@@ -1122,6 +1128,12 @@
 #define MMIO_SBDS	BIT(2)
 /* CPU is affected by RETbleed, speculating where you would not expect it */
 #define RETBLEED	BIT(3)
+/* CPU is affected by SMT (cross-thread) return predictions */
+#define SMT_RSB		BIT(4)
+/* CPU is affected by SRSO */
+#define SRSO		BIT(5)
+/* CPU is affected by GDS */
+#define GDS		BIT(6)
 
 static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
 	VULNBL_INTEL_STEPPINGS(IVYBRIDGE,	X86_STEPPING_ANY,		SRBDS),
@@ -1133,28 +1145,31 @@
 	VULNBL_INTEL_STEPPINGS(BROADWELL_G,	X86_STEPPING_ANY,		SRBDS),
 	VULNBL_INTEL_STEPPINGS(BROADWELL_X,	X86_STEPPING_ANY,		MMIO),
 	VULNBL_INTEL_STEPPINGS(BROADWELL,	X86_STEPPING_ANY,		SRBDS),
-	VULNBL_INTEL_STEPPINGS(SKYLAKE_L,	X86_STEPPING_ANY,		SRBDS | MMIO | RETBLEED),
-	VULNBL_INTEL_STEPPINGS(SKYLAKE_X,	X86_STEPPING_ANY,		MMIO | RETBLEED),
-	VULNBL_INTEL_STEPPINGS(SKYLAKE,		X86_STEPPING_ANY,		SRBDS | MMIO | RETBLEED),
-	VULNBL_INTEL_STEPPINGS(KABYLAKE_L,	X86_STEPPING_ANY,		SRBDS | MMIO | RETBLEED),
-	VULNBL_INTEL_STEPPINGS(KABYLAKE,	X86_STEPPING_ANY,		SRBDS | MMIO | RETBLEED),
+	VULNBL_INTEL_STEPPINGS(SKYLAKE_X,	X86_STEPPING_ANY,		MMIO | RETBLEED | GDS),
+	VULNBL_INTEL_STEPPINGS(SKYLAKE_L,	X86_STEPPING_ANY,		MMIO | RETBLEED | GDS | SRBDS),
+	VULNBL_INTEL_STEPPINGS(SKYLAKE,		X86_STEPPING_ANY,		MMIO | RETBLEED | GDS | SRBDS),
+	VULNBL_INTEL_STEPPINGS(KABYLAKE_L,	X86_STEPPING_ANY,		MMIO | RETBLEED | GDS | SRBDS),
+	VULNBL_INTEL_STEPPINGS(KABYLAKE,	X86_STEPPING_ANY,		MMIO | RETBLEED | GDS | SRBDS),
 	VULNBL_INTEL_STEPPINGS(CANNONLAKE_L,	X86_STEPPING_ANY,		RETBLEED),
-	VULNBL_INTEL_STEPPINGS(ICELAKE_L,	X86_STEPPING_ANY,		MMIO | MMIO_SBDS | RETBLEED),
-	VULNBL_INTEL_STEPPINGS(ICELAKE_D,	X86_STEPPING_ANY,		MMIO),
-	VULNBL_INTEL_STEPPINGS(ICELAKE_X,	X86_STEPPING_ANY,		MMIO),
-	VULNBL_INTEL_STEPPINGS(COMETLAKE,	X86_STEPPING_ANY,		MMIO | MMIO_SBDS | RETBLEED),
+	VULNBL_INTEL_STEPPINGS(ICELAKE_L,	X86_STEPPING_ANY,		MMIO | MMIO_SBDS | RETBLEED | GDS),
+	VULNBL_INTEL_STEPPINGS(ICELAKE_D,	X86_STEPPING_ANY,		MMIO | GDS),
+	VULNBL_INTEL_STEPPINGS(ICELAKE_X,	X86_STEPPING_ANY,		MMIO | GDS),
+	VULNBL_INTEL_STEPPINGS(COMETLAKE,	X86_STEPPING_ANY,		MMIO | MMIO_SBDS | RETBLEED | GDS),
 	VULNBL_INTEL_STEPPINGS(COMETLAKE_L,	X86_STEPPINGS(0x0, 0x0),	MMIO | RETBLEED),
-	VULNBL_INTEL_STEPPINGS(COMETLAKE_L,	X86_STEPPING_ANY,		MMIO | MMIO_SBDS | RETBLEED),
+	VULNBL_INTEL_STEPPINGS(COMETLAKE_L,	X86_STEPPING_ANY,		MMIO | MMIO_SBDS | RETBLEED | GDS),
+	VULNBL_INTEL_STEPPINGS(TIGERLAKE_L,	X86_STEPPING_ANY,		GDS),
+	VULNBL_INTEL_STEPPINGS(TIGERLAKE,	X86_STEPPING_ANY,		GDS),
 	VULNBL_INTEL_STEPPINGS(LAKEFIELD,	X86_STEPPING_ANY,		MMIO | MMIO_SBDS | RETBLEED),
-	VULNBL_INTEL_STEPPINGS(ROCKETLAKE,	X86_STEPPING_ANY,		MMIO | RETBLEED),
+	VULNBL_INTEL_STEPPINGS(ROCKETLAKE,	X86_STEPPING_ANY,		MMIO | RETBLEED | GDS),
 	VULNBL_INTEL_STEPPINGS(ATOM_TREMONT,	X86_STEPPING_ANY,		MMIO | MMIO_SBDS),
 	VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D,	X86_STEPPING_ANY,		MMIO),
 	VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L,	X86_STEPPING_ANY,		MMIO | MMIO_SBDS),
 
 	VULNBL_AMD(0x15, RETBLEED),
 	VULNBL_AMD(0x16, RETBLEED),
-	VULNBL_AMD(0x17, RETBLEED),
+	VULNBL_AMD(0x17, RETBLEED | SRSO),
 	VULNBL_HYGON(0x18, RETBLEED),
+	VULNBL_AMD(0x19, SRSO),
 	{}
 };
 
@@ -1271,6 +1286,21 @@
 	    !cpu_matches(cpu_vuln_whitelist, NO_EIBRS_PBRSB) &&
 	    !(ia32_cap & ARCH_CAP_PBRSB_NO))
 		setup_force_cpu_bug(X86_BUG_EIBRS_PBRSB);
+
+	/*
+	 * Check if CPU is vulnerable to GDS. If running in a virtual machine on
+	 * an affected processor, the VMM may have disabled the use of GATHER by
+	 * disabling AVX2. The only way to do this in HW is to clear XCR0[2],
+	 * which means that AVX will be disabled.
+	 */
+	if (cpu_matches(cpu_vuln_blacklist, GDS) && !(ia32_cap & ARCH_CAP_GDS_NO) &&
+	    boot_cpu_has(X86_FEATURE_AVX))
+		setup_force_cpu_bug(X86_BUG_GDS);
+
+	if (!cpu_has(c, X86_FEATURE_SRSO_NO)) {
+		if (cpu_matches(cpu_vuln_blacklist, SRSO))
+			setup_force_cpu_bug(X86_BUG_SRSO);
+	}
 
 	if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
 		return;
@@ -1412,8 +1442,6 @@
 	cpu_set_bug_bits(c);
 
 	cpu_set_core_cap_bits(c);
-
-	fpu__init_system(c);
 
 #ifdef CONFIG_X86_32
 	/*
@@ -1792,6 +1820,8 @@
 	validate_apic_and_package_id(c);
 	x86_spec_ctrl_setup_ap();
 	update_srbds_msr();
+	if (boot_cpu_has_bug(X86_BUG_GDS))
+		update_gds_msr();
 }
 
 static __init int setup_noclflush(char *arg)
@@ -2048,13 +2078,12 @@
 
 /*
  * cpu_init() initializes state that is per-CPU. Some data is already
- * initialized (naturally) in the bootstrap process, such as the GDT
- * and IDT. We reload them nevertheless, this function acts as a
- * 'CPU state barrier', nothing should get across.
+ * initialized (naturally) in the bootstrap process, such as the GDT.  We
+ * reload it nevertheless, this function acts as a 'CPU state barrier',
+ * nothing should get across.
  */
 void cpu_init(void)
 {
-	struct tss_struct *tss = this_cpu_ptr(&cpu_tss_rw);
 	struct task_struct *cur = current;
 	int cpu = raw_smp_processor_id();
 
@@ -2067,8 +2096,6 @@
 	    early_cpu_to_node(cpu) != NUMA_NO_NODE)
 		set_numa_node(early_cpu_to_node(cpu));
 #endif
-	setup_getcpu(cpu);
-
 	pr_debug("Initializing CPU#%d\n", cpu);
 
 	if (IS_ENABLED(CONFIG_X86_64) || cpu_feature_enabled(X86_FEATURE_VME) ||
@@ -2080,7 +2107,6 @@
 	 * and set up the GDT descriptor:
 	 */
 	switch_to_new_gdt(cpu);
-	load_current_idt();
 
 	if (IS_ENABLED(CONFIG_X86_64)) {
 		loadsegment(fs, 0);
@@ -2100,12 +2126,6 @@
 	initialize_tlbstate_and_flush();
 	enter_lazy_tlb(&init_mm, cur);
 
-	/* Initialize the TSS. */
-	tss_setup_ist(tss);
-	tss_setup_io_bitmap(tss);
-	set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss);
-
-	load_TR_desc();
 	/*
 	 * sp0 points to the entry trampoline stack regardless of what task
 	 * is running.
@@ -2119,43 +2139,73 @@
 
 	doublefault_init_cpu_tss();
 
-	fpu__init_cpu();
-
 	if (is_uv_system())
 		uv_cpu_init();
 
 	load_fixmap_gdt(cpu);
 }
 
-/*
+#ifdef CONFIG_SMP
+void cpu_init_secondary(void)
+{
+	/*
+	 * Relies on the BP having set-up the IDT tables, which are loaded
+	 * on this CPU in cpu_init_exception_handling().
+	 */
+	cpu_init_exception_handling();
+	cpu_init();
+	fpu__init_cpu();
+}
+#endif
+
+#ifdef CONFIG_MICROCODE_LATE_LOADING
+/**
+ * store_cpu_caps() - Store a snapshot of CPU capabilities
+ * @curr_info: Pointer where to store it
+ *
+ * Returns: None
+ */
+void store_cpu_caps(struct cpuinfo_x86 *curr_info)
+{
+	/* Reload CPUID max function as it might've changed. */
+	curr_info->cpuid_level = cpuid_eax(0);
+
+	/* Copy all capability leafs and pick up the synthetic ones. */
+	memcpy(&curr_info->x86_capability, &boot_cpu_data.x86_capability,
+	       sizeof(curr_info->x86_capability));
+
+	/* Get the hardware CPUID leafs */
+	get_cpu_cap(curr_info);
+}
+
+/**
+ * microcode_check() - Check if any CPU capabilities changed after an update.
+ * @prev_info:	CPU capabilities stored before an update.
+ *
  * The microcode loader calls this upon late microcode load to recheck features,
  * only when microcode has been updated. Caller holds microcode_mutex and CPU
  * hotplug lock.
+ *
+ * Return: None
  */
-void microcode_check(void)
+void microcode_check(struct cpuinfo_x86 *prev_info)
 {
-	struct cpuinfo_x86 info;
+	struct cpuinfo_x86 curr_info;
 
 	perf_check_microcode();
 
-	/* Reload CPUID max function as it might've changed. */
-	info.cpuid_level = cpuid_eax(0);
+	amd_check_microcode();
 
-	/*
-	 * Copy all capability leafs to pick up the synthetic ones so that
-	 * memcmp() below doesn't fail on that. The ones coming from CPUID will
-	 * get overwritten in get_cpu_cap().
-	 */
-	memcpy(&info.x86_capability, &boot_cpu_data.x86_capability, sizeof(info.x86_capability));
+	store_cpu_caps(&curr_info);
 
-	get_cpu_cap(&info);
-
-	if (!memcmp(&info.x86_capability, &boot_cpu_data.x86_capability, sizeof(info.x86_capability)))
+	if (!memcmp(&prev_info->x86_capability, &curr_info.x86_capability,
+		    sizeof(prev_info->x86_capability)))
 		return;
 
 	pr_warn("x86/CPU: CPU features have changed after loading microcode, but might not take effect.\n");
 	pr_warn("x86/CPU: Please consider either early loading through initrd/built-in or a potential BIOS update.\n");
 }
+#endif
 
 /*
  * Invoked from core CPU hotplug code after hotplug operations
@@ -2167,3 +2217,69 @@
 	/* Check whether IPI broadcasting can be enabled */
 	apic_smt_update();
 }
+
+void __init arch_cpu_finalize_init(void)
+{
+	identify_boot_cpu();
+
+	/*
+	 * identify_boot_cpu() initialized SMT support information, let the
+	 * core code know.
+	 */
+	cpu_smt_check_topology();
+
+	if (!IS_ENABLED(CONFIG_SMP)) {
+		pr_info("CPU: ");
+		print_cpu_info(&boot_cpu_data);
+	}
+
+	cpu_select_mitigations();
+
+	arch_smt_update();
+
+	if (IS_ENABLED(CONFIG_X86_32)) {
+		/*
+		 * Check whether this is a real i386 which is not longer
+		 * supported and fixup the utsname.
+		 */
+		if (boot_cpu_data.x86 < 4)
+			panic("Kernel requires i486+ for 'invlpg' and other features");
+
+		init_utsname()->machine[1] =
+			'0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86);
+	}
+
+	/*
+	 * Must be before alternatives because it might set or clear
+	 * feature bits.
+	 */
+	fpu__init_system();
+	fpu__init_cpu();
+
+	alternative_instructions();
+
+	if (IS_ENABLED(CONFIG_X86_64)) {
+		/*
+		 * Make sure the first 2MB area is not mapped by huge pages
+		 * There are typically fixed size MTRRs in there and overlapping
+		 * MTRRs into large pages causes slow downs.
+		 *
+		 * Right now we don't do that with gbpages because there seems
+		 * very little benefit for that case.
+		 */
+		if (!direct_gbpages)
+			set_memory_4k((unsigned long)__va(0), 1);
+	} else {
+		fpu__init_check_bugs();
+	}
+
+	/*
+	 * This needs to be called before any devices perform DMA
+	 * operations that might use the SWIOTLB bounce buffers. It will
+	 * mark the bounce buffers as decrypted so that their usage will
+	 * not cause "plain-text" data to be decrypted when accessed. It
+	 * must be called after late_time_init() so that Hyper-V x86/x64
+	 * hypercalls work when the SWIOTLB bounce buffers are decrypted.
+	 */
+	mem_encrypt_init();
+}
diff --git a/kernel/arch/x86/kernel/cpu/cpu.h b/kernel/arch/x86/kernel/cpu/cpu.h
index 91df90a..66e1938 100644
--- a/kernel/arch/x86/kernel/cpu/cpu.h
+++ b/kernel/arch/x86/kernel/cpu/cpu.h
@@ -78,9 +78,11 @@
 extern void check_null_seg_clears_base(struct cpuinfo_x86 *c);
 
 unsigned int aperfmperf_get_khz(int cpu);
+void cpu_select_mitigations(void);
 
 extern void x86_spec_ctrl_setup_ap(void);
 extern void update_srbds_msr(void);
+extern void update_gds_msr(void);
 
 extern u64 x86_read_arch_cap_msr(void);
 
diff --git a/kernel/arch/x86/kernel/cpu/mce/amd.c b/kernel/arch/x86/kernel/cpu/mce/amd.c
index 09f7c65..cd8db6b 100644
--- a/kernel/arch/x86/kernel/cpu/mce/amd.c
+++ b/kernel/arch/x86/kernel/cpu/mce/amd.c
@@ -197,10 +197,10 @@
  * A list of the banks enabled on each logical CPU. Controls which respective
  * descriptors to initialize later in mce_threshold_create_device().
  */
-static DEFINE_PER_CPU(unsigned int, bank_map);
+static DEFINE_PER_CPU(u64, bank_map);
 
 /* Map of banks that have more than MCA_MISC0 available. */
-static DEFINE_PER_CPU(u32, smca_misc_banks_map);
+static DEFINE_PER_CPU(u64, smca_misc_banks_map);
 
 static void amd_threshold_interrupt(void);
 static void amd_deferred_error_interrupt(void);
@@ -229,7 +229,7 @@
 		return;
 
 	if (low & MASK_BLKPTR_LO)
-		per_cpu(smca_misc_banks_map, cpu) |= BIT(bank);
+		per_cpu(smca_misc_banks_map, cpu) |= BIT_ULL(bank);
 
 }
 
@@ -492,7 +492,7 @@
 	if (!block)
 		return MSR_AMD64_SMCA_MCx_MISC(bank);
 
-	if (!(per_cpu(smca_misc_banks_map, cpu) & BIT(bank)))
+	if (!(per_cpu(smca_misc_banks_map, cpu) & BIT_ULL(bank)))
 		return 0;
 
 	return MSR_AMD64_SMCA_MCx_MISCy(bank, block - 1);
@@ -513,7 +513,7 @@
 	/* Fall back to method we used for older processors: */
 	switch (block) {
 	case 0:
-		addr = msr_ops.misc(bank);
+		addr = mca_msr_reg(bank, MCA_MISC);
 		break;
 	case 1:
 		offset = ((low & MASK_BLKPTR_LO) >> 21);
@@ -536,7 +536,7 @@
 	int new;
 
 	if (!block)
-		per_cpu(bank_map, cpu) |= (1 << bank);
+		per_cpu(bank_map, cpu) |= BIT_ULL(bank);
 
 	memset(&b, 0, sizeof(b));
 	b.cpu			= cpu;
@@ -952,6 +952,24 @@
 	return status & MCI_STATUS_DEFERRED;
 }
 
+static bool _log_error_deferred(unsigned int bank, u32 misc)
+{
+	if (!_log_error_bank(bank, mca_msr_reg(bank, MCA_STATUS),
+			     mca_msr_reg(bank, MCA_ADDR), misc))
+		return false;
+
+	/*
+	 * Non-SMCA systems don't have MCA_DESTAT/MCA_DEADDR registers.
+	 * Return true here to avoid accessing these registers.
+	 */
+	if (!mce_flags.smca)
+		return true;
+
+	/* Clear MCA_DESTAT if the deferred error was logged from MCA_STATUS. */
+	wrmsrl(MSR_AMD64_SMCA_MCx_DESTAT(bank), 0);
+	return true;
+}
+
 /*
  * We have three scenarios for checking for Deferred errors:
  *
@@ -963,19 +981,8 @@
  */
 static void log_error_deferred(unsigned int bank)
 {
-	bool defrd;
-
-	defrd = _log_error_bank(bank, msr_ops.status(bank),
-					msr_ops.addr(bank), 0);
-
-	if (!mce_flags.smca)
+	if (_log_error_deferred(bank, 0))
 		return;
-
-	/* Clear MCA_DESTAT if we logged the deferred error from MCA_STATUS. */
-	if (defrd) {
-		wrmsrl(MSR_AMD64_SMCA_MCx_DESTAT(bank), 0);
-		return;
-	}
 
 	/*
 	 * Only deferred errors are logged in MCA_DE{STAT,ADDR} so just check
@@ -996,7 +1003,7 @@
 
 static void log_error_thresholding(unsigned int bank, u64 misc)
 {
-	_log_error_bank(bank, msr_ops.status(bank), msr_ops.addr(bank), misc);
+	_log_error_deferred(bank, misc);
 }
 
 static void log_and_reset_block(struct threshold_block *block)
@@ -1041,7 +1048,7 @@
 		return;
 
 	for (bank = 0; bank < this_cpu_read(mce_num_banks); ++bank) {
-		if (!(per_cpu(bank_map, cpu) & (1 << bank)))
+		if (!(per_cpu(bank_map, cpu) & BIT_ULL(bank)))
 			continue;
 
 		first_block = bp[bank]->blocks;
@@ -1384,7 +1391,7 @@
 		}
 	}
 
-	err = allocate_threshold_blocks(cpu, b, bank, 0, msr_ops.misc(bank));
+	err = allocate_threshold_blocks(cpu, b, bank, 0, mca_msr_reg(bank, MCA_MISC));
 	if (err)
 		goto out_kobj;
 
@@ -1518,7 +1525,7 @@
 		return -ENOMEM;
 
 	for (bank = 0; bank < numbanks; ++bank) {
-		if (!(this_cpu_read(bank_map) & (1 << bank)))
+		if (!(this_cpu_read(bank_map) & BIT_ULL(bank)))
 			continue;
 		err = threshold_create_bank(bp, cpu, bank);
 		if (err) {
diff --git a/kernel/arch/x86/kernel/cpu/mce/core.c b/kernel/arch/x86/kernel/cpu/mce/core.c
index 5cf1a02..0b7c813 100644
--- a/kernel/arch/x86/kernel/cpu/mce/core.c
+++ b/kernel/arch/x86/kernel/cpu/mce/core.c
@@ -176,52 +176,26 @@
 }
 EXPORT_SYMBOL_GPL(mce_unregister_decode_chain);
 
-static inline u32 ctl_reg(int bank)
+u32 mca_msr_reg(int bank, enum mca_msr reg)
 {
-	return MSR_IA32_MCx_CTL(bank);
-}
+	if (mce_flags.smca) {
+		switch (reg) {
+		case MCA_CTL:	 return MSR_AMD64_SMCA_MCx_CTL(bank);
+		case MCA_ADDR:	 return MSR_AMD64_SMCA_MCx_ADDR(bank);
+		case MCA_MISC:	 return MSR_AMD64_SMCA_MCx_MISC(bank);
+		case MCA_STATUS: return MSR_AMD64_SMCA_MCx_STATUS(bank);
+		}
+	}
 
-static inline u32 status_reg(int bank)
-{
-	return MSR_IA32_MCx_STATUS(bank);
-}
+	switch (reg) {
+	case MCA_CTL:	 return MSR_IA32_MCx_CTL(bank);
+	case MCA_ADDR:	 return MSR_IA32_MCx_ADDR(bank);
+	case MCA_MISC:	 return MSR_IA32_MCx_MISC(bank);
+	case MCA_STATUS: return MSR_IA32_MCx_STATUS(bank);
+	}
 
-static inline u32 addr_reg(int bank)
-{
-	return MSR_IA32_MCx_ADDR(bank);
+	return 0;
 }
-
-static inline u32 misc_reg(int bank)
-{
-	return MSR_IA32_MCx_MISC(bank);
-}
-
-static inline u32 smca_ctl_reg(int bank)
-{
-	return MSR_AMD64_SMCA_MCx_CTL(bank);
-}
-
-static inline u32 smca_status_reg(int bank)
-{
-	return MSR_AMD64_SMCA_MCx_STATUS(bank);
-}
-
-static inline u32 smca_addr_reg(int bank)
-{
-	return MSR_AMD64_SMCA_MCx_ADDR(bank);
-}
-
-static inline u32 smca_misc_reg(int bank)
-{
-	return MSR_AMD64_SMCA_MCx_MISC(bank);
-}
-
-struct mca_msr_regs msr_ops = {
-	.ctl	= ctl_reg,
-	.status	= status_reg,
-	.addr	= addr_reg,
-	.misc	= misc_reg
-};
 
 static void __print_mce(struct mce *m)
 {
@@ -371,11 +345,11 @@
 
 	if (msr == mca_cfg.rip_msr)
 		return offsetof(struct mce, ip);
-	if (msr == msr_ops.status(bank))
+	if (msr == mca_msr_reg(bank, MCA_STATUS))
 		return offsetof(struct mce, status);
-	if (msr == msr_ops.addr(bank))
+	if (msr == mca_msr_reg(bank, MCA_ADDR))
 		return offsetof(struct mce, addr);
-	if (msr == msr_ops.misc(bank))
+	if (msr == mca_msr_reg(bank, MCA_MISC))
 		return offsetof(struct mce, misc);
 	if (msr == MSR_IA32_MCG_STATUS)
 		return offsetof(struct mce, mcgstatus);
@@ -694,10 +668,10 @@
 static noinstr void mce_read_aux(struct mce *m, int i)
 {
 	if (m->status & MCI_STATUS_MISCV)
-		m->misc = mce_rdmsrl(msr_ops.misc(i));
+		m->misc = mce_rdmsrl(mca_msr_reg(i, MCA_MISC));
 
 	if (m->status & MCI_STATUS_ADDRV) {
-		m->addr = mce_rdmsrl(msr_ops.addr(i));
+		m->addr = mce_rdmsrl(mca_msr_reg(i, MCA_ADDR));
 
 		/*
 		 * Mask the reported address by the reported granularity.
@@ -767,7 +741,7 @@
 		m.bank = i;
 
 		barrier();
-		m.status = mce_rdmsrl(msr_ops.status(i));
+		m.status = mce_rdmsrl(mca_msr_reg(i, MCA_STATUS));
 
 		/* If this entry is not valid, ignore it */
 		if (!(m.status & MCI_STATUS_VAL))
@@ -835,7 +809,7 @@
 		/*
 		 * Clear state for this bank.
 		 */
-		mce_wrmsrl(msr_ops.status(i), 0);
+		mce_wrmsrl(mca_msr_reg(i, MCA_STATUS), 0);
 	}
 
 	/*
@@ -860,7 +834,7 @@
 	int i;
 
 	for (i = 0; i < this_cpu_read(mce_num_banks); i++) {
-		m->status = mce_rdmsrl(msr_ops.status(i));
+		m->status = mce_rdmsrl(mca_msr_reg(i, MCA_STATUS));
 		if (!(m->status & MCI_STATUS_VAL))
 			continue;
 
@@ -1149,7 +1123,7 @@
 
 	for (i = 0; i < this_cpu_read(mce_num_banks); i++) {
 		if (test_bit(i, toclear))
-			mce_wrmsrl(msr_ops.status(i), 0);
+			mce_wrmsrl(mca_msr_reg(i, MCA_STATUS), 0);
 	}
 }
 
@@ -1208,7 +1182,7 @@
 		m->addr = 0;
 		m->bank = i;
 
-		m->status = mce_rdmsrl(msr_ops.status(i));
+		m->status = mce_rdmsrl(mca_msr_reg(i, MCA_STATUS));
 		if (!(m->status & MCI_STATUS_VAL))
 			continue;
 
@@ -1704,8 +1678,8 @@
 
 		if (!b->init)
 			continue;
-		wrmsrl(msr_ops.ctl(i), b->ctl);
-		wrmsrl(msr_ops.status(i), 0);
+		wrmsrl(mca_msr_reg(i, MCA_CTL), b->ctl);
+		wrmsrl(mca_msr_reg(i, MCA_STATUS), 0);
 	}
 }
 
@@ -1731,7 +1705,7 @@
 		if (!b->init)
 			continue;
 
-		rdmsrl(msr_ops.ctl(i), msrval);
+		rdmsrl(mca_msr_reg(i, MCA_CTL), msrval);
 		b->init = !!msrval;
 	}
 }
@@ -1890,13 +1864,6 @@
 		mce_flags.succor	 = !!cpu_has(c, X86_FEATURE_SUCCOR);
 		mce_flags.smca		 = !!cpu_has(c, X86_FEATURE_SMCA);
 		mce_flags.amd_threshold	 = 1;
-
-		if (mce_flags.smca) {
-			msr_ops.ctl	= smca_ctl_reg;
-			msr_ops.status	= smca_status_reg;
-			msr_ops.addr	= smca_addr_reg;
-			msr_ops.misc	= smca_misc_reg;
-		}
 	}
 }
 
@@ -2272,7 +2239,7 @@
 		struct mce_bank *b = &mce_banks[i];
 
 		if (b->init)
-			wrmsrl(msr_ops.ctl(i), 0);
+			wrmsrl(mca_msr_reg(i, MCA_CTL), 0);
 	}
 	return;
 }
@@ -2342,6 +2309,7 @@
 {
 	mce_timer_delete_all();
 	on_each_cpu(mce_cpu_restart, NULL, 1);
+	mce_schedule_work();
 }
 
 /* Toggle features for corrected errors */
@@ -2624,7 +2592,7 @@
 		struct mce_bank *b = &mce_banks[i];
 
 		if (b->init)
-			wrmsrl(msr_ops.ctl(i), b->ctl);
+			wrmsrl(mca_msr_reg(i, MCA_CTL), b->ctl);
 	}
 }
 
diff --git a/kernel/arch/x86/kernel/cpu/mce/internal.h b/kernel/arch/x86/kernel/cpu/mce/internal.h
index 88dcc79..3a485c0 100644
--- a/kernel/arch/x86/kernel/cpu/mce/internal.h
+++ b/kernel/arch/x86/kernel/cpu/mce/internal.h
@@ -168,14 +168,14 @@
 
 extern struct mce_vendor_flags mce_flags;
 
-struct mca_msr_regs {
-	u32 (*ctl)	(int bank);
-	u32 (*status)	(int bank);
-	u32 (*addr)	(int bank);
-	u32 (*misc)	(int bank);
+enum mca_msr {
+	MCA_CTL,
+	MCA_STATUS,
+	MCA_ADDR,
+	MCA_MISC,
 };
 
-extern struct mca_msr_regs msr_ops;
+u32 mca_msr_reg(int bank, enum mca_msr reg);
 
 /* Decide whether to add MCE record to MCE event pool or filter it out. */
 extern bool filter_mce(struct mce *m);
diff --git a/kernel/arch/x86/kernel/cpu/microcode/amd.c b/kernel/arch/x86/kernel/cpu/microcode/amd.c
index 234a96f..936085d 100644
--- a/kernel/arch/x86/kernel/cpu/microcode/amd.c
+++ b/kernel/arch/x86/kernel/cpu/microcode/amd.c
@@ -55,7 +55,9 @@
 };
 
 static u32 ucode_new_rev;
-static u8 amd_ucode_patch[PATCH_MAX_SIZE];
+
+/* One blob per node. */
+static u8 amd_ucode_patch[MAX_NUMNODES][PATCH_MAX_SIZE];
 
 /*
  * Microcode patch container file is prepended to the initrd in cpio
@@ -429,7 +431,7 @@
 	patch	= (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch);
 #else
 	new_rev = &ucode_new_rev;
-	patch	= &amd_ucode_patch;
+	patch	= &amd_ucode_patch[0];
 #endif
 
 	desc.cpuid_1_eax = cpuid_1_eax;
@@ -548,8 +550,7 @@
 	apply_microcode_early_amd(cpuid_1_eax, cp.data, cp.size, false);
 }
 
-static enum ucode_state
-load_microcode_amd(bool save, u8 family, const u8 *data, size_t size);
+static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size);
 
 int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
 {
@@ -567,19 +568,19 @@
 	if (!desc.mc)
 		return -EINVAL;
 
-	ret = load_microcode_amd(true, x86_family(cpuid_1_eax), desc.data, desc.size);
+	ret = load_microcode_amd(x86_family(cpuid_1_eax), desc.data, desc.size);
 	if (ret > UCODE_UPDATED)
 		return -EINVAL;
 
 	return 0;
 }
 
-void reload_ucode_amd(void)
+void reload_ucode_amd(unsigned int cpu)
 {
-	struct microcode_amd *mc;
 	u32 rev, dummy __always_unused;
+	struct microcode_amd *mc;
 
-	mc = (struct microcode_amd *)amd_ucode_patch;
+	mc = (struct microcode_amd *)amd_ucode_patch[cpu_to_node(cpu)];
 
 	rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
 
@@ -699,7 +700,7 @@
 	rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
 
 	/* need to apply patch? */
-	if (rev >= mc_amd->hdr.patch_id) {
+	if (rev > mc_amd->hdr.patch_id) {
 		ret = UCODE_OK;
 		goto out;
 	}
@@ -845,9 +846,10 @@
 	return UCODE_OK;
 }
 
-static enum ucode_state
-load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)
+static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size)
 {
+	struct cpuinfo_x86 *c;
+	unsigned int nid, cpu;
 	struct ucode_patch *p;
 	enum ucode_state ret;
 
@@ -860,22 +862,22 @@
 		return ret;
 	}
 
-	p = find_patch(0);
-	if (!p) {
-		return ret;
-	} else {
-		if (boot_cpu_data.microcode >= p->patch_id)
-			return ret;
+	for_each_node(nid) {
+		cpu = cpumask_first(cpumask_of_node(nid));
+		c = &cpu_data(cpu);
+
+		p = find_patch(cpu);
+		if (!p)
+			continue;
+
+		if (c->microcode >= p->patch_id)
+			continue;
 
 		ret = UCODE_NEW;
+
+		memset(&amd_ucode_patch[nid], 0, PATCH_MAX_SIZE);
+		memcpy(&amd_ucode_patch[nid], p->data, min_t(u32, p->size, PATCH_MAX_SIZE));
 	}
-
-	/* save BSP's matching patch for early load */
-	if (!save)
-		return ret;
-
-	memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
-	memcpy(amd_ucode_patch, p->data, min_t(u32, p->size, PATCH_MAX_SIZE));
 
 	return ret;
 }
@@ -901,12 +903,11 @@
 {
 	char fw_name[36] = "amd-ucode/microcode_amd.bin";
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
-	bool bsp = c->cpu_index == boot_cpu_data.cpu_index;
 	enum ucode_state ret = UCODE_NFOUND;
 	const struct firmware *fw;
 
 	/* reload ucode container only on the boot cpu */
-	if (!refresh_fw || !bsp)
+	if (!refresh_fw)
 		return UCODE_OK;
 
 	if (c->x86 >= 0x15)
@@ -921,7 +922,7 @@
 	if (!verify_container(fw->data, fw->size, false))
 		goto fw_release;
 
-	ret = load_microcode_amd(bsp, c->x86, fw->data, fw->size);
+	ret = load_microcode_amd(c->x86, fw->data, fw->size);
 
  fw_release:
 	release_firmware(fw);
diff --git a/kernel/arch/x86/kernel/cpu/microcode/core.c b/kernel/arch/x86/kernel/cpu/microcode/core.c
index 0b1732b..24254d1 100644
--- a/kernel/arch/x86/kernel/cpu/microcode/core.c
+++ b/kernel/arch/x86/kernel/cpu/microcode/core.c
@@ -55,7 +55,7 @@
  * All non cpu-hotplug-callback call sites use:
  *
  * - microcode_mutex to synchronize with each other;
- * - get/put_online_cpus() to synchronize with
+ * - cpus_read_lock/unlock() to synchronize with
  *   the cpu-hotplug-callback call sites.
  *
  * We guarantee that only a single cpu is being
@@ -315,7 +315,7 @@
 #endif
 }
 
-void reload_early_microcode(void)
+void reload_early_microcode(unsigned int cpu)
 {
 	int vendor, family;
 
@@ -329,7 +329,7 @@
 		break;
 	case X86_VENDOR_AMD:
 		if (family >= 0x10)
-			reload_ucode_amd();
+			reload_ucode_amd(cpu);
 		break;
 	default:
 		break;
@@ -390,101 +390,10 @@
 	return ret;
 }
 
-#ifdef CONFIG_MICROCODE_OLD_INTERFACE
-static int do_microcode_update(const void __user *buf, size_t size)
-{
-	int error = 0;
-	int cpu;
-
-	for_each_online_cpu(cpu) {
-		struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
-		enum ucode_state ustate;
-
-		if (!uci->valid)
-			continue;
-
-		ustate = microcode_ops->request_microcode_user(cpu, buf, size);
-		if (ustate == UCODE_ERROR) {
-			error = -1;
-			break;
-		} else if (ustate == UCODE_NEW) {
-			apply_microcode_on_target(cpu);
-		}
-	}
-
-	return error;
-}
-
-static int microcode_open(struct inode *inode, struct file *file)
-{
-	return capable(CAP_SYS_RAWIO) ? stream_open(inode, file) : -EPERM;
-}
-
-static ssize_t microcode_write(struct file *file, const char __user *buf,
-			       size_t len, loff_t *ppos)
-{
-	ssize_t ret = -EINVAL;
-	unsigned long nr_pages = totalram_pages();
-
-	if ((len >> PAGE_SHIFT) > nr_pages) {
-		pr_err("too much data (max %ld pages)\n", nr_pages);
-		return ret;
-	}
-
-	get_online_cpus();
-	mutex_lock(&microcode_mutex);
-
-	if (do_microcode_update(buf, len) == 0)
-		ret = (ssize_t)len;
-
-	if (ret > 0)
-		perf_check_microcode();
-
-	mutex_unlock(&microcode_mutex);
-	put_online_cpus();
-
-	return ret;
-}
-
-static const struct file_operations microcode_fops = {
-	.owner			= THIS_MODULE,
-	.write			= microcode_write,
-	.open			= microcode_open,
-	.llseek		= no_llseek,
-};
-
-static struct miscdevice microcode_dev = {
-	.minor			= MICROCODE_MINOR,
-	.name			= "microcode",
-	.nodename		= "cpu/microcode",
-	.fops			= &microcode_fops,
-};
-
-static int __init microcode_dev_init(void)
-{
-	int error;
-
-	error = misc_register(&microcode_dev);
-	if (error) {
-		pr_err("can't misc_register on minor=%d\n", MICROCODE_MINOR);
-		return error;
-	}
-
-	return 0;
-}
-
-static void __exit microcode_dev_exit(void)
-{
-	misc_deregister(&microcode_dev);
-}
-#else
-#define microcode_dev_init()	0
-#define microcode_dev_exit()	do { } while (0)
-#endif
-
 /* fake device for request_firmware */
 static struct platform_device	*microcode_pdev;
 
+#ifdef CONFIG_MICROCODE_LATE_LOADING
 /*
  * Late loading dance. Why the heavy-handed stomp_machine effort?
  *
@@ -599,16 +508,27 @@
  */
 static int microcode_reload_late(void)
 {
-	int ret;
+	int old = boot_cpu_data.microcode, ret;
+	struct cpuinfo_x86 prev_info;
 
 	atomic_set(&late_cpus_in,  0);
 	atomic_set(&late_cpus_out, 0);
 
-	ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask);
-	if (ret == 0)
-		microcode_check();
+	/*
+	 * Take a snapshot before the microcode update in order to compare and
+	 * check whether any bits changed after an update.
+	 */
+	store_cpu_caps(&prev_info);
 
-	pr_info("Reload completed, microcode revision: 0x%x\n", boot_cpu_data.microcode);
+	ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask);
+	if (!ret) {
+		pr_info("Reload succeeded, microcode revision: 0x%x -> 0x%x\n",
+			old, boot_cpu_data.microcode);
+		microcode_check(&prev_info);
+	} else {
+		pr_info("Reload failed, current microcode revision: 0x%x\n",
+			boot_cpu_data.microcode);
+	}
 
 	return ret;
 }
@@ -629,7 +549,7 @@
 	if (val != 1)
 		return size;
 
-	get_online_cpus();
+	cpus_read_lock();
 
 	ret = check_online_cpus();
 	if (ret)
@@ -644,13 +564,16 @@
 	mutex_unlock(&microcode_mutex);
 
 put:
-	put_online_cpus();
+	cpus_read_unlock();
 
 	if (ret == 0)
 		ret = size;
 
 	return ret;
 }
+
+static DEVICE_ATTR_WO(reload);
+#endif
 
 static ssize_t version_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
@@ -668,7 +591,6 @@
 	return sprintf(buf, "0x%x\n", uci->cpu_sig.pf);
 }
 
-static DEVICE_ATTR_WO(reload);
 static DEVICE_ATTR(version, 0444, version_show, NULL);
 static DEVICE_ATTR(processor_flags, 0444, pf_show, NULL);
 
@@ -785,7 +707,7 @@
 	if (uci->valid && uci->mc)
 		microcode_ops->apply_microcode(cpu);
 	else if (!uci->mc)
-		reload_early_microcode();
+		reload_early_microcode(cpu);
 }
 
 static struct syscore_ops mc_syscore_ops = {
@@ -821,7 +743,9 @@
 }
 
 static struct attribute *cpu_root_microcode_attrs[] = {
+#ifdef CONFIG_MICROCODE_LATE_LOADING
 	&dev_attr_reload.attr,
+#endif
 	NULL
 };
 
@@ -853,14 +777,14 @@
 	if (IS_ERR(microcode_pdev))
 		return PTR_ERR(microcode_pdev);
 
-	get_online_cpus();
+	cpus_read_lock();
 	mutex_lock(&microcode_mutex);
 
 	error = subsys_interface_register(&mc_cpu_interface);
 	if (!error)
 		perf_check_microcode();
 	mutex_unlock(&microcode_mutex);
-	put_online_cpus();
+	cpus_read_unlock();
 
 	if (error)
 		goto out_pdev;
@@ -873,10 +797,6 @@
 		goto out_driver;
 	}
 
-	error = microcode_dev_init();
-	if (error)
-		goto out_ucode_group;
-
 	register_syscore_ops(&mc_syscore_ops);
 	cpuhp_setup_state_nocalls(CPUHP_AP_MICROCODE_LOADER, "x86/microcode:starting",
 				  mc_cpu_starting, NULL);
@@ -887,18 +807,14 @@
 
 	return 0;
 
- out_ucode_group:
-	sysfs_remove_group(&cpu_subsys.dev_root->kobj,
-			   &cpu_root_microcode_group);
-
  out_driver:
-	get_online_cpus();
+	cpus_read_lock();
 	mutex_lock(&microcode_mutex);
 
 	subsys_interface_unregister(&mc_cpu_interface);
 
 	mutex_unlock(&microcode_mutex);
-	put_online_cpus();
+	cpus_read_unlock();
 
  out_pdev:
 	platform_device_unregister(microcode_pdev);
diff --git a/kernel/arch/x86/kernel/cpu/microcode/intel.c b/kernel/arch/x86/kernel/cpu/microcode/intel.c
index 7e8e07b..1ba590e 100644
--- a/kernel/arch/x86/kernel/cpu/microcode/intel.c
+++ b/kernel/arch/x86/kernel/cpu/microcode/intel.c
@@ -659,7 +659,6 @@
 	else
 		iup = &intel_ucode_patch;
 
-reget:
 	if (!*iup) {
 		patch = __load_ucode_intel(&uci);
 		if (!patch)
@@ -670,12 +669,7 @@
 
 	uci.mc = *iup;
 
-	if (apply_microcode_early(&uci, true)) {
-		/* Mixed-silicon system? Try to refetch the proper patch: */
-		*iup = NULL;
-
-		goto reget;
-	}
+	apply_microcode_early(&uci, true);
 }
 
 static struct microcode_intel *find_patch(struct ucode_cpu_info *uci)
diff --git a/kernel/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/kernel/arch/x86/kernel/cpu/resctrl/rdtgroup.c
index 5a59e33..1e73b6f 100644
--- a/kernel/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+++ b/kernel/arch/x86/kernel/cpu/resctrl/rdtgroup.c
@@ -311,7 +311,7 @@
 	 * executing task might have its own closid selected. Just reuse
 	 * the context switch code.
 	 */
-	resctrl_sched_in();
+	resctrl_sched_in(current);
 }
 
 /*
@@ -532,7 +532,7 @@
 	 * Otherwise, the MSR is updated when the task is scheduled in.
 	 */
 	if (task == current)
-		resctrl_sched_in();
+		resctrl_sched_in(task);
 }
 
 static void update_task_closid_rmid(struct task_struct *t)
@@ -563,11 +563,11 @@
 	 */
 
 	if (rdtgrp->type == RDTCTRL_GROUP) {
-		tsk->closid = rdtgrp->closid;
-		tsk->rmid = rdtgrp->mon.rmid;
+		WRITE_ONCE(tsk->closid, rdtgrp->closid);
+		WRITE_ONCE(tsk->rmid, rdtgrp->mon.rmid);
 	} else if (rdtgrp->type == RDTMON_GROUP) {
 		if (rdtgrp->mon.parent->closid == tsk->closid) {
-			tsk->rmid = rdtgrp->mon.rmid;
+			WRITE_ONCE(tsk->rmid, rdtgrp->mon.rmid);
 		} else {
 			rdt_last_cmd_puts("Can't move task to different control group\n");
 			return -EINVAL;
@@ -577,8 +577,10 @@
 	/*
 	 * Ensure the task's closid and rmid are written before determining if
 	 * the task is current that will decide if it will be interrupted.
+	 * This pairs with the full barrier between the rq->curr update and
+	 * resctrl_sched_in() during context switch.
 	 */
-	barrier();
+	smp_mb();
 
 	/*
 	 * By now, the task's closid and rmid are set. If the task is current
@@ -713,11 +715,15 @@
 static void show_rdt_tasks(struct rdtgroup *r, struct seq_file *s)
 {
 	struct task_struct *p, *t;
+	pid_t pid;
 
 	rcu_read_lock();
 	for_each_process_thread(p, t) {
-		if (is_closid_match(t, r) || is_rmid_match(t, r))
-			seq_printf(s, "%d\n", t->pid);
+		if (is_closid_match(t, r) || is_rmid_match(t, r)) {
+			pid = task_pid_vnr(t);
+			if (pid)
+				seq_printf(s, "%d\n", pid);
+		}
 	}
 	rcu_read_unlock();
 }
@@ -2310,22 +2316,26 @@
 	for_each_process_thread(p, t) {
 		if (!from || is_closid_match(t, from) ||
 		    is_rmid_match(t, from)) {
-			t->closid = to->closid;
-			t->rmid = to->mon.rmid;
+			WRITE_ONCE(t->closid, to->closid);
+			WRITE_ONCE(t->rmid, to->mon.rmid);
 
-#ifdef CONFIG_SMP
 			/*
-			 * This is safe on x86 w/o barriers as the ordering
-			 * of writing to task_cpu() and t->on_cpu is
-			 * reverse to the reading here. The detection is
-			 * inaccurate as tasks might move or schedule
-			 * before the smp function call takes place. In
-			 * such a case the function call is pointless, but
+			 * Order the closid/rmid stores above before the loads
+			 * in task_curr(). This pairs with the full barrier
+			 * between the rq->curr update and resctrl_sched_in()
+			 * during context switch.
+			 */
+			smp_mb();
+
+			/*
+			 * If the task is on a CPU, set the CPU in the mask.
+			 * The detection is inaccurate as tasks might move or
+			 * schedule before the smp function call takes place.
+			 * In such a case the function call is pointless, but
 			 * there is no other side effect.
 			 */
-			if (mask && t->on_cpu)
+			if (IS_ENABLED(CONFIG_SMP) && mask && task_curr(t))
 				cpumask_set_cpu(task_cpu(t), mask);
-#endif
 		}
 	}
 	read_unlock(&tasklist_lock);
diff --git a/kernel/arch/x86/kernel/cpu/scattered.c b/kernel/arch/x86/kernel/cpu/scattered.c
index 82fe492..f1cd1b6 100644
--- a/kernel/arch/x86/kernel/cpu/scattered.c
+++ b/kernel/arch/x86/kernel/cpu/scattered.c
@@ -41,10 +41,6 @@
 	{ X86_FEATURE_CPB,		CPUID_EDX,  9, 0x80000007, 0 },
 	{ X86_FEATURE_PROC_FEEDBACK,    CPUID_EDX, 11, 0x80000007, 0 },
 	{ X86_FEATURE_MBA,		CPUID_EBX,  6, 0x80000008, 0 },
-	{ X86_FEATURE_SME,		CPUID_EAX,  0, 0x8000001f, 0 },
-	{ X86_FEATURE_SEV,		CPUID_EAX,  1, 0x8000001f, 0 },
-	{ X86_FEATURE_SEV_ES,		CPUID_EAX,  3, 0x8000001f, 0 },
-	{ X86_FEATURE_SME_COHERENT,	CPUID_EAX, 10, 0x8000001f, 0 },
 	{ 0, 0, 0, 0, 0 }
 };
 
diff --git a/kernel/arch/x86/kernel/cpu/topology.c b/kernel/arch/x86/kernel/cpu/topology.c
index 37d48ab..58d17c0 100644
--- a/kernel/arch/x86/kernel/cpu/topology.c
+++ b/kernel/arch/x86/kernel/cpu/topology.c
@@ -79,7 +79,7 @@
 	 * initial apic id, which also represents 32-bit extended x2apic id.
 	 */
 	c->initial_apicid = edx;
-	smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
+	smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx));
 #endif
 	return 0;
 }
@@ -109,7 +109,8 @@
 	 */
 	cpuid_count(leaf, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
 	c->initial_apicid = edx;
-	core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
+	core_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
+	smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx));
 	core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
 	die_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
 	pkg_mask_width = die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
diff --git a/kernel/arch/x86/kernel/crash.c b/kernel/arch/x86/kernel/crash.c
index b1deacb..a932a07 100644
--- a/kernel/arch/x86/kernel/crash.c
+++ b/kernel/arch/x86/kernel/crash.c
@@ -37,7 +37,6 @@
 #include <linux/kdebug.h>
 #include <asm/cpu.h>
 #include <asm/reboot.h>
-#include <asm/virtext.h>
 #include <asm/intel_pt.h>
 #include <asm/crash.h>
 #include <asm/cmdline.h>
@@ -93,15 +92,6 @@
 	 * VMCLEAR VMCSs loaded on all cpus if needed.
 	 */
 	cpu_crash_vmclear_loaded_vmcss();
-
-	/* Disable VMX or SVM if needed.
-	 *
-	 * We need to disable virtualization on all CPUs.
-	 * Having VMX or SVM enabled on any CPU may break rebooting
-	 * after the kdump kernel has finished its task.
-	 */
-	cpu_emergency_vmxoff();
-	cpu_emergency_svm_disable();
 
 	/*
 	 * Disable Intel PT to stop its logging
@@ -161,12 +151,7 @@
 	 */
 	cpu_crash_vmclear_loaded_vmcss();
 
-	/* Booting kdump kernel with VMX or SVM enabled won't work,
-	 * because (among other limitations) we can't disable paging
-	 * with the virt flags.
-	 */
-	cpu_emergency_vmxoff();
-	cpu_emergency_svm_disable();
+	cpu_emergency_disable_virtualization();
 
 	/*
 	 * Disable Intel PT to stop its logging
diff --git a/kernel/arch/x86/kernel/dumpstack.c b/kernel/arch/x86/kernel/dumpstack.c
index 97aa900..b9736aa 100644
--- a/kernel/arch/x86/kernel/dumpstack.c
+++ b/kernel/arch/x86/kernel/dumpstack.c
@@ -195,7 +195,6 @@
 	printk("%sCall Trace:\n", log_lvl);
 
 	unwind_start(&state, task, regs, stack);
-	stack = stack ? : get_stack_pointer(task, regs);
 	regs = unwind_get_entry_regs(&state, &partial);
 
 	/*
@@ -214,8 +213,12 @@
 	 * - hardirq stack
 	 * - entry stack
 	 */
-	for ( ; stack; stack = PTR_ALIGN(stack_info.next_sp, sizeof(long))) {
+	for (stack = stack ?: get_stack_pointer(task, regs);
+	     stack;
+	     stack = stack_info.next_sp) {
 		const char *stack_name;
+
+		stack = PTR_ALIGN(stack, sizeof(long));
 
 		if (get_stack_info(stack, task, &stack_info, &visit_mask)) {
 			/*
@@ -351,7 +354,7 @@
 }
 NOKPROBE_SYMBOL(oops_begin);
 
-void __noreturn rewind_stack_do_exit(int signr);
+void __noreturn rewind_stack_and_make_dead(int signr);
 
 void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
 {
@@ -386,7 +389,7 @@
 	 * reuse the task stack and that existing poisons are invalid.
 	 */
 	kasan_unpoison_task_stack(current);
-	rewind_stack_do_exit(signr);
+	rewind_stack_and_make_dead(signr);
 }
 NOKPROBE_SYMBOL(oops_end);
 
diff --git a/kernel/arch/x86/kernel/fpu/core.c b/kernel/arch/x86/kernel/fpu/core.c
index 571220a..835b948 100644
--- a/kernel/arch/x86/kernel/fpu/core.c
+++ b/kernel/arch/x86/kernel/fpu/core.c
@@ -25,17 +25,7 @@
  */
 union fpregs_state init_fpstate __read_mostly;
 
-/*
- * Track whether the kernel is using the FPU state
- * currently.
- *
- * This flag is used:
- *
- *   - by IRQ context code to potentially use the FPU
- *     if it's unused.
- *
- *   - to debug kernel_fpu_begin()/end() correctness
- */
+/* Track in-kernel FPU usage */
 static DEFINE_PER_CPU(bool, in_kernel_fpu);
 
 /*
@@ -43,42 +33,37 @@
  */
 DEFINE_PER_CPU(struct fpu *, fpu_fpregs_owner_ctx);
 
-static bool kernel_fpu_disabled(void)
-{
-	return this_cpu_read(in_kernel_fpu);
-}
-
-static bool interrupted_kernel_fpu_idle(void)
-{
-	return !kernel_fpu_disabled();
-}
-
-/*
- * Were we in user mode (or vm86 mode) when we were
- * interrupted?
- *
- * Doing kernel_fpu_begin/end() is ok if we are running
- * in an interrupt context from user mode - we'll just
- * save the FPU state as required.
- */
-static bool interrupted_user_mode(void)
-{
-	struct pt_regs *regs = get_irq_regs();
-	return regs && user_mode(regs);
-}
-
 /*
  * Can we use the FPU in kernel mode with the
  * whole "kernel_fpu_begin/end()" sequence?
- *
- * It's always ok in process context (ie "not interrupt")
- * but it is sometimes ok even from an irq.
  */
 bool irq_fpu_usable(void)
 {
-	return !in_interrupt() ||
-		interrupted_user_mode() ||
-		interrupted_kernel_fpu_idle();
+	if (WARN_ON_ONCE(in_nmi()))
+		return false;
+
+	/* In kernel FPU usage already active? */
+	if (this_cpu_read(in_kernel_fpu))
+		return false;
+
+	/*
+	 * When not in NMI or hard interrupt context, FPU can be used in:
+	 *
+	 * - Task context except from within fpregs_lock()'ed critical
+	 *   regions.
+	 *
+	 * - Soft interrupt processing context which cannot happen
+	 *   while in a fpregs_lock()'ed critical region.
+	 */
+	if (!in_irq())
+		return true;
+
+	/*
+	 * In hard interrupt context it's safe when soft interrupts
+	 * are enabled, which means the interrupt did not hit in
+	 * a fpregs_lock()'ed critical region.
+	 */
+	return !softirq_count();
 }
 EXPORT_SYMBOL(irq_fpu_usable);
 
diff --git a/kernel/arch/x86/kernel/fpu/init.c b/kernel/arch/x86/kernel/fpu/init.c
index 701f196..ed73f9b 100644
--- a/kernel/arch/x86/kernel/fpu/init.c
+++ b/kernel/arch/x86/kernel/fpu/init.c
@@ -49,7 +49,7 @@
 	fpu__init_cpu_xstate();
 }
 
-static bool fpu__probe_without_cpuid(void)
+static bool __init fpu__probe_without_cpuid(void)
 {
 	unsigned long cr0;
 	u16 fsw, fcw;
@@ -67,7 +67,7 @@
 	return fsw == 0 && (fcw & 0x103f) == 0x003f;
 }
 
-static void fpu__init_system_early_generic(struct cpuinfo_x86 *c)
+static void __init fpu__init_system_early_generic(void)
 {
 	if (!boot_cpu_has(X86_FEATURE_CPUID) &&
 	    !test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) {
@@ -138,9 +138,6 @@
 unsigned int fpu_kernel_xstate_size;
 EXPORT_SYMBOL_GPL(fpu_kernel_xstate_size);
 
-/* Get alignment of the TYPE. */
-#define TYPE_ALIGN(TYPE) offsetof(struct { char x; TYPE test; }, test)
-
 /*
  * Enforce that 'MEMBER' is the last field of 'TYPE'.
  *
@@ -148,8 +145,8 @@
  * because that's how C aligns structs.
  */
 #define CHECK_MEMBER_AT_END_OF(TYPE, MEMBER) \
-	BUILD_BUG_ON(sizeof(TYPE) != ALIGN(offsetofend(TYPE, MEMBER), \
-					   TYPE_ALIGN(TYPE)))
+	BUILD_BUG_ON(sizeof(TYPE) !=         \
+		     ALIGN(offsetofend(TYPE, MEMBER), _Alignof(TYPE)))
 
 /*
  * We append the 'struct fpu' to the task_struct:
@@ -240,9 +237,9 @@
  * Called on the boot CPU once per system bootup, to set up the initial
  * FPU state that is later cloned into all processes:
  */
-void __init fpu__init_system(struct cpuinfo_x86 *c)
+void __init fpu__init_system(void)
 {
-	fpu__init_system_early_generic(c);
+	fpu__init_system_early_generic();
 
 	/*
 	 * The FPU has to be operational for some of the
diff --git a/kernel/arch/x86/kernel/fpu/xstate.c b/kernel/arch/x86/kernel/fpu/xstate.c
index 80836b9..b897feb 100644
--- a/kernel/arch/x86/kernel/fpu/xstate.c
+++ b/kernel/arch/x86/kernel/fpu/xstate.c
@@ -892,6 +892,14 @@
 	setup_init_fpu_buf();
 	setup_xstate_comp_offsets();
 	setup_supervisor_only_offsets();
+
+	/*
+	 * CPU capabilities initialization runs before FPU init. So
+	 * X86_FEATURE_OSXSAVE is not set. Now that XSAVE is completely
+	 * functional, set the feature bit so depending code works.
+	 */
+	setup_force_cpu_cap(X86_FEATURE_OSXSAVE);
+
 	print_xstate_offset_size();
 
 	pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n",
diff --git a/kernel/arch/x86/kernel/ftrace.c b/kernel/arch/x86/kernel/ftrace.c
index d096b5a..6d546f4 100644
--- a/kernel/arch/x86/kernel/ftrace.c
+++ b/kernel/arch/x86/kernel/ftrace.c
@@ -219,7 +219,9 @@
 
 		ret = ftrace_verify_code(rec->ip, old);
 		if (ret) {
+			ftrace_expected = old;
 			ftrace_bug(ret, rec);
+			ftrace_expected = NULL;
 			return;
 		}
 	}
diff --git a/kernel/arch/x86/kernel/i8259.c b/kernel/arch/x86/kernel/i8259.c
index 282b4ee..f325389 100644
--- a/kernel/arch/x86/kernel/i8259.c
+++ b/kernel/arch/x86/kernel/i8259.c
@@ -114,6 +114,7 @@
 	disable_irq_nosync(irq);
 	io_apic_irqs &= ~(1<<irq);
 	irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
+	irq_set_status_flags(irq, IRQ_LEVEL);
 	enable_irq(irq);
 	lapic_assign_legacy_vector(irq, true);
 }
diff --git a/kernel/arch/x86/kernel/irqinit.c b/kernel/arch/x86/kernel/irqinit.c
index beb1bad..c683666 100644
--- a/kernel/arch/x86/kernel/irqinit.c
+++ b/kernel/arch/x86/kernel/irqinit.c
@@ -65,8 +65,10 @@
 
 	legacy_pic->init(0);
 
-	for (i = 0; i < nr_legacy_irqs(); i++)
+	for (i = 0; i < nr_legacy_irqs(); i++) {
 		irq_set_chip_and_handler(i, chip, handle_level_irq);
+		irq_set_status_flags(i, IRQ_LEVEL);
+	}
 }
 
 void __init init_IRQ(void)
diff --git a/kernel/arch/x86/kernel/kprobes/core.c b/kernel/arch/x86/kernel/kprobes/core.c
index ee85f1b..c78b494 100644
--- a/kernel/arch/x86/kernel/kprobes/core.c
+++ b/kernel/arch/x86/kernel/kprobes/core.c
@@ -37,6 +37,7 @@
 #include <linux/extable.h>
 #include <linux/kdebug.h>
 #include <linux/kallsyms.h>
+#include <linux/kgdb.h>
 #include <linux/ftrace.h>
 #include <linux/kasan.h>
 #include <linux/moduleloader.h>
@@ -133,26 +134,6 @@
 NOKPROBE_SYMBOL(synthesize_relcall);
 
 /*
- * Skip the prefixes of the instruction.
- */
-static kprobe_opcode_t *skip_prefixes(kprobe_opcode_t *insn)
-{
-	insn_attr_t attr;
-
-	attr = inat_get_opcode_attribute((insn_byte_t)*insn);
-	while (inat_is_legacy_prefix(attr)) {
-		insn++;
-		attr = inat_get_opcode_attribute((insn_byte_t)*insn);
-	}
-#ifdef CONFIG_X86_64
-	if (inat_is_rex_prefix(attr))
-		insn++;
-#endif
-	return insn;
-}
-NOKPROBE_SYMBOL(skip_prefixes);
-
-/*
  * Returns non-zero if INSN is boostable.
  * RIP relative instructions are adjusted at copying time in 64 bits mode
  */
@@ -184,29 +165,28 @@
 
 	opcode = insn->opcode.bytes[0];
 
-	switch (opcode & 0xf0) {
-	case 0x60:
-		/* can't boost "bound" */
-		return (opcode != 0x62);
-	case 0x70:
-		return 0; /* can't boost conditional jump */
-	case 0x90:
-		return opcode != 0x9a;	/* can't boost call far */
-	case 0xc0:
-		/* can't boost software-interruptions */
-		return (0xc1 < opcode && opcode < 0xcc) || opcode == 0xcf;
-	case 0xd0:
-		/* can boost AA* and XLAT */
-		return (opcode == 0xd4 || opcode == 0xd5 || opcode == 0xd7);
-	case 0xe0:
-		/* can boost in/out and absolute jmps */
-		return ((opcode & 0x04) || opcode == 0xea);
-	case 0xf0:
-		/* clear and set flags are boostable */
-		return (opcode == 0xf5 || (0xf7 < opcode && opcode < 0xfe));
+	switch (opcode) {
+	case 0x62:		/* bound */
+	case 0x70 ... 0x7f:	/* Conditional jumps */
+	case 0x9a:		/* Call far */
+	case 0xc0 ... 0xc1:	/* Grp2 */
+	case 0xcc ... 0xce:	/* software exceptions */
+	case 0xd0 ... 0xd3:	/* Grp2 */
+	case 0xd6:		/* (UD) */
+	case 0xd8 ... 0xdf:	/* ESC */
+	case 0xe0 ... 0xe3:	/* LOOP*, JCXZ */
+	case 0xe8 ... 0xe9:	/* near Call, JMP */
+	case 0xeb:		/* Short JMP */
+	case 0xf0 ... 0xf4:	/* LOCK/REP, HLT */
+	case 0xf6 ... 0xf7:	/* Grp3 */
+	case 0xfe:		/* Grp4 */
+		/* ... are not boostable */
+		return 0;
+	case 0xff:		/* Grp5 */
+		/* Only indirect jmp is boostable */
+		return X86_MODRM_REG(insn->modrm.bytes[0]) == 4;
 	default:
-		/* call is not boostable */
-		return opcode != 0x9a;
+		return 1;
 	}
 }
 
@@ -292,6 +272,8 @@
 	/* Decode instructions */
 	addr = paddr - offset;
 	while (addr < paddr) {
+		int ret;
+
 		/*
 		 * Check if the instruction has been modified by another
 		 * kprobe, in which case we replace the breakpoint by the
@@ -303,38 +285,24 @@
 		__addr = recover_probed_instruction(buf, addr);
 		if (!__addr)
 			return 0;
-		kernel_insn_init(&insn, (void *)__addr, MAX_INSN_SIZE);
-		insn_get_length(&insn);
 
-		/*
-		 * Another debugging subsystem might insert this breakpoint.
-		 * In that case, we can't recover it.
-		 */
-		if (insn.opcode.bytes[0] == INT3_INSN_OPCODE)
+		ret = insn_decode(&insn, (void *)__addr, MAX_INSN_SIZE, INSN_MODE_KERN);
+		if (ret < 0)
 			return 0;
+
+#ifdef CONFIG_KGDB
+		/*
+		 * If there is a dynamically installed kgdb sw breakpoint,
+		 * this function should not be probed.
+		 */
+		if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
+		    kgdb_has_hit_break(addr))
+			return 0;
+#endif
 		addr += insn.length;
 	}
 
 	return (addr == paddr);
-}
-
-/*
- * Returns non-zero if opcode modifies the interrupt flag.
- */
-static int is_IF_modifier(kprobe_opcode_t *insn)
-{
-	/* Skip prefixes */
-	insn = skip_prefixes(insn);
-
-	switch (*insn) {
-	case 0xfa:		/* cli */
-	case 0xfb:		/* sti */
-	case 0xcf:		/* iret/iretd */
-	case 0x9d:		/* popf/popfd */
-		return 1;
-	}
-
-	return 0;
 }
 
 /*
@@ -347,8 +315,8 @@
 int __copy_instruction(u8 *dest, u8 *src, u8 *real, struct insn *insn)
 {
 	kprobe_opcode_t buf[MAX_INSN_SIZE];
-	unsigned long recovered_insn =
-		recover_probed_instruction(buf, (unsigned long)src);
+	unsigned long recovered_insn = recover_probed_instruction(buf, (unsigned long)src);
+	int ret;
 
 	if (!recovered_insn || !insn)
 		return 0;
@@ -358,8 +326,9 @@
 			MAX_INSN_SIZE))
 		return 0;
 
-	kernel_insn_init(insn, dest, MAX_INSN_SIZE);
-	insn_get_length(insn);
+	ret = insn_decode(insn, dest, MAX_INSN_SIZE, INSN_MODE_KERN);
+	if (ret < 0)
+		return 0;
 
 	/* We can not probe force emulate prefixed instruction */
 	if (insn_has_emulate_prefix(insn))
@@ -403,13 +372,14 @@
 	return insn->length;
 }
 
-/* Prepare reljump right after instruction to boost */
-static int prepare_boost(kprobe_opcode_t *buf, struct kprobe *p,
-			  struct insn *insn)
+/* Prepare reljump or int3 right after instruction */
+static int prepare_singlestep(kprobe_opcode_t *buf, struct kprobe *p,
+			      struct insn *insn)
 {
 	int len = insn->length;
 
-	if (can_boost(insn, p->addr) &&
+	if (!IS_ENABLED(CONFIG_PREEMPTION) &&
+	    !p->post_handler && can_boost(insn, p->addr) &&
 	    MAX_INSN_SIZE - len >= JMP32_INSN_SIZE) {
 		/*
 		 * These instructions can be executed directly if it
@@ -418,9 +388,14 @@
 		synthesize_reljump(buf + len, p->ainsn.insn + len,
 				   p->addr + insn->length);
 		len += JMP32_INSN_SIZE;
-		p->ainsn.boostable = true;
+		p->ainsn.boostable = 1;
 	} else {
-		p->ainsn.boostable = false;
+		/* Otherwise, put an int3 for trapping singlestep */
+		if (MAX_INSN_SIZE - len < INT3_INSN_SIZE)
+			return -ENOSPC;
+
+		buf[len] = INT3_INSN_OPCODE;
+		len += INT3_INSN_SIZE;
 	}
 
 	return len;
@@ -457,25 +432,290 @@
 	module_memfree(page);
 }
 
+/* Kprobe x86 instruction emulation - only regs->ip or IF flag modifiers */
+
+static void kprobe_emulate_ifmodifiers(struct kprobe *p, struct pt_regs *regs)
+{
+	switch (p->ainsn.opcode) {
+	case 0xfa:	/* cli */
+		regs->flags &= ~(X86_EFLAGS_IF);
+		break;
+	case 0xfb:	/* sti */
+		regs->flags |= X86_EFLAGS_IF;
+		break;
+	case 0x9c:	/* pushf */
+		int3_emulate_push(regs, regs->flags);
+		break;
+	case 0x9d:	/* popf */
+		regs->flags = int3_emulate_pop(regs);
+		break;
+	}
+	regs->ip = regs->ip - INT3_INSN_SIZE + p->ainsn.size;
+}
+NOKPROBE_SYMBOL(kprobe_emulate_ifmodifiers);
+
+static void kprobe_emulate_ret(struct kprobe *p, struct pt_regs *regs)
+{
+	int3_emulate_ret(regs);
+}
+NOKPROBE_SYMBOL(kprobe_emulate_ret);
+
+static void kprobe_emulate_call(struct kprobe *p, struct pt_regs *regs)
+{
+	unsigned long func = regs->ip - INT3_INSN_SIZE + p->ainsn.size;
+
+	func += p->ainsn.rel32;
+	int3_emulate_call(regs, func);
+}
+NOKPROBE_SYMBOL(kprobe_emulate_call);
+
+static nokprobe_inline
+void __kprobe_emulate_jmp(struct kprobe *p, struct pt_regs *regs, bool cond)
+{
+	unsigned long ip = regs->ip - INT3_INSN_SIZE + p->ainsn.size;
+
+	if (cond)
+		ip += p->ainsn.rel32;
+	int3_emulate_jmp(regs, ip);
+}
+
+static void kprobe_emulate_jmp(struct kprobe *p, struct pt_regs *regs)
+{
+	__kprobe_emulate_jmp(p, regs, true);
+}
+NOKPROBE_SYMBOL(kprobe_emulate_jmp);
+
+static const unsigned long jcc_mask[6] = {
+	[0] = X86_EFLAGS_OF,
+	[1] = X86_EFLAGS_CF,
+	[2] = X86_EFLAGS_ZF,
+	[3] = X86_EFLAGS_CF | X86_EFLAGS_ZF,
+	[4] = X86_EFLAGS_SF,
+	[5] = X86_EFLAGS_PF,
+};
+
+static void kprobe_emulate_jcc(struct kprobe *p, struct pt_regs *regs)
+{
+	bool invert = p->ainsn.jcc.type & 1;
+	bool match;
+
+	if (p->ainsn.jcc.type < 0xc) {
+		match = regs->flags & jcc_mask[p->ainsn.jcc.type >> 1];
+	} else {
+		match = ((regs->flags & X86_EFLAGS_SF) >> X86_EFLAGS_SF_BIT) ^
+			((regs->flags & X86_EFLAGS_OF) >> X86_EFLAGS_OF_BIT);
+		if (p->ainsn.jcc.type >= 0xe)
+			match = match || (regs->flags & X86_EFLAGS_ZF);
+	}
+	__kprobe_emulate_jmp(p, regs, (match && !invert) || (!match && invert));
+}
+NOKPROBE_SYMBOL(kprobe_emulate_jcc);
+
+static void kprobe_emulate_loop(struct kprobe *p, struct pt_regs *regs)
+{
+	bool match;
+
+	if (p->ainsn.loop.type != 3) {	/* LOOP* */
+		if (p->ainsn.loop.asize == 32)
+			match = ((*(u32 *)&regs->cx)--) != 0;
+#ifdef CONFIG_X86_64
+		else if (p->ainsn.loop.asize == 64)
+			match = ((*(u64 *)&regs->cx)--) != 0;
+#endif
+		else
+			match = ((*(u16 *)&regs->cx)--) != 0;
+	} else {			/* JCXZ */
+		if (p->ainsn.loop.asize == 32)
+			match = *(u32 *)(&regs->cx) == 0;
+#ifdef CONFIG_X86_64
+		else if (p->ainsn.loop.asize == 64)
+			match = *(u64 *)(&regs->cx) == 0;
+#endif
+		else
+			match = *(u16 *)(&regs->cx) == 0;
+	}
+
+	if (p->ainsn.loop.type == 0)	/* LOOPNE */
+		match = match && !(regs->flags & X86_EFLAGS_ZF);
+	else if (p->ainsn.loop.type == 1)	/* LOOPE */
+		match = match && (regs->flags & X86_EFLAGS_ZF);
+
+	__kprobe_emulate_jmp(p, regs, match);
+}
+NOKPROBE_SYMBOL(kprobe_emulate_loop);
+
+static const int addrmode_regoffs[] = {
+	offsetof(struct pt_regs, ax),
+	offsetof(struct pt_regs, cx),
+	offsetof(struct pt_regs, dx),
+	offsetof(struct pt_regs, bx),
+	offsetof(struct pt_regs, sp),
+	offsetof(struct pt_regs, bp),
+	offsetof(struct pt_regs, si),
+	offsetof(struct pt_regs, di),
+#ifdef CONFIG_X86_64
+	offsetof(struct pt_regs, r8),
+	offsetof(struct pt_regs, r9),
+	offsetof(struct pt_regs, r10),
+	offsetof(struct pt_regs, r11),
+	offsetof(struct pt_regs, r12),
+	offsetof(struct pt_regs, r13),
+	offsetof(struct pt_regs, r14),
+	offsetof(struct pt_regs, r15),
+#endif
+};
+
+static void kprobe_emulate_call_indirect(struct kprobe *p, struct pt_regs *regs)
+{
+	unsigned long offs = addrmode_regoffs[p->ainsn.indirect.reg];
+
+	int3_emulate_call(regs, regs_get_register(regs, offs));
+}
+NOKPROBE_SYMBOL(kprobe_emulate_call_indirect);
+
+static void kprobe_emulate_jmp_indirect(struct kprobe *p, struct pt_regs *regs)
+{
+	unsigned long offs = addrmode_regoffs[p->ainsn.indirect.reg];
+
+	int3_emulate_jmp(regs, regs_get_register(regs, offs));
+}
+NOKPROBE_SYMBOL(kprobe_emulate_jmp_indirect);
+
+static int prepare_emulation(struct kprobe *p, struct insn *insn)
+{
+	insn_byte_t opcode = insn->opcode.bytes[0];
+
+	switch (opcode) {
+	case 0xfa:		/* cli */
+	case 0xfb:		/* sti */
+	case 0x9c:		/* pushfl */
+	case 0x9d:		/* popf/popfd */
+		/*
+		 * IF modifiers must be emulated since it will enable interrupt while
+		 * int3 single stepping.
+		 */
+		p->ainsn.emulate_op = kprobe_emulate_ifmodifiers;
+		p->ainsn.opcode = opcode;
+		break;
+	case 0xc2:	/* ret/lret */
+	case 0xc3:
+	case 0xca:
+	case 0xcb:
+		p->ainsn.emulate_op = kprobe_emulate_ret;
+		break;
+	case 0x9a:	/* far call absolute -- segment is not supported */
+	case 0xea:	/* far jmp absolute -- segment is not supported */
+	case 0xcc:	/* int3 */
+	case 0xcf:	/* iret -- in-kernel IRET is not supported */
+		return -EOPNOTSUPP;
+		break;
+	case 0xe8:	/* near call relative */
+		p->ainsn.emulate_op = kprobe_emulate_call;
+		if (insn->immediate.nbytes == 2)
+			p->ainsn.rel32 = *(s16 *)&insn->immediate.value;
+		else
+			p->ainsn.rel32 = *(s32 *)&insn->immediate.value;
+		break;
+	case 0xeb:	/* short jump relative */
+	case 0xe9:	/* near jump relative */
+		p->ainsn.emulate_op = kprobe_emulate_jmp;
+		if (insn->immediate.nbytes == 1)
+			p->ainsn.rel32 = *(s8 *)&insn->immediate.value;
+		else if (insn->immediate.nbytes == 2)
+			p->ainsn.rel32 = *(s16 *)&insn->immediate.value;
+		else
+			p->ainsn.rel32 = *(s32 *)&insn->immediate.value;
+		break;
+	case 0x70 ... 0x7f:
+		/* 1 byte conditional jump */
+		p->ainsn.emulate_op = kprobe_emulate_jcc;
+		p->ainsn.jcc.type = opcode & 0xf;
+		p->ainsn.rel32 = *(char *)insn->immediate.bytes;
+		break;
+	case 0x0f:
+		opcode = insn->opcode.bytes[1];
+		if ((opcode & 0xf0) == 0x80) {
+			/* 2 bytes Conditional Jump */
+			p->ainsn.emulate_op = kprobe_emulate_jcc;
+			p->ainsn.jcc.type = opcode & 0xf;
+			if (insn->immediate.nbytes == 2)
+				p->ainsn.rel32 = *(s16 *)&insn->immediate.value;
+			else
+				p->ainsn.rel32 = *(s32 *)&insn->immediate.value;
+		} else if (opcode == 0x01 &&
+			   X86_MODRM_REG(insn->modrm.bytes[0]) == 0 &&
+			   X86_MODRM_MOD(insn->modrm.bytes[0]) == 3) {
+			/* VM extensions - not supported */
+			return -EOPNOTSUPP;
+		}
+		break;
+	case 0xe0:	/* Loop NZ */
+	case 0xe1:	/* Loop */
+	case 0xe2:	/* Loop */
+	case 0xe3:	/* J*CXZ */
+		p->ainsn.emulate_op = kprobe_emulate_loop;
+		p->ainsn.loop.type = opcode & 0x3;
+		p->ainsn.loop.asize = insn->addr_bytes * 8;
+		p->ainsn.rel32 = *(s8 *)&insn->immediate.value;
+		break;
+	case 0xff:
+		/*
+		 * Since the 0xff is an extended group opcode, the instruction
+		 * is determined by the MOD/RM byte.
+		 */
+		opcode = insn->modrm.bytes[0];
+		if ((opcode & 0x30) == 0x10) {
+			if ((opcode & 0x8) == 0x8)
+				return -EOPNOTSUPP;	/* far call */
+			/* call absolute, indirect */
+			p->ainsn.emulate_op = kprobe_emulate_call_indirect;
+		} else if ((opcode & 0x30) == 0x20) {
+			if ((opcode & 0x8) == 0x8)
+				return -EOPNOTSUPP;	/* far jmp */
+			/* jmp near absolute indirect */
+			p->ainsn.emulate_op = kprobe_emulate_jmp_indirect;
+		} else
+			break;
+
+		if (insn->addr_bytes != sizeof(unsigned long))
+			return -EOPNOTSUPP;	/* Don't support differnt size */
+		if (X86_MODRM_MOD(opcode) != 3)
+			return -EOPNOTSUPP;	/* TODO: support memory addressing */
+
+		p->ainsn.indirect.reg = X86_MODRM_RM(opcode);
+#ifdef CONFIG_X86_64
+		if (X86_REX_B(insn->rex_prefix.value))
+			p->ainsn.indirect.reg += 8;
+#endif
+		break;
+	default:
+		break;
+	}
+	p->ainsn.size = insn->length;
+
+	return 0;
+}
+
 static int arch_copy_kprobe(struct kprobe *p)
 {
 	struct insn insn;
 	kprobe_opcode_t buf[MAX_INSN_SIZE];
-	int len;
+	int ret, len;
 
 	/* Copy an instruction with recovering if other optprobe modifies it.*/
 	len = __copy_instruction(buf, p->addr, p->ainsn.insn, &insn);
 	if (!len)
 		return -EINVAL;
 
-	/*
-	 * __copy_instruction can modify the displacement of the instruction,
-	 * but it doesn't affect boostable check.
-	 */
-	len = prepare_boost(buf, p, &insn);
+	/* Analyze the opcode and setup emulate functions */
+	ret = prepare_emulation(p, &insn);
+	if (ret < 0)
+		return ret;
 
-	/* Check whether the instruction modifies Interrupt Flag or not */
-	p->ainsn.if_modifier = is_IF_modifier(buf);
+	/* Add int3 for single-step or booster jmp */
+	len = prepare_singlestep(buf, p, &insn);
+	if (len < 0)
+		return len;
 
 	/* Also, displacement change doesn't affect the first byte */
 	p->opcode = buf[0];
@@ -498,6 +738,9 @@
 
 	if (!can_probe((unsigned long)p->addr))
 		return -EILSEQ;
+
+	memset(&p->ainsn, 0, sizeof(p->ainsn));
+
 	/* insn: must be on special executable page on x86. */
 	p->ainsn.insn = get_insn_slot();
 	if (!p->ainsn.insn)
@@ -565,29 +808,7 @@
 {
 	__this_cpu_write(current_kprobe, p);
 	kcb->kprobe_saved_flags = kcb->kprobe_old_flags
-		= (regs->flags & (X86_EFLAGS_TF | X86_EFLAGS_IF));
-	if (p->ainsn.if_modifier)
-		kcb->kprobe_saved_flags &= ~X86_EFLAGS_IF;
-}
-
-static nokprobe_inline void clear_btf(void)
-{
-	if (test_thread_flag(TIF_BLOCKSTEP)) {
-		unsigned long debugctl = get_debugctlmsr();
-
-		debugctl &= ~DEBUGCTLMSR_BTF;
-		update_debugctlmsr(debugctl);
-	}
-}
-
-static nokprobe_inline void restore_btf(void)
-{
-	if (test_thread_flag(TIF_BLOCKSTEP)) {
-		unsigned long debugctl = get_debugctlmsr();
-
-		debugctl |= DEBUGCTLMSR_BTF;
-		update_debugctlmsr(debugctl);
-	}
+		= (regs->flags & X86_EFLAGS_IF);
 }
 
 void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs)
@@ -602,6 +823,26 @@
 }
 NOKPROBE_SYMBOL(arch_prepare_kretprobe);
 
+static void kprobe_post_process(struct kprobe *cur, struct pt_regs *regs,
+			       struct kprobe_ctlblk *kcb)
+{
+	/* Restore back the original saved kprobes variables and continue. */
+	if (kcb->kprobe_status == KPROBE_REENTER) {
+		/* This will restore both kcb and current_kprobe */
+		restore_previous_kprobe(kcb);
+	} else {
+		/*
+		 * Always update the kcb status because
+		 * reset_curent_kprobe() doesn't update kcb.
+		 */
+		kcb->kprobe_status = KPROBE_HIT_SSDONE;
+		if (cur->post_handler)
+			cur->post_handler(cur, regs, 0);
+		reset_current_kprobe();
+	}
+}
+NOKPROBE_SYMBOL(kprobe_post_process);
+
 static void setup_singlestep(struct kprobe *p, struct pt_regs *regs,
 			     struct kprobe_ctlblk *kcb, int reenter)
 {
@@ -609,7 +850,7 @@
 		return;
 
 #if !defined(CONFIG_PREEMPTION)
-	if (p->ainsn.boostable && !p->post_handler) {
+	if (p->ainsn.boostable) {
 		/* Boost up -- we can execute copied instructions directly */
 		if (!reenter)
 			reset_current_kprobe();
@@ -628,17 +869,49 @@
 		kcb->kprobe_status = KPROBE_REENTER;
 	} else
 		kcb->kprobe_status = KPROBE_HIT_SS;
-	/* Prepare real single stepping */
-	clear_btf();
-	regs->flags |= X86_EFLAGS_TF;
+
+	if (p->ainsn.emulate_op) {
+		p->ainsn.emulate_op(p, regs);
+		kprobe_post_process(p, regs, kcb);
+		return;
+	}
+
+	/* Disable interrupt, and set ip register on trampoline */
 	regs->flags &= ~X86_EFLAGS_IF;
-	/* single step inline if the instruction is an int3 */
-	if (p->opcode == INT3_INSN_OPCODE)
-		regs->ip = (unsigned long)p->addr;
-	else
-		regs->ip = (unsigned long)p->ainsn.insn;
+	regs->ip = (unsigned long)p->ainsn.insn;
 }
 NOKPROBE_SYMBOL(setup_singlestep);
+
+/*
+ * Called after single-stepping.  p->addr is the address of the
+ * instruction whose first byte has been replaced by the "int3"
+ * instruction.  To avoid the SMP problems that can occur when we
+ * temporarily put back the original opcode to single-step, we
+ * single-stepped a copy of the instruction.  The address of this
+ * copy is p->ainsn.insn. We also doesn't use trap, but "int3" again
+ * right after the copied instruction.
+ * Different from the trap single-step, "int3" single-step can not
+ * handle the instruction which changes the ip register, e.g. jmp,
+ * call, conditional jmp, and the instructions which changes the IF
+ * flags because interrupt must be disabled around the single-stepping.
+ * Such instructions are software emulated, but others are single-stepped
+ * using "int3".
+ *
+ * When the 2nd "int3" handled, the regs->ip and regs->flags needs to
+ * be adjusted, so that we can resume execution on correct code.
+ */
+static void resume_singlestep(struct kprobe *p, struct pt_regs *regs,
+			      struct kprobe_ctlblk *kcb)
+{
+	unsigned long copy_ip = (unsigned long)p->ainsn.insn;
+	unsigned long orig_ip = (unsigned long)p->addr;
+
+	/* Restore saved interrupt flag and ip register */
+	regs->flags |= kcb->kprobe_saved_flags;
+	/* Note that regs->ip is executed int3 so must be a step back */
+	regs->ip += (orig_ip - copy_ip) - INT3_INSN_SIZE;
+}
+NOKPROBE_SYMBOL(resume_singlestep);
 
 /*
  * We have reentered the kprobe_handler(), since another probe was hit while
@@ -674,6 +947,12 @@
 	return 1;
 }
 NOKPROBE_SYMBOL(reenter_kprobe);
+
+static nokprobe_inline int kprobe_is_ss(struct kprobe_ctlblk *kcb)
+{
+	return (kcb->kprobe_status == KPROBE_HIT_SS ||
+		kcb->kprobe_status == KPROBE_REENTER);
+}
 
 /*
  * Interrupts are disabled on entry as trap3 is an interrupt gate and they
@@ -719,7 +998,18 @@
 				reset_current_kprobe();
 			return 1;
 		}
-	} else if (*addr != INT3_INSN_OPCODE) {
+	} else if (kprobe_is_ss(kcb)) {
+		p = kprobe_running();
+		if ((unsigned long)p->ainsn.insn < regs->ip &&
+		    (unsigned long)p->ainsn.insn + MAX_INSN_SIZE > regs->ip) {
+			/* Most provably this is the second int3 for singlestep */
+			resume_singlestep(p, regs, kcb);
+			kprobe_post_process(p, regs, kcb);
+			return 1;
+		}
+	}
+
+	if (*addr != INT3_INSN_OPCODE) {
 		/*
 		 * The breakpoint instruction was removed right
 		 * after we hit it.  Another cpu has removed
@@ -792,135 +1082,6 @@
 }
 NOKPROBE_SYMBOL(trampoline_handler);
 
-/*
- * Called after single-stepping.  p->addr is the address of the
- * instruction whose first byte has been replaced by the "int 3"
- * instruction.  To avoid the SMP problems that can occur when we
- * temporarily put back the original opcode to single-step, we
- * single-stepped a copy of the instruction.  The address of this
- * copy is p->ainsn.insn.
- *
- * This function prepares to return from the post-single-step
- * interrupt.  We have to fix up the stack as follows:
- *
- * 0) Except in the case of absolute or indirect jump or call instructions,
- * the new ip is relative to the copied instruction.  We need to make
- * it relative to the original instruction.
- *
- * 1) If the single-stepped instruction was pushfl, then the TF and IF
- * flags are set in the just-pushed flags, and may need to be cleared.
- *
- * 2) If the single-stepped instruction was a call, the return address
- * that is atop the stack is the address following the copied instruction.
- * We need to make it the address following the original instruction.
- *
- * If this is the first time we've single-stepped the instruction at
- * this probepoint, and the instruction is boostable, boost it: add a
- * jump instruction after the copied instruction, that jumps to the next
- * instruction after the probepoint.
- */
-static void resume_execution(struct kprobe *p, struct pt_regs *regs,
-			     struct kprobe_ctlblk *kcb)
-{
-	unsigned long *tos = stack_addr(regs);
-	unsigned long copy_ip = (unsigned long)p->ainsn.insn;
-	unsigned long orig_ip = (unsigned long)p->addr;
-	kprobe_opcode_t *insn = p->ainsn.insn;
-
-	/* Skip prefixes */
-	insn = skip_prefixes(insn);
-
-	regs->flags &= ~X86_EFLAGS_TF;
-	switch (*insn) {
-	case 0x9c:	/* pushfl */
-		*tos &= ~(X86_EFLAGS_TF | X86_EFLAGS_IF);
-		*tos |= kcb->kprobe_old_flags;
-		break;
-	case 0xc2:	/* iret/ret/lret */
-	case 0xc3:
-	case 0xca:
-	case 0xcb:
-	case 0xcf:
-	case 0xea:	/* jmp absolute -- ip is correct */
-		/* ip is already adjusted, no more changes required */
-		p->ainsn.boostable = true;
-		goto no_change;
-	case 0xe8:	/* call relative - Fix return addr */
-		*tos = orig_ip + (*tos - copy_ip);
-		break;
-#ifdef CONFIG_X86_32
-	case 0x9a:	/* call absolute -- same as call absolute, indirect */
-		*tos = orig_ip + (*tos - copy_ip);
-		goto no_change;
-#endif
-	case 0xff:
-		if ((insn[1] & 0x30) == 0x10) {
-			/*
-			 * call absolute, indirect
-			 * Fix return addr; ip is correct.
-			 * But this is not boostable
-			 */
-			*tos = orig_ip + (*tos - copy_ip);
-			goto no_change;
-		} else if (((insn[1] & 0x31) == 0x20) ||
-			   ((insn[1] & 0x31) == 0x21)) {
-			/*
-			 * jmp near and far, absolute indirect
-			 * ip is correct. And this is boostable
-			 */
-			p->ainsn.boostable = true;
-			goto no_change;
-		}
-	default:
-		break;
-	}
-
-	regs->ip += orig_ip - copy_ip;
-
-no_change:
-	restore_btf();
-}
-NOKPROBE_SYMBOL(resume_execution);
-
-/*
- * Interrupts are disabled on entry as trap1 is an interrupt gate and they
- * remain disabled throughout this function.
- */
-int kprobe_debug_handler(struct pt_regs *regs)
-{
-	struct kprobe *cur = kprobe_running();
-	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
-
-	if (!cur)
-		return 0;
-
-	resume_execution(cur, regs, kcb);
-	regs->flags |= kcb->kprobe_saved_flags;
-
-	if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
-		kcb->kprobe_status = KPROBE_HIT_SSDONE;
-		cur->post_handler(cur, regs, 0);
-	}
-
-	/* Restore back the original saved kprobes variables and continue. */
-	if (kcb->kprobe_status == KPROBE_REENTER) {
-		restore_previous_kprobe(kcb);
-		goto out;
-	}
-	reset_current_kprobe();
-out:
-	/*
-	 * if somebody else is singlestepping across a probe point, flags
-	 * will have TF set, in which case, continue the remaining processing
-	 * of do_debug, as if this is not a probe hit.
-	 */
-	if (regs->flags & X86_EFLAGS_TF)
-		return 0;
-
-	return 1;
-}
-NOKPROBE_SYMBOL(kprobe_debug_handler);
-
 int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
 	struct kprobe *cur = kprobe_running();
@@ -938,20 +1099,9 @@
 		 * normal page fault.
 		 */
 		regs->ip = (unsigned long)cur->addr;
-		/*
-		 * Trap flag (TF) has been set here because this fault
-		 * happened where the single stepping will be done.
-		 * So clear it by resetting the current kprobe:
-		 */
-		regs->flags &= ~X86_EFLAGS_TF;
-		/*
-		 * Since the single step (trap) has been cancelled,
-		 * we need to restore BTF here.
-		 */
-		restore_btf();
 
 		/*
-		 * If the TF flag was set before the kprobe hit,
+		 * If the IF flag was set before the kprobe hit,
 		 * don't touch it:
 		 */
 		regs->flags |= kcb->kprobe_old_flags;
diff --git a/kernel/arch/x86/kernel/kprobes/opt.c b/kernel/arch/x86/kernel/kprobes/opt.c
index 50d656d..7afaa4c 100644
--- a/kernel/arch/x86/kernel/kprobes/opt.c
+++ b/kernel/arch/x86/kernel/kprobes/opt.c
@@ -15,6 +15,7 @@
 #include <linux/extable.h>
 #include <linux/kdebug.h>
 #include <linux/kallsyms.h>
+#include <linux/kgdb.h>
 #include <linux/ftrace.h>
 #include <linux/objtool.h>
 #include <linux/pgtable.h>
@@ -45,8 +46,8 @@
 		/* This function only handles jump-optimized kprobe */
 		if (kp && kprobe_optimized(kp)) {
 			op = container_of(kp, struct optimized_kprobe, kp);
-			/* If op->list is not empty, op is under optimizing */
-			if (list_empty(&op->list))
+			/* If op is optimized or under unoptimizing */
+			if (list_empty(&op->list) || optprobe_queued_unopt(op))
 				goto found;
 		}
 	}
@@ -277,19 +278,6 @@
 	return ret;
 }
 
-static bool is_padding_int3(unsigned long addr, unsigned long eaddr)
-{
-	unsigned char ops;
-
-	for (; addr < eaddr; addr++) {
-		if (get_kernel_nofault(ops, (void *)addr) < 0 ||
-		    ops != INT3_INSN_OPCODE)
-			return false;
-	}
-
-	return true;
-}
-
 /* Decode whole function to ensure any instructions don't jump into target */
 static int can_optimize(unsigned long paddr)
 {
@@ -317,6 +305,8 @@
 	addr = paddr - offset;
 	while (addr < paddr - offset + size) { /* Decode until function end */
 		unsigned long recovered_insn;
+		int ret;
+
 		if (search_exception_tables(addr))
 			/*
 			 * Since some fixup code will jumps into this function,
@@ -326,16 +316,19 @@
 		recovered_insn = recover_probed_instruction(buf, addr);
 		if (!recovered_insn)
 			return 0;
-		kernel_insn_init(&insn, (void *)recovered_insn, MAX_INSN_SIZE);
-		insn_get_length(&insn);
-		/*
-		 * In the case of detecting unknown breakpoint, this could be
-		 * a padding INT3 between functions. Let's check that all the
-		 * rest of the bytes are also INT3.
-		 */
-		if (insn.opcode.bytes[0] == INT3_INSN_OPCODE)
-			return is_padding_int3(addr, paddr - offset + size) ? 1 : 0;
 
+		ret = insn_decode(&insn, (void *)recovered_insn, MAX_INSN_SIZE, INSN_MODE_KERN);
+		if (ret < 0)
+			return 0;
+#ifdef CONFIG_KGDB
+		/*
+		 * If there is a dynamically installed kgdb sw breakpoint,
+		 * this function should not be probed.
+		 */
+		if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
+		    kgdb_has_hit_break(addr))
+			return 0;
+#endif
 		/* Recover address */
 		insn.kaddr = (void *)addr;
 		insn.next_byte = (void *)(addr + insn.length);
@@ -358,7 +351,7 @@
 
 	for (i = 1; i < op->optinsn.size; i++) {
 		p = get_kprobe(op->kp.addr + i);
-		if (p && !kprobe_disabled(p))
+		if (p && !kprobe_disarmed(p))
 			return -EEXIST;
 	}
 
diff --git a/kernel/arch/x86/kernel/process.c b/kernel/arch/x86/kernel/process.c
index 5e17c39..1cba09a 100644
--- a/kernel/arch/x86/kernel/process.c
+++ b/kernel/arch/x86/kernel/process.c
@@ -720,7 +720,7 @@
 }
 #endif
 
-void stop_this_cpu(void *dummy)
+void __noreturn stop_this_cpu(void *dummy)
 {
 	local_irq_disable();
 	/*
diff --git a/kernel/arch/x86/kernel/process_32.c b/kernel/arch/x86/kernel/process_32.c
index 98bf8fd..3b4c394 100644
--- a/kernel/arch/x86/kernel/process_32.c
+++ b/kernel/arch/x86/kernel/process_32.c
@@ -214,7 +214,7 @@
 	switch_fpu_finish(next_p);
 
 	/* Load the Intel cache allocation PQR MSR. */
-	resctrl_sched_in();
+	resctrl_sched_in(next_p);
 
 	return prev_p;
 }
diff --git a/kernel/arch/x86/kernel/process_64.c b/kernel/arch/x86/kernel/process_64.c
index ad3f82a..1d8bc47 100644
--- a/kernel/arch/x86/kernel/process_64.c
+++ b/kernel/arch/x86/kernel/process_64.c
@@ -629,7 +629,7 @@
 	}
 
 	/* Load the Intel cache allocation PQR MSR. */
-	resctrl_sched_in();
+	resctrl_sched_in(next_p);
 
 	return prev_p;
 }
diff --git a/kernel/arch/x86/kernel/reboot.c b/kernel/arch/x86/kernel/reboot.c
index df35148..4d8c0e2 100644
--- a/kernel/arch/x86/kernel/reboot.c
+++ b/kernel/arch/x86/kernel/reboot.c
@@ -528,33 +528,29 @@
 	}
 }
 
-static void vmxoff_nmi(int cpu, struct pt_regs *regs)
-{
-	cpu_emergency_vmxoff();
-}
+static inline void nmi_shootdown_cpus_on_restart(void);
 
-/* Use NMIs as IPIs to tell all CPUs to disable virtualization */
-static void emergency_vmx_disable_all(void)
+static void emergency_reboot_disable_virtualization(void)
 {
 	/* Just make sure we won't change CPUs while doing this */
 	local_irq_disable();
 
 	/*
-	 * Disable VMX on all CPUs before rebooting, otherwise we risk hanging
-	 * the machine, because the CPU blocks INIT when it's in VMX root.
+	 * Disable virtualization on all CPUs before rebooting to avoid hanging
+	 * the system, as VMX and SVM block INIT when running in the host.
 	 *
 	 * We can't take any locks and we may be on an inconsistent state, so
-	 * use NMIs as IPIs to tell the other CPUs to exit VMX root and halt.
+	 * use NMIs as IPIs to tell the other CPUs to disable VMX/SVM and halt.
 	 *
-	 * Do the NMI shootdown even if VMX if off on _this_ CPU, as that
-	 * doesn't prevent a different CPU from being in VMX root operation.
+	 * Do the NMI shootdown even if virtualization is off on _this_ CPU, as
+	 * other CPUs may have virtualization enabled.
 	 */
-	if (cpu_has_vmx()) {
-		/* Safely force _this_ CPU out of VMX root operation. */
-		__cpu_emergency_vmxoff();
+	if (cpu_has_vmx() || cpu_has_svm(NULL)) {
+		/* Safely force _this_ CPU out of VMX/SVM operation. */
+		cpu_emergency_disable_virtualization();
 
-		/* Halt and exit VMX root operation on the other CPUs. */
-		nmi_shootdown_cpus(vmxoff_nmi);
+		/* Disable VMX/SVM and halt on other CPUs. */
+		nmi_shootdown_cpus_on_restart();
 	}
 }
 
@@ -590,7 +586,7 @@
 	unsigned short mode;
 
 	if (reboot_emergency)
-		emergency_vmx_disable_all();
+		emergency_reboot_disable_virtualization();
 
 	tboot_shutdown(TB_SHUTDOWN_REBOOT);
 
@@ -795,6 +791,17 @@
 /* This is the CPU performing the emergency shutdown work. */
 int crashing_cpu = -1;
 
+/*
+ * Disable virtualization, i.e. VMX or SVM, to ensure INIT is recognized during
+ * reboot.  VMX blocks INIT if the CPU is post-VMXON, and SVM blocks INIT if
+ * GIF=0, i.e. if the crash occurred between CLGI and STGI.
+ */
+void cpu_emergency_disable_virtualization(void)
+{
+	cpu_emergency_vmxoff();
+	cpu_emergency_svm_disable();
+}
+
 #if defined(CONFIG_SMP)
 
 static nmi_shootdown_cb shootdown_callback;
@@ -817,7 +824,14 @@
 		return NMI_HANDLED;
 	local_irq_disable();
 
-	shootdown_callback(cpu, regs);
+	if (shootdown_callback)
+		shootdown_callback(cpu, regs);
+
+	/*
+	 * Prepare the CPU for reboot _after_ invoking the callback so that the
+	 * callback can safely use virtualization instructions, e.g. VMCLEAR.
+	 */
+	cpu_emergency_disable_virtualization();
 
 	atomic_dec(&waiting_for_crash_ipi);
 	/* Assume hlt works */
@@ -828,17 +842,31 @@
 	return NMI_HANDLED;
 }
 
-/*
- * Halt all other CPUs, calling the specified function on each of them
+/**
+ * nmi_shootdown_cpus - Stop other CPUs via NMI
+ * @callback:	Optional callback to be invoked from the NMI handler
  *
- * This function can be used to halt all other CPUs on crash
- * or emergency reboot time. The function passed as parameter
- * will be called inside a NMI handler on all CPUs.
+ * The NMI handler on the remote CPUs invokes @callback, if not
+ * NULL, first and then disables virtualization to ensure that
+ * INIT is recognized during reboot.
+ *
+ * nmi_shootdown_cpus() can only be invoked once. After the first
+ * invocation all other CPUs are stuck in crash_nmi_callback() and
+ * cannot respond to a second NMI.
  */
 void nmi_shootdown_cpus(nmi_shootdown_cb callback)
 {
 	unsigned long msecs;
+
 	local_irq_disable();
+
+	/*
+	 * Avoid certain doom if a shootdown already occurred; re-registering
+	 * the NMI handler will cause list corruption, modifying the callback
+	 * will do who knows what, etc...
+	 */
+	if (WARN_ON_ONCE(crash_ipi_issued))
+		return;
 
 	/* Make a note of crashing cpu. Will be used in NMI callback. */
 	crashing_cpu = safe_smp_processor_id();
@@ -867,7 +895,17 @@
 		msecs--;
 	}
 
-	/* Leave the nmi callback set */
+	/*
+	 * Leave the nmi callback set, shootdown is a one-time thing.  Clearing
+	 * the callback could result in a NULL pointer dereference if a CPU
+	 * (finally) responds after the timeout expires.
+	 */
+}
+
+static inline void nmi_shootdown_cpus_on_restart(void)
+{
+	if (!crash_ipi_issued)
+		nmi_shootdown_cpus(NULL);
 }
 
 /*
@@ -897,6 +935,8 @@
 	/* No other CPUs to shoot down */
 }
 
+static inline void nmi_shootdown_cpus_on_restart(void) { }
+
 void run_crash_ipi_callback(struct pt_regs *regs)
 {
 }
diff --git a/kernel/arch/x86/kernel/smp.c b/kernel/arch/x86/kernel/smp.c
index eff4ce3..95758ae 100644
--- a/kernel/arch/x86/kernel/smp.c
+++ b/kernel/arch/x86/kernel/smp.c
@@ -32,7 +32,7 @@
 #include <asm/mce.h>
 #include <asm/trace/irq_vectors.h>
 #include <asm/kexec.h>
-#include <asm/virtext.h>
+#include <asm/reboot.h>
 
 /*
  *	Some notes on x86 processor bugs affecting SMP operation:
@@ -122,7 +122,7 @@
 	if (raw_smp_processor_id() == atomic_read(&stopping_cpu))
 		return NMI_HANDLED;
 
-	cpu_emergency_vmxoff();
+	cpu_emergency_disable_virtualization();
 	stop_this_cpu(NULL);
 
 	return NMI_HANDLED;
@@ -134,7 +134,7 @@
 DEFINE_IDTENTRY_SYSVEC(sysvec_reboot)
 {
 	ack_APIC_irq();
-	cpu_emergency_vmxoff();
+	cpu_emergency_disable_virtualization();
 	stop_this_cpu(NULL);
 }
 
diff --git a/kernel/arch/x86/kernel/smpboot.c b/kernel/arch/x86/kernel/smpboot.c
index e8e5515..d2403da 100644
--- a/kernel/arch/x86/kernel/smpboot.c
+++ b/kernel/arch/x86/kernel/smpboot.c
@@ -100,6 +100,17 @@
 DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
 EXPORT_PER_CPU_SYMBOL(cpu_info);
 
+struct mwait_cpu_dead {
+	unsigned int	control;
+	unsigned int	status;
+};
+
+/*
+ * Cache line aligned data for mwait_play_dead(). Separate on purpose so
+ * that it's unlikely to be touched by other CPUs.
+ */
+static DEFINE_PER_CPU_ALIGNED(struct mwait_cpu_dead, mwait_cpu_dead);
+
 /* Logical package management. We might want to allocate that dynamically */
 unsigned int __max_logical_packages __read_mostly;
 EXPORT_SYMBOL(__max_logical_packages);
@@ -227,8 +238,7 @@
 	load_cr3(swapper_pg_dir);
 	__flush_tlb_all();
 #endif
-	cpu_init_exception_handling();
-	cpu_init();
+	cpu_init_secondary();
 	rcu_cpu_starting(raw_smp_processor_id());
 	x86_cpuinit.early_percpu_clock_init();
 	smp_callin();
@@ -1675,10 +1685,10 @@
  */
 static inline void mwait_play_dead(void)
 {
+	struct mwait_cpu_dead *md = this_cpu_ptr(&mwait_cpu_dead);
 	unsigned int eax, ebx, ecx, edx;
 	unsigned int highest_cstate = 0;
 	unsigned int highest_subcstate = 0;
-	void *mwait_ptr;
 	int i;
 
 	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
@@ -1713,13 +1723,6 @@
 			(highest_subcstate - 1);
 	}
 
-	/*
-	 * This should be a memory location in a cache line which is
-	 * unlikely to be touched by other processors.  The actual
-	 * content is immaterial as it is not actually modified in any way.
-	 */
-	mwait_ptr = &current_thread_info()->flags;
-
 	wbinvd();
 
 	while (1) {
@@ -1731,9 +1734,9 @@
 		 * case where we return around the loop.
 		 */
 		mb();
-		clflush(mwait_ptr);
+		clflush(md);
 		mb();
-		__monitor(mwait_ptr, 0, 0);
+		__monitor(md, 0, 0);
 		mb();
 		__mwait(eax, 0);
 
diff --git a/kernel/arch/x86/kernel/static_call.c b/kernel/arch/x86/kernel/static_call.c
index 2973b3f..759b986 100644
--- a/kernel/arch/x86/kernel/static_call.c
+++ b/kernel/arch/x86/kernel/static_call.c
@@ -123,6 +123,19 @@
  */
 bool __static_call_fixup(void *tramp, u8 op, void *dest)
 {
+	unsigned long addr = (unsigned long)tramp;
+	/*
+	 * Not all .return_sites are a static_call trampoline (most are not).
+	 * Check if the 3 bytes after the return are still kernel text, if not,
+	 * then this definitely is not a trampoline and we need not worry
+	 * further.
+	 *
+	 * This avoids the memcmp() below tripping over pagefaults etc..
+	 */
+	if (((addr >> PAGE_SHIFT) != ((addr + 7) >> PAGE_SHIFT)) &&
+	    !kernel_text_address(addr + 7))
+		return false;
+
 	if (memcmp(tramp+5, tramp_ud, 3)) {
 		/* Not a trampoline site, not our problem. */
 		return false;
diff --git a/kernel/arch/x86/kernel/sysfb_efi.c b/kernel/arch/x86/kernel/sysfb_efi.c
index 653b7f6..fff04d2 100644
--- a/kernel/arch/x86/kernel/sysfb_efi.c
+++ b/kernel/arch/x86/kernel/sysfb_efi.c
@@ -264,6 +264,22 @@
 					"Lenovo ideapad D330-10IGM"),
 		},
 	},
+	{
+		/* Lenovo IdeaPad Duet 3 10IGL5 with 1200x1920 portrait screen */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_VERSION,
+					"IdeaPad Duet 3 10IGL5"),
+		},
+	},
+	{
+		/* Lenovo Yoga Book X91F / X91L */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			/* Non exact match to match F + L versions */
+			DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"),
+		},
+	},
 	{},
 };
 
diff --git a/kernel/arch/x86/kernel/traps.c b/kernel/arch/x86/kernel/traps.c
index 2a39a2d..98838b7 100644
--- a/kernel/arch/x86/kernel/traps.c
+++ b/kernel/arch/x86/kernel/traps.c
@@ -917,9 +917,6 @@
 	if ((dr6 & DR_STEP) && is_sysenter_singlestep(regs))
 		dr6 &= ~DR_STEP;
 
-	if (kprobe_debug_handler(regs))
-		goto out;
-
 	/*
 	 * The kernel doesn't use INT1
 	 */
@@ -1185,9 +1182,7 @@
 
 	idt_setup_traps();
 
-	/*
-	 * Should be a barrier for any external CPU state:
-	 */
+	cpu_init_exception_handling();
 	cpu_init();
 
 	idt_setup_ist_traps();
diff --git a/kernel/arch/x86/kernel/uprobes.c b/kernel/arch/x86/kernel/uprobes.c
index 138bdb1..9f948b2 100644
--- a/kernel/arch/x86/kernel/uprobes.c
+++ b/kernel/arch/x86/kernel/uprobes.c
@@ -722,8 +722,9 @@
 	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 @@
 			return -ENOTSUPP;
 	}
 
+setup:
 	auprobe->branch.opc1 = opc1;
 	auprobe->branch.ilen = insn->length;
 	auprobe->branch.offs = insn->immediate.value;
diff --git a/kernel/arch/x86/kernel/vmlinux.lds.S b/kernel/arch/x86/kernel/vmlinux.lds.S
index b36f5f4..b6729ca 100644
--- a/kernel/arch/x86/kernel/vmlinux.lds.S
+++ b/kernel/arch/x86/kernel/vmlinux.lds.S
@@ -133,7 +133,20 @@
 		LOCK_TEXT
 		KPROBES_TEXT
 		ALIGN_ENTRY_TEXT_BEGIN
+#ifdef CONFIG_CPU_SRSO
+		*(.text..__x86.rethunk_untrain)
+#endif
+
 		ENTRY_TEXT
+
+#ifdef CONFIG_CPU_SRSO
+		/*
+		 * See the comment above srso_alias_untrain_ret()'s
+		 * definition.
+		 */
+		. = srso_alias_untrain_ret | (1 << 2) | (1 << 8) | (1 << 14) | (1 << 20);
+		*(.text..__x86.rethunk_safe)
+#endif
 		ALIGN_ENTRY_TEXT_END
 		SOFTIRQENTRY_TEXT
 		STATIC_CALL_TEXT
@@ -142,13 +155,15 @@
 
 #ifdef CONFIG_RETPOLINE
 		__indirect_thunk_start = .;
-		*(.text.__x86.*)
+		*(.text..__x86.indirect_thunk)
+		*(.text..__x86.return_thunk)
 		__indirect_thunk_end = .;
 #endif
 	} :text =0xcccc
 
 	/* End of text section, which should occupy whole number of pages */
 	_etext = .;
+
 	. = ALIGN(PAGE_SIZE);
 
 	X86_ALIGN_RODATA_BEGIN
@@ -502,6 +517,27 @@
            "fixed_percpu_data is not at start of per-cpu area");
 #endif
 
+#ifdef CONFIG_RETHUNK
+. = ASSERT((retbleed_return_thunk & 0x3f) == 0, "retbleed_return_thunk not cacheline-aligned");
+. = ASSERT((srso_safe_ret & 0x3f) == 0, "srso_safe_ret not cacheline-aligned");
+#endif
+
+#ifdef CONFIG_CPU_SRSO
+/*
+ * GNU ld cannot do XOR until 2.41.
+ * https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=f6f78318fca803c4907fb8d7f6ded8295f1947b1
+ *
+ * LLVM lld cannot do XOR until lld-17.
+ * https://github.com/llvm/llvm-project/commit/fae96104d4378166cbe5c875ef8ed808a356f3fb
+ *
+ * Instead do: (A | B) - (A & B) in order to compute the XOR
+ * of the two function addresses:
+ */
+. = ASSERT(((ABSOLUTE(srso_alias_untrain_ret) | srso_alias_safe_ret) -
+		(ABSOLUTE(srso_alias_untrain_ret) & srso_alias_safe_ret)) == ((1 << 2) | (1 << 8) | (1 << 14) | (1 << 20)),
+		"SRSO function pair won't alias");
+#endif
+
 #endif /* CONFIG_X86_32 */
 
 #ifdef CONFIG_KEXEC_CORE
diff --git a/kernel/arch/x86/kernel/x86_init.c b/kernel/arch/x86/kernel/x86_init.c
index a3038d8..b758eee 100644
--- a/kernel/arch/x86/kernel/x86_init.c
+++ b/kernel/arch/x86/kernel/x86_init.c
@@ -32,8 +32,8 @@
 static void iommu_shutdown_noop(void) { }
 bool __init bool_x86_init_noop(void) { return false; }
 void x86_op_int_noop(int cpu) { }
-static __init int set_rtc_noop(const struct timespec64 *now) { return -EINVAL; }
-static __init void get_rtc_noop(struct timespec64 *now) { }
+static int set_rtc_noop(const struct timespec64 *now) { return -EINVAL; }
+static void get_rtc_noop(struct timespec64 *now) { }
 
 static __initconst const struct of_device_id of_cmos_match[] = {
 	{ .compatible = "motorola,mc146818" },
diff --git a/kernel/arch/x86/kvm/cpuid.c b/kernel/arch/x86/kvm/cpuid.c
index 06a776f..8b07e48 100644
--- a/kernel/arch/x86/kvm/cpuid.c
+++ b/kernel/arch/x86/kvm/cpuid.c
@@ -491,6 +491,9 @@
 	    !boot_cpu_has(X86_FEATURE_AMD_SSBD))
 		kvm_cpu_cap_set(X86_FEATURE_VIRT_SSBD);
 
+	if (cpu_feature_enabled(X86_FEATURE_SRSO_NO))
+		kvm_cpu_cap_set(X86_FEATURE_SRSO_NO);
+
 	/*
 	 * Hide all SVM features by default, SVM will set the cap bits for
 	 * features it emulates and/or exposes for L1.
@@ -511,15 +514,21 @@
 	int nent;
 };
 
-static struct kvm_cpuid_entry2 *do_host_cpuid(struct kvm_cpuid_array *array,
-					      u32 function, u32 index)
+static struct kvm_cpuid_entry2 *get_next_cpuid(struct kvm_cpuid_array *array)
 {
-	struct kvm_cpuid_entry2 *entry;
-
 	if (array->nent >= array->maxnent)
 		return NULL;
 
-	entry = &array->entries[array->nent++];
+	return &array->entries[array->nent++];
+}
+
+static struct kvm_cpuid_entry2 *do_host_cpuid(struct kvm_cpuid_array *array,
+					      u32 function, u32 index)
+{
+	struct kvm_cpuid_entry2 *entry = get_next_cpuid(array);
+
+	if (!entry)
+		return NULL;
 
 	entry->function = function;
 	entry->index = index;
@@ -698,22 +707,13 @@
 		entry->edx = edx.full;
 		break;
 	}
-	/*
-	 * Per Intel's SDM, the 0x1f is a superset of 0xb,
-	 * thus they can be handled by common code.
-	 */
 	case 0x1f:
 	case 0xb:
 		/*
-		 * Populate entries until the level type (ECX[15:8]) of the
-		 * previous entry is zero.  Note, CPUID EAX.{0x1f,0xb}.0 is
-		 * the starting entry, filled by the primary do_host_cpuid().
+		 * No topology; a valid topology is indicated by the presence
+		 * of subleaf 1.
 		 */
-		for (i = 1; entry->ecx & 0xff00; ++i) {
-			entry = do_host_cpuid(array, function, i);
-			if (!entry)
-				goto out;
-		}
+		entry->eax = entry->ebx = entry->ecx = 0;
 		break;
 	case 0xd:
 		entry->eax &= supported_xcr0;
@@ -866,6 +866,9 @@
 		entry->ebx = entry->ecx = entry->edx = 0;
 		break;
 	case 0x8000001e:
+		/* Do not return host topology information.  */
+		entry->eax = entry->ebx = entry->ecx = 0;
+		entry->edx = 0; /* reserved */
 		break;
 	/* Support memory encryption cpuid if host supports it */
 	case 0x8000001F:
diff --git a/kernel/arch/x86/kvm/cpuid.h b/kernel/arch/x86/kvm/cpuid.h
index dc921d7..1ba9313 100644
--- a/kernel/arch/x86/kvm/cpuid.h
+++ b/kernel/arch/x86/kvm/cpuid.h
@@ -63,6 +63,7 @@
 	[CPUID_8000_0007_EBX] = {0x80000007, 0, CPUID_EBX},
 	[CPUID_7_EDX]         = {         7, 0, CPUID_EDX},
 	[CPUID_7_1_EAX]       = {         7, 1, CPUID_EAX},
+	[CPUID_8000_0021_EAX] = {0x80000021, 0, CPUID_EAX},
 };
 
 /*
diff --git a/kernel/arch/x86/kvm/hyperv.c b/kernel/arch/x86/kvm/hyperv.c
index 09ec1cd..e03e320 100644
--- a/kernel/arch/x86/kvm/hyperv.c
+++ b/kernel/arch/x86/kvm/hyperv.c
@@ -1562,16 +1562,19 @@
 
 	cpumask_clear(&hv_vcpu->tlb_flush);
 
-	vcpu_mask = all_cpus ? NULL :
-		sparse_set_to_vcpu_mask(kvm, sparse_banks, valid_bank_mask,
-					vp_bitmap, vcpu_bitmap);
-
 	/*
 	 * vcpu->arch.cr3 may not be up-to-date for running vCPUs so we can't
 	 * analyze it here, flush TLB regardless of the specified address space.
 	 */
-	kvm_make_vcpus_request_mask(kvm, KVM_REQ_TLB_FLUSH_GUEST,
-				    NULL, vcpu_mask, &hv_vcpu->tlb_flush);
+	if (all_cpus) {
+		kvm_make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH_GUEST);
+	} else {
+		vcpu_mask = sparse_set_to_vcpu_mask(kvm, sparse_banks, valid_bank_mask,
+						    vp_bitmap, vcpu_bitmap);
+
+		kvm_make_vcpus_request_mask(kvm, KVM_REQ_TLB_FLUSH_GUEST,
+					    NULL, vcpu_mask, &hv_vcpu->tlb_flush);
+	}
 
 ret_success:
 	/* We always do full TLB flush, set rep_done = rep_cnt. */
diff --git a/kernel/arch/x86/kvm/lapic.c b/kernel/arch/x86/kvm/lapic.c
index 260727e..2118980 100644
--- a/kernel/arch/x86/kvm/lapic.c
+++ b/kernel/arch/x86/kvm/lapic.c
@@ -2115,10 +2115,14 @@
 		break;
 
 	case APIC_SELF_IPI:
-		if (apic_x2apic_mode(apic))
-			kvm_apic_send_ipi(apic, APIC_DEST_SELF | (val & APIC_VECTOR_MASK), 0);
-		else
+		/*
+		 * Self-IPI exists only when x2APIC is enabled.  Bits 7:0 hold
+		 * the vector, everything else is reserved.
+		 */
+		if (!apic_x2apic_mode(apic) || (val & ~APIC_VECTOR_MASK))
 			ret = 1;
+		else
+			kvm_apic_send_ipi(apic, APIC_DEST_SELF | val, 0);
 		break;
 	default:
 		ret = 1;
diff --git a/kernel/arch/x86/kvm/svm/svm.c b/kernel/arch/x86/kvm/svm/svm.c
index c34ba03..1616e39 100644
--- a/kernel/arch/x86/kvm/svm/svm.c
+++ b/kernel/arch/x86/kvm/svm/svm.c
@@ -1392,7 +1392,9 @@
 
 	if (sd->current_vmcb != svm->vmcb) {
 		sd->current_vmcb = svm->vmcb;
-		indirect_branch_prediction_barrier();
+
+		if (!cpu_feature_enabled(X86_FEATURE_IBPB_ON_VMEXIT))
+			indirect_branch_prediction_barrier();
 	}
 	avic_vcpu_load(vcpu, cpu);
 }
@@ -3374,6 +3376,7 @@
 
 static void svm_prepare_guest_switch(struct kvm_vcpu *vcpu)
 {
+	amd_clear_divider();
 }
 
 static inline void sync_cr8_to_lapic(struct kvm_vcpu *vcpu)
@@ -3480,8 +3483,14 @@
 
 static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu)
 {
-	if (to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_MSR &&
-	    to_svm(vcpu)->vmcb->control.exit_info_1)
+	struct vmcb_control_area *control = &to_svm(vcpu)->vmcb->control;
+
+	/*
+	 * Note, the next RIP must be provided as SRCU isn't held, i.e. KVM
+	 * can't read guest memory (dereference memslots) to decode the WRMSR.
+	 */
+	if (control->exit_code == SVM_EXIT_MSR && control->exit_info_1 &&
+	    nrips && control->next_rip)
 		return handle_fastpath_set_msr_irqoff(vcpu);
 
 	return EXIT_FASTPATH_NONE;
@@ -3977,6 +3986,8 @@
 
 static void svm_handle_exit_irqoff(struct kvm_vcpu *vcpu)
 {
+	if (to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_INTR)
+		vcpu->arch.at_instruction_boundary = true;
 }
 
 static void svm_sched_in(struct kvm_vcpu *vcpu, int cpu)
diff --git a/kernel/arch/x86/kvm/svm/vmenter.S b/kernel/arch/x86/kvm/svm/vmenter.S
index c18d812..a8859c1 100644
--- a/kernel/arch/x86/kvm/svm/vmenter.S
+++ b/kernel/arch/x86/kvm/svm/vmenter.S
@@ -137,6 +137,9 @@
 	 */
 	UNTRAIN_RET
 
+	/* SRSO */
+	ALTERNATIVE "", "call entry_ibpb", X86_FEATURE_IBPB_ON_VMEXIT
+
 	/*
 	 * Clear all general purpose registers except RSP and RAX to prevent
 	 * speculative use of the guest's values, even those that are reloaded
diff --git a/kernel/arch/x86/kvm/vmx/evmcs.h b/kernel/arch/x86/kvm/vmx/evmcs.h
index 011929a..9180155 100644
--- a/kernel/arch/x86/kvm/vmx/evmcs.h
+++ b/kernel/arch/x86/kvm/vmx/evmcs.h
@@ -166,16 +166,6 @@
 	return *(u16 *)((char *)current_evmcs + offset);
 }
 
-static inline void evmcs_touch_msr_bitmap(void)
-{
-	if (unlikely(!current_evmcs))
-		return;
-
-	if (current_evmcs->hv_enlightenments_control.msr_bitmap)
-		current_evmcs->hv_clean_fields &=
-			~HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP;
-}
-
 static inline void evmcs_load(u64 phys_addr)
 {
 	struct hv_vp_assist_page *vp_ap =
@@ -196,7 +186,6 @@
 static inline u32 evmcs_read32(unsigned long field) { return 0; }
 static inline u16 evmcs_read16(unsigned long field) { return 0; }
 static inline void evmcs_load(u64 phys_addr) {}
-static inline void evmcs_touch_msr_bitmap(void) {}
 #endif /* IS_ENABLED(CONFIG_HYPERV) */
 
 enum nested_evmptrld_status {
diff --git a/kernel/arch/x86/kvm/vmx/nested.c b/kernel/arch/x86/kvm/vmx/nested.c
index 498fed0..c165ddb 100644
--- a/kernel/arch/x86/kvm/vmx/nested.c
+++ b/kernel/arch/x86/kvm/vmx/nested.c
@@ -2998,7 +2998,7 @@
 					struct vmcs12 *vmcs12,
 					enum vm_entry_failure_code *entry_failure_code)
 {
-	bool ia32e;
+	bool ia32e = !!(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE);
 
 	*entry_failure_code = ENTRY_FAIL_DEFAULT;
 
@@ -3024,6 +3024,13 @@
 					   vmcs12->guest_ia32_perf_global_ctrl)))
 		return -EINVAL;
 
+	if (CC((vmcs12->guest_cr0 & (X86_CR0_PG | X86_CR0_PE)) == X86_CR0_PG))
+		return -EINVAL;
+
+	if (CC(ia32e && !(vmcs12->guest_cr4 & X86_CR4_PAE)) ||
+	    CC(ia32e && !(vmcs12->guest_cr0 & X86_CR0_PG)))
+		return -EINVAL;
+
 	/*
 	 * If the load IA32_EFER VM-entry control is 1, the following checks
 	 * are performed on the field for the IA32_EFER MSR:
@@ -3035,7 +3042,6 @@
 	 */
 	if (to_vmx(vcpu)->nested.nested_run_pending &&
 	    (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_EFER)) {
-		ia32e = (vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) != 0;
 		if (CC(!kvm_valid_efer(vcpu, vmcs12->guest_ia32_efer)) ||
 		    CC(ia32e != !!(vmcs12->guest_ia32_efer & EFER_LMA)) ||
 		    CC(((vmcs12->guest_cr0 & X86_CR0_PG) &&
@@ -4556,6 +4562,17 @@
 
 	vmx_switch_vmcs(vcpu, &vmx->vmcs01);
 
+	/*
+	 * If IBRS is advertised to the vCPU, KVM must flush the indirect
+	 * branch predictors when transitioning from L2 to L1, as L1 expects
+	 * hardware (KVM in this case) to provide separate predictor modes.
+	 * Bare metal isolates VMX root (host) from VMX non-root (guest), but
+	 * doesn't isolate different VMCSs, i.e. in this case, doesn't provide
+	 * separate modes for L2 vs L1.
+	 */
+	if (guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL))
+		indirect_branch_prediction_barrier();
+
 	/* Update any VMCS fields that might have changed while L2 ran */
 	vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, vmx->msr_autoload.host.nr);
 	vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, vmx->msr_autoload.guest.nr);
@@ -4901,24 +4918,35 @@
 		| FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX;
 
 	/*
-	 * Note, KVM cannot rely on hardware to perform the CR0/CR4 #UD checks
-	 * that have higher priority than VM-Exit (see Intel SDM's pseudocode
-	 * for VMXON), as KVM must load valid CR0/CR4 values into hardware while
-	 * running the guest, i.e. KVM needs to check the _guest_ values.
+	 * Manually check CR4.VMXE checks, KVM must force CR4.VMXE=1 to enter
+	 * the guest and so cannot rely on hardware to perform the check,
+	 * which has higher priority than VM-Exit (see Intel SDM's pseudocode
+	 * for VMXON).
 	 *
-	 * Rely on hardware for the other two pre-VM-Exit checks, !VM86 and
-	 * !COMPATIBILITY modes.  KVM may run the guest in VM86 to emulate Real
-	 * Mode, but KVM will never take the guest out of those modes.
+	 * Rely on hardware for the other pre-VM-Exit checks, CR0.PE=1, !VM86
+	 * and !COMPATIBILITY modes.  For an unrestricted guest, KVM doesn't
+	 * force any of the relevant guest state.  For a restricted guest, KVM
+	 * does force CR0.PE=1, but only to also force VM86 in order to emulate
+	 * Real Mode, and so there's no need to check CR0.PE manually.
 	 */
-	if (!nested_host_cr0_valid(vcpu, kvm_read_cr0(vcpu)) ||
-	    !nested_host_cr4_valid(vcpu, kvm_read_cr4(vcpu))) {
+	if (!kvm_read_cr4_bits(vcpu, X86_CR4_VMXE)) {
 		kvm_queue_exception(vcpu, UD_VECTOR);
 		return 1;
 	}
 
 	/*
-	 * CPL=0 and all other checks that are lower priority than VM-Exit must
-	 * be checked manually.
+	 * The CPL is checked for "not in VMX operation" and for "in VMX root",
+	 * and has higher priority than the VM-Fail due to being post-VMXON,
+	 * i.e. VMXON #GPs outside of VMX non-root if CPL!=0.  In VMX non-root,
+	 * VMXON causes VM-Exit and KVM unconditionally forwards VMXON VM-Exits
+	 * from L2 to L1, i.e. there's no need to check for the vCPU being in
+	 * VMX non-root.
+	 *
+	 * Forwarding the VM-Exit unconditionally, i.e. without performing the
+	 * #UD checks (see above), is functionally ok because KVM doesn't allow
+	 * L1 to run L2 without CR4.VMXE=0, and because KVM never modifies L2's
+	 * CR0 or CR4, i.e. it's L2's responsibility to emulate #UDs that are
+	 * missed by hardware due to shadowing CR0 and/or CR4.
 	 */
 	if (vmx_get_cpl(vcpu)) {
 		kvm_inject_gp(vcpu, 0);
@@ -4928,6 +4956,17 @@
 	if (vmx->nested.vmxon)
 		return nested_vmx_fail(vcpu, VMXERR_VMXON_IN_VMX_ROOT_OPERATION);
 
+	/*
+	 * Invalid CR0/CR4 generates #GP.  These checks are performed if and
+	 * only if the vCPU isn't already in VMX operation, i.e. effectively
+	 * have lower priority than the VM-Fail above.
+	 */
+	if (!nested_host_cr0_valid(vcpu, kvm_read_cr0(vcpu)) ||
+	    !nested_host_cr4_valid(vcpu, kvm_read_cr4(vcpu))) {
+		kvm_inject_gp(vcpu, 0);
+		return 1;
+	}
+
 	if ((vmx->msr_ia32_feature_control & VMXON_NEEDED_FEATURES)
 			!= VMXON_NEEDED_FEATURES) {
 		kvm_inject_gp(vcpu, 0);
diff --git a/kernel/arch/x86/kvm/vmx/vmx.c b/kernel/arch/x86/kvm/vmx/vmx.c
index af6742d..2445c61 100644
--- a/kernel/arch/x86/kvm/vmx/vmx.c
+++ b/kernel/arch/x86/kvm/vmx/vmx.c
@@ -135,8 +135,7 @@
 #define KVM_VM_CR0_ALWAYS_OFF (X86_CR0_NW | X86_CR0_CD)
 #define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST X86_CR0_NE
 #define KVM_VM_CR0_ALWAYS_ON				\
-	(KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | 	\
-	 X86_CR0_WP | X86_CR0_PG | X86_CR0_PE)
+	(KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
 
 #define KVM_VM_CR4_ALWAYS_ON_UNRESTRICTED_GUEST X86_CR4_VMXE
 #define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE)
@@ -1431,8 +1430,10 @@
 
 		/*
 		 * No indirect branch prediction barrier needed when switching
-		 * the active VMCS within a guest, e.g. on nested VM-Enter.
-		 * The L1 VMM can protect itself with retpolines, IBPB or IBRS.
+		 * the active VMCS within a vCPU, unless IBRS is advertised to
+		 * the vCPU.  To minimize the number of IBPBs executed, KVM
+		 * performs IBPB on nested VM-Exit (a single nested transition
+		 * may switch the active VMCS multiple times).
 		 */
 		if (!buddy || WARN_ON_ONCE(buddy->vmcs != prev))
 			indirect_branch_prediction_barrier();
@@ -1518,6 +1519,11 @@
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	unsigned long old_rflags;
 
+	/*
+	 * Unlike CR0 and CR4, RFLAGS handling requires checking if the vCPU
+	 * is an unrestricted guest in order to mark L2 as needing emulation
+	 * if L1 runs L2 as a restricted guest.
+	 */
 	if (is_unrestricted_guest(vcpu)) {
 		kvm_register_mark_available(vcpu, VCPU_EXREG_RFLAGS);
 		vmx->rflags = rflags;
@@ -2723,15 +2729,6 @@
 		if (!loaded_vmcs->msr_bitmap)
 			goto out_vmcs;
 		memset(loaded_vmcs->msr_bitmap, 0xff, PAGE_SIZE);
-
-		if (IS_ENABLED(CONFIG_HYPERV) &&
-		    static_branch_unlikely(&enable_evmcs) &&
-		    (ms_hyperv.nested_features & HV_X64_NESTED_MSR_BITMAP)) {
-			struct hv_enlightened_vmcs *evmcs =
-				(struct hv_enlightened_vmcs *)loaded_vmcs->vmcs;
-
-			evmcs->hv_enlightenments_control.msr_bitmap = 1;
-		}
 	}
 
 	memset(&loaded_vmcs->host_state, 0, sizeof(struct vmcs_host_state));
@@ -3071,42 +3068,22 @@
 	kvm_register_mark_dirty(vcpu, VCPU_EXREG_PDPTR);
 }
 
-static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
-					unsigned long cr0,
-					struct kvm_vcpu *vcpu)
-{
-	struct vcpu_vmx *vmx = to_vmx(vcpu);
-
-	if (!kvm_register_is_available(vcpu, VCPU_EXREG_CR3))
-		vmx_cache_reg(vcpu, VCPU_EXREG_CR3);
-	if (!(cr0 & X86_CR0_PG)) {
-		/* From paging/starting to nonpaging */
-		exec_controls_setbit(vmx, CPU_BASED_CR3_LOAD_EXITING |
-					  CPU_BASED_CR3_STORE_EXITING);
-		vcpu->arch.cr0 = cr0;
-		vmx_set_cr4(vcpu, kvm_read_cr4(vcpu));
-	} else if (!is_paging(vcpu)) {
-		/* From nonpaging to paging */
-		exec_controls_clearbit(vmx, CPU_BASED_CR3_LOAD_EXITING |
-					    CPU_BASED_CR3_STORE_EXITING);
-		vcpu->arch.cr0 = cr0;
-		vmx_set_cr4(vcpu, kvm_read_cr4(vcpu));
-	}
-
-	if (!(cr0 & X86_CR0_WP))
-		*hw_cr0 &= ~X86_CR0_WP;
-}
+#define CR3_EXITING_BITS (CPU_BASED_CR3_LOAD_EXITING | \
+			  CPU_BASED_CR3_STORE_EXITING)
 
 void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	unsigned long hw_cr0;
+	u32 tmp;
 
 	hw_cr0 = (cr0 & ~KVM_VM_CR0_ALWAYS_OFF);
-	if (is_unrestricted_guest(vcpu))
+	if (enable_unrestricted_guest)
 		hw_cr0 |= KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST;
 	else {
 		hw_cr0 |= KVM_VM_CR0_ALWAYS_ON;
+		if (!enable_ept)
+			hw_cr0 |= X86_CR0_WP;
 
 		if (vmx->rmode.vm86_active && (cr0 & X86_CR0_PE))
 			enter_pmode(vcpu);
@@ -3124,8 +3101,47 @@
 	}
 #endif
 
-	if (enable_ept && !is_unrestricted_guest(vcpu))
-		ept_update_paging_mode_cr0(&hw_cr0, cr0, vcpu);
+	if (enable_ept && !enable_unrestricted_guest) {
+		/*
+		 * Ensure KVM has an up-to-date snapshot of the guest's CR3.  If
+		 * the below code _enables_ CR3 exiting, vmx_cache_reg() will
+		 * (correctly) stop reading vmcs.GUEST_CR3 because it thinks
+		 * KVM's CR3 is installed.
+		 */
+		if (!kvm_register_is_available(vcpu, VCPU_EXREG_CR3))
+			vmx_cache_reg(vcpu, VCPU_EXREG_CR3);
+
+		/*
+		 * When running with EPT but not unrestricted guest, KVM must
+		 * intercept CR3 accesses when paging is _disabled_.  This is
+		 * necessary because restricted guests can't actually run with
+		 * paging disabled, and so KVM stuffs its own CR3 in order to
+		 * run the guest when identity mapped page tables.
+		 *
+		 * Do _NOT_ check the old CR0.PG, e.g. to optimize away the
+		 * update, it may be stale with respect to CR3 interception,
+		 * e.g. after nested VM-Enter.
+		 *
+		 * Lastly, honor L1's desires, i.e. intercept CR3 loads and/or
+		 * stores to forward them to L1, even if KVM does not need to
+		 * intercept them to preserve its identity mapped page tables.
+		 */
+		if (!(cr0 & X86_CR0_PG)) {
+			exec_controls_setbit(vmx, CR3_EXITING_BITS);
+		} else if (!is_guest_mode(vcpu)) {
+			exec_controls_clearbit(vmx, CR3_EXITING_BITS);
+		} else {
+			tmp = exec_controls_get(vmx);
+			tmp &= ~CR3_EXITING_BITS;
+			tmp |= get_vmcs12(vcpu)->cpu_based_vm_exec_control & CR3_EXITING_BITS;
+			exec_controls_set(vmx, tmp);
+		}
+
+		if (!is_paging(vcpu) != !(cr0 & X86_CR0_PG)) {
+			vcpu->arch.cr0 = cr0;
+			vmx_set_cr4(vcpu, kvm_read_cr4(vcpu));
+		}
+	}
 
 	vmcs_writel(CR0_READ_SHADOW, cr0);
 	vmcs_writel(GUEST_CR0, hw_cr0);
@@ -3220,7 +3236,7 @@
 	unsigned long hw_cr4;
 
 	hw_cr4 = (cr4_read_shadow() & X86_CR4_MCE) | (cr4 & ~X86_CR4_MCE);
-	if (is_unrestricted_guest(vcpu))
+	if (enable_unrestricted_guest)
 		hw_cr4 |= KVM_VM_CR4_ALWAYS_ON_UNRESTRICTED_GUEST;
 	else if (vmx->rmode.vm86_active)
 		hw_cr4 |= KVM_RMODE_VM_CR4_ALWAYS_ON;
@@ -3240,7 +3256,7 @@
 	vcpu->arch.cr4 = cr4;
 	kvm_register_mark_available(vcpu, VCPU_EXREG_CR4);
 
-	if (!is_unrestricted_guest(vcpu)) {
+	if (!enable_unrestricted_guest) {
 		if (enable_ept) {
 			if (!is_paging(vcpu)) {
 				hw_cr4 &= ~X86_CR4_PAE;
@@ -3332,18 +3348,15 @@
 {
 	u32 ar;
 
-	if (var->unusable || !var->present)
-		ar = 1 << 16;
-	else {
-		ar = var->type & 15;
-		ar |= (var->s & 1) << 4;
-		ar |= (var->dpl & 3) << 5;
-		ar |= (var->present & 1) << 7;
-		ar |= (var->avl & 1) << 12;
-		ar |= (var->l & 1) << 13;
-		ar |= (var->db & 1) << 14;
-		ar |= (var->g & 1) << 15;
-	}
+	ar = var->type & 15;
+	ar |= (var->s & 1) << 4;
+	ar |= (var->dpl & 3) << 5;
+	ar |= (var->present & 1) << 7;
+	ar |= (var->avl & 1) << 12;
+	ar |= (var->l & 1) << 13;
+	ar |= (var->db & 1) << 14;
+	ar |= (var->g & 1) << 15;
+	ar |= (var->unusable || !var->present) << 16;
 
 	return ar;
 }
@@ -3795,6 +3808,22 @@
 		__set_bit(msr & 0x1fff, msr_bitmap + 0xc00 / f);
 }
 
+static void vmx_msr_bitmap_l01_changed(struct vcpu_vmx *vmx)
+{
+	/*
+	 * When KVM is a nested hypervisor on top of Hyper-V and uses
+	 * 'Enlightened MSR Bitmap' feature L0 needs to know that MSR
+	 * bitmap has changed.
+	 */
+	if (IS_ENABLED(CONFIG_HYPERV) && static_branch_unlikely(&enable_evmcs)) {
+		struct hv_enlightened_vmcs *evmcs = (void *)vmx->vmcs01.vmcs;
+
+		if (evmcs->hv_enlightenments_control.msr_bitmap)
+			evmcs->hv_clean_fields &=
+				~HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP;
+	}
+}
+
 static __always_inline void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu,
 							  u32 msr, int type)
 {
@@ -3804,8 +3833,7 @@
 	if (!cpu_has_vmx_msr_bitmap())
 		return;
 
-	if (static_branch_unlikely(&enable_evmcs))
-		evmcs_touch_msr_bitmap();
+	vmx_msr_bitmap_l01_changed(vmx);
 
 	/*
 	 * Mark the desired intercept state in shadow bitmap, this is needed
@@ -3850,8 +3878,7 @@
 	if (!cpu_has_vmx_msr_bitmap())
 		return;
 
-	if (static_branch_unlikely(&enable_evmcs))
-		evmcs_touch_msr_bitmap();
+	vmx_msr_bitmap_l01_changed(vmx);
 
 	/*
 	 * Mark the desired intercept state in shadow bitmap, this is needed
@@ -6506,6 +6533,7 @@
 		return;
 
 	handle_interrupt_nmi_irqoff(vcpu, gate_offset(desc));
+	vcpu->arch.at_instruction_boundary = true;
 }
 
 static void vmx_handle_exit_irqoff(struct kvm_vcpu *vcpu)
@@ -7030,6 +7058,19 @@
 	if (err < 0)
 		goto free_pml;
 
+	/*
+	 * Use Hyper-V 'Enlightened MSR Bitmap' feature when KVM runs as a
+	 * nested (L1) hypervisor and Hyper-V in L0 supports it. Enable the
+	 * feature only for vmcs01, KVM currently isn't equipped to realize any
+	 * performance benefits from enabling it for vmcs02.
+	 */
+	if (IS_ENABLED(CONFIG_HYPERV) && static_branch_unlikely(&enable_evmcs) &&
+	    (ms_hyperv.nested_features & HV_X64_NESTED_MSR_BITMAP)) {
+		struct hv_enlightened_vmcs *evmcs = (void *)vmx->vmcs01.vmcs;
+
+		evmcs->hv_enlightenments_control.msr_bitmap = 1;
+	}
+
 	/* The MSR bitmap starts with all ones */
 	bitmap_fill(vmx->shadow_msr_intercept.read, MAX_POSSIBLE_PASSTHROUGH_MSRS);
 	bitmap_fill(vmx->shadow_msr_intercept.write, MAX_POSSIBLE_PASSTHROUGH_MSRS);
@@ -7519,6 +7560,21 @@
 		/* FIXME: produce nested vmexit and return X86EMUL_INTERCEPTED.  */
 		break;
 
+	case x86_intercept_pause:
+		/*
+		 * PAUSE is a single-byte NOP with a REPE prefix, i.e. collides
+		 * with vanilla NOPs in the emulator.  Apply the interception
+		 * check only to actual PAUSE instructions.  Don't check
+		 * PAUSE-loop-exiting, software can't expect a given PAUSE to
+		 * exit, i.e. KVM is within its rights to allow L2 to execute
+		 * the PAUSE.
+		 */
+		if ((info->rep_prefix != REPE_PREFIX) ||
+		    !nested_cpu_has2(vmcs12, CPU_BASED_PAUSE_EXITING))
+			return X86EMUL_CONTINUE;
+
+		break;
+
 	/* TODO: check more intercepts... */
 	default:
 		break;
diff --git a/kernel/arch/x86/kvm/x86.c b/kernel/arch/x86/kvm/x86.c
index 23d7c56..9d30158 100644
--- a/kernel/arch/x86/kvm/x86.c
+++ b/kernel/arch/x86/kvm/x86.c
@@ -231,6 +231,8 @@
 	VCPU_STAT("l1d_flush", l1d_flush),
 	VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),
 	VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),
+	VCPU_STAT("preemption_reported", preemption_reported),
+	VCPU_STAT("preemption_other", preemption_other),
 	VM_STAT("mmu_shadow_zapped", mmu_shadow_zapped),
 	VM_STAT("mmu_pte_write", mmu_pte_write),
 	VM_STAT("mmu_pde_zapped", mmu_pde_zapped),
@@ -1387,7 +1389,7 @@
 	 ARCH_CAP_SKIP_VMENTRY_L1DFLUSH | ARCH_CAP_SSB_NO | ARCH_CAP_MDS_NO | \
 	 ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \
 	 ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \
-	 ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO)
+	 ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO)
 
 static u64 kvm_get_arch_capabilities(void)
 {
@@ -1443,6 +1445,9 @@
 		 * using VERW to clear CPU buffers.
 		 */
 	}
+
+	if (!boot_cpu_has_bug(X86_BUG_GDS) || gds_ucode_mitigated())
+		data |= ARCH_CAP_GDS_NO;
 
 	return data;
 }
@@ -1586,6 +1591,9 @@
 			allowed = !!test_bit(index - start, bitmap);
 			break;
 		}
+
+		/* Note, VM-Exits that go down the "slow" path are accounted below. */
+		++vcpu->stat.exits;
 	}
 
 out:
@@ -3020,51 +3028,95 @@
 
 static void record_steal_time(struct kvm_vcpu *vcpu)
 {
-	struct kvm_host_map map;
-	struct kvm_steal_time *st;
+	struct gfn_to_hva_cache *ghc = &vcpu->arch.st.cache;
+	struct kvm_steal_time __user *st;
+	struct kvm_memslots *slots;
+	gpa_t gpa = vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS;
+	u64 steal;
+	u32 version;
 
 	if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
 		return;
 
-	/* -EAGAIN is returned in atomic context so we can just return. */
-	if (kvm_map_gfn(vcpu, vcpu->arch.st.msr_val >> PAGE_SHIFT,
-			&map, &vcpu->arch.st.cache, false))
+	if (WARN_ON_ONCE(current->mm != vcpu->kvm->mm))
 		return;
 
-	st = map.hva +
-		offset_in_page(vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS);
+	slots = kvm_memslots(vcpu->kvm);
 
+	if (unlikely(slots->generation != ghc->generation ||
+		     gpa != ghc->gpa ||
+		     kvm_is_error_hva(ghc->hva) || !ghc->memslot)) {
+		/* We rely on the fact that it fits in a single page. */
+		BUILD_BUG_ON((sizeof(*st) - 1) & KVM_STEAL_VALID_BITS);
+
+		if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, gpa, sizeof(*st)) ||
+		    kvm_is_error_hva(ghc->hva) || !ghc->memslot)
+			return;
+	}
+
+	st = (struct kvm_steal_time __user *)ghc->hva;
 	/*
 	 * Doing a TLB flush here, on the guest's behalf, can avoid
 	 * expensive IPIs.
 	 */
 	if (guest_pv_has(vcpu, KVM_FEATURE_PV_TLB_FLUSH)) {
+		u8 st_preempted = 0;
+		int err = -EFAULT;
+
+		if (!user_access_begin(st, sizeof(*st)))
+			return;
+
+		asm volatile("1: xchgb %0, %2\n"
+			     "xor %1, %1\n"
+			     "2:\n"
+			     _ASM_EXTABLE_UA(1b, 2b)
+			     : "+q" (st_preempted),
+			       "+&r" (err),
+			       "+m" (st->preempted));
+		if (err)
+			goto out;
+
+		user_access_end();
+
+		vcpu->arch.st.preempted = 0;
+
 		trace_kvm_pv_tlb_flush(vcpu->vcpu_id,
-				       st->preempted & KVM_VCPU_FLUSH_TLB);
-		if (xchg(&st->preempted, 0) & KVM_VCPU_FLUSH_TLB)
+				       st_preempted & KVM_VCPU_FLUSH_TLB);
+		if (st_preempted & KVM_VCPU_FLUSH_TLB)
 			kvm_vcpu_flush_tlb_guest(vcpu);
+
+		if (!user_access_begin(st, sizeof(*st)))
+			goto dirty;
 	} else {
-		st->preempted = 0;
+		if (!user_access_begin(st, sizeof(*st)))
+			return;
+
+		unsafe_put_user(0, &st->preempted, out);
+		vcpu->arch.st.preempted = 0;
 	}
 
-	vcpu->arch.st.preempted = 0;
+	unsafe_get_user(version, &st->version, out);
+	if (version & 1)
+		version += 1;  /* first time write, random junk */
 
-	if (st->version & 1)
-		st->version += 1;  /* first time write, random junk */
-
-	st->version += 1;
+	version += 1;
+	unsafe_put_user(version, &st->version, out);
 
 	smp_wmb();
 
-	st->steal += current->sched_info.run_delay -
+	unsafe_get_user(steal, &st->steal, out);
+	steal += current->sched_info.run_delay -
 		vcpu->arch.st.last_steal;
 	vcpu->arch.st.last_steal = current->sched_info.run_delay;
+	unsafe_put_user(steal, &st->steal, out);
 
-	smp_wmb();
+	version += 1;
+	unsafe_put_user(version, &st->version, out);
 
-	st->version += 1;
-
-	kvm_unmap_gfn(vcpu, &map, &vcpu->arch.st.cache, true, false);
+ out:
+	user_access_end();
+ dirty:
+	mark_page_dirty_in_slot(ghc->memslot, gpa_to_gfn(ghc->gpa));
 }
 
 int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
@@ -4049,51 +4101,67 @@
 
 static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu)
 {
-	struct kvm_host_map map;
-	struct kvm_steal_time *st;
+	struct gfn_to_hva_cache *ghc = &vcpu->arch.st.cache;
+	struct kvm_steal_time __user *st;
+	struct kvm_memslots *slots;
+	static const u8 preempted = KVM_VCPU_PREEMPTED;
+	gpa_t gpa = vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS;
 
+	/*
+	 * The vCPU can be marked preempted if and only if the VM-Exit was on
+	 * an instruction boundary and will not trigger guest emulation of any
+	 * kind (see vcpu_run).  Vendor specific code controls (conservatively)
+	 * when this is true, for example allowing the vCPU to be marked
+	 * preempted if and only if the VM-Exit was due to a host interrupt.
+	 */
+	if (!vcpu->arch.at_instruction_boundary) {
+		vcpu->stat.preemption_other++;
+		return;
+	}
+
+	vcpu->stat.preemption_reported++;
 	if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
 		return;
 
 	if (vcpu->arch.st.preempted)
 		return;
 
-	if (kvm_map_gfn(vcpu, vcpu->arch.st.msr_val >> PAGE_SHIFT, &map,
-			&vcpu->arch.st.cache, true))
+	/* This happens on process exit */
+	if (unlikely(current->mm != vcpu->kvm->mm))
 		return;
 
-	st = map.hva +
-		offset_in_page(vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS);
+	slots = kvm_memslots(vcpu->kvm);
 
-	st->preempted = vcpu->arch.st.preempted = KVM_VCPU_PREEMPTED;
+	if (unlikely(slots->generation != ghc->generation ||
+		     gpa != ghc->gpa ||
+		     kvm_is_error_hva(ghc->hva) || !ghc->memslot))
+		return;
 
-	kvm_unmap_gfn(vcpu, &map, &vcpu->arch.st.cache, true, true);
+	st = (struct kvm_steal_time __user *)ghc->hva;
+	BUILD_BUG_ON(sizeof(st->preempted) != sizeof(preempted));
+
+	if (!copy_to_user_nofault(&st->preempted, &preempted, sizeof(preempted)))
+		vcpu->arch.st.preempted = KVM_VCPU_PREEMPTED;
+
+	mark_page_dirty_in_slot(ghc->memslot, gpa_to_gfn(ghc->gpa));
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
 	int idx;
 
-	if (vcpu->preempted)
+	if (vcpu->preempted) {
 		vcpu->arch.preempted_in_kernel = !kvm_x86_ops.get_cpl(vcpu);
 
-	/*
-	 * Disable page faults because we're in atomic context here.
-	 * kvm_write_guest_offset_cached() would call might_fault()
-	 * that relies on pagefault_disable() to tell if there's a
-	 * bug. NOTE: the write to guest memory may not go through if
-	 * during postcopy live migration or if there's heavy guest
-	 * paging.
-	 */
-	pagefault_disable();
-	/*
-	 * kvm_memslots() will be called by
-	 * kvm_write_guest_offset_cached() so take the srcu lock.
-	 */
-	idx = srcu_read_lock(&vcpu->kvm->srcu);
-	kvm_steal_time_set_preempted(vcpu);
-	srcu_read_unlock(&vcpu->kvm->srcu, idx);
-	pagefault_enable();
+		/*
+		 * Take the srcu lock as memslots will be accessed to check the gfn
+		 * cache generation against the memslots generation.
+		 */
+		idx = srcu_read_lock(&vcpu->kvm->srcu);
+		kvm_steal_time_set_preempted(vcpu);
+		srcu_read_unlock(&vcpu->kvm->srcu, idx);
+	}
+
 	kvm_x86_ops.vcpu_put(vcpu);
 	vcpu->arch.last_host_tsc = rdtsc();
 	/*
@@ -4455,12 +4523,11 @@
 {
 	unsigned long val;
 
+	memset(dbgregs, 0, sizeof(*dbgregs));
 	memcpy(dbgregs->db, vcpu->arch.db, sizeof(vcpu->arch.db));
 	kvm_get_dr(vcpu, 6, &val);
 	dbgregs->dr6 = val;
 	dbgregs->dr7 = vcpu->arch.dr7;
-	dbgregs->flags = 0;
-	memset(&dbgregs->reserved, 0, sizeof(dbgregs->reserved));
 }
 
 static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
@@ -7535,7 +7602,9 @@
 						  write_fault_to_spt,
 						  emulation_type))
 				return 1;
-			if (ctxt->have_exception) {
+
+			if (ctxt->have_exception &&
+			    !(emulation_type & EMULTYPE_SKIP)) {
 				/*
 				 * #UD should result in just EMULATION_FAILED, and trap-like
 				 * exception should not be encountered during decode.
@@ -9356,6 +9425,13 @@
 	vcpu->arch.l1tf_flush_l1d = true;
 
 	for (;;) {
+		/*
+		 * If another guest vCPU requests a PV TLB flush in the middle
+		 * of instruction emulation, the rest of the emulation could
+		 * use a stale page translation. Assume that any code after
+		 * this point can start executing an instruction.
+		 */
+		vcpu->arch.at_instruction_boundary = false;
 		if (kvm_vcpu_running(vcpu)) {
 			r = vcpu_enter_guest(vcpu);
 		} else {
@@ -10241,10 +10317,7 @@
 
 void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
 {
-	struct gfn_to_pfn_cache *cache = &vcpu->arch.st.cache;
 	int idx;
-
-	kvm_release_pfn(cache->pfn, cache->dirty, cache);
 
 	kvmclock_reset(vcpu);
 
diff --git a/kernel/arch/x86/lib/iomap_copy_64.S b/kernel/arch/x86/lib/iomap_copy_64.S
index a1f9416..6ff2f56 100644
--- a/kernel/arch/x86/lib/iomap_copy_64.S
+++ b/kernel/arch/x86/lib/iomap_copy_64.S
@@ -10,6 +10,6 @@
  */
 SYM_FUNC_START(__iowrite32_copy)
 	movl %edx,%ecx
-	rep movsd
+	rep movsl
 	RET
 SYM_FUNC_END(__iowrite32_copy)
diff --git a/kernel/arch/x86/lib/retpoline.S b/kernel/arch/x86/lib/retpoline.S
index 1221bb0..6f5321b 100644
--- a/kernel/arch/x86/lib/retpoline.S
+++ b/kernel/arch/x86/lib/retpoline.S
@@ -9,8 +9,9 @@
 #include <asm/nospec-branch.h>
 #include <asm/unwind_hints.h>
 #include <asm/frame.h>
+#include <asm/nops.h>
 
-	.section .text.__x86.indirect_thunk
+	.section .text..__x86.indirect_thunk
 
 .macro RETPOLINE reg
 	ANNOTATE_INTRA_FUNCTION_CALL
@@ -73,36 +74,106 @@
  */
 #ifdef CONFIG_RETHUNK
 
-	.section .text.__x86.return_thunk
+/*
+ * srso_alias_untrain_ret() and srso_alias_safe_ret() are placed at
+ * special addresses:
+ *
+ * - srso_alias_untrain_ret() is 2M aligned
+ * - srso_alias_safe_ret() is also in the same 2M page but bits 2, 8, 14
+ * and 20 in its virtual address are set (while those bits in the
+ * srso_alias_untrain_ret() function are cleared).
+ *
+ * This guarantees that those two addresses will alias in the branch
+ * target buffer of Zen3/4 generations, leading to any potential
+ * poisoned entries at that BTB slot to get evicted.
+ *
+ * As a result, srso_alias_safe_ret() becomes a safe return.
+ */
+#ifdef CONFIG_CPU_SRSO
+	.section .text..__x86.rethunk_untrain
+
+SYM_START(srso_alias_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE)
+	UNWIND_HINT_FUNC
+	ASM_NOP2
+	lfence
+	jmp srso_alias_return_thunk
+SYM_FUNC_END(srso_alias_untrain_ret)
+__EXPORT_THUNK(srso_alias_untrain_ret)
+
+	.section .text..__x86.rethunk_safe
+#else
+/* dummy definition for alternatives */
+SYM_START(srso_alias_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE)
+	ANNOTATE_UNRET_SAFE
+	ret
+	int3
+SYM_FUNC_END(srso_alias_untrain_ret)
+#endif
+
+SYM_START(srso_alias_safe_ret, SYM_L_GLOBAL, SYM_A_NONE)
+	lea 8(%_ASM_SP), %_ASM_SP
+	UNWIND_HINT_FUNC
+	ANNOTATE_UNRET_SAFE
+	ret
+	int3
+SYM_FUNC_END(srso_alias_safe_ret)
+
+	.section .text..__x86.return_thunk
+
+SYM_CODE_START(srso_alias_return_thunk)
+	UNWIND_HINT_FUNC
+	ANNOTATE_NOENDBR
+	call srso_alias_safe_ret
+	ud2
+SYM_CODE_END(srso_alias_return_thunk)
+
+/*
+ * Some generic notes on the untraining sequences:
+ *
+ * They are interchangeable when it comes to flushing potentially wrong
+ * RET predictions from the BTB.
+ *
+ * The SRSO Zen1/2 (MOVABS) untraining sequence is longer than the
+ * Retbleed sequence because the return sequence done there
+ * (srso_safe_ret()) is longer and the return sequence must fully nest
+ * (end before) the untraining sequence. Therefore, the untraining
+ * sequence must fully overlap the return sequence.
+ *
+ * Regarding alignment - the instructions which need to be untrained,
+ * must all start at a cacheline boundary for Zen1/2 generations. That
+ * is, instruction sequences starting at srso_safe_ret() and
+ * the respective instruction sequences at retbleed_return_thunk()
+ * must start at a cacheline boundary.
+ */
 
 /*
  * Safety details here pertain to the AMD Zen{1,2} microarchitecture:
- * 1) The RET at __x86_return_thunk must be on a 64 byte boundary, for
+ * 1) The RET at retbleed_return_thunk must be on a 64 byte boundary, for
  *    alignment within the BTB.
- * 2) The instruction at zen_untrain_ret must contain, and not
+ * 2) The instruction at retbleed_untrain_ret must contain, and not
  *    end with, the 0xc3 byte of the RET.
  * 3) STIBP must be enabled, or SMT disabled, to prevent the sibling thread
  *    from re-poisioning the BTB prediction.
  */
 	.align 64
-	.skip 63, 0xcc
-SYM_FUNC_START_NOALIGN(zen_untrain_ret);
+	.skip 64 - (retbleed_return_thunk - retbleed_untrain_ret), 0xcc
+SYM_FUNC_START_NOALIGN(retbleed_untrain_ret);
 
 	/*
-	 * As executed from zen_untrain_ret, this is:
+	 * As executed from retbleed_untrain_ret, this is:
 	 *
 	 *   TEST $0xcc, %bl
 	 *   LFENCE
-	 *   JMP __x86_return_thunk
+	 *   JMP retbleed_return_thunk
 	 *
 	 * Executing the TEST instruction has a side effect of evicting any BTB
 	 * prediction (potentially attacker controlled) attached to the RET, as
-	 * __x86_return_thunk + 1 isn't an instruction boundary at the moment.
+	 * retbleed_return_thunk + 1 isn't an instruction boundary at the moment.
 	 */
 	.byte	0xf6
 
 	/*
-	 * As executed from __x86_return_thunk, this is a plain RET.
+	 * As executed from retbleed_return_thunk, this is a plain RET.
 	 *
 	 * As part of the TEST above, RET is the ModRM byte, and INT3 the imm8.
 	 *
@@ -114,13 +185,13 @@
 	 * With SMT enabled and STIBP active, a sibling thread cannot poison
 	 * RET's prediction to a type of its choice, but can evict the
 	 * prediction due to competitive sharing. If the prediction is
-	 * evicted, __x86_return_thunk will suffer Straight Line Speculation
+	 * evicted, retbleed_return_thunk will suffer Straight Line Speculation
 	 * which will be contained safely by the INT3.
 	 */
-SYM_INNER_LABEL(__x86_return_thunk, SYM_L_GLOBAL)
+SYM_INNER_LABEL(retbleed_return_thunk, SYM_L_GLOBAL)
 	ret
 	int3
-SYM_CODE_END(__x86_return_thunk)
+SYM_CODE_END(retbleed_return_thunk)
 
 	/*
 	 * Ensure the TEST decoding / BTB invalidation is complete.
@@ -131,11 +202,66 @@
 	 * Jump back and execute the RET in the middle of the TEST instruction.
 	 * INT3 is for SLS protection.
 	 */
-	jmp __x86_return_thunk
+	jmp retbleed_return_thunk
 	int3
-SYM_FUNC_END(zen_untrain_ret)
-__EXPORT_THUNK(zen_untrain_ret)
+SYM_FUNC_END(retbleed_untrain_ret)
+__EXPORT_THUNK(retbleed_untrain_ret)
 
+/*
+ * SRSO untraining sequence for Zen1/2, similar to retbleed_untrain_ret()
+ * above. On kernel entry, srso_untrain_ret() is executed which is a
+ *
+ * movabs $0xccccc30824648d48,%rax
+ *
+ * and when the return thunk executes the inner label srso_safe_ret()
+ * later, it is a stack manipulation and a RET which is mispredicted and
+ * thus a "safe" one to use.
+ */
+	.align 64
+	.skip 64 - (srso_safe_ret - srso_untrain_ret), 0xcc
+SYM_START(srso_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE)
+	.byte 0x48, 0xb8
+
+/*
+ * This forces the function return instruction to speculate into a trap
+ * (UD2 in srso_return_thunk() below).  This RET will then mispredict
+ * and execution will continue at the return site read from the top of
+ * the stack.
+ */
+SYM_INNER_LABEL(srso_safe_ret, SYM_L_GLOBAL)
+	lea 8(%_ASM_SP), %_ASM_SP
+	ret
+	int3
+	int3
+	/* end of movabs */
+	lfence
+	call srso_safe_ret
+	ud2
+SYM_CODE_END(srso_safe_ret)
+SYM_FUNC_END(srso_untrain_ret)
+__EXPORT_THUNK(srso_untrain_ret)
+
+SYM_CODE_START(srso_return_thunk)
+	UNWIND_HINT_FUNC
+	ANNOTATE_NOENDBR
+	call srso_safe_ret
+	ud2
+SYM_CODE_END(srso_return_thunk)
+
+SYM_FUNC_START(entry_untrain_ret)
+	ALTERNATIVE_2 "jmp retbleed_untrain_ret", \
+		      "jmp srso_untrain_ret", X86_FEATURE_SRSO, \
+		      "jmp srso_alias_untrain_ret", X86_FEATURE_SRSO_ALIAS
+SYM_FUNC_END(entry_untrain_ret)
+__EXPORT_THUNK(entry_untrain_ret)
+
+SYM_CODE_START(__x86_return_thunk)
+	UNWIND_HINT_FUNC
+	ANNOTATE_NOENDBR
+	ANNOTATE_UNRET_SAFE
+	ret
+	int3
+SYM_CODE_END(__x86_return_thunk)
 EXPORT_SYMBOL(__x86_return_thunk)
 
 #endif /* CONFIG_RETHUNK */
diff --git a/kernel/arch/x86/mm/init.c b/kernel/arch/x86/mm/init.c
index 88a1e0d..8f67fed 100644
--- a/kernel/arch/x86/mm/init.c
+++ b/kernel/arch/x86/mm/init.c
@@ -7,8 +7,10 @@
 #include <linux/swapops.h>
 #include <linux/kmemleak.h>
 #include <linux/sched/task.h>
+#include <linux/sched/mm.h>
 
 #include <asm/set_memory.h>
+#include <asm/cpu_device_id.h>
 #include <asm/e820/api.h>
 #include <asm/init.h>
 #include <asm/page.h>
@@ -26,6 +28,7 @@
 #include <asm/pti.h>
 #include <asm/text-patching.h>
 #include <asm/memtype.h>
+#include <asm/paravirt.h>
 
 /*
  * We need to define the tracepoints somewhere, and tlb.c
@@ -260,6 +263,24 @@
 	}
 }
 
+#define INTEL_MATCH(_model) { .vendor  = X86_VENDOR_INTEL,	\
+			      .family  = 6,			\
+			      .model = _model,			\
+			    }
+/*
+ * INVLPG may not properly flush Global entries
+ * on these CPUs when PCIDs are enabled.
+ */
+static const struct x86_cpu_id invlpg_miss_ids[] = {
+	INTEL_MATCH(INTEL_FAM6_ALDERLAKE   ),
+	INTEL_MATCH(INTEL_FAM6_ALDERLAKE_L ),
+	INTEL_MATCH(INTEL_FAM6_ALDERLAKE_N ),
+	INTEL_MATCH(INTEL_FAM6_RAPTORLAKE  ),
+	INTEL_MATCH(INTEL_FAM6_RAPTORLAKE_P),
+	INTEL_MATCH(INTEL_FAM6_RAPTORLAKE_S),
+	{}
+};
+
 static void setup_pcid(void)
 {
 	if (!IS_ENABLED(CONFIG_X86_64))
@@ -267,6 +288,12 @@
 
 	if (!boot_cpu_has(X86_FEATURE_PCID))
 		return;
+
+	if (x86_match_cpu(invlpg_miss_ids)) {
+		pr_info("Incomplete global flushes, disabling PCID");
+		setup_clear_cpu_cap(X86_FEATURE_PCID);
+		return;
+	}
 
 	if (boot_cpu_has(X86_FEATURE_PGE)) {
 		/*
@@ -785,9 +812,12 @@
 	spinlock_t *ptl;
 	pte_t *ptep;
 
-	poking_mm = copy_init_mm();
+	poking_mm = mm_alloc();
 	BUG_ON(!poking_mm);
 
+	/* Xen PV guests need the PGD to be pinned. */
+	paravirt_arch_dup_mmap(NULL, poking_mm);
+
 	/*
 	 * Randomize the poking address, but make sure that the following page
 	 * will be mapped at the same PMD. We need 2 pages, so find space for 3,
diff --git a/kernel/arch/x86/mm/init_64.c b/kernel/arch/x86/mm/init_64.c
index 20951ab..acf4e50 100644
--- a/kernel/arch/x86/mm/init_64.c
+++ b/kernel/arch/x86/mm/init_64.c
@@ -193,8 +193,8 @@
 			spin_lock(pgt_lock);
 
 			if (!p4d_none(*p4d_ref) && !p4d_none(*p4d))
-				BUG_ON(p4d_page_vaddr(*p4d)
-				       != p4d_page_vaddr(*p4d_ref));
+				BUG_ON(p4d_pgtable(*p4d)
+				       != p4d_pgtable(*p4d_ref));
 
 			if (p4d_none(*p4d))
 				set_p4d(p4d, *p4d_ref);
diff --git a/kernel/arch/x86/mm/kaslr.c b/kernel/arch/x86/mm/kaslr.c
index 6e6b397..a8cdbbe 100644
--- a/kernel/arch/x86/mm/kaslr.c
+++ b/kernel/arch/x86/mm/kaslr.c
@@ -172,10 +172,10 @@
 		set_p4d(p4d_tramp,
 			__p4d(_KERNPG_TABLE | __pa(pud_page_tramp)));
 
-		set_pgd(&trampoline_pgd_entry,
-			__pgd(_KERNPG_TABLE | __pa(p4d_page_tramp)));
+		trampoline_pgd_entry =
+			__pgd(_KERNPG_TABLE | __pa(p4d_page_tramp));
 	} else {
-		set_pgd(&trampoline_pgd_entry,
-			__pgd(_KERNPG_TABLE | __pa(pud_page_tramp)));
+		trampoline_pgd_entry =
+			__pgd(_KERNPG_TABLE | __pa(pud_page_tramp));
 	}
 }
diff --git a/kernel/arch/x86/mm/mem_encrypt_identity.c b/kernel/arch/x86/mm/mem_encrypt_identity.c
index 011e042..5ec47af 100644
--- a/kernel/arch/x86/mm/mem_encrypt_identity.c
+++ b/kernel/arch/x86/mm/mem_encrypt_identity.c
@@ -586,7 +586,8 @@
 	cmdline_ptr = (const char *)((u64)bp->hdr.cmd_line_ptr |
 				     ((u64)bp->ext_cmd_line_ptr << 32));
 
-	cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer));
+	if (cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer)) < 0)
+		return;
 
 	if (!strncmp(buffer, cmdline_on, sizeof(buffer)))
 		sme_me_mask = me_mask;
diff --git a/kernel/arch/x86/mm/pat/set_memory.c b/kernel/arch/x86/mm/pat/set_memory.c
index 40baa90..217dda6 100644
--- a/kernel/arch/x86/mm/pat/set_memory.c
+++ b/kernel/arch/x86/mm/pat/set_memory.c
@@ -1126,7 +1126,7 @@
 			      unsigned long start, unsigned long end)
 {
 	if (unmap_pte_range(pmd, start, end))
-		if (try_to_free_pmd_page((pmd_t *)pud_page_vaddr(*pud)))
+		if (try_to_free_pmd_page(pud_pgtable(*pud)))
 			pud_clear(pud);
 }
 
@@ -1170,7 +1170,7 @@
 	 * Try again to free the PMD page if haven't succeeded above.
 	 */
 	if (!pud_none(*pud))
-		if (try_to_free_pmd_page((pmd_t *)pud_page_vaddr(*pud)))
+		if (try_to_free_pmd_page(pud_pgtable(*pud)))
 			pud_clear(pud);
 }
 
diff --git a/kernel/arch/x86/mm/pgtable.c b/kernel/arch/x86/mm/pgtable.c
index f6a9e2e..204b25e 100644
--- a/kernel/arch/x86/mm/pgtable.c
+++ b/kernel/arch/x86/mm/pgtable.c
@@ -805,7 +805,7 @@
 	pte_t *pte;
 	int i;
 
-	pmd = (pmd_t *)pud_page_vaddr(*pud);
+	pmd = pud_pgtable(*pud);
 	pmd_sv = (pmd_t *)__get_free_page(GFP_KERNEL);
 	if (!pmd_sv)
 		return 0;
diff --git a/kernel/arch/x86/mm/pkeys.c b/kernel/arch/x86/mm/pkeys.c
index 8873ed1..379c396 100644
--- a/kernel/arch/x86/mm/pkeys.c
+++ b/kernel/arch/x86/mm/pkeys.c
@@ -10,7 +10,6 @@
 
 #include <asm/cpufeature.h>             /* boot_cpu_has, ...            */
 #include <asm/mmu_context.h>            /* vma_pkey()                   */
-#include <asm/fpu/internal.h>		/* init_fpstate			*/
 
 int __execute_only_pkey(struct mm_struct *mm)
 {
@@ -154,7 +153,6 @@
 static ssize_t init_pkru_write_file(struct file *file,
 		 const char __user *user_buf, size_t count, loff_t *ppos)
 {
-	struct pkru_state *pk;
 	char buf[32];
 	ssize_t len;
 	u32 new_init_pkru;
@@ -177,10 +175,6 @@
 		return -EINVAL;
 
 	WRITE_ONCE(init_pkru_value, new_init_pkru);
-	pk = get_xsave_addr(&init_fpstate.xsave, XFEATURE_PKRU);
-	if (!pk)
-		return -EINVAL;
-	pk->pkru = new_init_pkru;
 	return count;
 }
 
diff --git a/kernel/arch/x86/pci/fixup.c b/kernel/arch/x86/pci/fixup.c
index 9b0e771..3f3411b 100644
--- a/kernel/arch/x86/pci/fixup.c
+++ b/kernel/arch/x86/pci/fixup.c
@@ -7,6 +7,7 @@
 #include <linux/dmi.h>
 #include <linux/pci.h>
 #include <linux/vgaarb.h>
+#include <asm/amd_nb.h>
 #include <asm/hpet.h>
 #include <asm/pci_x86.h>
 
@@ -824,3 +825,23 @@
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7910, rs690_fix_64bit_dma);
 
 #endif
+
+#ifdef CONFIG_AMD_NB
+
+#define AMD_15B8_RCC_DEV2_EPF0_STRAP2                                  0x10136008
+#define AMD_15B8_RCC_DEV2_EPF0_STRAP2_NO_SOFT_RESET_DEV2_F0_MASK       0x00000080L
+
+static void quirk_clear_strap_no_soft_reset_dev2_f0(struct pci_dev *dev)
+{
+	u32 data;
+
+	if (!amd_smn_read(0, AMD_15B8_RCC_DEV2_EPF0_STRAP2, &data)) {
+		data &= ~AMD_15B8_RCC_DEV2_EPF0_STRAP2_NO_SOFT_RESET_DEV2_F0_MASK;
+		if (amd_smn_write(0, AMD_15B8_RCC_DEV2_EPF0_STRAP2, data))
+			pci_err(dev, "Failed to write data 0x%x\n", data);
+	} else {
+		pci_err(dev, "Failed to read data\n");
+	}
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15b8, quirk_clear_strap_no_soft_reset_dev2_f0);
+#endif
diff --git a/kernel/arch/x86/purgatory/Makefile b/kernel/arch/x86/purgatory/Makefile
index ed46ad7..279ad47 100644
--- a/kernel/arch/x86/purgatory/Makefile
+++ b/kernel/arch/x86/purgatory/Makefile
@@ -14,6 +14,11 @@
 
 CFLAGS_sha256.o := -D__DISABLE_EXPORTS
 
+# When profile-guided optimization is enabled, llvm emits two different
+# overlapping text sections, which is not supported by kexec. Remove profile
+# optimization flags.
+KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%,$(KBUILD_CFLAGS))
+
 # When linking purgatory.ro with -r unresolved symbols are not checked,
 # also link a purgatory.chk binary without -r to check for unresolved symbols.
 PURGATORY_LDFLAGS := -e purgatory_start -nostdlib -z nodefaultlib
@@ -64,8 +69,7 @@
 CFLAGS_REMOVE_string.o		+= $(PURGATORY_CFLAGS_REMOVE)
 CFLAGS_string.o			+= $(PURGATORY_CFLAGS)
 
-AFLAGS_REMOVE_setup-x86_$(BITS).o	+= -Wa,-gdwarf-2
-AFLAGS_REMOVE_entry64.o			+= -Wa,-gdwarf-2
+asflags-remove-y		+= -g -Wa,-gdwarf-2
 
 $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
 		$(call if_changed,ld)
diff --git a/kernel/arch/x86/um/vdso/um_vdso.c b/kernel/arch/x86/um/vdso/um_vdso.c
index 2112b8d..ff0f3b4 100644
--- a/kernel/arch/x86/um/vdso/um_vdso.c
+++ b/kernel/arch/x86/um/vdso/um_vdso.c
@@ -17,8 +17,10 @@
 {
 	long ret;
 
-	asm("syscall" : "=a" (ret) :
-		"0" (__NR_clock_gettime), "D" (clock), "S" (ts) : "memory");
+	asm("syscall"
+		: "=a" (ret)
+		: "0" (__NR_clock_gettime), "D" (clock), "S" (ts)
+		: "rcx", "r11", "memory");
 
 	return ret;
 }
@@ -29,8 +31,10 @@
 {
 	long ret;
 
-	asm("syscall" : "=a" (ret) :
-		"0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory");
+	asm("syscall"
+		: "=a" (ret)
+		: "0" (__NR_gettimeofday), "D" (tv), "S" (tz)
+		: "rcx", "r11", "memory");
 
 	return ret;
 }
diff --git a/kernel/arch/x86/xen/smp.c b/kernel/arch/x86/xen/smp.c
index c1b2f76..cdec892 100644
--- a/kernel/arch/x86/xen/smp.c
+++ b/kernel/arch/x86/xen/smp.c
@@ -32,30 +32,30 @@
 
 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 @@
 	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 @@
 	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 @@
 	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 @@
 		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 @@
 	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/kernel/arch/x86/xen/smp_pv.c b/kernel/arch/x86/xen/smp_pv.c
index 35b6d15..755e939 100644
--- a/kernel/arch/x86/xen/smp_pv.c
+++ b/kernel/arch/x86/xen/smp_pv.c
@@ -30,6 +30,7 @@
 #include <asm/desc.h>
 #include <asm/cpu.h>
 #include <asm/io_apic.h>
+#include <asm/fpu/internal.h>
 
 #include <xen/interface/xen.h>
 #include <xen/interface/vcpu.h>
@@ -63,6 +64,7 @@
 
 	cr4_init();
 	cpu_init();
+	fpu__init_cpu();
 	touch_softlockup_watchdog();
 	preempt_disable();
 
@@ -98,18 +100,18 @@
 
 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 +121,7 @@
 	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 +131,10 @@
 	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 +142,6 @@
 		if (rc < 0)
 			goto fail;
 		per_cpu(xen_pmu_irq, cpu).irq = rc;
-		per_cpu(xen_pmu_irq, cpu).name = pmu_name;
 	}
 
 	return 0;
diff --git a/kernel/arch/x86/xen/spinlock.c b/kernel/arch/x86/xen/spinlock.c
index 043c73d..5c6fc16 100644
--- a/kernel/arch/x86/xen/spinlock.c
+++ b/kernel/arch/x86/xen/spinlock.c
@@ -75,6 +75,7 @@
 	     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 @@
 	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 @@
 	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 @@
 
 	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);
diff --git a/kernel/arch/xtensa/boot/Makefile b/kernel/arch/xtensa/boot/Makefile
index f6bb352..c8fd705 100644
--- a/kernel/arch/xtensa/boot/Makefile
+++ b/kernel/arch/xtensa/boot/Makefile
@@ -9,8 +9,7 @@
 
 
 # KBUILD_CFLAGS used when building rest of boot (takes effect recursively)
-KBUILD_CFLAGS	+= -fno-builtin -Iarch/$(ARCH)/boot/include
-HOSTFLAGS	+= -Iarch/$(ARCH)/boot/include
+KBUILD_CFLAGS	+= -fno-builtin
 
 BIG_ENDIAN	:= $(shell echo __XTENSA_EB__ | $(CC) -E - | grep -v "\#")
 
diff --git a/kernel/arch/xtensa/boot/lib/zmem.c b/kernel/arch/xtensa/boot/lib/zmem.c
index e3ecd74..b891893 100644
--- a/kernel/arch/xtensa/boot/lib/zmem.c
+++ b/kernel/arch/xtensa/boot/lib/zmem.c
@@ -4,13 +4,14 @@
 /* bits taken from ppc */
 
 extern void *avail_ram, *end_avail;
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp);
 
-void exit (void)
+static void exit(void)
 {
   for (;;);
 }
 
-void *zalloc(unsigned size)
+static void *zalloc(unsigned int size)
 {
         void *p = avail_ram;
 
diff --git a/kernel/arch/xtensa/include/asm/bugs.h b/kernel/arch/xtensa/include/asm/bugs.h
deleted file mode 100644
index 69b29d1..0000000
--- a/kernel/arch/xtensa/include/asm/bugs.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * include/asm-xtensa/bugs.h
- *
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Xtensa processors don't have any bugs.  :)
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License.  See the file "COPYING" in the main directory of
- * this archive for more details.
- */
-
-#ifndef _XTENSA_BUGS_H
-#define _XTENSA_BUGS_H
-
-static void check_bugs(void) { }
-
-#endif /* _XTENSA_BUGS_H */
diff --git a/kernel/arch/xtensa/include/asm/core.h b/kernel/arch/xtensa/include/asm/core.h
index 5590b0f..0fa3649 100644
--- a/kernel/arch/xtensa/include/asm/core.h
+++ b/kernel/arch/xtensa/include/asm/core.h
@@ -6,6 +6,10 @@
 
 #include <variant/core.h>
 
+#ifndef XCHAL_HAVE_DIV32
+#define XCHAL_HAVE_DIV32 0
+#endif
+
 #ifndef XCHAL_HAVE_EXCLUSIVE
 #define XCHAL_HAVE_EXCLUSIVE 0
 #endif
@@ -26,4 +30,13 @@
 #define XCHAL_SPANNING_WAY 0
 #endif
 
+#ifndef XCHAL_HW_MIN_VERSION
+#if defined(XCHAL_HW_MIN_VERSION_MAJOR) && defined(XCHAL_HW_MIN_VERSION_MINOR)
+#define XCHAL_HW_MIN_VERSION (XCHAL_HW_MIN_VERSION_MAJOR * 100 + \
+			      XCHAL_HW_MIN_VERSION_MINOR)
+#else
+#define XCHAL_HW_MIN_VERSION 0
+#endif
+#endif
+
 #endif
diff --git a/kernel/arch/xtensa/kernel/perf_event.c b/kernel/arch/xtensa/kernel/perf_event.c
index a0d05c8..1836180 100644
--- a/kernel/arch/xtensa/kernel/perf_event.c
+++ b/kernel/arch/xtensa/kernel/perf_event.c
@@ -13,17 +13,26 @@
 #include <linux/perf_event.h>
 #include <linux/platform_device.h>
 
+#include <asm/core.h>
 #include <asm/processor.h>
 #include <asm/stacktrace.h>
 
+#define XTENSA_HWVERSION_RG_2015_0	260000
+
+#if XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RG_2015_0
+#define XTENSA_PMU_ERI_BASE		0x00101000
+#else
+#define XTENSA_PMU_ERI_BASE		0x00001000
+#endif
+
 /* Global control/status for all perf counters */
-#define XTENSA_PMU_PMG			0x1000
+#define XTENSA_PMU_PMG			XTENSA_PMU_ERI_BASE
 /* Perf counter values */
-#define XTENSA_PMU_PM(i)		(0x1080 + (i) * 4)
+#define XTENSA_PMU_PM(i)		(XTENSA_PMU_ERI_BASE + 0x80 + (i) * 4)
 /* Perf counter control registers */
-#define XTENSA_PMU_PMCTRL(i)		(0x1100 + (i) * 4)
+#define XTENSA_PMU_PMCTRL(i)		(XTENSA_PMU_ERI_BASE + 0x100 + (i) * 4)
 /* Perf counter status registers */
-#define XTENSA_PMU_PMSTAT(i)		(0x1180 + (i) * 4)
+#define XTENSA_PMU_PMSTAT(i)		(XTENSA_PMU_ERI_BASE + 0x180 + (i) * 4)
 
 #define XTENSA_PMU_PMG_PMEN		0x1
 
diff --git a/kernel/arch/xtensa/kernel/traps.c b/kernel/arch/xtensa/kernel/traps.c
index efc3a29..6af6830 100644
--- a/kernel/arch/xtensa/kernel/traps.c
+++ b/kernel/arch/xtensa/kernel/traps.c
@@ -503,7 +503,7 @@
 
 void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl)
 {
-	size_t len;
+	size_t len, off = 0;
 
 	if (!sp)
 		sp = stack_pointer(task);
@@ -512,9 +512,17 @@
 		  kstack_depth_to_print * STACK_DUMP_ENTRY_SIZE);
 
 	printk("%sStack:\n", loglvl);
-	print_hex_dump(loglvl, " ", DUMP_PREFIX_NONE,
-		       STACK_DUMP_LINE_SIZE, STACK_DUMP_ENTRY_SIZE,
-		       sp, len, false);
+	while (off < len) {
+		u8 line[STACK_DUMP_LINE_SIZE];
+		size_t line_len = len - off > STACK_DUMP_LINE_SIZE ?
+			STACK_DUMP_LINE_SIZE : len - off;
+
+		__memcpy(line, (u8 *)sp + off, line_len);
+		print_hex_dump(loglvl, " ", DUMP_PREFIX_NONE,
+			       STACK_DUMP_LINE_SIZE, STACK_DUMP_ENTRY_SIZE,
+			       line, line_len, false);
+		off += STACK_DUMP_LINE_SIZE;
+	}
 	show_trace(task, sp, loglvl);
 }
 
@@ -545,5 +553,5 @@
 	if (panic_on_oops)
 		panic("Fatal exception");
 
-	do_exit(err);
+	make_task_dead(err);
 }
diff --git a/kernel/arch/xtensa/platforms/iss/network.c b/kernel/arch/xtensa/platforms/iss/network.c
index 08d70c8..e8491ac 100644
--- a/kernel/arch/xtensa/platforms/iss/network.c
+++ b/kernel/arch/xtensa/platforms/iss/network.c
@@ -204,7 +204,7 @@
 	return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len);
 }
 
-unsigned short tuntap_protocol(struct sk_buff *skb)
+static unsigned short tuntap_protocol(struct sk_buff *skb)
 {
 	return eth_type_trans(skb, skb->dev);
 }
@@ -231,7 +231,7 @@
 
 	init += sizeof(TRANSPORT_TUNTAP_NAME) - 1;
 	if (*init == ',') {
-		rem = split_if_spec(init + 1, &mac_str, &dev_name);
+		rem = split_if_spec(init + 1, &mac_str, &dev_name, NULL);
 		if (rem != NULL) {
 			pr_err("%s: extra garbage on specification : '%s'\n",
 			       dev->name, rem);
@@ -477,7 +477,7 @@
 	return -EINVAL;
 }
 
-void iss_net_user_timer_expire(struct timer_list *unused)
+static void iss_net_user_timer_expire(struct timer_list *unused)
 {
 }
 
diff --git a/kernel/block/bfq-cgroup.c b/kernel/block/bfq-cgroup.c
index badb903..1f9ccc6 100644
--- a/kernel/block/bfq-cgroup.c
+++ b/kernel/block/bfq-cgroup.c
@@ -705,15 +705,15 @@
 				     struct bfq_io_cq *bic,
 				     struct bfq_group *bfqg)
 {
-	struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0);
-	struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1);
+	struct bfq_queue *async_bfqq = bic_to_bfqq(bic, false);
+	struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, true);
 	struct bfq_entity *entity;
 
 	if (async_bfqq) {
 		entity = &async_bfqq->entity;
 
 		if (entity->sched_data != &bfqg->sched_data) {
-			bic_set_bfqq(bic, NULL, 0);
+			bic_set_bfqq(bic, NULL, false);
 			bfq_release_process_ref(bfqd, async_bfqq);
 		}
 	}
@@ -748,8 +748,8 @@
 				 * request from the old cgroup.
 				 */
 				bfq_put_cooperator(sync_bfqq);
+				bic_set_bfqq(bic, NULL, true);
 				bfq_release_process_ref(bfqd, sync_bfqq);
-				bic_set_bfqq(bic, NULL, 1);
 			}
 		}
 	}
diff --git a/kernel/block/bfq-iosched.c b/kernel/block/bfq-iosched.c
index 0e64aa5..7e12d36 100644
--- a/kernel/block/bfq-iosched.c
+++ b/kernel/block/bfq-iosched.c
@@ -373,6 +373,12 @@
 
 void bic_set_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq, bool is_sync)
 {
+	struct bfq_queue *old_bfqq = bic->bfqq[is_sync];
+
+	/* Clear bic pointer if bfqq is detached from this bic */
+	if (old_bfqq && old_bfqq->bic == bic)
+		old_bfqq->bic = NULL;
+
 	bic->bfqq[is_sync] = bfqq;
 }
 
@@ -2810,7 +2816,7 @@
 	/*
 	 * Merge queues (that is, let bic redirect its requests to new_bfqq)
 	 */
-	bic_set_bfqq(bic, new_bfqq, 1);
+	bic_set_bfqq(bic, new_bfqq, true);
 	bfq_mark_bfqq_coop(new_bfqq);
 	/*
 	 * new_bfqq now belongs to at least two bics (it is a shared queue):
@@ -4974,9 +4980,8 @@
 		unsigned long flags;
 
 		spin_lock_irqsave(&bfqd->lock, flags);
-		bfqq->bic = NULL;
-		bfq_exit_bfqq(bfqd, bfqq);
 		bic_set_bfqq(bic, NULL, is_sync);
+		bfq_exit_bfqq(bfqd, bfqq);
 		spin_unlock_irqrestore(&bfqd->lock, flags);
 	}
 }
@@ -5062,9 +5067,11 @@
 
 	bfqq = bic_to_bfqq(bic, false);
 	if (bfqq) {
-		bfq_release_process_ref(bfqd, bfqq);
-		bfqq = bfq_get_queue(bfqd, bio, BLK_RW_ASYNC, bic);
+		struct bfq_queue *old_bfqq = bfqq;
+
+		bfqq = bfq_get_queue(bfqd, bio, false, bic);
 		bic_set_bfqq(bic, bfqq, false);
+		bfq_release_process_ref(bfqd, old_bfqq);
 	}
 
 	bfqq = bic_to_bfqq(bic, true);
@@ -6004,7 +6011,7 @@
 		return bfqq;
 	}
 
-	bic_set_bfqq(bic, NULL, 1);
+	bic_set_bfqq(bic, NULL, true);
 
 	bfq_put_cooperator(bfqq);
 
diff --git a/kernel/block/bio-integrity.c b/kernel/block/bio-integrity.c
index 4f6f140..a4cfc97 100644
--- a/kernel/block/bio-integrity.c
+++ b/kernel/block/bio-integrity.c
@@ -428,6 +428,7 @@
 
 	bip->bip_vcnt = bip_src->bip_vcnt;
 	bip->bip_iter = bip_src->bip_iter;
+	bip->bip_flags = bip_src->bip_flags & ~BIP_BLOCK_INTEGRITY;
 
 	return 0;
 }
diff --git a/kernel/block/blk-cgroup.c b/kernel/block/blk-cgroup.c
index 39c94ee..10cc2e6 100644
--- a/kernel/block/blk-cgroup.c
+++ b/kernel/block/blk-cgroup.c
@@ -1376,6 +1376,10 @@
 		list_for_each_entry_reverse(blkg, &q->blkg_list, q_node)
 			pol->pd_init_fn(blkg->pd[pol->plid]);
 
+	if (pol->pd_online_fn)
+		list_for_each_entry_reverse(blkg, &q->blkg_list, q_node)
+			pol->pd_online_fn(blkg->pd[pol->plid]);
+
 	__set_bit(pol->plid, q->blkcg_pols);
 	ret = 0;
 
@@ -1790,6 +1794,7 @@
 		current->use_memdelay = use_memdelay;
 	set_notify_resume(current);
 }
+EXPORT_SYMBOL_GPL(blkcg_schedule_throttle);
 
 /**
  * blkcg_add_delay - add delay to this blkg
diff --git a/kernel/block/blk-core.c b/kernel/block/blk-core.c
index 637d680..d64ce14 100644
--- a/kernel/block/blk-core.c
+++ b/kernel/block/blk-core.c
@@ -420,8 +420,6 @@
 		blk_mq_sched_free_requests(q);
 	mutex_unlock(&q->sysfs_lock);
 
-	percpu_ref_exit(&q->q_usage_counter);
-
 	/* @q is and will stay empty, shutdown and put */
 	blk_put_queue(q);
 }
@@ -706,9 +704,7 @@
 
 		if (op_is_flush(bio->bi_opf) && !bio_sectors(bio))
 			return false;
-
-		WARN_ONCE(1,
-		       "Trying to write to read-only block-device %s (partno %d)\n",
+		pr_warn("Trying to write to read-only block-device %s (partno %d)\n",
 			bio_devname(bio, b), part->partno);
 		/* Older lvm-tools actually trigger this */
 		return false;
@@ -1452,6 +1448,13 @@
 		req->q->integrity.profile->complete_fn(req, nr_bytes);
 #endif
 
+	/*
+	 * Upper layers may call blk_crypto_evict_key() anytime after the last
+	 * bio_endio().  Therefore, the keyslot must be released before that.
+	 */
+	if (blk_crypto_rq_has_keyslot(req) && nr_bytes >= blk_rq_bytes(req))
+		__blk_crypto_rq_put_keyslot(req);
+
 	if (unlikely(error && !blk_rq_is_passthrough(req) &&
 		     !(req->rq_flags & RQF_QUIET)))
 		print_req_error(req, error, __func__);
diff --git a/kernel/block/blk-crypto-internal.h b/kernel/block/blk-crypto-internal.h
index 0d36aae..8e08345 100644
--- a/kernel/block/blk-crypto-internal.h
+++ b/kernel/block/blk-crypto-internal.h
@@ -60,6 +60,11 @@
 	return rq->crypt_ctx;
 }
 
+static inline bool blk_crypto_rq_has_keyslot(struct request *rq)
+{
+	return rq->crypt_keyslot;
+}
+
 #else /* CONFIG_BLK_INLINE_ENCRYPTION */
 
 static inline bool bio_crypt_rq_ctx_compatible(struct request *rq,
@@ -89,6 +94,11 @@
 static inline void blk_crypto_rq_set_defaults(struct request *rq) { }
 
 static inline bool blk_crypto_rq_is_encrypted(struct request *rq)
+{
+	return false;
+}
+
+static inline bool blk_crypto_rq_has_keyslot(struct request *rq)
 {
 	return false;
 }
@@ -127,12 +137,19 @@
 	return true;
 }
 
-blk_status_t __blk_crypto_init_request(struct request *rq);
-static inline blk_status_t blk_crypto_init_request(struct request *rq)
+blk_status_t __blk_crypto_rq_get_keyslot(struct request *rq);
+static inline blk_status_t blk_crypto_rq_get_keyslot(struct request *rq)
 {
 	if (blk_crypto_rq_is_encrypted(rq))
-		return __blk_crypto_init_request(rq);
+		return __blk_crypto_rq_get_keyslot(rq);
 	return BLK_STS_OK;
+}
+
+void __blk_crypto_rq_put_keyslot(struct request *rq);
+static inline void blk_crypto_rq_put_keyslot(struct request *rq)
+{
+	if (blk_crypto_rq_has_keyslot(rq))
+		__blk_crypto_rq_put_keyslot(rq);
 }
 
 void __blk_crypto_free_request(struct request *rq);
@@ -173,7 +190,7 @@
 {
 
 	if (blk_crypto_rq_is_encrypted(rq))
-		return blk_crypto_init_request(rq);
+		return blk_crypto_rq_get_keyslot(rq);
 	return BLK_STS_OK;
 }
 
diff --git a/kernel/block/blk-crypto.c b/kernel/block/blk-crypto.c
index 722868e..ccb2dc5 100644
--- a/kernel/block/blk-crypto.c
+++ b/kernel/block/blk-crypto.c
@@ -13,6 +13,7 @@
 #include <linux/blkdev.h>
 #include <linux/keyslot-manager.h>
 #include <linux/module.h>
+#include <linux/ratelimit.h>
 #include <linux/slab.h>
 
 #include "blk-crypto-internal.h"
@@ -217,26 +218,26 @@
 	return true;
 }
 
-blk_status_t __blk_crypto_init_request(struct request *rq)
+blk_status_t __blk_crypto_rq_get_keyslot(struct request *rq)
 {
 	return blk_ksm_get_slot_for_key(rq->q->ksm, rq->crypt_ctx->bc_key,
 					&rq->crypt_keyslot);
 }
 
-/**
- * __blk_crypto_free_request - Uninitialize the crypto fields of a request.
- *
- * @rq: The request whose crypto fields to uninitialize.
- *
- * Completely uninitializes the crypto fields of a request. If a keyslot has
- * been programmed into some inline encryption hardware, that keyslot is
- * released. The rq->crypt_ctx is also freed.
- */
-void __blk_crypto_free_request(struct request *rq)
+void __blk_crypto_rq_put_keyslot(struct request *rq)
 {
 	blk_ksm_put_slot(rq->crypt_keyslot);
+	rq->crypt_keyslot = NULL;
+}
+
+void __blk_crypto_free_request(struct request *rq)
+{
+	/* The keyslot, if one was needed, should have been released earlier. */
+	if (WARN_ON_ONCE(rq->crypt_keyslot))
+		__blk_crypto_rq_put_keyslot(rq);
+
 	mempool_free(rq->crypt_ctx, bio_crypt_ctx_pool);
-	blk_crypto_rq_set_defaults(rq);
+	rq->crypt_ctx = NULL;
 }
 
 /**
@@ -409,29 +410,39 @@
 EXPORT_SYMBOL_GPL(blk_crypto_start_using_key);
 
 /**
- * blk_crypto_evict_key() - Evict a key from any inline encryption hardware
- *			    it may have been programmed into
- * @q: The request queue who's associated inline encryption hardware this key
- *     might have been programmed into
- * @key: The key to evict
+ * blk_crypto_evict_key() - Evict a blk_crypto_key from a request_queue
+ * @q: a request_queue on which I/O using the key may have been done
+ * @key: the key to evict
  *
- * Upper layers (filesystems) must call this function to ensure that a key is
- * evicted from any hardware that it might have been programmed into.  The key
- * must not be in use by any in-flight IO when this function is called.
+ * For a given request_queue, this function removes the given blk_crypto_key
+ * from the keyslot management structures and evicts it from any underlying
+ * hardware keyslot(s) or blk-crypto-fallback keyslot it may have been
+ * programmed into.
  *
- * Return: 0 on success or if key is not present in the q's ksm, -err on error.
+ * Upper layers must call this before freeing the blk_crypto_key.  It must be
+ * called for every request_queue the key may have been used on.  The key must
+ * no longer be in use by any I/O when this function is called.
+ *
+ * Context: May sleep.
  */
-int blk_crypto_evict_key(struct request_queue *q,
-			 const struct blk_crypto_key *key)
+void blk_crypto_evict_key(struct request_queue *q,
+			  const struct blk_crypto_key *key)
 {
-	if (blk_ksm_crypto_cfg_supported(q->ksm, &key->crypto_cfg))
-		return blk_ksm_evict_key(q->ksm, key);
+	int err;
 
+	if (blk_ksm_crypto_cfg_supported(q->ksm, &key->crypto_cfg))
+		err = blk_ksm_evict_key(q->ksm, key);
+	else
+		err = blk_crypto_fallback_evict_key(key);
 	/*
-	 * If the request queue's associated inline encryption hardware didn't
-	 * have support for the key, then the key might have been programmed
-	 * into the fallback keyslot manager, so try to evict from there.
+	 * An error can only occur here if the key failed to be evicted from a
+	 * keyslot (due to a hardware or driver issue) or is allegedly still in
+	 * use by I/O (due to a kernel bug).  Even in these cases, the key is
+	 * still unlinked from the keyslot management structures, and the caller
+	 * is allowed and expected to free it right away.  There's nothing
+	 * callers can do to handle errors, so just log them and return void.
 	 */
-	return blk_crypto_fallback_evict_key(key);
+	if (err)
+		pr_warn_ratelimited("error %d evicting key\n", err);
 }
 EXPORT_SYMBOL_GPL(blk_crypto_evict_key);
diff --git a/kernel/block/blk-iocost.c b/kernel/block/blk-iocost.c
index fb8f959..7ba7c4e 100644
--- a/kernel/block/blk-iocost.c
+++ b/kernel/block/blk-iocost.c
@@ -232,7 +232,9 @@
 
 	/* 1/64k is granular enough and can easily be handled w/ u32 */
 	WEIGHT_ONE		= 1 << 16,
+};
 
+enum {
 	/*
 	 * As vtime is used to calculate the cost of each IO, it needs to
 	 * be fairly high precision.  For example, it should be able to
@@ -256,6 +258,11 @@
 	VRATE_MIN		= VTIME_PER_USEC * VRATE_MIN_PPM / MILLION,
 	VRATE_CLAMP_ADJ_PCT	= 4,
 
+	/* switch iff the conditions are met for longer than this */
+	AUTOP_CYCLE_NSEC	= 10LLU * NSEC_PER_SEC,
+};
+
+enum {
 	/* if IOs end up waiting for requests, issue less */
 	RQ_WAIT_BUSY_PCT	= 5,
 
@@ -293,9 +300,6 @@
 
 	/* don't let cmds which take a very long time pin lagging for too long */
 	MAX_LAGGING_PERIODS	= 10,
-
-	/* switch iff the conditions are met for longer than this */
-	AUTOP_CYCLE_NSEC	= 10LLU * NSEC_PER_SEC,
 
 	/*
 	 * Count IO size in 4k pages.  The 12bit shift helps keeping
@@ -872,9 +876,14 @@
 
 	*page = *seqio = *randio = 0;
 
-	if (bps)
-		*page = DIV64_U64_ROUND_UP(VTIME_PER_SEC,
-					   DIV_ROUND_UP_ULL(bps, IOC_PAGE_SIZE));
+	if (bps) {
+		u64 bps_pages = DIV_ROUND_UP_ULL(bps, IOC_PAGE_SIZE);
+
+		if (bps_pages)
+			*page = DIV64_U64_ROUND_UP(VTIME_PER_SEC, bps_pages);
+		else
+			*page = 1;
+	}
 
 	if (seqiops) {
 		v = DIV64_U64_ROUND_UP(VTIME_PER_SEC, seqiops);
@@ -2417,6 +2426,7 @@
 	u32 hwi, adj_step;
 	s64 margin;
 	u64 cost, new_inuse;
+	unsigned long flags;
 
 	current_hweight(iocg, NULL, &hwi);
 	old_hwi = hwi;
@@ -2435,11 +2445,11 @@
 	    iocg->inuse == iocg->active)
 		return cost;
 
-	spin_lock_irq(&ioc->lock);
+	spin_lock_irqsave(&ioc->lock, flags);
 
 	/* we own inuse only when @iocg is in the normal active state */
 	if (iocg->abs_vdebt || list_empty(&iocg->active_list)) {
-		spin_unlock_irq(&ioc->lock);
+		spin_unlock_irqrestore(&ioc->lock, flags);
 		return cost;
 	}
 
@@ -2460,7 +2470,7 @@
 	} while (time_after64(vtime + cost, now->vnow) &&
 		 iocg->inuse != iocg->active);
 
-	spin_unlock_irq(&ioc->lock);
+	spin_unlock_irqrestore(&ioc->lock, flags);
 
 	TRACE_IOCG_PATH(inuse_adjust, iocg, now,
 			old_inuse, iocg->inuse, old_hwi, hwi);
diff --git a/kernel/block/blk-merge.c b/kernel/block/blk-merge.c
index 087e422..4512ba4 100644
--- a/kernel/block/blk-merge.c
+++ b/kernel/block/blk-merge.c
@@ -803,6 +803,8 @@
 	if (!blk_discard_mergable(req))
 		elv_merge_requests(q, req, next);
 
+	blk_crypto_rq_put_keyslot(next);
+
 	/*
 	 * 'next' is going away, so update stats accordingly
 	 */
diff --git a/kernel/block/blk-mq-sched.c b/kernel/block/blk-mq-sched.c
index 8cd05dc..91b7626 100644
--- a/kernel/block/blk-mq-sched.c
+++ b/kernel/block/blk-mq-sched.c
@@ -45,8 +45,7 @@
 }
 
 /*
- * Mark a hardware queue as needing a restart. For shared queues, maintain
- * a count of how many hardware queues are marked for restart.
+ * Mark a hardware queue as needing a restart.
  */
 void blk_mq_sched_mark_restart_hctx(struct blk_mq_hw_ctx *hctx)
 {
@@ -109,7 +108,7 @@
 /*
  * Only SCSI implements .get_budget and .put_budget, and SCSI restarts
  * its queue by itself in its completion handler, so we don't need to
- * restart queue if .get_budget() returns BLK_STS_NO_RESOURCE.
+ * restart queue if .get_budget() fails to get the budget.
  *
  * Returns -EAGAIN if hctx->dispatch was found non-empty and run_work has to
  * be run again.  This is necessary to avoid starving flushes.
@@ -223,7 +222,7 @@
 /*
  * Only SCSI implements .get_budget and .put_budget, and SCSI restarts
  * its queue by itself in its completion handler, so we don't need to
- * restart queue if .get_budget() returns BLK_STS_NO_RESOURCE.
+ * restart queue if .get_budget() fails to get the budget.
  *
  * Returns -EAGAIN if hctx->dispatch was found non-empty and run_work has to
  * be run again.  This is necessary to avoid starving flushes.
diff --git a/kernel/block/blk-mq-sysfs.c b/kernel/block/blk-mq-sysfs.c
index 7b52e76..f0bc339 100644
--- a/kernel/block/blk-mq-sysfs.c
+++ b/kernel/block/blk-mq-sysfs.c
@@ -242,7 +242,7 @@
 {
 	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 @@
 	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;
 }
 
diff --git a/kernel/block/blk-mq.c b/kernel/block/blk-mq.c
index 5d520b1..21544b1 100644
--- a/kernel/block/blk-mq.c
+++ b/kernel/block/blk-mq.c
@@ -451,7 +451,8 @@
 	 * allocator for this for the rare use case of a command tied to
 	 * a specific queue.
 	 */
-	if (WARN_ON_ONCE(!(flags & (BLK_MQ_REQ_NOWAIT | BLK_MQ_REQ_RESERVED))))
+	if (WARN_ON_ONCE(!(flags & BLK_MQ_REQ_NOWAIT)) ||
+	    WARN_ON_ONCE(!(flags & BLK_MQ_REQ_RESERVED)))
 		return ERR_PTR(-EINVAL);
 
 	if (hctx_idx >= q->nr_hw_queues)
@@ -2247,7 +2248,7 @@
 
 	blk_mq_bio_to_request(rq, bio, nr_segs);
 
-	ret = blk_crypto_init_request(rq);
+	ret = blk_crypto_rq_get_keyslot(rq);
 	if (ret != BLK_STS_OK) {
 		bio->bi_status = ret;
 		bio_endio(bio);
diff --git a/kernel/block/blk-sysfs.c b/kernel/block/blk-sysfs.c
index 8c58163..9174137 100644
--- a/kernel/block/blk-sysfs.c
+++ b/kernel/block/blk-sysfs.c
@@ -726,6 +726,8 @@
 {
 	struct request_queue *q = container_of(rcu_head, struct request_queue,
 					       rcu_head);
+
+	percpu_ref_exit(&q->q_usage_counter);
 	kmem_cache_free(blk_requestq_cachep, q);
 }
 
diff --git a/kernel/block/keyslot-manager.c b/kernel/block/keyslot-manager.c
index 7ba541f..9470477 100644
--- a/kernel/block/keyslot-manager.c
+++ b/kernel/block/keyslot-manager.c
@@ -350,25 +350,16 @@
 	return true;
 }
 
-/**
- * blk_ksm_evict_key() - Evict a key from the lower layer device.
- * @ksm: The keyslot manager to evict from
- * @key: The key to evict
- *
- * Find the keyslot that the specified key was programmed into, and evict that
- * slot from the lower layer device. The slot must not be in use by any
- * in-flight IO when this function is called.
- *
- * Context: Process context. Takes and releases ksm->lock.
- * Return: 0 on success or if there's no keyslot with the specified key, -EBUSY
- *	   if the keyslot is still in use, or another -errno value on other
- *	   error.
+/*
+ * This is an internal function that evicts a key from an inline encryption
+ * device that can be either a real device or the blk-crypto-fallback "device".
+ * It is used only by blk_crypto_evict_key(); see that function for details.
  */
 int blk_ksm_evict_key(struct blk_keyslot_manager *ksm,
 		      const struct blk_crypto_key *key)
 {
 	struct blk_ksm_keyslot *slot;
-	int err = 0;
+	int err;
 
 	if (blk_ksm_is_passthrough(ksm)) {
 		if (ksm->ksm_ll_ops.keyslot_evict) {
@@ -382,22 +373,30 @@
 
 	blk_ksm_hw_enter(ksm);
 	slot = blk_ksm_find_keyslot(ksm, key);
-	if (!slot)
-		goto out_unlock;
+	if (!slot) {
+		/*
+		 * Not an error, since a key not in use by I/O is not guaranteed
+		 * to be in a keyslot.  There can be more keys than keyslots.
+		 */
+		err = 0;
+		goto out;
+	}
 
 	if (WARN_ON_ONCE(atomic_read(&slot->slot_refs) != 0)) {
+		/* BUG: key is still in use by I/O */
 		err = -EBUSY;
-		goto out_unlock;
+		goto out_remove;
 	}
 	err = ksm->ksm_ll_ops.keyslot_evict(ksm, key,
 					    blk_ksm_get_slot_idx(slot));
-	if (err)
-		goto out_unlock;
-
+out_remove:
+	/*
+	 * Callers free the key even on error, so unlink the key from the hash
+	 * table and clear slot->key even on error.
+	 */
 	hlist_del(&slot->hash_node);
 	slot->key = NULL;
-	err = 0;
-out_unlock:
+out:
 	blk_ksm_hw_exit(ksm);
 	return err;
 }
diff --git a/kernel/block/mq-deadline-main.c b/kernel/block/mq-deadline-main.c
index cdcf72e..560752a 100644
--- a/kernel/block/mq-deadline-main.c
+++ b/kernel/block/mq-deadline-main.c
@@ -793,6 +793,18 @@
 	rq->elv.priv[0] = NULL;
 }
 
+static bool dd_has_write_work(struct blk_mq_hw_ctx *hctx)
+{
+	struct deadline_data *dd = hctx->queue->elevator->elevator_data;
+	enum dd_prio p;
+
+	for (p = 0; p <= DD_PRIO_MAX; p++)
+		if (!list_empty_careful(&dd->per_prio[p].fifo_list[DD_WRITE]))
+			return true;
+
+	return false;
+}
+
 /*
  * Callback from inside blk_mq_free_request().
  *
@@ -816,7 +828,6 @@
 	struct dd_blkcg *blkcg = rq->elv.priv[0];
 	const u8 ioprio_class = dd_rq_ioclass(rq);
 	const enum dd_prio prio = ioprio_class_to_prio[ioprio_class];
-	struct dd_per_prio *per_prio = &dd->per_prio[prio];
 
 	dd_count(dd, completed, prio);
 	ddcg_count(blkcg, completed, ioprio_class);
@@ -826,9 +837,10 @@
 
 		spin_lock_irqsave(&dd->zone_lock, flags);
 		blk_req_zone_write_unlock(rq);
-		if (!list_empty(&per_prio->fifo_list[DD_WRITE]))
-			blk_mq_sched_mark_restart_hctx(rq->mq_hctx);
 		spin_unlock_irqrestore(&dd->zone_lock, flags);
+
+		if (dd_has_write_work(rq->mq_hctx))
+			blk_mq_sched_mark_restart_hctx(rq->mq_hctx);
 	}
 }
 
diff --git a/kernel/block/partitions/amiga.c b/kernel/block/partitions/amiga.c
index 9526491..a99ec7f 100644
--- a/kernel/block/partitions/amiga.c
+++ b/kernel/block/partitions/amiga.c
@@ -11,9 +11,17 @@
 #define pr_fmt(fmt) fmt
 
 #include <linux/types.h>
+#include <linux/mm_types.h>
+#include <linux/overflow.h>
 #include <linux/affs_hardblocks.h>
 
 #include "check.h"
+
+/* magic offsets in partition DosEnvVec */
+#define NR_HD	3
+#define NR_SECT	5
+#define LO_CYL	9
+#define HI_CYL	10
 
 static __inline__ u32
 checksum_block(__be32 *m, int size)
@@ -31,8 +39,12 @@
 	unsigned char *data;
 	struct RigidDiskBlock *rdb;
 	struct PartitionBlock *pb;
-	int start_sect, nr_sects, blk, part, res = 0;
-	int blksize = 1;	/* Multiplier for disk block size */
+	u64 start_sect, nr_sects;
+	sector_t blk, end_sect;
+	u32 cylblk;		/* rdb_CylBlocks = nr_heads*sect_per_track */
+	u32 nr_hd, nr_sect, lo_cyl, hi_cyl;
+	int part, res = 0;
+	unsigned int blksize = 1;	/* Multiplier for disk block size */
 	int slot = 1;
 	char b[BDEVNAME_SIZE];
 
@@ -41,7 +53,7 @@
 			goto rdb_done;
 		data = read_part_sector(state, blk, &sect);
 		if (!data) {
-			pr_err("Dev %s: unable to read RDB block %d\n",
+			pr_err("Dev %s: unable to read RDB block %llu\n",
 			       bdevname(state->bdev, b), blk);
 			res = -1;
 			goto rdb_done;
@@ -58,12 +70,12 @@
 		*(__be32 *)(data+0xdc) = 0;
 		if (checksum_block((__be32 *)data,
 				be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)==0) {
-			pr_err("Trashed word at 0xd0 in block %d ignored in checksum calculation\n",
+			pr_err("Trashed word at 0xd0 in block %llu ignored in checksum calculation\n",
 			       blk);
 			break;
 		}
 
-		pr_err("Dev %s: RDB in block %d has bad checksum\n",
+		pr_err("Dev %s: RDB in block %llu has bad checksum\n",
 		       bdevname(state->bdev, b), blk);
 	}
 
@@ -79,11 +91,16 @@
 	}
 	blk = be32_to_cpu(rdb->rdb_PartitionList);
 	put_dev_sector(sect);
-	for (part = 1; blk>0 && part<=16; part++, put_dev_sector(sect)) {
-		blk *= blksize;	/* Read in terms partition table understands */
+	for (part = 1; (s32) blk>0 && part<=16; part++, put_dev_sector(sect)) {
+		/* Read in terms partition table understands */
+		if (check_mul_overflow(blk, (sector_t) blksize, &blk)) {
+			pr_err("Dev %s: overflow calculating partition block %llu! Skipping partitions %u and beyond\n",
+				bdevname(state->bdev, b), blk, part);
+			break;
+		}
 		data = read_part_sector(state, blk, &sect);
 		if (!data) {
-			pr_err("Dev %s: unable to read partition block %d\n",
+			pr_err("Dev %s: unable to read partition block %llu\n",
 			       bdevname(state->bdev, b), blk);
 			res = -1;
 			goto rdb_done;
@@ -95,19 +112,70 @@
 		if (checksum_block((__be32 *)pb, be32_to_cpu(pb->pb_SummedLongs) & 0x7F) != 0 )
 			continue;
 
-		/* Tell Kernel about it */
+		/* RDB gives us more than enough rope to hang ourselves with,
+		 * many times over (2^128 bytes if all fields max out).
+		 * Some careful checks are in order, so check for potential
+		 * overflows.
+		 * We are multiplying four 32 bit numbers to one sector_t!
+		 */
 
-		nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 -
-			    be32_to_cpu(pb->pb_Environment[9])) *
-			   be32_to_cpu(pb->pb_Environment[3]) *
-			   be32_to_cpu(pb->pb_Environment[5]) *
-			   blksize;
+		nr_hd   = be32_to_cpu(pb->pb_Environment[NR_HD]);
+		nr_sect = be32_to_cpu(pb->pb_Environment[NR_SECT]);
+
+		/* CylBlocks is total number of blocks per cylinder */
+		if (check_mul_overflow(nr_hd, nr_sect, &cylblk)) {
+			pr_err("Dev %s: heads*sects %u overflows u32, skipping partition!\n",
+				bdevname(state->bdev, b), cylblk);
+			continue;
+		}
+
+		/* check for consistency with RDB defined CylBlocks */
+		if (cylblk > be32_to_cpu(rdb->rdb_CylBlocks)) {
+			pr_warn("Dev %s: cylblk %u > rdb_CylBlocks %u!\n",
+				bdevname(state->bdev, b), cylblk,
+				be32_to_cpu(rdb->rdb_CylBlocks));
+		}
+
+		/* RDB allows for variable logical block size -
+		 * normalize to 512 byte blocks and check result.
+		 */
+
+		if (check_mul_overflow(cylblk, blksize, &cylblk)) {
+			pr_err("Dev %s: partition %u bytes per cyl. overflows u32, skipping partition!\n",
+				bdevname(state->bdev, b), part);
+			continue;
+		}
+
+		/* Calculate partition start and end. Limit of 32 bit on cylblk
+		 * guarantees no overflow occurs if LBD support is enabled.
+		 */
+
+		lo_cyl = be32_to_cpu(pb->pb_Environment[LO_CYL]);
+		start_sect = ((u64) lo_cyl * cylblk);
+
+		hi_cyl = be32_to_cpu(pb->pb_Environment[HI_CYL]);
+		nr_sects = (((u64) hi_cyl - lo_cyl + 1) * cylblk);
+
 		if (!nr_sects)
 			continue;
-		start_sect = be32_to_cpu(pb->pb_Environment[9]) *
-			     be32_to_cpu(pb->pb_Environment[3]) *
-			     be32_to_cpu(pb->pb_Environment[5]) *
-			     blksize;
+
+		/* Warn user if partition end overflows u32 (AmigaDOS limit) */
+
+		if ((start_sect + nr_sects) > UINT_MAX) {
+			pr_warn("Dev %s: partition %u (%llu-%llu) needs 64 bit device support!\n",
+				bdevname(state->bdev, b), part,
+				start_sect, start_sect + nr_sects);
+		}
+
+		if (check_add_overflow(start_sect, nr_sects, &end_sect)) {
+			pr_err("Dev %s: partition %u (%llu-%llu) needs LBD device support, skipping partition!\n",
+				bdevname(state->bdev, b), part,
+				start_sect, end_sect);
+			continue;
+		}
+
+		/* Tell Kernel about it */
+
 		put_partition(state,slot++,start_sect,nr_sects);
 		{
 			/* Be even more informative to aid mounting */
diff --git a/kernel/build.config.gki.aarch64 b/kernel/build.config.gki.aarch64
index 738ddee..ba3c113 100644
--- a/kernel/build.config.gki.aarch64
+++ b/kernel/build.config.gki.aarch64
@@ -22,7 +22,9 @@
 android/abi_gki_aarch64_honor
 android/abi_gki_aarch64_imx
 android/abi_gki_aarch64_lenovo
+android/abi_gki_aarch64_moto
 android/abi_gki_aarch64_mtk
+android/abi_gki_aarch64_nothing
 android/abi_gki_aarch64_oplus
 android/abi_gki_aarch64_qcom
 android/abi_gki_aarch64_rockchip
@@ -30,6 +32,7 @@
 android/abi_gki_aarch64_virtual_device
 android/abi_gki_aarch64_vivo
 android/abi_gki_aarch64_xiaomi
+android/abi_gki_aarch64_zebra
 android/abi_gki_aarch64_asus
 android/abi_gki_aarch64_transsion
 android/abi_gki_aarch64_tuxera
diff --git a/kernel/crypto/algapi.c b/kernel/crypto/algapi.c
index 9de27da..42dca17 100644
--- a/kernel/crypto/algapi.c
+++ b/kernel/crypto/algapi.c
@@ -456,7 +456,9 @@
 	if (WARN(ret, "Algorithm %s is not registered", alg->cra_driver_name))
 		return;
 
-	BUG_ON(refcount_read(&alg->cra_refcnt) != 1);
+	if (WARN_ON(refcount_read(&alg->cra_refcnt) != 1))
+		return;
+
 	if (alg->cra_destroy)
 		alg->cra_destroy(alg);
 
diff --git a/kernel/crypto/asymmetric_keys/pkcs7_verify.c b/kernel/crypto/asymmetric_keys/pkcs7_verify.c
index ce49820..01e5445 100644
--- a/kernel/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/kernel/crypto/asymmetric_keys/pkcs7_verify.c
@@ -79,16 +79,16 @@
 		}
 
 		if (sinfo->msgdigest_len != sig->digest_size) {
-			pr_debug("Sig %u: Invalid digest size (%u)\n",
-				 sinfo->index, sinfo->msgdigest_len);
+			pr_warn("Sig %u: Invalid digest size (%u)\n",
+				sinfo->index, sinfo->msgdigest_len);
 			ret = -EBADMSG;
 			goto error;
 		}
 
 		if (memcmp(sig->digest, sinfo->msgdigest,
 			   sinfo->msgdigest_len) != 0) {
-			pr_debug("Sig %u: Message digest doesn't match\n",
-				 sinfo->index);
+			pr_warn("Sig %u: Message digest doesn't match\n",
+				sinfo->index);
 			ret = -EKEYREJECTED;
 			goto error;
 		}
@@ -488,7 +488,7 @@
 			       const void *data, size_t datalen)
 {
 	if (pkcs7->data) {
-		pr_debug("Data already supplied\n");
+		pr_warn("Data already supplied\n");
 		return -EINVAL;
 	}
 	pkcs7->data = data;
diff --git a/kernel/crypto/asymmetric_keys/public_key.c b/kernel/crypto/asymmetric_keys/public_key.c
index cf9b7ac..bd713a2 100644
--- a/kernel/crypto/asymmetric_keys/public_key.c
+++ b/kernel/crypto/asymmetric_keys/public_key.c
@@ -316,9 +316,10 @@
 	struct crypto_wait cwait;
 	struct crypto_akcipher *tfm;
 	struct akcipher_request *req;
-	struct scatterlist src_sg[2];
+	struct scatterlist src_sg;
 	char alg_name[CRYPTO_MAX_ALG_NAME];
-	char *key, *ptr;
+	char *buf, *ptr;
+	size_t buf_len;
 	int ret;
 
 	pr_devel("==>%s()\n", __func__);
@@ -342,34 +343,37 @@
 	if (!req)
 		goto error_free_tfm;
 
-	key = kmalloc(pkey->keylen + sizeof(u32) * 2 + pkey->paramlen,
-		      GFP_KERNEL);
-	if (!key)
+	buf_len = max_t(size_t, pkey->keylen + sizeof(u32) * 2 + pkey->paramlen,
+			sig->s_size + sig->digest_size);
+
+	buf = kmalloc(buf_len, GFP_KERNEL);
+	if (!buf)
 		goto error_free_req;
 
-	memcpy(key, pkey->key, pkey->keylen);
-	ptr = key + pkey->keylen;
+	memcpy(buf, pkey->key, pkey->keylen);
+	ptr = buf + pkey->keylen;
 	ptr = pkey_pack_u32(ptr, pkey->algo);
 	ptr = pkey_pack_u32(ptr, pkey->paramlen);
 	memcpy(ptr, pkey->params, pkey->paramlen);
 
 	if (pkey->key_is_private)
-		ret = crypto_akcipher_set_priv_key(tfm, key, pkey->keylen);
+		ret = crypto_akcipher_set_priv_key(tfm, buf, pkey->keylen);
 	else
-		ret = crypto_akcipher_set_pub_key(tfm, key, pkey->keylen);
+		ret = crypto_akcipher_set_pub_key(tfm, buf, pkey->keylen);
 	if (ret)
-		goto error_free_key;
+		goto error_free_buf;
 
 	if (strcmp(pkey->pkey_algo, "sm2") == 0 && sig->data_size) {
 		ret = cert_sig_digest_update(sig, tfm);
 		if (ret)
-			goto error_free_key;
+			goto error_free_buf;
 	}
 
-	sg_init_table(src_sg, 2);
-	sg_set_buf(&src_sg[0], sig->s, sig->s_size);
-	sg_set_buf(&src_sg[1], sig->digest, sig->digest_size);
-	akcipher_request_set_crypt(req, src_sg, NULL, sig->s_size,
+	memcpy(buf, sig->s, sig->s_size);
+	memcpy(buf + sig->s_size, sig->digest, sig->digest_size);
+
+	sg_init_one(&src_sg, buf, sig->s_size + sig->digest_size);
+	akcipher_request_set_crypt(req, &src_sg, NULL, sig->s_size,
 				   sig->digest_size);
 	crypto_init_wait(&cwait);
 	akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
@@ -377,8 +381,8 @@
 				      crypto_req_done, &cwait);
 	ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);
 
-error_free_key:
-	kfree(key);
+error_free_buf:
+	kfree(buf);
 error_free_req:
 	akcipher_request_free(req);
 error_free_tfm:
diff --git a/kernel/crypto/asymmetric_keys/verify_pefile.c b/kernel/crypto/asymmetric_keys/verify_pefile.c
index 7553ab1..22beaf2 100644
--- a/kernel/crypto/asymmetric_keys/verify_pefile.c
+++ b/kernel/crypto/asymmetric_keys/verify_pefile.c
@@ -74,7 +74,7 @@
 		break;
 
 	default:
-		pr_debug("Unknown PEOPT magic = %04hx\n", pe32->magic);
+		pr_warn("Unknown PEOPT magic = %04hx\n", pe32->magic);
 		return -ELIBBAD;
 	}
 
@@ -95,7 +95,7 @@
 	ctx->certs_size = ddir->certs.size;
 
 	if (!ddir->certs.virtual_address || !ddir->certs.size) {
-		pr_debug("Unsigned PE binary\n");
+		pr_warn("Unsigned PE binary\n");
 		return -ENODATA;
 	}
 
@@ -127,7 +127,7 @@
 	unsigned len;
 
 	if (ctx->sig_len < sizeof(wrapper)) {
-		pr_debug("Signature wrapper too short\n");
+		pr_warn("Signature wrapper too short\n");
 		return -ELIBBAD;
 	}
 
@@ -135,19 +135,23 @@
 	pr_debug("sig wrapper = { %x, %x, %x }\n",
 		 wrapper.length, wrapper.revision, wrapper.cert_type);
 
-	/* Both pesign and sbsign round up the length of certificate table
-	 * (in optional header data directories) to 8 byte alignment.
+	/* sbsign rounds up the length of certificate table (in optional
+	 * header data directories) to 8 byte alignment.  However, the PE
+	 * specification states that while entries are 8-byte aligned, this is
+	 * not included in their length, and as a result, pesign has not
+	 * rounded up since 0.110.
 	 */
-	if (round_up(wrapper.length, 8) != ctx->sig_len) {
-		pr_debug("Signature wrapper len wrong\n");
+	if (wrapper.length > ctx->sig_len) {
+		pr_warn("Signature wrapper bigger than sig len (%x > %x)\n",
+			ctx->sig_len, wrapper.length);
 		return -ELIBBAD;
 	}
 	if (wrapper.revision != WIN_CERT_REVISION_2_0) {
-		pr_debug("Signature is not revision 2.0\n");
+		pr_warn("Signature is not revision 2.0\n");
 		return -ENOTSUPP;
 	}
 	if (wrapper.cert_type != WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
-		pr_debug("Signature certificate type is not PKCS\n");
+		pr_warn("Signature certificate type is not PKCS\n");
 		return -ENOTSUPP;
 	}
 
@@ -160,7 +164,7 @@
 	ctx->sig_offset += sizeof(wrapper);
 	ctx->sig_len -= sizeof(wrapper);
 	if (ctx->sig_len < 4) {
-		pr_debug("Signature data missing\n");
+		pr_warn("Signature data missing\n");
 		return -EKEYREJECTED;
 	}
 
@@ -194,7 +198,7 @@
 		return 0;
 	}
 not_pkcs7:
-	pr_debug("Signature data not PKCS#7\n");
+	pr_warn("Signature data not PKCS#7\n");
 	return -ELIBBAD;
 }
 
@@ -337,8 +341,8 @@
 	digest_size = crypto_shash_digestsize(tfm);
 
 	if (digest_size != ctx->digest_len) {
-		pr_debug("Digest size mismatch (%zx != %x)\n",
-			 digest_size, ctx->digest_len);
+		pr_warn("Digest size mismatch (%zx != %x)\n",
+			digest_size, ctx->digest_len);
 		ret = -EBADMSG;
 		goto error_no_desc;
 	}
@@ -369,7 +373,7 @@
 	 * PKCS#7 certificate.
 	 */
 	if (memcmp(digest, ctx->digest, ctx->digest_len) != 0) {
-		pr_debug("Digest mismatch\n");
+		pr_warn("Digest mismatch\n");
 		ret = -EKEYREJECTED;
 	} else {
 		pr_debug("The digests match!\n");
diff --git a/kernel/crypto/asymmetric_keys/x509_public_key.c b/kernel/crypto/asymmetric_keys/x509_public_key.c
index ae450eb..b8135c3 100644
--- a/kernel/crypto/asymmetric_keys/x509_public_key.c
+++ b/kernel/crypto/asymmetric_keys/x509_public_key.c
@@ -132,6 +132,11 @@
 	if (strcmp(cert->pub->pkey_algo, cert->sig->pkey_algo) != 0)
 		goto out;
 
+	if (cert->unsupported_sig) {
+		ret = 0;
+		goto out;
+	}
+
 	ret = public_key_verify_signature(cert->pub, cert->sig);
 	if (ret < 0) {
 		if (ret == -ENOPKG) {
diff --git a/kernel/crypto/cryptd.c b/kernel/crypto/cryptd.c
index 668095e..ca3a40f 100644
--- a/kernel/crypto/cryptd.c
+++ b/kernel/crypto/cryptd.c
@@ -68,11 +68,12 @@
 
 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 @@
 				  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 @@
 	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 @@
 	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 @@
 	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 @@
 {
 	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 cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(&tfm->base);
 
-	return &ctx->child->base;
+	return ctx->child;
 }
 EXPORT_SYMBOL_GPL(cryptd_skcipher_child);
 
diff --git a/kernel/crypto/drbg.c b/kernel/crypto/drbg.c
index c769c44..839c36a 100644
--- a/kernel/crypto/drbg.c
+++ b/kernel/crypto/drbg.c
@@ -1516,6 +1516,14 @@
 		return 0;
 
 	drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0);
+	if (IS_ERR(drbg->jent)) {
+		const int err = PTR_ERR(drbg->jent);
+
+		drbg->jent = NULL;
+		if (fips_enabled)
+			return err;
+		pr_info("DRBG: Continuing without Jitter RNG\n");
+	}
 
 	return 0;
 }
@@ -1570,14 +1578,6 @@
 		ret = drbg_prepare_hrng(drbg);
 		if (ret)
 			goto free_everything;
-
-		if (IS_ERR(drbg->jent)) {
-			ret = PTR_ERR(drbg->jent);
-			drbg->jent = NULL;
-			if (fips_enabled || ret != -ENOENT)
-				goto free_everything;
-			pr_info("DRBG: Continuing without Jitter RNG\n");
-		}
 
 		reseed = false;
 	}
diff --git a/kernel/crypto/essiv.c b/kernel/crypto/essiv.c
index 8bcc5bd..3505b07 100644
--- a/kernel/crypto/essiv.c
+++ b/kernel/crypto/essiv.c
@@ -171,7 +171,12 @@
 	struct aead_request *req = areq->data;
 	struct essiv_aead_request_ctx *rctx = aead_request_ctx(req);
 
+	if (err == -EINPROGRESS)
+		goto out;
+
 	kfree(rctx->assoc);
+
+out:
 	aead_request_complete(req, err);
 }
 
@@ -247,7 +252,7 @@
 	err = enc ? crypto_aead_encrypt(subreq) :
 		    crypto_aead_decrypt(subreq);
 
-	if (rctx->assoc && err != -EINPROGRESS)
+	if (rctx->assoc && err != -EINPROGRESS && err != -EBUSY)
 		kfree(rctx->assoc);
 	return err;
 }
diff --git a/kernel/crypto/lrw.c b/kernel/crypto/lrw.c
index bcf09fb..80d9076 100644
--- a/kernel/crypto/lrw.c
+++ b/kernel/crypto/lrw.c
@@ -357,10 +357,10 @@
 	 * cipher name.
 	 */
 	if (!strncmp(cipher_name, "ecb(", 4)) {
-		unsigned len;
+		int len;
 
-		len = strlcpy(ecb_name, cipher_name + 4, sizeof(ecb_name));
-		if (len < 2 || len >= sizeof(ecb_name))
+		len = strscpy(ecb_name, cipher_name + 4, sizeof(ecb_name));
+		if (len < 2)
 			goto err_free_inst;
 
 		if (ecb_name[len - 1] != ')')
diff --git a/kernel/crypto/rsa-pkcs1pad.c b/kernel/crypto/rsa-pkcs1pad.c
index 9d80483..a4ebbb8 100644
--- a/kernel/crypto/rsa-pkcs1pad.c
+++ b/kernel/crypto/rsa-pkcs1pad.c
@@ -214,16 +214,14 @@
 		struct crypto_async_request *child_async_req, int err)
 {
 	struct akcipher_request *req = child_async_req->data;
-	struct crypto_async_request async_req;
 
 	if (err == -EINPROGRESS)
-		return;
+		goto out;
 
-	async_req.data = req->base.data;
-	async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
-	async_req.flags = child_async_req->flags;
-	req->base.complete(&async_req,
-			pkcs1pad_encrypt_sign_complete(req, err));
+	err = pkcs1pad_encrypt_sign_complete(req, err);
+
+out:
+	akcipher_request_complete(req, err);
 }
 
 static int pkcs1pad_encrypt(struct akcipher_request *req)
@@ -332,15 +330,14 @@
 		struct crypto_async_request *child_async_req, int err)
 {
 	struct akcipher_request *req = child_async_req->data;
-	struct crypto_async_request async_req;
 
 	if (err == -EINPROGRESS)
-		return;
+		goto out;
 
-	async_req.data = req->base.data;
-	async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
-	async_req.flags = child_async_req->flags;
-	req->base.complete(&async_req, pkcs1pad_decrypt_complete(req, err));
+	err = pkcs1pad_decrypt_complete(req, err);
+
+out:
+	akcipher_request_complete(req, err);
 }
 
 static int pkcs1pad_decrypt(struct akcipher_request *req)
@@ -512,15 +509,14 @@
 		struct crypto_async_request *child_async_req, int err)
 {
 	struct akcipher_request *req = child_async_req->data;
-	struct crypto_async_request async_req;
 
 	if (err == -EINPROGRESS)
-		return;
+		goto out;
 
-	async_req.data = req->base.data;
-	async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
-	async_req.flags = child_async_req->flags;
-	req->base.complete(&async_req, pkcs1pad_verify_complete(req, err));
+	err = pkcs1pad_verify_complete(req, err);
+
+out:
+	akcipher_request_complete(req, err);
 }
 
 /*
diff --git a/kernel/crypto/seqiv.c b/kernel/crypto/seqiv.c
index 0899d52..b1bcfe5 100644
--- a/kernel/crypto/seqiv.c
+++ b/kernel/crypto/seqiv.c
@@ -23,7 +23,7 @@
 	struct aead_request *subreq = aead_request_ctx(req);
 	struct crypto_aead *geniv;
 
-	if (err == -EINPROGRESS)
+	if (err == -EINPROGRESS || err == -EBUSY)
 		return;
 
 	if (err)
diff --git a/kernel/crypto/tcrypt.c b/kernel/crypto/tcrypt.c
index 8609174..7972d27 100644
--- a/kernel/crypto/tcrypt.c
+++ b/kernel/crypto/tcrypt.c
@@ -1282,15 +1282,6 @@
 			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) {
diff --git a/kernel/crypto/xts.c b/kernel/crypto/xts.c
index 6c12f30..3a5f1b2 100644
--- a/kernel/crypto/xts.c
+++ b/kernel/crypto/xts.c
@@ -203,12 +203,12 @@
 	if (!err) {
 		struct xts_request_ctx *rctx = skcipher_request_ctx(req);
 
-		rctx->subreq.base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+		rctx->subreq.base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG;
 		err = xts_xor_tweak_post(req, true);
 
 		if (!err && unlikely(req->cryptlen % XTS_BLOCK_SIZE)) {
 			err = xts_cts_final(req, crypto_skcipher_encrypt);
-			if (err == -EINPROGRESS)
+			if (err == -EINPROGRESS || err == -EBUSY)
 				return;
 		}
 	}
@@ -223,12 +223,12 @@
 	if (!err) {
 		struct xts_request_ctx *rctx = skcipher_request_ctx(req);
 
-		rctx->subreq.base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+		rctx->subreq.base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG;
 		err = xts_xor_tweak_post(req, false);
 
 		if (!err && unlikely(req->cryptlen % XTS_BLOCK_SIZE)) {
 			err = xts_cts_final(req, crypto_skcipher_decrypt);
-			if (err == -EINPROGRESS)
+			if (err == -EINPROGRESS || err == -EBUSY)
 				return;
 		}
 	}
@@ -396,10 +396,10 @@
 	 * cipher name.
 	 */
 	if (!strncmp(cipher_name, "ecb(", 4)) {
-		unsigned len;
+		int len;
 
-		len = strlcpy(ctx->name, cipher_name + 4, sizeof(ctx->name));
-		if (len < 2 || len >= sizeof(ctx->name))
+		len = strscpy(ctx->name, cipher_name + 4, sizeof(ctx->name));
+		if (len < 2)
 			goto err_free_inst;
 
 		if (ctx->name[len - 1] != ')')
diff --git a/kernel/drivers/acpi/acpica/Makefile b/kernel/drivers/acpi/acpica/Makefile
index 5970043..f919811 100644
--- a/kernel/drivers/acpi/acpica/Makefile
+++ b/kernel/drivers/acpi/acpica/Makefile
@@ -3,7 +3,7 @@
 # Makefile for ACPICA Core interpreter
 #
 
-ccflags-y			:= -Os -D_LINUX -DBUILDING_ACPICA
+ccflags-y			:= -D_LINUX -DBUILDING_ACPICA
 ccflags-$(CONFIG_ACPI_DEBUG)	+= -DACPI_DEBUG_OUTPUT
 
 # use acpi.o to put all files here into acpi.o modparam namespace
diff --git a/kernel/drivers/acpi/acpica/dbnames.c b/kernel/drivers/acpi/acpica/dbnames.c
index 3615e1a..b91155e 100644
--- a/kernel/drivers/acpi/acpica/dbnames.c
+++ b/kernel/drivers/acpi/acpica/dbnames.c
@@ -652,6 +652,9 @@
 		object_info =
 		    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info));
 
+		if (!object_info)
+			return (AE_NO_MEMORY);
+
 		/* Walk the namespace from the root */
 
 		(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
diff --git a/kernel/drivers/acpi/acpica/dsmethod.c b/kernel/drivers/acpi/acpica/dsmethod.c
index cf67caf..97971c7 100644
--- a/kernel/drivers/acpi/acpica/dsmethod.c
+++ b/kernel/drivers/acpi/acpica/dsmethod.c
@@ -517,7 +517,7 @@
 	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_FREE(info);
 	if (ACPI_FAILURE(status)) {
-		goto cleanup;
+		goto pop_walk_state;
 	}
 
 	next_walk_state->method_nesting_depth =
@@ -575,6 +575,12 @@
 
 	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 */
diff --git a/kernel/drivers/acpi/acpica/dswstate.c b/kernel/drivers/acpi/acpica/dswstate.c
index 809a0c0..f9ba769 100644
--- a/kernel/drivers/acpi/acpica/dswstate.c
+++ b/kernel/drivers/acpi/acpica/dswstate.c
@@ -576,9 +576,14 @@
 	ACPI_FUNCTION_TRACE(ds_init_aml_walk);
 
 	walk_state->parser_state.aml =
-	    walk_state->parser_state.aml_start = aml_start;
-	walk_state->parser_state.aml_end =
-	    walk_state->parser_state.pkg_end = aml_start + aml_length;
+	    walk_state->parser_state.aml_start =
+	    walk_state->parser_state.aml_end =
+	    walk_state->parser_state.pkg_end = aml_start;
+	/* Avoid undefined behavior: applying zero offset to null pointer */
+	if (aml_length != 0) {
+		walk_state->parser_state.aml_end += aml_length;
+		walk_state->parser_state.pkg_end += aml_length;
+	}
 
 	/* The next_op of the next_walk will be the beginning of the method */
 
diff --git a/kernel/drivers/acpi/acpica/hwvalid.c b/kernel/drivers/acpi/acpica/hwvalid.c
index b2ca7df..0cc4de3 100644
--- a/kernel/drivers/acpi/acpica/hwvalid.c
+++ b/kernel/drivers/acpi/acpica/hwvalid.c
@@ -23,8 +23,8 @@
  *
  * The table is used to implement the Microsoft port access rules that
  * first appeared in Windows XP. Some ports are always illegal, and some
- * ports are only illegal if the BIOS calls _OSI with a win_XP string or
- * later (meaning that the BIOS itelf is post-XP.)
+ * ports are only illegal if the BIOS calls _OSI with nothing newer than
+ * the specific _OSI strings.
  *
  * This provides ACPICA with the desired port protections and
  * Microsoft compatibility.
@@ -145,7 +145,8 @@
 
 			/* Port illegality may depend on the _OSI calls made by the BIOS */
 
-			if (acpi_gbl_osi_data >= port_info->osi_dependency) {
+			if (port_info->osi_dependency == ACPI_ALWAYS_ILLEGAL ||
+			    acpi_gbl_osi_data == port_info->osi_dependency) {
 				ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
 						  "Denied AML access to port 0x%8.8X%8.8X/%X (%s 0x%.4X-0x%.4X)\n",
 						  ACPI_FORMAT_UINT64(address),
diff --git a/kernel/drivers/acpi/acpica/nsrepair.c b/kernel/drivers/acpi/acpica/nsrepair.c
index 90db2d8..f28d811 100644
--- a/kernel/drivers/acpi/acpica/nsrepair.c
+++ b/kernel/drivers/acpi/acpica/nsrepair.c
@@ -181,8 +181,9 @@
 	 * Try to fix if there was no return object. Warning if failed to fix.
 	 */
 	if (!return_object) {
-		if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) {
-			if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
+		if (expected_btypes) {
+			if (!(expected_btypes & ACPI_RTYPE_NONE) &&
+			    package_index != ACPI_NOT_PACKAGE_ELEMENT) {
 				ACPI_WARN_PREDEFINED((AE_INFO,
 						      info->full_pathname,
 						      ACPI_WARN_ALWAYS,
@@ -196,14 +197,15 @@
 				if (ACPI_SUCCESS(status)) {
 					return (AE_OK);	/* Repair was successful */
 				}
-			} else {
+			}
+
+			if (expected_btypes != ACPI_RTYPE_NONE) {
 				ACPI_WARN_PREDEFINED((AE_INFO,
 						      info->full_pathname,
 						      ACPI_WARN_ALWAYS,
 						      "Missing expected return value"));
+				return (AE_AML_NO_RETURN_VALUE);
 			}
-
-			return (AE_AML_NO_RETURN_VALUE);
 		}
 	}
 
diff --git a/kernel/drivers/acpi/acpica/psopcode.c b/kernel/drivers/acpi/acpica/psopcode.c
index 28af492..62957cb 100644
--- a/kernel/drivers/acpi/acpica/psopcode.c
+++ b/kernel/drivers/acpi/acpica/psopcode.c
@@ -603,7 +603,7 @@
 
 /* 7E */ ACPI_OP("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY,
 			 AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R,
-			 AML_FLAGS_EXEC_0A_0T_1R),
+			 AML_FLAGS_EXEC_0A_0T_1R | AML_NO_OPERAND_RESOLVE),
 
 /* ACPI 5.0 opcodes */
 
diff --git a/kernel/drivers/acpi/acpica/utcopy.c b/kernel/drivers/acpi/acpica/utcopy.c
index 41bdd02..9a7cc67 100644
--- a/kernel/drivers/acpi/acpica/utcopy.c
+++ b/kernel/drivers/acpi/acpica/utcopy.c
@@ -916,13 +916,6 @@
 	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);
 }
 
diff --git a/kernel/drivers/acpi/apei/ghes.c b/kernel/drivers/acpi/apei/ghes.c
index 9bdb5bd..8678e16 100644
--- a/kernel/drivers/acpi/apei/ghes.c
+++ b/kernel/drivers/acpi/apei/ghes.c
@@ -1457,33 +1457,35 @@
 	.remove		= ghes_remove,
 };
 
-static int __init ghes_init(void)
+void __init ghes_init(void)
 {
 	int rc;
 
+	sdei_init();
+
 	if (acpi_disabled)
-		return -ENODEV;
+		return;
 
 	switch (hest_disable) {
 	case HEST_NOT_FOUND:
-		return -ENODEV;
+		return;
 	case HEST_DISABLED:
 		pr_info(GHES_PFX "HEST is not enabled!\n");
-		return -EINVAL;
+		return;
 	default:
 		break;
 	}
 
 	if (ghes_disable) {
 		pr_info(GHES_PFX "GHES is not enabled!\n");
-		return -EINVAL;
+		return;
 	}
 
 	ghes_nmi_init_cxt();
 
 	rc = platform_driver_register(&ghes_platform_driver);
 	if (rc)
-		goto err;
+		return;
 
 	rc = apei_osc_setup();
 	if (rc == 0 && osc_sb_apei_support_acked)
@@ -1494,9 +1496,4 @@
 		pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n");
 	else
 		pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
-
-	return 0;
-err:
-	return rc;
 }
-device_initcall(ghes_init);
diff --git a/kernel/drivers/acpi/arm64/iort.c b/kernel/drivers/acpi/arm64/iort.c
index 50ed949..554943b 100644
--- a/kernel/drivers/acpi/arm64/iort.c
+++ b/kernel/drivers/acpi/arm64/iort.c
@@ -1474,7 +1474,10 @@
 static struct acpi_platform_list pmcg_plat_info[] __initdata = {
 	/* HiSilicon Hip08 Platform */
 	{"HISI  ", "HIP08   ", 0, ACPI_SIG_IORT, greater_than_or_equal,
-	 "Erratum #162001800", IORT_SMMU_V3_PMCG_HISI_HIP08},
+	 "Erratum #162001800, Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP08},
+	/* HiSilicon Hip09 Platform */
+	{"HISI  ", "HIP09   ", 0, ACPI_SIG_IORT, greater_than_or_equal,
+	 "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
 	{ }
 };
 
diff --git a/kernel/drivers/acpi/battery.c b/kernel/drivers/acpi/battery.c
index be743d1..8b43efe 100644
--- a/kernel/drivers/acpi/battery.c
+++ b/kernel/drivers/acpi/battery.c
@@ -454,7 +454,7 @@
 			u8 *ptr = (u8 *)battery + offsets[i].offset;
 			if (element->type == ACPI_TYPE_STRING ||
 			    element->type == ACPI_TYPE_BUFFER)
-				strncpy(ptr, element->string.pointer, 32);
+				strscpy(ptr, element->string.pointer, 32);
 			else if (element->type == ACPI_TYPE_INTEGER) {
 				strncpy(ptr, (u8 *)&element->integer.value,
 					sizeof(u64));
diff --git a/kernel/drivers/acpi/bus.c b/kernel/drivers/acpi/bus.c
index 5e14288..60dfe63 100644
--- a/kernel/drivers/acpi/bus.c
+++ b/kernel/drivers/acpi/bus.c
@@ -1252,6 +1252,8 @@
 
 	pci_mmcfg_late_init();
 	acpi_iort_init();
+	acpi_hest_init();
+	ghes_init();
 	acpi_scan_init();
 	acpi_ec_init();
 	acpi_debugfs_init();
diff --git a/kernel/drivers/acpi/button.c b/kernel/drivers/acpi/button.c
index 0d93a5e..4861aad 100644
--- a/kernel/drivers/acpi/button.c
+++ b/kernel/drivers/acpi/button.c
@@ -83,6 +83,15 @@
 		.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_DISABLED,
 	},
 	{
+		/* Nextbook Ares 8A tablet, _LID device always reports lid closed */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "CherryTrail"),
+			DMI_MATCH(DMI_BIOS_VERSION, "M882"),
+		},
+		.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_DISABLED,
+	},
+	{
 		/*
 		 * Medion Akoya E2215T, notification of the LID device only
 		 * happens on close, not on open and _LID always returns closed.
diff --git a/kernel/drivers/acpi/device_pm.c b/kernel/drivers/acpi/device_pm.c
index ecd2ddc..66e53df 100644
--- a/kernel/drivers/acpi/device_pm.c
+++ b/kernel/drivers/acpi/device_pm.c
@@ -1326,4 +1326,33 @@
 	return 1;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
+
+/**
+ * acpi_storage_d3 - Check if D3 should be used in the suspend path
+ * @dev: Device to check
+ *
+ * Return %true if the platform firmware wants @dev to be programmed
+ * into D3hot or D3cold (if supported) in the suspend path, or %false
+ * when there is no specific preference. On some platforms, if this
+ * hint is ignored, @dev may remain unresponsive after suspending the
+ * platform as a whole.
+ *
+ * Although the property has storage in the name it actually is
+ * applied to the PCIe slot and plugging in a non-storage device the
+ * same platform restrictions will likely apply.
+ */
+bool acpi_storage_d3(struct device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	u8 val;
+
+	if (!adev)
+		return false;
+	if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable",
+			&val))
+		return false;
+	return val == 1;
+}
+EXPORT_SYMBOL_GPL(acpi_storage_d3);
+
 #endif /* CONFIG_PM */
diff --git a/kernel/drivers/acpi/ec.c b/kernel/drivers/acpi/ec.c
index 4707d18..4878844 100644
--- a/kernel/drivers/acpi/ec.c
+++ b/kernel/drivers/acpi/ec.c
@@ -1114,6 +1114,7 @@
 void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
 {
 	acpi_ec_remove_query_handlers(ec, false, query_bit);
+	flush_workqueue(ec_query_wq);
 }
 EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
 
diff --git a/kernel/drivers/acpi/nfit/core.c b/kernel/drivers/acpi/nfit/core.c
index 6d1fae6..d87d4e8 100644
--- a/kernel/drivers/acpi/nfit/core.c
+++ b/kernel/drivers/acpi/nfit/core.c
@@ -3686,8 +3686,8 @@
 
 	mutex_lock(&acpi_desc->init_mutex);
 	set_bit(ARS_CANCEL, &acpi_desc->scrub_flags);
-	cancel_delayed_work_sync(&acpi_desc->dwork);
 	mutex_unlock(&acpi_desc->init_mutex);
+	cancel_delayed_work_sync(&acpi_desc->dwork);
 
 	/*
 	 * Bounce the nvdimm bus lock to make sure any in-flight
diff --git a/kernel/drivers/acpi/pci_root.c b/kernel/drivers/acpi/pci_root.c
index c12b5fb..d972ea0 100644
--- a/kernel/drivers/acpi/pci_root.c
+++ b/kernel/drivers/acpi/pci_root.c
@@ -20,8 +20,6 @@
 #include <linux/slab.h>
 #include <linux/dmi.h>
 #include <linux/platform_data/x86/apple.h>
-#include <acpi/apei.h>	/* for acpi_hest_init() */
-
 #include "internal.h"
 
 #define ACPI_PCI_ROOT_CLASS		"pci_bridge"
@@ -950,7 +948,6 @@
 
 void __init acpi_pci_root_init(void)
 {
-	acpi_hest_init();
 	if (acpi_pci_disabled)
 		return;
 
diff --git a/kernel/drivers/acpi/processor_idle.c b/kernel/drivers/acpi/processor_idle.c
index e5dd87d..59781e7 100644
--- a/kernel/drivers/acpi/processor_idle.c
+++ b/kernel/drivers/acpi/processor_idle.c
@@ -536,10 +536,27 @@
 	/* No delay is needed if we are in guest */
 	if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
 		return;
+	/*
+	 * Modern (>=Nehalem) Intel systems use ACPI via intel_idle,
+	 * not this code.  Assume that any Intel systems using this
+	 * are ancient and may need the dummy wait.  This also assumes
+	 * that the motivating chipset issue was Intel-only.
+	 */
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return;
 #endif
-	/* Dummy wait op - must do something useless after P_LVL2 read
-	   because chipsets cannot guarantee that STPCLK# signal
-	   gets asserted in time to freeze execution properly. */
+	/*
+	 * Dummy wait op - must do something useless after P_LVL2 read
+	 * because chipsets cannot guarantee that STPCLK# signal gets
+	 * asserted in time to freeze execution properly
+	 *
+	 * This workaround has been in place since the original ACPI
+	 * implementation was merged, circa 2002.
+	 *
+	 * If a profile is pointing to this instruction, please first
+	 * consider moving your system to a more modern idle
+	 * mechanism.
+	 */
 	inl(acpi_gbl_FADT.xpm_timer_block.address);
 }
 
diff --git a/kernel/drivers/acpi/processor_pdc.c b/kernel/drivers/acpi/processor_pdc.c
index 813f1b7..c0d2d9a 100644
--- a/kernel/drivers/acpi/processor_pdc.c
+++ b/kernel/drivers/acpi/processor_pdc.c
@@ -14,6 +14,8 @@
 #include <linux/acpi.h>
 #include <acpi/processor.h>
 
+#include <xen/xen.h>
+
 #include "internal.h"
 
 #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
@@ -50,6 +52,15 @@
 		return false;
 	}
 
+	if (xen_initial_domain())
+		/*
+		 * When running as a Xen dom0 the number of processors Linux
+		 * sees can be different from the real number of processors on
+		 * the system, and we still need to execute _PDC for all of
+		 * them.
+		 */
+		return xen_processor_present(acpi_id);
+
 	type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
 	cpuid = acpi_get_cpuid(handle, type, acpi_id);
 
diff --git a/kernel/drivers/acpi/processor_perflib.c b/kernel/drivers/acpi/processor_perflib.c
index b04a689..fc42d64 100644
--- a/kernel/drivers/acpi/processor_perflib.c
+++ b/kernel/drivers/acpi/processor_perflib.c
@@ -56,6 +56,8 @@
 {
 	acpi_status status = 0;
 	unsigned long long ppc = 0;
+	s32 qos_value;
+	int index;
 	int ret;
 
 	if (!pr)
@@ -75,17 +77,30 @@
 		return -ENODEV;
 	}
 
-	pr_debug("CPU %d: _PPC is %d - frequency %s limited\n", pr->id,
-		       (int)ppc, ppc ? "" : "not");
+	index = ppc;
 
-	pr->performance_platform_limit = (int)ppc;
-
-	if (ppc >= pr->performance->state_count ||
-	    unlikely(!freq_qos_request_active(&pr->perflib_req)))
+	if (pr->performance_platform_limit == index ||
+	    ppc >= pr->performance->state_count)
 		return 0;
 
-	ret = freq_qos_update_request(&pr->perflib_req,
-			pr->performance->states[ppc].core_frequency * 1000);
+	pr_debug("CPU %d: _PPC is %d - frequency %s limited\n", pr->id,
+		 index, index ? "is" : "is not");
+
+	pr->performance_platform_limit = index;
+
+	if (unlikely(!freq_qos_request_active(&pr->perflib_req)))
+		return 0;
+
+	/*
+	 * If _PPC returns 0, it means that all of the available states can be
+	 * used ("no limit").
+	 */
+	if (index == 0)
+		qos_value = FREQ_QOS_MAX_DEFAULT_VALUE;
+	else
+		qos_value = pr->performance->states[index].core_frequency * 1000;
+
+	ret = freq_qos_update_request(&pr->perflib_req, qos_value);
 	if (ret < 0) {
 		pr_warn("Failed to update perflib freq constraint: CPU%d (%d)\n",
 			pr->id, ret);
@@ -168,9 +183,16 @@
 		if (!pr)
 			continue;
 
+		/*
+		 * Reset performance_platform_limit in case there is a stale
+		 * value in it, so as to make it match the "no limit" QoS value
+		 * below.
+		 */
+		pr->performance_platform_limit = 0;
+
 		ret = freq_qos_add_request(&policy->constraints,
-					   &pr->perflib_req,
-					   FREQ_QOS_MAX, INT_MAX);
+					   &pr->perflib_req, FREQ_QOS_MAX,
+					   FREQ_QOS_MAX_DEFAULT_VALUE);
 		if (ret < 0)
 			pr_err("Failed to add freq constraint for CPU%d (%d)\n",
 			       cpu, ret);
diff --git a/kernel/drivers/acpi/thermal.c b/kernel/drivers/acpi/thermal.c
index 859b1de..d62bf6d 100644
--- a/kernel/drivers/acpi/thermal.c
+++ b/kernel/drivers/acpi/thermal.c
@@ -1120,8 +1120,6 @@
 		return -EINVAL;
 
 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
-		if (!(&tz->trips.active[i]))
-			break;
 		if (!tz->trips.active[i].flags.valid)
 			break;
 		tz->trips.active[i].flags.enabled = 1;
diff --git a/kernel/drivers/acpi/video_detect.c b/kernel/drivers/acpi/video_detect.c
index b137131..a5cb9e1 100644
--- a/kernel/drivers/acpi/video_detect.c
+++ b/kernel/drivers/acpi/video_detect.c
@@ -308,12 +308,21 @@
 		},
 	},
 	{
+	 /* https://bugzilla.suse.com/show_bug.cgi?id=1208724 */
+	 .callback = video_detect_force_native,
+	 /* Lenovo Ideapad Z470 */
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		DMI_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Z470"),
+		},
+	},
+	{
 	 /* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */
 	 .callback = video_detect_force_native,
 	 .ident = "Lenovo Ideapad Z570",
 	 .matches = {
 		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-		DMI_MATCH(DMI_PRODUCT_NAME, "102434U"),
+		DMI_MATCH(DMI_PRODUCT_VERSION, "Ideapad Z570"),
 		},
 	},
 	{
@@ -333,6 +342,40 @@
 		},
 	},
 	{
+	 .callback = video_detect_force_native,
+	 /* Lenovo ThinkPad X131e (3371 AMD version) */
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "3371"),
+		},
+	},
+	{
+	 .callback = video_detect_force_native,
+	 /* Apple iMac11,3 */
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+		DMI_MATCH(DMI_PRODUCT_NAME, "iMac11,3"),
+		},
+	},
+	{
+	 /* https://gitlab.freedesktop.org/drm/amd/-/issues/1838 */
+	 .callback = video_detect_force_native,
+	 /* Apple iMac12,1 */
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+		DMI_MATCH(DMI_PRODUCT_NAME, "iMac12,1"),
+		},
+	},
+	{
+	 /* https://gitlab.freedesktop.org/drm/amd/-/issues/2753 */
+	 .callback = video_detect_force_native,
+	 /* Apple iMac12,2 */
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+		DMI_MATCH(DMI_PRODUCT_NAME, "iMac12,2"),
+		},
+	},
+	{
 	 /* https://bugzilla.redhat.com/show_bug.cgi?id=1217249 */
 	 .callback = video_detect_force_native,
 	 .ident = "Apple MacBook Pro 12,1",
diff --git a/kernel/drivers/amba/bus.c b/kernel/drivers/amba/bus.c
index 47c7244..52ab582 100644
--- a/kernel/drivers/amba/bus.c
+++ b/kernel/drivers/amba/bus.c
@@ -363,6 +363,7 @@
 {
 	struct amba_device *d = to_amba_device(dev);
 
+	of_node_put(d->dev.of_node);
 	if (d->res.parent)
 		release_resource(&d->res);
 	kfree(d);
diff --git a/kernel/drivers/android/binder.c b/kernel/drivers/android/binder.c
index 16e0ba3..4165922 100644
--- a/kernel/drivers/android/binder.c
+++ b/kernel/drivers/android/binder.c
@@ -1399,7 +1399,8 @@
  */
 static void binder_free_ref(struct binder_ref *ref)
 {
-	trace_android_vh_binder_del_ref(ref->proc ? ref->proc->tsk : 0, ref->data.desc);
+	trace_android_vh_binder_del_ref(ref->proc ? ref->proc->tsk : NULL,
+					ref->data.desc);
 	if (ref->node)
 		binder_free_node(ref->node);
 	kfree(ref->death);
@@ -2033,24 +2034,23 @@
 static void binder_transaction_buffer_release(struct binder_proc *proc,
 					      struct binder_thread *thread,
 					      struct binder_buffer *buffer,
-					      binder_size_t failed_at,
+					      binder_size_t off_end_offset,
 					      bool is_failure)
 {
 	int debug_id = buffer->debug_id;
-	binder_size_t off_start_offset, buffer_offset, off_end_offset;
+	binder_size_t off_start_offset, buffer_offset;
 
 	binder_debug(BINDER_DEBUG_TRANSACTION,
 		     "%d buffer release %d, size %zd-%zd, failed at %llx\n",
 		     proc->pid, buffer->debug_id,
 		     buffer->data_size, buffer->offsets_size,
-		     (unsigned long long)failed_at);
+		     (unsigned long long)off_end_offset);
 
 	if (buffer->target_node)
 		binder_dec_node(buffer->target_node, 1, 0);
 
 	off_start_offset = ALIGN(buffer->data_size, sizeof(void *));
-	off_end_offset = is_failure && failed_at ? failed_at :
-				off_start_offset + buffer->offsets_size;
+
 	for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
 	     buffer_offset += sizeof(binder_size_t)) {
 		struct binder_object_header *hdr;
@@ -2208,6 +2208,21 @@
 			break;
 		}
 	}
+}
+
+/* Clean up all the objects in the buffer */
+static inline void binder_release_entire_buffer(struct binder_proc *proc,
+						struct binder_thread *thread,
+						struct binder_buffer *buffer,
+						bool is_failure)
+{
+	binder_size_t off_end_offset;
+
+	off_end_offset = ALIGN(buffer->data_size, sizeof(void *));
+	off_end_offset += buffer->offsets_size;
+
+	binder_transaction_buffer_release(proc, thread, buffer,
+					  off_end_offset, is_failure);
 }
 
 static int binder_translate_binder(struct flat_binder_object *fp,
@@ -2871,7 +2886,8 @@
 		thread = binder_select_thread_ilocked(proc);
 
 	trace_android_vh_binder_proc_transaction(current, proc->tsk,
-		thread ? thread->task : 0, node->debug_id, t->code, pending_async);
+		thread ? thread->task : NULL, node->debug_id, t->code,
+		pending_async);
 
 	if (thread) {
 		binder_transaction_priority(thread->task, t, node_prio,
@@ -2914,7 +2930,7 @@
 		t_outdated->buffer = NULL;
 		buffer->transaction = NULL;
 		trace_binder_transaction_update_buffer_release(buffer);
-		binder_transaction_buffer_release(proc, NULL, buffer, 0, 0);
+		binder_release_entire_buffer(proc, NULL, buffer, false);
 		binder_alloc_free_buf(&proc->alloc, buffer);
 		kfree(t_outdated);
 		binder_stats_deleted(BINDER_STAT_TRANSACTION);
@@ -3828,7 +3844,7 @@
 		binder_node_inner_unlock(buf_node);
 	}
 	trace_binder_transaction_buffer_release(buffer);
-	binder_transaction_buffer_release(proc, thread, buffer, 0, is_failure);
+	binder_release_entire_buffer(proc, thread, buffer, is_failure);
 	binder_alloc_free_buf(&proc->alloc, buffer);
 }
 
@@ -6663,6 +6679,7 @@
 
 err_alloc_device_names_failed:
 	debugfs_remove_recursive(binder_debugfs_dir_entry_root);
+	binder_alloc_shrinker_exit();
 
 	return ret;
 }
diff --git a/kernel/drivers/android/binder_alloc.c b/kernel/drivers/android/binder_alloc.c
index 447342a..eb5633c 100644
--- a/kernel/drivers/android/binder_alloc.c
+++ b/kernel/drivers/android/binder_alloc.c
@@ -1097,6 +1097,12 @@
 	return ret;
 }
 
+void binder_alloc_shrinker_exit(void)
+{
+	unregister_shrinker(&binder_shrinker);
+	list_lru_destroy(&binder_alloc_lru);
+}
+
 /**
  * check_buffer() - verify that buffer/offset is safe to access
  * @alloc: binder_alloc for this proc
diff --git a/kernel/drivers/android/binder_alloc.h b/kernel/drivers/android/binder_alloc.h
index 7dea57a..399f2b2 100644
--- a/kernel/drivers/android/binder_alloc.h
+++ b/kernel/drivers/android/binder_alloc.h
@@ -131,6 +131,7 @@
 						  int pid);
 extern void binder_alloc_init(struct binder_alloc *alloc);
 extern int binder_alloc_shrinker_init(void);
+extern void binder_alloc_shrinker_exit(void);
 extern void binder_alloc_vma_close(struct binder_alloc *alloc);
 extern struct binder_buffer *
 binder_alloc_prepare_to_free(struct binder_alloc *alloc,
diff --git a/kernel/drivers/android/vendor_hooks.c b/kernel/drivers/android/vendor_hooks.c
index 18ef440..3ca92b6 100644
--- a/kernel/drivers/android/vendor_hooks.c
+++ b/kernel/drivers/android/vendor_hooks.c
@@ -42,7 +42,6 @@
 #include <trace/hooks/power.h>
 #include <trace/hooks/fault.h>
 #include <trace/hooks/iommu.h>
-#include <trace/hooks/dma_noalias.h>
 #include <trace/hooks/thermal.h>
 #include <trace/hooks/ufshcd.h>
 #include <trace/hooks/block.h>
@@ -77,6 +76,7 @@
 #include <trace/hooks/ipv4.h>
 #include <trace/hooks/pci.h>
 #include <trace/hooks/dmabuf.h>
+#include <trace/hooks/wakeupbypass.h>
 
 /*
  * Export tracepoints that act as a bare tracehook (ie: have no trace event
@@ -106,6 +106,7 @@
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_do_send_sig_info);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_process_killed);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_killed_process);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_percpu_rwsem_wq_add);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_init);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_wake);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_write_finished);
@@ -122,6 +123,9 @@
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mutex_wait_finish);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rtmutex_wait_start);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rtmutex_wait_finish);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mutex_opt_spin_start);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mutex_opt_spin_finish);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mutex_can_spin_on_owner);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_read_wait_start);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_read_wait_finish);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_write_wait_start);
@@ -131,6 +135,9 @@
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_mark_wake_readers);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_up_read_end);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_up_write_end);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_opt_spin_start);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_opt_spin_finish);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_can_spin_on_owner);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sched_show_task);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_shmem_alloc_page);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpu_idle_enter);
@@ -211,7 +218,6 @@
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_sea);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_mem_abort);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_sp_pc_abort);
-EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_setup_dma_ops);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_iommu_setup_dma_ops);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_iommu_setup_dma_ops);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_iommu_alloc_iova);
@@ -271,6 +277,8 @@
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_exit_creds);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_override_creds);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_revert_creds);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_dm_bufio_shrink_scan_bypass);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cleanup_old_buffers_bypass);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_record_mutex_lock_starttime);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_record_rtmutex_lock_starttime);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_record_rwsem_lock_starttime);
@@ -326,6 +334,12 @@
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_referenced_check_bypass);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_drain_all_pages_bypass);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cma_drain_all_pages_bypass);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_unref_page_bypass);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_kvmalloc_node_use_vmalloc);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_should_alloc_pages_retry);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_unreserve_highatomic_bypass);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_pageset_update);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rmqueue_bulk_bypass);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_pcplist_add_cma_pages_bypass);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_psi_event);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_psi_group);
@@ -435,6 +449,7 @@
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_handle_tlb_conf);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_shrink_node_memcgs);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ra_tuning_max_page);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_tune_mmap_readaround);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_handle_pte_fault_end);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_handle_pte_fault_end);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cow_user_page);
@@ -454,12 +469,17 @@
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_swap_slot);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_get_swap_page);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_swap_page);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_add_to_avail_list);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_del_from_avail_list);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh___cgroup_throttle_swaprate);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_madvise_cold_or_pageout);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_isolated_for_reclaim);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_should_end_madvise);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_inactive_is_low);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_snapshot_refaults);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_account_swap_pages);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_unuse_swap_page);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_swap_avail_heads_init);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_init_swap_info_struct);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_si_swapinfo);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_alloc_si);
@@ -475,6 +495,10 @@
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_look_around_migrate_page);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_test_clear_look_around_ref);
 EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_dma_buf_stats_teardown);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_madvise_cold_or_pageout_abort);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_compact_finished);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_wakeup_bypass);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_skip_swapcache);
 /*
  * For type visibility
  */
diff --git a/kernel/drivers/ata/ahci.c b/kernel/drivers/ata/ahci.c
index ff2add0..4297a8d 100644
--- a/kernel/drivers/ata/ahci.c
+++ b/kernel/drivers/ata/ahci.c
@@ -50,7 +50,8 @@
 	/* board IDs by feature in alphabetical order */
 	board_ahci,
 	board_ahci_ign_iferr,
-	board_ahci_mobile,
+	board_ahci_low_power,
+	board_ahci_no_debounce_delay,
 	board_ahci_nomsi,
 	board_ahci_noncq,
 	board_ahci_nosntf,
@@ -83,6 +84,7 @@
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static void ahci_remove_one(struct pci_dev *dev);
 static void ahci_shutdown_one(struct pci_dev *dev);
+static void ahci_intel_pcs_quirk(struct pci_dev *pdev, struct ahci_host_priv *hpriv);
 static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
 				 unsigned long deadline);
 static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
@@ -134,9 +136,16 @@
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_ops,
 	},
-	[board_ahci_mobile] = {
+	[board_ahci_low_power] = {
 		AHCI_HFLAGS	(AHCI_HFLAG_IS_MOBILE),
 		.flags		= AHCI_FLAG_COMMON,
+		.pio_mask	= ATA_PIO4,
+		.udma_mask	= ATA_UDMA6,
+		.port_ops	= &ahci_ops,
+	},
+	[board_ahci_no_debounce_delay] = {
+		.flags		= AHCI_FLAG_COMMON,
+		.link_flags	= ATA_LFLAG_NO_DEBOUNCE_DELAY,
 		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_ops,
@@ -267,13 +276,13 @@
 	{ PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */
 	{ PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */
 	{ PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */
-	{ PCI_VDEVICE(INTEL, 0x2929), board_ahci_mobile }, /* ICH9M */
-	{ PCI_VDEVICE(INTEL, 0x292a), board_ahci_mobile }, /* ICH9M */
-	{ PCI_VDEVICE(INTEL, 0x292b), board_ahci_mobile }, /* ICH9M */
-	{ PCI_VDEVICE(INTEL, 0x292c), board_ahci_mobile }, /* ICH9M */
-	{ PCI_VDEVICE(INTEL, 0x292f), board_ahci_mobile }, /* ICH9M */
+	{ PCI_VDEVICE(INTEL, 0x2929), board_ahci_low_power }, /* ICH9M */
+	{ PCI_VDEVICE(INTEL, 0x292a), board_ahci_low_power }, /* ICH9M */
+	{ PCI_VDEVICE(INTEL, 0x292b), board_ahci_low_power }, /* ICH9M */
+	{ PCI_VDEVICE(INTEL, 0x292c), board_ahci_low_power }, /* ICH9M */
+	{ PCI_VDEVICE(INTEL, 0x292f), board_ahci_low_power }, /* ICH9M */
 	{ PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */
-	{ PCI_VDEVICE(INTEL, 0x294e), board_ahci_mobile }, /* ICH9M */
+	{ PCI_VDEVICE(INTEL, 0x294e), board_ahci_low_power }, /* ICH9M */
 	{ PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */
 	{ PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */
 	{ PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */
@@ -283,9 +292,9 @@
 	{ PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */
 	{ PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
 	{ PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */
-	{ PCI_VDEVICE(INTEL, 0x3b29), board_ahci_mobile }, /* PCH M AHCI */
+	{ PCI_VDEVICE(INTEL, 0x3b29), board_ahci_low_power }, /* PCH M AHCI */
 	{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
-	{ PCI_VDEVICE(INTEL, 0x3b2c), board_ahci_mobile }, /* PCH M RAID */
+	{ PCI_VDEVICE(INTEL, 0x3b2c), board_ahci_low_power }, /* PCH M RAID */
 	{ PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */
 	{ PCI_VDEVICE(INTEL, 0x19b0), board_ahci_pcs7 }, /* DNV AHCI */
 	{ PCI_VDEVICE(INTEL, 0x19b1), board_ahci_pcs7 }, /* DNV AHCI */
@@ -308,9 +317,9 @@
 	{ PCI_VDEVICE(INTEL, 0x19cE), board_ahci_pcs7 }, /* DNV AHCI */
 	{ PCI_VDEVICE(INTEL, 0x19cF), board_ahci_pcs7 }, /* DNV AHCI */
 	{ PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */
-	{ PCI_VDEVICE(INTEL, 0x1c03), board_ahci_mobile }, /* CPT M AHCI */
+	{ PCI_VDEVICE(INTEL, 0x1c03), board_ahci_low_power }, /* CPT M AHCI */
 	{ PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */
-	{ PCI_VDEVICE(INTEL, 0x1c05), board_ahci_mobile }, /* CPT M RAID */
+	{ PCI_VDEVICE(INTEL, 0x1c05), board_ahci_low_power }, /* CPT M RAID */
 	{ PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */
 	{ PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */
 	{ PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */
@@ -319,29 +328,29 @@
 	{ PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */
 	{ PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */
 	{ PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */
-	{ PCI_VDEVICE(INTEL, 0x1e03), board_ahci_mobile }, /* Panther M AHCI */
+	{ PCI_VDEVICE(INTEL, 0x1e03), board_ahci_low_power }, /* Panther M AHCI */
 	{ PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */
 	{ PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */
 	{ PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
-	{ PCI_VDEVICE(INTEL, 0x1e07), board_ahci_mobile }, /* Panther M RAID */
+	{ PCI_VDEVICE(INTEL, 0x1e07), board_ahci_low_power }, /* Panther M RAID */
 	{ PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */
 	{ PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */
-	{ PCI_VDEVICE(INTEL, 0x8c03), board_ahci_mobile }, /* Lynx M AHCI */
+	{ PCI_VDEVICE(INTEL, 0x8c03), board_ahci_low_power }, /* Lynx M AHCI */
 	{ PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */
-	{ PCI_VDEVICE(INTEL, 0x8c05), board_ahci_mobile }, /* Lynx M RAID */
+	{ PCI_VDEVICE(INTEL, 0x8c05), board_ahci_low_power }, /* Lynx M RAID */
 	{ PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */
-	{ PCI_VDEVICE(INTEL, 0x8c07), board_ahci_mobile }, /* Lynx M RAID */
+	{ PCI_VDEVICE(INTEL, 0x8c07), board_ahci_low_power }, /* Lynx M RAID */
 	{ PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */
-	{ PCI_VDEVICE(INTEL, 0x8c0f), board_ahci_mobile }, /* Lynx M RAID */
-	{ PCI_VDEVICE(INTEL, 0x9c02), board_ahci_mobile }, /* Lynx LP AHCI */
-	{ PCI_VDEVICE(INTEL, 0x9c03), board_ahci_mobile }, /* Lynx LP AHCI */
-	{ PCI_VDEVICE(INTEL, 0x9c04), board_ahci_mobile }, /* Lynx LP RAID */
-	{ PCI_VDEVICE(INTEL, 0x9c05), board_ahci_mobile }, /* Lynx LP RAID */
-	{ PCI_VDEVICE(INTEL, 0x9c06), board_ahci_mobile }, /* Lynx LP RAID */
-	{ PCI_VDEVICE(INTEL, 0x9c07), board_ahci_mobile }, /* Lynx LP RAID */
-	{ PCI_VDEVICE(INTEL, 0x9c0e), board_ahci_mobile }, /* Lynx LP RAID */
-	{ PCI_VDEVICE(INTEL, 0x9c0f), board_ahci_mobile }, /* Lynx LP RAID */
-	{ PCI_VDEVICE(INTEL, 0x9dd3), board_ahci_mobile }, /* Cannon Lake PCH-LP AHCI */
+	{ PCI_VDEVICE(INTEL, 0x8c0f), board_ahci_low_power }, /* Lynx M RAID */
+	{ PCI_VDEVICE(INTEL, 0x9c02), board_ahci_low_power }, /* Lynx LP AHCI */
+	{ PCI_VDEVICE(INTEL, 0x9c03), board_ahci_low_power }, /* Lynx LP AHCI */
+	{ PCI_VDEVICE(INTEL, 0x9c04), board_ahci_low_power }, /* Lynx LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x9c05), board_ahci_low_power }, /* Lynx LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x9c06), board_ahci_low_power }, /* Lynx LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x9c07), board_ahci_low_power }, /* Lynx LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x9c0e), board_ahci_low_power }, /* Lynx LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x9c0f), board_ahci_low_power }, /* Lynx LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x9dd3), board_ahci_low_power }, /* Cannon Lake PCH-LP AHCI */
 	{ PCI_VDEVICE(INTEL, 0x1f22), board_ahci }, /* Avoton AHCI */
 	{ PCI_VDEVICE(INTEL, 0x1f23), board_ahci }, /* Avoton AHCI */
 	{ PCI_VDEVICE(INTEL, 0x1f24), board_ahci }, /* Avoton RAID */
@@ -373,26 +382,26 @@
 	{ PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
 	{ PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */
 	{ PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */
-	{ PCI_VDEVICE(INTEL, 0x9c83), board_ahci_mobile }, /* Wildcat LP AHCI */
-	{ PCI_VDEVICE(INTEL, 0x9c85), board_ahci_mobile }, /* Wildcat LP RAID */
-	{ PCI_VDEVICE(INTEL, 0x9c87), board_ahci_mobile }, /* Wildcat LP RAID */
-	{ PCI_VDEVICE(INTEL, 0x9c8f), board_ahci_mobile }, /* Wildcat LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x9c83), board_ahci_low_power }, /* Wildcat LP AHCI */
+	{ PCI_VDEVICE(INTEL, 0x9c85), board_ahci_low_power }, /* Wildcat LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x9c87), board_ahci_low_power }, /* Wildcat LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x9c8f), board_ahci_low_power }, /* Wildcat LP RAID */
 	{ PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */
-	{ PCI_VDEVICE(INTEL, 0x8c83), board_ahci_mobile }, /* 9 Series M AHCI */
+	{ PCI_VDEVICE(INTEL, 0x8c83), board_ahci_low_power }, /* 9 Series M AHCI */
 	{ PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */
-	{ PCI_VDEVICE(INTEL, 0x8c85), board_ahci_mobile }, /* 9 Series M RAID */
+	{ PCI_VDEVICE(INTEL, 0x8c85), board_ahci_low_power }, /* 9 Series M RAID */
 	{ PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */
-	{ PCI_VDEVICE(INTEL, 0x8c87), board_ahci_mobile }, /* 9 Series M RAID */
+	{ PCI_VDEVICE(INTEL, 0x8c87), board_ahci_low_power }, /* 9 Series M RAID */
 	{ PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
-	{ PCI_VDEVICE(INTEL, 0x8c8f), board_ahci_mobile }, /* 9 Series M RAID */
-	{ PCI_VDEVICE(INTEL, 0x9d03), board_ahci_mobile }, /* Sunrise LP AHCI */
-	{ PCI_VDEVICE(INTEL, 0x9d05), board_ahci_mobile }, /* Sunrise LP RAID */
-	{ PCI_VDEVICE(INTEL, 0x9d07), board_ahci_mobile }, /* Sunrise LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x8c8f), board_ahci_low_power }, /* 9 Series M RAID */
+	{ PCI_VDEVICE(INTEL, 0x9d03), board_ahci_low_power }, /* Sunrise LP AHCI */
+	{ PCI_VDEVICE(INTEL, 0x9d05), board_ahci_low_power }, /* Sunrise LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x9d07), board_ahci_low_power }, /* Sunrise LP RAID */
 	{ PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */
-	{ PCI_VDEVICE(INTEL, 0xa103), board_ahci_mobile }, /* Sunrise M AHCI */
+	{ PCI_VDEVICE(INTEL, 0xa103), board_ahci_low_power }, /* Sunrise M AHCI */
 	{ PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
 	{ PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */
-	{ PCI_VDEVICE(INTEL, 0xa107), board_ahci_mobile }, /* Sunrise M RAID */
+	{ PCI_VDEVICE(INTEL, 0xa107), board_ahci_low_power }, /* Sunrise M RAID */
 	{ PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
 	{ PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/
@@ -409,13 +418,15 @@
 	{ PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */
 	{ PCI_VDEVICE(INTEL, 0x06d7), board_ahci }, /* Comet Lake-H RAID */
 	{ PCI_VDEVICE(INTEL, 0xa386), board_ahci }, /* Comet Lake PCH-V RAID */
-	{ PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */
-	{ PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */
-	{ PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */
-	{ PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_mobile }, /* ApolloLake AHCI */
-	{ PCI_VDEVICE(INTEL, 0x34d3), board_ahci_mobile }, /* Ice Lake LP AHCI */
-	{ PCI_VDEVICE(INTEL, 0x02d3), board_ahci_mobile }, /* Comet Lake PCH-U AHCI */
-	{ PCI_VDEVICE(INTEL, 0x02d7), board_ahci_mobile }, /* Comet Lake PCH RAID */
+	{ PCI_VDEVICE(INTEL, 0x0f22), board_ahci_low_power }, /* Bay Trail AHCI */
+	{ PCI_VDEVICE(INTEL, 0x0f23), board_ahci_low_power }, /* Bay Trail AHCI */
+	{ PCI_VDEVICE(INTEL, 0x22a3), board_ahci_low_power }, /* Cherry Tr. AHCI */
+	{ PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_low_power }, /* ApolloLake AHCI */
+	{ PCI_VDEVICE(INTEL, 0x34d3), board_ahci_low_power }, /* Ice Lake LP AHCI */
+	{ PCI_VDEVICE(INTEL, 0x02d3), board_ahci_low_power }, /* Comet Lake PCH-U AHCI */
+	{ PCI_VDEVICE(INTEL, 0x02d7), board_ahci_low_power }, /* Comet Lake PCH RAID */
+	/* Elkhart Lake IDs 0x4b60 & 0x4b62 https://sata-io.org/product/8803 not tested yet */
+	{ PCI_VDEVICE(INTEL, 0x4b63), board_ahci_low_power }, /* Elkhart Lake AHCI */
 
 	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
 	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -441,8 +452,9 @@
 		board_ahci_al },
 	/* AMD */
 	{ PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */
+	{ PCI_VDEVICE(AMD, 0x7801), board_ahci_no_debounce_delay }, /* AMD Hudson-2 (AHCI mode) */
 	{ PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */
-	{ PCI_VDEVICE(AMD, 0x7901), board_ahci_mobile }, /* AMD Green Sardine */
+	{ PCI_VDEVICE(AMD, 0x7901), board_ahci_low_power }, /* AMD Green Sardine */
 	/* AMD is using RAID class only for ahci controllers */
 	{ PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
 	  PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci },
@@ -664,6 +676,25 @@
 	ahci_save_initial_config(&pdev->dev, hpriv);
 }
 
+static int ahci_pci_reset_controller(struct ata_host *host)
+{
+	struct pci_dev *pdev = to_pci_dev(host->dev);
+	struct ahci_host_priv *hpriv = host->private_data;
+	int rc;
+
+	rc = ahci_reset_controller(host);
+	if (rc)
+		return rc;
+
+	/*
+	 * If platform firmware failed to enable ports, try to enable
+	 * them here.
+	 */
+	ahci_intel_pcs_quirk(pdev, hpriv);
+
+	return 0;
+}
+
 static void ahci_pci_init_controller(struct ata_host *host)
 {
 	struct ahci_host_priv *hpriv = host->private_data;
@@ -683,7 +714,7 @@
 
 		/* clear port IRQ */
 		tmp = readl(port_mmio + PORT_IRQ_STAT);
-		VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
+		dev_dbg(&pdev->dev, "PORT_IRQ_STAT 0x%x\n", tmp);
 		if (tmp)
 			writel(tmp, port_mmio + PORT_IRQ_STAT);
 	}
@@ -865,7 +896,7 @@
 	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
-	rc = ahci_reset_controller(host);
+	rc = ahci_pci_reset_controller(host);
 	if (rc)
 		return rc;
 	ahci_pci_init_controller(host);
@@ -900,7 +931,7 @@
 		ahci_mcp89_apple_enable(pdev);
 
 	if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
-		rc = ahci_reset_controller(host);
+		rc = ahci_pci_reset_controller(host);
 		if (rc)
 			return rc;
 
@@ -1475,7 +1506,6 @@
 	u32 irq_stat, irq_masked;
 	unsigned int handled = 1;
 
-	VPRINTK("ENTER\n");
 	hpriv = host->private_data;
 	mmio = hpriv->mmio;
 	irq_stat = readl(mmio + HOST_IRQ_STAT);
@@ -1492,7 +1522,6 @@
 		irq_stat = readl(mmio + HOST_IRQ_STAT);
 		spin_unlock(&host->lock);
 	} while (irq_stat);
-	VPRINTK("EXIT\n");
 
 	return IRQ_RETVAL(handled);
 }
@@ -1785,12 +1814,6 @@
 	/* save initial config */
 	ahci_pci_save_initial_config(pdev, hpriv);
 
-	/*
-	 * If platform firmware failed to enable ports, try to enable
-	 * them here.
-	 */
-	ahci_intel_pcs_quirk(pdev, hpriv);
-
 	/* prepare host */
 	if (hpriv->cap & HOST_CAP_NCQ) {
 		pi.flags |= ATA_FLAG_NCQ;
@@ -1868,6 +1891,15 @@
 	else
 		dev_info(&pdev->dev, "SSS flag set, parallel bus scan disabled\n");
 
+	if (!(hpriv->cap & HOST_CAP_PART))
+		host->flags |= ATA_HOST_NO_PART;
+
+	if (!(hpriv->cap & HOST_CAP_SSC))
+		host->flags |= ATA_HOST_NO_SSC;
+
+	if (!(hpriv->cap2 & HOST_CAP2_SDS))
+		host->flags |= ATA_HOST_NO_DEVSLP;
+
 	if (pi.flags & ATA_FLAG_EM)
 		ahci_reset_em(host);
 
@@ -1900,7 +1932,7 @@
 	if (rc)
 		return rc;
 
-	rc = ahci_reset_controller(host);
+	rc = ahci_pci_reset_controller(host);
 	if (rc)
 		return rc;
 
diff --git a/kernel/drivers/ata/ahci.h b/kernel/drivers/ata/ahci.h
index 1ce8973..7cc6feb 100644
--- a/kernel/drivers/ata/ahci.h
+++ b/kernel/drivers/ata/ahci.h
@@ -24,6 +24,7 @@
 #include <linux/libata.h>
 #include <linux/phy/phy.h>
 #include <linux/regulator/consumer.h>
+#include <linux/bits.h>
 
 /* Enclosure Management Control */
 #define EM_CTRL_MSG_TYPE              0x000f0000
@@ -54,12 +55,12 @@
 	AHCI_PORT_PRIV_FBS_DMA_SZ	= AHCI_CMD_SLOT_SZ +
 					  AHCI_CMD_TBL_AR_SZ +
 					  (AHCI_RX_FIS_SZ * 16),
-	AHCI_IRQ_ON_SG		= (1 << 31),
-	AHCI_CMD_ATAPI		= (1 << 5),
-	AHCI_CMD_WRITE		= (1 << 6),
-	AHCI_CMD_PREFETCH	= (1 << 7),
-	AHCI_CMD_RESET		= (1 << 8),
-	AHCI_CMD_CLR_BUSY	= (1 << 10),
+	AHCI_IRQ_ON_SG		= BIT(31),
+	AHCI_CMD_ATAPI		= BIT(5),
+	AHCI_CMD_WRITE		= BIT(6),
+	AHCI_CMD_PREFETCH	= BIT(7),
+	AHCI_CMD_RESET		= BIT(8),
+	AHCI_CMD_CLR_BUSY	= BIT(10),
 
 	RX_FIS_PIO_SETUP	= 0x20,	/* offset of PIO Setup FIS data */
 	RX_FIS_D2H_REG		= 0x40,	/* offset of D2H Register FIS data */
@@ -77,37 +78,37 @@
 	HOST_CAP2		= 0x24, /* host capabilities, extended */
 
 	/* HOST_CTL bits */
-	HOST_RESET		= (1 << 0),  /* reset controller; self-clear */
-	HOST_IRQ_EN		= (1 << 1),  /* global IRQ enable */
-	HOST_MRSM		= (1 << 2),  /* MSI Revert to Single Message */
-	HOST_AHCI_EN		= (1 << 31), /* AHCI enabled */
+	HOST_RESET		= BIT(0),  /* reset controller; self-clear */
+	HOST_IRQ_EN		= BIT(1),  /* global IRQ enable */
+	HOST_MRSM		= BIT(2),  /* MSI Revert to Single Message */
+	HOST_AHCI_EN		= BIT(31), /* AHCI enabled */
 
 	/* HOST_CAP bits */
-	HOST_CAP_SXS		= (1 << 5),  /* Supports External SATA */
-	HOST_CAP_EMS		= (1 << 6),  /* Enclosure Management support */
-	HOST_CAP_CCC		= (1 << 7),  /* Command Completion Coalescing */
-	HOST_CAP_PART		= (1 << 13), /* Partial state capable */
-	HOST_CAP_SSC		= (1 << 14), /* Slumber state capable */
-	HOST_CAP_PIO_MULTI	= (1 << 15), /* PIO multiple DRQ support */
-	HOST_CAP_FBS		= (1 << 16), /* FIS-based switching support */
-	HOST_CAP_PMP		= (1 << 17), /* Port Multiplier support */
-	HOST_CAP_ONLY		= (1 << 18), /* Supports AHCI mode only */
-	HOST_CAP_CLO		= (1 << 24), /* Command List Override support */
-	HOST_CAP_LED		= (1 << 25), /* Supports activity LED */
-	HOST_CAP_ALPM		= (1 << 26), /* Aggressive Link PM support */
-	HOST_CAP_SSS		= (1 << 27), /* Staggered Spin-up */
-	HOST_CAP_MPS		= (1 << 28), /* Mechanical presence switch */
-	HOST_CAP_SNTF		= (1 << 29), /* SNotification register */
-	HOST_CAP_NCQ		= (1 << 30), /* Native Command Queueing */
-	HOST_CAP_64		= (1 << 31), /* PCI DAC (64-bit DMA) support */
+	HOST_CAP_SXS		= BIT(5),  /* Supports External SATA */
+	HOST_CAP_EMS		= BIT(6),  /* Enclosure Management support */
+	HOST_CAP_CCC		= BIT(7),  /* Command Completion Coalescing */
+	HOST_CAP_PART		= BIT(13), /* Partial state capable */
+	HOST_CAP_SSC		= BIT(14), /* Slumber state capable */
+	HOST_CAP_PIO_MULTI	= BIT(15), /* PIO multiple DRQ support */
+	HOST_CAP_FBS		= BIT(16), /* FIS-based switching support */
+	HOST_CAP_PMP		= BIT(17), /* Port Multiplier support */
+	HOST_CAP_ONLY		= BIT(18), /* Supports AHCI mode only */
+	HOST_CAP_CLO		= BIT(24), /* Command List Override support */
+	HOST_CAP_LED		= BIT(25), /* Supports activity LED */
+	HOST_CAP_ALPM		= BIT(26), /* Aggressive Link PM support */
+	HOST_CAP_SSS		= BIT(27), /* Staggered Spin-up */
+	HOST_CAP_MPS		= BIT(28), /* Mechanical presence switch */
+	HOST_CAP_SNTF		= BIT(29), /* SNotification register */
+	HOST_CAP_NCQ		= BIT(30), /* Native Command Queueing */
+	HOST_CAP_64		= BIT(31), /* PCI DAC (64-bit DMA) support */
 
 	/* HOST_CAP2 bits */
-	HOST_CAP2_BOH		= (1 << 0),  /* BIOS/OS handoff supported */
-	HOST_CAP2_NVMHCI	= (1 << 1),  /* NVMHCI supported */
-	HOST_CAP2_APST		= (1 << 2),  /* Automatic partial to slumber */
-	HOST_CAP2_SDS		= (1 << 3),  /* Support device sleep */
-	HOST_CAP2_SADM		= (1 << 4),  /* Support aggressive DevSlp */
-	HOST_CAP2_DESO		= (1 << 5),  /* DevSlp from slumber only */
+	HOST_CAP2_BOH		= BIT(0),  /* BIOS/OS handoff supported */
+	HOST_CAP2_NVMHCI	= BIT(1),  /* NVMHCI supported */
+	HOST_CAP2_APST		= BIT(2),  /* Automatic partial to slumber */
+	HOST_CAP2_SDS		= BIT(3),  /* Support device sleep */
+	HOST_CAP2_SADM		= BIT(4),  /* Support aggressive DevSlp */
+	HOST_CAP2_DESO		= BIT(5),  /* DevSlp from slumber only */
 
 	/* registers for each SATA port */
 	PORT_LST_ADDR		= 0x00, /* command list DMA addr */
@@ -129,24 +130,24 @@
 	PORT_DEVSLP		= 0x44, /* device sleep */
 
 	/* PORT_IRQ_{STAT,MASK} bits */
-	PORT_IRQ_COLD_PRES	= (1 << 31), /* cold presence detect */
-	PORT_IRQ_TF_ERR		= (1 << 30), /* task file error */
-	PORT_IRQ_HBUS_ERR	= (1 << 29), /* host bus fatal error */
-	PORT_IRQ_HBUS_DATA_ERR	= (1 << 28), /* host bus data error */
-	PORT_IRQ_IF_ERR		= (1 << 27), /* interface fatal error */
-	PORT_IRQ_IF_NONFATAL	= (1 << 26), /* interface non-fatal error */
-	PORT_IRQ_OVERFLOW	= (1 << 24), /* xfer exhausted available S/G */
-	PORT_IRQ_BAD_PMP	= (1 << 23), /* incorrect port multiplier */
+	PORT_IRQ_COLD_PRES	= BIT(31), /* cold presence detect */
+	PORT_IRQ_TF_ERR		= BIT(30), /* task file error */
+	PORT_IRQ_HBUS_ERR	= BIT(29), /* host bus fatal error */
+	PORT_IRQ_HBUS_DATA_ERR	= BIT(28), /* host bus data error */
+	PORT_IRQ_IF_ERR		= BIT(27), /* interface fatal error */
+	PORT_IRQ_IF_NONFATAL	= BIT(26), /* interface non-fatal error */
+	PORT_IRQ_OVERFLOW	= BIT(24), /* xfer exhausted available S/G */
+	PORT_IRQ_BAD_PMP	= BIT(23), /* incorrect port multiplier */
 
-	PORT_IRQ_PHYRDY		= (1 << 22), /* PhyRdy changed */
-	PORT_IRQ_DEV_ILCK	= (1 << 7), /* device interlock */
-	PORT_IRQ_CONNECT	= (1 << 6), /* port connect change status */
-	PORT_IRQ_SG_DONE	= (1 << 5), /* descriptor processed */
-	PORT_IRQ_UNK_FIS	= (1 << 4), /* unknown FIS rx'd */
-	PORT_IRQ_SDB_FIS	= (1 << 3), /* Set Device Bits FIS rx'd */
-	PORT_IRQ_DMAS_FIS	= (1 << 2), /* DMA Setup FIS rx'd */
-	PORT_IRQ_PIOS_FIS	= (1 << 1), /* PIO Setup FIS rx'd */
-	PORT_IRQ_D2H_REG_FIS	= (1 << 0), /* D2H Register FIS rx'd */
+	PORT_IRQ_PHYRDY		= BIT(22), /* PhyRdy changed */
+	PORT_IRQ_DEV_ILCK	= BIT(7),  /* device interlock */
+	PORT_IRQ_CONNECT	= BIT(6),  /* port connect change status */
+	PORT_IRQ_SG_DONE	= BIT(5),  /* descriptor processed */
+	PORT_IRQ_UNK_FIS	= BIT(4),  /* unknown FIS rx'd */
+	PORT_IRQ_SDB_FIS	= BIT(3),  /* Set Device Bits FIS rx'd */
+	PORT_IRQ_DMAS_FIS	= BIT(2),  /* DMA Setup FIS rx'd */
+	PORT_IRQ_PIOS_FIS	= BIT(1),  /* PIO Setup FIS rx'd */
+	PORT_IRQ_D2H_REG_FIS	= BIT(0),  /* D2H Register FIS rx'd */
 
 	PORT_IRQ_FREEZE		= PORT_IRQ_HBUS_ERR |
 				  PORT_IRQ_IF_ERR |
@@ -162,34 +163,34 @@
 				  PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS,
 
 	/* PORT_CMD bits */
-	PORT_CMD_ASP		= (1 << 27), /* Aggressive Slumber/Partial */
-	PORT_CMD_ALPE		= (1 << 26), /* Aggressive Link PM enable */
-	PORT_CMD_ATAPI		= (1 << 24), /* Device is ATAPI */
-	PORT_CMD_FBSCP		= (1 << 22), /* FBS Capable Port */
-	PORT_CMD_ESP		= (1 << 21), /* External Sata Port */
-	PORT_CMD_HPCP		= (1 << 18), /* HotPlug Capable Port */
-	PORT_CMD_PMP		= (1 << 17), /* PMP attached */
-	PORT_CMD_LIST_ON	= (1 << 15), /* cmd list DMA engine running */
-	PORT_CMD_FIS_ON		= (1 << 14), /* FIS DMA engine running */
-	PORT_CMD_FIS_RX		= (1 << 4), /* Enable FIS receive DMA engine */
-	PORT_CMD_CLO		= (1 << 3), /* Command list override */
-	PORT_CMD_POWER_ON	= (1 << 2), /* Power up device */
-	PORT_CMD_SPIN_UP	= (1 << 1), /* Spin up device */
-	PORT_CMD_START		= (1 << 0), /* Enable port DMA engine */
+	PORT_CMD_ASP		= BIT(27), /* Aggressive Slumber/Partial */
+	PORT_CMD_ALPE		= BIT(26), /* Aggressive Link PM enable */
+	PORT_CMD_ATAPI		= BIT(24), /* Device is ATAPI */
+	PORT_CMD_FBSCP		= BIT(22), /* FBS Capable Port */
+	PORT_CMD_ESP		= BIT(21), /* External Sata Port */
+	PORT_CMD_HPCP		= BIT(18), /* HotPlug Capable Port */
+	PORT_CMD_PMP		= BIT(17), /* PMP attached */
+	PORT_CMD_LIST_ON	= BIT(15), /* cmd list DMA engine running */
+	PORT_CMD_FIS_ON		= BIT(14), /* FIS DMA engine running */
+	PORT_CMD_FIS_RX		= BIT(4),  /* Enable FIS receive DMA engine */
+	PORT_CMD_CLO		= BIT(3),  /* Command list override */
+	PORT_CMD_POWER_ON	= BIT(2),  /* Power up device */
+	PORT_CMD_SPIN_UP	= BIT(1),  /* Spin up device */
+	PORT_CMD_START		= BIT(0),  /* Enable port DMA engine */
 
-	PORT_CMD_ICC_MASK	= (0xf << 28), /* i/f ICC state mask */
-	PORT_CMD_ICC_ACTIVE	= (0x1 << 28), /* Put i/f in active state */
-	PORT_CMD_ICC_PARTIAL	= (0x2 << 28), /* Put i/f in partial state */
-	PORT_CMD_ICC_SLUMBER	= (0x6 << 28), /* Put i/f in slumber state */
+	PORT_CMD_ICC_MASK	= (0xfu << 28), /* i/f ICC state mask */
+	PORT_CMD_ICC_ACTIVE	= (0x1u << 28), /* Put i/f in active state */
+	PORT_CMD_ICC_PARTIAL	= (0x2u << 28), /* Put i/f in partial state */
+	PORT_CMD_ICC_SLUMBER	= (0x6u << 28), /* Put i/f in slumber state */
 
 	/* PORT_FBS bits */
 	PORT_FBS_DWE_OFFSET	= 16, /* FBS device with error offset */
 	PORT_FBS_ADO_OFFSET	= 12, /* FBS active dev optimization offset */
 	PORT_FBS_DEV_OFFSET	= 8,  /* FBS device to issue offset */
 	PORT_FBS_DEV_MASK	= (0xf << PORT_FBS_DEV_OFFSET),  /* FBS.DEV */
-	PORT_FBS_SDE		= (1 << 2), /* FBS single device error */
-	PORT_FBS_DEC		= (1 << 1), /* FBS device error clear */
-	PORT_FBS_EN		= (1 << 0), /* Enable FBS */
+	PORT_FBS_SDE		= BIT(2), /* FBS single device error */
+	PORT_FBS_DEC		= BIT(1), /* FBS device error clear */
+	PORT_FBS_EN		= BIT(0), /* Enable FBS */
 
 	/* PORT_DEVSLP bits */
 	PORT_DEVSLP_DM_OFFSET	= 25,             /* DITO multiplier offset */
@@ -197,52 +198,52 @@
 	PORT_DEVSLP_DITO_OFFSET	= 15,             /* DITO offset */
 	PORT_DEVSLP_MDAT_OFFSET	= 10,             /* Minimum assertion time */
 	PORT_DEVSLP_DETO_OFFSET	= 2,              /* DevSlp exit timeout */
-	PORT_DEVSLP_DSP		= (1 << 1),       /* DevSlp present */
-	PORT_DEVSLP_ADSE	= (1 << 0),       /* Aggressive DevSlp enable */
+	PORT_DEVSLP_DSP		= BIT(1),         /* DevSlp present */
+	PORT_DEVSLP_ADSE	= BIT(0),         /* Aggressive DevSlp enable */
 
 	/* hpriv->flags bits */
 
 #define AHCI_HFLAGS(flags)		.private_data	= (void *)(flags)
 
-	AHCI_HFLAG_NO_NCQ		= (1 << 0),
-	AHCI_HFLAG_IGN_IRQ_IF_ERR	= (1 << 1), /* ignore IRQ_IF_ERR */
-	AHCI_HFLAG_IGN_SERR_INTERNAL	= (1 << 2), /* ignore SERR_INTERNAL */
-	AHCI_HFLAG_32BIT_ONLY		= (1 << 3), /* force 32bit */
-	AHCI_HFLAG_MV_PATA		= (1 << 4), /* PATA port */
-	AHCI_HFLAG_NO_MSI		= (1 << 5), /* no PCI MSI */
-	AHCI_HFLAG_NO_PMP		= (1 << 6), /* no PMP */
-	AHCI_HFLAG_SECT255		= (1 << 8), /* max 255 sectors */
-	AHCI_HFLAG_YES_NCQ		= (1 << 9), /* force NCQ cap on */
-	AHCI_HFLAG_NO_SUSPEND		= (1 << 10), /* don't suspend */
-	AHCI_HFLAG_SRST_TOUT_IS_OFFLINE	= (1 << 11), /* treat SRST timeout as
-							link offline */
-	AHCI_HFLAG_NO_SNTF		= (1 << 12), /* no sntf */
-	AHCI_HFLAG_NO_FPDMA_AA		= (1 << 13), /* no FPDMA AA */
-	AHCI_HFLAG_YES_FBS		= (1 << 14), /* force FBS cap on */
-	AHCI_HFLAG_DELAY_ENGINE		= (1 << 15), /* do not start engine on
-						        port start (wait until
-						        error-handling stage) */
-	AHCI_HFLAG_NO_DEVSLP		= (1 << 17), /* no device sleep */
-	AHCI_HFLAG_NO_FBS		= (1 << 18), /* no FBS */
+	AHCI_HFLAG_NO_NCQ		= BIT(0),
+	AHCI_HFLAG_IGN_IRQ_IF_ERR	= BIT(1), /* ignore IRQ_IF_ERR */
+	AHCI_HFLAG_IGN_SERR_INTERNAL	= BIT(2), /* ignore SERR_INTERNAL */
+	AHCI_HFLAG_32BIT_ONLY		= BIT(3), /* force 32bit */
+	AHCI_HFLAG_MV_PATA		= BIT(4), /* PATA port */
+	AHCI_HFLAG_NO_MSI		= BIT(5), /* no PCI MSI */
+	AHCI_HFLAG_NO_PMP		= BIT(6), /* no PMP */
+	AHCI_HFLAG_SECT255		= BIT(8), /* max 255 sectors */
+	AHCI_HFLAG_YES_NCQ		= BIT(9), /* force NCQ cap on */
+	AHCI_HFLAG_NO_SUSPEND		= BIT(10), /* don't suspend */
+	AHCI_HFLAG_SRST_TOUT_IS_OFFLINE	= BIT(11), /* treat SRST timeout as
+						      link offline */
+	AHCI_HFLAG_NO_SNTF		= BIT(12), /* no sntf */
+	AHCI_HFLAG_NO_FPDMA_AA		= BIT(13), /* no FPDMA AA */
+	AHCI_HFLAG_YES_FBS		= BIT(14), /* force FBS cap on */
+	AHCI_HFLAG_DELAY_ENGINE		= BIT(15), /* do not start engine on
+						      port start (wait until
+						      error-handling stage) */
+	AHCI_HFLAG_NO_DEVSLP		= BIT(17), /* no device sleep */
+	AHCI_HFLAG_NO_FBS		= BIT(18), /* no FBS */
 
 #ifdef CONFIG_PCI_MSI
-	AHCI_HFLAG_MULTI_MSI		= (1 << 20), /* per-port MSI(-X) */
+	AHCI_HFLAG_MULTI_MSI		= BIT(20), /* per-port MSI(-X) */
 #else
 	/* compile out MSI infrastructure */
 	AHCI_HFLAG_MULTI_MSI		= 0,
 #endif
-	AHCI_HFLAG_WAKE_BEFORE_STOP	= (1 << 22), /* wake before DMA stop */
-	AHCI_HFLAG_YES_ALPM		= (1 << 23), /* force ALPM cap on */
-	AHCI_HFLAG_NO_WRITE_TO_RO	= (1 << 24), /* don't write to read
-							only registers */
-	AHCI_HFLAG_IS_MOBILE		= (1 << 25), /* mobile chipset, use
-							SATA_MOBILE_LPM_POLICY
-							as default lpm_policy */
-	AHCI_HFLAG_SUSPEND_PHYS		= (1 << 26), /* handle PHYs during
-							suspend/resume */
-	AHCI_HFLAG_IGN_NOTSUPP_POWER_ON	= (1 << 27), /* ignore -EOPNOTSUPP
-							from phy_power_on() */
-	AHCI_HFLAG_NO_SXS		= (1 << 28), /* SXS not supported */
+	AHCI_HFLAG_WAKE_BEFORE_STOP	= BIT(22), /* wake before DMA stop */
+	AHCI_HFLAG_YES_ALPM		= BIT(23), /* force ALPM cap on */
+	AHCI_HFLAG_NO_WRITE_TO_RO	= BIT(24), /* don't write to read
+						      only registers */
+	AHCI_HFLAG_IS_MOBILE            = BIT(25), /* mobile chipset, use
+						      SATA_MOBILE_LPM_POLICY
+						      as default lpm_policy */
+	AHCI_HFLAG_SUSPEND_PHYS		= BIT(26), /* handle PHYs during
+						      suspend/resume */
+	AHCI_HFLAG_IGN_NOTSUPP_POWER_ON	= BIT(27), /* ignore -EOPNOTSUPP
+						      from phy_power_on() */
+	AHCI_HFLAG_NO_SXS		= BIT(28), /* SXS not supported */
 
 	/* ap->flags bits */
 
@@ -258,22 +259,22 @@
 	EM_MAX_RETRY			= 5,
 
 	/* em_ctl bits */
-	EM_CTL_RST		= (1 << 9), /* Reset */
-	EM_CTL_TM		= (1 << 8), /* Transmit Message */
-	EM_CTL_MR		= (1 << 0), /* Message Received */
-	EM_CTL_ALHD		= (1 << 26), /* Activity LED */
-	EM_CTL_XMT		= (1 << 25), /* Transmit Only */
-	EM_CTL_SMB		= (1 << 24), /* Single Message Buffer */
-	EM_CTL_SGPIO		= (1 << 19), /* SGPIO messages supported */
-	EM_CTL_SES		= (1 << 18), /* SES-2 messages supported */
-	EM_CTL_SAFTE		= (1 << 17), /* SAF-TE messages supported */
-	EM_CTL_LED		= (1 << 16), /* LED messages supported */
+	EM_CTL_RST		= BIT(9), /* Reset */
+	EM_CTL_TM		= BIT(8), /* Transmit Message */
+	EM_CTL_MR		= BIT(0), /* Message Received */
+	EM_CTL_ALHD		= BIT(26), /* Activity LED */
+	EM_CTL_XMT		= BIT(25), /* Transmit Only */
+	EM_CTL_SMB		= BIT(24), /* Single Message Buffer */
+	EM_CTL_SGPIO		= BIT(19), /* SGPIO messages supported */
+	EM_CTL_SES		= BIT(18), /* SES-2 messages supported */
+	EM_CTL_SAFTE		= BIT(17), /* SAF-TE messages supported */
+	EM_CTL_LED		= BIT(16), /* LED messages supported */
 
 	/* em message type */
-	EM_MSG_TYPE_LED		= (1 << 0), /* LED */
-	EM_MSG_TYPE_SAFTE	= (1 << 1), /* SAF-TE */
-	EM_MSG_TYPE_SES2	= (1 << 2), /* SES-2 */
-	EM_MSG_TYPE_SGPIO	= (1 << 3), /* SGPIO */
+	EM_MSG_TYPE_LED		= BIT(0), /* LED */
+	EM_MSG_TYPE_SAFTE	= BIT(1), /* SAF-TE */
+	EM_MSG_TYPE_SES2	= BIT(2), /* SES-2 */
+	EM_MSG_TYPE_SGPIO	= BIT(3), /* SGPIO */
 };
 
 struct ahci_cmd_hdr {
diff --git a/kernel/drivers/ata/ahci_brcm.c b/kernel/drivers/ata/ahci_brcm.c
index 5b32df5..2e42525 100644
--- a/kernel/drivers/ata/ahci_brcm.c
+++ b/kernel/drivers/ata/ahci_brcm.c
@@ -332,7 +332,7 @@
 
 static const struct ata_port_info ahci_brcm_port_info = {
 	.flags		= AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
-	.link_flags	= ATA_LFLAG_NO_DB_DELAY,
+	.link_flags	= ATA_LFLAG_NO_DEBOUNCE_DELAY,
 	.pio_mask	= ATA_PIO4,
 	.udma_mask	= ATA_UDMA6,
 	.port_ops	= &ahci_brcm_platform_ops,
diff --git a/kernel/drivers/ata/ahci_xgene.c b/kernel/drivers/ata/ahci_xgene.c
index 16246c8..e0f0577 100644
--- a/kernel/drivers/ata/ahci_xgene.c
+++ b/kernel/drivers/ata/ahci_xgene.c
@@ -588,8 +588,6 @@
 	void __iomem *mmio;
 	u32 irq_stat, irq_masked;
 
-	VPRINTK("ENTER\n");
-
 	hpriv = host->private_data;
 	mmio = hpriv->mmio;
 
@@ -611,8 +609,6 @@
 	rc = xgene_ahci_handle_broken_edge_irq(host, irq_masked);
 
 	spin_unlock(&host->lock);
-
-	VPRINTK("EXIT\n");
 
 	return IRQ_RETVAL(rc);
 }
diff --git a/kernel/drivers/ata/libahci.c b/kernel/drivers/ata/libahci.c
index 055439e..65ae938 100644
--- a/kernel/drivers/ata/libahci.c
+++ b/kernel/drivers/ata/libahci.c
@@ -1199,6 +1199,26 @@
 	return sprintf(buf, "%d\n", emp->blink_policy);
 }
 
+static void ahci_port_clear_pending_irq(struct ata_port *ap)
+{
+	struct ahci_host_priv *hpriv = ap->host->private_data;
+	void __iomem *port_mmio = ahci_port_base(ap);
+	u32 tmp;
+
+	/* clear SError */
+	tmp = readl(port_mmio + PORT_SCR_ERR);
+	dev_dbg(ap->host->dev, "PORT_SCR_ERR 0x%x\n", tmp);
+	writel(tmp, port_mmio + PORT_SCR_ERR);
+
+	/* clear port IRQ */
+	tmp = readl(port_mmio + PORT_IRQ_STAT);
+	dev_dbg(ap->host->dev, "PORT_IRQ_STAT 0x%x\n", tmp);
+	if (tmp)
+		writel(tmp, port_mmio + PORT_IRQ_STAT);
+
+	writel(1 << ap->port_no, hpriv->mmio + HOST_IRQ_STAT);
+}
+
 static void ahci_port_init(struct device *dev, struct ata_port *ap,
 			   int port_no, void __iomem *mmio,
 			   void __iomem *port_mmio)
@@ -1213,18 +1233,7 @@
 	if (rc)
 		dev_warn(dev, "%s (%d)\n", emsg, rc);
 
-	/* clear SError */
-	tmp = readl(port_mmio + PORT_SCR_ERR);
-	VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
-	writel(tmp, port_mmio + PORT_SCR_ERR);
-
-	/* clear port IRQ */
-	tmp = readl(port_mmio + PORT_IRQ_STAT);
-	VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
-	if (tmp)
-		writel(tmp, port_mmio + PORT_IRQ_STAT);
-
-	writel(1 << port_no, mmio + HOST_IRQ_STAT);
+	ahci_port_clear_pending_irq(ap);
 
 	/* mark esata ports */
 	tmp = readl(port_mmio + PORT_CMD);
@@ -1251,10 +1260,10 @@
 	}
 
 	tmp = readl(mmio + HOST_CTL);
-	VPRINTK("HOST_CTL 0x%x\n", tmp);
+	dev_dbg(host->dev, "HOST_CTL 0x%x\n", tmp);
 	writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
 	tmp = readl(mmio + HOST_CTL);
-	VPRINTK("HOST_CTL 0x%x\n", tmp);
+	dev_dbg(host->dev, "HOST_CTL 0x%x\n", tmp);
 }
 EXPORT_SYMBOL_GPL(ahci_init_controller);
 
@@ -1553,6 +1562,8 @@
 	ata_tf_init(link->device, &tf);
 	tf.command = ATA_BUSY;
 	ata_tf_to_fis(&tf, 0, 0, d2h_fis);
+
+	ahci_port_clear_pending_irq(ap);
 
 	rc = sata_link_hardreset(link, timing, deadline, online,
 				 ahci_check_ready);
@@ -1905,16 +1916,12 @@
 	void __iomem *port_mmio = ahci_port_base(ap);
 	u32 status;
 
-	VPRINTK("ENTER\n");
-
 	status = readl(port_mmio + PORT_IRQ_STAT);
 	writel(status, port_mmio + PORT_IRQ_STAT);
 
 	spin_lock(ap->lock);
 	ahci_handle_port_interrupt(ap, port_mmio, status);
 	spin_unlock(ap->lock);
-
-	VPRINTK("EXIT\n");
 
 	return IRQ_HANDLED;
 }
@@ -1932,9 +1939,7 @@
 		ap = host->ports[i];
 		if (ap) {
 			ahci_port_intr(ap);
-			VPRINTK("port %u\n", i);
 		} else {
-			VPRINTK("port %u (no irq)\n", i);
 			if (ata_ratelimit())
 				dev_warn(host->dev,
 					 "interrupt on disabled port %u\n", i);
@@ -1954,8 +1959,6 @@
 	unsigned int rc = 0;
 	void __iomem *mmio;
 	u32 irq_stat, irq_masked;
-
-	VPRINTK("ENTER\n");
 
 	hpriv = host->private_data;
 	mmio = hpriv->mmio;
@@ -1983,8 +1986,6 @@
 	writel(irq_stat, mmio + HOST_IRQ_STAT);
 
 	spin_unlock(&host->lock);
-
-	VPRINTK("EXIT\n");
 
 	return IRQ_RETVAL(rc);
 }
diff --git a/kernel/drivers/ata/libata-core.c b/kernel/drivers/ata/libata-core.c
index d13474c..702b8e0 100644
--- a/kernel/drivers/ata/libata-core.c
+++ b/kernel/drivers/ata/libata-core.c
@@ -3051,7 +3051,7 @@
 	 */
 	if (spd > 1)
 		mask &= (1 << (spd - 1)) - 1;
-	else
+	else if (link->sata_spd)
 		return -EINVAL;
 
 	/* were we already at the bottom? */
@@ -4974,17 +4974,19 @@
 	struct ata_link *link;
 	unsigned long flags;
 
-	/* Previous resume operation might still be in
-	 * progress.  Wait for PM_PENDING to clear.
-	 */
-	if (ap->pflags & ATA_PFLAG_PM_PENDING) {
-		ata_port_wait_eh(ap);
-		WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
-	}
-
-	/* request PM ops to EH */
 	spin_lock_irqsave(ap->lock, flags);
 
+	/*
+	 * A previous PM operation might still be in progress. Wait for
+	 * ATA_PFLAG_PM_PENDING to clear.
+	 */
+	if (ap->pflags & ATA_PFLAG_PM_PENDING) {
+		spin_unlock_irqrestore(ap->lock, flags);
+		ata_port_wait_eh(ap);
+		spin_lock_irqsave(ap->lock, flags);
+	}
+
+	/* Request PM operation to EH */
 	ap->pm_mesg = mesg;
 	ap->pflags |= ATA_PFLAG_PM_PENDING;
 	ata_for_each_link(link, ap, HOST_FIRST) {
@@ -4996,10 +4998,8 @@
 
 	spin_unlock_irqrestore(ap->lock, flags);
 
-	if (!async) {
+	if (!async)
 		ata_port_wait_eh(ap);
-		WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
-	}
 }
 
 /*
@@ -5167,7 +5167,7 @@
 #endif
 
 const struct device_type ata_port_type = {
-	.name = "ata_port",
+	.name = ATA_PORT_TYPE_NAME,
 #ifdef CONFIG_PM
 	.pm = &ata_port_pm_ops,
 #endif
@@ -5915,11 +5915,30 @@
 	if (!ap->ops->error_handler)
 		goto skip_eh;
 
-	/* tell EH we're leaving & flush EH */
+	/* Wait for any ongoing EH */
+	ata_port_wait_eh(ap);
+
+	mutex_lock(&ap->scsi_scan_mutex);
 	spin_lock_irqsave(ap->lock, flags);
+
+	/* Remove scsi devices */
+	ata_for_each_link(link, ap, HOST_FIRST) {
+		ata_for_each_dev(dev, link, ALL) {
+			if (dev->sdev) {
+				spin_unlock_irqrestore(ap->lock, flags);
+				scsi_remove_device(dev->sdev);
+				spin_lock_irqsave(ap->lock, flags);
+				dev->sdev = NULL;
+			}
+		}
+	}
+
+	/* Tell EH to disable all devices */
 	ap->pflags |= ATA_PFLAG_UNLOADING;
 	ata_port_schedule_eh(ap);
+
 	spin_unlock_irqrestore(ap->lock, flags);
+	mutex_unlock(&ap->scsi_scan_mutex);
 
 	/* wait till EH commits suicide */
 	ata_port_wait_eh(ap);
diff --git a/kernel/drivers/ata/libata-eh.c b/kernel/drivers/ata/libata-eh.c
index 973f4d3..5fb3eda 100644
--- a/kernel/drivers/ata/libata-eh.c
+++ b/kernel/drivers/ata/libata-eh.c
@@ -2703,18 +2703,11 @@
 			postreset(slave, classes);
 	}
 
-	/*
-	 * Some controllers can't be frozen very well and may set spurious
-	 * error conditions during reset.  Clear accumulated error
-	 * information and re-thaw the port if frozen.  As reset is the
-	 * final recovery action and we cross check link onlineness against
-	 * device classification later, no hotplug event is lost by this.
-	 */
+	/* clear cached SError */
 	spin_lock_irqsave(link->ap->lock, flags);
-	memset(&link->eh_info, 0, sizeof(link->eh_info));
+	link->eh_info.serror = 0;
 	if (slave)
-		memset(&slave->eh_info, 0, sizeof(link->eh_info));
-	ap->pflags &= ~ATA_PFLAG_EH_PENDING;
+		slave->eh_info.serror = 0;
 	spin_unlock_irqrestore(link->ap->lock, flags);
 
 	if (ap->pflags & ATA_PFLAG_FROZEN)
diff --git a/kernel/drivers/ata/libata-sata.c b/kernel/drivers/ata/libata-sata.c
index c16423e..4565606 100644
--- a/kernel/drivers/ata/libata-sata.c
+++ b/kernel/drivers/ata/libata-sata.c
@@ -317,7 +317,7 @@
 		 * immediately after resuming.  Delay 200ms before
 		 * debouncing.
 		 */
-		if (!(link->flags & ATA_LFLAG_NO_DB_DELAY))
+		if (!(link->flags & ATA_LFLAG_NO_DEBOUNCE_DELAY))
 			ata_msleep(link->ap, 200);
 
 		/* is SControl restored correctly? */
@@ -394,10 +394,23 @@
 	case ATA_LPM_MED_POWER_WITH_DIPM:
 	case ATA_LPM_MIN_POWER_WITH_PARTIAL:
 	case ATA_LPM_MIN_POWER:
-		if (ata_link_nr_enabled(link) > 0)
-			/* no restrictions on LPM transitions */
+		if (ata_link_nr_enabled(link) > 0) {
+			/* assume no restrictions on LPM transitions */
 			scontrol &= ~(0x7 << 8);
-		else {
+
+			/*
+			 * If the controller does not support partial, slumber,
+			 * or devsleep, then disallow these transitions.
+			 */
+			if (link->ap->host->flags & ATA_HOST_NO_PART)
+				scontrol |= (0x1 << 8);
+
+			if (link->ap->host->flags & ATA_HOST_NO_SSC)
+				scontrol |= (0x2 << 8);
+
+			if (link->ap->host->flags & ATA_HOST_NO_DEVSLP)
+				scontrol |= (0x4 << 8);
+		} else {
 			/* empty port, power off */
 			scontrol &= ~0xf;
 			scontrol |= (0x1 << 2);
diff --git a/kernel/drivers/ata/libata-scsi.c b/kernel/drivers/ata/libata-scsi.c
index f1755ef..36f32fa 100644
--- a/kernel/drivers/ata/libata-scsi.c
+++ b/kernel/drivers/ata/libata-scsi.c
@@ -2742,17 +2742,35 @@
 	return 0;
 }
 
-static struct ata_device *ata_find_dev(struct ata_port *ap, int devno)
+static struct ata_device *ata_find_dev(struct ata_port *ap, unsigned int devno)
 {
-	if (!sata_pmp_attached(ap)) {
-		if (likely(devno >= 0 &&
-			   devno < ata_link_max_devices(&ap->link)))
+	/*
+	 * For the non-PMP case, ata_link_max_devices() returns 1 (SATA case),
+	 * or 2 (IDE master + slave case). However, the former case includes
+	 * libsas hosted devices which are numbered per scsi host, leading
+	 * to devno potentially being larger than 0 but with each struct
+	 * ata_device having its own struct ata_port and struct ata_link.
+	 * To accommodate these, ignore devno and always use device number 0.
+	 */
+	if (likely(!sata_pmp_attached(ap))) {
+		int link_max_devices = ata_link_max_devices(&ap->link);
+
+		if (link_max_devices == 1)
+			return &ap->link.device[0];
+
+		if (devno < link_max_devices)
 			return &ap->link.device[devno];
-	} else {
-		if (likely(devno >= 0 &&
-			   devno < ap->nr_pmp_links))
-			return &ap->pmp_link[devno].device[0];
+
+		return NULL;
 	}
+
+	/*
+	 * For PMP-attached devices, the device number corresponds to C
+	 * (channel) of SCSI [H:C:I:L], indicating the port pmp link
+	 * for the device.
+	 */
+	if (devno < ap->nr_pmp_links)
+		return &ap->pmp_link[devno].device[0];
 
 	return NULL;
 }
@@ -4241,7 +4259,7 @@
 		break;
 
 	case MAINTENANCE_IN:
-		if (scsicmd[1] == MI_REPORT_SUPPORTED_OPERATION_CODES)
+		if ((scsicmd[1] & 0x1f) == MI_REPORT_SUPPORTED_OPERATION_CODES)
 			ata_scsi_rbuf_fill(&args, ata_scsiop_maint_in);
 		else
 			ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
diff --git a/kernel/drivers/ata/libata-transport.c b/kernel/drivers/ata/libata-transport.c
index 31a66fc..513b379 100644
--- a/kernel/drivers/ata/libata-transport.c
+++ b/kernel/drivers/ata/libata-transport.c
@@ -266,6 +266,10 @@
 	put_device(dev);
 }
 
+static const struct device_type ata_port_sas_type = {
+	.name = ATA_PORT_TYPE_NAME,
+};
+
 /** ata_tport_add - initialize a transport ATA port structure
  *
  * @parent:	parent device
@@ -283,7 +287,10 @@
 	struct device *dev = &ap->tdev;
 
 	device_initialize(dev);
-	dev->type = &ata_port_type;
+	if (ap->flags & ATA_FLAG_SAS_HOST)
+		dev->type = &ata_port_sas_type;
+	else
+		dev->type = &ata_port_type;
 
 	dev->parent = parent;
 	ata_host_get(ap->host);
diff --git a/kernel/drivers/ata/libata.h b/kernel/drivers/ata/libata.h
index 68cdd81..bf71bd9 100644
--- a/kernel/drivers/ata/libata.h
+++ b/kernel/drivers/ata/libata.h
@@ -30,6 +30,8 @@
 	ATA_DNXFER_QUIET	= (1 << 31),
 };
 
+#define ATA_PORT_TYPE_NAME	"ata_port"
+
 extern atomic_t ata_print_id;
 extern int atapi_passthru16;
 extern int libata_fua;
diff --git a/kernel/drivers/ata/pata_arasan_cf.c b/kernel/drivers/ata/pata_arasan_cf.c
index 63f3944..4ba02f0 100644
--- a/kernel/drivers/ata/pata_arasan_cf.c
+++ b/kernel/drivers/ata/pata_arasan_cf.c
@@ -528,7 +528,8 @@
 	/* dma_request_channel may sleep, so calling from process context */
 	acdev->dma_chan = dma_request_chan(acdev->host->dev, "data");
 	if (IS_ERR(acdev->dma_chan)) {
-		dev_err(acdev->host->dev, "Unable to get dma_chan\n");
+		dev_err_probe(acdev->host->dev, PTR_ERR(acdev->dma_chan),
+			      "Unable to get dma_chan\n");
 		acdev->dma_chan = NULL;
 		goto chan_request_fail;
 	}
diff --git a/kernel/drivers/ata/pata_ftide010.c b/kernel/drivers/ata/pata_ftide010.c
index 34cb104..bc30e2f 100644
--- a/kernel/drivers/ata/pata_ftide010.c
+++ b/kernel/drivers/ata/pata_ftide010.c
@@ -570,6 +570,7 @@
 };
 module_platform_driver(pata_ftide010_driver);
 
+MODULE_DESCRIPTION("low level driver for Faraday Technology FTIDE010");
 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/kernel/drivers/ata/pata_ixp4xx_cf.c b/kernel/drivers/ata/pata_ixp4xx_cf.c
index abc0e87..43215a4 100644
--- a/kernel/drivers/ata/pata_ixp4xx_cf.c
+++ b/kernel/drivers/ata/pata_ixp4xx_cf.c
@@ -135,12 +135,12 @@
 
 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);
diff --git a/kernel/drivers/ata/pata_ns87415.c b/kernel/drivers/ata/pata_ns87415.c
index 1532b2e..9217385 100644
--- a/kernel/drivers/ata/pata_ns87415.c
+++ b/kernel/drivers/ata/pata_ns87415.c
@@ -260,7 +260,7 @@
  *	LOCKING:
  *	Inherited from caller.
  */
-void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+static void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
 {
 	struct ata_ioports *ioaddr = &ap->ioaddr;
 
diff --git a/kernel/drivers/ata/sata_gemini.c b/kernel/drivers/ata/sata_gemini.c
index f793564..6fd54e9 100644
--- a/kernel/drivers/ata/sata_gemini.c
+++ b/kernel/drivers/ata/sata_gemini.c
@@ -435,6 +435,7 @@
 };
 module_platform_driver(gemini_sata_driver);
 
+MODULE_DESCRIPTION("low level driver for Cortina Systems Gemini SATA bridge");
 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/kernel/drivers/atm/idt77252.c b/kernel/drivers/atm/idt77252.c
index 82f6f1f..a217b50 100644
--- a/kernel/drivers/atm/idt77252.c
+++ b/kernel/drivers/atm/idt77252.c
@@ -2915,6 +2915,7 @@
 
 				recycle_rx_pool_skb(card, &vc->rcv.rx_pool);
 			}
+			kfree(vc);
 		}
 	}
 }
@@ -2956,6 +2957,15 @@
 	clear_bit(VCF_IDLE, &vc->flags);
 	writel(TCMDQ_START | 0, SAR_REG_TCMDQ);
 	return 0;
+}
+
+static void
+close_card_ubr0(struct idt77252_dev *card)
+{
+	struct vc_map *vc = card->vcs[0];
+
+	free_scq(card, vc->scq);
+	kfree(vc);
 }
 
 static int
@@ -3007,6 +3017,7 @@
 	struct idt77252_dev *card = dev->dev_data;
 	u32 conf;
 
+	close_card_ubr0(card);
 	close_card_oam(card);
 
 	conf = SAR_CFG_RXPTH |	/* enable receive path           */
diff --git a/kernel/drivers/base/class.c b/kernel/drivers/base/class.c
index c345148..ef7ff82 100644
--- a/kernel/drivers/base/class.c
+++ b/kernel/drivers/base/class.c
@@ -192,6 +192,11 @@
 	}
 	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);
diff --git a/kernel/drivers/base/core.c b/kernel/drivers/base/core.c
index 23fce12..a5f85b2 100644
--- a/kernel/drivers/base/core.c
+++ b/kernel/drivers/base/core.c
@@ -4635,6 +4635,13 @@
 }
 EXPORT_SYMBOL_GPL(device_set_of_node_from_dev);
 
+void device_set_node(struct device *dev, struct fwnode_handle *fwnode)
+{
+	dev->fwnode = fwnode;
+	dev->of_node = to_of_node(fwnode);
+}
+EXPORT_SYMBOL_GPL(device_set_node);
+
 int device_match_name(struct device *dev, const void *name)
 {
 	return sysfs_streq(dev_name(dev), name);
diff --git a/kernel/drivers/base/cpu.c b/kernel/drivers/base/cpu.c
index 24dd532..2db1e0e 100644
--- a/kernel/drivers/base/cpu.c
+++ b/kernel/drivers/base/cpu.c
@@ -489,7 +489,8 @@
 bool cpu_is_hotpluggable(unsigned cpu)
 {
 	struct device *dev = get_cpu_device(cpu);
-	return dev && container_of(dev, struct cpu, dev)->hotpluggable;
+	return dev && container_of(dev, struct cpu, dev)->hotpluggable
+		&& tick_nohz_cpu_hotpluggable(cpu);
 }
 EXPORT_SYMBOL_GPL(cpu_is_hotpluggable);
 
@@ -578,6 +579,18 @@
 	return sysfs_emit(buf, "Not affected\n");
 }
 
+ssize_t __weak cpu_show_gds(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	return sysfs_emit(buf, "Not affected\n");
+}
+
+ssize_t __weak cpu_show_spec_rstack_overflow(struct device *dev,
+					     struct device_attribute *attr, char *buf)
+{
+	return sysfs_emit(buf, "Not affected\n");
+}
+
 static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
 static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);
 static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL);
@@ -589,6 +602,8 @@
 static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL);
 static DEVICE_ATTR(mmio_stale_data, 0444, cpu_show_mmio_stale_data, NULL);
 static DEVICE_ATTR(retbleed, 0444, cpu_show_retbleed, NULL);
+static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL);
+static DEVICE_ATTR(spec_rstack_overflow, 0444, cpu_show_spec_rstack_overflow, NULL);
 
 static struct attribute *cpu_root_vulnerabilities_attrs[] = {
 	&dev_attr_meltdown.attr,
@@ -602,6 +617,8 @@
 	&dev_attr_srbds.attr,
 	&dev_attr_mmio_stale_data.attr,
 	&dev_attr_retbleed.attr,
+	&dev_attr_gather_data_sampling.attr,
+	&dev_attr_spec_rstack_overflow.attr,
 	NULL
 };
 
diff --git a/kernel/drivers/base/dd.c b/kernel/drivers/base/dd.c
index 020fd56..e0524eb 100644
--- a/kernel/drivers/base/dd.c
+++ b/kernel/drivers/base/dd.c
@@ -677,7 +677,12 @@
 	calltime = ktime_get();
 	ret = really_probe(dev, drv);
 	rettime = ktime_get();
-	pr_debug("probe of %s returned %d after %lld usecs\n",
+	/*
+	 * Don't change this to pr_debug() because that requires
+	 * CONFIG_DYNAMIC_DEBUG and we want a simple 'initcall_debug' on the
+	 * kernel commandline to print this all the time at the debug level.
+	 */
+	printk(KERN_DEBUG "probe of %s returned %d after %lld usecs\n",
 		 dev_name(dev), ret, ktime_us_delta(rettime, calltime));
 	return ret;
 }
@@ -1088,7 +1093,11 @@
 		return 0;
 	} else if (ret < 0) {
 		dev_dbg(dev, "Bus failed to match device: %d\n", ret);
-		return ret;
+		/*
+		 * Driver could not match with device, but may match with
+		 * another device on the bus.
+		 */
+		return 0;
 	} /* ret > 0 means positive match */
 
 	if (driver_allows_async_probing(drv)) {
diff --git a/kernel/drivers/base/firmware_loader/fallback.c b/kernel/drivers/base/firmware_loader/fallback.c
index 0fdd18c..45dfb6e 100644
--- a/kernel/drivers/base/firmware_loader/fallback.c
+++ b/kernel/drivers/base/firmware_loader/fallback.c
@@ -106,7 +106,7 @@
 
 static LIST_HEAD(pending_fw_head);
 
-void kill_pending_fw_fallback_reqs(bool only_kill_custom)
+void kill_pending_fw_fallback_reqs(bool kill_all)
 {
 	struct fw_priv *fw_priv;
 	struct fw_priv *next;
@@ -114,9 +114,13 @@
 	mutex_lock(&fw_lock);
 	list_for_each_entry_safe(fw_priv, next, &pending_fw_head,
 				 pending_list) {
-		if (!fw_priv->need_uevent || !only_kill_custom)
+		if (kill_all || !fw_priv->need_uevent)
 			 __fw_load_abort(fw_priv);
 	}
+
+	if (kill_all)
+		fw_load_abort_all = true;
+
 	mutex_unlock(&fw_lock);
 }
 
@@ -511,7 +515,7 @@
 	}
 
 	mutex_lock(&fw_lock);
-	if (fw_state_is_aborted(fw_priv)) {
+	if (fw_load_abort_all || fw_state_is_aborted(fw_priv)) {
 		mutex_unlock(&fw_lock);
 		retval = -EINTR;
 		goto out;
diff --git a/kernel/drivers/base/firmware_loader/fallback.h b/kernel/drivers/base/firmware_loader/fallback.h
index 3af7205..1d9476d 100644
--- a/kernel/drivers/base/firmware_loader/fallback.h
+++ b/kernel/drivers/base/firmware_loader/fallback.h
@@ -35,7 +35,7 @@
 			    struct device *device,
 			    u32 opt_flags,
 			    int ret);
-void kill_pending_fw_fallback_reqs(bool only_kill_custom);
+void kill_pending_fw_fallback_reqs(bool kill_all);
 
 void fw_fallback_set_cache_timeout(void);
 void fw_fallback_set_default_timeout(void);
@@ -52,7 +52,7 @@
 	return ret;
 }
 
-static inline void kill_pending_fw_fallback_reqs(bool only_kill_custom) { }
+static inline void kill_pending_fw_fallback_reqs(bool kill_all) { }
 static inline void fw_fallback_set_cache_timeout(void) { }
 static inline void fw_fallback_set_default_timeout(void) { }
 
diff --git a/kernel/drivers/base/firmware_loader/firmware.h b/kernel/drivers/base/firmware_loader/firmware.h
index a3014e9..53e08de 100644
--- a/kernel/drivers/base/firmware_loader/firmware.h
+++ b/kernel/drivers/base/firmware_loader/firmware.h
@@ -87,6 +87,7 @@
 };
 
 extern struct mutex fw_lock;
+extern bool fw_load_abort_all;
 
 static inline bool __fw_state_check(struct fw_priv *fw_priv,
 				    enum fw_status status)
diff --git a/kernel/drivers/base/firmware_loader/main.c b/kernel/drivers/base/firmware_loader/main.c
index 1372f40..9dbfdf9 100644
--- a/kernel/drivers/base/firmware_loader/main.c
+++ b/kernel/drivers/base/firmware_loader/main.c
@@ -91,6 +91,7 @@
 DEFINE_MUTEX(fw_lock);
 
 static struct firmware_cache fw_cache;
+bool fw_load_abort_all;
 
 /* Builtin firmware support */
 
@@ -1442,10 +1443,10 @@
 	case PM_SUSPEND_PREPARE:
 	case PM_RESTORE_PREPARE:
 		/*
-		 * kill pending fallback requests with a custom fallback
-		 * to avoid stalling suspend.
+		 * Here, kill pending fallback requests will only kill
+		 * non-uevent firmware request to avoid stalling suspend.
 		 */
-		kill_pending_fw_fallback_reqs(true);
+		kill_pending_fw_fallback_reqs(false);
 		device_cache_fw_images();
 		break;
 
@@ -1530,7 +1531,7 @@
 	 * Kill all pending fallback requests to avoid both stalling shutdown,
 	 * and avoid a deadlock with the usermode_lock.
 	 */
-	kill_pending_fw_fallback_reqs(false);
+	kill_pending_fw_fallback_reqs(true);
 
 	return NOTIFY_DONE;
 }
diff --git a/kernel/drivers/base/power/domain.c b/kernel/drivers/base/power/domain.c
index c4e56e0..fa76018 100644
--- a/kernel/drivers/base/power/domain.c
+++ b/kernel/drivers/base/power/domain.c
@@ -2835,10 +2835,10 @@
 
 	err = of_property_read_u32(state_node, "min-residency-us", &residency);
 	if (!err)
-		genpd_state->residency_ns = 1000 * residency;
+		genpd_state->residency_ns = 1000LL * residency;
 
-	genpd_state->power_on_latency_ns = 1000 * exit_latency;
-	genpd_state->power_off_latency_ns = 1000 * entry_latency;
+	genpd_state->power_on_latency_ns = 1000LL * exit_latency;
+	genpd_state->power_off_latency_ns = 1000LL * entry_latency;
 	genpd_state->fwnode = &state_node->fwnode;
 
 	return 0;
diff --git a/kernel/drivers/base/power/power.h b/kernel/drivers/base/power/power.h
index 54292cd..922ed45 100644
--- a/kernel/drivers/base/power/power.h
+++ b/kernel/drivers/base/power/power.h
@@ -25,8 +25,11 @@
 
 #define WAKE_IRQ_DEDICATED_ALLOCATED	BIT(0)
 #define WAKE_IRQ_DEDICATED_MANAGED	BIT(1)
+#define WAKE_IRQ_DEDICATED_REVERSE	BIT(2)
 #define WAKE_IRQ_DEDICATED_MASK		(WAKE_IRQ_DEDICATED_ALLOCATED | \
-					 WAKE_IRQ_DEDICATED_MANAGED)
+					 WAKE_IRQ_DEDICATED_MANAGED | \
+					 WAKE_IRQ_DEDICATED_REVERSE)
+#define WAKE_IRQ_DEDICATED_ENABLED	BIT(3)
 
 struct wake_irq {
 	struct device *dev;
@@ -39,7 +42,8 @@
 extern void dev_pm_disarm_wake_irq(struct wake_irq *wirq);
 extern void dev_pm_enable_wake_irq_check(struct device *dev,
 					 bool can_change_status);
-extern void dev_pm_disable_wake_irq_check(struct device *dev);
+extern void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable);
+extern void dev_pm_enable_wake_irq_complete(struct device *dev);
 
 #ifdef CONFIG_PM_SLEEP
 
diff --git a/kernel/drivers/base/power/runtime.c b/kernel/drivers/base/power/runtime.c
index 835a39e..fbbc3ed 100644
--- a/kernel/drivers/base/power/runtime.c
+++ b/kernel/drivers/base/power/runtime.c
@@ -464,7 +464,10 @@
 	/* 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,17 @@
 
 	dev->power.idle_notification = true;
 
-	callback = RPM_GET_CALLBACK(dev, runtime_idle);
+	if (dev->power.irq_safe)
+		spin_unlock(&dev->power.lock);
+	else
+		spin_unlock_irq(&dev->power.lock);
 
-	if (callback)
-		retval = __rpm_callback(callback, dev);
+	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);
@@ -665,6 +675,8 @@
 	if (retval)
 		goto fail;
 
+	dev_pm_enable_wake_irq_complete(dev);
+
  no_callback:
 	__update_runtime_status(dev, RPM_SUSPENDED);
 	pm_runtime_deactivate_timer(dev);
@@ -710,7 +722,7 @@
 	return retval;
 
  fail:
-	dev_pm_disable_wake_irq_check(dev);
+	dev_pm_disable_wake_irq_check(dev, true);
 	__update_runtime_status(dev, RPM_ACTIVE);
 	dev->power.deferred_resume = false;
 	wake_up_all(&dev->power.wait_queue);
@@ -893,7 +905,7 @@
 
 	callback = RPM_GET_CALLBACK(dev, runtime_resume);
 
-	dev_pm_disable_wake_irq_check(dev);
+	dev_pm_disable_wake_irq_check(dev, false);
 	retval = rpm_callback(callback, dev);
 	if (retval) {
 		__update_runtime_status(dev, RPM_SUSPENDED);
diff --git a/kernel/drivers/base/power/wakeirq.c b/kernel/drivers/base/power/wakeirq.c
index 8e02108..aea690c 100644
--- a/kernel/drivers/base/power/wakeirq.c
+++ b/kernel/drivers/base/power/wakeirq.c
@@ -145,24 +145,7 @@
 	return IRQ_HANDLED;
 }
 
-/**
- * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt
- * @dev: Device entry
- * @irq: Device wake-up interrupt
- *
- * Unless your hardware has separate wake-up interrupts in addition
- * to the device IO interrupts, you don't need this.
- *
- * Sets up a threaded interrupt handler for a device that has
- * a dedicated wake-up interrupt in addition to the device IO
- * interrupt.
- *
- * The interrupt starts disabled, and needs to be managed for
- * the device by the bus code or the device driver using
- * dev_pm_enable_wake_irq() and dev_pm_disable_wake_irq()
- * functions.
- */
-int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
+static int __dev_pm_set_dedicated_wake_irq(struct device *dev, int irq, unsigned int flag)
 {
 	struct wake_irq *wirq;
 	int err;
@@ -200,7 +183,7 @@
 	if (err)
 		goto err_free_irq;
 
-	wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED;
+	wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED | flag;
 
 	return err;
 
@@ -213,7 +196,56 @@
 
 	return err;
 }
+
+
+/**
+ * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt
+ * @dev: Device entry
+ * @irq: Device wake-up interrupt
+ *
+ * Unless your hardware has separate wake-up interrupts in addition
+ * to the device IO interrupts, you don't need this.
+ *
+ * Sets up a threaded interrupt handler for a device that has
+ * a dedicated wake-up interrupt in addition to the device IO
+ * interrupt.
+ *
+ * The interrupt starts disabled, and needs to be managed for
+ * the device by the bus code or the device driver using
+ * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*()
+ * functions.
+ */
+int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
+{
+	return __dev_pm_set_dedicated_wake_irq(dev, irq, 0);
+}
 EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq);
+
+/**
+ * dev_pm_set_dedicated_wake_irq_reverse - Request a dedicated wake-up interrupt
+ *                                         with reverse enable ordering
+ * @dev: Device entry
+ * @irq: Device wake-up interrupt
+ *
+ * Unless your hardware has separate wake-up interrupts in addition
+ * to the device IO interrupts, you don't need this.
+ *
+ * Sets up a threaded interrupt handler for a device that has a dedicated
+ * wake-up interrupt in addition to the device IO interrupt. It sets
+ * the status of WAKE_IRQ_DEDICATED_REVERSE to tell rpm_suspend()
+ * to enable dedicated wake-up interrupt after running the runtime suspend
+ * callback for @dev.
+ *
+ * The interrupt starts disabled, and needs to be managed for
+ * the device by the bus code or the device driver using
+ * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*()
+ * functions.
+ */
+int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq)
+{
+	return __dev_pm_set_dedicated_wake_irq(dev, irq, WAKE_IRQ_DEDICATED_REVERSE);
+}
+EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq_reverse);
 
 /**
  * dev_pm_enable_wake_irq - Enable device wake-up interrupt
@@ -285,25 +317,56 @@
 	return;
 
 enable:
-	enable_irq(wirq->irq);
+	if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) {
+		enable_irq(wirq->irq);
+		wirq->status |= WAKE_IRQ_DEDICATED_ENABLED;
+	}
 }
 
 /**
  * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt
  * @dev: Device
+ * @cond_disable: if set, also check WAKE_IRQ_DEDICATED_REVERSE
  *
  * Disables wake-up interrupt conditionally based on status.
  * Should be only called from rpm_suspend() and rpm_resume() path.
  */
-void dev_pm_disable_wake_irq_check(struct device *dev)
+void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable)
 {
 	struct wake_irq *wirq = dev->power.wakeirq;
 
 	if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
 		return;
 
-	if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED)
+	if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE))
+		return;
+
+	if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) {
+		wirq->status &= ~WAKE_IRQ_DEDICATED_ENABLED;
 		disable_irq_nosync(wirq->irq);
+	}
+}
+
+/**
+ * dev_pm_enable_wake_irq_complete - enable wake IRQ not enabled before
+ * @dev: Device using the wake IRQ
+ *
+ * Enable wake IRQ conditionally based on status, mainly used if want to
+ * enable wake IRQ after running ->runtime_suspend() which depends on
+ * WAKE_IRQ_DEDICATED_REVERSE.
+ *
+ * Should be only called from rpm_suspend() path.
+ */
+void dev_pm_enable_wake_irq_complete(struct device *dev)
+{
+	struct wake_irq *wirq = dev->power.wakeirq;
+
+	if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
+		return;
+
+	if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED &&
+	    wirq->status & WAKE_IRQ_DEDICATED_REVERSE)
+		enable_irq(wirq->irq);
 }
 
 /**
@@ -320,7 +383,7 @@
 
 	if (device_may_wakeup(wirq->dev)) {
 		if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
-		    !pm_runtime_status_suspended(wirq->dev))
+		    !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
 			enable_irq(wirq->irq);
 
 		enable_irq_wake(wirq->irq);
@@ -343,7 +406,7 @@
 		disable_irq_wake(wirq->irq);
 
 		if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
-		    !pm_runtime_status_suspended(wirq->dev))
+		    !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
 			disable_irq_nosync(wirq->irq);
 	}
 }
diff --git a/kernel/drivers/base/regmap/regcache-rbtree.c b/kernel/drivers/base/regmap/regcache-rbtree.c
index fabf870..d65715b 100644
--- a/kernel/drivers/base/regmap/regcache-rbtree.c
+++ b/kernel/drivers/base/regmap/regcache-rbtree.c
@@ -277,7 +277,7 @@
 
 	blk = krealloc(rbnode->block,
 		       blklen * map->cache_word_size,
-		       GFP_KERNEL);
+		       map->alloc_flags);
 	if (!blk)
 		return -ENOMEM;
 
@@ -286,7 +286,7 @@
 	if (BITS_TO_LONGS(blklen) > BITS_TO_LONGS(rbnode->blklen)) {
 		present = krealloc(rbnode->cache_present,
 				   BITS_TO_LONGS(blklen) * sizeof(*present),
-				   GFP_KERNEL);
+				   map->alloc_flags);
 		if (!present)
 			return -ENOMEM;
 
@@ -320,7 +320,7 @@
 	const struct regmap_range *range;
 	int i;
 
-	rbnode = kzalloc(sizeof(*rbnode), GFP_KERNEL);
+	rbnode = kzalloc(sizeof(*rbnode), map->alloc_flags);
 	if (!rbnode)
 		return NULL;
 
@@ -346,13 +346,13 @@
 	}
 
 	rbnode->block = kmalloc_array(rbnode->blklen, map->cache_word_size,
-				      GFP_KERNEL);
+				      map->alloc_flags);
 	if (!rbnode->block)
 		goto err_free;
 
 	rbnode->cache_present = kcalloc(BITS_TO_LONGS(rbnode->blklen),
 					sizeof(*rbnode->cache_present),
-					GFP_KERNEL);
+					map->alloc_flags);
 	if (!rbnode->cache_present)
 		goto err_free_block;
 
@@ -453,7 +453,8 @@
 		if (!rbnode)
 			return -ENOMEM;
 		regcache_rbtree_set_register(map, rbnode,
-					     reg - rbnode->base_reg, value);
+					     (reg - rbnode->base_reg) / map->reg_stride,
+					     value);
 		regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode);
 		rbtree_ctx->cached_rbnode = rbnode;
 	}
diff --git a/kernel/drivers/base/regmap/regcache.c b/kernel/drivers/base/regmap/regcache.c
index 7f4b3b6..7fdd702 100644
--- a/kernel/drivers/base/regmap/regcache.c
+++ b/kernel/drivers/base/regmap/regcache.c
@@ -343,6 +343,9 @@
 	const char *name;
 	bool bypass;
 
+	if (WARN_ON(map->cache_type == REGCACHE_NONE))
+		return -EINVAL;
+
 	BUG_ON(!map->cache_ops);
 
 	map->lock(map->lock_arg);
@@ -412,6 +415,9 @@
 	const char *name;
 	bool bypass;
 
+	if (WARN_ON(map->cache_type == REGCACHE_NONE))
+		return -EINVAL;
+
 	BUG_ON(!map->cache_ops);
 
 	map->lock(map->lock_arg);
diff --git a/kernel/drivers/base/regmap/regmap-i2c.c b/kernel/drivers/base/regmap/regmap-i2c.c
index 62b95a9..051c10e 100644
--- a/kernel/drivers/base/regmap/regmap-i2c.c
+++ b/kernel/drivers/base/regmap/regmap-i2c.c
@@ -242,8 +242,8 @@
 static const struct regmap_bus regmap_i2c_smbus_i2c_block = {
 	.write = regmap_i2c_smbus_i2c_write,
 	.read = regmap_i2c_smbus_i2c_read,
-	.max_raw_read = I2C_SMBUS_BLOCK_MAX,
-	.max_raw_write = I2C_SMBUS_BLOCK_MAX,
+	.max_raw_read = I2C_SMBUS_BLOCK_MAX - 1,
+	.max_raw_write = I2C_SMBUS_BLOCK_MAX - 1,
 };
 
 static int regmap_i2c_smbus_i2c_write_reg16(void *context, const void *data,
@@ -299,8 +299,8 @@
 static const struct regmap_bus regmap_i2c_smbus_i2c_block_reg16 = {
 	.write = regmap_i2c_smbus_i2c_write_reg16,
 	.read = regmap_i2c_smbus_i2c_read_reg16,
-	.max_raw_read = I2C_SMBUS_BLOCK_MAX,
-	.max_raw_write = I2C_SMBUS_BLOCK_MAX,
+	.max_raw_read = I2C_SMBUS_BLOCK_MAX - 2,
+	.max_raw_write = I2C_SMBUS_BLOCK_MAX - 2,
 };
 
 static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
diff --git a/kernel/drivers/base/test/test_async_driver_probe.c b/kernel/drivers/base/test/test_async_driver_probe.c
index 3bb7beb..88336f0 100644
--- a/kernel/drivers/base/test/test_async_driver_probe.c
+++ b/kernel/drivers/base/test/test_async_driver_probe.c
@@ -84,7 +84,7 @@
 
 	pdev = platform_device_alloc(name, id);
 	if (!pdev)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	if (nid != NUMA_NO_NODE)
 		set_dev_node(&pdev->dev, nid);
@@ -146,7 +146,7 @@
 	calltime = ktime_get();
 	for_each_online_cpu(cpu) {
 		nid = cpu_to_node(cpu);
-		pdev = &sync_dev[sync_id];
+		pdev = &async_dev[async_id];
 
 		*pdev = test_platform_device_register_node("test_async_driver",
 							   async_id,
diff --git a/kernel/drivers/block/Kconfig b/kernel/drivers/block/Kconfig
index 40c5363..408c742 100644
--- a/kernel/drivers/block/Kconfig
+++ b/kernel/drivers/block/Kconfig
@@ -16,13 +16,7 @@
 
 if BLK_DEV
 
-config BLK_DEV_NULL_BLK
-	tristate "Null test block driver"
-	select CONFIGFS_FS
-
-config BLK_DEV_NULL_BLK_FAULT_INJECTION
-	bool "Support fault injection for Null test block driver"
-	depends on BLK_DEV_NULL_BLK && FAULT_INJECTION
+source "drivers/block/null_blk/Kconfig"
 
 config BLK_DEV_FD
 	tristate "Normal floppy disk support"
@@ -298,15 +292,6 @@
 	STEC, Inc. S1120 PCIe SSD.
 
 	Use device /dev/skd$N amd /dev/skd$Np$M.
-
-config BLK_DEV_SX8
-	tristate "Promise SATA SX8 support"
-	depends on PCI
-	help
-	  Saying Y or M here will enable support for the 
-	  Promise SATA SX8 controllers.
-
-	  Use devices /dev/sx8/$N and /dev/sx8/$Np$M.
 
 config BLK_DEV_RAM
 	tristate "RAM block device support"
diff --git a/kernel/drivers/block/Makefile b/kernel/drivers/block/Makefile
index e1f6311..24427da 100644
--- a/kernel/drivers/block/Makefile
+++ b/kernel/drivers/block/Makefile
@@ -29,8 +29,6 @@
 obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o
 obj-$(CONFIG_VIRTIO_BLK)	+= virtio_blk.o
 
-obj-$(CONFIG_BLK_DEV_SX8)	+= sx8.o
-
 obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	+= xen-blkfront.o
 obj-$(CONFIG_XEN_BLKDEV_BACKEND)	+= xen-blkback/
 obj-$(CONFIG_BLK_DEV_DRBD)     += drbd/
@@ -41,12 +39,7 @@
 obj-$(CONFIG_ZRAM) += zram/
 obj-$(CONFIG_BLK_DEV_RNBD)	+= rnbd/
 
-obj-$(CONFIG_BLK_DEV_NULL_BLK)	+= null_blk.o
-null_blk-objs	:= null_blk_main.o
-ifeq ($(CONFIG_BLK_DEV_ZONED), y)
-null_blk-$(CONFIG_TRACING) += null_blk_trace.o
-endif
-null_blk-$(CONFIG_BLK_DEV_ZONED) += null_blk_zoned.o
+obj-$(CONFIG_BLK_DEV_NULL_BLK)	+= null_blk/
 
 skd-y		:= skd_main.o
 swim_mod-y	:= swim.o swim_asm.o
diff --git a/kernel/drivers/block/brd.c b/kernel/drivers/block/brd.c
index cc49a92..11078e1 100644
--- a/kernel/drivers/block/brd.c
+++ b/kernel/drivers/block/brd.c
@@ -80,11 +80,9 @@
 }
 
 /*
- * Look up and return a brd's page for a given sector.
- * If one does not exist, allocate an empty page, and insert that. Then
- * return it.
+ * Insert a new page for a given sector, if one does not already exist.
  */
-static struct page *brd_insert_page(struct brd_device *brd, sector_t sector)
+static int brd_insert_page(struct brd_device *brd, sector_t sector)
 {
 	pgoff_t idx;
 	struct page *page;
@@ -92,7 +90,7 @@
 
 	page = brd_lookup_page(brd, sector);
 	if (page)
-		return page;
+		return 0;
 
 	/*
 	 * Must use NOIO because we don't want to recurse back into the
@@ -101,11 +99,11 @@
 	gfp_flags = GFP_NOIO | __GFP_ZERO | __GFP_HIGHMEM;
 	page = alloc_page(gfp_flags);
 	if (!page)
-		return NULL;
+		return -ENOMEM;
 
 	if (radix_tree_preload(GFP_NOIO)) {
 		__free_page(page);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	spin_lock(&brd->brd_lock);
@@ -120,8 +118,7 @@
 	spin_unlock(&brd->brd_lock);
 
 	radix_tree_preload_end();
-
-	return page;
+	return 0;
 }
 
 /*
@@ -174,16 +171,17 @@
 {
 	unsigned int offset = (sector & (PAGE_SECTORS-1)) << SECTOR_SHIFT;
 	size_t copy;
+	int ret;
 
 	copy = min_t(size_t, n, PAGE_SIZE - offset);
-	if (!brd_insert_page(brd, sector))
-		return -ENOSPC;
+	ret = brd_insert_page(brd, sector);
+	if (ret)
+		return ret;
 	if (copy < n) {
 		sector += copy >> SECTOR_SHIFT;
-		if (!brd_insert_page(brd, sector))
-			return -ENOSPC;
+		ret = brd_insert_page(brd, sector);
 	}
-	return 0;
+	return ret;
 }
 
 /*
diff --git a/kernel/drivers/block/drbd/drbd_main.c b/kernel/drivers/block/drbd/drbd_main.c
index 51450f7..420bdaf 100644
--- a/kernel/drivers/block/drbd/drbd_main.c
+++ b/kernel/drivers/block/drbd/drbd_main.c
@@ -2819,7 +2819,7 @@
 
 	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 @@
 	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);
diff --git a/kernel/drivers/block/drbd/drbd_receiver.c b/kernel/drivers/block/drbd/drbd_receiver.c
index dc333db..405e095 100644
--- a/kernel/drivers/block/drbd/drbd_receiver.c
+++ b/kernel/drivers/block/drbd/drbd_receiver.c
@@ -1299,7 +1299,7 @@
 	bio_set_dev(bio, device->ldev->backing_bdev);
 	bio->bi_private = octx;
 	bio->bi_end_io = one_flush_endio;
-	bio->bi_opf = REQ_OP_FLUSH | REQ_PREFLUSH;
+	bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
 
 	device->flush_jif = jiffies;
 	set_bit(FLUSH_PENDING, &device->flags);
diff --git a/kernel/drivers/block/loop.c b/kernel/drivers/block/loop.c
index 538a076..38a2461 100644
--- a/kernel/drivers/block/loop.c
+++ b/kernel/drivers/block/loop.c
@@ -1029,12 +1029,12 @@
 	if (err)
 		return err;
 
+	/* Avoid assigning overflow values */
+	if (info->lo_offset > LLONG_MAX || info->lo_sizelimit > LLONG_MAX)
+		return -EOVERFLOW;
+
 	lo->lo_offset = info->lo_offset;
 	lo->lo_sizelimit = info->lo_sizelimit;
-
-	/* loff_t vars have been assigned __u64 */
-	if (lo->lo_offset < 0 || lo->lo_sizelimit < 0)
-		return -EOVERFLOW;
 
 	memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE);
 	memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE);
diff --git a/kernel/drivers/block/nbd.c b/kernel/drivers/block/nbd.c
index b0d3dad..e0f805c 100644
--- a/kernel/drivers/block/nbd.c
+++ b/kernel/drivers/block/nbd.c
@@ -1624,7 +1624,7 @@
 		return -EIO;
 
 	dir = debugfs_create_dir(nbd_name(nbd), nbd_dbg_dir);
-	if (!dir) {
+	if (IS_ERR(dir)) {
 		dev_err(nbd_to_dev(nbd), "Failed to create debugfs dir for '%s'\n",
 			nbd_name(nbd));
 		return -EIO;
@@ -1650,7 +1650,7 @@
 	struct dentry *dbg_dir;
 
 	dbg_dir = debugfs_create_dir("nbd", NULL);
-	if (!dbg_dir)
+	if (IS_ERR(dbg_dir))
 		return -EIO;
 
 	nbd_dbg_dir = dbg_dir;
@@ -1723,7 +1723,8 @@
 		if (err == -ENOSPC)
 			err = -EEXIST;
 	} else {
-		err = idr_alloc(&nbd_index_idr, nbd, 0, 0, GFP_KERNEL);
+		err = idr_alloc(&nbd_index_idr, nbd, 0,
+				(MINORMASK >> part_shift) + 1, GFP_KERNEL);
 		if (err >= 0)
 			index = err;
 	}
@@ -1865,8 +1866,19 @@
 	if (!netlink_capable(skb, CAP_SYS_ADMIN))
 		return -EPERM;
 
-	if (info->attrs[NBD_ATTR_INDEX])
+	if (info->attrs[NBD_ATTR_INDEX]) {
 		index = nla_get_u32(info->attrs[NBD_ATTR_INDEX]);
+
+		/*
+		 * Too big first_minor can cause duplicate creation of
+		 * sysfs files/links, since index << part_shift might overflow, or
+		 * MKDEV() expect that the max bits of first_minor is 20.
+		 */
+		if (index < 0 || index > MINORMASK >> part_shift) {
+			printk(KERN_ERR "nbd: illegal input index %d\n", index);
+			return -EINVAL;
+		}
+	}
 	if (!info->attrs[NBD_ATTR_SOCKETS]) {
 		printk(KERN_ERR "nbd: must specify at least one socket\n");
 		return -EINVAL;
diff --git a/kernel/drivers/block/null_blk/Kconfig b/kernel/drivers/block/null_blk/Kconfig
new file mode 100644
index 0000000..6bf1f8c
--- /dev/null
+++ b/kernel/drivers/block/null_blk/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Null block device driver configuration
+#
+
+config BLK_DEV_NULL_BLK
+	tristate "Null test block driver"
+	select CONFIGFS_FS
+
+config BLK_DEV_NULL_BLK_FAULT_INJECTION
+	bool "Support fault injection for Null test block driver"
+	depends on BLK_DEV_NULL_BLK && FAULT_INJECTION
diff --git a/kernel/drivers/block/null_blk/Makefile b/kernel/drivers/block/null_blk/Makefile
new file mode 100644
index 0000000..84c36e5
--- /dev/null
+++ b/kernel/drivers/block/null_blk/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# needed for trace events
+ccflags-y			+= -I$(src)
+
+obj-$(CONFIG_BLK_DEV_NULL_BLK)	+= null_blk.o
+null_blk-objs			:= main.o
+ifeq ($(CONFIG_BLK_DEV_ZONED), y)
+null_blk-$(CONFIG_TRACING) 	+= trace.o
+endif
+null_blk-$(CONFIG_BLK_DEV_ZONED) += zoned.o
diff --git a/kernel/drivers/block/null_blk_main.c b/kernel/drivers/block/null_blk/main.c
similarity index 98%
rename from kernel/drivers/block/null_blk_main.c
rename to kernel/drivers/block/null_blk/main.c
index c6ba8f9..35b390a 100644
--- a/kernel/drivers/block/null_blk_main.c
+++ b/kernel/drivers/block/null_blk/main.c
@@ -1309,8 +1309,7 @@
 	case NULL_IRQ_SOFTIRQ:
 		switch (cmd->nq->dev->queue_mode) {
 		case NULL_Q_MQ:
-			if (likely(!blk_should_fake_timeout(cmd->rq->q)))
-				blk_mq_complete_request(cmd->rq);
+			blk_mq_complete_request(cmd->rq);
 			break;
 		case NULL_Q_BIO:
 			/*
@@ -1486,7 +1485,8 @@
 	cmd->rq = bd->rq;
 	cmd->error = BLK_STS_OK;
 	cmd->nq = nq;
-	cmd->fake_timeout = should_timeout_request(bd->rq);
+	cmd->fake_timeout = should_timeout_request(bd->rq) ||
+		blk_should_fake_timeout(bd->rq->q);
 
 	blk_mq_start_request(bd->rq);
 
@@ -1738,6 +1738,11 @@
 
 static int null_validate_conf(struct nullb_device *dev)
 {
+	if (dev->queue_mode == NULL_Q_RQ) {
+		pr_err("legacy IO path is no longer available\n");
+		return -EINVAL;
+	}
+
 	dev->blocksize = round_down(dev->blocksize, 512);
 	dev->blocksize = clamp_t(unsigned int, dev->blocksize, 512, 4096);
 
diff --git a/kernel/drivers/block/null_blk.h b/kernel/drivers/block/null_blk/null_blk.h
similarity index 100%
rename from kernel/drivers/block/null_blk.h
rename to kernel/drivers/block/null_blk/null_blk.h
diff --git a/kernel/drivers/block/null_blk_trace.c b/kernel/drivers/block/null_blk/trace.c
similarity index 93%
rename from kernel/drivers/block/null_blk_trace.c
rename to kernel/drivers/block/null_blk/trace.c
index f246e7b..3711cba 100644
--- a/kernel/drivers/block/null_blk_trace.c
+++ b/kernel/drivers/block/null_blk/trace.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2020 Western Digital Corporation or its affiliates.
  */
-#include "null_blk_trace.h"
+#include "trace.h"
 
 /*
  * Helper to use for all null_blk traces to extract disk name.
diff --git a/kernel/drivers/block/null_blk_trace.h b/kernel/drivers/block/null_blk/trace.h
similarity index 97%
rename from kernel/drivers/block/null_blk_trace.h
rename to kernel/drivers/block/null_blk/trace.h
index 4f83032..ce3b430 100644
--- a/kernel/drivers/block/null_blk_trace.h
+++ b/kernel/drivers/block/null_blk/trace.h
@@ -73,7 +73,7 @@
 #undef TRACE_INCLUDE_PATH
 #define TRACE_INCLUDE_PATH .
 #undef TRACE_INCLUDE_FILE
-#define TRACE_INCLUDE_FILE null_blk_trace
+#define TRACE_INCLUDE_FILE trace
 
 /* This part must be outside protection */
 #include <trace/define_trace.h>
diff --git a/kernel/drivers/block/null_blk_zoned.c b/kernel/drivers/block/null_blk/zoned.c
similarity index 99%
rename from kernel/drivers/block/null_blk_zoned.c
rename to kernel/drivers/block/null_blk/zoned.c
index f5df82c..41220ce 100644
--- a/kernel/drivers/block/null_blk_zoned.c
+++ b/kernel/drivers/block/null_blk/zoned.c
@@ -4,7 +4,7 @@
 #include "null_blk.h"
 
 #define CREATE_TRACE_POINTS
-#include "null_blk_trace.h"
+#include "trace.h"
 
 #define MB_TO_SECTS(mb) (((sector_t)mb * SZ_1M) >> SECTOR_SHIFT)
 
diff --git a/kernel/drivers/block/rbd.c b/kernel/drivers/block/rbd.c
index 340b1df..b0f7930 100644
--- a/kernel/drivers/block/rbd.c
+++ b/kernel/drivers/block/rbd.c
@@ -632,9 +632,8 @@
 static void rbd_dev_remove_parent(struct rbd_device *rbd_dev);
 
 static int rbd_dev_refresh(struct rbd_device *rbd_dev);
-static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev);
-static int rbd_dev_header_info(struct rbd_device *rbd_dev);
-static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev);
+static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev,
+				     struct rbd_image_header *header);
 static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev,
 					u64 snap_id);
 static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
@@ -1047,15 +1046,24 @@
 	RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL);
 }
 
+static void rbd_image_header_cleanup(struct rbd_image_header *header)
+{
+	kfree(header->object_prefix);
+	ceph_put_snap_context(header->snapc);
+	kfree(header->snap_sizes);
+	kfree(header->snap_names);
+
+	memset(header, 0, sizeof(*header));
+}
+
 /*
  * Fill an rbd image header with information from the given format 1
  * on-disk header.
  */
-static int rbd_header_from_disk(struct rbd_device *rbd_dev,
-				 struct rbd_image_header_ondisk *ondisk)
+static int rbd_header_from_disk(struct rbd_image_header *header,
+				struct rbd_image_header_ondisk *ondisk,
+				bool first_time)
 {
-	struct rbd_image_header *header = &rbd_dev->header;
-	bool first_time = header->object_prefix == NULL;
 	struct ceph_snap_context *snapc;
 	char *object_prefix = NULL;
 	char *snap_names = NULL;
@@ -1122,11 +1130,6 @@
 	if (first_time) {
 		header->object_prefix = object_prefix;
 		header->obj_order = ondisk->options.order;
-		rbd_init_layout(rbd_dev);
-	} else {
-		ceph_put_snap_context(header->snapc);
-		kfree(header->snap_names);
-		kfree(header->snap_sizes);
 	}
 
 	/* The remaining fields always get updated (when we refresh) */
@@ -1397,14 +1400,30 @@
 /*
  * Must be called after rbd_obj_calc_img_extents().
  */
-static bool rbd_obj_copyup_enabled(struct rbd_obj_request *obj_req)
+static void rbd_obj_set_copyup_enabled(struct rbd_obj_request *obj_req)
 {
-	if (!obj_req->num_img_extents ||
-	    (rbd_obj_is_entire(obj_req) &&
-	     !obj_req->img_request->snapc->num_snaps))
-		return false;
+	rbd_assert(obj_req->img_request->snapc);
 
-	return true;
+	if (obj_req->img_request->op_type == OBJ_OP_DISCARD) {
+		dout("%s %p objno %llu discard\n", __func__, obj_req,
+		     obj_req->ex.oe_objno);
+		return;
+	}
+
+	if (!obj_req->num_img_extents) {
+		dout("%s %p objno %llu not overlapping\n", __func__, obj_req,
+		     obj_req->ex.oe_objno);
+		return;
+	}
+
+	if (rbd_obj_is_entire(obj_req) &&
+	    !obj_req->img_request->snapc->num_snaps) {
+		dout("%s %p objno %llu entire\n", __func__, obj_req,
+		     obj_req->ex.oe_objno);
+		return;
+	}
+
+	obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ENABLED;
 }
 
 static u64 rbd_obj_img_extents_bytes(struct rbd_obj_request *obj_req)
@@ -1505,6 +1524,7 @@
 static struct ceph_osd_request *
 rbd_obj_add_osd_request(struct rbd_obj_request *obj_req, int num_ops)
 {
+	rbd_assert(obj_req->img_request->snapc);
 	return __rbd_obj_add_osd_request(obj_req, obj_req->img_request->snapc,
 					 num_ops);
 }
@@ -1641,15 +1661,18 @@
 	mutex_init(&img_request->state_mutex);
 }
 
+/*
+ * Only snap_id is captured here, for reads.  For writes, snapshot
+ * context is captured in rbd_img_object_requests() after exclusive
+ * lock is ensured to be held.
+ */
 static void rbd_img_capture_header(struct rbd_img_request *img_req)
 {
 	struct rbd_device *rbd_dev = img_req->rbd_dev;
 
 	lockdep_assert_held(&rbd_dev->header_rwsem);
 
-	if (rbd_img_is_write(img_req))
-		img_req->snapc = ceph_get_snap_context(rbd_dev->header.snapc);
-	else
+	if (!rbd_img_is_write(img_req))
 		img_req->snap_id = rbd_dev->spec->snap_id;
 
 	if (rbd_dev_parent_get(rbd_dev))
@@ -2296,9 +2319,6 @@
 	if (ret)
 		return ret;
 
-	if (rbd_obj_copyup_enabled(obj_req))
-		obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ENABLED;
-
 	obj_req->write_state = RBD_OBJ_WRITE_START;
 	return 0;
 }
@@ -2404,8 +2424,6 @@
 	if (ret)
 		return ret;
 
-	if (rbd_obj_copyup_enabled(obj_req))
-		obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ENABLED;
 	if (!obj_req->num_img_extents) {
 		obj_req->flags |= RBD_OBJ_FLAG_NOOP_FOR_NONEXISTENT;
 		if (rbd_obj_is_entire(obj_req))
@@ -3351,6 +3369,7 @@
 	case RBD_OBJ_WRITE_START:
 		rbd_assert(!*result);
 
+		rbd_obj_set_copyup_enabled(obj_req);
 		if (rbd_obj_write_is_noop(obj_req))
 			return true;
 
@@ -3537,9 +3556,19 @@
 
 static void rbd_img_object_requests(struct rbd_img_request *img_req)
 {
+	struct rbd_device *rbd_dev = img_req->rbd_dev;
 	struct rbd_obj_request *obj_req;
 
 	rbd_assert(!img_req->pending.result && !img_req->pending.num_pending);
+	rbd_assert(!need_exclusive_lock(img_req) ||
+		   __rbd_is_lock_owner(rbd_dev));
+
+	if (rbd_img_is_write(img_req)) {
+		rbd_assert(!img_req->snapc);
+		down_read(&rbd_dev->header_rwsem);
+		img_req->snapc = ceph_get_snap_context(rbd_dev->header.snapc);
+		up_read(&rbd_dev->header_rwsem);
+	}
 
 	for_each_obj_request(img_req, obj_req) {
 		int result = 0;
@@ -3557,7 +3586,6 @@
 
 static bool rbd_img_advance(struct rbd_img_request *img_req, int *result)
 {
-	struct rbd_device *rbd_dev = img_req->rbd_dev;
 	int ret;
 
 again:
@@ -3577,9 +3605,6 @@
 	case RBD_IMG_EXCLUSIVE_LOCK:
 		if (*result)
 			return true;
-
-		rbd_assert(!need_exclusive_lock(img_req) ||
-			   __rbd_is_lock_owner(rbd_dev));
 
 		rbd_img_object_requests(img_req);
 		if (!img_req->pending.num_pending) {
@@ -3718,7 +3743,7 @@
 	ret = ceph_cls_lock(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc,
 			    RBD_LOCK_NAME, CEPH_CLS_LOCK_EXCLUSIVE, cookie,
 			    RBD_LOCK_TAG, "", 0);
-	if (ret)
+	if (ret && ret != -EEXIST)
 		return ret;
 
 	__rbd_lock(rbd_dev, cookie);
@@ -3892,10 +3917,26 @@
 	list_splice_tail_init(&rbd_dev->acquiring_list, &rbd_dev->running_list);
 }
 
-static int get_lock_owner_info(struct rbd_device *rbd_dev,
-			       struct ceph_locker **lockers, u32 *num_lockers)
+static bool locker_equal(const struct ceph_locker *lhs,
+			 const struct ceph_locker *rhs)
+{
+	return lhs->id.name.type == rhs->id.name.type &&
+	       lhs->id.name.num == rhs->id.name.num &&
+	       !strcmp(lhs->id.cookie, rhs->id.cookie) &&
+	       ceph_addr_equal_no_type(&lhs->info.addr, &rhs->info.addr);
+}
+
+static void free_locker(struct ceph_locker *locker)
+{
+	if (locker)
+		ceph_free_lockers(locker, 1);
+}
+
+static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev)
 {
 	struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
+	struct ceph_locker *lockers;
+	u32 num_lockers;
 	u8 lock_type;
 	char *lock_tag;
 	int ret;
@@ -3904,39 +3945,45 @@
 
 	ret = ceph_cls_lock_info(osdc, &rbd_dev->header_oid,
 				 &rbd_dev->header_oloc, RBD_LOCK_NAME,
-				 &lock_type, &lock_tag, lockers, num_lockers);
-	if (ret)
-		return ret;
+				 &lock_type, &lock_tag, &lockers, &num_lockers);
+	if (ret) {
+		rbd_warn(rbd_dev, "failed to get header lockers: %d", ret);
+		return ERR_PTR(ret);
+	}
 
-	if (*num_lockers == 0) {
+	if (num_lockers == 0) {
 		dout("%s rbd_dev %p no lockers detected\n", __func__, rbd_dev);
+		lockers = NULL;
 		goto out;
 	}
 
 	if (strcmp(lock_tag, RBD_LOCK_TAG)) {
 		rbd_warn(rbd_dev, "locked by external mechanism, tag %s",
 			 lock_tag);
-		ret = -EBUSY;
-		goto out;
+		goto err_busy;
 	}
 
 	if (lock_type == CEPH_CLS_LOCK_SHARED) {
 		rbd_warn(rbd_dev, "shared lock type detected");
-		ret = -EBUSY;
-		goto out;
+		goto err_busy;
 	}
 
-	if (strncmp((*lockers)[0].id.cookie, RBD_LOCK_COOKIE_PREFIX,
+	WARN_ON(num_lockers != 1);
+	if (strncmp(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX,
 		    strlen(RBD_LOCK_COOKIE_PREFIX))) {
 		rbd_warn(rbd_dev, "locked by external mechanism, cookie %s",
-			 (*lockers)[0].id.cookie);
-		ret = -EBUSY;
-		goto out;
+			 lockers[0].id.cookie);
+		goto err_busy;
 	}
 
 out:
 	kfree(lock_tag);
-	return ret;
+	return lockers;
+
+err_busy:
+	kfree(lock_tag);
+	ceph_free_lockers(lockers, num_lockers);
+	return ERR_PTR(-EBUSY);
 }
 
 static int find_watcher(struct rbd_device *rbd_dev,
@@ -3952,13 +3999,19 @@
 	ret = ceph_osdc_list_watchers(osdc, &rbd_dev->header_oid,
 				      &rbd_dev->header_oloc, &watchers,
 				      &num_watchers);
-	if (ret)
+	if (ret) {
+		rbd_warn(rbd_dev, "failed to get watchers: %d", ret);
 		return ret;
+	}
 
 	sscanf(locker->id.cookie, RBD_LOCK_COOKIE_PREFIX " %llu", &cookie);
 	for (i = 0; i < num_watchers; i++) {
-		if (!memcmp(&watchers[i].addr, &locker->info.addr,
-			    sizeof(locker->info.addr)) &&
+		/*
+		 * Ignore addr->type while comparing.  This mimics
+		 * entity_addr_t::get_legacy_str() + strcmp().
+		 */
+		if (ceph_addr_equal_no_type(&watchers[i].addr,
+					    &locker->info.addr) &&
 		    watchers[i].cookie == cookie) {
 			struct rbd_client_id cid = {
 				.gid = le64_to_cpu(watchers[i].name.num),
@@ -3986,57 +4039,82 @@
 static int rbd_try_lock(struct rbd_device *rbd_dev)
 {
 	struct ceph_client *client = rbd_dev->rbd_client->client;
-	struct ceph_locker *lockers;
-	u32 num_lockers;
+	struct ceph_locker *locker, *refreshed_locker;
 	int ret;
 
 	for (;;) {
+		locker = refreshed_locker = NULL;
+
 		ret = rbd_lock(rbd_dev);
-		if (ret != -EBUSY)
-			return ret;
+		if (!ret)
+			goto out;
+		if (ret != -EBUSY) {
+			rbd_warn(rbd_dev, "failed to lock header: %d", ret);
+			goto out;
+		}
 
 		/* determine if the current lock holder is still alive */
-		ret = get_lock_owner_info(rbd_dev, &lockers, &num_lockers);
-		if (ret)
-			return ret;
-
-		if (num_lockers == 0)
+		locker = get_lock_owner_info(rbd_dev);
+		if (IS_ERR(locker)) {
+			ret = PTR_ERR(locker);
+			locker = NULL;
+			goto out;
+		}
+		if (!locker)
 			goto again;
 
-		ret = find_watcher(rbd_dev, lockers);
+		ret = find_watcher(rbd_dev, locker);
 		if (ret)
 			goto out; /* request lock or error */
 
+		refreshed_locker = get_lock_owner_info(rbd_dev);
+		if (IS_ERR(refreshed_locker)) {
+			ret = PTR_ERR(refreshed_locker);
+			refreshed_locker = NULL;
+			goto out;
+		}
+		if (!refreshed_locker ||
+		    !locker_equal(locker, refreshed_locker))
+			goto again;
+
 		rbd_warn(rbd_dev, "breaking header lock owned by %s%llu",
-			 ENTITY_NAME(lockers[0].id.name));
+			 ENTITY_NAME(locker->id.name));
 
 		ret = ceph_monc_blocklist_add(&client->monc,
-					      &lockers[0].info.addr);
+					      &locker->info.addr);
 		if (ret) {
-			rbd_warn(rbd_dev, "blocklist of %s%llu failed: %d",
-				 ENTITY_NAME(lockers[0].id.name), ret);
+			rbd_warn(rbd_dev, "failed to blocklist %s%llu: %d",
+				 ENTITY_NAME(locker->id.name), ret);
 			goto out;
 		}
 
 		ret = ceph_cls_break_lock(&client->osdc, &rbd_dev->header_oid,
 					  &rbd_dev->header_oloc, RBD_LOCK_NAME,
-					  lockers[0].id.cookie,
-					  &lockers[0].id.name);
-		if (ret && ret != -ENOENT)
+					  locker->id.cookie, &locker->id.name);
+		if (ret && ret != -ENOENT) {
+			rbd_warn(rbd_dev, "failed to break header lock: %d",
+				 ret);
 			goto out;
+		}
 
 again:
-		ceph_free_lockers(lockers, num_lockers);
+		free_locker(refreshed_locker);
+		free_locker(locker);
 	}
 
 out:
-	ceph_free_lockers(lockers, num_lockers);
+	free_locker(refreshed_locker);
+	free_locker(locker);
 	return ret;
 }
 
 static int rbd_post_acquire_action(struct rbd_device *rbd_dev)
 {
 	int ret;
+
+	ret = rbd_dev_refresh(rbd_dev);
+	if (ret)
+		return ret;
 
 	if (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP) {
 		ret = rbd_object_map_open(rbd_dev);
@@ -4076,11 +4154,8 @@
 
 	ret = rbd_try_lock(rbd_dev);
 	if (ret < 0) {
-		rbd_warn(rbd_dev, "failed to lock header: %d", ret);
-		if (ret == -EBLOCKLISTED)
-			goto out;
-
-		ret = 1; /* request lock anyway */
+		rbd_warn(rbd_dev, "failed to acquire lock: %d", ret);
+		goto out;
 	}
 	if (ret > 0) {
 		up_write(&rbd_dev->lock_rwsem);
@@ -4844,7 +4919,9 @@
  * return, the rbd_dev->header field will contain up-to-date
  * information about the image.
  */
-static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev)
+static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev,
+				  struct rbd_image_header *header,
+				  bool first_time)
 {
 	struct rbd_image_header_ondisk *ondisk = NULL;
 	u32 snap_count = 0;
@@ -4892,7 +4969,7 @@
 		snap_count = le32_to_cpu(ondisk->snap_count);
 	} while (snap_count != want_count);
 
-	ret = rbd_header_from_disk(rbd_dev, ondisk);
+	ret = rbd_header_from_disk(header, ondisk, first_time);
 out:
 	kfree(ondisk);
 
@@ -4915,39 +4992,6 @@
 		set_capacity(rbd_dev->disk, size);
 		revalidate_disk_size(rbd_dev->disk, true);
 	}
-}
-
-static int rbd_dev_refresh(struct rbd_device *rbd_dev)
-{
-	u64 mapping_size;
-	int ret;
-
-	down_write(&rbd_dev->header_rwsem);
-	mapping_size = rbd_dev->mapping.size;
-
-	ret = rbd_dev_header_info(rbd_dev);
-	if (ret)
-		goto out;
-
-	/*
-	 * If there is a parent, see if it has disappeared due to the
-	 * mapped image getting flattened.
-	 */
-	if (rbd_dev->parent) {
-		ret = rbd_dev_v2_parent_info(rbd_dev);
-		if (ret)
-			goto out;
-	}
-
-	rbd_assert(!rbd_is_snap(rbd_dev));
-	rbd_dev->mapping.size = rbd_dev->header.image_size;
-
-out:
-	up_write(&rbd_dev->header_rwsem);
-	if (!ret && mapping_size != rbd_dev->mapping.size)
-		rbd_dev_update_size(rbd_dev);
-
-	return ret;
 }
 
 static const struct blk_mq_ops rbd_mq_ops = {
@@ -5369,8 +5413,7 @@
 		module_put(THIS_MODULE);
 }
 
-static struct rbd_device *__rbd_dev_create(struct rbd_client *rbdc,
-					   struct rbd_spec *spec)
+static struct rbd_device *__rbd_dev_create(struct rbd_spec *spec)
 {
 	struct rbd_device *rbd_dev;
 
@@ -5415,9 +5458,6 @@
 	rbd_dev->dev.parent = &rbd_root_dev;
 	device_initialize(&rbd_dev->dev);
 
-	rbd_dev->rbd_client = rbdc;
-	rbd_dev->spec = spec;
-
 	return rbd_dev;
 }
 
@@ -5430,11 +5470,9 @@
 {
 	struct rbd_device *rbd_dev;
 
-	rbd_dev = __rbd_dev_create(rbdc, spec);
+	rbd_dev = __rbd_dev_create(spec);
 	if (!rbd_dev)
 		return NULL;
-
-	rbd_dev->opts = opts;
 
 	/* get an id and fill in device name */
 	rbd_dev->dev_id = ida_simple_get(&rbd_dev_id_ida, 0,
@@ -5451,6 +5489,10 @@
 
 	/* we have a ref from do_rbd_add() */
 	__module_get(THIS_MODULE);
+
+	rbd_dev->rbd_client = rbdc;
+	rbd_dev->spec = spec;
+	rbd_dev->opts = opts;
 
 	dout("%s rbd_dev %p dev_id %d\n", __func__, rbd_dev, rbd_dev->dev_id);
 	return rbd_dev;
@@ -5506,17 +5548,12 @@
 	return 0;
 }
 
-static int rbd_dev_v2_image_size(struct rbd_device *rbd_dev)
-{
-	return _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP,
-					&rbd_dev->header.obj_order,
-					&rbd_dev->header.image_size);
-}
-
-static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev)
+static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev,
+				    char **pobject_prefix)
 {
 	size_t size;
 	void *reply_buf;
+	char *object_prefix;
 	int ret;
 	void *p;
 
@@ -5534,16 +5571,16 @@
 		goto out;
 
 	p = reply_buf;
-	rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p,
-						p + ret, NULL, GFP_NOIO);
+	object_prefix = ceph_extract_encoded_string(&p, p + ret, NULL,
+						    GFP_NOIO);
+	if (IS_ERR(object_prefix)) {
+		ret = PTR_ERR(object_prefix);
+		goto out;
+	}
 	ret = 0;
 
-	if (IS_ERR(rbd_dev->header.object_prefix)) {
-		ret = PTR_ERR(rbd_dev->header.object_prefix);
-		rbd_dev->header.object_prefix = NULL;
-	} else {
-		dout("  object_prefix = %s\n", rbd_dev->header.object_prefix);
-	}
+	*pobject_prefix = object_prefix;
+	dout("  object_prefix = %s\n", object_prefix);
 out:
 	kfree(reply_buf);
 
@@ -5594,13 +5631,6 @@
 	return 0;
 }
 
-static int rbd_dev_v2_features(struct rbd_device *rbd_dev)
-{
-	return _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP,
-					 rbd_is_ro(rbd_dev),
-					 &rbd_dev->header.features);
-}
-
 /*
  * These are generic image flags, but since they are used only for
  * object map, store them in rbd_dev->object_map_flags.
@@ -5636,6 +5666,14 @@
 	bool		has_overlap;
 	u64		overlap;
 };
+
+static void rbd_parent_info_cleanup(struct parent_image_info *pii)
+{
+	kfree(pii->pool_ns);
+	kfree(pii->image_id);
+
+	memset(pii, 0, sizeof(*pii));
+}
 
 /*
  * The caller is responsible for @pii.
@@ -5706,6 +5744,9 @@
 	if (pii->has_overlap)
 		ceph_decode_64_safe(&p, end, pii->overlap, e_inval);
 
+	dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n",
+	     __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id,
+	     pii->has_overlap, pii->overlap);
 	return 0;
 
 e_inval:
@@ -5744,14 +5785,17 @@
 	pii->has_overlap = true;
 	ceph_decode_64_safe(&p, end, pii->overlap, e_inval);
 
+	dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n",
+	     __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id,
+	     pii->has_overlap, pii->overlap);
 	return 0;
 
 e_inval:
 	return -EINVAL;
 }
 
-static int get_parent_info(struct rbd_device *rbd_dev,
-			   struct parent_image_info *pii)
+static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev,
+				  struct parent_image_info *pii)
 {
 	struct page *req_page, *reply_page;
 	void *p;
@@ -5779,7 +5823,7 @@
 	return ret;
 }
 
-static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
+static int rbd_dev_setup_parent(struct rbd_device *rbd_dev)
 {
 	struct rbd_spec *parent_spec;
 	struct parent_image_info pii = { 0 };
@@ -5789,37 +5833,12 @@
 	if (!parent_spec)
 		return -ENOMEM;
 
-	ret = get_parent_info(rbd_dev, &pii);
+	ret = rbd_dev_v2_parent_info(rbd_dev, &pii);
 	if (ret)
 		goto out_err;
 
-	dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n",
-	     __func__, pii.pool_id, pii.pool_ns, pii.image_id, pii.snap_id,
-	     pii.has_overlap, pii.overlap);
-
-	if (pii.pool_id == CEPH_NOPOOL || !pii.has_overlap) {
-		/*
-		 * Either the parent never existed, or we have
-		 * record of it but the image got flattened so it no
-		 * longer has a parent.  When the parent of a
-		 * layered image disappears we immediately set the
-		 * overlap to 0.  The effect of this is that all new
-		 * requests will be treated as if the image had no
-		 * parent.
-		 *
-		 * If !pii.has_overlap, the parent image spec is not
-		 * applicable.  It's there to avoid duplication in each
-		 * snapshot record.
-		 */
-		if (rbd_dev->parent_overlap) {
-			rbd_dev->parent_overlap = 0;
-			rbd_dev_parent_put(rbd_dev);
-			pr_info("%s: clone image has been flattened\n",
-				rbd_dev->disk->disk_name);
-		}
-
+	if (pii.pool_id == CEPH_NOPOOL || !pii.has_overlap)
 		goto out;	/* No parent?  No problem. */
-	}
 
 	/* The ceph file layout needs to fit pool id in 32 bits */
 
@@ -5831,58 +5850,46 @@
 	}
 
 	/*
-	 * The parent won't change (except when the clone is
-	 * flattened, already handled that).  So we only need to
-	 * record the parent spec we have not already done so.
+	 * The parent won't change except when the clone is flattened,
+	 * so we only need to record the parent image spec once.
 	 */
-	if (!rbd_dev->parent_spec) {
-		parent_spec->pool_id = pii.pool_id;
-		if (pii.pool_ns && *pii.pool_ns) {
-			parent_spec->pool_ns = pii.pool_ns;
-			pii.pool_ns = NULL;
-		}
-		parent_spec->image_id = pii.image_id;
-		pii.image_id = NULL;
-		parent_spec->snap_id = pii.snap_id;
-
-		rbd_dev->parent_spec = parent_spec;
-		parent_spec = NULL;	/* rbd_dev now owns this */
+	parent_spec->pool_id = pii.pool_id;
+	if (pii.pool_ns && *pii.pool_ns) {
+		parent_spec->pool_ns = pii.pool_ns;
+		pii.pool_ns = NULL;
 	}
+	parent_spec->image_id = pii.image_id;
+	pii.image_id = NULL;
+	parent_spec->snap_id = pii.snap_id;
+
+	rbd_assert(!rbd_dev->parent_spec);
+	rbd_dev->parent_spec = parent_spec;
+	parent_spec = NULL;	/* rbd_dev now owns this */
 
 	/*
-	 * We always update the parent overlap.  If it's zero we issue
-	 * a warning, as we will proceed as if there was no parent.
+	 * Record the parent overlap.  If it's zero, issue a warning as
+	 * we will proceed as if there is no parent.
 	 */
-	if (!pii.overlap) {
-		if (parent_spec) {
-			/* refresh, careful to warn just once */
-			if (rbd_dev->parent_overlap)
-				rbd_warn(rbd_dev,
-				    "clone now standalone (overlap became 0)");
-		} else {
-			/* initial probe */
-			rbd_warn(rbd_dev, "clone is standalone (overlap 0)");
-		}
-	}
+	if (!pii.overlap)
+		rbd_warn(rbd_dev, "clone is standalone (overlap 0)");
 	rbd_dev->parent_overlap = pii.overlap;
 
 out:
 	ret = 0;
 out_err:
-	kfree(pii.pool_ns);
-	kfree(pii.image_id);
+	rbd_parent_info_cleanup(&pii);
 	rbd_spec_put(parent_spec);
 	return ret;
 }
 
-static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev)
+static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev,
+				    u64 *stripe_unit, u64 *stripe_count)
 {
 	struct {
 		__le64 stripe_unit;
 		__le64 stripe_count;
 	} __attribute__ ((packed)) striping_info_buf = { 0 };
 	size_t size = sizeof (striping_info_buf);
-	void *p;
 	int ret;
 
 	ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid,
@@ -5894,27 +5901,33 @@
 	if (ret < size)
 		return -ERANGE;
 
-	p = &striping_info_buf;
-	rbd_dev->header.stripe_unit = ceph_decode_64(&p);
-	rbd_dev->header.stripe_count = ceph_decode_64(&p);
+	*stripe_unit = le64_to_cpu(striping_info_buf.stripe_unit);
+	*stripe_count = le64_to_cpu(striping_info_buf.stripe_count);
+	dout("  stripe_unit = %llu stripe_count = %llu\n", *stripe_unit,
+	     *stripe_count);
+
 	return 0;
 }
 
-static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev)
+static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev, s64 *data_pool_id)
 {
-	__le64 data_pool_id;
+	__le64 data_pool_buf;
 	int ret;
 
 	ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid,
 				  &rbd_dev->header_oloc, "get_data_pool",
-				  NULL, 0, &data_pool_id, sizeof(data_pool_id));
+				  NULL, 0, &data_pool_buf,
+				  sizeof(data_pool_buf));
+	dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret);
 	if (ret < 0)
 		return ret;
-	if (ret < sizeof(data_pool_id))
+	if (ret < sizeof(data_pool_buf))
 		return -EBADMSG;
 
-	rbd_dev->header.data_pool_id = le64_to_cpu(data_pool_id);
-	WARN_ON(rbd_dev->header.data_pool_id == CEPH_NOPOOL);
+	*data_pool_id = le64_to_cpu(data_pool_buf);
+	dout("  data_pool_id = %lld\n", *data_pool_id);
+	WARN_ON(*data_pool_id == CEPH_NOPOOL);
+
 	return 0;
 }
 
@@ -6106,7 +6119,8 @@
 	return ret;
 }
 
-static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev)
+static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev,
+				   struct ceph_snap_context **psnapc)
 {
 	size_t size;
 	int ret;
@@ -6167,9 +6181,7 @@
 	for (i = 0; i < snap_count; i++)
 		snapc->snaps[i] = ceph_decode_64(&p);
 
-	ceph_put_snap_context(rbd_dev->header.snapc);
-	rbd_dev->header.snapc = snapc;
-
+	*psnapc = snapc;
 	dout("  snap context seq = %llu, snap_count = %u\n",
 		(unsigned long long)seq, (unsigned int)snap_count);
 out:
@@ -6218,38 +6230,42 @@
 	return snap_name;
 }
 
-static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev)
+static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev,
+				  struct rbd_image_header *header,
+				  bool first_time)
 {
-	bool first_time = rbd_dev->header.object_prefix == NULL;
 	int ret;
 
-	ret = rbd_dev_v2_image_size(rbd_dev);
+	ret = _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP,
+				    first_time ? &header->obj_order : NULL,
+				    &header->image_size);
 	if (ret)
 		return ret;
 
 	if (first_time) {
-		ret = rbd_dev_v2_header_onetime(rbd_dev);
+		ret = rbd_dev_v2_header_onetime(rbd_dev, header);
 		if (ret)
 			return ret;
 	}
 
-	ret = rbd_dev_v2_snap_context(rbd_dev);
-	if (ret && first_time) {
-		kfree(rbd_dev->header.object_prefix);
-		rbd_dev->header.object_prefix = NULL;
-	}
+	ret = rbd_dev_v2_snap_context(rbd_dev, &header->snapc);
+	if (ret)
+		return ret;
 
-	return ret;
+	return 0;
 }
 
-static int rbd_dev_header_info(struct rbd_device *rbd_dev)
+static int rbd_dev_header_info(struct rbd_device *rbd_dev,
+			       struct rbd_image_header *header,
+			       bool first_time)
 {
 	rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
+	rbd_assert(!header->object_prefix && !header->snapc);
 
 	if (rbd_dev->image_format == 1)
-		return rbd_dev_v1_header_info(rbd_dev);
+		return rbd_dev_v1_header_info(rbd_dev, header, first_time);
 
-	return rbd_dev_v2_header_info(rbd_dev);
+	return rbd_dev_v2_header_info(rbd_dev, header, first_time);
 }
 
 /*
@@ -6632,12 +6648,11 @@
 		cancel_delayed_work_sync(&rbd_dev->lock_dwork);
 		if (!ret)
 			ret = -ETIMEDOUT;
-	}
 
-	if (ret) {
-		rbd_warn(rbd_dev, "failed to acquire exclusive lock: %ld", ret);
-		return ret;
+		rbd_warn(rbd_dev, "failed to acquire lock: %ld", ret);
 	}
+	if (ret)
+		return ret;
 
 	/*
 	 * The lock may have been released by now, unless automatic lock
@@ -6737,60 +6752,49 @@
  */
 static void rbd_dev_unprobe(struct rbd_device *rbd_dev)
 {
-	struct rbd_image_header	*header;
-
 	rbd_dev_parent_put(rbd_dev);
 	rbd_object_map_free(rbd_dev);
 	rbd_dev_mapping_clear(rbd_dev);
 
 	/* Free dynamic fields from the header, then zero it out */
 
-	header = &rbd_dev->header;
-	ceph_put_snap_context(header->snapc);
-	kfree(header->snap_sizes);
-	kfree(header->snap_names);
-	kfree(header->object_prefix);
-	memset(header, 0, sizeof (*header));
+	rbd_image_header_cleanup(&rbd_dev->header);
 }
 
-static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev)
+static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev,
+				     struct rbd_image_header *header)
 {
 	int ret;
 
-	ret = rbd_dev_v2_object_prefix(rbd_dev);
+	ret = rbd_dev_v2_object_prefix(rbd_dev, &header->object_prefix);
 	if (ret)
-		goto out_err;
+		return ret;
 
 	/*
 	 * Get the and check features for the image.  Currently the
 	 * features are assumed to never change.
 	 */
-	ret = rbd_dev_v2_features(rbd_dev);
+	ret = _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP,
+					rbd_is_ro(rbd_dev), &header->features);
 	if (ret)
-		goto out_err;
+		return ret;
 
 	/* If the image supports fancy striping, get its parameters */
 
-	if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) {
-		ret = rbd_dev_v2_striping_info(rbd_dev);
-		if (ret < 0)
-			goto out_err;
-	}
-
-	if (rbd_dev->header.features & RBD_FEATURE_DATA_POOL) {
-		ret = rbd_dev_v2_data_pool(rbd_dev);
+	if (header->features & RBD_FEATURE_STRIPINGV2) {
+		ret = rbd_dev_v2_striping_info(rbd_dev, &header->stripe_unit,
+					       &header->stripe_count);
 		if (ret)
-			goto out_err;
+			return ret;
 	}
 
-	rbd_init_layout(rbd_dev);
-	return 0;
+	if (header->features & RBD_FEATURE_DATA_POOL) {
+		ret = rbd_dev_v2_data_pool(rbd_dev, &header->data_pool_id);
+		if (ret)
+			return ret;
+	}
 
-out_err:
-	rbd_dev->header.features = 0;
-	kfree(rbd_dev->header.object_prefix);
-	rbd_dev->header.object_prefix = NULL;
-	return ret;
+	return 0;
 }
 
 /*
@@ -6812,7 +6816,7 @@
 		goto out_err;
 	}
 
-	parent = __rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec);
+	parent = __rbd_dev_create(rbd_dev->parent_spec);
 	if (!parent) {
 		ret = -ENOMEM;
 		goto out_err;
@@ -6822,8 +6826,8 @@
 	 * Images related by parent/child relationships always share
 	 * rbd_client and spec/parent_spec, so bump their refcounts.
 	 */
-	__rbd_get_client(rbd_dev->rbd_client);
-	rbd_spec_get(rbd_dev->parent_spec);
+	parent->rbd_client = __rbd_get_client(rbd_dev->rbd_client);
+	parent->spec = rbd_spec_get(rbd_dev->parent_spec);
 
 	__set_bit(RBD_DEV_FLAG_READONLY, &parent->flags);
 
@@ -6985,12 +6989,14 @@
 	if (!depth)
 		down_write(&rbd_dev->header_rwsem);
 
-	ret = rbd_dev_header_info(rbd_dev);
+	ret = rbd_dev_header_info(rbd_dev, &rbd_dev->header, true);
 	if (ret) {
 		if (ret == -ENOENT && !need_watch)
 			rbd_print_dne(rbd_dev, false);
 		goto err_out_probe;
 	}
+
+	rbd_init_layout(rbd_dev);
 
 	/*
 	 * If this image is the one being mapped, we have pool name and
@@ -7020,7 +7026,7 @@
 	}
 
 	if (rbd_dev->header.features & RBD_FEATURE_LAYERING) {
-		ret = rbd_dev_v2_parent_info(rbd_dev);
+		ret = rbd_dev_setup_parent(rbd_dev);
 		if (ret)
 			goto err_out_probe;
 	}
@@ -7046,6 +7052,107 @@
 	return ret;
 }
 
+static void rbd_dev_update_header(struct rbd_device *rbd_dev,
+				  struct rbd_image_header *header)
+{
+	rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
+	rbd_assert(rbd_dev->header.object_prefix); /* !first_time */
+
+	if (rbd_dev->header.image_size != header->image_size) {
+		rbd_dev->header.image_size = header->image_size;
+
+		if (!rbd_is_snap(rbd_dev)) {
+			rbd_dev->mapping.size = header->image_size;
+			rbd_dev_update_size(rbd_dev);
+		}
+	}
+
+	ceph_put_snap_context(rbd_dev->header.snapc);
+	rbd_dev->header.snapc = header->snapc;
+	header->snapc = NULL;
+
+	if (rbd_dev->image_format == 1) {
+		kfree(rbd_dev->header.snap_names);
+		rbd_dev->header.snap_names = header->snap_names;
+		header->snap_names = NULL;
+
+		kfree(rbd_dev->header.snap_sizes);
+		rbd_dev->header.snap_sizes = header->snap_sizes;
+		header->snap_sizes = NULL;
+	}
+}
+
+static void rbd_dev_update_parent(struct rbd_device *rbd_dev,
+				  struct parent_image_info *pii)
+{
+	if (pii->pool_id == CEPH_NOPOOL || !pii->has_overlap) {
+		/*
+		 * Either the parent never existed, or we have
+		 * record of it but the image got flattened so it no
+		 * longer has a parent.  When the parent of a
+		 * layered image disappears we immediately set the
+		 * overlap to 0.  The effect of this is that all new
+		 * requests will be treated as if the image had no
+		 * parent.
+		 *
+		 * If !pii.has_overlap, the parent image spec is not
+		 * applicable.  It's there to avoid duplication in each
+		 * snapshot record.
+		 */
+		if (rbd_dev->parent_overlap) {
+			rbd_dev->parent_overlap = 0;
+			rbd_dev_parent_put(rbd_dev);
+			pr_info("%s: clone has been flattened\n",
+				rbd_dev->disk->disk_name);
+		}
+	} else {
+		rbd_assert(rbd_dev->parent_spec);
+
+		/*
+		 * Update the parent overlap.  If it became zero, issue
+		 * a warning as we will proceed as if there is no parent.
+		 */
+		if (!pii->overlap && rbd_dev->parent_overlap)
+			rbd_warn(rbd_dev,
+				 "clone has become standalone (overlap 0)");
+		rbd_dev->parent_overlap = pii->overlap;
+	}
+}
+
+static int rbd_dev_refresh(struct rbd_device *rbd_dev)
+{
+	struct rbd_image_header	header = { 0 };
+	struct parent_image_info pii = { 0 };
+	int ret;
+
+	dout("%s rbd_dev %p\n", __func__, rbd_dev);
+
+	ret = rbd_dev_header_info(rbd_dev, &header, false);
+	if (ret)
+		goto out;
+
+	/*
+	 * If there is a parent, see if it has disappeared due to the
+	 * mapped image getting flattened.
+	 */
+	if (rbd_dev->parent) {
+		ret = rbd_dev_v2_parent_info(rbd_dev, &pii);
+		if (ret)
+			goto out;
+	}
+
+	down_write(&rbd_dev->header_rwsem);
+	rbd_dev_update_header(rbd_dev, &header);
+	if (rbd_dev->parent)
+		rbd_dev_update_parent(rbd_dev, &pii);
+	up_write(&rbd_dev->header_rwsem);
+
+out:
+	rbd_parent_info_cleanup(&pii);
+	rbd_image_header_cleanup(&header);
+	return ret;
+}
+
 static ssize_t do_rbd_add(struct bus_type *bus,
 			  const char *buf,
 			  size_t count)
diff --git a/kernel/drivers/block/rnbd/rnbd-proto.h b/kernel/drivers/block/rnbd/rnbd-proto.h
index ca16624..cb11855 100644
--- a/kernel/drivers/block/rnbd/rnbd-proto.h
+++ b/kernel/drivers/block/rnbd/rnbd-proto.h
@@ -234,7 +234,7 @@
 		bio_opf = REQ_OP_WRITE;
 		break;
 	case RNBD_OP_FLUSH:
-		bio_opf = REQ_OP_FLUSH | REQ_PREFLUSH;
+		bio_opf = REQ_OP_WRITE | REQ_PREFLUSH;
 		break;
 	case RNBD_OP_DISCARD:
 		bio_opf = REQ_OP_DISCARD;
diff --git a/kernel/drivers/block/sunvdc.c b/kernel/drivers/block/sunvdc.c
index 39aeebc..d9e41d3 100644
--- a/kernel/drivers/block/sunvdc.c
+++ b/kernel/drivers/block/sunvdc.c
@@ -984,6 +984,8 @@
 	print_version();
 
 	hp = mdesc_grab();
+	if (!hp)
+		return -ENODEV;
 
 	err = -ENODEV;
 	if ((vdev->dev_no << PARTITION_SHIFT) & ~(u64)MINORMASK) {
diff --git a/kernel/drivers/block/sx8.c b/kernel/drivers/block/sx8.c
deleted file mode 100644
index 4478eb7..0000000
--- a/kernel/drivers/block/sx8.c
+++ /dev/null
@@ -1,1586 +0,0 @@
-/*
- *  sx8.c: Driver for Promise SATA SX8 looks-like-I2O hardware
- *
- *  Copyright 2004-2005 Red Hat, Inc.
- *
- *  Author/maintainer:  Jeff Garzik <jgarzik@pobox.com>
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file "COPYING" in the main directory of this archive
- *  for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/blk-mq.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/compiler.h>
-#include <linux/workqueue.h>
-#include <linux/bitops.h>
-#include <linux/delay.h>
-#include <linux/ktime.h>
-#include <linux/hdreg.h>
-#include <linux/dma-mapping.h>
-#include <linux/completion.h>
-#include <linux/scatterlist.h>
-#include <asm/io.h>
-#include <linux/uaccess.h>
-
-#if 0
-#define CARM_DEBUG
-#define CARM_VERBOSE_DEBUG
-#else
-#undef CARM_DEBUG
-#undef CARM_VERBOSE_DEBUG
-#endif
-#undef CARM_NDEBUG
-
-#define DRV_NAME "sx8"
-#define DRV_VERSION "1.0"
-#define PFX DRV_NAME ": "
-
-MODULE_AUTHOR("Jeff Garzik");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Promise SATA SX8 block driver");
-MODULE_VERSION(DRV_VERSION);
-
-/*
- * SX8 hardware has a single message queue for all ATA ports.
- * When this driver was written, the hardware (firmware?) would
- * corrupt data eventually, if more than one request was outstanding.
- * As one can imagine, having 8 ports bottlenecking on a single
- * command hurts performance.
- *
- * Based on user reports, later versions of the hardware (firmware?)
- * seem to be able to survive with more than one command queued.
- *
- * Therefore, we default to the safe option -- 1 command -- but
- * allow the user to increase this.
- *
- * SX8 should be able to support up to ~60 queued commands (CARM_MAX_REQ),
- * but problems seem to occur when you exceed ~30, even on newer hardware.
- */
-static int max_queue = 1;
-module_param(max_queue, int, 0444);
-MODULE_PARM_DESC(max_queue, "Maximum number of queued commands. (min==1, max==30, safe==1)");
-
-
-#define NEXT_RESP(idx)	((idx + 1) % RMSG_Q_LEN)
-
-/* 0xf is just arbitrary, non-zero noise; this is sorta like poisoning */
-#define TAG_ENCODE(tag)	(((tag) << 16) | 0xf)
-#define TAG_DECODE(tag)	(((tag) >> 16) & 0x1f)
-#define TAG_VALID(tag)	((((tag) & 0xf) == 0xf) && (TAG_DECODE(tag) < 32))
-
-/* note: prints function name for you */
-#ifdef CARM_DEBUG
-#define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
-#ifdef CARM_VERBOSE_DEBUG
-#define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
-#else
-#define VPRINTK(fmt, args...)
-#endif	/* CARM_VERBOSE_DEBUG */
-#else
-#define DPRINTK(fmt, args...)
-#define VPRINTK(fmt, args...)
-#endif	/* CARM_DEBUG */
-
-#ifdef CARM_NDEBUG
-#define assert(expr)
-#else
-#define assert(expr) \
-        if(unlikely(!(expr))) {                                   \
-        printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \
-	#expr, __FILE__, __func__, __LINE__);          \
-        }
-#endif
-
-/* defines only for the constants which don't work well as enums */
-struct carm_host;
-
-enum {
-	/* adapter-wide limits */
-	CARM_MAX_PORTS		= 8,
-	CARM_SHM_SIZE		= (4096 << 7),
-	CARM_MINORS_PER_MAJOR	= 256 / CARM_MAX_PORTS,
-	CARM_MAX_WAIT_Q		= CARM_MAX_PORTS + 1,
-
-	/* command message queue limits */
-	CARM_MAX_REQ		= 64,	       /* max command msgs per host */
-	CARM_MSG_LOW_WATER	= (CARM_MAX_REQ / 4),	     /* refill mark */
-
-	/* S/G limits, host-wide and per-request */
-	CARM_MAX_REQ_SG		= 32,	     /* max s/g entries per request */
-	CARM_MAX_HOST_SG	= 600,		/* max s/g entries per host */
-	CARM_SG_LOW_WATER	= (CARM_MAX_HOST_SG / 4),   /* re-fill mark */
-
-	/* hardware registers */
-	CARM_IHQP		= 0x1c,
-	CARM_INT_STAT		= 0x10, /* interrupt status */
-	CARM_INT_MASK		= 0x14, /* interrupt mask */
-	CARM_HMUC		= 0x18, /* host message unit control */
-	RBUF_ADDR_LO		= 0x20, /* response msg DMA buf low 32 bits */
-	RBUF_ADDR_HI		= 0x24, /* response msg DMA buf high 32 bits */
-	RBUF_BYTE_SZ		= 0x28,
-	CARM_RESP_IDX		= 0x2c,
-	CARM_CMS0		= 0x30, /* command message size reg 0 */
-	CARM_LMUC		= 0x48,
-	CARM_HMPHA		= 0x6c,
-	CARM_INITC		= 0xb5,
-
-	/* bits in CARM_INT_{STAT,MASK} */
-	INT_RESERVED		= 0xfffffff0,
-	INT_WATCHDOG		= (1 << 3),	/* watchdog timer */
-	INT_Q_OVERFLOW		= (1 << 2),	/* cmd msg q overflow */
-	INT_Q_AVAILABLE		= (1 << 1),	/* cmd msg q has free space */
-	INT_RESPONSE		= (1 << 0),	/* response msg available */
-	INT_ACK_MASK		= INT_WATCHDOG | INT_Q_OVERFLOW,
-	INT_DEF_MASK		= INT_RESERVED | INT_Q_OVERFLOW |
-				  INT_RESPONSE,
-
-	/* command messages, and related register bits */
-	CARM_HAVE_RESP		= 0x01,
-	CARM_MSG_READ		= 1,
-	CARM_MSG_WRITE		= 2,
-	CARM_MSG_VERIFY		= 3,
-	CARM_MSG_GET_CAPACITY	= 4,
-	CARM_MSG_FLUSH		= 5,
-	CARM_MSG_IOCTL		= 6,
-	CARM_MSG_ARRAY		= 8,
-	CARM_MSG_MISC		= 9,
-	CARM_CME		= (1 << 2),
-	CARM_RME		= (1 << 1),
-	CARM_WZBC		= (1 << 0),
-	CARM_RMI		= (1 << 0),
-	CARM_Q_FULL		= (1 << 3),
-	CARM_MSG_SIZE		= 288,
-	CARM_Q_LEN		= 48,
-
-	/* CARM_MSG_IOCTL messages */
-	CARM_IOC_SCAN_CHAN	= 5,	/* scan channels for devices */
-	CARM_IOC_GET_TCQ	= 13,	/* get tcq/ncq depth */
-	CARM_IOC_SET_TCQ	= 14,	/* set tcq/ncq depth */
-
-	IOC_SCAN_CHAN_NODEV	= 0x1f,
-	IOC_SCAN_CHAN_OFFSET	= 0x40,
-
-	/* CARM_MSG_ARRAY messages */
-	CARM_ARRAY_INFO		= 0,
-
-	ARRAY_NO_EXIST		= (1 << 31),
-
-	/* response messages */
-	RMSG_SZ			= 8,	/* sizeof(struct carm_response) */
-	RMSG_Q_LEN		= 48,	/* resp. msg list length */
-	RMSG_OK			= 1,	/* bit indicating msg was successful */
-					/* length of entire resp. msg buffer */
-	RBUF_LEN		= RMSG_SZ * RMSG_Q_LEN,
-
-	PDC_SHM_SIZE		= (4096 << 7), /* length of entire h/w buffer */
-
-	/* CARM_MSG_MISC messages */
-	MISC_GET_FW_VER		= 2,
-	MISC_ALLOC_MEM		= 3,
-	MISC_SET_TIME		= 5,
-
-	/* MISC_GET_FW_VER feature bits */
-	FW_VER_4PORT		= (1 << 2), /* 1=4 ports, 0=8 ports */
-	FW_VER_NON_RAID		= (1 << 1), /* 1=non-RAID firmware, 0=RAID */
-	FW_VER_ZCR		= (1 << 0), /* zero channel RAID (whatever that is) */
-
-	/* carm_host flags */
-	FL_NON_RAID		= FW_VER_NON_RAID,
-	FL_4PORT		= FW_VER_4PORT,
-	FL_FW_VER_MASK		= (FW_VER_NON_RAID | FW_VER_4PORT),
-	FL_DYN_MAJOR		= (1 << 17),
-};
-
-enum {
-	CARM_SG_BOUNDARY	= 0xffffUL,	    /* s/g segment boundary */
-};
-
-enum scatter_gather_types {
-	SGT_32BIT		= 0,
-	SGT_64BIT		= 1,
-};
-
-enum host_states {
-	HST_INVALID,		/* invalid state; never used */
-	HST_ALLOC_BUF,		/* setting up master SHM area */
-	HST_ERROR,		/* we never leave here */
-	HST_PORT_SCAN,		/* start dev scan */
-	HST_DEV_SCAN_START,	/* start per-device probe */
-	HST_DEV_SCAN,		/* continue per-device probe */
-	HST_DEV_ACTIVATE,	/* activate devices we found */
-	HST_PROBE_FINISHED,	/* probe is complete */
-	HST_PROBE_START,	/* initiate probe */
-	HST_SYNC_TIME,		/* tell firmware what time it is */
-	HST_GET_FW_VER,		/* get firmware version, adapter port cnt */
-};
-
-#ifdef CARM_DEBUG
-static const char *state_name[] = {
-	"HST_INVALID",
-	"HST_ALLOC_BUF",
-	"HST_ERROR",
-	"HST_PORT_SCAN",
-	"HST_DEV_SCAN_START",
-	"HST_DEV_SCAN",
-	"HST_DEV_ACTIVATE",
-	"HST_PROBE_FINISHED",
-	"HST_PROBE_START",
-	"HST_SYNC_TIME",
-	"HST_GET_FW_VER",
-};
-#endif
-
-struct carm_port {
-	unsigned int			port_no;
-	struct gendisk			*disk;
-	struct carm_host		*host;
-
-	/* attached device characteristics */
-	u64				capacity;
-	char				name[41];
-	u16				dev_geom_head;
-	u16				dev_geom_sect;
-	u16				dev_geom_cyl;
-};
-
-struct carm_request {
-	int				n_elem;
-	unsigned int			msg_type;
-	unsigned int			msg_subtype;
-	unsigned int			msg_bucket;
-	struct scatterlist		sg[CARM_MAX_REQ_SG];
-};
-
-struct carm_host {
-	unsigned long			flags;
-	void				__iomem *mmio;
-	void				*shm;
-	dma_addr_t			shm_dma;
-
-	int				major;
-	int				id;
-	char				name[32];
-
-	spinlock_t			lock;
-	struct pci_dev			*pdev;
-	unsigned int			state;
-	u32				fw_ver;
-
-	struct blk_mq_tag_set		tag_set;
-	struct request_queue		*oob_q;
-	unsigned int			n_oob;
-
-	unsigned int			hw_sg_used;
-
-	unsigned int			resp_idx;
-
-	unsigned int			wait_q_prod;
-	unsigned int			wait_q_cons;
-	struct request_queue		*wait_q[CARM_MAX_WAIT_Q];
-
-	void				*msg_base;
-	dma_addr_t			msg_dma;
-
-	int				cur_scan_dev;
-	unsigned long			dev_active;
-	unsigned long			dev_present;
-	struct carm_port		port[CARM_MAX_PORTS];
-
-	struct work_struct		fsm_task;
-
-	struct completion		probe_comp;
-};
-
-struct carm_response {
-	__le32 ret_handle;
-	__le32 status;
-}  __attribute__((packed));
-
-struct carm_msg_sg {
-	__le32 start;
-	__le32 len;
-}  __attribute__((packed));
-
-struct carm_msg_rw {
-	u8 type;
-	u8 id;
-	u8 sg_count;
-	u8 sg_type;
-	__le32 handle;
-	__le32 lba;
-	__le16 lba_count;
-	__le16 lba_high;
-	struct carm_msg_sg sg[32];
-}  __attribute__((packed));
-
-struct carm_msg_allocbuf {
-	u8 type;
-	u8 subtype;
-	u8 n_sg;
-	u8 sg_type;
-	__le32 handle;
-	__le32 addr;
-	__le32 len;
-	__le32 evt_pool;
-	__le32 n_evt;
-	__le32 rbuf_pool;
-	__le32 n_rbuf;
-	__le32 msg_pool;
-	__le32 n_msg;
-	struct carm_msg_sg sg[8];
-}  __attribute__((packed));
-
-struct carm_msg_ioctl {
-	u8 type;
-	u8 subtype;
-	u8 array_id;
-	u8 reserved1;
-	__le32 handle;
-	__le32 data_addr;
-	u32 reserved2;
-}  __attribute__((packed));
-
-struct carm_msg_sync_time {
-	u8 type;
-	u8 subtype;
-	u16 reserved1;
-	__le32 handle;
-	u32 reserved2;
-	__le32 timestamp;
-}  __attribute__((packed));
-
-struct carm_msg_get_fw_ver {
-	u8 type;
-	u8 subtype;
-	u16 reserved1;
-	__le32 handle;
-	__le32 data_addr;
-	u32 reserved2;
-}  __attribute__((packed));
-
-struct carm_fw_ver {
-	__le32 version;
-	u8 features;
-	u8 reserved1;
-	u16 reserved2;
-}  __attribute__((packed));
-
-struct carm_array_info {
-	__le32 size;
-
-	__le16 size_hi;
-	__le16 stripe_size;
-
-	__le32 mode;
-
-	__le16 stripe_blk_sz;
-	__le16 reserved1;
-
-	__le16 cyl;
-	__le16 head;
-
-	__le16 sect;
-	u8 array_id;
-	u8 reserved2;
-
-	char name[40];
-
-	__le32 array_status;
-
-	/* device list continues beyond this point? */
-}  __attribute__((packed));
-
-static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-static void carm_remove_one (struct pci_dev *pdev);
-static int carm_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo);
-
-static const struct pci_device_id carm_pci_tbl[] = {
-	{ PCI_VENDOR_ID_PROMISE, 0x8000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
-	{ PCI_VENDOR_ID_PROMISE, 0x8002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
-	{ }	/* terminate list */
-};
-MODULE_DEVICE_TABLE(pci, carm_pci_tbl);
-
-static struct pci_driver carm_driver = {
-	.name		= DRV_NAME,
-	.id_table	= carm_pci_tbl,
-	.probe		= carm_init_one,
-	.remove		= carm_remove_one,
-};
-
-static const struct block_device_operations carm_bd_ops = {
-	.owner		= THIS_MODULE,
-	.getgeo		= carm_bdev_getgeo,
-};
-
-static unsigned int carm_host_id;
-static unsigned long carm_major_alloc;
-
-
-
-static int carm_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo)
-{
-	struct carm_port *port = bdev->bd_disk->private_data;
-
-	geo->heads = (u8) port->dev_geom_head;
-	geo->sectors = (u8) port->dev_geom_sect;
-	geo->cylinders = port->dev_geom_cyl;
-	return 0;
-}
-
-static const u32 msg_sizes[] = { 32, 64, 128, CARM_MSG_SIZE };
-
-static inline int carm_lookup_bucket(u32 msg_size)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(msg_sizes); i++)
-		if (msg_size <= msg_sizes[i])
-			return i;
-
-	return -ENOENT;
-}
-
-static void carm_init_buckets(void __iomem *mmio)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(msg_sizes); i++)
-		writel(msg_sizes[i], mmio + CARM_CMS0 + (4 * i));
-}
-
-static inline void *carm_ref_msg(struct carm_host *host,
-				 unsigned int msg_idx)
-{
-	return host->msg_base + (msg_idx * CARM_MSG_SIZE);
-}
-
-static inline dma_addr_t carm_ref_msg_dma(struct carm_host *host,
-					  unsigned int msg_idx)
-{
-	return host->msg_dma + (msg_idx * CARM_MSG_SIZE);
-}
-
-static int carm_send_msg(struct carm_host *host,
-			 struct carm_request *crq, unsigned tag)
-{
-	void __iomem *mmio = host->mmio;
-	u32 msg = (u32) carm_ref_msg_dma(host, tag);
-	u32 cm_bucket = crq->msg_bucket;
-	u32 tmp;
-	int rc = 0;
-
-	VPRINTK("ENTER\n");
-
-	tmp = readl(mmio + CARM_HMUC);
-	if (tmp & CARM_Q_FULL) {
-#if 0
-		tmp = readl(mmio + CARM_INT_MASK);
-		tmp |= INT_Q_AVAILABLE;
-		writel(tmp, mmio + CARM_INT_MASK);
-		readl(mmio + CARM_INT_MASK);	/* flush */
-#endif
-		DPRINTK("host msg queue full\n");
-		rc = -EBUSY;
-	} else {
-		writel(msg | (cm_bucket << 1), mmio + CARM_IHQP);
-		readl(mmio + CARM_IHQP);	/* flush */
-	}
-
-	return rc;
-}
-
-static int carm_array_info (struct carm_host *host, unsigned int array_idx)
-{
-	struct carm_msg_ioctl *ioc;
-	u32 msg_data;
-	dma_addr_t msg_dma;
-	struct carm_request *crq;
-	struct request *rq;
-	int rc;
-
-	rq = blk_mq_alloc_request(host->oob_q, REQ_OP_DRV_OUT, 0);
-	if (IS_ERR(rq)) {
-		rc = -ENOMEM;
-		goto err_out;
-	}
-	crq = blk_mq_rq_to_pdu(rq);
-
-	ioc = carm_ref_msg(host, rq->tag);
-	msg_dma = carm_ref_msg_dma(host, rq->tag);
-	msg_data = (u32) (msg_dma + sizeof(struct carm_array_info));
-
-	crq->msg_type = CARM_MSG_ARRAY;
-	crq->msg_subtype = CARM_ARRAY_INFO;
-	rc = carm_lookup_bucket(sizeof(struct carm_msg_ioctl) +
-				sizeof(struct carm_array_info));
-	BUG_ON(rc < 0);
-	crq->msg_bucket = (u32) rc;
-
-	memset(ioc, 0, sizeof(*ioc));
-	ioc->type	= CARM_MSG_ARRAY;
-	ioc->subtype	= CARM_ARRAY_INFO;
-	ioc->array_id	= (u8) array_idx;
-	ioc->handle	= cpu_to_le32(TAG_ENCODE(rq->tag));
-	ioc->data_addr	= cpu_to_le32(msg_data);
-
-	spin_lock_irq(&host->lock);
-	assert(host->state == HST_DEV_SCAN_START ||
-	       host->state == HST_DEV_SCAN);
-	spin_unlock_irq(&host->lock);
-
-	DPRINTK("blk_execute_rq_nowait, tag == %u\n", rq->tag);
-	blk_execute_rq_nowait(host->oob_q, NULL, rq, true, NULL);
-
-	return 0;
-
-err_out:
-	spin_lock_irq(&host->lock);
-	host->state = HST_ERROR;
-	spin_unlock_irq(&host->lock);
-	return rc;
-}
-
-typedef unsigned int (*carm_sspc_t)(struct carm_host *, unsigned int, void *);
-
-static int carm_send_special (struct carm_host *host, carm_sspc_t func)
-{
-	struct request *rq;
-	struct carm_request *crq;
-	struct carm_msg_ioctl *ioc;
-	void *mem;
-	unsigned int msg_size;
-	int rc;
-
-	rq = blk_mq_alloc_request(host->oob_q, REQ_OP_DRV_OUT, 0);
-	if (IS_ERR(rq))
-		return -ENOMEM;
-	crq = blk_mq_rq_to_pdu(rq);
-
-	mem = carm_ref_msg(host, rq->tag);
-
-	msg_size = func(host, rq->tag, mem);
-
-	ioc = mem;
-	crq->msg_type = ioc->type;
-	crq->msg_subtype = ioc->subtype;
-	rc = carm_lookup_bucket(msg_size);
-	BUG_ON(rc < 0);
-	crq->msg_bucket = (u32) rc;
-
-	DPRINTK("blk_execute_rq_nowait, tag == %u\n", rq->tag);
-	blk_execute_rq_nowait(host->oob_q, NULL, rq, true, NULL);
-
-	return 0;
-}
-
-static unsigned int carm_fill_sync_time(struct carm_host *host,
-					unsigned int idx, void *mem)
-{
-	struct carm_msg_sync_time *st = mem;
-
-	time64_t tv = ktime_get_real_seconds();
-
-	memset(st, 0, sizeof(*st));
-	st->type	= CARM_MSG_MISC;
-	st->subtype	= MISC_SET_TIME;
-	st->handle	= cpu_to_le32(TAG_ENCODE(idx));
-	st->timestamp	= cpu_to_le32(tv);
-
-	return sizeof(struct carm_msg_sync_time);
-}
-
-static unsigned int carm_fill_alloc_buf(struct carm_host *host,
-					unsigned int idx, void *mem)
-{
-	struct carm_msg_allocbuf *ab = mem;
-
-	memset(ab, 0, sizeof(*ab));
-	ab->type	= CARM_MSG_MISC;
-	ab->subtype	= MISC_ALLOC_MEM;
-	ab->handle	= cpu_to_le32(TAG_ENCODE(idx));
-	ab->n_sg	= 1;
-	ab->sg_type	= SGT_32BIT;
-	ab->addr	= cpu_to_le32(host->shm_dma + (PDC_SHM_SIZE >> 1));
-	ab->len		= cpu_to_le32(PDC_SHM_SIZE >> 1);
-	ab->evt_pool	= cpu_to_le32(host->shm_dma + (16 * 1024));
-	ab->n_evt	= cpu_to_le32(1024);
-	ab->rbuf_pool	= cpu_to_le32(host->shm_dma);
-	ab->n_rbuf	= cpu_to_le32(RMSG_Q_LEN);
-	ab->msg_pool	= cpu_to_le32(host->shm_dma + RBUF_LEN);
-	ab->n_msg	= cpu_to_le32(CARM_Q_LEN);
-	ab->sg[0].start	= cpu_to_le32(host->shm_dma + (PDC_SHM_SIZE >> 1));
-	ab->sg[0].len	= cpu_to_le32(65536);
-
-	return sizeof(struct carm_msg_allocbuf);
-}
-
-static unsigned int carm_fill_scan_channels(struct carm_host *host,
-					    unsigned int idx, void *mem)
-{
-	struct carm_msg_ioctl *ioc = mem;
-	u32 msg_data = (u32) (carm_ref_msg_dma(host, idx) +
-			      IOC_SCAN_CHAN_OFFSET);
-
-	memset(ioc, 0, sizeof(*ioc));
-	ioc->type	= CARM_MSG_IOCTL;
-	ioc->subtype	= CARM_IOC_SCAN_CHAN;
-	ioc->handle	= cpu_to_le32(TAG_ENCODE(idx));
-	ioc->data_addr	= cpu_to_le32(msg_data);
-
-	/* fill output data area with "no device" default values */
-	mem += IOC_SCAN_CHAN_OFFSET;
-	memset(mem, IOC_SCAN_CHAN_NODEV, CARM_MAX_PORTS);
-
-	return IOC_SCAN_CHAN_OFFSET + CARM_MAX_PORTS;
-}
-
-static unsigned int carm_fill_get_fw_ver(struct carm_host *host,
-					 unsigned int idx, void *mem)
-{
-	struct carm_msg_get_fw_ver *ioc = mem;
-	u32 msg_data = (u32) (carm_ref_msg_dma(host, idx) + sizeof(*ioc));
-
-	memset(ioc, 0, sizeof(*ioc));
-	ioc->type	= CARM_MSG_MISC;
-	ioc->subtype	= MISC_GET_FW_VER;
-	ioc->handle	= cpu_to_le32(TAG_ENCODE(idx));
-	ioc->data_addr	= cpu_to_le32(msg_data);
-
-	return sizeof(struct carm_msg_get_fw_ver) +
-	       sizeof(struct carm_fw_ver);
-}
-
-static inline void carm_push_q (struct carm_host *host, struct request_queue *q)
-{
-	unsigned int idx = host->wait_q_prod % CARM_MAX_WAIT_Q;
-
-	blk_mq_stop_hw_queues(q);
-	VPRINTK("STOPPED QUEUE %p\n", q);
-
-	host->wait_q[idx] = q;
-	host->wait_q_prod++;
-	BUG_ON(host->wait_q_prod == host->wait_q_cons); /* overrun */
-}
-
-static inline struct request_queue *carm_pop_q(struct carm_host *host)
-{
-	unsigned int idx;
-
-	if (host->wait_q_prod == host->wait_q_cons)
-		return NULL;
-
-	idx = host->wait_q_cons % CARM_MAX_WAIT_Q;
-	host->wait_q_cons++;
-
-	return host->wait_q[idx];
-}
-
-static inline void carm_round_robin(struct carm_host *host)
-{
-	struct request_queue *q = carm_pop_q(host);
-	if (q) {
-		blk_mq_start_hw_queues(q);
-		VPRINTK("STARTED QUEUE %p\n", q);
-	}
-}
-
-static inline enum dma_data_direction carm_rq_dir(struct request *rq)
-{
-	return op_is_write(req_op(rq)) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
-}
-
-static blk_status_t carm_queue_rq(struct blk_mq_hw_ctx *hctx,
-				  const struct blk_mq_queue_data *bd)
-{
-	struct request_queue *q = hctx->queue;
-	struct request *rq = bd->rq;
-	struct carm_port *port = q->queuedata;
-	struct carm_host *host = port->host;
-	struct carm_request *crq = blk_mq_rq_to_pdu(rq);
-	struct carm_msg_rw *msg;
-	struct scatterlist *sg;
-	int i, n_elem = 0, rc;
-	unsigned int msg_size;
-	u32 tmp;
-
-	crq->n_elem = 0;
-	sg_init_table(crq->sg, CARM_MAX_REQ_SG);
-
-	blk_mq_start_request(rq);
-
-	spin_lock_irq(&host->lock);
-	if (req_op(rq) == REQ_OP_DRV_OUT)
-		goto send_msg;
-
-	/* get scatterlist from block layer */
-	sg = &crq->sg[0];
-	n_elem = blk_rq_map_sg(q, rq, sg);
-	if (n_elem <= 0)
-		goto out_ioerr;
-
-	/* map scatterlist to PCI bus addresses */
-	n_elem = dma_map_sg(&host->pdev->dev, sg, n_elem, carm_rq_dir(rq));
-	if (n_elem <= 0)
-		goto out_ioerr;
-
-	/* obey global hardware limit on S/G entries */
-	if (host->hw_sg_used >= CARM_MAX_HOST_SG - n_elem)
-		goto out_resource;
-
-	crq->n_elem = n_elem;
-	host->hw_sg_used += n_elem;
-
-	/*
-	 * build read/write message
-	 */
-
-	VPRINTK("build msg\n");
-	msg = (struct carm_msg_rw *) carm_ref_msg(host, rq->tag);
-
-	if (rq_data_dir(rq) == WRITE) {
-		msg->type = CARM_MSG_WRITE;
-		crq->msg_type = CARM_MSG_WRITE;
-	} else {
-		msg->type = CARM_MSG_READ;
-		crq->msg_type = CARM_MSG_READ;
-	}
-
-	msg->id		= port->port_no;
-	msg->sg_count	= n_elem;
-	msg->sg_type	= SGT_32BIT;
-	msg->handle	= cpu_to_le32(TAG_ENCODE(rq->tag));
-	msg->lba	= cpu_to_le32(blk_rq_pos(rq) & 0xffffffff);
-	tmp		= (blk_rq_pos(rq) >> 16) >> 16;
-	msg->lba_high	= cpu_to_le16( (u16) tmp );
-	msg->lba_count	= cpu_to_le16(blk_rq_sectors(rq));
-
-	msg_size = sizeof(struct carm_msg_rw) - sizeof(msg->sg);
-	for (i = 0; i < n_elem; i++) {
-		struct carm_msg_sg *carm_sg = &msg->sg[i];
-		carm_sg->start = cpu_to_le32(sg_dma_address(&crq->sg[i]));
-		carm_sg->len = cpu_to_le32(sg_dma_len(&crq->sg[i]));
-		msg_size += sizeof(struct carm_msg_sg);
-	}
-
-	rc = carm_lookup_bucket(msg_size);
-	BUG_ON(rc < 0);
-	crq->msg_bucket = (u32) rc;
-send_msg:
-	/*
-	 * queue read/write message to hardware
-	 */
-	VPRINTK("send msg, tag == %u\n", rq->tag);
-	rc = carm_send_msg(host, crq, rq->tag);
-	if (rc) {
-		host->hw_sg_used -= n_elem;
-		goto out_resource;
-	}
-
-	spin_unlock_irq(&host->lock);
-	return BLK_STS_OK;
-out_resource:
-	dma_unmap_sg(&host->pdev->dev, &crq->sg[0], n_elem, carm_rq_dir(rq));
-	carm_push_q(host, q);
-	spin_unlock_irq(&host->lock);
-	return BLK_STS_DEV_RESOURCE;
-out_ioerr:
-	carm_round_robin(host);
-	spin_unlock_irq(&host->lock);
-	return BLK_STS_IOERR;
-}
-
-static void carm_handle_array_info(struct carm_host *host,
-				   struct carm_request *crq, u8 *mem,
-				   blk_status_t error)
-{
-	struct carm_port *port;
-	u8 *msg_data = mem + sizeof(struct carm_array_info);
-	struct carm_array_info *desc = (struct carm_array_info *) msg_data;
-	u64 lo, hi;
-	int cur_port;
-	size_t slen;
-
-	DPRINTK("ENTER\n");
-
-	if (error)
-		goto out;
-	if (le32_to_cpu(desc->array_status) & ARRAY_NO_EXIST)
-		goto out;
-
-	cur_port = host->cur_scan_dev;
-
-	/* should never occur */
-	if ((cur_port < 0) || (cur_port >= CARM_MAX_PORTS)) {
-		printk(KERN_ERR PFX "BUG: cur_scan_dev==%d, array_id==%d\n",
-		       cur_port, (int) desc->array_id);
-		goto out;
-	}
-
-	port = &host->port[cur_port];
-
-	lo = (u64) le32_to_cpu(desc->size);
-	hi = (u64) le16_to_cpu(desc->size_hi);
-
-	port->capacity = lo | (hi << 32);
-	port->dev_geom_head = le16_to_cpu(desc->head);
-	port->dev_geom_sect = le16_to_cpu(desc->sect);
-	port->dev_geom_cyl = le16_to_cpu(desc->cyl);
-
-	host->dev_active |= (1 << cur_port);
-
-	strncpy(port->name, desc->name, sizeof(port->name));
-	port->name[sizeof(port->name) - 1] = 0;
-	slen = strlen(port->name);
-	while (slen && (port->name[slen - 1] == ' ')) {
-		port->name[slen - 1] = 0;
-		slen--;
-	}
-
-	printk(KERN_INFO DRV_NAME "(%s): port %u device %Lu sectors\n",
-	       pci_name(host->pdev), port->port_no,
-	       (unsigned long long) port->capacity);
-	printk(KERN_INFO DRV_NAME "(%s): port %u device \"%s\"\n",
-	       pci_name(host->pdev), port->port_no, port->name);
-
-out:
-	assert(host->state == HST_DEV_SCAN);
-	schedule_work(&host->fsm_task);
-}
-
-static void carm_handle_scan_chan(struct carm_host *host,
-				  struct carm_request *crq, u8 *mem,
-				  blk_status_t error)
-{
-	u8 *msg_data = mem + IOC_SCAN_CHAN_OFFSET;
-	unsigned int i, dev_count = 0;
-	int new_state = HST_DEV_SCAN_START;
-
-	DPRINTK("ENTER\n");
-
-	if (error) {
-		new_state = HST_ERROR;
-		goto out;
-	}
-
-	/* TODO: scan and support non-disk devices */
-	for (i = 0; i < 8; i++)
-		if (msg_data[i] == 0) { /* direct-access device (disk) */
-			host->dev_present |= (1 << i);
-			dev_count++;
-		}
-
-	printk(KERN_INFO DRV_NAME "(%s): found %u interesting devices\n",
-	       pci_name(host->pdev), dev_count);
-
-out:
-	assert(host->state == HST_PORT_SCAN);
-	host->state = new_state;
-	schedule_work(&host->fsm_task);
-}
-
-static void carm_handle_generic(struct carm_host *host,
-				struct carm_request *crq, blk_status_t error,
-				int cur_state, int next_state)
-{
-	DPRINTK("ENTER\n");
-
-	assert(host->state == cur_state);
-	if (error)
-		host->state = HST_ERROR;
-	else
-		host->state = next_state;
-	schedule_work(&host->fsm_task);
-}
-
-static inline void carm_handle_resp(struct carm_host *host,
-				    __le32 ret_handle_le, u32 status)
-{
-	u32 handle = le32_to_cpu(ret_handle_le);
-	unsigned int msg_idx;
-	struct request *rq;
-	struct carm_request *crq;
-	blk_status_t error = (status == RMSG_OK) ? 0 : BLK_STS_IOERR;
-	u8 *mem;
-
-	VPRINTK("ENTER, handle == 0x%x\n", handle);
-
-	if (unlikely(!TAG_VALID(handle))) {
-		printk(KERN_ERR DRV_NAME "(%s): BUG: invalid tag 0x%x\n",
-		       pci_name(host->pdev), handle);
-		return;
-	}
-
-	msg_idx = TAG_DECODE(handle);
-	VPRINTK("tag == %u\n", msg_idx);
-
-	rq = blk_mq_tag_to_rq(host->tag_set.tags[0], msg_idx);
-	crq = blk_mq_rq_to_pdu(rq);
-
-	/* fast path */
-	if (likely(crq->msg_type == CARM_MSG_READ ||
-		   crq->msg_type == CARM_MSG_WRITE)) {
-		dma_unmap_sg(&host->pdev->dev, &crq->sg[0], crq->n_elem,
-			     carm_rq_dir(rq));
-		goto done;
-	}
-
-	mem = carm_ref_msg(host, msg_idx);
-
-	switch (crq->msg_type) {
-	case CARM_MSG_IOCTL: {
-		switch (crq->msg_subtype) {
-		case CARM_IOC_SCAN_CHAN:
-			carm_handle_scan_chan(host, crq, mem, error);
-			goto done;
-		default:
-			/* unknown / invalid response */
-			goto err_out;
-		}
-		break;
-	}
-
-	case CARM_MSG_MISC: {
-		switch (crq->msg_subtype) {
-		case MISC_ALLOC_MEM:
-			carm_handle_generic(host, crq, error,
-					    HST_ALLOC_BUF, HST_SYNC_TIME);
-			goto done;
-		case MISC_SET_TIME:
-			carm_handle_generic(host, crq, error,
-					    HST_SYNC_TIME, HST_GET_FW_VER);
-			goto done;
-		case MISC_GET_FW_VER: {
-			struct carm_fw_ver *ver = (struct carm_fw_ver *)
-				(mem + sizeof(struct carm_msg_get_fw_ver));
-			if (!error) {
-				host->fw_ver = le32_to_cpu(ver->version);
-				host->flags |= (ver->features & FL_FW_VER_MASK);
-			}
-			carm_handle_generic(host, crq, error,
-					    HST_GET_FW_VER, HST_PORT_SCAN);
-			goto done;
-		}
-		default:
-			/* unknown / invalid response */
-			goto err_out;
-		}
-		break;
-	}
-
-	case CARM_MSG_ARRAY: {
-		switch (crq->msg_subtype) {
-		case CARM_ARRAY_INFO:
-			carm_handle_array_info(host, crq, mem, error);
-			break;
-		default:
-			/* unknown / invalid response */
-			goto err_out;
-		}
-		break;
-	}
-
-	default:
-		/* unknown / invalid response */
-		goto err_out;
-	}
-
-	return;
-
-err_out:
-	printk(KERN_WARNING DRV_NAME "(%s): BUG: unhandled message type %d/%d\n",
-	       pci_name(host->pdev), crq->msg_type, crq->msg_subtype);
-	error = BLK_STS_IOERR;
-done:
-	host->hw_sg_used -= crq->n_elem;
-	blk_mq_end_request(blk_mq_rq_from_pdu(crq), error);
-
-	if (host->hw_sg_used <= CARM_SG_LOW_WATER)
-		carm_round_robin(host);
-}
-
-static inline void carm_handle_responses(struct carm_host *host)
-{
-	void __iomem *mmio = host->mmio;
-	struct carm_response *resp = (struct carm_response *) host->shm;
-	unsigned int work = 0;
-	unsigned int idx = host->resp_idx % RMSG_Q_LEN;
-
-	while (1) {
-		u32 status = le32_to_cpu(resp[idx].status);
-
-		if (status == 0xffffffff) {
-			VPRINTK("ending response on index %u\n", idx);
-			writel(idx << 3, mmio + CARM_RESP_IDX);
-			break;
-		}
-
-		/* response to a message we sent */
-		else if ((status & (1 << 31)) == 0) {
-			VPRINTK("handling msg response on index %u\n", idx);
-			carm_handle_resp(host, resp[idx].ret_handle, status);
-			resp[idx].status = cpu_to_le32(0xffffffff);
-		}
-
-		/* asynchronous events the hardware throws our way */
-		else if ((status & 0xff000000) == (1 << 31)) {
-			u8 *evt_type_ptr = (u8 *) &resp[idx];
-			u8 evt_type = *evt_type_ptr;
-			printk(KERN_WARNING DRV_NAME "(%s): unhandled event type %d\n",
-			       pci_name(host->pdev), (int) evt_type);
-			resp[idx].status = cpu_to_le32(0xffffffff);
-		}
-
-		idx = NEXT_RESP(idx);
-		work++;
-	}
-
-	VPRINTK("EXIT, work==%u\n", work);
-	host->resp_idx += work;
-}
-
-static irqreturn_t carm_interrupt(int irq, void *__host)
-{
-	struct carm_host *host = __host;
-	void __iomem *mmio;
-	u32 mask;
-	int handled = 0;
-	unsigned long flags;
-
-	if (!host) {
-		VPRINTK("no host\n");
-		return IRQ_NONE;
-	}
-
-	spin_lock_irqsave(&host->lock, flags);
-
-	mmio = host->mmio;
-
-	/* reading should also clear interrupts */
-	mask = readl(mmio + CARM_INT_STAT);
-
-	if (mask == 0 || mask == 0xffffffff) {
-		VPRINTK("no work, mask == 0x%x\n", mask);
-		goto out;
-	}
-
-	if (mask & INT_ACK_MASK)
-		writel(mask, mmio + CARM_INT_STAT);
-
-	if (unlikely(host->state == HST_INVALID)) {
-		VPRINTK("not initialized yet, mask = 0x%x\n", mask);
-		goto out;
-	}
-
-	if (mask & CARM_HAVE_RESP) {
-		handled = 1;
-		carm_handle_responses(host);
-	}
-
-out:
-	spin_unlock_irqrestore(&host->lock, flags);
-	VPRINTK("EXIT\n");
-	return IRQ_RETVAL(handled);
-}
-
-static void carm_fsm_task (struct work_struct *work)
-{
-	struct carm_host *host =
-		container_of(work, struct carm_host, fsm_task);
-	unsigned long flags;
-	unsigned int state;
-	int rc, i, next_dev;
-	int reschedule = 0;
-	int new_state = HST_INVALID;
-
-	spin_lock_irqsave(&host->lock, flags);
-	state = host->state;
-	spin_unlock_irqrestore(&host->lock, flags);
-
-	DPRINTK("ENTER, state == %s\n", state_name[state]);
-
-	switch (state) {
-	case HST_PROBE_START:
-		new_state = HST_ALLOC_BUF;
-		reschedule = 1;
-		break;
-
-	case HST_ALLOC_BUF:
-		rc = carm_send_special(host, carm_fill_alloc_buf);
-		if (rc) {
-			new_state = HST_ERROR;
-			reschedule = 1;
-		}
-		break;
-
-	case HST_SYNC_TIME:
-		rc = carm_send_special(host, carm_fill_sync_time);
-		if (rc) {
-			new_state = HST_ERROR;
-			reschedule = 1;
-		}
-		break;
-
-	case HST_GET_FW_VER:
-		rc = carm_send_special(host, carm_fill_get_fw_ver);
-		if (rc) {
-			new_state = HST_ERROR;
-			reschedule = 1;
-		}
-		break;
-
-	case HST_PORT_SCAN:
-		rc = carm_send_special(host, carm_fill_scan_channels);
-		if (rc) {
-			new_state = HST_ERROR;
-			reschedule = 1;
-		}
-		break;
-
-	case HST_DEV_SCAN_START:
-		host->cur_scan_dev = -1;
-		new_state = HST_DEV_SCAN;
-		reschedule = 1;
-		break;
-
-	case HST_DEV_SCAN:
-		next_dev = -1;
-		for (i = host->cur_scan_dev + 1; i < CARM_MAX_PORTS; i++)
-			if (host->dev_present & (1 << i)) {
-				next_dev = i;
-				break;
-			}
-
-		if (next_dev >= 0) {
-			host->cur_scan_dev = next_dev;
-			rc = carm_array_info(host, next_dev);
-			if (rc) {
-				new_state = HST_ERROR;
-				reschedule = 1;
-			}
-		} else {
-			new_state = HST_DEV_ACTIVATE;
-			reschedule = 1;
-		}
-		break;
-
-	case HST_DEV_ACTIVATE: {
-		int activated = 0;
-		for (i = 0; i < CARM_MAX_PORTS; i++)
-			if (host->dev_active & (1 << i)) {
-				struct carm_port *port = &host->port[i];
-				struct gendisk *disk = port->disk;
-
-				set_capacity(disk, port->capacity);
-				add_disk(disk);
-				activated++;
-			}
-
-		printk(KERN_INFO DRV_NAME "(%s): %d ports activated\n",
-		       pci_name(host->pdev), activated);
-
-		new_state = HST_PROBE_FINISHED;
-		reschedule = 1;
-		break;
-	}
-
-	case HST_PROBE_FINISHED:
-		complete(&host->probe_comp);
-		break;
-
-	case HST_ERROR:
-		/* FIXME: TODO */
-		break;
-
-	default:
-		/* should never occur */
-		printk(KERN_ERR PFX "BUG: unknown state %d\n", state);
-		assert(0);
-		break;
-	}
-
-	if (new_state != HST_INVALID) {
-		spin_lock_irqsave(&host->lock, flags);
-		host->state = new_state;
-		spin_unlock_irqrestore(&host->lock, flags);
-	}
-	if (reschedule)
-		schedule_work(&host->fsm_task);
-}
-
-static int carm_init_wait(void __iomem *mmio, u32 bits, unsigned int test_bit)
-{
-	unsigned int i;
-
-	for (i = 0; i < 50000; i++) {
-		u32 tmp = readl(mmio + CARM_LMUC);
-		udelay(100);
-
-		if (test_bit) {
-			if ((tmp & bits) == bits)
-				return 0;
-		} else {
-			if ((tmp & bits) == 0)
-				return 0;
-		}
-
-		cond_resched();
-	}
-
-	printk(KERN_ERR PFX "carm_init_wait timeout, bits == 0x%x, test_bit == %s\n",
-	       bits, test_bit ? "yes" : "no");
-	return -EBUSY;
-}
-
-static void carm_init_responses(struct carm_host *host)
-{
-	void __iomem *mmio = host->mmio;
-	unsigned int i;
-	struct carm_response *resp = (struct carm_response *) host->shm;
-
-	for (i = 0; i < RMSG_Q_LEN; i++)
-		resp[i].status = cpu_to_le32(0xffffffff);
-
-	writel(0, mmio + CARM_RESP_IDX);
-}
-
-static int carm_init_host(struct carm_host *host)
-{
-	void __iomem *mmio = host->mmio;
-	u32 tmp;
-	u8 tmp8;
-	int rc;
-
-	DPRINTK("ENTER\n");
-
-	writel(0, mmio + CARM_INT_MASK);
-
-	tmp8 = readb(mmio + CARM_INITC);
-	if (tmp8 & 0x01) {
-		tmp8 &= ~0x01;
-		writeb(tmp8, mmio + CARM_INITC);
-		readb(mmio + CARM_INITC);	/* flush */
-
-		DPRINTK("snooze...\n");
-		msleep(5000);
-	}
-
-	tmp = readl(mmio + CARM_HMUC);
-	if (tmp & CARM_CME) {
-		DPRINTK("CME bit present, waiting\n");
-		rc = carm_init_wait(mmio, CARM_CME, 1);
-		if (rc) {
-			DPRINTK("EXIT, carm_init_wait 1 failed\n");
-			return rc;
-		}
-	}
-	if (tmp & CARM_RME) {
-		DPRINTK("RME bit present, waiting\n");
-		rc = carm_init_wait(mmio, CARM_RME, 1);
-		if (rc) {
-			DPRINTK("EXIT, carm_init_wait 2 failed\n");
-			return rc;
-		}
-	}
-
-	tmp &= ~(CARM_RME | CARM_CME);
-	writel(tmp, mmio + CARM_HMUC);
-	readl(mmio + CARM_HMUC);	/* flush */
-
-	rc = carm_init_wait(mmio, CARM_RME | CARM_CME, 0);
-	if (rc) {
-		DPRINTK("EXIT, carm_init_wait 3 failed\n");
-		return rc;
-	}
-
-	carm_init_buckets(mmio);
-
-	writel(host->shm_dma & 0xffffffff, mmio + RBUF_ADDR_LO);
-	writel((host->shm_dma >> 16) >> 16, mmio + RBUF_ADDR_HI);
-	writel(RBUF_LEN, mmio + RBUF_BYTE_SZ);
-
-	tmp = readl(mmio + CARM_HMUC);
-	tmp |= (CARM_RME | CARM_CME | CARM_WZBC);
-	writel(tmp, mmio + CARM_HMUC);
-	readl(mmio + CARM_HMUC);	/* flush */
-
-	rc = carm_init_wait(mmio, CARM_RME | CARM_CME, 1);
-	if (rc) {
-		DPRINTK("EXIT, carm_init_wait 4 failed\n");
-		return rc;
-	}
-
-	writel(0, mmio + CARM_HMPHA);
-	writel(INT_DEF_MASK, mmio + CARM_INT_MASK);
-
-	carm_init_responses(host);
-
-	/* start initialization, probing state machine */
-	spin_lock_irq(&host->lock);
-	assert(host->state == HST_INVALID);
-	host->state = HST_PROBE_START;
-	spin_unlock_irq(&host->lock);
-	schedule_work(&host->fsm_task);
-
-	DPRINTK("EXIT\n");
-	return 0;
-}
-
-static const struct blk_mq_ops carm_mq_ops = {
-	.queue_rq	= carm_queue_rq,
-};
-
-static int carm_init_disk(struct carm_host *host, unsigned int port_no)
-{
-	struct carm_port *port = &host->port[port_no];
-	struct gendisk *disk;
-	struct request_queue *q;
-
-	port->host = host;
-	port->port_no = port_no;
-
-	disk = alloc_disk(CARM_MINORS_PER_MAJOR);
-	if (!disk)
-		return -ENOMEM;
-
-	port->disk = disk;
-	sprintf(disk->disk_name, DRV_NAME "/%u",
-		(unsigned int)host->id * CARM_MAX_PORTS + port_no);
-	disk->major = host->major;
-	disk->first_minor = port_no * CARM_MINORS_PER_MAJOR;
-	disk->fops = &carm_bd_ops;
-	disk->private_data = port;
-
-	q = blk_mq_init_queue(&host->tag_set);
-	if (IS_ERR(q))
-		return PTR_ERR(q);
-
-	blk_queue_max_segments(q, CARM_MAX_REQ_SG);
-	blk_queue_segment_boundary(q, CARM_SG_BOUNDARY);
-
-	q->queuedata = port;
-	disk->queue = q;
-	return 0;
-}
-
-static void carm_free_disk(struct carm_host *host, unsigned int port_no)
-{
-	struct carm_port *port = &host->port[port_no];
-	struct gendisk *disk = port->disk;
-
-	if (!disk)
-		return;
-
-	if (disk->flags & GENHD_FL_UP)
-		del_gendisk(disk);
-	if (disk->queue)
-		blk_cleanup_queue(disk->queue);
-	put_disk(disk);
-}
-
-static int carm_init_shm(struct carm_host *host)
-{
-	host->shm = dma_alloc_coherent(&host->pdev->dev, CARM_SHM_SIZE,
-				       &host->shm_dma, GFP_KERNEL);
-	if (!host->shm)
-		return -ENOMEM;
-
-	host->msg_base = host->shm + RBUF_LEN;
-	host->msg_dma = host->shm_dma + RBUF_LEN;
-
-	memset(host->shm, 0xff, RBUF_LEN);
-	memset(host->msg_base, 0, PDC_SHM_SIZE - RBUF_LEN);
-
-	return 0;
-}
-
-static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	struct carm_host *host;
-	int rc;
-	struct request_queue *q;
-	unsigned int i;
-
-	printk_once(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
-
-	rc = pci_enable_device(pdev);
-	if (rc)
-		return rc;
-
-	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc)
-		goto err_out;
-
-	rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
-	if (rc) {
-		printk(KERN_ERR DRV_NAME "(%s): DMA mask failure\n",
-			pci_name(pdev));
-		goto err_out_regions;
-	}
-
-	host = kzalloc(sizeof(*host), GFP_KERNEL);
-	if (!host) {
-		printk(KERN_ERR DRV_NAME "(%s): memory alloc failure\n",
-		       pci_name(pdev));
-		rc = -ENOMEM;
-		goto err_out_regions;
-	}
-
-	host->pdev = pdev;
-	spin_lock_init(&host->lock);
-	INIT_WORK(&host->fsm_task, carm_fsm_task);
-	init_completion(&host->probe_comp);
-
-	host->mmio = ioremap(pci_resource_start(pdev, 0),
-			     pci_resource_len(pdev, 0));
-	if (!host->mmio) {
-		printk(KERN_ERR DRV_NAME "(%s): MMIO alloc failure\n",
-		       pci_name(pdev));
-		rc = -ENOMEM;
-		goto err_out_kfree;
-	}
-
-	rc = carm_init_shm(host);
-	if (rc) {
-		printk(KERN_ERR DRV_NAME "(%s): DMA SHM alloc failure\n",
-		       pci_name(pdev));
-		goto err_out_iounmap;
-	}
-
-	memset(&host->tag_set, 0, sizeof(host->tag_set));
-	host->tag_set.ops = &carm_mq_ops;
-	host->tag_set.cmd_size = sizeof(struct carm_request);
-	host->tag_set.nr_hw_queues = 1;
-	host->tag_set.nr_maps = 1;
-	host->tag_set.queue_depth = max_queue;
-	host->tag_set.numa_node = NUMA_NO_NODE;
-	host->tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
-
-	rc = blk_mq_alloc_tag_set(&host->tag_set);
-	if (rc)
-		goto err_out_dma_free;
-
-	q = blk_mq_init_queue(&host->tag_set);
-	if (IS_ERR(q)) {
-		rc = PTR_ERR(q);
-		blk_mq_free_tag_set(&host->tag_set);
-		goto err_out_dma_free;
-	}
-
-	host->oob_q = q;
-	q->queuedata = host;
-
-	/*
-	 * Figure out which major to use: 160, 161, or dynamic
-	 */
-	if (!test_and_set_bit(0, &carm_major_alloc))
-		host->major = 160;
-	else if (!test_and_set_bit(1, &carm_major_alloc))
-		host->major = 161;
-	else
-		host->flags |= FL_DYN_MAJOR;
-
-	host->id = carm_host_id;
-	sprintf(host->name, DRV_NAME "%d", carm_host_id);
-
-	rc = register_blkdev(host->major, host->name);
-	if (rc < 0)
-		goto err_out_free_majors;
-	if (host->flags & FL_DYN_MAJOR)
-		host->major = rc;
-
-	for (i = 0; i < CARM_MAX_PORTS; i++) {
-		rc = carm_init_disk(host, i);
-		if (rc)
-			goto err_out_blkdev_disks;
-	}
-
-	pci_set_master(pdev);
-
-	rc = request_irq(pdev->irq, carm_interrupt, IRQF_SHARED, DRV_NAME, host);
-	if (rc) {
-		printk(KERN_ERR DRV_NAME "(%s): irq alloc failure\n",
-		       pci_name(pdev));
-		goto err_out_blkdev_disks;
-	}
-
-	rc = carm_init_host(host);
-	if (rc)
-		goto err_out_free_irq;
-
-	DPRINTK("waiting for probe_comp\n");
-	wait_for_completion(&host->probe_comp);
-
-	printk(KERN_INFO "%s: pci %s, ports %d, io %llx, irq %u, major %d\n",
-	       host->name, pci_name(pdev), (int) CARM_MAX_PORTS,
-	       (unsigned long long)pci_resource_start(pdev, 0),
-		   pdev->irq, host->major);
-
-	carm_host_id++;
-	pci_set_drvdata(pdev, host);
-	return 0;
-
-err_out_free_irq:
-	free_irq(pdev->irq, host);
-err_out_blkdev_disks:
-	for (i = 0; i < CARM_MAX_PORTS; i++)
-		carm_free_disk(host, i);
-	unregister_blkdev(host->major, host->name);
-err_out_free_majors:
-	if (host->major == 160)
-		clear_bit(0, &carm_major_alloc);
-	else if (host->major == 161)
-		clear_bit(1, &carm_major_alloc);
-	blk_cleanup_queue(host->oob_q);
-	blk_mq_free_tag_set(&host->tag_set);
-err_out_dma_free:
-	dma_free_coherent(&pdev->dev, CARM_SHM_SIZE, host->shm, host->shm_dma);
-err_out_iounmap:
-	iounmap(host->mmio);
-err_out_kfree:
-	kfree(host);
-err_out_regions:
-	pci_release_regions(pdev);
-err_out:
-	pci_disable_device(pdev);
-	return rc;
-}
-
-static void carm_remove_one (struct pci_dev *pdev)
-{
-	struct carm_host *host = pci_get_drvdata(pdev);
-	unsigned int i;
-
-	if (!host) {
-		printk(KERN_ERR PFX "BUG: no host data for PCI(%s)\n",
-		       pci_name(pdev));
-		return;
-	}
-
-	free_irq(pdev->irq, host);
-	for (i = 0; i < CARM_MAX_PORTS; i++)
-		carm_free_disk(host, i);
-	unregister_blkdev(host->major, host->name);
-	if (host->major == 160)
-		clear_bit(0, &carm_major_alloc);
-	else if (host->major == 161)
-		clear_bit(1, &carm_major_alloc);
-	blk_cleanup_queue(host->oob_q);
-	blk_mq_free_tag_set(&host->tag_set);
-	dma_free_coherent(&pdev->dev, CARM_SHM_SIZE, host->shm, host->shm_dma);
-	iounmap(host->mmio);
-	kfree(host);
-	pci_release_regions(pdev);
-	pci_disable_device(pdev);
-}
-
-module_pci_driver(carm_driver);
diff --git a/kernel/drivers/block/xen-blkfront.c b/kernel/drivers/block/xen-blkfront.c
index 6f33d62..d68a8ca 100644
--- a/kernel/drivers/block/xen-blkfront.c
+++ b/kernel/drivers/block/xen-blkfront.c
@@ -792,7 +792,8 @@
 		ring_req->u.rw.handle = info->handle;
 		ring_req->operation = rq_data_dir(req) ?
 			BLKIF_OP_WRITE : BLKIF_OP_READ;
-		if (req_op(req) == REQ_OP_FLUSH || req->cmd_flags & REQ_FUA) {
+		if (req_op(req) == REQ_OP_FLUSH ||
+		    (req_op(req) == REQ_OP_WRITE && (req->cmd_flags & REQ_FUA))) {
 			/*
 			 * Ideally we can do an unordered flush-to-disk.
 			 * In case the backend onlysupports barriers, use that.
diff --git a/kernel/drivers/bluetooth/btbcm.c b/kernel/drivers/bluetooth/btbcm.c
index d263eac..3fe056c 100644
--- a/kernel/drivers/bluetooth/btbcm.c
+++ b/kernel/drivers/bluetooth/btbcm.c
@@ -6,6 +6,9 @@
  *  Copyright (C) 2015  Intel Corporation
  */
 
+#ifndef __GENKSYMS__	// ANDROID CRC kabi preservation hack due to commit 76dd7893bd10
+#include <linux/efi.h>
+#endif
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <asm/unaligned.h>
@@ -31,6 +34,43 @@
 #define BCM_FW_NAME_COUNT_MAX		2
 /* For kmalloc-ing the fw-name array instead of putting it on the stack */
 typedef char bcm_fw_name[BCM_FW_NAME_LEN];
+
+#ifdef CONFIG_EFI
+static int btbcm_set_bdaddr_from_efi(struct hci_dev *hdev)
+{
+	efi_guid_t guid = EFI_GUID(0x74b00bd9, 0x805a, 0x4d61, 0xb5, 0x1f,
+				   0x43, 0x26, 0x81, 0x23, 0xd1, 0x13);
+	bdaddr_t efi_bdaddr, bdaddr;
+	efi_status_t status;
+	unsigned long len;
+	int ret;
+
+	if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
+		return -EOPNOTSUPP;
+
+	len = sizeof(efi_bdaddr);
+	status = efi.get_variable(L"BDADDR", &guid, NULL, &len, &efi_bdaddr);
+	if (status != EFI_SUCCESS)
+		return -ENXIO;
+
+	if (len != sizeof(efi_bdaddr))
+		return -EIO;
+
+	baswap(&bdaddr, &efi_bdaddr);
+
+	ret = btbcm_set_bdaddr(hdev, &bdaddr);
+	if (ret)
+		return ret;
+
+	bt_dev_info(hdev, "BCM: Using EFI device address (%pMR)", &bdaddr);
+	return 0;
+}
+#else
+static int btbcm_set_bdaddr_from_efi(struct hci_dev *hdev)
+{
+	return -EOPNOTSUPP;
+}
+#endif
 
 int btbcm_check_bdaddr(struct hci_dev *hdev)
 {
@@ -85,9 +125,12 @@
 	    !bacmp(&bda->bdaddr, BDADDR_BCM4345C5) ||
 	    !bacmp(&bda->bdaddr, BDADDR_BCM43430A0) ||
 	    !bacmp(&bda->bdaddr, BDADDR_BCM43341B)) {
-		bt_dev_info(hdev, "BCM: Using default device address (%pMR)",
-			    &bda->bdaddr);
-		set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
+		/* Try falling back to BDADDR EFI variable */
+		if (btbcm_set_bdaddr_from_efi(hdev) != 0) {
+			bt_dev_info(hdev, "BCM: Using default device address (%pMR)",
+				    &bda->bdaddr);
+			set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
+		}
 	}
 
 	kfree_skb(skb);
diff --git a/kernel/drivers/bluetooth/btqcomsmd.c b/kernel/drivers/bluetooth/btqcomsmd.c
index 2acb719..11c7e04 100644
--- a/kernel/drivers/bluetooth/btqcomsmd.c
+++ b/kernel/drivers/bluetooth/btqcomsmd.c
@@ -122,6 +122,21 @@
 	return 0;
 }
 
+static int btqcomsmd_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+	int ret;
+
+	ret = qca_set_bdaddr_rome(hdev, bdaddr);
+	if (ret)
+		return ret;
+
+	/* The firmware stops responding for a while after setting the bdaddr,
+	 * causing timeouts for subsequent commands. Sleep a bit to avoid this.
+	 */
+	usleep_range(1000, 10000);
+	return 0;
+}
+
 static int btqcomsmd_probe(struct platform_device *pdev)
 {
 	struct btqcomsmd *btq;
@@ -162,7 +177,7 @@
 	hdev->close = btqcomsmd_close;
 	hdev->send = btqcomsmd_send;
 	hdev->setup = btqcomsmd_setup;
-	hdev->set_bdaddr = qca_set_bdaddr_rome;
+	hdev->set_bdaddr = btqcomsmd_set_bdaddr;
 
 	ret = hci_register_dev(hdev);
 	if (ret < 0)
diff --git a/kernel/drivers/bluetooth/btsdio.c b/kernel/drivers/bluetooth/btsdio.c
index 199e8f7..2e4ac39 100644
--- a/kernel/drivers/bluetooth/btsdio.c
+++ b/kernel/drivers/bluetooth/btsdio.c
@@ -355,6 +355,7 @@
 	if (!data)
 		return;
 
+	cancel_work_sync(&data->work);
 	hdev = data->hdev;
 
 	sdio_set_drvdata(func, NULL);
diff --git a/kernel/drivers/bluetooth/btusb.c b/kernel/drivers/bluetooth/btusb.c
index 54001ad..f99d190 100644
--- a/kernel/drivers/bluetooth/btusb.c
+++ b/kernel/drivers/bluetooth/btusb.c
@@ -393,6 +393,10 @@
 	{ USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01),
 	  .driver_info = BTUSB_IGNORE },
 
+	/* Realtek 8821CE Bluetooth devices */
+	{ USB_DEVICE(0x13d3, 0x3529), .driver_info = BTUSB_REALTEK |
+						     BTUSB_WIDEBAND_SPEECH },
+
 	/* Realtek 8822CE Bluetooth devices */
 	{ USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK |
 						     BTUSB_WIDEBAND_SPEECH },
@@ -426,6 +430,9 @@
 						     BTUSB_WIDEBAND_SPEECH |
 						     BTUSB_VALID_LE_STATES },
 	{ USB_DEVICE(0x0489, 0xe0d9), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x0489, 0xe0f5), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH |
 						     BTUSB_VALID_LE_STATES },
 	{ USB_DEVICE(0x13d3, 0x3568), .driver_info = BTUSB_MEDIATEK |
@@ -661,13 +668,13 @@
 
 	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);
@@ -1682,7 +1689,7 @@
 		 * alternate setting.
 		 */
 		spin_lock_irqsave(&data->rxlock, flags);
-		kfree_skb(data->sco_skb);
+		dev_kfree_skb_irq(data->sco_skb);
 		data->sco_skb = NULL;
 		spin_unlock_irqrestore(&data->rxlock, flags);
 
diff --git a/kernel/drivers/bluetooth/hci_bcsp.c b/kernel/drivers/bluetooth/hci_bcsp.c
index cf4a560..8055f63 100644
--- a/kernel/drivers/bluetooth/hci_bcsp.c
+++ b/kernel/drivers/bluetooth/hci_bcsp.c
@@ -378,7 +378,7 @@
 		i++;
 
 		__skb_unlink(skb, &bcsp->unack);
-		kfree_skb(skb);
+		dev_kfree_skb_irq(skb);
 	}
 
 	if (skb_queue_empty(&bcsp->unack))
diff --git a/kernel/drivers/bluetooth/hci_h5.c b/kernel/drivers/bluetooth/hci_h5.c
index 996729e..7f70a67 100644
--- a/kernel/drivers/bluetooth/hci_h5.c
+++ b/kernel/drivers/bluetooth/hci_h5.c
@@ -299,7 +299,7 @@
 			break;
 
 		__skb_unlink(skb, &h5->unack);
-		kfree_skb(skb);
+		dev_kfree_skb_irq(skb);
 	}
 
 	if (skb_queue_empty(&h5->unack))
diff --git a/kernel/drivers/bluetooth/hci_ll.c b/kernel/drivers/bluetooth/hci_ll.c
index 8bfe024..7495ca3 100644
--- a/kernel/drivers/bluetooth/hci_ll.c
+++ b/kernel/drivers/bluetooth/hci_ll.c
@@ -345,7 +345,7 @@
 	default:
 		BT_ERR("illegal hcill state: %ld (losing packet)",
 		       ll->hcill_state);
-		kfree_skb(skb);
+		dev_kfree_skb_irq(skb);
 		break;
 	}
 
diff --git a/kernel/drivers/bluetooth/hci_nokia.c b/kernel/drivers/bluetooth/hci_nokia.c
index 05f7f6d..97da0b2 100644
--- a/kernel/drivers/bluetooth/hci_nokia.c
+++ b/kernel/drivers/bluetooth/hci_nokia.c
@@ -734,7 +734,11 @@
 		return err;
 	}
 
-	clk_prepare_enable(sysclk);
+	err = clk_prepare_enable(sysclk);
+	if (err) {
+		dev_err(dev, "could not enable sysclk: %d", err);
+		return err;
+	}
 	btdev->sysclk_speed = clk_get_rate(sysclk);
 	clk_disable_unprepare(sysclk);
 
diff --git a/kernel/drivers/bluetooth/hci_qca.c b/kernel/drivers/bluetooth/hci_qca.c
index eea18ae..bc0850d 100644
--- a/kernel/drivers/bluetooth/hci_qca.c
+++ b/kernel/drivers/bluetooth/hci_qca.c
@@ -50,6 +50,9 @@
 #define IBS_HOST_TX_IDLE_TIMEOUT_MS	2000
 #define CMD_TRANS_TIMEOUT_MS		100
 #define MEMDUMP_TIMEOUT_MS		8000
+#define IBS_DISABLE_SSR_TIMEOUT_MS \
+	(MEMDUMP_TIMEOUT_MS + FW_DOWNLOAD_TIMEOUT_MS)
+#define FW_DOWNLOAD_TIMEOUT_MS		3000
 
 /* susclk rate */
 #define SUSCLK_RATE_32KHZ	32768
@@ -68,12 +71,15 @@
 #define QCA_MEMDUMP_BYTE		0xFB
 
 enum qca_flags {
-	QCA_IBS_ENABLED,
+	QCA_IBS_DISABLED,
 	QCA_DROP_VENDOR_EVENT,
 	QCA_SUSPENDING,
 	QCA_MEMDUMP_COLLECTION,
 	QCA_HW_ERROR_EVENT,
-	QCA_SSR_TRIGGERED
+	QCA_SSR_TRIGGERED,
+	QCA_BT_OFF,
+	QCA_ROM_FW,
+	QCA_DEBUGFS_CREATED,
 };
 
 enum qca_capabilities {
@@ -628,6 +634,9 @@
 	if (!hdev->debugfs)
 		return;
 
+	if (test_and_set_bit(QCA_DEBUGFS_CREATED, &qca->flags))
+		return;
+
 	ibs_dir = debugfs_create_dir("ibs", hdev->debugfs);
 
 	/* read only */
@@ -870,7 +879,7 @@
 	 * Out-Of-Band(GPIOs control) sleep is selected.
 	 * Don't wake the device up when suspending.
 	 */
-	if (!test_bit(QCA_IBS_ENABLED, &qca->flags) ||
+	if (test_bit(QCA_IBS_DISABLED, &qca->flags) ||
 	    test_bit(QCA_SUSPENDING, &qca->flags)) {
 		skb_queue_tail(&qca->txq, skb);
 		spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
@@ -905,7 +914,7 @@
 	default:
 		BT_ERR("Illegal tx state: %d (losing packet)",
 		       qca->tx_ibs_state);
-		kfree_skb(skb);
+		dev_kfree_skb_irq(skb);
 		break;
 	}
 
@@ -1015,7 +1024,7 @@
 			 * the controller to send the dump is 8 seconds. let us
 			 * start timer to handle this asynchronous activity.
 			 */
-			clear_bit(QCA_IBS_ENABLED, &qca->flags);
+			set_bit(QCA_IBS_DISABLED, &qca->flags);
 			set_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
 			dump = (void *) skb->data;
 			dump_size = __le32_to_cpu(dump->dump_size);
@@ -1621,6 +1630,7 @@
 	struct hci_uart *hu = hci_get_drvdata(hdev);
 	enum qca_btsoc_type soc_type = qca_soc_type(hu);
 	struct qca_serdev *qcadev;
+	struct qca_data *qca = hu->priv;
 	int ret = 0;
 
 	/* Non-serdev device usually is powered by external power
@@ -1640,6 +1650,7 @@
 		}
 	}
 
+	clear_bit(QCA_BT_OFF, &qca->flags);
 	return ret;
 }
 
@@ -1658,8 +1669,9 @@
 	if (ret)
 		return ret;
 
+	clear_bit(QCA_ROM_FW, &qca->flags);
 	/* Patch downloading has to be done without IBS mode */
-	clear_bit(QCA_IBS_ENABLED, &qca->flags);
+	set_bit(QCA_IBS_DISABLED, &qca->flags);
 
 	/* Enable controller to do both LE scan and BR/EDR inquiry
 	 * simultaneously.
@@ -1710,18 +1722,20 @@
 	ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver,
 			firmware_name);
 	if (!ret) {
-		set_bit(QCA_IBS_ENABLED, &qca->flags);
+		clear_bit(QCA_IBS_DISABLED, &qca->flags);
 		qca_debugfs_init(hdev);
 		hu->hdev->hw_error = qca_hw_error;
 		hu->hdev->cmd_timeout = qca_cmd_timeout;
 	} else if (ret == -ENOENT) {
 		/* No patch/nvm-config found, run with original fw/config */
+		set_bit(QCA_ROM_FW, &qca->flags);
 		ret = 0;
 	} else if (ret == -EAGAIN) {
 		/*
 		 * Userspace firmware loader will return -EAGAIN in case no
 		 * patch/nvm-config is found, so run with original fw/config.
 		 */
+		set_bit(QCA_ROM_FW, &qca->flags);
 		ret = 0;
 	} else {
 		if (retries < MAX_INIT_RETRIES) {
@@ -1814,7 +1828,7 @@
 	 * data in skb's.
 	 */
 	spin_lock_irqsave(&qca->hci_ibs_lock, flags);
-	clear_bit(QCA_IBS_ENABLED, &qca->flags);
+	set_bit(QCA_IBS_DISABLED, &qca->flags);
 	qca_flush(hu);
 	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
 
@@ -1833,6 +1847,8 @@
 	} else if (qcadev->bt_en) {
 		gpiod_set_value_cansleep(qcadev->bt_en, 0);
 	}
+
+	set_bit(QCA_BT_OFF, &qca->flags);
 }
 
 static int qca_power_off(struct hci_dev *hdev)
@@ -2057,10 +2073,17 @@
 	int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS);
 	struct serdev_device *serdev = to_serdev_device(dev);
 	struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
+	struct hci_uart *hu = &qcadev->serdev_hu;
+	struct hci_dev *hdev = hu->hdev;
+	struct qca_data *qca = hu->priv;
 	const u8 ibs_wake_cmd[] = { 0xFD };
 	const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 };
 
 	if (qcadev->btsoc_type == QCA_QCA6390) {
+		if (test_bit(QCA_BT_OFF, &qca->flags) ||
+		    !test_bit(HCI_RUNNING, &hdev->flags))
+			return;
+
 		serdev_device_write_flush(serdev);
 		ret = serdev_device_write_buf(serdev, ibs_wake_cmd,
 					      sizeof(ibs_wake_cmd));
@@ -2093,13 +2116,44 @@
 	bool tx_pending = false;
 	int ret = 0;
 	u8 cmd;
+	u32 wait_timeout = 0;
 
 	set_bit(QCA_SUSPENDING, &qca->flags);
 
-	/* Device is downloading patch or doesn't support in-band sleep. */
-	if (!test_bit(QCA_IBS_ENABLED, &qca->flags))
+	/* if BT SoC is running with default firmware then it does not
+	 * support in-band sleep
+	 */
+	if (test_bit(QCA_ROM_FW, &qca->flags))
 		return 0;
 
+	/* During SSR after memory dump collection, controller will be
+	 * powered off and then powered on.If controller is powered off
+	 * during SSR then we should wait until SSR is completed.
+	 */
+	if (test_bit(QCA_BT_OFF, &qca->flags) &&
+	    !test_bit(QCA_SSR_TRIGGERED, &qca->flags))
+		return 0;
+
+	if (test_bit(QCA_IBS_DISABLED, &qca->flags) ||
+	    test_bit(QCA_SSR_TRIGGERED, &qca->flags)) {
+		wait_timeout = test_bit(QCA_SSR_TRIGGERED, &qca->flags) ?
+					IBS_DISABLE_SSR_TIMEOUT_MS :
+					FW_DOWNLOAD_TIMEOUT_MS;
+
+		/* QCA_IBS_DISABLED flag is set to true, During FW download
+		 * and during memory dump collection. It is reset to false,
+		 * After FW download complete.
+		 */
+		wait_on_bit_timeout(&qca->flags, QCA_IBS_DISABLED,
+			    TASK_UNINTERRUPTIBLE, msecs_to_jiffies(wait_timeout));
+
+		if (test_bit(QCA_IBS_DISABLED, &qca->flags)) {
+			bt_dev_err(hu->hdev, "SSR or FW download time out");
+			ret = -ETIMEDOUT;
+			goto error;
+		}
+	}
+
 	cancel_work_sync(&qca->ws_awake_device);
 	cancel_work_sync(&qca->ws_awake_rx);
 
diff --git a/kernel/drivers/bus/Makefile b/kernel/drivers/bus/Makefile
index 397e353..16c47a0 100644
--- a/kernel/drivers/bus/Makefile
+++ b/kernel/drivers/bus/Makefile
@@ -38,4 +38,4 @@
 obj-$(CONFIG_DA8XX_MSTPRI)	+= da8xx-mstpri.o
 
 # MHI
-obj-$(CONFIG_MHI_BUS)		+= mhi/
+obj-y				+= mhi/
diff --git a/kernel/drivers/bus/imx-weim.c b/kernel/drivers/bus/imx-weim.c
index 28bb65a..2017678 100644
--- a/kernel/drivers/bus/imx-weim.c
+++ b/kernel/drivers/bus/imx-weim.c
@@ -192,8 +192,8 @@
 	const struct of_device_id *of_id = of_match_device(weim_id_table,
 							   &pdev->dev);
 	const struct imx_weim_devtype *devtype = of_id->data;
+	int ret = 0, have_child = 0;
 	struct device_node *child;
-	int ret, have_child = 0;
 	struct cs_timing_state ts = {};
 	u32 reg;
 
diff --git a/kernel/drivers/bus/mhi/Kconfig b/kernel/drivers/bus/mhi/Kconfig
index e841c10..4748df7 100644
--- a/kernel/drivers/bus/mhi/Kconfig
+++ b/kernel/drivers/bus/mhi/Kconfig
@@ -2,21 +2,7 @@
 #
 # MHI bus
 #
-# Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+# Copyright (c) 2021, Linaro Ltd.
 #
 
-config MHI_BUS
-	tristate "Modem Host Interface (MHI) bus"
-	help
-	  Bus driver for MHI protocol. Modem Host Interface (MHI) is a
-	  communication protocol used by the host processors to control
-	  and communicate with modem devices over a high speed peripheral
-	  bus or shared memory.
-
-config MHI_BUS_DEBUG
-	bool "Debugfs support for the MHI bus"
-	depends on MHI_BUS && DEBUG_FS
-	help
-	  Enable debugfs support for use with the MHI transport. Allows
-	  reading and/or modifying some values within the MHI controller
-	  for debug and test purposes.
+source "drivers/bus/mhi/host/Kconfig"
diff --git a/kernel/drivers/bus/mhi/Makefile b/kernel/drivers/bus/mhi/Makefile
index 19e6443..5f5708a 100644
--- a/kernel/drivers/bus/mhi/Makefile
+++ b/kernel/drivers/bus/mhi/Makefile
@@ -1,2 +1,2 @@
-# core layer
-obj-y += core/
+# Host MHI stack
+obj-y += host/
diff --git a/kernel/drivers/bus/mhi/core/Makefile b/kernel/drivers/bus/mhi/core/Makefile
deleted file mode 100644
index c3feb41..0000000
--- a/kernel/drivers/bus/mhi/core/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-obj-$(CONFIG_MHI_BUS) += mhi.o
-
-mhi-y := init.o main.o pm.o boot.o
-mhi-$(CONFIG_MHI_BUS_DEBUG) += debugfs.o
diff --git a/kernel/drivers/bus/mhi/host/Kconfig b/kernel/drivers/bus/mhi/host/Kconfig
new file mode 100644
index 0000000..da5cd0c
--- /dev/null
+++ b/kernel/drivers/bus/mhi/host/Kconfig
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# MHI bus
+#
+# Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+#
+
+config MHI_BUS
+	tristate "Modem Host Interface (MHI) bus"
+	help
+	  Bus driver for MHI protocol. Modem Host Interface (MHI) is a
+	  communication protocol used by the host processors to control
+	  and communicate with modem devices over a high speed peripheral
+	  bus or shared memory.
+
+config MHI_BUS_DEBUG
+	bool "Debugfs support for the MHI bus"
+	depends on MHI_BUS && DEBUG_FS
+	help
+	  Enable debugfs support for use with the MHI transport. Allows
+	  reading and/or modifying some values within the MHI controller
+	  for debug and test purposes.
+
+config MHI_BUS_PCI_GENERIC
+	tristate "MHI PCI controller driver"
+	depends on MHI_BUS
+	depends on PCI
+	help
+	  This driver provides MHI PCI controller driver for devices such as
+	  Qualcomm SDX55 based PCIe modems.
+
diff --git a/kernel/drivers/bus/mhi/host/Makefile b/kernel/drivers/bus/mhi/host/Makefile
new file mode 100644
index 0000000..859c2f3
--- /dev/null
+++ b/kernel/drivers/bus/mhi/host/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_MHI_BUS) += mhi.o
+mhi-y := init.o main.o pm.o boot.o
+mhi-$(CONFIG_MHI_BUS_DEBUG) += debugfs.o
+
+obj-$(CONFIG_MHI_BUS_PCI_GENERIC) += mhi_pci_generic.o
+mhi_pci_generic-y += pci_generic.o
diff --git a/kernel/drivers/bus/mhi/core/boot.c b/kernel/drivers/bus/mhi/host/boot.c
similarity index 100%
rename from kernel/drivers/bus/mhi/core/boot.c
rename to kernel/drivers/bus/mhi/host/boot.c
diff --git a/kernel/drivers/bus/mhi/core/debugfs.c b/kernel/drivers/bus/mhi/host/debugfs.c
similarity index 100%
rename from kernel/drivers/bus/mhi/core/debugfs.c
rename to kernel/drivers/bus/mhi/host/debugfs.c
diff --git a/kernel/drivers/bus/mhi/core/init.c b/kernel/drivers/bus/mhi/host/init.c
similarity index 98%
rename from kernel/drivers/bus/mhi/core/init.c
rename to kernel/drivers/bus/mhi/host/init.c
index 0d0386f..2cc48f9 100644
--- a/kernel/drivers/bus/mhi/core/init.c
+++ b/kernel/drivers/bus/mhi/host/init.c
@@ -498,6 +498,12 @@
 		return -EIO;
 	}
 
+	if (val >= mhi_cntrl->reg_len - (8 * MHI_DEV_WAKE_DB)) {
+		dev_err(dev, "CHDB offset: 0x%x is out of range: 0x%zx\n",
+			val, mhi_cntrl->reg_len - (8 * MHI_DEV_WAKE_DB));
+		return -ERANGE;
+	}
+
 	/* Setup wake db */
 	mhi_cntrl->wake_db = base + val + (8 * MHI_DEV_WAKE_DB);
 	mhi_write_reg(mhi_cntrl, mhi_cntrl->wake_db, 4, 0);
@@ -517,6 +523,12 @@
 		return -EIO;
 	}
 
+	if (val >= mhi_cntrl->reg_len - (8 * mhi_cntrl->total_ev_rings)) {
+		dev_err(dev, "ERDB offset: 0x%x is out of range: 0x%zx\n",
+			val, mhi_cntrl->reg_len - (8 * mhi_cntrl->total_ev_rings));
+		return -ERANGE;
+	}
+
 	/* Setup event db address for each ev_ring */
 	mhi_event = mhi_cntrl->mhi_event;
 	for (i = 0; i < mhi_cntrl->total_ev_rings; i++, val += 8, mhi_event++) {
diff --git a/kernel/drivers/bus/mhi/core/internal.h b/kernel/drivers/bus/mhi/host/internal.h
similarity index 100%
rename from kernel/drivers/bus/mhi/core/internal.h
rename to kernel/drivers/bus/mhi/host/internal.h
diff --git a/kernel/drivers/bus/mhi/core/main.c b/kernel/drivers/bus/mhi/host/main.c
similarity index 100%
rename from kernel/drivers/bus/mhi/core/main.c
rename to kernel/drivers/bus/mhi/host/main.c
diff --git a/kernel/drivers/bus/mhi/host/pci_generic.c b/kernel/drivers/bus/mhi/host/pci_generic.c
new file mode 100644
index 0000000..f5bee76
--- /dev/null
+++ b/kernel/drivers/bus/mhi/host/pci_generic.c
@@ -0,0 +1,345 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * MHI PCI driver - MHI over PCI controller driver
+ *
+ * This module is a generic driver for registering MHI-over-PCI devices,
+ * such as PCIe QCOM modems.
+ *
+ * Copyright (C) 2020 Linaro Ltd <loic.poulain@linaro.org>
+ */
+
+#include <linux/device.h>
+#include <linux/mhi.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#define MHI_PCI_DEFAULT_BAR_NUM 0
+
+/**
+ * struct mhi_pci_dev_info - MHI PCI device specific information
+ * @config: MHI controller configuration
+ * @name: name of the PCI module
+ * @fw: firmware path (if any)
+ * @edl: emergency download mode firmware path (if any)
+ * @bar_num: PCI base address register to use for MHI MMIO register space
+ * @dma_data_width: DMA transfer word size (32 or 64 bits)
+ */
+struct mhi_pci_dev_info {
+	const struct mhi_controller_config *config;
+	const char *name;
+	const char *fw;
+	const char *edl;
+	unsigned int bar_num;
+	unsigned int dma_data_width;
+};
+
+#define MHI_CHANNEL_CONFIG_UL(ch_num, ch_name, el_count, ev_ring) \
+	{						\
+		.num = ch_num,				\
+		.name = ch_name,			\
+		.num_elements = el_count,		\
+		.event_ring = ev_ring,			\
+		.dir = DMA_TO_DEVICE,			\
+		.ee_mask = BIT(MHI_EE_AMSS),		\
+		.pollcfg = 0,				\
+		.doorbell = MHI_DB_BRST_DISABLE,	\
+		.lpm_notify = false,			\
+		.offload_channel = false,		\
+		.doorbell_mode_switch = false,		\
+	}						\
+
+#define MHI_CHANNEL_CONFIG_DL(ch_num, ch_name, el_count, ev_ring) \
+	{						\
+		.num = ch_num,				\
+		.name = ch_name,			\
+		.num_elements = el_count,		\
+		.event_ring = ev_ring,			\
+		.dir = DMA_FROM_DEVICE,			\
+		.ee_mask = BIT(MHI_EE_AMSS),		\
+		.pollcfg = 0,				\
+		.doorbell = MHI_DB_BRST_DISABLE,	\
+		.lpm_notify = false,			\
+		.offload_channel = false,		\
+		.doorbell_mode_switch = false,		\
+	}
+
+#define MHI_EVENT_CONFIG_CTRL(ev_ring)		\
+	{					\
+		.num_elements = 64,		\
+		.irq_moderation_ms = 0,		\
+		.irq = (ev_ring) + 1,		\
+		.priority = 1,			\
+		.mode = MHI_DB_BRST_DISABLE,	\
+		.data_type = MHI_ER_CTRL,	\
+		.hardware_event = false,	\
+		.client_managed = false,	\
+		.offload_channel = false,	\
+	}
+
+#define MHI_EVENT_CONFIG_DATA(ev_ring)		\
+	{					\
+		.num_elements = 128,		\
+		.irq_moderation_ms = 5,		\
+		.irq = (ev_ring) + 1,		\
+		.priority = 1,			\
+		.mode = MHI_DB_BRST_DISABLE,	\
+		.data_type = MHI_ER_DATA,	\
+		.hardware_event = false,	\
+		.client_managed = false,	\
+		.offload_channel = false,	\
+	}
+
+#define MHI_EVENT_CONFIG_HW_DATA(ev_ring, ch_num) \
+	{					\
+		.num_elements = 128,		\
+		.irq_moderation_ms = 5,		\
+		.irq = (ev_ring) + 1,		\
+		.priority = 1,			\
+		.mode = MHI_DB_BRST_DISABLE,	\
+		.data_type = MHI_ER_DATA,	\
+		.hardware_event = true,		\
+		.client_managed = false,	\
+		.offload_channel = false,	\
+		.channel = ch_num,		\
+	}
+
+static const struct mhi_channel_config modem_qcom_v1_mhi_channels[] = {
+	MHI_CHANNEL_CONFIG_UL(12, "MBIM", 4, 0),
+	MHI_CHANNEL_CONFIG_DL(13, "MBIM", 4, 0),
+	MHI_CHANNEL_CONFIG_UL(14, "QMI", 4, 0),
+	MHI_CHANNEL_CONFIG_DL(15, "QMI", 4, 0),
+	MHI_CHANNEL_CONFIG_UL(20, "IPCR", 8, 0),
+	MHI_CHANNEL_CONFIG_DL(21, "IPCR", 8, 0),
+	MHI_CHANNEL_CONFIG_UL(100, "IP_HW0", 128, 1),
+	MHI_CHANNEL_CONFIG_DL(101, "IP_HW0", 128, 2),
+};
+
+static const struct mhi_event_config modem_qcom_v1_mhi_events[] = {
+	/* first ring is control+data ring */
+	MHI_EVENT_CONFIG_CTRL(0),
+	/* Hardware channels request dedicated hardware event rings */
+	MHI_EVENT_CONFIG_HW_DATA(1, 100),
+	MHI_EVENT_CONFIG_HW_DATA(2, 101)
+};
+
+static const struct mhi_controller_config modem_qcom_v1_mhiv_config = {
+	.max_channels = 128,
+	.timeout_ms = 5000,
+	.num_channels = ARRAY_SIZE(modem_qcom_v1_mhi_channels),
+	.ch_cfg = modem_qcom_v1_mhi_channels,
+	.num_events = ARRAY_SIZE(modem_qcom_v1_mhi_events),
+	.event_cfg = modem_qcom_v1_mhi_events,
+};
+
+static const struct mhi_pci_dev_info mhi_qcom_sdx55_info = {
+	.name = "qcom-sdx55m",
+	.fw = "qcom/sdx55m/sbl1.mbn",
+	.edl = "qcom/sdx55m/edl.mbn",
+	.config = &modem_qcom_v1_mhiv_config,
+	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
+	.dma_data_width = 32
+};
+
+static const struct pci_device_id mhi_pci_id_table[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0306),
+		.driver_data = (kernel_ulong_t) &mhi_qcom_sdx55_info },
+	{  }
+};
+MODULE_DEVICE_TABLE(pci, mhi_pci_id_table);
+
+static int mhi_pci_read_reg(struct mhi_controller *mhi_cntrl,
+			    void __iomem *addr, u32 *out)
+{
+	*out = readl(addr);
+	return 0;
+}
+
+static void mhi_pci_write_reg(struct mhi_controller *mhi_cntrl,
+			      void __iomem *addr, u32 val)
+{
+	writel(val, addr);
+}
+
+static void mhi_pci_status_cb(struct mhi_controller *mhi_cntrl,
+			      enum mhi_callback cb)
+{
+	/* Nothing to do for now */
+}
+
+static int mhi_pci_claim(struct mhi_controller *mhi_cntrl,
+			 unsigned int bar_num, u64 dma_mask)
+{
+	struct pci_dev *pdev = to_pci_dev(mhi_cntrl->cntrl_dev);
+	int err;
+
+	err = pci_assign_resource(pdev, bar_num);
+	if (err)
+		return err;
+
+	err = pcim_enable_device(pdev);
+	if (err) {
+		dev_err(&pdev->dev, "failed to enable pci device: %d\n", err);
+		return err;
+	}
+
+	err = pcim_iomap_regions(pdev, 1 << bar_num, pci_name(pdev));
+	if (err) {
+		dev_err(&pdev->dev, "failed to map pci region: %d\n", err);
+		return err;
+	}
+	mhi_cntrl->regs = pcim_iomap_table(pdev)[bar_num];
+
+	err = pci_set_dma_mask(pdev, dma_mask);
+	if (err) {
+		dev_err(&pdev->dev, "Cannot set proper DMA mask\n");
+		return err;
+	}
+
+	err = pci_set_consistent_dma_mask(pdev, dma_mask);
+	if (err) {
+		dev_err(&pdev->dev, "set consistent dma mask failed\n");
+		return err;
+	}
+
+	pci_set_master(pdev);
+
+	return 0;
+}
+
+static int mhi_pci_get_irqs(struct mhi_controller *mhi_cntrl,
+			    const struct mhi_controller_config *mhi_cntrl_config)
+{
+	struct pci_dev *pdev = to_pci_dev(mhi_cntrl->cntrl_dev);
+	int nr_vectors, i;
+	int *irq;
+
+	/*
+	 * Alloc one MSI vector for BHI + one vector per event ring, ideally...
+	 * No explicit pci_free_irq_vectors required, done by pcim_release.
+	 */
+	mhi_cntrl->nr_irqs = 1 + mhi_cntrl_config->num_events;
+
+	nr_vectors = pci_alloc_irq_vectors(pdev, 1, mhi_cntrl->nr_irqs, PCI_IRQ_MSI);
+	if (nr_vectors < 0) {
+		dev_err(&pdev->dev, "Error allocating MSI vectors %d\n",
+			nr_vectors);
+		return nr_vectors;
+	}
+
+	if (nr_vectors < mhi_cntrl->nr_irqs) {
+		dev_warn(&pdev->dev, "Not enough MSI vectors (%d/%d), use shared MSI\n",
+			 nr_vectors, mhi_cntrl_config->num_events);
+	}
+
+	irq = devm_kcalloc(&pdev->dev, mhi_cntrl->nr_irqs, sizeof(int), GFP_KERNEL);
+	if (!irq)
+		return -ENOMEM;
+
+	for (i = 0; i < mhi_cntrl->nr_irqs; i++) {
+		int vector = i >= nr_vectors ? (nr_vectors - 1) : i;
+
+		irq[i] = pci_irq_vector(pdev, vector);
+	}
+
+	mhi_cntrl->irq = irq;
+
+	return 0;
+}
+
+static int mhi_pci_runtime_get(struct mhi_controller *mhi_cntrl)
+{
+	/* no PM for now */
+	return 0;
+}
+
+static void mhi_pci_runtime_put(struct mhi_controller *mhi_cntrl)
+{
+	/* no PM for now */
+}
+
+static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	const struct mhi_pci_dev_info *info = (struct mhi_pci_dev_info *) id->driver_data;
+	const struct mhi_controller_config *mhi_cntrl_config;
+	struct mhi_controller *mhi_cntrl;
+	int err;
+
+	dev_dbg(&pdev->dev, "MHI PCI device found: %s\n", info->name);
+
+	mhi_cntrl = mhi_alloc_controller();
+	if (!mhi_cntrl)
+		return -ENOMEM;
+
+	mhi_cntrl_config = info->config;
+	mhi_cntrl->cntrl_dev = &pdev->dev;
+	mhi_cntrl->iova_start = 0;
+	mhi_cntrl->iova_stop = (dma_addr_t)DMA_BIT_MASK(info->dma_data_width);
+	mhi_cntrl->fw_image = info->fw;
+	mhi_cntrl->edl_image = info->edl;
+
+	mhi_cntrl->read_reg = mhi_pci_read_reg;
+	mhi_cntrl->write_reg = mhi_pci_write_reg;
+	mhi_cntrl->status_cb = mhi_pci_status_cb;
+	mhi_cntrl->runtime_get = mhi_pci_runtime_get;
+	mhi_cntrl->runtime_put = mhi_pci_runtime_put;
+
+	err = mhi_pci_claim(mhi_cntrl, info->bar_num, DMA_BIT_MASK(info->dma_data_width));
+	if (err)
+		goto err_release;
+
+	err = mhi_pci_get_irqs(mhi_cntrl, mhi_cntrl_config);
+	if (err)
+		goto err_release;
+
+	pci_set_drvdata(pdev, mhi_cntrl);
+
+	err = mhi_register_controller(mhi_cntrl, mhi_cntrl_config);
+	if (err)
+		goto err_release;
+
+	/* MHI bus does not power up the controller by default */
+	err = mhi_prepare_for_power_up(mhi_cntrl);
+	if (err) {
+		dev_err(&pdev->dev, "failed to prepare MHI controller\n");
+		goto err_unregister;
+	}
+
+	err = mhi_sync_power_up(mhi_cntrl);
+	if (err) {
+		dev_err(&pdev->dev, "failed to power up MHI controller\n");
+		goto err_unprepare;
+	}
+
+	return 0;
+
+err_unprepare:
+	mhi_unprepare_after_power_down(mhi_cntrl);
+err_unregister:
+	mhi_unregister_controller(mhi_cntrl);
+err_release:
+	mhi_free_controller(mhi_cntrl);
+
+	return err;
+}
+
+static void mhi_pci_remove(struct pci_dev *pdev)
+{
+	struct mhi_controller *mhi_cntrl = pci_get_drvdata(pdev);
+
+	mhi_power_down(mhi_cntrl, true);
+	mhi_unprepare_after_power_down(mhi_cntrl);
+	mhi_unregister_controller(mhi_cntrl);
+	mhi_free_controller(mhi_cntrl);
+}
+
+static struct pci_driver mhi_pci_driver = {
+	.name		= "mhi-pci-generic",
+	.id_table	= mhi_pci_id_table,
+	.probe		= mhi_pci_probe,
+	.remove		= mhi_pci_remove
+};
+module_pci_driver(mhi_pci_driver);
+
+MODULE_AUTHOR("Loic Poulain <loic.poulain@linaro.org>");
+MODULE_DESCRIPTION("Modem Host Interface (MHI) PCI controller driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/bus/mhi/core/pm.c b/kernel/drivers/bus/mhi/host/pm.c
similarity index 98%
rename from kernel/drivers/bus/mhi/core/pm.c
rename to kernel/drivers/bus/mhi/host/pm.c
index 044dcdd..fe8ecd6 100644
--- a/kernel/drivers/bus/mhi/core/pm.c
+++ b/kernel/drivers/bus/mhi/host/pm.c
@@ -298,7 +298,8 @@
 		read_lock_irq(&mhi_chan->lock);
 
 		/* Only ring DB if ring is not empty */
-		if (tre_ring->base && tre_ring->wp  != tre_ring->rp)
+		if (tre_ring->base && tre_ring->wp  != tre_ring->rp &&
+		    mhi_chan->ch_state == MHI_CH_STATE_ENABLED)
 			mhi_ring_chan_db(mhi_cntrl, mhi_chan);
 		read_unlock_irq(&mhi_chan->lock);
 	}
@@ -489,6 +490,10 @@
 		u32 in_reset = -1;
 		unsigned long timeout = msecs_to_jiffies(mhi_cntrl->timeout_ms);
 
+		/* Skip MHI RESET if in RDDM state */
+		if (mhi_cntrl->rddm_image && mhi_get_exec_env(mhi_cntrl) == MHI_EE_RDDM)
+			goto skip_mhi_reset;
+
 		dev_dbg(dev, "Triggering MHI Reset in device\n");
 		mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET);
 
@@ -514,6 +519,7 @@
 		mhi_write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0);
 	}
 
+skip_mhi_reset:
 	dev_dbg(dev,
 		 "Waiting for all pending event ring processing to complete\n");
 	mhi_event = mhi_cntrl->mhi_event;
diff --git a/kernel/drivers/bus/sunxi-rsb.c b/kernel/drivers/bus/sunxi-rsb.c
index f8c29b8..98cbb18 100644
--- a/kernel/drivers/bus/sunxi-rsb.c
+++ b/kernel/drivers/bus/sunxi-rsb.c
@@ -781,7 +781,13 @@
 		return ret;
 	}
 
-	return platform_driver_register(&sunxi_rsb_driver);
+	ret = platform_driver_register(&sunxi_rsb_driver);
+	if (ret) {
+		bus_unregister(&sunxi_rsb_bus);
+		return ret;
+	}
+
+	return 0;
 }
 module_init(sunxi_rsb_init);
 
diff --git a/kernel/drivers/bus/ti-sysc.c b/kernel/drivers/bus/ti-sysc.c
index 4ee20be..ef8c7bf 100644
--- a/kernel/drivers/bus/ti-sysc.c
+++ b/kernel/drivers/bus/ti-sysc.c
@@ -38,6 +38,7 @@
 	SOC_2420,
 	SOC_2430,
 	SOC_3430,
+	SOC_AM35,
 	SOC_3630,
 	SOC_4430,
 	SOC_4460,
@@ -1113,6 +1114,11 @@
 	if (ddata->cfg.quirks & (SYSC_QUIRK_SWSUP_SIDLE |
 				 SYSC_QUIRK_SWSUP_SIDLE_ACT)) {
 		best_mode = SYSC_IDLE_NO;
+
+		/* Clear WAKEUP */
+		if (regbits->enwkup_shift >= 0 &&
+		    ddata->cfg.sysc_val & BIT(regbits->enwkup_shift))
+			reg &= ~BIT(regbits->enwkup_shift);
 	} else {
 		best_mode = fls(ddata->cfg.sidlemodes) - 1;
 		if (best_mode > SYSC_IDLE_MASK) {
@@ -1231,6 +1237,13 @@
 			dev_err(dev, "%s: invalid sidlemode\n", __func__);
 			return ret;
 		}
+	}
+
+	if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_SIDLE_ACT) {
+		/* Set WAKEUP */
+		if (regbits->enwkup_shift >= 0 &&
+		    ddata->cfg.sysc_val & BIT(regbits->enwkup_shift))
+			reg |= BIT(regbits->enwkup_shift);
 	}
 
 	reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift);
@@ -1496,14 +1509,16 @@
 	SYSC_QUIRK("smartreflex", 0, -ENODEV, 0x38, -ENODEV, 0x00000000, 0xffffffff,
 		   SYSC_QUIRK_LEGACY_IDLE),
 	SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff,
-		   SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE),
+		   SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
 	SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff,
-		   SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE),
+		   SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
 	/* Uarts on omap4 and later */
 	SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff,
-		   SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE),
+		   SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
 	SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff,
-		   SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE),
+		   SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
+	SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff,
+		   SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
 
 	/* Quirks that need to be set based on the module address */
 	SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff,
@@ -1748,7 +1763,7 @@
 	if (!ddata->module_va)
 		return -EIO;
 
-	/* DISP_CONTROL */
+	/* DISP_CONTROL, shut down lcd and digit on disable if enabled */
 	val = sysc_read(ddata, dispc_offset + 0x40);
 	lcd_en = val & lcd_en_mask;
 	digit_en = val & digit_en_mask;
@@ -1760,7 +1775,7 @@
 		else
 			irq_mask |= BIT(2) | BIT(3);	/* EVSYNC bits */
 	}
-	if (disable & (lcd_en | digit_en))
+	if (disable && (lcd_en || digit_en))
 		sysc_write(ddata, dispc_offset + 0x40,
 			   val & ~(lcd_en_mask | digit_en_mask));
 
@@ -1816,7 +1831,7 @@
 		dev_warn(ddata->dev, "%s: timed out %08x !+ %08x\n",
 			 __func__, val, irq_mask);
 
-	if (sysc_soc->soc == SOC_3430) {
+	if (sysc_soc->soc == SOC_3430 || sysc_soc->soc == SOC_AM35) {
 		/* Clear DSS_SDI_CONTROL */
 		sysc_write(ddata, 0x44, 0);
 
@@ -2078,11 +2093,12 @@
 		sysc_val = sysc_read_sysconfig(ddata);
 		sysc_val |= sysc_mask;
 		sysc_write(ddata, sysc_offset, sysc_val);
+		/* Flush posted write */
+		sysc_val = sysc_read_sysconfig(ddata);
 	}
 
 	if (ddata->cfg.srst_udelay)
-		usleep_range(ddata->cfg.srst_udelay,
-			     ddata->cfg.srst_udelay * 2);
+		fsleep(ddata->cfg.srst_udelay);
 
 	if (ddata->post_reset_quirk)
 		ddata->post_reset_quirk(ddata);
@@ -2956,6 +2972,7 @@
 static const struct soc_device_attribute sysc_soc_match[] = {
 	SOC_FLAG("OMAP242*", SOC_2420),
 	SOC_FLAG("OMAP243*", SOC_2430),
+	SOC_FLAG("AM35*", SOC_AM35),
 	SOC_FLAG("OMAP3[45]*", SOC_3430),
 	SOC_FLAG("OMAP3[67]*", SOC_3630),
 	SOC_FLAG("OMAP443*", SOC_4430),
@@ -3039,7 +3056,7 @@
 
 	match = soc_device_match(sysc_soc_match);
 	if (match && match->data)
-		sysc_soc->soc = (int)match->data;
+		sysc_soc->soc = (enum sysc_soc)(uintptr_t)match->data;
 
 	/* Ignore devices that are not available on HS and EMU SoCs */
 	if (!sysc_soc->general_purpose) {
@@ -3143,7 +3160,7 @@
 	 * can be dropped if we stop supporting old beagleboard revisions
 	 * A to B4 at some point.
 	 */
-	if (sysc_soc->soc == SOC_3430)
+	if (sysc_soc->soc == SOC_3430 || sysc_soc->soc == SOC_AM35)
 		error = -ENXIO;
 	else
 		error = -EBUSY;
diff --git a/kernel/drivers/char/agp/parisc-agp.c b/kernel/drivers/char/agp/parisc-agp.c
index d68d05d..c6f1817 100644
--- a/kernel/drivers/char/agp/parisc-agp.c
+++ b/kernel/drivers/char/agp/parisc-agp.c
@@ -90,6 +90,9 @@
 {
 	struct _parisc_agp_info *info = &parisc_agp_info;
 
+	/* force fdc ops to be visible to IOMMU */
+	asm_io_sync();
+
 	writeq(info->gart_base | ilog2(info->gart_size), info->ioc_regs+IOC_PCOM);
 	readq(info->ioc_regs+IOC_PCOM);	/* flush */
 }
@@ -158,6 +161,7 @@
 			info->gatt[j] =
 				parisc_agp_mask_memory(agp_bridge,
 					paddr, type);
+			asm_io_fdc(&info->gatt[j]);
 		}
 	}
 
@@ -191,7 +195,16 @@
 parisc_agp_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr,
 		       int type)
 {
-	return SBA_PDIR_VALID_BIT | addr;
+	unsigned ci;			/* coherent index */
+	dma_addr_t pa;
+
+	pa = addr & IOVP_MASK;
+	asm("lci 0(%1), %0" : "=r" (ci) : "r" (phys_to_virt(pa)));
+
+	pa |= (ci >> PAGE_SHIFT) & 0xff;/* move CI (8 bits) into lowest byte */
+	pa |= SBA_PDIR_VALID_BIT;	/* set "valid" bit */
+
+	return cpu_to_le64(pa);
 }
 
 static void
@@ -381,8 +394,6 @@
 static int __init
 parisc_agp_init(void)
 {
-	extern struct sba_device *sba_list;
-
 	int err = -1;
 	struct parisc_device *sba = NULL, *lba = NULL;
 	struct lba_device *lbadev = NULL;
diff --git a/kernel/drivers/char/hw_random/amd-rng.c b/kernel/drivers/char/hw_random/amd-rng.c
index 9959c76..db3dd46 100644
--- a/kernel/drivers/char/hw_random/amd-rng.c
+++ b/kernel/drivers/char/hw_random/amd-rng.c
@@ -143,15 +143,19 @@
 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 @@
 	release_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE);
 out:
 	kfree(priv);
+put_dev:
+	pci_dev_put(pdev);
 	return err;
 }
 
@@ -200,6 +206,8 @@
 
 	release_region(priv->pmbase + PMBASE_OFFSET, PMBASE_SIZE);
 
+	pci_dev_put(priv->pcidev);
+
 	kfree(priv);
 }
 
diff --git a/kernel/drivers/char/hw_random/geode-rng.c b/kernel/drivers/char/hw_random/geode-rng.c
index e1d421a..2072729 100644
--- a/kernel/drivers/char/hw_random/geode-rng.c
+++ b/kernel/drivers/char/hw_random/geode-rng.c
@@ -51,6 +51,10 @@
 };
 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 @@
 	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 @@
 			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 @@
 		       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);
diff --git a/kernel/drivers/char/hw_random/imx-rngc.c b/kernel/drivers/char/hw_random/imx-rngc.c
index 9b182e5..dbb2da6 100644
--- a/kernel/drivers/char/hw_random/imx-rngc.c
+++ b/kernel/drivers/char/hw_random/imx-rngc.c
@@ -110,7 +110,7 @@
 	cmd = readl(rngc->base + RNGC_COMMAND);
 	writel(cmd | RNGC_CMD_SELF_TEST, rngc->base + RNGC_COMMAND);
 
-	ret = wait_for_completion_timeout(&rngc->rng_op_done, RNGC_TIMEOUT);
+	ret = wait_for_completion_timeout(&rngc->rng_op_done, msecs_to_jiffies(RNGC_TIMEOUT));
 	imx_rngc_irq_mask_clear(rngc);
 	if (!ret)
 		return -ETIMEDOUT;
@@ -187,9 +187,7 @@
 		cmd = readl(rngc->base + RNGC_COMMAND);
 		writel(cmd | RNGC_CMD_SEED, rngc->base + RNGC_COMMAND);
 
-		ret = wait_for_completion_timeout(&rngc->rng_op_done,
-				RNGC_TIMEOUT);
-
+		ret = wait_for_completion_timeout(&rngc->rng_op_done, msecs_to_jiffies(RNGC_TIMEOUT));
 		if (!ret) {
 			ret = -ETIMEDOUT;
 			goto err;
diff --git a/kernel/drivers/char/hw_random/iproc-rng200.c b/kernel/drivers/char/hw_random/iproc-rng200.c
index 01583fa..52c4aa6 100644
--- a/kernel/drivers/char/hw_random/iproc-rng200.c
+++ b/kernel/drivers/char/hw_random/iproc-rng200.c
@@ -195,6 +195,8 @@
 		return PTR_ERR(priv->base);
 	}
 
+	dev_set_drvdata(dev, priv);
+
 	priv->rng.name = "iproc-rng200";
 	priv->rng.read = iproc_rng200_read;
 	priv->rng.init = iproc_rng200_init;
@@ -212,6 +214,28 @@
 	return 0;
 }
 
+static int __maybe_unused iproc_rng200_suspend(struct device *dev)
+{
+	struct iproc_rng200_dev *priv = dev_get_drvdata(dev);
+
+	iproc_rng200_cleanup(&priv->rng);
+
+	return 0;
+}
+
+static int __maybe_unused iproc_rng200_resume(struct device *dev)
+{
+	struct iproc_rng200_dev *priv =  dev_get_drvdata(dev);
+
+	iproc_rng200_init(&priv->rng);
+
+	return 0;
+}
+
+static const struct dev_pm_ops iproc_rng200_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(iproc_rng200_suspend, iproc_rng200_resume)
+};
+
 static const struct of_device_id iproc_rng200_of_match[] = {
 	{ .compatible = "brcm,bcm2711-rng200", },
 	{ .compatible = "brcm,bcm7211-rng200", },
@@ -225,6 +249,7 @@
 	.driver = {
 		.name		= "iproc-rng200",
 		.of_match_table = iproc_rng200_of_match,
+		.pm		= &iproc_rng200_pm_ops,
 	},
 	.probe		= iproc_rng200_probe,
 };
diff --git a/kernel/drivers/char/hw_random/nomadik-rng.c b/kernel/drivers/char/hw_random/nomadik-rng.c
index e8f9621..3774adf 100644
--- a/kernel/drivers/char/hw_random/nomadik-rng.c
+++ b/kernel/drivers/char/hw_random/nomadik-rng.c
@@ -13,8 +13,6 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 
-static struct clk *rng_clk;
-
 static int nmk_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
 {
 	void __iomem *base = (void __iomem *)rng->priv;
@@ -36,21 +34,20 @@
 
 static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id)
 {
+	struct clk *rng_clk;
 	void __iomem *base;
 	int ret;
 
-	rng_clk = devm_clk_get(&dev->dev, NULL);
+	rng_clk = devm_clk_get_enabled(&dev->dev, NULL);
 	if (IS_ERR(rng_clk)) {
 		dev_err(&dev->dev, "could not get rng clock\n");
 		ret = PTR_ERR(rng_clk);
 		return ret;
 	}
 
-	clk_prepare_enable(rng_clk);
-
 	ret = amba_request_regions(dev, dev->dev.init_name);
 	if (ret)
-		goto out_clk;
+		return ret;
 	ret = -ENOMEM;
 	base = devm_ioremap(&dev->dev, dev->res.start,
 			    resource_size(&dev->res));
@@ -64,15 +61,12 @@
 
 out_release:
 	amba_release_regions(dev);
-out_clk:
-	clk_disable_unprepare(rng_clk);
 	return ret;
 }
 
 static void nmk_rng_remove(struct amba_device *dev)
 {
 	amba_release_regions(dev);
-	clk_disable_unprepare(rng_clk);
 }
 
 static const struct amba_id nmk_rng_ids[] = {
diff --git a/kernel/drivers/char/hw_random/st-rng.c b/kernel/drivers/char/hw_random/st-rng.c
index 15ba1e6..6e9dfac 100644
--- a/kernel/drivers/char/hw_random/st-rng.c
+++ b/kernel/drivers/char/hw_random/st-rng.c
@@ -42,7 +42,6 @@
 
 struct st_rng_data {
 	void __iomem	*base;
-	struct clk	*clk;
 	struct hwrng	ops;
 };
 
@@ -85,39 +84,22 @@
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
-	clk = devm_clk_get(&pdev->dev, NULL);
+	clk = devm_clk_get_enabled(&pdev->dev, NULL);
 	if (IS_ERR(clk))
 		return PTR_ERR(clk);
-
-	ret = clk_prepare_enable(clk);
-	if (ret)
-		return ret;
 
 	ddata->ops.priv	= (unsigned long)ddata;
 	ddata->ops.read	= st_rng_read;
 	ddata->ops.name	= pdev->name;
 	ddata->base	= base;
-	ddata->clk	= clk;
-
-	dev_set_drvdata(&pdev->dev, ddata);
 
 	ret = devm_hwrng_register(&pdev->dev, &ddata->ops);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register HW RNG\n");
-		clk_disable_unprepare(clk);
 		return ret;
 	}
 
 	dev_info(&pdev->dev, "Successfully registered HW RNG\n");
-
-	return 0;
-}
-
-static int st_rng_remove(struct platform_device *pdev)
-{
-	struct st_rng_data *ddata = dev_get_drvdata(&pdev->dev);
-
-	clk_disable_unprepare(ddata->clk);
 
 	return 0;
 }
@@ -134,7 +116,6 @@
 		.of_match_table = of_match_ptr(st_rng_match),
 	},
 	.probe = st_rng_probe,
-	.remove = st_rng_remove
 };
 
 module_platform_driver(st_rng_driver);
diff --git a/kernel/drivers/char/hw_random/virtio-rng.c b/kernel/drivers/char/hw_random/virtio-rng.c
index a90001e..3a194eb 100644
--- a/kernel/drivers/char/hw_random/virtio-rng.c
+++ b/kernel/drivers/char/hw_random/virtio-rng.c
@@ -4,6 +4,7 @@
  *  Copyright (C) 2007, 2008 Rusty Russell IBM Corporation
  */
 
+#include <asm/barrier.h>
 #include <linux/err.h>
 #include <linux/hw_random.h>
 #include <linux/scatterlist.h>
@@ -18,71 +19,111 @@
 struct virtrng_info {
 	struct hwrng hwrng;
 	struct virtqueue *vq;
-	struct completion have_data;
 	char name[25];
-	unsigned int data_avail;
 	int index;
-	bool busy;
 	bool hwrng_register_done;
 	bool hwrng_removed;
+	/* data transfer */
+	struct completion have_data;
+	unsigned int data_avail;
+	unsigned int data_idx;
+	/* minimal size returned by rng_buffer_size() */
+#if SMP_CACHE_BYTES < 32
+	u8 data[32];
+#else
+	u8 data[SMP_CACHE_BYTES];
+#endif
 };
 
 static void random_recv_done(struct virtqueue *vq)
 {
 	struct virtrng_info *vi = vq->vdev->priv;
+	unsigned int len;
 
 	/* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */
-	if (!virtqueue_get_buf(vi->vq, &vi->data_avail))
+	if (!virtqueue_get_buf(vi->vq, &len))
 		return;
 
+	smp_store_release(&vi->data_avail, len);
 	complete(&vi->have_data);
 }
 
-/* The host will fill any buffer we give it with sweet, sweet randomness. */
-static void register_buffer(struct virtrng_info *vi, u8 *buf, size_t size)
+static void request_entropy(struct virtrng_info *vi)
 {
 	struct scatterlist sg;
 
-	sg_init_one(&sg, buf, size);
+	reinit_completion(&vi->have_data);
+	vi->data_idx = 0;
+
+	sg_init_one(&sg, vi->data, sizeof(vi->data));
 
 	/* There should always be room for one buffer. */
-	virtqueue_add_inbuf(vi->vq, &sg, 1, buf, GFP_KERNEL);
+	virtqueue_add_inbuf(vi->vq, &sg, 1, vi->data, GFP_KERNEL);
 
 	virtqueue_kick(vi->vq);
+}
+
+static unsigned int copy_data(struct virtrng_info *vi, void *buf,
+			      unsigned int size)
+{
+	size = min_t(unsigned int, size, vi->data_avail);
+	memcpy(buf, vi->data + vi->data_idx, size);
+	vi->data_idx += size;
+	vi->data_avail -= size;
+	if (vi->data_avail == 0)
+		request_entropy(vi);
+	return size;
 }
 
 static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
 {
 	int ret;
 	struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
+	unsigned int chunk;
+	size_t read;
 
 	if (vi->hwrng_removed)
 		return -ENODEV;
 
-	if (!vi->busy) {
-		vi->busy = true;
-		reinit_completion(&vi->have_data);
-		register_buffer(vi, buf, size);
+	read = 0;
+
+	/* copy available data */
+	if (smp_load_acquire(&vi->data_avail)) {
+		chunk = copy_data(vi, buf, size);
+		size -= chunk;
+		read += chunk;
 	}
 
 	if (!wait)
-		return 0;
+		return read;
 
-	ret = wait_for_completion_killable(&vi->have_data);
-	if (ret < 0)
-		return ret;
+	/* We have already copied available entropy,
+	 * so either size is 0 or data_avail is 0
+	 */
+	while (size != 0) {
+		/* data_avail is 0 but a request is pending */
+		ret = wait_for_completion_killable(&vi->have_data);
+		if (ret < 0)
+			return ret;
+		/* if vi->data_avail is 0, we have been interrupted
+		 * by a cleanup, but buffer stays in the queue
+		 */
+		if (vi->data_avail == 0)
+			return read;
 
-	vi->busy = false;
+		chunk = copy_data(vi, buf + read, size);
+		size -= chunk;
+		read += chunk;
+	}
 
-	return vi->data_avail;
+	return read;
 }
 
 static void virtio_cleanup(struct hwrng *rng)
 {
 	struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
 
-	if (vi->busy)
-		wait_for_completion(&vi->have_data);
+	complete(&vi->have_data);
 }
 
 static int probe_common(struct virtio_device *vdev)
@@ -118,6 +159,9 @@
 		goto err_find;
 	}
 
+	/* we always have a pending entropy request */
+	request_entropy(vi);
+
 	return 0;
 
 err_find:
@@ -133,9 +177,9 @@
 
 	vi->hwrng_removed = true;
 	vi->data_avail = 0;
+	vi->data_idx = 0;
 	complete(&vi->have_data);
 	vdev->config->reset(vdev);
-	vi->busy = false;
 	if (vi->hwrng_register_done)
 		hwrng_unregister(&vi->hwrng);
 	vdev->config->del_vqs(vdev);
diff --git a/kernel/drivers/char/ipmi/Kconfig b/kernel/drivers/char/ipmi/Kconfig
index 07847d9..f443186 100644
--- a/kernel/drivers/char/ipmi/Kconfig
+++ b/kernel/drivers/char/ipmi/Kconfig
@@ -126,7 +126,8 @@
 
 config ASPEED_BT_IPMI_BMC
 	depends on ARCH_ASPEED || COMPILE_TEST
-	depends on REGMAP && REGMAP_MMIO && MFD_SYSCON
+	depends on MFD_SYSCON
+	select REGMAP_MMIO
 	tristate "BT IPMI bmc driver"
 	help
 	  Provides a driver for the BT (Block Transfer) IPMI interface
diff --git a/kernel/drivers/char/ipmi/ipmi_msghandler.c b/kernel/drivers/char/ipmi/ipmi_msghandler.c
index 05e7339..b89f300 100644
--- a/kernel/drivers/char/ipmi/ipmi_msghandler.c
+++ b/kernel/drivers/char/ipmi/ipmi_msghandler.c
@@ -1284,6 +1284,7 @@
 	unsigned long    flags;
 	struct cmd_rcvr  *rcvr;
 	struct cmd_rcvr  *rcvrs = NULL;
+	struct module    *owner;
 
 	if (!acquire_ipmi_user(user, &i)) {
 		/*
@@ -1345,8 +1346,9 @@
 		kfree(rcvr);
 	}
 
+	owner = intf->owner;
 	kref_put(&intf->refcount, intf_free);
-	module_put(intf->owner);
+	module_put(owner);
 }
 
 int ipmi_destroy_user(struct ipmi_user *user)
@@ -3540,12 +3542,16 @@
 				     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)
diff --git a/kernel/drivers/char/ipmi/ipmi_si_intf.c b/kernel/drivers/char/ipmi/ipmi_si_intf.c
index 5eac94c..a541869 100644
--- a/kernel/drivers/char/ipmi/ipmi_si_intf.c
+++ b/kernel/drivers/char/ipmi/ipmi_si_intf.c
@@ -2089,6 +2089,11 @@
 		new_smi->io.io_cleanup = NULL;
 	}
 
+	if (rv && new_smi->si_sm) {
+		kfree(new_smi->si_sm);
+		new_smi->si_sm = NULL;
+	}
+
 	return rv;
 }
 
@@ -2160,6 +2165,20 @@
 }
 module_init(init_ipmi_si);
 
+static void wait_msg_processed(struct smi_info *smi_info)
+{
+	unsigned long jiffies_now;
+	long time_diff;
+
+	while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
+		jiffies_now = jiffies;
+		time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies)
+		     * SI_USEC_PER_JIFFY);
+		smi_event_handler(smi_info, time_diff);
+		schedule_timeout_uninterruptible(1);
+	}
+}
+
 static void shutdown_smi(void *send_info)
 {
 	struct smi_info *smi_info = send_info;
@@ -2194,16 +2213,13 @@
 	 * in the BMC.  Note that timers and CPU interrupts are off,
 	 * so no need for locks.
 	 */
-	while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
-		poll(smi_info);
-		schedule_timeout_uninterruptible(1);
-	}
+	wait_msg_processed(smi_info);
+
 	if (smi_info->handlers)
 		disable_si_irq(smi_info);
-	while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
-		poll(smi_info);
-		schedule_timeout_uninterruptible(1);
-	}
+
+	wait_msg_processed(smi_info);
+
 	if (smi_info->handlers)
 		smi_info->handlers->cleanup(smi_info->si_sm);
 
diff --git a/kernel/drivers/char/ipmi/ipmi_ssif.c b/kernel/drivers/char/ipmi/ipmi_ssif.c
index 4771397..30f7572 100644
--- a/kernel/drivers/char/ipmi/ipmi_ssif.c
+++ b/kernel/drivers/char/ipmi/ipmi_ssif.c
@@ -74,7 +74,8 @@
 /*
  * Timer values
  */
-#define SSIF_MSG_USEC		20000	/* 20ms between message tries. */
+#define SSIF_MSG_USEC		60000	/* 60ms between message tries (T3). */
+#define SSIF_REQ_RETRY_USEC	60000	/* 60ms between send retries (T6). */
 #define SSIF_MSG_PART_USEC	5000	/* 5ms for a message part */
 
 /* How many times to we retry sending/receiving the message. */
@@ -82,7 +83,9 @@
 #define	SSIF_RECV_RETRIES	250
 
 #define SSIF_MSG_MSEC		(SSIF_MSG_USEC / 1000)
+#define SSIF_REQ_RETRY_MSEC	(SSIF_REQ_RETRY_USEC / 1000)
 #define SSIF_MSG_JIFFIES	((SSIF_MSG_USEC * 1000) / TICK_NSEC)
+#define SSIF_REQ_RETRY_JIFFIES	((SSIF_REQ_RETRY_USEC * 1000) / TICK_NSEC)
 #define SSIF_MSG_PART_JIFFIES	((SSIF_MSG_PART_USEC * 1000) / TICK_NSEC)
 
 /*
@@ -92,7 +95,7 @@
 #define SSIF_WATCH_WATCHDOG_TIMEOUT	msecs_to_jiffies(250)
 
 enum ssif_intf_state {
-	SSIF_NORMAL,
+	SSIF_IDLE,
 	SSIF_GETTING_FLAGS,
 	SSIF_GETTING_EVENTS,
 	SSIF_CLEARING_FLAGS,
@@ -100,8 +103,8 @@
 	/* FIXME - add watchdog stuff. */
 };
 
-#define SSIF_IDLE(ssif)	 ((ssif)->ssif_state == SSIF_NORMAL \
-			  && (ssif)->curr_msg == NULL)
+#define IS_SSIF_IDLE(ssif) ((ssif)->ssif_state == SSIF_IDLE \
+			    && (ssif)->curr_msg == NULL)
 
 /*
  * Indexes into stats[] in ssif_info below.
@@ -229,6 +232,9 @@
 	bool		    got_alert;
 	bool		    waiting_alert;
 
+	/* Used to inform the timeout that it should do a resend. */
+	bool		    do_resend;
+
 	/*
 	 * If set to true, this will request events the next time the
 	 * state machine is idle.
@@ -348,9 +354,9 @@
 
 /*
  * Must be called with the message lock held.  This will release the
- * message lock.  Note that the caller will check SSIF_IDLE and start a
- * new operation, so there is no need to check for new messages to
- * start in here.
+ * message lock.  Note that the caller will check IS_SSIF_IDLE and
+ * start a new operation, so there is no need to check for new
+ * messages to start in here.
  */
 static void start_clear_flags(struct ssif_info *ssif_info, unsigned long *flags)
 {
@@ -367,7 +373,7 @@
 
 	if (start_send(ssif_info, msg, 3) != 0) {
 		/* Error, just go to normal state. */
-		ssif_info->ssif_state = SSIF_NORMAL;
+		ssif_info->ssif_state = SSIF_IDLE;
 	}
 }
 
@@ -382,7 +388,7 @@
 	mb[0] = (IPMI_NETFN_APP_REQUEST << 2);
 	mb[1] = IPMI_GET_MSG_FLAGS_CMD;
 	if (start_send(ssif_info, mb, 2) != 0)
-		ssif_info->ssif_state = SSIF_NORMAL;
+		ssif_info->ssif_state = SSIF_IDLE;
 }
 
 static void check_start_send(struct ssif_info *ssif_info, unsigned long *flags,
@@ -393,7 +399,7 @@
 
 		flags = ipmi_ssif_lock_cond(ssif_info, &oflags);
 		ssif_info->curr_msg = NULL;
-		ssif_info->ssif_state = SSIF_NORMAL;
+		ssif_info->ssif_state = SSIF_IDLE;
 		ipmi_ssif_unlock_cond(ssif_info, flags);
 		ipmi_free_smi_msg(msg);
 	}
@@ -407,7 +413,7 @@
 
 	msg = ipmi_alloc_smi_msg();
 	if (!msg) {
-		ssif_info->ssif_state = SSIF_NORMAL;
+		ssif_info->ssif_state = SSIF_IDLE;
 		ipmi_ssif_unlock_cond(ssif_info, flags);
 		return;
 	}
@@ -430,7 +436,7 @@
 
 	msg = ipmi_alloc_smi_msg();
 	if (!msg) {
-		ssif_info->ssif_state = SSIF_NORMAL;
+		ssif_info->ssif_state = SSIF_IDLE;
 		ipmi_ssif_unlock_cond(ssif_info, flags);
 		return;
 	}
@@ -448,9 +454,9 @@
 
 /*
  * Must be called with the message lock held.  This will release the
- * message lock.  Note that the caller will check SSIF_IDLE and start a
- * new operation, so there is no need to check for new messages to
- * start in here.
+ * message lock.  Note that the caller will check IS_SSIF_IDLE and
+ * start a new operation, so there is no need to check for new
+ * messages to start in here.
  */
 static void handle_flags(struct ssif_info *ssif_info, unsigned long *flags)
 {
@@ -466,7 +472,7 @@
 		/* Events available. */
 		start_event_fetch(ssif_info, flags);
 	else {
-		ssif_info->ssif_state = SSIF_NORMAL;
+		ssif_info->ssif_state = SSIF_IDLE;
 		ipmi_ssif_unlock_cond(ssif_info, flags);
 	}
 }
@@ -510,7 +516,7 @@
 	return 0;
 }
 
-static int ssif_i2c_send(struct ssif_info *ssif_info,
+static void ssif_i2c_send(struct ssif_info *ssif_info,
 			ssif_i2c_done handler,
 			int read_write, int command,
 			unsigned char *data, unsigned int size)
@@ -522,7 +528,6 @@
 	ssif_info->i2c_data = data;
 	ssif_info->i2c_size = size;
 	complete(&ssif_info->wake_thread);
-	return 0;
 }
 
 
@@ -531,40 +536,38 @@
 
 static void start_get(struct ssif_info *ssif_info)
 {
-	int rv;
-
 	ssif_info->rtc_us_timer = 0;
 	ssif_info->multi_pos = 0;
 
-	rv = ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ,
-			  SSIF_IPMI_RESPONSE,
-			  ssif_info->recv, I2C_SMBUS_BLOCK_DATA);
-	if (rv < 0) {
-		/* request failed, just return the error. */
-		if (ssif_info->ssif_debug & SSIF_DEBUG_MSG)
-			dev_dbg(&ssif_info->client->dev,
-				"Error from i2c_non_blocking_op(5)\n");
-
-		msg_done_handler(ssif_info, -EIO, NULL, 0);
-	}
+	ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ,
+		  SSIF_IPMI_RESPONSE,
+		  ssif_info->recv, I2C_SMBUS_BLOCK_DATA);
 }
+
+static void start_resend(struct ssif_info *ssif_info);
 
 static void retry_timeout(struct timer_list *t)
 {
 	struct ssif_info *ssif_info = from_timer(ssif_info, t, retry_timer);
 	unsigned long oflags, *flags;
-	bool waiting;
+	bool waiting, resend;
 
 	if (ssif_info->stopping)
 		return;
 
 	flags = ipmi_ssif_lock_cond(ssif_info, &oflags);
+	resend = ssif_info->do_resend;
+	ssif_info->do_resend = false;
 	waiting = ssif_info->waiting_alert;
 	ssif_info->waiting_alert = false;
 	ipmi_ssif_unlock_cond(ssif_info, flags);
 
 	if (waiting)
 		start_get(ssif_info);
+	if (resend) {
+		start_resend(ssif_info);
+		ssif_inc_stat(ssif_info, send_retries);
+	}
 }
 
 static void watch_timeout(struct timer_list *t)
@@ -579,7 +582,7 @@
 	if (ssif_info->watch_timeout) {
 		mod_timer(&ssif_info->watch_timer,
 			  jiffies + ssif_info->watch_timeout);
-		if (SSIF_IDLE(ssif_info)) {
+		if (IS_SSIF_IDLE(ssif_info)) {
 			start_flag_fetch(ssif_info, flags); /* Releases lock */
 			return;
 		}
@@ -613,14 +616,11 @@
 		start_get(ssif_info);
 }
 
-static int start_resend(struct ssif_info *ssif_info);
-
 static void msg_done_handler(struct ssif_info *ssif_info, int result,
 			     unsigned char *data, unsigned int len)
 {
 	struct ipmi_smi_msg *msg;
 	unsigned long oflags, *flags;
-	int rv;
 
 	/*
 	 * We are single-threaded here, so no need for a lock until we
@@ -666,17 +666,10 @@
 		ssif_info->multi_len = len;
 		ssif_info->multi_pos = 1;
 
-		rv = ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ,
-				  SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE,
-				  ssif_info->recv, I2C_SMBUS_BLOCK_DATA);
-		if (rv < 0) {
-			if (ssif_info->ssif_debug & SSIF_DEBUG_MSG)
-				dev_dbg(&ssif_info->client->dev,
-					"Error from i2c_non_blocking_op(1)\n");
-
-			result = -EIO;
-		} else
-			return;
+		ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ,
+			 SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE,
+			 ssif_info->recv, I2C_SMBUS_BLOCK_DATA);
+		return;
 	} else if (ssif_info->multi_pos) {
 		/* Middle of multi-part read.  Start the next transaction. */
 		int i;
@@ -738,19 +731,12 @@
 
 			ssif_info->multi_pos++;
 
-			rv = ssif_i2c_send(ssif_info, msg_done_handler,
-					   I2C_SMBUS_READ,
-					   SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE,
-					   ssif_info->recv,
-					   I2C_SMBUS_BLOCK_DATA);
-			if (rv < 0) {
-				if (ssif_info->ssif_debug & SSIF_DEBUG_MSG)
-					dev_dbg(&ssif_info->client->dev,
-						"Error from ssif_i2c_send\n");
-
-				result = -EIO;
-			} else
-				return;
+			ssif_i2c_send(ssif_info, msg_done_handler,
+				  I2C_SMBUS_READ,
+				  SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE,
+				  ssif_info->recv,
+				  I2C_SMBUS_BLOCK_DATA);
+			return;
 		}
 	}
 
@@ -782,7 +768,7 @@
 	}
 
 	switch (ssif_info->ssif_state) {
-	case SSIF_NORMAL:
+	case SSIF_IDLE:
 		ipmi_ssif_unlock_cond(ssif_info, flags);
 		if (!msg)
 			break;
@@ -800,7 +786,7 @@
 			 * Error fetching flags, or invalid length,
 			 * just give up for now.
 			 */
-			ssif_info->ssif_state = SSIF_NORMAL;
+			ssif_info->ssif_state = SSIF_IDLE;
 			ipmi_ssif_unlock_cond(ssif_info, flags);
 			dev_warn(&ssif_info->client->dev,
 				 "Error getting flags: %d %d, %x\n",
@@ -808,9 +794,9 @@
 		} else if (data[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2
 			   || data[1] != IPMI_GET_MSG_FLAGS_CMD) {
 			/*
-			 * Don't abort here, maybe it was a queued
-			 * response to a previous command.
+			 * Recv error response, give up.
 			 */
+			ssif_info->ssif_state = SSIF_IDLE;
 			ipmi_ssif_unlock_cond(ssif_info, flags);
 			dev_warn(&ssif_info->client->dev,
 				 "Invalid response getting flags: %x %x\n",
@@ -835,7 +821,7 @@
 				 "Invalid response clearing flags: %x %x\n",
 				 data[0], data[1]);
 		}
-		ssif_info->ssif_state = SSIF_NORMAL;
+		ssif_info->ssif_state = SSIF_IDLE;
 		ipmi_ssif_unlock_cond(ssif_info, flags);
 		break;
 
@@ -913,7 +899,7 @@
 	}
 
 	flags = ipmi_ssif_lock_cond(ssif_info, &oflags);
-	if (SSIF_IDLE(ssif_info) && !ssif_info->stopping) {
+	if (IS_SSIF_IDLE(ssif_info) && !ssif_info->stopping) {
 		if (ssif_info->req_events)
 			start_event_fetch(ssif_info, flags);
 		else if (ssif_info->req_flags)
@@ -931,37 +917,27 @@
 static void msg_written_handler(struct ssif_info *ssif_info, int result,
 				unsigned char *data, unsigned int len)
 {
-	int rv;
-
 	/* We are single-threaded here, so no need for a lock. */
 	if (result < 0) {
 		ssif_info->retries_left--;
 		if (ssif_info->retries_left > 0) {
-			if (!start_resend(ssif_info)) {
-				ssif_inc_stat(ssif_info, send_retries);
-				return;
-			}
-			/* request failed, just return the error. */
-			ssif_inc_stat(ssif_info, send_errors);
-
-			if (ssif_info->ssif_debug & SSIF_DEBUG_MSG)
-				dev_dbg(&ssif_info->client->dev,
-					"%s: Out of retries\n", __func__);
-			msg_done_handler(ssif_info, -EIO, NULL, 0);
+			/*
+			 * Wait the retry timeout time per the spec,
+			 * then redo the send.
+			 */
+			ssif_info->do_resend = true;
+			mod_timer(&ssif_info->retry_timer,
+				  jiffies + SSIF_REQ_RETRY_JIFFIES);
 			return;
 		}
 
 		ssif_inc_stat(ssif_info, send_errors);
 
-		/*
-		 * Got an error on transmit, let the done routine
-		 * handle it.
-		 */
 		if (ssif_info->ssif_debug & SSIF_DEBUG_MSG)
 			dev_dbg(&ssif_info->client->dev,
-				"%s: Error  %d\n", __func__, result);
+				"%s: Out of retries\n", __func__);
 
-		msg_done_handler(ssif_info, result, NULL, 0);
+		msg_done_handler(ssif_info, -EIO, NULL, 0);
 		return;
 	}
 
@@ -995,18 +971,9 @@
 			ssif_info->multi_data = NULL;
 		}
 
-		rv = ssif_i2c_send(ssif_info, msg_written_handler,
-				   I2C_SMBUS_WRITE, cmd,
-				   data_to_send, I2C_SMBUS_BLOCK_DATA);
-		if (rv < 0) {
-			/* request failed, just return the error. */
-			ssif_inc_stat(ssif_info, send_errors);
-
-			if (ssif_info->ssif_debug & SSIF_DEBUG_MSG)
-				dev_dbg(&ssif_info->client->dev,
-					"Error from i2c_non_blocking_op(3)\n");
-			msg_done_handler(ssif_info, -EIO, NULL, 0);
-		}
+		ssif_i2c_send(ssif_info, msg_written_handler,
+			  I2C_SMBUS_WRITE, cmd,
+			  data_to_send, I2C_SMBUS_BLOCK_DATA);
 	} else {
 		/* Ready to request the result. */
 		unsigned long oflags, *flags;
@@ -1033,9 +1000,8 @@
 	}
 }
 
-static int start_resend(struct ssif_info *ssif_info)
+static void start_resend(struct ssif_info *ssif_info)
 {
-	int rv;
 	int command;
 
 	ssif_info->got_alert = false;
@@ -1057,12 +1023,8 @@
 		ssif_info->data[0] = ssif_info->data_len;
 	}
 
-	rv = ssif_i2c_send(ssif_info, msg_written_handler, I2C_SMBUS_WRITE,
-			  command, ssif_info->data, I2C_SMBUS_BLOCK_DATA);
-	if (rv && (ssif_info->ssif_debug & SSIF_DEBUG_MSG))
-		dev_dbg(&ssif_info->client->dev,
-			"Error from i2c_non_blocking_op(4)\n");
-	return rv;
+	ssif_i2c_send(ssif_info, msg_written_handler, I2C_SMBUS_WRITE,
+		   command, ssif_info->data, I2C_SMBUS_BLOCK_DATA);
 }
 
 static int start_send(struct ssif_info *ssif_info,
@@ -1077,7 +1039,8 @@
 	ssif_info->retries_left = SSIF_SEND_RETRIES;
 	memcpy(ssif_info->data + 1, data, len);
 	ssif_info->data_len = len;
-	return start_resend(ssif_info);
+	start_resend(ssif_info);
+	return 0;
 }
 
 /* Must be called with the message lock held. */
@@ -1087,7 +1050,7 @@
 	unsigned long oflags;
 
  restart:
-	if (!SSIF_IDLE(ssif_info)) {
+	if (!IS_SSIF_IDLE(ssif_info)) {
 		ipmi_ssif_unlock_cond(ssif_info, flags);
 		return;
 	}
@@ -1310,7 +1273,7 @@
 	dev_set_drvdata(&ssif_info->client->dev, NULL);
 
 	/* make sure the driver is not looking for flags any more. */
-	while (ssif_info->ssif_state != SSIF_NORMAL)
+	while (ssif_info->ssif_state != SSIF_IDLE)
 		schedule_timeout(1);
 
 	ssif_info->stopping = true;
@@ -1377,8 +1340,10 @@
 	ret = i2c_smbus_write_block_data(client, SSIF_IPMI_REQUEST, len, msg);
 	if (ret) {
 		retry_cnt--;
-		if (retry_cnt > 0)
+		if (retry_cnt > 0) {
+			msleep(SSIF_REQ_RETRY_MSEC);
 			goto retry1;
+		}
 		return -ENODEV;
 	}
 
@@ -1449,7 +1414,7 @@
 restart:
 	list_for_each_entry(info, &ssif_infos, link) {
 		if (info->binfo.addr == addr) {
-			if (info->addr_src == SI_SMBIOS)
+			if (info->addr_src == SI_SMBIOS && !info->adapter_name)
 				info->adapter_name = kstrdup(adapter_name,
 							     GFP_KERNEL);
 
@@ -1519,8 +1484,10 @@
 					 32, msg);
 	if (ret) {
 		retry_cnt--;
-		if (retry_cnt > 0)
+		if (retry_cnt > 0) {
+			msleep(SSIF_REQ_RETRY_MSEC);
 			goto retry_write;
+		}
 		dev_err(&client->dev, "Could not write multi-part start, though the BMC said it could handle it.  Just limit sends to one part.\n");
 		return ret;
 	}
@@ -1647,6 +1614,11 @@
 	info->addr_src = SI_ACPI;
 	info->client = client;
 	info->adapter_name = kstrdup(client->adapter->name, GFP_KERNEL);
+	if (!info->adapter_name) {
+		kfree(info);
+		return -ENOMEM;
+	}
+
 	info->binfo.addr = client->addr;
 	list_add_tail(&info->link, &ssif_infos);
 	return 0;
@@ -1882,7 +1854,7 @@
 	}
 
 	spin_lock_init(&ssif_info->lock);
-	ssif_info->ssif_state = SSIF_NORMAL;
+	ssif_info->ssif_state = SSIF_IDLE;
 	timer_setup(&ssif_info->retry_timer, retry_timeout, 0);
 	timer_setup(&ssif_info->watch_timer, watch_timeout, 0);
 
diff --git a/kernel/drivers/char/ipmi/ipmi_watchdog.c b/kernel/drivers/char/ipmi/ipmi_watchdog.c
index 92eda5b..883b4a3 100644
--- a/kernel/drivers/char/ipmi/ipmi_watchdog.c
+++ b/kernel/drivers/char/ipmi/ipmi_watchdog.c
@@ -503,7 +503,7 @@
 	msg.cmd = IPMI_WDOG_RESET_TIMER;
 	msg.data = NULL;
 	msg.data_len = 0;
-	atomic_add(1, &panic_done_count);
+	atomic_add(2, &panic_done_count);
 	rv = ipmi_request_supply_msgs(watchdog_user,
 				      (struct ipmi_addr *) &addr,
 				      0,
@@ -513,7 +513,7 @@
 				      &panic_halt_heartbeat_recv_msg,
 				      1);
 	if (rv)
-		atomic_sub(1, &panic_done_count);
+		atomic_sub(2, &panic_done_count);
 }
 
 static struct ipmi_smi_msg panic_halt_smi_msg = {
@@ -537,12 +537,12 @@
 	/* Wait for the messages to be free. */
 	while (atomic_read(&panic_done_count) != 0)
 		ipmi_poll_interface(watchdog_user);
-	atomic_add(1, &panic_done_count);
+	atomic_add(2, &panic_done_count);
 	rv = __ipmi_set_timeout(&panic_halt_smi_msg,
 				&panic_halt_recv_msg,
 				&send_heartbeat_now);
 	if (rv) {
-		atomic_sub(1, &panic_done_count);
+		atomic_sub(2, &panic_done_count);
 		pr_warn("Unable to extend the watchdog timeout\n");
 	} else {
 		if (send_heartbeat_now)
diff --git a/kernel/drivers/char/tpm/eventlog/acpi.c b/kernel/drivers/char/tpm/eventlog/acpi.c
index 1b18ce5..cd26602 100644
--- a/kernel/drivers/char/tpm/eventlog/acpi.c
+++ b/kernel/drivers/char/tpm/eventlog/acpi.c
@@ -90,16 +90,21 @@
 			return -ENODEV;
 
 		if (tbl->header.length <
-				sizeof(*tbl) + sizeof(struct acpi_tpm2_phy))
+				sizeof(*tbl) + sizeof(struct acpi_tpm2_phy)) {
+			acpi_put_table((struct acpi_table_header *)tbl);
 			return -ENODEV;
+		}
 
 		tpm2_phy = (void *)tbl + sizeof(*tbl);
 		len = tpm2_phy->log_area_minimum_length;
 
 		start = tpm2_phy->log_area_start_address;
-		if (!start || !len)
+		if (!start || !len) {
+			acpi_put_table((struct acpi_table_header *)tbl);
 			return -ENODEV;
+		}
 
+		acpi_put_table((struct acpi_table_header *)tbl);
 		format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
 	} else {
 		/* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
@@ -120,8 +125,10 @@
 			break;
 		}
 
+		acpi_put_table((struct acpi_table_header *)buff);
 		format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
 	}
+
 	if (!len) {
 		dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__);
 		return -EIO;
@@ -136,8 +143,12 @@
 
 	ret = -EIO;
 	virt = acpi_os_map_iomem(start, len);
-	if (!virt)
+	if (!virt) {
+		dev_warn(&chip->dev, "%s: Failed to map ACPI memory\n", __func__);
+		/* try EFI log next */
+		ret = -ENODEV;
 		goto err;
+	}
 
 	memcpy_fromio(log->bios_event_log, virt, len);
 
@@ -156,5 +167,4 @@
 	kfree(log->bios_event_log);
 	log->bios_event_log = NULL;
 	return ret;
-
 }
diff --git a/kernel/drivers/char/tpm/tpm_crb.c b/kernel/drivers/char/tpm/tpm_crb.c
index a9dcf31..5fe52a6 100644
--- a/kernel/drivers/char/tpm/tpm_crb.c
+++ b/kernel/drivers/char/tpm/tpm_crb.c
@@ -252,7 +252,7 @@
 	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;
 	}
 
@@ -676,12 +676,16 @@
 
 	/* Should the FIFO driver handle this? */
 	sm = buf->start_method;
-	if (sm == ACPI_TPM2_MEMORY_MAPPED)
-		return -ENODEV;
+	if (sm == ACPI_TPM2_MEMORY_MAPPED) {
+		rc = -ENODEV;
+		goto out;
+	}
 
 	priv = devm_kzalloc(dev, sizeof(struct crb_priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
+	if (!priv) {
+		rc = -ENOMEM;
+		goto out;
+	}
 
 	if (sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) {
 		if (buf->header.length < (sizeof(*buf) + sizeof(*crb_smc))) {
@@ -689,7 +693,8 @@
 				FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n",
 				buf->header.length,
 				ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC);
-			return -EINVAL;
+			rc = -EINVAL;
+			goto out;
 		}
 		crb_smc = ACPI_ADD_PTR(struct tpm2_crb_smc, buf, sizeof(*buf));
 		priv->smc_func_id = crb_smc->smc_func_id;
@@ -700,17 +705,23 @@
 
 	rc = crb_map_io(device, priv, buf);
 	if (rc)
-		return rc;
+		goto out;
 
 	chip = tpmm_chip_alloc(dev, &tpm_crb);
-	if (IS_ERR(chip))
-		return PTR_ERR(chip);
+	if (IS_ERR(chip)) {
+		rc = PTR_ERR(chip);
+		goto out;
+	}
 
 	dev_set_drvdata(&chip->dev, priv);
 	chip->acpi_dev_handle = device->handle;
 	chip->flags = TPM_CHIP_FLAG_TPM2;
 
-	return tpm_chip_register(chip);
+	rc = tpm_chip_register(chip);
+
+out:
+	acpi_put_table((struct acpi_table_header *)buf);
+	return rc;
 }
 
 static int crb_acpi_remove(struct acpi_device *device)
diff --git a/kernel/drivers/char/tpm/tpm_ftpm_tee.c b/kernel/drivers/char/tpm/tpm_ftpm_tee.c
index 6e32355..d9daaaf 100644
--- a/kernel/drivers/char/tpm/tpm_ftpm_tee.c
+++ b/kernel/drivers/char/tpm/tpm_ftpm_tee.c
@@ -397,7 +397,13 @@
 	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)
diff --git a/kernel/drivers/char/tpm/tpm_tis.c b/kernel/drivers/char/tpm/tpm_tis.c
index 4ed6e66..3e1bb28 100644
--- a/kernel/drivers/char/tpm/tpm_tis.c
+++ b/kernel/drivers/char/tpm/tpm_tis.c
@@ -83,6 +83,22 @@
 			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T490s"),
 		},
 	},
+	{
+		.callback = tpm_tis_disable_irq,
+		.ident = "ThinkStation P360 Tiny",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkStation P360 Tiny"),
+		},
+	},
+	{
+		.callback = tpm_tis_disable_irq,
+		.ident = "ThinkPad L490",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L490"),
+		},
+	},
 	{}
 };
 
@@ -125,6 +141,7 @@
 	const struct acpi_device_id *aid = acpi_match_device(tpm_acpi_tbl, dev);
 	struct acpi_table_tpm2 *tbl;
 	acpi_status st;
+	int ret = 0;
 
 	if (!aid || aid->driver_data != DEVICE_IS_TPM2)
 		return 0;
@@ -132,8 +149,7 @@
 	/* If the ACPI TPM2 signature is matched then a global ACPI_SIG_TPM2
 	 * table is mandatory
 	 */
-	st =
-	    acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **)&tbl);
+	st = acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **)&tbl);
 	if (ACPI_FAILURE(st) || tbl->header.length < sizeof(*tbl)) {
 		dev_err(dev, FW_BUG "failed to get TPM2 ACPI table\n");
 		return -EINVAL;
@@ -141,9 +157,10 @@
 
 	/* The tpm2_crb driver handles this device */
 	if (tbl->start_method != ACPI_TPM2_MEMORY_MAPPED)
-		return -ENODEV;
+		ret = -ENODEV;
 
-	return 0;
+	acpi_put_table((struct acpi_table_header *)tbl);
+	return ret;
 }
 #else
 static int check_acpi_tpm2(struct device *dev)
diff --git a/kernel/drivers/char/tpm/tpm_tis_core.c b/kernel/drivers/char/tpm/tpm_tis_core.c
index dc56b97..b345225 100644
--- a/kernel/drivers/char/tpm/tpm_tis_core.c
+++ b/kernel/drivers/char/tpm/tpm_tis_core.c
@@ -136,16 +136,27 @@
 	return false;
 }
 
-static int release_locality(struct tpm_chip *chip, int l)
+static int __tpm_tis_relinquish_locality(struct tpm_tis_data *priv, int l)
 {
-	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
-
 	tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
 
 	return 0;
 }
 
-static int request_locality(struct tpm_chip *chip, int l)
+static int tpm_tis_relinquish_locality(struct tpm_chip *chip, int l)
+{
+	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+
+	mutex_lock(&priv->locality_count_mutex);
+	priv->locality_count--;
+	if (priv->locality_count == 0)
+		__tpm_tis_relinquish_locality(priv, l);
+	mutex_unlock(&priv->locality_count_mutex);
+
+	return 0;
+}
+
+static int __tpm_tis_request_locality(struct tpm_chip *chip, int l)
 {
 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
 	unsigned long stop, timeout;
@@ -184,6 +195,20 @@
 		} while (time_before(jiffies, stop));
 	}
 	return -1;
+}
+
+static int tpm_tis_request_locality(struct tpm_chip *chip, int l)
+{
+	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+	int ret = 0;
+
+	mutex_lock(&priv->locality_count_mutex);
+	if (priv->locality_count == 0)
+		ret = __tpm_tis_request_locality(chip, l);
+	if (!ret)
+		priv->locality_count++;
+	mutex_unlock(&priv->locality_count_mutex);
+	return ret;
 }
 
 static u8 tpm_tis_status(struct tpm_chip *chip)
@@ -289,6 +314,7 @@
 	int size = 0;
 	int status;
 	u32 expected;
+	int rc;
 
 	if (count < TPM_HEADER_SIZE) {
 		size = -EIO;
@@ -308,8 +334,13 @@
 		goto out;
 	}
 
-	size += recv_data(chip, &buf[TPM_HEADER_SIZE],
-			  expected - TPM_HEADER_SIZE);
+	rc = recv_data(chip, &buf[TPM_HEADER_SIZE],
+		       expected - TPM_HEADER_SIZE);
+	if (rc < 0) {
+		size = rc;
+		goto out;
+	}
+	size += rc;
 	if (size < expected) {
 		dev_err(&chip->dev, "Unable to read remainder of result\n");
 		size = -ETIME;
@@ -438,10 +469,17 @@
 	int rc;
 	u32 ordinal;
 	unsigned long dur;
+	unsigned int try;
 
-	rc = tpm_tis_send_data(chip, buf, len);
-	if (rc < 0)
-		return rc;
+	for (try = 0; try < TPM_RETRY; try++) {
+		rc = tpm_tis_send_data(chip, buf, len);
+		if (rc >= 0)
+			/* Data transfer done successfully */
+			break;
+		else if (rc != -EIO)
+			/* Data transfer failed, not recoverable */
+			return rc;
+	}
 
 	/* go and do it */
 	rc = tpm_tis_write8(priv, TPM_STS(priv->locality), TPM_STS_GO);
@@ -638,7 +676,7 @@
 	if (vendor != TPM_VID_INTEL)
 		return 0;
 
-	if (request_locality(chip, 0) != 0)
+	if (tpm_tis_request_locality(chip, 0) != 0)
 		return -EBUSY;
 
 	rc = tpm_tis_send_data(chip, cmd_getticks, len);
@@ -659,7 +697,7 @@
 
 out:
 	tpm_tis_ready(chip);
-	release_locality(chip, priv->locality);
+	tpm_tis_relinquish_locality(chip, priv->locality);
 
 	return rc;
 }
@@ -706,7 +744,9 @@
 		wake_up_interruptible(&priv->int_queue);
 
 	/* Clear interrupts handled with TPM_EOI */
+	tpm_tis_request_locality(chip, 0);
 	rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), interrupt);
+	tpm_tis_relinquish_locality(chip, 0);
 	if (rc < 0)
 		return IRQ_NONE;
 
@@ -714,25 +754,17 @@
 	return IRQ_HANDLED;
 }
 
-static int tpm_tis_gen_interrupt(struct tpm_chip *chip)
+static void tpm_tis_gen_interrupt(struct tpm_chip *chip)
 {
 	const char *desc = "attempting to generate an interrupt";
 	u32 cap2;
 	cap_t cap;
 	int ret;
 
-	ret = request_locality(chip, 0);
-	if (ret < 0)
-		return ret;
-
 	if (chip->flags & TPM_CHIP_FLAG_TPM2)
 		ret = tpm2_get_tpm_pt(chip, 0x100, &cap2, desc);
 	else
 		ret = tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, 0);
-
-	release_locality(chip, 0);
-
-	return ret;
 }
 
 /* Register the IRQ and issue a command that will cause an interrupt. If an
@@ -747,60 +779,66 @@
 	int rc;
 	u32 int_status;
 
-	if (devm_request_irq(chip->dev.parent, irq, tis_int_handler, flags,
-			     dev_name(&chip->dev), chip) != 0) {
+
+	rc = devm_request_threaded_irq(chip->dev.parent, irq, NULL,
+				       tis_int_handler, IRQF_ONESHOT | flags,
+				       dev_name(&chip->dev), chip);
+	if (rc) {
 		dev_info(&chip->dev, "Unable to request irq: %d for probe\n",
 			 irq);
 		return -1;
 	}
 	priv->irq = irq;
 
-	rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality),
-			   &original_int_vec);
+	rc = tpm_tis_request_locality(chip, 0);
 	if (rc < 0)
 		return rc;
+
+	rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality),
+			   &original_int_vec);
+	if (rc < 0) {
+		tpm_tis_relinquish_locality(chip, priv->locality);
+		return rc;
+	}
 
 	rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), irq);
 	if (rc < 0)
-		return rc;
+		goto restore_irqs;
 
 	rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status);
 	if (rc < 0)
-		return rc;
+		goto restore_irqs;
 
 	/* Clear all existing */
 	rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status);
 	if (rc < 0)
-		return rc;
-
+		goto restore_irqs;
 	/* Turn on */
 	rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality),
 			     intmask | TPM_GLOBAL_INT_ENABLE);
 	if (rc < 0)
-		return rc;
+		goto restore_irqs;
 
 	priv->irq_tested = false;
 
 	/* Generate an interrupt by having the core call through to
 	 * tpm_tis_send
 	 */
-	rc = tpm_tis_gen_interrupt(chip);
-	if (rc < 0)
-		return rc;
+	tpm_tis_gen_interrupt(chip);
 
+restore_irqs:
 	/* tpm_tis_send will either confirm the interrupt is working or it
 	 * will call disable_irq which undoes all of the above.
 	 */
 	if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
-		rc = tpm_tis_write8(priv, original_int_vec,
-				TPM_INT_VECTOR(priv->locality));
-		if (rc < 0)
-			return rc;
-
-		return 1;
+		tpm_tis_write8(priv, original_int_vec,
+			       TPM_INT_VECTOR(priv->locality));
+		rc = -1;
 	}
 
-	return 0;
+	tpm_tis_relinquish_locality(chip, priv->locality);
+
+	return rc;
 }
 
 /* Try to find the IRQ the TPM is using. This is for legacy x86 systems that
@@ -914,8 +952,8 @@
 	.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 	.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 	.req_canceled = tpm_tis_req_canceled,
-	.request_locality = request_locality,
-	.relinquish_locality = release_locality,
+	.request_locality = tpm_tis_request_locality,
+	.relinquish_locality = tpm_tis_relinquish_locality,
 	.clk_enable = tpm_tis_clkrun_enable,
 };
 
@@ -949,6 +987,8 @@
 	priv->timeout_min = TPM_TIMEOUT_USECS_MIN;
 	priv->timeout_max = TPM_TIMEOUT_USECS_MAX;
 	priv->phy_ops = phy_ops;
+	priv->locality_count = 0;
+	mutex_init(&priv->locality_count_mutex);
 
 	dev_set_drvdata(&chip->dev, priv);
 
@@ -995,14 +1035,14 @@
 		   TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT;
 	intmask &= ~TPM_GLOBAL_INT_ENABLE;
 
-	rc = request_locality(chip, 0);
+	rc = tpm_tis_request_locality(chip, 0);
 	if (rc < 0) {
 		rc = -ENODEV;
 		goto out_err;
 	}
 
 	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
-	release_locality(chip, 0);
+	tpm_tis_relinquish_locality(chip, 0);
 
 	rc = tpm_chip_start(chip);
 	if (rc)
@@ -1062,13 +1102,13 @@
 		 * proper timeouts for the driver.
 		 */
 
-		rc = request_locality(chip, 0);
+		rc = tpm_tis_request_locality(chip, 0);
 		if (rc < 0)
 			goto out_err;
 
 		rc = tpm_get_timeouts(chip);
 
-		release_locality(chip, 0);
+		tpm_tis_relinquish_locality(chip, 0);
 
 		if (rc) {
 			dev_err(dev, "Could not get TPM timeouts and durations\n");
@@ -1076,17 +1116,21 @@
 			goto out_err;
 		}
 
-		if (irq) {
+		if (irq)
 			tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
 						 irq);
-			if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
-				dev_err(&chip->dev, FW_BUG
+		else
+			tpm_tis_probe_irq(chip, intmask);
+
+		if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
+			dev_err(&chip->dev, FW_BUG
 					"TPM interrupt not working, polling instead\n");
 
-				disable_interrupts(chip);
-			}
-		} else {
-			tpm_tis_probe_irq(chip, intmask);
+			rc = tpm_tis_request_locality(chip, 0);
+			if (rc < 0)
+				goto out_err;
+			disable_interrupts(chip);
+			tpm_tis_relinquish_locality(chip, 0);
 		}
 	}
 
@@ -1147,28 +1191,27 @@
 	struct tpm_chip *chip = dev_get_drvdata(dev);
 	int ret;
 
+	ret = tpm_tis_request_locality(chip, 0);
+	if (ret < 0)
+		return ret;
+
 	if (chip->flags & TPM_CHIP_FLAG_IRQ)
 		tpm_tis_reenable_interrupts(chip);
 
 	ret = tpm_pm_resume(dev);
 	if (ret)
-		return ret;
+		goto out;
 
 	/*
 	 * TPM 1.2 requires self-test on resume. This function actually returns
 	 * an error code but for unknown reason it isn't handled.
 	 */
-	if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
-		ret = request_locality(chip, 0);
-		if (ret < 0)
-			return ret;
-
+	if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
 		tpm1_do_selftest(chip);
+out:
+	tpm_tis_relinquish_locality(chip, 0);
 
-		release_locality(chip, 0);
-	}
-
-	return 0;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(tpm_tis_resume);
 #endif
diff --git a/kernel/drivers/char/tpm/tpm_tis_core.h b/kernel/drivers/char/tpm/tpm_tis_core.h
index 3be24f2..464ed35 100644
--- a/kernel/drivers/char/tpm/tpm_tis_core.h
+++ b/kernel/drivers/char/tpm/tpm_tis_core.h
@@ -90,6 +90,8 @@
 
 struct tpm_tis_data {
 	u16 manufacturer_id;
+	struct mutex locality_count_mutex;
+	unsigned int locality_count;
 	int locality;
 	int irq;
 	bool irq_tested;
diff --git a/kernel/drivers/char/tpm/tpm_vtpm_proxy.c b/kernel/drivers/char/tpm/tpm_vtpm_proxy.c
index 91c772e..ff2ec71 100644
--- a/kernel/drivers/char/tpm/tpm_vtpm_proxy.c
+++ b/kernel/drivers/char/tpm/tpm_vtpm_proxy.c
@@ -683,37 +683,21 @@
 	.fops = &vtpmx_fops,
 };
 
-static int vtpmx_init(void)
-{
-	return misc_register(&vtpmx_miscdev);
-}
-
-static void vtpmx_cleanup(void)
-{
-	misc_deregister(&vtpmx_miscdev);
-}
-
 static int __init vtpm_module_init(void)
 {
 	int rc;
 
-	rc = vtpmx_init();
-	if (rc) {
-		pr_err("couldn't create vtpmx device\n");
-		return rc;
-	}
-
 	workqueue = create_workqueue("tpm-vtpm");
 	if (!workqueue) {
 		pr_err("couldn't create workqueue\n");
-		rc = -ENOMEM;
-		goto err_vtpmx_cleanup;
+		return -ENOMEM;
 	}
 
-	return 0;
-
-err_vtpmx_cleanup:
-	vtpmx_cleanup();
+	rc = misc_register(&vtpmx_miscdev);
+	if (rc) {
+		pr_err("couldn't create vtpmx device\n");
+		destroy_workqueue(workqueue);
+	}
 
 	return rc;
 }
@@ -721,7 +705,7 @@
 static void __exit vtpm_module_exit(void)
 {
 	destroy_workqueue(workqueue);
-	vtpmx_cleanup();
+	misc_deregister(&vtpmx_miscdev);
 }
 
 module_init(vtpm_module_init);
diff --git a/kernel/drivers/clk/Kconfig b/kernel/drivers/clk/Kconfig
index 42bb63d..1422352 100644
--- a/kernel/drivers/clk/Kconfig
+++ b/kernel/drivers/clk/Kconfig
@@ -86,7 +86,7 @@
 config COMMON_CLK_HI655X
 	tristate "Clock driver for Hi655x" if EXPERT
 	depends on (MFD_HI655X_PMIC || COMPILE_TEST)
-	depends on REGMAP
+	select REGMAP
 	default MFD_HI655X_PMIC
 	help
 	  This driver supports the hi655x PMIC clock. This
@@ -363,6 +363,7 @@
 config COMMON_CLK_FIXED_MMIO
 	bool "Clock driver for Memory Mapped Fixed values"
 	depends on COMMON_CLK && OF
+	depends on HAS_IOMEM
 	help
 	  Support for Memory Mapped IO Fixed clocks
 
diff --git a/kernel/drivers/clk/at91/clk-sam9x60-pll.c b/kernel/drivers/clk/at91/clk-sam9x60-pll.c
index 5a9daa3..5fe50ba 100644
--- a/kernel/drivers/clk/at91/clk-sam9x60-pll.c
+++ b/kernel/drivers/clk/at91/clk-sam9x60-pll.c
@@ -452,7 +452,7 @@
 
 		ret = sam9x60_frac_pll_compute_mul_frac(&frac->core, FCORE_MIN,
 							parent_rate, true);
-		if (ret <= 0) {
+		if (ret < 0) {
 			hw = ERR_PTR(ret);
 			goto free;
 		}
diff --git a/kernel/drivers/clk/clk-cdce925.c b/kernel/drivers/clk/clk-cdce925.c
index 308b353..470d91d 100644
--- a/kernel/drivers/clk/clk-cdce925.c
+++ b/kernel/drivers/clk/clk-cdce925.c
@@ -705,6 +705,10 @@
 	for (i = 0; i < data->chip_info->num_plls; ++i) {
 		pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d",
 			client->dev.of_node, i);
+		if (!pll_clk_name[i]) {
+			err = -ENOMEM;
+			goto error;
+		}
 		init.name = pll_clk_name[i];
 		data->pll[i].chip = data;
 		data->pll[i].hw.init = &init;
@@ -746,6 +750,10 @@
 	init.num_parents = 1;
 	init.parent_names = &parent_name; /* Mux Y1 to input */
 	init.name = kasprintf(GFP_KERNEL, "%pOFn.Y1", client->dev.of_node);
+	if (!init.name) {
+		err = -ENOMEM;
+		goto error;
+	}
 	data->clk[0].chip = data;
 	data->clk[0].hw.init = &init;
 	data->clk[0].index = 0;
@@ -764,6 +772,10 @@
 	for (i = 1; i < data->chip_info->num_outputs; ++i) {
 		init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d",
 			client->dev.of_node, i+1);
+		if (!init.name) {
+			err = -ENOMEM;
+			goto error;
+		}
 		data->clk[i].chip = data;
 		data->clk[i].hw.init = &init;
 		data->clk[i].index = i;
diff --git a/kernel/drivers/clk/clk-conf.c b/kernel/drivers/clk/clk-conf.c
index 2ef8196..1a4e634 100644
--- a/kernel/drivers/clk/clk-conf.c
+++ b/kernel/drivers/clk/clk-conf.c
@@ -33,9 +33,12 @@
 			else
 				return rc;
 		}
-		if (clkspec.np == node && !clk_supplier)
+		if (clkspec.np == node && !clk_supplier) {
+			of_node_put(clkspec.np);
 			return 0;
+		}
 		pclk = of_clk_get_from_provider(&clkspec);
+		of_node_put(clkspec.np);
 		if (IS_ERR(pclk)) {
 			if (PTR_ERR(pclk) != -EPROBE_DEFER)
 				pr_warn("clk: couldn't get parent clock %d for %pOF\n",
@@ -48,10 +51,12 @@
 		if (rc < 0)
 			goto err;
 		if (clkspec.np == node && !clk_supplier) {
+			of_node_put(clkspec.np);
 			rc = 0;
 			goto err;
 		}
 		clk = of_clk_get_from_provider(&clkspec);
+		of_node_put(clkspec.np);
 		if (IS_ERR(clk)) {
 			if (PTR_ERR(clk) != -EPROBE_DEFER)
 				pr_warn("clk: couldn't get assigned clock %d for %pOF\n",
@@ -93,10 +98,13 @@
 				else
 					return rc;
 			}
-			if (clkspec.np == node && !clk_supplier)
+			if (clkspec.np == node && !clk_supplier) {
+				of_node_put(clkspec.np);
 				return 0;
+			}
 
 			clk = of_clk_get_from_provider(&clkspec);
+			of_node_put(clkspec.np);
 			if (IS_ERR(clk)) {
 				if (PTR_ERR(clk) != -EPROBE_DEFER)
 					pr_warn("clk: couldn't get clock %d for %pOF\n",
diff --git a/kernel/drivers/clk/clk-devres.c b/kernel/drivers/clk/clk-devres.c
index f9d5b73..737aa70 100644
--- a/kernel/drivers/clk/clk-devres.c
+++ b/kernel/drivers/clk/clk-devres.c
@@ -4,41 +4,100 @@
 #include <linux/export.h>
 #include <linux/gfp.h>
 
+struct devm_clk_state {
+	struct clk *clk;
+	void (*exit)(struct clk *clk);
+};
+
 static void devm_clk_release(struct device *dev, void *res)
 {
-	clk_put(*(struct clk **)res);
+	struct devm_clk_state *state = res;
+
+	if (state->exit)
+		state->exit(state->clk);
+
+	clk_put(state->clk);
+}
+
+static struct clk *__devm_clk_get(struct device *dev, const char *id,
+				  struct clk *(*get)(struct device *dev, const char *id),
+				  int (*init)(struct clk *clk),
+				  void (*exit)(struct clk *clk))
+{
+	struct devm_clk_state *state;
+	struct clk *clk;
+	int ret;
+
+	state = devres_alloc(devm_clk_release, sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return ERR_PTR(-ENOMEM);
+
+	clk = get(dev, id);
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		goto err_clk_get;
+	}
+
+	if (init) {
+		ret = init(clk);
+		if (ret)
+			goto err_clk_init;
+	}
+
+	state->clk = clk;
+	state->exit = exit;
+
+	devres_add(dev, state);
+
+	return clk;
+
+err_clk_init:
+
+	clk_put(clk);
+err_clk_get:
+
+	devres_free(state);
+	return ERR_PTR(ret);
 }
 
 struct clk *devm_clk_get(struct device *dev, const char *id)
 {
-	struct clk **ptr, *clk;
-
-	ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
-	if (!ptr)
-		return ERR_PTR(-ENOMEM);
-
-	clk = clk_get(dev, id);
-	if (!IS_ERR(clk)) {
-		*ptr = clk;
-		devres_add(dev, ptr);
-	} else {
-		devres_free(ptr);
-	}
-
-	return clk;
+	return __devm_clk_get(dev, id, clk_get, NULL, NULL);
 }
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_prepared(struct device *dev, const char *id)
+{
+	return __devm_clk_get(dev, id, clk_get, clk_prepare, clk_unprepare);
+}
+EXPORT_SYMBOL_GPL(devm_clk_get_prepared);
+
+struct clk *devm_clk_get_enabled(struct device *dev, const char *id)
+{
+	return __devm_clk_get(dev, id, clk_get,
+			      clk_prepare_enable, clk_disable_unprepare);
+}
+EXPORT_SYMBOL_GPL(devm_clk_get_enabled);
+
 struct clk *devm_clk_get_optional(struct device *dev, const char *id)
 {
-	struct clk *clk = devm_clk_get(dev, id);
-
-	if (clk == ERR_PTR(-ENOENT))
-		return NULL;
-
-	return clk;
+	return __devm_clk_get(dev, id, clk_get_optional, NULL, NULL);
 }
 EXPORT_SYMBOL(devm_clk_get_optional);
+
+struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id)
+{
+	return __devm_clk_get(dev, id, clk_get_optional,
+			      clk_prepare, clk_unprepare);
+}
+EXPORT_SYMBOL_GPL(devm_clk_get_optional_prepared);
+
+struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id)
+{
+	return __devm_clk_get(dev, id, clk_get_optional,
+			      clk_prepare_enable, clk_disable_unprepare);
+}
+EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled);
 
 struct clk_bulk_devres {
 	struct clk_bulk_data *clks;
@@ -146,18 +205,19 @@
 struct clk *devm_get_clk_from_child(struct device *dev,
 				    struct device_node *np, const char *con_id)
 {
-	struct clk **ptr, *clk;
+	struct devm_clk_state *state;
+	struct clk *clk;
 
-	ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
-	if (!ptr)
+	state = devres_alloc(devm_clk_release, sizeof(*state), GFP_KERNEL);
+	if (!state)
 		return ERR_PTR(-ENOMEM);
 
 	clk = of_clk_get_by_name(np, con_id);
 	if (!IS_ERR(clk)) {
-		*ptr = clk;
-		devres_add(dev, ptr);
+		state->clk = clk;
+		devres_add(dev, state);
 	} else {
-		devres_free(ptr);
+		devres_free(state);
 	}
 
 	return clk;
diff --git a/kernel/drivers/clk/clk-si5341.c b/kernel/drivers/clk/clk-si5341.c
index 382a061..4dea29f 100644
--- a/kernel/drivers/clk/clk-si5341.c
+++ b/kernel/drivers/clk/clk-si5341.c
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <asm/unaligned.h>
 
@@ -59,6 +60,7 @@
 struct clk_si5341_output {
 	struct clk_hw hw;
 	struct clk_si5341 *data;
+	struct regulator *vddo_reg;
 	u8 index;
 };
 #define to_clk_si5341_output(_hw) \
@@ -84,6 +86,7 @@
 struct clk_si5341_output_config {
 	u8 out_format_drv_bits;
 	u8 out_cm_ampl_bits;
+	u8 vdd_sel_bits;
 	bool synth_master;
 	bool always_on;
 };
@@ -135,6 +138,8 @@
 #define SI5341_OUT_MUX_SEL(output)	(SI5341_OUT_CONFIG(output) + 3)
 #define SI5341_OUT_R_REG(output)	\
 			((output)->data->reg_rdiv_offset[(output)->index])
+
+#define SI5341_OUT_MUX_VDD_SEL_MASK 0x38
 
 /* Synthesize N divider */
 #define SI5341_SYNTH_N_NUM(x)	(0x0302 + ((x) * 11))
@@ -1250,11 +1255,11 @@
 	.volatile_table = &si5341_regmap_volatile,
 };
 
-static int si5341_dt_parse_dt(struct i2c_client *client,
-	struct clk_si5341_output_config *config)
+static int si5341_dt_parse_dt(struct clk_si5341 *data,
+			      struct clk_si5341_output_config *config)
 {
 	struct device_node *child;
-	struct device_node *np = client->dev.of_node;
+	struct device_node *np = data->i2c_client->dev.of_node;
 	u32 num;
 	u32 val;
 
@@ -1263,13 +1268,13 @@
 
 	for_each_child_of_node(np, child) {
 		if (of_property_read_u32(child, "reg", &num)) {
-			dev_err(&client->dev, "missing reg property of %s\n",
+			dev_err(&data->i2c_client->dev, "missing reg property of %s\n",
 				child->name);
 			goto put_child;
 		}
 
 		if (num >= SI5341_MAX_NUM_OUTPUTS) {
-			dev_err(&client->dev, "invalid clkout %d\n", num);
+			dev_err(&data->i2c_client->dev, "invalid clkout %d\n", num);
 			goto put_child;
 		}
 
@@ -1288,7 +1293,7 @@
 				config[num].out_format_drv_bits |= 0xc0;
 				break;
 			default:
-				dev_err(&client->dev,
+				dev_err(&data->i2c_client->dev,
 					"invalid silabs,format %u for %u\n",
 					val, num);
 				goto put_child;
@@ -1301,7 +1306,7 @@
 
 		if (!of_property_read_u32(child, "silabs,common-mode", &val)) {
 			if (val > 0xf) {
-				dev_err(&client->dev,
+				dev_err(&data->i2c_client->dev,
 					"invalid silabs,common-mode %u\n",
 					val);
 				goto put_child;
@@ -1312,7 +1317,7 @@
 
 		if (!of_property_read_u32(child, "silabs,amplitude", &val)) {
 			if (val > 0xf) {
-				dev_err(&client->dev,
+				dev_err(&data->i2c_client->dev,
 					"invalid silabs,amplitude %u\n",
 					val);
 				goto put_child;
@@ -1329,6 +1334,34 @@
 
 		config[num].always_on =
 			of_property_read_bool(child, "always-on");
+
+		config[num].vdd_sel_bits = 0x08;
+		if (data->clk[num].vddo_reg) {
+			int vdd = regulator_get_voltage(data->clk[num].vddo_reg);
+
+			switch (vdd) {
+			case 3300000:
+				config[num].vdd_sel_bits |= 0 << 4;
+				break;
+			case 1800000:
+				config[num].vdd_sel_bits |= 1 << 4;
+				break;
+			case 2500000:
+				config[num].vdd_sel_bits |= 2 << 4;
+				break;
+			default:
+				dev_err(&data->i2c_client->dev,
+					"unsupported vddo voltage %d for %s\n",
+					vdd, child->name);
+				goto put_child;
+			}
+		} else {
+			/* chip seems to default to 2.5V when not set */
+			dev_warn(&data->i2c_client->dev,
+				"no regulator set, defaulting vdd_sel to 2.5V for %s\n",
+				child->name);
+			config[num].vdd_sel_bits |= 2 << 4;
+		}
 	}
 
 	return 0;
@@ -1417,6 +1450,94 @@
 	return res;
 }
 
+static ssize_t input_present_show(struct device *dev,
+				  struct device_attribute *attr,
+				  char *buf)
+{
+	struct clk_si5341 *data = dev_get_drvdata(dev);
+	u32 status;
+	int res = regmap_read(data->regmap, SI5341_STATUS, &status);
+
+	if (res < 0)
+		return res;
+	res = !(status & SI5341_STATUS_LOSREF);
+	return snprintf(buf, PAGE_SIZE, "%d\n", res);
+}
+static DEVICE_ATTR_RO(input_present);
+
+static ssize_t input_present_sticky_show(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	struct clk_si5341 *data = dev_get_drvdata(dev);
+	u32 status;
+	int res = regmap_read(data->regmap, SI5341_STATUS_STICKY, &status);
+
+	if (res < 0)
+		return res;
+	res = !(status & SI5341_STATUS_LOSREF);
+	return snprintf(buf, PAGE_SIZE, "%d\n", res);
+}
+static DEVICE_ATTR_RO(input_present_sticky);
+
+static ssize_t pll_locked_show(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	struct clk_si5341 *data = dev_get_drvdata(dev);
+	u32 status;
+	int res = regmap_read(data->regmap, SI5341_STATUS, &status);
+
+	if (res < 0)
+		return res;
+	res = !(status & SI5341_STATUS_LOL);
+	return snprintf(buf, PAGE_SIZE, "%d\n", res);
+}
+static DEVICE_ATTR_RO(pll_locked);
+
+static ssize_t pll_locked_sticky_show(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf)
+{
+	struct clk_si5341 *data = dev_get_drvdata(dev);
+	u32 status;
+	int res = regmap_read(data->regmap, SI5341_STATUS_STICKY, &status);
+
+	if (res < 0)
+		return res;
+	res = !(status & SI5341_STATUS_LOL);
+	return snprintf(buf, PAGE_SIZE, "%d\n", res);
+}
+static DEVICE_ATTR_RO(pll_locked_sticky);
+
+static ssize_t clear_sticky_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
+{
+	struct clk_si5341 *data = dev_get_drvdata(dev);
+	long val;
+
+	if (kstrtol(buf, 10, &val))
+		return -EINVAL;
+	if (val) {
+		int res = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0);
+
+		if (res < 0)
+			return res;
+	}
+	return count;
+}
+static DEVICE_ATTR_WO(clear_sticky);
+
+static const struct attribute *si5341_attributes[] = {
+	&dev_attr_input_present.attr,
+	&dev_attr_input_present_sticky.attr,
+	&dev_attr_pll_locked.attr,
+	&dev_attr_pll_locked_sticky.attr,
+	&dev_attr_clear_sticky.attr,
+	NULL
+};
+
 static int si5341_probe(struct i2c_client *client,
 		const struct i2c_device_id *id)
 {
@@ -1424,7 +1545,7 @@
 	struct clk_init_data init;
 	struct clk *input;
 	const char *root_clock_name;
-	const char *synth_clock_names[SI5341_NUM_SYNTH];
+	const char *synth_clock_names[SI5341_NUM_SYNTH] = { NULL };
 	int err;
 	unsigned int i;
 	struct clk_si5341_output_config config[SI5341_MAX_NUM_OUTPUTS];
@@ -1454,9 +1575,33 @@
 		}
 	}
 
-	err = si5341_dt_parse_dt(client, config);
+	for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) {
+		char reg_name[10];
+
+		snprintf(reg_name, sizeof(reg_name), "vddo%d", i);
+		data->clk[i].vddo_reg = devm_regulator_get_optional(
+			&client->dev, reg_name);
+		if (IS_ERR(data->clk[i].vddo_reg)) {
+			err = PTR_ERR(data->clk[i].vddo_reg);
+			data->clk[i].vddo_reg = NULL;
+			if (err == -ENODEV)
+				continue;
+			goto cleanup;
+		} else {
+			err = regulator_enable(data->clk[i].vddo_reg);
+			if (err) {
+				dev_err(&client->dev,
+					"failed to enable %s regulator: %d\n",
+					reg_name, err);
+				data->clk[i].vddo_reg = NULL;
+				goto cleanup;
+			}
+		}
+	}
+
+	err = si5341_dt_parse_dt(data, config);
 	if (err)
-		return err;
+		goto cleanup;
 
 	if (of_property_read_string(client->dev.of_node, "clock-output-names",
 			&init.name))
@@ -1464,21 +1609,23 @@
 	root_clock_name = init.name;
 
 	data->regmap = devm_regmap_init_i2c(client, &si5341_regmap_config);
-	if (IS_ERR(data->regmap))
-		return PTR_ERR(data->regmap);
+	if (IS_ERR(data->regmap)) {
+		err = PTR_ERR(data->regmap);
+		goto cleanup;
+	}
 
 	i2c_set_clientdata(client, data);
 
 	err = si5341_probe_chip_id(data);
 	if (err < 0)
-		return err;
+		goto cleanup;
 
 	if (of_property_read_bool(client->dev.of_node, "silabs,reprogram")) {
 		initialization_required = true;
 	} else {
 		err = si5341_is_programmed_already(data);
 		if (err < 0)
-			return err;
+			goto cleanup;
 
 		initialization_required = !err;
 	}
@@ -1487,11 +1634,11 @@
 		/* Populate the regmap cache in preparation for "cache only" */
 		err = si5341_read_settings(data);
 		if (err < 0)
-			return err;
+			goto cleanup;
 
 		err = si5341_send_preamble(data);
 		if (err < 0)
-			return err;
+			goto cleanup;
 
 		/*
 		 * We intend to send all 'final' register values in a single
@@ -1504,19 +1651,19 @@
 		err = si5341_write_multiple(data, si5341_reg_defaults,
 					ARRAY_SIZE(si5341_reg_defaults));
 		if (err < 0)
-			return err;
+			goto cleanup;
 	}
 
 	/* Input must be up and running at this point */
 	err = si5341_clk_select_active_input(data);
 	if (err < 0)
-		return err;
+		goto cleanup;
 
 	if (initialization_required) {
 		/* PLL configuration is required */
 		err = si5341_initialize_pll(data);
 		if (err < 0)
-			return err;
+			goto cleanup;
 	}
 
 	/* Register the PLL */
@@ -1529,7 +1676,7 @@
 	err = devm_clk_hw_register(&client->dev, &data->hw);
 	if (err) {
 		dev_err(&client->dev, "clock registration failed\n");
-		return err;
+		goto cleanup;
 	}
 
 	init.num_parents = 1;
@@ -1538,6 +1685,10 @@
 	for (i = 0; i < data->num_synth; ++i) {
 		synth_clock_names[i] = devm_kasprintf(&client->dev, GFP_KERNEL,
 				"%s.N%u", client->dev.of_node->name, i);
+		if (!synth_clock_names[i]) {
+			err = -ENOMEM;
+			goto free_clk_names;
+		}
 		init.name = synth_clock_names[i];
 		data->synth[i].index = i;
 		data->synth[i].data = data;
@@ -1546,6 +1697,7 @@
 		if (err) {
 			dev_err(&client->dev,
 				"synth N%u registration failed\n", i);
+			goto free_clk_names;
 		}
 	}
 
@@ -1555,6 +1707,10 @@
 	for (i = 0; i < data->num_outputs; ++i) {
 		init.name = kasprintf(GFP_KERNEL, "%s.%d",
 			client->dev.of_node->name, i);
+		if (!init.name) {
+			err = -ENOMEM;
+			goto free_clk_names;
+		}
 		init.flags = config[i].synth_master ? CLK_SET_RATE_PARENT : 0;
 		data->clk[i].index = i;
 		data->clk[i].data = data;
@@ -1566,13 +1722,17 @@
 			regmap_write(data->regmap,
 				SI5341_OUT_CM(&data->clk[i]),
 				config[i].out_cm_ampl_bits);
+			regmap_update_bits(data->regmap,
+				SI5341_OUT_MUX_SEL(&data->clk[i]),
+				SI5341_OUT_MUX_VDD_SEL_MASK,
+				config[i].vdd_sel_bits);
 		}
 		err = devm_clk_hw_register(&client->dev, &data->clk[i].hw);
 		kfree(init.name); /* clock framework made a copy of the name */
 		if (err) {
 			dev_err(&client->dev,
 				"output %u registration failed\n", i);
-			return err;
+			goto free_clk_names;
 		}
 		if (config[i].always_on)
 			clk_prepare(data->clk[i].hw.clk);
@@ -1582,7 +1742,7 @@
 			data);
 	if (err) {
 		dev_err(&client->dev, "unable to add clk provider\n");
-		return err;
+		goto free_clk_names;
 	}
 
 	if (initialization_required) {
@@ -1590,11 +1750,11 @@
 		regcache_cache_only(data->regmap, false);
 		err = regcache_sync(data->regmap);
 		if (err < 0)
-			return err;
+			goto free_clk_names;
 
 		err = si5341_finalize_defaults(data);
 		if (err < 0)
-			return err;
+			goto free_clk_names;
 	}
 
 	/* wait for device to report input clock present and PLL lock */
@@ -1603,19 +1763,46 @@
 	       10000, 250000);
 	if (err) {
 		dev_err(&client->dev, "Error waiting for input clock or PLL lock\n");
-		return err;
+		goto free_clk_names;
 	}
 
 	/* clear sticky alarm bits from initialization */
 	err = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0);
 	if (err) {
 		dev_err(&client->dev, "unable to clear sticky status\n");
-		return err;
+		goto free_clk_names;
 	}
 
+	err = sysfs_create_files(&client->dev.kobj, si5341_attributes);
+	if (err)
+		dev_err(&client->dev, "unable to create sysfs files\n");
+
+free_clk_names:
 	/* Free the names, clk framework makes copies */
 	for (i = 0; i < data->num_synth; ++i)
 		 devm_kfree(&client->dev, (void *)synth_clock_names[i]);
+
+cleanup:
+	if (err) {
+		for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) {
+			if (data->clk[i].vddo_reg)
+				regulator_disable(data->clk[i].vddo_reg);
+		}
+	}
+	return err;
+}
+
+static int si5341_remove(struct i2c_client *client)
+{
+	struct clk_si5341 *data = i2c_get_clientdata(client);
+	int i;
+
+	sysfs_remove_files(&client->dev.kobj, si5341_attributes);
+
+	for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) {
+		if (data->clk[i].vddo_reg)
+			regulator_disable(data->clk[i].vddo_reg);
+	}
 
 	return 0;
 }
@@ -1646,6 +1833,7 @@
 		.of_match_table = clk_si5341_of_match,
 	},
 	.probe		= si5341_probe,
+	.remove		= si5341_remove,
 	.id_table	= si5341_id,
 };
 module_i2c_driver(si5341_driver);
diff --git a/kernel/drivers/clk/clk-versaclock5.c b/kernel/drivers/clk/clk-versaclock5.c
index eb597ea..3ddb974 100644
--- a/kernel/drivers/clk/clk-versaclock5.c
+++ b/kernel/drivers/clk/clk-versaclock5.c
@@ -906,6 +906,11 @@
 	}
 
 	init.name = kasprintf(GFP_KERNEL, "%pOFn.mux", client->dev.of_node);
+	if (!init.name) {
+		ret = -ENOMEM;
+		goto err_clk;
+	}
+
 	init.ops = &vc5_mux_ops;
 	init.flags = 0;
 	init.parent_names = parent_names;
@@ -920,6 +925,10 @@
 		memset(&init, 0, sizeof(init));
 		init.name = kasprintf(GFP_KERNEL, "%pOFn.dbl",
 				      client->dev.of_node);
+		if (!init.name) {
+			ret = -ENOMEM;
+			goto err_clk;
+		}
 		init.ops = &vc5_dbl_ops;
 		init.flags = CLK_SET_RATE_PARENT;
 		init.parent_names = parent_names;
@@ -935,6 +944,10 @@
 	/* Register PFD */
 	memset(&init, 0, sizeof(init));
 	init.name = kasprintf(GFP_KERNEL, "%pOFn.pfd", client->dev.of_node);
+	if (!init.name) {
+		ret = -ENOMEM;
+		goto err_clk;
+	}
 	init.ops = &vc5_pfd_ops;
 	init.flags = CLK_SET_RATE_PARENT;
 	init.parent_names = parent_names;
@@ -952,6 +965,10 @@
 	/* Register PLL */
 	memset(&init, 0, sizeof(init));
 	init.name = kasprintf(GFP_KERNEL, "%pOFn.pll", client->dev.of_node);
+	if (!init.name) {
+		ret = -ENOMEM;
+		goto err_clk;
+	}
 	init.ops = &vc5_pll_ops;
 	init.flags = CLK_SET_RATE_PARENT;
 	init.parent_names = parent_names;
@@ -971,6 +988,10 @@
 		memset(&init, 0, sizeof(init));
 		init.name = kasprintf(GFP_KERNEL, "%pOFn.fod%d",
 				      client->dev.of_node, idx);
+		if (!init.name) {
+			ret = -ENOMEM;
+			goto err_clk;
+		}
 		init.ops = &vc5_fod_ops;
 		init.flags = CLK_SET_RATE_PARENT;
 		init.parent_names = parent_names;
@@ -989,6 +1010,10 @@
 	memset(&init, 0, sizeof(init));
 	init.name = kasprintf(GFP_KERNEL, "%pOFn.out0_sel_i2cb",
 			      client->dev.of_node);
+	if (!init.name) {
+		ret = -ENOMEM;
+		goto err_clk;
+	}
 	init.ops = &vc5_clk_out_ops;
 	init.flags = CLK_SET_RATE_PARENT;
 	init.parent_names = parent_names;
@@ -1015,6 +1040,10 @@
 		memset(&init, 0, sizeof(init));
 		init.name = kasprintf(GFP_KERNEL, "%pOFn.out%d",
 				      client->dev.of_node, idx + 1);
+		if (!init.name) {
+			ret = -ENOMEM;
+			goto err_clk;
+		}
 		init.ops = &vc5_clk_out_ops;
 		init.flags = CLK_SET_RATE_PARENT;
 		init.parent_names = parent_names;
diff --git a/kernel/drivers/clk/clk.c b/kernel/drivers/clk/clk.c
index 3d82193..672eb93 100644
--- a/kernel/drivers/clk/clk.c
+++ b/kernel/drivers/clk/clk.c
@@ -253,6 +253,17 @@
 		}
 	}
 
+	/*
+	 * This could be called with the enable lock held, or from atomic
+	 * context. If the parent isn't enabled already, we can't do
+	 * anything here. We can also assume this clock isn't enabled.
+	 */
+	if ((core->flags & CLK_OPS_PARENT_ENABLE) && core->parent)
+		if (!clk_core_is_enabled(core->parent)) {
+			ret = false;
+			goto done;
+		}
+
 	ret = core->ops->is_enabled(core->hw);
 done:
 	if (core->rpm_enabled)
diff --git a/kernel/drivers/clk/imx/clk-composite-8m.c b/kernel/drivers/clk/imx/clk-composite-8m.c
index 04e7285..75e0558 100644
--- a/kernel/drivers/clk/imx/clk-composite-8m.c
+++ b/kernel/drivers/clk/imx/clk-composite-8m.c
@@ -97,7 +97,7 @@
 	int prediv_value;
 	int div_value;
 	int ret;
-	u32 val;
+	u32 orig, val;
 
 	ret = imx8m_clk_composite_compute_dividers(rate, parent_rate,
 						&prediv_value, &div_value);
@@ -106,13 +106,15 @@
 
 	spin_lock_irqsave(divider->lock, flags);
 
-	val = readl(divider->reg);
-	val &= ~((clk_div_mask(divider->width) << divider->shift) |
-			(clk_div_mask(PCG_DIV_WIDTH) << PCG_DIV_SHIFT));
+	orig = readl(divider->reg);
+	val = orig & ~((clk_div_mask(divider->width) << divider->shift) |
+		       (clk_div_mask(PCG_DIV_WIDTH) << PCG_DIV_SHIFT));
 
 	val |= (u32)(prediv_value  - 1) << divider->shift;
 	val |= (u32)(div_value - 1) << PCG_DIV_SHIFT;
-	writel(val, divider->reg);
+
+	if (val != orig)
+		writel(val, divider->reg);
 
 	spin_unlock_irqrestore(divider->lock, flags);
 
diff --git a/kernel/drivers/clk/imx/clk-imx8mn.c b/kernel/drivers/clk/imx/clk-imx8mn.c
index db122d9..23f37a2 100644
--- a/kernel/drivers/clk/imx/clk-imx8mn.c
+++ b/kernel/drivers/clk/imx/clk-imx8mn.c
@@ -105,27 +105,27 @@
 						      "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",
@@ -291,7 +291,7 @@
 	void __iomem *base;
 	int ret;
 
-	clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
+	clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
 					  IMX8MN_CLK_END), GFP_KERNEL);
 	if (WARN_ON(!clk_hw_data))
 		return -ENOMEM;
@@ -308,10 +308,10 @@
 	hws[IMX8MN_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4");
 
 	np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop");
-	base = of_iomap(np, 0);
+	base = devm_of_iomap(dev, np, 0, NULL);
 	of_node_put(np);
-	if (WARN_ON(!base)) {
-		ret = -ENOMEM;
+	if (WARN_ON(IS_ERR(base))) {
+		ret = PTR_ERR(base);
 		goto unregister_hws;
 	}
 
diff --git a/kernel/drivers/clk/imx/clk-imx8mp.c b/kernel/drivers/clk/imx/clk-imx8mp.c
index 36e8d61..1485728 100644
--- a/kernel/drivers/clk/imx/clk-imx8mp.c
+++ b/kernel/drivers/clk/imx/clk-imx8mp.c
@@ -17,6 +17,7 @@
 
 static u32 share_count_nand;
 static u32 share_count_media;
+static u32 share_count_usb;
 
 static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
 static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
@@ -179,10 +180,6 @@
 static const char * const imx8mp_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
 						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext3", "clk_ext4", };
-
-static const char * const imx8mp_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
-						"clk_ext1", "clk_ext2", };
 
 static const char * const imx8mp_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
 						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
@@ -362,7 +359,7 @@
 							       "clk_ext2", "audio_pll2_out",
 							       "video_pll1_out", };
 
-static const char * const imx8mp_media_disp1_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out",
+static const char * const imx8mp_media_disp_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out",
 							   "audio_pll1_out", "sys_pll1_800m",
 							   "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
 
@@ -411,6 +408,11 @@
 
 static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
 
+static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+						  "dummy", "dummy", "gpu_pll_out", "vpu_pll_out",
+						  "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
+						  "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
+
 static struct clk_hw **hws;
 static struct clk_hw_onecell_data *clk_hw_data;
 
@@ -419,25 +421,22 @@
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 	void __iomem *anatop_base, *ccm_base;
+	int err;
 
 	np = of_find_compatible_node(NULL, NULL, "fsl,imx8mp-anatop");
-	anatop_base = of_iomap(np, 0);
+	anatop_base = devm_of_iomap(dev, np, 0, NULL);
 	of_node_put(np);
-	if (WARN_ON(!anatop_base))
-		return -ENOMEM;
+	if (WARN_ON(IS_ERR(anatop_base)))
+		return PTR_ERR(anatop_base);
 
 	np = dev->of_node;
 	ccm_base = devm_platform_ioremap_resource(pdev, 0);
-	if (WARN_ON(IS_ERR(ccm_base))) {
-		iounmap(anatop_base);
+	if (WARN_ON(IS_ERR(ccm_base)))
 		return PTR_ERR(ccm_base);
-	}
 
-	clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL);
-	if (WARN_ON(!clk_hw_data)) {
-		iounmap(anatop_base);
+	clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL);
+	if (WARN_ON(!clk_hw_data))
 		return -ENOMEM;
-	}
 
 	clk_hw_data->num = IMX8MP_CLK_END;
 	hws = clk_hw_data->hws;
@@ -532,6 +531,15 @@
 	hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2);
 	hws[IMX8MP_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
 
+	hws[IMX8MP_CLK_CLKOUT1_SEL] = imx_clk_hw_mux2("clkout1_sel", anatop_base + 0x128, 4, 4,
+						      imx8mp_clkout_sels, ARRAY_SIZE(imx8mp_clkout_sels));
+	hws[IMX8MP_CLK_CLKOUT1_DIV] = imx_clk_hw_divider("clkout1_div", "clkout1_sel", anatop_base + 0x128, 0, 4);
+	hws[IMX8MP_CLK_CLKOUT1] = imx_clk_hw_gate("clkout1", "clkout1_div", anatop_base + 0x128, 8);
+	hws[IMX8MP_CLK_CLKOUT2_SEL] = imx_clk_hw_mux2("clkout2_sel", anatop_base + 0x128, 20, 4,
+						      imx8mp_clkout_sels, ARRAY_SIZE(imx8mp_clkout_sels));
+	hws[IMX8MP_CLK_CLKOUT2_DIV] = imx_clk_hw_divider("clkout2_div", "clkout2_sel", anatop_base + 0x128, 16, 4);
+	hws[IMX8MP_CLK_CLKOUT2] = imx_clk_hw_gate("clkout2", "clkout2_div", anatop_base + 0x128, 24);
+
 	hws[IMX8MP_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mp_a53_sels, ccm_base + 0x8000);
 	hws[IMX8MP_CLK_A53_SRC] = hws[IMX8MP_CLK_A53_DIV];
 	hws[IMX8MP_CLK_A53_CG] = hws[IMX8MP_CLK_A53_DIV];
@@ -566,6 +574,7 @@
 	hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_bus_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000);
 	hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100);
 	hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite_bus("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200);
+	hws[IMX8MP_CLK_MEDIA_DISP2_PIX] = imx8m_clk_hw_composite("media_disp2_pix", imx8mp_media_disp_pix_sels, ccm_base + 0x9300);
 
 	hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1);
 	hws[IMX8MP_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", ccm_base + 0x9180, 0, 1);
@@ -583,7 +592,6 @@
 	hws[IMX8MP_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mp_sai1_sels, ccm_base + 0xa580);
 	hws[IMX8MP_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mp_sai2_sels, ccm_base + 0xa600);
 	hws[IMX8MP_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mp_sai3_sels, ccm_base + 0xa680);
-	hws[IMX8MP_CLK_SAI4] = imx8m_clk_hw_composite("sai4", imx8mp_sai4_sels, ccm_base + 0xa700);
 	hws[IMX8MP_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mp_sai5_sels, ccm_base + 0xa780);
 	hws[IMX8MP_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mp_sai6_sels, ccm_base + 0xa800);
 	hws[IMX8MP_CLK_ENET_QOS] = imx8m_clk_hw_composite("enet_qos", imx8mp_enet_qos_sels, ccm_base + 0xa880);
@@ -630,7 +638,7 @@
 	hws[IMX8MP_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mp_usdhc3_sels, ccm_base + 0xbc80);
 	hws[IMX8MP_CLK_MEDIA_CAM1_PIX] = imx8m_clk_hw_composite("media_cam1_pix", imx8mp_media_cam1_pix_sels, ccm_base + 0xbd00);
 	hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF] = imx8m_clk_hw_composite("media_mipi_phy1_ref", imx8mp_media_mipi_phy1_ref_sels, ccm_base + 0xbd80);
-	hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp1_pix_sels, ccm_base + 0xbe00);
+	hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp_pix_sels, ccm_base + 0xbe00);
 	hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base + 0xbe80);
 	hws[IMX8MP_CLK_MEDIA_LDB] = imx8m_clk_hw_composite("media_ldb", imx8mp_media_ldb_sels, ccm_base + 0xbf00);
 	hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite_critical("mem_repair", imx8mp_memrepair_sels, ccm_base + 0xbf80);
@@ -691,7 +699,8 @@
 	hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0);
 	hws[IMX8MP_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", ccm_base + 0x44b0, 0);
 	hws[IMX8MP_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", ccm_base + 0x44c0, 0);
-	hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate4("usb_root_clk", "hsio_axi", ccm_base + 0x44d0, 0);
+	hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate2_shared2("usb_root_clk", "hsio_axi", ccm_base + 0x44d0, 0, &share_count_usb);
+	hws[IMX8MP_CLK_USB_SUSP] = imx_clk_hw_gate2_shared2("usb_suspend_clk", "osc_32k", ccm_base + 0x44d0, 0, &share_count_usb);
 	hws[IMX8MP_CLK_USB_PHY_ROOT] = imx_clk_hw_gate4("usb_phy_root_clk", "usb_phy_ref", ccm_base + 0x44f0, 0);
 	hws[IMX8MP_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", ccm_base + 0x4510, 0);
 	hws[IMX8MP_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", ccm_base + 0x4520, 0);
@@ -726,7 +735,12 @@
 
 	imx_check_clk_hws(hws, IMX8MP_CLK_END);
 
-	of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
+	err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
+	if (err < 0) {
+		dev_err(dev, "failed to register hws for i.MX8MP\n");
+		imx_unregister_hw_clocks(hws, IMX8MP_CLK_END);
+		return err;
+	}
 
 	imx_register_uart_clocks(4);
 
diff --git a/kernel/drivers/clk/imx/clk.c b/kernel/drivers/clk/imx/clk.c
index 7cc6699..d4cf0c7 100644
--- a/kernel/drivers/clk/imx/clk.c
+++ b/kernel/drivers/clk/imx/clk.c
@@ -201,9 +201,10 @@
 			clk_disable_unprepare(imx_uart_clocks[i]);
 			clk_put(imx_uart_clocks[i]);
 		}
-		kfree(imx_uart_clocks);
 	}
 
+	kfree(imx_uart_clocks);
+
 	return 0;
 }
 late_initcall_sync(imx_clk_disable_uart);
diff --git a/kernel/drivers/clk/keystone/pll.c b/kernel/drivers/clk/keystone/pll.c
index d59a762..ee5c723 100644
--- a/kernel/drivers/clk/keystone/pll.c
+++ b/kernel/drivers/clk/keystone/pll.c
@@ -209,7 +209,7 @@
 	}
 
 	clk = clk_register_pll(NULL, node->name, parent_name, pll_data);
-	if (clk) {
+	if (!IS_ERR_OR_NULL(clk)) {
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		return;
 	}
diff --git a/kernel/drivers/clk/keystone/sci-clk.c b/kernel/drivers/clk/keystone/sci-clk.c
index aaf31ab..9e06c28 100644
--- a/kernel/drivers/clk/keystone/sci-clk.c
+++ b/kernel/drivers/clk/keystone/sci-clk.c
@@ -302,6 +302,8 @@
 
 	name = kasprintf(GFP_KERNEL, "clk:%d:%d", sci_clk->dev_id,
 			 sci_clk->clk_id);
+	if (!name)
+		return -ENOMEM;
 
 	init.name = name;
 
diff --git a/kernel/drivers/clk/qcom/clk-krait.c b/kernel/drivers/clk/qcom/clk-krait.c
index 9004642..e74fc81 100644
--- a/kernel/drivers/clk/qcom/clk-krait.c
+++ b/kernel/drivers/clk/qcom/clk-krait.c
@@ -98,6 +98,8 @@
 
 	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);
diff --git a/kernel/drivers/clk/qcom/gcc-ipq6018.c b/kernel/drivers/clk/qcom/gcc-ipq6018.c
index 3f9c2f6..cde62a1 100644
--- a/kernel/drivers/clk/qcom/gcc-ipq6018.c
+++ b/kernel/drivers/clk/qcom/gcc-ipq6018.c
@@ -1654,7 +1654,7 @@
 		.name = "sdcc1_apps_clk_src",
 		.parent_data = gcc_xo_gpll0_gpll2_gpll0_out_main_div2,
 		.num_parents = 4,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_rcg2_floor_ops,
 	},
 };
 
@@ -4517,24 +4517,24 @@
 	[GCC_PCIE0_AHB_ARES] = { 0x75040, 5 },
 	[GCC_PCIE0_AXI_MASTER_STICKY_ARES] = { 0x75040, 6 },
 	[GCC_PCIE0_AXI_SLAVE_STICKY_ARES] = { 0x75040, 7 },
-	[GCC_PPE_FULL_RESET] = { 0x68014, 0 },
-	[GCC_UNIPHY0_SOFT_RESET] = { 0x56004, 0 },
+	[GCC_PPE_FULL_RESET] = { .reg = 0x68014, .bitmask = 0xf0000 },
+	[GCC_UNIPHY0_SOFT_RESET] = { .reg = 0x56004, .bitmask = 0x3ff2 },
 	[GCC_UNIPHY0_XPCS_RESET] = { 0x56004, 2 },
-	[GCC_UNIPHY1_SOFT_RESET] = { 0x56104, 0 },
+	[GCC_UNIPHY1_SOFT_RESET] = { .reg = 0x56104, .bitmask = 0x32 },
 	[GCC_UNIPHY1_XPCS_RESET] = { 0x56104, 2 },
-	[GCC_EDMA_HW_RESET] = { 0x68014, 0 },
-	[GCC_NSSPORT1_RESET] = { 0x68014, 0 },
-	[GCC_NSSPORT2_RESET] = { 0x68014, 0 },
-	[GCC_NSSPORT3_RESET] = { 0x68014, 0 },
-	[GCC_NSSPORT4_RESET] = { 0x68014, 0 },
-	[GCC_NSSPORT5_RESET] = { 0x68014, 0 },
-	[GCC_UNIPHY0_PORT1_ARES] = { 0x56004, 0 },
-	[GCC_UNIPHY0_PORT2_ARES] = { 0x56004, 0 },
-	[GCC_UNIPHY0_PORT3_ARES] = { 0x56004, 0 },
-	[GCC_UNIPHY0_PORT4_ARES] = { 0x56004, 0 },
-	[GCC_UNIPHY0_PORT5_ARES] = { 0x56004, 0 },
-	[GCC_UNIPHY0_PORT_4_5_RESET] = { 0x56004, 0 },
-	[GCC_UNIPHY0_PORT_4_RESET] = { 0x56004, 0 },
+	[GCC_EDMA_HW_RESET] = { .reg = 0x68014, .bitmask = 0x300000 },
+	[GCC_NSSPORT1_RESET] = { .reg = 0x68014, .bitmask = 0x1000003 },
+	[GCC_NSSPORT2_RESET] = { .reg = 0x68014, .bitmask = 0x200000c },
+	[GCC_NSSPORT3_RESET] = { .reg = 0x68014, .bitmask = 0x4000030 },
+	[GCC_NSSPORT4_RESET] = { .reg = 0x68014, .bitmask = 0x8000300 },
+	[GCC_NSSPORT5_RESET] = { .reg = 0x68014, .bitmask = 0x10000c00 },
+	[GCC_UNIPHY0_PORT1_ARES] = { .reg = 0x56004, .bitmask = 0x30 },
+	[GCC_UNIPHY0_PORT2_ARES] = { .reg = 0x56004, .bitmask = 0xc0 },
+	[GCC_UNIPHY0_PORT3_ARES] = { .reg = 0x56004, .bitmask = 0x300 },
+	[GCC_UNIPHY0_PORT4_ARES] = { .reg = 0x56004, .bitmask = 0xc00 },
+	[GCC_UNIPHY0_PORT5_ARES] = { .reg = 0x56004, .bitmask = 0x3000 },
+	[GCC_UNIPHY0_PORT_4_5_RESET] = { .reg = 0x56004, .bitmask = 0x3c02 },
+	[GCC_UNIPHY0_PORT_4_RESET] = { .reg = 0x56004, .bitmask = 0xc02 },
 	[GCC_LPASS_BCR] = {0x1F000, 0},
 	[GCC_UBI32_TBU_BCR] = {0x65000, 0},
 	[GCC_LPASS_TBU_BCR] = {0x6C000, 0},
diff --git a/kernel/drivers/clk/qcom/gcc-mdm9615.c b/kernel/drivers/clk/qcom/gcc-mdm9615.c
index 8bed02a..470a277 100644
--- a/kernel/drivers/clk/qcom/gcc-mdm9615.c
+++ b/kernel/drivers/clk/qcom/gcc-mdm9615.c
@@ -58,7 +58,7 @@
 	.enable_mask = BIT(0),
 	.hw.init = &(struct clk_init_data){
 		.name = "pll0_vote",
-		.parent_names = (const char *[]){ "pll8" },
+		.parent_names = (const char *[]){ "pll0" },
 		.num_parents = 1,
 		.ops = &clk_pll_vote_ops,
 	},
diff --git a/kernel/drivers/clk/qcom/gcc-qcs404.c b/kernel/drivers/clk/qcom/gcc-qcs404.c
index 46d314d..a7a9884 100644
--- a/kernel/drivers/clk/qcom/gcc-qcs404.c
+++ b/kernel/drivers/clk/qcom/gcc-qcs404.c
@@ -25,11 +25,9 @@
 	P_CORE_BI_PLL_TEST_SE,
 	P_DSI0_PHY_PLL_OUT_BYTECLK,
 	P_DSI0_PHY_PLL_OUT_DSICLK,
-	P_GPLL0_OUT_AUX,
 	P_GPLL0_OUT_MAIN,
 	P_GPLL1_OUT_MAIN,
 	P_GPLL3_OUT_MAIN,
-	P_GPLL4_OUT_AUX,
 	P_GPLL4_OUT_MAIN,
 	P_GPLL6_OUT_AUX,
 	P_HDMI_PHY_PLL_CLK,
@@ -109,28 +107,24 @@
 static const struct parent_map gcc_parent_map_5[] = {
 	{ P_XO, 0 },
 	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
-	{ P_GPLL0_OUT_AUX, 2 },
 	{ P_CORE_BI_PLL_TEST_SE, 7 },
 };
 
 static const char * const gcc_parent_names_5[] = {
 	"cxo",
-	"dsi0pll_byteclk_src",
-	"gpll0_out_aux",
+	"dsi0pllbyte",
 	"core_bi_pll_test_se",
 };
 
 static const struct parent_map gcc_parent_map_6[] = {
 	{ P_XO, 0 },
 	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
-	{ P_GPLL0_OUT_AUX, 3 },
 	{ P_CORE_BI_PLL_TEST_SE, 7 },
 };
 
 static const char * const gcc_parent_names_6[] = {
 	"cxo",
-	"dsi0_phy_pll_out_byteclk",
-	"gpll0_out_aux",
+	"dsi0pllbyte",
 	"core_bi_pll_test_se",
 };
 
@@ -139,7 +133,6 @@
 	{ P_GPLL0_OUT_MAIN, 1 },
 	{ P_GPLL3_OUT_MAIN, 2 },
 	{ P_GPLL6_OUT_AUX, 3 },
-	{ P_GPLL4_OUT_AUX, 4 },
 	{ P_CORE_BI_PLL_TEST_SE, 7 },
 };
 
@@ -148,7 +141,6 @@
 	"gpll0_out_main",
 	"gpll3_out_main",
 	"gpll6_out_aux",
-	"gpll4_out_aux",
 	"core_bi_pll_test_se",
 };
 
@@ -175,7 +167,7 @@
 static const char * const gcc_parent_names_9[] = {
 	"cxo",
 	"gpll0_out_main",
-	"dsi0_phy_pll_out_dsiclk",
+	"dsi0pll",
 	"gpll6_out_aux",
 	"core_bi_pll_test_se",
 };
@@ -207,14 +199,12 @@
 static const struct parent_map gcc_parent_map_12[] = {
 	{ P_XO, 0 },
 	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
-	{ P_GPLL0_OUT_AUX, 2 },
 	{ P_CORE_BI_PLL_TEST_SE, 7 },
 };
 
 static const char * const gcc_parent_names_12[] = {
 	"cxo",
-	"dsi0pll_pclk_src",
-	"gpll0_out_aux",
+	"dsi0pll",
 	"core_bi_pll_test_se",
 };
 
@@ -237,40 +227,34 @@
 static const struct parent_map gcc_parent_map_14[] = {
 	{ P_XO, 0 },
 	{ P_GPLL0_OUT_MAIN, 1 },
-	{ P_GPLL4_OUT_AUX, 2 },
 	{ P_CORE_BI_PLL_TEST_SE, 7 },
 };
 
 static const char * const gcc_parent_names_14[] = {
 	"cxo",
 	"gpll0_out_main",
-	"gpll4_out_aux",
 	"core_bi_pll_test_se",
 };
 
 static const struct parent_map gcc_parent_map_15[] = {
 	{ P_XO, 0 },
-	{ P_GPLL0_OUT_AUX, 2 },
 	{ P_CORE_BI_PLL_TEST_SE, 7 },
 };
 
 static const char * const gcc_parent_names_15[] = {
 	"cxo",
-	"gpll0_out_aux",
 	"core_bi_pll_test_se",
 };
 
 static const struct parent_map gcc_parent_map_16[] = {
 	{ P_XO, 0 },
 	{ P_GPLL0_OUT_MAIN, 1 },
-	{ P_GPLL0_OUT_AUX, 2 },
 	{ P_CORE_BI_PLL_TEST_SE, 7 },
 };
 
 static const char * const gcc_parent_names_16[] = {
 	"cxo",
 	"gpll0_out_main",
-	"gpll0_out_aux",
 	"core_bi_pll_test_se",
 };
 
diff --git a/kernel/drivers/clk/qcom/gcc-sc7180.c b/kernel/drivers/clk/qcom/gcc-sc7180.c
index 7e80dbd..bebe317 100644
--- a/kernel/drivers/clk/qcom/gcc-sc7180.c
+++ b/kernel/drivers/clk/qcom/gcc-sc7180.c
@@ -285,7 +285,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_cpuss_ahb_clk_src",
 		.parent_data = gcc_parent_data_0_ao,
-		.num_parents = 4,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0_ao),
 		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_rcg2_ops,
 		},
@@ -309,7 +309,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_gp1_clk_src",
 		.parent_data = gcc_parent_data_4,
-		.num_parents = 5,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_4),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -323,7 +323,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_gp2_clk_src",
 		.parent_data = gcc_parent_data_4,
-		.num_parents = 5,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_4),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -337,7 +337,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_gp3_clk_src",
 		.parent_data = gcc_parent_data_4,
-		.num_parents = 5,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_4),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -357,7 +357,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_pdm2_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 4,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -378,7 +378,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_qspi_core_clk_src",
 		.parent_data = gcc_parent_data_2,
-		.num_parents = 6,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_2),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -619,7 +619,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_sdcc1_apps_clk_src",
 		.parent_data = gcc_parent_data_1,
-		.num_parents = 5,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_1),
 		.ops = &clk_rcg2_floor_ops,
 	},
 };
@@ -641,7 +641,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_sdcc1_ice_core_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 4,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -665,7 +665,8 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_sdcc2_apps_clk_src",
 		.parent_data = gcc_parent_data_5,
-		.num_parents = 5,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_5),
+		.flags = CLK_OPS_PARENT_ENABLE,
 		.ops = &clk_rcg2_floor_ops,
 	},
 };
@@ -688,7 +689,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_ufs_phy_axi_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 4,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -710,7 +711,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_ufs_phy_ice_core_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 4,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -730,7 +731,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_ufs_phy_phy_aux_clk_src",
 		.parent_data = gcc_parent_data_3,
-		.num_parents = 3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_3),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -751,7 +752,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_ufs_phy_unipro_core_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 4,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -773,7 +774,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_usb30_prim_master_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 4,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -793,7 +794,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_usb30_prim_mock_utmi_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 4,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -812,7 +813,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_usb3_prim_phy_aux_clk_src",
 		.parent_data = gcc_parent_data_6,
-		.num_parents = 4,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_6),
 		.ops = &clk_rcg2_ops,
 	},
 };
diff --git a/kernel/drivers/clk/qcom/gcc-sm8250.c b/kernel/drivers/clk/qcom/gcc-sm8250.c
index ab594a0..70723e4 100644
--- a/kernel/drivers/clk/qcom/gcc-sm8250.c
+++ b/kernel/drivers/clk/qcom/gcc-sm8250.c
@@ -200,7 +200,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_cpuss_ahb_clk_src",
 		.parent_data = gcc_parent_data_0_ao,
-		.num_parents = 3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0_ao),
 		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_rcg2_ops,
 	},
@@ -224,7 +224,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_gp1_clk_src",
 		.parent_data = gcc_parent_data_1,
-		.num_parents = 4,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_1),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -238,7 +238,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_gp2_clk_src",
 		.parent_data = gcc_parent_data_1,
-		.num_parents = 4,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_1),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -252,7 +252,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_gp3_clk_src",
 		.parent_data = gcc_parent_data_1,
-		.num_parents = 4,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_1),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -272,7 +272,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_pcie_0_aux_clk_src",
 		.parent_data = gcc_parent_data_2,
-		.num_parents = 2,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_2),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -286,7 +286,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_pcie_1_aux_clk_src",
 		.parent_data = gcc_parent_data_2,
-		.num_parents = 2,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_2),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -300,7 +300,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_pcie_2_aux_clk_src",
 		.parent_data = gcc_parent_data_2,
-		.num_parents = 2,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_2),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -320,7 +320,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_pcie_phy_refgen_clk_src",
 		.parent_data = gcc_parent_data_0_ao,
-		.num_parents = 3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0_ao),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -341,7 +341,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_pdm2_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -369,7 +369,7 @@
 static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = {
 	.name = "gcc_qupv3_wrap0_s0_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -385,7 +385,7 @@
 static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = {
 	.name = "gcc_qupv3_wrap0_s1_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -417,7 +417,7 @@
 static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = {
 	.name = "gcc_qupv3_wrap0_s2_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -433,7 +433,7 @@
 static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = {
 	.name = "gcc_qupv3_wrap0_s3_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -449,7 +449,7 @@
 static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = {
 	.name = "gcc_qupv3_wrap0_s4_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -465,7 +465,7 @@
 static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = {
 	.name = "gcc_qupv3_wrap0_s5_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -481,7 +481,7 @@
 static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = {
 	.name = "gcc_qupv3_wrap0_s6_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -497,7 +497,7 @@
 static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = {
 	.name = "gcc_qupv3_wrap0_s7_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -513,7 +513,7 @@
 static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = {
 	.name = "gcc_qupv3_wrap1_s0_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -529,7 +529,7 @@
 static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = {
 	.name = "gcc_qupv3_wrap1_s1_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -545,7 +545,7 @@
 static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = {
 	.name = "gcc_qupv3_wrap1_s2_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -561,7 +561,7 @@
 static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = {
 	.name = "gcc_qupv3_wrap1_s3_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -577,7 +577,7 @@
 static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = {
 	.name = "gcc_qupv3_wrap1_s4_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -593,7 +593,7 @@
 static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = {
 	.name = "gcc_qupv3_wrap1_s5_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -609,7 +609,7 @@
 static struct clk_init_data gcc_qupv3_wrap2_s0_clk_src_init = {
 	.name = "gcc_qupv3_wrap2_s0_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -625,7 +625,7 @@
 static struct clk_init_data gcc_qupv3_wrap2_s1_clk_src_init = {
 	.name = "gcc_qupv3_wrap2_s1_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -641,7 +641,7 @@
 static struct clk_init_data gcc_qupv3_wrap2_s2_clk_src_init = {
 	.name = "gcc_qupv3_wrap2_s2_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -657,7 +657,7 @@
 static struct clk_init_data gcc_qupv3_wrap2_s3_clk_src_init = {
 	.name = "gcc_qupv3_wrap2_s3_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -673,7 +673,7 @@
 static struct clk_init_data gcc_qupv3_wrap2_s4_clk_src_init = {
 	.name = "gcc_qupv3_wrap2_s4_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -689,7 +689,7 @@
 static struct clk_init_data gcc_qupv3_wrap2_s5_clk_src_init = {
 	.name = "gcc_qupv3_wrap2_s5_clk_src",
 	.parent_data = gcc_parent_data_0,
-	.num_parents = 3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.ops = &clk_rcg2_ops,
 };
 
@@ -721,7 +721,8 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_sdcc2_apps_clk_src",
 		.parent_data = gcc_parent_data_4,
-		.num_parents = 5,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_4),
+		.flags = CLK_OPS_PARENT_ENABLE,
 		.ops = &clk_rcg2_floor_ops,
 	},
 };
@@ -744,7 +745,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_sdcc4_apps_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_floor_ops,
 	},
 };
@@ -763,7 +764,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_tsif_ref_clk_src",
 		.parent_data = gcc_parent_data_5,
-		.num_parents = 4,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_5),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -785,7 +786,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_ufs_card_axi_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -807,7 +808,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_ufs_card_ice_core_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -826,7 +827,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_ufs_card_phy_aux_clk_src",
 		.parent_data = gcc_parent_data_3,
-		.num_parents = 1,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_3),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -847,7 +848,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_ufs_card_unipro_core_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -870,7 +871,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_ufs_phy_axi_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -884,7 +885,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_ufs_phy_ice_core_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -898,7 +899,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_ufs_phy_phy_aux_clk_src",
 		.parent_data = gcc_parent_data_3,
-		.num_parents = 1,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_3),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -912,7 +913,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_ufs_phy_unipro_core_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -935,7 +936,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_usb30_prim_master_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -949,7 +950,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_usb30_prim_mock_utmi_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -963,7 +964,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_usb30_sec_master_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -977,7 +978,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_usb30_sec_mock_utmi_clk_src",
 		.parent_data = gcc_parent_data_0,
-		.num_parents = 3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -991,7 +992,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_usb3_prim_phy_aux_clk_src",
 		.parent_data = gcc_parent_data_2,
-		.num_parents = 2,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_2),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -1005,7 +1006,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_usb3_sec_phy_aux_clk_src",
 		.parent_data = gcc_parent_data_2,
-		.num_parents = 2,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_2),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -3268,7 +3269,7 @@
 	.pd = {
 		.name = "usb30_prim_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 };
 
 static struct gdsc usb30_sec_gdsc = {
@@ -3276,7 +3277,7 @@
 	.pd = {
 		.name = "usb30_sec_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 };
 
 static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = {
diff --git a/kernel/drivers/clk/qcom/gpucc-sc7180.c b/kernel/drivers/clk/qcom/gpucc-sc7180.c
index 88a739b..c51114e 100644
--- a/kernel/drivers/clk/qcom/gpucc-sc7180.c
+++ b/kernel/drivers/clk/qcom/gpucc-sc7180.c
@@ -21,8 +21,6 @@
 #define CX_GMU_CBCR_SLEEP_SHIFT		4
 #define CX_GMU_CBCR_WAKE_MASK		0xF
 #define CX_GMU_CBCR_WAKE_SHIFT		8
-#define CLK_DIS_WAIT_SHIFT		12
-#define CLK_DIS_WAIT_MASK		(0xf << CLK_DIS_WAIT_SHIFT)
 
 enum {
 	P_BI_TCXO,
@@ -163,6 +161,7 @@
 static struct gdsc cx_gdsc = {
 	.gdscr = 0x106c,
 	.gds_hw_ctrl = 0x1540,
+	.clk_dis_wait_val = 8,
 	.pd = {
 		.name = "cx_gdsc",
 	},
@@ -244,10 +243,6 @@
 	mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT;
 	value = 0xF << CX_GMU_CBCR_WAKE_SHIFT | 0xF << CX_GMU_CBCR_SLEEP_SHIFT;
 	regmap_update_bits(regmap, 0x1098, mask, value);
-
-	/* Configure clk_dis_wait for gpu_cx_gdsc */
-	regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK,
-						8 << CLK_DIS_WAIT_SHIFT);
 
 	return qcom_cc_really_probe(pdev, &gpu_cc_sc7180_desc, regmap);
 }
diff --git a/kernel/drivers/clk/qcom/gpucc-sdm845.c b/kernel/drivers/clk/qcom/gpucc-sdm845.c
index 46916a7..1981755 100644
--- a/kernel/drivers/clk/qcom/gpucc-sdm845.c
+++ b/kernel/drivers/clk/qcom/gpucc-sdm845.c
@@ -22,8 +22,6 @@
 #define CX_GMU_CBCR_SLEEP_SHIFT		4
 #define CX_GMU_CBCR_WAKE_MASK		0xf
 #define CX_GMU_CBCR_WAKE_SHIFT		8
-#define CLK_DIS_WAIT_SHIFT		12
-#define CLK_DIS_WAIT_MASK		(0xf << CLK_DIS_WAIT_SHIFT)
 
 enum {
 	P_BI_TCXO,
@@ -124,6 +122,7 @@
 static struct gdsc gpu_cx_gdsc = {
 	.gdscr = 0x106c,
 	.gds_hw_ctrl = 0x1540,
+	.clk_dis_wait_val = 0x8,
 	.pd = {
 		.name = "gpu_cx_gdsc",
 	},
@@ -195,10 +194,6 @@
 	mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT;
 	value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT;
 	regmap_update_bits(regmap, 0x1098, mask, value);
-
-	/* Configure clk_dis_wait for gpu_cx_gdsc */
-	regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK,
-						8 << CLK_DIS_WAIT_SHIFT);
 
 	return qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap);
 }
diff --git a/kernel/drivers/clk/qcom/reset.c b/kernel/drivers/clk/qcom/reset.c
index 819d194..e45e328 100644
--- a/kernel/drivers/clk/qcom/reset.c
+++ b/kernel/drivers/clk/qcom/reset.c
@@ -13,8 +13,11 @@
 
 static int qcom_reset(struct reset_controller_dev *rcdev, unsigned long id)
 {
+	struct qcom_reset_controller *rst = to_qcom_reset_controller(rcdev);
+
 	rcdev->ops->assert(rcdev, id);
-	udelay(1);
+	fsleep(rst->reset_map[id].udelay ?: 1); /* use 1 us as default */
+
 	rcdev->ops->deassert(rcdev, id);
 	return 0;
 }
@@ -28,7 +31,7 @@
 
 	rst = to_qcom_reset_controller(rcdev);
 	map = &rst->reset_map[id];
-	mask = BIT(map->bit);
+	mask = map->bitmask ? map->bitmask : BIT(map->bit);
 
 	return regmap_update_bits(rst->regmap, map->reg, mask, mask);
 }
@@ -42,7 +45,7 @@
 
 	rst = to_qcom_reset_controller(rcdev);
 	map = &rst->reset_map[id];
-	mask = BIT(map->bit);
+	mask = map->bitmask ? map->bitmask : BIT(map->bit);
 
 	return regmap_update_bits(rst->regmap, map->reg, mask, 0);
 }
diff --git a/kernel/drivers/clk/qcom/reset.h b/kernel/drivers/clk/qcom/reset.h
index 2a08b5e..9a47c83 100644
--- a/kernel/drivers/clk/qcom/reset.h
+++ b/kernel/drivers/clk/qcom/reset.h
@@ -11,6 +11,8 @@
 struct qcom_reset_map {
 	unsigned int reg;
 	u8 bit;
+	u8 udelay;
+	u32 bitmask;
 };
 
 struct regmap;
diff --git a/kernel/drivers/clk/renesas/r9a06g032-clocks.c b/kernel/drivers/clk/renesas/r9a06g032-clocks.c
index 245150a..285f6ac 100644
--- a/kernel/drivers/clk/renesas/r9a06g032-clocks.c
+++ b/kernel/drivers/clk/renesas/r9a06g032-clocks.c
@@ -386,7 +386,7 @@
 	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 @@
 			if (error)
 				return error;
 		}
-		i++;
 	}
 
 	return 0;
diff --git a/kernel/drivers/clk/renesas/renesas-cpg-mssr.c b/kernel/drivers/clk/renesas/renesas-cpg-mssr.c
index 94db883..a5a68e1 100644
--- a/kernel/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/kernel/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -914,9 +914,8 @@
 		}
 
 		if (!i)
-			dev_warn(dev, "Failed to enable %s%u[0x%x]\n",
-				 priv->reg_layout == CLK_REG_LAYOUT_RZ_A ?
-				 "STB" : "SMSTP", reg, oldval & mask);
+			dev_warn(dev, "Failed to enable SMSTP%u[0x%x]\n", reg,
+				 oldval & mask);
 	}
 
 	return 0;
@@ -960,7 +959,6 @@
 		goto out_err;
 	}
 
-	cpg_mssr_priv = priv;
 	priv->num_core_clks = info->num_total_core_clks;
 	priv->num_mod_clks = info->num_hw_mod_clks;
 	priv->last_dt_core_clk = info->last_dt_core_clk;
@@ -990,6 +988,8 @@
 	if (error)
 		goto out_err;
 
+	cpg_mssr_priv = priv;
+
 	return 0;
 
 out_err:
diff --git a/kernel/drivers/clk/rockchip/clk-out.c b/kernel/drivers/clk/rockchip/clk-out.c
index 689832e..97177a4 100644
--- a/kernel/drivers/clk/rockchip/clk-out.c
+++ b/kernel/drivers/clk/rockchip/clk-out.c
@@ -23,6 +23,7 @@
 	void __iomem *reg;
 	u32 shift = 0;
 	u8 clk_gate_flags = CLK_GATE_HIWORD_MASK;
+	unsigned long flags = CLK_SET_RATE_PARENT;
 	int ret;
 
 	ret = device_property_read_string(dev, "clock-output-names", &clk_name);
@@ -35,6 +36,9 @@
 
 	if (device_property_read_bool(dev, "rockchip,bit-set-to-disable"))
 		clk_gate_flags |= CLK_GATE_SET_TO_DISABLE;
+
+	if (device_property_read_bool(dev, "rockchip,clk-ignore-unused"))
+		flags |= CLK_IGNORE_UNUSED;
 
 	ret = of_clk_parent_fill(node, &parent_name, 1);
 	if (ret != 1)
@@ -50,7 +54,8 @@
 
 	pm_runtime_enable(dev);
 
-	hw = clk_hw_register_gate(dev, clk_name, parent_name, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+
+	hw = clk_hw_register_gate(dev, clk_name, parent_name, flags,
 				  reg, shift, clk_gate_flags, &clk_out_lock);
 	if (IS_ERR(hw)) {
 		ret = -EINVAL;
diff --git a/kernel/drivers/clk/rockchip/clk-pll.c b/kernel/drivers/clk/rockchip/clk-pll.c
index 8008ee9..89ecdd0 100644
--- a/kernel/drivers/clk/rockchip/clk-pll.c
+++ b/kernel/drivers/clk/rockchip/clk-pll.c
@@ -1876,6 +1876,7 @@
 	return mux_clk;
 
 err_pll:
+	kfree(pll->rate_table);
 	clk_unregister(mux_clk);
 	mux_clk = pll_clk;
 err_mux:
diff --git a/kernel/drivers/clk/rockchip/clk-rk3399.c b/kernel/drivers/clk/rockchip/clk-rk3399.c
index 6112951..6c4e0d2 100644
--- a/kernel/drivers/clk/rockchip/clk-rk3399.c
+++ b/kernel/drivers/clk/rockchip/clk-rk3399.c
@@ -1356,7 +1356,7 @@
 			RK3399_CLKSEL_CON(56), 6, 2, MFLAGS,
 			RK3399_CLKGATE_CON(10), 7, GFLAGS),
 
-	COMPOSITE_NOGATE(SCLK_CIF_OUT, "clk_cifout", mux_clk_cif_p, 0,
+	COMPOSITE_NOGATE(SCLK_CIF_OUT, "clk_cifout", mux_clk_cif_p, CLK_SET_RATE_PARENT,
 			 RK3399_CLKSEL_CON(56), 5, 1, MFLAGS, 0, 5, DFLAGS),
 
 	/* gic */
diff --git a/kernel/drivers/clk/rockchip/clk-rk3562.c b/kernel/drivers/clk/rockchip/clk-rk3562.c
index cbf8ddb..3c6f78f 100644
--- a/kernel/drivers/clk/rockchip/clk-rk3562.c
+++ b/kernel/drivers/clk/rockchip/clk-rk3562.c
@@ -137,7 +137,7 @@
 		     0, RK3562_PMU1_PLL_CON(0),
 		     RK3562_PMU1_MODE_CON, 0, 2, 0, rk3562_pll_rates),
 	[dpll] = PLL(pll_rk3328, PLL_DPLL, "dpll", mux_pll_p,
-		     0, RK3562_SUBDDR_PLL_CON(0),
+		     CLK_IS_CRITICAL, RK3562_SUBDDR_PLL_CON(0),
 		     RK3562_SUBDDR_MODE_CON, 0, 1, 0, NULL),
 };
 
@@ -624,7 +624,7 @@
 	COMPOSITE(CLK_UART3_SRC, "clk_uart3_src", gpll_cpll_p, 0,
 			RK3562_PERI_CLKSEL_CON(25), 8, 1, MFLAGS, 0, 7, DFLAGS,
 			RK3562_PERI_CLKGATE_CON(7), 15, GFLAGS),
-	COMPOSITE_FRACMUX(CLK_UART3_FRAC, "clk_uart3_frac", "clk_uart3", CLK_SET_RATE_PARENT,
+	COMPOSITE_FRACMUX(CLK_UART3_FRAC, "clk_uart3_frac", "clk_uart3_src", CLK_SET_RATE_PARENT,
 			RK3562_PERI_CLKSEL_CON(26), 0,
 			RK3562_PERI_CLKGATE_CON(8), 0, GFLAGS,
 			&rk3562_clk_uart3_fracmux),
@@ -1011,10 +1011,10 @@
 			RK3562_CLKGATE_CON(13), 6, GFLAGS),
 	GATE(HCLK_VOP, "hclk_vop", "hclk_vo_pre", 0,
 			RK3562_CLKGATE_CON(13), 7, GFLAGS),
-	COMPOSITE(DCLK_VOP, "dclk_vop", gpll_dmyhpll_vpll_apll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+	COMPOSITE(DCLK_VOP, "dclk_vop", gpll_dmyhpll_vpll_apll_p, CLK_SET_RATE_NO_REPARENT,
 			RK3562_CLKSEL_CON(30), 14, 2, MFLAGS, 0, 8, DFLAGS,
 			RK3562_CLKGATE_CON(13), 8, GFLAGS),
-	COMPOSITE(DCLK_VOP1, "dclk_vop1", gpll_dmyhpll_vpll_apll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+	COMPOSITE(DCLK_VOP1, "dclk_vop1", gpll_dmyhpll_vpll_apll_p, CLK_SET_RATE_NO_REPARENT,
 			RK3562_CLKSEL_CON(31), 14, 2, MFLAGS, 0, 8, DFLAGS,
 			RK3562_CLKGATE_CON(13), 9, GFLAGS),
 };
diff --git a/kernel/drivers/clk/rockchip/clk-rk3568.c b/kernel/drivers/clk/rockchip/clk-rk3568.c
index 79365eb..0f5ed13 100644
--- a/kernel/drivers/clk/rockchip/clk-rk3568.c
+++ b/kernel/drivers/clk/rockchip/clk-rk3568.c
@@ -1068,13 +1068,13 @@
 			RK3568_CLKGATE_CON(20), 8, GFLAGS),
 	GATE(HCLK_VOP, "hclk_vop", "hclk_vo", 0,
 			RK3568_CLKGATE_CON(20), 9, GFLAGS),
-	COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+	COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT,
 			RK3568_CLKSEL_CON(39), 10, 2, MFLAGS, 0, 8, DFLAGS,
 			RK3568_CLKGATE_CON(20), 10, GFLAGS),
-	COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+	COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT,
 			RK3568_CLKSEL_CON(40), 10, 2, MFLAGS, 0, 8, DFLAGS,
 			RK3568_CLKGATE_CON(20), 11, GFLAGS),
-	COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, 0,
+	COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT,
 			RK3568_CLKSEL_CON(41), 10, 2, MFLAGS, 0, 8, DFLAGS,
 			RK3568_CLKGATE_CON(20), 12, GFLAGS),
 	GATE(CLK_VOP_PWM, "clk_vop_pwm", "xin24m", 0,
diff --git a/kernel/drivers/clk/rockchip/clk-rk3588.c b/kernel/drivers/clk/rockchip/clk-rk3588.c
index 4b03505..c297e4e 100644
--- a/kernel/drivers/clk/rockchip/clk-rk3588.c
+++ b/kernel/drivers/clk/rockchip/clk-rk3588.c
@@ -2065,13 +2065,13 @@
 			RK3588_CLKGATE_CON(72), 4, GFLAGS),
 	GATE(HCLK_VOP, "hclk_vop", "hclk_vop_root", 0,
 			RK3588_CLKGATE_CON(52), 8, GFLAGS),
-	COMPOSITE(DCLK_VOP0_SRC, "dclk_vop0_src", gpll_cpll_v0pll_aupll_p, 0,
+	COMPOSITE(DCLK_VOP0_SRC, "dclk_vop0_src", gpll_cpll_v0pll_aupll_p, CLK_SET_RATE_NO_REPARENT,
 			RK3588_CLKSEL_CON(111), 7, 2, MFLAGS, 0, 7, DFLAGS,
 			RK3588_CLKGATE_CON(52), 10, GFLAGS),
-	COMPOSITE(DCLK_VOP1_SRC, "dclk_vop1_src", gpll_cpll_v0pll_aupll_p, 0,
+	COMPOSITE(DCLK_VOP1_SRC, "dclk_vop1_src", gpll_cpll_v0pll_aupll_p, CLK_SET_RATE_NO_REPARENT,
 			RK3588_CLKSEL_CON(111), 14, 2, MFLAGS, 9, 5, DFLAGS,
 			RK3588_CLKGATE_CON(52), 11, GFLAGS),
-	COMPOSITE(DCLK_VOP2_SRC, "dclk_vop2_src", gpll_cpll_v0pll_aupll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+	COMPOSITE(DCLK_VOP2_SRC, "dclk_vop2_src", gpll_cpll_v0pll_aupll_p, CLK_SET_RATE_NO_REPARENT,
 			RK3588_CLKSEL_CON(112), 5, 2, MFLAGS, 0, 5, DFLAGS,
 			RK3588_CLKGATE_CON(52), 12, GFLAGS),
 	COMPOSITE_NODIV(DCLK_VOP0, "dclk_vop0", dclk_vop0_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
@@ -2083,7 +2083,7 @@
 	COMPOSITE_NODIV(DCLK_VOP2, "dclk_vop2", dclk_vop2_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
 			RK3588_CLKSEL_CON(112), 11, 2, MFLAGS,
 			RK3588_CLKGATE_CON(53), 1, GFLAGS),
-	COMPOSITE(DCLK_VOP3, "dclk_vop3", gpll_cpll_v0pll_aupll_p, 0,
+	COMPOSITE(DCLK_VOP3, "dclk_vop3", gpll_cpll_v0pll_aupll_p, CLK_SET_RATE_NO_REPARENT,
 			RK3588_CLKSEL_CON(113), 7, 2, MFLAGS, 0, 7, DFLAGS,
 			RK3588_CLKGATE_CON(53), 2, GFLAGS),
 	GATE(PCLK_DSIHOST0, "pclk_dsihost0", "pclk_vop_root", 0,
diff --git a/kernel/drivers/clk/rockchip/clk.c b/kernel/drivers/clk/rockchip/clk.c
index d0c32dd..1c91007 100644
--- a/kernel/drivers/clk/rockchip/clk.c
+++ b/kernel/drivers/clk/rockchip/clk.c
@@ -24,6 +24,10 @@
 #include <linux/rational.h>
 #include "clk.h"
 
+#ifdef MODULE
+static HLIST_HEAD(clk_ctx_list);
+#endif
+
 /**
  * Register a clock branch.
  * Most clock branches have a form like
@@ -185,6 +189,14 @@
 	struct clk_hw *p_parent;
 	unsigned long scale;
 
+	if (rate == 0) {
+		pr_warn("%s p_rate(%ld), rate(%ld), maybe invalid frequency setting!\n",
+			clk_hw_get_name(hw), *parent_rate, rate);
+		*m = 0;
+		*n = 1;
+		return;
+	}
+
 	p_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
 	if ((rate * 20 > p_rate) && (p_rate % rate != 0)) {
 		p_parent = clk_hw_get_parent(clk_hw_get_parent(hw));
@@ -221,6 +233,13 @@
 	 * for m and n. In the result it will be the nearest rate left shifted
 	 * by (scale - fd->nwidth) bits.
 	 */
+	if (*parent_rate == 0) {
+		pr_warn("%s p_rate(%ld), rate(%ld), maybe invalid frequency setting!\n",
+			clk_hw_get_name(hw), *parent_rate, rate);
+		*m = 0;
+		*n = 1;
+		return;
+	}
 	scale = fls_long(*parent_rate / rate - 1);
 	if (scale > fd->nwidth)
 		rate <<= scale - fd->nwidth;
@@ -417,6 +436,10 @@
 						   "rockchip,grf");
 	ctx->pmugrf = syscon_regmap_lookup_by_phandle(ctx->cru_node,
 						   "rockchip,pmugrf");
+
+#ifdef MODULE
+	hlist_add_head(&ctx->list_node, &clk_ctx_list);
+#endif
 
 	return ctx;
 
@@ -783,4 +806,30 @@
 
 }
 EXPORT_SYMBOL_GPL(rockchip_clk_unprotect);
+
+void rockchip_clk_disable_unused(void)
+{
+	struct rockchip_clk_provider *ctx;
+	struct clk *clk;
+	struct clk_hw *hw;
+	int i = 0, flag = 0;
+
+	hlist_for_each_entry(ctx, &clk_ctx_list, list_node) {
+		for (i = 0; i < ctx->clk_data.clk_num; i++) {
+			clk = ctx->clk_data.clks[i];
+			if (clk && !IS_ERR(clk)) {
+				hw = __clk_get_hw(clk);
+				if (hw)
+					flag = clk_hw_get_flags(hw);
+				if (flag & CLK_IGNORE_UNUSED)
+					continue;
+				if (flag & CLK_IS_CRITICAL)
+					continue;
+				clk_prepare_enable(clk);
+				clk_disable_unprepare(clk);
+			}
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(rockchip_clk_disable_unused);
 #endif /* MODULE */
diff --git a/kernel/drivers/clk/rockchip/clk.h b/kernel/drivers/clk/rockchip/clk.h
index d0212c5..ed525eb 100644
--- a/kernel/drivers/clk/rockchip/clk.h
+++ b/kernel/drivers/clk/rockchip/clk.h
@@ -498,6 +498,7 @@
  * @clk_data: holds clock related data like clk* and number of clocks.
  * @cru_node: device-node of the clock-provider
  * @grf: regmap of the general-register-files syscon
+ * @list_node: node in the global ctx list
  * @lock: maintains exclusion between callbacks for a given clock-provider.
  */
 struct rockchip_clk_provider {
@@ -506,6 +507,7 @@
 	struct device_node *cru_node;
 	struct regmap *grf;
 	struct regmap *pmugrf;
+	struct hlist_node list_node;
 	spinlock_t lock;
 };
 
@@ -1313,6 +1315,7 @@
 int rockchip_clk_protect(struct rockchip_clk_provider *ctx,
 			 unsigned int *clocks, unsigned int nclocks);
 void rockchip_clk_unprotect(void);
+void rockchip_clk_disable_unused(void);
 #else
 static inline int rockchip_clk_protect(struct rockchip_clk_provider *ctx,
 				       unsigned int *clocks,
@@ -1324,5 +1327,9 @@
 static inline void rockchip_clk_unprotect(void)
 {
 }
+
+static inline void rockchip_clk_disable_unused(void)
+{
+}
 #endif
 #endif
diff --git a/kernel/drivers/clk/rockchip/regmap/clk-regmap-fractional-divider.c b/kernel/drivers/clk/rockchip/regmap/clk-regmap-fractional-divider.c
index 3d5f1d2..1acbc16 100644
--- a/kernel/drivers/clk/rockchip/regmap/clk-regmap-fractional-divider.c
+++ b/kernel/drivers/clk/rockchip/regmap/clk-regmap-fractional-divider.c
@@ -47,6 +47,16 @@
 	struct clk_hw *p_parent;
 	unsigned long scale;
 
+	if (!rate) {
+		*m = 0;
+		*n = 1;
+
+		dev_dbg(fd->dev, "%s rate:(%ld) maybe invalid frequency setting!\n",
+			clk_hw_get_name(hw), rate);
+
+		return;
+	}
+
 	p_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
 	if ((rate * 20 > p_rate) && (p_rate % rate != 0)) {
 		p_parent = clk_hw_get_parent(clk_hw_get_parent(hw));
diff --git a/kernel/drivers/clk/samsung/clk-pll.c b/kernel/drivers/clk/samsung/clk-pll.c
index ac70ad7..33df20f 100644
--- a/kernel/drivers/clk/samsung/clk-pll.c
+++ b/kernel/drivers/clk/samsung/clk-pll.c
@@ -1390,6 +1390,7 @@
 	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;
 	}
diff --git a/kernel/drivers/clk/socfpga/clk-gate.c b/kernel/drivers/clk/socfpga/clk-gate.c
index cf94a12..ee2a2d2 100644
--- a/kernel/drivers/clk/socfpga/clk-gate.c
+++ b/kernel/drivers/clk/socfpga/clk-gate.c
@@ -174,21 +174,24 @@
 	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))
 		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)
@@ -238,12 +241,15 @@
 	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(ops);
 		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/kernel/drivers/clk/socfpga/clk-periph.c b/kernel/drivers/clk/socfpga/clk-periph.c
index 5e0c4b4..43707e2 100644
--- a/kernel/drivers/clk/socfpga/clk-periph.c
+++ b/kernel/drivers/clk/socfpga/clk-periph.c
@@ -51,7 +51,7 @@
 	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 @@
 	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/kernel/drivers/clk/socfpga/clk-pll.c b/kernel/drivers/clk/socfpga/clk-pll.c
index e5fb786..dcb573d 100644
--- a/kernel/drivers/clk/socfpga/clk-pll.c
+++ b/kernel/drivers/clk/socfpga/clk-pll.c
@@ -70,17 +70,18 @@
 	.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);
 
@@ -106,13 +107,15 @@
 
 	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);
 	}
-	rc = 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)
diff --git a/kernel/drivers/clk/sprd/common.c b/kernel/drivers/clk/sprd/common.c
index ce81e40..2bfbab8 100644
--- a/kernel/drivers/clk/sprd/common.c
+++ b/kernel/drivers/clk/sprd/common.c
@@ -17,7 +17,6 @@
 	.reg_bits	= 32,
 	.reg_stride	= 4,
 	.val_bits	= 32,
-	.max_register	= 0xffff,
 	.fast_io	= true,
 };
 
@@ -43,6 +42,8 @@
 	struct device *dev = &pdev->dev;
 	struct device_node *node = dev->of_node, *np;
 	struct regmap *regmap;
+	struct resource *res;
+	struct regmap_config reg_config = sprdclk_regmap_config;
 
 	if (of_find_property(node, "sprd,syscon", NULL)) {
 		regmap = syscon_regmap_lookup_by_phandle(node, "sprd,syscon");
@@ -59,12 +60,14 @@
 			return PTR_ERR(regmap);
 		}
 	} else {
-		base = devm_platform_ioremap_resource(pdev, 0);
+		base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 		if (IS_ERR(base))
 			return PTR_ERR(base);
 
+		reg_config.max_register = resource_size(res) - reg_config.reg_stride;
+
 		regmap = devm_regmap_init_mmio(&pdev->dev, base,
-					       &sprdclk_regmap_config);
+					       &reg_config);
 		if (IS_ERR(regmap)) {
 			pr_err("failed to init regmap\n");
 			return PTR_ERR(regmap);
diff --git a/kernel/drivers/clk/st/clkgen-fsyn.c b/kernel/drivers/clk/st/clkgen-fsyn.c
index f1adc85..0e58a7c 100644
--- a/kernel/drivers/clk/st/clkgen-fsyn.c
+++ b/kernel/drivers/clk/st/clkgen-fsyn.c
@@ -942,9 +942,10 @@
 
 	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)),
diff --git a/kernel/drivers/clk/sunxi-ng/ccu_mmc_timing.c b/kernel/drivers/clk/sunxi-ng/ccu_mmc_timing.c
index de33414..c6a6ce9 100644
--- a/kernel/drivers/clk/sunxi-ng/ccu_mmc_timing.c
+++ b/kernel/drivers/clk/sunxi-ng/ccu_mmc_timing.c
@@ -43,7 +43,7 @@
 EXPORT_SYMBOL_GPL(sunxi_ccu_set_mmc_timing_mode);
 
 /**
- * sunxi_ccu_set_mmc_timing_mode: Get the current MMC clock timing mode
+ * sunxi_ccu_get_mmc_timing_mode: Get the current MMC clock timing mode
  * @clk: clock to query
  *
  * Returns 0 if the clock is in old timing mode, > 0 if it is in
diff --git a/kernel/drivers/clk/tegra/clk-bpmp.c b/kernel/drivers/clk/tegra/clk-bpmp.c
index a66263b..0084504 100644
--- a/kernel/drivers/clk/tegra/clk-bpmp.c
+++ b/kernel/drivers/clk/tegra/clk-bpmp.c
@@ -159,7 +159,7 @@
 
 	err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
 	if (err < 0)
-		return err;
+		return 0;
 
 	return response.rate;
 }
diff --git a/kernel/drivers/clk/tegra/clk-tegra124-emc.c b/kernel/drivers/clk/tegra/clk-tegra124-emc.c
index 733a962..15f728e 100644
--- a/kernel/drivers/clk/tegra/clk-tegra124-emc.c
+++ b/kernel/drivers/clk/tegra/clk-tegra124-emc.c
@@ -455,6 +455,7 @@
 		err = load_one_timing_from_dt(tegra, timing, child);
 		if (err) {
 			of_node_put(child);
+			kfree(tegra->timings);
 			return err;
 		}
 
@@ -506,6 +507,7 @@
 		err = load_timings_from_dt(tegra, node, node_ram_code);
 		if (err) {
 			of_node_put(node);
+			kfree(tegra);
 			return ERR_PTR(err);
 		}
 	}
diff --git a/kernel/drivers/clk/tegra/clk-tegra20.c b/kernel/drivers/clk/tegra/clk-tegra20.c
index d60ee6e..fb1da5d 100644
--- a/kernel/drivers/clk/tegra/clk-tegra20.c
+++ b/kernel/drivers/clk/tegra/clk-tegra20.c
@@ -18,24 +18,24 @@
 #define MISC_CLK_ENB 0x48
 
 #define OSC_CTRL 0x50
-#define OSC_CTRL_OSC_FREQ_MASK (3<<30)
-#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
-#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30)
-#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30)
-#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30)
-#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
+#define OSC_CTRL_OSC_FREQ_MASK (3u<<30)
+#define OSC_CTRL_OSC_FREQ_13MHZ (0u<<30)
+#define OSC_CTRL_OSC_FREQ_19_2MHZ (1u<<30)
+#define OSC_CTRL_OSC_FREQ_12MHZ (2u<<30)
+#define OSC_CTRL_OSC_FREQ_26MHZ (3u<<30)
+#define OSC_CTRL_MASK (0x3f2u | OSC_CTRL_OSC_FREQ_MASK)
 
-#define OSC_CTRL_PLL_REF_DIV_MASK (3<<28)
-#define OSC_CTRL_PLL_REF_DIV_1		(0<<28)
-#define OSC_CTRL_PLL_REF_DIV_2		(1<<28)
-#define OSC_CTRL_PLL_REF_DIV_4		(2<<28)
+#define OSC_CTRL_PLL_REF_DIV_MASK	(3u<<28)
+#define OSC_CTRL_PLL_REF_DIV_1		(0u<<28)
+#define OSC_CTRL_PLL_REF_DIV_2		(1u<<28)
+#define OSC_CTRL_PLL_REF_DIV_4		(2u<<28)
 
 #define OSC_FREQ_DET 0x58
-#define OSC_FREQ_DET_TRIG (1<<31)
+#define OSC_FREQ_DET_TRIG (1u<<31)
 
 #define OSC_FREQ_DET_STATUS 0x5c
-#define OSC_FREQ_DET_BUSY (1<<31)
-#define OSC_FREQ_DET_CNT_MASK 0xFFFF
+#define OSC_FREQ_DET_BUSYu (1<<31)
+#define OSC_FREQ_DET_CNT_MASK 0xFFFFu
 
 #define TEGRA20_CLK_PERIPH_BANKS	3
 
diff --git a/kernel/drivers/clk/ti/clkctrl.c b/kernel/drivers/clk/ti/clkctrl.c
index 864c484..157abc4 100644
--- a/kernel/drivers/clk/ti/clkctrl.c
+++ b/kernel/drivers/clk/ti/clkctrl.c
@@ -267,6 +267,9 @@
 	if (clkctrl_name && !legacy_naming) {
 		clock_name = kasprintf(GFP_KERNEL, "%s-clkctrl:%04x:%d",
 				       clkctrl_name, offset, index);
+		if (!clock_name)
+			return NULL;
+
 		strreplace(clock_name, '_', '-');
 
 		return clock_name;
@@ -598,6 +601,10 @@
 	if (clkctrl_name) {
 		provider->clkdm_name = kasprintf(GFP_KERNEL,
 						 "%s_clkdm", clkctrl_name);
+		if (!provider->clkdm_name) {
+			kfree(provider);
+			return;
+		}
 		goto clkdm_found;
 	}
 
diff --git a/kernel/drivers/clk/x86/Kconfig b/kernel/drivers/clk/x86/Kconfig
index 69642e1..ced99e0 100644
--- a/kernel/drivers/clk/x86/Kconfig
+++ b/kernel/drivers/clk/x86/Kconfig
@@ -1,8 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config CLK_LGM_CGU
 	depends on OF && HAS_IOMEM && (X86 || COMPILE_TEST)
+	select MFD_SYSCON
 	select OF_EARLY_FLATTREE
 	bool "Clock driver for Lightning Mountain(LGM) platform"
 	help
-	  Clock Generation Unit(CGU) driver for Intel Lightning Mountain(LGM)
-	  network processor SoC.
+	  Clock Generation Unit(CGU) driver for MaxLinear's x86 based
+	  Lightning Mountain(LGM) network processor SoC.
diff --git a/kernel/drivers/clk/x86/clk-cgu-pll.c b/kernel/drivers/clk/x86/clk-cgu-pll.c
index 3179557..409dbf5 100644
--- a/kernel/drivers/clk/x86/clk-cgu-pll.c
+++ b/kernel/drivers/clk/x86/clk-cgu-pll.c
@@ -1,8 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
+ * Copyright (C) 2020-2022 MaxLinear, Inc.
  * Copyright (C) 2020 Intel Corporation.
- * Zhu YiXin <yixin.zhu@intel.com>
- * Rahul Tanwar <rahul.tanwar@intel.com>
+ * Zhu Yixin <yzhu@maxlinear.com>
+ * Rahul Tanwar <rtanwar@maxlinear.com>
  */
 
 #include <linux/clk-provider.h>
@@ -40,13 +41,10 @@
 {
 	struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
 	unsigned int div, mult, frac;
-	unsigned long flags;
 
-	spin_lock_irqsave(&pll->lock, flags);
 	mult = lgm_get_clk_val(pll->membase, PLL_REF_DIV(pll->reg), 0, 12);
 	div = lgm_get_clk_val(pll->membase, PLL_REF_DIV(pll->reg), 18, 6);
 	frac = lgm_get_clk_val(pll->membase, pll->reg, 2, 24);
-	spin_unlock_irqrestore(&pll->lock, flags);
 
 	if (pll->type == TYPE_LJPLL)
 		div *= 4;
@@ -57,12 +55,9 @@
 static int lgm_pll_is_enabled(struct clk_hw *hw)
 {
 	struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
-	unsigned long flags;
 	unsigned int ret;
 
-	spin_lock_irqsave(&pll->lock, flags);
 	ret = lgm_get_clk_val(pll->membase, pll->reg, 0, 1);
-	spin_unlock_irqrestore(&pll->lock, flags);
 
 	return ret;
 }
@@ -70,15 +65,13 @@
 static int lgm_pll_enable(struct clk_hw *hw)
 {
 	struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
-	unsigned long flags;
 	u32 val;
 	int ret;
 
-	spin_lock_irqsave(&pll->lock, flags);
 	lgm_set_clk_val(pll->membase, pll->reg, 0, 1, 1);
-	ret = readl_poll_timeout_atomic(pll->membase + pll->reg,
-					val, (val & 0x1), 1, 100);
-	spin_unlock_irqrestore(&pll->lock, flags);
+	ret = regmap_read_poll_timeout_atomic(pll->membase, pll->reg,
+					      val, (val & 0x1), 1, 100);
+
 
 	return ret;
 }
@@ -86,11 +79,8 @@
 static void lgm_pll_disable(struct clk_hw *hw)
 {
 	struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
-	unsigned long flags;
 
-	spin_lock_irqsave(&pll->lock, flags);
 	lgm_set_clk_val(pll->membase, pll->reg, 0, 1, 0);
-	spin_unlock_irqrestore(&pll->lock, flags);
 }
 
 static const struct clk_ops lgm_pll_ops = {
@@ -121,7 +111,6 @@
 		return ERR_PTR(-ENOMEM);
 
 	pll->membase = ctx->membase;
-	pll->lock = ctx->lock;
 	pll->reg = list->reg;
 	pll->flags = list->flags;
 	pll->type = list->type;
diff --git a/kernel/drivers/clk/x86/clk-cgu.c b/kernel/drivers/clk/x86/clk-cgu.c
index 33de600..89b53f2 100644
--- a/kernel/drivers/clk/x86/clk-cgu.c
+++ b/kernel/drivers/clk/x86/clk-cgu.c
@@ -1,8 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
+ * Copyright (C) 2020-2022 MaxLinear, Inc.
  * Copyright (C) 2020 Intel Corporation.
- * Zhu YiXin <yixin.zhu@intel.com>
- * Rahul Tanwar <rahul.tanwar@intel.com>
+ * Zhu Yixin <yzhu@maxlinear.com>
+ * Rahul Tanwar <rtanwar@maxlinear.com>
  */
 #include <linux/clk-provider.h>
 #include <linux/device.h>
@@ -24,14 +25,10 @@
 static struct clk_hw *lgm_clk_register_fixed(struct lgm_clk_provider *ctx,
 					     const struct lgm_clk_branch *list)
 {
-	unsigned long flags;
 
-	if (list->div_flags & CLOCK_FLAG_VAL_INIT) {
-		spin_lock_irqsave(&ctx->lock, flags);
+	if (list->div_flags & CLOCK_FLAG_VAL_INIT)
 		lgm_set_clk_val(ctx->membase, list->div_off, list->div_shift,
 				list->div_width, list->div_val);
-		spin_unlock_irqrestore(&ctx->lock, flags);
-	}
 
 	return clk_hw_register_fixed_rate(NULL, list->name,
 					  list->parent_data[0].name,
@@ -41,33 +38,27 @@
 static u8 lgm_clk_mux_get_parent(struct clk_hw *hw)
 {
 	struct lgm_clk_mux *mux = to_lgm_clk_mux(hw);
-	unsigned long flags;
 	u32 val;
 
-	spin_lock_irqsave(&mux->lock, flags);
 	if (mux->flags & MUX_CLK_SW)
 		val = mux->reg;
 	else
 		val = lgm_get_clk_val(mux->membase, mux->reg, mux->shift,
 				      mux->width);
-	spin_unlock_irqrestore(&mux->lock, flags);
 	return clk_mux_val_to_index(hw, NULL, mux->flags, val);
 }
 
 static int lgm_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 {
 	struct lgm_clk_mux *mux = to_lgm_clk_mux(hw);
-	unsigned long flags;
 	u32 val;
 
 	val = clk_mux_index_to_val(NULL, mux->flags, index);
-	spin_lock_irqsave(&mux->lock, flags);
 	if (mux->flags & MUX_CLK_SW)
 		mux->reg = val;
 	else
 		lgm_set_clk_val(mux->membase, mux->reg, mux->shift,
 				mux->width, val);
-	spin_unlock_irqrestore(&mux->lock, flags);
 
 	return 0;
 }
@@ -90,7 +81,7 @@
 lgm_clk_register_mux(struct lgm_clk_provider *ctx,
 		     const struct lgm_clk_branch *list)
 {
-	unsigned long flags, cflags = list->mux_flags;
+	unsigned long cflags = list->mux_flags;
 	struct device *dev = ctx->dev;
 	u8 shift = list->mux_shift;
 	u8 width = list->mux_width;
@@ -111,7 +102,6 @@
 	init.num_parents = list->num_parents;
 
 	mux->membase = ctx->membase;
-	mux->lock = ctx->lock;
 	mux->reg = reg;
 	mux->shift = shift;
 	mux->width = width;
@@ -123,11 +113,8 @@
 	if (ret)
 		return ERR_PTR(ret);
 
-	if (cflags & CLOCK_FLAG_VAL_INIT) {
-		spin_lock_irqsave(&mux->lock, flags);
+	if (cflags & CLOCK_FLAG_VAL_INIT)
 		lgm_set_clk_val(mux->membase, reg, shift, width, list->mux_val);
-		spin_unlock_irqrestore(&mux->lock, flags);
-	}
 
 	return hw;
 }
@@ -136,13 +123,10 @@
 lgm_clk_divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 {
 	struct lgm_clk_divider *divider = to_lgm_clk_divider(hw);
-	unsigned long flags;
 	unsigned int val;
 
-	spin_lock_irqsave(&divider->lock, flags);
 	val = lgm_get_clk_val(divider->membase, divider->reg,
 			      divider->shift, divider->width);
-	spin_unlock_irqrestore(&divider->lock, flags);
 
 	return divider_recalc_rate(hw, parent_rate, val, divider->table,
 				   divider->flags, divider->width);
@@ -163,7 +147,6 @@
 			 unsigned long prate)
 {
 	struct lgm_clk_divider *divider = to_lgm_clk_divider(hw);
-	unsigned long flags;
 	int value;
 
 	value = divider_get_val(rate, prate, divider->table,
@@ -171,10 +154,8 @@
 	if (value < 0)
 		return value;
 
-	spin_lock_irqsave(&divider->lock, flags);
 	lgm_set_clk_val(divider->membase, divider->reg,
 			divider->shift, divider->width, value);
-	spin_unlock_irqrestore(&divider->lock, flags);
 
 	return 0;
 }
@@ -182,12 +163,10 @@
 static int lgm_clk_divider_enable_disable(struct clk_hw *hw, int enable)
 {
 	struct lgm_clk_divider *div = to_lgm_clk_divider(hw);
-	unsigned long flags;
 
-	spin_lock_irqsave(&div->lock, flags);
-	lgm_set_clk_val(div->membase, div->reg, div->shift_gate,
-			div->width_gate, enable);
-	spin_unlock_irqrestore(&div->lock, flags);
+	if (div->flags != DIV_CLK_NO_MASK)
+		lgm_set_clk_val(div->membase, div->reg, div->shift_gate,
+				div->width_gate, enable);
 	return 0;
 }
 
@@ -213,7 +192,7 @@
 lgm_clk_register_divider(struct lgm_clk_provider *ctx,
 			 const struct lgm_clk_branch *list)
 {
-	unsigned long flags, cflags = list->div_flags;
+	unsigned long cflags = list->div_flags;
 	struct device *dev = ctx->dev;
 	struct lgm_clk_divider *div;
 	struct clk_init_data init = {};
@@ -236,7 +215,6 @@
 	init.num_parents = 1;
 
 	div->membase = ctx->membase;
-	div->lock = ctx->lock;
 	div->reg = reg;
 	div->shift = shift;
 	div->width = width;
@@ -251,11 +229,8 @@
 	if (ret)
 		return ERR_PTR(ret);
 
-	if (cflags & CLOCK_FLAG_VAL_INIT) {
-		spin_lock_irqsave(&div->lock, flags);
+	if (cflags & CLOCK_FLAG_VAL_INIT)
 		lgm_set_clk_val(div->membase, reg, shift, width, list->div_val);
-		spin_unlock_irqrestore(&div->lock, flags);
-	}
 
 	return hw;
 }
@@ -264,7 +239,6 @@
 lgm_clk_register_fixed_factor(struct lgm_clk_provider *ctx,
 			      const struct lgm_clk_branch *list)
 {
-	unsigned long flags;
 	struct clk_hw *hw;
 
 	hw = clk_hw_register_fixed_factor(ctx->dev, list->name,
@@ -273,12 +247,9 @@
 	if (IS_ERR(hw))
 		return ERR_CAST(hw);
 
-	if (list->div_flags & CLOCK_FLAG_VAL_INIT) {
-		spin_lock_irqsave(&ctx->lock, flags);
+	if (list->div_flags & CLOCK_FLAG_VAL_INIT)
 		lgm_set_clk_val(ctx->membase, list->div_off, list->div_shift,
 				list->div_width, list->div_val);
-		spin_unlock_irqrestore(&ctx->lock, flags);
-	}
 
 	return hw;
 }
@@ -286,13 +257,10 @@
 static int lgm_clk_gate_enable(struct clk_hw *hw)
 {
 	struct lgm_clk_gate *gate = to_lgm_clk_gate(hw);
-	unsigned long flags;
 	unsigned int reg;
 
-	spin_lock_irqsave(&gate->lock, flags);
 	reg = GATE_HW_REG_EN(gate->reg);
 	lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1);
-	spin_unlock_irqrestore(&gate->lock, flags);
 
 	return 0;
 }
@@ -300,25 +268,19 @@
 static void lgm_clk_gate_disable(struct clk_hw *hw)
 {
 	struct lgm_clk_gate *gate = to_lgm_clk_gate(hw);
-	unsigned long flags;
 	unsigned int reg;
 
-	spin_lock_irqsave(&gate->lock, flags);
 	reg = GATE_HW_REG_DIS(gate->reg);
 	lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1);
-	spin_unlock_irqrestore(&gate->lock, flags);
 }
 
 static int lgm_clk_gate_is_enabled(struct clk_hw *hw)
 {
 	struct lgm_clk_gate *gate = to_lgm_clk_gate(hw);
 	unsigned int reg, ret;
-	unsigned long flags;
 
-	spin_lock_irqsave(&gate->lock, flags);
 	reg = GATE_HW_REG_STAT(gate->reg);
 	ret = lgm_get_clk_val(gate->membase, reg, gate->shift, 1);
-	spin_unlock_irqrestore(&gate->lock, flags);
 
 	return ret;
 }
@@ -333,7 +295,7 @@
 lgm_clk_register_gate(struct lgm_clk_provider *ctx,
 		      const struct lgm_clk_branch *list)
 {
-	unsigned long flags, cflags = list->gate_flags;
+	unsigned long cflags = list->gate_flags;
 	const char *pname = list->parent_data[0].name;
 	struct device *dev = ctx->dev;
 	u8 shift = list->gate_shift;
@@ -354,7 +316,6 @@
 	init.num_parents = pname ? 1 : 0;
 
 	gate->membase = ctx->membase;
-	gate->lock = ctx->lock;
 	gate->reg = reg;
 	gate->shift = shift;
 	gate->flags = cflags;
@@ -366,9 +327,7 @@
 		return ERR_PTR(ret);
 
 	if (cflags & CLOCK_FLAG_VAL_INIT) {
-		spin_lock_irqsave(&gate->lock, flags);
 		lgm_set_clk_val(gate->membase, reg, shift, 1, list->gate_val);
-		spin_unlock_irqrestore(&gate->lock, flags);
 	}
 
 	return hw;
@@ -396,8 +355,22 @@
 			hw = lgm_clk_register_fixed_factor(ctx, list);
 			break;
 		case CLK_TYPE_GATE:
-			hw = lgm_clk_register_gate(ctx, list);
+			if (list->gate_flags & GATE_CLK_HW) {
+				hw = lgm_clk_register_gate(ctx, list);
+			} else {
+				/*
+				 * GATE_CLKs can be controlled either from
+				 * CGU clk driver i.e. this driver or directly
+				 * from power management driver/daemon. It is
+				 * dependent on the power policy/profile requirements
+				 * of the end product. To override control of gate
+				 * clks from this driver, provide NULL for this index
+				 * of gate clk provider.
+				 */
+				hw = NULL;
+			}
 			break;
+
 		default:
 			dev_err(ctx->dev, "invalid clk type\n");
 			return -EINVAL;
@@ -443,24 +416,18 @@
 static int lgm_clk_ddiv_enable(struct clk_hw *hw)
 {
 	struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
-	unsigned long flags;
 
-	spin_lock_irqsave(&ddiv->lock, flags);
 	lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate,
 			ddiv->width_gate, 1);
-	spin_unlock_irqrestore(&ddiv->lock, flags);
 	return 0;
 }
 
 static void lgm_clk_ddiv_disable(struct clk_hw *hw)
 {
 	struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
-	unsigned long flags;
 
-	spin_lock_irqsave(&ddiv->lock, flags);
 	lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate,
 			ddiv->width_gate, 0);
-	spin_unlock_irqrestore(&ddiv->lock, flags);
 }
 
 static int
@@ -497,32 +464,25 @@
 {
 	struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
 	u32 div, ddiv1, ddiv2;
-	unsigned long flags;
 
 	div = DIV_ROUND_CLOSEST_ULL((u64)prate, rate);
 
-	spin_lock_irqsave(&ddiv->lock, flags);
 	if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
 		div = DIV_ROUND_CLOSEST_ULL((u64)div, 5);
 		div = div * 2;
 	}
 
-	if (div <= 0) {
-		spin_unlock_irqrestore(&ddiv->lock, flags);
+	if (div <= 0)
 		return -EINVAL;
-	}
 
-	if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2)) {
-		spin_unlock_irqrestore(&ddiv->lock, flags);
+	if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2))
 		return -EINVAL;
-	}
 
 	lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift0, ddiv->width0,
 			ddiv1 - 1);
 
 	lgm_set_clk_val(ddiv->membase, ddiv->reg,  ddiv->shift1, ddiv->width1,
 			ddiv2 - 1);
-	spin_unlock_irqrestore(&ddiv->lock, flags);
 
 	return 0;
 }
@@ -533,18 +493,15 @@
 {
 	struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
 	u32 div, ddiv1, ddiv2;
-	unsigned long flags;
 	u64 rate64;
 
 	div = DIV_ROUND_CLOSEST_ULL((u64)*prate, rate);
 
 	/* if predivide bit is enabled, modify div by factor of 2.5 */
-	spin_lock_irqsave(&ddiv->lock, flags);
 	if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
 		div = div * 2;
 		div = DIV_ROUND_CLOSEST_ULL((u64)div, 5);
 	}
-	spin_unlock_irqrestore(&ddiv->lock, flags);
 
 	if (div <= 0)
 		return *prate;
@@ -558,12 +515,10 @@
 	do_div(rate64, ddiv2);
 
 	/* if predivide bit is enabled, modify rounded rate by factor of 2.5 */
-	spin_lock_irqsave(&ddiv->lock, flags);
 	if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
 		rate64 = rate64 * 2;
 		rate64 = DIV_ROUND_CLOSEST_ULL(rate64, 5);
 	}
-	spin_unlock_irqrestore(&ddiv->lock, flags);
 
 	return rate64;
 }
@@ -600,7 +555,6 @@
 		init.num_parents = 1;
 
 		ddiv->membase = ctx->membase;
-		ddiv->lock = ctx->lock;
 		ddiv->reg = list->reg;
 		ddiv->shift0 = list->shift0;
 		ddiv->width0 = list->width0;
diff --git a/kernel/drivers/clk/x86/clk-cgu.h b/kernel/drivers/clk/x86/clk-cgu.h
index 4e22bfb..bcaf8ae 100644
--- a/kernel/drivers/clk/x86/clk-cgu.h
+++ b/kernel/drivers/clk/x86/clk-cgu.h
@@ -1,28 +1,28 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Copyright(c) 2020 Intel Corporation.
- * Zhu YiXin <yixin.zhu@intel.com>
- * Rahul Tanwar <rahul.tanwar@intel.com>
+ * Copyright (C) 2020-2022 MaxLinear, Inc.
+ * Copyright (C) 2020 Intel Corporation.
+ * Zhu Yixin <yzhu@maxlinear.com>
+ * Rahul Tanwar <rtanwar@maxlinear.com>
  */
 
 #ifndef __CLK_CGU_H
 #define __CLK_CGU_H
 
-#include <linux/io.h>
+#include <linux/regmap.h>
 
 struct lgm_clk_mux {
 	struct clk_hw hw;
-	void __iomem *membase;
+	struct regmap *membase;
 	unsigned int reg;
 	u8 shift;
 	u8 width;
 	unsigned long flags;
-	spinlock_t lock;
 };
 
 struct lgm_clk_divider {
 	struct clk_hw hw;
-	void __iomem *membase;
+	struct regmap *membase;
 	unsigned int reg;
 	u8 shift;
 	u8 width;
@@ -30,12 +30,11 @@
 	u8 width_gate;
 	unsigned long flags;
 	const struct clk_div_table *table;
-	spinlock_t lock;
 };
 
 struct lgm_clk_ddiv {
 	struct clk_hw hw;
-	void __iomem *membase;
+	struct regmap *membase;
 	unsigned int reg;
 	u8 shift0;
 	u8 width0;
@@ -48,16 +47,14 @@
 	unsigned int mult;
 	unsigned int div;
 	unsigned long flags;
-	spinlock_t lock;
 };
 
 struct lgm_clk_gate {
 	struct clk_hw hw;
-	void __iomem *membase;
+	struct regmap *membase;
 	unsigned int reg;
 	u8 shift;
 	unsigned long flags;
-	spinlock_t lock;
 };
 
 enum lgm_clk_type {
@@ -77,11 +74,10 @@
  * @clk_data: array of hw clocks and clk number.
  */
 struct lgm_clk_provider {
-	void __iomem *membase;
+	struct regmap *membase;
 	struct device_node *np;
 	struct device *dev;
 	struct clk_hw_onecell_data clk_data;
-	spinlock_t lock;
 };
 
 enum pll_type {
@@ -92,11 +88,10 @@
 
 struct lgm_clk_pll {
 	struct clk_hw hw;
-	void __iomem *membase;
+	struct regmap *membase;
 	unsigned int reg;
 	unsigned long flags;
 	enum pll_type type;
-	spinlock_t lock;
 };
 
 /**
@@ -202,6 +197,8 @@
 /* clock flags definition */
 #define CLOCK_FLAG_VAL_INIT	BIT(16)
 #define MUX_CLK_SW		BIT(17)
+#define GATE_CLK_HW		BIT(18)
+#define DIV_CLK_NO_MASK		BIT(19)
 
 #define LGM_MUX(_id, _name, _pdata, _f, _reg,		\
 		_shift, _width, _cf, _v)		\
@@ -300,29 +297,32 @@
 		.div = _d,					\
 	}
 
-static inline void lgm_set_clk_val(void __iomem *membase, u32 reg,
+static inline void lgm_set_clk_val(struct regmap *membase, u32 reg,
 				   u8 shift, u8 width, u32 set_val)
 {
 	u32 mask = (GENMASK(width - 1, 0) << shift);
-	u32 regval;
 
-	regval = readl(membase + reg);
-	regval = (regval & ~mask) | ((set_val << shift) & mask);
-	writel(regval, membase + reg);
+	regmap_update_bits(membase, reg, mask, set_val << shift);
 }
 
-static inline u32 lgm_get_clk_val(void __iomem *membase, u32 reg,
+static inline u32 lgm_get_clk_val(struct regmap *membase, u32 reg,
 				  u8 shift, u8 width)
 {
 	u32 mask = (GENMASK(width - 1, 0) << shift);
 	u32 val;
 
-	val = readl(membase + reg);
+	if (regmap_read(membase, reg, &val)) {
+		WARN_ONCE(1, "Failed to read clk reg: 0x%x\n", reg);
+		return 0;
+	}
+
 	val = (val & mask) >> shift;
 
 	return val;
 }
 
+
+
 int lgm_clk_register_branches(struct lgm_clk_provider *ctx,
 			      const struct lgm_clk_branch *list,
 			      unsigned int nr_clk);
diff --git a/kernel/drivers/clk/x86/clk-lgm.c b/kernel/drivers/clk/x86/clk-lgm.c
index 020f4e8..f69455d 100644
--- a/kernel/drivers/clk/x86/clk-lgm.c
+++ b/kernel/drivers/clk/x86/clk-lgm.c
@@ -1,10 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
+ * Copyright (C) 2020-2022 MaxLinear, Inc.
  * Copyright (C) 2020 Intel Corporation.
- * Zhu YiXin <yixin.zhu@intel.com>
- * Rahul Tanwar <rahul.tanwar@intel.com>
+ * Zhu Yixin <yzhu@maxlinear.com>
+ * Rahul Tanwar <rtanwar@maxlinear.com>
  */
 #include <linux/clk-provider.h>
+#include <linux/mfd/syscon.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <dt-bindings/clock/intel,lgm-clk.h>
@@ -253,8 +255,8 @@
 	LGM_FIXED(LGM_CLK_SLIC, "slic", NULL, 0, CGU_IF_CLK1,
 		  8, 2, CLOCK_FLAG_VAL_INIT, 8192000, 2),
 	LGM_FIXED(LGM_CLK_DOCSIS, "v_docsis", NULL, 0, 0, 0, 0, 0, 16000000, 0),
-	LGM_DIV(LGM_CLK_DCL, "dcl", "v_ifclk", 0, CGU_PCMCR,
-		25, 3, 0, 0, 0, 0, dcl_div),
+	LGM_DIV(LGM_CLK_DCL, "dcl", "v_ifclk", CLK_SET_RATE_PARENT, CGU_PCMCR,
+		25, 3, 0, 0, DIV_CLK_NO_MASK, 0, dcl_div),
 	LGM_MUX(LGM_CLK_PCM, "pcm", pcm_p, 0, CGU_C55_PCMCR,
 		0, 1, CLK_MUX_ROUND_CLOSEST, 0),
 	LGM_FIXED_FACTOR(LGM_CLK_DDR_PHY, "ddr_phy", "ddr",
@@ -433,13 +435,15 @@
 
 	ctx->clk_data.num = CLK_NR_CLKS;
 
-	ctx->membase = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(ctx->membase))
+	ctx->membase = syscon_node_to_regmap(np);
+	if (IS_ERR(ctx->membase)) {
+		dev_err(dev, "Failed to get clk CGU iomem\n");
 		return PTR_ERR(ctx->membase);
+	}
+
 
 	ctx->np = np;
 	ctx->dev = dev;
-	spin_lock_init(&ctx->lock);
 
 	ret = lgm_clk_register_plls(ctx, lgm_pll_clks,
 				    ARRAY_SIZE(lgm_pll_clks));
diff --git a/kernel/drivers/clocksource/sh_cmt.c b/kernel/drivers/clocksource/sh_cmt.c
index 09be548..89cddbf 100644
--- a/kernel/drivers/clocksource/sh_cmt.c
+++ b/kernel/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 @@
 	void __iomem *mapbase;
 	struct clk *clk;
 	unsigned long rate;
+	unsigned int reg_delay;
 
 	raw_spinlock_t lock; /* Protect the shared start/stop register */
 
@@ -235,6 +237,8 @@
 #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)
@@ -245,10 +249,17 @@
 
 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)
@@ -258,7 +269,12 @@
 
 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)
@@ -266,14 +282,33 @@
 	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)
@@ -317,7 +352,7 @@
 
 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);
@@ -345,26 +380,9 @@
 	}
 
 	sh_cmt_write_cmcor(ch, 0xffffffff);
-	sh_cmt_write_cmcnt(ch, 0);
+	ret = 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);
-	}
-
-	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;
@@ -849,6 +867,7 @@
 				unsigned int hwidx, bool clockevent,
 				bool clocksource, struct sh_cmt_device *cmt)
 {
+	u32 value;
 	int ret;
 
 	/* Skip unused channels. */
@@ -878,6 +897,11 @@
 		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;
 	}
 
@@ -968,8 +992,8 @@
 
 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;
@@ -1005,17 +1029,21 @@
 	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;
+	}
 
-	clk_disable(cmt->clk);
+	/* 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);
 	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 +1071,8 @@
 		mask &= ~(1 << hwidx);
 	}
 
+	clk_disable(cmt->clk);
+
 	platform_set_drvdata(pdev, cmt);
 
 	return 0;
@@ -1050,6 +1080,8 @@
 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:
diff --git a/kernel/drivers/clocksource/timer-cadence-ttc.c b/kernel/drivers/clocksource/timer-cadence-ttc.c
index 4efd0cf..0d52e28 100644
--- a/kernel/drivers/clocksource/timer-cadence-ttc.c
+++ b/kernel/drivers/clocksource/timer-cadence-ttc.c
@@ -486,10 +486,10 @@
 	 * and use it. Note that the event timer uses the interrupt and it's the
 	 * 2nd TTC hence the irq_of_parse_and_map(,1)
 	 */
-	timer_baseaddr = of_iomap(timer, 0);
-	if (!timer_baseaddr) {
+	timer_baseaddr = devm_of_iomap(&pdev->dev, timer, 0, NULL);
+	if (IS_ERR(timer_baseaddr)) {
 		pr_err("ERROR: invalid timer base address\n");
-		return -ENXIO;
+		return PTR_ERR(timer_baseaddr);
 	}
 
 	irq = irq_of_parse_and_map(timer, 1);
@@ -513,20 +513,27 @@
 	clk_ce = of_clk_get(timer, clksel);
 	if (IS_ERR(clk_ce)) {
 		pr_err("ERROR: timer input clock not found\n");
-		return PTR_ERR(clk_ce);
+		ret = PTR_ERR(clk_ce);
+		goto put_clk_cs;
 	}
 
 	ret = ttc_setup_clocksource(clk_cs, timer_baseaddr, timer_width);
 	if (ret)
-		return ret;
+		goto put_clk_ce;
 
 	ret = ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq);
 	if (ret)
-		return ret;
+		goto put_clk_ce;
 
 	pr_info("%pOFn #0 at %p, irq=%d\n", timer, timer_baseaddr, irq);
 
 	return 0;
+
+put_clk_ce:
+	clk_put(clk_ce);
+put_clk_cs:
+	clk_put(clk_cs);
+	return ret;
 }
 
 static const struct of_device_id ttc_timer_of_match[] = {
diff --git a/kernel/drivers/clocksource/timer-davinci.c b/kernel/drivers/clocksource/timer-davinci.c
index bb4eee3..3dc0c6c 100644
--- a/kernel/drivers/clocksource/timer-davinci.c
+++ b/kernel/drivers/clocksource/timer-davinci.c
@@ -258,21 +258,25 @@
 				resource_size(&timer_cfg->reg),
 				"davinci-timer")) {
 		pr_err("Unable to request memory region\n");
-		return -EBUSY;
+		rv = -EBUSY;
+		goto exit_clk_disable;
 	}
 
 	base = ioremap(timer_cfg->reg.start, resource_size(&timer_cfg->reg));
 	if (!base) {
 		pr_err("Unable to map the register range\n");
-		return -ENOMEM;
+		rv = -ENOMEM;
+		goto exit_mem_region;
 	}
 
 	davinci_timer_init(base);
 	tick_rate = clk_get_rate(clk);
 
 	clockevent = kzalloc(sizeof(*clockevent), GFP_KERNEL);
-	if (!clockevent)
-		return -ENOMEM;
+	if (!clockevent) {
+		rv = -ENOMEM;
+		goto exit_iounmap_base;
+	}
 
 	clockevent->dev.name = "tim12";
 	clockevent->dev.features = CLOCK_EVT_FEAT_ONESHOT;
@@ -297,7 +301,7 @@
 			 "clockevent/tim12", clockevent);
 	if (rv) {
 		pr_err("Unable to request the clockevent interrupt\n");
-		return rv;
+		goto exit_free_clockevent;
 	}
 
 	davinci_clocksource.dev.rating = 300;
@@ -324,13 +328,27 @@
 	rv = clocksource_register_hz(&davinci_clocksource.dev, tick_rate);
 	if (rv) {
 		pr_err("Unable to register clocksource\n");
-		return rv;
+		goto exit_free_irq;
 	}
 
 	sched_clock_register(davinci_timer_read_sched_clock,
 			     DAVINCI_TIMER_CLKSRC_BITS, tick_rate);
 
 	return 0;
+
+exit_free_irq:
+	free_irq(timer_cfg->irq[DAVINCI_TIMER_CLOCKEVENT_IRQ].start,
+			clockevent);
+exit_free_clockevent:
+	kfree(clockevent);
+exit_iounmap_base:
+	iounmap(base);
+exit_mem_region:
+	release_mem_region(timer_cfg->reg.start,
+			   resource_size(&timer_cfg->reg));
+exit_clk_disable:
+	clk_disable_unprepare(clk);
+	return rv;
 }
 
 static int __init of_davinci_timer_register(struct device_node *np)
diff --git a/kernel/drivers/clocksource/timer-ti-dm-systimer.c b/kernel/drivers/clocksource/timer-ti-dm-systimer.c
index 2737407..632523c 100644
--- a/kernel/drivers/clocksource/timer-ti-dm-systimer.c
+++ b/kernel/drivers/clocksource/timer-ti-dm-systimer.c
@@ -345,8 +345,10 @@
 		return error;
 
 	r = clk_get_rate(clock);
-	if (!r)
+	if (!r) {
+		clk_disable_unprepare(clock);
 		return -ENODEV;
+	}
 
 	if (is_ick)
 		t->ick = clock;
diff --git a/kernel/drivers/counter/104-quad-8.c b/kernel/drivers/counter/104-quad-8.c
index 21bb2bb..89c9cb8 100644
--- a/kernel/drivers/counter/104-quad-8.c
+++ b/kernel/drivers/counter/104-quad-8.c
@@ -62,10 +62,6 @@
 #define QUAD8_REG_CHAN_OP 0x11
 #define QUAD8_REG_INDEX_INPUT_LEVELS 0x16
 #define QUAD8_DIFF_ENCODER_CABLE_STATUS 0x17
-/* Borrow Toggle flip-flop */
-#define QUAD8_FLAG_BT BIT(0)
-/* Carry Toggle flip-flop */
-#define QUAD8_FLAG_CT BIT(1)
 /* Error flag */
 #define QUAD8_FLAG_E BIT(4)
 /* Up/Down flag */
@@ -104,9 +100,6 @@
 {
 	struct quad8_iio *const priv = iio_priv(indio_dev);
 	const int base_offset = priv->base + 2 * chan->channel;
-	unsigned int flags;
-	unsigned int borrow;
-	unsigned int carry;
 	int i;
 
 	switch (mask) {
@@ -117,12 +110,7 @@
 			return IIO_VAL_INT;
 		}
 
-		flags = inb(base_offset + 1);
-		borrow = flags & QUAD8_FLAG_BT;
-		carry = !!(flags & QUAD8_FLAG_CT);
-
-		/* Borrow XOR Carry effectively doubles count range */
-		*val = (borrow ^ carry) << 24;
+		*val = 0;
 
 		mutex_lock(&priv->lock);
 
@@ -643,17 +631,9 @@
 {
 	struct quad8_iio *const priv = counter->priv;
 	const int base_offset = priv->base + 2 * count->id;
-	unsigned int flags;
-	unsigned int borrow;
-	unsigned int carry;
 	int i;
 
-	flags = inb(base_offset + 1);
-	borrow = flags & QUAD8_FLAG_BT;
-	carry = !!(flags & QUAD8_FLAG_CT);
-
-	/* Borrow XOR Carry effectively doubles count range */
-	*val = (unsigned long)(borrow ^ carry) << 24;
+	*val = 0;
 
 	mutex_lock(&priv->lock);
 
@@ -1198,8 +1178,8 @@
 
 	mutex_unlock(&priv->lock);
 
-	/* By default 0x1FFFFFF (25 bits unsigned) is maximum count */
-	return sprintf(buf, "33554431\n");
+	/* By default 0xFFFFFF (24 bits unsigned) is maximum count */
+	return sprintf(buf, "16777215\n");
 }
 
 static ssize_t quad8_count_ceiling_write(struct counter_device *counter,
diff --git a/kernel/drivers/counter/stm32-lptimer-cnt.c b/kernel/drivers/counter/stm32-lptimer-cnt.c
index 9374396..b084e97 100644
--- a/kernel/drivers/counter/stm32-lptimer-cnt.c
+++ b/kernel/drivers/counter/stm32-lptimer-cnt.c
@@ -69,7 +69,7 @@
 
 	/* 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;
diff --git a/kernel/drivers/cpufreq/amd_freq_sensitivity.c b/kernel/drivers/cpufreq/amd_freq_sensitivity.c
index d0b10ba..1517711 100644
--- a/kernel/drivers/cpufreq/amd_freq_sensitivity.c
+++ b/kernel/drivers/cpufreq/amd_freq_sensitivity.c
@@ -124,6 +124,8 @@
 	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))
diff --git a/kernel/drivers/cpufreq/armada-37xx-cpufreq.c b/kernel/drivers/cpufreq/armada-37xx-cpufreq.c
index 2de7fd1..f0be8a4 100644
--- a/kernel/drivers/cpufreq/armada-37xx-cpufreq.c
+++ b/kernel/drivers/cpufreq/armada-37xx-cpufreq.c
@@ -443,7 +443,7 @@
 		return -ENODEV;
 	}
 
-	clk = clk_get(cpu_dev, 0);
+	clk = clk_get(cpu_dev, NULL);
 	if (IS_ERR(clk)) {
 		dev_err(cpu_dev, "Cannot get clock for CPU0\n");
 		return PTR_ERR(clk);
diff --git a/kernel/drivers/cpufreq/brcmstb-avs-cpufreq.c b/kernel/drivers/cpufreq/brcmstb-avs-cpufreq.c
index 4153150..f644c5e 100644
--- a/kernel/drivers/cpufreq/brcmstb-avs-cpufreq.c
+++ b/kernel/drivers/cpufreq/brcmstb-avs-cpufreq.c
@@ -434,7 +434,11 @@
 	if (ret)
 		return ERR_PTR(ret);
 
-	table = devm_kcalloc(dev, AVS_PSTATE_MAX + 1, sizeof(*table),
+	/*
+	 * We allocate space for the 5 different P-STATES AVS,
+	 * plus extra space for a terminating element.
+	 */
+	table = devm_kcalloc(dev, AVS_PSTATE_MAX + 1 + 1, sizeof(*table),
 			     GFP_KERNEL);
 	if (!table)
 		return ERR_PTR(-ENOMEM);
diff --git a/kernel/drivers/cpufreq/cpufreq-dt-platdev.c b/kernel/drivers/cpufreq/cpufreq-dt-platdev.c
index 75a2460..cb158c0 100644
--- a/kernel/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/kernel/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -115,6 +115,7 @@
 	{ .compatible = "nvidia,tegra30", },
 	{ .compatible = "nvidia,tegra124", },
 	{ .compatible = "nvidia,tegra210", },
+	{ .compatible = "nvidia,tegra234", },
 
 	{ .compatible = "qcom,apq8096", },
 	{ .compatible = "qcom,msm8996", },
diff --git a/kernel/drivers/cpufreq/cpufreq.c b/kernel/drivers/cpufreq/cpufreq.c
index b8c241b..ab223ef 100644
--- a/kernel/drivers/cpufreq/cpufreq.c
+++ b/kernel/drivers/cpufreq/cpufreq.c
@@ -454,8 +454,10 @@
 			    policy->cur,
 			    policy->cpuinfo.max_freq);
 
+	spin_lock(&policy->transition_lock);
 	policy->transition_ongoing = false;
 	policy->transition_task = NULL;
+	spin_unlock(&policy->transition_lock);
 
 	wake_up(&policy->transition_wait);
 }
@@ -1226,6 +1228,7 @@
 	if (!zalloc_cpumask_var(&policy->real_cpus, GFP_KERNEL))
 		goto err_free_rcpumask;
 
+	init_completion(&policy->kobj_unregister);
 	ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
 				   cpufreq_global_kobject, "policy%u", cpu);
 	if (ret) {
@@ -1264,7 +1267,6 @@
 	init_rwsem(&policy->rwsem);
 	spin_lock_init(&policy->transition_lock);
 	init_waitqueue_head(&policy->transition_wait);
-	init_completion(&policy->kobj_unregister);
 	INIT_WORK(&policy->update, handle_update);
 
 	policy->cpu = cpu;
diff --git a/kernel/drivers/cpufreq/intel_pstate.c b/kernel/drivers/cpufreq/intel_pstate.c
index 1686705..4359ed1 100644
--- a/kernel/drivers/cpufreq/intel_pstate.c
+++ b/kernel/drivers/cpufreq/intel_pstate.c
@@ -443,20 +443,6 @@
 			 (u32) cpu->acpi_perf_data.states[i].control);
 	}
 
-	/*
-	 * The _PSS table doesn't contain whole turbo frequency range.
-	 * This just contains +1 MHZ above the max non turbo frequency,
-	 * with control value corresponding to max turbo ratio. But
-	 * when cpufreq set policy is called, it will call with this
-	 * max frequency, which will cause a reduced performance as
-	 * this driver uses real max turbo frequency as the max
-	 * frequency. So correct this frequency in _PSS table to
-	 * correct max turbo frequency based on the turbo state.
-	 * Also need to convert to MHz as _PSS freq is in MHz.
-	 */
-	if (!global.turbo_disabled)
-		cpu->acpi_perf_data.states[0].core_frequency =
-					policy->cpuinfo.max_freq / 1000;
 	cpu->valid_pss_table = true;
 	pr_debug("_PPC limits will be enforced\n");
 
@@ -777,6 +763,8 @@
 			err = cpufreq_start_governor(policy);
 			if (!ret)
 				ret = err;
+		} else {
+			ret = 0;
 		}
 	}
 
diff --git a/kernel/drivers/cpufreq/powernow-k8.c b/kernel/drivers/cpufreq/powernow-k8.c
index b9ccb6a..22d4c63 100644
--- a/kernel/drivers/cpufreq/powernow-k8.c
+++ b/kernel/drivers/cpufreq/powernow-k8.c
@@ -1101,7 +1101,8 @@
 
 	kfree(data->powernow_table);
 	kfree(data);
-	for_each_cpu(cpu, pol->cpus)
+	/* pol->cpus will be empty here, use related_cpus instead. */
+	for_each_cpu(cpu, pol->related_cpus)
 		per_cpu(powernow_data, cpu) = NULL;
 
 	return 0;
diff --git a/kernel/drivers/cpufreq/qcom-cpufreq-hw.c b/kernel/drivers/cpufreq/qcom-cpufreq-hw.c
index 6de0755..a988099 100644
--- a/kernel/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/kernel/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -158,6 +158,7 @@
 		}
 	} 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;
diff --git a/kernel/drivers/cpufreq/rockchip-cpufreq.c b/kernel/drivers/cpufreq/rockchip-cpufreq.c
index 804fcfd..27c6d92 100644
--- a/kernel/drivers/cpufreq/rockchip-cpufreq.c
+++ b/kernel/drivers/cpufreq/rockchip-cpufreq.c
@@ -606,6 +606,7 @@
 	if (opp_info->data && opp_info->data->get_soc_info)
 		opp_info->data->get_soc_info(dev, np, &bin, &process);
 	rockchip_get_soc_info(dev, np, &bin, &process);
+	rockchip_init_pvtpll_table(&cluster->opp_info, bin);
 	rockchip_get_scale_volt_sel(dev, "cpu_leakage", reg_name, bin, process,
 				    &cluster->scale, &volt_sel);
 	if (opp_info->data && opp_info->data->set_soc_info)
diff --git a/kernel/drivers/cpuidle/cpuidle-psci-domain.c b/kernel/drivers/cpuidle/cpuidle-psci-domain.c
index ff2c3f8..ce5c415 100644
--- a/kernel/drivers/cpuidle/cpuidle-psci-domain.c
+++ b/kernel/drivers/cpuidle/cpuidle-psci-domain.c
@@ -182,7 +182,8 @@
 	struct psci_pd_provider *pd_provider, *it;
 	struct generic_pm_domain *genpd;
 
-	list_for_each_entry_safe(pd_provider, it, &psci_pd_providers, link) {
+	list_for_each_entry_safe_reverse(pd_provider, it,
+					 &psci_pd_providers, link) {
 		of_genpd_del_provider(pd_provider->node);
 
 		genpd = of_genpd_remove_last(pd_provider->node);
diff --git a/kernel/drivers/cpuidle/cpuidle-pseries.c b/kernel/drivers/cpuidle/cpuidle-pseries.c
index ff164de..f4cf3ad 100644
--- a/kernel/drivers/cpuidle/cpuidle-pseries.c
+++ b/kernel/drivers/cpuidle/cpuidle-pseries.c
@@ -409,13 +409,7 @@
 		return -ENODEV;
 
 	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
-		/*
-		 * Use local_paca instead of get_lppaca() since
-		 * preemption is not disabled, and it is not required in
-		 * fact, since lppaca_ptr does not need to be the value
-		 * associated to the current CPU, it can be from any CPU.
-		 */
-		if (lppaca_shared_proc(local_paca->lppaca_ptr)) {
+		if (lppaca_shared_proc()) {
 			cpuidle_state_table = shared_states;
 			max_idle_state = ARRAY_SIZE(shared_states);
 		} else {
diff --git a/kernel/drivers/cpuidle/dt_idle_states.c b/kernel/drivers/cpuidle/dt_idle_states.c
index 252f2a9..448bc79 100644
--- a/kernel/drivers/cpuidle/dt_idle_states.c
+++ b/kernel/drivers/cpuidle/dt_idle_states.c
@@ -223,6 +223,6 @@
 	 * 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);
diff --git a/kernel/drivers/crypto/Kconfig b/kernel/drivers/crypto/Kconfig
index 4aed2f4..e882be4 100644
--- a/kernel/drivers/crypto/Kconfig
+++ b/kernel/drivers/crypto/Kconfig
@@ -906,6 +906,7 @@
 	select CRYPTO_AES_ARM64
 	select CRYPTO_ALGAPI
 	select CRYPTO_AUTHENC
+	select CRYPTO_DES
 	select CRYPTO_SHA1
 	select CRYPTO_SHA256
 	select CRYPTO_SHA512
diff --git a/kernel/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/kernel/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
index d095499..8a94f81 100644
--- a/kernel/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+++ b/kernel/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
@@ -105,7 +105,7 @@
 	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;
@@ -132,7 +132,7 @@
 		}
 		rctx->p_iv[i] = a;
 		/* we need to setup all others IVs only in the decrypt way */
-		if (rctx->op_dir & SS_ENCRYPTION)
+		if (rctx->op_dir == SS_ENCRYPTION)
 			return 0;
 		todo = min(len, sg_dma_len(sg));
 		len -= todo;
diff --git a/kernel/drivers/crypto/amcc/crypto4xx_core.c b/kernel/drivers/crypto/amcc/crypto4xx_core.c
index 2e3690f..6d05ac0 100644
--- a/kernel/drivers/crypto/amcc/crypto4xx_core.c
+++ b/kernel/drivers/crypto/amcc/crypto4xx_core.c
@@ -522,7 +522,6 @@
 {
 	struct skcipher_request *req;
 	struct scatterlist *dst;
-	dma_addr_t addr;
 
 	req = skcipher_request_cast(pd_uinfo->async_req);
 
@@ -531,8 +530,8 @@
 					  req->cryptlen, req->dst);
 	} else {
 		dst = pd_uinfo->dest_va;
-		addr = dma_map_page(dev->core_dev->device, sg_page(dst),
-				    dst->offset, dst->length, DMA_FROM_DEVICE);
+		dma_unmap_page(dev->core_dev->device, pd->dest, dst->length,
+			       DMA_FROM_DEVICE);
 	}
 
 	if (pd_uinfo->sa_va->sa_command_0.bf.save_iv == SA_SAVE_IV) {
@@ -557,10 +556,9 @@
 	struct ahash_request *ahash_req;
 
 	ahash_req = ahash_request_cast(pd_uinfo->async_req);
-	ctx  = crypto_tfm_ctx(ahash_req->base.tfm);
+	ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(ahash_req));
 
-	crypto4xx_copy_digest_to_dst(ahash_req->result, pd_uinfo,
-				     crypto_tfm_ctx(ahash_req->base.tfm));
+	crypto4xx_copy_digest_to_dst(ahash_req->result, pd_uinfo, ctx);
 	crypto4xx_ret_sg_desc(dev, pd_uinfo);
 
 	if (pd_uinfo->state & PD_ENTRY_BUSY)
diff --git a/kernel/drivers/crypto/amlogic/amlogic-gxl-core.c b/kernel/drivers/crypto/amlogic/amlogic-gxl-core.c
index 5bbeff4..7a5cf11 100644
--- a/kernel/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/kernel/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -240,7 +240,6 @@
 		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/kernel/drivers/crypto/amlogic/amlogic-gxl.h b/kernel/drivers/crypto/amlogic/amlogic-gxl.h
index dc0f142..8c0746a 100644
--- a/kernel/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/kernel/drivers/crypto/amlogic/amlogic-gxl.h
@@ -95,7 +95,7 @@
 	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
diff --git a/kernel/drivers/crypto/caam/caampkc.c b/kernel/drivers/crypto/caam/caampkc.c
index 3acc825..5bd70a5 100644
--- a/kernel/drivers/crypto/caam/caampkc.c
+++ b/kernel/drivers/crypto/caam/caampkc.c
@@ -222,7 +222,9 @@
 		if (len && *buff)
 			break;
 
-		sg_miter_next(&miter);
+		if (!sg_miter_next(&miter))
+			break;
+
 		buff = miter.addr;
 		len = miter.length;
 
diff --git a/kernel/drivers/crypto/caam/ctrl.c b/kernel/drivers/crypto/caam/ctrl.c
index f87aa21..f9a1ec3 100644
--- a/kernel/drivers/crypto/caam/ctrl.c
+++ b/kernel/drivers/crypto/caam/ctrl.c
@@ -284,6 +284,10 @@
 		const u32 rdsta_if = RDSTA_IF0 << sh_idx;
 		const u32 rdsta_pr = RDSTA_PR0 << sh_idx;
 		const u32 rdsta_mask = rdsta_if | rdsta_pr;
+
+		/* Clear the contents before using the descriptor */
+		memset(desc, 0x00, CAAM_CMD_SZ * 7);
+
 		/*
 		 * If the corresponding bit is set, this state handle
 		 * was initialized by somebody else, so it's left alone.
@@ -327,8 +331,6 @@
 		}
 
 		dev_info(ctrldev, "Instantiated RNG4 SH%d\n", sh_idx);
-		/* Clear the contents before recreating the descriptor */
-		memset(desc, 0x00, CAAM_CMD_SZ * 7);
 	}
 
 	kfree(desc);
diff --git a/kernel/drivers/crypto/cavium/nitrox/nitrox_mbx.c b/kernel/drivers/crypto/cavium/nitrox/nitrox_mbx.c
index b51b044..a131dbb 100644
--- a/kernel/drivers/crypto/cavium/nitrox/nitrox_mbx.c
+++ b/kernel/drivers/crypto/cavium/nitrox/nitrox_mbx.c
@@ -190,6 +190,7 @@
 	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 */
diff --git a/kernel/drivers/crypto/ccp/ccp-dmaengine.c b/kernel/drivers/crypto/ccp/ccp-dmaengine.c
index b9299de..e416456 100644
--- a/kernel/drivers/crypto/ccp/ccp-dmaengine.c
+++ b/kernel/drivers/crypto/ccp/ccp-dmaengine.c
@@ -643,11 +643,23 @@
 		chan = ccp->ccp_dma_chan + i;
 		dma_chan = &chan->dma_chan;
 
-		if (dma_chan->client_count)
-			dma_release_channel(dma_chan);
-
 		tasklet_kill(&chan->cleanup_tasklet);
 		list_del_rcu(&dma_chan->device_node);
+	}
+}
+
+static void ccp_dma_release_channels(struct ccp_device *ccp)
+{
+	struct ccp_dma_chan *chan;
+	struct dma_chan *dma_chan;
+	unsigned int i;
+
+	for (i = 0; i < ccp->cmd_q_count; i++) {
+		chan = ccp->ccp_dma_chan + i;
+		dma_chan = &chan->dma_chan;
+
+		if (dma_chan->client_count)
+			dma_release_channel(dma_chan);
 	}
 }
 
@@ -771,8 +783,9 @@
 	if (!dmaengine)
 		return;
 
-	ccp_dma_release(ccp);
+	ccp_dma_release_channels(ccp);
 	dma_async_device_unregister(dma_dev);
+	ccp_dma_release(ccp);
 
 	kmem_cache_destroy(ccp->dma_desc_cache);
 	kmem_cache_destroy(ccp->dma_cmd_cache);
diff --git a/kernel/drivers/crypto/ccp/psp-dev.c b/kernel/drivers/crypto/ccp/psp-dev.c
index ae7b445..4bf9eaa 100644
--- a/kernel/drivers/crypto/ccp/psp-dev.c
+++ b/kernel/drivers/crypto/ccp/psp-dev.c
@@ -42,6 +42,9 @@
 	/* Read the interrupt status: */
 	status = ioread32(psp->io_regs + psp->vdata->intsts_reg);
 
+	/* Clear the interrupt status by writing the same value we read. */
+	iowrite32(status, psp->io_regs + psp->vdata->intsts_reg);
+
 	/* invoke subdevice interrupt handlers */
 	if (status) {
 		if (psp->sev_irq_handler)
@@ -50,9 +53,6 @@
 		if (psp->tee_irq_handler)
 			psp->tee_irq_handler(irq, psp->tee_irq_data, status);
 	}
-
-	/* Clear the interrupt status by writing the same value we read. */
-	iowrite32(status, psp->io_regs + psp->vdata->intsts_reg);
 
 	return IRQ_HANDLED;
 }
diff --git a/kernel/drivers/crypto/ccp/sev-dev.c b/kernel/drivers/crypto/ccp/sev-dev.c
index ed39a22..8e2672e 100644
--- a/kernel/drivers/crypto/ccp/sev-dev.c
+++ b/kernel/drivers/crypto/ccp/sev-dev.c
@@ -23,6 +23,7 @@
 #include <linux/gfp.h>
 
 #include <asm/smp.h>
+#include <asm/cacheflush.h>
 
 #include "psp-dev.h"
 #include "sev-dev.h"
@@ -138,12 +139,24 @@
 	return 0;
 }
 
+static void *sev_fw_alloc(unsigned long len)
+{
+	struct page *page;
+
+	page = alloc_pages(GFP_KERNEL, get_order(len));
+	if (!page)
+		return NULL;
+
+	return page_address(page);
+}
+
 static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
 {
 	struct psp_device *psp = psp_master;
 	struct sev_device *sev;
 	unsigned int phys_lsb, phys_msb;
 	unsigned int reg, ret = 0;
+	int buf_len;
 
 	if (!psp || !psp->sev_data)
 		return -ENODEV;
@@ -153,18 +166,27 @@
 
 	sev = psp->sev_data;
 
-	if (data && WARN_ON_ONCE(!virt_addr_valid(data)))
+	buf_len = sev_cmd_buffer_len(cmd);
+	if (WARN_ON_ONCE(!data != !buf_len))
 		return -EINVAL;
 
+	/*
+	 * Copy the incoming data to driver's scratch buffer as __pa() will not
+	 * work for some memory, e.g. vmalloc'd addresses, and @data may not be
+	 * physically contiguous.
+	 */
+	if (data)
+		memcpy(sev->cmd_buf, data, buf_len);
+
 	/* Get the physical address of the command buffer */
-	phys_lsb = data ? lower_32_bits(__psp_pa(data)) : 0;
-	phys_msb = data ? upper_32_bits(__psp_pa(data)) : 0;
+	phys_lsb = data ? lower_32_bits(__psp_pa(sev->cmd_buf)) : 0;
+	phys_msb = data ? upper_32_bits(__psp_pa(sev->cmd_buf)) : 0;
 
 	dev_dbg(sev->dev, "sev command id %#x buffer 0x%08x%08x timeout %us\n",
 		cmd, phys_msb, phys_lsb, psp_timeout);
 
 	print_hex_dump_debug("(in):  ", DUMP_PREFIX_OFFSET, 16, 2, data,
-			     sev_cmd_buffer_len(cmd), false);
+			     buf_len, false);
 
 	iowrite32(phys_lsb, sev->io_regs + sev->vdata->cmdbuff_addr_lo_reg);
 	iowrite32(phys_msb, sev->io_regs + sev->vdata->cmdbuff_addr_hi_reg);
@@ -200,7 +222,14 @@
 	}
 
 	print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data,
-			     sev_cmd_buffer_len(cmd), false);
+			     buf_len, false);
+
+	/*
+	 * Copy potential output from the PSP back to data.  Do this even on
+	 * failure in case the caller wants to glean something from the error.
+	 */
+	if (data)
+		memcpy(data, sev->cmd_buf, buf_len);
 
 	return ret;
 }
@@ -304,15 +333,14 @@
 
 static int sev_get_platform_state(int *state, int *error)
 {
-	struct sev_device *sev = psp_master->sev_data;
+	struct sev_user_data_status data;
 	int rc;
 
-	rc = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS,
-				 &sev->status_cmd_buf, error);
+	rc = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, &data, error);
 	if (rc)
 		return rc;
 
-	*state = sev->status_cmd_buf.state;
+	*state = data.state;
 	return rc;
 }
 
@@ -350,15 +378,16 @@
 
 static int sev_ioctl_do_platform_status(struct sev_issue_cmd *argp)
 {
-	struct sev_device *sev = psp_master->sev_data;
-	struct sev_user_data_status *data = &sev->status_cmd_buf;
+	struct sev_user_data_status data;
 	int ret;
 
-	ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, data, &argp->error);
+	memset(&data, 0, sizeof(data));
+
+	ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, &data, &argp->error);
 	if (ret)
 		return ret;
 
-	if (copy_to_user((void __user *)argp->data, data, sizeof(*data)))
+	if (copy_to_user((void __user *)argp->data, &data, sizeof(data)))
 		ret = -EFAULT;
 
 	return ret;
@@ -385,7 +414,7 @@
 {
 	struct sev_device *sev = psp_master->sev_data;
 	struct sev_user_data_pek_csr input;
-	struct sev_data_pek_csr *data;
+	struct sev_data_pek_csr data;
 	void __user *input_address;
 	void *blob = NULL;
 	int ret;
@@ -396,9 +425,7 @@
 	if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
 		return -EFAULT;
 
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
+	memset(&data, 0, sizeof(data));
 
 	/* userspace wants to query CSR length */
 	if (!input.address || !input.length)
@@ -406,19 +433,15 @@
 
 	/* allocate a physically contiguous buffer to store the CSR blob */
 	input_address = (void __user *)input.address;
-	if (input.length > SEV_FW_BLOB_MAX_SIZE) {
-		ret = -EFAULT;
-		goto e_free;
-	}
+	if (input.length > SEV_FW_BLOB_MAX_SIZE)
+		return -EFAULT;
 
-	blob = kmalloc(input.length, GFP_KERNEL);
-	if (!blob) {
-		ret = -ENOMEM;
-		goto e_free;
-	}
+	blob = kzalloc(input.length, GFP_KERNEL);
+	if (!blob)
+		return -ENOMEM;
 
-	data->address = __psp_pa(blob);
-	data->len = input.length;
+	data.address = __psp_pa(blob);
+	data.len = input.length;
 
 cmd:
 	if (sev->state == SEV_STATE_UNINIT) {
@@ -427,10 +450,10 @@
 			goto e_free_blob;
 	}
 
-	ret = __sev_do_cmd_locked(SEV_CMD_PEK_CSR, data, &argp->error);
+	ret = __sev_do_cmd_locked(SEV_CMD_PEK_CSR, &data, &argp->error);
 
 	 /* If we query the CSR length, FW responded with expected data. */
-	input.length = data->len;
+	input.length = data.len;
 
 	if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) {
 		ret = -EFAULT;
@@ -444,8 +467,6 @@
 
 e_free_blob:
 	kfree(blob);
-e_free:
-	kfree(data);
 	return ret;
 }
 
@@ -465,21 +486,20 @@
 static int sev_get_api_version(void)
 {
 	struct sev_device *sev = psp_master->sev_data;
-	struct sev_user_data_status *status;
+	struct sev_user_data_status status;
 	int error = 0, ret;
 
-	status = &sev->status_cmd_buf;
-	ret = sev_platform_status(status, &error);
+	ret = sev_platform_status(&status, &error);
 	if (ret) {
 		dev_err(sev->dev,
 			"SEV: failed to get status. Error: %#x\n", error);
 		return 1;
 	}
 
-	sev->api_major = status->api_major;
-	sev->api_minor = status->api_minor;
-	sev->build = status->build;
-	sev->state = status->state;
+	sev->api_major = status.api_major;
+	sev->api_minor = status.api_minor;
+	sev->build = status.build;
+	sev->state = status.state;
 
 	return 0;
 }
@@ -577,7 +597,7 @@
 {
 	struct sev_device *sev = psp_master->sev_data;
 	struct sev_user_data_pek_cert_import input;
-	struct sev_data_pek_cert_import *data;
+	struct sev_data_pek_cert_import data;
 	void *pek_blob, *oca_blob;
 	int ret;
 
@@ -587,19 +607,14 @@
 	if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
 		return -EFAULT;
 
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
 	/* copy PEK certificate blobs from userspace */
 	pek_blob = psp_copy_user_blob(input.pek_cert_address, input.pek_cert_len);
-	if (IS_ERR(pek_blob)) {
-		ret = PTR_ERR(pek_blob);
-		goto e_free;
-	}
+	if (IS_ERR(pek_blob))
+		return PTR_ERR(pek_blob);
 
-	data->pek_cert_address = __psp_pa(pek_blob);
-	data->pek_cert_len = input.pek_cert_len;
+	data.reserved = 0;
+	data.pek_cert_address = __psp_pa(pek_blob);
+	data.pek_cert_len = input.pek_cert_len;
 
 	/* copy PEK certificate blobs from userspace */
 	oca_blob = psp_copy_user_blob(input.oca_cert_address, input.oca_cert_len);
@@ -608,8 +623,8 @@
 		goto e_free_pek;
 	}
 
-	data->oca_cert_address = __psp_pa(oca_blob);
-	data->oca_cert_len = input.oca_cert_len;
+	data.oca_cert_address = __psp_pa(oca_blob);
+	data.oca_cert_len = input.oca_cert_len;
 
 	/* If platform is not in INIT state then transition it to INIT */
 	if (sev->state != SEV_STATE_INIT) {
@@ -618,21 +633,19 @@
 			goto e_free_oca;
 	}
 
-	ret = __sev_do_cmd_locked(SEV_CMD_PEK_CERT_IMPORT, data, &argp->error);
+	ret = __sev_do_cmd_locked(SEV_CMD_PEK_CERT_IMPORT, &data, &argp->error);
 
 e_free_oca:
 	kfree(oca_blob);
 e_free_pek:
 	kfree(pek_blob);
-e_free:
-	kfree(data);
 	return ret;
 }
 
 static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp)
 {
 	struct sev_user_data_get_id2 input;
-	struct sev_data_get_id *data;
+	struct sev_data_get_id data;
 	void __user *input_address;
 	void *id_blob = NULL;
 	int ret;
@@ -646,28 +659,32 @@
 
 	input_address = (void __user *)input.address;
 
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
 	if (input.address && input.length) {
-		id_blob = kmalloc(input.length, GFP_KERNEL);
-		if (!id_blob) {
-			kfree(data);
+		/*
+		 * The length of the ID shouldn't be assumed by software since
+		 * it may change in the future.  The allocation size is limited
+		 * to 1 << (PAGE_SHIFT + MAX_ORDER - 1) by the page allocator.
+		 * If the allocation fails, simply return ENOMEM rather than
+		 * warning in the kernel log.
+		 */
+		id_blob = kzalloc(input.length, GFP_KERNEL | __GFP_NOWARN);
+		if (!id_blob)
 			return -ENOMEM;
-		}
 
-		data->address = __psp_pa(id_blob);
-		data->len = input.length;
+		data.address = __psp_pa(id_blob);
+		data.len = input.length;
+	} else {
+		data.address = 0;
+		data.len = 0;
 	}
 
-	ret = __sev_do_cmd_locked(SEV_CMD_GET_ID, data, &argp->error);
+	ret = __sev_do_cmd_locked(SEV_CMD_GET_ID, &data, &argp->error);
 
 	/*
 	 * Firmware will return the length of the ID value (either the minimum
 	 * required length or the actual length written), return it to the user.
 	 */
-	input.length = data->len;
+	input.length = data.len;
 
 	if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) {
 		ret = -EFAULT;
@@ -675,7 +692,7 @@
 	}
 
 	if (id_blob) {
-		if (copy_to_user(input_address, id_blob, data->len)) {
+		if (copy_to_user(input_address, id_blob, data.len)) {
 			ret = -EFAULT;
 			goto e_free;
 		}
@@ -683,7 +700,6 @@
 
 e_free:
 	kfree(id_blob);
-	kfree(data);
 
 	return ret;
 }
@@ -733,7 +749,7 @@
 	struct sev_device *sev = psp_master->sev_data;
 	struct sev_user_data_pdh_cert_export input;
 	void *pdh_blob = NULL, *cert_blob = NULL;
-	struct sev_data_pdh_cert_export *data;
+	struct sev_data_pdh_cert_export data;
 	void __user *input_cert_chain_address;
 	void __user *input_pdh_cert_address;
 	int ret;
@@ -751,9 +767,7 @@
 	if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
 		return -EFAULT;
 
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
+	memset(&data, 0, sizeof(data));
 
 	/* Userspace wants to query the certificate length. */
 	if (!input.pdh_cert_address ||
@@ -765,41 +779,35 @@
 	input_cert_chain_address = (void __user *)input.cert_chain_address;
 
 	/* Allocate a physically contiguous buffer to store the PDH blob. */
-	if (input.pdh_cert_len > SEV_FW_BLOB_MAX_SIZE) {
-		ret = -EFAULT;
-		goto e_free;
-	}
+	if (input.pdh_cert_len > SEV_FW_BLOB_MAX_SIZE)
+		return -EFAULT;
 
 	/* Allocate a physically contiguous buffer to store the cert chain blob. */
-	if (input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE) {
-		ret = -EFAULT;
-		goto e_free;
-	}
+	if (input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE)
+		return -EFAULT;
 
-	pdh_blob = kmalloc(input.pdh_cert_len, GFP_KERNEL);
-	if (!pdh_blob) {
-		ret = -ENOMEM;
-		goto e_free;
-	}
+	pdh_blob = kzalloc(input.pdh_cert_len, GFP_KERNEL);
+	if (!pdh_blob)
+		return -ENOMEM;
 
-	data->pdh_cert_address = __psp_pa(pdh_blob);
-	data->pdh_cert_len = input.pdh_cert_len;
+	data.pdh_cert_address = __psp_pa(pdh_blob);
+	data.pdh_cert_len = input.pdh_cert_len;
 
-	cert_blob = kmalloc(input.cert_chain_len, GFP_KERNEL);
+	cert_blob = kzalloc(input.cert_chain_len, GFP_KERNEL);
 	if (!cert_blob) {
 		ret = -ENOMEM;
 		goto e_free_pdh;
 	}
 
-	data->cert_chain_address = __psp_pa(cert_blob);
-	data->cert_chain_len = input.cert_chain_len;
+	data.cert_chain_address = __psp_pa(cert_blob);
+	data.cert_chain_len = input.cert_chain_len;
 
 cmd:
-	ret = __sev_do_cmd_locked(SEV_CMD_PDH_CERT_EXPORT, data, &argp->error);
+	ret = __sev_do_cmd_locked(SEV_CMD_PDH_CERT_EXPORT, &data, &argp->error);
 
 	/* If we query the length, FW responded with expected data. */
-	input.cert_chain_len = data->cert_chain_len;
-	input.pdh_cert_len = data->pdh_cert_len;
+	input.cert_chain_len = data.cert_chain_len;
+	input.pdh_cert_len = data.pdh_cert_len;
 
 	if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) {
 		ret = -EFAULT;
@@ -824,8 +832,6 @@
 	kfree(cert_blob);
 e_free_pdh:
 	kfree(pdh_blob);
-e_free:
-	kfree(data);
 	return ret;
 }
 
@@ -985,6 +991,10 @@
 	if (!sev)
 		goto e_err;
 
+	sev->cmd_buf = (void *)devm_get_free_pages(dev, GFP_KERNEL, 0);
+	if (!sev->cmd_buf)
+		goto e_sev;
+
 	psp->sev_data = sev;
 
 	sev->dev = dev;
@@ -996,7 +1006,7 @@
 	if (!sev->vdata) {
 		ret = -ENODEV;
 		dev_err(dev, "sev: missing driver data\n");
-		goto e_sev;
+		goto e_buf;
 	}
 
 	psp_set_sev_irq_handler(psp, sev_irq_handler, sev);
@@ -1011,6 +1021,8 @@
 
 e_irq:
 	psp_clear_sev_irq_handler(psp);
+e_buf:
+	devm_free_pages(dev, (unsigned long)sev->cmd_buf);
 e_sev:
 	devm_kfree(dev, sev);
 e_err:
@@ -1063,7 +1075,6 @@
 void sev_pci_init(void)
 {
 	struct sev_device *sev = psp_master->sev_data;
-	struct page *tmr_page;
 	int error, rc;
 
 	if (!sev)
@@ -1079,14 +1090,13 @@
 		sev_get_api_version();
 
 	/* Obtain the TMR memory area for SEV-ES use */
-	tmr_page = alloc_pages(GFP_KERNEL, get_order(SEV_ES_TMR_SIZE));
-	if (tmr_page) {
-		sev_es_tmr = page_address(tmr_page);
-	} else {
-		sev_es_tmr = NULL;
+	sev_es_tmr = sev_fw_alloc(SEV_ES_TMR_SIZE);
+	if (sev_es_tmr)
+		/* Must flush the cache before giving it to the firmware */
+		clflush_cache_range(sev_es_tmr, SEV_ES_TMR_SIZE);
+	else
 		dev_warn(sev->dev,
 			 "SEV: TMR allocation failed, SEV-ES support unavailable\n");
-	}
 
 	/* Initialize the platform */
 	rc = sev_platform_init(&error);
diff --git a/kernel/drivers/crypto/ccp/sev-dev.h b/kernel/drivers/crypto/ccp/sev-dev.h
index dd5c4fe..0fd2143 100644
--- a/kernel/drivers/crypto/ccp/sev-dev.h
+++ b/kernel/drivers/crypto/ccp/sev-dev.h
@@ -46,12 +46,13 @@
 	unsigned int int_rcvd;
 	wait_queue_head_t int_queue;
 	struct sev_misc_dev *misc;
-	struct sev_user_data_status status_cmd_buf;
 	struct sev_data_init init_cmd_buf;
 
 	u8 api_major;
 	u8 api_minor;
 	u8 build;
+
+	void *cmd_buf;
 };
 
 int sev_dev_init(struct psp_device *psp);
diff --git a/kernel/drivers/crypto/ccree/cc_debugfs.c b/kernel/drivers/crypto/ccree/cc_debugfs.c
index 7083767..8f008f0 100644
--- a/kernel/drivers/crypto/ccree/cc_debugfs.c
+++ b/kernel/drivers/crypto/ccree/cc_debugfs.c
@@ -55,7 +55,7 @@
 	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);
 }
diff --git a/kernel/drivers/crypto/ccree/cc_driver.c b/kernel/drivers/crypto/ccree/cc_driver.c
index 6f519d3..7924693 100644
--- a/kernel/drivers/crypto/ccree/cc_driver.c
+++ b/kernel/drivers/crypto/ccree/cc_driver.c
@@ -614,9 +614,17 @@
 
 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);
 
diff --git a/kernel/drivers/crypto/hisilicon/qm.h b/kernel/drivers/crypto/hisilicon/qm.h
index 0420f4c..aaad3d7 100644
--- a/kernel/drivers/crypto/hisilicon/qm.h
+++ b/kernel/drivers/crypto/hisilicon/qm.h
@@ -289,14 +289,14 @@
 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 @@
 			q_num = QM_QNUM_V1;
 		else
 			q_num = QM_QNUM_V2;
+
+		pci_dev_put(pdev);
 	}
 
 	ret = kstrtou32(val, 10, &n);
diff --git a/kernel/drivers/crypto/hisilicon/sgl.c b/kernel/drivers/crypto/hisilicon/sgl.c
index 725a739..ce77826 100644
--- a/kernel/drivers/crypto/hisilicon/sgl.c
+++ b/kernel/drivers/crypto/hisilicon/sgl.c
@@ -113,9 +113,8 @@
 	for (j = 0; j < i; j++) {
 		dma_free_coherent(dev, block_size, block[j].sgl,
 				  block[j].sgl_dma);
-		memset(block + j, 0, sizeof(*block));
 	}
-	kfree(pool);
+	kfree_sensitive(pool);
 	return ERR_PTR(-ENOMEM);
 }
 EXPORT_SYMBOL_GPL(hisi_acc_create_sgl_pool);
diff --git a/kernel/drivers/crypto/img-hash.c b/kernel/drivers/crypto/img-hash.c
index 91f555c..cecae50 100644
--- a/kernel/drivers/crypto/img-hash.c
+++ b/kernel/drivers/crypto/img-hash.c
@@ -357,12 +357,16 @@
 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);
diff --git a/kernel/drivers/crypto/inside-secure/safexcel.c b/kernel/drivers/crypto/inside-secure/safexcel.c
index bcfb3af..7795eed 100644
--- a/kernel/drivers/crypto/inside-secure/safexcel.c
+++ b/kernel/drivers/crypto/inside-secure/safexcel.c
@@ -1634,19 +1634,23 @@
 						     &priv->ring[i].rdr);
 		if (ret) {
 			dev_err(dev, "Failed to initialize rings\n");
-			return ret;
+			goto err_cleanup_rings;
 		}
 
 		priv->ring[i].rdr_req = devm_kcalloc(dev,
 			EIP197_DEFAULT_RING_SIZE,
 			sizeof(*priv->ring[i].rdr_req),
 			GFP_KERNEL);
-		if (!priv->ring[i].rdr_req)
-			return -ENOMEM;
+		if (!priv->ring[i].rdr_req) {
+			ret = -ENOMEM;
+			goto err_cleanup_rings;
+		}
 
 		ring_irq = devm_kzalloc(dev, sizeof(*ring_irq), GFP_KERNEL);
-		if (!ring_irq)
-			return -ENOMEM;
+		if (!ring_irq) {
+			ret = -ENOMEM;
+			goto err_cleanup_rings;
+		}
 
 		ring_irq->priv = priv;
 		ring_irq->ring = i;
@@ -1660,7 +1664,8 @@
 						ring_irq);
 		if (irq < 0) {
 			dev_err(dev, "Failed to get IRQ ID for ring %d\n", i);
-			return irq;
+			ret = irq;
+			goto err_cleanup_rings;
 		}
 
 		priv->ring[i].irq = irq;
@@ -1672,8 +1677,10 @@
 		snprintf(wq_name, 9, "wq_ring%d", i);
 		priv->ring[i].workqueue =
 			create_singlethread_workqueue(wq_name);
-		if (!priv->ring[i].workqueue)
-			return -ENOMEM;
+		if (!priv->ring[i].workqueue) {
+			ret = -ENOMEM;
+			goto err_cleanup_rings;
+		}
 
 		priv->ring[i].requests = 0;
 		priv->ring[i].busy = false;
@@ -1690,16 +1697,26 @@
 	ret = safexcel_hw_init(priv);
 	if (ret) {
 		dev_err(dev, "HW init failed (%d)\n", ret);
-		return ret;
+		goto err_cleanup_rings;
 	}
 
 	ret = safexcel_register_algorithms(priv);
 	if (ret) {
 		dev_err(dev, "Failed to register algorithms (%d)\n", ret);
-		return ret;
+		goto err_cleanup_rings;
 	}
 
 	return 0;
+
+err_cleanup_rings:
+	for (i = 0; i < priv->config.rings; i++) {
+		if (priv->ring[i].irq)
+			irq_set_affinity_hint(priv->ring[i].irq, NULL);
+		if (priv->ring[i].workqueue)
+			destroy_workqueue(priv->ring[i].workqueue);
+	}
+
+	return ret;
 }
 
 static void safexcel_hw_reset_rings(struct safexcel_crypto_priv *priv)
diff --git a/kernel/drivers/crypto/marvell/cesa/cipher.c b/kernel/drivers/crypto/marvell/cesa/cipher.c
index 596a8c7..8dc10f9 100644
--- a/kernel/drivers/crypto/marvell/cesa/cipher.c
+++ b/kernel/drivers/crypto/marvell/cesa/cipher.c
@@ -287,7 +287,7 @@
 static int mv_cesa_des3_ede_setkey(struct crypto_skcipher *cipher,
 				   const u8 *key, unsigned int len)
 {
-	struct mv_cesa_des_ctx *ctx = crypto_skcipher_ctx(cipher);
+	struct mv_cesa_des3_ctx *ctx = crypto_skcipher_ctx(cipher);
 	int err;
 
 	err = verify_skcipher_des3_key(cipher, key);
diff --git a/kernel/drivers/crypto/n2_core.c b/kernel/drivers/crypto/n2_core.c
index 3642bf8..8c4149c 100644
--- a/kernel/drivers/crypto/n2_core.c
+++ b/kernel/drivers/crypto/n2_core.c
@@ -1228,6 +1228,7 @@
 	const u8	*hash_init;
 	u8		hw_op_hashsz;
 	u8		digest_size;
+	u8		statesize;
 	u8		block_size;
 	u8		auth_type;
 	u8		hmac_type;
@@ -1259,6 +1260,7 @@
 	  .hmac_type	= AUTH_TYPE_HMAC_MD5,
 	  .hw_op_hashsz	= MD5_DIGEST_SIZE,
 	  .digest_size	= MD5_DIGEST_SIZE,
+	  .statesize	= sizeof(struct md5_state),
 	  .block_size	= MD5_HMAC_BLOCK_SIZE },
 	{ .name		= "sha1",
 	  .hash_zero	= sha1_zero_message_hash,
@@ -1267,6 +1269,7 @@
 	  .hmac_type	= AUTH_TYPE_HMAC_SHA1,
 	  .hw_op_hashsz	= SHA1_DIGEST_SIZE,
 	  .digest_size	= SHA1_DIGEST_SIZE,
+	  .statesize	= sizeof(struct sha1_state),
 	  .block_size	= SHA1_BLOCK_SIZE },
 	{ .name		= "sha256",
 	  .hash_zero	= sha256_zero_message_hash,
@@ -1275,6 +1278,7 @@
 	  .hmac_type	= AUTH_TYPE_HMAC_SHA256,
 	  .hw_op_hashsz	= SHA256_DIGEST_SIZE,
 	  .digest_size	= SHA256_DIGEST_SIZE,
+	  .statesize	= sizeof(struct sha256_state),
 	  .block_size	= SHA256_BLOCK_SIZE },
 	{ .name		= "sha224",
 	  .hash_zero	= sha224_zero_message_hash,
@@ -1283,6 +1287,7 @@
 	  .hmac_type	= AUTH_TYPE_RESERVED,
 	  .hw_op_hashsz	= SHA256_DIGEST_SIZE,
 	  .digest_size	= SHA224_DIGEST_SIZE,
+	  .statesize	= sizeof(struct sha256_state),
 	  .block_size	= SHA224_BLOCK_SIZE },
 };
 #define NUM_HASH_TMPLS ARRAY_SIZE(hash_tmpls)
@@ -1423,6 +1428,7 @@
 
 	halg = &ahash->halg;
 	halg->digestsize = tmpl->digest_size;
+	halg->statesize = tmpl->statesize;
 
 	base = &halg->base;
 	snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name);
diff --git a/kernel/drivers/crypto/nx/Makefile b/kernel/drivers/crypto/nx/Makefile
index bc89a20..351822a 100644
--- a/kernel/drivers/crypto/nx/Makefile
+++ b/kernel/drivers/crypto/nx/Makefile
@@ -1,7 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_CRYPTO_DEV_NX_ENCRYPT) += nx-crypto.o
 nx-crypto-objs := nx.o \
-		  nx_debugfs.o \
 		  nx-aes-cbc.o \
 		  nx-aes-ecb.o \
 		  nx-aes-gcm.o \
@@ -11,6 +10,7 @@
 		  nx-sha256.o \
 		  nx-sha512.o
 
+nx-crypto-$(CONFIG_DEBUG_FS) += nx_debugfs.o
 obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES) += nx-compress-pseries.o nx-compress.o
 obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV) += nx-compress-powernv.o nx-compress.o
 nx-compress-objs := nx-842.o
diff --git a/kernel/drivers/crypto/nx/nx.h b/kernel/drivers/crypto/nx/nx.h
index c623317..2697bae 100644
--- a/kernel/drivers/crypto/nx/nx.h
+++ b/kernel/drivers/crypto/nx/nx.h
@@ -170,8 +170,8 @@
 void nx_debugfs_init(struct nx_crypto_driver *);
 void nx_debugfs_fini(struct nx_crypto_driver *);
 #else
-#define NX_DEBUGFS_INIT(drv)	(0)
-#define NX_DEBUGFS_FINI(drv)	(0)
+#define NX_DEBUGFS_INIT(drv)	do {} while (0)
+#define NX_DEBUGFS_FINI(drv)	do {} while (0)
 #endif
 
 #define NX_PAGE_NUM(x)		((u64)(x) & 0xfffffffffffff000ULL)
diff --git a/kernel/drivers/crypto/omap-sham.c b/kernel/drivers/crypto/omap-sham.c
index 48f78e3..5a57617 100644
--- a/kernel/drivers/crypto/omap-sham.c
+++ b/kernel/drivers/crypto/omap-sham.c
@@ -2130,7 +2130,7 @@
 	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;
diff --git a/kernel/drivers/crypto/rockchip/cryptodev_linux/ioctl.c b/kernel/drivers/crypto/rockchip/cryptodev_linux/ioctl.c
index 0ad4400..032b016 100644
--- a/kernel/drivers/crypto/rockchip/cryptodev_linux/ioctl.c
+++ b/kernel/drivers/crypto/rockchip/cryptodev_linux/ioctl.c
@@ -131,6 +131,8 @@
 		return -EINVAL;
 	}
 
+	memset(&keys, 0x00, sizeof(keys));
+
 	switch (sop->cipher) {
 	case 0:
 		break;
diff --git a/kernel/drivers/crypto/rockchip/cryptodev_linux/rk_cryptodev.c b/kernel/drivers/crypto/rockchip/cryptodev_linux/rk_cryptodev.c
index 4c744f3..bf85f65 100644
--- a/kernel/drivers/crypto/rockchip/cryptodev_linux/rk_cryptodev.c
+++ b/kernel/drivers/crypto/rockchip/cryptodev_linux/rk_cryptodev.c
@@ -636,7 +636,7 @@
 	const char *driver = "rsa-rk";
 	struct crypto_akcipher *tfm = NULL;
 	struct akcipher_request *req = NULL;
-	struct crypto_wait wait;
+	DECLARE_CRYPTO_WAIT(wait);
 	struct scatterlist src, dst;
 	bool is_priv_key = (rop->flags & COP_FLAG_RSA_PRIV) == COP_FLAG_RSA_PRIV;
 
diff --git a/kernel/drivers/crypto/rockchip/cryptodev_linux/zc.c b/kernel/drivers/crypto/rockchip/cryptodev_linux/zc.c
index 1fc5887..7671c31 100644
--- a/kernel/drivers/crypto/rockchip/cryptodev_linux/zc.c
+++ b/kernel/drivers/crypto/rockchip/cryptodev_linux/zc.c
@@ -90,7 +90,7 @@
 #else
 	mmap_read_unlock(mm);
 #endif
-	if (ret != pgcount)
+	if (ret < 0 || ret != pgcount)
 		return -EINVAL;
 
 	sg_init_table(sg, pgcount);
diff --git a/kernel/drivers/crypto/rockchip/rk3288_crypto.c b/kernel/drivers/crypto/rockchip/rk3288_crypto.c
index 35d7306..14a0aef 100644
--- a/kernel/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/kernel/drivers/crypto/rockchip/rk3288_crypto.c
@@ -65,184 +65,22 @@
 	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;
-
-	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",
-				__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);
-		}
-	} 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__);
-			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->count = count;
-	return 0;
-}
-
-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;
-	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;
-		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[] = {
@@ -337,8 +175,6 @@
 	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);
@@ -389,18 +225,11 @@
 	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);
 
-	crypto_info->enable_clk = rk_crypto_enable_clk;
-	crypto_info->disable_clk = rk_crypto_disable_clk;
-	crypto_info->load_data = rk_load_data;
-	crypto_info->unload_data = rk_unload_data;
-	crypto_info->enqueue = rk_crypto_enqueue;
-	crypto_info->busy = false;
+	rk_crypto_enable_clk(crypto_info);
 
 	err = rk_crypto_register(crypto_info);
 	if (err) {
@@ -412,9 +241,9 @@
 	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;
 }
 
@@ -423,8 +252,8 @@
 	struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev);
 
 	rk_crypto_unregister();
-	tasklet_kill(&crypto_tmp->done_task);
-	tasklet_kill(&crypto_tmp->queue_task);
+	rk_crypto_disable_clk(crypto_tmp);
+	crypto_engine_exit(crypto_tmp->engine);
 	return 0;
 }
 
diff --git a/kernel/drivers/crypto/rockchip/rk3288_crypto.h b/kernel/drivers/crypto/rockchip/rk3288_crypto.h
index 3db5955..6b1413c 100644
--- a/kernel/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/kernel/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,45 +194,15 @@
 	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		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;
-	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 (*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);
-	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;
@@ -240,14 +212,23 @@
 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;
-	u32				mode;
+	u8				key[AES_MAX_KEY_SIZE];
 	u8				iv[AES_BLOCK_SIZE];
+	struct crypto_skcipher *fallback_tfm;
+};
+
+struct rk_cipher_rctx {
+	u8 backup_iv[AES_BLOCK_SIZE];
+	u32				mode;
+	struct skcipher_request fallback_req;   // keep at the end
 };
 
 enum alg_type {
diff --git a/kernel/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/kernel/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index 81befe7..edd40e1 100644
--- a/kernel/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/kernel/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -9,12 +9,47 @@
  * Some ideas are from marvell/cesa.c and s5p-sss.c driver.
  */
 #include <linux/device.h>
+#include <asm/unaligned.h>
 #include "rk3288_crypto.h"
 
 /*
  * IC can not process zero message hash,
  * 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)
 {
@@ -38,17 +73,13 @@
 	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);
-	int reg_status = 0;
+	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) |
 		     RK_CRYPTO_HASH_FLUSH | _SBF(0xffff, 16);
@@ -74,7 +105,7 @@
 					  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)
@@ -167,48 +198,64 @@
 	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
-		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)
 {
-	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);
+	int ret;
 
-	err = dev->load_data(dev, dev->sg_src, NULL);
-	if (!err)
-		crypto_ahash_dma_start(dev);
-	return err;
+	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_ahash_start(struct rk_crypto_info *dev)
+static int rk_hash_unprepare(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;
+	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);
 
-	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;
-	dev->src_nents = sg_nents(req->src);
-	rctx = ahash_request_ctx(req);
+	dma_unmap_sg(tctx->dev->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE);
+	return 0;
+}
+
+static int rk_hash_run(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);
+	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;
@@ -220,32 +267,26 @@
 		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 (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);
+	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;
 		}
-		err = rk_ahash_set_data_start(dev);
-	} else {
+		sg = sg_next(sg);
+	}
+
 		/*
 		 * it will take some time to process date after last dma
 		 * transmission.
@@ -256,18 +297,20 @@
 		 * efficiency, and make it response quickly when dma
 		 * complete.
 		 */
-		while (!CRYPTO_READ(dev, RK_CRYPTO_HASH_STS))
-			udelay(10);
+	while (!CRYPTO_READ(tctx->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);
+	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)
@@ -281,14 +324,6 @@
 	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;
 
 	/* for fallback */
 	tctx->fallback_tfm = crypto_alloc_ahash(alg_name, 0,
@@ -297,19 +332,23 @@
 		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));
 
-	return tctx->dev->enable_clk(tctx->dev);
+	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;
 }
 
 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);
+	crypto_free_ahash(tctx->fallback_tfm);
 }
 
 struct rk_crypto_tmp rk_ahash_sha1 = {
diff --git a/kernel/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/kernel/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 5bbf0d2..67a7e05 100644
--- a/kernel/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/kernel/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -9,23 +9,77 @@
  * 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)
 
-static void rk_crypto_complete(struct crypto_async_request *base, int err)
+static int rk_cipher_need_fallback(struct skcipher_request *req)
 {
-	if (base->complete)
-		base->complete(base, err);
+	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 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);
+	struct crypto_engine *engine = dev->engine;
+
+	if (rk_cipher_need_fallback(req))
+		return rk_cipher_fallback(req);
+
+	return crypto_transfer_skcipher_request_to_engine(engine, req);
 }
 
 static int rk_aes_setkey(struct crypto_skcipher *cipher,
@@ -38,8 +92,9 @@
 	    keylen != AES_KEYSIZE_256)
 		return -EINVAL;
 	ctx->keylen = keylen;
-	memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, key, keylen);
-	return 0;
+	memcpy(ctx->key, key, keylen);
+
+	return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
 }
 
 static int rk_des_setkey(struct crypto_skcipher *cipher,
@@ -53,8 +108,9 @@
 		return err;
 
 	ctx->keylen = keylen;
-	memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
-	return 0;
+	memcpy(ctx->key, key, keylen);
+
+	return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
 }
 
 static int rk_tdes_setkey(struct crypto_skcipher *cipher,
@@ -68,17 +124,19 @@
 		return err;
 
 	ctx->keylen = keylen;
-	memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
-	return 0;
+	memcpy(ctx->key, key, keylen);
+
+	return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
 }
 
 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 +144,10 @@
 {
 	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 +155,10 @@
 {
 	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 +166,10 @@
 {
 	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 +177,10 @@
 {
 	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 +188,10 @@
 {
 	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 +199,10 @@
 {
 	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 +210,10 @@
 {
 	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 +221,10 @@
 {
 	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 +232,10 @@
 {
 	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 +243,10 @@
 {
 	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,43 +254,42 @@
 {
 	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);
 }
 
-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) {
-		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);
-		memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize);
+		CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode);
+		memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen);
 		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);
-		memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize);
+			rctx->mode |= RK_CRYPTO_AES_256BIT_key;
+		CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode);
+		memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen);
 	}
 	conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO |
 		    RK_CRYPTO_BYTESWAP_BRFIFO;
@@ -231,146 +298,138 @@
 		     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 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 (ctx->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;
 
-	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);
-	dev->aligned = 1;
-
-	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_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 (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);
+	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);
 		}
 	}
-}
 
-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_ctx *ctx = crypto_skcipher_ctx(tfm);
-	u32 ivsize = crypto_skcipher_ivsize(tfm);
-	u8 *new_iv = NULL;
+	sgs = areq->src;
+	sgd = areq->dst;
 
-	if (ctx->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 (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);
-}
-
-/* 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->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;
+	while (sgs && sgd && len) {
+		if (!sgs->length) {
+			sgs = sg_next(sgs);
+			sgd = sg_next(sgd);
+			continue;
 		}
-	}
-	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",
-					__func__, __LINE__);
-				err = -ENOMEM;
-				goto out_rx;
+		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;
 			}
-			dev->sg_src = sg_next(dev->sg_src);
-			dev->sg_dst = sg_next(dev->sg_dst);
+		} 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 = rk_set_data_start(dev);
-	} 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);
+		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);
 	}
-out_rx:
+
+	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);
+		}
+	}
+
+theend:
+	local_bh_disable();
+	crypto_finalize_skcipher_request(engine, areq, err);
+	local_bh_enable();
+	return 0;
+
+theend_sgs:
+	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);
+	}
+theend_iv:
 	return err;
 }
 
@@ -378,26 +437,34 @@
 {
 	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);
 
 	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);
 
-	return ctx->dev->addr_vir ? ctx->dev->enable_clk(ctx->dev) : -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);
+
+	ctx->enginectx.op.do_one_request = rk_cipher_run;
+
+	return 0;
 }
 
 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);
+	memzero_explicit(ctx->key, ctx->keylen);
+	crypto_free_skcipher(ctx->fallback_tfm);
 }
 
 struct rk_crypto_tmp rk_ecb_aes_alg = {
@@ -406,7 +473,7 @@
 		.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,
@@ -428,7 +495,7 @@
 		.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,
@@ -451,7 +518,7 @@
 		.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,
@@ -473,7 +540,7 @@
 		.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,
@@ -496,7 +563,7 @@
 		.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,
@@ -518,7 +585,7 @@
 		.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,
diff --git a/kernel/drivers/crypto/stm32/stm32-hash.c b/kernel/drivers/crypto/stm32/stm32-hash.c
index 16bb528..37fde13 100644
--- a/kernel/drivers/crypto/stm32/stm32-hash.c
+++ b/kernel/drivers/crypto/stm32/stm32-hash.c
@@ -564,9 +564,9 @@
 	}
 
 	for_each_sg(rctx->sg, tsg, rctx->nents, i) {
+		sg[0] = *tsg;
 		len = sg->length;
 
-		sg[0] = *tsg;
 		if (sg_is_last(sg)) {
 			if (hdev->dma_mode == 1) {
 				len = (ALIGN(sg->length, 16) - 16);
@@ -1565,9 +1565,7 @@
 	if (!hdev)
 		return -ENODEV;
 
-	ret = pm_runtime_resume_and_get(hdev->dev);
-	if (ret < 0)
-		return ret;
+	ret = pm_runtime_get_sync(hdev->dev);
 
 	stm32_hash_unregister_algs(hdev);
 
@@ -1583,7 +1581,8 @@
 	pm_runtime_disable(hdev->dev);
 	pm_runtime_put_noidle(hdev->dev);
 
-	clk_disable_unprepare(hdev->clk);
+	if (ret >= 0)
+		clk_disable_unprepare(hdev->clk);
 
 	return 0;
 }
diff --git a/kernel/drivers/dax/bus.c b/kernel/drivers/dax/bus.c
index c1d379b..0541b7e 100644
--- a/kernel/drivers/dax/bus.c
+++ b/kernel/drivers/dax/bus.c
@@ -398,23 +398,39 @@
 	dev_dbg(dev, "%s\n", __func__);
 
 	kill_dev_dax(dev_dax);
-	free_dev_dax_ranges(dev_dax);
 	device_del(dev);
+	free_dev_dax_ranges(dev_dax);
 	put_device(dev);
 }
+
+static void dax_region_free(struct kref *kref)
+{
+	struct dax_region *dax_region;
+
+	dax_region = container_of(kref, struct dax_region, kref);
+	kfree(dax_region);
+}
+
+void dax_region_put(struct dax_region *dax_region)
+{
+	kref_put(&dax_region->kref, dax_region_free);
+}
+EXPORT_SYMBOL_GPL(dax_region_put);
 
 /* a return value >= 0 indicates this invocation invalidated the id */
 static int __free_dev_dax_id(struct dev_dax *dev_dax)
 {
-	struct dax_region *dax_region = dev_dax->region;
 	struct device *dev = &dev_dax->dev;
+	struct dax_region *dax_region;
 	int rc = dev_dax->id;
 
 	device_lock_assert(dev);
 
-	if (is_static(dax_region) || dev_dax->id < 0)
+	if (!dev_dax->dyn_id || dev_dax->id < 0)
 		return -1;
+	dax_region = dev_dax->region;
 	ida_free(&dax_region->ida, dev_dax->id);
+	dax_region_put(dax_region);
 	dev_dax->id = -1;
 	return rc;
 }
@@ -428,6 +444,20 @@
 	rc = __free_dev_dax_id(dev_dax);
 	device_unlock(dev);
 	return rc;
+}
+
+static int alloc_dev_dax_id(struct dev_dax *dev_dax)
+{
+	struct dax_region *dax_region = dev_dax->region;
+	int id;
+
+	id = ida_alloc(&dax_region->ida, GFP_KERNEL);
+	if (id < 0)
+		return id;
+	kref_get(&dax_region->kref);
+	dev_dax->dyn_id = true;
+	dev_dax->id = id;
+	return id;
 }
 
 static ssize_t delete_store(struct device *dev, struct device_attribute *attr,
@@ -517,20 +547,6 @@
 	NULL,
 };
 
-static void dax_region_free(struct kref *kref)
-{
-	struct dax_region *dax_region;
-
-	dax_region = container_of(kref, struct dax_region, kref);
-	kfree(dax_region);
-}
-
-void dax_region_put(struct dax_region *dax_region)
-{
-	kref_put(&dax_region->kref, dax_region_free);
-}
-EXPORT_SYMBOL_GPL(dax_region_put);
-
 static void dax_region_unregister(void *region)
 {
 	struct dax_region *dax_region = region;
@@ -592,10 +608,12 @@
 static void dax_mapping_release(struct device *dev)
 {
 	struct dax_mapping *mapping = to_dax_mapping(dev);
-	struct dev_dax *dev_dax = to_dev_dax(dev->parent);
+	struct device *parent = dev->parent;
+	struct dev_dax *dev_dax = to_dev_dax(parent);
 
 	ida_free(&dev_dax->ida, mapping->id);
 	kfree(mapping);
+	put_device(parent);
 }
 
 static void unregister_dax_mapping(void *data)
@@ -735,6 +753,7 @@
 	dev = &mapping->dev;
 	device_initialize(dev);
 	dev->parent = &dev_dax->dev;
+	get_device(dev->parent);
 	dev->type = &dax_mapping_type;
 	dev_set_name(dev, "mapping%d", mapping->id);
 	rc = device_add(dev);
@@ -1267,12 +1286,10 @@
 static void dev_dax_release(struct device *dev)
 {
 	struct dev_dax *dev_dax = to_dev_dax(dev);
-	struct dax_region *dax_region = dev_dax->region;
 	struct dax_device *dax_dev = dev_dax->dax_dev;
 
 	put_dax(dax_dev);
 	free_dev_dax_id(dev_dax);
-	dax_region_put(dax_region);
 	kfree(dev_dax->pgmap);
 	kfree(dev_dax);
 }
@@ -1296,6 +1313,7 @@
 	if (!dev_dax)
 		return ERR_PTR(-ENOMEM);
 
+	dev_dax->region = dax_region;
 	if (is_static(dax_region)) {
 		if (dev_WARN_ONCE(parent, data->id < 0,
 				"dynamic id specified to static region\n")) {
@@ -1311,13 +1329,11 @@
 			goto err_id;
 		}
 
-		rc = ida_alloc(&dax_region->ida, GFP_KERNEL);
+		rc = alloc_dev_dax_id(dev_dax);
 		if (rc < 0)
 			goto err_id;
-		dev_dax->id = rc;
 	}
 
-	dev_dax->region = dax_region;
 	dev = &dev_dax->dev;
 	device_initialize(dev);
 	dev_set_name(dev, "dax%d.%d", dax_region->id, dev_dax->id);
@@ -1355,7 +1371,6 @@
 	dev_dax->target_node = dax_region->target_node;
 	dev_dax->align = dax_region->align;
 	ida_init(&dev_dax->ida);
-	kref_get(&dax_region->kref);
 
 	inode = dax_inode(dax_dev);
 	dev->devt = inode->i_rdev;
diff --git a/kernel/drivers/dax/dax-private.h b/kernel/drivers/dax/dax-private.h
index 1c974b7..afcada6 100644
--- a/kernel/drivers/dax/dax-private.h
+++ b/kernel/drivers/dax/dax-private.h
@@ -52,7 +52,8 @@
  * @region - parent region
  * @dax_dev - core dax functionality
  * @target_node: effective numa node if dev_dax memory range is onlined
- * @id: ida allocated id
+ * @dyn_id: is this a dynamic or statically created instance
+ * @id: ida allocated id when the dax_region is not static
  * @ida: mapping id allocator
  * @dev - device core
  * @pgmap - pgmap for memmap setup / lifetime (driver owned)
@@ -64,6 +65,7 @@
 	struct dax_device *dax_dev;
 	unsigned int align;
 	int target_node;
+	bool dyn_id;
 	int id;
 	struct ida ida;
 	struct device dev;
diff --git a/kernel/drivers/dax/kmem.c b/kernel/drivers/dax/kmem.c
index b4368c5..27d669f 100644
--- a/kernel/drivers/dax/kmem.c
+++ b/kernel/drivers/dax/kmem.c
@@ -114,7 +114,7 @@
 		if (rc) {
 			dev_warn(dev, "mapping%d: %#llx-%#llx memory add failed\n",
 					i, range.start, range.end);
-			release_resource(res);
+			remove_resource(res);
 			kfree(res);
 			data->res[i] = NULL;
 			if (mapped)
@@ -159,7 +159,7 @@
 		rc = remove_memory(dev_dax->target_node, range.start,
 				range_len(&range));
 		if (rc == 0) {
-			release_resource(data->res[i]);
+			remove_resource(data->res[i]);
 			kfree(data->res[i]);
 			data->res[i] = NULL;
 			success++;
diff --git a/kernel/drivers/devfreq/devfreq.c b/kernel/drivers/devfreq/devfreq.c
index 16b6d8f..3ef5a51 100644
--- a/kernel/drivers/devfreq/devfreq.c
+++ b/kernel/drivers/devfreq/devfreq.c
@@ -732,6 +732,7 @@
 		devfreq->profile->exit(devfreq->dev.parent);
 
 	mutex_destroy(&devfreq->lock);
+	srcu_cleanup_notifier_head(&devfreq->transition_notifier_list);
 	kfree(devfreq);
 }
 
diff --git a/kernel/drivers/devfreq/rockchip_dmc.c b/kernel/drivers/devfreq/rockchip_dmc.c
index 7b957db..e3d39bd 100644
--- a/kernel/drivers/devfreq/rockchip_dmc.c
+++ b/kernel/drivers/devfreq/rockchip_dmc.c
@@ -7,7 +7,6 @@
  */
 
 #include <dt-bindings/clock/rockchip-ddr.h>
-#include <dt-bindings/soc/rockchip-system-status.h>
 #include <drm/drm_modeset_lock.h>
 #include <linux/arm-smccc.h>
 #include <linux/clk.h>
@@ -141,6 +140,7 @@
 	unsigned long hdmirx_rate;
 	unsigned long idle_rate;
 	unsigned long suspend_rate;
+	unsigned long deep_suspend_rate;
 	unsigned long reboot_rate;
 	unsigned long boost_rate;
 	unsigned long fixed_rate;
@@ -1996,6 +1996,12 @@
 	if (of_property_read_u32(pdev->dev.of_node, "wait-mode", &ddr_psci_param->wait_mode))
 		ddr_psci_param->wait_mode = 0;
 
+	res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, ROCKCHIP_SIP_CONFIG_DRAM_GET_STALL_TIME);
+	if (res.a0)
+		dev_err(dmcfreq->dev, "Current ATF unsupported get_stall_time\n");
+	else
+		dmcfreq->info.stall_time_ns = (unsigned int)res.a1;
+
 	dmcfreq->set_auto_self_refresh = rockchip_ddr_set_auto_self_refresh;
 
 	return 0;
@@ -2248,6 +2254,9 @@
 		case SYS_STATUS_SUSPEND:
 			dmcfreq->suspend_rate = freq * 1000;
 			break;
+		case SYS_STATUS_DEEP_SUSPEND:
+			dmcfreq->deep_suspend_rate = freq * 1000;
+			break;
 		case SYS_STATUS_VIDEO_1080P:
 			dmcfreq->video_1080p_rate = freq * 1000;
 			break;
@@ -2389,6 +2398,11 @@
 		case SYS_STATUS_SUSPEND:
 			dmcfreq->suspend_rate = rockchip_freq_level_2_rate(dmcfreq, level);
 			dev_info(dmcfreq->dev, "suspend_rate = %ld\n", dmcfreq->suspend_rate);
+			break;
+		case SYS_STATUS_DEEP_SUSPEND:
+			dmcfreq->deep_suspend_rate = rockchip_freq_level_2_rate(dmcfreq, level);
+			dev_info(dmcfreq->dev, "deep_suspend_rate = %ld\n",
+				 dmcfreq->deep_suspend_rate);
 			break;
 		case SYS_STATUS_VIDEO_1080P:
 			dmcfreq->video_1080p_rate = rockchip_freq_level_2_rate(dmcfreq, level);
@@ -3091,6 +3105,7 @@
 	devm_devfreq_register_opp_notifier(dev, devfreq);
 
 	devfreq->last_status.current_frequency = opp_rate;
+	devfreq->suspend_freq = dmcfreq->deep_suspend_rate;
 
 	reset_last_status(devfreq);
 
diff --git a/kernel/drivers/devfreq/rockchip_dmc_common.c b/kernel/drivers/devfreq/rockchip_dmc_common.c
index bb658eb..7765e71 100644
--- a/kernel/drivers/devfreq/rockchip_dmc_common.c
+++ b/kernel/drivers/devfreq/rockchip_dmc_common.c
@@ -166,6 +166,15 @@
 }
 EXPORT_SYMBOL(rockchip_dmcfreq_vop_bandwidth_request);
 
+unsigned int rockchip_dmcfreq_get_stall_time_ns(void)
+{
+	if (!common_info)
+		return 0;
+
+	return common_info->stall_time_ns;
+}
+EXPORT_SYMBOL(rockchip_dmcfreq_get_stall_time_ns);
+
 MODULE_AUTHOR("Finley Xiao <finley.xiao@rock-chips.com>");
 MODULE_DESCRIPTION("rockchip dmcfreq driver with devfreq framework");
 MODULE_LICENSE("GPL v2");
diff --git a/kernel/drivers/dio/dio.c b/kernel/drivers/dio/dio.c
index 193b40e..1414a1c 100644
--- a/kernel/drivers/dio/dio.c
+++ b/kernel/drivers/dio/dio.c
@@ -110,6 +110,12 @@
 
 #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 @@
 		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 @@
 		if (error) {
 			pr_err("DIO: Error registering device %s\n",
 			       dev->name);
+			put_device(&dev->dev);
 			continue;
 		}
 		error = dio_create_sysfs_dev_files(dev);
diff --git a/kernel/drivers/dma-buf/heaps/page_pool.c b/kernel/drivers/dma-buf/heaps/page_pool.c
index de9d728..9d3ddb5 100644
--- a/kernel/drivers/dma-buf/heaps/page_pool.c
+++ b/kernel/drivers/dma-buf/heaps/page_pool.c
@@ -144,7 +144,6 @@
 	pool->gfp_mask = gfp_mask | __GFP_COMP;
 	pool->order = order;
 	mutex_init(&pool->mutex); /* No longer used! */
-	mutex_lock(&pool->mutex); /* Make sure anyone who attempts to acquire this hangs */
 
 	mutex_lock(&pool_list_lock);
 	list_add(&pool->list, &pool_list);
diff --git a/kernel/drivers/dma-buf/sw_sync.c b/kernel/drivers/dma-buf/sw_sync.c
index 3daa6c7..e403cde 100644
--- a/kernel/drivers/dma-buf/sw_sync.c
+++ b/kernel/drivers/dma-buf/sw_sync.c
@@ -193,6 +193,7 @@
  */
 static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
 {
+	LIST_HEAD(signalled);
 	struct sync_pt *pt, *next;
 
 	trace_sync_timeline(obj);
@@ -205,21 +206,20 @@
 		if (!timeline_fence_signaled(&pt->base))
 			break;
 
-		list_del_init(&pt->link);
+		dma_fence_get(&pt->base);
+
+		list_move_tail(&pt->link, &signalled);
 		rb_erase(&pt->node, &obj->pt_tree);
 
-		/*
-		 * A signal callback may release the last reference to this
-		 * fence, causing it to be freed. That operation has to be
-		 * last to avoid a use after free inside this loop, and must
-		 * be after we remove the fence from the timeline in order to
-		 * prevent deadlocking on timeline->lock inside
-		 * timeline_fence_release().
-		 */
 		dma_fence_signal_locked(&pt->base);
 	}
 
 	spin_unlock_irq(&obj->lock);
+
+	list_for_each_entry_safe(pt, next, &signalled, link) {
+		list_del_init(&pt->link);
+		dma_fence_put(&pt->base);
+	}
 }
 
 /**
diff --git a/kernel/drivers/dma/Kconfig b/kernel/drivers/dma/Kconfig
index 0801334..7e1bd79 100644
--- a/kernel/drivers/dma/Kconfig
+++ b/kernel/drivers/dma/Kconfig
@@ -208,6 +208,7 @@
 config FSL_EDMA
 	tristate "Freescale eDMA engine support"
 	depends on OF
+	depends on HAS_IOMEM
 	select DMA_ENGINE
 	select DMA_VIRTUAL_CHANNELS
 	help
@@ -277,6 +278,7 @@
 
 config INTEL_IDMA64
 	tristate "Intel integrated DMA 64-bit support"
+	depends on HAS_IOMEM
 	select DMA_ENGINE
 	select DMA_VIRTUAL_CHANNELS
 	help
diff --git a/kernel/drivers/dma/at_xdmac.c b/kernel/drivers/dma/at_xdmac.c
index b5d691a..861be86 100644
--- a/kernel/drivers/dma/at_xdmac.c
+++ b/kernel/drivers/dma/at_xdmac.c
@@ -212,6 +212,7 @@
 	int			irq;
 	struct clk		*clk;
 	u32			save_gim;
+	u32			save_gs;
 	struct dma_pool		*at_xdmac_desc_pool;
 	struct at_xdmac_chan	chan[];
 };
@@ -677,7 +678,8 @@
 		if (!desc) {
 			dev_err(chan2dev(chan), "can't get descriptor\n");
 			if (first)
-				list_splice_init(&first->descs_list, &atchan->free_descs_list);
+				list_splice_tail_init(&first->descs_list,
+						      &atchan->free_descs_list);
 			goto spin_unlock;
 		}
 
@@ -765,7 +767,8 @@
 		if (!desc) {
 			dev_err(chan2dev(chan), "can't get descriptor\n");
 			if (first)
-				list_splice_init(&first->descs_list, &atchan->free_descs_list);
+				list_splice_tail_init(&first->descs_list,
+						      &atchan->free_descs_list);
 			spin_unlock_irqrestore(&atchan->lock, irqflags);
 			return NULL;
 		}
@@ -967,6 +970,8 @@
 							NULL,
 							src_addr, dst_addr,
 							xt, xt->sgl);
+		if (!first)
+			return NULL;
 
 		/* Length of the block is (BLEN+1) microblocks. */
 		for (i = 0; i < xt->numf - 1; i++)
@@ -997,8 +1002,9 @@
 							       src_addr, dst_addr,
 							       xt, chunk);
 			if (!desc) {
-				list_splice_init(&first->descs_list,
-						 &atchan->free_descs_list);
+				if (first)
+					list_splice_tail_init(&first->descs_list,
+							      &atchan->free_descs_list);
 				return NULL;
 			}
 
@@ -1076,7 +1082,8 @@
 		if (!desc) {
 			dev_err(chan2dev(chan), "can't get descriptor\n");
 			if (first)
-				list_splice_init(&first->descs_list, &atchan->free_descs_list);
+				list_splice_tail_init(&first->descs_list,
+						      &atchan->free_descs_list);
 			return NULL;
 		}
 
@@ -1250,8 +1257,8 @@
 						   sg_dma_len(sg),
 						   value);
 		if (!desc && first)
-			list_splice_init(&first->descs_list,
-					 &atchan->free_descs_list);
+			list_splice_tail_init(&first->descs_list,
+					      &atchan->free_descs_list);
 
 		if (!first)
 			first = desc;
@@ -1526,20 +1533,6 @@
 	return ret;
 }
 
-/* Call must be protected by lock. */
-static void at_xdmac_remove_xfer(struct at_xdmac_chan *atchan,
-				    struct at_xdmac_desc *desc)
-{
-	dev_dbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, desc);
-
-	/*
-	 * Remove the transfer from the transfer list then move the transfer
-	 * descriptors into the free descriptors list.
-	 */
-	list_del(&desc->xfer_node);
-	list_splice_init(&desc->descs_list, &atchan->free_descs_list);
-}
-
 static void at_xdmac_advance_work(struct at_xdmac_chan *atchan)
 {
 	struct at_xdmac_desc	*desc;
@@ -1650,17 +1643,20 @@
 		}
 
 		txd = &desc->tx_dma_desc;
-
-		at_xdmac_remove_xfer(atchan, desc);
+		dma_cookie_complete(txd);
+		/* Remove the transfer from the transfer list. */
+		list_del(&desc->xfer_node);
 		spin_unlock_irq(&atchan->lock);
 
-		dma_cookie_complete(txd);
 		if (txd->flags & DMA_PREP_INTERRUPT)
 			dmaengine_desc_get_callback_invoke(txd, NULL);
 
 		dma_run_dependencies(txd);
 
 		spin_lock_irq(&atchan->lock);
+		/* Move the xfer descriptors into the free descriptors list. */
+		list_splice_tail_init(&desc->descs_list,
+				      &atchan->free_descs_list);
 		at_xdmac_advance_work(atchan);
 		spin_unlock_irq(&atchan->lock);
 	}
@@ -1807,8 +1803,11 @@
 		cpu_relax();
 
 	/* Cancel all pending transfers. */
-	list_for_each_entry_safe(desc, _desc, &atchan->xfers_list, xfer_node)
-		at_xdmac_remove_xfer(atchan, desc);
+	list_for_each_entry_safe(desc, _desc, &atchan->xfers_list, xfer_node) {
+		list_del(&desc->xfer_node);
+		list_splice_tail_init(&desc->descs_list,
+				      &atchan->free_descs_list);
+	}
 
 	clear_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status);
 	clear_bit(AT_XDMAC_CHAN_IS_CYCLIC, &atchan->status);
@@ -1910,6 +1909,7 @@
 		}
 	}
 	atxdmac->save_gim = at_xdmac_read(atxdmac, AT_XDMAC_GIM);
+	atxdmac->save_gs = at_xdmac_read(atxdmac, AT_XDMAC_GS);
 
 	at_xdmac_off(atxdmac);
 	clk_disable_unprepare(atxdmac->clk);
@@ -1946,7 +1946,8 @@
 			at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc);
 			at_xdmac_chan_write(atchan, AT_XDMAC_CIE, atchan->save_cim);
 			wmb();
-			at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask);
+			if (atxdmac->save_gs & atchan->mask)
+				at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask);
 		}
 	}
 	return 0;
diff --git a/kernel/drivers/dma/dmaengine.c b/kernel/drivers/dma/dmaengine.c
index af3ee28..4ec7bb5 100644
--- a/kernel/drivers/dma/dmaengine.c
+++ b/kernel/drivers/dma/dmaengine.c
@@ -451,7 +451,8 @@
 	/* The channel is already in use, update client count */
 	if (chan->client_count) {
 		__module_get(owner);
-		goto out;
+		chan->client_count++;
+		return 0;
 	}
 
 	if (!try_module_get(owner))
@@ -470,11 +471,11 @@
 			goto err_out;
 	}
 
+	chan->client_count++;
+
 	if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask))
 		balance_ref_count(chan);
 
-out:
-	chan->client_count++;
 	return 0;
 
 err_out:
diff --git a/kernel/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/kernel/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 14c1ac2..b8b5d91 100644
--- a/kernel/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/kernel/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -551,6 +551,11 @@
 
 	/* The bad descriptor currently is in the head of vc list */
 	vd = vchan_next_desc(&chan->vc);
+	if (!vd) {
+		dev_err(chan2dev(chan), "BUG: %s, IRQ with no descriptors\n",
+			axi_chan_name(chan));
+		goto out;
+	}
 	/* Remove the completed descriptor from issued list */
 	list_del(&vd->node);
 
@@ -565,6 +570,7 @@
 	/* Try to restart the controller */
 	axi_chan_start_first_queued(chan);
 
+out:
 	spin_unlock_irqrestore(&chan->vc.lock, flags);
 }
 
diff --git a/kernel/drivers/dma/dw-edma/dw-edma-core.c b/kernel/drivers/dma/dw-edma/dw-edma-core.c
index d7ed50f..f91dbf4 100644
--- a/kernel/drivers/dma/dw-edma/dw-edma-core.c
+++ b/kernel/drivers/dma/dw-edma/dw-edma-core.c
@@ -166,7 +166,7 @@
 	dw_edma_free_desc(vd2dw_edma_desc(vdesc));
 }
 
-static void dw_edma_start_transfer(struct dw_edma_chan *chan)
+static int dw_edma_start_transfer(struct dw_edma_chan *chan)
 {
 	struct dw_edma_chunk *child;
 	struct dw_edma_desc *desc;
@@ -174,16 +174,16 @@
 
 	vd = vchan_next_desc(&chan->vc);
 	if (!vd)
-		return;
+		return 0;
 
 	desc = vd2dw_edma_desc(vd);
 	if (!desc)
-		return;
+		return 0;
 
 	child = list_first_entry_or_null(&desc->chunk->list,
 					 struct dw_edma_chunk, list);
 	if (!child)
-		return;
+		return 0;
 
 	dw_edma_v0_core_start(child, !desc->xfer_sz);
 	desc->xfer_sz += child->ll_region.sz;
@@ -191,6 +191,8 @@
 	list_del(&child->list);
 	kfree(child);
 	desc->chunks_alloc--;
+
+	return 1;
 }
 
 static int dw_edma_device_config(struct dma_chan *dchan,
@@ -274,9 +276,12 @@
 	struct dw_edma_chan *chan = dchan2dw_edma_chan(dchan);
 	unsigned long flags;
 
+	if (!chan->configured)
+		return;
+
 	spin_lock_irqsave(&chan->vc.lock, flags);
-	if (chan->configured && chan->request == EDMA_REQ_NONE &&
-	    chan->status == EDMA_ST_IDLE && vchan_issue_pending(&chan->vc)) {
+	if (vchan_issue_pending(&chan->vc) && chan->request == EDMA_REQ_NONE &&
+	    chan->status == EDMA_ST_IDLE) {
 		chan->status = EDMA_ST_BUSY;
 		dw_edma_start_transfer(chan);
 	}
@@ -497,14 +502,14 @@
 		switch (chan->request) {
 		case EDMA_REQ_NONE:
 			desc = vd2dw_edma_desc(vd);
-			if (desc->chunks_alloc) {
-				chan->status = EDMA_ST_BUSY;
-				dw_edma_start_transfer(chan);
-			} else {
+			if (!desc->chunks_alloc) {
 				list_del(&vd->node);
 				vchan_cookie_complete(vd);
-				chan->status = EDMA_ST_IDLE;
 			}
+
+			/* Continue transferring if there are remaining chunks or issued requests.
+			 */
+			chan->status = dw_edma_start_transfer(chan) ? EDMA_ST_BUSY : EDMA_ST_IDLE;
 			break;
 
 		case EDMA_REQ_STOP:
diff --git a/kernel/drivers/dma/imx-sdma.c b/kernel/drivers/dma/imx-sdma.c
index 2283dcd..6514db8 100644
--- a/kernel/drivers/dma/imx-sdma.c
+++ b/kernel/drivers/dma/imx-sdma.c
@@ -1363,10 +1363,12 @@
 		sdma_config_ownership(sdmac, false, true, false);
 
 	if (sdma_load_context(sdmac))
-		goto err_desc_out;
+		goto err_bd_out;
 
 	return desc;
 
+err_bd_out:
+	sdma_free_bd(desc);
 err_desc_out:
 	kfree(desc);
 err_out:
diff --git a/kernel/drivers/dma/mcf-edma.c b/kernel/drivers/dma/mcf-edma.c
index e12b754..60d3c5f 100644
--- a/kernel/drivers/dma/mcf-edma.c
+++ b/kernel/drivers/dma/mcf-edma.c
@@ -191,7 +191,13 @@
 		return -EINVAL;
 	}
 
-	chans = pdata->dma_channels;
+	if (!pdata->dma_channels) {
+		dev_info(&pdev->dev, "setting default channel number to 64");
+		chans = 64;
+	} else {
+		chans = pdata->dma_channels;
+	}
+
 	len = sizeof(*mcf_edma) + sizeof(*mcf_chan) * chans;
 	mcf_edma = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
 	if (!mcf_edma)
@@ -202,11 +208,6 @@
 	/* Set up drvdata for ColdFire edma */
 	mcf_edma->drvdata = &mcf_data;
 	mcf_edma->big_endian = 1;
-
-	if (!mcf_edma->n_chans) {
-		dev_info(&pdev->dev, "setting default channel number to 64");
-		mcf_edma->n_chans = 64;
-	}
 
 	mutex_init(&mcf_edma->fsl_edma_mutex);
 
diff --git a/kernel/drivers/dma/mv_xor_v2.c b/kernel/drivers/dma/mv_xor_v2.c
index 4800c59..9f3e011 100644
--- a/kernel/drivers/dma/mv_xor_v2.c
+++ b/kernel/drivers/dma/mv_xor_v2.c
@@ -756,7 +756,7 @@
 
 	xor_dev->clk = devm_clk_get(&pdev->dev, NULL);
 	if (PTR_ERR(xor_dev->clk) == -EPROBE_DEFER) {
-		ret = EPROBE_DEFER;
+		ret = -EPROBE_DEFER;
 		goto disable_reg_clk;
 	}
 	if (!IS_ERR(xor_dev->clk)) {
diff --git a/kernel/drivers/dma/pl330.c b/kernel/drivers/dma/pl330.c
index b1d6fae..0d14147 100644
--- a/kernel/drivers/dma/pl330.c
+++ b/kernel/drivers/dma/pl330.c
@@ -405,6 +405,12 @@
 	 */
 	BUSY,
 	/*
+	 * Pause was called while descriptor was BUSY. Due to hardware
+	 * limitations, only termination is possible for descriptors
+	 * that have been paused.
+	 */
+	PAUSED,
+	/*
 	 * Sitting on the channel work_list but xfer done
 	 * by PL330 core
 	 */
@@ -541,11 +547,9 @@
 	/* For cyclic capability */
 	bool cyclic;
 	size_t num_periods;
-#ifdef CONFIG_NO_GKI
-	/* interlace size */
-	unsigned int src_interlace_size;
-	unsigned int dst_interlace_size;
-#endif
+
+	/* interleaved size */
+	struct data_chunk sgl;
 };
 
 struct _xfer_spec {
@@ -1073,7 +1077,7 @@
 	return true;
 }
 
-static bool _start(struct pl330_thread *thrd)
+static bool pl330_start_thread(struct pl330_thread *thrd)
 {
 	switch (_state(thrd)) {
 	case PL330_STATE_FAULT_COMPLETING:
@@ -1204,7 +1208,7 @@
 				 const struct _xfer_spec *pxs, int cyc,
 				 enum pl330_cond cond)
 {
-	int off = 0;
+	int off = 0, i = 0, burstn = 1;
 
 	/*
 	 * do FLUSHP at beginning to clear any stale dma requests before the
@@ -1212,30 +1216,36 @@
 	 */
 	if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
 		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
+
+	if (pxs->desc->sgl.size) {
+		WARN_ON(BYTE_MOD_BURST_LEN(pxs->desc->sgl.size, pxs->ccr));
+		burstn = BYTE_TO_BURST(pxs->desc->sgl.size, pxs->ccr);
+	}
+
 	while (cyc--) {
-		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
-		off += _emit_load(dry_run, &buf[off], cond, pxs->desc->rqtype,
-			pxs->desc->peri);
-		off += _emit_store(dry_run, &buf[off], cond, pxs->desc->rqtype,
-			pxs->desc->peri);
-#ifdef CONFIG_NO_GKI
+		for (i = 0; i < burstn; i++) {
+			off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
+			off += _emit_load(dry_run, &buf[off], cond, pxs->desc->rqtype,
+				pxs->desc->peri);
+			off += _emit_store(dry_run, &buf[off], cond, pxs->desc->rqtype,
+				pxs->desc->peri);
+		}
+
 		switch (pxs->desc->rqtype) {
 		case DMA_DEV_TO_MEM:
-
-			if (pxs->desc->dst_interlace_size)
+			if (pxs->desc->sgl.dst_icg)
 				off += _emit_ADDH(dry_run, &buf[off], DST,
-						  pxs->desc->dst_interlace_size);
+						  pxs->desc->sgl.dst_icg);
 			break;
 		case DMA_MEM_TO_DEV:
-			if (pxs->desc->src_interlace_size)
+			if (pxs->desc->sgl.src_icg)
 				off += _emit_ADDH(dry_run, &buf[off], SRC,
-						  pxs->desc->src_interlace_size);
+						  pxs->desc->sgl.src_icg);
 			break;
 		default:
 			WARN_ON(1);
 			break;
 		}
-#endif
 	}
 
 	return off;
@@ -1450,9 +1460,7 @@
 		off += _emit_LPEND(dry_run, &buf[off], &lpend);
 	}
 
-#ifdef CONFIG_NO_GKI
-	if (!pxs->desc->src_interlace_size &&
-	    !pxs->desc->dst_interlace_size) {
+	if (!pxs->desc->sgl.src_icg && !pxs->desc->sgl.dst_icg) {
 		num_dregs = BYTE_MOD_BURST_LEN(x->bytes, pxs->ccr);
 
 		if (num_dregs) {
@@ -1460,14 +1468,6 @@
 			off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr);
 		}
 	}
-#else
-	num_dregs = BYTE_MOD_BURST_LEN(x->bytes, pxs->ccr);
-
-	if (num_dregs) {
-		off += _dregs(pl330, dry_run, &buf[off], pxs, num_dregs);
-		off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr);
-	}
-#endif
 
 	off += _emit_SEV(dry_run, &buf[off], ev);
 
@@ -1535,26 +1535,18 @@
 		BRST_SIZE(ccr);
 	int off = 0;
 
-#ifdef CONFIG_NO_GKI
-	if (pxs->desc->rqtype == DMA_DEV_TO_MEM)
-		bursts = x->bytes / (BRST_SIZE(ccr) * BRST_LEN(ccr) +
-				     pxs->desc->dst_interlace_size);
-	else if (pxs->desc->rqtype == DMA_MEM_TO_DEV)
-		bursts = x->bytes / (BRST_SIZE(ccr) * BRST_LEN(ccr) +
-				     pxs->desc->src_interlace_size);
-#endif
+	if (pxs->desc->sgl.size)
+		bursts = x->bytes / pxs->desc->sgl.size;
+
 	while (bursts) {
 		c = bursts;
 		off += _loop(pl330, dry_run, &buf[off], &c, pxs);
 		bursts -= c;
 	}
-#ifdef CONFIG_NO_GKI
-	if (!pxs->desc->src_interlace_size &&
-	    !pxs->desc->dst_interlace_size)
+
+	if (!pxs->desc->sgl.src_icg && !pxs->desc->sgl.dst_icg)
 		off += _dregs(pl330, dry_run, &buf[off], pxs, num_dregs);
-#else
-	off += _dregs(pl330, dry_run, &buf[off], pxs, num_dregs);
-#endif
+
 	return off;
 }
 
@@ -1585,14 +1577,9 @@
 	unsigned long bursts = BYTE_TO_BURST(x->bytes, ccr);
 	int off = 0;
 
-#ifdef CONFIG_NO_GKI
-	if (pxs->desc->rqtype == DMA_DEV_TO_MEM)
-		bursts = x->bytes / (BRST_SIZE(ccr) * BRST_LEN(ccr)
-			+ pxs->desc->dst_interlace_size);
-	else if (pxs->desc->rqtype == DMA_MEM_TO_DEV)
-		bursts = x->bytes / (BRST_SIZE(ccr) * BRST_LEN(ccr)
-			+ pxs->desc->src_interlace_size);
-#endif
+	if (pxs->desc->sgl.size)
+		bursts = x->bytes / pxs->desc->sgl.size;
+
 	/* Setup Loop(s) */
 	off += _loop_cyclic(pl330, dry_run, &buf[off], bursts, pxs, ev);
 
@@ -1907,7 +1894,7 @@
 					thrd->req[active].desc = NULL;
 					thrd->req_running = -1;
 					/* Get going again ASAP */
-					_start(thrd);
+					pl330_start_thread(thrd);
 				}
 
 				/* For now, just make a list of callbacks to be done */
@@ -2248,7 +2235,7 @@
 	list_for_each_entry(desc, &pch->work_list, node) {
 
 		/* If already submitted */
-		if (desc->status == BUSY)
+		if (desc->status == BUSY || desc->status == PAUSED)
 			continue;
 
 		ret = pl330_submit_req(pch->thread, desc);
@@ -2309,7 +2296,7 @@
 	} else {
 		/* Make sure the PL330 Channel thread is active */
 		spin_lock(&pch->thread->dmac->lock);
-		_start(pch->thread);
+		pl330_start_thread(pch->thread);
 		spin_unlock(&pch->thread->dmac->lock);
 	}
 
@@ -2454,10 +2441,6 @@
 			pch->fifo_addr = slave_config->dst_addr;
 		if (slave_config->dst_addr_width)
 			pch->burst_sz = __ffs(slave_config->dst_addr_width);
-#ifdef CONFIG_NO_GKI
-		if (slave_config->src_interlace_size)
-			pch->slave_config.src_interlace_size = slave_config->src_interlace_size;
-#endif
 		pch->burst_len = fixup_burst_len(slave_config->dst_maxburst,
 			pch->dmac->quirks);
 	} else if (direction == DMA_DEV_TO_MEM) {
@@ -2465,10 +2448,6 @@
 			pch->fifo_addr = slave_config->src_addr;
 		if (slave_config->src_addr_width)
 			pch->burst_sz = __ffs(slave_config->src_addr_width);
-#ifdef CONFIG_NO_GKI
-		if (slave_config->dst_interlace_size)
-			pch->slave_config.dst_interlace_size = slave_config->dst_interlace_size;
-#endif
 		pch->burst_len = fixup_burst_len(slave_config->src_maxburst,
 			pch->dmac->quirks);
 	}
@@ -2541,6 +2520,7 @@
 {
 	struct dma_pl330_chan *pch = to_pchan(chan);
 	struct pl330_dmac *pl330 = pch->dmac;
+	struct dma_pl330_desc *desc;
 	unsigned long flags;
 
 	pm_runtime_get_sync(pl330->ddma.dev);
@@ -2550,6 +2530,10 @@
 	_stop(pch->thread);
 	spin_unlock(&pl330->lock);
 
+	list_for_each_entry(desc, &pch->work_list, node) {
+		if (desc->status == BUSY)
+			desc->status = PAUSED;
+	}
 	spin_unlock_irqrestore(&pch->lock, flags);
 	pm_runtime_mark_last_busy(pl330->ddma.dev);
 	pm_runtime_put_autosuspend(pl330->ddma.dev);
@@ -2639,7 +2623,7 @@
 		else if (running && desc == running)
 			transferred =
 				pl330_get_current_xferred_count(pch, desc);
-		else if (desc->status == BUSY)
+		else if (desc->status == BUSY || desc->status == PAUSED)
 			/*
 			 * Busy but not running means either just enqueued,
 			 * or finished and not yet marked done
@@ -2655,6 +2639,9 @@
 			switch (desc->status) {
 			case DONE:
 				ret = DMA_COMPLETE;
+				break;
+			case PAUSED:
+				ret = DMA_PAUSED;
 				break;
 			case PREP:
 			case BUSY:
@@ -2821,6 +2808,10 @@
 	desc->cyclic = false;
 	desc->num_periods = 1;
 
+	desc->sgl.size = 0;
+	desc->sgl.src_icg = 0;
+	desc->sgl.dst_icg = 0;
+
 	dma_async_tx_descriptor_init(&desc->txd, &pch->chan);
 
 	return desc;
@@ -2936,10 +2927,82 @@
 	desc->cyclic = true;
 	desc->num_periods = len / period_len;
 	desc->txd.flags = flags;
+
+	return &desc->txd;
+}
+
+static struct dma_async_tx_descriptor *pl330_prep_interleaved_dma(
+	struct dma_chan *chan, struct dma_interleaved_template *xt,
+	unsigned long flags)
+{
+	struct dma_pl330_desc *desc = NULL;
+	struct dma_pl330_chan *pch = to_pchan(chan);
+	dma_addr_t dst = 0, src = 0;
+	size_t size, src_icg, dst_icg, period_bytes, buffer_bytes, full_buffer_bytes;
+	size_t nump = 0, numf = 0;
+
+	if (!xt->numf || !xt->sgl[0].size || xt->frame_size != 1)
+		return NULL;
+
 #ifdef CONFIG_NO_GKI
-	desc->src_interlace_size = pch->slave_config.src_interlace_size;
-	desc->dst_interlace_size = pch->slave_config.dst_interlace_size;
+	nump = xt->nump;
 #endif
+	numf = xt->numf;
+	size = xt->sgl[0].size;
+	period_bytes = size * nump;
+	buffer_bytes = size * numf;
+
+	if (flags & DMA_PREP_REPEAT && (!nump || (numf % nump)))
+		return NULL;
+
+	src_icg = dmaengine_get_src_icg(xt, &xt->sgl[0]);
+	dst_icg = dmaengine_get_dst_icg(xt, &xt->sgl[0]);
+
+	pl330_config_write(chan, &pch->slave_config, xt->dir);
+
+	if (!pl330_prep_slave_fifo(pch, xt->dir))
+		return NULL;
+
+	desc = pl330_get_desc(pch);
+	if (!desc) {
+		dev_err(chan->device->dev, "Failed to get desc\n");
+		return NULL;
+	}
+
+	if (xt->dir == DMA_MEM_TO_DEV) {
+		desc->rqcfg.src_inc = 1;
+		desc->rqcfg.dst_inc = 0;
+		src = xt->src_start;
+		dst = pch->fifo_dma;
+		full_buffer_bytes = (size + src_icg) * numf;
+	} else {
+		desc->rqcfg.src_inc = 0;
+		desc->rqcfg.dst_inc = 1;
+		src = pch->fifo_dma;
+		dst = xt->dst_start;
+		full_buffer_bytes = (size + dst_icg) * numf;
+	}
+
+	desc->rqtype = xt->dir;
+	desc->rqcfg.brst_size = pch->burst_sz;
+	desc->rqcfg.brst_len = pch->burst_len;
+	desc->bytes_requested = full_buffer_bytes;
+	desc->sgl.size = size;
+	desc->sgl.src_icg = src_icg;
+	desc->sgl.dst_icg = dst_icg;
+	desc->txd.flags = flags;
+
+	if (flags & DMA_PREP_REPEAT) {
+		desc->cyclic = true;
+		desc->num_periods = numf / nump;
+		fill_px(&desc->px, dst, src, period_bytes);
+	} else {
+		fill_px(&desc->px, dst, src, buffer_bytes);
+	}
+
+	dev_dbg(chan->device->dev, "size: %zu, src_icg: %zu, dst_icg: %zu, nump: %zu, numf: %zu\n",
+		size, src_icg, dst_icg, nump, numf);
+
 	return &desc->txd;
 }
 
@@ -3072,10 +3135,6 @@
 		desc->rqcfg.brst_len = pch->burst_len;
 		desc->rqtype = direction;
 		desc->bytes_requested = sg_dma_len(sg);
-#ifdef CONFIG_NO_GKI
-		desc->src_interlace_size = pch->slave_config.src_interlace_size;
-		desc->dst_interlace_size = pch->slave_config.dst_interlace_size;
-#endif
 	}
 
 	/* Return the last desc in the chain */
@@ -3311,12 +3370,16 @@
 		dma_cap_set(DMA_SLAVE, pd->cap_mask);
 		dma_cap_set(DMA_CYCLIC, pd->cap_mask);
 		dma_cap_set(DMA_PRIVATE, pd->cap_mask);
+		dma_cap_set(DMA_INTERLEAVE, pd->cap_mask);
+		dma_cap_set(DMA_REPEAT, pd->cap_mask);
+		dma_cap_set(DMA_LOAD_EOT, pd->cap_mask);
 	}
 
 	pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
 	pd->device_free_chan_resources = pl330_free_chan_resources;
 	pd->device_prep_dma_memcpy = pl330_prep_dma_memcpy;
 	pd->device_prep_dma_cyclic = pl330_prep_dma_cyclic;
+	pd->device_prep_interleaved_dma = pl330_prep_interleaved_dma;
 	pd->device_tx_status = pl330_tx_status;
 	pd->device_prep_slave_sg = pl330_prep_slave_sg;
 	pd->device_config = pl330_config;
diff --git a/kernel/drivers/dma/ste_dma40.c b/kernel/drivers/dma/ste_dma40.c
index b35b97c..d99fec8 100644
--- a/kernel/drivers/dma/ste_dma40.c
+++ b/kernel/drivers/dma/ste_dma40.c
@@ -3598,6 +3598,10 @@
 	spin_lock_init(&base->lcla_pool.lock);
 
 	base->irq = platform_get_irq(pdev, 0);
+	if (base->irq < 0) {
+		ret = base->irq;
+		goto destroy_cache;
+	}
 
 	ret = request_irq(base->irq, d40_handle_interrupt, 0, D40_NAME, base);
 	if (ret) {
diff --git a/kernel/drivers/dma/tegra210-adma.c b/kernel/drivers/dma/tegra210-adma.c
index c5fa2ef..d84010c 100644
--- a/kernel/drivers/dma/tegra210-adma.c
+++ b/kernel/drivers/dma/tegra210-adma.c
@@ -224,7 +224,7 @@
 	int ret;
 
 	/* Clear any interrupts */
-	tdma_write(tdma, tdma->cdata->global_int_clear, 0x1);
+	tdma_write(tdma, tdma->cdata->ch_base_offset + tdma->cdata->global_int_clear, 0x1);
 
 	/* Assert soft reset */
 	tdma_write(tdma, ADMA_GLOBAL_SOFT_RESET, 0x1);
diff --git a/kernel/drivers/dma/xilinx/xilinx_dma.c b/kernel/drivers/dma/xilinx/xilinx_dma.c
index e76adc3..12ad4bb 100644
--- a/kernel/drivers/dma/xilinx/xilinx_dma.c
+++ b/kernel/drivers/dma/xilinx/xilinx_dma.c
@@ -3119,8 +3119,10 @@
 	/* Initialize the channels */
 	for_each_child_of_node(node, child) {
 		err = xilinx_dma_child_probe(xdev, child);
-		if (err < 0)
+		if (err < 0) {
+			of_node_put(child);
 			goto error;
+		}
 	}
 
 	if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {
diff --git a/kernel/drivers/edac/edac_device.c b/kernel/drivers/edac/edac_device.c
index 8c4d947..85c2299 100644
--- a/kernel/drivers/edac/edac_device.c
+++ b/kernel/drivers/edac/edac_device.c
@@ -34,6 +34,9 @@
 static DEFINE_MUTEX(device_ctls_mutex);
 static LIST_HEAD(edac_device_list);
 
+/* Default workqueue processing interval on this instance, in msecs */
+#define DEFAULT_POLL_INTERVAL 1000
+
 #ifdef CONFIG_EDAC_DEBUG
 static void edac_device_dump_device(struct edac_device_ctl_info *edac_dev)
 {
@@ -366,7 +369,7 @@
 	 * whole one second to save timers firing all over the period
 	 * between integral seconds
 	 */
-	if (edac_dev->poll_msec == 1000)
+	if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL)
 		edac_queue_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay));
 	else
 		edac_queue_work(&edac_dev->work, edac_dev->delay);
@@ -396,7 +399,7 @@
 	 * timers firing on sub-second basis, while they are happy
 	 * to fire together on the 1 second exactly
 	 */
-	if (edac_dev->poll_msec == 1000)
+	if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL)
 		edac_queue_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay));
 	else
 		edac_queue_work(&edac_dev->work, edac_dev->delay);
@@ -424,17 +427,16 @@
  *	Then restart the workq on the new delay
  */
 void edac_device_reset_delay_period(struct edac_device_ctl_info *edac_dev,
-					unsigned long value)
+				    unsigned long msec)
 {
-	unsigned long jiffs = msecs_to_jiffies(value);
+	edac_dev->poll_msec = msec;
+	edac_dev->delay	    = msecs_to_jiffies(msec);
 
-	if (value == 1000)
-		jiffs = round_jiffies_relative(value);
-
-	edac_dev->poll_msec = value;
-	edac_dev->delay	    = jiffs;
-
-	edac_mod_work(&edac_dev->work, jiffs);
+	/* See comment in edac_device_workq_setup() above */
+	if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL)
+		edac_mod_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay));
+	else
+		edac_mod_work(&edac_dev->work, edac_dev->delay);
 }
 
 int edac_device_alloc_index(void)
@@ -473,11 +475,7 @@
 		/* This instance is NOW RUNNING */
 		edac_dev->op_state = OP_RUNNING_POLL;
 
-		/*
-		 * enable workq processing on this instance,
-		 * default = 1000 msec
-		 */
-		edac_device_workq_setup(edac_dev, 1000);
+		edac_device_workq_setup(edac_dev, edac_dev->poll_msec ?: DEFAULT_POLL_INTERVAL);
 	} else {
 		edac_dev->op_state = OP_RUNNING_INTERRUPT;
 	}
diff --git a/kernel/drivers/edac/edac_module.h b/kernel/drivers/edac/edac_module.h
index aa1f916..841d238 100644
--- a/kernel/drivers/edac/edac_module.h
+++ b/kernel/drivers/edac/edac_module.h
@@ -56,7 +56,7 @@
 bool edac_mod_work(struct delayed_work *work, unsigned long delay);
 
 extern void edac_device_reset_delay_period(struct edac_device_ctl_info
-					   *edac_dev, unsigned long value);
+					   *edac_dev, unsigned long msec);
 extern void edac_mc_reset_delay_period(unsigned long value);
 
 extern void *edac_align_ptr(void **p, unsigned size, int n_elems);
diff --git a/kernel/drivers/edac/highbank_mc_edac.c b/kernel/drivers/edac/highbank_mc_edac.c
index 61b76ec..19fba25 100644
--- a/kernel/drivers/edac/highbank_mc_edac.c
+++ b/kernel/drivers/edac/highbank_mc_edac.c
@@ -174,8 +174,10 @@
 	drvdata = mci->pvt_info;
 	platform_set_drvdata(pdev, mci);
 
-	if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL))
-		return -ENOMEM;
+	if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) {
+		res = -ENOMEM;
+		goto free;
+	}
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!r) {
@@ -243,6 +245,7 @@
 	edac_mc_del_mc(&pdev->dev);
 err:
 	devres_release_group(&pdev->dev, NULL);
+free:
 	edac_mc_free(mci);
 	return res;
 }
diff --git a/kernel/drivers/edac/i10nm_base.c b/kernel/drivers/edac/i10nm_base.c
index 3a7362f..43dbea6 100644
--- a/kernel/drivers/edac/i10nm_base.c
+++ b/kernel/drivers/edac/i10nm_base.c
@@ -53,10 +53,9 @@
 	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;
 }
diff --git a/kernel/drivers/edac/qcom_edac.c b/kernel/drivers/edac/qcom_edac.c
index 97a27e4..c45519f 100644
--- a/kernel/drivers/edac/qcom_edac.c
+++ b/kernel/drivers/edac/qcom_edac.c
@@ -252,7 +252,7 @@
 static int
 dump_syn_reg(struct edac_device_ctl_info *edev_ctl, int err_type, u32 bank)
 {
-	struct llcc_drv_data *drv = edev_ctl->pvt_info;
+	struct llcc_drv_data *drv = edev_ctl->dev->platform_data;
 	int ret;
 
 	ret = dump_syn_reg_values(drv, bank, err_type);
@@ -289,7 +289,7 @@
 llcc_ecc_irq_handler(int irq, void *edev_ctl)
 {
 	struct edac_device_ctl_info *edac_dev_ctl = edev_ctl;
-	struct llcc_drv_data *drv = edac_dev_ctl->pvt_info;
+	struct llcc_drv_data *drv = edac_dev_ctl->dev->platform_data;
 	irqreturn_t irq_rc = IRQ_NONE;
 	u32 drp_error, trp_error, i;
 	int ret;
@@ -358,7 +358,6 @@
 	edev_ctl->dev_name = dev_name(dev);
 	edev_ctl->ctl_name = "llcc";
 	edev_ctl->panic_on_ue = LLCC_ERP_PANIC_ON_UE;
-	edev_ctl->pvt_info = llcc_driv_data;
 
 	rc = edac_device_add_device(edev_ctl);
 	if (rc)
diff --git a/kernel/drivers/edac/skx_base.c b/kernel/drivers/edac/skx_base.c
index f887e31..ba3e833 100644
--- a/kernel/drivers/edac/skx_base.c
+++ b/kernel/drivers/edac/skx_base.c
@@ -509,7 +509,7 @@
 }
 
 static u8 skx_close_row[] = {
-	15, 16, 17, 18, 20, 21, 22, 28, 10, 11, 12, 13, 29, 30, 31, 32, 33
+	15, 16, 17, 18, 20, 21, 22, 28, 10, 11, 12, 13, 29, 30, 31, 32, 33, 34
 };
 
 static u8 skx_close_column[] = {
@@ -517,7 +517,7 @@
 };
 
 static u8 skx_open_row[] = {
-	14, 15, 16, 20, 28, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33
+	14, 15, 16, 20, 28, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34
 };
 
 static u8 skx_open_column[] = {
diff --git a/kernel/drivers/extcon/extcon.c b/kernel/drivers/extcon/extcon.c
index a11aaaf..97b0c8f 100644
--- a/kernel/drivers/extcon/extcon.c
+++ b/kernel/drivers/extcon/extcon.c
@@ -211,6 +211,14 @@
  * @attr_name:		"name" sysfs entry
  * @attr_state:		"state" sysfs entry
  * @attrs:		the array pointing to attr_name and attr_state for attr_g
+ * @usb_propval:	the array of USB connector properties
+ * @chg_propval:	the array of charger connector properties
+ * @jack_propval:	the array of jack connector properties
+ * @disp_propval:	the array of display connector properties
+ * @usb_bits:		the bit array of the USB connector property capabilities
+ * @chg_bits:		the bit array of the charger connector property capabilities
+ * @jack_bits:		the bit array of the jack connector property capabilities
+ * @disp_bits:		the bit array of the display connector property capabilities
  */
 struct extcon_cable {
 	struct extcon_dev *edev;
diff --git a/kernel/drivers/firewire/core-cdev.c b/kernel/drivers/firewire/core-cdev.c
index b0cc3f1..16ea847 100644
--- a/kernel/drivers/firewire/core-cdev.c
+++ b/kernel/drivers/firewire/core-cdev.c
@@ -818,8 +818,10 @@
 
 	r = container_of(resource, struct inbound_transaction_resource,
 			 resource);
-	if (is_fcp_request(r->request))
+	if (is_fcp_request(r->request)) {
+		kfree(r->data);
 		goto out;
+	}
 
 	if (a->length != fw_get_response_length(r->request)) {
 		ret = -EINVAL;
diff --git a/kernel/drivers/firmware/Kconfig b/kernel/drivers/firmware/Kconfig
index 84cc022..3c5a47f 100644
--- a/kernel/drivers/firmware/Kconfig
+++ b/kernel/drivers/firmware/Kconfig
@@ -72,6 +72,7 @@
 config ARM_SDE_INTERFACE
 	bool "ARM Software Delegated Exception Interface (SDEI)"
 	depends on ARM64
+	depends on ACPI_APEI_GHES
 	help
 	  The Software Delegated Exception Interface (SDEI) is an ARM
 	  standard for registering callbacks from the platform firmware
diff --git a/kernel/drivers/firmware/arm_scmi/mailbox.c b/kernel/drivers/firmware/arm_scmi/mailbox.c
index 4626404..ad773a6 100644
--- a/kernel/drivers/firmware/arm_scmi/mailbox.c
+++ b/kernel/drivers/firmware/arm_scmi/mailbox.c
@@ -52,6 +52,39 @@
 					   "#mbox-cells", idx, NULL);
 }
 
+static int mailbox_chan_validate(struct device *cdev)
+{
+	int num_mb, num_sh, ret = 0;
+	struct device_node *np = cdev->of_node;
+
+	num_mb = of_count_phandle_with_args(np, "mboxes", "#mbox-cells");
+	num_sh = of_count_phandle_with_args(np, "shmem", NULL);
+	/* Bail out if mboxes and shmem descriptors are inconsistent */
+	if (num_mb <= 0 || num_sh > 2 || num_mb != num_sh) {
+		dev_warn(cdev, "Invalid channel descriptor for '%s'\n",
+			 of_node_full_name(np));
+		return -EINVAL;
+	}
+
+	if (num_sh > 1) {
+		struct device_node *np_tx, *np_rx;
+
+		np_tx = of_parse_phandle(np, "shmem", 0);
+		np_rx = of_parse_phandle(np, "shmem", 1);
+		/* SCMI Tx and Rx shared mem areas have to be distinct */
+		if (!np_tx || !np_rx || np_tx == np_rx) {
+			dev_warn(cdev, "Invalid shmem descriptor for '%s'\n",
+				 of_node_full_name(np));
+			ret = -EINVAL;
+		}
+
+		of_node_put(np_tx);
+		of_node_put(np_rx);
+	}
+
+	return ret;
+}
+
 static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
 			      bool tx)
 {
@@ -64,6 +97,10 @@
 	resource_size_t size;
 	struct resource res;
 
+	ret = mailbox_chan_validate(cdev);
+	if (ret)
+		return ret;
+
 	smbox = devm_kzalloc(dev, sizeof(*smbox), GFP_KERNEL);
 	if (!smbox)
 		return -ENOMEM;
diff --git a/kernel/drivers/firmware/arm_scmi/shmem.c b/kernel/drivers/firmware/arm_scmi/shmem.c
index 0e3eaea..56a1f61 100644
--- a/kernel/drivers/firmware/arm_scmi/shmem.c
+++ b/kernel/drivers/firmware/arm_scmi/shmem.c
@@ -58,10 +58,11 @@
 void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
 			  struct scmi_xfer *xfer)
 {
+	size_t len = ioread32(&shmem->length);
+
 	xfer->hdr.status = ioread32(shmem->msg_payload);
 	/* Skip the length of header and status in shmem area i.e 8 bytes */
-	xfer->rx.len = min_t(size_t, xfer->rx.len,
-			     ioread32(&shmem->length) - 8);
+	xfer->rx.len = min_t(size_t, xfer->rx.len, len > 8 ? len - 8 : 0);
 
 	/* Take a copy to the rx buffer.. */
 	memcpy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len);
@@ -70,8 +71,10 @@
 void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem,
 			      size_t max_len, struct scmi_xfer *xfer)
 {
+	size_t len = ioread32(&shmem->length);
+
 	/* Skip only the length of header in shmem area i.e 4 bytes */
-	xfer->rx.len = min_t(size_t, max_len, ioread32(&shmem->length) - 4);
+	xfer->rx.len = min_t(size_t, max_len, len > 4 ? len - 4 : 0);
 
 	/* Take a copy to the rx buffer.. */
 	memcpy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len);
diff --git a/kernel/drivers/firmware/arm_sdei.c b/kernel/drivers/firmware/arm_sdei.c
index 052f533..842ac05 100644
--- a/kernel/drivers/firmware/arm_sdei.c
+++ b/kernel/drivers/firmware/arm_sdei.c
@@ -1140,14 +1140,14 @@
 	return true;
 }
 
-static int __init sdei_init(void)
+void __init sdei_init(void)
 {
 	struct platform_device *pdev;
 	int ret;
 
 	ret = platform_driver_register(&sdei_driver);
 	if (ret || !sdei_present_acpi())
-		return ret;
+		return;
 
 	pdev = platform_device_register_simple(sdei_driver.driver.name,
 					       0, NULL, 0);
@@ -1157,16 +1157,7 @@
 		pr_info("Failed to register ACPI:SDEI platform device %d\n",
 			ret);
 	}
-
-	return ret;
 }
-
-/*
- * On an ACPI system SDEI needs to be ready before HEST:GHES tries to register
- * its events. ACPI is initialised from a subsys_initcall(), GHES is initialised
- * by device_initcall(). We want to be called in the middle.
- */
-subsys_initcall_sync(sdei_init);
 
 int sdei_event_handler(struct pt_regs *regs,
 		       struct sdei_registered_event *arg)
@@ -1195,3 +1186,22 @@
 	return err;
 }
 NOKPROBE_SYMBOL(sdei_event_handler);
+
+void sdei_handler_abort(void)
+{
+	/*
+	 * If the crash happened in an SDEI event handler then we need to
+	 * finish the handler with the firmware so that we can have working
+	 * interrupts in the crash kernel.
+	 */
+	if (__this_cpu_read(sdei_active_critical_event)) {
+	        pr_warn("still in SDEI critical event context, attempting to finish handler.\n");
+	        __sdei_handler_abort();
+	        __this_cpu_write(sdei_active_critical_event, NULL);
+	}
+	if (__this_cpu_read(sdei_active_normal_event)) {
+	        pr_warn("still in SDEI normal event context, attempting to finish handler.\n");
+	        __sdei_handler_abort();
+	        __this_cpu_write(sdei_active_normal_event, NULL);
+	}
+}
diff --git a/kernel/drivers/firmware/efi/efi.c b/kernel/drivers/firmware/efi/efi.c
index 70be9c8..332739f 100644
--- a/kernel/drivers/firmware/efi/efi.c
+++ b/kernel/drivers/firmware/efi/efi.c
@@ -385,8 +385,8 @@
 	efi_kobj = kobject_create_and_add("efi", firmware_kobj);
 	if (!efi_kobj) {
 		pr_err("efi: Firmware registration failed.\n");
-		destroy_workqueue(efi_rts_wq);
-		return -ENOMEM;
+		error = -ENOMEM;
+		goto err_destroy_wq;
 	}
 
 	if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
@@ -429,7 +429,10 @@
 		generic_ops_unregister();
 err_put:
 	kobject_put(efi_kobj);
-	destroy_workqueue(efi_rts_wq);
+err_destroy_wq:
+	if (efi_rts_wq)
+		destroy_workqueue(efi_rts_wq);
+
 	return error;
 }
 
@@ -590,7 +593,7 @@
 
 		seed = early_memremap(efi_rng_seed, sizeof(*seed));
 		if (seed != NULL) {
-			size = min(seed->size, EFI_RANDOM_SEED_SIZE);
+			size = min_t(u32, seed->size, SZ_1K); // sanity check
 			early_memunmap(seed, sizeof(*seed));
 		} else {
 			pr_err("Could not map UEFI random seed!\n");
@@ -599,8 +602,8 @@
 			seed = early_memremap(efi_rng_seed,
 					      sizeof(*seed) + size);
 			if (seed != NULL) {
-				pr_notice("seeding entropy pool\n");
 				add_bootloader_randomness(seed->bits, size);
+				memzero_explicit(seed->bits, size);
 				early_memunmap(seed, sizeof(*seed) + size);
 			} else {
 				pr_err("Could not map UEFI random seed!\n");
@@ -947,6 +950,8 @@
 	/* first try to find a slot in an existing linked list entry */
 	for (prsv = efi_memreserve_root->next; prsv; ) {
 		rsv = memremap(prsv, sizeof(*rsv), MEMREMAP_WB);
+		if (!rsv)
+			return -ENOMEM;
 		index = atomic_fetch_add_unless(&rsv->count, 1, rsv->size);
 		if (index < rsv->size) {
 			rsv->entry[index].base = addr;
diff --git a/kernel/drivers/firmware/efi/libstub/efistub.h b/kernel/drivers/firmware/efi/libstub/efistub.h
index 2d7abcd..c5e0c6e 100644
--- a/kernel/drivers/firmware/efi/libstub/efistub.h
+++ b/kernel/drivers/firmware/efi/libstub/efistub.h
@@ -767,6 +767,8 @@
 efi_status_t efi_random_alloc(unsigned long size, unsigned long align,
 			      unsigned long *addr, unsigned long random_seed);
 
+efi_status_t efi_random_get_seed(void);
+
 efi_status_t check_platform_features(void);
 
 void *get_efi_config_table(efi_guid_t guid);
diff --git a/kernel/drivers/firmware/efi/libstub/random.c b/kernel/drivers/firmware/efi/libstub/random.c
index 33ab567..f85d2c0 100644
--- a/kernel/drivers/firmware/efi/libstub/random.c
+++ b/kernel/drivers/firmware/efi/libstub/random.c
@@ -67,8 +67,9 @@
 	efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
 	efi_guid_t rng_algo_raw = EFI_RNG_ALGORITHM_RAW;
 	efi_guid_t rng_table_guid = LINUX_EFI_RANDOM_SEED_TABLE_GUID;
+	struct linux_efi_random_seed *prev_seed, *seed = NULL;
+	int prev_seed_size = 0, seed_size = EFI_RANDOM_SEED_SIZE;
 	efi_rng_protocol_t *rng = NULL;
-	struct linux_efi_random_seed *seed = NULL;
 	efi_status_t status;
 
 	status = efi_bs_call(locate_protocol, &rng_proto, NULL, (void **)&rng);
@@ -76,18 +77,33 @@
 		return status;
 
 	/*
+	 * Check whether a seed was provided by a prior boot stage. In that
+	 * case, instead of overwriting it, let's create a new buffer that can
+	 * hold both, and concatenate the existing and the new seeds.
+	 * Note that we should read the seed size with caution, in case the
+	 * table got corrupted in memory somehow.
+	 */
+	prev_seed = get_efi_config_table(LINUX_EFI_RANDOM_SEED_TABLE_GUID);
+	if (prev_seed && prev_seed->size <= 512U) {
+		prev_seed_size = prev_seed->size;
+		seed_size += prev_seed_size;
+	}
+
+	/*
 	 * Use EFI_ACPI_RECLAIM_MEMORY here so that it is guaranteed that the
 	 * allocation will survive a kexec reboot (although we refresh the seed
 	 * beforehand)
 	 */
 	status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY,
-			     sizeof(*seed) + EFI_RANDOM_SEED_SIZE,
+			     struct_size(seed, bits, seed_size),
 			     (void **)&seed);
-	if (status != EFI_SUCCESS)
-		return status;
+	if (status != EFI_SUCCESS) {
+		efi_warn("Failed to allocate memory for RNG seed.\n");
+		goto err_warn;
+	}
 
 	status = efi_call_proto(rng, get_rng, &rng_algo_raw,
-				 EFI_RANDOM_SEED_SIZE, seed->bits);
+				EFI_RANDOM_SEED_SIZE, seed->bits);
 
 	if (status == EFI_UNSUPPORTED)
 		/*
@@ -100,14 +116,28 @@
 	if (status != EFI_SUCCESS)
 		goto err_freepool;
 
-	seed->size = EFI_RANDOM_SEED_SIZE;
+	seed->size = seed_size;
+	if (prev_seed_size)
+		memcpy(seed->bits + EFI_RANDOM_SEED_SIZE, prev_seed->bits,
+		       prev_seed_size);
+
 	status = efi_bs_call(install_configuration_table, &rng_table_guid, seed);
 	if (status != EFI_SUCCESS)
 		goto err_freepool;
 
+	if (prev_seed_size) {
+		/* wipe and free the old seed if we managed to install the new one */
+		memzero_explicit(prev_seed->bits, prev_seed_size);
+		efi_bs_call(free_pool, prev_seed);
+	}
 	return EFI_SUCCESS;
 
 err_freepool:
+	memzero_explicit(seed, struct_size(seed, bits, seed_size));
 	efi_bs_call(free_pool, seed);
+	efi_warn("Failed to obtain seed from EFI_RNG_PROTOCOL\n");
+err_warn:
+	if (prev_seed)
+		efi_warn("Retaining bootloader-supplied seed only");
 	return status;
 }
diff --git a/kernel/drivers/firmware/efi/libstub/x86-stub.c b/kernel/drivers/firmware/efi/libstub/x86-stub.c
index 5d0f1b1..9f998e6 100644
--- a/kernel/drivers/firmware/efi/libstub/x86-stub.c
+++ b/kernel/drivers/firmware/efi/libstub/x86-stub.c
@@ -60,7 +60,7 @@
 	rom->data.type	= SETUP_PCI;
 	rom->data.len	= size - sizeof(struct setup_data);
 	rom->data.next	= 0;
-	rom->pcilen	= pci->romsize;
+	rom->pcilen	= romsize;
 	*__rom = rom;
 
 	status = efi_call_proto(pci, pci.read, EfiPciIoWidthUint16,
diff --git a/kernel/drivers/firmware/efi/memattr.c b/kernel/drivers/firmware/efi/memattr.c
index 0a9aba5..f178b29 100644
--- a/kernel/drivers/firmware/efi/memattr.c
+++ b/kernel/drivers/firmware/efi/memattr.c
@@ -33,7 +33,7 @@
 		return -ENOMEM;
 	}
 
-	if (tbl->version > 1) {
+	if (tbl->version > 2) {
 		pr_warn("Unexpected EFI Memory Attributes table version %d\n",
 			tbl->version);
 		goto unmap;
diff --git a/kernel/drivers/firmware/efi/runtime-wrappers.c b/kernel/drivers/firmware/efi/runtime-wrappers.c
index f3e54f6..60075e0 100644
--- a/kernel/drivers/firmware/efi/runtime-wrappers.c
+++ b/kernel/drivers/firmware/efi/runtime-wrappers.c
@@ -62,6 +62,7 @@
 									\
 	if (!efi_enabled(EFI_RUNTIME_SERVICES)) {			\
 		pr_warn_once("EFI Runtime Services are disabled!\n");	\
+		efi_rts_work.status = EFI_DEVICE_ERROR;			\
 		goto exit;						\
 	}								\
 									\
diff --git a/kernel/drivers/firmware/google/framebuffer-coreboot.c b/kernel/drivers/firmware/google/framebuffer-coreboot.c
index 916f26a..922c079 100644
--- a/kernel/drivers/firmware/google/framebuffer-coreboot.c
+++ b/kernel/drivers/firmware/google/framebuffer-coreboot.c
@@ -43,9 +43,7 @@
 		    fb->green_mask_pos     == formats[i].green.offset &&
 		    fb->green_mask_size    == formats[i].green.length &&
 		    fb->blue_mask_pos      == formats[i].blue.offset &&
-		    fb->blue_mask_size     == formats[i].blue.length &&
-		    fb->reserved_mask_pos  == formats[i].transp.offset &&
-		    fb->reserved_mask_size == formats[i].transp.length)
+		    fb->blue_mask_size     == formats[i].blue.length)
 			pdata.format = formats[i].name;
 	}
 	if (!pdata.format)
diff --git a/kernel/drivers/firmware/google/gsmi.c b/kernel/drivers/firmware/google/gsmi.c
index c1cd5ca..407cac7 100644
--- a/kernel/drivers/firmware/google/gsmi.c
+++ b/kernel/drivers/firmware/google/gsmi.c
@@ -360,9 +360,10 @@
 		memcpy(data, gsmi_dev.data_buf->start, *data_size);
 
 		/* All variables are have the following attributes */
-		*attr = EFI_VARIABLE_NON_VOLATILE |
-			EFI_VARIABLE_BOOTSERVICE_ACCESS |
-			EFI_VARIABLE_RUNTIME_ACCESS;
+		if (attr)
+			*attr = EFI_VARIABLE_NON_VOLATILE |
+				EFI_VARIABLE_BOOTSERVICE_ACCESS |
+				EFI_VARIABLE_RUNTIME_ACCESS;
 	}
 
 	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
diff --git a/kernel/drivers/firmware/meson/meson_sm.c b/kernel/drivers/firmware/meson/meson_sm.c
index 77aa5c6..d081a63 100644
--- a/kernel/drivers/firmware/meson/meson_sm.c
+++ b/kernel/drivers/firmware/meson/meson_sm.c
@@ -292,6 +292,8 @@
 		return -ENOMEM;
 
 	chip = of_match_device(meson_sm_ids, dev)->data;
+	if (!chip)
+		return -EINVAL;
 
 	if (chip->cmd_shmem_in_base) {
 		fw->sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base,
diff --git a/kernel/drivers/firmware/qcom_scm.c b/kernel/drivers/firmware/qcom_scm.c
index d3a1d4c..2619eb3 100644
--- a/kernel/drivers/firmware/qcom_scm.c
+++ b/kernel/drivers/firmware/qcom_scm.c
@@ -1262,8 +1262,7 @@
 static void qcom_scm_shutdown(struct platform_device *pdev)
 {
 	/* Clean shutdown, disable download mode to allow normal restart */
-	if (download_mode)
-		qcom_scm_set_download_mode(false);
+	qcom_scm_set_download_mode(false);
 }
 
 static const struct of_device_id qcom_scm_dt_match[] = {
diff --git a/kernel/drivers/firmware/raspberrypi.c b/kernel/drivers/firmware/raspberrypi.c
index 1d965c1..45ff03d 100644
--- a/kernel/drivers/firmware/raspberrypi.c
+++ b/kernel/drivers/firmware/raspberrypi.c
@@ -243,6 +243,13 @@
 }
 EXPORT_SYMBOL_GPL(rpi_firmware_put);
 
+static void devm_rpi_firmware_put(void *data)
+{
+	struct rpi_firmware *fw = data;
+
+	rpi_firmware_put(fw);
+}
+
 static int rpi_firmware_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -265,6 +272,7 @@
 		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;
 	}
 
@@ -337,6 +345,28 @@
 }
 EXPORT_SYMBOL_GPL(rpi_firmware_get);
 
+/**
+ * devm_rpi_firmware_get - Get pointer to rpi_firmware structure.
+ * @firmware_node:    Pointer to the firmware Device Tree node.
+ *
+ * Returns NULL is the firmware device is not ready.
+ */
+struct rpi_firmware *devm_rpi_firmware_get(struct device *dev,
+					   struct device_node *firmware_node)
+{
+	struct rpi_firmware *fw;
+
+	fw = rpi_firmware_get(firmware_node);
+	if (!fw)
+		return NULL;
+
+	if (devm_add_action_or_reset(dev, devm_rpi_firmware_put, fw))
+		return NULL;
+
+	return fw;
+}
+EXPORT_SYMBOL_GPL(devm_rpi_firmware_get);
+
 static const struct of_device_id rpi_firmware_of_match[] = {
 	{ .compatible = "raspberrypi,bcm2835-firmware", },
 	{},
diff --git a/kernel/drivers/firmware/rockchip_sip.c b/kernel/drivers/firmware/rockchip_sip.c
index 99f3d2c..e483899 100644
--- a/kernel/drivers/firmware/rockchip_sip.c
+++ b/kernel/drivers/firmware/rockchip_sip.c
@@ -283,6 +283,33 @@
 }
 EXPORT_SYMBOL_GPL(sip_smc_get_amp_info);
 
+struct arm_smccc_res sip_smc_get_pvtpll_info(u32 sub_func_id, u32 arg1)
+{
+	struct arm_smccc_res res;
+
+	/*
+	 * res.a0: error code(0: success, !0: error).
+	 * res.a1: low temp config flag(0: support, !0: don't support).
+	 */
+	arm_smccc_smc(SIP_PVTPLL_CFG, sub_func_id, arg1, 0, 0, 0, 0, 0, &res);
+	return res;
+}
+EXPORT_SYMBOL_GPL(sip_smc_get_pvtpll_info);
+
+struct arm_smccc_res sip_smc_pvtpll_config(u32 sub_func_id, u32 arg1, u32 arg2,
+					   u32 arg3, u32 arg4, u32 arg5, u32 arg6)
+{
+	struct arm_smccc_res res;
+
+	/*
+	 * res.a0: error code(0: success, !0: error).
+	 */
+	arm_smccc_smc(SIP_PVTPLL_CFG, sub_func_id, arg1, arg2, arg3, arg4, arg5,
+		      arg6, &res);
+	return res;
+}
+EXPORT_SYMBOL_GPL(sip_smc_pvtpll_config);
+
 void __iomem *sip_hdcp_request_share_memory(int id)
 {
 	static void __iomem *base;
diff --git a/kernel/drivers/firmware/stratix10-svc.c b/kernel/drivers/firmware/stratix10-svc.c
index 7dd0ac1..cd0f12b 100644
--- a/kernel/drivers/firmware/stratix10-svc.c
+++ b/kernel/drivers/firmware/stratix10-svc.c
@@ -622,8 +622,8 @@
 	end = rounddown(sh_memory->addr + sh_memory->size, PAGE_SIZE);
 	paddr = begin;
 	size = end - begin;
-	va = memremap(paddr, size, MEMREMAP_WC);
-	if (!va) {
+	va = devm_memremap(dev, paddr, size, MEMREMAP_WC);
+	if (IS_ERR(va)) {
 		dev_err(dev, "fail to remap shared memory\n");
 		return ERR_PTR(-EINVAL);
 	}
@@ -989,8 +989,8 @@
 		return ret;
 
 	genpool = svc_create_memory_pool(pdev, sh_memory);
-	if (!genpool)
-		return -ENOMEM;
+	if (IS_ERR(genpool))
+		return PTR_ERR(genpool);
 
 	/* allocate service controller and supporting channel */
 	controller = devm_kzalloc(dev, sizeof(*controller), GFP_KERNEL);
diff --git a/kernel/drivers/firmware/tegra/bpmp-debugfs.c b/kernel/drivers/firmware/tegra/bpmp-debugfs.c
index 286fe12..fbc0d66 100644
--- a/kernel/drivers/firmware/tegra/bpmp-debugfs.c
+++ b/kernel/drivers/firmware/tegra/bpmp-debugfs.c
@@ -77,13 +77,14 @@
 	const char *root_path, *filename = NULL;
 	char *root_path_buf;
 	size_t root_len;
+	size_t root_path_buf_len = 512;
 
-	root_path_buf = kzalloc(512, GFP_KERNEL);
+	root_path_buf = kzalloc(root_path_buf_len, GFP_KERNEL);
 	if (!root_path_buf)
 		goto out;
 
 	root_path = dentry_path(bpmp->debugfs_mirror, root_path_buf,
-				sizeof(root_path_buf));
+				root_path_buf_len);
 	if (IS_ERR(root_path))
 		goto out;
 
diff --git a/kernel/drivers/firmware/xilinx/zynqmp.c b/kernel/drivers/firmware/xilinx/zynqmp.c
index 9e65045..300ba29 100644
--- a/kernel/drivers/firmware/xilinx/zynqmp.c
+++ b/kernel/drivers/firmware/xilinx/zynqmp.c
@@ -171,7 +171,7 @@
 	}
 
 	/* Add new entry if not present */
-	feature_data = kmalloc(sizeof(*feature_data), GFP_KERNEL);
+	feature_data = kmalloc(sizeof(*feature_data), GFP_ATOMIC);
 	if (!feature_data)
 		return -ENOMEM;
 
diff --git a/kernel/drivers/fpga/fpga-bridge.c b/kernel/drivers/fpga/fpga-bridge.c
index 2deccac..851debe 100644
--- a/kernel/drivers/fpga/fpga-bridge.c
+++ b/kernel/drivers/fpga/fpga-bridge.c
@@ -115,7 +115,7 @@
 /**
  * fpga_bridge_get - get an exclusive reference to a fpga bridge
  * @dev:	parent device that fpga bridge was registered with
- * @info:	fpga manager info
+ * @info:	fpga image specific information
  *
  * Given a device, get an exclusive reference to a fpga bridge.
  *
diff --git a/kernel/drivers/fpga/stratix10-soc.c b/kernel/drivers/fpga/stratix10-soc.c
index 9e34bbb..7a8269b 100644
--- a/kernel/drivers/fpga/stratix10-soc.c
+++ b/kernel/drivers/fpga/stratix10-soc.c
@@ -213,9 +213,9 @@
 	/* Allocate buffers from the service layer's pool. */
 	for (i = 0; i < NUM_SVC_BUFS; i++) {
 		kbuf = stratix10_svc_allocate_memory(priv->chan, SVC_BUF_SIZE);
-		if (!kbuf) {
+		if (IS_ERR(kbuf)) {
 			s10_free_buffers(mgr);
-			ret = -ENOMEM;
+			ret = PTR_ERR(kbuf);
 			goto init_done;
 		}
 
diff --git a/kernel/drivers/fsi/fsi-master-aspeed.c b/kernel/drivers/fsi/fsi-master-aspeed.c
index 87edc77..db0519d 100644
--- a/kernel/drivers/fsi/fsi-master-aspeed.c
+++ b/kernel/drivers/fsi/fsi-master-aspeed.c
@@ -445,6 +445,8 @@
 	gpiod_set_value(aspeed->cfam_reset_gpio, 1);
 	usleep_range(900, 1000);
 	gpiod_set_value(aspeed->cfam_reset_gpio, 0);
+	usleep_range(900, 1000);
+	opb_writel(aspeed, ctrl_base + FSI_MRESP0, cpu_to_be32(FSI_MRESP_RST_ALL_MASTER));
 	mutex_unlock(&aspeed->lock);
 
 	return count;
diff --git a/kernel/drivers/fsi/fsi-master-ast-cf.c b/kernel/drivers/fsi/fsi-master-ast-cf.c
index 70c03e3..42f9080 100644
--- a/kernel/drivers/fsi/fsi-master-ast-cf.c
+++ b/kernel/drivers/fsi/fsi-master-ast-cf.c
@@ -1440,3 +1440,4 @@
 
 module_platform_driver(fsi_master_acf);
 MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(FW_FILE_NAME);
diff --git a/kernel/drivers/fsi/fsi-sbefifo.c b/kernel/drivers/fsi/fsi-sbefifo.c
index 84cb965..97045a8 100644
--- a/kernel/drivers/fsi/fsi-sbefifo.c
+++ b/kernel/drivers/fsi/fsi-sbefifo.c
@@ -640,7 +640,7 @@
 	}
         ffdc_iov.iov_base = ffdc;
 	ffdc_iov.iov_len = SBEFIFO_MAX_FFDC_SIZE;
-        iov_iter_kvec(&ffdc_iter, WRITE, &ffdc_iov, 1, SBEFIFO_MAX_FFDC_SIZE);
+        iov_iter_kvec(&ffdc_iter, READ, &ffdc_iov, 1, SBEFIFO_MAX_FFDC_SIZE);
 	cmd[0] = cpu_to_be32(2);
 	cmd[1] = cpu_to_be32(SBEFIFO_CMD_GET_SBE_FFDC);
 	rc = sbefifo_do_command(sbefifo, cmd, 2, &ffdc_iter);
@@ -737,7 +737,7 @@
 	rbytes = (*resp_len) * sizeof(__be32);
 	resp_iov.iov_base = response;
 	resp_iov.iov_len = rbytes;
-        iov_iter_kvec(&resp_iter, WRITE, &resp_iov, 1, rbytes);
+        iov_iter_kvec(&resp_iter, READ, &resp_iov, 1, rbytes);
 
 	/* Perform the command */
 	mutex_lock(&sbefifo->lock);
@@ -817,7 +817,7 @@
 	/* Prepare iov iterator */
 	resp_iov.iov_base = buf;
 	resp_iov.iov_len = len;
-	iov_iter_init(&resp_iter, WRITE, &resp_iov, 1, len);
+	iov_iter_init(&resp_iter, READ, &resp_iov, 1, len);
 
 	/* Perform the command */
 	mutex_lock(&sbefifo->lock);
diff --git a/kernel/drivers/gpio/Kconfig b/kernel/drivers/gpio/Kconfig
index 9c5778b..a937d2b 100644
--- a/kernel/drivers/gpio/Kconfig
+++ b/kernel/drivers/gpio/Kconfig
@@ -99,7 +99,7 @@
 	tristate
 
 config GPIO_REGMAP
-	depends on REGMAP
+	select REGMAP
 	tristate
 
 # put drivers in the right section, in alphabetical order
diff --git a/kernel/drivers/gpio/gpio-aspeed.c b/kernel/drivers/gpio/gpio-aspeed.c
index e0d5d80..bbd04a6 100644
--- a/kernel/drivers/gpio/gpio-aspeed.c
+++ b/kernel/drivers/gpio/gpio-aspeed.c
@@ -966,7 +966,7 @@
 	else if (param == PIN_CONFIG_BIAS_DISABLE ||
 			param == PIN_CONFIG_BIAS_PULL_DOWN ||
 			param == PIN_CONFIG_DRIVE_STRENGTH)
-		return pinctrl_gpio_set_config(offset, config);
+		return pinctrl_gpio_set_config(chip->base + offset, config);
 	else if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN ||
 			param == PIN_CONFIG_DRIVE_OPEN_SOURCE)
 		/* Return -ENOTSUPP to trigger emulation, as per datasheet */
diff --git a/kernel/drivers/gpio/gpio-davinci.c b/kernel/drivers/gpio/gpio-davinci.c
index 6f21385..80597e9 100644
--- a/kernel/drivers/gpio/gpio-davinci.c
+++ b/kernel/drivers/gpio/gpio-davinci.c
@@ -326,7 +326,7 @@
 	.irq_enable	= gpio_irq_enable,
 	.irq_disable	= gpio_irq_disable,
 	.irq_set_type	= gpio_irq_type,
-	.flags		= IRQCHIP_SET_TYPE_MASKED,
+	.flags		= IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE,
 };
 
 static void gpio_irq_handler(struct irq_desc *desc)
diff --git a/kernel/drivers/gpio/gpio-mockup.c b/kernel/drivers/gpio/gpio-mockup.c
index 876027f..e20b604 100644
--- a/kernel/drivers/gpio/gpio-mockup.c
+++ b/kernel/drivers/gpio/gpio-mockup.c
@@ -370,7 +370,7 @@
 		priv->offset = i;
 		priv->desc = &gc->gpiodev->descs[i];
 
-		debugfs_create_file(name, 0200, chip->dbg_dir, priv,
+		debugfs_create_file(name, 0600, chip->dbg_dir, priv,
 				    &gpio_mockup_debugfs_ops);
 	}
 }
diff --git a/kernel/drivers/gpio/gpio-mxc.c b/kernel/drivers/gpio/gpio-mxc.c
index ba6ed2a..0d5a9fe 100644
--- a/kernel/drivers/gpio/gpio-mxc.c
+++ b/kernel/drivers/gpio/gpio-mxc.c
@@ -231,7 +231,7 @@
 
 	writel(1 << gpio_idx, port->base + GPIO_ISR);
 
-	return 0;
+	return port->gc.direction_input(&port->gc, gpio_idx);
 }
 
 static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
diff --git a/kernel/drivers/gpio/gpio-pmic-eic-sprd.c b/kernel/drivers/gpio/gpio-pmic-eic-sprd.c
index 9382851..e969ce9 100644
--- a/kernel/drivers/gpio/gpio-pmic-eic-sprd.c
+++ b/kernel/drivers/gpio/gpio-pmic-eic-sprd.c
@@ -338,6 +338,7 @@
 	pmic_eic->chip.set_config = sprd_pmic_eic_set_config;
 	pmic_eic->chip.set = sprd_pmic_eic_set;
 	pmic_eic->chip.get = sprd_pmic_eic_get;
+	pmic_eic->chip.can_sleep = true;
 
 	pmic_eic->intc.name = dev_name(&pdev->dev);
 	pmic_eic->intc.irq_mask = sprd_pmic_eic_irq_mask;
diff --git a/kernel/drivers/gpio/gpio-pxa.c b/kernel/drivers/gpio/gpio-pxa.c
index 0cb6600..1dbeaf6 100644
--- a/kernel/drivers/gpio/gpio-pxa.c
+++ b/kernel/drivers/gpio/gpio-pxa.c
@@ -243,6 +243,7 @@
 	switch (gpio_type) {
 	case PXA3XX_GPIO:
 	case MMP2_GPIO:
+	case MMP_GPIO:
 		return false;
 
 	default:
diff --git a/kernel/drivers/gpio/gpio-sifive.c b/kernel/drivers/gpio/gpio-sifive.c
index 4f28fa7..a42ffb9 100644
--- a/kernel/drivers/gpio/gpio-sifive.c
+++ b/kernel/drivers/gpio/gpio-sifive.c
@@ -195,6 +195,7 @@
 		return -ENODEV;
 	}
 	parent = irq_find_host(irq_parent);
+	of_node_put(irq_parent);
 	if (!parent) {
 		dev_err(dev, "no IRQ parent domain\n");
 		return -ENODEV;
diff --git a/kernel/drivers/gpio/gpio-tb10x.c b/kernel/drivers/gpio/gpio-tb10x.c
index 866201c..4a9dcaa 100644
--- a/kernel/drivers/gpio/gpio-tb10x.c
+++ b/kernel/drivers/gpio/gpio-tb10x.c
@@ -195,7 +195,7 @@
 				handle_edge_irq, IRQ_NOREQUEST, IRQ_NOPROBE,
 				IRQ_GC_INIT_MASK_CACHE);
 		if (ret)
-			return ret;
+			goto err_remove_domain;
 
 		gc = tb10x_gpio->domain->gc->gc[0];
 		gc->reg_base                         = tb10x_gpio->base;
@@ -209,6 +209,10 @@
 	}
 
 	return 0;
+
+err_remove_domain:
+	irq_domain_remove(tb10x_gpio->domain);
+	return ret;
 }
 
 static int tb10x_gpio_remove(struct platform_device *pdev)
diff --git a/kernel/drivers/gpio/gpio-tps68470.c b/kernel/drivers/gpio/gpio-tps68470.c
index f7f5f77..e19eb7c 100644
--- a/kernel/drivers/gpio/gpio-tps68470.c
+++ b/kernel/drivers/gpio/gpio-tps68470.c
@@ -91,12 +91,12 @@
 	struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc);
 	struct regmap *regmap = tps68470_gpio->tps68470_regmap;
 
+	/* Set the initial value */
+	tps68470_gpio_set(gc, offset, value);
+
 	/* rest are always outputs */
 	if (offset >= TPS68470_N_REGULAR_GPIO)
 		return 0;
-
-	/* Set the initial value */
-	tps68470_gpio_set(gc, offset, value);
 
 	return regmap_update_bits(regmap, TPS68470_GPIO_CTL_REG_A(offset),
 				 TPS68470_GPIO_MODE_MASK,
diff --git a/kernel/drivers/gpio/gpio-vf610.c b/kernel/drivers/gpio/gpio-vf610.c
index 1ae612c..396a687 100644
--- a/kernel/drivers/gpio/gpio-vf610.c
+++ b/kernel/drivers/gpio/gpio-vf610.c
@@ -304,7 +304,7 @@
 	gc = &port->gc;
 	gc->of_node = np;
 	gc->parent = dev;
-	gc->label = "vf610-gpio";
+	gc->label = dev_name(dev);
 	gc->ngpio = VF610_GPIO_PER_PORT;
 	gc->base = of_alias_get_id(np, "gpio") * VF610_GPIO_PER_PORT;
 
diff --git a/kernel/drivers/gpio/gpiolib-cdev.c b/kernel/drivers/gpio/gpiolib-cdev.c
index 381cfa2..40d0196 100644
--- a/kernel/drivers/gpio/gpiolib-cdev.c
+++ b/kernel/drivers/gpio/gpiolib-cdev.c
@@ -197,16 +197,18 @@
 	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);
+	if (!lh->gdev->chip)
+		return -ENODEV;
+
+	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 +220,7 @@
 			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 +242,11 @@
 						     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 +1168,19 @@
 	struct linereq *lr = file->private_data;
 	void __user *ip = (void __user *)arg;
 
-	if (cmd == GPIO_V2_LINE_GET_VALUES_IOCTL)
-		return linereq_get_values(lr, ip);
-	else if (cmd == GPIO_V2_LINE_SET_VALUES_IOCTL)
-		return linereq_set_values(lr, ip);
-	else if (cmd == GPIO_V2_LINE_SET_CONFIG_IOCTL)
-		return linereq_set_config(lr, ip);
+	if (!lr->gdev->chip)
+		return -ENODEV;
 
-	return -EINVAL;
+	switch (cmd) {
+	case GPIO_V2_LINE_GET_VALUES_IOCTL:
+		return linereq_get_values(lr, ip);
+	case GPIO_V2_LINE_SET_VALUES_IOCTL:
+		return linereq_set_values(lr, ip);
+	case GPIO_V2_LINE_SET_CONFIG_IOCTL:
+		return linereq_set_config(lr, ip);
+	default:
+		return -EINVAL;
+	}
 }
 
 #ifdef CONFIG_COMPAT
@@ -1188,6 +1196,9 @@
 {
 	struct linereq *lr = file->private_data;
 	__poll_t events = 0;
+
+	if (!lr->gdev->chip)
+		return EPOLLHUP | EPOLLERR;
 
 	poll_wait(file, &lr->wait, wait);
 
@@ -1207,6 +1218,9 @@
 	struct gpio_v2_line_event le;
 	ssize_t bytes_read = 0;
 	int ret;
+
+	if (!lr->gdev->chip)
+		return -ENODEV;
 
 	if (count < sizeof(le))
 		return -EINVAL;
@@ -1473,6 +1487,9 @@
 	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))
@@ -1507,6 +1524,9 @@
 	ssize_t bytes_read = 0;
 	ssize_t ge_size;
 	int ret;
+
+	if (!le->gdev->chip)
+		return -ENODEV;
 
 	/*
 	 * When compatible system call is being used the struct gpioevent_data,
@@ -1585,6 +1605,9 @@
 	struct lineevent_state *le = file->private_data;
 	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,
@@ -2095,28 +2118,30 @@
 		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
@@ -2164,6 +2189,9 @@
 	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,
@@ -2182,6 +2210,9 @@
 	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)
diff --git a/kernel/drivers/gpio/gpiolib.c b/kernel/drivers/gpio/gpiolib.c
index 2c50f8a..e885218 100644
--- a/kernel/drivers/gpio/gpiolib.c
+++ b/kernel/drivers/gpio/gpiolib.c
@@ -190,9 +190,8 @@
 		/* 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)) {
@@ -2482,8 +2481,7 @@
 			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;
@@ -2657,9 +2655,9 @@
 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) {
diff --git a/kernel/drivers/gpu/arm/bifrost/csf/mali_kbase_csf_kcpu.c b/kernel/drivers/gpu/arm/bifrost/csf/mali_kbase_csf_kcpu.c
index 2b4d4a4..da8dde2 100644
--- a/kernel/drivers/gpu/arm/bifrost/csf/mali_kbase_csf_kcpu.c
+++ b/kernel/drivers/gpu/arm/bifrost/csf/mali_kbase_csf_kcpu.c
@@ -1604,6 +1604,10 @@
 	if (!kcpu_fence)
 		return -ENOMEM;
 
+	/* Set reference to KCPU metadata and increment refcount */
+	kcpu_fence->metadata = kcpu_queue->metadata;
+	WARN_ON(!kbase_refcount_inc_not_zero(&kcpu_fence->metadata->refcount));
+
 #if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE)
 	fence_out = (struct fence *)kcpu_fence;
 #else
@@ -1624,10 +1628,6 @@
 	 */
 	dma_fence_get(fence_out);
 #endif
-
-	/* Set reference to KCPU metadata and increment refcount */
-	kcpu_fence->metadata = kcpu_queue->metadata;
-	WARN_ON(!kbase_refcount_inc_not_zero(&kcpu_fence->metadata->refcount));
 
 	/* create a sync_file fd representing the fence */
 	*sync_file = sync_file_create(fence_out);
diff --git a/kernel/drivers/gpu/arm/bifrost/device/mali_kbase_device.c b/kernel/drivers/gpu/arm/bifrost/device/mali_kbase_device.c
index 77093b9..b2b0cfd 100644
--- a/kernel/drivers/gpu/arm/bifrost/device/mali_kbase_device.c
+++ b/kernel/drivers/gpu/arm/bifrost/device/mali_kbase_device.c
@@ -194,16 +194,22 @@
 	list_for_each_entry(kctx, &kbdev->kctx_list, kctx_list_link) {
 		struct pid *pid_struct;
 		struct task_struct *task;
+		struct pid *tgid_struct;
+		struct task_struct *tgid_task;
+
 		unsigned long task_alloc_total =
 			KBASE_PAGES_TO_KIB(atomic_read(&(kctx->used_pages)));
 
 		rcu_read_lock();
 		pid_struct = find_get_pid(kctx->pid);
 		task = pid_task(pid_struct, PIDTYPE_PID);
+		tgid_struct = find_get_pid(kctx->tgid);
+		tgid_task = pid_task(tgid_struct, PIDTYPE_PID);
 
 		dev_err(kbdev->dev,
-			"OOM notifier: tsk %s  tgid (%u)  pid (%u) %lu kB\n",
-			task ? task->comm : "[null task]", kctx->tgid,
+			"OOM notifier: tsk %s:%s  tgid (%u)  pid (%u) %lu kB\n",
+			tgid_task ? tgid_task->comm : "[null task]",
+			task ? task->comm : "[null comm]", kctx->tgid,
 			kctx->pid, task_alloc_total);
 
 		put_pid(pid_struct);
diff --git a/kernel/drivers/gpu/arm/bifrost/mali_kbase_gpu_memory_debugfs.c b/kernel/drivers/gpu/arm/bifrost/mali_kbase_gpu_memory_debugfs.c
index b02a32c..bf5f259 100644
--- a/kernel/drivers/gpu/arm/bifrost/mali_kbase_gpu_memory_debugfs.c
+++ b/kernel/drivers/gpu/arm/bifrost/mali_kbase_gpu_memory_debugfs.c
@@ -48,18 +48,30 @@
 
 		kbdev = list_entry(entry, struct kbase_device, entry);
 		/* output the total memory usage and cap for this device */
+		seq_printf(sfile, "<dev>                <pages>\n");
 		seq_printf(sfile, "%-16s  %10u\n",
 				kbdev->devname,
 				atomic_read(&(kbdev->memdev.used_pages)));
 		mutex_lock(&kbdev->kctx_list_lock);
+		seq_printf(sfile, "  <kctx>                  <comm>               <pid>         <pages>\n");
 		list_for_each_entry(kctx, &kbdev->kctx_list, kctx_list_link) {
+			struct pid *pid_struct;
+			struct task_struct *task;
+
+			rcu_read_lock();
+			pid_struct = find_get_pid(kctx->tgid);
+			task = pid_task(pid_struct, PIDTYPE_PID);
 			/* output the memory usage and cap for each kctx
 			 * opened on this device
 			 */
-			seq_printf(sfile, "  %s-0x%pK %10u\n",
+			seq_printf(sfile, "  %s-0x%pK %-20s %-10d %10u\n",
 				"kctx",
 				kctx,
+				task ? task->comm : "[null comm]",
+				kctx->tgid,
 				atomic_read(&(kctx->used_pages)));
+			put_pid(pid_struct);
+			rcu_read_unlock();
 		}
 		mutex_unlock(&kbdev->kctx_list_lock);
 	}
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
index 6333cad..4b568ee 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
@@ -313,6 +313,7 @@
 
 	if (!found)
 		return false;
+	pci_dev_put(pdev);
 
 	adev->bios = kmalloc(size, GFP_KERNEL);
 	if (!adev->bios) {
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index ffd8f56..7f2adac 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -45,7 +45,6 @@
 	struct drm_gem_object *gobj;
 	struct amdgpu_bo *bo;
 	unsigned long size;
-	int r;
 
 	gobj = drm_gem_object_lookup(p->filp, data->handle);
 	if (gobj == NULL)
@@ -60,23 +59,14 @@
 	drm_gem_object_put(gobj);
 
 	size = amdgpu_bo_size(bo);
-	if (size != PAGE_SIZE || (data->offset + 8) > size) {
-		r = -EINVAL;
-		goto error_unref;
-	}
+	if (size != PAGE_SIZE || data->offset > (size - 8))
+		return -EINVAL;
 
-	if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) {
-		r = -EINVAL;
-		goto error_unref;
-	}
+	if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm))
+		return -EINVAL;
 
 	*offset = data->offset;
-
 	return 0;
-
-error_unref:
-	amdgpu_bo_unref(&bo);
-	return r;
 }
 
 static int amdgpu_cs_bo_handles_chunk(struct amdgpu_cs_parser *p,
@@ -1517,15 +1507,15 @@
 			continue;
 
 		r = dma_fence_wait_timeout(fence, true, timeout);
+		if (r > 0 && fence->error)
+			r = fence->error;
+
 		dma_fence_put(fence);
 		if (r < 0)
 			return r;
 
 		if (r == 0)
 			break;
-
-		if (fence->error)
-			return fence->error;
 	}
 
 	memset(wait, 0, sizeof(*wait));
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index bde0496..f0db972 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1091,6 +1091,9 @@
 	u16 cmd;
 	int r;
 
+	if (!IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT))
+		return 0;
+
 	/* Bypass for VF */
 	if (amdgpu_sriov_vf(adev))
 		return 0;
@@ -4443,6 +4446,8 @@
 		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 +4486,7 @@
 
 		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 +4494,7 @@
 
 	pm_runtime_disable(&(p->dev));
 
+	pci_dev_put(p);
 	return 0;
 }
 
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 30659c1..0d8c1c3 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -1121,6 +1121,15 @@
 			 "See modparam exp_hw_support\n");
 		return -ENODEV;
 	}
+	/* differentiate between P10 and P11 asics with the same DID */
+	if (pdev->device == 0x67FF &&
+	    (pdev->revision == 0xE3 ||
+	     pdev->revision == 0xE7 ||
+	     pdev->revision == 0xF3 ||
+	     pdev->revision == 0xF7)) {
+		flags &= ~AMD_ASIC_MASK;
+		flags |= CHIP_POLARIS10;
+	}
 
 	/* Due to hardware bugs, S/G Display on raven requires a 1:1 IOMMU mapping,
 	 * however, SME requires an indirect IOMMU mapping because the encryption
@@ -1190,12 +1199,12 @@
 	ddev->pdev = pdev;
 	pci_set_drvdata(pdev, ddev);
 
-	ret = amdgpu_driver_load_kms(adev, ent->driver_data);
+	ret = amdgpu_driver_load_kms(adev, flags);
 	if (ret)
 		goto err_pci;
 
 retry_init:
-	ret = drm_dev_register(ddev, ent->driver_data);
+	ret = drm_dev_register(ddev, flags);
 	if (ret == -EAGAIN && ++retry <= 3) {
 		DRM_INFO("retry init %d\n", retry);
 		/* Don't request EX mode too frequently which is attacking */
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 917b940..93a4b52 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -505,6 +505,7 @@
 			crtc = (struct drm_crtc *)minfo->crtcs[i];
 			if (crtc && crtc->base.id == info->mode_crtc.id) {
 				struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
+
 				ui32 = amdgpu_crtc->crtc_id;
 				found = 1;
 				break;
@@ -523,7 +524,7 @@
 		if (ret)
 			return ret;
 
-		ret = copy_to_user(out, &ip, min((size_t)size, sizeof(ip)));
+		ret = copy_to_user(out, &ip, min_t(size_t, size, sizeof(ip)));
 		return ret ? -EFAULT : 0;
 	}
 	case AMDGPU_INFO_HW_IP_COUNT: {
@@ -671,17 +672,18 @@
 				    ? -EFAULT : 0;
 	}
 	case AMDGPU_INFO_READ_MMR_REG: {
-		unsigned n, alloc_size;
+		unsigned int n, alloc_size;
 		uint32_t *regs;
-		unsigned se_num = (info->read_mmr_reg.instance >>
+		unsigned int se_num = (info->read_mmr_reg.instance >>
 				   AMDGPU_INFO_MMR_SE_INDEX_SHIFT) &
 				  AMDGPU_INFO_MMR_SE_INDEX_MASK;
-		unsigned sh_num = (info->read_mmr_reg.instance >>
+		unsigned int sh_num = (info->read_mmr_reg.instance >>
 				   AMDGPU_INFO_MMR_SH_INDEX_SHIFT) &
 				  AMDGPU_INFO_MMR_SH_INDEX_MASK;
 
 		/* set full masks if the userspace set all bits
-		 * in the bitfields */
+		 * in the bitfields
+		 */
 		if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK)
 			se_num = 0xffffffff;
 		else if (se_num >= AMDGPU_GFX_MAX_SE)
@@ -799,7 +801,7 @@
 				    min((size_t)size, sizeof(dev_info))) ? -EFAULT : 0;
 	}
 	case AMDGPU_INFO_VCE_CLOCK_TABLE: {
-		unsigned i;
+		unsigned int i;
 		struct drm_amdgpu_info_vce_clock_table vce_clk_table = {};
 		struct amd_vce_state *vce_state;
 
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
index 0da0a0d..15c0a30 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
@@ -66,6 +66,7 @@
 {
 	struct fd f = fdget(fd);
 	struct amdgpu_fpriv *fpriv;
+	struct amdgpu_ctx_mgr *mgr;
 	struct amdgpu_ctx *ctx;
 	uint32_t id;
 	int r;
@@ -79,8 +80,11 @@
 		return r;
 	}
 
-	idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id)
+	mgr = &fpriv->ctx_mgr;
+	mutex_lock(&mgr->lock);
+	idr_for_each_entry(&mgr->ctx_handles, ctx, id)
 		amdgpu_ctx_priority_override(ctx, priority);
+	mutex_unlock(&mgr->lock);
 
 	fdput(f);
 	return 0;
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
index aea49ba..fbd92ff 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
@@ -62,6 +62,8 @@
 	uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE];
 };
 
+enum idh_request;
+
 /**
  * struct amdgpu_virt_ops - amdgpu device virt operations
  */
@@ -71,7 +73,8 @@
 	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);
 };
 
 /*
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 45b1f00..8445bb7 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2229,14 +2229,14 @@
 	uint64_t eaddr;
 
 	/* validate the parameters */
-	if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK ||
-	    size == 0 || size & ~PAGE_MASK)
+	if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK)
+		return -EINVAL;
+	if (saddr + size <= saddr || offset + size <= offset)
 		return -EINVAL;
 
 	/* make sure object fit at this offset */
 	eaddr = saddr + size - 1;
-	if (saddr >= eaddr ||
-	    (bo && offset + size > amdgpu_bo_size(bo)) ||
+	if ((bo && offset + size > amdgpu_bo_size(bo)) ||
 	    (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT))
 		return -EINVAL;
 
@@ -2295,14 +2295,14 @@
 	int r;
 
 	/* validate the parameters */
-	if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK ||
-	    size == 0 || size & ~PAGE_MASK)
+	if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK)
+		return -EINVAL;
+	if (saddr + size <= saddr || offset + size <= offset)
 		return -EINVAL;
 
 	/* make sure object fit at this offset */
 	eaddr = saddr + size - 1;
-	if (saddr >= eaddr ||
-	    (bo && offset + size > amdgpu_bo_size(bo)) ||
+	if ((bo && offset + size > amdgpu_bo_size(bo)) ||
 	    (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT))
 		return -EINVAL;
 
@@ -3252,6 +3252,10 @@
 	long timeout = msecs_to_jiffies(2000);
 	int r;
 
+	/* No valid flags defined yet */
+	if (args->in.flags)
+		return -EINVAL;
+
 	switch (args->in.op) {
 	case AMDGPU_VM_OP_RESERVE_VMID:
 		/* We only have requirement to reserve vmid from gfxhub */
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/cik.c b/kernel/drivers/gpu/drm/amd/amdgpu/cik.c
index 5442df0..4534649 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/cik.c
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/cik.c
@@ -1509,17 +1509,8 @@
 			u16 bridge_cfg2, gpu_cfg2;
 			u32 max_lw, current_lw, tmp;
 
-			pcie_capability_read_word(root, PCI_EXP_LNKCTL,
-						  &bridge_cfg);
-			pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL,
-						  &gpu_cfg);
-
-			tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
-			pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
-
-			tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
-			pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL,
-						   tmp16);
+			pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
+			pcie_capability_set_word(adev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
 
 			tmp = RREG32_PCIE(ixPCIE_LC_STATUS1);
 			max_lw = (tmp & PCIE_LC_STATUS1__LC_DETECTED_LINK_WIDTH_MASK) >>
@@ -1572,21 +1563,14 @@
 				msleep(100);
 
 				/* linkctl */
-				pcie_capability_read_word(root, PCI_EXP_LNKCTL,
-							  &tmp16);
-				tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
-				tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
-				pcie_capability_write_word(root, PCI_EXP_LNKCTL,
-							   tmp16);
-
-				pcie_capability_read_word(adev->pdev,
-							  PCI_EXP_LNKCTL,
-							  &tmp16);
-				tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
-				tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
-				pcie_capability_write_word(adev->pdev,
-							   PCI_EXP_LNKCTL,
-							   tmp16);
+				pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
+								   PCI_EXP_LNKCTL_HAWD,
+								   bridge_cfg &
+								   PCI_EXP_LNKCTL_HAWD);
+				pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL,
+								   PCI_EXP_LNKCTL_HAWD,
+								   gpu_cfg &
+								   PCI_EXP_LNKCTL_HAWD);
 
 				/* linkctl2 */
 				pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/kernel/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index 0e3ff5c..72410a2 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -6702,8 +6702,10 @@
 		return r;
 
 	r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
-	if (unlikely(r != 0))
+	if (unlikely(r != 0)) {
+		amdgpu_bo_unreserve(ring->mqd_obj);
 		return r;
+	}
 
 	gfx_v10_0_kiq_init_queue(ring);
 	amdgpu_bo_kunmap(ring->mqd_obj);
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/kernel/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index 38f4c74..acef222 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -3800,8 +3800,10 @@
 		return r;
 
 	r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
-	if (unlikely(r != 0))
+	if (unlikely(r != 0)) {
+		amdgpu_bo_unreserve(ring->mqd_obj);
 		return r;
+	}
 
 	gfx_v9_0_kiq_init_queue(ring);
 	amdgpu_bo_kunmap(ring->mqd_obj);
@@ -3943,7 +3945,8 @@
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-	amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0);
+	if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
+		amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0);
 	amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
 	amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
 
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/kernel/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index 1673bf3..945cbdb 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -1686,7 +1686,6 @@
 		return 0;
 	}
 
-	amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0);
 	amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0);
 
 	return 0;
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/kernel/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index 1f2e246..dbcaef3 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -1979,9 +1979,11 @@
 	if (amdgpu_sriov_vf(adev))
 		return 0;
 
-	for (i = 0; i < adev->sdma.num_instances; i++) {
-		amdgpu_irq_put(adev, &adev->sdma.ecc_irq,
-			       AMDGPU_SDMA_IRQ_INSTANCE0 + i);
+	if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__SDMA)) {
+		for (i = 0; i < adev->sdma.num_instances; i++) {
+			amdgpu_irq_put(adev, &adev->sdma.ecc_irq,
+				       AMDGPU_SDMA_IRQ_INSTANCE0 + i);
+		}
 	}
 
 	sdma_v4_0_ctx_switch_enable(adev, false);
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/si.c b/kernel/drivers/gpu/drm/amd/amdgpu/si.c
index e5e336f..b7e1201 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/si.c
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/si.c
@@ -2159,17 +2159,8 @@
 			u16 bridge_cfg2, gpu_cfg2;
 			u32 max_lw, current_lw, tmp;
 
-			pcie_capability_read_word(root, PCI_EXP_LNKCTL,
-						  &bridge_cfg);
-			pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL,
-						  &gpu_cfg);
-
-			tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
-			pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
-
-			tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
-			pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL,
-						   tmp16);
+			pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
+			pcie_capability_set_word(adev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
 
 			tmp = RREG32_PCIE(PCIE_LC_STATUS1);
 			max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
@@ -2214,21 +2205,14 @@
 
 				mdelay(100);
 
-				pcie_capability_read_word(root, PCI_EXP_LNKCTL,
-							  &tmp16);
-				tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
-				tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
-				pcie_capability_write_word(root, PCI_EXP_LNKCTL,
-							   tmp16);
-
-				pcie_capability_read_word(adev->pdev,
-							  PCI_EXP_LNKCTL,
-							  &tmp16);
-				tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
-				tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
-				pcie_capability_write_word(adev->pdev,
-							   PCI_EXP_LNKCTL,
-							   tmp16);
+				pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
+								   PCI_EXP_LNKCTL_HAWD,
+								   bridge_cfg &
+								   PCI_EXP_LNKCTL_HAWD);
+				pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL,
+								   PCI_EXP_LNKCTL_HAWD,
+								   gpu_cfg &
+								   PCI_EXP_LNKCTL_HAWD);
 
 				pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
 							  &tmp16);
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/soc15.c b/kernel/drivers/gpu/drm/amd/amdgpu/soc15.c
index 7212b99..994e663 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -382,8 +382,9 @@
 	*value = 0;
 	for (i = 0; i < ARRAY_SIZE(soc15_allowed_read_registers); i++) {
 		en = &soc15_allowed_read_registers[i];
-		if (adev->reg_offset[en->hwip][en->inst] &&
-			reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
+		if (!adev->reg_offset[en->hwip][en->inst])
+			continue;
+		else if (reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
 					+ en->reg_offset))
 			continue;
 
diff --git a/kernel/drivers/gpu/drm/amd/amdgpu/vi.c b/kernel/drivers/gpu/drm/amd/amdgpu/vi.c
index 9bcd0ee..2e030a3 100644
--- a/kernel/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/kernel/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -329,8 +329,15 @@
 	u32 reference_clock = adev->clock.spll.reference_freq;
 	u32 tmp;
 
-	if (adev->flags & AMD_IS_APU)
-		return reference_clock;
+	if (adev->flags & AMD_IS_APU) {
+		switch (adev->asic_type) {
+		case CHIP_STONEY:
+			/* vbios says 48Mhz, but the actual freq is 100Mhz */
+			return 10000;
+		default:
+			return reference_clock;
+		}
+	}
 
 	tmp = RREG32_SMC(ixCG_CLKPIN_CNTL_2);
 	if (REG_GET_FIELD(tmp, CG_CLKPIN_CNTL_2, MUX_TCLK_TO_XCLK))
diff --git a/kernel/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/kernel/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index 159be13..2c19b37 100644
--- a/kernel/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/kernel/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -528,16 +528,13 @@
 	struct kfd_event_waiter *event_waiters;
 	uint32_t i;
 
-	event_waiters = kmalloc_array(num_events,
-					sizeof(struct kfd_event_waiter),
-					GFP_KERNEL);
+	event_waiters = kcalloc(num_events, sizeof(struct kfd_event_waiter),
+				GFP_KERNEL);
 	if (!event_waiters)
 		return NULL;
 
-	for (i = 0; (event_waiters) && (i < num_events) ; i++) {
+	for (i = 0; i < num_events; i++)
 		init_wait(&event_waiters[i].wait);
-		event_waiters[i].activated = false;
-	}
 
 	return event_waiters;
 }
diff --git a/kernel/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/kernel/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
index 3b6f596..dadeb20 100644
--- a/kernel/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
+++ b/kernel/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
@@ -113,18 +113,19 @@
 			&(mqd_mem_obj->gtt_mem),
 			&(mqd_mem_obj->gpu_addr),
 			(void *)&(mqd_mem_obj->cpu_ptr), true);
+
+		if (retval) {
+			kfree(mqd_mem_obj);
+			return NULL;
+		}
 	} else {
 		retval = kfd_gtt_sa_allocate(kfd, sizeof(struct v9_mqd),
 				&mqd_mem_obj);
-	}
-
-	if (retval) {
-		kfree(mqd_mem_obj);
-		return NULL;
+		if (retval)
+			return NULL;
 	}
 
 	return mqd_mem_obj;
-
 }
 
 static void init_mqd(struct mqd_manager *mm, void **mqd,
diff --git a/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 167a1ee..652ddec 100644
--- a/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2051,12 +2051,14 @@
 	drm_for_each_connector_iter(connector, &iter) {
 		aconnector = to_amdgpu_dm_connector(connector);
 
+		if (!aconnector->dc_link)
+			continue;
+
 		/*
 		 * this is the case when traversing through already created
 		 * MST connectors, should be skipped
 		 */
-		if (aconnector->dc_link &&
-		    aconnector->dc_link->type == dc_connection_mst_branch)
+		if (aconnector->dc_link->type == dc_connection_mst_branch)
 			continue;
 
 		mutex_lock(&aconnector->hpd_lock);
@@ -4567,8 +4569,6 @@
 	timing_out->pix_clk_100hz = mode_in->crtc_clock * 10;
 	timing_out->aspect_ratio = get_aspect_ratio(mode_in);
 
-	stream->output_color_space = get_output_color_space(timing_out);
-
 	stream->out_transfer_func->type = TF_TYPE_PREDEFINED;
 	stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
 	if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) {
@@ -4579,6 +4579,8 @@
 			adjust_colour_depth_from_display_info(timing_out, info);
 		}
 	}
+
+	stream->output_color_space = get_output_color_space(timing_out);
 }
 
 static void fill_audio_info(struct audio_info *audio_info,
@@ -6969,6 +6971,13 @@
 	attributes.rotation_angle    = 0;
 	attributes.attribute_flags.value = 0;
 
+	/* Enable cursor degamma ROM on DCN3+ for implicit sRGB degamma in DRM
+	 * legacy gamma setup.
+	 */
+	if (crtc_state->cm_is_degamma_srgb &&
+	    adev->dm.dc->caps.color.dpp.gamma_corr)
+		attributes.attribute_flags.bits.ENABLE_CURSOR_DEGAMMA = 1;
+
 	attributes.pitch = attributes.width;
 
 	if (crtc_state->stream) {
@@ -7246,6 +7255,8 @@
 			continue;
 
 		dc_plane = dm_new_plane_state->dc_state;
+		if (!dc_plane)
+			continue;
 
 		bundle->surface_updates[planes_count].surface = dc_plane;
 		if (new_pcrtc_state->color_mgmt_changed) {
@@ -7426,6 +7437,12 @@
 		if (acrtc_state->abm_level != dm_old_crtc_state->abm_level)
 			bundle->stream_update.abm_level = &acrtc_state->abm_level;
 
+		mutex_lock(&dm->dc_lock);
+		if ((acrtc_state->update_type > UPDATE_TYPE_FAST) &&
+				acrtc_state->stream->link->psr_settings.psr_allow_active)
+			amdgpu_dm_psr_disable(acrtc_state->stream);
+		mutex_unlock(&dm->dc_lock);
+
 		/*
 		 * If FreeSync state on the stream has changed then we need to
 		 * re-adjust the min/max bounds now that DC doesn't handle this
@@ -7440,9 +7457,6 @@
 			spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
 		}
 		mutex_lock(&dm->dc_lock);
-		if ((acrtc_state->update_type > UPDATE_TYPE_FAST) &&
-				acrtc_state->stream->link->psr_settings.psr_allow_active)
-			amdgpu_dm_psr_disable(acrtc_state->stream);
 
 		dc_commit_updates_for_stream(dm->dc,
 						     bundle->surface_updates,
@@ -8560,8 +8574,9 @@
 			return -EINVAL;
 		}
 
+		if (dm_old_plane_state->dc_state)
+			dc_plane_state_release(dm_old_plane_state->dc_state);
 
-		dc_plane_state_release(dm_old_plane_state->dc_state);
 		dm_new_plane_state->dc_state = NULL;
 
 		*lock_and_validation_needed = true;
@@ -8783,8 +8798,8 @@
 			goto fail;
 		}
 
-		if (dm_old_con_state->abm_level !=
-		    dm_new_con_state->abm_level)
+		if (dm_old_con_state->abm_level != dm_new_con_state->abm_level ||
+		    dm_old_con_state->scaling != dm_new_con_state->scaling)
 			new_crtc_state->connectors_changed = true;
 	}
 
diff --git a/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index d617e98..767b3d3 100644
--- a/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -164,6 +164,21 @@
 	return false;
 }
 
+bool is_synaptics_cascaded_panamera(struct dc_link *link, struct drm_dp_mst_port *port)
+{
+	u8 branch_vendor_data[4] = { 0 }; // Vendor data 0x50C ~ 0x50F
+
+	if (drm_dp_dpcd_read(port->mgr->aux, DP_BRANCH_VENDOR_SPECIFIC_START, &branch_vendor_data, 4) == 4) {
+		if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
+				IS_SYNAPTICS_CASCADED_PANAMERA(link->dpcd_caps.branch_dev_name, branch_vendor_data)) {
+			DRM_INFO("Synaptics Cascaded MST hub\n");
+			return true;
+		}
+	}
+
+	return false;
+}
+
 static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnector)
 {
 	struct dc_sink *dc_sink = aconnector->dc_sink;
@@ -185,6 +200,10 @@
 	    needs_dsc_aux_workaround(aconnector->dc_link))
 		aconnector->dsc_aux = &aconnector->mst_port->dm_dp_aux.aux;
 
+	/* synaptics cascaded MST hub case */
+	if (!aconnector->dsc_aux && is_synaptics_cascaded_panamera(aconnector->dc_link, port))
+		aconnector->dsc_aux = port->mgr->aux;
+
 	if (!aconnector->dsc_aux)
 		return false;
 
diff --git a/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
index b38bd68..5d60e2b 100644
--- a/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
+++ b/kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
@@ -26,6 +26,18 @@
 #ifndef __DAL_AMDGPU_DM_MST_TYPES_H__
 #define __DAL_AMDGPU_DM_MST_TYPES_H__
 
+#define DP_BRANCH_VENDOR_SPECIFIC_START 0x50C
+
+/**
+ * Panamera MST Hub detection
+ * Offset DPCD 050Eh == 0x5A indicates cascaded MST hub case
+ * Check from beginning of branch device vendor specific field (050Ch)
+ */
+#define IS_SYNAPTICS_PANAMERA(branchDevName) (((int)branchDevName[4] & 0xF0) == 0x50 ? 1 : 0)
+#define BRANCH_HW_REVISION_PANAMERA_A2 0x10
+#define SYNAPTICS_CASCADED_HUB_ID  0x5A
+#define IS_SYNAPTICS_CASCADED_PANAMERA(devName, data) ((IS_SYNAPTICS_PANAMERA(devName) && ((int)data[2] == SYNAPTICS_CASCADED_HUB_ID)) ? 1 : 0)
+
 struct amdgpu_display_manager;
 struct amdgpu_dm_connector;
 
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/kernel/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
index 29d64e7..9dd41ea 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
@@ -352,6 +352,7 @@
 	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 @@
 			- 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
@@ -408,11 +406,8 @@
 	info->i2c_slave_address = record->i2c_slave_addr;
 
 	/* TODO: check how to get register offset for en, Y, etc. */
-	info->gpio_info.clk_a_register_index =
-			le16_to_cpu(
-			header->gpio_pin[table_index].data_a_reg_index);
-	info->gpio_info.clk_a_shift =
-			header->gpio_pin[table_index].gpio_bitshift;
+	info->gpio_info.clk_a_register_index = le16_to_cpu(pin->data_a_reg_index);
+	info->gpio_info.clk_a_shift = pin->gpio_bitshift;
 
 	return BP_RESULT_OK;
 }
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/kernel/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
index 51397b5..93280dc 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
@@ -459,9 +459,9 @@
 	struct _vcs_dpi_display_dlg_regs_st *dlg_regs = &pipe->dlg_regs;
 	struct _vcs_dpi_display_ttu_regs_st *ttu_regs = &pipe->ttu_regs;
 	struct _vcs_dpi_display_rq_regs_st *rq_regs = &pipe->rq_regs;
-	struct _vcs_dpi_display_rq_params_st rq_param = {0};
-	struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param = {0};
-	struct _vcs_dpi_display_e2e_pipe_params_st input = { { { 0 } } };
+	struct _vcs_dpi_display_rq_params_st *rq_param = &pipe->dml_rq_param;
+	struct _vcs_dpi_display_dlg_sys_params_st *dlg_sys_param = &pipe->dml_dlg_sys_param;
+	struct _vcs_dpi_display_e2e_pipe_params_st *input = &pipe->dml_input;
 	float total_active_bw = 0;
 	float total_prefetch_bw = 0;
 	int total_flip_bytes = 0;
@@ -470,45 +470,48 @@
 	memset(dlg_regs, 0, sizeof(*dlg_regs));
 	memset(ttu_regs, 0, sizeof(*ttu_regs));
 	memset(rq_regs, 0, sizeof(*rq_regs));
+	memset(rq_param, 0, sizeof(*rq_param));
+	memset(dlg_sys_param, 0, sizeof(*dlg_sys_param));
+	memset(input, 0, sizeof(*input));
 
 	for (i = 0; i < number_of_planes; i++) {
 		total_active_bw += v->read_bandwidth[i];
 		total_prefetch_bw += v->prefetch_bandwidth[i];
 		total_flip_bytes += v->total_immediate_flip_bytes[i];
 	}
-	dlg_sys_param.total_flip_bw = v->return_bw - dcn_bw_max2(total_active_bw, total_prefetch_bw);
-	if (dlg_sys_param.total_flip_bw < 0.0)
-		dlg_sys_param.total_flip_bw = 0;
+	dlg_sys_param->total_flip_bw = v->return_bw - dcn_bw_max2(total_active_bw, total_prefetch_bw);
+	if (dlg_sys_param->total_flip_bw < 0.0)
+		dlg_sys_param->total_flip_bw = 0;
 
-	dlg_sys_param.t_mclk_wm_us = v->dram_clock_change_watermark;
-	dlg_sys_param.t_sr_wm_us = v->stutter_enter_plus_exit_watermark;
-	dlg_sys_param.t_urg_wm_us = v->urgent_watermark;
-	dlg_sys_param.t_extra_us = v->urgent_extra_latency;
-	dlg_sys_param.deepsleep_dcfclk_mhz = v->dcf_clk_deep_sleep;
-	dlg_sys_param.total_flip_bytes = total_flip_bytes;
+	dlg_sys_param->t_mclk_wm_us = v->dram_clock_change_watermark;
+	dlg_sys_param->t_sr_wm_us = v->stutter_enter_plus_exit_watermark;
+	dlg_sys_param->t_urg_wm_us = v->urgent_watermark;
+	dlg_sys_param->t_extra_us = v->urgent_extra_latency;
+	dlg_sys_param->deepsleep_dcfclk_mhz = v->dcf_clk_deep_sleep;
+	dlg_sys_param->total_flip_bytes = total_flip_bytes;
 
-	pipe_ctx_to_e2e_pipe_params(pipe, &input.pipe);
-	input.clks_cfg.dcfclk_mhz = v->dcfclk;
-	input.clks_cfg.dispclk_mhz = v->dispclk;
-	input.clks_cfg.dppclk_mhz = v->dppclk;
-	input.clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
-	input.clks_cfg.socclk_mhz = v->socclk;
-	input.clks_cfg.voltage = v->voltage_level;
+	pipe_ctx_to_e2e_pipe_params(pipe, &input->pipe);
+	input->clks_cfg.dcfclk_mhz = v->dcfclk;
+	input->clks_cfg.dispclk_mhz = v->dispclk;
+	input->clks_cfg.dppclk_mhz = v->dppclk;
+	input->clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
+	input->clks_cfg.socclk_mhz = v->socclk;
+	input->clks_cfg.voltage = v->voltage_level;
 //	dc->dml.logger = pool->base.logger;
-	input.dout.output_format = (v->output_format[in_idx] == dcn_bw_420) ? dm_420 : dm_444;
-	input.dout.output_type  = (v->output[in_idx] == dcn_bw_hdmi) ? dm_hdmi : dm_dp;
+	input->dout.output_format = (v->output_format[in_idx] == dcn_bw_420) ? dm_420 : dm_444;
+	input->dout.output_type  = (v->output[in_idx] == dcn_bw_hdmi) ? dm_hdmi : dm_dp;
 	//input[in_idx].dout.output_standard;
 
 	/*todo: soc->sr_enter_plus_exit_time??*/
-	dlg_sys_param.t_srx_delay_us = dc->dcn_ip->dcfclk_cstate_latency / v->dcf_clk_deep_sleep;
+	dlg_sys_param->t_srx_delay_us = dc->dcn_ip->dcfclk_cstate_latency / v->dcf_clk_deep_sleep;
 
-	dml1_rq_dlg_get_rq_params(dml, &rq_param, input.pipe.src);
+	dml1_rq_dlg_get_rq_params(dml, rq_param, input.pipe.src);
 	dml1_extract_rq_regs(dml, rq_regs, rq_param);
 	dml1_rq_dlg_get_dlg_params(
 			dml,
 			dlg_regs,
 			ttu_regs,
-			rq_param.dlg,
+			rq_param->dlg,
 			dlg_sys_param,
 			input,
 			true,
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/core/dc.c b/kernel/drivers/gpu/drm/amd/display/dc/core/dc.c
index 99887bc..099542d 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -616,6 +616,7 @@
 
 	dc_ctx->perf_trace = dc_perf_trace_create();
 	if (!dc_ctx->perf_trace) {
+		kfree(dc_ctx);
 		ASSERT_CRITICAL(false);
 		return false;
 	}
@@ -1853,9 +1854,6 @@
 	enum surface_update_type type;
 	enum surface_update_type overall_type = UPDATE_TYPE_FAST;
 	union surface_update_flags *update_flags = &u->surface->update_flags;
-
-	if (u->flip_addr)
-		update_flags->bits.addr_update = 1;
 
 	if (!is_surface_in_context(context, u->surface) || u->surface->force_full_update) {
 		update_flags->raw = 0xFFFFFFFF;
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/kernel/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index 2a90804..86f3ea4 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -92,8 +92,8 @@
 		{ 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
 				0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
 	{ COLOR_SPACE_YCBCR2020_TYPE,
-		{ 0x1000, 0xF149, 0xFEB7, 0x0000, 0x0868, 0x15B2,
-				0x01E6, 0x0000, 0xFB88, 0xF478, 0x1000, 0x0000} },
+		{ 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868, 0x15B2,
+				0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} },
 	{ COLOR_SPACE_YCBCR709_BLACK_TYPE,
 		{ 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000,
 				0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x1000} },
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/kernel/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 1e47afc..f1eda1a 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1502,6 +1502,9 @@
 	struct dc_stream_status *stream_status = NULL;
 	struct resource_pool *pool = dc->res_pool;
 
+	if (!plane_state)
+		return true;
+
 	for (i = 0; i < context->stream_count; i++)
 		if (context->streams[i] == stream) {
 			stream_status = &context->stream_status[i];
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c b/kernel/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
index e2e7902..a54a309 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
@@ -1011,7 +1011,7 @@
 		color_depth = COLOR_DEPTH_101010;
 		pixel_depth = 0;
 		expan_mode  = 1;
-		BREAK_TO_DEBUGGER();
+		DC_LOG_DC("The pixel depth %d is not valid, set COLOR_DEPTH_101010 instead.", depth);
 		break;
 	}
 
@@ -1025,8 +1025,7 @@
 	if (!(xfm_dce->lb_pixel_depth_supported & depth)) {
 		/*we should use unsupported capabilities
 		 *  unless it is required by w/a*/
-		DC_LOG_WARNING("%s: Capability not supported",
-			__func__);
+		DC_LOG_DC("%s: Capability not supported", __func__);
 	}
 }
 
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/kernel/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index e33fe02..53e8def 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -1682,10 +1682,13 @@
 			hws->funcs.edp_backlight_control(edp_link_with_sink, false);
 		}
 		/*resume from S3, no vbios posting, no need to power down again*/
+		clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
+
 		power_down_all_hw_blocks(dc);
 		disable_vga_and_power_gate_all_controllers(dc);
 		if (edp_link_with_sink && !keep_edp_vdd_on)
 			dc->hwss.edp_power_control(edp_link_with_sink, false);
+		clk_mgr_optimize_pwr_state(dc, dc->clk_mgr);
 	}
 	bios_set_scratch_acc_mode_change(dc->ctx->dc_bios);
 }
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c b/kernel/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c
index 5a5a9cb..bcdd8a9 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c
@@ -1132,6 +1132,7 @@
 	if (dce60_construct(num_virtual_links, dc, pool))
 		return &pool->base;
 
+	kfree(pool);
 	BREAK_TO_DEBUGGER();
 	return NULL;
 }
@@ -1329,6 +1330,7 @@
 	if (dce61_construct(num_virtual_links, dc, pool))
 		return &pool->base;
 
+	kfree(pool);
 	BREAK_TO_DEBUGGER();
 	return NULL;
 }
@@ -1522,6 +1524,7 @@
 	if (dce64_construct(num_virtual_links, dc, pool))
 		return &pool->base;
 
+	kfree(pool);
 	BREAK_TO_DEBUGGER();
 	return NULL;
 }
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/kernel/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
index a19be9d..2eefa07 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
@@ -1141,6 +1141,7 @@
 	if (dce80_construct(num_virtual_links, dc, pool))
 		return &pool->base;
 
+	kfree(pool);
 	BREAK_TO_DEBUGGER();
 	return NULL;
 }
@@ -1338,6 +1339,7 @@
 	if (dce81_construct(num_virtual_links, dc, pool))
 		return &pool->base;
 
+	kfree(pool);
 	BREAK_TO_DEBUGGER();
 	return NULL;
 }
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/kernel/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index 71a85c5..1c669f1 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -3282,7 +3282,9 @@
 		if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst]) {
 			struct hubp *hubp = get_hubp_by_inst(res_pool, mpcc_inst);
 
-			res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, mpcc_inst);
+			if (pipe_ctx->stream_res.tg &&
+				pipe_ctx->stream_res.tg->funcs->is_tg_enabled(pipe_ctx->stream_res.tg))
+				res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, mpcc_inst);
 			pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst] = false;
 			hubp->funcs->set_blank(hubp, true);
 		}
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c b/kernel/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
index 8556825..fd08177 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
@@ -206,8 +206,9 @@
 		/* check insert_above_mpcc exist in tree->opp_list */
 		struct mpcc *temp_mpcc = tree->opp_list;
 
-		while (temp_mpcc && temp_mpcc->mpcc_bot != insert_above_mpcc)
-			temp_mpcc = temp_mpcc->mpcc_bot;
+		if (temp_mpcc != insert_above_mpcc)
+			while (temp_mpcc && temp_mpcc->mpcc_bot != insert_above_mpcc)
+				temp_mpcc = temp_mpcc->mpcc_bot;
 		if (temp_mpcc == NULL)
 			return NULL;
 	}
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/kernel/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index 53ac826..3346074 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -3130,7 +3130,7 @@
 
 		context->bw_ctx.dml.funcs.rq_dlg_get_rq_reg(&context->bw_ctx.dml,
 				&context->res_ctx.pipe_ctx[i].rq_regs,
-				pipes[pipe_idx].pipe);
+				&pipes[pipe_idx].pipe);
 		pipe_idx++;
 	}
 }
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c b/kernel/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
index 0eb881f..8e729ef 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
@@ -354,8 +354,11 @@
 	int cur_rom_en = 0;
 
 	if (color_format == CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA ||
-		color_format == CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA)
-		cur_rom_en = 1;
+		color_format == CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA) {
+		if (cursor_attributes->attribute_flags.bits.ENABLE_CURSOR_DEGAMMA) {
+			cur_rom_en = 1;
+		}
+	}
 
 	REG_UPDATE_3(CURSOR0_CONTROL,
 			CUR0_MODE, color_format,
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
index b3f0476..14e7a59 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
@@ -3897,14 +3897,14 @@
 					mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
 							* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
 
-				locals->ODMCombineEnablePerState[i][k] = false;
+				locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
 				mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
 				if (mode_lib->vba.ODMCapability) {
 					if (locals->PlaneRequiredDISPCLKWithoutODMCombine > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
-						locals->ODMCombineEnablePerState[i][k] = true;
+						locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
 						mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
 					} else if (locals->HActive[k] > DCN20_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) {
-						locals->ODMCombineEnablePerState[i][k] = true;
+						locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
 						mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
 					}
 				}
@@ -3957,7 +3957,7 @@
 				locals->RequiredDISPCLK[i][j] = 0.0;
 				locals->DISPCLK_DPPCLK_Support[i][j] = true;
 				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
-					locals->ODMCombineEnablePerState[i][k] = false;
+					locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
 					if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) {
 						locals->NoOfDPP[i][j][k] = 1;
 						locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
index 1bcda7e..ee1c803 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
@@ -3974,17 +3974,17 @@
 					mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
 							* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
 
-				locals->ODMCombineEnablePerState[i][k] = false;
+				locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
 				mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
 				if (mode_lib->vba.ODMCapability) {
 					if (locals->PlaneRequiredDISPCLKWithoutODMCombine > MaxMaxDispclkRoundedDown) {
-						locals->ODMCombineEnablePerState[i][k] = true;
+						locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
 						mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
 					} else if (locals->DSCEnabled[k] && (locals->HActive[k] > DCN20_MAX_DSC_IMAGE_WIDTH)) {
-						locals->ODMCombineEnablePerState[i][k] = true;
+						locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
 						mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
 					} else if (locals->HActive[k] > DCN20_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) {
-						locals->ODMCombineEnablePerState[i][k] = true;
+						locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
 						mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
 					}
 				}
@@ -4037,7 +4037,7 @@
 				locals->RequiredDISPCLK[i][j] = 0.0;
 				locals->DISPCLK_DPPCLK_Support[i][j] = true;
 				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
-					locals->ODMCombineEnablePerState[i][k] = false;
+					locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
 					if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) {
 						locals->NoOfDPP[i][j][k] = 1;
 						locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
index 799bae2..ed1625d 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
@@ -768,12 +768,12 @@
 
 void dml20_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib,
 		display_rq_regs_st *rq_regs,
-		const display_pipe_params_st pipe_param)
+		const display_pipe_params_st *pipe_param)
 {
 	display_rq_params_st rq_param = {0};
 
 	memset(rq_regs, 0, sizeof(*rq_regs));
-	dml20_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param.src);
+	dml20_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param->src);
 	extract_rq_regs(mode_lib, rq_regs, rq_param);
 
 	print__rq_regs_st(mode_lib, *rq_regs);
@@ -1549,7 +1549,7 @@
 void dml20_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
 		display_dlg_regs_st *dlg_regs,
 		display_ttu_regs_st *ttu_regs,
-		display_e2e_pipe_params_st *e2e_pipe_param,
+		const display_e2e_pipe_params_st *e2e_pipe_param,
 		const unsigned int num_pipes,
 		const unsigned int pipe_idx,
 		const bool cstate_en,
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.h b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.h
index d0b9094..8b23867 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.h
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.h
@@ -43,7 +43,7 @@
 void dml20_rq_dlg_get_rq_reg(
 		struct display_mode_lib *mode_lib,
 		display_rq_regs_st *rq_regs,
-		const display_pipe_params_st pipe_param);
+		const display_pipe_params_st *pipe_param);
 
 
 // Function: dml_rq_dlg_get_dlg_reg
@@ -61,7 +61,7 @@
 		struct display_mode_lib *mode_lib,
 		display_dlg_regs_st *dlg_regs,
 		display_ttu_regs_st *ttu_regs,
-		display_e2e_pipe_params_st *e2e_pipe_param,
+		const display_e2e_pipe_params_st *e2e_pipe_param,
 		const unsigned int num_pipes,
 		const unsigned int pipe_idx,
 		const bool cstate_en,
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
index 6a6d597..b120808 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
@@ -768,12 +768,12 @@
 
 void dml20v2_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib,
 		display_rq_regs_st *rq_regs,
-		const display_pipe_params_st pipe_param)
+		const display_pipe_params_st *pipe_param)
 {
 	display_rq_params_st rq_param = {0};
 
 	memset(rq_regs, 0, sizeof(*rq_regs));
-	dml20v2_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param.src);
+	dml20v2_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param->src);
 	extract_rq_regs(mode_lib, rq_regs, rq_param);
 
 	print__rq_regs_st(mode_lib, *rq_regs);
@@ -1550,7 +1550,7 @@
 void dml20v2_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
 		display_dlg_regs_st *dlg_regs,
 		display_ttu_regs_st *ttu_regs,
-		display_e2e_pipe_params_st *e2e_pipe_param,
+		const display_e2e_pipe_params_st *e2e_pipe_param,
 		const unsigned int num_pipes,
 		const unsigned int pipe_idx,
 		const bool cstate_en,
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h
index 27cf8be..2b4e46e 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h
@@ -43,7 +43,7 @@
 void dml20v2_rq_dlg_get_rq_reg(
 		struct display_mode_lib *mode_lib,
 		display_rq_regs_st *rq_regs,
-		const display_pipe_params_st pipe_param);
+		const display_pipe_params_st *pipe_param);
 
 
 // Function: dml_rq_dlg_get_dlg_reg
@@ -61,7 +61,7 @@
 		struct display_mode_lib *mode_lib,
 		display_dlg_regs_st *dlg_regs,
 		display_ttu_regs_st *ttu_regs,
-		display_e2e_pipe_params_st *e2e_pipe_param,
+		const display_e2e_pipe_params_st *e2e_pipe_param,
 		const unsigned int num_pipes,
 		const unsigned int pipe_idx,
 		const bool cstate_en,
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
index c09bca3..25693e6 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
@@ -3975,17 +3975,17 @@
 					mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
 							* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
 
-				locals->ODMCombineEnablePerState[i][k] = false;
+				locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
 				mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
 				if (mode_lib->vba.ODMCapability) {
 					if (locals->PlaneRequiredDISPCLKWithoutODMCombine > MaxMaxDispclkRoundedDown) {
-						locals->ODMCombineEnablePerState[i][k] = true;
+						locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
 						mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
 					} else if (locals->DSCEnabled[k] && (locals->HActive[k] > DCN21_MAX_DSC_IMAGE_WIDTH)) {
-						locals->ODMCombineEnablePerState[i][k] = true;
+						locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
 						mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
 					} else if (locals->HActive[k] > DCN21_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) {
-						locals->ODMCombineEnablePerState[i][k] = true;
+						locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
 						mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
 					}
 				}
@@ -4038,7 +4038,7 @@
 				locals->RequiredDISPCLK[i][j] = 0.0;
 				locals->DISPCLK_DPPCLK_Support[i][j] = true;
 				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
-					locals->ODMCombineEnablePerState[i][k] = false;
+					locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
 					if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) {
 						locals->NoOfDPP[i][j][k] = 1;
 						locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
@@ -5213,7 +5213,7 @@
 			mode_lib->vba.ODMCombineEnabled[k] =
 					locals->ODMCombineEnablePerState[mode_lib->vba.VoltageLevel][k];
 		} else {
-			mode_lib->vba.ODMCombineEnabled[k] = false;
+			mode_lib->vba.ODMCombineEnabled[k] = dm_odm_combine_mode_disabled;
 		}
 		mode_lib->vba.DSCEnabled[k] =
 				locals->RequiresDSC[mode_lib->vba.VoltageLevel][k];
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
index dc1c81a..bca9406 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
@@ -694,7 +694,7 @@
 		display_data_rq_sizing_params_st *rq_sizing_param,
 		display_data_rq_dlg_params_st *rq_dlg_param,
 		display_data_rq_misc_params_st *rq_misc_param,
-		const display_pipe_params_st pipe_param,
+		const display_pipe_params_st *pipe_param,
 		bool is_chroma)
 {
 	bool mode_422 = false;
@@ -706,30 +706,30 @@
 
 	// FIXME check if ppe apply for both luma and chroma in 422 case
 	if (is_chroma) {
-		vp_width = pipe_param.src.viewport_width_c / ppe;
-		vp_height = pipe_param.src.viewport_height_c;
-		data_pitch = pipe_param.src.data_pitch_c;
-		meta_pitch = pipe_param.src.meta_pitch_c;
+		vp_width = pipe_param->src.viewport_width_c / ppe;
+		vp_height = pipe_param->src.viewport_height_c;
+		data_pitch = pipe_param->src.data_pitch_c;
+		meta_pitch = pipe_param->src.meta_pitch_c;
 	} else {
-		vp_width = pipe_param.src.viewport_width / ppe;
-		vp_height = pipe_param.src.viewport_height;
-		data_pitch = pipe_param.src.data_pitch;
-		meta_pitch = pipe_param.src.meta_pitch;
+		vp_width = pipe_param->src.viewport_width / ppe;
+		vp_height = pipe_param->src.viewport_height;
+		data_pitch = pipe_param->src.data_pitch;
+		meta_pitch = pipe_param->src.meta_pitch;
 	}
 
-	if (pipe_param.dest.odm_combine) {
+	if (pipe_param->dest.odm_combine) {
 		unsigned int access_dir;
 		unsigned int full_src_vp_width;
 		unsigned int hactive_half;
 		unsigned int src_hactive_half;
-		access_dir = (pipe_param.src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed
-		hactive_half  = pipe_param.dest.hactive / 2;
+		access_dir = (pipe_param->src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed
+		hactive_half  = pipe_param->dest.hactive / 2;
 		if (is_chroma) {
-			full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio_c * pipe_param.dest.full_recout_width;
-			src_hactive_half  = pipe_param.scale_ratio_depth.hscl_ratio_c * hactive_half;
+			full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio_c * pipe_param->dest.full_recout_width;
+			src_hactive_half  = pipe_param->scale_ratio_depth.hscl_ratio_c * hactive_half;
 		} else {
-			full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio * pipe_param.dest.full_recout_width;
-			src_hactive_half  = pipe_param.scale_ratio_depth.hscl_ratio * hactive_half;
+			full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio * pipe_param->dest.full_recout_width;
+			src_hactive_half  = pipe_param->scale_ratio_depth.hscl_ratio * hactive_half;
 		}
 
 		if (access_dir == 0) {
@@ -754,7 +754,7 @@
 	rq_sizing_param->meta_chunk_bytes = 2048;
 	rq_sizing_param->min_meta_chunk_bytes = 256;
 
-	if (pipe_param.src.hostvm)
+	if (pipe_param->src.hostvm)
 		rq_sizing_param->mpte_group_bytes = 512;
 	else
 		rq_sizing_param->mpte_group_bytes = 2048;
@@ -768,23 +768,23 @@
 			vp_height,
 			data_pitch,
 			meta_pitch,
-			pipe_param.src.source_format,
-			pipe_param.src.sw_mode,
-			pipe_param.src.macro_tile_size,
-			pipe_param.src.source_scan,
-			pipe_param.src.hostvm,
+			pipe_param->src.source_format,
+			pipe_param->src.sw_mode,
+			pipe_param->src.macro_tile_size,
+			pipe_param->src.source_scan,
+			pipe_param->src.hostvm,
 			is_chroma);
 }
 
 static void dml_rq_dlg_get_rq_params(
 		struct display_mode_lib *mode_lib,
 		display_rq_params_st *rq_param,
-		const display_pipe_params_st pipe_param)
+		const display_pipe_params_st *pipe_param)
 {
 	// get param for luma surface
-	rq_param->yuv420 = pipe_param.src.source_format == dm_420_8
-			|| pipe_param.src.source_format == dm_420_10;
-	rq_param->yuv420_10bpc = pipe_param.src.source_format == dm_420_10;
+	rq_param->yuv420 = pipe_param->src.source_format == dm_420_8
+			|| pipe_param->src.source_format == dm_420_10;
+	rq_param->yuv420_10bpc = pipe_param->src.source_format == dm_420_10;
 
 	get_surf_rq_param(
 			mode_lib,
@@ -794,7 +794,7 @@
 			pipe_param,
 			0);
 
-	if (is_dual_plane((enum source_format_class) (pipe_param.src.source_format))) {
+	if (is_dual_plane((enum source_format_class) (pipe_param->src.source_format))) {
 		// get param for chroma surface
 		get_surf_rq_param(
 				mode_lib,
@@ -806,14 +806,14 @@
 	}
 
 	// calculate how to split the det buffer space between luma and chroma
-	handle_det_buf_split(mode_lib, rq_param, pipe_param.src);
+	handle_det_buf_split(mode_lib, rq_param, pipe_param->src);
 	print__rq_params_st(mode_lib, *rq_param);
 }
 
 void dml21_rq_dlg_get_rq_reg(
 		struct display_mode_lib *mode_lib,
 		display_rq_regs_st *rq_regs,
-		const display_pipe_params_st pipe_param)
+		const display_pipe_params_st *pipe_param)
 {
 	display_rq_params_st rq_param = {0};
 
@@ -1658,7 +1658,7 @@
 		struct display_mode_lib *mode_lib,
 		display_dlg_regs_st *dlg_regs,
 		display_ttu_regs_st *ttu_regs,
-		display_e2e_pipe_params_st *e2e_pipe_param,
+		const display_e2e_pipe_params_st *e2e_pipe_param,
 		const unsigned int num_pipes,
 		const unsigned int pipe_idx,
 		const bool cstate_en,
@@ -1696,7 +1696,7 @@
 	// system parameter calculation done
 
 	dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx);
-	dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe);
+	dml_rq_dlg_get_rq_params(mode_lib, &rq_param, &e2e_pipe_param[pipe_idx].pipe);
 	dml_rq_dlg_get_dlg_params(
 			mode_lib,
 			e2e_pipe_param,
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.h b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.h
index e8f7785..af6ad0c 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.h
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.h
@@ -44,7 +44,7 @@
 void dml21_rq_dlg_get_rq_reg(
 		struct display_mode_lib *mode_lib,
 		display_rq_regs_st *rq_regs,
-		const display_pipe_params_st pipe_param);
+		const display_pipe_params_st *pipe_param);
 
 // Function: dml_rq_dlg_get_dlg_reg
 //   Calculate and return DLG and TTU register struct given the system setting
@@ -61,7 +61,7 @@
 		struct display_mode_lib *mode_lib,
 		display_dlg_regs_st *dlg_regs,
 		display_ttu_regs_st *ttu_regs,
-		display_e2e_pipe_params_st *e2e_pipe_param,
+		const display_e2e_pipe_params_st *e2e_pipe_param,
 		const unsigned int num_pipes,
 		const unsigned int pipe_idx,
 		const bool cstate_en,
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
index e427f4f..e5b1002 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
@@ -1868,7 +1868,10 @@
 	}
 
 	if (SurfaceTiling == dm_sw_linear) {
-		*dpte_row_height = dml_min(128, 1 << (unsigned int) dml_floor(dml_log2(PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch), 1));
+		if (PTEBufferSizeInRequests == 0)
+			*dpte_row_height = 1;
+		else
+			*dpte_row_height = dml_min(128, 1 << (unsigned int) dml_floor(dml_log2(PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch), 1));
 		*dpte_row_width_ub = (dml_ceil(((double) SwathWidth - 1) / *PixelPTEReqWidth, 1) + 1) * *PixelPTEReqWidth;
 		*PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqWidth * *PTERequestSize;
 	} else if (ScanDirection != dm_vert) {
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
index 58c312f..f4d6aca 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
@@ -747,7 +747,7 @@
 	display_data_rq_sizing_params_st *rq_sizing_param,
 	display_data_rq_dlg_params_st *rq_dlg_param,
 	display_data_rq_misc_params_st *rq_misc_param,
-	const display_pipe_params_st pipe_param,
+	const display_pipe_params_st *pipe_param,
 	bool is_chroma,
 	bool is_alpha)
 {
@@ -761,32 +761,32 @@
 
 	// FIXME check if ppe apply for both luma and chroma in 422 case
 	if (is_chroma | is_alpha) {
-		vp_width = pipe_param.src.viewport_width_c / ppe;
-		vp_height = pipe_param.src.viewport_height_c;
-		data_pitch = pipe_param.src.data_pitch_c;
-		meta_pitch = pipe_param.src.meta_pitch_c;
-		surface_height = pipe_param.src.surface_height_y / 2.0;
+		vp_width = pipe_param->src.viewport_width_c / ppe;
+		vp_height = pipe_param->src.viewport_height_c;
+		data_pitch = pipe_param->src.data_pitch_c;
+		meta_pitch = pipe_param->src.meta_pitch_c;
+		surface_height = pipe_param->src.surface_height_y / 2.0;
 	} else {
-		vp_width = pipe_param.src.viewport_width / ppe;
-		vp_height = pipe_param.src.viewport_height;
-		data_pitch = pipe_param.src.data_pitch;
-		meta_pitch = pipe_param.src.meta_pitch;
-		surface_height = pipe_param.src.surface_height_y;
+		vp_width = pipe_param->src.viewport_width / ppe;
+		vp_height = pipe_param->src.viewport_height;
+		data_pitch = pipe_param->src.data_pitch;
+		meta_pitch = pipe_param->src.meta_pitch;
+		surface_height = pipe_param->src.surface_height_y;
 	}
 
-	if (pipe_param.dest.odm_combine) {
+	if (pipe_param->dest.odm_combine) {
 		unsigned int access_dir = 0;
 		unsigned int full_src_vp_width = 0;
 		unsigned int hactive_odm = 0;
 		unsigned int src_hactive_odm = 0;
-		access_dir = (pipe_param.src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed
-		hactive_odm  = pipe_param.dest.hactive / ((unsigned int)pipe_param.dest.odm_combine*2);
+		access_dir = (pipe_param->src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed
+		hactive_odm  = pipe_param->dest.hactive / ((unsigned int) pipe_param->dest.odm_combine*2);
 		if (is_chroma) {
-			full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio_c * pipe_param.dest.full_recout_width;
-			src_hactive_odm  = pipe_param.scale_ratio_depth.hscl_ratio_c * hactive_odm;
+			full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio_c * pipe_param->dest.full_recout_width;
+			src_hactive_odm  = pipe_param->scale_ratio_depth.hscl_ratio_c * hactive_odm;
 		} else {
-			full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio * pipe_param.dest.full_recout_width;
-			src_hactive_odm  = pipe_param.scale_ratio_depth.hscl_ratio * hactive_odm;
+			full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio * pipe_param->dest.full_recout_width;
+			src_hactive_odm  = pipe_param->scale_ratio_depth.hscl_ratio * hactive_odm;
 		}
 
 		if (access_dir == 0) {
@@ -815,7 +815,7 @@
 	rq_sizing_param->meta_chunk_bytes = 2048;
 	rq_sizing_param->min_meta_chunk_bytes = 256;
 
-	if (pipe_param.src.hostvm)
+	if (pipe_param->src.hostvm)
 		rq_sizing_param->mpte_group_bytes = 512;
 	else
 		rq_sizing_param->mpte_group_bytes = 2048;
@@ -828,28 +828,28 @@
 		vp_height,
 		data_pitch,
 		meta_pitch,
-		pipe_param.src.source_format,
-		pipe_param.src.sw_mode,
-		pipe_param.src.macro_tile_size,
-		pipe_param.src.source_scan,
-		pipe_param.src.hostvm,
+		pipe_param->src.source_format,
+		pipe_param->src.sw_mode,
+		pipe_param->src.macro_tile_size,
+		pipe_param->src.source_scan,
+		pipe_param->src.hostvm,
 		is_chroma,
 		surface_height);
 }
 
 static void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib,
 	display_rq_params_st *rq_param,
-	const display_pipe_params_st pipe_param)
+	const display_pipe_params_st *pipe_param)
 {
 	// get param for luma surface
-	rq_param->yuv420 = pipe_param.src.source_format == dm_420_8
-	|| pipe_param.src.source_format == dm_420_10
-	|| pipe_param.src.source_format == dm_rgbe_alpha
-	|| pipe_param.src.source_format == dm_420_12;
+	rq_param->yuv420 = pipe_param->src.source_format == dm_420_8
+	|| pipe_param->src.source_format == dm_420_10
+	|| pipe_param->src.source_format == dm_rgbe_alpha
+	|| pipe_param->src.source_format == dm_420_12;
 
-	rq_param->yuv420_10bpc = pipe_param.src.source_format == dm_420_10;
+	rq_param->yuv420_10bpc = pipe_param->src.source_format == dm_420_10;
 
-	rq_param->rgbe_alpha = (pipe_param.src.source_format == dm_rgbe_alpha)?1:0;
+	rq_param->rgbe_alpha = (pipe_param->src.source_format == dm_rgbe_alpha)?1:0;
 
 	get_surf_rq_param(mode_lib,
 		&(rq_param->sizing.rq_l),
@@ -859,7 +859,7 @@
 		0,
 		0);
 
-	if (is_dual_plane((enum source_format_class)(pipe_param.src.source_format))) {
+	if (is_dual_plane((enum source_format_class)(pipe_param->src.source_format))) {
 		// get param for chroma surface
 		get_surf_rq_param(mode_lib,
 			&(rq_param->sizing.rq_c),
@@ -871,13 +871,13 @@
 	}
 
 	// calculate how to split the det buffer space between luma and chroma
-	handle_det_buf_split(mode_lib, rq_param, pipe_param.src);
+	handle_det_buf_split(mode_lib, rq_param, pipe_param->src);
 	print__rq_params_st(mode_lib, *rq_param);
 }
 
 void dml30_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib,
 	display_rq_regs_st *rq_regs,
-	const display_pipe_params_st pipe_param)
+	const display_pipe_params_st *pipe_param)
 {
 	display_rq_params_st rq_param = { 0 };
 
@@ -1831,7 +1831,7 @@
 void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
 	display_dlg_regs_st *dlg_regs,
 	display_ttu_regs_st *ttu_regs,
-	display_e2e_pipe_params_st *e2e_pipe_param,
+	const display_e2e_pipe_params_st *e2e_pipe_param,
 	const unsigned int num_pipes,
 	const unsigned int pipe_idx,
 	const bool cstate_en,
@@ -1866,7 +1866,7 @@
 	// system parameter calculation done
 
 	dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx);
-	dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe);
+	dml_rq_dlg_get_rq_params(mode_lib, &rq_param, &e2e_pipe_param[pipe_idx].pipe);
 	dml_rq_dlg_get_dlg_params(mode_lib,
 		e2e_pipe_param,
 		num_pipes,
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.h b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.h
index c04965c..625e41f 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.h
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.h
@@ -41,7 +41,7 @@
 //            See also: <display_rq_regs_st>
 void dml30_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib,
 		display_rq_regs_st *rq_regs,
-		const display_pipe_params_st pipe_param);
+		const display_pipe_params_st *pipe_param);
 
 // Function: dml_rq_dlg_get_dlg_reg
 //   Calculate and return DLG and TTU register struct given the system setting
@@ -57,7 +57,7 @@
 void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib             *mode_lib,
 		display_dlg_regs_st          *dlg_regs,
 		display_ttu_regs_st          *ttu_regs,
-		display_e2e_pipe_params_st   *e2e_pipe_param,
+		const display_e2e_pipe_params_st   *e2e_pipe_param,
 		const unsigned int            num_pipes,
 		const unsigned int            pipe_idx,
 		const bool                    cstate_en,
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h b/kernel/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h
index 6adee8a..0be31ea 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h
+++ b/kernel/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h
@@ -49,7 +49,7 @@
 			struct display_mode_lib *mode_lib,
 			display_dlg_regs_st *dlg_regs,
 			display_ttu_regs_st *ttu_regs,
-			display_e2e_pipe_params_st *e2e_pipe_param,
+			const display_e2e_pipe_params_st *e2e_pipe_param,
 			const unsigned int num_pipes,
 			const unsigned int pipe_idx,
 			const bool cstate_en,
@@ -60,7 +60,7 @@
 	void (*rq_dlg_get_rq_reg)(
 		struct display_mode_lib *mode_lib,
 		display_rq_regs_st *rq_regs,
-		const display_pipe_params_st pipe_param);
+		const display_pipe_params_st *pipe_param);
 	void (*recalculate)(struct display_mode_lib *mode_lib);
 	void (*validate)(struct display_mode_lib *mode_lib);
 };
diff --git a/kernel/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/kernel/drivers/gpu/drm/amd/display/dc/inc/core_types.h
index 6e6bc66..e40a1d5 100644
--- a/kernel/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/kernel/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -328,6 +328,9 @@
 	struct _vcs_dpi_display_ttu_regs_st ttu_regs;
 	struct _vcs_dpi_display_rq_regs_st rq_regs;
 	struct _vcs_dpi_display_pipe_dest_params_st pipe_dlg_param;
+	struct _vcs_dpi_display_rq_params_st dml_rq_param;
+	struct _vcs_dpi_display_dlg_sys_params_st dml_dlg_sys_param;
+	struct _vcs_dpi_display_e2e_pipe_params_st dml_input;
 #endif
 	union pipe_update_flags update_flags;
 	struct dwbc *dwbc;
diff --git a/kernel/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/kernel/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
index c6a8d6c..882b4e2 100644
--- a/kernel/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+++ b/kernel/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
@@ -347,7 +347,7 @@
  * of a firmware to know if feature or functionality is supported or present.
  */
 #define DMUB_FW_VERSION(major, minor, revision) \
-	((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | ((revision) & 0xFFFF))
+	((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | (((revision) & 0xFF) << 8))
 
 /**
  * dmub_srv_create() - creates the DMUB service.
diff --git a/kernel/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/kernel/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index d988533..627d578 100644
--- a/kernel/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/kernel/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -327,7 +327,9 @@
 		 *  - Delta for CEIL: delta_from_mid_point_in_us_1
 		 *  - Delta for FLOOR: delta_from_mid_point_in_us_2
 		 */
-		if ((last_render_time_in_us / mid_point_frames_ceil) < in_out_vrr->min_duration_in_us) {
+		if (mid_point_frames_ceil &&
+		    (last_render_time_in_us / mid_point_frames_ceil) <
+		    in_out_vrr->min_duration_in_us) {
 			/* Check for out of range.
 			 * If using CEIL produces a value that is out of range,
 			 * then we are forced to use FLOOR.
@@ -374,8 +376,9 @@
 		/* Either we've calculated the number of frames to insert,
 		 * or we need to insert min duration frames
 		 */
-		if (last_render_time_in_us / frames_to_insert <
-				in_out_vrr->min_duration_in_us){
+		if (frames_to_insert &&
+		    (last_render_time_in_us / frames_to_insert) <
+		    in_out_vrr->min_duration_in_us){
 			frames_to_insert -= (frames_to_insert > 1) ?
 					1 : 0;
 		}
diff --git a/kernel/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/kernel/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index 94132c7..5e8876a 100644
--- a/kernel/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/kernel/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -282,7 +282,8 @@
 	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/kernel/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/kernel/drivers/gpu/drm/amd/pm/amdgpu_pm.c
index 5abb680..d58a59c 100644
--- a/kernel/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+++ b/kernel/drivers/gpu/drm/amd/pm/amdgpu_pm.c
@@ -2115,15 +2115,19 @@
 				     uint32_t mask, struct list_head *attr_list)
 {
 	int ret = 0;
-	struct device_attribute *dev_attr = &attr->dev_attr;
-	const char *name = dev_attr->attr.name;
 	enum amdgpu_device_attr_states attr_states = ATTR_STATE_SUPPORTED;
 	struct amdgpu_device_attr_entry *attr_entry;
+	struct device_attribute *dev_attr;
+	const char *name;
 
 	int (*attr_update)(struct amdgpu_device *adev, struct amdgpu_device_attr *attr,
 			   uint32_t mask, enum amdgpu_device_attr_states *states) = default_attr_update;
 
-	BUG_ON(!attr);
+	if (!attr)
+		return -EINVAL;
+
+	dev_attr = &attr->dev_attr;
+	name = dev_attr->attr.name;
 
 	attr_update = attr->attr_update ? attr_update : default_attr_update;
 
diff --git a/kernel/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/kernel/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
index eab9768..a98ea29 100644
--- a/kernel/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
+++ b/kernel/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
@@ -924,7 +924,8 @@
 	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;
 
diff --git a/kernel/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/kernel/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
index 60cde0c..57a354a 100644
--- a/kernel/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
+++ b/kernel/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
@@ -2962,7 +2962,8 @@
 			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;
 
diff --git a/kernel/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/kernel/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
index e646f59..89f2049 100644
--- a/kernel/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+++ b/kernel/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
@@ -1476,6 +1476,10 @@
 	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))
diff --git a/kernel/drivers/gpu/drm/arm/malidp_planes.c b/kernel/drivers/gpu/drm/arm/malidp_planes.c
index f1e8bc3..24604b4 100644
--- a/kernel/drivers/gpu/drm/arm/malidp_planes.c
+++ b/kernel/drivers/gpu/drm/arm/malidp_planes.c
@@ -348,7 +348,7 @@
 		else
 			sgt = obj->funcs->get_sg_table(obj);
 
-		if (!sgt)
+		if (IS_ERR(sgt))
 			return false;
 
 		sgl = sgt->sgl;
diff --git a/kernel/drivers/gpu/drm/armada/armada_drv.c b/kernel/drivers/gpu/drm/armada/armada_drv.c
index 980d3f1..2d1e1e4 100644
--- a/kernel/drivers/gpu/drm/armada/armada_drv.c
+++ b/kernel/drivers/gpu/drm/armada/armada_drv.c
@@ -102,7 +102,6 @@
 	if (ret) {
 		dev_err(dev, "[" DRM_NAME ":%s] can't kick out simple-fb: %d\n",
 			__func__, ret);
-		kfree(priv);
 		return ret;
 	}
 
diff --git a/kernel/drivers/gpu/drm/armada/armada_overlay.c b/kernel/drivers/gpu/drm/armada/armada_overlay.c
index 30e0110..7ee4c90 100644
--- a/kernel/drivers/gpu/drm/armada/armada_overlay.c
+++ b/kernel/drivers/gpu/drm/armada/armada_overlay.c
@@ -4,6 +4,8 @@
  *  Rewritten from the dovefb driver, and Armada510 manuals.
  */
 
+#include <linux/bitfield.h>
+
 #include <drm/armada_drm.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
@@ -446,8 +448,8 @@
 			     drm_to_overlay_state(state)->colorkey_ug,
 			     drm_to_overlay_state(state)->colorkey_vb, 0);
 	} else if (property == priv->colorkey_mode_prop) {
-		*val = (drm_to_overlay_state(state)->colorkey_mode &
-			CFG_CKMODE_MASK) >> ffs(CFG_CKMODE_MASK);
+		*val = FIELD_GET(CFG_CKMODE_MASK,
+				 drm_to_overlay_state(state)->colorkey_mode);
 	} else if (property == priv->brightness_prop) {
 		*val = drm_to_overlay_state(state)->brightness + 256;
 	} else if (property == priv->contrast_prop) {
diff --git a/kernel/drivers/gpu/drm/ast/ast_post.c b/kernel/drivers/gpu/drm/ast/ast_post.c
index 8902c2f..1bc05bf 100644
--- a/kernel/drivers/gpu/drm/ast/ast_post.c
+++ b/kernel/drivers/gpu/drm/ast/ast_post.c
@@ -290,7 +290,7 @@
 				;
 			} while (ast_read32(ast, 0x10100) != 0xa8);
 		} else {/* AST2100/1100 */
-			if (ast->chip == AST2100 || ast->chip == 2200)
+			if (ast->chip == AST2100 || ast->chip == AST2200)
 				dram_reg_info = ast2100_dram_table_data;
 			else
 				dram_reg_info = ast1100_dram_table_data;
diff --git a/kernel/drivers/gpu/drm/bridge/adv7511/adv7511.h b/kernel/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 711061b..e95abeb 100644
--- a/kernel/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/kernel/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -394,7 +394,8 @@
 
 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/kernel/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/kernel/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 7f30001..5a5d397 100644
--- a/kernel/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/kernel/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -700,7 +700,7 @@
 }
 
 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;
@@ -789,13 +789,15 @@
 	else
 		low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE;
 
-	regmap_update_bits(adv7511->regmap, 0xfb,
-		0x6, low_refresh_rate << 1);
+	if (adv7511->type == ADV7511)
+		regmap_update_bits(adv7511->regmap, 0xfb,
+				   0x6, low_refresh_rate << 1);
+	else
+		regmap_update_bits(adv7511->regmap, 0x4a,
+				   0xc, low_refresh_rate << 2);
+
 	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);
 
@@ -916,6 +918,18 @@
 	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)
 {
@@ -966,6 +980,7 @@
 	.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/kernel/drivers/gpu/drm/bridge/adv7511/adv7533.c b/kernel/drivers/gpu/drm/bridge/adv7511/adv7533.c
index aa19d5a..e0bdedf 100644
--- a/kernel/drivers/gpu/drm/bridge/adv7511/adv7533.c
+++ b/kernel/drivers/gpu/drm/bridge/adv7511/adv7533.c
@@ -100,26 +100,24 @@
 	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)
 {
+	unsigned long max_lane_freq;
 	struct mipi_dsi_device *dsi = adv->dsi;
-	int lanes, ret;
+	u8 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
 
-	if (adv->num_dsi_lanes != 4)
-		return;
+	/* Check max clock for either 7533 or 7535 */
+	if (mode->clock > (adv->type == ADV7533 ? 80000 : 148500))
+		return MODE_CLOCK_HIGH;
 
-	if (mode->clock > 80000)
-		lanes = 4;
-	else
-		lanes = 3;
+	/* Check max clock for each lane */
+	max_lane_freq = (adv->type == ADV7533 ? 800000 : 891000);
 
-	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");
-	}
+	if (mode->clock * bpp > max_lane_freq * adv->num_dsi_lanes)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
 }
 
 int adv7533_patch_registers(struct adv7511 *adv)
diff --git a/kernel/drivers/gpu/drm/bridge/lontium-lt9611.c b/kernel/drivers/gpu/drm/bridge/lontium-lt9611.c
index 1dcc28a..660e05f 100644
--- a/kernel/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/kernel/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -185,12 +185,14 @@
 
 	regmap_write(lt9611->regmap, 0x8319, (u8)(hfront_porch % 256));
 
-	regmap_write(lt9611->regmap, 0x831a, (u8)(hsync_porch / 256));
+	regmap_write(lt9611->regmap, 0x831a, (u8)(hsync_porch / 256) |
+						((hfront_porch / 256) << 4));
 	regmap_write(lt9611->regmap, 0x831b, (u8)(hsync_porch % 256));
 }
 
-static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode)
+static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode, unsigned int postdiv)
 {
+	unsigned int pcr_m = mode->clock * 5 * postdiv / 27000;
 	const struct reg_sequence reg_cfg[] = {
 		{ 0x830b, 0x01 },
 		{ 0x830c, 0x10 },
@@ -205,7 +207,6 @@
 
 		/* stage 2 */
 		{ 0x834a, 0x40 },
-		{ 0x831d, 0x10 },
 
 		/* MK limit */
 		{ 0x832d, 0x38 },
@@ -220,30 +221,28 @@
 		{ 0x8325, 0x00 },
 		{ 0x832a, 0x01 },
 		{ 0x834a, 0x10 },
-		{ 0x831d, 0x10 },
-		{ 0x8326, 0x37 },
 	};
+	u8 pol = 0x10;
 
-	regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
+	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+		pol |= 0x2;
+	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+		pol |= 0x1;
+	regmap_write(lt9611->regmap, 0x831d, pol);
 
-	switch (mode->hdisplay) {
-	case 640:
-		regmap_write(lt9611->regmap, 0x8326, 0x14);
-		break;
-	case 1920:
-		regmap_write(lt9611->regmap, 0x8326, 0x37);
-		break;
-	case 3840:
+	if (mode->hdisplay == 3840)
 		regmap_multi_reg_write(lt9611->regmap, reg_cfg2, ARRAY_SIZE(reg_cfg2));
-		break;
-	}
+	else
+		regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
+
+	regmap_write(lt9611->regmap, 0x8326, pcr_m);
 
 	/* pcr rst */
 	regmap_write(lt9611->regmap, 0x8011, 0x5a);
 	regmap_write(lt9611->regmap, 0x8011, 0xfa);
 }
 
-static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode)
+static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode, unsigned int *postdiv)
 {
 	unsigned int pclk = mode->clock;
 	const struct reg_sequence reg_cfg[] = {
@@ -257,16 +256,21 @@
 		{ 0x8126, 0x55 },
 		{ 0x8127, 0x66 },
 		{ 0x8128, 0x88 },
+		{ 0x812a, 0x20 },
 	};
 
 	regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
 
-	if (pclk > 150000)
+	if (pclk > 150000) {
 		regmap_write(lt9611->regmap, 0x812d, 0x88);
-	else if (pclk > 70000)
+		*postdiv = 1;
+	} else if (pclk > 70000) {
 		regmap_write(lt9611->regmap, 0x812d, 0x99);
-	else
+		*postdiv = 2;
+	} else {
 		regmap_write(lt9611->regmap, 0x812d, 0xaa);
+		*postdiv = 4;
+	}
 
 	/*
 	 * first divide pclk by 2 first
@@ -446,12 +450,11 @@
 		{ 0x8023, 0x01 },
 		{ 0x8157, 0x03 }, /* set addr pin as output */
 		{ 0x8149, 0x0b },
-		{ 0x8151, 0x30 }, /* disable IRQ */
+
 		{ 0x8102, 0x48 }, /* MIPI Rx power down */
 		{ 0x8123, 0x80 },
 		{ 0x8130, 0x00 },
-		{ 0x8100, 0x01 }, /* bandgap power down */
-		{ 0x8101, 0x00 }, /* system clk power down */
+		{ 0x8011, 0x0a },
 	};
 
 	regmap_multi_reg_write(lt9611->regmap,
@@ -757,7 +760,7 @@
 static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611,
 						 struct device_node *dsi_node)
 {
-	const struct mipi_dsi_device_info info = { "lt9611", 0, NULL };
+	const struct mipi_dsi_device_info info = { "lt9611", 0, lt9611->dev->of_node};
 	struct mipi_dsi_device *dsi;
 	struct mipi_dsi_host *host;
 	int ret;
@@ -881,12 +884,18 @@
 static void lt9611_bridge_pre_enable(struct drm_bridge *bridge)
 {
 	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+	static const struct reg_sequence reg_cfg[] = {
+		{ 0x8102, 0x12 },
+		{ 0x8123, 0x40 },
+		{ 0x8130, 0xea },
+		{ 0x8011, 0xfa },
+	};
 
 	if (!lt9611->sleep)
 		return;
 
-	lt9611_reset(lt9611);
-	regmap_write(lt9611->regmap, 0x80ee, 0x01);
+	regmap_multi_reg_write(lt9611->regmap,
+			       reg_cfg, ARRAY_SIZE(reg_cfg));
 
 	lt9611->sleep = false;
 }
@@ -904,14 +913,15 @@
 {
 	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
 	struct hdmi_avi_infoframe avi_frame;
+	unsigned int postdiv;
 	int ret;
 
 	lt9611_bridge_pre_enable(bridge);
 
 	lt9611_mipi_input_digital(lt9611, mode);
-	lt9611_pll_setup(lt9611, mode);
+	lt9611_pll_setup(lt9611, mode, &postdiv);
 	lt9611_mipi_video_setup(lt9611, mode);
-	lt9611_pcr_setup(lt9611, mode);
+	lt9611_pcr_setup(lt9611, mode, postdiv);
 
 	ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame,
 						       &lt9611->connector,
diff --git a/kernel/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/kernel/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
index 72248a5..e41afcc 100644
--- a/kernel/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
+++ b/kernel/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
@@ -444,7 +444,11 @@
 	if (ret)
 		return ret;
 
-	return i2c_add_driver(&stdp2690_ge_b850v3_fw_driver);
+	ret = i2c_add_driver(&stdp2690_ge_b850v3_fw_driver);
+	if (ret)
+		i2c_del_driver(&stdp4028_ge_b850v3_fw_driver);
+
+	return ret;
 }
 module_init(stdpxxxx_ge_b850v3_init);
 
diff --git a/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h b/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
index f72d272..966d297 100644
--- a/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
+++ b/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
@@ -17,6 +17,7 @@
 
 	void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
 	u8 (*read)(struct dw_hdmi *hdmi, int offset);
+	void (*mod)(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned int reg);
 	u8 *(*get_eld)(struct dw_hdmi *hdmi);
 };
 
diff --git a/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index 95b0cae..7ec390d 100644
--- a/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -34,6 +34,14 @@
 	return audio->read(hdmi, offset);
 }
 
+static inline void hdmi_update_bits(struct dw_hdmi_i2s_audio_data *audio,
+				    u8 data, u8 mask, unsigned int reg)
+{
+	struct dw_hdmi *hdmi = audio->hdmi;
+
+	audio->mod(hdmi, data, mask, reg);
+}
+
 static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
 				 struct hdmi_codec_daifmt *fmt,
 				 struct hdmi_codec_params *hparms)
@@ -52,7 +60,8 @@
 	}
 
 	/* Reset the FIFOs before applying new params */
-	hdmi_write(audio, HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0);
+	hdmi_update_bits(audio, HDMI_AUD_CONF0_SW_RESET,
+			 HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0);
 	hdmi_write(audio, (u8)~HDMI_MC_SWRSTZ_I2SSWRST_REQ, HDMI_MC_SWRSTZ);
 
 	inputclkfs	= HDMI_AUD_INPUTCLKFS_64FS;
@@ -136,17 +145,7 @@
 			       struct hdmi_codec_daifmt *fmt,
 			       struct hdmi_codec_params *hparms)
 {
-	struct dw_hdmi_i2s_audio_data *audio = data;
-	struct dw_hdmi *hdmi = audio->hdmi;
-
-	dw_hdmi_audio_disable(hdmi);
-
-	hdmi_write(audio, HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0);
-	hdmi_write(audio, (u8)~HDMI_MC_SWRSTZ_I2SSWRST_REQ, HDMI_MC_SWRSTZ);
-
-	dw_hdmi_audio_enable(hdmi);
-
-	return 0;
+	return dw_hdmi_i2s_hw_params(dev, data, fmt, hparms);
 }
 
 static int dw_hdmi_i2s_audio_startup(struct device *dev, void *data)
diff --git a/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index c36513c..5d20a72 100644
--- a/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -422,14 +422,18 @@
 
 	if (hdmi->bridge.dev) {
 		bool change;
+		void *data = hdmi->plat_data->phy_data;
 
 		change = drm_helper_hpd_irq_event(hdmi->bridge.dev);
 
-		if (change && hdmi->cec_adap &&
-		    hdmi->cec_adap->devnode.registered)
-			cec_queue_pin_hpd_event(hdmi->cec_adap,
-						hdmi->hpd_state,
-						ktime_get());
+		if (change) {
+			if (hdmi->plat_data->set_ddc_io)
+				hdmi->plat_data->set_ddc_io(data, hdmi->hpd_state);
+			if (hdmi->cec_adap->devnode.registered)
+				cec_queue_pin_hpd_event(hdmi->cec_adap,
+							hdmi->hpd_state,
+							ktime_get());
+		}
 		drm_bridge_hpd_notify(&hdmi->bridge, status);
 	}
 }
@@ -535,10 +539,12 @@
 	hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE,
 		    HDMI_IH_MUTE_I2CM_STAT0);
 
-	/* set SDA high level holding time */
-	hdmi_writeb(hdmi, 0x48, HDMI_I2CM_SDA_HOLD);
-
-	dw_hdmi_i2c_set_divs(hdmi);
+	/* Only configure when we use the internal I2C controller */
+	if (hdmi->i2c) {
+		/* set SDA high level holding time */
+		hdmi_writeb(hdmi, 0x48, HDMI_I2CM_SDA_HOLD);
+		dw_hdmi_i2c_set_divs(hdmi);
+	}
 }
 
 static bool dw_hdmi_i2c_unwedge(struct dw_hdmi *hdmi)
@@ -643,11 +649,7 @@
 
 		while (retry > 0) {
 			if (!(hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD)) {
-				void *data = hdmi->plat_data->phy_data;
-
 				dev_dbg(hdmi->dev, "hdmi disconnect, stop ddc read\n");
-				if (hdmi->plat_data->set_ddc_io)
-					hdmi->plat_data->set_ddc_io(data, false);
 				return -EPERM;
 			}
 
@@ -726,11 +728,7 @@
 
 		while (retry > 0) {
 			if (!(hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD)) {
-				void *data = hdmi->plat_data->phy_data;
-
 				dev_dbg(hdmi->dev, "hdmi disconnect, stop ddc write\n");
-				if (hdmi->plat_data->set_ddc_io)
-					hdmi->plat_data->set_ddc_io(data, false);
 				return -EPERM;
 			}
 
@@ -775,7 +773,6 @@
 	struct dw_hdmi *hdmi = i2c_get_adapdata(adap);
 	struct dw_hdmi_i2c *i2c = hdmi->i2c;
 	u8 addr = msgs[0].addr;
-	void *data = hdmi->plat_data->phy_data;
 	int i, ret = 0;
 
 	if (addr == DDC_CI_ADDR)
@@ -799,9 +796,6 @@
 	}
 
 	mutex_lock(&i2c->lock);
-
-	if (hdmi->plat_data->set_ddc_io)
-		hdmi->plat_data->set_ddc_io(data, true);
 
 	hdmi_writeb(hdmi, 0, HDMI_I2CM_SOFTRSTZ);
 	udelay(100);
@@ -2425,9 +2419,6 @@
 
 	vmode->previous_pixelclock = vmode->mpixelclock;
 	vmode->mpixelclock = mode->crtc_clock * 1000;
-	if ((mode->flags & DRM_MODE_FLAG_3D_MASK) ==
-		DRM_MODE_FLAG_3D_FRAME_PACKING)
-		vmode->mpixelclock *= 2;
 	dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
 
 	vmode->previous_tmdsclock = vmode->mtmdsclock;
@@ -3993,7 +3984,6 @@
 					  struct drm_bridge_state *old_state)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
-	void *data = hdmi->plat_data->phy_data;
 
 	mutex_lock(&hdmi->mutex);
 	hdmi->disabled = true;
@@ -4004,11 +3994,6 @@
 	if (hdmi->plat_data->dclk_set)
 		hdmi->plat_data->dclk_set(hdmi->plat_data->phy_data, false, 0);
 	mutex_unlock(&hdmi->mutex);
-
-	mutex_lock(&hdmi->i2c->lock);
-	if (hdmi->plat_data->set_ddc_io)
-		hdmi->plat_data->set_ddc_io(data, false);
-	mutex_unlock(&hdmi->i2c->lock);
 }
 
 static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
@@ -4338,8 +4323,7 @@
 	 * Even if we are using a separate i2c adapter doing this doesn't
 	 * hurt.
 	 */
-	if (hdmi->i2c)
-		dw_hdmi_i2c_init(hdmi);
+	dw_hdmi_i2c_init(hdmi);
 
 	if (hdmi->phy.ops->setup_hpd)
 		hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
@@ -5008,6 +4992,7 @@
 		audio.get_eld	= hdmi_audio_get_eld;
 		audio.write	= hdmi_writeb;
 		audio.read	= hdmi_readb;
+		audio.mod	= hdmi_modb;
 		hdmi->enable_audio = dw_hdmi_i2s_audio_enable;
 		hdmi->disable_audio = dw_hdmi_i2s_audio_disable;
 
@@ -5227,8 +5212,7 @@
 	pinctrl_pm_select_default_state(hdmi->dev);
 	mutex_lock(&hdmi->mutex);
 	dw_hdmi_reg_initial(hdmi);
-	if (hdmi->i2c)
-		dw_hdmi_i2c_init(hdmi);
+	dw_hdmi_i2c_init(hdmi);
 	if (hdmi->irq)
 		enable_irq(hdmi->irq);
 	/*
diff --git a/kernel/drivers/gpu/drm/bridge/tc358762.c b/kernel/drivers/gpu/drm/bridge/tc358762.c
index 1bfdfc6..21c57d3 100644
--- a/kernel/drivers/gpu/drm/bridge/tc358762.c
+++ b/kernel/drivers/gpu/drm/bridge/tc358762.c
@@ -224,7 +224,7 @@
 	dsi->lanes = 1;
 	dsi->format = MIPI_DSI_FMT_RGB888;
 	dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
-			  MIPI_DSI_MODE_LPM;
+			  MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_VIDEO_HSE;
 
 	ret = tc358762_parse_dt(ctx);
 	if (ret < 0)
diff --git a/kernel/drivers/gpu/drm/bridge/tc358764.c b/kernel/drivers/gpu/drm/bridge/tc358764.c
index d89394b..ea1445e 100644
--- a/kernel/drivers/gpu/drm/bridge/tc358764.c
+++ b/kernel/drivers/gpu/drm/bridge/tc358764.c
@@ -180,7 +180,7 @@
 	if (ret >= 0)
 		le32_to_cpus(val);
 
-	dev_dbg(ctx->dev, "read: %d, addr: %d\n", addr, *val);
+	dev_dbg(ctx->dev, "read: addr=0x%04x data=0x%08x\n", addr, *val);
 }
 
 static void tc358764_write(struct tc358764 *ctx, u16 addr, u32 val)
diff --git a/kernel/drivers/gpu/drm/bridge/tc358768.c b/kernel/drivers/gpu/drm/bridge/tc358768.c
index 8ed8302..b4a69b2 100644
--- a/kernel/drivers/gpu/drm/bridge/tc358768.c
+++ b/kernel/drivers/gpu/drm/bridge/tc358768.c
@@ -9,6 +9,8 @@
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/kernel.h>
+#include <linux/media-bus-format.h>
+#include <linux/minmax.h>
 #include <linux/module.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
@@ -147,6 +149,7 @@
 
 	u32 pd_lines; /* number of Parallel Port Input Data Lines */
 	u32 dsi_lanes; /* number of DSI Lanes */
+	u32 dsi_bpp; /* number of Bits Per Pixel over DSI */
 
 	/* Parameters for PLL programming */
 	u32 fbd;	/* PLL feedback divider */
@@ -279,12 +282,12 @@
 
 static u32 tc358768_pll_to_pclk(struct tc358768_priv *priv, u32 pll_clk)
 {
-	return (u32)div_u64((u64)pll_clk * priv->dsi_lanes, priv->pd_lines);
+	return (u32)div_u64((u64)pll_clk * priv->dsi_lanes, priv->dsi_bpp);
 }
 
 static u32 tc358768_pclk_to_pll(struct tc358768_priv *priv, u32 pclk)
 {
-	return (u32)div_u64((u64)pclk * priv->pd_lines, priv->dsi_lanes);
+	return (u32)div_u64((u64)pclk * priv->dsi_bpp, priv->dsi_lanes);
 }
 
 static int tc358768_calc_pll(struct tc358768_priv *priv,
@@ -329,11 +332,15 @@
 		u32 fbd;
 
 		for (fbd = 0; fbd < 512; ++fbd) {
-			u32 pll, diff;
+			u32 pll, diff, pll_in;
 
 			pll = (u32)div_u64((u64)refclk * (fbd + 1), divisor);
 
 			if (pll >= max_pll || pll < min_pll)
+				continue;
+
+			pll_in = (u32)div_u64((u64)refclk, prd + 1);
+			if (pll_in < 4000000)
 				continue;
 
 			diff = max(pll, target_pll) - min(pll, target_pll);
@@ -417,6 +424,7 @@
 	priv->output.panel = panel;
 
 	priv->dsi_lanes = dev->lanes;
+	priv->dsi_bpp = mipi_dsi_pixel_format_to_bpp(dev->format);
 
 	/* get input ep (port0/endpoint0) */
 	ret = -EINVAL;
@@ -428,7 +436,7 @@
 	}
 
 	if (ret)
-		priv->pd_lines = mipi_dsi_pixel_format_to_bpp(dev->format);
+		priv->pd_lines = priv->dsi_bpp;
 
 	drm_bridge_add(&priv->bridge);
 
@@ -626,6 +634,7 @@
 	struct tc358768_priv *priv = bridge_to_tc358768(bridge);
 	struct mipi_dsi_device *dsi_dev = priv->output.dev;
 	u32 val, val2, lptxcnt, hact, data_type;
+	s32 raw_val;
 	const struct drm_display_mode *mode;
 	u32 dsibclk_nsk, dsiclk_nsk, ui_nsk, phy_delay_nsk;
 	u32 dsiclk, dsibclk;
@@ -719,25 +728,26 @@
 
 	/* 38ns < TCLK_PREPARE < 95ns */
 	val = tc358768_ns_to_cnt(65, dsibclk_nsk) - 1;
-	/* TCLK_PREPARE > 300ns */
-	val2 = tc358768_ns_to_cnt(300 + tc358768_to_ns(3 * ui_nsk),
-				  dsibclk_nsk);
-	val |= (val2 - tc358768_to_ns(phy_delay_nsk - dsibclk_nsk)) << 8;
+	/* TCLK_PREPARE + TCLK_ZERO > 300ns */
+	val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk),
+				  dsibclk_nsk) - 2;
+	val |= val2 << 8;
 	dev_dbg(priv->dev, "TCLK_HEADERCNT: 0x%x\n", val);
 	tc358768_write(priv, TC358768_TCLK_HEADERCNT, val);
 
-	/* TCLK_TRAIL > 60ns + 3*UI */
-	val = 60 + tc358768_to_ns(3 * ui_nsk);
-	val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 5;
+	/* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */
+	raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), dsibclk_nsk) - 5;
+	val = clamp(raw_val, 0, 127);
 	dev_dbg(priv->dev, "TCLK_TRAILCNT: 0x%x\n", val);
 	tc358768_write(priv, TC358768_TCLK_TRAILCNT, val);
 
 	/* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */
 	val = 50 + tc358768_to_ns(4 * ui_nsk);
 	val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1;
-	/* THS_ZERO > 145ns + 10*UI */
-	val2 = tc358768_ns_to_cnt(145 - tc358768_to_ns(ui_nsk), dsibclk_nsk);
-	val |= (val2 - tc358768_to_ns(phy_delay_nsk)) << 8;
+	/* THS_PREPARE + THS_ZERO > 145ns + 10*UI */
+	raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), dsibclk_nsk) - 10;
+	val2 = clamp(raw_val, 0, 127);
+	val |= val2 << 8;
 	dev_dbg(priv->dev, "THS_HEADERCNT: 0x%x\n", val);
 	tc358768_write(priv, TC358768_THS_HEADERCNT, val);
 
@@ -753,9 +763,10 @@
 	dev_dbg(priv->dev, "TCLK_POSTCNT: 0x%x\n", val);
 	tc358768_write(priv, TC358768_TCLK_POSTCNT, val);
 
-	/* 60ns + 4*UI < THS_PREPARE < 105ns + 12*UI */
-	val = tc358768_ns_to_cnt(60 + tc358768_to_ns(15 * ui_nsk),
-				 dsibclk_nsk) - 5;
+	/* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */
+	raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(18 * ui_nsk),
+				     dsibclk_nsk) - 4;
+	val = clamp(raw_val, 0, 15);
 	dev_dbg(priv->dev, "THS_TRAILCNT: 0x%x\n", val);
 	tc358768_write(priv, TC358768_THS_TRAILCNT, val);
 
@@ -769,7 +780,7 @@
 
 	/* TXTAGOCNT[26:16] RXTASURECNT[10:0] */
 	val = tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk * 4);
-	val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1;
+	val = tc358768_ns_to_cnt(val, dsibclk_nsk) / 4 - 1;
 	val2 = tc358768_ns_to_cnt(tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk),
 				  dsibclk_nsk) - 2;
 	val |= val2 << 16;
@@ -819,8 +830,7 @@
 	val = TC358768_DSI_CONFW_MODE_SET | TC358768_DSI_CONFW_ADDR_DSI_CONTROL;
 	val |= (dsi_dev->lanes - 1) << 1;
 
-	if (!(dsi_dev->mode_flags & MIPI_DSI_MODE_LPM))
-		val |= TC358768_DSI_CONTROL_TXMD;
+	val |= TC358768_DSI_CONTROL_TXMD;
 
 	if (!(dsi_dev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
 		val |= TC358768_DSI_CONTROL_HSCKMD;
@@ -866,6 +876,44 @@
 	}
 }
 
+#define MAX_INPUT_SEL_FORMATS	1
+
+static u32 *
+tc358768_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
+				   struct drm_bridge_state *bridge_state,
+				   struct drm_crtc_state *crtc_state,
+				   struct drm_connector_state *conn_state,
+				   u32 output_fmt,
+				   unsigned int *num_input_fmts)
+{
+	struct tc358768_priv *priv = bridge_to_tc358768(bridge);
+	u32 *input_fmts;
+
+	*num_input_fmts = 0;
+
+	input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),
+			     GFP_KERNEL);
+	if (!input_fmts)
+		return NULL;
+
+	switch (priv->pd_lines) {
+	case 16:
+		input_fmts[0] = MEDIA_BUS_FMT_RGB565_1X16;
+		break;
+	case 18:
+		input_fmts[0] = MEDIA_BUS_FMT_RGB666_1X18;
+		break;
+	default:
+	case 24:
+		input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
+		break;
+	};
+
+	*num_input_fmts = MAX_INPUT_SEL_FORMATS;
+
+	return input_fmts;
+}
+
 static const struct drm_bridge_funcs tc358768_bridge_funcs = {
 	.attach = tc358768_bridge_attach,
 	.mode_valid = tc358768_bridge_mode_valid,
@@ -873,6 +921,11 @@
 	.enable = tc358768_bridge_enable,
 	.disable = tc358768_bridge_disable,
 	.post_disable = tc358768_bridge_post_disable,
+
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+	.atomic_get_input_bus_fmts = tc358768_atomic_get_input_bus_fmts,
 };
 
 static const struct drm_bridge_timings default_tc358768_timings = {
diff --git a/kernel/drivers/gpu/drm/drm_atomic.c b/kernel/drivers/gpu/drm/drm_atomic.c
index 58527f1..b10ba50 100644
--- a/kernel/drivers/gpu/drm/drm_atomic.c
+++ b/kernel/drivers/gpu/drm/drm_atomic.c
@@ -98,6 +98,12 @@
 	if (!state->planes)
 		goto fail;
 
+	/*
+	 * Because drm_atomic_state can be committed asynchronously we need our
+	 * own reference and cannot rely on the on implied by drm_file in the
+	 * ioctl call.
+	 */
+	drm_dev_get(dev);
 	state->dev = dev;
 
 	DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
@@ -257,7 +263,8 @@
 void __drm_atomic_state_free(struct kref *ref)
 {
 	struct drm_atomic_state *state = container_of(ref, typeof(*state), ref);
-	struct drm_mode_config *config = &state->dev->mode_config;
+	struct drm_device *dev = state->dev;
+	struct drm_mode_config *config = &dev->mode_config;
 
 	drm_atomic_state_clear(state);
 
@@ -269,6 +276,8 @@
 		drm_atomic_state_default_release(state);
 		kfree(state);
 	}
+
+	drm_dev_put(dev);
 }
 EXPORT_SYMBOL(__drm_atomic_state_free);
 
@@ -1010,6 +1019,7 @@
 	drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name);
 	drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
 	drm_printf(p, "\tself_refresh_aware=%d\n", state->self_refresh_aware);
+	drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc);
 
 	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
 		if (state->writeback_job && state->writeback_job->fb)
diff --git a/kernel/drivers/gpu/drm/drm_atomic_helper.c b/kernel/drivers/gpu/drm/drm_atomic_helper.c
index 7fc8e70..0fde260 100644
--- a/kernel/drivers/gpu/drm/drm_atomic_helper.c
+++ b/kernel/drivers/gpu/drm/drm_atomic_helper.c
@@ -1113,7 +1113,16 @@
 			continue;
 
 		ret = drm_crtc_vblank_get(crtc);
-		WARN_ONCE(ret != -EINVAL, "driver forgot to call drm_crtc_vblank_off()\n");
+		/*
+		 * Self-refresh is not a true "disable"; ensure vblank remains
+		 * enabled.
+		 */
+		if (new_crtc_state->self_refresh_active)
+			WARN_ONCE(ret != 0,
+				  "driver disabled vblank in self-refresh\n");
+		else
+			WARN_ONCE(ret != -EINVAL,
+				  "driver forgot to call drm_crtc_vblank_off()\n");
 		if (ret == 0)
 			drm_crtc_vblank_put(crtc);
 	}
diff --git a/kernel/drivers/gpu/drm/drm_atomic_uapi.c b/kernel/drivers/gpu/drm/drm_atomic_uapi.c
index 25c269b..b606283 100644
--- a/kernel/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/kernel/drivers/gpu/drm/drm_atomic_uapi.c
@@ -75,15 +75,17 @@
 	state->mode_blob = NULL;
 
 	if (mode) {
+		struct drm_property_blob *blob;
+
 		drm_mode_convert_to_umode(&umode, mode);
-		state->mode_blob =
-			drm_property_create_blob(state->crtc->dev,
-		                                 sizeof(umode),
-		                                 &umode);
-		if (IS_ERR(state->mode_blob))
-			return PTR_ERR(state->mode_blob);
+		blob = drm_property_create_blob(crtc->dev,
+						sizeof(umode), &umode);
+		if (IS_ERR(blob))
+			return PTR_ERR(blob);
 
 		drm_mode_copy(&state->mode, mode);
+
+		state->mode_blob = blob;
 		state->enable = true;
 		DRM_DEBUG_ATOMIC("Set [MODE:%s] for [CRTC:%d:%s] state %p\n",
 				 mode->name, crtc->base.id, crtc->name, state);
diff --git a/kernel/drivers/gpu/drm/drm_client_modeset.c b/kernel/drivers/gpu/drm/drm_client_modeset.c
index b7e9e1c..d5fd418 100644
--- a/kernel/drivers/gpu/drm/drm_client_modeset.c
+++ b/kernel/drivers/gpu/drm/drm_client_modeset.c
@@ -308,6 +308,9 @@
 	can_clone = true;
 	dmt_mode = drm_mode_find_dmt(dev, 1024, 768, 60, false);
 
+	if (!dmt_mode)
+		goto fail;
+
 	for (i = 0; i < connector_count; i++) {
 		if (!enabled[i])
 			continue;
@@ -323,11 +326,13 @@
 		if (!modes[i])
 			can_clone = false;
 	}
+	kfree(dmt_mode);
 
 	if (can_clone) {
 		DRM_DEBUG_KMS("can clone using 1024x768\n");
 		return true;
 	}
+fail:
 	DRM_INFO("kms: can't enable cloning when we probably wanted to.\n");
 	return false;
 }
@@ -859,6 +864,7 @@
 				break;
 			}
 
+			kfree(modeset->mode);
 			modeset->mode = drm_mode_duplicate(dev, mode);
 			drm_connector_get(connector);
 			modeset->connectors[modeset->num_connectors++] = connector;
diff --git a/kernel/drivers/gpu/drm/drm_connector.c b/kernel/drivers/gpu/drm/drm_connector.c
index 5163433..9c3bbe2 100644
--- a/kernel/drivers/gpu/drm/drm_connector.c
+++ b/kernel/drivers/gpu/drm/drm_connector.c
@@ -484,6 +484,9 @@
 	mutex_destroy(&connector->mutex);
 
 	memset(connector, 0, sizeof(*connector));
+
+	if (dev->registered)
+		drm_sysfs_hotplug_event(dev);
 }
 EXPORT_SYMBOL(drm_connector_cleanup);
 
diff --git a/kernel/drivers/gpu/drm/drm_dp_mst_topology.c b/kernel/drivers/gpu/drm/drm_dp_mst_topology.c
index 0feeac5..b5e1593 100644
--- a/kernel/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/kernel/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3769,6 +3769,9 @@
 		set_bit(0, &mgr->payload_mask);
 		mgr->vcpi_mask = 0;
 		mgr->payload_id_table_cleared = false;
+
+		memset(&mgr->down_rep_recv, 0, sizeof(mgr->down_rep_recv));
+		memset(&mgr->up_req_recv, 0, sizeof(mgr->up_req_recv));
 	}
 
 out_unlock:
@@ -3985,7 +3988,7 @@
 	struct drm_dp_sideband_msg_rx *msg = &mgr->down_rep_recv;
 
 	if (!drm_dp_get_one_sb_msg(mgr, false, &mstb))
-		goto out;
+		goto out_clear_reply;
 
 	/* Multi-packet message transmission, don't clear the reply */
 	if (!msg->have_eomt)
diff --git a/kernel/drivers/gpu/drm/drm_edid.c b/kernel/drivers/gpu/drm/drm_edid.c
index 4a57b25..836d2a7 100644
--- a/kernel/drivers/gpu/drm/drm_edid.c
+++ b/kernel/drivers/gpu/drm/drm_edid.c
@@ -5948,8 +5948,6 @@
 static u8 drm_mode_cea_vic(const struct drm_connector *connector,
 			   const struct drm_display_mode *mode)
 {
-	u8 vic;
-
 	/*
 	 * HDMI spec says if a mode is found in HDMI 1.4b 4K modes
 	 * we should send its VIC in vendor infoframes, else send the
@@ -5959,13 +5957,18 @@
 	if (drm_mode_hdmi_vic(connector, mode))
 		return 0;
 
-	vic = drm_match_cea_mode(mode);
+	return drm_match_cea_mode(mode);
+}
 
-	/*
-	 * HDMI 1.4 VIC range: 1 <= VIC <= 64 (CEA-861-D) but
-	 * HDMI 2.0 VIC range: 1 <= VIC <= 107 (CEA-861-F). So we
-	 * have to make sure we dont break HDMI 1.4 sinks.
-	 */
+/*
+ * Avoid sending VICs defined in HDMI 2.0 in AVI infoframes to sinks that
+ * conform to HDMI 1.4.
+ *
+ * HDMI 1.4 (CTA-861-D) VIC range: [1..64]
+ * HDMI 2.0 (CTA-861-F) VIC range: [1..107]
+ */
+static u8 vic_for_avi_infoframe(const struct drm_connector *connector, u8 vic)
+{
 	if (!is_hdmi2_sink(connector) && vic > 64)
 		return 0;
 
@@ -6041,7 +6044,7 @@
 		picture_aspect = HDMI_PICTURE_ASPECT_NONE;
 	}
 
-	frame->video_code = vic;
+	frame->video_code = vic_for_avi_infoframe(connector, vic);
 	frame->picture_aspect = picture_aspect;
 	frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
 	frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN;
diff --git a/kernel/drivers/gpu/drm/drm_fb_helper.c b/kernel/drivers/gpu/drm/drm_fb_helper.c
index ac5d61e..04f2ec2 100644
--- a/kernel/drivers/gpu/drm/drm_fb_helper.c
+++ b/kernel/drivers/gpu/drm/drm_fb_helper.c
@@ -1299,6 +1299,9 @@
 		return -EINVAL;
 	}
 
+	var->xres_virtual = fb->width;
+	var->yres_virtual = fb->height;
+
 	/*
 	 * Workaround for SDL 1.2, which is known to be setting all pixel format
 	 * fields values to zero in some cases. We treat this situation as a
diff --git a/kernel/drivers/gpu/drm/drm_fourcc.c b/kernel/drivers/gpu/drm/drm_fourcc.c
index e2241a5..e4c8aa3 100644
--- a/kernel/drivers/gpu/drm/drm_fourcc.c
+++ b/kernel/drivers/gpu/drm/drm_fourcc.c
@@ -178,6 +178,10 @@
 		{ .format = DRM_FORMAT_BGRA5551,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
 		{ .format = DRM_FORMAT_RGB565,		.depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
 		{ .format = DRM_FORMAT_BGR565,		.depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
+#ifdef __BIG_ENDIAN
+		{ .format = DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
+		{ .format = DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
+#endif
 		{ .format = DRM_FORMAT_RGB888,		.depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 },
 		{ .format = DRM_FORMAT_BGR888,		.depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 },
 		{ .format = DRM_FORMAT_XRGB8888,	.depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
@@ -290,12 +294,15 @@
 #endif
 		{ .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},
 	};
 
 	unsigned int i;
diff --git a/kernel/drivers/gpu/drm/drm_gem_shmem_helper.c b/kernel/drivers/gpu/drm/drm_gem_shmem_helper.c
index c56656a..e8f0730 100644
--- a/kernel/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/kernel/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -614,11 +614,20 @@
 	int ret;
 
 	if (obj->import_attach) {
-		/* Drop the reference drm_gem_mmap_obj() acquired.*/
-		drm_gem_object_put(obj);
+		/* Reset both vm_ops and vm_private_data, so we don't end up with
+		 * vm_ops pointing to our implementation if the dma-buf backend
+		 * doesn't set those fields.
+		 */
 		vma->vm_private_data = NULL;
+		vma->vm_ops = NULL;
 
-		return dma_buf_mmap(obj->dma_buf, vma, 0);
+		ret = dma_buf_mmap(obj->dma_buf, vma, 0);
+
+		/* Drop the reference drm_gem_mmap_obj() acquired.*/
+		if (!ret)
+			drm_gem_object_put(obj);
+
+		return ret;
 	}
 
 	shmem = to_drm_gem_shmem_obj(obj);
diff --git a/kernel/drivers/gpu/drm/drm_gem_vram_helper.c b/kernel/drivers/gpu/drm/drm_gem_vram_helper.c
index 375c79e..eb104de 100644
--- a/kernel/drivers/gpu/drm/drm_gem_vram_helper.c
+++ b/kernel/drivers/gpu/drm/drm_gem_vram_helper.c
@@ -41,7 +41,7 @@
  * the frame's scanout buffer or the cursor image. If there's no more space
  * left in VRAM, inactive GEM objects can be moved to system memory.
  *
- * To initialize the VRAM helper library call drmm_vram_helper_alloc_mm().
+ * To initialize the VRAM helper library call drmm_vram_helper_init().
  * The function allocates and initializes an instance of &struct drm_vram_mm
  * in &struct drm_device.vram_mm . Use &DRM_GEM_VRAM_DRIVER to initialize
  * &struct drm_driver and  &DRM_VRAM_MM_FILE_OPERATIONS to initialize
@@ -69,7 +69,7 @@
  *		// setup device, vram base and size
  *		// ...
  *
- *		ret = drmm_vram_helper_alloc_mm(dev, vram_base, vram_size);
+ *		ret = drmm_vram_helper_init(dev, vram_base, vram_size);
  *		if (ret)
  *			return ret;
  *		return 0;
@@ -82,7 +82,7 @@
  * to userspace.
  *
  * You don't have to clean up the instance of VRAM MM.
- * drmm_vram_helper_alloc_mm() is a managed interface that installs a
+ * drmm_vram_helper_init() is a managed interface that installs a
  * clean-up handler to run during the DRM device's release.
  *
  * For drawing or scanout operations, rsp. buffer objects have to be pinned
diff --git a/kernel/drivers/gpu/drm/drm_mipi_dsi.c b/kernel/drivers/gpu/drm/drm_mipi_dsi.c
index d95bf57..fddc041 100644
--- a/kernel/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/kernel/drivers/gpu/drm/drm_mipi_dsi.c
@@ -221,7 +221,7 @@
 		return dsi;
 	}
 
-	dsi->dev.of_node = info->node;
+	device_set_node(&dsi->dev, of_fwnode_handle(info->node));
 	dsi->channel = info->channel;
 	strlcpy(dsi->name, info->type, sizeof(dsi->name));
 
@@ -1144,6 +1144,58 @@
 }
 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness);
 
+/**
+ * mipi_dsi_dcs_set_display_brightness_large() - sets the 16-bit brightness value
+ *    of the display
+ * @dsi: DSI peripheral device
+ * @brightness: brightness value
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi,
+					     u16 brightness)
+{
+	u8 payload[2] = { brightness >> 8, brightness & 0xff };
+	ssize_t err;
+
+	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
+				 payload, sizeof(payload));
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_large);
+
+/**
+ * mipi_dsi_dcs_get_display_brightness_large() - gets the current 16-bit
+ *    brightness value of the display
+ * @dsi: DSI peripheral device
+ * @brightness: brightness value
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
+					     u16 *brightness)
+{
+	u8 brightness_be[2];
+	ssize_t err;
+
+	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
+				brightness_be, sizeof(brightness_be));
+	if (err <= 0) {
+		if (err == 0)
+			err = -ENODATA;
+
+		return err;
+	}
+
+	*brightness = (brightness_be[0] << 8) | brightness_be[1];
+
+	return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large);
+
 static int mipi_dsi_drv_probe(struct device *dev)
 {
 	struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
diff --git a/kernel/drivers/gpu/drm/drm_mode_config.c b/kernel/drivers/gpu/drm/drm_mode_config.c
index f1affc1..fad2c11 100644
--- a/kernel/drivers/gpu/drm/drm_mode_config.c
+++ b/kernel/drivers/gpu/drm/drm_mode_config.c
@@ -398,6 +398,8 @@
  */
 int drmm_mode_config_init(struct drm_device *dev)
 {
+	int ret;
+
 	mutex_init(&dev->mode_config.mutex);
 	drm_modeset_lock_init(&dev->mode_config.connection_mutex);
 	mutex_init(&dev->mode_config.idr_mutex);
@@ -419,7 +421,11 @@
 	init_llist_head(&dev->mode_config.connector_free_list);
 	INIT_WORK(&dev->mode_config.connector_free_work, drm_connector_free_work_fn);
 
-	drm_mode_create_standard_properties(dev);
+	ret = drm_mode_create_standard_properties(dev);
+	if (ret) {
+		drm_mode_config_cleanup(dev);
+		return ret;
+	}
 
 	/* Just to be sure */
 	dev->mode_config.num_fb = 0;
diff --git a/kernel/drivers/gpu/drm/drm_panel_orientation_quirks.c b/kernel/drivers/gpu/drm/drm_panel_orientation_quirks.c
index ca0fefe..6106fa7 100644
--- a/kernel/drivers/gpu/drm/drm_panel_orientation_quirks.c
+++ b/kernel/drivers/gpu/drm/drm_panel_orientation_quirks.c
@@ -272,10 +272,29 @@
 		  DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"),
 		},
 		.driver_data = (void *)&lcd1200x1920_rightside_up,
-	}, {	/* Lenovo Yoga Book X90F / X91F / X91L */
+	}, {	/* Lenovo Ideapad D330-10IGL (HD) */
 		.matches = {
-		  /* Non exact match to match all versions */
-		  DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"),
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGL"),
+		},
+		.driver_data = (void *)&lcd800x1280_rightside_up,
+	}, {	/* Lenovo IdeaPad Duet 3 10IGL5 */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Duet 3 10IGL5"),
+		},
+		.driver_data = (void *)&lcd1200x1920_rightside_up,
+	}, {	/* Lenovo Yoga Book X90F / X90L */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"),
+		},
+		.driver_data = (void *)&lcd1200x1920_rightside_up,
+	}, {	/* Lenovo Yoga Book X91F / X91L */
+		.matches = {
+		  /* Non exact match to match F + L versions */
+		  DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"),
 		},
 		.driver_data = (void *)&lcd1200x1920_rightside_up,
 	}, {	/* OneGX1 Pro */
diff --git a/kernel/drivers/gpu/drm/drm_probe_helper.c b/kernel/drivers/gpu/drm/drm_probe_helper.c
index e5432dc..d3f0d04 100644
--- a/kernel/drivers/gpu/drm/drm_probe_helper.c
+++ b/kernel/drivers/gpu/drm/drm_probe_helper.c
@@ -488,8 +488,9 @@
 		 */
 		dev->mode_config.delayed_event = true;
 		if (dev->mode_config.poll_enabled)
-			schedule_delayed_work(&dev->mode_config.output_poll_work,
-					      0);
+			mod_delayed_work(system_wq,
+					 &dev->mode_config.output_poll_work,
+					 0);
 	}
 
 	/* Re-enable polling in case the global poll config changed. */
diff --git a/kernel/drivers/gpu/drm/etnaviv/etnaviv_dump.c b/kernel/drivers/gpu/drm/etnaviv/etnaviv_dump.c
index 706af03..7b57d01 100644
--- a/kernel/drivers/gpu/drm/etnaviv/etnaviv_dump.c
+++ b/kernel/drivers/gpu/drm/etnaviv/etnaviv_dump.c
@@ -125,9 +125,9 @@
 		return;
 	etnaviv_dump_core = false;
 
-	mutex_lock(&gpu->mmu_context->lock);
+	mutex_lock(&submit->mmu_context->lock);
 
-	mmu_size = etnaviv_iommu_dump_size(gpu->mmu_context);
+	mmu_size = etnaviv_iommu_dump_size(submit->mmu_context);
 
 	/* We always dump registers, mmu, ring, hanging cmdbuf and end marker */
 	n_obj = 5;
@@ -157,7 +157,7 @@
 	iter.start = __vmalloc(file_size, GFP_KERNEL | __GFP_NOWARN |
 			__GFP_NORETRY);
 	if (!iter.start) {
-		mutex_unlock(&gpu->mmu_context->lock);
+		mutex_unlock(&submit->mmu_context->lock);
 		dev_warn(gpu->dev, "failed to allocate devcoredump file\n");
 		return;
 	}
@@ -169,18 +169,18 @@
 	memset(iter.hdr, 0, iter.data - iter.start);
 
 	etnaviv_core_dump_registers(&iter, gpu);
-	etnaviv_core_dump_mmu(&iter, gpu->mmu_context, mmu_size);
+	etnaviv_core_dump_mmu(&iter, submit->mmu_context, mmu_size);
 	etnaviv_core_dump_mem(&iter, ETDUMP_BUF_RING, gpu->buffer.vaddr,
 			      gpu->buffer.size,
 			      etnaviv_cmdbuf_get_va(&gpu->buffer,
-					&gpu->mmu_context->cmdbuf_mapping));
+					&submit->mmu_context->cmdbuf_mapping));
 
 	etnaviv_core_dump_mem(&iter, ETDUMP_BUF_CMD,
 			      submit->cmdbuf.vaddr, submit->cmdbuf.size,
 			      etnaviv_cmdbuf_get_va(&submit->cmdbuf,
-					&gpu->mmu_context->cmdbuf_mapping));
+					&submit->mmu_context->cmdbuf_mapping));
 
-	mutex_unlock(&gpu->mmu_context->lock);
+	mutex_unlock(&submit->mmu_context->lock);
 
 	/* Reserve space for the bomap */
 	if (n_bomap_pages) {
diff --git a/kernel/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/kernel/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
index 4aa3426..33974cc 100644
--- a/kernel/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
+++ b/kernel/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
@@ -93,7 +93,15 @@
 static int etnaviv_gem_prime_mmap_obj(struct etnaviv_gem_object *etnaviv_obj,
 		struct vm_area_struct *vma)
 {
-	return dma_buf_mmap(etnaviv_obj->base.dma_buf, vma, 0);
+	int ret;
+
+	ret = dma_buf_mmap(etnaviv_obj->base.dma_buf, vma, 0);
+	if (!ret) {
+		/* Drop the reference acquired by drm_gem_mmap_obj(). */
+		drm_gem_object_put(&etnaviv_obj->base);
+	}
+
+	return ret;
 }
 
 static const struct etnaviv_gem_ops etnaviv_gem_prime_ops = {
diff --git a/kernel/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/kernel/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index 2520b7d..f3281d5 100644
--- a/kernel/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/kernel/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -408,6 +408,12 @@
 	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 @@
 				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 |
diff --git a/kernel/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/kernel/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
index 9ba2fe4..44fbc0a 100644
--- a/kernel/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
+++ b/kernel/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
@@ -80,10 +80,10 @@
 		return -EINVAL;
 
 	for_each_sgtable_dma_sg(sgt, sg, i) {
-		u32 pa = sg_dma_address(sg) - sg->offset;
+		phys_addr_t pa = sg_dma_address(sg) - sg->offset;
 		size_t bytes = sg_dma_len(sg) + sg->offset;
 
-		VERB("map[%d]: %08x %08x(%zx)", i, iova, pa, bytes);
+		VERB("map[%d]: %08x %pap(%zx)", i, iova, &pa, bytes);
 
 		ret = etnaviv_context_map(context, da, pa, bytes, prot);
 		if (ret)
diff --git a/kernel/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/kernel/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index 1f79bc2..c277d2f 100644
--- a/kernel/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/kernel/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -775,8 +775,8 @@
 			return irq;
 		}
 	}
-	irq_set_status_flags(irq, IRQ_NOAUTOEN);
-	ret = devm_request_irq(ctx->dev, irq, handler, flags, "drm_decon", ctx);
+	ret = devm_request_irq(ctx->dev, irq, handler,
+			       flags | IRQF_NO_AUTOEN, "drm_decon", ctx);
 	if (ret < 0) {
 		dev_err(ctx->dev, "IRQ %s request failed\n", name);
 		return ret;
diff --git a/kernel/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/kernel/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 1c03485..de9fadc 100644
--- a/kernel/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/kernel/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -39,13 +39,12 @@
 	if (exynos_crtc->ops->atomic_disable)
 		exynos_crtc->ops->atomic_disable(exynos_crtc);
 
+	spin_lock_irq(&crtc->dev->event_lock);
 	if (crtc->state->event && !crtc->state->active) {
-		spin_lock_irq(&crtc->dev->event_lock);
 		drm_crtc_send_vblank_event(crtc, crtc->state->event);
-		spin_unlock_irq(&crtc->dev->event_lock);
-
 		crtc->state->event = NULL;
 	}
+	spin_unlock_irq(&crtc->dev->event_lock);
 }
 
 static int exynos_crtc_atomic_check(struct drm_crtc *crtc,
diff --git a/kernel/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/kernel/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 5b9666f..afb03de 100644
--- a/kernel/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/kernel/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1353,10 +1353,9 @@
 	}
 
 	te_gpio_irq = gpio_to_irq(dsi->te_gpio);
-	irq_set_status_flags(te_gpio_irq, IRQ_NOAUTOEN);
 
 	ret = request_threaded_irq(te_gpio_irq, exynos_dsi_te_irq_handler, NULL,
-					IRQF_TRIGGER_RISING, "TE", dsi);
+				   IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN, "TE", dsi);
 	if (ret) {
 		dev_err(dsi->dev, "request interrupt failed with %d\n", ret);
 		gpio_free(dsi->te_gpio);
@@ -1802,9 +1801,9 @@
 	if (dsi->irq < 0)
 		return dsi->irq;
 
-	irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN);
 	ret = devm_request_threaded_irq(dev, dsi->irq, NULL,
-					exynos_dsi_irq, IRQF_ONESHOT,
+					exynos_dsi_irq,
+					IRQF_ONESHOT | IRQF_NO_AUTOEN,
 					dev_name(dev), dsi);
 	if (ret) {
 		dev_err(dev, "failed to request dsi irq\n");
diff --git a/kernel/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/kernel/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 967a5cd..81211a9 100644
--- a/kernel/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/kernel/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -1332,7 +1332,7 @@
 	/* Let the runqueue know that there is work to do. */
 	queue_work(g2d->g2d_workq, &g2d->runqueue_work);
 
-	if (runqueue_node->async)
+	if (req->async)
 		goto out;
 
 	wait_for_completion(&runqueue_node->complete);
diff --git a/kernel/drivers/gpu/drm/exynos/exynos_drm_g2d.h b/kernel/drivers/gpu/drm/exynos/exynos_drm_g2d.h
index 74ea3c2..1a5ae78 100644
--- a/kernel/drivers/gpu/drm/exynos/exynos_drm_g2d.h
+++ b/kernel/drivers/gpu/drm/exynos/exynos_drm_g2d.h
@@ -34,11 +34,11 @@
 	return -ENODEV;
 }
 
-int g2d_open(struct drm_device *drm_dev, struct drm_file *file)
+static inline int g2d_open(struct drm_device *drm_dev, struct drm_file *file)
 {
 	return 0;
 }
 
-void g2d_close(struct drm_device *drm_dev, struct drm_file *file)
+static inline void g2d_close(struct drm_device *drm_dev, struct drm_file *file)
 { }
 #endif
diff --git a/kernel/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/kernel/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index e5662bd..e96436e 100644
--- a/kernel/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/kernel/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -468,8 +468,6 @@
 	if (ctx->raw_edid != (struct edid *)fake_edid_info) {
 		kfree(ctx->raw_edid);
 		ctx->raw_edid = NULL;
-
-		return -EINVAL;
 	}
 
 	component_del(&pdev->dev, &vidi_component_ops);
diff --git a/kernel/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c b/kernel/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
index 4d4a715..2c2b923 100644
--- a/kernel/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
+++ b/kernel/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
@@ -60,8 +60,9 @@
 	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;
diff --git a/kernel/drivers/gpu/drm/i915/display/intel_bw.c b/kernel/drivers/gpu/drm/i915/display/intel_bw.c
index bd06040..4b5a30a 100644
--- a/kernel/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/kernel/drivers/gpu/drm/i915/display/intel_bw.c
@@ -20,75 +20,8 @@
 struct intel_qgv_info {
 	struct intel_qgv_point points[I915_NUM_QGV_POINTS];
 	u8 num_points;
-	u8 num_channels;
 	u8 t_bl;
-	enum intel_dram_type dram_type;
 };
-
-static int icl_pcode_read_mem_global_info(struct drm_i915_private *dev_priv,
-					  struct intel_qgv_info *qi)
-{
-	u32 val = 0;
-	int ret;
-
-	ret = sandybridge_pcode_read(dev_priv,
-				     ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
-				     ICL_PCODE_MEM_SS_READ_GLOBAL_INFO,
-				     &val, NULL);
-	if (ret)
-		return ret;
-
-	if (IS_GEN(dev_priv, 12)) {
-		switch (val & 0xf) {
-		case 0:
-			qi->dram_type = INTEL_DRAM_DDR4;
-			break;
-		case 3:
-			qi->dram_type = INTEL_DRAM_LPDDR4;
-			break;
-		case 4:
-			qi->dram_type = INTEL_DRAM_DDR3;
-			break;
-		case 5:
-			qi->dram_type = INTEL_DRAM_LPDDR3;
-			break;
-		default:
-			MISSING_CASE(val & 0xf);
-			break;
-		}
-	} else if (IS_GEN(dev_priv, 11)) {
-		switch (val & 0xf) {
-		case 0:
-			qi->dram_type = INTEL_DRAM_DDR4;
-			break;
-		case 1:
-			qi->dram_type = INTEL_DRAM_DDR3;
-			break;
-		case 2:
-			qi->dram_type = INTEL_DRAM_LPDDR3;
-			break;
-		case 3:
-			qi->dram_type = INTEL_DRAM_LPDDR4;
-			break;
-		default:
-			MISSING_CASE(val & 0xf);
-			break;
-		}
-	} else {
-		MISSING_CASE(INTEL_GEN(dev_priv));
-		qi->dram_type = INTEL_DRAM_LPDDR3; /* Conservative default */
-	}
-
-	qi->num_channels = (val & 0xf0) >> 4;
-	qi->num_points = (val & 0xf00) >> 8;
-
-	if (IS_GEN(dev_priv, 12))
-		qi->t_bl = qi->dram_type == INTEL_DRAM_DDR4 ? 4 : 16;
-	else if (IS_GEN(dev_priv, 11))
-		qi->t_bl = qi->dram_type == INTEL_DRAM_DDR4 ? 4 : 8;
-
-	return 0;
-}
 
 static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv,
 					 struct intel_qgv_point *sp,
@@ -139,11 +72,15 @@
 static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
 			      struct intel_qgv_info *qi)
 {
+	const struct dram_info *dram_info = &dev_priv->dram_info;
 	int i, ret;
 
-	ret = icl_pcode_read_mem_global_info(dev_priv, qi);
-	if (ret)
-		return ret;
+	qi->num_points = dram_info->num_qgv_points;
+
+	if (IS_GEN(dev_priv, 12))
+		qi->t_bl = dev_priv->dram_info.type == INTEL_DRAM_DDR4 ? 4 : 16;
+	else if (IS_GEN(dev_priv, 11))
+		qi->t_bl = dev_priv->dram_info.type == INTEL_DRAM_DDR4 ? 4 : 8;
 
 	if (drm_WARN_ON(&dev_priv->drm,
 			qi->num_points > ARRAY_SIZE(qi->points)))
@@ -209,7 +146,7 @@
 {
 	struct intel_qgv_info qi = {};
 	bool is_y_tile = true; /* assume y tile may be used */
-	int num_channels;
+	int num_channels = dev_priv->dram_info.num_channels;
 	int deinterleave;
 	int ipqdepth, ipqdepthpch;
 	int dclk_max;
@@ -222,7 +159,6 @@
 			    "Failed to get memory subsystem information, ignoring bandwidth limits");
 		return ret;
 	}
-	num_channels = qi.num_channels;
 
 	deinterleave = DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2);
 	dclk_max = icl_sagv_max_dclk(&qi);
diff --git a/kernel/drivers/gpu/drm/i915/display/intel_display.c b/kernel/drivers/gpu/drm/i915/display/intel_display.c
index 45c2556..9a06bd8 100644
--- a/kernel/drivers/gpu/drm/i915/display/intel_display.c
+++ b/kernel/drivers/gpu/drm/i915/display/intel_display.c
@@ -5844,7 +5844,7 @@
 		num_encoders++;
 	}
 
-	drm_WARN(encoder->base.dev, num_encoders != 1,
+	drm_WARN(state->base.dev, num_encoders != 1,
 		 "%d encoders for pipe %c\n",
 		 num_encoders, pipe_name(crtc->pipe));
 
@@ -13335,6 +13335,7 @@
 	 * only fields that are know to not cause problems are preserved. */
 
 	saved_state->uapi = crtc_state->uapi;
+	saved_state->inherited = crtc_state->inherited;
 	saved_state->scaler_state = crtc_state->scaler_state;
 	saved_state->shared_dpll = crtc_state->shared_dpll;
 	saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
diff --git a/kernel/drivers/gpu/drm/i915/display/intel_dp.c b/kernel/drivers/gpu/drm/i915/display/intel_dp.c
index 1c1931f..7f633f8 100644
--- a/kernel/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/kernel/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2281,6 +2281,11 @@
 		pipe_config->dsc.slice_count =
 			drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
 							true);
+		if (!pipe_config->dsc.slice_count) {
+			drm_dbg_kms(&dev_priv->drm, "Unsupported Slice Count %d\n",
+				    pipe_config->dsc.slice_count);
+			return -EINVAL;
+		}
 	} else {
 		u16 dsc_max_output_bpp;
 		u8 dsc_dp_slice_count;
diff --git a/kernel/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/kernel/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index 8777d35..117ea44 100644
--- a/kernel/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/kernel/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -133,9 +133,9 @@
 		return ffs(intel_dsi->ports) - 1;
 
 	if (seq_port) {
-		if (intel_dsi->ports & PORT_B)
+		if (intel_dsi->ports & BIT(PORT_B))
 			return PORT_B;
-		else if (intel_dsi->ports & PORT_C)
+		else if (intel_dsi->ports & BIT(PORT_C))
 			return PORT_C;
 	}
 
diff --git a/kernel/drivers/gpu/drm/i915/display/intel_quirks.c b/kernel/drivers/gpu/drm/i915/display/intel_quirks.c
index 8eb1842..b4e74c8 100644
--- a/kernel/drivers/gpu/drm/i915/display/intel_quirks.c
+++ b/kernel/drivers/gpu/drm/i915/display/intel_quirks.c
@@ -159,6 +159,8 @@
 	/* ECS Liva Q2 */
 	{ 0x3185, 0x1019, 0xa94d, quirk_increase_ddi_disabled_time },
 	{ 0x3184, 0x1019, 0xa94d, quirk_increase_ddi_disabled_time },
+	/* HP Notebook - 14-r206nv */
+	{ 0x0f31, 0x103c, 0x220f, quirk_invert_brightness },
 };
 
 void intel_init_quirks(struct drm_i915_private *i915)
diff --git a/kernel/drivers/gpu/drm/i915/gem/i915_gem_tiling.c b/kernel/drivers/gpu/drm/i915/gem/i915_gem_tiling.c
index ffcaee7..545fa70 100644
--- a/kernel/drivers/gpu/drm/i915/gem/i915_gem_tiling.c
+++ b/kernel/drivers/gpu/drm/i915/gem/i915_gem_tiling.c
@@ -296,10 +296,6 @@
 	spin_unlock(&obj->vma.lock);
 
 	obj->tiling_and_stride = tiling | stride;
-	i915_gem_object_unlock(obj);
-
-	/* Force the fence to be reacquired for GTT access */
-	i915_gem_object_release_mmap_gtt(obj);
 
 	/* Try to preallocate memory required to save swizzling on put-pages */
 	if (i915_gem_object_needs_bit17_swizzle(obj)) {
@@ -312,6 +308,11 @@
 		obj->bit_17 = NULL;
 	}
 
+	i915_gem_object_unlock(obj);
+
+	/* Force the fence to be reacquired for GTT access */
+	i915_gem_object_release_mmap_gtt(obj);
+
 	return 0;
 }
 
diff --git a/kernel/drivers/gpu/drm/i915/gt/intel_reset.c b/kernel/drivers/gpu/drm/i915/gt/intel_reset.c
index ac36b67..00b5912 100644
--- a/kernel/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/kernel/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -289,6 +289,7 @@
 static int gen6_hw_domain_reset(struct intel_gt *gt, u32 hw_domain_mask)
 {
 	struct intel_uncore *uncore = gt->uncore;
+	int loops = 2;
 	int err;
 
 	/*
@@ -296,18 +297,39 @@
 	 * for fifo space for the write or forcewake the chip for
 	 * the read
 	 */
-	intel_uncore_write_fw(uncore, GEN6_GDRST, hw_domain_mask);
+	do {
+		intel_uncore_write_fw(uncore, GEN6_GDRST, hw_domain_mask);
 
-	/* Wait for the device to ack the reset requests */
-	err = __intel_wait_for_register_fw(uncore,
-					   GEN6_GDRST, hw_domain_mask, 0,
-					   500, 0,
-					   NULL);
+		/*
+		 * Wait for the device to ack the reset requests.
+		 *
+		 * On some platforms, e.g. Jasperlake, we see that the
+		 * engine register state is not cleared until shortly after
+		 * GDRST reports completion, causing a failure as we try
+		 * to immediately resume while the internal state is still
+		 * in flux. If we immediately repeat the reset, the second
+		 * reset appears to serialise with the first, and since
+		 * it is a no-op, the registers should retain their reset
+		 * value. However, there is still a concern that upon
+		 * leaving the second reset, the internal engine state
+		 * is still in flux and not ready for resuming.
+		 */
+		err = __intel_wait_for_register_fw(uncore, GEN6_GDRST,
+						   hw_domain_mask, 0,
+						   2000, 0,
+						   NULL);
+	} while (err == 0 && --loops);
 	if (err)
 		drm_dbg(&gt->i915->drm,
 			"Wait for 0x%08x engines reset failed\n",
 			hw_domain_mask);
 
+	/*
+	 * As we have observed that the engine state is still volatile
+	 * after GDRST is acked, impose a small delay to let everything settle.
+	 */
+	udelay(50);
+
 	return err;
 }
 
diff --git a/kernel/drivers/gpu/drm/i915/gt/intel_ring.c b/kernel/drivers/gpu/drm/i915/gt/intel_ring.c
index 4034a4b..de67b27 100644
--- a/kernel/drivers/gpu/drm/i915/gt/intel_ring.c
+++ b/kernel/drivers/gpu/drm/i915/gt/intel_ring.c
@@ -49,7 +49,7 @@
 	if (unlikely(ret))
 		goto err_unpin;
 
-	if (i915_vma_is_map_and_fenceable(vma))
+	if (i915_vma_is_map_and_fenceable(vma) && !HAS_LLC(vma->vm->i915))
 		addr = (void __force *)i915_vma_pin_iomap(vma);
 	else
 		addr = i915_gem_object_pin_map(vma->obj,
@@ -91,7 +91,7 @@
 		return;
 
 	i915_vma_unset_ggtt_write(vma);
-	if (i915_vma_is_map_and_fenceable(vma))
+	if (i915_vma_is_map_and_fenceable(vma) && !HAS_LLC(vma->vm->i915))
 		i915_vma_unpin_iomap(vma);
 	else
 		i915_gem_object_unpin_map(vma->obj);
@@ -108,7 +108,7 @@
 	struct i915_vma *vma;
 
 	obj = ERR_PTR(-ENODEV);
-	if (i915_ggtt_has_aperture(ggtt))
+	if (i915_ggtt_has_aperture(ggtt) && !HAS_LLC(i915))
 		obj = i915_gem_object_create_stolen(i915, size);
 	if (IS_ERR(obj))
 		obj = i915_gem_object_create_internal(i915, size);
diff --git a/kernel/drivers/gpu/drm/i915/gt/intel_workarounds.c b/kernel/drivers/gpu/drm/i915/gt/intel_workarounds.c
index 4a3bde7..ae5cf2b 100644
--- a/kernel/drivers/gpu/drm/i915/gt/intel_workarounds.c
+++ b/kernel/drivers/gpu/drm/i915/gt/intel_workarounds.c
@@ -1212,6 +1212,22 @@
 		    GAMT_CHKN_BIT_REG,
 		    GAMT_CHKN_DISABLE_L3_COH_PIPE);
 
+	/*
+	 * Wa_1408615072:icl,ehl  (vsunit)
+	 * Wa_1407596294:icl,ehl  (hsunit)
+	 */
+	wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE,
+		    VSUNIT_CLKGATE_DIS | HSUNIT_CLKGATE_DIS);
+
+	/* Wa_1407352427:icl,ehl */
+	wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE2,
+		    PSDUNIT_CLKGATE_DIS);
+
+	/* Wa_1406680159:icl,ehl */
+	wa_write_or(wal,
+		    SUBSLICE_UNIT_LEVEL_CLKGATE,
+		    GWUNIT_CLKGATE_DIS);
+
 	/* Wa_1607087056:icl,ehl,jsl */
 	if (IS_ICELAKE(i915) ||
 	    IS_EHL_REVID(i915, EHL_REVID_A0, EHL_REVID_A0)) {
@@ -1815,22 +1831,6 @@
 		/* WaEnable32PlaneMode:icl */
 		wa_masked_en(wal, GEN9_CSFE_CHICKEN1_RCS,
 			     GEN11_ENABLE_32_PLANE_MODE);
-
-		/*
-		 * Wa_1408615072:icl,ehl  (vsunit)
-		 * Wa_1407596294:icl,ehl  (hsunit)
-		 */
-		wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE,
-			    VSUNIT_CLKGATE_DIS | HSUNIT_CLKGATE_DIS);
-
-		/* Wa_1407352427:icl,ehl */
-		wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE2,
-			    PSDUNIT_CLKGATE_DIS);
-
-		/* Wa_1406680159:icl,ehl */
-		wa_write_or(wal,
-			    SUBSLICE_UNIT_LEVEL_CLKGATE,
-			    GWUNIT_CLKGATE_DIS);
 
 		/*
 		 * Wa_1408767742:icl[a2..forever],ehl[all]
diff --git a/kernel/drivers/gpu/drm/i915/gvt/debugfs.c b/kernel/drivers/gpu/drm/i915/gvt/debugfs.c
index 62e6a14..9468d53 100644
--- a/kernel/drivers/gpu/drm/i915/gvt/debugfs.c
+++ b/kernel/drivers/gpu/drm/i915/gvt/debugfs.c
@@ -175,8 +175,13 @@
  */
 void intel_gvt_debugfs_remove_vgpu(struct intel_vgpu *vgpu)
 {
-	debugfs_remove_recursive(vgpu->debugfs);
-	vgpu->debugfs = NULL;
+	struct intel_gvt *gvt = vgpu->gvt;
+	struct drm_minor *minor = gvt->gt->i915->drm.primary;
+
+	if (minor->debugfs_root && gvt->debugfs_root) {
+		debugfs_remove_recursive(vgpu->debugfs);
+		vgpu->debugfs = NULL;
+	}
 }
 
 /**
@@ -199,6 +204,10 @@
  */
 void intel_gvt_debugfs_clean(struct intel_gvt *gvt)
 {
-	debugfs_remove_recursive(gvt->debugfs_root);
-	gvt->debugfs_root = NULL;
+	struct drm_minor *minor = gvt->gt->i915->drm.primary;
+
+	if (minor->debugfs_root) {
+		debugfs_remove_recursive(gvt->debugfs_root);
+		gvt->debugfs_root = NULL;
+	}
 }
diff --git a/kernel/drivers/gpu/drm/i915/gvt/gtt.c b/kernel/drivers/gpu/drm/i915/gvt/gtt.c
index a3a4305..0d31a0d 100644
--- a/kernel/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/kernel/drivers/gpu/drm/i915/gvt/gtt.c
@@ -636,8 +636,17 @@
 		struct intel_gvt_gtt_entry *entry, unsigned long index)
 {
 	struct intel_gvt_gtt_pte_ops *pte_ops = mm->vgpu->gvt->gtt.pte_ops;
+	unsigned long offset = index;
 
 	GEM_BUG_ON(mm->type != INTEL_GVT_MM_GGTT);
+
+	if (vgpu_gmadr_is_aperture(mm->vgpu, index << I915_GTT_PAGE_SHIFT)) {
+		offset -= (vgpu_aperture_gmadr_base(mm->vgpu) >> PAGE_SHIFT);
+		mm->ggtt_mm.host_ggtt_aperture[offset] = entry->val64;
+	} else if (vgpu_gmadr_is_hidden(mm->vgpu, index << I915_GTT_PAGE_SHIFT)) {
+		offset -= (vgpu_hidden_gmadr_base(mm->vgpu) >> PAGE_SHIFT);
+		mm->ggtt_mm.host_ggtt_hidden[offset] = entry->val64;
+	}
 
 	pte_ops->set_entry(NULL, entry, index, false, 0, mm->vgpu);
 }
@@ -1192,10 +1201,8 @@
 	for_each_shadow_entry(sub_spt, &sub_se, sub_index) {
 		ret = intel_gvt_hypervisor_dma_map_guest_page(vgpu,
 				start_gfn + sub_index, PAGE_SIZE, &dma_addr);
-		if (ret) {
-			ppgtt_invalidate_spt(spt);
-			return ret;
-		}
+		if (ret)
+			goto err;
 		sub_se.val64 = se->val64;
 
 		/* Copy the PAT field from PDE. */
@@ -1214,6 +1221,17 @@
 	ops->set_pfn(se, sub_spt->shadow_page.mfn);
 	ppgtt_set_shadow_entry(spt, se, index);
 	return 0;
+err:
+	/* Cancel the existing addess mappings of DMA addr. */
+	for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) {
+		gvt_vdbg_mm("invalidate 4K entry\n");
+		ppgtt_invalidate_pte(sub_spt, &sub_se);
+	}
+	/* Release the new allocated spt. */
+	trace_spt_change(sub_spt->vgpu->id, "release", sub_spt,
+		sub_spt->guest_page.gfn, sub_spt->shadow_page.type);
+	ppgtt_free_spt(sub_spt);
+	return ret;
 }
 
 static int split_64KB_gtt_entry(struct intel_vgpu *vgpu,
@@ -1944,6 +1962,21 @@
 		return ERR_PTR(-ENOMEM);
 	}
 
+	mm->ggtt_mm.host_ggtt_aperture = vzalloc((vgpu_aperture_sz(vgpu) >> PAGE_SHIFT) * sizeof(u64));
+	if (!mm->ggtt_mm.host_ggtt_aperture) {
+		vfree(mm->ggtt_mm.virtual_ggtt);
+		vgpu_free_mm(mm);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	mm->ggtt_mm.host_ggtt_hidden = vzalloc((vgpu_hidden_sz(vgpu) >> PAGE_SHIFT) * sizeof(u64));
+	if (!mm->ggtt_mm.host_ggtt_hidden) {
+		vfree(mm->ggtt_mm.host_ggtt_aperture);
+		vfree(mm->ggtt_mm.virtual_ggtt);
+		vgpu_free_mm(mm);
+		return ERR_PTR(-ENOMEM);
+	}
+
 	return mm;
 }
 
@@ -1971,6 +2004,8 @@
 		invalidate_ppgtt_mm(mm);
 	} else {
 		vfree(mm->ggtt_mm.virtual_ggtt);
+		vfree(mm->ggtt_mm.host_ggtt_aperture);
+		vfree(mm->ggtt_mm.host_ggtt_hidden);
 	}
 
 	vgpu_free_mm(mm);
@@ -2836,19 +2871,39 @@
 }
 
 /**
- * intel_vgpu_reset_gtt - reset the all GTT related status
- * @vgpu: a vGPU
+ * intel_gvt_restore_ggtt - restore all vGPU's ggtt entries
+ * @gvt: intel gvt device
  *
- * This function is called from vfio core to reset reset all
- * GTT related status, including GGTT, PPGTT, scratch page.
+ * This function is called at driver resume stage to restore
+ * GGTT entries of every vGPU.
  *
  */
-void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu)
+void intel_gvt_restore_ggtt(struct intel_gvt *gvt)
 {
-	/* Shadow pages are only created when there is no page
-	 * table tracking data, so remove page tracking data after
-	 * removing the shadow pages.
-	 */
-	intel_vgpu_destroy_all_ppgtt_mm(vgpu);
-	intel_vgpu_reset_ggtt(vgpu, true);
+	struct intel_vgpu *vgpu;
+	struct intel_vgpu_mm *mm;
+	int id;
+	gen8_pte_t pte;
+	u32 idx, num_low, num_hi, offset;
+
+	/* Restore dirty host ggtt for all vGPUs */
+	idr_for_each_entry(&(gvt)->vgpu_idr, vgpu, id) {
+		mm = vgpu->gtt.ggtt_mm;
+
+		num_low = vgpu_aperture_sz(vgpu) >> PAGE_SHIFT;
+		offset = vgpu_aperture_gmadr_base(vgpu) >> PAGE_SHIFT;
+		for (idx = 0; idx < num_low; idx++) {
+			pte = mm->ggtt_mm.host_ggtt_aperture[idx];
+			if (pte & _PAGE_PRESENT)
+				write_pte64(vgpu->gvt->gt->ggtt, offset + idx, pte);
+		}
+
+		num_hi = vgpu_hidden_sz(vgpu) >> PAGE_SHIFT;
+		offset = vgpu_hidden_gmadr_base(vgpu) >> PAGE_SHIFT;
+		for (idx = 0; idx < num_hi; idx++) {
+			pte = mm->ggtt_mm.host_ggtt_hidden[idx];
+			if (pte & _PAGE_PRESENT)
+				write_pte64(vgpu->gvt->gt->ggtt, offset + idx, pte);
+		}
+	}
 }
diff --git a/kernel/drivers/gpu/drm/i915/gvt/gtt.h b/kernel/drivers/gpu/drm/i915/gvt/gtt.h
index 52d0d88..89ffb52 100644
--- a/kernel/drivers/gpu/drm/i915/gvt/gtt.h
+++ b/kernel/drivers/gpu/drm/i915/gvt/gtt.h
@@ -164,6 +164,9 @@
 		} ppgtt_mm;
 		struct {
 			void *virtual_ggtt;
+			/* Save/restore for PM */
+			u64 *host_ggtt_aperture;
+			u64 *host_ggtt_hidden;
 			struct list_head partial_pte_list;
 		} ggtt_mm;
 	};
@@ -212,7 +215,6 @@
 void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu);
 
 int intel_gvt_init_gtt(struct intel_gvt *gvt);
-void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu);
 void intel_gvt_clean_gtt(struct intel_gvt *gvt);
 
 struct intel_vgpu_mm *intel_gvt_find_ppgtt_mm(struct intel_vgpu *vgpu,
@@ -280,5 +282,6 @@
 	unsigned int off, void *p_data, unsigned int bytes);
 
 void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu);
+void intel_gvt_restore_ggtt(struct intel_gvt *gvt);
 
 #endif /* _GVT_GTT_H_ */
diff --git a/kernel/drivers/gpu/drm/i915/gvt/gvt.c b/kernel/drivers/gpu/drm/i915/gvt/gvt.c
index 5c9ef8e..87f22a8 100644
--- a/kernel/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/kernel/drivers/gpu/drm/i915/gvt/gvt.c
@@ -406,6 +406,15 @@
 }
 
 int
+intel_gvt_pm_resume(struct intel_gvt *gvt)
+{
+	intel_gvt_restore_fence(gvt);
+	intel_gvt_restore_mmio(gvt);
+	intel_gvt_restore_ggtt(gvt);
+	return 0;
+}
+
+int
 intel_gvt_register_hypervisor(struct intel_gvt_mpt *m)
 {
 	int ret;
diff --git a/kernel/drivers/gpu/drm/i915/gvt/gvt.h b/kernel/drivers/gpu/drm/i915/gvt/gvt.h
index a81cf0f..b3d6355 100644
--- a/kernel/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/kernel/drivers/gpu/drm/i915/gvt/gvt.h
@@ -255,6 +255,8 @@
 #define F_CMD_ACCESS	(1 << 3)
 /* This reg has been accessed by a VM */
 #define F_ACCESSED	(1 << 4)
+/* This reg requires save & restore during host PM suspend/resume */
+#define F_PM_SAVE	(1 << 5)
 /* This reg could be accessed by unaligned address */
 #define F_UNALIGN	(1 << 6)
 /* This reg is in GVT's mmio save-restor list and in hardware
@@ -685,6 +687,7 @@
 void intel_gvt_debugfs_init(struct intel_gvt *gvt);
 void intel_gvt_debugfs_clean(struct intel_gvt *gvt);
 
+int intel_gvt_pm_resume(struct intel_gvt *gvt);
 
 #include "trace.h"
 #include "mpt.h"
diff --git a/kernel/drivers/gpu/drm/i915/gvt/handlers.c b/kernel/drivers/gpu/drm/i915/gvt/handlers.c
index 606e6c3..55ce7aa 100644
--- a/kernel/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/kernel/drivers/gpu/drm/i915/gvt/handlers.c
@@ -3135,9 +3135,10 @@
 	MMIO_DFH(TRVATTL3PTRDW(2), D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
 	MMIO_DFH(TRVATTL3PTRDW(3), D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
 	MMIO_DFH(TRVADR, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
-	MMIO_DFH(TRTTE, D_SKL_PLUS, F_CMD_ACCESS,
-		NULL, gen9_trtte_write);
-	MMIO_DH(_MMIO(0x4dfc), D_SKL_PLUS, NULL, gen9_trtt_chicken_write);
+	MMIO_DFH(TRTTE, D_SKL_PLUS, F_CMD_ACCESS | F_PM_SAVE,
+		 NULL, gen9_trtte_write);
+	MMIO_DFH(_MMIO(0x4dfc), D_SKL_PLUS, F_PM_SAVE,
+		 NULL, gen9_trtt_chicken_write);
 
 	MMIO_D(_MMIO(0x46430), D_SKL_PLUS);
 
@@ -3686,3 +3687,40 @@
 		intel_vgpu_default_mmio_read(vgpu, offset, pdata, bytes) :
 		intel_vgpu_default_mmio_write(vgpu, offset, pdata, bytes);
 }
+
+void intel_gvt_restore_fence(struct intel_gvt *gvt)
+{
+	struct intel_vgpu *vgpu;
+	int i, id;
+
+	idr_for_each_entry(&(gvt)->vgpu_idr, vgpu, id) {
+		mmio_hw_access_pre(gvt->gt);
+		for (i = 0; i < vgpu_fence_sz(vgpu); i++)
+			intel_vgpu_write_fence(vgpu, i, vgpu_vreg64(vgpu, fence_num_to_offset(i)));
+		mmio_hw_access_post(gvt->gt);
+	}
+}
+
+static inline int mmio_pm_restore_handler(struct intel_gvt *gvt,
+					  u32 offset, void *data)
+{
+	struct intel_vgpu *vgpu = data;
+	struct drm_i915_private *dev_priv = gvt->gt->i915;
+
+	if (gvt->mmio.mmio_attribute[offset >> 2] & F_PM_SAVE)
+		I915_WRITE(_MMIO(offset), vgpu_vreg(vgpu, offset));
+
+	return 0;
+}
+
+void intel_gvt_restore_mmio(struct intel_gvt *gvt)
+{
+	struct intel_vgpu *vgpu;
+	int id;
+
+	idr_for_each_entry(&(gvt)->vgpu_idr, vgpu, id) {
+		mmio_hw_access_pre(gvt->gt);
+		intel_gvt_for_each_tracked_mmio(gvt, mmio_pm_restore_handler, vgpu);
+		mmio_hw_access_post(gvt->gt);
+	}
+}
diff --git a/kernel/drivers/gpu/drm/i915/gvt/mmio.h b/kernel/drivers/gpu/drm/i915/gvt/mmio.h
index cc48126..9e862dc 100644
--- a/kernel/drivers/gpu/drm/i915/gvt/mmio.h
+++ b/kernel/drivers/gpu/drm/i915/gvt/mmio.h
@@ -104,4 +104,8 @@
 
 int intel_vgpu_mask_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
 				  void *p_data, unsigned int bytes);
+
+void intel_gvt_restore_fence(struct intel_gvt *gvt);
+void intel_gvt_restore_mmio(struct intel_gvt *gvt);
+
 #endif
diff --git a/kernel/drivers/gpu/drm/i915/gvt/scheduler.c b/kernel/drivers/gpu/drm/i915/gvt/scheduler.c
index aed2ef6..2bb6203 100644
--- a/kernel/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/kernel/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -647,6 +647,7 @@
 
 	if (workload->shadow_mm->type != INTEL_GVT_MM_PPGTT ||
 	    !workload->shadow_mm->ppgtt_mm.shadowed) {
+		intel_vgpu_unpin_mm(workload->shadow_mm);
 		gvt_vgpu_err("workload shadow ppgtt isn't ready\n");
 		return -EINVAL;
 	}
diff --git a/kernel/drivers/gpu/drm/i915/i915_active.c b/kernel/drivers/gpu/drm/i915/i915_active.c
index c4c2d24..aba811c 100644
--- a/kernel/drivers/gpu/drm/i915/i915_active.c
+++ b/kernel/drivers/gpu/drm/i915/i915_active.c
@@ -96,8 +96,7 @@
 static void debug_active_activate(struct i915_active *ref)
 {
 	lockdep_assert_held(&ref->tree_lock);
-	if (!atomic_read(&ref->count)) /* before the first inc */
-		debug_object_activate(ref, &active_debug_desc);
+	debug_object_activate(ref, &active_debug_desc);
 }
 
 static void debug_active_deactivate(struct i915_active *ref)
@@ -432,8 +431,7 @@
 	 * we can use it to substitute for the pending idle-barrer
 	 * request that we want to emit on the kernel_context.
 	 */
-	__active_del_barrier(ref, node_from_active(active));
-	return true;
+	return __active_del_barrier(ref, node_from_active(active));
 }
 
 int i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence)
@@ -446,18 +444,24 @@
 	if (err)
 		return err;
 
-	active = active_instance(ref, idx);
-	if (!active) {
-		err = -ENOMEM;
-		goto out;
-	}
+	do {
+		active = active_instance(ref, idx);
+		if (!active) {
+			err = -ENOMEM;
+			goto out;
+		}
 
-	if (replace_barrier(ref, active)) {
-		RCU_INIT_POINTER(active->fence, NULL);
-		atomic_dec(&ref->count);
-	}
-	if (!__i915_active_fence_set(active, fence))
+		if (replace_barrier(ref, active)) {
+			RCU_INIT_POINTER(active->fence, NULL);
+			atomic_dec(&ref->count);
+		}
+	} while (unlikely(is_barrier(active)));
+
+	fence = __i915_active_fence_set(active, fence);
+	if (!fence)
 		__i915_active_acquire(ref);
+	else
+		dma_fence_put(fence);
 
 out:
 	i915_active_release(ref);
@@ -476,13 +480,9 @@
 		return NULL;
 	}
 
-	rcu_read_lock();
 	prev = __i915_active_fence_set(active, fence);
-	if (prev)
-		prev = dma_fence_get_rcu(prev);
-	else
+	if (!prev)
 		__i915_active_acquire(ref);
-	rcu_read_unlock();
 
 	return prev;
 }
@@ -1049,10 +1049,11 @@
  *
  * Records the new @fence as the last active fence along its timeline in
  * this active tracker, moving the tracking callbacks from the previous
- * fence onto this one. Returns the previous fence (if not already completed),
- * which the caller must ensure is executed before the new fence. To ensure
- * that the order of fences within the timeline of the i915_active_fence is
- * understood, it should be locked by the caller.
+ * fence onto this one. Gets and returns a reference to the previous fence
+ * (if not already completed), which the caller must put after making sure
+ * that it is executed before the new fence. To ensure that the order of
+ * fences within the timeline of the i915_active_fence is understood, it
+ * should be locked by the caller.
  */
 struct dma_fence *
 __i915_active_fence_set(struct i915_active_fence *active,
@@ -1061,7 +1062,23 @@
 	struct dma_fence *prev;
 	unsigned long flags;
 
-	if (fence == rcu_access_pointer(active->fence))
+	/*
+	 * In case of fences embedded in i915_requests, their memory is
+	 * SLAB_FAILSAFE_BY_RCU, then it can be reused right after release
+	 * by new requests.  Then, there is a risk of passing back a pointer
+	 * to a new, completely unrelated fence that reuses the same memory
+	 * while tracked under a different active tracker.  Combined with i915
+	 * perf open/close operations that build await dependencies between
+	 * engine kernel context requests and user requests from different
+	 * timelines, this can lead to dependency loops and infinite waits.
+	 *
+	 * As a countermeasure, we try to get a reference to the active->fence
+	 * first, so if we succeed and pass it back to our user then it is not
+	 * released and potentially reused by an unrelated request before the
+	 * user has a chance to set up an await dependency on it.
+	 */
+	prev = i915_active_fence_get(active);
+	if (fence == prev)
 		return fence;
 
 	GEM_BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags));
@@ -1070,27 +1087,56 @@
 	 * Consider that we have two threads arriving (A and B), with
 	 * C already resident as the active->fence.
 	 *
-	 * A does the xchg first, and so it sees C or NULL depending
-	 * on the timing of the interrupt handler. If it is NULL, the
-	 * previous fence must have been signaled and we know that
-	 * we are first on the timeline. If it is still present,
-	 * we acquire the lock on that fence and serialise with the interrupt
-	 * handler, in the process removing it from any future interrupt
-	 * callback. A will then wait on C before executing (if present).
-	 *
-	 * As B is second, it sees A as the previous fence and so waits for
-	 * it to complete its transition and takes over the occupancy for
-	 * itself -- remembering that it needs to wait on A before executing.
+	 * Both A and B have got a reference to C or NULL, depending on the
+	 * timing of the interrupt handler.  Let's assume that if A has got C
+	 * then it has locked C first (before B).
 	 *
 	 * Note the strong ordering of the timeline also provides consistent
 	 * nesting rules for the fence->lock; the inner lock is always the
 	 * older lock.
 	 */
 	spin_lock_irqsave(fence->lock, flags);
-	prev = xchg(__active_fence_slot(active), fence);
-	if (prev) {
-		GEM_BUG_ON(prev == fence);
+	if (prev)
 		spin_lock_nested(prev->lock, SINGLE_DEPTH_NESTING);
+
+	/*
+	 * A does the cmpxchg first, and so it sees C or NULL, as before, or
+	 * something else, depending on the timing of other threads and/or
+	 * interrupt handler.  If not the same as before then A unlocks C if
+	 * applicable and retries, starting from an attempt to get a new
+	 * active->fence.  Meanwhile, B follows the same path as A.
+	 * Once A succeeds with cmpxch, B fails again, retires, gets A from
+	 * active->fence, locks it as soon as A completes, and possibly
+	 * succeeds with cmpxchg.
+	 */
+	while (cmpxchg(__active_fence_slot(active), prev, fence) != prev) {
+		if (prev) {
+			spin_unlock(prev->lock);
+			dma_fence_put(prev);
+		}
+		spin_unlock_irqrestore(fence->lock, flags);
+
+		prev = i915_active_fence_get(active);
+		GEM_BUG_ON(prev == fence);
+
+		spin_lock_irqsave(fence->lock, flags);
+		if (prev)
+			spin_lock_nested(prev->lock, SINGLE_DEPTH_NESTING);
+	}
+
+	/*
+	 * If prev is NULL then the previous fence must have been signaled
+	 * and we know that we are first on the timeline.  If it is still
+	 * present then, having the lock on that fence already acquired, we
+	 * serialise with the interrupt handler, in the process of removing it
+	 * from any future interrupt callback.  A will then wait on C before
+	 * executing (if present).
+	 *
+	 * As B is second, it sees A as the previous fence and so waits for
+	 * it to complete its transition and takes over the occupancy for
+	 * itself -- remembering that it needs to wait on A before executing.
+	 */
+	if (prev) {
 		__list_del_entry(&active->cb.node);
 		spin_unlock(prev->lock); /* serialise with prev->cb_list */
 	}
@@ -1107,11 +1153,7 @@
 	int err = 0;
 
 	/* Must maintain timeline ordering wrt previous active requests */
-	rcu_read_lock();
 	fence = __i915_active_fence_set(active, &rq->fence);
-	if (fence) /* but the previous fence may not belong to that timeline! */
-		fence = dma_fence_get_rcu(fence);
-	rcu_read_unlock();
 	if (fence) {
 		err = i915_request_await_dma_fence(rq, fence);
 		dma_fence_put(fence);
diff --git a/kernel/drivers/gpu/drm/i915/i915_drv.c b/kernel/drivers/gpu/drm/i915/i915_drv.c
index 382cf04..c72a26a 100644
--- a/kernel/drivers/gpu/drm/i915/i915_drv.c
+++ b/kernel/drivers/gpu/drm/i915/i915_drv.c
@@ -84,6 +84,7 @@
 #include "intel_gvt.h"
 #include "intel_memory_region.h"
 #include "intel_pm.h"
+#include "intel_sideband.h"
 #include "vlv_suspend.h"
 
 static struct drm_driver driver;
@@ -608,6 +609,9 @@
 		goto err_msi;
 
 	intel_opregion_setup(dev_priv);
+
+	intel_pcode_init(dev_priv);
+
 	/*
 	 * Fill the dram structure to get the system raw bandwidth and
 	 * dram info. This will be used for memory latency calculation.
diff --git a/kernel/drivers/gpu/drm/i915/i915_drv.h b/kernel/drivers/gpu/drm/i915/i915_drv.h
index 6909901..a8b65ba 100644
--- a/kernel/drivers/gpu/drm/i915/i915_drv.h
+++ b/kernel/drivers/gpu/drm/i915/i915_drv.h
@@ -1148,6 +1148,7 @@
 			INTEL_DRAM_LPDDR3,
 			INTEL_DRAM_LPDDR4
 		} type;
+		u8 num_qgv_points;
 	} dram_info;
 
 	struct intel_bw_info {
diff --git a/kernel/drivers/gpu/drm/i915/i915_pci.c b/kernel/drivers/gpu/drm/i915/i915_pci.c
index fb5e30d..63dc0fc 100644
--- a/kernel/drivers/gpu/drm/i915/i915_pci.c
+++ b/kernel/drivers/gpu/drm/i915/i915_pci.c
@@ -403,7 +403,8 @@
 	.has_coherent_ggtt = true, \
 	.has_llc = 1, \
 	.has_rc6 = 1, \
-	.has_rc6p = 1, \
+	/* snb does support rc6p, but enabling it causes various issues */ \
+	.has_rc6p = 0, \
 	.has_rps = true, \
 	.dma_mask_size = 40, \
 	.ppgtt_type = INTEL_PPGTT_ALIASING, \
diff --git a/kernel/drivers/gpu/drm/i915/i915_reg.h b/kernel/drivers/gpu/drm/i915/i915_reg.h
index 04157d8..728a464 100644
--- a/kernel/drivers/gpu/drm/i915/i915_reg.h
+++ b/kernel/drivers/gpu/drm/i915/i915_reg.h
@@ -9235,6 +9235,9 @@
 #define     GEN9_SAGV_DISABLE			0x0
 #define     GEN9_SAGV_IS_DISABLED		0x1
 #define     GEN9_SAGV_ENABLE			0x3
+#define   DG1_PCODE_STATUS			0x7E
+#define     DG1_UNCORE_GET_INIT_STATUS		0x0
+#define     DG1_UNCORE_INIT_STATUS_COMPLETE	0x1
 #define GEN12_PCODE_READ_SAGV_BLOCK_TIME_US	0x23
 #define GEN6_PCODE_DATA				_MMIO(0x138128)
 #define   GEN6_PCODE_FREQ_IA_RATIO_SHIFT	8
diff --git a/kernel/drivers/gpu/drm/i915/i915_request.c b/kernel/drivers/gpu/drm/i915/i915_request.c
index 896389f..eda56b2 100644
--- a/kernel/drivers/gpu/drm/i915/i915_request.c
+++ b/kernel/drivers/gpu/drm/i915/i915_request.c
@@ -1525,6 +1525,8 @@
 							 &rq->dep,
 							 0);
 	}
+	if (prev)
+		i915_request_put(prev);
 
 	/*
 	 * Make sure that no request gazumped us - if it was allocated after
diff --git a/kernel/drivers/gpu/drm/i915/intel_dram.c b/kernel/drivers/gpu/drm/i915/intel_dram.c
index 8aa12ca..26e109c 100644
--- a/kernel/drivers/gpu/drm/i915/intel_dram.c
+++ b/kernel/drivers/gpu/drm/i915/intel_dram.c
@@ -5,6 +5,7 @@
 
 #include "i915_drv.h"
 #include "intel_dram.h"
+#include "intel_sideband.h"
 
 struct dram_dimm_info {
 	u8 size, width, ranks;
@@ -433,6 +434,81 @@
 	return 0;
 }
 
+static int icl_pcode_read_mem_global_info(struct drm_i915_private *dev_priv)
+{
+	struct dram_info *dram_info = &dev_priv->dram_info;
+	u32 val = 0;
+	int ret;
+
+	ret = sandybridge_pcode_read(dev_priv,
+				     ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
+				     ICL_PCODE_MEM_SS_READ_GLOBAL_INFO,
+				     &val, NULL);
+	if (ret)
+		return ret;
+
+	if (IS_GEN(dev_priv, 12)) {
+		switch (val & 0xf) {
+		case 0:
+			dram_info->type = INTEL_DRAM_DDR4;
+			break;
+		case 3:
+			dram_info->type = INTEL_DRAM_LPDDR4;
+			break;
+		case 4:
+			dram_info->type = INTEL_DRAM_DDR3;
+			break;
+		case 5:
+			dram_info->type = INTEL_DRAM_LPDDR3;
+			break;
+		default:
+			MISSING_CASE(val & 0xf);
+			return -1;
+		}
+	} else {
+		switch (val & 0xf) {
+		case 0:
+			dram_info->type = INTEL_DRAM_DDR4;
+			break;
+		case 1:
+			dram_info->type = INTEL_DRAM_DDR3;
+			break;
+		case 2:
+			dram_info->type = INTEL_DRAM_LPDDR3;
+			break;
+		case 3:
+			dram_info->type = INTEL_DRAM_LPDDR4;
+			break;
+		default:
+			MISSING_CASE(val & 0xf);
+			return -1;
+		}
+	}
+
+	dram_info->num_channels = (val & 0xf0) >> 4;
+	dram_info->num_qgv_points = (val & 0xf00) >> 8;
+
+	return 0;
+}
+
+static int gen11_get_dram_info(struct drm_i915_private *i915)
+{
+	int ret = skl_get_dram_info(i915);
+
+	if (ret)
+		return ret;
+
+	return icl_pcode_read_mem_global_info(i915);
+}
+
+static int gen12_get_dram_info(struct drm_i915_private *i915)
+{
+	/* Always needed for GEN12+ */
+	i915->dram_info.is_16gb_dimm = true;
+
+	return icl_pcode_read_mem_global_info(i915);
+}
+
 void intel_dram_detect(struct drm_i915_private *i915)
 {
 	struct dram_info *dram_info = &i915->dram_info;
@@ -448,7 +524,11 @@
 	if (INTEL_GEN(i915) < 9 || !HAS_DISPLAY(i915))
 		return;
 
-	if (IS_GEN9_LP(i915))
+	if (INTEL_GEN(i915) >= 12)
+		ret = gen12_get_dram_info(i915);
+	else if (INTEL_GEN(i915) >= 11)
+		ret = gen11_get_dram_info(i915);
+	else if (IS_GEN9_LP(i915))
 		ret = bxt_get_dram_info(i915);
 	else
 		ret = skl_get_dram_info(i915);
diff --git a/kernel/drivers/gpu/drm/i915/intel_gvt.c b/kernel/drivers/gpu/drm/i915/intel_gvt.c
index 99fe8ae..4e70c1a 100644
--- a/kernel/drivers/gpu/drm/i915/intel_gvt.c
+++ b/kernel/drivers/gpu/drm/i915/intel_gvt.c
@@ -24,6 +24,7 @@
 #include "i915_drv.h"
 #include "i915_vgpu.h"
 #include "intel_gvt.h"
+#include "gvt/gvt.h"
 
 /**
  * DOC: Intel GVT-g host support
@@ -147,3 +148,17 @@
 
 	intel_gvt_clean_device(dev_priv);
 }
+
+/**
+ * intel_gvt_resume - GVT resume routine wapper
+ *
+ * @dev_priv: drm i915 private *
+ *
+ * This function is called at the i915 driver resume stage to restore required
+ * HW status for GVT so that vGPU can continue running after resumed.
+ */
+void intel_gvt_resume(struct drm_i915_private *dev_priv)
+{
+	if (intel_gvt_active(dev_priv))
+		intel_gvt_pm_resume(dev_priv->gvt);
+}
diff --git a/kernel/drivers/gpu/drm/i915/intel_gvt.h b/kernel/drivers/gpu/drm/i915/intel_gvt.h
index 502fad8..d7d3fb6 100644
--- a/kernel/drivers/gpu/drm/i915/intel_gvt.h
+++ b/kernel/drivers/gpu/drm/i915/intel_gvt.h
@@ -33,6 +33,7 @@
 void intel_gvt_clean_device(struct drm_i915_private *dev_priv);
 int intel_gvt_init_host(void);
 void intel_gvt_sanitize_options(struct drm_i915_private *dev_priv);
+void intel_gvt_resume(struct drm_i915_private *dev_priv);
 #else
 static inline int intel_gvt_init(struct drm_i915_private *dev_priv)
 {
@@ -46,6 +47,10 @@
 static inline void intel_gvt_sanitize_options(struct drm_i915_private *dev_priv)
 {
 }
+
+static inline void intel_gvt_resume(struct drm_i915_private *dev_priv)
+{
+}
 #endif
 
 #endif /* _INTEL_GVT_H_ */
diff --git a/kernel/drivers/gpu/drm/i915/intel_sideband.c b/kernel/drivers/gpu/drm/i915/intel_sideband.c
index 5b32792..02ebf5a 100644
--- a/kernel/drivers/gpu/drm/i915/intel_sideband.c
+++ b/kernel/drivers/gpu/drm/i915/intel_sideband.c
@@ -555,3 +555,18 @@
 	return ret ? ret : status;
 #undef COND
 }
+
+void intel_pcode_init(struct drm_i915_private *i915)
+{
+	int ret;
+
+	if (!IS_DGFX(i915))
+		return;
+
+	ret = skl_pcode_request(i915, DG1_PCODE_STATUS,
+				DG1_UNCORE_GET_INIT_STATUS,
+				DG1_UNCORE_INIT_STATUS_COMPLETE,
+				DG1_UNCORE_INIT_STATUS_COMPLETE, 50);
+	if (ret)
+		drm_err(&i915->drm, "Pcode did not report uncore initialization completion!\n");
+}
diff --git a/kernel/drivers/gpu/drm/i915/intel_sideband.h b/kernel/drivers/gpu/drm/i915/intel_sideband.h
index 7fb9574..094c7b1 100644
--- a/kernel/drivers/gpu/drm/i915/intel_sideband.h
+++ b/kernel/drivers/gpu/drm/i915/intel_sideband.h
@@ -138,4 +138,6 @@
 int skl_pcode_request(struct drm_i915_private *i915, u32 mbox, u32 request,
 		      u32 reply_mask, u32 reply, int timeout_base_ms);
 
+void intel_pcode_init(struct drm_i915_private *i915);
+
 #endif /* _INTEL_SIDEBAND_H */
diff --git a/kernel/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/kernel/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
index e34718c..5ec9770 100644
--- a/kernel/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+++ b/kernel/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
@@ -1120,7 +1120,11 @@
 			return err;
 	}
 
-	return platform_driver_register(&ingenic_drm_driver);
+	err = platform_driver_register(&ingenic_drm_driver);
+	if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU) && err)
+		platform_driver_unregister(ingenic_ipu_driver_ptr);
+
+	return err;
 }
 module_init(ingenic_drm_init);
 
diff --git a/kernel/drivers/gpu/drm/lima/lima_drv.c b/kernel/drivers/gpu/drm/lima/lima_drv.c
index ab46012..65dc0dc 100644
--- a/kernel/drivers/gpu/drm/lima/lima_drv.c
+++ b/kernel/drivers/gpu/drm/lima/lima_drv.c
@@ -392,8 +392,10 @@
 
 	/* Allocate and initialize the DRM device. */
 	ddev = drm_dev_alloc(&lima_drm_driver, &pdev->dev);
-	if (IS_ERR(ddev))
-		return PTR_ERR(ddev);
+	if (IS_ERR(ddev)) {
+		err = PTR_ERR(ddev);
+		goto err_out0;
+	}
 
 	ddev->dev_private = ldev;
 	ldev->ddev = ddev;
diff --git a/kernel/drivers/gpu/drm/mediatek/mtk_dpi.c b/kernel/drivers/gpu/drm/mediatek/mtk_dpi.c
index c1ae336..aa3d472 100644
--- a/kernel/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/kernel/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -367,9 +367,6 @@
 	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);
@@ -393,9 +390,6 @@
 		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
 		goto err_pixel;
 	}
-
-	if (dpi->pinctrl && dpi->pins_dpi)
-		pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
 
 	return 0;
 
@@ -525,12 +519,18 @@
 	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);
diff --git a/kernel/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/kernel/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index dfd5ed1..e83b1c4 100644
--- a/kernel/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/kernel/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -803,6 +803,8 @@
 
 	mtk_crtc->planes = devm_kcalloc(dev, num_comp_planes,
 					sizeof(struct drm_plane), GFP_KERNEL);
+	if (!mtk_crtc->planes)
+		return -ENOMEM;
 
 	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 		ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
diff --git a/kernel/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/kernel/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 59c85c6..719c46d 100644
--- a/kernel/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/kernel/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -378,6 +378,7 @@
 err_deinit:
 	mtk_drm_kms_deinit(drm);
 err_free:
+	private->drm = NULL;
 	drm_dev_put(drm);
 	return ret;
 }
diff --git a/kernel/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/kernel/drivers/gpu/drm/mediatek/mtk_drm_gem.c
index 0583e55..b20ea58 100644
--- a/kernel/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+++ b/kernel/drivers/gpu/drm/mediatek/mtk_drm_gem.c
@@ -142,8 +142,6 @@
 
 	ret = dma_mmap_attrs(priv->dma_dev, vma, mtk_gem->cookie,
 			     mtk_gem->dma_addr, obj->size, mtk_gem->dma_attrs);
-	if (ret)
-		drm_gem_vm_close(vma);
 
 	return ret;
 }
@@ -251,7 +249,11 @@
 
 	mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP,
 			       pgprot_writecombine(PAGE_KERNEL));
-
+	if (!mtk_gem->kvaddr) {
+		kfree(sgt);
+		kfree(mtk_gem->pages);
+		return NULL;
+	}
 out:
 	kfree(sgt);
 
@@ -266,6 +268,6 @@
 		return;
 
 	vunmap(vaddr);
-	mtk_gem->kvaddr = 0;
+	mtk_gem->kvaddr = NULL;
 	kfree(mtk_gem->pages);
 }
diff --git a/kernel/drivers/gpu/drm/mediatek/mtk_dsi.c b/kernel/drivers/gpu/drm/mediatek/mtk_dsi.c
index 146c4d0..a6e71b7 100644
--- a/kernel/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/kernel/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -704,7 +704,7 @@
 		mtk_dsi_clk_ulp_mode_leave(dsi);
 		mtk_dsi_lane0_ulp_mode_leave(dsi);
 		mtk_dsi_clk_hs_mode(dsi, 0);
-		msleep(20);
+		usleep_range(1000, 3000);
 		/* The reaction time after pulling up the mipi signal for dsi_rx */
 	}
 }
diff --git a/kernel/drivers/gpu/drm/meson/meson_drv.c b/kernel/drivers/gpu/drm/meson/meson_drv.c
index b0bfe85..5c29ddf 100644
--- a/kernel/drivers/gpu/drm/meson/meson_drv.c
+++ b/kernel/drivers/gpu/drm/meson/meson_drv.c
@@ -320,38 +320,38 @@
 	if (priv->afbcd.ops) {
 		ret = priv->afbcd.ops->init(priv);
 		if (ret)
-			return ret;
+			goto free_drm;
 	}
 
 	/* Encoder Initialization */
 
 	ret = meson_venc_cvbs_create(priv);
 	if (ret)
-		goto free_drm;
+		goto exit_afbcd;
 
 	if (has_components) {
 		ret = component_bind_all(drm->dev, drm);
 		if (ret) {
 			dev_err(drm->dev, "Couldn't bind all components\n");
-			goto free_drm;
+			goto exit_afbcd;
 		}
 	}
 
 	ret = meson_plane_create(priv);
 	if (ret)
-		goto free_drm;
+		goto unbind_all;
 
 	ret = meson_overlay_create(priv);
 	if (ret)
-		goto free_drm;
+		goto unbind_all;
 
 	ret = meson_crtc_create(priv);
 	if (ret)
-		goto free_drm;
+		goto unbind_all;
 
 	ret = drm_irq_install(drm, priv->vsync_irq);
 	if (ret)
-		goto free_drm;
+		goto unbind_all;
 
 	drm_mode_config_reset(drm);
 
@@ -369,6 +369,12 @@
 
 uninstall_irq:
 	drm_irq_uninstall(drm);
+unbind_all:
+	if (has_components)
+		component_unbind_all(drm->dev, drm);
+exit_afbcd:
+	if (priv->afbcd.ops)
+		priv->afbcd.ops->exit(priv);
 free_drm:
 	drm_dev_put(drm);
 
diff --git a/kernel/drivers/gpu/drm/meson/meson_viu.c b/kernel/drivers/gpu/drm/meson/meson_viu.c
index d4b9078..cd399b0 100644
--- a/kernel/drivers/gpu/drm/meson/meson_viu.c
+++ b/kernel/drivers/gpu/drm/meson/meson_viu.c
@@ -436,15 +436,14 @@
 
 	/* Initialize OSD1 fifo control register */
 	reg = VIU_OSD_DDR_PRIORITY_URGENT |
-		VIU_OSD_HOLD_FIFO_LINES(31) |
 		VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */
 		VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */
 		VIU_OSD_FIFO_LIMITS(2);      /* fifo_lim: 2*16=32 */
 
 	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
-		reg |= VIU_OSD_BURST_LENGTH_32;
+		reg |= (VIU_OSD_BURST_LENGTH_32 | VIU_OSD_HOLD_FIFO_LINES(31));
 	else
-		reg |= VIU_OSD_BURST_LENGTH_64;
+		reg |= (VIU_OSD_BURST_LENGTH_64 | VIU_OSD_HOLD_FIFO_LINES(4));
 
 	writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
 	writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
diff --git a/kernel/drivers/gpu/drm/meson/meson_vpp.c b/kernel/drivers/gpu/drm/meson/meson_vpp.c
index 1548376..5df1957 100644
--- a/kernel/drivers/gpu/drm/meson/meson_vpp.c
+++ b/kernel/drivers/gpu/drm/meson/meson_vpp.c
@@ -100,6 +100,8 @@
 			       priv->io_base + _REG(VPP_DOLBY_CTRL));
 		writel_relaxed(0x1020080,
 				priv->io_base + _REG(VPP_DUMMY_DATA1));
+		writel_relaxed(0x42020,
+				priv->io_base + _REG(VPP_DUMMY_DATA));
 	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
 		writel_relaxed(0xf, priv->io_base + _REG(DOLBY_PATH_CTRL));
 
diff --git a/kernel/drivers/gpu/drm/msm/Makefile b/kernel/drivers/gpu/drm/msm/Makefile
index 340682c..2457ef9 100644
--- a/kernel/drivers/gpu/drm/msm/Makefile
+++ b/kernel/drivers/gpu/drm/msm/Makefile
@@ -19,7 +19,7 @@
 	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/kernel/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/kernel/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
index 7e82c41..64ee63d 100644
--- a/kernel/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
+++ b/kernel/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
@@ -521,16 +521,16 @@
 	gpu->perfcntrs = perfcntrs;
 	gpu->num_perfcntrs = ARRAY_SIZE(perfcntrs);
 
+	ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
+	if (ret)
+		goto fail;
+
 	if (adreno_is_a20x(adreno_gpu))
 		adreno_gpu->registers = a200_registers;
 	else if (adreno_is_a225(adreno_gpu))
 		adreno_gpu->registers = a225_registers;
 	else
 		adreno_gpu->registers = a220_registers;
-
-	ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
-	if (ret)
-		goto fail;
 
 	if (!gpu->aspace) {
 		dev_err(dev->dev, "No memory protection without MMU\n");
diff --git a/kernel/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/kernel/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 0ca7e53..9ae0e60 100644
--- a/kernel/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/kernel/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -36,7 +36,7 @@
 		OUT_RING(ring, upper_32_bits(shadowptr(a5xx_gpu, ring)));
 	}
 
-	spin_lock_irqsave(&ring->lock, flags);
+	spin_lock_irqsave(&ring->preempt_lock, flags);
 
 	/* Copy the shadow to the actual register */
 	ring->cur = ring->next;
@@ -44,7 +44,7 @@
 	/* Make sure to wrap wptr if we need to */
 	wptr = get_wptr(ring);
 
-	spin_unlock_irqrestore(&ring->lock, flags);
+	spin_unlock_irqrestore(&ring->preempt_lock, flags);
 
 	/* Make sure everything is posted before making a decision */
 	mb();
@@ -81,7 +81,7 @@
 			 * since we've already mapped it once in
 			 * submit_reloc()
 			 */
-			if (WARN_ON(!ptr))
+			if (WARN_ON(IS_ERR_OR_NULL(ptr)))
 				return;
 
 			for (i = 0; i < dwords; i++) {
@@ -144,8 +144,8 @@
 	OUT_RING(ring, 1);
 
 	/* Enable local preemption for finegrain preemption */
-	OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1);
-	OUT_RING(ring, 0x02);
+	OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1);
+	OUT_RING(ring, 0x1);
 
 	/* Allow CP_CONTEXT_SWITCH_YIELD packets in the IB2 */
 	OUT_PKT7(ring, CP_YIELD_ENABLE, 1);
@@ -1569,6 +1569,7 @@
 	struct a5xx_gpu *a5xx_gpu = NULL;
 	struct adreno_gpu *adreno_gpu;
 	struct msm_gpu *gpu;
+	unsigned int nr_rings;
 	int ret;
 
 	if (!pdev) {
@@ -1589,7 +1590,12 @@
 
 	check_speed_bin(&pdev->dev);
 
-	ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4);
+	nr_rings = 4;
+
+	if (adreno_is_a510(adreno_gpu))
+		nr_rings = 1;
+
+	ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, nr_rings);
 	if (ret) {
 		a5xx_destroy(&(a5xx_gpu->base.base));
 		return ERR_PTR(ret);
diff --git a/kernel/drivers/gpu/drm/msm/adreno/a5xx_preempt.c b/kernel/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
index 7e04509..b8e71ad 100644
--- a/kernel/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
+++ b/kernel/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
@@ -45,9 +45,9 @@
 	if (!ring)
 		return;
 
-	spin_lock_irqsave(&ring->lock, flags);
+	spin_lock_irqsave(&ring->preempt_lock, flags);
 	wptr = get_wptr(ring);
-	spin_unlock_irqrestore(&ring->lock, flags);
+	spin_unlock_irqrestore(&ring->preempt_lock, flags);
 
 	gpu_write(gpu, REG_A5XX_CP_RB_WPTR, wptr);
 }
@@ -62,9 +62,9 @@
 		bool empty;
 		struct msm_ringbuffer *ring = gpu->rb[i];
 
-		spin_lock_irqsave(&ring->lock, flags);
-		empty = (get_wptr(ring) == ring->memptrs->rptr);
-		spin_unlock_irqrestore(&ring->lock, flags);
+		spin_lock_irqsave(&ring->preempt_lock, flags);
+		empty = (get_wptr(ring) == gpu->funcs->get_rptr(gpu, ring));
+		spin_unlock_irqrestore(&ring->preempt_lock, flags);
 
 		if (!empty)
 			return ring;
@@ -132,9 +132,9 @@
 	}
 
 	/* Make sure the wptr doesn't update while we're in motion */
-	spin_lock_irqsave(&ring->lock, flags);
+	spin_lock_irqsave(&ring->preempt_lock, flags);
 	a5xx_gpu->preempt[ring->id]->wptr = get_wptr(ring);
-	spin_unlock_irqrestore(&ring->lock, flags);
+	spin_unlock_irqrestore(&ring->preempt_lock, flags);
 
 	/* Set the address of the incoming preemption record */
 	gpu_write64(gpu, REG_A5XX_CP_CONTEXT_SWITCH_RESTORE_ADDR_LO,
@@ -210,6 +210,7 @@
 		a5xx_gpu->preempt[i]->wptr = 0;
 		a5xx_gpu->preempt[i]->rptr = 0;
 		a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova;
+		a5xx_gpu->preempt[i]->rptr_addr = shadowptr(a5xx_gpu, gpu->rb[i]);
 	}
 
 	/* Write a 0 to signal that we aren't switching pagetables */
@@ -261,7 +262,6 @@
 	ptr->data = 0;
 	ptr->cntl = MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE;
 
-	ptr->rptr_addr = shadowptr(a5xx_gpu, ring);
 	ptr->counter = counters_iova;
 
 	return 0;
diff --git a/kernel/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/kernel/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index dffc133..29b40ac 100644
--- a/kernel/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/kernel/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -65,7 +65,7 @@
 		OUT_RING(ring, upper_32_bits(shadowptr(a6xx_gpu, ring)));
 	}
 
-	spin_lock_irqsave(&ring->lock, flags);
+	spin_lock_irqsave(&ring->preempt_lock, flags);
 
 	/* Copy the shadow to the actual register */
 	ring->cur = ring->next;
@@ -73,7 +73,7 @@
 	/* Make sure to wrap wptr if we need to */
 	wptr = get_wptr(ring);
 
-	spin_unlock_irqrestore(&ring->lock, flags);
+	spin_unlock_irqrestore(&ring->preempt_lock, flags);
 
 	/* Make sure everything is posted before making a decision */
 	mb();
diff --git a/kernel/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h b/kernel/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
index 2fb58b7..3bd2065 100644
--- a/kernel/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
+++ b/kernel/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
@@ -200,7 +200,7 @@
 	SHADER(A6XX_SP_LB_3_DATA, 0x800),
 	SHADER(A6XX_SP_LB_4_DATA, 0x800),
 	SHADER(A6XX_SP_LB_5_DATA, 0x200),
-	SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x2000),
+	SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x800),
 	SHADER(A6XX_SP_CB_LEGACY_DATA, 0x280),
 	SHADER(A6XX_SP_UAV_DATA, 0x80),
 	SHADER(A6XX_SP_INST_TAG, 0x80),
diff --git a/kernel/drivers/gpu/drm/msm/adreno/adreno_device.c b/kernel/drivers/gpu/drm/msm/adreno/adreno_device.c
index 58e03b2..760687f 100644
--- a/kernel/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/kernel/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -301,8 +301,11 @@
 	if (ret)
 		return NULL;
 
-	/* Make sure pm runtime is active and reset any previous errors */
-	pm_runtime_set_active(&pdev->dev);
+	/*
+	 * Now that we have firmware loaded, and are ready to begin
+	 * booting the gpu, go ahead and enable runpm:
+	 */
+	pm_runtime_enable(&pdev->dev);
 
 	ret = pm_runtime_get_sync(&pdev->dev);
 	if (ret < 0) {
diff --git a/kernel/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/kernel/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index de8cc25..11a6a41 100644
--- a/kernel/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/kernel/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -916,7 +916,6 @@
 	pm_runtime_set_autosuspend_delay(dev,
 		adreno_gpu->info->inactive_period);
 	pm_runtime_use_autosuspend(dev);
-	pm_runtime_enable(dev);
 
 	ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base,
 			adreno_gpu->info->name, &adreno_gpu_config);
@@ -954,13 +953,13 @@
 void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
 {
 	struct msm_gpu *gpu = &adreno_gpu->base;
-	struct msm_drm_private *priv = gpu->dev->dev_private;
+	struct msm_drm_private *priv = gpu->dev ? gpu->dev->dev_private : NULL;
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++)
 		release_firmware(adreno_gpu->fw[i]);
 
-	if (pm_runtime_enabled(&priv->gpu_pdev->dev))
+	if (priv && pm_runtime_enabled(&priv->gpu_pdev->dev))
 		pm_runtime_disable(&priv->gpu_pdev->dev);
 
 	msm_gpu_cleanup(&adreno_gpu->base);
diff --git a/kernel/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/kernel/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index c3775f7..4656e70 100644
--- a/kernel/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/kernel/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -28,11 +28,9 @@
 	ADRENO_FW_MAX,
 };
 
-enum adreno_quirks {
-	ADRENO_QUIRK_TWO_PASS_USE_WFI = 1,
-	ADRENO_QUIRK_FAULT_DETECT_MASK = 2,
-	ADRENO_QUIRK_LMLOADKILL_DISABLE = 3,
-};
+#define ADRENO_QUIRK_TWO_PASS_USE_WFI		BIT(0)
+#define ADRENO_QUIRK_FAULT_DETECT_MASK		BIT(1)
+#define ADRENO_QUIRK_LMLOADKILL_DISABLE		BIT(2)
 
 struct adreno_rev {
 	uint8_t  core;
@@ -62,7 +60,7 @@
 	const char *name;
 	const char *fw[ADRENO_FW_MAX];
 	uint32_t gmem;
-	enum adreno_quirks quirks;
+	u64 quirks;
 	struct msm_gpu *(*init)(struct drm_device *dev);
 	const char *zapfw;
 	u32 inactive_period;
diff --git a/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h b/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
index cf4b9b5..cd6c351 100644
--- a/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
+++ b/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
@@ -15,19 +15,6 @@
 #define	DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE	412500000
 
 /**
- * enum dpu_core_perf_data_bus_id - data bus identifier
- * @DPU_CORE_PERF_DATA_BUS_ID_MNOC: DPU/MNOC data bus
- * @DPU_CORE_PERF_DATA_BUS_ID_LLCC: MNOC/LLCC data bus
- * @DPU_CORE_PERF_DATA_BUS_ID_EBI: LLCC/EBI data bus
- */
-enum dpu_core_perf_data_bus_id {
-	DPU_CORE_PERF_DATA_BUS_ID_MNOC,
-	DPU_CORE_PERF_DATA_BUS_ID_LLCC,
-	DPU_CORE_PERF_DATA_BUS_ID_EBI,
-	DPU_CORE_PERF_DATA_BUS_ID_MAX,
-};
-
-/**
  * struct dpu_core_perf_params - definition of performance parameters
  * @max_per_pipe_ib: maximum instantaneous bandwidth request
  * @bw_ctl: arbitrated bandwidth request
diff --git a/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index f56414a..4c64e2d 100644
--- a/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -682,7 +682,10 @@
 	if (crtc->state)
 		dpu_crtc_destroy_state(crtc, crtc->state);
 
-	__drm_atomic_helper_crtc_reset(crtc, &cstate->base);
+	if (cstate)
+		__drm_atomic_helper_crtc_reset(crtc, &cstate->base);
+	else
+		__drm_atomic_helper_crtc_reset(crtc, NULL);
 }
 
 /**
@@ -831,6 +834,8 @@
 	struct drm_rect crtc_rect = { 0 };
 
 	pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
+	if (!pstates)
+		return -ENOMEM;
 
 	if (!state->enable || !state->active) {
 		DPU_DEBUG("crtc%d -> enable %d, active %d, skip atomic_check\n",
@@ -1257,6 +1262,8 @@
 struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
 				struct drm_plane *cursor)
 {
+	struct msm_drm_private *priv = dev->dev_private;
+	struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
 	struct drm_crtc *crtc = NULL;
 	struct dpu_crtc *dpu_crtc = NULL;
 	int i;
@@ -1288,7 +1295,8 @@
 
 	drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs);
 
-	drm_crtc_enable_color_mgmt(crtc, 0, true, 0);
+	if (dpu_kms->catalog->dspp_count)
+		drm_crtc_enable_color_mgmt(crtc, 0, true, 0);
 
 	/* save user friendly CRTC name for later */
 	snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id);
diff --git a/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index a0274fc..408fc6c 100644
--- a/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -634,7 +634,7 @@
 		if (drm_atomic_crtc_needs_modeset(crtc_state)) {
 			dpu_rm_release(global_state, drm_enc);
 
-			if (!crtc_state->active_changed || crtc_state->active)
+			if (!crtc_state->active_changed || crtc_state->enable)
 				ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
 						drm_enc, crtc_state, topology);
 		}
diff --git a/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
index 108882b..7aa6acc 100644
--- a/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -51,11 +51,6 @@
 #define   INTF_TPG_RGB_MAPPING          0x11C
 #define   INTF_PROG_FETCH_START         0x170
 #define   INTF_PROG_ROT_START           0x174
-
-#define   INTF_FRAME_LINE_COUNT_EN      0x0A8
-#define   INTF_FRAME_COUNT              0x0AC
-#define   INTF_LINE_COUNT               0x0B0
-
 #define   INTF_MUX                      0x25C
 
 static const struct dpu_intf_cfg *_intf_offset(enum dpu_intf intf,
diff --git a/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 74a13cc..9483005 100644
--- a/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/kernel/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -633,6 +633,11 @@
 				  blks_size, enc_id);
 			break;
 		}
+		if (!hw_blks[i]) {
+			DPU_ERROR("Allocated resource %d unavailable to assign to enc %d\n",
+				  type, enc_id);
+			break;
+		}
 		blks[num_blks++] = hw_blks[i];
 	}
 
diff --git a/kernel/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/kernel/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index ff4f207..60e7371 100644
--- a/kernel/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/kernel/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -1124,7 +1124,10 @@
 	if (crtc->state)
 		mdp5_crtc_destroy_state(crtc, crtc->state);
 
-	__drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base);
+	if (mdp5_cstate)
+		__drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base);
+	else
+		__drm_atomic_helper_crtc_reset(crtc, NULL);
 }
 
 static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = {
diff --git a/kernel/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/kernel/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
index 0dc23c8..e1c1b4a 100644
--- a/kernel/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+++ b/kernel/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
@@ -221,8 +221,7 @@
 {
 	struct mdp5_plane_state *pstate = to_mdp5_plane_state(state);
 
-	if (state->fb)
-		drm_framebuffer_put(state->fb);
+	__drm_atomic_helper_plane_destroy_state(state);
 
 	kfree(pstate);
 }
diff --git a/kernel/drivers/gpu/drm/msm/dp/dp_audio.c b/kernel/drivers/gpu/drm/msm/dp/dp_audio.c
index d7e4a39..0eaaaa9 100644
--- a/kernel/drivers/gpu/drm/msm/dp/dp_audio.c
+++ b/kernel/drivers/gpu/drm/msm/dp/dp_audio.c
@@ -577,6 +577,18 @@
 	.i2s = 1,
 };
 
+void dp_unregister_audio_driver(struct device *dev, struct dp_audio *dp_audio)
+{
+	struct dp_audio_private *audio_priv;
+
+	audio_priv = container_of(dp_audio, struct dp_audio_private, dp_audio);
+
+	if (audio_priv->audio_pdev) {
+		platform_device_unregister(audio_priv->audio_pdev);
+		audio_priv->audio_pdev = NULL;
+	}
+}
+
 int dp_register_audio_driver(struct device *dev,
 		struct dp_audio *dp_audio)
 {
diff --git a/kernel/drivers/gpu/drm/msm/dp/dp_audio.h b/kernel/drivers/gpu/drm/msm/dp/dp_audio.h
index 84e5f4a..4ab7888 100644
--- a/kernel/drivers/gpu/drm/msm/dp/dp_audio.h
+++ b/kernel/drivers/gpu/drm/msm/dp/dp_audio.h
@@ -53,6 +53,8 @@
 int dp_register_audio_driver(struct device *dev,
 		struct dp_audio *dp_audio);
 
+void dp_unregister_audio_driver(struct device *dev, struct dp_audio *dp_audio);
+
 /**
  * dp_audio_put()
  *
diff --git a/kernel/drivers/gpu/drm/msm/dp/dp_aux.c b/kernel/drivers/gpu/drm/msm/dp/dp_aux.c
index 19b35ae..a73a2b2 100644
--- a/kernel/drivers/gpu/drm/msm/dp/dp_aux.c
+++ b/kernel/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -423,6 +423,10 @@
 
 	aux->isr = dp_catalog_aux_get_irq(aux->catalog);
 
+	/* no interrupts pending, return immediately */
+	if (!aux->isr)
+		return;
+
 	if (!aux->cmd_busy)
 		return;
 
diff --git a/kernel/drivers/gpu/drm/msm/dp/dp_display.c b/kernel/drivers/gpu/drm/msm/dp/dp_display.c
index 5a152d5..4da8cea 100644
--- a/kernel/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/kernel/drivers/gpu/drm/msm/dp/dp_display.c
@@ -276,6 +276,7 @@
 	kthread_stop(dp->ev_tsk);
 
 	dp_power_client_deinit(dp->power);
+	dp_unregister_audio_driver(dev, dp->audio);
 	dp_aux_unregister(dp->aux);
 	priv->dp = NULL;
 }
@@ -848,7 +849,7 @@
 
 	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);
@@ -1266,9 +1267,9 @@
 	dp = container_of(g_dp_display,
 			struct dp_display_private, dp_display);
 
+	component_del(&pdev->dev, &dp_display_comp_ops);
 	dp_display_deinit_sub_modules(dp);
 
-	component_del(&pdev->dev, &dp_display_comp_ops);
 	platform_set_drvdata(pdev, NULL);
 
 	return 0;
diff --git a/kernel/drivers/gpu/drm/msm/dsi/dsi_host.c b/kernel/drivers/gpu/drm/msm/dsi/dsi_host.c
index 51e8318..5a76aa1 100644
--- a/kernel/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/kernel/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1913,6 +1913,9 @@
 
 	/* setup workqueue */
 	msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0);
+	if (!msm_host->workqueue)
+		return -ENOMEM;
+
 	INIT_WORK(&msm_host->err_work, dsi_err_worker);
 	INIT_WORK(&msm_host->hpd_work, dsi_hpd_worker);
 
diff --git a/kernel/drivers/gpu/drm/msm/hdmi/hdmi.c b/kernel/drivers/gpu/drm/msm/hdmi/hdmi.c
index bd65dc9..bee2087 100644
--- a/kernel/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/kernel/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 @@
 	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);
@@ -245,9 +247,27 @@
 		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);
+	if (!hdmi->workq) {
+		ret = -ENOMEM;
+		goto fail;
+	}
 
 	hdmi->i2c = msm_hdmi_i2c_init(hdmi);
 	if (IS_ERR(hdmi->i2c)) {
@@ -311,13 +331,15 @@
 		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);
 		hdmi->connector = NULL;
 		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) {
@@ -335,7 +357,9 @@
 		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;
@@ -421,20 +445,6 @@
 		HDMI_CFG(pwr_clk, 8x74),
 		HDMI_CFG(hpd_clk, 8x74),
 		.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" },
 };
 
 /*
@@ -549,7 +559,7 @@
 	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);
@@ -560,42 +570,6 @@
 
 	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;
 
diff --git a/kernel/drivers/gpu/drm/msm/hdmi/hdmi.h b/kernel/drivers/gpu/drm/msm/hdmi/hdmi.h
index d0b84f0..20f5543 100644
--- a/kernel/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/kernel/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -19,16 +19,8 @@
 #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;
@@ -60,6 +52,8 @@
 	struct regulator **pwr_regs;
 	struct clk **hpd_clks;
 	struct clk **pwr_clks;
+
+	struct gpio_desc *hpd_gpiod;
 
 	struct hdmi_phy *phy;
 	struct device *phy_dev;
@@ -109,10 +103,14 @@
 	/* 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 {
+	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);
 
@@ -230,13 +228,11 @@
 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/kernel/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/kernel/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index 6e380db..efcfdd7 100644
--- a/kernel/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/kernel/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 @@
 		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 @@
 	}
 
 	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/kernel/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/kernel/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
deleted file mode 100644
index 58707a1..0000000
--- a/kernel/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
+++ /dev/null
@@ -1,451 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2013 Red Hat
- * Author: Rob Clark <robdclark@gmail.com>
- */
-
-#include <linux/delay.h>
-#include <linux/gpio/consumer.h>
-#include <linux/pinctrl/consumer.h>
-
-#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;
-
-	val = hdmi_read(hdmi, REG_HDMI_PHY_CTRL);
-
-	if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
-		/* pull low */
-		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
-				val & ~HDMI_PHY_CTRL_SW_RESET);
-	} else {
-		/* pull high */
-		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
-				val | HDMI_PHY_CTRL_SW_RESET);
-	}
-
-	if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
-		/* pull low */
-		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
-				val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
-	} else {
-		/* pull high */
-		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
-				val | HDMI_PHY_CTRL_SW_RESET_PLL);
-	}
-
-	msleep(100);
-
-	if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
-		/* pull high */
-		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
-				val | HDMI_PHY_CTRL_SW_RESET);
-	} else {
-		/* pull low */
-		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
-				val & ~HDMI_PHY_CTRL_SW_RESET);
-	}
-
-	if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
-		/* pull high */
-		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
-				val | HDMI_PHY_CTRL_SW_RESET_PLL);
-	} else {
-		/* pull low */
-		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
-				val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
-	}
-}
-
-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;
-	struct device *dev = &hdmi->pdev->dev;
-	int i, ret;
-
-	if (enable) {
-		for (i = 0; i < config->hpd_clk_cnt; i++) {
-			if (config->hpd_freq && config->hpd_freq[i]) {
-				ret = clk_set_rate(hdmi->hpd_clks[i],
-						   config->hpd_freq[i]);
-				if (ret)
-					dev_warn(dev,
-						 "failed to set clk %s (%d)\n",
-						 config->hpd_clk_names[i], ret);
-			}
-
-			ret = clk_prepare_enable(hdmi->hpd_clks[i]);
-			if (ret) {
-				DRM_DEV_ERROR(dev,
-					"failed to enable hpd clk: %s (%d)\n",
-					config->hpd_clk_names[i], ret);
-			}
-		}
-	} else {
-		for (i = config->hpd_clk_cnt - 1; i >= 0; i--)
-			clk_disable_unprepare(hdmi->hpd_clks[i]);
-	}
-}
-
-int msm_hdmi_hpd_enable(struct drm_connector *connector)
-{
-	struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
-	struct hdmi *hdmi = hdmi_connector->hdmi;
-	const struct hdmi_platform_config *config = hdmi->config;
-	struct device *dev = &hdmi->pdev->dev;
-	uint32_t hpd_ctrl;
-	int i, ret;
-	unsigned long flags;
-
-	for (i = 0; i < config->hpd_reg_cnt; i++) {
-		ret = regulator_enable(hdmi->hpd_regs[i]);
-		if (ret) {
-			DRM_DEV_ERROR(dev, "failed to enable hpd regulator: %s (%d)\n",
-					config->hpd_reg_names[i], ret);
-			goto fail;
-		}
-	}
-
-	ret = pinctrl_pm_select_default_state(dev);
-	if (ret) {
-		DRM_DEV_ERROR(dev, "pinctrl state chg failed: %d\n", ret);
-		goto fail;
-	}
-
-	ret = gpio_config(hdmi, true);
-	if (ret) {
-		DRM_DEV_ERROR(dev, "failed to configure GPIOs: %d\n", ret);
-		goto fail;
-	}
-
-	pm_runtime_get_sync(dev);
-	enable_hpd_clocks(hdmi, true);
-
-	msm_hdmi_set_mode(hdmi, false);
-	msm_hdmi_phy_reset(hdmi);
-	msm_hdmi_set_mode(hdmi, true);
-
-	hdmi_write(hdmi, REG_HDMI_USEC_REFTIMER, 0x0001001b);
-
-	/* enable HPD events: */
-	hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
-			HDMI_HPD_INT_CTRL_INT_CONNECT |
-			HDMI_HPD_INT_CTRL_INT_EN);
-
-	/* set timeout to 4.1ms (max) for hardware debounce */
-	spin_lock_irqsave(&hdmi->reg_lock, flags);
-	hpd_ctrl = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
-	hpd_ctrl |= HDMI_HPD_CTRL_TIMEOUT(0x1fff);
-
-	/* Toggle HPD circuit to trigger HPD sense */
-	hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
-			~HDMI_HPD_CTRL_ENABLE & hpd_ctrl);
-	hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
-			HDMI_HPD_CTRL_ENABLE | hpd_ctrl);
-	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
-
-	return 0;
-
-fail:
-	return ret;
-}
-
-static void hdp_disable(struct hdmi_connector *hdmi_connector)
-{
-	struct hdmi *hdmi = hdmi_connector->hdmi;
-	const struct hdmi_platform_config *config = hdmi->config;
-	struct device *dev = &hdmi->pdev->dev;
-	int i, ret = 0;
-
-	/* Disable HPD interrupt */
-	hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, 0);
-
-	msm_hdmi_set_mode(hdmi, false);
-
-	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);
-
-	for (i = 0; i < config->hpd_reg_cnt; i++) {
-		ret = regulator_disable(hdmi->hpd_regs[i]);
-		if (ret)
-			dev_warn(dev, "failed to disable hpd regulator: %s (%d)\n",
-					config->hpd_reg_names[i], ret);
-	}
-}
-
-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)
-{
-	struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
-	struct hdmi *hdmi = hdmi_connector->hdmi;
-	uint32_t hpd_int_status, hpd_int_ctrl;
-
-	/* Process HPD: */
-	hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
-	hpd_int_ctrl   = hdmi_read(hdmi, REG_HDMI_HPD_INT_CTRL);
-
-	if ((hpd_int_ctrl & HDMI_HPD_INT_CTRL_INT_EN) &&
-			(hpd_int_status & HDMI_HPD_INT_STATUS_INT)) {
-		bool detected = !!(hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED);
-
-		/* ack & disable (temporarily) HPD events: */
-		hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
-			HDMI_HPD_INT_CTRL_INT_ACK);
-
-		DBG("status=%04x, ctrl=%04x", hpd_int_status, hpd_int_ctrl);
-
-		/* detect disconnect if we are connected or visa versa: */
-		hpd_int_ctrl = HDMI_HPD_INT_CTRL_INT_EN;
-		if (!detected)
-			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);
-	}
-}
-
-static enum drm_connector_status detect_reg(struct hdmi *hdmi)
-{
-	uint32_t hpd_int_status;
-
-	pm_runtime_get_sync(&hdmi->pdev->dev);
-	enable_hpd_clocks(hdmi, true);
-
-	hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
-
-	enable_hpd_clocks(hdmi, false);
-	pm_runtime_put_autosuspend(&hdmi->pdev->dev);
-
-	return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?
-			connector_status_connected : connector_status_disconnected;
-}
-
-#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) ?
-			connector_status_connected :
-			connector_status_disconnected;
-}
-
-static enum drm_connector_status hdmi_connector_detect(
-		struct drm_connector *connector, bool force)
-{
-	struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
-	struct hdmi *hdmi = hdmi_connector->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;
-
-	/*
-	 * 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)
-		return detect_reg(hdmi);
-
-	do {
-		stat_gpio = detect_gpio(hdmi);
-		stat_reg  = detect_reg(hdmi);
-
-		if (stat_gpio == stat_reg)
-			break;
-
-		mdelay(10);
-	} while (--retry);
-
-	/* the status we get from reading gpio seems to be more reliable,
-	 * so trust that one the most if we didn't manage to get hdmi and
-	 * gpio status to agree:
-	 */
-	if (stat_gpio != stat_reg) {
-		DBG("HDMI_HPD_INT_STATUS tells us: %d", stat_reg);
-		DBG("hpd gpio tells us: %d", stat_gpio);
-	}
-
-	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;
-}
diff --git a/kernel/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c b/kernel/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
new file mode 100644
index 0000000..52ebe56
--- /dev/null
+++ b/kernel/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
@@ -0,0 +1,269 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/pinctrl/consumer.h>
+
+#include "msm_kms.h"
+#include "hdmi.h"
+
+static void msm_hdmi_phy_reset(struct hdmi *hdmi)
+{
+	unsigned int val;
+
+	val = hdmi_read(hdmi, REG_HDMI_PHY_CTRL);
+
+	if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
+		/* pull low */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val & ~HDMI_PHY_CTRL_SW_RESET);
+	} else {
+		/* pull high */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val | HDMI_PHY_CTRL_SW_RESET);
+	}
+
+	if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
+		/* pull low */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
+	} else {
+		/* pull high */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val | HDMI_PHY_CTRL_SW_RESET_PLL);
+	}
+
+	msleep(100);
+
+	if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
+		/* pull high */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val | HDMI_PHY_CTRL_SW_RESET);
+	} else {
+		/* pull low */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val & ~HDMI_PHY_CTRL_SW_RESET);
+	}
+
+	if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
+		/* pull high */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val | HDMI_PHY_CTRL_SW_RESET_PLL);
+	} else {
+		/* pull low */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
+	}
+}
+
+static void enable_hpd_clocks(struct hdmi *hdmi, bool enable)
+{
+	const struct hdmi_platform_config *config = hdmi->config;
+	struct device *dev = &hdmi->pdev->dev;
+	int i, ret;
+
+	if (enable) {
+		for (i = 0; i < config->hpd_clk_cnt; i++) {
+			if (config->hpd_freq && config->hpd_freq[i]) {
+				ret = clk_set_rate(hdmi->hpd_clks[i],
+						   config->hpd_freq[i]);
+				if (ret)
+					dev_warn(dev,
+						 "failed to set clk %s (%d)\n",
+						 config->hpd_clk_names[i], ret);
+			}
+
+			ret = clk_prepare_enable(hdmi->hpd_clks[i]);
+			if (ret) {
+				DRM_DEV_ERROR(dev,
+					"failed to enable hpd clk: %s (%d)\n",
+					config->hpd_clk_names[i], ret);
+			}
+		}
+	} else {
+		for (i = config->hpd_clk_cnt - 1; i >= 0; i--)
+			clk_disable_unprepare(hdmi->hpd_clks[i]);
+	}
+}
+
+int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
+{
+	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;
+	int i, ret;
+	unsigned long flags;
+
+	for (i = 0; i < config->hpd_reg_cnt; i++) {
+		ret = regulator_enable(hdmi->hpd_regs[i]);
+		if (ret) {
+			DRM_DEV_ERROR(dev, "failed to enable hpd regulator: %s (%d)\n",
+					config->hpd_reg_names[i], ret);
+			goto fail;
+		}
+	}
+
+	ret = pinctrl_pm_select_default_state(dev);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "pinctrl state chg failed: %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);
+
+	msm_hdmi_set_mode(hdmi, false);
+	msm_hdmi_phy_reset(hdmi);
+	msm_hdmi_set_mode(hdmi, true);
+
+	hdmi_write(hdmi, REG_HDMI_USEC_REFTIMER, 0x0001001b);
+
+	/* enable HPD events: */
+	hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
+			HDMI_HPD_INT_CTRL_INT_CONNECT |
+			HDMI_HPD_INT_CTRL_INT_EN);
+
+	/* set timeout to 4.1ms (max) for hardware debounce */
+	spin_lock_irqsave(&hdmi->reg_lock, flags);
+	hpd_ctrl = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
+	hpd_ctrl |= HDMI_HPD_CTRL_TIMEOUT(0x1fff);
+
+	/* Toggle HPD circuit to trigger HPD sense */
+	hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
+			~HDMI_HPD_CTRL_ENABLE & hpd_ctrl);
+	hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
+			HDMI_HPD_CTRL_ENABLE | hpd_ctrl);
+	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+
+	return 0;
+
+fail:
+	return ret;
+}
+
+void msm_hdmi_hpd_disable(struct hdmi_bridge *hdmi_bridge)
+{
+	struct hdmi *hdmi = hdmi_bridge->hdmi;
+	const struct hdmi_platform_config *config = hdmi->config;
+	struct device *dev = &hdmi->pdev->dev;
+	int i, ret = 0;
+
+	/* Disable HPD interrupt */
+	hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, 0);
+
+	msm_hdmi_set_mode(hdmi, false);
+
+	enable_hpd_clocks(hdmi, false);
+	pm_runtime_put_autosuspend(dev);
+
+	ret = pinctrl_pm_select_sleep_state(dev);
+	if (ret)
+		dev_warn(dev, "pinctrl state chg failed: %d\n", ret);
+
+	for (i = 0; i < config->hpd_reg_cnt; i++) {
+		ret = regulator_disable(hdmi->hpd_regs[i]);
+		if (ret)
+			dev_warn(dev, "failed to disable hpd regulator: %s (%d)\n",
+					config->hpd_reg_names[i], ret);
+	}
+}
+
+void msm_hdmi_hpd_irq(struct drm_bridge *bridge)
+{
+	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: */
+	hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
+	hpd_int_ctrl   = hdmi_read(hdmi, REG_HDMI_HPD_INT_CTRL);
+
+	if ((hpd_int_ctrl & HDMI_HPD_INT_CTRL_INT_EN) &&
+			(hpd_int_status & HDMI_HPD_INT_STATUS_INT)) {
+		bool detected = !!(hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED);
+
+		/* ack & disable (temporarily) HPD events: */
+		hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
+			HDMI_HPD_INT_CTRL_INT_ACK);
+
+		DBG("status=%04x, ctrl=%04x", hpd_int_status, hpd_int_ctrl);
+
+		/* detect disconnect if we are connected or visa versa: */
+		hpd_int_ctrl = HDMI_HPD_INT_CTRL_INT_EN;
+		if (!detected)
+			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_bridge->hpd_work);
+	}
+}
+
+static enum drm_connector_status detect_reg(struct hdmi *hdmi)
+{
+	uint32_t hpd_int_status;
+
+	pm_runtime_get_sync(&hdmi->pdev->dev);
+	enable_hpd_clocks(hdmi, true);
+
+	hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
+
+	enable_hpd_clocks(hdmi, false);
+	pm_runtime_put_autosuspend(&hdmi->pdev->dev);
+
+	return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?
+			connector_status_connected : connector_status_disconnected;
+}
+
+#define HPD_GPIO_INDEX	2
+static enum drm_connector_status detect_gpio(struct hdmi *hdmi)
+{
+	return gpiod_get_value(hdmi->hpd_gpiod) ?
+			connector_status_connected :
+			connector_status_disconnected;
+}
+
+enum drm_connector_status msm_hdmi_bridge_detect(
+		struct drm_bridge *bridge)
+{
+	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+	struct hdmi *hdmi = hdmi_bridge->hdmi;
+	enum drm_connector_status stat_gpio, stat_reg;
+	int retry = 20;
+
+	/*
+	 * some platforms may not have hpd gpio. Rely only on the status
+	 * provided by REG_HDMI_HPD_INT_STATUS in this case.
+	 */
+	if (!hdmi->hpd_gpiod)
+		return detect_reg(hdmi);
+
+	do {
+		stat_gpio = detect_gpio(hdmi);
+		stat_reg  = detect_reg(hdmi);
+
+		if (stat_gpio == stat_reg)
+			break;
+
+		mdelay(10);
+	} while (--retry);
+
+	/* the status we get from reading gpio seems to be more reliable,
+	 * so trust that one the most if we didn't manage to get hdmi and
+	 * gpio status to agree:
+	 */
+	if (stat_gpio != stat_reg) {
+		DBG("HDMI_HPD_INT_STATUS tells us: %d", stat_reg);
+		DBG("hpd gpio tells us: %d", stat_gpio);
+	}
+
+	return stat_gpio;
+}
diff --git a/kernel/drivers/gpu/drm/msm/msm_fence.c b/kernel/drivers/gpu/drm/msm/msm_fence.c
index cd59a59..50a25c1 100644
--- a/kernel/drivers/gpu/drm/msm/msm_fence.c
+++ b/kernel/drivers/gpu/drm/msm/msm_fence.c
@@ -20,7 +20,7 @@
 		return ERR_PTR(-ENOMEM);
 
 	fctx->dev = dev;
-	strncpy(fctx->name, name, sizeof(fctx->name));
+	strscpy(fctx->name, name, sizeof(fctx->name));
 	fctx->context = dma_fence_context_alloc(1);
 	init_waitqueue_head(&fctx->event);
 	spin_lock_init(&fctx->spinlock);
diff --git a/kernel/drivers/gpu/drm/msm/msm_gem_submit.c b/kernel/drivers/gpu/drm/msm/msm_gem_submit.c
index aa5c60a..c4e5037 100644
--- a/kernel/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/kernel/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -494,8 +494,8 @@
 	int ret = 0;
 	uint32_t i, j;
 
-	post_deps = kmalloc_array(nr_syncobjs, sizeof(*post_deps),
-	                          GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
+	post_deps = kcalloc(nr_syncobjs, sizeof(*post_deps),
+			    GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
 	if (!post_deps)
 		return ERR_PTR(-ENOMEM);
 
@@ -510,7 +510,6 @@
 		}
 
 		post_deps[i].point = syncobj_desc.point;
-		post_deps[i].chain = NULL;
 
 		if (syncobj_desc.flags) {
 			ret = -EINVAL;
diff --git a/kernel/drivers/gpu/drm/msm/msm_iommu.c b/kernel/drivers/gpu/drm/msm/msm_iommu.c
index 2dcb7d1..becefff 100644
--- a/kernel/drivers/gpu/drm/msm/msm_iommu.c
+++ b/kernel/drivers/gpu/drm/msm/msm_iommu.c
@@ -154,7 +154,12 @@
 	/* Get the pagetable configuration from the domain */
 	if (adreno_smmu->cookie)
 		ttbr1_cfg = adreno_smmu->get_ttbr1_cfg(adreno_smmu->cookie);
-	if (!ttbr1_cfg)
+
+	/*
+	 * If you hit this WARN_ONCE() you are probably missing an entry in
+	 * qcom_smmu_impl_of_match[] in arm-smmu-qcom.c
+	 */
+	if (WARN_ONCE(!ttbr1_cfg, "No per-process page tables"))
 		return ERR_PTR(-ENODEV);
 
 	pagetable = kzalloc(sizeof(*pagetable), GFP_KERNEL);
diff --git a/kernel/drivers/gpu/drm/msm/msm_ringbuffer.c b/kernel/drivers/gpu/drm/msm/msm_ringbuffer.c
index 935bf9b..1b6958e 100644
--- a/kernel/drivers/gpu/drm/msm/msm_ringbuffer.c
+++ b/kernel/drivers/gpu/drm/msm/msm_ringbuffer.c
@@ -46,7 +46,7 @@
 	ring->memptrs_iova = memptrs_iova;
 
 	INIT_LIST_HEAD(&ring->submits);
-	spin_lock_init(&ring->lock);
+	spin_lock_init(&ring->preempt_lock);
 
 	snprintf(name, sizeof(name), "gpu-ring-%d", ring->id);
 
diff --git a/kernel/drivers/gpu/drm/msm/msm_ringbuffer.h b/kernel/drivers/gpu/drm/msm/msm_ringbuffer.h
index 0987d6b..4956d1b 100644
--- a/kernel/drivers/gpu/drm/msm/msm_ringbuffer.h
+++ b/kernel/drivers/gpu/drm/msm/msm_ringbuffer.h
@@ -46,7 +46,12 @@
 	struct msm_rbmemptrs *memptrs;
 	uint64_t memptrs_iova;
 	struct msm_fence_context *fctx;
-	spinlock_t lock;
+
+	/*
+	 * preempt_lock protects preemption and serializes wptr updates against
+	 * preemption.  Can be aquired from irq context.
+	 */
+	spinlock_t preempt_lock;
 };
 
 struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id,
diff --git a/kernel/drivers/gpu/drm/mxsfb/Kconfig b/kernel/drivers/gpu/drm/mxsfb/Kconfig
index ee22cd2..e7201e1 100644
--- a/kernel/drivers/gpu/drm/mxsfb/Kconfig
+++ b/kernel/drivers/gpu/drm/mxsfb/Kconfig
@@ -8,6 +8,7 @@
 	tristate "i.MX (e)LCDIF LCD controller"
 	depends on DRM && OF
 	depends on COMMON_CLK
+	depends on ARCH_MXS || ARCH_MXC || COMPILE_TEST
 	select DRM_MXS
 	select DRM_KMS_HELPER
 	select DRM_KMS_CMA_HELPER
diff --git a/kernel/drivers/gpu/drm/nouveau/dispnv50/disp.c b/kernel/drivers/gpu/drm/nouveau/dispnv50/disp.c
index c2d34c9..0ac1202 100644
--- a/kernel/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/kernel/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -396,6 +396,35 @@
 	return 0;
 }
 
+static void
+nv50_outp_atomic_fix_depth(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state)
+{
+	struct nv50_head_atom *asyh = nv50_head_atom(crtc_state);
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_display_mode *mode = &asyh->state.adjusted_mode;
+	unsigned int max_rate, mode_rate;
+
+	switch (nv_encoder->dcb->type) {
+	case DCB_OUTPUT_DP:
+		max_rate = nv_encoder->dp.link_nr * nv_encoder->dp.link_bw;
+
+		/* we don't support more than 10 anyway */
+		asyh->or.bpc = min_t(u8, asyh->or.bpc, 10);
+
+		/* reduce the bpc until it works out */
+		while (asyh->or.bpc > 6) {
+			mode_rate = DIV_ROUND_UP(mode->clock * asyh->or.bpc * 3, 8);
+			if (mode_rate <= max_rate)
+				break;
+
+			asyh->or.bpc -= 2;
+		}
+		break;
+	default:
+		break;
+	}
+}
+
 static int
 nv50_outp_atomic_check(struct drm_encoder *encoder,
 		       struct drm_crtc_state *crtc_state,
@@ -413,6 +442,9 @@
 
 	if (crtc_state->mode_changed || crtc_state->connectors_changed)
 		asyh->or.bpc = connector->display_info.bpc;
+
+	/* We might have to reduce the bpc */
+	nv50_outp_atomic_fix_depth(encoder, crtc_state);
 
 	return 0;
 }
@@ -2555,14 +2587,6 @@
 {
 	struct nouveau_drm *drm = nouveau_drm(dev);
 	struct drm_encoder *encoder;
-	struct drm_plane *plane;
-
-	drm_for_each_plane(plane, dev) {
-		struct nv50_wndw *wndw = nv50_wndw(plane);
-		if (plane->funcs != &nv50_wndw)
-			continue;
-		nv50_wndw_fini(wndw);
-	}
 
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 		if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST)
@@ -2578,7 +2602,6 @@
 {
 	struct nv50_core *core = nv50_disp(dev)->core;
 	struct drm_encoder *encoder;
-	struct drm_plane *plane;
 
 	if (resume || runtime)
 		core->func->init(core);
@@ -2589,13 +2612,6 @@
 				nouveau_encoder(encoder);
 			nv50_mstm_init(nv_encoder, runtime);
 		}
-	}
-
-	drm_for_each_plane(plane, dev) {
-		struct nv50_wndw *wndw = nv50_wndw(plane);
-		if (plane->funcs != &nv50_wndw)
-			continue;
-		nv50_wndw_init(wndw);
 	}
 
 	return 0;
diff --git a/kernel/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/kernel/drivers/gpu/drm/nouveau/dispnv50/wndw.c
index f07916f..831125b 100644
--- a/kernel/drivers/gpu/drm/nouveau/dispnv50/wndw.c
+++ b/kernel/drivers/gpu/drm/nouveau/dispnv50/wndw.c
@@ -690,18 +690,6 @@
 	return NVIF_NOTIFY_KEEP;
 }
 
-void
-nv50_wndw_fini(struct nv50_wndw *wndw)
-{
-	nvif_notify_put(&wndw->notify);
-}
-
-void
-nv50_wndw_init(struct nv50_wndw *wndw)
-{
-	nvif_notify_get(&wndw->notify);
-}
-
 static const u64 nv50_cursor_format_modifiers[] = {
 	DRM_FORMAT_MOD_LINEAR,
 	DRM_FORMAT_MOD_INVALID,
diff --git a/kernel/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/kernel/drivers/gpu/drm/nouveau/dispnv50/wndw.h
index 3278e28..77bf124 100644
--- a/kernel/drivers/gpu/drm/nouveau/dispnv50/wndw.h
+++ b/kernel/drivers/gpu/drm/nouveau/dispnv50/wndw.h
@@ -38,10 +38,9 @@
 
 int nv50_wndw_new_(const struct nv50_wndw_func *, struct drm_device *,
 		   enum drm_plane_type, const char *name, int index,
-		   const u32 *format, enum nv50_disp_interlock_type,
-		   u32 interlock_data, u32 heads, struct nv50_wndw **);
-void nv50_wndw_init(struct nv50_wndw *);
-void nv50_wndw_fini(struct nv50_wndw *);
+		   const u32 *format, u32 heads,
+		   enum nv50_disp_interlock_type, u32 interlock_data,
+		   struct nv50_wndw **);
 void nv50_wndw_flush_set(struct nv50_wndw *, u32 *interlock,
 			 struct nv50_wndw_atom *);
 void nv50_wndw_flush_clr(struct nv50_wndw *, u32 *interlock, bool flush,
diff --git a/kernel/drivers/gpu/drm/nouveau/nouveau_acpi.c b/kernel/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 69a84d0..7b946d4 100644
--- a/kernel/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/kernel/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -220,6 +220,9 @@
 	int optimus_funcs;
 	struct pci_dev *parent_pdev;
 
+	if (pdev->vendor != PCI_VENDOR_ID_NVIDIA)
+		return;
+
 	*has_pr3 = false;
 	parent_pdev = pci_upstream_bridge(pdev);
 	if (parent_pdev) {
diff --git a/kernel/drivers/gpu/drm/nouveau/nouveau_bo.c b/kernel/drivers/gpu/drm/nouveau/nouveau_bo.c
index b57dcad..7633f56 100644
--- a/kernel/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/kernel/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -823,6 +823,15 @@
 		if (ret == 0) {
 			ret = nouveau_fence_new(chan, false, &fence);
 			if (ret == 0) {
+				/* TODO: figure out a better solution here
+				 *
+				 * wait on the fence here explicitly as going through
+				 * ttm_bo_move_accel_cleanup somehow doesn't seem to do it.
+				 *
+				 * Without this the operation can timeout and we'll fallback to a
+				 * software copy, which might take several minutes to finish.
+				 */
+				nouveau_fence_wait(fence, false, false);
 				ret = ttm_bo_move_accel_cleanup(bo,
 								&fence->base,
 								evict, false,
diff --git a/kernel/drivers/gpu/drm/nouveau/nouveau_connector.c b/kernel/drivers/gpu/drm/nouveau/nouveau_connector.c
index 9542fc6..d2cefca 100644
--- a/kernel/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/kernel/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -726,7 +726,8 @@
 #endif
 
 	nouveau_connector_set_edid(nv_connector, edid);
-	nouveau_connector_set_encoder(connector, nv_encoder);
+	if (nv_encoder)
+		nouveau_connector_set_encoder(connector, nv_encoder);
 	return status;
 }
 
@@ -967,7 +968,7 @@
 	 * "native" mode as some VBIOS tables require us to use the
 	 * pixel clock as part of the lookup...
 	 */
-	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
+	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS && nv_connector->native_mode)
 		nouveau_connector_detect_depth(connector);
 
 	if (nv_encoder->dcb->type == DCB_OUTPUT_TV)
diff --git a/kernel/drivers/gpu/drm/nouveau/nouveau_dp.c b/kernel/drivers/gpu/drm/nouveau/nouveau_dp.c
index 040ed88..447b759 100644
--- a/kernel/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/kernel/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -220,8 +220,6 @@
 }
 
 /* TODO:
- * - Use the minimum possible BPC here, once we add support for the max bpc
- *   property.
  * - Validate against the DP caps advertised by the GPU (we don't check these
  *   yet)
  */
@@ -233,7 +231,11 @@
 {
 	const unsigned int min_clock = 25000;
 	unsigned int max_rate, mode_rate, ds_max_dotclock, clock = mode->clock;
-	const u8 bpp = connector->display_info.bpc * 3;
+	/* Check with the minmum bpc always, so we can advertise better modes.
+	 * In particlar not doing this causes modes to be dropped on HDR
+	 * displays as we might check with a bpc of 16 even.
+	 */
+	const u8 bpp = 6 * 3;
 
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE && !outp->caps.dp_interlace)
 		return MODE_NO_INTERLACE;
diff --git a/kernel/drivers/gpu/drm/nouveau/nouveau_drm.c b/kernel/drivers/gpu/drm/nouveau/nouveau_drm.c
index ac96b6a..8e15ff9 100644
--- a/kernel/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/kernel/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -124,10 +124,16 @@
 static inline bool
 nouveau_cli_work_ready(struct dma_fence *fence)
 {
-	if (!dma_fence_is_signaled(fence))
-		return false;
-	dma_fence_put(fence);
-	return true;
+	bool ret = true;
+
+	spin_lock_irq(fence->lock);
+	if (!dma_fence_is_signaled_locked(fence))
+		ret = false;
+	spin_unlock_irq(fence->lock);
+
+	if (ret == true)
+		dma_fence_put(fence);
+	return ret;
 }
 
 static void
diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h
index 32bbddc..679aff7 100644
--- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h
+++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h
@@ -123,6 +123,7 @@
 
 extern const struct gf100_grctx_func gk110_grctx;
 void gk110_grctx_generate_r419eb0(struct gf100_gr *);
+void gk110_grctx_generate_r419f78(struct gf100_gr *);
 
 extern const struct gf100_grctx_func gk110b_grctx;
 extern const struct gf100_grctx_func gk208_grctx;
diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c
index 304e9d2..f894f82 100644
--- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c
+++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c
@@ -916,7 +916,9 @@
 gk104_grctx_generate_r419f78(struct gf100_gr *gr)
 {
 	struct nvkm_device *device = gr->base.engine.subdev.device;
-	nvkm_mask(device, 0x419f78, 0x00000001, 0x00000000);
+
+	/* bit 3 set disables loads in fp helper invocations, we need it enabled */
+	nvkm_mask(device, 0x419f78, 0x00000009, 0x00000000);
 }
 
 void
diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c
index 86547cf..e88740d 100644
--- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c
+++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c
@@ -820,6 +820,15 @@
 	nvkm_mask(device, 0x419eb0, 0x00001000, 0x00001000);
 }
 
+void
+gk110_grctx_generate_r419f78(struct gf100_gr *gr)
+{
+	struct nvkm_device *device = gr->base.engine.subdev.device;
+
+	/* bit 3 set disables loads in fp helper invocations, we need it enabled */
+	nvkm_mask(device, 0x419f78, 0x00000008, 0x00000000);
+}
+
 const struct gf100_grctx_func
 gk110_grctx = {
 	.main  = gf100_grctx_generate_main,
@@ -852,4 +861,5 @@
 	.gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr,
 	.r418800 = gk104_grctx_generate_r418800,
 	.r419eb0 = gk110_grctx_generate_r419eb0,
+	.r419f78 = gk110_grctx_generate_r419f78,
 };
diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c
index ebb947b..086e4d4 100644
--- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c
+++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c
@@ -101,4 +101,5 @@
 	.gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr,
 	.r418800 = gk104_grctx_generate_r418800,
 	.r419eb0 = gk110_grctx_generate_r419eb0,
+	.r419f78 = gk110_grctx_generate_r419f78,
 };
diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c
index 4d40512..0bf438c 100644
--- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c
+++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c
@@ -566,4 +566,5 @@
 	.dist_skip_table = gf117_grctx_generate_dist_skip_table,
 	.gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr,
 	.r418800 = gk104_grctx_generate_r418800,
+	.r419f78 = gk110_grctx_generate_r419f78,
 };
diff --git a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c
index 0b3964e..acdf093 100644
--- a/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c
+++ b/kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c
@@ -991,4 +991,5 @@
 	.r406500 = gm107_grctx_generate_r406500,
 	.gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr,
 	.r419e00 = gm107_grctx_generate_r419e00,
+	.r419f78 = gk110_grctx_generate_r419f78,
 };
diff --git a/kernel/drivers/gpu/drm/omapdrm/dss/dsi.c b/kernel/drivers/gpu/drm/omapdrm/dss/dsi.c
index eeccf40..1b1ddc5 100644
--- a/kernel/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/kernel/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -1444,22 +1444,26 @@
 {
 	struct dsi_data *dsi = s->private;
 	unsigned long flags;
-	struct dsi_irq_stats stats;
+	struct dsi_irq_stats *stats;
+
+	stats = kmalloc(sizeof(*stats), GFP_KERNEL);
+	if (!stats)
+		return -ENOMEM;
 
 	spin_lock_irqsave(&dsi->irq_stats_lock, flags);
 
-	stats = dsi->irq_stats;
+	*stats = dsi->irq_stats;
 	memset(&dsi->irq_stats, 0, sizeof(dsi->irq_stats));
 	dsi->irq_stats.last_reset = jiffies;
 
 	spin_unlock_irqrestore(&dsi->irq_stats_lock, flags);
 
 	seq_printf(s, "period %u ms\n",
-			jiffies_to_msecs(jiffies - stats.last_reset));
+			jiffies_to_msecs(jiffies - stats->last_reset));
 
-	seq_printf(s, "irqs %d\n", stats.irq_count);
+	seq_printf(s, "irqs %d\n", stats->irq_count);
 #define PIS(x) \
-	seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]);
+	seq_printf(s, "%-20s %10d\n", #x, stats->dsi_irqs[ffs(DSI_IRQ_##x)-1]);
 
 	seq_printf(s, "-- DSI%d interrupts --\n", dsi->module_id + 1);
 	PIS(VC0);
@@ -1483,10 +1487,10 @@
 
 #define PIS(x) \
 	seq_printf(s, "%-20s %10d %10d %10d %10d\n", #x, \
-			stats.vc_irqs[0][ffs(DSI_VC_IRQ_##x)-1], \
-			stats.vc_irqs[1][ffs(DSI_VC_IRQ_##x)-1], \
-			stats.vc_irqs[2][ffs(DSI_VC_IRQ_##x)-1], \
-			stats.vc_irqs[3][ffs(DSI_VC_IRQ_##x)-1]);
+			stats->vc_irqs[0][ffs(DSI_VC_IRQ_##x)-1], \
+			stats->vc_irqs[1][ffs(DSI_VC_IRQ_##x)-1], \
+			stats->vc_irqs[2][ffs(DSI_VC_IRQ_##x)-1], \
+			stats->vc_irqs[3][ffs(DSI_VC_IRQ_##x)-1]);
 
 	seq_printf(s, "-- VC interrupts --\n");
 	PIS(CS);
@@ -1502,7 +1506,7 @@
 
 #define PIS(x) \
 	seq_printf(s, "%-20s %10d\n", #x, \
-			stats.cio_irqs[ffs(DSI_CIO_IRQ_##x)-1]);
+			stats->cio_irqs[ffs(DSI_CIO_IRQ_##x)-1]);
 
 	seq_printf(s, "-- CIO interrupts --\n");
 	PIS(ERRSYNCESC1);
@@ -1527,6 +1531,8 @@
 	PIS(ULPSACTIVENOT_ALL1);
 #undef PIS
 
+	kfree(stats);
+
 	return 0;
 }
 #endif
diff --git a/kernel/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c b/kernel/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
index 6ac1acc..b19597b 100644
--- a/kernel/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
+++ b/kernel/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
@@ -458,7 +458,7 @@
 		       DRM_MODE_CONNECTOR_DSI);
 
 	ctx->bl_dev = devm_backlight_device_register(dev, dev_name(dev),
-						     dsi->host->dev, ctx,
+						     dev, ctx,
 						     &otm8009a_backlight_ops,
 						     NULL);
 	if (IS_ERR(ctx->bl_dev)) {
diff --git a/kernel/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c b/kernel/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
index 16dbf0f..1f5fb15 100644
--- a/kernel/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
+++ b/kernel/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
@@ -192,15 +192,15 @@
 }
 
 static const struct drm_display_mode default_mode = {
-	.clock = 41118,
+	.clock = (540 + 48 + 32 + 80) * (960 + 3 + 10 + 15) * 60 / 1000,
 	.hdisplay = 540,
 	.hsync_start = 540 + 48,
-	.hsync_end = 540 + 48 + 80,
-	.htotal = 540 + 48 + 80 + 32,
+	.hsync_end = 540 + 48 + 32,
+	.htotal = 540 + 48 + 32 + 80,
 	.vdisplay = 960,
 	.vsync_start = 960 + 3,
-	.vsync_end = 960 + 3 + 15,
-	.vtotal = 960 + 3 + 15 + 1,
+	.vsync_end = 960 + 3 + 10,
+	.vtotal = 960 + 3 + 10 + 15,
 };
 
 static int sharp_nt_panel_get_modes(struct drm_panel *panel,
@@ -280,6 +280,7 @@
 	dsi->lanes = 2;
 	dsi->format = MIPI_DSI_FMT_RGB888;
 	dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
+			MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
 			MIPI_DSI_MODE_VIDEO_HSE |
 			MIPI_DSI_CLOCK_NON_CONTINUOUS |
 			MIPI_DSI_MODE_EOT_PACKET;
diff --git a/kernel/drivers/gpu/drm/panel/panel-simple.c b/kernel/drivers/gpu/drm/panel/panel-simple.c
index 5d8a58b..422c096 100644
--- a/kernel/drivers/gpu/drm/panel/panel-simple.c
+++ b/kernel/drivers/gpu/drm/panel/panel-simple.c
@@ -160,6 +160,11 @@
 	enum drm_panel_orientation orientation;
 };
 
+static inline void panel_simple_msleep(unsigned int msecs)
+{
+	usleep_range(msecs * 1000, msecs * 1000 + 100);
+}
+
 static inline struct panel_simple *to_panel_simple(struct drm_panel *panel)
 {
 	return container_of(panel, struct panel_simple, base);
@@ -277,7 +282,7 @@
 			dev_err(dev, "failed to write dcs cmd: %d\n", err);
 
 		if (cmd->header.delay)
-			usleep_range(cmd->header.delay * 1000, cmd->header.delay * 1000 + 100);
+			panel_simple_msleep(cmd->header.delay);
 	}
 
 	return 0;
@@ -300,7 +305,7 @@
 			return ret;
 
 		if (cmd->header.delay)
-			usleep_range(cmd->header.delay * 1000, cmd->header.delay * 1000 + 100);
+			panel_simple_msleep(cmd->header.delay);
 	}
 
 	return 0;
@@ -478,7 +483,7 @@
 		return 0;
 
 	if (p->desc->delay.disable)
-		usleep_range(p->desc->delay.disable * 1000, p->desc->delay.disable * 1000 + 100);
+		panel_simple_msleep(p->desc->delay.disable);
 
 	p->enabled = false;
 
@@ -510,7 +515,7 @@
 	panel_simple_regulator_disable(p);
 
 	if (p->desc->delay.unprepare)
-		usleep_range(p->desc->delay.unprepare * 1000, p->desc->delay.unprepare * 1000 + 100);
+		panel_simple_msleep(p->desc->delay.unprepare);
 
 	p->prepared = false;
 
@@ -564,7 +569,7 @@
 	if (p->no_hpd)
 		delay += p->desc->delay.hpd_absent_delay;
 	if (delay)
-		usleep_range(delay * 1000, delay * 1000 + 100);
+		panel_simple_msleep(delay);
 
 	if (p->hpd_gpio) {
 		if (IS_ERR(p->hpd_gpio)) {
@@ -589,12 +594,12 @@
 	gpiod_direction_output(p->reset_gpio, 1);
 
 	if (p->desc->delay.reset)
-		usleep_range(p->desc->delay.reset * 1000, p->desc->delay.reset * 1000 + 100);
+		panel_simple_msleep(p->desc->delay.reset);
 
 	gpiod_direction_output(p->reset_gpio, 0);
 
 	if (p->desc->delay.init)
-		usleep_range(p->desc->delay.init * 1000, p->desc->delay.init * 1000 + 100);
+		panel_simple_msleep(p->desc->delay.init);
 
 	if (p->desc->init_seq) {
 		if (p->desc->cmd_type == CMD_TYPE_SPI) {
@@ -621,7 +626,7 @@
 		return 0;
 
 	if (p->desc->delay.enable)
-		usleep_range(p->desc->delay.enable * 1000, p->desc->delay.enable * 1000 + 100);
+		panel_simple_msleep(p->desc->delay.enable);
 
 	p->enabled = true;
 
@@ -1042,8 +1047,8 @@
 	.num_modes = 1,
 	.bpc = 8,
 	.size = {
-		.width = 105,
-		.height = 67,
+		.width = 99,
+		.height = 58,
 	},
 	.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 };
@@ -1348,21 +1353,21 @@
 	},
 };
 
-static const struct drm_display_mode auo_g121ean01_mode = {
-	.clock = 66700,
-	.hdisplay = 1280,
-	.hsync_start = 1280 + 58,
-	.hsync_end = 1280 + 58 + 8,
-	.htotal = 1280 + 58 + 8 + 70,
-	.vdisplay = 800,
-	.vsync_start = 800 + 6,
-	.vsync_end = 800 + 6 + 4,
-	.vtotal = 800 + 6 + 4 + 10,
+static const struct display_timing auo_g121ean01_timing = {
+	.pixelclock = { 60000000, 74400000, 90000000 },
+	.hactive = { 1280, 1280, 1280 },
+	.hfront_porch = { 20, 50, 100 },
+	.hback_porch = { 20, 50, 100 },
+	.hsync_len = { 30, 100, 200 },
+	.vactive = { 800, 800, 800 },
+	.vfront_porch = { 2, 10, 25 },
+	.vback_porch = { 2, 10, 25 },
+	.vsync_len = { 4, 18, 50 },
 };
 
 static const struct panel_desc auo_g121ean01 = {
-	.modes = &auo_g121ean01_mode,
-	.num_modes = 1,
+	.timings = &auo_g121ean01_timing,
+	.num_timings = 1,
 	.bpc = 8,
 	.size = {
 		.width = 261,
@@ -1538,7 +1543,9 @@
 	.delay = {
 		.disable = 5,
 		.unprepare = 1000,
-	}
+	},
+	.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
+	.connector_type = DRM_MODE_CONNECTOR_LVDS,
 };
 
 static const struct drm_display_mode avic_tm070ddh03_mode = {
@@ -2429,6 +2436,7 @@
 		.height = 54,
 	},
 	.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
+	.connector_type = DRM_MODE_CONNECTOR_DPI,
 	.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
 };
 
@@ -3490,6 +3498,7 @@
 	.vsync_start = 480 + 49,
 	.vsync_end = 480 + 49 + 2,
 	.vtotal = 480 + 49 + 2 + 22,
+	.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
 };
 
 static const struct panel_desc powertip_ph800480t013_idf02  = {
diff --git a/kernel/drivers/gpu/drm/panel/panel-sitronix-st7701.c b/kernel/drivers/gpu/drm/panel/panel-sitronix-st7701.c
index 4d2a149..cd9f019 100644
--- a/kernel/drivers/gpu/drm/panel/panel-sitronix-st7701.c
+++ b/kernel/drivers/gpu/drm/panel/panel-sitronix-st7701.c
@@ -384,7 +384,15 @@
 	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)
diff --git a/kernel/drivers/gpu/drm/panfrost/Kconfig b/kernel/drivers/gpu/drm/panfrost/Kconfig
index 86cdc0c..77f4d32 100644
--- a/kernel/drivers/gpu/drm/panfrost/Kconfig
+++ b/kernel/drivers/gpu/drm/panfrost/Kconfig
@@ -3,7 +3,8 @@
 config DRM_PANFROST
 	tristate "Panfrost (DRM support for ARM Mali Midgard/Bifrost GPUs)"
 	depends on DRM
-	depends on ARM || ARM64 || (COMPILE_TEST && !GENERIC_ATOMIC64)
+	depends on ARM || ARM64 || COMPILE_TEST
+	depends on !GENERIC_ATOMIC64    # for IOMMU_IO_PGTABLE_LPAE
 	depends on MMU
 	select DRM_SCHED
 	select IOMMU_SUPPORT
diff --git a/kernel/drivers/gpu/drm/panfrost/panfrost_drv.c b/kernel/drivers/gpu/drm/panfrost/panfrost_drv.c
index 1dfc457..4af25c0 100644
--- a/kernel/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/kernel/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -81,6 +81,7 @@
 	struct panfrost_gem_object *bo;
 	struct drm_panfrost_create_bo *args = data;
 	struct panfrost_gem_mapping *mapping;
+	int ret;
 
 	if (!args->size || args->pad ||
 	    (args->flags & ~(PANFROST_BO_NOEXEC | PANFROST_BO_HEAP)))
@@ -91,21 +92,29 @@
 	    !(args->flags & PANFROST_BO_NOEXEC))
 		return -EINVAL;
 
-	bo = panfrost_gem_create_with_handle(file, dev, args->size, args->flags,
-					     &args->handle);
+	bo = panfrost_gem_create(dev, args->size, args->flags);
 	if (IS_ERR(bo))
 		return PTR_ERR(bo);
 
+	ret = drm_gem_handle_create(file, &bo->base.base, &args->handle);
+	if (ret)
+		goto out;
+
 	mapping = panfrost_gem_mapping_get(bo, priv);
-	if (!mapping) {
-		drm_gem_object_put(&bo->base.base);
-		return -EINVAL;
+	if (mapping) {
+		args->offset = mapping->mmnode.start << PAGE_SHIFT;
+		panfrost_gem_mapping_put(mapping);
+	} else {
+		/* This can only happen if the handle from
+		 * drm_gem_handle_create() has already been guessed and freed
+		 * by user space
+		 */
+		ret = -EINVAL;
 	}
 
-	args->offset = mapping->mmnode.start << PAGE_SHIFT;
-	panfrost_gem_mapping_put(mapping);
-
-	return 0;
+out:
+	drm_gem_object_put(&bo->base.base);
+	return ret;
 }
 
 /**
diff --git a/kernel/drivers/gpu/drm/panfrost/panfrost_gem.c b/kernel/drivers/gpu/drm/panfrost/panfrost_gem.c
index 1d917ce..c843fbf 100644
--- a/kernel/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/kernel/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -232,12 +232,8 @@
 }
 
 struct panfrost_gem_object *
-panfrost_gem_create_with_handle(struct drm_file *file_priv,
-				struct drm_device *dev, size_t size,
-				u32 flags,
-				uint32_t *handle)
+panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags)
 {
-	int ret;
 	struct drm_gem_shmem_object *shmem;
 	struct panfrost_gem_object *bo;
 
@@ -252,16 +248,6 @@
 	bo = to_panfrost_bo(&shmem->base);
 	bo->noexec = !!(flags & PANFROST_BO_NOEXEC);
 	bo->is_heap = !!(flags & PANFROST_BO_HEAP);
-
-	/*
-	 * Allocate an id of idr table where the obj is registered
-	 * and handle has the id what user can see.
-	 */
-	ret = drm_gem_handle_create(file_priv, &shmem->base, handle);
-	/* drop reference from allocate - handle holds it now. */
-	drm_gem_object_put(&shmem->base);
-	if (ret)
-		return ERR_PTR(ret);
 
 	return bo;
 }
diff --git a/kernel/drivers/gpu/drm/panfrost/panfrost_gem.h b/kernel/drivers/gpu/drm/panfrost/panfrost_gem.h
index 8088d5f..ad2877e 100644
--- a/kernel/drivers/gpu/drm/panfrost/panfrost_gem.h
+++ b/kernel/drivers/gpu/drm/panfrost/panfrost_gem.h
@@ -69,10 +69,7 @@
 				   struct sg_table *sgt);
 
 struct panfrost_gem_object *
-panfrost_gem_create_with_handle(struct drm_file *file_priv,
-				struct drm_device *dev, size_t size,
-				u32 flags,
-				uint32_t *handle);
+panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags);
 
 int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv);
 void panfrost_gem_close(struct drm_gem_object *obj,
diff --git a/kernel/drivers/gpu/drm/panfrost/panfrost_mmu.c b/kernel/drivers/gpu/drm/panfrost/panfrost_mmu.c
index 8f7af65..7ab916a 100644
--- a/kernel/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/kernel/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -236,7 +236,7 @@
 	if (pm_runtime_active(pfdev->dev))
 		mmu_hw_do_operation(pfdev, mmu, iova, size, AS_COMMAND_FLUSH_PT);
 
-	pm_runtime_put_sync_autosuspend(pfdev->dev);
+	pm_runtime_put_autosuspend(pfdev->dev);
 }
 
 static int mmu_map_sg(struct panfrost_device *pfdev, struct panfrost_mmu *mmu,
@@ -451,6 +451,7 @@
 		if (IS_ERR(pages[i])) {
 			mutex_unlock(&bo->base.pages_lock);
 			ret = PTR_ERR(pages[i]);
+			pages[i] = NULL;
 			goto err_pages;
 		}
 	}
diff --git a/kernel/drivers/gpu/drm/radeon/atombios_encoders.c b/kernel/drivers/gpu/drm/radeon/atombios_encoders.c
index 12aa787..8cca58f 100644
--- a/kernel/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/kernel/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -2191,11 +2191,12 @@
 
 	/*
 	 * On DCE32 any encoder can drive any block so usually just use crtc id,
-	 * but Apple thinks different at least on iMac10,1, so there use linkb,
+	 * but Apple thinks different at least on iMac10,1 and iMac11,2, so there use linkb,
 	 * otherwise the internal eDP panel will stay dark.
 	 */
 	if (ASIC_IS_DCE32(rdev)) {
-		if (dmi_match(DMI_PRODUCT_NAME, "iMac10,1"))
+		if (dmi_match(DMI_PRODUCT_NAME, "iMac10,1") ||
+		    dmi_match(DMI_PRODUCT_NAME, "iMac11,2"))
 			enc_idx = (dig->linkb) ? 1 : 0;
 		else
 			enc_idx = radeon_crtc->crtc_id;
diff --git a/kernel/drivers/gpu/drm/radeon/ci_dpm.c b/kernel/drivers/gpu/drm/radeon/ci_dpm.c
index 886e995..f98df82 100644
--- a/kernel/drivers/gpu/drm/radeon/ci_dpm.c
+++ b/kernel/drivers/gpu/drm/radeon/ci_dpm.c
@@ -5541,6 +5541,7 @@
 	u8 frev, crev;
 	u8 *power_state_offset;
 	struct ci_ps *ps;
+	int ret;
 
 	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
 				   &frev, &crev, &data_offset))
@@ -5570,11 +5571,15 @@
 		non_clock_array_index = power_state->v2.nonClockInfoIndex;
 		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
 			&non_clock_info_array->nonClockInfo[non_clock_array_index];
-		if (!rdev->pm.power_state[i].clock_info)
-			return -EINVAL;
+		if (!rdev->pm.power_state[i].clock_info) {
+			ret = -EINVAL;
+			goto err_free_ps;
+		}
 		ps = kzalloc(sizeof(struct ci_ps), GFP_KERNEL);
-		if (ps == NULL)
-			return -ENOMEM;
+		if (ps == NULL) {
+			ret = -ENOMEM;
+			goto err_free_ps;
+		}
 		rdev->pm.dpm.ps[i].ps_priv = ps;
 		ci_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
 					      non_clock_info,
@@ -5614,6 +5619,12 @@
 	}
 
 	return 0;
+
+err_free_ps:
+	for (i = 0; i < rdev->pm.dpm.num_ps; i++)
+		kfree(rdev->pm.dpm.ps[i].ps_priv);
+	kfree(rdev->pm.dpm.ps);
+	return ret;
 }
 
 static int ci_get_vbios_boot_values(struct radeon_device *rdev,
@@ -5702,25 +5713,26 @@
 
 	ret = ci_get_vbios_boot_values(rdev, &pi->vbios_boot_state);
 	if (ret) {
-		ci_dpm_fini(rdev);
+		kfree(rdev->pm.dpm.priv);
 		return ret;
 	}
 
 	ret = r600_get_platform_caps(rdev);
 	if (ret) {
-		ci_dpm_fini(rdev);
+		kfree(rdev->pm.dpm.priv);
 		return ret;
 	}
 
 	ret = r600_parse_extended_power_table(rdev);
 	if (ret) {
-		ci_dpm_fini(rdev);
+		kfree(rdev->pm.dpm.priv);
 		return ret;
 	}
 
 	ret = ci_parse_power_table(rdev);
 	if (ret) {
-		ci_dpm_fini(rdev);
+		kfree(rdev->pm.dpm.priv);
+		r600_free_extended_power_table(rdev);
 		return ret;
 	}
 
diff --git a/kernel/drivers/gpu/drm/radeon/cik.c b/kernel/drivers/gpu/drm/radeon/cik.c
index 5c42877..13f25ec 100644
--- a/kernel/drivers/gpu/drm/radeon/cik.c
+++ b/kernel/drivers/gpu/drm/radeon/cik.c
@@ -9551,17 +9551,8 @@
 			u16 bridge_cfg2, gpu_cfg2;
 			u32 max_lw, current_lw, tmp;
 
-			pcie_capability_read_word(root, PCI_EXP_LNKCTL,
-						  &bridge_cfg);
-			pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL,
-						  &gpu_cfg);
-
-			tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
-			pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
-
-			tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
-			pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL,
-						   tmp16);
+			pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
+			pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
 
 			tmp = RREG32_PCIE_PORT(PCIE_LC_STATUS1);
 			max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
@@ -9608,21 +9599,14 @@
 				msleep(100);
 
 				/* linkctl */
-				pcie_capability_read_word(root, PCI_EXP_LNKCTL,
-							  &tmp16);
-				tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
-				tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
-				pcie_capability_write_word(root, PCI_EXP_LNKCTL,
-							   tmp16);
-
-				pcie_capability_read_word(rdev->pdev,
-							  PCI_EXP_LNKCTL,
-							  &tmp16);
-				tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
-				tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
-				pcie_capability_write_word(rdev->pdev,
-							   PCI_EXP_LNKCTL,
-							   tmp16);
+				pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
+								   PCI_EXP_LNKCTL_HAWD,
+								   bridge_cfg &
+								   PCI_EXP_LNKCTL_HAWD);
+				pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL,
+								   PCI_EXP_LNKCTL_HAWD,
+								   gpu_cfg &
+								   PCI_EXP_LNKCTL_HAWD);
 
 				/* linkctl2 */
 				pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
diff --git a/kernel/drivers/gpu/drm/radeon/cypress_dpm.c b/kernel/drivers/gpu/drm/radeon/cypress_dpm.c
index 35b177d..7120710 100644
--- a/kernel/drivers/gpu/drm/radeon/cypress_dpm.c
+++ b/kernel/drivers/gpu/drm/radeon/cypress_dpm.c
@@ -559,8 +559,12 @@
 						     ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
 			u32 reference_clock = rdev->clock.mpll.reference_freq;
 			u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
-			u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
-			u32 clk_v = ss.percentage *
+			u32 clk_s, clk_v;
+
+			if (!decoded_ref)
+				return -EINVAL;
+			clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
+			clk_v = ss.percentage *
 				(0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625);
 
 			mpll_ss1 &= ~CLKV_MASK;
diff --git a/kernel/drivers/gpu/drm/radeon/ni_dpm.c b/kernel/drivers/gpu/drm/radeon/ni_dpm.c
index a521874..f79b348 100644
--- a/kernel/drivers/gpu/drm/radeon/ni_dpm.c
+++ b/kernel/drivers/gpu/drm/radeon/ni_dpm.c
@@ -2240,8 +2240,12 @@
 						     ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
 			u32 reference_clock = rdev->clock.mpll.reference_freq;
 			u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
-			u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
-			u32 clk_v = ss.percentage *
+			u32 clk_s, clk_v;
+
+			if (!decoded_ref)
+				return -EINVAL;
+			clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
+			clk_v = ss.percentage *
 				(0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625);
 
 			mpll_ss1 &= ~CLKV_MASK;
diff --git a/kernel/drivers/gpu/drm/radeon/radeon_bios.c b/kernel/drivers/gpu/drm/radeon/radeon_bios.c
index bb29cf0..0c94147 100644
--- a/kernel/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/kernel/drivers/gpu/drm/radeon/radeon_bios.c
@@ -227,6 +227,7 @@
 
 	if (!found)
 		return false;
+	pci_dev_put(pdev);
 
 	rdev->bios = kmalloc(size, GFP_KERNEL);
 	if (!rdev->bios) {
@@ -612,13 +613,14 @@
 	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 +633,13 @@
 		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 +651,18 @@
 			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)
diff --git a/kernel/drivers/gpu/drm/radeon/radeon_cs.c b/kernel/drivers/gpu/drm/radeon/radeon_cs.c
index 21ce2f9..ea0e6ef 100644
--- a/kernel/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/kernel/drivers/gpu/drm/radeon/radeon_cs.c
@@ -271,7 +271,8 @@
 {
 	struct drm_radeon_cs *cs = data;
 	uint64_t *chunk_array_ptr;
-	unsigned size, i;
+	u64 size;
+	unsigned i;
 	u32 ring = RADEON_CS_RING_GFX;
 	s32 priority = 0;
 
diff --git a/kernel/drivers/gpu/drm/radeon/radeon_device.c b/kernel/drivers/gpu/drm/radeon/radeon_device.c
index 8287410..131f425 100644
--- a/kernel/drivers/gpu/drm/radeon/radeon_device.c
+++ b/kernel/drivers/gpu/drm/radeon/radeon_device.c
@@ -1022,6 +1022,7 @@
 {
 	if (rdev->mode_info.atom_context) {
 		kfree(rdev->mode_info.atom_context->scratch);
+		kfree(rdev->mode_info.atom_context->iio);
 	}
 	kfree(rdev->mode_info.atom_context);
 	rdev->mode_info.atom_context = NULL;
diff --git a/kernel/drivers/gpu/drm/radeon/radeon_gem.c b/kernel/drivers/gpu/drm/radeon/radeon_gem.c
index e5c4271..7505391 100644
--- a/kernel/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/kernel/drivers/gpu/drm/radeon/radeon_gem.c
@@ -385,7 +385,6 @@
 	struct radeon_device *rdev = dev->dev_private;
 	struct drm_radeon_gem_set_domain *args = data;
 	struct drm_gem_object *gobj;
-	struct radeon_bo *robj;
 	int r;
 
 	/* for now if someone requests domain CPU -
@@ -398,13 +397,12 @@
 		up_read(&rdev->exclusive_lock);
 		return -ENOENT;
 	}
-	robj = gem_to_radeon_bo(gobj);
 
 	r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain);
 
 	drm_gem_object_put(gobj);
 	up_read(&rdev->exclusive_lock);
-	r = radeon_gem_handle_lockup(robj->rdev, r);
+	r = radeon_gem_handle_lockup(rdev, r);
 	return r;
 }
 
diff --git a/kernel/drivers/gpu/drm/radeon/rv740_dpm.c b/kernel/drivers/gpu/drm/radeon/rv740_dpm.c
index 327d65a..79b2de6 100644
--- a/kernel/drivers/gpu/drm/radeon/rv740_dpm.c
+++ b/kernel/drivers/gpu/drm/radeon/rv740_dpm.c
@@ -250,8 +250,12 @@
 						     ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
 			u32 reference_clock = rdev->clock.mpll.reference_freq;
 			u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
-			u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
-			u32 clk_v = 0x40000 * ss.percentage *
+			u32 clk_s, clk_v;
+
+			if (!decoded_ref)
+				return -EINVAL;
+			clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
+			clk_v = 0x40000 * ss.percentage *
 				(dividers.whole_fb_div + (dividers.frac_fb_div / 8)) / (clk_s * 10000);
 
 			mpll_ss1 &= ~CLKV_MASK;
diff --git a/kernel/drivers/gpu/drm/radeon/si.c b/kernel/drivers/gpu/drm/radeon/si.c
index 93dcab5..31e2c10 100644
--- a/kernel/drivers/gpu/drm/radeon/si.c
+++ b/kernel/drivers/gpu/drm/radeon/si.c
@@ -7138,17 +7138,8 @@
 			u16 bridge_cfg2, gpu_cfg2;
 			u32 max_lw, current_lw, tmp;
 
-			pcie_capability_read_word(root, PCI_EXP_LNKCTL,
-						  &bridge_cfg);
-			pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL,
-						  &gpu_cfg);
-
-			tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
-			pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
-
-			tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
-			pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL,
-						   tmp16);
+			pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
+			pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
 
 			tmp = RREG32_PCIE(PCIE_LC_STATUS1);
 			max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
@@ -7195,22 +7186,14 @@
 				msleep(100);
 
 				/* linkctl */
-				pcie_capability_read_word(root, PCI_EXP_LNKCTL,
-							  &tmp16);
-				tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
-				tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
-				pcie_capability_write_word(root,
-							   PCI_EXP_LNKCTL,
-							   tmp16);
-
-				pcie_capability_read_word(rdev->pdev,
-							  PCI_EXP_LNKCTL,
-							  &tmp16);
-				tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
-				tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
-				pcie_capability_write_word(rdev->pdev,
-							   PCI_EXP_LNKCTL,
-							   tmp16);
+				pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
+								   PCI_EXP_LNKCTL_HAWD,
+								   bridge_cfg &
+								   PCI_EXP_LNKCTL_HAWD);
+				pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL,
+								   PCI_EXP_LNKCTL_HAWD,
+								   gpu_cfg &
+								   PCI_EXP_LNKCTL_HAWD);
 
 				/* linkctl2 */
 				pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
diff --git a/kernel/drivers/gpu/drm/rcar-du/Kconfig b/kernel/drivers/gpu/drm/rcar-du/Kconfig
index b47e744..3e588dd 100644
--- a/kernel/drivers/gpu/drm/rcar-du/Kconfig
+++ b/kernel/drivers/gpu/drm/rcar-du/Kconfig
@@ -4,8 +4,6 @@
 	depends on DRM && OF
 	depends on ARM || ARM64
 	depends on ARCH_RENESAS || COMPILE_TEST
-	imply DRM_RCAR_CMM
-	imply DRM_RCAR_LVDS
 	select DRM_KMS_HELPER
 	select DRM_KMS_CMA_HELPER
 	select DRM_GEM_CMA_HELPER
@@ -14,12 +12,16 @@
 	  Choose this option if you have an R-Car chipset.
 	  If M is selected the module will be called rcar-du-drm.
 
-config DRM_RCAR_CMM
-	tristate "R-Car DU Color Management Module (CMM) Support"
-	depends on DRM && OF
+config DRM_RCAR_USE_CMM
+	bool "R-Car DU Color Management Module (CMM) Support"
 	depends on DRM_RCAR_DU
+	default DRM_RCAR_DU
 	help
 	  Enable support for R-Car Color Management Module (CMM).
+
+config DRM_RCAR_CMM
+	def_tristate DRM_RCAR_DU
+	depends on DRM_RCAR_USE_CMM
 
 config DRM_RCAR_DW_HDMI
 	tristate "R-Car Gen3 and RZ/G2 DU HDMI Encoder Support"
@@ -28,15 +30,20 @@
 	help
 	  Enable support for R-Car Gen3 or RZ/G2 internal HDMI encoder.
 
+config DRM_RCAR_USE_LVDS
+	bool "R-Car DU LVDS Encoder Support"
+	depends on DRM_BRIDGE && OF
+	default DRM_RCAR_DU
+	help
+	  Enable support for the R-Car Display Unit embedded LVDS encoders.
+
 config DRM_RCAR_LVDS
-	tristate "R-Car DU LVDS Encoder Support"
-	depends on DRM && DRM_BRIDGE && OF
+	def_tristate DRM_RCAR_DU
+	depends on DRM_RCAR_USE_LVDS
 	select DRM_KMS_HELPER
 	select DRM_PANEL
 	select OF_FLATTREE
 	select OF_OVERLAY
-	help
-	  Enable support for the R-Car Display Unit embedded LVDS encoders.
 
 config DRM_RCAR_VSP
 	bool "R-Car DU VSP Compositor Support" if ARM
diff --git a/kernel/drivers/gpu/drm/rockchip/Makefile b/kernel/drivers/gpu/drm/rockchip/Makefile
index 7a42624..3287356 100644
--- a/kernel/drivers/gpu/drm/rockchip/Makefile
+++ b/kernel/drivers/gpu/drm/rockchip/Makefile
@@ -4,7 +4,7 @@
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
 rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
-		rockchip_drm_gem.o rockchip_drm_logo.o \
+		 rockchip_drm_gem.o rockchip_drm_logo.o rockchip_drm_clk.o\
 
 rockchipdrm-$(CONFIG_ROCKCHIP_VOP) += rockchip_drm_vop.o rockchip_vop_reg.o
 rockchipdrm-$(CONFIG_ROCKCHIP_VOP2) += rockchip_drm_vop2.o rockchip_vop2_reg.o rockchip_post_csc.o
diff --git a/kernel/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/kernel/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index e15c50e..9f09525 100644
--- a/kernel/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/kernel/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -314,6 +314,23 @@
 		rockchip_drm_unregister_sub_dev(sdev);
 }
 
+static enum drm_mode_status
+rockchip_dp_drm_encoder_mode_valid(struct drm_encoder *encoder,
+				   const struct drm_display_mode *mode)
+{
+	struct rockchip_dp_device *dp = to_dp(encoder);
+	struct videomode vm;
+
+	drm_display_mode_to_videomode(mode, &vm);
+
+	if (!vm.hfront_porch || !vm.hback_porch || !vm.vfront_porch || !vm.vback_porch) {
+		DRM_DEV_ERROR(dp->dev, "front porch or back porch can not be 0\n");
+		return MODE_BAD;
+	}
+
+	return MODE_OK;
+}
+
 static bool
 rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder,
 				   const struct drm_display_mode *mode,
@@ -484,6 +501,7 @@
 }
 
 static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {
+	.mode_valid = rockchip_dp_drm_encoder_mode_valid,
 	.mode_fixup = rockchip_dp_drm_encoder_mode_fixup,
 	.mode_set = rockchip_dp_drm_encoder_mode_set,
 	.atomic_enable = rockchip_dp_drm_encoder_enable,
@@ -681,6 +699,7 @@
 
 		dp->plat_data.right = secondary->adp;
 		dp->plat_data.split_mode = true;
+		secondary->plat_data.panel = dp->plat_data.panel;
 		secondary->plat_data.left = dp->adp;
 		secondary->plat_data.split_mode = true;
 	}
diff --git a/kernel/drivers/gpu/drm/rockchip/cdn-dp-core.c b/kernel/drivers/gpu/drm/rockchip/cdn-dp-core.c
index bae50c5..9804fe1 100644
--- a/kernel/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/kernel/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -539,7 +539,7 @@
 	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/kernel/drivers/gpu/drm/rockchip/dw-dp.c b/kernel/drivers/gpu/drm/rockchip/dw-dp.c
index 31136d4..e6c3ac3 100644
--- a/kernel/drivers/gpu/drm/rockchip/dw-dp.c
+++ b/kernel/drivers/gpu/drm/rockchip/dw-dp.c
@@ -2757,7 +2757,7 @@
 {
 	struct dw_dp *dp = bridge_to_dp(bridge);
 	struct dw_dp_link *link = &dp->link;
-	struct drm_display_mode m;
+	struct drm_display_mode m = {};
 	u32 min_bpp;
 
 	drm_mode_copy(&m, mode);
diff --git a/kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index abae085..f90b2e5 100644
--- a/kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -629,7 +629,7 @@
 
 	dsi->format = format;
 	bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
-	if (bpp < 0) {
+	if (bpp <= 0) {
 		DRM_DEV_ERROR(dsi->dev,
 			      "failed to get bpp for pixel format %d\n",
 			      dsi->format);
diff --git a/kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
index 46ace54..e66df80 100644
--- a/kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
+++ b/kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
@@ -246,6 +246,8 @@
 	struct phy *dcphy;
 	union phy_configure_opts phy_opts;
 
+	bool disable_hold_mode;
+	bool auto_calc_mode;
 	bool c_option;
 	bool scrambling_en;
 	unsigned int slice_width;
@@ -270,7 +272,7 @@
 	u32 lanes;
 	u32 format;
 	unsigned long mode_flags;
-
+	u64 mipi_pixel_rate;
 	const struct dw_mipi_dsi2_plat_data *pdata;
 	struct rockchip_drm_sub_dev sub_dev;
 
@@ -609,9 +611,8 @@
 
 static void dw_mipi_dsi2_phy_ratio_cfg(struct dw_mipi_dsi2 *dsi2)
 {
-	struct drm_display_mode *mode = &dsi2->mode;
 	u64 sys_clk = clk_get_rate(dsi2->sys_clk);
-	u64 pixel_clk, ipi_clk, phy_hsclk;
+	u64 ipi_clk, phy_hsclk;
 	u64 tmp;
 
 	/*
@@ -625,8 +626,9 @@
 		phy_hsclk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_hs_rate * MSEC_PER_SEC, 16);
 
 	/* IPI_RATIO_MAN_CFG = PHY_HSTX_CLK / IPI_CLK */
-	pixel_clk = mode->crtc_clock * MSEC_PER_SEC;
-	ipi_clk = pixel_clk / 4;
+	ipi_clk = dsi2->mipi_pixel_rate;
+	if (!sys_clk || !ipi_clk)
+		return;
 
 	tmp = DIV_ROUND_CLOSEST_ULL(phy_hsclk << 16, ipi_clk);
 	regmap_write(dsi2->regmap, DSI2_PHY_IPI_RATIO_MAN_CFG,
@@ -666,6 +668,10 @@
 {
 	dw_mipi_dsi2_phy_mode_cfg(dsi2);
 	dw_mipi_dsi2_phy_clk_mode_cfg(dsi2);
+
+	if (dsi2->auto_calc_mode)
+		return;
+
 	dw_mipi_dsi2_phy_ratio_cfg(dsi2);
 	dw_mipi_dsi2_lp2hs_or_hs2lp_cfg(dsi2);
 
@@ -733,6 +739,9 @@
 	regmap_write(dsi2->regmap, DSI2_IPI_PIX_PKT_CFG, MAX_PIX_PKT(val));
 
 	dw_mipi_dsi2_ipi_color_coding_cfg(dsi2);
+
+	if (dsi2->auto_calc_mode)
+		return;
 
 	/*
 	 * if the controller is intended to operate in data stream mode,
@@ -807,7 +816,7 @@
 
 	/* there may be some timeout registers may be configured if desired */
 
-	dw_mipi_dsi2_work_mode(dsi2, MANUAL_MODE_EN);
+	dw_mipi_dsi2_work_mode(dsi2, dsi2->auto_calc_mode ? 0 : MANUAL_MODE_EN);
 	dw_mipi_dsi2_phy_init(dsi2);
 	dw_mipi_dsi2_tx_option_set(dsi2);
 	dw_mipi_dsi2_irq_enable(dsi2, 1);
@@ -830,7 +839,19 @@
 
 static void dw_mipi_dsi2_enable(struct dw_mipi_dsi2 *dsi2)
 {
+	u32 mode;
+	int ret;
+
 	dw_mipi_dsi2_ipi_set(dsi2);
+
+	if (dsi2->auto_calc_mode) {
+		regmap_write(dsi2->regmap, DSI2_MODE_CTRL, AUTOCALC_MODE);
+		ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS,
+					       mode, mode == IDLE_MODE,
+					       1000, MODE_STATUS_TIMEOUT_US);
+		if (ret < 0)
+			dev_err(dsi2->dev, "auto calculation training failed\n");
+	}
 
 	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO)
 		dw_mipi_dsi2_set_vid_mode(dsi2);
@@ -841,6 +862,31 @@
 		dw_mipi_dsi2_enable(dsi2->slave);
 }
 
+static void dw_mipi_dsi2_get_mipi_pixel_clk(struct dw_mipi_dsi2 *dsi2,
+					    struct rockchip_crtc_state *s)
+{
+	struct drm_display_mode *mode = &dsi2->mode;
+	u8 k = dsi2->slave ? 2 : 1;
+
+	/* 1.When MIPI works in uncompressed mode:
+	 * (Video Timing Pixel Rate)/(4)=(MIPI Pixel ClockxK)=(dclk_out×K)=dclk_core
+	 * 2.When MIPI works in compressed mode:
+	 * MIPI Pixel Clock = cds_clk / 2
+	 * MIPI is configured as double channel display mode, K=2, otherwise K=1.
+	 */
+	if (dsi2->dsc_enable) {
+		dsi2->mipi_pixel_rate = s->dsc_cds_clk_rate / 2;
+		if (dsi2->slave)
+			dsi2->slave->mipi_pixel_rate = dsi2->mipi_pixel_rate;
+
+		return;
+	}
+
+	dsi2->mipi_pixel_rate = (mode->crtc_clock * MSEC_PER_SEC) / (4 * k);
+	if (dsi2->slave)
+		dsi2->slave->mipi_pixel_rate = dsi2->mipi_pixel_rate;
+}
+
 static int dw_mipi_dsi2_encoder_mode_set(struct dw_mipi_dsi2 *dsi2,
 					 struct drm_atomic_state *state)
 {
@@ -848,6 +894,7 @@
 	struct drm_connector *connector;
 	struct drm_connector_state *conn_state;
 	struct drm_crtc_state *crtc_state;
+	struct rockchip_crtc_state *vcstate;
 	const struct drm_display_mode *adjusted_mode;
 	struct drm_display_mode *mode = &dsi2->mode;
 
@@ -865,6 +912,7 @@
 		return -ENODEV;
 	}
 
+	vcstate = to_rockchip_crtc_state(crtc_state);
 	adjusted_mode = &crtc_state->adjusted_mode;
 	drm_mode_copy(mode, adjusted_mode);
 
@@ -873,6 +921,8 @@
 
 	if (dsi2->slave)
 		drm_mode_copy(&dsi2->slave->mode, mode);
+
+	dw_mipi_dsi2_get_mipi_pixel_clk(dsi2, vcstate);
 
 	return 0;
 }
@@ -954,7 +1004,7 @@
 	if (!(dsi2->mode_flags & MIPI_DSI_MODE_VIDEO)) {
 		s->output_flags |= ROCKCHIP_OUTPUT_MIPI_DS_MODE;
 		s->soft_te = dsi2->te_gpio ? true : false;
-		s->hold_mode = true;
+		s->hold_mode = dsi2->disable_hold_mode ? false : true;
 	}
 
 	if (dsi2->slave) {
@@ -1164,6 +1214,7 @@
 		dsi2->slave->master = dsi2;
 		dsi2->lanes /= 2;
 
+		dsi2->slave->auto_calc_mode = dsi2->auto_calc_mode;
 		dsi2->slave->lanes = dsi2->lanes;
 		dsi2->slave->channel = dsi2->channel;
 		dsi2->slave->format = dsi2->format;
@@ -1639,6 +1690,12 @@
 	dsi2->pdata = of_device_get_match_data(dev);
 	platform_set_drvdata(pdev, dsi2);
 
+	if (device_property_read_bool(dev, "auto-calculation-mode"))
+		dsi2->auto_calc_mode = true;
+
+	if (device_property_read_bool(dev, "disable-hold-mode"))
+		dsi2->disable_hold_mode = true;
+
 	if (device_property_read_bool(dev, "dual-connector-split")) {
 		dsi2->dual_connector_split = true;
 
diff --git a/kernel/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/kernel/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 450b162..3253cf2 100644
--- a/kernel/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/kernel/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -856,7 +856,7 @@
 				    struct drm_crtc_state *crtc_state,
 				    unsigned int tmdsclk)
 {
-	struct drm_display_mode mode;
+	struct drm_display_mode mode = {};
 	int max_lanes, max_rate_per_lane;
 	int max_dsc_lanes, max_dsc_rate_per_lane;
 	unsigned long max_frl_rate;
@@ -1982,7 +1982,7 @@
 			       unsigned int *eotf)
 {
 	struct drm_display_info *info = &conn_state->connector->display_info;
-	struct drm_display_mode mode;
+	struct drm_display_mode mode = {};
 	struct hdr_output_metadata *hdr_metadata;
 	u32 vic;
 	unsigned long tmdsclock, pixclock;
@@ -2237,7 +2237,7 @@
 	struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
 	struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
 	unsigned int colorformat, bus_width, tmdsclk;
-	struct drm_display_mode mode;
+	struct drm_display_mode mode = {};
 	unsigned int output_mode;
 	unsigned long bus_format;
 	int color_depth;
diff --git a/kernel/drivers/gpu/drm/rockchip/inno_hdmi.c b/kernel/drivers/gpu/drm/rockchip/inno_hdmi.c
index f251cef..c74e036 100644
--- a/kernel/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/kernel/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -546,7 +546,7 @@
 	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/kernel/drivers/gpu/drm/rockchip/rk3066_hdmi.c b/kernel/drivers/gpu/drm/rockchip/rk3066_hdmi.c
index 58b366f..4668393 100644
--- a/kernel/drivers/gpu/drm/rockchip/rk3066_hdmi.c
+++ b/kernel/drivers/gpu/drm/rockchip/rk3066_hdmi.c
@@ -383,7 +383,7 @@
 	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)
diff --git a/kernel/drivers/gpu/drm/rockchip/rk628/rk628_combtxphy.c b/kernel/drivers/gpu/drm/rockchip/rk628/rk628_combtxphy.c
index 8cdb50c..cbe7923 100644
--- a/kernel/drivers/gpu/drm/rockchip/rk628/rk628_combtxphy.c
+++ b/kernel/drivers/gpu/drm/rockchip/rk628/rk628_combtxphy.c
@@ -366,6 +366,10 @@
 		ref_clk = clk_get_rate(combtxphy->ref_clk) / 1000; /* khz */
 		if (combtxphy->division_mode)
 			ref_clk /= 2;
+
+		if (!ref_clk)
+			return -EINVAL;
+
 		/*
 		 * the reference clock at PFD(FPFD = ref_clk / ref_div) about
 		 * 25MHz is recommende, FPFD must range from 16MHz to 35MHz,
diff --git a/kernel/drivers/gpu/drm/rockchip/rk628/rk628_dsi.c b/kernel/drivers/gpu/drm/rockchip/rk628/rk628_dsi.c
index 2ada423..fc7da77 100644
--- a/kernel/drivers/gpu/drm/rockchip/rk628/rk628_dsi.c
+++ b/kernel/drivers/gpu/drm/rockchip/rk628/rk628_dsi.c
@@ -637,6 +637,9 @@
 	u32 val;
 	int ret;
 
+	if (!vrefresh)
+		return -EINVAL;
+
 	ret = regmap_read_poll_timeout(dsi->regmap,
 				       dsi->reg_base + DSI_CMD_PKT_STATUS,
 				       val, !(val & GEN_RD_CMD_BUSY),
diff --git a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_clk.c b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_clk.c
new file mode 100644
index 0000000..f606377
--- /dev/null
+++ b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_clk.c
@@ -0,0 +1,284 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ * Author: Sandy Huang <hjc@rock-chips.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/clk-conf.h>
+
+#include "rockchip_drm_vop.h"
+#include "rockchip_drm_drv.h"
+
+#define VOP2_PLL_LIMIT_FREQ 594000000
+#define VOP2_PLL_MIN_FREQ 40000000
+
+static long rockchip_rk3562_drm_dclk_round_rate(struct clk *dclk, unsigned long rate)
+{
+	struct clk_hw *hw;
+	struct clk_hw *p_hw;
+	unsigned long round_rate;
+	const char *name;
+
+	hw = __clk_get_hw(dclk);
+	if (!hw)
+		return -EINVAL;
+
+	p_hw = clk_hw_get_parent(hw);
+	if (!p_hw)
+		return -EINVAL;
+	name = clk_hw_get_name(p_hw);
+
+	if (!strcmp(name, "vpll"))
+		round_rate = rate;
+	else
+		round_rate = clk_round_rate(dclk, rate);
+
+	return round_rate;
+}
+
+static long rockchip_rk3568_drm_dclk_round_rate(struct clk *dclk, unsigned long rate)
+{
+	struct clk_hw *hw;
+	struct clk_hw *p_hw;
+	unsigned long round_rate;
+	const char *name;
+
+	hw = __clk_get_hw(dclk);
+	if (!hw)
+		return -EINVAL;
+
+	p_hw = clk_hw_get_parent(hw);
+	if (!p_hw)
+		return -EINVAL;
+	name = clk_hw_get_name(p_hw);
+
+	if (!strcmp(name, "vpll"))
+		round_rate = rate;
+	else if (!strcmp(name, "hpll"))
+		round_rate = rate;
+	else
+		round_rate = clk_round_rate(dclk, rate);
+
+	return round_rate;
+}
+
+static long rockchip_rk3588_drm_dclk_round_rate(struct clk *dclk, unsigned long rate)
+{
+	struct clk_hw *hw;
+	struct clk_hw *p_hw;
+	unsigned long round_rate;
+	const char *name;
+
+	hw = __clk_get_hw(dclk);
+	if (!hw)
+		return -EINVAL;
+	name = clk_hw_get_name(hw);
+
+	if (!strcmp(name, "dclk_vop3")) {
+		p_hw = clk_hw_get_parent(hw);
+	} else {
+		p_hw = clk_hw_get_parent(hw);
+		if (!p_hw)
+			return -EINVAL;
+		p_hw = clk_hw_get_parent(p_hw);
+	}
+
+	if (!p_hw)
+		return -EINVAL;
+	name = clk_hw_get_name(p_hw);
+
+	if (!strcmp(name, "v0pll"))
+		round_rate = rate;
+	else
+		round_rate = clk_round_rate(dclk, rate);
+
+	return round_rate;
+}
+
+/*
+ * The rk3562 is a single display, exclusive to vpll
+ */
+static int rockchip_rk3562_drm_dclk_set_rate(struct clk *dclk, unsigned long rate)
+{
+	struct clk_hw *hw;
+	struct clk_hw *p_hw;
+	unsigned long pll_rate;
+	const char *name;
+	int div = 0;
+
+	hw = __clk_get_hw(dclk);
+	if (!hw)
+		return -EINVAL;
+
+	p_hw = clk_hw_get_parent(hw);
+	if (!p_hw)
+		return -EINVAL;
+	name = clk_hw_get_name(p_hw);
+
+	if (!strcmp(name, "vpll")) {
+		pll_rate = clk_hw_get_rate(p_hw);
+		if (pll_rate >= VOP2_PLL_LIMIT_FREQ && pll_rate % rate == 0) {
+			clk_set_rate(dclk, rate);
+		} else {
+			div = DIV_ROUND_UP(VOP2_PLL_LIMIT_FREQ, rate);
+			if (div % 2)
+				div += 1;
+			clk_set_rate(p_hw->clk, rate * div);
+			clk_set_rate(dclk, rate);
+		}
+	} else {
+		clk_set_rate(dclk, rate);
+	}
+
+	pr_debug("%s:request rate = %ld, %s = %ld, %s = %ld\n", __func__, rate,
+		 clk_hw_get_name(hw), clk_hw_get_rate(hw),
+		 clk_hw_get_name(p_hw), clk_hw_get_rate(p_hw));
+
+	return 0;
+}
+
+/*
+ * The rk3568 has three ports, dclk_vop0/dclk_vop1/dclk_vop2
+ * For the dclk used by hdmi, the parent clock must be specified in hpll.
+ * There is also a dclk that can be specified on the vpll.
+ * The last dclk can only choose the nearest frequency division,
+ * and cannot support accurate frequency setting.
+ */
+static int rockchip_rk3568_drm_dclk_set_rate(struct clk *dclk, unsigned long rate)
+{
+	struct clk_hw *hw;
+	struct clk_hw *p_hw;
+	unsigned long pll_rate;
+	const char *name;
+	int div = 0;
+
+	hw = __clk_get_hw(dclk);
+	if (!hw)
+		return -EINVAL;
+
+	p_hw = clk_hw_get_parent(hw);
+	if (!p_hw)
+		return -EINVAL;
+	name = clk_hw_get_name(p_hw);
+
+	if (!strcmp(name, "vpll")) {
+		pll_rate = clk_hw_get_rate(p_hw);
+		if (pll_rate >= VOP2_PLL_LIMIT_FREQ && pll_rate % rate == 0) {
+			clk_set_rate(dclk, rate);
+		} else {
+			div = DIV_ROUND_UP(VOP2_PLL_LIMIT_FREQ, rate);
+			if (div % 2)
+				div += 1;
+			clk_set_rate(p_hw->clk, rate * div);
+			clk_set_rate(dclk, rate);
+		}
+	} else if (!strcmp(name, "hpll")) {
+		if (rate < VOP2_PLL_MIN_FREQ)
+			pr_warn("%s: Warning: rate is low than pll min limit!\n", __func__);
+		clk_set_rate(p_hw->clk, rate);
+		clk_set_rate(dclk, rate);
+	} else {
+		clk_set_rate(dclk, rate);
+	}
+
+	pr_debug("%s:request rate = %ld, %s = %ld %s = %ld\n", __func__, rate,
+		 clk_hw_get_name(hw), clk_hw_get_rate(hw),
+		 clk_hw_get_name(p_hw), clk_hw_get_rate(p_hw));
+
+	return 0;
+}
+
+/*
+ * The rk3588 has four ports, dclk_vop0\1\2\3.
+ * The dclk_vop0\1\2 can select 2 ports specified on clk_hdmiphy_pixelx.
+ * The dclk_vop0\1\2\3 can select 1 ports specified on v0pll.
+ * The last dclk can only choose the nearest frequency division,
+ * and cannot support accurate frequency setting.
+ */
+static int rockchip_rk3588_drm_dclk_set_rate(struct clk *dclk, unsigned long rate)
+{
+	struct clk_hw *hw;
+	struct clk_hw *p_hw;
+	unsigned long pll_rate;
+	const char *name;
+	int div = 0;
+
+	hw = __clk_get_hw(dclk);
+	if (!hw)
+		return -EINVAL;
+	name = clk_hw_get_name(hw);
+
+	if (!strcmp(name, "dclk_vop3")) {
+		p_hw = clk_hw_get_parent(hw);
+	} else {
+		p_hw = clk_hw_get_parent(hw);
+		if (!p_hw)
+			return -EINVAL;
+		p_hw = clk_hw_get_parent(p_hw);
+	}
+
+	if (!p_hw)
+		return -EINVAL;
+	name = clk_hw_get_name(p_hw);
+
+	if (!strcmp(name, "v0pll")) {
+		pll_rate = clk_hw_get_rate(p_hw);
+		if (pll_rate >= VOP2_PLL_LIMIT_FREQ && pll_rate % rate == 0) {
+			clk_set_rate(dclk, rate);
+		} else {
+			div = DIV_ROUND_UP(VOP2_PLL_LIMIT_FREQ, rate);
+			if (div % 2)
+				div += 1;
+			clk_set_rate(p_hw->clk, rate * div);
+			clk_set_rate(dclk, rate);
+		}
+	} else {
+		clk_set_rate(dclk, rate);
+	}
+
+	pr_debug("%s:request rate = %ld, %s = %ld %s = %ld\n", __func__, rate,
+		 clk_hw_get_name(hw), clk_hw_get_rate(hw),
+		 clk_hw_get_name(p_hw), clk_hw_get_rate(p_hw));
+
+	return 0;
+}
+
+long rockchip_drm_dclk_round_rate(u32 version, struct clk *dclk, unsigned long rate)
+{
+	long round_rate;
+
+	if (version == VOP_VERSION_RK3562)
+		round_rate = rockchip_rk3562_drm_dclk_round_rate(dclk, rate);
+	else if (version == VOP_VERSION_RK3568)
+		round_rate = rockchip_rk3568_drm_dclk_round_rate(dclk, rate);
+	else if (version == VOP_VERSION_RK3588)
+		round_rate = rockchip_rk3588_drm_dclk_round_rate(dclk, rate);
+	else
+		round_rate = clk_round_rate(dclk, rate);
+
+	if (round_rate < 0)
+		pr_warn("%s:the clk_hw of dclk or parent of dclk may be NULL\n", __func__);
+
+	return round_rate;
+}
+
+int rockchip_drm_dclk_set_rate(u32 version, struct clk *dclk, unsigned long rate)
+{
+	int ret;
+
+	if (version == VOP_VERSION_RK3562)
+		ret = rockchip_rk3562_drm_dclk_set_rate(dclk, rate);
+	else if (version == VOP_VERSION_RK3568)
+		ret = rockchip_rk3568_drm_dclk_set_rate(dclk, rate);
+	else if (version == VOP_VERSION_RK3588)
+		ret = rockchip_rk3588_drm_dclk_set_rate(dclk, rate);
+	else
+		ret = clk_set_rate(dclk, rate);
+
+	if (ret < 0)
+		pr_warn("%s:the clk_hw of dclk or parent of dclk may be NULL\n", __func__);
+
+	return ret;
+}
diff --git a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.c b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.c
index 723c284..923bcf3 100644
--- a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.c
+++ b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.c
@@ -56,7 +56,7 @@
 int rockchip_drm_dump_plane_buffer(struct vop_dump_info *dump_info, int frame_count)
 {
 	int flags;
-	int bpp = 32;
+	int bpp;
 	const char *ptr;
 	char file_name[100];
 	int width;
@@ -70,6 +70,10 @@
 	drm_get_format_name(dump_info->format->format, &format_name);
 	strscpy(format, format_name.str, 5);
 	bpp = rockchip_drm_get_bpp(dump_info->format);
+	if (!bpp) {
+		DRM_WARN("invalid bpp %d\n", bpp);
+		return 0;
+	}
 
 	if (dump_info->yuv_format) {
 		u8 hsub = dump_info->format->hsub;
diff --git a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index a3a8c44..9f64ad8 100644
--- a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -37,7 +37,6 @@
 #include "rockchip_drm_logo.h"
 
 #include "../drm_crtc_internal.h"
-#include "../drivers/clk/rockchip/clk.h"
 
 #define DRIVER_NAME	"rockchip"
 #define DRIVER_DESC	"RockChip Soc DRM"
@@ -1583,8 +1582,6 @@
 	ret = drm_dev_register(drm_dev, 0);
 	if (ret)
 		goto err_kms_helper_poll_fini;
-
-	rockchip_clk_unprotect();
 
 	return 0;
 err_kms_helper_poll_fini:
diff --git a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 7b6abed..2e8739b 100644
--- a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -576,6 +576,8 @@
 int rockchip_drm_parse_next_hdr(struct next_hdr_sink_data *sink_data,
 				const struct edid *edid);
 int rockchip_drm_parse_colorimetry_data_block(u8 *colorimetry, const struct edid *edid);
+long rockchip_drm_dclk_round_rate(u32 version, struct clk *dclk, unsigned long rate);
+int rockchip_drm_dclk_set_rate(u32 version, struct clk *dclk, unsigned long rate);
 
 __printf(3, 4)
 void rockchip_drm_dbg(const struct device *dev, enum rockchip_drm_debug_category category,
diff --git a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 48893f5..9a4b78d 100644
--- a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -565,9 +565,6 @@
 		ret = rockchip_drm_gem_object_mmap_dma(obj, vma);
 	}
 
-	if (ret)
-		drm_gem_vm_close(vma);
-
 	return ret;
 }
 
diff --git a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 326b571..b80ef0c 100644
--- a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -39,7 +39,6 @@
 #ifdef CONFIG_DRM_ANALOGIX_DP
 #include <drm/bridge/analogix_dp.h>
 #endif
-#include <dt-bindings/soc/rockchip-system-status.h>
 
 #include <soc/rockchip/rockchip_dmc.h>
 #include <soc/rockchip/rockchip-system-status.h>
@@ -223,7 +222,6 @@
 	struct dentry *debugfs;
 	struct drm_info_list *debugfs_files;
 	struct drm_property *plane_feature_prop;
-	struct drm_property *plane_mask_prop;
 	struct drm_property *feature_prop;
 
 	bool is_iommu_enabled;
@@ -238,7 +236,6 @@
 	u32 background;
 	u32 line_flag;
 	u8 id;
-	u8 plane_mask;
 	u64 soc_id;
 	struct drm_prop_enum_list *plane_name_list;
 
@@ -318,6 +315,8 @@
 	{ MEDIA_BUS_FMT_UYYVYY8_0_5X24, "UYYVYY8_0_5X24" },
 	{ MEDIA_BUS_FMT_YUV10_1X30, "YUV10_1X30" },
 	{ MEDIA_BUS_FMT_UYYVYY10_0_5X30, "UYYVYY10_0_5X30" },
+	{ MEDIA_BUS_FMT_RGB565_2X8_LE, "RGB565_2X8_LE" },
+	{ MEDIA_BUS_FMT_RGB666_3X6, "RGB666_3X6" },
 	{ MEDIA_BUS_FMT_RGB888_3X8, "RGB888_3X8" },
 	{ MEDIA_BUS_FMT_RGB888_DUMMY_4X8, "RGB888_DUMMY_4X8" },
 	{ MEDIA_BUS_FMT_RGB888_1X24, "RGB888_1X24" },
@@ -463,6 +462,11 @@
 	const struct vop_hdr_table *table = vop->data->hdr_table;
 	uint32_t sdr2hdr_eotf_oetf_yn[65];
 	uint32_t sdr2hdr_oetf_dx_dxpow[64];
+
+	if (cmd != SDR2HDR_FOR_BT2020 && cmd != SDR2HDR_FOR_HDR && cmd != SDR2HDR_FOR_HLG_HDR) {
+		DRM_WARN("unknown sdr2hdr oetf: %d\n", cmd);
+		return;
+	}
 
 	for (i = 0; i < 65; i++) {
 		if (cmd == SDR2HDR_FOR_BT2020)
@@ -1873,11 +1877,11 @@
 					to_vop_plane_state(plane->state);
 #endif
 
-	rockchip_drm_dbg(vop->dev, VOP_DEBUG_PLANE, "disable win%d-area%d by %s\n",
-			 win->win_id, win->area_id, current->comm);
-
 	if (!old_state->crtc)
 		return;
+
+	rockchip_drm_dbg(vop->dev, VOP_DEBUG_PLANE, "disable win%d-area%d by %s\n",
+			 win->win_id, win->area_id, current->comm);
 
 	spin_lock(&vop->reg_lock);
 
@@ -3258,6 +3262,12 @@
 {
 	struct vop *vop = to_vop(crtc);
 
+	/*
+	 * If mcu_hold_mode is 1, set 1 to mcu_frame_st will
+	 * refresh one frame from ddr. So mcu_frame_st is needed
+	 * to be initialized as 0.
+	 */
+	VOP_CTRL_SET(vop, mcu_frame_st, 0);
 	VOP_CTRL_SET(vop, mcu_clk_sel, 1);
 	VOP_CTRL_SET(vop, mcu_type, 1);
 
@@ -4627,32 +4637,6 @@
 	return 0;
 }
 
-static int vop_crtc_create_plane_mask_property(struct vop *vop, struct drm_crtc *crtc)
-{
-	struct drm_property *prop;
-
-	static const struct drm_prop_enum_list props[] = {
-		{ ROCKCHIP_VOP_WIN0, "Win0" },
-		{ ROCKCHIP_VOP_WIN1, "Win1" },
-		{ ROCKCHIP_VOP_WIN2, "Win2" },
-		{ ROCKCHIP_VOP_WIN3, "Win3" },
-	};
-
-	prop = drm_property_create_bitmask(vop->drm_dev,
-					   DRM_MODE_PROP_IMMUTABLE, "PLANE_MASK",
-					   props, ARRAY_SIZE(props),
-					   0xffffffff);
-	if (!prop) {
-		DRM_DEV_ERROR(vop->dev, "create plane_mask prop for vp%d failed\n", vop->id);
-		return -ENOMEM;
-	}
-
-	vop->plane_mask_prop = prop;
-	drm_object_attach_property(&crtc->base, vop->plane_mask_prop, vop->plane_mask);
-
-	return 0;
-}
-
 static int vop_crtc_create_feature_property(struct vop *vop, struct drm_crtc *crtc)
 {
 	const struct vop_data *vop_data = vop->data;
@@ -4780,7 +4764,6 @@
 	VOP_ATTACH_MODE_CONFIG_PROP(tv_top_margin_property, 100);
 	VOP_ATTACH_MODE_CONFIG_PROP(tv_bottom_margin_property, 100);
 #undef VOP_ATTACH_MODE_CONFIG_PROP
-	vop_crtc_create_plane_mask_property(vop, crtc);
 	vop_crtc_create_feature_property(vop, crtc);
 	ret = drm_self_refresh_helper_init(crtc);
 	if (ret)
@@ -4949,7 +4932,6 @@
 			vop_area->name = devm_kstrdup(vop->dev, name, GFP_KERNEL);
 			num_wins++;
 		}
-		vop->plane_mask |= BIT(vop_win->win_id);
 	}
 
 	vop->num_wins = num_wins;
diff --git a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index b6e12d2..5f72a76 100644
--- a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -91,14 +91,6 @@
 	ROCKCHIP_VOP_VP3,
 };
 
-enum vop_win_phy_id {
-	ROCKCHIP_VOP_WIN0 = 0,
-	ROCKCHIP_VOP_WIN1,
-	ROCKCHIP_VOP_WIN2,
-	ROCKCHIP_VOP_WIN3,
-	ROCKCHIP_VOP_PHY_ID_INVALID = -1,
-};
-
 enum bcsh_out_mode {
 	BCSH_OUT_MODE_BLACK,
 	BCSH_OUT_MODE_BLUE,
diff --git a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 52dbcca..2c7a66a 100644
--- a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -20,7 +20,6 @@
 #ifdef CONFIG_DRM_ANALOGIX_DP
 #include <drm/bridge/analogix_dp.h>
 #endif
-#include <dt-bindings/soc/rockchip-system-status.h>
 
 #include <linux/debugfs.h>
 #include <linux/fixp-arith.h>
@@ -46,6 +45,7 @@
 #include <linux/rockchip/cpu.h>
 #include <linux/workqueue.h>
 #include <linux/types.h>
+#include <soc/rockchip/rockchip_csu.h>
 #include <soc/rockchip/rockchip_dmc.h>
 #include <soc/rockchip/rockchip-system-status.h>
 #include <uapi/linux/videodev2.h>
@@ -885,6 +885,7 @@
 	struct clk *pclk;
 	struct reset_control *ahb_rst;
 	struct reset_control *axi_rst;
+	struct csu_clk *csu_aclk;
 
 	/* list_head of extend clk */
 	struct list_head extend_clk_list_head;
@@ -929,6 +930,7 @@
 	{ MEDIA_BUS_FMT_UYYVYY8_0_5X24, "UYYVYY8_0_5X24" },
 	{ MEDIA_BUS_FMT_YUV10_1X30, "YUV10_1X30" },
 	{ MEDIA_BUS_FMT_UYYVYY10_0_5X30, "UYYVYY10_0_5X30" },
+	{ MEDIA_BUS_FMT_RGB565_2X8_LE, "RGB565_2X8_LE" },
 	{ MEDIA_BUS_FMT_RGB888_3X8, "RGB888_3X8" },
 	{ MEDIA_BUS_FMT_RGB888_DUMMY_4X8, "RGB888_DUMMY_4X8" },
 	{ MEDIA_BUS_FMT_RGB888_1X24, "RGB888_1X24" },
@@ -3243,8 +3245,21 @@
 	return 0;
 }
 
+static void vop2_wb_encoder_atomic_disable(struct drm_encoder *encoder,
+					   struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc = encoder->crtc;
+	struct vop2_video_port *vp = to_vop2_video_port(crtc);
+
+	if (!crtc->state->active_changed && !crtc->state->mode_changed) {
+		crtc->state->connectors_changed = false;
+		DRM_DEBUG("VP%d force change connectors_changed to false when disable wb\n", vp->id);
+	}
+}
+
 static const struct drm_encoder_helper_funcs vop2_wb_encoder_helper_funcs = {
 	.atomic_check = vop2_wb_encoder_atomic_check,
+	.atomic_disable = vop2_wb_encoder_atomic_disable,
 };
 
 static const struct drm_connector_helper_funcs vop2_wb_connector_helper_funcs = {
@@ -5142,7 +5157,7 @@
 	actual_w = drm_rect_width(src) >> 16;
 	actual_h = drm_rect_height(src) >> 16;
 
-	if (!actual_w || !actual_h) {
+	if (!actual_w || !actual_h || !bpp) {
 		vop2_win_disable(win, true);
 		return;
 	}
@@ -5263,10 +5278,6 @@
 		/* AFBC pic_vir_width is count by pixel, this is different
 		 * with WIN_VIR_STRIDE.
 		 */
-		if (!bpp) {
-			WARN(1, "bpp is zero\n");
-			bpp = 1;
-		}
 		stride = (fb->pitches[0] << 3) / bpp;
 		if ((stride & 0x3f) &&
 		    (vpstate->xmirror_en || vpstate->rotate_90_en || vpstate->rotate_270_en))
@@ -6111,6 +6122,27 @@
 	return 0;
 }
 
+static void vop2_crtc_csu_set_rate(struct drm_crtc *crtc)
+{
+	struct vop2_video_port *vp = to_vop2_video_port(crtc);
+	struct vop2 *vop2 = vp->vop2;
+	unsigned long aclk_rate = 0, dclk_rate = 0;
+	u32 csu_div = 0;
+
+	if (!vop2->csu_aclk)
+		return;
+
+	aclk_rate = clk_get_rate(vop2->aclk);
+	dclk_rate = clk_get_rate(vp->dclk);
+	if (!dclk_rate)
+		return;
+
+	/* aclk >= 1/2 * dclk */
+	csu_div = aclk_rate * 2 / dclk_rate;
+
+	rockchip_csu_set_div(vop2->csu_aclk, csu_div);
+}
+
 static int vop2_crtc_loader_protect(struct drm_crtc *crtc, bool on, void *data)
 {
 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
@@ -6190,6 +6222,8 @@
 			cubic_lut_mst = cubic_lut->offset + private->cubic_lut_dma_addr;
 			VOP_MODULE_SET(vop2, vp, cubic_lut_mst, cubic_lut_mst);
 		}
+
+		vop2_crtc_csu_set_rate(crtc);
 	} else {
 		vop2_crtc_atomic_disable(crtc, NULL);
 	}
@@ -6330,7 +6364,8 @@
 
 	/* only need to dump once at first active crtc for vop2 */
 	for (i = 0; i < vop2_data->nr_vps; i++) {
-		if (vop2->vps[i].rockchip_crtc.crtc.state->active) {
+		if (vop2->vps[i].rockchip_crtc.crtc.state &&
+		    vop2->vps[i].rockchip_crtc.crtc.state->active) {
 			first_active_crtc = &vop2->vps[i].rockchip_crtc.crtc;
 			break;
 		}
@@ -6373,7 +6408,8 @@
 
 	/* only need to dump once at first active crtc for vop2 */
 	for (i = 0; i < vop2_data->nr_vps; i++) {
-		if (vop2->vps[i].rockchip_crtc.crtc.state->active) {
+		if (vop2->vps[i].rockchip_crtc.crtc.state &&
+		    vop2->vps[i].rockchip_crtc.crtc.state->active) {
 			first_active_crtc = &vop2->vps[i].rockchip_crtc.crtc;
 			break;
 		}
@@ -6543,7 +6579,8 @@
 	} else {
 		if (request_clock > VOP2_MAX_DCLK_RATE)
 			request_clock = request_clock >> 2;
-		clock = clk_round_rate(vp->dclk, request_clock * 1000) / 1000;
+		clock = rockchip_drm_dclk_round_rate(vop2->version, vp->dclk,
+						     request_clock * 1000) / 1000;
 	}
 
 	/*
@@ -6586,7 +6623,7 @@
 	size_t bandwidth;
 
 	if (src_width <= 0 || src_height <= 0 || dst_width <= 0 ||
-	    dst_height <= 0)
+	    dst_height <= 0 || !bpp)
 		return 0;
 
 	bandwidth = src_width * bpp / 8;
@@ -6832,6 +6869,14 @@
 	if (mode->flags & DRM_MODE_FLAG_DBLCLK || vcstate->output_if & VOP_OUTPUT_IF_BT656)
 		adj_mode->crtc_clock *= 2;
 
+	/*
+	 * For RK3528, the path of CVBS output is like:
+	 * VOP BT656 ENCODER -> CVBS BT656 DECODER -> CVBS ENCODER -> CVBS VDAC
+	 * The vop2 dclk should be four times crtc_clock for CVBS sampling clock needs.
+	 */
+	if (vop2->version == VOP_VERSION_RK3528 && vcstate->output_if & VOP_OUTPUT_IF_BT656)
+		adj_mode->crtc_clock *= 4;
+
 	if (vp->mcu_timing.mcu_pix_total)
 		adj_mode->crtc_clock *= rockchip_drm_get_cycles_per_pixel(vcstate->bus_format) *
 					(vp->mcu_timing.mcu_pix_total + 1);
@@ -6847,9 +6892,11 @@
 	}
 	drm_connector_list_iter_end(&conn_iter);
 
-	if (adj_mode->crtc_clock <= VOP2_MAX_DCLK_RATE)
-		adj_mode->crtc_clock = DIV_ROUND_UP(clk_round_rate(vp->dclk,
-						    adj_mode->crtc_clock * 1000), 1000);
+	if (adj_mode->crtc_clock <= VOP2_MAX_DCLK_RATE) {
+		adj_mode->crtc_clock = rockchip_drm_dclk_round_rate(vop2->version, vp->dclk,
+								    adj_mode->crtc_clock * 1000);
+		adj_mode->crtc_clock = DIV_ROUND_UP(adj_mode->crtc_clock, 1000);
+	}
 	return true;
 }
 
@@ -7745,11 +7792,11 @@
 	vop2_set_system_status(vop2);
 
 	vop2_lock(vop2);
-	DRM_DEV_INFO(vop2->dev, "Update mode to %dx%d%s%d, type: %d(if:%x, flag:0x%x) for vp%d dclk: %d\n",
+	DRM_DEV_INFO(vop2->dev, "Update mode to %dx%d%s%d, type: %d(if:%x, flag:0x%x) for vp%d dclk: %llu\n",
 		     hdisplay, adjusted_mode->vdisplay, interlaced ? "i" : "p",
 		     drm_mode_vrefresh(adjusted_mode),
 		     vcstate->output_type, vcstate->output_if, vcstate->output_flags,
-		     vp->id, adjusted_mode->crtc_clock * 1000);
+		     vp->id, (unsigned long long)adjusted_mode->crtc_clock * 1000);
 
 	if (adjusted_mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) {
 		vcstate->splice_mode = true;
@@ -8081,19 +8128,12 @@
 		if (ret < 0)
 			goto out;
 
-		clk_set_rate(vp->dclk, dclk->rate);
+		rockchip_drm_dclk_set_rate(vop2->version, vp->dclk, dclk->rate);
 		DRM_DEV_INFO(vop2->dev, "set %s to %ld, get %ld\n",
 			      __clk_get_name(vp->dclk), dclk->rate, clk_get_rate(vp->dclk));
 	} else {
-		/*
-		 * For RK3528, the path of CVBS output is like:
-		 * VOP BT656 ENCODER -> CVBS BT656 DECODER -> CVBS ENCODER -> CVBS VDAC
-		 * The vop2 dclk should be four times crtc_clock for CVBS sampling clock needs.
-		 */
-		if (vop2->version == VOP_VERSION_RK3528 && vcstate->output_if & VOP_OUTPUT_IF_BT656)
-			clk_set_rate(vp->dclk, 4 * adjusted_mode->crtc_clock * 1000);
-		else
-			clk_set_rate(vp->dclk, adjusted_mode->crtc_clock * 1000);
+		rockchip_drm_dclk_set_rate(vop2->version, vp->dclk,
+					   adjusted_mode->crtc_clock * 1000);
 	}
 
 	if (vp_data->feature & VOP_FEATURE_OVERSCAN)
@@ -8122,6 +8162,7 @@
 	if (is_vop3(vop2))
 		vop3_setup_pipe_dly(vp, NULL);
 
+	vop2_crtc_csu_set_rate(crtc);
 	vop2_cfg_done(crtc);
 
 	/*
@@ -8158,6 +8199,30 @@
 		vop2_crtc_load_lut(crtc);
 		vop2_cfg_done(crtc);
 		vop2_wait_for_fs_by_done_bit_status(vp);
+	}
+
+	/*
+	 * In RK3588 VOP, HDMI1/eDP1 MUX1 module's reset signal should be released
+	 * when PD_VOP turn on. If this reset signal is not be released, the HDMI1
+	 * or eDP1 output interface can't work normally.
+	 * However, If the deassert signal want to transfer to HDMI1/eDP1 MUX1 and
+	 * take effect, it need the video port0 dclk's source clk work a few moment.
+	 * In some cases, the video port0 dclk's source clk is disabled(now only the
+	 * hdmi0/1 phy pll as the dclk source parent will appear) after PD_VOP turn
+	 * on, for example, vidoe port0 dclk source select hdmi phy pll. To fix
+	 * this issue, enable video port0 dclk for a few monent when active a video
+	 * port which attach to eDP1/HDMI1.
+	 */
+	if (vop2->version == VOP_VERSION_RK3588) {
+		if (vp->id != 0 && (vp->output_if & (VOP_OUTPUT_IF_eDP1 | VOP_OUTPUT_IF_HDMI1))) {
+			struct vop2_video_port *vp0 = &vop2->vps[0];
+
+			clk_prepare_enable(vp0->dclk);
+			if (!clk_get_rate(vp0->dclk))
+				clk_set_rate(vp0->dclk, 148500000);
+			udelay(20);
+			clk_disable_unprepare(vp0->dclk);
+		}
 	}
 out:
 	vop2_unlock(vop2);
@@ -10941,25 +11006,14 @@
 	return 0;
 }
 
-static struct drm_plane *vop2_cursor_plane_init(struct vop2_video_port *vp)
+static struct drm_plane *vop2_cursor_plane_init(struct vop2_video_port *vp, u32 possible_crtcs)
 {
 	struct vop2 *vop2 = vp->vop2;
 	struct drm_plane *cursor = NULL;
 	struct vop2_win *win;
-	unsigned long possible_crtcs = 0;
 
 	win = vop2_find_win_by_phys_id(vop2, vp->cursor_win_id);
 	if (win) {
-		if (vop2->disable_win_move) {
-			const struct vop2_data *vop2_data = vop2->data;
-			struct drm_crtc *crtc = vop2_find_crtc_by_plane_mask(vop2, win->phys_id);
-
-			if (crtc)
-				possible_crtcs = drm_crtc_mask(crtc);
-			else
-				possible_crtcs = (1 << vop2_data->nr_vps) - 1;
-		}
-
 		if (win->possible_crtcs)
 			possible_crtcs = win->possible_crtcs;
 		win->type = DRM_PLANE_TYPE_CURSOR;
@@ -11263,11 +11317,13 @@
 			possible_crtcs = BIT(registered_num_crtcs);
 
 		/*
-		 * we assume a vp with a zere plane_mask(set from dts or bootloader)
+		 * we assume a vp with a zero plane_mask(set from dts or bootloader)
 		 * as unused.
 		 */
-		if (!vp->plane_mask && bootloader_initialized)
+		if (!vp->plane_mask && bootloader_initialized) {
+			DRM_DEV_INFO(vop2->dev, "VP%d plane_mask is zero, so ignore register crtc\n", vp->id);
 			continue;
+		}
 
 		if (vop2_soc_is_rk3566())
 			soc_id = vp_data->soc_id[1];
@@ -11389,7 +11445,7 @@
 		}
 
 		if (vp->cursor_win_id >= 0) {
-			cursor = vop2_cursor_plane_init(vp);
+			cursor = vop2_cursor_plane_init(vp, possible_crtcs);
 			if (!cursor)
 				DRM_WARN("failed to init cursor plane for vp%d\n", vp->id);
 			else
@@ -11587,6 +11643,7 @@
 	struct vop2_win *win;
 	struct vop2_layer *layer;
 	char name[DRM_PROP_NAME_LEN];
+	char area_name[DRM_PROP_NAME_LEN];
 	unsigned int num_wins = 0;
 	uint8_t plane_id = 0;
 	unsigned int i, j;
@@ -11662,8 +11719,8 @@
 			area->phys_id = win->phys_id;
 			area->area_id = j + 1;
 			area->plane_id = plane_id++;
-			snprintf(name, min(sizeof(name), strlen(win->name)), "%s", win->name);
-			snprintf(name, sizeof(name), "%s%d", name, area->area_id);
+			snprintf(area_name, min(sizeof(area_name), strlen(win->name)), "%s", win->name);
+			snprintf(name, sizeof(name), "%s%d", area_name, area->area_id);
 			area->name = devm_kstrdup(vop2->dev, name, GFP_KERNEL);
 			num_wins++;
 		}
@@ -11957,6 +12014,10 @@
 		return PTR_ERR(vop2->axi_rst);
 	}
 
+	vop2->csu_aclk = rockchip_csu_get(dev, "aclk");
+	if (IS_ERR(vop2->csu_aclk))
+		vop2->csu_aclk = NULL;
+
 	vop2->irq = platform_get_irq(pdev, 0);
 	if (vop2->irq < 0) {
 		DRM_DEV_ERROR(dev, "cannot find irq for vop2\n");
diff --git a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vvop.c b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vvop.c
index 2b0dbdb..3f4432a 100644
--- a/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vvop.c
+++ b/kernel/drivers/gpu/drm/rockchip/rockchip_drm_vvop.c
@@ -17,36 +17,48 @@
 
 #define DRIVER_NAME	"virtual-vop"
 
-#define XRES_MIN    32
-#define YRES_MIN    32
+#define XRES_MIN	32
+#define YRES_MIN	32
 
-#define XRES_DEF  1024
-#define YRES_DEF   768
+#define XRES_DEF	1024
+#define YRES_DEF	768
 
-#define XRES_MAX  8192
-#define YRES_MAX  8192
+#define XRES_MAX	8192
+#define YRES_MAX	8192
 
+#define VVOP_MAX_CRTC	8
 
-struct vvop {
-	struct device *dev;
-	struct drm_device *drm_dev;
-	struct platform_device *pdev;
+static struct platform_device *vvop_pdev;
+
+struct vvop_crtc {
 	struct drm_crtc crtc;
-	struct drm_plane *plane;
+	struct drm_plane plane;
 	struct drm_encoder encoder;
 	struct drm_connector connector;
 	struct hrtimer vblank_hrtimer;
 	ktime_t period_ns;
 	struct drm_pending_vblank_event *event;
 
+	struct drm_property *is_virtual_prop;
+	struct drm_property *soc_id_prop;
+};
+
+struct vvop {
+	struct device *dev;
+	struct drm_device *drm_dev;
+	struct platform_device *pdev;
+
+	struct vvop_crtc vcrtc[VVOP_MAX_CRTC];
+
+	uint32_t crtc_mask;
 };
 
 static const u32 vvop_formats[] = {
 	DRM_FORMAT_XRGB8888,
 };
 
-#define drm_crtc_to_vvop(crtc) \
-	container_of(crtc, struct vvop, crtc)
+#define drm_crtc_to_vvop_crtc(crtc) \
+	container_of(crtc, struct vvop_crtc, crtc)
 
 
 static const struct drm_plane_funcs vvop_plane_funcs = {
@@ -59,7 +71,7 @@
 };
 
 static void vvop_plane_atomic_update(struct drm_plane *plane,
-				      struct drm_plane_state *old_state)
+				     struct drm_plane_state *old_state)
 {
 }
 
@@ -67,71 +79,60 @@
 	.atomic_update		= vvop_plane_atomic_update,
 };
 
-static struct drm_plane *vvop_plane_init(struct vvop *vvop)
+static int vvop_plane_init(struct drm_device *dev, struct drm_plane *primary)
 {
-	struct drm_device *dev = vvop->drm_dev;
-	struct drm_plane *plane;
-	const u32 *formats;
-	int ret, nformats;
+	int ret;
 
-	plane = kzalloc(sizeof(*plane), GFP_KERNEL);
-	if (!plane)
-		return ERR_PTR(-ENOMEM);
-
-	formats = vvop_formats;
-	nformats = ARRAY_SIZE(vvop_formats);
-
-	ret = drm_universal_plane_init(dev, plane, 0,
+	ret = drm_universal_plane_init(dev, primary, 0,
 				       &vvop_plane_funcs,
-				       formats, nformats,
+				       vvop_formats, ARRAY_SIZE(vvop_formats),
 				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
-	if (ret) {
-		kfree(plane);
-		return ERR_PTR(ret);
-	}
+	if (ret)
+		return ret;
 
-	drm_plane_helper_add(plane, &vvop_plane_helper_funcs);
+	drm_plane_helper_add(primary, &vvop_plane_helper_funcs);
 
-	return plane;
+	return 0;
 }
 
 static enum hrtimer_restart vvop_vblank_simulate(struct hrtimer *timer)
 {
-	struct vvop *vvop = container_of(timer, struct vvop, vblank_hrtimer);
-	struct drm_crtc *crtc = &vvop->crtc;
+	struct vvop_crtc *vcrtc = container_of(timer, struct vvop_crtc, vblank_hrtimer);
+	struct drm_crtc *crtc = &vcrtc->crtc;
 	bool ret;
 
-	ret = drm_crtc_handle_vblank(crtc);
-	if (!ret)
-		DRM_ERROR("vvop failure on handling vblank");
+	hrtimer_forward_now(&vcrtc->vblank_hrtimer, vcrtc->period_ns);
 
-	hrtimer_forward_now(&vvop->vblank_hrtimer, vvop->period_ns);
+	ret = drm_crtc_handle_vblank(crtc);
+	/* Don't queue timer again when vblank is disabled. */
+	if (!ret) {
+		drm_dbg(crtc->dev, "vblank is already disabled\n");
+		return HRTIMER_NORESTART;
+	}
 
 	return HRTIMER_RESTART;
 }
 
 static int vvop_enable_vblank(struct drm_crtc *crtc)
 {
+	struct vvop_crtc *vcrtc = drm_crtc_to_vvop_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
 	unsigned int pipe = drm_crtc_index(crtc);
 	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
-	struct vvop *vvop = drm_crtc_to_vvop(crtc);
 
 	drm_calc_timestamping_constants(crtc, &crtc->mode);
 
-	hrtimer_init(&vvop->vblank_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-	vvop->vblank_hrtimer.function = &vvop_vblank_simulate;
-	vvop->period_ns = ktime_set(0, vblank->framedur_ns);
-	hrtimer_start(&vvop->vblank_hrtimer, vvop->period_ns, HRTIMER_MODE_REL);
+	vcrtc->period_ns = ktime_set(0, vblank->framedur_ns);
+	hrtimer_start(&vcrtc->vblank_hrtimer, vcrtc->period_ns, HRTIMER_MODE_REL);
 
 	return 0;
 }
 
 static void vvop_disable_vblank(struct drm_crtc *crtc)
 {
-	struct vvop *vvop = drm_crtc_to_vvop(crtc);
+	struct vvop_crtc *vcrtc = drm_crtc_to_vvop_crtc(crtc);
 
-	hrtimer_cancel(&vvop->vblank_hrtimer);
+	hrtimer_try_to_cancel(&vcrtc->vblank_hrtimer);
 }
 
 static void vvop_connector_destroy(struct drm_connector *connector)
@@ -152,11 +153,231 @@
 	.destroy = drm_encoder_cleanup,
 };
 
+static struct drm_display_mode vvop_modes_builtin[] = {
+	/* 1280x720@30Hz */
+	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 37125, 1280, 1390,
+		   1430, 1650, 0, 720, 725, 730, 750, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1920x1080@30Hz */
+	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
+		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 2560x1440@30Hz */
+	{ DRM_MODE("2560x1440", DRM_MODE_TYPE_DRIVER, 120750, 2560, 2608,
+		   2640, 2720, 0, 1440, 1443, 1448, 1481, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 3840x2160@30Hz */
+	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
+		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 4096x2160@30Hz */
+	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 4184,
+		   4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 720x1280@30Hz */
+	{ DRM_MODE("720x1280", DRM_MODE_TYPE_DRIVER, 37125, 720, 725,
+		   730, 750, 0, 1280, 1390, 1430, 1650, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1080x1920@30Hz */
+	{ DRM_MODE("1080x1920", DRM_MODE_TYPE_DRIVER, 74250, 1080, 1084,
+		   1089, 1125, 0, 1920, 2008, 2052, 2200, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1440x2560@30Hz */
+	{ DRM_MODE("1440x2560", DRM_MODE_TYPE_DRIVER, 120750, 1440, 1443,
+		   1448, 1481, 0, 2560, 2608, 2640, 2720, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 2160x3840@30Hz */
+	{ DRM_MODE("2160x3840", DRM_MODE_TYPE_DRIVER, 297000, 2160, 2168,
+		   2178, 2250, 0, 3840, 4016, 4104, 4400, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 2160x4096@30Hz */
+	{ DRM_MODE("2160x4096", DRM_MODE_TYPE_DRIVER, 297000, 2160, 2168,
+		   2178, 2250, 0, 4096, 4184, 4272, 4400, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+
+	/* 1280x720@60Hz */
+	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
+		   1430, 1650, 0, 720, 725, 730, 750, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1920x1080@60Hz */
+	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
+		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 2560x1440@60Hz */
+	{ DRM_MODE("2560x1440", DRM_MODE_TYPE_DRIVER, 241500, 2560, 2608,
+		   2640, 2720, 0, 1440, 1443, 1448, 1481, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 3840x2160@60Hz */
+	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
+		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 4096x2160@60Hz */
+	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 4184,
+		   4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 720x1280@60Hz */
+	{ DRM_MODE("720x1280", DRM_MODE_TYPE_DRIVER, 74250, 720, 725,
+		   730, 750, 0, 1280, 1390, 1430, 1650, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1080x1920@60Hz */
+	{ DRM_MODE("1080x1920", DRM_MODE_TYPE_DRIVER, 148500, 1080, 1084,
+		   1089, 1125, 0, 1920, 2008, 2052, 2200, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1440x2560@60Hz */
+	{ DRM_MODE("1440x2560", DRM_MODE_TYPE_DRIVER, 241500, 1440, 1443,
+		   1448, 1481, 0, 2560, 2608, 2640, 2720, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 2160x3840@60Hz */
+	{ DRM_MODE("2160x3840", DRM_MODE_TYPE_DRIVER, 594000, 2160, 2168,
+		   2178, 2250, 0, 3840, 4016, 4104, 4400, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 2160x4096@60Hz */
+	{ DRM_MODE("2160x4096", DRM_MODE_TYPE_DRIVER, 594000, 2160, 2168,
+		   2178, 2250, 0, 4096, 4184, 4272, 4400, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+
+	/* 1280x720@90Hz */
+	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 111375, 1280, 1390,
+		   1430, 1650, 0, 720, 725, 730, 750, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1920x1080@90Hz */
+	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 222750, 1920, 2008,
+		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 2560x1440@90Hz */
+	{ DRM_MODE("2560x1440", DRM_MODE_TYPE_DRIVER, 362250, 2560, 2608,
+		   2640, 2720, 0, 1440, 1443, 1448, 1481, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 3840x2160@90Hz */
+	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 891000, 3840, 4016,
+		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 4096x2160@90Hz */
+	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 891000, 4096, 4184,
+		   4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 720x1280@90Hz */
+	{ DRM_MODE("720x1280", DRM_MODE_TYPE_DRIVER, 111375, 720, 725,
+		   730, 750, 0, 1280, 1390, 1430, 1650, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1080x1920@90Hz */
+	{ DRM_MODE("1080x1920", DRM_MODE_TYPE_DRIVER, 222750, 1080, 1084,
+		   1089, 1125, 0, 1920, 2008, 2052, 2200, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1440x2560@90Hz */
+	{ DRM_MODE("1440x2560", DRM_MODE_TYPE_DRIVER, 362250, 1440, 1443,
+		   1448, 1481, 0, 2560, 2608, 2640, 2720, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 2160x3840@90Hz */
+	{ DRM_MODE("2160x3840", DRM_MODE_TYPE_DRIVER, 891000, 2160, 2168,
+		   2178, 2250, 0, 3840, 4016, 4104, 4400, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 2160x4096@90Hz */
+	{ DRM_MODE("2160x4096", DRM_MODE_TYPE_DRIVER, 891000, 2160, 2168,
+		   2178, 2250, 0, 4096, 4184, 4272, 4400, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+
+	/* 1280x720@120Hz */
+	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
+		   1430, 1650, 0, 720, 725, 730, 750, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1920x1080@120Hz */
+	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
+		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 2560x1440@120Hz */
+	{ DRM_MODE("2560x1440", DRM_MODE_TYPE_DRIVER, 483000, 2560, 2608,
+		   2640, 2720, 0, 1440, 1443, 1448, 1481, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 3840x2160@120Hz */
+	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4016,
+		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 4096x2160@120Hz */
+	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 1188000, 4096, 4184,
+		   4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 720x1280@120Hz */
+	{ DRM_MODE("720x1280", DRM_MODE_TYPE_DRIVER, 148500, 720, 725,
+		   730, 750, 0, 1280, 1390, 1430, 1650, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1080x1920@120Hz */
+	{ DRM_MODE("1080x1920", DRM_MODE_TYPE_DRIVER, 297000, 1080, 1084,
+		   1089, 1125, 0, 1920, 2008, 2052, 2200, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1440x2560@120Hz */
+	{ DRM_MODE("1440x2560", DRM_MODE_TYPE_DRIVER, 483000, 1440, 1443,
+		   1448, 1481, 0, 2560, 2608, 2640, 2720, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 2160x3840@120Hz */
+	{ DRM_MODE("2160x3840", DRM_MODE_TYPE_DRIVER, 1188000, 2160, 2168,
+		   2178, 2250, 0, 3840, 4016, 4104, 4400, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 2160x4096@120Hz */
+	{ DRM_MODE("2160x4096", DRM_MODE_TYPE_DRIVER, 1188000, 2160, 2168,
+		   2178, 2250, 0, 4096, 4184, 4272, 4400, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+
+	/* 1280x720@144Hz */
+	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 178200, 1280, 1390,
+		   1430, 1650, 0, 720, 725, 730, 750, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1920x1080@144Hz */
+	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 356400, 1920, 2008,
+		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 2560x1440@144Hz */
+	{ DRM_MODE("2560x1440", DRM_MODE_TYPE_DRIVER, 483000, 2560, 2608,
+		   2640, 2720, 0, 1440, 1443, 1448, 1481, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 3840x2160@144Hz */
+	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1425600, 3840, 4016,
+		   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 4096x2160@144Hz */
+	{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 1425600, 4096, 4184,
+		   4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 720x1280@144Hz */
+	{ DRM_MODE("720x1280", DRM_MODE_TYPE_DRIVER, 178200, 720, 725,
+		   730, 750, 0, 1280, 1390, 1430, 1650, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1080x1920@144Hz */
+	{ DRM_MODE("1080x1920", DRM_MODE_TYPE_DRIVER, 356400, 1080, 1084,
+		   1089, 1125, 0, 1920, 2008, 2052, 2200, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1440x2560@144Hz */
+	{ DRM_MODE("1440x2560", DRM_MODE_TYPE_DRIVER, 580000, 1440, 1443,
+		   1448, 1481, 0, 2560, 2608, 2640, 2720, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 2160x3840@144Hz */
+	{ DRM_MODE("2160x3840", DRM_MODE_TYPE_DRIVER, 1425600, 2160, 2168,
+		   2178, 2250, 0, 3840, 4016, 4104, 4400, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 2160x4096@144Hz */
+	{ DRM_MODE("2160x4096", DRM_MODE_TYPE_DRIVER, 1425600, 2160, 2168,
+		   2178, 2250, 0, 4096, 4184, 4272, 4400, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+};
+
 static int vvop_conn_get_modes(struct drm_connector *connector)
 {
-	int count;
+	struct drm_display_mode *mode = NULL;
+	struct drm_display_mode *bmode;
+	int count = 0;
+	int i;
 
-	count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
+	count += drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
+	for (i = 0; vvop_modes_builtin[i].type != 0; i++) {
+		bmode = &vvop_modes_builtin[i];
+
+		mode = drm_mode_duplicate(connector->dev, bmode);
+		if (!mode)
+			return 0;
+
+		drm_mode_probed_add(connector, mode);
+		count++;
+	}
 	drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
 
 	return count;
@@ -167,12 +388,12 @@
 };
 
 static const struct drm_crtc_funcs vvop_crtc_funcs = {
-	.set_config             = drm_atomic_helper_set_config,
-	.destroy                = drm_crtc_cleanup,
-	.page_flip              = drm_atomic_helper_page_flip,
-	.reset                  = drm_atomic_helper_crtc_reset,
-	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
-	.atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,
+	.set_config		= drm_atomic_helper_set_config,
+	.destroy		= drm_crtc_cleanup,
+	.page_flip		= drm_atomic_helper_page_flip,
+	.reset			= drm_atomic_helper_crtc_reset,
+	.atomic_duplicate_state	= drm_atomic_helper_crtc_duplicate_state,
+	.atomic_destroy_state	= drm_atomic_helper_crtc_destroy_state,
 	.enable_vblank		= vvop_enable_vblank,
 	.disable_vblank		= vvop_disable_vblank,
 };
@@ -224,9 +445,34 @@
 	.atomic_disable	= vvop_crtc_atomic_disable,
 };
 
-static int vvop_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
-		   struct drm_plane *primary, struct drm_plane *cursor)
+static u64 vvop_get_soc_id(void)
 {
+	if (of_machine_is_compatible("rockchip,rk3588"))
+		return 0x3588;
+	else if (of_machine_is_compatible("rockchip,rk3568"))
+		return 0x3568;
+	else if (of_machine_is_compatible("rockchip,rk3566"))
+		return 0x3566;
+	else if (of_machine_is_compatible("rockchip,rk3562"))
+		return 0x3562;
+	else if (of_machine_is_compatible("rockchip,rk3528"))
+		return 0x3528;
+	else
+		return 0;
+}
+
+static void vvop_crtc_deinit(struct drm_crtc *crtc)
+{
+	struct vvop_crtc *vcrtc = drm_crtc_to_vvop_crtc(crtc);
+
+	hrtimer_cancel(&vcrtc->vblank_hrtimer);
+	drm_crtc_cleanup(crtc);
+}
+
+static int vvop_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
+			  struct drm_plane *primary, struct drm_plane *cursor)
+{
+	struct vvop_crtc *vcrtc = drm_crtc_to_vvop_crtc(crtc);
 	int ret;
 
 	ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor,
@@ -238,18 +484,112 @@
 
 	drm_crtc_helper_add(crtc, &vvop_crtc_helper_funcs);
 
+	vcrtc->is_virtual_prop = drm_property_create_object(dev,
+							    DRM_MODE_PROP_ATOMIC |
+							    DRM_MODE_PROP_IMMUTABLE,
+							    "IS_VIRTUAL", DRM_MODE_OBJECT_CRTC);
+	drm_object_attach_property(&crtc->base, vcrtc->is_virtual_prop, 1);
+
+	vcrtc->soc_id_prop = drm_property_create_object(dev,
+							DRM_MODE_PROP_ATOMIC |
+							DRM_MODE_PROP_IMMUTABLE,
+							"SOC_ID", DRM_MODE_OBJECT_CRTC);
+	drm_object_attach_property(&crtc->base, vcrtc->soc_id_prop, vvop_get_soc_id());
+
+	hrtimer_init(&vcrtc->vblank_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	vcrtc->vblank_hrtimer.function = &vvop_vblank_simulate;
+
 	return ret;
+}
+
+static int vvop_create_crtc(struct vvop *vvop, int index)
+{
+	struct drm_crtc *crtc = &vvop->vcrtc[index].crtc;
+	struct drm_connector *connector = &vvop->vcrtc[index].connector;
+	struct drm_encoder *encoder = &vvop->vcrtc[index].encoder;
+	struct drm_plane *primary = &vvop->vcrtc[index].plane;
+	int ret;
+
+	ret = vvop_plane_init(vvop->drm_dev, primary);
+	if (ret) {
+		DRM_ERROR("Failed to init primary plane for crtc-%d\n", index);
+		return ret;
+	}
+
+	ret = vvop_crtc_init(vvop->drm_dev, crtc, primary, NULL);
+	if (ret) {
+		DRM_ERROR("Failed to init crtc-%d\n", index);
+		goto err_crtc;
+	}
+
+	ret = drm_connector_init(vvop->drm_dev, connector, &vvop_connector_funcs,
+				 DRM_MODE_CONNECTOR_VIRTUAL);
+	if (ret) {
+		DRM_ERROR("Failed to init connector-%d\n", index);
+		goto err_connector;
+	}
+	drm_connector_helper_add(connector, &vvop_conn_helper_funcs);
+
+	ret = drm_connector_register(connector);
+	if (ret) {
+		DRM_ERROR("Failed to register connector-%d\n", index);
+		goto err_connector_register;
+	}
+
+	ret = drm_encoder_init(vvop->drm_dev, encoder, &vvop_encoder_funcs,
+			       DRM_MODE_ENCODER_VIRTUAL, NULL);
+	if (ret) {
+		DRM_ERROR("Failed to init encoder-%d\n", index);
+		goto err_encoder;
+	}
+	encoder->possible_crtcs = BIT(index);
+
+	ret = drm_connector_attach_encoder(connector, encoder);
+	if (ret) {
+		DRM_ERROR("Failed to attach connector-%d to encoder-%d\n", index, index);
+		goto err_attach;
+	}
+
+	vvop->crtc_mask |= drm_crtc_mask(crtc);
+
+	return 0;
+
+err_attach:
+	drm_encoder_cleanup(encoder);
+err_encoder:
+	drm_connector_unregister(connector);
+err_connector_register:
+	drm_connector_cleanup(connector);
+err_connector:
+	vvop_crtc_deinit(crtc);
+err_crtc:
+	drm_plane_cleanup(primary);
+
+	return ret;
+}
+
+static int vvop_create_crtcs(struct vvop *vvop)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < VVOP_MAX_CRTC; i++) {
+		ret = vvop_create_crtc(vvop, i);
+		if (ret) {
+			DRM_WARN("Failed to create virtual crtc, index = %d\n", i);
+			break;
+		}
+	}
+
+	DRM_INFO("Create %d(total: %d) virtual crtcs\n", i, VVOP_MAX_CRTC);
+
+	return 0;
 }
 
 static int vvop_bind(struct device *dev, struct device *master, void *data)
 {
 	struct drm_device *drm_dev = data;
-	struct drm_connector *connector;
-	struct drm_encoder *encoder;
-	struct drm_plane *primary;
-	struct drm_crtc *crtc;
 	struct vvop *vvop;
-	int ret;
 
 	vvop = devm_kzalloc(dev, sizeof(*vvop), GFP_KERNEL);
 	if (!vvop)
@@ -257,77 +597,33 @@
 
 	vvop->dev = dev;
 	vvop->drm_dev = drm_dev;
-	connector = &vvop->connector;
-	encoder = &vvop->encoder;
-	crtc = &vvop->crtc;
-
 	dev_set_drvdata(dev, vvop);
 
-	primary = vvop_plane_init(vvop);
-	if (IS_ERR(primary))
-		return PTR_ERR(primary);
-	vvop->plane = primary;
-
-	ret = vvop_crtc_init(drm_dev, crtc, primary, NULL);
-	if (ret)
-		goto err_crtc;
-
-	ret = drm_connector_init(drm_dev, connector, &vvop_connector_funcs,
-				 DRM_MODE_CONNECTOR_VIRTUAL);
-	if (ret) {
-		DRM_ERROR("Failed to init connector\n");
-		goto err_connector;
-	}
-
-	drm_connector_helper_add(connector, &vvop_conn_helper_funcs);
-
-	ret = drm_connector_register(connector);
-	if (ret) {
-		DRM_ERROR("Failed to register connector\n");
-		goto err_connector_register;
-	}
-
-	ret = drm_encoder_init(drm_dev, encoder, &vvop_encoder_funcs,
-			       DRM_MODE_ENCODER_VIRTUAL, NULL);
-	if (ret) {
-		DRM_ERROR("Failed to init encoder\n");
-		goto err_encoder;
-	}
-	encoder->possible_crtcs = 1;
-
-	ret = drm_connector_attach_encoder(connector, encoder);
-	if (ret) {
-		DRM_ERROR("Failed to attach connector to encoder\n");
-		goto err_attach;
-	}
+	vvop_create_crtcs(vvop);
 
 	return 0;
-
-err_attach:
-	drm_encoder_cleanup(encoder);
-
-err_encoder:
-	drm_connector_unregister(connector);
-
-err_connector_register:
-	drm_connector_cleanup(connector);
-
-err_connector:
-	drm_crtc_cleanup(crtc);
-
-err_crtc:
-	drm_plane_cleanup(primary);
-
-	return ret;
 }
 
 static void vvop_unbind(struct device *dev, struct device *master, void *data)
 {
 	struct vvop *vvop = dev_get_drvdata(dev);
+	struct drm_device *drm_dev = vvop->drm_dev;
+	struct list_head *crtc_list = &drm_dev->mode_config.crtc_list;
+	struct drm_crtc *crtc, *tmp_crtc;
+	struct vvop_crtc *vcrtc;
 
-	drm_plane_cleanup(vvop->plane);
-	drm_connector_cleanup(&vvop->connector);
-	drm_crtc_cleanup(&vvop->crtc);
+	list_for_each_entry_safe(crtc, tmp_crtc, crtc_list, head) {
+		if (vvop->crtc_mask & drm_crtc_mask(crtc)) {
+			vcrtc = drm_crtc_to_vvop_crtc(crtc);
+
+			drm_encoder_cleanup(&vcrtc->encoder);
+			drm_connector_unregister(&vcrtc->connector);
+			drm_connector_cleanup(&vcrtc->connector);
+			drm_plane_cleanup(&vcrtc->plane);
+			vvop->crtc_mask &= ~(drm_crtc_mask(crtc));
+			vvop_crtc_deinit(crtc);
+		}
+	}
 }
 
 const struct component_ops vvop_component_ops = {
@@ -362,12 +658,10 @@
 
 static int __init vvop_init(void)
 {
-	struct platform_device *pdev;
-
-	pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
-	if (IS_ERR(pdev)) {
+	vvop_pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
+	if (IS_ERR(vvop_pdev)) {
 		DRM_ERROR("failed to register platform device %s\n", DRIVER_NAME);
-		return PTR_ERR(pdev);
+		return PTR_ERR(vvop_pdev);
 	}
 
 	return 0;
@@ -375,6 +669,7 @@
 
 static void __exit vvop_exit(void)
 {
+	platform_device_unregister(vvop_pdev);
 }
 
 rootfs_initcall(vvop_init);
diff --git a/kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c b/kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c
index c4d74e1..bc21bf4 100644
--- a/kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c
+++ b/kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c
@@ -533,6 +533,15 @@
 			goto err_free_encoder;
 		}
 
+		if (lvds->secondary) {
+			kfree(connector->name);
+			connector->name = kasprintf(GFP_KERNEL, "LVDS-DUAL");
+			if (!connector->name) {
+				ret = -ENOMEM;
+				goto err_free_connector;
+			}
+		}
+
 		drm_connector_helper_add(connector,
 					 &rockchip_lvds_connector_helper_funcs);
 
diff --git a/kernel/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/kernel/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index f844376..9854a23 100644
--- a/kernel/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/kernel/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -3913,8 +3913,8 @@
 	.nr_mixers = 5,
 	.nr_layers = 6,
 	.nr_gammas = 1,
-	.max_input = { 4096, 2304 },
-	.max_output = { 4096, 2304 },
+	.max_input = { 4096, 4096 },
+	.max_output = { 4096, 4096 },
 	.ctrl = &rk3568_vop_ctrl,
 	.sys_grf = &rk3568_sys_grf_ctrl,
 	.axi_intr = rk3568_vop_axi_intr,
diff --git a/kernel/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/kernel/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 7c63267..069cb6e 100644
--- a/kernel/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/kernel/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -185,7 +185,7 @@
 	.nformats = ARRAY_SIZE(formats_win_full_10bit),
 	.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
 	.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
-	.fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 4),
+	.fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
 	.csc_mode = VOP_REG_VER(RK3288_WIN0_CTRL0, 0x3, 10, 3, 2, -1),
 	.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
 	.xmirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 21, 3, 2, -1),
@@ -669,7 +669,7 @@
 	.nformats = ARRAY_SIZE(formats_win_full_10bit_yuyv),
 	.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
 	.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
-	.fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 4),
+	.fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
 	.fmt_yuyv = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 17),
 	.csc_mode = VOP_REG_VER(RK3288_WIN0_CTRL0, 0x3, 10, 3, 2, -1),
 	.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
diff --git a/kernel/drivers/gpu/drm/sti/sti_dvo.c b/kernel/drivers/gpu/drm/sti/sti_dvo.c
index ddb4184..11225ac 100644
--- a/kernel/drivers/gpu/drm/sti/sti_dvo.c
+++ b/kernel/drivers/gpu/drm/sti/sti_dvo.c
@@ -288,7 +288,7 @@
 
 	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. */
@@ -346,8 +346,9 @@
 
 #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/kernel/drivers/gpu/drm/sti/sti_hda.c b/kernel/drivers/gpu/drm/sti/sti_hda.c
index 5c2b650..418dfcc 100644
--- a/kernel/drivers/gpu/drm/sti/sti_hda.c
+++ b/kernel/drivers/gpu/drm/sti/sti_hda.c
@@ -523,7 +523,7 @@
 
 	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");
@@ -600,8 +600,9 @@
 
 #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/kernel/drivers/gpu/drm/sti/sti_hdmi.c b/kernel/drivers/gpu/drm/sti/sti_hdmi.c
index 38a5587..1bcee73 100644
--- a/kernel/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/kernel/drivers/gpu/drm/sti/sti_hdmi.c
@@ -934,7 +934,7 @@
 	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);
@@ -997,8 +997,9 @@
 
 #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;
diff --git a/kernel/drivers/gpu/drm/sun4i/sun4i_drv.c b/kernel/drivers/gpu/drm/sun4i/sun4i_drv.c
index c5912fd..9c6ae8c 100644
--- a/kernel/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/kernel/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -93,7 +93,7 @@
 	/* drm_vblank_init calls kcalloc, which can fail */
 	ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
 	if (ret)
-		goto cleanup_mode_config;
+		goto unbind_all;
 
 	drm->irq_enabled = true;
 
@@ -117,6 +117,8 @@
 
 finish_poll:
 	drm_kms_helper_poll_fini(drm);
+unbind_all:
+	component_unbind_all(dev, NULL);
 cleanup_mode_config:
 	drm_mode_config_cleanup(drm);
 	of_reserved_mem_device_release(dev);
diff --git a/kernel/drivers/gpu/drm/sun4i/sun4i_tcon.c b/kernel/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 9f06dec..bb43196 100644
--- a/kernel/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/kernel/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -777,21 +777,19 @@
 static int sun4i_tcon_init_clocks(struct device *dev,
 				  struct sun4i_tcon *tcon)
 {
-	tcon->clk = devm_clk_get(dev, "ahb");
+	tcon->clk = devm_clk_get_enabled(dev, "ahb");
 	if (IS_ERR(tcon->clk)) {
 		dev_err(dev, "Couldn't get the TCON bus clock\n");
 		return PTR_ERR(tcon->clk);
 	}
-	clk_prepare_enable(tcon->clk);
 
 	if (tcon->quirks->has_channel_0) {
-		tcon->sclk0 = devm_clk_get(dev, "tcon-ch0");
+		tcon->sclk0 = devm_clk_get_enabled(dev, "tcon-ch0");
 		if (IS_ERR(tcon->sclk0)) {
 			dev_err(dev, "Couldn't get the TCON channel 0 clock\n");
 			return PTR_ERR(tcon->sclk0);
 		}
 	}
-	clk_prepare_enable(tcon->sclk0);
 
 	if (tcon->quirks->has_channel_1) {
 		tcon->sclk1 = devm_clk_get(dev, "tcon-ch1");
@@ -802,12 +800,6 @@
 	}
 
 	return 0;
-}
-
-static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon)
-{
-	clk_disable_unprepare(tcon->sclk0);
-	clk_disable_unprepare(tcon->clk);
 }
 
 static int sun4i_tcon_init_irq(struct device *dev,
@@ -1224,14 +1216,14 @@
 	ret = sun4i_tcon_init_regmap(dev, tcon);
 	if (ret) {
 		dev_err(dev, "Couldn't init our TCON regmap\n");
-		goto err_free_clocks;
+		goto err_assert_reset;
 	}
 
 	if (tcon->quirks->has_channel_0) {
 		ret = sun4i_dclk_create(dev, tcon);
 		if (ret) {
 			dev_err(dev, "Couldn't create our TCON dot clock\n");
-			goto err_free_clocks;
+			goto err_assert_reset;
 		}
 	}
 
@@ -1294,8 +1286,6 @@
 err_free_dotclock:
 	if (tcon->quirks->has_channel_0)
 		sun4i_dclk_free(tcon);
-err_free_clocks:
-	sun4i_tcon_free_clocks(tcon);
 err_assert_reset:
 	reset_control_assert(tcon->lcd_rst);
 	return ret;
@@ -1309,7 +1299,6 @@
 	list_del(&tcon->list);
 	if (tcon->quirks->has_channel_0)
 		sun4i_dclk_free(tcon);
-	sun4i_tcon_free_clocks(tcon);
 }
 
 static const struct component_ops sun4i_tcon_ops = {
diff --git a/kernel/drivers/gpu/drm/tegra/dc.c b/kernel/drivers/gpu/drm/tegra/dc.c
index ceb8633..958d12d 100644
--- a/kernel/drivers/gpu/drm/tegra/dc.c
+++ b/kernel/drivers/gpu/drm/tegra/dc.c
@@ -2564,8 +2564,10 @@
 	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);
 
diff --git a/kernel/drivers/gpu/drm/tegra/dpaux.c b/kernel/drivers/gpu/drm/tegra/dpaux.c
index 105fb9c..f8b8107 100644
--- a/kernel/drivers/gpu/drm/tegra/dpaux.c
+++ b/kernel/drivers/gpu/drm/tegra/dpaux.c
@@ -467,10 +467,8 @@
 		return PTR_ERR(dpaux->regs);
 
 	dpaux->irq = platform_get_irq(pdev, 0);
-	if (dpaux->irq < 0) {
-		dev_err(&pdev->dev, "failed to get IRQ\n");
-		return -ENXIO;
-	}
+	if (dpaux->irq < 0)
+		return dpaux->irq;
 
 	if (!pdev->dev.pm_domain) {
 		dpaux->rst = devm_reset_control_get(&pdev->dev, "dpaux");
diff --git a/kernel/drivers/gpu/drm/tegra/sor.c b/kernel/drivers/gpu/drm/tegra/sor.c
index 32c83f2..9d60d1c 100644
--- a/kernel/drivers/gpu/drm/tegra/sor.c
+++ b/kernel/drivers/gpu/drm/tegra/sor.c
@@ -1153,7 +1153,7 @@
 				    struct drm_dp_link *link)
 {
 	const u64 f = 100000, link_rate = link->rate * 1000;
-	const u64 pclk = mode->clock * 1000;
+	const u64 pclk = (u64)mode->clock * 1000;
 	u64 input, output, watermark, num;
 	struct tegra_sor_params params;
 	u32 num_syms_per_line;
diff --git a/kernel/drivers/gpu/drm/tidss/tidss_dispc.c b/kernel/drivers/gpu/drm/tidss/tidss_dispc.c
index b669168..3371621 100644
--- a/kernel/drivers/gpu/drm/tidss/tidss_dispc.c
+++ b/kernel/drivers/gpu/drm/tidss/tidss_dispc.c
@@ -1855,8 +1855,8 @@
 	{ DRM_FORMAT_XBGR4444, 0x21, },
 	{ DRM_FORMAT_RGBX4444, 0x22, },
 
-	{ DRM_FORMAT_ARGB1555, 0x25, },
-	{ DRM_FORMAT_ABGR1555, 0x26, },
+	{ DRM_FORMAT_XRGB1555, 0x25, },
+	{ DRM_FORMAT_XBGR1555, 0x26, },
 
 	{ DRM_FORMAT_XRGB8888, 0x27, },
 	{ DRM_FORMAT_XBGR8888, 0x28, },
diff --git a/kernel/drivers/gpu/drm/tiny/gm12u320.c b/kernel/drivers/gpu/drm/tiny/gm12u320.c
index 0f5d1e5..1656f3e 100644
--- a/kernel/drivers/gpu/drm/tiny/gm12u320.c
+++ b/kernel/drivers/gpu/drm/tiny/gm12u320.c
@@ -67,10 +67,10 @@
 #define READ_STATUS_SIZE		13
 #define MISC_VALUE_SIZE			4
 
-#define CMD_TIMEOUT			msecs_to_jiffies(200)
-#define DATA_TIMEOUT			msecs_to_jiffies(1000)
-#define IDLE_TIMEOUT			msecs_to_jiffies(2000)
-#define FIRST_FRAME_TIMEOUT		msecs_to_jiffies(2000)
+#define CMD_TIMEOUT			200
+#define DATA_TIMEOUT			1000
+#define IDLE_TIMEOUT			2000
+#define FIRST_FRAME_TIMEOUT		2000
 
 #define MISC_REQ_GET_SET_ECO_A		0xff
 #define MISC_REQ_GET_SET_ECO_B		0x35
@@ -399,7 +399,7 @@
 	 * switches back to showing its logo.
 	 */
 	queue_delayed_work(system_long_wq, &gm12u320->fb_update.work,
-			   IDLE_TIMEOUT);
+			   msecs_to_jiffies(IDLE_TIMEOUT));
 
 	return;
 err:
diff --git a/kernel/drivers/gpu/drm/tiny/ili9486.c b/kernel/drivers/gpu/drm/tiny/ili9486.c
index 403af68..7ea26e5 100644
--- a/kernel/drivers/gpu/drm/tiny/ili9486.c
+++ b/kernel/drivers/gpu/drm/tiny/ili9486.c
@@ -43,6 +43,7 @@
 			     size_t num)
 {
 	struct spi_device *spi = mipi->spi;
+	unsigned int bpw = 8;
 	void *data = par;
 	u32 speed_hz;
 	int i, ret;
@@ -56,8 +57,6 @@
 	 * The displays are Raspberry Pi HATs and connected to the 8-bit only
 	 * SPI controller, so 16-bit command and parameters need byte swapping
 	 * before being transferred as 8-bit on the big endian SPI bus.
-	 * Pixel data bytes have already been swapped before this function is
-	 * called.
 	 */
 	buf[0] = cpu_to_be16(*cmd);
 	gpiod_set_value_cansleep(mipi->dc, 0);
@@ -71,12 +70,18 @@
 		for (i = 0; i < num; i++)
 			buf[i] = cpu_to_be16(par[i]);
 		num *= 2;
-		speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num);
 		data = buf;
 	}
 
+	/*
+	 * Check whether pixel data bytes needs to be swapped or not
+	 */
+	if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !mipi->swap_bytes)
+		bpw = 16;
+
 	gpiod_set_value_cansleep(mipi->dc, 1);
-	ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, data, num);
+	speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num);
+	ret = mipi_dbi_spi_transfer(spi, speed_hz, bpw, data, num);
  free:
 	kfree(buf);
 
diff --git a/kernel/drivers/gpu/drm/ttm/ttm_tt.c b/kernel/drivers/gpu/drm/ttm/ttm_tt.c
index f43fa69..3f1a029 100644
--- a/kernel/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/kernel/drivers/gpu/drm/ttm/ttm_tt.c
@@ -466,3 +466,4 @@
 	else
 		ttm_pool_unpopulate(ttm);
 }
+EXPORT_SYMBOL(ttm_tt_unpopulate);
diff --git a/kernel/drivers/gpu/drm/vc4/vc4_dpi.c b/kernel/drivers/gpu/drm/vc4/vc4_dpi.c
index a90f254..9c8a71d 100644
--- a/kernel/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/kernel/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -148,35 +148,45 @@
 	}
 	drm_connector_list_iter_end(&conn_iter);
 
-	if (connector && connector->display_info.num_bus_formats) {
-		u32 bus_format = connector->display_info.bus_formats[0];
+	if (connector) {
+		if (connector->display_info.num_bus_formats) {
+			u32 bus_format = connector->display_info.bus_formats[0];
 
-		switch (bus_format) {
-		case MEDIA_BUS_FMT_RGB888_1X24:
-			dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB,
-					       DPI_FORMAT);
-			break;
-		case MEDIA_BUS_FMT_BGR888_1X24:
-			dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB,
-					       DPI_FORMAT);
-			dpi_c |= VC4_SET_FIELD(DPI_ORDER_BGR, DPI_ORDER);
-			break;
-		case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
-			dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_2,
-					       DPI_FORMAT);
-			break;
-		case MEDIA_BUS_FMT_RGB666_1X18:
-			dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1,
-					       DPI_FORMAT);
-			break;
-		case MEDIA_BUS_FMT_RGB565_1X16:
-			dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_3,
-					       DPI_FORMAT);
-			break;
-		default:
-			DRM_ERROR("Unknown media bus format %d\n", bus_format);
-			break;
+			switch (bus_format) {
+			case MEDIA_BUS_FMT_RGB888_1X24:
+				dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB,
+						       DPI_FORMAT);
+				break;
+			case MEDIA_BUS_FMT_BGR888_1X24:
+				dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB,
+						       DPI_FORMAT);
+				dpi_c |= VC4_SET_FIELD(DPI_ORDER_BGR,
+						       DPI_ORDER);
+				break;
+			case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
+				dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_2,
+						       DPI_FORMAT);
+				break;
+			case MEDIA_BUS_FMT_RGB666_1X18:
+				dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1,
+						       DPI_FORMAT);
+				break;
+			case MEDIA_BUS_FMT_RGB565_1X16:
+				dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_1,
+						       DPI_FORMAT);
+				break;
+			default:
+				DRM_ERROR("Unknown media bus format %d\n",
+					  bus_format);
+				break;
+			}
 		}
+
+		if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
+			dpi_c |= DPI_PIXEL_CLK_INVERT;
+
+		if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW)
+			dpi_c |= DPI_OUTPUT_ENABLE_INVERT;
 	} else {
 		/* Default to 24bit if no connector found. */
 		dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, DPI_FORMAT);
diff --git a/kernel/drivers/gpu/drm/vc4/vc4_hdmi.c b/kernel/drivers/gpu/drm/vc4/vc4_hdmi.c
index 08175c3..7e86208 100644
--- a/kernel/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/kernel/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -567,11 +567,12 @@
 		     VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL));
 	u32 vertb = (VC4_SET_FIELD(mode->htotal >> (2 - pixel_rep),
 				   VC5_HDMI_VERTB_VSPO) |
-		     VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
+		     VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end +
+				   interlaced,
 				   VC4_HDMI_VERTB_VBP));
 	u32 vertb_even = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
 			  VC4_SET_FIELD(mode->crtc_vtotal -
-					mode->crtc_vsync_end - interlaced,
+					mode->crtc_vsync_end,
 					VC4_HDMI_VERTB_VBP));
 
 	HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021);
@@ -1491,7 +1492,8 @@
 		return 0;
 
 	vc4_hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops,
-						  vc4_hdmi, "vc4",
+						  vc4_hdmi,
+						  vc4_hdmi->variant->card_name,
 						  CEC_CAP_DEFAULTS |
 						  CEC_CAP_CONNECTOR_INFO, 1);
 	ret = PTR_ERR_OR_ZERO(vc4_hdmi->cec_adap);
diff --git a/kernel/drivers/gpu/drm/vc4/vc4_hvs.c b/kernel/drivers/gpu/drm/vc4/vc4_hvs.c
index 95fa6fc..f8f2fc3 100644
--- a/kernel/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/kernel/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -677,6 +677,17 @@
 		      SCALER_DISPCTRL_DSPEISLUR(2) |
 		      SCALER_DISPCTRL_SCLEIRQ);
 
+	/* Set AXI panic mode.
+	 * VC4 panics when < 2 lines in FIFO.
+	 * VC5 panics when less than 1 line in the FIFO.
+	 */
+	dispctrl &= ~(SCALER_DISPCTRL_PANIC0_MASK |
+		      SCALER_DISPCTRL_PANIC1_MASK |
+		      SCALER_DISPCTRL_PANIC2_MASK);
+	dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC0);
+	dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC1);
+	dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2);
+
 	HVS_WRITE(SCALER_DISPCTRL, dispctrl);
 
 	ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
diff --git a/kernel/drivers/gpu/drm/vc4/vc4_plane.c b/kernel/drivers/gpu/drm/vc4/vc4_plane.c
index 4df222a..2e03c16 100644
--- a/kernel/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/kernel/drivers/gpu/drm/vc4/vc4_plane.c
@@ -72,11 +72,13 @@
 		.drm = DRM_FORMAT_ARGB1555,
 		.hvs = HVS_PIXEL_FORMAT_RGBA5551,
 		.pixel_order = HVS_PIXEL_ORDER_ABGR,
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
 	},
 	{
 		.drm = DRM_FORMAT_XRGB1555,
 		.hvs = HVS_PIXEL_FORMAT_RGBA5551,
 		.pixel_order = HVS_PIXEL_ORDER_ABGR,
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
 	},
 	{
 		.drm = DRM_FORMAT_RGB888,
diff --git a/kernel/drivers/gpu/drm/vc4/vc4_regs.h b/kernel/drivers/gpu/drm/vc4/vc4_regs.h
index be2c32a..a324ef8 100644
--- a/kernel/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/kernel/drivers/gpu/drm/vc4/vc4_regs.h
@@ -220,6 +220,12 @@
 #define SCALER_DISPCTRL                         0x00000000
 /* Global register for clock gating the HVS */
 # define SCALER_DISPCTRL_ENABLE			BIT(31)
+# define SCALER_DISPCTRL_PANIC0_MASK		VC4_MASK(25, 24)
+# define SCALER_DISPCTRL_PANIC0_SHIFT		24
+# define SCALER_DISPCTRL_PANIC1_MASK		VC4_MASK(27, 26)
+# define SCALER_DISPCTRL_PANIC1_SHIFT		26
+# define SCALER_DISPCTRL_PANIC2_MASK		VC4_MASK(29, 28)
+# define SCALER_DISPCTRL_PANIC2_SHIFT		28
 # define SCALER_DISPCTRL_DSP3_MUX_MASK		VC4_MASK(19, 18)
 # define SCALER_DISPCTRL_DSP3_MUX_SHIFT		18
 
diff --git a/kernel/drivers/gpu/drm/vgem/vgem_fence.c b/kernel/drivers/gpu/drm/vgem/vgem_fence.c
index 17f32f5..575bc33 100644
--- a/kernel/drivers/gpu/drm/vgem/vgem_fence.c
+++ b/kernel/drivers/gpu/drm/vgem/vgem_fence.c
@@ -249,4 +249,5 @@
 {
 	idr_for_each(&vfile->fence_idr, __vgem_fence_idr_fini, vfile);
 	idr_destroy(&vfile->fence_idr);
+	mutex_destroy(&vfile->fence_mutex);
 }
diff --git a/kernel/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/kernel/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 33b8eba..36efa27 100644
--- a/kernel/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/kernel/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -279,10 +279,18 @@
 		drm_gem_object_release(obj);
 		return ret;
 	}
-	drm_gem_object_put(obj);
 
 	rc->res_handle = qobj->hw_res_handle; /* similiar to a VM address */
 	rc->bo_handle = handle;
+
+	/*
+	 * The handle owns the reference now.  But we must drop our
+	 * remaining reference *after* we no longer need to dereference
+	 * the obj.  Otherwise userspace could guess the handle and
+	 * race closing it from another thread.
+	 */
+	drm_gem_object_put(obj);
+
 	return 0;
 }
 
diff --git a/kernel/drivers/gpu/drm/virtio/virtgpu_object.c b/kernel/drivers/gpu/drm/virtio/virtgpu_object.c
index 0c98978..49fa59e 100644
--- a/kernel/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/kernel/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -157,9 +157,11 @@
 	 * since virtio_gpu doesn't support dma-buf import from other devices.
 	 */
 	shmem->pages = drm_gem_shmem_get_sg_table(&bo->base.base);
-	if (!shmem->pages) {
+	if (IS_ERR(shmem->pages)) {
 		drm_gem_shmem_unpin(&bo->base.base);
-		return -EINVAL;
+		ret = PTR_ERR(shmem->pages);
+		shmem->pages = NULL;
+		return ret;
 	}
 
 	if (use_dma_api) {
diff --git a/kernel/drivers/gpu/drm/vkms/vkms_drv.c b/kernel/drivers/gpu/drm/vkms/vkms_drv.c
index cb0b623..8384289 100644
--- a/kernel/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/kernel/drivers/gpu/drm/vkms/vkms_drv.c
@@ -61,7 +61,8 @@
 {
 	struct vkms_device *vkms = container_of(dev, struct vkms_device, drm);
 
-	destroy_workqueue(vkms->output.composer_workq);
+	if (vkms->output.composer_workq)
+		destroy_workqueue(vkms->output.composer_workq);
 }
 
 static void vkms_atomic_commit_tail(struct drm_atomic_state *old_state)
diff --git a/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index ad208a5..0a79c57 100644
--- a/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -1606,4 +1606,17 @@
 {
 	WRITE_ONCE(*addr, value);
 }
+
+static inline bool vmw_shadertype_is_valid(enum vmw_sm_type shader_model,
+					   u32 shader_type)
+{
+	SVGA3dShaderType max_allowed = SVGA3D_SHADERTYPE_PREDX_MAX;
+
+	if (shader_model >= VMW_SM_5)
+		max_allowed = SVGA3D_SHADERTYPE_MAX;
+	else if (shader_model >= VMW_SM_4)
+		max_allowed = SVGA3D_SHADERTYPE_DX10_MAX;
+	return shader_type >= SVGA3D_SHADERTYPE_MIN && shader_type < max_allowed;
+}
+
 #endif
diff --git a/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index 739cbc7..4c6c2e5 100644
--- a/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -1998,7 +1998,7 @@
 
 	cmd = container_of(header, typeof(*cmd), header);
 
-	if (cmd->body.type >= SVGA3D_SHADERTYPE_PREDX_MAX) {
+	if (!vmw_shadertype_is_valid(VMW_SM_LEGACY, cmd->body.type)) {
 		VMW_DEBUG_USER("Illegal shader type %u.\n",
 			       (unsigned int) cmd->body.type);
 		return -EINVAL;
@@ -2120,8 +2120,6 @@
 				      SVGA3dCmdHeader *header)
 {
 	VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetSingleConstantBuffer);
-	SVGA3dShaderType max_shader_num = has_sm5_context(dev_priv) ?
-		SVGA3D_NUM_SHADERTYPE : SVGA3D_NUM_SHADERTYPE_DX10;
 
 	struct vmw_resource *res = NULL;
 	struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
@@ -2138,6 +2136,14 @@
 	if (unlikely(ret != 0))
 		return ret;
 
+	if (!vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type) ||
+	    cmd->body.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) {
+		VMW_DEBUG_USER("Illegal const buffer shader %u slot %u.\n",
+			       (unsigned int) cmd->body.type,
+			       (unsigned int) cmd->body.slot);
+		return -EINVAL;
+	}
+
 	binding.bi.ctx = ctx_node->ctx;
 	binding.bi.res = res;
 	binding.bi.bt = vmw_ctx_binding_cb;
@@ -2145,14 +2151,6 @@
 	binding.offset = cmd->body.offsetInBytes;
 	binding.size = cmd->body.sizeInBytes;
 	binding.slot = cmd->body.slot;
-
-	if (binding.shader_slot >= max_shader_num ||
-	    binding.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) {
-		VMW_DEBUG_USER("Illegal const buffer shader %u slot %u.\n",
-			       (unsigned int) cmd->body.type,
-			       (unsigned int) binding.slot);
-		return -EINVAL;
-	}
 
 	vmw_binding_add(ctx_node->staged, &binding.bi, binding.shader_slot,
 			binding.slot);
@@ -2174,15 +2172,13 @@
 {
 	VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShaderResources) =
 		container_of(header, typeof(*cmd), header);
-	SVGA3dShaderType max_allowed = has_sm5_context(dev_priv) ?
-		SVGA3D_SHADERTYPE_MAX : SVGA3D_SHADERTYPE_DX10_MAX;
 
 	u32 num_sr_view = (cmd->header.size - sizeof(cmd->body)) /
 		sizeof(SVGA3dShaderResourceViewId);
 
 	if ((u64) cmd->body.startView + (u64) num_sr_view >
 	    (u64) SVGA3D_DX_MAX_SRVIEWS ||
-	    cmd->body.type >= max_allowed) {
+	    !vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type)) {
 		VMW_DEBUG_USER("Invalid shader binding.\n");
 		return -EINVAL;
 	}
@@ -2206,8 +2202,6 @@
 				 SVGA3dCmdHeader *header)
 {
 	VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShader);
-	SVGA3dShaderType max_allowed = has_sm5_context(dev_priv) ?
-		SVGA3D_SHADERTYPE_MAX : SVGA3D_SHADERTYPE_DX10_MAX;
 	struct vmw_resource *res = NULL;
 	struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
 	struct vmw_ctx_bindinfo_shader binding;
@@ -2218,8 +2212,7 @@
 
 	cmd = container_of(header, typeof(*cmd), header);
 
-	if (cmd->body.type >= max_allowed ||
-	    cmd->body.type < SVGA3D_SHADERTYPE_MIN) {
+	if (!vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type)) {
 		VMW_DEBUG_USER("Illegal shader type %u.\n",
 			       (unsigned int) cmd->body.type);
 		return -EINVAL;
diff --git a/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index e581129..0e963fd 100644
--- a/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -182,7 +182,8 @@
 	if (cmd->dma.guest.ptr.offset % PAGE_SIZE ||
 	    box->x != 0    || box->y != 0    || box->z != 0    ||
 	    box->srcx != 0 || box->srcy != 0 || box->srcz != 0 ||
-	    box->d != 1    || box_count != 1) {
+	    box->d != 1    || box_count != 1 ||
+	    box->w > 64 || box->h > 64) {
 		/* TODO handle none page aligned offsets */
 		/* TODO handle more dst & src != 0 */
 		/* TODO handle more then one copy */
diff --git a/kernel/drivers/gpu/drm/xlnx/zynqmp_dpsub.c b/kernel/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
index 8e69303..5f6eea8 100644
--- a/kernel/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
+++ b/kernel/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
@@ -214,7 +214,9 @@
 	dpsub->dev = &pdev->dev;
 	platform_set_drvdata(pdev, dpsub);
 
-	dma_set_mask(dpsub->dev, DMA_BIT_MASK(ZYNQMP_DISP_MAX_DMA_BIT));
+	ret = dma_set_mask(dpsub->dev, DMA_BIT_MASK(ZYNQMP_DISP_MAX_DMA_BIT));
+	if (ret)
+		return ret;
 
 	/* Try the reserved memory. Proceed if there's none. */
 	of_reserved_mem_device_init(&pdev->dev);
diff --git a/kernel/drivers/gpu/host1x/hw/syncpt_hw.c b/kernel/drivers/gpu/host1x/hw/syncpt_hw.c
index dd39d67..8cf35b2 100644
--- a/kernel/drivers/gpu/host1x/hw/syncpt_hw.c
+++ b/kernel/drivers/gpu/host1x/hw/syncpt_hw.c
@@ -106,9 +106,6 @@
 #if HOST1X_HW >= 6
 	struct host1x *host = sp->host;
 
-	if (!host->hv_regs)
-		return;
-
 	host1x_sync_writel(host,
 			   HOST1X_SYNC_SYNCPT_CH_APP_CH(ch ? ch->id : 0xff),
 			   HOST1X_SYNC_SYNCPT_CH_APP(sp->id));
diff --git a/kernel/drivers/gpu/ipu-v3/ipu-common.c b/kernel/drivers/gpu/ipu-v3/ipu-common.c
index d166ee2..22dae3f 100644
--- a/kernel/drivers/gpu/ipu-v3/ipu-common.c
+++ b/kernel/drivers/gpu/ipu-v3/ipu-common.c
@@ -1168,6 +1168,7 @@
 		pdev = platform_device_alloc(reg->name, id++);
 		if (!pdev) {
 			ret = -ENOMEM;
+			of_node_put(of_node);
 			goto err_register;
 		}
 
diff --git a/kernel/drivers/hid/hid-asus.c b/kernel/drivers/hid/hid-asus.c
index f85c6e3..6865cab 100644
--- a/kernel/drivers/hid/hid-asus.c
+++ b/kernel/drivers/hid/hid-asus.c
@@ -95,6 +95,7 @@
 	struct hid_device *hdev;
 	struct work_struct work;
 	unsigned int brightness;
+	spinlock_t lock;
 	bool removed;
 };
 
@@ -397,24 +398,42 @@
 	return ret;
 }
 
+static void asus_schedule_work(struct asus_kbd_leds *led)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&led->lock, flags);
+	if (!led->removed)
+		schedule_work(&led->work);
+	spin_unlock_irqrestore(&led->lock, flags);
+}
+
 static void asus_kbd_backlight_set(struct led_classdev *led_cdev,
 				   enum led_brightness brightness)
 {
 	struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds,
 						 cdev);
-	if (led->brightness == brightness)
-		return;
+	unsigned long flags;
 
+	spin_lock_irqsave(&led->lock, flags);
 	led->brightness = brightness;
-	schedule_work(&led->work);
+	spin_unlock_irqrestore(&led->lock, flags);
+
+	asus_schedule_work(led);
 }
 
 static enum led_brightness asus_kbd_backlight_get(struct led_classdev *led_cdev)
 {
 	struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds,
 						 cdev);
+	enum led_brightness brightness;
+	unsigned long flags;
 
-	return led->brightness;
+	spin_lock_irqsave(&led->lock, flags);
+	brightness = led->brightness;
+	spin_unlock_irqrestore(&led->lock, flags);
+
+	return brightness;
 }
 
 static void asus_kbd_backlight_work(struct work_struct *work)
@@ -422,11 +441,11 @@
 	struct asus_kbd_leds *led = container_of(work, struct asus_kbd_leds, work);
 	u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, 0x00 };
 	int ret;
+	unsigned long flags;
 
-	if (led->removed)
-		return;
-
+	spin_lock_irqsave(&led->lock, flags);
 	buf[4] = led->brightness;
+	spin_unlock_irqrestore(&led->lock, flags);
 
 	ret = asus_kbd_set_report(led->hdev, buf, sizeof(buf));
 	if (ret < 0)
@@ -488,6 +507,7 @@
 	drvdata->kbd_backlight->cdev.brightness_set = asus_kbd_backlight_set;
 	drvdata->kbd_backlight->cdev.brightness_get = asus_kbd_backlight_get;
 	INIT_WORK(&drvdata->kbd_backlight->work, asus_kbd_backlight_work);
+	spin_lock_init(&drvdata->kbd_backlight->lock);
 
 	ret = devm_led_classdev_register(&hdev->dev, &drvdata->kbd_backlight->cdev);
 	if (ret < 0) {
@@ -1016,9 +1036,13 @@
 static void asus_remove(struct hid_device *hdev)
 {
 	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
+	unsigned long flags;
 
 	if (drvdata->kbd_backlight) {
+		spin_lock_irqsave(&drvdata->kbd_backlight->lock, flags);
 		drvdata->kbd_backlight->removed = true;
+		spin_unlock_irqrestore(&drvdata->kbd_backlight->lock, flags);
+
 		cancel_work_sync(&drvdata->kbd_backlight->work);
 	}
 
diff --git a/kernel/drivers/hid/hid-betopff.c b/kernel/drivers/hid/hid-betopff.c
index 467d789..25ed7b9 100644
--- a/kernel/drivers/hid/hid-betopff.c
+++ b/kernel/drivers/hid/hid-betopff.c
@@ -60,7 +60,6 @@
 	struct list_head *report_list =
 			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
 	struct input_dev *dev;
-	int field_count = 0;
 	int error;
 	int i, j;
 
@@ -86,17 +85,19 @@
 	 * -----------------------------------------
 	 * Do init them with default value.
 	 */
+	if (report->maxfield < 4) {
+		hid_err(hid, "not enough fields in the report: %d\n",
+				report->maxfield);
+		return -ENODEV;
+	}
 	for (i = 0; i < report->maxfield; i++) {
+		if (report->field[i]->report_count < 1) {
+			hid_err(hid, "no values in the field\n");
+			return -ENODEV;
+		}
 		for (j = 0; j < report->field[i]->report_count; j++) {
 			report->field[i]->value[j] = 0x00;
-			field_count++;
 		}
-	}
-
-	if (field_count < 4) {
-		hid_err(hid, "not enough fields in the report: %d\n",
-				field_count);
-		return -ENODEV;
 	}
 
 	betopff = kzalloc(sizeof(*betopff), GFP_KERNEL);
diff --git a/kernel/drivers/hid/hid-bigbenff.c b/kernel/drivers/hid/hid-bigbenff.c
index e8c5e3a..a02cb51 100644
--- a/kernel/drivers/hid/hid-bigbenff.c
+++ b/kernel/drivers/hid/hid-bigbenff.c
@@ -174,6 +174,7 @@
 struct bigben_device {
 	struct hid_device *hid;
 	struct hid_report *report;
+	spinlock_t lock;
 	bool removed;
 	u8 led_state;         /* LED1 = 1 .. LED4 = 8 */
 	u8 right_motor_on;    /* right motor off/on 0/1 */
@@ -184,18 +185,39 @@
 	struct work_struct worker;
 };
 
+static inline void bigben_schedule_work(struct bigben_device *bigben)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&bigben->lock, flags);
+	if (!bigben->removed)
+		schedule_work(&bigben->worker);
+	spin_unlock_irqrestore(&bigben->lock, flags);
+}
 
 static void bigben_worker(struct work_struct *work)
 {
 	struct bigben_device *bigben = container_of(work,
 		struct bigben_device, worker);
 	struct hid_field *report_field = bigben->report->field[0];
+	bool do_work_led = false;
+	bool do_work_ff = false;
+	u8 *buf;
+	u32 len;
+	unsigned long flags;
 
-	if (bigben->removed || !report_field)
+	buf = hid_alloc_report_buf(bigben->report, GFP_KERNEL);
+	if (!buf)
 		return;
+
+	len = hid_report_len(bigben->report);
+
+	/* LED work */
+	spin_lock_irqsave(&bigben->lock, flags);
 
 	if (bigben->work_led) {
 		bigben->work_led = false;
+		do_work_led = true;
 		report_field->value[0] = 0x01; /* 1 = led message */
 		report_field->value[1] = 0x08; /* reserved value, always 8 */
 		report_field->value[2] = bigben->led_state;
@@ -204,11 +226,22 @@
 		report_field->value[5] = 0x00; /* padding */
 		report_field->value[6] = 0x00; /* padding */
 		report_field->value[7] = 0x00; /* padding */
-		hid_hw_request(bigben->hid, bigben->report, HID_REQ_SET_REPORT);
+		hid_output_report(bigben->report, buf);
 	}
+
+	spin_unlock_irqrestore(&bigben->lock, flags);
+
+	if (do_work_led) {
+		hid_hw_raw_request(bigben->hid, bigben->report->id, buf, len,
+				   bigben->report->type, HID_REQ_SET_REPORT);
+	}
+
+	/* FF work */
+	spin_lock_irqsave(&bigben->lock, flags);
 
 	if (bigben->work_ff) {
 		bigben->work_ff = false;
+		do_work_ff = true;
 		report_field->value[0] = 0x02; /* 2 = rumble effect message */
 		report_field->value[1] = 0x08; /* reserved value, always 8 */
 		report_field->value[2] = bigben->right_motor_on;
@@ -217,8 +250,17 @@
 		report_field->value[5] = 0x00; /* padding */
 		report_field->value[6] = 0x00; /* padding */
 		report_field->value[7] = 0x00; /* padding */
-		hid_hw_request(bigben->hid, bigben->report, HID_REQ_SET_REPORT);
+		hid_output_report(bigben->report, buf);
 	}
+
+	spin_unlock_irqrestore(&bigben->lock, flags);
+
+	if (do_work_ff) {
+		hid_hw_raw_request(bigben->hid, bigben->report->id, buf, len,
+				   bigben->report->type, HID_REQ_SET_REPORT);
+	}
+
+	kfree(buf);
 }
 
 static int hid_bigben_play_effect(struct input_dev *dev, void *data,
@@ -228,6 +270,7 @@
 	struct bigben_device *bigben = hid_get_drvdata(hid);
 	u8 right_motor_on;
 	u8 left_motor_force;
+	unsigned long flags;
 
 	if (!bigben) {
 		hid_err(hid, "no device data\n");
@@ -242,10 +285,13 @@
 
 	if (right_motor_on != bigben->right_motor_on ||
 			left_motor_force != bigben->left_motor_force) {
+		spin_lock_irqsave(&bigben->lock, flags);
 		bigben->right_motor_on   = right_motor_on;
 		bigben->left_motor_force = left_motor_force;
 		bigben->work_ff = true;
-		schedule_work(&bigben->worker);
+		spin_unlock_irqrestore(&bigben->lock, flags);
+
+		bigben_schedule_work(bigben);
 	}
 
 	return 0;
@@ -259,6 +305,7 @@
 	struct bigben_device *bigben = hid_get_drvdata(hid);
 	int n;
 	bool work;
+	unsigned long flags;
 
 	if (!bigben) {
 		hid_err(hid, "no device data\n");
@@ -267,6 +314,7 @@
 
 	for (n = 0; n < NUM_LEDS; n++) {
 		if (led == bigben->leds[n]) {
+			spin_lock_irqsave(&bigben->lock, flags);
 			if (value == LED_OFF) {
 				work = (bigben->led_state & BIT(n));
 				bigben->led_state &= ~BIT(n);
@@ -274,10 +322,11 @@
 				work = !(bigben->led_state & BIT(n));
 				bigben->led_state |= BIT(n);
 			}
+			spin_unlock_irqrestore(&bigben->lock, flags);
 
 			if (work) {
 				bigben->work_led = true;
-				schedule_work(&bigben->worker);
+				bigben_schedule_work(bigben);
 			}
 			return;
 		}
@@ -307,8 +356,12 @@
 static void bigben_remove(struct hid_device *hid)
 {
 	struct bigben_device *bigben = hid_get_drvdata(hid);
+	unsigned long flags;
 
+	spin_lock_irqsave(&bigben->lock, flags);
 	bigben->removed = true;
+	spin_unlock_irqrestore(&bigben->lock, flags);
+
 	cancel_work_sync(&bigben->worker);
 	hid_hw_stop(hid);
 }
@@ -318,7 +371,6 @@
 {
 	struct bigben_device *bigben;
 	struct hid_input *hidinput;
-	struct list_head *report_list;
 	struct led_classdev *led;
 	char *name;
 	size_t name_sz;
@@ -343,9 +395,12 @@
 		return error;
 	}
 
-	report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
-	bigben->report = list_entry(report_list->next,
-		struct hid_report, list);
+	bigben->report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 8);
+	if (!bigben->report) {
+		hid_err(hid, "no output report found\n");
+		error = -ENODEV;
+		goto error_hw_stop;
+	}
 
 	if (list_empty(&hid->inputs)) {
 		hid_err(hid, "no inputs found\n");
@@ -357,6 +412,7 @@
 	set_bit(FF_RUMBLE, hidinput->input->ffbit);
 
 	INIT_WORK(&bigben->worker, bigben_worker);
+	spin_lock_init(&bigben->lock);
 
 	error = input_ff_create_memless(hidinput->input, NULL,
 		hid_bigben_play_effect);
@@ -397,7 +453,7 @@
 	bigben->left_motor_force = 0;
 	bigben->work_led = true;
 	bigben->work_ff = true;
-	schedule_work(&bigben->worker);
+	bigben_schedule_work(bigben);
 
 	hid_info(hid, "LED and force feedback support for BigBen gamepad\n");
 
diff --git a/kernel/drivers/hid/hid-core.c b/kernel/drivers/hid/hid-core.c
index eaaf732..b007074 100644
--- a/kernel/drivers/hid/hid-core.c
+++ b/kernel/drivers/hid/hid-core.c
@@ -32,6 +32,7 @@
 #include <linux/hiddev.h>
 #include <linux/hid-debug.h>
 #include <linux/hidraw.h>
+#include <linux/uhid.h>
 
 #include "hid-ids.h"
 
@@ -258,6 +259,7 @@
 {
 	struct hid_report *report;
 	struct hid_field *field;
+	unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE;
 	unsigned int usages;
 	unsigned int offset;
 	unsigned int i;
@@ -288,8 +290,11 @@
 	offset = report->size;
 	report->size += parser->global.report_size * parser->global.report_count;
 
+	if (IS_ENABLED(CONFIG_UHID) && parser->device->ll_driver == &uhid_hid_driver)
+		max_buffer_size = UHID_DATA_MAX;
+
 	/* Total size check: Allow for possible report index byte */
-	if (report->size > (HID_MAX_BUFFER_SIZE - 1) << 3) {
+	if (report->size > (max_buffer_size - 1) << 3) {
 		hid_err(parser->device, "report is too long\n");
 		return -1;
 	}
@@ -988,8 +993,8 @@
 		 * Validating on id 0 means we should examine the first
 		 * report in the list.
 		 */
-		report = list_entry(
-				hid->report_enum[type].report_list.next,
+		report = list_first_entry_or_null(
+				&hid->report_enum[type].report_list,
 				struct hid_report, list);
 	} else {
 		report = hid->report_enum[type].report_id_hash[id];
@@ -1197,6 +1202,7 @@
 	__u8 *end;
 	__u8 *next;
 	int ret;
+	int i;
 	static int (*dispatch_type[])(struct hid_parser *parser,
 				      struct hid_item *item) = {
 		hid_parser_main,
@@ -1247,6 +1253,8 @@
 		goto err;
 	}
 	device->collection_size = HID_DEFAULT_NUM_COLLECTIONS;
+	for (i = 0; i < HID_DEFAULT_NUM_COLLECTIONS; i++)
+		device->collection[i].parent_idx = -1;
 
 	ret = -EINVAL;
 	while ((next = fetch_item(start, end, &item)) != NULL) {
@@ -1749,6 +1757,7 @@
 	struct hid_report_enum *report_enum = hid->report_enum + type;
 	struct hid_report *report;
 	struct hid_driver *hdrv;
+	int max_buffer_size = HID_MAX_BUFFER_SIZE;
 	unsigned int a;
 	u32 rsize, csize = size;
 	u8 *cdata = data;
@@ -1765,10 +1774,13 @@
 
 	rsize = hid_compute_report_size(report);
 
-	if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE)
-		rsize = HID_MAX_BUFFER_SIZE - 1;
-	else if (rsize > HID_MAX_BUFFER_SIZE)
-		rsize = HID_MAX_BUFFER_SIZE;
+	if (IS_ENABLED(CONFIG_UHID) && hid->ll_driver == &uhid_hid_driver)
+		max_buffer_size = UHID_DATA_MAX;
+
+	if (report_enum->numbered && rsize >= max_buffer_size)
+		rsize = max_buffer_size - 1;
+	else if (rsize > max_buffer_size)
+		rsize = max_buffer_size;
 
 	if (csize < rsize) {
 		dbg_hid("report %d is too short, (%d < %d)\n", report->id,
diff --git a/kernel/drivers/hid/hid-cp2112.c b/kernel/drivers/hid/hid-cp2112.c
index 172f20e..d902fe4 100644
--- a/kernel/drivers/hid/hid-cp2112.c
+++ b/kernel/drivers/hid/hid-cp2112.c
@@ -1352,6 +1352,7 @@
 	girq->parents = NULL;
 	girq->default_type = IRQ_TYPE_NONE;
 	girq->handler = handle_simple_irq;
+	girq->threaded = true;
 
 	ret = gpiochip_add_data(&dev->gc, dev);
 	if (ret < 0) {
diff --git a/kernel/drivers/hid/hid-debug.c b/kernel/drivers/hid/hid-debug.c
index f4e2e69..1f60a38 100644
--- a/kernel/drivers/hid/hid-debug.c
+++ b/kernel/drivers/hid/hid-debug.c
@@ -933,6 +933,7 @@
 	[KEY_VOICECOMMAND] = "VoiceCommand",
 	[KEY_EMOJI_PICKER] = "EmojiPicker",
 	[KEY_DICTATE] = "Dictate",
+	[KEY_MICMUTE] = "MicrophoneMute",
 	[KEY_BRIGHTNESS_MIN] = "BrightnessMin",
 	[KEY_BRIGHTNESS_MAX] = "BrightnessMax",
 	[KEY_BRIGHTNESS_AUTO] = "BrightnessAuto",
diff --git a/kernel/drivers/hid/hid-google-hammer.c b/kernel/drivers/hid/hid-google-hammer.c
index 0476301..2f4c5b4 100644
--- a/kernel/drivers/hid/hid-google-hammer.c
+++ b/kernel/drivers/hid/hid-google-hammer.c
@@ -533,6 +533,8 @@
 	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
 		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) },
 	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
+		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_JEWEL) },
+	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
 		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MAGNEMITE) },
 	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
 		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MASTERBALL) },
diff --git a/kernel/drivers/hid/hid-ids.h b/kernel/drivers/hid/hid-ids.h
index 2b7f6ea..c801b8d 100644
--- a/kernel/drivers/hid/hid-ids.h
+++ b/kernel/drivers/hid/hid-ids.h
@@ -257,7 +257,6 @@
 #define USB_DEVICE_ID_CH_AXIS_295	0x001c
 
 #define USB_VENDOR_ID_CHERRY		0x046a
-#define USB_DEVICE_ID_CHERRY_MOUSE_000C	0x000c
 #define USB_DEVICE_ID_CHERRY_CYMOTION	0x0023
 #define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR	0x0027
 
@@ -492,6 +491,7 @@
 #define USB_DEVICE_ID_GOOGLE_MOONBALL	0x5044
 #define USB_DEVICE_ID_GOOGLE_DON	0x5050
 #define USB_DEVICE_ID_GOOGLE_EEL	0x5057
+#define USB_DEVICE_ID_GOOGLE_JEWEL	0x5061
 
 #define USB_VENDOR_ID_GOTOP		0x08f2
 #define USB_DEVICE_ID_SUPER_Q2		0x007f
@@ -582,6 +582,7 @@
 #define USB_DEVICE_ID_UGCI_FIGHTING	0x0030
 
 #define USB_VENDOR_ID_HP		0x03f0
+#define USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A		0x464a
 #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A	0x0a4a
 #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A	0x0b4a
 #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE		0x134a
@@ -951,7 +952,10 @@
 #define USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S	0x8003
 
 #define USB_VENDOR_ID_PLANTRONICS	0x047f
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES	0xc055
 #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES	0xc056
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES	0xc057
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES	0xc058
 
 #define USB_VENDOR_ID_PANASONIC		0x04da
 #define USB_DEVICE_ID_PANABOARD_UBT780	0x1044
diff --git a/kernel/drivers/hid/hid-input.c b/kernel/drivers/hid/hid-input.c
index 75a4d8d..3399953 100644
--- a/kernel/drivers/hid/hid-input.c
+++ b/kernel/drivers/hid/hid-input.c
@@ -675,6 +675,14 @@
 			break;
 		}
 
+		if ((usage->hid & 0xf0) == 0xa0) {	/* SystemControl */
+			switch (usage->hid & 0xf) {
+			case 0x9: map_key_clear(KEY_MICMUTE); break;
+			default: goto ignore;
+			}
+			break;
+		}
+
 		if ((usage->hid & 0xf0) == 0xb0) {	/* SC - Display */
 			switch (usage->hid & 0xf) {
 			case 0x05: map_key_clear(KEY_SWITCHVIDEOMODE); break;
diff --git a/kernel/drivers/hid/hid-logitech-dj.c b/kernel/drivers/hid/hid-logitech-dj.c
index 587259b..f4d79ec 100644
--- a/kernel/drivers/hid/hid-logitech-dj.c
+++ b/kernel/drivers/hid/hid-logitech-dj.c
@@ -1217,6 +1217,9 @@
 		 * 50 msec should gives enough time to the receiver to be ready.
 		 */
 		msleep(50);
+
+		if (retval)
+			return retval;
 	}
 
 	/*
@@ -1238,7 +1241,7 @@
 	buf[5] = 0x09;
 	buf[6] = 0x00;
 
-	hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf,
+	retval = hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf,
 			HIDPP_REPORT_SHORT_LENGTH, HID_OUTPUT_REPORT,
 			HID_REQ_SET_REPORT);
 
diff --git a/kernel/drivers/hid/hid-logitech-hidpp.c b/kernel/drivers/hid/hid-logitech-hidpp.c
index 66b1051..6ac0c2d 100644
--- a/kernel/drivers/hid/hid-logitech-hidpp.c
+++ b/kernel/drivers/hid/hid-logitech-hidpp.c
@@ -828,8 +828,7 @@
 	if (ret)
 		return ret;
 
-	snprintf(hdev->uniq, sizeof(hdev->uniq), "%04x-%4phD",
-		 hdev->product, &serial);
+	snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial);
 	dbg_hid("HID++ Unifying: Got serial: %s\n", hdev->uniq);
 
 	name = hidpp_unifying_get_name(hidpp);
@@ -919,6 +918,54 @@
 print_version:
 	hid_info(hidpp->hid_dev, "HID++ %u.%u device connected.\n",
 		 hidpp->protocol_major, hidpp->protocol_minor);
+	return 0;
+}
+
+/* -------------------------------------------------------------------------- */
+/* 0x0003: Device Information                                                 */
+/* -------------------------------------------------------------------------- */
+
+#define HIDPP_PAGE_DEVICE_INFORMATION			0x0003
+
+#define CMD_GET_DEVICE_INFO				0x00
+
+static int hidpp_get_serial(struct hidpp_device *hidpp, u32 *serial)
+{
+	struct hidpp_report response;
+	u8 feature_type;
+	u8 feature_index;
+	int ret;
+
+	ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_DEVICE_INFORMATION,
+				     &feature_index,
+				     &feature_type);
+	if (ret)
+		return ret;
+
+	ret = hidpp_send_fap_command_sync(hidpp, feature_index,
+					  CMD_GET_DEVICE_INFO,
+					  NULL, 0, &response);
+	if (ret)
+		return ret;
+
+	/* See hidpp_unifying_get_serial() */
+	*serial = *((u32 *)&response.rap.params[1]);
+	return 0;
+}
+
+static int hidpp_serial_init(struct hidpp_device *hidpp)
+{
+	struct hid_device *hdev = hidpp->hid_dev;
+	u32 serial;
+	int ret;
+
+	ret = hidpp_get_serial(hidpp, &serial);
+	if (ret)
+		return ret;
+
+	snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial);
+	dbg_hid("HID++ DeviceInformation: Got serial: %s\n", hdev->uniq);
+
 	return 0;
 }
 
@@ -3763,6 +3810,7 @@
 	bool connected;
 	unsigned int connect_mask = HID_CONNECT_DEFAULT;
 	struct hidpp_ff_private_data data;
+	bool will_restart = false;
 
 	/* report_fixup needs drvdata to be set before we call hid_parse */
 	hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL);
@@ -3818,6 +3866,10 @@
 			return ret;
 	}
 
+	if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT ||
+	    hidpp->quirks & HIDPP_QUIRK_UNIFYING)
+		will_restart = true;
+
 	INIT_WORK(&hidpp->work, delayed_work_cb);
 	mutex_init(&hidpp->send_mutex);
 	init_waitqueue_head(&hidpp->wait);
@@ -3832,7 +3884,7 @@
 	 * Plain USB connections need to actually call start and open
 	 * on the transport driver to allow incoming data.
 	 */
-	ret = hid_hw_start(hdev, 0);
+	ret = hid_hw_start(hdev, will_restart ? 0 : connect_mask);
 	if (ret) {
 		hid_err(hdev, "hw start failed\n");
 		goto hid_hw_start_fail;
@@ -3850,6 +3902,8 @@
 
 	if (hidpp->quirks & HIDPP_QUIRK_UNIFYING)
 		hidpp_unifying_init(hidpp);
+	else if (hid_is_usb(hidpp->hid_dev))
+		hidpp_serial_init(hidpp);
 
 	connected = hidpp_root_get_protocol_version(hidpp) == 0;
 	atomic_set(&hidpp->connected, connected);
@@ -3869,6 +3923,7 @@
 			hidpp->wireless_feature_index = 0;
 		else if (ret)
 			goto hid_hw_init_fail;
+		ret = 0;
 	}
 
 	if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) {
@@ -3883,19 +3938,21 @@
 
 	hidpp_connect_event(hidpp);
 
-	/* Reset the HID node state */
-	hid_device_io_stop(hdev);
-	hid_hw_close(hdev);
-	hid_hw_stop(hdev);
+	if (will_restart) {
+		/* Reset the HID node state */
+		hid_device_io_stop(hdev);
+		hid_hw_close(hdev);
+		hid_hw_stop(hdev);
 
-	if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT)
-		connect_mask &= ~HID_CONNECT_HIDINPUT;
+		if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT)
+			connect_mask &= ~HID_CONNECT_HIDINPUT;
 
-	/* Now export the actual inputs and hidraw nodes to the world */
-	ret = hid_hw_start(hdev, connect_mask);
-	if (ret) {
-		hid_err(hdev, "%s:hid_hw_start returned error\n", __func__);
-		goto hid_hw_start_fail;
+		/* Now export the actual inputs and hidraw nodes to the world */
+		ret = hid_hw_start(hdev, connect_mask);
+		if (ret) {
+			hid_err(hdev, "%s:hid_hw_start returned error\n", __func__);
+			goto hid_hw_start_fail;
+		}
 	}
 
 	if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
@@ -3952,7 +4009,7 @@
 	{ /* wireless touchpad T651 */
 	  HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
 		USB_DEVICE_ID_LOGITECH_T651),
-	  .driver_data = HIDPP_QUIRK_CLASS_WTP },
+	  .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT },
 	{ /* Mouse Logitech Anywhere MX */
 	  LDJ_DEVICE(0x1017), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
 	{ /* Mouse Logitech Cube */
diff --git a/kernel/drivers/hid/hid-mcp2221.c b/kernel/drivers/hid/hid-mcp2221.c
index de52e9f..560eeec 100644
--- a/kernel/drivers/hid/hid-mcp2221.c
+++ b/kernel/drivers/hid/hid-mcp2221.c
@@ -840,11 +840,18 @@
 		return ret;
 	}
 
-	ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
+	/*
+	 * This driver uses the .raw_event callback and therefore does not need any
+	 * HID_CONNECT_xxx flags.
+	 */
+	ret = hid_hw_start(hdev, 0);
 	if (ret) {
 		hid_err(hdev, "can't start hardware\n");
 		return ret;
 	}
+
+	hid_info(hdev, "USB HID v%x.%02x Device [%s] on %s\n", hdev->version >> 8,
+			hdev->version & 0xff, hdev->name, hdev->phys);
 
 	ret = hid_hw_open(hdev);
 	if (ret) {
@@ -870,8 +877,7 @@
 	mcp->adapter.retries = 1;
 	mcp->adapter.dev.parent = &hdev->dev;
 	snprintf(mcp->adapter.name, sizeof(mcp->adapter.name),
-			"MCP2221 usb-i2c bridge on hidraw%d",
-			((struct hidraw *)hdev->hidraw)->minor);
+			"MCP2221 usb-i2c bridge");
 
 	ret = i2c_add_adapter(&mcp->adapter);
 	if (ret) {
diff --git a/kernel/drivers/hid/hid-multitouch.c b/kernel/drivers/hid/hid-multitouch.c
index a78ce16..dc7c33f 100644
--- a/kernel/drivers/hid/hid-multitouch.c
+++ b/kernel/drivers/hid/hid-multitouch.c
@@ -1541,7 +1541,6 @@
 static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
 {
 	struct mt_device *td = hid_get_drvdata(hdev);
-	char *name;
 	const char *suffix = NULL;
 	struct mt_report_data *rdata;
 	struct mt_application *mt_application = NULL;
@@ -1595,15 +1594,9 @@
 		break;
 	}
 
-	if (suffix) {
-		name = devm_kzalloc(&hi->input->dev,
-				    strlen(hdev->name) + strlen(suffix) + 2,
-				    GFP_KERNEL);
-		if (name) {
-			sprintf(name, "%s %s", hdev->name, suffix);
-			hi->input->name = name;
-		}
-	}
+	if (suffix)
+		hi->input->name = devm_kasprintf(&hdev->dev, GFP_KERNEL,
+						 "%s %s", hdev->name, suffix);
 
 	return 0;
 }
@@ -1912,6 +1905,10 @@
 		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
 			USB_VENDOR_ID_ELAN, 0x313a) },
 
+	{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
+		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+			USB_VENDOR_ID_ELAN, 0x3148) },
+
 	/* Elitegroup panel */
 	{ .driver_data = MT_CLS_SERIAL,
 		MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP,
diff --git a/kernel/drivers/hid/hid-plantronics.c b/kernel/drivers/hid/hid-plantronics.c
index e81b7ce..3d414ae 100644
--- a/kernel/drivers/hid/hid-plantronics.c
+++ b/kernel/drivers/hid/hid-plantronics.c
@@ -199,8 +199,17 @@
 
 static const struct hid_device_id plantronics_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+					 USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES),
+		.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
 					 USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES),
 		.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+					 USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES),
+		.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+					 USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES),
+		.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
 	{ }
 };
diff --git a/kernel/drivers/hid/hid-quirks.c b/kernel/drivers/hid/hid-quirks.c
index 1efde40..4229e5d 100644
--- a/kernel/drivers/hid/hid-quirks.c
+++ b/kernel/drivers/hid/hid-quirks.c
@@ -54,7 +54,6 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE), HID_QUIRK_NOGET },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS), HID_QUIRK_NOGET },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_MOUSE_000C), HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB), HID_QUIRK_NO_INIT_REPORTS },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB), HID_QUIRK_NO_INIT_REPORTS },
@@ -97,6 +96,7 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096), HID_QUIRK_NO_INIT_REPORTS },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293), HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A), HID_QUIRK_ALWAYS_POLL },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A), HID_QUIRK_MULTI_INPUT },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A), HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL },
diff --git a/kernel/drivers/hid/hid-sensor-custom.c b/kernel/drivers/hid/hid-sensor-custom.c
index 4d25577..971600a 100644
--- a/kernel/drivers/hid/hid-sensor-custom.c
+++ b/kernel/drivers/hid/hid-sensor-custom.c
@@ -59,7 +59,7 @@
 	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},
diff --git a/kernel/drivers/hid/intel-ish-hid/ishtp/dma-if.c b/kernel/drivers/hid/intel-ish-hid/ishtp/dma-if.c
index 40554c8..00046cb 100644
--- a/kernel/drivers/hid/intel-ish-hid/ishtp/dma-if.c
+++ b/kernel/drivers/hid/intel-ish-hid/ishtp/dma-if.c
@@ -104,6 +104,11 @@
 	int required_slots = (size / DMA_SLOT_SIZE)
 		+ 1 * (size % DMA_SLOT_SIZE != 0);
 
+	if (!dev->ishtp_dma_tx_map) {
+		dev_err(dev->devc, "Fail to allocate Tx map\n");
+		return NULL;
+	}
+
 	spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags);
 	for (i = 0; i <= (dev->ishtp_dma_num_slots - required_slots); i++) {
 		free = 1;
@@ -150,6 +155,11 @@
 		return;
 	}
 
+	if (!dev->ishtp_dma_tx_map) {
+		dev_err(dev->devc, "Fail to allocate Tx map\n");
+		return;
+	}
+
 	i = (msg_addr - dev->ishtp_host_dma_tx_buf) / DMA_SLOT_SIZE;
 	spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags);
 	for (j = 0; j < acked_slots; j++) {
diff --git a/kernel/drivers/hid/wacom.h b/kernel/drivers/hid/wacom.h
index 203d27d..c034a1e 100644
--- a/kernel/drivers/hid/wacom.h
+++ b/kernel/drivers/hid/wacom.h
@@ -91,6 +91,7 @@
 #include <linux/leds.h>
 #include <linux/usb/input.h>
 #include <linux/power_supply.h>
+#include <linux/timer.h>
 #include <asm/unaligned.h>
 
 /*
@@ -152,6 +153,7 @@
 		struct input_dev *input;
 		bool registered;
 		struct wacom_battery battery;
+		ktime_t active_time;
 	} remotes[WACOM_MAX_REMOTES];
 };
 
@@ -167,6 +169,7 @@
 	struct delayed_work init_work;
 	struct wacom_remote *remote;
 	struct work_struct mode_change_work;
+	struct timer_list idleprox_timer;
 	bool generic_has_leds;
 	struct wacom_leds {
 		struct wacom_group_leds *groups;
@@ -239,4 +242,5 @@
 struct wacom_led *wacom_led_next(struct wacom *wacom, struct wacom_led *cur);
 int wacom_equivalent_usage(int usage);
 int wacom_initialize_leds(struct wacom *wacom);
+void wacom_idleprox_timeout(struct timer_list *list);
 #endif
diff --git a/kernel/drivers/hid/wacom_sys.c b/kernel/drivers/hid/wacom_sys.c
index 4dbf690..1a7e1d3 100644
--- a/kernel/drivers/hid/wacom_sys.c
+++ b/kernel/drivers/hid/wacom_sys.c
@@ -160,6 +160,9 @@
 {
 	struct wacom *wacom = hid_get_drvdata(hdev);
 
+	if (wacom->wacom_wac.features.type == BOOTLOADER)
+		return 0;
+
 	if (size > WACOM_PKGLEN_MAX)
 		return 1;
 
@@ -2416,8 +2419,13 @@
 		goto fail_quirks;
 	}
 
-	if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR)
+	if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR) {
 		error = hid_hw_open(hdev);
+		if (error) {
+			hid_err(hdev, "hw open failed\n");
+			goto fail_quirks;
+		}
+	}
 
 	wacom_set_shared_values(wacom_wac);
 	devres_close_group(&hdev->dev, wacom);
@@ -2521,6 +2529,18 @@
 	return;
 }
 
+static void wacom_remote_destroy_battery(struct wacom *wacom, int index)
+{
+	struct wacom_remote *remote = wacom->remote;
+
+	if (remote->remotes[index].battery.battery) {
+		devres_release_group(&wacom->hdev->dev,
+				     &remote->remotes[index].battery.bat_desc);
+		remote->remotes[index].battery.battery = NULL;
+		remote->remotes[index].active_time = 0;
+	}
+}
+
 static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index)
 {
 	struct wacom_remote *remote = wacom->remote;
@@ -2535,9 +2555,7 @@
 			remote->remotes[i].registered = false;
 			spin_unlock_irqrestore(&remote->remote_lock, flags);
 
-			if (remote->remotes[i].battery.battery)
-				devres_release_group(&wacom->hdev->dev,
-						     &remote->remotes[i].battery.bat_desc);
+			wacom_remote_destroy_battery(wacom, i);
 
 			if (remote->remotes[i].group.name)
 				devres_release_group(&wacom->hdev->dev,
@@ -2545,7 +2563,6 @@
 
 			remote->remotes[i].serial = 0;
 			remote->remotes[i].group.name = NULL;
-			remote->remotes[i].battery.battery = NULL;
 			wacom->led.groups[i].select = WACOM_STATUS_UNKNOWN;
 		}
 	}
@@ -2630,6 +2647,9 @@
 	if (remote->remotes[index].battery.battery)
 		return 0;
 
+	if (!remote->remotes[index].active_time)
+		return 0;
+
 	if (wacom->led.groups[index].select == WACOM_STATUS_UNKNOWN)
 		return 0;
 
@@ -2645,6 +2665,7 @@
 {
 	struct wacom *wacom = container_of(work, struct wacom, remote_work);
 	struct wacom_remote *remote = wacom->remote;
+	ktime_t kt = ktime_get();
 	struct wacom_remote_data data;
 	unsigned long flags;
 	unsigned int count;
@@ -2670,6 +2691,10 @@
 	for (i = 0; i < WACOM_MAX_REMOTES; i++) {
 		serial = data.remote[i].serial;
 		if (data.remote[i].connected) {
+
+			if (kt - remote->remotes[i].active_time > WACOM_REMOTE_BATTERY_TIMEOUT
+			    && remote->remotes[i].active_time != 0)
+				wacom_remote_destroy_battery(wacom, i);
 
 			if (remote->remotes[i].serial == serial) {
 				wacom_remote_attach_battery(wacom, i);
@@ -2778,12 +2803,18 @@
 	INIT_WORK(&wacom->battery_work, wacom_battery_work);
 	INIT_WORK(&wacom->remote_work, wacom_remote_work);
 	INIT_WORK(&wacom->mode_change_work, wacom_mode_change_work);
+	timer_setup(&wacom->idleprox_timer, &wacom_idleprox_timeout, TIMER_DEFERRABLE);
 
 	/* ask for the report descriptor to be loaded by HID */
 	error = hid_parse(hdev);
 	if (error) {
 		hid_err(hdev, "parse failed\n");
 		return error;
+	}
+
+	if (features->type == BOOTLOADER) {
+		hid_warn(hdev, "Using device in hidraw-only mode");
+		return hid_hw_start(hdev, HID_CONNECT_HIDRAW);
 	}
 
 	error = wacom_parse_and_register(wacom, false);
@@ -2817,6 +2848,7 @@
 	cancel_work_sync(&wacom->battery_work);
 	cancel_work_sync(&wacom->remote_work);
 	cancel_work_sync(&wacom->mode_change_work);
+	del_timer_sync(&wacom->idleprox_timer);
 	if (hdev->bus == BUS_BLUETOOTH)
 		device_remove_file(&hdev->dev, &dev_attr_speed);
 
diff --git a/kernel/drivers/hid/wacom_wac.c b/kernel/drivers/hid/wacom_wac.c
index d8d127f..1b5e5e9 100644
--- a/kernel/drivers/hid/wacom_wac.c
+++ b/kernel/drivers/hid/wacom_wac.c
@@ -11,6 +11,7 @@
 #include "wacom_wac.h"
 #include "wacom.h"
 #include <linux/input/mt.h>
+#include <linux/jiffies.h>
 
 /* resolution for penabled devices */
 #define WACOM_PL_RES		20
@@ -41,6 +42,43 @@
 
 static void wacom_update_led(struct wacom *wacom, int button_count, int mask,
 			     int group);
+
+static void wacom_force_proxout(struct wacom_wac *wacom_wac)
+{
+	struct input_dev *input = wacom_wac->pen_input;
+
+	wacom_wac->shared->stylus_in_proximity = 0;
+
+	input_report_key(input, BTN_TOUCH, 0);
+	input_report_key(input, BTN_STYLUS, 0);
+	input_report_key(input, BTN_STYLUS2, 0);
+	input_report_key(input, BTN_STYLUS3, 0);
+	input_report_key(input, wacom_wac->tool[0], 0);
+	if (wacom_wac->serial[0]) {
+		input_report_abs(input, ABS_MISC, 0);
+	}
+	input_report_abs(input, ABS_PRESSURE, 0);
+
+	wacom_wac->tool[0] = 0;
+	wacom_wac->id[0] = 0;
+	wacom_wac->serial[0] = 0;
+
+	input_sync(input);
+}
+
+void wacom_idleprox_timeout(struct timer_list *list)
+{
+	struct wacom *wacom = from_timer(wacom, list, idleprox_timer);
+	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+
+	if (!wacom_wac->hid_data.sense_state) {
+		return;
+	}
+
+	hid_warn(wacom->hdev, "%s: tool appears to be hung in-prox. forcing it out.\n", __func__);
+	wacom_force_proxout(wacom_wac);
+}
+
 /*
  * Percent of battery capacity for Graphire.
  * 8th value means AC online and show 100% capacity.
@@ -675,11 +713,14 @@
 	case 0x802: /* Intuos4/5 13HD/24HD General Pen */
 	case 0x8e2: /* IntuosHT2 pen */
 	case 0x022:
+	case 0x200: /* Pro Pen 3 */
+	case 0x04200: /* Pro Pen 3 */
 	case 0x10842: /* MobileStudio Pro Pro Pen slim */
 	case 0x14802: /* Intuos4/5 13HD/24HD Classic Pen */
 	case 0x16802: /* Cintiq 13HD Pro Pen */
 	case 0x18802: /* DTH2242 Pen */
 	case 0x10802: /* Intuos4/5 13HD/24HD General Pen */
+	case 0x80842: /* Intuos Pro and Cintiq Pro 3D Pen */
 		tool_type = BTN_TOOL_PEN;
 		break;
 
@@ -790,7 +831,7 @@
 	/* Enter report */
 	if ((data[1] & 0xfc) == 0xc0) {
 		/* serial number of the tool */
-		wacom->serial[idx] = ((data[3] & 0x0f) << 28) +
+		wacom->serial[idx] = ((__u64)(data[3] & 0x0f) << 28) +
 			(data[4] << 20) + (data[5] << 12) +
 			(data[6] << 4) + (data[7] >> 4);
 
@@ -1086,6 +1127,7 @@
 	if (index < 0 || !remote->remotes[index].registered)
 		goto out;
 
+	remote->remotes[i].active_time = ktime_get();
 	input = remote->remotes[index].input;
 
 	input_report_key(input, BTN_0, (data[9] & 0x01));
@@ -1265,6 +1307,9 @@
 
 	struct input_dev *pen_input = wacom->pen_input;
 	unsigned char *data = wacom->data;
+	int number_of_valid_frames = 0;
+	ktime_t time_interval = 15000000;
+	ktime_t time_packet_received = ktime_get();
 	int i;
 
 	if (wacom->features.type == INTUOSP2_BT ||
@@ -1285,12 +1330,30 @@
 		wacom->id[0] |= (wacom->serial[0] >> 32) & 0xFFFFF;
 	}
 
+	/* number of valid frames */
 	for (i = 0; i < pen_frames; i++) {
+		unsigned char *frame = &data[i*pen_frame_len + 1];
+		bool valid = frame[0] & 0x80;
+
+		if (valid)
+			number_of_valid_frames++;
+	}
+
+	if (number_of_valid_frames) {
+		if (wacom->hid_data.time_delayed)
+			time_interval = ktime_get() - wacom->hid_data.time_delayed;
+		time_interval = div_u64(time_interval, number_of_valid_frames);
+		wacom->hid_data.time_delayed = time_packet_received;
+	}
+
+	for (i = 0; i < number_of_valid_frames; i++) {
 		unsigned char *frame = &data[i*pen_frame_len + 1];
 		bool valid = frame[0] & 0x80;
 		bool prox = frame[0] & 0x40;
 		bool range = frame[0] & 0x20;
 		bool invert = frame[0] & 0x10;
+		int frames_number_reversed = number_of_valid_frames - i - 1;
+		ktime_t event_timestamp = time_packet_received - frames_number_reversed * time_interval;
 
 		if (!valid)
 			continue;
@@ -1303,6 +1366,7 @@
 			wacom->tool[0] = 0;
 			wacom->id[0] = 0;
 			wacom->serial[0] = 0;
+			wacom->hid_data.time_delayed = 0;
 			return;
 		}
 
@@ -1339,6 +1403,7 @@
 						 get_unaligned_le16(&frame[11]));
 			}
 		}
+
 		if (wacom->tool[0]) {
 			input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5]));
 			if (wacom->features.type == INTUOSP2_BT ||
@@ -1361,6 +1426,9 @@
 		}
 
 		wacom->shared->stylus_in_proximity = prox;
+
+		/* add timestamp to unpack the frames */
+		input_set_timestamp(pen_input, event_timestamp);
 
 		input_sync(pen_input);
 	}
@@ -1853,6 +1921,7 @@
 	int fmax = field->logical_maximum;
 	unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
 	int resolution_code = code;
+	int resolution = hidinput_calc_abs_res(field, resolution_code);
 
 	if (equivalent_usage == HID_DG_TWIST) {
 		resolution_code = ABS_RZ;
@@ -1875,8 +1944,15 @@
 	switch (type) {
 	case EV_ABS:
 		input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
-		input_abs_set_res(input, code,
-				  hidinput_calc_abs_res(field, resolution_code));
+
+		/* older tablet may miss physical usage */
+		if ((code == ABS_X || code == ABS_Y) && !resolution) {
+			resolution = WACOM_INTUOS_RES;
+			hid_warn(input,
+				 "Wacom usage (%d) missing resolution \n",
+				 code);
+		}
+		input_abs_set_res(input, code, resolution);
 		break;
 	case EV_KEY:
 		input_set_capability(input, EV_KEY, code);
@@ -1893,18 +1969,7 @@
 static void wacom_wac_battery_usage_mapping(struct hid_device *hdev,
 		struct hid_field *field, struct hid_usage *usage)
 {
-	struct wacom *wacom = hid_get_drvdata(hdev);
-	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
-	struct wacom_features *features = &wacom_wac->features;
-	unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
-
-	switch (equivalent_usage) {
-	case HID_DG_BATTERYSTRENGTH:
-	case WACOM_HID_WD_BATTERY_LEVEL:
-	case WACOM_HID_WD_BATTERY_CHARGING:
-		features->quirks |= WACOM_QUIRK_BATTERY;
-		break;
-	}
+	return;
 }
 
 static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *field,
@@ -1925,18 +1990,21 @@
 			wacom_wac->hid_data.bat_connected = 1;
 			wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;
 		}
+		wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;
 		break;
 	case WACOM_HID_WD_BATTERY_LEVEL:
 		value = value * 100 / (field->logical_maximum - field->logical_minimum);
 		wacom_wac->hid_data.battery_capacity = value;
 		wacom_wac->hid_data.bat_connected = 1;
 		wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;
+		wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;
 		break;
 	case WACOM_HID_WD_BATTERY_CHARGING:
 		wacom_wac->hid_data.bat_charging = value;
 		wacom_wac->hid_data.ps_connected = value;
 		wacom_wac->hid_data.bat_connected = 1;
 		wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;
+		wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;
 		break;
 	}
 }
@@ -1952,18 +2020,15 @@
 {
 	struct wacom *wacom = hid_get_drvdata(hdev);
 	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
-	struct wacom_features *features = &wacom_wac->features;
 
-	if (features->quirks & WACOM_QUIRK_BATTERY) {
-		int status = wacom_wac->hid_data.bat_status;
-		int capacity = wacom_wac->hid_data.battery_capacity;
-		bool charging = wacom_wac->hid_data.bat_charging;
-		bool connected = wacom_wac->hid_data.bat_connected;
-		bool powered = wacom_wac->hid_data.ps_connected;
+	int status = wacom_wac->hid_data.bat_status;
+	int capacity = wacom_wac->hid_data.battery_capacity;
+	bool charging = wacom_wac->hid_data.bat_charging;
+	bool connected = wacom_wac->hid_data.bat_connected;
+	bool powered = wacom_wac->hid_data.ps_connected;
 
-		wacom_notify_battery(wacom_wac, status, capacity, charging,
-				     connected, powered);
-	}
+	wacom_notify_battery(wacom_wac, status, capacity, charging,
+			     connected, powered);
 }
 
 static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
@@ -2305,6 +2370,7 @@
 		value = field->logical_maximum - value;
 		break;
 	case HID_DG_INRANGE:
+		mod_timer(&wacom->idleprox_timer, jiffies + msecs_to_jiffies(100));
 		wacom_wac->hid_data.inrange_state = value;
 		if (!(features->quirks & WACOM_QUIRK_SENSE))
 			wacom_wac->hid_data.sense_state = value;
@@ -4778,9 +4844,16 @@
 static const struct wacom_features wacom_features_0x3c8 =
 	{ "Wacom Intuos BT M", 21600, 13500, 4095, 63,
 	  INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 };
+static const struct wacom_features wacom_features_0x3dd =
+	{ "Wacom Intuos Pro S", 31920, 19950, 8191, 63,
+	  INTUOSP2S_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7,
+	  .touch_max = 10 };
 
 static const struct wacom_features wacom_features_HID_ANY_ID =
 	{ "Wacom HID", .type = HID_GENERIC, .oVid = HID_ANY_ID, .oPid = HID_ANY_ID };
+
+static const struct wacom_features wacom_features_0x94 =
+	{ "Wacom Bootloader", .type = BOOTLOADER };
 
 #define USB_DEVICE_WACOM(prod)						\
 	HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
@@ -4855,6 +4928,7 @@
 	{ USB_DEVICE_WACOM(0x84) },
 	{ USB_DEVICE_WACOM(0x90) },
 	{ USB_DEVICE_WACOM(0x93) },
+	{ USB_DEVICE_WACOM(0x94) },
 	{ USB_DEVICE_WACOM(0x97) },
 	{ USB_DEVICE_WACOM(0x9A) },
 	{ USB_DEVICE_WACOM(0x9F) },
@@ -4953,6 +5027,7 @@
 	{ BT_DEVICE_WACOM(0x393) },
 	{ BT_DEVICE_WACOM(0x3c6) },
 	{ BT_DEVICE_WACOM(0x3c8) },
+	{ BT_DEVICE_WACOM(0x3dd) },
 	{ USB_DEVICE_WACOM(0x4001) },
 	{ USB_DEVICE_WACOM(0x4004) },
 	{ USB_DEVICE_WACOM(0x5000) },
diff --git a/kernel/drivers/hid/wacom_wac.h b/kernel/drivers/hid/wacom_wac.h
index 8dea7cb..d393f96 100644
--- a/kernel/drivers/hid/wacom_wac.h
+++ b/kernel/drivers/hid/wacom_wac.h
@@ -15,6 +15,7 @@
 #define WACOM_NAME_MAX		64
 #define WACOM_MAX_REMOTES	5
 #define WACOM_STATUS_UNKNOWN	255
+#define WACOM_REMOTE_BATTERY_TIMEOUT	21000000000ll
 
 /* packet length for individual models */
 #define WACOM_PKGLEN_BBFUN	 9
@@ -242,6 +243,7 @@
 	MTTPC,
 	MTTPC_B,
 	HID_GENERIC,
+	BOOTLOADER,
 	MAX_TYPE
 };
 
@@ -319,6 +321,7 @@
 	int bat_connected;
 	int ps_connected;
 	bool pad_input_event_flag;
+	ktime_t time_delayed;
 };
 
 struct wacom_remote_data {
diff --git a/kernel/drivers/hsi/controllers/omap_ssi_core.c b/kernel/drivers/hsi/controllers/omap_ssi_core.c
index eb98201..26f2c3c 100644
--- a/kernel/drivers/hsi/controllers/omap_ssi_core.c
+++ b/kernel/drivers/hsi/controllers/omap_ssi_core.c
@@ -502,8 +502,10 @@
 	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);
 
@@ -536,9 +538,9 @@
 	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;
 }
@@ -629,7 +631,13 @@
 	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);
 
diff --git a/kernel/drivers/hv/channel_mgmt.c b/kernel/drivers/hv/channel_mgmt.c
index 5b902ad..0c6c540 100644
--- a/kernel/drivers/hv/channel_mgmt.c
+++ b/kernel/drivers/hv/channel_mgmt.c
@@ -765,11 +765,22 @@
 		if (completion_done(&vmbus_connection.unload_event))
 			goto completed;
 
-		for_each_online_cpu(cpu) {
+		for_each_present_cpu(cpu) {
 			struct hv_per_cpu_context *hv_cpu
 				= per_cpu_ptr(hv_context.cpu_context, cpu);
 
+			/*
+			 * In a CoCo VM the synic_message_page is not allocated
+			 * in hv_synic_alloc(). Instead it is set/cleared in
+			 * hv_synic_enable_regs() and hv_synic_disable_regs()
+			 * such that it is set only when the CPU is online. If
+			 * not all present CPUs are online, the message page
+			 * might be NULL, so skip such CPUs.
+			 */
 			page_addr = hv_cpu->synic_message_page;
+			if (!page_addr)
+				continue;
+
 			msg = (struct hv_message *)page_addr
 				+ VMBUS_MESSAGE_SINT;
 
@@ -803,11 +814,14 @@
 	 * maybe-pending messages on all CPUs to be able to receive new
 	 * messages after we reconnect.
 	 */
-	for_each_online_cpu(cpu) {
+	for_each_present_cpu(cpu) {
 		struct hv_per_cpu_context *hv_cpu
 			= per_cpu_ptr(hv_context.cpu_context, cpu);
 
 		page_addr = hv_cpu->synic_message_page;
+		if (!page_addr)
+			continue;
+
 		msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
 		msg->header.message_type = HVMSG_NONE;
 	}
diff --git a/kernel/drivers/hv/connection.c b/kernel/drivers/hv/connection.c
index bfd7f00..683fdfa 100644
--- a/kernel/drivers/hv/connection.c
+++ b/kernel/drivers/hv/connection.c
@@ -305,6 +305,10 @@
  */
 struct vmbus_channel *relid2channel(u32 relid)
 {
+	if (vmbus_connection.channels == NULL) {
+		pr_warn_once("relid2channel: relid=%d: No channels mapped!\n", relid);
+		return NULL;
+	}
 	if (WARN_ON(relid >= MAX_CHANNEL_RELIDS))
 		return NULL;
 	return READ_ONCE(vmbus_connection.channels[relid]);
diff --git a/kernel/drivers/hv/ring_buffer.c b/kernel/drivers/hv/ring_buffer.c
index 769851b..7ed6fad 100644
--- a/kernel/drivers/hv/ring_buffer.c
+++ b/kernel/drivers/hv/ring_buffer.c
@@ -246,6 +246,19 @@
 	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/kernel/drivers/hwmon/Kconfig b/kernel/drivers/hwmon/Kconfig
index f741c74..8a42746 100644
--- a/kernel/drivers/hwmon/Kconfig
+++ b/kernel/drivers/hwmon/Kconfig
@@ -766,6 +766,7 @@
 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/kernel/drivers/hwmon/adt7475.c b/kernel/drivers/hwmon/adt7475.c
index 9d5b019..22e3147 100644
--- a/kernel/drivers/hwmon/adt7475.c
+++ b/kernel/drivers/hwmon/adt7475.c
@@ -486,10 +486,10 @@
 		val = (temp - val) / 1000;
 
 		if (sattr->index != 1) {
-			data->temp[HYSTERSIS][sattr->index] &= 0xF0;
+			data->temp[HYSTERSIS][sattr->index] &= 0x0F;
 			data->temp[HYSTERSIS][sattr->index] |= (val & 0xF) << 4;
 		} else {
-			data->temp[HYSTERSIS][sattr->index] &= 0x0F;
+			data->temp[HYSTERSIS][sattr->index] &= 0xF0;
 			data->temp[HYSTERSIS][sattr->index] |= (val & 0xF);
 		}
 
@@ -554,11 +554,11 @@
 		val = data->enh_acoustics[0] & 0xf;
 		break;
 	case 1:
-		val = (data->enh_acoustics[1] >> 4) & 0xf;
+		val = data->enh_acoustics[1] & 0xf;
 		break;
 	case 2:
 	default:
-		val = data->enh_acoustics[1] & 0xf;
+		val = (data->enh_acoustics[1] >> 4) & 0xf;
 		break;
 	}
 
@@ -1515,9 +1515,9 @@
 	int ret, i;
 	u8 val;
 
-	ret = of_property_read_u32_array(client->dev.of_node,
-					 "adi,pwm-active-state", states,
-					 ARRAY_SIZE(states));
+	ret = device_property_read_u32_array(&client->dev,
+					     "adi,pwm-active-state", states,
+					     ARRAY_SIZE(states));
 	if (ret)
 		return ret;
 
diff --git a/kernel/drivers/hwmon/coretemp.c b/kernel/drivers/hwmon/coretemp.c
index 42b84eb..eaae5de 100644
--- a/kernel/drivers/hwmon/coretemp.c
+++ b/kernel/drivers/hwmon/coretemp.c
@@ -550,66 +550,49 @@
 		ida_free(&pdata->ida, indx - BASE_SYSFS_ATTR_NO);
 }
 
-static int coretemp_probe(struct platform_device *pdev)
+static int coretemp_device_add(int zoneid)
 {
-	struct device *dev = &pdev->dev;
+	struct platform_device *pdev;
 	struct platform_data *pdata;
+	int err;
 
 	/* Initialize the per-zone data structures */
-	pdata = devm_kzalloc(dev, sizeof(struct platform_data), GFP_KERNEL);
+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
 		return -ENOMEM;
 
-	pdata->pkg_id = pdev->id;
+	pdata->pkg_id = zoneid;
 	ida_init(&pdata->ida);
-	platform_set_drvdata(pdev, pdata);
-
-	pdata->hwmon_dev = devm_hwmon_device_register_with_groups(dev, DRVNAME,
-								  pdata, NULL);
-	return PTR_ERR_OR_ZERO(pdata->hwmon_dev);
-}
-
-static int coretemp_remove(struct platform_device *pdev)
-{
-	struct platform_data *pdata = platform_get_drvdata(pdev);
-	int i;
-
-	for (i = MAX_CORE_DATA - 1; i >= 0; --i)
-		if (pdata->core_data[i])
-			coretemp_remove_core(pdata, i);
-
-	ida_destroy(&pdata->ida);
-	return 0;
-}
-
-static struct platform_driver coretemp_driver = {
-	.driver = {
-		.name = DRVNAME,
-	},
-	.probe = coretemp_probe,
-	.remove = coretemp_remove,
-};
-
-static struct platform_device *coretemp_device_add(unsigned int cpu)
-{
-	int err, zoneid = topology_logical_die_id(cpu);
-	struct platform_device *pdev;
-
-	if (zoneid < 0)
-		return ERR_PTR(-ENOMEM);
 
 	pdev = platform_device_alloc(DRVNAME, zoneid);
-	if (!pdev)
-		return ERR_PTR(-ENOMEM);
-
-	err = platform_device_add(pdev);
-	if (err) {
-		platform_device_put(pdev);
-		return ERR_PTR(err);
+	if (!pdev) {
+		err = -ENOMEM;
+		goto err_free_pdata;
 	}
 
+	err = platform_device_add(pdev);
+	if (err)
+		goto err_put_dev;
+
+	platform_set_drvdata(pdev, pdata);
 	zone_devices[zoneid] = pdev;
-	return pdev;
+	return 0;
+
+err_put_dev:
+	platform_device_put(pdev);
+err_free_pdata:
+	kfree(pdata);
+	return err;
+}
+
+static void coretemp_device_remove(int zoneid)
+{
+	struct platform_device *pdev = zone_devices[zoneid];
+	struct platform_data *pdata = platform_get_drvdata(pdev);
+
+	ida_destroy(&pdata->ida);
+	kfree(pdata);
+	platform_device_unregister(pdev);
 }
 
 static int coretemp_cpu_online(unsigned int cpu)
@@ -633,7 +616,10 @@
 	if (!cpu_has(c, X86_FEATURE_DTHERM))
 		return -ENODEV;
 
-	if (!pdev) {
+	pdata = platform_get_drvdata(pdev);
+	if (!pdata->hwmon_dev) {
+		struct device *hwmon;
+
 		/* Check the microcode version of the CPU */
 		if (chk_ucode_version(cpu))
 			return -EINVAL;
@@ -644,9 +630,11 @@
 		 * online. So, initialize per-pkg data structures and
 		 * then bring this core online.
 		 */
-		pdev = coretemp_device_add(cpu);
-		if (IS_ERR(pdev))
-			return PTR_ERR(pdev);
+		hwmon = hwmon_device_register_with_groups(&pdev->dev, DRVNAME,
+							  pdata, NULL);
+		if (IS_ERR(hwmon))
+			return PTR_ERR(hwmon);
+		pdata->hwmon_dev = hwmon;
 
 		/*
 		 * Check whether pkgtemp support is available.
@@ -656,7 +644,6 @@
 			coretemp_add_core(pdev, cpu, 1);
 	}
 
-	pdata = platform_get_drvdata(pdev);
 	/*
 	 * Check whether a thread sibling is already online. If not add the
 	 * interface for this CPU core.
@@ -675,18 +662,14 @@
 	struct temp_data *tdata;
 	int i, indx = -1, target;
 
-	/*
-	 * Don't execute this on suspend as the device remove locks
-	 * up the machine.
-	 */
+	/* No need to tear down any interfaces for suspend */
 	if (cpuhp_tasks_frozen)
 		return 0;
 
 	/* If the physical CPU device does not exist, just return */
-	if (!pdev)
-		return 0;
-
 	pd = platform_get_drvdata(pdev);
+	if (!pd->hwmon_dev)
+		return 0;
 
 	for (i = 0; i < NUM_REAL_CORES; i++) {
 		if (pd->cpu_map[i] == topology_core_id(cpu)) {
@@ -718,13 +701,14 @@
 	}
 
 	/*
-	 * If all cores in this pkg are offline, remove the device. This
-	 * will invoke the platform driver remove function, which cleans up
-	 * the rest.
+	 * If all cores in this pkg are offline, remove the interface.
 	 */
+	tdata = pd->core_data[PKG_SYSFS_ATTR_NO];
 	if (cpumask_empty(&pd->cpumask)) {
-		zone_devices[topology_logical_die_id(cpu)] = NULL;
-		platform_device_unregister(pdev);
+		if (tdata)
+			coretemp_remove_core(pd, PKG_SYSFS_ATTR_NO);
+		hwmon_device_unregister(pd->hwmon_dev);
+		pd->hwmon_dev = NULL;
 		return 0;
 	}
 
@@ -732,7 +716,6 @@
 	 * Check whether this core is the target for the package
 	 * interface. We need to assign it to some other cpu.
 	 */
-	tdata = pd->core_data[PKG_SYSFS_ATTR_NO];
 	if (tdata && tdata->cpu == cpu) {
 		target = cpumask_first(&pd->cpumask);
 		mutex_lock(&tdata->update_lock);
@@ -751,7 +734,7 @@
 
 static int __init coretemp_init(void)
 {
-	int err;
+	int i, err;
 
 	/*
 	 * CPUID.06H.EAX[0] indicates whether the CPU has thermal
@@ -767,20 +750,22 @@
 	if (!zone_devices)
 		return -ENOMEM;
 
-	err = platform_driver_register(&coretemp_driver);
-	if (err)
-		goto outzone;
+	for (i = 0; i < max_zones; i++) {
+		err = coretemp_device_add(i);
+		if (err)
+			goto outzone;
+	}
 
 	err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/coretemp:online",
 				coretemp_cpu_online, coretemp_cpu_offline);
 	if (err < 0)
-		goto outdrv;
+		goto outzone;
 	coretemp_hp_online = err;
 	return 0;
 
-outdrv:
-	platform_driver_unregister(&coretemp_driver);
 outzone:
+	while (i--)
+		coretemp_device_remove(i);
 	kfree(zone_devices);
 	return err;
 }
@@ -788,8 +773,11 @@
 
 static void __exit coretemp_exit(void)
 {
+	int i;
+
 	cpuhp_remove_state(coretemp_hp_online);
-	platform_driver_unregister(&coretemp_driver);
+	for (i = 0; i < max_zones; i++)
+		coretemp_device_remove(i);
 	kfree(zone_devices);
 }
 module_exit(coretemp_exit)
diff --git a/kernel/drivers/hwmon/gsc-hwmon.c b/kernel/drivers/hwmon/gsc-hwmon.c
index f29ce49..89d036b 100644
--- a/kernel/drivers/hwmon/gsc-hwmon.c
+++ b/kernel/drivers/hwmon/gsc-hwmon.c
@@ -82,8 +82,8 @@
 	if (kstrtol(buf, 10, &temp))
 		return -EINVAL;
 
-	temp = clamp_val(temp, 0, 10000);
-	temp = DIV_ROUND_CLOSEST(temp, 10);
+	temp = clamp_val(temp, 0, 100000);
+	temp = DIV_ROUND_CLOSEST(temp, 100);
 
 	regs[0] = temp & 0xff;
 	regs[1] = (temp >> 8) & 0xff;
@@ -100,7 +100,7 @@
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 
-	return sprintf(buf, "%d\n", 255 * (50 + (attr->index * 10)) / 100);
+	return sprintf(buf, "%d\n", 255 * (50 + (attr->index * 10)));
 }
 
 static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point1_pwm, pwm_auto_point_pwm, 0);
diff --git a/kernel/drivers/hwmon/hwmon.c b/kernel/drivers/hwmon/hwmon.c
index d649fea..045dc3f 100644
--- a/kernel/drivers/hwmon/hwmon.c
+++ b/kernel/drivers/hwmon/hwmon.c
@@ -700,6 +700,7 @@
 {
 	struct hwmon_device *hwdev;
 	struct device *hdev;
+	struct device *tdev = dev;
 	int i, err, id;
 
 	/* Complain about invalid characters in hwmon name attribute */
@@ -757,7 +758,9 @@
 	hwdev->name = name;
 	hdev->class = &hwmon_class;
 	hdev->parent = dev;
-	hdev->of_node = dev ? dev->of_node : NULL;
+	while (tdev && !tdev->of_node)
+		tdev = tdev->parent;
+	hdev->of_node = tdev ? tdev->of_node : NULL;
 	hwdev->chip = chip;
 	dev_set_drvdata(hdev, drvdata);
 	dev_set_name(hdev, HWMON_ID_FORMAT, id);
@@ -769,7 +772,7 @@
 
 	INIT_LIST_HEAD(&hwdev->tzdata);
 
-	if (dev && dev->of_node && chip && chip->ops->read &&
+	if (hdev->of_node && chip && chip->ops->read &&
 	    chip->info[0]->type == hwmon_chip &&
 	    (chip->info[0]->config[0] & HWMON_C_REGISTER_TZ)) {
 		err = hwmon_thermal_register_sensors(hdev);
diff --git a/kernel/drivers/hwmon/ina3221.c b/kernel/drivers/hwmon/ina3221.c
index d3c9811..836e757 100644
--- a/kernel/drivers/hwmon/ina3221.c
+++ b/kernel/drivers/hwmon/ina3221.c
@@ -772,7 +772,7 @@
 		return ret;
 	} else if (val > INA3221_CHANNEL3) {
 		dev_err(dev, "invalid reg %d of %pOFn\n", val, child);
-		return ret;
+		return -EINVAL;
 	}
 
 	input = &ina->inputs[val];
diff --git a/kernel/drivers/hwmon/it87.c b/kernel/drivers/hwmon/it87.c
index fac9b5c..85413d3 100644
--- a/kernel/drivers/hwmon/it87.c
+++ b/kernel/drivers/hwmon/it87.c
@@ -486,6 +486,8 @@
 #define has_pwm_freq2(data)	((data)->features & FEAT_PWM_FREQ2)
 #define has_six_temp(data)	((data)->features & FEAT_SIX_TEMP)
 #define has_vin3_5v(data)	((data)->features & FEAT_VIN3_5V)
+#define has_scaling(data)	((data)->features & (FEAT_12MV_ADC | \
+						     FEAT_10_9MV_ADC))
 
 struct it87_sio_data {
 	int sioaddr;
@@ -3098,7 +3100,7 @@
 			 "Detected broken BIOS defaults, disabling PWM interface\n");
 
 	/* Starting with IT8721F, we handle scaling of internal voltages */
-	if (has_12mv_adc(data)) {
+	if (has_scaling(data)) {
 		if (sio_data->internal & BIT(0))
 			data->in_scaled |= BIT(3);	/* in3 is AVCC */
 		if (sio_data->internal & BIT(1))
diff --git a/kernel/drivers/hwmon/jc42.c b/kernel/drivers/hwmon/jc42.c
index 4a03d01..52f341d 100644
--- a/kernel/drivers/hwmon/jc42.c
+++ b/kernel/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 @@
 	{ 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 @@
 	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 @@
 
 	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)
+			break;
+
 		/*
 		 * JC42.4 compliant chips only support four hysteresis values.
 		 * Pick best choice and go from there.
@@ -346,7 +349,7 @@
 		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 @@
 		}
 		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 @@
 	.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 @@
 
 		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,11 @@
 	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);
+
+	regcache_cache_only(data->regmap, true);
+	regcache_mark_dirty(data->regmap);
+
 	return 0;
 }
 
@@ -544,10 +578,13 @@
 {
 	struct jc42_data *data = dev_get_drvdata(dev);
 
+	regcache_cache_only(data->regmap, false);
+
 	data->config &= ~JC42_CFG_SHUTDOWN;
-	i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG,
-				     data->config);
-	return 0;
+	regmap_write(data->regmap, JC42_REG_CONFIG, data->config);
+
+	/* Restore cached register values to hardware */
+	return regcache_sync(data->regmap);
 }
 
 static const struct dev_pm_ops jc42_dev_pm_ops = {
diff --git a/kernel/drivers/hwmon/k10temp.c b/kernel/drivers/hwmon/k10temp.c
index 3bc2551..74a6708 100644
--- a/kernel/drivers/hwmon/k10temp.c
+++ b/kernel/drivers/hwmon/k10temp.c
@@ -74,6 +74,7 @@
 
 #define ZEN_CUR_TEMP_SHIFT			21
 #define ZEN_CUR_TEMP_RANGE_SEL_MASK		BIT(19)
+#define ZEN_CUR_TEMP_TJ_SEL_MASK		GENMASK(17, 16)
 
 #define ZEN_SVI_BASE				0x0005A000
 
@@ -173,7 +174,8 @@
 
 	data->read_tempreg(data->pdev, &regval);
 	temp = (regval >> ZEN_CUR_TEMP_SHIFT) * 125;
-	if (regval & data->temp_adjust_mask)
+	if ((regval & data->temp_adjust_mask) ||
+	    (regval & ZEN_CUR_TEMP_TJ_SEL_MASK) == ZEN_CUR_TEMP_TJ_SEL_MASK)
 		temp -= 49000;
 	return temp;
 }
diff --git a/kernel/drivers/hwmon/ltc2945.c b/kernel/drivers/hwmon/ltc2945.c
index ba9c868..65d792f 100644
--- a/kernel/drivers/hwmon/ltc2945.c
+++ b/kernel/drivers/hwmon/ltc2945.c
@@ -248,6 +248,8 @@
 
 	/* convert to register value, then clamp and write result */
 	regval = ltc2945_val_to_reg(dev, reg, val);
+	if (regval < 0)
+		return regval;
 	if (is_power_reg(reg)) {
 		regval = clamp_val(regval, 0, 0xffffff);
 		regbuf[0] = regval >> 16;
diff --git a/kernel/drivers/hwmon/mlxreg-fan.c b/kernel/drivers/hwmon/mlxreg-fan.c
index bd8f5a3..052c897 100644
--- a/kernel/drivers/hwmon/mlxreg-fan.c
+++ b/kernel/drivers/hwmon/mlxreg-fan.c
@@ -127,6 +127,12 @@
 			if (err)
 				return err;
 
+			if (MLXREG_FAN_GET_FAULT(regval, tacho->mask)) {
+				/* FAN is broken - return zero for FAN speed. */
+				*val = 0;
+				return 0;
+			}
+
 			*val = MLXREG_FAN_GET_RPM(regval, fan->divider,
 						  fan->samples);
 			break;
diff --git a/kernel/drivers/hwmon/nct7802.c b/kernel/drivers/hwmon/nct7802.c
index 604af2f..88eddb8 100644
--- a/kernel/drivers/hwmon/nct7802.c
+++ b/kernel/drivers/hwmon/nct7802.c
@@ -708,7 +708,7 @@
 	if (index >= 38 && index < 46 && !(reg & 0x01))		/* PECI 0 */
 		return 0;
 
-	if (index >= 0x46 && (!(reg & 0x02)))			/* PECI 1 */
+	if (index >= 46 && !(reg & 0x02))			/* PECI 1 */
 		return 0;
 
 	return attr->mode;
diff --git a/kernel/drivers/hwmon/pmbus/adm1266.c b/kernel/drivers/hwmon/pmbus/adm1266.c
index c7b373b..d1b2e93 100644
--- a/kernel/drivers/hwmon/pmbus/adm1266.c
+++ b/kernel/drivers/hwmon/pmbus/adm1266.c
@@ -301,6 +301,7 @@
 	data->gc.label = name;
 	data->gc.parent = &data->client->dev;
 	data->gc.owner = THIS_MODULE;
+	data->gc.can_sleep = true;
 	data->gc.base = -1;
 	data->gc.names = data->gpio_names;
 	data->gc.ngpio = ARRAY_SIZE(data->gpio_names);
diff --git a/kernel/drivers/hwmon/pmbus/adm1275.c b/kernel/drivers/hwmon/pmbus/adm1275.c
index e7997f3..c061820 100644
--- a/kernel/drivers/hwmon/pmbus/adm1275.c
+++ b/kernel/drivers/hwmon/pmbus/adm1275.c
@@ -37,9 +37,12 @@
 
 #define ADM1272_IRANGE			BIT(0)
 
+#define ADM1278_TSFILT			BIT(15)
 #define ADM1278_TEMP1_EN		BIT(3)
 #define ADM1278_VIN_EN			BIT(2)
 #define ADM1278_VOUT_EN			BIT(1)
+
+#define ADM1278_PMON_DEFCONFIG		(ADM1278_VOUT_EN | ADM1278_TEMP1_EN | ADM1278_TSFILT)
 
 #define ADM1293_IRANGE_25		0
 #define ADM1293_IRANGE_50		BIT(6)
@@ -462,6 +465,22 @@
 };
 MODULE_DEVICE_TABLE(i2c, adm1275_id);
 
+/* Enable VOUT & TEMP1 if not enabled (disabled by default) */
+static int adm1275_enable_vout_temp(struct i2c_client *client, int config)
+{
+	int ret;
+
+	if ((config & ADM1278_PMON_DEFCONFIG) != ADM1278_PMON_DEFCONFIG) {
+		config |= ADM1278_PMON_DEFCONFIG;
+		ret = i2c_smbus_write_word_data(client, ADM1275_PMON_CONFIG, config);
+		if (ret < 0) {
+			dev_err(&client->dev, "Failed to enable VOUT/TEMP1 monitoring\n");
+			return ret;
+		}
+	}
+	return 0;
+}
+
 static int adm1275_probe(struct i2c_client *client)
 {
 	s32 (*config_read_fn)(const struct i2c_client *client, u8 reg);
@@ -475,6 +494,7 @@
 	int vindex = -1, voindex = -1, cindex = -1, pindex = -1;
 	int tindex = -1;
 	u32 shunt;
+	u32 avg;
 
 	if (!i2c_check_functionality(client->adapter,
 				     I2C_FUNC_SMBUS_READ_BYTE_DATA
@@ -611,24 +631,13 @@
 		tindex = 8;
 
 		info->func[0] |= PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT |
-			PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
+			PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
+			PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
 
-		/* Enable VOUT if not enabled (it is disabled by default) */
-		if (!(config & ADM1278_VOUT_EN)) {
-			config |= ADM1278_VOUT_EN;
-			ret = i2c_smbus_write_byte_data(client,
-							ADM1275_PMON_CONFIG,
-							config);
-			if (ret < 0) {
-				dev_err(&client->dev,
-					"Failed to enable VOUT monitoring\n");
-				return -ENODEV;
-			}
-		}
+		ret = adm1275_enable_vout_temp(client, config);
+		if (ret)
+			return ret;
 
-		if (config & ADM1278_TEMP1_EN)
-			info->func[0] |=
-				PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
 		if (config & ADM1278_VIN_EN)
 			info->func[0] |= PMBUS_HAVE_VIN;
 		break;
@@ -685,19 +694,9 @@
 			PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
 			PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
 
-		/* Enable VOUT & TEMP1 if not enabled (disabled by default) */
-		if ((config & (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) !=
-		    (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) {
-			config |= ADM1278_VOUT_EN | ADM1278_TEMP1_EN;
-			ret = i2c_smbus_write_byte_data(client,
-							ADM1275_PMON_CONFIG,
-							config);
-			if (ret < 0) {
-				dev_err(&client->dev,
-					"Failed to enable VOUT monitoring\n");
-				return -ENODEV;
-			}
-		}
+		ret = adm1275_enable_vout_temp(client, config);
+		if (ret)
+			return ret;
 
 		if (config & ADM1278_VIN_EN)
 			info->func[0] |= PMBUS_HAVE_VIN;
@@ -758,6 +757,43 @@
 		return -ENODEV;
 	}
 
+	if (data->have_power_sampling &&
+	    of_property_read_u32(client->dev.of_node,
+				 "adi,power-sample-average", &avg) == 0) {
+		if (!avg || avg > ADM1275_SAMPLES_AVG_MAX ||
+		    BIT(__fls(avg)) != avg) {
+			dev_err(&client->dev,
+				"Invalid number of power samples");
+			return -EINVAL;
+		}
+		ret = adm1275_write_pmon_config(data, client, true,
+						ilog2(avg));
+		if (ret < 0) {
+			dev_err(&client->dev,
+				"Setting power sample averaging failed with error %d",
+				ret);
+			return ret;
+		}
+	}
+
+	if (of_property_read_u32(client->dev.of_node,
+				"adi,volt-curr-sample-average", &avg) == 0) {
+		if (!avg || avg > ADM1275_SAMPLES_AVG_MAX ||
+		    BIT(__fls(avg)) != avg) {
+			dev_err(&client->dev,
+				"Invalid number of voltage/current samples");
+			return -EINVAL;
+		}
+		ret = adm1275_write_pmon_config(data, client, false,
+						ilog2(avg));
+		if (ret < 0) {
+			dev_err(&client->dev,
+				"Setting voltage and current sample averaging failed with error %d",
+				ret);
+			return ret;
+		}
+	}
+
 	if (voindex < 0)
 		voindex = vindex;
 	if (vindex >= 0) {
diff --git a/kernel/drivers/hwmon/pmbus/bel-pfe.c b/kernel/drivers/hwmon/pmbus/bel-pfe.c
index 2c5b853..fc3d9a9 100644
--- a/kernel/drivers/hwmon/pmbus/bel-pfe.c
+++ b/kernel/drivers/hwmon/pmbus/bel-pfe.c
@@ -17,12 +17,13 @@
 enum chips {pfe1100, pfe3000};
 
 /*
- * Disable status check for pfe3000 devices, because some devices report
- * communication error (invalid command) for VOUT_MODE command (0x20)
- * although correct VOUT_MODE (0x16) is returned: it leads to incorrect
- * exponent in linear mode.
+ * Disable status check because some devices report communication error
+ * (invalid command) for VOUT_MODE command (0x20) although the correct
+ * VOUT_MODE (0x16) is returned: it leads to incorrect exponent in linear
+ * mode.
+ * This affects both pfe3000 and pfe1100.
  */
-static struct pmbus_platform_data pfe3000_plat_data = {
+static struct pmbus_platform_data pfe_plat_data = {
 	.flags = PMBUS_SKIP_STATUS_CHECK,
 };
 
@@ -94,16 +95,15 @@
 	int model;
 
 	model = (int)i2c_match_id(pfe_device_id, client)->driver_data;
+	client->dev.platform_data = &pfe_plat_data;
 
 	/*
 	 * PFE3000-12-069RA devices may not stay in page 0 during device
 	 * probe which leads to probe failure (read status word failed).
 	 * So let's set the device to page 0 at the beginning.
 	 */
-	if (model == pfe3000) {
-		client->dev.platform_data = &pfe3000_plat_data;
+	if (model == pfe3000)
 		i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
-	}
 
 	return pmbus_do_probe(client, &pfe_driver_info[model]);
 }
diff --git a/kernel/drivers/hwmon/pmbus/ucd9000.c b/kernel/drivers/hwmon/pmbus/ucd9000.c
index f801799..9e26cc0 100644
--- a/kernel/drivers/hwmon/pmbus/ucd9000.c
+++ b/kernel/drivers/hwmon/pmbus/ucd9000.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/debugfs.h>
+#include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
@@ -16,6 +17,7 @@
 #include <linux/i2c.h>
 #include <linux/pmbus.h>
 #include <linux/gpio/driver.h>
+#include <linux/timekeeping.h>
 #include "pmbus.h"
 
 enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd90320, ucd9090,
@@ -65,6 +67,7 @@
 	struct gpio_chip gpio;
 #endif
 	struct dentry *debugfs;
+	ktime_t write_time;
 };
 #define to_ucd9000_data(_info) container_of(_info, struct ucd9000_data, info)
 
@@ -72,6 +75,73 @@
 	struct i2c_client *client;
 	u8 index;
 };
+
+/*
+ * It has been observed that the UCD90320 randomly fails register access when
+ * doing another access right on the back of a register write. To mitigate this
+ * make sure that there is a minimum delay between a write access and the
+ * following access. The 250us is based on experimental data. At a delay of
+ * 200us the issue seems to go away. Add a bit of extra margin to allow for
+ * system to system differences.
+ */
+#define UCD90320_WAIT_DELAY_US 250
+
+static inline void ucd90320_wait(const struct ucd9000_data *data)
+{
+	s64 delta = ktime_us_delta(ktime_get(), data->write_time);
+
+	if (delta < UCD90320_WAIT_DELAY_US)
+		udelay(UCD90320_WAIT_DELAY_US - delta);
+}
+
+static int ucd90320_read_word_data(struct i2c_client *client, int page,
+				   int phase, int reg)
+{
+	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
+	struct ucd9000_data *data = to_ucd9000_data(info);
+
+	if (reg >= PMBUS_VIRT_BASE)
+		return -ENXIO;
+
+	ucd90320_wait(data);
+	return pmbus_read_word_data(client, page, phase, reg);
+}
+
+static int ucd90320_read_byte_data(struct i2c_client *client, int page, int reg)
+{
+	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
+	struct ucd9000_data *data = to_ucd9000_data(info);
+
+	ucd90320_wait(data);
+	return pmbus_read_byte_data(client, page, reg);
+}
+
+static int ucd90320_write_word_data(struct i2c_client *client, int page,
+				    int reg, u16 word)
+{
+	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
+	struct ucd9000_data *data = to_ucd9000_data(info);
+	int ret;
+
+	ucd90320_wait(data);
+	ret = pmbus_write_word_data(client, page, reg, word);
+	data->write_time = ktime_get();
+
+	return ret;
+}
+
+static int ucd90320_write_byte(struct i2c_client *client, int page, u8 value)
+{
+	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
+	struct ucd9000_data *data = to_ucd9000_data(info);
+	int ret;
+
+	ucd90320_wait(data);
+	ret = pmbus_write_byte(client, page, value);
+	data->write_time = ktime_get();
+
+	return ret;
+}
 
 static int ucd9000_get_fan_config(struct i2c_client *client, int fan)
 {
@@ -598,6 +668,11 @@
 		info->read_byte_data = ucd9000_read_byte_data;
 		info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12
 		  | PMBUS_HAVE_FAN34 | PMBUS_HAVE_STATUS_FAN34;
+	} else if (mid->driver_data == ucd90320) {
+		info->read_byte_data = ucd90320_read_byte_data;
+		info->read_word_data = ucd90320_read_word_data;
+		info->write_byte = ucd90320_write_byte;
+		info->write_word_data = ucd90320_write_word_data;
 	}
 
 	ucd9000_probe_gpio(client, mid, data);
diff --git a/kernel/drivers/hwmon/tmp513.c b/kernel/drivers/hwmon/tmp513.c
index 47bbe47..b9a93ee 100644
--- a/kernel/drivers/hwmon/tmp513.c
+++ b/kernel/drivers/hwmon/tmp513.c
@@ -434,7 +434,7 @@
 
 	switch (type) {
 	case hwmon_temp:
-		if (data->id == tmp512 && channel == 4)
+		if (data->id == tmp512 && channel == 3)
 			return 0;
 		switch (attr) {
 		case hwmon_temp_input:
@@ -758,7 +758,7 @@
 static struct i2c_driver tmp51x_driver = {
 	.driver = {
 		.name	= "tmp51x",
-		.of_match_table = of_match_ptr(tmp51x_of_match),
+		.of_match_table = tmp51x_of_match,
 	},
 	.probe_new	= tmp51x_probe,
 	.id_table	= tmp51x_id,
diff --git a/kernel/drivers/hwmon/xgene-hwmon.c b/kernel/drivers/hwmon/xgene-hwmon.c
index f2a5af2..f5d3cf8 100644
--- a/kernel/drivers/hwmon/xgene-hwmon.c
+++ b/kernel/drivers/hwmon/xgene-hwmon.c
@@ -768,6 +768,7 @@
 {
 	struct xgene_hwmon_dev *ctx = platform_get_drvdata(pdev);
 
+	cancel_work_sync(&ctx->workq);
 	hwmon_device_unregister(ctx->hwmon_dev);
 	kfifo_free(&ctx->async_msg_fifo);
 	if (acpi_disabled)
diff --git a/kernel/drivers/hwtracing/coresight/coresight-core.c b/kernel/drivers/hwtracing/coresight/coresight-core.c
index 53dc2aa..08c7d00 100644
--- a/kernel/drivers/hwtracing/coresight/coresight-core.c
+++ b/kernel/drivers/hwtracing/coresight/coresight-core.c
@@ -1415,13 +1415,8 @@
 		if (csdev->dev.fwnode == conn->child_fwnode) {
 			iterator->orphan = true;
 			coresight_remove_links(iterator, conn);
-			/*
-			 * Drop the reference to the handle for the remote
-			 * device acquired in parsing the connections from
-			 * platform data.
-			 */
-			fwnode_handle_put(conn->child_fwnode);
-			conn->child_fwnode = NULL;
+
+			conn->child_dev = NULL;
 			/* No need to continue */
 			break;
 		}
diff --git a/kernel/drivers/hwtracing/coresight/coresight-etm-perf.c b/kernel/drivers/hwtracing/coresight/coresight-etm-perf.c
index 9142c5b..417b834 100644
--- a/kernel/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/kernel/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -740,6 +740,7 @@
 	etm_pmu.addr_filters_sync	= etm_addr_filters_sync;
 	etm_pmu.addr_filters_validate	= etm_addr_filters_validate;
 	etm_pmu.nr_addr_filters		= ETM_ADDR_CMP_MAX;
+	etm_pmu.module			= THIS_MODULE;
 
 	ret = perf_pmu_register(&etm_pmu, CORESIGHT_ETM_PMU_NAME, -1);
 	if (ret == 0)
diff --git a/kernel/drivers/hwtracing/coresight/coresight-etm4x-core.c b/kernel/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 19dbb79..146c893 100644
--- a/kernel/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/kernel/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -447,7 +447,7 @@
 		if (etm4x_sspcicrn_present(drvdata, i))
 			etm4x_relaxed_write32(csa, config->ss_pe_cmp[i], TRCSSPCICRn(i));
 	}
-	for (i = 0; i < drvdata->nr_addr_cmp; i++) {
+	for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
 		etm4x_relaxed_write64(csa, config->addr_val[i], TRCACVRn(i));
 		etm4x_relaxed_write64(csa, config->addr_acc[i], TRCACATRn(i));
 	}
@@ -960,25 +960,21 @@
 				   struct csdev_access *csa)
 {
 	u32 devarch = readl_relaxed(drvdata->base + TRCDEVARCH);
-	u32 idr1 = readl_relaxed(drvdata->base + TRCIDR1);
 
 	/*
 	 * All ETMs must implement TRCDEVARCH to indicate that
-	 * the component is an ETMv4. To support any broken
-	 * implementations we fall back to TRCIDR1 check, which
-	 * is not really reliable.
+	 * the component is an ETMv4. Even though TRCIDR1 also
+	 * contains the information, it is part of the "Trace"
+	 * register and must be accessed with the OSLK cleared,
+	 * with MMIO. But we cannot touch the OSLK until we are
+	 * sure this is an ETM. So rely only on the TRCDEVARCH.
 	 */
-	if ((devarch & ETM_DEVARCH_ID_MASK) == ETM_DEVARCH_ETMv4x_ARCH) {
-		drvdata->arch = etm_devarch_to_arch(devarch);
-	} else {
-		pr_warn("CPU%d: ETM4x incompatible TRCDEVARCH: %x, falling back to TRCIDR1\n",
-			smp_processor_id(), devarch);
-
-		if (ETM_TRCIDR1_ARCH_MAJOR(idr1) != ETM_TRCIDR1_ARCH_ETMv4)
-			return false;
-		drvdata->arch = etm_trcidr_to_arch(idr1);
+	if ((devarch & ETM_DEVARCH_ID_MASK) != ETM_DEVARCH_ETMv4x_ARCH) {
+		pr_warn_once("TRCDEVARCH doesn't match ETMv4 architecture\n");
+		return false;
 	}
 
+	drvdata->arch = etm_devarch_to_arch(devarch);
 	*csa = CSDEV_ACCESS_IOMEM(drvdata->base);
 	return true;
 }
diff --git a/kernel/drivers/hwtracing/coresight/coresight-etm4x.h b/kernel/drivers/hwtracing/coresight/coresight-etm4x.h
index 3c4d69b..1ac4a06 100644
--- a/kernel/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/kernel/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -668,14 +668,12 @@
  * TRCDEVARCH	- CoreSight architected register
  *                - Bits[15:12] - Major version
  *                - Bits[19:16] - Minor version
- * TRCIDR1	- ETM architected register
- *                - Bits[11:8] - Major version
- *                - Bits[7:4]  - Minor version
- * We must rely on TRCDEVARCH for the version information,
- * however we don't want to break the support for potential
- * old implementations which might not implement it. Thus
- * we fall back to TRCIDR1 if TRCDEVARCH is not implemented
- * for memory mapped components.
+ *
+ * We must rely only on TRCDEVARCH for the version information. Even though,
+ * TRCIDR1 also provides the architecture version, it is a "Trace" register
+ * and as such must be accessed only with Trace power domain ON. This may
+ * not be available at probe time.
+ *
  * Now to make certain decisions easier based on the version
  * we use an internal representation of the version in the
  * driver, as follows :
@@ -699,12 +697,6 @@
 {
 	return ETM_ARCH_VERSION(ETM_DEVARCH_ARCHID_ARCH_VER(devarch),
 				ETM_DEVARCH_REVISION(devarch));
-}
-
-static inline u8 etm_trcidr_to_arch(u32 trcidr1)
-{
-	return ETM_ARCH_VERSION(ETM_TRCIDR1_ARCH_MAJOR(trcidr1),
-				ETM_TRCIDR1_ARCH_MINOR(trcidr1));
 }
 
 enum etm_impdef_type {
diff --git a/kernel/drivers/hwtracing/coresight/coresight-tmc-etf.c b/kernel/drivers/hwtracing/coresight/coresight-tmc-etf.c
index cd0fb7b..e9c2b07 100644
--- a/kernel/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/kernel/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -428,7 +428,7 @@
 		return -EINVAL;
 
 	/* wrap head around to the amount of space we have */
-	head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1);
+	head = handle->head & (((unsigned long)buf->nr_pages << PAGE_SHIFT) - 1);
 
 	/* find the page to write to */
 	buf->cur = head / PAGE_SIZE;
diff --git a/kernel/drivers/hwtracing/coresight/coresight-tmc-etr.c b/kernel/drivers/hwtracing/coresight/coresight-tmc-etr.c
index ec092b6..19e701e 100644
--- a/kernel/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/kernel/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -47,7 +47,8 @@
 };
 
 /* Convert the perf index to an offset within the ETR buffer */
-#define PERF_IDX2OFF(idx, buf)	((idx) % ((buf)->nr_pages << PAGE_SHIFT))
+#define PERF_IDX2OFF(idx, buf)		\
+		((idx) % ((unsigned long)(buf)->nr_pages << PAGE_SHIFT))
 
 /* Lower limit for ETR hardware buffer */
 #define TMC_ETR_PERF_MIN_BUF_SIZE	SZ_1M
@@ -944,7 +945,7 @@
 
 	len = tmc_etr_buf_get_data(etr_buf, offset,
 				   CORESIGHT_BARRIER_PKT_SIZE, &bufp);
-	if (WARN_ON(len < CORESIGHT_BARRIER_PKT_SIZE))
+	if (WARN_ON(len < 0 || len < CORESIGHT_BARRIER_PKT_SIZE))
 		return -EINVAL;
 	coresight_insert_barrier_packet(bufp);
 	return offset + CORESIGHT_BARRIER_PKT_SIZE;
@@ -1250,7 +1251,7 @@
 	 * than the size requested via sysfs.
 	 */
 	if ((nr_pages << PAGE_SHIFT) > drvdata->size) {
-		etr_buf = tmc_alloc_etr_buf(drvdata, (nr_pages << PAGE_SHIFT),
+		etr_buf = tmc_alloc_etr_buf(drvdata, ((ssize_t)nr_pages << PAGE_SHIFT),
 					    0, node, NULL);
 		if (!IS_ERR(etr_buf))
 			goto done;
diff --git a/kernel/drivers/hwtracing/coresight/coresight-tmc.h b/kernel/drivers/hwtracing/coresight/coresight-tmc.h
index b91ec7d..3655b3b 100644
--- a/kernel/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/kernel/drivers/hwtracing/coresight/coresight-tmc.h
@@ -321,7 +321,7 @@
 static inline unsigned long
 tmc_sg_table_buf_size(struct tmc_sg_table *sg_table)
 {
-	return sg_table->data_pages.nr_pages << PAGE_SHIFT;
+	return (unsigned long)sg_table->data_pages.nr_pages << PAGE_SHIFT;
 }
 
 struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata);
diff --git a/kernel/drivers/hwtracing/coresight/coresight-trbe.c b/kernel/drivers/hwtracing/coresight/coresight-trbe.c
index 7dddb85..fac63d0 100644
--- a/kernel/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/kernel/drivers/hwtracing/coresight/coresight-trbe.c
@@ -1030,6 +1030,7 @@
 
 static void arm_trbe_remove_cpuhp(struct trbe_drvdata *drvdata)
 {
+	cpuhp_state_remove_instance(drvdata->trbe_online, &drvdata->hotplug_node);
 	cpuhp_remove_multi_state(drvdata->trbe_online);
 }
 
diff --git a/kernel/drivers/i2c/busses/i2c-aspeed.c b/kernel/drivers/i2c/busses/i2c-aspeed.c
index 724bf30..dac46bc 100644
--- a/kernel/drivers/i2c/busses/i2c-aspeed.c
+++ b/kernel/drivers/i2c/busses/i2c-aspeed.c
@@ -693,13 +693,16 @@
 
 	if (time_left == 0) {
 		/*
-		 * If timed out and bus is still busy in a multi master
-		 * environment, attempt recovery at here.
+		 * In a multi-master setup, if a timeout occurs, attempt
+		 * recovery. But if the bus is idle, we still need to reset the
+		 * i2c controller to clear the remaining interrupts.
 		 */
 		if (bus->multi_master &&
 		    (readl(bus->base + ASPEED_I2C_CMD_REG) &
 		     ASPEED_I2CD_BUS_BUSY_STS))
 			aspeed_i2c_recover_bus(bus);
+		else
+			aspeed_i2c_reset(bus);
 
 		/*
 		 * If timed out and the state is still pending, drop the pending
diff --git a/kernel/drivers/i2c/busses/i2c-bcm-iproc.c b/kernel/drivers/i2c/busses/i2c-bcm-iproc.c
index 35baca2..a524d2c 100644
--- a/kernel/drivers/i2c/busses/i2c-bcm-iproc.c
+++ b/kernel/drivers/i2c/busses/i2c-bcm-iproc.c
@@ -242,13 +242,14 @@
 				   u32 offset)
 {
 	u32 val;
+	unsigned long flags;
 
 	if (iproc_i2c->idm_base) {
-		spin_lock(&iproc_i2c->idm_lock);
+		spin_lock_irqsave(&iproc_i2c->idm_lock, flags);
 		writel(iproc_i2c->ape_addr_mask,
 		       iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET);
 		val = readl(iproc_i2c->base + offset);
-		spin_unlock(&iproc_i2c->idm_lock);
+		spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags);
 	} else {
 		val = readl(iproc_i2c->base + offset);
 	}
@@ -259,12 +260,14 @@
 static inline void iproc_i2c_wr_reg(struct bcm_iproc_i2c_dev *iproc_i2c,
 				    u32 offset, u32 val)
 {
+	unsigned long flags;
+
 	if (iproc_i2c->idm_base) {
-		spin_lock(&iproc_i2c->idm_lock);
+		spin_lock_irqsave(&iproc_i2c->idm_lock, flags);
 		writel(iproc_i2c->ape_addr_mask,
 		       iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET);
 		writel(val, iproc_i2c->base + offset);
-		spin_unlock(&iproc_i2c->idm_lock);
+		spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags);
 	} else {
 		writel(val, iproc_i2c->base + offset);
 	}
diff --git a/kernel/drivers/i2c/busses/i2c-cadence.c b/kernel/drivers/i2c/busses/i2c-cadence.c
index 5092821..2498790 100644
--- a/kernel/drivers/i2c/busses/i2c-cadence.c
+++ b/kernel/drivers/i2c/busses/i2c-cadence.c
@@ -792,8 +792,10 @@
 #if IS_ENABLED(CONFIG_I2C_SLAVE)
 	/* Check i2c operating mode and switch if possible */
 	if (id->dev_mode == CDNS_I2C_MODE_SLAVE) {
-		if (id->slave_state != CDNS_I2C_SLAVE_STATE_IDLE)
-			return -EAGAIN;
+		if (id->slave_state != CDNS_I2C_SLAVE_STATE_IDLE) {
+			ret = -EAGAIN;
+			goto out;
+		}
 
 		/* Set mode to master */
 		cdns_i2c_set_mode(CDNS_I2C_MODE_MASTER, id);
diff --git a/kernel/drivers/i2c/busses/i2c-designware-common.c b/kernel/drivers/i2c/busses/i2c-designware-common.c
index 9468c6c..682fffa 100644
--- a/kernel/drivers/i2c/busses/i2c-designware-common.c
+++ b/kernel/drivers/i2c/busses/i2c-designware-common.c
@@ -24,6 +24,7 @@
 #include <linux/regmap.h>
 #include <linux/swab.h>
 #include <linux/types.h>
+#include <linux/units.h>
 
 #include "i2c-designware-core.h"
 
@@ -347,7 +348,8 @@
 		 *
 		 * If your hardware is free from tHD;STA issue, try this one.
 		 */
-		return (ic_clk * tSYMBOL + 500000) / 1000000 - 8 + offset;
+		return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * tSYMBOL, MICRO) -
+		       8 + offset;
 	else
 		/*
 		 * Conditional expression:
@@ -363,8 +365,8 @@
 		 * The reason why we need to take into account "tf" here,
 		 * is the same as described in i2c_dw_scl_lcnt().
 		 */
-		return (ic_clk * (tSYMBOL + tf) + 500000) / 1000000
-			- 3 + offset;
+		return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * (tSYMBOL + tf), MICRO) -
+		       3 + offset;
 }
 
 u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
@@ -380,7 +382,8 @@
 	 * account the fall time of SCL signal (tf).  Default tf value
 	 * should be 0.3 us, for safety.
 	 */
-	return ((ic_clk * (tLOW + tf) + 500000) / 1000000) - 1 + offset;
+	return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * (tLOW + tf), MICRO) -
+	       1 + offset;
 }
 
 int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev)
diff --git a/kernel/drivers/i2c/busses/i2c-designware-master.c b/kernel/drivers/i2c/busses/i2c-designware-master.c
index 2871cf2..106080b 100644
--- a/kernel/drivers/i2c/busses/i2c-designware-master.c
+++ b/kernel/drivers/i2c/busses/i2c-designware-master.c
@@ -432,8 +432,19 @@
 
 			regmap_read(dev->map, DW_IC_DATA_CMD, &tmp);
 			/* Ensure length byte is a valid value */
-			if (flags & I2C_M_RECV_LEN &&
-			    tmp <= I2C_SMBUS_BLOCK_MAX && tmp > 0) {
+			if (flags & I2C_M_RECV_LEN) {
+				/*
+				 * if IC_EMPTYFIFO_HOLD_MASTER_EN is set, which cannot be
+				 * detected from the registers, the controller can be
+				 * disabled if the STOP bit is set. But it is only set
+				 * after receiving block data response length in
+				 * I2C_FUNC_SMBUS_BLOCK_DATA case. That needs to read
+				 * another byte with STOP bit set when the block data
+				 * response length is invalid to complete the transaction.
+				 */
+				if (!tmp || tmp > I2C_SMBUS_BLOCK_MAX)
+					tmp = 1;
+
 				len = i2c_dw_recv_len(dev, tmp);
 			}
 			*buf++ = tmp;
diff --git a/kernel/drivers/i2c/busses/i2c-designware-platdrv.c b/kernel/drivers/i2c/busses/i2c-designware-platdrv.c
index ad91c7c..4747541 100644
--- a/kernel/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/kernel/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -32,12 +32,13 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/suspend.h>
+#include <linux/units.h>
 
 #include "i2c-designware-core.h"
 
 static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
 {
-	return clk_get_rate(dev->clk)/1000;
+	return clk_get_rate(dev->clk) / KILO;
 }
 
 #ifdef CONFIG_ACPI
@@ -284,7 +285,7 @@
 
 		if (!dev->sda_hold_time && t->sda_hold_ns)
 			dev->sda_hold_time =
-				div_u64(clk_khz * t->sda_hold_ns + 500000, 1000000);
+				DIV_S64_ROUND_CLOSEST(clk_khz * t->sda_hold_ns, MICRO);
 	}
 
 	adap = &dev->adapter;
diff --git a/kernel/drivers/i2c/busses/i2c-i801.c b/kernel/drivers/i2c/busses/i2c-i801.c
index 45682d3..4aec451 100644
--- a/kernel/drivers/i2c/busses/i2c-i801.c
+++ b/kernel/drivers/i2c/busses/i2c-i801.c
@@ -1907,6 +1907,7 @@
 		"SMBus I801 adapter at %04lx", priv->smba);
 	err = i2c_add_adapter(&priv->adapter);
 	if (err) {
+		platform_device_unregister(priv->tco_pdev);
 		i801_acpi_remove(priv);
 		return err;
 	}
diff --git a/kernel/drivers/i2c/busses/i2c-ibm_iic.c b/kernel/drivers/i2c/busses/i2c-ibm_iic.c
index 9f71daf..c073f5b 100644
--- a/kernel/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/kernel/drivers/i2c/busses/i2c-ibm_iic.c
@@ -694,10 +694,8 @@
 	int ret;
 
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (!dev) {
-		dev_err(&ofdev->dev, "failed to allocate device data\n");
+	if (!dev)
 		return -ENOMEM;
-	}
 
 	platform_set_drvdata(ofdev, dev);
 
diff --git a/kernel/drivers/i2c/busses/i2c-imx-lpi2c.c b/kernel/drivers/i2c/busses/i2c-imx-lpi2c.c
index 8b9ba05..c688f11 100644
--- a/kernel/drivers/i2c/busses/i2c-imx-lpi2c.c
+++ b/kernel/drivers/i2c/busses/i2c-imx-lpi2c.c
@@ -200,8 +200,8 @@
 /* CLKLO = I2C_CLK_RATIO * CLKHI, SETHOLD = CLKHI, DATAVD = CLKHI/2 */
 static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx)
 {
-	u8 prescale, filt, sethold, clkhi, clklo, datavd;
-	unsigned int clk_rate, clk_cycle;
+	u8 prescale, filt, sethold, datavd;
+	unsigned int clk_rate, clk_cycle, clkhi, clklo;
 	enum lpi2c_imx_pincfg pincfg;
 	unsigned int temp;
 
@@ -462,6 +462,8 @@
 		if (num == 1 && msgs[0].len == 0)
 			goto stop;
 
+		lpi2c_imx->rx_buf = NULL;
+		lpi2c_imx->tx_buf = NULL;
 		lpi2c_imx->delivered = 0;
 		lpi2c_imx->msglen = msgs[i].len;
 		init_completion(&lpi2c_imx->complete);
@@ -502,10 +504,14 @@
 static irqreturn_t lpi2c_imx_isr(int irq, void *dev_id)
 {
 	struct lpi2c_imx_struct *lpi2c_imx = dev_id;
+	unsigned int enabled;
 	unsigned int temp;
+
+	enabled = readl(lpi2c_imx->base + LPI2C_MIER);
 
 	lpi2c_imx_intctrl(lpi2c_imx, 0);
 	temp = readl(lpi2c_imx->base + LPI2C_MSR);
+	temp &= enabled;
 
 	if (temp & MSR_RDF)
 		lpi2c_imx_read_rxfifo(lpi2c_imx);
diff --git a/kernel/drivers/i2c/busses/i2c-ismt.c b/kernel/drivers/i2c/busses/i2c-ismt.c
index 3d2d926..cec2b2a 100644
--- a/kernel/drivers/i2c/busses/i2c-ismt.c
+++ b/kernel/drivers/i2c/busses/i2c-ismt.c
@@ -507,6 +507,9 @@
 		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;
diff --git a/kernel/drivers/i2c/busses/i2c-mxs.c b/kernel/drivers/i2c/busses/i2c-mxs.c
index c4b08a9..abad248 100644
--- a/kernel/drivers/i2c/busses/i2c-mxs.c
+++ b/kernel/drivers/i2c/busses/i2c-mxs.c
@@ -842,8 +842,8 @@
 	/* Setup the DMA */
 	i2c->dmach = dma_request_chan(dev, "rx-tx");
 	if (IS_ERR(i2c->dmach)) {
-		dev_err(dev, "Failed to request dma\n");
-		return PTR_ERR(i2c->dmach);
+		return dev_err_probe(dev, PTR_ERR(i2c->dmach),
+				     "Failed to request dma\n");
 	}
 
 	platform_set_drvdata(pdev, i2c);
diff --git a/kernel/drivers/i2c/busses/i2c-nomadik.c b/kernel/drivers/i2c/busses/i2c-nomadik.c
index a3363b2..a06c4b7 100644
--- a/kernel/drivers/i2c/busses/i2c-nomadik.c
+++ b/kernel/drivers/i2c/busses/i2c-nomadik.c
@@ -970,12 +970,10 @@
 	struct i2c_vendor_data *vendor = id->data;
 	u32 max_fifo_threshold = (vendor->fifodepth / 2) - 1;
 
-	dev = devm_kzalloc(&adev->dev, sizeof(struct nmk_i2c_dev), GFP_KERNEL);
-	if (!dev) {
-		dev_err(&adev->dev, "cannot allocate memory\n");
-		ret = -ENOMEM;
-		goto err_no_mem;
-	}
+	dev = devm_kzalloc(&adev->dev, sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
 	dev->vendor = vendor;
 	dev->adev = adev;
 	nmk_i2c_of_probe(np, dev);
@@ -996,30 +994,21 @@
 
 	dev->virtbase = devm_ioremap(&adev->dev, adev->res.start,
 				resource_size(&adev->res));
-	if (!dev->virtbase) {
-		ret = -ENOMEM;
-		goto err_no_mem;
-	}
+	if (!dev->virtbase)
+		return -ENOMEM;
 
 	dev->irq = adev->irq[0];
 	ret = devm_request_irq(&adev->dev, dev->irq, i2c_irq_handler, 0,
 				DRIVER_NAME, dev);
 	if (ret) {
 		dev_err(&adev->dev, "cannot claim the irq %d\n", dev->irq);
-		goto err_no_mem;
+		return ret;
 	}
 
-	dev->clk = devm_clk_get(&adev->dev, NULL);
+	dev->clk = devm_clk_get_enabled(&adev->dev, NULL);
 	if (IS_ERR(dev->clk)) {
-		dev_err(&adev->dev, "could not get i2c clock\n");
-		ret = PTR_ERR(dev->clk);
-		goto err_no_mem;
-	}
-
-	ret = clk_prepare_enable(dev->clk);
-	if (ret) {
-		dev_err(&adev->dev, "can't prepare_enable clock\n");
-		goto err_no_mem;
+		dev_err(&adev->dev, "could enable i2c clock\n");
+		return PTR_ERR(dev->clk);
 	}
 
 	init_hw(dev);
@@ -1042,22 +1031,15 @@
 
 	ret = i2c_add_adapter(adap);
 	if (ret)
-		goto err_no_adap;
+		return ret;
 
 	pm_runtime_put(&adev->dev);
 
 	return 0;
-
- err_no_adap:
-	clk_disable_unprepare(dev->clk);
- err_no_mem:
-
-	return ret;
 }
 
 static void nmk_i2c_remove(struct amba_device *adev)
 {
-	struct resource *res = &adev->res;
 	struct nmk_i2c_dev *dev = amba_get_drvdata(adev);
 
 	i2c_del_adapter(&dev->adap);
@@ -1066,8 +1048,6 @@
 	clear_all_interrupts(dev);
 	/* disable the controller */
 	i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
-	clk_disable_unprepare(dev->clk);
-	release_mem_region(res->start, resource_size(res));
 }
 
 static struct i2c_vendor_data vendor_stn8815 = {
diff --git a/kernel/drivers/i2c/busses/i2c-npcm7xx.c b/kernel/drivers/i2c/busses/i2c-npcm7xx.c
index c1b6797..73c808e 100644
--- a/kernel/drivers/i2c/busses/i2c-npcm7xx.c
+++ b/kernel/drivers/i2c/busses/i2c-npcm7xx.c
@@ -675,6 +675,7 @@
 {
 	struct i2c_msg *msgs;
 	int msgs_num;
+	bool do_complete = false;
 
 	msgs = bus->msgs;
 	msgs_num = bus->msgs_num;
@@ -701,23 +702,17 @@
 				 msgs[1].flags & I2C_M_RD)
 				msgs[1].len = info;
 		}
-		if (completion_done(&bus->cmd_complete) == false)
-			complete(&bus->cmd_complete);
-	break;
-
+		do_complete = true;
+		break;
 	case I2C_NACK_IND:
 		/* MASTER transmit got a NACK before tx all bytes */
 		bus->cmd_err = -ENXIO;
-		if (bus->master_or_slave == I2C_MASTER)
-			complete(&bus->cmd_complete);
-
+		do_complete = true;
 		break;
 	case I2C_BUS_ERR_IND:
 		/* Bus error */
 		bus->cmd_err = -EAGAIN;
-		if (bus->master_or_slave == I2C_MASTER)
-			complete(&bus->cmd_complete);
-
+		do_complete = true;
 		break;
 	case I2C_WAKE_UP_IND:
 		/* I2C wake up */
@@ -731,6 +726,8 @@
 	if (bus->slave)
 		bus->master_or_slave = I2C_SLAVE;
 #endif
+	if (do_complete)
+		complete(&bus->cmd_complete);
 }
 
 static u8 npcm_i2c_fifo_usage(struct npcm_i2c *bus)
diff --git a/kernel/drivers/i2c/busses/i2c-ocores.c b/kernel/drivers/i2c/busses/i2c-ocores.c
index f5fc75b..71e26aa 100644
--- a/kernel/drivers/i2c/busses/i2c-ocores.c
+++ b/kernel/drivers/i2c/busses/i2c-ocores.c
@@ -343,18 +343,18 @@
  * ocores_isr(), we just add our polling code around it.
  *
  * It can run in atomic context
+ *
+ * Return: 0 on success, -ETIMEDOUT on timeout
  */
-static void ocores_process_polling(struct ocores_i2c *i2c)
+static int ocores_process_polling(struct ocores_i2c *i2c)
 {
-	while (1) {
-		irqreturn_t ret;
-		int err;
+	irqreturn_t ret;
+	int err = 0;
 
+	while (1) {
 		err = ocores_poll_wait(i2c);
-		if (err) {
-			i2c->state = STATE_ERROR;
+		if (err)
 			break; /* timeout */
-		}
 
 		ret = ocores_isr(-1, i2c);
 		if (ret == IRQ_NONE)
@@ -365,13 +365,15 @@
 					break;
 		}
 	}
+
+	return err;
 }
 
 static int ocores_xfer_core(struct ocores_i2c *i2c,
 			    struct i2c_msg *msgs, int num,
 			    bool polling)
 {
-	int ret;
+	int ret = 0;
 	u8 ctrl;
 
 	ctrl = oc_getreg(i2c, OCI2C_CONTROL);
@@ -389,15 +391,16 @@
 	oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
 
 	if (polling) {
-		ocores_process_polling(i2c);
+		ret = ocores_process_polling(i2c);
 	} else {
-		ret = wait_event_timeout(i2c->wait,
-					 (i2c->state == STATE_ERROR) ||
-					 (i2c->state == STATE_DONE), HZ);
-		if (ret == 0) {
-			ocores_process_timeout(i2c);
-			return -ETIMEDOUT;
-		}
+		if (wait_event_timeout(i2c->wait,
+				       (i2c->state == STATE_ERROR) ||
+				       (i2c->state == STATE_DONE), HZ) == 0)
+			ret = -ETIMEDOUT;
+	}
+	if (ret) {
+		ocores_process_timeout(i2c);
+		return ret;
 	}
 
 	return (i2c->state == STATE_DONE) ? num : -EIO;
diff --git a/kernel/drivers/i2c/busses/i2c-omap.c b/kernel/drivers/i2c/busses/i2c-omap.c
index d4f6c6d..8955f62 100644
--- a/kernel/drivers/i2c/busses/i2c-omap.c
+++ b/kernel/drivers/i2c/busses/i2c-omap.c
@@ -1058,7 +1058,7 @@
 	u16 stat;
 
 	stat = omap_i2c_read_reg(omap, OMAP_I2C_STAT_REG);
-	mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG);
+	mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG) & ~OMAP_I2C_STAT_NACK;
 
 	if (stat & mask)
 		ret = IRQ_WAKE_THREAD;
diff --git a/kernel/drivers/i2c/busses/i2c-pxa-pci.c b/kernel/drivers/i2c/busses/i2c-pxa-pci.c
index f614cad..30e38bc 100644
--- a/kernel/drivers/i2c/busses/i2c-pxa-pci.c
+++ b/kernel/drivers/i2c/busses/i2c-pxa-pci.c
@@ -105,7 +105,7 @@
 	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 @@
 		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 @@
 
 err_dev_add:
 	kfree(sds);
-err_mem:
-	pci_disable_device(dev);
 	return ret;
 }
 
diff --git a/kernel/drivers/i2c/busses/i2c-qup.c b/kernel/drivers/i2c/busses/i2c-qup.c
index 5a47915..576c126 100644
--- a/kernel/drivers/i2c/busses/i2c-qup.c
+++ b/kernel/drivers/i2c/busses/i2c-qup.c
@@ -1752,16 +1752,21 @@
 	if (!clk_freq || clk_freq > I2C_MAX_FAST_MODE_PLUS_FREQ) {
 		dev_err(qup->dev, "clock frequency not supported %d\n",
 			clk_freq);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto fail_dma;
 	}
 
 	qup->base = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(qup->base))
-		return PTR_ERR(qup->base);
+	if (IS_ERR(qup->base)) {
+		ret = PTR_ERR(qup->base);
+		goto fail_dma;
+	}
 
 	qup->irq = platform_get_irq(pdev, 0);
-	if (qup->irq < 0)
-		return qup->irq;
+	if (qup->irq < 0) {
+		ret = qup->irq;
+		goto fail_dma;
+	}
 
 	if (has_acpi_companion(qup->dev)) {
 		ret = device_property_read_u32(qup->dev,
@@ -1775,13 +1780,15 @@
 		qup->clk = devm_clk_get(qup->dev, "core");
 		if (IS_ERR(qup->clk)) {
 			dev_err(qup->dev, "Could not get core clock\n");
-			return PTR_ERR(qup->clk);
+			ret = PTR_ERR(qup->clk);
+			goto fail_dma;
 		}
 
 		qup->pclk = devm_clk_get(qup->dev, "iface");
 		if (IS_ERR(qup->pclk)) {
 			dev_err(qup->dev, "Could not get iface clock\n");
-			return PTR_ERR(qup->pclk);
+			ret = PTR_ERR(qup->pclk);
+			goto fail_dma;
 		}
 		qup_i2c_enable_clocks(qup);
 		src_clk_freq = clk_get_rate(qup->clk);
diff --git a/kernel/drivers/i2c/busses/i2c-rk3x.c b/kernel/drivers/i2c/busses/i2c-rk3x.c
index 71592ed..4fe2e04 100644
--- a/kernel/drivers/i2c/busses/i2c-rk3x.c
+++ b/kernel/drivers/i2c/busses/i2c-rk3x.c
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/reset.h>
 #include <linux/spinlock.h>
 #include <linux/clk.h>
 #include <linux/wait.h>
@@ -39,6 +40,7 @@
 #define REG_IEN        0x18 /* interrupt enable */
 #define REG_IPD        0x1c /* interrupt pending */
 #define REG_FCNT       0x20 /* finished count */
+#define REG_SCL_OE_DB  0x24 /* Slave hold scl debounce */
 #define REG_CON1       0x228 /* control register1 */
 
 /* Data buffer offsets */
@@ -87,6 +89,7 @@
 #define REG_INT_START     BIT(4) /* START condition generated */
 #define REG_INT_STOP      BIT(5) /* STOP condition generated */
 #define REG_INT_NAKRCV    BIT(6) /* NACK received */
+#define REG_INT_SLV_HDSCL BIT(7) /* slave hold scl */
 #define REG_INT_ALL       0xff
 
 /* Disable i2c all irqs */
@@ -97,11 +100,11 @@
 #define REG_CON1_NACK_AUTO_STOP BIT(2)
 
 /* Constants */
-#define WAIT_TIMEOUT      1000 /* ms */
+#define WAIT_TIMEOUT      200 /* ms */
 #define DEFAULT_SCL_RATE  (100 * 1000) /* Hz */
 
 /**
- * struct i2c_spec_values:
+ * struct i2c_spec_values - I2C specification values for various modes
  * @min_hold_start_ns: min hold time (repeated) START condition
  * @min_low_ns: min LOW period of the SCL clock
  * @min_high_ns: min HIGH period of the SCL cloc
@@ -157,7 +160,7 @@
 };
 
 /**
- * struct rk3x_i2c_calced_timings:
+ * struct rk3x_i2c_calced_timings - calculated V1 timings
  * @div_low: Divider output for low
  * @div_high: Divider output for high
  * @tuning: Used to adjust setup/hold data time,
@@ -179,7 +182,7 @@
 };
 
 /**
- * struct rk3x_i2c_soc_data:
+ * struct rk3x_i2c_soc_data - SOC-specific data
  * @grf_offset: offset inside the grf regmap for setting the i2c type
  * @calc_timings: Callback function for i2c timing information calculated
  */
@@ -224,6 +227,9 @@
 	struct clk *pclk;
 	struct notifier_block clk_rate_nb;
 	bool autostop_supported;
+
+	struct reset_control *reset;
+	struct reset_control *reset_apb;
 
 	/* Settings */
 	struct i2c_timings t;
@@ -307,6 +313,13 @@
 	if (len > 32)
 		goto out;
 
+	/* For tx mode, one byte of the device address also needs to be counted,
+	 * if the data length is equal to 32, which is actually 33 bytes, it would
+	 * need to be divided into two parts, and needs to jump out of autostop.
+	 */
+	if (i2c->msg->len == 32 && i2c->mode == REG_CON_MOD_TX && !i2c->processed)
+		goto out;
+
 	i2c->state = STATE_STOP;
 
 	con1 |= REG_CON1_TRANSFER_AUTO_STOP | REG_CON1_AUTO_STOP;
@@ -324,7 +337,8 @@
 }
 
 /**
- * Generate a START condition, which triggers a REG_INT_START interrupt.
+ * rk3x_i2c_start - Generate a START condition, which triggers a REG_INT_START interrupt.
+ * @i2c: target controller data
  */
 static void rk3x_i2c_start(struct rk3x_i2c *i2c)
 {
@@ -364,8 +378,8 @@
 }
 
 /**
- * Generate a STOP condition, which triggers a REG_INT_STOP interrupt.
- *
+ * rk3x_i2c_stop - Generate a STOP condition, which triggers a REG_INT_STOP interrupt.
+ * @i2c: target controller data
  * @error: Error code to return in rk3x_i2c_xfer
  */
 static void rk3x_i2c_stop(struct rk3x_i2c *i2c, int error)
@@ -373,7 +387,6 @@
 	unsigned int ctrl;
 
 	i2c->processed = 0;
-	i2c->msg = NULL;
 	i2c->error = error;
 
 	if (i2c->is_last_msg) {
@@ -390,6 +403,7 @@
 		/* Signal rk3x_i2c_xfer to start the next message. */
 		i2c->busy = false;
 		i2c->state = STATE_IDLE;
+		i2c->msg = NULL;
 
 		/*
 		 * The HW is actually not capable of REPEATED START. But we can
@@ -405,7 +419,8 @@
 }
 
 /**
- * Setup a read according to i2c->msg
+ * rk3x_i2c_prepare_read - Setup a read according to i2c->msg
+ * @i2c: target controller data
  */
 static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c)
 {
@@ -438,7 +453,8 @@
 }
 
 /**
- * Fill the transmit buffer with data from i2c->msg
+ * rk3x_i2c_fill_transmit_buf - Fill the transmit buffer with data from i2c->msg
+ * @i2c: target controller data
  */
 static int rk3x_i2c_fill_transmit_buf(struct rk3x_i2c *i2c, bool sendend)
 {
@@ -556,7 +572,6 @@
 		}
 
 		i2c->processed = 0;
-		i2c->msg = NULL;
 	}
 
 	/* ack interrupt */
@@ -571,6 +586,7 @@
 
 	i2c->busy = false;
 	i2c->state = STATE_IDLE;
+	i2c->msg = NULL;
 
 	/* signal rk3x_i2c_xfer that we are finished */
 	rk3x_i2c_wake_up(i2c);
@@ -595,7 +611,7 @@
 	dev_dbg(i2c->dev, "IRQ: state %d, ipd: %x\n", i2c->state, ipd);
 
 	/* Clean interrupt bits we don't care about */
-	ipd &= ~(REG_INT_BRF | REG_INT_BTF);
+	ipd &= ~(REG_INT_BRF | REG_INT_BTF | REG_INT_START);
 
 	if (ipd & REG_INT_NAKRCV) {
 		/*
@@ -642,11 +658,10 @@
 }
 
 /**
- * Get timing values of I2C specification
- *
+ * rk3x_i2c_get_spec - Get timing values of I2C specification
  * @speed: Desired SCL frequency
  *
- * Returns: Matched i2c spec values.
+ * Return: Matched i2c_spec_values.
  */
 static const struct i2c_spec_values *rk3x_i2c_get_spec(unsigned int speed)
 {
@@ -659,13 +674,12 @@
 }
 
 /**
- * Calculate divider values for desired SCL frequency
- *
+ * rk3x_i2c_v0_calc_timings - Calculate divider values for desired SCL frequency
  * @clk_rate: I2C input clock rate
  * @t: Known I2C timing information
  * @t_calc: Caculated rk3x private timings that would be written into regs
  *
- * Returns: 0 on success, -EINVAL if the goal SCL rate is too slow. In that case
+ * Return: %0 on success, -%EINVAL if the goal SCL rate is too slow. In that case
  * a best-effort divider value is returned in divs. If the target rate is
  * too high, we silently use the highest possible rate.
  */
@@ -820,13 +834,12 @@
 }
 
 /**
- * Calculate timing values for desired SCL frequency
- *
+ * rk3x_i2c_v1_calc_timings - Calculate timing values for desired SCL frequency
  * @clk_rate: I2C input clock rate
  * @t: Known I2C timing information
  * @t_calc: Caculated rk3x private timings that would be written into regs
  *
- * Returns: 0 on success, -EINVAL if the goal SCL rate is too slow. In that case
+ * Return: %0 on success, -%EINVAL if the goal SCL rate is too slow. In that case
  * a best-effort divider value is returned in divs. If the target rate is
  * too high, we silently use the highest possible rate.
  * The following formulas are v1's method to calculate timings.
@@ -983,9 +996,10 @@
 {
 	struct i2c_timings *t = &i2c->t;
 	struct rk3x_i2c_calced_timings calc;
+	unsigned long period, time_hold = (WAIT_TIMEOUT / 2) * 1000000;
 	u64 t_low_ns, t_high_ns;
 	unsigned long flags;
-	u32 val;
+	u32 val, cnt;
 	int ret;
 
 	ret = i2c->soc_data->calc_timings(clk_rate, t, &calc);
@@ -1000,6 +1014,10 @@
 	i2c_writel(i2c, val, REG_CON);
 	i2c_writel(i2c, (calc.div_high << 16) | (calc.div_low & 0xffff),
 		   REG_CLKDIV);
+
+	period = DIV_ROUND_UP(1000000000, clk_rate);
+	cnt = DIV_ROUND_UP(time_hold, period);
+	i2c_writel(i2c, cnt, REG_SCL_OE_DB);
 	spin_unlock_irqrestore(&i2c->lock, flags);
 
 	clk_disable(i2c->pclk);
@@ -1070,14 +1088,14 @@
 }
 
 /**
- * Setup I2C registers for an I2C operation specified by msgs, num.
- *
- * Must be called with i2c->lock held.
- *
+ * rk3x_i2c_setup - Setup I2C registers for an I2C operation specified by msgs, num.
+ * @i2c: target controller data
  * @msgs: I2C msgs to process
  * @num: Number of msgs
  *
- * returns: Number of I2C msgs processed or negative in case of error
+ * Must be called with i2c->lock held.
+ *
+ * Return: Number of I2C msgs processed or negative in case of error
  */
 static int rk3x_i2c_setup(struct rk3x_i2c *i2c, struct i2c_msg *msgs, int num)
 {
@@ -1165,12 +1183,30 @@
 	return !i2c->busy;
 }
 
+/*
+ * Reset i2c controller, reset all i2c registers.
+ */
+static void rk3x_i2c_reset_controller(struct rk3x_i2c *i2c)
+{
+	if (!IS_ERR_OR_NULL(i2c->reset)) {
+		reset_control_assert(i2c->reset);
+		udelay(10);
+		reset_control_deassert(i2c->reset);
+	}
+
+	if (!IS_ERR_OR_NULL(i2c->reset_apb)) {
+		reset_control_assert(i2c->reset_apb);
+		udelay(10);
+		reset_control_deassert(i2c->reset_apb);
+	}
+}
+
 static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
 				struct i2c_msg *msgs, int num, bool polling)
 {
 	struct rk3x_i2c *i2c = (struct rk3x_i2c *)adap->algo_data;
 	unsigned long timeout, flags;
-	u32 val;
+	u32 val, ipd = 0;
 	int ret = 0;
 	int i;
 
@@ -1189,7 +1225,7 @@
 	 * rk3x_i2c_setup()).
 	 */
 	for (i = 0; i < num; i += ret) {
-		unsigned long xfer_time = 100;
+		unsigned long xfer_time = WAIT_TIMEOUT;
 		int len;
 
 		ret = rk3x_i2c_setup(i2c, msgs + i, num - i);
@@ -1227,8 +1263,9 @@
 		spin_lock_irqsave(&i2c->lock, flags);
 
 		if (timeout == 0) {
+			ipd = i2c_readl(i2c, REG_IPD);
 			dev_err(i2c->dev, "timeout, ipd: 0x%02x, state: %d\n",
-				i2c_readl(i2c, REG_IPD), i2c->state);
+				ipd, i2c->state);
 
 			/* Force a STOP condition without interrupt */
 			rk3x_i2c_disable_irq(i2c);
@@ -1255,6 +1292,12 @@
 	clk_disable(i2c->clk);
 
 	spin_unlock_irqrestore(&i2c->lock, flags);
+
+	if ((ret == -ETIMEDOUT) && (ipd & REG_INT_SLV_HDSCL)) {
+		rk3x_i2c_reset_controller(i2c);
+		dev_err(i2c->dev, "SCL hold by slave, check your device.\n");
+		rk3x_i2c_adapt_div(i2c, clk_get_rate(i2c->clk));
+	}
 
 	return ret < 0 ? ret : num;
 }
@@ -1602,6 +1645,7 @@
 
 	platform_set_drvdata(pdev, i2c);
 
+	i2c->reset = devm_reset_control_get(&pdev->dev, "i2c");
 	if (!has_acpi_companion(&pdev->dev)) {
 		if (i2c->soc_data->calc_timings == rk3x_i2c_v0_calc_timings) {
 			/* Only one clock to use for bus clock and peripheral clock */
@@ -1610,6 +1654,7 @@
 		} else {
 			i2c->clk = devm_clk_get(&pdev->dev, "i2c");
 			i2c->pclk = devm_clk_get(&pdev->dev, "pclk");
+			i2c->reset_apb = devm_reset_control_get(&pdev->dev, "apb");
 		}
 
 		if (IS_ERR(i2c->clk))
diff --git a/kernel/drivers/i2c/busses/i2c-sh7760.c b/kernel/drivers/i2c/busses/i2c-sh7760.c
index 319d1fa..051b904 100644
--- a/kernel/drivers/i2c/busses/i2c-sh7760.c
+++ b/kernel/drivers/i2c/busses/i2c-sh7760.c
@@ -443,9 +443,8 @@
 		goto out0;
 	}
 
-	id = kzalloc(sizeof(struct cami2c), GFP_KERNEL);
+	id = kzalloc(sizeof(*id), GFP_KERNEL);
 	if (!id) {
-		dev_err(&pdev->dev, "no mem for private data\n");
 		ret = -ENOMEM;
 		goto out0;
 	}
diff --git a/kernel/drivers/i2c/busses/i2c-sprd.c b/kernel/drivers/i2c/busses/i2c-sprd.c
index 8ead7e0..a520aa0 100644
--- a/kernel/drivers/i2c/busses/i2c-sprd.c
+++ b/kernel/drivers/i2c/busses/i2c-sprd.c
@@ -576,12 +576,14 @@
 	struct sprd_i2c *i2c_dev = platform_get_drvdata(pdev);
 	int ret;
 
-	ret = pm_runtime_resume_and_get(i2c_dev->dev);
+	ret = pm_runtime_get_sync(i2c_dev->dev);
 	if (ret < 0)
-		return ret;
+		dev_err(&pdev->dev, "Failed to resume device (%pe)\n", ERR_PTR(ret));
 
 	i2c_del_adapter(&i2c_dev->adap);
-	clk_disable_unprepare(i2c_dev->clk);
+
+	if (ret >= 0)
+		clk_disable_unprepare(i2c_dev->clk);
 
 	pm_runtime_put_noidle(i2c_dev->dev);
 	pm_runtime_disable(i2c_dev->dev);
diff --git a/kernel/drivers/i2c/busses/i2c-tiny-usb.c b/kernel/drivers/i2c/busses/i2c-tiny-usb.c
index 7279ca0..d1fa9ff 100644
--- a/kernel/drivers/i2c/busses/i2c-tiny-usb.c
+++ b/kernel/drivers/i2c/busses/i2c-tiny-usb.c
@@ -226,10 +226,8 @@
 
 	/* allocate memory for our device state and initialize it */
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (dev == NULL) {
-		dev_err(&interface->dev, "Out of memory\n");
+	if (!dev)
 		goto error;
-	}
 
 	dev->usb_dev = usb_get_dev(interface_to_usbdev(interface));
 	dev->interface = interface;
diff --git a/kernel/drivers/i2c/busses/i2c-xgene-slimpro.c b/kernel/drivers/i2c/busses/i2c-xgene-slimpro.c
index 63cbb9c..76e9dcd 100644
--- a/kernel/drivers/i2c/busses/i2c-xgene-slimpro.c
+++ b/kernel/drivers/i2c/busses/i2c-xgene-slimpro.c
@@ -308,6 +308,9 @@
 	u32 msg[3];
 	int rc;
 
+	if (writelen > I2C_SMBUS_BLOCK_MAX)
+		return -EINVAL;
+
 	memcpy(ctx->dma_buffer, data, writelen);
 	paddr = dma_map_single(ctx->dev, ctx->dma_buffer, writelen,
 			       DMA_TO_DEVICE);
diff --git a/kernel/drivers/i2c/busses/i2c-xiic.c b/kernel/drivers/i2c/busses/i2c-xiic.c
index 3b564e6..568e97c 100644
--- a/kernel/drivers/i2c/busses/i2c-xiic.c
+++ b/kernel/drivers/i2c/busses/i2c-xiic.c
@@ -375,6 +375,9 @@
 	struct xiic_i2c *i2c = dev_id;
 	u32 pend, isr, ier;
 	u32 clr = 0;
+	int xfer_more = 0;
+	int wakeup_req = 0;
+	int wakeup_code = 0;
 
 	/* Get the interrupt Status from the IPIF. There is no clearing of
 	 * interrupts in the IPIF. Interrupts must be cleared at the source.
@@ -411,10 +414,16 @@
 		 */
 		xiic_reinit(i2c);
 
-		if (i2c->rx_msg)
-			xiic_wakeup(i2c, STATE_ERROR);
-		if (i2c->tx_msg)
-			xiic_wakeup(i2c, STATE_ERROR);
+		if (i2c->rx_msg) {
+			wakeup_req = 1;
+			wakeup_code = STATE_ERROR;
+		}
+		if (i2c->tx_msg) {
+			wakeup_req = 1;
+			wakeup_code = STATE_ERROR;
+		}
+		/* don't try to handle other events */
+		goto out;
 	}
 	if (pend & XIIC_INTR_RX_FULL_MASK) {
 		/* Receive register/FIFO is full */
@@ -448,8 +457,7 @@
 				i2c->tx_msg++;
 				dev_dbg(i2c->adap.dev.parent,
 					"%s will start next...\n", __func__);
-
-				__xiic_start_xfer(i2c);
+				xfer_more = 1;
 			}
 		}
 	}
@@ -463,11 +471,13 @@
 		if (!i2c->tx_msg)
 			goto out;
 
-		if ((i2c->nmsgs == 1) && !i2c->rx_msg &&
-			xiic_tx_space(i2c) == 0)
-			xiic_wakeup(i2c, STATE_DONE);
+		wakeup_req = 1;
+
+		if (i2c->nmsgs == 1 && !i2c->rx_msg &&
+		    xiic_tx_space(i2c) == 0)
+			wakeup_code = STATE_DONE;
 		else
-			xiic_wakeup(i2c, STATE_ERROR);
+			wakeup_code = STATE_ERROR;
 	}
 	if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) {
 		/* Transmit register/FIFO is empty or ½ empty */
@@ -491,7 +501,7 @@
 			if (i2c->nmsgs > 1) {
 				i2c->nmsgs--;
 				i2c->tx_msg++;
-				__xiic_start_xfer(i2c);
+				xfer_more = 1;
 			} else {
 				xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
 
@@ -509,6 +519,13 @@
 	dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr);
 
 	xiic_setreg32(i2c, XIIC_IISR_OFFSET, clr);
+	if (xfer_more)
+		__xiic_start_xfer(i2c);
+	if (wakeup_req)
+		xiic_wakeup(i2c, wakeup_code);
+
+	WARN_ON(xfer_more && wakeup_req);
+
 	mutex_unlock(&i2c->lock);
 	return IRQ_HANDLED;
 }
diff --git a/kernel/drivers/i2c/muxes/i2c-demux-pinctrl.c b/kernel/drivers/i2c/muxes/i2c-demux-pinctrl.c
index f7a7405..8e8688e 100644
--- a/kernel/drivers/i2c/muxes/i2c-demux-pinctrl.c
+++ b/kernel/drivers/i2c/muxes/i2c-demux-pinctrl.c
@@ -243,6 +243,10 @@
 
 		props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL);
 		props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL);
+		if (!props[i].name || !props[i].value) {
+			err = -ENOMEM;
+			goto err_rollback;
+		}
 		props[i].length = 3;
 
 		of_changeset_init(&priv->chan[i].chgset);
diff --git a/kernel/drivers/i2c/muxes/i2c-mux-reg.c b/kernel/drivers/i2c/muxes/i2c-mux-reg.c
index 0e0679f..30a6de1 100644
--- a/kernel/drivers/i2c/muxes/i2c-mux-reg.c
+++ b/kernel/drivers/i2c/muxes/i2c-mux-reg.c
@@ -183,13 +183,12 @@
 	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 &&
diff --git a/kernel/drivers/iio/Kconfig b/kernel/drivers/iio/Kconfig
index 2675533..2ed303a 100644
--- a/kernel/drivers/iio/Kconfig
+++ b/kernel/drivers/iio/Kconfig
@@ -70,6 +70,7 @@
 
 source "drivers/iio/accel/Kconfig"
 source "drivers/iio/adc/Kconfig"
+source "drivers/iio/addac/Kconfig"
 source "drivers/iio/afe/Kconfig"
 source "drivers/iio/amplifiers/Kconfig"
 source "drivers/iio/chemical/Kconfig"
diff --git a/kernel/drivers/iio/Makefile b/kernel/drivers/iio/Makefile
index 1712011..d6690e4 100644
--- a/kernel/drivers/iio/Makefile
+++ b/kernel/drivers/iio/Makefile
@@ -15,6 +15,7 @@
 
 obj-y += accel/
 obj-y += adc/
+obj-y += addac/
 obj-y += afe/
 obj-y += amplifiers/
 obj-y += buffer/
diff --git a/kernel/drivers/iio/accel/adis16201.c b/kernel/drivers/iio/accel/adis16201.c
index 84bbdfd..b4ae4f8 100644
--- a/kernel/drivers/iio/accel/adis16201.c
+++ b/kernel/drivers/iio/accel/adis16201.c
@@ -304,3 +304,4 @@
 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/kernel/drivers/iio/accel/adis16209.c b/kernel/drivers/iio/accel/adis16209.c
index 4a841ae..e6e465f 100644
--- a/kernel/drivers/iio/accel/adis16209.c
+++ b/kernel/drivers/iio/accel/adis16209.c
@@ -314,3 +314,4 @@
 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/kernel/drivers/iio/accel/hid-sensor-accel-3d.c b/kernel/drivers/iio/accel/hid-sensor-accel-3d.c
index f05840d..8d929a4 100644
--- a/kernel/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/kernel/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -277,6 +277,7 @@
 			hid_sensor_convert_timestamp(
 					&accel_state->common_attributes,
 					*(int64_t *)raw_data);
+		ret = 0;
 	break;
 	default:
 		break;
diff --git a/kernel/drivers/iio/accel/mma9551_core.c b/kernel/drivers/iio/accel/mma9551_core.c
index 666e7a0..9bb5c2f 100644
--- a/kernel/drivers/iio/accel/mma9551_core.c
+++ b/kernel/drivers/iio/accel/mma9551_core.c
@@ -296,9 +296,12 @@
 
 	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
 			       reg, NULL, 0, (u8 *)&v, 2);
+	if (ret < 0)
+		return ret;
+
 	*val = be16_to_cpu(v);
 
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL(mma9551_read_config_word);
 
@@ -354,9 +357,12 @@
 
 	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
 			       reg, NULL, 0, (u8 *)&v, 2);
+	if (ret < 0)
+		return ret;
+
 	*val = be16_to_cpu(v);
 
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL(mma9551_read_status_word);
 
diff --git a/kernel/drivers/iio/adc/ad7192.c b/kernel/drivers/iio/adc/ad7192.c
index 1b8baba..614c5e8 100644
--- a/kernel/drivers/iio/adc/ad7192.c
+++ b/kernel/drivers/iio/adc/ad7192.c
@@ -835,10 +835,6 @@
 	__AD719x_CHANNEL(_si, _channel1, -1, _address, NULL, IIO_VOLTAGE, \
 		BIT(IIO_CHAN_INFO_SCALE), ad7192_calibsys_ext_info)
 
-#define AD719x_SHORTED_CHANNEL(_si, _channel1, _address) \
-	__AD719x_CHANNEL(_si, _channel1, -1, _address, "shorted", IIO_VOLTAGE, \
-		BIT(IIO_CHAN_INFO_SCALE), ad7192_calibsys_ext_info)
-
 #define AD719x_TEMP_CHANNEL(_si, _address) \
 	__AD719x_CHANNEL(_si, 0, -1, _address, NULL, IIO_TEMP, 0, NULL)
 
@@ -846,7 +842,7 @@
 	AD719x_DIFF_CHANNEL(0, 1, 2, AD7192_CH_AIN1P_AIN2M),
 	AD719x_DIFF_CHANNEL(1, 3, 4, AD7192_CH_AIN3P_AIN4M),
 	AD719x_TEMP_CHANNEL(2, AD7192_CH_TEMP),
-	AD719x_SHORTED_CHANNEL(3, 2, AD7192_CH_AIN2P_AIN2M),
+	AD719x_DIFF_CHANNEL(3, 2, 2, AD7192_CH_AIN2P_AIN2M),
 	AD719x_CHANNEL(4, 1, AD7192_CH_AIN1),
 	AD719x_CHANNEL(5, 2, AD7192_CH_AIN2),
 	AD719x_CHANNEL(6, 3, AD7192_CH_AIN3),
@@ -860,7 +856,7 @@
 	AD719x_DIFF_CHANNEL(2, 5, 6, AD7193_CH_AIN5P_AIN6M),
 	AD719x_DIFF_CHANNEL(3, 7, 8, AD7193_CH_AIN7P_AIN8M),
 	AD719x_TEMP_CHANNEL(4, AD7193_CH_TEMP),
-	AD719x_SHORTED_CHANNEL(5, 2, AD7193_CH_AIN2P_AIN2M),
+	AD719x_DIFF_CHANNEL(5, 2, 2, AD7193_CH_AIN2P_AIN2M),
 	AD719x_CHANNEL(6, 1, AD7193_CH_AIN1),
 	AD719x_CHANNEL(7, 2, AD7193_CH_AIN2),
 	AD719x_CHANNEL(8, 3, AD7193_CH_AIN3),
diff --git a/kernel/drivers/iio/adc/ad7791.c b/kernel/drivers/iio/adc/ad7791.c
index d57ad96..f3502f1 100644
--- a/kernel/drivers/iio/adc/ad7791.c
+++ b/kernel/drivers/iio/adc/ad7791.c
@@ -253,7 +253,7 @@
 	.has_registers = true,
 	.addr_shift = 4,
 	.read_mask = BIT(3),
-	.irq_flags = IRQF_TRIGGER_LOW,
+	.irq_flags = IRQF_TRIGGER_FALLING,
 };
 
 static int ad7791_read_raw(struct iio_dev *indio_dev,
diff --git a/kernel/drivers/iio/adc/ad_sigma_delta.c b/kernel/drivers/iio/adc/ad_sigma_delta.c
index 3a6f239..496cb2b 100644
--- a/kernel/drivers/iio/adc/ad_sigma_delta.c
+++ b/kernel/drivers/iio/adc/ad_sigma_delta.c
@@ -280,10 +280,10 @@
 	unsigned int data_reg;
 	int ret = 0;
 
-	if (iio_buffer_enabled(indio_dev))
-		return -EBUSY;
+	ret = iio_device_claim_direct_mode(indio_dev);
+	if (ret)
+		return ret;
 
-	mutex_lock(&indio_dev->mlock);
 	ad_sigma_delta_set_channel(sigma_delta, chan->address);
 
 	spi_bus_lock(sigma_delta->spi->master);
@@ -322,7 +322,7 @@
 	ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
 	sigma_delta->bus_locked = false;
 	spi_bus_unlock(sigma_delta->spi->master);
-	mutex_unlock(&indio_dev->mlock);
+	iio_device_release_direct_mode(indio_dev);
 
 	if (ret)
 		return ret;
diff --git a/kernel/drivers/iio/adc/at91-sama5d2_adc.c b/kernel/drivers/iio/adc/at91-sama5d2_adc.c
index 250b78e..b806c1a 100644
--- a/kernel/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/kernel/drivers/iio/adc/at91-sama5d2_adc.c
@@ -1002,7 +1002,7 @@
 	trig = devm_iio_trigger_alloc(&indio->dev, "%s-dev%d-%s", indio->name,
 				      indio->id, trigger_name);
 	if (!trig)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	trig->dev.parent = indio->dev.parent;
 	iio_trigger_set_drvdata(trig, indio);
diff --git a/kernel/drivers/iio/adc/berlin2-adc.c b/kernel/drivers/iio/adc/berlin2-adc.c
index 8b04b95..fa2c879 100644
--- a/kernel/drivers/iio/adc/berlin2-adc.c
+++ b/kernel/drivers/iio/adc/berlin2-adc.c
@@ -289,8 +289,10 @@
 	int ret;
 
 	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
-	if (!indio_dev)
+	if (!indio_dev) {
+		of_node_put(parent_np);
 		return -ENOMEM;
+	}
 
 	priv = iio_priv(indio_dev);
 	platform_set_drvdata(pdev, indio_dev);
diff --git a/kernel/drivers/iio/adc/meson_saradc.c b/kernel/drivers/iio/adc/meson_saradc.c
index e039886..e771299 100644
--- a/kernel/drivers/iio/adc/meson_saradc.c
+++ b/kernel/drivers/iio/adc/meson_saradc.c
@@ -71,7 +71,7 @@
 	#define MESON_SAR_ADC_REG3_PANEL_DETECT_COUNT_MASK	GENMASK(20, 18)
 	#define MESON_SAR_ADC_REG3_PANEL_DETECT_FILTER_TB_MASK	GENMASK(17, 16)
 	#define MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT		10
-	#define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH		5
+	#define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH		6
 	#define MESON_SAR_ADC_REG3_BLOCK_DLY_SEL_MASK		GENMASK(9, 8)
 	#define MESON_SAR_ADC_REG3_BLOCK_DLY_MASK		GENMASK(7, 0)
 
diff --git a/kernel/drivers/iio/adc/mxs-lradc-adc.c b/kernel/drivers/iio/adc/mxs-lradc-adc.c
index c480cb4..c37e39b 100644
--- a/kernel/drivers/iio/adc/mxs-lradc-adc.c
+++ b/kernel/drivers/iio/adc/mxs-lradc-adc.c
@@ -757,13 +757,13 @@
 
 	ret = mxs_lradc_adc_trigger_init(iio);
 	if (ret)
-		goto err_trig;
+		return ret;
 
 	ret = iio_triggered_buffer_setup(iio, &iio_pollfunc_store_time,
 					 &mxs_lradc_adc_trigger_handler,
 					 &mxs_lradc_adc_buffer_ops);
 	if (ret)
-		return ret;
+		goto err_trig;
 
 	adc->vref_mv = mxs_lradc_adc_vref_mv[lradc->soc];
 
@@ -801,9 +801,9 @@
 
 err_dev:
 	mxs_lradc_adc_hw_stop(adc);
-	mxs_lradc_adc_trigger_remove(iio);
-err_trig:
 	iio_triggered_buffer_cleanup(iio);
+err_trig:
+	mxs_lradc_adc_trigger_remove(iio);
 	return ret;
 }
 
@@ -814,8 +814,8 @@
 
 	iio_device_unregister(iio);
 	mxs_lradc_adc_hw_stop(adc);
-	mxs_lradc_adc_trigger_remove(iio);
 	iio_triggered_buffer_cleanup(iio);
+	mxs_lradc_adc_trigger_remove(iio);
 
 	return 0;
 }
diff --git a/kernel/drivers/iio/adc/palmas_gpadc.c b/kernel/drivers/iio/adc/palmas_gpadc.c
index f475667..6ed0d15 100644
--- a/kernel/drivers/iio/adc/palmas_gpadc.c
+++ b/kernel/drivers/iio/adc/palmas_gpadc.c
@@ -628,7 +628,7 @@
 
 static int palmas_gpadc_remove(struct platform_device *pdev)
 {
-	struct iio_dev *indio_dev = dev_to_iio_dev(&pdev->dev);
+	struct iio_dev *indio_dev = dev_get_drvdata(&pdev->dev);
 	struct palmas_gpadc *adc = iio_priv(indio_dev);
 
 	if (adc->wakeup1_enable || adc->wakeup2_enable)
diff --git a/kernel/drivers/iio/adc/rockchip_saradc.c b/kernel/drivers/iio/adc/rockchip_saradc.c
index 4fb68c1..4aa7afc 100644
--- a/kernel/drivers/iio/adc/rockchip_saradc.c
+++ b/kernel/drivers/iio/adc/rockchip_saradc.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -68,6 +69,8 @@
 	struct clk		*clk;
 	struct completion	completion;
 	struct regulator	*vref;
+	/* lock to protect against multiple access to the device */
+	struct mutex		lock;
 	int			uv_vref;
 	struct reset_control	*reset;
 	const struct rockchip_saradc_data *data;
@@ -189,22 +192,22 @@
 #endif
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
-		mutex_lock(&indio_dev->mlock);
+		mutex_lock(&info->lock);
 
 		if (info->suspended) {
-			mutex_unlock(&indio_dev->mlock);
+			mutex_unlock(&info->lock);
 			return -EBUSY;
 		}
 
 		ret = rockchip_saradc_conversion(info, chan);
 		if (ret) {
 			rockchip_saradc_power_down(info);
-			mutex_unlock(&indio_dev->mlock);
+			mutex_unlock(&info->lock);
 			return ret;
 		}
 
 		*val = info->last_val;
-		mutex_unlock(&indio_dev->mlock);
+		mutex_unlock(&info->lock);
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
 		/* It is a dummy regulator */
@@ -476,7 +479,7 @@
 	int ret;
 	int i, j = 0;
 
-	mutex_lock(&i_dev->mlock);
+	mutex_lock(&info->lock);
 
 	for_each_set_bit(i, i_dev->active_scan_mask, i_dev->masklength) {
 		const struct iio_chan_spec *chan = &i_dev->channels[i];
@@ -493,7 +496,7 @@
 
 	iio_push_to_buffers_with_timestamp(i_dev, &data, iio_get_time_ns(i_dev));
 out:
-	mutex_unlock(&i_dev->mlock);
+	mutex_unlock(&info->lock);
 
 	iio_trigger_notify_done(i_dev->trig);
 
@@ -784,6 +787,8 @@
 		return ret;
 	}
 #endif
+	mutex_init(&info->lock);
+
 	return devm_iio_device_register(&pdev->dev, indio_dev);
 }
 
@@ -794,14 +799,14 @@
 	struct rockchip_saradc *info = iio_priv(indio_dev);
 
 	/* Avoid reading saradc when suspending */
-	mutex_lock(&indio_dev->mlock);
+	mutex_lock(&info->lock);
 
 	clk_disable_unprepare(info->clk);
 	clk_disable_unprepare(info->pclk);
 	regulator_disable(info->vref);
 
 	info->suspended = true;
-	mutex_unlock(&indio_dev->mlock);
+	mutex_unlock(&info->lock);
 
 	return 0;
 }
diff --git a/kernel/drivers/iio/adc/stm32-dfsdm-adc.c b/kernel/drivers/iio/adc/stm32-dfsdm-adc.c
index 9234f14..171d73e 100644
--- a/kernel/drivers/iio/adc/stm32-dfsdm-adc.c
+++ b/kernel/drivers/iio/adc/stm32-dfsdm-adc.c
@@ -1521,6 +1521,7 @@
 	},
 	{}
 };
+MODULE_DEVICE_TABLE(of, stm32_dfsdm_adc_match);
 
 static int stm32_dfsdm_adc_probe(struct platform_device *pdev)
 {
diff --git a/kernel/drivers/iio/adc/stx104.c b/kernel/drivers/iio/adc/stx104.c
index 55bd2dc..b658a75 100644
--- a/kernel/drivers/iio/adc/stx104.c
+++ b/kernel/drivers/iio/adc/stx104.c
@@ -15,7 +15,9 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/mutex.h>
 #include <linux/spinlock.h>
+#include <linux/types.h>
 
 #define STX104_OUT_CHAN(chan) {				\
 	.type = IIO_VOLTAGE,				\
@@ -45,13 +47,37 @@
 MODULE_PARM_DESC(base, "Apex Embedded Systems STX104 base addresses");
 
 /**
+ * struct stx104_reg - device register structure
+ * @ssr_ad:	Software Strobe Register and ADC Data
+ * @achan:	ADC Channel
+ * @dio:	Digital I/O
+ * @dac:	DAC Channels
+ * @cir_asr:	Clear Interrupts and ADC Status
+ * @acr:	ADC Control
+ * @pccr_fsh:	Pacer Clock Control and FIFO Status MSB
+ * @acfg:	ADC Configuration
+ */
+struct stx104_reg {
+	u16 ssr_ad;
+	u8 achan;
+	u8 dio;
+	u16 dac[2];
+	u8 cir_asr;
+	u8 acr;
+	u8 pccr_fsh;
+	u8 acfg;
+};
+
+/**
  * struct stx104_iio - IIO device private data structure
+ * @lock: synchronization lock to prevent I/O race conditions
  * @chan_out_states:	channels' output states
- * @base:		base port address of the IIO device
+ * @reg:		I/O address offset for the device registers
  */
 struct stx104_iio {
+	struct mutex lock;
 	unsigned int chan_out_states[STX104_NUM_OUT_CHAN];
-	unsigned int base;
+	struct stx104_reg __iomem *reg;
 };
 
 /**
@@ -64,7 +90,7 @@
 struct stx104_gpio {
 	struct gpio_chip chip;
 	spinlock_t lock;
-	unsigned int base;
+	u8 __iomem *base;
 	unsigned int out_state;
 };
 
@@ -72,6 +98,7 @@
 	struct iio_chan_spec const *chan, int *val, int *val2, long mask)
 {
 	struct stx104_iio *const priv = iio_priv(indio_dev);
+	struct stx104_reg __iomem *const reg = priv->reg;
 	unsigned int adc_config;
 	int adbu;
 	int gain;
@@ -79,7 +106,7 @@
 	switch (mask) {
 	case IIO_CHAN_INFO_HARDWAREGAIN:
 		/* get gain configuration */
-		adc_config = inb(priv->base + 11);
+		adc_config = ioread8(&reg->acfg);
 		gain = adc_config & 0x3;
 
 		*val = 1 << gain;
@@ -90,25 +117,31 @@
 			return IIO_VAL_INT;
 		}
 
+		mutex_lock(&priv->lock);
+
 		/* select ADC channel */
-		outb(chan->channel | (chan->channel << 4), priv->base + 2);
+		iowrite8(chan->channel | (chan->channel << 4), &reg->achan);
 
-		/* trigger ADC sample capture and wait for completion */
-		outb(0, priv->base);
-		while (inb(priv->base + 8) & BIT(7));
+		/* trigger ADC sample capture by writing to the 8-bit
+		 * Software Strobe Register and wait for completion
+		 */
+		iowrite8(0, &reg->ssr_ad);
+		while (ioread8(&reg->cir_asr) & BIT(7));
 
-		*val = inw(priv->base);
+		*val = ioread16(&reg->ssr_ad);
+
+		mutex_unlock(&priv->lock);
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_OFFSET:
 		/* get ADC bipolar/unipolar configuration */
-		adc_config = inb(priv->base + 11);
+		adc_config = ioread8(&reg->acfg);
 		adbu = !(adc_config & BIT(2));
 
 		*val = -32768 * adbu;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
 		/* get ADC bipolar/unipolar and gain configuration */
-		adc_config = inb(priv->base + 11);
+		adc_config = ioread8(&reg->acfg);
 		adbu = !(adc_config & BIT(2));
 		gain = adc_config & 0x3;
 
@@ -130,16 +163,16 @@
 		/* Only four gain states (x1, x2, x4, x8) */
 		switch (val) {
 		case 1:
-			outb(0, priv->base + 11);
+			iowrite8(0, &priv->reg->acfg);
 			break;
 		case 2:
-			outb(1, priv->base + 11);
+			iowrite8(1, &priv->reg->acfg);
 			break;
 		case 4:
-			outb(2, priv->base + 11);
+			iowrite8(2, &priv->reg->acfg);
 			break;
 		case 8:
-			outb(3, priv->base + 11);
+			iowrite8(3, &priv->reg->acfg);
 			break;
 		default:
 			return -EINVAL;
@@ -152,9 +185,12 @@
 			if ((unsigned int)val > 65535)
 				return -EINVAL;
 
-			priv->chan_out_states[chan->channel] = val;
-			outw(val, priv->base + 4 + 2 * chan->channel);
+			mutex_lock(&priv->lock);
 
+			priv->chan_out_states[chan->channel] = val;
+			iowrite16(val, &priv->reg->dac[chan->channel]);
+
+			mutex_unlock(&priv->lock);
 			return 0;
 		}
 		return -EINVAL;
@@ -222,7 +258,7 @@
 	if (offset >= 4)
 		return -EINVAL;
 
-	return !!(inb(stx104gpio->base) & BIT(offset));
+	return !!(ioread8(stx104gpio->base) & BIT(offset));
 }
 
 static int stx104_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
@@ -230,7 +266,7 @@
 {
 	struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip);
 
-	*bits = inb(stx104gpio->base);
+	*bits = ioread8(stx104gpio->base);
 
 	return 0;
 }
@@ -252,7 +288,7 @@
 	else
 		stx104gpio->out_state &= ~mask;
 
-	outb(stx104gpio->out_state, stx104gpio->base);
+	iowrite8(stx104gpio->out_state, stx104gpio->base);
 
 	spin_unlock_irqrestore(&stx104gpio->lock, flags);
 }
@@ -279,7 +315,7 @@
 
 	stx104gpio->out_state &= ~*mask;
 	stx104gpio->out_state |= *mask & *bits;
-	outb(stx104gpio->out_state, stx104gpio->base);
+	iowrite8(stx104gpio->out_state, stx104gpio->base);
 
 	spin_unlock_irqrestore(&stx104gpio->lock, flags);
 }
@@ -306,11 +342,16 @@
 		return -EBUSY;
 	}
 
+	priv = iio_priv(indio_dev);
+	priv->reg = devm_ioport_map(dev, base[id], STX104_EXTENT);
+	if (!priv->reg)
+		return -ENOMEM;
+
 	indio_dev->info = &stx104_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
 	/* determine if differential inputs */
-	if (inb(base[id] + 8) & BIT(5)) {
+	if (ioread8(&priv->reg->cir_asr) & BIT(5)) {
 		indio_dev->num_channels = ARRAY_SIZE(stx104_channels_diff);
 		indio_dev->channels = stx104_channels_diff;
 	} else {
@@ -320,18 +361,17 @@
 
 	indio_dev->name = dev_name(dev);
 
-	priv = iio_priv(indio_dev);
-	priv->base = base[id];
+	mutex_init(&priv->lock);
 
 	/* configure device for software trigger operation */
-	outb(0, base[id] + 9);
+	iowrite8(0, &priv->reg->acr);
 
 	/* initialize gain setting to x1 */
-	outb(0, base[id] + 11);
+	iowrite8(0, &priv->reg->acfg);
 
 	/* initialize DAC output to 0V */
-	outw(0, base[id] + 4);
-	outw(0, base[id] + 6);
+	iowrite16(0, &priv->reg->dac[0]);
+	iowrite16(0, &priv->reg->dac[1]);
 
 	stx104gpio->chip.label = dev_name(dev);
 	stx104gpio->chip.parent = dev;
@@ -346,7 +386,7 @@
 	stx104gpio->chip.get_multiple = stx104_gpio_get_multiple;
 	stx104gpio->chip.set = stx104_gpio_set;
 	stx104gpio->chip.set_multiple = stx104_gpio_set_multiple;
-	stx104gpio->base = base[id] + 3;
+	stx104gpio->base = &priv->reg->dio;
 	stx104gpio->out_state = 0x0;
 
 	spin_lock_init(&stx104gpio->lock);
diff --git a/kernel/drivers/iio/adc/ti-adc128s052.c b/kernel/drivers/iio/adc/ti-adc128s052.c
index 83c1ae0..8618ae7 100644
--- a/kernel/drivers/iio/adc/ti-adc128s052.c
+++ b/kernel/drivers/iio/adc/ti-adc128s052.c
@@ -193,13 +193,13 @@
 }
 
 static const struct of_device_id adc128_of_match[] = {
-	{ .compatible = "ti,adc128s052", },
-	{ .compatible = "ti,adc122s021", },
-	{ .compatible = "ti,adc122s051", },
-	{ .compatible = "ti,adc122s101", },
-	{ .compatible = "ti,adc124s021", },
-	{ .compatible = "ti,adc124s051", },
-	{ .compatible = "ti,adc124s101", },
+	{ .compatible = "ti,adc128s052", .data = (void*)0L, },
+	{ .compatible = "ti,adc122s021", .data = (void*)1L, },
+	{ .compatible = "ti,adc122s051", .data = (void*)1L, },
+	{ .compatible = "ti,adc122s101", .data = (void*)1L, },
+	{ .compatible = "ti,adc124s021", .data = (void*)2L, },
+	{ .compatible = "ti,adc124s051", .data = (void*)2L, },
+	{ .compatible = "ti,adc124s101", .data = (void*)2L, },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, adc128_of_match);
diff --git a/kernel/drivers/iio/adc/ti-ads7950.c b/kernel/drivers/iio/adc/ti-ads7950.c
index a2b83f0..d4583b7 100644
--- a/kernel/drivers/iio/adc/ti-ads7950.c
+++ b/kernel/drivers/iio/adc/ti-ads7950.c
@@ -634,6 +634,7 @@
 	st->chip.label = dev_name(&st->spi->dev);
 	st->chip.parent = &st->spi->dev;
 	st->chip.owner = THIS_MODULE;
+	st->chip.can_sleep = true;
 	st->chip.base = -1;
 	st->chip.ngpio = TI_ADS7950_NUM_GPIOS;
 	st->chip.get_direction = ti_ads7950_get_direction;
diff --git a/kernel/drivers/iio/adc/twl6030-gpadc.c b/kernel/drivers/iio/adc/twl6030-gpadc.c
index 256177b..024bdc1 100644
--- a/kernel/drivers/iio/adc/twl6030-gpadc.c
+++ b/kernel/drivers/iio/adc/twl6030-gpadc.c
@@ -57,6 +57,18 @@
 #define TWL6030_GPADCS				BIT(1)
 #define TWL6030_GPADCR				BIT(0)
 
+#define USB_VBUS_CTRL_SET			0x04
+#define USB_ID_CTRL_SET				0x06
+
+#define TWL6030_MISC1				0xE4
+#define VBUS_MEAS				0x01
+#define ID_MEAS					0x01
+
+#define VAC_MEAS                0x04
+#define VBAT_MEAS               0x02
+#define BB_MEAS                 0x01
+
+
 /**
  * struct twl6030_chnl_calib - channel calibration
  * @gain:		slope coefficient for ideal curve
@@ -927,6 +939,26 @@
 		return ret;
 	}
 
+	ret = twl_i2c_write_u8(TWL_MODULE_USB, VBUS_MEAS, USB_VBUS_CTRL_SET);
+	if (ret < 0) {
+		dev_err(dev, "failed to wire up inputs\n");
+		return ret;
+	}
+
+	ret = twl_i2c_write_u8(TWL_MODULE_USB, ID_MEAS, USB_ID_CTRL_SET);
+	if (ret < 0) {
+		dev_err(dev, "failed to wire up inputs\n");
+		return ret;
+	}
+
+	ret = twl_i2c_write_u8(TWL6030_MODULE_ID0,
+				VBAT_MEAS | BB_MEAS | VAC_MEAS,
+				TWL6030_MISC1);
+	if (ret < 0) {
+		dev_err(dev, "failed to wire up inputs\n");
+		return ret;
+	}
+
 	indio_dev->name = DRIVER_NAME;
 	indio_dev->info = &twl6030_gpadc_iio_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
diff --git a/kernel/drivers/iio/addac/Kconfig b/kernel/drivers/iio/addac/Kconfig
new file mode 100644
index 0000000..2e64d77
--- /dev/null
+++ b/kernel/drivers/iio/addac/Kconfig
@@ -0,0 +1,8 @@
+#
+# ADC DAC drivers
+#
+# When adding new entries keep the list in alphabetical order
+
+menu "Analog to digital and digital to analog converters"
+
+endmenu
diff --git a/kernel/drivers/iio/addac/Makefile b/kernel/drivers/iio/addac/Makefile
new file mode 100644
index 0000000..b888b9e
--- /dev/null
+++ b/kernel/drivers/iio/addac/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for industrial I/O ADDAC drivers
+#
+
+# When adding new entries keep the list in alphabetical order
diff --git a/kernel/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/kernel/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
index e3f5077..829077b 100644
--- a/kernel/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
+++ b/kernel/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
@@ -263,7 +263,7 @@
 	platform_set_drvdata(pdev, indio_dev);
 
 	state->ec = ec->ec_dev;
-	state->msg = devm_kzalloc(&pdev->dev,
+	state->msg = devm_kzalloc(&pdev->dev, sizeof(*state->msg) +
 				max((u16)sizeof(struct ec_params_motion_sense),
 				state->ec->max_response), GFP_KERNEL);
 	if (!state->msg)
diff --git a/kernel/drivers/iio/dac/Makefile b/kernel/drivers/iio/dac/Makefile
index 2fc4811..09506d2 100644
--- a/kernel/drivers/iio/dac/Makefile
+++ b/kernel/drivers/iio/dac/Makefile
@@ -16,7 +16,7 @@
 obj-$(CONFIG_AD5592R) += ad5592r.o
 obj-$(CONFIG_AD5593R) += ad5593r.o
 obj-$(CONFIG_AD5755) += ad5755.o
-obj-$(CONFIG_AD5755) += ad5758.o
+obj-$(CONFIG_AD5758) += ad5758.o
 obj-$(CONFIG_AD5761) += ad5761.o
 obj-$(CONFIG_AD5764) += ad5764.o
 obj-$(CONFIG_AD5770R) += ad5770r.o
diff --git a/kernel/drivers/iio/dac/cio-dac.c b/kernel/drivers/iio/dac/cio-dac.c
index 9581356..77a6916 100644
--- a/kernel/drivers/iio/dac/cio-dac.c
+++ b/kernel/drivers/iio/dac/cio-dac.c
@@ -66,8 +66,8 @@
 	if (mask != IIO_CHAN_INFO_RAW)
 		return -EINVAL;
 
-	/* DAC can only accept up to a 16-bit value */
-	if ((unsigned int)val > 65535)
+	/* DAC can only accept up to a 12-bit value */
+	if ((unsigned int)val > 4095)
 		return -EINVAL;
 
 	priv->chan_out_states[chan->channel] = val;
diff --git a/kernel/drivers/iio/dac/mcp4725.c b/kernel/drivers/iio/dac/mcp4725.c
index beb9a15..0c0e726 100644
--- a/kernel/drivers/iio/dac/mcp4725.c
+++ b/kernel/drivers/iio/dac/mcp4725.c
@@ -47,12 +47,18 @@
 	struct mcp4725_data *data = iio_priv(i2c_get_clientdata(
 		to_i2c_client(dev)));
 	u8 outbuf[2];
+	int ret;
 
 	outbuf[0] = (data->powerdown_mode + 1) << 4;
 	outbuf[1] = 0;
 	data->powerdown = true;
 
-	return i2c_master_send(data->client, outbuf, 2);
+	ret = i2c_master_send(data->client, outbuf, 2);
+	if (ret < 0)
+		return ret;
+	else if (ret != 2)
+		return -EIO;
+	return 0;
 }
 
 static int __maybe_unused mcp4725_resume(struct device *dev)
@@ -60,13 +66,19 @@
 	struct mcp4725_data *data = iio_priv(i2c_get_clientdata(
 		to_i2c_client(dev)));
 	u8 outbuf[2];
+	int ret;
 
 	/* restore previous DAC value */
 	outbuf[0] = (data->dac_value >> 8) & 0xf;
 	outbuf[1] = data->dac_value & 0xff;
 	data->powerdown = false;
 
-	return i2c_master_send(data->client, outbuf, 2);
+	ret = i2c_master_send(data->client, outbuf, 2);
+	if (ret < 0)
+		return ret;
+	else if (ret != 2)
+		return -EIO;
+	return 0;
 }
 static SIMPLE_DEV_PM_OPS(mcp4725_pm_ops, mcp4725_suspend, mcp4725_resume);
 
diff --git a/kernel/drivers/iio/gyro/adis16136.c b/kernel/drivers/iio/gyro/adis16136.c
index a11ae9d..74db8ed 100644
--- a/kernel/drivers/iio/gyro/adis16136.c
+++ b/kernel/drivers/iio/gyro/adis16136.c
@@ -599,3 +599,4 @@
 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/kernel/drivers/iio/gyro/adis16260.c b/kernel/drivers/iio/gyro/adis16260.c
index e7c9a3e..1e45d93 100644
--- a/kernel/drivers/iio/gyro/adis16260.c
+++ b/kernel/drivers/iio/gyro/adis16260.c
@@ -438,3 +438,4 @@
 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/kernel/drivers/iio/imu/adis.c b/kernel/drivers/iio/imu/adis.c
index 715eef8..e982181 100644
--- a/kernel/drivers/iio/imu/adis.c
+++ b/kernel/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,14 +118,14 @@
 	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;
 	}
 
 	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)
@@ -134,8 +134,8 @@
  * @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,11 +205,11 @@
 	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:
@@ -222,7 +222,7 @@
 
 	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,17 +247,17 @@
 
 	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
 
-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,36 +265,41 @@
 			*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);
+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;
-	uint16_t msc;
+	int ret;
+	u16 msc;
 
-	mutex_lock(&adis->state_lock);
+	if (adis->data->enable_irq)
+		return adis->data->enable_irq(adis, enable);
 
-	if (adis->data->enable_irq) {
-		ret = adis->data->enable_irq(adis, enable);
-		goto out_unlock;
+	if (adis->data->unmasked_drdy) {
+		if (enable)
+			enable_irq(adis->spi->irq);
+		else
+			disable_irq(adis->spi->irq);
+
+		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;
@@ -303,13 +308,9 @@
 	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(adis_enable_irq);
+EXPORT_SYMBOL_NS(__adis_enable_irq, IIO_ADISLIB);
 
 /**
  * __adis_check_status() - Check the device for error conditions (unlocked)
@@ -319,7 +320,7 @@
  */
 int __adis_check_status(struct adis *adis)
 {
-	uint16_t status;
+	u16 status;
 	int ret;
 	int i;
 
@@ -341,7 +342,7 @@
 
 	return -EIO;
 }
-EXPORT_SYMBOL_GPL(__adis_check_status);
+EXPORT_SYMBOL_NS_GPL(__adis_check_status, IIO_ADISLIB);
 
 /**
  * __adis_reset() - Reset the device (unlocked version)
@@ -355,7 +356,7 @@
 	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;
@@ -365,7 +366,7 @@
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(__adis_reset);
+EXPORT_SYMBOL_NS_GPL(__adis_reset, IIO_ADIS_LIB);
 
 static int adis_self_test(struct adis *adis)
 {
@@ -411,7 +412,7 @@
 {
 	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 */
@@ -420,7 +421,7 @@
 		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);
@@ -434,7 +435,13 @@
 	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;
@@ -450,7 +457,7 @@
 
 	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
@@ -468,7 +475,8 @@
  * 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;
@@ -477,7 +485,7 @@
 	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;
 
@@ -497,7 +505,7 @@
 	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
@@ -512,7 +520,7 @@
  * 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");
@@ -534,7 +542,7 @@
 
 	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/kernel/drivers/iio/imu/adis16400.c b/kernel/drivers/iio/imu/adis16400.c
index 4aff164..c525511 100644
--- a/kernel/drivers/iio/imu/adis16400.c
+++ b/kernel/drivers/iio/imu/adis16400.c
@@ -1252,3 +1252,4 @@
 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/kernel/drivers/iio/imu/adis16460.c b/kernel/drivers/iio/imu/adis16460.c
index 74a161e..a28143a 100644
--- a/kernel/drivers/iio/imu/adis16460.c
+++ b/kernel/drivers/iio/imu/adis16460.c
@@ -403,11 +403,11 @@
 	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)
@@ -447,3 +447,4 @@
 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/kernel/drivers/iio/imu/adis16475.c b/kernel/drivers/iio/imu/adis16475.c
index 3c4e4de..aed1cf3 100644
--- a/kernel/drivers/iio/imu/adis16475.c
+++ b/kernel/drivers/iio/imu/adis16475.c
@@ -1196,6 +1196,9 @@
 		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 @@
 	if (ret)
 		return ret;
 
-	adis16475_enable_irq(&st->adis, false);
-
 	ret = devm_iio_device_register(&spi->dev, indio_dev);
 	if (ret)
 		return ret;
@@ -1323,3 +1324,4 @@
 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/kernel/drivers/iio/imu/adis16480.c b/kernel/drivers/iio/imu/adis16480.c
index dfe86c5..c6a3d9a 100644
--- a/kernel/drivers/iio/imu/adis16480.c
+++ b/kernel/drivers/iio/imu/adis16480.c
@@ -1340,3 +1340,4 @@
 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/kernel/drivers/iio/imu/adis_buffer.c b/kernel/drivers/iio/imu/adis_buffer.c
index 175af15..7cc1145 100644
--- a/kernel/drivers/iio/imu/adis_buffer.c
+++ b/kernel/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 @@
 }
 
 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;
@@ -120,7 +120,7 @@
 
 	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)
 {
@@ -149,7 +149,7 @@
 	}
 
 	iio_push_to_buffers_with_timestamp(indio_dev, adis->buffer,
-		pf->timestamp);
+					   pf->timestamp);
 
 	iio_trigger_notify_done(indio_dev->trig);
 
@@ -202,5 +202,5 @@
 	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/kernel/drivers/iio/imu/adis_trigger.c b/kernel/drivers/iio/imu/adis_trigger.c
index 64e0ba5..80adfa5 100644
--- a/kernel/drivers/iio/imu/adis_trigger.c
+++ b/kernel/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);
 
@@ -36,18 +35,23 @@
 
 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
 	 * 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;
@@ -88,5 +92,5 @@
 
 	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/kernel/drivers/iio/imu/fxos8700_core.c b/kernel/drivers/iio/imu/fxos8700_core.c
index ab28818..04d3778 100644
--- a/kernel/drivers/iio/imu/fxos8700_core.c
+++ b/kernel/drivers/iio/imu/fxos8700_core.c
@@ -10,6 +10,7 @@
 #include <linux/regmap.h>
 #include <linux/acpi.h>
 #include <linux/bitops.h>
+#include <linux/bitfield.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
@@ -144,9 +145,8 @@
 #define FXOS8700_NVM_DATA_BNK0      0xa7
 
 /* Bit definitions for FXOS8700_CTRL_REG1 */
-#define FXOS8700_CTRL_ODR_MSK       0x38
 #define FXOS8700_CTRL_ODR_MAX       0x00
-#define FXOS8700_CTRL_ODR_MIN       GENMASK(4, 3)
+#define FXOS8700_CTRL_ODR_MSK       GENMASK(5, 3)
 
 /* Bit definitions for FXOS8700_M_CTRL_REG1 */
 #define FXOS8700_HMS_MASK           GENMASK(1, 0)
@@ -320,7 +320,7 @@
 	switch (iio_type) {
 	case IIO_ACCEL:
 		return FXOS8700_ACCEL;
-	case IIO_ANGL_VEL:
+	case IIO_MAGN:
 		return FXOS8700_MAGN;
 	default:
 		return -EINVAL;
@@ -345,13 +345,33 @@
 static int fxos8700_set_scale(struct fxos8700_data *data,
 			      enum fxos8700_sensor t, int uscale)
 {
-	int i;
+	int i, ret, val;
+	bool active_mode;
 	static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale);
 	struct device *dev = regmap_get_device(data->regmap);
 
 	if (t == FXOS8700_MAGN) {
-		dev_err(dev, "Magnetometer scale is locked at 1200uT\n");
+		dev_err(dev, "Magnetometer scale is locked at 0.001Gs\n");
 		return -EINVAL;
+	}
+
+	/*
+	 * When device is in active mode, it failed to set an ACCEL
+	 * full-scale range(2g/4g/8g) in FXOS8700_XYZ_DATA_CFG.
+	 * This is not align with the datasheet, but it is a fxos8700
+	 * chip behavier. Set the device in standby mode before setting
+	 * an ACCEL full-scale range.
+	 */
+	ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val);
+	if (ret)
+		return ret;
+
+	active_mode = val & FXOS8700_ACTIVE;
+	if (active_mode) {
+		ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1,
+				   val & ~FXOS8700_ACTIVE);
+		if (ret)
+			return ret;
 	}
 
 	for (i = 0; i < scale_num; i++)
@@ -361,8 +381,12 @@
 	if (i == scale_num)
 		return -EINVAL;
 
-	return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG,
+	ret = regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG,
 			    fxos8700_accel_scale[i].bits);
+	if (ret)
+		return ret;
+	return regmap_write(data->regmap, FXOS8700_CTRL_REG1,
+				  active_mode);
 }
 
 static int fxos8700_get_scale(struct fxos8700_data *data,
@@ -372,7 +396,7 @@
 	static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale);
 
 	if (t == FXOS8700_MAGN) {
-		*uscale = 1200; /* Magnetometer is locked at 1200uT */
+		*uscale = 1000; /* Magnetometer is locked at 0.001Gs */
 		return 0;
 	}
 
@@ -394,22 +418,61 @@
 			     int axis, int *val)
 {
 	u8 base, reg;
+	s16 tmp;
 	int ret;
-	enum fxos8700_sensor type = fxos8700_to_sensor(chan_type);
 
-	base = type ? FXOS8700_OUT_X_MSB : FXOS8700_M_OUT_X_MSB;
+	/*
+	 * Different register base addresses varies with channel types.
+	 * This bug hasn't been noticed before because using an enum is
+	 * really hard to read. Use an a switch statement to take over that.
+	 */
+	switch (chan_type) {
+	case IIO_ACCEL:
+		base = FXOS8700_OUT_X_MSB;
+		break;
+	case IIO_MAGN:
+		base = FXOS8700_M_OUT_X_MSB;
+		break;
+	default:
+		return -EINVAL;
+	}
 
 	/* Block read 6 bytes of device output registers to avoid data loss */
 	ret = regmap_bulk_read(data->regmap, base, data->buf,
-			       FXOS8700_DATA_BUF_SIZE);
+			       sizeof(data->buf));
 	if (ret)
 		return ret;
 
 	/* Convert axis to buffer index */
 	reg = axis - IIO_MOD_X;
 
+	/*
+	 * Convert to native endianness. The accel data and magn data
+	 * are signed, so a forced type conversion is needed.
+	 */
+	tmp = be16_to_cpu(data->buf[reg]);
+
+	/*
+	 * ACCEL output data registers contain the X-axis, Y-axis, and Z-axis
+	 * 14-bit left-justified sample data and MAGN output data registers
+	 * contain the X-axis, Y-axis, and Z-axis 16-bit sample data. Apply
+	 * a signed 2 bits right shift to the readback raw data from ACCEL
+	 * output data register and keep that from MAGN sensor as the origin.
+	 * Value should be extended to 32 bit.
+	 */
+	switch (chan_type) {
+	case IIO_ACCEL:
+		tmp = tmp >> 2;
+		break;
+	case IIO_MAGN:
+		/* Nothing to do */
+		break;
+	default:
+		return -EINVAL;
+	}
+
 	/* Convert to native endianness */
-	*val = sign_extend32(be16_to_cpu(data->buf[reg]), 15);
+	*val = sign_extend32(tmp, 15);
 
 	return 0;
 }
@@ -445,10 +508,9 @@
 	if (i >= odr_num)
 		return -EINVAL;
 
-	return regmap_update_bits(data->regmap,
-				  FXOS8700_CTRL_REG1,
-				  FXOS8700_CTRL_ODR_MSK + FXOS8700_ACTIVE,
-				  fxos8700_odr[i].bits << 3 | active_mode);
+	val &= ~FXOS8700_CTRL_ODR_MSK;
+	val |= FIELD_PREP(FXOS8700_CTRL_ODR_MSK, fxos8700_odr[i].bits) | FXOS8700_ACTIVE;
+	return regmap_write(data->regmap, FXOS8700_CTRL_REG1, val);
 }
 
 static int fxos8700_get_odr(struct fxos8700_data *data, enum fxos8700_sensor t,
@@ -461,7 +523,7 @@
 	if (ret)
 		return ret;
 
-	val &= FXOS8700_CTRL_ODR_MSK;
+	val = FIELD_GET(FXOS8700_CTRL_ODR_MSK, val);
 
 	for (i = 0; i < odr_num; i++)
 		if (val == fxos8700_odr[i].bits)
@@ -526,7 +588,7 @@
 static IIO_CONST_ATTR(in_magn_sampling_frequency_available,
 		      "1.5625 6.25 12.5 50 100 200 400 800");
 static IIO_CONST_ATTR(in_accel_scale_available, "0.000244 0.000488 0.000976");
-static IIO_CONST_ATTR(in_magn_scale_available, "0.000001200");
+static IIO_CONST_ATTR(in_magn_scale_available, "0.001000");
 
 static struct attribute *fxos8700_attrs[] = {
 	&iio_const_attr_in_accel_sampling_frequency_available.dev_attr.attr,
@@ -592,14 +654,19 @@
 	if (ret)
 		return ret;
 
-	/* Max ODR (800Hz individual or 400Hz hybrid), active mode */
-	ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1,
-			   FXOS8700_CTRL_ODR_MAX | FXOS8700_ACTIVE);
+	/*
+	 * Set max full-scale range (+/-8G) for ACCEL sensor in chip
+	 * initialization then activate the device.
+	 */
+	ret = regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, MODE_8G);
 	if (ret)
 		return ret;
 
-	/* Set for max full-scale range (+/-8G) */
-	return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, MODE_8G);
+	/* Max ODR (800Hz individual or 400Hz hybrid), active mode */
+	return regmap_update_bits(data->regmap, FXOS8700_CTRL_REG1,
+				FXOS8700_CTRL_ODR_MSK | FXOS8700_ACTIVE,
+				FIELD_PREP(FXOS8700_CTRL_ODR_MSK, FXOS8700_CTRL_ODR_MAX) |
+				FXOS8700_ACTIVE);
 }
 
 static void fxos8700_chip_uninit(void *data)
diff --git a/kernel/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c b/kernel/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
index 99576b2..32d7f83 100644
--- a/kernel/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
+++ b/kernel/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
@@ -275,8 +275,13 @@
 {
 	struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
 	struct device *dev = regmap_get_device(st->map);
+	struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
 
 	pm_runtime_get_sync(dev);
+
+	mutex_lock(&st->lock);
+	inv_icm42600_timestamp_reset(ts);
+	mutex_unlock(&st->lock);
 
 	return 0;
 }
@@ -375,7 +380,6 @@
 	struct device *dev = regmap_get_device(st->map);
 	unsigned int sensor;
 	unsigned int *watermark;
-	struct inv_icm42600_timestamp *ts;
 	struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
 	unsigned int sleep_temp = 0;
 	unsigned int sleep_sensor = 0;
@@ -385,11 +389,9 @@
 	if (indio_dev == st->indio_gyro) {
 		sensor = INV_ICM42600_SENSOR_GYRO;
 		watermark = &st->fifo.watermark.gyro;
-		ts = iio_priv(st->indio_gyro);
 	} else if (indio_dev == st->indio_accel) {
 		sensor = INV_ICM42600_SENSOR_ACCEL;
 		watermark = &st->fifo.watermark.accel;
-		ts = iio_priv(st->indio_accel);
 	} else {
 		return -EINVAL;
 	}
@@ -416,8 +418,6 @@
 	/* if FIFO is off, turn temperature off */
 	if (!st->fifo.on)
 		ret = inv_icm42600_set_temp_conf(st, false, &sleep_temp);
-
-	inv_icm42600_timestamp_reset(ts);
 
 out_unlock:
 	mutex_unlock(&st->lock);
diff --git a/kernel/drivers/iio/light/cm32181.c b/kernel/drivers/iio/light/cm32181.c
index 9764994..c14a630 100644
--- a/kernel/drivers/iio/light/cm32181.c
+++ b/kernel/drivers/iio/light/cm32181.c
@@ -429,6 +429,14 @@
 	.attrs			= &cm32181_attribute_group,
 };
 
+static void cm32181_unregister_dummy_client(void *data)
+{
+	struct i2c_client *client = data;
+
+	/* Unregister the dummy client */
+	i2c_unregister_device(client);
+}
+
 static int cm32181_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
@@ -458,6 +466,10 @@
 		client = i2c_acpi_new_device(dev, 1, &board_info);
 		if (IS_ERR(client))
 			return PTR_ERR(client);
+
+		ret = devm_add_action_or_reset(dev, cm32181_unregister_dummy_client, client);
+		if (ret)
+			return ret;
 	}
 
 	cm32181 = iio_priv(indio_dev);
diff --git a/kernel/drivers/iio/light/max44009.c b/kernel/drivers/iio/light/max44009.c
index 801e5a0..f3648f2 100644
--- a/kernel/drivers/iio/light/max44009.c
+++ b/kernel/drivers/iio/light/max44009.c
@@ -528,6 +528,12 @@
 	return devm_iio_device_register(&client->dev, indio_dev);
 }
 
+static const struct of_device_id max44009_of_match[] = {
+	{ .compatible = "maxim,max44009" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, max44009_of_match);
+
 static const struct i2c_device_id max44009_id[] = {
 	{ "max44009", 0 },
 	{ }
@@ -537,17 +543,12 @@
 static struct i2c_driver max44009_driver = {
 	.driver = {
 		.name = MAX44009_DRV_NAME,
+		.of_match_table = max44009_of_match,
 	},
 	.probe = max44009_probe,
 	.id_table = max44009_id,
 };
 module_i2c_driver(max44009_driver);
-
-static const struct of_device_id max44009_of_match[] = {
-	{ .compatible = "maxim,max44009" },
-	{ }
-};
-MODULE_DEVICE_TABLE(of, max44009_of_match);
 
 MODULE_AUTHOR("Robert Eshleman <bobbyeshleman@gmail.com>");
 MODULE_LICENSE("GPL v2");
diff --git a/kernel/drivers/iio/light/tsl2772.c b/kernel/drivers/iio/light/tsl2772.c
index d792053..ff33ad3 100644
--- a/kernel/drivers/iio/light/tsl2772.c
+++ b/kernel/drivers/iio/light/tsl2772.c
@@ -606,6 +606,7 @@
 			return -EINVAL;
 		}
 	}
+	chip->settings.prox_diode = prox_diode_mask;
 
 	return 0;
 }
diff --git a/kernel/drivers/iio/light/vcnl4035.c b/kernel/drivers/iio/light/vcnl4035.c
index 1bd85e2..6e38a33 100644
--- a/kernel/drivers/iio/light/vcnl4035.c
+++ b/kernel/drivers/iio/light/vcnl4035.c
@@ -8,6 +8,7 @@
  * TODO: Proximity
  */
 #include <linux/bitops.h>
+#include <linux/bitfield.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
@@ -42,6 +43,7 @@
 #define VCNL4035_ALS_PERS_MASK		GENMASK(3, 2)
 #define VCNL4035_INT_ALS_IF_H_MASK	BIT(12)
 #define VCNL4035_INT_ALS_IF_L_MASK	BIT(13)
+#define VCNL4035_DEV_ID_MASK		GENMASK(7, 0)
 
 /* Default values */
 #define VCNL4035_MODE_ALS_ENABLE	BIT(0)
@@ -415,6 +417,7 @@
 		return ret;
 	}
 
+	id = FIELD_GET(VCNL4035_DEV_ID_MASK, id);
 	if (id != VCNL4035_DEV_ID_VAL) {
 		dev_err(&data->client->dev, "Wrong id, got %x, expected %x\n",
 			id, VCNL4035_DEV_ID_VAL);
diff --git a/kernel/drivers/iio/temperature/ltc2983.c b/kernel/drivers/iio/temperature/ltc2983.c
index 8306daa..b2ae2d2 100644
--- a/kernel/drivers/iio/temperature/ltc2983.c
+++ b/kernel/drivers/iio/temperature/ltc2983.c
@@ -205,6 +205,7 @@
 	 * Holds the converted temperature
 	 */
 	__be32 temp ____cacheline_aligned;
+	__be32 chan_val;
 };
 
 struct ltc2983_sensor {
@@ -309,19 +310,18 @@
 	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,
diff --git a/kernel/drivers/infiniband/core/cm.c b/kernel/drivers/infiniband/core/cm.c
index 3133b6b..db1a25f 100644
--- a/kernel/drivers/infiniband/core/cm.c
+++ b/kernel/drivers/infiniband/core/cm.c
@@ -2924,6 +2924,8 @@
 	    (ari && ari_length > IB_CM_REJ_ARI_LENGTH))
 		return -EINVAL;
 
+	trace_icm_send_rej(&cm_id_priv->id, reason);
+
 	switch (state) {
 	case IB_CM_REQ_SENT:
 	case IB_CM_MRA_REQ_RCVD:
@@ -2954,7 +2956,6 @@
 		return -EINVAL;
 	}
 
-	trace_icm_send_rej(&cm_id_priv->id, reason);
 	ret = ib_post_send_mad(msg, NULL);
 	if (ret) {
 		cm_free_msg(msg);
diff --git a/kernel/drivers/infiniband/core/cma.c b/kernel/drivers/infiniband/core/cma.c
index 9ed5de3..0603d06 100644
--- a/kernel/drivers/infiniband/core/cma.c
+++ b/kernel/drivers/infiniband/core/cma.c
@@ -505,21 +505,10 @@
 	return id_priv->id.route.addr.src_addr.ss_family;
 }
 
-static int cma_set_qkey(struct rdma_id_private *id_priv, u32 qkey)
+static int cma_set_default_qkey(struct rdma_id_private *id_priv)
 {
 	struct ib_sa_mcmember_rec rec;
 	int ret = 0;
-
-	if (id_priv->qkey) {
-		if (qkey && id_priv->qkey != qkey)
-			return -EINVAL;
-		return 0;
-	}
-
-	if (qkey) {
-		id_priv->qkey = qkey;
-		return 0;
-	}
 
 	switch (id_priv->id.ps) {
 	case RDMA_PS_UDP:
@@ -538,6 +527,16 @@
 		break;
 	}
 	return ret;
+}
+
+static int cma_set_qkey(struct rdma_id_private *id_priv, u32 qkey)
+{
+	if (!qkey ||
+	    (id_priv->qkey && (id_priv->qkey != qkey)))
+		return -EINVAL;
+
+	id_priv->qkey = qkey;
+	return 0;
 }
 
 static void cma_translate_ib(struct sockaddr_ib *sib, struct rdma_dev_addr *dev_addr)
@@ -1107,7 +1106,7 @@
 	*qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT;
 
 	if (id_priv->id.qp_type == IB_QPT_UD) {
-		ret = cma_set_qkey(id_priv, 0);
+		ret = cma_set_default_qkey(id_priv);
 		if (ret)
 			return ret;
 
@@ -1793,6 +1792,14 @@
 {
 	switch (state) {
 	case RDMA_CM_ADDR_QUERY:
+		/*
+		 * We can avoid doing the rdma_addr_cancel() based on state,
+		 * only RDMA_CM_ADDR_QUERY has a work that could still execute.
+		 * Notice that the addr_handler work could still be exiting
+		 * outside this state, however due to the interaction with the
+		 * handler_mutex the work is guaranteed not to touch id_priv
+		 * during exit.
+		 */
 		rdma_addr_cancel(&id_priv->id.route.addr.dev_addr);
 		break;
 	case RDMA_CM_ROUTE_QUERY:
@@ -3070,7 +3077,7 @@
 	route->path_rec->traffic_class = tos;
 	route->path_rec->mtu = iboe_get_mtu(ndev->mtu);
 	route->path_rec->rate_selector = IB_SA_EQ;
-	route->path_rec->rate = iboe_get_rate(ndev);
+	route->path_rec->rate = IB_RATE_PORT_CURRENT;
 	dev_put(ndev);
 	route->path_rec->packet_life_time_selector = IB_SA_EQ;
 	/* In case ACK timeout is set, use this value to calculate
@@ -3402,6 +3409,21 @@
 		if (dst_addr->sa_family == AF_IB) {
 			ret = cma_resolve_ib_addr(id_priv);
 		} else {
+			/*
+			 * The FSM can return back to RDMA_CM_ADDR_BOUND after
+			 * rdma_resolve_ip() is called, eg through the error
+			 * path in addr_handler(). If this happens the existing
+			 * request must be canceled before issuing a new one.
+			 * Since canceling a request is a bit slow and this
+			 * oddball path is rare, keep track once a request has
+			 * been issued. The track turns out to be a permanent
+			 * state since this is the only cancel as it is
+			 * immediately before rdma_resolve_ip().
+			 */
+			if (id_priv->used_resolve_ip)
+				rdma_addr_cancel(&id->route.addr.dev_addr);
+			else
+				id_priv->used_resolve_ip = 1;
 			ret = rdma_resolve_ip(cma_src_addr(id_priv), dst_addr,
 					      &id->route.addr.dev_addr,
 					      timeout_ms, addr_handler,
@@ -4312,7 +4334,10 @@
 	memset(&rep, 0, sizeof rep);
 	rep.status = status;
 	if (status == IB_SIDR_SUCCESS) {
-		ret = cma_set_qkey(id_priv, qkey);
+		if (qkey)
+			ret = cma_set_qkey(id_priv, qkey);
+		else
+			ret = cma_set_default_qkey(id_priv);
 		if (ret)
 			return ret;
 		rep.qp_num = id_priv->qp_num;
@@ -4516,9 +4541,7 @@
 	enum ib_gid_type gid_type;
 	struct net_device *ndev;
 
-	if (!status)
-		status = cma_set_qkey(id_priv, be32_to_cpu(multicast->rec.qkey));
-	else
+	if (status)
 		pr_debug_ratelimited("RDMA CM: MULTICAST_ERROR: failed to join multicast. status %d\n",
 				     status);
 
@@ -4546,7 +4569,7 @@
 	}
 
 	event->param.ud.qp_num = 0xFFFFFF;
-	event->param.ud.qkey = be32_to_cpu(multicast->rec.qkey);
+	event->param.ud.qkey = id_priv->qkey;
 
 out:
 	if (ndev)
@@ -4565,8 +4588,11 @@
 	    READ_ONCE(id_priv->state) == RDMA_CM_DESTROYING)
 		goto out;
 
-	cma_make_mc_event(status, id_priv, multicast, &event, mc);
-	ret = cma_cm_event_handler(id_priv, &event);
+	ret = cma_set_qkey(id_priv, be32_to_cpu(multicast->rec.qkey));
+	if (!ret) {
+		cma_make_mc_event(status, id_priv, multicast, &event, mc);
+		ret = cma_cm_event_handler(id_priv, &event);
+	}
 	rdma_destroy_ah_attr(&event.param.ud.ah_attr);
 	WARN_ON(ret);
 
@@ -4619,9 +4645,11 @@
 	if (ret)
 		return ret;
 
-	ret = cma_set_qkey(id_priv, 0);
-	if (ret)
-		return ret;
+	if (!id_priv->qkey) {
+		ret = cma_set_default_qkey(id_priv);
+		if (ret)
+			return ret;
+	}
 
 	cma_set_mgid(id_priv, (struct sockaddr *) &mc->addr, &rec.mgid);
 	rec.qkey = cpu_to_be32(id_priv->qkey);
@@ -4695,7 +4723,7 @@
 	int err = 0;
 	struct sockaddr *addr = (struct sockaddr *)&mc->addr;
 	struct net_device *ndev = NULL;
-	struct ib_sa_multicast ib;
+	struct ib_sa_multicast ib = {};
 	enum ib_gid_type gid_type;
 	bool send_only;
 
@@ -4709,15 +4737,12 @@
 	cma_iboe_set_mgid(addr, &ib.rec.mgid, gid_type);
 
 	ib.rec.pkey = cpu_to_be16(0xffff);
-	if (id_priv->id.ps == RDMA_PS_UDP)
-		ib.rec.qkey = cpu_to_be32(RDMA_UDP_QKEY);
-
 	if (dev_addr->bound_dev_if)
 		ndev = dev_get_by_index(dev_addr->net, dev_addr->bound_dev_if);
 	if (!ndev)
 		return -ENODEV;
 
-	ib.rec.rate = iboe_get_rate(ndev);
+	ib.rec.rate = IB_RATE_PORT_CURRENT;
 	ib.rec.hop_limit = 1;
 	ib.rec.mtu = iboe_get_mtu(ndev->mtu);
 
@@ -4736,6 +4761,9 @@
 	dev_put(ndev);
 	if (err || !ib.rec.mtu)
 		return err ?: -EINVAL;
+
+	if (!id_priv->qkey)
+		cma_set_default_qkey(id_priv);
 
 	rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.src_addr,
 		    &ib.rec.port_gid);
@@ -4762,6 +4790,9 @@
 			    READ_ONCE(id_priv->state) != RDMA_CM_ADDR_RESOLVED))
 		return -EINVAL;
 
+	if (id_priv->id.qp_type != IB_QPT_UD)
+		return -EINVAL;
+
 	mc = kzalloc(sizeof(*mc), GFP_KERNEL);
 	if (!mc)
 		return -ENOMEM;
diff --git a/kernel/drivers/infiniband/core/cma_configfs.c b/kernel/drivers/infiniband/core/cma_configfs.c
index 35d1ec1..d7cc8d5 100644
--- a/kernel/drivers/infiniband/core/cma_configfs.c
+++ b/kernel/drivers/infiniband/core/cma_configfs.c
@@ -221,7 +221,7 @@
 	}
 
 	for (i = 0; i < ports_num; i++) {
-		char port_str[10];
+		char port_str[11];
 
 		ports[i].port_num = i + 1;
 		snprintf(port_str, sizeof(port_str), "%u", i + 1);
diff --git a/kernel/drivers/infiniband/core/cma_priv.h b/kernel/drivers/infiniband/core/cma_priv.h
index caece96..b53f4fa 100644
--- a/kernel/drivers/infiniband/core/cma_priv.h
+++ b/kernel/drivers/infiniband/core/cma_priv.h
@@ -89,6 +89,7 @@
 	u8			reuseaddr;
 	u8			afonly;
 	u8			timeout;
+	u8 used_resolve_ip;
 	enum ib_gid_type	gid_type;
 
 	/*
diff --git a/kernel/drivers/infiniband/core/device.c b/kernel/drivers/infiniband/core/device.c
index d91892f..3c29fd0 100644
--- a/kernel/drivers/infiniband/core/device.c
+++ b/kernel/drivers/infiniband/core/device.c
@@ -600,6 +600,17 @@
 	init_completion(&device->unreg_completion);
 	INIT_WORK(&device->unregistration_work, ib_unregister_work);
 
+	device->uverbs_ex_cmd_mask =
+		BIT_ULL(IB_USER_VERBS_EX_CMD_CREATE_FLOW) |
+		BIT_ULL(IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL) |
+		BIT_ULL(IB_USER_VERBS_EX_CMD_CREATE_WQ) |
+		BIT_ULL(IB_USER_VERBS_EX_CMD_DESTROY_FLOW) |
+		BIT_ULL(IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL) |
+		BIT_ULL(IB_USER_VERBS_EX_CMD_DESTROY_WQ) |
+		BIT_ULL(IB_USER_VERBS_EX_CMD_MODIFY_CQ) |
+		BIT_ULL(IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
+		BIT_ULL(IB_USER_VERBS_EX_CMD_QUERY_DEVICE);
+
 	return device;
 }
 EXPORT_SYMBOL(_ib_alloc_device);
@@ -2793,8 +2804,8 @@
 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();
diff --git a/kernel/drivers/infiniband/core/nldev.c b/kernel/drivers/infiniband/core/nldev.c
index c90f637..f8dfec7 100644
--- a/kernel/drivers/infiniband/core/nldev.c
+++ b/kernel/drivers/infiniband/core/nldev.c
@@ -502,7 +502,7 @@
 
 	/* 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)
@@ -541,7 +541,7 @@
 	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))
@@ -754,6 +754,8 @@
 	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);
@@ -2146,6 +2148,7 @@
 	},
 	[RDMA_NLDEV_CMD_SYS_SET] = {
 		.doit = nldev_set_sys_set_doit,
+		.flags = RDMA_NL_ADMIN_PERM,
 	},
 	[RDMA_NLDEV_CMD_STAT_SET] = {
 		.doit = nldev_stat_set_doit,
diff --git a/kernel/drivers/infiniband/core/user_mad.c b/kernel/drivers/infiniband/core/user_mad.c
index 4688a66..3bd0dcd 100644
--- a/kernel/drivers/infiniband/core/user_mad.c
+++ b/kernel/drivers/infiniband/core/user_mad.c
@@ -131,6 +131,11 @@
 	struct ib_user_mad mad;
 };
 
+struct ib_rmpp_mad_hdr {
+	struct ib_mad_hdr	mad_hdr;
+	struct ib_rmpp_hdr      rmpp_hdr;
+} __packed;
+
 #define CREATE_TRACE_POINTS
 #include <trace/events/ib_umad.h>
 
@@ -494,11 +499,11 @@
 			     size_t count, loff_t *pos)
 {
 	struct ib_umad_file *file = filp->private_data;
+	struct ib_rmpp_mad_hdr *rmpp_mad_hdr;
 	struct ib_umad_packet *packet;
 	struct ib_mad_agent *agent;
 	struct rdma_ah_attr ah_attr;
 	struct ib_ah *ah;
-	struct ib_rmpp_mad *rmpp_mad;
 	__be64 *tid;
 	int ret, data_len, hdr_len, copy_offset, rmpp_active;
 	u8 base_version;
@@ -506,7 +511,7 @@
 	if (count < hdr_size(file) + IB_MGMT_RMPP_HDR)
 		return -EINVAL;
 
-	packet = kzalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL);
+	packet = kzalloc(sizeof(*packet) + IB_MGMT_RMPP_HDR, GFP_KERNEL);
 	if (!packet)
 		return -ENOMEM;
 
@@ -560,13 +565,13 @@
 		goto err_up;
 	}
 
-	rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data;
-	hdr_len = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class);
+	rmpp_mad_hdr = (struct ib_rmpp_mad_hdr *)packet->mad.data;
+	hdr_len = ib_get_mad_data_offset(rmpp_mad_hdr->mad_hdr.mgmt_class);
 
-	if (ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)
+	if (ib_is_mad_class_rmpp(rmpp_mad_hdr->mad_hdr.mgmt_class)
 	    && ib_mad_kernel_rmpp_agent(agent)) {
 		copy_offset = IB_MGMT_RMPP_HDR;
-		rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
+		rmpp_active = ib_get_rmpp_flags(&rmpp_mad_hdr->rmpp_hdr) &
 						IB_MGMT_RMPP_FLAG_ACTIVE;
 	} else {
 		copy_offset = IB_MGMT_MAD_HDR;
@@ -615,12 +620,12 @@
 		tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid;
 		*tid = cpu_to_be64(((u64) agent->hi_tid) << 32 |
 				   (be64_to_cpup(tid) & 0xffffffff));
-		rmpp_mad->mad_hdr.tid = *tid;
+		rmpp_mad_hdr->mad_hdr.tid = *tid;
 	}
 
 	if (!ib_mad_kernel_rmpp_agent(agent)
-	   && ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)
-	   && (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) {
+	    && ib_is_mad_class_rmpp(rmpp_mad_hdr->mad_hdr.mgmt_class)
+	    && (ib_get_rmpp_flags(&rmpp_mad_hdr->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) {
 		spin_lock_irq(&file->send_lock);
 		list_add_tail(&packet->list, &file->send_list);
 		spin_unlock_irq(&file->send_lock);
diff --git a/kernel/drivers/infiniband/core/uverbs_cmd.c b/kernel/drivers/infiniband/core/uverbs_cmd.c
index d7c90da..158f9ea 100644
--- a/kernel/drivers/infiniband/core/uverbs_cmd.c
+++ b/kernel/drivers/infiniband/core/uverbs_cmd.c
@@ -1842,8 +1842,13 @@
 		attr->path_mtu = cmd->base.path_mtu;
 	if (cmd->base.attr_mask & IB_QP_PATH_MIG_STATE)
 		attr->path_mig_state = cmd->base.path_mig_state;
-	if (cmd->base.attr_mask & IB_QP_QKEY)
+	if (cmd->base.attr_mask & IB_QP_QKEY) {
+		if (cmd->base.qkey & IB_QP_SET_QKEY && !capable(CAP_NET_RAW)) {
+			ret = -EPERM;
+			goto release_qp;
+		}
 		attr->qkey = cmd->base.qkey;
+	}
 	if (cmd->base.attr_mask & IB_QP_RQ_PSN)
 		attr->rq_psn = cmd->base.rq_psn;
 	if (cmd->base.attr_mask & IB_QP_SQ_PSN)
@@ -3773,7 +3778,7 @@
 			IB_USER_VERBS_EX_CMD_MODIFY_CQ,
 			ib_uverbs_ex_modify_cq,
 			UAPI_DEF_WRITE_I(struct ib_uverbs_ex_modify_cq),
-			UAPI_DEF_METHOD_NEEDS_FN(create_cq))),
+			UAPI_DEF_METHOD_NEEDS_FN(modify_cq))),
 
 	DECLARE_UVERBS_OBJECT(
 		UVERBS_OBJECT_DEVICE,
diff --git a/kernel/drivers/infiniband/core/uverbs_main.c b/kernel/drivers/infiniband/core/uverbs_main.c
index 4bb7c64..f2fcdb7 100644
--- a/kernel/drivers/infiniband/core/uverbs_main.c
+++ b/kernel/drivers/infiniband/core/uverbs_main.c
@@ -222,8 +222,12 @@
 	spin_lock_irq(&ev_queue->lock);
 
 	while (list_empty(&ev_queue->event_list)) {
-		spin_unlock_irq(&ev_queue->lock);
+		if (ev_queue->is_closed) {
+			spin_unlock_irq(&ev_queue->lock);
+			return -EIO;
+		}
 
+		spin_unlock_irq(&ev_queue->lock);
 		if (filp->f_flags & O_NONBLOCK)
 			return -EAGAIN;
 
@@ -233,12 +237,6 @@
 			return -ERESTARTSYS;
 
 		spin_lock_irq(&ev_queue->lock);
-
-		/* If device was disassociated and no event exists set an error */
-		if (list_empty(&ev_queue->event_list) && ev_queue->is_closed) {
-			spin_unlock_irq(&ev_queue->lock);
-			return -EIO;
-		}
 	}
 
 	event = list_entry(ev_queue->event_list.next, struct ib_uverbs_event, list);
@@ -537,7 +535,7 @@
 	if (hdr->in_words * 4 != count)
 		return -EINVAL;
 
-	if (count < method_elm->req_size + sizeof(hdr)) {
+	if (count < method_elm->req_size + sizeof(*hdr)) {
 		/*
 		 * rdma-core v18 and v19 have a bug where they send DESTROY_CQ
 		 * with a 16 byte write instead of 24. Old kernels didn't
diff --git a/kernel/drivers/infiniband/core/uverbs_std_types_counters.c b/kernel/drivers/infiniband/core/uverbs_std_types_counters.c
index b3c6c06..c61b10f 100644
--- a/kernel/drivers/infiniband/core/uverbs_std_types_counters.c
+++ b/kernel/drivers/infiniband/core/uverbs_std_types_counters.c
@@ -108,6 +108,8 @@
 		return ret;
 
 	uattr = uverbs_attr_get(attrs, UVERBS_ATTR_READ_COUNTERS_BUFF);
+	if (IS_ERR(uattr))
+		return PTR_ERR(uattr);
 	read_attr.ncounters = uattr->ptr_attr.len / sizeof(u64);
 	read_attr.counters_buff = uverbs_zalloc(
 		attrs, array_size(read_attr.ncounters, sizeof(u64)));
diff --git a/kernel/drivers/infiniband/core/verbs.c b/kernel/drivers/infiniband/core/verbs.c
index 5889639..4fcabe5 100644
--- a/kernel/drivers/infiniband/core/verbs.c
+++ b/kernel/drivers/infiniband/core/verbs.c
@@ -535,6 +535,8 @@
 
 	ret = device->ops.create_ah(ah, &init_attr, udata);
 	if (ret) {
+		if (ah->sgid_attr)
+			rdma_put_gid_attr(ah->sgid_attr);
 		kfree(ah);
 		return ERR_PTR(ret);
 	}
@@ -2911,15 +2913,18 @@
 bool __rdma_block_iter_next(struct ib_block_iter *biter)
 {
 	unsigned int block_offset;
+	unsigned int sg_delta;
 
 	if (!biter->__sg_nents || !biter->__sg)
 		return false;
 
 	biter->__dma_addr = sg_dma_address(biter->__sg) + biter->__sg_advance;
 	block_offset = biter->__dma_addr & (BIT_ULL(biter->__pg_bit) - 1);
-	biter->__sg_advance += BIT_ULL(biter->__pg_bit) - block_offset;
+	sg_delta = BIT_ULL(biter->__pg_bit) - block_offset;
 
-	if (biter->__sg_advance >= sg_dma_len(biter->__sg)) {
+	if (sg_dma_len(biter->__sg) - biter->__sg_advance > sg_delta) {
+		biter->__sg_advance += sg_delta;
+	} else {
 		biter->__sg_advance = 0;
 		biter->__sg = sg_next(biter->__sg);
 		biter->__sg_nents--;
diff --git a/kernel/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/kernel/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 10d77f5..2a973a1 100644
--- a/kernel/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/kernel/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -469,7 +469,6 @@
 	struct bnxt_re_mr *mr = NULL;
 	dma_addr_t dma_addr = 0;
 	struct ib_mw *mw;
-	u64 pbl_tbl;
 	int rc;
 
 	dma_addr = dma_map_single(dev, fence->va, BNXT_RE_FENCE_BYTES,
@@ -504,9 +503,8 @@
 	mr->ib_mr.lkey = mr->qplib_mr.lkey;
 	mr->qplib_mr.va = (u64)(unsigned long)fence->va;
 	mr->qplib_mr.total_size = BNXT_RE_FENCE_BYTES;
-	pbl_tbl = dma_addr;
-	rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, &pbl_tbl,
-			       BNXT_RE_FENCE_PBL_SIZE, false, PAGE_SIZE);
+	rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, NULL,
+			       BNXT_RE_FENCE_PBL_SIZE, PAGE_SIZE);
 	if (rc) {
 		ibdev_err(&rdev->ibdev, "Failed to register fence-MR\n");
 		goto fail;
@@ -3249,9 +3247,7 @@
 	udwr.remote_qkey = gsi_sqp->qplib_qp.qkey;
 
 	/* post data received  in the send queue */
-	rc = bnxt_re_post_send_shadow_qp(rdev, gsi_sqp, swr);
-
-	return 0;
+	return bnxt_re_post_send_shadow_qp(rdev, gsi_sqp, swr);
 }
 
 static void bnxt_re_process_res_rawqp1_wc(struct ib_wc *wc,
@@ -3588,7 +3584,6 @@
 	struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
 	struct bnxt_re_dev *rdev = pd->rdev;
 	struct bnxt_re_mr *mr;
-	u64 pbl = 0;
 	int rc;
 
 	mr = kzalloc(sizeof(*mr), GFP_KERNEL);
@@ -3607,7 +3602,7 @@
 
 	mr->qplib_mr.hwq.level = PBL_LVL_MAX;
 	mr->qplib_mr.total_size = -1; /* Infinte length */
-	rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, &pbl, 0, false,
+	rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, NULL, 0,
 			       PAGE_SIZE);
 	if (rc)
 		goto fail_mr;
@@ -3778,19 +3773,6 @@
 	return rc;
 }
 
-static int fill_umem_pbl_tbl(struct ib_umem *umem, u64 *pbl_tbl_orig,
-			     int page_shift)
-{
-	u64 *pbl_tbl = pbl_tbl_orig;
-	u64 page_size =  BIT_ULL(page_shift);
-	struct ib_block_iter biter;
-
-	rdma_umem_for_each_dma_block(umem, &biter, page_size)
-		*pbl_tbl++ = rdma_block_iter_dma_address(&biter);
-
-	return pbl_tbl - pbl_tbl_orig;
-}
-
 /* uverbs */
 struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, u64 start, u64 length,
 				  u64 virt_addr, int mr_access_flags,
@@ -3800,7 +3782,6 @@
 	struct bnxt_re_dev *rdev = pd->rdev;
 	struct bnxt_re_mr *mr;
 	struct ib_umem *umem;
-	u64 *pbl_tbl = NULL;
 	unsigned long page_size;
 	int umem_pgs, rc;
 
@@ -3854,30 +3835,18 @@
 	}
 
 	umem_pgs = ib_umem_num_dma_blocks(umem, page_size);
-	pbl_tbl = kcalloc(umem_pgs, sizeof(*pbl_tbl), GFP_KERNEL);
-	if (!pbl_tbl) {
-		rc = -ENOMEM;
-		goto free_umem;
-	}
-
-	/* Map umem buf ptrs to the PBL */
-	umem_pgs = fill_umem_pbl_tbl(umem, pbl_tbl, order_base_2(page_size));
-	rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, pbl_tbl,
-			       umem_pgs, false, page_size);
+	rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, umem,
+			       umem_pgs, page_size);
 	if (rc) {
 		ibdev_err(&rdev->ibdev, "Failed to register user MR");
-		goto fail;
+		goto free_umem;
 	}
-
-	kfree(pbl_tbl);
 
 	mr->ib_mr.lkey = mr->qplib_mr.lkey;
 	mr->ib_mr.rkey = mr->qplib_mr.lkey;
 	atomic_inc(&rdev->mr_count);
 
 	return &mr->ib_mr;
-fail:
-	kfree(pbl_tbl);
 free_umem:
 	ib_umem_release(umem);
 free_mrw:
diff --git a/kernel/drivers/infiniband/hw/bnxt_re/main.c b/kernel/drivers/infiniband/hw/bnxt_re/main.c
index 9ef6aea..8a61876 100644
--- a/kernel/drivers/infiniband/hw/bnxt_re/main.c
+++ b/kernel/drivers/infiniband/hw/bnxt_re/main.c
@@ -294,15 +294,21 @@
 	for (indx = 0; indx < rdev->num_msix; indx++)
 		rdev->msix_entries[indx].vector = ent[indx].vector;
 
-	bnxt_qplib_rcfw_start_irq(rcfw, msix_ent[BNXT_RE_AEQ_IDX].vector,
-				  false);
+	rc = bnxt_qplib_rcfw_start_irq(rcfw, msix_ent[BNXT_RE_AEQ_IDX].vector,
+				       false);
+	if (rc) {
+		ibdev_warn(&rdev->ibdev, "Failed to reinit CREQ\n");
+		return;
+	}
 	for (indx = BNXT_RE_NQ_IDX ; indx < rdev->num_msix; indx++) {
 		nq = &rdev->nq[indx - 1];
 		rc = bnxt_qplib_nq_start_irq(nq, indx - 1,
 					     msix_ent[indx].vector, false);
-		if (rc)
+		if (rc) {
 			ibdev_warn(&rdev->ibdev, "Failed to reinit NQ index %d\n",
 				   indx - 1);
+			return;
+		}
 	}
 }
 
@@ -1185,12 +1191,6 @@
 	if (!ib_device_try_get(&rdev->ibdev))
 		return 0;
 
-	if (!sgid_tbl) {
-		ibdev_err(&rdev->ibdev, "QPLIB: SGID table not allocated");
-		rc = -EINVAL;
-		goto out;
-	}
-
 	for (index = 0; index < sgid_tbl->active; index++) {
 		gid_idx = sgid_tbl->hw_id[index];
 
@@ -1208,7 +1208,7 @@
 		rc = bnxt_qplib_update_sgid(sgid_tbl, &gid, gid_idx,
 					    rdev->qplib_res.netdev->dev_addr);
 	}
-out:
+
 	ib_device_put(&rdev->ibdev);
 	return rc;
 }
diff --git a/kernel/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/kernel/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index bd153aa..d44b6a5 100644
--- a/kernel/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/kernel/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -404,6 +404,9 @@
 
 void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill)
 {
+	if (!nq->requested)
+		return;
+
 	tasklet_disable(&nq->nq_tasklet);
 	/* Mask h/w interrupt */
 	bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, false);
@@ -411,11 +414,12 @@
 	synchronize_irq(nq->msix_vec);
 	if (kill)
 		tasklet_kill(&nq->nq_tasklet);
-	if (nq->requested) {
-		irq_set_affinity_hint(nq->msix_vec, NULL);
-		free_irq(nq->msix_vec, nq);
-		nq->requested = false;
-	}
+
+	irq_set_affinity_hint(nq->msix_vec, NULL);
+	free_irq(nq->msix_vec, nq);
+	kfree(nq->name);
+	nq->name = NULL;
+	nq->requested = false;
 }
 
 void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq)
@@ -441,6 +445,7 @@
 int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx,
 			    int msix_vector, bool need_init)
 {
+	struct bnxt_qplib_res *res = nq->res;
 	int rc;
 
 	if (nq->requested)
@@ -452,10 +457,17 @@
 	else
 		tasklet_enable(&nq->nq_tasklet);
 
-	snprintf(nq->name, sizeof(nq->name), "bnxt_qplib_nq-%d", nq_indx);
+	nq->name = kasprintf(GFP_KERNEL, "bnxt_re-nq-%d@pci:%s",
+			     nq_indx, pci_name(res->pdev));
+	if (!nq->name)
+		return -ENOMEM;
 	rc = request_irq(nq->msix_vec, bnxt_qplib_nq_irq, 0, nq->name, nq);
-	if (rc)
+	if (rc) {
+		kfree(nq->name);
+		nq->name = NULL;
+		tasklet_disable(&nq->nq_tasklet);
 		return rc;
+	}
 
 	cpumask_clear(&nq->mask);
 	cpumask_set_cpu(nq_indx, &nq->mask);
@@ -466,7 +478,7 @@
 			 nq->msix_vec, nq_indx);
 	}
 	nq->requested = true;
-	bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, true);
+	bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, res->cctx, true);
 
 	return rc;
 }
@@ -1599,7 +1611,7 @@
 		il_src = (void *)wqe->sg_list[indx].addr;
 		t_len += len;
 		if (t_len > qp->max_inline_data)
-			goto bad;
+			return -ENOMEM;
 		while (len) {
 			if (pull_dst) {
 				pull_dst = false;
@@ -1623,8 +1635,6 @@
 	}
 
 	return t_len;
-bad:
-	return -ENOMEM;
 }
 
 static u32 bnxt_qplib_put_sges(struct bnxt_qplib_hwq *hwq,
@@ -2041,6 +2051,12 @@
 	u32 pg_sz_lvl;
 	int rc;
 
+	if (!cq->dpi) {
+		dev_err(&rcfw->pdev->dev,
+			"FP: CREATE_CQ failed due to NULL DPI\n");
+		return -EINVAL;
+	}
+
 	hwq_attr.res = res;
 	hwq_attr.depth = cq->max_wqe;
 	hwq_attr.stride = sizeof(struct cq_base);
@@ -2048,15 +2064,10 @@
 	hwq_attr.sginfo = &cq->sg_info;
 	rc = bnxt_qplib_alloc_init_hwq(&cq->hwq, &hwq_attr);
 	if (rc)
-		goto exit;
+		return rc;
 
 	RCFW_CMD_PREP(req, CREATE_CQ, cmd_flags);
 
-	if (!cq->dpi) {
-		dev_err(&rcfw->pdev->dev,
-			"FP: CREATE_CQ failed due to NULL DPI\n");
-		return -EINVAL;
-	}
 	req.dpi = cpu_to_le32(cq->dpi->dpi);
 	req.cq_handle = cpu_to_le64(cq->cq_handle);
 	req.cq_size = cpu_to_le32(cq->hwq.max_elements);
@@ -2094,7 +2105,6 @@
 
 fail:
 	bnxt_qplib_free_hwq(res, &cq->hwq);
-exit:
 	return rc;
 }
 
@@ -2722,11 +2732,8 @@
 
 	qp = (struct bnxt_qplib_qp *)((unsigned long)
 				      le64_to_cpu(hwcqe->qp_handle));
-	if (!qp) {
-		dev_err(&cq->hwq.pdev->dev,
-			"FP: CQ Process terminal qp is NULL\n");
+	if (!qp)
 		return -EINVAL;
-	}
 
 	/* Must block new posting of SQ and RQ */
 	qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
diff --git a/kernel/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/kernel/drivers/infiniband/hw/bnxt_re/qplib_fp.h
index f507844..667f93d 100644
--- a/kernel/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+++ b/kernel/drivers/infiniband/hw/bnxt_re/qplib_fp.h
@@ -469,7 +469,7 @@
 struct bnxt_qplib_nq {
 	struct pci_dev			*pdev;
 	struct bnxt_qplib_res		*res;
-	char				name[32];
+	char				*name;
 	struct bnxt_qplib_hwq		hwq;
 	struct bnxt_qplib_nq_db		nq_db;
 	u16				ring_id;
diff --git a/kernel/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/kernel/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
index 5759027..2b0c3a8 100644
--- a/kernel/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+++ b/kernel/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
@@ -181,7 +181,7 @@
 	} while (size > 0);
 	cmdq->seq_num++;
 
-	cmdq_prod = hwq->prod;
+	cmdq_prod = hwq->prod & 0xFFFF;
 	if (test_bit(FIRMWARE_FIRST_FLAG, &cmdq->flags)) {
 		/* The very first doorbell write
 		 * is required to set this flag
@@ -295,7 +295,8 @@
 }
 
 static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
-				       struct creq_qp_event *qp_event)
+				       struct creq_qp_event *qp_event,
+				       u32 *num_wait)
 {
 	struct creq_qp_error_notification *err_event;
 	struct bnxt_qplib_hwq *hwq = &rcfw->cmdq.hwq;
@@ -304,6 +305,7 @@
 	u16 cbit, blocked = 0;
 	struct pci_dev *pdev;
 	unsigned long flags;
+	u32 wait_cmds = 0;
 	__le16  mcookie;
 	u16 cookie;
 	int rc = 0;
@@ -363,9 +365,10 @@
 		crsqe->req_size = 0;
 
 		if (!blocked)
-			wake_up(&rcfw->cmdq.waitq);
+			wait_cmds++;
 		spin_unlock_irqrestore(&hwq->lock, flags);
 	}
+	*num_wait += wait_cmds;
 	return rc;
 }
 
@@ -379,6 +382,7 @@
 	struct creq_base *creqe;
 	u32 sw_cons, raw_cons;
 	unsigned long flags;
+	u32 num_wakeup = 0;
 
 	/* Service the CREQ until budget is over */
 	spin_lock_irqsave(&hwq->lock, flags);
@@ -397,7 +401,8 @@
 		switch (type) {
 		case CREQ_BASE_TYPE_QP_EVENT:
 			bnxt_qplib_process_qp_event
-				(rcfw, (struct creq_qp_event *)creqe);
+				(rcfw, (struct creq_qp_event *)creqe,
+				 &num_wakeup);
 			creq->stats.creq_qp_event_processed++;
 			break;
 		case CREQ_BASE_TYPE_FUNC_EVENT:
@@ -425,6 +430,8 @@
 				      rcfw->res->cctx, true);
 	}
 	spin_unlock_irqrestore(&hwq->lock, flags);
+	if (num_wakeup)
+		wake_up_nr(&rcfw->cmdq.waitq, num_wakeup);
 }
 
 static irqreturn_t bnxt_qplib_creq_irq(int irq, void *dev_instance)
@@ -595,7 +602,7 @@
 		rcfw->cmdq_depth = BNXT_QPLIB_CMDQE_MAX_CNT_8192;
 
 	sginfo.pgsize = bnxt_qplib_cmdqe_page_size(rcfw->cmdq_depth);
-	hwq_attr.depth = rcfw->cmdq_depth;
+	hwq_attr.depth = rcfw->cmdq_depth & 0x7FFFFFFF;
 	hwq_attr.stride = BNXT_QPLIB_CMDQE_UNITS;
 	hwq_attr.type = HWQ_TYPE_CTX;
 	if (bnxt_qplib_alloc_init_hwq(&cmdq->hwq, &hwq_attr)) {
@@ -633,6 +640,10 @@
 	struct bnxt_qplib_creq_ctx *creq;
 
 	creq = &rcfw->creq;
+
+	if (!creq->requested)
+		return;
+
 	tasklet_disable(&creq->creq_tasklet);
 	/* Mask h/w interrupts */
 	bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, false);
@@ -641,10 +652,10 @@
 	if (kill)
 		tasklet_kill(&creq->creq_tasklet);
 
-	if (creq->requested) {
-		free_irq(creq->msix_vec, rcfw);
-		creq->requested = false;
-	}
+	free_irq(creq->msix_vec, rcfw);
+	kfree(creq->irq_name);
+	creq->irq_name = NULL;
+	creq->requested = false;
 }
 
 void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw)
@@ -676,9 +687,11 @@
 			      bool need_init)
 {
 	struct bnxt_qplib_creq_ctx *creq;
+	struct bnxt_qplib_res *res;
 	int rc;
 
 	creq = &rcfw->creq;
+	res = rcfw->res;
 
 	if (creq->requested)
 		return -EFAULT;
@@ -688,13 +701,22 @@
 		tasklet_setup(&creq->creq_tasklet, bnxt_qplib_service_creq);
 	else
 		tasklet_enable(&creq->creq_tasklet);
+
+	creq->irq_name = kasprintf(GFP_KERNEL, "bnxt_re-creq@pci:%s",
+				   pci_name(res->pdev));
+	if (!creq->irq_name)
+		return -ENOMEM;
 	rc = request_irq(creq->msix_vec, bnxt_qplib_creq_irq, 0,
-			 "bnxt_qplib_creq", rcfw);
-	if (rc)
+			 creq->irq_name, rcfw);
+	if (rc) {
+		kfree(creq->irq_name);
+		creq->irq_name = NULL;
+		tasklet_disable(&creq->creq_tasklet);
 		return rc;
+	}
 	creq->requested = true;
 
-	bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, true);
+	bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, res->cctx, true);
 
 	return 0;
 }
diff --git a/kernel/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h b/kernel/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
index 6953f4e..7df7170 100644
--- a/kernel/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+++ b/kernel/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
@@ -172,6 +172,7 @@
 	u16				ring_id;
 	int				msix_vec;
 	bool				requested; /*irq handler installed */
+	char				*irq_name;
 };
 
 /* RCFW Communication Channels */
diff --git a/kernel/drivers/infiniband/hw/bnxt_re/qplib_res.c b/kernel/drivers/infiniband/hw/bnxt_re/qplib_res.c
index 754dceb..123ea75 100644
--- a/kernel/drivers/infiniband/hw/bnxt_re/qplib_res.c
+++ b/kernel/drivers/infiniband/hw/bnxt_re/qplib_res.c
@@ -215,17 +215,9 @@
 			return -EINVAL;
 		hwq_attr->sginfo->npages = npages;
 	} else {
-		unsigned long sginfo_num_pages = ib_umem_num_dma_blocks(
-			hwq_attr->sginfo->umem, hwq_attr->sginfo->pgsize);
-
+		npages = ib_umem_num_dma_blocks(hwq_attr->sginfo->umem,
+						hwq_attr->sginfo->pgsize);
 		hwq->is_user = true;
-		npages = sginfo_num_pages;
-		npages = (npages * PAGE_SIZE) /
-			  BIT_ULL(hwq_attr->sginfo->pgshft);
-		if ((sginfo_num_pages * PAGE_SIZE) %
-		     BIT_ULL(hwq_attr->sginfo->pgshft))
-			if (!npages)
-				npages++;
 	}
 
 	if (npages == MAX_PBL_LVL_0_PGS) {
diff --git a/kernel/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/kernel/drivers/infiniband/hw/bnxt_re/qplib_sp.c
index 64d44f5..f53d94c 100644
--- a/kernel/drivers/infiniband/hw/bnxt_re/qplib_sp.c
+++ b/kernel/drivers/infiniband/hw/bnxt_re/qplib_sp.c
@@ -650,16 +650,15 @@
 }
 
 int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
-		      u64 *pbl_tbl, int num_pbls, bool block, u32 buf_pg_size)
+		      struct ib_umem *umem, int num_pbls, u32 buf_pg_size)
 {
 	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
 	struct bnxt_qplib_hwq_attr hwq_attr = {};
 	struct bnxt_qplib_sg_info sginfo = {};
 	struct creq_register_mr_resp resp;
 	struct cmdq_register_mr req;
-	int pg_ptrs, pages, i, rc;
 	u16 cmd_flags = 0, level;
-	dma_addr_t **pbl_ptr;
+	int pages, rc, pg_ptrs;
 	u32 pg_size;
 
 	if (num_pbls) {
@@ -680,26 +679,21 @@
 		/* Free the hwq if it already exist, must be a rereg */
 		if (mr->hwq.max_elements)
 			bnxt_qplib_free_hwq(res, &mr->hwq);
-		/* Use system PAGE_SIZE */
 		hwq_attr.res = res;
 		hwq_attr.depth = pages;
-		hwq_attr.stride = PAGE_SIZE;
+		hwq_attr.stride = sizeof(dma_addr_t);
 		hwq_attr.type = HWQ_TYPE_MR;
 		hwq_attr.sginfo = &sginfo;
+		hwq_attr.sginfo->umem = umem;
 		hwq_attr.sginfo->npages = pages;
-		hwq_attr.sginfo->pgsize = PAGE_SIZE;
-		hwq_attr.sginfo->pgshft = PAGE_SHIFT;
+		hwq_attr.sginfo->pgsize = buf_pg_size;
+		hwq_attr.sginfo->pgshft = ilog2(buf_pg_size);
 		rc = bnxt_qplib_alloc_init_hwq(&mr->hwq, &hwq_attr);
 		if (rc) {
 			dev_err(&res->pdev->dev,
 				"SP: Reg MR memory allocation failed\n");
 			return -ENOMEM;
 		}
-		/* Write to the hwq */
-		pbl_ptr = (dma_addr_t **)mr->hwq.pbl_ptr;
-		for (i = 0; i < num_pbls; i++)
-			pbl_ptr[PTR_PG(i)][PTR_IDX(i)] =
-				(pbl_tbl[i] & PAGE_MASK) | PTU_PTE_VALID;
 	}
 
 	RCFW_CMD_PREP(req, REGISTER_MR, cmd_flags);
@@ -711,7 +705,7 @@
 		req.pbl = 0;
 		pg_size = PAGE_SIZE;
 	} else {
-		level = mr->hwq.level + 1;
+		level = mr->hwq.level;
 		req.pbl = cpu_to_le64(mr->hwq.pbl[PBL_LVL_0].pg_map_arr[0]);
 	}
 	pg_size = buf_pg_size ? buf_pg_size : PAGE_SIZE;
@@ -728,7 +722,7 @@
 	req.mr_size = cpu_to_le64(mr->total_size);
 
 	rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
-					  (void *)&resp, NULL, block);
+					  (void *)&resp, NULL, false);
 	if (rc)
 		goto fail;
 
diff --git a/kernel/drivers/infiniband/hw/bnxt_re/qplib_sp.h b/kernel/drivers/infiniband/hw/bnxt_re/qplib_sp.h
index 967890c..bc22834 100644
--- a/kernel/drivers/infiniband/hw/bnxt_re/qplib_sp.h
+++ b/kernel/drivers/infiniband/hw/bnxt_re/qplib_sp.h
@@ -254,7 +254,7 @@
 int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw,
 			 bool block);
 int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
-		      u64 *pbl_tbl, int num_pbls, bool block, u32 buf_pg_size);
+		      struct ib_umem *umem, int num_pbls, u32 buf_pg_size);
 int bnxt_qplib_free_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr);
 int bnxt_qplib_alloc_fast_reg_mr(struct bnxt_qplib_res *res,
 				 struct bnxt_qplib_mrw *mr, int max);
diff --git a/kernel/drivers/infiniband/hw/efa/efa_main.c b/kernel/drivers/infiniband/hw/efa/efa_main.c
index ffdd18f..cd41cd1 100644
--- a/kernel/drivers/infiniband/hw/efa/efa_main.c
+++ b/kernel/drivers/infiniband/hw/efa/efa_main.c
@@ -326,9 +326,6 @@
 		(1ull << IB_USER_VERBS_CMD_CREATE_AH) |
 		(1ull << IB_USER_VERBS_CMD_DESTROY_AH);
 
-	dev->ibdev.uverbs_ex_cmd_mask =
-		(1ull << IB_USER_VERBS_EX_CMD_QUERY_DEVICE);
-
 	ib_set_device_ops(&dev->ibdev, &efa_dev_ops);
 
 	err = ib_register_device(&dev->ibdev, "efa_%d", &pdev->dev);
diff --git a/kernel/drivers/infiniband/hw/efa/efa_verbs.c b/kernel/drivers/infiniband/hw/efa/efa_verbs.c
index 2ece682..9cf0518 100644
--- a/kernel/drivers/infiniband/hw/efa/efa_verbs.c
+++ b/kernel/drivers/infiniband/hw/efa/efa_verbs.c
@@ -1328,7 +1328,7 @@
  */
 static int pbl_indirect_initialize(struct efa_dev *dev, struct pbl_context *pbl)
 {
-	u32 size_in_pages = DIV_ROUND_UP(pbl->pbl_buf_size_in_bytes, PAGE_SIZE);
+	u32 size_in_pages = DIV_ROUND_UP(pbl->pbl_buf_size_in_bytes, EFA_CHUNK_PAYLOAD_SIZE);
 	struct scatterlist *sgl;
 	int sg_dma_cnt, err;
 
diff --git a/kernel/drivers/infiniband/hw/hfi1/affinity.c b/kernel/drivers/infiniband/hw/hfi1/affinity.c
index 04b1e8f..d5a8d01 100644
--- a/kernel/drivers/infiniband/hw/hfi1/affinity.c
+++ b/kernel/drivers/infiniband/hw/hfi1/affinity.c
@@ -219,6 +219,8 @@
 	for (node = 0; node < node_affinity.num_possible_nodes; node++)
 		hfi1_per_node_cntr[node] = 1;
 
+	pci_dev_put(dev);
+
 	return 0;
 }
 
diff --git a/kernel/drivers/infiniband/hw/hfi1/chip.c b/kernel/drivers/infiniband/hw/hfi1/chip.c
index 88476a1..c74868f 100644
--- a/kernel/drivers/infiniband/hw/hfi1/chip.c
+++ b/kernel/drivers/infiniband/hw/hfi1/chip.c
@@ -1097,7 +1097,7 @@
 static void handle_temp_err(struct hfi1_devdata *dd);
 static void dc_shutdown(struct hfi1_devdata *dd);
 static void dc_start(struct hfi1_devdata *dd);
-static int qos_rmt_entries(struct hfi1_devdata *dd, unsigned int *mp,
+static int qos_rmt_entries(unsigned int n_krcv_queues, unsigned int *mp,
 			   unsigned int *np);
 static void clear_full_mgmt_pkey(struct hfi1_pportdata *ppd);
 static int wait_link_transfer_active(struct hfi1_devdata *dd, int wait_ms);
@@ -12348,6 +12348,7 @@
 
 	if (dd->synth_stats_timer.function)
 		del_timer_sync(&dd->synth_stats_timer);
+	cancel_work_sync(&dd->update_cntr_work);
 	ppd = (struct hfi1_pportdata *)(dd + 1);
 	for (i = 0; i < dd->num_pports; i++, ppd++) {
 		kfree(ppd->cntrs);
@@ -13403,7 +13404,6 @@
 	int ret;
 	unsigned ngroups;
 	int rmt_count;
-	int user_rmt_reduced;
 	u32 n_usr_ctxts;
 	u32 send_contexts = chip_send_contexts(dd);
 	u32 rcv_contexts = chip_rcv_contexts(dd);
@@ -13462,28 +13462,34 @@
 					 (num_kernel_contexts + n_usr_ctxts),
 					 &node_affinity.real_cpu_mask);
 	/*
-	 * The RMT entries are currently allocated as shown below:
-	 * 1. QOS (0 to 128 entries);
-	 * 2. FECN (num_kernel_context - 1 + num_user_contexts +
-	 *    num_netdev_contexts);
-	 * 3. netdev (num_netdev_contexts).
-	 * It should be noted that FECN oversubscribe num_netdev_contexts
-	 * entries of RMT because both netdev and PSM could allocate any receive
-	 * context between dd->first_dyn_alloc_text and dd->num_rcv_contexts,
-	 * and PSM FECN must reserve an RMT entry for each possible PSM receive
-	 * context.
+	 * RMT entries are allocated as follows:
+	 * 1. QOS (0 to 128 entries)
+	 * 2. FECN (num_kernel_context - 1 [a] + num_user_contexts +
+	 *          num_netdev_contexts [b])
+	 * 3. netdev (NUM_NETDEV_MAP_ENTRIES)
+	 *
+	 * Notes:
+	 * [a] Kernel contexts (except control) are included in FECN if kernel
+	 *     TID_RDMA is active.
+	 * [b] Netdev and user contexts are randomly allocated from the same
+	 *     context pool, so FECN must cover all contexts in the pool.
 	 */
-	rmt_count = qos_rmt_entries(dd, NULL, NULL) + (num_netdev_contexts * 2);
-	if (HFI1_CAP_IS_KSET(TID_RDMA))
-		rmt_count += num_kernel_contexts - 1;
-	if (rmt_count + n_usr_ctxts > NUM_MAP_ENTRIES) {
-		user_rmt_reduced = NUM_MAP_ENTRIES - rmt_count;
-		dd_dev_err(dd,
-			   "RMT size is reducing the number of user receive contexts from %u to %d\n",
-			   n_usr_ctxts,
-			   user_rmt_reduced);
-		/* recalculate */
-		n_usr_ctxts = user_rmt_reduced;
+	rmt_count = qos_rmt_entries(num_kernel_contexts - 1, NULL, NULL)
+		    + (HFI1_CAP_IS_KSET(TID_RDMA) ? num_kernel_contexts - 1
+						  : 0)
+		    + n_usr_ctxts
+		    + num_netdev_contexts
+		    + NUM_NETDEV_MAP_ENTRIES;
+	if (rmt_count > NUM_MAP_ENTRIES) {
+		int over = rmt_count - NUM_MAP_ENTRIES;
+		/* try to squish user contexts, minimum of 1 */
+		if (over >= n_usr_ctxts) {
+			dd_dev_err(dd, "RMT overflow: reduce the requested number of contexts\n");
+			return -EINVAL;
+		}
+		dd_dev_err(dd, "RMT overflow: reducing # user contexts from %u to %u\n",
+			   n_usr_ctxts, n_usr_ctxts - over);
+		n_usr_ctxts -= over;
 	}
 
 	/* the first N are kernel contexts, the rest are user/netdev contexts */
@@ -14340,15 +14346,15 @@
 }
 
 /* return the number of RSM map table entries that will be used for QOS */
-static int qos_rmt_entries(struct hfi1_devdata *dd, unsigned int *mp,
+static int qos_rmt_entries(unsigned int n_krcv_queues, unsigned int *mp,
 			   unsigned int *np)
 {
 	int i;
 	unsigned int m, n;
-	u8 max_by_vl = 0;
+	uint max_by_vl = 0;
 
 	/* is QOS active at all? */
-	if (dd->n_krcv_queues <= MIN_KERNEL_KCTXTS ||
+	if (n_krcv_queues < MIN_KERNEL_KCTXTS ||
 	    num_vls == 1 ||
 	    krcvqsset <= 1)
 		goto no_qos;
@@ -14406,7 +14412,7 @@
 
 	if (!rmt)
 		goto bail;
-	rmt_entries = qos_rmt_entries(dd, &m, &n);
+	rmt_entries = qos_rmt_entries(dd->n_krcv_queues - 1, &m, &n);
 	if (rmt_entries == 0)
 		goto bail;
 	qpns_per_vl = 1 << m;
diff --git a/kernel/drivers/infiniband/hw/hfi1/file_ops.c b/kernel/drivers/infiniband/hw/hfi1/file_ops.c
index d84b109..7828fb5 100644
--- a/kernel/drivers/infiniband/hw/hfi1/file_ops.c
+++ b/kernel/drivers/infiniband/hw/hfi1/file_ops.c
@@ -1359,12 +1359,15 @@
 		addr = arg + offsetof(struct hfi1_tid_info, tidcnt);
 		if (copy_to_user((void __user *)addr, &tinfo.tidcnt,
 				 sizeof(tinfo.tidcnt)))
-			return -EFAULT;
+			ret = -EFAULT;
 
 		addr = arg + offsetof(struct hfi1_tid_info, length);
-		if (copy_to_user((void __user *)addr, &tinfo.length,
+		if (!ret && copy_to_user((void __user *)addr, &tinfo.length,
 				 sizeof(tinfo.length)))
 			ret = -EFAULT;
+
+		if (ret)
+			hfi1_user_exp_rcv_invalid(fd, &tinfo);
 	}
 
 	return ret;
diff --git a/kernel/drivers/infiniband/hw/hfi1/firmware.c b/kernel/drivers/infiniband/hw/hfi1/firmware.c
index 2cf102b..f3e64c8 100644
--- a/kernel/drivers/infiniband/hw/hfi1/firmware.c
+++ b/kernel/drivers/infiniband/hw/hfi1/firmware.c
@@ -1786,6 +1786,7 @@
 
 	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 @@
 	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 @@
 	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 @@
 			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 @@
 					   __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 @@
 					   __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 =
diff --git a/kernel/drivers/infiniband/hw/hfi1/ipoib_tx.c b/kernel/drivers/infiniband/hw/hfi1/ipoib_tx.c
index ab1eeff..1880484 100644
--- a/kernel/drivers/infiniband/hw/hfi1/ipoib_tx.c
+++ b/kernel/drivers/infiniband/hw/hfi1/ipoib_tx.c
@@ -15,6 +15,7 @@
 #include "verbs.h"
 #include "trace_ibhdrs.h"
 #include "ipoib.h"
+#include "trace_tx.h"
 
 /* Add a convenience helper */
 #define CIRC_ADD(val, add, size) (((val) + (add)) & ((size) - 1))
@@ -63,12 +64,14 @@
 
 static void hfi1_ipoib_stop_txq(struct hfi1_ipoib_txq *txq)
 {
+	trace_hfi1_txq_stop(txq);
 	if (atomic_inc_return(&txq->stops) == 1)
 		netif_stop_subqueue(txq->priv->netdev, txq->q_idx);
 }
 
 static void hfi1_ipoib_wake_txq(struct hfi1_ipoib_txq *txq)
 {
+	trace_hfi1_txq_wake(txq);
 	if (atomic_dec_and_test(&txq->stops))
 		netif_wake_subqueue(txq->priv->netdev, txq->q_idx);
 }
@@ -89,8 +92,10 @@
 {
 	++txq->sent_txreqs;
 	if (hfi1_ipoib_used(txq) >= hfi1_ipoib_ring_hwat(txq) &&
-	    !atomic_xchg(&txq->ring_full, 1))
+	    !atomic_xchg(&txq->ring_full, 1)) {
+		trace_hfi1_txq_full(txq);
 		hfi1_ipoib_stop_txq(txq);
+	}
 }
 
 static void hfi1_ipoib_check_queue_stopped(struct hfi1_ipoib_txq *txq)
@@ -112,8 +117,10 @@
 	 * to protect against ring overflow.
 	 */
 	if (hfi1_ipoib_used(txq) < hfi1_ipoib_ring_lwat(txq) &&
-	    atomic_xchg(&txq->ring_full, 0))
+	    atomic_xchg(&txq->ring_full, 0)) {
+		trace_hfi1_txq_xmit_unstopped(txq);
 		hfi1_ipoib_wake_txq(txq);
+	}
 }
 
 static void hfi1_ipoib_free_tx(struct ipoib_txreq *tx, int budget)
@@ -247,7 +254,8 @@
 				      txreq,
 				      skb_frag_page(frag),
 				      frag->bv_offset,
-				      skb_frag_size(frag));
+				      skb_frag_size(frag),
+				      NULL, NULL, NULL);
 		if (unlikely(ret))
 			break;
 	}
@@ -405,6 +413,7 @@
 				sdma_select_engine_sc(priv->dd,
 						      txp->flow.tx_queue,
 						      txp->flow.sc5);
+			trace_hfi1_flow_switch(txp->txq);
 		}
 
 		return tx;
@@ -525,6 +534,7 @@
 	if (txq->flow.as_int != txp->flow.as_int) {
 		int ret;
 
+		trace_hfi1_flow_flush(txq);
 		ret = hfi1_ipoib_flush_tx_list(dev, txq);
 		if (unlikely(ret)) {
 			if (ret == -EBUSY)
@@ -635,8 +645,10 @@
 			/* came from non-list submit */
 			list_add_tail(&txreq->list, &txq->tx_list);
 		if (list_empty(&txq->wait.list)) {
-			if (!atomic_xchg(&txq->no_desc, 1))
+			if (!atomic_xchg(&txq->no_desc, 1)) {
+				trace_hfi1_txq_queued(txq);
 				hfi1_ipoib_stop_txq(txq);
+			}
 			iowait_queue(pkts_sent, wait->iow, &sde->dmawait);
 		}
 
@@ -659,6 +671,7 @@
 	struct hfi1_ipoib_txq *txq =
 		container_of(wait, struct hfi1_ipoib_txq, wait);
 
+	trace_hfi1_txq_wakeup(txq);
 	if (likely(txq->priv->netdev->reg_state == NETREG_REGISTERED))
 		iowait_schedule(wait, system_highpri_wq, WORK_CPU_UNBOUND);
 }
diff --git a/kernel/drivers/infiniband/hw/hfi1/mmu_rb.c b/kernel/drivers/infiniband/hw/hfi1/mmu_rb.c
index ed8a96a..a501b7a 100644
--- a/kernel/drivers/infiniband/hw/hfi1/mmu_rb.c
+++ b/kernel/drivers/infiniband/hw/hfi1/mmu_rb.c
@@ -60,8 +60,7 @@
 		const struct mmu_notifier_range *);
 static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *,
 					   unsigned long, unsigned long);
-static void do_remove(struct mmu_rb_handler *handler,
-		      struct list_head *del_list);
+static void release_immediate(struct kref *refcount);
 static void handle_remove(struct work_struct *work);
 
 static const struct mmu_notifier_ops mn_opts = {
@@ -144,7 +143,11 @@
 	}
 	spin_unlock_irqrestore(&handler->lock, flags);
 
-	do_remove(handler, &del_list);
+	while (!list_empty(&del_list)) {
+		rbnode = list_first_entry(&del_list, struct mmu_rb_node, list);
+		list_del(&rbnode->list);
+		kref_put(&rbnode->refcount, release_immediate);
+	}
 
 	/* Now the mm may be freed. */
 	mmdrop(handler->mn.mm);
@@ -167,21 +170,28 @@
 	spin_lock_irqsave(&handler->lock, flags);
 	node = __mmu_rb_search(handler, mnode->addr, mnode->len);
 	if (node) {
-		ret = -EINVAL;
+		ret = -EEXIST;
 		goto unlock;
 	}
 	__mmu_int_rb_insert(mnode, &handler->root);
-	list_add(&mnode->list, &handler->lru_list);
-
-	ret = handler->ops->insert(handler->ops_arg, mnode);
-	if (ret) {
-		__mmu_int_rb_remove(mnode, &handler->root);
-		list_del(&mnode->list); /* remove from LRU list */
-	}
+	list_add_tail(&mnode->list, &handler->lru_list);
 	mnode->handler = handler;
 unlock:
 	spin_unlock_irqrestore(&handler->lock, flags);
 	return ret;
+}
+
+/* Caller must hold handler lock */
+struct mmu_rb_node *hfi1_mmu_rb_get_first(struct mmu_rb_handler *handler,
+					  unsigned long addr, unsigned long len)
+{
+	struct mmu_rb_node *node;
+
+	trace_hfi1_mmu_rb_search(addr, len);
+	node = __mmu_int_rb_iter_first(&handler->root, addr, (addr + len) - 1);
+	if (node)
+		list_move_tail(&node->list, &handler->lru_list);
+	return node;
 }
 
 /* Caller must hold handler lock */
@@ -208,30 +218,46 @@
 	return node;
 }
 
-bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler,
-				     unsigned long addr, unsigned long len,
-				     struct mmu_rb_node **rb_node)
+/*
+ * Must NOT call while holding mnode->handler->lock.
+ * mnode->handler->ops->remove() may sleep and mnode->handler->lock is a
+ * spinlock.
+ */
+static void release_immediate(struct kref *refcount)
 {
-	struct mmu_rb_node *node;
-	unsigned long flags;
-	bool ret = false;
+	struct mmu_rb_node *mnode =
+		container_of(refcount, struct mmu_rb_node, refcount);
+	mnode->handler->ops->remove(mnode->handler->ops_arg, mnode);
+}
 
-	if (current->mm != handler->mn.mm)
-		return ret;
+/* Caller must hold mnode->handler->lock */
+static void release_nolock(struct kref *refcount)
+{
+	struct mmu_rb_node *mnode =
+		container_of(refcount, struct mmu_rb_node, refcount);
+	list_move(&mnode->list, &mnode->handler->del_list);
+	queue_work(mnode->handler->wq, &mnode->handler->del_work);
+}
+
+/*
+ * struct mmu_rb_node->refcount kref_put() callback.
+ * Adds mmu_rb_node to mmu_rb_node->handler->del_list and queues
+ * handler->del_work on handler->wq.
+ * Does not remove mmu_rb_node from handler->lru_list or handler->rb_root.
+ * Acquires mmu_rb_node->handler->lock; do not call while already holding
+ * handler->lock.
+ */
+void hfi1_mmu_rb_release(struct kref *refcount)
+{
+	struct mmu_rb_node *mnode =
+		container_of(refcount, struct mmu_rb_node, refcount);
+	struct mmu_rb_handler *handler = mnode->handler;
+	unsigned long flags;
 
 	spin_lock_irqsave(&handler->lock, flags);
-	node = __mmu_rb_search(handler, addr, len);
-	if (node) {
-		if (node->addr == addr && node->len == len)
-			goto unlock;
-		__mmu_int_rb_remove(node, &handler->root);
-		list_del(&node->list); /* remove from LRU list */
-		ret = true;
-	}
-unlock:
+	list_move(&mnode->list, &mnode->handler->del_list);
 	spin_unlock_irqrestore(&handler->lock, flags);
-	*rb_node = node;
-	return ret;
+	queue_work(handler->wq, &handler->del_work);
 }
 
 void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg)
@@ -247,8 +273,11 @@
 	INIT_LIST_HEAD(&del_list);
 
 	spin_lock_irqsave(&handler->lock, flags);
-	list_for_each_entry_safe_reverse(rbnode, ptr, &handler->lru_list,
-					 list) {
+	list_for_each_entry_safe(rbnode, ptr, &handler->lru_list, list) {
+		/* refcount == 1 implies mmu_rb_handler has only rbnode ref */
+		if (kref_read(&rbnode->refcount) > 1)
+			continue;
+
 		if (handler->ops->evict(handler->ops_arg, rbnode, evict_arg,
 					&stop)) {
 			__mmu_int_rb_remove(rbnode, &handler->root);
@@ -260,34 +289,9 @@
 	}
 	spin_unlock_irqrestore(&handler->lock, flags);
 
-	while (!list_empty(&del_list)) {
-		rbnode = list_first_entry(&del_list, struct mmu_rb_node, list);
-		list_del(&rbnode->list);
-		handler->ops->remove(handler->ops_arg, rbnode);
+	list_for_each_entry_safe(rbnode, ptr, &del_list, list) {
+		kref_put(&rbnode->refcount, release_immediate);
 	}
-}
-
-/*
- * It is up to the caller to ensure that this function does not race with the
- * mmu invalidate notifier which may be calling the users remove callback on
- * 'node'.
- */
-void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler,
-			struct mmu_rb_node *node)
-{
-	unsigned long flags;
-
-	if (current->mm != handler->mn.mm)
-		return;
-
-	/* Validity of handler and node pointers has been checked by caller. */
-	trace_hfi1_mmu_rb_remove(node->addr, node->len);
-	spin_lock_irqsave(&handler->lock, flags);
-	__mmu_int_rb_remove(node, &handler->root);
-	list_del(&node->list); /* remove from LRU list */
-	spin_unlock_irqrestore(&handler->lock, flags);
-
-	handler->ops->remove(handler->ops_arg, node);
 }
 
 static int mmu_notifier_range_start(struct mmu_notifier *mn,
@@ -298,7 +302,6 @@
 	struct rb_root_cached *root = &handler->root;
 	struct mmu_rb_node *node, *ptr = NULL;
 	unsigned long flags;
-	bool added = false;
 
 	spin_lock_irqsave(&handler->lock, flags);
 	for (node = __mmu_int_rb_iter_first(root, range->start, range->end-1);
@@ -307,36 +310,14 @@
 		ptr = __mmu_int_rb_iter_next(node, range->start,
 					     range->end - 1);
 		trace_hfi1_mmu_mem_invalidate(node->addr, node->len);
-		if (handler->ops->invalidate(handler->ops_arg, node)) {
-			__mmu_int_rb_remove(node, root);
-			/* move from LRU list to delete list */
-			list_move(&node->list, &handler->del_list);
-			added = true;
-		}
+		/* Remove from rb tree and lru_list. */
+		__mmu_int_rb_remove(node, root);
+		list_del_init(&node->list);
+		kref_put(&node->refcount, release_nolock);
 	}
 	spin_unlock_irqrestore(&handler->lock, flags);
 
-	if (added)
-		queue_work(handler->wq, &handler->del_work);
-
 	return 0;
-}
-
-/*
- * Call the remove function for the given handler and the list.  This
- * is expected to be called with a delete list extracted from handler.
- * The caller should not be holding the handler lock.
- */
-static void do_remove(struct mmu_rb_handler *handler,
-		      struct list_head *del_list)
-{
-	struct mmu_rb_node *node;
-
-	while (!list_empty(del_list)) {
-		node = list_first_entry(del_list, struct mmu_rb_node, list);
-		list_del(&node->list);
-		handler->ops->remove(handler->ops_arg, node);
-	}
 }
 
 /*
@@ -351,11 +332,16 @@
 						del_work);
 	struct list_head del_list;
 	unsigned long flags;
+	struct mmu_rb_node *node;
 
 	/* remove anything that is queued to get removed */
 	spin_lock_irqsave(&handler->lock, flags);
 	list_replace_init(&handler->del_list, &del_list);
 	spin_unlock_irqrestore(&handler->lock, flags);
 
-	do_remove(handler, &del_list);
+	while (!list_empty(&del_list)) {
+		node = list_first_entry(&del_list, struct mmu_rb_node, list);
+		list_del(&node->list);
+		handler->ops->remove(handler->ops_arg, node);
+	}
 }
diff --git a/kernel/drivers/infiniband/hw/hfi1/mmu_rb.h b/kernel/drivers/infiniband/hw/hfi1/mmu_rb.h
index 423aacc..be85537 100644
--- a/kernel/drivers/infiniband/hw/hfi1/mmu_rb.h
+++ b/kernel/drivers/infiniband/hw/hfi1/mmu_rb.h
@@ -57,6 +57,7 @@
 	struct rb_node node;
 	struct mmu_rb_handler *handler;
 	struct list_head list;
+	struct kref refcount;
 };
 
 /*
@@ -92,11 +93,11 @@
 void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler);
 int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler,
 		       struct mmu_rb_node *mnode);
+void hfi1_mmu_rb_release(struct kref *refcount);
+
 void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg);
-void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler,
-			struct mmu_rb_node *mnode);
-bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler,
-				     unsigned long addr, unsigned long len,
-				     struct mmu_rb_node **rb_node);
+struct mmu_rb_node *hfi1_mmu_rb_get_first(struct mmu_rb_handler *handler,
+					  unsigned long addr,
+					  unsigned long len);
 
 #endif /* _HFI1_MMU_RB_H */
diff --git a/kernel/drivers/infiniband/hw/hfi1/sdma.c b/kernel/drivers/infiniband/hw/hfi1/sdma.c
index a044bee..2dc97de 100644
--- a/kernel/drivers/infiniband/hw/hfi1/sdma.c
+++ b/kernel/drivers/infiniband/hw/hfi1/sdma.c
@@ -1637,20 +1637,18 @@
 {
 	switch (sdma_mapping_type(descp)) {
 	case SDMA_MAP_SINGLE:
-		dma_unmap_single(
-			&dd->pcidev->dev,
-			sdma_mapping_addr(descp),
-			sdma_mapping_len(descp),
-			DMA_TO_DEVICE);
+		dma_unmap_single(&dd->pcidev->dev, sdma_mapping_addr(descp),
+				 sdma_mapping_len(descp), DMA_TO_DEVICE);
 		break;
 	case SDMA_MAP_PAGE:
-		dma_unmap_page(
-			&dd->pcidev->dev,
-			sdma_mapping_addr(descp),
-			sdma_mapping_len(descp),
-			DMA_TO_DEVICE);
+		dma_unmap_page(&dd->pcidev->dev, sdma_mapping_addr(descp),
+			       sdma_mapping_len(descp), DMA_TO_DEVICE);
 		break;
 	}
+
+	if (descp->pinning_ctx && descp->ctx_put)
+		descp->ctx_put(descp->pinning_ctx);
+	descp->pinning_ctx = NULL;
 }
 
 /*
@@ -3171,7 +3169,7 @@
 		/* Add descriptor for coalesce buffer */
 		tx->desc_limit = MAX_DESC;
 		return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, tx,
-					 addr, tx->tlen);
+					 addr, tx->tlen, NULL, NULL, NULL);
 	}
 
 	return 1;
@@ -3202,20 +3200,22 @@
 {
 	int rval = 0;
 
-	tx->num_desc++;
-	if ((unlikely(tx->num_desc == tx->desc_limit))) {
+	if ((unlikely(tx->num_desc + 1 == tx->desc_limit))) {
 		rval = _extend_sdma_tx_descs(dd, tx);
 		if (rval) {
 			__sdma_txclean(dd, tx);
 			return rval;
 		}
 	}
+
 	/* finish the one just added */
 	make_tx_sdma_desc(
 		tx,
 		SDMA_MAP_NONE,
 		dd->sdma_pad_phys,
-		sizeof(u32) - (tx->packet_len & (sizeof(u32) - 1)));
+		sizeof(u32) - (tx->packet_len & (sizeof(u32) - 1)),
+		NULL, NULL, NULL);
+	tx->num_desc++;
 	_sdma_close_tx(dd, tx);
 	return rval;
 }
diff --git a/kernel/drivers/infiniband/hw/hfi1/sdma.h b/kernel/drivers/infiniband/hw/hfi1/sdma.h
index 7a85119..7611f09 100644
--- a/kernel/drivers/infiniband/hw/hfi1/sdma.h
+++ b/kernel/drivers/infiniband/hw/hfi1/sdma.h
@@ -636,7 +636,10 @@
 	struct sdma_txreq *tx,
 	int type,
 	dma_addr_t addr,
-	size_t len)
+	size_t len,
+	void *pinning_ctx,
+	void (*ctx_get)(void *),
+	void (*ctx_put)(void *))
 {
 	struct sdma_desc *desc = &tx->descp[tx->num_desc];
 
@@ -653,6 +656,11 @@
 				<< SDMA_DESC0_PHY_ADDR_SHIFT) |
 			(((u64)len & SDMA_DESC0_BYTE_COUNT_MASK)
 				<< SDMA_DESC0_BYTE_COUNT_SHIFT);
+
+	desc->pinning_ctx = pinning_ctx;
+	desc->ctx_put = ctx_put;
+	if (pinning_ctx && ctx_get)
+		ctx_get(pinning_ctx);
 }
 
 /* helper to extend txreq */
@@ -672,14 +680,13 @@
 static inline void _sdma_close_tx(struct hfi1_devdata *dd,
 				  struct sdma_txreq *tx)
 {
-	tx->descp[tx->num_desc].qw[0] |=
-		SDMA_DESC0_LAST_DESC_FLAG;
-	tx->descp[tx->num_desc].qw[1] |=
-		dd->default_desc1;
+	u16 last_desc = tx->num_desc - 1;
+
+	tx->descp[last_desc].qw[0] |= SDMA_DESC0_LAST_DESC_FLAG;
+	tx->descp[last_desc].qw[1] |= dd->default_desc1;
 	if (tx->flags & SDMA_TXREQ_F_URGENT)
-		tx->descp[tx->num_desc].qw[1] |=
-			(SDMA_DESC1_HEAD_TO_HOST_FLAG |
-			 SDMA_DESC1_INT_REQ_FLAG);
+		tx->descp[last_desc].qw[1] |= (SDMA_DESC1_HEAD_TO_HOST_FLAG |
+					       SDMA_DESC1_INT_REQ_FLAG);
 }
 
 static inline int _sdma_txadd_daddr(
@@ -687,15 +694,20 @@
 	int type,
 	struct sdma_txreq *tx,
 	dma_addr_t addr,
-	u16 len)
+	u16 len,
+	void *pinning_ctx,
+	void (*ctx_get)(void *),
+	void (*ctx_put)(void *))
 {
 	int rval = 0;
 
 	make_tx_sdma_desc(
 		tx,
 		type,
-		addr, len);
+		addr, len,
+		pinning_ctx, ctx_get, ctx_put);
 	WARN_ON(len > tx->tlen);
+	tx->num_desc++;
 	tx->tlen -= len;
 	/* special cases for last */
 	if (!tx->tlen) {
@@ -707,7 +719,6 @@
 			_sdma_close_tx(dd, tx);
 		}
 	}
-	tx->num_desc++;
 	return rval;
 }
 
@@ -718,6 +729,14 @@
  * @page: page to map
  * @offset: offset within the page
  * @len: length in bytes
+ * @pinning_ctx: context to be stored on struct sdma_desc .pinning_ctx. Not
+ *               added if coalesce buffer is used. E.g. pointer to pinned-page
+ *               cache entry for the sdma_desc.
+ * @ctx_get: optional function to take reference to @pinning_ctx. Not called if
+ *           @pinning_ctx is NULL.
+ * @ctx_put: optional function to release reference to @pinning_ctx after
+ *           sdma_desc completes. May be called in interrupt context so must
+ *           not sleep. Not called if @pinning_ctx is NULL.
  *
  * This is used to add a page/offset/length descriptor.
  *
@@ -732,7 +751,10 @@
 	struct sdma_txreq *tx,
 	struct page *page,
 	unsigned long offset,
-	u16 len)
+	u16 len,
+	void *pinning_ctx,
+	void (*ctx_get)(void *),
+	void (*ctx_put)(void *))
 {
 	dma_addr_t addr;
 	int rval;
@@ -756,8 +778,8 @@
 		return -ENOSPC;
 	}
 
-	return _sdma_txadd_daddr(
-			dd, SDMA_MAP_PAGE, tx, addr, len);
+	return _sdma_txadd_daddr(dd, SDMA_MAP_PAGE, tx, addr, len,
+				 pinning_ctx, ctx_get, ctx_put);
 }
 
 /**
@@ -791,7 +813,8 @@
 			return rval;
 	}
 
-	return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, tx, addr, len);
+	return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, tx, addr, len,
+				 NULL, NULL, NULL);
 }
 
 /**
@@ -837,8 +860,8 @@
 		return -ENOSPC;
 	}
 
-	return _sdma_txadd_daddr(
-			dd, SDMA_MAP_SINGLE, tx, addr, len);
+	return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, tx, addr, len,
+				 NULL, NULL, NULL);
 }
 
 struct iowait_work;
@@ -1089,5 +1112,4 @@
 extern uint mod_num_sdma;
 
 void sdma_update_lmc(struct hfi1_devdata *dd, u64 mask, u32 lid);
-
 #endif
diff --git a/kernel/drivers/infiniband/hw/hfi1/sdma_txreq.h b/kernel/drivers/infiniband/hw/hfi1/sdma_txreq.h
index 514a478..fb091b5 100644
--- a/kernel/drivers/infiniband/hw/hfi1/sdma_txreq.h
+++ b/kernel/drivers/infiniband/hw/hfi1/sdma_txreq.h
@@ -61,6 +61,9 @@
 struct sdma_desc {
 	/* private:  don't use directly */
 	u64 qw[2];
+	void *pinning_ctx;
+	/* Release reference to @pinning_ctx. May be called in interrupt context. Must not sleep. */
+	void (*ctx_put)(void *ctx);
 };
 
 /**
diff --git a/kernel/drivers/infiniband/hw/hfi1/trace_mmu.h b/kernel/drivers/infiniband/hw/hfi1/trace_mmu.h
index 3b7abbc..c3055cf 100644
--- a/kernel/drivers/infiniband/hw/hfi1/trace_mmu.h
+++ b/kernel/drivers/infiniband/hw/hfi1/trace_mmu.h
@@ -78,10 +78,6 @@
 	     TP_PROTO(unsigned long addr, unsigned long len),
 	     TP_ARGS(addr, len));
 
-DEFINE_EVENT(hfi1_mmu_rb_template, hfi1_mmu_rb_remove,
-	     TP_PROTO(unsigned long addr, unsigned long len),
-	     TP_ARGS(addr, len));
-
 DEFINE_EVENT(hfi1_mmu_rb_template, hfi1_mmu_mem_invalidate,
 	     TP_PROTO(unsigned long addr, unsigned long len),
 	     TP_ARGS(addr, len));
diff --git a/kernel/drivers/infiniband/hw/hfi1/trace_tx.h b/kernel/drivers/infiniband/hw/hfi1/trace_tx.h
index 769e5e4..d44fc54 100644
--- a/kernel/drivers/infiniband/hw/hfi1/trace_tx.h
+++ b/kernel/drivers/infiniband/hw/hfi1/trace_tx.h
@@ -53,6 +53,8 @@
 #include "hfi.h"
 #include "mad.h"
 #include "sdma.h"
+#include "ipoib.h"
+#include "user_sdma.h"
 
 const char *parse_sdma_flags(struct trace_seq *p, u64 desc0, u64 desc1);
 
@@ -653,6 +655,80 @@
 		      __entry->code)
 );
 
+TRACE_EVENT(hfi1_usdma_defer,
+	    TP_PROTO(struct hfi1_user_sdma_pkt_q *pq,
+		     struct sdma_engine *sde,
+		     struct iowait *wait),
+	    TP_ARGS(pq, sde, wait),
+	    TP_STRUCT__entry(DD_DEV_ENTRY(pq->dd)
+			     __field(struct hfi1_user_sdma_pkt_q *, pq)
+			     __field(struct sdma_engine *, sde)
+			     __field(struct iowait *, wait)
+			     __field(int, engine)
+			     __field(int, empty)
+			     ),
+	     TP_fast_assign(DD_DEV_ASSIGN(pq->dd);
+			    __entry->pq = pq;
+			    __entry->sde = sde;
+			    __entry->wait = wait;
+			    __entry->engine = sde->this_idx;
+			    __entry->empty = list_empty(&__entry->wait->list);
+			    ),
+	     TP_printk("[%s] pq %llx sde %llx wait %llx engine %d empty %d",
+		       __get_str(dev),
+		       (unsigned long long)__entry->pq,
+		       (unsigned long long)__entry->sde,
+		       (unsigned long long)__entry->wait,
+		       __entry->engine,
+		       __entry->empty
+		)
+);
+
+TRACE_EVENT(hfi1_usdma_activate,
+	    TP_PROTO(struct hfi1_user_sdma_pkt_q *pq,
+		     struct iowait *wait,
+		     int reason),
+	    TP_ARGS(pq, wait, reason),
+	    TP_STRUCT__entry(DD_DEV_ENTRY(pq->dd)
+			     __field(struct hfi1_user_sdma_pkt_q *, pq)
+			     __field(struct iowait *, wait)
+			     __field(int, reason)
+			     ),
+	     TP_fast_assign(DD_DEV_ASSIGN(pq->dd);
+			    __entry->pq = pq;
+			    __entry->wait = wait;
+			    __entry->reason = reason;
+			    ),
+	     TP_printk("[%s] pq %llx wait %llx reason %d",
+		       __get_str(dev),
+		       (unsigned long long)__entry->pq,
+		       (unsigned long long)__entry->wait,
+		       __entry->reason
+		)
+);
+
+TRACE_EVENT(hfi1_usdma_we,
+	    TP_PROTO(struct hfi1_user_sdma_pkt_q *pq,
+		     int we_ret),
+	    TP_ARGS(pq, we_ret),
+	    TP_STRUCT__entry(DD_DEV_ENTRY(pq->dd)
+			     __field(struct hfi1_user_sdma_pkt_q *, pq)
+			     __field(int, state)
+			     __field(int, we_ret)
+			     ),
+	     TP_fast_assign(DD_DEV_ASSIGN(pq->dd);
+			    __entry->pq = pq;
+			    __entry->state = pq->state;
+			    __entry->we_ret = we_ret;
+			    ),
+	     TP_printk("[%s] pq %llx state %d we_ret %d",
+		       __get_str(dev),
+		       (unsigned long long)__entry->pq,
+		       __entry->state,
+		       __entry->we_ret
+		)
+);
+
 const char *print_u32_array(struct trace_seq *, u32 *, int);
 #define __print_u32_hex(arr, len) print_u32_array(p, arr, len)
 
@@ -858,6 +934,109 @@
 	TP_ARGS(qp, flag)
 );
 
+DECLARE_EVENT_CLASS(/* AIP  */
+	hfi1_ipoib_txq_template,
+	TP_PROTO(struct hfi1_ipoib_txq *txq),
+	TP_ARGS(txq),
+	TP_STRUCT__entry(/* entry */
+		DD_DEV_ENTRY(txq->priv->dd)
+		__field(struct hfi1_ipoib_txq *, txq)
+		__field(struct sdma_engine *, sde)
+		__field(ulong, head)
+		__field(ulong, tail)
+		__field(uint, used)
+		__field(uint, flow)
+		__field(int, stops)
+		__field(int, no_desc)
+		__field(u8, idx)
+		__field(u8, stopped)
+	),
+	TP_fast_assign(/* assign */
+		DD_DEV_ASSIGN(txq->priv->dd)
+		__entry->txq = txq;
+		__entry->sde = txq->sde;
+		__entry->head = txq->tx_ring.head;
+		__entry->tail = txq->tx_ring.tail;
+		__entry->idx = txq->q_idx;
+		__entry->used =
+			txq->sent_txreqs -
+			atomic64_read(&txq->complete_txreqs);
+		__entry->flow = txq->flow.as_int;
+		__entry->stops = atomic_read(&txq->stops);
+		__entry->no_desc = atomic_read(&txq->no_desc);
+		__entry->stopped =
+		 __netif_subqueue_stopped(txq->priv->netdev, txq->q_idx);
+	),
+	TP_printk(/* print  */
+		"[%s] txq %llx idx %u sde %llx head %lx tail %lx flow %x used %u stops %d no_desc %d stopped %u",
+		__get_str(dev),
+		(unsigned long long)__entry->txq,
+		__entry->idx,
+		(unsigned long long)__entry->sde,
+		__entry->head,
+		__entry->tail,
+		__entry->flow,
+		__entry->used,
+		__entry->stops,
+		__entry->no_desc,
+		__entry->stopped
+	)
+);
+
+DEFINE_EVENT(/* queue stop */
+	hfi1_ipoib_txq_template, hfi1_txq_stop,
+	TP_PROTO(struct hfi1_ipoib_txq *txq),
+	TP_ARGS(txq)
+);
+
+DEFINE_EVENT(/* queue wake */
+	hfi1_ipoib_txq_template, hfi1_txq_wake,
+	TP_PROTO(struct hfi1_ipoib_txq *txq),
+	TP_ARGS(txq)
+);
+
+DEFINE_EVENT(/* flow flush */
+	hfi1_ipoib_txq_template, hfi1_flow_flush,
+	TP_PROTO(struct hfi1_ipoib_txq *txq),
+	TP_ARGS(txq)
+);
+
+DEFINE_EVENT(/* flow switch */
+	hfi1_ipoib_txq_template, hfi1_flow_switch,
+	TP_PROTO(struct hfi1_ipoib_txq *txq),
+	TP_ARGS(txq)
+);
+
+DEFINE_EVENT(/* wakeup */
+	hfi1_ipoib_txq_template, hfi1_txq_wakeup,
+	TP_PROTO(struct hfi1_ipoib_txq *txq),
+	TP_ARGS(txq)
+);
+
+DEFINE_EVENT(/* full */
+	hfi1_ipoib_txq_template, hfi1_txq_full,
+	TP_PROTO(struct hfi1_ipoib_txq *txq),
+	TP_ARGS(txq)
+);
+
+DEFINE_EVENT(/* queued */
+	hfi1_ipoib_txq_template, hfi1_txq_queued,
+	TP_PROTO(struct hfi1_ipoib_txq *txq),
+	TP_ARGS(txq)
+);
+
+DEFINE_EVENT(/* xmit_stopped */
+	hfi1_ipoib_txq_template, hfi1_txq_xmit_stopped,
+	TP_PROTO(struct hfi1_ipoib_txq *txq),
+	TP_ARGS(txq)
+);
+
+DEFINE_EVENT(/* xmit_unstopped */
+	hfi1_ipoib_txq_template, hfi1_txq_xmit_unstopped,
+	TP_PROTO(struct hfi1_ipoib_txq *txq),
+	TP_ARGS(txq)
+);
+
 #endif /* __HFI1_TRACE_TX_H */
 
 #undef TRACE_INCLUDE_PATH
diff --git a/kernel/drivers/infiniband/hw/hfi1/user_exp_rcv.c b/kernel/drivers/infiniband/hw/hfi1/user_exp_rcv.c
index b94fc7f..0e0be6c 100644
--- a/kernel/drivers/infiniband/hw/hfi1/user_exp_rcv.c
+++ b/kernel/drivers/infiniband/hw/hfi1/user_exp_rcv.c
@@ -65,17 +65,24 @@
 static bool tid_rb_invalidate(struct mmu_interval_notifier *mni,
 			      const struct mmu_notifier_range *range,
 			      unsigned long cur_seq);
+static bool tid_cover_invalidate(struct mmu_interval_notifier *mni,
+			         const struct mmu_notifier_range *range,
+			         unsigned long cur_seq);
 static int program_rcvarray(struct hfi1_filedata *fd, struct tid_user_buf *,
 			    struct tid_group *grp,
 			    unsigned int start, u16 count,
 			    u32 *tidlist, unsigned int *tididx,
 			    unsigned int *pmapped);
-static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo,
-			      struct tid_group **grp);
+static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo);
+static void __clear_tid_node(struct hfi1_filedata *fd,
+			     struct tid_rb_node *node);
 static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node);
 
 static const struct mmu_interval_notifier_ops tid_mn_ops = {
 	.invalidate = tid_rb_invalidate,
+};
+static const struct mmu_interval_notifier_ops tid_cover_ops = {
+	.invalidate = tid_cover_invalidate,
 };
 
 /*
@@ -195,15 +202,10 @@
 static int pin_rcv_pages(struct hfi1_filedata *fd, struct tid_user_buf *tidbuf)
 {
 	int pinned;
-	unsigned int npages;
+	unsigned int npages = tidbuf->npages;
 	unsigned long vaddr = tidbuf->vaddr;
 	struct page **pages = NULL;
 	struct hfi1_devdata *dd = fd->uctxt->dd;
-
-	/* Get the number of pages the user buffer spans */
-	npages = num_user_pages(vaddr, tidbuf->length);
-	if (!npages)
-		return -EINVAL;
 
 	if (npages > fd->uctxt->expected_count) {
 		dd_dev_err(dd, "Expected buffer too big\n");
@@ -231,7 +233,6 @@
 		return pinned;
 	}
 	tidbuf->pages = pages;
-	tidbuf->npages = npages;
 	fd->tid_n_pinned += pinned;
 	return pinned;
 }
@@ -295,53 +296,66 @@
 		tididx = 0, mapped, mapped_pages = 0;
 	u32 *tidlist = NULL;
 	struct tid_user_buf *tidbuf;
+	unsigned long mmu_seq = 0;
 
 	if (!PAGE_ALIGNED(tinfo->vaddr))
+		return -EINVAL;
+	if (tinfo->length == 0)
 		return -EINVAL;
 
 	tidbuf = kzalloc(sizeof(*tidbuf), GFP_KERNEL);
 	if (!tidbuf)
 		return -ENOMEM;
 
+	mutex_init(&tidbuf->cover_mutex);
 	tidbuf->vaddr = tinfo->vaddr;
 	tidbuf->length = tinfo->length;
+	tidbuf->npages = num_user_pages(tidbuf->vaddr, tidbuf->length);
 	tidbuf->psets = kcalloc(uctxt->expected_count, sizeof(*tidbuf->psets),
 				GFP_KERNEL);
 	if (!tidbuf->psets) {
-		kfree(tidbuf);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto fail_release_mem;
+	}
+
+	if (fd->use_mn) {
+		ret = mmu_interval_notifier_insert(
+			&tidbuf->notifier, current->mm,
+			tidbuf->vaddr, tidbuf->npages * PAGE_SIZE,
+			&tid_cover_ops);
+		if (ret)
+			goto fail_release_mem;
+		mmu_seq = mmu_interval_read_begin(&tidbuf->notifier);
 	}
 
 	pinned = pin_rcv_pages(fd, tidbuf);
 	if (pinned <= 0) {
-		kfree(tidbuf->psets);
-		kfree(tidbuf);
-		return pinned;
+		ret = (pinned < 0) ? pinned : -ENOSPC;
+		goto fail_unpin;
 	}
 
 	/* Find sets of physically contiguous pages */
 	tidbuf->n_psets = find_phys_blocks(tidbuf, pinned);
 
-	/*
-	 * We don't need to access this under a lock since tid_used is per
-	 * process and the same process cannot be in hfi1_user_exp_rcv_clear()
-	 * and hfi1_user_exp_rcv_setup() at the same time.
-	 */
+	/* Reserve the number of expected tids to be used. */
 	spin_lock(&fd->tid_lock);
 	if (fd->tid_used + tidbuf->n_psets > fd->tid_limit)
 		pageset_count = fd->tid_limit - fd->tid_used;
 	else
 		pageset_count = tidbuf->n_psets;
+	fd->tid_used += pageset_count;
 	spin_unlock(&fd->tid_lock);
 
-	if (!pageset_count)
-		goto bail;
+	if (!pageset_count) {
+		ret = -ENOSPC;
+		goto fail_unreserve;
+	}
 
 	ngroups = pageset_count / dd->rcv_entries.group_size;
 	tidlist = kcalloc(pageset_count, sizeof(*tidlist), GFP_KERNEL);
 	if (!tidlist) {
 		ret = -ENOMEM;
-		goto nomem;
+		goto fail_unreserve;
 	}
 
 	tididx = 0;
@@ -437,43 +451,78 @@
 	}
 unlock:
 	mutex_unlock(&uctxt->exp_mutex);
-nomem:
 	hfi1_cdbg(TID, "total mapped: tidpairs:%u pages:%u (%d)", tididx,
 		  mapped_pages, ret);
-	if (tididx) {
-		spin_lock(&fd->tid_lock);
-		fd->tid_used += tididx;
-		spin_unlock(&fd->tid_lock);
-		tinfo->tidcnt = tididx;
-		tinfo->length = mapped_pages * PAGE_SIZE;
 
-		if (copy_to_user(u64_to_user_ptr(tinfo->tidlist),
-				 tidlist, sizeof(tidlist[0]) * tididx)) {
-			/*
-			 * On failure to copy to the user level, we need to undo
-			 * everything done so far so we don't leak resources.
-			 */
-			tinfo->tidlist = (unsigned long)&tidlist;
-			hfi1_user_exp_rcv_clear(fd, tinfo);
-			tinfo->tidlist = 0;
-			ret = -EFAULT;
-			goto bail;
+	/* fail if nothing was programmed, set error if none provided */
+	if (tididx == 0) {
+		if (ret >= 0)
+			ret = -ENOSPC;
+		goto fail_unreserve;
+	}
+
+	/* adjust reserved tid_used to actual count */
+	spin_lock(&fd->tid_lock);
+	fd->tid_used -= pageset_count - tididx;
+	spin_unlock(&fd->tid_lock);
+
+	/* unpin all pages not covered by a TID */
+	unpin_rcv_pages(fd, tidbuf, NULL, mapped_pages, pinned - mapped_pages,
+			false);
+
+	if (fd->use_mn) {
+		/* check for an invalidate during setup */
+		bool fail = false;
+
+		mutex_lock(&tidbuf->cover_mutex);
+		fail = mmu_interval_read_retry(&tidbuf->notifier, mmu_seq);
+		mutex_unlock(&tidbuf->cover_mutex);
+
+		if (fail) {
+			ret = -EBUSY;
+			goto fail_unprogram;
 		}
 	}
 
-	/*
-	 * If not everything was mapped (due to insufficient RcvArray entries,
-	 * for example), unpin all unmapped pages so we can pin them nex time.
-	 */
-	if (mapped_pages != pinned)
-		unpin_rcv_pages(fd, tidbuf, NULL, mapped_pages,
-				(pinned - mapped_pages), false);
-bail:
-	kfree(tidbuf->psets);
-	kfree(tidlist);
+	tinfo->tidcnt = tididx;
+	tinfo->length = mapped_pages * PAGE_SIZE;
+
+	if (copy_to_user(u64_to_user_ptr(tinfo->tidlist),
+			 tidlist, sizeof(tidlist[0]) * tididx)) {
+		ret = -EFAULT;
+		goto fail_unprogram;
+	}
+
+	if (fd->use_mn)
+		mmu_interval_notifier_remove(&tidbuf->notifier);
 	kfree(tidbuf->pages);
+	kfree(tidbuf->psets);
 	kfree(tidbuf);
-	return ret > 0 ? 0 : ret;
+	kfree(tidlist);
+	return 0;
+
+fail_unprogram:
+	/* unprogram, unmap, and unpin all allocated TIDs */
+	tinfo->tidlist = (unsigned long)tidlist;
+	hfi1_user_exp_rcv_clear(fd, tinfo);
+	tinfo->tidlist = 0;
+	pinned = 0;		/* nothing left to unpin */
+	pageset_count = 0;	/* nothing left reserved */
+fail_unreserve:
+	spin_lock(&fd->tid_lock);
+	fd->tid_used -= pageset_count;
+	spin_unlock(&fd->tid_lock);
+fail_unpin:
+	if (fd->use_mn)
+		mmu_interval_notifier_remove(&tidbuf->notifier);
+	if (pinned > 0)
+		unpin_rcv_pages(fd, tidbuf, NULL, 0, pinned, false);
+fail_release_mem:
+	kfree(tidbuf->pages);
+	kfree(tidbuf->psets);
+	kfree(tidbuf);
+	kfree(tidlist);
+	return ret;
 }
 
 int hfi1_user_exp_rcv_clear(struct hfi1_filedata *fd,
@@ -494,7 +543,7 @@
 
 	mutex_lock(&uctxt->exp_mutex);
 	for (tididx = 0; tididx < tinfo->tidcnt; tididx++) {
-		ret = unprogram_rcvarray(fd, tidinfo[tididx], NULL);
+		ret = unprogram_rcvarray(fd, tidinfo[tididx]);
 		if (ret) {
 			hfi1_cdbg(TID, "Failed to unprogram rcv array %d",
 				  ret);
@@ -750,6 +799,7 @@
 	}
 
 	node->fdata = fd;
+	mutex_init(&node->invalidate_mutex);
 	node->phys = page_to_phys(pages[0]);
 	node->npages = npages;
 	node->rcventry = rcventry;
@@ -765,11 +815,6 @@
 			&tid_mn_ops);
 		if (ret)
 			goto out_unmap;
-		/*
-		 * FIXME: This is in the wrong order, the notifier should be
-		 * established before the pages are pinned by pin_rcv_pages.
-		 */
-		mmu_interval_read_begin(&node->notifier);
 	}
 	fd->entry_to_rb[node->rcventry - uctxt->expected_base] = node;
 
@@ -789,8 +834,7 @@
 	return -EFAULT;
 }
 
-static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo,
-			      struct tid_group **grp)
+static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo)
 {
 	struct hfi1_ctxtdata *uctxt = fd->uctxt;
 	struct hfi1_devdata *dd = uctxt->dd;
@@ -813,9 +857,6 @@
 	if (!node || node->rcventry != (uctxt->expected_base + rcventry))
 		return -EBADF;
 
-	if (grp)
-		*grp = node->grp;
-
 	if (fd->use_mn)
 		mmu_interval_notifier_remove(&node->notifier);
 	cacheless_tid_rb_remove(fd, node);
@@ -823,23 +864,34 @@
 	return 0;
 }
 
-static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node)
+static void __clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node)
 {
 	struct hfi1_ctxtdata *uctxt = fd->uctxt;
 	struct hfi1_devdata *dd = uctxt->dd;
+
+	mutex_lock(&node->invalidate_mutex);
+	if (node->freed)
+		goto done;
+	node->freed = true;
 
 	trace_hfi1_exp_tid_unreg(uctxt->ctxt, fd->subctxt, node->rcventry,
 				 node->npages,
 				 node->notifier.interval_tree.start, node->phys,
 				 node->dma_addr);
 
-	/*
-	 * Make sure device has seen the write before we unpin the
-	 * pages.
-	 */
+	/* Make sure device has seen the write before pages are unpinned */
 	hfi1_put_tid(dd, node->rcventry, PT_INVALID_FLUSH, 0, 0);
 
 	unpin_rcv_pages(fd, NULL, node, 0, node->npages, true);
+done:
+	mutex_unlock(&node->invalidate_mutex);
+}
+
+static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node)
+{
+	struct hfi1_ctxtdata *uctxt = fd->uctxt;
+
+	__clear_tid_node(fd, node);
 
 	node->grp->used--;
 	node->grp->map &= ~(1 << (node->rcventry - node->grp->base));
@@ -898,10 +950,16 @@
 	if (node->freed)
 		return true;
 
+	/* take action only if unmapping */
+	if (range->event != MMU_NOTIFY_UNMAP)
+		return true;
+
 	trace_hfi1_exp_tid_inval(uctxt->ctxt, fdata->subctxt,
 				 node->notifier.interval_tree.start,
 				 node->rcventry, node->npages, node->dma_addr);
-	node->freed = true;
+
+	/* clear the hardware rcvarray entry */
+	__clear_tid_node(fdata, node);
 
 	spin_lock(&fdata->invalid_lock);
 	if (fdata->invalid_tid_idx < uctxt->expected_count) {
@@ -931,6 +989,23 @@
 	return true;
 }
 
+static bool tid_cover_invalidate(struct mmu_interval_notifier *mni,
+			         const struct mmu_notifier_range *range,
+			         unsigned long cur_seq)
+{
+	struct tid_user_buf *tidbuf =
+		container_of(mni, struct tid_user_buf, notifier);
+
+	/* take action only if unmapping */
+	if (range->event == MMU_NOTIFY_UNMAP) {
+		mutex_lock(&tidbuf->cover_mutex);
+		mmu_interval_set_seq(mni, cur_seq);
+		mutex_unlock(&tidbuf->cover_mutex);
+	}
+
+	return true;
+}
+
 static void cacheless_tid_rb_remove(struct hfi1_filedata *fdata,
 				    struct tid_rb_node *tnode)
 {
diff --git a/kernel/drivers/infiniband/hw/hfi1/user_exp_rcv.h b/kernel/drivers/infiniband/hw/hfi1/user_exp_rcv.h
index d45c7b6..849f265 100644
--- a/kernel/drivers/infiniband/hw/hfi1/user_exp_rcv.h
+++ b/kernel/drivers/infiniband/hw/hfi1/user_exp_rcv.h
@@ -57,6 +57,8 @@
 };
 
 struct tid_user_buf {
+	struct mmu_interval_notifier notifier;
+	struct mutex cover_mutex;
 	unsigned long vaddr;
 	unsigned long length;
 	unsigned int npages;
@@ -68,6 +70,7 @@
 struct tid_rb_node {
 	struct mmu_interval_notifier notifier;
 	struct hfi1_filedata *fdata;
+	struct mutex invalidate_mutex; /* covers hw removal */
 	unsigned long phys;
 	struct tid_group *grp;
 	u32 rcventry;
diff --git a/kernel/drivers/infiniband/hw/hfi1/user_sdma.c b/kernel/drivers/infiniband/hw/hfi1/user_sdma.c
index 4a4956f..a677911 100644
--- a/kernel/drivers/infiniband/hw/hfi1/user_sdma.c
+++ b/kernel/drivers/infiniband/hw/hfi1/user_sdma.c
@@ -65,7 +65,6 @@
 
 #include "hfi.h"
 #include "sdma.h"
-#include "mmu_rb.h"
 #include "user_sdma.h"
 #include "verbs.h"  /* for the headers */
 #include "common.h" /* for struct hfi1_tid_info */
@@ -80,11 +79,7 @@
 static int user_sdma_send_pkts(struct user_sdma_request *req, u16 maxpkts);
 static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status);
 static inline void pq_update(struct hfi1_user_sdma_pkt_q *pq);
-static void user_sdma_free_request(struct user_sdma_request *req, bool unpin);
-static int pin_vector_pages(struct user_sdma_request *req,
-			    struct user_sdma_iovec *iovec);
-static void unpin_vector_pages(struct mm_struct *mm, struct page **pages,
-			       unsigned start, unsigned npages);
+static void user_sdma_free_request(struct user_sdma_request *req);
 static int check_header_template(struct user_sdma_request *req,
 				 struct hfi1_pkt_header *hdr, u32 lrhlen,
 				 u32 datalen);
@@ -108,19 +103,20 @@
 static void activate_packet_queue(struct iowait *wait, int reason);
 static bool sdma_rb_filter(struct mmu_rb_node *node, unsigned long addr,
 			   unsigned long len);
-static int sdma_rb_insert(void *arg, struct mmu_rb_node *mnode);
 static int sdma_rb_evict(void *arg, struct mmu_rb_node *mnode,
 			 void *arg2, bool *stop);
 static void sdma_rb_remove(void *arg, struct mmu_rb_node *mnode);
-static int sdma_rb_invalidate(void *arg, struct mmu_rb_node *mnode);
 
 static struct mmu_rb_ops sdma_rb_ops = {
 	.filter = sdma_rb_filter,
-	.insert = sdma_rb_insert,
 	.evict = sdma_rb_evict,
 	.remove = sdma_rb_remove,
-	.invalidate = sdma_rb_invalidate
 };
+
+static int add_system_pages_to_sdma_packet(struct user_sdma_request *req,
+					   struct user_sdma_txreq *tx,
+					   struct user_sdma_iovec *iovec,
+					   u32 *pkt_remaining);
 
 static int defer_packet_queue(
 	struct sdma_engine *sde,
@@ -133,6 +129,7 @@
 		container_of(wait->iow, struct hfi1_user_sdma_pkt_q, busy);
 
 	write_seqlock(&sde->waitlock);
+	trace_hfi1_usdma_defer(pq, sde, &pq->busy);
 	if (sdma_progress(sde, seq, txreq))
 		goto eagain;
 	/*
@@ -157,7 +154,8 @@
 {
 	struct hfi1_user_sdma_pkt_q *pq =
 		container_of(wait, struct hfi1_user_sdma_pkt_q, busy);
-	pq->busy.lock = NULL;
+
+	trace_hfi1_usdma_activate(pq, wait, reason);
 	xchg(&pq->state, SDMA_PKT_Q_ACTIVE);
 	wake_up(&wait->wait_dma);
 };
@@ -200,9 +198,7 @@
 	if (!pq->reqs)
 		goto pq_reqs_nomem;
 
-	pq->req_in_use = kcalloc(BITS_TO_LONGS(hfi1_sdma_comp_ring_size),
-				 sizeof(*pq->req_in_use),
-				 GFP_KERNEL);
+	pq->req_in_use = bitmap_zalloc(hfi1_sdma_comp_ring_size, GFP_KERNEL);
 	if (!pq->req_in_use)
 		goto pq_reqs_no_in_use;
 
@@ -249,7 +245,7 @@
 cq_nomem:
 	kmem_cache_destroy(pq->txreq_cache);
 pq_txreq_nomem:
-	kfree(pq->req_in_use);
+	bitmap_free(pq->req_in_use);
 pq_reqs_no_in_use:
 	kfree(pq->reqs);
 pq_reqs_nomem:
@@ -288,15 +284,15 @@
 		spin_unlock(&fd->pq_rcu_lock);
 		synchronize_srcu(&fd->pq_srcu);
 		/* at this point there can be no more new requests */
-		if (pq->handler)
-			hfi1_mmu_rb_unregister(pq->handler);
 		iowait_sdma_drain(&pq->busy);
 		/* Wait until all requests have been freed. */
 		wait_event_interruptible(
 			pq->wait,
 			!atomic_read(&pq->n_reqs));
 		kfree(pq->reqs);
-		kfree(pq->req_in_use);
+		if (pq->handler)
+			hfi1_mmu_rb_unregister(pq->handler);
+		bitmap_free(pq->req_in_use);
 		kmem_cache_destroy(pq->txreq_cache);
 		flush_pq_iowait(pq);
 		kfree(pq);
@@ -451,6 +447,7 @@
 		ret = -EINVAL;
 		goto free_req;
 	}
+
 	/* Copy the header from the user buffer */
 	ret = copy_from_user(&req->hdr, iovec[idx].iov_base + sizeof(info),
 			     sizeof(req->hdr));
@@ -525,9 +522,8 @@
 		memcpy(&req->iovs[i].iov,
 		       iovec + idx++,
 		       sizeof(req->iovs[i].iov));
-		ret = pin_vector_pages(req, &req->iovs[i]);
-		if (ret) {
-			req->data_iovs = i;
+		if (req->iovs[i].iov.iov_len == 0) {
+			ret = -EINVAL;
 			goto free_req;
 		}
 		req->data_len += req->iovs[i].iov.iov_len;
@@ -599,13 +595,17 @@
 	while (req->seqsubmitted != req->info.npkts) {
 		ret = user_sdma_send_pkts(req, pcount);
 		if (ret < 0) {
+			int we_ret;
+
 			if (ret != -EBUSY)
 				goto free_req;
-			if (wait_event_interruptible_timeout(
+			we_ret = wait_event_interruptible_timeout(
 				pq->busy.wait_dma,
 				pq->state == SDMA_PKT_Q_ACTIVE,
 				msecs_to_jiffies(
-					SDMA_IOWAIT_TIMEOUT)) <= 0)
+					SDMA_IOWAIT_TIMEOUT));
+			trace_hfi1_usdma_we(pq, we_ret);
+			if (we_ret <= 0)
 				flush_pq_iowait(pq);
 		}
 	}
@@ -621,7 +621,7 @@
 		if (req->seqsubmitted)
 			wait_event(pq->busy.wait_dma,
 				   (req->seqcomp == req->seqsubmitted - 1));
-		user_sdma_free_request(req, true);
+		user_sdma_free_request(req);
 		pq_update(pq);
 		set_comp_state(pq, cq, info.comp_idx, ERROR, ret);
 	}
@@ -733,48 +733,6 @@
 	return ret;
 }
 
-static int user_sdma_txadd(struct user_sdma_request *req,
-			   struct user_sdma_txreq *tx,
-			   struct user_sdma_iovec *iovec, u32 datalen,
-			   u32 *queued_ptr, u32 *data_sent_ptr,
-			   u64 *iov_offset_ptr)
-{
-	int ret;
-	unsigned int pageidx, len;
-	unsigned long base, offset;
-	u64 iov_offset = *iov_offset_ptr;
-	u32 queued = *queued_ptr, data_sent = *data_sent_ptr;
-	struct hfi1_user_sdma_pkt_q *pq = req->pq;
-
-	base = (unsigned long)iovec->iov.iov_base;
-	offset = offset_in_page(base + iovec->offset + iov_offset);
-	pageidx = (((iovec->offset + iov_offset + base) - (base & PAGE_MASK)) >>
-		   PAGE_SHIFT);
-	len = offset + req->info.fragsize > PAGE_SIZE ?
-		PAGE_SIZE - offset : req->info.fragsize;
-	len = min((datalen - queued), len);
-	ret = sdma_txadd_page(pq->dd, &tx->txreq, iovec->pages[pageidx],
-			      offset, len);
-	if (ret) {
-		SDMA_DBG(req, "SDMA txreq add page failed %d\n", ret);
-		return ret;
-	}
-	iov_offset += len;
-	queued += len;
-	data_sent += len;
-	if (unlikely(queued < datalen && pageidx == iovec->npages &&
-		     req->iov_idx < req->data_iovs - 1)) {
-		iovec->offset += iov_offset;
-		iovec = &req->iovs[++req->iov_idx];
-		iov_offset = 0;
-	}
-
-	*queued_ptr = queued;
-	*data_sent_ptr = data_sent;
-	*iov_offset_ptr = iov_offset;
-	return ret;
-}
-
 static int user_sdma_send_pkts(struct user_sdma_request *req, u16 maxpkts)
 {
 	int ret = 0;
@@ -806,8 +764,7 @@
 		maxpkts = req->info.npkts - req->seqnum;
 
 	while (npkts < maxpkts) {
-		u32 datalen = 0, queued = 0, data_sent = 0;
-		u64 iov_offset = 0;
+		u32 datalen = 0;
 
 		/*
 		 * Check whether any of the completions have come back
@@ -900,27 +857,17 @@
 				goto free_txreq;
 		}
 
-		/*
-		 * If the request contains any data vectors, add up to
-		 * fragsize bytes to the descriptor.
-		 */
-		while (queued < datalen &&
-		       (req->sent + data_sent) < req->data_len) {
-			ret = user_sdma_txadd(req, tx, iovec, datalen,
-					      &queued, &data_sent, &iov_offset);
-			if (ret)
-				goto free_txreq;
-		}
-		/*
-		 * The txreq was submitted successfully so we can update
-		 * the counters.
-		 */
 		req->koffset += datalen;
 		if (req_opcode(req->info.ctrl) == EXPECTED)
 			req->tidoffset += datalen;
-		req->sent += data_sent;
-		if (req->data_len)
-			iovec->offset += iov_offset;
+		req->sent += datalen;
+		while (datalen) {
+			ret = add_system_pages_to_sdma_packet(req, tx, iovec,
+							      &datalen);
+			if (ret)
+				goto free_txreq;
+			iovec = &req->iovs[req->iov_idx];
+		}
 		list_add_tail(&tx->txreq.list, &req->txps);
 		/*
 		 * It is important to increment this here as it is used to
@@ -957,131 +904,12 @@
 static u32 sdma_cache_evict(struct hfi1_user_sdma_pkt_q *pq, u32 npages)
 {
 	struct evict_data evict_data;
+	struct mmu_rb_handler *handler = pq->handler;
 
 	evict_data.cleared = 0;
 	evict_data.target = npages;
-	hfi1_mmu_rb_evict(pq->handler, &evict_data);
+	hfi1_mmu_rb_evict(handler, &evict_data);
 	return evict_data.cleared;
-}
-
-static int pin_sdma_pages(struct user_sdma_request *req,
-			  struct user_sdma_iovec *iovec,
-			  struct sdma_mmu_node *node,
-			  int npages)
-{
-	int pinned, cleared;
-	struct page **pages;
-	struct hfi1_user_sdma_pkt_q *pq = req->pq;
-
-	pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
-	if (!pages)
-		return -ENOMEM;
-	memcpy(pages, node->pages, node->npages * sizeof(*pages));
-
-	npages -= node->npages;
-retry:
-	if (!hfi1_can_pin_pages(pq->dd, current->mm,
-				atomic_read(&pq->n_locked), npages)) {
-		cleared = sdma_cache_evict(pq, npages);
-		if (cleared >= npages)
-			goto retry;
-	}
-	pinned = hfi1_acquire_user_pages(current->mm,
-					 ((unsigned long)iovec->iov.iov_base +
-					 (node->npages * PAGE_SIZE)), npages, 0,
-					 pages + node->npages);
-	if (pinned < 0) {
-		kfree(pages);
-		return pinned;
-	}
-	if (pinned != npages) {
-		unpin_vector_pages(current->mm, pages, node->npages, pinned);
-		return -EFAULT;
-	}
-	kfree(node->pages);
-	node->rb.len = iovec->iov.iov_len;
-	node->pages = pages;
-	atomic_add(pinned, &pq->n_locked);
-	return pinned;
-}
-
-static void unpin_sdma_pages(struct sdma_mmu_node *node)
-{
-	if (node->npages) {
-		unpin_vector_pages(mm_from_sdma_node(node), node->pages, 0,
-				   node->npages);
-		atomic_sub(node->npages, &node->pq->n_locked);
-	}
-}
-
-static int pin_vector_pages(struct user_sdma_request *req,
-			    struct user_sdma_iovec *iovec)
-{
-	int ret = 0, pinned, npages;
-	struct hfi1_user_sdma_pkt_q *pq = req->pq;
-	struct sdma_mmu_node *node = NULL;
-	struct mmu_rb_node *rb_node;
-	struct iovec *iov;
-	bool extracted;
-
-	extracted =
-		hfi1_mmu_rb_remove_unless_exact(pq->handler,
-						(unsigned long)
-						iovec->iov.iov_base,
-						iovec->iov.iov_len, &rb_node);
-	if (rb_node) {
-		node = container_of(rb_node, struct sdma_mmu_node, rb);
-		if (!extracted) {
-			atomic_inc(&node->refcount);
-			iovec->pages = node->pages;
-			iovec->npages = node->npages;
-			iovec->node = node;
-			return 0;
-		}
-	}
-
-	if (!node) {
-		node = kzalloc(sizeof(*node), GFP_KERNEL);
-		if (!node)
-			return -ENOMEM;
-
-		node->rb.addr = (unsigned long)iovec->iov.iov_base;
-		node->pq = pq;
-		atomic_set(&node->refcount, 0);
-	}
-
-	iov = &iovec->iov;
-	npages = num_user_pages((unsigned long)iov->iov_base, iov->iov_len);
-	if (node->npages < npages) {
-		pinned = pin_sdma_pages(req, iovec, node, npages);
-		if (pinned < 0) {
-			ret = pinned;
-			goto bail;
-		}
-		node->npages += pinned;
-		npages = node->npages;
-	}
-	iovec->pages = node->pages;
-	iovec->npages = npages;
-	iovec->node = node;
-
-	ret = hfi1_mmu_rb_insert(req->pq->handler, &node->rb);
-	if (ret) {
-		iovec->node = NULL;
-		goto bail;
-	}
-	return 0;
-bail:
-	unpin_sdma_pages(node);
-	kfree(node);
-	return ret;
-}
-
-static void unpin_vector_pages(struct mm_struct *mm, struct page **pages,
-			       unsigned start, unsigned npages)
-{
-	hfi1_release_user_pages(mm, pages + start, npages, false);
-	kfree(pages);
 }
 
 static int check_header_template(struct user_sdma_request *req,
@@ -1425,7 +1253,7 @@
 	if (req->seqcomp != req->info.npkts - 1)
 		return;
 
-	user_sdma_free_request(req, false);
+	user_sdma_free_request(req);
 	set_comp_state(pq, cq, req->info.comp_idx, state, status);
 	pq_update(pq);
 }
@@ -1436,10 +1264,8 @@
 		wake_up(&pq->wait);
 }
 
-static void user_sdma_free_request(struct user_sdma_request *req, bool unpin)
+static void user_sdma_free_request(struct user_sdma_request *req)
 {
-	int i;
-
 	if (!list_empty(&req->txps)) {
 		struct sdma_txreq *t, *p;
 
@@ -1450,21 +1276,6 @@
 			sdma_txclean(req->pq->dd, t);
 			kmem_cache_free(req->pq->txreq_cache, tx);
 		}
-	}
-
-	for (i = 0; i < req->data_iovs; i++) {
-		struct sdma_mmu_node *node = req->iovs[i].node;
-
-		if (!node)
-			continue;
-
-		req->iovs[i].node = NULL;
-
-		if (unpin)
-			hfi1_mmu_rb_remove(req->pq->handler,
-					   &node->rb);
-		else
-			atomic_dec(&node->refcount);
 	}
 
 	kfree(req->tids);
@@ -1484,19 +1295,372 @@
 					idx, state, ret);
 }
 
+static void unpin_vector_pages(struct mm_struct *mm, struct page **pages,
+			       unsigned int start, unsigned int npages)
+{
+	hfi1_release_user_pages(mm, pages + start, npages, false);
+	kfree(pages);
+}
+
+static void free_system_node(struct sdma_mmu_node *node)
+{
+	if (node->npages) {
+		unpin_vector_pages(mm_from_sdma_node(node), node->pages, 0,
+				   node->npages);
+		atomic_sub(node->npages, &node->pq->n_locked);
+	}
+	kfree(node);
+}
+
+/*
+ * kref_get()'s an additional kref on the returned rb_node to prevent rb_node
+ * from being released until after rb_node is assigned to an SDMA descriptor
+ * (struct sdma_desc) under add_system_iovec_to_sdma_packet(), even if the
+ * virtual address range for rb_node is invalidated between now and then.
+ */
+static struct sdma_mmu_node *find_system_node(struct mmu_rb_handler *handler,
+					      unsigned long start,
+					      unsigned long end)
+{
+	struct mmu_rb_node *rb_node;
+	unsigned long flags;
+
+	spin_lock_irqsave(&handler->lock, flags);
+	rb_node = hfi1_mmu_rb_get_first(handler, start, (end - start));
+	if (!rb_node) {
+		spin_unlock_irqrestore(&handler->lock, flags);
+		return NULL;
+	}
+
+	/* "safety" kref to prevent release before add_system_iovec_to_sdma_packet() */
+	kref_get(&rb_node->refcount);
+	spin_unlock_irqrestore(&handler->lock, flags);
+
+	return container_of(rb_node, struct sdma_mmu_node, rb);
+}
+
+static int pin_system_pages(struct user_sdma_request *req,
+			    uintptr_t start_address, size_t length,
+			    struct sdma_mmu_node *node, int npages)
+{
+	struct hfi1_user_sdma_pkt_q *pq = req->pq;
+	int pinned, cleared;
+	struct page **pages;
+
+	pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
+	if (!pages)
+		return -ENOMEM;
+
+retry:
+	if (!hfi1_can_pin_pages(pq->dd, current->mm, atomic_read(&pq->n_locked),
+				npages)) {
+		SDMA_DBG(req, "Evicting: nlocked %u npages %u",
+			 atomic_read(&pq->n_locked), npages);
+		cleared = sdma_cache_evict(pq, npages);
+		if (cleared >= npages)
+			goto retry;
+	}
+
+	SDMA_DBG(req, "Acquire user pages start_address %lx node->npages %u npages %u",
+		 start_address, node->npages, npages);
+	pinned = hfi1_acquire_user_pages(current->mm, start_address, npages, 0,
+					 pages);
+
+	if (pinned < 0) {
+		kfree(pages);
+		SDMA_DBG(req, "pinned %d", pinned);
+		return pinned;
+	}
+	if (pinned != npages) {
+		unpin_vector_pages(current->mm, pages, node->npages, pinned);
+		SDMA_DBG(req, "npages %u pinned %d", npages, pinned);
+		return -EFAULT;
+	}
+	node->rb.addr = start_address;
+	node->rb.len = length;
+	node->pages = pages;
+	node->npages = npages;
+	atomic_add(pinned, &pq->n_locked);
+	SDMA_DBG(req, "done. pinned %d", pinned);
+	return 0;
+}
+
+/*
+ * kref refcount on *node_p will be 2 on successful addition: one kref from
+ * kref_init() for mmu_rb_handler and one kref to prevent *node_p from being
+ * released until after *node_p is assigned to an SDMA descriptor (struct
+ * sdma_desc) under add_system_iovec_to_sdma_packet(), even if the virtual
+ * address range for *node_p is invalidated between now and then.
+ */
+static int add_system_pinning(struct user_sdma_request *req,
+			      struct sdma_mmu_node **node_p,
+			      unsigned long start, unsigned long len)
+
+{
+	struct hfi1_user_sdma_pkt_q *pq = req->pq;
+	struct sdma_mmu_node *node;
+	int ret;
+
+	node = kzalloc(sizeof(*node), GFP_KERNEL);
+	if (!node)
+		return -ENOMEM;
+
+	/* First kref "moves" to mmu_rb_handler */
+	kref_init(&node->rb.refcount);
+
+	/* "safety" kref to prevent release before add_system_iovec_to_sdma_packet() */
+	kref_get(&node->rb.refcount);
+
+	node->pq = pq;
+	ret = pin_system_pages(req, start, len, node, PFN_DOWN(len));
+	if (ret == 0) {
+		ret = hfi1_mmu_rb_insert(pq->handler, &node->rb);
+		if (ret)
+			free_system_node(node);
+		else
+			*node_p = node;
+
+		return ret;
+	}
+
+	kfree(node);
+	return ret;
+}
+
+static int get_system_cache_entry(struct user_sdma_request *req,
+				  struct sdma_mmu_node **node_p,
+				  size_t req_start, size_t req_len)
+{
+	struct hfi1_user_sdma_pkt_q *pq = req->pq;
+	u64 start = ALIGN_DOWN(req_start, PAGE_SIZE);
+	u64 end = PFN_ALIGN(req_start + req_len);
+	struct mmu_rb_handler *handler = pq->handler;
+	int ret;
+
+	if ((end - start) == 0) {
+		SDMA_DBG(req,
+			 "Request for empty cache entry req_start %lx req_len %lx start %llx end %llx",
+			 req_start, req_len, start, end);
+		return -EINVAL;
+	}
+
+	SDMA_DBG(req, "req_start %lx req_len %lu", req_start, req_len);
+
+	while (1) {
+		struct sdma_mmu_node *node =
+			find_system_node(handler, start, end);
+		u64 prepend_len = 0;
+
+		SDMA_DBG(req, "node %p start %llx end %llu", node, start, end);
+		if (!node) {
+			ret = add_system_pinning(req, node_p, start,
+						 end - start);
+			if (ret == -EEXIST) {
+				/*
+				 * Another execution context has inserted a
+				 * conficting entry first.
+				 */
+				continue;
+			}
+			return ret;
+		}
+
+		if (node->rb.addr <= start) {
+			/*
+			 * This entry covers at least part of the region. If it doesn't extend
+			 * to the end, then this will be called again for the next segment.
+			 */
+			*node_p = node;
+			return 0;
+		}
+
+		SDMA_DBG(req, "prepend: node->rb.addr %lx, node->rb.refcount %d",
+			 node->rb.addr, kref_read(&node->rb.refcount));
+		prepend_len = node->rb.addr - start;
+
+		/*
+		 * This node will not be returned, instead a new node
+		 * will be. So release the reference.
+		 */
+		kref_put(&node->rb.refcount, hfi1_mmu_rb_release);
+
+		/* Prepend a node to cover the beginning of the allocation */
+		ret = add_system_pinning(req, node_p, start, prepend_len);
+		if (ret == -EEXIST) {
+			/* Another execution context has inserted a conficting entry first. */
+			continue;
+		}
+		return ret;
+	}
+}
+
+static void sdma_mmu_rb_node_get(void *ctx)
+{
+	struct mmu_rb_node *node = ctx;
+
+	kref_get(&node->refcount);
+}
+
+static void sdma_mmu_rb_node_put(void *ctx)
+{
+	struct sdma_mmu_node *node = ctx;
+
+	kref_put(&node->rb.refcount, hfi1_mmu_rb_release);
+}
+
+static int add_mapping_to_sdma_packet(struct user_sdma_request *req,
+				      struct user_sdma_txreq *tx,
+				      struct sdma_mmu_node *cache_entry,
+				      size_t start,
+				      size_t from_this_cache_entry)
+{
+	struct hfi1_user_sdma_pkt_q *pq = req->pq;
+	unsigned int page_offset;
+	unsigned int from_this_page;
+	size_t page_index;
+	void *ctx;
+	int ret;
+
+	/*
+	 * Because the cache may be more fragmented than the memory that is being accessed,
+	 * it's not strictly necessary to have a descriptor per cache entry.
+	 */
+
+	while (from_this_cache_entry) {
+		page_index = PFN_DOWN(start - cache_entry->rb.addr);
+
+		if (page_index >= cache_entry->npages) {
+			SDMA_DBG(req,
+				 "Request for page_index %zu >= cache_entry->npages %u",
+				 page_index, cache_entry->npages);
+			return -EINVAL;
+		}
+
+		page_offset = start - ALIGN_DOWN(start, PAGE_SIZE);
+		from_this_page = PAGE_SIZE - page_offset;
+
+		if (from_this_page < from_this_cache_entry) {
+			ctx = NULL;
+		} else {
+			/*
+			 * In the case they are equal the next line has no practical effect,
+			 * but it's better to do a register to register copy than a conditional
+			 * branch.
+			 */
+			from_this_page = from_this_cache_entry;
+			ctx = cache_entry;
+		}
+
+		ret = sdma_txadd_page(pq->dd, &tx->txreq,
+				      cache_entry->pages[page_index],
+				      page_offset, from_this_page,
+				      ctx,
+				      sdma_mmu_rb_node_get,
+				      sdma_mmu_rb_node_put);
+		if (ret) {
+			/*
+			 * When there's a failure, the entire request is freed by
+			 * user_sdma_send_pkts().
+			 */
+			SDMA_DBG(req,
+				 "sdma_txadd_page failed %d page_index %lu page_offset %u from_this_page %u",
+				 ret, page_index, page_offset, from_this_page);
+			return ret;
+		}
+		start += from_this_page;
+		from_this_cache_entry -= from_this_page;
+	}
+	return 0;
+}
+
+static int add_system_iovec_to_sdma_packet(struct user_sdma_request *req,
+					   struct user_sdma_txreq *tx,
+					   struct user_sdma_iovec *iovec,
+					   size_t from_this_iovec)
+{
+	while (from_this_iovec > 0) {
+		struct sdma_mmu_node *cache_entry;
+		size_t from_this_cache_entry;
+		size_t start;
+		int ret;
+
+		start = (uintptr_t)iovec->iov.iov_base + iovec->offset;
+		ret = get_system_cache_entry(req, &cache_entry, start,
+					     from_this_iovec);
+		if (ret) {
+			SDMA_DBG(req, "pin system segment failed %d", ret);
+			return ret;
+		}
+
+		from_this_cache_entry = cache_entry->rb.len - (start - cache_entry->rb.addr);
+		if (from_this_cache_entry > from_this_iovec)
+			from_this_cache_entry = from_this_iovec;
+
+		ret = add_mapping_to_sdma_packet(req, tx, cache_entry, start,
+						 from_this_cache_entry);
+
+		/*
+		 * Done adding cache_entry to zero or more sdma_desc. Can
+		 * kref_put() the "safety" kref taken under
+		 * get_system_cache_entry().
+		 */
+		kref_put(&cache_entry->rb.refcount, hfi1_mmu_rb_release);
+
+		if (ret) {
+			SDMA_DBG(req, "add system segment failed %d", ret);
+			return ret;
+		}
+
+		iovec->offset += from_this_cache_entry;
+		from_this_iovec -= from_this_cache_entry;
+	}
+
+	return 0;
+}
+
+static int add_system_pages_to_sdma_packet(struct user_sdma_request *req,
+					   struct user_sdma_txreq *tx,
+					   struct user_sdma_iovec *iovec,
+					   u32 *pkt_data_remaining)
+{
+	size_t remaining_to_add = *pkt_data_remaining;
+	/*
+	 * Walk through iovec entries, ensure the associated pages
+	 * are pinned and mapped, add data to the packet until no more
+	 * data remains to be added.
+	 */
+	while (remaining_to_add > 0) {
+		struct user_sdma_iovec *cur_iovec;
+		size_t from_this_iovec;
+		int ret;
+
+		cur_iovec = iovec;
+		from_this_iovec = iovec->iov.iov_len - iovec->offset;
+
+		if (from_this_iovec > remaining_to_add) {
+			from_this_iovec = remaining_to_add;
+		} else {
+			/* The current iovec entry will be consumed by this pass. */
+			req->iov_idx++;
+			iovec++;
+		}
+
+		ret = add_system_iovec_to_sdma_packet(req, tx, cur_iovec,
+						      from_this_iovec);
+		if (ret)
+			return ret;
+
+		remaining_to_add -= from_this_iovec;
+	}
+	*pkt_data_remaining = remaining_to_add;
+
+	return 0;
+}
+
 static bool sdma_rb_filter(struct mmu_rb_node *node, unsigned long addr,
 			   unsigned long len)
 {
 	return (bool)(node->addr == addr);
-}
-
-static int sdma_rb_insert(void *arg, struct mmu_rb_node *mnode)
-{
-	struct sdma_mmu_node *node =
-		container_of(mnode, struct sdma_mmu_node, rb);
-
-	atomic_inc(&node->refcount);
-	return 0;
 }
 
 /*
@@ -1510,10 +1674,6 @@
 	struct sdma_mmu_node *node =
 		container_of(mnode, struct sdma_mmu_node, rb);
 	struct evict_data *evict_data = evict_arg;
-
-	/* is this node still being used? */
-	if (atomic_read(&node->refcount))
-		return 0; /* keep this node */
 
 	/* this node will be evicted, add its pages to our count */
 	evict_data->cleared += node->npages;
@@ -1530,16 +1690,5 @@
 	struct sdma_mmu_node *node =
 		container_of(mnode, struct sdma_mmu_node, rb);
 
-	unpin_sdma_pages(node);
-	kfree(node);
-}
-
-static int sdma_rb_invalidate(void *arg, struct mmu_rb_node *mnode)
-{
-	struct sdma_mmu_node *node =
-		container_of(mnode, struct sdma_mmu_node, rb);
-
-	if (!atomic_read(&node->refcount))
-		return 1;
-	return 0;
+	free_system_node(node);
 }
diff --git a/kernel/drivers/infiniband/hw/hfi1/user_sdma.h b/kernel/drivers/infiniband/hw/hfi1/user_sdma.h
index 1e8c02f..b2b26b7 100644
--- a/kernel/drivers/infiniband/hw/hfi1/user_sdma.h
+++ b/kernel/drivers/infiniband/hw/hfi1/user_sdma.h
@@ -53,6 +53,7 @@
 #include "common.h"
 #include "iowait.h"
 #include "user_exp_rcv.h"
+#include "mmu_rb.h"
 
 /* The maximum number of Data io vectors per message/request */
 #define MAX_VECTORS_PER_REQ 8
@@ -144,7 +145,6 @@
 struct sdma_mmu_node {
 	struct mmu_rb_node rb;
 	struct hfi1_user_sdma_pkt_q *pq;
-	atomic_t refcount;
 	struct page **pages;
 	unsigned int npages;
 };
@@ -152,16 +152,11 @@
 struct user_sdma_iovec {
 	struct list_head list;
 	struct iovec iov;
-	/* number of pages in this vector */
-	unsigned int npages;
-	/* array of pinned pages for this vector */
-	struct page **pages;
 	/*
 	 * offset into the virtual address space of the vector at
 	 * which we last left off.
 	 */
 	u64 offset;
-	struct sdma_mmu_node *node;
 };
 
 /* evict operation argument */
diff --git a/kernel/drivers/infiniband/hw/hfi1/verbs.c b/kernel/drivers/infiniband/hw/hfi1/verbs.c
index 5f3edd2..693922d 100644
--- a/kernel/drivers/infiniband/hw/hfi1/verbs.c
+++ b/kernel/drivers/infiniband/hw/hfi1/verbs.c
@@ -820,8 +820,8 @@
 
 	/* add icrc, lt byte, and padding to flit */
 	if (extra_bytes)
-		ret = sdma_txadd_daddr(sde->dd, &tx->txreq,
-				       sde->dd->sdma_pad_phys, extra_bytes);
+		ret = sdma_txadd_daddr(sde->dd, &tx->txreq, sde->dd->sdma_pad_phys,
+				       extra_bytes);
 
 bail_txadd:
 	return ret;
diff --git a/kernel/drivers/infiniband/hw/hfi1/vnic_sdma.c b/kernel/drivers/infiniband/hw/hfi1/vnic_sdma.c
index 7d90b90..ab8bcdf 100644
--- a/kernel/drivers/infiniband/hw/hfi1/vnic_sdma.c
+++ b/kernel/drivers/infiniband/hw/hfi1/vnic_sdma.c
@@ -109,7 +109,8 @@
 				      &tx->txreq,
 				      skb_frag_page(frag),
 				      skb_frag_off(frag),
-				      skb_frag_size(frag));
+				      skb_frag_size(frag),
+				      NULL, NULL, NULL);
 		if (unlikely(ret))
 			goto bail_txadd;
 	}
diff --git a/kernel/drivers/infiniband/hw/hns/hns_roce_cmd.c b/kernel/drivers/infiniband/hw/hns/hns_roce_cmd.c
index 455d533..c493d76 100644
--- a/kernel/drivers/infiniband/hw/hns/hns_roce_cmd.c
+++ b/kernel/drivers/infiniband/hw/hns/hns_roce_cmd.c
@@ -36,9 +36,9 @@
 #include "hns_roce_device.h"
 #include "hns_roce_cmd.h"
 
-#define CMD_POLL_TOKEN		0xffff
-#define CMD_MAX_NUM		32
-#define CMD_TOKEN_MASK		0x1f
+#define CMD_POLL_TOKEN 0xffff
+#define CMD_MAX_NUM 32
+#define CMD_TOKEN_MASK 0x1f
 
 static int hns_roce_cmd_mbox_post_hw(struct hns_roce_dev *hr_dev, u64 in_param,
 				     u64 out_param, u32 in_modifier,
@@ -93,8 +93,8 @@
 void hns_roce_cmd_event(struct hns_roce_dev *hr_dev, u16 token, u8 status,
 			u64 out_param)
 {
-	struct hns_roce_cmd_context
-		*context = &hr_dev->cmd.context[token & hr_dev->cmd.token_mask];
+	struct hns_roce_cmd_context *context =
+		&hr_dev->cmd.context[token % hr_dev->cmd.max_cmds];
 
 	if (token != context->token)
 		return;
@@ -164,8 +164,8 @@
 	int ret;
 
 	down(&hr_dev->cmd.event_sem);
-	ret = __hns_roce_cmd_mbox_wait(hr_dev, in_param, out_param,
-				       in_modifier, op_modifier, op, timeout);
+	ret = __hns_roce_cmd_mbox_wait(hr_dev, in_param, out_param, in_modifier,
+				       op_modifier, op, timeout);
 	up(&hr_dev->cmd.event_sem);
 
 	return ret;
@@ -231,9 +231,8 @@
 	struct hns_roce_cmdq *hr_cmd = &hr_dev->cmd;
 	int i;
 
-	hr_cmd->context = kmalloc_array(hr_cmd->max_cmds,
-					sizeof(*hr_cmd->context),
-					GFP_KERNEL);
+	hr_cmd->context =
+		kcalloc(hr_cmd->max_cmds, sizeof(*hr_cmd->context), GFP_KERNEL);
 	if (!hr_cmd->context)
 		return -ENOMEM;
 
@@ -262,8 +261,8 @@
 	hr_cmd->use_events = 0;
 }
 
-struct hns_roce_cmd_mailbox
-	*hns_roce_alloc_cmd_mailbox(struct hns_roce_dev *hr_dev)
+struct hns_roce_cmd_mailbox *
+hns_roce_alloc_cmd_mailbox(struct hns_roce_dev *hr_dev)
 {
 	struct hns_roce_cmd_mailbox *mailbox;
 
@@ -271,8 +270,8 @@
 	if (!mailbox)
 		return ERR_PTR(-ENOMEM);
 
-	mailbox->buf = dma_pool_alloc(hr_dev->cmd.pool, GFP_KERNEL,
-				      &mailbox->dma);
+	mailbox->buf =
+		dma_pool_alloc(hr_dev->cmd.pool, GFP_KERNEL, &mailbox->dma);
 	if (!mailbox->buf) {
 		kfree(mailbox);
 		return ERR_PTR(-ENOMEM);
diff --git a/kernel/drivers/infiniband/hw/hns/hns_roce_cmd.h b/kernel/drivers/infiniband/hw/hns/hns_roce_cmd.h
index 1915bac..8e63b82 100644
--- a/kernel/drivers/infiniband/hw/hns/hns_roce_cmd.h
+++ b/kernel/drivers/infiniband/hw/hns/hns_roce_cmd.h
@@ -143,8 +143,8 @@
 		      unsigned long in_modifier, u8 op_modifier, u16 op,
 		      unsigned long timeout);
 
-struct hns_roce_cmd_mailbox
-	*hns_roce_alloc_cmd_mailbox(struct hns_roce_dev *hr_dev);
+struct hns_roce_cmd_mailbox *
+hns_roce_alloc_cmd_mailbox(struct hns_roce_dev *hr_dev);
 void hns_roce_free_cmd_mailbox(struct hns_roce_dev *hr_dev,
 			       struct hns_roce_cmd_mailbox *mailbox);
 
diff --git a/kernel/drivers/infiniband/hw/hns/hns_roce_cq.c b/kernel/drivers/infiniband/hw/hns/hns_roce_cq.c
index 8a6bded..9200e64 100644
--- a/kernel/drivers/infiniband/hw/hns/hns_roce_cq.c
+++ b/kernel/drivers/infiniband/hw/hns/hns_roce_cq.c
@@ -41,9 +41,9 @@
 
 static int alloc_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
 {
+	struct ib_device *ibdev = &hr_dev->ib_dev;
 	struct hns_roce_cmd_mailbox *mailbox;
 	struct hns_roce_cq_table *cq_table;
-	struct ib_device *ibdev = &hr_dev->ib_dev;
 	u64 mtts[MTT_MIN_COUNT] = { 0 };
 	dma_addr_t dma_handle;
 	int ret;
diff --git a/kernel/drivers/infiniband/hw/hns/hns_roce_device.h b/kernel/drivers/infiniband/hw/hns/hns_roce_device.h
index d9aa742..09b5e49 100644
--- a/kernel/drivers/infiniband/hw/hns/hns_roce_device.h
+++ b/kernel/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -46,8 +46,6 @@
 
 #define HNS_ROCE_IB_MIN_SQ_STRIDE		6
 
-#define HNS_ROCE_BA_SIZE			(32 * 4096)
-
 #define BA_BYTE_LEN				8
 
 /* Hardware specification only for v1 engine */
diff --git a/kernel/drivers/infiniband/hw/hns/hns_roce_hem.c b/kernel/drivers/infiniband/hw/hns/hns_roce_hem.c
index c880a8b..854b41c 100644
--- a/kernel/drivers/infiniband/hw/hns/hns_roce_hem.c
+++ b/kernel/drivers/infiniband/hw/hns/hns_roce_hem.c
@@ -36,9 +36,6 @@
 #include "hns_roce_hem.h"
 #include "hns_roce_common.h"
 
-#define DMA_ADDR_T_SHIFT		12
-#define BT_BA_SHIFT			32
-
 #define HEM_INDEX_BUF			BIT(0)
 #define HEM_INDEX_L0			BIT(1)
 #define HEM_INDEX_L1			BIT(2)
@@ -198,9 +195,9 @@
 {
 	struct device *dev = hr_dev->dev;
 	u32 chunk_ba_num;
+	u32 chunk_size;
 	u32 table_idx;
 	u32 bt_num;
-	u32 chunk_size;
 
 	if (get_hem_table_config(hr_dev, mhop, table->type))
 		return -EINVAL;
@@ -260,7 +257,6 @@
 	if (!hem)
 		return NULL;
 
-	hem->refcount = 0;
 	INIT_LIST_HEAD(&hem->chunk_list);
 
 	order = get_order(hem_alloc_size);
@@ -325,81 +321,6 @@
 	}
 
 	kfree(hem);
-}
-
-static int hns_roce_set_hem(struct hns_roce_dev *hr_dev,
-			    struct hns_roce_hem_table *table, unsigned long obj)
-{
-	spinlock_t *lock = &hr_dev->bt_cmd_lock;
-	struct device *dev = hr_dev->dev;
-	long end;
-	unsigned long flags;
-	struct hns_roce_hem_iter iter;
-	void __iomem *bt_cmd;
-	__le32 bt_cmd_val[2];
-	__le32 bt_cmd_h = 0;
-	__le32 bt_cmd_l;
-	u64 bt_ba;
-	int ret = 0;
-
-	/* Find the HEM(Hardware Entry Memory) entry */
-	unsigned long i = (obj & (table->num_obj - 1)) /
-			  (table->table_chunk_size / table->obj_size);
-
-	switch (table->type) {
-	case HEM_TYPE_QPC:
-	case HEM_TYPE_MTPT:
-	case HEM_TYPE_CQC:
-	case HEM_TYPE_SRQC:
-		roce_set_field(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
-			ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, table->type);
-		break;
-	default:
-		return ret;
-	}
-
-	roce_set_field(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_M,
-		       ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_S, obj);
-	roce_set_bit(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_S, 0);
-	roce_set_bit(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_HW_SYNS_S, 1);
-
-	/* Currently iter only a chunk */
-	for (hns_roce_hem_first(table->hem[i], &iter);
-	     !hns_roce_hem_last(&iter); hns_roce_hem_next(&iter)) {
-		bt_ba = hns_roce_hem_addr(&iter) >> DMA_ADDR_T_SHIFT;
-
-		spin_lock_irqsave(lock, flags);
-
-		bt_cmd = hr_dev->reg_base + ROCEE_BT_CMD_H_REG;
-
-		end = HW_SYNC_TIMEOUT_MSECS;
-		while (end > 0) {
-			if (!(readl(bt_cmd) >> BT_CMD_SYNC_SHIFT))
-				break;
-
-			mdelay(HW_SYNC_SLEEP_TIME_INTERVAL);
-			end -= HW_SYNC_SLEEP_TIME_INTERVAL;
-		}
-
-		if (end <= 0) {
-			dev_err(dev, "Write bt_cmd err,hw_sync is not zero.\n");
-			spin_unlock_irqrestore(lock, flags);
-			return -EBUSY;
-		}
-
-		bt_cmd_l = cpu_to_le32(bt_ba);
-		roce_set_field(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_M,
-			       ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_S,
-			       bt_ba >> BT_BA_SHIFT);
-
-		bt_cmd_val[0] = bt_cmd_l;
-		bt_cmd_val[1] = bt_cmd_h;
-		hns_roce_write64_k(bt_cmd_val,
-				   hr_dev->reg_base + ROCEE_BT_CMD_L_REG);
-		spin_unlock_irqrestore(lock, flags);
-	}
-
-	return ret;
 }
 
 static int calc_hem_config(struct hns_roce_dev *hr_dev,
@@ -607,7 +528,7 @@
 
 	mutex_lock(&table->mutex);
 	if (table->hem[index.buf]) {
-		++table->hem[index.buf]->refcount;
+		refcount_inc(&table->hem[index.buf]->refcount);
 		goto out;
 	}
 
@@ -626,7 +547,7 @@
 		}
 	}
 
-	++table->hem[index.buf]->refcount;
+	refcount_set(&table->hem[index.buf]->refcount, 1);
 	goto out;
 
 err_alloc:
@@ -640,8 +561,8 @@
 		       struct hns_roce_hem_table *table, unsigned long obj)
 {
 	struct device *dev = hr_dev->dev;
-	int ret = 0;
 	unsigned long i;
+	int ret = 0;
 
 	if (hns_roce_check_whether_mhop(hr_dev, table->type))
 		return hns_roce_table_mhop_get(hr_dev, table, obj);
@@ -652,7 +573,7 @@
 	mutex_lock(&table->mutex);
 
 	if (table->hem[i]) {
-		++table->hem[i]->refcount;
+		refcount_inc(&table->hem[i]->refcount);
 		goto out;
 	}
 
@@ -667,15 +588,16 @@
 	}
 
 	/* Set HEM base address(128K/page, pa) to Hardware */
-	if (hns_roce_set_hem(hr_dev, table, obj)) {
+	ret = hr_dev->hw->set_hem(hr_dev, table, obj, HEM_HOP_STEP_DIRECT);
+	if (ret) {
 		hns_roce_free_hem(hr_dev, table->hem[i]);
 		table->hem[i] = NULL;
-		ret = -ENODEV;
-		dev_err(dev, "set HEM base address to HW failed.\n");
+		dev_err(dev, "set HEM base address to HW failed, ret = %d.\n",
+			ret);
 		goto out;
 	}
 
-	++table->hem[i]->refcount;
+	refcount_set(&table->hem[i]->refcount, 1);
 out:
 	mutex_unlock(&table->mutex);
 	return ret;
@@ -742,11 +664,11 @@
 		return;
 	}
 
-	mutex_lock(&table->mutex);
-	if (check_refcount && (--table->hem[index.buf]->refcount > 0)) {
-		mutex_unlock(&table->mutex);
+	if (!check_refcount)
+		mutex_lock(&table->mutex);
+	else if (!refcount_dec_and_mutex_lock(&table->hem[index.buf]->refcount,
+					      &table->mutex))
 		return;
-	}
 
 	clear_mhop_hem(hr_dev, table, obj, &mhop, &index);
 	free_mhop_hem(hr_dev, table, &mhop, &index);
@@ -768,16 +690,15 @@
 	i = (obj & (table->num_obj - 1)) /
 	    (table->table_chunk_size / table->obj_size);
 
-	mutex_lock(&table->mutex);
+	if (!refcount_dec_and_mutex_lock(&table->hem[i]->refcount,
+					 &table->mutex))
+		return;
 
-	if (--table->hem[i]->refcount == 0) {
-		/* Clear HEM base address */
-		if (hr_dev->hw->clear_hem(hr_dev, table, obj, 0))
-			dev_warn(dev, "Clear HEM base address failed.\n");
+	if (hr_dev->hw->clear_hem(hr_dev, table, obj, HEM_HOP_STEP_DIRECT))
+		dev_warn(dev, "failed to clear HEM base address.\n");
 
-		hns_roce_free_hem(hr_dev, table->hem[i]);
-		table->hem[i] = NULL;
-	}
+	hns_roce_free_hem(hr_dev, table->hem[i]);
+	table->hem[i] = NULL;
 
 	mutex_unlock(&table->mutex);
 }
@@ -789,14 +710,14 @@
 	struct hns_roce_hem_chunk *chunk;
 	struct hns_roce_hem_mhop mhop;
 	struct hns_roce_hem *hem;
-	void *addr = NULL;
 	unsigned long mhop_obj = obj;
 	unsigned long obj_per_chunk;
 	unsigned long idx_offset;
 	int offset, dma_offset;
+	void *addr = NULL;
+	u32 hem_idx = 0;
 	int length;
 	int i, j;
-	u32 hem_idx = 0;
 
 	if (!table->lowmem)
 		return NULL;
@@ -966,8 +887,8 @@
 {
 	struct hns_roce_hem_mhop mhop;
 	u32 buf_chunk_size;
-	int i;
 	u64 obj;
+	int i;
 
 	if (hns_roce_calc_hem_mhop(hr_dev, table, NULL, &mhop))
 		return;
@@ -1298,8 +1219,8 @@
 				  const struct hns_roce_buf_region *regions,
 				  int region_cnt)
 {
-	struct roce_hem_item *hem, *temp_hem, *root_hem;
 	struct list_head temp_list[HNS_ROCE_MAX_BT_REGION];
+	struct roce_hem_item *hem, *temp_hem, *root_hem;
 	const struct hns_roce_buf_region *r;
 	struct list_head temp_root;
 	struct list_head temp_btm;
@@ -1404,8 +1325,8 @@
 {
 	const struct hns_roce_buf_region *r;
 	int ofs, end;
-	int ret;
 	int unit;
+	int ret;
 	int i;
 
 	if (region_cnt > HNS_ROCE_MAX_BT_REGION) {
diff --git a/kernel/drivers/infiniband/hw/hns/hns_roce_hem.h b/kernel/drivers/infiniband/hw/hns/hns_roce_hem.h
index b34c940..b761778 100644
--- a/kernel/drivers/infiniband/hw/hns/hns_roce_hem.h
+++ b/kernel/drivers/infiniband/hw/hns/hns_roce_hem.h
@@ -34,9 +34,7 @@
 #ifndef _HNS_ROCE_HEM_H
 #define _HNS_ROCE_HEM_H
 
-#define HW_SYNC_SLEEP_TIME_INTERVAL	20
-#define HW_SYNC_TIMEOUT_MSECS           (25 * HW_SYNC_SLEEP_TIME_INTERVAL)
-#define BT_CMD_SYNC_SHIFT		31
+#define HEM_HOP_STEP_DIRECT 0xff
 
 enum {
 	/* MAP HEM(Hardware Entry Memory) */
@@ -73,11 +71,6 @@
 	(type >= HEM_TYPE_MTT && hop_num == 1) || \
 	(type >= HEM_TYPE_MTT && hop_num == HNS_ROCE_HOP_NUM_0))
 
-enum {
-	 HNS_ROCE_HEM_PAGE_SHIFT = 12,
-	 HNS_ROCE_HEM_PAGE_SIZE  = 1 << HNS_ROCE_HEM_PAGE_SHIFT,
-};
-
 struct hns_roce_hem_chunk {
 	struct list_head	 list;
 	int			 npages;
@@ -87,8 +80,8 @@
 };
 
 struct hns_roce_hem {
-	struct list_head	 chunk_list;
-	int			 refcount;
+	struct list_head chunk_list;
+	refcount_t refcount;
 };
 
 struct hns_roce_hem_iter {
@@ -174,4 +167,4 @@
 	return sg_dma_address(&iter->chunk->mem[iter->page_idx]);
 }
 
-#endif /*_HNS_ROCE_HEM_H*/
+#endif /* _HNS_ROCE_HEM_H */
diff --git a/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index 5f4d8a3..6f9b024 100644
--- a/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -239,7 +239,7 @@
 				break;
 			}
 
-			/*Ctrl field, ctrl set type: sig, solic, imm, fence */
+			/* Ctrl field, ctrl set type: sig, solic, imm, fence */
 			/* SO wait for conforming application scenarios */
 			ctrl->flag |= (wr->send_flags & IB_SEND_SIGNALED ?
 				      cpu_to_le32(HNS_ROCE_WQE_CQ_NOTIFY) : 0) |
@@ -300,7 +300,7 @@
 				}
 				ctrl->flag |= cpu_to_le32(HNS_ROCE_WQE_INLINE);
 			} else {
-				/*sqe num is two */
+				/* sqe num is two */
 				for (i = 0; i < wr->num_sge; i++)
 					set_data_seg(dseg + i, wr->sg_list + i);
 
@@ -448,6 +448,82 @@
 	roce_set_bit(tmp, ROCEE_GLB_CFG_ROCEE_DB_OTH_MODE_S, odb_mode);
 	val = le32_to_cpu(tmp);
 	roce_write(hr_dev, ROCEE_GLB_CFG_REG, val);
+}
+
+static int hns_roce_v1_set_hem(struct hns_roce_dev *hr_dev,
+			       struct hns_roce_hem_table *table, int obj,
+			       int step_idx)
+{
+	spinlock_t *lock = &hr_dev->bt_cmd_lock;
+	struct device *dev = hr_dev->dev;
+	struct hns_roce_hem_iter iter;
+	void __iomem *bt_cmd;
+	__le32 bt_cmd_val[2];
+	__le32 bt_cmd_h = 0;
+	unsigned long flags;
+	__le32 bt_cmd_l;
+	int ret = 0;
+	u64 bt_ba;
+	long end;
+
+	/* Find the HEM(Hardware Entry Memory) entry */
+	unsigned long i = (obj & (table->num_obj - 1)) /
+			  (table->table_chunk_size / table->obj_size);
+
+	switch (table->type) {
+	case HEM_TYPE_QPC:
+	case HEM_TYPE_MTPT:
+	case HEM_TYPE_CQC:
+	case HEM_TYPE_SRQC:
+		roce_set_field(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
+			ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, table->type);
+		break;
+	default:
+		return ret;
+	}
+
+	roce_set_field(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_M,
+		       ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_S, obj);
+	roce_set_bit(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_S, 0);
+	roce_set_bit(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_HW_SYNS_S, 1);
+
+	/* Currently iter only a chunk */
+	for (hns_roce_hem_first(table->hem[i], &iter);
+	     !hns_roce_hem_last(&iter); hns_roce_hem_next(&iter)) {
+		bt_ba = hns_roce_hem_addr(&iter) >> HNS_HW_PAGE_SHIFT;
+
+		spin_lock_irqsave(lock, flags);
+
+		bt_cmd = hr_dev->reg_base + ROCEE_BT_CMD_H_REG;
+
+		end = HW_SYNC_TIMEOUT_MSECS;
+		while (end > 0) {
+			if (!(readl(bt_cmd) >> BT_CMD_SYNC_SHIFT))
+				break;
+
+			mdelay(HW_SYNC_SLEEP_TIME_INTERVAL);
+			end -= HW_SYNC_SLEEP_TIME_INTERVAL;
+		}
+
+		if (end <= 0) {
+			dev_err(dev, "Write bt_cmd err,hw_sync is not zero.\n");
+			spin_unlock_irqrestore(lock, flags);
+			return -EBUSY;
+		}
+
+		bt_cmd_l = cpu_to_le32(bt_ba);
+		roce_set_field(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_M,
+			       ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_S,
+			       upper_32_bits(bt_ba));
+
+		bt_cmd_val[0] = bt_cmd_l;
+		bt_cmd_val[1] = bt_cmd_h;
+		hns_roce_write64_k(bt_cmd_val,
+				   hr_dev->reg_base + ROCEE_BT_CMD_L_REG);
+		spin_unlock_irqrestore(lock, flags);
+	}
+
+	return ret;
 }
 
 static void hns_roce_set_db_ext_mode(struct hns_roce_dev *hr_dev, u32 sdb_mode,
@@ -1165,7 +1241,7 @@
 	}
 	raq->e_raq_buf->map = addr;
 
-	/* Configure raq extended address. 48bit 4K align*/
+	/* Configure raq extended address. 48bit 4K align */
 	roce_write(hr_dev, ROCEE_EXT_RAQ_REG, raq->e_raq_buf->map >> 12);
 
 	/* Configure raq_shift */
@@ -2062,11 +2138,6 @@
 		       CQ_CONTEXT_CQC_BYTE_32_CQ_CONS_IDX_S, 0);
 }
 
-static int hns_roce_v1_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
-{
-	return -EOPNOTSUPP;
-}
-
 static int hns_roce_v1_req_notify_cq(struct ib_cq *ibcq,
 				     enum ib_cq_notify_flags flags)
 {
@@ -2765,7 +2836,6 @@
 		roce_set_field(context->qpc_bytes_16,
 			       QP_CONTEXT_QPC_BYTES_16_QP_NUM_M,
 			       QP_CONTEXT_QPC_BYTES_16_QP_NUM_S, hr_qp->qpn);
-
 	} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_INIT) {
 		roce_set_field(context->qpc_bytes_4,
 			       QP_CONTEXT_QPC_BYTES_4_TRANSPORT_SERVICE_TYPE_M,
@@ -3798,7 +3868,6 @@
 	int event_type;
 
 	while ((aeqe = next_aeqe_sw_v1(eq))) {
-
 		/* Make sure we read the AEQ entry after we have checked the
 		 * ownership bit
 		 */
@@ -3903,7 +3972,6 @@
 	u32 cqn;
 
 	while ((ceqe = next_ceqe_sw_v1(eq))) {
-
 		/* Make sure we read CEQ entry after we have checked the
 		 * ownership bit
 		 */
@@ -4347,7 +4415,6 @@
 
 static const struct ib_device_ops hns_roce_v1_dev_ops = {
 	.destroy_qp = hns_roce_v1_destroy_qp,
-	.modify_cq = hns_roce_v1_modify_cq,
 	.poll_cq = hns_roce_v1_poll_cq,
 	.post_recv = hns_roce_v1_post_recv,
 	.post_send = hns_roce_v1_post_send,
@@ -4367,7 +4434,7 @@
 	.set_mtu = hns_roce_v1_set_mtu,
 	.write_mtpt = hns_roce_v1_write_mtpt,
 	.write_cqc = hns_roce_v1_write_cqc,
-	.modify_cq = hns_roce_v1_modify_cq,
+	.set_hem = hns_roce_v1_set_hem,
 	.clear_hem = hns_roce_v1_clear_hem,
 	.modify_qp = hns_roce_v1_modify_qp,
 	.query_qp = hns_roce_v1_query_qp,
diff --git a/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v1.h b/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
index ffd0156..9ff1a41 100644
--- a/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
+++ b/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
@@ -419,7 +419,7 @@
 
 struct hns_roce_wqe_raddr_seg {
 	__le32 rkey;
-	__le32 len;/* reserved */
+	__le32 len; /* reserved */
 	__le64 raddr;
 };
 
@@ -1042,6 +1042,11 @@
 	struct hns_roce_ext_db *ext_db;
 };
 
+#define HW_SYNC_SLEEP_TIME_INTERVAL 20
+#define HW_SYNC_TIMEOUT_MSECS (25 * HW_SYNC_SLEEP_TIME_INTERVAL)
+#define BT_CMD_SYNC_SHIFT 31
+#define HNS_ROCE_BA_SIZE (32 * 4096)
+
 struct hns_roce_bt_table {
 	struct hns_roce_buf_list qpc_buf;
 	struct hns_roce_buf_list mtpt_buf;
diff --git a/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
index 6dab03b..322f341 100644
--- a/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+++ b/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
@@ -154,21 +154,29 @@
 		       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 dseg_len = sizeof(struct hns_roce_v2_wqe_data_seg);
-	unsigned int ext_sge_sz = qp->sq.max_gs * dseg_len;
 	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;
@@ -188,7 +196,7 @@
 		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 +211,7 @@
 
 			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;
@@ -1020,8 +1028,8 @@
 	struct hns_roce_v2_priv *priv = hr_dev->priv;
 	struct hnae3_handle *handle = priv->handle;
 	const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
-	unsigned long instance_stage;	/* the current instance stage */
-	unsigned long reset_stage;	/* the current reset stage */
+	unsigned long instance_stage; /* the current instance stage */
+	unsigned long reset_stage; /* the current reset stage */
 	unsigned long reset_cnt;
 	bool sw_resetting;
 	bool hw_resetting;
@@ -2158,6 +2166,9 @@
 	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;
 }
 
@@ -2423,7 +2434,6 @@
 		if (i < (pg_num - 1))
 			entry[i].blk_ba1_nxt_ptr |=
 				(i + 1) << HNS_ROCE_LINK_TABLE_NXT_PTR_S;
-
 	}
 	link_tbl->npages = pg_num;
 	link_tbl->pg_sz = buf_chk_sz;
@@ -2730,7 +2740,8 @@
 	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);
@@ -5528,16 +5539,14 @@
 		case HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW:
 			hns_roce_cq_event(hr_dev, cqn, event_type);
 			break;
-		case HNS_ROCE_EVENT_TYPE_DB_OVERFLOW:
-			break;
 		case HNS_ROCE_EVENT_TYPE_MB:
 			hns_roce_cmd_event(hr_dev,
 					le16_to_cpu(aeqe->event.cmd.token),
 					aeqe->event.cmd.status,
 					le64_to_cpu(aeqe->event.cmd.out_param));
 			break;
+		case HNS_ROCE_EVENT_TYPE_DB_OVERFLOW:
 		case HNS_ROCE_EVENT_TYPE_CEQ_OVERFLOW:
-			break;
 		case HNS_ROCE_EVENT_TYPE_FLR:
 			break;
 		default:
diff --git a/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
index 8a92fae..8948d2b 100644
--- a/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+++ b/kernel/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
@@ -440,7 +440,7 @@
 #define SRQC_BYTE_60_SRQ_DB_RECORD_ADDR_S 1
 #define SRQC_BYTE_60_SRQ_DB_RECORD_ADDR_M GENMASK(31, 1)
 
-enum{
+enum {
 	V2_MPT_ST_VALID = 0x1,
 	V2_MPT_ST_FREE	= 0x2,
 };
@@ -1076,9 +1076,9 @@
 	__le32	dmac;
 	__le32	byte_48;
 	u8	dgid[GID_LEN_V2];
-
 };
-#define	V2_UD_SEND_WQE_BYTE_4_OPCODE_S 0
+
+#define V2_UD_SEND_WQE_BYTE_4_OPCODE_S 0
 #define V2_UD_SEND_WQE_BYTE_4_OPCODE_M GENMASK(4, 0)
 
 #define	V2_UD_SEND_WQE_BYTE_4_OWNER_S 7
diff --git a/kernel/drivers/infiniband/hw/hns/hns_roce_main.c b/kernel/drivers/infiniband/hw/hns/hns_roce_main.c
index 1e8b3e4..90cbd15 100644
--- a/kernel/drivers/infiniband/hw/hns/hns_roce_main.c
+++ b/kernel/drivers/infiniband/hw/hns/hns_roce_main.c
@@ -511,8 +511,6 @@
 		(1ULL << IB_USER_VERBS_CMD_QUERY_QP) |
 		(1ULL << IB_USER_VERBS_CMD_DESTROY_QP);
 
-	ib_dev->uverbs_ex_cmd_mask |= (1ULL << IB_USER_VERBS_EX_CMD_MODIFY_CQ);
-
 	if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_REREG_MR) {
 		ib_dev->uverbs_cmd_mask |= (1ULL << IB_USER_VERBS_CMD_REREG_MR);
 		ib_set_device_ops(ib_dev, &hns_roce_dev_mr_ops);
@@ -584,8 +582,8 @@
 
 static int hns_roce_init_hem(struct hns_roce_dev *hr_dev)
 {
-	int ret;
 	struct device *dev = hr_dev->dev;
+	int ret;
 
 	ret = hns_roce_init_hem_table(hr_dev, &hr_dev->mr_table.mtpt_table,
 				      HEM_TYPE_MTPT, hr_dev->caps.mtpt_entry_sz,
@@ -725,8 +723,8 @@
  */
 static int hns_roce_setup_hca(struct hns_roce_dev *hr_dev)
 {
-	int ret;
 	struct device *dev = hr_dev->dev;
+	int ret;
 
 	spin_lock_init(&hr_dev->sm_lock);
 	spin_lock_init(&hr_dev->bt_cmd_lock);
@@ -849,8 +847,8 @@
 
 int hns_roce_init(struct hns_roce_dev *hr_dev)
 {
-	int ret;
 	struct device *dev = hr_dev->dev;
+	int ret;
 
 	if (hr_dev->hw->reset) {
 		ret = hr_dev->hw->reset(hr_dev, true);
diff --git a/kernel/drivers/infiniband/hw/hns/hns_roce_mr.c b/kernel/drivers/infiniband/hw/hns/hns_roce_mr.c
index 6d7cc72..d5b3b10 100644
--- a/kernel/drivers/infiniband/hw/hns/hns_roce_mr.c
+++ b/kernel/drivers/infiniband/hw/hns/hns_roce_mr.c
@@ -167,10 +167,10 @@
 static int hns_roce_mr_enable(struct hns_roce_dev *hr_dev,
 			      struct hns_roce_mr *mr)
 {
-	int ret;
 	unsigned long mtpt_idx = key_to_hw_index(mr->key);
-	struct device *dev = hr_dev->dev;
 	struct hns_roce_cmd_mailbox *mailbox;
+	struct device *dev = hr_dev->dev;
+	int ret;
 
 	/* Allocate mailbox memory */
 	mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
@@ -456,10 +456,10 @@
 
 	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);
diff --git a/kernel/drivers/infiniband/hw/hns/hns_roce_qp.c b/kernel/drivers/infiniband/hw/hns/hns_roce_qp.c
index 6fe98af..c42c676 100644
--- a/kernel/drivers/infiniband/hw/hns/hns_roce_qp.c
+++ b/kernel/drivers/infiniband/hw/hns/hns_roce_qp.c
@@ -114,8 +114,8 @@
 static void hns_roce_ib_qp_event(struct hns_roce_qp *hr_qp,
 				 enum hns_roce_event type)
 {
-	struct ib_event event;
 	struct ib_qp *ibqp = &hr_qp->ibqp;
+	struct ib_event event;
 
 	if (ibqp->event_handler) {
 		event.device = ibqp->device;
diff --git a/kernel/drivers/infiniband/hw/hns/hns_roce_srq.c b/kernel/drivers/infiniband/hw/hns/hns_roce_srq.c
index 08df97e..02e2416 100644
--- a/kernel/drivers/infiniband/hw/hns/hns_roce_srq.c
+++ b/kernel/drivers/infiniband/hw/hns/hns_roce_srq.c
@@ -245,7 +245,6 @@
 			err = -ENOMEM;
 			goto err_idx_mtr;
 		}
-
 	}
 
 	return 0;
diff --git a/kernel/drivers/infiniband/hw/i40iw/i40iw.h b/kernel/drivers/infiniband/hw/i40iw/i40iw.h
index 832b80d..13545fc 100644
--- a/kernel/drivers/infiniband/hw/i40iw/i40iw.h
+++ b/kernel/drivers/infiniband/hw/i40iw/i40iw.h
@@ -422,9 +422,8 @@
 			    bool ipv4,
 			    u32 action);
 
-int i40iw_manage_apbvt(struct i40iw_device *iwdev,
-		       u16 accel_local_port,
-		       bool add_port);
+enum i40iw_status_code i40iw_manage_apbvt(struct i40iw_device *iwdev,
+					  u16 accel_local_port, bool add_port);
 
 struct i40iw_cqp_request *i40iw_get_cqp_request(struct i40iw_cqp *cqp, bool wait);
 void i40iw_free_cqp_request(struct i40iw_cqp *cqp, struct i40iw_cqp_request *cqp_request);
diff --git a/kernel/drivers/infiniband/hw/mlx4/main.c b/kernel/drivers/infiniband/hw/mlx4/main.c
index 05c7200..c62cdd6 100644
--- a/kernel/drivers/infiniband/hw/mlx4/main.c
+++ b/kernel/drivers/infiniband/hw/mlx4/main.c
@@ -2682,8 +2682,6 @@
 
 	ib_set_device_ops(&ibdev->ib_dev, &mlx4_ib_dev_ops);
 	ibdev->ib_dev.uverbs_ex_cmd_mask |=
-		(1ull << IB_USER_VERBS_EX_CMD_MODIFY_CQ) |
-		(1ull << IB_USER_VERBS_EX_CMD_QUERY_DEVICE) |
 		(1ull << IB_USER_VERBS_EX_CMD_CREATE_CQ) |
 		(1ull << IB_USER_VERBS_EX_CMD_CREATE_QP);
 
@@ -2691,15 +2689,8 @@
 	    ((mlx4_ib_port_link_layer(&ibdev->ib_dev, 1) ==
 	    IB_LINK_LAYER_ETHERNET) ||
 	    (mlx4_ib_port_link_layer(&ibdev->ib_dev, 2) ==
-	    IB_LINK_LAYER_ETHERNET))) {
-		ibdev->ib_dev.uverbs_ex_cmd_mask |=
-			(1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ)	  |
-			(1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ)	  |
-			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ)	  |
-			(1ull << IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL) |
-			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL);
+	    IB_LINK_LAYER_ETHERNET)))
 		ib_set_device_ops(&ibdev->ib_dev, &mlx4_ib_dev_wq_ops);
-	}
 
 	if (dev->caps.flags & MLX4_DEV_CAP_FLAG_MEM_WINDOW ||
 	    dev->caps.bmme_flags & MLX4_BMME_FLAG_TYPE_2_WIN) {
@@ -2718,9 +2709,6 @@
 
 	if (check_flow_steering_support(dev)) {
 		ibdev->steering_support = MLX4_STEERING_MODE_DEVICE_MANAGED;
-		ibdev->ib_dev.uverbs_ex_cmd_mask	|=
-			(1ull << IB_USER_VERBS_EX_CMD_CREATE_FLOW) |
-			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_FLOW);
 		ib_set_device_ops(&ibdev->ib_dev, &mlx4_ib_dev_fs_ops);
 	}
 
diff --git a/kernel/drivers/infiniband/hw/mlx4/qp.c b/kernel/drivers/infiniband/hw/mlx4/qp.c
index c6a815a..50b355e 100644
--- a/kernel/drivers/infiniband/hw/mlx4/qp.c
+++ b/kernel/drivers/infiniband/hw/mlx4/qp.c
@@ -412,9 +412,13 @@
 			    struct mlx4_ib_qp *qp,
 			    struct mlx4_ib_create_qp *ucmd)
 {
+	u32 cnt;
+
 	/* Sanity check SQ size before proceeding */
-	if ((1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes	 ||
-	    ucmd->log_sq_stride >
+	if (check_shl_overflow(1, ucmd->log_sq_bb_count, &cnt) ||
+	    cnt > dev->dev->caps.max_wqes)
+		return -EINVAL;
+	if (ucmd->log_sq_stride >
 		ilog2(roundup_pow_of_two(dev->dev->caps.max_sq_desc_sz)) ||
 	    ucmd->log_sq_stride < MLX4_IB_MIN_SQ_STRIDE)
 		return -EINVAL;
@@ -526,15 +530,15 @@
 		return (-EOPNOTSUPP);
 	}
 
-	if (ucmd->rx_hash_fields_mask & ~(MLX4_IB_RX_HASH_SRC_IPV4	|
-					  MLX4_IB_RX_HASH_DST_IPV4	|
-					  MLX4_IB_RX_HASH_SRC_IPV6	|
-					  MLX4_IB_RX_HASH_DST_IPV6	|
-					  MLX4_IB_RX_HASH_SRC_PORT_TCP	|
-					  MLX4_IB_RX_HASH_DST_PORT_TCP	|
-					  MLX4_IB_RX_HASH_SRC_PORT_UDP	|
-					  MLX4_IB_RX_HASH_DST_PORT_UDP  |
-					  MLX4_IB_RX_HASH_INNER)) {
+	if (ucmd->rx_hash_fields_mask & ~(u64)(MLX4_IB_RX_HASH_SRC_IPV4	|
+					       MLX4_IB_RX_HASH_DST_IPV4	|
+					       MLX4_IB_RX_HASH_SRC_IPV6	|
+					       MLX4_IB_RX_HASH_DST_IPV6	|
+					       MLX4_IB_RX_HASH_SRC_PORT_TCP |
+					       MLX4_IB_RX_HASH_DST_PORT_TCP |
+					       MLX4_IB_RX_HASH_SRC_PORT_UDP |
+					       MLX4_IB_RX_HASH_DST_PORT_UDP |
+					       MLX4_IB_RX_HASH_INNER)) {
 		pr_debug("RX Hash fields_mask has unsupported mask (0x%llx)\n",
 			 ucmd->rx_hash_fields_mask);
 		return (-EOPNOTSUPP);
diff --git a/kernel/drivers/infiniband/hw/mlx4/sysfs.c b/kernel/drivers/infiniband/hw/mlx4/sysfs.c
index ea1f3a0..6c3a23e 100644
--- a/kernel/drivers/infiniband/hw/mlx4/sysfs.c
+++ b/kernel/drivers/infiniband/hw/mlx4/sysfs.c
@@ -221,7 +221,7 @@
 static int add_port_entries(struct mlx4_ib_dev *device, int port_num)
 {
 	int i;
-	char buff[11];
+	char buff[12];
 	struct mlx4_ib_iov_port *port = NULL;
 	int ret = 0 ;
 	struct ib_port_attr attr;
diff --git a/kernel/drivers/infiniband/hw/mlx5/devx.c b/kernel/drivers/infiniband/hw/mlx5/devx.c
index 2f053f4..a56ebdc 100644
--- a/kernel/drivers/infiniband/hw/mlx5/devx.c
+++ b/kernel/drivers/infiniband/hw/mlx5/devx.c
@@ -595,7 +595,21 @@
 				      obj_id;
 
 	case MLX5_IB_OBJECT_DEVX_OBJ:
-		return ((struct devx_obj *)uobj->object)->obj_id == obj_id;
+	{
+		u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
+		struct devx_obj *devx_uobj = uobj->object;
+
+		if (opcode == MLX5_CMD_OP_QUERY_FLOW_COUNTER &&
+		    devx_uobj->flow_counter_bulk_size) {
+			u64 end;
+
+			end = devx_uobj->obj_id +
+				devx_uobj->flow_counter_bulk_size;
+			return devx_uobj->obj_id <= obj_id && end > obj_id;
+		}
+
+		return devx_uobj->obj_id == obj_id;
+	}
 
 	default:
 		return false;
@@ -1416,10 +1430,17 @@
 		goto obj_free;
 
 	if (opcode == MLX5_CMD_OP_ALLOC_FLOW_COUNTER) {
-		u8 bulk = MLX5_GET(alloc_flow_counter_in,
-				   cmd_in,
-				   flow_counter_bulk);
-		obj->flow_counter_bulk_size = 128UL * bulk;
+		u32 bulk = MLX5_GET(alloc_flow_counter_in,
+				    cmd_in,
+				    flow_counter_bulk_log_size);
+
+		if (bulk)
+			bulk = 1 << bulk;
+		else
+			bulk = 128UL * MLX5_GET(alloc_flow_counter_in,
+						cmd_in,
+						flow_counter_bulk);
+		obj->flow_counter_bulk_size = bulk;
 	}
 
 	uobj->object = obj;
diff --git a/kernel/drivers/infiniband/hw/mlx5/main.c b/kernel/drivers/infiniband/hw/mlx5/main.c
index eb69bec..d36436d 100644
--- a/kernel/drivers/infiniband/hw/mlx5/main.c
+++ b/kernel/drivers/infiniband/hw/mlx5/main.c
@@ -425,9 +425,25 @@
 		*active_width = IB_WIDTH_2X;
 		*active_speed = IB_SPEED_HDR;
 		break;
+	case MLX5E_PROT_MASK(MLX5E_100GAUI_1_100GBASE_CR_KR):
+		*active_width = IB_WIDTH_1X;
+		*active_speed = IB_SPEED_NDR;
+		break;
 	case MLX5E_PROT_MASK(MLX5E_200GAUI_4_200GBASE_CR4_KR4):
 		*active_width = IB_WIDTH_4X;
 		*active_speed = IB_SPEED_HDR;
+		break;
+	case MLX5E_PROT_MASK(MLX5E_200GAUI_2_200GBASE_CR2_KR2):
+		*active_width = IB_WIDTH_2X;
+		*active_speed = IB_SPEED_NDR;
+		break;
+	case MLX5E_PROT_MASK(MLX5E_400GAUI_8):
+		*active_width = IB_WIDTH_8X;
+		*active_speed = IB_SPEED_HDR;
+		break;
+	case MLX5E_PROT_MASK(MLX5E_400GAUI_4_400GBASE_CR4_KR4):
+		*active_width = IB_WIDTH_4X;
+		*active_speed = IB_SPEED_NDR;
 		break;
 	default:
 		return -EINVAL;
@@ -2053,7 +2069,7 @@
 	case MLX5_IB_MMAP_DEVICE_MEM:
 		return "Device Memory";
 	default:
-		return NULL;
+		return "Unknown";
 	}
 }
 
@@ -4164,14 +4180,10 @@
 		(1ull << IB_USER_VERBS_CMD_DESTROY_SRQ)		|
 		(1ull << IB_USER_VERBS_CMD_CREATE_XSRQ)		|
 		(1ull << IB_USER_VERBS_CMD_OPEN_QP);
-	dev->ib_dev.uverbs_ex_cmd_mask =
-		(1ull << IB_USER_VERBS_EX_CMD_QUERY_DEVICE)	|
+	dev->ib_dev.uverbs_ex_cmd_mask |=
 		(1ull << IB_USER_VERBS_EX_CMD_CREATE_CQ)	|
 		(1ull << IB_USER_VERBS_EX_CMD_CREATE_QP)	|
-		(1ull << IB_USER_VERBS_EX_CMD_MODIFY_QP)	|
-		(1ull << IB_USER_VERBS_EX_CMD_MODIFY_CQ)	|
-		(1ull << IB_USER_VERBS_EX_CMD_CREATE_FLOW)	|
-		(1ull << IB_USER_VERBS_EX_CMD_DESTROY_FLOW);
+		(1ull << IB_USER_VERBS_EX_CMD_MODIFY_QP);
 
 	if (MLX5_CAP_GEN(mdev, ipoib_enhanced_offloads) &&
 	    IS_ENABLED(CONFIG_MLX5_CORE_IPOIB))
@@ -4274,12 +4286,6 @@
 	ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap);
 
 	if (ll == IB_LINK_LAYER_ETHERNET) {
-		dev->ib_dev.uverbs_ex_cmd_mask |=
-			(1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
-			(1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
-			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ) |
-			(1ull << IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL) |
-			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL);
 		ib_set_device_ops(&dev->ib_dev, &mlx5_ib_dev_common_roce_ops);
 
 		port_num = mlx5_core_native_port_num(dev->mdev) - 1;
@@ -4730,6 +4736,9 @@
 	STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
 		     mlx5_ib_stage_post_ib_reg_umr_init,
 		     NULL),
+	STAGE_CREATE(MLX5_IB_STAGE_DELAY_DROP,
+		     mlx5_ib_stage_delay_drop_init,
+		     mlx5_ib_stage_delay_drop_cleanup),
 	STAGE_CREATE(MLX5_IB_STAGE_RESTRACK,
 		     mlx5_ib_restrack_init,
 		     NULL),
diff --git a/kernel/drivers/infiniband/hw/mlx5/qp.c b/kernel/drivers/infiniband/hw/mlx5/qp.c
index 7a2bec0..0c47e3e 100644
--- a/kernel/drivers/infiniband/hw/mlx5/qp.c
+++ b/kernel/drivers/infiniband/hw/mlx5/qp.c
@@ -4164,7 +4164,7 @@
 			return -EINVAL;
 
 		if (attr->port_num == 0 ||
-		    attr->port_num > MLX5_CAP_GEN(dev->mdev, num_ports)) {
+		    attr->port_num > dev->num_ports) {
 			mlx5_ib_dbg(dev, "invalid port number %d. number of ports is %d\n",
 				    attr->port_num, dev->num_ports);
 			return -EINVAL;
@@ -4256,6 +4256,40 @@
 		return true;
 
 	return false;
+}
+
+static int validate_rd_atomic(struct mlx5_ib_dev *dev, struct ib_qp_attr *attr,
+			      int attr_mask, enum ib_qp_type qp_type)
+{
+	int log_max_ra_res;
+	int log_max_ra_req;
+
+	if (qp_type == MLX5_IB_QPT_DCI) {
+		log_max_ra_res = 1 << MLX5_CAP_GEN(dev->mdev,
+						   log_max_ra_res_dc);
+		log_max_ra_req = 1 << MLX5_CAP_GEN(dev->mdev,
+						   log_max_ra_req_dc);
+	} else {
+		log_max_ra_res = 1 << MLX5_CAP_GEN(dev->mdev,
+						   log_max_ra_res_qp);
+		log_max_ra_req = 1 << MLX5_CAP_GEN(dev->mdev,
+						   log_max_ra_req_qp);
+	}
+
+	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
+	    attr->max_rd_atomic > log_max_ra_res) {
+		mlx5_ib_dbg(dev, "invalid max_rd_atomic value %d\n",
+			    attr->max_rd_atomic);
+		return false;
+	}
+
+	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
+	    attr->max_dest_rd_atomic > log_max_ra_req) {
+		mlx5_ib_dbg(dev, "invalid max_dest_rd_atomic value %d\n",
+			    attr->max_dest_rd_atomic);
+		return false;
+	}
+	return true;
 }
 
 int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
@@ -4352,21 +4386,8 @@
 		}
 	}
 
-	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
-	    attr->max_rd_atomic >
-	    (1 << MLX5_CAP_GEN(dev->mdev, log_max_ra_res_qp))) {
-		mlx5_ib_dbg(dev, "invalid max_rd_atomic value %d\n",
-			    attr->max_rd_atomic);
+	if (!validate_rd_atomic(dev, attr, attr_mask, qp_type))
 		goto out;
-	}
-
-	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
-	    attr->max_dest_rd_atomic >
-	    (1 << MLX5_CAP_GEN(dev->mdev, log_max_ra_req_qp))) {
-		mlx5_ib_dbg(dev, "invalid max_dest_rd_atomic value %d\n",
-			    attr->max_dest_rd_atomic);
-		goto out;
-	}
 
 	if (cur_state == new_state && cur_state == IB_QPS_RESET) {
 		err = 0;
diff --git a/kernel/drivers/infiniband/hw/mlx5/qpc.c b/kernel/drivers/infiniband/hw/mlx5/qpc.c
index c683d70..9a306da 100644
--- a/kernel/drivers/infiniband/hw/mlx5/qpc.c
+++ b/kernel/drivers/infiniband/hw/mlx5/qpc.c
@@ -297,8 +297,7 @@
 	MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP);
 	MLX5_SET(destroy_qp_in, in, qpn, qp->qpn);
 	MLX5_SET(destroy_qp_in, in, uid, qp->uid);
-	mlx5_cmd_exec_in(dev->mdev, destroy_qp, in);
-	return 0;
+	return mlx5_cmd_exec_in(dev->mdev, destroy_qp, in);
 }
 
 int mlx5_core_set_delay_drop(struct mlx5_ib_dev *dev,
@@ -542,14 +541,14 @@
 	return mlx5_cmd_exec_in(dev->mdev, dealloc_xrcd, in);
 }
 
-static void destroy_rq_tracked(struct mlx5_ib_dev *dev, u32 rqn, u16 uid)
+static int destroy_rq_tracked(struct mlx5_ib_dev *dev, u32 rqn, u16 uid)
 {
 	u32 in[MLX5_ST_SZ_DW(destroy_rq_in)] = {};
 
 	MLX5_SET(destroy_rq_in, in, opcode, MLX5_CMD_OP_DESTROY_RQ);
 	MLX5_SET(destroy_rq_in, in, rqn, rqn);
 	MLX5_SET(destroy_rq_in, in, uid, uid);
-	mlx5_cmd_exec_in(dev->mdev, destroy_rq, in);
+	return mlx5_cmd_exec_in(dev->mdev, destroy_rq, in);
 }
 
 int mlx5_core_create_rq_tracked(struct mlx5_ib_dev *dev, u32 *in, int inlen,
@@ -580,8 +579,7 @@
 				 struct mlx5_core_qp *rq)
 {
 	destroy_resource_common(dev, rq);
-	destroy_rq_tracked(dev, rq->qpn, rq->uid);
-	return 0;
+	return destroy_rq_tracked(dev, rq->qpn, rq->uid);
 }
 
 static void destroy_sq_tracked(struct mlx5_ib_dev *dev, u32 sqn, u16 uid)
diff --git a/kernel/drivers/infiniband/hw/mthca/mthca_qp.c b/kernel/drivers/infiniband/hw/mthca/mthca_qp.c
index 08a2a7a..3f57f7d 100644
--- a/kernel/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/kernel/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -1390,7 +1390,7 @@
 	if (mthca_array_get(&dev->qp_table.qp, mqpn))
 		err = -EBUSY;
 	else
-		mthca_array_set(&dev->qp_table.qp, mqpn, qp->sqp);
+		mthca_array_set(&dev->qp_table.qp, mqpn, qp);
 	spin_unlock_irq(&dev->qp_table.lock);
 
 	if (err)
diff --git a/kernel/drivers/infiniband/hw/usnic/usnic_uiom.c b/kernel/drivers/infiniband/hw/usnic/usnic_uiom.c
index 760b254..48a5756 100644
--- a/kernel/drivers/infiniband/hw/usnic/usnic_uiom.c
+++ b/kernel/drivers/infiniband/hw/usnic/usnic_uiom.c
@@ -281,8 +281,8 @@
 				size = pa_end - pa_start + PAGE_SIZE;
 				usnic_dbg("va 0x%lx pa %pa size 0x%zx flags 0x%x",
 					va_start, &pa_start, size, flags);
-				err = iommu_map(pd->domain, va_start, pa_start,
-							size, flags);
+				err = iommu_map_atomic(pd->domain, va_start,
+						       pa_start, size, flags);
 				if (err) {
 					usnic_err("Failed to map va 0x%lx pa %pa size 0x%zx with err %d\n",
 						va_start, &pa_start, size, err);
@@ -298,8 +298,8 @@
 				size = pa - pa_start + PAGE_SIZE;
 				usnic_dbg("va 0x%lx pa %pa size 0x%zx flags 0x%x\n",
 					va_start, &pa_start, size, flags);
-				err = iommu_map(pd->domain, va_start, pa_start,
-						size, flags);
+				err = iommu_map_atomic(pd->domain, va_start,
+						       pa_start, size, flags);
 				if (err) {
 					usnic_err("Failed to map va 0x%lx pa %pa size 0x%zx with err %d\n",
 						va_start, &pa_start, size, err);
diff --git a/kernel/drivers/infiniband/sw/rdmavt/qp.c b/kernel/drivers/infiniband/sw/rdmavt/qp.c
index 585a9c7..ddc8825 100644
--- a/kernel/drivers/infiniband/sw/rdmavt/qp.c
+++ b/kernel/drivers/infiniband/sw/rdmavt/qp.c
@@ -505,8 +505,6 @@
 	if (qps_inuse)
 		rvt_pr_err(rdi, "QP memory leak! %u still in use\n",
 			   qps_inuse);
-	if (!rdi->qp_dev)
-		return;
 
 	kfree(rdi->qp_dev->qp_table);
 	free_qpn_table(&rdi->qp_dev->qpn_table);
diff --git a/kernel/drivers/infiniband/sw/rxe/rxe_qp.c b/kernel/drivers/infiniband/sw/rxe/rxe_qp.c
index 2e4b008..4c938d8 100644
--- a/kernel/drivers/infiniband/sw/rxe/rxe_qp.c
+++ b/kernel/drivers/infiniband/sw/rxe/rxe_qp.c
@@ -192,6 +192,9 @@
 	spin_lock_init(&qp->rq.producer_lock);
 	spin_lock_init(&qp->rq.consumer_lock);
 
+	skb_queue_head_init(&qp->req_pkts);
+	skb_queue_head_init(&qp->resp_pkts);
+
 	atomic_set(&qp->ssn, 0);
 	atomic_set(&qp->skb_out, 0);
 }
@@ -247,12 +250,8 @@
 	qp->req.opcode		= -1;
 	qp->comp.opcode		= -1;
 
-	skb_queue_head_init(&qp->req_pkts);
-
-	rxe_init_task(rxe, &qp->req.task, qp,
-		      rxe_requester, "req");
-	rxe_init_task(rxe, &qp->comp.task, qp,
-		      rxe_completer, "comp");
+	rxe_init_task(&qp->req.task, qp, rxe_requester);
+	rxe_init_task(&qp->comp.task, qp, rxe_completer);
 
 	qp->qp_timeout_jiffies = 0; /* Can't be set for UD/UC in modify_qp */
 	if (init->qp_type == IB_QPT_RC) {
@@ -296,10 +295,7 @@
 		}
 	}
 
-	skb_queue_head_init(&qp->resp_pkts);
-
-	rxe_init_task(rxe, &qp->resp.task, qp,
-		      rxe_responder, "resp");
+	rxe_init_task(&qp->resp.task, qp, rxe_responder);
 
 	qp->resp.opcode		= OPCODE_NONE;
 	qp->resp.msn		= 0;
@@ -812,12 +808,12 @@
 		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);
 	}
diff --git a/kernel/drivers/infiniband/sw/rxe/rxe_task.c b/kernel/drivers/infiniband/sw/rxe/rxe_task.c
index 568cf56..5aa6994 100644
--- a/kernel/drivers/infiniband/sw/rxe/rxe_task.c
+++ b/kernel/drivers/infiniband/sw/rxe/rxe_task.c
@@ -95,13 +95,10 @@
 	task->ret = ret;
 }
 
-int rxe_init_task(void *obj, struct rxe_task *task,
-		  void *arg, int (*func)(void *), char *name)
+int rxe_init_task(struct rxe_task *task, void *arg, int (*func)(void *))
 {
-	task->obj	= obj;
 	task->arg	= arg;
 	task->func	= func;
-	snprintf(task->name, sizeof(task->name), "%s", name);
 	task->destroyed	= false;
 
 	tasklet_setup(&task->tasklet, rxe_do_task);
diff --git a/kernel/drivers/infiniband/sw/rxe/rxe_task.h b/kernel/drivers/infiniband/sw/rxe/rxe_task.h
index 11d183f..b3dfd97 100644
--- a/kernel/drivers/infiniband/sw/rxe/rxe_task.h
+++ b/kernel/drivers/infiniband/sw/rxe/rxe_task.h
@@ -19,14 +19,12 @@
  * called again.
  */
 struct rxe_task {
-	void			*obj;
 	struct tasklet_struct	tasklet;
 	int			state;
 	spinlock_t		state_lock; /* spinlock for task state */
 	void			*arg;
 	int			(*func)(void *arg);
 	int			ret;
-	char			name[16];
 	bool			destroyed;
 };
 
@@ -35,8 +33,7 @@
  *	arg  => parameter to pass to fcn
  *	func => function to call until it returns != 0
  */
-int rxe_init_task(void *obj, struct rxe_task *task,
-		  void *arg, int (*func)(void *), char *name);
+int rxe_init_task(struct rxe_task *task, void *arg, int (*func)(void *));
 
 /* cleanup task */
 void rxe_cleanup_task(struct rxe_task *task);
diff --git a/kernel/drivers/infiniband/sw/siw/siw_cm.c b/kernel/drivers/infiniband/sw/siw/siw_cm.c
index b87ba4c..df5f675 100644
--- a/kernel/drivers/infiniband/sw/siw/siw_cm.c
+++ b/kernel/drivers/infiniband/sw/siw/siw_cm.c
@@ -973,6 +973,7 @@
 			siw_cep_put(cep);
 			new_cep->listen_cep = NULL;
 			if (rv) {
+				siw_cancel_mpatimer(new_cep);
 				siw_cep_set_free(new_cep);
 				goto error;
 			}
@@ -1097,9 +1098,12 @@
 				/*
 				 * Socket close before MPA request received.
 				 */
-				siw_dbg_cep(cep, "no mpareq: drop listener\n");
-				siw_cep_put(cep->listen_cep);
-				cep->listen_cep = NULL;
+				if (cep->listen_cep) {
+					siw_dbg_cep(cep,
+						"no mpareq: drop listener\n");
+					siw_cep_put(cep->listen_cep);
+					cep->listen_cep = NULL;
+				}
 			}
 		}
 		release_cep = 1;
@@ -1222,7 +1226,11 @@
 	if (!cep)
 		goto out;
 
-	siw_dbg_cep(cep, "state: %d\n", cep->state);
+	siw_dbg_cep(cep, "cep state: %d, socket state %d\n",
+		    cep->state, sk->sk_state);
+
+	if (sk->sk_state != TCP_ESTABLISHED)
+		goto out;
 
 	switch (cep->state) {
 	case SIW_EPSTATE_RDMA_MODE:
@@ -1490,7 +1498,6 @@
 
 		cep->cm_id = NULL;
 		id->rem_ref(id);
-		siw_cep_put(cep);
 
 		qp->cep = NULL;
 		siw_cep_put(cep);
diff --git a/kernel/drivers/infiniband/sw/siw/siw_cq.c b/kernel/drivers/infiniband/sw/siw/siw_cq.c
index d68e378..403029d 100644
--- a/kernel/drivers/infiniband/sw/siw/siw_cq.c
+++ b/kernel/drivers/infiniband/sw/siw/siw_cq.c
@@ -56,8 +56,6 @@
 	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 @@
 				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 = SIW_WC_GENERAL_ERR;
+			} else if (status >= SIW_NUM_WC_STATUS) {
+				status = SIW_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/kernel/drivers/infiniband/sw/siw/siw_main.c b/kernel/drivers/infiniband/sw/siw/siw_main.c
index 32a553a..5ba0893 100644
--- a/kernel/drivers/infiniband/sw/siw/siw_main.c
+++ b/kernel/drivers/infiniband/sw/siw/siw_main.c
@@ -458,9 +458,6 @@
 
 	dev_dbg(&netdev->dev, "siw: event %lu\n", event);
 
-	if (dev_net(netdev) != &init_net)
-		return NOTIFY_OK;
-
 	base_dev = ib_device_get_by_netdev(netdev, RDMA_DRIVER_SIW);
 	if (!base_dev)
 		return NOTIFY_OK;
diff --git a/kernel/drivers/infiniband/sw/siw/siw_qp_tx.c b/kernel/drivers/infiniband/sw/siw/siw_qp_tx.c
index 3c3ae5e..ccc6d5b 100644
--- a/kernel/drivers/infiniband/sw/siw/siw_qp_tx.c
+++ b/kernel/drivers/infiniband/sw/siw/siw_qp_tx.c
@@ -29,7 +29,7 @@
 	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;
 }
@@ -548,7 +548,7 @@
 			data_len -= plen;
 			fp_off = 0;
 
-			if (++seg > (int)MAX_ARRAY) {
+			if (++seg >= (int)MAX_ARRAY) {
 				siw_dbg_qp(tx_qp(c_tx), "to many fragments\n");
 				siw_unmap_pages(page_array, kmap_mask);
 				wqe->processed -= c_tx->bytes_unsent;
diff --git a/kernel/drivers/infiniband/sw/siw/siw_verbs.c b/kernel/drivers/infiniband/sw/siw/siw_verbs.c
index 34e847a..1d4e0dc 100644
--- a/kernel/drivers/infiniband/sw/siw/siw_verbs.c
+++ b/kernel/drivers/infiniband/sw/siw/siw_verbs.c
@@ -672,13 +672,45 @@
 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;
@@ -1455,7 +1487,7 @@
 
 	if (pbl->max_buf < num_sle) {
 		siw_dbg_mem(mem, "too many SGE's: %d > %d\n",
-			    mem->pbl->max_buf, num_sle);
+			    num_sle, pbl->max_buf);
 		return -ENOMEM;
 	}
 	for_each_sg(sl, slp, num_sle, i) {
diff --git a/kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c b/kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
index abfab89..35322d2 100644
--- a/kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -2188,6 +2188,14 @@
 		rn->attach_mcast = ipoib_mcast_attach;
 		rn->detach_mcast = ipoib_mcast_detach;
 		rn->hca = hca;
+
+		rc = netif_set_real_num_tx_queues(dev, 1);
+		if (rc)
+			goto out;
+
+		rc = netif_set_real_num_rx_queues(dev, 1);
+		if (rc)
+			goto out;
 	}
 
 	priv->rn_ops = dev->netdev_ops;
diff --git a/kernel/drivers/infiniband/ulp/ipoib/ipoib_netlink.c b/kernel/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
index 5b05cf3..28e9b70 100644
--- a/kernel/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
+++ b/kernel/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
@@ -42,6 +42,11 @@
 	[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 @@
 	.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)
diff --git a/kernel/drivers/infiniband/ulp/isert/ib_isert.c b/kernel/drivers/infiniband/ulp/isert/ib_isert.c
index edea37d..ed375f5 100644
--- a/kernel/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/kernel/drivers/infiniband/ulp/isert/ib_isert.c
@@ -656,9 +656,13 @@
 isert_connect_error(struct rdma_cm_id *cma_id)
 {
 	struct isert_conn *isert_conn = cma_id->qp->qp_context;
+	struct isert_np *isert_np = cma_id->context;
 
 	ib_drain_qp(isert_conn->qp);
+
+	mutex_lock(&isert_np->mutex);
 	list_del_init(&isert_conn->node);
+	mutex_unlock(&isert_np->mutex);
 	isert_conn->cm_id = NULL;
 	isert_put_conn(isert_conn);
 
@@ -1553,12 +1557,12 @@
 		}
 		sec_offset_err = mr_status.sig_err.sig_err_offset;
 		do_div(sec_offset_err, block_size);
-		se_cmd->bad_sector = sec_offset_err + se_cmd->t_task_lba;
+		se_cmd->sense_info = sec_offset_err + se_cmd->t_task_lba;
 
 		isert_err("PI error found type %d at sector 0x%llx "
 			  "expected 0x%x vs actual 0x%x\n",
 			  mr_status.sig_err.err_type,
-			  (unsigned long long)se_cmd->bad_sector,
+			  (unsigned long long)se_cmd->sense_info,
 			  mr_status.sig_err.expected,
 			  mr_status.sig_err.actual);
 		ret = 1;
@@ -2421,6 +2425,7 @@
 {
 	struct isert_np *isert_np = np->np_context;
 	struct isert_conn *isert_conn, *n;
+	LIST_HEAD(drop_conn_list);
 
 	if (isert_np->cm_id)
 		rdma_destroy_id(isert_np->cm_id);
@@ -2440,7 +2445,7 @@
 					 node) {
 			isert_info("cleaning isert_conn %p state (%d)\n",
 				   isert_conn, isert_conn->state);
-			isert_connect_release(isert_conn);
+			list_move_tail(&isert_conn->node, &drop_conn_list);
 		}
 	}
 
@@ -2451,11 +2456,16 @@
 					 node) {
 			isert_info("cleaning isert_conn %p state (%d)\n",
 				   isert_conn, isert_conn->state);
-			isert_connect_release(isert_conn);
+			list_move_tail(&isert_conn->node, &drop_conn_list);
 		}
 	}
 	mutex_unlock(&isert_np->mutex);
 
+	list_for_each_entry_safe(isert_conn, n, &drop_conn_list, node) {
+		list_del_init(&isert_conn->node);
+		isert_connect_release(isert_conn);
+	}
+
 	np->np_context = NULL;
 	kfree(isert_np);
 }
diff --git a/kernel/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/kernel/drivers/infiniband/ulp/rtrs/rtrs-clt.c
index 5c39e4c..1a58052 100644
--- a/kernel/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+++ b/kernel/drivers/infiniband/ulp/rtrs/rtrs-clt.c
@@ -902,7 +902,7 @@
 	req->need_inv_comp = false;
 	req->inv_errno = 0;
 
-	iov_iter_kvec(&iter, READ, vec, 1, usr_len);
+	iov_iter_kvec(&iter, WRITE, vec, 1, usr_len);
 	len = _copy_from_iter(req->iu->buf, usr_len, &iter);
 	WARN_ON(len != usr_len);
 
diff --git a/kernel/drivers/infiniband/ulp/rtrs/rtrs.c b/kernel/drivers/infiniband/ulp/rtrs/rtrs.c
index 4629bb7..76b993e 100644
--- a/kernel/drivers/infiniband/ulp/rtrs/rtrs.c
+++ b/kernel/drivers/infiniband/ulp/rtrs/rtrs.c
@@ -37,8 +37,10 @@
 			goto err;
 
 		iu->dma_addr = ib_dma_map_single(dma_dev, iu->buf, size, dir);
-		if (ib_dma_mapping_error(dma_dev, iu->dma_addr))
+		if (ib_dma_mapping_error(dma_dev, iu->dma_addr)) {
+			kfree(iu->buf);
 			goto err;
+		}
 
 		iu->cqe.done  = done;
 		iu->size      = size;
diff --git a/kernel/drivers/infiniband/ulp/srp/ib_srp.c b/kernel/drivers/infiniband/ulp/srp/ib_srp.c
index b4ccb33..9b9b955 100644
--- a/kernel/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/kernel/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1990,12 +1990,8 @@
 
 		if (unlikely(rsp->flags & SRP_RSP_FLAG_DIUNDER))
 			scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt));
-		else if (unlikely(rsp->flags & SRP_RSP_FLAG_DIOVER))
-			scsi_set_resid(scmnd, -be32_to_cpu(rsp->data_in_res_cnt));
 		else if (unlikely(rsp->flags & SRP_RSP_FLAG_DOUNDER))
 			scsi_set_resid(scmnd, be32_to_cpu(rsp->data_out_res_cnt));
-		else if (unlikely(rsp->flags & SRP_RSP_FLAG_DOOVER))
-			scsi_set_resid(scmnd, -be32_to_cpu(rsp->data_out_res_cnt));
 
 		srp_free_req(ch, req, scmnd,
 			     be32_to_cpu(rsp->req_lim_delta));
@@ -3397,7 +3393,8 @@
 			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 +3454,8 @@
 			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 +3463,15 @@
 			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 +3482,40 @@
 			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 +3524,7 @@
 				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 +3547,24 @@
 			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 +3572,77 @@
 			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 +3651,7 @@
 		default:
 			pr_warn("unknown parameter or missing value '%s' in target creation request\n",
 				p);
+			ret = -EINVAL;
 			goto out;
 		}
 	}
diff --git a/kernel/drivers/infiniband/ulp/srp/ib_srp.h b/kernel/drivers/infiniband/ulp/srp/ib_srp.h
index 6818cac..85bac20 100644
--- a/kernel/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/kernel/drivers/infiniband/ulp/srp/ib_srp.h
@@ -62,9 +62,6 @@
 	SRP_DEFAULT_CMD_SQ_SIZE = SRP_DEFAULT_QUEUE_SIZE - SRP_RSP_SQ_SIZE -
 				  SRP_TSK_MGMT_SQ_SIZE,
 
-	SRP_TAG_NO_REQ		= ~0U,
-	SRP_TAG_TSK_MGMT	= 1U << 31,
-
 	SRP_MAX_PAGES_PER_MR	= 512,
 
 	SRP_MAX_ADD_CDB_LEN	= 16,
@@ -79,6 +76,11 @@
 				  sizeof(struct srp_imm_buf),
 };
 
+enum {
+	SRP_TAG_NO_REQ		= ~0U,
+	SRP_TAG_TSK_MGMT	= BIT(31),
+};
+
 enum srp_target_state {
 	SRP_TARGET_SCANNING,
 	SRP_TARGET_LIVE,
diff --git a/kernel/drivers/infiniband/ulp/srpt/ib_srpt.c b/kernel/drivers/infiniband/ulp/srpt/ib_srpt.c
index c0ed08f..983f59c 100644
--- a/kernel/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/kernel/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -549,6 +549,7 @@
  */
 static int srpt_refresh_port(struct srpt_port *sport)
 {
+	struct ib_mad_agent *mad_agent;
 	struct ib_mad_reg_req reg_req;
 	struct ib_port_modify port_modify;
 	struct ib_port_attr port_attr;
@@ -593,24 +594,26 @@
 		set_bit(IB_MGMT_METHOD_GET, reg_req.method_mask);
 		set_bit(IB_MGMT_METHOD_SET, reg_req.method_mask);
 
-		sport->mad_agent = ib_register_mad_agent(sport->sdev->device,
-							 sport->port,
-							 IB_QPT_GSI,
-							 &reg_req, 0,
-							 srpt_mad_send_handler,
-							 srpt_mad_recv_handler,
-							 sport, 0);
-		if (IS_ERR(sport->mad_agent)) {
+		mad_agent = ib_register_mad_agent(sport->sdev->device,
+						  sport->port,
+						  IB_QPT_GSI,
+						  &reg_req, 0,
+						  srpt_mad_send_handler,
+						  srpt_mad_recv_handler,
+						  sport, 0);
+		if (IS_ERR(mad_agent)) {
 			pr_err("%s-%d: MAD agent registration failed (%ld). Note: this is expected if SR-IOV is enabled.\n",
 			       dev_name(&sport->sdev->device->dev), sport->port,
-			       PTR_ERR(sport->mad_agent));
+			       PTR_ERR(mad_agent));
 			sport->mad_agent = NULL;
 			memset(&port_modify, 0, sizeof(port_modify));
 			port_modify.clr_port_cap_mask = IB_PORT_DEVICE_MGMT_SUP;
 			ib_modify_port(sport->sdev->device, sport->port, 0,
 				       &port_modify);
-
+			return 0;
 		}
+
+		sport->mad_agent = mad_agent;
 	}
 
 	return 0;
diff --git a/kernel/drivers/input/joystick/Kconfig b/kernel/drivers/input/joystick/Kconfig
index b080f0c..d8ec519 100644
--- a/kernel/drivers/input/joystick/Kconfig
+++ b/kernel/drivers/input/joystick/Kconfig
@@ -45,6 +45,7 @@
 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.
diff --git a/kernel/drivers/input/joystick/xpad.c b/kernel/drivers/input/joystick/xpad.c
index 70dedc0..b99318f 100644
--- a/kernel/drivers/input/joystick/xpad.c
+++ b/kernel/drivers/input/joystick/xpad.c
@@ -262,7 +262,6 @@
 	{ 0x1430, 0xf801, "RedOctane Controller", 0, XTYPE_XBOX360 },
 	{ 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 },
 	{ 0x146b, 0x0604, "Bigben Interactive DAIJA Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
-	{ 0x1532, 0x0037, "Razer Sabertooth", 0, XTYPE_XBOX360 },
 	{ 0x1532, 0x0a00, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
 	{ 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE },
 	{ 0x15e4, 0x3f00, "Power A Mini Pro Elite", 0, XTYPE_XBOX360 },
@@ -488,6 +487,9 @@
 		.len		= ARRAY_SIZE(_data),	\
 	}
 
+
+#define GIP_WIRED_INTF_DATA 0
+#define GIP_WIRED_INTF_AUDIO 1
 
 /*
  * This packet is required for all Xbox One pads with 2015
@@ -1813,7 +1815,7 @@
 	}
 
 	if (xpad->xtype == XTYPE_XBOXONE &&
-	    intf->cur_altsetting->desc.bInterfaceNumber != 0) {
+	    intf->cur_altsetting->desc.bInterfaceNumber != GIP_WIRED_INTF_DATA) {
 		/*
 		 * The Xbox One controller lists three interfaces all with the
 		 * same interface class, subclass and protocol. Differentiate by
diff --git a/kernel/drivers/input/keyboard/gpio_keys.c b/kernel/drivers/input/keyboard/gpio_keys.c
index f2d4e4d..725a196 100644
--- a/kernel/drivers/input/keyboard/gpio_keys.c
+++ b/kernel/drivers/input/keyboard/gpio_keys.c
@@ -28,6 +28,7 @@
 #include <linux/of_irq.h>
 #include <linux/spinlock.h>
 #include <dt-bindings/input/gpio-keys.h>
+#include <trace/hooks/wakeupbypass.h>
 
 struct gpio_button_data {
 	const struct gpio_keys_button *button;
@@ -958,11 +959,16 @@
 	struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev);
 	struct input_dev *input = ddata->input;
 	int error;
+	int wakeup_bypass_enabled = 0;
+
+	trace_android_vh_wakeup_bypass(&wakeup_bypass_enabled);
 
 	if (device_may_wakeup(dev)) {
-		error = gpio_keys_enable_wakeup(ddata);
-		if (error)
-			return error;
+		if (!wakeup_bypass_enabled) {
+			error = gpio_keys_enable_wakeup(ddata);
+			if (error)
+				return error;
+		}
 	} else {
 		mutex_lock(&input->mutex);
 		if (input->users)
@@ -978,9 +984,13 @@
 	struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev);
 	struct input_dev *input = ddata->input;
 	int error = 0;
+	int wakeup_bypass_enabled = 0;
+
+	trace_android_vh_wakeup_bypass(&wakeup_bypass_enabled);
 
 	if (device_may_wakeup(dev)) {
-		gpio_keys_disable_wakeup(ddata);
+		if (!wakeup_bypass_enabled)
+			gpio_keys_disable_wakeup(ddata);
 	} else {
 		mutex_lock(&input->mutex);
 		if (input->users)
diff --git a/kernel/drivers/input/misc/adxl34x.c b/kernel/drivers/input/misc/adxl34x.c
index 4cc4e8f..ad035c3 100644
--- a/kernel/drivers/input/misc/adxl34x.c
+++ b/kernel/drivers/input/misc/adxl34x.c
@@ -811,8 +811,7 @@
 	AC_WRITE(ac, POWER_CTL, 0);
 
 	err = request_threaded_irq(ac->irq, NULL, adxl34x_irq,
-				   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
-				   dev_name(dev), ac);
+				   IRQF_ONESHOT, dev_name(dev), ac);
 	if (err) {
 		dev_err(dev, "irq %d busy?\n", ac->irq);
 		goto err_free_mem;
diff --git a/kernel/drivers/input/misc/drv260x.c b/kernel/drivers/input/misc/drv260x.c
index 79d7fa7..54002d1 100644
--- a/kernel/drivers/input/misc/drv260x.c
+++ b/kernel/drivers/input/misc/drv260x.c
@@ -435,6 +435,7 @@
 	}
 
 	do {
+		usleep_range(15000, 15500);
 		error = regmap_read(haptics->regmap, DRV260X_GO, &cal_buf);
 		if (error) {
 			dev_err(&haptics->client->dev,
diff --git a/kernel/drivers/input/misc/iqs269a.c b/kernel/drivers/input/misc/iqs269a.c
index a348247..8b30c91 100644
--- a/kernel/drivers/input/misc/iqs269a.c
+++ b/kernel/drivers/input/misc/iqs269a.c
@@ -9,6 +9,7 @@
  * axial sliders presented by the device.
  */
 
+#include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/err.h>
@@ -96,8 +97,6 @@
 #define IQS269_MISC_B_TRACKING_UI_ENABLE	BIT(4)
 #define IQS269_MISC_B_FILT_STR_SLIDER		GENMASK(1, 0)
 
-#define IQS269_CHx_SETTINGS			0x8C
-
 #define IQS269_CHx_ENG_A_MEAS_CAP_SIZE		BIT(15)
 #define IQS269_CHx_ENG_A_RX_GND_INACTIVE	BIT(13)
 #define IQS269_CHx_ENG_A_LOCAL_CAP_SIZE		BIT(12)
@@ -146,14 +145,7 @@
 #define IQS269_NUM_CH				8
 #define IQS269_NUM_SL				2
 
-#define IQS269_ATI_POLL_SLEEP_US		(iqs269->delay_mult * 10000)
-#define IQS269_ATI_POLL_TIMEOUT_US		(iqs269->delay_mult * 500000)
-#define IQS269_ATI_STABLE_DELAY_MS		(iqs269->delay_mult * 150)
-
-#define IQS269_PWR_MODE_POLL_SLEEP_US		IQS269_ATI_POLL_SLEEP_US
-#define IQS269_PWR_MODE_POLL_TIMEOUT_US		IQS269_ATI_POLL_TIMEOUT_US
-
-#define iqs269_irq_wait()			usleep_range(100, 150)
+#define iqs269_irq_wait()			usleep_range(200, 250)
 
 enum iqs269_local_cap_size {
 	IQS269_LOCAL_CAP_SIZE_0,
@@ -245,6 +237,18 @@
 	u8 padding;
 } __packed;
 
+struct iqs269_ch_reg {
+	u8 rx_enable;
+	u8 tx_enable;
+	__be16 engine_a;
+	__be16 engine_b;
+	__be16 ati_comp;
+	u8 thresh[3];
+	u8 hyst;
+	u8 assoc_select;
+	u8 assoc_weight;
+} __packed;
+
 struct iqs269_sys_reg {
 	__be16 general;
 	u8 active;
@@ -266,18 +270,7 @@
 	u8 timeout_swipe;
 	u8 thresh_swipe;
 	u8 redo_ati;
-} __packed;
-
-struct iqs269_ch_reg {
-	u8 rx_enable;
-	u8 tx_enable;
-	__be16 engine_a;
-	__be16 engine_b;
-	__be16 ati_comp;
-	u8 thresh[3];
-	u8 hyst;
-	u8 assoc_select;
-	u8 assoc_weight;
+	struct iqs269_ch_reg ch_reg[IQS269_NUM_CH];
 } __packed;
 
 struct iqs269_flags {
@@ -292,13 +285,11 @@
 	struct regmap *regmap;
 	struct mutex lock;
 	struct iqs269_switch_desc switches[ARRAY_SIZE(iqs269_events)];
-	struct iqs269_ch_reg ch_reg[IQS269_NUM_CH];
 	struct iqs269_sys_reg sys_reg;
+	struct completion ati_done;
 	struct input_dev *keypad;
 	struct input_dev *slider[IQS269_NUM_SL];
 	unsigned int keycode[ARRAY_SIZE(iqs269_events) * IQS269_NUM_CH];
-	unsigned int suspend_mode;
-	unsigned int delay_mult;
 	unsigned int ch_num;
 	bool hall_enable;
 	bool ati_current;
@@ -307,6 +298,7 @@
 static int iqs269_ati_mode_set(struct iqs269_private *iqs269,
 			       unsigned int ch_num, unsigned int mode)
 {
+	struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
 	u16 engine_a;
 
 	if (ch_num >= IQS269_NUM_CH)
@@ -317,12 +309,12 @@
 
 	mutex_lock(&iqs269->lock);
 
-	engine_a = be16_to_cpu(iqs269->ch_reg[ch_num].engine_a);
+	engine_a = be16_to_cpu(ch_reg[ch_num].engine_a);
 
 	engine_a &= ~IQS269_CHx_ENG_A_ATI_MODE_MASK;
 	engine_a |= (mode << IQS269_CHx_ENG_A_ATI_MODE_SHIFT);
 
-	iqs269->ch_reg[ch_num].engine_a = cpu_to_be16(engine_a);
+	ch_reg[ch_num].engine_a = cpu_to_be16(engine_a);
 	iqs269->ati_current = false;
 
 	mutex_unlock(&iqs269->lock);
@@ -333,13 +325,14 @@
 static int iqs269_ati_mode_get(struct iqs269_private *iqs269,
 			       unsigned int ch_num, unsigned int *mode)
 {
+	struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
 	u16 engine_a;
 
 	if (ch_num >= IQS269_NUM_CH)
 		return -EINVAL;
 
 	mutex_lock(&iqs269->lock);
-	engine_a = be16_to_cpu(iqs269->ch_reg[ch_num].engine_a);
+	engine_a = be16_to_cpu(ch_reg[ch_num].engine_a);
 	mutex_unlock(&iqs269->lock);
 
 	engine_a &= IQS269_CHx_ENG_A_ATI_MODE_MASK;
@@ -351,6 +344,7 @@
 static int iqs269_ati_base_set(struct iqs269_private *iqs269,
 			       unsigned int ch_num, unsigned int base)
 {
+	struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
 	u16 engine_b;
 
 	if (ch_num >= IQS269_NUM_CH)
@@ -379,12 +373,12 @@
 
 	mutex_lock(&iqs269->lock);
 
-	engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
+	engine_b = be16_to_cpu(ch_reg[ch_num].engine_b);
 
 	engine_b &= ~IQS269_CHx_ENG_B_ATI_BASE_MASK;
 	engine_b |= base;
 
-	iqs269->ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
+	ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
 	iqs269->ati_current = false;
 
 	mutex_unlock(&iqs269->lock);
@@ -395,13 +389,14 @@
 static int iqs269_ati_base_get(struct iqs269_private *iqs269,
 			       unsigned int ch_num, unsigned int *base)
 {
+	struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
 	u16 engine_b;
 
 	if (ch_num >= IQS269_NUM_CH)
 		return -EINVAL;
 
 	mutex_lock(&iqs269->lock);
-	engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
+	engine_b = be16_to_cpu(ch_reg[ch_num].engine_b);
 	mutex_unlock(&iqs269->lock);
 
 	switch (engine_b & IQS269_CHx_ENG_B_ATI_BASE_MASK) {
@@ -429,6 +424,7 @@
 static int iqs269_ati_target_set(struct iqs269_private *iqs269,
 				 unsigned int ch_num, unsigned int target)
 {
+	struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
 	u16 engine_b;
 
 	if (ch_num >= IQS269_NUM_CH)
@@ -439,12 +435,12 @@
 
 	mutex_lock(&iqs269->lock);
 
-	engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
+	engine_b = be16_to_cpu(ch_reg[ch_num].engine_b);
 
 	engine_b &= ~IQS269_CHx_ENG_B_ATI_TARGET_MASK;
 	engine_b |= target / 32;
 
-	iqs269->ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
+	ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
 	iqs269->ati_current = false;
 
 	mutex_unlock(&iqs269->lock);
@@ -455,13 +451,14 @@
 static int iqs269_ati_target_get(struct iqs269_private *iqs269,
 				 unsigned int ch_num, unsigned int *target)
 {
+	struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
 	u16 engine_b;
 
 	if (ch_num >= IQS269_NUM_CH)
 		return -EINVAL;
 
 	mutex_lock(&iqs269->lock);
-	engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
+	engine_b = be16_to_cpu(ch_reg[ch_num].engine_b);
 	mutex_unlock(&iqs269->lock);
 
 	*target = (engine_b & IQS269_CHx_ENG_B_ATI_TARGET_MASK) * 32;
@@ -531,13 +528,7 @@
 	if (fwnode_property_present(ch_node, "azoteq,slider1-select"))
 		iqs269->sys_reg.slider_select[1] |= BIT(reg);
 
-	ch_reg = &iqs269->ch_reg[reg];
-
-	error = regmap_raw_read(iqs269->regmap,
-				IQS269_CHx_SETTINGS + reg * sizeof(*ch_reg) / 2,
-				ch_reg, sizeof(*ch_reg));
-	if (error)
-		return error;
+	ch_reg = &iqs269->sys_reg.ch_reg[reg];
 
 	error = iqs269_parse_mask(ch_node, "azoteq,rx-enable",
 				  &ch_reg->rx_enable);
@@ -694,6 +685,7 @@
 				dev_err(&client->dev,
 					"Invalid channel %u threshold: %u\n",
 					reg, val);
+				fwnode_handle_put(ev_node);
 				return -EINVAL;
 			}
 
@@ -707,6 +699,7 @@
 				dev_err(&client->dev,
 					"Invalid channel %u hysteresis: %u\n",
 					reg, val);
+				fwnode_handle_put(ev_node);
 				return -EINVAL;
 			}
 
@@ -721,8 +714,16 @@
 			}
 		}
 
-		if (fwnode_property_read_u32(ev_node, "linux,code", &val))
+		error = fwnode_property_read_u32(ev_node, "linux,code", &val);
+		fwnode_handle_put(ev_node);
+		if (error == -EINVAL) {
 			continue;
+		} else if (error) {
+			dev_err(&client->dev,
+				"Failed to read channel %u code: %d\n", reg,
+				error);
+			return error;
+		}
 
 		switch (reg) {
 		case IQS269_CHx_HALL_ACTIVE:
@@ -758,17 +759,6 @@
 
 	iqs269->hall_enable = device_property_present(&client->dev,
 						      "azoteq,hall-enable");
-
-	if (!device_property_read_u32(&client->dev, "azoteq,suspend-mode",
-				      &val)) {
-		if (val > IQS269_SYS_SETTINGS_PWR_MODE_MAX) {
-			dev_err(&client->dev, "Invalid suspend mode: %u\n",
-				val);
-			return -EINVAL;
-		}
-
-		iqs269->suspend_mode = val;
-	}
 
 	error = regmap_raw_read(iqs269->regmap, IQS269_SYS_SETTINGS, sys_reg,
 				sizeof(*sys_reg));
@@ -980,13 +970,8 @@
 
 	general = be16_to_cpu(sys_reg->general);
 
-	if (device_property_present(&client->dev, "azoteq,clk-div")) {
+	if (device_property_present(&client->dev, "azoteq,clk-div"))
 		general |= IQS269_SYS_SETTINGS_CLK_DIV;
-		iqs269->delay_mult = 4;
-	} else {
-		general &= ~IQS269_SYS_SETTINGS_CLK_DIV;
-		iqs269->delay_mult = 1;
-	}
 
 	/*
 	 * Configure the device to automatically switch between normal and low-
@@ -996,6 +981,17 @@
 	general &= ~IQS269_SYS_SETTINGS_ULP_AUTO;
 	general &= ~IQS269_SYS_SETTINGS_DIS_AUTO;
 	general &= ~IQS269_SYS_SETTINGS_PWR_MODE_MASK;
+
+	if (!device_property_read_u32(&client->dev, "azoteq,suspend-mode",
+				      &val)) {
+		if (val > IQS269_SYS_SETTINGS_PWR_MODE_MAX) {
+			dev_err(&client->dev, "Invalid suspend mode: %u\n",
+				val);
+			return -EINVAL;
+		}
+
+		general |= (val << IQS269_SYS_SETTINGS_PWR_MODE_SHIFT);
+	}
 
 	if (!device_property_read_u32(&client->dev, "azoteq,ulp-update",
 				      &val)) {
@@ -1032,10 +1028,7 @@
 
 static int iqs269_dev_init(struct iqs269_private *iqs269)
 {
-	struct iqs269_sys_reg *sys_reg = &iqs269->sys_reg;
-	struct iqs269_ch_reg *ch_reg;
-	unsigned int val;
-	int error, i;
+	int error;
 
 	mutex_lock(&iqs269->lock);
 
@@ -1045,38 +1038,17 @@
 	if (error)
 		goto err_mutex;
 
-	for (i = 0; i < IQS269_NUM_CH; i++) {
-		if (!(sys_reg->active & BIT(i)))
-			continue;
-
-		ch_reg = &iqs269->ch_reg[i];
-
-		error = regmap_raw_write(iqs269->regmap,
-					 IQS269_CHx_SETTINGS + i *
-					 sizeof(*ch_reg) / 2, ch_reg,
-					 sizeof(*ch_reg));
-		if (error)
-			goto err_mutex;
-	}
+	error = regmap_raw_write(iqs269->regmap, IQS269_SYS_SETTINGS,
+				 &iqs269->sys_reg, sizeof(iqs269->sys_reg));
+	if (error)
+		goto err_mutex;
 
 	/*
-	 * The REDO-ATI and ATI channel selection fields must be written in the
-	 * same block write, so every field between registers 0x80 through 0x8B
-	 * (inclusive) must be written as well.
+	 * The following delay gives the device time to deassert its RDY output
+	 * so as to prevent an interrupt from being serviced prematurely.
 	 */
-	error = regmap_raw_write(iqs269->regmap, IQS269_SYS_SETTINGS, sys_reg,
-				 sizeof(*sys_reg));
-	if (error)
-		goto err_mutex;
+	usleep_range(2000, 2100);
 
-	error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
-					!(val & IQS269_SYS_FLAGS_IN_ATI),
-					 IQS269_ATI_POLL_SLEEP_US,
-					 IQS269_ATI_POLL_TIMEOUT_US);
-	if (error)
-		goto err_mutex;
-
-	msleep(IQS269_ATI_STABLE_DELAY_MS);
 	iqs269->ati_current = true;
 
 err_mutex:
@@ -1088,10 +1060,8 @@
 static int iqs269_input_init(struct iqs269_private *iqs269)
 {
 	struct i2c_client *client = iqs269->client;
-	struct iqs269_flags flags;
 	unsigned int sw_code, keycode;
 	int error, i, j;
-	u8 dir_mask, state;
 
 	iqs269->keypad = devm_input_allocate_device(&client->dev);
 	if (!iqs269->keypad)
@@ -1104,23 +1074,7 @@
 	iqs269->keypad->name = "iqs269a_keypad";
 	iqs269->keypad->id.bustype = BUS_I2C;
 
-	if (iqs269->hall_enable) {
-		error = regmap_raw_read(iqs269->regmap, IQS269_SYS_FLAGS,
-					&flags, sizeof(flags));
-		if (error) {
-			dev_err(&client->dev,
-				"Failed to read initial status: %d\n", error);
-			return error;
-		}
-	}
-
 	for (i = 0; i < ARRAY_SIZE(iqs269_events); i++) {
-		dir_mask = flags.states[IQS269_ST_OFFS_DIR];
-		if (!iqs269_events[i].dir_up)
-			dir_mask = ~dir_mask;
-
-		state = flags.states[iqs269_events[i].st_offs] & dir_mask;
-
 		sw_code = iqs269->switches[i].code;
 
 		for (j = 0; j < IQS269_NUM_CH; j++) {
@@ -1133,13 +1087,9 @@
 			switch (j) {
 			case IQS269_CHx_HALL_ACTIVE:
 				if (iqs269->hall_enable &&
-				    iqs269->switches[i].enabled) {
+				    iqs269->switches[i].enabled)
 					input_set_capability(iqs269->keypad,
 							     EV_SW, sw_code);
-					input_report_switch(iqs269->keypad,
-							    sw_code,
-							    state & BIT(j));
-				}
 				fallthrough;
 
 			case IQS269_CHx_HALL_INACTIVE:
@@ -1153,14 +1103,6 @@
 							     EV_KEY, keycode);
 			}
 		}
-	}
-
-	input_sync(iqs269->keypad);
-
-	error = input_register_device(iqs269->keypad);
-	if (error) {
-		dev_err(&client->dev, "Failed to register keypad: %d\n", error);
-		return error;
 	}
 
 	for (i = 0; i < IQS269_NUM_SL; i++) {
@@ -1221,6 +1163,9 @@
 
 		return error;
 	}
+
+	if (be16_to_cpu(flags.system) & IQS269_SYS_FLAGS_IN_ATI)
+		return 0;
 
 	error = regmap_raw_read(iqs269->regmap, IQS269_SLIDER_X, slider_x,
 				sizeof(slider_x));
@@ -1284,6 +1229,12 @@
 
 	input_sync(iqs269->keypad);
 
+	/*
+	 * The following completion signals that ATI has finished, any initial
+	 * switch states have been reported and the keypad can be registered.
+	 */
+	complete_all(&iqs269->ati_done);
+
 	return 0;
 }
 
@@ -1315,6 +1266,9 @@
 	if (!iqs269->ati_current || iqs269->hall_enable)
 		return -EPERM;
 
+	if (!completion_done(&iqs269->ati_done))
+		return -EBUSY;
+
 	/*
 	 * Unsolicited I2C communication prompts the device to assert its RDY
 	 * pin, so disable the interrupt line until the operation is finished
@@ -1339,6 +1293,7 @@
 			     struct device_attribute *attr, char *buf)
 {
 	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
 	struct i2c_client *client = iqs269->client;
 	unsigned int val;
 	int error;
@@ -1353,8 +1308,8 @@
 	if (error)
 		return error;
 
-	switch (iqs269->ch_reg[IQS269_CHx_HALL_ACTIVE].rx_enable &
-		iqs269->ch_reg[IQS269_CHx_HALL_INACTIVE].rx_enable) {
+	switch (ch_reg[IQS269_CHx_HALL_ACTIVE].rx_enable &
+		ch_reg[IQS269_CHx_HALL_INACTIVE].rx_enable) {
 	case IQS269_HALL_PAD_R:
 		val &= IQS269_CAL_DATA_A_HALL_BIN_R_MASK;
 		val >>= IQS269_CAL_DATA_A_HALL_BIN_R_SHIFT;
@@ -1434,9 +1389,10 @@
 			      struct device_attribute *attr, char *buf)
 {
 	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
 
 	return scnprintf(buf, PAGE_SIZE, "%u\n",
-			 iqs269->ch_reg[iqs269->ch_num].rx_enable);
+			 ch_reg[iqs269->ch_num].rx_enable);
 }
 
 static ssize_t rx_enable_store(struct device *dev,
@@ -1444,6 +1400,7 @@
 			       size_t count)
 {
 	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
 	unsigned int val;
 	int error;
 
@@ -1456,7 +1413,7 @@
 
 	mutex_lock(&iqs269->lock);
 
-	iqs269->ch_reg[iqs269->ch_num].rx_enable = val;
+	ch_reg[iqs269->ch_num].rx_enable = val;
 	iqs269->ati_current = false;
 
 	mutex_unlock(&iqs269->lock);
@@ -1568,7 +1525,9 @@
 {
 	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
 
-	return scnprintf(buf, PAGE_SIZE, "%u\n", iqs269->ati_current);
+	return scnprintf(buf, PAGE_SIZE, "%u\n",
+			 iqs269->ati_current &&
+			 completion_done(&iqs269->ati_done));
 }
 
 static ssize_t ati_trigger_store(struct device *dev,
@@ -1588,6 +1547,7 @@
 		return count;
 
 	disable_irq(client->irq);
+	reinit_completion(&iqs269->ati_done);
 
 	error = iqs269_dev_init(iqs269);
 
@@ -1596,6 +1556,10 @@
 
 	if (error)
 		return error;
+
+	if (!wait_for_completion_timeout(&iqs269->ati_done,
+					 msecs_to_jiffies(2000)))
+		return -ETIMEDOUT;
 
 	return count;
 }
@@ -1655,6 +1619,7 @@
 	}
 
 	mutex_init(&iqs269->lock);
+	init_completion(&iqs269->ati_done);
 
 	error = regmap_raw_read(iqs269->regmap, IQS269_VER_INFO, &ver_info,
 				sizeof(ver_info));
@@ -1690,6 +1655,22 @@
 		return error;
 	}
 
+	if (!wait_for_completion_timeout(&iqs269->ati_done,
+					 msecs_to_jiffies(2000))) {
+		dev_err(&client->dev, "Failed to complete ATI\n");
+		return -ETIMEDOUT;
+	}
+
+	/*
+	 * The keypad may include one or more switches and is not registered
+	 * until ATI is complete and the initial switch states are read.
+	 */
+	error = input_register_device(iqs269->keypad);
+	if (error) {
+		dev_err(&client->dev, "Failed to register keypad: %d\n", error);
+		return error;
+	}
+
 	error = devm_device_add_group(&client->dev, &iqs269_attr_group);
 	if (error)
 		dev_err(&client->dev, "Failed to add attributes: %d\n", error);
@@ -1697,59 +1678,30 @@
 	return error;
 }
 
+static u16 iqs269_general_get(struct iqs269_private *iqs269)
+{
+	u16 general = be16_to_cpu(iqs269->sys_reg.general);
+
+	general &= ~IQS269_SYS_SETTINGS_REDO_ATI;
+	general &= ~IQS269_SYS_SETTINGS_ACK_RESET;
+
+	return general | IQS269_SYS_SETTINGS_DIS_AUTO;
+}
+
 static int __maybe_unused iqs269_suspend(struct device *dev)
 {
 	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
 	struct i2c_client *client = iqs269->client;
-	unsigned int val;
 	int error;
+	u16 general = iqs269_general_get(iqs269);
 
-	if (!iqs269->suspend_mode)
+	if (!(general & IQS269_SYS_SETTINGS_PWR_MODE_MASK))
 		return 0;
 
 	disable_irq(client->irq);
 
-	/*
-	 * Automatic power mode switching must be disabled before the device is
-	 * forced into any particular power mode. In this case, the device will
-	 * transition into normal-power mode.
-	 */
-	error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
-				   IQS269_SYS_SETTINGS_DIS_AUTO, ~0);
-	if (error)
-		goto err_irq;
+	error = regmap_write(iqs269->regmap, IQS269_SYS_SETTINGS, general);
 
-	/*
-	 * The following check ensures the device has completed its transition
-	 * into normal-power mode before a manual mode switch is performed.
-	 */
-	error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
-					!(val & IQS269_SYS_FLAGS_PWR_MODE_MASK),
-					 IQS269_PWR_MODE_POLL_SLEEP_US,
-					 IQS269_PWR_MODE_POLL_TIMEOUT_US);
-	if (error)
-		goto err_irq;
-
-	error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
-				   IQS269_SYS_SETTINGS_PWR_MODE_MASK,
-				   iqs269->suspend_mode <<
-				   IQS269_SYS_SETTINGS_PWR_MODE_SHIFT);
-	if (error)
-		goto err_irq;
-
-	/*
-	 * This last check ensures the device has completed its transition into
-	 * the desired power mode to prevent any spurious interrupts from being
-	 * triggered after iqs269_suspend has already returned.
-	 */
-	error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
-					 (val & IQS269_SYS_FLAGS_PWR_MODE_MASK)
-					 == (iqs269->suspend_mode <<
-					     IQS269_SYS_FLAGS_PWR_MODE_SHIFT),
-					 IQS269_PWR_MODE_POLL_SLEEP_US,
-					 IQS269_PWR_MODE_POLL_TIMEOUT_US);
-
-err_irq:
 	iqs269_irq_wait();
 	enable_irq(client->irq);
 
@@ -1760,43 +1712,20 @@
 {
 	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
 	struct i2c_client *client = iqs269->client;
-	unsigned int val;
 	int error;
+	u16 general = iqs269_general_get(iqs269);
 
-	if (!iqs269->suspend_mode)
+	if (!(general & IQS269_SYS_SETTINGS_PWR_MODE_MASK))
 		return 0;
 
 	disable_irq(client->irq);
 
-	error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
-				   IQS269_SYS_SETTINGS_PWR_MODE_MASK, 0);
-	if (error)
-		goto err_irq;
+	error = regmap_write(iqs269->regmap, IQS269_SYS_SETTINGS,
+			     general & ~IQS269_SYS_SETTINGS_PWR_MODE_MASK);
+	if (!error)
+		error = regmap_write(iqs269->regmap, IQS269_SYS_SETTINGS,
+				     general & ~IQS269_SYS_SETTINGS_DIS_AUTO);
 
-	/*
-	 * This check ensures the device has returned to normal-power mode
-	 * before automatic power mode switching is re-enabled.
-	 */
-	error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
-					!(val & IQS269_SYS_FLAGS_PWR_MODE_MASK),
-					 IQS269_PWR_MODE_POLL_SLEEP_US,
-					 IQS269_PWR_MODE_POLL_TIMEOUT_US);
-	if (error)
-		goto err_irq;
-
-	error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
-				   IQS269_SYS_SETTINGS_DIS_AUTO, 0);
-	if (error)
-		goto err_irq;
-
-	/*
-	 * This step reports any events that may have been "swallowed" as a
-	 * result of polling PWR_MODE (which automatically acknowledges any
-	 * pending interrupts).
-	 */
-	error = iqs269_report(iqs269);
-
-err_irq:
 	iqs269_irq_wait();
 	enable_irq(client->irq);
 
diff --git a/kernel/drivers/input/misc/soc_button_array.c b/kernel/drivers/input/misc/soc_button_array.c
index 31c02c2..67a134c 100644
--- a/kernel/drivers/input/misc/soc_button_array.c
+++ b/kernel/drivers/input/misc/soc_button_array.c
@@ -109,6 +109,27 @@
 };
 
 /*
+ * Some devices have a wrong entry which points to a GPIO which is
+ * required in another driver, so this driver must not claim it.
+ */
+static const struct dmi_system_id dmi_invalid_acpi_index[] = {
+	{
+		/*
+		 * Lenovo Yoga Book X90F / X90L, the PNP0C40 home button entry
+		 * points to a GPIO which is not a home button and which is
+		 * required by the lenovo-yogabook driver.
+		 */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"),
+		},
+		.driver_data = (void *)1l,
+	},
+	{} /* Terminating entry */
+};
+
+/*
  * Get the Nth GPIO number from the ACPI object.
  */
 static int soc_button_lookup_gpio(struct device *dev, int acpi_index,
@@ -137,6 +158,8 @@
 	struct platform_device *pd;
 	struct gpio_keys_button *gpio_keys;
 	struct gpio_keys_platform_data *gpio_keys_pdata;
+	const struct dmi_system_id *dmi_id;
+	int invalid_acpi_index = -1;
 	int error, gpio, irq;
 	int n_buttons = 0;
 
@@ -154,10 +177,17 @@
 	gpio_keys = (void *)(gpio_keys_pdata + 1);
 	n_buttons = 0;
 
+	dmi_id = dmi_first_match(dmi_invalid_acpi_index);
+	if (dmi_id)
+		invalid_acpi_index = (long)dmi_id->driver_data;
+
 	for (info = button_info; info->name; info++) {
 		if (info->autorepeat != autorepeat)
 			continue;
 
+		if (info->acpi_index == invalid_acpi_index)
+			continue;
+
 		error = soc_button_lookup_gpio(&pdev->dev, info->acpi_index, &gpio, &irq);
 		if (error || irq < 0) {
 			/*
diff --git a/kernel/drivers/input/mouse/alps.c b/kernel/drivers/input/mouse/alps.c
index b067bfd..0b10c46 100644
--- a/kernel/drivers/input/mouse/alps.c
+++ b/kernel/drivers/input/mouse/alps.c
@@ -852,8 +852,8 @@
 			x = y = z = 0;
 
 		/* Divide 4 since trackpoint's speed is too fast */
-		input_report_rel(dev2, REL_X, (char)x / 4);
-		input_report_rel(dev2, REL_Y, -((char)y / 4));
+		input_report_rel(dev2, REL_X, (s8)x / 4);
+		input_report_rel(dev2, REL_Y, -((s8)y / 4));
 
 		psmouse_report_standard_buttons(dev2, packet[3]);
 
@@ -1104,8 +1104,8 @@
 	    ((packet[3] & 0x20) << 1);
 	z = (packet[5] & 0x3f) | ((packet[3] & 0x80) >> 1);
 
-	input_report_rel(dev2, REL_X, (char)x);
-	input_report_rel(dev2, REL_Y, -((char)y));
+	input_report_rel(dev2, REL_X, (s8)x);
+	input_report_rel(dev2, REL_Y, -((s8)y));
 	input_report_abs(dev2, ABS_PRESSURE, z);
 
 	psmouse_report_standard_buttons(dev2, packet[1]);
@@ -2294,20 +2294,20 @@
 	if (reg < 0)
 		return reg;
 
-	x_pitch = (char)(reg << 4) >> 4; /* sign extend lower 4 bits */
+	x_pitch = (s8)(reg << 4) >> 4; /* sign extend lower 4 bits */
 	x_pitch = 50 + 2 * x_pitch; /* In 0.1 mm units */
 
-	y_pitch = (char)reg >> 4; /* sign extend upper 4 bits */
+	y_pitch = (s8)reg >> 4; /* sign extend upper 4 bits */
 	y_pitch = 36 + 2 * y_pitch; /* In 0.1 mm units */
 
 	reg = alps_command_mode_read_reg(psmouse, reg_pitch + 1);
 	if (reg < 0)
 		return reg;
 
-	x_electrode = (char)(reg << 4) >> 4; /* sign extend lower 4 bits */
+	x_electrode = (s8)(reg << 4) >> 4; /* sign extend lower 4 bits */
 	x_electrode = 17 + x_electrode;
 
-	y_electrode = (char)reg >> 4; /* sign extend upper 4 bits */
+	y_electrode = (s8)reg >> 4; /* sign extend upper 4 bits */
 	y_electrode = 13 + y_electrode;
 
 	x_phys = x_pitch * (x_electrode - 1); /* In 0.1 mm units */
diff --git a/kernel/drivers/input/mouse/elantech.c b/kernel/drivers/input/mouse/elantech.c
index 2e53ea2..598fcb9 100644
--- a/kernel/drivers/input/mouse/elantech.c
+++ b/kernel/drivers/input/mouse/elantech.c
@@ -674,10 +674,11 @@
 	struct input_dev *dev = psmouse->dev;
 	struct elantech_data *etd = psmouse->private;
 	unsigned char *packet = psmouse->packet;
-	int id = ((packet[3] & 0xe0) >> 5) - 1;
+	int id;
 	int pres, traces;
 
-	if (id < 0)
+	id = ((packet[3] & 0xe0) >> 5) - 1;
+	if (id < 0 || id >= ETP_MAX_FINGERS)
 		return;
 
 	etd->mt[id].x = ((packet[1] & 0x0f) << 8) | packet[2];
@@ -707,7 +708,7 @@
 	int id, sid;
 
 	id = ((packet[0] & 0xe0) >> 5) - 1;
-	if (id < 0)
+	if (id < 0 || id >= ETP_MAX_FINGERS)
 		return;
 
 	sid = ((packet[3] & 0xe0) >> 5) - 1;
@@ -728,7 +729,7 @@
 	input_report_abs(dev, ABS_MT_POSITION_X, etd->mt[id].x);
 	input_report_abs(dev, ABS_MT_POSITION_Y, etd->mt[id].y);
 
-	if (sid >= 0) {
+	if (sid >= 0 && sid < ETP_MAX_FINGERS) {
 		etd->mt[sid].x += delta_x2 * weight;
 		etd->mt[sid].y -= delta_y2 * weight;
 		input_mt_slot(dev, sid);
diff --git a/kernel/drivers/input/mouse/focaltech.c b/kernel/drivers/input/mouse/focaltech.c
index 6fd5fff..c74b990 100644
--- a/kernel/drivers/input/mouse/focaltech.c
+++ b/kernel/drivers/input/mouse/focaltech.c
@@ -202,8 +202,8 @@
 	state->pressed = packet[0] >> 7;
 	finger1 = ((packet[0] >> 4) & 0x7) - 1;
 	if (finger1 < FOC_MAX_FINGERS) {
-		state->fingers[finger1].x += (char)packet[1];
-		state->fingers[finger1].y += (char)packet[2];
+		state->fingers[finger1].x += (s8)packet[1];
+		state->fingers[finger1].y += (s8)packet[2];
 	} else {
 		psmouse_err(psmouse, "First finger in rel packet invalid: %d\n",
 			    finger1);
@@ -218,8 +218,8 @@
 	 */
 	finger2 = ((packet[3] >> 4) & 0x7) - 1;
 	if (finger2 < FOC_MAX_FINGERS) {
-		state->fingers[finger2].x += (char)packet[4];
-		state->fingers[finger2].y += (char)packet[5];
+		state->fingers[finger2].x += (s8)packet[4];
+		state->fingers[finger2].y += (s8)packet[5];
 	}
 }
 
diff --git a/kernel/drivers/input/mouse/synaptics.c b/kernel/drivers/input/mouse/synaptics.c
index f1013b9..8257709 100644
--- a/kernel/drivers/input/mouse/synaptics.c
+++ b/kernel/drivers/input/mouse/synaptics.c
@@ -191,7 +191,6 @@
 	"SYN3221", /* HP 15-ay000 */
 	"SYN323d", /* HP Spectre X360 13-w013dx */
 	"SYN3257", /* HP Envy 13-ad105ng */
-	"SYN3286", /* HP Laptop 15-da3001TU */
 	NULL
 };
 
diff --git a/kernel/drivers/input/sensors/accel/Kconfig b/kernel/drivers/input/sensors/accel/Kconfig
index 4576b8c..fb10b4c 100644
--- a/kernel/drivers/input/sensors/accel/Kconfig
+++ b/kernel/drivers/input/sensors/accel/Kconfig
@@ -158,6 +158,12 @@
 	  To have support for your specific gsesnor you will have to
 	  select the proper drivers which depend on this option.
 
+config ICM4260X_ACC
+	tristate "gsensor icm4260x"
+	help
+	  To have support for your specific gsesnor you will have to
+	  select the proper drivers which depend on this option.
+
 config IAM20680_ACC
 	tristate "gsensor iam20680"
 	default n
diff --git a/kernel/drivers/input/sensors/accel/Makefile b/kernel/drivers/input/sensors/accel/Makefile
index 96f6cc6..67e0bcd 100644
--- a/kernel/drivers/input/sensors/accel/Makefile
+++ b/kernel/drivers/input/sensors/accel/Makefile
@@ -21,5 +21,6 @@
 obj-$(CONFIG_GS_DA223)		+= da223.o
 obj-$(CONFIG_GS_DA228E)		+= da228e/
 obj-$(CONFIG_ICM2060X_ACC)	+= icm2060x_acc.o
+obj-$(CONFIG_ICM4260X_ACC)	+= icm4260x_acc.o
 da223-y	:= da223_cust.o da223_core.o
 obj-$(CONFIG_IAM20680_ACC)	+= iam20680_acc.o
diff --git a/kernel/drivers/input/sensors/accel/icm4260x_acc.c b/kernel/drivers/input/sensors/accel/icm4260x_acc.c
new file mode 100644
index 0000000..c2a3b2c
--- /dev/null
+++ b/kernel/drivers/input/sensors/accel/icm4260x_acc.c
@@ -0,0 +1,470 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Rockchip Co.,Ltd.
+ * Author: Wangqiang Guo <kay.guo@rock-chips.com>
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <linux/uaccess.h>
+#include <linux/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+#include <linux/icm4260x.h>
+
+/**
+ * icm4260x_set_idle() - Set Idle bit in PWR_MGMT_0 register
+ * @client: struct i2c_client..
+ *
+ * Set ACCEL_LP_CLK_SEL as well when necessary with a proper wait
+ *
+ * Return: 0 when successful.
+ */
+static int icm4260x_set_idle(struct i2c_client *client)
+{
+	u8 reg_pwr_mgmt_0;
+	u8 d;
+	int ret = 0;
+
+	reg_pwr_mgmt_0 = sensor_read_reg(client, ICM4260X_PWR_MGMT_0);
+	/* set Idle bit.
+	 * when accel LPM is already enabled, set ACCEL_LP_CLK_SEL bit as well.
+	 */
+	d = reg_pwr_mgmt_0;
+	d |= BIT_IDLE;
+	if ((d & BIT_ACCEL_MODE_MASK) == BIT_ACCEL_MODE_LPM)
+		d |= BIT_ACCEL_LP_CLK_SEL;
+
+	ret = sensor_write_reg(client, ICM4260X_PWR_MGMT_0, d);
+	usleep_range(20, 21);
+
+	return ret;
+}
+
+/**
+ * icm4260x_mreg_read() - Multiple byte read from MREG area.
+ * @client: struct i2c_client.
+ * @addr: MREG register start address including bank in upper byte.
+ * @len: length to read in byte.
+ * @data: pointer to store read data.
+ *
+ * Return: 0 when successful.
+ */
+static int icm4260x_mreg_read(struct i2c_client *client, int addr, int len, u8 *data)
+{
+	int ret;
+	u8 reg_pwr_mgmt_0;
+
+	reg_pwr_mgmt_0 = sensor_read_reg(client, ICM4260X_PWR_MGMT_0);
+
+	ret = icm4260x_set_idle(client);
+	if (ret)
+		return ret;
+
+	ret = sensor_write_reg(client, ICM4260X_BLK_SEL_R, (addr >> 8) & 0xff);
+	usleep_range(INV_ICM42607_BLK_SEL_WAIT_US,
+			INV_ICM42607_BLK_SEL_WAIT_US + 1);
+	if (ret)
+		goto restore_bank;
+
+	ret = sensor_write_reg(client, ICM4260X_MADDR_R, addr & 0xff);
+	usleep_range(INV_ICM42607_MADDR_WAIT_US,
+			INV_ICM42607_MADDR_WAIT_US + 1);
+	if (ret)
+		goto restore_bank;
+
+	*data = ICM4260X_M_R;
+	ret = sensor_rx_data(client, data, len);
+	usleep_range(INV_ICM42607_M_RW_WAIT_US,
+			INV_ICM42607_M_RW_WAIT_US + 1);
+	if (ret)
+		goto restore_bank;
+
+restore_bank:
+	ret |= sensor_write_reg(client, ICM4260X_BLK_SEL_R, 0);
+	usleep_range(INV_ICM42607_BLK_SEL_WAIT_US,
+			INV_ICM42607_BLK_SEL_WAIT_US + 1);
+
+	ret |= sensor_write_reg(client, ICM4260X_PWR_MGMT_0, reg_pwr_mgmt_0);
+
+	return ret;
+}
+
+/**
+ * icm4260x_mreg_single_write() - Single byte write to MREG area.
+ * @client: struct i2c_client.
+ * @addr: MREG register address including bank in upper byte.
+ * @data: data to write.
+ *
+ * Return: 0 when successful.
+ */
+static int icm4260x_mreg_single_write(struct i2c_client *client, int addr, u8 data)
+{
+	int ret;
+	u8 reg_pwr_mgmt_0;
+
+	reg_pwr_mgmt_0 = sensor_read_reg(client, ICM4260X_PWR_MGMT_0);
+
+	ret = icm4260x_set_idle(client);
+	if (ret)
+		return ret;
+
+	ret = sensor_write_reg(client, ICM4260X_BLK_SEL_W, (addr >> 8) & 0xff);
+	usleep_range(INV_ICM42607_BLK_SEL_WAIT_US,
+			INV_ICM42607_BLK_SEL_WAIT_US + 1);
+	if (ret)
+		goto restore_bank;
+
+	ret = sensor_write_reg(client, ICM4260X_MADDR_W, addr & 0xff);
+	usleep_range(INV_ICM42607_MADDR_WAIT_US,
+			INV_ICM42607_MADDR_WAIT_US + 1);
+	if (ret)
+		goto restore_bank;
+
+	ret = sensor_write_reg(client, ICM4260X_M_W, data);
+	usleep_range(INV_ICM42607_M_RW_WAIT_US,
+			INV_ICM42607_M_RW_WAIT_US + 1);
+	if (ret)
+		goto restore_bank;
+
+restore_bank:
+	ret |= sensor_write_reg(client, ICM4260X_BLK_SEL_W, 0);
+	usleep_range(INV_ICM42607_BLK_SEL_WAIT_US,
+			INV_ICM42607_BLK_SEL_WAIT_US + 1);
+
+	ret |= sensor_write_reg(client, ICM4260X_PWR_MGMT_0, reg_pwr_mgmt_0);
+
+	return ret;
+}
+
+/*
+ * OTP reload procedure.
+ */
+static int icm4260x_otp_reload(struct i2c_client *client)
+{
+	int ret;
+	u8 rb = 0;
+
+	/* set idle bit */
+	ret = icm4260x_set_idle(client);
+	if (ret)
+		return ret;
+
+	/* Set OTP_COPY_MODE to 2'b01 */
+	ret = icm4260x_mreg_read(client, ICM4260X_OTP_CONFIG_MREG_TOP1, 1, &rb);
+	if (ret)
+		return ret;
+	rb &= ~OTP_COPY_MODE_MASK;
+	rb |= BIT_OTP_COPY_NORMAL;
+	ret = icm4260x_mreg_single_write(client, ICM4260X_OTP_CONFIG_MREG_TOP1, rb);
+	if (ret)
+		return ret;
+
+	/* set OTP_PWR_DOWN to 1'b0 and wait for 300us */
+	ret = icm4260x_mreg_read(client, ICM4260X_OTP_CTRL7_MREG_OTP, 1, &rb);
+	if (ret)
+		return ret;
+	rb &= ~BIT_OTP_PWR_DOWN;
+	ret = icm4260x_mreg_single_write(client, ICM4260X_OTP_CTRL7_MREG_OTP, rb);
+	if (ret)
+		return ret;
+	usleep_range(300, 400);
+
+	/* set OTP_RELOAD to 1'b1 and wait for 280us */
+	ret = icm4260x_mreg_read(client, ICM4260X_OTP_CTRL7_MREG_OTP, 1, &rb);
+	if (ret)
+		return ret;
+	rb |= BIT_OTP_RELOAD;
+	ret = icm4260x_mreg_single_write(client, ICM4260X_OTP_CTRL7_MREG_OTP, rb);
+	if (ret)
+		return ret;
+	usleep_range(280, 380);
+
+	return 0;
+}
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+	struct sensor_private_data *sensor =
+	    (struct sensor_private_data *) i2c_get_clientdata(client);
+	int result = 0;
+	u8 status = 0;
+
+	sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+
+	if (!enable) {
+		status = (0xff & ~BIT_ACCEL_MODE_MASK);
+		sensor->ops->ctrl_data &= status;
+	} else {
+		status = BIT_ACCEL_MODE_LNM;
+		sensor->ops->ctrl_data |= status;
+		sensor->ops->ctrl_data &= ~BIT_IDLE;
+	}
+
+	result = sensor_write_reg(client, sensor->ops->ctrl_reg,
+						sensor->ops->ctrl_data);
+	if (result) {
+		dev_err(&client->dev,
+			"%s: fail to set pwr_mgmt0(%d)\n", __func__, result);
+		return result;
+	}
+	usleep_range(250, 260);
+
+	return result;
+}
+
+/*
+ * write POR value
+ */
+
+static int icm4260x_set_default_register(struct i2c_client *client)
+{
+	int status = 0;
+
+	status |= sensor_write_reg(client, ICM4260X_GYRO_CONFIG0, 0x06);
+	status |= sensor_write_reg(client, ICM4260X_ACCEL_CONFIG0, 0x06);
+	status |= sensor_write_reg(client, ICM4260X_APEX_CONFIG0, 0x08);
+	status |= sensor_write_reg(client, ICM4260X_APEX_CONFIG1, 0x02);
+	status |= sensor_write_reg(client, ICM4260X_WOM_CONFIG, 0);
+	status |= sensor_write_reg(client, ICM4260X_FIFO_CONFIG1, 0x01);
+	status |= sensor_write_reg(client, ICM4260X_FIFO_CONFIG2, 0);
+	status |= sensor_write_reg(client, ICM4260X_FIFO_CONFIG3, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_FIFO_CONFIG5_MREG_TOP1, 0x20);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_ST_CONFIG_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_INT_SOURCE7_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_INT_SOURCE8_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_INT_SOURCE9_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_INT_SOURCE10_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG2_MREG_TOP1, 0xA2);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG3_MREG_TOP1, 0x85);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG4_MREG_TOP1, 0x51);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG5_MREG_TOP1, 0x80);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG9_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG10_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG11_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_ACCEL_WOM_X_THR_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_ACCEL_WOM_Y_THR_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_ACCEL_WOM_Z_THR_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER0_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER1_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER2_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER3_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER4_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER5_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER6_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER7_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER8_MREG_TOP1, 0);
+	status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG12_MREG_TOP1, 0);
+
+	if (status)
+		return -EIO;
+
+	return 0;
+}
+
+static int sensor_init(struct i2c_client *client)
+{
+	int ret = 0;
+	u8 device_id = 0, value = 0;
+	struct sensor_private_data *sensor =
+	    (struct sensor_private_data *) i2c_get_clientdata(client);
+
+	device_id = sensor_read_reg(client, ICM4260X_WHO_AM_I);
+	if (device_id != ICM42607_DEVICE_ID) {
+		dev_err(&client->dev, "%s: check id err, read_id: %d\n",
+			__func__, device_id);
+		return -1;
+	}
+
+	ret = icm4260x_otp_reload(client);
+	if (ret) {
+		dev_err(&client->dev,
+			"ICM4260X OTP reload error,ret: %d!\n", ret);
+		return ret;
+	}
+
+
+	ret = icm4260x_set_default_register(client);
+	if (ret) {
+		dev_err(&client->dev,
+			"set ICM4260X default_register error,ret: %d!\n", ret);
+		return ret;
+	}
+
+	/* SPI or I2C only
+	 * FIFO count  : byte mode, big endian
+	 * sensor data : big endian
+	 */
+	value |= BIT_FIFO_COUNT_ENDIAN;
+	value |= BIT_SENSOR_DATA_ENDIAN;
+	ret = sensor_write_reg(client, ICM4260X_INTF_CONFIG0, value);
+	if (ret)
+		return ret;
+
+	/* configure clock */
+	value = BIT_CLK_SEL_PLL | BIT_I3C_SDR_EN | BIT_I3C_DDR_EN;
+	ret = sensor_write_reg(client, ICM4260X_INTF_CONFIG1, value);
+	if (ret)
+		return ret;
+
+	/* INT pin configuration */
+	/*
+	 * value = (INT_POLARITY << SHIFT_INT1_POLARITY) |
+	 *	(INT_DRIVE_CIRCUIT << SHIFT_INT1_DRIVE_CIRCUIT) |
+	 *	(INT_MODE << SHIFT_INT1_MODE);
+	 * ret = sensor_write_reg(client, ICM4260X_INT_CONFIG_REG, value);
+	 * if (ret)
+	 *	return ret;
+	 */
+
+	/* disable sensors */
+	ret = sensor_write_reg(client, ICM4260X_PWR_MGMT_0, 0);
+	if (ret)
+		return ret;
+
+	/* set Full scale select for accelerometer UI interface output*/
+	value = sensor_read_reg(client, ICM4260X_ACCEL_CONFIG0);
+	value &= ~BIT_ACCEL_FSR;
+	value |= ACCEL_FS_SEL << SHIFT_ACCEL_FS_SEL;
+	ret = sensor_write_reg(client, ICM4260X_ACCEL_CONFIG0, value);
+	if (ret)
+		return ret;
+
+	/* turn on accelerometer*/
+	ret = sensor->ops->active(client, 0, sensor->pdata->poll_delay_ms);
+	if (ret) {
+		dev_err(&client->dev,
+			"%s: fail to active sensor(%d)\n", __func__, ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int gsensor_report_value(struct i2c_client *client,
+				struct sensor_axis *axis)
+{
+	struct sensor_private_data *sensor =
+	    (struct sensor_private_data *) i2c_get_clientdata(client);
+
+	if (sensor->status_cur == SENSOR_ON) {
+		/* Report acceleration sensor information */
+		input_report_abs(sensor->input_dev, ABS_X, axis->x);
+		input_report_abs(sensor->input_dev, ABS_Y, axis->y);
+		input_report_abs(sensor->input_dev, ABS_Z, axis->z);
+		input_sync(sensor->input_dev);
+	}
+
+	return 0;
+}
+
+static int sensor_report_value(struct i2c_client *client)
+{
+	struct sensor_private_data *sensor =
+		(struct sensor_private_data *) i2c_get_clientdata(client);
+	struct sensor_platform_data *pdata = sensor->pdata;
+	int ret = 0;
+	short x, y, z;
+	struct sensor_axis axis;
+	u8 buffer[6] = {0};
+
+	if (sensor->ops->read_len < 6) {
+		dev_err(&client->dev, "%s: length is error, len = %d\n",
+			__func__, sensor->ops->read_len);
+		return -EINVAL;
+	}
+
+	/* Data bytes from hardware xH, xL, yH, yL, zH, zL */
+	*buffer = sensor->ops->read_reg;
+	ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
+	if (ret < 0) {
+		dev_err(&client->dev,
+			"%s: read data failed, ret = %d\n", __func__, ret);
+		return ret;
+	}
+	x = ((buffer[0] << 8) & 0xff00) + (buffer[1] & 0xFF);
+	y = ((buffer[2] << 8) & 0xff00) + (buffer[3] & 0xFF);
+	z = ((buffer[4] << 8) & 0xff00) + (buffer[5] & 0xFF);
+
+	//printk("%s,x:%d, y:%d, z:%d\n", __func__, x, y, z);
+	axis.x = (pdata->orientation[0]) * x + (pdata->orientation[1]) * y +
+		 (pdata->orientation[2]) * z;
+	axis.y = (pdata->orientation[3]) * x + (pdata->orientation[4]) * y +
+		 (pdata->orientation[5]) * z;
+	axis.z = (pdata->orientation[6]) * x + (pdata->orientation[7]) * y +
+		 (pdata->orientation[8]) * z;
+
+	gsensor_report_value(client, &axis);
+
+	mutex_lock(&(sensor->data_mutex));
+	sensor->axis = axis;
+	mutex_unlock(&(sensor->data_mutex));
+
+	return ret;
+}
+
+static struct sensor_operate gsensor_icm4260x_ops = {
+	.name		= "icm4260x_acc",
+	.type		= SENSOR_TYPE_ACCEL,
+	.id_i2c		= ACCEL_ID_ICM4260X,
+	.read_reg	= ICM4260X_ACCEL_DATA_X0,
+	.read_len	= 6,
+	.id_reg		= SENSOR_UNKNOW_DATA,
+	.id_data	= SENSOR_UNKNOW_DATA,
+	.precision	= ICM4260X_PRECISION,
+	.ctrl_reg	= ICM4260X_PWR_MGMT_0,
+	.int_status_reg = ICM4260X_INT_STATUS,
+	.range		= {-32768, 32768},
+	.trig		= IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+	.active		= sensor_active,
+	.init		= sensor_init,
+	.report		= sensor_report_value,
+};
+
+/****************operate according to sensor chip:end************/
+static int gsensor_icm4260x_probe(struct i2c_client *client,
+				 const struct i2c_device_id *devid)
+{
+	client->addr = ICM42607_ADDR;
+	return sensor_register_device(client, NULL, devid, &gsensor_icm4260x_ops);
+}
+
+static int gsensor_icm4260x_remove(struct i2c_client *client)
+{
+	return sensor_unregister_device(client, NULL, &gsensor_icm4260x_ops);
+}
+
+static const struct i2c_device_id gsensor_icm4260x_id[] = {
+	{"icm42607_acc", ACCEL_ID_ICM4260X},
+	{}
+};
+
+static struct i2c_driver gsensor_icm4260x_driver = {
+	.probe = gsensor_icm4260x_probe,
+	.remove = gsensor_icm4260x_remove,
+	.shutdown = sensor_shutdown,
+	.id_table = gsensor_icm4260x_id,
+	.driver = {
+		.name = "gsensor_icm4260x",
+#ifdef CONFIG_PM
+		.pm = &sensor_pm_ops,
+#endif
+	},
+};
+
+module_i2c_driver(gsensor_icm4260x_driver);
+
+MODULE_AUTHOR("Wangqiang Guo <dave.wang@rock-chips.com>");
+MODULE_DESCRIPTION("icm4260x_acc 3-Axis accelerometer driver");
+MODULE_LICENSE("GPL");
+
diff --git a/kernel/drivers/input/sensors/gyro/Kconfig b/kernel/drivers/input/sensors/gyro/Kconfig
index 5b27389..58b9b6d 100644
--- a/kernel/drivers/input/sensors/gyro/Kconfig
+++ b/kernel/drivers/input/sensors/gyro/Kconfig
@@ -40,6 +40,12 @@
 config GYRO_ICM2060X
 	tristate "gyroscope icm2060x_gyro"
 
+config GYRO_ICM4260X
+	tristate "gyroscope icm4260x_gyro"
+	help
+	  To have support for your specific gyro you will have to
+	  select the proper drivers which depend on this option.
+
 config GYRO_IAM20680
 	tristate "gyroscope iam20680_gyro"
 	default n
diff --git a/kernel/drivers/input/sensors/gyro/Makefile b/kernel/drivers/input/sensors/gyro/Makefile
index 8c0a427..d8c149b 100644
--- a/kernel/drivers/input/sensors/gyro/Makefile
+++ b/kernel/drivers/input/sensors/gyro/Makefile
@@ -9,4 +9,5 @@
 obj-$(CONFIG_GYRO_MPU6880)    += mpu6880_gyro.o
 obj-$(CONFIG_GYRO_LSM330)   += lsm330_gyro.o
 obj-$(CONFIG_GYRO_ICM2060X) += icm2060x_gyro.o
+obj-$(CONFIG_GYRO_ICM4260X) += icm4260x_gyro.o
 obj-$(CONFIG_GYRO_IAM20680) += iam20680_gyro.o
diff --git a/kernel/drivers/input/sensors/gyro/icm4260x_gyro.c b/kernel/drivers/input/sensors/gyro/icm4260x_gyro.c
new file mode 100644
index 0000000..965541a
--- /dev/null
+++ b/kernel/drivers/input/sensors/gyro/icm4260x_gyro.c
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Rockchip Co.,Ltd.
+ * Author: Wangqiang Guo <kay.guo@rock-chips.com>
+ */
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <linux/uaccess.h>
+#include <linux/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+#include <linux/icm4260x.h>
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+	struct sensor_private_data *sensor =
+	    (struct sensor_private_data *) i2c_get_clientdata(client);
+	int result = 0;
+	int status = 0;
+
+	sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+
+	if (!enable) {
+		status = (0xff & ~BIT_GYRO_MODE_MASK);
+		sensor->ops->ctrl_data &= status;
+	} else {
+		status = BIT_GYRO_MODE_LNM;
+		sensor->ops->ctrl_data |= status;
+		sensor->ops->ctrl_data &= ~BIT_IDLE;
+	}
+
+	result = sensor_write_reg(client, sensor->ops->ctrl_reg,
+						sensor->ops->ctrl_data);
+	if (result) {
+		dev_err(&client->dev,
+			"%s: fail to set pwr_mgmt0(%d)\n", __func__, result);
+		return result;
+	}
+	/* Gyroscope needs to be kept ON for a minimum of 45ms */
+	usleep_range(45*1000, 45*1010);
+
+	return result;
+}
+
+static int sensor_init(struct i2c_client *client)
+{
+	int ret = 0;
+	u8 value;
+	struct sensor_private_data *sensor =
+	    (struct sensor_private_data *) i2c_get_clientdata(client);
+
+	/*
+	 * init on icm42607_acc.c
+	 */
+
+	/* set Full scale select for accelerometer UI interface output*/
+	value = sensor_read_reg(client, ICM4260X_GYRO_CONFIG0);
+	value &= ~BIT_GYRO_FSR;
+	value |= GYRO_FS_SEL << SHIFT_GYRO_FS_SEL;
+	ret = sensor_write_reg(client, ICM4260X_GYRO_CONFIG0, value);
+	if (ret)
+		return ret;
+
+	/* turn on accelerometer*/
+	ret = sensor->ops->active(client, 0, sensor->pdata->poll_delay_ms);
+	if (ret) {
+		dev_err(&client->dev,
+			"%s: fail to active sensor(%d)\n", __func__, ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int gyro_report_value(struct i2c_client *client,
+				struct sensor_axis *axis)
+{
+	struct sensor_private_data *sensor =
+	    (struct sensor_private_data *) i2c_get_clientdata(client);
+
+	if (sensor->status_cur == SENSOR_ON) {
+		/* Report acceleration sensor information */
+		input_report_abs(sensor->input_dev, ABS_RX, axis->x);
+		input_report_abs(sensor->input_dev, ABS_RY, axis->y);
+		input_report_abs(sensor->input_dev, ABS_RZ, axis->z);
+		input_sync(sensor->input_dev);
+	}
+
+	return 0;
+}
+
+static int sensor_report_value(struct i2c_client *client)
+{
+	struct sensor_private_data *sensor =
+		(struct sensor_private_data *) i2c_get_clientdata(client);
+	struct sensor_platform_data *pdata = sensor->pdata;
+	int ret = 0;
+	short x, y, z;
+	struct sensor_axis axis;
+	u8 buffer[6] = {0};
+
+	if (sensor->ops->read_len < 6) {
+		dev_err(&client->dev, "%s: length is error, len = %d\n",
+			__func__, sensor->ops->read_len);
+		return -EINVAL;
+	}
+
+	*buffer = sensor->ops->read_reg;
+	ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
+	if (ret < 0) {
+		dev_err(&client->dev,
+			"%s: read data failed, ret = %d\n", __func__, ret);
+		return ret;
+	}
+
+	x = ((buffer[0] << 8) & 0xff00) + (buffer[1] & 0xFF);
+	y = ((buffer[2] << 8) & 0xff00) + (buffer[3] & 0xFF);
+	z = ((buffer[4] << 8) & 0xff00) + (buffer[5] & 0xFF);
+
+	axis.x = (pdata->orientation[0]) * x + (pdata->orientation[1]) * y +
+		 (pdata->orientation[2]) * z;
+	axis.y = (pdata->orientation[3]) * x + (pdata->orientation[4]) * y +
+		 (pdata->orientation[5]) * z;
+	axis.z = (pdata->orientation[6]) * x + (pdata->orientation[7]) * y +
+		 (pdata->orientation[8]) * z;
+
+	gyro_report_value(client, &axis);
+
+	mutex_lock(&(sensor->data_mutex));
+	sensor->axis = axis;
+	mutex_unlock(&(sensor->data_mutex));
+
+	return ret;
+}
+
+static struct sensor_operate gyro_icm4260x_ops = {
+	.name		= "icm4260x_gyro",
+	.type		= SENSOR_TYPE_GYROSCOPE,
+	.id_i2c		= GYRO_ID_ICM4260X,
+	.read_reg	= ICM4260X_GYRO_DATA_X0,
+	.read_len	= 6,
+	.id_reg		= SENSOR_UNKNOW_DATA,
+	.id_data	= SENSOR_UNKNOW_DATA,
+	.precision	= ICM4260X_PRECISION,
+	.ctrl_reg	= ICM4260X_PWR_MGMT_0,
+	.int_status_reg = ICM4260X_INT_STATUS,
+	.range		= {-32768, 32768},
+	.trig		= IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+	.active		= sensor_active,
+	.init		= sensor_init,
+	.report		= sensor_report_value,
+};
+
+/****************operate according to sensor chip:end************/
+static int gyro_icm4260x_probe(struct i2c_client *client,
+				 const struct i2c_device_id *devid)
+{
+	client->addr = ICM42607_ADDR;
+	return sensor_register_device(client, NULL, devid, &gyro_icm4260x_ops);
+}
+
+static int gyro_icm4260x_remove(struct i2c_client *client)
+{
+	return sensor_unregister_device(client, NULL, &gyro_icm4260x_ops);
+}
+
+static const struct i2c_device_id gyro_icm4260x_id[] = {
+	{"icm42607_gyro", GYRO_ID_ICM4260X},
+	{}
+};
+
+static struct i2c_driver gyro_icm4260x_driver = {
+	.probe = gyro_icm4260x_probe,
+	.remove = gyro_icm4260x_remove,
+	.shutdown = sensor_shutdown,
+	.id_table = gyro_icm4260x_id,
+	.driver = {
+		.name = "gyro_icm4260x",
+#ifdef CONFIG_PM
+		.pm = &sensor_pm_ops,
+#endif
+	},
+};
+
+static int __init gyro_icm4260x_init(void)
+{
+	return i2c_add_driver(&gyro_icm4260x_driver);
+}
+
+static void __exit gyro_icm4260x_exit(void)
+{
+	i2c_del_driver(&gyro_icm4260x_driver);
+}
+/* must register after icm4260x_acc */
+device_initcall_sync(gyro_icm4260x_init);
+module_exit(gyro_icm4260x_exit);
+
+MODULE_AUTHOR("Wangqiang Guo <dave.wang@rock-chips.com>");
+MODULE_DESCRIPTION("icm4260x_gyro 3-Axis accelerometer driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/input/serio/i8042-x86ia64io.h b/kernel/drivers/input/serio/i8042-acpipnpio.h
similarity index 68%
rename from kernel/drivers/input/serio/i8042-x86ia64io.h
rename to kernel/drivers/input/serio/i8042-acpipnpio.h
index 148a7c5..1bd5898 100644
--- a/kernel/drivers/input/serio/i8042-x86ia64io.h
+++ b/kernel/drivers/input/serio/i8042-acpipnpio.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
-#ifndef _I8042_X86IA64IO_H
-#define _I8042_X86IA64IO_H
+#ifndef _I8042_ACPIPNPIO_H
+#define _I8042_ACPIPNPIO_H
 
 
 #ifdef CONFIG_X86
@@ -67,25 +67,84 @@
 
 #include <linux/dmi.h>
 
-static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
+#define SERIO_QUIRK_NOKBD		BIT(0)
+#define SERIO_QUIRK_NOAUX		BIT(1)
+#define SERIO_QUIRK_NOMUX		BIT(2)
+#define SERIO_QUIRK_FORCEMUX		BIT(3)
+#define SERIO_QUIRK_UNLOCK		BIT(4)
+#define SERIO_QUIRK_PROBE_DEFER		BIT(5)
+#define SERIO_QUIRK_RESET_ALWAYS	BIT(6)
+#define SERIO_QUIRK_RESET_NEVER		BIT(7)
+#define SERIO_QUIRK_DIECT		BIT(8)
+#define SERIO_QUIRK_DUMBKBD		BIT(9)
+#define SERIO_QUIRK_NOLOOP		BIT(10)
+#define SERIO_QUIRK_NOTIMEOUT		BIT(11)
+#define SERIO_QUIRK_KBDRESET		BIT(12)
+#define SERIO_QUIRK_DRITEK		BIT(13)
+#define SERIO_QUIRK_NOPNP		BIT(14)
+
+/* Quirk table for different mainboards. Options similar or identical to i8042
+ * module parameters.
+ * ORDERING IS IMPORTANT! The first match will be apllied and the rest ignored.
+ * This allows entries to overwrite vendor wide quirks on a per device basis.
+ * Where this is irrelevant, entries are sorted case sensitive by DMI_SYS_VENDOR
+ * and/or DMI_BOARD_VENDOR to make it easier to avoid dublicate entries.
+ */
+static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
 	{
-		/*
-		 * Arima-Rioworks HDAMB -
-		 * AUX LOOP command does not raise AUX IRQ
-		 */
 		.matches = {
-			DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"),
-			DMI_MATCH(DMI_BOARD_NAME, "HDAMB"),
-			DMI_MATCH(DMI_BOARD_VERSION, "Rev E"),
+			DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
 	},
 	{
-		/* ASUS G1S */
 		.matches = {
-			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
-			DMI_MATCH(DMI_BOARD_NAME, "G1S"),
-			DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X750LN"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		/* Asus X450LCP */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_NEVER)
+	},
+	{
+		/* ASUS ZenBook UX425UA */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425UA"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER)
+	},
+	{
+		/* ASUS ZenBook UM325UA */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER)
+	},
+	/*
+	 * On some Asus laptops, just running self tests cause problems.
+	 */
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_NEVER)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_CHASSIS_TYPE, "31"), /* Convertible Notebook */
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_NEVER)
 	},
 	{
 		/* ASUS P65UP5 - AUX LOOP command does not raise AUX IRQ */
@@ -94,362 +153,23 @@
 			DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"),
 			DMI_MATCH(DMI_BOARD_VERSION, "REV 2.X"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
 	},
 	{
+		/* ASUS G1S */
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "X750LN"),
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
+			DMI_MATCH(DMI_BOARD_NAME, "G1S"),
+			DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
 		},
-	},
-	{
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
-			DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "8500"),
-		},
-	},
-	{
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
-			DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
-		},
-	},
-	{
-		/* Dell Embedded Box PC 3000 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000"),
-		},
-	},
-	{
-		/* OQO Model 01 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "00"),
-		},
-	},
-	{
-		/* ULI EV4873 - AUX LOOP does not work properly */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "ULI"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
-		},
-	},
-	{
-		/* Microsoft Virtual Machine */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
-		},
-	},
-	{
-		/* Medion MAM 2070 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
-		},
-	},
-	{
-		/* Medion Akoya E7225 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Medion"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Akoya E7225"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"),
-		},
-	},
-	{
-		/* Blue FB5601 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "blue"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "M606"),
-		},
-	},
-	{
-		/* Gigabyte M912 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "M912"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "01"),
-		},
-	},
-	{
-		/* Gigabyte M1022M netbook */
-		.matches = {
-			DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."),
-			DMI_MATCH(DMI_BOARD_NAME, "M1022E"),
-			DMI_MATCH(DMI_BOARD_VERSION, "1.02"),
-		},
-	},
-	{
-		/* Gigabyte Spring Peak - defines wrong chassis type */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"),
-		},
-	},
-	{
-		/* Gigabyte T1005 - defines wrong chassis type ("Other") */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "T1005"),
-		},
-	},
-	{
-		/* Gigabyte T1005M/P - defines wrong chassis type ("Other") */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"),
-		},
-	},
-	{
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"),
-		},
-	},
-	{
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "C15B"),
-		},
-	},
-	{
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "ByteSpeed LLC"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "ByteSpeed Laptop C15B"),
-		},
-	},
-	{ }
-};
-
-/*
- * Some Fujitsu notebooks are having trouble with touchpads if
- * active multiplexing mode is activated. Luckily they don't have
- * external PS/2 ports so we can safely disable it.
- * ... apparently some Toshibas don't like MUX mode either and
- * die horrible death on reboot.
- */
-static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
-	{
-		/* Fujitsu Lifebook P7010/P7010D */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "P7010"),
-		},
-	},
-	{
-		/* Fujitsu Lifebook P7010 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"),
-		},
-	},
-	{
-		/* Fujitsu Lifebook P5020D */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"),
-		},
-	},
-	{
-		/* Fujitsu Lifebook S2000 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"),
-		},
-	},
-	{
-		/* Fujitsu Lifebook S6230 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"),
-		},
-	},
-	{
-		/* Fujitsu Lifebook T725 laptop */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T725"),
-		},
-	},
-	{
-		/* Fujitsu Lifebook U745 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"),
-		},
-	},
-	{
-		/* Fujitsu T70H */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"),
-		},
-	},
-	{
-		/* Fujitsu-Siemens Lifebook T3010 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"),
-		},
-	},
-	{
-		/* Fujitsu-Siemens Lifebook E4010 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"),
-		},
-	},
-	{
-		/* Fujitsu-Siemens Amilo Pro 2010 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"),
-		},
-	},
-	{
-		/* Fujitsu-Siemens Amilo Pro 2030 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"),
-		},
-	},
-	{
-		/*
-		 * No data is coming from the touchscreen unless KBC
-		 * is in legacy mode.
-		 */
-		/* Panasonic CF-29 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"),
-		},
-	},
-	{
-		/*
-		 * HP Pavilion DV4017EA -
-		 * errors on MUX ports are reported without raising AUXDATA
-		 * causing "spurious NAK" messages.
-		 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"),
-		},
-	},
-	{
-		/*
-		 * HP Pavilion ZT1000 -
-		 * like DV4017EA does not raise AUXERR for errors on MUX ports.
-		 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"),
-		},
-	},
-	{
-		/*
-		 * HP Pavilion DV4270ca -
-		 * like DV4017EA does not raise AUXERR for errors on MUX ports.
-		 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"),
-		},
-	},
-	{
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"),
-		},
-	},
-	{
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
-		},
-	},
-	{
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"),
-		},
-	},
-	{
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"),
-		},
-	},
-	{
-		/* Sharp Actius MM20 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"),
-		},
-	},
-	{
-		/* Sony Vaio FS-115b */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"),
-		},
-	},
-	{
-		/*
-		 * Sony Vaio FZ-240E -
-		 * reset and GET ID commands issued via KBD port are
-		 * sometimes being delivered to AUX3.
-		 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
-		},
-	},
-	{
-		/*
-		 * Most (all?) VAIOs do not have external PS/2 ports nor
-		 * they implement active multiplexing properly, and
-		 * MUX discovery usually messes up keyboard/touchpad.
-		 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-			DMI_MATCH(DMI_BOARD_NAME, "VAIO"),
-		},
-	},
-	{
-		/* Amoi M636/A737 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
-		},
-	},
-	{
-		/* Lenovo 3000 n100 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "076804U"),
-		},
-	},
-	{
-		/* Lenovo XiaoXin Air 12 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "80UN"),
-		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
 	},
 	{
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
 	},
 	{
 		/* Acer Aspire 5710 */
@@ -457,6 +177,7 @@
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
 	},
 	{
 		/* Acer Aspire 7738 */
@@ -464,41 +185,7 @@
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738"),
 		},
-	},
-	{
-		/* Gericom Bellagio */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
-		},
-	},
-	{
-		/* IBM 2656 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "2656"),
-		},
-	},
-	{
-		/* Dell XPS M1530 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"),
-		},
-	},
-	{
-		/* Compal HEL80I */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
-		},
-	},
-	{
-		/* Dell Vostro 1510 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
-		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
 	},
 	{
 		/* Acer Aspire 5536 */
@@ -507,48 +194,7 @@
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"),
 			DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
 		},
-	},
-	{
-		/* Dell Vostro V13 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
-		},
-	},
-	{
-		/* Newer HP Pavilion dv4 models */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
-		},
-	},
-	{
-		/* Asus X450LCP */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"),
-		},
-	},
-	{
-		/* Avatar AVIU-145A6 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Intel"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"),
-		},
-	},
-	{
-		/* TUXEDO BU1406 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"),
-		},
-	},
-	{
-		/* Lenovo LaVie Z */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo LaVie Z"),
-		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
 	},
 	{
 		/*
@@ -560,6 +206,253 @@
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Acer Aspire One 150 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A114-31"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A314-31"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A315-31"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-132"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-332"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-432"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate Spin B118-RN"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	/*
+	 * Some Wistron based laptops need us to explicitly enable the 'Dritek
+	 * keyboard extension' to make their extra keys start generating scancodes.
+	 * Originally, this was just confined to older laptops, but a few Acer laptops
+	 * have turned up in 2007 that also need this again.
+	 */
+	{
+		/* Acer Aspire 5100 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_DRITEK)
+	},
+	{
+		/* Acer Aspire 5610 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_DRITEK)
+	},
+	{
+		/* Acer Aspire 5630 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_DRITEK)
+	},
+	{
+		/* Acer Aspire 5650 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_DRITEK)
+	},
+	{
+		/* Acer Aspire 5680 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_DRITEK)
+	},
+	{
+		/* Acer Aspire 5720 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_DRITEK)
+	},
+	{
+		/* Acer Aspire 9110 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_DRITEK)
+	},
+	{
+		/* Acer TravelMate 660 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_DRITEK)
+	},
+	{
+		/* Acer TravelMate 2490 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_DRITEK)
+	},
+	{
+		/* Acer TravelMate 4280 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_DRITEK)
+	},
+	{
+		/* Amoi M636/A737 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ByteSpeed LLC"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ByteSpeed Laptop C15B"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		/* Compal HEL80I */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "8500"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		/* Advent 4211 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		/* Dell Embedded Box PC 3000 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		/* Dell XPS M1530 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Dell Vostro 1510 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Dell Vostro V13 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT)
+	},
+	{
+		/* Dell Vostro 1320 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		/* Dell Vostro 1520 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		/* Dell Vostro 1720 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
 	},
 	{
 		/* Entroware Proteus */
@@ -568,11 +461,546 @@
 			DMI_MATCH(DMI_PRODUCT_NAME, "Proteus"),
 			DMI_MATCH(DMI_PRODUCT_VERSION, "EL07R4"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS)
 	},
-	{ }
-};
-
-static const struct dmi_system_id i8042_dmi_forcemux_table[] __initconst = {
+	/*
+	 * Some Fujitsu notebooks are having trouble with touchpads if
+	 * active multiplexing mode is activated. Luckily they don't have
+	 * external PS/2 ports so we can safely disable it.
+	 * ... apparently some Toshibas don't like MUX mode either and
+	 * die horrible death on reboot.
+	 */
+	{
+		/* Fujitsu Lifebook P7010/P7010D */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "P7010"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Fujitsu Lifebook P5020D */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Fujitsu Lifebook S2000 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Fujitsu Lifebook S6230 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Fujitsu Lifebook T725 laptop */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T725"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT)
+	},
+	{
+		/* Fujitsu Lifebook U745 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Fujitsu T70H */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Fujitsu A544 laptop */
+		/* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT)
+	},
+	{
+		/* Fujitsu AH544 laptop */
+		/* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT)
+	},
+	{
+		/* Fujitsu U574 laptop */
+		/* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT)
+	},
+	{
+		/* Fujitsu UH554 laptop */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT)
+	},
+	{
+		/* Fujitsu Lifebook P7010 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Fujitsu-Siemens Lifebook T3010 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Fujitsu-Siemens Lifebook E4010 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Fujitsu-Siemens Amilo Pro 2010 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Fujitsu-Siemens Amilo Pro 2030 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Fujitsu Lifebook A574/H */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "FMVA0501PZ"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Gigabyte M912 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "M912"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "01"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		/* Gigabyte Spring Peak - defines wrong chassis type */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		/* Gigabyte T1005 - defines wrong chassis type ("Other") */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "T1005"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		/* Gigabyte T1005M/P - defines wrong chassis type ("Other") */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	/*
+	 * Some laptops need keyboard reset before probing for the trackpad to get
+	 * it detected, initialised & finally work.
+	 */
+	{
+		/* Gigabyte P35 v2 - Elantech touchpad */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_KBDRESET)
+	},
+		{
+		/* Aorus branded Gigabyte X3 Plus - Elantech touchpad */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X3"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_KBDRESET)
+	},
+	{
+		/* Gigabyte P34 - Elantech touchpad */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "P34"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_KBDRESET)
+	},
+	{
+		/* Gigabyte P57 - Elantech touchpad */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "P57"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_KBDRESET)
+	},
+	{
+		/* Gericom Bellagio */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Gigabyte M1022M netbook */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."),
+			DMI_MATCH(DMI_BOARD_NAME, "M1022E"),
+			DMI_MATCH(DMI_BOARD_VERSION, "1.02"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		/*
+		 * HP Pavilion DV4017EA -
+		 * errors on MUX ports are reported without raising AUXDATA
+		 * causing "spurious NAK" messages.
+		 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/*
+		 * HP Pavilion ZT1000 -
+		 * like DV4017EA does not raise AUXERR for errors on MUX ports.
+		 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/*
+		 * HP Pavilion DV4270ca -
+		 * like DV4017EA does not raise AUXERR for errors on MUX ports.
+		 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Newer HP Pavilion dv4 models */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT)
+	},
+	{
+		/* IBM 2656 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2656"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Avatar AVIU-145A6 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Intel"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Intel MBO Desktop D845PESV */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+			DMI_MATCH(DMI_BOARD_NAME, "D845PESV"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOPNP)
+	},
+	{
+		/*
+		 * Intel NUC D54250WYK - does not have i8042 controller but
+		 * declares PS/2 devices in DSDT.
+		 */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+			DMI_MATCH(DMI_BOARD_NAME, "D54250WYK"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOPNP)
+	},
+	{
+		/* Lenovo 3000 n100 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "076804U"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Lenovo XiaoXin Air 12 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "80UN"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Lenovo LaVie Z */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo LaVie Z"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Lenovo Ideapad U455 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "20046"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		/* Lenovo ThinkPad L460 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		/* Lenovo ThinkPad Twist S230u */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "33474HU"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		/* LG Electronics X110 */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
+			DMI_MATCH(DMI_BOARD_NAME, "X110"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		/* Medion Akoya Mini E1210 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "E1210"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		/* Medion Akoya E1222 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "E122X"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		/* MSI Wind U-100 */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+			DMI_MATCH(DMI_BOARD_NAME, "U-100"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOPNP)
+	},
+	{
+		/*
+		 * No data is coming from the touchscreen unless KBC
+		 * is in legacy mode.
+		 */
+		/* Panasonic CF-29 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Medion Akoya E7225 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Medion"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Akoya E7225"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		/* Microsoft Virtual Machine */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		/* Medion MAM 2070 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		/* TUXEDO BU1406 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Clevo P650RS, 650RP6, Sager NP8152-S, and others */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		/* OQO Model 01 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "00"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "C15B"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		/* Acer Aspire 5 A515 */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "PK"),
+			DMI_MATCH(DMI_BOARD_NAME, "Grumpy_PK"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOPNP)
+	},
+	{
+		/* ULI EV4873 - AUX LOOP does not work properly */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ULI"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		/*
+		 * Arima-Rioworks HDAMB -
+		 * AUX LOOP command does not raise AUX IRQ
+		 */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"),
+			DMI_MATCH(DMI_BOARD_NAME, "HDAMB"),
+			DMI_MATCH(DMI_BOARD_VERSION, "Rev E"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	{
+		/* Sharp Actius MM20 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/*
+		 * Sony Vaio FZ-240E -
+		 * reset and GET ID commands issued via KBD port are
+		 * sometimes being delivered to AUX3.
+		 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/*
+		 * Most (all?) VAIOs do not have external PS/2 ports nor
+		 * they implement active multiplexing properly, and
+		 * MUX discovery usually messes up keyboard/touchpad.
+		 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+			DMI_MATCH(DMI_BOARD_NAME, "VAIO"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
+		/* Sony Vaio FS-115b */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
 	{
 		/*
 		 * Sony Vaio VGN-CS series require MUX or the touch sensor
@@ -582,111 +1010,51 @@
 			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-CS"),
 		},
-	},
-	{ }
-};
-
-/*
- * On some Asus laptops, just running self tests cause problems.
- */
-static const struct dmi_system_id i8042_dmi_noselftest_table[] = {
-	{
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-			DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
-		},
-	}, {
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-			DMI_MATCH(DMI_CHASSIS_TYPE, "31"), /* Convertible Notebook */
-		},
-	},
-	{ }
-};
-static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
-	{
-		/* MSI Wind U-100 */
-		.matches = {
-			DMI_MATCH(DMI_BOARD_NAME, "U-100"),
-			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
-		},
-	},
-	{
-		/* LG Electronics X110 */
-		.matches = {
-			DMI_MATCH(DMI_BOARD_NAME, "X110"),
-			DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
-		},
-	},
-	{
-		/* Acer Aspire One 150 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
-		},
+		.driver_data = (void *)(SERIO_QUIRK_FORCEMUX)
 	},
 	{
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A114-31"),
+			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
 	},
 	{
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A314-31"),
+			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
 	},
 	{
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A315-31"),
+			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	/*
+	 * A lot of modern Clevo barebones have touchpad and/or keyboard issues
+	 * after suspend fixable with nomux + reset + noloop + nopnp. Luckily,
+	 * none of them have an external PS/2 port so this can safely be set for
+	 * all of them. These two are based on a Clevo design, but have the
+	 * board_name changed.
+	 */
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "TUXEDO"),
+			DMI_MATCH(DMI_BOARD_NAME, "AURA1501"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
 	},
 	{
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-132"),
+			DMI_MATCH(DMI_BOARD_VENDOR, "TUXEDO"),
+			DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"),
 		},
-	},
-	{
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-332"),
-		},
-	},
-	{
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-432"),
-		},
-	},
-	{
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate Spin B118-RN"),
-		},
-	},
-	{
-		/* Advent 4211 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"),
-		},
-	},
-	{
-		/* Medion Akoya Mini E1210 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "E1210"),
-		},
-	},
-	{
-		/* Medion Akoya E1222 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "E122X"),
-		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
 	},
 	{
 		/* Mivvy M310 */
@@ -694,104 +1062,154 @@
 			DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	/*
+	 * Some laptops need keyboard reset before probing for the trackpad to get
+	 * it detected, initialised & finally work.
+	 */
+	{
+		/* Schenker XMG C504 - Elantech touchpad */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "XMG"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "C504"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_KBDRESET)
 	},
 	{
-		/* Dell Vostro 1320 */
+		/* Blue FB5601 */
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"),
+			DMI_MATCH(DMI_SYS_VENDOR, "blue"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "M606"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+	},
+	/*
+	 * A lot of modern Clevo barebones have touchpad and/or keyboard issues
+	 * after suspend fixable with nomux + reset + noloop + nopnp. Luckily,
+	 * none of them have an external PS/2 port so this can safely be set for
+	 * all of them.
+	 * Clevo barebones come with board_vendor and/or system_vendor set to
+	 * either the very generic string "Notebook" and/or a different value
+	 * for each individual reseller. The only somewhat universal way to
+	 * identify them is by board_name.
+	 */
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "LAPQC71A"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
 	},
 	{
-		/* Dell Vostro 1520 */
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"),
+			DMI_MATCH(DMI_BOARD_NAME, "LAPQC71B"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
 	},
 	{
-		/* Dell Vostro 1720 */
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
+			DMI_MATCH(DMI_BOARD_NAME, "N140CU"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
 	},
 	{
-		/* Lenovo Ideapad U455 */
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "20046"),
+			DMI_MATCH(DMI_BOARD_NAME, "N141CU"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
 	},
 	{
-		/* Lenovo ThinkPad L460 */
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460"),
+			DMI_MATCH(DMI_BOARD_NAME, "NH5xAx"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
 	},
 	{
-		/* Clevo P650RS, 650RP6, Sager NP8152-S, and others */
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"),
+			DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+	},
+	/*
+	 * At least one modern Clevo barebone has the touchpad connected both
+	 * via PS/2 and i2c interface. This causes a race condition between the
+	 * psmouse and i2c-hid driver. Since the full capability of the touchpad
+	 * is available via the i2c interface and the device has no external
+	 * PS/2 port, it is safe to just ignore all ps2 mouses here to avoid
+	 * this issue. The known affected device is the
+	 * TUXEDO InfinityBook S17 Gen6 / Clevo NS70MU which comes with one of
+	 * the two different dmi strings below. NS50MU is not a typo!
+	 */
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "NS50MU"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOAUX | SERIO_QUIRK_NOMUX |
+					SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP |
+					SERIO_QUIRK_NOPNP)
 	},
 	{
-		/* Lenovo ThinkPad Twist S230u */
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "33474HU"),
+			DMI_MATCH(DMI_BOARD_NAME, "NS50_70MU"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOAUX | SERIO_QUIRK_NOMUX |
+					SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP |
+					SERIO_QUIRK_NOPNP)
 	},
 	{
-		/* Entroware Proteus */
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Entroware"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Proteus"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "EL07R4"),
+			DMI_MATCH(DMI_BOARD_NAME, "NJ50_70CU"),
 		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "PB50_70DFx,DDx"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "PCX0DX"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+	},
+	/* See comment on TUXEDO InfinityBook S17 Gen6 / Clevo NS70MU above */
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "PD5x_7xPNP_PNR_PNN_PNT"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOAUX)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "X170SM"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "X170KM-G"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
 	},
 	{ }
 };
 
 #ifdef CONFIG_PNP
-static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = {
-	{
-		/* Intel MBO Desktop D845PESV */
-		.matches = {
-			DMI_MATCH(DMI_BOARD_NAME, "D845PESV"),
-			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
-		},
-	},
-	{
-		/*
-		 * Intel NUC D54250WYK - does not have i8042 controller but
-		 * declares PS/2 devices in DSDT.
-		 */
-		.matches = {
-			DMI_MATCH(DMI_BOARD_NAME, "D54250WYK"),
-			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
-		},
-	},
-	{
-		/* MSI Wind U-100 */
-		.matches = {
-			DMI_MATCH(DMI_BOARD_NAME, "U-100"),
-			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
-		},
-	},
-	{
-		/* Acer Aspire 5 A515 */
-		.matches = {
-			DMI_MATCH(DMI_BOARD_NAME, "Grumpy_PK"),
-			DMI_MATCH(DMI_BOARD_VENDOR, "PK"),
-		},
-	},
-	{ }
-};
-
-static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = {
+static const struct dmi_system_id i8042_dmi_laptop_table[] __initconst = {
 	{
 		.matches = {
 			DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
@@ -815,203 +1233,6 @@
 	{ }
 };
 #endif
-
-static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = {
-	{
-		/* Dell Vostro V13 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
-		},
-	},
-	{
-		/* Newer HP Pavilion dv4 models */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
-		},
-	},
-	{
-		/* Fujitsu A544 laptop */
-		/* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544"),
-		},
-	},
-	{
-		/* Fujitsu AH544 laptop */
-		/* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544"),
-		},
-	},
-	{
-		/* Fujitsu Lifebook T725 laptop */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T725"),
-		},
-	},
-	{
-		/* Fujitsu U574 laptop */
-		/* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"),
-		},
-	},
-	{
-		/* Fujitsu UH554 laptop */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544"),
-		},
-	},
-	{ }
-};
-
-/*
- * Some Wistron based laptops need us to explicitly enable the 'Dritek
- * keyboard extension' to make their extra keys start generating scancodes.
- * Originally, this was just confined to older laptops, but a few Acer laptops
- * have turned up in 2007 that also need this again.
- */
-static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = {
-	{
-		/* Acer Aspire 5100 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
-		},
-	},
-	{
-		/* Acer Aspire 5610 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
-		},
-	},
-	{
-		/* Acer Aspire 5630 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"),
-		},
-	},
-	{
-		/* Acer Aspire 5650 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"),
-		},
-	},
-	{
-		/* Acer Aspire 5680 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
-		},
-	},
-	{
-		/* Acer Aspire 5720 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
-		},
-	},
-	{
-		/* Acer Aspire 9110 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"),
-		},
-	},
-	{
-		/* Acer TravelMate 660 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
-		},
-	},
-	{
-		/* Acer TravelMate 2490 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
-		},
-	},
-	{
-		/* Acer TravelMate 4280 */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
-		},
-	},
-	{ }
-};
-
-/*
- * Some laptops need keyboard reset before probing for the trackpad to get
- * it detected, initialised & finally work.
- */
-static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = {
-	{
-		/* Gigabyte P35 v2 - Elantech touchpad */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"),
-		},
-	},
-		{
-		/* Aorus branded Gigabyte X3 Plus - Elantech touchpad */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "X3"),
-		},
-	},
-	{
-		/* Gigabyte P34 - Elantech touchpad */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "P34"),
-		},
-	},
-	{
-		/* Gigabyte P57 - Elantech touchpad */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "P57"),
-		},
-	},
-	{
-		/* Schenker XMG C504 - Elantech touchpad */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "XMG"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "C504"),
-		},
-	},
-	{ }
-};
-
-static const struct dmi_system_id i8042_dmi_probe_defer_table[] __initconst = {
-	{
-		/* ASUS ZenBook UX425UA */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425UA"),
-		},
-	},
-	{
-		/* ASUS ZenBook UM325UA */
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"),
-		},
-	},
-	{ }
-};
 
 #endif /* CONFIG_X86 */
 
@@ -1167,11 +1388,6 @@
 	bool pnp_data_busted = false;
 	int err;
 
-#ifdef CONFIG_X86
-	if (dmi_check_system(i8042_dmi_nopnp_table))
-		i8042_nopnp = true;
-#endif
-
 	if (i8042_nopnp) {
 		pr_info("PNP detection disabled\n");
 		return 0;
@@ -1275,6 +1491,59 @@
 static inline void i8042_pnp_exit(void) { }
 #endif /* CONFIG_PNP */
 
+
+#ifdef CONFIG_X86
+static void __init i8042_check_quirks(void)
+{
+	const struct dmi_system_id *device_quirk_info;
+	uintptr_t quirks;
+
+	device_quirk_info = dmi_first_match(i8042_dmi_quirk_table);
+	if (!device_quirk_info)
+		return;
+
+	quirks = (uintptr_t)device_quirk_info->driver_data;
+
+	if (quirks & SERIO_QUIRK_NOKBD)
+		i8042_nokbd = true;
+	if (quirks & SERIO_QUIRK_NOAUX)
+		i8042_noaux = true;
+	if (quirks & SERIO_QUIRK_NOMUX)
+		i8042_nomux = true;
+	if (quirks & SERIO_QUIRK_FORCEMUX)
+		i8042_nomux = false;
+	if (quirks & SERIO_QUIRK_UNLOCK)
+		i8042_unlock = true;
+	if (quirks & SERIO_QUIRK_PROBE_DEFER)
+		i8042_probe_defer = true;
+	/* Honor module parameter when value is not default */
+	if (i8042_reset == I8042_RESET_DEFAULT) {
+		if (quirks & SERIO_QUIRK_RESET_ALWAYS)
+			i8042_reset = I8042_RESET_ALWAYS;
+		if (quirks & SERIO_QUIRK_RESET_NEVER)
+			i8042_reset = I8042_RESET_NEVER;
+	}
+	if (quirks & SERIO_QUIRK_DIECT)
+		i8042_direct = true;
+	if (quirks & SERIO_QUIRK_DUMBKBD)
+		i8042_dumbkbd = true;
+	if (quirks & SERIO_QUIRK_NOLOOP)
+		i8042_noloop = true;
+	if (quirks & SERIO_QUIRK_NOTIMEOUT)
+		i8042_notimeout = true;
+	if (quirks & SERIO_QUIRK_KBDRESET)
+		i8042_kbdreset = true;
+	if (quirks & SERIO_QUIRK_DRITEK)
+		i8042_dritek = true;
+#ifdef CONFIG_PNP
+	if (quirks & SERIO_QUIRK_NOPNP)
+		i8042_nopnp = true;
+#endif
+}
+#else
+static inline void i8042_check_quirks(void) {}
+#endif
+
 static int __init i8042_platform_init(void)
 {
 	int retval;
@@ -1297,45 +1566,17 @@
 	i8042_kbd_irq = I8042_MAP_IRQ(1);
 	i8042_aux_irq = I8042_MAP_IRQ(12);
 
+#if defined(__ia64__)
+	i8042_reset = I8042_RESET_ALWAYS;
+#endif
+
+	i8042_check_quirks();
+
 	retval = i8042_pnp_init();
 	if (retval)
 		return retval;
 
-#if defined(__ia64__)
-        i8042_reset = I8042_RESET_ALWAYS;
-#endif
-
 #ifdef CONFIG_X86
-	/* Honor module parameter when value is not default */
-	if (i8042_reset == I8042_RESET_DEFAULT) {
-		if (dmi_check_system(i8042_dmi_reset_table))
-			i8042_reset = I8042_RESET_ALWAYS;
-
-		if (dmi_check_system(i8042_dmi_noselftest_table))
-			i8042_reset = I8042_RESET_NEVER;
-	}
-
-	if (dmi_check_system(i8042_dmi_noloop_table))
-		i8042_noloop = true;
-
-	if (dmi_check_system(i8042_dmi_nomux_table))
-		i8042_nomux = true;
-
-	if (dmi_check_system(i8042_dmi_forcemux_table))
-		i8042_nomux = false;
-
-	if (dmi_check_system(i8042_dmi_notimeout_table))
-		i8042_notimeout = true;
-
-	if (dmi_check_system(i8042_dmi_dritek_table))
-		i8042_dritek = true;
-
-	if (dmi_check_system(i8042_dmi_kbdreset_table))
-		i8042_kbdreset = true;
-
-	if (dmi_check_system(i8042_dmi_probe_defer_table))
-		i8042_probe_defer = true;
-
 	/*
 	 * A20 was already enabled during early kernel init. But some buggy
 	 * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to
@@ -1353,4 +1594,4 @@
 	i8042_pnp_exit();
 }
 
-#endif /* _I8042_X86IA64IO_H */
+#endif /* _I8042_ACPIPNPIO_H */
diff --git a/kernel/drivers/input/serio/i8042.h b/kernel/drivers/input/serio/i8042.h
index 5538178..bf2592f 100644
--- a/kernel/drivers/input/serio/i8042.h
+++ b/kernel/drivers/input/serio/i8042.h
@@ -20,7 +20,7 @@
 #elif defined(CONFIG_SPARC)
 #include "i8042-sparcio.h"
 #elif defined(CONFIG_X86) || defined(CONFIG_IA64)
-#include "i8042-x86ia64io.h"
+#include "i8042-acpipnpio.h"
 #else
 #include "i8042-io.h"
 #endif
diff --git a/kernel/drivers/input/touchscreen/Kconfig b/kernel/drivers/input/touchscreen/Kconfig
index 0efc7e7..fa0010e 100644
--- a/kernel/drivers/input/touchscreen/Kconfig
+++ b/kernel/drivers/input/touchscreen/Kconfig
@@ -430,6 +430,15 @@
 config TOUCHSCREEN_GT1X
 	tristate "GT1X touchscreens support"
 
+config TOUCHSCREEN_GT9XX
+	tristate "Goodix gt9xx support for rockchip platform"
+	depends on I2C && ARCH_ROCKCHIP
+	help
+	  Say Y here if you have a touchscreen interface using the gt9xx
+	  on Rockchip platform, and your board-specific initialization
+	  code includes that in its table of IIC devices.
+	  If unsure, say N.
+
 config TOUCHSCREEN_HIDEEP
 	tristate "HiDeep Touch IC"
 	depends on I2C
diff --git a/kernel/drivers/input/touchscreen/Makefile b/kernel/drivers/input/touchscreen/Makefile
index 0b1975b..21582b5 100644
--- a/kernel/drivers/input/touchscreen/Makefile
+++ b/kernel/drivers/input/touchscreen/Makefile
@@ -54,6 +54,7 @@
 obj-$(CONFIG_TOUCHSCREEN_GSLX680_PAD)	+= gslx680-pad.o
 gslx680-pad-y := gslx680_pad.o gsl_point_id.o
 obj-$(CONFIG_TOUCHSCREEN_GT1X)		+= gt1x/
+obj-$(CONFIG_TOUCHSCREEN_GT9XX)		+= gt9xx/
 obj-$(CONFIG_TOUCHSCREEN_HIDEEP)	+= hideep.o
 obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
 obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC)	+= imx6ul_tsc.o
diff --git a/kernel/drivers/input/touchscreen/ads7846.c b/kernel/drivers/input/touchscreen/ads7846.c
index ff97897..1753288 100644
--- a/kernel/drivers/input/touchscreen/ads7846.c
+++ b/kernel/drivers/input/touchscreen/ads7846.c
@@ -63,19 +63,15 @@
 /* this driver doesn't aim at the peak continuous sample rate */
 #define	SAMPLE_BITS	(8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */)
 
-struct ts_event {
-	/*
-	 * For portability, we can't read 12 bit values using SPI (which
-	 * would make the controller deliver them as native byte order u16
-	 * with msbs zeroed).  Instead, we read them as two 8-bit values,
-	 * *** WHICH NEED BYTESWAPPING *** and range adjustment.
-	 */
-	u16	x;
-	u16	y;
-	u16	z1, z2;
-	bool	ignore;
-	u8	x_buf[3];
-	u8	y_buf[3];
+struct ads7846_buf {
+	u8 cmd;
+	__be16 data;
+} __packed;
+
+struct ads7846_buf_layout {
+	unsigned int offset;
+	unsigned int count;
+	unsigned int skip;
 };
 
 /*
@@ -84,11 +80,18 @@
  * systems where main memory is not DMA-coherent (most non-x86 boards).
  */
 struct ads7846_packet {
-	u8			read_x, read_y, read_z1, read_z2, pwrdown;
-	u16			dummy;		/* for the pwrdown read */
-	struct ts_event		tc;
-	/* for ads7845 with mpc5121 psc spi we use 3-byte buffers */
-	u8			read_x_cmd[3], read_y_cmd[3], pwrdown_cmd[3];
+	unsigned int count;
+	unsigned int count_skip;
+	unsigned int cmds;
+	unsigned int last_cmd_idx;
+	struct ads7846_buf_layout l[5];
+	struct ads7846_buf *rx;
+	struct ads7846_buf *tx;
+
+	struct ads7846_buf pwrdown_cmd;
+
+	bool ignore;
+	u16 x, y, z1, z2;
 };
 
 struct ads7846 {
@@ -187,7 +190,6 @@
 #define	READ_Y(vref)	(READ_12BIT_DFR(y,  1, vref))
 #define	READ_Z1(vref)	(READ_12BIT_DFR(z1, 1, vref))
 #define	READ_Z2(vref)	(READ_12BIT_DFR(z2, 1, vref))
-
 #define	READ_X(vref)	(READ_12BIT_DFR(x,  1, vref))
 #define	PWRDOWN		(READ_12BIT_DFR(y,  0, 0))	/* LAST */
 
@@ -199,6 +201,21 @@
 
 #define	REF_ON	(READ_12BIT_DFR(x, 1, 1))
 #define	REF_OFF	(READ_12BIT_DFR(y, 0, 0))
+
+/* Order commands in the most optimal way to reduce Vref switching and
+ * settling time:
+ * Measure:  X; Vref: X+, X-; IN: Y+
+ * Measure:  Y; Vref: Y+, Y-; IN: X+
+ * Measure: Z1; Vref: Y+, X-; IN: X+
+ * Measure: Z2; Vref: Y+, X-; IN: Y-
+ */
+enum ads7846_cmds {
+	ADS7846_X,
+	ADS7846_Y,
+	ADS7846_Z1,
+	ADS7846_Z2,
+	ADS7846_PWDOWN,
+};
 
 static int get_pendown_state(struct ads7846 *ts)
 {
@@ -682,32 +699,109 @@
 	return ADS7846_FILTER_OK;
 }
 
-static int ads7846_get_value(struct ads7846 *ts, struct spi_message *m)
+static int ads7846_get_value(struct ads7846_buf *buf)
 {
 	int value;
-	struct spi_transfer *t =
-		list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
 
-	if (ts->model == 7845) {
-		value = be16_to_cpup((__be16 *)&(((char *)t->rx_buf)[1]));
-	} else {
-		/*
-		 * adjust:  on-wire is a must-ignore bit, a BE12 value, then
-		 * padding; built from two 8 bit values written msb-first.
-		 */
-		value = be16_to_cpup((__be16 *)t->rx_buf);
-	}
+	value = be16_to_cpup(&buf->data);
 
 	/* enforce ADC output is 12 bits width */
 	return (value >> 3) & 0xfff;
 }
 
-static void ads7846_update_value(struct spi_message *m, int val)
+static void ads7846_set_cmd_val(struct ads7846 *ts, enum ads7846_cmds cmd_idx,
+				u16 val)
 {
-	struct spi_transfer *t =
-		list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
+	struct ads7846_packet *packet = ts->packet;
 
-	*(u16 *)t->rx_buf = val;
+	switch (cmd_idx) {
+	case ADS7846_Y:
+		packet->y = val;
+		break;
+	case ADS7846_X:
+		packet->x = val;
+		break;
+	case ADS7846_Z1:
+		packet->z1 = val;
+		break;
+	case ADS7846_Z2:
+		packet->z2 = val;
+		break;
+	default:
+		WARN_ON_ONCE(1);
+	}
+}
+
+static u8 ads7846_get_cmd(enum ads7846_cmds cmd_idx, int vref)
+{
+	switch (cmd_idx) {
+	case ADS7846_Y:
+		return READ_Y(vref);
+	case ADS7846_X:
+		return READ_X(vref);
+
+	/* 7846 specific commands  */
+	case ADS7846_Z1:
+		return READ_Z1(vref);
+	case ADS7846_Z2:
+		return READ_Z2(vref);
+	case ADS7846_PWDOWN:
+		return PWRDOWN;
+	default:
+		WARN_ON_ONCE(1);
+	}
+
+	return 0;
+}
+
+static bool ads7846_cmd_need_settle(enum ads7846_cmds cmd_idx)
+{
+	switch (cmd_idx) {
+	case ADS7846_X:
+	case ADS7846_Y:
+	case ADS7846_Z1:
+	case ADS7846_Z2:
+		return true;
+	case ADS7846_PWDOWN:
+		return false;
+	default:
+		WARN_ON_ONCE(1);
+	}
+
+	return false;
+}
+
+static int ads7846_filter(struct ads7846 *ts)
+{
+	struct ads7846_packet *packet = ts->packet;
+	int action;
+	int val;
+	unsigned int cmd_idx, b;
+
+	packet->ignore = false;
+	for (cmd_idx = packet->last_cmd_idx; cmd_idx < packet->cmds - 1; cmd_idx++) {
+		struct ads7846_buf_layout *l = &packet->l[cmd_idx];
+
+		packet->last_cmd_idx = cmd_idx;
+
+		for (b = l->skip; b < l->count; b++) {
+			val = ads7846_get_value(&packet->rx[l->offset + b]);
+
+			action = ts->filter(ts->filter_data, cmd_idx, &val);
+			if (action == ADS7846_FILTER_REPEAT) {
+				if (b == l->count - 1)
+					return -EAGAIN;
+			} else if (action == ADS7846_FILTER_OK) {
+				ads7846_set_cmd_val(ts, cmd_idx, val);
+				break;
+			} else {
+				packet->ignore = true;
+				return 0;
+			}
+		}
+	}
+
+	return 0;
 }
 
 static void ads7846_read_state(struct ads7846 *ts)
@@ -715,52 +809,26 @@
 	struct ads7846_packet *packet = ts->packet;
 	struct spi_message *m;
 	int msg_idx = 0;
-	int val;
-	int action;
 	int error;
 
-	while (msg_idx < ts->msg_count) {
+	packet->last_cmd_idx = 0;
 
+	while (true) {
 		ts->wait_for_sync();
 
 		m = &ts->msg[msg_idx];
 		error = spi_sync(ts->spi, m);
 		if (error) {
 			dev_err(&ts->spi->dev, "spi_sync --> %d\n", error);
-			packet->tc.ignore = true;
+			packet->ignore = true;
 			return;
 		}
 
-		/*
-		 * Last message is power down request, no need to convert
-		 * or filter the value.
-		 */
-		if (msg_idx < ts->msg_count - 1) {
+		error = ads7846_filter(ts);
+		if (error)
+			continue;
 
-			val = ads7846_get_value(ts, m);
-
-			action = ts->filter(ts->filter_data, msg_idx, &val);
-			switch (action) {
-			case ADS7846_FILTER_REPEAT:
-				continue;
-
-			case ADS7846_FILTER_IGNORE:
-				packet->tc.ignore = true;
-				msg_idx = ts->msg_count - 1;
-				continue;
-
-			case ADS7846_FILTER_OK:
-				ads7846_update_value(m, val);
-				packet->tc.ignore = false;
-				msg_idx++;
-				break;
-
-			default:
-				BUG();
-			}
-		} else {
-			msg_idx++;
-		}
+		return;
 	}
 }
 
@@ -770,35 +838,22 @@
 	unsigned int Rt;
 	u16 x, y, z1, z2;
 
-	/*
-	 * ads7846_get_value() does in-place conversion (including byte swap)
-	 * from on-the-wire format as part of debouncing to get stable
-	 * readings.
-	 */
+	x = packet->x;
+	y = packet->y;
 	if (ts->model == 7845) {
-		x = *(u16 *)packet->tc.x_buf;
-		y = *(u16 *)packet->tc.y_buf;
 		z1 = 0;
 		z2 = 0;
 	} else {
-		x = packet->tc.x;
-		y = packet->tc.y;
-		z1 = packet->tc.z1;
-		z2 = packet->tc.z2;
+		z1 = packet->z1;
+		z2 = packet->z2;
 	}
 
 	/* range filtering */
 	if (x == MAX_12BIT)
 		x = 0;
 
-	if (ts->model == 7843) {
+	if (ts->model == 7843 || ts->model == 7845) {
 		Rt = ts->pressure_max / 2;
-	} else if (ts->model == 7845) {
-		if (get_pendown_state(ts))
-			Rt = ts->pressure_max / 2;
-		else
-			Rt = 0;
-		dev_vdbg(&ts->spi->dev, "x/y: %d/%d, PD %d\n", x, y, Rt);
 	} else if (likely(x && z1)) {
 		/* compute touch pressure resistance using equation #2 */
 		Rt = z2;
@@ -817,9 +872,9 @@
 	 * the maximum. Don't report it to user space, repeat at least
 	 * once more the measurement
 	 */
-	if (packet->tc.ignore || Rt > ts->pressure_max) {
+	if (packet->ignore || Rt > ts->pressure_max) {
 		dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n",
-			 packet->tc.ignore, Rt);
+			 packet->ignore, Rt);
 		return;
 	}
 
@@ -980,13 +1035,62 @@
  * Set up the transfers to read touchscreen state; this assumes we
  * use formula #2 for pressure, not #3.
  */
-static void ads7846_setup_spi_msg(struct ads7846 *ts,
+static int ads7846_setup_spi_msg(struct ads7846 *ts,
 				  const struct ads7846_platform_data *pdata)
 {
 	struct spi_message *m = &ts->msg[0];
 	struct spi_transfer *x = ts->xfer;
 	struct ads7846_packet *packet = ts->packet;
 	int vref = pdata->keep_vref_on;
+	unsigned int count, offset = 0;
+	unsigned int cmd_idx, b;
+	unsigned long time;
+	size_t size = 0;
+
+	/* time per bit */
+	time = NSEC_PER_SEC / ts->spi->max_speed_hz;
+
+	count = pdata->settle_delay_usecs * NSEC_PER_USEC / time;
+	packet->count_skip = DIV_ROUND_UP(count, 24);
+
+	if (ts->debounce_max && ts->debounce_rep)
+		/* ads7846_debounce_filter() is making ts->debounce_rep + 2
+		 * reads. So we need to get all samples for normal case. */
+		packet->count = ts->debounce_rep + 2;
+	else
+		packet->count = 1;
+
+	if (ts->model == 7846)
+		packet->cmds = 5; /* x, y, z1, z2, pwdown */
+	else
+		packet->cmds = 3; /* x, y, pwdown */
+
+	for (cmd_idx = 0; cmd_idx < packet->cmds; cmd_idx++) {
+		struct ads7846_buf_layout *l = &packet->l[cmd_idx];
+		unsigned int max_count;
+
+		if (cmd_idx == packet->cmds - 1)
+			cmd_idx = ADS7846_PWDOWN;
+
+		if (ads7846_cmd_need_settle(cmd_idx))
+			max_count = packet->count + packet->count_skip;
+		else
+			max_count = packet->count;
+
+		l->offset = offset;
+		offset += max_count;
+		l->count = max_count;
+		l->skip = packet->count_skip;
+		size += sizeof(*packet->tx) * max_count;
+	}
+
+	packet->tx = devm_kzalloc(&ts->spi->dev, size, GFP_KERNEL);
+	if (!packet->tx)
+		return -ENOMEM;
+
+	packet->rx = devm_kzalloc(&ts->spi->dev, size, GFP_KERNEL);
+	if (!packet->rx)
+		return -ENOMEM;
 
 	if (ts->model == 7873) {
 		/*
@@ -1002,185 +1106,25 @@
 	spi_message_init(m);
 	m->context = ts;
 
-	if (ts->model == 7845) {
-		packet->read_y_cmd[0] = READ_Y(vref);
-		packet->read_y_cmd[1] = 0;
-		packet->read_y_cmd[2] = 0;
-		x->tx_buf = &packet->read_y_cmd[0];
-		x->rx_buf = &packet->tc.y_buf[0];
-		x->len = 3;
-		spi_message_add_tail(x, m);
-	} else {
-		/* y- still on; turn on only y+ (and ADC) */
-		packet->read_y = READ_Y(vref);
-		x->tx_buf = &packet->read_y;
-		x->len = 1;
-		spi_message_add_tail(x, m);
+	for (cmd_idx = 0; cmd_idx < packet->cmds; cmd_idx++) {
+		struct ads7846_buf_layout *l = &packet->l[cmd_idx];
+		u8 cmd;
 
-		x++;
-		x->rx_buf = &packet->tc.y;
-		x->len = 2;
-		spi_message_add_tail(x, m);
+		if (cmd_idx == packet->cmds - 1)
+			cmd_idx = ADS7846_PWDOWN;
+
+		cmd = ads7846_get_cmd(cmd_idx, vref);
+
+		for (b = 0; b < l->count; b++)
+			packet->tx[l->offset + b].cmd = cmd;
 	}
 
-	/*
-	 * The first sample after switching drivers can be low quality;
-	 * optionally discard it, using a second one after the signals
-	 * have had enough time to stabilize.
-	 */
-	if (pdata->settle_delay_usecs) {
-		x->delay.value = pdata->settle_delay_usecs;
-		x->delay.unit = SPI_DELAY_UNIT_USECS;
-
-		x++;
-		x->tx_buf = &packet->read_y;
-		x->len = 1;
-		spi_message_add_tail(x, m);
-
-		x++;
-		x->rx_buf = &packet->tc.y;
-		x->len = 2;
-		spi_message_add_tail(x, m);
-	}
-
-	ts->msg_count++;
-	m++;
-	spi_message_init(m);
-	m->context = ts;
-
-	if (ts->model == 7845) {
-		x++;
-		packet->read_x_cmd[0] = READ_X(vref);
-		packet->read_x_cmd[1] = 0;
-		packet->read_x_cmd[2] = 0;
-		x->tx_buf = &packet->read_x_cmd[0];
-		x->rx_buf = &packet->tc.x_buf[0];
-		x->len = 3;
-		spi_message_add_tail(x, m);
-	} else {
-		/* turn y- off, x+ on, then leave in lowpower */
-		x++;
-		packet->read_x = READ_X(vref);
-		x->tx_buf = &packet->read_x;
-		x->len = 1;
-		spi_message_add_tail(x, m);
-
-		x++;
-		x->rx_buf = &packet->tc.x;
-		x->len = 2;
-		spi_message_add_tail(x, m);
-	}
-
-	/* ... maybe discard first sample ... */
-	if (pdata->settle_delay_usecs) {
-		x->delay.value = pdata->settle_delay_usecs;
-		x->delay.unit = SPI_DELAY_UNIT_USECS;
-
-		x++;
-		x->tx_buf = &packet->read_x;
-		x->len = 1;
-		spi_message_add_tail(x, m);
-
-		x++;
-		x->rx_buf = &packet->tc.x;
-		x->len = 2;
-		spi_message_add_tail(x, m);
-	}
-
-	/* turn y+ off, x- on; we'll use formula #2 */
-	if (ts->model == 7846) {
-		ts->msg_count++;
-		m++;
-		spi_message_init(m);
-		m->context = ts;
-
-		x++;
-		packet->read_z1 = READ_Z1(vref);
-		x->tx_buf = &packet->read_z1;
-		x->len = 1;
-		spi_message_add_tail(x, m);
-
-		x++;
-		x->rx_buf = &packet->tc.z1;
-		x->len = 2;
-		spi_message_add_tail(x, m);
-
-		/* ... maybe discard first sample ... */
-		if (pdata->settle_delay_usecs) {
-			x->delay.value = pdata->settle_delay_usecs;
-			x->delay.unit = SPI_DELAY_UNIT_USECS;
-
-			x++;
-			x->tx_buf = &packet->read_z1;
-			x->len = 1;
-			spi_message_add_tail(x, m);
-
-			x++;
-			x->rx_buf = &packet->tc.z1;
-			x->len = 2;
-			spi_message_add_tail(x, m);
-		}
-
-		ts->msg_count++;
-		m++;
-		spi_message_init(m);
-		m->context = ts;
-
-		x++;
-		packet->read_z2 = READ_Z2(vref);
-		x->tx_buf = &packet->read_z2;
-		x->len = 1;
-		spi_message_add_tail(x, m);
-
-		x++;
-		x->rx_buf = &packet->tc.z2;
-		x->len = 2;
-		spi_message_add_tail(x, m);
-
-		/* ... maybe discard first sample ... */
-		if (pdata->settle_delay_usecs) {
-			x->delay.value = pdata->settle_delay_usecs;
-			x->delay.unit = SPI_DELAY_UNIT_USECS;
-
-			x++;
-			x->tx_buf = &packet->read_z2;
-			x->len = 1;
-			spi_message_add_tail(x, m);
-
-			x++;
-			x->rx_buf = &packet->tc.z2;
-			x->len = 2;
-			spi_message_add_tail(x, m);
-		}
-	}
-
-	/* power down */
-	ts->msg_count++;
-	m++;
-	spi_message_init(m);
-	m->context = ts;
-
-	if (ts->model == 7845) {
-		x++;
-		packet->pwrdown_cmd[0] = PWRDOWN;
-		packet->pwrdown_cmd[1] = 0;
-		packet->pwrdown_cmd[2] = 0;
-		x->tx_buf = &packet->pwrdown_cmd[0];
-		x->len = 3;
-	} else {
-		x++;
-		packet->pwrdown = PWRDOWN;
-		x->tx_buf = &packet->pwrdown;
-		x->len = 1;
-		spi_message_add_tail(x, m);
-
-		x++;
-		x->rx_buf = &packet->dummy;
-		x->len = 2;
-	}
-
-	CS_CHANGE(*x);
+	x->tx_buf = packet->tx;
+	x->rx_buf = packet->rx;
+	x->len = size;
 	spi_message_add_tail(x, m);
+
+	return 0;
 }
 
 #ifdef CONFIG_OF
@@ -1381,8 +1325,9 @@
 			pdata->y_min ? : 0,
 			pdata->y_max ? : MAX_12BIT,
 			0, 0);
-	input_set_abs_params(input_dev, ABS_PRESSURE,
-			pdata->pressure_min, pdata->pressure_max, 0, 0);
+	if (ts->model != 7845)
+		input_set_abs_params(input_dev, ABS_PRESSURE,
+				pdata->pressure_min, pdata->pressure_max, 0, 0);
 
 	/*
 	 * Parse common framework properties. Must be done here to ensure the
diff --git a/kernel/drivers/input/touchscreen/elants_i2c.c b/kernel/drivers/input/touchscreen/elants_i2c.c
index c09aefa..ca9cee5 100644
--- a/kernel/drivers/input/touchscreen/elants_i2c.c
+++ b/kernel/drivers/input/touchscreen/elants_i2c.c
@@ -1219,14 +1219,12 @@
 	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 @@
 			"failed to enable vccio regulator: %d\n",
 			error);
 		regulator_disable(ts->vcc33);
-		goto release_reset_gpio;
+		return error;
 	}
 
 	/*
@@ -1244,7 +1242,6 @@
 	 */
 	udelay(ELAN_POWERON_DELAY_USEC);
 
-release_reset_gpio:
 	gpiod_set_value_cansleep(ts->reset_gpio, 0);
 	if (error)
 		return error;
@@ -1352,7 +1349,7 @@
 		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);
 
diff --git a/kernel/drivers/input/touchscreen/goodix.c b/kernel/drivers/input/touchscreen/goodix.c
index b7f87ad..098115e 100644
--- a/kernel/drivers/input/touchscreen/goodix.c
+++ b/kernel/drivers/input/touchscreen/goodix.c
@@ -183,10 +183,18 @@
 static const struct dmi_system_id nine_bytes_report[] = {
 #if defined(CONFIG_DMI) && defined(CONFIG_X86)
 	{
-		.ident = "Lenovo YogaBook",
-		/* YB1-X91L/F and YB1-X90L/F */
+		/* Lenovo Yoga Book X90F / X90L */
 		.matches = {
-			DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9")
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"),
+		}
+	},
+	{
+		/* Lenovo Yoga Book X91F / X91L */
+		.matches = {
+			/* Non exact match to match F + L versions */
+			DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"),
 		}
 	},
 #endif
diff --git a/kernel/drivers/input/touchscreen/gt9xx/Makefile b/kernel/drivers/input/touchscreen/gt9xx/Makefile
index f63b5f2..cb01c65 100644
--- a/kernel/drivers/input/touchscreen/gt9xx/Makefile
+++ b/kernel/drivers/input/touchscreen/gt9xx/Makefile
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
-obj-y	+= goodix_gt9xx.o
+obj-$(CONFIG_TOUCHSCREEN_GT9XX)	+= goodix_gt9xx.o
 
 #goodix_gt9xx-y		+=goodix_tool.o
 goodix_gt9xx-y		+=gt9xx.o
diff --git a/kernel/drivers/input/touchscreen/gt9xx/gt9xx.c b/kernel/drivers/input/touchscreen/gt9xx/gt9xx.c
index 67b1b34..f340c04 100644
--- a/kernel/drivers/input/touchscreen/gt9xx/gt9xx.c
+++ b/kernel/drivers/input/touchscreen/gt9xx/gt9xx.c
@@ -68,8 +68,8 @@
 
 static const char *goodix_ts_name = "goodix-ts";
 static struct workqueue_struct *goodix_wq;
-struct i2c_client * i2c_connect_client = NULL; 
-u8 config[GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH]
+struct i2c_client * gtp_i2c_connect_client = NULL; 
+static u8 config[GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH]
                 = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff};
 
 #if GTP_HAVE_TOUCH_KEY
@@ -86,12 +86,12 @@
 static s8 gtp_i2c_test(struct i2c_client *client);
 void gtp_reset_guitar(struct i2c_client *client, s32 ms);
 s32 gtp_send_cfg(struct i2c_client *client);
-void gtp_int_sync(s32 ms, struct goodix_ts_data *ts);
+static void gtp_int_sync(s32 ms, struct goodix_ts_data *ts);
 
 static ssize_t gt91xx_config_read_proc(struct file *, char __user *, size_t, loff_t *);
 static ssize_t gt91xx_config_write_proc(struct file *, const char __user *, size_t, loff_t *);
 
-static struct proc_dir_entry *gt91xx_config_proc = NULL;
+//static struct proc_dir_entry *gt91xx_config_proc = NULL;
 static const struct file_operations config_proc_ops = {
     .owner = THIS_MODULE,
     .read = gt91xx_config_read_proc,
@@ -117,15 +117,15 @@
 
 //*********** For GT9XXF Start **********//
 #if GTP_COMPATIBLE_MODE
-extern s32 i2c_read_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len);
-extern s32 i2c_write_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len);
-extern s32 gup_clk_calibration(void);
-extern s32 gup_fw_download_proc(void *dir, u8 dwn_mode);
-extern u8 gup_check_fs_mounted(char *path_name);
+//extern s32 gtp_i2c_read_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len);
+//extern s32 gtp_i2c_write_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len);
+//extern s32 gtp_gup_clk_calibration(void);
+//extern s32 gtp_gup_fw_download_proc(void *dir, u8 dwn_mode);
+//extern u8 gtp_gup_check_fs_mounted(char *path_name);
 
-void gtp_recovery_reset(struct i2c_client *client);
+static void gtp_recovery_reset(struct i2c_client *client);
 static s32 gtp_esd_recovery(struct i2c_client *client);
-s32 gtp_fw_startup(struct i2c_client *client);
+//s32 gtp_fw_startup(struct i2c_client *client);
 static s32 gtp_main_clk_proc(struct goodix_ts_data *ts);
 static s32 gtp_bak_ref_proc(struct goodix_ts_data *ts, u8 mode);
 
@@ -143,7 +143,7 @@
 static s8 gtp_enter_doze(struct goodix_ts_data *ts);
 #endif
 
-u8 grp_cfg_version = 0;
+static u8 grp_cfg_version = 0;
 
 /*******************************************************
 Function:
@@ -157,7 +157,7 @@
     numbers of i2c_msgs to transfer: 
       2: succeed, otherwise: failed
 *********************************************************/
-s32 gtp_i2c_read(struct i2c_client *client, u8 *buf, s32 len)
+static s32 gtp_i2c_read(struct i2c_client *client, u8 *buf, s32 len)
 {
     struct i2c_msg msgs[2];
     s32 ret=-1;
@@ -230,7 +230,7 @@
     numbers of i2c_msgs to transfer: 
         1: succeed, otherwise: failed
 *********************************************************/
-s32 gtp_i2c_write(struct i2c_client *client,u8 *buf,s32 len)
+static s32 gtp_i2c_write(struct i2c_client *client,u8 *buf,s32 len)
 {
     struct i2c_msg msg;
     s32 ret = -1;
@@ -523,7 +523,7 @@
 
 static void gtp_pen_down(s32 x, s32 y, s32 w, s32 id)
 {
-    struct goodix_ts_data *ts = i2c_get_clientdata(i2c_connect_client);
+    struct goodix_ts_data *ts = i2c_get_clientdata(gtp_i2c_connect_client);
 
 	if (gtp_change_x2y)
 		GTP_SWAP(x, y);
@@ -551,7 +551,7 @@
 
 static void gtp_pen_up(s32 id)
 {
-    struct goodix_ts_data *ts = i2c_get_clientdata(i2c_connect_client);
+    struct goodix_ts_data *ts = i2c_get_clientdata(gtp_i2c_connect_client);
     
     input_report_key(ts->pen_dev, BTN_TOOL_PEN, 0);
     
@@ -613,7 +613,7 @@
 #if GTP_GESTURE_WAKEUP
     if (DOZE_ENABLED == doze_status)
     {               
-        ret = gtp_i2c_read(i2c_connect_client, doze_buf, 3);
+        ret = gtp_i2c_read(gtp_i2c_connect_client, doze_buf, 3);
         GTP_DEBUG("0x814B = 0x%02X", doze_buf[2]);
         if (ret > 0)
         {     
@@ -640,7 +640,7 @@
                 input_sync(ts->input_dev);
                 // clear 0x814B
                 doze_buf[2] = 0x00;
-                gtp_i2c_write(i2c_connect_client, doze_buf, 3);
+                gtp_i2c_write(gtp_i2c_connect_client, doze_buf, 3);
 			}
 			else if ( (doze_buf[2] == 0xAA) || (doze_buf[2] == 0xBB) ||
 				(doze_buf[2] == 0xAB) || (doze_buf[2] == 0xBA) )
@@ -656,7 +656,7 @@
                 input_sync(ts->input_dev);
                 // clear 0x814B
                 doze_buf[2] = 0x00;
-                gtp_i2c_write(i2c_connect_client, doze_buf, 3);
+                gtp_i2c_write(gtp_i2c_connect_client, doze_buf, 3);
             }
             else if (0xCC == doze_buf[2])
             {
@@ -668,13 +668,13 @@
                 input_sync(ts->input_dev);
                 // clear 0x814B
                 doze_buf[2] = 0x00;
-                gtp_i2c_write(i2c_connect_client, doze_buf, 3);
+                gtp_i2c_write(gtp_i2c_connect_client, doze_buf, 3);
             }
             else
             {
                 // clear 0x814B
                 doze_buf[2] = 0x00;
-                gtp_i2c_write(i2c_connect_client, doze_buf, 3);
+                gtp_i2c_write(gtp_i2c_connect_client, doze_buf, 3);
                 gtp_enter_doze(ts);
             }
         }
@@ -1087,7 +1087,7 @@
 Output:
     None.
 *******************************************************/
-void gtp_int_sync(s32 ms, struct goodix_ts_data *ts)
+static void gtp_int_sync(s32 ms, struct goodix_ts_data *ts)
 {
     GTP_GPIO_OUTPUT(ts->irq_pin, 0);
     msleep(ms);
@@ -1706,7 +1706,7 @@
     ptr += sprintf(ptr, "\n");
 
     ptr += sprintf(ptr, "==== GT9XX config real value====\n");
-    gtp_i2c_read(i2c_connect_client, temp_data, GTP_CONFIG_MAX_LENGTH + 2);
+    gtp_i2c_read(gtp_i2c_connect_client, temp_data, GTP_CONFIG_MAX_LENGTH + 2);
     for (i = 0 ; i < GTP_CONFIG_MAX_LENGTH ; i++)
     {
         ptr += sprintf(ptr, "0x%02X ", temp_data[i+2]);
@@ -1734,7 +1734,7 @@
         return -EFAULT;
     }
 
-    ret = gtp_send_cfg(i2c_connect_client);
+    ret = gtp_send_cfg(gtp_i2c_connect_client);
 
     if (ret < 0)
     {
@@ -2144,7 +2144,7 @@
     struct goodix_ts_data *ts = i2c_get_clientdata(client);
     //init sw WDT
 	opr_buf[0] = 0xAA;
-	ret = i2c_write_bytes(client, 0x8041, opr_buf, 1);
+	ret = gtp_i2c_write_bytes(client, 0x8041, opr_buf, 1);
     if (ret < 0)
     {
         return FAIL;
@@ -2152,7 +2152,7 @@
     
     //release SS51 & DSP
     opr_buf[0] = 0x00;
-    ret = i2c_write_bytes(client, 0x4180, opr_buf, 1);
+    ret = gtp_i2c_write_bytes(client, 0x4180, opr_buf, 1);
     if (ret < 0)
     {
         return FAIL;
@@ -2161,7 +2161,7 @@
     gtp_int_sync(25, ts);  
     
     //check fw run status
-    ret = i2c_read_bytes(client, 0x8041, opr_buf, 1);
+    ret = gtp_i2c_read_bytes(client, 0x8041, opr_buf, 1);
     if (ret < 0)
     {
         return FAIL;
@@ -2175,7 +2175,7 @@
     {
         GTP_INFO("IC works normally, Startup success.");
         opr_buf[0] = 0xAA;
-        i2c_write_bytes(client, 0x8041, opr_buf, 1);
+        gtp_i2c_write_bytes(client, 0x8041, opr_buf, 1);
         return SUCCESS;
     }
 }
@@ -2193,7 +2193,7 @@
     GTP_INFO("GT9XXF esd recovery mode");
     for (retry = 0; retry < 5; retry++)
     {
-        ret = gup_fw_download_proc(NULL, GTP_FL_ESD_RECOVERY); 
+        ret = gtp_gup_fw_download_proc(NULL, GTP_FL_ESD_RECOVERY); 
         if (FAIL == ret)
         {
             GTP_ERROR("esd recovery failed %d", retry+1);
@@ -2219,7 +2219,7 @@
     return SUCCESS;
 }
 
-void gtp_recovery_reset(struct i2c_client *client)
+static void gtp_recovery_reset(struct i2c_client *client)
 {
 #if GTP_ESD_PROTECT
     gtp_esd_switch(client, SWITCH_OFF);
@@ -2246,7 +2246,7 @@
     struct file *ref_filp = NULL;
     u8 *p_bak_ref;
     
-    ret = gup_check_fs_mounted("/data");
+    ret = gtp_gup_check_fs_mounted("/data");
     if (FAIL == ret)
     {
         ts->ref_chk_fs_times++;
@@ -2334,7 +2334,7 @@
                 }
             }
         }
-        ret = i2c_write_bytes(ts->client, GTP_REG_BAK_REF, p_bak_ref, ts->bak_ref_len);
+        ret = gtp_i2c_write_bytes(ts->client, GTP_REG_BAK_REF, p_bak_ref, ts->bak_ref_len);
         if (FAIL == ret)
         {
             GTP_ERROR("failed to send bak_ref because of iic comm error");
@@ -2344,7 +2344,7 @@
         
     case GTP_BAK_REF_STORE:
         GTP_INFO("Store backup-reference");
-        ret = i2c_read_bytes(ts->client, GTP_REG_BAK_REF, p_bak_ref, ts->bak_ref_len);
+        ret = gtp_i2c_read_bytes(ts->client, GTP_REG_BAK_REF, p_bak_ref, ts->bak_ref_len);
         if (ret < 0)
         {
             GTP_ERROR("failed to read bak_ref info, sending default back-reference");
@@ -2368,7 +2368,7 @@
         memset(&p_bak_ref[j * ref_seg_len], 0, ref_seg_len);
         p_bak_ref[j * ref_seg_len + ref_seg_len - 1] = 0x01;  // checksum = 1     
     }
-    ret = i2c_write_bytes(ts->client, GTP_REG_BAK_REF, p_bak_ref, ts->bak_ref_len);
+    ret = gtp_i2c_write_bytes(ts->client, GTP_REG_BAK_REF, p_bak_ref, ts->bak_ref_len);
     if (!IS_ERR(ref_filp))
     {
         GTP_INFO("write backup-reference data into %s", GTP_BAK_REF_PATH);
@@ -2450,7 +2450,7 @@
 		goto update_main_clk;
 	}
 	#else
-    ret = gup_check_fs_mounted("/data");
+    ret = gtp_gup_check_fs_mounted("/data");
     if (FAIL == ret)
     {
         ts->clk_chk_fs_times++;
@@ -2496,7 +2496,7 @@
 #if GTP_ESD_PROTECT
     gtp_esd_switch(ts->client, SWITCH_OFF);
 #endif
-    ret = gup_clk_calibration();
+    ret = gtp_gup_clk_calibration();
     gtp_esd_recovery(ts->client);
     
 #if GTP_ESD_PROTECT
@@ -2527,7 +2527,7 @@
     }
     
 update_main_clk:
-    ret = i2c_write_bytes(ts->client, GTP_REG_MAIN_CLK, p_main_clk, 6);
+    ret = gtp_i2c_write_bytes(ts->client, GTP_REG_MAIN_CLK, p_main_clk, 6);
     if (FAIL == ret)
     {
         GTP_ERROR("update main clock failed!");
@@ -2544,11 +2544,11 @@
 }
 
 
-s32 gtp_gt9xxf_init(struct i2c_client *client)
+static s32 gtp_gt9xxf_init(struct i2c_client *client)
 {
     s32 ret = 0;
     
-    ret = gup_fw_download_proc(NULL, GTP_FL_FW_BURN); 
+    ret = gtp_gup_fw_download_proc(NULL, GTP_FL_FW_BURN); 
     if (FAIL == ret)
     {
         return FAIL;
@@ -2562,7 +2562,7 @@
     return SUCCESS;
 }
 
-void gtp_get_chip_type(struct goodix_ts_data *ts)
+static void gtp_get_chip_type(struct goodix_ts_data *ts)
 {
     u8 opr_buf[10] = {0x00};
     s32 ret = 0;
@@ -2626,7 +2626,7 @@
     GTP_INFO("GTP Driver Version: %s", GTP_DRIVER_VERSION);
     GTP_INFO("GTP I2C Address: 0x%02x", client->addr);
 
-    i2c_connect_client = client;
+    gtp_i2c_connect_client = client;
     
     if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 
     {
@@ -2670,8 +2670,8 @@
 	} else if (val == 9110) {
 		m89or101 = FALSE;
 		bgt9110 = TRUE;
-		gtp_change_x2y = TRUE;
-		gtp_x_reverse = TRUE;
+		gtp_change_x2y = FALSE;
+		gtp_x_reverse = FALSE;
 		gtp_y_reverse = FALSE;
 	} else if (val == 9111) {
 		m89or101 = FALSE;
@@ -2804,6 +2804,7 @@
     
     ts->irq_flags = ts->int_trigger_type ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
     // Create proc file system
+#if 0
 	gt91xx_config_proc = proc_create(GT91XX_CONFIG_PROC_FILE, 0664, NULL, &config_proc_ops);
     if (gt91xx_config_proc == NULL)
     {
@@ -2813,6 +2814,7 @@
     {
         GTP_INFO("create proc entry %s success", GT91XX_CONFIG_PROC_FILE);
     }
+#endif
     
 #if GTP_AUTO_UPDATE
     ret = gup_init_update_proc(ts);
@@ -3061,7 +3063,7 @@
     
     GTP_DEBUG_FUNC();
    
-    ts = i2c_get_clientdata(i2c_connect_client);
+    ts = i2c_get_clientdata(gtp_i2c_connect_client);
 
     if (ts->gtp_is_suspend)
     {
@@ -3233,3 +3235,4 @@
 
 MODULE_DESCRIPTION("GTP Series Driver");
 MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
diff --git a/kernel/drivers/input/touchscreen/gt9xx/gt9xx.h b/kernel/drivers/input/touchscreen/gt9xx/gt9xx.h
index acc2885..5f9ae18 100644
--- a/kernel/drivers/input/touchscreen/gt9xx/gt9xx.h
+++ b/kernel/drivers/input/touchscreen/gt9xx/gt9xx.h
@@ -154,8 +154,8 @@
     struct regulator *tp_regulator;
 };
 
-extern u16 show_len;
-extern u16 total_len;
+//extern u16 show_len;
+//extern u16 total_len;
 
 
 //*************************** PART2:TODO define **********************************
@@ -391,7 +391,22 @@
                                        }while (0)
 
 //*****************************End of Part III********************************
-#define TRUE    1
-#define FALSE   0
+//#define TRUE    1
+//#define FALSE   0
+
+extern struct i2c_client *gtp_i2c_connect_client;
+
+s32 gtp_fw_startup(struct i2c_client *client);
+s32 gtp_i2c_read_dbl_check(struct i2c_client *client, u16 addr, u8 *rxbuf, int len);
+void gtp_irq_disable(struct goodix_ts_data *ts);
+void gtp_irq_enable(struct goodix_ts_data *ts);
+s32 gtp_read_version(struct i2c_client *client, u16 *version);
+void gtp_reset_guitar(struct i2c_client *client, s32 ms);
+s32 gtp_send_cfg(struct i2c_client *client);
+u8 gtp_gup_check_fs_mounted(char *path_name);
+s32 gtp_gup_fw_download_proc(void *dir, u8 dwn_mode);
+s32 gtp_i2c_read_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len);
+s32 gtp_i2c_write_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len);
+s32 gtp_gup_clk_calibration(void);
 
 #endif /* _GOODIX_GT9XX_H_ */
diff --git a/kernel/drivers/input/touchscreen/gt9xx/gt9xx_cfg.h b/kernel/drivers/input/touchscreen/gt9xx/gt9xx_cfg.h
index 2b083c5..584da09 100644
--- a/kernel/drivers/input/touchscreen/gt9xx/gt9xx_cfg.h
+++ b/kernel/drivers/input/touchscreen/gt9xx/gt9xx_cfg.h
@@ -19,21 +19,21 @@
 #define _GOODIX_GT9XX_CFG_H_
 
 /* CFG for GT911 */
-u8 gtp_dat_gt11[] = {
+static u8 gtp_dat_gt11[] = {
 	/* <1200, 1920>*/
 	#include "WGJ89006B_GT911_Config_20140625_085816_0X43.cfg"
 };
 
-u8 gtp_dat_gt9110[] = {
+static u8 gtp_dat_gt9110[] = {
 	/* <1200, 1920>*/
 	#include "GT9110P(2020)V71_Config_20201028_170326.cfg"
 };
 
-u8 gtp_dat_gt9111[] = {
+static u8 gtp_dat_gt9111[] = {
 	#include "HLS-0102-1398V1-1060-GT911_Config_20201204_V66.cfg"
 };
 
-u8 gtp_dat_8_9[] = {
+static u8 gtp_dat_8_9[] = {
 	/* TODO:Puts your update firmware data here! */
 	/* <1920, 1200> 8.9 */
 	/* #include "WGJ89006B_GT9271_Config_20140625_085816_0X41.cfg" */
@@ -41,22 +41,22 @@
 	#include "WGJ10162B_GT9271_1060_Config_20140821_1341110X42.cfg"
 };
 
-u8 gtp_dat_8_9_1[] = {
+static u8 gtp_dat_8_9_1[] = {
 	#include "GT9271_Config_20170526.cfg"
 };
 
-u8 gtp_dat_9_7[] = {
+static u8 gtp_dat_9_7[] = {
 	/* <1536, 2048> 9.7 */
 	#include "GT9110P_Config_20160217_1526_2048_97.cfg"
 };
 
-u8 gtp_dat_10_1[] = {
+static u8 gtp_dat_10_1[] = {
 	/* TODO:Puts your update firmware data here! */
 	/* <1200, 1920> 10.1 */
 	#include "WGJ10187_GT9271_Config_20140623_104014_0X41.cfg"
 };
 
-u8 gtp_dat_7[] = {
+static u8 gtp_dat_7[] = {
 	/* TODO:Puts your update firmware data here! */
 	/* <1024, 600> 7.0 */
 	#include "WGJ10187_GT910_Config_20140623_104014_0X41.cfg"
diff --git a/kernel/drivers/input/touchscreen/gt9xx/gt9xx_firmware.h b/kernel/drivers/input/touchscreen/gt9xx/gt9xx_firmware.h
index 7dce604..8fc22fd 100644
--- a/kernel/drivers/input/touchscreen/gt9xx/gt9xx_firmware.h
+++ b/kernel/drivers/input/touchscreen/gt9xx/gt9xx_firmware.h
@@ -15,7 +15,7 @@
 #define _GT9XX_FIRMWARE_H_
 
 #if GTP_HEADER_FW_UPDATE
-unsigned char gtp_default_FW[] = {
+static unsigned char gtp_default_FW[] = {
 };
 #endif
 
@@ -26,7 +26,7 @@
  *[GENERATED]2014/01/20 17:37:45
  */
 #if GTP_COMPATIBLE_MODE
-unsigned char gtp_default_FW_fl[] = {
+static unsigned char gtp_default_FW_fl[] = {
 	0x00, 0x90, 0x06, 0x00, 0x39, 0x31, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x80, 0x00,
 	0x55, 0x40, 0xa4, 0x28, 0xb3, 0x26, 0x69, 0xf0, 0x0c, 0xc1, 0x00, 0x62, 0x72, 0xed, 0x88, 0x5c,
 	0x4f, 0x41, 0xf0, 0x90, 0x24, 0xbf, 0x32, 0xe0, 0x1d, 0xc9, 0xdf, 0xf2, 0x53, 0x73, 0x01, 0x20,
diff --git a/kernel/drivers/input/touchscreen/gt9xx/gt9xx_update.c b/kernel/drivers/input/touchscreen/gt9xx/gt9xx_update.c
index 8affe60..5590f43 100644
--- a/kernel/drivers/input/touchscreen/gt9xx/gt9xx_update.c
+++ b/kernel/drivers/input/touchscreen/gt9xx/gt9xx_update.c
@@ -26,7 +26,7 @@
  *          3. add update file cal checksum.
  *                          By Andrew, 2012/12/12
  *      V1.6: 
- *          1. replace guitar_client with i2c_connect_client;
+ *          1. replace guitar_client with gtp_i2c_connect_client;
  *          2. support firmware header array update.
  *                          By Meta, 2013/03/11
  *      V2.2:
@@ -106,21 +106,21 @@
     u32 fw_burned_len;
 }st_update_msg;
 
-st_update_msg update_msg;
-u16 show_len;
-u16 total_len;
-u8 got_file_flag = 0;  
-u8 searching_file = 0;
+static st_update_msg update_msg;
+static u16 show_len;
+static u16 total_len;
+//static u8 got_file_flag = 0;  
+static u8 searching_file = 0;
 
-extern u8 config[GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH];
-extern void gtp_reset_guitar(struct i2c_client *client, s32 ms);
-extern s32  gtp_send_cfg(struct i2c_client *client);
-extern s32 gtp_read_version(struct i2c_client *, u16* );
-extern struct i2c_client * i2c_connect_client;
-extern void gtp_irq_enable(struct goodix_ts_data *ts);
-extern void gtp_irq_disable(struct goodix_ts_data *ts);
-extern s32 gtp_i2c_read_dbl_check(struct i2c_client *, u16, u8 *, int);
-static u8 gup_burn_fw_gwake_section(struct i2c_client *client, u8 *fw_section, u16 start_addr, u32 len, u8 bank_cmd );
+//extern u8 config[GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH];
+//extern void gtp_reset_guitar(struct i2c_client *client, s32 ms);
+//extern s32  gtp_send_cfg(struct i2c_client *client);
+//extern s32 gtp_read_version(struct i2c_client *, u16* );
+//extern struct i2c_client * gtp_i2c_connect_client;
+//extern void gtp_irq_enable(struct goodix_ts_data *ts);
+//extern void gtp_irq_disable(struct goodix_ts_data *ts);
+//extern s32 gtp_i2c_read_dbl_check(struct i2c_client *, u16, u8 *, int);
+//static u8 gup_burn_fw_gwake_section(struct i2c_client *client, u8 *fw_section, u16 start_addr, u32 len, u8 bank_cmd );
 
 #define _CLOSE_FILE(p_file) if (p_file && !IS_ERR(p_file)) \
                             { \
@@ -132,7 +132,7 @@
 #endif
 
 #if GTP_COMPATIBLE_MODE
-s32 gup_fw_download_proc(void *dir, u8 dwn_mode);
+s32 gtp_gup_fw_download_proc(void *dir, u8 dwn_mode);
 #endif
 /*******************************************************
 Function:
@@ -146,7 +146,7 @@
     numbers of i2c_msgs to transfer: 
       2: succeed, otherwise: failed
 *********************************************************/
-s32 gup_i2c_read(struct i2c_client *client, u8 *buf, s32 len)
+static s32 gup_i2c_read(struct i2c_client *client, u8 *buf, s32 len)
 {
     struct i2c_msg msgs[2];
     s32 ret=-1;
@@ -192,7 +192,7 @@
     numbers of i2c_msgs to transfer: 
         1: succeed, otherwise: failed
 *********************************************************/
-s32 gup_i2c_write(struct i2c_client *client,u8 *buf,s32 len)
+static s32 gup_i2c_write(struct i2c_client *client,u8 *buf,s32 len)
 {
     struct i2c_msg msg;
     s32 ret=-1;
@@ -218,6 +218,7 @@
     return ret;
 }
 
+#if 0
 static s32 gup_init_panel(struct goodix_ts_data *ts)
 {
     s32 ret = 0;
@@ -329,6 +330,7 @@
     msleep(10);
     return 0;
 }
+#endif
 
 
 static u8 gup_get_ic_msg(struct i2c_client *client, u16 addr, u8* msg, s32 len)
@@ -381,6 +383,7 @@
     return SUCCESS;
 }
 
+#if 0
 static u8 gup_get_ic_fw_msg(struct i2c_client *client)
 {
     s32 ret = -1;
@@ -462,7 +465,7 @@
     return SUCCESS;
 }
 
-s32 gup_enter_update_mode(struct i2c_client *client)
+static s32 gup_enter_update_mode(struct i2c_client *client)
 {
     s32 ret = -1;
     s32 retry = 0;
@@ -519,14 +522,14 @@
     return ret;
 }
 
-void gup_leave_update_mode(struct goodix_ts_data *ts)
+static void gup_leave_update_mode(struct goodix_ts_data *ts)
 {
     gpio_direction_input(ts->irq_pin);
     //s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);
     //s3c_gpio_cfgpin(pin, GTP_INT_CFG);
     
     GTP_DEBUG("[leave_update_mode]reset chip.");
-    gtp_reset_guitar(i2c_connect_client, 20);
+    gtp_reset_guitar(gtp_i2c_connect_client, 20);
 }
 
 // Get the correct nvram data
@@ -646,6 +649,7 @@
 
     return FAIL;
 }
+#endif
 
 
 
@@ -869,6 +873,7 @@
 #endif
 
 
+#if 0
 static u8 gup_check_update_file(struct i2c_client *client, st_fw_head* fw_head, u8* path)
 {
     s32 ret = 0;
@@ -924,7 +929,7 @@
         gup_search_file(AUTO_SEARCH_BIN | AUTO_SEARCH_CFG);
         if (got_file_flag & CFG_FILE_READY)
         {
-            ret = gup_update_config(i2c_connect_client);
+            ret = gup_update_config(gtp_i2c_connect_client);
             if(ret <= 0)
             {
                 GTP_ERROR("Update config failed.");
@@ -2271,7 +2276,7 @@
     }
     return FAIL;
 }
-s32 gup_update_proc(void *dir)
+static s32 gup_update_proc(void *dir)
 {
     s32 ret = 0;
     s32 update_ret = FAIL;
@@ -2281,7 +2286,7 @@
     
     GTP_DEBUG("[update_proc]Begin update ......");
     
-    ts = i2c_get_clientdata(i2c_connect_client);
+    ts = i2c_get_clientdata(gtp_i2c_connect_client);
     
 #if GTP_AUTO_UPDATE
     if (searching_file)
@@ -2302,19 +2307,19 @@
 #if GTP_COMPATIBLE_MODE
     if (CHIP_TYPE_GT9F == ts->chip_type)
     {
-        return gup_fw_download_proc(dir, GTP_FL_FW_BURN);
+        return gtp_gup_fw_download_proc(dir, GTP_FL_FW_BURN);
     }
 #endif
 
     update_msg.file = NULL;
-    ret = gup_check_update_file(i2c_connect_client, &fw_head, (u8*)dir);     //20121211
+    ret = gup_check_update_file(gtp_i2c_connect_client, &fw_head, (u8*)dir);     //20121211
     if(FAIL == ret)
     {
         GTP_ERROR("[update_proc]check update file fail.");
         goto file_fail;
     }
     
-    ret = gup_get_ic_fw_msg(i2c_connect_client);
+    ret = gup_get_ic_fw_msg(gtp_i2c_connect_client);
     if(FAIL == ret)
     {
         GTP_ERROR("[update_proc]get ic message fail.");
@@ -2333,7 +2338,7 @@
 #if GTP_ESD_PROTECT
     gtp_esd_switch(ts->client, SWITCH_OFF);
 #endif
-    ret = gup_enter_update_mode(i2c_connect_client);
+    ret = gup_enter_update_mode(gtp_i2c_connect_client);
     if(FAIL == ret)
     {
          GTP_ERROR("[update_proc]enter update mode fail.");
@@ -2345,7 +2350,7 @@
         show_len = 10;
         total_len = 100;
         update_msg.fw_burned_len = 0;
-        ret = gup_burn_dsp_isp(i2c_connect_client);
+        ret = gup_burn_dsp_isp(gtp_i2c_connect_client);
         if(FAIL == ret)
         {
             GTP_ERROR("[update_proc]burn dsp isp fail.");
@@ -2353,7 +2358,7 @@
         }
         
         show_len = 20;
-        ret = gup_burn_fw_ss51(i2c_connect_client);
+        ret = gup_burn_fw_ss51(gtp_i2c_connect_client);
         if(FAIL == ret)
         {
             GTP_ERROR("[update_proc]burn ss51 firmware fail.");
@@ -2361,7 +2366,7 @@
         }
         
         show_len = 30;
-        ret = gup_burn_fw_dsp(i2c_connect_client);
+        ret = gup_burn_fw_dsp(gtp_i2c_connect_client);
         if(FAIL == ret)
         {
             GTP_ERROR("[update_proc]burn dsp firmware fail.");
@@ -2369,7 +2374,7 @@
         }
         
         show_len = 40;
-        ret = gup_burn_fw_boot(i2c_connect_client);
+        ret = gup_burn_fw_boot(gtp_i2c_connect_client);
         if(FAIL == ret)
         {
             GTP_ERROR("[update_proc]burn bootloader firmware fail.");
@@ -2377,7 +2382,7 @@
         }
         show_len = 50;
         
-        ret = gup_burn_fw_boot_isp(i2c_connect_client);
+        ret = gup_burn_fw_boot_isp(gtp_i2c_connect_client);
         if (FAIL == ret)
         {
             GTP_ERROR("[update_proc]burn boot_isp firmware fail.");
@@ -2385,7 +2390,7 @@
         }
         
         show_len = 60;
-        ret = gup_burn_fw_link(i2c_connect_client);
+        ret = gup_burn_fw_link(gtp_i2c_connect_client);
         if (FAIL == ret)
         {
             GTP_ERROR("[update_proc]burn link firmware fail.");
@@ -2393,7 +2398,7 @@
         }
         
         show_len = 70;
-        ret = gup_burn_fw_gwake(i2c_connect_client);
+        ret = gup_burn_fw_gwake(gtp_i2c_connect_client);
         if (FAIL == ret)
         {
             GTP_ERROR("[update_proc]burn app_code firmware fail.");
@@ -2401,7 +2406,7 @@
         }       
         show_len = 80;
         
-        ret = gup_burn_fw_finish(i2c_connect_client);
+        ret = gup_burn_fw_finish(gtp_i2c_connect_client);
         if (FAIL == ret)
         {
             GTP_ERROR("[update_proc]burn finish fail.");
@@ -2439,7 +2444,7 @@
         else
         {
             GTP_DEBUG("[update_proc]send config.");
-            ret = gtp_send_cfg(i2c_connect_client);
+            ret = gtp_send_cfg(gtp_i2c_connect_client);
             if (ret < 0)
             {
                 GTP_ERROR("[update_proc]send config fail.");
@@ -2472,7 +2477,7 @@
         gup_search_file(AUTO_SEARCH_CFG);
         if (got_file_flag & CFG_FILE_READY)
         {
-            ret = gup_update_config(i2c_connect_client);
+            ret = gup_update_config(gtp_i2c_connect_client);
             if(ret <= 0)
             {
                 GTP_ERROR("Update config failed.");
@@ -2495,6 +2500,7 @@
         return FAIL;
     }
 }
+#endif
 
 #if GTP_AUTO_UPDATE
 u8 gup_init_update_proc(struct goodix_ts_data *ts)
@@ -2570,16 +2576,16 @@
 
 #if GTP_COMPATIBLE_MODE
 
-u8 i2c_opr_buf[GTP_ADDR_LENGTH + FL_PACK_SIZE] = {0};
-u8 chk_cmp_buf[FL_PACK_SIZE] = {0};
+static u8 i2c_opr_buf[GTP_ADDR_LENGTH + FL_PACK_SIZE] = {0};
+static u8 chk_cmp_buf[FL_PACK_SIZE] = {0};
 
-extern s32 gtp_fw_startup(struct i2c_client *client);
+//extern s32 gtp_fw_startup(struct i2c_client *client);
 static u8 gup_download_fw_dsp(struct i2c_client *client, u8 dwn_mode);
 static s32 gup_burn_fw_proc(struct i2c_client *client, u16 start_addr, s32 start_index, s32 burn_len);
 static s32 gup_check_and_repair(struct i2c_client *client, u16 start_addr, s32 start_index, s32 chk_len);
 
 
-u8 gup_check_fs_mounted(char *path_name)
+u8 gtp_gup_check_fs_mounted(char *path_name)
 {
     struct path root_path;
     struct path path;
@@ -2617,7 +2623,7 @@
 #endif
 }
 
-s32 i2c_write_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len)
+s32 gtp_i2c_write_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len)
 {
     s32 ret = 0;
     s32 write_bytes = 0;
@@ -2658,7 +2664,7 @@
     return 1;
 }
 
-s32 i2c_read_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len)
+s32 gtp_i2c_read_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len)
 {
     s32 ret = 0;
     s32 read_bytes = 0;
@@ -2705,11 +2711,11 @@
 static void gup_bit_write(s32 addr, s32 bit, s32 val)
 {
     u8 buf;
-    i2c_read_bytes(i2c_connect_client, addr, &buf, 1);
+    gtp_i2c_read_bytes(gtp_i2c_connect_client, addr, &buf, 1);
 
     buf = (buf & (~((u8)1 << bit))) | ((u8)val << bit);
 
-    i2c_write_bytes(i2c_connect_client, addr, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, addr, &buf, 1);
 }
 
 static void gup_clk_count_init(s32 bCh, s32 bCNT)
@@ -2722,13 +2728,13 @@
     gup_bit_write(_fRW_MISCTL__MEA, 1, 1);
     //_bRW_MISCTL__MEA_MODE = 0; //Pulse mode
     buf = 0;
-    i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__MEA_MODE, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, _bRW_MISCTL__MEA_MODE, &buf, 1);
     //_bRW_MISCTL__MEA_SRCSEL = 8 + bCh; //From GIO1
     buf = 8 + bCh;
-    i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__MEA_SRCSEL, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, _bRW_MISCTL__MEA_SRCSEL, &buf, 1);
     //_wRW_MISCTL__MEA_MAX_NUM = bCNT; //Set the Measure Counts = 1
     buf = bCNT;
-    i2c_write_bytes(i2c_connect_client, _wRW_MISCTL__MEA_MAX_NUM, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, _wRW_MISCTL__MEA_MAX_NUM, &buf, 1);
     //_fRW_MISCTL__MEA_CLR = 0; //Frequency measure not clear
     gup_bit_write(_fRW_MISCTL__MEA, 1, 0);
     //_fRW_MISCTL__MEA_EN = 1;
@@ -2743,7 +2749,7 @@
 
     while (ready == 0) //Wait for measurement complete
     {
-        i2c_read_bytes(i2c_connect_client, _bRO_MISCTL__MEA_RDY, buf, 1);
+        gtp_i2c_read_bytes(gtp_i2c_connect_client, _bRO_MISCTL__MEA_RDY, buf, 1);
         ready = buf[0];
     }
 
@@ -2751,7 +2757,7 @@
 
     //_fRW_MISCTL__MEA_EN = 0;
     gup_bit_write(_fRW_MISCTL__MEA, 0, 0);
-    i2c_read_bytes(i2c_connect_client, _dRO_MISCTL__MEA_VAL, buf, 4);
+    gtp_i2c_read_bytes(gtp_i2c_connect_client, _dRO_MISCTL__MEA_VAL, buf, 4);
     GTP_DEBUG("Clk_count 0: %2X", buf[0]);
     GTP_DEBUG("Clk_count 1: %2X", buf[1]);
     GTP_DEBUG("Clk_count 2: %2X", buf[2]);
@@ -2761,23 +2767,23 @@
     GTP_INFO("Clk_count : %d", temp);
     return temp;
 }
-u8 gup_clk_dac_setting(int dac)
+static u8 gup_clk_dac_setting(int dac)
 {
     s8 buf1, buf2;
     
-    i2c_read_bytes(i2c_connect_client, _wRW_MISCTL__RG_DMY, &buf1, 1);
-    i2c_read_bytes(i2c_connect_client, _bRW_MISCTL__RG_OSC_CALIB, &buf2, 1);
+    gtp_i2c_read_bytes(gtp_i2c_connect_client, _wRW_MISCTL__RG_DMY, &buf1, 1);
+    gtp_i2c_read_bytes(gtp_i2c_connect_client, _bRW_MISCTL__RG_OSC_CALIB, &buf2, 1);
 
     buf1 = (buf1 & 0xFFCF) | ((dac & 0x03) << 4);
     buf2 = (dac >> 2) & 0x3f;
 
-    i2c_write_bytes(i2c_connect_client, _wRW_MISCTL__RG_DMY, &buf1, 1);
-    i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__RG_OSC_CALIB, &buf2, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, _wRW_MISCTL__RG_DMY, &buf1, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, _bRW_MISCTL__RG_OSC_CALIB, &buf2, 1);
     
     return 0;
 }
 
-static u8 gup_clk_calibration_pin_select(s32 bCh)
+static u8 gtp_gup_clk_calibration_pin_select(s32 bCh)
 {
     s32 i2c_addr;
 
@@ -2822,6 +2828,9 @@
         case 9:
             i2c_addr = _fRW_MISCTL__GIO9;
             break;
+
+        default:
+            return -1;
     }
 
     gup_bit_write(i2c_addr, 1, 0);
@@ -2829,12 +2838,12 @@
     return 0;
 }
 
-void gup_output_pulse(int t)
+static void gup_output_pulse(int t)
 {
 	unsigned long flags;
 	struct goodix_ts_data *ts;
 
-	ts = i2c_get_clientdata(i2c_connect_client);
+	ts = i2c_get_clientdata(gtp_i2c_connect_client);
 
 	GTP_GPIO_OUTPUT(ts->irq_pin, 0);
 	msleep(10);
@@ -2861,13 +2870,13 @@
     gup_bit_write(_rRW_MISCTL__ANA_RXADC_B0_, 5, 0);
     //_bRW_MISCTL__RG_LDO_A18_PWD = 0; //DrvMISCTL_A18_PowerON
     buf = 0;
-    i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__RG_LDO_A18_PWD, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, _bRW_MISCTL__RG_LDO_A18_PWD, &buf, 1);
     //_bRW_MISCTL__RG_BG_PWD = 0; //DrvMISCTL_BG_PowerON
     buf = 0;
-    i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__RG_BG_PWD, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, _bRW_MISCTL__RG_BG_PWD, &buf, 1);
     //_bRW_MISCTL__RG_CLKGEN_PWD = 0; //DrvMISCTL_CLKGEN_PowerON
     buf = 0;
-    i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__RG_CLKGEN_PWD, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, _bRW_MISCTL__RG_CLKGEN_PWD, &buf, 1);
     //_fRW_MISCTL__RG_RXADC_PWD = 0; //DrvMISCTL_RX_ADC_PowerON
     gup_bit_write(_rRW_MISCTL__ANA_RXADC_B0_, 0, 0);
     //_fRW_MISCTL__RG_RXADC_REF_PWD = 0; //DrvMISCTL_RX_ADCREF_PowerON
@@ -2875,26 +2884,26 @@
     //gup_clk_dac_setting(60);
     //_bRW_MISCTL__OSC_CK_SEL = 1;;
     buf = 1;
-    i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__OSC_CK_SEL, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, _bRW_MISCTL__OSC_CK_SEL, &buf, 1);
 }
 
-s32 gup_clk_calibration(void)
+s32 gtp_gup_clk_calibration(void)
 {
     u8 buf;
     //u8 trigger;
     s32 i;
-    struct timeval start, end;
+    //struct timeval start, end;
     s32 count;
-    s32 count_ref;
-    s32 sec;
-    s32 usec;
+    //s32 count_ref;
+    //s32 sec;
+    //s32 usec;
     //unsigned long flags;
     struct goodix_ts_data *ts;
 
-	ts = i2c_get_clientdata(i2c_connect_client);
+	ts = i2c_get_clientdata(gtp_i2c_connect_client);
 
     buf = 0x0C; // hold ss51 and dsp
-    i2c_write_bytes(i2c_connect_client, _rRW_MISCTL__SWRST_B0_, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, _rRW_MISCTL__SWRST_B0_, &buf, 1);
 
     //_fRW_MISCTL__CLK_BIAS = 0; //disable clock bias
     gup_bit_write(_rRW_MISCTL_RG_DMY83, 7, 0);
@@ -2906,12 +2915,12 @@
     gup_bit_write(_rRW_MISCTL__GIO1CTL_B1_, 1, 0);
 
     //buf = 0x00;
-    //i2c_write_bytes(i2c_connect_client, _rRW_MISCTL__SWRST_B0_, &buf, 1);
+    //gtp_i2c_write_bytes(gtp_i2c_connect_client, _rRW_MISCTL__SWRST_B0_, &buf, 1);
     //msleep(1000);
 
     GTP_INFO("CLK calibration GO");
     gup_sys_clk_init();
-    gup_clk_calibration_pin_select(1);//use GIO1 to do the calibration
+    gtp_gup_clk_calibration_pin_select(1);//use GIO1 to do the calibration
 
 	GTP_GPIO_OUTPUT(ts->irq_pin, 0);
  
@@ -2928,7 +2937,7 @@
         gup_clk_dac_setting(i);
         gup_clk_count_init(1, CLK_AVG_TIME);
 
-    #if 0
+    #if 1
         gup_output_pulse(PULSE_LENGTH);
         count = gup_clk_count_get();
   
@@ -2975,24 +2984,24 @@
 
     //clk_dac = i;
 
-    gtp_reset_guitar(i2c_connect_client, 20);
+    gtp_reset_guitar(gtp_i2c_connect_client, 20);
 
 #if 0//for debug
     //-- ouput clk to GPIO 4
     buf = 0x00;
-    i2c_write_bytes(i2c_connect_client, 0x41FA, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, 0x41FA, &buf, 1);
     buf = 0x00;
-    i2c_write_bytes(i2c_connect_client, 0x4104, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, 0x4104, &buf, 1);
     buf = 0x00;
-    i2c_write_bytes(i2c_connect_client, 0x4105, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, 0x4105, &buf, 1);
     buf = 0x00;
-    i2c_write_bytes(i2c_connect_client, 0x4106, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, 0x4106, &buf, 1);
     buf = 0x01;
-    i2c_write_bytes(i2c_connect_client, 0x4107, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, 0x4107, &buf, 1);
     buf = 0x06;
-    i2c_write_bytes(i2c_connect_client, 0x41F8, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, 0x41F8, &buf, 1);
     buf = 0x02;
-    i2c_write_bytes(i2c_connect_client, 0x41F9, &buf, 1);
+    gtp_i2c_write_bytes(gtp_i2c_connect_client, 0x41F9, &buf, 1);
 #endif
 
 	/*GTP_GPIO_AS_INT(ts->irq_pin);*/
@@ -3002,7 +3011,7 @@
 
 
 
-s32 gup_hold_ss51_dsp(struct i2c_client *client)
+static s32 gup_hold_ss51_dsp(struct i2c_client *client)
 {
     s32 ret = -1;
     s32 retry = 0;
@@ -3083,7 +3092,7 @@
     return SUCCESS;
 }
 
-s32 gup_enter_update_mode_fl(struct i2c_client *client)
+static s32 gup_enter_update_mode_fl(struct i2c_client *client)
 {
     s32 ret = -1;
     //s32 retry = 0;
@@ -3215,7 +3224,7 @@
     
     GTP_DEBUG("burn firmware: 0x%04X, %d bytes, start_index: 0x%04X", start_addr, burn_len, start_index);
     
-    ret = i2c_write_bytes(client, start_addr, (u8*)&gtp_default_FW_fl[FW_HEAD_LENGTH + start_index], burn_len);
+    ret = gtp_i2c_write_bytes(client, start_addr, (u8*)&gtp_default_FW_fl[FW_HEAD_LENGTH + start_index], burn_len);
     if (ret < 0)
     {
         GTP_ERROR("burn 0x%04X, %d bytes failed!", start_addr, burn_len);
@@ -3248,7 +3257,7 @@
 			GTP_ERROR("Check failed, buffer overflow\n");
 			break;
 		}
-        ret = i2c_read_bytes(client, cmp_addr, chk_cmp_buf, cmp_len);
+        ret = gtp_i2c_read_bytes(client, cmp_addr, chk_cmp_buf, cmp_len);
         if (ret < 0)
         {
             chk_fail = 1;
@@ -3259,7 +3268,7 @@
             if (chk_cmp_buf[i] != gtp_default_FW_fl[FW_HEAD_LENGTH + start_index +i])
             {
                 chk_fail = 1;
-                i2c_write_bytes(client, cmp_addr+i, &gtp_default_FW_fl[FW_HEAD_LENGTH + start_index + i], cmp_len-i);
+                gtp_i2c_write_bytes(client, cmp_addr+i, &gtp_default_FW_fl[FW_HEAD_LENGTH + start_index + i], cmp_len-i);
                 GTP_ERROR("Check failed index: %d(%d != %d), redownload chuck", i, chk_cmp_buf[i], 
                         gtp_default_FW_fl[FW_HEAD_LENGTH + start_index +i]);
                 break;
@@ -3373,7 +3382,7 @@
     s32 ret = 0;
     s32 i = 0;
     s32 timeout = 0;
-    struct goodix_ts_data *ts = i2c_get_clientdata(i2c_connect_client);
+    struct goodix_ts_data *ts = i2c_get_clientdata(gtp_i2c_connect_client);
     
     if (!memcmp(path, "update", 6))
     {
@@ -3512,14 +3521,14 @@
     return ret;
 }
 
-s32 gup_fw_download_proc(void *dir, u8 dwn_mode)
+s32 gtp_gup_fw_download_proc(void *dir, u8 dwn_mode)
 {
     s32 ret = 0;
     u8  retry = 0;
     st_fw_head fw_head;
     struct goodix_ts_data *ts;
     
-    ts = i2c_get_clientdata(i2c_connect_client);
+    ts = i2c_get_clientdata(gtp_i2c_connect_client);
     if (NULL == dir)
     {
         if(GTP_FL_FW_BURN == dwn_mode)       // GT9XXF firmware burn mode
@@ -3543,7 +3552,7 @@
     total_len = 100;
     show_len = 0;
     
-    ret = gup_check_update_file_fl(i2c_connect_client, &fw_head, (char *)dir);
+    ret = gup_check_update_file_fl(gtp_i2c_connect_client, &fw_head, (char *)dir);
     show_len = 10;
     
     if (FAIL == ret)
@@ -3570,7 +3579,7 @@
 #endif
     }
     
-    ret = gup_enter_update_mode_fl(i2c_connect_client);
+    ret = gup_enter_update_mode_fl(gtp_i2c_connect_client);
     show_len = 20;
     if (FAIL == ret)
     {
@@ -3580,7 +3589,7 @@
 
     while (retry++ < 5)
     {
-        ret = gup_download_fw_ss51(i2c_connect_client, dwn_mode);
+        ret = gup_download_fw_ss51(gtp_i2c_connect_client, dwn_mode);
         show_len = 60;
         if (FAIL == ret)
         {
@@ -3588,7 +3597,7 @@
             continue;
         }
 
-        ret = gup_download_fw_dsp(i2c_connect_client, dwn_mode);
+        ret = gup_download_fw_dsp(gtp_i2c_connect_client, dwn_mode);
         show_len = 80;
         if (FAIL == ret)
         {
diff --git a/kernel/drivers/input/touchscreen/raspberrypi-ts.c b/kernel/drivers/input/touchscreen/raspberrypi-ts.c
index ef6aaed..45c575d 100644
--- a/kernel/drivers/input/touchscreen/raspberrypi-ts.c
+++ b/kernel/drivers/input/touchscreen/raspberrypi-ts.c
@@ -134,7 +134,7 @@
 		return -ENOENT;
 	}
 
-	fw = rpi_firmware_get(fw_node);
+	fw = devm_rpi_firmware_get(&pdev->dev, fw_node);
 	of_node_put(fw_node);
 	if (!fw)
 		return -EPROBE_DEFER;
@@ -160,7 +160,6 @@
 	touchbuf = (u32)ts->fw_regs_phys;
 	error = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF,
 				      &touchbuf, sizeof(touchbuf));
-
 	if (error || touchbuf != 0) {
 		dev_warn(dev, "Failed to set touchbuf, %d\n", error);
 		return error;
diff --git a/kernel/drivers/interconnect/core.c b/kernel/drivers/interconnect/core.c
index ceb6cdc..7db6d0f 100644
--- a/kernel/drivers/interconnect/core.c
+++ b/kernel/drivers/interconnect/core.c
@@ -850,6 +850,10 @@
 
 	mutex_unlock(&icc_lock);
 
+	if (!node)
+		return;
+
+	kfree(node->links);
 	kfree(node);
 }
 EXPORT_SYMBOL_GPL(icc_node_destroy);
diff --git a/kernel/drivers/interconnect/qcom/osm-l3.c b/kernel/drivers/interconnect/qcom/osm-l3.c
index 695f287..08a282d 100644
--- a/kernel/drivers/interconnect/qcom/osm-l3.c
+++ b/kernel/drivers/interconnect/qcom/osm-l3.c
@@ -258,7 +258,7 @@
 	qnodes = desc->nodes;
 	num_nodes = desc->num_nodes;
 
-	data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
+	data = devm_kzalloc(&pdev->dev, struct_size(data, nodes, num_nodes), GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
 
diff --git a/kernel/drivers/iommu/amd/amd_iommu_types.h b/kernel/drivers/iommu/amd/amd_iommu_types.h
index 690c597..4a8791e 100644
--- a/kernel/drivers/iommu/amd/amd_iommu_types.h
+++ b/kernel/drivers/iommu/amd/amd_iommu_types.h
@@ -897,8 +897,8 @@
 	 */
 	struct irq_cfg *cfg;
 	int ga_vector;
-	int ga_root_ptr;
-	int ga_tag;
+	u64 ga_root_ptr;
+	u32 ga_tag;
 };
 
 struct amd_irte_ops {
diff --git a/kernel/drivers/iommu/amd/init.c b/kernel/drivers/iommu/amd/init.c
index e988f6f..603f625 100644
--- a/kernel/drivers/iommu/amd/init.c
+++ b/kernel/drivers/iommu/amd/init.c
@@ -85,6 +85,10 @@
 #define ACPI_DEVFLAG_ATSDIS             0x10000000
 
 #define LOOP_TIMEOUT	2000000
+
+#define IVRS_GET_SBDF_ID(seg, bus, dev, fd)	(((seg & 0xffff) << 16) | ((bus & 0xff) << 8) \
+						 | ((dev & 0x1f) << 3) | (fn & 0x7))
+
 /*
  * ACPI table definitions
  *
@@ -3046,24 +3050,32 @@
 
 static int __init parse_ivrs_ioapic(char *str)
 {
-	unsigned int bus, dev, fn;
-	int ret, id, i;
-	u16 devid;
+	u32 seg = 0, bus, dev, fn;
+	int id, i;
+	u32 devid;
 
-	ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
+	if (sscanf(str, "=%d@%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
+	    sscanf(str, "=%d@%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5)
+		goto found;
 
-	if (ret != 4) {
-		pr_err("Invalid command line: ivrs_ioapic%s\n", str);
-		return 1;
+	if (sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
+	    sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) {
+		pr_warn("ivrs_ioapic%s option format deprecated; use ivrs_ioapic=%d@%04x:%02x:%02x.%d instead\n",
+			str, id, seg, bus, dev, fn);
+		goto found;
 	}
 
+	pr_err("Invalid command line: ivrs_ioapic%s\n", str);
+	return 1;
+
+found:
 	if (early_ioapic_map_size == EARLY_MAP_SIZE) {
 		pr_err("Early IOAPIC map overflow - ignoring ivrs_ioapic%s\n",
 			str);
 		return 1;
 	}
 
-	devid = ((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7);
+	devid = IVRS_GET_SBDF_ID(seg, bus, dev, fn);
 
 	cmdline_maps			= true;
 	i				= early_ioapic_map_size++;
@@ -3076,24 +3088,32 @@
 
 static int __init parse_ivrs_hpet(char *str)
 {
-	unsigned int bus, dev, fn;
-	int ret, id, i;
-	u16 devid;
+	u32 seg = 0, bus, dev, fn;
+	int id, i;
+	u32 devid;
 
-	ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
+	if (sscanf(str, "=%d@%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
+	    sscanf(str, "=%d@%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5)
+		goto found;
 
-	if (ret != 4) {
-		pr_err("Invalid command line: ivrs_hpet%s\n", str);
-		return 1;
+	if (sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
+	    sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) {
+		pr_warn("ivrs_hpet%s option format deprecated; use ivrs_hpet=%d@%04x:%02x:%02x.%d instead\n",
+			str, id, seg, bus, dev, fn);
+		goto found;
 	}
 
+	pr_err("Invalid command line: ivrs_hpet%s\n", str);
+	return 1;
+
+found:
 	if (early_hpet_map_size == EARLY_MAP_SIZE) {
 		pr_err("Early HPET map overflow - ignoring ivrs_hpet%s\n",
 			str);
 		return 1;
 	}
 
-	devid = ((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7);
+	devid = IVRS_GET_SBDF_ID(seg, bus, dev, fn);
 
 	cmdline_maps			= true;
 	i				= early_hpet_map_size++;
@@ -3104,19 +3124,53 @@
 	return 1;
 }
 
+#define ACPIID_LEN (ACPIHID_UID_LEN + ACPIHID_HID_LEN)
+
 static int __init parse_ivrs_acpihid(char *str)
 {
-	u32 bus, dev, fn;
-	char *hid, *uid, *p;
-	char acpiid[ACPIHID_UID_LEN + ACPIHID_HID_LEN] = {0};
-	int ret, i;
+	u32 seg = 0, bus, dev, fn;
+	char *hid, *uid, *p, *addr;
+	char acpiid[ACPIID_LEN] = {0};
+	int i;
 
-	ret = sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid);
-	if (ret != 4) {
-		pr_err("Invalid command line: ivrs_acpihid(%s)\n", str);
-		return 1;
+	addr = strchr(str, '@');
+	if (!addr) {
+		addr = strchr(str, '=');
+		if (!addr)
+			goto not_found;
+
+		++addr;
+
+		if (strlen(addr) > ACPIID_LEN)
+			goto not_found;
+
+		if (sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid) == 4 ||
+		    sscanf(str, "[%x:%x:%x.%x]=%s", &seg, &bus, &dev, &fn, acpiid) == 5) {
+			pr_warn("ivrs_acpihid%s option format deprecated; use ivrs_acpihid=%s@%04x:%02x:%02x.%d instead\n",
+				str, acpiid, seg, bus, dev, fn);
+			goto found;
+		}
+		goto not_found;
 	}
 
+	/* We have the '@', make it the terminator to get just the acpiid */
+	*addr++ = 0;
+
+	if (strlen(str) > ACPIID_LEN + 1)
+		goto not_found;
+
+	if (sscanf(str, "=%s", acpiid) != 1)
+		goto not_found;
+
+	if (sscanf(addr, "%x:%x.%x", &bus, &dev, &fn) == 3 ||
+	    sscanf(addr, "%x:%x:%x.%x", &seg, &bus, &dev, &fn) == 4)
+		goto found;
+
+not_found:
+	pr_err("Invalid command line: ivrs_acpihid%s\n", str);
+	return 1;
+
+found:
 	p = acpiid;
 	hid = strsep(&p, ":");
 	uid = p;
@@ -3126,11 +3180,17 @@
 		return 1;
 	}
 
+	/*
+	 * Ignore leading zeroes after ':', so e.g., AMDI0095:00
+	 * will match AMDI0095:0 in the second strcmp in acpi_dev_hid_uid_match
+	 */
+	while (*uid == '0' && *(uid + 1))
+		uid++;
+
 	i = early_acpihid_map_size++;
 	memcpy(early_acpihid_map[i].hid, hid, strlen(hid));
 	memcpy(early_acpihid_map[i].uid, uid, strlen(uid));
-	early_acpihid_map[i].devid =
-		((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7);
+	early_acpihid_map[i].devid = IVRS_GET_SBDF_ID(seg, bus, dev, fn);
 	early_acpihid_map[i].cmd_line	= true;
 
 	return 1;
diff --git a/kernel/drivers/iommu/amd/iommu.c b/kernel/drivers/iommu/amd/iommu.c
index f216a86..0a061a1 100644
--- a/kernel/drivers/iommu/amd/iommu.c
+++ b/kernel/drivers/iommu/amd/iommu.c
@@ -3914,8 +3914,7 @@
 	struct irte_ga *entry = (struct irte_ga *) ir_data->entry;
 	u64 valid;
 
-	if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) ||
-	    !entry || entry->lo.fields_vapic.guest_mode)
+	if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) || !entry)
 		return 0;
 
 	valid = entry->lo.fields_vapic.valid;
diff --git a/kernel/drivers/iommu/amd/iommu_v2.c b/kernel/drivers/iommu/amd/iommu_v2.c
index fb61bdc..16776e3 100644
--- a/kernel/drivers/iommu/amd/iommu_v2.c
+++ b/kernel/drivers/iommu/amd/iommu_v2.c
@@ -587,6 +587,7 @@
 	put_device_state(dev_state);
 
 out:
+	pci_dev_put(pdev);
 	return ret;
 }
 
diff --git a/kernel/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/kernel/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 2b24dfa..6868086 100644
--- a/kernel/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/kernel/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -162,6 +162,18 @@
 	q->cons = Q_OVF(q->cons) | Q_WRP(q, cons) | Q_IDX(q, cons);
 }
 
+static void queue_sync_cons_ovf(struct arm_smmu_queue *q)
+{
+	struct arm_smmu_ll_queue *llq = &q->llq;
+
+	if (likely(Q_OVF(llq->prod) == Q_OVF(llq->cons)))
+		return;
+
+	llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
+		      Q_IDX(llq, llq->cons);
+	queue_sync_cons_out(q);
+}
+
 static int queue_sync_prod_in(struct arm_smmu_queue *q)
 {
 	u32 prod;
@@ -1380,8 +1392,7 @@
 	} while (!queue_empty(llq));
 
 	/* Sync our overflow flag, as we believe we're up to speed */
-	llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
-		    Q_IDX(llq, llq->cons);
+	queue_sync_cons_ovf(q);
 	return IRQ_HANDLED;
 }
 
@@ -1439,9 +1450,7 @@
 	} while (!queue_empty(llq));
 
 	/* Sync our overflow flag, as we believe we're up to speed */
-	llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
-		      Q_IDX(llq, llq->cons);
-	queue_sync_cons_out(q);
+	queue_sync_cons_ovf(q);
 	return IRQ_HANDLED;
 }
 
diff --git a/kernel/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/kernel/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index a48bb51..7246b55 100644
--- a/kernel/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/kernel/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -199,13 +199,27 @@
 
 static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
 {
-	unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1);
 	struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+	unsigned int last_s2cr;
 	u32 reg;
 	u32 smr;
 	int i;
 
 	/*
+	 * Some platforms support more than the Arm SMMU architected maximum of
+	 * 128 stream matching groups. For unknown reasons, the additional
+	 * groups don't exhibit the same behavior as the architected registers,
+	 * so limit the groups to 128 until the behavior is fixed for the other
+	 * groups.
+	 */
+	if (smmu->num_mapping_groups > 128) {
+		dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n");
+		smmu->num_mapping_groups = 128;
+	}
+
+	last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1);
+
+	/*
 	 * With some firmware versions writes to S2CR of type FAULT are
 	 * ignored, and writing BYPASS will end up written as FAULT in the
 	 * register. Perform a write to S2CR to detect if this is the case and
diff --git a/kernel/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/kernel/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 3864111..373cf0d 100644
--- a/kernel/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/kernel/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -275,6 +275,13 @@
 			ctx->secure_init = true;
 		}
 
+		/* Disable context bank before programming */
+		iommu_writel(ctx, ARM_SMMU_CB_SCTLR, 0);
+
+		/* Clear context bank fault address fault status registers */
+		iommu_writel(ctx, ARM_SMMU_CB_FAR, 0);
+		iommu_writel(ctx, ARM_SMMU_CB_FSR, ARM_SMMU_FSR_FAULT);
+
 		/* TTBRs */
 		iommu_writeq(ctx, ARM_SMMU_CB_TTBR0,
 				pgtbl_cfg.arm_lpae_s1_cfg.ttbr |
diff --git a/kernel/drivers/iommu/fsl_pamu.c b/kernel/drivers/iommu/fsl_pamu.c
index b9a974d..25689bd 100644
--- a/kernel/drivers/iommu/fsl_pamu.c
+++ b/kernel/drivers/iommu/fsl_pamu.c
@@ -1122,7 +1122,7 @@
 		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;
 		}
 	}
 
diff --git a/kernel/drivers/iommu/intel/pasid.c b/kernel/drivers/iommu/intel/pasid.c
index 86fd49a..9b24e82 100644
--- a/kernel/drivers/iommu/intel/pasid.c
+++ b/kernel/drivers/iommu/intel/pasid.c
@@ -24,7 +24,6 @@
 /*
  * Intel IOMMU system wide PASID name space:
  */
-static DEFINE_SPINLOCK(pasid_lock);
 u32 intel_pasid_max_id = PASID_MAX;
 
 int vcmd_alloc_pasid(struct intel_iommu *iommu, u32 *pasid)
@@ -187,6 +186,9 @@
 attach_out:
 	device_attach_pasid_table(info, pasid_table);
 
+	if (!ecap_coherent(info->iommu->ecap))
+		clflush_cache_range(pasid_table->table, (1 << order) * PAGE_SIZE);
+
 	return 0;
 }
 
@@ -259,19 +261,29 @@
 	dir_index = pasid >> PASID_PDE_SHIFT;
 	index = pasid & PASID_PTE_MASK;
 
-	spin_lock(&pasid_lock);
+retry:
 	entries = get_pasid_table_from_pde(&dir[dir_index]);
 	if (!entries) {
 		entries = alloc_pgtable_page(info->iommu->node);
-		if (!entries) {
-			spin_unlock(&pasid_lock);
+		if (!entries)
 			return NULL;
-		}
 
-		WRITE_ONCE(dir[dir_index].val,
-			   (u64)virt_to_phys(entries) | PASID_PTE_PRESENT);
+		/*
+		 * The pasid directory table entry won't be freed after
+		 * allocation. No worry about the race with free and
+		 * clear. However, this entry might be populated by others
+		 * while we are preparing it. Use theirs with a retry.
+		 */
+		if (cmpxchg64(&dir[dir_index].val, 0ULL,
+			      (u64)virt_to_phys(entries) | PASID_PTE_PRESENT)) {
+			free_pgtable_page(entries);
+			goto retry;
+		}
+		if (!ecap_coherent(info->iommu->ecap)) {
+			clflush_cache_range(entries, VTD_PAGE_SIZE);
+			clflush_cache_range(&dir[dir_index].val, sizeof(*dir));
+		}
 	}
-	spin_unlock(&pasid_lock);
 
 	return &entries[index];
 }
diff --git a/kernel/drivers/iommu/iommu.c b/kernel/drivers/iommu/iommu.c
index 793c528..64d7a37 100644
--- a/kernel/drivers/iommu/iommu.c
+++ b/kernel/drivers/iommu/iommu.c
@@ -201,13 +201,23 @@
 	const struct iommu_ops *ops = dev->bus->iommu_ops;
 	struct iommu_device *iommu_dev;
 	struct iommu_group *group;
+	static DEFINE_MUTEX(iommu_probe_device_lock);
 	int ret;
 
 	if (!ops)
 		return -ENODEV;
-
-	if (!dev_iommu_get(dev))
-		return -ENOMEM;
+	/*
+	 * Serialise to avoid races between IOMMU drivers registering in
+	 * parallel and/or the "replay" calls from ACPI/OF code via client
+	 * driver probe. Once the latter have been cleaned up we should
+	 * probably be able to use device_lock() here to minimise the scope,
+	 * but for now enforcing a simple global ordering is fine.
+	 */
+	mutex_lock(&iommu_probe_device_lock);
+	if (!dev_iommu_get(dev)) {
+		ret = -ENOMEM;
+		goto err_unlock;
+	}
 
 	if (!try_module_get(ops->owner)) {
 		ret = -EINVAL;
@@ -227,11 +237,14 @@
 		ret = PTR_ERR(group);
 		goto out_release;
 	}
-	iommu_group_put(group);
 
+	mutex_lock(&group->mutex);
 	if (group_list && !group->default_domain && list_empty(&group->entry))
 		list_add_tail(&group->entry, group_list);
+	mutex_unlock(&group->mutex);
+	iommu_group_put(group);
 
+	mutex_unlock(&iommu_probe_device_lock);
 	iommu_device_link(iommu_dev, dev);
 
 	return 0;
@@ -244,6 +257,9 @@
 
 err_free:
 	dev_iommu_free(dev);
+
+err_unlock:
+	mutex_unlock(&iommu_probe_device_lock);
 
 	return ret;
 }
@@ -1766,10 +1782,10 @@
 		return ret;
 
 	list_for_each_entry_safe(group, next, &group_list, entry) {
+		mutex_lock(&group->mutex);
+
 		/* Remove item from the list */
 		list_del_init(&group->entry);
-
-		mutex_lock(&group->mutex);
 
 		/* Try to allocate default domain */
 		probe_alloc_default_domain(bus, group);
diff --git a/kernel/drivers/iommu/mtk_iommu_v1.c b/kernel/drivers/iommu/mtk_iommu_v1.c
index 82ddfe9..2abbdd7 100644
--- a/kernel/drivers/iommu/mtk_iommu_v1.c
+++ b/kernel/drivers/iommu/mtk_iommu_v1.c
@@ -618,18 +618,34 @@
 	ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL,
 				     dev_name(&pdev->dev));
 	if (ret)
-		return ret;
+		goto out_clk_unprepare;
 
 	iommu_device_set_ops(&data->iommu, &mtk_iommu_ops);
 
 	ret = iommu_device_register(&data->iommu);
 	if (ret)
-		return ret;
+		goto out_sysfs_remove;
 
-	if (!iommu_present(&platform_bus_type))
-		bus_set_iommu(&platform_bus_type,  &mtk_iommu_ops);
+	if (!iommu_present(&platform_bus_type)) {
+		ret = bus_set_iommu(&platform_bus_type,  &mtk_iommu_ops);
+		if (ret)
+			goto out_dev_unreg;
+	}
 
-	return component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
+	ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
+	if (ret)
+		goto out_bus_set_null;
+	return ret;
+
+out_bus_set_null:
+	bus_set_iommu(&platform_bus_type, NULL);
+out_dev_unreg:
+	iommu_device_unregister(&data->iommu);
+out_sysfs_remove:
+	iommu_device_sysfs_remove(&data->iommu);
+out_clk_unprepare:
+	clk_disable_unprepare(data->bclk);
+	return ret;
 }
 
 static int mtk_iommu_remove(struct platform_device *pdev)
diff --git a/kernel/drivers/iommu/rockchip-iommu.c b/kernel/drivers/iommu/rockchip-iommu.c
index f6720d0..bb29a4e 100644
--- a/kernel/drivers/iommu/rockchip-iommu.c
+++ b/kernel/drivers/iommu/rockchip-iommu.c
@@ -1636,15 +1636,15 @@
 	for (i = 0; i < iommu->num_irq; i++) {
 		int irq = platform_get_irq(pdev, i);
 
-		if (irq < 0)
-			return irq;
+		if (irq < 0) {
+			err = irq;
+			goto err_pm_disable;
+		}
 
 		err = devm_request_irq(iommu->dev, irq, rk_iommu_irq,
 				       IRQF_SHARED, dev_name(dev), iommu);
-		if (err) {
-			pm_runtime_disable(dev);
-			goto err_remove_sysfs;
-		}
+		if (err)
+			goto err_pm_disable;
 	}
 
 skip_request_irq:
@@ -1657,6 +1657,8 @@
 	dma_set_mask_and_coherent(dev, rk_ops->dma_bit_mask);
 
 	return 0;
+err_pm_disable:
+	pm_runtime_disable(dev);
 err_remove_sysfs:
 	iommu_device_sysfs_remove(&iommu->iommu);
 err_put_group:
diff --git a/kernel/drivers/iommu/sun50i-iommu.c b/kernel/drivers/iommu/sun50i-iommu.c
index ea6db13..65aa30d 100644
--- a/kernel/drivers/iommu/sun50i-iommu.c
+++ b/kernel/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)
 
@@ -271,7 +272,7 @@
 	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;
@@ -512,7 +513,7 @@
 		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;
@@ -602,7 +603,6 @@
 	struct sun50i_iommu_domain *sun50i_domain;
 
 	if (type != IOMMU_DOMAIN_DMA &&
-	    type != IOMMU_DOMAIN_IDENTITY &&
 	    type != IOMMU_DOMAIN_UNMANAGED)
 		return NULL;
 
@@ -880,8 +880,8 @@
 
 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);
 
@@ -890,6 +890,9 @@
 		spin_unlock(&iommu->iommu_lock);
 		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,
@@ -904,8 +907,9 @@
 
 	iommu_write(iommu, IOMMU_INT_CLR_REG, status);
 
-	iommu_write(iommu, IOMMU_RESET_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);
 
diff --git a/kernel/drivers/irqchip/irq-alpine-msi.c b/kernel/drivers/irqchip/irq-alpine-msi.c
index ede02dc..1819bb1 100644
--- a/kernel/drivers/irqchip/irq-alpine-msi.c
+++ b/kernel/drivers/irqchip/irq-alpine-msi.c
@@ -199,6 +199,7 @@
 	}
 
 	gic_domain = irq_find_host(gic_node);
+	of_node_put(gic_node);
 	if (!gic_domain) {
 		pr_err("Failed to find the GIC domain\n");
 		return -ENXIO;
diff --git a/kernel/drivers/irqchip/irq-aspeed-vic.c b/kernel/drivers/irqchip/irq-aspeed-vic.c
index 6567ed7..58717cd 100644
--- a/kernel/drivers/irqchip/irq-aspeed-vic.c
+++ b/kernel/drivers/irqchip/irq-aspeed-vic.c
@@ -71,7 +71,7 @@
 	writel(0, vic->base + AVIC_INT_SELECT);
 	writel(0, vic->base + AVIC_INT_SELECT + 4);
 
-	/* Some interrupts have a programable high/low level trigger
+	/* Some interrupts have a programmable high/low level trigger
 	 * (4 GPIO direct inputs), for now we assume this was configured
 	 * by firmware. We read which ones are edge now.
 	 */
@@ -203,7 +203,7 @@
 	}
 	vic->base = regs;
 
-	/* Initialize soures, all masked */
+	/* Initialize sources, all masked */
 	vic_init_hw(vic);
 
 	/* Ready to receive interrupts */
diff --git a/kernel/drivers/irqchip/irq-bcm6345-l1.c b/kernel/drivers/irqchip/irq-bcm6345-l1.c
index 1bd0621..4827a11 100644
--- a/kernel/drivers/irqchip/irq-bcm6345-l1.c
+++ b/kernel/drivers/irqchip/irq-bcm6345-l1.c
@@ -82,6 +82,7 @@
 };
 
 struct bcm6345_l1_cpu {
+	struct bcm6345_l1_chip	*intc;
 	void __iomem		*map_base;
 	unsigned int		parent_irq;
 	u32			enable_cache[];
@@ -115,16 +116,10 @@
 
 static void bcm6345_l1_irq_handle(struct irq_desc *desc)
 {
-	struct bcm6345_l1_chip *intc = irq_desc_get_handler_data(desc);
-	struct bcm6345_l1_cpu *cpu;
+	struct bcm6345_l1_cpu *cpu = irq_desc_get_handler_data(desc);
+	struct bcm6345_l1_chip *intc = cpu->intc;
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 	unsigned int idx;
-
-#ifdef CONFIG_SMP
-	cpu = intc->cpus[cpu_logical_map(smp_processor_id())];
-#else
-	cpu = intc->cpus[0];
-#endif
 
 	chained_irq_enter(chip, desc);
 
@@ -257,6 +252,7 @@
 	if (!cpu)
 		return -ENOMEM;
 
+	cpu->intc = intc;
 	cpu->map_base = ioremap(res.start, sz);
 	if (!cpu->map_base)
 		return -ENOMEM;
@@ -272,7 +268,7 @@
 		return -EINVAL;
 	}
 	irq_set_chained_handler_and_data(cpu->parent_irq,
-						bcm6345_l1_irq_handle, intc);
+						bcm6345_l1_irq_handle, cpu);
 
 	return 0;
 }
diff --git a/kernel/drivers/irqchip/irq-bcm7120-l2.c b/kernel/drivers/irqchip/irq-bcm7120-l2.c
index c7c9e97..1c2c5bd 100644
--- a/kernel/drivers/irqchip/irq-bcm7120-l2.c
+++ b/kernel/drivers/irqchip/irq-bcm7120-l2.c
@@ -273,7 +273,8 @@
 		flags |= IRQ_GC_BE_IO;
 
 	ret = irq_alloc_domain_generic_chips(data->domain, IRQS_PER_WORD, 1,
-				dn->full_name, handle_level_irq, clr, 0, flags);
+				dn->full_name, handle_level_irq, clr,
+				IRQ_LEVEL, flags);
 	if (ret) {
 		pr_err("failed to allocate generic irq chip\n");
 		goto out_free_domain;
@@ -309,7 +310,7 @@
 
 		if (data->can_wake) {
 			/* This IRQ chip can wake the system, set all
-			 * relevant child interupts in wake_enabled mask
+			 * relevant child interrupts in wake_enabled mask
 			 */
 			gc->wake_enabled = 0xffffffff;
 			gc->wake_enabled &= ~gc->unused;
diff --git a/kernel/drivers/irqchip/irq-brcmstb-l2.c b/kernel/drivers/irqchip/irq-brcmstb-l2.c
index cdd6a42..a4aee16 100644
--- a/kernel/drivers/irqchip/irq-brcmstb-l2.c
+++ b/kernel/drivers/irqchip/irq-brcmstb-l2.c
@@ -161,6 +161,7 @@
 					  *init_params)
 {
 	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	unsigned int set = 0;
 	struct brcmstb_l2_intc_data *data;
 	struct irq_chip_type *ct;
 	int ret;
@@ -208,9 +209,12 @@
 	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
 		flags |= IRQ_GC_BE_IO;
 
+	if (init_params->handler == handle_level_irq)
+		set |= IRQ_LEVEL;
+
 	/* Allocate a single Generic IRQ chip for this node */
 	ret = irq_alloc_domain_generic_chips(data->domain, 32, 1,
-			np->full_name, init_params->handler, clr, 0, flags);
+			np->full_name, init_params->handler, clr, set, flags);
 	if (ret) {
 		pr_err("failed to allocate generic irq chip\n");
 		goto out_free_domain;
diff --git a/kernel/drivers/irqchip/irq-csky-apb-intc.c b/kernel/drivers/irqchip/irq-csky-apb-intc.c
index 5a2ec43..ab91afa 100644
--- a/kernel/drivers/irqchip/irq-csky-apb-intc.c
+++ b/kernel/drivers/irqchip/irq-csky-apb-intc.c
@@ -176,7 +176,7 @@
 	writel(0x0, reg_base + GX_INTC_NEN63_32);
 
 	/*
-	 * Initial mask reg with all unmasked, because we only use enalbe reg
+	 * Initial mask reg with all unmasked, because we only use enable reg
 	 */
 	writel(0x0, reg_base + GX_INTC_NMASK31_00);
 	writel(0x0, reg_base + GX_INTC_NMASK63_32);
diff --git a/kernel/drivers/irqchip/irq-gic-common.c b/kernel/drivers/irqchip/irq-gic-common.c
index 7ce79b5..18dccc5 100644
--- a/kernel/drivers/irqchip/irq-gic-common.c
+++ b/kernel/drivers/irqchip/irq-gic-common.c
@@ -33,7 +33,13 @@
 			  const struct gic_quirk *quirks, void *data)
 {
 	for (; quirks->desc; quirks++) {
-		if (!of_device_is_compatible(np, quirks->compatible))
+		if (!quirks->compatible && !quirks->property)
+			continue;
+		if (quirks->compatible &&
+		    !of_device_is_compatible(np, quirks->compatible))
+			continue;
+		if (quirks->property &&
+		    !of_property_read_bool(np, quirks->property))
 			continue;
 		if (quirks->init(data))
 			pr_info("GIC: enabling workaround for %s\n",
@@ -45,7 +51,7 @@
 		void *data)
 {
 	for (; quirks->desc; quirks++) {
-		if (quirks->compatible)
+		if (quirks->compatible || quirks->property)
 			continue;
 		if (quirks->iidr != (quirks->mask & iidr))
 			continue;
@@ -122,7 +128,7 @@
 
 		amp_pri = 0;
 		for (j = 0; j < 4; j++) {
-			if (rockchip_amp_check_amp_irq(i + j)) {
+			if (rockchip_amp_need_init_amp_irq(i + j)) {
 				amp_pri |= rockchip_amp_get_irq_prio(i + j) <<
 					   (j * 8);
 			} else {
diff --git a/kernel/drivers/irqchip/irq-gic-common.h b/kernel/drivers/irqchip/irq-gic-common.h
index ccba8b0..b42572d 100644
--- a/kernel/drivers/irqchip/irq-gic-common.h
+++ b/kernel/drivers/irqchip/irq-gic-common.h
@@ -13,6 +13,7 @@
 struct gic_quirk {
 	const char *desc;
 	const char *compatible;
+	const char *property;
 	bool (*init)(void *data);
 	u32 iidr;
 	u32 mask;
diff --git a/kernel/drivers/irqchip/irq-gic-pm.c b/kernel/drivers/irqchip/irq-gic-pm.c
index 1337cec..8be7d13 100644
--- a/kernel/drivers/irqchip/irq-gic-pm.c
+++ b/kernel/drivers/irqchip/irq-gic-pm.c
@@ -104,7 +104,7 @@
 
 	pm_runtime_enable(dev);
 
-	ret = pm_runtime_get_sync(dev);
+	ret = pm_runtime_resume_and_get(dev);
 	if (ret < 0)
 		goto rpm_disable;
 
diff --git a/kernel/drivers/irqchip/irq-gic-v2m.c b/kernel/drivers/irqchip/irq-gic-v2m.c
index fbec07d..4116b48 100644
--- a/kernel/drivers/irqchip/irq-gic-v2m.c
+++ b/kernel/drivers/irqchip/irq-gic-v2m.c
@@ -371,7 +371,7 @@
 	 * the MSI data is the absolute value within the range from
 	 * spi_start to (spi_start + num_spis).
 	 *
-	 * Broadom NS2 GICv2m implementation has an erratum where the MSI data
+	 * Broadcom NS2 GICv2m implementation has an erratum where the MSI data
 	 * is 'spi_number - 32'
 	 *
 	 * Reading that register fails on the Graviton implementation
diff --git a/kernel/drivers/irqchip/irq-gic-v3-its.c b/kernel/drivers/irqchip/irq-gic-v3-its.c
index 5b73539..8f0b4a3 100644
--- a/kernel/drivers/irqchip/irq-gic-v3-its.c
+++ b/kernel/drivers/irqchip/irq-gic-v3-its.c
@@ -268,13 +268,23 @@
 	raw_spin_unlock_irqrestore(&vpe->vpe_lock, flags);
 }
 
+static struct irq_chip its_vpe_irq_chip;
+
 static int irq_to_cpuid_lock(struct irq_data *d, unsigned long *flags)
 {
-	struct its_vlpi_map *map = get_vlpi_map(d);
+	struct its_vpe *vpe = NULL;
 	int cpu;
 
-	if (map) {
-		cpu = vpe_to_cpuid_lock(map->vpe, flags);
+	if (d->chip == &its_vpe_irq_chip) {
+		vpe = irq_data_get_irq_chip_data(d);
+	} else {
+		struct its_vlpi_map *map = get_vlpi_map(d);
+		if (map)
+			vpe = map->vpe;
+	}
+
+	if (vpe) {
+		cpu = vpe_to_cpuid_lock(vpe, flags);
 	} else {
 		/* Physical LPIs are already locked via the irq_desc lock */
 		struct its_device *its_dev = irq_data_get_irq_chip_data(d);
@@ -288,10 +298,18 @@
 
 static void irq_to_cpuid_unlock(struct irq_data *d, unsigned long flags)
 {
-	struct its_vlpi_map *map = get_vlpi_map(d);
+	struct its_vpe *vpe = NULL;
 
-	if (map)
-		vpe_to_cpuid_unlock(map->vpe, flags);
+	if (d->chip == &its_vpe_irq_chip) {
+		vpe = irq_data_get_irq_chip_data(d);
+	} else {
+		struct its_vlpi_map *map = get_vlpi_map(d);
+		if (map)
+			vpe = map->vpe;
+	}
+
+	if (vpe)
+		vpe_to_cpuid_unlock(vpe, flags);
 }
 
 static struct its_collection *valid_col(struct its_collection *col)
@@ -1423,13 +1441,28 @@
 		cpu_relax();
 }
 
+static void __direct_lpi_inv(struct irq_data *d, u64 val)
+{
+	void __iomem *rdbase;
+	unsigned long flags;
+	int cpu;
+
+	/* Target the redistributor this LPI is currently routed to */
+	cpu = irq_to_cpuid_lock(d, &flags);
+	raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock);
+
+	rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base;
+	gic_write_lpir(val, rdbase + GICR_INVLPIR);
+	wait_for_syncr(rdbase);
+
+	raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock);
+	irq_to_cpuid_unlock(d, flags);
+}
+
 static void direct_lpi_inv(struct irq_data *d)
 {
 	struct its_vlpi_map *map = get_vlpi_map(d);
-	void __iomem *rdbase;
-	unsigned long flags;
 	u64 val;
-	int cpu;
 
 	if (map) {
 		struct its_device *its_dev = irq_data_get_irq_chip_data(d);
@@ -1443,15 +1476,7 @@
 		val = d->hwirq;
 	}
 
-	/* Target the redistributor this LPI is currently routed to */
-	cpu = irq_to_cpuid_lock(d, &flags);
-	raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock);
-	rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base;
-	gic_write_lpir(val, rdbase + GICR_INVLPIR);
-
-	wait_for_syncr(rdbase);
-	raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock);
-	irq_to_cpuid_unlock(d, flags);
+	__direct_lpi_inv(d, val);
 }
 
 static void lpi_update_config(struct irq_data *d, u8 clr, u8 set)
@@ -1493,7 +1518,7 @@
 	 *
 	 * Ideally, we'd issue a VMAPTI to set the doorbell to its LPI
 	 * value or to 1023, depending on the enable bit. But that
-	 * would be issueing a mapping for an /existing/ DevID+EventID
+	 * would be issuing a mapping for an /existing/ DevID+EventID
 	 * pair, which is UNPREDICTABLE. Instead, let's issue a VMOVI
 	 * to the /same/ vPE, using this opportunity to adjust the
 	 * doorbell. Mouahahahaha. We loves it, Precious.
@@ -3172,7 +3197,7 @@
 
 		/*
 		 * It's possible for CPU to receive VLPIs before it is
-		 * sheduled as a vPE, especially for the first CPU, and the
+		 * scheduled as a vPE, especially for the first CPU, and the
 		 * VLPI with INTID larger than 2^(IDbits+1) will be considered
 		 * as out of range and dropped by GIC.
 		 * So we initialize IDbits to known value to avoid VLPI drop.
@@ -3694,7 +3719,7 @@
 
 	/*
 	 * If all interrupts have been freed, start mopping the
-	 * floor. This is conditionned on the device not being shared.
+	 * floor. This is conditioned on the device not being shared.
 	 */
 	if (!its_dev->shared &&
 	    bitmap_empty(its_dev->event_map.lpi_map,
@@ -3999,18 +4024,10 @@
 {
 	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
 
-	if (gic_rdists->has_direct_lpi) {
-		void __iomem *rdbase;
-
-		/* Target the redistributor this VPE is currently known on */
-		raw_spin_lock(&gic_data_rdist_cpu(vpe->col_idx)->rd_lock);
-		rdbase = per_cpu_ptr(gic_rdists->rdist, vpe->col_idx)->rd_base;
-		gic_write_lpir(d->parent_data->hwirq, rdbase + GICR_INVLPIR);
-		wait_for_syncr(rdbase);
-		raw_spin_unlock(&gic_data_rdist_cpu(vpe->col_idx)->rd_lock);
-	} else {
+	if (gic_rdists->has_direct_lpi)
+		__direct_lpi_inv(d, d->parent_data->hwirq);
+	else
 		its_vpe_send_cmd(vpe, its_send_inv);
-	}
 }
 
 static void its_vpe_mask_irq(struct irq_data *d)
@@ -4272,7 +4289,7 @@
 {
 	/*
 	 * There is no notion of affinity for virtual SGIs, at least
-	 * not on the host (since they can only be targetting a vPE).
+	 * not on the host (since they can only be targeting a vPE).
 	 * Tell the kernel we've done whatever it asked for.
 	 */
 	irq_data_update_effective_affinity(d, mask_val);
@@ -4317,7 +4334,7 @@
 	/*
 	 * Locking galore! We can race against two different events:
 	 *
-	 * - Concurent vPE affinity change: we must make sure it cannot
+	 * - Concurrent vPE affinity change: we must make sure it cannot
 	 *   happen, or we'll talk to the wrong redistributor. This is
 	 *   identical to what happens with vLPIs.
 	 *
diff --git a/kernel/drivers/irqchip/irq-gic-v3.c b/kernel/drivers/irqchip/irq-gic-v3.c
index 6db1dbc..192a9b1 100644
--- a/kernel/drivers/irqchip/irq-gic-v3.c
+++ b/kernel/drivers/irqchip/irq-gic-v3.c
@@ -41,6 +41,7 @@
 
 #define FLAGS_WORKAROUND_GICR_WAKER_MSM8996	(1ULL << 0)
 #define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539	(1ULL << 1)
+#define FLAGS_WORKAROUND_MTK_GICR_SAVE		(1ULL << 2)
 
 #define GIC_IRQ_TYPE_PARTITION	(GIC_IRQ_TYPE_LPI + 1)
 
@@ -49,6 +50,8 @@
 	phys_addr_t		phys_base;
 	bool			single_redist;
 };
+
+static DEFINE_STATIC_KEY_FALSE(gic_arm64_2941627_erratum);
 
 static struct gic_chip_data gic_data __read_mostly;
 static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
@@ -541,9 +544,39 @@
 	gic_irq_set_prio(d, GICD_INT_DEF_PRI);
 }
 
+static bool gic_arm64_erratum_2941627_needed(struct irq_data *d)
+{
+	enum gic_intid_range range;
+
+	if (!static_branch_unlikely(&gic_arm64_2941627_erratum))
+		return false;
+
+	range = get_intid_range(d);
+
+	/*
+	 * The workaround is needed if the IRQ is an SPI and
+	 * the target cpu is different from the one we are
+	 * executing on.
+	 */
+	return (range == SPI_RANGE || range == ESPI_RANGE) &&
+		!cpumask_test_cpu(raw_smp_processor_id(),
+				  irq_data_get_effective_affinity_mask(d));
+}
+
 static void gic_eoi_irq(struct irq_data *d)
 {
-	gic_write_eoir(gic_irq(d));
+	write_gicreg(gic_irq(d), ICC_EOIR1_EL1);
+	isb();
+
+	if (gic_arm64_erratum_2941627_needed(d)) {
+		/*
+		 * Make sure the GIC stream deactivate packet
+		 * issued by ICC_EOIR1_EL1 has completed before
+		 * deactivating through GICD_IACTIVER.
+		 */
+		dsb(sy);
+		gic_poke_irq(d, GICD_ICACTIVER);
+	}
 }
 
 static void gic_eoimode1_eoi_irq(struct irq_data *d)
@@ -554,7 +587,11 @@
 	 */
 	if (gic_irq(d) >= 8192 || irqd_is_forwarded_to_vcpu(d))
 		return;
-	gic_write_dir(gic_irq(d));
+
+	if (!gic_arm64_erratum_2941627_needed(d))
+		gic_write_dir(gic_irq(d));
+	else
+		gic_poke_irq(d, GICD_ICACTIVER);
 }
 
 static int gic_set_type(struct irq_data *d, unsigned int type)
@@ -1472,7 +1509,7 @@
 
 		/*
 		 * Make it clear that broken DTs are... broken.
-		 * Partitionned PPIs are an unfortunate exception.
+		 * Partitioned PPIs are an unfortunate exception.
 		 */
 		WARN_ON(*type == IRQ_TYPE_NONE &&
 			fwspec->param[0] != GIC_IRQ_TYPE_PARTITION);
@@ -1603,6 +1640,15 @@
 	return true;
 }
 
+static bool gic_enable_quirk_mtk_gicr(void *data)
+{
+	struct gic_chip_data *d = data;
+
+	d->flags |= FLAGS_WORKAROUND_MTK_GICR_SAVE;
+
+	return true;
+}
+
 static bool gic_enable_quirk_cavium_38539(void *data)
 {
 	struct gic_chip_data *d = data;
@@ -1632,11 +1678,22 @@
 	return false;
 }
 
+static bool gic_enable_quirk_arm64_2941627(void *data)
+{
+	static_branch_enable(&gic_arm64_2941627_erratum);
+	return true;
+}
+
 static const struct gic_quirk gic_quirks[] = {
 	{
 		.desc	= "GICv3: Qualcomm MSM8996 broken firmware",
 		.compatible = "qcom,msm8996-gic-v3",
 		.init	= gic_enable_quirk_msm8996,
+	},
+	{
+		.desc	= "GICv3: Mediatek Chromebook GICR save problem",
+		.property = "mediatek,broken-save-restore-fw",
+		.init	= gic_enable_quirk_mtk_gicr,
 	},
 	{
 		.desc	= "GICv3: HIP06 erratum 161010803",
@@ -1664,6 +1721,25 @@
 		.init	= gic_enable_quirk_cavium_38539,
 	},
 	{
+		/*
+		 * GIC-700: 2941627 workaround - IP variant [0,1]
+		 *
+		 */
+		.desc	= "GICv3: ARM64 erratum 2941627",
+		.iidr	= 0x0400043b,
+		.mask	= 0xff0e0fff,
+		.init	= gic_enable_quirk_arm64_2941627,
+	},
+	{
+		/*
+		 * GIC-700: 2941627 workaround - IP variant [2]
+		 */
+		.desc	= "GICv3: ARM64 erratum 2941627",
+		.iidr	= 0x0402043b,
+		.mask	= 0xff0f0fff,
+		.init	= gic_enable_quirk_arm64_2941627,
+	},
+	{
 	}
 };
 
@@ -1674,6 +1750,11 @@
 	if (!gic_prio_masking_enabled())
 		return;
 
+	if (gic_data.flags & FLAGS_WORKAROUND_MTK_GICR_SAVE) {
+		pr_warn("Skipping NMI enable due to firmware issues\n");
+		return;
+	}
+
 	ppi_nmi_refs = kcalloc(gic_data.ppi_nr, sizeof(*ppi_nmi_refs), GFP_KERNEL);
 	if (!ppi_nmi_refs)
 		return;
diff --git a/kernel/drivers/irqchip/irq-gic.c b/kernel/drivers/irqchip/irq-gic.c
index cd3f72b..7f4edce 100644
--- a/kernel/drivers/irqchip/irq-gic.c
+++ b/kernel/drivers/irqchip/irq-gic.c
@@ -271,7 +271,8 @@
 	u32 reg;
 
 #ifdef CONFIG_ROCKCHIP_AMP
-	if (rockchip_amp_check_amp_irq(gic_irq(d)))
+	if (which != IRQCHIP_STATE_PENDING &&
+	    rockchip_amp_check_amp_irq(gic_irq(d)))
 		return -EINVAL;
 #endif
 	switch (which) {
@@ -533,7 +534,7 @@
 
 		maskval = 0;
 		for (j = 0; j < 4; j++) {
-			if (rockchip_amp_check_amp_irq(i + j)) {
+			if (rockchip_amp_need_init_amp_irq(i + j)) {
 				maskval |= rockchip_amp_get_irq_cpumask(i + j) <<
 					   (j * 8);
 			} else {
@@ -1348,6 +1349,9 @@
 		goto error;
 	}
 
+#ifdef CONFIG_ROCKCHIP_AMP
+	rockchip_amp_get_gic_info(gic->gic_irqs, GIC_V2);
+#endif
 	gic_dist_init(gic);
 	ret = gic_cpu_init(gic);
 	if (ret)
@@ -1565,10 +1569,6 @@
 		gic->percpu_offset = 0;
 
 	gic_enable_of_quirks(node, gic_quirks, gic);
-
-#ifdef CONFIG_ROCKCHIP_AMP
-	rockchip_amp_get_gic_info();
-#endif
 
 	return 0;
 
diff --git a/kernel/drivers/irqchip/irq-jcore-aic.c b/kernel/drivers/irqchip/irq-jcore-aic.c
index 033bccb..b9dcc8e 100644
--- a/kernel/drivers/irqchip/irq-jcore-aic.c
+++ b/kernel/drivers/irqchip/irq-jcore-aic.c
@@ -68,6 +68,7 @@
 	unsigned min_irq = JCORE_AIC2_MIN_HWIRQ;
 	unsigned dom_sz = JCORE_AIC_MAX_HWIRQ+1;
 	struct irq_domain *domain;
+	int ret;
 
 	pr_info("Initializing J-Core AIC\n");
 
@@ -100,11 +101,17 @@
 	jcore_aic.irq_unmask = noop;
 	jcore_aic.name = "AIC";
 
-	domain = irq_domain_add_linear(node, dom_sz, &jcore_aic_irqdomain_ops,
+	ret = irq_alloc_descs(-1, min_irq, dom_sz - min_irq,
+			      of_node_to_nid(node));
+
+	if (ret < 0)
+		return ret;
+
+	domain = irq_domain_add_legacy(node, dom_sz - min_irq, min_irq, min_irq,
+				       &jcore_aic_irqdomain_ops,
 				       &jcore_aic);
 	if (!domain)
 		return -ENOMEM;
-	irq_create_strict_mappings(domain, min_irq, min_irq, dom_sz - min_irq);
 
 	return 0;
 }
diff --git a/kernel/drivers/irqchip/irq-loongson-pch-pic.c b/kernel/drivers/irqchip/irq-loongson-pch-pic.c
index 90e1ad6..a4eb8a2 100644
--- a/kernel/drivers/irqchip/irq-loongson-pch-pic.c
+++ b/kernel/drivers/irqchip/irq-loongson-pch-pic.c
@@ -180,7 +180,7 @@
 	int i;
 
 	for (i = 0; i < PIC_COUNT; i++) {
-		/* Write vectore ID */
+		/* Write vectored ID */
 		writeb(priv->ht_vec_base + i, priv->base + PCH_INT_HTVEC(i));
 		/* Hardcode route to HT0 Lo */
 		writeb(1, priv->base + PCH_INT_ROUTE(i));
diff --git a/kernel/drivers/irqchip/irq-meson-gpio.c b/kernel/drivers/irqchip/irq-meson-gpio.c
index e3b462b..cfc5cf5 100644
--- a/kernel/drivers/irqchip/irq-meson-gpio.c
+++ b/kernel/drivers/irqchip/irq-meson-gpio.c
@@ -229,7 +229,7 @@
 
 	/*
 	 * Get the hwirq number assigned to this channel through
-	 * a pointer the channel_irq table. The added benifit of this
+	 * a pointer the channel_irq table. The added benefit of this
 	 * method is that we can also retrieve the channel index with
 	 * it, using the table base.
 	 */
diff --git a/kernel/drivers/irqchip/irq-mips-gic.c b/kernel/drivers/irqchip/irq-mips-gic.c
index 8ada91b..fc25b90 100644
--- a/kernel/drivers/irqchip/irq-mips-gic.c
+++ b/kernel/drivers/irqchip/irq-mips-gic.c
@@ -48,7 +48,7 @@
 
 static DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks);
 
-static DEFINE_SPINLOCK(gic_lock);
+static DEFINE_RAW_SPINLOCK(gic_lock);
 static struct irq_domain *gic_irq_domain;
 static int gic_shared_intrs;
 static unsigned int gic_cpu_pin;
@@ -209,7 +209,7 @@
 
 	irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
 
-	spin_lock_irqsave(&gic_lock, flags);
+	raw_spin_lock_irqsave(&gic_lock, flags);
 	switch (type & IRQ_TYPE_SENSE_MASK) {
 	case IRQ_TYPE_EDGE_FALLING:
 		pol = GIC_POL_FALLING_EDGE;
@@ -249,7 +249,7 @@
 	else
 		irq_set_chip_handler_name_locked(d, &gic_level_irq_controller,
 						 handle_level_irq, NULL);
-	spin_unlock_irqrestore(&gic_lock, flags);
+	raw_spin_unlock_irqrestore(&gic_lock, flags);
 
 	return 0;
 }
@@ -267,7 +267,7 @@
 		return -EINVAL;
 
 	/* Assumption : cpumask refers to a single CPU */
-	spin_lock_irqsave(&gic_lock, flags);
+	raw_spin_lock_irqsave(&gic_lock, flags);
 
 	/* Re-route this IRQ */
 	write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpu)));
@@ -278,7 +278,7 @@
 		set_bit(irq, per_cpu_ptr(pcpu_masks, cpu));
 
 	irq_data_update_effective_affinity(d, cpumask_of(cpu));
-	spin_unlock_irqrestore(&gic_lock, flags);
+	raw_spin_unlock_irqrestore(&gic_lock, flags);
 
 	return IRQ_SET_MASK_OK;
 }
@@ -356,12 +356,12 @@
 	cd = irq_data_get_irq_chip_data(d);
 	cd->mask = false;
 
-	spin_lock_irqsave(&gic_lock, flags);
+	raw_spin_lock_irqsave(&gic_lock, flags);
 	for_each_online_cpu(cpu) {
 		write_gic_vl_other(mips_cm_vp_id(cpu));
 		write_gic_vo_rmask(BIT(intr));
 	}
-	spin_unlock_irqrestore(&gic_lock, flags);
+	raw_spin_unlock_irqrestore(&gic_lock, flags);
 }
 
 static void gic_unmask_local_irq_all_vpes(struct irq_data *d)
@@ -374,32 +374,43 @@
 	cd = irq_data_get_irq_chip_data(d);
 	cd->mask = true;
 
-	spin_lock_irqsave(&gic_lock, flags);
+	raw_spin_lock_irqsave(&gic_lock, flags);
 	for_each_online_cpu(cpu) {
 		write_gic_vl_other(mips_cm_vp_id(cpu));
 		write_gic_vo_smask(BIT(intr));
 	}
-	spin_unlock_irqrestore(&gic_lock, flags);
+	raw_spin_unlock_irqrestore(&gic_lock, flags);
 }
 
-static void gic_all_vpes_irq_cpu_online(struct irq_data *d)
+static void gic_all_vpes_irq_cpu_online(void)
 {
-	struct gic_all_vpes_chip_data *cd;
-	unsigned int intr;
+	static const unsigned int local_intrs[] = {
+		GIC_LOCAL_INT_TIMER,
+		GIC_LOCAL_INT_PERFCTR,
+		GIC_LOCAL_INT_FDC,
+	};
+	unsigned long flags;
+	int i;
 
-	intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
-	cd = irq_data_get_irq_chip_data(d);
+	raw_spin_lock_irqsave(&gic_lock, flags);
 
-	write_gic_vl_map(mips_gic_vx_map_reg(intr), cd->map);
-	if (cd->mask)
-		write_gic_vl_smask(BIT(intr));
+	for (i = 0; i < ARRAY_SIZE(local_intrs); i++) {
+		unsigned int intr = local_intrs[i];
+		struct gic_all_vpes_chip_data *cd;
+
+		cd = &gic_all_vpes_chip_data[intr];
+		write_gic_vl_map(mips_gic_vx_map_reg(intr), cd->map);
+		if (cd->mask)
+			write_gic_vl_smask(BIT(intr));
+	}
+
+	raw_spin_unlock_irqrestore(&gic_lock, flags);
 }
 
 static struct irq_chip gic_all_vpes_local_irq_controller = {
 	.name			= "MIPS GIC Local",
 	.irq_mask		= gic_mask_local_irq_all_vpes,
 	.irq_unmask		= gic_unmask_local_irq_all_vpes,
-	.irq_cpu_online		= gic_all_vpes_irq_cpu_online,
 };
 
 static void __gic_irq_dispatch(void)
@@ -423,11 +434,11 @@
 
 	data = irq_get_irq_data(virq);
 
-	spin_lock_irqsave(&gic_lock, flags);
+	raw_spin_lock_irqsave(&gic_lock, flags);
 	write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
 	write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu)));
 	irq_data_update_effective_affinity(data, cpumask_of(cpu));
-	spin_unlock_irqrestore(&gic_lock, flags);
+	raw_spin_unlock_irqrestore(&gic_lock, flags);
 
 	return 0;
 }
@@ -480,6 +491,10 @@
 	intr = GIC_HWIRQ_TO_LOCAL(hwirq);
 	map = GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin;
 
+	/*
+	 * If adding support for more per-cpu interrupts, keep the the
+	 * array in gic_all_vpes_irq_cpu_online() in sync.
+	 */
 	switch (intr) {
 	case GIC_LOCAL_INT_TIMER:
 		/* CONFIG_MIPS_CMP workaround (see __gic_init) */
@@ -518,12 +533,12 @@
 	if (!gic_local_irq_is_routable(intr))
 		return -EPERM;
 
-	spin_lock_irqsave(&gic_lock, flags);
+	raw_spin_lock_irqsave(&gic_lock, flags);
 	for_each_online_cpu(cpu) {
 		write_gic_vl_other(mips_cm_vp_id(cpu));
 		write_gic_vo_map(mips_gic_vx_map_reg(intr), map);
 	}
-	spin_unlock_irqrestore(&gic_lock, flags);
+	raw_spin_unlock_irqrestore(&gic_lock, flags);
 
 	return 0;
 }
@@ -710,8 +725,8 @@
 	/* Clear all local IRQ masks (ie. disable all local interrupts) */
 	write_gic_vl_rmask(~0);
 
-	/* Invoke irq_cpu_online callbacks to enable desired interrupts */
-	irq_cpu_online();
+	/* Enable desired interrupts */
+	gic_all_vpes_irq_cpu_online();
 
 	return 0;
 }
diff --git a/kernel/drivers/irqchip/irq-mtk-cirq.c b/kernel/drivers/irqchip/irq-mtk-cirq.c
index 69ba8ce..9bca091 100644
--- a/kernel/drivers/irqchip/irq-mtk-cirq.c
+++ b/kernel/drivers/irqchip/irq-mtk-cirq.c
@@ -217,7 +217,7 @@
 {
 	u32 value;
 
-	/* flush recored interrupts, will send signals to parent controller */
+	/* flush recorded interrupts, will send signals to parent controller */
 	value = readl_relaxed(cirq_data->base + CIRQ_CONTROL);
 	writel_relaxed(value | CIRQ_FLUSH, cirq_data->base + CIRQ_CONTROL);
 
diff --git a/kernel/drivers/irqchip/irq-mvebu-gicp.c b/kernel/drivers/irqchip/irq-mvebu-gicp.c
index 3be5c5d..5caec41 100644
--- a/kernel/drivers/irqchip/irq-mvebu-gicp.c
+++ b/kernel/drivers/irqchip/irq-mvebu-gicp.c
@@ -223,6 +223,7 @@
 	}
 
 	parent_domain = irq_find_host(irq_parent_dn);
+	of_node_put(irq_parent_dn);
 	if (!parent_domain) {
 		dev_err(&pdev->dev, "failed to find parent IRQ domain\n");
 		return -ENODEV;
diff --git a/kernel/drivers/irqchip/irq-mxs.c b/kernel/drivers/irqchip/irq-mxs.c
index a671938..d1f5740 100644
--- a/kernel/drivers/irqchip/irq-mxs.c
+++ b/kernel/drivers/irqchip/irq-mxs.c
@@ -58,7 +58,7 @@
 static struct icoll_priv icoll_priv;
 static struct irq_domain *icoll_domain;
 
-/* calculate bit offset depending on number of intterupt per register */
+/* calculate bit offset depending on number of interrupt per register */
 static u32 icoll_intr_bitshift(struct irq_data *d, u32 bit)
 {
 	/*
@@ -68,7 +68,7 @@
 	return bit << ((d->hwirq & 3) << 3);
 }
 
-/* calculate mem offset depending on number of intterupt per register */
+/* calculate mem offset depending on number of interrupt per register */
 static void __iomem *icoll_intr_reg(struct irq_data *d)
 {
 	/* offset = hwirq / intr_per_reg * 0x10 */
diff --git a/kernel/drivers/irqchip/irq-sun4i.c b/kernel/drivers/irqchip/irq-sun4i.c
index fb78d66..9ea9445 100644
--- a/kernel/drivers/irqchip/irq-sun4i.c
+++ b/kernel/drivers/irqchip/irq-sun4i.c
@@ -189,7 +189,7 @@
 	 * 3) spurious irq
 	 * So if we immediately get a reading of 0, check the irq-pending reg
 	 * to differentiate between 2 and 3. We only do this once to avoid
-	 * the extra check in the common case of 1 hapening after having
+	 * the extra check in the common case of 1 happening after having
 	 * read the vector-reg once.
 	 */
 	hwirq = readl(irq_ic_data->irq_base + SUN4I_IRQ_VECTOR_REG) >> 2;
diff --git a/kernel/drivers/irqchip/irq-ti-sci-inta.c b/kernel/drivers/irqchip/irq-ti-sci-inta.c
index 532d0ae..ca1f593 100644
--- a/kernel/drivers/irqchip/irq-ti-sci-inta.c
+++ b/kernel/drivers/irqchip/irq-ti-sci-inta.c
@@ -78,7 +78,7 @@
  * struct ti_sci_inta_irq_domain - Structure representing a TISCI based
  *				   Interrupt Aggregator IRQ domain.
  * @sci:		Pointer to TISCI handle
- * @vint:		TISCI resource pointer representing IA inerrupts.
+ * @vint:		TISCI resource pointer representing IA interrupts.
  * @global_event:	TISCI resource pointer representing global events.
  * @vint_list:		List of the vints active in the system
  * @vint_mutex:		Mutex to protect vint_list
diff --git a/kernel/drivers/irqchip/irq-ti-sci-intr.c b/kernel/drivers/irqchip/irq-ti-sci-intr.c
index fe8fad2..020ddf2 100644
--- a/kernel/drivers/irqchip/irq-ti-sci-intr.c
+++ b/kernel/drivers/irqchip/irq-ti-sci-intr.c
@@ -236,6 +236,7 @@
 	}
 
 	parent_domain = irq_find_host(parent_node);
+	of_node_put(parent_node);
 	if (!parent_domain) {
 		dev_err(dev, "Failed to find IRQ parent domain\n");
 		return -ENODEV;
diff --git a/kernel/drivers/irqchip/irq-vic.c b/kernel/drivers/irqchip/irq-vic.c
index e460363..62f3d29 100644
--- a/kernel/drivers/irqchip/irq-vic.c
+++ b/kernel/drivers/irqchip/irq-vic.c
@@ -163,7 +163,7 @@
 };
 
 /**
- * vic_pm_init - initicall to register VIC pm
+ * vic_pm_init - initcall to register VIC pm
  *
  * This is called via late_initcall() to register
  * the resources for the VICs due to the early
@@ -397,7 +397,7 @@
 /*
  * The PL190 cell from ARM has been modified by ST to handle 64 interrupts.
  * The original cell has 32 interrupts, while the modified one has 64,
- * replocating two blocks 0x00..0x1f in 0x20..0x3f. In that case
+ * replicating two blocks 0x00..0x1f in 0x20..0x3f. In that case
  * the probe function is called twice, with base set to offset 000
  *  and 020 within the page. We call this "second block".
  */
diff --git a/kernel/drivers/irqchip/irq-xilinx-intc.c b/kernel/drivers/irqchip/irq-xilinx-intc.c
index 1d3d273..8cd1bfc 100644
--- a/kernel/drivers/irqchip/irq-xilinx-intc.c
+++ b/kernel/drivers/irqchip/irq-xilinx-intc.c
@@ -210,7 +210,7 @@
 
 	/*
 	 * Disable all external interrupts until they are
-	 * explicity requested.
+	 * explicitly requested.
 	 */
 	xintc_write(irqc, IER, 0);
 
diff --git a/kernel/drivers/irqchip/irqchip.c b/kernel/drivers/irqchip/irqchip.c
index 3570f0a..7899607 100644
--- a/kernel/drivers/irqchip/irqchip.c
+++ b/kernel/drivers/irqchip/irqchip.c
@@ -38,8 +38,10 @@
 	struct device_node *par_np = of_irq_find_parent(np);
 	of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev);
 
-	if (!irq_init_cb)
+	if (!irq_init_cb) {
+		of_node_put(par_np);
 		return -EINVAL;
+	}
 
 	if (par_np == np)
 		par_np = NULL;
@@ -52,8 +54,10 @@
 	 * interrupt controller. The actual initialization callback of this
 	 * interrupt controller can check for specific domains as necessary.
 	 */
-	if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY))
+	if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) {
+		of_node_put(par_np);
 		return -EPROBE_DEFER;
+	}
 
 	return irq_init_cb(np, par_np);
 }
diff --git a/kernel/drivers/isdn/hardware/mISDN/hfcmulti.c b/kernel/drivers/isdn/hardware/mISDN/hfcmulti.c
index 7013a3f..4c5b677 100644
--- a/kernel/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/kernel/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -3219,6 +3219,7 @@
 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 @@
 		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 @@
 				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 @@
 	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 @@
 				/* 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 @@
 #endif
 			ret = 0;
 			spin_unlock_irqrestore(&hc->lock, flags);
+			__skb_queue_purge(&free_queue);
 		} else
 			ret = l1_event(dch->l1, hh->prim);
 		break;
diff --git a/kernel/drivers/isdn/hardware/mISDN/hfcpci.c b/kernel/drivers/isdn/hardware/mISDN/hfcpci.c
index af17459..d6cf01c 100644
--- a/kernel/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/kernel/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -839,7 +839,7 @@
 		*z1t = cpu_to_le16(new_z1);	/* now send data */
 		if (bch->tx_idx < bch->tx_skb->len)
 			return;
-		dev_kfree_skb(bch->tx_skb);
+		dev_kfree_skb_any(bch->tx_skb);
 		if (get_next_bframe(bch))
 			goto next_t_frame;
 		return;
@@ -895,7 +895,7 @@
 	}
 	bz->za[new_f1].z1 = cpu_to_le16(new_z1);	/* for next buffer */
 	bz->f1 = new_f1;	/* next frame */
-	dev_kfree_skb(bch->tx_skb);
+	dev_kfree_skb_any(bch->tx_skb);
 	get_next_bframe(bch);
 }
 
@@ -1119,7 +1119,7 @@
 	if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len)
 		hfcpci_fill_fifo(bch);
 	else {
-		dev_kfree_skb(bch->tx_skb);
+		dev_kfree_skb_any(bch->tx_skb);
 		if (get_next_bframe(bch))
 			hfcpci_fill_fifo(bch);
 	}
@@ -1617,16 +1617,19 @@
 		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 @@
 			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)
@@ -2272,7 +2277,7 @@
 		return 0;
 
 	if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) {
-		spin_lock(&hc->lock);
+		spin_lock_irq(&hc->lock);
 		bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
 		if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */
 			main_rec_hfcpci(bch);
@@ -2283,7 +2288,7 @@
 			main_rec_hfcpci(bch);
 			tx_birq(bch);
 		}
-		spin_unlock(&hc->lock);
+		spin_unlock_irq(&hc->lock);
 	}
 	return 0;
 }
diff --git a/kernel/drivers/isdn/hardware/mISDN/hfcsusb.c b/kernel/drivers/isdn/hardware/mISDN/hfcsusb.c
index cd5642c..e8b37bd 100644
--- a/kernel/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ b/kernel/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -326,20 +326,24 @@
 		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 @@
 					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;
diff --git a/kernel/drivers/isdn/mISDN/dsp.h b/kernel/drivers/isdn/mISDN/dsp.h
index fa09d51..baf3125 100644
--- a/kernel/drivers/isdn/mISDN/dsp.h
+++ b/kernel/drivers/isdn/mISDN/dsp.h
@@ -247,7 +247,7 @@
 extern int dsp_cmx_conf(struct dsp *dsp, u32 conf_id);
 extern void dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb);
 extern void dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb);
-extern void dsp_cmx_send(void *arg);
+extern void dsp_cmx_send(struct timer_list *arg);
 extern void dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb);
 extern int dsp_cmx_del_conf_member(struct dsp *dsp);
 extern int dsp_cmx_del_conf(struct dsp_conf *conf);
diff --git a/kernel/drivers/isdn/mISDN/dsp_cmx.c b/kernel/drivers/isdn/mISDN/dsp_cmx.c
index 6d2088f..1b73af5 100644
--- a/kernel/drivers/isdn/mISDN/dsp_cmx.c
+++ b/kernel/drivers/isdn/mISDN/dsp_cmx.c
@@ -1625,7 +1625,7 @@
 static int	dsp_count_valid; /* if we have last sample count */
 
 void
-dsp_cmx_send(void *arg)
+dsp_cmx_send(struct timer_list *arg)
 {
 	struct dsp_conf *conf;
 	struct dsp_conf_member *member;
diff --git a/kernel/drivers/isdn/mISDN/dsp_core.c b/kernel/drivers/isdn/mISDN/dsp_core.c
index 038e72a..5b95401 100644
--- a/kernel/drivers/isdn/mISDN/dsp_core.c
+++ b/kernel/drivers/isdn/mISDN/dsp_core.c
@@ -1200,7 +1200,7 @@
 	}
 
 	/* set sample timer */
-	timer_setup(&dsp_spl_tl, (void *)dsp_cmx_send, 0);
+	timer_setup(&dsp_spl_tl, dsp_cmx_send, 0);
 	dsp_spl_tl.expires = jiffies + dsp_tics;
 	dsp_spl_jiffies = dsp_spl_tl.expires;
 	add_timer(&dsp_spl_tl);
diff --git a/kernel/drivers/leds/Kconfig b/kernel/drivers/leds/Kconfig
index 2b40b42..8148dfd 100644
--- a/kernel/drivers/leds/Kconfig
+++ b/kernel/drivers/leds/Kconfig
@@ -877,7 +877,7 @@
 config LEDS_TI_LMU_COMMON
 	tristate "LED driver for TI LMU"
 	depends on LEDS_CLASS
-	depends on REGMAP
+	select REGMAP
 	help
 	  Say Y to enable the LED driver for TI LMU devices.
 	  This supports common features between the TI LM3532, LM3631, LM3632,
diff --git a/kernel/drivers/leds/led-class.c b/kernel/drivers/leds/led-class.c
index 4365c1c..fcb9eee 100644
--- a/kernel/drivers/leds/led-class.c
+++ b/kernel/drivers/leds/led-class.c
@@ -236,14 +236,17 @@
 
 	led_dev = class_find_device_by_of_node(leds_class, led_node);
 	of_node_put(led_node);
+	put_device(led_dev);
 
 	if (!led_dev)
 		return ERR_PTR(-EPROBE_DEFER);
 
 	led_cdev = dev_get_drvdata(led_dev);
 
-	if (!try_module_get(led_cdev->dev->parent->driver->owner))
+	if (!try_module_get(led_cdev->dev->parent->driver->owner)) {
+		put_device(led_cdev->dev);
 		return ERR_PTR(-ENODEV);
+	}
 
 	return led_cdev;
 }
@@ -256,6 +259,7 @@
 void led_put(struct led_classdev *led_cdev)
 {
 	module_put(led_cdev->dev->parent->driver->owner);
+	put_device(led_cdev->dev);
 }
 EXPORT_SYMBOL_GPL(led_put);
 
diff --git a/kernel/drivers/leds/leds-tca6507.c b/kernel/drivers/leds/leds-tca6507.c
index 225b765..caad9d3 100644
--- a/kernel/drivers/leds/leds-tca6507.c
+++ b/kernel/drivers/leds/leds-tca6507.c
@@ -696,8 +696,9 @@
 		if (fwnode_property_read_string(child, "label", &led.name))
 			led.name = fwnode_get_name(child);
 
-		fwnode_property_read_string(child, "linux,default-trigger",
-					    &led.default_trigger);
+		if (fwnode_property_read_string(child, "linux,default-trigger",
+						&led.default_trigger))
+			led.default_trigger = NULL;
 
 		led.flags = 0;
 		if (fwnode_property_match_string(child, "compatible",
diff --git a/kernel/drivers/leds/trigger/ledtrig-netdev.c b/kernel/drivers/leds/trigger/ledtrig-netdev.c
index d5e774d..f4d670ec 100644
--- a/kernel/drivers/leds/trigger/ledtrig-netdev.c
+++ b/kernel/drivers/leds/trigger/ledtrig-netdev.c
@@ -318,6 +318,9 @@
 	clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
 	switch (evt) {
 	case NETDEV_CHANGENAME:
+		if (netif_carrier_ok(dev))
+			set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
+		fallthrough;
 	case NETDEV_REGISTER:
 		if (trigger_data->net_dev)
 			dev_put(trigger_data->net_dev);
diff --git a/kernel/drivers/macintosh/Kconfig b/kernel/drivers/macintosh/Kconfig
index 539a2ed..a0e717a 100644
--- a/kernel/drivers/macintosh/Kconfig
+++ b/kernel/drivers/macintosh/Kconfig
@@ -86,6 +86,7 @@
 
 config ADB_PMU_LED_DISK
 	bool "Use front LED as DISK LED by default"
+	depends on ATA
 	depends on ADB_PMU_LED
 	depends on LEDS_CLASS
 	select LEDS_TRIGGERS
diff --git a/kernel/drivers/macintosh/macio-adb.c b/kernel/drivers/macintosh/macio-adb.c
index d4759db..defe65f 100644
--- a/kernel/drivers/macintosh/macio-adb.c
+++ b/kernel/drivers/macintosh/macio-adb.c
@@ -106,6 +106,10 @@
 		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);
diff --git a/kernel/drivers/macintosh/macio_asic.c b/kernel/drivers/macintosh/macio_asic.c
index 49af60b..7db2e23 100644
--- a/kernel/drivers/macintosh/macio_asic.c
+++ b/kernel/drivers/macintosh/macio_asic.c
@@ -425,7 +425,7 @@
 	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;
 	}
 
diff --git a/kernel/drivers/macintosh/windfarm_lm75_sensor.c b/kernel/drivers/macintosh/windfarm_lm75_sensor.c
index 29f48c2..e90ad1b 100644
--- a/kernel/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/kernel/drivers/macintosh/windfarm_lm75_sensor.c
@@ -34,8 +34,8 @@
 #endif
 
 struct wf_lm75_sensor {
-	int			ds1775 : 1;
-	int			inited : 1;
+	unsigned int		ds1775 : 1;
+	unsigned int		inited : 1;
 	struct i2c_client	*i2c;
 	struct wf_sensor	sens;
 };
diff --git a/kernel/drivers/macintosh/windfarm_smu_sat.c b/kernel/drivers/macintosh/windfarm_smu_sat.c
index e46e115..7d7d621 100644
--- a/kernel/drivers/macintosh/windfarm_smu_sat.c
+++ b/kernel/drivers/macintosh/windfarm_smu_sat.c
@@ -171,6 +171,7 @@
 
 	if (sat->nr >= 0)
 		sats[sat->nr] = NULL;
+	of_node_put(sat->node);
 	kfree(sat);
 }
 
diff --git a/kernel/drivers/macintosh/windfarm_smu_sensors.c b/kernel/drivers/macintosh/windfarm_smu_sensors.c
index c8706cf..714c1e1 100644
--- a/kernel/drivers/macintosh/windfarm_smu_sensors.c
+++ b/kernel/drivers/macintosh/windfarm_smu_sensors.c
@@ -273,8 +273,8 @@
 	struct list_head	link;
 	struct wf_sensor	*volts;
 	struct wf_sensor	*amps;
-	int			fake_volts : 1;
-	int			quadratic : 1;
+	unsigned int		fake_volts : 1;
+	unsigned int		quadratic : 1;
 	struct wf_sensor	sens;
 };
 #define to_smu_cpu_power(c) container_of(c, struct smu_cpu_power_sensor, sens)
diff --git a/kernel/drivers/mailbox/mailbox-test.c b/kernel/drivers/mailbox/mailbox-test.c
index 4555d67..abcee58 100644
--- a/kernel/drivers/mailbox/mailbox-test.c
+++ b/kernel/drivers/mailbox/mailbox-test.c
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/mailbox_client.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/poll.h>
@@ -38,6 +39,7 @@
 	char			*signal;
 	char			*message;
 	spinlock_t		lock;
+	struct mutex		mutex;
 	wait_queue_head_t	waitq;
 	struct fasync_struct	*async_queue;
 	struct dentry		*root_debugfs_dir;
@@ -95,6 +97,7 @@
 				       size_t count, loff_t *ppos)
 {
 	struct mbox_test_device *tdev = filp->private_data;
+	char *message;
 	void *data;
 	int ret;
 
@@ -110,10 +113,13 @@
 		return -EINVAL;
 	}
 
-	tdev->message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL);
-	if (!tdev->message)
+	message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL);
+	if (!message)
 		return -ENOMEM;
 
+	mutex_lock(&tdev->mutex);
+
+	tdev->message = message;
 	ret = copy_from_user(tdev->message, userbuf, count);
 	if (ret) {
 		ret = -EFAULT;
@@ -143,6 +149,8 @@
 	kfree(tdev->signal);
 	kfree(tdev->message);
 	tdev->signal = NULL;
+
+	mutex_unlock(&tdev->mutex);
 
 	return ret < 0 ? ret : count;
 }
@@ -392,6 +400,7 @@
 	platform_set_drvdata(pdev, tdev);
 
 	spin_lock_init(&tdev->lock);
+	mutex_init(&tdev->mutex);
 
 	if (tdev->rx_channel) {
 		tdev->rx_buffer = devm_kzalloc(&pdev->dev,
diff --git a/kernel/drivers/mailbox/ti-msgmgr.c b/kernel/drivers/mailbox/ti-msgmgr.c
index 0130628..535fe73 100644
--- a/kernel/drivers/mailbox/ti-msgmgr.c
+++ b/kernel/drivers/mailbox/ti-msgmgr.c
@@ -385,14 +385,20 @@
 		/* Ensure all unused data is 0 */
 		data_trail &= 0xFFFFFFFF >> (8 * (sizeof(u32) - trail_bytes));
 		writel(data_trail, data_reg);
-		data_reg++;
+		data_reg += sizeof(u32);
 	}
+
 	/*
 	 * 'data_reg' indicates next register to write. If we did not already
 	 * write on tx complete reg(last reg), we must do so for transmit
+	 * In addition, we also need to make sure all intermediate data
+	 * registers(if any required), are reset to 0 for TISCI backward
+	 * compatibility to be maintained.
 	 */
-	if (data_reg <= qinst->queue_buff_end)
-		writel(0, qinst->queue_buff_end);
+	while (data_reg <= qinst->queue_buff_end) {
+		writel(0, data_reg);
+		data_reg += sizeof(u32);
+	}
 
 	return 0;
 }
diff --git a/kernel/drivers/mailbox/zynqmp-ipi-mailbox.c b/kernel/drivers/mailbox/zynqmp-ipi-mailbox.c
index f44079d..be06de7 100644
--- a/kernel/drivers/mailbox/zynqmp-ipi-mailbox.c
+++ b/kernel/drivers/mailbox/zynqmp-ipi-mailbox.c
@@ -110,7 +110,7 @@
 	unsigned int method;
 	u32 local_id;
 	int num_mboxes;
-	struct zynqmp_ipi_mbox *ipi_mboxes;
+	struct zynqmp_ipi_mbox ipi_mboxes[];
 };
 
 static struct device_driver zynqmp_ipi_mbox_driver = {
@@ -152,7 +152,7 @@
 	struct zynqmp_ipi_message *msg;
 	u64 arg0, arg3;
 	struct arm_smccc_res res;
-	int ret, i;
+	int ret, i, status = IRQ_NONE;
 
 	(void)irq;
 	arg0 = SMC_IPI_MAILBOX_STATUS_ENQUIRY;
@@ -170,11 +170,11 @@
 				memcpy_fromio(msg->data, mchan->req_buf,
 					      msg->len);
 				mbox_chan_received_data(chan, (void *)msg);
-				return IRQ_HANDLED;
+				status = IRQ_HANDLED;
 			}
 		}
 	}
-	return IRQ_NONE;
+	return status;
 }
 
 /**
@@ -493,6 +493,7 @@
 	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 @@
 		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);
 		}
 	}
 }
@@ -632,8 +634,13 @@
 	struct zynqmp_ipi_mbox *mbox;
 	int num_mboxes, ret = -EINVAL;
 
-	num_mboxes = of_get_child_count(np);
-	pdata = devm_kzalloc(dev, sizeof(*pdata) + (num_mboxes * sizeof(*mbox)),
+	num_mboxes = of_get_available_child_count(np);
+	if (num_mboxes == 0) {
+		dev_err(dev, "mailbox nodes not available\n");
+		return -EINVAL;
+	}
+
+	pdata = devm_kzalloc(dev, struct_size(pdata, ipi_mboxes, num_mboxes),
 			     GFP_KERNEL);
 	if (!pdata)
 		return -ENOMEM;
@@ -647,8 +654,6 @@
 	}
 
 	pdata->num_mboxes = num_mboxes;
-	pdata->ipi_mboxes = (struct zynqmp_ipi_mbox *)
-			    ((char *)pdata + sizeof(*pdata));
 
 	mbox = pdata->ipi_mboxes;
 	for_each_available_child_of_node(np, nc) {
diff --git a/kernel/drivers/mcb/mcb-core.c b/kernel/drivers/mcb/mcb-core.c
index 38cc834..8b8cd75 100644
--- a/kernel/drivers/mcb/mcb-core.c
+++ b/kernel/drivers/mcb/mcb-core.c
@@ -71,8 +71,10 @@
 
 	get_device(dev);
 	ret = mdrv->probe(mdev, found_id);
-	if (ret)
+	if (ret) {
 		module_put(carrier_mod);
+		put_device(dev);
+	}
 
 	return ret;
 }
diff --git a/kernel/drivers/mcb/mcb-parse.c b/kernel/drivers/mcb/mcb-parse.c
index 0266bfd..aa6938d 100644
--- a/kernel/drivers/mcb/mcb-parse.c
+++ b/kernel/drivers/mcb/mcb-parse.c
@@ -108,7 +108,7 @@
 	return 0;
 
 err:
-	mcb_free_dev(mdev);
+	put_device(&mdev->dev);
 
 	return ret;
 }
diff --git a/kernel/drivers/mcb/mcb-pci.c b/kernel/drivers/mcb/mcb-pci.c
index dc88232..53d9202 100644
--- a/kernel/drivers/mcb/mcb-pci.c
+++ b/kernel/drivers/mcb/mcb-pci.c
@@ -31,7 +31,7 @@
 {
 	struct resource *res;
 	struct priv *priv;
-	int ret;
+	int ret, table_size;
 	unsigned long flags;
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(struct priv), GFP_KERNEL);
@@ -90,7 +90,30 @@
 	if (ret < 0)
 		goto out_mcb_bus;
 
-	dev_dbg(&pdev->dev, "Found %d cells\n", ret);
+	table_size = ret;
+
+	if (table_size < CHAM_HEADER_SIZE) {
+		/* Release the previous resources */
+		devm_iounmap(&pdev->dev, priv->base);
+		devm_release_mem_region(&pdev->dev, priv->mapbase, CHAM_HEADER_SIZE);
+
+		/* Then, allocate it again with the actual chameleon table size */
+		res = devm_request_mem_region(&pdev->dev, priv->mapbase,
+						table_size,
+						KBUILD_MODNAME);
+		if (!res) {
+			dev_err(&pdev->dev, "Failed to request PCI memory\n");
+			ret = -EBUSY;
+			goto out_mcb_bus;
+		}
+
+		priv->base = devm_ioremap(&pdev->dev, priv->mapbase, table_size);
+		if (!priv->base) {
+			dev_err(&pdev->dev, "Cannot ioremap\n");
+			ret = -ENOMEM;
+			goto out_mcb_bus;
+		}
+	}
 
 	mcb_bus_add_devices(priv->bus);
 
diff --git a/kernel/drivers/md/bcache/btree.c b/kernel/drivers/md/bcache/btree.c
index b47c00d..24c57bb 100644
--- a/kernel/drivers/md/bcache/btree.c
+++ b/kernel/drivers/md/bcache/btree.c
@@ -885,7 +885,7 @@
  * cannibalize_bucket() will take. This means every time we unlock the root of
  * the btree, we need to release this lock if we have it held.
  */
-static void bch_cannibalize_unlock(struct cache_set *c)
+void bch_cannibalize_unlock(struct cache_set *c)
 {
 	spin_lock(&c->btree_cannibalize_lock);
 	if (c->btree_cache_alloc_lock == current) {
@@ -1090,10 +1090,12 @@
 				     struct btree *parent)
 {
 	BKEY_PADDED(key) k;
-	struct btree *b = ERR_PTR(-EAGAIN);
+	struct btree *b;
 
 	mutex_lock(&c->bucket_lock);
 retry:
+	/* return ERR_PTR(-EAGAIN) when it fails */
+	b = ERR_PTR(-EAGAIN);
 	if (__bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, wait))
 		goto err;
 
@@ -1138,7 +1140,7 @@
 {
 	struct btree *n = bch_btree_node_alloc(b->c, op, b->level, b->parent);
 
-	if (!IS_ERR_OR_NULL(n)) {
+	if (!IS_ERR(n)) {
 		mutex_lock(&n->write_lock);
 		bch_btree_sort_into(&b->keys, &n->keys, &b->c->sort);
 		bkey_copy_key(&n->key, &b->key);
@@ -1340,7 +1342,7 @@
 	memset(new_nodes, 0, sizeof(new_nodes));
 	closure_init_stack(&cl);
 
-	while (nodes < GC_MERGE_NODES && !IS_ERR_OR_NULL(r[nodes].b))
+	while (nodes < GC_MERGE_NODES && !IS_ERR(r[nodes].b))
 		keys += r[nodes++].keys;
 
 	blocks = btree_default_blocks(b->c) * 2 / 3;
@@ -1352,7 +1354,7 @@
 
 	for (i = 0; i < nodes; i++) {
 		new_nodes[i] = btree_node_alloc_replacement(r[i].b, NULL);
-		if (IS_ERR_OR_NULL(new_nodes[i]))
+		if (IS_ERR(new_nodes[i]))
 			goto out_nocoalesce;
 	}
 
@@ -1487,7 +1489,7 @@
 	bch_keylist_free(&keylist);
 
 	for (i = 0; i < nodes; i++)
-		if (!IS_ERR_OR_NULL(new_nodes[i])) {
+		if (!IS_ERR(new_nodes[i])) {
 			btree_node_free(new_nodes[i]);
 			rw_unlock(true, new_nodes[i]);
 		}
@@ -1669,7 +1671,7 @@
 	if (should_rewrite) {
 		n = btree_node_alloc_replacement(b, NULL);
 
-		if (!IS_ERR_OR_NULL(n)) {
+		if (!IS_ERR(n)) {
 			bch_btree_node_write_sync(n);
 
 			bch_btree_set_root(n);
@@ -1968,6 +1970,15 @@
 			c->gc_stats.nodes++;
 			bch_btree_op_init(&op, 0);
 			ret = bcache_btree(check_recurse, p, c->root, &op);
+			/*
+			 * The op may be added to cache_set's btree_cache_wait
+			 * in mca_cannibalize(), must ensure it is removed from
+			 * the list and release btree_cache_alloc_lock before
+			 * free op memory.
+			 * Otherwise, the btree_cache_wait will be damaged.
+			 */
+			bch_cannibalize_unlock(c);
+			finish_wait(&c->btree_cache_wait, &(&op)->wait);
 			if (ret)
 				goto out;
 		}
diff --git a/kernel/drivers/md/bcache/btree.h b/kernel/drivers/md/bcache/btree.h
index 1b5fdbc..a2920bb 100644
--- a/kernel/drivers/md/bcache/btree.h
+++ b/kernel/drivers/md/bcache/btree.h
@@ -282,6 +282,7 @@
 void bch_moving_gc(struct cache_set *c);
 int bch_btree_check(struct cache_set *c);
 void bch_initial_mark_key(struct cache_set *c, int level, struct bkey *k);
+void bch_cannibalize_unlock(struct cache_set *c);
 
 static inline void wake_up_gc(struct cache_set *c)
 {
diff --git a/kernel/drivers/md/bcache/super.c b/kernel/drivers/md/bcache/super.c
index 7f5ea25..e8c8077 100644
--- a/kernel/drivers/md/bcache/super.c
+++ b/kernel/drivers/md/bcache/super.c
@@ -1748,7 +1748,7 @@
 	if (!IS_ERR_OR_NULL(c->gc_thread))
 		kthread_stop(c->gc_thread);
 
-	if (!IS_ERR_OR_NULL(c->root))
+	if (!IS_ERR(c->root))
 		list_add(&c->root->list, &c->btree_cache);
 
 	/*
@@ -2112,7 +2112,7 @@
 
 		err = "cannot allocate new btree root";
 		c->root = __bch_btree_node_alloc(c, NULL, 0, true, NULL);
-		if (IS_ERR_OR_NULL(c->root))
+		if (IS_ERR(c->root))
 			goto err;
 
 		mutex_lock(&c->root->write_lock);
diff --git a/kernel/drivers/md/bcache/writeback.c b/kernel/drivers/md/bcache/writeback.c
index 3aa73da..6324c92 100644
--- a/kernel/drivers/md/bcache/writeback.c
+++ b/kernel/drivers/md/bcache/writeback.c
@@ -834,6 +834,16 @@
 	if (ret < 0)
 		pr_warn("sectors dirty init failed, ret=%d!\n", ret);
 
+	/*
+	 * The op may be added to cache_set's btree_cache_wait
+	 * in mca_cannibalize(), must ensure it is removed from
+	 * the list and release btree_cache_alloc_lock before
+	 * free op memory.
+	 * Otherwise, the btree_cache_wait will be damaged.
+	 */
+	bch_cannibalize_unlock(c);
+	finish_wait(&c->btree_cache_wait, &(&op.op)->wait);
+
 	return ret;
 }
 
diff --git a/kernel/drivers/md/dm-bufio.c b/kernel/drivers/md/dm-bufio.c
index 50f3e67..bb0e3dd 100644
--- a/kernel/drivers/md/dm-bufio.c
+++ b/kernel/drivers/md/dm-bufio.c
@@ -19,6 +19,8 @@
 #include <linux/rbtree.h>
 #include <linux/stacktrace.h>
 
+#include <trace/hooks/mm.h>
+
 #define DM_MSG_PREFIX "bufio"
 
 /*
@@ -1683,6 +1685,13 @@
 static unsigned long dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
 {
 	struct dm_bufio_client *c;
+	bool bypass = false;
+
+	trace_android_vh_dm_bufio_shrink_scan_bypass(
+			dm_bufio_current_allocated,
+			&bypass);
+	if (bypass)
+		return 0;
 
 	c = container_of(shrink, struct dm_bufio_client, shrinker);
 	atomic_long_add(sc->nr_to_scan, &c->need_shrink);
@@ -2009,6 +2018,14 @@
 {
 	unsigned long max_age_hz = get_max_age_hz();
 	struct dm_bufio_client *c;
+	bool bypass = false;
+
+	trace_android_vh_cleanup_old_buffers_bypass(
+				dm_bufio_current_allocated,
+				&max_age_hz,
+				&bypass);
+	if (bypass)
+		return;
 
 	mutex_lock(&dm_bufio_clients_lock);
 
diff --git a/kernel/drivers/md/dm-cache-metadata.c b/kernel/drivers/md/dm-cache-metadata.c
index af6d4f8..2ecd0db 100644
--- a/kernel/drivers/md/dm-cache-metadata.c
+++ b/kernel/drivers/md/dm-cache-metadata.c
@@ -551,11 +551,13 @@
 	return r;
 }
 
-static void __destroy_persistent_data_objects(struct dm_cache_metadata *cmd)
+static void __destroy_persistent_data_objects(struct dm_cache_metadata *cmd,
+					      bool destroy_bm)
 {
 	dm_sm_destroy(cmd->metadata_sm);
 	dm_tm_destroy(cmd->tm);
-	dm_block_manager_destroy(cmd->bm);
+	if (destroy_bm)
+		dm_block_manager_destroy(cmd->bm);
 }
 
 typedef unsigned long (*flags_mutator)(unsigned long);
@@ -826,7 +828,7 @@
 		cmd2 = lookup(bdev);
 		if (cmd2) {
 			mutex_unlock(&table_lock);
-			__destroy_persistent_data_objects(cmd);
+			__destroy_persistent_data_objects(cmd, true);
 			kfree(cmd);
 			return cmd2;
 		}
@@ -874,7 +876,7 @@
 		mutex_unlock(&table_lock);
 
 		if (!cmd->fail_io)
-			__destroy_persistent_data_objects(cmd);
+			__destroy_persistent_data_objects(cmd, true);
 		kfree(cmd);
 	}
 }
@@ -1808,14 +1810,52 @@
 
 int dm_cache_metadata_abort(struct dm_cache_metadata *cmd)
 {
-	int r;
+	int r = -EINVAL;
+	struct dm_block_manager *old_bm = NULL, *new_bm = NULL;
+
+	/* fail_io is double-checked with cmd->root_lock held below */
+	if (unlikely(cmd->fail_io))
+		return r;
+
+	/*
+	 * Replacement block manager (new_bm) is created and old_bm destroyed outside of
+	 * cmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of
+	 * shrinker associated with the block manager's bufio client vs cmd root_lock).
+	 * - must take shrinker_rwsem without holding cmd->root_lock
+	 */
+	new_bm = dm_block_manager_create(cmd->bdev, DM_CACHE_METADATA_BLOCK_SIZE << SECTOR_SHIFT,
+					 CACHE_MAX_CONCURRENT_LOCKS);
 
 	WRITE_LOCK(cmd);
-	__destroy_persistent_data_objects(cmd);
-	r = __create_persistent_data_objects(cmd, false);
+	if (cmd->fail_io) {
+		WRITE_UNLOCK(cmd);
+		goto out;
+	}
+
+	__destroy_persistent_data_objects(cmd, false);
+	old_bm = cmd->bm;
+	if (IS_ERR(new_bm)) {
+		DMERR("could not create block manager during abort");
+		cmd->bm = NULL;
+		r = PTR_ERR(new_bm);
+		goto out_unlock;
+	}
+
+	cmd->bm = new_bm;
+	r = __open_or_format_metadata(cmd, false);
+	if (r) {
+		cmd->bm = NULL;
+		goto out_unlock;
+	}
+	new_bm = NULL;
+out_unlock:
 	if (r)
 		cmd->fail_io = true;
 	WRITE_UNLOCK(cmd);
+	dm_block_manager_destroy(old_bm);
+out:
+	if (new_bm && !IS_ERR(new_bm))
+		dm_block_manager_destroy(new_bm);
 
 	return r;
 }
diff --git a/kernel/drivers/md/dm-cache-policy-smq.c b/kernel/drivers/md/dm-cache-policy-smq.c
index b61aac0..8590731 100644
--- a/kernel/drivers/md/dm-cache-policy-smq.c
+++ b/kernel/drivers/md/dm-cache-policy-smq.c
@@ -854,7 +854,13 @@
 
 	struct background_tracker *bg_work;
 
-	bool migrations_allowed;
+	bool migrations_allowed:1;
+
+	/*
+	 * If this is set the policy will try and clean the whole cache
+	 * even if the device is not idle.
+	 */
+	bool cleaner:1;
 };
 
 /*----------------------------------------------------------------*/
@@ -1133,7 +1139,7 @@
 	 * Cache entries may not be populated.  So we cannot rely on the
 	 * size of the clean queue.
 	 */
-	if (idle) {
+	if (idle || mq->cleaner) {
 		/*
 		 * We'd like to clean everything.
 		 */
@@ -1716,11 +1722,9 @@
 		*hotspot_block_size /= 2u;
 }
 
-static struct dm_cache_policy *__smq_create(dm_cblock_t cache_size,
-					    sector_t origin_size,
-					    sector_t cache_block_size,
-					    bool mimic_mq,
-					    bool migrations_allowed)
+static struct dm_cache_policy *
+__smq_create(dm_cblock_t cache_size, sector_t origin_size, sector_t cache_block_size,
+	     bool mimic_mq, bool migrations_allowed, bool cleaner)
 {
 	unsigned i;
 	unsigned nr_sentinels_per_queue = 2u * NR_CACHE_LEVELS;
@@ -1807,6 +1811,7 @@
 		goto bad_btracker;
 
 	mq->migrations_allowed = migrations_allowed;
+	mq->cleaner = cleaner;
 
 	return &mq->policy;
 
@@ -1830,21 +1835,24 @@
 					  sector_t origin_size,
 					  sector_t cache_block_size)
 {
-	return __smq_create(cache_size, origin_size, cache_block_size, false, true);
+	return __smq_create(cache_size, origin_size, cache_block_size,
+			    false, true, false);
 }
 
 static struct dm_cache_policy *mq_create(dm_cblock_t cache_size,
 					 sector_t origin_size,
 					 sector_t cache_block_size)
 {
-	return __smq_create(cache_size, origin_size, cache_block_size, true, true);
+	return __smq_create(cache_size, origin_size, cache_block_size,
+			    true, true, false);
 }
 
 static struct dm_cache_policy *cleaner_create(dm_cblock_t cache_size,
 					      sector_t origin_size,
 					      sector_t cache_block_size)
 {
-	return __smq_create(cache_size, origin_size, cache_block_size, false, false);
+	return __smq_create(cache_size, origin_size, cache_block_size,
+			    false, false, true);
 }
 
 /*----------------------------------------------------------------*/
diff --git a/kernel/drivers/md/dm-cache-target.c b/kernel/drivers/md/dm-cache-target.c
index 4bc453f..f98ad43 100644
--- a/kernel/drivers/md/dm-cache-target.c
+++ b/kernel/drivers/md/dm-cache-target.c
@@ -985,14 +985,14 @@
 	if (get_cache_mode(cache) >= CM_READ_ONLY)
 		return;
 
-	if (dm_cache_metadata_set_needs_check(cache->cmd)) {
-		DMERR("%s: failed to set 'needs_check' flag in metadata", dev_name);
-		set_cache_mode(cache, CM_FAIL);
-	}
-
 	DMERR_LIMIT("%s: aborting current metadata transaction", dev_name);
 	if (dm_cache_metadata_abort(cache->cmd)) {
 		DMERR("%s: failed to abort metadata transaction", dev_name);
+		set_cache_mode(cache, CM_FAIL);
+	}
+
+	if (dm_cache_metadata_set_needs_check(cache->cmd)) {
+		DMERR("%s: failed to set 'needs_check' flag in metadata", dev_name);
 		set_cache_mode(cache, CM_FAIL);
 	}
 }
@@ -1883,6 +1883,7 @@
 
 		else
 			commit_needed = process_bio(cache, bio) || commit_needed;
+		cond_resched();
 	}
 
 	if (commit_needed)
@@ -1905,6 +1906,7 @@
 	while ((bio = bio_list_pop(&bios))) {
 		bio->bi_status = BLK_STS_DM_REQUEUE;
 		bio_endio(bio);
+		cond_resched();
 	}
 }
 
@@ -1945,6 +1947,8 @@
 		r = mg_start(cache, op, NULL);
 		if (r)
 			break;
+
+		cond_resched();
 	}
 }
 
@@ -1965,6 +1969,7 @@
 	if (cache->prison)
 		dm_bio_prison_destroy_v2(cache->prison);
 
+	cancel_delayed_work_sync(&cache->waker);
 	if (cache->wq)
 		destroy_workqueue(cache->wq);
 
diff --git a/kernel/drivers/md/dm-clone-target.c b/kernel/drivers/md/dm-clone-target.c
index bdb255e..e3156b3 100644
--- a/kernel/drivers/md/dm-clone-target.c
+++ b/kernel/drivers/md/dm-clone-target.c
@@ -1966,6 +1966,7 @@
 
 	mempool_exit(&clone->hydration_pool);
 	dm_kcopyd_client_destroy(clone->kcopyd_client);
+	cancel_delayed_work_sync(&clone->waker);
 	destroy_workqueue(clone->wq);
 	hash_table_exit(clone);
 	dm_clone_metadata_close(clone->cmd);
@@ -2220,6 +2221,7 @@
 	r = dm_register_target(&clone_target);
 	if (r < 0) {
 		DMERR("Failed to register clone target");
+		kmem_cache_destroy(_hydration_cache);
 		return r;
 	}
 
diff --git a/kernel/drivers/md/dm-crypt.c b/kernel/drivers/md/dm-crypt.c
index 3d975db..5d772f3 100644
--- a/kernel/drivers/md/dm-crypt.c
+++ b/kernel/drivers/md/dm-crypt.c
@@ -67,7 +67,9 @@
 	struct crypt_config *cc;
 	struct bio *base_bio;
 	u8 *integrity_metadata;
-	bool integrity_metadata_from_pool;
+	bool integrity_metadata_from_pool:1;
+	bool in_tasklet:1;
+
 	struct work_struct work;
 	struct tasklet_struct tasklet;
 
@@ -1722,6 +1724,7 @@
 	io->ctx.r.req = NULL;
 	io->integrity_metadata = NULL;
 	io->integrity_metadata_from_pool = false;
+	io->in_tasklet = false;
 	atomic_set(&io->io_pending, 0);
 }
 
@@ -1767,14 +1770,13 @@
 	 * our tasklet. In this case we need to delay bio_endio()
 	 * execution to after the tasklet is done and dequeued.
 	 */
-	if (tasklet_trylock(&io->tasklet)) {
-		tasklet_unlock(&io->tasklet);
-		bio_endio(base_bio);
+	if (io->in_tasklet) {
+		INIT_WORK(&io->work, kcryptd_io_bio_endio);
+		queue_work(cc->io_queue, &io->work);
 		return;
 	}
 
-	INIT_WORK(&io->work, kcryptd_io_bio_endio);
-	queue_work(cc->io_queue, &io->work);
+	bio_endio(base_bio);
 }
 
 /*
@@ -1934,6 +1936,7 @@
 			io = crypt_io_from_node(rb_first(&write_tree));
 			rb_erase(&io->rb_node, &write_tree);
 			kcryptd_io_write(io);
+			cond_resched();
 		} while (!RB_EMPTY_ROOT(&write_tree));
 		blk_finish_plug(&plug);
 	}
@@ -2227,6 +2230,7 @@
 		 * it is being executed with irqs disabled.
 		 */
 		if (in_irq() || irqs_disabled()) {
+			io->in_tasklet = true;
 			tasklet_init(&io->tasklet, kcryptd_crypt_tasklet, (unsigned long)&io->work);
 			tasklet_schedule(&io->tasklet);
 			return;
diff --git a/kernel/drivers/md/dm-default-key.c b/kernel/drivers/md/dm-default-key.c
index e8e9b72..eaa8329 100644
--- a/kernel/drivers/md/dm-default-key.c
+++ b/kernel/drivers/md/dm-default-key.c
@@ -67,13 +67,9 @@
 static void default_key_dtr(struct dm_target *ti)
 {
 	struct default_key_c *dkc = ti->private;
-	int err;
 
 	if (dkc->dev) {
-		err = blk_crypto_evict_key(bdev_get_queue(dkc->dev->bdev),
-					   &dkc->key);
-		if (err && err != -ENOKEY)
-			DMWARN("Failed to evict crypto key: %d", err);
+		blk_crypto_evict_key(bdev_get_queue(dkc->dev->bdev), &dkc->key);
 		dm_put_device(ti, dkc->dev);
 	}
 	kfree_sensitive(dkc->cipher_string);
diff --git a/kernel/drivers/md/dm-flakey.c b/kernel/drivers/md/dm-flakey.c
index 30c6bc1..aeea538 100644
--- a/kernel/drivers/md/dm-flakey.c
+++ b/kernel/drivers/md/dm-flakey.c
@@ -124,9 +124,9 @@
 			 * Direction r or w?
 			 */
 			arg_name = dm_shift_arg(as);
-			if (!strcasecmp(arg_name, "w"))
+			if (arg_name && !strcasecmp(arg_name, "w"))
 				fc->corrupt_bio_rw = WRITE;
-			else if (!strcasecmp(arg_name, "r"))
+			else if (arg_name && !strcasecmp(arg_name, "r"))
 				fc->corrupt_bio_rw = READ;
 			else {
 				ti->error = "Invalid corrupt bio direction (r or w)";
@@ -301,8 +301,11 @@
 	 */
 	bio_for_each_segment(bvec, bio, iter) {
 		if (bio_iter_len(bio, iter) > corrupt_bio_byte) {
-			char *segment = (page_address(bio_iter_page(bio, iter))
-					 + bio_iter_offset(bio, iter));
+			char *segment;
+			struct page *page = bio_iter_page(bio, iter);
+			if (unlikely(page == ZERO_PAGE(0)))
+				break;
+			segment = (page_address(page) + bio_iter_offset(bio, iter));
 			segment[corrupt_bio_byte] = fc->corrupt_bio_value;
 			DMDEBUG("Corrupting data bio=%p by writing %u to byte %u "
 				"(rw=%c bi_opf=%u bi_sector=%llu size=%u)\n",
@@ -359,9 +362,11 @@
 		/*
 		 * Corrupt matching writes.
 		 */
-		if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == WRITE)) {
-			if (all_corrupt_bio_flags_match(bio, fc))
-				corrupt_bio_data(bio, fc);
+		if (fc->corrupt_bio_byte) {
+			if (fc->corrupt_bio_rw == WRITE) {
+				if (all_corrupt_bio_flags_match(bio, fc))
+					corrupt_bio_data(bio, fc);
+			}
 			goto map_bio;
 		}
 
@@ -387,13 +392,14 @@
 		return DM_ENDIO_DONE;
 
 	if (!*error && pb->bio_submitted && (bio_data_dir(bio) == READ)) {
-		if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) &&
-		    all_corrupt_bio_flags_match(bio, fc)) {
-			/*
-			 * Corrupt successful matching READs while in down state.
-			 */
-			corrupt_bio_data(bio, fc);
-
+		if (fc->corrupt_bio_byte) {
+			if ((fc->corrupt_bio_rw == READ) &&
+			    all_corrupt_bio_flags_match(bio, fc)) {
+				/*
+				 * Corrupt successful matching READs while in down state.
+				 */
+				corrupt_bio_data(bio, fc);
+			}
 		} else if (!test_bit(DROP_WRITES, &fc->flags) &&
 			   !test_bit(ERROR_WRITES, &fc->flags)) {
 			/*
diff --git a/kernel/drivers/md/dm-integrity.c b/kernel/drivers/md/dm-integrity.c
index 2156a2d..1667ac1 100644
--- a/kernel/drivers/md/dm-integrity.c
+++ b/kernel/drivers/md/dm-integrity.c
@@ -31,11 +31,11 @@
 #define DEFAULT_BUFFER_SECTORS		128
 #define DEFAULT_JOURNAL_WATERMARK	50
 #define DEFAULT_SYNC_MSEC		10000
-#define DEFAULT_MAX_JOURNAL_SECTORS	131072
+#define DEFAULT_MAX_JOURNAL_SECTORS	(IS_ENABLED(CONFIG_64BIT) ? 131072 : 8192)
 #define MIN_LOG2_INTERLEAVE_SECTORS	3
 #define MAX_LOG2_INTERLEAVE_SECTORS	31
 #define METADATA_WORKQUEUE_MAX_ACTIVE	16
-#define RECALC_SECTORS			8192
+#define RECALC_SECTORS			(IS_ENABLED(CONFIG_64BIT) ? 32768 : 2048)
 #define RECALC_WRITE_SUPER		16
 #define BITMAP_BLOCK_SIZE		4096	/* don't change it */
 #define BITMAP_FLUSH_INTERVAL		(10 * HZ)
@@ -4388,6 +4388,8 @@
 	BUG_ON(!RB_EMPTY_ROOT(&ic->in_progress));
 	BUG_ON(!list_empty(&ic->wait_list));
 
+	if (ic->mode == 'B')
+		cancel_delayed_work_sync(&ic->bitmap_flush_work);
 	if (ic->metadata_wq)
 		destroy_workqueue(ic->metadata_wq);
 	if (ic->wait_wq)
@@ -4479,11 +4481,13 @@
 	}
 
 	r = dm_register_target(&integrity_target);
-
-	if (r < 0)
+	if (r < 0) {
 		DMERR("register failed %d", r);
+		kmem_cache_destroy(journal_io_cache);
+		return r;
+	}
 
-	return r;
+	return 0;
 }
 
 static void __exit dm_integrity_exit(void)
diff --git a/kernel/drivers/md/dm-ioctl.c b/kernel/drivers/md/dm-ioctl.c
index 20171c9..5f9b917 100644
--- a/kernel/drivers/md/dm-ioctl.c
+++ b/kernel/drivers/md/dm-ioctl.c
@@ -1435,11 +1435,12 @@
 		hc->new_map = NULL;
 	}
 
-	param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
-
-	__dev_status(hc->md, param);
 	md = hc->md;
 	up_write(&_hash_lock);
+
+	param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
+	__dev_status(md, param);
+
 	if (old_map) {
 		dm_sync_table(md);
 		dm_table_destroy(old_map);
diff --git a/kernel/drivers/md/dm-raid.c b/kernel/drivers/md/dm-raid.c
index a2d09c9..140bdf2 100644
--- a/kernel/drivers/md/dm-raid.c
+++ b/kernel/drivers/md/dm-raid.c
@@ -3258,8 +3258,7 @@
 	r = md_start(&rs->md);
 	if (r) {
 		ti->error = "Failed to start raid array";
-		mddev_unlock(&rs->md);
-		goto bad_md_start;
+		goto bad_unlock;
 	}
 
 	/* If raid4/5/6 journal mode explicitly requested (only possible with journal dev) -> set it */
@@ -3267,8 +3266,7 @@
 		r = r5c_journal_mode_set(&rs->md, rs->journal_dev.mode);
 		if (r) {
 			ti->error = "Failed to set raid4/5/6 journal mode";
-			mddev_unlock(&rs->md);
-			goto bad_journal_mode_set;
+			goto bad_unlock;
 		}
 	}
 
@@ -3279,14 +3277,14 @@
 	if (rs_is_raid456(rs)) {
 		r = rs_set_raid456_stripe_cache(rs);
 		if (r)
-			goto bad_stripe_cache;
+			goto bad_unlock;
 	}
 
 	/* Now do an early reshape check */
 	if (test_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) {
 		r = rs_check_reshape(rs);
 		if (r)
-			goto bad_check_reshape;
+			goto bad_unlock;
 
 		/* Restore new, ctr requested layout to perform check */
 		rs_config_restore(rs, &rs_layout);
@@ -3295,7 +3293,7 @@
 			r = rs->md.pers->check_reshape(&rs->md);
 			if (r) {
 				ti->error = "Reshape check failed";
-				goto bad_check_reshape;
+				goto bad_unlock;
 			}
 		}
 	}
@@ -3306,11 +3304,9 @@
 	mddev_unlock(&rs->md);
 	return 0;
 
-bad_md_start:
-bad_journal_mode_set:
-bad_stripe_cache:
-bad_check_reshape:
+bad_unlock:
 	md_stop(&rs->md);
+	mddev_unlock(&rs->md);
 bad:
 	raid_set_free(rs);
 
@@ -3321,7 +3317,9 @@
 {
 	struct raid_set *rs = ti->private;
 
+	mddev_lock_nointr(&rs->md);
 	md_stop(&rs->md);
+	mddev_unlock(&rs->md);
 	raid_set_free(rs);
 }
 
diff --git a/kernel/drivers/md/dm-stats.c b/kernel/drivers/md/dm-stats.c
index 55443a6..4029281 100644
--- a/kernel/drivers/md/dm-stats.c
+++ b/kernel/drivers/md/dm-stats.c
@@ -188,7 +188,7 @@
 	       atomic_read(&shared->in_flight[WRITE]);
 }
 
-void dm_stats_init(struct dm_stats *stats)
+int dm_stats_init(struct dm_stats *stats)
 {
 	int cpu;
 	struct dm_stats_last_position *last;
@@ -196,11 +196,16 @@
 	mutex_init(&stats->mutex);
 	INIT_LIST_HEAD(&stats->list);
 	stats->last = alloc_percpu(struct dm_stats_last_position);
+	if (!stats->last)
+		return -ENOMEM;
+
 	for_each_possible_cpu(cpu) {
 		last = per_cpu_ptr(stats->last, cpu);
 		last->last_sector = (sector_t)ULLONG_MAX;
 		last->last_rw = UINT_MAX;
 	}
+
+	return 0;
 }
 
 void dm_stats_cleanup(struct dm_stats *stats)
diff --git a/kernel/drivers/md/dm-stats.h b/kernel/drivers/md/dm-stats.h
index 2ddfae6..dcac11f 100644
--- a/kernel/drivers/md/dm-stats.h
+++ b/kernel/drivers/md/dm-stats.h
@@ -22,7 +22,7 @@
 	unsigned long long duration_ns;
 };
 
-void dm_stats_init(struct dm_stats *st);
+int dm_stats_init(struct dm_stats *st);
 void dm_stats_cleanup(struct dm_stats *st);
 
 struct mapped_device;
diff --git a/kernel/drivers/md/dm-table.c b/kernel/drivers/md/dm-table.c
index ade798f..743bdb1 100644
--- a/kernel/drivers/md/dm-table.c
+++ b/kernel/drivers/md/dm-table.c
@@ -1221,21 +1221,12 @@
 	struct mapped_device *md;
 };
 
-struct dm_keyslot_evict_args {
-	const struct blk_crypto_key *key;
-	int err;
-};
-
 static int dm_keyslot_evict_callback(struct dm_target *ti, struct dm_dev *dev,
 				     sector_t start, sector_t len, void *data)
 {
-	struct dm_keyslot_evict_args *args = data;
-	int err;
+	const struct blk_crypto_key *key = data;
 
-	err = blk_crypto_evict_key(bdev_get_queue(dev->bdev), args->key);
-	if (!args->err)
-		args->err = err;
-	/* Always try to evict the key from all devices. */
+	blk_crypto_evict_key(bdev_get_queue(dev->bdev), key);
 	return 0;
 }
 
@@ -1250,7 +1241,6 @@
 						       struct dm_keyslot_manager,
 						       ksm);
 	struct mapped_device *md = dksm->md;
-	struct dm_keyslot_evict_args args = { key };
 	struct dm_table *t;
 	int srcu_idx;
 	int i;
@@ -1263,10 +1253,11 @@
 		ti = dm_table_get_target(t, i);
 		if (!ti->type->iterate_devices)
 			continue;
-		ti->type->iterate_devices(ti, dm_keyslot_evict_callback, &args);
+		ti->type->iterate_devices(ti, dm_keyslot_evict_callback,
+					  (void *)key);
 	}
 	dm_put_live_table(md, srcu_idx);
-	return args.err;
+	return 0;
 }
 
 struct dm_derive_raw_secret_args {
diff --git a/kernel/drivers/md/dm-thin-metadata.c b/kernel/drivers/md/dm-thin-metadata.c
index 842d79e..8f4d149 100644
--- a/kernel/drivers/md/dm-thin-metadata.c
+++ b/kernel/drivers/md/dm-thin-metadata.c
@@ -701,6 +701,15 @@
 		goto bad_cleanup_data_sm;
 	}
 
+	/*
+	 * For pool metadata opening process, root setting is redundant
+	 * because it will be set again in __begin_transaction(). But dm
+	 * pool aborting process really needs to get last transaction's
+	 * root to avoid accessing broken btree.
+	 */
+	pmd->root = le64_to_cpu(disk_super->data_mapping_root);
+	pmd->details_root = le64_to_cpu(disk_super->device_details_root);
+
 	__setup_btree_details(pmd);
 	dm_bm_unlock(sblock);
 
@@ -753,13 +762,15 @@
 	return r;
 }
 
-static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd)
+static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd,
+					      bool destroy_bm)
 {
 	dm_sm_destroy(pmd->data_sm);
 	dm_sm_destroy(pmd->metadata_sm);
 	dm_tm_destroy(pmd->nb_tm);
 	dm_tm_destroy(pmd->tm);
-	dm_block_manager_destroy(pmd->bm);
+	if (destroy_bm)
+		dm_block_manager_destroy(pmd->bm);
 }
 
 static int __begin_transaction(struct dm_pool_metadata *pmd)
@@ -966,7 +977,7 @@
 	}
 	pmd_write_unlock(pmd);
 	if (!pmd->fail_io)
-		__destroy_persistent_data_objects(pmd);
+		__destroy_persistent_data_objects(pmd, true);
 
 	kfree(pmd);
 	return 0;
@@ -1873,19 +1884,52 @@
 int dm_pool_abort_metadata(struct dm_pool_metadata *pmd)
 {
 	int r = -EINVAL;
+	struct dm_block_manager *old_bm = NULL, *new_bm = NULL;
+
+	/* fail_io is double-checked with pmd->root_lock held below */
+	if (unlikely(pmd->fail_io))
+		return r;
+
+	/*
+	 * Replacement block manager (new_bm) is created and old_bm destroyed outside of
+	 * pmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of
+	 * shrinker associated with the block manager's bufio client vs pmd root_lock).
+	 * - must take shrinker_rwsem without holding pmd->root_lock
+	 */
+	new_bm = dm_block_manager_create(pmd->bdev, THIN_METADATA_BLOCK_SIZE << SECTOR_SHIFT,
+					 THIN_MAX_CONCURRENT_LOCKS);
 
 	pmd_write_lock(pmd);
-	if (pmd->fail_io)
+	if (pmd->fail_io) {
+		pmd_write_unlock(pmd);
 		goto out;
+	}
 
 	__set_abort_with_changes_flags(pmd);
-	__destroy_persistent_data_objects(pmd);
-	r = __create_persistent_data_objects(pmd, false);
+	__destroy_persistent_data_objects(pmd, false);
+	old_bm = pmd->bm;
+	if (IS_ERR(new_bm)) {
+		DMERR("could not create block manager during abort");
+		pmd->bm = NULL;
+		r = PTR_ERR(new_bm);
+		goto out_unlock;
+	}
+
+	pmd->bm = new_bm;
+	r = __open_or_format_metadata(pmd, false);
+	if (r) {
+		pmd->bm = NULL;
+		goto out_unlock;
+	}
+	new_bm = NULL;
+out_unlock:
 	if (r)
 		pmd->fail_io = true;
-
-out:
 	pmd_write_unlock(pmd);
+	dm_block_manager_destroy(old_bm);
+out:
+	if (new_bm && !IS_ERR(new_bm))
+		dm_block_manager_destroy(new_bm);
 
 	return r;
 }
diff --git a/kernel/drivers/md/dm-thin.c b/kernel/drivers/md/dm-thin.c
index a196d7c..9314074 100644
--- a/kernel/drivers/md/dm-thin.c
+++ b/kernel/drivers/md/dm-thin.c
@@ -2217,6 +2217,7 @@
 			throttle_work_update(&pool->throttle);
 			dm_pool_issue_prefetches(pool->pmd);
 		}
+		cond_resched();
 	}
 	blk_finish_plug(&plug);
 }
@@ -2299,6 +2300,7 @@
 			else
 				pool->process_cell(tc, cell);
 		}
+		cond_resched();
 	} while (!list_empty(&cells));
 }
 
@@ -2907,6 +2909,8 @@
 	dm_bio_prison_destroy(pool->prison);
 	dm_kcopyd_client_destroy(pool->copier);
 
+	cancel_delayed_work_sync(&pool->waker);
+	cancel_delayed_work_sync(&pool->no_space_timeout);
 	if (pool->wq)
 		destroy_workqueue(pool->wq);
 
@@ -3379,6 +3383,7 @@
 	pt->low_water_blocks = low_water_blocks;
 	pt->adjusted_pf = pt->requested_pf = pf;
 	ti->num_flush_bios = 1;
+	ti->limit_swap_bios = true;
 
 	/*
 	 * Only need to enable discards if the pool should pass
@@ -3566,20 +3571,28 @@
 	 */
 	r = bind_control_target(pool, ti);
 	if (r)
-		return r;
+		goto out;
 
 	r = maybe_resize_data_dev(ti, &need_commit1);
 	if (r)
-		return r;
+		goto out;
 
 	r = maybe_resize_metadata_dev(ti, &need_commit2);
 	if (r)
-		return r;
+		goto out;
 
 	if (need_commit1 || need_commit2)
 		(void) commit(pool);
+out:
+	/*
+	 * When a thin-pool is PM_FAIL, it cannot be rebuilt if
+	 * bio is in deferred list. Therefore need to return 0
+	 * to allow pool_resume() to flush IO.
+	 */
+	if (r && get_pool_mode(pool) == PM_FAIL)
+		r = 0;
 
-	return 0;
+	return r;
 }
 
 static void pool_suspend_active_thins(struct pool *pool)
@@ -4247,6 +4260,7 @@
 		goto bad;
 
 	ti->num_flush_bios = 1;
+	ti->limit_swap_bios = true;
 	ti->flush_supported = true;
 	ti->per_io_data_size = sizeof(struct dm_thin_endio_hook);
 
diff --git a/kernel/drivers/md/dm-verity-target.c b/kernel/drivers/md/dm-verity-target.c
index 1c8038c..0ca2997 100644
--- a/kernel/drivers/md/dm-verity-target.c
+++ b/kernel/drivers/md/dm-verity-target.c
@@ -482,7 +482,7 @@
 		sector_t cur_block = io->block + b;
 		struct ahash_request *req = verity_io_hash_req(v, io);
 
-		if (v->validated_blocks &&
+		if (v->validated_blocks && bio->bi_status == BLK_STS_OK &&
 		    likely(test_bit(cur_block, v->validated_blocks))) {
 			verity_bv_skip_block(v, io, &io->iter);
 			continue;
@@ -538,7 +538,7 @@
 				return -EIO;
 			}
 			if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA,
-					   cur_block))
+					      cur_block))
 				return -EIO;
 		}
 	}
@@ -1219,8 +1219,16 @@
 		goto bad;
 	}
 
-	/* WQ_UNBOUND greatly improves performance when running on ramdisk */
-	v->verify_wq = alloc_workqueue("kverityd", WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM | WQ_UNBOUND, num_online_cpus());
+	/*
+	 * Using WQ_HIGHPRI improves throughput and completion latency by
+	 * reducing wait times when reading from a dm-verity device.
+	 *
+	 * Also as required for the "try_verify_in_tasklet" feature: WQ_HIGHPRI
+	 * allows verify_wq to preempt softirq since verification in tasklet
+	 * will fall-back to using it for error handling (or if the bufio cache
+	 * doesn't have required hashes).
+	 */
+	v->verify_wq = alloc_workqueue("kverityd", WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
 	if (!v->verify_wq) {
 		ti->error = "Cannot allocate workqueue";
 		r = -ENOMEM;
diff --git a/kernel/drivers/md/dm-zoned-target.c b/kernel/drivers/md/dm-zoned-target.c
index 7e88df6..48fc723 100644
--- a/kernel/drivers/md/dm-zoned-target.c
+++ b/kernel/drivers/md/dm-zoned-target.c
@@ -750,17 +750,16 @@
 /*
  * Cleanup zoned device information.
  */
-static void dmz_put_zoned_device(struct dm_target *ti)
+static void dmz_put_zoned_devices(struct dm_target *ti)
 {
 	struct dmz_target *dmz = ti->private;
 	int i;
 
-	for (i = 0; i < dmz->nr_ddevs; i++) {
-		if (dmz->ddev[i]) {
+	for (i = 0; i < dmz->nr_ddevs; i++)
+		if (dmz->ddev[i])
 			dm_put_device(ti, dmz->ddev[i]);
-			dmz->ddev[i] = NULL;
-		}
-	}
+
+	kfree(dmz->ddev);
 }
 
 static int dmz_fixup_devices(struct dm_target *ti)
@@ -951,7 +950,7 @@
 err_meta:
 	dmz_dtr_metadata(dmz->metadata);
 err_dev:
-	dmz_put_zoned_device(ti);
+	dmz_put_zoned_devices(ti);
 err:
 	kfree(dmz->dev);
 	kfree(dmz);
@@ -982,7 +981,7 @@
 
 	bioset_exit(&dmz->bio_set);
 
-	dmz_put_zoned_device(ti);
+	dmz_put_zoned_devices(ti);
 
 	mutex_destroy(&dmz->chunk_lock);
 
diff --git a/kernel/drivers/md/dm.c b/kernel/drivers/md/dm.c
index be1bf1c..cb58c40 100644
--- a/kernel/drivers/md/dm.c
+++ b/kernel/drivers/md/dm.c
@@ -266,7 +266,6 @@
 
 static void local_exit(void)
 {
-	flush_scheduled_work();
 	destroy_workqueue(deferred_remove_workqueue);
 
 	unregister_blkdev(_major, _name);
@@ -1927,7 +1926,9 @@
 	if (!md->bdev)
 		goto bad;
 
-	dm_stats_init(&md->stats);
+	r = dm_stats_init(&md->stats);
+	if (r < 0)
+		goto bad;
 
 	/* Populate the mapping, nobody knows we exist yet */
 	spin_lock(&_minor_lock);
@@ -2410,6 +2411,7 @@
 			break;
 
 		submit_bio_noacct(bio);
+		cond_resched();
 	}
 }
 
diff --git a/kernel/drivers/md/md-bitmap.c b/kernel/drivers/md/md-bitmap.c
index d377ea0..b283028 100644
--- a/kernel/drivers/md/md-bitmap.c
+++ b/kernel/drivers/md/md-bitmap.c
@@ -54,14 +54,7 @@
 {
 	unsigned char *mappage;
 
-	if (page >= bitmap->pages) {
-		/* This can happen if bitmap_start_sync goes beyond
-		 * End-of-device while looking for a whole page.
-		 * It is harmless.
-		 */
-		return -EINVAL;
-	}
-
+	WARN_ON_ONCE(page >= bitmap->pages);
 	if (bitmap->bp[page].hijacked) /* it's hijacked, don't try to alloc */
 		return 0;
 
@@ -486,7 +479,7 @@
 	sb = kmap_atomic(bitmap->storage.sb_page);
 	pr_debug("%s: bitmap file superblock:\n", bmname(bitmap));
 	pr_debug("         magic: %08x\n", le32_to_cpu(sb->magic));
-	pr_debug("       version: %d\n", le32_to_cpu(sb->version));
+	pr_debug("       version: %u\n", le32_to_cpu(sb->version));
 	pr_debug("          uuid: %08x.%08x.%08x.%08x\n",
 		 le32_to_cpu(*(__le32 *)(sb->uuid+0)),
 		 le32_to_cpu(*(__le32 *)(sb->uuid+4)),
@@ -497,11 +490,11 @@
 	pr_debug("events cleared: %llu\n",
 		 (unsigned long long) le64_to_cpu(sb->events_cleared));
 	pr_debug("         state: %08x\n", le32_to_cpu(sb->state));
-	pr_debug("     chunksize: %d B\n", le32_to_cpu(sb->chunksize));
-	pr_debug("  daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep));
+	pr_debug("     chunksize: %u B\n", le32_to_cpu(sb->chunksize));
+	pr_debug("  daemon sleep: %us\n", le32_to_cpu(sb->daemon_sleep));
 	pr_debug("     sync size: %llu KB\n",
 		 (unsigned long long)le64_to_cpu(sb->sync_size)/2);
-	pr_debug("max write behind: %d\n", le32_to_cpu(sb->write_behind));
+	pr_debug("max write behind: %u\n", le32_to_cpu(sb->write_behind));
 	kunmap_atomic(sb);
 }
 
@@ -1365,6 +1358,14 @@
 	sector_t csize;
 	int err;
 
+	if (page >= bitmap->pages) {
+		/*
+		 * This can happen if bitmap_start_sync goes beyond
+		 * End-of-device while looking for a whole page or
+		 * user set a huge number to sysfs bitmap_set_bits.
+		 */
+		return NULL;
+	}
 	err = md_bitmap_checkpage(bitmap, page, create, 0);
 
 	if (bitmap->bp[page].hijacked ||
@@ -2106,7 +2107,8 @@
 			bytes = DIV_ROUND_UP(chunks, 8);
 			if (!bitmap->mddev->bitmap_info.external)
 				bytes += sizeof(bitmap_super_t);
-		} while (bytes > (space << 9));
+		} while (bytes > (space << 9) && (chunkshift + BITMAP_BLOCK_SHIFT) <
+			(BITS_PER_BYTE * sizeof(((bitmap_super_t *)0)->chunksize) - 1));
 	} else
 		chunkshift = ffz(~chunksize) - BITMAP_BLOCK_SHIFT;
 
@@ -2151,7 +2153,7 @@
 	bitmap->counts.missing_pages = pages;
 	bitmap->counts.chunkshift = chunkshift;
 	bitmap->counts.chunks = chunks;
-	bitmap->mddev->bitmap_info.chunksize = 1 << (chunkshift +
+	bitmap->mddev->bitmap_info.chunksize = 1UL << (chunkshift +
 						     BITMAP_BLOCK_SHIFT);
 
 	blocks = min(old_counts.chunks << old_counts.chunkshift,
@@ -2177,8 +2179,8 @@
 				bitmap->counts.missing_pages = old_counts.pages;
 				bitmap->counts.chunkshift = old_counts.chunkshift;
 				bitmap->counts.chunks = old_counts.chunks;
-				bitmap->mddev->bitmap_info.chunksize = 1 << (old_counts.chunkshift +
-									     BITMAP_BLOCK_SHIFT);
+				bitmap->mddev->bitmap_info.chunksize =
+					1UL << (old_counts.chunkshift + BITMAP_BLOCK_SHIFT);
 				blocks = old_counts.chunks << old_counts.chunkshift;
 				pr_warn("Could not pre-allocate in-memory bitmap for cluster raid\n");
 				break;
@@ -2196,20 +2198,23 @@
 
 		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;
 		}
@@ -2471,11 +2476,35 @@
 {
 	unsigned long backlog;
 	unsigned long old_mwb = mddev->bitmap_info.max_write_behind;
+	struct md_rdev *rdev;
+	bool has_write_mostly = false;
 	int rv = kstrtoul(buf, 10, &backlog);
 	if (rv)
 		return rv;
 	if (backlog > COUNTER_MAX)
 		return -EINVAL;
+
+	rv = mddev_lock(mddev);
+	if (rv)
+		return rv;
+
+	/*
+	 * Without write mostly device, it doesn't make sense to set
+	 * backlog for max_write_behind.
+	 */
+	rdev_for_each(rdev, mddev) {
+		if (test_bit(WriteMostly, &rdev->flags)) {
+			has_write_mostly = true;
+			break;
+		}
+	}
+	if (!has_write_mostly) {
+		pr_warn_ratelimited("%s: can't set backlog, no write mostly device available\n",
+				    mdname(mddev));
+		mddev_unlock(mddev);
+		return -EINVAL;
+	}
+
 	mddev->bitmap_info.max_write_behind = backlog;
 	if (!backlog && mddev->serial_info_pool) {
 		/* serial_info_pool is not needed if backlog is zero */
@@ -2483,13 +2512,13 @@
 			mddev_destroy_serial_pool(mddev, NULL, false);
 	} else if (backlog && !mddev->serial_info_pool) {
 		/* serial_info_pool is needed since backlog is not zero */
-		struct md_rdev *rdev;
-
 		rdev_for_each(rdev, mddev)
 			mddev_create_serial_pool(mddev, rdev, false);
 	}
 	if (old_mwb != backlog)
 		md_bitmap_update_sb(mddev->bitmap);
+
+	mddev_unlock(mddev);
 	return len;
 }
 
@@ -2516,6 +2545,9 @@
 	if (csize < 512 ||
 	    !is_power_of_2(csize))
 		return -EINVAL;
+	if (BITS_PER_LONG > 32 && csize >= (1ULL << (BITS_PER_BYTE *
+		sizeof(((bitmap_super_t *)0)->chunksize))))
+		return -EOVERFLOW;
 	mddev->bitmap_info.chunksize = csize;
 	return len;
 }
diff --git a/kernel/drivers/md/md.c b/kernel/drivers/md/md.c
index 0043dec..6efe49f 100644
--- a/kernel/drivers/md/md.c
+++ b/kernel/drivers/md/md.c
@@ -555,13 +555,14 @@
 	struct md_rdev *rdev = bio->bi_private;
 	struct mddev *mddev = rdev->mddev;
 
+	bio_put(bio);
+
 	rdev_dec_pending(rdev, mddev);
 
 	if (atomic_dec_and_test(&mddev->flush_pending)) {
 		/* The pre-request flush has finished */
 		queue_work(md_wq, &mddev->flush_work);
 	}
-	bio_put(bio);
 }
 
 static void md_submit_flush_data(struct work_struct *ws);
@@ -966,10 +967,12 @@
 	} else
 		clear_bit(LastDev, &rdev->flags);
 
+	bio_put(bio);
+
+	rdev_dec_pending(rdev, mddev);
+
 	if (atomic_dec_and_test(&mddev->pending_writes))
 		wake_up(&mddev->sb_wait);
-	rdev_dec_pending(rdev, mddev);
-	bio_put(bio);
 }
 
 void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
@@ -3204,6 +3207,9 @@
 		err = kstrtouint(buf, 10, (unsigned int *)&slot);
 		if (err < 0)
 			return err;
+		if (slot < 0)
+			/* overflow */
+			return -ENOSPC;
 	}
 	if (rdev->mddev->pers && slot == -1) {
 		/* Setting 'slot' on an active array requires also
@@ -3884,8 +3890,9 @@
 static ssize_t
 safe_delay_show(struct mddev *mddev, char *page)
 {
-	int msec = (mddev->safemode_delay*1000)/HZ;
-	return sprintf(page, "%d.%03d\n", msec/1000, msec%1000);
+	unsigned int msec = ((unsigned long)mddev->safemode_delay*1000)/HZ;
+
+	return sprintf(page, "%u.%03u\n", msec/1000, msec%1000);
 }
 static ssize_t
 safe_delay_store(struct mddev *mddev, const char *cbuf, size_t len)
@@ -3897,7 +3904,7 @@
 		return -EINVAL;
 	}
 
-	if (strict_strtoul_scaled(cbuf, &msec, 3) < 0)
+	if (strict_strtoul_scaled(cbuf, &msec, 3) < 0 || msec > UINT_MAX / HZ)
 		return -EINVAL;
 	if (msec == 0)
 		mddev->safemode_delay = 0;
@@ -4567,6 +4574,8 @@
 	rv = kstrtouint(buf, 10, &n);
 	if (rv < 0)
 		return rv;
+	if (n > INT_MAX)
+		return -EINVAL;
 	atomic_set(&mddev->max_corr_read_errors, n);
 	return len;
 }
@@ -4881,11 +4890,21 @@
 			return -EINVAL;
 		err = mddev_lock(mddev);
 		if (!err) {
-			if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
+			if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) {
 				err =  -EBUSY;
-			else {
+			} else if (mddev->reshape_position == MaxSector ||
+				   mddev->pers->check_reshape == NULL ||
+				   mddev->pers->check_reshape(mddev)) {
 				clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
 				err = mddev->pers->start_reshape(mddev);
+			} else {
+				/*
+				 * If reshape is still in progress, and
+				 * md_check_recovery() can continue to reshape,
+				 * don't restart reshape because data can be
+				 * corrupted for raid456.
+				 */
+				clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
 			}
 			mddev_unlock(mddev);
 		}
@@ -5680,6 +5699,7 @@
 	 * completely removed (mddev_delayed_delete).
 	 */
 	flush_workqueue(md_misc_wq);
+	flush_workqueue(md_rdev_misc_wq);
 
 	mutex_lock(&disks_mutex);
 	error = -EEXIST;
@@ -6296,6 +6316,8 @@
 
 void md_stop(struct mddev *mddev)
 {
+	lockdep_assert_held(&mddev->reconfig_mutex);
+
 	/* stop the array and free an attached data structures.
 	 * This is called from dm-raid
 	 */
diff --git a/kernel/drivers/md/raid0.c b/kernel/drivers/md/raid0.c
index a20332e..ee2cfd6 100644
--- a/kernel/drivers/md/raid0.c
+++ b/kernel/drivers/md/raid0.c
@@ -274,6 +274,18 @@
 		goto abort;
 	}
 
+	if (conf->layout == RAID0_ORIG_LAYOUT) {
+		for (i = 1; i < conf->nr_strip_zones; i++) {
+			sector_t first_sector = conf->strip_zone[i-1].zone_end;
+
+			sector_div(first_sector, mddev->chunk_sectors);
+			zone = conf->strip_zone + i;
+			/* disk_shift is first disk index used in the zone */
+			zone->disk_shift = sector_div(first_sector,
+						      zone->nb_dev);
+		}
+	}
+
 	pr_debug("md/raid0:%s: done.\n", mdname(mddev));
 	*private_conf = conf;
 
@@ -427,6 +439,20 @@
 	kfree(conf);
 }
 
+/*
+ * Convert disk_index to the disk order in which it is read/written.
+ *  For example, if we have 4 disks, they are numbered 0,1,2,3. If we
+ *  write the disks starting at disk 3, then the read/write order would
+ *  be disk 3, then 0, then 1, and then disk 2 and we want map_disk_shift()
+ *  to map the disks as follows 0,1,2,3 => 1,2,3,0. So disk 0 would map
+ *  to 1, 1 to 2, 2 to 3, and 3 to 0. That way we can compare disks in
+ *  that 'output' space to understand the read/write disk ordering.
+ */
+static int map_disk_shift(int disk_index, int num_disks, int disk_shift)
+{
+	return ((disk_index + num_disks - disk_shift) % num_disks);
+}
+
 static void raid0_handle_discard(struct mddev *mddev, struct bio *bio)
 {
 	struct r0conf *conf = mddev->private;
@@ -440,7 +466,9 @@
 	sector_t end_disk_offset;
 	unsigned int end_disk_index;
 	unsigned int disk;
+	sector_t orig_start, orig_end;
 
+	orig_start = start;
 	zone = find_zone(conf, &start);
 
 	if (bio_end_sector(bio) > zone->zone_end) {
@@ -454,6 +482,7 @@
 	} else
 		end = bio_end_sector(bio);
 
+	orig_end = end;
 	if (zone != conf->strip_zone)
 		end = end - zone[-1].zone_end;
 
@@ -465,13 +494,26 @@
 	last_stripe_index = end;
 	sector_div(last_stripe_index, stripe_size);
 
-	start_disk_index = (int)(start - first_stripe_index * stripe_size) /
-		mddev->chunk_sectors;
+	/* In the first zone the original and alternate layouts are the same */
+	if ((conf->layout == RAID0_ORIG_LAYOUT) && (zone != conf->strip_zone)) {
+		sector_div(orig_start, mddev->chunk_sectors);
+		start_disk_index = sector_div(orig_start, zone->nb_dev);
+		start_disk_index = map_disk_shift(start_disk_index,
+						  zone->nb_dev,
+						  zone->disk_shift);
+		sector_div(orig_end, mddev->chunk_sectors);
+		end_disk_index = sector_div(orig_end, zone->nb_dev);
+		end_disk_index = map_disk_shift(end_disk_index,
+						zone->nb_dev, zone->disk_shift);
+	} else {
+		start_disk_index = (int)(start - first_stripe_index * stripe_size) /
+			mddev->chunk_sectors;
+		end_disk_index = (int)(end - last_stripe_index * stripe_size) /
+			mddev->chunk_sectors;
+	}
 	start_disk_offset = ((int)(start - first_stripe_index * stripe_size) %
 		mddev->chunk_sectors) +
 		first_stripe_index * mddev->chunk_sectors;
-	end_disk_index = (int)(end - last_stripe_index * stripe_size) /
-		mddev->chunk_sectors;
 	end_disk_offset = ((int)(end - last_stripe_index * stripe_size) %
 		mddev->chunk_sectors) +
 		last_stripe_index * mddev->chunk_sectors;
@@ -480,18 +522,22 @@
 		sector_t dev_start, dev_end;
 		struct bio *discard_bio = NULL;
 		struct md_rdev *rdev;
+		int compare_disk;
 
-		if (disk < start_disk_index)
+		compare_disk = map_disk_shift(disk, zone->nb_dev,
+					      zone->disk_shift);
+
+		if (compare_disk < start_disk_index)
 			dev_start = (first_stripe_index + 1) *
 				mddev->chunk_sectors;
-		else if (disk > start_disk_index)
+		else if (compare_disk > start_disk_index)
 			dev_start = first_stripe_index * mddev->chunk_sectors;
 		else
 			dev_start = start_disk_offset;
 
-		if (disk < end_disk_index)
+		if (compare_disk < end_disk_index)
 			dev_end = (last_stripe_index + 1) * mddev->chunk_sectors;
-		else if (disk > end_disk_index)
+		else if (compare_disk > end_disk_index)
 			dev_end = last_stripe_index * mddev->chunk_sectors;
 		else
 			dev_end = end_disk_offset;
diff --git a/kernel/drivers/md/raid0.h b/kernel/drivers/md/raid0.h
index 3816e54..8cc761c 100644
--- a/kernel/drivers/md/raid0.h
+++ b/kernel/drivers/md/raid0.h
@@ -6,6 +6,7 @@
 	sector_t zone_end;	/* Start of the next zone (in sectors) */
 	sector_t dev_start;	/* Zone offset in real dev (in sectors) */
 	int	 nb_dev;	/* # of devices attached to the zone */
+	int	 disk_shift;	/* start disk for the original layout */
 };
 
 /* Linux 3.14 (20d0189b101) made an unintended change to
diff --git a/kernel/drivers/md/raid1.c b/kernel/drivers/md/raid1.c
index fb31e5d..3619db7 100644
--- a/kernel/drivers/md/raid1.c
+++ b/kernel/drivers/md/raid1.c
@@ -1793,6 +1793,9 @@
 	int number = rdev->raid_disk;
 	struct raid1_info *p = conf->mirrors + number;
 
+	if (unlikely(number >= conf->raid_disks))
+		goto abort;
+
 	if (rdev != p->rdev)
 		p = conf->mirrors + conf->raid_disks + number;
 
@@ -3115,6 +3118,7 @@
 	 * RAID1 needs at least one disk in active
 	 */
 	if (conf->raid_disks - mddev->degraded < 1) {
+		md_unregister_thread(&conf->thread);
 		ret = -EINVAL;
 		goto abort;
 	}
diff --git a/kernel/drivers/md/raid10.c b/kernel/drivers/md/raid10.c
index 0e741a8..55144f7 100644
--- a/kernel/drivers/md/raid10.c
+++ b/kernel/drivers/md/raid10.c
@@ -751,8 +751,16 @@
 		disk = r10_bio->devs[slot].devnum;
 		rdev = rcu_dereference(conf->mirrors[disk].replacement);
 		if (rdev == NULL || test_bit(Faulty, &rdev->flags) ||
-		    r10_bio->devs[slot].addr + sectors > rdev->recovery_offset)
+		    r10_bio->devs[slot].addr + sectors >
+		    rdev->recovery_offset) {
+			/*
+			 * Read replacement first to prevent reading both rdev
+			 * and replacement as NULL during replacement replace
+			 * rdev.
+			 */
+			smp_mb();
 			rdev = rcu_dereference(conf->mirrors[disk].rdev);
+		}
 		if (rdev == NULL ||
 		    test_bit(Faulty, &rdev->flags))
 			continue;
@@ -894,6 +902,7 @@
 			else
 				submit_bio_noacct(bio);
 			bio = next;
+			cond_resched();
 		}
 		blk_finish_plug(&plug);
 	} else
@@ -1087,6 +1096,7 @@
 		else
 			submit_bio_noacct(bio);
 		bio = next;
+		cond_resched();
 	}
 	kfree(plug);
 }
@@ -1346,9 +1356,15 @@
 
 	for (i = 0;  i < conf->copies; i++) {
 		int d = r10_bio->devs[i].devnum;
-		struct md_rdev *rdev = rcu_dereference(conf->mirrors[d].rdev);
-		struct md_rdev *rrdev = rcu_dereference(
-			conf->mirrors[d].replacement);
+		struct md_rdev *rdev, *rrdev;
+
+		rrdev = rcu_dereference(conf->mirrors[d].replacement);
+		/*
+		 * Read replacement first to prevent reading both rdev and
+		 * replacement as NULL during replacement replace rdev.
+		 */
+		smp_mb();
+		rdev = rcu_dereference(conf->mirrors[d].rdev);
 		if (rdev == rrdev)
 			rrdev = NULL;
 		if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) {
@@ -2212,11 +2228,22 @@
 {
 	struct r10conf *conf = mddev->private;
 	int d;
-	struct bio *wbio, *wbio2;
+	struct bio *wbio = r10_bio->devs[1].bio;
+	struct bio *wbio2 = r10_bio->devs[1].repl_bio;
+
+	/* Need to test wbio2->bi_end_io before we call
+	 * submit_bio_noacct as if the former is NULL,
+	 * the latter is free to free wbio2.
+	 */
+	if (wbio2 && !wbio2->bi_end_io)
+		wbio2 = NULL;
 
 	if (!test_bit(R10BIO_Uptodate, &r10_bio->state)) {
 		fix_recovery_read_error(r10_bio);
-		end_sync_request(r10_bio);
+		if (wbio->bi_end_io)
+			end_sync_request(r10_bio);
+		if (wbio2)
+			end_sync_request(r10_bio);
 		return;
 	}
 
@@ -2225,14 +2252,6 @@
 	 * and submit the write request
 	 */
 	d = r10_bio->devs[1].devnum;
-	wbio = r10_bio->devs[1].bio;
-	wbio2 = r10_bio->devs[1].repl_bio;
-	/* Need to test wbio2->bi_end_io before we call
-	 * submit_bio_noacct as if the former is NULL,
-	 * the latter is free to free wbio2.
-	 */
-	if (wbio2 && !wbio2->bi_end_io)
-		wbio2 = NULL;
 	if (wbio->bi_end_io) {
 		atomic_inc(&conf->mirrors[d].rdev->nr_pending);
 		md_sync_acct(conf->mirrors[d].rdev->bdev, bio_sectors(wbio));
@@ -2900,10 +2919,6 @@
 	sector_t chunk_mask = conf->geo.chunk_mask;
 	int page_idx = 0;
 
-	if (!mempool_initialized(&conf->r10buf_pool))
-		if (init_resync(conf))
-			return 0;
-
 	/*
 	 * Allow skipping a full rebuild for incremental assembly
 	 * of a clean array, like RAID1 does.
@@ -2918,6 +2933,10 @@
 		*skipped = 1;
 		return mddev->dev_sectors - sector_nr;
 	}
+
+	if (!mempool_initialized(&conf->r10buf_pool))
+		if (init_resync(conf))
+			return 0;
 
  skipped:
 	max_sector = mddev->dev_sectors;
@@ -3034,7 +3053,6 @@
 			int must_sync;
 			int any_working;
 			int need_recover = 0;
-			int need_replace = 0;
 			struct raid10_info *mirror = &conf->mirrors[i];
 			struct md_rdev *mrdev, *mreplace;
 
@@ -3046,11 +3064,10 @@
 			    !test_bit(Faulty, &mrdev->flags) &&
 			    !test_bit(In_sync, &mrdev->flags))
 				need_recover = 1;
-			if (mreplace != NULL &&
-			    !test_bit(Faulty, &mreplace->flags))
-				need_replace = 1;
+			if (mreplace && test_bit(Faulty, &mreplace->flags))
+				mreplace = NULL;
 
-			if (!need_recover && !need_replace) {
+			if (!need_recover && !mreplace) {
 				rcu_read_unlock();
 				continue;
 			}
@@ -3066,8 +3083,6 @@
 				rcu_read_unlock();
 				continue;
 			}
-			if (mreplace && test_bit(Faulty, &mreplace->flags))
-				mreplace = NULL;
 			/* Unless we are doing a full sync, or a replacement
 			 * we only need to recover the block if it is set in
 			 * the bitmap
@@ -3190,11 +3205,11 @@
 				bio = r10_bio->devs[1].repl_bio;
 				if (bio)
 					bio->bi_end_io = NULL;
-				/* Note: if need_replace, then bio
+				/* Note: if replace is not NULL, then bio
 				 * cannot be NULL as r10buf_pool_alloc will
 				 * have allocated it.
 				 */
-				if (!need_replace)
+				if (!mreplace)
 					break;
 				bio->bi_next = biolist;
 				biolist = bio;
@@ -3615,6 +3630,20 @@
 	return nc*fc;
 }
 
+static void raid10_free_conf(struct r10conf *conf)
+{
+	if (!conf)
+		return;
+
+	mempool_exit(&conf->r10bio_pool);
+	kfree(conf->mirrors);
+	kfree(conf->mirrors_old);
+	kfree(conf->mirrors_new);
+	safe_put_page(conf->tmppage);
+	bioset_exit(&conf->bio_split);
+	kfree(conf);
+}
+
 static struct r10conf *setup_conf(struct mddev *mddev)
 {
 	struct r10conf *conf = NULL;
@@ -3697,13 +3726,7 @@
 	return conf;
 
  out:
-	if (conf) {
-		mempool_exit(&conf->r10bio_pool);
-		kfree(conf->mirrors);
-		safe_put_page(conf->tmppage);
-		bioset_exit(&conf->bio_split);
-		kfree(conf);
-	}
+	raid10_free_conf(conf);
 	return ERR_PTR(err);
 }
 
@@ -3741,6 +3764,9 @@
 	if (!conf)
 		goto out;
 
+	mddev->thread = conf->thread;
+	conf->thread = NULL;
+
 	if (mddev_is_clustered(conf->mddev)) {
 		int fc, fo;
 
@@ -3752,9 +3778,6 @@
 			goto out_free_conf;
 		}
 	}
-
-	mddev->thread = conf->thread;
-	conf->thread = NULL;
 
 	if (mddev->queue) {
 		blk_queue_max_discard_sectors(mddev->queue,
@@ -3909,10 +3932,7 @@
 
 out_free_conf:
 	md_unregister_thread(&mddev->thread);
-	mempool_exit(&conf->r10bio_pool);
-	safe_put_page(conf->tmppage);
-	kfree(conf->mirrors);
-	kfree(conf);
+	raid10_free_conf(conf);
 	mddev->private = NULL;
 out:
 	return -EIO;
@@ -3920,15 +3940,7 @@
 
 static void raid10_free(struct mddev *mddev, void *priv)
 {
-	struct r10conf *conf = priv;
-
-	mempool_exit(&conf->r10bio_pool);
-	safe_put_page(conf->tmppage);
-	kfree(conf->mirrors);
-	kfree(conf->mirrors_old);
-	kfree(conf->mirrors_new);
-	bioset_exit(&conf->bio_split);
-	kfree(conf);
+	raid10_free_conf(priv);
 }
 
 static void raid10_quiesce(struct mddev *mddev, int quiesce)
diff --git a/kernel/drivers/media/cec/core/cec-adap.c b/kernel/drivers/media/cec/core/cec-adap.c
index e23aa60..97b4792 100644
--- a/kernel/drivers/media/cec/core/cec-adap.c
+++ b/kernel/drivers/media/cec/core/cec-adap.c
@@ -1085,7 +1085,8 @@
 	mutex_lock(&adap->lock);
 	dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg);
 
-	adap->last_initiator = 0xff;
+	if (!adap->transmit_in_progress)
+		adap->last_initiator = 0xff;
 
 	/* Check if this message was for us (directed or broadcast). */
 	if (!cec_msg_is_broadcast(msg))
diff --git a/kernel/drivers/media/cec/i2c/Kconfig b/kernel/drivers/media/cec/i2c/Kconfig
index 70432a1..d912d14 100644
--- a/kernel/drivers/media/cec/i2c/Kconfig
+++ b/kernel/drivers/media/cec/i2c/Kconfig
@@ -5,6 +5,7 @@
 config CEC_CH7322
 	tristate "Chrontel CH7322 CEC controller"
 	depends on I2C
+	select REGMAP
 	select REGMAP_I2C
 	select CEC_CORE
 	help
diff --git a/kernel/drivers/media/cec/usb/pulse8/pulse8-cec.c b/kernel/drivers/media/cec/usb/pulse8/pulse8-cec.c
index 04b13cd..ba67587 100644
--- a/kernel/drivers/media/cec/usb/pulse8/pulse8-cec.c
+++ b/kernel/drivers/media/cec/usb/pulse8/pulse8-cec.c
@@ -809,8 +809,11 @@
 
 	mutex_lock(&pulse8->lock);
 	cmd = MSGCODE_PING;
-	pulse8_send_and_wait(pulse8, &cmd, 1,
-			     MSGCODE_COMMAND_ACCEPTED, 0);
+	if (pulse8_send_and_wait(pulse8, &cmd, 1,
+				 MSGCODE_COMMAND_ACCEPTED, 0)) {
+		dev_warn(pulse8->dev, "failed to ping EEPROM\n");
+		goto unlock;
+	}
 
 	if (pulse8->vers < 2)
 		goto unlock;
diff --git a/kernel/drivers/media/dvb-core/dvb_ca_en50221.c b/kernel/drivers/media/dvb-core/dvb_ca_en50221.c
index cfc2762..dec036e 100644
--- a/kernel/drivers/media/dvb-core/dvb_ca_en50221.c
+++ b/kernel/drivers/media/dvb-core/dvb_ca_en50221.c
@@ -151,13 +151,19 @@
 
 	/* mutex serializing ioctls */
 	struct mutex ioctl_mutex;
+
+	/* A mutex used when a device is disconnected */
+	struct mutex remove_mutex;
+
+	/* Whether the device is disconnected */
+	int exit;
 };
 
 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);
 
@@ -187,7 +193,7 @@
 static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot,
 				    u8 *ebuf, int ecount);
 static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
-				     u8 *ebuf, int ecount);
+				     u8 *ebuf, int ecount, int size_write_flag);
 
 /**
  * Safely find needle in haystack.
@@ -370,7 +376,7 @@
 	ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_FR, HZ / 10);
 	if (ret)
 		return ret;
-	ret = dvb_ca_en50221_write_data(ca, slot, buf, 2);
+	ret = dvb_ca_en50221_write_data(ca, slot, buf, 2, CMDREG_SW);
 	if (ret != 2)
 		return -EIO;
 	ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN);
@@ -778,11 +784,13 @@
  * @buf: The data in this buffer is treated as a complete link-level packet to
  *	 be written.
  * @bytes_write: Size of ebuf.
+ * @size_write_flag: A flag on Command Register which says whether the link size
+ * information will be writen or not.
  *
  * return: Number of bytes written, or < 0 on error.
  */
 static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
-				     u8 *buf, int bytes_write)
+				     u8 *buf, int bytes_write, int size_write_flag)
 {
 	struct dvb_ca_slot *sl = &ca->slot_info[slot];
 	int status;
@@ -817,7 +825,7 @@
 
 	/* OK, set HC bit */
 	status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND,
-					    IRQEN | CMDREG_HC);
+					    IRQEN | CMDREG_HC | size_write_flag);
 	if (status)
 		goto exit;
 
@@ -1505,7 +1513,7 @@
 
 			mutex_lock(&sl->slot_lock);
 			status = dvb_ca_en50221_write_data(ca, slot, fragbuf,
-							   fraglen + 2);
+							   fraglen + 2, 0);
 			mutex_unlock(&sl->slot_lock);
 			if (status == (fraglen + 2)) {
 				written = 1;
@@ -1706,12 +1714,22 @@
 
 	dprintk("%s\n", __func__);
 
-	if (!try_module_get(ca->pub->owner))
+	mutex_lock(&ca->remove_mutex);
+
+	if (ca->exit) {
+		mutex_unlock(&ca->remove_mutex);
+		return -ENODEV;
+	}
+
+	if (!try_module_get(ca->pub->owner)) {
+		mutex_unlock(&ca->remove_mutex);
 		return -EIO;
+	}
 
 	err = dvb_generic_open(inode, file);
 	if (err < 0) {
 		module_put(ca->pub->owner);
+		mutex_unlock(&ca->remove_mutex);
 		return err;
 	}
 
@@ -1736,6 +1754,7 @@
 
 	dvb_ca_private_get(ca);
 
+	mutex_unlock(&ca->remove_mutex);
 	return 0;
 }
 
@@ -1755,6 +1774,8 @@
 
 	dprintk("%s\n", __func__);
 
+	mutex_lock(&ca->remove_mutex);
+
 	/* mark the CA device as closed */
 	ca->open = 0;
 	dvb_ca_en50221_thread_update_delay(ca);
@@ -1764,6 +1785,13 @@
 	module_put(ca->pub->owner);
 
 	dvb_ca_private_put(ca);
+
+	if (dvbdev->users == 1 && ca->exit == 1) {
+		mutex_unlock(&ca->remove_mutex);
+		wake_up(&dvbdev->wait_queue);
+	} else {
+		mutex_unlock(&ca->remove_mutex);
+	}
 
 	return err;
 }
@@ -1888,6 +1916,7 @@
 	}
 
 	mutex_init(&ca->ioctl_mutex);
+	mutex_init(&ca->remove_mutex);
 
 	if (signal_pending(current)) {
 		ret = -EINTR;
@@ -1930,6 +1959,14 @@
 
 	dprintk("%s\n", __func__);
 
+	mutex_lock(&ca->remove_mutex);
+	ca->exit = 1;
+	mutex_unlock(&ca->remove_mutex);
+
+	if (ca->dvbdev->users < 1)
+		wait_event(ca->dvbdev->wait_queue,
+				ca->dvbdev->users == 1);
+
 	/* shutdown the thread if there was one */
 	kthread_stop(ca->thread);
 
diff --git a/kernel/drivers/media/dvb-core/dvb_demux.c b/kernel/drivers/media/dvb-core/dvb_demux.c
index 5fde1d3..80b4959 100644
--- a/kernel/drivers/media/dvb-core/dvb_demux.c
+++ b/kernel/drivers/media/dvb-core/dvb_demux.c
@@ -125,12 +125,12 @@
 
 	cc = buf[3] & 0x0f;
 	ccok = ((feed->cc + 1) & 0x0f) == cc;
-	feed->cc = cc;
 	if (!ccok) {
 		set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
 		dprintk_sect_loss("missed packet: %d instead of %d!\n",
 				  cc, (feed->cc + 1) & 0x0f);
 	}
+	feed->cc = cc;
 
 	if (buf[1] & 0x40)	// PUSI ?
 		feed->peslen = 0xfffa;
@@ -310,7 +310,6 @@
 
 	cc = buf[3] & 0x0f;
 	ccok = ((feed->cc + 1) & 0x0f) == cc;
-	feed->cc = cc;
 
 	if (buf[3] & 0x20) {
 		/* adaption field present, check for discontinuity_indicator */
@@ -346,6 +345,7 @@
 		feed->pusi_seen = false;
 		dvb_dmx_swfilter_section_new(feed);
 	}
+	feed->cc = cc;
 
 	if (buf[1] & 0x40) {
 		/* PUSI=1 (is set), section boundary is here */
diff --git a/kernel/drivers/media/dvb-core/dvb_frontend.c b/kernel/drivers/media/dvb-core/dvb_frontend.c
index 06ea30a..ad3e42a 100644
--- a/kernel/drivers/media/dvb-core/dvb_frontend.c
+++ b/kernel/drivers/media/dvb-core/dvb_frontend.c
@@ -135,7 +135,7 @@
 	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);
 
@@ -292,14 +292,22 @@
 	}
 
 	if (events->eventw == events->eventr) {
-		int ret;
+		struct wait_queue_entry wait;
+		int ret = 0;
 
 		if (flags & O_NONBLOCK)
 			return -EWOULDBLOCK;
 
-		ret = wait_event_interruptible(events->wait_queue,
-					       dvb_frontend_test_event(fepriv, events));
-
+		init_waitqueue_entry(&wait, current);
+		add_wait_queue(&events->wait_queue, &wait);
+		while (!dvb_frontend_test_event(fepriv, events)) {
+			wait_woken(&wait, TASK_INTERRUPTIBLE, 0);
+			if (signal_pending(current)) {
+				ret = -ERESTARTSYS;
+				break;
+			}
+		}
+		remove_wait_queue(&events->wait_queue, &wait);
 		if (ret < 0)
 			return ret;
 	}
@@ -2961,6 +2969,7 @@
 		.name = fe->ops.info.name,
 #endif
 	};
+	int ret;
 
 	dev_dbg(dvb->device, "%s:\n", __func__);
 
@@ -2994,8 +3003,13 @@
 		 "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
diff --git a/kernel/drivers/media/dvb-core/dvb_net.c b/kernel/drivers/media/dvb-core/dvb_net.c
index dddebea..c594b1b 100644
--- a/kernel/drivers/media/dvb-core/dvb_net.c
+++ b/kernel/drivers/media/dvb-core/dvb_net.c
@@ -1564,15 +1564,43 @@
 	return dvb_usercopy(file, cmd, arg, dvb_net_do_ioctl);
 }
 
+static int locked_dvb_net_open(struct inode *inode, struct file *file)
+{
+	struct dvb_device *dvbdev = file->private_data;
+	struct dvb_net *dvbnet = dvbdev->priv;
+	int ret;
+
+	if (mutex_lock_interruptible(&dvbnet->remove_mutex))
+		return -ERESTARTSYS;
+
+	if (dvbnet->exit) {
+		mutex_unlock(&dvbnet->remove_mutex);
+		return -ENODEV;
+	}
+
+	ret = dvb_generic_open(inode, file);
+
+	mutex_unlock(&dvbnet->remove_mutex);
+
+	return ret;
+}
+
 static int dvb_net_close(struct inode *inode, struct file *file)
 {
 	struct dvb_device *dvbdev = file->private_data;
 	struct dvb_net *dvbnet = dvbdev->priv;
 
+	mutex_lock(&dvbnet->remove_mutex);
+
 	dvb_generic_release(inode, file);
 
-	if(dvbdev->users == 1 && dvbnet->exit == 1)
+	if (dvbdev->users == 1 && dvbnet->exit == 1) {
+		mutex_unlock(&dvbnet->remove_mutex);
 		wake_up(&dvbdev->wait_queue);
+	} else {
+		mutex_unlock(&dvbnet->remove_mutex);
+	}
+
 	return 0;
 }
 
@@ -1580,7 +1608,7 @@
 static const struct file_operations dvb_net_fops = {
 	.owner = THIS_MODULE,
 	.unlocked_ioctl = dvb_net_ioctl,
-	.open =	dvb_generic_open,
+	.open =	locked_dvb_net_open,
 	.release = dvb_net_close,
 	.llseek = noop_llseek,
 };
@@ -1599,10 +1627,13 @@
 {
 	int i;
 
+	mutex_lock(&dvbnet->remove_mutex);
 	dvbnet->exit = 1;
+	mutex_unlock(&dvbnet->remove_mutex);
+
 	if (dvbnet->dvbdev->users < 1)
 		wait_event(dvbnet->dvbdev->wait_queue,
-				dvbnet->dvbdev->users==1);
+				dvbnet->dvbdev->users == 1);
 
 	dvb_unregister_device(dvbnet->dvbdev);
 
@@ -1621,6 +1652,7 @@
 	int i;
 
 	mutex_init(&dvbnet->ioctl_mutex);
+	mutex_init(&dvbnet->remove_mutex);
 	dvbnet->demux = dmx;
 
 	for (i=0; i<DVB_NET_DEVICES_MAX; i++)
diff --git a/kernel/drivers/media/dvb-core/dvbdev.c b/kernel/drivers/media/dvb-core/dvbdev.c
index ec9ebff..2ff8a1b 100644
--- a/kernel/drivers/media/dvb-core/dvbdev.c
+++ b/kernel/drivers/media/dvb-core/dvbdev.c
@@ -37,6 +37,7 @@
 #include <media/tuner.h>
 
 static DEFINE_MUTEX(dvbdev_mutex);
+static LIST_HEAD(dvbdevfops_list);
 static int dvbdev_debug;
 
 module_param(dvbdev_debug, int, 0644);
@@ -107,7 +108,7 @@
 		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 +172,9 @@
 	}
 
 	dvbdev->users++;
+
+	dvb_device_put(dvbdev);
+
 	return 0;
 }
 EXPORT_SYMBOL(dvb_generic_release);
@@ -342,6 +346,7 @@
 				       GFP_KERNEL);
 		if (!dvbdev->pads) {
 			kfree(dvbdev->entity);
+			dvbdev->entity = NULL;
 			return -ENOMEM;
 		}
 	}
@@ -458,14 +463,15 @@
 			enum dvb_device_type type, int demux_sink_pads)
 {
 	struct dvb_device *dvbdev;
-	struct file_operations *dvbdevfops;
+	struct file_operations *dvbdevfops = NULL;
+	struct dvbdevfops_node *node = NULL, *new_node = NULL;
 	struct device *clsdev;
 	int minor;
 	int id, ret;
 
 	mutex_lock(&dvbdev_register_lock);
 
-	if ((id = dvbdev_get_free_id (adap, type)) < 0){
+	if ((id = dvbdev_get_free_id (adap, type)) < 0) {
 		mutex_unlock(&dvbdev_register_lock);
 		*pdvbdev = NULL;
 		pr_err("%s: couldn't find free device id\n", __func__);
@@ -473,40 +479,69 @@
 	}
 
 	*pdvbdev = dvbdev = kzalloc(sizeof(*dvbdev), GFP_KERNEL);
-
 	if (!dvbdev){
 		mutex_unlock(&dvbdev_register_lock);
 		return -ENOMEM;
 	}
 
-	dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL);
+	/*
+	 * When a device of the same type is probe()d more than once,
+	 * the first allocated fops are used. This prevents memory leaks
+	 * that can occur when the same device is probe()d repeatedly.
+	 */
+	list_for_each_entry(node, &dvbdevfops_list, list_head) {
+		if (node->fops->owner == adap->module &&
+				node->type == type &&
+				node->template == template) {
+			dvbdevfops = node->fops;
+			break;
+		}
+	}
 
-	if (!dvbdevfops){
-		kfree (dvbdev);
-		mutex_unlock(&dvbdev_register_lock);
-		return -ENOMEM;
+	if (dvbdevfops == NULL) {
+		dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL);
+		if (!dvbdevfops) {
+			kfree(dvbdev);
+			mutex_unlock(&dvbdev_register_lock);
+			return -ENOMEM;
+		}
+
+		new_node = kzalloc(sizeof(struct dvbdevfops_node), GFP_KERNEL);
+		if (!new_node) {
+			kfree(dvbdevfops);
+			kfree(dvbdev);
+			mutex_unlock(&dvbdev_register_lock);
+			return -ENOMEM;
+		}
+
+		new_node->fops = dvbdevfops;
+		new_node->type = type;
+		new_node->template = template;
+		list_add_tail (&new_node->list_head, &dvbdevfops_list);
 	}
 
 	memcpy(dvbdev, template, sizeof(struct dvb_device));
+	kref_init(&dvbdev->ref);
 	dvbdev->type = type;
 	dvbdev->id = id;
 	dvbdev->adapter = adap;
 	dvbdev->priv = priv;
 	dvbdev->fops = dvbdevfops;
 	init_waitqueue_head (&dvbdev->wait_queue);
-
 	dvbdevfops->owner = adap->module;
-
 	list_add_tail (&dvbdev->list_head, &adap->device_list);
-
 	down_write(&minor_rwsem);
 #ifdef CONFIG_DVB_DYNAMIC_MINORS
 	for (minor = 0; minor < MAX_DVB_MINORS; minor++)
 		if (dvb_minors[minor] == NULL)
 			break;
-
 	if (minor == MAX_DVB_MINORS) {
-		kfree(dvbdevfops);
+		if (new_node) {
+			list_del (&new_node->list_head);
+			kfree(dvbdevfops);
+			kfree(new_node);
+		}
+		list_del (&dvbdev->list_head);
 		kfree(dvbdev);
 		up_write(&minor_rwsem);
 		mutex_unlock(&dvbdev_register_lock);
@@ -515,24 +550,24 @@
 #else
 	minor = nums2minor(adap->num, type, id);
 #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);
 	if (ret) {
 		pr_err("%s: dvb_register_media_device failed to create the mediagraph\n",
 		      __func__);
-
+		if (new_node) {
+			list_del (&new_node->list_head);
+			kfree(dvbdevfops);
+			kfree(new_node);
+		}
 		dvb_media_device_free(dvbdev);
-		kfree(dvbdevfops);
+		list_del (&dvbdev->list_head);
 		kfree(dvbdev);
 		mutex_unlock(&dvbdev_register_lock);
 		return ret;
 	}
-
-	mutex_unlock(&dvbdev_register_lock);
 
 	clsdev = device_create(dvb_class, adap->device,
 			       MKDEV(DVB_MAJOR, minor),
@@ -540,11 +575,22 @@
 	if (IS_ERR(clsdev)) {
 		pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n",
 		       __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
+		if (new_node) {
+			list_del (&new_node->list_head);
+			kfree(dvbdevfops);
+			kfree(new_node);
+		}
+		dvb_media_device_free(dvbdev);
+		list_del (&dvbdev->list_head);
+		kfree(dvbdev);
+		mutex_unlock(&dvbdev_register_lock);
 		return PTR_ERR(clsdev);
 	}
+
 	dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
 		adap->num, dnames[type], id, minor, minor);
 
+	mutex_unlock(&dvbdev_register_lock);
 	return 0;
 }
 EXPORT_SYMBOL(dvb_register_device);
@@ -557,6 +603,7 @@
 
 	down_write(&minor_rwsem);
 	dvb_minors[dvbdev->minor] = NULL;
+	dvb_device_put(dvbdev);
 	up_write(&minor_rwsem);
 
 	dvb_media_device_free(dvbdev);
@@ -568,21 +615,33 @@
 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);
 
@@ -1065,9 +1124,17 @@
 
 static void __exit exit_dvbdev(void)
 {
+	struct dvbdevfops_node *node, *next;
+
 	class_destroy(dvb_class);
 	cdev_del(&dvb_device_cdev);
 	unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
+
+	list_for_each_entry_safe(node, next, &dvbdevfops_list, list_head) {
+		list_del (&node->list_head);
+		kfree(node->fops);
+		kfree(node);
+	}
 }
 
 subsys_initcall(init_dvbdev);
diff --git a/kernel/drivers/media/dvb-frontends/ascot2e.c b/kernel/drivers/media/dvb-frontends/ascot2e.c
index 9b00b56..cf8e5f1 100644
--- a/kernel/drivers/media/dvb-frontends/ascot2e.c
+++ b/kernel/drivers/media/dvb-frontends/ascot2e.c
@@ -533,7 +533,7 @@
 		priv->i2c_address, priv->i2c);
 	return fe;
 }
-EXPORT_SYMBOL(ascot2e_attach);
+EXPORT_SYMBOL_GPL(ascot2e_attach);
 
 MODULE_DESCRIPTION("Sony ASCOT2E terr/cab tuner driver");
 MODULE_AUTHOR("info@netup.ru");
diff --git a/kernel/drivers/media/dvb-frontends/atbm8830.c b/kernel/drivers/media/dvb-frontends/atbm8830.c
index bdd16b9..778c865 100644
--- a/kernel/drivers/media/dvb-frontends/atbm8830.c
+++ b/kernel/drivers/media/dvb-frontends/atbm8830.c
@@ -489,7 +489,7 @@
 	return NULL;
 
 }
-EXPORT_SYMBOL(atbm8830_attach);
+EXPORT_SYMBOL_GPL(atbm8830_attach);
 
 MODULE_DESCRIPTION("AltoBeam ATBM8830/8831 GB20600 demodulator driver");
 MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
diff --git a/kernel/drivers/media/dvb-frontends/au8522_dig.c b/kernel/drivers/media/dvb-frontends/au8522_dig.c
index 78cafdf..230436b 100644
--- a/kernel/drivers/media/dvb-frontends/au8522_dig.c
+++ b/kernel/drivers/media/dvb-frontends/au8522_dig.c
@@ -879,7 +879,7 @@
 	au8522_release_state(state);
 	return NULL;
 }
-EXPORT_SYMBOL(au8522_attach);
+EXPORT_SYMBOL_GPL(au8522_attach);
 
 static const struct dvb_frontend_ops au8522_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
diff --git a/kernel/drivers/media/dvb-frontends/bcm3510.c b/kernel/drivers/media/dvb-frontends/bcm3510.c
index da0ff7b..b3f5c49 100644
--- a/kernel/drivers/media/dvb-frontends/bcm3510.c
+++ b/kernel/drivers/media/dvb-frontends/bcm3510.c
@@ -649,6 +649,7 @@
 		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;
@@ -834,7 +835,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(bcm3510_attach);
+EXPORT_SYMBOL_GPL(bcm3510_attach);
 
 static const struct dvb_frontend_ops bcm3510_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
diff --git a/kernel/drivers/media/dvb-frontends/cx22700.c b/kernel/drivers/media/dvb-frontends/cx22700.c
index b39ff51..1d04c0a 100644
--- a/kernel/drivers/media/dvb-frontends/cx22700.c
+++ b/kernel/drivers/media/dvb-frontends/cx22700.c
@@ -432,4 +432,4 @@
 MODULE_AUTHOR("Holger Waechtler");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(cx22700_attach);
+EXPORT_SYMBOL_GPL(cx22700_attach);
diff --git a/kernel/drivers/media/dvb-frontends/cx22702.c b/kernel/drivers/media/dvb-frontends/cx22702.c
index cc6acbf..61ad34b 100644
--- a/kernel/drivers/media/dvb-frontends/cx22702.c
+++ b/kernel/drivers/media/dvb-frontends/cx22702.c
@@ -604,7 +604,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(cx22702_attach);
+EXPORT_SYMBOL_GPL(cx22702_attach);
 
 static const struct dvb_frontend_ops cx22702_ops = {
 	.delsys = { SYS_DVBT },
diff --git a/kernel/drivers/media/dvb-frontends/cx24110.c b/kernel/drivers/media/dvb-frontends/cx24110.c
index 6f99d6a..9aeea08 100644
--- a/kernel/drivers/media/dvb-frontends/cx24110.c
+++ b/kernel/drivers/media/dvb-frontends/cx24110.c
@@ -653,4 +653,4 @@
 MODULE_AUTHOR("Peter Hettkamp");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(cx24110_attach);
+EXPORT_SYMBOL_GPL(cx24110_attach);
diff --git a/kernel/drivers/media/dvb-frontends/cx24113.c b/kernel/drivers/media/dvb-frontends/cx24113.c
index 60a9f70..619df83 100644
--- a/kernel/drivers/media/dvb-frontends/cx24113.c
+++ b/kernel/drivers/media/dvb-frontends/cx24113.c
@@ -590,7 +590,7 @@
 
 	return NULL;
 }
-EXPORT_SYMBOL(cx24113_attach);
+EXPORT_SYMBOL_GPL(cx24113_attach);
 
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
diff --git a/kernel/drivers/media/dvb-frontends/cx24116.c b/kernel/drivers/media/dvb-frontends/cx24116.c
index ea8264c..8b978a9 100644
--- a/kernel/drivers/media/dvb-frontends/cx24116.c
+++ b/kernel/drivers/media/dvb-frontends/cx24116.c
@@ -1133,7 +1133,7 @@
 	state->frontend.demodulator_priv = state;
 	return &state->frontend;
 }
-EXPORT_SYMBOL(cx24116_attach);
+EXPORT_SYMBOL_GPL(cx24116_attach);
 
 /*
  * Initialise or wake up device
diff --git a/kernel/drivers/media/dvb-frontends/cx24120.c b/kernel/drivers/media/dvb-frontends/cx24120.c
index 2464b63..0fa0336 100644
--- a/kernel/drivers/media/dvb-frontends/cx24120.c
+++ b/kernel/drivers/media/dvb-frontends/cx24120.c
@@ -305,7 +305,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(cx24120_attach);
+EXPORT_SYMBOL_GPL(cx24120_attach);
 
 static int cx24120_test_rom(struct cx24120_state *state)
 {
@@ -972,7 +972,9 @@
 	cmd.arg[8] = (clock_ratios_table[idx].rate >> 8) & 0xff;
 	cmd.arg[9] = (clock_ratios_table[idx].rate >> 0) & 0xff;
 
-	cx24120_message_send(state, &cmd);
+	ret = cx24120_message_send(state, &cmd);
+	if (ret != 0)
+		return;
 
 	/* Calculate ber window rates for stat work */
 	cx24120_calculate_ber_window(state, clock_ratios_table[idx].rate);
diff --git a/kernel/drivers/media/dvb-frontends/cx24123.c b/kernel/drivers/media/dvb-frontends/cx24123.c
index 3d84ee1..539889e 100644
--- a/kernel/drivers/media/dvb-frontends/cx24123.c
+++ b/kernel/drivers/media/dvb-frontends/cx24123.c
@@ -1096,7 +1096,7 @@
 
 	return NULL;
 }
-EXPORT_SYMBOL(cx24123_attach);
+EXPORT_SYMBOL_GPL(cx24123_attach);
 
 static const struct dvb_frontend_ops cx24123_ops = {
 	.delsys = { SYS_DVBS },
diff --git a/kernel/drivers/media/dvb-frontends/cxd2820r_core.c b/kernel/drivers/media/dvb-frontends/cxd2820r_core.c
index b161833..b0e6343 100644
--- a/kernel/drivers/media/dvb-frontends/cxd2820r_core.c
+++ b/kernel/drivers/media/dvb-frontends/cxd2820r_core.c
@@ -536,7 +536,7 @@
 
 	return pdata.get_dvb_frontend(client);
 }
-EXPORT_SYMBOL(cxd2820r_attach);
+EXPORT_SYMBOL_GPL(cxd2820r_attach);
 
 static struct dvb_frontend *cxd2820r_get_dvb_frontend(struct i2c_client *client)
 {
diff --git a/kernel/drivers/media/dvb-frontends/cxd2841er.c b/kernel/drivers/media/dvb-frontends/cxd2841er.c
index 758c95b..493ba8b 100644
--- a/kernel/drivers/media/dvb-frontends/cxd2841er.c
+++ b/kernel/drivers/media/dvb-frontends/cxd2841er.c
@@ -3930,14 +3930,14 @@
 {
 	return cxd2841er_attach(cfg, i2c, SYS_DVBS);
 }
-EXPORT_SYMBOL(cxd2841er_attach_s);
+EXPORT_SYMBOL_GPL(cxd2841er_attach_s);
 
 struct dvb_frontend *cxd2841er_attach_t_c(struct cxd2841er_config *cfg,
 					struct i2c_adapter *i2c)
 {
 	return cxd2841er_attach(cfg, i2c, 0);
 }
-EXPORT_SYMBOL(cxd2841er_attach_t_c);
+EXPORT_SYMBOL_GPL(cxd2841er_attach_t_c);
 
 static const struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = {
 	.delsys = { SYS_DVBS, SYS_DVBS2 },
diff --git a/kernel/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c b/kernel/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c
index d5b1b37..09d31c3 100644
--- a/kernel/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c
+++ b/kernel/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c
@@ -1950,7 +1950,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(cxd2880_attach);
+EXPORT_SYMBOL_GPL(cxd2880_attach);
 
 MODULE_DESCRIPTION("Sony CXD2880 DVB-T2/T tuner + demod driver");
 MODULE_AUTHOR("Sony Semiconductor Solutions Corporation");
diff --git a/kernel/drivers/media/dvb-frontends/dib0070.c b/kernel/drivers/media/dvb-frontends/dib0070.c
index cafb41d..9a8e7cd 100644
--- a/kernel/drivers/media/dvb-frontends/dib0070.c
+++ b/kernel/drivers/media/dvb-frontends/dib0070.c
@@ -762,7 +762,7 @@
 	fe->tuner_priv = NULL;
 	return NULL;
 }
-EXPORT_SYMBOL(dib0070_attach);
+EXPORT_SYMBOL_GPL(dib0070_attach);
 
 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for the DiBcom 0070 base-band RF Tuner");
diff --git a/kernel/drivers/media/dvb-frontends/dib0090.c b/kernel/drivers/media/dvb-frontends/dib0090.c
index 08a8583..bb2fc12 100644
--- a/kernel/drivers/media/dvb-frontends/dib0090.c
+++ b/kernel/drivers/media/dvb-frontends/dib0090.c
@@ -2632,7 +2632,7 @@
 	return NULL;
 }
 
-EXPORT_SYMBOL(dib0090_register);
+EXPORT_SYMBOL_GPL(dib0090_register);
 
 struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
 {
@@ -2658,7 +2658,7 @@
 	fe->tuner_priv = NULL;
 	return NULL;
 }
-EXPORT_SYMBOL(dib0090_fw_register);
+EXPORT_SYMBOL_GPL(dib0090_fw_register);
 
 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_AUTHOR("Olivier Grenie <olivier.grenie@parrot.com>");
diff --git a/kernel/drivers/media/dvb-frontends/dib3000mb.c b/kernel/drivers/media/dvb-frontends/dib3000mb.c
index a6c2fc4..c598b2a 100644
--- a/kernel/drivers/media/dvb-frontends/dib3000mb.c
+++ b/kernel/drivers/media/dvb-frontends/dib3000mb.c
@@ -815,4 +815,4 @@
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(dib3000mb_attach);
+EXPORT_SYMBOL_GPL(dib3000mb_attach);
diff --git a/kernel/drivers/media/dvb-frontends/dib3000mc.c b/kernel/drivers/media/dvb-frontends/dib3000mc.c
index 692600c..c696650 100644
--- a/kernel/drivers/media/dvb-frontends/dib3000mc.c
+++ b/kernel/drivers/media/dvb-frontends/dib3000mc.c
@@ -935,7 +935,7 @@
 	kfree(st);
 	return NULL;
 }
-EXPORT_SYMBOL(dib3000mc_attach);
+EXPORT_SYMBOL_GPL(dib3000mc_attach);
 
 static const struct dvb_frontend_ops dib3000mc_ops = {
 	.delsys = { SYS_DVBT },
diff --git a/kernel/drivers/media/dvb-frontends/dib7000m.c b/kernel/drivers/media/dvb-frontends/dib7000m.c
index 97ce977..fdb22f3 100644
--- a/kernel/drivers/media/dvb-frontends/dib7000m.c
+++ b/kernel/drivers/media/dvb-frontends/dib7000m.c
@@ -1434,7 +1434,7 @@
 	kfree(st);
 	return NULL;
 }
-EXPORT_SYMBOL(dib7000m_attach);
+EXPORT_SYMBOL_GPL(dib7000m_attach);
 
 static const struct dvb_frontend_ops dib7000m_ops = {
 	.delsys = { SYS_DVBT },
diff --git a/kernel/drivers/media/dvb-frontends/dib7000p.c b/kernel/drivers/media/dvb-frontends/dib7000p.c
index 55bee50..8c426baf 100644
--- a/kernel/drivers/media/dvb-frontends/dib7000p.c
+++ b/kernel/drivers/media/dvb-frontends/dib7000p.c
@@ -497,7 +497,7 @@
 	prediv = reg_1856 & 0x3f;
 	loopdiv = (reg_1856 >> 6) & 0x3f;
 
-	if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
+	if (loopdiv && bw && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
 		dprintk("Updating pll (prediv: old =  %d new = %d ; loopdiv : old = %d new = %d)\n", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
 		reg_1856 &= 0xf000;
 		reg_1857 = dib7000p_read_word(state, 1857);
@@ -2822,7 +2822,7 @@
 
 	return ops;
 }
-EXPORT_SYMBOL(dib7000p_attach);
+EXPORT_SYMBOL_GPL(dib7000p_attach);
 
 static const struct dvb_frontend_ops dib7000p_ops = {
 	.delsys = { SYS_DVBT },
diff --git a/kernel/drivers/media/dvb-frontends/dib8000.c b/kernel/drivers/media/dvb-frontends/dib8000.c
index d67f2dd..02cb482 100644
--- a/kernel/drivers/media/dvb-frontends/dib8000.c
+++ b/kernel/drivers/media/dvb-frontends/dib8000.c
@@ -4527,7 +4527,7 @@
 
 	return ops;
 }
-EXPORT_SYMBOL(dib8000_attach);
+EXPORT_SYMBOL_GPL(dib8000_attach);
 
 MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@parrot.com, Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
diff --git a/kernel/drivers/media/dvb-frontends/dib9000.c b/kernel/drivers/media/dvb-frontends/dib9000.c
index 04d92d6..24f7f7a 100644
--- a/kernel/drivers/media/dvb-frontends/dib9000.c
+++ b/kernel/drivers/media/dvb-frontends/dib9000.c
@@ -2546,7 +2546,7 @@
 	kfree(st);
 	return NULL;
 }
-EXPORT_SYMBOL(dib9000_attach);
+EXPORT_SYMBOL_GPL(dib9000_attach);
 
 static const struct dvb_frontend_ops dib9000_ops = {
 	.delsys = { SYS_DVBT },
diff --git a/kernel/drivers/media/dvb-frontends/drx39xyj/drxj.c b/kernel/drivers/media/dvb-frontends/drx39xyj/drxj.c
index 237b9d0..499b37b 100644
--- a/kernel/drivers/media/dvb-frontends/drx39xyj/drxj.c
+++ b/kernel/drivers/media/dvb-frontends/drx39xyj/drxj.c
@@ -12375,7 +12375,7 @@
 
 	return NULL;
 }
-EXPORT_SYMBOL(drx39xxj_attach);
+EXPORT_SYMBOL_GPL(drx39xxj_attach);
 
 static const struct dvb_frontend_ops drx39xxj_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
diff --git a/kernel/drivers/media/dvb-frontends/drxd_hard.c b/kernel/drivers/media/dvb-frontends/drxd_hard.c
index 45f9828..e3236ad 100644
--- a/kernel/drivers/media/dvb-frontends/drxd_hard.c
+++ b/kernel/drivers/media/dvb-frontends/drxd_hard.c
@@ -2948,7 +2948,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(drxd_attach);
+EXPORT_SYMBOL_GPL(drxd_attach);
 
 MODULE_DESCRIPTION("DRXD driver");
 MODULE_AUTHOR("Micronas");
diff --git a/kernel/drivers/media/dvb-frontends/drxk_hard.c b/kernel/drivers/media/dvb-frontends/drxk_hard.c
index 2134e25..a6b86c1 100644
--- a/kernel/drivers/media/dvb-frontends/drxk_hard.c
+++ b/kernel/drivers/media/dvb-frontends/drxk_hard.c
@@ -6845,7 +6845,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(drxk_attach);
+EXPORT_SYMBOL_GPL(drxk_attach);
 
 MODULE_DESCRIPTION("DRX-K driver");
 MODULE_AUTHOR("Ralph Metzler");
diff --git a/kernel/drivers/media/dvb-frontends/ds3000.c b/kernel/drivers/media/dvb-frontends/ds3000.c
index 20fcf31..515aa7c 100644
--- a/kernel/drivers/media/dvb-frontends/ds3000.c
+++ b/kernel/drivers/media/dvb-frontends/ds3000.c
@@ -859,7 +859,7 @@
 	ds3000_set_voltage(&state->frontend, SEC_VOLTAGE_OFF);
 	return &state->frontend;
 }
-EXPORT_SYMBOL(ds3000_attach);
+EXPORT_SYMBOL_GPL(ds3000_attach);
 
 static int ds3000_set_carrier_offset(struct dvb_frontend *fe,
 					s32 carrier_offset_khz)
diff --git a/kernel/drivers/media/dvb-frontends/dvb-pll.c b/kernel/drivers/media/dvb-frontends/dvb-pll.c
index d45b4dd..846bfe7 100644
--- a/kernel/drivers/media/dvb-frontends/dvb-pll.c
+++ b/kernel/drivers/media/dvb-frontends/dvb-pll.c
@@ -866,7 +866,7 @@
 
 	return NULL;
 }
-EXPORT_SYMBOL(dvb_pll_attach);
+EXPORT_SYMBOL_GPL(dvb_pll_attach);
 
 
 static int
diff --git a/kernel/drivers/media/dvb-frontends/ec100.c b/kernel/drivers/media/dvb-frontends/ec100.c
index 03bd806..2ad0a3c 100644
--- a/kernel/drivers/media/dvb-frontends/ec100.c
+++ b/kernel/drivers/media/dvb-frontends/ec100.c
@@ -299,7 +299,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(ec100_attach);
+EXPORT_SYMBOL_GPL(ec100_attach);
 
 static const struct dvb_frontend_ops ec100_ops = {
 	.delsys = { SYS_DVBT },
diff --git a/kernel/drivers/media/dvb-frontends/helene.c b/kernel/drivers/media/dvb-frontends/helene.c
index 8c1310c..c299d31 100644
--- a/kernel/drivers/media/dvb-frontends/helene.c
+++ b/kernel/drivers/media/dvb-frontends/helene.c
@@ -1025,7 +1025,7 @@
 			priv->i2c_address, priv->i2c);
 	return fe;
 }
-EXPORT_SYMBOL(helene_attach_s);
+EXPORT_SYMBOL_GPL(helene_attach_s);
 
 struct dvb_frontend *helene_attach(struct dvb_frontend *fe,
 		const struct helene_config *config,
@@ -1061,7 +1061,7 @@
 			priv->i2c_address, priv->i2c);
 	return fe;
 }
-EXPORT_SYMBOL(helene_attach);
+EXPORT_SYMBOL_GPL(helene_attach);
 
 static int helene_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
diff --git a/kernel/drivers/media/dvb-frontends/horus3a.c b/kernel/drivers/media/dvb-frontends/horus3a.c
index 24bf5cb..0330b78 100644
--- a/kernel/drivers/media/dvb-frontends/horus3a.c
+++ b/kernel/drivers/media/dvb-frontends/horus3a.c
@@ -395,7 +395,7 @@
 		priv->i2c_address, priv->i2c);
 	return fe;
 }
-EXPORT_SYMBOL(horus3a_attach);
+EXPORT_SYMBOL_GPL(horus3a_attach);
 
 MODULE_DESCRIPTION("Sony HORUS3A satellite tuner driver");
 MODULE_AUTHOR("Sergey Kozlov <serjk@netup.ru>");
diff --git a/kernel/drivers/media/dvb-frontends/isl6405.c b/kernel/drivers/media/dvb-frontends/isl6405.c
index 2cd69b4..7d28a74 100644
--- a/kernel/drivers/media/dvb-frontends/isl6405.c
+++ b/kernel/drivers/media/dvb-frontends/isl6405.c
@@ -141,7 +141,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(isl6405_attach);
+EXPORT_SYMBOL_GPL(isl6405_attach);
 
 MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6405");
 MODULE_AUTHOR("Hartmut Hackmann & Oliver Endriss");
diff --git a/kernel/drivers/media/dvb-frontends/isl6421.c b/kernel/drivers/media/dvb-frontends/isl6421.c
index 43b0dfc..2e9f6f1 100644
--- a/kernel/drivers/media/dvb-frontends/isl6421.c
+++ b/kernel/drivers/media/dvb-frontends/isl6421.c
@@ -213,7 +213,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(isl6421_attach);
+EXPORT_SYMBOL_GPL(isl6421_attach);
 
 MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421");
 MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss");
diff --git a/kernel/drivers/media/dvb-frontends/isl6423.c b/kernel/drivers/media/dvb-frontends/isl6423.c
index 8cd1bb8..a0d0a38 100644
--- a/kernel/drivers/media/dvb-frontends/isl6423.c
+++ b/kernel/drivers/media/dvb-frontends/isl6423.c
@@ -289,7 +289,7 @@
 	fe->sec_priv = NULL;
 	return NULL;
 }
-EXPORT_SYMBOL(isl6423_attach);
+EXPORT_SYMBOL_GPL(isl6423_attach);
 
 MODULE_DESCRIPTION("ISL6423 SEC");
 MODULE_AUTHOR("Manu Abraham");
diff --git a/kernel/drivers/media/dvb-frontends/itd1000.c b/kernel/drivers/media/dvb-frontends/itd1000.c
index 1b33478..f8f362f 100644
--- a/kernel/drivers/media/dvb-frontends/itd1000.c
+++ b/kernel/drivers/media/dvb-frontends/itd1000.c
@@ -389,7 +389,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(itd1000_attach);
+EXPORT_SYMBOL_GPL(itd1000_attach);
 
 MODULE_AUTHOR("Patrick Boettcher <pb@linuxtv.org>");
 MODULE_DESCRIPTION("Integrant ITD1000 driver");
diff --git a/kernel/drivers/media/dvb-frontends/ix2505v.c b/kernel/drivers/media/dvb-frontends/ix2505v.c
index 73f2710..3212e33 100644
--- a/kernel/drivers/media/dvb-frontends/ix2505v.c
+++ b/kernel/drivers/media/dvb-frontends/ix2505v.c
@@ -302,7 +302,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(ix2505v_attach);
+EXPORT_SYMBOL_GPL(ix2505v_attach);
 
 module_param_named(debug, ix2505v_debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
diff --git a/kernel/drivers/media/dvb-frontends/l64781.c b/kernel/drivers/media/dvb-frontends/l64781.c
index c5106a1..fe5af24 100644
--- a/kernel/drivers/media/dvb-frontends/l64781.c
+++ b/kernel/drivers/media/dvb-frontends/l64781.c
@@ -593,4 +593,4 @@
 MODULE_AUTHOR("Holger Waechtler, Marko Kohtala");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(l64781_attach);
+EXPORT_SYMBOL_GPL(l64781_attach);
diff --git a/kernel/drivers/media/dvb-frontends/lg2160.c b/kernel/drivers/media/dvb-frontends/lg2160.c
index f343066..fe700aa 100644
--- a/kernel/drivers/media/dvb-frontends/lg2160.c
+++ b/kernel/drivers/media/dvb-frontends/lg2160.c
@@ -1426,7 +1426,7 @@
 
 	return &state->frontend;
 }
-EXPORT_SYMBOL(lg2160_attach);
+EXPORT_SYMBOL_GPL(lg2160_attach);
 
 MODULE_DESCRIPTION("LG Electronics LG216x ATSC/MH Demodulator Driver");
 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
diff --git a/kernel/drivers/media/dvb-frontends/lgdt3305.c b/kernel/drivers/media/dvb-frontends/lgdt3305.c
index 62d7439..60a97f1 100644
--- a/kernel/drivers/media/dvb-frontends/lgdt3305.c
+++ b/kernel/drivers/media/dvb-frontends/lgdt3305.c
@@ -1148,7 +1148,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(lgdt3305_attach);
+EXPORT_SYMBOL_GPL(lgdt3305_attach);
 
 static const struct dvb_frontend_ops lgdt3304_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
diff --git a/kernel/drivers/media/dvb-frontends/lgdt3306a.c b/kernel/drivers/media/dvb-frontends/lgdt3306a.c
index 722576f..47fb221 100644
--- a/kernel/drivers/media/dvb-frontends/lgdt3306a.c
+++ b/kernel/drivers/media/dvb-frontends/lgdt3306a.c
@@ -1895,7 +1895,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(lgdt3306a_attach);
+EXPORT_SYMBOL_GPL(lgdt3306a_attach);
 
 #ifdef DBG_DUMP
 
diff --git a/kernel/drivers/media/dvb-frontends/lgdt330x.c b/kernel/drivers/media/dvb-frontends/lgdt330x.c
index da3a8c5..53b1443 100644
--- a/kernel/drivers/media/dvb-frontends/lgdt330x.c
+++ b/kernel/drivers/media/dvb-frontends/lgdt330x.c
@@ -928,7 +928,7 @@
 
 	return lgdt330x_get_dvb_frontend(client);
 }
-EXPORT_SYMBOL(lgdt330x_attach);
+EXPORT_SYMBOL_GPL(lgdt330x_attach);
 
 static const struct dvb_frontend_ops lgdt3302_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
diff --git a/kernel/drivers/media/dvb-frontends/lgs8gxx.c b/kernel/drivers/media/dvb-frontends/lgs8gxx.c
index 3001497..ffaf60e 100644
--- a/kernel/drivers/media/dvb-frontends/lgs8gxx.c
+++ b/kernel/drivers/media/dvb-frontends/lgs8gxx.c
@@ -1043,7 +1043,7 @@
 	return NULL;
 
 }
-EXPORT_SYMBOL(lgs8gxx_attach);
+EXPORT_SYMBOL_GPL(lgs8gxx_attach);
 
 MODULE_DESCRIPTION("Legend Silicon LGS8913/LGS8GXX DMB-TH demodulator driver");
 MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
diff --git a/kernel/drivers/media/dvb-frontends/lnbh25.c b/kernel/drivers/media/dvb-frontends/lnbh25.c
index 9ffe06c..41bec05 100644
--- a/kernel/drivers/media/dvb-frontends/lnbh25.c
+++ b/kernel/drivers/media/dvb-frontends/lnbh25.c
@@ -173,7 +173,7 @@
 		__func__, priv->i2c_address);
 	return fe;
 }
-EXPORT_SYMBOL(lnbh25_attach);
+EXPORT_SYMBOL_GPL(lnbh25_attach);
 
 MODULE_DESCRIPTION("ST LNBH25 driver");
 MODULE_AUTHOR("info@netup.ru");
diff --git a/kernel/drivers/media/dvb-frontends/lnbp21.c b/kernel/drivers/media/dvb-frontends/lnbp21.c
index e564974..32593b1 100644
--- a/kernel/drivers/media/dvb-frontends/lnbp21.c
+++ b/kernel/drivers/media/dvb-frontends/lnbp21.c
@@ -155,7 +155,7 @@
 	return lnbx2x_attach(fe, i2c, override_set, override_clear,
 							i2c_addr, LNBH24_TTX);
 }
-EXPORT_SYMBOL(lnbh24_attach);
+EXPORT_SYMBOL_GPL(lnbh24_attach);
 
 struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
 				struct i2c_adapter *i2c, u8 override_set,
@@ -164,7 +164,7 @@
 	return lnbx2x_attach(fe, i2c, override_set, override_clear,
 							0x08, LNBP21_ISEL);
 }
-EXPORT_SYMBOL(lnbp21_attach);
+EXPORT_SYMBOL_GPL(lnbp21_attach);
 
 MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24");
 MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin");
diff --git a/kernel/drivers/media/dvb-frontends/lnbp22.c b/kernel/drivers/media/dvb-frontends/lnbp22.c
index b8c7145..cb4ea5d 100644
--- a/kernel/drivers/media/dvb-frontends/lnbp22.c
+++ b/kernel/drivers/media/dvb-frontends/lnbp22.c
@@ -125,7 +125,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(lnbp22_attach);
+EXPORT_SYMBOL_GPL(lnbp22_attach);
 
 MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp22");
 MODULE_AUTHOR("Dominik Kuhlen");
diff --git a/kernel/drivers/media/dvb-frontends/m88ds3103.c b/kernel/drivers/media/dvb-frontends/m88ds3103.c
index c120cff..ff106d6 100644
--- a/kernel/drivers/media/dvb-frontends/m88ds3103.c
+++ b/kernel/drivers/media/dvb-frontends/m88ds3103.c
@@ -1699,7 +1699,7 @@
 	*tuner_i2c_adapter = pdata.get_i2c_adapter(client);
 	return pdata.get_dvb_frontend(client);
 }
-EXPORT_SYMBOL(m88ds3103_attach);
+EXPORT_SYMBOL_GPL(m88ds3103_attach);
 
 static const struct dvb_frontend_ops m88ds3103_ops = {
 	.delsys = {SYS_DVBS, SYS_DVBS2},
diff --git a/kernel/drivers/media/dvb-frontends/m88rs2000.c b/kernel/drivers/media/dvb-frontends/m88rs2000.c
index 39cbb3e..d1f235b 100644
--- a/kernel/drivers/media/dvb-frontends/m88rs2000.c
+++ b/kernel/drivers/media/dvb-frontends/m88rs2000.c
@@ -807,7 +807,7 @@
 
 	return NULL;
 }
-EXPORT_SYMBOL(m88rs2000_attach);
+EXPORT_SYMBOL_GPL(m88rs2000_attach);
 
 MODULE_DESCRIPTION("M88RS2000 DVB-S Demodulator driver");
 MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
diff --git a/kernel/drivers/media/dvb-frontends/mb86a16.c b/kernel/drivers/media/dvb-frontends/mb86a16.c
index 2505f1e..ed08e0c 100644
--- a/kernel/drivers/media/dvb-frontends/mb86a16.c
+++ b/kernel/drivers/media/dvb-frontends/mb86a16.c
@@ -1848,6 +1848,6 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(mb86a16_attach);
+EXPORT_SYMBOL_GPL(mb86a16_attach);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Manu Abraham");
diff --git a/kernel/drivers/media/dvb-frontends/mb86a20s.c b/kernel/drivers/media/dvb-frontends/mb86a20s.c
index a7faf0c..8a333af 100644
--- a/kernel/drivers/media/dvb-frontends/mb86a20s.c
+++ b/kernel/drivers/media/dvb-frontends/mb86a20s.c
@@ -2081,7 +2081,7 @@
 	dev_info(&i2c->dev, "Detected a Fujitsu mb86a20s frontend\n");
 	return &state->frontend;
 }
-EXPORT_SYMBOL(mb86a20s_attach);
+EXPORT_SYMBOL_GPL(mb86a20s_attach);
 
 static const struct dvb_frontend_ops mb86a20s_ops = {
 	.delsys = { SYS_ISDBT },
diff --git a/kernel/drivers/media/dvb-frontends/mn88443x.c b/kernel/drivers/media/dvb-frontends/mn88443x.c
index fff212c..05894de 100644
--- a/kernel/drivers/media/dvb-frontends/mn88443x.c
+++ b/kernel/drivers/media/dvb-frontends/mn88443x.c
@@ -800,7 +800,7 @@
 static struct i2c_driver mn88443x_driver = {
 	.driver = {
 		.name = "mn88443x",
-		.of_match_table = of_match_ptr(mn88443x_of_match),
+		.of_match_table = mn88443x_of_match,
 	},
 	.probe    = mn88443x_probe,
 	.remove   = mn88443x_remove,
diff --git a/kernel/drivers/media/dvb-frontends/mt312.c b/kernel/drivers/media/dvb-frontends/mt312.c
index d43a670..fb867dd 100644
--- a/kernel/drivers/media/dvb-frontends/mt312.c
+++ b/kernel/drivers/media/dvb-frontends/mt312.c
@@ -827,7 +827,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(mt312_attach);
+EXPORT_SYMBOL_GPL(mt312_attach);
 
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
diff --git a/kernel/drivers/media/dvb-frontends/mt352.c b/kernel/drivers/media/dvb-frontends/mt352.c
index 399d5c5..1b2889f 100644
--- a/kernel/drivers/media/dvb-frontends/mt352.c
+++ b/kernel/drivers/media/dvb-frontends/mt352.c
@@ -593,4 +593,4 @@
 MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(mt352_attach);
+EXPORT_SYMBOL_GPL(mt352_attach);
diff --git a/kernel/drivers/media/dvb-frontends/nxt200x.c b/kernel/drivers/media/dvb-frontends/nxt200x.c
index 35b83b1..1124baf 100644
--- a/kernel/drivers/media/dvb-frontends/nxt200x.c
+++ b/kernel/drivers/media/dvb-frontends/nxt200x.c
@@ -1232,5 +1232,5 @@
 MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(nxt200x_attach);
+EXPORT_SYMBOL_GPL(nxt200x_attach);
 
diff --git a/kernel/drivers/media/dvb-frontends/nxt6000.c b/kernel/drivers/media/dvb-frontends/nxt6000.c
index 136918f..e8d4940 100644
--- a/kernel/drivers/media/dvb-frontends/nxt6000.c
+++ b/kernel/drivers/media/dvb-frontends/nxt6000.c
@@ -621,4 +621,4 @@
 MODULE_AUTHOR("Florian Schirmer");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(nxt6000_attach);
+EXPORT_SYMBOL_GPL(nxt6000_attach);
diff --git a/kernel/drivers/media/dvb-frontends/or51132.c b/kernel/drivers/media/dvb-frontends/or51132.c
index 24de1b1..144a1f2 100644
--- a/kernel/drivers/media/dvb-frontends/or51132.c
+++ b/kernel/drivers/media/dvb-frontends/or51132.c
@@ -605,4 +605,4 @@
 MODULE_AUTHOR("Trent Piepho");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(or51132_attach);
+EXPORT_SYMBOL_GPL(or51132_attach);
diff --git a/kernel/drivers/media/dvb-frontends/or51211.c b/kernel/drivers/media/dvb-frontends/or51211.c
index ddcaea5..dc60482 100644
--- a/kernel/drivers/media/dvb-frontends/or51211.c
+++ b/kernel/drivers/media/dvb-frontends/or51211.c
@@ -551,5 +551,5 @@
 MODULE_AUTHOR("Kirk Lapray");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(or51211_attach);
+EXPORT_SYMBOL_GPL(or51211_attach);
 
diff --git a/kernel/drivers/media/dvb-frontends/s5h1409.c b/kernel/drivers/media/dvb-frontends/s5h1409.c
index 3089cc1..28b1dca 100644
--- a/kernel/drivers/media/dvb-frontends/s5h1409.c
+++ b/kernel/drivers/media/dvb-frontends/s5h1409.c
@@ -981,7 +981,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(s5h1409_attach);
+EXPORT_SYMBOL_GPL(s5h1409_attach);
 
 static const struct dvb_frontend_ops s5h1409_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
diff --git a/kernel/drivers/media/dvb-frontends/s5h1411.c b/kernel/drivers/media/dvb-frontends/s5h1411.c
index c1334d7..ae2b391 100644
--- a/kernel/drivers/media/dvb-frontends/s5h1411.c
+++ b/kernel/drivers/media/dvb-frontends/s5h1411.c
@@ -900,7 +900,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(s5h1411_attach);
+EXPORT_SYMBOL_GPL(s5h1411_attach);
 
 static const struct dvb_frontend_ops s5h1411_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
diff --git a/kernel/drivers/media/dvb-frontends/s5h1420.c b/kernel/drivers/media/dvb-frontends/s5h1420.c
index 6bdec28..d700de1 100644
--- a/kernel/drivers/media/dvb-frontends/s5h1420.c
+++ b/kernel/drivers/media/dvb-frontends/s5h1420.c
@@ -918,7 +918,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(s5h1420_attach);
+EXPORT_SYMBOL_GPL(s5h1420_attach);
 
 static const struct dvb_frontend_ops s5h1420_ops = {
 	.delsys = { SYS_DVBS },
diff --git a/kernel/drivers/media/dvb-frontends/s5h1432.c b/kernel/drivers/media/dvb-frontends/s5h1432.c
index 956e8ee..ff5d3bd 100644
--- a/kernel/drivers/media/dvb-frontends/s5h1432.c
+++ b/kernel/drivers/media/dvb-frontends/s5h1432.c
@@ -355,7 +355,7 @@
 
 	return &state->frontend;
 }
-EXPORT_SYMBOL(s5h1432_attach);
+EXPORT_SYMBOL_GPL(s5h1432_attach);
 
 static const struct dvb_frontend_ops s5h1432_ops = {
 	.delsys = { SYS_DVBT },
diff --git a/kernel/drivers/media/dvb-frontends/s921.c b/kernel/drivers/media/dvb-frontends/s921.c
index f118d8e..7e461ac 100644
--- a/kernel/drivers/media/dvb-frontends/s921.c
+++ b/kernel/drivers/media/dvb-frontends/s921.c
@@ -495,7 +495,7 @@
 
 	return &state->frontend;
 }
-EXPORT_SYMBOL(s921_attach);
+EXPORT_SYMBOL_GPL(s921_attach);
 
 static const struct dvb_frontend_ops s921_ops = {
 	.delsys = { SYS_ISDBT },
diff --git a/kernel/drivers/media/dvb-frontends/si21xx.c b/kernel/drivers/media/dvb-frontends/si21xx.c
index a116eff..6d84a55 100644
--- a/kernel/drivers/media/dvb-frontends/si21xx.c
+++ b/kernel/drivers/media/dvb-frontends/si21xx.c
@@ -938,7 +938,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(si21xx_attach);
+EXPORT_SYMBOL_GPL(si21xx_attach);
 
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
diff --git a/kernel/drivers/media/dvb-frontends/sp887x.c b/kernel/drivers/media/dvb-frontends/sp887x.c
index c89a91a..72f5862 100644
--- a/kernel/drivers/media/dvb-frontends/sp887x.c
+++ b/kernel/drivers/media/dvb-frontends/sp887x.c
@@ -626,4 +626,4 @@
 MODULE_DESCRIPTION("Spase sp887x DVB-T demodulator driver");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(sp887x_attach);
+EXPORT_SYMBOL_GPL(sp887x_attach);
diff --git a/kernel/drivers/media/dvb-frontends/stb0899_drv.c b/kernel/drivers/media/dvb-frontends/stb0899_drv.c
index 4ee6c1e..2f4d8fb 100644
--- a/kernel/drivers/media/dvb-frontends/stb0899_drv.c
+++ b/kernel/drivers/media/dvb-frontends/stb0899_drv.c
@@ -1638,7 +1638,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(stb0899_attach);
+EXPORT_SYMBOL_GPL(stb0899_attach);
 MODULE_PARM_DESC(verbose, "Set Verbosity level");
 MODULE_AUTHOR("Manu Abraham");
 MODULE_DESCRIPTION("STB0899 Multi-Std frontend");
diff --git a/kernel/drivers/media/dvb-frontends/stb6000.c b/kernel/drivers/media/dvb-frontends/stb6000.c
index 8c9800d..d74e346 100644
--- a/kernel/drivers/media/dvb-frontends/stb6000.c
+++ b/kernel/drivers/media/dvb-frontends/stb6000.c
@@ -232,7 +232,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(stb6000_attach);
+EXPORT_SYMBOL_GPL(stb6000_attach);
 
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
diff --git a/kernel/drivers/media/dvb-frontends/stb6100.c b/kernel/drivers/media/dvb-frontends/stb6100.c
index d541d66..9f92760 100644
--- a/kernel/drivers/media/dvb-frontends/stb6100.c
+++ b/kernel/drivers/media/dvb-frontends/stb6100.c
@@ -557,7 +557,7 @@
 	kfree(state);
 }
 
-EXPORT_SYMBOL(stb6100_attach);
+EXPORT_SYMBOL_GPL(stb6100_attach);
 MODULE_PARM_DESC(verbose, "Set Verbosity level");
 
 MODULE_AUTHOR("Manu Abraham");
diff --git a/kernel/drivers/media/dvb-frontends/stv0288.c b/kernel/drivers/media/dvb-frontends/stv0288.c
index 3d54a0e..a5581bd 100644
--- a/kernel/drivers/media/dvb-frontends/stv0288.c
+++ b/kernel/drivers/media/dvb-frontends/stv0288.c
@@ -440,9 +440,8 @@
 	struct stv0288_state *state = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 
-	char tm;
-	unsigned char tda[3];
-	u8 reg, time_out = 0;
+	u8 tda[3], reg, time_out = 0;
+	s8 tm;
 
 	dprintk("%s : FE_SET_FRONTEND\n", __func__);
 
@@ -591,7 +590,7 @@
 
 	return NULL;
 }
-EXPORT_SYMBOL(stv0288_attach);
+EXPORT_SYMBOL_GPL(stv0288_attach);
 
 module_param(debug_legacy_dish_switch, int, 0444);
 MODULE_PARM_DESC(debug_legacy_dish_switch,
diff --git a/kernel/drivers/media/dvb-frontends/stv0297.c b/kernel/drivers/media/dvb-frontends/stv0297.c
index 6d5962d..9d4dbd9 100644
--- a/kernel/drivers/media/dvb-frontends/stv0297.c
+++ b/kernel/drivers/media/dvb-frontends/stv0297.c
@@ -710,4 +710,4 @@
 MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(stv0297_attach);
+EXPORT_SYMBOL_GPL(stv0297_attach);
diff --git a/kernel/drivers/media/dvb-frontends/stv0299.c b/kernel/drivers/media/dvb-frontends/stv0299.c
index 421395e..0a1b57e 100644
--- a/kernel/drivers/media/dvb-frontends/stv0299.c
+++ b/kernel/drivers/media/dvb-frontends/stv0299.c
@@ -751,4 +751,4 @@
 MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, Andreas Oberritter, Andrew de Quincey, Kenneth Aafly");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(stv0299_attach);
+EXPORT_SYMBOL_GPL(stv0299_attach);
diff --git a/kernel/drivers/media/dvb-frontends/stv0367.c b/kernel/drivers/media/dvb-frontends/stv0367.c
index 6c2b05f..0bfca11 100644
--- a/kernel/drivers/media/dvb-frontends/stv0367.c
+++ b/kernel/drivers/media/dvb-frontends/stv0367.c
@@ -1750,7 +1750,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(stv0367ter_attach);
+EXPORT_SYMBOL_GPL(stv0367ter_attach);
 
 static int stv0367cab_gate_ctrl(struct dvb_frontend *fe, int enable)
 {
@@ -2923,7 +2923,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(stv0367cab_attach);
+EXPORT_SYMBOL_GPL(stv0367cab_attach);
 
 /*
  * Functions for operation on Digital Devices hardware
@@ -3344,7 +3344,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(stv0367ddb_attach);
+EXPORT_SYMBOL_GPL(stv0367ddb_attach);
 
 MODULE_PARM_DESC(debug, "Set debug");
 MODULE_PARM_DESC(i2c_debug, "Set i2c debug");
diff --git a/kernel/drivers/media/dvb-frontends/stv0900_core.c b/kernel/drivers/media/dvb-frontends/stv0900_core.c
index 212312d..e7b9b9b 100644
--- a/kernel/drivers/media/dvb-frontends/stv0900_core.c
+++ b/kernel/drivers/media/dvb-frontends/stv0900_core.c
@@ -1957,7 +1957,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(stv0900_attach);
+EXPORT_SYMBOL_GPL(stv0900_attach);
 
 MODULE_PARM_DESC(debug, "Set debug");
 
diff --git a/kernel/drivers/media/dvb-frontends/stv090x.c b/kernel/drivers/media/dvb-frontends/stv090x.c
index 90d2413..799dbef 100644
--- a/kernel/drivers/media/dvb-frontends/stv090x.c
+++ b/kernel/drivers/media/dvb-frontends/stv090x.c
@@ -5073,7 +5073,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(stv090x_attach);
+EXPORT_SYMBOL_GPL(stv090x_attach);
 
 static const struct i2c_device_id stv090x_id_table[] = {
 	{"stv090x", 0},
diff --git a/kernel/drivers/media/dvb-frontends/stv6110.c b/kernel/drivers/media/dvb-frontends/stv6110.c
index 963f6a8..1cf9c09 100644
--- a/kernel/drivers/media/dvb-frontends/stv6110.c
+++ b/kernel/drivers/media/dvb-frontends/stv6110.c
@@ -427,7 +427,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(stv6110_attach);
+EXPORT_SYMBOL_GPL(stv6110_attach);
 
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
diff --git a/kernel/drivers/media/dvb-frontends/stv6110x.c b/kernel/drivers/media/dvb-frontends/stv6110x.c
index 5012d02..b08c753 100644
--- a/kernel/drivers/media/dvb-frontends/stv6110x.c
+++ b/kernel/drivers/media/dvb-frontends/stv6110x.c
@@ -469,7 +469,7 @@
 	dev_info(&stv6110x->i2c->dev, "Attaching STV6110x\n");
 	return stv6110x->devctl;
 }
-EXPORT_SYMBOL(stv6110x_attach);
+EXPORT_SYMBOL_GPL(stv6110x_attach);
 
 static const struct i2c_device_id stv6110x_id_table[] = {
 	{"stv6110x", 0},
diff --git a/kernel/drivers/media/dvb-frontends/tda10021.c b/kernel/drivers/media/dvb-frontends/tda10021.c
index faa6e54..462e12a 100644
--- a/kernel/drivers/media/dvb-frontends/tda10021.c
+++ b/kernel/drivers/media/dvb-frontends/tda10021.c
@@ -523,4 +523,4 @@
 MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Markus Schulz");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(tda10021_attach);
+EXPORT_SYMBOL_GPL(tda10021_attach);
diff --git a/kernel/drivers/media/dvb-frontends/tda10023.c b/kernel/drivers/media/dvb-frontends/tda10023.c
index 8f32edf..4c2541e 100644
--- a/kernel/drivers/media/dvb-frontends/tda10023.c
+++ b/kernel/drivers/media/dvb-frontends/tda10023.c
@@ -594,4 +594,4 @@
 MODULE_AUTHOR("Georg Acher, Hartmut Birr");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(tda10023_attach);
+EXPORT_SYMBOL_GPL(tda10023_attach);
diff --git a/kernel/drivers/media/dvb-frontends/tda10048.c b/kernel/drivers/media/dvb-frontends/tda10048.c
index d1d206e..f1d5e77 100644
--- a/kernel/drivers/media/dvb-frontends/tda10048.c
+++ b/kernel/drivers/media/dvb-frontends/tda10048.c
@@ -1138,7 +1138,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(tda10048_attach);
+EXPORT_SYMBOL_GPL(tda10048_attach);
 
 static const struct dvb_frontend_ops tda10048_ops = {
 	.delsys = { SYS_DVBT },
diff --git a/kernel/drivers/media/dvb-frontends/tda1004x.c b/kernel/drivers/media/dvb-frontends/tda1004x.c
index 83a798c..6f306db 100644
--- a/kernel/drivers/media/dvb-frontends/tda1004x.c
+++ b/kernel/drivers/media/dvb-frontends/tda1004x.c
@@ -1378,5 +1378,5 @@
 MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(tda10045_attach);
-EXPORT_SYMBOL(tda10046_attach);
+EXPORT_SYMBOL_GPL(tda10045_attach);
+EXPORT_SYMBOL_GPL(tda10046_attach);
diff --git a/kernel/drivers/media/dvb-frontends/tda10086.c b/kernel/drivers/media/dvb-frontends/tda10086.c
index cdcf976..b449514 100644
--- a/kernel/drivers/media/dvb-frontends/tda10086.c
+++ b/kernel/drivers/media/dvb-frontends/tda10086.c
@@ -764,4 +764,4 @@
 MODULE_AUTHOR("Andrew de Quincey");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(tda10086_attach);
+EXPORT_SYMBOL_GPL(tda10086_attach);
diff --git a/kernel/drivers/media/dvb-frontends/tda665x.c b/kernel/drivers/media/dvb-frontends/tda665x.c
index 13e8969..346be50 100644
--- a/kernel/drivers/media/dvb-frontends/tda665x.c
+++ b/kernel/drivers/media/dvb-frontends/tda665x.c
@@ -227,7 +227,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(tda665x_attach);
+EXPORT_SYMBOL_GPL(tda665x_attach);
 
 MODULE_DESCRIPTION("TDA665x driver");
 MODULE_AUTHOR("Manu Abraham");
diff --git a/kernel/drivers/media/dvb-frontends/tda8083.c b/kernel/drivers/media/dvb-frontends/tda8083.c
index 5be11fd..9fc16e9 100644
--- a/kernel/drivers/media/dvb-frontends/tda8083.c
+++ b/kernel/drivers/media/dvb-frontends/tda8083.c
@@ -481,4 +481,4 @@
 MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(tda8083_attach);
+EXPORT_SYMBOL_GPL(tda8083_attach);
diff --git a/kernel/drivers/media/dvb-frontends/tda8261.c b/kernel/drivers/media/dvb-frontends/tda8261.c
index 0d576d4..8b06f92 100644
--- a/kernel/drivers/media/dvb-frontends/tda8261.c
+++ b/kernel/drivers/media/dvb-frontends/tda8261.c
@@ -188,7 +188,7 @@
 	return NULL;
 }
 
-EXPORT_SYMBOL(tda8261_attach);
+EXPORT_SYMBOL_GPL(tda8261_attach);
 
 MODULE_AUTHOR("Manu Abraham");
 MODULE_DESCRIPTION("TDA8261 8PSK/QPSK Tuner");
diff --git a/kernel/drivers/media/dvb-frontends/tda826x.c b/kernel/drivers/media/dvb-frontends/tda826x.c
index f9703a1..eafcf5f 100644
--- a/kernel/drivers/media/dvb-frontends/tda826x.c
+++ b/kernel/drivers/media/dvb-frontends/tda826x.c
@@ -164,7 +164,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(tda826x_attach);
+EXPORT_SYMBOL_GPL(tda826x_attach);
 
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
diff --git a/kernel/drivers/media/dvb-frontends/ts2020.c b/kernel/drivers/media/dvb-frontends/ts2020.c
index 234607b..1f1004c 100644
--- a/kernel/drivers/media/dvb-frontends/ts2020.c
+++ b/kernel/drivers/media/dvb-frontends/ts2020.c
@@ -525,7 +525,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(ts2020_attach);
+EXPORT_SYMBOL_GPL(ts2020_attach);
 
 /*
  * We implement own regmap locking due to legacy DVB attach which uses frontend
diff --git a/kernel/drivers/media/dvb-frontends/tua6100.c b/kernel/drivers/media/dvb-frontends/tua6100.c
index 2483f61..41dd9b6 100644
--- a/kernel/drivers/media/dvb-frontends/tua6100.c
+++ b/kernel/drivers/media/dvb-frontends/tua6100.c
@@ -186,7 +186,7 @@
 	fe->tuner_priv = priv;
 	return fe;
 }
-EXPORT_SYMBOL(tua6100_attach);
+EXPORT_SYMBOL_GPL(tua6100_attach);
 
 MODULE_DESCRIPTION("DVB tua6100 driver");
 MODULE_AUTHOR("Andrew de Quincey");
diff --git a/kernel/drivers/media/dvb-frontends/ves1820.c b/kernel/drivers/media/dvb-frontends/ves1820.c
index 9df14d0..ee5620e 100644
--- a/kernel/drivers/media/dvb-frontends/ves1820.c
+++ b/kernel/drivers/media/dvb-frontends/ves1820.c
@@ -434,4 +434,4 @@
 MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(ves1820_attach);
+EXPORT_SYMBOL_GPL(ves1820_attach);
diff --git a/kernel/drivers/media/dvb-frontends/ves1x93.c b/kernel/drivers/media/dvb-frontends/ves1x93.c
index b747272..c60e21d 100644
--- a/kernel/drivers/media/dvb-frontends/ves1x93.c
+++ b/kernel/drivers/media/dvb-frontends/ves1x93.c
@@ -540,4 +540,4 @@
 MODULE_AUTHOR("Ralph Metzler");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(ves1x93_attach);
+EXPORT_SYMBOL_GPL(ves1x93_attach);
diff --git a/kernel/drivers/media/dvb-frontends/zl10036.c b/kernel/drivers/media/dvb-frontends/zl10036.c
index d392c7c..7ba575e 100644
--- a/kernel/drivers/media/dvb-frontends/zl10036.c
+++ b/kernel/drivers/media/dvb-frontends/zl10036.c
@@ -496,7 +496,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(zl10036_attach);
+EXPORT_SYMBOL_GPL(zl10036_attach);
 
 module_param_named(debug, zl10036_debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
diff --git a/kernel/drivers/media/dvb-frontends/zl10039.c b/kernel/drivers/media/dvb-frontends/zl10039.c
index 1335bf7..a3e4d21 100644
--- a/kernel/drivers/media/dvb-frontends/zl10039.c
+++ b/kernel/drivers/media/dvb-frontends/zl10039.c
@@ -295,7 +295,7 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(zl10039_attach);
+EXPORT_SYMBOL_GPL(zl10039_attach);
 
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
diff --git a/kernel/drivers/media/dvb-frontends/zl10353.c b/kernel/drivers/media/dvb-frontends/zl10353.c
index 2a2cf20..8849d05 100644
--- a/kernel/drivers/media/dvb-frontends/zl10353.c
+++ b/kernel/drivers/media/dvb-frontends/zl10353.c
@@ -665,4 +665,4 @@
 MODULE_AUTHOR("Chris Pascoe");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(zl10353_attach);
+EXPORT_SYMBOL_GPL(zl10353_attach);
diff --git a/kernel/drivers/media/i2c/Kconfig b/kernel/drivers/media/i2c/Kconfig
index 669daed..2202262 100644
--- a/kernel/drivers/media/i2c/Kconfig
+++ b/kernel/drivers/media/i2c/Kconfig
@@ -5,6 +5,12 @@
 
 if VIDEO_V4L2
 
+config VIDEO_CAM_SLEEP_WAKEUP
+	tristate "Enable sensor sleep wake up function"
+	depends on ARCH_ROCKCHIP
+	help
+	  Support for sensor sleep and wake up.
+
 comment "IR I2C driver auto-selected by 'Autoselect ancillary drivers'"
 	depends on MEDIA_SUBDRV_AUTOSELECT && I2C && RC_CORE
 
@@ -663,6 +669,18 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called max96722.
 
+config VIDEO_MAX96756
+	tristate "Maxim MAX96756 GMSL1/2 CSI display deserializer support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on MEDIA_CAMERA_SUPPORT
+	select V4L2_FWNODE
+	help
+	  This driver supports the Maxim MAX96756 GMSL1/2 CSI display deserializer.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called max96756.
+
+source "drivers/media/i2c/maxim2c/Kconfig"
 source "drivers/media/i2c/maxim4c/Kconfig"
 
 comment "Video and audio decoders"
@@ -946,6 +964,18 @@
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called ar0822.
+
+config VIDEO_AR2020
+	tristate "Onsemi AR2020 sensor support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on MEDIA_CAMERA_SUPPORT
+	select V4L2_FWNODE
+	help
+	  This is a Video4Linux2 sensor driver for the Onsemi
+	  AR2020 camera.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ar2020.
 
 config VIDEO_GC02M2
 	tristate "GalaxyCore GC02M2 sensor support"
@@ -1384,6 +1414,24 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called jx_k17.
 
+config VIDEO_OG01A10
+	tristate "OmniVision OG01A10 sensor support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on MEDIA_CAMERA_SUPPORT
+	select V4L2_FWNODE
+	help
+	  This is a Video4Linux2 sensor driver for the OmniVision
+	  OG01A10 camera.
+
+config VIDEO_OG02B10
+	tristate "OmniVision OG02B10 sensor support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on MEDIA_CAMERA_SUPPORT
+	select V4L2_FWNODE
+	help
+	  This is a Video4Linux2 sensor driver for the OmniVision
+	  OG02B10 camera.
+
 config VIDEO_OS02G10
 	tristate "OmniVision OS02G10 sensor support"
 	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
@@ -1420,6 +1468,15 @@
 	  This is a Video4Linux2 sensor driver for the OmniVision
 	  OS04A10 camera.
 
+config VIDEO_OS04D10
+	tristate "OmniVision OS04D10 sensor support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on MEDIA_CAMERA_SUPPORT
+	select V4L2_FWNODE
+	help
+	  This is a Video4Linux2 sensor driver for the OmniVision
+	  OS04D10 camera.
+
 config VIDEO_OS05A20
 	tristate "OmniVision OS05A20 sensor support"
 	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
@@ -1455,6 +1512,15 @@
 	help
 	  This is a Video4Linux2 sensor driver for the OmniVision
 	  OV02K10 camera.
+
+config VIDEO_OV16885
+	tristate "OmniVision OV16885 sensor support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on MEDIA_CAMERA_SUPPORT
+	select V4L2_FWNODE
+	help
+	  This is a Video4Linux2 sensor driver for the OmniVision
+	  OV16885 camera.
 
 config VIDEO_OV16A10
 	tristate "OmniVision OV16A10 sensor support"
@@ -1827,6 +1893,26 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called vs6624.
 
+config VIDEO_MIS2031
+	tristate "ImageDesign mis2031 sensor support"
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
+	select V4L2_FWNODE
+	help
+	  This is a Video4Linux2 sensor driver for the ImageDesign
+	  MIS2031 camera.
+
+config VIDEO_MIS4001
+	tristate "ImageDesign mis4001 sensor support"
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
+	select V4L2_FWNODE
+	help
+	  This is a Video4Linux2 sensor driver for the ImageDesign
+	  MIS4001 camera.
+
 config VIDEO_MT9M001
 	tristate "mt9m001 support"
 	depends on I2C && VIDEO_V4L2
@@ -2035,6 +2121,16 @@
 	  This is a Video4Linux2 sensor driver for the SmartSens
 	  SC2336 camera.
 
+config VIDEO_SC2355
+	tristate "SmartSens SC2355 sensor support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on MEDIA_CAMERA_SUPPORT
+	select V4L2_FWNODE
+	help
+	  Support for the SmartSens SC2355 sensor.
+	  To compile this driver as a module, choose M here: the
+	  module will be called sc2355.
+
 config VIDEO_SC301IOT
     tristate "SmartSens SC301IOT sensor support"
 	depends on I2C && VIDEO_V4L2
@@ -2114,6 +2210,26 @@
 	help
 	  This is a Video4Linux2 sensor driver for the SmartSens
 	  SC4336 camera.
+
+config VIDEO_SC4336P
+	tristate "SmartSens SC4336P sensor support"
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
+	select V4L2_FWNODE
+	help
+	  This is a Video4Linux2 sensor driver for the SmartSens
+	  SC4336P camera.
+
+config VIDEO_SC450AI
+	tristate "SmartSens SC450AI sensor support"
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
+	select V4L2_FWNODE
+	help
+	  This is a Video4Linux2 sensor driver for the SmartSens
+	  SC450ai camera.
 
 config VIDEO_SC500AI
 	tristate "SmartSens SC500AI sensor support"
@@ -2372,6 +2488,18 @@
 	  capability. This is designed for linear control of
 	  voice coil motors, controlled via I2C serial interface.
 
+config VIDEO_DW9800V
+	tristate "DW9800V lens voice coil support"
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
+	select V4L2_FWNODE
+	help
+	  This is a driver for the DW9800V camera lens voice coil.
+	  DW9800W is a 10 bit DAC with ±130mA output current sink
+	  capability. This is designed for linear control of bi-direction
+	  voice coil motors, controlled via I2C serial interface.
+
 config VIDEO_DW9800W
 	tristate "DW9800W lens voice coil support"
 	depends on I2C && VIDEO_V4L2
diff --git a/kernel/drivers/media/i2c/Makefile b/kernel/drivers/media/i2c/Makefile
index 11c344f..12a0f59 100644
--- a/kernel/drivers/media/i2c/Makefile
+++ b/kernel/drivers/media/i2c/Makefile
@@ -10,6 +10,7 @@
 obj-$(CONFIG_VIDEO_NVP6158)	+= nvp6158_drv/
 obj-$(CONFIG_VIDEO_NVP6188)	+= nvp6188.o
 obj-$(CONFIG_VIDEO_NVP6324)	+= jaguar1_drv/
+obj-$(CONFIG_VIDEO_DES_MAXIM2C)	+= maxim2c/
 obj-$(CONFIG_VIDEO_DES_MAXIM4C)	+= maxim4c/
 
 obj-$(CONFIG_VIDEO_APTINA_PLL) += aptina-pll.o
@@ -33,6 +34,7 @@
 obj-$(CONFIG_VIDEO_DW9714)  += dw9714.o
 obj-$(CONFIG_VIDEO_DW9763) += dw9763.o
 obj-$(CONFIG_VIDEO_DW9768)  += dw9768.o
+obj-$(CONFIG_VIDEO_DW9800V) += dw9800v.o
 obj-$(CONFIG_VIDEO_DW9800W) += dw9800w.o
 obj-$(CONFIG_VIDEO_DW9807_VCM)  += dw9807-vcm.o
 obj-$(CONFIG_VIDEO_FP5510)  += fp5510.o
@@ -75,14 +77,18 @@
 obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o
 obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
 obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
+obj-$(CONFIG_VIDEO_OG01A10) += og01a10.o
+obj-$(CONFIG_VIDEO_OG02B10) += og02b10.o
 obj-$(CONFIG_VIDEO_OS02G10) += os02g10.o
 obj-$(CONFIG_VIDEO_OS02K10) += os02k10.o
 obj-$(CONFIG_VIDEO_OS03B10) += os03b10.o
 obj-$(CONFIG_VIDEO_OS04A10) += os04a10.o
+obj-$(CONFIG_VIDEO_OS04D10) += os04d10.o
 obj-$(CONFIG_VIDEO_OS05A20) += os05a20.o
 obj-$(CONFIG_VIDEO_OS08A20) += os08a20.o
 obj-$(CONFIG_VIDEO_OV02B10) += ov02b10.o
 obj-$(CONFIG_VIDEO_OV02K10) += ov02k10.o
+obj-$(CONFIG_VIDEO_OV16885) += ov16885.o
 obj-$(CONFIG_VIDEO_OV16A10) += ov16a10.o
 obj-$(CONFIG_VIDEO_OV16A1Q) += ov16a1q.o
 obj-$(CONFIG_VIDEO_OV2640) += ov2640.o
@@ -115,6 +121,8 @@
 obj-$(CONFIG_VIDEO_OV13850) += ov13850.o
 obj-$(CONFIG_VIDEO_OV13855) += ov13855.o
 obj-$(CONFIG_VIDEO_OV13858) += ov13858.o
+obj-$(CONFIG_VIDEO_MIS2031) += mis2031.o
+obj-$(CONFIG_VIDEO_MIS4001) += mis4001.o
 obj-$(CONFIG_VIDEO_MT9M001) += mt9m001.o
 obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
 obj-$(CONFIG_VIDEO_MT9M111) += mt9m111.o
@@ -136,6 +144,7 @@
 obj-$(CONFIG_VIDEO_SC230AI) += sc230ai.o
 obj-$(CONFIG_VIDEO_SC2310) += sc2310.o
 obj-$(CONFIG_VIDEO_SC2336) += sc2336.o
+obj-$(CONFIG_VIDEO_SC2355) += sc2355.o
 obj-$(CONFIG_VIDEO_SC301IOT) += sc301iot.o
 obj-$(CONFIG_VIDEO_SC3336) += sc3336.o
 obj-$(CONFIG_VIDEO_SC3338) += sc3338.o
@@ -144,6 +153,8 @@
 obj-$(CONFIG_VIDEO_SC4238) += sc4238.o
 obj-$(CONFIG_VIDEO_SC430CS) += sc430cs.o
 obj-$(CONFIG_VIDEO_SC4336) += sc4336.o
+obj-$(CONFIG_VIDEO_SC4336P) += sc4336p.o
+obj-$(CONFIG_VIDEO_SC450AI) += sc450ai.o
 obj-$(CONFIG_VIDEO_SC500AI) += sc500ai.o
 obj-$(CONFIG_VIDEO_SC501AI) += sc501ai.o
 obj-$(CONFIG_VIDEO_SC530AI) += sc530ai.o
@@ -185,6 +196,7 @@
 obj-$(CONFIG_VIDEO_RK628)	+= rk628/
 obj-$(CONFIG_VIDEO_AR0230)	+= ar0230.o
 obj-$(CONFIG_VIDEO_AR0822)	+= ar0822.o
+obj-$(CONFIG_VIDEO_AR2020)	+= ar2020.o
 obj-$(CONFIG_VIDEO_GC02M2)	+= gc02m2.o
 obj-$(CONFIG_VIDEO_GC08A3)	+= gc08a3.o
 obj-$(CONFIG_VIDEO_GC1084)	+= gc1084.o
@@ -228,6 +240,7 @@
 obj-$(CONFIG_VIDEO_MAX96712)	+= max96712.o
 obj-$(CONFIG_VIDEO_MAX96714)	+= max96714.o
 obj-$(CONFIG_VIDEO_MAX96722)	+= max96722.o
+obj-$(CONFIG_VIDEO_MAX96756)	+= max96756.o
 rdacm20-camera_module-objs	:= rdacm20.o max9271.o
 obj-$(CONFIG_VIDEO_RDACM20)	+= rdacm20-camera_module.o
 obj-$(CONFIG_VIDEO_ST_MIPID02) += st-mipid02.o
@@ -236,3 +249,5 @@
 
 obj-$(CONFIG_VIDEO_OTP_EEPROM)	+= otp_eeprom.o
 obj-$(CONFIG_VIDEO_PREISP_DUMMY_SENSOR) += preisp-dummy.o
+obj-$(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)	+= cam-tb-setup.o
+obj-$(CONFIG_VIDEO_CAM_SLEEP_WAKEUP)	+= cam-sleep-wakeup.o
diff --git a/kernel/drivers/media/i2c/ad5820.c b/kernel/drivers/media/i2c/ad5820.c
index 19c74db..d2c69ee 100644
--- a/kernel/drivers/media/i2c/ad5820.c
+++ b/kernel/drivers/media/i2c/ad5820.c
@@ -329,18 +329,18 @@
 
 	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;
 }
 
@@ -359,7 +359,6 @@
 static const struct i2c_device_id ad5820_id_table[] = {
 	{ "ad5820", 0 },
 	{ "ad5821", 0 },
-	{ "ad5823", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, ad5820_id_table);
@@ -367,7 +366,6 @@
 static const struct of_device_id ad5820_of_table[] = {
 	{ .compatible = "adi,ad5820" },
 	{ .compatible = "adi,ad5821" },
-	{ .compatible = "adi,ad5823" },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, ad5820_of_table);
diff --git a/kernel/drivers/media/i2c/ar2020.c b/kernel/drivers/media/i2c/ar2020.c
new file mode 100644
index 0000000..01bed93
--- /dev/null
+++ b/kernel/drivers/media/i2c/ar2020.c
@@ -0,0 +1,5413 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ar2020 driver
+ *
+ * Copyright (C) 2020 Fuzhou Rockchip Electronics Co., Ltd.
+ *
+ * V0.0X01.0X00 first version.
+ * V0.0X01.0X01 support conversion gain switch.
+ * V0.0X01.0X02 add debug interface for conversion gain switch.
+ * V0.0X01.0X03 support enum sensor fmt
+ * V0.0X01.0X04 add quick stream on/off
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/rk-camera-module.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/rk-preisp.h>
+#include "../platform/rockchip/isp/rkisp_tb_helper.h"
+
+#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x04)
+#ifndef V4L2_CID_DIGITAL_GAIN
+#define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
+#endif
+#define USE_8LANE			1
+#define LANE_NUM_8			8
+#define AR2020_BPP			10
+#define AR2020_LANES			4
+
+#define MIPI_FREQ_600M			600000000
+#define MIPI_FREQ_860M			860000000
+
+#define PIXEL_RATE_WITH_600M		(MIPI_FREQ_600M / AR2020_BPP * 2 * AR2020_LANES)
+#define PIXEL_RATE_MAX			(MIPI_FREQ_860M / AR2020_BPP * 2 * AR2020_LANES)
+
+#define OF_CAMERA_HDR_MODE		"rockchip,camera-hdr-mode"
+
+#define AR2020_XVCLK_FREQ_27M		27000000
+#define AR2020_XVCLK_FREQ_20M		20000000
+
+#define CHIP_ID				0x0653
+#define AR2020_REG_CHIP_ID		0x0016
+
+#define AR2020_REG_CTRL_MODE		0x0100
+#define AR2020_MODE_SW_STANDBY		0x0000
+#define AR2020_MODE_STREAMING		0x0001
+
+#define	AR2020_EXPOSURE_MIN		2
+#define	AR2020_EXPOSURE_STEP		1
+#define AR2020_VTS_MAX			0xffff
+
+#define AR2020_REG_EXP			0x0202
+#define AR2020_REG_EXP_T2		0x0224
+
+//needed be updated for different settings, FLL(REG 0x0342)-t1_to_t2_dist-1
+#define AR2020_CIT_MAX_T1		7498
+//needed be updated for different settings, t1_to_t2_dist(R0x3042[14:0])-4
+#define AR2020_CIT_MAX_T2		237
+
+#define AR2020_REG_GAIN			0x3062
+#define AR2020_REG_GAIN2		0x3062
+
+#define AR2020_GAIN_MIN			0
+#define AR2020_GAIN_MAX			127
+#define AR2020_GAIN_STEP		1
+#define AR2020_GAIN_DEFAULT		0x20
+#define AR2020_REG_VTS			0x0340
+
+/* make sure exposure and gain take effect from N+2 frame; open.k */
+#define AR2020_GROUP_UPDATE_ADDRESS	0x0104
+#define AR2020_GROUP_UPDATE_START_DATA	0x0001
+#define AR2020_GROUP_UPDATE_END_DATA	0x0000
+
+#define AR2020_SOFTWARE_RESET_REG	0x0103
+
+/* Flag address for I2C array write,indicate this is the last row of I2C register table; open.k */
+#define REG_NULL			0xFFFF
+#define REG_DELAY			0xFFFE
+
+#define AR2020_REG_VALUE_08BIT		1
+#define AR2020_REG_VALUE_16BIT		2
+#define AR2020_REG_VALUE_24BIT		3
+
+#define OF_CAMERA_PINCTRL_STATE_DEFAULT	"rockchip,camera_default"
+#define OF_CAMERA_PINCTRL_STATE_SLEEP	"rockchip,camera_sleep"
+
+#define AR2020_NAME			"ar2020"
+
+enum regmode {
+	REG_MODE_DEFAULT = -1,
+	INITIAL_STREAMING,
+	SEPERATE_STREAMING,
+	REG_MODE_MAX,
+};
+
+/*  sensor power on config, need check power, MCLK, GPIO etc,,,
+ * need go to .dts file to change the config;
+ * open.k
+ */
+static const char * const ar2020_supply_names[] = {
+	"avdd",		/* Analog power */
+	"dovdd",	/* Digital I/O power */
+	"dvdd",		/* Digital core power */
+};
+
+
+#define AR2020_NUM_SUPPLIES ARRAY_SIZE(ar2020_supply_names)
+
+#define AR2020_FLIP_REG			0x0101
+#define MIRROR_BIT_MASK			BIT(0)
+#define FLIP_BIT_MASK			BIT(1)
+
+struct regval {
+	u16 addr;
+	u16 val;
+	u8  bits;
+};
+
+/* Config resolution ,LLPCLK, FLL,
+ * exposure time,fps, MIPI channel config, HDR mode ,
+ * open.k
+ */
+struct ar2020_mode {
+	u32 bus_fmt;
+	u32 width;
+	u32 height;
+	struct v4l2_fract max_fps;
+	u32 hts_def;
+	u32 vts_def;
+	u32 exp_def;
+	const struct regval *reg_list;
+	u32 hdr_mode;
+	u32 mipi_freq;
+	u32 mipi_rate;
+	u32 mclk;
+	u32 reg_mode;
+	u32 vc[PAD_MAX];
+};
+
+struct ar2020 {
+	struct i2c_client	*client;
+	struct clk		*xvclk;
+	struct gpio_desc	*reset_gpio;
+	struct gpio_desc	*pwdn_gpio;
+	struct regulator_bulk_data supplies[AR2020_NUM_SUPPLIES];
+
+	struct pinctrl		*pinctrl;
+	struct pinctrl_state	*pins_default;
+	struct pinctrl_state	*pins_sleep;
+
+	struct v4l2_subdev	subdev;
+	struct media_pad	pad;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl	*exposure;
+	struct v4l2_ctrl	*anal_gain;
+	struct v4l2_ctrl	*digi_gain;
+	struct v4l2_ctrl	*hblank;
+	struct v4l2_ctrl	*vblank;
+	struct v4l2_ctrl	*test_pattern;
+	struct v4l2_ctrl	*pixel_rate;
+	struct v4l2_ctrl	*link_freq;
+	struct v4l2_ctrl	*h_flip;
+	struct v4l2_ctrl	*v_flip;
+	struct mutex		mutex;
+	bool			streaming;
+	bool			power_on;
+	const struct ar2020_mode *cur_mode;
+	u32			cfg_num;
+	u32			module_index;
+	const char		*module_facing;
+	const char		*module_name;
+	struct rkmodule_multi_dev_info multi_dev_info;
+	const char		*len_name;
+	bool			has_init_exp;
+	struct preisp_hdrae_exp_s init_hdrae_exp;
+	bool			long_hcg;
+	bool			middle_hcg;
+	bool			short_hcg;
+	bool			is_thunderboot;
+	bool			is_thunderboot_ng;
+	bool			is_first_streamoff;
+	u8			flip;
+	u32			cur_mclk;
+	u32			csi_lanes_in_use;
+};
+#define to_ar2020(sd) container_of(sd, struct ar2020, subdev)
+
+static const struct regval ar2020_edr12bit_5120x3840_30fps_8lane_regs[] = {
+	{REG_DELAY, 2000, AR2020_REG_VALUE_16BIT},
+	{0x44D6, 0xF206, AR2020_REG_VALUE_16BIT},//DAC_LD_32_33
+	{0x0100, 0x00, AR2020_REG_VALUE_08BIT},//MODE_SELECT
+	{0x0304, 0x0006, AR2020_REG_VALUE_16BIT},//VT_PRE_PLL_CLK_DIV
+	{0x0306, 0x00E5, AR2020_REG_VALUE_16BIT},//VT_PLL_MULTIPLIER
+	{0x0300, 0x0006, AR2020_REG_VALUE_16BIT},//VT_PIX_CLK_DIV
+	{0x0302, 0x0001, AR2020_REG_VALUE_16BIT},//VT_SYS_CLK_DIV
+	{0x030C, 0x0007, AR2020_REG_VALUE_16BIT},//OP_PRE_PLL_CLK_DIV
+	{0x030E, 0x01BD, AR2020_REG_VALUE_16BIT},//OP_PLL_MULTIPLIER
+	{0x0308, 0x0006, AR2020_REG_VALUE_16BIT},//OP_PIX_CLK_DIV
+	{0x030A, 0x0002, AR2020_REG_VALUE_16BIT},//OP_SYS_CLK_DIV
+	{0x0344, 0x0008, AR2020_REG_VALUE_16BIT},//X_ADDR_START
+	{0x0348, 0x1407, AR2020_REG_VALUE_16BIT},//X_ADDR_END
+	{0x0346, 0x0008, AR2020_REG_VALUE_16BIT},//Y_ADDR_START
+	{0x034A, 0x0F07, AR2020_REG_VALUE_16BIT},//Y_ADDR_END
+	{0x034C, 0x1400, AR2020_REG_VALUE_16BIT},//X_OUTPUT_SIZE
+	{0x034E, 0x0F00, AR2020_REG_VALUE_16BIT},//Y_OUTPUT_SIZE
+	{0x0380, 0x0001, AR2020_REG_VALUE_16BIT},//X_EVEN_INC
+	{0x0382, 0x0001, AR2020_REG_VALUE_16BIT},//X_ODD_INC
+	{0x0384, 0x0001, AR2020_REG_VALUE_16BIT},//Y_EVEN_INC
+	{0x0386, 0x0001, AR2020_REG_VALUE_16BIT},//Y_ODD_INC
+	{0x0900, 0x00, AR2020_REG_VALUE_08BIT},//BINNING_MODE
+	{0x0901, 0x11, AR2020_REG_VALUE_08BIT},//BINNING_TYPE
+	{0x0342, 0x2E30, AR2020_REG_VALUE_16BIT},//LINE_LENGTH_PCK
+	{0x0340, 0x0F1E, AR2020_REG_VALUE_16BIT},//FRAME_LENGTH_LINES
+	{0x0202, 0x0D9E, AR2020_REG_VALUE_16BIT},//COARSE_INTEGRATION_TIME
+	{0x0112, 0x0C0C, AR2020_REG_VALUE_16BIT},//CSI_DATA_FORMAT
+	{0x0114, 0x07, AR2020_REG_VALUE_08BIT},//CSI_LANE_MODE
+	{0x0800, 0x0D, AR2020_REG_VALUE_08BIT},//TCLK_POST
+	{0x0801, 0x08, AR2020_REG_VALUE_08BIT},//THS_PREPARE
+	{0x0802, 0x0E, AR2020_REG_VALUE_08BIT},//THS_ZERO_MIN
+	{0x0803, 0x0A, AR2020_REG_VALUE_08BIT},//THS_TRAIL
+	{0x0804, 0x0C, AR2020_REG_VALUE_08BIT},//TCLK_TRAIL_MIN
+	{0x0805, 0x07, AR2020_REG_VALUE_08BIT},//TCLK_PREPARE
+	{0x0806, 0x2B, AR2020_REG_VALUE_08BIT},//TCLK_ZERO
+	{0x0807, 0x09, AR2020_REG_VALUE_08BIT},//TLPX
+	{0x082A, 0x12, AR2020_REG_VALUE_08BIT},//TWAKEUP
+	{0x082B, 0x0E, AR2020_REG_VALUE_08BIT},//TINIT
+	{0x082C, 0x10, AR2020_REG_VALUE_08BIT},//THS_EXIT
+	{0x3F06, 0x00C0, AR2020_REG_VALUE_16BIT},//MIPI_TIMING_2
+	{0x3F0A, 0xA000, AR2020_REG_VALUE_16BIT},//MIPI_TIMING_4
+	{0x3F0C, 0x000C, AR2020_REG_VALUE_16BIT},//MIPI_TIMING_5
+	{0x3F20, 0x8080, AR2020_REG_VALUE_16BIT},//MIPI_PHY_TRIM_MSB
+	{0x3F1E, 0x0004, AR2020_REG_VALUE_16BIT},//MIPI_PHY_TRIM_LSB
+	{0x3f22, 0x3806, AR2020_REG_VALUE_16BIT},
+	{0x3040, 0x0011, AR2020_REG_VALUE_16BIT},//READ_MODE
+	{0x0220, 0x01, AR2020_REG_VALUE_08BIT},//HDR_MODE
+	{0x3F18, 0x3B30, AR2020_REG_VALUE_16BIT},//MIPI_JPEG_PN9_DATA_TYPE
+	{0x4000, 0x0114, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_00
+	{0x4002, 0x1A25, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_02
+	{0x4004, 0x3DFF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_04
+	{0x4006, 0xFFFF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_06
+	{0x4008, 0x0A35, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_08
+	{0x400A, 0x10EF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_0A
+	{0x400C, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_0C
+	{0x400E, 0x30D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_0E
+	{0x4010, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10
+	{0x4012, 0xB5F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12
+	{0x4014, 0x0085, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14
+	{0x4016, 0xF004, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16
+	{0x4018, 0x9A89, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18
+	{0x401A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A
+	{0x401C, 0x9997, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C
+	{0x401E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E
+	{0x4020, 0x30C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20
+	{0x4022, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22
+	{0x4024, 0x82F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24
+	{0x4026, 0x0030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26
+	{0x4028, 0x18F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28
+	{0x402A, 0x0320, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A
+	{0x402C, 0x58F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C
+	{0x402E, 0x089C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E
+	{0x4030, 0xF010, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30
+	{0x4032, 0x99B6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32
+	{0x4034, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34
+	{0x4036, 0xB498, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36
+	{0x4038, 0xA096, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38
+	{0x403A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A
+	{0x403C, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C
+	{0x403E, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E
+	{0x4040, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40
+	{0x4042, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42
+	{0x4044, 0x209D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44
+	{0x4046, 0x8C08, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46
+	{0x4048, 0x08F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48
+	{0x404A, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A
+	{0x404C, 0x008F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4C
+	{0x404E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4E
+	{0x4050, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_50
+	{0x4052, 0x0488, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_52
+	{0x4054, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_54
+	{0x4056, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_56
+	{0x4058, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_58
+	{0x405A, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_5A
+	{0x405C, 0x0290, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_5C
+	{0x405E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_5E
+	{0x4060, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_60
+	{0x4062, 0x2EA3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_62
+	{0x4064, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_64
+	{0x4066, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_66
+	{0x4068, 0x089D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_68
+	{0x406A, 0xF075, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_6A
+	{0x406C, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_6C
+	{0x406E, 0x4070, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_6E
+	{0x4070, 0x216D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_70
+	{0x4072, 0x1CF6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_72
+	{0x4074, 0x8B00, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_74
+	{0x4076, 0x5186, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_76
+	{0x4078, 0x1300, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_78
+	{0x407A, 0x0205, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_7A
+	{0x407C, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_7C
+	{0x407E, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_7E
+	{0x4080, 0x8387, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_80
+	{0x4082, 0xF006, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_82
+	{0x4084, 0x8702, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_84
+	{0x4086, 0x0D02, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_86
+	{0x4088, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_88
+	{0x408A, 0x0383, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_8A
+	{0x408C, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_8C
+	{0x408E, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_8E
+	{0x4090, 0x0213, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_90
+	{0x4092, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_92
+	{0x4094, 0xD887, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_94
+	{0x4096, 0x020D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_96
+	{0x4098, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_98
+	{0x409A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_9A
+	{0x409C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_9C
+	{0x409E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_9E
+	{0x40A0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A0
+	{0x40A2, 0x0401, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A2
+	{0x40A4, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A4
+	{0x40A6, 0x82F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A6
+	{0x40A8, 0x0883, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A8
+	{0x40AA, 0xF009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_AA
+	{0x40AC, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_AC
+	{0x40AE, 0x2985, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_AE
+	{0x40B0, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B0
+	{0x40B2, 0x2A87, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B2
+	{0x40B4, 0xF63E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B4
+	{0x40B6, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B6
+	{0x40B8, 0x0801, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B8
+	{0x40BA, 0x40F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_BA
+	{0x40BC, 0x0800, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_BC
+	{0x40BE, 0x48F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_BE
+	{0x40C0, 0x0882, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C0
+	{0x40C2, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C2
+	{0x40C4, 0x0401, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C4
+	{0x40C6, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C6
+	{0x40C8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C8
+	{0x40CA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_CA
+	{0x40CC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_CC
+	{0x40CE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_CE
+	{0x40D0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D0
+	{0x40D2, 0x0401, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D2
+	{0x40D4, 0xF015, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D4
+	{0x40D6, 0x002C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D6
+	{0x40D8, 0xF00E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D8
+	{0x40DA, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_DA
+	{0x40DC, 0x0687, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_DC
+	{0x40DE, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_DE
+	{0x40E0, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E0
+	{0x40E2, 0x61E8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E2
+	{0x40E4, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E4
+	{0x40E6, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E6
+	{0x40E8, 0x3480, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E8
+	{0x40EA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_EA
+	{0x40EC, 0x3240, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_EC
+	{0x40EE, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_EE
+	{0x40F0, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F0
+	{0x40F2, 0xF00E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F2
+	{0x40F4, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F4
+	{0x40F6, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F6
+	{0x40F8, 0x3240, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F8
+	{0x40FA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_FA
+	{0x40FC, 0x3480, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_FC
+	{0x40FE, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_FE
+	{0x4100, 0xC0E6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_100
+	{0x4102, 0xF004, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_102
+	{0x4104, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_104
+	{0x4106, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_106
+	{0x4108, 0xB0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_108
+	{0x410A, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10A
+	{0x410C, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10C
+	{0x410E, 0x86F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10E
+	{0x4110, 0x0086, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_110
+	{0x4112, 0xF089, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_112
+	{0x4114, 0xB0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_114
+	{0x4116, 0x00E9, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_116
+	{0x4118, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_118
+	{0x411A, 0x8AF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_11A
+	{0x411C, 0x0000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_11C
+	{0x411E, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_11E
+	{0x4120, 0x00E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_120
+	{0x4122, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_122
+	{0x4124, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_124
+	{0x4126, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_126
+	{0x4128, 0x0A35, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_128
+	{0x412A, 0x10EF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12A
+	{0x412C, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12C
+	{0x412E, 0x30D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12E
+	{0x4130, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_130
+	{0x4132, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_132
+	{0x4134, 0x049A, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_134
+	{0x4136, 0x89F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_136
+	{0x4138, 0x0099, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_138
+	{0x413A, 0x97F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_13A
+	{0x413C, 0x0030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_13C
+	{0x413E, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_13E
+	{0x4140, 0x0082, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_140
+	{0x4142, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_142
+	{0x4144, 0x3018, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_144
+	{0x4146, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_146
+	{0x4148, 0xB520, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_148
+	{0x414A, 0x58F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14A
+	{0x414C, 0x089C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14C
+	{0x414E, 0xF010, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14E
+	{0x4150, 0x99B6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_150
+	{0x4152, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_152
+	{0x4154, 0xB498, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_154
+	{0x4156, 0xA096, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_156
+	{0x4158, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_158
+	{0x415A, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_15A
+	{0x415C, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_15C
+	{0x415E, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_15E
+	{0x4160, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_160
+	{0x4162, 0x209D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_162
+	{0x4164, 0x8C08, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_164
+	{0x4166, 0x08F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_166
+	{0x4168, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_168
+	{0x416A, 0x008F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16A
+	{0x416C, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16C
+	{0x416E, 0x0188, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16E
+	{0x4170, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_170
+	{0x4172, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_172
+	{0x4174, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_174
+	{0x4176, 0x0290, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_176
+	{0x4178, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_178
+	{0x417A, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_17A
+	{0x417C, 0x2DA3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_17C
+	{0x417E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_17E
+	{0x4180, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_180
+	{0x4182, 0x089D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_182
+	{0x4184, 0xF06D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_184
+	{0x4186, 0x4070, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_186
+	{0x4188, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_188
+	{0x418A, 0x214D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18A
+	{0x418C, 0x1FF6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18C
+	{0x418E, 0x0851, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18E
+	{0x4190, 0x0245, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_190
+	{0x4192, 0x9D36, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_192
+	{0x4194, 0xD8F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_194
+	{0x4196, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_196
+	{0x4198, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_198
+	{0x419A, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_19A
+	{0x419C, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_19C
+	{0x419E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_19E
+	{0x41A0, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A0
+	{0x41A2, 0x020D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A2
+	{0x41A4, 0x0205, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A4
+	{0x41A6, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A6
+	{0x41A8, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A8
+	{0x41AA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1AA
+	{0x41AC, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1AC
+	{0x41AE, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1AE
+	{0x41B0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B0
+	{0x41B2, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B2
+	{0x41B4, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B4
+	{0x41B6, 0xD802, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B6
+	{0x41B8, 0x0D02, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B8
+	{0x41BA, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1BA
+	{0x41BC, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1BC
+	{0x41BE, 0xD8F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1BE
+	{0x41C0, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C0
+	{0x41C2, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C2
+	{0x41C4, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C4
+	{0x41C6, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C6
+	{0x41C8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C8
+	{0x41CA, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1CA
+	{0x41CC, 0x020D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1CC
+	{0x41CE, 0x0205, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1CE
+	{0x41D0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D0
+	{0x41D2, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D2
+	{0x41D4, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D4
+	{0x41D6, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D6
+	{0x41D8, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D8
+	{0x41DA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1DA
+	{0x41DC, 0x8713, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1DC
+	{0x41DE, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1DE
+	{0x41E0, 0xD802, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E0
+	{0x41E2, 0x0DE0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E2
+	{0x41E4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E4
+	{0x41E6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E6
+	{0x41E8, 0x0035, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E8
+	{0x41EA, 0x10AF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1EA
+	{0x41EC, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1EC
+	{0x41EE, 0x30C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1EE
+	{0x41F0, 0xB2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F0
+	{0x41F2, 0x01B5, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F2
+	{0x41F4, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F4
+	{0x41F6, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F6
+	{0x41F8, 0x0292, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F8
+	{0x41FA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1FA
+	{0x41FC, 0x9A8B, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1FC
+	{0x41FE, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1FE
+	{0x4200, 0x9997, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_200
+	{0x4202, 0xF007, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_202
+	{0x4204, 0xB6F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_204
+	{0x4206, 0x0020, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_206
+	{0x4208, 0x5830, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_208
+	{0x420A, 0xC040, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20A
+	{0x420C, 0x1282, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20C
+	{0x420E, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20E
+	{0x4210, 0x9CF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_210
+	{0x4212, 0x01B2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_212
+	{0x4214, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_214
+	{0x4216, 0xB8F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_216
+	{0x4218, 0x0799, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_218
+	{0x421A, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_21A
+	{0x421C, 0x98F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_21C
+	{0x421E, 0x0296, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_21E
+	{0x4220, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_220
+	{0x4222, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_222
+	{0x4224, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_224
+	{0x4226, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_226
+	{0x4228, 0x02A1, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_228
+	{0x422A, 0xF01F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22A
+	{0x422C, 0x1009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22C
+	{0x422E, 0x2220, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22E
+	{0x4230, 0x0808, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_230
+	{0x4232, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_232
+	{0x4234, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_234
+	{0x4236, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_236
+	{0x4238, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_238
+	{0x423A, 0x0788, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_23A
+	{0x423C, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_23C
+	{0x423E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_23E
+	{0x4240, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_240
+	{0x4242, 0x0290, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_242
+	{0x4244, 0xF016, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_244
+	{0x4246, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_246
+	{0x4248, 0x11A3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_248
+	{0x424A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24A
+	{0x424C, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24C
+	{0x424E, 0x089D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24E
+	{0x4250, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_250
+	{0x4252, 0xA1F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_252
+	{0x4254, 0x20A1, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_254
+	{0x4256, 0xF006, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_256
+	{0x4258, 0x4300, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_258
+	{0x425A, 0xF04A, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_25A
+	{0x425C, 0x8B8E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_25C
+	{0x425E, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_25E
+	{0x4260, 0x1640, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_260
+	{0x4262, 0x14F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_262
+	{0x4264, 0x0B02, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_264
+	{0x4266, 0x02F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_266
+	{0x4268, 0x00A6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_268
+	{0x426A, 0xF013, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26A
+	{0x426C, 0xB283, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26C
+	{0x426E, 0x9C36, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26E
+	{0x4270, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_270
+	{0x4272, 0x0636, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_272
+	{0x4274, 0x009C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_274
+	{0x4276, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_276
+	{0x4278, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_278
+	{0x427A, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_27A
+	{0x427C, 0xA0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_27C
+	{0x427E, 0x0630, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_27E
+	{0x4280, 0x18F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_280
+	{0x4282, 0x02A3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_282
+	{0x4284, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_284
+	{0x4286, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_286
+	{0x4288, 0x0243, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_288
+	{0x428A, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28A
+	{0x428C, 0x049D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28C
+	{0x428E, 0xF078, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28E
+	{0x4290, 0x3018, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_290
+	{0x4292, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_292
+	{0x4294, 0x9D82, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_294
+	{0x4296, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_296
+	{0x4298, 0x9030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_298
+	{0x429A, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_29A
+	{0x429C, 0x1130, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_29C
+	{0x429E, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_29E
+	{0x42A0, 0x0082, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A0
+	{0x42A2, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A2
+	{0x42A4, 0x1009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A4
+	{0x42A6, 0xF02A, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A6
+	{0x42A8, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A8
+	{0x42AA, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2AA
+	{0x42AC, 0x3018, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2AC
+	{0x42AE, 0xF007, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2AE
+	{0x42B0, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B0
+	{0x42B2, 0x1C8C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B2
+	{0x42B4, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B4
+	{0x42B6, 0x301F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B6
+	{0x42B8, 0x216D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B8
+	{0x42BA, 0x0A51, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2BA
+	{0x42BC, 0x1CEA, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2BC
+	{0x42BE, 0x4162, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2BE
+	{0x42C0, 0x0045, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C0
+	{0x42C2, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C2
+	{0x42C4, 0x30C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C4
+	{0x42C6, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C6
+	{0x42C8, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C8
+	{0x42CA, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2CA
+	{0x42CC, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2CC
+	{0x42CE, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2CE
+	{0x42D0, 0xF006, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D0
+	{0x42D2, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D2
+	{0x42D4, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D4
+	{0x42D6, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D6
+	{0x42D8, 0x0000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D8
+	{0x42DA, 0x0D00, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2DA
+	{0x42DC, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2DC
+	{0x42DE, 0x0030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2DE
+	{0x42E0, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E0
+	{0x42E2, 0x0183, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E2
+	{0x42E4, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E4
+	{0x42E6, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E6
+	{0x42E8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E8
+	{0x42EA, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2EA
+	{0x42EC, 0x0687, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2EC
+	{0x42EE, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2EE
+	{0x42F0, 0x36C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F0
+	{0x42F2, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F2
+	{0x42F4, 0x000F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F4
+	{0x42F6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F6
+	{0x42F8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F8
+	{0x42FA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2FA
+	{0x42FC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2FC
+	{0x42FE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2FE
+	{0x4300, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_300
+	{0x4302, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_302
+	{0x4304, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_304
+	{0x4306, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_306
+	{0x4308, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_308
+	{0x430A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30A
+	{0x430C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30C
+	{0x430E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30E
+	{0x4310, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_310
+	{0x4312, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_312
+	{0x4314, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_314
+	{0x4316, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_316
+	{0x4318, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_318
+	{0x431A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_31A
+	{0x431C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_31C
+	{0x431E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_31E
+	{0x4320, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_320
+	{0x4322, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_322
+	{0x4324, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_324
+	{0x4326, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_326
+	{0x4328, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_328
+	{0x432A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32A
+	{0x432C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32C
+	{0x432E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32E
+	{0x4330, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_330
+	{0x4332, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_332
+	{0x4334, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_334
+	{0x4336, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_336
+	{0x4338, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_338
+	{0x433A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_33A
+	{0x433C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_33C
+	{0x433E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_33E
+	{0x4340, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_340
+	{0x4342, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_342
+	{0x4344, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_344
+	{0x4346, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_346
+	{0x4348, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_348
+	{0x434A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34A
+	{0x434C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34C
+	{0x434E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34E
+	{0x4350, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_350
+	{0x4352, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_352
+	{0x4354, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_354
+	{0x4356, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_356
+	{0x4358, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_358
+	{0x435A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_35A
+	{0x435C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_35C
+	{0x435E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_35E
+	{0x4360, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_360
+	{0x4362, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_362
+	{0x4364, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_364
+	{0x4366, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_366
+	{0x4368, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_368
+	{0x436A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36A
+	{0x436C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36C
+	{0x436E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36E
+	{0x4370, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_370
+	{0x4372, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_372
+	{0x4374, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_374
+	{0x4376, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_376
+	{0x4378, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_378
+	{0x437A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_37A
+	{0x437C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_37C
+	{0x437E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_37E
+	{0x4380, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_380
+	{0x4382, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_382
+	{0x4384, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_384
+	{0x4386, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_386
+	{0x4388, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_388
+	{0x438A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38A
+	{0x438C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38C
+	{0x438E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38E
+	{0x4390, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_390
+	{0x4392, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_392
+	{0x4394, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_394
+	{0x4396, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_396
+	{0x4398, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_398
+	{0x439A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_39A
+	{0x439C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_39C
+	{0x439E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_39E
+	{0x43A0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A0
+	{0x43A2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A2
+	{0x43A4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A4
+	{0x43A6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A6
+	{0x43A8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A8
+	{0x43AA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3AA
+	{0x43AC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3AC
+	{0x43AE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3AE
+	{0x43B0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B0
+	{0x43B2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B2
+	{0x43B4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B4
+	{0x43B6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B6
+	{0x43B8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B8
+	{0x43BA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3BA
+	{0x43BC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3BC
+	{0x43BE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3BE
+	{0x43C0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C0
+	{0x43C2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C2
+	{0x43C4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C4
+	{0x43C6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C6
+	{0x43C8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C8
+	{0x43CA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3CA
+	{0x43CC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3CC
+	{0x43CE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3CE
+	{0x43D0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D0
+	{0x43D2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D2
+	{0x43D4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D4
+	{0x43D6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D6
+	{0x43D8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D8
+	{0x43DA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3DA
+	{0x43DC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3DC
+	{0x43DE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3DE
+	{0x43E0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E0
+	{0x43E2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E2
+	{0x43E4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E4
+	{0x43E6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E6
+	{0x43E8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E8
+	{0x43EA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3EA
+	{0x43EC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3EC
+	{0x43EE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3EE
+	{0x43F0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F0
+	{0x43F2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F2
+	{0x43F4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F4
+	{0x43F6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F6
+	{0x43F8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F8
+	{0x43FA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3FA
+	{0x43FC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3FC
+	{0x43FE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3FE
+	{0x4400, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_400
+	{0x4402, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_402
+	{0x4404, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_404
+	{0x4406, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_406
+	{0x4408, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_408
+	{0x440A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40A
+	{0x440C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40C
+	{0x440E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40E
+	{0x4410, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_410
+	{0x4412, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_412
+	{0x4414, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_414
+	{0x4416, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_416
+	{0x4418, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_418
+	{0x441A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_41A
+	{0x441C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_41C
+	{0x441E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_41E
+	{0x4420, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_420
+	{0x4422, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_422
+	{0x4424, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_424
+	{0x4426, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_426
+	{0x4428, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_428
+	{0x442A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42A
+	{0x442C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42C
+	{0x442E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42E
+	{0x4430, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_430
+	{0x4432, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_432
+	{0x4434, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_434
+	{0x4436, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_436
+	{0x4438, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_438
+	{0x443A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_43A
+	{0x443C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_43C
+	{0x443E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_43E
+	{0x4440, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_440
+	{0x4442, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_442
+	{0x4444, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_444
+	{0x4446, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_446
+	{0x4448, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_448
+	{0x444A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44A
+	{0x444C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44C
+	{0x444E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44E
+	{0x4450, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_450
+	{0x4452, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_452
+	{0x4454, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_454
+	{0x4456, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_456
+	{0x4458, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_458
+	{0x445A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_45A
+	{0x445C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_45C
+	{0x445E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_45E
+	{0x4460, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_460
+	{0x4462, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_462
+	{0x4464, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_464
+	{0x4466, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_466
+	{0x4468, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_468
+	{0x446A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46A
+	{0x446C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46C
+	{0x446E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46E
+	{0x4470, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_470
+	{0x4472, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_472
+	{0x4474, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_474
+	{0x4476, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_476
+	{0x4478, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_478
+	{0x447A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_47A
+	{0x447C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_47C
+	{0x447E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_47E
+	{0x4480, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_480
+	{0x4482, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_482
+	{0x4484, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_484
+	{0x4486, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_486
+	{0x4488, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_488
+	{0x448A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48A
+	{0x448C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48C
+	{0x448E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48E
+	{0x4490, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_490
+	{0x4492, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_492
+	{0x4494, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_494
+	{0x4496, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_496
+	{0x4498, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_498
+	{0x449A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_49A
+	{0x449C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_49C
+	{0x449E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_49E
+	{0x44A0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A0
+	{0x44A2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A2
+	{0x44A4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A4
+	{0x44A6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A6
+	{0x44A8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A8
+	{0x44AA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4AA
+	{0x44AC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4AC
+	{0x44AE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4AE
+	{0x44B0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4B0
+	{0x44B2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4B2
+	{0x44B4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4B4
+	{0x44BA, 0x036A, AR2020_REG_VALUE_16BIT},//DAC_LD_4_5
+	{0x44BC, 0xACAA, AR2020_REG_VALUE_16BIT},//DAC_LD_6_7
+	{0x44BE, 0x86C0, AR2020_REG_VALUE_16BIT},//DAC_LD_8_9
+	{0x44C0, 0x404B, AR2020_REG_VALUE_16BIT},//DAC_LD_10_11
+	{0x44C2, 0x2080, AR2020_REG_VALUE_16BIT},//DAC_LD_12_13
+	{0x44C4, 0x04BC, AR2020_REG_VALUE_16BIT},//DAC_LD_14_15
+	{0x44C6, 0x14E2, AR2020_REG_VALUE_16BIT},//DAC_LD_16_17
+	{0x44C8, 0x7743, AR2020_REG_VALUE_16BIT},//DAC_LD_18_19
+	{0x44CA, 0x000E, AR2020_REG_VALUE_16BIT},//DAC_LD_20_21
+	{0x44CC, 0x8888, AR2020_REG_VALUE_16BIT},//DAC_LD_22_23
+	{0x44CE, 0x8BA4, AR2020_REG_VALUE_16BIT},//DAC_LD_24_25
+	{0x44D0, 0x1735, AR2020_REG_VALUE_16BIT},//DAC_LD_26_27
+	{0x44D2, 0x0B87, AR2020_REG_VALUE_16BIT},//DAC_LD_28_29
+	{0x44D4, 0x8000, AR2020_REG_VALUE_16BIT},//DAC_LD_30_31
+	{0x44D6, 0xF206, AR2020_REG_VALUE_16BIT},//DAC_LD_32_33
+	{0x44D8, 0xAAFA, AR2020_REG_VALUE_16BIT},//DAC_LD_34_35
+	{0x44DA, 0xC001, AR2020_REG_VALUE_16BIT},//DAC_LD_36_37
+	{0x44DC, 0x1C80, AR2020_REG_VALUE_16BIT},//DAC_LD_38_39
+	{0x44DE, 0x1ABC, AR2020_REG_VALUE_16BIT},//DAC_LD_40_41
+	{0x44E0, 0x323C, AR2020_REG_VALUE_16BIT},//DAC_LD_42_43
+	{0x44E2, 0x3221, AR2020_REG_VALUE_16BIT},//DAC_LD_44_45
+	{0x44E4, 0x8000, AR2020_REG_VALUE_16BIT},//DAC_LD_46_47
+	{0x44E6, 0x723F, AR2020_REG_VALUE_16BIT},//DAC_LD_48_49
+	{0x32A4, 0x0000, AR2020_REG_VALUE_16BIT},//CRM_CTRL
+	{0x328E, 0x0004, AR2020_REG_VALUE_16BIT},//ADDR_CTRL
+	{0x333C, 0x0001, AR2020_REG_VALUE_16BIT},//DYNAMIC_CTRL
+	{0x3098, 0x0001, AR2020_REG_VALUE_16BIT},//MODULE_ODP_FORCE_CLK
+	{0x301A, 0x0000, AR2020_REG_VALUE_16BIT},//RESET_REGISTER
+	{0x3600, 0x94DF, AR2020_REG_VALUE_16BIT},//FDOC_CTRL
+	{0x3616, 0x0000, AR2020_REG_VALUE_16BIT},//FDOC_CTRL2
+	{0x3700, 0x0001, AR2020_REG_VALUE_16BIT},//PIX_DEF_ID
+	{0x3980, 0x0003, AR2020_REG_VALUE_16BIT},//PIX_DEF_CORR
+	{0x36C0, 0x0001, AR2020_REG_VALUE_16BIT},//DIGITAL_GAIN_CTRL
+	{0x36DE, 0x002A, AR2020_REG_VALUE_16BIT},//DATA_PEDESTAL1
+	{0x301A, 0x0008, AR2020_REG_VALUE_16BIT},//RESET_REGISTER
+	{0x31D2, 0x0784, AR2020_REG_VALUE_16BIT},//HDR_SC_GAIN_RATIO
+	{0x31D4, 0x110D, AR2020_REG_VALUE_16BIT},//HDR_SC_SCALE
+	{0x31D6, 0x01F4, AR2020_REG_VALUE_16BIT},//HDR_SC_THRESHOLD_1A
+	{0x31DA, 0x03D5, AR2020_REG_VALUE_16BIT},//HDR_SC_THRESHOLD_2A
+	{0x301A, 0x0000, AR2020_REG_VALUE_16BIT},//RESET_REGISTER
+	{0x0008, 0x00A8, AR2020_REG_VALUE_16BIT},//DATA_PEDESTAL
+	{0x301A, 0x0008, AR2020_REG_VALUE_16BIT},//RESET_REGISTER
+	{0x3340, 0x0C60, AR2020_REG_VALUE_16BIT},//OTPM_CTRL
+	{0x3340, 0x1C60, AR2020_REG_VALUE_16BIT},//OTPM_CTRL
+	{0x0100, 0x01, AR2020_REG_VALUE_08BIT},//MODE_SELECT
+	{0x44D6, 0xB206, AR2020_REG_VALUE_16BIT},//DAC_LD_32_33
+
+	{REG_NULL, 0x00, AR2020_REG_VALUE_16BIT},
+};
+
+static const struct regval ar2020_hdr10bit_5120x3840_30fps_8lane_regs[] = {
+	{REG_DELAY, 2000, AR2020_REG_VALUE_16BIT},
+	{0x44D6, 0xF206, AR2020_REG_VALUE_16BIT},//DAC_LD_32_33
+	{0x0100, 0x00, AR2020_REG_VALUE_08BIT},//MODE_SELECT
+	{0x0304, 0x0006, AR2020_REG_VALUE_16BIT},//VT_PRE_PLL_CLK_DIV
+	{0x0306, 0x00E5, AR2020_REG_VALUE_16BIT},//VT_PLL_MULTIPLIER
+	{0x0300, 0x0006, AR2020_REG_VALUE_16BIT},//VT_PIX_CLK_DIV
+	{0x0302, 0x0001, AR2020_REG_VALUE_16BIT},//VT_SYS_CLK_DIV
+	{0x030C, 0x0007, AR2020_REG_VALUE_16BIT},//OP_PRE_PLL_CLK_DIV
+	{0x030E, 0x01BD, AR2020_REG_VALUE_16BIT},//OP_PLL_MULTIPLIER
+	{0x0308, 0x0005, AR2020_REG_VALUE_16BIT},//OP_PIX_CLK_DIV
+	{0x030A, 0x0002, AR2020_REG_VALUE_16BIT},//OP_SYS_CLK_DIV
+	{0x0344, 0x0008, AR2020_REG_VALUE_16BIT},//X_ADDR_START
+	{0x0348, 0x1407, AR2020_REG_VALUE_16BIT},//X_ADDR_END
+	{0x0346, 0x0008, AR2020_REG_VALUE_16BIT},//Y_ADDR_START
+	{0x034A, 0x0F07, AR2020_REG_VALUE_16BIT},//Y_ADDR_END
+	{0x034C, 0x1400, AR2020_REG_VALUE_16BIT},//X_OUTPUT_SIZE
+	{0x034E, 0x0F00, AR2020_REG_VALUE_16BIT},//Y_OUTPUT_SIZE
+	{0x0380, 0x0001, AR2020_REG_VALUE_16BIT},//X_EVEN_INC
+	{0x0382, 0x0001, AR2020_REG_VALUE_16BIT},//X_ODD_INC
+	{0x0384, 0x0001, AR2020_REG_VALUE_16BIT},//Y_EVEN_INC
+	{0x0386, 0x0001, AR2020_REG_VALUE_16BIT},//Y_ODD_INC
+	{0x0900, 0x00, AR2020_REG_VALUE_08BIT},//BINNING_MODE
+	{0x0901, 0x11, AR2020_REG_VALUE_08BIT},//BINNING_TYPE
+	{0x0342, 0x1718, AR2020_REG_VALUE_16BIT},//LINE_LENGTH_PCK
+	{0x0340, 0x1E3C, AR2020_REG_VALUE_16BIT},//FRAME_LENGTH_LINES
+	{0x0112, 0x0A0A, AR2020_REG_VALUE_16BIT},//CSI_DATA_FORMAT
+	{0x0114, 0x07, AR2020_REG_VALUE_08BIT},//CSI_LANE_MODE
+	{0x0800, 0x10, AR2020_REG_VALUE_08BIT},//TCLK_POST
+	{0x0801, 0x09, AR2020_REG_VALUE_08BIT},//THS_PREPARE
+	{0x0802, 0x11, AR2020_REG_VALUE_08BIT},//THS_ZERO_MIN
+	{0x0803, 0x0C, AR2020_REG_VALUE_08BIT},//THS_TRAIL
+	{0x0804, 0x0F, AR2020_REG_VALUE_08BIT},//TCLK_TRAIL_MIN
+	{0x0805, 0x08, AR2020_REG_VALUE_08BIT},//TCLK_PREPARE
+	{0x0806, 0x34, AR2020_REG_VALUE_08BIT},//TCLK_ZERO
+	{0x0807, 0x0A, AR2020_REG_VALUE_08BIT},//TLPX
+	{0x082A, 0x15, AR2020_REG_VALUE_08BIT},//TWAKEUP
+	{0x082B, 0x11, AR2020_REG_VALUE_08BIT},//TINIT
+	{0x082C, 0x13, AR2020_REG_VALUE_08BIT},//THS_EXIT
+	{0x3F06, 0x00C0, AR2020_REG_VALUE_16BIT},//MIPI_TIMING_2
+	{0x3F0A, 0xA000, AR2020_REG_VALUE_16BIT},//MIPI_TIMING_4
+	{0x3F0C, 0x000E, AR2020_REG_VALUE_16BIT},//MIPI_TIMING_5
+	{0x3F20, 0x8080, AR2020_REG_VALUE_16BIT},//MIPI_PHY_TRIM_MSB
+	{0x3F1E, 0x0004, AR2020_REG_VALUE_16BIT},//MIPI_PHY_TRIM_LSB
+	{0x0202, 0x079E, AR2020_REG_VALUE_16BIT},//COARSE_INTEGRATION_TIME
+	{0x0224, 0x00C3, AR2020_REG_VALUE_16BIT},//SHORT_COARSE_INTEGRATION_TIME
+	{0x3040, 0x0010, AR2020_REG_VALUE_16BIT},//READ_MODE
+	{0x3042, 0x80F1, AR2020_REG_VALUE_16BIT},//T1_TO_T2_DIST_CTRL
+	{0x0220, 0x73, AR2020_REG_VALUE_08BIT},//HDR_MODE
+	{0x3F18, 0x7B70, AR2020_REG_VALUE_16BIT},//MIPI_JPEG_PN9_DATA_TYPE
+	{0x3F1A, 0x102B, AR2020_REG_VALUE_16BIT},
+	{0x3f22,  0x3806, AR2020_REG_VALUE_16BIT},
+	{0x4000, 0x0114, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_00
+	{0x4002, 0x1A25, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_02
+	{0x4004, 0x3DFF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_04
+	{0x4006, 0xFFFF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_06
+	{0x4008, 0x0A35, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_08
+	{0x400A, 0x10EF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_0A
+	{0x400C, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_0C
+	{0x400E, 0x30D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_0E
+	{0x4010, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10
+	{0x4012, 0xB5F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12
+	{0x4014, 0x0085, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14
+	{0x4016, 0xF004, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16
+	{0x4018, 0x9A89, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18
+	{0x401A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A
+	{0x401C, 0x9997, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C
+	{0x401E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E
+	{0x4020, 0x30C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20
+	{0x4022, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22
+	{0x4024, 0x82F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24
+	{0x4026, 0x0030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26
+	{0x4028, 0x18F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28
+	{0x402A, 0x0320, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A
+	{0x402C, 0x58F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C
+	{0x402E, 0x089C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E
+	{0x4030, 0xF010, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30
+	{0x4032, 0x99B6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32
+	{0x4034, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34
+	{0x4036, 0xB498, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36
+	{0x4038, 0xA096, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38
+	{0x403A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A
+	{0x403C, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C
+	{0x403E, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E
+	{0x4040, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40
+	{0x4042, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42
+	{0x4044, 0x209D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44
+	{0x4046, 0x8C08, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46
+	{0x4048, 0x08F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48
+	{0x404A, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A
+	{0x404C, 0x008F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4C
+	{0x404E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4E
+	{0x4050, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_50
+	{0x4052, 0x0488, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_52
+	{0x4054, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_54
+	{0x4056, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_56
+	{0x4058, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_58
+	{0x405A, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_5A
+	{0x405C, 0x0290, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_5C
+	{0x405E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_5E
+	{0x4060, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_60
+	{0x4062, 0x2EA3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_62
+	{0x4064, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_64
+	{0x4066, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_66
+	{0x4068, 0x089D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_68
+	{0x406A, 0xF075, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_6A
+	{0x406C, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_6C
+	{0x406E, 0x4070, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_6E
+	{0x4070, 0x216D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_70
+	{0x4072, 0x1CF6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_72
+	{0x4074, 0x8B00, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_74
+	{0x4076, 0x5186, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_76
+	{0x4078, 0x1300, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_78
+	{0x407A, 0x0205, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_7A
+	{0x407C, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_7C
+	{0x407E, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_7E
+	{0x4080, 0x8387, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_80
+	{0x4082, 0xF006, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_82
+	{0x4084, 0x8702, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_84
+	{0x4086, 0x0D02, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_86
+	{0x4088, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_88
+	{0x408A, 0x0383, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_8A
+	{0x408C, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_8C
+	{0x408E, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_8E
+	{0x4090, 0x0213, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_90
+	{0x4092, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_92
+	{0x4094, 0xD887, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_94
+	{0x4096, 0x020D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_96
+	{0x4098, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_98
+	{0x409A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_9A
+	{0x409C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_9C
+	{0x409E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_9E
+	{0x40A0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A0
+	{0x40A2, 0x0401, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A2
+	{0x40A4, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A4
+	{0x40A6, 0x82F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A6
+	{0x40A8, 0x0883, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A8
+	{0x40AA, 0xF009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_AA
+	{0x40AC, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_AC
+	{0x40AE, 0x2985, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_AE
+	{0x40B0, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B0
+	{0x40B2, 0x2A87, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B2
+	{0x40B4, 0xF63E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B4
+	{0x40B6, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B6
+	{0x40B8, 0x0801, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B8
+	{0x40BA, 0x40F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_BA
+	{0x40BC, 0x0800, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_BC
+	{0x40BE, 0x48F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_BE
+	{0x40C0, 0x0882, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C0
+	{0x40C2, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C2
+	{0x40C4, 0x0401, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C4
+	{0x40C6, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C6
+	{0x40C8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C8
+	{0x40CA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_CA
+	{0x40CC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_CC
+	{0x40CE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_CE
+	{0x40D0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D0
+	{0x40D2, 0x0401, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D2
+	{0x40D4, 0xF015, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D4
+	{0x40D6, 0x002C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D6
+	{0x40D8, 0xF00E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D8
+	{0x40DA, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_DA
+	{0x40DC, 0x0687, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_DC
+	{0x40DE, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_DE
+	{0x40E0, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E0
+	{0x40E2, 0x61E8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E2
+	{0x40E4, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E4
+	{0x40E6, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E6
+	{0x40E8, 0x3480, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E8
+	{0x40EA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_EA
+	{0x40EC, 0x3240, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_EC
+	{0x40EE, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_EE
+	{0x40F0, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F0
+	{0x40F2, 0xF00E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F2
+	{0x40F4, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F4
+	{0x40F6, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F6
+	{0x40F8, 0x3240, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F8
+	{0x40FA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_FA
+	{0x40FC, 0x3480, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_FC
+	{0x40FE, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_FE
+	{0x4100, 0xC0E6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_100
+	{0x4102, 0xF004, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_102
+	{0x4104, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_104
+	{0x4106, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_106
+	{0x4108, 0xB0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_108
+	{0x410A, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10A
+	{0x410C, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10C
+	{0x410E, 0x86F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10E
+	{0x4110, 0x0086, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_110
+	{0x4112, 0xF089, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_112
+	{0x4114, 0xB0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_114
+	{0x4116, 0x00E9, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_116
+	{0x4118, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_118
+	{0x411A, 0x8AF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_11A
+	{0x411C, 0x0000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_11C
+	{0x411E, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_11E
+	{0x4120, 0x00E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_120
+	{0x4122, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_122
+	{0x4124, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_124
+	{0x4126, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_126
+	{0x4128, 0x0A35, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_128
+	{0x412A, 0x10EF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12A
+	{0x412C, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12C
+	{0x412E, 0x30D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12E
+	{0x4130, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_130
+	{0x4132, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_132
+	{0x4134, 0x049A, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_134
+	{0x4136, 0x89F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_136
+	{0x4138, 0x0099, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_138
+	{0x413A, 0x97F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_13A
+	{0x413C, 0x0030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_13C
+	{0x413E, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_13E
+	{0x4140, 0x0082, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_140
+	{0x4142, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_142
+	{0x4144, 0x3018, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_144
+	{0x4146, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_146
+	{0x4148, 0xB520, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_148
+	{0x414A, 0x58F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14A
+	{0x414C, 0x089C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14C
+	{0x414E, 0xF010, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14E
+	{0x4150, 0x99B6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_150
+	{0x4152, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_152
+	{0x4154, 0xB498, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_154
+	{0x4156, 0xA096, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_156
+	{0x4158, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_158
+	{0x415A, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_15A
+	{0x415C, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_15C
+	{0x415E, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_15E
+	{0x4160, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_160
+	{0x4162, 0x209D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_162
+	{0x4164, 0x8C08, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_164
+	{0x4166, 0x08F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_166
+	{0x4168, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_168
+	{0x416A, 0x008F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16A
+	{0x416C, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16C
+	{0x416E, 0x0188, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16E
+	{0x4170, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_170
+	{0x4172, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_172
+	{0x4174, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_174
+	{0x4176, 0x0290, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_176
+	{0x4178, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_178
+	{0x417A, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_17A
+	{0x417C, 0x2DA3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_17C
+	{0x417E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_17E
+	{0x4180, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_180
+	{0x4182, 0x089D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_182
+	{0x4184, 0xF06D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_184
+	{0x4186, 0x4070, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_186
+	{0x4188, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_188
+	{0x418A, 0x214D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18A
+	{0x418C, 0x1FF6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18C
+	{0x418E, 0x0851, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18E
+	{0x4190, 0x0245, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_190
+	{0x4192, 0x9D36, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_192
+	{0x4194, 0xD8F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_194
+	{0x4196, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_196
+	{0x4198, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_198
+	{0x419A, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_19A
+	{0x419C, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_19C
+	{0x419E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_19E
+	{0x41A0, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A0
+	{0x41A2, 0x020D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A2
+	{0x41A4, 0x0205, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A4
+	{0x41A6, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A6
+	{0x41A8, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A8
+	{0x41AA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1AA
+	{0x41AC, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1AC
+	{0x41AE, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1AE
+	{0x41B0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B0
+	{0x41B2, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B2
+	{0x41B4, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B4
+	{0x41B6, 0xD802, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B6
+	{0x41B8, 0x0D02, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B8
+	{0x41BA, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1BA
+	{0x41BC, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1BC
+	{0x41BE, 0xD8F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1BE
+	{0x41C0, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C0
+	{0x41C2, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C2
+	{0x41C4, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C4
+	{0x41C6, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C6
+	{0x41C8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C8
+	{0x41CA, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1CA
+	{0x41CC, 0x020D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1CC
+	{0x41CE, 0x0205, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1CE
+	{0x41D0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D0
+	{0x41D2, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D2
+	{0x41D4, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D4
+	{0x41D6, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D6
+	{0x41D8, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D8
+	{0x41DA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1DA
+	{0x41DC, 0x8713, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1DC
+	{0x41DE, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1DE
+	{0x41E0, 0xD802, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E0
+	{0x41E2, 0x0DE0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E2
+	{0x41E4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E4
+	{0x41E6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E6
+	{0x41E8, 0x0035, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E8
+	{0x41EA, 0x10AF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1EA
+	{0x41EC, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1EC
+	{0x41EE, 0x30C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1EE
+	{0x41F0, 0xB2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F0
+	{0x41F2, 0x01B5, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F2
+	{0x41F4, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F4
+	{0x41F6, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F6
+	{0x41F8, 0x0292, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F8
+	{0x41FA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1FA
+	{0x41FC, 0x9A8B, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1FC
+	{0x41FE, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1FE
+	{0x4200, 0x9997, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_200
+	{0x4202, 0xF007, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_202
+	{0x4204, 0xB6F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_204
+	{0x4206, 0x0020, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_206
+	{0x4208, 0x5830, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_208
+	{0x420A, 0xC040, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20A
+	{0x420C, 0x1282, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20C
+	{0x420E, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20E
+	{0x4210, 0x9CF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_210
+	{0x4212, 0x01B2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_212
+	{0x4214, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_214
+	{0x4216, 0xB8F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_216
+	{0x4218, 0x0799, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_218
+	{0x421A, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_21A
+	{0x421C, 0x98F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_21C
+	{0x421E, 0x0296, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_21E
+	{0x4220, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_220
+	{0x4222, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_222
+	{0x4224, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_224
+	{0x4226, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_226
+	{0x4228, 0x02A1, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_228
+	{0x422A, 0xF01F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22A
+	{0x422C, 0x1009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22C
+	{0x422E, 0x2220, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22E
+	{0x4230, 0x0808, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_230
+	{0x4232, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_232
+	{0x4234, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_234
+	{0x4236, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_236
+	{0x4238, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_238
+	{0x423A, 0x0788, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_23A
+	{0x423C, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_23C
+	{0x423E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_23E
+	{0x4240, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_240
+	{0x4242, 0x0290, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_242
+	{0x4244, 0xF016, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_244
+	{0x4246, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_246
+	{0x4248, 0x11A3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_248
+	{0x424A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24A
+	{0x424C, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24C
+	{0x424E, 0x089D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24E
+	{0x4250, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_250
+	{0x4252, 0xA1F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_252
+	{0x4254, 0x20A1, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_254
+	{0x4256, 0xF006, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_256
+	{0x4258, 0x4300, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_258
+	{0x425A, 0xF04A, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_25A
+	{0x425C, 0x8B8E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_25C
+	{0x425E, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_25E
+	{0x4260, 0x1640, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_260
+	{0x4262, 0x14F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_262
+	{0x4264, 0x0B02, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_264
+	{0x4266, 0x02F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_266
+	{0x4268, 0x00A6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_268
+	{0x426A, 0xF013, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26A
+	{0x426C, 0xB283, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26C
+	{0x426E, 0x9C36, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26E
+	{0x4270, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_270
+	{0x4272, 0x0636, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_272
+	{0x4274, 0x009C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_274
+	{0x4276, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_276
+	{0x4278, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_278
+	{0x427A, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_27A
+	{0x427C, 0xA0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_27C
+	{0x427E, 0x0630, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_27E
+	{0x4280, 0x18F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_280
+	{0x4282, 0x02A3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_282
+	{0x4284, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_284
+	{0x4286, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_286
+	{0x4288, 0x0243, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_288
+	{0x428A, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28A
+	{0x428C, 0x049D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28C
+	{0x428E, 0xF078, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28E
+	{0x4290, 0x3018, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_290
+	{0x4292, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_292
+	{0x4294, 0x9D82, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_294
+	{0x4296, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_296
+	{0x4298, 0x9030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_298
+	{0x429A, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_29A
+	{0x429C, 0x1130, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_29C
+	{0x429E, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_29E
+	{0x42A0, 0x0082, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A0
+	{0x42A2, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A2
+	{0x42A4, 0x1009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A4
+	{0x42A6, 0xF02A, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A6
+	{0x42A8, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A8
+	{0x42AA, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2AA
+	{0x42AC, 0x3018, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2AC
+	{0x42AE, 0xF007, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2AE
+	{0x42B0, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B0
+	{0x42B2, 0x1C8C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B2
+	{0x42B4, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B4
+	{0x42B6, 0x301F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B6
+	{0x42B8, 0x216D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B8
+	{0x42BA, 0x0A51, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2BA
+	{0x42BC, 0x1CEA, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2BC
+	{0x42BE, 0x4162, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2BE
+	{0x42C0, 0x0045, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C0
+	{0x42C2, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C2
+	{0x42C4, 0x30C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C4
+	{0x42C6, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C6
+	{0x42C8, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C8
+	{0x42CA, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2CA
+	{0x42CC, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2CC
+	{0x42CE, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2CE
+	{0x42D0, 0xF006, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D0
+	{0x42D2, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D2
+	{0x42D4, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D4
+	{0x42D6, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D6
+	{0x42D8, 0x0000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D8
+	{0x42DA, 0x0D00, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2DA
+	{0x42DC, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2DC
+	{0x42DE, 0x0030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2DE
+	{0x42E0, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E0
+	{0x42E2, 0x0183, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E2
+	{0x42E4, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E4
+	{0x42E6, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E6
+	{0x42E8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E8
+	{0x42EA, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2EA
+	{0x42EC, 0x0687, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2EC
+	{0x42EE, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2EE
+	{0x42F0, 0x36C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F0
+	{0x42F2, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F2
+	{0x42F4, 0x000F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F4
+	{0x42F6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F6
+	{0x42F8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F8
+	{0x42FA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2FA
+	{0x42FC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2FC
+	{0x42FE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2FE
+	{0x4300, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_300
+	{0x4302, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_302
+	{0x4304, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_304
+	{0x4306, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_306
+	{0x4308, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_308
+	{0x430A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30A
+	{0x430C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30C
+	{0x430E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30E
+	{0x4310, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_310
+	{0x4312, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_312
+	{0x4314, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_314
+	{0x4316, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_316
+	{0x4318, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_318
+	{0x431A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_31A
+	{0x431C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_31C
+	{0x431E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_31E
+	{0x4320, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_320
+	{0x4322, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_322
+	{0x4324, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_324
+	{0x4326, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_326
+	{0x4328, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_328
+	{0x432A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32A
+	{0x432C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32C
+	{0x432E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32E
+	{0x4330, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_330
+	{0x4332, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_332
+	{0x4334, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_334
+	{0x4336, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_336
+	{0x4338, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_338
+	{0x433A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_33A
+	{0x433C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_33C
+	{0x433E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_33E
+	{0x4340, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_340
+	{0x4342, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_342
+	{0x4344, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_344
+	{0x4346, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_346
+	{0x4348, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_348
+	{0x434A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34A
+	{0x434C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34C
+	{0x434E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34E
+	{0x4350, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_350
+	{0x4352, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_352
+	{0x4354, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_354
+	{0x4356, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_356
+	{0x4358, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_358
+	{0x435A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_35A
+	{0x435C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_35C
+	{0x435E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_35E
+	{0x4360, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_360
+	{0x4362, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_362
+	{0x4364, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_364
+	{0x4366, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_366
+	{0x4368, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_368
+	{0x436A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36A
+	{0x436C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36C
+	{0x436E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36E
+	{0x4370, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_370
+	{0x4372, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_372
+	{0x4374, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_374
+	{0x4376, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_376
+	{0x4378, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_378
+	{0x437A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_37A
+	{0x437C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_37C
+	{0x437E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_37E
+	{0x4380, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_380
+	{0x4382, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_382
+	{0x4384, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_384
+	{0x4386, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_386
+	{0x4388, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_388
+	{0x438A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38A
+	{0x438C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38C
+	{0x438E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38E
+	{0x4390, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_390
+	{0x4392, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_392
+	{0x4394, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_394
+	{0x4396, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_396
+	{0x4398, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_398
+	{0x439A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_39A
+	{0x439C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_39C
+	{0x439E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_39E
+	{0x43A0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A0
+	{0x43A2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A2
+	{0x43A4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A4
+	{0x43A6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A6
+	{0x43A8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A8
+	{0x43AA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3AA
+	{0x43AC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3AC
+	{0x43AE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3AE
+	{0x43B0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B0
+	{0x43B2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B2
+	{0x43B4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B4
+	{0x43B6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B6
+	{0x43B8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B8
+	{0x43BA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3BA
+	{0x43BC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3BC
+	{0x43BE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3BE
+	{0x43C0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C0
+	{0x43C2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C2
+	{0x43C4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C4
+	{0x43C6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C6
+	{0x43C8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C8
+	{0x43CA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3CA
+	{0x43CC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3CC
+	{0x43CE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3CE
+	{0x43D0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D0
+	{0x43D2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D2
+	{0x43D4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D4
+	{0x43D6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D6
+	{0x43D8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D8
+	{0x43DA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3DA
+	{0x43DC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3DC
+	{0x43DE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3DE
+	{0x43E0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E0
+	{0x43E2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E2
+	{0x43E4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E4
+	{0x43E6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E6
+	{0x43E8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E8
+	{0x43EA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3EA
+	{0x43EC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3EC
+	{0x43EE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3EE
+	{0x43F0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F0
+	{0x43F2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F2
+	{0x43F4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F4
+	{0x43F6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F6
+	{0x43F8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F8
+	{0x43FA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3FA
+	{0x43FC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3FC
+	{0x43FE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3FE
+	{0x4400, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_400
+	{0x4402, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_402
+	{0x4404, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_404
+	{0x4406, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_406
+	{0x4408, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_408
+	{0x440A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40A
+	{0x440C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40C
+	{0x440E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40E
+	{0x4410, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_410
+	{0x4412, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_412
+	{0x4414, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_414
+	{0x4416, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_416
+	{0x4418, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_418
+	{0x441A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_41A
+	{0x441C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_41C
+	{0x441E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_41E
+	{0x4420, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_420
+	{0x4422, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_422
+	{0x4424, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_424
+	{0x4426, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_426
+	{0x4428, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_428
+	{0x442A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42A
+	{0x442C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42C
+	{0x442E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42E
+	{0x4430, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_430
+	{0x4432, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_432
+	{0x4434, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_434
+	{0x4436, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_436
+	{0x4438, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_438
+	{0x443A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_43A
+	{0x443C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_43C
+	{0x443E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_43E
+	{0x4440, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_440
+	{0x4442, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_442
+	{0x4444, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_444
+	{0x4446, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_446
+	{0x4448, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_448
+	{0x444A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44A
+	{0x444C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44C
+	{0x444E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44E
+	{0x4450, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_450
+	{0x4452, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_452
+	{0x4454, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_454
+	{0x4456, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_456
+	{0x4458, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_458
+	{0x445A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_45A
+	{0x445C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_45C
+	{0x445E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_45E
+	{0x4460, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_460
+	{0x4462, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_462
+	{0x4464, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_464
+	{0x4466, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_466
+	{0x4468, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_468
+	{0x446A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46A
+	{0x446C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46C
+	{0x446E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46E
+	{0x4470, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_470
+	{0x4472, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_472
+	{0x4474, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_474
+	{0x4476, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_476
+	{0x4478, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_478
+	{0x447A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_47A
+	{0x447C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_47C
+	{0x447E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_47E
+	{0x4480, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_480
+	{0x4482, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_482
+	{0x4484, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_484
+	{0x4486, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_486
+	{0x4488, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_488
+	{0x448A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48A
+	{0x448C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48C
+	{0x448E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48E
+	{0x4490, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_490
+	{0x4492, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_492
+	{0x4494, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_494
+	{0x4496, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_496
+	{0x4498, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_498
+	{0x449A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_49A
+	{0x449C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_49C
+	{0x449E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_49E
+	{0x44A0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A0
+	{0x44A2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A2
+	{0x44A4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A4
+	{0x44A6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A6
+	{0x44A8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A8
+	{0x44AA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4AA
+	{0x44AC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4AC
+	{0x44AE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4AE
+	{0x44B0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4B0
+	{0x44B2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4B2
+	{0x44B4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4B4
+	{0x5500, 0x0000, AR2020_REG_VALUE_16BIT},//AGAIN_LUT0
+	{0x5502, 0x0002, AR2020_REG_VALUE_16BIT},//AGAIN_LUT1
+	{0x5504, 0x0006, AR2020_REG_VALUE_16BIT},//AGAIN_LUT2
+	{0x5506, 0x0009, AR2020_REG_VALUE_16BIT},//AGAIN_LUT3
+	{0x5508, 0x000F, AR2020_REG_VALUE_16BIT},//AGAIN_LUT4
+	{0x550A, 0x0010, AR2020_REG_VALUE_16BIT},//AGAIN_LUT5
+	{0x550C, 0x0011, AR2020_REG_VALUE_16BIT},//AGAIN_LUT6
+	{0x550E, 0x0012, AR2020_REG_VALUE_16BIT},//AGAIN_LUT7
+	{0x5510, 0x0019, AR2020_REG_VALUE_16BIT},//AGAIN_LUT8
+	{0x5512, 0x0020, AR2020_REG_VALUE_16BIT},//AGAIN_LUT9
+	{0x5514, 0x0021, AR2020_REG_VALUE_16BIT},//AGAIN_LUT10
+	{0x5516, 0x0023, AR2020_REG_VALUE_16BIT},//AGAIN_LUT11
+	{0x5518, 0x0026, AR2020_REG_VALUE_16BIT},//AGAIN_LUT12
+	{0x551A, 0x002B, AR2020_REG_VALUE_16BIT},//AGAIN_LUT13
+	{0x551C, 0x002F, AR2020_REG_VALUE_16BIT},//AGAIN_LUT14
+	{0x551E, 0x0030, AR2020_REG_VALUE_16BIT},//AGAIN_LUT15
+	{0x5430, 0x0100, AR2020_REG_VALUE_16BIT},//GT2_COARSE0
+	{0x5432, 0x00E8, AR2020_REG_VALUE_16BIT},//GT2_COARSE1
+	{0x5434, 0x0123, AR2020_REG_VALUE_16BIT},//GT2_COARSE2
+	{0x5436, 0x0108, AR2020_REG_VALUE_16BIT},//GT2_COARSE3
+	{0x5438, 0x5125, AR2020_REG_VALUE_16BIT},//GT2_COARSE4
+	{0x543A, 0x510A, AR2020_REG_VALUE_16BIT},//GT2_COARSE5
+	{0x543C, 0x9133, AR2020_REG_VALUE_16BIT},//GT2_COARSE6
+	{0x543E, 0x9117, AR2020_REG_VALUE_16BIT},//GT2_COARSE7
+	{0x5440, 0xF130, AR2020_REG_VALUE_16BIT},//GT2_COARSE8
+	{0x5442, 0xF114, AR2020_REG_VALUE_16BIT},//GT2_COARSE9
+	{0x5444, 0xF186, AR2020_REG_VALUE_16BIT},//GT2_COARSE10
+	{0x5446, 0xF227, AR2020_REG_VALUE_16BIT},//GT2_COARSE11
+	{0x5448, 0xF30A, AR2020_REG_VALUE_16BIT},//GT2_COARSE12
+	{0x544A, 0xF44B, AR2020_REG_VALUE_16BIT},//GT2_COARSE13
+	{0x544C, 0xF611, AR2020_REG_VALUE_16BIT},//GT2_COARSE14
+	{0x544E, 0xF892, AR2020_REG_VALUE_16BIT},//GT2_COARSE15
+	{0x5450, 0xFC1B, AR2020_REG_VALUE_16BIT},//GT2_COARSE16
+	{0x5452, 0xFC1B, AR2020_REG_VALUE_16BIT},//GT2_COARSE17
+	{0x5454, 0x7772, AR2020_REG_VALUE_16BIT},//GT2_DCG_ATTN_SET0
+	{0x5456, 0x5557, AR2020_REG_VALUE_16BIT},//GT2_DCG_ATTN_SET1
+	{0x5458, 0x0005, AR2020_REG_VALUE_16BIT},//GT2_DCG_ATTN_SET2
+	{0x545A, 0xA550, AR2020_REG_VALUE_16BIT},//GT2_ZONE_SET0
+	{0x545C, 0xAAAA, AR2020_REG_VALUE_16BIT},//GT2_ZONE_SET1
+	{0x545E, 0x000A, AR2020_REG_VALUE_16BIT},//GT2_ZONE_SET2
+	{0x54A0, 0x0000, AR2020_REG_VALUE_16BIT},//ZT2_REG0_ADDR
+	{0x54A2, 0x0241, AR2020_REG_VALUE_16BIT},//ZT2_REG0_VALUE0
+	{0x54A4, 0x0841, AR2020_REG_VALUE_16BIT},//ZT2_REG0_VALUE1
+	{0x54A6, 0x0A41, AR2020_REG_VALUE_16BIT},//ZT2_REG0_VALUE2
+	{0x54D8, 0x0000, AR2020_REG_VALUE_16BIT},//ZT2_REG7_ADDR
+	{0x54DA, 0x54E2, AR2020_REG_VALUE_16BIT},//ZT2_REG7_VALUE0
+	{0x54DC, 0x54E3, AR2020_REG_VALUE_16BIT},//ZT2_REG7_VALUE1
+	{0x54DE, 0x54E3, AR2020_REG_VALUE_16BIT},//ZT2_REG7_VALUE2
+	{0x3060, 0x0007, AR2020_REG_VALUE_16BIT},//GAIN_TABLE_CTRL
+	{0x44BA, 0x0050, AR2020_REG_VALUE_16BIT},//DAC_LD_4_5
+	{0x44BC, 0xBCAA, AR2020_REG_VALUE_16BIT},//DAC_LD_6_7
+	{0x44C0, 0x4070, AR2020_REG_VALUE_16BIT},//DAC_LD_10_11
+	{0x44C4, 0x04D0, AR2020_REG_VALUE_16BIT},//DAC_LD_14_15
+	{0x44C6, 0x17E2, AR2020_REG_VALUE_16BIT},//DAC_LD_16_17
+	{0x44C8, 0x5A43, AR2020_REG_VALUE_16BIT},//DAC_LD_18_19
+	{0x44CA, 0x000E, AR2020_REG_VALUE_16BIT},//DAC_LD_20_21
+	{0x44CC, 0x7777, AR2020_REG_VALUE_16BIT},//DAC_LD_22_23
+	{0x44CE, 0x8BA4, AR2020_REG_VALUE_16BIT},//DAC_LD_24_25
+	{0x44D0, 0x1735, AR2020_REG_VALUE_16BIT},//DAC_LD_26_27
+	{0x44D4, 0x8000, AR2020_REG_VALUE_16BIT},//DAC_LD_30_31
+	{0x44D6, 0xF206, AR2020_REG_VALUE_16BIT},//DAC_LD_32_33
+	{0x44D8, 0xAAFA, AR2020_REG_VALUE_16BIT},//DAC_LD_34_35
+	{0x44DA, 0xE001, AR2020_REG_VALUE_16BIT},//DAC_LD_36_37
+	{0x44DC, 0x7480, AR2020_REG_VALUE_16BIT},//DAC_LD_38_39
+	{0x44DE, 0x9BBC, AR2020_REG_VALUE_16BIT},//DAC_LD_40_41
+	{0x44E0, 0x283C, AR2020_REG_VALUE_16BIT},//DAC_LD_42_43
+	{0x44E2, 0x2821, AR2020_REG_VALUE_16BIT},//DAC_LD_44_45
+	{0x44E4, 0x8000, AR2020_REG_VALUE_16BIT},//DAC_LD_46_47
+	{0x44E6, 0x703F, AR2020_REG_VALUE_16BIT},//DAC_LD_48_49
+	{0x32A4, 0x0000, AR2020_REG_VALUE_16BIT},//CRM_CTRL
+	{0x328E, 0x0004, AR2020_REG_VALUE_16BIT},//ADDR_CTRL
+	{0x333C, 0x0001, AR2020_REG_VALUE_16BIT},//DYNAMIC_CTRL
+	{0x301A, 0x0000, AR2020_REG_VALUE_16BIT},//RESET_REGISTER
+	{0x3600, 0x94DF, AR2020_REG_VALUE_16BIT},//FDOC_CTRL
+	{0x3616, 0x0000, AR2020_REG_VALUE_16BIT},//FDOC_CTRL2
+	{0x3700, 0x0001, AR2020_REG_VALUE_16BIT},//PIX_DEF_ID
+	{0x3980, 0x0003, AR2020_REG_VALUE_16BIT},//PIX_DEF_CORR
+	{0x36C0, 0x0001, AR2020_REG_VALUE_16BIT},//DIGITAL_GAIN_CTRL
+	{0x36DE, 0x002A, AR2020_REG_VALUE_16BIT},//DATA_PEDESTAL1
+	{0x301A, 0x0008, AR2020_REG_VALUE_16BIT},//RESET_REGISTER
+	{0x4600, 0x0333, AR2020_REG_VALUE_16BIT},//LISREG_CTRL
+	{0x4602, 0x311C, AR2020_REG_VALUE_16BIT},//LISREG0_CTRL
+	{0x4604, 0x090B, AR2020_REG_VALUE_16BIT},//LISREG0_DATA0N1
+	{0x4606, 0x0009, AR2020_REG_VALUE_16BIT},//LISREG0_DATA2
+	{0x4608, 0x3206, AR2020_REG_VALUE_16BIT},//LISREG1_CTRL
+	{0x460A, 0xBCBC, AR2020_REG_VALUE_16BIT},//LISREG1_DATA0N1
+	{0x460C, 0x00BE, AR2020_REG_VALUE_16BIT},//LISREG1_DATA2
+	{0x460E, 0x3112, AR2020_REG_VALUE_16BIT},//LISREG2_CTRL
+	{0x4610, 0x5AFA, AR2020_REG_VALUE_16BIT},//LISREG2_DATA0N1
+	{0x4612, 0x005A, AR2020_REG_VALUE_16BIT},//LISREG2_DATA2
+	{0x3340, 0x0C60, AR2020_REG_VALUE_16BIT},//OTPM_CTRL
+	{0x3340, 0x1C60, AR2020_REG_VALUE_16BIT},//OTPM_CTRL
+	{0x0101, 0x01, AR2020_REG_VALUE_08BIT},//Bing added, this is for H mirror FLIP.
+	{0x0100, 0x01, AR2020_REG_VALUE_08BIT},//MODE_SELECT
+	{0x44D6, 0xB206, AR2020_REG_VALUE_16BIT},//DAC_LD_32_33
+
+	{REG_NULL, 0x00, AR2020_REG_VALUE_16BIT},
+};
+
+static const struct regval ar2020_hdr10bit_5120x3840_22fps_8lane_regs[] = {
+	{REG_DELAY, 2000, AR2020_REG_VALUE_16BIT},
+	{0x44D6, 0xF206, AR2020_REG_VALUE_16BIT},//DAC_LD_32_33
+	{0x0100, 0x00, AR2020_REG_VALUE_08BIT},//MODE_SELECT
+	{0x0304, 0x0002, AR2020_REG_VALUE_16BIT},//VT_PRE_PLL_CLK_DIV
+	{0x0306, 0x0067, AR2020_REG_VALUE_16BIT},//VT_PLL_MULTIPLIER
+	{0x0300, 0x0006, AR2020_REG_VALUE_16BIT},//VT_PIX_CLK_DIV
+	{0x0302, 0x0001, AR2020_REG_VALUE_16BIT},//VT_SYS_CLK_DIV
+	{0x030C, 0x0007, AR2020_REG_VALUE_16BIT},//OP_PRE_PLL_CLK_DIV
+	{0x030E, 0x01A4, AR2020_REG_VALUE_16BIT},//OP_PLL_MULTIPLIER
+	{0x0308, 0x0005, AR2020_REG_VALUE_16BIT},//OP_PIX_CLK_DIV
+	{0x030A, 0x0002, AR2020_REG_VALUE_16BIT},//OP_SYS_CLK_DIV
+	{0x0344, 0x0008, AR2020_REG_VALUE_16BIT},//X_ADDR_START
+	{0x0348, 0x1407, AR2020_REG_VALUE_16BIT},//X_ADDR_END
+	{0x0346, 0x0008, AR2020_REG_VALUE_16BIT},//Y_ADDR_START
+	{0x034A, 0x0F07, AR2020_REG_VALUE_16BIT},//Y_ADDR_END
+	{0x034C, 0x1400, AR2020_REG_VALUE_16BIT},//X_OUTPUT_SIZE
+	{0x034E, 0x0F00, AR2020_REG_VALUE_16BIT},//Y_OUTPUT_SIZE
+	{0x0380, 0x0001, AR2020_REG_VALUE_16BIT},//X_EVEN_INC
+	{0x0382, 0x0001, AR2020_REG_VALUE_16BIT},//X_ODD_INC
+	{0x0384, 0x0001, AR2020_REG_VALUE_16BIT},//Y_EVEN_INC
+	{0x0386, 0x0001, AR2020_REG_VALUE_16BIT},//Y_ODD_INC
+	{0x0900, 0x00, AR2020_REG_VALUE_08BIT},//BINNING_MODE
+	{0x0901, 0x11, AR2020_REG_VALUE_08BIT},//BINNING_TYPE
+	{0x0342, 0x1FC0, AR2020_REG_VALUE_16BIT},//LINE_LENGTH_PCK
+	{0x0340, 0x1E3C, AR2020_REG_VALUE_16BIT},//FRAME_LENGTH_LINES
+	{0x0202, 0x00E8, AR2020_REG_VALUE_16BIT},//COARSE_INTEGRATION_TIME
+	{0x0112, 0x0A0A, AR2020_REG_VALUE_16BIT},//CSI_DATA_FORMAT
+	{0x0114, 0x07, AR2020_REG_VALUE_08BIT},//CSI_LANE_MODE
+	{0x0800, 0x0D, AR2020_REG_VALUE_08BIT},//TCLK_POST
+	{0x0801, 0x07, AR2020_REG_VALUE_08BIT},//THS_PREPARE
+	{0x0802, 0x0C, AR2020_REG_VALUE_08BIT},//THS_ZERO_MIN
+	{0x0803, 0x09, AR2020_REG_VALUE_08BIT},//THS_TRAIL
+	{0x0804, 0x0B, AR2020_REG_VALUE_08BIT},//TCLK_TRAIL_MIN
+	{0x0805, 0x06, AR2020_REG_VALUE_08BIT},//TCLK_PREPARE
+	{0x0806, 0x24, AR2020_REG_VALUE_08BIT},//TCLK_ZERO
+	{0x0807, 0x07, AR2020_REG_VALUE_08BIT},//TLPX
+	{0x082A, 0x0F, AR2020_REG_VALUE_08BIT},//TWAKEUP
+	{0x082B, 0x0C, AR2020_REG_VALUE_08BIT},//TINIT
+	{0x082C, 0x0D, AR2020_REG_VALUE_08BIT},//THS_EXIT
+	{0x3F06, 0x00C0, AR2020_REG_VALUE_16BIT},//MIPI_TIMING_2
+	{0x3F0A, 0xA000, AR2020_REG_VALUE_16BIT},//MIPI_TIMING_4
+	{0x3F0C, 0x000A, AR2020_REG_VALUE_16BIT},//MIPI_TIMING_5
+	{0x3F20, 0x8080, AR2020_REG_VALUE_16BIT},//MIPI_PHY_TRIM_MSB
+	{0x3F1E, 0x0004, AR2020_REG_VALUE_16BIT},//MIPI_PHY_TRIM_LSB
+	{0x3F1A, 0x102B, AR2020_REG_VALUE_16BIT},
+	{0x3f22,  0x3806, AR2020_REG_VALUE_16BIT},
+	{0x3040, 0x0010, AR2020_REG_VALUE_16BIT},//READ_MODE
+	{0x3042, 0x80F1, AR2020_REG_VALUE_16BIT},//T1_TO_T2_DIST_CTRL
+	{0x0220, 0x73, AR2020_REG_VALUE_08BIT},//HDR_MODE
+	{0x3F18, 0x7B70, AR2020_REG_VALUE_16BIT},//MIPI_JPEG_PN9_DATA_TYPE
+	{0x4000, 0x0114, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_00
+	{0x4002, 0x1A25, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_02
+	{0x4004, 0x3DFF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_04
+	{0x4006, 0xFFFF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_06
+	{0x4008, 0x0A35, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_08
+	{0x400A, 0x10EF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_0A
+	{0x400C, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_0C
+	{0x400E, 0x30D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_0E
+	{0x4010, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10
+	{0x4012, 0xB5F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12
+	{0x4014, 0x0085, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14
+	{0x4016, 0xF004, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16
+	{0x4018, 0x9A89, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18
+	{0x401A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A
+	{0x401C, 0x9997, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C
+	{0x401E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E
+	{0x4020, 0x30C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20
+	{0x4022, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22
+	{0x4024, 0x82F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24
+	{0x4026, 0x0030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26
+	{0x4028, 0x18F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28
+	{0x402A, 0x0320, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A
+	{0x402C, 0x58F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C
+	{0x402E, 0x089C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E
+	{0x4030, 0xF010, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30
+	{0x4032, 0x99B6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32
+	{0x4034, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34
+	{0x4036, 0xB498, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36
+	{0x4038, 0xA096, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38
+	{0x403A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A
+	{0x403C, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C
+	{0x403E, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E
+	{0x4040, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40
+	{0x4042, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42
+	{0x4044, 0x209D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44
+	{0x4046, 0x8C08, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46
+	{0x4048, 0x08F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48
+	{0x404A, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A
+	{0x404C, 0x008F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4C
+	{0x404E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4E
+	{0x4050, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_50
+	{0x4052, 0x0488, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_52
+	{0x4054, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_54
+	{0x4056, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_56
+	{0x4058, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_58
+	{0x405A, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_5A
+	{0x405C, 0x0290, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_5C
+	{0x405E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_5E
+	{0x4060, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_60
+	{0x4062, 0x2EA3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_62
+	{0x4064, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_64
+	{0x4066, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_66
+	{0x4068, 0x089D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_68
+	{0x406A, 0xF075, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_6A
+	{0x406C, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_6C
+	{0x406E, 0x4070, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_6E
+	{0x4070, 0x216D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_70
+	{0x4072, 0x1CF6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_72
+	{0x4074, 0x8B00, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_74
+	{0x4076, 0x5186, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_76
+	{0x4078, 0x1300, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_78
+	{0x407A, 0x0205, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_7A
+	{0x407C, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_7C
+	{0x407E, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_7E
+	{0x4080, 0x8387, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_80
+	{0x4082, 0xF006, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_82
+	{0x4084, 0x8702, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_84
+	{0x4086, 0x0D02, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_86
+	{0x4088, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_88
+	{0x408A, 0x0383, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_8A
+	{0x408C, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_8C
+	{0x408E, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_8E
+	{0x4090, 0x0213, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_90
+	{0x4092, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_92
+	{0x4094, 0xD887, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_94
+	{0x4096, 0x020D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_96
+	{0x4098, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_98
+	{0x409A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_9A
+	{0x409C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_9C
+	{0x409E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_9E
+	{0x40A0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A0
+	{0x40A2, 0x0401, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A2
+	{0x40A4, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A4
+	{0x40A6, 0x82F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A6
+	{0x40A8, 0x0883, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A8
+	{0x40AA, 0xF009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_AA
+	{0x40AC, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_AC
+	{0x40AE, 0x2985, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_AE
+	{0x40B0, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B0
+	{0x40B2, 0x2A87, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B2
+	{0x40B4, 0xF63E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B4
+	{0x40B6, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B6
+	{0x40B8, 0x0801, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B8
+	{0x40BA, 0x40F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_BA
+	{0x40BC, 0x0800, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_BC
+	{0x40BE, 0x48F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_BE
+	{0x40C0, 0x0882, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C0
+	{0x40C2, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C2
+	{0x40C4, 0x0401, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C4
+	{0x40C6, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C6
+	{0x40C8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C8
+	{0x40CA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_CA
+	{0x40CC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_CC
+	{0x40CE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_CE
+	{0x40D0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D0
+	{0x40D2, 0x0401, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D2
+	{0x40D4, 0xF015, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D4
+	{0x40D6, 0x002C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D6
+	{0x40D8, 0xF00E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D8
+	{0x40DA, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_DA
+	{0x40DC, 0x0687, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_DC
+	{0x40DE, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_DE
+	{0x40E0, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E0
+	{0x40E2, 0x61E8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E2
+	{0x40E4, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E4
+	{0x40E6, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E6
+	{0x40E8, 0x3480, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E8
+	{0x40EA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_EA
+	{0x40EC, 0x3240, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_EC
+	{0x40EE, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_EE
+	{0x40F0, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F0
+	{0x40F2, 0xF00E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F2
+	{0x40F4, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F4
+	{0x40F6, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F6
+	{0x40F8, 0x3240, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F8
+	{0x40FA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_FA
+	{0x40FC, 0x3480, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_FC
+	{0x40FE, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_FE
+	{0x4100, 0xC0E6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_100
+	{0x4102, 0xF004, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_102
+	{0x4104, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_104
+	{0x4106, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_106
+	{0x4108, 0xB0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_108
+	{0x410A, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10A
+	{0x410C, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10C
+	{0x410E, 0x86F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10E
+	{0x4110, 0x0086, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_110
+	{0x4112, 0xF089, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_112
+	{0x4114, 0xB0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_114
+	{0x4116, 0x00E9, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_116
+	{0x4118, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_118
+	{0x411A, 0x8AF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_11A
+	{0x411C, 0x0000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_11C
+	{0x411E, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_11E
+	{0x4120, 0x00E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_120
+	{0x4122, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_122
+	{0x4124, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_124
+	{0x4126, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_126
+	{0x4128, 0x0A35, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_128
+	{0x412A, 0x10EF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12A
+	{0x412C, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12C
+	{0x412E, 0x30D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12E
+	{0x4130, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_130
+	{0x4132, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_132
+	{0x4134, 0x049A, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_134
+	{0x4136, 0x89F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_136
+	{0x4138, 0x0099, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_138
+	{0x413A, 0x97F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_13A
+	{0x413C, 0x0030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_13C
+	{0x413E, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_13E
+	{0x4140, 0x0082, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_140
+	{0x4142, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_142
+	{0x4144, 0x3018, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_144
+	{0x4146, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_146
+	{0x4148, 0xB520, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_148
+	{0x414A, 0x58F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14A
+	{0x414C, 0x089C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14C
+	{0x414E, 0xF010, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14E
+	{0x4150, 0x99B6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_150
+	{0x4152, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_152
+	{0x4154, 0xB498, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_154
+	{0x4156, 0xA096, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_156
+	{0x4158, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_158
+	{0x415A, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_15A
+	{0x415C, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_15C
+	{0x415E, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_15E
+	{0x4160, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_160
+	{0x4162, 0x209D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_162
+	{0x4164, 0x8C08, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_164
+	{0x4166, 0x08F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_166
+	{0x4168, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_168
+	{0x416A, 0x008F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16A
+	{0x416C, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16C
+	{0x416E, 0x0188, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16E
+	{0x4170, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_170
+	{0x4172, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_172
+	{0x4174, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_174
+	{0x4176, 0x0290, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_176
+	{0x4178, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_178
+	{0x417A, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_17A
+	{0x417C, 0x2DA3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_17C
+	{0x417E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_17E
+	{0x4180, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_180
+	{0x4182, 0x089D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_182
+	{0x4184, 0xF06D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_184
+	{0x4186, 0x4070, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_186
+	{0x4188, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_188
+	{0x418A, 0x214D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18A
+	{0x418C, 0x1FF6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18C
+	{0x418E, 0x0851, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18E
+	{0x4190, 0x0245, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_190
+	{0x4192, 0x9D36, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_192
+	{0x4194, 0xD8F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_194
+	{0x4196, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_196
+	{0x4198, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_198
+	{0x419A, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_19A
+	{0x419C, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_19C
+	{0x419E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_19E
+	{0x41A0, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A0
+	{0x41A2, 0x020D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A2
+	{0x41A4, 0x0205, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A4
+	{0x41A6, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A6
+	{0x41A8, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A8
+	{0x41AA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1AA
+	{0x41AC, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1AC
+	{0x41AE, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1AE
+	{0x41B0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B0
+	{0x41B2, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B2
+	{0x41B4, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B4
+	{0x41B6, 0xD802, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B6
+	{0x41B8, 0x0D02, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B8
+	{0x41BA, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1BA
+	{0x41BC, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1BC
+	{0x41BE, 0xD8F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1BE
+	{0x41C0, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C0
+	{0x41C2, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C2
+	{0x41C4, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C4
+	{0x41C6, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C6
+	{0x41C8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C8
+	{0x41CA, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1CA
+	{0x41CC, 0x020D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1CC
+	{0x41CE, 0x0205, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1CE
+	{0x41D0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D0
+	{0x41D2, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D2
+	{0x41D4, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D4
+	{0x41D6, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D6
+	{0x41D8, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D8
+	{0x41DA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1DA
+	{0x41DC, 0x8713, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1DC
+	{0x41DE, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1DE
+	{0x41E0, 0xD802, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E0
+	{0x41E2, 0x0DE0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E2
+	{0x41E4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E4
+	{0x41E6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E6
+	{0x41E8, 0x9F13, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E8
+	{0x41EA, 0x0041, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1EA
+	{0x41EC, 0x80F3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1EC
+	{0x41EE, 0xF213, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1EE
+	{0x41F0, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F0
+	{0x41F2, 0x13B8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F2
+	{0x41F4, 0xF04C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F4
+	{0x41F6, 0x9FF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F6
+	{0x41F8, 0x00B7, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F8
+	{0x41FA, 0xF006, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1FA
+	{0x41FC, 0x0035, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1FC
+	{0x41FE, 0x10AF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1FE
+	{0x4200, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_200
+	{0x4202, 0x30C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_202
+	{0x4204, 0xB2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_204
+	{0x4206, 0x01B5, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_206
+	{0x4208, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_208
+	{0x420A, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20A
+	{0x420C, 0x0292, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20C
+	{0x420E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20E
+	{0x4210, 0x9A8B, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_210
+	{0x4212, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_212
+	{0x4214, 0x9997, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_214
+	{0x4216, 0xF007, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_216
+	{0x4218, 0xB6F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_218
+	{0x421A, 0x0020, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_21A
+	{0x421C, 0x5830, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_21C
+	{0x421E, 0xC040, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_21E
+	{0x4220, 0x1282, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_220
+	{0x4222, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_222
+	{0x4224, 0x9CF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_224
+	{0x4226, 0x01B2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_226
+	{0x4228, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_228
+	{0x422A, 0xB8F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22A
+	{0x422C, 0x0799, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22C
+	{0x422E, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22E
+	{0x4230, 0x98F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_230
+	{0x4232, 0x0296, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_232
+	{0x4234, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_234
+	{0x4236, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_236
+	{0x4238, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_238
+	{0x423A, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_23A
+	{0x423C, 0x02A1, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_23C
+	{0x423E, 0xF01F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_23E
+	{0x4240, 0x1009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_240
+	{0x4242, 0x2220, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_242
+	{0x4244, 0x0808, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_244
+	{0x4246, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_246
+	{0x4248, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_248
+	{0x424A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24A
+	{0x424C, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24C
+	{0x424E, 0x0788, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24E
+	{0x4250, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_250
+	{0x4252, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_252
+	{0x4254, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_254
+	{0x4256, 0x0290, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_256
+	{0x4258, 0xF016, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_258
+	{0x425A, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_25A
+	{0x425C, 0x11A3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_25C
+	{0x425E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_25E
+	{0x4260, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_260
+	{0x4262, 0x089D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_262
+	{0x4264, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_264
+	{0x4266, 0xA1F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_266
+	{0x4268, 0x20A1, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_268
+	{0x426A, 0xF006, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26A
+	{0x426C, 0x4300, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26C
+	{0x426E, 0xF049, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26E
+	{0x4270, 0x4014, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_270
+	{0x4272, 0x8B8E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_272
+	{0x4274, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_274
+	{0x4276, 0x0802, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_276
+	{0x4278, 0x02F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_278
+	{0x427A, 0x00A6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_27A
+	{0x427C, 0xF013, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_27C
+	{0x427E, 0xB283, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_27E
+	{0x4280, 0x9C36, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_280
+	{0x4282, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_282
+	{0x4284, 0x0636, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_284
+	{0x4286, 0x009C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_286
+	{0x4288, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_288
+	{0x428A, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28A
+	{0x428C, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28C
+	{0x428E, 0xA0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28E
+	{0x4290, 0x0630, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_290
+	{0x4292, 0x18F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_292
+	{0x4294, 0x02A3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_294
+	{0x4296, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_296
+	{0x4298, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_298
+	{0x429A, 0x0243, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_29A
+	{0x429C, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_29C
+	{0x429E, 0x049D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_29E
+	{0x42A0, 0xF078, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A0
+	{0x42A2, 0x3018, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A2
+	{0x42A4, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A4
+	{0x42A6, 0x9D82, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A6
+	{0x42A8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A8
+	{0x42AA, 0x9030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2AA
+	{0x42AC, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2AC
+	{0x42AE, 0x1130, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2AE
+	{0x42B0, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B0
+	{0x42B2, 0x0082, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B2
+	{0x42B4, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B4
+	{0x42B6, 0x1009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B6
+	{0x42B8, 0xF02A, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B8
+	{0x42BA, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2BA
+	{0x42BC, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2BC
+	{0x42BE, 0x3018, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2BE
+	{0x42C0, 0xF007, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C0
+	{0x42C2, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C2
+	{0x42C4, 0x1C8C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C4
+	{0x42C6, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C6
+	{0x42C8, 0x301F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C8
+	{0x42CA, 0x216D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2CA
+	{0x42CC, 0x0A51, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2CC
+	{0x42CE, 0x1FEA, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2CE
+	{0x42D0, 0x8640, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D0
+	{0x42D2, 0xE29F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D2
+	{0x42D4, 0xF009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D4
+	{0x42D6, 0x0005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D6
+	{0x42D8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D8
+	{0x42DA, 0x30C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2DA
+	{0x42DC, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2DC
+	{0x42DE, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2DE
+	{0x42E0, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E0
+	{0x42E2, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E2
+	{0x42E4, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E4
+	{0x42E6, 0xF007, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E6
+	{0x42E8, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E8
+	{0x42EA, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2EA
+	{0x42EC, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2EC
+	{0x42EE, 0x0000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2EE
+	{0x42F0, 0x0DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F0
+	{0x42F2, 0x0000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F2
+	{0x42F4, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F4
+	{0x42F6, 0x0030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F6
+	{0x42F8, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F8
+	{0x42FA, 0x0183, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2FA
+	{0x42FC, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2FC
+	{0x42FE, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2FE
+	{0x4300, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_300
+	{0x4302, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_302
+	{0x4304, 0x0787, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_304
+	{0x4306, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_306
+	{0x4308, 0x36C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_308
+	{0x430A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30A
+	{0x430C, 0x000F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30C
+	{0x430E, 0xF42A, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30E
+	{0x4310, 0x4180, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_310
+	{0x4312, 0x1300, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_312
+	{0x4314, 0x9FF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_314
+	{0x4316, 0x00E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_316
+	{0x4318, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_318
+	{0x431A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_31A
+	{0x431C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_31C
+	{0x431E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_31E
+	{0x4320, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_320
+	{0x4322, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_322
+	{0x4324, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_324
+	{0x4326, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_326
+	{0x4328, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_328
+	{0x432A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32A
+	{0x432C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32C
+	{0x432E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32E
+	{0x4330, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_330
+	{0x4332, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_332
+	{0x4334, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_334
+	{0x4336, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_336
+	{0x4338, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_338
+	{0x433A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_33A
+	{0x433C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_33C
+	{0x433E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_33E
+	{0x4340, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_340
+	{0x4342, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_342
+	{0x4344, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_344
+	{0x4346, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_346
+	{0x4348, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_348
+	{0x434A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34A
+	{0x434C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34C
+	{0x434E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34E
+	{0x4350, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_350
+	{0x4352, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_352
+	{0x4354, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_354
+	{0x4356, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_356
+	{0x4358, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_358
+	{0x435A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_35A
+	{0x435C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_35C
+	{0x435E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_35E
+	{0x4360, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_360
+	{0x4362, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_362
+	{0x4364, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_364
+	{0x4366, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_366
+	{0x4368, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_368
+	{0x436A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36A
+	{0x436C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36C
+	{0x436E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36E
+	{0x4370, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_370
+	{0x4372, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_372
+	{0x4374, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_374
+	{0x4376, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_376
+	{0x4378, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_378
+	{0x437A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_37A
+	{0x437C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_37C
+	{0x437E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_37E
+	{0x4380, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_380
+	{0x4382, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_382
+	{0x4384, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_384
+	{0x4386, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_386
+	{0x4388, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_388
+	{0x438A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38A
+	{0x438C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38C
+	{0x438E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38E
+	{0x4390, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_390
+	{0x4392, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_392
+	{0x4394, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_394
+	{0x4396, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_396
+	{0x4398, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_398
+	{0x439A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_39A
+	{0x439C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_39C
+	{0x439E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_39E
+	{0x43A0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A0
+	{0x43A2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A2
+	{0x43A4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A4
+	{0x43A6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A6
+	{0x43A8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A8
+	{0x43AA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3AA
+	{0x43AC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3AC
+	{0x43AE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3AE
+	{0x43B0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B0
+	{0x43B2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B2
+	{0x43B4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B4
+	{0x43B6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B6
+	{0x43B8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B8
+	{0x43BA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3BA
+	{0x43BC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3BC
+	{0x43BE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3BE
+	{0x43C0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C0
+	{0x43C2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C2
+	{0x43C4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C4
+	{0x43C6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C6
+	{0x43C8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C8
+	{0x43CA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3CA
+	{0x43CC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3CC
+	{0x43CE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3CE
+	{0x43D0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D0
+	{0x43D2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D2
+	{0x43D4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D4
+	{0x43D6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D6
+	{0x43D8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D8
+	{0x43DA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3DA
+	{0x43DC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3DC
+	{0x43DE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3DE
+	{0x43E0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E0
+	{0x43E2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E2
+	{0x43E4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E4
+	{0x43E6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E6
+	{0x43E8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E8
+	{0x43EA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3EA
+	{0x43EC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3EC
+	{0x43EE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3EE
+	{0x43F0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F0
+	{0x43F2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F2
+	{0x43F4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F4
+	{0x43F6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F6
+	{0x43F8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F8
+	{0x43FA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3FA
+	{0x43FC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3FC
+	{0x43FE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3FE
+	{0x4400, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_400
+	{0x4402, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_402
+	{0x4404, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_404
+	{0x4406, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_406
+	{0x4408, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_408
+	{0x440A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40A
+	{0x440C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40C
+	{0x440E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40E
+	{0x4410, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_410
+	{0x4412, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_412
+	{0x4414, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_414
+	{0x4416, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_416
+	{0x4418, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_418
+	{0x441A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_41A
+	{0x441C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_41C
+	{0x441E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_41E
+	{0x4420, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_420
+	{0x4422, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_422
+	{0x4424, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_424
+	{0x4426, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_426
+	{0x4428, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_428
+	{0x442A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42A
+	{0x442C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42C
+	{0x442E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42E
+	{0x4430, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_430
+	{0x4432, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_432
+	{0x4434, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_434
+	{0x4436, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_436
+	{0x4438, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_438
+	{0x443A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_43A
+	{0x443C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_43C
+	{0x443E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_43E
+	{0x4440, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_440
+	{0x4442, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_442
+	{0x4444, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_444
+	{0x4446, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_446
+	{0x4448, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_448
+	{0x444A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44A
+	{0x444C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44C
+	{0x444E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44E
+	{0x4450, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_450
+	{0x4452, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_452
+	{0x4454, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_454
+	{0x4456, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_456
+	{0x4458, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_458
+	{0x445A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_45A
+	{0x445C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_45C
+	{0x445E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_45E
+	{0x4460, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_460
+	{0x4462, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_462
+	{0x4464, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_464
+	{0x4466, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_466
+	{0x4468, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_468
+	{0x446A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46A
+	{0x446C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46C
+	{0x446E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46E
+	{0x4470, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_470
+	{0x4472, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_472
+	{0x4474, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_474
+	{0x4476, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_476
+	{0x4478, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_478
+	{0x447A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_47A
+	{0x447C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_47C
+	{0x447E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_47E
+	{0x4480, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_480
+	{0x4482, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_482
+	{0x4484, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_484
+	{0x4486, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_486
+	{0x4488, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_488
+	{0x448A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48A
+	{0x448C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48C
+	{0x448E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48E
+	{0x4490, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_490
+	{0x4492, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_492
+	{0x4494, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_494
+	{0x4496, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_496
+	{0x4498, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_498
+	{0x449A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_49A
+	{0x449C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_49C
+	{0x449E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_49E
+	{0x44A0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A0
+	{0x44A2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A2
+	{0x44A4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A4
+	{0x44A6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A6
+	{0x44A8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A8
+	{0x44AA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4AA
+	{0x44AC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4AC
+	{0x44AE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4AE
+	{0x44B0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4B0
+	{0x44B2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4B2
+	{0x44B4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4B4
+	{0x5500, 0x0000, AR2020_REG_VALUE_16BIT},//AGAIN_LUT0
+	{0x5502, 0x0002, AR2020_REG_VALUE_16BIT},//AGAIN_LUT1
+	{0x5504, 0x0006, AR2020_REG_VALUE_16BIT},//AGAIN_LUT2
+	{0x5506, 0x0009, AR2020_REG_VALUE_16BIT},//AGAIN_LUT3
+	{0x5508, 0x000F, AR2020_REG_VALUE_16BIT},//AGAIN_LUT4
+	{0x550A, 0x0010, AR2020_REG_VALUE_16BIT},//AGAIN_LUT5
+	{0x550C, 0x0011, AR2020_REG_VALUE_16BIT},//AGAIN_LUT6
+	{0x550E, 0x0012, AR2020_REG_VALUE_16BIT},//AGAIN_LUT7
+	{0x5510, 0x0019, AR2020_REG_VALUE_16BIT},//AGAIN_LUT8
+	{0x5512, 0x0020, AR2020_REG_VALUE_16BIT},//AGAIN_LUT9
+	{0x5514, 0x0021, AR2020_REG_VALUE_16BIT},//AGAIN_LUT10
+	{0x5516, 0x0023, AR2020_REG_VALUE_16BIT},//AGAIN_LUT11
+	{0x5518, 0x0026, AR2020_REG_VALUE_16BIT},//AGAIN_LUT12
+	{0x551A, 0x002B, AR2020_REG_VALUE_16BIT},//AGAIN_LUT13
+	{0x551C, 0x002F, AR2020_REG_VALUE_16BIT},//AGAIN_LUT14
+	{0x551E, 0x0030, AR2020_REG_VALUE_16BIT},//AGAIN_LUT15
+	{0x5430, 0x0100, AR2020_REG_VALUE_16BIT},//GT2_COARSE0
+	{0x5432, 0x00E8, AR2020_REG_VALUE_16BIT},//GT2_COARSE1
+	{0x5434, 0x0123, AR2020_REG_VALUE_16BIT},//GT2_COARSE2
+	{0x5436, 0x0108, AR2020_REG_VALUE_16BIT},//GT2_COARSE3
+	{0x5438, 0x5125, AR2020_REG_VALUE_16BIT},//GT2_COARSE4
+	{0x543A, 0x510A, AR2020_REG_VALUE_16BIT},//GT2_COARSE5
+	{0x543C, 0x9133, AR2020_REG_VALUE_16BIT},//GT2_COARSE6
+	{0x543E, 0x9117, AR2020_REG_VALUE_16BIT},//GT2_COARSE7
+	{0x5440, 0xF130, AR2020_REG_VALUE_16BIT},//GT2_COARSE8
+	{0x5442, 0xF114, AR2020_REG_VALUE_16BIT},//GT2_COARSE9
+	{0x5444, 0xF186, AR2020_REG_VALUE_16BIT},//GT2_COARSE10
+	{0x5446, 0xF227, AR2020_REG_VALUE_16BIT},//GT2_COARSE11
+	{0x5448, 0xF30A, AR2020_REG_VALUE_16BIT},//GT2_COARSE12
+	{0x544A, 0xF44B, AR2020_REG_VALUE_16BIT},//GT2_COARSE13
+	{0x544C, 0xF611, AR2020_REG_VALUE_16BIT},//GT2_COARSE14
+	{0x544E, 0xF892, AR2020_REG_VALUE_16BIT},//GT2_COARSE15
+	{0x5450, 0xFC1B, AR2020_REG_VALUE_16BIT},//GT2_COARSE16
+	{0x5452, 0xFC1B, AR2020_REG_VALUE_16BIT},//GT2_COARSE17
+	{0x5454, 0x7772, AR2020_REG_VALUE_16BIT},//GT2_DCG_ATTN_SET0
+	{0x5456, 0x5557, AR2020_REG_VALUE_16BIT},//GT2_DCG_ATTN_SET1
+	{0x5458, 0x0005, AR2020_REG_VALUE_16BIT},//GT2_DCG_ATTN_SET2
+	{0x545A, 0xA550, AR2020_REG_VALUE_16BIT},//GT2_ZONE_SET0
+	{0x545C, 0xAAAA, AR2020_REG_VALUE_16BIT},//GT2_ZONE_SET1
+	{0x545E, 0x000A, AR2020_REG_VALUE_16BIT},//GT2_ZONE_SET2
+	{0x54A0, 0x0000, AR2020_REG_VALUE_16BIT},//ZT2_REG0_ADDR
+	{0x54A2, 0x0241, AR2020_REG_VALUE_16BIT},//ZT2_REG0_VALUE0
+	{0x54A4, 0x0841, AR2020_REG_VALUE_16BIT},//ZT2_REG0_VALUE1
+	{0x54A6, 0x0A41, AR2020_REG_VALUE_16BIT},//ZT2_REG0_VALUE2
+	{0x54D8, 0x0000, AR2020_REG_VALUE_16BIT},//ZT2_REG7_ADDR
+	{0x54DA, 0x54E2, AR2020_REG_VALUE_16BIT},//ZT2_REG7_VALUE0
+	{0x54DC, 0x54E3, AR2020_REG_VALUE_16BIT},//ZT2_REG7_VALUE1
+	{0x54DE, 0x54E3, AR2020_REG_VALUE_16BIT},//ZT2_REG7_VALUE2
+	{0x3060, 0x0007, AR2020_REG_VALUE_16BIT},//GAIN_TABLE_CTRL
+	{0x44BA, 0x0050, AR2020_REG_VALUE_16BIT},//DAC_LD_4_5
+	{0x44BC, 0xBCAA, AR2020_REG_VALUE_16BIT},//DAC_LD_6_7
+	{0x44C0, 0x4070, AR2020_REG_VALUE_16BIT},//DAC_LD_10_11
+	{0x44C4, 0x04D0, AR2020_REG_VALUE_16BIT},//DAC_LD_14_15
+	{0x44C6, 0x17E2, AR2020_REG_VALUE_16BIT},//DAC_LD_16_17
+	{0x44C8, 0x5A43, AR2020_REG_VALUE_16BIT},//DAC_LD_18_19
+	{0x44CA, 0x000E, AR2020_REG_VALUE_16BIT},//DAC_LD_20_21
+	{0x44CC, 0x7777, AR2020_REG_VALUE_16BIT},//DAC_LD_22_23
+	{0x44CE, 0x8BA4, AR2020_REG_VALUE_16BIT},//DAC_LD_24_25
+	{0x44D0, 0x1735, AR2020_REG_VALUE_16BIT},//DAC_LD_26_27
+	{0x44D4, 0x8000, AR2020_REG_VALUE_16BIT},//DAC_LD_30_31
+	{0x44D6, 0xF206, AR2020_REG_VALUE_16BIT},//DAC_LD_32_33
+	{0x44D8, 0xAAFA, AR2020_REG_VALUE_16BIT},//DAC_LD_34_35
+	{0x44DA, 0xE001, AR2020_REG_VALUE_16BIT},//DAC_LD_36_37
+	{0x44DC, 0x7480, AR2020_REG_VALUE_16BIT},//DAC_LD_38_39
+	{0x44DE, 0x9BBC, AR2020_REG_VALUE_16BIT},//DAC_LD_40_41
+	{0x44E0, 0x283C, AR2020_REG_VALUE_16BIT},//DAC_LD_42_43
+	{0x44E2, 0x2821, AR2020_REG_VALUE_16BIT},//DAC_LD_44_45
+	{0x44E4, 0x8000, AR2020_REG_VALUE_16BIT},//DAC_LD_46_47
+	{0x44E6, 0x703F, AR2020_REG_VALUE_16BIT},//DAC_LD_48_49
+	{0x32A4, 0x0000, AR2020_REG_VALUE_16BIT},//CRM_CTRL
+	{0x328E, 0x0004, AR2020_REG_VALUE_16BIT},//ADDR_CTRL
+	{0x333C, 0x0001, AR2020_REG_VALUE_16BIT},//DYNAMIC_CTRL
+	{0x301A, 0x0000, AR2020_REG_VALUE_16BIT},//RESET_REGISTER
+	{0x3600, 0x94DF, AR2020_REG_VALUE_16BIT},//FDOC_CTRL
+	{0x3616, 0x0000, AR2020_REG_VALUE_16BIT},//FDOC_CTRL2
+	{0x3700, 0x0001, AR2020_REG_VALUE_16BIT},//PIX_DEF_ID
+	{0x3980, 0x0003, AR2020_REG_VALUE_16BIT},//PIX_DEF_CORR
+	{0x36C0, 0x0001, AR2020_REG_VALUE_16BIT},//DIGITAL_GAIN_CTRL
+	{0x36DE, 0x002A, AR2020_REG_VALUE_16BIT},//DATA_PEDESTAL1
+	{0x301A, 0x0008, AR2020_REG_VALUE_16BIT},//RESET_REGISTER
+	{0x4600, 0x0333, AR2020_REG_VALUE_16BIT},//LISREG_CTRL
+	{0x4602, 0x311C, AR2020_REG_VALUE_16BIT},//LISREG0_CTRL
+	{0x4604, 0x090B, AR2020_REG_VALUE_16BIT},//LISREG0_DATA0N1
+	{0x4606, 0x0009, AR2020_REG_VALUE_16BIT},//LISREG0_DATA2
+	{0x4608, 0x3206, AR2020_REG_VALUE_16BIT},//LISREG1_CTRL
+	{0x460A, 0xBCBC, AR2020_REG_VALUE_16BIT},//LISREG1_DATA0N1
+	{0x460C, 0x00BE, AR2020_REG_VALUE_16BIT},//LISREG1_DATA2
+	{0x460E, 0x3112, AR2020_REG_VALUE_16BIT},//LISREG2_CTRL
+	{0x4610, 0x5AFA, AR2020_REG_VALUE_16BIT},//LISREG2_DATA0N1
+	{0x4612, 0x005A, AR2020_REG_VALUE_16BIT},//LISREG2_DATA2
+	{0x3340, 0x0C60, AR2020_REG_VALUE_16BIT},//OTPM_CTRL
+	{0x3340, 0x1C60, AR2020_REG_VALUE_16BIT},//OTPM_CTRL
+	{0x0202, 0x079E, AR2020_REG_VALUE_16BIT},//COARSE_INTEGRATION_TIME
+	{0x0224, 0x00C3, AR2020_REG_VALUE_16BIT},//SHORT_COARSE_INTEGRATION_TIME
+	{0x0100, 0x01, AR2020_REG_VALUE_08BIT},//MODE_SELECT
+	{0x44D6, 0xB206, AR2020_REG_VALUE_16BIT},//DAC_LD_32_33
+
+	{REG_NULL, 0x00, AR2020_REG_VALUE_16BIT},
+};
+
+static const struct regval ar2020_linear_8lane_global_regs[] = {
+	{REG_DELAY, 2000, AR2020_REG_VALUE_16BIT},
+	{0x44D6, 0xF206, AR2020_REG_VALUE_16BIT},//DAC_LD_32_33
+	{0x0100, 0x00, AR2020_REG_VALUE_08BIT},//MODE_SELECT
+	{0x0304, 0x0002, AR2020_REG_VALUE_16BIT},//VT_PRE_PLL_CLK_DIV
+	{0x0306, 0x0067, AR2020_REG_VALUE_16BIT},//VT_PLL_MULTIPLIER
+	{0x0300, 0x0006, AR2020_REG_VALUE_16BIT},//VT_PIX_CLK_DIV
+	{0x0302, 0x0001, AR2020_REG_VALUE_16BIT},//VT_SYS_CLK_DIV
+	{0x030C, 0x0007, AR2020_REG_VALUE_16BIT},//OP_PRE_PLL_CLK_DIV
+	{0x030E, 0x01A4, AR2020_REG_VALUE_16BIT},//OP_PLL_MULTIPLIER
+	{0x0308, 0x0005, AR2020_REG_VALUE_16BIT},//OP_PIX_CLK_DIV
+	{0x030A, 0x0002, AR2020_REG_VALUE_16BIT},//OP_SYS_CLK_DIV
+	{0x0344, 0x0008, AR2020_REG_VALUE_16BIT},//X_ADDR_START
+	{0x0348, 0x1407, AR2020_REG_VALUE_16BIT},//X_ADDR_END
+	{0x0346, 0x0008, AR2020_REG_VALUE_16BIT},//Y_ADDR_START
+	{0x034A, 0x0F07, AR2020_REG_VALUE_16BIT},//Y_ADDR_END
+	{0x034C, 0x1400, AR2020_REG_VALUE_16BIT},//X_OUTPUT_SIZE
+	{0x034E, 0x0F00, AR2020_REG_VALUE_16BIT},//Y_OUTPUT_SIZE
+	{0x0380, 0x0001, AR2020_REG_VALUE_16BIT},//X_EVEN_INC
+	{0x0382, 0x0001, AR2020_REG_VALUE_16BIT},//X_ODD_INC
+	{0x0386, 0x0001, AR2020_REG_VALUE_16BIT},//Y_ODD_INC
+	{0x0384, 0x0001, AR2020_REG_VALUE_16BIT},//Y_EVEN_INC
+	{0x0900, 0x00, AR2020_REG_VALUE_08BIT},//BINNING_MODE
+	{0x0901, 0x11, AR2020_REG_VALUE_08BIT},//BINNING_TYPE
+	{0x0342, 0x1FC0, AR2020_REG_VALUE_16BIT},//LINE_LENGTH_PCK
+	{0x0340, 0x0F1E, AR2020_REG_VALUE_16BIT},//FRAME_LENGTH_LINES
+	{0x0202, 0x0B2D, AR2020_REG_VALUE_16BIT},//COARSE_INTEGRATION_TIME
+	{0x0112, 0x0A0A, AR2020_REG_VALUE_16BIT},//CSI_DATA_FORMAT
+	{0x0114, 0x07, AR2020_REG_VALUE_08BIT},//CSI_LANE_MODE
+	{0x0800, 0x0D, AR2020_REG_VALUE_08BIT},//TCLK_POST
+	{0x0801, 0x07, AR2020_REG_VALUE_08BIT},//THS_PREPARE
+	{0x0802, 0x0C, AR2020_REG_VALUE_08BIT},//THS_ZERO_MIN
+	{0x0803, 0x09, AR2020_REG_VALUE_08BIT},//THS_TRAIL
+	{0x0804, 0x0B, AR2020_REG_VALUE_08BIT},//TCLK_TRAIL_MIN
+	{0x0805, 0x06, AR2020_REG_VALUE_08BIT},//TCLK_PREPARE
+	{0x0806, 0x24, AR2020_REG_VALUE_08BIT},//TCLK_ZERO
+	{0x0807, 0x07, AR2020_REG_VALUE_08BIT},//TLPX
+	{0x082A, 0x0F, AR2020_REG_VALUE_08BIT},//TWAKEUP
+	{0x082B, 0x0C, AR2020_REG_VALUE_08BIT},//TINIT
+	{0x082C, 0x0D, AR2020_REG_VALUE_08BIT},//THS_EXIT
+	{0x3F06, 0x00C0, AR2020_REG_VALUE_16BIT},//MIPI_TIMING_2
+	{0x3F0A, 0xA000, AR2020_REG_VALUE_16BIT},//MIPI_TIMING_4
+	{0x3F0C, 0x000A, AR2020_REG_VALUE_16BIT},//MIPI_TIMING_5
+	{0x3F20, 0x8080, AR2020_REG_VALUE_16BIT},//MIPI_PHY_TRIM_MSB
+	{0x3F1E, 0x0004, AR2020_REG_VALUE_16BIT},//MIPI_PHY_TRIM_LSB
+	{0x3F22, 0x3806, AR2020_REG_VALUE_16BIT},// MIPI_8LANE_CONTROL
+	{0x4000, 0x0114, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_00
+	{0x4002, 0x1A25, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_02
+	{0x4004, 0x3DFF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_04
+	{0x4006, 0xFFFF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_06
+	{0x4008, 0x0A35, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_08
+	{0x400A, 0x10EF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_0A
+	{0x400C, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_0C
+	{0x400E, 0x30D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_0E
+	{0x4010, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10
+	{0x4012, 0xB5F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12
+	{0x4014, 0x0085, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14
+	{0x4016, 0xF004, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16
+	{0x4018, 0x9A89, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18
+	{0x401A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A
+	{0x401C, 0x9997, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C
+	{0x401E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E
+	{0x4020, 0x30C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20
+	{0x4022, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22
+	{0x4024, 0x82F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24
+	{0x4026, 0x0030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26
+	{0x4028, 0x18F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28
+	{0x402A, 0x0320, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A
+	{0x402C, 0x58F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C
+	{0x402E, 0x089C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E
+	{0x4030, 0xF010, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30
+	{0x4032, 0x99B6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32
+	{0x4034, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34
+	{0x4036, 0xB498, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36
+	{0x4038, 0xA096, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38
+	{0x403A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A
+	{0x403C, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C
+	{0x403E, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E
+	{0x4040, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40
+	{0x4042, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42
+	{0x4044, 0x209D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44
+	{0x4046, 0x8C08, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46
+	{0x4048, 0x08F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48
+	{0x404A, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A
+	{0x404C, 0x008F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4C
+	{0x404E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4E
+	{0x4050, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_50
+	{0x4052, 0x0488, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_52
+	{0x4054, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_54
+	{0x4056, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_56
+	{0x4058, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_58
+	{0x405A, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_5A
+	{0x405C, 0x0290, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_5C
+	{0x405E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_5E
+	{0x4060, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_60
+	{0x4062, 0x2EA3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_62
+	{0x4064, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_64
+	{0x4066, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_66
+	{0x4068, 0x089D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_68
+	{0x406A, 0xF075, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_6A
+	{0x406C, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_6C
+	{0x406E, 0x4070, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_6E
+	{0x4070, 0x216D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_70
+	{0x4072, 0x1CF6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_72
+	{0x4074, 0x8B00, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_74
+	{0x4076, 0x5186, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_76
+	{0x4078, 0x1300, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_78
+	{0x407A, 0x0205, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_7A
+	{0x407C, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_7C
+	{0x407E, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_7E
+	{0x4080, 0x8387, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_80
+	{0x4082, 0xF006, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_82
+	{0x4084, 0x8702, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_84
+	{0x4086, 0x0D02, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_86
+	{0x4088, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_88
+	{0x408A, 0x0383, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_8A
+	{0x408C, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_8C
+	{0x408E, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_8E
+	{0x4090, 0x0213, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_90
+	{0x4092, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_92
+	{0x4094, 0xD887, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_94
+	{0x4096, 0x020D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_96
+	{0x4098, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_98
+	{0x409A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_9A
+	{0x409C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_9C
+	{0x409E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_9E
+	{0x40A0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A0
+	{0x40A2, 0x0401, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A2
+	{0x40A4, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A4
+	{0x40A6, 0x82F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A6
+	{0x40A8, 0x0883, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A8
+	{0x40AA, 0xF009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_AA
+	{0x40AC, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_AC
+	{0x40AE, 0x2985, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_AE
+	{0x40B0, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B0
+	{0x40B2, 0x2A87, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B2
+	{0x40B4, 0xF63E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B4
+	{0x40B6, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B6
+	{0x40B8, 0x0801, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B8
+	{0x40BA, 0x40F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_BA
+	{0x40BC, 0x0800, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_BC
+	{0x40BE, 0x48F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_BE
+	{0x40C0, 0x0882, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C0
+	{0x40C2, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C2
+	{0x40C4, 0x0401, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C4
+	{0x40C6, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C6
+	{0x40C8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C8
+	{0x40CA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_CA
+	{0x40CC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_CC
+	{0x40CE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_CE
+	{0x40D0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D0
+	{0x40D2, 0x0401, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D2
+	{0x40D4, 0xF015, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D4
+	{0x40D6, 0x002C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D6
+	{0x40D8, 0xF00E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D8
+	{0x40DA, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_DA
+	{0x40DC, 0x0687, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_DC
+	{0x40DE, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_DE
+	{0x40E0, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E0
+	{0x40E2, 0x61E8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E2
+	{0x40E4, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E4
+	{0x40E6, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E6
+	{0x40E8, 0x3480, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E8
+	{0x40EA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_EA
+	{0x40EC, 0x3240, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_EC
+	{0x40EE, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_EE
+	{0x40F0, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F0
+	{0x40F2, 0xF00E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F2
+	{0x40F4, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F4
+	{0x40F6, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F6
+	{0x40F8, 0x3240, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F8
+	{0x40FA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_FA
+	{0x40FC, 0x3480, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_FC
+	{0x40FE, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_FE
+	{0x4100, 0xC0E6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_100
+	{0x4102, 0xF004, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_102
+	{0x4104, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_104
+	{0x4106, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_106
+	{0x4108, 0xB0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_108
+	{0x410A, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10A
+	{0x410C, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10C
+	{0x410E, 0x86F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10E
+	{0x4110, 0x0086, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_110
+	{0x4112, 0xF089, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_112
+	{0x4114, 0xB0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_114
+	{0x4116, 0x00E9, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_116
+	{0x4118, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_118
+	{0x411A, 0x8AF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_11A
+	{0x411C, 0x0000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_11C
+	{0x411E, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_11E
+	{0x4120, 0x00E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_120
+	{0x4122, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_122
+	{0x4124, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_124
+	{0x4126, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_126
+	{0x4128, 0x0A35, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_128
+	{0x412A, 0x10EF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12A
+	{0x412C, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12C
+	{0x412E, 0x30D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12E
+	{0x4130, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_130
+	{0x4132, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_132
+	{0x4134, 0x049A, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_134
+	{0x4136, 0x89F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_136
+	{0x4138, 0x0099, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_138
+	{0x413A, 0x97F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_13A
+	{0x413C, 0x0030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_13C
+	{0x413E, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_13E
+	{0x4140, 0x0082, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_140
+	{0x4142, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_142
+	{0x4144, 0x3018, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_144
+	{0x4146, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_146
+	{0x4148, 0xB520, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_148
+	{0x414A, 0x58F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14A
+	{0x414C, 0x089C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14C
+	{0x414E, 0xF010, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14E
+	{0x4150, 0x99B6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_150
+	{0x4152, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_152
+	{0x4154, 0xB498, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_154
+	{0x4156, 0xA096, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_156
+	{0x4158, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_158
+	{0x415A, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_15A
+	{0x415C, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_15C
+	{0x415E, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_15E
+	{0x4160, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_160
+	{0x4162, 0x209D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_162
+	{0x4164, 0x8C08, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_164
+	{0x4166, 0x08F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_166
+	{0x4168, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_168
+	{0x416A, 0x008F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16A
+	{0x416C, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16C
+	{0x416E, 0x0188, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16E
+	{0x4170, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_170
+	{0x4172, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_172
+	{0x4174, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_174
+	{0x4176, 0x0290, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_176
+	{0x4178, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_178
+	{0x417A, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_17A
+	{0x417C, 0x2DA3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_17C
+	{0x417E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_17E
+	{0x4180, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_180
+	{0x4182, 0x089D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_182
+	{0x4184, 0xF06D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_184
+	{0x4186, 0x4070, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_186
+	{0x4188, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_188
+	{0x418A, 0x214D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18A
+	{0x418C, 0x1FF6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18C
+	{0x418E, 0x0851, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18E
+	{0x4190, 0x0245, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_190
+	{0x4192, 0x9D36, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_192
+	{0x4194, 0xD8F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_194
+	{0x4196, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_196
+	{0x4198, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_198
+	{0x419A, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_19A
+	{0x419C, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_19C
+	{0x419E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_19E
+	{0x41A0, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A0
+	{0x41A2, 0x020D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A2
+	{0x41A4, 0x0205, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A4
+	{0x41A6, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A6
+	{0x41A8, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A8
+	{0x41AA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1AA
+	{0x41AC, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1AC
+	{0x41AE, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1AE
+	{0x41B0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B0
+	{0x41B2, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B2
+	{0x41B4, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B4
+	{0x41B6, 0xD802, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B6
+	{0x41B8, 0x0D02, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B8
+	{0x41BA, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1BA
+	{0x41BC, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1BC
+	{0x41BE, 0xD8F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1BE
+	{0x41C0, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C0
+	{0x41C2, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C2
+	{0x41C4, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C4
+	{0x41C6, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C6
+	{0x41C8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C8
+	{0x41CA, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1CA
+	{0x41CC, 0x020D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1CC
+	{0x41CE, 0x0205, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1CE
+	{0x41D0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D0
+	{0x41D2, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D2
+	{0x41D4, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D4
+	{0x41D6, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D6
+	{0x41D8, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D8
+	{0x41DA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1DA
+	{0x41DC, 0x8713, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1DC
+	{0x41DE, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1DE
+	{0x41E0, 0xD802, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E0
+	{0x41E2, 0x0DE0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E2
+	{0x41E4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E4
+	{0x41E6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E6
+	{0x41E8, 0x9F13, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E8
+	{0x41EA, 0x0041, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1EA
+	{0x41EC, 0x80F3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1EC
+	{0x41EE, 0xF213, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1EE
+	{0x41F0, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F0
+	{0x41F2, 0x13B8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F2
+	{0x41F4, 0xF04C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F4
+	{0x41F6, 0x9FF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F6
+	{0x41F8, 0x00B7, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F8
+	{0x41FA, 0xF006, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1FA
+	{0x41FC, 0x0035, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1FC
+	{0x41FE, 0x10AF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1FE
+	{0x4200, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_200
+	{0x4202, 0x30C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_202
+	{0x4204, 0xB2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_204
+	{0x4206, 0x01B5, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_206
+	{0x4208, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_208
+	{0x420A, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20A
+	{0x420C, 0x0292, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20C
+	{0x420E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20E
+	{0x4210, 0x9A8B, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_210
+	{0x4212, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_212
+	{0x4214, 0x9997, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_214
+	{0x4216, 0xF007, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_216
+	{0x4218, 0xB6F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_218
+	{0x421A, 0x0020, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_21A
+	{0x421C, 0x5830, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_21C
+	{0x421E, 0xC040, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_21E
+	{0x4220, 0x1282, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_220
+	{0x4222, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_222
+	{0x4224, 0x9CF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_224
+	{0x4226, 0x01B2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_226
+	{0x4228, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_228
+	{0x422A, 0xB8F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22A
+	{0x422C, 0x0799, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22C
+	{0x422E, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22E
+	{0x4230, 0x98F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_230
+	{0x4232, 0x0296, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_232
+	{0x4234, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_234
+	{0x4236, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_236
+	{0x4238, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_238
+	{0x423A, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_23A
+	{0x423C, 0x02A1, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_23C
+	{0x423E, 0xF01F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_23E
+	{0x4240, 0x1009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_240
+	{0x4242, 0x2220, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_242
+	{0x4244, 0x0808, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_244
+	{0x4246, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_246
+	{0x4248, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_248
+	{0x424A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24A
+	{0x424C, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24C
+	{0x424E, 0x0788, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24E
+	{0x4250, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_250
+	{0x4252, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_252
+	{0x4254, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_254
+	{0x4256, 0x0290, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_256
+	{0x4258, 0xF016, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_258
+	{0x425A, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_25A
+	{0x425C, 0x11A3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_25C
+	{0x425E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_25E
+	{0x4260, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_260
+	{0x4262, 0x089D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_262
+	{0x4264, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_264
+	{0x4266, 0xA1F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_266
+	{0x4268, 0x20A1, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_268
+	{0x426A, 0xF006, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26A
+	{0x426C, 0x4300, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26C
+	{0x426E, 0xF049, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26E
+	{0x4270, 0x4014, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_270
+	{0x4272, 0x8B8E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_272
+	{0x4274, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_274
+	{0x4276, 0x0802, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_276
+	{0x4278, 0x02F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_278
+	{0x427A, 0x00A6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_27A
+	{0x427C, 0xF013, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_27C
+	{0x427E, 0xB283, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_27E
+	{0x4280, 0x9C36, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_280
+	{0x4282, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_282
+	{0x4284, 0x0636, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_284
+	{0x4286, 0x009C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_286
+	{0x4288, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_288
+	{0x428A, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28A
+	{0x428C, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28C
+	{0x428E, 0xA0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28E
+	{0x4290, 0x0630, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_290
+	{0x4292, 0x18F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_292
+	{0x4294, 0x02A3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_294
+	{0x4296, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_296
+	{0x4298, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_298
+	{0x429A, 0x0243, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_29A
+	{0x429C, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_29C
+	{0x429E, 0x049D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_29E
+	{0x42A0, 0xF078, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A0
+	{0x42A2, 0x3018, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A2
+	{0x42A4, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A4
+	{0x42A6, 0x9D82, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A6
+	{0x42A8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A8
+	{0x42AA, 0x9030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2AA
+	{0x42AC, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2AC
+	{0x42AE, 0x1130, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2AE
+	{0x42B0, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B0
+	{0x42B2, 0x0082, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B2
+	{0x42B4, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B4
+	{0x42B6, 0x1009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B6
+	{0x42B8, 0xF02A, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B8
+	{0x42BA, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2BA
+	{0x42BC, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2BC
+	{0x42BE, 0x3018, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2BE
+	{0x42C0, 0xF007, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C0
+	{0x42C2, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C2
+	{0x42C4, 0x1C8C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C4
+	{0x42C6, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C6
+	{0x42C8, 0x301F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C8
+	{0x42CA, 0x216D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2CA
+	{0x42CC, 0x0A51, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2CC
+	{0x42CE, 0x1FEA, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2CE
+	{0x42D0, 0x8640, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D0
+	{0x42D2, 0xE29F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D2
+	{0x42D4, 0xF009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D4
+	{0x42D6, 0x0005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D6
+	{0x42D8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D8
+	{0x42DA, 0x30C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2DA
+	{0x42DC, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2DC
+	{0x42DE, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2DE
+	{0x42E0, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E0
+	{0x42E2, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E2
+	{0x42E4, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E4
+	{0x42E6, 0xF007, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E6
+	{0x42E8, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E8
+	{0x42EA, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2EA
+	{0x42EC, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2EC
+	{0x42EE, 0x0000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2EE
+	{0x42F0, 0x0DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F0
+	{0x42F2, 0x0000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F2
+	{0x42F4, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F4
+	{0x42F6, 0x0030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F6
+	{0x42F8, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F8
+	{0x42FA, 0x0183, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2FA
+	{0x42FC, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2FC
+	{0x42FE, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2FE
+	{0x4300, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_300
+	{0x4302, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_302
+	{0x4304, 0x0787, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_304
+	{0x4306, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_306
+	{0x4308, 0x36C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_308
+	{0x430A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30A
+	{0x430C, 0x000F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30C
+	{0x430E, 0xF42A, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30E
+	{0x4310, 0x4180, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_310
+	{0x4312, 0x1300, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_312
+	{0x4314, 0x9FF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_314
+	{0x4316, 0x00E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_316
+	{0x4318, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_318
+	{0x431A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_31A
+	{0x431C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_31C
+	{0x431E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_31E
+	{0x4320, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_320
+	{0x4322, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_322
+	{0x4324, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_324
+	{0x4326, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_326
+	{0x4328, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_328
+	{0x432A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32A
+	{0x432C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32C
+	{0x432E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32E
+	{0x4330, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_330
+	{0x4332, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_332
+	{0x4334, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_334
+	{0x4336, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_336
+	{0x4338, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_338
+	{0x433A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_33A
+	{0x433C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_33C
+	{0x433E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_33E
+	{0x4340, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_340
+	{0x4342, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_342
+	{0x4344, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_344
+	{0x4346, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_346
+	{0x4348, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_348
+	{0x434A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34A
+	{0x434C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34C
+	{0x434E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34E
+	{0x4350, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_350
+	{0x4352, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_352
+	{0x4354, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_354
+	{0x4356, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_356
+	{0x4358, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_358
+	{0x435A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_35A
+	{0x435C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_35C
+	{0x435E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_35E
+	{0x4360, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_360
+	{0x4362, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_362
+	{0x4364, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_364
+	{0x4366, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_366
+	{0x4368, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_368
+	{0x436A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36A
+	{0x436C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36C
+	{0x436E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36E
+	{0x4370, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_370
+	{0x4372, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_372
+	{0x4374, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_374
+	{0x4376, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_376
+	{0x4378, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_378
+	{0x437A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_37A
+	{0x437C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_37C
+	{0x437E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_37E
+	{0x4380, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_380
+	{0x4382, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_382
+	{0x4384, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_384
+	{0x4386, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_386
+	{0x4388, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_388
+	{0x438A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38A
+	{0x438C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38C
+	{0x438E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38E
+	{0x4390, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_390
+	{0x4392, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_392
+	{0x4394, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_394
+	{0x4396, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_396
+	{0x4398, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_398
+	{0x439A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_39A
+	{0x439C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_39C
+	{0x439E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_39E
+	{0x43A0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A0
+	{0x43A2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A2
+	{0x43A4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A4
+	{0x43A6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A6
+	{0x43A8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A8
+	{0x43AA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3AA
+	{0x43AC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3AC
+	{0x43AE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3AE
+	{0x43B0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B0
+	{0x43B2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B2
+	{0x43B4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B4
+	{0x43B6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B6
+	{0x43B8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B8
+	{0x43BA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3BA
+	{0x43BC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3BC
+	{0x43BE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3BE
+	{0x43C0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C0
+	{0x43C2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C2
+	{0x43C4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C4
+	{0x43C6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C6
+	{0x43C8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C8
+	{0x43CA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3CA
+	{0x43CC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3CC
+	{0x43CE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3CE
+	{0x43D0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D0
+	{0x43D2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D2
+	{0x43D4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D4
+	{0x43D6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D6
+	{0x43D8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D8
+	{0x43DA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3DA
+	{0x43DC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3DC
+	{0x43DE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3DE
+	{0x43E0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E0
+	{0x43E2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E2
+	{0x43E4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E4
+	{0x43E6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E6
+	{0x43E8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E8
+	{0x43EA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3EA
+	{0x43EC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3EC
+	{0x43EE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3EE
+	{0x43F0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F0
+	{0x43F2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F2
+	{0x43F4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F4
+	{0x43F6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F6
+	{0x43F8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F8
+	{0x43FA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3FA
+	{0x43FC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3FC
+	{0x43FE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3FE
+	{0x4400, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_400
+	{0x4402, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_402
+	{0x4404, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_404
+	{0x4406, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_406
+	{0x4408, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_408
+	{0x440A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40A
+	{0x440C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40C
+	{0x440E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40E
+	{0x4410, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_410
+	{0x4412, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_412
+	{0x4414, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_414
+	{0x4416, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_416
+	{0x4418, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_418
+	{0x441A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_41A
+	{0x441C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_41C
+	{0x441E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_41E
+	{0x4420, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_420
+	{0x4422, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_422
+	{0x4424, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_424
+	{0x4426, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_426
+	{0x4428, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_428
+	{0x442A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42A
+	{0x442C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42C
+	{0x442E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42E
+	{0x4430, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_430
+	{0x4432, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_432
+	{0x4434, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_434
+	{0x4436, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_436
+	{0x4438, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_438
+	{0x443A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_43A
+	{0x443C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_43C
+	{0x443E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_43E
+	{0x4440, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_440
+	{0x4442, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_442
+	{0x4444, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_444
+	{0x4446, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_446
+	{0x4448, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_448
+	{0x444A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44A
+	{0x444C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44C
+	{0x444E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44E
+	{0x4450, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_450
+	{0x4452, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_452
+	{0x4454, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_454
+	{0x4456, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_456
+	{0x4458, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_458
+	{0x445A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_45A
+	{0x445C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_45C
+	{0x445E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_45E
+	{0x4460, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_460
+	{0x4462, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_462
+	{0x4464, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_464
+	{0x4466, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_466
+	{0x4468, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_468
+	{0x446A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46A
+	{0x446C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46C
+	{0x446E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46E
+	{0x4470, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_470
+	{0x4472, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_472
+	{0x4474, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_474
+	{0x4476, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_476
+	{0x4478, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_478
+	{0x447A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_47A
+	{0x447C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_47C
+	{0x447E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_47E
+	{0x4480, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_480
+	{0x4482, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_482
+	{0x4484, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_484
+	{0x4486, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_486
+	{0x4488, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_488
+	{0x448A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48A
+	{0x448C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48C
+	{0x448E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48E
+	{0x4490, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_490
+	{0x4492, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_492
+	{0x4494, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_494
+	{0x4496, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_496
+	{0x4498, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_498
+	{0x449A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_49A
+	{0x449C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_49C
+	{0x449E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_49E
+	{0x44A0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A0
+	{0x44A2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A2
+	{0x44A4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A4
+	{0x44A6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A6
+	{0x44A8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A8
+	{0x44AA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4AA
+	{0x44AC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4AC
+	{0x44AE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4AE
+	{0x44B0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4B0
+	{0x44B2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4B2
+	{0x44B4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4B4
+	{0x5500, 0x0000, AR2020_REG_VALUE_16BIT},//AGAIN_LUT0
+	{0x5502, 0x0002, AR2020_REG_VALUE_16BIT},//AGAIN_LUT1
+	{0x5504, 0x0006, AR2020_REG_VALUE_16BIT},//AGAIN_LUT2
+	{0x5506, 0x0009, AR2020_REG_VALUE_16BIT},//AGAIN_LUT3
+	{0x5508, 0x000F, AR2020_REG_VALUE_16BIT},//AGAIN_LUT4
+	{0x550A, 0x0010, AR2020_REG_VALUE_16BIT},//AGAIN_LUT5
+	{0x550C, 0x0011, AR2020_REG_VALUE_16BIT},//AGAIN_LUT6
+	{0x550E, 0x0012, AR2020_REG_VALUE_16BIT},//AGAIN_LUT7
+	{0x5510, 0x0019, AR2020_REG_VALUE_16BIT},//AGAIN_LUT8
+	{0x5512, 0x0020, AR2020_REG_VALUE_16BIT},//AGAIN_LUT9
+	{0x5514, 0x0021, AR2020_REG_VALUE_16BIT},//AGAIN_LUT10
+	{0x5516, 0x0023, AR2020_REG_VALUE_16BIT},//AGAIN_LUT11
+	{0x5518, 0x0026, AR2020_REG_VALUE_16BIT},//AGAIN_LUT12
+	{0x551A, 0x002B, AR2020_REG_VALUE_16BIT},//AGAIN_LUT13
+	{0x551C, 0x002F, AR2020_REG_VALUE_16BIT},//AGAIN_LUT14
+	{0x551E, 0x0030, AR2020_REG_VALUE_16BIT},//AGAIN_LUT15
+	{0x5400, 0x0100, AR2020_REG_VALUE_16BIT},//GT1_COARSE0
+	{0x5402, 0x2106, AR2020_REG_VALUE_16BIT},//GT1_COARSE1
+	{0x5404, 0x1101, AR2020_REG_VALUE_16BIT},//GT1_COARSE2
+	{0x5406, 0x3106, AR2020_REG_VALUE_16BIT},//GT1_COARSE3
+	{0x5408, 0x7100, AR2020_REG_VALUE_16BIT},//GT1_COARSE4
+	{0x540A, 0x8107, AR2020_REG_VALUE_16BIT},//GT1_COARSE5
+	{0x540C, 0xB101, AR2020_REG_VALUE_16BIT},//GT1_COARSE6
+	{0x540E, 0xD101, AR2020_REG_VALUE_16BIT},//GT1_COARSE7
+	{0x5410, 0xF12E, AR2020_REG_VALUE_16BIT},//GT1_COARSE8
+	{0x5412, 0xF112, AR2020_REG_VALUE_16BIT},//GT1_COARSE9
+	{0x5414, 0xF184, AR2020_REG_VALUE_16BIT},//GT1_COARSE10
+	{0x5416, 0xF224, AR2020_REG_VALUE_16BIT},//GT1_COARSE11
+	{0x5418, 0xF306, AR2020_REG_VALUE_16BIT},//GT1_COARSE12
+	{0x541A, 0xF446, AR2020_REG_VALUE_16BIT},//GT1_COARSE13
+	{0x541C, 0xF609, AR2020_REG_VALUE_16BIT},//GT1_COARSE14
+	{0x541E, 0xF887, AR2020_REG_VALUE_16BIT},//GT1_COARSE15
+	{0x5420, 0xFC0B, AR2020_REG_VALUE_16BIT},//GT1_COARSE16
+	{0x5422, 0xFC0B, AR2020_REG_VALUE_16BIT},//GT1_COARSE17
+	{0x5424, 0xFFFA, AR2020_REG_VALUE_16BIT},//GT1_DCG_ATTN_SET0
+	{0x5426, 0x5557, AR2020_REG_VALUE_16BIT},//GT1_DCG_ATTN_SET1
+	{0x5428, 0x0005, AR2020_REG_VALUE_16BIT},//GT1_DCG_ATTN_SET2
+	{0x542A, 0xA550, AR2020_REG_VALUE_16BIT},//GT1_ZONE_SET0
+	{0x542C, 0xAAAA, AR2020_REG_VALUE_16BIT},//GT1_ZONE_SET1
+	{0x542E, 0x000A, AR2020_REG_VALUE_16BIT},//GT1_ZONE_SET2
+	{0x5460, 0x2269, AR2020_REG_VALUE_16BIT},//ZT1_REG0_ADDR
+	{0x5462, 0x0B87, AR2020_REG_VALUE_16BIT},//ZT1_REG0_VALUE0
+	{0x5464, 0x0B87, AR2020_REG_VALUE_16BIT},//ZT1_REG0_VALUE1
+	{0x5466, 0x0983, AR2020_REG_VALUE_16BIT},//ZT1_REG0_VALUE2
+	{0x5498, 0x225E, AR2020_REG_VALUE_16BIT},//ZT1_REG7_ADDR
+	{0x549A, 0xBCAA, AR2020_REG_VALUE_16BIT},//ZT1_REG7_VALUE0
+	{0x549C, 0xBCAA, AR2020_REG_VALUE_16BIT},//ZT1_REG7_VALUE1
+	{0x549E, 0xBDAA, AR2020_REG_VALUE_16BIT},//ZT1_REG7_VALUE2
+	{0x3060, 0xFF01, AR2020_REG_VALUE_16BIT},//GAIN_TABLE_CTRL
+	{0x44BA, 0x0050, AR2020_REG_VALUE_16BIT},//DAC_LD_4_5
+	{0x44BC, 0xBCAA, AR2020_REG_VALUE_16BIT},//DAC_LD_6_7
+	{0x44C0, 0x4070, AR2020_REG_VALUE_16BIT},//DAC_LD_10_11
+	{0x44C4, 0x04D0, AR2020_REG_VALUE_16BIT},//DAC_LD_14_15
+	{0x44C6, 0x17E2, AR2020_REG_VALUE_16BIT},//DAC_LD_16_17
+	{0x44C8, 0xEA43, AR2020_REG_VALUE_16BIT},//DAC_LD_18_19
+	{0x44CA, 0x000E, AR2020_REG_VALUE_16BIT},//DAC_LD_20_21
+	{0x44CC, 0x7777, AR2020_REG_VALUE_16BIT},//DAC_LD_22_23
+	{0x44CE, 0x8BA4, AR2020_REG_VALUE_16BIT},//DAC_LD_24_25
+	{0x44D0, 0x1735, AR2020_REG_VALUE_16BIT},//DAC_LD_26_27
+	{0x44D2, 0x0B87, AR2020_REG_VALUE_16BIT},//DAC_LD_28_29
+	{0x44D4, 0x0000, AR2020_REG_VALUE_16BIT},//DAC_LD_30_31
+	{0x44D6, 0xF206, AR2020_REG_VALUE_16BIT},//DAC_LD_32_33
+	{0x44D8, 0xAAFA, AR2020_REG_VALUE_16BIT},//DAC_LD_34_35
+	{0x44DA, 0xE001, AR2020_REG_VALUE_16BIT},//DAC_LD_36_37
+	{0x44DE, 0x9BBC, AR2020_REG_VALUE_16BIT},//DAC_LD_40_41
+	{0x44E0, 0x283C, AR2020_REG_VALUE_16BIT},//DAC_LD_42_43
+	{0x44E2, 0x2821, AR2020_REG_VALUE_16BIT},//DAC_LD_44_45
+	{0x44E4, 0x8000, AR2020_REG_VALUE_16BIT},//DAC_LD_46_47
+	{0x44E6, 0x503F, AR2020_REG_VALUE_16BIT},//DAC_LD_48_49
+	{0x32A4, 0x0000, AR2020_REG_VALUE_16BIT},//CRM_CTRL
+	{0x328E, 0x0004, AR2020_REG_VALUE_16BIT},//ADDR_CTRL
+	{0x333C, 0x0001, AR2020_REG_VALUE_16BIT},//DYNAMIC_CTRL
+	{0x301A, 0x0000, AR2020_REG_VALUE_16BIT},//RESET_REGISTER
+	{0x3600, 0x94DF, AR2020_REG_VALUE_16BIT},//FDOC_CTRL
+	{0x3616, 0x0000, AR2020_REG_VALUE_16BIT},//FDOC_CTRL2
+	{0x3700, 0x0001, AR2020_REG_VALUE_16BIT},//PIX_DEF_ID
+	{0x3980, 0x0003, AR2020_REG_VALUE_16BIT},//PIX_DEF_CORR
+	{0x36C0, 0x0001, AR2020_REG_VALUE_16BIT},//DIGITAL_GAIN_CTRL
+	{0x36DE, 0x002A, AR2020_REG_VALUE_16BIT},//DATA_PEDESTAL1
+	{0x301A, 0x0008, AR2020_REG_VALUE_16BIT},//RESET_REGISTER
+	{0x3060, 0x0000, AR2020_REG_VALUE_16BIT},//GAIN_TABLE_CTRL
+	{0x3982, 0xAC70, AR2020_REG_VALUE_16BIT},//PDC_DYN_EDGE_THRES
+	{0x3984, 0xFA98, AR2020_REG_VALUE_16BIT},//PDC_DYN_LO_DEFECT_THRES
+	{0x3986, 0xFC3F, AR2020_REG_VALUE_16BIT},//PDC_DYN_HI_DEFECT_THRES
+	{0x3988, 0xAC70, AR2020_REG_VALUE_16BIT},//PDC_DYN_EDGE_THRES_T2
+	{0x398A, 0xFA98, AR2020_REG_VALUE_16BIT},//PDC_DYN_LO_DEFECT_THRES_T2
+	{0x398C, 0xFC3F, AR2020_REG_VALUE_16BIT},//PDC_DYN_HI_DEFECT_THRES_T2
+	{0x3980, 0x0003, AR2020_REG_VALUE_16BIT},//PIX_DEF_CORR
+	{0x3060, 0xFF01, AR2020_REG_VALUE_16BIT},//GAIN_TABLE_CTRL
+	{0x3340, 0x0C60, AR2020_REG_VALUE_16BIT},//OTPM_CTRL
+	{0x3340, 0x1C60, AR2020_REG_VALUE_16BIT},//OTPM_CTRL
+	{0x0101,  0x01, AR2020_REG_VALUE_08BIT},//Bing added, this is for H mirror FLIP.
+	{0x0100, 0x01, AR2020_REG_VALUE_08BIT},//MODE_SELECT
+	{0x44D6, 0xB206, AR2020_REG_VALUE_16BIT},//DAC_LD_32_33
+
+	{REG_NULL, 0x00, AR2020_REG_VALUE_16BIT},
+};
+
+static const struct regval ar2020_linear_5120x3840_30fps_regs[] = {
+	{REG_DELAY, 2000, AR2020_REG_VALUE_16BIT},
+	{0x44D6, 0xF206, AR2020_REG_VALUE_16BIT},//DAC_LD_32_33
+	{0x0100, 0x00, AR2020_REG_VALUE_08BIT},//MODE_SELECT
+	{0x0304, 0x0002, AR2020_REG_VALUE_16BIT},//VT_PRE_PLL_CLK_DIV
+	{0x0306, 0x0067, AR2020_REG_VALUE_16BIT},//VT_PLL_MULTIPLIER
+	{0x0300, 0x0006, AR2020_REG_VALUE_16BIT},//VT_PIX_CLK_DIV
+	{0x0302, 0x0001, AR2020_REG_VALUE_16BIT},//VT_SYS_CLK_DIV
+	{0x030C, 0x0007, AR2020_REG_VALUE_16BIT},//OP_PRE_PLL_CLK_DIV
+	{0x030E, 0x0258, AR2020_REG_VALUE_16BIT},//OP_PLL_MULTIPLIER
+	{0x0308, 0x0005, AR2020_REG_VALUE_16BIT},//OP_PIX_CLK_DIV
+	{0x030A, 0x0002, AR2020_REG_VALUE_16BIT},//OP_SYS_CLK_DIV
+	{0x0344, 0x0008, AR2020_REG_VALUE_16BIT},//X_ADDR_START
+	{0x0348, 0x1407, AR2020_REG_VALUE_16BIT},//X_ADDR_END
+	{0x0346, 0x0008, AR2020_REG_VALUE_16BIT},//Y_ADDR_START
+	{0x034A, 0x0F07, AR2020_REG_VALUE_16BIT},//Y_ADDR_END
+	{0x034C, 0x1400, AR2020_REG_VALUE_16BIT},//X_OUTPUT_SIZE
+	{0x034E, 0x0F00, AR2020_REG_VALUE_16BIT},//Y_OUTPUT_SIZE
+	{0x0380, 0x0001, AR2020_REG_VALUE_16BIT},//X_EVEN_INC
+	{0x0382, 0x0001, AR2020_REG_VALUE_16BIT},//X_ODD_INC
+	{0x0384, 0x0001, AR2020_REG_VALUE_16BIT},//Y_EVEN_INC
+	{0x0386, 0x0001, AR2020_REG_VALUE_16BIT},//Y_ODD_INC
+	{0x0900, 0x00, AR2020_REG_VALUE_08BIT},//BINNING_MODE
+	{0x0901, 0x11, AR2020_REG_VALUE_08BIT},//BINNING_TYPE
+	{0x0342, 0x2DF0, AR2020_REG_VALUE_16BIT},//LINE_LENGTH_PCK
+	{0x0340, 0x0F28, AR2020_REG_VALUE_16BIT},//FRAME_LENGTH_LINES
+	{0x0202, 0x0F34, AR2020_REG_VALUE_16BIT},//COARSE_INTEGRATION_TIME
+	{0x0112, 0x0A0A, AR2020_REG_VALUE_16BIT},//CSI_DATA_FORMAT
+	{0x0114, 0x03, AR2020_REG_VALUE_08BIT},//CSI_LANE_MODE
+	{0x0800, 0x10, AR2020_REG_VALUE_08BIT},//TCLK_POST
+	{0x0801, 0x09, AR2020_REG_VALUE_08BIT},//THS_PREPARE
+	{0x0802, 0x11, AR2020_REG_VALUE_08BIT},//THS_ZERO_MIN
+	{0x0803, 0x0C, AR2020_REG_VALUE_08BIT},//THS_TRAIL
+	{0x0804, 0x0F, AR2020_REG_VALUE_08BIT},//TCLK_TRAIL_MIN
+	{0x0805, 0x08, AR2020_REG_VALUE_08BIT},//TCLK_PREPARE
+	{0x0806, 0x34, AR2020_REG_VALUE_08BIT},//TCLK_ZERO
+	{0x0807, 0x0A, AR2020_REG_VALUE_08BIT},//TLPX
+	{0x082A, 0x15, AR2020_REG_VALUE_08BIT},//TWAKEUP
+	{0x082B, 0x11, AR2020_REG_VALUE_08BIT},//TINIT
+	{0x082C, 0x13, AR2020_REG_VALUE_08BIT},//THS_EXIT
+	{0x3F06, 0x00C0, AR2020_REG_VALUE_16BIT},//MIPI_TIMING_2
+	{0x3F0A, 0xA000, AR2020_REG_VALUE_16BIT},//MIPI_TIMING_4
+	{0x3F0C, 0x000E, AR2020_REG_VALUE_16BIT},//MIPI_TIMING_5
+	{0x3F20, 0x8080, AR2020_REG_VALUE_16BIT},//MIPI_PHY_TRIM_MSB
+	{0x3F1E, 0x0004, AR2020_REG_VALUE_16BIT},//MIPI_PHY_TRIM_LSB
+	{0x4000, 0x0115, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_00
+	{0x4002, 0x1B26, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_02
+	{0x4004, 0x3FFF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_04
+	{0x4006, 0xFFFF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_06
+	{0x4008, 0x0A35, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_08
+	{0x400A, 0x10EF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_0A
+	{0x400C, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_0C
+	{0x400E, 0x30D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_0E
+	{0x4010, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10
+	{0x4012, 0xB5F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12
+	{0x4014, 0x0085, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14
+	{0x4016, 0xF004, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16
+	{0x4018, 0x9A89, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18
+	{0x401A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A
+	{0x401C, 0x9997, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C
+	{0x401E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E
+	{0x4020, 0x30C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20
+	{0x4022, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22
+	{0x4024, 0x82F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24
+	{0x4026, 0x0030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26
+	{0x4028, 0x18F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28
+	{0x402A, 0x0320, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A
+	{0x402C, 0x58F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C
+	{0x402E, 0x089C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E
+	{0x4030, 0xF010, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30
+	{0x4032, 0x99B6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32
+	{0x4034, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34
+	{0x4036, 0xB498, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36
+	{0x4038, 0xA096, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38
+	{0x403A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A
+	{0x403C, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C
+	{0x403E, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E
+	{0x4040, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40
+	{0x4042, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42
+	{0x4044, 0x209D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44
+	{0x4046, 0x8C08, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46
+	{0x4048, 0x08F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48
+	{0x404A, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A
+	{0x404C, 0x008F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4C
+	{0x404E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4E
+	{0x4050, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_50
+	{0x4052, 0x0488, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_52
+	{0x4054, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_54
+	{0x4056, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_56
+	{0x4058, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_58
+	{0x405A, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_5A
+	{0x405C, 0x0290, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_5C
+	{0x405E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_5E
+	{0x4060, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_60
+	{0x4062, 0x2EA3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_62
+	{0x4064, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_64
+	{0x4066, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_66
+	{0x4068, 0x089D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_68
+	{0x406A, 0xF075, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_6A
+	{0x406C, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_6C
+	{0x406E, 0x4070, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_6E
+	{0x4070, 0x216D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_70
+	{0x4072, 0x1CF6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_72
+	{0x4074, 0x8B00, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_74
+	{0x4076, 0x5186, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_76
+	{0x4078, 0x1300, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_78
+	{0x407A, 0x0205, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_7A
+	{0x407C, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_7C
+	{0x407E, 0x9FB7, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_7E
+	{0x4080, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_80
+	{0x4082, 0x8387, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_82
+	{0x4084, 0xF006, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_84
+	{0x4086, 0x8702, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_86
+	{0x4088, 0x0D02, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_88
+	{0x408A, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_8A
+	{0x408C, 0x0383, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_8C
+	{0x408E, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_8E
+	{0x4090, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_90
+	{0x4092, 0x0336, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_92
+	{0x4094, 0xD887, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_94
+	{0x4096, 0x020D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_96
+	{0x4098, 0xF14F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_98
+	{0x409A, 0xB79F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_9A
+	{0x409C, 0x1300, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_9C
+	{0x409E, 0xF012, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_9E
+	{0x40A0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A0
+	{0x40A2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A2
+	{0x40A4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A4
+	{0x40A6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A6
+	{0x40A8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_A8
+	{0x40AA, 0x0401, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_AA
+	{0x40AC, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_AC
+	{0x40AE, 0x82F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_AE
+	{0x40B0, 0x0883, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B0
+	{0x40B2, 0xF009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B2
+	{0x40B4, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B4
+	{0x40B6, 0x2985, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B6
+	{0x40B8, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_B8
+	{0x40BA, 0x2A87, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_BA
+	{0x40BC, 0xF63E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_BC
+	{0x40BE, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_BE
+	{0x40C0, 0x0801, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C0
+	{0x40C2, 0x40F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C2
+	{0x40C4, 0x0800, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C4
+	{0x40C6, 0x48F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C6
+	{0x40C8, 0x0882, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_C8
+	{0x40CA, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_CA
+	{0x40CC, 0x0401, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_CC
+	{0x40CE, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_CE
+	{0x40D0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D0
+	{0x40D2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D2
+	{0x40D4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D4
+	{0x40D6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D6
+	{0x40D8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_D8
+	{0x40DA, 0x0401, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_DA
+	{0x40DC, 0xF015, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_DC
+	{0x40DE, 0x002C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_DE
+	{0x40E0, 0xF00E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E0
+	{0x40E2, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E2
+	{0x40E4, 0x0687, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E4
+	{0x40E6, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E6
+	{0x40E8, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_E8
+	{0x40EA, 0x61E8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_EA
+	{0x40EC, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_EC
+	{0x40EE, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_EE
+	{0x40F0, 0x3480, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F0
+	{0x40F2, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F2
+	{0x40F4, 0x3240, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F4
+	{0x40F6, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F6
+	{0x40F8, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_F8
+	{0x40FA, 0xF00E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_FA
+	{0x40FC, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_FC
+	{0x40FE, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_FE
+	{0x4100, 0x3240, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_100
+	{0x4102, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_102
+	{0x4104, 0x3480, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_104
+	{0x4106, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_106
+	{0x4108, 0xC0EE, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_108
+	{0x410A, 0xF004, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10A
+	{0x410C, 0x3900, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10C
+	{0x410E, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_10E
+	{0x4110, 0xB0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_110
+	{0x4112, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_112
+	{0x4114, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_114
+	{0x4116, 0x86F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_116
+	{0x4118, 0x0086, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_118
+	{0x411A, 0xF089, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_11A
+	{0x411C, 0xB0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_11C
+	{0x411E, 0x00E9, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_11E
+	{0x4120, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_120
+	{0x4122, 0x8AF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_122
+	{0x4124, 0x0000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_124
+	{0x4126, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_126
+	{0x4128, 0x00E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_128
+	{0x412A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12A
+	{0x412C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12C
+	{0x412E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_12E
+	{0x4130, 0x0A35, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_130
+	{0x4132, 0x10EF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_132
+	{0x4134, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_134
+	{0x4136, 0x30D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_136
+	{0x4138, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_138
+	{0x413A, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_13A
+	{0x413C, 0x049A, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_13C
+	{0x413E, 0x89F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_13E
+	{0x4140, 0x0099, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_140
+	{0x4142, 0x97F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_142
+	{0x4144, 0x0030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_144
+	{0x4146, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_146
+	{0x4148, 0x0082, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_148
+	{0x414A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14A
+	{0x414C, 0x3018, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14C
+	{0x414E, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_14E
+	{0x4150, 0xB520, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_150
+	{0x4152, 0x58F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_152
+	{0x4154, 0x089C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_154
+	{0x4156, 0xF010, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_156
+	{0x4158, 0x99B6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_158
+	{0x415A, 0xF003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_15A
+	{0x415C, 0xB498, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_15C
+	{0x415E, 0xA096, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_15E
+	{0x4160, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_160
+	{0x4162, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_162
+	{0x4164, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_164
+	{0x4166, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_166
+	{0x4168, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_168
+	{0x416A, 0x209D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16A
+	{0x416C, 0x8C08, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16C
+	{0x416E, 0x08F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_16E
+	{0x4170, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_170
+	{0x4172, 0x008F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_172
+	{0x4174, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_174
+	{0x4176, 0x0188, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_176
+	{0x4178, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_178
+	{0x417A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_17A
+	{0x417C, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_17C
+	{0x417E, 0x0290, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_17E
+	{0x4180, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_180
+	{0x4182, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_182
+	{0x4184, 0x2DA3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_184
+	{0x4186, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_186
+	{0x4188, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_188
+	{0x418A, 0x089D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18A
+	{0x418C, 0xF06D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18C
+	{0x418E, 0x4070, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_18E
+	{0x4190, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_190
+	{0x4192, 0x214D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_192
+	{0x4194, 0x1FF6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_194
+	{0x4196, 0x0851, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_196
+	{0x4198, 0x0245, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_198
+	{0x419A, 0x20A0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_19A
+	{0x419C, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_19C
+	{0x419E, 0xB783, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_19E
+	{0x41A0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A0
+	{0x41A2, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A2
+	{0x41A4, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A4
+	{0x41A6, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A6
+	{0x41A8, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1A8
+	{0x41AA, 0x020D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1AA
+	{0x41AC, 0x0205, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1AC
+	{0x41AE, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1AE
+	{0x41B0, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B0
+	{0x41B2, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B2
+	{0x41B4, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B4
+	{0x41B6, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B6
+	{0x41B8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1B8
+	{0x41BA, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1BA
+	{0x41BC, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1BC
+	{0x41BE, 0xD802, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1BE
+	{0x41C0, 0x0D02, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C0
+	{0x41C2, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C2
+	{0x41C4, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C4
+	{0x41C6, 0xD8F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C6
+	{0x41C8, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1C8
+	{0x41CA, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1CA
+	{0x41CC, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1CC
+	{0x41CE, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1CE
+	{0x41D0, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D0
+	{0x41D2, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D2
+	{0x41D4, 0x020D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D4
+	{0x41D6, 0x0205, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D6
+	{0x41D8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1D8
+	{0x41DA, 0x36D8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1DA
+	{0x41DC, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1DC
+	{0x41DE, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1DE
+	{0x41E0, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E0
+	{0x41E2, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E2
+	{0x41E4, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E4
+	{0x41E6, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E6
+	{0x41E8, 0xD802, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1E8
+	{0x41EA, 0x0DF1, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1EA
+	{0x41EC, 0x4FB7, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1EC
+	{0x41EE, 0x9F13, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1EE
+	{0x41F0, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F0
+	{0x41F2, 0x12E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F2
+	{0x41F4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F4
+	{0x41F6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F6
+	{0x41F8, 0x9F13, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1F8
+	{0x41FA, 0x0041, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1FA
+	{0x41FC, 0x80F1, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1FC
+	{0x41FE, 0x30B8, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_1FE
+	{0x4200, 0xF00D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_200
+	{0x4202, 0x1300, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_202
+	{0x4204, 0xF03D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_204
+	{0x4206, 0x9FF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_206
+	{0x4208, 0x00B7, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_208
+	{0x420A, 0xF006, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20A
+	{0x420C, 0x0035, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20C
+	{0x420E, 0x10AF, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_20E
+	{0x4210, 0x3003, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_210
+	{0x4212, 0x30C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_212
+	{0x4214, 0xB2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_214
+	{0x4216, 0x01B5, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_216
+	{0x4218, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_218
+	{0x421A, 0x85F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_21A
+	{0x421C, 0x0292, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_21C
+	{0x421E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_21E
+	{0x4220, 0x9A8B, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_220
+	{0x4222, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_222
+	{0x4224, 0x9997, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_224
+	{0x4226, 0xF007, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_226
+	{0x4228, 0xB6F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_228
+	{0x422A, 0x0020, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22A
+	{0x422C, 0x5830, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22C
+	{0x422E, 0xC040, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_22E
+	{0x4230, 0x1282, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_230
+	{0x4232, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_232
+	{0x4234, 0x9CF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_234
+	{0x4236, 0x01B2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_236
+	{0x4238, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_238
+	{0x423A, 0xB8F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_23A
+	{0x423C, 0x0799, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_23C
+	{0x423E, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_23E
+	{0x4240, 0x98F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_240
+	{0x4242, 0x0296, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_242
+	{0x4244, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_244
+	{0x4246, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_246
+	{0x4248, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_248
+	{0x424A, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24A
+	{0x424C, 0x02A1, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24C
+	{0x424E, 0xF01F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_24E
+	{0x4250, 0x1009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_250
+	{0x4252, 0x2220, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_252
+	{0x4254, 0x0808, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_254
+	{0x4256, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_256
+	{0x4258, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_258
+	{0x425A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_25A
+	{0x425C, 0x88F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_25C
+	{0x425E, 0x0788, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_25E
+	{0x4260, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_260
+	{0x4262, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_262
+	{0x4264, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_264
+	{0x4266, 0x0290, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_266
+	{0x4268, 0xF016, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_268
+	{0x426A, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26A
+	{0x426C, 0x11A3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26C
+	{0x426E, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_26E
+	{0x4270, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_270
+	{0x4272, 0x089D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_272
+	{0x4274, 0xF002, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_274
+	{0x4276, 0xA1F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_276
+	{0x4278, 0x20A1, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_278
+	{0x427A, 0xF006, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_27A
+	{0x427C, 0x4300, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_27C
+	{0x427E, 0xF049, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_27E
+	{0x4280, 0x4014, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_280
+	{0x4282, 0x8B8E, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_282
+	{0x4284, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_284
+	{0x4286, 0x0802, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_286
+	{0x4288, 0x02F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_288
+	{0x428A, 0x00A6, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28A
+	{0x428C, 0xF013, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28C
+	{0x428E, 0xB283, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_28E
+	{0x4290, 0x9C36, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_290
+	{0x4292, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_292
+	{0x4294, 0x0636, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_294
+	{0x4296, 0x009C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_296
+	{0x4298, 0xF008, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_298
+	{0x429A, 0x8BF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_29A
+	{0x429C, 0x0083, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_29C
+	{0x429E, 0xA0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_29E
+	{0x42A0, 0x0630, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A0
+	{0x42A2, 0x18F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A2
+	{0x42A4, 0x02A3, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A4
+	{0x42A6, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A6
+	{0x42A8, 0xA3F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2A8
+	{0x42AA, 0x0243, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2AA
+	{0x42AC, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2AC
+	{0x42AE, 0x049D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2AE
+	{0x42B0, 0xF078, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B0
+	{0x42B2, 0x3018, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B2
+	{0x42B4, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B4
+	{0x42B6, 0x9D82, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B6
+	{0x42B8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2B8
+	{0x42BA, 0x9030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2BA
+	{0x42BC, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2BC
+	{0x42BE, 0x1130, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2BE
+	{0x42C0, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C0
+	{0x42C2, 0x0082, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C2
+	{0x42C4, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C4
+	{0x42C6, 0x1009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C6
+	{0x42C8, 0xF02A, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2C8
+	{0x42CA, 0xA2F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2CA
+	{0x42CC, 0x00A2, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2CC
+	{0x42CE, 0x3018, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2CE
+	{0x42D0, 0xF007, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D0
+	{0x42D2, 0x9DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D2
+	{0x42D4, 0x1C8C, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D4
+	{0x42D6, 0xF005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D6
+	{0x42D8, 0x301F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2D8
+	{0x42DA, 0x216D, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2DA
+	{0x42DC, 0x0A51, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2DC
+	{0x42DE, 0x1FEA, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2DE
+	{0x42E0, 0x8640, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E0
+	{0x42E2, 0xE29F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E2
+	{0x42E4, 0xF009, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E4
+	{0x42E6, 0x0005, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E6
+	{0x42E8, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2E8
+	{0x42EA, 0x30C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2EA
+	{0x42EC, 0xF001, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2EC
+	{0x42EE, 0x83F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2EE
+	{0x42F0, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F0
+	{0x42F2, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F2
+	{0x42F4, 0x0087, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F4
+	{0x42F6, 0xF007, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F6
+	{0x42F8, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2F8
+	{0x42FA, 0x0036, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2FA
+	{0x42FC, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2FC
+	{0x42FE, 0x0000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_2FE
+	{0x4300, 0x0DF0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_300
+	{0x4302, 0x0000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_302
+	{0x4304, 0x05F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_304
+	{0x4306, 0x0030, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_306
+	{0x4308, 0xC0F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_308
+	{0x430A, 0x0183, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30A
+	{0x430C, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30C
+	{0x430E, 0x3600, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_30E
+	{0x4310, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_310
+	{0x4312, 0x87F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_312
+	{0x4314, 0x0787, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_314
+	{0x4316, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_316
+	{0x4318, 0x36C0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_318
+	{0x431A, 0xF000, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_31A
+	{0x431C, 0x000F, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_31C
+	{0x431E, 0xF153, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_31E
+	{0x4320, 0x4180, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_320
+	{0x4322, 0x9F13, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_322
+	{0x4324, 0x00F0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_324
+	{0x4326, 0x00E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_326
+	{0x4328, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_328
+	{0x432A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32A
+	{0x432C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32C
+	{0x432E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_32E
+	{0x4330, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_330
+	{0x4332, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_332
+	{0x4334, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_334
+	{0x4336, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_336
+	{0x4338, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_338
+	{0x433A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_33A
+	{0x433C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_33C
+	{0x433E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_33E
+	{0x4340, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_340
+	{0x4342, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_342
+	{0x4344, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_344
+	{0x4346, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_346
+	{0x4348, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_348
+	{0x434A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34A
+	{0x434C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34C
+	{0x434E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_34E
+	{0x4350, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_350
+	{0x4352, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_352
+	{0x4354, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_354
+	{0x4356, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_356
+	{0x4358, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_358
+	{0x435A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_35A
+	{0x435C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_35C
+	{0x435E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_35E
+	{0x4360, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_360
+	{0x4362, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_362
+	{0x4364, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_364
+	{0x4366, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_366
+	{0x4368, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_368
+	{0x436A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36A
+	{0x436C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36C
+	{0x436E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_36E
+	{0x4370, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_370
+	{0x4372, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_372
+	{0x4374, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_374
+	{0x4376, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_376
+	{0x4378, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_378
+	{0x437A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_37A
+	{0x437C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_37C
+	{0x437E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_37E
+	{0x4380, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_380
+	{0x4382, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_382
+	{0x4384, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_384
+	{0x4386, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_386
+	{0x4388, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_388
+	{0x438A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38A
+	{0x438C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38C
+	{0x438E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_38E
+	{0x4390, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_390
+	{0x4392, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_392
+	{0x4394, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_394
+	{0x4396, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_396
+	{0x4398, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_398
+	{0x439A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_39A
+	{0x439C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_39C
+	{0x439E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_39E
+	{0x43A0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A0
+	{0x43A2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A2
+	{0x43A4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A4
+	{0x43A6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A6
+	{0x43A8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3A8
+	{0x43AA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3AA
+	{0x43AC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3AC
+	{0x43AE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3AE
+	{0x43B0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B0
+	{0x43B2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B2
+	{0x43B4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B4
+	{0x43B6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B6
+	{0x43B8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3B8
+	{0x43BA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3BA
+	{0x43BC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3BC
+	{0x43BE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3BE
+	{0x43C0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C0
+	{0x43C2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C2
+	{0x43C4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C4
+	{0x43C6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C6
+	{0x43C8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3C8
+	{0x43CA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3CA
+	{0x43CC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3CC
+	{0x43CE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3CE
+	{0x43D0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D0
+	{0x43D2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D2
+	{0x43D4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D4
+	{0x43D6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D6
+	{0x43D8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3D8
+	{0x43DA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3DA
+	{0x43DC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3DC
+	{0x43DE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3DE
+	{0x43E0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E0
+	{0x43E2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E2
+	{0x43E4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E4
+	{0x43E6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E6
+	{0x43E8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3E8
+	{0x43EA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3EA
+	{0x43EC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3EC
+	{0x43EE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3EE
+	{0x43F0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F0
+	{0x43F2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F2
+	{0x43F4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F4
+	{0x43F6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F6
+	{0x43F8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3F8
+	{0x43FA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3FA
+	{0x43FC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3FC
+	{0x43FE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_3FE
+	{0x4400, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_400
+	{0x4402, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_402
+	{0x4404, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_404
+	{0x4406, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_406
+	{0x4408, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_408
+	{0x440A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40A
+	{0x440C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40C
+	{0x440E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_40E
+	{0x4410, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_410
+	{0x4412, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_412
+	{0x4414, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_414
+	{0x4416, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_416
+	{0x4418, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_418
+	{0x441A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_41A
+	{0x441C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_41C
+	{0x441E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_41E
+	{0x4420, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_420
+	{0x4422, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_422
+	{0x4424, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_424
+	{0x4426, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_426
+	{0x4428, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_428
+	{0x442A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42A
+	{0x442C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42C
+	{0x442E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_42E
+	{0x4430, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_430
+	{0x4432, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_432
+	{0x4434, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_434
+	{0x4436, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_436
+	{0x4438, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_438
+	{0x443A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_43A
+	{0x443C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_43C
+	{0x443E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_43E
+	{0x4440, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_440
+	{0x4442, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_442
+	{0x4444, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_444
+	{0x4446, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_446
+	{0x4448, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_448
+	{0x444A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44A
+	{0x444C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44C
+	{0x444E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_44E
+	{0x4450, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_450
+	{0x4452, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_452
+	{0x4454, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_454
+	{0x4456, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_456
+	{0x4458, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_458
+	{0x445A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_45A
+	{0x445C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_45C
+	{0x445E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_45E
+	{0x4460, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_460
+	{0x4462, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_462
+	{0x4464, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_464
+	{0x4466, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_466
+	{0x4468, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_468
+	{0x446A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46A
+	{0x446C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46C
+	{0x446E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_46E
+	{0x4470, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_470
+	{0x4472, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_472
+	{0x4474, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_474
+	{0x4476, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_476
+	{0x4478, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_478
+	{0x447A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_47A
+	{0x447C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_47C
+	{0x447E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_47E
+	{0x4480, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_480
+	{0x4482, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_482
+	{0x4484, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_484
+	{0x4486, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_486
+	{0x4488, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_488
+	{0x448A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48A
+	{0x448C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48C
+	{0x448E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_48E
+	{0x4490, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_490
+	{0x4492, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_492
+	{0x4494, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_494
+	{0x4496, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_496
+	{0x4498, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_498
+	{0x449A, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_49A
+	{0x449C, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_49C
+	{0x449E, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_49E
+	{0x44A0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A0
+	{0x44A2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A2
+	{0x44A4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A4
+	{0x44A6, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A6
+	{0x44A8, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4A8
+	{0x44AA, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4AA
+	{0x44AC, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4AC
+	{0x44AE, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4AE
+	{0x44B0, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4B0
+	{0x44B2, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4B2
+	{0x44B4, 0xE0E0, AR2020_REG_VALUE_16BIT},//DYNAMIC_SEQRAM_4B4
+	{0x5500, 0x0000, AR2020_REG_VALUE_16BIT},//AGAIN_LUT0
+	{0x5502, 0x0002, AR2020_REG_VALUE_16BIT},//AGAIN_LUT1
+	{0x5504, 0x0006, AR2020_REG_VALUE_16BIT},//AGAIN_LUT2
+	{0x5506, 0x0009, AR2020_REG_VALUE_16BIT},//AGAIN_LUT3
+	{0x5508, 0x000F, AR2020_REG_VALUE_16BIT},//AGAIN_LUT4
+	{0x550A, 0x0010, AR2020_REG_VALUE_16BIT},//AGAIN_LUT5
+	{0x550C, 0x0011, AR2020_REG_VALUE_16BIT},//AGAIN_LUT6
+	{0x550E, 0x0012, AR2020_REG_VALUE_16BIT},//AGAIN_LUT7
+	{0x5510, 0x0019, AR2020_REG_VALUE_16BIT},//AGAIN_LUT8
+	{0x5512, 0x0020, AR2020_REG_VALUE_16BIT},//AGAIN_LUT9
+	{0x5514, 0x0021, AR2020_REG_VALUE_16BIT},//AGAIN_LUT10
+	{0x5516, 0x0023, AR2020_REG_VALUE_16BIT},//AGAIN_LUT11
+	{0x5518, 0x0026, AR2020_REG_VALUE_16BIT},//AGAIN_LUT12
+	{0x551A, 0x002B, AR2020_REG_VALUE_16BIT},//AGAIN_LUT13
+	{0x551C, 0x002F, AR2020_REG_VALUE_16BIT},//AGAIN_LUT14
+	{0x551E, 0x0030, AR2020_REG_VALUE_16BIT},//AGAIN_LUT15
+	{0x5400, 0x0100, AR2020_REG_VALUE_16BIT},//GT1_COARSE0
+	{0x5402, 0x2106, AR2020_REG_VALUE_16BIT},//GT1_COARSE1
+	{0x5404, 0x1101, AR2020_REG_VALUE_16BIT},//GT1_COARSE2
+	{0x5406, 0x3106, AR2020_REG_VALUE_16BIT},//GT1_COARSE3
+	{0x5408, 0x7100, AR2020_REG_VALUE_16BIT},//GT1_COARSE4
+	{0x540A, 0x8107, AR2020_REG_VALUE_16BIT},//GT1_COARSE5
+	{0x540C, 0xB101, AR2020_REG_VALUE_16BIT},//GT1_COARSE6
+	{0x540E, 0xD101, AR2020_REG_VALUE_16BIT},//GT1_COARSE7
+	{0x5410, 0xF12E, AR2020_REG_VALUE_16BIT},//GT1_COARSE8
+	{0x5412, 0xF112, AR2020_REG_VALUE_16BIT},//GT1_COARSE9
+	{0x5414, 0xF184, AR2020_REG_VALUE_16BIT},//GT1_COARSE10
+	{0x5416, 0xF224, AR2020_REG_VALUE_16BIT},//GT1_COARSE11
+	{0x5418, 0xF306, AR2020_REG_VALUE_16BIT},//GT1_COARSE12
+	{0x541A, 0xF446, AR2020_REG_VALUE_16BIT},//GT1_COARSE13
+	{0x541C, 0xF609, AR2020_REG_VALUE_16BIT},//GT1_COARSE14
+	{0x541E, 0xF887, AR2020_REG_VALUE_16BIT},//GT1_COARSE15
+	{0x5420, 0xFC0B, AR2020_REG_VALUE_16BIT},//GT1_COARSE16
+	{0x5422, 0xFC0B, AR2020_REG_VALUE_16BIT},//GT1_COARSE17
+	{0x5424, 0xFFFA, AR2020_REG_VALUE_16BIT},//GT1_DCG_ATTN_SET0
+	{0x5426, 0x5557, AR2020_REG_VALUE_16BIT},//GT1_DCG_ATTN_SET1
+	{0x5428, 0x0005, AR2020_REG_VALUE_16BIT},//GT1_DCG_ATTN_SET2
+	{0x542A, 0xA550, AR2020_REG_VALUE_16BIT},//GT1_ZONE_SET0
+	{0x542C, 0xAAAA, AR2020_REG_VALUE_16BIT},//GT1_ZONE_SET1
+	{0x542E, 0x000A, AR2020_REG_VALUE_16BIT},//GT1_ZONE_SET2
+	{0x5460, 0x2269, AR2020_REG_VALUE_16BIT},//ZT1_REG0_ADDR
+	{0x5462, 0x0B87, AR2020_REG_VALUE_16BIT},//ZT1_REG0_VALUE0
+	{0x5464, 0x0B87, AR2020_REG_VALUE_16BIT},//ZT1_REG0_VALUE1
+	{0x5466, 0x0983, AR2020_REG_VALUE_16BIT},//ZT1_REG0_VALUE2
+	{0x5498, 0x225E, AR2020_REG_VALUE_16BIT},//ZT1_REG7_ADDR
+	{0x549A, 0xBCAA, AR2020_REG_VALUE_16BIT},//ZT1_REG7_VALUE0
+	{0x549C, 0xBCAA, AR2020_REG_VALUE_16BIT},//ZT1_REG7_VALUE1
+	{0x549E, 0xBDAA, AR2020_REG_VALUE_16BIT},//ZT1_REG7_VALUE2
+	{0x3060, 0xFF01, AR2020_REG_VALUE_16BIT},//GAIN_TABLE_CTRL
+	{0x44BA, 0x0050, AR2020_REG_VALUE_16BIT},//DAC_LD_4_5
+	{0x44BC, 0xBCAA, AR2020_REG_VALUE_16BIT},//DAC_LD_6_7
+	{0x44C0, 0x4070, AR2020_REG_VALUE_16BIT},//DAC_LD_10_11
+	{0x44C4, 0x04D0, AR2020_REG_VALUE_16BIT},//DAC_LD_14_15
+	{0x44C6, 0x17E2, AR2020_REG_VALUE_16BIT},//DAC_LD_16_17
+	{0x44C8, 0xEA43, AR2020_REG_VALUE_16BIT},//DAC_LD_18_19
+	{0x44CA, 0x000E, AR2020_REG_VALUE_16BIT},//DAC_LD_20_21
+	{0x44CC, 0x7777, AR2020_REG_VALUE_16BIT},//DAC_LD_22_23
+	{0x44CE, 0x8BA4, AR2020_REG_VALUE_16BIT},//DAC_LD_24_25
+	{0x44D0, 0x1735, AR2020_REG_VALUE_16BIT},//DAC_LD_26_27
+	{0x44D2, 0x0B87, AR2020_REG_VALUE_16BIT},//DAC_LD_28_29
+	{0x44D4, 0x0000, AR2020_REG_VALUE_16BIT},//DAC_LD_30_31
+	{0x44D6, 0xF206, AR2020_REG_VALUE_16BIT},//DAC_LD_32_33
+	{0x44D8, 0xAAFA, AR2020_REG_VALUE_16BIT},//DAC_LD_34_35
+	{0x44DA, 0xE001, AR2020_REG_VALUE_16BIT},//DAC_LD_36_37
+	{0x44DE, 0x9BBC, AR2020_REG_VALUE_16BIT},//DAC_LD_40_41
+	{0x44E0, 0x283C, AR2020_REG_VALUE_16BIT},//DAC_LD_42_43
+	{0x44E2, 0x2821, AR2020_REG_VALUE_16BIT},//DAC_LD_44_45
+	{0x44E4, 0x8000, AR2020_REG_VALUE_16BIT},//DAC_LD_46_47
+	{0x44E6, 0x503F, AR2020_REG_VALUE_16BIT},//DAC_LD_48_49
+	{0x32A4, 0x0000, AR2020_REG_VALUE_16BIT},//CRM_CTRL
+	{0x328E, 0x0004, AR2020_REG_VALUE_16BIT},//ADDR_CTRL
+	{0x333C, 0x0001, AR2020_REG_VALUE_16BIT},//DYNAMIC_CTRL
+	{0x301A, 0x0000, AR2020_REG_VALUE_16BIT},//RESET_REGISTER
+	{0x3600, 0x94DF, AR2020_REG_VALUE_16BIT},//FDOC_CTRL
+	{0x3616, 0x0000, AR2020_REG_VALUE_16BIT},//FDOC_CTRL2
+	{0x3700, 0x0001, AR2020_REG_VALUE_16BIT},//PIX_DEF_ID
+	{0x3980, 0x0003, AR2020_REG_VALUE_16BIT},//PIX_DEF_CORR
+	{0x36C0, 0x0001, AR2020_REG_VALUE_16BIT},//DIGITAL_GAIN_CTRL
+	{0x36DE, 0x002A, AR2020_REG_VALUE_16BIT},//DATA_PEDESTAL1
+	{0x301A, 0x0008, AR2020_REG_VALUE_16BIT},//RESET_REGISTER
+	{0x3060, 0x0000, AR2020_REG_VALUE_16BIT},//GAIN_TABLE_CTRL
+	{0x3982, 0xAC70, AR2020_REG_VALUE_16BIT},//PDC_DYN_EDGE_THRES
+	{0x3984, 0xFA98, AR2020_REG_VALUE_16BIT},//PDC_DYN_LO_DEFECT_THRES
+	{0x3986, 0xFC3F, AR2020_REG_VALUE_16BIT},//PDC_DYN_HI_DEFECT_THRES
+	{0x3988, 0xAC70, AR2020_REG_VALUE_16BIT},//PDC_DYN_EDGE_THRES_T2
+	{0x398A, 0xFA98, AR2020_REG_VALUE_16BIT},//PDC_DYN_LO_DEFECT_THRES_T2
+	{0x398C, 0xFC3F, AR2020_REG_VALUE_16BIT},//PDC_DYN_HI_DEFECT_THRES_T2
+	{0x3980, 0x0003, AR2020_REG_VALUE_16BIT},//PIX_DEF_CORR
+	{0x3060, 0xFF01, AR2020_REG_VALUE_16BIT},//GAIN_TABLE_CTRL
+	{0x3340, 0x0C60, AR2020_REG_VALUE_16BIT},//OTPM_CTRL
+	{0x3340, 0x1C60, AR2020_REG_VALUE_16BIT},//OTPM_CTRL
+	{0x0101, 0x01, AR2020_REG_VALUE_08BIT},//Bing added, this is for H mirror FLIP.
+	{0x0100, 0x01, AR2020_REG_VALUE_08BIT},//MODE_SELECT
+	{0x44D6, 0xB206, AR2020_REG_VALUE_16BIT},//DAC_LD_32_33
+
+	{REG_NULL, 0x00, AR2020_REG_VALUE_16BIT},
+};
+
+
+static const s64 link_freq_menu_items[] = {
+	MIPI_FREQ_600M,
+	MIPI_FREQ_860M,
+};
+
+#define MIPI_FREQ_600M_INDEX 0
+#define MIPI_FREQ_860M_INDEX 1
+#define MIPI_FREQ_MAX_INDEX  2
+/*
+ * The width and height must be configured to be
+ * the same as the current output resolution of the sensor.
+ * The input width of the isp needs to be 16 aligned.
+ * The input height of the isp needs to be 8 aligned.
+ * If the width or height does not meet the alignment rules,
+ * you can configure the cropping parameters with the following function to
+ * crop out the appropriate resolution.
+ * struct v4l2_subdev_pad_ops {
+ *	.get_selection
+ * }
+ */
+
+/* Config resolution ,LLPCLK, FLL, exposure time,fps, MIPI channel config, HDR mode , open.k */
+static const struct ar2020_mode supported_modes[] = {
+	{
+		.bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,//H mirrored, so color format changed.
+		.width = 5120,
+		.height = 3840,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 300000,
+		},
+		.exp_def = 0x0240,
+		//reg 0342,for linear mode,hblank is 4*LINE_LENGTH_PCK_-WIDTH,so hts is 4*LINE_LENGTH_PCK_
+		.hts_def = 0x2DF0,
+		.vts_def = 0x0F28,//reg 0340
+		.reg_list = ar2020_linear_5120x3840_30fps_regs,
+		.hdr_mode = NO_HDR,
+		.mipi_freq = MIPI_FREQ_860M_INDEX,
+		.mipi_rate = MIPI_FREQ_860M / AR2020_BPP * 2 * AR2020_LANES,
+		.reg_mode = INITIAL_STREAMING,
+		.mclk = AR2020_XVCLK_FREQ_20M,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	},
+	{
+		.bus_fmt = MEDIA_BUS_FMT_SGRBG12_1X12,
+		.width = 5120,
+		.height = 3840,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 300000,
+		},
+		.exp_def = 0x0240,
+		//for HDR,hblank is 4*LINE_LENGTH_PCK_-WIDTH*2,so hts is 4*LINE_LENGTH_PCK_-WIDTH.
+		.hts_def = 0x2e30,
+		.vts_def = 0x0f1e,
+		.reg_list = ar2020_edr12bit_5120x3840_30fps_8lane_regs,
+		.hdr_mode = NO_HDR,
+		.mipi_freq = MIPI_FREQ_860M_INDEX,
+		.mipi_rate = MIPI_FREQ_860M / AR2020_BPP * 2 * AR2020_LANES,
+		.mclk = AR2020_XVCLK_FREQ_27M,
+		.reg_mode = INITIAL_STREAMING,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	},
+	{
+		.bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,
+		.width = 5120,
+		.height = 3840,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 440000,
+		},
+		.exp_def = 0x0240,
+		//for linear mode, hblank is 4*LINE_LENGTH_PCK_-WIDTH,so hts is 4*LINE_LENGTH_PCK_.
+		.hts_def = 0x4790,
+		.vts_def = 0x0F1E,
+		.reg_list = ar2020_linear_8lane_global_regs,
+		.hdr_mode = NO_HDR,
+		.mipi_freq = MIPI_FREQ_600M_INDEX,
+		.mipi_rate = MIPI_FREQ_600M / AR2020_BPP * 2 * AR2020_LANES,
+		.mclk = AR2020_XVCLK_FREQ_20M,
+		.reg_mode = INITIAL_STREAMING,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	},
+	{
+		.bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,
+		.width = 5120,
+		.height = 3840,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 300000,
+		},
+		.exp_def = 0x0240,
+		//for HDR,hblank is 4*LINE_LENGTH_PCK_-WIDTH*2,so hts is 4*LINE_LENGTH_PCK_-WIDTH.
+		.hts_def = 0x1718,
+		.vts_def = 0x1E3C,
+		.reg_list = ar2020_hdr10bit_5120x3840_30fps_8lane_regs,
+		.hdr_mode = HDR_X2,
+		.mipi_freq = MIPI_FREQ_860M_INDEX,
+		.mipi_rate = MIPI_FREQ_860M / AR2020_BPP * 2 * AR2020_LANES,
+		.mclk = AR2020_XVCLK_FREQ_27M,
+		.reg_mode = INITIAL_STREAMING,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+		.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,
+		.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
+		.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0
+	},
+	{
+		.bus_fmt = MEDIA_BUS_FMT_SGRBG10_1X10,
+		.width = 5120,
+		.height = 3840,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 220000,
+		},
+		.exp_def = 0x0240,
+		//for HDR,hblank is 4*LINE_LENGTH_PCK_-WIDTH*2,so hts is 4*LINE_LENGTH_PCK_-WIDTH.
+		.hts_def = 0x4790,
+		.vts_def = 0x1E3C,
+		.reg_list = ar2020_hdr10bit_5120x3840_22fps_8lane_regs,
+		.hdr_mode = HDR_X2,
+		.mipi_freq = MIPI_FREQ_600M_INDEX,
+		.mipi_rate = MIPI_FREQ_600M / AR2020_BPP * 2 * AR2020_LANES,
+		.mclk = AR2020_XVCLK_FREQ_20M,
+		.reg_mode = INITIAL_STREAMING,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+		.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,
+		.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
+		.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0
+	},
+};
+
+
+/* use ar2020_enable_test_pattern to config test pattern mode here, open.k */
+static const char * const ar2020_test_pattern_menu[] = {
+	"Disabled",
+	"Vertical Color Bar Type 1",
+	"Vertical Color Bar Type 2",
+	"Vertical Color Bar Type 3",
+	"Vertical Color Bar Type 4"
+};
+
+static int __ar2020_power_on(struct ar2020 *ar2020);
+static int ar2020_set_mclk(struct ar2020 *ar2020)
+{
+	int ret = 0;
+	struct device *dev = &ar2020->client->dev;
+
+	ret = clk_set_rate(ar2020->xvclk, ar2020->cur_mode->mclk);
+	if (ret < 0)
+		dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
+	if (clk_get_rate(ar2020->xvclk) != ar2020->cur_mode->mclk) {
+		dev_err(dev, "xvclk set mclk failed, value still %ld\n",
+			clk_get_rate(ar2020->xvclk));
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+/* Write registers up to 4 at a time */
+static int ar2020_write_reg(struct i2c_client *client, u16 reg,
+			    u32 len, u32 val)
+{
+	u32 buf_i, val_i;
+	u8 buf[6];
+	u8 *val_p;
+	__be32 val_be;
+
+	if (len > 4)
+		return -EINVAL;
+
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xff;
+
+	val_be = cpu_to_be32(val);
+	val_p = (u8 *)&val_be;
+	buf_i = 2;
+	val_i = 4 - len;
+
+	while (val_i < 4)
+		buf[buf_i++] = val_p[val_i++];
+
+	if (i2c_master_send(client, buf, len + 2) != len + 2)
+		return -EIO;
+
+	return 0;
+}
+
+static int ar2020_write_array(struct i2c_client *client,
+			       const struct regval *regs)
+{
+	u32 i;
+	int ret = 0;
+
+	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) {
+		if (unlikely(regs[i].addr == REG_DELAY))
+			usleep_range(regs[i].val * 200, regs[i].val * 250);
+		else
+			ret |= ar2020_write_reg(client, regs[i].addr,
+				regs[i].bits, regs[i].val);
+
+		if (ret != 0)
+			dev_err(&client->dev, "write reg %x with val %x failed, ret: %d\n",
+				regs[i].addr, regs[i].val, ret);
+	}
+	return ret;
+}
+
+/* Read registers up to 4 at a time */
+static int ar2020_read_reg(struct i2c_client *client,
+			    u16 reg,
+			    unsigned int len,
+			    u32 *val)
+{
+	struct i2c_msg msgs[2];
+	u8 *data_be_p;
+	__be32 data_be = 0;
+	__be16 reg_addr_be = cpu_to_be16(reg);
+	int ret;
+
+	if (len > 4 || !len)
+		return -EINVAL;
+
+	data_be_p = (u8 *)&data_be;
+	/* Write register address */
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = 2;
+	msgs[0].buf = (u8 *)&reg_addr_be;
+
+	/* Read data from register */
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = len;
+	msgs[1].buf = &data_be_p[4 - len];
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs))
+		return -EIO;
+
+	*val = be32_to_cpu(data_be);
+
+	return 0;
+}
+
+static int ar2020_get_reso_dist(const struct ar2020_mode *mode,
+				struct v4l2_mbus_framefmt *framefmt)
+{
+	return abs(mode->width - framefmt->width) +
+	       abs(mode->height - framefmt->height);
+}
+
+static const struct ar2020_mode *
+ar2020_find_best_fit(struct ar2020 *ar2020, struct v4l2_subdev_format *fmt)
+{
+	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
+	int dist;
+	int cur_best_fit = 0;
+	int cur_best_fit_dist = -1;
+	unsigned int i;
+
+	for (i = 0; i < ar2020->cfg_num; i++) {
+		dist = ar2020_get_reso_dist(&supported_modes[i], framefmt);
+		if ((cur_best_fit_dist == -1 || dist < cur_best_fit_dist) &&
+			(supported_modes[i].bus_fmt == framefmt->code)) {
+			cur_best_fit_dist = dist;
+			cur_best_fit = i;
+		}
+	}
+
+	return &supported_modes[cur_best_fit];
+}
+static int ar2020_set_rates(struct ar2020 *ar2020)
+{
+	const struct ar2020_mode *mode = ar2020->cur_mode;
+	s64 h_blank, vblank_def;
+	int ret = 0;
+
+	h_blank = mode->hts_def - mode->width;
+	__v4l2_ctrl_modify_range(ar2020->hblank, h_blank,
+				 h_blank, 1, h_blank);
+	vblank_def = mode->vts_def - mode->height;
+	__v4l2_ctrl_modify_range(ar2020->vblank, vblank_def,
+				 AR2020_VTS_MAX - mode->height,
+				 1, vblank_def);
+
+	__v4l2_ctrl_s_ctrl_int64(ar2020->pixel_rate,
+				 mode->mipi_rate);
+	__v4l2_ctrl_s_ctrl(ar2020->link_freq,
+			   mode->mipi_freq);
+
+	return ret;
+}
+/* setup sensor work format to determine the MIPI speed, open.k */
+static int ar2020_set_fmt(struct v4l2_subdev *sd,
+			  struct v4l2_subdev_pad_config *cfg,
+			  struct v4l2_subdev_format *fmt)
+{
+	struct ar2020 *ar2020 = to_ar2020(sd);
+	const struct ar2020_mode *mode;
+
+	mutex_lock(&ar2020->mutex);
+
+	mode = ar2020_find_best_fit(ar2020, fmt);
+	fmt->format.code = mode->bus_fmt;
+	fmt->format.width = mode->width;
+	fmt->format.height = mode->height;
+	fmt->format.field = V4L2_FIELD_NONE;
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+#else
+		mutex_unlock(&ar2020->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		ar2020->cur_mode = mode;
+		if (ar2020->cur_mclk != mode->mclk) {
+			if (ar2020_set_mclk(ar2020) == 0)
+				ar2020->cur_mclk = mode->mclk;
+		}
+		ar2020_set_rates(ar2020);
+	}
+
+	mutex_unlock(&ar2020->mutex);
+
+	return 0;
+}
+
+static int ar2020_get_fmt(struct v4l2_subdev *sd,
+			  struct v4l2_subdev_pad_config *cfg,
+			  struct v4l2_subdev_format *fmt)
+{
+	struct ar2020 *ar2020 = to_ar2020(sd);
+	const struct ar2020_mode *mode = ar2020->cur_mode;
+
+	mutex_lock(&ar2020->mutex);
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+#else
+		mutex_unlock(&ar2020->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		fmt->format.width = mode->width;
+		fmt->format.height = mode->height;
+		fmt->format.code = mode->bus_fmt;
+		fmt->format.field = V4L2_FIELD_NONE;
+		if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
+			fmt->reserved[0] = mode->vc[fmt->pad];
+		else
+			fmt->reserved[0] = mode->vc[PAD0];
+	}
+	mutex_unlock(&ar2020->mutex);
+
+	return 0;
+}
+
+static int ar2020_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_pad_config *cfg,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct ar2020 *ar2020 = to_ar2020(sd);
+
+	if (code->index >= ar2020->cfg_num)
+		return -EINVAL;
+	code->code = supported_modes[code->index].bus_fmt;
+
+	return 0;
+}
+
+static int ar2020_enum_frame_sizes(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_pad_config *cfg,
+				   struct v4l2_subdev_frame_size_enum *fse)
+{
+	struct ar2020 *ar2020 = to_ar2020(sd);
+
+	if (fse->index >= ar2020->cfg_num)
+		return -EINVAL;
+
+	if (fse->code != supported_modes[fse->index].bus_fmt)
+		return -EINVAL;
+
+	fse->min_width  = supported_modes[fse->index].width;
+	fse->max_width  = supported_modes[fse->index].width;
+	fse->max_height = supported_modes[fse->index].height;
+	fse->min_height = supported_modes[fse->index].height;
+
+	return 0;
+}
+/* use ar2020_enable_test_pattern to config test pattern mode here, open.k */
+static int ar2020_enable_test_pattern(struct ar2020 *ar2020, u32 pattern)
+{
+	int ret = 0;
+
+	return ret;
+}
+
+static int ar2020_g_frame_interval(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_frame_interval *fi)
+{
+	struct ar2020 *ar2020 = to_ar2020(sd);
+	const struct ar2020_mode *mode = ar2020->cur_mode;
+
+	mutex_lock(&ar2020->mutex);
+	fi->interval = mode->max_fps;
+	mutex_unlock(&ar2020->mutex);
+
+	return 0;
+}
+
+static int ar2020_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
+				struct v4l2_mbus_config *config)
+{
+	struct ar2020 *ar2020 = to_ar2020(sd);
+	const struct ar2020_mode *mode = ar2020->cur_mode;
+	u32 val = 0;
+
+	val = 1 << (AR2020_LANES - 1) |
+		V4L2_MBUS_CSI2_CHANNEL_0 |
+		V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+	if (mode->hdr_mode != NO_HDR)
+		val |= V4L2_MBUS_CSI2_CHANNEL_1;
+	if (mode->hdr_mode == HDR_X3)
+		val |= V4L2_MBUS_CSI2_CHANNEL_2;
+
+	config->type = V4L2_MBUS_CSI2_DPHY;
+	config->flags = val;
+
+	return 0;
+}
+
+
+static void ar2020_get_module_inf(struct ar2020 *ar2020,
+				  struct rkmodule_inf *inf)
+{
+	memset(inf, 0, sizeof(*inf));
+	strscpy(inf->base.sensor, AR2020_NAME, sizeof(inf->base.sensor));
+	strscpy(inf->base.module, ar2020->module_name,
+		sizeof(inf->base.module));
+	strscpy(inf->base.lens, ar2020->len_name, sizeof(inf->base.lens));
+}
+
+static int ar2020_set_hdrae(struct ar2020 *ar2020,
+			     struct preisp_hdrae_exp_s *ae)
+{
+	u32 l_exp_time, m_exp_time, s_exp_time;
+	u32 l_a_gain, m_a_gain, s_a_gain;
+	int ret = 0;
+	u32 gain_val = 0;
+
+	if (!ar2020->has_init_exp && !ar2020->streaming) {
+		ar2020->init_hdrae_exp = *ae;
+		ar2020->has_init_exp = true;
+		dev_err(&ar2020->client->dev, "ar2020 don't stream, record exp for hdr!\n");
+		return ret;
+	}
+	l_exp_time = ae->long_exp_reg;
+	m_exp_time = ae->middle_exp_reg;
+	s_exp_time = ae->short_exp_reg;
+	l_a_gain = ae->long_gain_reg;
+	m_a_gain = ae->middle_gain_reg;
+	s_a_gain = ae->short_gain_reg;
+	dev_dbg(&ar2020->client->dev,
+		"Bing irev exp req: L_exp: 0x%x, 0x%x, M_exp: 0x%x, 0x%x S_exp: 0x%x, 0x%x\n",
+		l_exp_time, l_a_gain,
+		m_exp_time, m_a_gain,
+		s_exp_time, s_a_gain);
+
+	if (ar2020->cur_mode->hdr_mode == HDR_X2) {
+		//2 stagger
+		l_a_gain = m_a_gain;
+		l_exp_time = m_exp_time;
+		m_a_gain = s_a_gain;
+		m_exp_time = s_exp_time;
+	}
+
+	l_a_gain = (l_a_gain > AR2020_GAIN_MAX) ? AR2020_GAIN_MAX : l_a_gain;
+	m_a_gain = (m_a_gain > AR2020_GAIN_MAX) ? AR2020_GAIN_MAX : m_a_gain;
+
+	l_exp_time = (l_exp_time > AR2020_CIT_MAX_T1)?AR2020_CIT_MAX_T1:l_exp_time;
+	m_exp_time = (m_exp_time > AR2020_CIT_MAX_T2)?AR2020_CIT_MAX_T2:m_exp_time;
+
+	ret |= ar2020_write_reg(ar2020->client,
+		AR2020_GROUP_UPDATE_ADDRESS,
+		AR2020_REG_VALUE_08BIT,
+		AR2020_GROUP_UPDATE_START_DATA);
+
+
+	gain_val = (m_a_gain << 8) + l_a_gain;
+	ret |= ar2020_write_reg(ar2020->client,
+		AR2020_REG_GAIN2,
+		AR2020_REG_VALUE_16BIT, gain_val);
+
+	ret |= ar2020_write_reg(ar2020->client,
+		AR2020_REG_EXP,
+		AR2020_REG_VALUE_16BIT,
+		l_exp_time);//T1/T2 ratio is not used here.
+	ret |= ar2020_write_reg(ar2020->client,
+		AR2020_REG_EXP_T2,
+		AR2020_REG_VALUE_16BIT,
+		m_exp_time);
+	ret |= ar2020_write_reg(ar2020->client,
+		AR2020_GROUP_UPDATE_ADDRESS,
+		AR2020_REG_VALUE_08BIT,
+		AR2020_GROUP_UPDATE_END_DATA);
+
+	return ret;
+}
+
+static int ar2020_get_channel_info(struct ar2020 *ar2020, struct rkmodule_channel_info *ch_info)
+{
+	if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX)
+		return -EINVAL;
+
+	ch_info->vc = ar2020->cur_mode->vc[ch_info->index];
+	ch_info->width = ar2020->cur_mode->width;
+	ch_info->height = ar2020->cur_mode->height;
+	ch_info->bus_fmt = ar2020->cur_mode->bus_fmt;
+	return 0;
+}
+
+static long ar2020_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	struct ar2020 *ar2020 = to_ar2020(sd);
+	struct rkmodule_hdr_cfg *hdr_cfg;
+	struct rkmodule_channel_info *ch_info;
+	long ret = 0;
+	u32 i, h, w;
+	u32 stream = 0;
+	struct rkmodule_capture_info  *capture_info;
+
+	switch (cmd) {
+	case PREISP_CMD_SET_HDRAE_EXP:
+		ar2020_set_hdrae(ar2020, arg);
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
+		w = ar2020->cur_mode->width;
+		h = ar2020->cur_mode->height;
+		for (i = 0; i < ar2020->cfg_num; i++) {
+			if (w == supported_modes[i].width &&
+			    h == supported_modes[i].height &&
+			    supported_modes[i].hdr_mode == hdr_cfg->hdr_mode) {
+				ar2020->cur_mode = &supported_modes[i];
+				break;
+			}
+		}
+		if (i == ar2020->cfg_num) {
+			dev_err(&ar2020->client->dev,
+				"not find hdr mode:%d %dx%d config\n",
+				hdr_cfg->hdr_mode, w, h);
+			ret = -EINVAL;
+		} else {
+			w = ar2020->cur_mode->hts_def - ar2020->cur_mode->width;
+			h = ar2020->cur_mode->vts_def - ar2020->cur_mode->height;
+			__v4l2_ctrl_modify_range(ar2020->hblank, w, w, 1, w);
+			__v4l2_ctrl_modify_range(ar2020->vblank, h,
+						 AR2020_VTS_MAX - ar2020->cur_mode->height,
+						 1, h);
+		}
+		if (ar2020->cur_mclk != ar2020->cur_mode->mclk) {
+			if (ar2020_set_mclk(ar2020) == 0)
+				ar2020->cur_mclk = ar2020->cur_mode->mclk;
+		}
+		ar2020_set_rates(ar2020);
+		break;
+	case RKMODULE_GET_MODULE_INFO:
+		ar2020_get_module_inf(ar2020, (struct rkmodule_inf *)arg);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
+		hdr_cfg->esp.mode = HDR_NORMAL_VC;
+		hdr_cfg->hdr_mode = ar2020->cur_mode->hdr_mode;
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+
+		stream = *((u32 *)arg);
+
+		if (stream)
+			ret = ar2020_write_reg(ar2020->client, AR2020_REG_CTRL_MODE,
+				AR2020_REG_VALUE_16BIT, AR2020_MODE_STREAMING);
+		else
+			ret = ar2020_write_reg(ar2020->client, AR2020_REG_CTRL_MODE,
+				AR2020_REG_VALUE_16BIT, AR2020_MODE_SW_STANDBY);
+		break;
+	case RKMODULE_GET_CHANNEL_INFO:
+		ch_info = (struct rkmodule_channel_info *)arg;
+		ret = ar2020_get_channel_info(ar2020, ch_info);
+		break;
+	case RKMODULE_GET_CAPTURE_MODE:
+		capture_info = (struct rkmodule_capture_info *)arg;
+		if (ar2020->csi_lanes_in_use == 8) {
+			dev_info(&ar2020->client->dev, "8 lanes in use, set dual mipi mode\n");
+			capture_info->mode = RKMODULE_MULTI_DEV_COMBINE_ONE;
+			capture_info->multi_dev = ar2020->multi_dev_info;
+		} else {
+			capture_info->mode = 0;
+		}
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long ar2020_compat_ioctl32(struct v4l2_subdev *sd,
+				  unsigned int cmd, unsigned long arg)
+{
+	void __user *up = compat_ptr(arg);
+	struct rkmodule_inf *inf;
+	struct rkmodule_awb_cfg *cfg;
+	struct rkmodule_hdr_cfg *hdr;
+	struct preisp_hdrae_exp_s *hdrae;
+	struct rkmodule_channel_info *ch_info;
+	long ret;
+	u32 stream = 0;
+	struct rkmodule_capture_info  *capture_info;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
+		if (!inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = ar2020_ioctl(sd, cmd, inf);
+		if (!ret) {
+			ret = copy_to_user(up, inf, sizeof(*inf));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(inf);
+		break;
+	case RKMODULE_AWB_CFG:
+		cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+		if (!cfg) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(cfg, up, sizeof(*cfg));
+		if (!ret)
+			ret = ar2020_ioctl(sd, cmd, cfg);
+		else
+			ret = -EFAULT;
+		kfree(cfg);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = ar2020_ioctl(sd, cmd, hdr);
+		if (!ret) {
+			ret = copy_to_user(up, hdr, sizeof(*hdr));
+			if (ret)
+				ret = -EFAULT;
+		} else {
+			ret = -EFAULT;
+		}
+		kfree(hdr);
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(hdr, up, sizeof(*hdr));
+		if (!ret)
+			ret = ar2020_ioctl(sd, cmd, hdr);
+		else
+			ret = -EFAULT;
+		kfree(hdr);
+		break;
+	case PREISP_CMD_SET_HDRAE_EXP:
+		hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
+		if (!hdrae) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(hdrae, up, sizeof(*hdrae));
+		if (!ret)
+			ret = ar2020_ioctl(sd, cmd, hdrae);
+		else
+			ret = -EFAULT;
+		kfree(hdrae);
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		ret = copy_from_user(&stream, up, sizeof(u32));
+		if (!ret)
+			ret = ar2020_ioctl(sd, cmd, &stream);
+		else
+			ret = -EFAULT;
+		break;
+	case RKMODULE_GET_CHANNEL_INFO:
+		ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
+		if (!ch_info) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = ar2020_ioctl(sd, cmd, ch_info);
+		if (!ret) {
+			ret = copy_to_user(up, ch_info, sizeof(*ch_info));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(ch_info);
+		break;
+	case RKMODULE_GET_CAPTURE_MODE:
+		capture_info = kzalloc(sizeof(*capture_info), GFP_KERNEL);
+		if (!capture_info) {
+			ret = -ENOMEM;
+			return ret;
+		}
+		ret = ar2020_ioctl(sd, cmd, capture_info);
+		if (!ret) {
+			ret = copy_to_user(up, capture_info, sizeof(*capture_info));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(capture_info);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+#endif
+
+static int __ar2020_start_stream(struct ar2020 *ar2020)
+{
+	int ret = 0;
+
+	if (!ar2020->is_thunderboot) {
+		ret = ar2020_write_reg(ar2020->client,
+					 AR2020_SOFTWARE_RESET_REG,
+					 AR2020_REG_VALUE_08BIT,
+					 0x0001);
+		usleep_range(100000, 200000);
+
+		ret |= ar2020_write_array(ar2020->client, ar2020->cur_mode->reg_list);
+		if (ret)
+			return ret;
+	}
+
+	/* In case these controls are set before streaming */
+	ret = __v4l2_ctrl_handler_setup(&ar2020->ctrl_handler);
+	if (ret)
+		return ret;
+	if (ar2020->has_init_exp && ar2020->cur_mode->hdr_mode != NO_HDR) {
+		ret = ar2020_ioctl(&ar2020->subdev,
+				   PREISP_CMD_SET_HDRAE_EXP,
+				   &ar2020->init_hdrae_exp);
+		if (ret) {
+			dev_err(&ar2020->client->dev,
+				"init exp fail in hdr mode\n");
+			return ret;
+		}
+	}
+	if (ar2020->cur_mode->reg_mode == INITIAL_STREAMING)
+		return ret;
+	return ar2020_write_reg(ar2020->client, AR2020_REG_CTRL_MODE,
+		AR2020_REG_VALUE_08BIT, AR2020_MODE_STREAMING);
+}
+
+static int __ar2020_stop_stream(struct ar2020 *ar2020)
+{
+	ar2020->has_init_exp = false;
+	if (ar2020->is_thunderboot)
+		ar2020->is_first_streamoff = true;
+	return ar2020_write_reg(ar2020->client, AR2020_REG_CTRL_MODE,
+		AR2020_REG_VALUE_16BIT, AR2020_MODE_SW_STANDBY);
+}
+
+static int ar2020_s_stream(struct v4l2_subdev *sd, int on)
+{
+	struct ar2020 *ar2020 = to_ar2020(sd);
+	struct i2c_client *client = ar2020->client;
+	int ret = 0;
+
+	mutex_lock(&ar2020->mutex);
+	on = !!on;
+	if (on == ar2020->streaming)
+		goto unlock_and_return;
+
+	if (on) {
+		if (ar2020->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
+			ar2020->is_thunderboot = false;
+			__ar2020_power_on(ar2020);
+		}
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		ret = __ar2020_start_stream(ar2020);
+		if (ret) {
+			v4l2_err(sd, "start stream failed while write regs\n");
+			pm_runtime_put(&client->dev);
+			goto unlock_and_return;
+		}
+	} else {
+		__ar2020_stop_stream(ar2020);
+		pm_runtime_put(&client->dev);
+	}
+	dev_dbg(&ar2020->client->dev, "s streaming well\n");
+	ar2020->streaming = on;
+
+unlock_and_return:
+	mutex_unlock(&ar2020->mutex);
+
+	return ret;
+}
+
+static int ar2020_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct ar2020 *ar2020 = to_ar2020(sd);
+	struct i2c_client *client = ar2020->client;
+	int ret = 0;
+
+	mutex_lock(&ar2020->mutex);
+	/* If the power state is not modified - no work to do. */
+	if (ar2020->power_on == !!on)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		if (!ar2020->is_thunderboot) {
+			ret |= ar2020_write_reg(ar2020->client,
+						 AR2020_SOFTWARE_RESET_REG,
+						 AR2020_REG_VALUE_16BIT,
+						 0x0001);
+			usleep_range(100, 200);
+		}
+
+		ar2020->power_on = true;
+	} else {
+		pm_runtime_put(&client->dev);
+		ar2020->power_on = false;
+	}
+
+unlock_and_return:
+	mutex_unlock(&ar2020->mutex);
+
+	return ret;
+}
+
+/* Calculate the delay in us by clock rate and clock cycles */
+static inline u32 ar2020_cal_delay(u32 cycles, struct ar2020 *ar2020)
+{
+	return DIV_ROUND_UP(cycles, ar2020->cur_mclk / 1000 / 1000);
+}
+
+/*
+ * sensor power on config, need check power, MCLK, GPIO etc,,,
+ * need go to .dts file to change the config;
+ * open.k
+ */
+static int __ar2020_power_on(struct ar2020 *ar2020)
+{
+	int ret;
+	u32 delay_us;
+	struct device *dev = &ar2020->client->dev;
+
+	if (ar2020->is_thunderboot)
+		return 0;
+
+	if (!IS_ERR_OR_NULL(ar2020->pins_default)) {
+		ret = pinctrl_select_state(ar2020->pinctrl,
+					   ar2020->pins_default);
+		if (ret < 0)
+			dev_err(dev, "could not set pins\n");
+	}
+	ret = clk_set_rate(ar2020->xvclk, /*AR2020_XVCLK_FREQ*/ ar2020->cur_mode->mclk);
+	if (ret < 0)
+		dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
+	if (clk_get_rate(ar2020->xvclk) != ar2020->cur_mode->mclk)
+		dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
+	ret = clk_prepare_enable(ar2020->xvclk);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable xvclk\n");
+		return ret;
+	}
+	ar2020->cur_mclk = ar2020->cur_mode->mclk;
+
+	ret = regulator_bulk_enable(AR2020_NUM_SUPPLIES, ar2020->supplies);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable regulators\n");
+		goto disable_clk;
+	}
+
+	usleep_range(500, 1000);
+	if (!IS_ERR(ar2020->pwdn_gpio))
+		gpiod_direction_output(ar2020->pwdn_gpio, 1);
+	/*
+	 * There is no need to wait for the delay of RC circuit
+	 * if the reset signal is directly controlled by GPIO.
+	 */
+	if (!IS_ERR(ar2020->reset_gpio))
+		usleep_range(6000, 8000);
+	else
+		usleep_range(12000, 16000);
+
+	/* 8192 cycles prior to first SCCB transaction */
+	delay_us = ar2020_cal_delay(8192, ar2020);
+	usleep_range(delay_us, delay_us * 2);
+
+	return 0;
+
+disable_clk:
+	clk_disable_unprepare(ar2020->xvclk);
+
+	return ret;
+}
+
+static void __ar2020_power_off(struct ar2020 *ar2020)
+{
+	int ret;
+	struct device *dev = &ar2020->client->dev;
+
+	if (ar2020->is_thunderboot) {
+		if (ar2020->is_first_streamoff) {
+			ar2020->is_thunderboot = false;
+			ar2020->is_first_streamoff = false;
+		} else {
+			return;
+		}
+	}
+
+	if (!IS_ERR(ar2020->pwdn_gpio))
+		gpiod_direction_output(ar2020->pwdn_gpio, 0);
+
+	clk_disable_unprepare(ar2020->xvclk);
+
+	if (!IS_ERR(ar2020->reset_gpio))
+		gpiod_direction_output(ar2020->reset_gpio, 0);
+	if (!IS_ERR_OR_NULL(ar2020->pins_sleep)) {
+		ret = pinctrl_select_state(ar2020->pinctrl,
+					   ar2020->pins_sleep);
+		if (ret < 0)
+			dev_dbg(dev, "could not set pins\n");
+	}
+
+	if (ar2020->is_thunderboot_ng) {
+		ar2020->is_thunderboot_ng = false;
+		regulator_bulk_disable(AR2020_NUM_SUPPLIES, ar2020->supplies);
+	}
+}
+
+static int ar2020_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ar2020 *ar2020 = to_ar2020(sd);
+
+	return __ar2020_power_on(ar2020);
+}
+
+static int ar2020_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ar2020 *ar2020 = to_ar2020(sd);
+
+	__ar2020_power_off(ar2020);
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int ar2020_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct ar2020 *ar2020 = to_ar2020(sd);
+	struct v4l2_mbus_framefmt *try_fmt =
+				v4l2_subdev_get_try_format(sd, fh->pad, 0);
+	const struct ar2020_mode *def_mode = &supported_modes[0];
+
+	mutex_lock(&ar2020->mutex);
+	/* Initialize try_fmt */
+	try_fmt->width = def_mode->width;
+	try_fmt->height = def_mode->height;
+	try_fmt->code = def_mode->bus_fmt;
+	try_fmt->field = V4L2_FIELD_NONE;
+
+	mutex_unlock(&ar2020->mutex);
+	/* No crop or compose */
+
+	return 0;
+}
+#endif
+
+static int ar2020_enum_frame_interval(struct v4l2_subdev *sd,
+				       struct v4l2_subdev_pad_config *cfg,
+				       struct v4l2_subdev_frame_interval_enum *fie)
+{
+	struct ar2020 *ar2020 = to_ar2020(sd);
+
+	if (fie->index >= ar2020->cfg_num)
+		return -EINVAL;
+
+	fie->code = supported_modes[fie->index].bus_fmt;
+	fie->width = supported_modes[fie->index].width;
+	fie->height = supported_modes[fie->index].height;
+	fie->interval = supported_modes[fie->index].max_fps;
+	fie->reserved[0] = supported_modes[fie->index].hdr_mode;
+
+	return 0;
+}
+
+static const struct dev_pm_ops ar2020_pm_ops = {
+	SET_RUNTIME_PM_OPS(ar2020_runtime_suspend,
+			   ar2020_runtime_resume, NULL)
+};
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static const struct v4l2_subdev_internal_ops ar2020_internal_ops = {
+	.open = ar2020_open,
+};
+#endif
+
+static const struct v4l2_subdev_core_ops ar2020_core_ops = {
+	.s_power = ar2020_s_power,
+	.ioctl = ar2020_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl32 = ar2020_compat_ioctl32,
+#endif
+};
+
+static const struct v4l2_subdev_video_ops ar2020_video_ops = {
+	.s_stream = ar2020_s_stream,
+	.g_frame_interval = ar2020_g_frame_interval,
+};
+
+static const struct v4l2_subdev_pad_ops ar2020_pad_ops = {
+	.enum_mbus_code = ar2020_enum_mbus_code,
+	.enum_frame_size = ar2020_enum_frame_sizes,
+	.enum_frame_interval = ar2020_enum_frame_interval,
+	.get_fmt = ar2020_get_fmt,
+	.set_fmt = ar2020_set_fmt,
+	.get_mbus_config = ar2020_g_mbus_config,
+};
+
+static const struct v4l2_subdev_ops ar2020_subdev_ops = {
+	.core	= &ar2020_core_ops,
+	.video	= &ar2020_video_ops,
+	.pad	= &ar2020_pad_ops,
+};
+
+
+static int ar2020_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct ar2020 *ar2020 = container_of(ctrl->handler,
+					     struct ar2020, ctrl_handler);
+	struct i2c_client *client = ar2020->client;
+	s64 max;
+	int ret = 0;
+	u32 val = 0;
+
+	/* Propagate change of current control to all related controls */
+	switch (ctrl->id) {
+	case V4L2_CID_VBLANK:
+		/* Update max exposure while meeting expected vblanking */
+		max = ar2020->cur_mode->height + ctrl->val - 4;
+		__v4l2_ctrl_modify_range(ar2020->exposure,
+					 ar2020->exposure->minimum, max,
+					 ar2020->exposure->step,
+					 ar2020->exposure->default_value);
+		break;
+	}
+
+	if (!pm_runtime_get_if_in_use(&client->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		ret = ar2020_write_reg(ar2020->client,
+				       AR2020_REG_EXP,
+				       AR2020_REG_VALUE_16BIT,
+				       ctrl->val);
+		dev_dbg(&client->dev, "set exposure 0x%x\n",
+			ctrl->val);
+		break;
+	case V4L2_CID_ANALOGUE_GAIN:
+
+		ret = ar2020_write_reg(ar2020->client,
+				       AR2020_REG_GAIN,
+				       AR2020_REG_VALUE_16BIT,
+				       ctrl->val);
+
+		dev_dbg(&client->dev, "set analog gain 0x%x\n",
+			ctrl->val);
+		break;
+	case V4L2_CID_VBLANK:
+		ret = ar2020_write_reg(ar2020->client, AR2020_REG_VTS,
+				       AR2020_REG_VALUE_16BIT,
+				       ctrl->val + ar2020->cur_mode->height);
+		dev_dbg(&client->dev, "set vblank 0x%x\n",
+			ctrl->val);
+		break;
+	case V4L2_CID_TEST_PATTERN:
+		ret = ar2020_enable_test_pattern(ar2020, ctrl->val);
+		break;
+	case V4L2_CID_HFLIP:
+		ret = ar2020_read_reg(ar2020->client, AR2020_FLIP_REG,
+				      AR2020_REG_VALUE_16BIT,
+				      &val);
+		if (ctrl->val)
+			val |= MIRROR_BIT_MASK;
+		else
+			val &= ~MIRROR_BIT_MASK;
+		ret |= ar2020_write_reg(ar2020->client, AR2020_FLIP_REG,
+					AR2020_REG_VALUE_16BIT,
+					val);
+		if (ret == 0)
+			ar2020->flip = val;
+		break;
+	case V4L2_CID_VFLIP:
+		ret = ar2020_read_reg(ar2020->client, AR2020_FLIP_REG,
+				      AR2020_REG_VALUE_16BIT,
+				      &val);
+		if (ctrl->val)
+			val |= FLIP_BIT_MASK;
+		else
+			val &= ~FLIP_BIT_MASK;
+		ret |= ar2020_write_reg(ar2020->client, AR2020_FLIP_REG,
+					AR2020_REG_VALUE_16BIT,
+					val);
+		if (ret == 0)
+			ar2020->flip = val;
+		break;
+	default:
+		dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
+			 __func__, ctrl->id, ctrl->val);
+		break;
+	}
+
+	pm_runtime_put(&client->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops ar2020_ctrl_ops = {
+	.s_ctrl = ar2020_set_ctrl,
+};
+
+static int ar2020_initialize_controls(struct ar2020 *ar2020)
+{
+	const struct ar2020_mode *mode;
+	struct v4l2_ctrl_handler *handler;
+	s64 exposure_max, vblank_def;
+	u32 h_blank;
+	int ret;
+	u64 dst_link_freq = 0;
+	u64 dst_pixel_rate = 0;
+
+	handler = &ar2020->ctrl_handler;
+	mode = ar2020->cur_mode;
+	ret = v4l2_ctrl_handler_init(handler, 9);
+	if (ret)
+		return ret;
+	handler->lock = &ar2020->mutex;
+
+	ar2020->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
+			V4L2_CID_LINK_FREQ,
+			MIPI_FREQ_MAX_INDEX, 0, link_freq_menu_items);
+
+	dst_link_freq = mode->mipi_freq;
+	dst_pixel_rate = mode->mipi_rate;
+	/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
+	ar2020->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
+			V4L2_CID_PIXEL_RATE,
+			0, PIXEL_RATE_MAX,
+			1, dst_pixel_rate);
+
+	__v4l2_ctrl_s_ctrl(ar2020->link_freq,
+			   dst_link_freq);
+
+	h_blank = mode->hts_def - mode->width;
+	ar2020->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
+				h_blank, h_blank, 1, h_blank);
+	if (ar2020->hblank)
+		ar2020->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	vblank_def = mode->vts_def - mode->height;
+	ar2020->vblank = v4l2_ctrl_new_std(handler, &ar2020_ctrl_ops,
+				V4L2_CID_VBLANK, vblank_def,
+				AR2020_VTS_MAX - mode->height,
+				1, vblank_def);
+
+	exposure_max = mode->vts_def - 4;
+	ar2020->exposure = v4l2_ctrl_new_std(handler, &ar2020_ctrl_ops,
+				V4L2_CID_EXPOSURE, AR2020_EXPOSURE_MIN,
+				exposure_max, AR2020_EXPOSURE_STEP,
+				mode->exp_def);
+
+	ar2020->anal_gain = v4l2_ctrl_new_std(handler, &ar2020_ctrl_ops,
+				V4L2_CID_ANALOGUE_GAIN, AR2020_GAIN_MIN,
+				AR2020_GAIN_MAX, AR2020_GAIN_STEP,
+				AR2020_GAIN_DEFAULT);
+
+	ar2020->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
+				&ar2020_ctrl_ops, V4L2_CID_TEST_PATTERN,
+				ARRAY_SIZE(ar2020_test_pattern_menu) - 1,
+				0, 0, ar2020_test_pattern_menu);
+
+	ar2020->h_flip = v4l2_ctrl_new_std(handler, &ar2020_ctrl_ops,
+				V4L2_CID_HFLIP, 0, 1, 1, 0);
+
+	ar2020->v_flip = v4l2_ctrl_new_std(handler, &ar2020_ctrl_ops,
+				V4L2_CID_VFLIP, 0, 1, 1, 0);
+	ar2020->flip = 0;
+	if (handler->error) {
+		ret = handler->error;
+		dev_err(&ar2020->client->dev,
+			"Failed to init controls(%d)\n", ret);
+		goto err_free_handler;
+	}
+
+	ar2020->subdev.ctrl_handler = handler;
+	ar2020->has_init_exp = false;
+	ar2020->long_hcg = false;
+	ar2020->middle_hcg = false;
+	ar2020->short_hcg = false;
+
+	return 0;
+
+err_free_handler:
+	v4l2_ctrl_handler_free(handler);
+
+	return ret;
+}
+
+static int ar2020_check_sensor_id(struct ar2020 *ar2020,
+				  struct i2c_client *client)
+{
+	struct device *dev = &ar2020->client->dev;
+	u32 id = 0;
+	int ret;
+
+	if (ar2020->is_thunderboot) {
+		dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
+		return 0;
+	}
+
+	ret = ar2020_read_reg(client, AR2020_REG_CHIP_ID,
+			       AR2020_REG_VALUE_16BIT, &id);
+	if (id != CHIP_ID) {
+		dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
+		return -ENODEV;
+	}
+
+	dev_info(dev, "Detected ar2020-%04x sensor\n", CHIP_ID);
+
+	return 0;
+}
+
+static int ar2020_configure_regulators(struct ar2020 *ar2020)
+{
+	unsigned int i;
+
+	for (i = 0; i < AR2020_NUM_SUPPLIES; i++)
+		ar2020->supplies[i].supply = ar2020_supply_names[i];
+
+	return devm_regulator_bulk_get(&ar2020->client->dev,
+				       AR2020_NUM_SUPPLIES,
+				       ar2020->supplies);
+}
+
+static int ar2020_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct device_node *node = dev->of_node;
+	struct ar2020 *ar2020;
+	struct v4l2_subdev *sd;
+	char facing[2];
+	int ret;
+	u32 i, hdr_mode = 0;
+
+	dev_dbg(dev, "driver version: %02x.%02x.%02x",
+		DRIVER_VERSION >> 16,
+		(DRIVER_VERSION & 0xff00) >> 8,
+		DRIVER_VERSION & 0x00ff);
+
+	ar2020 = devm_kzalloc(dev, sizeof(*ar2020), GFP_KERNEL);
+	if (!ar2020)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
+				   &ar2020->module_index);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
+				       &ar2020->module_facing);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
+				       &ar2020->module_name);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
+				       &ar2020->len_name);
+	if (ret) {
+		dev_err(dev, "could not get module information!\n");
+		return -EINVAL;
+	}
+	#if USE_8LANE
+	/*dual mipi settings, should move to dts in future*/
+	ar2020->csi_lanes_in_use = LANE_NUM_8;
+	ar2020->multi_dev_info.dev_idx[0] = 0;//0;
+	ar2020->multi_dev_info.dev_idx[1] = 1;//device num, dcphy0->0, dcphy1->1,csi0->2,csi1->4;
+	ar2020->multi_dev_info.combine_idx[0] = 1;//main dev,default right sight image
+	ar2020->multi_dev_info.pixel_offset = 24;//the overlapped pixel number of L&R frame.
+	ar2020->multi_dev_info.dev_num = 2;//two mipi dev, each 4 lanes;
+	/*dual mipi setting over*/
+	#endif
+	ar2020->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
+	ret = of_property_read_u32(node, OF_CAMERA_HDR_MODE,
+			&hdr_mode);
+	if (ret) {
+		hdr_mode = NO_HDR;
+		dev_warn(dev, " Get hdr mode failed! no hdr default\n");
+	}
+	ar2020->cfg_num = ARRAY_SIZE(supported_modes);
+	if (ar2020->cfg_num == 0) {
+		dev_err(dev, "no any supported mode providec, force exit probe!\n");
+		return -EINVAL;
+	}
+	ar2020->cur_mode = &supported_modes[0];//initialize.
+	for (i = 0; i < ar2020->cfg_num; i++) {
+		if (hdr_mode == supported_modes[i].hdr_mode) {
+			ar2020->cur_mode = &supported_modes[i];
+			break;
+		}
+	}
+	ar2020->client = client;
+
+	ar2020->xvclk = devm_clk_get(dev, "xvclk");
+	if (IS_ERR(ar2020->xvclk)) {
+		dev_err(dev, "Failed to get xvclk\n");
+		return -EINVAL;
+	}
+
+	ar2020->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
+	if (IS_ERR(ar2020->pwdn_gpio))
+		dev_warn(dev, "Failed to get pwdn-gpios\n");
+
+	ar2020->pinctrl = devm_pinctrl_get(dev);
+	if (!IS_ERR(ar2020->pinctrl)) {
+		ar2020->pins_default =
+			pinctrl_lookup_state(ar2020->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_DEFAULT);
+		if (IS_ERR(ar2020->pins_default))
+			dev_err(dev, "could not get default pinstate\n");
+
+		ar2020->pins_sleep =
+			pinctrl_lookup_state(ar2020->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_SLEEP);
+		if (IS_ERR(ar2020->pins_sleep))
+			dev_err(dev, "could not get sleep pinstate\n");
+	} else {
+		dev_err(dev, "no pinctrl\n");
+	}
+
+	ret = ar2020_configure_regulators(ar2020);
+	if (ret) {
+		dev_err(dev, "Failed to get power regulators\n");
+		return ret;
+	}
+
+	mutex_init(&ar2020->mutex);
+
+	sd = &ar2020->subdev;
+	v4l2_i2c_subdev_init(sd, client, &ar2020_subdev_ops);
+	ret = ar2020_initialize_controls(ar2020);
+	if (ret)
+		goto err_destroy_mutex;
+
+	ret = __ar2020_power_on(ar2020);
+	if (ret)
+		goto err_free_handler;
+
+	ret = ar2020_check_sensor_id(ar2020, client);
+	if (ret)
+		goto err_power_off;
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	sd->internal_ops = &ar2020_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+#endif
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	ar2020->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &ar2020->pad);
+	if (ret < 0)
+		goto err_power_off;
+#endif
+
+	memset(facing, 0, sizeof(facing));
+	if (strcmp(ar2020->module_facing, "back") == 0)
+		facing[0] = 'b';
+	else
+		facing[0] = 'f';
+
+	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
+		 ar2020->module_index, facing,
+		 AR2020_NAME, dev_name(sd->dev));
+	ret = v4l2_async_register_subdev_sensor_common(sd);
+	if (ret) {
+		dev_err(dev, "v4l2 async register subdev failed\n");
+		goto err_clean_entity;
+	}
+
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_idle(dev);
+
+	return 0;
+
+err_clean_entity:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+err_power_off:
+	__ar2020_power_off(ar2020);
+err_free_handler:
+	v4l2_ctrl_handler_free(&ar2020->ctrl_handler);
+err_destroy_mutex:
+	mutex_destroy(&ar2020->mutex);
+
+	return ret;
+}
+
+static int ar2020_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ar2020 *ar2020 = to_ar2020(sd);
+
+	v4l2_async_unregister_subdev(sd);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+	v4l2_ctrl_handler_free(&ar2020->ctrl_handler);
+	mutex_destroy(&ar2020->mutex);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		__ar2020_power_off(ar2020);
+	pm_runtime_set_suspended(&client->dev);
+
+	return 0;
+}
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id ar2020_of_match[] = {
+	{ .compatible = "onsemi,ar2020" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, ar2020_of_match);
+#endif
+
+static const struct i2c_device_id ar2020_match_id[] = {
+	{ "onsemi,ar2020", 0 },
+	{ },
+};
+
+static struct i2c_driver ar2020_i2c_driver = {
+	.driver = {
+		.name = AR2020_NAME,
+		.pm = &ar2020_pm_ops,
+		.of_match_table = of_match_ptr(ar2020_of_match),
+	},
+	.probe		= &ar2020_probe,
+	.remove		= &ar2020_remove,
+	.id_table	= ar2020_match_id,
+};
+
+#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
+module_i2c_driver(ar2020_i2c_driver);
+#else
+static int __init sensor_mod_init(void)
+{
+	return i2c_add_driver(&ar2020_i2c_driver);
+}
+
+static void __exit sensor_mod_exit(void)
+{
+	i2c_del_driver(&ar2020_i2c_driver);
+}
+
+device_initcall_sync(sensor_mod_init);
+module_exit(sensor_mod_exit);
+#endif
+
+MODULE_DESCRIPTION("Onsemi ar2020 sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/cam-sleep-wakeup.c b/kernel/drivers/media/i2c/cam-sleep-wakeup.c
new file mode 100644
index 0000000..f8a6c83
--- /dev/null
+++ b/kernel/drivers/media/i2c/cam-sleep-wakeup.c
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2023 Rockchip Electronics Co., Ltd
+
+#include <linux/i2c.h>
+#include <linux/clk.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/rk-preisp.h>
+#include <linux/gpio/consumer.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+#include "cam-sleep-wakeup.h"
+
+struct cam_sw_info *cam_sw_init(void)
+{
+	struct cam_sw_info *cam_info =
+		kzalloc(sizeof(*cam_info), GFP_KERNEL);
+	if (!cam_info)
+		pr_err("kmalloc for cam fail\n");
+	return cam_info;
+}
+EXPORT_SYMBOL_GPL(cam_sw_init);
+
+int cam_sw_deinit(struct cam_sw_info *info)
+{
+	if (IS_ERR_OR_NULL(info)) {
+		pr_err("%s param is null\n", __func__);
+		return -EINVAL;
+	}
+
+	kfree(info);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cam_sw_deinit);
+
+int cam_sw_clk_init(struct cam_sw_info *info, struct clk *xvclk, u32 clk_freq)
+{
+	if (IS_ERR_OR_NULL(info)) {
+		pr_err("%s param is null\n", __func__);
+		return -EINVAL;
+	}
+
+	info->clk.xvclk = xvclk;
+	info->clk.clk_freq = clk_freq;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cam_sw_clk_init);
+
+int cam_sw_reset_pin_init(struct cam_sw_info *info,
+			  struct gpio_desc *reset_gpio, bool reset_active_state)
+{
+	if (IS_ERR_OR_NULL(info)) {
+		pr_err("%s param is null\n", __func__);
+		return -EINVAL;
+	}
+
+	info->pin.reset_gpio = reset_gpio;
+	info->pin.reset_active_state = reset_active_state;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cam_sw_reset_pin_init);
+
+int cam_sw_pwdn_pin_init(struct cam_sw_info *info, struct gpio_desc *pwdn_gpio,
+			 bool pwdn_active_state)
+{
+	if (IS_ERR_OR_NULL(info)) {
+		pr_err("%s param is null\n", __func__);
+		return -EINVAL;
+	}
+
+	info->pin.pwdn_gpio = pwdn_gpio;
+	info->pin.pwdn_active_state = pwdn_active_state;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cam_sw_pwdn_pin_init);
+
+int cam_sw_pinctrl_init(struct cam_sw_info *info, struct pinctrl *pinctrl,
+			struct pinctrl_state *pins_default,
+			struct pinctrl_state *pins_sleep)
+{
+	if (IS_ERR_OR_NULL(info)) {
+		pr_err("%s param is null\n", __func__);
+		return -EINVAL;
+	}
+
+	info->pin.pinctrl = pinctrl;
+	info->pin.pins_default = pins_default;
+	info->pin.pins_sleep = pins_sleep;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cam_sw_pinctrl_init);
+
+int cam_sw_regulator_bulk_init(struct cam_sw_info *info, int supplies_num,
+			       struct regulator_bulk_data *supplies)
+{
+	if (IS_ERR_OR_NULL(info)) {
+		pr_err("%s param is null\n", __func__);
+		return -EINVAL;
+	}
+	info->pin.supplies_num = supplies_num;
+	info->pin.supplies = supplies;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cam_sw_regulator_bulk_init);
+
+int cam_sw_write_array_cb_init(struct cam_sw_info *info,
+			       struct i2c_client *client, void *array_regs,
+			       sensor_write_array write_array)
+{
+	if (IS_ERR_OR_NULL(info) || IS_ERR_OR_NULL(client)) {
+		pr_err("%s param is null\n", __func__);
+		return -EINVAL;
+	}
+
+	info->client = client;
+	info->array_regs = array_regs;
+	info->write_array = write_array;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cam_sw_write_array_cb_init);
+
+int cam_sw_write_array(struct cam_sw_info *info)
+{
+	if (IS_ERR_OR_NULL(info) || !info->write_array) {
+		pr_err("%s param is null\n", __func__);
+		return -EINVAL;
+	}
+
+	info->write_array(info->client, info->array_regs);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cam_sw_write_array);
+
+int cam_sw_prepare_wakeup(struct cam_sw_info *info, struct device *dev)
+{
+	int ret = 0;
+
+	if (!IS_ERR_OR_NULL(info->pin.pins_default)) {
+		ret = pinctrl_select_state(info->pin.pinctrl,
+					   info->pin.pins_default);
+		if (ret < 0)
+			dev_err(dev, "could not set pins\n");
+	}
+
+	if (clk_set_rate(info->clk.xvclk, info->clk.clk_freq) < 0)
+		dev_warn(dev, "clk_set_rate fail!");
+
+	if (clk_get_rate(info->clk.xvclk) != info->clk.clk_freq)
+		dev_warn(dev, "clk_get_rate fail!");
+
+	if (clk_prepare_enable(info->clk.xvclk) < 0) {
+		dev_err(dev, "clk_prepare_enable fail!");
+		return -EINVAL;
+	}
+
+	if (!IS_ERR(info->pin.reset_gpio))
+		gpiod_set_value_cansleep(info->pin.reset_gpio, info->pin.reset_active_state);
+
+	if (!IS_ERR(info->pin.supplies) && info->pin.supplies_num) {
+		ret = regulator_bulk_enable(info->pin.supplies_num, info->pin.supplies);
+		if (ret != 0)
+			dev_err(dev, "regulator_bulk_enable fail");
+	}
+
+	if (!IS_ERR(info->pin.reset_gpio))
+		gpiod_set_value_cansleep(info->pin.reset_gpio, !info->pin.reset_active_state);
+
+	if (!IS_ERR(info->pin.pwdn_gpio))
+		gpiod_set_value_cansleep(info->pin.pwdn_gpio, info->pin.pwdn_active_state);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cam_sw_prepare_wakeup);
+
+int cam_sw_prepare_sleep(struct cam_sw_info *info)
+{
+	if (!IS_ERR(info->clk.xvclk))
+		clk_disable_unprepare(info->clk.xvclk);
+
+	if (!IS_ERR(info->pin.pwdn_gpio))
+		gpiod_set_value_cansleep(info->pin.pwdn_gpio, !info->pin.pwdn_active_state);
+
+	if (!IS_ERR(info->pin.reset_gpio))
+		gpiod_set_value_cansleep(info->pin.reset_gpio, !info->pin.reset_active_state);
+
+	if (!IS_ERR_OR_NULL(info->pin.pins_sleep))
+		pinctrl_select_state(info->pin.pinctrl, info->pin.pins_sleep);
+
+	if (!IS_ERR(info->pin.supplies) && info->pin.supplies_num)
+		regulator_bulk_disable(info->pin.supplies_num, info->pin.supplies);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cam_sw_prepare_sleep);
+
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/cam-sleep-wakeup.h b/kernel/drivers/media/i2c/cam-sleep-wakeup.h
new file mode 100644
index 0000000..827b48a
--- /dev/null
+++ b/kernel/drivers/media/i2c/cam-sleep-wakeup.h
@@ -0,0 +1,131 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2023 Rockchip Electronics Co., Ltd. */
+
+#ifndef CAM_SLEEP_WAKEUP_H
+#define CAM_SLEEP_WAKEUP_H
+
+#include <linux/types.h>
+
+typedef int (*sensor_write_array)(struct i2c_client *, void *);
+
+struct sensor_clk_obj {
+	struct clk *xvclk;
+	u32 clk_freq;
+};
+
+struct sensor_pin_obj {
+	struct pinctrl *pinctrl;
+	struct pinctrl_state *pins_default;
+	struct pinctrl_state *pins_sleep;
+	bool reset_active_state;
+	bool pwdn_active_state;
+	struct gpio_desc *reset_gpio;
+	struct gpio_desc *pwdn_gpio;
+	int supplies_num;
+	struct regulator_bulk_data *supplies;
+};
+
+struct cam_sw_info {
+	phys_addr_t phys;
+	struct sensor_clk_obj clk;
+	struct sensor_pin_obj pin;
+	struct i2c_client *client;
+	void *array_regs;
+	struct preisp_hdrae_exp_s hdr_ae;
+	sensor_write_array write_array;
+};
+
+#if IS_REACHABLE(CONFIG_VIDEO_CAM_SLEEP_WAKEUP)
+struct cam_sw_info *cam_sw_init(void);
+int cam_sw_deinit(struct cam_sw_info *info);
+int cam_sw_clk_init(struct cam_sw_info *info, struct clk *xvclk, u32 clk_freq);
+int cam_sw_reset_pin_init(struct cam_sw_info *info,
+			  struct gpio_desc *reset_gpio,
+			  bool reset_active_state);
+int cam_sw_pwdn_pin_init(struct cam_sw_info *info, struct gpio_desc *pwdn_gpio,
+			 bool pwdn_active_state);
+int cam_sw_pinctrl_init(struct cam_sw_info *info, struct pinctrl *pinctrl,
+			struct pinctrl_state *pins_default,
+			struct pinctrl_state *pins_sleep);
+int cam_sw_regulator_bulk_init(struct cam_sw_info *info, int supplies_num,
+			       struct regulator_bulk_data *supplies);
+int cam_sw_write_array_cb_init(struct cam_sw_info *info,
+			       struct i2c_client *client, void *array_regs,
+			       sensor_write_array write_array);
+int cam_sw_write_array(struct cam_sw_info *info);
+int cam_sw_prepare_wakeup(struct cam_sw_info *info, struct device *dev);
+int cam_sw_prepare_sleep(struct cam_sw_info *info);
+
+#else
+
+static inline struct cam_sw_info *cam_sw_init(void)
+{
+	return NULL;
+}
+
+static inline int cam_sw_deinit(struct cam_sw_info *info)
+{
+	return 0;
+}
+
+static inline int cam_sw_clk_init(struct cam_sw_info *info, struct clk *xvclk,
+				  u32 clk_freq)
+{
+	return 0;
+}
+
+static inline int cam_sw_reset_pin_init(struct cam_sw_info *info,
+					struct gpio_desc *reset_gpio,
+					bool reset_active_state)
+{
+	return 0;
+}
+
+static inline int cam_sw_pwdn_pin_init(struct cam_sw_info *info,
+				       struct gpio_desc *pwdn_gpio,
+				       bool pwdn_active_state)
+{
+	return 0;
+}
+
+static inline int cam_sw_pinctrl_init(struct cam_sw_info *info,
+				      struct pinctrl *pinctrl,
+				      struct pinctrl_state *pins_default,
+				      struct pinctrl_state *pins_sleep)
+{
+	return 0;
+}
+
+static inline int
+cam_sw_regulator_bulk_init(struct cam_sw_info *info, int supplies_num,
+			   struct regulator_bulk_data *supplies)
+{
+	return 0;
+}
+
+static inline int cam_sw_write_array_cb_init(struct cam_sw_info *info,
+					     struct i2c_client *client,
+					     void *array_regs,
+					     sensor_write_array write_array)
+{
+	return 0;
+}
+
+static inline int cam_sw_write_array(struct cam_sw_info *info)
+{
+	return 0;
+}
+
+static inline int cam_sw_prepare_wakeup(struct cam_sw_info *info,
+					struct device *dev)
+{
+	return 0;
+}
+
+static inline int cam_sw_prepare_sleep(struct cam_sw_info *info)
+{
+	return 0;
+}
+
+#endif
+#endif
diff --git a/kernel/drivers/media/i2c/cam-tb-setup.c b/kernel/drivers/media/i2c/cam-tb-setup.c
new file mode 100644
index 0000000..e300dc6
--- /dev/null
+++ b/kernel/drivers/media/i2c/cam-tb-setup.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2023 Rockchip Electronics Co., Ltd
+
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include "cam-tb-setup.h"
+
+static u32 rk_cam_w;
+static u32 rk_cam_h;
+static u32 rk_cam_hdr;
+static u32 rk_cam_fps;
+
+static int __init rk_cam_w_setup(char *str)
+{
+	int ret = 0;
+	unsigned long val = 0;
+
+	ret = kstrtoul(str, 0, &val);
+	if (!ret)
+		rk_cam_w = (u32)val;
+	else
+		pr_err("get rk_cam_w fail\n");
+
+	return 0;
+}
+
+u32 get_rk_cam_w(void)
+{
+	return rk_cam_w;
+}
+EXPORT_SYMBOL(get_rk_cam_w);
+
+static int __init rk_cam_h_setup(char *str)
+{
+	int ret = 0;
+	unsigned long val = 0;
+
+	ret = kstrtoul(str, 0, &val);
+	if (!ret)
+		rk_cam_h = (u32)val;
+	else
+		pr_err("get rk_cam_h fail\n");
+
+	return 0;
+}
+
+u32 get_rk_cam_h(void)
+{
+	return rk_cam_h;
+}
+EXPORT_SYMBOL(get_rk_cam_h);
+
+static int __init rk_cam_hdr_setup(char *str)
+{
+	int ret = 0;
+	unsigned long val = 0;
+
+	ret = kstrtoul(str, 0, &val);
+	if (!ret)
+		rk_cam_hdr = (u32)val;
+	else
+		pr_err("get rk_cam_hdr fail\n");
+
+	return 0;
+}
+
+u32 get_rk_cam_hdr(void)
+{
+	return rk_cam_hdr;
+}
+EXPORT_SYMBOL(get_rk_cam_hdr);
+
+static int __init __maybe_unused rk_cam_fps_setup(char *str)
+{
+	int ret = 0;
+	unsigned long val = 0;
+
+	ret = kstrtoul(str, 0, &val);
+	if (!ret)
+		rk_cam_fps = (u32)val;
+	else
+		pr_err("get rk_cam_fps fail\n");
+
+	return 0;
+}
+
+u32 get_rk_cam_fps(void)
+{
+	return rk_cam_fps;
+}
+EXPORT_SYMBOL(get_rk_cam_fps);
+
+__setup("rk_cam_w=", rk_cam_w_setup);
+__setup("rk_cam_h=", rk_cam_h_setup);
+__setup("rk_cam_hdr=", rk_cam_hdr_setup);
+__setup("rk_cam_fps=", rk_cam_fps_setup);
diff --git a/kernel/drivers/media/i2c/cam-tb-setup.h b/kernel/drivers/media/i2c/cam-tb-setup.h
new file mode 100644
index 0000000..61afc32
--- /dev/null
+++ b/kernel/drivers/media/i2c/cam-tb-setup.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2023 Rockchip Electronics Co., Ltd. */
+
+#ifndef CAM_TB_SETUP_H
+#define CAM_TB_SETUP_H
+
+#include <linux/types.h>
+
+#ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
+u32 get_rk_cam_w(void);
+u32 get_rk_cam_h(void);
+u32 get_rk_cam_hdr(void);
+u32 get_rk_cam_fps(void);
+#else
+static inline u32 get_rk_cam_w(void)
+{
+	return 0;
+}
+static inline u32 get_rk_cam_h(void)
+{
+	return 0;
+}
+static inline u32 get_rk_cam_hdr(void)
+{
+	return 0;
+}
+static inline u32 get_rk_cam_fps(void)
+{
+	return 0;
+}
+#endif
+
+#endif
diff --git a/kernel/drivers/media/i2c/dw9800v.c b/kernel/drivers/media/i2c/dw9800v.c
new file mode 100644
index 0000000..79a2a56
--- /dev/null
+++ b/kernel/drivers/media/i2c/dw9800v.c
@@ -0,0 +1,1068 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dw9800v vcm driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ */
+//#define DEBUG
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/rk-camera-module.h>
+#include <linux/version.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <linux/rk_vcm_head.h>
+#include <linux/compat.h>
+#include <linux/regulator/consumer.h>
+
+#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x0)
+#define DW9800V_NAME			"dw9800v"
+
+#define DW9800V_MAX_CURRENT		1023U
+#define DW9800V_MAX_REG			1023U
+#define DW9800V_GRADUAL_MOVELENS_STEPS	32
+
+#define DW9800V_DEFAULT_START_CURRENT	553
+#define DW9800V_DEFAULT_RATED_CURRENT	853
+#define DW9800V_DEFAULT_STEP_MODE	0x0
+#define DW9800V_DEFAULT_T_SACT		0x10
+#define DW9800V_DEFAULT_T_DIV		0x1
+#define REG_NULL			0xFF
+
+#define DW9800V_ADVMODE_VCM_MSB		0x03
+#define DW9800V_ADVMODE_VCM_LSB		0x04
+#define DW9800V_ADVMODE_STATUS		0x05
+
+#define DW9800V_CHIP_ID			0xEB
+#define DW9800V_REG_CHIP_ID		0x00
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "debug level (0-2)");
+
+enum mode_e {
+	SAC2_MODE,
+	SAC3_MODE,
+	SAC4_MODE,
+	SAC5_MODE,
+	DIRECT_MODE,
+	LSC_MODE,
+};
+
+/* dw9800v device structure */
+struct dw9800v_device {
+	struct v4l2_ctrl_handler ctrls_vcm;
+	struct v4l2_ctrl *focus;
+	struct v4l2_subdev sd;
+	struct v4l2_device vdev;
+	u16 current_val;
+
+	struct gpio_desc *power_gpio;
+	unsigned short current_related_pos;
+	unsigned short current_lens_pos;
+	unsigned int start_current;
+	unsigned int rated_current;
+	unsigned int step;
+	unsigned int step_mode;
+	unsigned int vcm_movefull_t;
+	unsigned int t_src;
+	unsigned int t_div;
+	unsigned int max_logicalpos;
+
+	struct __kernel_old_timeval start_move_tv;
+	struct __kernel_old_timeval end_move_tv;
+	unsigned long move_us;
+
+	u32 module_index;
+	const char *module_facing;
+	struct rk_cam_vcm_cfg vcm_cfg;
+	int max_ma;
+
+	struct gpio_desc *xsd_gpio;
+	struct regulator *supply;
+	struct i2c_client *client;
+	bool power_on;
+
+};
+
+static inline struct dw9800v_device *to_dw9800v_vcm(struct v4l2_ctrl *ctrl)
+{
+	return container_of(ctrl->handler, struct dw9800v_device, ctrls_vcm);
+}
+
+static inline struct dw9800v_device *sd_to_dw9800v_vcm(struct v4l2_subdev *subdev)
+{
+	return container_of(subdev, struct dw9800v_device, sd);
+}
+
+static int dw9800v_write_reg(struct i2c_client *client, u8 reg,
+			    u32 len, u32 val)
+{
+	u32 buf_i, val_i;
+	u8 buf[5];
+	u8 *val_p;
+	__be32 val_be;
+
+	if (len > 4)
+		return -EINVAL;
+
+	buf[0] = reg;
+
+	val_be = cpu_to_be32(val);
+	val_p = (u8 *)&val_be;
+	buf_i = 1;
+	val_i = 4 - len;
+
+	while (val_i < 4)
+		buf[buf_i++] = val_p[val_i++];
+
+	if (i2c_master_send(client, buf, len + 1) != len + 1) {
+		dev_err(&client->dev, "Failed to write 0x%04x,0x%x\n", reg, val);
+		return -EIO;
+	}
+	return 0;
+}
+
+static int dw9800v_read_reg(struct i2c_client *client,
+			    u8 reg,
+			    unsigned int len,
+			    u32 *val)
+{
+	struct i2c_msg msgs[2];
+	u8 *data_be_p;
+	__be32 data_be = 0;
+	int ret;
+
+	if (len > 4 || !len)
+		return -EINVAL;
+
+	data_be_p = (u8 *)&data_be;
+	/* Write register address */
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = 1;
+	msgs[0].buf = (u8 *)&reg;
+
+	/* Read data from register */
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = len;
+	msgs[1].buf = &data_be_p[4 - len];
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs))
+		return -EIO;
+
+	*val = be32_to_cpu(data_be);
+
+	return 0;
+}
+
+static unsigned int dw9800v_move_time_div(struct dw9800v_device *dev_vcm,
+					 unsigned int move_time_us)
+{
+	struct i2c_client *client = dev_vcm->client;
+	unsigned int move_time = 0;
+
+	switch (dev_vcm->t_div) {
+	case 0:
+		move_time = move_time_us * 2;
+		break;
+	case 1:
+		move_time = move_time_us;
+		break;
+	case 2:
+		move_time = move_time_us / 2;
+		break;
+	case 3:
+		move_time = move_time_us / 4;
+		break;
+	case 4:
+		move_time = move_time_us * 8;
+		break;
+	case 5:
+		move_time = move_time_us * 4;
+		break;
+	default:
+		dev_err(&client->dev,
+			"%s: t_div parameter err %d\n",
+			__func__, dev_vcm->t_div);
+		break;
+	}
+	return move_time;
+}
+
+static unsigned int dw9800v_move_time(struct dw9800v_device *dev_vcm,
+	unsigned int move_pos)
+{
+	struct i2c_client *client = dev_vcm->client;
+	unsigned int move_time_us = 0;
+
+	switch (dev_vcm->step_mode) {
+	case LSC_MODE:
+		move_time_us = 252 + dev_vcm->t_src * 4;
+		move_time_us = move_time_us * move_pos;
+		break;
+	case SAC2_MODE:
+	case SAC3_MODE:
+	case SAC4_MODE:
+	case SAC5_MODE:
+		move_time_us = 6300 + dev_vcm->t_src * 100;
+		move_time_us = dw9800v_move_time_div(dev_vcm, move_time_us);
+		break;
+	case DIRECT_MODE:
+		move_time_us = 30000;
+		break;
+	default:
+		dev_err(&client->dev,
+			"%s: step_mode is error %d\n",
+			__func__, dev_vcm->step_mode);
+		break;
+	}
+
+	dev_info(&client->dev,
+		"%s: vcm_movefull_t is: %d us\n",
+		__func__, move_time_us);
+
+	return move_time_us;
+}
+
+static int dw9800v_set_dac(struct dw9800v_device *dev_vcm,
+	unsigned int dest_dac)
+{
+	struct i2c_client *client = dev_vcm->client;
+	int ret;
+
+	unsigned int i;
+	bool vcm_idle = false;
+
+	/* wait for I2C bus idle */
+	vcm_idle = false;
+	for (i = 0; i < 10; i++) {
+		unsigned int status = 0;
+
+		dw9800v_read_reg(client, DW9800V_ADVMODE_STATUS, 1, &status);
+		status &= 0x01;
+		if (status == 0) {
+			vcm_idle = true;
+			break;
+		}
+		usleep_range(1000, 1200);
+	}
+
+	if (!vcm_idle) {
+		dev_err(&client->dev,
+			"%s: watting 0x05 flag timeout!\n", __func__);
+		return -ETIMEDOUT;
+	}
+
+	/* vcm move */
+	ret = dw9800v_write_reg(client, DW9800V_ADVMODE_VCM_MSB,
+				2, dest_dac);
+	if (ret != 0)
+		goto err;
+
+	return ret;
+err:
+	dev_err(&client->dev,
+		"%s: failed with error %d\n", __func__, ret);
+	return ret;
+}
+
+static int dw9800v_get_pos(struct dw9800v_device *dev_vcm,
+	unsigned int *cur_pos)
+{
+	struct i2c_client *client = dev_vcm->client;
+	int ret;
+	unsigned int dac, abs_step;
+
+
+	ret = dw9800v_read_reg(client, 0x03, 2, &dac);
+	if (ret != 0)
+		goto err;
+
+	if (dac <= dev_vcm->start_current)
+		abs_step = dev_vcm->max_logicalpos;
+	else if ((dac > dev_vcm->start_current) &&
+		 (dac <= dev_vcm->rated_current))
+		abs_step = (dev_vcm->rated_current - dac) / dev_vcm->step;
+	else
+		abs_step = 0;
+
+	*cur_pos = abs_step;
+	v4l2_dbg(1, debug, &dev_vcm->sd, "%s: get position %d, dac %d\n",
+		 __func__, *cur_pos, dac);
+	return 0;
+
+err:
+	dev_err(&client->dev,
+		"%s: failed with error %d\n", __func__, ret);
+	return ret;
+}
+
+static int dw9800v_set_pos(struct dw9800v_device *dev_vcm,
+	unsigned int dest_pos)
+{
+	int ret;
+	unsigned int position = 0;
+	struct i2c_client *client = dev_vcm->client;
+	u32 is_busy, i;
+
+	if (dest_pos >= dev_vcm->max_logicalpos)
+		position = dev_vcm->start_current;
+	else
+		position = dev_vcm->start_current +
+			   (dev_vcm->step * (dev_vcm->max_logicalpos - dest_pos));
+
+	if (position > DW9800V_MAX_REG)
+		position = DW9800V_MAX_REG;
+
+	dev_vcm->current_lens_pos = position;
+	dev_vcm->current_related_pos = dest_pos;
+	for (i = 0; i < 100; i++) {
+		ret = dw9800v_read_reg(client, 0x05, 1, &is_busy);
+		if (!ret && !(is_busy & 0x01))
+			break;
+		usleep_range(100, 200);
+	}
+
+	ret = dw9800v_write_reg(client, 0x03, 2, dev_vcm->current_lens_pos);
+	if (ret != 0)
+		goto err;
+	v4l2_dbg(1, debug, &dev_vcm->sd, "%s: set position %d, dac %d\n",
+		 __func__, dest_pos, position);
+
+	return ret;
+err:
+	dev_err(&client->dev,
+		"%s: failed with error %d\n", __func__, ret);
+	return ret;
+}
+
+static int dw9800v_get_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct dw9800v_device *dev_vcm = to_dw9800v_vcm(ctrl);
+
+	if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE)
+		return dw9800v_get_pos(dev_vcm, &ctrl->val);
+
+	return -EINVAL;
+}
+
+static int dw9800v_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct dw9800v_device *dev_vcm = to_dw9800v_vcm(ctrl);
+	struct i2c_client *client = dev_vcm->client;
+	unsigned int dest_pos = ctrl->val;
+	int move_pos;
+	long mv_us;
+	int ret = 0;
+
+	if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE) {
+
+		if (dest_pos > dev_vcm->max_logicalpos) {
+			dev_info(&client->dev,
+				"%s dest_pos is error. %d > %d\n",
+				__func__, dest_pos, dev_vcm->max_logicalpos);
+			return -EINVAL;
+		}
+		/* calculate move time */
+		move_pos = dev_vcm->current_related_pos - dest_pos;
+		if (move_pos < 0)
+			move_pos = -move_pos;
+
+		ret = dw9800v_set_pos(dev_vcm, dest_pos);
+		if (dev_vcm->step_mode == LSC_MODE)
+			dev_vcm->move_us = ((dev_vcm->vcm_movefull_t * (uint32_t)move_pos) /
+					   dev_vcm->max_logicalpos);
+		else
+			dev_vcm->move_us = dev_vcm->vcm_movefull_t;
+
+		v4l2_dbg(1, debug, &dev_vcm->sd,
+			"dest_pos %d, move_us %ld\n",
+			dest_pos, dev_vcm->move_us);
+
+		dev_vcm->start_move_tv = ns_to_kernel_old_timeval(ktime_get_ns());
+		mv_us = dev_vcm->start_move_tv.tv_usec +
+				dev_vcm->move_us;
+		if (mv_us >= 1000000) {
+			dev_vcm->end_move_tv.tv_sec =
+				dev_vcm->start_move_tv.tv_sec + 1;
+			dev_vcm->end_move_tv.tv_usec = mv_us - 1000000;
+		} else {
+			dev_vcm->end_move_tv.tv_sec =
+					dev_vcm->start_move_tv.tv_sec;
+			dev_vcm->end_move_tv.tv_usec = mv_us;
+		}
+	}
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops dw9800v_vcm_ctrl_ops = {
+	.g_volatile_ctrl = dw9800v_get_ctrl,
+	.s_ctrl = dw9800v_set_ctrl,
+};
+
+static int dw9800v_init(struct i2c_client *client);
+
+static int dw9800v_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	int rval;
+	struct dw9800v_device *dev_vcm = sd_to_dw9800v_vcm(sd);
+	unsigned int move_time;
+	int dac = dev_vcm->start_current;
+	struct i2c_client *client = dev_vcm->client;
+
+#ifdef CONFIG_PM
+	v4l2_info(sd, "%s: enter,  power.usage_count(%d)!\n", __func__,
+		  atomic_read(&sd->dev->power.usage_count));
+#endif
+
+	rval = pm_runtime_get_sync(sd->dev);
+	if (rval < 0) {
+		pm_runtime_put_noidle(sd->dev);
+		return rval;
+	}
+	dw9800v_init(client);
+
+	usleep_range(1000, 1200);
+	v4l2_dbg(1, debug, sd, "%s: current_lens_pos %d, current_related_pos %d\n",
+		 __func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos);
+
+	move_time = dw9800v_move_time(dev_vcm, DW9800V_GRADUAL_MOVELENS_STEPS);
+	while (dac <= dev_vcm->current_lens_pos) {
+		dw9800v_set_dac(dev_vcm, dac);
+		usleep_range(move_time, move_time + 1000);
+		dac += DW9800V_GRADUAL_MOVELENS_STEPS;
+		if (dac >= dev_vcm->current_lens_pos)
+			break;
+	}
+
+	if (dac > dev_vcm->current_lens_pos) {
+		dac = dev_vcm->current_lens_pos;
+		dw9800v_set_dac(dev_vcm, dac);
+	}
+
+#ifdef CONFIG_PM
+	v4l2_info(sd, "%s: exit,  power.usage_count(%d)!\n", __func__,
+		  atomic_read(&sd->dev->power.usage_count));
+#endif
+
+	return 0;
+}
+
+static int dw9800v_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct dw9800v_device *dev_vcm = sd_to_dw9800v_vcm(sd);
+	int dac = dev_vcm->current_lens_pos;
+	unsigned int move_time;
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+#ifdef CONFIG_PM
+	v4l2_info(sd, "%s: enter,  power.usage_count(%d)!\n", __func__,
+		  atomic_read(&sd->dev->power.usage_count));
+#endif
+	v4l2_dbg(1, debug, sd, "%s: current_lens_pos %d, current_related_pos %d\n",
+		 __func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos);
+	move_time = dw9800v_move_time(dev_vcm, DW9800V_GRADUAL_MOVELENS_STEPS);
+	while (dac >= DW9800V_GRADUAL_MOVELENS_STEPS) {
+		dw9800v_set_dac(dev_vcm, dac);
+		usleep_range(move_time, move_time + 1000);
+		dac -= DW9800V_GRADUAL_MOVELENS_STEPS;
+		if (dac <= 0)
+			break;
+	}
+
+	if (dac < DW9800V_GRADUAL_MOVELENS_STEPS) {
+		dac = DW9800V_GRADUAL_MOVELENS_STEPS;
+		dw9800v_set_dac(dev_vcm, dac);
+	}
+	/* set to power down mode */
+	dw9800v_write_reg(client, 0x02, 1, 0x01);
+
+	pm_runtime_put(sd->dev);
+
+#ifdef CONFIG_PM
+	v4l2_info(sd, "%s: exit,  power.usage_count(%d)!\n", __func__,
+		  atomic_read(&sd->dev->power.usage_count));
+#endif
+
+	return 0;
+}
+
+static const struct v4l2_subdev_internal_ops dw9800v_int_ops = {
+	.open = dw9800v_open,
+	.close = dw9800v_close,
+};
+
+static void dw9800v_update_vcm_cfg(struct dw9800v_device *dev_vcm)
+{
+	struct i2c_client *client = dev_vcm->client;
+	int cur_dist;
+
+	if (dev_vcm->max_ma == 0) {
+		dev_err(&client->dev, "max current is zero");
+		return;
+	}
+
+	cur_dist = dev_vcm->vcm_cfg.rated_ma - dev_vcm->vcm_cfg.start_ma;
+	cur_dist = cur_dist * DW9800V_MAX_REG / dev_vcm->max_ma;
+	dev_vcm->step = (cur_dist + (dev_vcm->max_logicalpos - 1)) / dev_vcm->max_logicalpos;
+	dev_vcm->start_current = dev_vcm->vcm_cfg.start_ma *
+				 DW9800V_MAX_REG / dev_vcm->max_ma;
+	dev_vcm->rated_current = dev_vcm->vcm_cfg.rated_ma *
+				 DW9800V_MAX_REG / dev_vcm->max_ma;
+	dev_vcm->step_mode = dev_vcm->vcm_cfg.step_mode;
+
+	v4l2_dbg(1, debug, &dev_vcm->sd,
+		"vcm_cfg: %d, %d, %d, max_ma %d\n",
+		dev_vcm->vcm_cfg.start_ma,
+		dev_vcm->vcm_cfg.rated_ma,
+		dev_vcm->vcm_cfg.step_mode,
+		dev_vcm->max_ma);
+}
+
+static long dw9800v_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	struct dw9800v_device *dev_vcm = sd_to_dw9800v_vcm(sd);
+	struct i2c_client *client = dev_vcm->client;
+	struct rk_cam_vcm_tim *vcm_tim;
+	struct rk_cam_vcm_cfg *vcm_cfg;
+	unsigned int max_logicalpos;
+	int ret = 0;
+
+	if (cmd == RK_VIDIOC_VCM_TIMEINFO) {
+		vcm_tim = (struct rk_cam_vcm_tim *)arg;
+
+		vcm_tim->vcm_start_t.tv_sec = dev_vcm->start_move_tv.tv_sec;
+		vcm_tim->vcm_start_t.tv_usec =
+				dev_vcm->start_move_tv.tv_usec;
+		vcm_tim->vcm_end_t.tv_sec = dev_vcm->end_move_tv.tv_sec;
+		vcm_tim->vcm_end_t.tv_usec = dev_vcm->end_move_tv.tv_usec;
+
+		v4l2_dbg(1, debug, sd, "dw9800v_get_move_res 0x%lx, 0x%lx, 0x%lx, 0x%lx\n",
+			vcm_tim->vcm_start_t.tv_sec,
+			vcm_tim->vcm_start_t.tv_usec,
+			vcm_tim->vcm_end_t.tv_sec,
+			vcm_tim->vcm_end_t.tv_usec);
+	} else if (cmd == RK_VIDIOC_GET_VCM_CFG) {
+		vcm_cfg = (struct rk_cam_vcm_cfg *)arg;
+
+		vcm_cfg->start_ma = dev_vcm->vcm_cfg.start_ma;
+		vcm_cfg->rated_ma = dev_vcm->vcm_cfg.rated_ma;
+		vcm_cfg->step_mode = dev_vcm->vcm_cfg.step_mode;
+	} else if (cmd == RK_VIDIOC_SET_VCM_CFG) {
+		vcm_cfg = (struct rk_cam_vcm_cfg *)arg;
+
+		if (vcm_cfg->start_ma == 0 && vcm_cfg->rated_ma == 0) {
+			dev_err(&client->dev,
+				"vcm_cfg err, start_ma %d, rated_ma %d\n",
+				vcm_cfg->start_ma, vcm_cfg->rated_ma);
+			return -EINVAL;
+		}
+		if (vcm_cfg->rated_ma > DW9800V_MAX_CURRENT) {
+			dev_warn(&client->dev,
+				 "vcm_cfg use dac value, do convert!\n");
+			vcm_cfg->rated_ma = vcm_cfg->rated_ma *
+					    dev_vcm->max_ma / DW9800V_MAX_REG;
+			vcm_cfg->start_ma = vcm_cfg->start_ma *
+					    dev_vcm->max_ma / DW9800V_MAX_REG;
+		}
+
+		dev_vcm->vcm_cfg.start_ma = vcm_cfg->start_ma;
+		dev_vcm->vcm_cfg.rated_ma = vcm_cfg->rated_ma;
+		dev_vcm->vcm_cfg.step_mode = vcm_cfg->step_mode;
+		dw9800v_update_vcm_cfg(dev_vcm);
+	} else if (cmd == RK_VIDIOC_SET_VCM_MAX_LOGICALPOS) {
+		max_logicalpos = *(unsigned int *)arg;
+
+		if (max_logicalpos > 0) {
+			dev_vcm->max_logicalpos = max_logicalpos;
+			__v4l2_ctrl_modify_range(dev_vcm->focus,
+				0, dev_vcm->max_logicalpos, 1, dev_vcm->max_logicalpos);
+		}
+		v4l2_dbg(1, debug, &dev_vcm->sd,
+			"max_logicalpos %d\n", max_logicalpos);
+	} else {
+		dev_err(&client->dev,
+			"cmd 0x%x not supported\n", cmd);
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long dw9800v_compat_ioctl32(struct v4l2_subdev *sd,
+	unsigned int cmd, unsigned long arg)
+{
+	struct dw9800v_device *dev_vcm = sd_to_dw9800v_vcm(sd);
+	struct i2c_client *client = dev_vcm->client;
+	void __user *up = compat_ptr(arg);
+	struct rk_cam_compat_vcm_tim compat_vcm_tim;
+	struct rk_cam_vcm_tim vcm_tim;
+	struct rk_cam_vcm_cfg vcm_cfg;
+	unsigned int max_logicalpos;
+	long ret;
+
+	if (cmd == RK_VIDIOC_COMPAT_VCM_TIMEINFO) {
+		struct rk_cam_compat_vcm_tim __user *p32 = up;
+
+		ret = dw9800v_ioctl(sd, RK_VIDIOC_VCM_TIMEINFO, &vcm_tim);
+		compat_vcm_tim.vcm_start_t.tv_sec = vcm_tim.vcm_start_t.tv_sec;
+		compat_vcm_tim.vcm_start_t.tv_usec = vcm_tim.vcm_start_t.tv_usec;
+		compat_vcm_tim.vcm_end_t.tv_sec = vcm_tim.vcm_end_t.tv_sec;
+		compat_vcm_tim.vcm_end_t.tv_usec = vcm_tim.vcm_end_t.tv_usec;
+
+		put_user(compat_vcm_tim.vcm_start_t.tv_sec,
+			&p32->vcm_start_t.tv_sec);
+		put_user(compat_vcm_tim.vcm_start_t.tv_usec,
+			&p32->vcm_start_t.tv_usec);
+		put_user(compat_vcm_tim.vcm_end_t.tv_sec,
+			&p32->vcm_end_t.tv_sec);
+		put_user(compat_vcm_tim.vcm_end_t.tv_usec,
+			&p32->vcm_end_t.tv_usec);
+	} else if (cmd == RK_VIDIOC_GET_VCM_CFG) {
+		ret = dw9800v_ioctl(sd, RK_VIDIOC_GET_VCM_CFG, &vcm_cfg);
+		if (!ret) {
+			ret = copy_to_user(up, &vcm_cfg, sizeof(vcm_cfg));
+			if (ret)
+				ret = -EFAULT;
+		}
+	} else if (cmd == RK_VIDIOC_SET_VCM_CFG) {
+		ret = copy_from_user(&vcm_cfg, up, sizeof(vcm_cfg));
+		if (!ret)
+			ret = dw9800v_ioctl(sd, cmd, &vcm_cfg);
+		else
+			ret = -EFAULT;
+	} else if (cmd == RK_VIDIOC_SET_VCM_MAX_LOGICALPOS) {
+		ret = copy_from_user(&max_logicalpos, up, sizeof(max_logicalpos));
+		if (!ret)
+			ret = dw9800v_ioctl(sd, cmd, &max_logicalpos);
+		else
+			ret = -EFAULT;
+	} else {
+		dev_err(&client->dev,
+			"cmd 0x%x not supported\n", cmd);
+		return -EINVAL;
+	}
+
+	return ret;
+}
+#endif
+
+static const struct v4l2_subdev_core_ops dw9800v_core_ops = {
+	.ioctl = dw9800v_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl32 = dw9800v_compat_ioctl32
+#endif
+};
+
+static const struct v4l2_subdev_ops dw9800v_ops = {
+	.core = &dw9800v_core_ops,
+};
+
+static void dw9800v_subdev_cleanup(struct dw9800v_device *dw9800v_dev)
+{
+	v4l2_device_unregister_subdev(&dw9800v_dev->sd);
+	v4l2_device_unregister(&dw9800v_dev->vdev);
+	v4l2_ctrl_handler_free(&dw9800v_dev->ctrls_vcm);
+	media_entity_cleanup(&dw9800v_dev->sd.entity);
+}
+
+static int dw9800v_init_controls(struct dw9800v_device *dev_vcm)
+{
+	struct v4l2_ctrl_handler *hdl = &dev_vcm->ctrls_vcm;
+	const struct v4l2_ctrl_ops *ops = &dw9800v_vcm_ctrl_ops;
+
+	v4l2_ctrl_handler_init(hdl, 1);
+
+	dev_vcm->focus = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE,
+					   0, dev_vcm->max_logicalpos, 1, 0);
+
+	if (hdl->error)
+		dev_err(dev_vcm->sd.dev, "%s fail error: 0x%x\n",
+			__func__, hdl->error);
+	dev_vcm->sd.ctrl_handler = hdl;
+	return hdl->error;
+}
+
+static int __dw9800v_set_power(struct dw9800v_device *dw9800v, bool on)
+{
+	struct i2c_client *client = dw9800v->client;
+	int ret = 0;
+
+	dev_info(&client->dev, "%s(%d) on(%d)\n", __func__, __LINE__, on);
+
+	if (dw9800v->power_on == !!on)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = regulator_enable(dw9800v->supply);
+		if (ret < 0) {
+			dev_err(&client->dev, "Failed to enable regulator\n");
+			goto unlock_and_return;
+		}
+		dw9800v->power_on = true;
+	} else {
+		ret = regulator_disable(dw9800v->supply);
+		if (ret < 0) {
+			dev_err(&client->dev, "Failed to disable regulator\n");
+			goto unlock_and_return;
+		}
+		dw9800v->power_on = false;
+	}
+
+unlock_and_return:
+	return ret;
+}
+
+static int dw9800v_check_id(struct dw9800v_device *dw9800v_dev)
+{
+	int ret = 0;
+	unsigned int pid = 0x00;
+	struct i2c_client *client = dw9800v_dev->client;
+	struct device *dev = &client->dev;
+
+	__dw9800v_set_power(dw9800v_dev, true);
+	ret = dw9800v_read_reg(client, DW9800V_REG_CHIP_ID, 1, &pid);
+
+	if (pid != DW9800V_CHIP_ID) {
+		dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", pid, ret);
+		return -ENODEV;
+	}
+
+	dev_info(&dw9800v_dev->client->dev,
+		 "Detected dw9800v vcm id:0x%x\n", DW9800V_CHIP_ID);
+	return 0;
+}
+static int dw9800v_probe_init(struct i2c_client *client)
+{
+	int ret = 0;
+
+	/* Default goto power down mode when finished probe */
+	ret = dw9800v_write_reg(client, 0x02, 1, 0x01);
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	dev_err(&client->dev, "probe init failed with error %d\n", ret);
+	return -1;
+}
+
+static int dw9800v_configure_regulator(struct dw9800v_device *dw9800v)
+{
+	struct i2c_client *client = dw9800v->client;
+	int ret = 0;
+
+	dw9800v->supply = devm_regulator_get(&client->dev, "avdd");
+	if (IS_ERR(dw9800v->supply)) {
+		ret = PTR_ERR(dw9800v->supply);
+		if (ret != -EPROBE_DEFER)
+			dev_err(&client->dev, "could not get regulator avdd\n");
+		return ret;
+	}
+	dw9800v->power_on = false;
+	return ret;
+}
+static int dw9800v_parse_dt_property(struct i2c_client *client,
+				    struct dw9800v_device *dev_vcm)
+{
+	struct device_node *np = of_node_get(client->dev.of_node);
+	int ret;
+
+	if (of_property_read_u32(np,
+		OF_CAMERA_VCMDRV_MAX_CURRENT,
+		(unsigned int *)&dev_vcm->max_ma)) {
+		dev_vcm->max_ma = DW9800V_MAX_CURRENT;
+		dev_info(&client->dev,
+			"could not get module %s from dts!\n",
+			OF_CAMERA_VCMDRV_MAX_CURRENT);
+	}
+	if (dev_vcm->max_ma == 0)
+		dev_vcm->max_ma = DW9800V_MAX_CURRENT;
+
+	if (of_property_read_u32(np,
+		OF_CAMERA_VCMDRV_START_CURRENT,
+		(unsigned int *)&dev_vcm->vcm_cfg.start_ma)) {
+		dev_vcm->vcm_cfg.start_ma = DW9800V_DEFAULT_START_CURRENT;
+		dev_info(&client->dev,
+			"could not get module %s from dts!\n",
+			OF_CAMERA_VCMDRV_START_CURRENT);
+	}
+	if (of_property_read_u32(np,
+		OF_CAMERA_VCMDRV_RATED_CURRENT,
+		(unsigned int *)&dev_vcm->vcm_cfg.rated_ma)) {
+		dev_vcm->vcm_cfg.rated_ma = DW9800V_DEFAULT_RATED_CURRENT;
+		dev_info(&client->dev,
+			"could not get module %s from dts!\n",
+			OF_CAMERA_VCMDRV_RATED_CURRENT);
+	}
+	if (of_property_read_u32(np,
+		OF_CAMERA_VCMDRV_STEP_MODE,
+		(unsigned int *)&dev_vcm->vcm_cfg.step_mode)) {
+		dev_vcm->vcm_cfg.step_mode = DW9800V_DEFAULT_STEP_MODE;
+		dev_info(&client->dev,
+			"could not get module %s from dts!\n",
+			OF_CAMERA_VCMDRV_STEP_MODE);
+	}
+
+	if (of_property_read_u32(np,
+		OF_CAMERA_VCMDRV_T_SRC,
+		(unsigned int *)&dev_vcm->t_src)) {
+		dev_vcm->t_src = DW9800V_DEFAULT_T_SACT;
+		dev_info(&client->dev,
+			"could not get module %s from dts!\n",
+			OF_CAMERA_VCMDRV_T_SRC);
+	}
+
+	if (of_property_read_u32(np,
+		OF_CAMERA_VCMDRV_T_DIV,
+		(unsigned int *)&dev_vcm->t_div)) {
+		dev_vcm->t_div = DW9800V_DEFAULT_T_DIV;
+		dev_info(&client->dev,
+			"could not get module %s from dts!\n",
+			OF_CAMERA_VCMDRV_T_DIV);
+	}
+
+	dev_vcm->xsd_gpio = devm_gpiod_get(&client->dev, "xsd", GPIOD_OUT_HIGH);
+	if (IS_ERR(dev_vcm->xsd_gpio))
+		dev_warn(&client->dev, "Failed to get xsd-gpios\n");
+
+	ret = of_property_read_u32(np, RKMODULE_CAMERA_MODULE_INDEX,
+				   &dev_vcm->module_index);
+	ret |= of_property_read_string(np, RKMODULE_CAMERA_MODULE_FACING,
+					   &dev_vcm->module_facing);
+	if (ret) {
+		dev_err(&client->dev,
+			"could not get module information!\n");
+		return -EINVAL;
+	}
+	dev_vcm->client = client;
+	ret = dw9800v_configure_regulator(dev_vcm);
+	if (ret) {
+		dev_err(&client->dev, "Failed to get power regulator!\n");
+		return ret;
+	}
+
+	dev_info(&client->dev, "current: %d, %d, %d, t_div: %d, t_src: %d, step_mode: %d",
+		dev_vcm->max_ma,
+		dev_vcm->start_current,
+		dev_vcm->rated_current,
+		dev_vcm->t_div,
+		dev_vcm->t_src,
+		dev_vcm->vcm_cfg.step_mode);
+
+	return 0;
+}
+
+static int dw9800v_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct dw9800v_device *dw9800v_dev;
+	struct v4l2_subdev *sd;
+	char facing[2];
+	int ret;
+
+	dev_info(&client->dev, "probing...\n");
+	dw9800v_dev = devm_kzalloc(&client->dev, sizeof(*dw9800v_dev),
+				  GFP_KERNEL);
+	if (dw9800v_dev == NULL)
+		return -ENOMEM;
+
+	ret = dw9800v_parse_dt_property(client, dw9800v_dev);
+	if (ret)
+		return ret;
+
+	dw9800v_dev->client = client;
+
+	ret = dw9800v_check_id(dw9800v_dev);
+	if (ret)
+		goto err_power_off;
+
+	/* enter power down mode */
+	dw9800v_probe_init(client);
+
+	v4l2_i2c_subdev_init(&dw9800v_dev->sd, client, &dw9800v_ops);
+	dw9800v_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	dw9800v_dev->sd.internal_ops = &dw9800v_int_ops;
+
+	dw9800v_dev->max_logicalpos = VCMDRV_MAX_LOG;
+	ret = dw9800v_init_controls(dw9800v_dev);
+	if (ret)
+		goto err_cleanup;
+
+	ret = media_entity_pads_init(&dw9800v_dev->sd.entity, 0, NULL);
+	if (ret < 0)
+		goto err_cleanup;
+
+	sd = &dw9800v_dev->sd;
+	sd->entity.function = MEDIA_ENT_F_LENS;
+
+	memset(facing, 0, sizeof(facing));
+	if (strcmp(dw9800v_dev->module_facing, "back") == 0)
+		facing[0] = 'b';
+	else
+		facing[0] = 'f';
+
+	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
+		 dw9800v_dev->module_index, facing,
+		 DW9800V_NAME, dev_name(sd->dev));
+	ret = v4l2_async_register_subdev(sd);
+	if (ret)
+		dev_err(&client->dev, "v4l2 async register subdev failed\n");
+
+	dw9800v_update_vcm_cfg(dw9800v_dev);
+	dw9800v_dev->move_us	= 0;
+	dw9800v_dev->current_related_pos = VCMDRV_MAX_LOG;
+	dw9800v_dev->start_move_tv = ns_to_kernel_old_timeval(ktime_get_ns());
+	dw9800v_dev->end_move_tv = ns_to_kernel_old_timeval(ktime_get_ns());
+
+	i2c_set_clientdata(client, dw9800v_dev);
+
+	dw9800v_dev->vcm_movefull_t =
+		dw9800v_move_time(dw9800v_dev, DW9800V_MAX_REG);
+	pm_runtime_set_active(&client->dev);
+	pm_runtime_enable(&client->dev);
+	pm_runtime_idle(&client->dev);
+
+	dev_info(&client->dev, "probing successful\n");
+
+	return 0;
+err_cleanup:
+	dw9800v_subdev_cleanup(dw9800v_dev);
+err_power_off:
+	__dw9800v_set_power(dw9800v_dev, false);
+
+	dev_err(&client->dev, "Probe failed: %d\n", ret);
+
+	return ret;
+}
+
+static int dw9800v_remove(struct i2c_client *client)
+{
+	struct dw9800v_device *dw9800v_dev = i2c_get_clientdata(client);
+
+	pm_runtime_disable(&client->dev);
+	dw9800v_subdev_cleanup(dw9800v_dev);
+
+	return 0;
+}
+
+static int dw9800v_init(struct i2c_client *client)
+{
+	struct dw9800v_device *dev_vcm = i2c_get_clientdata(client);
+	int ret = 0;
+	u32 ring = 0;
+	u32 mode_val = 0;
+	u32 algo_time = 0;
+
+
+	/* Delay 200us~300us */
+	usleep_range(200, 300);
+	ret = dw9800v_write_reg(client, 0x02, 1, 0x00);
+	if (ret)
+		goto err;
+	usleep_range(100, 200);
+
+	if (dev_vcm->step_mode != DIRECT_MODE &&
+	    dev_vcm->step_mode != LSC_MODE)
+		ring = 0x02;
+	ret = dw9800v_write_reg(client, 0x02, 1, ring);
+	if (ret)
+		goto err;
+	switch (dev_vcm->step_mode) {
+	case SAC2_MODE:
+	case SAC3_MODE:
+	case SAC4_MODE:
+	case SAC5_MODE:
+		mode_val |= dev_vcm->step_mode << 6;
+		break;
+	case LSC_MODE:
+		mode_val |= 0x80;
+		break;
+	default:
+		break;
+	}
+	mode_val |= ((dev_vcm->t_div >> 2) & 0x01);
+	algo_time = dev_vcm->t_div << 6 | dev_vcm->t_src;
+	ret = dw9800v_write_reg(client, 0x06, 1, mode_val);
+	if (ret)
+		goto err;
+	ret = dw9800v_write_reg(client, 0x07, 1, algo_time);
+	if (ret)
+		goto err;
+	usleep_range(100, 200);
+
+	return 0;
+err:
+	dev_err(&client->dev, "init failed with error %d\n", ret);
+	return -1;
+}
+
+static int __maybe_unused dw9800v_vcm_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct dw9800v_device *dev_vcm = i2c_get_clientdata(client);
+	struct v4l2_subdev *sd = &dev_vcm->sd;
+
+#ifdef CONFIG_PM
+	v4l2_dbg(1, debug, sd, "%s: enter,	power.usage_count(%d)!\n", __func__,
+		 atomic_read(&sd->dev->power.usage_count));
+#endif
+
+	__dw9800v_set_power(dev_vcm, false);
+	return 0;
+}
+
+static int __maybe_unused dw9800v_vcm_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct dw9800v_device *dev_vcm = i2c_get_clientdata(client);
+	struct v4l2_subdev *sd = &dev_vcm->sd;
+
+#ifdef CONFIG_PM
+	v4l2_dbg(1, debug, sd, "%s: enter,	power.usage_count(%d)!\n", __func__,
+		 atomic_read(&sd->dev->power.usage_count));
+#endif
+
+	__dw9800v_set_power(dev_vcm, true);
+	return 0;
+}
+
+static const struct i2c_device_id dw9800v_id_table[] = {
+	{ DW9800V_NAME, 0 },
+	{ { 0 } }
+};
+MODULE_DEVICE_TABLE(i2c, dw9800v_id_table);
+
+static const struct of_device_id dw9800v_of_table[] = {
+	{ .compatible = "dongwoon,dw9800v" },
+	{ { 0 } }
+};
+MODULE_DEVICE_TABLE(of, dw9800v_of_table);
+
+static const struct dev_pm_ops dw9800v_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(dw9800v_vcm_suspend, dw9800v_vcm_resume)
+	SET_RUNTIME_PM_OPS(dw9800v_vcm_suspend, dw9800v_vcm_resume, NULL)
+};
+
+static struct i2c_driver dw9800v_i2c_driver = {
+	.driver = {
+		.name = DW9800V_NAME,
+		.pm = &dw9800v_pm_ops,
+		.of_match_table = dw9800v_of_table,
+	},
+	.probe = &dw9800v_probe,
+	.remove = &dw9800v_remove,
+	.id_table = dw9800v_id_table,
+};
+
+module_i2c_driver(dw9800v_i2c_driver);
+
+MODULE_DESCRIPTION("DW9800V VCM driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/dw9800w.c b/kernel/drivers/media/i2c/dw9800w.c
index 2b0729e..e104336 100644
--- a/kernel/drivers/media/i2c/dw9800w.c
+++ b/kernel/drivers/media/i2c/dw9800w.c
@@ -44,6 +44,7 @@
 /* dw9800w device structure */
 struct dw9800w_device {
 	struct v4l2_ctrl_handler ctrls_vcm;
+	struct v4l2_ctrl *focus;
 	struct i2c_client *client;
 	struct v4l2_subdev sd;
 	struct v4l2_device vdev;
@@ -52,13 +53,14 @@
 	struct gpio_desc *power_gpio;
 	unsigned short current_related_pos;
 	unsigned short current_lens_pos;
+	unsigned int max_current;
 	unsigned int start_current;
 	unsigned int rated_current;
-	unsigned int step;
 	unsigned int step_mode;
 	unsigned int vcm_movefull_t;
 	unsigned int t_src;
 	unsigned int t_div;
+	unsigned int max_logicalpos;
 
 	struct __kernel_old_timeval start_move_tv;
 	struct __kernel_old_timeval end_move_tv;
@@ -67,7 +69,6 @@
 	u32 module_index;
 	const char *module_facing;
 	struct rk_cam_vcm_cfg vcm_cfg;
-	int max_ma;
 	struct mutex lock;
 };
 
@@ -217,22 +218,25 @@
 	unsigned int *cur_pos)
 {
 	struct i2c_client *client = dev_vcm->client;
+	unsigned int dac, position, range;
 	int ret;
-	unsigned int abs_step;
 
-	ret = dw9800w_read_reg(client, 0x03, 2, &abs_step);
+	range = dev_vcm->rated_current - dev_vcm->start_current;
+	ret = dw9800w_read_reg(client, 0x03, 2, &dac);
 	if (ret != 0)
 		goto err;
 
-	if (abs_step <= dev_vcm->start_current)
-		abs_step = VCMDRV_MAX_LOG;
-	else if ((abs_step > dev_vcm->start_current) &&
-		 (abs_step <= dev_vcm->rated_current))
-		abs_step = (dev_vcm->rated_current - abs_step) / dev_vcm->step;
-	else
-		abs_step = 0;
+	if (dac <= dev_vcm->start_current) {
+		position = dev_vcm->max_logicalpos;
+	} else if ((dac > dev_vcm->start_current) &&
+		   (dac <= dev_vcm->rated_current)) {
+		position = (dac - dev_vcm->start_current) * dev_vcm->max_logicalpos / range;
+		position = dev_vcm->max_logicalpos - position;
+	} else {
+		position = 0;
+	}
 
-	*cur_pos = abs_step;
+	*cur_pos = position;
 	dev_dbg(&client->dev, "%s: get position %d\n", __func__, *cur_pos);
 	return 0;
 
@@ -245,16 +249,18 @@
 static int dw9800w_set_pos(struct dw9800w_device *dev_vcm,
 	unsigned int dest_pos)
 {
-	int ret;
-	unsigned int position = 0;
-	struct i2c_client *client = dev_vcm->client;
+	struct i2c_client *client = v4l2_get_subdevdata(&dev_vcm->sd);
+	unsigned int position;
+	unsigned int range;
 	u32 is_busy, i;
+	int ret;
 
-	if (dest_pos >= VCMDRV_MAX_LOG)
+	range = dev_vcm->rated_current - dev_vcm->start_current;
+	if (dest_pos >= dev_vcm->max_logicalpos)
 		position = dev_vcm->start_current;
 	else
 		position = dev_vcm->start_current +
-			   (dev_vcm->step * (VCMDRV_MAX_LOG - dest_pos));
+			   (range * (dev_vcm->max_logicalpos - dest_pos) / dev_vcm->max_logicalpos);
 
 	if (position > DW9800W_MAX_REG)
 		position = DW9800W_MAX_REG;
@@ -304,10 +310,10 @@
 
 	if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE) {
 
-		if (dest_pos > VCMDRV_MAX_LOG) {
+		if (dest_pos > dev_vcm->max_logicalpos) {
 			dev_info(&client->dev,
 				"%s dest_pos is error. %d > %d\n",
-				__func__, dest_pos, VCMDRV_MAX_LOG);
+				__func__, dest_pos, dev_vcm->max_logicalpos);
 			return -EINVAL;
 		}
 		/* calculate move time */
@@ -318,7 +324,7 @@
 		ret = dw9800w_set_pos(dev_vcm, dest_pos);
 		if (dev_vcm->step_mode == LSC_MODE)
 			dev_vcm->move_us = ((dev_vcm->vcm_movefull_t * (uint32_t)move_pos) /
-					   VCMDRV_MAX_LOG);
+					   dev_vcm->max_logicalpos);
 		else
 			dev_vcm->move_us = dev_vcm->vcm_movefull_t;
 
@@ -376,28 +382,27 @@
 static void dw9800w_update_vcm_cfg(struct dw9800w_device *dev_vcm)
 {
 	struct i2c_client *client = dev_vcm->client;
-	int cur_dist;
 
-	if (dev_vcm->max_ma == 0) {
+	if (dev_vcm->max_current == 0) {
 		dev_err(&client->dev, "max current is zero");
 		return;
 	}
 
-	cur_dist = dev_vcm->vcm_cfg.rated_ma - dev_vcm->vcm_cfg.start_ma;
-	cur_dist = cur_dist * DW9800W_MAX_REG / dev_vcm->max_ma;
-	dev_vcm->step = (cur_dist + (VCMDRV_MAX_LOG - 1)) / VCMDRV_MAX_LOG;
+	if (dev_vcm->vcm_cfg.rated_ma > dev_vcm->max_current)
+		dev_vcm->max_current = DW9800W_MAX_REG;
+
 	dev_vcm->start_current = dev_vcm->vcm_cfg.start_ma *
-				 DW9800W_MAX_REG / dev_vcm->max_ma;
+				 DW9800W_MAX_REG / dev_vcm->max_current;
 	dev_vcm->rated_current = dev_vcm->vcm_cfg.rated_ma *
-				 DW9800W_MAX_REG / dev_vcm->max_ma;
+				 DW9800W_MAX_REG / dev_vcm->max_current;
 	dev_vcm->step_mode = dev_vcm->vcm_cfg.step_mode;
 
 	dev_info(&client->dev,
-		"vcm_cfg: %d, %d, %d, max_ma %d\n",
+		"vcm_cfg: %d, %d, %d, max_current %d\n",
 		dev_vcm->vcm_cfg.start_ma,
 		dev_vcm->vcm_cfg.rated_ma,
 		dev_vcm->vcm_cfg.step_mode,
-		dev_vcm->max_ma);
+		dev_vcm->max_current);
 }
 
 static long dw9800w_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
@@ -406,6 +411,7 @@
 	struct i2c_client *client = dev_vcm->client;
 	struct rk_cam_vcm_tim *vcm_tim;
 	struct rk_cam_vcm_cfg *vcm_cfg;
+	unsigned int max_logicalpos;
 	int ret = 0;
 
 	if (cmd == RK_VIDIOC_VCM_TIMEINFO) {
@@ -441,6 +447,16 @@
 		dev_vcm->vcm_cfg.rated_ma = vcm_cfg->rated_ma;
 		dev_vcm->vcm_cfg.step_mode = vcm_cfg->step_mode;
 		dw9800w_update_vcm_cfg(dev_vcm);
+	} else if (cmd == RK_VIDIOC_SET_VCM_MAX_LOGICALPOS) {
+		max_logicalpos = *(unsigned int *)arg;
+
+		if (max_logicalpos > 0) {
+			dev_vcm->max_logicalpos = max_logicalpos;
+			__v4l2_ctrl_modify_range(dev_vcm->focus,
+				0, dev_vcm->max_logicalpos, 1, dev_vcm->max_logicalpos);
+		}
+		dev_dbg(&client->dev,
+			"max_logicalpos %d\n", max_logicalpos);
 	} else {
 		dev_err(&client->dev,
 			"cmd 0x%x not supported\n", cmd);
@@ -460,6 +476,7 @@
 	struct rk_cam_compat_vcm_tim compat_vcm_tim;
 	struct rk_cam_vcm_tim vcm_tim;
 	struct rk_cam_vcm_cfg vcm_cfg;
+	unsigned int max_logicalpos;
 	long ret;
 
 	if (cmd == RK_VIDIOC_COMPAT_VCM_TIMEINFO) {
@@ -490,6 +507,12 @@
 		ret = copy_from_user(&vcm_cfg, up, sizeof(vcm_cfg));
 		if (!ret)
 			ret = dw9800w_ioctl(sd, cmd, &vcm_cfg);
+		else
+			ret = -EFAULT;
+	} else if (cmd == RK_VIDIOC_SET_VCM_MAX_LOGICALPOS) {
+		ret = copy_from_user(&max_logicalpos, up, sizeof(max_logicalpos));
+		if (!ret)
+			ret = dw9800w_ioctl(sd, cmd, &max_logicalpos);
 		else
 			ret = -EFAULT;
 	} else {
@@ -528,8 +551,9 @@
 
 	v4l2_ctrl_handler_init(hdl, 1);
 
-	v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE,
-			  0, VCMDRV_MAX_LOG, 1, 32);
+	dev_vcm->focus = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE,
+					   0, dev_vcm->max_logicalpos, 1,
+					   dev_vcm->max_logicalpos / 2);
 
 	if (hdl->error)
 		dev_err(dev_vcm->sd.dev, "%s fail error: 0x%x\n",
@@ -585,7 +609,7 @@
 {
 	struct device_node *np = of_node_get(client->dev.of_node);
 	struct dw9800w_device *dw9800w_dev;
-	unsigned int max_ma, start_ma, rated_ma, step_mode;
+	unsigned int max_current, start_ma, rated_ma, step_mode;
 	unsigned int t_src, t_div;
 	struct v4l2_subdev *sd;
 	char facing[2];
@@ -594,14 +618,14 @@
 	dev_info(&client->dev, "probing...\n");
 	if (of_property_read_u32(np,
 		OF_CAMERA_VCMDRV_MAX_CURRENT,
-		(unsigned int *)&max_ma)) {
-		max_ma = DW9800W_MAX_CURRENT;
+		(unsigned int *)&max_current)) {
+		max_current = DW9800W_MAX_CURRENT;
 		dev_info(&client->dev,
 			"could not get module %s from dts!\n",
 			OF_CAMERA_VCMDRV_MAX_CURRENT);
 	}
-	if (max_ma == 0)
-		max_ma = DW9800W_MAX_CURRENT;
+	if (max_current == 0)
+		max_current = DW9800W_MAX_CURRENT;
 
 	if (of_property_read_u32(np,
 		OF_CAMERA_VCMDRV_START_CURRENT,
@@ -680,6 +704,7 @@
 	dw9800w_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	dw9800w_dev->sd.internal_ops = &dw9800w_int_ops;
 
+	dw9800w_dev->max_logicalpos = VCMDRV_MAX_LOG;
 	ret = dw9800w_init_controls(dw9800w_dev);
 	if (ret)
 		goto err_cleanup;
@@ -704,13 +729,13 @@
 	if (ret)
 		dev_err(&client->dev, "v4l2 async register subdev failed\n");
 
-	dw9800w_dev->max_ma = max_ma;
+	dw9800w_dev->max_current = max_current;
 	dw9800w_dev->vcm_cfg.start_ma = start_ma;
 	dw9800w_dev->vcm_cfg.rated_ma = rated_ma;
 	dw9800w_dev->vcm_cfg.step_mode = step_mode;
 	dw9800w_update_vcm_cfg(dw9800w_dev);
 	dw9800w_dev->move_us	= 0;
-	dw9800w_dev->current_related_pos = VCMDRV_MAX_LOG;
+	dw9800w_dev->current_related_pos = dw9800w_dev->max_logicalpos;
 	dw9800w_dev->start_move_tv = ns_to_kernel_old_timeval(ktime_get_ns());
 	dw9800w_dev->end_move_tv = ns_to_kernel_old_timeval(ktime_get_ns());
 
diff --git a/kernel/drivers/media/i2c/gc2093.c b/kernel/drivers/media/i2c/gc2093.c
index aa87a73..f612814 100644
--- a/kernel/drivers/media/i2c/gc2093.c
+++ b/kernel/drivers/media/i2c/gc2093.c
@@ -33,6 +33,7 @@
 #include <media/v4l2-fwnode.h>
 #include <media/v4l2-subdev.h>
 #include "../platform/rockchip/isp/rkisp_tb_helper.h"
+#include "cam-tb-setup.h"
 
 #define DRIVER_VERSION		KERNEL_VERSION(0, 0x01, 0x02)
 #define GC2093_NAME		"gc2093"
@@ -1612,68 +1613,6 @@
 
 
 #ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
-static u32 rk_cam_hdr;
-static u32 rk_cam_w;
-static u32 rk_cam_h;
-static u32 rk_cam_fps;
-
-static int __init __maybe_unused rk_cam_hdr_setup(char *str)
-{
-	int ret = 0;
-	unsigned long val = 0;
-
-	ret = kstrtoul(str, 0, &val);
-	if (!ret)
-		rk_cam_hdr = (u32)val;
-	else
-		pr_err("get rk_cam_hdr fail\n");
-	return 1;
-}
-
-static int __init __maybe_unused rk_cam_w_setup(char *str)
-{
-	int ret = 0;
-	unsigned long val = 0;
-
-	ret = kstrtoul(str, 0, &val);
-	if (!ret)
-		rk_cam_w = (u32)val;
-	else
-		pr_err("get rk_cam_w fail\n");
-	return 1;
-}
-
-static int __init __maybe_unused rk_cam_h_setup(char *str)
-{
-	int ret = 0;
-	unsigned long val = 0;
-
-	ret = kstrtoul(str, 0, &val);
-	if (!ret)
-		rk_cam_h = (u32)val;
-	else
-		pr_err("get rk_cam_h fail\n");
-	return 1;
-}
-
-static int __init __maybe_unused rk_cam_fps_setup(char *str)
-{
-	int ret = 0;
-	unsigned long val = 0;
-
-	ret = kstrtoul(str, 0, &val);
-	if (!ret)
-		rk_cam_fps = (u32)val;
-	else
-		pr_err("get rk_cam_fps fail\n");
-	return 1;
-}
-
-__setup("rk_cam_hdr=", rk_cam_hdr_setup);
-__setup("rk_cam_w=", rk_cam_w_setup);
-__setup("rk_cam_h=", rk_cam_h_setup);
-__setup("rk_cam_fps=", rk_cam_fps_setup);
-
 static void find_terminal_resolution(struct gc2093 *gc2093)
 {
 	int i = 0;
@@ -1682,6 +1621,10 @@
 	u32 cur_fps = 0;
 	u32 dst_fps = 0;
 	u32 tmp_fps = 0;
+	u32 rk_cam_hdr = get_rk_cam_hdr();
+	u32 rk_cam_w = get_rk_cam_w();
+	u32 rk_cam_h = get_rk_cam_h();
+	u32 rk_cam_fps = get_rk_cam_fps();
 
 	if (rk_cam_w == 0 || rk_cam_h == 0 ||
 	    rk_cam_fps == 0)
diff --git a/kernel/drivers/media/i2c/gc8034.c b/kernel/drivers/media/i2c/gc8034.c
index caa71e5..bd7e4bd 100644
--- a/kernel/drivers/media/i2c/gc8034.c
+++ b/kernel/drivers/media/i2c/gc8034.c
@@ -2575,6 +2575,8 @@
 	if (!IS_ERR(gc8034->reset_gpio))
 		gpiod_set_value_cansleep(gc8034->reset_gpio, 0);
 
+	usleep_range(6000, 7000);
+
 	/* 8192 cycles prior to first SCCB transaction */
 	delay_us = gc8034_cal_delay(8192);
 	usleep_range(delay_us, delay_us * 2);
diff --git a/kernel/drivers/media/i2c/imx219.c b/kernel/drivers/media/i2c/imx219.c
index 4771d0e..b975636 100644
--- a/kernel/drivers/media/i2c/imx219.c
+++ b/kernel/drivers/media/i2c/imx219.c
@@ -89,6 +89,12 @@
 
 #define IMX219_REG_ORIENTATION		0x0172
 
+/* Binning  Mode */
+#define IMX219_REG_BINNING_MODE		0x0174
+#define IMX219_BINNING_NONE		0x0000
+#define IMX219_BINNING_2X2		0x0101
+#define IMX219_BINNING_2X2_ANALOG	0x0303
+
 /* Test Pattern Control */
 #define IMX219_REG_TEST_PATTERN		0x0600
 #define IMX219_TEST_PATTERN_DISABLE	0
@@ -143,6 +149,58 @@
 
 	/* Default register values */
 	struct imx219_reg_list reg_list;
+
+	/* 2x2 binning is used */
+	bool binning;
+};
+
+static const struct imx219_reg imx219_common_regs[] = {
+	{0x0100, 0x00},	/* Mode Select */
+
+	/* To Access Addresses 3000-5fff, send the following commands */
+	{0x30eb, 0x0c},
+	{0x30eb, 0x05},
+	{0x300a, 0xff},
+	{0x300b, 0xff},
+	{0x30eb, 0x05},
+	{0x30eb, 0x09},
+
+	/* PLL Clock Table */
+	{0x0301, 0x05},	/* VTPXCK_DIV */
+	{0x0303, 0x01},	/* VTSYSCK_DIV */
+	{0x0304, 0x03},	/* PREPLLCK_VT_DIV 0x03 = AUTO set */
+	{0x0305, 0x03}, /* PREPLLCK_OP_DIV 0x03 = AUTO set */
+	{0x0306, 0x00},	/* PLL_VT_MPY */
+	{0x0307, 0x39},
+	{0x030b, 0x01},	/* OP_SYS_CLK_DIV */
+	{0x030c, 0x00},	/* PLL_OP_MPY */
+	{0x030d, 0x72},
+
+	/* Undocumented registers */
+	{0x455e, 0x00},
+	{0x471e, 0x4b},
+	{0x4767, 0x0f},
+	{0x4750, 0x14},
+	{0x4540, 0x00},
+	{0x47b4, 0x14},
+	{0x4713, 0x30},
+	{0x478b, 0x10},
+	{0x478f, 0x10},
+	{0x4793, 0x10},
+	{0x4797, 0x0e},
+	{0x479b, 0x0e},
+
+	/* Frame Bank Register Group "A" */
+	{0x0162, 0x0d},	/* Line_Length_A */
+	{0x0163, 0x78},
+	{0x0170, 0x01}, /* X_ODD_INC_A */
+	{0x0171, 0x01}, /* Y_ODD_INC_A */
+
+	/* Output setup registers */
+	{0x0114, 0x01},	/* CSI 2-Lane Mode */
+	{0x0128, 0x00},	/* DPHY Auto Mode */
+	{0x012a, 0x18},	/* EXCK_Freq */
+	{0x012b, 0x00},
 };
 
 /*
@@ -151,17 +209,6 @@
  * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7.
  */
 static const struct imx219_reg mode_3280x2464_regs[] = {
-	{0x0100, 0x00},
-	{0x30eb, 0x0c},
-	{0x30eb, 0x05},
-	{0x300a, 0xff},
-	{0x300b, 0xff},
-	{0x30eb, 0x05},
-	{0x30eb, 0x09},
-	{0x0114, 0x01},
-	{0x0128, 0x00},
-	{0x012a, 0x18},
-	{0x012b, 0x00},
 	{0x0164, 0x00},
 	{0x0165, 0x00},
 	{0x0166, 0x0c},
@@ -174,53 +221,13 @@
 	{0x016d, 0xd0},
 	{0x016e, 0x09},
 	{0x016f, 0xa0},
-	{0x0170, 0x01},
-	{0x0171, 0x01},
-	{0x0174, 0x00},
-	{0x0175, 0x00},
-	{0x0301, 0x05},
-	{0x0303, 0x01},
-	{0x0304, 0x03},
-	{0x0305, 0x03},
-	{0x0306, 0x00},
-	{0x0307, 0x39},
-	{0x030b, 0x01},
-	{0x030c, 0x00},
-	{0x030d, 0x72},
 	{0x0624, 0x0c},
 	{0x0625, 0xd0},
 	{0x0626, 0x09},
 	{0x0627, 0xa0},
-	{0x455e, 0x00},
-	{0x471e, 0x4b},
-	{0x4767, 0x0f},
-	{0x4750, 0x14},
-	{0x4540, 0x00},
-	{0x47b4, 0x14},
-	{0x4713, 0x30},
-	{0x478b, 0x10},
-	{0x478f, 0x10},
-	{0x4793, 0x10},
-	{0x4797, 0x0e},
-	{0x479b, 0x0e},
-	{0x0162, 0x0d},
-	{0x0163, 0x78},
 };
 
 static const struct imx219_reg mode_1920_1080_regs[] = {
-	{0x0100, 0x00},
-	{0x30eb, 0x05},
-	{0x30eb, 0x0c},
-	{0x300a, 0xff},
-	{0x300b, 0xff},
-	{0x30eb, 0x05},
-	{0x30eb, 0x09},
-	{0x0114, 0x01},
-	{0x0128, 0x00},
-	{0x012a, 0x18},
-	{0x012b, 0x00},
-	{0x0162, 0x0d},
-	{0x0163, 0x78},
 	{0x0164, 0x02},
 	{0x0165, 0xa8},
 	{0x0166, 0x0a},
@@ -233,51 +240,13 @@
 	{0x016d, 0x80},
 	{0x016e, 0x04},
 	{0x016f, 0x38},
-	{0x0170, 0x01},
-	{0x0171, 0x01},
-	{0x0174, 0x00},
-	{0x0175, 0x00},
-	{0x0301, 0x05},
-	{0x0303, 0x01},
-	{0x0304, 0x03},
-	{0x0305, 0x03},
-	{0x0306, 0x00},
-	{0x0307, 0x39},
-	{0x030b, 0x01},
-	{0x030c, 0x00},
-	{0x030d, 0x72},
 	{0x0624, 0x07},
 	{0x0625, 0x80},
 	{0x0626, 0x04},
 	{0x0627, 0x38},
-	{0x455e, 0x00},
-	{0x471e, 0x4b},
-	{0x4767, 0x0f},
-	{0x4750, 0x14},
-	{0x4540, 0x00},
-	{0x47b4, 0x14},
-	{0x4713, 0x30},
-	{0x478b, 0x10},
-	{0x478f, 0x10},
-	{0x4793, 0x10},
-	{0x4797, 0x0e},
-	{0x479b, 0x0e},
-	{0x0162, 0x0d},
-	{0x0163, 0x78},
 };
 
 static const struct imx219_reg mode_1640_1232_regs[] = {
-	{0x0100, 0x00},
-	{0x30eb, 0x0c},
-	{0x30eb, 0x05},
-	{0x300a, 0xff},
-	{0x300b, 0xff},
-	{0x30eb, 0x05},
-	{0x30eb, 0x09},
-	{0x0114, 0x01},
-	{0x0128, 0x00},
-	{0x012a, 0x18},
-	{0x012b, 0x00},
 	{0x0164, 0x00},
 	{0x0165, 0x00},
 	{0x0166, 0x0c},
@@ -290,53 +259,13 @@
 	{0x016d, 0x68},
 	{0x016e, 0x04},
 	{0x016f, 0xd0},
-	{0x0170, 0x01},
-	{0x0171, 0x01},
-	{0x0174, 0x01},
-	{0x0175, 0x01},
-	{0x0301, 0x05},
-	{0x0303, 0x01},
-	{0x0304, 0x03},
-	{0x0305, 0x03},
-	{0x0306, 0x00},
-	{0x0307, 0x39},
-	{0x030b, 0x01},
-	{0x030c, 0x00},
-	{0x030d, 0x72},
 	{0x0624, 0x06},
 	{0x0625, 0x68},
 	{0x0626, 0x04},
 	{0x0627, 0xd0},
-	{0x455e, 0x00},
-	{0x471e, 0x4b},
-	{0x4767, 0x0f},
-	{0x4750, 0x14},
-	{0x4540, 0x00},
-	{0x47b4, 0x14},
-	{0x4713, 0x30},
-	{0x478b, 0x10},
-	{0x478f, 0x10},
-	{0x4793, 0x10},
-	{0x4797, 0x0e},
-	{0x479b, 0x0e},
-	{0x0162, 0x0d},
-	{0x0163, 0x78},
 };
 
 static const struct imx219_reg mode_640_480_regs[] = {
-	{0x0100, 0x00},
-	{0x30eb, 0x05},
-	{0x30eb, 0x0c},
-	{0x300a, 0xff},
-	{0x300b, 0xff},
-	{0x30eb, 0x05},
-	{0x30eb, 0x09},
-	{0x0114, 0x01},
-	{0x0128, 0x00},
-	{0x012a, 0x18},
-	{0x012b, 0x00},
-	{0x0162, 0x0d},
-	{0x0163, 0x78},
 	{0x0164, 0x03},
 	{0x0165, 0xe8},
 	{0x0166, 0x08},
@@ -349,35 +278,10 @@
 	{0x016d, 0x80},
 	{0x016e, 0x01},
 	{0x016f, 0xe0},
-	{0x0170, 0x01},
-	{0x0171, 0x01},
-	{0x0174, 0x03},
-	{0x0175, 0x03},
-	{0x0301, 0x05},
-	{0x0303, 0x01},
-	{0x0304, 0x03},
-	{0x0305, 0x03},
-	{0x0306, 0x00},
-	{0x0307, 0x39},
-	{0x030b, 0x01},
-	{0x030c, 0x00},
-	{0x030d, 0x72},
 	{0x0624, 0x06},
 	{0x0625, 0x68},
 	{0x0626, 0x04},
 	{0x0627, 0xd0},
-	{0x455e, 0x00},
-	{0x471e, 0x4b},
-	{0x4767, 0x0f},
-	{0x4750, 0x14},
-	{0x4540, 0x00},
-	{0x47b4, 0x14},
-	{0x4713, 0x30},
-	{0x478b, 0x10},
-	{0x478f, 0x10},
-	{0x4793, 0x10},
-	{0x4797, 0x0e},
-	{0x479b, 0x0e},
 };
 
 static const struct imx219_reg raw8_framefmt_regs[] = {
@@ -483,6 +387,7 @@
 			.num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
 			.regs = mode_3280x2464_regs,
 		},
+		.binning = false,
 	},
 	{
 		/* 1080P 30fps cropped */
@@ -499,6 +404,7 @@
 			.num_of_regs = ARRAY_SIZE(mode_1920_1080_regs),
 			.regs = mode_1920_1080_regs,
 		},
+		.binning = false,
 	},
 	{
 		/* 2x2 binned 30fps mode */
@@ -515,6 +421,7 @@
 			.num_of_regs = ARRAY_SIZE(mode_1640_1232_regs),
 			.regs = mode_1640_1232_regs,
 		},
+		.binning = true,
 	},
 	{
 		/* 640x480 30fps mode */
@@ -531,6 +438,7 @@
 			.num_of_regs = ARRAY_SIZE(mode_640_480_regs),
 			.regs = mode_640_480_regs,
 		},
+		.binning = true,
 	},
 };
 
@@ -969,6 +877,35 @@
 	return -EINVAL;
 }
 
+static int imx219_set_binning(struct imx219 *imx219)
+{
+	if (!imx219->mode->binning) {
+		return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE,
+					IMX219_REG_VALUE_16BIT,
+					IMX219_BINNING_NONE);
+	}
+
+	switch (imx219->fmt.code) {
+	case MEDIA_BUS_FMT_SRGGB8_1X8:
+	case MEDIA_BUS_FMT_SGRBG8_1X8:
+	case MEDIA_BUS_FMT_SGBRG8_1X8:
+	case MEDIA_BUS_FMT_SBGGR8_1X8:
+		return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE,
+					IMX219_REG_VALUE_16BIT,
+					IMX219_BINNING_2X2_ANALOG);
+
+	case MEDIA_BUS_FMT_SRGGB10_1X10:
+	case MEDIA_BUS_FMT_SGRBG10_1X10:
+	case MEDIA_BUS_FMT_SGBRG10_1X10:
+	case MEDIA_BUS_FMT_SBGGR10_1X10:
+		return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE,
+					IMX219_REG_VALUE_16BIT,
+					IMX219_BINNING_2X2);
+	}
+
+	return -EINVAL;
+}
+
 static const struct v4l2_rect *
 __imx219_get_pad_crop(struct imx219 *imx219, struct v4l2_subdev_pad_config *cfg,
 		      unsigned int pad, enum v4l2_subdev_format_whence which)
@@ -1032,6 +969,13 @@
 		return ret;
 	}
 
+	/* Send all registers that are common to all modes */
+	ret = imx219_write_regs(imx219, imx219_common_regs, ARRAY_SIZE(imx219_common_regs));
+	if (ret) {
+		dev_err(&client->dev, "%s failed to send mfg header\n", __func__);
+		goto err_rpm_put;
+	}
+
 	/* Apply default values of current mode */
 	reg_list = &imx219->mode->reg_list;
 	ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs);
@@ -1047,6 +991,13 @@
 		goto err_rpm_put;
 	}
 
+	ret = imx219_set_binning(imx219);
+	if (ret) {
+		dev_err(&client->dev, "%s failed to set binning: %d\n",
+			__func__, ret);
+		goto err_rpm_put;
+	}
+
 	/* Apply customized values from user */
 	ret =  __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler);
 	if (ret)
diff --git a/kernel/drivers/media/i2c/imx415.c b/kernel/drivers/media/i2c/imx415.c
index 0bd0431..2cf6561 100644
--- a/kernel/drivers/media/i2c/imx415.c
+++ b/kernel/drivers/media/i2c/imx415.c
@@ -50,6 +50,8 @@
 #include <media/v4l2-subdev.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/rk-preisp.h>
+#include <media/v4l2-fwnode.h>
+#include <linux/of_graph.h>
 #include "../platform/rockchip/isp/rkisp_tb_helper.h"
 
 #define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x08)
@@ -58,17 +60,20 @@
 #define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
 #endif
 
+#define MIPI_FREQ_1188M			1188000000
 #define MIPI_FREQ_891M			891000000
 #define MIPI_FREQ_446M			446000000
 #define MIPI_FREQ_743M			743000000
 #define MIPI_FREQ_297M			297000000
 
 #define IMX415_4LANES			4
+#define IMX415_2LANES			2
 
 #define IMX415_MAX_PIXEL_RATE		(MIPI_FREQ_891M / 10 * 2 * IMX415_4LANES)
 #define OF_CAMERA_HDR_MODE		"rockchip,camera-hdr-mode"
 
 #define IMX415_XVCLK_FREQ_37M		37125000
+#define IMX415_XVCLK_FREQ_27M		27000000
 
 /* TODO: Get the real chip id from reg */
 #define CHIP_ID				0xE0
@@ -142,6 +147,7 @@
 #define IMX415_FLIP_REG			0x3030
 
 #define REG_NULL			0xFFFF
+#define REG_DELAY			0xFFFE
 
 #define IMX415_REG_VALUE_08BIT		1
 #define IMX415_REG_VALUE_16BIT		2
@@ -164,6 +170,7 @@
 
 #define OF_CAMERA_PINCTRL_STATE_DEFAULT	"rockchip,camera_default"
 #define OF_CAMERA_PINCTRL_STATE_SLEEP	"rockchip,camera_sleep"
+#define RKMODULE_CAMERA_FASTBOOT_ENABLE "rockchip,camera_fastboot"
 
 #define IMX415_NAME			"imx415"
 
@@ -194,6 +201,7 @@
 	const struct regval *reg_list;
 	u32 hdr_mode;
 	u32 vc[PAD_MAX];
+	u32 xvclk;
 };
 
 struct imx415 {
@@ -220,9 +228,10 @@
 	struct mutex		mutex;
 	bool			streaming;
 	bool			power_on;
-	bool			is_thunderboot;
+	u32			is_thunderboot;
 	bool			is_thunderboot_ng;
 	bool			is_first_streamoff;
+	const struct imx415_mode *supported_modes;
 	const struct imx415_mode *cur_mode;
 	u32			module_index;
 	u32			cfg_num;
@@ -232,6 +241,7 @@
 	u32			cur_vts;
 	bool			has_init_exp;
 	struct preisp_hdrae_exp_s init_hdrae_exp;
+	struct v4l2_fwnode_endpoint bus_cfg;
 };
 
 static struct rkmodule_csi_dphy_param dcphy_param = {
@@ -746,6 +756,311 @@
 };
 
 /*
+ * Xclk 27Mhz
+ * 15fps
+ * CSI-2_2lane
+ * AD:12bit Output:12bit
+ * 891Mbps
+ * Master Mode
+ * Time 9.988ms Gain:6dB
+ * All-pixel
+ */
+static __maybe_unused const struct regval imx415_linear_12bit_3864x2192_891M_regs_2lane[] = {
+	{0x3008, 0x5D},
+	{0x300A, 0x42},
+	{0x3028, 0x98},
+	{0x3029, 0x08},
+	{0x3033, 0x05},
+	{0x3050, 0x79},
+	{0x3051, 0x07},
+	{0x3090, 0x14},
+	{0x30C1, 0x00},
+	{0x3116, 0x23},
+	{0x3118, 0xC6},
+	{0x311A, 0xE7},
+	{0x311E, 0x23},
+	{0x32D4, 0x21},
+	{0x32EC, 0xA1},
+	{0x344C, 0x2B},
+	{0x344D, 0x01},
+	{0x344E, 0xED},
+	{0x344F, 0x01},
+	{0x3450, 0xF6},
+	{0x3451, 0x02},
+	{0x3452, 0x7F},
+	{0x3453, 0x03},
+	{0x358A, 0x04},
+	{0x35A1, 0x02},
+	{0x35EC, 0x27},
+	{0x35EE, 0x8D},
+	{0x35F0, 0x8D},
+	{0x35F2, 0x29},
+	{0x36BC, 0x0C},
+	{0x36CC, 0x53},
+	{0x36CD, 0x00},
+	{0x36CE, 0x3C},
+	{0x36D0, 0x8C},
+	{0x36D1, 0x00},
+	{0x36D2, 0x71},
+	{0x36D4, 0x3C},
+	{0x36D6, 0x53},
+	{0x36D7, 0x00},
+	{0x36D8, 0x71},
+	{0x36DA, 0x8C},
+	{0x36DB, 0x00},
+	{0x3720, 0x00},
+	{0x3724, 0x02},
+	{0x3726, 0x02},
+	{0x3732, 0x02},
+	{0x3734, 0x03},
+	{0x3736, 0x03},
+	{0x3742, 0x03},
+	{0x3862, 0xE0},
+	{0x38CC, 0x30},
+	{0x38CD, 0x2F},
+	{0x395C, 0x0C},
+	{0x39A4, 0x07},
+	{0x39A8, 0x32},
+	{0x39AA, 0x32},
+	{0x39AC, 0x32},
+	{0x39AE, 0x32},
+	{0x39B0, 0x32},
+	{0x39B2, 0x2F},
+	{0x39B4, 0x2D},
+	{0x39B6, 0x28},
+	{0x39B8, 0x30},
+	{0x39BA, 0x30},
+	{0x39BC, 0x30},
+	{0x39BE, 0x30},
+	{0x39C0, 0x30},
+	{0x39C2, 0x2E},
+	{0x39C4, 0x2B},
+	{0x39C6, 0x25},
+	{0x3A42, 0xD1},
+	{0x3A4C, 0x77},
+	{0x3AE0, 0x02},
+	{0x3AEC, 0x0C},
+	{0x3B00, 0x2E},
+	{0x3B06, 0x29},
+	{0x3B98, 0x25},
+	{0x3B99, 0x21},
+	{0x3B9B, 0x13},
+	{0x3B9C, 0x13},
+	{0x3B9D, 0x13},
+	{0x3B9E, 0x13},
+	{0x3BA1, 0x00},
+	{0x3BA2, 0x06},
+	{0x3BA3, 0x0B},
+	{0x3BA4, 0x10},
+	{0x3BA5, 0x14},
+	{0x3BA6, 0x18},
+	{0x3BA7, 0x1A},
+	{0x3BA8, 0x1A},
+	{0x3BA9, 0x1A},
+	{0x3BAC, 0xED},
+	{0x3BAD, 0x01},
+	{0x3BAE, 0xF6},
+	{0x3BAF, 0x02},
+	{0x3BB0, 0xA2},
+	{0x3BB1, 0x03},
+	{0x3BB2, 0xE0},
+	{0x3BB3, 0x03},
+	{0x3BB4, 0xE0},
+	{0x3BB5, 0x03},
+	{0x3BB6, 0xE0},
+	{0x3BB7, 0x03},
+	{0x3BB8, 0xE0},
+	{0x3BBA, 0xE0},
+	{0x3BBC, 0xDA},
+	{0x3BBE, 0x88},
+	{0x3BC0, 0x44},
+	{0x3BC2, 0x7B},
+	{0x3BC4, 0xA2},
+	{0x3BC8, 0xBD},
+	{0x3BCA, 0xBD},
+	{0x4001, 0x01},
+	{0x4004, 0xC0},
+	{0x4005, 0x06},
+	{0x400C, 0x00},
+	{0x4018, 0x7F},
+	{0x401A, 0x37},
+	{0x401C, 0x37},
+	{0x401E, 0xF7},
+	{0x401F, 0x00},
+	{0x4020, 0x3F},
+	{0x4022, 0x6F},
+	{0x4024, 0x3F},
+	{0x4026, 0x5F},
+	{0x4028, 0x2F},
+	{0x4074, 0x01},
+	{0x3002, 0x00},
+	//{0x3000, 0x00},
+	{REG_DELAY, 0x1E},//wait_ms(30)
+	{REG_NULL, 0x00},
+};
+
+/*
+ * Xclk 27Mhz
+ * 90.059fps
+ * CSI-2_2lane
+ * AD:10bit Output:12bit
+ * 2376Mbps
+ * Master Mode
+ * Time 9.999ms Gain:6dB
+ * 2568x1440 2/2-line binning & Window cropping
+ */
+static __maybe_unused const struct regval imx415_linear_12bit_1284x720_2376M_regs_2lane[] = {
+	{0x3008, 0x5D},
+	{0x300A, 0x42},
+	{0x301C, 0x04},
+	{0x3020, 0x01},
+	{0x3021, 0x01},
+	{0x3022, 0x01},
+	{0x3024, 0xAB},
+	{0x3025, 0x07},
+	{0x3028, 0xA4},
+	{0x3029, 0x01},
+	{0x3031, 0x00},
+	{0x3033, 0x00},
+	{0x3040, 0x88},
+	{0x3041, 0x02},
+	{0x3042, 0x08},
+	{0x3043, 0x0A},
+	{0x3044, 0xF0},
+	{0x3045, 0x02},
+	{0x3046, 0x40},
+	{0x3047, 0x0B},
+	{0x3050, 0xC4},
+	{0x3090, 0x14},
+	{0x30C1, 0x00},
+	{0x30D9, 0x02},
+	{0x30DA, 0x01},
+	{0x3116, 0x23},
+	{0x3118, 0x08},
+	{0x3119, 0x01},
+	{0x311A, 0xE7},
+	{0x311E, 0x23},
+	{0x32D4, 0x21},
+	{0x32EC, 0xA1},
+	{0x344C, 0x2B},
+	{0x344D, 0x01},
+	{0x344E, 0xED},
+	{0x344F, 0x01},
+	{0x3450, 0xF6},
+	{0x3451, 0x02},
+	{0x3452, 0x7F},
+	{0x3453, 0x03},
+	{0x358A, 0x04},
+	{0x35A1, 0x02},
+	{0x35EC, 0x27},
+	{0x35EE, 0x8D},
+	{0x35F0, 0x8D},
+	{0x35F2, 0x29},
+	{0x36BC, 0x0C},
+	{0x36CC, 0x53},
+	{0x36CD, 0x00},
+	{0x36CE, 0x3C},
+	{0x36D0, 0x8C},
+	{0x36D1, 0x00},
+	{0x36D2, 0x71},
+	{0x36D4, 0x3C},
+	{0x36D6, 0x53},
+	{0x36D7, 0x00},
+	{0x36D8, 0x71},
+	{0x36DA, 0x8C},
+	{0x36DB, 0x00},
+	{0x3701, 0x00},
+	{0x3720, 0x00},
+	{0x3724, 0x02},
+	{0x3726, 0x02},
+	{0x3732, 0x02},
+	{0x3734, 0x03},
+	{0x3736, 0x03},
+	{0x3742, 0x03},
+	{0x3862, 0xE0},
+	{0x38CC, 0x30},
+	{0x38CD, 0x2F},
+	{0x395C, 0x0C},
+	{0x39A4, 0x07},
+	{0x39A8, 0x32},
+	{0x39AA, 0x32},
+	{0x39AC, 0x32},
+	{0x39AE, 0x32},
+	{0x39B0, 0x32},
+	{0x39B2, 0x2F},
+	{0x39B4, 0x2D},
+	{0x39B6, 0x28},
+	{0x39B8, 0x30},
+	{0x39BA, 0x30},
+	{0x39BC, 0x30},
+	{0x39BE, 0x30},
+	{0x39C0, 0x30},
+	{0x39C2, 0x2E},
+	{0x39C4, 0x2B},
+	{0x39C6, 0x25},
+	{0x3A42, 0xD1},
+	{0x3A4C, 0x77},
+	{0x3AE0, 0x02},
+	{0x3AEC, 0x0C},
+	{0x3B00, 0x2E},
+	{0x3B06, 0x29},
+	{0x3B98, 0x25},
+	{0x3B99, 0x21},
+	{0x3B9B, 0x13},
+	{0x3B9C, 0x13},
+	{0x3B9D, 0x13},
+	{0x3B9E, 0x13},
+	{0x3BA1, 0x00},
+	{0x3BA2, 0x06},
+	{0x3BA3, 0x0B},
+	{0x3BA4, 0x10},
+	{0x3BA5, 0x14},
+	{0x3BA6, 0x18},
+	{0x3BA7, 0x1A},
+	{0x3BA8, 0x1A},
+	{0x3BA9, 0x1A},
+	{0x3BAC, 0xED},
+	{0x3BAD, 0x01},
+	{0x3BAE, 0xF6},
+	{0x3BAF, 0x02},
+	{0x3BB0, 0xA2},
+	{0x3BB1, 0x03},
+	{0x3BB2, 0xE0},
+	{0x3BB3, 0x03},
+	{0x3BB4, 0xE0},
+	{0x3BB5, 0x03},
+	{0x3BB6, 0xE0},
+	{0x3BB7, 0x03},
+	{0x3BB8, 0xE0},
+	{0x3BBA, 0xE0},
+	{0x3BBC, 0xDA},
+	{0x3BBE, 0x88},
+	{0x3BC0, 0x44},
+	{0x3BC2, 0x7B},
+	{0x3BC4, 0xA2},
+	{0x3BC8, 0xBD},
+	{0x3BCA, 0xBD},
+	{0x4001, 0x01},
+	{0x4004, 0xC0},
+	{0x4005, 0x06},
+	{0x4018, 0xE7},
+	{0x401A, 0x8F},
+	{0x401C, 0x8F},
+	{0x401E, 0x7F},
+	{0x401F, 0x02},
+	{0x4020, 0x97},
+	{0x4022, 0x0F},
+	{0x4023, 0x01},
+	{0x4024, 0x97},
+	{0x4026, 0xF7},
+	{0x4028, 0x7F},
+	{0x3002, 0x00},
+	//{0x3000, 0x00},
+	{REG_DELAY, 0x1E},//wait_ms(30)
+	{REG_NULL, 0x00},
+};
+
+/*
  * The width and height must be configured to be
  * the same as the current output resolution of the sensor.
  * The input width of the isp needs to be 16 aligned.
@@ -779,6 +1094,7 @@
 		.mipi_freq_idx = 1,
 		.bpp = 10,
 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+		.xvclk = IMX415_XVCLK_FREQ_37M,
 	},
 	{
 		.bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
@@ -804,6 +1120,7 @@
 		.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
 		.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
 		.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
+		.xvclk = IMX415_XVCLK_FREQ_37M,
 	},
 	{
 		.bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
@@ -829,6 +1146,7 @@
 		.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0
 		.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
 		.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_2,//S->csi wr2
+		.xvclk = IMX415_XVCLK_FREQ_37M,
 	},
 	{
 		.bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
@@ -854,6 +1172,7 @@
 		.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0
 		.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
 		.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_2,//S->csi wr2
+		.xvclk = IMX415_XVCLK_FREQ_37M,
 	},
 	{
 		/* 1H period = (1100 clock) = (1100 * 1 / 74.25MHz) */
@@ -873,6 +1192,7 @@
 		.mipi_freq_idx = 1,
 		.bpp = 12,
 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+		.xvclk = IMX415_XVCLK_FREQ_37M,
 	},
 	{
 		.bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
@@ -898,6 +1218,7 @@
 		.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
 		.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
 		.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
+		.xvclk = IMX415_XVCLK_FREQ_37M,
 	},
 	{
 		.bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
@@ -923,6 +1244,7 @@
 		.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0
 		.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
 		.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_2,//S->csi wr2
+		.xvclk = IMX415_XVCLK_FREQ_37M,
 	},
 	{
 		.bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
@@ -941,6 +1263,7 @@
 		.mipi_freq_idx = 0,
 		.bpp = 12,
 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+		.xvclk = IMX415_XVCLK_FREQ_37M,
 	},
 	{
 		.bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
@@ -966,6 +1289,50 @@
 		.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
 		.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
 		.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
+		.xvclk = IMX415_XVCLK_FREQ_37M,
+	},
+};
+
+static const struct imx415_mode supported_modes_2lane[] = {
+	{
+		/* 1H period = (1100 clock) = (1100 * 1 / 74.25MHz) */
+		.bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.width = 3864,
+		.height = 2192,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 150000,
+		},
+		.exp_def = 0x08ca - 0x08,
+		.hts_def = 0x0898 * IMX415_2LANES * 2,
+		.vts_def = 0x08ca,
+		.global_reg_list = NULL,
+		.reg_list = imx415_linear_12bit_3864x2192_891M_regs_2lane,
+		.hdr_mode = NO_HDR,
+		.mipi_freq_idx = 1,
+		.bpp = 12,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+		.xvclk = IMX415_XVCLK_FREQ_27M,
+	},
+	{
+		/* 1H period = (1100 clock) = (1100 * 1 / 74.25MHz) */
+		.bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.width = 1284,
+		.height = 720,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 900000,
+		},
+		.exp_def = 0x07AB-8,
+		.hts_def = 0x01A4 * IMX415_2LANES * 2,
+		.vts_def = 0x07AB,
+		.global_reg_list = NULL,
+		.reg_list = imx415_linear_12bit_1284x720_2376M_regs_2lane,
+		.hdr_mode = NO_HDR,
+		.mipi_freq_idx = 4,
+		.bpp = 12,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+		.xvclk = IMX415_XVCLK_FREQ_27M,
 	},
 };
 
@@ -974,6 +1341,7 @@
 	MIPI_FREQ_446M,
 	MIPI_FREQ_743M,
 	MIPI_FREQ_891M,
+	MIPI_FREQ_1188M,
 };
 
 /* Write registers up to 4 at a time */
@@ -1010,10 +1378,18 @@
 {
 	u32 i;
 	int ret = 0;
-
+	if (!regs) {
+		dev_err(&client->dev, "write reg array error\n");
+		return ret;
+	}
 	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) {
-		ret = imx415_write_reg(client, regs[i].addr,
-				       IMX415_REG_VALUE_08BIT, regs[i].val);
+		if (regs[i].addr == REG_DELAY) {
+			usleep_range(regs[i].val * 1000, regs[i].val * 1000 + 500);
+			dev_info(&client->dev, "write reg array, sleep %dms\n", regs[i].val);
+		} else {
+			ret = imx415_write_reg(client, regs[i].addr,
+				IMX415_REG_VALUE_08BIT, regs[i].val);
+		}
 	}
 	return ret;
 }
@@ -1070,9 +1446,9 @@
 	unsigned int i;
 
 	for (i = 0; i < imx415->cfg_num; i++) {
-		dist = imx415_get_reso_dist(&supported_modes[i], framefmt);
+		dist = imx415_get_reso_dist(&imx415->supported_modes[i], framefmt);
 		if ((cur_best_fit_dist == -1 || dist < cur_best_fit_dist) &&
-			supported_modes[i].bus_fmt == framefmt->code) {
+			imx415->supported_modes[i].bus_fmt == framefmt->code) {
 			cur_best_fit_dist = dist;
 			cur_best_fit = i;
 		}
@@ -1080,7 +1456,7 @@
 	dev_info(&imx415->client->dev, "%s: cur_best_fit(%d)",
 		 __func__, cur_best_fit);
 
-	return &supported_modes[cur_best_fit];
+	return &imx415->supported_modes[cur_best_fit];
 }
 
 static int __imx415_power_on(struct imx415 *imx415);
@@ -1094,8 +1470,8 @@
 	}
 	imx415->cur_mode = mode;
 	imx415->cur_vts = imx415->cur_mode->vts_def;
-	dev_dbg(&imx415->client->dev, "set fmt: cur_mode: %dx%d, hdr: %d\n",
-		mode->width, mode->height, mode->hdr_mode);
+	dev_info(&imx415->client->dev, "set fmt: cur_mode: %dx%d, hdr: %d, bpp: %d\n",
+		mode->width, mode->height, mode->hdr_mode, mode->bpp);
 }
 
 static int imx415_set_fmt(struct v4l2_subdev *sd,
@@ -1106,6 +1482,7 @@
 	const struct imx415_mode *mode;
 	s64 h_blank, vblank_def, vblank_min;
 	u64 pixel_rate = 0;
+	u8 lanes = imx415->bus_cfg.bus.mipi_csi2.num_data_lanes;
 
 	mutex_lock(&imx415->mutex);
 
@@ -1134,7 +1511,8 @@
 					 1, vblank_def);
 		__v4l2_ctrl_s_ctrl(imx415->vblank, vblank_def);
 		__v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx);
-		pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * IMX415_4LANES;
+		pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] /
+			mode->bpp * 2 * lanes;
 		__v4l2_ctrl_s_ctrl_int64(imx415->pixel_rate,
 					 pixel_rate);
 	}
@@ -1185,7 +1563,7 @@
 	if (code->index >= imx415->cfg_num)
 		return -EINVAL;
 
-	code->code = supported_modes[code->index].bus_fmt;
+	code->code = imx415->supported_modes[code->index].bus_fmt;
 
 	return 0;
 }
@@ -1199,13 +1577,13 @@
 	if (fse->index >= imx415->cfg_num)
 		return -EINVAL;
 
-	if (fse->code != supported_modes[fse->index].bus_fmt)
+	if (fse->code != imx415->supported_modes[fse->index].bus_fmt)
 		return -EINVAL;
 
-	fse->min_width  = supported_modes[fse->index].width;
-	fse->max_width  = supported_modes[fse->index].width;
-	fse->max_height = supported_modes[fse->index].height;
-	fse->min_height = supported_modes[fse->index].height;
+	fse->min_width  = imx415->supported_modes[fse->index].width;
+	fse->max_width  = imx415->supported_modes[fse->index].width;
+	fse->max_height = imx415->supported_modes[fse->index].height;
+	fse->min_height = imx415->supported_modes[fse->index].height;
 
 	return 0;
 }
@@ -1227,8 +1605,9 @@
 	struct imx415 *imx415 = to_imx415(sd);
 	const struct imx415_mode *mode = imx415->cur_mode;
 	u32 val = 0;
+	u8 lanes = imx415->bus_cfg.bus.mipi_csi2.num_data_lanes;
 
-	val = 1 << (IMX415_4LANES - 1) |
+	val = 1 << (lanes - 1) |
 	      V4L2_MBUS_CSI2_CHANNEL_0 |
 	      V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
 	if (mode->hdr_mode != NO_HDR)
@@ -1687,6 +2066,7 @@
 	const struct imx415_mode *mode;
 	u64 pixel_rate = 0;
 	struct rkmodule_csi_dphy_param *dphy_param;
+	u8 lanes = imx415->bus_cfg.bus.mipi_csi2.num_data_lanes;
 
 	switch (cmd) {
 	case PREISP_CMD_SET_HDRAE_EXP:
@@ -1708,10 +2088,11 @@
 		w = imx415->cur_mode->width;
 		h = imx415->cur_mode->height;
 		for (i = 0; i < imx415->cfg_num; i++) {
-			if (w == supported_modes[i].width &&
-			    h == supported_modes[i].height &&
-			    supported_modes[i].hdr_mode == hdr->hdr_mode) {
-				imx415_change_mode(imx415, &supported_modes[i]);
+			if (w == imx415->supported_modes[i].width &&
+			    h == imx415->supported_modes[i].height &&
+			    imx415->supported_modes[i].hdr_mode == hdr->hdr_mode) {
+				dev_info(&imx415->client->dev, "set hdr cfg, set mode to %d\n", i);
+				imx415_change_mode(imx415, &imx415->supported_modes[i]);
 				break;
 			}
 		}
@@ -1741,7 +2122,8 @@
 				IMX415_VTS_MAX - mode->height,
 				1, h);
 			__v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx);
-			pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * IMX415_4LANES;
+			pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] /
+				mode->bpp * 2 * lanes;
 			__v4l2_ctrl_s_ctrl_int64(imx415->pixel_rate,
 						 pixel_rate);
 			mutex_unlock(&imx415->mutex);
@@ -2045,10 +2427,6 @@
 {
 	int ret;
 	struct device *dev = &imx415->client->dev;
-
-	if (imx415->is_thunderboot)
-		return 0;
-
 	if (!IS_ERR_OR_NULL(imx415->pins_default)) {
 		ret = pinctrl_select_state(imx415->pinctrl,
 					   imx415->pins_default);
@@ -2056,26 +2434,28 @@
 			dev_err(dev, "could not set pins\n");
 	}
 
-	ret = regulator_bulk_enable(IMX415_NUM_SUPPLIES, imx415->supplies);
-	if (ret < 0) {
-		dev_err(dev, "Failed to enable regulators\n");
-		goto err_pinctrl;
-	}
-	if (!IS_ERR(imx415->power_gpio))
-		gpiod_direction_output(imx415->power_gpio, 1);
-	/* At least 500ns between power raising and XCLR */
-	/* fix power on timing if insmod this ko */
-	usleep_range(10 * 1000, 20 * 1000);
-	if (!IS_ERR(imx415->reset_gpio))
-		gpiod_direction_output(imx415->reset_gpio, 0);
+	if (!imx415->is_thunderboot) {
+		ret = regulator_bulk_enable(IMX415_NUM_SUPPLIES, imx415->supplies);
+		if (ret < 0) {
+			dev_err(dev, "Failed to enable regulators\n");
+			goto err_pinctrl;
+		}
+		if (!IS_ERR(imx415->power_gpio))
+			gpiod_direction_output(imx415->power_gpio, 1);
+		/* At least 500ns between power raising and XCLR */
+		/* fix power on timing if insmod this ko */
+		usleep_range(10 * 1000, 20 * 1000);
+		if (!IS_ERR(imx415->reset_gpio))
+			gpiod_direction_output(imx415->reset_gpio, 0);
 
-	/* At least 1us between XCLR and clk */
-	/* fix power on timing if insmod this ko */
-	usleep_range(10 * 1000, 20 * 1000);
-	ret = clk_set_rate(imx415->xvclk, IMX415_XVCLK_FREQ_37M);
+		/* At least 1us between XCLR and clk */
+		/* fix power on timing if insmod this ko */
+		usleep_range(10 * 1000, 20 * 1000);
+	}
+	ret = clk_set_rate(imx415->xvclk, imx415->cur_mode->xvclk);
 	if (ret < 0)
 		dev_warn(dev, "Failed to set xvclk rate\n");
-	if (clk_get_rate(imx415->xvclk) != IMX415_XVCLK_FREQ_37M)
+	if (clk_get_rate(imx415->xvclk) != imx415->cur_mode->xvclk)
 		dev_warn(dev, "xvclk mismatched\n");
 	ret = clk_prepare_enable(imx415->xvclk);
 	if (ret < 0) {
@@ -2084,7 +2464,8 @@
 	}
 
 	/* At least 20us between XCLR and I2C communication */
-	usleep_range(20*1000, 30*1000);
+	if (!imx415->is_thunderboot)
+		usleep_range(20*1000, 30*1000);
 
 	return 0;
 
@@ -2154,7 +2535,7 @@
 	struct imx415 *imx415 = to_imx415(sd);
 	struct v4l2_mbus_framefmt *try_fmt =
 				v4l2_subdev_get_try_format(sd, fh->pad, 0);
-	const struct imx415_mode *def_mode = &supported_modes[0];
+	const struct imx415_mode *def_mode = &imx415->supported_modes[0];
 
 	mutex_lock(&imx415->mutex);
 	/* Initialize try_fmt */
@@ -2179,11 +2560,11 @@
 	if (fie->index >= imx415->cfg_num)
 		return -EINVAL;
 
-	fie->code = supported_modes[fie->index].bus_fmt;
-	fie->width = supported_modes[fie->index].width;
-	fie->height = supported_modes[fie->index].height;
-	fie->interval = supported_modes[fie->index].max_fps;
-	fie->reserved[0] = supported_modes[fie->index].hdr_mode;
+	fie->code = imx415->supported_modes[fie->index].bus_fmt;
+	fie->width = imx415->supported_modes[fie->index].width;
+	fie->height = imx415->supported_modes[fie->index].height;
+	fie->interval = imx415->supported_modes[fie->index].max_fps;
+	fie->reserved[0] = imx415->supported_modes[fie->index].hdr_mode;
 	return 0;
 }
 
@@ -2401,8 +2782,10 @@
 	struct v4l2_ctrl_handler *handler;
 	s64 exposure_max, vblank_def;
 	u64 pixel_rate;
+	u64 max_pixel_rate;
 	u32 h_blank;
 	int ret;
+	u8 lanes = imx415->bus_cfg.bus.mipi_csi2.num_data_lanes;
 
 	handler = &imx415->ctrl_handler;
 	mode = imx415->cur_mode;
@@ -2418,9 +2801,10 @@
 	v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx);
 
 	/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
-	pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * IMX415_4LANES;
+	pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * lanes;
+	max_pixel_rate = MIPI_FREQ_1188M / mode->bpp * 2 * lanes;
 	imx415->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
-		V4L2_CID_PIXEL_RATE, 0, IMX415_MAX_PIXEL_RATE,
+		V4L2_CID_PIXEL_RATE, 0, max_pixel_rate,
 		1, pixel_rate);
 
 	h_blank = mode->hts_def - mode->width;
@@ -2511,6 +2895,7 @@
 	struct device_node *node = dev->of_node;
 	struct imx415 *imx415;
 	struct v4l2_subdev *sd;
+	struct device_node *endpoint;
 	char facing[2];
 	int ret;
 	u32 i, hdr_mode = 0;
@@ -2542,16 +2927,41 @@
 		hdr_mode = NO_HDR;
 		dev_warn(dev, " Get hdr mode failed! no hdr default\n");
 	}
+
+	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+	if (!endpoint) {
+		dev_err(dev, "Failed to get endpoint\n");
+		return -EINVAL;
+	}
+
+	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
+		&imx415->bus_cfg);
+	of_node_put(endpoint);
+	if (ret) {
+		dev_err(dev, "Failed to get bus config\n");
+		return -EINVAL;
+	}
+
 	imx415->client = client;
-	imx415->cfg_num = ARRAY_SIZE(supported_modes);
+	if (imx415->bus_cfg.bus.mipi_csi2.num_data_lanes == IMX415_4LANES) {
+		imx415->supported_modes = supported_modes;
+		imx415->cfg_num = ARRAY_SIZE(supported_modes);
+	} else {
+		imx415->supported_modes = supported_modes_2lane;
+		imx415->cfg_num = ARRAY_SIZE(supported_modes_2lane);
+	}
+	dev_info(dev, "detect imx415 lane %d\n",
+		imx415->bus_cfg.bus.mipi_csi2.num_data_lanes);
+
 	for (i = 0; i < imx415->cfg_num; i++) {
-		if (hdr_mode == supported_modes[i].hdr_mode) {
-			imx415->cur_mode = &supported_modes[i];
+		if (hdr_mode == imx415->supported_modes[i].hdr_mode) {
+			imx415->cur_mode = &imx415->supported_modes[i];
 			break;
 		}
 	}
 
-	imx415->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
+	of_property_read_u32(node, RKMODULE_CAMERA_FASTBOOT_ENABLE,
+		&imx415->is_thunderboot);
 
 	imx415->xvclk = devm_clk_get(dev, "xvclk");
 	if (IS_ERR(imx415->xvclk)) {
diff --git a/kernel/drivers/media/i2c/imx464.c b/kernel/drivers/media/i2c/imx464.c
index 10674ea..142550a 100644
--- a/kernel/drivers/media/i2c/imx464.c
+++ b/kernel/drivers/media/i2c/imx464.c
@@ -1854,7 +1854,7 @@
 		__LINE__, rhs1, s_exp_time, rhs1_old,
 		(rhs1_old + 2 * BRL - fsc + 2));
 
-	rhs1 = (rhs1 >> 2) * 4 + 1;
+	rhs1 = ((rhs1 + 3) >> 2) * 4 + 1;
 	rhs1_old = rhs1;
 
 	if (rhs1 - s_exp_time <= SHR1_MIN) {
diff --git a/kernel/drivers/media/i2c/imx577.c b/kernel/drivers/media/i2c/imx577.c
index b1567c2..0658f46 100644
--- a/kernel/drivers/media/i2c/imx577.c
+++ b/kernel/drivers/media/i2c/imx577.c
@@ -62,7 +62,7 @@
 
 #define IMX577_REG_EXPOSURE_H		0x0202
 #define IMX577_REG_EXPOSURE_L		0x0203
-#define	IMX577_EXPOSURE_MIN		4
+#define	IMX577_EXPOSURE_MIN		8
 #define	IMX577_EXPOSURE_STEP		1
 #define IMX577_VTS_MAX			0xffff
 
@@ -971,7 +971,7 @@
 			.numerator = 10000,
 			.denominator = 300000,
 		},
-		.exp_def = 0x0c10,
+		.exp_def = 0x0c08,
 		.hts_def = 0x11a0,
 		.vts_def = 0x0c1e,
 		.bpp = 10,
@@ -991,7 +991,7 @@
 			.numerator = 10000,
 			.denominator = 600000,
 		},
-		.exp_def = 0x0c10,
+		.exp_def = 0x0c08,
 		.hts_def = 0x11a0,
 		.vts_def = 0x0c1e,
 		.bpp = 10,
@@ -2031,7 +2031,7 @@
 	case V4L2_CID_VBLANK:
 		if (imx577->cur_mode->hdr_mode == NO_HDR) {
 			/* Update max exposure while meeting expected vblanking */
-			max = imx577->cur_mode->height + ctrl->val - 4;
+			max = imx577->cur_mode->height + ctrl->val - 22;
 			__v4l2_ctrl_modify_range(imx577->exposure,
 					 imx577->exposure->minimum, max,
 					 imx577->exposure->step,
@@ -2195,7 +2195,7 @@
 				IMX577_VTS_MAX - mode->height,
 				1, vblank_def);
 	imx577->cur_vts = mode->vts_def;
-	exposure_max = mode->vts_def - 4;
+	exposure_max = mode->vts_def - 22;
 	imx577->exposure = v4l2_ctrl_new_std(handler, &imx577_ctrl_ops,
 				V4L2_CID_EXPOSURE, IMX577_EXPOSURE_MIN,
 				exposure_max, IMX577_EXPOSURE_STEP,
diff --git a/kernel/drivers/media/i2c/jaguar1_drv/jaguar1_v4l2.c b/kernel/drivers/media/i2c/jaguar1_drv/jaguar1_v4l2.c
index 1538a91..432cc06 100644
--- a/kernel/drivers/media/i2c/jaguar1_drv/jaguar1_v4l2.c
+++ b/kernel/drivers/media/i2c/jaguar1_drv/jaguar1_v4l2.c
@@ -3,6 +3,7 @@
  * jaguar1 driver
  * V0.0X01.0X00 first version.
  * V0.0X01.0X01 fix kernel5.10 compile error.
+ * V0.0X01.0X02 add workqueue to detect ahd state.
  *
  */
 
@@ -41,7 +42,19 @@
 #include "jaguar1_drv.h"
 #include "jaguar1_v4l2.h"
 
-#define DRIVER_VERSION				KERNEL_VERSION(0, 0x01, 0x1)
+#define WORK_QUEUE
+
+#ifdef WORK_QUEUE
+#include <linux/workqueue.h>
+
+struct sensor_state_check_work {
+	struct workqueue_struct *state_check_wq;
+	struct delayed_work d_work;
+};
+
+#endif
+
+#define DRIVER_VERSION				KERNEL_VERSION(0, 0x01, 0x2)
 
 #ifndef V4L2_CID_DIGITAL_GAIN
 #define V4L2_CID_DIGITAL_GAIN			V4L2_CID_GAIN
@@ -104,6 +117,12 @@
 	unsigned int height;
 };
 
+enum jaguar1_hot_plug_state {
+	PLUG_IN = 0,
+	PLUG_OUT,
+	PLUG_STATE_MAX,
+};
+
 struct jaguar1 {
 	struct i2c_client	*client;
 	struct clk		*xvclk;
@@ -134,6 +153,16 @@
 	const struct jaguar1_framesize *frame_size;
 	int streaming;
 	struct jaguar1_default_rect defrect;
+#ifdef WORK_QUEUE
+	struct sensor_state_check_work plug_state_check;
+	u8 cur_detect_status;
+	u8 last_detect_status;
+	u64 timestamp0;
+	u64 timestamp1;
+#endif
+	bool hot_plug;
+	u8 is_reset;
+	struct semaphore reg_sem;
 };
 
 #define to_jaguar1(sd) container_of(sd, struct jaguar1, subdev)
@@ -212,6 +241,63 @@
 static const s64 link_freq_menu_items[] = {
 	JAGUAR1_LINK_FREQ
 };
+
+/* sensor register write */
+static int jaguar1_write(struct i2c_client *client, u8 reg, u8 val)
+{
+	struct i2c_msg msg;
+	u8 buf[2];
+	int ret;
+
+	dev_dbg(&client->dev, "write reg(0x%x val:0x%x)!\n", reg, val);
+	buf[0] = reg & 0xFF;
+	buf[1] = val;
+
+	msg.addr = client->addr;
+	msg.flags = client->flags;
+	msg.buf = buf;
+	msg.len = sizeof(buf);
+
+	ret = i2c_transfer(client->adapter, &msg, 1);
+	if (ret >= 0)
+		return 0;
+
+	dev_err(&client->dev,
+		"jaguar1 write reg(0x%x val:0x%x) failed !\n", reg, val);
+
+	return ret;
+}
+
+/* sensor register read */
+static int jaguar1_read(struct i2c_client *client, u8 reg, u8 *val)
+{
+	struct i2c_msg msg[2];
+	u8 buf[1];
+	int ret;
+
+	buf[0] = reg & 0xFF;
+
+	msg[0].addr = client->addr;
+	msg[0].flags = client->flags;
+	msg[0].buf = buf;
+	msg[0].len = sizeof(buf);
+
+	msg[1].addr = client->addr;
+	msg[1].flags = client->flags | I2C_M_RD;
+	msg[1].buf = buf;
+	msg[1].len = 1;
+
+	ret = i2c_transfer(client->adapter, msg, 2);
+	if (ret >= 0) {
+		*val = buf[0];
+		return 0;
+	}
+
+	dev_err(&client->dev, "jaguar1 read reg(0x%x) failed !\n", reg);
+
+	return ret;
+}
+
 static int __jaguar1_power_on(struct jaguar1 *jaguar1)
 {
 	u32 i;
@@ -340,7 +426,7 @@
 	struct jaguar1 *jaguar1 = to_jaguar1(sd);
 	int ret = 0;
 
-	dev_dbg(&client->dev, "%s: on %d\n", __func__, on);
+	dev_info(&client->dev, "%s: on %d\n", __func__, on);
 	mutex_lock(&jaguar1->mutex);
 
 	/* If the power state is not modified - no work to do. */
@@ -351,11 +437,12 @@
 		ret = __jaguar1_power_on(jaguar1);
 		if (ret < 0)
 			goto exit;
-
 		jaguar1->power_on = true;
+
 	} else {
 		__jaguar1_power_off(jaguar1);
 		jaguar1->power_on = false;
+
 	}
 
 exit:
@@ -430,6 +517,7 @@
 	format->field = match->field;
 }
 
+static inline bool jaguar1_no_signal(struct v4l2_subdev *sd, u8 *novid);
 static int jaguar1_stream(struct v4l2_subdev *sd, int on)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -438,7 +526,7 @@
 	enum NC_VIVO_CH_FORMATDEF fmt_idx;
 	int ch;
 
-	dev_dbg(&client->dev, "%s: on %d\n", __func__, on);
+	dev_info(&client->dev, "%s: on %d\n", __func__, on);
 	mutex_lock(&jaguar1->mutex);
 	on = !!on;
 
@@ -455,8 +543,35 @@
 			video_init.ch_param[ch].interface = YUV_422;
 		}
 		jaguar1_start(&video_init);
+#ifdef WORK_QUEUE
+		jaguar1->hot_plug = false;
+		jaguar1->is_reset = 0;
+		usleep_range(20000, 21000);
+		/* get power on state first*/
+		jaguar1_no_signal(sd, &jaguar1->last_detect_status);
+		/* check hot plug state */
+		if (jaguar1->plug_state_check.state_check_wq) {
+			dev_info(&client->dev, "%s queue_delayed_work 1000ms", __func__);
+			queue_delayed_work(jaguar1->plug_state_check.state_check_wq,
+					   &jaguar1->plug_state_check.d_work,
+					   msecs_to_jiffies(1000));
+		}
+		jaguar1->timestamp0 = ktime_get_ns();
+#endif
 	} else {
 		jaguar1_stop();
+#ifdef WORK_QUEUE
+		jaguar1->timestamp1 = ktime_get_ns();
+		/* if stream off & on interval too short, do repower */
+		if (div_u64((jaguar1->timestamp1 - jaguar1->timestamp0), 1000000) < 1200) {
+			dev_info(&client->dev, "stream on/off too short, do power off & on!");
+			__jaguar1_power_off(jaguar1);
+			usleep_range(40000, 41000);
+			__jaguar1_power_on(jaguar1);
+		}
+		cancel_delayed_work_sync(&jaguar1->plug_state_check.d_work);
+		dev_info(&client->dev, "cancle_queue_delayed_work");
+#endif
 	}
 
 	jaguar1->streaming = on;
@@ -505,12 +620,144 @@
 	return 0;
 }
 
+/* indicate N4 no signal channel */
+static inline bool jaguar1_no_signal(struct v4l2_subdev *sd, u8 *novid)
+{
+	struct jaguar1 *jaguar1 = to_jaguar1(sd);
+	struct i2c_client *client = jaguar1->client;
+	u8 videoloss = 0;
+	u8 temp = 0;
+	int ch, ret;
+	bool no_signal = false;
+
+	jaguar1_write(client, 0xff, 0x00);
+	for (ch = 0 ; ch < 4; ch++) {
+		ret = jaguar1_read(client, 0xa4 + ch, &temp);
+		if (ret < 0)
+			dev_err(&client->dev, "Failed to read videoloss state!\n");
+		videoloss |= (temp << ch);
+	}
+	*novid = videoloss;
+	dev_dbg(&client->dev, "%s: video loss status:0x%x.\n", __func__, videoloss);
+	if (videoloss == 0xf) {
+		dev_dbg(&client->dev, "%s: all channels No Video detected.\n", __func__);
+		no_signal = true;
+	} else {
+		dev_dbg(&client->dev, "%s: channel has some video detection.\n", __func__);
+		no_signal = false;
+	}
+	return no_signal;
+}
+
+/* indicate N4 channel locked status */
+static inline bool jaguar1_sync(struct v4l2_subdev *sd, u8 *lock_st)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	u8 video_lock_status = 0;
+	u8 temp = 0;
+	int ch, ret;
+	bool has_sync = false;
+
+	jaguar1_write(client, 0xff, 0x00);
+	for (ch = 0 ; ch < 4; ch++) {
+		ret = jaguar1_read(client, 0xd0 + ch, &temp);
+		if (ret < 0)
+			dev_err(&client->dev, "Failed to read LOCK status!\n");
+		video_lock_status |= (temp << ch);
+	}
+
+	dev_dbg(&client->dev, "%s: video AGC LOCK status:0x%x.\n",
+			__func__, video_lock_status);
+	*lock_st = video_lock_status;
+	if (video_lock_status) {
+		dev_dbg(&client->dev, "%s: channel has AGC LOCK.\n", __func__);
+		has_sync = true;
+	} else {
+		dev_dbg(&client->dev, "%s: channel has no AGC LOCK.\n", __func__);
+		has_sync = false;
+	}
+	return has_sync;
+}
+
+#ifdef WORK_QUEUE
+static void jaguar1_plug_state_check_work(struct work_struct *work)
+{
+	struct sensor_state_check_work *params_check =
+		container_of(work, struct sensor_state_check_work, d_work.work);
+	struct jaguar1 *jaguar1 =
+		container_of(params_check, struct jaguar1, plug_state_check);
+	struct i2c_client *client = jaguar1->client;
+	struct v4l2_subdev *sd = &jaguar1->subdev;
+	u8 novid_status = 0x00;
+	u8 sync_status = 0x00;
+
+	down(&jaguar1->reg_sem);
+	jaguar1_no_signal(sd, &novid_status);
+	jaguar1_sync(sd, &sync_status);
+	up(&jaguar1->reg_sem);
+	jaguar1->cur_detect_status = novid_status;
+
+	/* detect state change to determine is there has plug motion */
+	novid_status = jaguar1->cur_detect_status ^ jaguar1->last_detect_status;
+	if (novid_status)
+		jaguar1->hot_plug = true;
+	else
+		jaguar1->hot_plug = false;
+	jaguar1->last_detect_status = jaguar1->cur_detect_status;
+
+	if (jaguar1->hot_plug)
+		dev_info(&client->dev, "%s has plug motion? (%s)", __func__,
+				jaguar1->hot_plug ? "true" : "false");
+	if (jaguar1->hot_plug) {
+		dev_dbg(&client->dev, "queue_delayed_work 1500ms, if has hot plug motion.");
+		queue_delayed_work(jaguar1->plug_state_check.state_check_wq,
+				   &jaguar1->plug_state_check.d_work, msecs_to_jiffies(1500));
+		jaguar1_write(client, 0xFF, 0x20);
+		jaguar1_write(client, 0x00, 0x00);
+		//jaguar1_write(client, 0x00, (sync_status << 4) | sync_status);
+		usleep_range(3000, 5000);
+		jaguar1_write(client, 0x00, 0xFF);
+	} else {
+		dev_dbg(&client->dev, "queue_delayed_work 100ms, if no hot plug motion.");
+		queue_delayed_work(jaguar1->plug_state_check.state_check_wq,
+				   &jaguar1->plug_state_check.d_work, msecs_to_jiffies(100));
+	}
+}
+#endif
+
+static int jaguar1_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct jaguar1 *jaguar1 = to_jaguar1(sd);
+	int ret;
+	u8 temp_novid;
+	u8 temp_lock_st;
+
+	if (!jaguar1->power_on) {
+		ret = __jaguar1_power_on(jaguar1);
+		if (ret < 0)
+			goto exit;
+		usleep_range(40000, 50000);
+		jaguar1->power_on = true;
+	}
+
+	*status = 0;
+	*status |= jaguar1_no_signal(sd, &temp_novid) ? V4L2_IN_ST_NO_SIGNAL : 0;
+	*status |= jaguar1_sync(sd, &temp_lock_st) ? 0 : V4L2_IN_ST_NO_SYNC;
+
+	dev_info(&client->dev, "%s: status = 0x%x\n", __func__, *status);
+
+exit:
+	return 0;
+}
+
 static int jaguar1_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
 				 struct v4l2_mbus_config *cfg)
 {
 	cfg->type = V4L2_MBUS_CSI2_DPHY;
 	cfg->flags = V4L2_MBUS_CSI2_4_LANE |
-		     V4L2_MBUS_CSI2_CHANNELS;
+		     V4L2_MBUS_CSI2_CHANNELS |
+		     V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
 
 	return 0;
 }
@@ -660,17 +907,67 @@
 	strlcpy(inf->base.lens, jaguar1->len_name, sizeof(inf->base.lens));
 }
 
+static void jaguar1_get_vicap_rst_inf(struct jaguar1 *jaguar1,
+				   struct rkmodule_vicap_reset_info *rst_info)
+{
+	struct i2c_client *client = jaguar1->client;
+
+	rst_info->is_reset = jaguar1->hot_plug;
+	jaguar1->hot_plug = false;
+	rst_info->src = RKCIF_RESET_SRC_ERR_HOTPLUG;
+	if (rst_info->is_reset)
+		dev_info(&client->dev, "%s: rst_info->is_reset:%d.\n",
+				 __func__, rst_info->is_reset);
+}
+
+static void jaguar1_set_vicap_rst_inf(struct jaguar1 *jaguar1,
+				   struct rkmodule_vicap_reset_info rst_info)
+{
+	jaguar1->is_reset = rst_info.is_reset;
+	jaguar1->hot_plug = rst_info.is_reset;
+}
+
+static void jaguar1_set_streaming(struct jaguar1 *jaguar1, int on)
+{
+	struct i2c_client *client = jaguar1->client;
+
+
+	dev_info(&client->dev, "%s: on: %d\n", __func__, on);
+	down(&jaguar1->reg_sem);
+	if (on) {
+		/* enter mipi clk normal operation */
+		jaguar1_write(client, 0xff, 0x21);
+		jaguar1_write(client, 0x46, 0x00);
+	} else {
+		/* enter mipi clk powerdown */
+		jaguar1_write(client, 0xff, 0x21);
+		jaguar1_write(client, 0x46, 0x01);
+	}
+	up(&jaguar1->reg_sem);
+}
+
 static long jaguar1_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
 	struct jaguar1 *jaguar1 = to_jaguar1(sd);
 	long ret = 0;
+	u32 stream = 0;
 
 	switch (cmd) {
 	case RKMODULE_GET_MODULE_INFO:
 		jaguar1_get_module_inf(jaguar1, (struct rkmodule_inf *)arg);
 		break;
+	case RKMODULE_GET_VICAP_RST_INFO:
+		jaguar1_get_vicap_rst_inf(jaguar1, (struct rkmodule_vicap_reset_info *)arg);
+		break;
+	case RKMODULE_SET_VICAP_RST_INFO:
+		jaguar1_set_vicap_rst_inf(jaguar1, *(struct rkmodule_vicap_reset_info *)arg);
+		break;
 	case RKMODULE_GET_START_STREAM_SEQ:
 		*(int *)arg = RKMODULE_START_STREAM_FRONT;
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		stream = *((u32 *)arg);
+		jaguar1_set_streaming(jaguar1, !!stream);
 		break;
 	default:
 		ret = -ENOTTY;
@@ -687,8 +984,10 @@
 	void __user *up = compat_ptr(arg);
 	struct rkmodule_inf *inf;
 	struct rkmodule_awb_cfg *cfg;
+	struct rkmodule_vicap_reset_info *vicap_rst_inf;
 	long ret;
 	int *seq;
+	u32 stream = 0;
 
 	switch (cmd) {
 	case RKMODULE_GET_MODULE_INFO:
@@ -720,6 +1019,35 @@
 			ret = -EFAULT;
 		kfree(cfg);
 		break;
+	case RKMODULE_GET_VICAP_RST_INFO:
+		vicap_rst_inf = kzalloc(sizeof(*vicap_rst_inf), GFP_KERNEL);
+		if (!vicap_rst_inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = jaguar1_ioctl(sd, cmd, vicap_rst_inf);
+		if (!ret) {
+			ret = copy_to_user(up, vicap_rst_inf, sizeof(*vicap_rst_inf));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(vicap_rst_inf);
+		break;
+	case RKMODULE_SET_VICAP_RST_INFO:
+		vicap_rst_inf = kzalloc(sizeof(*vicap_rst_inf), GFP_KERNEL);
+		if (!vicap_rst_inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(vicap_rst_inf, up, sizeof(*vicap_rst_inf));
+		if (!ret)
+			ret = jaguar1_ioctl(sd, cmd, vicap_rst_inf);
+		else
+			ret = -EFAULT;
+		kfree(vicap_rst_inf);
+		break;
 	case RKMODULE_GET_START_STREAM_SEQ:
 		seq = kzalloc(sizeof(*seq), GFP_KERNEL);
 		if (!seq) {
@@ -734,6 +1062,13 @@
 				ret = -EFAULT;
 		}
 		kfree(seq);
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		ret = copy_from_user(&stream, up, sizeof(u32));
+		if (!ret)
+			ret = jaguar1_ioctl(sd, cmd, &stream);
+		else
+			ret = -EFAULT;
 		break;
 	default:
 		ret = -ENOIOCTLCMD;
@@ -770,6 +1105,7 @@
 };
 
 static const struct v4l2_subdev_video_ops jaguar1_video_ops = {
+	.g_input_status = jaguar1_g_input_status,
 	.s_stream = jaguar1_stream,
 	.g_frame_interval = jaguar1_g_frame_interval,
 };
@@ -984,7 +1320,7 @@
 	}
 
 	__jaguar1_power_on(jaguar1);
-	ret = jaguar1_init(i2c_adapter_id(client->adapter));
+	ret |= jaguar1_init(i2c_adapter_id(client->adapter));
 	if (ret) {
 		dev_err(dev, "Failed to init jaguar1\n");
 		__jaguar1_power_off(jaguar1);
@@ -992,7 +1328,7 @@
 
 		return ret;
 	}
-
+	sema_init(&jaguar1->reg_sem, 1);
 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
 	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 #endif
@@ -1034,6 +1370,22 @@
 
 	v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
 			client->addr << 1, client->adapter->name);
+#ifdef WORK_QUEUE
+	/* init work_queue for state_check */
+	INIT_DELAYED_WORK(&jaguar1->plug_state_check.d_work, jaguar1_plug_state_check_work);
+	jaguar1->plug_state_check.state_check_wq =
+		create_singlethread_workqueue("jaguar1_work_queue");
+	if (jaguar1->plug_state_check.state_check_wq == NULL) {
+		dev_err(dev, "%s(%d): %s create failed.\n", __func__, __LINE__,
+			"jaguar1_work_queue");
+	}
+	jaguar1->cur_detect_status = 0x0;
+	jaguar1->last_detect_status = 0x0;
+	jaguar1->hot_plug = false;
+	jaguar1->is_reset = 0;
+
+#endif
+
 	return 0;
 
 err_power_off:
@@ -1060,7 +1412,10 @@
 	if (!pm_runtime_status_suspended(&client->dev))
 		__jaguar1_power_off(jaguar1);
 	pm_runtime_set_suspended(&client->dev);
-
+#ifdef WORK_QUEUE
+	if (jaguar1->plug_state_check.state_check_wq != NULL)
+		destroy_workqueue(jaguar1->plug_state_check.state_check_wq);
+#endif
 	return 0;
 }
 
diff --git a/kernel/drivers/media/i2c/lt6911uxc.c b/kernel/drivers/media/i2c/lt6911uxc.c
index c801d29..dc30a14 100644
--- a/kernel/drivers/media/i2c/lt6911uxc.c
+++ b/kernel/drivers/media/i2c/lt6911uxc.c
@@ -6,6 +6,8 @@
  * V0.0X01.0X00 first version.
  * V0.0X01.0X01 fix if plugin_gpio was not used.
  * V0.0X01.0X02 modify driver init level to late_initcall.
+ * V0.0X01.0X03 add 4K60 dual mipi support
+ *
  */
 
 #include <linux/clk.h>
@@ -34,12 +36,16 @@
 #include <media/v4l2-fwnode.h>
 #include "lt6911uxc.h"
 
-#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x2)
+#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x3)
 #define LT6911UXC_NAME			"LT6911UXC"
 
-#define LT6911UXC_LINK_FREQ_HIGH	400000000
-#define LT6911UXC_LINK_FREQ_LOW		200000000
-#define LT6911UXC_PIXEL_RATE		400000000
+#define LT6911UXC_LINK_FREQ_650M	650000000
+#define LT6911UXC_LINK_FREQ_400M	400000000
+#define LT6911UXC_LINK_FREQ_300M	300000000
+#define LT6911UXC_LINK_FREQ_200M	200000000
+#define LT6911UXC_LINK_FREQ_100M	100000000
+#define LT6911UXC_LINK_FREQ_60M		60000000
+#define LT6911UXC_PIXEL_RATE		600000000
 
 #define I2C_MAX_XFER_SIZE		128
 
@@ -54,8 +60,12 @@
 MODULE_PARM_DESC(debug, "debug level (0-2)");
 
 static const s64 link_freq_menu_items[] = {
-	LT6911UXC_LINK_FREQ_HIGH,
-	LT6911UXC_LINK_FREQ_LOW,
+	LT6911UXC_LINK_FREQ_650M,
+	LT6911UXC_LINK_FREQ_400M,
+	LT6911UXC_LINK_FREQ_300M,
+	LT6911UXC_LINK_FREQ_200M,
+	LT6911UXC_LINK_FREQ_100M,
+	LT6911UXC_LINK_FREQ_60M,
 };
 
 struct lt6911uxc {
@@ -78,6 +88,7 @@
 	struct v4l2_dv_timings timings;
 	struct v4l2_fwnode_bus_mipi_csi2 bus;
 	struct v4l2_subdev sd;
+	struct rkmodule_multi_dev_info multi_dev_info;
 	const char *len_name;
 	const char *module_facing;
 	const char *module_name;
@@ -100,13 +111,25 @@
 	u32 hts_def;
 	u32 vts_def;
 	u32 exp_def;
+	u32 mipi_freq_idx;
+};
+
+static struct rkmodule_csi_dphy_param rk3588_dcphy_param = {
+	.vendor = PHY_VENDOR_SAMSUNG,
+	.lp_vol_ref = 3,
+	.lp_hys_sw = {3, 0, 3, 0},
+	.lp_escclk_pol_sel = {1, 1, 0, 0},
+	.skew_data_cal_clk = {0, 0, 0, 0},
+	.clk_hs_term_sel = 2,
+	.data_hs_term_sel = {2, 2, 2, 2},
+	.reserved = {0},
 };
 
 static const struct v4l2_dv_timings_cap lt6911uxc_timings_cap = {
 	.type = V4L2_DV_BT_656_1120,
 	/* keep this initialization for compatibility with GCC < 4.4.6 */
 	.reserved = { 0 },
-	V4L2_INIT_BT_TIMINGS(1, 10000, 1, 10000, 0, 400000000,
+	V4L2_INIT_BT_TIMINGS(1, 10000, 1, 10000, 0, 600000000,
 			V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
 			V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT,
 			V4L2_DV_BT_CAP_PROGRESSIVE |
@@ -121,10 +144,21 @@
 		.height = 2160,
 		.max_fps = {
 			.numerator = 10000,
+			.denominator = 600000,
+		},
+		.hts_def = 4400,
+		.vts_def = 2250,
+		.mipi_freq_idx = 0,
+	}, {
+		.width = 3840,
+		.height = 2160,
+		.max_fps = {
+			.numerator = 10000,
 			.denominator = 300000,
 		},
 		.hts_def = 4400,
 		.vts_def = 2250,
+		.mipi_freq_idx = 0,
 	}, {
 		.width = 1920,
 		.height = 1080,
@@ -134,6 +168,7 @@
 		},
 		.hts_def = 2200,
 		.vts_def = 1125,
+		.mipi_freq_idx = 2,
 	}, {
 		.width = 1920,
 		.height = 540,
@@ -141,6 +176,7 @@
 			.numerator = 10000,
 			.denominator = 600000,
 		},
+		.mipi_freq_idx = 3,
 	}, {
 		.width = 1440,
 		.height = 240,
@@ -148,6 +184,7 @@
 			.numerator = 10000,
 			.denominator = 600000,
 		},
+		.mipi_freq_idx = 4,
 	}, {
 		.width = 1440,
 		.height = 288,
@@ -155,6 +192,7 @@
 			.numerator = 10000,
 			.denominator = 500000,
 		},
+		.mipi_freq_idx = 4,
 	}, {
 		.width = 1280,
 		.height = 720,
@@ -164,6 +202,7 @@
 		},
 		.hts_def = 1650,
 		.vts_def = 750,
+		.mipi_freq_idx = 3,
 	}, {
 		.width = 720,
 		.height = 576,
@@ -173,6 +212,7 @@
 		},
 		.hts_def = 864,
 		.vts_def = 625,
+		.mipi_freq_idx = 5,
 	}, {
 		.width = 720,
 		.height = 480,
@@ -182,6 +222,7 @@
 		},
 		.hts_def = 858,
 		.vts_def = 525,
+		.mipi_freq_idx = 5,
 	},
 };
 
@@ -390,6 +431,7 @@
 	u8 value, val_h, val_l;
 	u32 fw_ver, mipi_byte_clk, mipi_bitrate;
 	u8 fw_a, fw_b, fw_c, fw_d, lanes;
+	u8 video_fmt;
 	int ret;
 
 	memset(timings, 0, sizeof(struct v4l2_dv_timings));
@@ -421,13 +463,15 @@
 
 	i2c_rd8(sd, MIPI_LANES, &lanes);
 	lt6911uxc->csi_lanes_in_use = lanes;
+	if (lt6911uxc->csi_lanes_in_use == 8)
+		v4l2_info(sd, "get 8 lane in use, set dual mipi mode\n");
 	i2c_wr8(sd, FM1_DET_CLK_SRC_SEL, AD_LMTX_WRITE_CLK);
 	i2c_rd8(sd, FREQ_METER_H, &clk_h);
 	i2c_rd8(sd, FREQ_METER_M, &clk_m);
 	i2c_rd8(sd, FREQ_METER_L, &clk_l);
 	mipi_byte_clk = (((clk_h & 0xf) << 16) | (clk_m << 8) | clk_l);
 	mipi_bitrate = mipi_byte_clk * 8 / 1000;
-	v4l2_info(sd, "MIPI Byte clk: %dKHz, MIPI bitrate: %dMbps, lanes:%d\n",
+	v4l2_info(sd, "MIPI Byte clk: %uKHz, MIPI bitrate: %uMbps, lanes:%d\n",
 			mipi_byte_clk, mipi_bitrate, lanes);
 
 	i2c_rd8(sd, HTOTAL_H, &val_h);
@@ -457,7 +501,15 @@
 	hbp = ((val_h << 8) | val_l) * 2;
 	i2c_rd8(sd, VBP, &value);
 	vbp = value;
+	i2c_rd8(sd, COLOR_FMT_STATUS, &video_fmt);
+	video_fmt = (video_fmt & GENMASK(6, 5)) >> 5;
 	lt6911uxc_i2c_disable(sd);
+
+	if (video_fmt == 0x3) {
+		lt6911uxc->nosignal = true;
+		v4l2_err(sd, "%s ERROR: HDMI input YUV420, don't support YUV420!\n", __func__);
+		return -EINVAL;
+	}
 
 	if (!lt6911uxc_rcv_supported_res(sd, hact, vact)) {
 		lt6911uxc->nosignal = true;
@@ -694,7 +746,6 @@
 	}
 
 	lt6911uxc->timings = *timings;
-
 	enable_stream(sd, false);
 
 	return 0;
@@ -771,7 +822,9 @@
 	case 4:
 		cfg->flags |= V4L2_MBUS_CSI2_4_LANE;
 		break;
-
+	case 8:
+		cfg->flags |= V4L2_MBUS_CSI2_4_LANE;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -836,11 +889,50 @@
 	return 0;
 }
 
+static int lt6911uxc_get_reso_dist(const struct lt6911uxc_mode *mode,
+		struct v4l2_dv_timings *timings)
+{
+	struct v4l2_bt_timings *bt = &timings->bt;
+	u32 cur_fps, dist_fps;
+
+	cur_fps = fps_calc(bt);
+	dist_fps = DIV_ROUND_CLOSEST(mode->max_fps.denominator, mode->max_fps.numerator);
+
+	return abs(mode->width - bt->width) +
+		abs(mode->height - bt->height) + abs(dist_fps - cur_fps);
+}
+
+static const struct lt6911uxc_mode *
+lt6911uxc_find_best_fit(struct lt6911uxc *lt6911uxc)
+{
+	int dist;
+	int cur_best_fit = 0;
+	int cur_best_fit_dist = -1;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+		dist = lt6911uxc_get_reso_dist(&supported_modes[i], &lt6911uxc->timings);
+		if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
+			cur_best_fit_dist = dist;
+			cur_best_fit = i;
+		}
+	}
+	dev_info(&lt6911uxc->i2c_client->dev,
+		"find current mode: support_mode[%d], %dx%d@%dfps\n",
+		cur_best_fit, supported_modes[cur_best_fit].width,
+		supported_modes[cur_best_fit].height,
+		DIV_ROUND_CLOSEST(supported_modes[cur_best_fit].max_fps.denominator,
+		supported_modes[cur_best_fit].max_fps.numerator));
+
+	return &supported_modes[cur_best_fit];
+}
+
 static int lt6911uxc_get_fmt(struct v4l2_subdev *sd,
 		struct v4l2_subdev_pad_config *cfg,
 		struct v4l2_subdev_format *format)
 {
 	struct lt6911uxc *lt6911uxc = to_state(sd);
+	const struct lt6911uxc_mode *mode;
 
 	mutex_lock(&lt6911uxc->confctl_mutex);
 	format->format.code = lt6911uxc->mbus_fmt_code;
@@ -850,6 +942,14 @@
 		lt6911uxc->timings.bt.interlaced ?
 		V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
 	format->format.colorspace = V4L2_COLORSPACE_SRGB;
+
+	mode = lt6911uxc_find_best_fit(lt6911uxc);
+	lt6911uxc->cur_mode = mode;
+	__v4l2_ctrl_s_ctrl_int64(lt6911uxc->pixel_rate,
+				LT6911UXC_PIXEL_RATE);
+	__v4l2_ctrl_s_ctrl(lt6911uxc->link_freq,
+				mode->mipi_freq_idx);
+
 	mutex_unlock(&lt6911uxc->confctl_mutex);
 
 	v4l2_dbg(1, debug, sd, "%s: fmt code:%d, w:%d, h:%d, field mode:%s\n",
@@ -859,40 +959,12 @@
 	return 0;
 }
 
-static int lt6911uxc_get_reso_dist(const struct lt6911uxc_mode *mode,
-		struct v4l2_mbus_framefmt *framefmt)
-{
-	return abs(mode->width - framefmt->width) +
-	       abs(mode->height - framefmt->height);
-}
-
-static const struct lt6911uxc_mode *
-lt6911uxc_find_best_fit(struct v4l2_subdev_format *fmt)
-{
-	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
-	int dist;
-	int cur_best_fit = 0;
-	int cur_best_fit_dist = -1;
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
-		dist = lt6911uxc_get_reso_dist(&supported_modes[i], framefmt);
-		if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
-			cur_best_fit_dist = dist;
-			cur_best_fit = i;
-		}
-	}
-
-	return &supported_modes[cur_best_fit];
-}
-
 static int lt6911uxc_set_fmt(struct v4l2_subdev *sd,
 		struct v4l2_subdev_pad_config *cfg,
 		struct v4l2_subdev_format *format)
 {
 	struct lt6911uxc *lt6911uxc = to_state(sd);
 	const struct lt6911uxc_mode *mode;
-	int index;
 
 	/* is overwritten by get_fmt */
 	u32 code = format->format.code;
@@ -915,19 +987,9 @@
 		return 0;
 
 	lt6911uxc->mbus_fmt_code = format->format.code;
-	mode = lt6911uxc_find_best_fit(format);
+	mode = lt6911uxc_find_best_fit(lt6911uxc);
 	lt6911uxc->cur_mode = mode;
 	enable_stream(sd, false);
-
-	if (((mode->width == 720) && (mode->height == 576)) ||
-	    ((mode->width == 720) && (mode->height == 480)))
-		index = 1;
-	else
-		index = 0;
-
-	__v4l2_ctrl_s_ctrl(lt6911uxc->link_freq, index);
-	v4l2_dbg(1, debug, sd, "%s res wxh:%dx%d, link freq:%llu", __func__,
-			mode->width, mode->height, link_freq_menu_items[index]);
 
 	return 0;
 }
@@ -957,7 +1019,10 @@
 static long lt6911uxc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
 	struct lt6911uxc *lt6911uxc = to_state(sd);
+	struct device *dev = &lt6911uxc->i2c_client->dev;
 	long ret = 0;
+	struct rkmodule_csi_dphy_param *dphy_param;
+	struct rkmodule_capture_info  *capture_info;
 
 	switch (cmd) {
 	case RKMODULE_GET_MODULE_INFO:
@@ -965,6 +1030,29 @@
 		break;
 	case RKMODULE_GET_HDMI_MODE:
 		*(int *)arg = RKMODULE_HDMIIN_MODE;
+		break;
+	case RKMODULE_SET_CSI_DPHY_PARAM:
+		dphy_param = (struct rkmodule_csi_dphy_param *)arg;
+		if (dphy_param->vendor == PHY_VENDOR_SAMSUNG)
+			rk3588_dcphy_param = *dphy_param;
+		dev_dbg(&lt6911uxc->i2c_client->dev,
+			"sensor set dphy param\n");
+		break;
+	case RKMODULE_GET_CSI_DPHY_PARAM:
+		dphy_param = (struct rkmodule_csi_dphy_param *)arg;
+		*dphy_param = rk3588_dcphy_param;
+		dev_dbg(&lt6911uxc->i2c_client->dev,
+			"sensor get dphy param\n");
+		break;
+	case RKMODULE_GET_CAPTURE_MODE:
+		capture_info = (struct rkmodule_capture_info *)arg;
+		if (lt6911uxc->csi_lanes_in_use == 8) {
+			dev_info(dev, "8 lanes in use, set dual mipi mode\n");
+			capture_info->mode = RKMODULE_MULTI_DEV_COMBINE_ONE;
+			capture_info->multi_dev = lt6911uxc->multi_dev_info;
+		} else {
+			capture_info->mode = 0;
+		}
 		break;
 	default:
 		ret = -ENOIOCTLCMD;
@@ -982,6 +1070,8 @@
 	struct rkmodule_inf *inf;
 	long ret;
 	int *seq;
+	struct rkmodule_csi_dphy_param *dphy_param;
+	struct rkmodule_capture_info  *capture_info;
 
 	switch (cmd) {
 	case RKMODULE_GET_MODULE_INFO:
@@ -1013,6 +1103,50 @@
 				ret = -EFAULT;
 		}
 		kfree(seq);
+		break;
+	case RKMODULE_SET_CSI_DPHY_PARAM:
+		dphy_param = kzalloc(sizeof(*dphy_param), GFP_KERNEL);
+		if (!dphy_param) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(dphy_param, up, sizeof(*dphy_param));
+		if (!ret)
+			ret = lt6911uxc_ioctl(sd, cmd, dphy_param);
+		else
+			ret = -EFAULT;
+		kfree(dphy_param);
+		break;
+	case RKMODULE_GET_CSI_DPHY_PARAM:
+		dphy_param = kzalloc(sizeof(*dphy_param), GFP_KERNEL);
+		if (!dphy_param) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = lt6911uxc_ioctl(sd, cmd, dphy_param);
+		if (!ret) {
+			ret = copy_to_user(up, dphy_param, sizeof(*dphy_param));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(dphy_param);
+		break;
+	case RKMODULE_GET_CAPTURE_MODE:
+		capture_info = kzalloc(sizeof(*capture_info), GFP_KERNEL);
+		if (!capture_info) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = lt6911uxc_ioctl(sd, cmd, capture_info);
+		if (!ret) {
+			ret = copy_to_user(up, capture_info, sizeof(*capture_info));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(capture_info);
 		break;
 	default:
 		ret = -ENOIOCTLCMD;
@@ -1093,9 +1227,11 @@
 
 static int lt6911uxc_init_v4l2_ctrls(struct lt6911uxc *lt6911uxc)
 {
+	const struct lt6911uxc_mode *mode;
 	struct v4l2_subdev *sd;
 	int ret;
 
+	mode = lt6911uxc->cur_mode;
 	sd = &lt6911uxc->sd;
 	ret = v4l2_ctrl_handler_init(&lt6911uxc->hdl, 5);
 	if (ret)
@@ -1105,8 +1241,9 @@
 			V4L2_CID_LINK_FREQ,
 			ARRAY_SIZE(link_freq_menu_items) - 1, 0,
 			link_freq_menu_items);
-	v4l2_ctrl_new_std(&lt6911uxc->hdl, NULL, V4L2_CID_PIXEL_RATE,
-			  0, LT6911UXC_PIXEL_RATE, 1, LT6911UXC_PIXEL_RATE);
+	lt6911uxc->pixel_rate = v4l2_ctrl_new_std(&lt6911uxc->hdl, NULL,
+			V4L2_CID_PIXEL_RATE,
+			0, LT6911UXC_PIXEL_RATE, 1, LT6911UXC_PIXEL_RATE);
 
 	lt6911uxc->detect_tx_5v_ctrl = v4l2_ctrl_new_std(&lt6911uxc->hdl,
 			NULL, V4L2_CID_DV_RX_POWER_PRESENT,
@@ -1124,6 +1261,9 @@
 		v4l2_err(sd, "cfg v4l2 ctrls failed! ret:%d\n", ret);
 		return ret;
 	}
+
+	__v4l2_ctrl_s_ctrl(lt6911uxc->link_freq, mode->mipi_freq_idx);
+	__v4l2_ctrl_s_ctrl_int64(lt6911uxc->pixel_rate, LT6911UXC_PIXEL_RATE);
 
 	if (lt6911uxc_update_controls(sd)) {
 		ret = -ENODEV;
@@ -1309,6 +1449,36 @@
 };
 ATTRIBUTE_GROUPS(lt6911);
 
+static int lt6911uxc_get_multi_dev_info(struct lt6911uxc *lt6911uxc)
+{
+	struct device *dev = &lt6911uxc->i2c_client->dev;
+	struct device_node *node = dev->of_node;
+	struct device_node *multi_info_np;
+
+	multi_info_np = of_get_child_by_name(node, "multi-dev-info");
+	if (!multi_info_np) {
+		dev_info(dev, "failed to get multi dev info\n");
+		return -EINVAL;
+	}
+
+	of_property_read_u32(multi_info_np, "dev-idx-l",
+			&lt6911uxc->multi_dev_info.dev_idx[0]);
+	of_property_read_u32(multi_info_np, "dev-idx-r",
+			&lt6911uxc->multi_dev_info.dev_idx[1]);
+	of_property_read_u32(multi_info_np, "combine-idx",
+			&lt6911uxc->multi_dev_info.combine_idx[0]);
+	of_property_read_u32(multi_info_np, "pixel-offset",
+			&lt6911uxc->multi_dev_info.pixel_offset);
+	of_property_read_u32(multi_info_np, "dev-num",
+			&lt6911uxc->multi_dev_info.dev_num);
+	dev_info(dev,
+		"multi dev left: mipi%d, multi dev right: mipi%d, combile mipi%d, dev num: %d\n",
+		lt6911uxc->multi_dev_info.dev_idx[0], lt6911uxc->multi_dev_info.dev_idx[1],
+		lt6911uxc->multi_dev_info.combine_idx[0], lt6911uxc->multi_dev_info.dev_num);
+
+	return 0;
+}
+
 static int lt6911uxc_probe(struct i2c_client *client,
 		const struct i2c_device_id *id)
 {
@@ -1340,6 +1510,10 @@
 		v4l2_err(sd, "lt6911uxc_parse_of failed! err:%d\n", err);
 		return err;
 	}
+
+	err = lt6911uxc_get_multi_dev_info(lt6911uxc);
+	if (err)
+		v4l2_info(sd, "get multi dev info failed, not use dual mipi mode\n");
 
 	err = lt6911uxc_check_chip_id(lt6911uxc);
 	if (err < 0)
@@ -1497,9 +1671,10 @@
 	i2c_del_driver(&lt6911uxc_driver);
 }
 
-late_initcall(lt6911uxc_driver_init);
+device_initcall_sync(lt6911uxc_driver_init);
 module_exit(lt6911uxc_driver_exit);
 
 MODULE_DESCRIPTION("Lontium LT6911UXC HDMI to MIPI CSI-2 bridge driver");
 MODULE_AUTHOR("Dingxian Wen <shawn.wen@rock-chips.com>");
+MODULE_AUTHOR("Jianwei Fan <jianwei.fan@rock-chips.com>");
 MODULE_LICENSE("GPL v2");
diff --git a/kernel/drivers/media/i2c/lt6911uxc.h b/kernel/drivers/media/i2c/lt6911uxc.h
index 45cb297..29c9217 100644
--- a/kernel/drivers/media/i2c/lt6911uxc.h
+++ b/kernel/drivers/media/i2c/lt6911uxc.h
@@ -65,4 +65,9 @@
 #define AUDIO_SAMPLE_RATAE_H	0xb0aa
 #define AUDIO_SAMPLE_RATAE_L	0xb0ab
 
+#define COLOR_FMT_STATUS	0xb092
+#define STREAM_CTRL		0x811d
+#define STREAM_ENABLE		0xFB
+#define STREAM_DISABLE		0xBB
+
 #endif
diff --git a/kernel/drivers/media/i2c/lt8619c.c b/kernel/drivers/media/i2c/lt8619c.c
index 8743797..6255318 100644
--- a/kernel/drivers/media/i2c/lt8619c.c
+++ b/kernel/drivers/media/i2c/lt8619c.c
@@ -1727,6 +1727,8 @@
 			const struct i2c_device_id *id)
 {
 	struct device *dev = &client->dev;
+	struct v4l2_dv_timings default_timing =
+				V4L2_DV_BT_CEA_640X480P59_94;
 	struct lt8619c *lt8619c;
 	struct v4l2_subdev *sd;
 	char facing[2];
@@ -1743,6 +1745,7 @@
 
 	sd = &lt8619c->sd;
 	lt8619c->i2c_client = client;
+	lt8619c->timings = default_timing;
 	lt8619c->cur_mode = &supported_modes[0];
 	lt8619c->mbus_fmt_code = MEDIA_BUS_FMT_UYVY8_2X8;
 
diff --git a/kernel/drivers/media/i2c/m5mols/m5mols_core.c b/kernel/drivers/media/i2c/m5mols/m5mols_core.c
index 21666d7..dcf9e4d 100644
--- a/kernel/drivers/media/i2c/m5mols/m5mols_core.c
+++ b/kernel/drivers/media/i2c/m5mols/m5mols_core.c
@@ -488,7 +488,7 @@
 	do {
 		if (code == m5mols_default_ffmt[type].code)
 			return type;
-	} while (type++ != SIZE_DEFAULT_FFMT);
+	} while (++type != SIZE_DEFAULT_FFMT);
 
 	return 0;
 }
diff --git a/kernel/drivers/media/i2c/max9286.c b/kernel/drivers/media/i2c/max9286.c
index b1e2476..62ce275 100644
--- a/kernel/drivers/media/i2c/max9286.c
+++ b/kernel/drivers/media/i2c/max9286.c
@@ -890,6 +890,7 @@
 err_put_node:
 	fwnode_handle_put(ep);
 err_async:
+	v4l2_ctrl_handler_free(&priv->ctrls);
 	max9286_v4l2_notifier_unregister(priv);
 
 	return ret;
@@ -898,6 +899,7 @@
 static void max9286_v4l2_unregister(struct max9286_priv *priv)
 {
 	fwnode_handle_put(priv->sd.fwnode);
+	v4l2_ctrl_handler_free(&priv->ctrls);
 	v4l2_async_unregister_subdev(&priv->sd);
 	max9286_v4l2_notifier_unregister(priv);
 }
diff --git a/kernel/drivers/media/i2c/max96756.c b/kernel/drivers/media/i2c/max96756.c
new file mode 100644
index 0000000..2cb2812
--- /dev/null
+++ b/kernel/drivers/media/i2c/max96756.c
@@ -0,0 +1,1397 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * max96756 GMSL2/GMSL1 to CSI-2 Deserializer driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * V0.0X01.0X00 first version.
+ *
+ * V0.0X01.0X01
+ *  - Support V4L2 DV class features
+ */
+#define DEBUG
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/compat.h>
+#include <linux/rk-camera-module.h>
+#include <linux/v4l2-dv-timings.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+#include <linux/pinctrl/consumer.h>
+#include "max96756.h"
+
+#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x01)
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "debug level (0-3)");
+
+#ifndef V4L2_CID_DIGITAL_GAIN
+#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
+#endif
+
+#define MAX96756_LINK_FREQ_MHZ(x) ((x)*1000 * 1000ULL)
+#define MAX96756_PIXEL_RATE (450LL * 2 * 4 / 8)
+
+#define MAX96756_REG_CHIP_ID 0x0D
+#define CHIP_ID 0x90
+
+#define MAX96756_REG_CTRL_MODE 0x0313
+#define MAX96756_MODE_SW_STANDBY 0x0
+#define MAX96756_MODE_STREAMING BIT(1)
+
+#define REG_NULL 0xFFFF
+
+#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
+#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
+
+#define MAX96756_REG_VALUE_08BIT 1
+#define MAX96756_REG_VALUE_16BIT 2
+
+#define MAX96756_NAME "max96756"
+#define MAX96756_MEDIA_BUS_FMT MEDIA_BUS_FMT_BGR888_1X24
+
+static const char *const max96756_supply_names[] = {
+	"vcc1v2", /* Analog power */
+	"vcc1v8", /* Digital I/O power */
+};
+#define MAX96756_NUM_SUPPLIES ARRAY_SIZE(max96756_supply_names)
+
+static struct rkmodule_csi_dphy_param rk3588_dcphy_param = {
+	.vendor = PHY_VENDOR_SAMSUNG,
+	.lp_vol_ref = 3,
+	.lp_hys_sw = { 3, 0, 0, 0 },
+	.lp_escclk_pol_sel = { 1, 0, 0, 0 },
+	.skew_data_cal_clk = { 0, 0, 0, 0 },
+	.clk_hs_term_sel = 2,
+	.data_hs_term_sel = { 2, 2, 2, 2 },
+	.reserved = { 0 },
+};
+
+struct regval {
+	u16 i2c_addr;
+	u16 addr;
+	u8 val;
+	u16 delay;
+};
+
+struct max96756_mode {
+	u32 width;
+	u32 height;
+	struct v4l2_fract max_fps;
+	u32 hts_def;
+	u32 vts_def;
+	u32 exp_def;
+	u32 link_freq_idx;
+	u32 bpp;
+	const struct regval *reg_list;
+};
+
+static const struct v4l2_dv_timings_cap max96756_timings_cap = {
+	.type = V4L2_DV_BT_656_1120,
+	.reserved = { 0 },
+	V4L2_INIT_BT_TIMINGS(
+		1, 10000, 1, 10000, 0, 800000000,
+		V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
+			V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT,
+		V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_INTERLACED |
+			V4L2_DV_BT_CAP_REDUCED_BLANKING | V4L2_DV_BT_CAP_CUSTOM)
+};
+
+struct max96756 {
+	struct i2c_client *client;
+
+	struct clk *xvclk;
+
+	struct gpio_desc *pwdn_gpio;
+	struct regulator_bulk_data supplies[MAX96756_NUM_SUPPLIES];
+
+	struct pinctrl *pinctrl;
+	struct pinctrl_state *pins_default;
+	struct pinctrl_state *pins_sleep;
+
+	struct gpio_desc *lock_gpio;
+	int lock_irq;
+	struct delayed_work delayed_work_lock;
+	struct work_struct work_i2c_poll;
+
+	struct v4l2_subdev subdev;
+	struct media_pad pad;
+	struct v4l2_fwnode_endpoint bus_cfg;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl *lock_det;
+	struct v4l2_ctrl *pixel_rate;
+	struct v4l2_ctrl *link_freq;
+	struct v4l2_ctrl *test_pattern;
+	struct v4l2_dv_timings timings;
+
+	struct mutex mutex;
+	bool streaming;
+	bool power_on;
+	bool hot_plug;
+	u8 is_reset;
+
+	const struct max96756_mode *cur_mode;
+	u32 module_index;
+	const char *module_facing;
+	const char *module_name;
+	const char *len_name;
+};
+
+#define to_max96756(sd) container_of(sd, struct max96756, subdev)
+
+static const struct regval max96756_mipi_1080p_60fps[] = {
+	// Disable all phys
+	{ 0x48, 0x0332, 0x00, 0x00 },
+	// Video pipes tx disabled, audio tx EN
+	{ 0x48, 0x0002, 0x03, 0x00 },
+	// CSI output disabled
+	{ 0x48, 0x0313, 0x00, 0x00 },
+
+	// AUTOLINK = 0, LINK_CFG = Link A
+	// VDD = 1.2V
+	// Oneshot Reset[5]=0b1
+	// REG_ENABLE[2]=0b1
+	{ 0x48, 0x0010, 0x25, 0x00 },
+	// CXTP_B[2]=0b1
+	// CXTP_A[0]=0b1
+	{ 0x48, 0x0011, 0x0F, 0x00 },
+	// REG_MNL[4]=0b1
+	{ 0x48, 0x0012, 0x14, 0x00 },
+	{ 0x48, 0x0010, 0x05, 0x00 },
+
+	// PHY mode 2x4
+	{ 0x48, 0x0330, 0x04, 0x00 },
+
+	// PHY1 900 Mbps, override bpp,vc,dt
+	{ 0x48, 0x0320, 0xA9, 0x00 },
+	// PHY2 900 Mbps
+	{ 0x48, 0x0323, 0x29, 0x00 },
+	// Lane mapping
+	{ 0x48, 0x0333, 0x4E, 0x00 },
+	{ 0x48, 0x0334, 0x4E, 0x00 },
+	// 4 data lanes
+	{ 0x48, 0x044A, 0xD0, 0x00 },
+	{ 0x48, 0x048A, 0xD0, 0x00 },
+	// Map DST 0/1/2/3 to DPHY1
+	{ 0x48, 0x046D, 0x55, 0x00 },
+	// Map EN 0/1/2
+	{ 0x48, 0x044B, 0x07, 0x00 },
+	// SRC0 FS
+	{ 0x48, 0x044D, 0x00, 0x00 },
+	// DST0 FS
+	{ 0x48, 0x044E, 0x00, 0x00 },
+	// SRC1 FS ???
+	{ 0x48, 0x044F, 0x01, 0x00 },
+	// DST1 FE
+	{ 0x48, 0x0450, 0x01, 0x00 },
+	// SRC2 DT 0x24
+	{ 0x48, 0x0451, 0x24, 0x00 },
+	// DST2 DT 0x24
+	{ 0x48, 0x0452, 0x24, 0x00 },
+	// DT Y=0x24 0b100100
+	{ 0x48, 0x0316, 0x80, 0x00 },
+	{ 0x48, 0x0317, 0x04, 0x00 },
+	// BPP Y=0x18(DT=0x24)
+	{ 0x48, 0x0319, 0x18, 0x00 },
+
+	// Pipe X stream id 1
+	{ 0x48, 0x0050, 0x01, 0x00 },
+	// Pipe Y stream id 0
+	{ 0x48, 0x0051, 0x00, 0x00 },
+
+	// HS, VS output
+	// { 0x48, 0x0540, 0xA0, 0x00 },
+	// { 0x48, 0x0542, 0xA0, 0x00 },
+
+	// Video pipe Y en, Audio en
+	{ 0x48, 0x0002, 0x27, 0x00 },
+
+	// Enable all phys
+	// T_hs_trail = 66.7ns + 8UI
+	// T_lpx = 106.7ns
+	{ 0x48, 0x0332, 0xF4, 0x00 },
+
+	// Audio RX EN
+	{ 0x48, 0x0158, 0x21, 0x00 },
+
+	{ 0x48, REG_NULL, 0x00, 0x00 },
+};
+
+static const struct max96756_mode supported_modes[] = {
+	{
+		.width = 1920,
+		.height = 1080,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 600000,
+		},
+		.reg_list = max96756_mipi_1080p_60fps,
+		.link_freq_idx = 0,
+	},
+};
+
+static const struct max96756_mode supported_modes_dcphy[] = {
+	{
+		.width = 1920,
+		.height = 1080,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 600000,
+		},
+		.reg_list = max96756_mipi_1080p_60fps,
+		.link_freq_idx = 1,
+	},
+};
+
+static const s64 link_freq_items[] = {
+	MAX96756_LINK_FREQ_MHZ(450),
+	MAX96756_LINK_FREQ_MHZ(900),
+};
+
+static int max96756_write_reg(struct i2c_client *client, u16 reg, u32 len,
+			      u32 val)
+{
+	u32 buf_i, val_i;
+	u8 buf[6];
+	u8 *val_p;
+	__be32 val_be;
+
+	dev_dbg(&client->dev, "write reg(0x%04x val:0x%02x)!\n", reg, val);
+
+	if (len > 4)
+		return -EINVAL;
+
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xff;
+
+	val_be = cpu_to_be32(val);
+	val_p = (u8 *)&val_be;
+	buf_i = 2;
+	val_i = 4 - len;
+
+	while (val_i < 4)
+		buf[buf_i++] = val_p[val_i++];
+
+	if (i2c_master_send(client, buf, len + 2) != len + 2)
+		return -EIO;
+
+	return 0;
+}
+
+static int max96756_write_array(struct i2c_client *client,
+				const struct regval *regs)
+{
+	u32 i;
+	int ret = 0;
+
+	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) {
+		client->addr = regs[i].i2c_addr;
+		ret = max96756_write_reg(client, regs[i].addr,
+					 MAX96756_REG_VALUE_08BIT, regs[i].val);
+		if (regs[i].delay > 0)
+			msleep(regs[i].delay);
+	}
+
+	return ret;
+}
+
+static int max96756_read_reg(struct i2c_client *client, u16 reg,
+			     unsigned int len, u32 *val)
+{
+	struct i2c_msg msgs[2];
+	u8 *data_be_p;
+	__be32 data_be = 0;
+	__be16 reg_addr_be = cpu_to_be16(reg);
+	int ret;
+
+	if (len > 4 || !len)
+		return -EINVAL;
+
+	data_be_p = (u8 *)&data_be;
+	/* Write register address */
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = 2;
+	msgs[0].buf = (u8 *)&reg_addr_be;
+
+	/* Read data from register */
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = len;
+	msgs[1].buf = &data_be_p[4 - len];
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs))
+		return -EIO;
+
+	*val = be32_to_cpu(data_be);
+
+	return 0;
+}
+
+static int max96756_get_reso_dist(const struct max96756_mode *mode,
+				  struct v4l2_mbus_framefmt *framefmt)
+{
+	return abs(mode->width - framefmt->width) +
+	       abs(mode->height - framefmt->height);
+}
+
+static const struct max96756_mode *
+max96756_find_best_fit(struct v4l2_subdev_format *fmt)
+{
+	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
+	int dist;
+	int cur_best_fit = 0;
+	int cur_best_fit_dist = -1;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+		dist = max96756_get_reso_dist(&supported_modes[i], framefmt);
+		if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
+			cur_best_fit_dist = dist;
+			cur_best_fit = i;
+		}
+	}
+
+	return &supported_modes[cur_best_fit];
+}
+
+static int max96756_set_fmt(struct v4l2_subdev *sd,
+			    struct v4l2_subdev_pad_config *cfg,
+			    struct v4l2_subdev_format *fmt)
+{
+	struct max96756 *max96756 = to_max96756(sd);
+	const struct max96756_mode *mode;
+
+	mutex_lock(&max96756->mutex);
+
+	mode = max96756_find_best_fit(fmt);
+	fmt->format.code = MAX96756_MEDIA_BUS_FMT;
+	fmt->format.width = mode->width;
+	fmt->format.height = mode->height;
+	fmt->format.field = V4L2_FIELD_NONE;
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+#else
+		mutex_unlock(&max96756->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		if (max96756->streaming) {
+			mutex_unlock(&max96756->mutex);
+			return -EBUSY;
+		}
+	}
+
+	mutex_unlock(&max96756->mutex);
+
+	return 0;
+}
+
+static int max96756_get_fmt(struct v4l2_subdev *sd,
+			    struct v4l2_subdev_pad_config *cfg,
+			    struct v4l2_subdev_format *fmt)
+{
+	struct max96756 *max96756 = to_max96756(sd);
+	const struct max96756_mode *mode = max96756->cur_mode;
+
+	mutex_lock(&max96756->mutex);
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+#else
+		mutex_unlock(&max96756->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		fmt->format.width = mode->width;
+		fmt->format.height = mode->height;
+		fmt->format.code = MAX96756_MEDIA_BUS_FMT;
+		fmt->format.field = V4L2_FIELD_NONE;
+	}
+	mutex_unlock(&max96756->mutex);
+
+	return 0;
+}
+
+static int max96756_enum_mbus_code(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_pad_config *cfg,
+				   struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index != 0)
+		return -EINVAL;
+
+	code->code = MAX96756_MEDIA_BUS_FMT;
+
+	return 0;
+}
+
+static int max96756_enum_frame_sizes(struct v4l2_subdev *sd,
+				     struct v4l2_subdev_pad_config *cfg,
+				     struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	if (fse->code != MAX96756_MEDIA_BUS_FMT)
+		return -EINVAL;
+
+	fse->min_width = supported_modes[fse->index].width;
+	fse->max_width = supported_modes[fse->index].width;
+	fse->max_height = supported_modes[fse->index].height;
+	fse->min_height = supported_modes[fse->index].height;
+
+	return 0;
+}
+
+static int max96756_g_frame_interval(struct v4l2_subdev *sd,
+				     struct v4l2_subdev_frame_interval *fi)
+{
+	struct max96756 *max96756 = to_max96756(sd);
+	const struct max96756_mode *mode = max96756->cur_mode;
+
+	mutex_lock(&max96756->mutex);
+	fi->interval = mode->max_fps;
+	mutex_unlock(&max96756->mutex);
+
+	return 0;
+}
+
+static void max96756_get_module_inf(struct max96756 *max96756,
+				    struct rkmodule_inf *inf)
+{
+	memset(inf, 0, sizeof(*inf));
+	strscpy(inf->base.sensor, MAX96756_NAME, sizeof(inf->base.sensor));
+	strscpy(inf->base.module, max96756->module_name,
+		sizeof(inf->base.module));
+	strscpy(inf->base.lens, max96756->len_name, sizeof(inf->base.lens));
+}
+
+static void
+max96756_get_vicap_rst_inf(struct max96756 *max96756,
+			   struct rkmodule_vicap_reset_info *rst_info)
+{
+	struct i2c_client *client = max96756->client;
+
+	rst_info->is_reset = max96756->hot_plug;
+	max96756->hot_plug = false;
+	rst_info->src = RKCIF_RESET_SRC_ERR_HOTPLUG;
+	dev_info(&client->dev, "%s: rst_info->is_reset:%d.\n", __func__,
+		 rst_info->is_reset);
+}
+
+static void
+max96756_set_vicap_rst_inf(struct max96756 *max96756,
+			   struct rkmodule_vicap_reset_info rst_info)
+{
+	max96756->is_reset = rst_info.is_reset;
+}
+
+static long max96756_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	struct max96756 *max96756 = to_max96756(sd);
+	long ret = 0;
+	u32 stream = 0;
+	struct rkmodule_csi_dphy_param *dphy_param;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		max96756_get_module_inf(max96756, (struct rkmodule_inf *)arg);
+		break;
+	case RKMODULE_GET_HDMI_MODE:
+		*(int *)arg = RKMODULE_HDMIIN_MODE;
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		stream = *((u32 *)arg);
+		if (stream)
+			ret = max96756_write_reg(max96756->client,
+						 MAX96756_REG_CTRL_MODE,
+						 MAX96756_REG_VALUE_08BIT,
+						 MAX96756_MODE_STREAMING);
+		else
+			ret = max96756_write_reg(max96756->client,
+						 MAX96756_REG_CTRL_MODE,
+						 MAX96756_REG_VALUE_08BIT,
+						 MAX96756_MODE_SW_STANDBY);
+		break;
+	case RKMODULE_GET_VICAP_RST_INFO:
+		max96756_get_vicap_rst_inf(
+			max96756, (struct rkmodule_vicap_reset_info *)arg);
+		break;
+	case RKMODULE_SET_VICAP_RST_INFO:
+		max96756_set_vicap_rst_inf(
+			max96756, *(struct rkmodule_vicap_reset_info *)arg);
+		break;
+	case RKMODULE_SET_CSI_DPHY_PARAM:
+		dphy_param = (struct rkmodule_csi_dphy_param *)arg;
+		rk3588_dcphy_param = *dphy_param;
+		dev_dbg(&max96756->client->dev, "sensor set dphy param\n");
+		break;
+	case RKMODULE_GET_CSI_DPHY_PARAM:
+		dphy_param = (struct rkmodule_csi_dphy_param *)arg;
+		*dphy_param = rk3588_dcphy_param;
+		dev_dbg(&max96756->client->dev, "sensor get dphy param\n");
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long max96756_compat_ioctl32(struct v4l2_subdev *sd, unsigned int cmd,
+				    unsigned long arg)
+{
+	void __user *up = compat_ptr(arg);
+	struct rkmodule_inf *inf;
+	struct rkmodule_vicap_reset_info *vicap_rst_inf;
+	long ret = 0;
+	int *seq;
+	u32 stream = 0;
+	struct rkmodule_csi_dphy_param *dphy_param;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
+		if (!inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = max96756_ioctl(sd, cmd, inf);
+		if (!ret) {
+			ret = copy_to_user(up, inf, sizeof(*inf));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(inf);
+		break;
+	case RKMODULE_GET_HDMI_MODE:
+		seq = kzalloc(sizeof(*seq), GFP_KERNEL);
+		if (!seq) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = max96756_ioctl(sd, cmd, seq);
+		if (!ret) {
+			ret = copy_to_user(up, seq, sizeof(*seq));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(seq);
+		break;
+	case RKMODULE_GET_VICAP_RST_INFO:
+		vicap_rst_inf = kzalloc(sizeof(*vicap_rst_inf), GFP_KERNEL);
+		if (!vicap_rst_inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = max96756_ioctl(sd, cmd, vicap_rst_inf);
+		if (!ret) {
+			ret = copy_to_user(up, vicap_rst_inf,
+					   sizeof(*vicap_rst_inf));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(vicap_rst_inf);
+		break;
+	case RKMODULE_SET_VICAP_RST_INFO:
+		vicap_rst_inf = kzalloc(sizeof(*vicap_rst_inf), GFP_KERNEL);
+		if (!vicap_rst_inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(vicap_rst_inf, up, sizeof(*vicap_rst_inf));
+		if (!ret)
+			ret = max96756_ioctl(sd, cmd, vicap_rst_inf);
+		else
+			ret = -EFAULT;
+		kfree(vicap_rst_inf);
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		ret = copy_from_user(&stream, up, sizeof(u32));
+		if (!ret)
+			ret = max96756_ioctl(sd, cmd, &stream);
+		else
+			ret = -EFAULT;
+		break;
+	case RKMODULE_SET_CSI_DPHY_PARAM:
+		dphy_param = kzalloc(sizeof(*dphy_param), GFP_KERNEL);
+		if (!dphy_param) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(dphy_param, up, sizeof(*dphy_param));
+		if (!ret)
+			ret = max96756_ioctl(sd, cmd, dphy_param);
+		else
+			ret = -EFAULT;
+		kfree(dphy_param);
+		break;
+	case RKMODULE_GET_CSI_DPHY_PARAM:
+		dphy_param = kzalloc(sizeof(*dphy_param), GFP_KERNEL);
+		if (!dphy_param) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = max96756_ioctl(sd, cmd, dphy_param);
+		if (!ret) {
+			ret = copy_to_user(up, dphy_param, sizeof(*dphy_param));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(dphy_param);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+#endif
+
+static int max96756_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+				    struct v4l2_event_subscription *sub)
+{
+	switch (sub->type) {
+	case V4L2_EVENT_SOURCE_CHANGE:
+		return v4l2_src_change_event_subdev_subscribe(sd, fh, sub);
+	case V4L2_EVENT_CTRL:
+		return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int __max96756_start_stream(struct max96756 *max96756)
+{
+	int ret;
+
+	ret = max96756_write_array(max96756->client,
+				   max96756->cur_mode->reg_list);
+	if (ret) {
+		dev_warn(&max96756->client->dev,
+			 "Failed to write initial sequence\n");
+		return ret;
+	}
+
+	/* In case these controls are set before streaming */
+	mutex_unlock(&max96756->mutex);
+	ret = v4l2_ctrl_handler_setup(&max96756->ctrl_handler);
+	mutex_lock(&max96756->mutex);
+	if (ret) {
+		dev_warn(&max96756->client->dev, "Failed to setup ctrl\n");
+		return ret;
+	}
+
+	return max96756_write_reg(max96756->client, MAX96756_REG_CTRL_MODE,
+				  MAX96756_REG_VALUE_08BIT,
+				  MAX96756_MODE_STREAMING);
+}
+
+static int __max96756_stop_stream(struct max96756 *max96756)
+{
+	int ret;
+
+	ret = max96756_write_reg(max96756->client, MAX96756_REG_CTRL_MODE,
+				 MAX96756_REG_VALUE_08BIT,
+				 MAX96756_MODE_SW_STANDBY);
+
+	return ret;
+}
+
+static bool max96756_match_timings(const struct v4l2_dv_timings *t1,
+				   const struct v4l2_dv_timings *t2)
+{
+	if (t1->type != t2->type || t1->type != V4L2_DV_BT_656_1120)
+		return false;
+	if (t1->bt.width == t2->bt.width && t1->bt.height == t2->bt.height &&
+	    t1->bt.interlaced == t2->bt.interlaced)
+		return true;
+
+	return false;
+}
+
+static inline bool max96756_detect_lock_status(struct max96756 *max96756)
+{
+	bool ret;
+	int val, i, cnt;
+
+	/* if not use lock gpio */
+	if (!max96756->lock_gpio)
+		return true;
+
+	cnt = 0;
+	for (i = 0; i < 5; i++) {
+		val = gpiod_get_value(max96756->lock_gpio);
+		if (val > 0)
+			cnt++;
+		usleep_range(500, 600);
+	}
+
+	ret = (cnt >= 3) ? true : false;
+
+	v4l2_dbg(1, debug, &max96756->subdev, "%s: %d\n", __func__, ret);
+
+	return ret;
+}
+
+static bool max96756_check_signal(struct max96756 *max96756)
+{
+	u32 val = 0;
+
+	max96756_read_reg(max96756->client, 0x11A, MAX96756_REG_VALUE_08BIT,
+			  &val);
+
+	return val & (1 << 6);
+}
+
+static int max96756_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+	struct max96756 *max96756 = to_max96756(sd);
+	*status = 0;
+	*status |= max96756_check_signal(max96756) ? V4L2_IN_ST_NO_SIGNAL : 0;
+
+	v4l2_dbg(1, debug, sd, "%s: status = 0x%x\n", __func__, *status);
+
+	return 0;
+}
+
+static int max96756_s_dv_timings(struct v4l2_subdev *sd,
+				 struct v4l2_dv_timings *timings)
+{
+	struct max96756 *max96756 = to_max96756(sd);
+
+	if (!timings)
+		return -EINVAL;
+
+	if (debug)
+		v4l2_print_dv_timings(sd->name, "s_dv_timings: ", timings,
+				      false);
+
+	if (max96756_match_timings(&max96756->timings, timings)) {
+		v4l2_dbg(1, debug, sd, "%s: no change\n", __func__);
+		return 0;
+	}
+
+	if (!v4l2_valid_dv_timings(timings, &max96756_timings_cap, NULL,
+				   NULL)) {
+		v4l2_dbg(1, debug, sd, "%s: timings out of range\n", __func__);
+		return -ERANGE;
+	}
+
+	max96756->timings = *timings;
+
+	__max96756_stop_stream(max96756);
+
+	return 0;
+}
+static int max96756_g_dv_timings(struct v4l2_subdev *sd,
+				 struct v4l2_dv_timings *timings)
+{
+	struct max96756 *max96756 = to_max96756(sd);
+
+	*timings = max96756->timings;
+
+	return 0;
+}
+
+static int max96756_enum_dv_timings(struct v4l2_subdev *sd,
+				    struct v4l2_enum_dv_timings *timings)
+{
+	if (timings->pad != 0)
+		return -EINVAL;
+
+	return v4l2_enum_dv_timings_cap(timings, &max96756_timings_cap, NULL,
+					NULL);
+}
+
+static int max96756_query_dv_timings(struct v4l2_subdev *sd,
+				     struct v4l2_dv_timings *timings)
+{
+	struct max96756 *max96756 = to_max96756(sd);
+
+	*timings = max96756->timings;
+	if (debug)
+		v4l2_print_dv_timings(sd->name, "query_dv_timings: ", timings,
+				      false);
+
+	if (!v4l2_valid_dv_timings(timings, &max96756_timings_cap, NULL,
+				   NULL)) {
+		v4l2_dbg(1, debug, sd, "%s: timings out of range\n", __func__);
+
+		return -ERANGE;
+	}
+
+	return 0;
+}
+
+static int max96756_dv_timings_cap(struct v4l2_subdev *sd,
+				   struct v4l2_dv_timings_cap *cap)
+{
+	if (cap->pad != 0)
+		return -EINVAL;
+
+	*cap = max96756_timings_cap;
+
+	return 0;
+}
+
+static int max96756_s_stream(struct v4l2_subdev *sd, int on)
+{
+	struct max96756 *max96756 = to_max96756(sd);
+	struct i2c_client *client = max96756->client;
+	int ret = 0;
+
+	dev_info(&client->dev, "%s: on: %d, %dx%d@%d\n", __func__, on,
+		 max96756->cur_mode->width, max96756->cur_mode->height,
+		 DIV_ROUND_CLOSEST(max96756->cur_mode->max_fps.denominator,
+				   max96756->cur_mode->max_fps.numerator));
+
+	mutex_lock(&max96756->mutex);
+	on = !!on;
+	if (on == max96756->streaming)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		ret = __max96756_start_stream(max96756);
+		if (ret) {
+			v4l2_err(sd, "start stream failed while write regs\n");
+			pm_runtime_put(&client->dev);
+			goto unlock_and_return;
+		}
+	} else {
+		__max96756_stop_stream(max96756);
+		pm_runtime_put(&client->dev);
+	}
+
+	max96756->streaming = on;
+
+unlock_and_return:
+	mutex_unlock(&max96756->mutex);
+
+	return ret;
+}
+
+static int max96756_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct max96756 *max96756 = to_max96756(sd);
+	struct i2c_client *client = max96756->client;
+	int ret = 0;
+
+	mutex_lock(&max96756->mutex);
+
+	/* If the power state is not modified - no work to do. */
+	if (max96756->power_on == !!on)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		max96756->power_on = true;
+	} else {
+		pm_runtime_put(&client->dev);
+		max96756->power_on = false;
+	}
+
+unlock_and_return:
+	mutex_unlock(&max96756->mutex);
+
+	return ret;
+}
+
+static int __max96756_power_on(struct max96756 *max96756)
+{
+	int ret;
+	struct device *dev = &max96756->client->dev;
+
+	if (!IS_ERR_OR_NULL(max96756->pins_default)) {
+		ret = pinctrl_select_state(max96756->pinctrl,
+					   max96756->pins_default);
+		if (ret < 0)
+			dev_err(dev, "could not set pins\n");
+	}
+
+	if (!IS_ERR(max96756->pwdn_gpio)) {
+		gpiod_set_value_cansleep(max96756->pwdn_gpio, 1);
+		usleep_range(45000, 100000);
+	}
+
+	return 0;
+}
+
+static void __max96756_power_off(struct max96756 *max96756)
+{
+	int ret;
+	struct device *dev = &max96756->client->dev;
+
+	if (!IS_ERR(max96756->pwdn_gpio)) {
+		gpiod_set_value_cansleep(max96756->pwdn_gpio, 0);
+		usleep_range(1000, 2000);
+	}
+
+	if (!IS_ERR_OR_NULL(max96756->pins_sleep)) {
+		ret = pinctrl_select_state(max96756->pinctrl,
+					   max96756->pins_sleep);
+		if (ret < 0)
+			dev_dbg(dev, "could not set pins\n");
+	}
+}
+
+static int max96756_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct max96756 *max96756 = to_max96756(sd);
+
+	return __max96756_power_on(max96756);
+}
+
+static int max96756_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct max96756 *max96756 = to_max96756(sd);
+
+	__max96756_power_off(max96756);
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int max96756_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct max96756 *max96756 = to_max96756(sd);
+	struct v4l2_mbus_framefmt *try_fmt =
+		v4l2_subdev_get_try_format(sd, fh->pad, 0);
+	const struct max96756_mode *def_mode = &supported_modes[0];
+
+	mutex_lock(&max96756->mutex);
+	/* Initialize try_fmt */
+	try_fmt->width = def_mode->width;
+	try_fmt->height = def_mode->height;
+	try_fmt->code = MAX96756_MEDIA_BUS_FMT;
+	try_fmt->field = V4L2_FIELD_NONE;
+
+	mutex_unlock(&max96756->mutex);
+	/* No crop or compose */
+
+	return 0;
+}
+#endif
+
+static int
+max96756_enum_frame_interval(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_pad_config *cfg,
+			     struct v4l2_subdev_frame_interval_enum *fie)
+{
+	if (fie->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	fie->code = MAX96756_MEDIA_BUS_FMT;
+
+	fie->width = supported_modes[fie->index].width;
+	fie->height = supported_modes[fie->index].height;
+	fie->interval = supported_modes[fie->index].max_fps;
+
+	return 0;
+}
+
+static int max96756_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
+				  struct v4l2_mbus_config *config)
+{
+	config->type = V4L2_MBUS_CSI2_DPHY;
+	config->flags = V4L2_MBUS_CSI2_4_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
+			V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+
+	return 0;
+}
+
+static int max96756_get_selection(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_pad_config *cfg,
+				  struct v4l2_subdev_selection *sel)
+{
+	struct max96756 *max96756 = to_max96756(sd);
+
+	if (sel->target == V4L2_SEL_TGT_CROP_BOUNDS) {
+		sel->r.left = 0;
+		sel->r.width = max96756->cur_mode->width;
+		sel->r.top = 0;
+		sel->r.height = max96756->cur_mode->height;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static const struct dev_pm_ops max96756_pm_ops = { SET_RUNTIME_PM_OPS(
+	max96756_runtime_suspend, max96756_runtime_resume, NULL) };
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static const struct v4l2_subdev_internal_ops max96756_internal_ops = {
+	.open = max96756_open,
+};
+#endif
+
+static const struct v4l2_subdev_core_ops max96756_core_ops = {
+	.s_power = max96756_s_power,
+	.subscribe_event = max96756_subscribe_event,
+	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+	.ioctl = max96756_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl32 = max96756_compat_ioctl32,
+#endif
+};
+
+static const struct v4l2_subdev_video_ops max96756_video_ops = {
+	.g_input_status = max96756_g_input_status,
+	.s_dv_timings = max96756_s_dv_timings,
+	.g_dv_timings = max96756_g_dv_timings,
+	.query_dv_timings = max96756_query_dv_timings,
+	.s_stream = max96756_s_stream,
+	.g_frame_interval = max96756_g_frame_interval,
+};
+
+static const struct v4l2_subdev_pad_ops max96756_pad_ops = {
+	.enum_mbus_code = max96756_enum_mbus_code,
+	.enum_frame_size = max96756_enum_frame_sizes,
+	.enum_frame_interval = max96756_enum_frame_interval,
+	.get_fmt = max96756_get_fmt,
+	.set_fmt = max96756_set_fmt,
+	.get_selection = max96756_get_selection,
+	.get_mbus_config = max96756_g_mbus_config,
+	.enum_dv_timings = max96756_enum_dv_timings,
+	.dv_timings_cap = max96756_dv_timings_cap,
+};
+
+static const struct v4l2_subdev_ops max96756_subdev_ops = {
+	.core = &max96756_core_ops,
+	.video = &max96756_video_ops,
+	.pad = &max96756_pad_ops,
+};
+
+static int max96756_initialize_controls(struct max96756 *max96756)
+{
+	const struct max96756_mode *mode;
+	struct v4l2_ctrl_handler *handler;
+	int ret;
+
+	handler = &max96756->ctrl_handler;
+	mode = max96756->cur_mode;
+	ret = v4l2_ctrl_handler_init(handler, 3);
+	if (ret)
+		return ret;
+
+	handler->lock = &max96756->mutex;
+
+	max96756->link_freq =
+		v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
+				       ARRAY_SIZE(link_freq_items) - 1, 0,
+				       link_freq_items);
+	max96756->pixel_rate =
+		v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, 0,
+				  MAX96756_PIXEL_RATE, 1, MAX96756_PIXEL_RATE);
+	max96756->lock_det = v4l2_ctrl_new_std(
+		handler, NULL, V4L2_CID_DV_RX_POWER_PRESENT, 0, 1, 0, 0);
+
+	__v4l2_ctrl_s_ctrl_int64(max96756->pixel_rate, MAX96756_PIXEL_RATE);
+	__v4l2_ctrl_s_ctrl(max96756->link_freq, mode->link_freq_idx);
+	__v4l2_ctrl_s_ctrl(max96756->lock_det,
+			   max96756_detect_lock_status(max96756));
+
+	if (handler->error) {
+		ret = handler->error;
+		dev_err(&max96756->client->dev, "Failed to init controls(%d)\n",
+			ret);
+		goto err_free_handler;
+	}
+
+	max96756->subdev.ctrl_handler = handler;
+
+	return 0;
+
+err_free_handler:
+	v4l2_ctrl_handler_free(handler);
+
+	return ret;
+}
+
+static int max96756_check_sensor_id(struct max96756 *max96756,
+				    struct i2c_client *client)
+{
+	struct device *dev = &max96756->client->dev;
+	u32 id = 0;
+	int ret;
+
+	ret = max96756_read_reg(client, MAX96756_REG_CHIP_ID,
+				MAX96756_REG_VALUE_08BIT, &id);
+	if (id != CHIP_ID) {
+		dev_err(dev, "Unexpected sensor id(%02x), ret(%d)\n", id, ret);
+		return -ENODEV;
+	}
+
+	dev_info(dev, "Detected %02x deserializer\n", CHIP_ID);
+
+	return 0;
+}
+
+static void max96756_delayed_work_lock(struct work_struct *work)
+{
+	struct delayed_work *dwork = to_delayed_work(work);
+	struct max96756 *max96756 =
+		container_of(dwork, struct max96756, delayed_work_lock);
+
+	__v4l2_ctrl_s_ctrl(max96756->lock_det,
+			   max96756_detect_lock_status(max96756));
+}
+
+static irqreturn_t lock_irq_handler(int irq, void *dev_id)
+{
+	struct max96756 *max96756 = dev_id;
+
+	mutex_lock(&max96756->mutex);
+	if (max96756->streaming)
+		schedule_delayed_work(&max96756->delayed_work_lock,
+				      msecs_to_jiffies(50));
+	mutex_unlock(&max96756->mutex);
+
+	return IRQ_HANDLED;
+}
+
+static int max96756_configure_regulators(struct max96756 *max96756)
+{
+	unsigned int i;
+
+	for (i = 0; i < MAX96756_NUM_SUPPLIES; i++)
+		max96756->supplies[i].supply = max96756_supply_names[i];
+
+	return devm_regulator_bulk_get(&max96756->client->dev,
+				       MAX96756_NUM_SUPPLIES,
+				       max96756->supplies);
+}
+
+static int max96756_probe(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	struct device_node *node = dev->of_node;
+	struct max96756 *max96756;
+	struct v4l2_subdev *sd;
+	char facing[2];
+	int ret;
+
+	dev_info(dev, "driver version: %02x.%02x.%02x", DRIVER_VERSION >> 16,
+		 (DRIVER_VERSION & 0xff00) >> 8, DRIVER_VERSION & 0x00ff);
+
+	max96756 = devm_kzalloc(dev, sizeof(*max96756), GFP_KERNEL);
+	if (!max96756)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
+				   &max96756->module_index);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
+				       &max96756->module_facing);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
+				       &max96756->module_name);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
+				       &max96756->len_name);
+	if (ret) {
+		dev_err(dev, "could not get module information!\n");
+		return -EINVAL;
+	}
+
+	max96756->client = client;
+	max96756->cur_mode = &supported_modes[0];
+
+	max96756->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
+	if (IS_ERR(max96756->pwdn_gpio))
+		dev_warn(dev, "Failed to get pwdn-gpios\n");
+
+	max96756->lock_gpio = devm_gpiod_get_optional(dev, "lock", GPIOD_IN);
+	if (IS_ERR(max96756->lock_gpio)) {
+		dev_warn(dev, "failed to get lock gpio, will use i2c poll\n");
+	} else {
+		max96756->lock_irq = gpiod_to_irq(max96756->lock_gpio);
+		if (max96756->lock_irq < 0)
+			dev_err(dev, "failed to get lock irq, maybe no use\n");
+
+		ret = devm_request_threaded_irq(
+			dev, max96756->lock_irq, NULL, lock_irq_handler,
+			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
+				IRQF_ONESHOT,
+			"max96756", max96756);
+		if (ret)
+			dev_err(dev,
+				"failed to register lock irq (%d), maybe no use\n",
+				ret);
+	}
+
+	ret = max96756_configure_regulators(max96756);
+	if (ret) {
+		dev_err(dev, "Failed to get power regulators\n");
+		return ret;
+	}
+
+	max96756->pinctrl = devm_pinctrl_get(dev);
+	if (!IS_ERR(max96756->pinctrl)) {
+		max96756->pins_default = pinctrl_lookup_state(
+			max96756->pinctrl, OF_CAMERA_PINCTRL_STATE_DEFAULT);
+		if (IS_ERR(max96756->pins_default))
+			dev_err(dev, "could not get default pinstate\n");
+
+		max96756->pins_sleep = pinctrl_lookup_state(
+			max96756->pinctrl, OF_CAMERA_PINCTRL_STATE_SLEEP);
+		if (IS_ERR(max96756->pins_sleep))
+			dev_err(dev, "could not get sleep pinstate\n");
+	}
+
+	mutex_init(&max96756->mutex);
+
+	sd = &max96756->subdev;
+	v4l2_i2c_subdev_init(sd, client, &max96756_subdev_ops);
+	ret = max96756_initialize_controls(max96756);
+	if (ret)
+		goto err_destroy_mutex;
+
+	ret = __max96756_power_on(max96756);
+	if (ret)
+		goto err_free_handler;
+
+	ret = max96756_check_sensor_id(max96756, client);
+	if (ret)
+		goto err_power_off;
+
+	INIT_DELAYED_WORK(&max96756->delayed_work_lock,
+			  max96756_delayed_work_lock);
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	sd->internal_ops = &max96756_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
+#endif
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	max96756->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &max96756->pad);
+	if (ret < 0)
+		goto err_power_off;
+#endif
+
+	memset(facing, 0, sizeof(facing));
+	if (strcmp(max96756->module_facing, "back") == 0)
+		facing[0] = 'b';
+	else
+		facing[0] = 'f';
+
+	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
+		 max96756->module_index, facing, MAX96756_NAME,
+		 dev_name(sd->dev));
+	ret = v4l2_async_register_subdev_sensor_common(sd);
+	if (ret) {
+		dev_err(dev, "v4l2 async register subdev failed\n");
+		goto err_clean_entity;
+	}
+
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_idle(dev);
+
+	return 0;
+
+err_clean_entity:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+err_power_off:
+	__max96756_power_off(max96756);
+err_free_handler:
+	v4l2_ctrl_handler_free(&max96756->ctrl_handler);
+err_destroy_mutex:
+	mutex_destroy(&max96756->mutex);
+
+	return ret;
+}
+
+static int max96756_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct max96756 *max96756 = to_max96756(sd);
+
+	cancel_delayed_work_sync(&max96756->delayed_work_lock);
+
+	v4l2_async_unregister_subdev(sd);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+	v4l2_ctrl_handler_free(&max96756->ctrl_handler);
+	mutex_destroy(&max96756->mutex);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		__max96756_power_off(max96756);
+	pm_runtime_set_suspended(&client->dev);
+
+	return 0;
+}
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id max96756_of_match[] = {
+	{ .compatible = "maxim,max96756" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, max96756_of_match);
+#endif
+
+static const struct i2c_device_id max96756_match_id[] = {
+	{ "maxim,max96756", 0 },
+	{},
+};
+
+static struct i2c_driver max96756_i2c_driver = {
+	.driver = {
+		.name = MAX96756_NAME,
+		.pm = &max96756_pm_ops,
+		.of_match_table = of_match_ptr(max96756_of_match),
+	},
+	.probe_new	= &max96756_probe,
+	.remove		= &max96756_remove,
+	.id_table	= max96756_match_id,
+};
+
+module_i2c_driver(max96756_i2c_driver);
+
+MODULE_DESCRIPTION("Maxim MAX96756 GMSL1/2 CSI display deserializer driver");
+MODULE_AUTHOR("Cody Xie <cody.xie@rock-chips.com>");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/max96756.h b/kernel/drivers/media/i2c/max96756.h
new file mode 100644
index 0000000..b2abafc
--- /dev/null
+++ b/kernel/drivers/media/i2c/max96756.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * max96756 driver
+ *
+ */
+#ifndef _MAX96756_H_
+#define _MAX96756_H_
+
+int max96756_sensor_mod_init(void);
+
+#endif
diff --git a/kernel/drivers/media/i2c/maxim2c/Kconfig b/kernel/drivers/media/i2c/maxim2c/Kconfig
new file mode 100644
index 0000000..b07b96a
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/Kconfig
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Maxim Dual GMSL deserializer and serializer devices
+#
+config VIDEO_DES_MAXIM2C
+	tristate "Maxim Dual GMSL deserializer support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on MEDIA_CAMERA_SUPPORT
+	select V4L2_FWNODE
+	help
+	  This driver supports the Maxim Dual GMSL2/GMSL1 deserializer.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called maxim2c.
+
+menu "Maxim Dual GMSL serializer devices support"
+	visible if VIDEO_DES_MAXIM2C
+
+config MAXIM2C_SER_MAX9295
+	tristate "Maxim GMSL2 serializer max9295 support"
+	depends on VIDEO_DES_MAXIM2C
+	help
+	  This driver supports the Maxim GMSL2 max9295 serializer.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called remote_max9295.
+
+config MAXIM2C_SER_MAX96715
+	tristate "Maxim GMSL1 Serializer max96715 support"
+	depends on VIDEO_DES_MAXIM2C
+	help
+	  This driver supports the Maxim GMSL1 max96715 serializer.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called remote_max96715.
+
+config MAXIM2C_SER_MAX96717
+	tristate "Maxim GMSL2 Serializer max96717 support"
+	depends on VIDEO_DES_MAXIM2C
+	help
+	  This driver supports the Maxim GMSL2 max96717 serializer.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called remote_max96717.
+
+endmenu
diff --git a/kernel/drivers/media/i2c/maxim2c/Makefile b/kernel/drivers/media/i2c/maxim2c/Makefile
new file mode 100644
index 0000000..f9b7990
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/Makefile
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_VIDEO_DES_MAXIM2C)	+= maxim2c.o
+maxim2c-objs	+= maxim2c_i2c.o \
+		   maxim2c_mipi_txphy.o \
+		   maxim2c_video_pipe.o \
+		   maxim2c_link.o \
+		   maxim2c_remote.o \
+		   maxim2c_pattern.o \
+		   maxim2c_v4l2.o \
+		   maxim2c_drv.o
+
+obj-$(CONFIG_MAXIM2C_SER_MAX9295)	+= remote_max9295.o
+obj-$(CONFIG_MAXIM2C_SER_MAX96715)	+= remote_max96715.o
+obj-$(CONFIG_MAXIM2C_SER_MAX96717)	+= remote_max96717.o
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_api.h b/kernel/drivers/media/i2c/maxim2c/maxim2c_api.h
new file mode 100644
index 0000000..7668c1f
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_api.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Maxim Dual GMSL Deserializer driver API function declaration
+ *
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * Author: Cai Wenzhong <cwz@rock-chips.com>
+ */
+
+#ifndef __MAXIM2C_API_H__
+#define __MAXIM2C_API_H__
+
+#include "maxim2c_i2c.h"
+#include "maxim2c_link.h"
+#include "maxim2c_video_pipe.h"
+#include "maxim2c_mipi_txphy.h"
+#include "maxim2c_remote.h"
+#include "maxim2c_pattern.h"
+#include "maxim2c_drv.h"
+
+#define MAXIM2C_NAME			"maxim2c"
+
+/* Maxim Deserializer Test Pattern */
+#define MAXIM2C_TEST_PATTERN		0
+
+/* Maxim Deserializer pwdn on/off enable */
+#define MAXIM2C_LOCAL_DES_ON_OFF_EN	0
+
+/* maxim2c i2c api */
+int maxim2c_i2c_write_reg(struct i2c_client *client,
+		u16 reg_addr, u16 reg_len, u16 val_len, u32 reg_val);
+int maxim2c_i2c_read_reg(struct i2c_client *client,
+		u16 reg_addr, u16 reg_len, u16 val_len, u32 *reg_val);
+int maxim2c_i2c_update_reg(struct i2c_client *client,
+		u16 reg_addr, u16 reg_len,
+		u32 val_len, u32 val_mask, u32 reg_val);
+
+int maxim2c_i2c_write_byte(struct i2c_client *client,
+		u16 reg_addr, u16 reg_len, u8 reg_val);
+int maxim2c_i2c_read_byte(struct i2c_client *client,
+		u16 reg_addr, u16 reg_len, u8 *reg_val);
+int maxim2c_i2c_update_byte(struct i2c_client *client,
+		u16 reg_addr, u16 reg_len, u8 val_mask, u8 reg_val);
+
+int maxim2c_i2c_write_array(struct i2c_client *client,
+				const struct maxim2c_i2c_regval *regs);
+int maxim2c_i2c_load_init_seq(struct device *dev,
+		struct device_node *node, struct maxim2c_i2c_init_seq *init_seq);
+int maxim2c_i2c_run_init_seq(struct i2c_client *client,
+			struct maxim2c_i2c_init_seq *init_seq);
+
+/* maxim2c link api */
+u8 maxim2c_link_get_lock_state(maxim2c_t *maxim2c, u8 link_mask);
+int maxim2c_link_oneshot_reset(maxim2c_t *maxim2c, u8 link_mask);
+int maxim2c_link_mask_enable(maxim2c_t *maxim2c, u8 link_mask, bool enable);
+int maxim2c_link_wait_linklock(maxim2c_t *maxim2c, u8 link_mask);
+int maxim2c_link_select_remote_enable(maxim2c_t *maxim2c, u8 link_mask);
+int maxim2c_link_select_remote_control(maxim2c_t *maxim2c, u8 link_mask);
+int maxim2c_link_hw_init(maxim2c_t *maxim2c);
+void maxim2c_link_data_init(maxim2c_t *maxim2c);
+int maxim2c_link_parse_dt(maxim2c_t *maxim2c, struct device_node *of_node);
+
+/* maxim2c video pipe api */
+int maxim2c_video_pipe_hw_init(maxim2c_t *maxim2c);
+int maxim2c_video_pipe_mask_enable(maxim2c_t *maxim2c, u8 video_pipe_mask, bool enable);
+int maxim2c_video_pipe_linkid_enable(maxim2c_t *maxim2c, u8 link_id, bool enable);
+void maxim2c_video_pipe_data_init(maxim2c_t *maxim2c);
+int maxim2c_video_pipe_parse_dt(maxim2c_t *maxim2c, struct device_node *of_node);
+
+/* maxim2c mipi txphy api */
+int maxim2c_mipi_txphy_hw_init(maxim2c_t *maxim2c);
+void maxim2c_mipi_txphy_data_init(maxim2c_t *maxim2c);
+int maxim2c_mipi_txphy_parse_dt(maxim2c_t *maxim2c, struct device_node *of_node);
+int maxim2c_mipi_txphy_enable(maxim2c_t *maxim2c, bool enable);
+int maxim2c_dphy_dpll_predef_set(maxim2c_t *maxim2c, s64 link_freq_hz);
+int maxim2c_mipi_csi_output(maxim2c_t *maxim2c, bool enable);
+
+/* maxim2c remote api */
+int maxim2c_remote_mfd_add_devices(maxim2c_t *maxim2c);
+int maxim2c_remote_devices_init(maxim2c_t *maxim2c, u8 link_init_mask);
+int maxim2c_remote_devices_deinit(maxim2c_t *maxim2c, u8 link_init_mask);
+int maxim2c_remote_load_init_seq(maxim2c_remote_t *remote_device);
+int maxim2c_remote_i2c_addr_select(maxim2c_remote_t *remote_device, u32 i2c_id);
+int maxim2c_remote_i2c_client_init(maxim2c_remote_t *remote_device,
+				struct i2c_client *des_client);
+int maxim2c_remote_device_register(maxim2c_t *maxim2c,
+				maxim2c_remote_t *remote_device);
+
+/* maxim2c v4l2 subdev api */
+int maxim2c_v4l2_subdev_init(maxim2c_t *maxim2c);
+void maxim2c_v4l2_subdev_deinit(maxim2c_t *maxim2c);
+
+/* maxim2c driver api */
+int maxim2c_module_hw_init(maxim2c_t *maxim2c);
+int maxim2c_hot_plug_detect_work_start(maxim2c_t *maxim2c);
+
+/* maxim2c pattern api */
+int maxim2c_pattern_hw_init(maxim2c_t *maxim2c);
+int maxim2c_pattern_support_mode_init(maxim2c_t *maxim2c);
+int maxim2c_pattern_data_init(maxim2c_t *maxim2c);
+int maxim2c_pattern_enable(maxim2c_t *maxim2c, bool enable);
+
+#endif /* __MAXIM2C_API_H__ */
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_drv.c b/kernel/drivers/media/i2c/maxim2c/maxim2c_drv.c
new file mode 100644
index 0000000..0ae41e2
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_drv.c
@@ -0,0 +1,750 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim Dual GMSL2/GMSL1 to CSI-2 Deserializer driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * Author: Cai Wenzhong <cwz@rock-chips.com>
+ *
+ * V2.00.00 maxim serdes dual GMSL2/GMSL1 driver framework.
+ *     1. local deserializer support: max96716/max96718
+ *     2. remote serializer support: max9295/max96715/max96717
+ *     3. support deserializer and serializer auto adaptive
+ *     4. support deserializer output test pattern
+ *     5. support remote serializer channel management
+ *     6. support remote serializer I2c address mapping
+ *     7. support remote serializer hot plug detection and recovery
+ *
+ * V2.00.01
+ *     1. MIPI TXPHY add tunnel mode support
+ *     2. MIPI TXPHY mode only support 2x4Lanes and 2x2Lanes
+ *
+ */
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/compat.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/pm_runtime.h>
+#include <linux/workqueue.h>
+#include <linux/rk-camera-module.h>
+#include <linux/gpio/consumer.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+#include "maxim2c_api.h"
+
+#define DRIVER_VERSION			KERNEL_VERSION(2, 0x00, 0x01)
+
+#define MAXIM2C_XVCLK_FREQ		25000000
+
+static int maxim2c_check_local_chipid(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	int ret = 0, loop = 0;
+	u8 chipid = 0;
+
+	for (loop = 0; loop < 5; loop++) {
+		if (loop != 0) {
+			dev_info(dev, "check local chipid retry (%d)", loop);
+			msleep(10);
+		}
+
+		ret = maxim2c_i2c_read_byte(client,
+				MAXIM2C_REG_CHIP_ID, MAXIM2C_I2C_REG_ADDR_16BITS,
+				&chipid);
+		if (ret == 0) {
+			if (chipid == maxim2c->chipid) {
+				if (chipid == MAX96716_CHIP_ID) {
+					dev_info(dev, "MAX96716 is Detected\n");
+					return 0;
+				}
+
+				if (chipid == MAX96718_CHIP_ID) {
+					dev_info(dev, "MAX96718 is Detected\n");
+					return 0;
+				}
+			} else {
+				// if chipid is unexpected, retry
+				dev_err(dev, "Unexpected maxim chipid = %02x\n", chipid);
+			}
+		}
+	}
+
+	dev_err(dev, "maxim check chipid error, ret(%d)\n", ret);
+
+	return -ENODEV;
+}
+
+static irqreturn_t maxim2c_hot_plug_detect_irq_handler(int irq, void *dev_id)
+{
+	struct maxim2c *maxim2c = dev_id;
+	struct device *dev = &maxim2c->client->dev;
+	int lock_gpio_level = 0;
+
+	mutex_lock(&maxim2c->mutex);
+	if (maxim2c->streaming) {
+		lock_gpio_level = gpiod_get_value_cansleep(maxim2c->lock_gpio);
+		if (lock_gpio_level == 0) {
+			dev_info(dev, "serializer hot plug out\n");
+
+			maxim2c->hot_plug_state = MAXIM2C_HOT_PLUG_OUT;
+		} else {
+			dev_info(dev, "serializer hot plug in\n");
+
+			maxim2c->hot_plug_state = MAXIM2C_HOT_PLUG_IN;
+		}
+
+		queue_delayed_work(maxim2c->hot_plug_work.state_check_wq,
+					&maxim2c->hot_plug_work.state_d_work,
+					msecs_to_jiffies(100));
+	}
+	mutex_unlock(&maxim2c->mutex);
+
+	return IRQ_HANDLED;
+}
+
+static void maxim2c_lock_irq_init(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	int ret = 0;
+
+	if (!IS_ERR(maxim2c->lock_gpio)) {
+		maxim2c->hot_plug_irq = gpiod_to_irq(maxim2c->lock_gpio);
+		if (maxim2c->hot_plug_irq < 0) {
+			dev_err(dev, "failed to get hot plug irq\n");
+		} else {
+			ret = devm_request_threaded_irq(dev,
+					maxim2c->hot_plug_irq,
+					NULL,
+					maxim2c_hot_plug_detect_irq_handler,
+					IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+					"maxim2c_hot_plug",
+					maxim2c);
+			if (ret) {
+				dev_err(dev, "failed to request hot plug irq (%d)\n", ret);
+				maxim2c->hot_plug_irq = -1;
+			} else {
+				disable_irq(maxim2c->hot_plug_irq);
+			}
+		}
+	}
+}
+
+static void maxim2c_hot_plug_state_check_work(struct work_struct *work)
+{
+	struct maxim2c_hot_plug_work *hot_plug_work =
+		container_of(work, struct maxim2c_hot_plug_work, state_d_work.work);
+	struct maxim2c *maxim2c =
+		container_of(hot_plug_work, struct maxim2c, hot_plug_work);
+	struct device *dev = &maxim2c->client->dev;
+	u8 curr_lock_state = 0, last_lock_state = 0, link_lock_change = 0;
+	u8 link_enable_mask = 0, link_id = 0;
+
+	dev_dbg(dev, "%s\n", __func__);
+
+	mutex_lock(&maxim2c->mutex);
+	if (maxim2c->streaming == 0) {
+		mutex_unlock(&maxim2c->mutex);
+		return;
+	}
+
+	link_enable_mask = maxim2c->gmsl_link.link_enable_mask;
+	last_lock_state = maxim2c->link_lock_state;
+	if ((maxim2c->hot_plug_state == MAXIM2C_HOT_PLUG_OUT)
+			&& (last_lock_state == link_enable_mask)) {
+		maxim2c_link_select_remote_control(maxim2c, 0);
+	}
+
+	curr_lock_state = maxim2c_link_get_lock_state(maxim2c, link_enable_mask);
+	link_lock_change = (last_lock_state ^ curr_lock_state);
+	if (link_lock_change) {
+		dev_dbg(dev, "lock state: current = 0x%02x, last = 0x%02x\n",
+			curr_lock_state, last_lock_state);
+
+		maxim2c->link_lock_state = curr_lock_state;
+	}
+
+	if (link_lock_change & MAXIM2C_LINK_MASK_A) {
+		link_id = MAXIM2C_LINK_ID_A;
+
+		if (curr_lock_state & MAXIM2C_LINK_MASK_A) {
+			dev_info(dev, "Link A plug in\n");
+
+			if (maxim2c->hot_plug_irq > 0)
+				disable_irq(maxim2c->hot_plug_irq);
+
+			maxim2c_remote_devices_init(maxim2c, MAXIM2C_LINK_MASK_A);
+
+			if (maxim2c->hot_plug_irq > 0)
+				enable_irq(maxim2c->hot_plug_irq);
+
+			maxim2c_video_pipe_linkid_enable(maxim2c, link_id, true);
+		} else {
+			dev_info(dev, "Link A plug out\n");
+
+			maxim2c_video_pipe_linkid_enable(maxim2c, link_id, false);
+		}
+	}
+
+	if (link_lock_change & MAXIM2C_LINK_MASK_B) {
+		link_id = MAXIM2C_LINK_ID_B;
+
+		if (curr_lock_state & MAXIM2C_LINK_MASK_B) {
+			dev_info(dev, "Link B plug in\n");
+
+			if (maxim2c->hot_plug_irq > 0)
+				disable_irq(maxim2c->hot_plug_irq);
+
+			maxim2c_remote_devices_init(maxim2c, MAXIM2C_LINK_MASK_B);
+
+			if (maxim2c->hot_plug_irq > 0)
+				enable_irq(maxim2c->hot_plug_irq);
+
+			maxim2c_video_pipe_linkid_enable(maxim2c, link_id, true);
+		} else {
+			dev_info(dev, "Link B plug out\n");
+
+			maxim2c_video_pipe_linkid_enable(maxim2c, link_id, false);
+		}
+	}
+
+	if (curr_lock_state == link_enable_mask) {
+		// remote control mask enable
+		maxim2c_link_select_remote_control(maxim2c, link_enable_mask);
+	} else {
+		queue_delayed_work(maxim2c->hot_plug_work.state_check_wq,
+				&maxim2c->hot_plug_work.state_d_work,
+				msecs_to_jiffies(200));
+	}
+
+	mutex_unlock(&maxim2c->mutex);
+}
+
+int maxim2c_hot_plug_detect_work_start(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	u8 link_lock_state = 0, link_enable_mask = 0;
+
+	link_lock_state = maxim2c->link_lock_state;
+	link_enable_mask = maxim2c->gmsl_link.link_enable_mask;
+
+	if (link_lock_state != link_enable_mask) {
+		dev_info(dev, "%s: link_lock = 0x%02x, link_mask = 0x%02x\n",
+			__func__, link_lock_state, link_enable_mask);
+
+		maxim2c->hot_plug_state = MAXIM2C_HOT_PLUG_OUT;
+
+		queue_delayed_work(maxim2c->hot_plug_work.state_check_wq,
+				&maxim2c->hot_plug_work.state_d_work,
+				msecs_to_jiffies(200));
+	}
+
+	return 0;
+}
+
+static int maxim2c_lock_state_work_init(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+
+	INIT_DELAYED_WORK(&maxim2c->hot_plug_work.state_d_work,
+			maxim2c_hot_plug_state_check_work);
+	maxim2c->hot_plug_work.state_check_wq =
+		create_singlethread_workqueue("maxim2c work queue");
+	if (maxim2c->hot_plug_work.state_check_wq == NULL) {
+		dev_err(dev, "failed to create hot plug work queue\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static int maxim2c_lock_state_work_deinit(maxim2c_t *maxim2c)
+{
+	if (maxim2c->hot_plug_work.state_check_wq) {
+		cancel_delayed_work_sync(&maxim2c->hot_plug_work.state_d_work);
+		destroy_workqueue(maxim2c->hot_plug_work.state_check_wq);
+		maxim2c->hot_plug_work.state_check_wq = NULL;
+	}
+
+	return 0;
+}
+
+/* Calculate the delay in us by clock rate and clock cycles */
+static inline u32 maxim2c_cal_delay(u32 cycles)
+{
+	return DIV_ROUND_UP(cycles, MAXIM2C_XVCLK_FREQ / 1000 / 1000);
+}
+
+static int maxim2c_local_device_power_on(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+
+	if (!IS_ERR(maxim2c->pwdn_gpio)) {
+		dev_info(dev, "local device pwdn gpio on\n");
+
+		gpiod_set_value_cansleep(maxim2c->pwdn_gpio, 1);
+
+		usleep_range(20000, 20100);
+	}
+
+	return 0;
+}
+
+static void maxim2c_local_device_power_off(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+
+	if (!IS_ERR(maxim2c->pwdn_gpio)) {
+		dev_info(dev, "local device pwdn gpio off\n");
+
+		gpiod_set_value_cansleep(maxim2c->pwdn_gpio, 0);
+	}
+}
+
+static int maxim2c_remote_device_power_on(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+
+	// remote PoC enable
+	if (!IS_ERR(maxim2c->pocen_gpio)) {
+		dev_info(dev, "remote device pocen gpio on\n");
+
+		gpiod_set_value_cansleep(maxim2c->pocen_gpio, 1);
+		usleep_range(5000, 10000);
+	}
+
+	return 0;
+}
+
+static int maxim2c_remote_device_power_off(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+
+	// remote PoC enable
+	if (!IS_ERR(maxim2c->pocen_gpio)) {
+		dev_info(dev, "remote device pocen gpio off\n");
+
+		gpiod_set_value_cansleep(maxim2c->pocen_gpio, 0);
+	}
+
+	return 0;
+}
+
+static int maxim2c_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+	int ret = 0;
+
+#if MAXIM2C_LOCAL_DES_ON_OFF_EN
+	ret |= maxim2c_local_device_power_on(maxim2c);
+#endif /* MAXIM2C_LOCAL_DES_ON_OFF_EN */
+
+	ret |= maxim2c_remote_device_power_on(maxim2c);
+
+	return ret;
+}
+
+static int maxim2c_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+	int ret = 0;
+
+	ret |= maxim2c_remote_device_power_off(maxim2c);
+
+#if MAXIM2C_LOCAL_DES_ON_OFF_EN
+	maxim2c_local_device_power_off(maxim2c);
+#endif /* MAXIM2C_LOCAL_DES_ON_OFF_EN */
+
+	return ret;
+}
+
+static const struct dev_pm_ops maxim2c_pm_ops = {
+	SET_RUNTIME_PM_OPS(
+		maxim2c_runtime_suspend, maxim2c_runtime_resume, NULL)
+};
+
+static void maxim2c_module_data_init(maxim2c_t *maxim2c)
+{
+	maxim2c_link_data_init(maxim2c);
+	maxim2c_video_pipe_data_init(maxim2c);
+	maxim2c_mipi_txphy_data_init(maxim2c);
+}
+
+static int maxim2c_extra_init_seq_parse(maxim2c_t *maxim2c, struct device_node *node)
+{
+	struct device *dev = &maxim2c->client->dev;
+	struct device_node *init_seq_node = NULL;
+	struct maxim2c_i2c_init_seq *init_seq = NULL;
+
+	init_seq_node = of_get_child_by_name(node, "extra-init-sequence");
+	if (IS_ERR_OR_NULL(init_seq_node)) {
+		dev_dbg(dev, "%pOF no child node extra-init-sequence\n", node);
+		return 0;
+	}
+
+	if (!of_device_is_available(init_seq_node)) {
+		dev_dbg(dev, "%pOF is disabled\n", init_seq_node);
+
+		of_node_put(init_seq_node);
+		return 0;
+	}
+
+	dev_info(dev, "load extra-init-sequence\n");
+
+	init_seq = &maxim2c->extra_init_seq;
+	maxim2c_i2c_load_init_seq(dev,
+			init_seq_node, init_seq);
+
+	of_node_put(init_seq_node);
+
+	return 0;
+}
+
+static int maxim2c_module_parse_dt(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	struct device_node *node = NULL;
+
+	// maxim serdes local
+	node = of_get_child_by_name(dev->of_node, "serdes-local-device");
+	if (IS_ERR_OR_NULL(node)) {
+		dev_err(dev, "%pOF has no child node: serdes-local-device\n",
+				dev->of_node);
+
+		return -ENODEV;
+	}
+
+	if (!of_device_is_available(node)) {
+		dev_info(dev, "%pOF is disabled\n", node);
+
+		of_node_put(node);
+		return -ENODEV;
+	}
+
+	/* gmsl link parse dt */
+	maxim2c_link_parse_dt(maxim2c, node);
+
+	/* video pipe parse dt */
+	maxim2c_video_pipe_parse_dt(maxim2c, node);
+
+	/* mipi txphy parse dt */
+	maxim2c_mipi_txphy_parse_dt(maxim2c, node);
+
+	/* extra init seq parse dt */
+	maxim2c_extra_init_seq_parse(maxim2c, node);
+
+	of_node_put(node);
+
+	return 0;
+}
+
+static int maxim2c_run_extra_init_seq(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	int ret = 0;
+
+	ret = maxim2c_i2c_run_init_seq(client,
+			&maxim2c->extra_init_seq);
+	if (ret) {
+		dev_err(dev, "extra init sequence error\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int maxim2c_module_hw_previnit(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	int ret = 0;
+
+	// Disable data transmission through video pipe.
+	ret = maxim2c_i2c_update_byte(client,
+			0x0002, MAXIM2C_I2C_REG_ADDR_16BITS,
+			0xF0, 0x00);
+	if (ret)
+		return ret;
+
+	// Video Pipe Y/Z Disable
+	ret = maxim2c_i2c_update_byte(client,
+			0x0160, MAXIM2C_I2C_REG_ADDR_16BITS,
+			BIT(1) | BIT(0), 0);
+	if (ret)
+		return ret;
+
+	// MIPI CSI output disable.
+	ret = maxim2c_i2c_write_byte(client,
+			0x0313, MAXIM2C_I2C_REG_ADDR_16BITS,
+			0x00);
+	if (ret)
+		return ret;
+
+	// MIPI TXPHY standby
+	ret = maxim2c_i2c_update_byte(client,
+			0x0332, MAXIM2C_I2C_REG_ADDR_16BITS,
+			0xF0, 0x00);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int maxim2c_module_hw_postinit(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	int ret = 0;
+
+	// video pipe disable all
+	ret |= maxim2c_i2c_write_byte(client,
+			0x0160, MAXIM2C_I2C_REG_ADDR_16BITS,
+			0);
+
+	// remote control disable all
+	ret |= maxim2c_link_select_remote_control(maxim2c, 0);
+
+	// Enable data transmission through video pipe.
+	ret |= maxim2c_i2c_update_byte(client,
+			0x0002, MAXIM2C_I2C_REG_ADDR_16BITS,
+			0xF0, 0xF0);
+
+	return ret;
+}
+
+int maxim2c_module_hw_init(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	int ret = 0;
+
+	ret = maxim2c_module_hw_previnit(maxim2c);
+	if (ret) {
+		dev_err(dev, "%s: hw prev init error\n", __func__);
+
+		return ret;
+	}
+
+	ret = maxim2c_link_hw_init(maxim2c);
+	if (ret) {
+		dev_err(dev, "%s: hw link init error\n", __func__);
+		return ret;
+	}
+
+	ret = maxim2c_video_pipe_hw_init(maxim2c);
+	if (ret) {
+		dev_err(dev, "%s: hw pipe init error\n", __func__);
+		return ret;
+	}
+
+	ret = maxim2c_mipi_txphy_hw_init(maxim2c);
+	if (ret) {
+		dev_err(dev, "%s: hw txphy init error\n", __func__);
+		return ret;
+	}
+
+	ret = maxim2c_run_extra_init_seq(maxim2c);
+	if (ret) {
+		dev_err(dev, "%s: run extra init seq error\n", __func__);
+		return ret;
+	}
+
+	ret = maxim2c_module_hw_postinit(maxim2c);
+	if (ret) {
+		dev_err(dev, "%s: hw post init error\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_module_hw_init);
+
+static int maxim2c_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct device_node *node = dev->of_node;
+	maxim2c_t *maxim2c = NULL;
+	u32 chip_id;
+	int ret = 0;
+
+	dev_info(dev, "driver version: %02x.%02x.%02x", DRIVER_VERSION >> 16,
+		 (DRIVER_VERSION & 0xff00) >> 8, DRIVER_VERSION & 0x00ff);
+
+	chip_id = (uintptr_t)of_device_get_match_data(dev);
+	if (chip_id == MAX96716_CHIP_ID) {
+		dev_info(dev, "maxim2c driver for max96716\n");
+	} else if (chip_id == MAX96718_CHIP_ID) {
+		dev_info(dev, "maxim2c driver for max96718\n");
+	} else {
+		dev_err(dev, "maxim2c driver unknown chip\n");
+		return -EINVAL;
+	}
+
+	maxim2c = devm_kzalloc(dev, sizeof(*maxim2c), GFP_KERNEL);
+	if (!maxim2c) {
+		dev_err(dev, "maxim2c probe no memory error\n");
+		return -ENOMEM;
+	}
+
+	maxim2c->client = client;
+	maxim2c->chipid = chip_id;
+
+	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
+				   &maxim2c->module_index);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
+				       &maxim2c->module_facing);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
+				       &maxim2c->module_name);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
+				       &maxim2c->len_name);
+	if (ret) {
+		dev_err(dev, "could not get module information!\n");
+		return -EINVAL;
+	}
+
+	maxim2c->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
+	if (IS_ERR(maxim2c->pwdn_gpio))
+		dev_warn(dev, "Failed to get pwdn-gpios, maybe no use\n");
+	else
+		usleep_range(1000, 1100);
+
+	maxim2c->pocen_gpio = devm_gpiod_get(dev, "pocen", GPIOD_OUT_LOW);
+	if (IS_ERR(maxim2c->pocen_gpio))
+		dev_warn(dev, "Failed to get pocen-gpios\n");
+
+	maxim2c->lock_gpio = devm_gpiod_get(dev, "lock", GPIOD_IN);
+	if (IS_ERR(maxim2c->lock_gpio))
+		dev_warn(dev, "Failed to get lock-gpios\n");
+
+	mutex_init(&maxim2c->mutex);
+
+	ret = maxim2c_local_device_power_on(maxim2c);
+	if (ret)
+		goto err_destroy_mutex;
+
+	ret = maxim2c_check_local_chipid(maxim2c);
+	if (ret)
+		goto err_power_off;
+
+	// client->dev->driver_data = subdev
+	// subdev->dev->driver_data = maxim2c
+	ret = maxim2c_v4l2_subdev_init(maxim2c);
+	if (ret) {
+		dev_err(dev, "maxim2c probe v4l2 subdev init error\n");
+		goto err_power_off;
+	}
+
+#if MAXIM2C_TEST_PATTERN
+	ret = maxim2c_pattern_data_init(maxim2c);
+	if (ret)
+		goto err_power_off;
+
+#if (MAXIM2C_LOCAL_DES_ON_OFF_EN == 0)
+	ret = maxim2c_pattern_hw_init(maxim2c);
+	if (ret)
+		goto err_power_off;
+#endif /* MAXIM2C_LOCAL_DES_ON_OFF_EN */
+
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_idle(dev);
+
+	return 0;
+#endif /* MAXIM2C_TEST_PATTERN */
+
+	maxim2c_module_data_init(maxim2c);
+	maxim2c_module_parse_dt(maxim2c);
+
+#if (MAXIM2C_LOCAL_DES_ON_OFF_EN == 0)
+	ret = maxim2c_module_hw_init(maxim2c);
+	if (ret)
+		goto err_subdev_deinit;
+#endif /* MAXIM2C_LOCAL_DES_ON_OFF_EN */
+
+	ret = maxim2c_remote_mfd_add_devices(maxim2c);
+	if (ret)
+		goto err_subdev_deinit;
+
+	maxim2c_lock_irq_init(maxim2c);
+	maxim2c_lock_state_work_init(maxim2c);
+
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_idle(dev);
+
+	return 0;
+
+err_subdev_deinit:
+	maxim2c_v4l2_subdev_deinit(maxim2c);
+err_power_off:
+	maxim2c_local_device_power_off(maxim2c);
+err_destroy_mutex:
+	mutex_destroy(&maxim2c->mutex);
+
+	return ret;
+}
+
+static int maxim2c_remove(struct i2c_client *client)
+{
+	maxim2c_t *maxim2c = i2c_get_clientdata(client);
+
+	maxim2c_lock_state_work_deinit(maxim2c);
+
+	maxim2c_v4l2_subdev_deinit(maxim2c);
+
+	mutex_destroy(&maxim2c->mutex);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		maxim2c_local_device_power_off(maxim2c);
+	pm_runtime_set_suspended(&client->dev);
+
+	return 0;
+}
+
+static const struct of_device_id maxim2c_of_match[] = {
+	{
+		.compatible = "maxim2c,max96716",
+		.data = (const void *)MAX96716_CHIP_ID
+	}, {
+		.compatible = "maxim2c,max96718",
+		.data = (const void *)MAX96718_CHIP_ID
+	},
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, maxim2c_of_match);
+
+static struct i2c_driver maxim2c_i2c_driver = {
+	.driver = {
+		.name = MAXIM2C_NAME,
+		.pm = &maxim2c_pm_ops,
+		.of_match_table = of_match_ptr(maxim2c_of_match),
+	},
+	.probe		= &maxim2c_probe,
+	.remove		= &maxim2c_remove,
+};
+
+module_i2c_driver(maxim2c_i2c_driver);
+
+MODULE_AUTHOR("Cai Wenzhong <cwz@rock-chips.com>");
+MODULE_DESCRIPTION("Maxim dual gmsl deserializer driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_drv.h b/kernel/drivers/media/i2c/maxim2c/maxim2c_drv.h
new file mode 100644
index 0000000..dfaad26
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_drv.h
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+#ifndef __MAXIM2C_DRV_H__
+#define __MAXIM2C_DRV_H__
+
+#include <linux/workqueue.h>
+#include <linux/rk-camera-module.h>
+#include <linux/mfd/core.h>
+#include <linux/regulator/consumer.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+#include "maxim2c_i2c.h"
+#include "maxim2c_link.h"
+#include "maxim2c_mipi_txphy.h"
+#include "maxim2c_remote.h"
+#include "maxim2c_pattern.h"
+
+#define MAXIM2C_REG_CHIP_ID		0x0D
+#define MAX96716_CHIP_ID		0xBE
+#define MAX96718_CHIP_ID		0xB8
+
+enum {
+	MAXIM2C_HOT_PLUG_OUT = 0,
+	MAXIM2C_HOT_PLUG_IN,
+};
+
+struct maxim2c_hot_plug_work {
+	struct workqueue_struct *state_check_wq;
+	struct delayed_work state_d_work;
+	u32 hot_plug_state;
+};
+
+struct maxim2c_mode {
+	u32 width;
+	u32 height;
+	struct v4l2_fract max_fps;
+	u32 hts_def;
+	u32 vts_def;
+	u32 exp_def;
+	u32 link_freq_idx;
+	u32 bus_fmt;
+	u32 bpp;
+	const struct regval *reg_list;
+	u32 vc[PAD_MAX];
+};
+
+typedef struct maxim2c {
+	struct i2c_client *client;
+	struct clk *xvclk;
+	struct gpio_desc *pwdn_gpio;
+	struct gpio_desc *pocen_gpio;
+	struct gpio_desc *lock_gpio;
+
+	struct mutex mutex;
+
+	struct v4l2_subdev subdev;
+	struct media_pad pad;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl *exposure;
+	struct v4l2_ctrl *anal_gain;
+	struct v4l2_ctrl *digi_gain;
+	struct v4l2_ctrl *hblank;
+	struct v4l2_ctrl *vblank;
+	struct v4l2_ctrl *pixel_rate;
+	struct v4l2_ctrl *link_freq;
+	struct v4l2_fwnode_endpoint bus_cfg;
+
+	u32 chipid;
+
+	bool streaming;
+	bool power_on;
+	bool hot_plug;
+	u8 is_reset;
+	int hot_plug_irq;
+	u32 hot_plug_state;
+	u32 link_lock_state;
+	struct maxim2c_hot_plug_work hot_plug_work;
+
+	struct maxim2c_mode supported_mode;
+	const struct maxim2c_mode *cur_mode;
+	u32 cfg_modes_num;
+
+	u32 module_index;
+	const char *module_facing;
+	const char *module_name;
+	const char *len_name;
+
+	maxim2c_gmsl_link_t gmsl_link;
+	maxim2c_video_pipe_t video_pipe;
+	maxim2c_mipi_txphy_t mipi_txphy;
+
+	struct maxim2c_pattern pattern;
+
+	struct maxim2c_i2c_init_seq extra_init_seq;
+
+	struct mfd_cell remote_mfd_devs[MAXIM2C_LINK_ID_MAX];
+	maxim2c_remote_t *remote_device[MAXIM2C_LINK_ID_MAX];
+} maxim2c_t;
+
+#endif /* __MAXIM2C_DRV_H__ */
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_i2c.c b/kernel/drivers/media/i2c/maxim2c/maxim2c_i2c.c
new file mode 100644
index 0000000..2ae7500
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_i2c.c
@@ -0,0 +1,407 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim Dual GMSL Deserializer I2C read/write driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * Author: Cai Wenzhong <cwz@rock-chips.com>
+ *
+ */
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include "maxim2c_i2c.h"
+
+/* Write registers up to 4 at a time */
+int maxim2c_i2c_write_reg(struct i2c_client *client,
+		u16 reg_addr, u16 reg_len, u32 val_len, u32 reg_val)
+{
+	u32 buf_i, val_i;
+	u8 buf[6];
+	u8 *val_p;
+	__be32 val_be;
+
+	dev_info(&client->dev, "i2c addr(0x%02x) write: 0x%04x (%d) = 0x%08x (%d)\n",
+			client->addr, reg_addr, reg_len, reg_val, val_len);
+
+	if (val_len > 4)
+		return -EINVAL;
+
+	if (reg_len == 2) {
+		buf[0] = reg_addr >> 8;
+		buf[1] = reg_addr & 0xff;
+
+		buf_i = 2;
+	} else {
+		buf[0] = reg_addr & 0xff;
+
+		buf_i = 1;
+	}
+
+	val_be = cpu_to_be32(reg_val);
+	val_p = (u8 *)&val_be;
+	val_i = 4 - val_len;
+
+	while (val_i < 4)
+		buf[buf_i++] = val_p[val_i++];
+
+	if (i2c_master_send(client, buf, (val_len + reg_len)) != (val_len + reg_len)) {
+		dev_err(&client->dev,
+			"%s: writing register 0x%04x from 0x%02x failed\n",
+			__func__, reg_addr, client->addr);
+		return -EIO;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_i2c_write_reg);
+
+/* Read registers up to 4 at a time */
+int maxim2c_i2c_read_reg(struct i2c_client *client,
+		u16 reg_addr, u16 reg_len, u32 val_len, u32 *reg_val)
+{
+	struct i2c_msg msgs[2];
+	u8 *data_be_p;
+	__be32 data_be = 0;
+	__be16 reg_addr_be = cpu_to_be16(reg_addr);
+	u8 *reg_be_p;
+	int ret;
+
+	if (val_len > 4 || !val_len)
+		return -EINVAL;
+
+	data_be_p = (u8 *)&data_be;
+	reg_be_p = (u8 *)&reg_addr_be;
+
+	/* Write register address */
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = reg_len;
+	msgs[0].buf = &reg_be_p[2 - reg_len];
+
+	/* Read data from register */
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = val_len;
+	msgs[1].buf = &data_be_p[4 - val_len];
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs)) {
+		dev_err(&client->dev,
+			"%s: reading register 0x%04x from 0x%02x failed\n",
+			__func__, reg_addr, client->addr);
+		return -EIO;
+	}
+
+	*reg_val = be32_to_cpu(data_be);
+
+#if 0
+	dev_info(&client->dev, "i2c addr(0x%02x) read: 0x%04x (%d) = 0x%08x (%d)\n",
+		client->addr, reg_addr, reg_len, *reg_val, val_len);
+#endif
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_i2c_read_reg);
+
+/* Update registers up to 4 at a time */
+int maxim2c_i2c_update_reg(struct i2c_client *client,
+		u16 reg_addr, u16 reg_len, u32 val_len, u32 val_mask, u32 reg_val)
+{
+	u32 value;
+	int ret;
+
+	ret = maxim2c_i2c_read_reg(client, reg_addr, reg_len, val_len, &value);
+	if (ret)
+		return ret;
+
+	value &= ~val_mask;
+	value |= (reg_val & val_mask);
+	ret = maxim2c_i2c_write_reg(client, reg_addr, reg_len, val_len, value);
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_i2c_update_reg);
+
+int maxim2c_i2c_write_byte(struct i2c_client *client,
+		u16 reg_addr, u16 reg_len, u8 reg_val)
+{
+	int ret = 0;
+
+	ret = maxim2c_i2c_write_reg(client,
+			reg_addr, reg_len,
+			MAXIM2C_I2C_REG_VALUE_08BITS, reg_val);
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_i2c_write_byte);
+
+int maxim2c_i2c_read_byte(struct i2c_client *client,
+		u16 reg_addr, u16 reg_len, u8 *reg_val)
+{
+	int ret = 0;
+	u32 value = 0;
+	u8 *value_be_p = (u8 *)&value;
+
+	ret = maxim2c_i2c_read_reg(client,
+			reg_addr, reg_len,
+			MAXIM2C_I2C_REG_VALUE_08BITS, &value);
+
+	*reg_val = *value_be_p;
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_i2c_read_byte);
+
+int maxim2c_i2c_update_byte(struct i2c_client *client,
+		u16 reg_addr, u16 reg_len, u8 val_mask, u8 reg_val)
+{
+	u8 value;
+	int ret;
+
+	ret = maxim2c_i2c_read_byte(client, reg_addr, reg_len, &value);
+	if (ret)
+		return ret;
+
+	value &= ~val_mask;
+	value |= (reg_val & val_mask);
+	ret = maxim2c_i2c_write_byte(client, reg_addr, reg_len, value);
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_i2c_update_byte);
+
+int maxim2c_i2c_write_array(struct i2c_client *client,
+				const struct maxim2c_i2c_regval *regs)
+{
+	u32 i = 0;
+	int ret = 0;
+
+	for (i = 0; (ret == 0) && (regs[i].reg_addr != MAXIM2C_REG_NULL); i++) {
+		if (regs[i].val_mask != 0)
+			ret = maxim2c_i2c_update_reg(client,
+					regs[i].reg_addr, regs[i].reg_len,
+					regs[i].val_len, regs[i].val_mask, regs[i].reg_val);
+		else
+			ret = maxim2c_i2c_write_reg(client,
+					regs[i].reg_addr, regs[i].reg_len,
+					regs[i].val_len, regs[i].reg_val);
+
+		if (regs[i].delay != 0)
+			usleep_range(regs[i].delay * 1000, regs[i].delay * 1000 + 100);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_i2c_write_array);
+
+static int maxim2c_i2c_parse_init_seq(struct device *dev,
+		const u8 *seq_data, int data_len, struct maxim2c_i2c_init_seq *init_seq)
+{
+	struct maxim2c_i2c_regval *reg_val = NULL;
+	u8 *data_buf = NULL, *d8 = NULL;
+	u32 i = 0;
+
+	if ((seq_data == NULL) || (init_seq == NULL)) {
+		dev_err(dev, "%s: input parameter = NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	if ((init_seq->seq_item_size == 0)
+			|| (data_len == 0)
+			|| (init_seq->reg_len == 0)
+			|| (init_seq->val_len == 0)) {
+		dev_err(dev, "%s: input parameter size zero\n", __func__);
+		return -EINVAL;
+	}
+
+	// data_len = seq_item_size * N
+	if (data_len % init_seq->seq_item_size) {
+		dev_err(dev, "%s: data_len or seq_item_size error\n", __func__);
+		return -EINVAL;
+	}
+
+	// seq_item_size = reg_len + val_len * 2 + 1
+	if (init_seq->seq_item_size !=
+			(init_seq->reg_len + init_seq->val_len * 2 + 1)) {
+		dev_err(dev, "%s: seq_item_size or reg_len or val_len error\n", __func__);
+		return -EINVAL;
+	}
+
+	data_buf = devm_kmemdup(dev, seq_data, data_len, GFP_KERNEL);
+	if (!data_buf) {
+		dev_err(dev, "%s data buf error\n", __func__);
+		return -ENOMEM;
+	}
+
+	d8 = data_buf;
+
+	init_seq->reg_seq_size = data_len / init_seq->seq_item_size;
+	init_seq->reg_seq_size += 1; // add 1 for end register setting
+
+	init_seq->reg_init_seq = devm_kcalloc(dev, init_seq->reg_seq_size,
+					sizeof(struct maxim2c_i2c_regval), GFP_KERNEL);
+	if (!init_seq->reg_init_seq) {
+		dev_err(dev, "%s init seq buffer error\n", __func__);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < init_seq->reg_seq_size - 1; i++) {
+		reg_val = &init_seq->reg_init_seq[i];
+
+		reg_val->reg_len = init_seq->reg_len;
+		reg_val->val_len = init_seq->val_len;
+
+		reg_val->reg_addr = 0;
+		switch (init_seq->reg_len) {
+		case 4:
+			reg_val->reg_addr |= (*d8 << 24);
+			d8 += 1;
+			fallthrough;
+		case 3:
+			reg_val->reg_addr |= (*d8 << 16);
+			d8 += 1;
+			fallthrough;
+		case 2:
+			reg_val->reg_addr |= (*d8 << 8);
+			d8 += 1;
+			fallthrough;
+		case 1:
+			reg_val->reg_addr |= (*d8 << 0);
+			d8 += 1;
+			break;
+		}
+
+		reg_val->reg_val = 0;
+		switch (init_seq->val_len) {
+		case 4:
+			reg_val->reg_val |= (*d8 << 24);
+			d8 += 1;
+			fallthrough;
+		case 3:
+			reg_val->reg_val |= (*d8 << 16);
+			d8 += 1;
+			fallthrough;
+		case 2:
+			reg_val->reg_val |= (*d8 << 8);
+			d8 += 1;
+			fallthrough;
+		case 1:
+			reg_val->reg_val |= (*d8 << 0);
+			d8 += 1;
+			break;
+		}
+
+		reg_val->val_mask = 0;
+		switch (init_seq->val_len) {
+		case 4:
+			reg_val->val_mask |= (*d8 << 24);
+			d8 += 1;
+			fallthrough;
+		case 3:
+			reg_val->val_mask |= (*d8 << 16);
+			d8 += 1;
+			fallthrough;
+		case 2:
+			reg_val->val_mask |= (*d8 << 8);
+			d8 += 1;
+			fallthrough;
+		case 1:
+			reg_val->val_mask |= (*d8 << 0);
+			d8 += 1;
+			break;
+		}
+
+		reg_val->delay = *d8;
+		d8 += 1;
+	}
+
+	// End register setting
+	init_seq->reg_init_seq[init_seq->reg_seq_size - 1].reg_len = init_seq->reg_len;
+	init_seq->reg_init_seq[init_seq->reg_seq_size - 1].reg_addr = MAXIM2C_REG_NULL;
+
+	return 0;
+}
+
+int maxim2c_i2c_load_init_seq(struct device *dev,
+		struct device_node *node, struct maxim2c_i2c_init_seq *init_seq)
+{
+	const void *init_seq_data = NULL;
+	u32 seq_data_len = 0, value = 0;
+	int ret = 0;
+
+	if ((node == NULL) || (init_seq == NULL)) {
+		dev_err(dev, "%s input parameter error\n", __func__);
+		return -EINVAL;
+	}
+
+	init_seq->reg_init_seq = NULL;
+	init_seq->reg_seq_size = 0;
+
+	if (!of_device_is_available(node)) {
+		dev_info(dev, "%pOF is disabled\n", node);
+
+		return 0;
+	}
+
+	init_seq_data = of_get_property(node, "init-sequence", &seq_data_len);
+	if (!init_seq_data) {
+		dev_err(dev, "failed to get property init-sequence\n");
+		return -EINVAL;
+	}
+	if (seq_data_len == 0) {
+		dev_err(dev, "init-sequence date is empty\n");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(node, "seq-item-size", &value);
+	if (ret) {
+		dev_err(dev, "failed to get property seq-item-size\n");
+		return -EINVAL;
+	} else {
+		dev_info(dev, "seq-item-size property: %d", value);
+		init_seq->seq_item_size = value;
+	}
+
+	ret = of_property_read_u32(node, "reg-addr-len", &value);
+	if (ret) {
+		dev_err(dev, "failed to get property reg-addr-len\n");
+		return -EINVAL;
+	} else {
+		dev_info(dev, "reg-addr-len property: %d", value);
+		init_seq->reg_len = value;
+	}
+
+	ret = of_property_read_u32(node, "reg-val-len", &value);
+	if (ret) {
+		dev_err(dev, "failed to get property reg-val-len\n");
+		return -EINVAL;
+	} else {
+		dev_info(dev, "reg-val-len property: %d", value);
+		init_seq->val_len = value;
+	}
+
+	ret = maxim2c_i2c_parse_init_seq(dev,
+			init_seq_data, seq_data_len, init_seq);
+	if (ret) {
+		dev_err(dev, "failed to parse init-sequence\n");
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_i2c_load_init_seq);
+
+int maxim2c_i2c_run_init_seq(struct i2c_client *client,
+			struct maxim2c_i2c_init_seq *init_seq)
+{
+	int ret = 0;
+
+	if (init_seq == NULL || init_seq->reg_init_seq == NULL)
+		return 0;
+
+	ret = maxim2c_i2c_write_array(client,
+			init_seq->reg_init_seq);
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_i2c_run_init_seq);
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_i2c.h b/kernel/drivers/media/i2c/maxim2c/maxim2c_i2c.h
new file mode 100644
index 0000000..620a4ff
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_i2c.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+#ifndef __MAXIM2C_I2C_H__
+#define __MAXIM2C_I2C_H__
+
+#include <linux/i2c.h>
+
+/* register address: 8bit or 16bit */
+#define MAXIM2C_I2C_REG_ADDR_08BITS	1
+#define MAXIM2C_I2C_REG_ADDR_16BITS	2
+
+/* register value: 8bit or 16bit or 24bit */
+#define MAXIM2C_I2C_REG_VALUE_08BITS	1
+#define MAXIM2C_I2C_REG_VALUE_16BITS	2
+#define MAXIM2C_I2C_REG_VALUE_24BITS	3
+
+/* I2C Device ID */
+enum {
+	MAXIM2C_I2C_DES_DEF,	/* Deserializer I2C address: Default */
+
+	MAXIM2C_I2C_SER_DEF,	/* Serializer I2C address: Default */
+	MAXIM2C_I2C_SER_MAP,	/* Serializer I2C address: Mapping */
+
+	MAXIM2C_I2C_CAM_DEF,	/* Camera I2C address: Default */
+	MAXIM2C_I2C_CAM_MAP,	/* Camera I2C address: Mapping */
+
+	MAXIM2C_I2C_DEV_MAX,
+};
+
+/* i2c register array end */
+#define MAXIM2C_REG_NULL		0xFFFF
+
+struct maxim2c_i2c_regval {
+	u16 reg_len;
+	u16 reg_addr;
+	u32 val_len;
+	u32 reg_val;
+	u32 val_mask;
+	u8 delay;
+};
+
+/* seq_item_size = reg_len + val_len * 2 + 1 */
+struct maxim2c_i2c_init_seq {
+	struct maxim2c_i2c_regval *reg_init_seq;
+	u32 reg_seq_size;
+	u32 seq_item_size;
+	u32 reg_len;
+	u32 val_len;
+};
+
+#endif /* __MAXIM2C_I2C_H__ */
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_link.c b/kernel/drivers/media/i2c/maxim2c/maxim2c_link.c
new file mode 100644
index 0000000..4b17335
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_link.c
@@ -0,0 +1,618 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim Dual GMSL Deserializer Link driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * Author: Cai Wenzhong <cwz@rock-chips.com>
+ *
+ */
+#include <linux/delay.h>
+#include "maxim2c_api.h"
+
+static int maxim2c_link_enable_vdd_ldo1(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	int ret = 0;
+
+	/* IF VDD = 1.2V: Enable REG_ENABLE and REG_MNL
+	 *	CTRL0: Enable REG_ENABLE
+	 *	CTRL2: Enable REG_MNL
+	 */
+	ret |= maxim2c_i2c_update_byte(client,
+			0x0010, MAXIM2C_I2C_REG_ADDR_16BITS, BIT(2), BIT(2));
+	ret |= maxim2c_i2c_update_byte(client,
+			0x0012, MAXIM2C_I2C_REG_ADDR_16BITS, BIT(4), BIT(4));
+
+	return ret;
+}
+
+static int maxim2c_link_set_rate(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	maxim2c_gmsl_link_t *gmsl_link = &maxim2c->gmsl_link;
+	struct maxim2c_link_cfg *link_cfg = NULL;
+	u8 link_rate = 0;
+	int ret = 0;
+
+	/* Link A rate setting */
+	link_rate = 0; /* default Transmitter Rate is 187.5Mbps */
+	link_cfg = &gmsl_link->link_cfg[MAXIM2C_LINK_ID_A];
+	if (link_cfg->link_enable) {
+		/* Link A: Receiver Rate */
+		if (link_cfg->link_rx_rate == MAXIM2C_LINK_RX_RATE_3GBPS)
+			link_rate |= (0x1 << 0);
+		else
+			link_rate |= (0x2 << 0);
+
+		ret |= maxim2c_i2c_update_byte(client,
+				0x0001, MAXIM2C_I2C_REG_ADDR_16BITS,
+				0x0F, link_rate);
+	}
+
+	/* Link B rate setting */
+	link_rate = 0; /* default Transmitter Rate is 187.5Mbps */
+	link_cfg = &gmsl_link->link_cfg[MAXIM2C_LINK_ID_B];
+	if (link_cfg->link_enable) {
+		/* Link B: Receiver Rate */
+		if (link_cfg->link_rx_rate == MAXIM2C_LINK_RX_RATE_3GBPS)
+			link_rate |= (0x1 << 0);
+		else
+			link_rate |= (0x2 << 0);
+
+		ret |= maxim2c_i2c_update_byte(client,
+				0x0004, MAXIM2C_I2C_REG_ADDR_16BITS,
+				0x0F, link_rate);
+	}
+
+	return ret;
+}
+
+static int maxim2c_link_run_init_seq(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	maxim2c_gmsl_link_t *gmsl_link = &maxim2c->gmsl_link;
+	struct maxim2c_link_cfg *link_cfg = NULL;
+	struct maxim2c_i2c_init_seq *init_seq = NULL;
+	int link_idx = 0;
+	int ret = 0;
+
+	// link init sequence
+	for (link_idx = 0; link_idx < MAXIM2C_LINK_ID_MAX; link_idx++) {
+		link_cfg = &gmsl_link->link_cfg[link_idx];
+		init_seq = &link_cfg->link_init_seq;
+		ret = maxim2c_i2c_run_init_seq(client, init_seq);
+		if (ret) {
+			dev_err(dev, "link id = %d init sequence error\n", link_idx);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int maxim2c_link_status_init(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	maxim2c_gmsl_link_t *gmsl_link = &maxim2c->gmsl_link;
+	struct maxim2c_link_cfg *link_cfg = NULL;
+	u8 reg_mask = 0, reg_value = 0;
+	u16 reg_addr = 0;
+	int ret = 0, link_idx = 0;
+
+	gmsl_link->link_enable_mask = 0x00;
+	gmsl_link->link_type_mask = 0x03;
+	gmsl_link->link_locked_mask = 0;
+
+	reg_mask = 0xC0;
+	reg_value = 0xC0; /* default GMSL2 */
+	for (link_idx = 0; link_idx < MAXIM2C_LINK_ID_MAX; link_idx++) {
+		link_cfg = &gmsl_link->link_cfg[link_idx];
+		if (link_cfg->link_enable) {
+			gmsl_link->link_enable_mask |= BIT(link_idx);
+
+			if (link_cfg->link_type == MAXIM2C_GMSL1) {
+				gmsl_link->link_type_mask &= ~BIT(link_idx);
+				reg_value &= ~BIT(6 + link_idx);
+			}
+		}
+	}
+	ret |= maxim2c_i2c_update_byte(client,
+			0x0006, MAXIM2C_I2C_REG_ADDR_16BITS,
+			reg_mask, reg_value);
+
+	// AUTO_LINK disable, LINK_CFG for Link A and Link B select
+	reg_mask = BIT(4) | BIT(1) | BIT(0);
+	reg_value = 0;
+	for (link_idx = 0; link_idx < MAXIM2C_LINK_ID_MAX; link_idx++) {
+		link_cfg = &gmsl_link->link_cfg[link_idx];
+		if (link_cfg->link_enable)
+			reg_value |= BIT(link_idx);
+	}
+	ret |= maxim2c_i2c_update_byte(client,
+			0x0010, MAXIM2C_I2C_REG_ADDR_16BITS,
+			reg_mask, reg_value);
+
+	// GMSL1 Link disable forward and reverse control channel
+	reg_mask = BIT(1) | BIT(0);
+	reg_value = 0;
+	for (link_idx = 0; link_idx < MAXIM2C_LINK_ID_MAX; link_idx++) {
+		reg_addr = 0x0B04 + 0x100 * link_idx;
+		ret |= maxim2c_i2c_update_byte(client,
+				reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS,
+				reg_mask, reg_value);
+	}
+
+	// GMSL2 Link disable remote control channel
+	reg_mask = BIT(4);
+	reg_value = BIT(4);
+	reg_addr = 0x0001;
+	ret |= maxim2c_i2c_update_byte(client,
+			reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS,
+			reg_mask, reg_value);
+
+	reg_mask = BIT(2);
+	reg_value = BIT(2);
+	reg_addr = 0x0003;
+	ret |= maxim2c_i2c_update_byte(client,
+			reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS,
+			reg_mask, reg_value);
+
+	return ret;
+}
+
+u8 maxim2c_link_get_lock_state(maxim2c_t *maxim2c, u8 link_mask)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	maxim2c_gmsl_link_t *gmsl_link = &maxim2c->gmsl_link;
+	u8 link_type = 0, link_lock = 0, lock_state = 0;
+
+	dev_dbg(dev, "%s, link_mask = 0x%x\n", __func__, link_mask);
+
+	// Link A
+	if (link_mask & MAXIM2C_LINK_MASK_A) {
+		link_type = gmsl_link->link_cfg[MAXIM2C_LINK_ID_A].link_type;
+		if (link_type == MAXIM2C_GMSL2) {
+			// GMSL2 Link A
+			maxim2c_i2c_read_byte(client,
+				0x0013, MAXIM2C_I2C_REG_ADDR_16BITS,
+				&link_lock);
+			if (link_lock & BIT(3)) {
+				lock_state |= MAXIM2C_LINK_MASK_A;
+				dev_dbg(dev, "GMSL2 Link A locked\n");
+			}
+		} else {
+			// GMSL1 Link A
+			maxim2c_i2c_read_byte(client,
+				0x0BCB, MAXIM2C_I2C_REG_ADDR_16BITS,
+				&link_lock);
+			if (link_lock & BIT(0)) {
+				lock_state |= MAXIM2C_LINK_MASK_A;
+				dev_dbg(dev, "GMSL1 Link A locked\n");
+			}
+		}
+
+		// record link lock
+		if (lock_state & MAXIM2C_LINK_MASK_A)
+			gmsl_link->link_locked_mask |= MAXIM2C_LINK_MASK_A;
+		else
+			gmsl_link->link_locked_mask &= ~MAXIM2C_LINK_MASK_A;
+	}
+
+	// Link B
+	if (link_mask & MAXIM2C_LINK_MASK_B) {
+		link_type = gmsl_link->link_cfg[MAXIM2C_LINK_ID_B].link_type;
+		if (link_type == MAXIM2C_GMSL2) {
+			// GMSL2 Link B
+			maxim2c_i2c_read_byte(client,
+				0x5009, MAXIM2C_I2C_REG_ADDR_16BITS,
+				&link_lock);
+			if (link_lock & BIT(3)) {
+				lock_state |= MAXIM2C_LINK_MASK_B;
+				dev_dbg(dev, "GMSL2 Link B locked\n");
+			}
+		} else {
+			// GMSL1 Link B
+			maxim2c_i2c_read_byte(client,
+				0x0CCB, MAXIM2C_I2C_REG_ADDR_16BITS,
+				&link_lock);
+			if (link_lock & BIT(0)) {
+				lock_state |= MAXIM2C_LINK_MASK_B;
+				dev_dbg(dev, "GMSL1 Link B locked\n");
+			}
+		}
+
+		// record link lock
+		if (lock_state & MAXIM2C_LINK_MASK_B)
+			gmsl_link->link_locked_mask |= MAXIM2C_LINK_MASK_B;
+		else
+			gmsl_link->link_locked_mask &= ~MAXIM2C_LINK_MASK_B;
+	}
+
+	return lock_state;
+}
+EXPORT_SYMBOL(maxim2c_link_get_lock_state);
+
+int maxim2c_link_oneshot_reset(struct maxim2c *maxim2c, u8 link_mask)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	maxim2c_gmsl_link_t *gmsl_link = &maxim2c->gmsl_link;
+	struct maxim2c_link_cfg *link_cfg = NULL;
+	int ret = 0, link_idx = 0;
+
+	dev_dbg(dev, "%s, link_mask = 0x%x\n", __func__, link_mask);
+
+	// Link A
+	if (link_mask & MAXIM2C_LINK_MASK_A) {
+		link_idx = MAXIM2C_LINK_ID_A;
+		link_cfg = &gmsl_link->link_cfg[link_idx];
+		if (link_cfg->link_enable && (link_mask & BIT(link_idx))) {
+			ret = maxim2c_i2c_update_byte(client,
+					0x0010, MAXIM2C_I2C_REG_ADDR_16BITS,
+					BIT(5), BIT(5));
+			if (ret) {
+				dev_err(dev, "Link A oneshot reset error\n");
+				return ret;
+			}
+		}
+	}
+
+	// Link B
+	if (link_mask & MAXIM2C_LINK_MASK_B) {
+		link_idx = MAXIM2C_LINK_ID_B;
+		link_cfg = &gmsl_link->link_cfg[link_idx];
+		if (link_cfg->link_enable && (link_mask & BIT(link_idx))) {
+			ret = maxim2c_i2c_update_byte(client,
+					0x0012, MAXIM2C_I2C_REG_ADDR_16BITS,
+					BIT(5), BIT(5));
+			if (ret) {
+				dev_err(dev, "Link B oneshot reset error\n");
+				return ret;
+			}
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_link_oneshot_reset);
+
+int maxim2c_link_mask_enable(struct maxim2c *maxim2c, u8 link_mask, bool enable)
+{
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_link_mask_enable);
+
+int maxim2c_link_wait_linklock(struct maxim2c *maxim2c, u8 link_mask)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	u8 lock_state = 0, link_bit_mask = 0;
+	int loop_idx = 0, time_ms = 0, link_idx = 0;
+
+	time_ms = 50;
+	msleep(time_ms);
+
+	for (loop_idx = 0; loop_idx < 20; loop_idx++) {
+		if (loop_idx != 0) {
+			msleep(10);
+			time_ms += 10;
+		}
+
+		for (link_idx = 0; link_idx < MAXIM2C_LINK_ID_MAX; link_idx++) {
+			link_bit_mask = BIT(link_idx);
+
+			if ((link_mask & link_bit_mask)
+					&& ((lock_state & link_bit_mask) == 0)) {
+				if (maxim2c_link_get_lock_state(maxim2c, link_bit_mask)) {
+					lock_state |= link_bit_mask;
+					dev_info(dev, "Link %c locked time: %d ms\n",
+						'A' + link_idx, time_ms);
+				}
+			}
+		}
+
+		if ((lock_state & link_mask) == link_mask) {
+			dev_info(dev, "All Links are locked: 0x%x, time_ms = %d\n",
+				lock_state, time_ms);
+			maxim2c->link_lock_state = lock_state;
+			return 0;
+		}
+	}
+
+	if ((lock_state & link_mask) != 0) {
+		dev_info(dev, "Partial links are locked: 0x%x, time_ms = %d\n",
+			lock_state, time_ms);
+		maxim2c->link_lock_state = lock_state;
+		return 0;
+	} else {
+		dev_err(dev, "Failed to detect remote link, time_ms = %d!\n", time_ms);
+		maxim2c->link_lock_state = 0;
+		return -ENODEV;
+	}
+}
+EXPORT_SYMBOL(maxim2c_link_wait_linklock);
+
+int maxim2c_link_select_remote_enable(struct maxim2c *maxim2c, u8 link_mask)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	int ret = 0;
+
+	dev_dbg(dev, "%s, link_mask = 0x%x\n", __func__, link_mask);
+
+	ret = maxim2c_link_oneshot_reset(maxim2c, link_mask);
+	if (ret) {
+		dev_err(dev, "%s: link oneshot reset error, link mask = 0x%x\n",
+				__func__, link_mask);
+		return ret;
+	}
+
+	ret = maxim2c_link_mask_enable(maxim2c, link_mask, true);
+	if (ret) {
+		dev_err(dev, "%s: link enable error, link mask = 0x%x\n",
+				__func__, link_mask);
+		return ret;
+	}
+
+	maxim2c_link_wait_linklock(maxim2c, link_mask);
+	dev_info(dev, "link_mask = 0x%02x, link_lock = 0x%02x\n",
+			link_mask, maxim2c->link_lock_state);
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_link_select_remote_enable);
+
+int maxim2c_link_select_remote_control(struct maxim2c *maxim2c, u8 link_mask)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	maxim2c_gmsl_link_t *gmsl_link = &maxim2c->gmsl_link;
+	struct maxim2c_link_cfg *link_cfg = NULL;
+	u8 reg_mask = 0, reg_value = 0;
+	u16 reg_addr = 0;
+	int link_idx = 0, ret = 0;
+
+	dev_dbg(dev, "%s, link mask = 0x%x\n", __func__, link_mask);
+
+	for (link_idx = 0; link_idx < MAXIM2C_LINK_ID_MAX; link_idx++) {
+		link_cfg = &gmsl_link->link_cfg[link_idx];
+		if (link_cfg->link_enable == 0)
+			continue;
+
+		if (link_cfg->link_type == MAXIM2C_GMSL1) {
+			// GMSL1 Link forward and reverse control channel
+			reg_mask = BIT(1) | BIT(0);
+
+			if (link_mask & BIT(link_idx))
+				// GMSL1: Enable control channel transmitter
+				reg_value = BIT(1) | BIT(0);
+			else
+				// GMSL1: Disable control channel transmitter
+				reg_value = 0;
+
+			reg_addr = 0x0B04 + 0x100 * link_idx;
+			ret |= maxim2c_i2c_update_byte(client,
+					reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS,
+					reg_mask, reg_value);
+		} else {
+			// GMSL2 Link remote control channel
+			if (link_idx == MAXIM2C_LINK_ID_A) {
+				reg_addr = 0x0001;
+				reg_mask = BIT(4);
+
+				if (link_mask & BIT(link_idx))
+					reg_value = 0;
+				else
+					reg_value = BIT(4); // Link A remote control channel disabled
+				ret |= maxim2c_i2c_update_byte(client,
+						reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS,
+						reg_mask, reg_value);
+			} else {
+				reg_addr = 0x0003;
+				reg_mask = BIT(2);
+				if (link_mask & BIT(link_idx))
+					reg_value = 0;
+				else
+					reg_value = BIT(2); // Link B remote control channel disabled
+				ret |= maxim2c_i2c_update_byte(client,
+						reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS,
+						reg_mask, reg_value);
+			}
+		}
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_link_select_remote_control);
+
+static int maxim2c_gmsl_link_config_parse_dt(struct device *dev,
+			maxim2c_gmsl_link_t *gmsl_link,
+			struct device_node *parent_node)
+{
+	struct device_node *node = NULL;
+	struct device_node *init_seq_node = NULL;
+	struct maxim2c_i2c_init_seq *init_seq = NULL;
+	struct maxim2c_link_cfg *link_cfg = NULL;
+	const char *link_cfg_name = "gmsl-link-config";
+	u32 value = 0;
+	u32 sub_idx = 0, link_id = 0;
+	int ret = 0;
+
+	node = NULL;
+	sub_idx = 0;
+	while ((node = of_get_next_child(parent_node, node))) {
+		if (!strncasecmp(node->name,
+				 link_cfg_name,
+				 strlen(link_cfg_name))) {
+			if (sub_idx >= MAXIM2C_LINK_ID_MAX) {
+				dev_err(dev, "%pOF: Too many matching %s node\n",
+						parent_node, link_cfg_name);
+
+				of_node_put(node);
+				break;
+			}
+
+			if (!of_device_is_available(node)) {
+				dev_info(dev, "%pOF is disabled\n", node);
+
+				sub_idx++;
+
+				continue;
+			}
+
+			/* GMSL LINK: link id */
+			ret = of_property_read_u32(node, "link-id", &link_id);
+			if (ret) {
+				// if link_id is error, parse next node
+				dev_err(dev, "Can not get link-id property!");
+
+				sub_idx++;
+
+				continue;
+			}
+			if (link_id >= MAXIM2C_LINK_ID_MAX) {
+				// if link_id is error, parse next node
+				dev_err(dev, "Error link-id = %d!", link_id);
+
+				sub_idx++;
+
+				continue;
+			}
+
+			link_cfg = &gmsl_link->link_cfg[link_id];
+
+			/* GMSL LINK: link enable */
+			link_cfg->link_enable = 1;
+
+			dev_info(dev, "gmsl link id = %d: link_enable = %d\n",
+					link_id, link_cfg->link_enable);
+
+			/* GMSL LINK: other config */
+			ret = of_property_read_u32(node, "link-type", &value);
+			if (ret == 0) {
+				dev_info(dev, "link-type property: %d", value);
+				link_cfg->link_type = value;
+			}
+
+			ret = of_property_read_u32(node, "link-rx-rate", &value);
+			if (ret == 0) {
+				dev_info(dev, "link-rx-rate property: %d", value);
+				link_cfg->link_rx_rate = value;
+			}
+
+			/* link init sequence */
+			init_seq_node = of_get_child_by_name(node, "link-init-sequence");
+			if (!IS_ERR_OR_NULL(init_seq_node)) {
+				dev_info(dev, "load pipe-init-sequence\n");
+
+				init_seq = &link_cfg->link_init_seq;
+				maxim2c_i2c_load_init_seq(dev,
+						init_seq_node, init_seq);
+
+				of_node_put(init_seq_node);
+			}
+
+			sub_idx++;
+		}
+	}
+
+	return 0;
+}
+
+int maxim2c_link_parse_dt(maxim2c_t *maxim2c, struct device_node *of_node)
+{
+	struct device *dev = &maxim2c->client->dev;
+	struct device_node *node = NULL;
+	maxim2c_gmsl_link_t *gmsl_link = &maxim2c->gmsl_link;
+	u32 value = 0;
+	int ret = 0;
+
+	dev_info(dev, "=== maxim2c link parse dt ===\n");
+
+	node = of_get_child_by_name(of_node, "gmsl-links");
+	if (IS_ERR_OR_NULL(node)) {
+		dev_err(dev, "%pOF has no child node: gmsl-links\n",
+				of_node);
+		return -ENODEV;
+	}
+
+	if (!of_device_is_available(node)) {
+		dev_info(dev, "%pOF is disabled\n", node);
+		of_node_put(node);
+		return -ENODEV;
+	}
+
+	/* vdd 1.2v ldo1 enable */
+	ret = of_property_read_u32(node, "link-vdd-ldo1-en", &value);
+	if (ret == 0) {
+		dev_info(dev, "link-vdd-ldo1-en property: %d\n", value);
+		gmsl_link->link_vdd_ldo1_en = value;
+	}
+
+	ret = maxim2c_gmsl_link_config_parse_dt(dev, gmsl_link, node);
+
+	of_node_put(node);
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_link_parse_dt);
+
+int maxim2c_link_hw_init(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	maxim2c_gmsl_link_t *gmsl_link = &maxim2c->gmsl_link;
+	int ret = 0;
+
+	// All links disable at beginning.
+	ret = maxim2c_link_status_init(maxim2c);
+	if (ret) {
+		dev_err(dev, "%s: link status error\n", __func__);
+		return ret;
+	}
+
+	if (gmsl_link->link_vdd_ldo1_en)
+		ret |= maxim2c_link_enable_vdd_ldo1(maxim2c);
+	if (ret) {
+		dev_err(dev, "%s: link vdd ldo enable error\n", __func__);
+		return ret;
+	}
+
+	// Link Rate Setting
+	ret = maxim2c_link_set_rate(maxim2c);
+	if (ret) {
+		dev_err(dev, "%s: link set rate error\n", __func__);
+		return ret;
+	}
+
+	// link init sequence
+	ret = maxim2c_link_run_init_seq(maxim2c);
+	if (ret) {
+		dev_err(dev, "%s: link run init seq error\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_link_hw_init);
+
+void maxim2c_link_data_init(maxim2c_t *maxim2c)
+{
+	maxim2c_gmsl_link_t *gmsl_link = &maxim2c->gmsl_link;
+	struct maxim2c_link_cfg *link_cfg = NULL;
+	int i = 0;
+
+	gmsl_link->link_vdd_ldo1_en = 0;
+
+	for (i = 0; i < MAXIM2C_LINK_ID_MAX; i++) {
+		link_cfg = &gmsl_link->link_cfg[i];
+
+		link_cfg->link_enable = 0;
+		link_cfg->link_type = MAXIM2C_GMSL2;
+		link_cfg->link_tx_rate = MAXIM2C_LINK_TX_RATE_187_5MPS;
+		link_cfg->link_init_seq.reg_init_seq = NULL;
+	}
+}
+EXPORT_SYMBOL(maxim2c_link_data_init);
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_link.h b/kernel/drivers/media/i2c/maxim2c/maxim2c_link.h
new file mode 100644
index 0000000..3708ee9
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_link.h
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+#ifndef __MAXIM2C_LINK_H__
+#define __MAXIM2C_LINK_H__
+
+#include "maxim2c_i2c.h"
+
+/* Link cable */
+enum maxim2c_link_cable {
+	MAXIM2C_CABLE_COAX = 0,
+	MAXIM2C_CABLE_STP,
+};
+
+/* Link Type */
+enum maxim2c_link_type {
+	MAXIM2C_GMSL1 = 0,
+	MAXIM2C_GMSL2,
+};
+
+/* Link Mode */
+enum maxim2c_link_mode {
+	MAXIM2C_GMSL_PIXEL = 0,
+	MAXIM2C_GMSL_TUNNEL,
+};
+
+/* I2C Remote Control Port */
+enum {
+	MAXIM2C_I2C_PORT0 = 0,
+	MAXIM2C_I2C_PORT1,
+	MAXIM2C_I2C_PORT2,
+	MAXIM2C_I2C_PORT_MAX,
+};
+
+/* Link SIO ID: 0 ~ 3 */
+enum {
+	MAXIM2C_LINK_ID_A = 0,
+	MAXIM2C_LINK_ID_B,
+	MAXIM2C_LINK_ID_MAX,
+};
+
+/* Link Bit Mask: bit0 ~ bit3 */
+#define MAXIM2C_LINK_MASK_A		BIT(MAXIM2C_LINK_ID_A)
+#define MAXIM2C_LINK_MASK_B		BIT(MAXIM2C_LINK_ID_B)
+
+#define MAXIM2C_LINK_MASK_ALL		GENMASK(MAXIM2C_LINK_ID_B, MAXIM2C_LINK_ID_A)
+
+/* Link Receiver Rate */
+enum maxim2c_link_rx_rate {
+	MAXIM2C_LINK_RX_RATE_3GBPS = 0,
+	MAXIM2C_LINK_RX_RATE_6GBPS,
+};
+
+/* Link Transmitter Rate */
+enum maxim2c_link_tx_rate {
+	MAXIM2C_LINK_TX_RATE_187_5MPS = 0,
+};
+
+struct maxim2c_link_cfg {
+	u8 link_enable;
+	u8 link_type;
+	u8 link_rx_rate;
+	u8 link_tx_rate;
+
+	struct maxim2c_i2c_init_seq link_init_seq;
+};
+
+typedef struct maxim2c_gmsl_link {
+	u8 link_enable_mask;
+	u8 link_type_mask;
+	u8 link_locked_mask;
+	u8 link_vdd_ldo1_en;
+
+	struct maxim2c_link_cfg link_cfg[MAXIM2C_LINK_ID_MAX];
+} maxim2c_gmsl_link_t;
+
+#endif /* __MAXIM2C_LINK_H__ */
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.c b/kernel/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.c
new file mode 100644
index 0000000..fd21497
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.c
@@ -0,0 +1,592 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim Dual GMSL Deserializer MIPI txphy driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * Author: Cai Wenzhong <cwz@rock-chips.com>
+ *
+ */
+#include <linux/iopoll.h>
+
+#include "maxim2c_api.h"
+
+static int maxim2c_txphy_auto_init_deskew(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	maxim2c_mipi_txphy_t *mipi_txphy = &maxim2c->mipi_txphy;
+	struct maxim2c_txphy_cfg *phy_cfg = NULL;
+	u16 reg_addr = 0;
+	u8 phy_idx = 0;
+	int ret = 0;
+
+	// D-PHY Deskew Initial Calibration Control
+	for (phy_idx = 0; phy_idx < MAXIM2C_TXPHY_ID_MAX; phy_idx++) {
+		// Auto Deskew can only be configured on PHY1 and PHY2
+		if ((phy_idx == MAXIM2C_TXPHY_ID_A) || (phy_idx == MAXIM2C_TXPHY_ID_D))
+			continue;
+
+		phy_cfg = &mipi_txphy->phy_cfg[phy_idx];
+		if (phy_cfg->phy_enable && (phy_cfg->auto_deskew & BIT(7))) {
+			reg_addr = 0x0403 + 0x40 * phy_idx;
+			ret |= maxim2c_i2c_write_byte(client,
+					reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS,
+					phy_cfg->auto_deskew);
+		}
+	}
+
+	return ret;
+}
+
+static int maxim2c_mipi_txphy_lane_mapping(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	maxim2c_mipi_txphy_t *mipi_txphy = &maxim2c->mipi_txphy;
+	struct maxim2c_txphy_cfg *phy_cfg = NULL;
+	u8 reg_value = 0, reg_mask = 0;
+	int ret = 0;
+
+	// MIPI TXPHY A/B: data lane mapping
+	reg_mask = 0;
+	reg_value = 0;
+	phy_cfg = &mipi_txphy->phy_cfg[MAXIM2C_TXPHY_ID_A];
+	if (phy_cfg->phy_enable) {
+		reg_mask |= 0x0F;
+		reg_value |= (phy_cfg->data_lane_map << 0);
+	}
+	phy_cfg = &mipi_txphy->phy_cfg[MAXIM2C_TXPHY_ID_B];
+	if (phy_cfg->phy_enable) {
+		reg_mask |= 0xF0;
+		reg_value |= (phy_cfg->data_lane_map << 4);
+	}
+	if (reg_mask != 0) {
+		ret |= maxim2c_i2c_update_byte(client,
+				0x0333, MAXIM2C_I2C_REG_ADDR_16BITS,
+				reg_mask, reg_value);
+	}
+
+	// MIPI TXPHY C/D: data lane mapping
+	reg_mask = 0;
+	reg_value = 0;
+	phy_cfg = &mipi_txphy->phy_cfg[MAXIM2C_TXPHY_ID_C];
+	if (phy_cfg->phy_enable) {
+		reg_mask |= 0x0F;
+		reg_value |= (phy_cfg->data_lane_map << 0);
+	}
+	phy_cfg = &mipi_txphy->phy_cfg[MAXIM2C_TXPHY_ID_D];
+	if (phy_cfg->phy_enable) {
+		reg_mask |= 0xF0;
+		reg_value |= (phy_cfg->data_lane_map << 4);
+	}
+	if (reg_mask != 0) {
+		ret |= maxim2c_i2c_update_byte(client,
+				0x0334, MAXIM2C_I2C_REG_ADDR_16BITS,
+				reg_mask, reg_value);
+	}
+
+	return ret;
+}
+
+static int maxim2c_mipi_txphy_type_vcx_lane_num(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	maxim2c_mipi_txphy_t *mipi_txphy = &maxim2c->mipi_txphy;
+	struct maxim2c_txphy_cfg *phy_cfg = NULL;
+	u8 phy_idx = 0;
+	u8 reg_mask = 0, reg_value = 0;
+	u16 reg_addr = 0;
+	int ret = 0;
+
+	for (phy_idx = 0; phy_idx < MAXIM2C_TXPHY_ID_MAX; phy_idx++) {
+		phy_cfg = &mipi_txphy->phy_cfg[phy_idx];
+		if (phy_cfg->phy_enable == 0)
+			continue;
+
+		reg_mask = BIT(7) | BIT(6) | BIT(5) | BIT(3);
+		reg_value = 0;
+
+		if (phy_cfg->phy_type == MAXIM2C_TXPHY_TYPE_CPHY)
+			reg_value |= BIT(5);
+
+		if (phy_cfg->vc_ext_en)
+			reg_value |= BIT(3);
+
+		reg_value |= ((phy_cfg->data_lane_num - 1) << 6);
+
+		reg_addr = 0x040A + 0x40 * phy_idx;
+		ret |= maxim2c_i2c_update_byte(client,
+				reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS,
+				reg_mask, reg_value);
+	}
+
+	return ret;
+}
+
+static int maxim2c_mipi_txphy_tunnel_init(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	maxim2c_mipi_txphy_t *mipi_txphy = &maxim2c->mipi_txphy;
+	struct maxim2c_txphy_cfg *phy_cfg = NULL;
+	u8 phy_idx = 0;
+	u8 reg_mask = 0, reg_value = 0;
+	u16 reg_addr = 0;
+	int ret = 0;
+
+	for (phy_idx = 0; phy_idx < MAXIM2C_TXPHY_ID_MAX; phy_idx++) {
+		// Tunnel mode can only be configured on PHY1 and PHY2
+		if ((phy_idx == MAXIM2C_TXPHY_ID_A) || (phy_idx == MAXIM2C_TXPHY_ID_D))
+			continue;
+
+		phy_cfg = &mipi_txphy->phy_cfg[phy_idx];
+		if (phy_cfg->tunnel_enable) {
+			// tunnel mode: enable
+			reg_mask = BIT(0);
+			reg_value = BIT(0);
+
+			// tunnel pipe destination
+			reg_mask |= BIT(1);
+			reg_value |= ((phy_cfg->tunnel_dest & 0x1) << 1);
+		} else {
+			// tunnel mode: disable
+			reg_mask = BIT(0);
+			reg_value = 0;
+		}
+
+		reg_addr = 0x0434 + 0x40 * phy_idx;
+		ret |= maxim2c_i2c_update_byte(client,
+				reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS,
+				reg_mask, reg_value);
+
+		if (phy_cfg->tunnel_enable) {
+			reg_addr = 0x0433 + 0x40 * phy_idx;
+			reg_mask = (BIT(7) | BIT(6) | BIT(5));
+			reg_value = ((phy_cfg->tunnel_vs_wait & 0x07) << 5);
+
+			ret |= maxim2c_i2c_update_byte(client,
+					reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS,
+					reg_mask, reg_value);
+		}
+	}
+
+	return ret;
+}
+
+int maxim2c_mipi_txphy_enable(maxim2c_t *maxim2c, bool enable)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	maxim2c_mipi_txphy_t *mipi_txphy = &maxim2c->mipi_txphy;
+	u8 phy_idx = 0;
+	u8 reg_mask = 0, reg_value = 0;
+	int ret = 0;
+
+	dev_dbg(dev, "%s: enable = %d\n", __func__, enable);
+
+	reg_mask = 0xF0;
+	reg_value = 0;
+
+	if (enable) {
+		for (phy_idx = 0; phy_idx < MAXIM2C_TXPHY_ID_MAX; phy_idx++) {
+			if (mipi_txphy->phy_cfg[phy_idx].phy_enable)
+				reg_value |= BIT(4 + phy_idx);
+		}
+	}
+
+	ret |= maxim2c_i2c_update_byte(client,
+			0x0332, MAXIM2C_I2C_REG_ADDR_16BITS,
+			reg_mask, reg_value);
+
+	return ret;
+}
+
+int maxim2c_dphy_dpll_predef_set(maxim2c_t *maxim2c, s64 link_freq_hz)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	maxim2c_mipi_txphy_t *mipi_txphy = &maxim2c->mipi_txphy;
+	struct maxim2c_txphy_cfg *phy_cfg = NULL;
+	u32 link_freq_mhz = 0;
+	u16 reg_addr = 0;
+	u8 phy_idx = 0;
+	u8 dpll_mask = 0, dpll_val = 0, dpll_lock = 0;
+	int ret = 0;
+
+	dpll_mask = 0;
+
+	link_freq_mhz = (u32)div_s64(link_freq_hz, 1000000L);
+	dpll_val = DIV_ROUND_UP(link_freq_mhz * 2, 100) & 0x1F;
+	if (dpll_val == 0)
+		dpll_val = 15; /* default 1500MBps */
+	// Disable software override for frequency fine tuning
+	dpll_val |= BIT(5);
+
+	for (phy_idx = 0; phy_idx < MAXIM2C_TXPHY_ID_MAX; phy_idx++) {
+		phy_cfg = &mipi_txphy->phy_cfg[phy_idx];
+		if ((phy_cfg->phy_enable == 0) || (phy_cfg->clock_master == 0))
+			continue;
+
+		if (phy_cfg->clock_mode != MAXIM2C_TXPHY_DPLL_PREDEF)
+			continue;
+
+		dpll_mask |= BIT(phy_idx + 4);
+
+		// Hold DPLL in reset (config_soft_rst_n = 0) before changing the rate
+		reg_addr = 0x1C00 + 0x100 * phy_idx;
+		ret |= maxim2c_i2c_write_byte(client,
+				reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS,
+				0xf4);
+
+		// Set dpll data rate
+		reg_addr = 0x031D + 0x03 * phy_idx;
+		ret |= maxim2c_i2c_update_byte(client,
+				reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS,
+				0x3F, dpll_val);
+
+		// Release reset to DPLL (config_soft_rst_n = 1)
+		reg_addr = 0x1C00 + 0x100 * phy_idx;
+		ret |= maxim2c_i2c_write_byte(client,
+				reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS,
+				0xf5);
+	}
+
+	if (ret) {
+		dev_err(dev, "DPLL predef set error!\n");
+		return ret;
+	}
+
+#if 0
+	ret = read_poll_timeout(maxim2c_i2c_read_byte, ret,
+				!(ret < 0) && (dpll_lock & dpll_mask),
+				1000, 10000, false,
+				client,
+				0x0308, MAXIM2C_I2C_REG_ADDR_16BITS,
+				&dpll_lock);
+	if (ret < 0) {
+		dev_err(dev, "DPLL is unlocked: 0x%02x\n", dpll_lock);
+		return ret;
+	} else {
+		dev_info(dev, "DPLL is locked: 0x%02x\n", dpll_lock);
+		return 0;
+	}
+#else
+	// The locking status of DPLL cannot be obtained before csi output
+	usleep_range(1000, 1100);
+	ret = maxim2c_i2c_read_byte(client,
+				0x0308, MAXIM2C_I2C_REG_ADDR_16BITS,
+				&dpll_lock);
+	dev_info(dev, "DPLL lock state: 0x%02x\n", dpll_lock);
+
+	return ret;
+#endif
+}
+EXPORT_SYMBOL(maxim2c_dphy_dpll_predef_set);
+
+int maxim2c_mipi_csi_output(maxim2c_t *maxim2c, bool enable)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	maxim2c_mipi_txphy_t *mipi_txphy = &maxim2c->mipi_txphy;
+	u8 reg_mask = 0, reg_value = 0;
+	int ret = 0;
+
+	dev_dbg(dev, "%s: enable = %d\n", __func__, enable);
+
+	if (mipi_txphy->force_clock_out_en != 0) {
+		reg_mask = BIT(7);
+		reg_value = enable ? BIT(7) : 0;
+
+		// Force all MIPI clocks running Config
+		ret |= maxim2c_i2c_update_byte(client,
+				0x0330, MAXIM2C_I2C_REG_ADDR_16BITS,
+				reg_mask, reg_value);
+	}
+
+	/* Bit1 of the register 0x0313: CSI_OUT_EN
+	 *     1 = CSI output enabled
+	 *     0 = CSI output disabled
+	 */
+	reg_mask = BIT(1);
+	reg_value = enable ? BIT(1) : 0;
+
+	// MIPI CSI output Setting
+	ret |= maxim2c_i2c_update_byte(client,
+			0x0313, MAXIM2C_I2C_REG_ADDR_16BITS,
+			reg_mask, reg_value);
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_mipi_csi_output);
+
+static int maxim2c_mipi_txphy_config_parse_dt(struct device *dev,
+				maxim2c_mipi_txphy_t *mipi_txphy,
+				struct device_node *parent_node)
+{
+	struct device_node *node = NULL;
+	struct maxim2c_txphy_cfg *phy_cfg = NULL;
+	const char *txphy_cfg_name = "mipi-txphy-config";
+	u32 value = 0;
+	u32 sub_idx = 0, phy_id = 0;
+	int ret;
+
+	node = NULL;
+	sub_idx = 0;
+	while ((node = of_get_next_child(parent_node, node))) {
+		if (!strncasecmp(node->name,
+				 txphy_cfg_name,
+				 strlen(txphy_cfg_name))) {
+			if (sub_idx >= MAXIM2C_TXPHY_ID_MAX) {
+				dev_err(dev, "%pOF: Too many matching %s node\n",
+						parent_node, txphy_cfg_name);
+
+				of_node_put(node);
+				break;
+			}
+
+			if (!of_device_is_available(node)) {
+				dev_info(dev, "%pOF is disabled\n", node);
+
+				sub_idx++;
+
+				continue;
+			}
+
+			/* MIPI TXPHY: phy id */
+			ret = of_property_read_u32(node, "phy-id", &phy_id);
+			if (ret) {
+				// if mipi txphy phy_id is error, parse next node
+				dev_err(dev, "Can not get phy-id property!");
+
+				sub_idx++;
+
+				continue;
+			}
+			if (phy_id >= MAXIM2C_TXPHY_ID_MAX) {
+				// if mipi txphy phy_id is error, parse next node
+				dev_err(dev, "Error phy-id = %d!", phy_id);
+
+				sub_idx++;
+
+				continue;
+			}
+
+			phy_cfg = &mipi_txphy->phy_cfg[phy_id];
+
+			/* MIPI TXPHY: phy enable */
+			phy_cfg->phy_enable = 1;
+
+			dev_info(dev, "mipi txphy id = %d: phy_enable = %d\n",
+					phy_id, phy_cfg->phy_enable);
+
+			/* MIPI TXPHY: other config */
+			ret = of_property_read_u32(node, "phy-type", &value);
+			if (ret == 0) {
+				dev_info(dev, "phy-type property: %d", value);
+				phy_cfg->phy_type = value;
+			}
+
+			ret = of_property_read_u32(node, "auto-deskew", &value);
+			if (ret == 0) {
+				dev_info(dev, "auto-deskew property: 0x%x", value);
+				phy_cfg->auto_deskew = value;
+			}
+
+			ret = of_property_read_u32(node, "data-lane-num", &value);
+			if (ret == 0) {
+				dev_info(dev, "data-lane-num property: %d", value);
+				phy_cfg->data_lane_num = value;
+			}
+
+			ret = of_property_read_u32(node, "data-lane-map", &value);
+			if (ret == 0) {
+				dev_info(dev, "data-lane-map property: 0x%x", value);
+				phy_cfg->data_lane_map = value;
+			}
+
+			ret = of_property_read_u32(node, "vc-ext-en", &value);
+			if (ret == 0) {
+				dev_info(dev, "vc-ext-en property: %d", value);
+				phy_cfg->vc_ext_en = value;
+			}
+
+			ret = of_property_read_u32(node, "tunnel-enable", &value);
+			if (ret == 0) {
+				dev_info(dev, "tunnel-enable property: %d", value);
+				phy_cfg->tunnel_enable = value;
+			}
+
+			ret = of_property_read_u32(node, "tunnel-vs-wait", &value);
+			if (ret == 0) {
+				dev_info(dev, "tunnel-vs-wait property: %d", value);
+				phy_cfg->tunnel_vs_wait = value;
+			}
+
+			ret = of_property_read_u32(node, "tunnel-dest", &value);
+			if (ret == 0) {
+				dev_info(dev, "tunnel-dest property: %d", value);
+				phy_cfg->tunnel_dest = value;
+			}
+
+			ret = of_property_read_u32(node, "clock-mode", &value);
+			if (ret == 0) {
+				dev_info(dev, "clock-mode property: %d", value);
+				phy_cfg->clock_mode = value;
+			}
+
+			sub_idx++;
+		}
+	}
+
+	return 0;
+}
+
+int maxim2c_mipi_txphy_parse_dt(maxim2c_t *maxim2c, struct device_node *of_node)
+{
+	struct device *dev = &maxim2c->client->dev;
+	struct device_node *node = NULL;
+	maxim2c_mipi_txphy_t *mipi_txphy = &maxim2c->mipi_txphy;
+	u32 value = 0;
+	int ret = 0;
+
+	dev_info(dev, "=== maxim2c mipi txphy parse dt ===\n");
+
+	node = of_get_child_by_name(of_node, "mipi-txphys");
+	if (IS_ERR_OR_NULL(node)) {
+		dev_err(dev, "%pOF has no child node: mipi-txphys\n",
+				of_node);
+		return -ENODEV;
+	}
+
+	if (!of_device_is_available(node)) {
+		dev_info(dev, "%pOF is disabled\n", node);
+		of_node_put(node);
+		return -ENODEV;
+	}
+
+	/* mipi txphy mode */
+	ret = of_property_read_u32(node, "phy-mode", &value);
+	if (ret == 0) {
+		dev_info(dev, "phy-mode property: %d\n", value);
+		mipi_txphy->phy_mode = value;
+	}
+	dev_info(dev, "mipi txphy mode: %d\n", mipi_txphy->phy_mode);
+
+	/* MIPI clocks running mode */
+	ret = of_property_read_u32(node, "phy-force-clock-out", &value);
+	if (ret == 0) {
+		dev_info(dev, "phy-force-clock-out property: %d\n", value);
+		mipi_txphy->force_clock_out_en = value;
+	}
+	dev_info(dev, "mipi txphy force clock out enable: %d\n",
+			mipi_txphy->force_clock_out_en);
+
+	ret = maxim2c_mipi_txphy_config_parse_dt(dev, mipi_txphy, node);
+
+	of_node_put(node);
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_mipi_txphy_parse_dt);
+
+int maxim2c_mipi_txphy_hw_init(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	maxim2c_mipi_txphy_t *mipi_txphy = &maxim2c->mipi_txphy;
+	struct maxim2c_txphy_cfg *phy_cfg = NULL;
+	u8 mode = 0;
+	int ret = 0;
+
+	switch (mipi_txphy->phy_mode) {
+	case MAXIM2C_TXPHY_MODE_2X2LANES:
+		mode = BIT(0);
+		break;
+	case MAXIM2C_TXPHY_MODE_2X4LANES:
+	default:
+		mode = BIT(2);
+		break;
+	}
+
+	// clock master
+	phy_cfg = &mipi_txphy->phy_cfg[MAXIM2C_TXPHY_ID_B];
+	if (phy_cfg->phy_enable) {
+		if (phy_cfg->tunnel_enable) {
+			if (phy_cfg->tunnel_dest == 0) {
+				phy_cfg->clock_master = 1;
+			} else {
+				phy_cfg->phy_enable = 0;
+				phy_cfg->clock_master = 0;
+			}
+		} else {
+			phy_cfg->clock_master = 1;
+		}
+	}
+
+	phy_cfg = &mipi_txphy->phy_cfg[MAXIM2C_TXPHY_ID_C];
+	if (phy_cfg->phy_enable) {
+		if (phy_cfg->tunnel_enable) {
+			if (phy_cfg->tunnel_dest == 1) {
+				phy_cfg->clock_master = 1;
+			} else {
+				phy_cfg->phy_enable = 0;
+				phy_cfg->clock_master = 0;
+			}
+		} else {
+			phy_cfg->clock_master = 1;
+		}
+	}
+
+	// MIPI TXPHY Mode setting
+	ret |= maxim2c_i2c_write_byte(client,
+			0x0330, MAXIM2C_I2C_REG_ADDR_16BITS,
+			mode);
+
+	// Waits for a frame before generating MIPI Packet requests to the MIPI TX
+	ret |= maxim2c_i2c_update_byte(client,
+			0x0325, MAXIM2C_I2C_REG_ADDR_16BITS,
+			BIT(7), BIT(7));
+
+	// mipi txphy data lane mapping
+	ret |= maxim2c_mipi_txphy_lane_mapping(maxim2c);
+
+	// mipi txphy type, lane number, virtual channel extension
+	ret |= maxim2c_mipi_txphy_type_vcx_lane_num(maxim2c);
+
+	// mipi txphy tunnel init
+	ret |= maxim2c_mipi_txphy_tunnel_init(maxim2c);
+
+	// mipi txphy auto init deskew
+	ret |= maxim2c_txphy_auto_init_deskew(maxim2c);
+
+	if (ret) {
+		dev_err(dev, "%s: txphy hw init error\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_mipi_txphy_hw_init);
+
+void maxim2c_mipi_txphy_data_init(maxim2c_t *maxim2c)
+{
+	maxim2c_mipi_txphy_t *mipi_txphy = &maxim2c->mipi_txphy;
+	struct maxim2c_txphy_cfg *phy_cfg = NULL;
+	int i = 0;
+
+	mipi_txphy->phy_mode = MAXIM2C_TXPHY_MODE_2X4LANES;
+	mipi_txphy->force_clock_out_en = 1;
+
+	for (i = 0; i < MAXIM2C_TXPHY_ID_MAX; i++) {
+		phy_cfg = &mipi_txphy->phy_cfg[i];
+
+		phy_cfg->phy_enable = 0;
+		phy_cfg->phy_type = MAXIM2C_TXPHY_TYPE_DPHY;
+		phy_cfg->auto_deskew = 0;
+		phy_cfg->data_lane_num = 4;
+		phy_cfg->data_lane_map = 0xe4;
+		phy_cfg->vc_ext_en = 0;
+		phy_cfg->tunnel_enable = 0;
+		phy_cfg->clock_master = 0;
+		phy_cfg->clock_mode = MAXIM2C_TXPHY_DPLL_PREDEF;
+	}
+}
+EXPORT_SYMBOL(maxim2c_mipi_txphy_data_init);
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.h b/kernel/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.h
new file mode 100644
index 0000000..5e2ae46
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+#ifndef __MAXIM2C_MIPI_TXPHY_H__
+#define __MAXIM2C_MIPI_TXPHY_H__
+
+/* MIPI TXPHY ID: 0 ~ 3 */
+enum {
+	MAXIM2C_TXPHY_ID_A = 0,
+	MAXIM2C_TXPHY_ID_B,
+	MAXIM2C_TXPHY_ID_C,
+	MAXIM2C_TXPHY_ID_D,
+	MAXIM2C_TXPHY_ID_MAX,
+};
+
+/* MIPI TXPHY Bit Mask: bit0 ~ bit3 */
+#define MAXIM2C_TXPHY_MASK_A		BIT(MAXIM2C_TXPHY_ID_A)
+#define MAXIM2C_TXPHY_MASK_B		BIT(MAXIM2C_TXPHY_ID_B)
+#define MAXIM2C_TXPHY_MASK_C		BIT(MAXIM2C_TXPHY_ID_C)
+#define MAXIM2C_TXPHY_MASK_D		BIT(MAXIM2C_TXPHY_ID_D)
+
+#define MAXIM2C_TXPHY_MASK_ALL		GENMASK(MAXIM2C_TXPHY_ID_D, MAXIM2C_TXPHY_ID_A)
+
+/* MIPI TXPHY Type */
+enum {
+	MAXIM2C_TXPHY_TYPE_DPHY = 0,
+	MAXIM2C_TXPHY_TYPE_CPHY,
+};
+
+/* MIPI TXPHY Mode */
+enum {
+	MAXIM2C_TXPHY_MODE_2X4LANES = 0, /* PortA: 1x4Lanes, PortB: 1x4Lanes */
+	MAXIM2C_TXPHY_MODE_2X2LANES, /* PortA: 2Lanes, PortB: 2Lanes */
+};
+
+/* MIPI TXPHY DPLL */
+enum {
+	MAXIM2C_TXPHY_DPLL_PREDEF = 0,
+	MAXIM2C_TXPHY_DPLL_FINE_TUNING,
+};
+
+struct maxim2c_txphy_cfg {
+	u8 phy_enable;
+	u8 phy_type;
+	u8 auto_deskew;
+	u8 data_lane_num;
+	u8 data_lane_map;
+	u8 vc_ext_en;
+	u8 tunnel_enable;
+	u8 tunnel_vs_wait;
+	u8 tunnel_dest;
+	u8 clock_master;
+	u8 clock_mode;
+};
+
+typedef struct maxim2c_mipi_txphy {
+	u8 phy_mode; /* mipi txphy mode */
+	u8 force_clock_out_en; /* Force all MIPI clocks running */
+
+	struct maxim2c_txphy_cfg phy_cfg[MAXIM2C_TXPHY_ID_MAX];
+} maxim2c_mipi_txphy_t;
+
+#endif /* __MAXIM2C_MIPI_TXPHY_H__ */
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_pattern.c b/kernel/drivers/media/i2c/maxim2c/maxim2c_pattern.c
new file mode 100644
index 0000000..06f70f3
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_pattern.c
@@ -0,0 +1,351 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim Dual GMSL Deserializer Test Pattern Driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * Author: Cai Wenzhong <cwz@rock-chips.com>
+ *
+ */
+#include "maxim2c_api.h"
+
+#define PATTERN_WIDTH		1920
+#define PATTERN_HEIGHT		1080
+
+/* pattern mode: checkerboard or gradient */
+enum {
+	PATTERN_CHECKERBOARD = 0,
+	PATTERN_GRADIENT,
+};
+
+/* pattern pclk: 25M or 75M 0r 150M or 600M */
+enum {
+	PATTERN_PCLK_25M = 0,
+	PATTERN_PCLK_75M,
+	PATTERN_PCLK_150M,
+	PATTERN_PCLK_600M,
+};
+
+static const struct maxim2c_mode maxim2c_pattern_mode = {
+	.width = PATTERN_WIDTH,
+	.height = PATTERN_HEIGHT,
+	.max_fps = {
+		.numerator = 10000,
+		.denominator = 300000,
+	},
+	.link_freq_idx = 24,
+	.bus_fmt = MEDIA_BUS_FMT_RGB888_1X24,
+	.bpp = 24,
+	.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+};
+
+int maxim2c_pattern_enable(maxim2c_t *maxim2c, bool enable)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	struct maxim2c_pattern *pattern = &maxim2c->pattern;
+	u32 pattern_mode;
+	u8 reg_mask = 0, reg_val = 0;
+	int ret = 0;
+
+	dev_info(dev, "video pattern: enable = %d\n", enable);
+
+	pattern_mode = pattern->pattern_mode;
+
+	reg_mask = BIT(5) | BIT(4);
+	if (pattern_mode == PATTERN_CHECKERBOARD) {
+		/* Generate checkerboard pattern. */
+		reg_val = enable ? BIT(4) : 0;
+	} else {
+		/* Generate gradient pattern. */
+		reg_val = enable ? BIT(5) : 0;
+	}
+	ret = maxim2c_i2c_update_byte(client,
+			0x0241, MAXIM2C_I2C_REG_ADDR_16BITS,
+			reg_mask, reg_val);
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_pattern_enable);
+
+static int maxim2c_pattern_previnit(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	int ret = 0;
+
+	// Disable data transmission through video pipe.
+	ret = maxim2c_i2c_update_byte(client,
+			0x0002, MAXIM2C_I2C_REG_ADDR_16BITS,
+			0xF0, 0x00);
+	if (ret)
+		return ret;
+
+	// video pipe disable.
+	ret = maxim2c_i2c_write_byte(client,
+			0x0160, MAXIM2C_I2C_REG_ADDR_16BITS,
+			0x00);
+	if (ret)
+		return ret;
+
+	// MIPI CSI output disable.
+	ret = maxim2c_i2c_write_byte(client,
+			0x0313, MAXIM2C_I2C_REG_ADDR_16BITS,
+			0x00);
+	if (ret)
+		return ret;
+
+	// MIPI TXPHY standby
+	ret = maxim2c_i2c_update_byte(client,
+			0x0332, MAXIM2C_I2C_REG_ADDR_16BITS,
+			0xF0, 0x00);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int maxim2c_pattern_config(maxim2c_t *maxim2c)
+{
+	const u32 h_active = PATTERN_WIDTH;
+	const u32 h_fp = 88;
+	const u32 h_sw = 44;
+	const u32 h_bp = 148;
+	const u32 h_tot = h_active + h_fp + h_sw + h_bp;
+
+	const u32 v_active = PATTERN_HEIGHT;
+	const u32 v_fp = 4;
+	const u32 v_sw = 5;
+	const u32 v_bp = 36;
+	const u32 v_tot = v_active + v_fp + v_sw + v_bp;
+
+	struct i2c_client *client = maxim2c->client;
+	struct maxim2c_pattern *pattern = &maxim2c->pattern;
+	u32 pattern_mode;
+	u32 pattern_pclk;
+	u16 reg_addr = 0;
+	u8 reg_mask = 0, reg_val = 0;
+	int ret = 0, i = 0;
+
+	pattern_mode = pattern->pattern_mode;
+	pattern_pclk = pattern->pattern_pclk;
+
+	// PATGEN_MODE = 0, Pattern generator disabled
+	//	use video from the serializer input
+	ret |= maxim2c_i2c_update_byte(client,
+			0x0241, MAXIM2C_I2C_REG_ADDR_16BITS,
+			BIT(5) | BIT(4), 0x00);
+
+	/* Pattern PCLK:
+	 *	0b00 - 25MHz
+	 *	0b01 - 75MHz
+	 *	0b1x - (PATGEN_CLK_SRC: 0 - 150MHz, 1 - 600MHz).
+	 */
+	pattern_pclk = (pattern_pclk & 0x03);
+	ret |= maxim2c_i2c_write_byte(client,
+			0x0038, MAXIM2C_I2C_REG_ADDR_16BITS,
+			pattern_pclk);
+	if (pattern_pclk >= PATTERN_PCLK_150M) {
+		reg_mask = BIT(7);
+		if (pattern_pclk == PATTERN_PCLK_600M)
+			reg_val = BIT(7);
+		else
+			reg_val = 0;
+
+		for (i = 0; i < 2; i++) {
+			reg_addr = 0x01FC + i * 0x20;
+			ret |= maxim2c_i2c_update_byte(client,
+					reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS,
+					reg_mask, reg_val);
+		}
+	}
+
+	/* Configure Video Timing Generator for 1920x1080 @ 30 fps. */
+	// VS_DLY = 0
+	ret |= maxim2c_i2c_write_reg(client,
+			0x0242, MAXIM2C_I2C_REG_ADDR_16BITS,
+			MAXIM2C_I2C_REG_VALUE_24BITS, 0x000000);
+	// VS_HIGH = Vsw * Htot
+	ret |= maxim2c_i2c_write_reg(client,
+			0x0245, MAXIM2C_I2C_REG_ADDR_16BITS,
+			MAXIM2C_I2C_REG_VALUE_24BITS, v_sw * h_tot);
+	// VS_LOW = (Vactive + Vfp + Vbp) * Htot
+	ret |= maxim2c_i2c_write_reg(client,
+			0x0248, MAXIM2C_I2C_REG_ADDR_16BITS,
+			MAXIM2C_I2C_REG_VALUE_24BITS, (v_active + v_fp + v_bp) * h_tot);
+	// V2H = VS_DLY
+	ret |= maxim2c_i2c_write_reg(client,
+			0x024B, MAXIM2C_I2C_REG_ADDR_16BITS,
+			MAXIM2C_I2C_REG_VALUE_24BITS, 0x000000);
+	// HS_HIGH = Hsw
+	ret |= maxim2c_i2c_write_reg(client,
+			0x024E, MAXIM2C_I2C_REG_ADDR_16BITS,
+			MAXIM2C_I2C_REG_VALUE_16BITS, h_sw);
+	// HS_LOW = Hactive + Hfp + Hbp
+	ret |= maxim2c_i2c_write_reg(client,
+			0x0250, MAXIM2C_I2C_REG_ADDR_16BITS,
+			MAXIM2C_I2C_REG_VALUE_16BITS, h_active + h_fp + h_bp);
+	// HS_CNT = Vtot
+	ret |= maxim2c_i2c_write_reg(client,
+			0x0252, MAXIM2C_I2C_REG_ADDR_16BITS,
+			MAXIM2C_I2C_REG_VALUE_16BITS, v_tot);
+	// V2D = VS_DLY + Htot * (Vsw + Vbp) + (Hsw + Hbp)
+	ret |= maxim2c_i2c_write_reg(client,
+			0x0254, MAXIM2C_I2C_REG_ADDR_16BITS,
+			MAXIM2C_I2C_REG_VALUE_24BITS, h_tot * (v_sw + v_bp) + (h_sw + h_bp));
+	// DE_HIGH = Hactive
+	ret |= maxim2c_i2c_write_reg(client,
+			0x0257, MAXIM2C_I2C_REG_ADDR_16BITS,
+			MAXIM2C_I2C_REG_VALUE_16BITS, h_active);
+	// DE_LOW = Hfp + Hsw + Hbp
+	ret |= maxim2c_i2c_write_reg(client,
+			0x0259, MAXIM2C_I2C_REG_ADDR_16BITS,
+			MAXIM2C_I2C_REG_VALUE_16BITS, h_fp + h_sw + h_bp);
+	// DE_CNT = Vactive
+	ret |= maxim2c_i2c_write_reg(client,
+			0x025B, MAXIM2C_I2C_REG_ADDR_16BITS,
+			MAXIM2C_I2C_REG_VALUE_16BITS, v_active);
+
+	/* Generate VS, HS and DE in free-running mode, Invert HS and VS. */
+	ret |= maxim2c_i2c_write_byte(client,
+			0x0240, MAXIM2C_I2C_REG_ADDR_16BITS,
+			0xfb);
+
+	/* Configure Video Pattern Generator. */
+	if (pattern_mode == PATTERN_CHECKERBOARD) {
+		/* Set checkerboard pattern size. */
+		ret |= maxim2c_i2c_write_reg(client,
+			0x0264, MAXIM2C_I2C_REG_ADDR_16BITS,
+			MAXIM2C_I2C_REG_VALUE_24BITS, 0x3c3c3c);
+
+		/* Set checkerboard pattern colors. */
+		ret |= maxim2c_i2c_write_reg(client,
+			0x025E, MAXIM2C_I2C_REG_ADDR_16BITS,
+			MAXIM2C_I2C_REG_VALUE_24BITS, 0xfecc00);
+		ret |= maxim2c_i2c_write_reg(client,
+			0x0261, MAXIM2C_I2C_REG_ADDR_16BITS,
+			MAXIM2C_I2C_REG_VALUE_24BITS, 0x006aa7);
+	} else {
+		/* Set gradient increment. */
+		ret |= maxim2c_i2c_write_byte(client,
+				0x025D, MAXIM2C_I2C_REG_ADDR_16BITS,
+				0x10);
+	}
+
+	return ret;
+}
+
+int maxim2c_pattern_support_mode_init(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	struct maxim2c_mode *supported_mode = NULL;
+
+	dev_info(dev, "=== maxim2c pattern support mode init ===\n");
+
+	maxim2c->cfg_modes_num = 1;
+	maxim2c->cur_mode = &maxim2c->supported_mode;
+	supported_mode = &maxim2c->supported_mode;
+
+	// init using def mode
+	memcpy(supported_mode, &maxim2c_pattern_mode, sizeof(struct maxim2c_mode));
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_pattern_support_mode_init);
+
+int maxim2c_pattern_data_init(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	struct device_node *node = NULL;
+	struct maxim2c_mode *supported_mode = NULL;
+	struct maxim2c_pattern *pattern = NULL;
+	maxim2c_mipi_txphy_t *mipi_txphy = &maxim2c->mipi_txphy;
+	int ret = 0;
+
+	// maxim serdes local
+	node = of_get_child_by_name(dev->of_node, "serdes-local-device");
+	if (IS_ERR_OR_NULL(node)) {
+		dev_err(dev, "%pOF has no child node: serdes-local-device\n",
+				dev->of_node);
+		return -ENODEV;
+	}
+
+	if (!of_device_is_available(node)) {
+		dev_info(dev, "%pOF is disabled\n", node);
+
+		of_node_put(node);
+		return -ENODEV;
+	}
+
+	maxim2c_mipi_txphy_data_init(maxim2c);
+
+	/* mipi txphy parse dt */
+	ret = maxim2c_mipi_txphy_parse_dt(maxim2c, node);
+	if (ret) {
+		dev_err(dev, "%s: txphy parse dt error\n", __func__);
+		return ret;
+	}
+
+	// pattern need enable force_clock_out_en
+	dev_info(dev, "Pattern mode force_clock_out_en default enable\n");
+	mipi_txphy->force_clock_out_en = 1;
+
+	// pattern generator and mode init
+	pattern = &maxim2c->pattern;
+	pattern->pattern_mode = PATTERN_CHECKERBOARD;
+	pattern->pattern_pclk = PATTERN_PCLK_75M;
+
+	supported_mode = &maxim2c->supported_mode;
+	switch (pattern->pattern_pclk) {
+	case PATTERN_PCLK_25M:
+		supported_mode->max_fps.denominator = 100000;
+		break;
+	case PATTERN_PCLK_75M:
+		supported_mode->max_fps.denominator = 300000;
+		break;
+	case PATTERN_PCLK_150M:
+		supported_mode->max_fps.denominator = 600000;
+		if (supported_mode->link_freq_idx < 12)
+			dev_warn(dev, "link_freq_idx = %d is too low\n",
+					supported_mode->link_freq_idx);
+		break;
+	case PATTERN_PCLK_600M:
+		supported_mode->max_fps.denominator = 1500000;
+		if (supported_mode->link_freq_idx < 22)
+			dev_warn(dev, "link_freq_idx = %d is too low\n",
+					supported_mode->link_freq_idx);
+		break;
+	}
+
+	dev_info(dev, "video pattern: mode = %d, pclk = %d\n",
+		pattern->pattern_mode, pattern->pattern_pclk);
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_pattern_data_init);
+
+int maxim2c_pattern_hw_init(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	int ret = 0;
+
+	ret = maxim2c_pattern_previnit(maxim2c);
+	if (ret) {
+		dev_err(dev, "%s: pattern previnit error\n", __func__);
+		return ret;
+	}
+
+	ret = maxim2c_mipi_txphy_hw_init(maxim2c);
+	if (ret) {
+		dev_err(dev, "%s: txphy hw init error\n", __func__);
+		return ret;
+	}
+
+	ret = maxim2c_pattern_config(maxim2c);
+	if (ret) {
+		dev_err(dev, "%s: pattern config error\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_pattern_hw_init);
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_pattern.h b/kernel/drivers/media/i2c/maxim2c/maxim2c_pattern.h
new file mode 100644
index 0000000..2ea7b05
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_pattern.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+#ifndef __MAXIM2C_PATTERN_H__
+#define __MAXIM2C_PATTERN_H__
+
+struct maxim2c_pattern {
+	u32 pattern_mode;
+	u32 pattern_pclk;
+};
+
+#endif /* __MAXIM2C_PATTERN_H__ */
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_remote.c b/kernel/drivers/media/i2c/maxim2c/maxim2c_remote.c
new file mode 100644
index 0000000..461c064
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_remote.c
@@ -0,0 +1,434 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim Dual GMSL Deserializer Remode Device Manage
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * Author: Cai Wenzhong <cwz@rock-chips.com>
+ *
+ */
+#include <linux/module.h>
+#include <linux/of_graph.h>
+#include <linux/mfd/core.h>
+#include "maxim2c_api.h"
+
+static const char *maxim2c_remote_devs_name[MAXIM2C_LINK_ID_MAX] = {
+	"remote0", "remote1"
+};
+
+static const char *maxim2c_remote_link_compat[MAXIM2C_LINK_ID_MAX] = {
+	"maxim2c,link0", "maxim2c,link1"
+};
+
+static int maxim2c_remote_dev_info_parse(struct device *dev,
+			struct mfd_cell *remote_mfd_dev, u8 link_id)
+{
+	struct device_node *node = NULL;
+	const char *remote_device_name = "serdes-remote-device";
+	const char *prop_str = NULL, *link_compat = NULL;
+	u32 sub_idx = 0, remote_id = 0;
+	int ret = 0;
+
+	node = NULL;
+	sub_idx = 0;
+	while ((node = of_get_next_child(dev->of_node, node))) {
+		if (!strncasecmp(node->name,
+					remote_device_name,
+					strlen(remote_device_name))) {
+			if (sub_idx >= MAXIM2C_LINK_ID_MAX) {
+				dev_err(dev, "%pOF: Too many matching %s node\n",
+						dev->of_node, remote_device_name);
+
+				of_node_put(node);
+				break;
+			}
+
+			if (!of_device_is_available(node)) {
+				dev_info(dev, "%pOF is disabled\n", node);
+
+				sub_idx++;
+
+				continue;
+			}
+
+			/* remote id */
+			ret = of_property_read_u32(node, "remote-id", &remote_id);
+			if (ret) {
+				sub_idx++;
+
+				continue;
+			}
+			if (remote_id >= MAXIM2C_LINK_ID_MAX) {
+				sub_idx++;
+
+				continue;
+			}
+
+			if (remote_id != link_id) {
+				sub_idx++;
+
+				continue;
+			}
+
+			dev_info(dev, "remote device id = %d\n", remote_id);
+
+			ret = of_property_read_string(node, "compatible", &prop_str);
+			if (ret) {
+				dev_err(dev, "%pOF no compatible error\n", node);
+
+				of_node_put(node);
+				return -EINVAL;
+			}
+
+			link_compat = maxim2c_remote_link_compat[remote_id];
+			if (!strncasecmp(prop_str,
+					link_compat, strlen(link_compat))) {
+				dev_info(dev, "compatible property: %s\n", prop_str);
+
+				remote_mfd_dev->name = maxim2c_remote_devs_name[remote_id];
+				remote_mfd_dev->of_compatible = prop_str;
+
+				of_node_put(node);
+				return 0;
+			}
+
+			dev_err(dev, "%pOF compatible and remote_id mismatch\n", node);
+
+			of_node_put(node);
+			return -EINVAL;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int maxim2c_remote_mfd_devs_init(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	maxim2c_gmsl_link_t *gmsl_link = &maxim2c->gmsl_link;
+	struct mfd_cell *remote_mfd_dev = NULL;
+	int link_idx = 0, nr_mfd_cell = 0;
+	int ret = 0;
+
+	remote_mfd_dev = maxim2c->remote_mfd_devs;
+	nr_mfd_cell = 0;
+	for (link_idx = 0; link_idx < MAXIM2C_LINK_ID_MAX; link_idx++) {
+		remote_mfd_dev->name = NULL;
+		remote_mfd_dev->of_compatible = NULL;
+
+		if (gmsl_link->link_cfg[link_idx].link_enable == 0) {
+			dev_dbg(dev, "%s: link id = %d is disabled\n",
+					__func__, link_idx);
+			continue;
+		}
+
+		ret = maxim2c_remote_dev_info_parse(dev, remote_mfd_dev, link_idx);
+		if (ret == 0) {
+			remote_mfd_dev++;
+			nr_mfd_cell++;
+		}
+	}
+
+	dev_info(dev, "Total number of remote devices is %d", nr_mfd_cell);
+
+	return nr_mfd_cell;
+}
+
+int maxim2c_remote_mfd_add_devices(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	int nr_mfd_cell = 0, ret = 0;
+
+	dev_info(dev, "=== maxim2c add remote devices ===");
+
+	nr_mfd_cell = maxim2c_remote_mfd_devs_init(maxim2c);
+	if (nr_mfd_cell == 0) {
+		dev_err(dev, "%s: remote mfd devices init error\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO,
+			maxim2c->remote_mfd_devs, nr_mfd_cell,
+			NULL, 0, NULL);
+	if (ret)
+		dev_err(dev, "%s: add remote mfd devices error: %d\n",
+				__func__, ret);
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_remote_mfd_add_devices);
+
+int maxim2c_remote_devices_init(maxim2c_t *maxim2c, u8 link_init_mask)
+{
+	struct device *dev = &maxim2c->client->dev;
+	struct maxim2c_remote *remote_device = NULL;
+	const struct maxim2c_remote_ops *remote_ops = NULL;
+	u8 link_mask = 0, link_enable = 0, link_locked = 0;
+	int ret = 0, i = 0;
+
+	dev_dbg(dev, "%s: link init mask = 0x%02x\n", __func__, link_init_mask);
+
+	for (i = 0; i < MAXIM2C_LINK_ID_MAX; i++) {
+		if ((link_init_mask & BIT(i)) == 0) {
+			dev_dbg(dev, "link id = %d init mask is disabled\n", i);
+			continue;
+		}
+
+		link_enable = maxim2c->gmsl_link.link_cfg[i].link_enable;
+		if (link_enable == 0) {
+			dev_info(dev, "link id = %d is disabled\n", i);
+			continue;
+		}
+
+		remote_device = maxim2c->remote_device[i];
+		if (remote_device == NULL) {
+			dev_info(dev, "remote device id = %d isn't detected\n", i);
+			continue;
+		}
+
+		if (remote_device->remote_enable == 0) {
+			dev_info(dev, "remote device id = %d isn't enabled\n", i);
+			continue;
+		}
+
+		remote_ops = remote_device->remote_ops;
+		if (remote_ops == NULL) {
+			dev_info(dev, "remote device id = %d is no ops\n", i);
+			continue;
+		}
+
+		link_mask = BIT(i);
+		link_locked = maxim2c_link_get_lock_state(maxim2c, link_mask);
+		if (link_locked != link_mask) {
+			dev_info(dev, "link id = %d is unlocked\n", i);
+			continue;
+		}
+
+		maxim2c_link_select_remote_control(maxim2c, link_mask);
+
+		if (remote_ops->remote_init)
+			ret |= remote_ops->remote_init(remote_device);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_remote_devices_init);
+
+int maxim2c_remote_devices_deinit(maxim2c_t *maxim2c, u8 link_init_mask)
+{
+	struct device *dev = &maxim2c->client->dev;
+	struct maxim2c_remote *remote_device = NULL;
+	const struct maxim2c_remote_ops *remote_ops = NULL;
+	u8 link_mask = 0, link_enable = 0, link_locked = 0;
+	int ret = 0, i = 0;
+
+	dev_dbg(dev, "%s: link init mask = 0x%02x\n", __func__, link_init_mask);
+
+	for (i = 0; i < MAXIM2C_LINK_ID_MAX; i++) {
+		if ((link_init_mask & BIT(i)) == 0) {
+			dev_dbg(dev, "link id = %d init mask is disabled\n", i);
+			continue;
+		}
+
+		link_enable = maxim2c->gmsl_link.link_cfg[i].link_enable;
+		if (link_enable == 0) {
+			dev_info(dev, "link id = %d is disabled\n", i);
+			continue;
+		}
+
+		remote_device = maxim2c->remote_device[i];
+		if (remote_device == NULL) {
+			dev_info(dev, "remote device id = %d isn't detected\n", i);
+			continue;
+		}
+
+		if (remote_device->remote_enable == 0) {
+			dev_info(dev, "remote device id = %d isn't enabled\n", i);
+			continue;
+		}
+
+		remote_ops = remote_device->remote_ops;
+		if (remote_ops == NULL) {
+			dev_info(dev, "remote device id = %d is no ops\n", i);
+			continue;
+		}
+
+		link_mask = BIT(i);
+		link_locked = maxim2c_link_get_lock_state(maxim2c, link_mask);
+		if (link_locked != link_mask) {
+			dev_info(dev, "link id = %d is unlocked\n", i);
+			continue;
+		}
+
+		maxim2c_link_select_remote_control(maxim2c, link_mask);
+
+		if (remote_ops->remote_deinit)
+			ret |= remote_ops->remote_deinit(remote_device);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_remote_devices_deinit);
+
+int maxim2c_remote_load_init_seq(maxim2c_remote_t *remote_device)
+{
+	struct device *dev = remote_device->dev;
+	struct device_node *node = NULL;
+	int ret = 0;
+
+	node = of_get_child_by_name(dev->of_node, "remote-init-sequence");
+	if (!IS_ERR_OR_NULL(node)) {
+		dev_info(dev, "load remote-init-sequence\n");
+
+		ret = maxim2c_i2c_load_init_seq(dev, node,
+					&remote_device->remote_init_seq);
+
+		of_node_put(node);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_remote_load_init_seq);
+
+int maxim2c_remote_i2c_addr_select(maxim2c_remote_t *remote_device, u32 i2c_id)
+{
+	struct device *dev = remote_device->dev;
+	struct i2c_client *client = remote_device->client;
+
+	if (i2c_id == MAXIM2C_I2C_SER_DEF) {
+		client->addr = remote_device->ser_i2c_addr_def;
+		dev_info(dev, "ser select default i2c addr = 0x%02x\n", client->addr);
+	} else if (i2c_id == MAXIM2C_I2C_SER_MAP) {
+		client->addr = remote_device->ser_i2c_addr_map;
+		dev_info(dev, "ser select mapping i2c addr = 0x%02x\n", client->addr);
+	} else {
+		dev_err(dev, "i2c select id = %d error\n", i2c_id);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_remote_i2c_addr_select);
+
+int maxim2c_remote_i2c_client_init(maxim2c_remote_t *remote_device,
+				struct i2c_client *des_client)
+{
+	struct device *dev = remote_device->dev;
+	struct i2c_client *ser_client = NULL;
+	u16 ser_client_addr = 0;
+
+	if (remote_device->ser_i2c_addr_map)
+		ser_client_addr = remote_device->ser_i2c_addr_map;
+	else
+		ser_client_addr = remote_device->ser_i2c_addr_def;
+	ser_client = devm_i2c_new_dummy_device(&des_client->dev,
+				des_client->adapter, ser_client_addr);
+	if (IS_ERR(ser_client)) {
+		dev_err(dev, "failed to alloc i2c client.\n");
+		return -PTR_ERR(ser_client);
+	}
+	ser_client->addr = remote_device->ser_i2c_addr_def;
+
+	remote_device->client = ser_client;
+	i2c_set_clientdata(ser_client, remote_device);
+
+	dev_info(dev, "remote i2c client init, i2c_addr = 0x%02x\n",
+			ser_client_addr);
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_remote_i2c_client_init);
+
+static int maxim2c_remote_device_chain_check(maxim2c_remote_t *remote_device)
+{
+	struct device *dev = NULL;
+	struct device_node *endpoint = NULL;
+	struct device_node *link_node = NULL;
+	u8 remote_id, link_id;
+	u32 value;
+	int ret = 0;
+
+	if (remote_device == NULL) {
+		dev_err(dev, "%s: input parameter is error\n", __func__);
+		return -EINVAL;
+	}
+
+	dev = remote_device->dev;
+	remote_id = remote_device->remote_id;
+
+	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+	if (!endpoint) {
+		dev_err(dev, "%s: no endpoint error\n", __func__);
+		return -EINVAL;
+	}
+
+	link_node = of_graph_get_remote_port_parent(endpoint);
+	if (!link_node) {
+		dev_err(dev, "%pOF: endpoint has no remote port parent error\n",
+				endpoint);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(link_node, "link-id", &value);
+	if (ret) {
+		dev_err(dev, "%pOF: no property link_id error\n", link_node);
+
+		of_node_put(link_node);
+		return -EINVAL;
+	}
+	of_node_put(link_node);
+	link_id = value;
+
+	if (remote_id != link_id) {
+		dev_err(dev, "remote_id (%d) != link_id (%d) of %pOF\n",
+				remote_id, link_id, link_node);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int maxim2c_remote_device_register(maxim2c_t *maxim2c,
+		maxim2c_remote_t *remote_device)
+{
+	struct device *dev = NULL;
+	u8 remote_id;
+	int ret = 0;
+
+	if ((maxim2c == NULL) || (remote_device == NULL)) {
+		dev_err(dev, "%s: input parameter is error!\n", __func__);
+
+		return -EINVAL;
+	}
+
+	dev = remote_device->dev;
+	remote_id = remote_device->remote_id;
+	if (remote_id >= MAXIM2C_LINK_ID_MAX) {
+		dev_err(dev, "%s: remote_id = %d is error\n",
+				__func__, remote_id);
+
+		return -EINVAL;
+	}
+
+	if (maxim2c->remote_device[remote_id] != NULL) {
+		dev_err(dev, "%s: remote_id = %d is conflict\n",
+				__func__, remote_id);
+
+		return -EINVAL;
+	}
+
+	ret = maxim2c_remote_device_chain_check(remote_device);
+	if (ret) {
+		dev_err(dev, "%s: remote device id = %d chain error\n",
+				__func__, remote_id);
+		return -EINVAL;
+	}
+
+	remote_device->remote_enable = 1;
+	maxim2c->remote_device[remote_id] = remote_device;
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_remote_device_register);
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_remote.h b/kernel/drivers/media/i2c/maxim2c/maxim2c_remote.h
new file mode 100644
index 0000000..9044d46
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_remote.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+#ifndef __MAXIM2C_REMOTE_H__
+#define __MAXIM2C_REMOTE_H__
+
+#include "maxim2c_i2c.h"
+
+struct maxim2c_remote;
+
+struct maxim2c_remote_ops {
+	int (*remote_init)(struct maxim2c_remote *remote);
+	int (*remote_deinit)(struct maxim2c_remote *remote);
+};
+
+typedef struct maxim2c_remote {
+	struct i2c_client *client;
+	struct device *dev;
+	void *local;
+	const struct maxim2c_remote_ops *remote_ops;
+	struct maxim2c_i2c_init_seq remote_init_seq;
+
+	u8 remote_id;
+	u8 remote_enable;
+
+	u8 ser_i2c_addr_def;
+	u8 ser_i2c_addr_map;
+
+	u8 cam_i2c_addr_def;
+	u8 cam_i2c_addr_map;
+} maxim2c_remote_t;
+
+#endif /* __MAXIM2C_REMOTE_H__ */
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_v4l2.c b/kernel/drivers/media/i2c/maxim2c/maxim2c_v4l2.c
new file mode 100644
index 0000000..fd79ab8
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_v4l2.c
@@ -0,0 +1,992 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim Dual GMSL Deserializer V4L2 driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * Author: Cai Wenzhong <cwz@rock-chips.com>
+ *
+ */
+#include <linux/interrupt.h>
+#include <linux/of_graph.h>
+#include <linux/pm_runtime.h>
+#include <linux/compat.h>
+#include <linux/rk-camera-module.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+#include "maxim2c_api.h"
+
+#ifndef V4L2_CID_DIGITAL_GAIN
+#define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
+#endif
+
+#define MIPI_PHY_FREQ_MHZ(x)		((x) * 1000000UL)
+
+/* link freq = index * MIPI_PHY_FREQ_MHZ(50) */
+static const s64 link_freq_items[] = {
+	MIPI_PHY_FREQ_MHZ(0),
+	MIPI_PHY_FREQ_MHZ(50),
+	MIPI_PHY_FREQ_MHZ(100),
+	MIPI_PHY_FREQ_MHZ(150),
+	MIPI_PHY_FREQ_MHZ(200),
+	MIPI_PHY_FREQ_MHZ(250),
+	MIPI_PHY_FREQ_MHZ(300),
+	MIPI_PHY_FREQ_MHZ(350),
+	MIPI_PHY_FREQ_MHZ(400),
+	MIPI_PHY_FREQ_MHZ(450),
+	MIPI_PHY_FREQ_MHZ(500),
+	MIPI_PHY_FREQ_MHZ(550),
+	MIPI_PHY_FREQ_MHZ(600),
+	MIPI_PHY_FREQ_MHZ(650),
+	MIPI_PHY_FREQ_MHZ(700),
+	MIPI_PHY_FREQ_MHZ(750),
+	MIPI_PHY_FREQ_MHZ(800),
+	MIPI_PHY_FREQ_MHZ(850),
+	MIPI_PHY_FREQ_MHZ(900),
+	MIPI_PHY_FREQ_MHZ(950),
+	MIPI_PHY_FREQ_MHZ(1000),
+	MIPI_PHY_FREQ_MHZ(1050),
+	MIPI_PHY_FREQ_MHZ(1100),
+	MIPI_PHY_FREQ_MHZ(1150),
+	MIPI_PHY_FREQ_MHZ(1200),
+	MIPI_PHY_FREQ_MHZ(1250),
+};
+
+static const struct maxim2c_mode maxim2c_def_mode = {
+	.width = 1920,
+	.height = 1080,
+	.max_fps = {
+		.numerator = 10000,
+		.denominator = 300000,
+	},
+	.link_freq_idx = 15,
+	.bus_fmt = MEDIA_BUS_FMT_UYVY8_2X8,
+	.bpp = 16,
+	.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,
+	.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_2,
+	.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_3,
+};
+
+static struct rkmodule_csi_dphy_param rk3588_dcphy_param = {
+	.vendor = PHY_VENDOR_SAMSUNG,
+	.lp_vol_ref = 3,
+	.lp_hys_sw = {3, 0, 0, 0},
+	.lp_escclk_pol_sel = {1, 0, 0, 0},
+	.skew_data_cal_clk = {0, 0, 0, 0},
+	.clk_hs_term_sel = 2,
+	.data_hs_term_sel = {2, 2, 2, 2},
+	.reserved = {0},
+};
+
+static int maxim2c_support_mode_init(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	struct device_node *node = NULL;
+	struct maxim2c_mode *mode = NULL;
+	u32 value = 0, vc_array[PAD_MAX];
+	int ret = 0, i = 0, array_size = 0;
+
+	dev_info(dev, "=== maxim2c support mode init ===\n");
+
+#if MAXIM2C_TEST_PATTERN
+	ret = maxim2c_pattern_support_mode_init(maxim2c);
+	return ret;
+#endif
+
+	maxim2c->cfg_modes_num = 1;
+	maxim2c->cur_mode = &maxim2c->supported_mode;
+	mode = &maxim2c->supported_mode;
+
+	// init using def mode
+	memcpy(mode, &maxim2c_def_mode, sizeof(struct maxim2c_mode));
+
+	node = of_get_child_by_name(dev->of_node, "support-mode-config");
+	if (IS_ERR_OR_NULL(node)) {
+		dev_info(dev, "no mode config node, using default config.\n");
+
+		return 0;
+	}
+
+	if (!of_device_is_available(node)) {
+		dev_info(dev, "%pOF is disabled, using default config.\n", node);
+
+		of_node_put(node);
+
+		return 0;
+	}
+
+	ret = of_property_read_u32(node, "sensor-width", &value);
+	if (ret == 0) {
+		dev_info(dev, "sensor-width property: %d\n", value);
+		mode->width = value;
+	}
+	dev_info(dev, "support mode: width = %d\n", mode->width);
+
+	ret = of_property_read_u32(node, "sensor-height", &value);
+	if (ret == 0) {
+		dev_info(dev, "sensor-height property: %d\n", value);
+		mode->height = value;
+	}
+	dev_info(dev, "support mode: height = %d\n", mode->height);
+
+	ret = of_property_read_u32(node, "bus-format", &value);
+	if (ret == 0) {
+		dev_info(dev, "bus-format property: %d\n", value);
+		mode->bus_fmt = value;
+	}
+	dev_info(dev, "support mode: bus_fmt = 0x%x\n", mode->bus_fmt);
+
+	ret = of_property_read_u32(node, "bpp", &value);
+	if (ret == 0) {
+		dev_info(dev, "bpp property: %d\n", value);
+		mode->bpp = value;
+	}
+	dev_info(dev, "support mode: bpp = %d\n", mode->bpp);
+
+	ret = of_property_read_u32(node, "max-fps-numerator", &value);
+	if (ret == 0) {
+		dev_info(dev, "max-fps-numerator property: %d\n", value);
+		mode->max_fps.numerator = value;
+	}
+	dev_info(dev, "support mode: numerator = %d\n", mode->max_fps.numerator);
+
+	ret = of_property_read_u32(node, "max-fps-denominator", &value);
+	if (ret == 0) {
+		dev_info(dev, "max-fps-denominator property: %d\n", value);
+		mode->max_fps.denominator = value;
+	}
+	dev_info(dev, "support mode: denominator = %d\n", mode->max_fps.denominator);
+
+	ret = of_property_read_u32(node, "link-freq-idx", &value);
+	if (ret == 0) {
+		dev_info(dev, "link-freq-idx property: %d\n", value);
+		mode->link_freq_idx = value;
+	}
+	dev_info(dev, "support mode: link_freq_idx = %d\n", mode->link_freq_idx);
+
+	ret = of_property_read_u32(node, "hts-def", &value);
+	if (ret == 0) {
+		dev_info(dev, "hts-def property: %d\n", value);
+		mode->hts_def = value;
+	}
+	dev_info(dev, "support mode: hts_def = %d\n", mode->hts_def);
+
+	ret = of_property_read_u32(node, "vts-def", &value);
+	if (ret == 0) {
+		dev_info(dev, "vts-def property: %d\n", value);
+		mode->vts_def = value;
+	}
+	dev_info(dev, "support mode: vts_def = %d\n", mode->vts_def);
+
+	ret = of_property_read_u32(node, "exp-def", &value);
+	if (ret == 0) {
+		dev_info(dev, "exp-def property: %d\n", value);
+		mode->exp_def = value;
+	}
+	dev_info(dev, "support mode: exp_def = %d\n", mode->exp_def);
+
+	array_size = of_property_read_variable_u32_array(node,
+				"vc-array", vc_array, 1, PAD_MAX);
+	if (array_size > 0) {
+		if (array_size > PAD_MAX)
+			array_size = PAD_MAX;
+
+		for (i = 0; i < array_size; i++) {
+			dev_info(dev, "vc-array[%d] property: 0x%x\n", i, vc_array[i]);
+			mode->vc[i] = vc_array[i];
+		}
+	}
+	for (i = 0; i < PAD_MAX; i++)
+		dev_info(dev, "support mode: vc[%d] = 0x%x\n", i, mode->vc[i]);
+
+	of_node_put(node);
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int maxim2c_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+	struct v4l2_mbus_framefmt *try_fmt =
+		v4l2_subdev_get_try_format(sd, fh->pad, 0);
+	const struct maxim2c_mode *def_mode = &maxim2c->supported_mode;
+
+	mutex_lock(&maxim2c->mutex);
+
+	/* Initialize try_fmt */
+	try_fmt->width = def_mode->width;
+	try_fmt->height = def_mode->height;
+	try_fmt->code = def_mode->bus_fmt;
+	try_fmt->field = V4L2_FIELD_NONE;
+
+	mutex_unlock(&maxim2c->mutex);
+	/* No crop or compose */
+
+	return 0;
+}
+#endif
+
+static int maxim2c_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+	struct i2c_client *client = maxim2c->client;
+	int ret = 0;
+
+	mutex_lock(&maxim2c->mutex);
+
+	/* If the power state is not modified - no work to do. */
+	if (maxim2c->power_on == !!on)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		maxim2c->power_on = true;
+	} else {
+		pm_runtime_put(&client->dev);
+		maxim2c->power_on = false;
+	}
+
+unlock_and_return:
+	mutex_unlock(&maxim2c->mutex);
+
+	return ret;
+}
+
+static void maxim2c_get_module_inf(struct maxim2c *maxim2c,
+					struct rkmodule_inf *inf)
+{
+	memset(inf, 0, sizeof(*inf));
+	strscpy(inf->base.sensor, MAXIM2C_NAME, sizeof(inf->base.sensor));
+	strscpy(inf->base.module, maxim2c->module_name,
+		sizeof(inf->base.module));
+	strscpy(inf->base.lens, maxim2c->len_name, sizeof(inf->base.lens));
+}
+
+static void maxim2c_get_vicap_rst_inf(struct maxim2c *maxim2c,
+				struct rkmodule_vicap_reset_info *rst_info)
+{
+	struct i2c_client *client = maxim2c->client;
+
+	rst_info->is_reset = maxim2c->hot_plug;
+	maxim2c->hot_plug = false;
+	rst_info->src = RKCIF_RESET_SRC_ERR_HOTPLUG;
+
+	dev_info(&client->dev, "%s: rst_info->is_reset:%d.\n",
+		__func__, rst_info->is_reset);
+}
+
+static void maxim2c_set_vicap_rst_inf(struct maxim2c *maxim2c,
+				struct rkmodule_vicap_reset_info rst_info)
+{
+	maxim2c->is_reset = rst_info.is_reset;
+}
+
+static long maxim2c_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+	struct rkmodule_csi_dphy_param *dphy_param;
+	long ret = 0;
+
+	dev_dbg(&maxim2c->client->dev, "ioctl cmd = 0x%08x\n", cmd);
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		maxim2c_get_module_inf(maxim2c, (struct rkmodule_inf *)arg);
+		break;
+	case RKMODULE_GET_VICAP_RST_INFO:
+		maxim2c_get_vicap_rst_inf(maxim2c,
+			(struct rkmodule_vicap_reset_info *)arg);
+		break;
+	case RKMODULE_SET_VICAP_RST_INFO:
+		maxim2c_set_vicap_rst_inf(maxim2c,
+			*(struct rkmodule_vicap_reset_info *)arg);
+		break;
+	case RKMODULE_SET_CSI_DPHY_PARAM:
+		dphy_param = (struct rkmodule_csi_dphy_param *)arg;
+		rk3588_dcphy_param = *dphy_param;
+		dev_dbg(&maxim2c->client->dev, "set dcphy param\n");
+		break;
+	case RKMODULE_GET_CSI_DPHY_PARAM:
+		dphy_param = (struct rkmodule_csi_dphy_param *)arg;
+		*dphy_param = rk3588_dcphy_param;
+		dev_dbg(&maxim2c->client->dev, "get dcphy param\n");
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long maxim2c_compat_ioctl32(struct v4l2_subdev *sd, unsigned int cmd,
+					unsigned long arg)
+{
+	void __user *up = compat_ptr(arg);
+	struct rkmodule_inf *inf;
+	struct rkmodule_vicap_reset_info *vicap_rst_inf;
+	struct rkmodule_csi_dphy_param *dphy_param;
+	long ret = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
+		if (!inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = maxim2c_ioctl(sd, cmd, inf);
+		if (!ret) {
+			ret = copy_to_user(up, inf, sizeof(*inf));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(inf);
+		break;
+	case RKMODULE_GET_VICAP_RST_INFO:
+		vicap_rst_inf = kzalloc(sizeof(*vicap_rst_inf), GFP_KERNEL);
+		if (!vicap_rst_inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = maxim2c_ioctl(sd, cmd, vicap_rst_inf);
+		if (!ret) {
+			ret = copy_to_user(up, vicap_rst_inf, sizeof(*vicap_rst_inf));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(vicap_rst_inf);
+		break;
+	case RKMODULE_SET_VICAP_RST_INFO:
+		vicap_rst_inf = kzalloc(sizeof(*vicap_rst_inf), GFP_KERNEL);
+		if (!vicap_rst_inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(vicap_rst_inf, up, sizeof(*vicap_rst_inf));
+		if (!ret)
+			ret = maxim2c_ioctl(sd, cmd, vicap_rst_inf);
+		else
+			ret = -EFAULT;
+		kfree(vicap_rst_inf);
+		break;
+	case RKMODULE_SET_CSI_DPHY_PARAM:
+		dphy_param = kzalloc(sizeof(*dphy_param), GFP_KERNEL);
+		if (!dphy_param) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(dphy_param, up, sizeof(*dphy_param));
+		if (!ret)
+			ret = maxim2c_ioctl(sd, cmd, dphy_param);
+		else
+			ret = -EFAULT;
+		kfree(dphy_param);
+		break;
+	case RKMODULE_GET_CSI_DPHY_PARAM:
+		dphy_param = kzalloc(sizeof(*dphy_param), GFP_KERNEL);
+		if (!dphy_param) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = maxim2c_ioctl(sd, cmd, dphy_param);
+		if (!ret) {
+			ret = copy_to_user(up, dphy_param, sizeof(*dphy_param));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(dphy_param);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+#endif /* CONFIG_COMPAT */
+
+static int __maxim2c_start_stream(struct maxim2c *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	int ret = 0;
+	s64 link_freq_hz = 0;
+	u8 link_mask = 0, link_freq_idx = 0;
+	u8 video_pipe_mask = 0;
+
+#if MAXIM2C_LOCAL_DES_ON_OFF_EN
+#if MAXIM2C_TEST_PATTERN
+	ret = maxim2c_pattern_hw_init(maxim2c);
+	if (ret) {
+		dev_err(dev, "test pattern hw init error\n");
+		return ret;
+	}
+#else
+	ret = maxim2c_module_hw_init(maxim2c);
+	if (ret) {
+		dev_err(dev, "maxim2c module hw init error\n");
+		return ret;
+	}
+#endif /* MAXIM2C_TEST_PATTERN */
+#endif /* MAXIM2C_LOCAL_DES_ON_OFF_EN */
+
+	link_mask = maxim2c->gmsl_link.link_enable_mask;
+	video_pipe_mask = maxim2c->video_pipe.pipe_enable_mask;
+
+	// disable all remote control
+	ret = maxim2c_link_select_remote_control(maxim2c, 0);
+	if (ret) {
+		dev_err(dev, "link disable remote control error\n");
+		return ret;
+	}
+
+	// disable all video pipe
+	ret = maxim2c_video_pipe_mask_enable(maxim2c, video_pipe_mask, false);
+	if (ret) {
+		dev_err(dev, "video pipe disable error\n");
+		return ret;
+	}
+
+	ret = maxim2c_link_select_remote_enable(maxim2c, link_mask);
+	if (ret) {
+		dev_err(dev, "link select enable error, mask = 0x%x\n", link_mask);
+		return ret;
+	}
+
+	link_mask = maxim2c->gmsl_link.link_locked_mask;
+	ret = maxim2c_remote_devices_init(maxim2c, link_mask);
+	if (ret) {
+		dev_err(dev, "remote devices init error\n");
+		return ret;
+	}
+
+	// mipi txphy enable setting: standby or enable
+	ret = maxim2c_mipi_txphy_enable(maxim2c, true);
+	if (ret) {
+		dev_err(dev, "mipi txphy enable error\n");
+		return ret;
+	}
+
+	// mipi txphy dpll setting
+	link_freq_idx = maxim2c->cur_mode->link_freq_idx;
+	link_freq_hz = link_freq_items[link_freq_idx];
+	ret = maxim2c_dphy_dpll_predef_set(maxim2c, link_freq_hz);
+	if (ret) {
+		dev_err(dev, "mipi txphy dpll setting error\n");
+		return ret;
+	}
+
+	// enable video pipe
+	ret = maxim2c_video_pipe_mask_enable(maxim2c, video_pipe_mask, true);
+	if (ret) {
+		dev_err(dev, "video pipe enable error\n");
+		return ret;
+	}
+
+	ret = maxim2c_link_select_remote_control(maxim2c, link_mask);
+	if (ret) {
+		dev_err(dev, "remote control enable error\n");
+		return ret;
+	}
+
+	/* In case these controls are set before streaming */
+	mutex_unlock(&maxim2c->mutex);
+	ret = v4l2_ctrl_handler_setup(&maxim2c->ctrl_handler);
+	mutex_lock(&maxim2c->mutex);
+	if (ret)
+		return ret;
+
+#if MAXIM2C_TEST_PATTERN
+	ret = maxim2c_pattern_enable(maxim2c, true);
+	if (ret) {
+		dev_err(dev, "test pattern setting error\n");
+		return ret;
+	}
+#endif /* MAXIM2C_TEST_PATTERN */
+
+	ret = maxim2c_mipi_csi_output(maxim2c, true);
+	if (ret) {
+		dev_err(dev, "mipi csi output error\n");
+		return ret;
+	}
+
+	if (maxim2c->hot_plug_irq > 0)
+		enable_irq(maxim2c->hot_plug_irq);
+
+	if (maxim2c->link_lock_state != maxim2c->gmsl_link.link_enable_mask) {
+		dev_info(dev, "partial links are locked, start hot plug detect work.\n");
+		maxim2c_hot_plug_detect_work_start(maxim2c);
+	}
+
+	return 0;
+}
+
+static int __maxim2c_stop_stream(struct maxim2c *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	u8 link_mask = 0, pipe_mask = 0;
+	int ret = 0;
+
+	link_mask = maxim2c->gmsl_link.link_enable_mask;
+	pipe_mask = maxim2c->video_pipe.pipe_enable_mask;
+
+	if (maxim2c->hot_plug_irq > 0)
+		disable_irq(maxim2c->hot_plug_irq);
+
+	if (maxim2c->hot_plug_work.state_check_wq)
+		cancel_delayed_work_sync(&maxim2c->hot_plug_work.state_d_work);
+
+	ret |= maxim2c_mipi_csi_output(maxim2c, false);
+	ret |= maxim2c_mipi_txphy_enable(maxim2c, false);
+
+#if MAXIM2C_TEST_PATTERN
+	ret |= maxim2c_pattern_enable(maxim2c, false);
+#endif /* MAXIM2C_TEST_PATTERN */
+
+	ret |= maxim2c_video_pipe_mask_enable(maxim2c, pipe_mask, false);
+
+	ret |= maxim2c_remote_devices_deinit(maxim2c, link_mask);
+
+	ret |= maxim2c_link_select_remote_control(maxim2c, 0);
+	ret |= maxim2c_link_mask_enable(maxim2c, link_mask, false);
+
+	if (ret) {
+		dev_err(dev, "stop stream error\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int maxim2c_s_stream(struct v4l2_subdev *sd, int on)
+{
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+	struct i2c_client *client = maxim2c->client;
+	int ret = 0;
+
+	dev_info(&client->dev, "%s: on: %d, %dx%d@%d\n", __func__, on,
+		maxim2c->cur_mode->width, maxim2c->cur_mode->height,
+		DIV_ROUND_CLOSEST(maxim2c->cur_mode->max_fps.denominator,
+				maxim2c->cur_mode->max_fps.numerator));
+
+	mutex_lock(&maxim2c->mutex);
+	on = !!on;
+	if (on == maxim2c->streaming)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		ret = __maxim2c_start_stream(maxim2c);
+		if (ret) {
+			v4l2_err(sd, "start stream failed while write regs\n");
+			pm_runtime_put(&client->dev);
+			goto unlock_and_return;
+		}
+	} else {
+		__maxim2c_stop_stream(maxim2c);
+		pm_runtime_put(&client->dev);
+	}
+
+	maxim2c->streaming = on;
+
+unlock_and_return:
+	mutex_unlock(&maxim2c->mutex);
+
+	return ret;
+}
+
+static int maxim2c_g_frame_interval(struct v4l2_subdev *sd,
+				struct v4l2_subdev_frame_interval *fi)
+{
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+	const struct maxim2c_mode *mode = maxim2c->cur_mode;
+
+	mutex_lock(&maxim2c->mutex);
+	fi->interval = mode->max_fps;
+	mutex_unlock(&maxim2c->mutex);
+
+	return 0;
+}
+
+static int maxim2c_enum_mbus_code(struct v4l2_subdev *sd,
+				struct v4l2_subdev_pad_config *cfg,
+				struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+	const struct maxim2c_mode *mode = maxim2c->cur_mode;
+
+	if (code->index != 0)
+		return -EINVAL;
+	code->code = mode->bus_fmt;
+
+	return 0;
+}
+
+static int maxim2c_enum_frame_sizes(struct v4l2_subdev *sd,
+				struct v4l2_subdev_pad_config *cfg,
+				struct v4l2_subdev_frame_size_enum *fse)
+{
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+
+	if (fse->index >= maxim2c->cfg_modes_num)
+		return -EINVAL;
+
+	if (fse->code != maxim2c->supported_mode.bus_fmt)
+		return -EINVAL;
+
+	fse->min_width  = maxim2c->supported_mode.width;
+	fse->max_width  = maxim2c->supported_mode.width;
+	fse->max_height = maxim2c->supported_mode.height;
+	fse->min_height = maxim2c->supported_mode.height;
+
+	return 0;
+}
+
+static int
+maxim2c_enum_frame_interval(struct v4l2_subdev *sd,
+			struct v4l2_subdev_pad_config *cfg,
+			struct v4l2_subdev_frame_interval_enum *fie)
+{
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+
+	if (fie->index >= maxim2c->cfg_modes_num)
+		return -EINVAL;
+
+	fie->code = maxim2c->supported_mode.bus_fmt;
+	fie->width = maxim2c->supported_mode.width;
+	fie->height = maxim2c->supported_mode.height;
+	fie->interval = maxim2c->supported_mode.max_fps;
+
+	return 0;
+}
+
+static int maxim2c_get_fmt(struct v4l2_subdev *sd,
+			struct v4l2_subdev_pad_config *cfg,
+			struct v4l2_subdev_format *fmt)
+{
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+	const struct maxim2c_mode *mode = maxim2c->cur_mode;
+
+	mutex_lock(&maxim2c->mutex);
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+#else
+		mutex_unlock(&maxim2c->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		fmt->format.width = mode->width;
+		fmt->format.height = mode->height;
+		fmt->format.code = mode->bus_fmt;
+		fmt->format.field = V4L2_FIELD_NONE;
+		if (fmt->pad < PAD_MAX && fmt->pad >= PAD0)
+			fmt->reserved[0] = mode->vc[fmt->pad];
+		else
+			fmt->reserved[0] = mode->vc[PAD0];
+	}
+	mutex_unlock(&maxim2c->mutex);
+
+	return 0;
+}
+
+static int maxim2c_set_fmt(struct v4l2_subdev *sd,
+			struct v4l2_subdev_pad_config *cfg,
+			struct v4l2_subdev_format *fmt)
+{
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+	struct device *dev = &maxim2c->client->dev;
+	const struct maxim2c_mode *mode = NULL;
+	u64 link_freq = 0, pixel_rate = 0;
+	u8 data_lanes;
+
+	mutex_lock(&maxim2c->mutex);
+
+	mode = &maxim2c->supported_mode;
+
+	fmt->format.code = mode->bus_fmt;
+	fmt->format.width = mode->width;
+	fmt->format.height = mode->height;
+	fmt->format.field = V4L2_FIELD_NONE;
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+#else
+		mutex_unlock(&maxim2c->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		if (maxim2c->streaming) {
+			mutex_unlock(&maxim2c->mutex);
+			return -EBUSY;
+		}
+
+		maxim2c->cur_mode = mode;
+
+		__v4l2_ctrl_s_ctrl(maxim2c->link_freq, mode->link_freq_idx);
+
+		/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
+		link_freq = link_freq_items[mode->link_freq_idx];
+		data_lanes = maxim2c->bus_cfg.bus.mipi_csi2.num_data_lanes;
+		pixel_rate = (u32)link_freq / mode->bpp * 2 * data_lanes;
+		__v4l2_ctrl_s_ctrl_int64(maxim2c->pixel_rate, pixel_rate);
+
+		dev_info(dev, "mipi_freq_idx = %d, mipi_link_freq = %lld\n",
+					mode->link_freq_idx, link_freq);
+		dev_info(dev, "pixel_rate = %lld, bpp = %d\n",
+					pixel_rate, mode->bpp);
+	}
+
+	mutex_unlock(&maxim2c->mutex);
+
+	return 0;
+}
+
+static int maxim2c_get_selection(struct v4l2_subdev *sd,
+				struct v4l2_subdev_pad_config *cfg,
+				struct v4l2_subdev_selection *sel)
+{
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+
+	if (sel->target == V4L2_SEL_TGT_CROP_BOUNDS) {
+		sel->r.left = 0;
+		sel->r.width = maxim2c->cur_mode->width;
+		sel->r.top = 0;
+		sel->r.height = maxim2c->cur_mode->height;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int maxim2c_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
+				struct v4l2_mbus_config *config)
+{
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+	u32 val = 0;
+	u8 data_lanes = maxim2c->bus_cfg.bus.mipi_csi2.num_data_lanes;
+
+	val |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+	val |= (1 << (data_lanes - 1));
+
+	val |= V4L2_MBUS_CSI2_CHANNEL_3 | V4L2_MBUS_CSI2_CHANNEL_2 |
+	       V4L2_MBUS_CSI2_CHANNEL_1 | V4L2_MBUS_CSI2_CHANNEL_0;
+
+	config->type = V4L2_MBUS_CSI2_DPHY;
+	config->flags = val;
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static const struct v4l2_subdev_internal_ops maxim2c_internal_ops = {
+	.open = maxim2c_open,
+};
+#endif
+
+static const struct v4l2_subdev_core_ops maxim2c_core_ops = {
+	.s_power = maxim2c_s_power,
+	.ioctl = maxim2c_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl32 = maxim2c_compat_ioctl32,
+#endif
+};
+
+static const struct v4l2_subdev_video_ops maxim2c_video_ops = {
+	.s_stream = maxim2c_s_stream,
+	.g_frame_interval = maxim2c_g_frame_interval,
+};
+
+static const struct v4l2_subdev_pad_ops maxim2c_pad_ops = {
+	.enum_mbus_code = maxim2c_enum_mbus_code,
+	.enum_frame_size = maxim2c_enum_frame_sizes,
+	.enum_frame_interval = maxim2c_enum_frame_interval,
+	.get_fmt = maxim2c_get_fmt,
+	.set_fmt = maxim2c_set_fmt,
+	.get_selection = maxim2c_get_selection,
+	.get_mbus_config = maxim2c_g_mbus_config,
+};
+
+static const struct v4l2_subdev_ops maxim2c_subdev_ops = {
+	.core = &maxim2c_core_ops,
+	.video = &maxim2c_video_ops,
+	.pad = &maxim2c_pad_ops,
+};
+
+static int maxim2c_initialize_controls(struct maxim2c *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	const struct maxim2c_mode *mode;
+	struct v4l2_ctrl_handler *handler;
+	u64 link_freq = 0, pixel_rate = 0;
+	u8 data_lanes;
+	int ret = 0;
+
+	handler = &maxim2c->ctrl_handler;
+
+	ret = v4l2_ctrl_handler_init(handler, 2);
+	if (ret)
+		return ret;
+	handler->lock = &maxim2c->mutex;
+
+	mode = maxim2c->cur_mode;
+	maxim2c->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
+				V4L2_CID_LINK_FREQ,
+				ARRAY_SIZE(link_freq_items) - 1, 0,
+				link_freq_items);
+	__v4l2_ctrl_s_ctrl(maxim2c->link_freq, mode->link_freq_idx);
+
+	link_freq = link_freq_items[mode->link_freq_idx];
+	dev_info(dev, "mipi_freq_idx = %d, mipi_link_freq = %lld\n",
+				mode->link_freq_idx, link_freq);
+
+	/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
+	data_lanes = maxim2c->bus_cfg.bus.mipi_csi2.num_data_lanes;
+	pixel_rate = (u32)link_freq / mode->bpp * 2 * data_lanes;
+	maxim2c->pixel_rate =
+		v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, 0,
+				pixel_rate, 1, pixel_rate);
+	dev_info(dev, "pixel_rate = %lld, bpp = %d\n",
+				pixel_rate, mode->bpp);
+
+	if (handler->error) {
+		ret = handler->error;
+		dev_err(dev, "Failed to init controls(%d)\n", ret);
+		goto err_free_handler;
+	}
+
+	maxim2c->subdev.ctrl_handler = handler;
+
+	return 0;
+
+err_free_handler:
+	v4l2_ctrl_handler_free(handler);
+
+	return ret;
+}
+
+static int maxim2c_mipi_data_lanes_parse(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	struct device_node *endpoint;
+	u8 mipi_data_lanes;
+	int ret = 0;
+
+	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+	if (!endpoint) {
+		dev_err(dev, "Failed to get endpoint\n");
+		return -EINVAL;
+	}
+
+	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
+		&maxim2c->bus_cfg);
+	if (ret) {
+		dev_err(dev, "Failed to get bus config\n");
+		return -EINVAL;
+	}
+	mipi_data_lanes = maxim2c->bus_cfg.bus.mipi_csi2.num_data_lanes;
+	dev_info(dev, "mipi csi2 phy data lanes = %d\n", mipi_data_lanes);
+
+	return 0;
+}
+
+int maxim2c_v4l2_subdev_init(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	struct v4l2_subdev *sd = NULL;
+	char facing[2];
+	int ret = 0;
+
+	maxim2c_mipi_data_lanes_parse(maxim2c);
+
+	maxim2c_support_mode_init(maxim2c);
+
+	sd = &maxim2c->subdev;
+	v4l2_i2c_subdev_init(sd, client, &maxim2c_subdev_ops);
+	ret = maxim2c_initialize_controls(maxim2c);
+	if (ret)
+		goto err_free_handler;
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	sd->internal_ops = &maxim2c_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+#endif
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	maxim2c->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &maxim2c->pad);
+	if (ret < 0)
+		goto err_free_handler;
+#endif
+
+	v4l2_set_subdevdata(sd, maxim2c);
+
+	memset(facing, 0, sizeof(facing));
+	if (strcmp(maxim2c->module_facing, "back") == 0)
+		facing[0] = 'b';
+	else
+		facing[0] = 'f';
+
+	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
+		 maxim2c->module_index, facing, MAXIM2C_NAME,
+		 dev_name(sd->dev));
+
+	ret = v4l2_async_register_subdev_sensor_common(sd);
+	if (ret) {
+		dev_err(dev, "v4l2 async register subdev failed\n");
+		goto err_clean_entity;
+	}
+
+	return 0;
+
+err_clean_entity:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+
+err_free_handler:
+	v4l2_ctrl_handler_free(&maxim2c->ctrl_handler);
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_v4l2_subdev_init);
+
+void maxim2c_v4l2_subdev_deinit(maxim2c_t *maxim2c)
+{
+	struct v4l2_subdev *sd = &maxim2c->subdev;
+
+	v4l2_async_unregister_subdev(sd);
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+
+	v4l2_ctrl_handler_free(&maxim2c->ctrl_handler);
+}
+EXPORT_SYMBOL(maxim2c_v4l2_subdev_deinit);
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_video_pipe.c b/kernel/drivers/media/i2c/maxim2c/maxim2c_video_pipe.c
new file mode 100644
index 0000000..032f7d7
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_video_pipe.c
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim Dual GMSL Deserializer Video Pipe driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * Author: Cai Wenzhong <cwz@rock-chips.com>
+ *
+ */
+#include "maxim2c_api.h"
+
+static int maxim2c_video_pipe_select(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	maxim2c_video_pipe_t *video_pipe = &maxim2c->video_pipe;
+	struct maxim2c_pipe_cfg *video_pipe_cfg = NULL;
+	u8 link_idx, pipe_idx;
+	u8 reg_mask = 0, reg_value = 0;
+	int ret = 0;
+
+	// video pipe selection
+	reg_mask = 0;
+	reg_value = 0;
+
+	video_pipe_cfg = &video_pipe->pipe_cfg[MAXIM2C_PIPE_O_ID_Y];
+	if (video_pipe_cfg->pipe_enable) {
+		reg_mask |= (0x7 << 0);
+
+		pipe_idx = video_pipe_cfg->pipe_idx;
+		link_idx = video_pipe_cfg->link_idx;
+		reg_value |= ((pipe_idx + link_idx * MAXIM2C_PIPE_I_ID_MAX) << 0);
+	}
+	video_pipe_cfg = &video_pipe->pipe_cfg[MAXIM2C_PIPE_O_ID_Z];
+	if (video_pipe_cfg->pipe_enable) {
+		reg_mask |= (0x7 << 3);
+
+		pipe_idx = video_pipe_cfg->pipe_idx;
+		link_idx = video_pipe_cfg->link_idx;
+
+		reg_value |= ((pipe_idx + link_idx * MAXIM2C_PIPE_I_ID_MAX) << 3);
+	}
+
+	ret |= maxim2c_i2c_update_byte(client,
+			0x0161, MAXIM2C_I2C_REG_ADDR_16BITS,
+			reg_mask, reg_value);
+
+	return ret;
+}
+
+static int maxim2c_video_pipe_run_init_seq(maxim2c_t *maxim2c)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	maxim2c_video_pipe_t *video_pipe = &maxim2c->video_pipe;
+	struct maxim2c_pipe_cfg *video_pipe_cfg = NULL;
+	struct maxim2c_i2c_init_seq *init_seq = NULL;
+	int i = 0;
+	int ret = 0;
+
+	// video pipe init sequence
+	for (i = 0; i < MAXIM2C_PIPE_O_ID_MAX; i++) {
+		video_pipe_cfg = &video_pipe->pipe_cfg[i];
+		init_seq = &video_pipe_cfg->pipe_init_seq;
+		ret = maxim2c_i2c_run_init_seq(client, init_seq);
+		if (ret) {
+			dev_err(dev, "pipe id = %d init sequence error\n", i);
+			return ret;
+		}
+	}
+
+	// video pipe parallel mode init sequence
+	init_seq = &video_pipe->parallel_init_seq;
+	ret = maxim2c_i2c_run_init_seq(client, init_seq);
+	if (ret) {
+		dev_err(dev, "pipe parallel init sequence error\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int maxim2c_video_pipe_config_parse_dt(struct device *dev,
+		maxim2c_video_pipe_t *video_pipe,
+		struct device_node *parent_node)
+{
+	struct device_node *node = NULL;
+	struct device_node *init_seq_node = NULL;
+	struct maxim2c_i2c_init_seq *init_seq = NULL;
+	struct maxim2c_pipe_cfg *video_pipe_cfg = NULL;
+	const char *pipe_cfg_name = "video-pipe-config";
+	u32 sub_idx = 0, pipe_id = 0;
+	u32 value = 0;
+	int ret = 0;
+
+	node = NULL;
+	sub_idx = 0;
+	while ((node = of_get_next_child(parent_node, node))) {
+		if (!strncasecmp(node->name,
+					pipe_cfg_name,
+					strlen(pipe_cfg_name))) {
+			if (sub_idx >= MAXIM2C_PIPE_O_ID_MAX) {
+				dev_err(dev, "%pOF: Too many matching %s node\n",
+						parent_node, pipe_cfg_name);
+
+				of_node_put(node);
+				break;
+			}
+
+			if (!of_device_is_available(node)) {
+				dev_info(dev, "%pOF is disabled\n", node);
+
+				sub_idx++;
+
+				continue;
+			}
+
+			/* Video Pipe: pipe id */
+			ret = of_property_read_u32(node, "pipe-id", &pipe_id);
+			if (ret) {
+				// if pipe_id is error, parse next node
+				dev_err(dev, "Can not get pipe-id property!");
+
+				sub_idx++;
+
+				continue;
+			}
+			if (pipe_id >= MAXIM2C_PIPE_O_ID_MAX) {
+				// if pipe_id is error, parse next node
+				dev_err(dev, "Error pipe-id = %d!", pipe_id);
+
+				sub_idx++;
+
+				continue;
+			}
+
+			video_pipe_cfg = &video_pipe->pipe_cfg[pipe_id];
+
+			/* Video Pipe: pipe enable */
+			video_pipe_cfg->pipe_enable = 1;
+			video_pipe->pipe_enable_mask |= BIT(pipe_id);
+
+			dev_info(dev, "video pipe id = %d: pipe enable = %d\n",
+				pipe_id, video_pipe_cfg->pipe_enable);
+
+			/* Video Pipe: other config */
+			ret = of_property_read_u32(node, "pipe-idx", &value);
+			if (ret == 0) {
+				dev_info(dev, "pipe-idx property: %d", value);
+				video_pipe_cfg->pipe_idx = value;
+			}
+
+			ret = of_property_read_u32(node, "link-idx", &value);
+			if (ret == 0) {
+				dev_info(dev, "link-idx property: %d", value);
+				video_pipe_cfg->link_idx = value;
+			}
+
+			init_seq_node = of_get_child_by_name(node, "pipe-init-sequence");
+			if (!IS_ERR_OR_NULL(init_seq_node)) {
+				dev_info(dev, "load pipe-init-sequence\n");
+
+				init_seq = &video_pipe_cfg->pipe_init_seq;
+				maxim2c_i2c_load_init_seq(dev, init_seq_node, init_seq);
+
+				of_node_put(init_seq_node);
+			}
+
+			sub_idx++;
+		}
+	}
+
+	node = of_get_child_by_name(parent_node, "parallel-mode-config");
+	if (!IS_ERR_OR_NULL(node)) {
+		if (!of_device_is_available(node)) {
+			dev_info(dev, "%pOF is disabled\n", node);
+
+			of_node_put(node);
+			return 0;
+		}
+
+		init_seq_node = of_get_child_by_name(node, "parallel-init-sequence");
+		if (!IS_ERR_OR_NULL(init_seq_node)) {
+			dev_info(dev, "load parallel-init-sequence\n");
+
+			init_seq = &video_pipe->parallel_init_seq;
+			maxim2c_i2c_load_init_seq(dev, init_seq_node, init_seq);
+
+			of_node_put(init_seq_node);
+		}
+
+		of_node_put(node);
+	}
+
+	return 0;
+}
+
+int maxim2c_video_pipe_parse_dt(maxim2c_t *maxim2c, struct device_node *of_node)
+{
+	struct device *dev = &maxim2c->client->dev;
+	struct device_node *node = NULL;
+	maxim2c_video_pipe_t *video_pipe = &maxim2c->video_pipe;
+	int ret = 0;
+
+	dev_info(dev, "=== maxim2c video pipe parse dt ===\n");
+
+	node = of_get_child_by_name(of_node, "video-pipes");
+	if (IS_ERR_OR_NULL(node)) {
+		dev_err(dev, "%pOF has no child node: video-pipes\n",
+				of_node);
+		return -ENODEV;
+	}
+
+	if (!of_device_is_available(node)) {
+		dev_info(dev, "%pOF is disabled\n", node);
+		of_node_put(node);
+		return -ENODEV;
+	}
+
+	ret = maxim2c_video_pipe_config_parse_dt(dev, video_pipe, node);
+
+	of_node_put(node);
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_video_pipe_parse_dt);
+
+int maxim2c_video_pipe_mask_enable(maxim2c_t *maxim2c, u8 video_pipe_mask, bool enable)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	maxim2c_video_pipe_t *video_pipe = &maxim2c->video_pipe;
+	struct maxim2c_pipe_cfg *video_pipe_cfg = NULL;
+	u8 reg_mask = 0, reg_value = 0;
+	int i = 0;
+	int ret = 0;
+
+	dev_dbg(dev, "%s, video_pipe_mask = 0x%x, enable = %d\n",
+			__func__, video_pipe_mask, enable);
+
+	reg_mask = 0;
+	reg_value = 0;
+	// video pipe enable
+	for (i = 0; i < MAXIM2C_PIPE_O_ID_MAX; i++) {
+		video_pipe_cfg = &video_pipe->pipe_cfg[i];
+		if (video_pipe_cfg->pipe_enable
+				&& (video_pipe_mask & BIT(i))) {
+			reg_mask |= BIT(i);
+			if (enable)
+				reg_value |= BIT(i);
+		}
+	}
+
+	if (reg_mask != 0) {
+		ret |= maxim2c_i2c_update_byte(client,
+				0x0160, MAXIM2C_I2C_REG_ADDR_16BITS,
+				reg_mask, reg_value);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_video_pipe_mask_enable);
+
+int maxim2c_video_pipe_linkid_enable(maxim2c_t *maxim2c, u8 link_id, bool enable)
+{
+	struct i2c_client *client = maxim2c->client;
+	struct device *dev = &client->dev;
+	maxim2c_video_pipe_t *video_pipe = &maxim2c->video_pipe;
+	struct maxim2c_pipe_cfg *video_pipe_cfg = NULL;
+	u8 reg_mask = 0, reg_value = 0;
+	int i = 0;
+	int ret = 0;
+
+	dev_dbg(dev, "%s, link_id = %d, enable = %d\n",
+			__func__, link_id, enable);
+
+	reg_mask = 0;
+	reg_value = 0;
+	// video pipe enable
+	for (i = 0; i < MAXIM2C_PIPE_O_ID_MAX; i++) {
+		video_pipe_cfg = &video_pipe->pipe_cfg[i];
+		if (video_pipe_cfg->pipe_enable
+				&& (video_pipe_cfg->link_idx == link_id)) {
+			reg_mask = BIT(i);
+			if (enable)
+				reg_value = BIT(i);
+		}
+	}
+
+	if (reg_mask != 0) {
+		ret = maxim2c_i2c_update_byte(client,
+				0x0160, MAXIM2C_I2C_REG_ADDR_16BITS,
+				reg_mask, reg_value);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(maxim2c_video_pipe_linkid_enable);
+
+void maxim2c_video_pipe_data_init(maxim2c_t *maxim2c)
+{
+	maxim2c_video_pipe_t *video_pipe = &maxim2c->video_pipe;
+	struct maxim2c_pipe_cfg *video_pipe_cfg = NULL;
+	int i = 0;
+
+	video_pipe->pipe_enable_mask = 0;
+	video_pipe->parallel_init_seq.reg_init_seq = NULL;
+
+	for (i = 0; i < MAXIM2C_PIPE_O_ID_MAX; i++) {
+		video_pipe_cfg = &video_pipe->pipe_cfg[i];
+
+		video_pipe_cfg->pipe_enable = 0;
+		video_pipe_cfg->pipe_idx = MAXIM2C_PIPE_I_ID_Z;
+		video_pipe_cfg->link_idx = i;
+		video_pipe_cfg->pipe_init_seq.reg_init_seq = NULL;
+	}
+}
+EXPORT_SYMBOL(maxim2c_video_pipe_data_init);
+
+int maxim2c_video_pipe_hw_init(maxim2c_t *maxim2c)
+{
+	struct device *dev = &maxim2c->client->dev;
+	u8 pipe_enable_mask = 0;
+	int ret = 0;
+
+	ret = maxim2c_video_pipe_select(maxim2c);
+	if (ret) {
+		dev_err(dev, "%s: video pipe select error\n", __func__);
+		return ret;
+	}
+
+	pipe_enable_mask = maxim2c->video_pipe.pipe_enable_mask;
+	ret = maxim2c_video_pipe_mask_enable(maxim2c, pipe_enable_mask, true);
+	if (ret) {
+		dev_err(dev, "%s: video pipe mask enable error\n", __func__);
+		return ret;
+	}
+
+	ret = maxim2c_video_pipe_run_init_seq(maxim2c);
+	if (ret) {
+		dev_err(dev, "%s: video pipe run init seq error\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim2c_video_pipe_hw_init);
diff --git a/kernel/drivers/media/i2c/maxim2c/maxim2c_video_pipe.h b/kernel/drivers/media/i2c/maxim2c/maxim2c_video_pipe.h
new file mode 100644
index 0000000..d7b149c
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/maxim2c_video_pipe.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+#ifndef __MAXIM2C_VIDEO_PIPE_H__
+#define __MAXIM2C_VIDEO_PIPE_H__
+
+#include "maxim2c_i2c.h"
+
+/* Video Pipe In ID: 0 ~ 3 */
+enum {
+	MAXIM2C_PIPE_I_ID_X = 0,
+	MAXIM2C_PIPE_I_ID_Y,
+	MAXIM2C_PIPE_I_ID_Z,
+	MAXIM2C_PIPE_I_ID_U,
+	MAXIM2C_PIPE_I_ID_MAX,
+};
+
+/* Video Pipe Out ID: 0 ~ 1 */
+enum {
+	MAXIM2C_PIPE_O_ID_Y = 0,
+	MAXIM2C_PIPE_O_ID_Z,
+	MAXIM2C_PIPE_O_ID_MAX,
+};
+
+/* Video Pipe Out Config */
+struct maxim2c_pipe_cfg {
+	u8 pipe_enable;
+	u8 pipe_idx;
+	u8 link_idx;
+
+	struct maxim2c_i2c_init_seq pipe_init_seq;
+};
+
+typedef struct maxim2c_video_pipe {
+	u8 pipe_enable_mask;
+
+	struct maxim2c_pipe_cfg pipe_cfg[MAXIM2C_PIPE_O_ID_MAX];
+	struct maxim2c_i2c_init_seq parallel_init_seq;
+} maxim2c_video_pipe_t;
+
+#endif /* __MAXIM2C_VIDEO_PIPE_H__ */
diff --git a/kernel/drivers/media/i2c/maxim2c/remote_max9295.c b/kernel/drivers/media/i2c/maxim2c/remote_max9295.c
new file mode 100644
index 0000000..0ae8a1c
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/remote_max9295.c
@@ -0,0 +1,331 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim Dual GMSL2/GMSL1 to CSI-2 Serializer driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * Author: Cai Wenzhong <cwz@rock-chips.com>
+ *
+ */
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#include "maxim2c_api.h"
+
+#define MAX9295_I2C_ADDR_DEF		0x40
+
+#define MAX9295_CHIP_ID			0x91
+#define MAX9295_REG_CHIP_ID		0x0D
+
+static int max9295_i2c_addr_remap(maxim2c_remote_t *max9295)
+{
+	struct device *dev = max9295->dev;
+	struct i2c_client *client = max9295->client;
+	u16 i2c_8bit_addr = 0;
+	int ret = 0;
+
+	if (max9295->ser_i2c_addr_map) {
+		dev_info(dev, "Serializer i2c address remap\n");
+
+		maxim2c_remote_i2c_addr_select(max9295, MAXIM2C_I2C_SER_DEF);
+
+		i2c_8bit_addr = (max9295->ser_i2c_addr_map << 1);
+		ret = maxim2c_i2c_write_byte(client,
+				0x0000, MAXIM2C_I2C_REG_ADDR_16BITS,
+				i2c_8bit_addr);
+		if (ret) {
+			dev_err(dev, "ser i2c address map setting error!\n");
+			return ret;
+		}
+
+		maxim2c_remote_i2c_addr_select(max9295, MAXIM2C_I2C_SER_MAP);
+	}
+
+	if (max9295->cam_i2c_addr_map) {
+		dev_info(dev, "Camera i2c address remap\n");
+
+		i2c_8bit_addr = (max9295->cam_i2c_addr_map << 1);
+		ret = maxim2c_i2c_write_byte(client,
+				0x0042, MAXIM2C_I2C_REG_ADDR_16BITS,
+				i2c_8bit_addr);
+		if (ret) {
+			dev_err(dev, "cam i2c address source setting error!\n");
+			return ret;
+		}
+
+		i2c_8bit_addr = (max9295->cam_i2c_addr_def << 1);
+		ret = maxim2c_i2c_write_byte(client,
+				0x0043, MAXIM2C_I2C_REG_ADDR_16BITS,
+				i2c_8bit_addr);
+		if (ret) {
+			dev_err(dev, "cam i2c address destination setting error!\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int max9295_i2c_addr_def(maxim2c_remote_t *max9295)
+{
+	struct device *dev = max9295->dev;
+	struct i2c_client *client = max9295->client;
+	u16 i2c_8bit_addr = 0;
+	int ret = 0;
+
+	if (max9295->ser_i2c_addr_map) {
+		dev_info(dev, "Serializer i2c address def\n");
+
+		maxim2c_remote_i2c_addr_select(max9295, MAXIM2C_I2C_SER_MAP);
+
+		i2c_8bit_addr = (max9295->ser_i2c_addr_def << 1);
+		ret = maxim2c_i2c_write_byte(client,
+				0x0000, MAXIM2C_I2C_REG_ADDR_16BITS,
+				i2c_8bit_addr);
+		if (ret) {
+			dev_err(dev, "ser i2c address def setting error!\n");
+			return ret;
+		}
+
+		maxim2c_remote_i2c_addr_select(max9295, MAXIM2C_I2C_SER_DEF);
+	}
+
+	return 0;
+}
+
+static int max9295_check_chipid(maxim2c_remote_t *max9295)
+{
+	struct device *dev = max9295->dev;
+	struct i2c_client *client = max9295->client;
+	u8 chip_id;
+	int ret = 0;
+
+	// max9295
+	ret = maxim2c_i2c_read_byte(client,
+			MAX9295_REG_CHIP_ID, MAXIM2C_I2C_REG_ADDR_16BITS,
+			&chip_id);
+	if (ret != 0) {
+		dev_info(dev, "Retry check chipid using map address\n");
+		maxim2c_remote_i2c_addr_select(max9295, MAXIM2C_I2C_SER_MAP);
+		ret = maxim2c_i2c_read_byte(client,
+				MAX9295_REG_CHIP_ID, MAXIM2C_I2C_REG_ADDR_16BITS,
+				&chip_id);
+		if (ret != 0) {
+			dev_err(dev, "MAX9295 detect error, ret(%d)\n", ret);
+			maxim2c_remote_i2c_addr_select(max9295, MAXIM2C_I2C_SER_DEF);
+
+			return -ENODEV;
+		}
+
+		max9295_i2c_addr_def(max9295);
+	}
+
+	if (chip_id != MAX9295_CHIP_ID) {
+		dev_err(dev, "Unexpected chip id = %02x\n", chip_id);
+		return -ENODEV;
+	}
+
+	dev_info(dev, "Detected MAX9295 chip id: 0x%02x\n", chip_id);
+
+	return 0;
+}
+
+static int max9295_soft_power_down(maxim2c_remote_t *max9295)
+{
+	struct device *dev = max9295->dev;
+	struct i2c_client *client = max9295->client;
+	int ret = 0;
+
+	ret = maxim2c_i2c_write_byte(client,
+			0x10, MAXIM2C_I2C_REG_ADDR_16BITS,
+			BIT(7));
+	if (ret) {
+		dev_err(dev, "soft power down setting error!\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int max9295_module_init(maxim2c_remote_t *max9295)
+{
+	struct device *dev = max9295->dev;
+	struct i2c_client *client = max9295->client;
+	int ret = 0;
+
+	ret = maxim2c_remote_i2c_addr_select(max9295, MAXIM2C_I2C_SER_DEF);
+	if (ret)
+		return ret;
+
+	ret = max9295_check_chipid(max9295);
+	if (ret)
+		return ret;
+
+	ret = max9295_i2c_addr_remap(max9295);
+	if (ret)
+		return ret;
+
+	ret = maxim2c_i2c_run_init_seq(client,
+			&max9295->remote_init_seq);
+	if (ret) {
+		dev_err(dev, "remote id = %d init sequence error\n",
+				max9295->remote_id);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int max9295_module_deinit(maxim2c_remote_t *max9295)
+{
+	int ret = 0;
+
+#if 0
+	ret |= max9295_i2c_addr_def(max9295);
+#endif
+	ret |= max9295_soft_power_down(max9295);
+
+	return ret;
+}
+
+static const struct maxim2c_remote_ops max9295_ops = {
+	.remote_init = max9295_module_init,
+	.remote_deinit = max9295_module_deinit,
+};
+
+static int max9295_parse_dt(maxim2c_remote_t *max9295)
+{
+	struct device *dev = max9295->dev;
+	struct device_node *of_node = dev->of_node;
+	u32 value = 0;
+	int ret = 0;
+
+	dev_info(dev, "=== maxim2c remote max9295 parse dt ===\n");
+
+	ret = of_property_read_u32(of_node, "remote-id", &value);
+	if (ret == 0) {
+		dev_info(dev, "remote-id property: %d\n", value);
+		max9295->remote_id = value;
+	} else {
+		max9295->remote_id = MAXIM2C_LINK_ID_MAX;
+	}
+
+	dev_info(dev, "max9295 remote id: %d\n", max9295->remote_id);
+
+	ret = of_property_read_u32(of_node, "ser-i2c-addr-def", &value);
+	if (ret == 0) {
+		dev_info(dev, "ser-i2c-addr-def property: 0x%x", value);
+		max9295->ser_i2c_addr_def = value;
+	} else {
+		max9295->ser_i2c_addr_def = MAX9295_I2C_ADDR_DEF;
+	}
+
+	ret = of_property_read_u32(of_node, "ser-i2c-addr-map", &value);
+	if (ret == 0) {
+		dev_info(dev, "ser-i2c-addr-map property: 0x%x", value);
+		max9295->ser_i2c_addr_map = value;
+	}
+
+	ret = of_property_read_u32(of_node, "cam-i2c-addr-def", &value);
+	if (ret == 0) {
+		dev_info(dev, "cam-i2c-addr-def property: 0x%x", value);
+		max9295->cam_i2c_addr_def = value;
+	}
+
+	ret = of_property_read_u32(of_node, "cam-i2c-addr-map", &value);
+	if (ret == 0) {
+		dev_info(dev, "cam-i2c-addr-map property: 0x%x", value);
+		max9295->cam_i2c_addr_map = value;
+	}
+
+	return 0;
+}
+
+static int max9295_probe(struct platform_device *pdev)
+{
+	struct i2c_client *client = to_i2c_client(pdev->dev.parent);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+	struct maxim2c_remote *max9295 = NULL;
+	u32 link_id = MAXIM2C_LINK_ID_MAX;
+	int ret = 0;
+
+	dev_info(&pdev->dev, "max9295 serializer probe\n");
+
+	link_id = (uintptr_t)of_device_get_match_data(&pdev->dev);
+	link_id = link_id - MAXIM2C_LINK_ID_MAX;
+	if (link_id >= MAXIM2C_LINK_ID_MAX) {
+		dev_err(&pdev->dev, "max9295 probe match data error\n");
+		return -EINVAL;
+	}
+	dev_info(&pdev->dev, "max9295 probe link id = %d\n", link_id);
+
+	max9295 = devm_kzalloc(&pdev->dev, sizeof(*max9295), GFP_KERNEL);
+	if (!max9295) {
+		dev_err(&pdev->dev, "max9295 probe no memory error\n");
+		return -ENOMEM;
+	}
+
+	max9295->dev = &pdev->dev;
+	max9295->remote_ops = &max9295_ops;
+	max9295->local = maxim2c;
+	dev_set_drvdata(max9295->dev, max9295);
+
+	max9295_parse_dt(max9295);
+
+	if (max9295->remote_id != link_id) {
+		dev_err(&pdev->dev, "max9295 probe remote_id error\n");
+		return -EINVAL;
+	}
+
+	ret = maxim2c_remote_i2c_client_init(max9295, client);
+	if (ret) {
+		dev_err(&pdev->dev, "remote i2c client init error\n");
+		return ret;
+	}
+
+	ret = maxim2c_remote_device_register(maxim2c, max9295);
+	if (ret) {
+		dev_err(&pdev->dev, "remote serializer register error\n");
+		return ret;
+	}
+
+	maxim2c_remote_load_init_seq(max9295);
+
+	return 0;
+}
+
+static int max9295_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static const struct of_device_id max9295_of_table[] = {
+	{
+		.compatible = "maxim2c,link0,max9295",
+		.data = (const void *)(MAXIM2C_LINK_ID_MAX + MAXIM2C_LINK_ID_A)
+	}, {
+		.compatible = "maxim2c,link1,max9295",
+		.data = (const void *)(MAXIM2C_LINK_ID_MAX + MAXIM2C_LINK_ID_B)
+	},
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, max9295_of_table);
+
+static struct platform_driver max9295_driver = {
+	.probe		= max9295_probe,
+	.remove		= max9295_remove,
+	.driver		= {
+		.name	= "maxim2c-max9295",
+		.of_match_table = max9295_of_table,
+	},
+};
+
+module_platform_driver(max9295_driver);
+
+MODULE_AUTHOR("Cai Wenzhong <cwz@rock-chips.com>");
+MODULE_DESCRIPTION("Maxim MAX9295 Serializer Driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/maxim2c/remote_max96715.c b/kernel/drivers/media/i2c/maxim2c/remote_max96715.c
new file mode 100644
index 0000000..d1c4373
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/remote_max96715.c
@@ -0,0 +1,381 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim Dual GMSL2/GMSL1 to CSI-2 Serializer driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * Author: Cai Wenzhong <cwz@rock-chips.com>
+ *
+ */
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#include "maxim2c_api.h"
+
+#define MAX96715_I2C_ADDR_DEF		0x40
+
+#define MAX96715_CHIP_ID		0x45
+#define MAX96715_REG_CHIP_ID		0x1E
+
+/* Config and Video mode switch */
+#define MAX96715_MODE_SWITCH		1
+
+enum {
+	LINK_MODE_VIDEO = 0,
+	LINK_MODE_CONFIG,
+};
+
+static int __maybe_unused max96715_link_mode_select(maxim2c_remote_t *max96715, u32 mode)
+{
+	struct device *dev = max96715->dev;
+	struct i2c_client *client = max96715->client;
+	u8 reg_mask = 0, reg_value = 0;
+	u32 delay_ms = 0;
+	int ret = 0;
+
+	dev_dbg(dev, "%s: mode = %d\n", __func__, mode);
+
+	reg_mask = BIT(7) | BIT(6);
+	if (mode == LINK_MODE_CONFIG) {
+		reg_value = BIT(6);
+		delay_ms = 5;
+	} else {
+		reg_value = BIT(7);
+		delay_ms = 50;
+	}
+	ret |= maxim2c_i2c_update_byte(client,
+			0x04, MAXIM2C_I2C_REG_ADDR_08BITS,
+			reg_mask, reg_value);
+
+	msleep(delay_ms);
+
+	return ret;
+}
+
+static int max96715_i2c_addr_remap(maxim2c_remote_t *max96715)
+{
+	struct device *dev = max96715->dev;
+	struct i2c_client *client = max96715->client;
+	u16 i2c_8bit_addr = 0;
+	int ret = 0;
+
+	if (max96715->ser_i2c_addr_map) {
+		dev_info(dev, "Serializer i2c address remap\n");
+
+		maxim2c_remote_i2c_addr_select(max96715, MAXIM2C_I2C_SER_DEF);
+
+		i2c_8bit_addr = (max96715->ser_i2c_addr_map << 1);
+		ret = maxim2c_i2c_write_byte(client,
+				0x00, MAXIM2C_I2C_REG_ADDR_08BITS,
+				i2c_8bit_addr);
+		if (ret) {
+			dev_err(dev, "ser i2c address map setting error!\n");
+			return ret;
+		}
+
+		maxim2c_remote_i2c_addr_select(max96715, MAXIM2C_I2C_SER_MAP);
+	}
+
+	if (max96715->cam_i2c_addr_map) {
+		dev_info(dev, "Camera i2c address remap\n");
+
+		i2c_8bit_addr = (max96715->cam_i2c_addr_map << 1);
+		ret = maxim2c_i2c_write_byte(client,
+				0x09, MAXIM2C_I2C_REG_ADDR_08BITS,
+				i2c_8bit_addr);
+		if (ret) {
+			dev_err(dev, "cam i2c address source setting error!\n");
+			return ret;
+		}
+
+		i2c_8bit_addr = (max96715->cam_i2c_addr_def << 1);
+		ret = maxim2c_i2c_write_byte(client,
+				0x0A, MAXIM2C_I2C_REG_ADDR_08BITS,
+				i2c_8bit_addr);
+		if (ret) {
+			dev_err(dev, "cam i2c address destination setting error!\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int max96715_i2c_addr_def(maxim2c_remote_t *max96715)
+{
+	struct device *dev = max96715->dev;
+	struct i2c_client *client = max96715->client;
+	u16 i2c_8bit_addr = 0;
+	int ret = 0;
+
+	if (max96715->ser_i2c_addr_map) {
+		dev_info(dev, "Serializer i2c address def\n");
+
+		maxim2c_remote_i2c_addr_select(max96715, MAXIM2C_I2C_SER_MAP);
+
+		i2c_8bit_addr = (max96715->ser_i2c_addr_def << 1);
+		ret = maxim2c_i2c_write_byte(client,
+				0x00, MAXIM2C_I2C_REG_ADDR_08BITS,
+				i2c_8bit_addr);
+		if (ret) {
+			dev_err(dev, "ser i2c address def setting error!\n");
+			return ret;
+		}
+
+		maxim2c_remote_i2c_addr_select(max96715, MAXIM2C_I2C_SER_DEF);
+	}
+
+	return 0;
+}
+
+static int max96715_check_chipid(maxim2c_remote_t *max96715)
+{
+	struct device *dev = max96715->dev;
+	struct i2c_client *client = max96715->client;
+	u8 chip_id;
+	int ret = 0;
+
+	// max96715
+	ret = maxim2c_i2c_read_byte(client,
+			MAX96715_REG_CHIP_ID, MAXIM2C_I2C_REG_ADDR_08BITS,
+			&chip_id);
+	if (ret != 0) {
+		dev_info(dev, "Retry check chipid using map address\n");
+		maxim2c_remote_i2c_addr_select(max96715, MAXIM2C_I2C_SER_MAP);
+		ret = maxim2c_i2c_read_byte(client,
+				MAX96715_REG_CHIP_ID, MAXIM2C_I2C_REG_ADDR_08BITS,
+				&chip_id);
+		if (ret != 0) {
+			dev_err(dev, "MAX96715 detect error, ret(%d)\n", ret);
+			maxim2c_remote_i2c_addr_select(max96715, MAXIM2C_I2C_SER_DEF);
+
+			return -ENODEV;
+		}
+
+		max96715_i2c_addr_def(max96715);
+	}
+
+	if (chip_id != MAX96715_CHIP_ID) {
+		dev_err(dev, "Unexpected chip id = %02x\n", chip_id);
+		return -ENODEV;
+	}
+
+	dev_info(dev, "Detected MAX96715 chip id: 0x%02x\n", chip_id);
+
+	return 0;
+}
+
+static int max96715_soft_power_down(maxim2c_remote_t *max96715)
+{
+	struct device *dev = max96715->dev;
+	struct i2c_client *client = max96715->client;
+	int ret = 0;
+
+	ret = maxim2c_i2c_write_byte(client,
+			0x13, MAXIM2C_I2C_REG_ADDR_08BITS,
+			BIT(7));
+	if (ret) {
+		dev_err(dev, "soft power down setting error!\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int max96715_module_init(maxim2c_remote_t *max96715)
+{
+	struct device *dev = max96715->dev;
+	struct i2c_client *client = max96715->client;
+	int ret = 0;
+
+	ret = maxim2c_remote_i2c_addr_select(max96715, MAXIM2C_I2C_SER_DEF);
+	if (ret)
+		return ret;
+
+	ret = max96715_check_chipid(max96715);
+	if (ret)
+		return ret;
+
+	ret = max96715_i2c_addr_remap(max96715);
+	if (ret)
+		return ret;
+
+#if MAX96715_MODE_SWITCH
+	ret = max96715_link_mode_select(max96715, LINK_MODE_CONFIG);
+	if (ret)
+		return ret;
+#endif
+
+	ret = maxim2c_i2c_run_init_seq(client,
+			&max96715->remote_init_seq);
+
+	if (ret) {
+		dev_err(dev, "remote id = %d init sequence error\n",
+				max96715->remote_id);
+
+		return ret;
+	}
+
+#if MAX96715_MODE_SWITCH
+	ret = max96715_link_mode_select(max96715, LINK_MODE_VIDEO);
+	if (ret)
+		return ret;
+#endif
+
+	return 0;
+}
+
+static int max96715_module_deinit(maxim2c_remote_t *max96715)
+{
+	int ret = 0;
+
+#if 0
+	ret |= max96715_i2c_addr_def(max96715);
+#endif
+	ret |= max96715_soft_power_down(max96715);
+
+	return ret;
+}
+
+static const struct maxim2c_remote_ops max96715_ops = {
+	.remote_init = max96715_module_init,
+	.remote_deinit = max96715_module_deinit,
+};
+
+static int max96715_parse_dt(maxim2c_remote_t *max96715)
+{
+	struct device *dev = max96715->dev;
+	struct device_node *of_node = dev->of_node;
+	u32 value = 0;
+	int ret = 0;
+
+	dev_info(dev, "=== maxim2c remote max96715 parse dt ===\n");
+
+	ret = of_property_read_u32(of_node, "remote-id", &value);
+	if (ret == 0) {
+		dev_info(dev, "remote-id property: %d\n", value);
+		max96715->remote_id = value;
+	} else {
+		max96715->remote_id = MAXIM2C_LINK_ID_MAX;
+	}
+
+	dev_info(dev, "max96715 remote id: %d\n", max96715->remote_id);
+
+	ret = of_property_read_u32(of_node, "ser-i2c-addr-def", &value);
+	if (ret == 0) {
+		dev_info(dev, "ser-i2c-addr-def property: 0x%x", value);
+		max96715->ser_i2c_addr_def = value;
+	} else {
+		max96715->ser_i2c_addr_def = MAX96715_I2C_ADDR_DEF;
+	}
+
+	ret = of_property_read_u32(of_node, "ser-i2c-addr-map", &value);
+	if (ret == 0) {
+		dev_info(dev, "ser-i2c-addr-map property: 0x%x", value);
+		max96715->ser_i2c_addr_map = value;
+	}
+
+	ret = of_property_read_u32(of_node, "cam-i2c-addr-def", &value);
+	if (ret == 0) {
+		dev_info(dev, "cam-i2c-addr-def property: 0x%x", value);
+		max96715->cam_i2c_addr_def = value;
+	}
+
+	ret = of_property_read_u32(of_node, "cam-i2c-addr-map", &value);
+	if (ret == 0) {
+		dev_info(dev, "cam-i2c-addr-map property: 0x%x", value);
+		max96715->cam_i2c_addr_map = value;
+	}
+
+	return 0;
+}
+
+static int max96715_probe(struct platform_device *pdev)
+{
+	struct i2c_client *client = to_i2c_client(pdev->dev.parent);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+	struct maxim2c_remote *max96715 = NULL;
+	u32 link_id = MAXIM2C_LINK_ID_MAX;
+	int ret = 0;
+
+	dev_info(&pdev->dev, "max96715 serializer probe\n");
+
+	link_id = (uintptr_t)of_device_get_match_data(&pdev->dev);
+	link_id = link_id - MAXIM2C_LINK_ID_MAX;
+	if (link_id >= MAXIM2C_LINK_ID_MAX) {
+		dev_err(&pdev->dev, "max96715 probe match data error\n");
+		return -EINVAL;
+	}
+	dev_info(&pdev->dev, "max96715 probe link id = %d\n", link_id);
+
+	max96715 = devm_kzalloc(&pdev->dev, sizeof(*max96715), GFP_KERNEL);
+	if (!max96715) {
+		dev_err(&pdev->dev, "max96715 probe no memory error\n");
+		return -ENOMEM;
+	}
+
+	max96715->dev = &pdev->dev;
+	max96715->remote_ops = &max96715_ops;
+	max96715->local = maxim2c;
+	dev_set_drvdata(max96715->dev, max96715);
+
+	max96715_parse_dt(max96715);
+
+	if (max96715->remote_id != link_id) {
+		dev_err(&pdev->dev, "max96715 probe remote_id error\n");
+		return -EINVAL;
+	}
+
+	ret = maxim2c_remote_i2c_client_init(max96715, client);
+	if (ret) {
+		dev_err(&pdev->dev, "remote i2c client init error\n");
+		return ret;
+	}
+
+	ret = maxim2c_remote_device_register(maxim2c, max96715);
+	if (ret) {
+		dev_err(&pdev->dev, "remote serializer register error\n");
+		return ret;
+	}
+
+	maxim2c_remote_load_init_seq(max96715);
+
+	return 0;
+}
+
+static int max96715_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static const struct of_device_id max96715_of_table[] = {
+	{
+		.compatible = "maxim2c,link0,max96715",
+		.data = (const void *)(MAXIM2C_LINK_ID_MAX + MAXIM2C_LINK_ID_A)
+	}, {
+		.compatible = "maxim2c,link1,max96715",
+		.data = (const void *)(MAXIM2C_LINK_ID_MAX + MAXIM2C_LINK_ID_B)
+	},
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, max96715_of_table);
+
+static struct platform_driver max96715_driver = {
+	.probe		= max96715_probe,
+	.remove		= max96715_remove,
+	.driver		= {
+		.name	= "maxim2c-max96715",
+		.of_match_table = max96715_of_table,
+	},
+};
+
+module_platform_driver(max96715_driver);
+
+MODULE_AUTHOR("Cai Wenzhong <cwz@rock-chips.com>");
+MODULE_DESCRIPTION("Maxim MAX96715 Serializer Driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/maxim2c/remote_max96717.c b/kernel/drivers/media/i2c/maxim2c/remote_max96717.c
new file mode 100644
index 0000000..6e7fb9d
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim2c/remote_max96717.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim Dual GMSL2/GMSL1 to CSI-2 Serializer driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * Author: Cai Wenzhong <cwz@rock-chips.com>
+ *
+ */
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#include "maxim2c_api.h"
+
+#define MAX96717_I2C_ADDR_DEF		0x40
+
+#define MAX96717_CHIP_ID		0xBF
+#define MAX96717_REG_CHIP_ID		0x0D
+
+static int max96717_i2c_addr_remap(maxim2c_remote_t *max96717)
+{
+	struct device *dev = max96717->dev;
+	struct i2c_client *client = max96717->client;
+	u16 i2c_8bit_addr = 0;
+	int ret = 0;
+
+	if (max96717->ser_i2c_addr_map) {
+		dev_info(dev, "Serializer i2c address remap\n");
+
+		maxim2c_remote_i2c_addr_select(max96717, MAXIM2C_I2C_SER_DEF);
+
+		i2c_8bit_addr = (max96717->ser_i2c_addr_map << 1);
+		ret = maxim2c_i2c_write_byte(client,
+				0x0000, MAXIM2C_I2C_REG_ADDR_16BITS,
+				i2c_8bit_addr);
+		if (ret) {
+			dev_err(dev, "ser i2c address map setting error!\n");
+			return ret;
+		}
+
+		maxim2c_remote_i2c_addr_select(max96717, MAXIM2C_I2C_SER_MAP);
+	}
+
+	if (max96717->cam_i2c_addr_map) {
+		dev_info(dev, "Camera i2c address remap\n");
+
+		i2c_8bit_addr = (max96717->cam_i2c_addr_map << 1);
+		ret = maxim2c_i2c_write_byte(client,
+				0x0042, MAXIM2C_I2C_REG_ADDR_16BITS,
+				i2c_8bit_addr);
+		if (ret) {
+			dev_err(dev, "cam i2c address source setting error!\n");
+			return ret;
+		}
+
+		i2c_8bit_addr = (max96717->cam_i2c_addr_def << 1);
+		ret = maxim2c_i2c_write_byte(client,
+				0x0043, MAXIM2C_I2C_REG_ADDR_16BITS,
+				i2c_8bit_addr);
+		if (ret) {
+			dev_err(dev, "cam i2c address destination setting error!\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int max96717_i2c_addr_def(maxim2c_remote_t *max96717)
+{
+	struct device *dev = max96717->dev;
+	struct i2c_client *client = max96717->client;
+	u16 i2c_8bit_addr = 0;
+	int ret = 0;
+
+	if (max96717->ser_i2c_addr_map) {
+		dev_info(dev, "Serializer i2c address def\n");
+
+		maxim2c_remote_i2c_addr_select(max96717, MAXIM2C_I2C_SER_MAP);
+
+		i2c_8bit_addr = (max96717->ser_i2c_addr_def << 1);
+		ret = maxim2c_i2c_write_byte(client,
+				0x0000, MAXIM2C_I2C_REG_ADDR_16BITS,
+				i2c_8bit_addr);
+		if (ret) {
+			dev_err(dev, "ser i2c address def setting error!\n");
+			return ret;
+		}
+
+		maxim2c_remote_i2c_addr_select(max96717, MAXIM2C_I2C_SER_DEF);
+	}
+
+	return 0;
+}
+
+static int max96717_check_chipid(maxim2c_remote_t *max96717)
+{
+	struct device *dev = max96717->dev;
+	struct i2c_client *client = max96717->client;
+	u8 chip_id;
+	int ret = 0;
+
+	// max96717
+	ret = maxim2c_i2c_read_byte(client,
+			MAX96717_REG_CHIP_ID, MAXIM2C_I2C_REG_ADDR_16BITS,
+			&chip_id);
+	if (ret != 0) {
+		dev_info(dev, "Retry check chipid using map address\n");
+		maxim2c_remote_i2c_addr_select(max96717, MAXIM2C_I2C_SER_MAP);
+		ret = maxim2c_i2c_read_byte(client,
+				MAX96717_REG_CHIP_ID, MAXIM2C_I2C_REG_ADDR_16BITS,
+				&chip_id);
+		if (ret != 0) {
+			dev_err(dev, "MAX96717 detect error, ret(%d)\n", ret);
+			maxim2c_remote_i2c_addr_select(max96717, MAXIM2C_I2C_SER_DEF);
+
+			return -ENODEV;
+		}
+
+		max96717_i2c_addr_def(max96717);
+	}
+
+	if (chip_id != MAX96717_CHIP_ID) {
+		dev_err(dev, "Unexpected chip id = %02x\n", chip_id);
+		return -ENODEV;
+	}
+	dev_info(dev, "Detected MAX96717 chip id: 0x%02x\n", chip_id);
+
+	return 0;
+}
+
+static int max96717_module_init(maxim2c_remote_t *max96717)
+{
+	struct device *dev = max96717->dev;
+	struct i2c_client *client = max96717->client;
+	int ret = 0;
+
+	ret = maxim2c_remote_i2c_addr_select(max96717, MAXIM2C_I2C_SER_DEF);
+	if (ret)
+		return ret;
+
+	ret = max96717_check_chipid(max96717);
+	if (ret)
+		return ret;
+
+	ret = max96717_i2c_addr_remap(max96717);
+	if (ret)
+		return ret;
+
+	ret = maxim2c_i2c_run_init_seq(client,
+			&max96717->remote_init_seq);
+	if (ret) {
+		dev_err(dev, "remote id = %d init sequence error\n",
+				max96717->remote_id);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int max96717_module_deinit(maxim2c_remote_t *max96717)
+{
+	int ret = 0;
+
+	ret |= max96717_i2c_addr_def(max96717);
+
+	return ret;
+}
+
+static const struct maxim2c_remote_ops max96717_ops = {
+	.remote_init = max96717_module_init,
+	.remote_deinit = max96717_module_deinit,
+};
+
+static int max96717_parse_dt(maxim2c_remote_t *max96717)
+{
+	struct device *dev = max96717->dev;
+	struct device_node *of_node = dev->of_node;
+	u32 value = 0;
+	int ret = 0;
+
+	dev_info(dev, "=== maxim2c remote max96717 parse dt ===\n");
+
+	ret = of_property_read_u32(of_node, "remote-id", &value);
+	if (ret == 0) {
+		dev_info(dev, "remote-id property: %d\n", value);
+		max96717->remote_id = value;
+	} else {
+		max96717->remote_id = MAXIM2C_LINK_ID_MAX;
+	}
+
+	dev_info(dev, "max96717 remote id: %d\n", max96717->remote_id);
+
+	ret = of_property_read_u32(of_node, "ser-i2c-addr-def", &value);
+	if (ret == 0) {
+		dev_info(dev, "ser-i2c-addr-def property: 0x%x", value);
+		max96717->ser_i2c_addr_def = value;
+	} else {
+		max96717->ser_i2c_addr_def = MAX96717_I2C_ADDR_DEF;
+	}
+
+	ret = of_property_read_u32(of_node, "ser-i2c-addr-map", &value);
+	if (ret == 0) {
+		dev_info(dev, "ser-i2c-addr-map property: 0x%x", value);
+		max96717->ser_i2c_addr_map = value;
+	}
+
+	ret = of_property_read_u32(of_node, "cam-i2c-addr-def", &value);
+	if (ret == 0) {
+		dev_info(dev, "cam-i2c-addr-def property: 0x%x", value);
+		max96717->cam_i2c_addr_def = value;
+	}
+
+	ret = of_property_read_u32(of_node, "cam-i2c-addr-map", &value);
+	if (ret == 0) {
+		dev_info(dev, "cam-i2c-addr-map property: 0x%x", value);
+		max96717->cam_i2c_addr_map = value;
+	}
+
+	return 0;
+}
+
+static int max96717_probe(struct platform_device *pdev)
+{
+	struct i2c_client *client = to_i2c_client(pdev->dev.parent);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct maxim2c *maxim2c = v4l2_get_subdevdata(sd);
+	struct maxim2c_remote *max96717 = NULL;
+	u32 link_id = MAXIM2C_LINK_ID_MAX;
+	int ret = 0;
+
+	dev_info(&pdev->dev, "max96717 serializer probe\n");
+
+	link_id = (uintptr_t)of_device_get_match_data(&pdev->dev);
+	link_id = link_id - MAXIM2C_LINK_ID_MAX;
+	if (link_id >= MAXIM2C_LINK_ID_MAX) {
+		dev_err(&pdev->dev, "max96717 probe match data error\n");
+		return -EINVAL;
+	}
+	dev_info(&pdev->dev, "max96717 probe link id = %d\n", link_id);
+
+	max96717 = devm_kzalloc(&pdev->dev, sizeof(*max96717), GFP_KERNEL);
+	if (!max96717) {
+		dev_err(&pdev->dev, "max96717 probe no memory error\n");
+		return -ENOMEM;
+	}
+
+	max96717->dev = &pdev->dev;
+	max96717->remote_ops = &max96717_ops;
+	max96717->local = maxim2c;
+	dev_set_drvdata(max96717->dev, max96717);
+
+	max96717_parse_dt(max96717);
+
+	if (max96717->remote_id != link_id) {
+		dev_err(&pdev->dev, "max96717 probe remote_id error\n");
+		return -EINVAL;
+	}
+
+	ret = maxim2c_remote_i2c_client_init(max96717, client);
+	if (ret) {
+		dev_err(&pdev->dev, "remote i2c client init error\n");
+		return ret;
+	}
+
+	ret = maxim2c_remote_device_register(maxim2c, max96717);
+	if (ret) {
+		dev_err(&pdev->dev, "remote serializer register error\n");
+		return ret;
+	}
+
+	maxim2c_remote_load_init_seq(max96717);
+
+	return 0;
+}
+
+static int max96717_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static const struct of_device_id max96717_of_table[] = {
+	{
+		.compatible = "maxim2c,link0,max96717",
+		.data = (const void *)(MAXIM2C_LINK_ID_MAX + MAXIM2C_LINK_ID_A)
+	}, {
+		.compatible = "maxim2c,link1,max96717",
+		.data = (const void *)(MAXIM2C_LINK_ID_MAX + MAXIM2C_LINK_ID_B)
+	},
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, max96717_of_table);
+
+static struct platform_driver max96717_driver = {
+	.probe		= max96717_probe,
+	.remove		= max96717_remove,
+	.driver		= {
+		.name	= "maxim2c-max96717",
+		.of_match_table = max96717_of_table,
+	},
+};
+
+module_platform_driver(max96717_driver);
+
+MODULE_AUTHOR("Cai Wenzhong <cwz@rock-chips.com>");
+MODULE_DESCRIPTION("Maxim MAX96717 Serializer Driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/maxim4c/Makefile b/kernel/drivers/media/i2c/maxim4c/Makefile
index f1ee630..665a866 100644
--- a/kernel/drivers/media/i2c/maxim4c/Makefile
+++ b/kernel/drivers/media/i2c/maxim4c/Makefile
@@ -7,7 +7,8 @@
 		   maxim4c_remote.o \
 		   maxim4c_pattern.o \
 		   maxim4c_v4l2.o \
-		   maxim4c_drv.o
+		   maxim4c_drv.o \
+		   maxim4c_debugfs.o
 
 obj-$(CONFIG_MAXIM4C_SER_MAX9295)	+= remote_max9295.o
 obj-$(CONFIG_MAXIM4C_SER_MAX96715)	+= remote_max96715.o
diff --git a/kernel/drivers/media/i2c/maxim4c/maxim4c_api.h b/kernel/drivers/media/i2c/maxim4c/maxim4c_api.h
index 6dd3bbc..a2968a3 100644
--- a/kernel/drivers/media/i2c/maxim4c/maxim4c_api.h
+++ b/kernel/drivers/media/i2c/maxim4c/maxim4c_api.h
@@ -90,7 +90,9 @@
 int maxim4c_v4l2_subdev_init(maxim4c_t *maxim4c);
 void maxim4c_v4l2_subdev_deinit(maxim4c_t *maxim4c);
 
+/* maxim4c driver api */
 int maxim4c_module_hw_init(maxim4c_t *maxim4c);
+int maxim4c_hot_plug_detect_work_start(maxim4c_t *maxim4c);
 
 /* maxim4c pattern api */
 int maxim4c_pattern_hw_init(maxim4c_t *maxim4c);
@@ -98,4 +100,7 @@
 int maxim4c_pattern_data_init(maxim4c_t *maxim4c);
 int maxim4c_pattern_enable(maxim4c_t *maxim4c, bool enable);
 
+int maxim4c_dbgfs_init(maxim4c_t *maxim4c);
+void maxim4c_dbgfs_deinit(maxim4c_t *maxim4c);
+
 #endif /* __MAXIM4C_API_H__ */
diff --git a/kernel/drivers/media/i2c/maxim4c/maxim4c_debugfs.c b/kernel/drivers/media/i2c/maxim4c/maxim4c_debugfs.c
new file mode 100644
index 0000000..75dddd7
--- /dev/null
+++ b/kernel/drivers/media/i2c/maxim4c/maxim4c_debugfs.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim Quad GMSL Deserializer debugfs helper functions
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * Author: Cai Wenzhong <cwz@rock-chips.com>
+ *
+ */
+#include <linux/export.h>
+#include <linux/debugfs.h>
+
+#include "maxim4c_api.h"
+
+int maxim4c_dbgfs_init(maxim4c_t *maxim4c)
+{
+	struct dentry *entry;
+
+	entry = debugfs_create_dir("maxim4c", NULL);
+
+	debugfs_create_u8("timing_override_en", 0600, entry,
+			  &maxim4c->mipi_txphy.timing_override_en);
+
+	debugfs_create_u8("t_hs_przero", 0600, entry,
+			  &maxim4c->mipi_txphy.timing.t_hs_przero);
+	debugfs_create_u8("t_hs_prep", 0600, entry,
+			  &maxim4c->mipi_txphy.timing.t_hs_prep);
+	debugfs_create_u8("t_clk_trail", 0600, entry,
+			  &maxim4c->mipi_txphy.timing.t_clk_trail);
+	debugfs_create_u8("t_clk_przero", 0600, entry,
+			  &maxim4c->mipi_txphy.timing.t_clk_przero);
+	debugfs_create_u8("t_lpx", 0600, entry, &maxim4c->mipi_txphy.timing.t_lpx);
+	debugfs_create_u8("t_hs_trail", 0600, entry,
+			  &maxim4c->mipi_txphy.timing.t_hs_trail);
+
+	debugfs_create_u8("t_clk_prep", 0600, entry,
+			  &maxim4c->mipi_txphy.timing.t_clk_prep);
+	debugfs_create_u8("t_lpxesc", 0600, entry,
+			  &maxim4c->mipi_txphy.timing.t_lpxesc);
+
+	debugfs_create_u8("csi2_t_pre", 0600, entry,
+			  &maxim4c->mipi_txphy.timing.csi2_t_pre);
+	debugfs_create_u8("csi2_t_post", 0600, entry,
+			  &maxim4c->mipi_txphy.timing.csi2_t_post);
+	debugfs_create_u8("csi2_tx_gap", 0600, entry,
+			  &maxim4c->mipi_txphy.timing.csi2_tx_gap);
+	debugfs_create_u32("csi2_twakeup", 0600, entry,
+			  &maxim4c->mipi_txphy.timing.csi2_twakeup);
+
+	maxim4c->dbgfs_root = entry;
+
+	return 0;
+}
+EXPORT_SYMBOL(maxim4c_dbgfs_init);
+
+void maxim4c_dbgfs_deinit(maxim4c_t *maxim4c)
+{
+	debugfs_remove_recursive(maxim4c->dbgfs_root);
+}
+EXPORT_SYMBOL(maxim4c_dbgfs_deinit);
diff --git a/kernel/drivers/media/i2c/maxim4c/maxim4c_drv.c b/kernel/drivers/media/i2c/maxim4c/maxim4c_drv.c
index 88924dc..c543c62 100644
--- a/kernel/drivers/media/i2c/maxim4c/maxim4c_drv.c
+++ b/kernel/drivers/media/i2c/maxim4c/maxim4c_drv.c
@@ -22,6 +22,26 @@
  *     5. power control: local by pwdn gpio, remote by pocen gpio
  *     6. local pwdn on/off enable depend on MAXIM4C_LOCAL_DES_ON_OFF_EN
  *
+ * V2.02.00
+ *     1. Force all MIPI clocks running Setting in csi out enable.
+ *     2. Pattern mode force_clock_out_en default enable.
+ *
+ * V2.03.00
+ *     1. remote device add the maxim4c prefix to driver name.
+ *
+ * V2.04.04
+ *     1. Add regulator supplier dependencies.
+ *     2. Add config ssc-ratio property
+ *     3. Add debugfs entry to change MIPI timing
+ *     4. Use PM runtime autosuspend feature
+ *     5. Fix unbalanced disabling for PoC regulator
+ *     6. MIPI VC count does not affected by data lane count
+ *
+ * V2.05.00
+ *     1. local device power on add some delay for i2c normal access.
+ *     2. enable hot plug detect for partial links are locked.
+ *     3. remote device hot plug init disable lock irq.
+ *
  */
 #include <linux/clk.h>
 #include <linux/i2c.h>
@@ -51,9 +71,14 @@
 
 #include "maxim4c_api.h"
 
-#define DRIVER_VERSION			KERNEL_VERSION(2, 0x01, 0x00)
+#define DRIVER_VERSION			KERNEL_VERSION(2, 0x05, 0x00)
 
 #define MAXIM4C_XVCLK_FREQ		25000000
+
+static const char *const maxim4c_supply_names[MAXIM4C_NUM_SUPPLIES] = {
+	"vcc1v2",
+	"vcc1v8",
+};
 
 static int maxim4c_check_local_chipid(maxim4c_t *maxim4c)
 {
@@ -83,8 +108,8 @@
 					return 0;
 				}
 			} else {
+				// if chipid is unexpected, retry
 				dev_err(dev, "Unexpected maxim chipid = %02x\n", chipid);
-				return -ENODEV;
 			}
 		}
 	}
@@ -115,7 +140,7 @@
 
 		queue_delayed_work(maxim4c->hot_plug_work.state_check_wq,
 					&maxim4c->hot_plug_work.state_d_work,
-					msecs_to_jiffies(50));
+					msecs_to_jiffies(100));
 	}
 	mutex_unlock(&maxim4c->mutex);
 
@@ -189,7 +214,13 @@
 		if (curr_lock_state & MAXIM4C_LINK_MASK_A) {
 			dev_info(dev, "Link A plug in\n");
 
+			if (maxim4c->hot_plug_irq > 0)
+				disable_irq(maxim4c->hot_plug_irq);
+
 			maxim4c_remote_devices_init(maxim4c, MAXIM4C_LINK_MASK_A);
+
+			if (maxim4c->hot_plug_irq > 0)
+				enable_irq(maxim4c->hot_plug_irq);
 
 			maxim4c_video_pipe_linkid_enable(maxim4c, link_id, true);
 		} else {
@@ -205,7 +236,13 @@
 		if (curr_lock_state & MAXIM4C_LINK_MASK_B) {
 			dev_info(dev, "Link B plug in\n");
 
+			if (maxim4c->hot_plug_irq > 0)
+				disable_irq(maxim4c->hot_plug_irq);
+
 			maxim4c_remote_devices_init(maxim4c, MAXIM4C_LINK_MASK_B);
+
+			if (maxim4c->hot_plug_irq > 0)
+				enable_irq(maxim4c->hot_plug_irq);
 
 			maxim4c_video_pipe_linkid_enable(maxim4c, link_id, true);
 		} else {
@@ -221,7 +258,13 @@
 		if (curr_lock_state & MAXIM4C_LINK_MASK_C) {
 			dev_info(dev, "Link C plug in\n");
 
+			if (maxim4c->hot_plug_irq > 0)
+				disable_irq(maxim4c->hot_plug_irq);
+
 			maxim4c_remote_devices_init(maxim4c, MAXIM4C_LINK_MASK_C);
+
+			if (maxim4c->hot_plug_irq > 0)
+				enable_irq(maxim4c->hot_plug_irq);
 
 			maxim4c_video_pipe_linkid_enable(maxim4c, link_id, true);
 		} else {
@@ -237,7 +280,13 @@
 		if (curr_lock_state & MAXIM4C_LINK_MASK_D) {
 			dev_info(dev, "Link D plug in\n");
 
+			if (maxim4c->hot_plug_irq > 0)
+				disable_irq(maxim4c->hot_plug_irq);
+
 			maxim4c_remote_devices_init(maxim4c, MAXIM4C_LINK_MASK_D);
+
+			if (maxim4c->hot_plug_irq > 0)
+				enable_irq(maxim4c->hot_plug_irq);
 
 			maxim4c_video_pipe_linkid_enable(maxim4c, link_id, true);
 		} else {
@@ -253,10 +302,32 @@
 	} else {
 		queue_delayed_work(maxim4c->hot_plug_work.state_check_wq,
 				&maxim4c->hot_plug_work.state_d_work,
-				msecs_to_jiffies(100));
+				msecs_to_jiffies(200));
 	}
 
 	mutex_unlock(&maxim4c->mutex);
+}
+
+int maxim4c_hot_plug_detect_work_start(maxim4c_t *maxim4c)
+{
+	struct device *dev = &maxim4c->client->dev;
+	u8 link_lock_state = 0, link_enable_mask = 0;
+
+	link_lock_state = maxim4c->link_lock_state;
+	link_enable_mask = maxim4c->gmsl_link.link_enable_mask;
+
+	if (link_lock_state != link_enable_mask) {
+		dev_info(dev, "%s: link_lock = 0x%02x, link_mask = 0x%02x\n",
+			__func__, link_lock_state, link_enable_mask);
+
+		maxim4c->hot_plug_state = MAXIM4C_HOT_PLUG_OUT;
+
+		queue_delayed_work(maxim4c->hot_plug_work.state_check_wq,
+				&maxim4c->hot_plug_work.state_d_work,
+				msecs_to_jiffies(200));
+	}
+
+	return 0;
 }
 
 static int maxim4c_lock_state_work_init(maxim4c_t *maxim4c)
@@ -295,13 +366,20 @@
 static int maxim4c_local_device_power_on(maxim4c_t *maxim4c)
 {
 	struct device *dev = &maxim4c->client->dev;
+	int ret;
+
+	ret = regulator_bulk_enable(MAXIM4C_NUM_SUPPLIES, maxim4c->supplies);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable regulators\n");
+		return -EINVAL;
+	}
 
 	if (!IS_ERR(maxim4c->pwdn_gpio)) {
 		dev_info(dev, "local device pwdn gpio on\n");
 
 		gpiod_set_value_cansleep(maxim4c->pwdn_gpio, 1);
 
-		usleep_range(5000, 10000);
+		usleep_range(10000, 11000);
 	}
 
 	return 0;
@@ -310,24 +388,30 @@
 static void maxim4c_local_device_power_off(maxim4c_t *maxim4c)
 {
 	struct device *dev = &maxim4c->client->dev;
+	int ret;
 
 	if (!IS_ERR(maxim4c->pwdn_gpio)) {
 		dev_info(dev, "local device pwdn gpio off\n");
 
 		gpiod_set_value_cansleep(maxim4c->pwdn_gpio, 0);
 	}
+
+	ret = regulator_bulk_disable(MAXIM4C_NUM_SUPPLIES, maxim4c->supplies);
+	if (ret < 0) {
+		dev_warn(dev, "Failed to disable regulators\n");
+	}
 }
 
 static int maxim4c_remote_device_power_on(maxim4c_t *maxim4c)
 {
 	struct device *dev = &maxim4c->client->dev;
+	int ret;
 
-	// remote PoC enable
-	if (!IS_ERR(maxim4c->pocen_gpio)) {
-		dev_info(dev, "remote device pocen gpio on\n");
-
-		gpiod_set_value_cansleep(maxim4c->pocen_gpio, 1);
-		usleep_range(5000, 10000);
+	dev_dbg(dev, "Turn PoC on\n");
+	ret = regulator_enable(maxim4c->poc_regulator);
+	if (ret < 0) {
+		dev_err(dev, "Unable to turn PoC on\n");
+		return ret;
 	}
 
 	return 0;
@@ -336,13 +420,12 @@
 static int maxim4c_remote_device_power_off(maxim4c_t *maxim4c)
 {
 	struct device *dev = &maxim4c->client->dev;
+	int ret;
 
-	// remote PoC enable
-	if (!IS_ERR(maxim4c->pocen_gpio)) {
-		dev_info(dev, "remote device pocen gpio off\n");
-
-		gpiod_set_value_cansleep(maxim4c->pocen_gpio, 0);
-	}
+	dev_dbg(dev, "Turn PoC off\n");
+	ret = regulator_disable(maxim4c->poc_regulator);
+	if (ret < 0)
+		dev_warn(dev, "Unable to turn PoC off\n");
 
 	return 0;
 }
@@ -574,6 +657,7 @@
 	maxim4c_t *maxim4c = NULL;
 	u32 chip_id;
 	int ret = 0;
+	unsigned int i;
 
 	dev_info(dev, "driver version: %02x.%02x.%02x", DRIVER_VERSION >> 16,
 		 (DRIVER_VERSION & 0xff00) >> 8, DRIVER_VERSION & 0x00ff);
@@ -613,20 +697,53 @@
 	maxim4c->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
 	if (IS_ERR(maxim4c->pwdn_gpio))
 		dev_warn(dev, "Failed to get pwdn-gpios, maybe no use\n");
-
-	maxim4c->pocen_gpio = devm_gpiod_get(dev, "pocen", GPIOD_OUT_LOW);
-	if (IS_ERR(maxim4c->pocen_gpio))
-		dev_warn(dev, "Failed to get pocen-gpios\n");
+	else
+		usleep_range(1000, 1100);
 
 	maxim4c->lock_gpio = devm_gpiod_get(dev, "lock", GPIOD_IN);
 	if (IS_ERR(maxim4c->lock_gpio))
 		dev_warn(dev, "Failed to get lock-gpios\n");
+
+	for (i = 0; i < MAXIM4C_NUM_SUPPLIES; i++)
+		maxim4c->supplies[i].supply = maxim4c_supply_names[i];
+
+	ret = devm_regulator_bulk_get(dev, MAXIM4C_NUM_SUPPLIES,
+				      maxim4c->supplies);
+	if (ret < 0) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Unable to get supply regulators\n");
+		else
+			dev_warn(dev, "Get PoC regulator deferred\n");
+		return ret;
+	}
+
+	maxim4c->poc_regulator = devm_regulator_get(dev, "poc");
+	if (IS_ERR(maxim4c->poc_regulator)) {
+		if (PTR_ERR(maxim4c->poc_regulator) != -EPROBE_DEFER)
+			dev_err(dev, "Unable to get PoC regulator (%ld)\n",
+				PTR_ERR(maxim4c->poc_regulator));
+		else
+			dev_err(dev, "Get PoC regulator deferred\n");
+
+		ret = PTR_ERR(maxim4c->poc_regulator);
+#if !MAXIM4C_TEST_PATTERN
+		return ret;
+#endif
+	}
 
 	mutex_init(&maxim4c->mutex);
 
 	ret = maxim4c_local_device_power_on(maxim4c);
 	if (ret)
 		goto err_destroy_mutex;
+
+	ret = maxim4c_remote_device_power_on(maxim4c);
+	if (ret)
+		dev_warn(dev, "Power on PoC regulator failed\n");
+
+	pm_runtime_set_active(dev);
+	pm_runtime_get_noresume(dev);
+	pm_runtime_enable(dev);
 
 	ret = maxim4c_check_local_chipid(maxim4c);
 	if (ret)
@@ -651,9 +768,10 @@
 		goto err_power_off;
 #endif /* MAXIM4C_LOCAL_DES_ON_OFF_EN */
 
-	pm_runtime_set_active(dev);
-	pm_runtime_enable(dev);
-	pm_runtime_idle(dev);
+	pm_runtime_set_autosuspend_delay(dev, 1000);
+	pm_runtime_use_autosuspend(dev);
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
 
 	return 0;
 #endif /* MAXIM4C_TEST_PATTERN */
@@ -661,28 +779,38 @@
 	maxim4c_module_data_init(maxim4c);
 	maxim4c_module_parse_dt(maxim4c);
 
+	ret = maxim4c_dbgfs_init(maxim4c);
+	if (ret)
+		goto err_subdev_deinit;
+
 #if (MAXIM4C_LOCAL_DES_ON_OFF_EN == 0)
 	ret = maxim4c_module_hw_init(maxim4c);
 	if (ret)
-		goto err_subdev_deinit;
+		goto err_dbgfs_deinit;
 #endif /* MAXIM4C_LOCAL_DES_ON_OFF_EN */
 
 	ret = maxim4c_remote_mfd_add_devices(maxim4c);
 	if (ret)
-		goto err_subdev_deinit;
+		goto err_dbgfs_deinit;
 
 	maxim4c_lock_irq_init(maxim4c);
 	maxim4c_lock_state_work_init(maxim4c);
 
-	pm_runtime_set_active(dev);
-	pm_runtime_enable(dev);
-	pm_runtime_idle(dev);
+	pm_runtime_set_autosuspend_delay(dev, 1000);
+	pm_runtime_use_autosuspend(dev);
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
 
 	return 0;
 
+err_dbgfs_deinit:
+	maxim4c_dbgfs_deinit(maxim4c);
 err_subdev_deinit:
 	maxim4c_v4l2_subdev_deinit(maxim4c);
 err_power_off:
+	pm_runtime_disable(dev);
+	pm_runtime_put_noidle(dev);
+	maxim4c_remote_device_power_off(maxim4c);
 	maxim4c_local_device_power_off(maxim4c);
 err_destroy_mutex:
 	mutex_destroy(&maxim4c->mutex);
@@ -696,6 +824,8 @@
 
 	maxim4c_lock_state_work_deinit(maxim4c);
 
+	maxim4c_dbgfs_deinit(maxim4c);
+
 	maxim4c_v4l2_subdev_deinit(maxim4c);
 
 	mutex_destroy(&maxim4c->mutex);
diff --git a/kernel/drivers/media/i2c/maxim4c/maxim4c_drv.h b/kernel/drivers/media/i2c/maxim4c/maxim4c_drv.h
index 444f20f..d4542e1 100644
--- a/kernel/drivers/media/i2c/maxim4c/maxim4c_drv.h
+++ b/kernel/drivers/media/i2c/maxim4c/maxim4c_drv.h
@@ -10,6 +10,7 @@
 #include <linux/workqueue.h>
 #include <linux/rk-camera-module.h>
 #include <linux/mfd/core.h>
+#include <linux/regulator/consumer.h>
 #include <media/media-entity.h>
 #include <media/v4l2-async.h>
 #include <media/v4l2-ctrls.h>
@@ -27,6 +28,8 @@
 #define MAXIM4C_REG_CHIP_ID		0x0D
 #define MAX96712_CHIP_ID		0xA0
 #define MAX96722_CHIP_ID		0xA1
+
+#define MAXIM4C_NUM_SUPPLIES 2
 
 enum {
 	MAXIM4C_HOT_PLUG_OUT = 0,
@@ -57,8 +60,9 @@
 	struct i2c_client *client;
 	struct clk *xvclk;
 	struct gpio_desc *pwdn_gpio;
-	struct gpio_desc *pocen_gpio;
 	struct gpio_desc *lock_gpio;
+	struct regulator_bulk_data supplies[MAXIM4C_NUM_SUPPLIES];
+	struct regulator *poc_regulator;
 
 	struct mutex mutex;
 
@@ -104,6 +108,8 @@
 
 	struct mfd_cell remote_mfd_devs[MAXIM4C_LINK_ID_MAX];
 	maxim4c_remote_t *remote_device[MAXIM4C_LINK_ID_MAX];
+
+	struct dentry *dbgfs_root;
 } maxim4c_t;
 
 #endif /* __MAXIM4C_DRV_H__ */
diff --git a/kernel/drivers/media/i2c/maxim4c/maxim4c_link.c b/kernel/drivers/media/i2c/maxim4c/maxim4c_link.c
index 688dfe8..26f986e 100644
--- a/kernel/drivers/media/i2c/maxim4c/maxim4c_link.c
+++ b/kernel/drivers/media/i2c/maxim4c/maxim4c_link.c
@@ -463,7 +463,17 @@
 				0x0006, MAXIM4C_I2C_REG_ADDR_16BITS,
 				link_enable, link_enable);
 
-		ret |= maxim4c_link_wait_linklock(maxim4c, link_mask);
+		if (ret) {
+			dev_err(dev, "%s: link oneshot reset or enable error, link mask = 0x%x\n",
+				__func__, link_mask);
+			return ret;
+		}
+
+		maxim4c_link_wait_linklock(maxim4c, link_mask);
+		dev_info(dev, "link_mask = 0x%02x, link_lock = 0x%02x\n",
+			link_mask, maxim4c->link_lock_state);
+
+		return 0;
 	}
 
 	return ret;
diff --git a/kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c b/kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c
index 5734902..8776401 100644
--- a/kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c
+++ b/kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c
@@ -11,6 +11,82 @@
 
 #include "maxim4c_api.h"
 
+static int maxim4c_txphy_init_timing(maxim4c_t *maxim4c)
+{
+	struct i2c_client *client = maxim4c->client;
+	int ret = 0;
+	u16 reg_addr = 0;
+	u8 reg_mask;
+	u8 timing;
+	u8 phy_idx = 0;
+
+	if (!maxim4c->mipi_txphy.timing_override_en)
+		return 0;
+
+	timing = ((maxim4c->mipi_txphy.timing.t_hs_przero & 0x3) << 6 |
+		  (maxim4c->mipi_txphy.timing.t_hs_prep & 0x3) << 4 |
+		  (maxim4c->mipi_txphy.timing.t_clk_trail & 0x3) << 2 |
+		  (maxim4c->mipi_txphy.timing.t_clk_przero & 0x3) << 0);
+
+	ret |= maxim4c_i2c_write_byte(client, 0x08A1,
+				      MAXIM4C_I2C_REG_ADDR_16BITS, timing);
+
+	reg_mask = 0x0F;
+	timing = ((maxim4c->mipi_txphy.timing.t_lpx & 0x3) << 2 |
+		  (maxim4c->mipi_txphy.timing.t_hs_trail & 0x3) << 0);
+
+	ret |= maxim4c_i2c_update_byte(
+		client, 0x08A2, MAXIM4C_I2C_REG_ADDR_16BITS, reg_mask, timing);
+
+	reg_mask = (0x3 << 6);
+	timing = (maxim4c->mipi_txphy.timing.t_lpxesc & 0x3) << 6;
+	ret |= maxim4c_i2c_update_byte(
+		client, 0x08A5, MAXIM4C_I2C_REG_ADDR_16BITS, reg_mask, timing);
+
+	reg_mask = (0x7 << 5);
+	timing = (maxim4c->mipi_txphy.timing.t_lpxesc & 0x7) << 5;
+	ret |= maxim4c_i2c_update_byte(
+		client, 0x08A8, MAXIM4C_I2C_REG_ADDR_16BITS, reg_mask, timing);
+
+	for (phy_idx = 0; phy_idx < MAXIM4C_TXPHY_ID_MAX; phy_idx++) {
+		reg_mask = 0xFF;
+		reg_addr = 0x0905 + 0x40 * phy_idx;
+		timing = maxim4c->mipi_txphy.timing.csi2_t_pre;
+		ret |= maxim4c_i2c_update_byte(client, reg_addr,
+					       MAXIM4C_I2C_REG_ADDR_16BITS,
+					       reg_mask, timing);
+
+		reg_addr = 0x0906 + 0x40 * phy_idx;
+		timing = maxim4c->mipi_txphy.timing.csi2_t_post;
+		ret |= maxim4c_i2c_update_byte(client, reg_addr,
+					       MAXIM4C_I2C_REG_ADDR_16BITS,
+					       reg_mask, timing);
+
+		reg_addr = 0x0907 + 0x40 * phy_idx;
+		timing = maxim4c->mipi_txphy.timing.csi2_tx_gap;
+		ret |= maxim4c_i2c_update_byte(client, reg_addr,
+					       MAXIM4C_I2C_REG_ADDR_16BITS,
+					       reg_mask, timing);
+
+		reg_addr = 0x0908 + 0x40 * phy_idx;
+		timing = maxim4c->mipi_txphy.timing.csi2_twakeup & 0xFF;
+		ret |= maxim4c_i2c_update_byte(client, reg_addr,
+					       MAXIM4C_I2C_REG_ADDR_16BITS,
+					       reg_mask, timing);
+		timing = (maxim4c->mipi_txphy.timing.csi2_twakeup >> 8) & 0xFF;
+		ret |= maxim4c_i2c_update_byte(client, reg_addr + 1,
+					       MAXIM4C_I2C_REG_ADDR_16BITS,
+					       reg_mask, timing);
+		reg_mask = 0x7;
+		timing = (maxim4c->mipi_txphy.timing.csi2_twakeup >> 16) & 0x7;
+		ret |= maxim4c_i2c_update_byte(client, reg_addr + 2,
+					       MAXIM4C_I2C_REG_ADDR_16BITS,
+					       reg_mask, timing);
+	}
+
+	return ret;
+}
+
 static int maxim4c_txphy_auto_init_deskew(maxim4c_t *maxim4c)
 {
 	struct i2c_client *client = maxim4c->client;
@@ -182,6 +258,11 @@
 				reg_addr, MAXIM4C_I2C_REG_ADDR_16BITS,
 				0xf4);
 
+		reg_addr = 0x1C03 + 0x100 * phy_idx;
+		ret |= maxim4c_i2c_update_byte(client, reg_addr,
+					       MAXIM4C_I2C_REG_ADDR_16BITS,
+					       0x07, phy_cfg->ssc_ratio);
+
 		// Set dpll data rate
 		reg_addr = 0x0415 + 0x03 * phy_idx;
 		ret |= maxim4c_i2c_update_byte(client,
@@ -349,6 +430,12 @@
 				phy_cfg->clock_mode = value;
 			}
 
+			ret = of_property_read_u32(node, "ssc-ratio", &value);
+			if (ret == 0) {
+				dev_info(dev, "ssc-ratio property: %d", value);
+				phy_cfg->ssc_ratio = value;
+			}
+
 			sub_idx++;
 		}
 	}
@@ -510,6 +597,9 @@
 	// mipi txphy auto init deskew
 	ret |= maxim4c_txphy_auto_init_deskew(maxim4c);
 
+	// mipi txphy timing init
+	ret |= maxim4c_txphy_init_timing(maxim4c);
+
 	if (ret) {
 		dev_err(dev, "%s: txphy hw init error\n", __func__);
 		return ret;
@@ -529,6 +619,11 @@
 	mipi_txphy->force_clock_out_en = 1;
 	mipi_txphy->force_clk0_en = 0;
 	mipi_txphy->force_clk3_en = 0;
+	mipi_txphy->timing.t_lpx = 1;
+	mipi_txphy->timing.csi2_t_pre = 0x71;
+	mipi_txphy->timing.csi2_t_post = 0x19;
+	mipi_txphy->timing.csi2_tx_gap = 0x1C;
+	mipi_txphy->timing.csi2_twakeup = 0x100;
 
 	for (i = 0; i < MAXIM4C_TXPHY_ID_MAX; i++) {
 		phy_cfg = &mipi_txphy->phy_cfg[i];
@@ -541,6 +636,7 @@
 		phy_cfg->vc_ext_en = 0;
 		phy_cfg->clock_master = 0;
 		phy_cfg->clock_mode = MAXIM4C_TXPHY_DPLL_PREDEF;
+		phy_cfg->ssc_ratio = 0;
 	}
 }
 EXPORT_SYMBOL(maxim4c_mipi_txphy_data_init);
diff --git a/kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.h b/kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.h
index 759488d..29416be 100644
--- a/kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.h
+++ b/kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.h
@@ -53,6 +53,38 @@
 	u8 vc_ext_en;
 	u8 clock_master;
 	u8 clock_mode;
+	u8 ssc_ratio;
+};
+
+struct maxim4c_txphy_timing {
+	/* 0x8A1 */
+	u8 t_hs_przero;
+	u8 t_hs_prep;
+	u8 t_clk_trail;
+	u8 t_clk_przero;
+
+	/* 0x8A2 */
+	u8 t_lpx;
+	u8 t_hs_trail;
+
+	/* 0x8A5 */
+	u8 t_clk_prep;
+
+	/* 0x8A8 */
+	u8 t_lpxesc;
+
+	/* 0x8AE */
+	u8 t_t3_post;
+	u8 t_t3_prep;
+
+	/* 0x905 */
+	u8 csi2_t_pre;
+	/* 0x906 */
+	u8 csi2_t_post;
+	/* 0x907 */
+	u8 csi2_tx_gap;
+	/* 0x908,0x909,0x90A */
+	u32 csi2_twakeup;
 };
 
 typedef struct maxim4c_mipi_txphy {
@@ -61,6 +93,9 @@
 	u8 force_clk0_en; /* DPHY0 enabled as clock */
 	u8 force_clk3_en; /* DPHY3 enabled as clock */
 
+	u8 timing_override_en;
+	struct maxim4c_txphy_timing timing;
+
 	struct maxim4c_txphy_cfg phy_cfg[MAXIM4C_TXPHY_ID_MAX];
 } maxim4c_mipi_txphy_t;
 
diff --git a/kernel/drivers/media/i2c/maxim4c/maxim4c_v4l2.c b/kernel/drivers/media/i2c/maxim4c/maxim4c_v4l2.c
index 37df9a6..908045e 100644
--- a/kernel/drivers/media/i2c/maxim4c/maxim4c_v4l2.c
+++ b/kernel/drivers/media/i2c/maxim4c/maxim4c_v4l2.c
@@ -532,6 +532,11 @@
 	if (maxim4c->hot_plug_irq > 0)
 		enable_irq(maxim4c->hot_plug_irq);
 
+	if (maxim4c->link_lock_state != maxim4c->gmsl_link.link_enable_mask) {
+		dev_info(dev, "partial links are locked, start hot plug detect work.\n");
+		maxim4c_hot_plug_detect_work_start(maxim4c);
+	}
+
 	return 0;
 }
 
@@ -589,21 +594,20 @@
 		goto unlock_and_return;
 
 	if (on) {
-		ret = pm_runtime_get_sync(&client->dev);
-		if (ret < 0) {
-			pm_runtime_put_noidle(&client->dev);
+		ret = pm_runtime_resume_and_get(&client->dev);
+		if (ret < 0)
 			goto unlock_and_return;
-		}
 
 		ret = __maxim4c_start_stream(maxim4c);
 		if (ret) {
 			v4l2_err(sd, "start stream failed while write regs\n");
-			pm_runtime_put(&client->dev);
+			pm_runtime_put_sync(&client->dev);
 			goto unlock_and_return;
 		}
 	} else {
 		__maxim4c_stop_stream(maxim4c);
-		pm_runtime_put(&client->dev);
+		pm_runtime_mark_last_busy(&client->dev);
+		pm_runtime_put_autosuspend(&client->dev);
 	}
 
 	maxim4c->streaming = on;
@@ -787,21 +791,9 @@
 
 	val |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
 	val |= (1 << (data_lanes - 1));
-	switch (data_lanes) {
-	case 4:
-		val |= V4L2_MBUS_CSI2_CHANNEL_3;
-		fallthrough;
-	case 3:
-		val |= V4L2_MBUS_CSI2_CHANNEL_2;
-		fallthrough;
-	case 2:
-		val |= V4L2_MBUS_CSI2_CHANNEL_1;
-		fallthrough;
-	case 1:
-	default:
-		val |= V4L2_MBUS_CSI2_CHANNEL_0;
-		break;
-	}
+
+	val |= V4L2_MBUS_CSI2_CHANNEL_3 | V4L2_MBUS_CSI2_CHANNEL_2 |
+	       V4L2_MBUS_CSI2_CHANNEL_1 | V4L2_MBUS_CSI2_CHANNEL_0;
 
 	config->type = V4L2_MBUS_CSI2_DPHY;
 	config->flags = val;
diff --git a/kernel/drivers/media/i2c/maxim4c/remote_max9295.c b/kernel/drivers/media/i2c/maxim4c/remote_max9295.c
index b050516..b224292 100644
--- a/kernel/drivers/media/i2c/maxim4c/remote_max9295.c
+++ b/kernel/drivers/media/i2c/maxim4c/remote_max9295.c
@@ -325,7 +325,7 @@
 	.probe		= max9295_probe,
 	.remove		= max9295_remove,
 	.driver		= {
-		.name	= "max9295",
+		.name	= "maxim4c-max9295",
 		.of_match_table = max9295_of_table,
 	},
 };
diff --git a/kernel/drivers/media/i2c/maxim4c/remote_max96715.c b/kernel/drivers/media/i2c/maxim4c/remote_max96715.c
index 3f2689a..11aa308 100644
--- a/kernel/drivers/media/i2c/maxim4c/remote_max96715.c
+++ b/kernel/drivers/media/i2c/maxim4c/remote_max96715.c
@@ -190,7 +190,6 @@
 {
 	struct device *dev = max96715->dev;
 	struct i2c_client *client = max96715->client;
-	struct maxim4c *maxim4c = max96715->local;
 	int ret = 0;
 
 	ret = maxim4c_remote_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF);
@@ -206,16 +205,9 @@
 		return ret;
 
 #if MAX96715_MODE_SWITCH
-	if (maxim4c->hot_plug_irq > 0)
-		disable_irq(maxim4c->hot_plug_irq);
-
 	ret = max96715_link_mode_select(max96715, LINK_MODE_CONFIG);
-	if (ret) {
-		if (maxim4c->hot_plug_irq > 0)
-			enable_irq(maxim4c->hot_plug_irq);
-
+	if (ret)
 		return ret;
-	}
 #endif
 
 	ret = maxim4c_i2c_run_init_seq(client,
@@ -225,16 +217,11 @@
 		dev_err(dev, "remote id = %d init sequence error\n",
 				max96715->remote_id);
 
-		if (maxim4c->hot_plug_irq > 0)
-			enable_irq(maxim4c->hot_plug_irq);
-
 		return ret;
 	}
 
 #if MAX96715_MODE_SWITCH
 	ret = max96715_link_mode_select(max96715, LINK_MODE_VIDEO);
-	if (maxim4c->hot_plug_irq > 0)
-		enable_irq(maxim4c->hot_plug_irq);
 	if (ret)
 		return ret;
 #endif
@@ -388,7 +375,7 @@
 	.probe		= max96715_probe,
 	.remove		= max96715_remove,
 	.driver		= {
-		.name	= "max96715",
+		.name	= "maxim4c-max96715",
 		.of_match_table = max96715_of_table,
 	},
 };
diff --git a/kernel/drivers/media/i2c/maxim4c/remote_max96717.c b/kernel/drivers/media/i2c/maxim4c/remote_max96717.c
index d0a3b7d..b78bb31 100644
--- a/kernel/drivers/media/i2c/maxim4c/remote_max96717.c
+++ b/kernel/drivers/media/i2c/maxim4c/remote_max96717.c
@@ -304,7 +304,7 @@
 	.probe		= max96717_probe,
 	.remove		= max96717_remove,
 	.driver		= {
-		.name	= "max96717",
+		.name	= "maxim4c-max96717",
 		.of_match_table = max96717_of_table,
 	},
 };
diff --git a/kernel/drivers/media/i2c/mis2031.c b/kernel/drivers/media/i2c/mis2031.c
new file mode 100644
index 0000000..16f310d
--- /dev/null
+++ b/kernel/drivers/media/i2c/mis2031.c
@@ -0,0 +1,1651 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mis2031 driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * V0.0X01.0X01 first version
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/rk-camera-module.h>
+#include <linux/rk-preisp.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <linux/pinctrl/consumer.h>
+#include "../platform/rockchip/isp/rkisp_tb_helper.h"
+
+#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x01)
+
+#define MIS2031_LANES			2
+#define MIS2031_BITS_PER_SAMPLE		10
+#define MIS2031_LINK_FREQ_185		185600000  //37.125mbps
+
+#define PIXEL_RATE_WITH_315M_10BIT	(MIS2031_LINK_FREQ_185 * 2 * \
+					MIS2031_LANES / MIS2031_BITS_PER_SAMPLE)
+#define MIS2031_XVCLK_FREQ		27000000
+
+#define CHIP_ID				0x2009
+#define MIS2031_REG_CHIP_ID		0x3000
+
+#define MIS2031_REG_CTRL_MODE		0x3006
+#define MIS2031_MODE_SW_STANDBY		BIT(1)
+#define MIS2031_MODE_STREAMING		0x0
+
+#define MIS2031_REG_EXPOSURE_H		0x3100
+#define MIS2031_REG_EXPOSURE_L		0x3101
+#define	MIS2031_EXPOSURE_MIN		1
+#define	MIS2031_EXPOSURE_STEP		1
+#define MIS2031_FETCH_EXP_H(VAL)	(((VAL) >> 8) & 0xFF)
+#define MIS2031_FETCH_EXP_L(VAL)	((VAL) & 0xFF)
+
+#define MIS2031_REG_DIG_GAIN		0x3700
+#define MIS2031_REG_DIG_FINE_GAIN	0x3701
+#define MIS2031_REG_ANA_GAIN		0x3109
+#define MIS2031_REG_ANA_FINE_GAIN       0x310a
+#define MIS2031_GAIN_MIN		0x20
+#define MIS2031_GAIN_MAX		(64 * 16 * 32)
+#define MIS2031_GAIN_STEP		1
+#define MIS2031_GAIN_DEFAULT		0x20
+#define MIS2031_FETCH_AGAIN_H(VAL)	(((VAL) >> 8) & 0x03)
+#define MIS2031_FETCH_AGAIN_L(VAL)	((VAL) & 0xFF)
+
+#define MIS2031_REG_GAIN_EXP_VALID	0x300c
+#define MIS2031_REG_GAIN_EXP_VALID_VAL	BIT(0)
+
+#define MIS2031_VTS_MAX			0xffff
+#define MIS2031_REG_VTS_H		0x3200
+#define MIS2031_REG_VTS_L		0x3201
+
+#define MIS2031_FLIP_MIRROR_REG		0x3007
+#define MIRROR_BIT_MASK			BIT(0)
+#define FLIP_BIT_MASK			BIT(1)
+#define MIS2031_FETCH_MIRROR(VAL, ENABLE)	(ENABLE ? VAL | 0x01 : VAL & 0xfe)
+#define MIS2031_FETCH_FLIP(VAL, ENABLE)		(ENABLE ? VAL | 0x10 : VAL & 0xfd)
+
+#define MIS2031_REG_TEST_PATTERN	0x3500
+#define MIS2031_TEST_PATTERN_BIT_MASK	BIT(0)
+
+#define REG_DELAY			0xFFFE
+#define REG_NULL			0xFFFF
+
+#define MIS2031_REG_VALUE_08BIT		1
+#define MIS2031_REG_VALUE_16BIT		2
+#define MIS2031_REG_VALUE_24BIT		3
+
+#define OF_CAMERA_PINCTRL_STATE_DEFAULT	"rockchip,camera_default"
+#define OF_CAMERA_PINCTRL_STATE_SLEEP	"rockchip,camera_sleep"
+#define MIS2031_NAME			"mis2031"
+
+static const char * const mis2031_supply_names[] = {
+	"avdd",		/* Analog power */
+	"dovdd",	/* Digital I/O power */
+	"dvdd",		/* Digital core power */
+};
+
+#define MIS2031_NUM_SUPPLIES ARRAY_SIZE(mis2031_supply_names)
+
+struct regval {
+	u16 addr;
+	u8 val;
+};
+
+struct mis2031_mode {
+	u32 bus_fmt;
+	u32 width;
+	u32 height;
+	struct v4l2_fract max_fps;
+	u32 hts_def;
+	u32 vts_def;
+	u32 exp_def;
+	const struct regval *reg_list;
+	u32 hdr_mode;
+	u32 vc[PAD_MAX];
+};
+
+struct mis2031 {
+	struct i2c_client	*client;
+	struct clk		*xvclk;
+	struct gpio_desc	*reset_gpio;
+	struct gpio_desc	*pwdn_gpio;
+	struct regulator_bulk_data supplies[MIS2031_NUM_SUPPLIES];
+
+	struct pinctrl		*pinctrl;
+	struct pinctrl_state	*pins_default;
+	struct pinctrl_state	*pins_sleep;
+
+	struct v4l2_subdev	subdev;
+	struct media_pad	pad;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl	*exposure;
+	struct v4l2_ctrl	*anal_gain;
+	struct v4l2_ctrl	*digi_gain;
+	struct v4l2_ctrl	*hblank;
+	struct v4l2_ctrl	*vblank;
+	struct v4l2_ctrl	*test_pattern;
+	struct mutex		mutex;
+	bool			streaming;
+	bool			power_on;
+	const struct mis2031_mode *cur_mode;
+	struct v4l2_fract	cur_fps;
+	u32			module_index;
+	const char		*module_facing;
+	const char		*module_name;
+	const char		*len_name;
+	u32			cur_vts;
+	bool			is_thunderboot;
+	bool			is_first_streamoff;
+};
+
+#define to_mis2031(sd) container_of(sd, struct mis2031, subdev)
+
+/*
+ * Xclk 24Mhz
+ */
+static const struct regval mis2031_global_regs[] = {
+	{REG_NULL, 0x00},
+};
+
+/*
+ * Xclk 24Mhz
+ * max_framerate 30fps
+ * mipi_datarate per lane 630Mbps, 2lane
+ */
+static const struct regval mis2031_linear_10_1920x1080_regs[] = {
+	{0x300b, 0x01},
+	{0x3006, 0x02},
+	{REG_DELAY, 0x50},
+	{0x330c, 0x01},
+	{0x3020, 0x01},
+	{0x3021, 0x02},
+	{0x3201, 0x65},
+	{0x3200, 0x04},
+	{0x3203, 0x98},
+	{0x3202, 0x08},
+	{0x3205, 0x00},
+	{0x3204, 0x00},
+	{0x3207, 0x3b},
+	{0x3206, 0x04},
+	{0x3209, 0x08},
+	{0x3208, 0x00},
+	{0x320b, 0x87},
+	{0x320a, 0x07},
+	{0x3102, 0x00},
+	{0x3105, 0x00},
+	{0x3108, 0x00},
+	{0x3007, 0x00},
+	{0x300a, 0x01},
+	{0x330c, 0x01},
+	{0x3300, 0x6e},
+	{0x3301, 0x01},
+	{0x3302, 0x02},
+	{0x3303, 0x06},
+	{0x3309, 0x01},
+	{0x3307, 0x02},
+	{0x330b, 0x0a},
+	{0x3014, 0x00},
+	{0x330f, 0x00},
+	{0x310f, 0x00},
+	{0x3986, 0x02},
+	{0x3986, 0x02},
+	{0x3900, 0x00},
+	{0x3902, 0x11},
+	{0x3901, 0x00},
+	{0x3904, 0x44},
+	{0x3903, 0x06},
+	{0x3906, 0xff},
+	{0x3905, 0x1f},
+	{0x3908, 0xff},
+	{0x3907, 0x1f},
+	{0x390a, 0x42},
+	{0x3909, 0x02},
+	{0x390c, 0x19},
+	{0x390b, 0x03},
+	{0x390e, 0x30},
+	{0x390d, 0x06},
+	{0x3910, 0xff},
+	{0x390f, 0x1f},
+	{0x3911, 0x01},
+	{0x3917, 0x00},
+	{0x3916, 0x00},
+	{0x3919, 0x90},
+	{0x3918, 0x01},
+	{0x3913, 0x11},
+	{0x3912, 0x00},
+	{0x3915, 0x52},
+	{0x3914, 0x02},
+	{0x391b, 0x00},
+	{0x391a, 0x00},
+	{0x391d, 0x41},
+	{0x391c, 0x06},
+	{0x391f, 0xff},
+	{0x391e, 0x1f},
+	{0x3921, 0xff},
+	{0x3920, 0x1f},
+	{0x3923, 0x00},
+	{0x3922, 0x00},
+	{0x3925, 0x46},
+	{0x3924, 0x02},
+	{0x394c, 0x00},
+	{0x394e, 0x74},
+	{0x394d, 0x00},
+	{0x3950, 0x84},
+	{0x394f, 0x00},
+	{0x3952, 0x63},
+	{0x3951, 0x00},
+	{0x3954, 0x71},
+	{0x3953, 0x02},
+	{0x3927, 0x00},
+	{0x3926, 0x00},
+	{0x3929, 0xc6},
+	{0x3928, 0x00},
+	{0x392b, 0x9d},
+	{0x392a, 0x01},
+	{0x392d, 0x31},
+	{0x392c, 0x02},
+	{0x392f, 0xcc},
+	{0x392e, 0x03},
+	{0x3931, 0x60},
+	{0x3930, 0x06},
+	{0x3933, 0x60},
+	{0x3932, 0x06},
+	{0x3935, 0x60},
+	{0x3934, 0x06},
+	{0x3937, 0x60},
+	{0x3936, 0x06},
+	{0x3939, 0x60},
+	{0x3938, 0x06},
+	{0x393b, 0x60},
+	{0x393a, 0x06},
+	{0x3991, 0x40},
+	{0x3990, 0x00},
+	{0x3993, 0x80},
+	{0x3992, 0x06},
+	{0x3995, 0xff},
+	{0x3994, 0x1f},
+	{0x3997, 0x00},
+	{0x3996, 0x00},
+	{0x393d, 0x74},
+	{0x393c, 0x00},
+	{0x393f, 0x9d},
+	{0x393e, 0x01},
+	{0x3941, 0x4a},
+	{0x3940, 0x03},
+	{0x3943, 0x9c},
+	{0x3942, 0x03},
+	{0x3945, 0x00},
+	{0x3944, 0x00},
+	{0x3947, 0xe7},
+	{0x3946, 0x00},
+	{0x3949, 0xe7},
+	{0x3948, 0x00},
+	{0x394b, 0x35},
+	{0x394a, 0x06},
+	{0x395a, 0x00},
+	{0x3959, 0x00},
+	{0x395c, 0x09},
+	{0x395b, 0x00},
+	{0x395e, 0x2f},
+	{0x395d, 0x02},
+	{0x3960, 0x39},
+	{0x395f, 0x03},
+	{0x3956, 0x09},
+	{0x3955, 0x00},
+	{0x3958, 0x35},
+	{0x3957, 0x06},
+	{0x3962, 0x00},
+	{0x3961, 0x00},
+	{0x3964, 0x84},
+	{0x3963, 0x00},
+	{0x3966, 0x00},
+	{0x3965, 0x00},
+	{0x3968, 0x74},
+	{0x3967, 0x00},
+	{0x3989, 0x00},
+	{0x3988, 0x00},
+	{0x398b, 0xa5},
+	{0x398a, 0x00},
+	{0x398d, 0x00},
+	{0x398c, 0x00},
+	{0x398f, 0x84},
+	{0x398e, 0x00},
+	{0x396a, 0x62},
+	{0x3969, 0x06},
+	{0x396d, 0x00},
+	{0x396c, 0x01},
+	{0x396f, 0x60},
+	{0x396e, 0x00},
+	{0x3971, 0x60},
+	{0x3970, 0x00},
+	{0x3973, 0x60},
+	{0x3972, 0x00},
+	{0x3975, 0x60},
+	{0x3974, 0x00},
+	{0x3977, 0x60},
+	{0x3976, 0x00},
+	{0x3979, 0xa0},
+	{0x3978, 0x01},
+	{0x397b, 0xa0},
+	{0x397a, 0x01},
+	{0x397d, 0xa0},
+	{0x397c, 0x01},
+	{0x397f, 0xa0},
+	{0x397e, 0x01},
+	{0x3981, 0xa0},
+	{0x3980, 0x01},
+	{0x3983, 0xa0},
+	{0x3982, 0x01},
+	{0x3985, 0xa0},
+	{0x3984, 0x05},
+	{0x3c42, 0x03},
+	{0x3012, 0x2b},
+	{0x3205, 0x08},
+	{0x3204, 0x00},
+	{0x310f, 0x00},
+	{0x3600, 0x63},
+	{0x3630, 0x00},
+	{0x3631, 0xFF},
+	{0x3632, 0xFF},
+	{0x364e, 0x63},
+	{0x367e, 0x00},
+	{0x367f, 0xFF},
+	{0x3680, 0xFF},
+	{0x369c, 0x63},
+	{0x36cc, 0x00},
+	{0x36cd, 0xFF},
+	{0x36ce, 0xFF},
+	{0x3706, 0x01},
+	{0x3707, 0x00},
+	{0x3708, 0x01},
+	{0x3709, 0x00},
+	{0x370a, 0x01},
+	{0x370b, 0x00},
+	{0x210b, 0x00},
+	{0x3021, 0x00},
+	{0x3a00, 0x00},
+	{0x3a04, 0x03},
+	{0x3a05, 0x78},
+	{0x3a0a, 0x3a},
+	{0x3a2a, 0x54},
+	{0x3a2e, 0x10},
+	{0x3a14, 0x04},
+	{0x3a1c, 0x01},
+	{0x3a36, 0x01},
+	{0x3a07, 0x56},
+	{0x3a35, 0x07},
+	{0x3a30, 0x52},
+	{0x3a31, 0x35},
+	{0x3a19, 0x08},
+	{0x3a1a, 0x08},
+	{0x3a36, 0x01},
+	{0x3006, 0x00},
+	{0x3100, 0x00},
+	{0x3101, 0x52},
+	{0x3109, 0x00},
+	{0x310a, 0x00},
+	{REG_NULL, 0x00},
+};
+
+static const struct mis2031_mode supported_modes[] = {
+	{
+		.width = 1920,
+		.height = 1080,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 300000,
+		},
+		.exp_def = 0x0052,
+		.hts_def = 0x0898,
+		.vts_def = 0x0465,
+		.bus_fmt = MEDIA_BUS_FMT_SGRBG10_1X10,
+		.reg_list = mis2031_linear_10_1920x1080_regs,
+		.hdr_mode = NO_HDR,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	}
+};
+
+static const s64 link_freq_menu_items[] = {
+	MIS2031_LINK_FREQ_185
+};
+
+static const char * const mis2031_test_pattern_menu[] = {
+	"Disabled",
+	"Vertical Color Bar Type 1",
+	"Vertical Color Bar Type 2",
+	"Vertical Color Bar Type 3",
+	"Vertical Color Bar Type 4"
+};
+
+/* Write registers up to 4 at a time */
+static int mis2031_write_reg(struct i2c_client *client, u16 reg,
+				u32 len, u32 val)
+{
+	u32 buf_i, val_i;
+	u8 buf[6];
+	u8 *val_p;
+	__be32 val_be;
+
+	if (len > 4)
+		return -EINVAL;
+
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xff;
+
+	val_be = cpu_to_be32(val);
+	val_p = (u8 *)&val_be;
+	buf_i = 2;
+	val_i = 4 - len;
+
+	while (val_i < 4)
+		buf[buf_i++] = val_p[val_i++];
+
+	if (i2c_master_send(client, buf, len + 2) != len + 2)
+		return -EIO;
+	return 0;
+}
+
+static int mis2031_write_array(struct i2c_client *client,
+					const struct regval *regs)
+{
+	u32 i;
+	int ret = 0;
+
+	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) {
+		if (regs[i].addr == REG_DELAY)
+			mdelay(regs[i].val);
+		else
+			ret = mis2031_write_reg(client, regs[i].addr,
+					MIS2031_REG_VALUE_08BIT, regs[i].val);
+	}
+
+	return ret;
+}
+
+/* Read registers up to 4 at a time */
+static int mis2031_read_reg(struct i2c_client *client, u16 reg, unsigned int len,
+				u32 *val)
+{
+	struct i2c_msg msgs[2];
+	u8 *data_be_p;
+	__be32 data_be = 0;
+	__be16 reg_addr_be = cpu_to_be16(reg);
+	int ret;
+
+	if (len > 4 || !len)
+		return -EINVAL;
+
+	data_be_p = (u8 *)&data_be;
+	/* Write register address */
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = 2;
+	msgs[0].buf = (u8 *)&reg_addr_be;
+
+	/* Read data from register */
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = len;
+	msgs[1].buf = &data_be_p[4 - len];
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs))
+		return -EIO;
+
+	*val = be32_to_cpu(data_be);
+
+	return 0;
+}
+
+static void mis2031_set_orientation_reg(struct mis2031 *mis2031, u32 en_flip_mir)
+{
+	switch (en_flip_mir) {
+	case  0:
+		mis2031_write_reg(mis2031->client, 0x3007, MIS2031_REG_VALUE_08BIT, 0x00);
+		mis2031_write_reg(mis2031->client, 0x3205, MIS2031_REG_VALUE_08BIT, 0x00);
+		mis2031_write_reg(mis2031->client, 0x3207, MIS2031_REG_VALUE_08BIT, 0x3b);
+		mis2031_write_reg(mis2031->client, 0x3209, MIS2031_REG_VALUE_08BIT, 0x08);
+		mis2031_write_reg(mis2031->client, 0x320b, MIS2031_REG_VALUE_08BIT, 0x87);
+		break;
+	case  1:
+		mis2031_write_reg(mis2031->client, 0x3007, MIS2031_REG_VALUE_08BIT, 0x01);
+		mis2031_write_reg(mis2031->client, 0x3205, MIS2031_REG_VALUE_08BIT, 0x00);
+		mis2031_write_reg(mis2031->client, 0x3207, MIS2031_REG_VALUE_08BIT, 0x3b);
+		mis2031_write_reg(mis2031->client, 0x3209, MIS2031_REG_VALUE_08BIT, 0x09);
+		mis2031_write_reg(mis2031->client, 0x320b, MIS2031_REG_VALUE_08BIT, 0x88);
+		break;
+	case  2:
+		mis2031_write_reg(mis2031->client, 0x3007, MIS2031_REG_VALUE_08BIT, 0x02);
+		mis2031_write_reg(mis2031->client, 0x3205, MIS2031_REG_VALUE_08BIT, 0x01);
+		mis2031_write_reg(mis2031->client, 0x3207, MIS2031_REG_VALUE_08BIT, 0x3c);
+		mis2031_write_reg(mis2031->client, 0x3209, MIS2031_REG_VALUE_08BIT, 0x08);
+		mis2031_write_reg(mis2031->client, 0x320b, MIS2031_REG_VALUE_08BIT, 0x87);
+		break;
+	case  3:
+		mis2031_write_reg(mis2031->client, 0x3007, MIS2031_REG_VALUE_08BIT, 0x03);
+		mis2031_write_reg(mis2031->client, 0x3205, MIS2031_REG_VALUE_08BIT, 0x01);
+		mis2031_write_reg(mis2031->client, 0x3207, MIS2031_REG_VALUE_08BIT, 0x3c);
+		mis2031_write_reg(mis2031->client, 0x3209, MIS2031_REG_VALUE_08BIT, 0x09);
+		mis2031_write_reg(mis2031->client, 0x320b, MIS2031_REG_VALUE_08BIT, 0x88);
+		break;
+	default:
+		break;
+	}
+}
+
+static int mis2031_set_gain_reg(struct mis2031 *mis2031, u32 gain)
+{
+	u32 coarse_again = 0, coarse_dgian = 0, fine_dgian = 0;
+	u32 dgain;
+	int ret = 0;
+
+	if (gain < 32)
+		gain = 32;
+	else if (gain > MIS2031_GAIN_MAX - 1)
+		gain = MIS2031_GAIN_MAX - 1;
+
+	if (gain < 32*64) {
+		coarse_again = 1024 - (1024*32/gain);
+		coarse_dgian = 0x1;
+		fine_dgian = 0;
+	} else if (gain < MIS2031_GAIN_MAX) {
+		coarse_again = 1008;
+		coarse_dgian = (gain/64)/32;
+		fine_dgian = (gain/64)%32;
+	}
+	dgain = ((coarse_dgian << 5) | fine_dgian);
+	ret = mis2031_write_reg(mis2031->client,
+				MIS2031_REG_DIG_GAIN,
+				MIS2031_REG_VALUE_08BIT,
+				MIS2031_FETCH_AGAIN_H(dgain));
+	ret |= mis2031_write_reg(mis2031->client,
+				MIS2031_REG_DIG_FINE_GAIN,
+				MIS2031_REG_VALUE_08BIT,
+				MIS2031_FETCH_AGAIN_L(dgain));
+	ret |= mis2031_write_reg(mis2031->client,
+				 MIS2031_REG_ANA_GAIN,
+				 MIS2031_REG_VALUE_08BIT,
+				 MIS2031_FETCH_AGAIN_H(coarse_again));
+	ret |= mis2031_write_reg(mis2031->client,
+				 MIS2031_REG_ANA_FINE_GAIN,
+				 MIS2031_REG_VALUE_08BIT,
+				 MIS2031_FETCH_AGAIN_L(coarse_again));
+	ret |= mis2031_write_reg(mis2031->client,
+				 MIS2031_REG_GAIN_EXP_VALID,
+				 MIS2031_REG_VALUE_08BIT,
+				 MIS2031_REG_GAIN_EXP_VALID_VAL);
+	return ret;
+}
+
+static int mis2031_get_reso_dist(const struct mis2031_mode *mode,
+				struct v4l2_mbus_framefmt *framefmt)
+{
+	return abs(mode->width - framefmt->width) +
+			abs(mode->height - framefmt->height);
+}
+
+static const struct mis2031_mode *
+mis2031_find_best_fit(struct v4l2_subdev_format *fmt)
+{
+	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
+	int dist;
+	int cur_best_fit = 0;
+	int cur_best_fit_dist = -1;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+		dist = mis2031_get_reso_dist(&supported_modes[i], framefmt);
+		if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
+			cur_best_fit_dist = dist;
+			cur_best_fit = i;
+		}
+	}
+
+	return &supported_modes[cur_best_fit];
+}
+
+static int mis2031_set_fmt(struct v4l2_subdev *sd,
+				struct v4l2_subdev_pad_config *cfg,
+				struct v4l2_subdev_format *fmt)
+{
+	struct mis2031 *mis2031 = to_mis2031(sd);
+	const struct mis2031_mode *mode;
+	s64 h_blank, vblank_def;
+
+	mutex_lock(&mis2031->mutex);
+
+	mode = mis2031_find_best_fit(fmt);
+	fmt->format.code = mode->bus_fmt;
+	fmt->format.width = mode->width;
+	fmt->format.height = mode->height;
+	fmt->format.field = V4L2_FIELD_NONE;
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+#else
+		mutex_unlock(&mis2031->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		mis2031->cur_mode = mode;
+		h_blank = mode->hts_def - mode->width;
+		__v4l2_ctrl_modify_range(mis2031->hblank, h_blank,
+					h_blank, 1, h_blank);
+		vblank_def = mode->vts_def - mode->height;
+		__v4l2_ctrl_modify_range(mis2031->vblank, vblank_def,
+					MIS2031_VTS_MAX - mode->height,
+					1, vblank_def);
+		mis2031->cur_fps = mode->max_fps;
+	}
+
+	mutex_unlock(&mis2031->mutex);
+
+	return 0;
+}
+
+static int mis2031_get_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct mis2031 *mis2031 = to_mis2031(sd);
+	const struct mis2031_mode *mode = mis2031->cur_mode;
+
+	mutex_lock(&mis2031->mutex);
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+#else
+		mutex_unlock(&mis2031->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		fmt->format.width = mode->width;
+		fmt->format.height = mode->height;
+		fmt->format.code = mode->bus_fmt;
+		fmt->format.field = V4L2_FIELD_NONE;
+		/* format info: width/height/data type/virctual channel */
+		if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
+			fmt->reserved[0] = mode->vc[fmt->pad];
+		else
+			fmt->reserved[0] = mode->vc[PAD0];
+	}
+	mutex_unlock(&mis2031->mutex);
+
+	return 0;
+}
+
+static int mis2031_enum_mbus_code(struct v4l2_subdev *sd,
+				struct v4l2_subdev_pad_config *cfg,
+				struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct mis2031 *mis2031 = to_mis2031(sd);
+
+	if (code->index != 0)
+		return -EINVAL;
+	code->code = mis2031->cur_mode->bus_fmt;
+
+	return 0;
+}
+
+static int mis2031_enum_frame_sizes(struct v4l2_subdev *sd,
+					struct v4l2_subdev_pad_config *cfg,
+					struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	if (fse->code != supported_modes[0].bus_fmt)
+		return -EINVAL;
+
+	fse->min_width  = supported_modes[fse->index].width;
+	fse->max_width  = supported_modes[fse->index].width;
+	fse->max_height = supported_modes[fse->index].height;
+	fse->min_height = supported_modes[fse->index].height;
+
+	return 0;
+}
+
+static int mis2031_enable_test_pattern(struct mis2031 *mis2031, u32 pattern)
+{
+	u32 val = 0;
+	int ret = 0;
+
+	ret = mis2031_read_reg(mis2031->client, MIS2031_REG_TEST_PATTERN,
+					MIS2031_REG_VALUE_08BIT, &val);
+	if (pattern)
+		val |= MIS2031_TEST_PATTERN_BIT_MASK;
+	else
+		val &= ~MIS2031_TEST_PATTERN_BIT_MASK;
+
+	ret |= mis2031_write_reg(mis2031->client, MIS2031_REG_TEST_PATTERN,
+				MIS2031_REG_VALUE_08BIT, val);
+	return ret;
+}
+
+static int mis2031_g_frame_interval(struct v4l2_subdev *sd,
+					struct v4l2_subdev_frame_interval *fi)
+{
+	struct mis2031 *mis2031 = to_mis2031(sd);
+	const struct mis2031_mode *mode = mis2031->cur_mode;
+
+	if (mis2031->streaming)
+		fi->interval = mis2031->cur_fps;
+	else
+		fi->interval = mode->max_fps;
+
+	return 0;
+}
+
+static int mis2031_g_mbus_config(struct v4l2_subdev *sd,
+				unsigned int pad_id,
+				struct v4l2_mbus_config *config)
+{
+	struct mis2031 *mis2031 = to_mis2031(sd);
+	const struct mis2031_mode *mode = mis2031->cur_mode;
+	u32 val = 1 << (MIS2031_LANES - 1) |
+		V4L2_MBUS_CSI2_CHANNEL_0 |
+		V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+
+	if (mode->hdr_mode != NO_HDR)
+		val |= V4L2_MBUS_CSI2_CHANNEL_1;
+	if (mode->hdr_mode == HDR_X3)
+		val |= V4L2_MBUS_CSI2_CHANNEL_2;
+
+	config->type = V4L2_MBUS_CSI2_DPHY;
+	config->flags = val;
+
+	return 0;
+}
+
+static void mis2031_get_module_inf(struct mis2031 *mis2031,
+					struct rkmodule_inf *inf)
+{
+	memset(inf, 0, sizeof(*inf));
+	strscpy(inf->base.sensor, MIS2031_NAME, sizeof(inf->base.sensor));
+	strscpy(inf->base.module, mis2031->module_name,
+		sizeof(inf->base.module));
+	strscpy(inf->base.lens, mis2031->len_name, sizeof(inf->base.lens));
+}
+
+static long mis2031_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	struct mis2031 *mis2031 = to_mis2031(sd);
+	struct rkmodule_hdr_cfg *hdr;
+	u32 i, h, w;
+	long ret = 0;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		mis2031_get_module_inf(mis2031, (struct rkmodule_inf *)arg);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr = (struct rkmodule_hdr_cfg *)arg;
+		hdr->esp.mode = HDR_NORMAL_VC;
+		hdr->hdr_mode = mis2031->cur_mode->hdr_mode;
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		hdr = (struct rkmodule_hdr_cfg *)arg;
+		w = mis2031->cur_mode->width;
+		h = mis2031->cur_mode->height;
+		for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+			if (w == supported_modes[i].width &&
+			    h == supported_modes[i].height &&
+			    supported_modes[i].hdr_mode == hdr->hdr_mode) {
+				mis2031->cur_mode = &supported_modes[i];
+				break;
+			}
+		}
+		if (i == ARRAY_SIZE(supported_modes)) {
+			dev_err(&mis2031->client->dev,
+				"not find hdr mode:%d %dx%d config\n",
+				hdr->hdr_mode, w, h);
+			ret = -EINVAL;
+		} else {
+			w = mis2031->cur_mode->hts_def - mis2031->cur_mode->width;
+			h = mis2031->cur_mode->vts_def - mis2031->cur_mode->height;
+			__v4l2_ctrl_modify_range(mis2031->hblank, w, w, 1, w);
+			__v4l2_ctrl_modify_range(mis2031->vblank, h,
+						 MIS2031_VTS_MAX - mis2031->cur_mode->height, 1, h);
+		}
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+
+		stream = *((u32 *)arg);
+
+		if (stream)
+			ret = mis2031_write_reg(mis2031->client, MIS2031_REG_CTRL_MODE,
+				 MIS2031_REG_VALUE_08BIT, MIS2031_MODE_STREAMING);
+		else
+			ret = mis2031_write_reg(mis2031->client, MIS2031_REG_CTRL_MODE,
+				 MIS2031_REG_VALUE_08BIT, MIS2031_MODE_SW_STANDBY);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long mis2031_compat_ioctl32(struct v4l2_subdev *sd,
+					unsigned int cmd, unsigned long arg)
+{
+	void __user *up = compat_ptr(arg);
+	struct rkmodule_inf *inf;
+	struct rkmodule_hdr_cfg *hdr;
+	struct preisp_hdrae_exp_s *hdrae;
+	long ret;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
+		if (!inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = mis2031_ioctl(sd, cmd, inf);
+		if (!ret) {
+			if (copy_to_user(up, inf, sizeof(*inf)))
+				ret = -EFAULT;
+		}
+		kfree(inf);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = mis2031_ioctl(sd, cmd, hdr);
+		if (!ret) {
+			if (copy_to_user(up, hdr, sizeof(*hdr)))
+				ret = -EFAULT;
+		}
+		kfree(hdr);
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(hdr, up, sizeof(*hdr));
+		if (!ret)
+			ret = mis2031_ioctl(sd, cmd, hdr);
+		else
+			ret = -EFAULT;
+		kfree(hdr);
+		break;
+	case PREISP_CMD_SET_HDRAE_EXP:
+		hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
+		if (!hdrae) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(hdrae, up, sizeof(*hdrae));
+		if (!ret)
+			ret = mis2031_ioctl(sd, cmd, hdrae);
+		else
+			ret = -EFAULT;
+		kfree(hdrae);
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		ret = copy_from_user(&stream, up, sizeof(u32));
+		if (!ret)
+			ret = mis2031_ioctl(sd, cmd, &stream);
+		else
+			ret = -EFAULT;
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+#endif
+
+static int __mis2031_start_stream(struct mis2031 *mis2031)
+{
+	int ret;
+
+	if (!mis2031->is_thunderboot) {
+		ret = mis2031_write_array(mis2031->client, mis2031->cur_mode->reg_list);
+		if (ret)
+			return ret;
+		/* In case these controls are set before streaming */
+		ret = __v4l2_ctrl_handler_setup(&mis2031->ctrl_handler);
+		if (ret)
+			return ret;
+	}
+
+	ret = mis2031_write_reg(mis2031->client, MIS2031_REG_CTRL_MODE,
+				 MIS2031_REG_VALUE_08BIT, MIS2031_MODE_STREAMING);
+	return ret;
+}
+
+static int __mis2031_stop_stream(struct mis2031 *mis2031)
+{
+	if (mis2031->is_thunderboot) {
+		mis2031->is_first_streamoff = true;
+		pm_runtime_put(&mis2031->client->dev);
+	}
+	return mis2031_write_reg(mis2031->client, MIS2031_REG_CTRL_MODE,
+				 MIS2031_REG_VALUE_08BIT, MIS2031_MODE_SW_STANDBY);
+}
+
+static int __mis2031_power_on(struct mis2031 *mis2031);
+static int mis2031_s_stream(struct v4l2_subdev *sd, int on)
+{
+	struct mis2031 *mis2031 = to_mis2031(sd);
+	struct i2c_client *client = mis2031->client;
+	int ret = 0;
+
+	mutex_lock(&mis2031->mutex);
+	on = !!on;
+	if (on == mis2031->streaming)
+		goto unlock_and_return;
+
+	if (on) {
+		if (mis2031->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
+			mis2031->is_thunderboot = false;
+			__mis2031_power_on(mis2031);
+		}
+
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		ret = __mis2031_start_stream(mis2031);
+		if (ret) {
+			v4l2_err(sd, "start stream failed while write regs\n");
+			pm_runtime_put(&client->dev);
+			goto unlock_and_return;
+		}
+	} else {
+		__mis2031_stop_stream(mis2031);
+		pm_runtime_put(&client->dev);
+	}
+
+	mis2031->streaming = on;
+
+unlock_and_return:
+	mutex_unlock(&mis2031->mutex);
+
+	return ret;
+}
+
+static int mis2031_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct mis2031 *mis2031 = to_mis2031(sd);
+	struct i2c_client *client = mis2031->client;
+	int ret = 0;
+
+	mutex_lock(&mis2031->mutex);
+
+	/* If the power state is not modified - no work to do. */
+	if (mis2031->power_on == !!on)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		if (!mis2031->is_thunderboot) {
+			ret = mis2031_write_array(mis2031->client, mis2031_global_regs);
+			if (ret) {
+				v4l2_err(sd, "could not set init registers\n");
+				pm_runtime_put_noidle(&client->dev);
+				goto unlock_and_return;
+			}
+		}
+
+		mis2031->power_on = true;
+	} else {
+		pm_runtime_put(&client->dev);
+		mis2031->power_on = false;
+	}
+
+unlock_and_return:
+	mutex_unlock(&mis2031->mutex);
+
+	return ret;
+}
+
+/* Calculate the delay in us by clock rate and clock cycles */
+static inline u32 mis2031_cal_delay(u32 cycles)
+{
+	return DIV_ROUND_UP(cycles, MIS2031_XVCLK_FREQ / 1000 / 1000);
+}
+
+static int __mis2031_power_on(struct mis2031 *mis2031)
+{
+	int ret;
+	u32 delay_us;
+	struct device *dev = &mis2031->client->dev;
+
+	if (!IS_ERR_OR_NULL(mis2031->pins_default)) {
+		ret = pinctrl_select_state(mis2031->pinctrl,
+						mis2031->pins_default);
+		if (ret < 0)
+			dev_err(dev, "could not set pins\n");
+	}
+	ret = clk_set_rate(mis2031->xvclk, MIS2031_XVCLK_FREQ);
+	if (ret < 0)
+		dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
+	if (clk_get_rate(mis2031->xvclk) != MIS2031_XVCLK_FREQ)
+		dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
+	ret = clk_prepare_enable(mis2031->xvclk);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable xvclk\n");
+		return ret;
+	}
+	if (mis2031->is_thunderboot)
+		return 0;
+
+	if (!IS_ERR(mis2031->reset_gpio))
+		gpiod_set_value_cansleep(mis2031->reset_gpio, 0);
+
+	ret = regulator_bulk_enable(MIS2031_NUM_SUPPLIES, mis2031->supplies);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable regulators\n");
+		goto disable_clk;
+	}
+
+	if (!IS_ERR(mis2031->reset_gpio))
+		gpiod_set_value_cansleep(mis2031->reset_gpio, 1);
+
+	usleep_range(500, 1000);
+	if (!IS_ERR(mis2031->pwdn_gpio))
+		gpiod_set_value_cansleep(mis2031->pwdn_gpio, 1);
+
+	if (!IS_ERR(mis2031->reset_gpio))
+		usleep_range(6000, 8000);
+	else
+		usleep_range(12000, 16000);
+
+	/* 8192 cycles prior to first SCCB transaction */
+	delay_us = mis2031_cal_delay(8192);
+	usleep_range(delay_us, delay_us * 2);
+	return 0;
+
+disable_clk:
+	clk_disable_unprepare(mis2031->xvclk);
+
+	return ret;
+}
+
+static void __mis2031_power_off(struct mis2031 *mis2031)
+{
+	int ret;
+	struct device *dev = &mis2031->client->dev;
+
+	clk_disable_unprepare(mis2031->xvclk);
+	if (mis2031->is_thunderboot) {
+		if (mis2031->is_first_streamoff) {
+			mis2031->is_thunderboot = false;
+			mis2031->is_first_streamoff = false;
+		} else {
+			return;
+		}
+	}
+
+	if (!IS_ERR(mis2031->pwdn_gpio))
+		gpiod_set_value_cansleep(mis2031->pwdn_gpio, 0);
+	if (!IS_ERR(mis2031->reset_gpio))
+		gpiod_set_value_cansleep(mis2031->reset_gpio, 0);
+	if (!IS_ERR_OR_NULL(mis2031->pins_sleep)) {
+		ret = pinctrl_select_state(mis2031->pinctrl,
+					   mis2031->pins_sleep);
+		if (ret < 0)
+			dev_dbg(dev, "could not set pins\n");
+	}
+	regulator_bulk_disable(MIS2031_NUM_SUPPLIES, mis2031->supplies);
+}
+
+static int __maybe_unused mis2031_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct mis2031 *mis2031 = to_mis2031(sd);
+
+	return __mis2031_power_on(mis2031);
+}
+
+static int __maybe_unused mis2031_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct mis2031 *mis2031 = to_mis2031(sd);
+
+	__mis2031_power_off(mis2031);
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int mis2031_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct mis2031 *mis2031 = to_mis2031(sd);
+	struct v4l2_mbus_framefmt *try_fmt =
+				v4l2_subdev_get_try_format(sd, fh->pad, 0);
+	const struct mis2031_mode *def_mode = &supported_modes[0];
+
+	mutex_lock(&mis2031->mutex);
+	/* Initialize try_fmt */
+	try_fmt->width = def_mode->width;
+	try_fmt->height = def_mode->height;
+	try_fmt->code = def_mode->bus_fmt;
+	try_fmt->field = V4L2_FIELD_NONE;
+
+	mutex_unlock(&mis2031->mutex);
+	/* No crop or compose */
+
+	return 0;
+}
+#endif
+
+static int mis2031_enum_frame_interval(struct v4l2_subdev *sd,
+						struct v4l2_subdev_pad_config *cfg,
+						struct v4l2_subdev_frame_interval_enum *fie)
+{
+	if (fie->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	fie->code = supported_modes[fie->index].bus_fmt;
+	fie->width = supported_modes[fie->index].width;
+	fie->height = supported_modes[fie->index].height;
+	fie->interval = supported_modes[fie->index].max_fps;
+	fie->reserved[0] = supported_modes[fie->index].hdr_mode;
+	return 0;
+}
+
+static const struct dev_pm_ops mis2031_pm_ops = {
+	SET_RUNTIME_PM_OPS(mis2031_runtime_suspend,
+			   mis2031_runtime_resume, NULL)
+};
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static const struct v4l2_subdev_internal_ops mis2031_internal_ops = {
+	.open = mis2031_open,
+};
+#endif
+
+static const struct v4l2_subdev_core_ops mis2031_core_ops = {
+	.s_power = mis2031_s_power,
+	.ioctl = mis2031_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl32 = mis2031_compat_ioctl32,
+#endif
+};
+
+static const struct v4l2_subdev_video_ops mis2031_video_ops = {
+	.s_stream = mis2031_s_stream,
+	.g_frame_interval = mis2031_g_frame_interval,
+};
+
+static const struct v4l2_subdev_pad_ops mis2031_pad_ops = {
+	.enum_mbus_code = mis2031_enum_mbus_code,
+	.enum_frame_size = mis2031_enum_frame_sizes,
+	.enum_frame_interval = mis2031_enum_frame_interval,
+	.get_fmt = mis2031_get_fmt,
+	.set_fmt = mis2031_set_fmt,
+	.get_mbus_config = mis2031_g_mbus_config,
+};
+
+static const struct v4l2_subdev_ops mis2031_subdev_ops = {
+	.core = &mis2031_core_ops,
+	.video = &mis2031_video_ops,
+	.pad = &mis2031_pad_ops,
+};
+
+static void mis2031_modify_fps_info(struct mis2031 *mis2031)
+{
+	const struct mis2031_mode *mode = mis2031->cur_mode;
+
+	mis2031->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
+						mis2031->cur_vts;
+}
+
+static int mis2031_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct mis2031 *mis2031 = container_of(ctrl->handler,
+							struct mis2031, ctrl_handler);
+	struct i2c_client *client = mis2031->client;
+	s64 max;
+	int ret = 0;
+	u32 val = 0;
+
+	/* Propagate change of current control to all related controls */
+	switch (ctrl->id) {
+	case V4L2_CID_VBLANK:
+		/* Update max exposure while meeting expected vblanking */
+		max = mis2031->cur_mode->height + ctrl->val - 8;
+		__v4l2_ctrl_modify_range(mis2031->exposure,
+					 mis2031->exposure->minimum, max,
+					 mis2031->exposure->step,
+					 mis2031->exposure->default_value);
+		break;
+	}
+
+	if (!pm_runtime_get_if_in_use(&client->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		dev_dbg(&client->dev, "set exposure 0x%x\n", ctrl->val);
+		if (mis2031->cur_mode->hdr_mode == NO_HDR) {
+			val = ctrl->val;
+			/* 4 least significant bits of expsoure are fractional part */
+			ret = mis2031_write_reg(mis2031->client,
+						MIS2031_REG_EXPOSURE_H,
+						MIS2031_REG_VALUE_08BIT,
+						MIS2031_FETCH_EXP_H(val));
+			ret |= mis2031_write_reg(mis2031->client,
+						 MIS2031_REG_EXPOSURE_L,
+						 MIS2031_REG_VALUE_08BIT,
+						 MIS2031_FETCH_EXP_L(val));
+			ret |= mis2031_write_reg(mis2031->client,
+						 MIS2031_REG_GAIN_EXP_VALID,
+						 MIS2031_REG_VALUE_08BIT,
+						 MIS2031_REG_GAIN_EXP_VALID_VAL);
+		}
+		break;
+	case V4L2_CID_ANALOGUE_GAIN:
+		dev_dbg(&client->dev, "set gain 0x%x\n", ctrl->val);
+		if (mis2031->cur_mode->hdr_mode == NO_HDR)
+			ret = mis2031_set_gain_reg(mis2031, ctrl->val);
+		break;
+	case V4L2_CID_VBLANK:
+		dev_dbg(&client->dev, "set vblank 0x%x\n", ctrl->val);
+		ret = mis2031_write_reg(mis2031->client,
+					MIS2031_REG_VTS_H,
+					MIS2031_REG_VALUE_08BIT,
+					(ctrl->val + mis2031->cur_mode->height)
+					>> 8);
+		ret |= mis2031_write_reg(mis2031->client,
+					 MIS2031_REG_VTS_L,
+					 MIS2031_REG_VALUE_08BIT,
+					 (ctrl->val + mis2031->cur_mode->height)
+					 & 0xff);
+		mis2031->cur_vts = ctrl->val + mis2031->cur_mode->height;
+		if (mis2031->cur_vts != mis2031->cur_mode->vts_def)
+			mis2031_modify_fps_info(mis2031);
+		break;
+	case V4L2_CID_TEST_PATTERN:
+		ret = mis2031_enable_test_pattern(mis2031, ctrl->val);
+		break;
+	case V4L2_CID_HFLIP:
+		ret = mis2031_read_reg(mis2031->client, MIS2031_FLIP_MIRROR_REG,
+				       MIS2031_REG_VALUE_08BIT, &val);
+		if (ctrl->val)
+			val |= MIRROR_BIT_MASK;
+		else
+			val &= ~MIRROR_BIT_MASK;
+		mis2031_set_orientation_reg(mis2031, val);
+		break;
+	case V4L2_CID_VFLIP:
+		ret = mis2031_read_reg(mis2031->client, MIS2031_FLIP_MIRROR_REG,
+				       MIS2031_REG_VALUE_08BIT, &val);
+		if (ctrl->val)
+			val |= FLIP_BIT_MASK;
+		else
+			val &= ~FLIP_BIT_MASK;
+		mis2031_set_orientation_reg(mis2031, val);
+		break;
+	default:
+		dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
+			 __func__, ctrl->id, ctrl->val);
+		break;
+	}
+
+	pm_runtime_put(&client->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops mis2031_ctrl_ops = {
+	.s_ctrl = mis2031_set_ctrl,
+};
+
+static int mis2031_initialize_controls(struct mis2031 *mis2031)
+{
+	const struct mis2031_mode *mode;
+	struct v4l2_ctrl_handler *handler;
+	struct v4l2_ctrl *ctrl;
+	s64 exposure_max, vblank_def;
+	u32 h_blank;
+	int ret;
+
+	handler = &mis2031->ctrl_handler;
+	mode = mis2031->cur_mode;
+	ret = v4l2_ctrl_handler_init(handler, 9);
+	if (ret)
+		return ret;
+	handler->lock = &mis2031->mutex;
+
+	ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
+				      0, 0, link_freq_menu_items);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
+			  0, PIXEL_RATE_WITH_315M_10BIT, 1, PIXEL_RATE_WITH_315M_10BIT);
+
+	h_blank = mode->hts_def - mode->width;
+	mis2031->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
+					    h_blank, h_blank, 1, h_blank);
+	if (mis2031->hblank)
+		mis2031->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+	vblank_def = mode->vts_def - mode->height;
+	mis2031->vblank = v4l2_ctrl_new_std(handler, &mis2031_ctrl_ops,
+					    V4L2_CID_VBLANK, vblank_def,
+					    MIS2031_VTS_MAX - mode->height,
+					    1, vblank_def);
+	mis2031->cur_fps = mode->max_fps;
+	exposure_max = mode->vts_def - 8;
+	mis2031->exposure = v4l2_ctrl_new_std(handler, &mis2031_ctrl_ops,
+					      V4L2_CID_EXPOSURE, MIS2031_EXPOSURE_MIN,
+					      exposure_max, MIS2031_EXPOSURE_STEP,
+					      mode->exp_def);
+	mis2031->anal_gain = v4l2_ctrl_new_std(handler, &mis2031_ctrl_ops,
+					       V4L2_CID_ANALOGUE_GAIN, MIS2031_GAIN_MIN,
+					       MIS2031_GAIN_MAX, MIS2031_GAIN_STEP,
+					       MIS2031_GAIN_DEFAULT);
+	mis2031->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
+							    &mis2031_ctrl_ops,
+					V4L2_CID_TEST_PATTERN,
+					ARRAY_SIZE(mis2031_test_pattern_menu) - 1,
+					0, 0, mis2031_test_pattern_menu);
+	v4l2_ctrl_new_std(handler, &mis2031_ctrl_ops,
+				V4L2_CID_HFLIP, 0, 1, 1, 0);
+	v4l2_ctrl_new_std(handler, &mis2031_ctrl_ops,
+				V4L2_CID_VFLIP, 0, 1, 1, 0);
+	if (handler->error) {
+		ret = handler->error;
+		dev_err(&mis2031->client->dev,
+			"Failed to init controls(%d)\n", ret);
+		goto err_free_handler;
+	}
+
+	mis2031->subdev.ctrl_handler = handler;
+
+	return 0;
+
+err_free_handler:
+	v4l2_ctrl_handler_free(handler);
+
+	return ret;
+}
+
+static int mis2031_check_sensor_id(struct mis2031 *mis2031,
+				   struct i2c_client *client)
+{
+	struct device *dev = &mis2031->client->dev;
+	u32 id = 0;
+	int ret;
+
+	if (mis2031->is_thunderboot) {
+		dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
+		return 0;
+	}
+
+	ret = mis2031_read_reg(client, MIS2031_REG_CHIP_ID,
+			       MIS2031_REG_VALUE_16BIT, &id);
+	if (id != CHIP_ID) {
+		dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
+		return -ENODEV;
+	}
+
+	dev_info(dev, "Detected OV%06x sensor\n", CHIP_ID);
+
+	return 0;
+}
+
+static int mis2031_configure_regulators(struct mis2031 *mis2031)
+{
+	unsigned int i;
+
+	for (i = 0; i < MIS2031_NUM_SUPPLIES; i++)
+		mis2031->supplies[i].supply = mis2031_supply_names[i];
+
+	return devm_regulator_bulk_get(&mis2031->client->dev,
+				       MIS2031_NUM_SUPPLIES,
+				       mis2031->supplies);
+}
+
+static int mis2031_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct device_node *node = dev->of_node;
+	struct mis2031 *mis2031;
+	struct v4l2_subdev *sd;
+	char facing[2];
+	int ret;
+
+	dev_info(dev, "driver version: %02x.%02x.%02x",
+		 DRIVER_VERSION >> 16,
+		 (DRIVER_VERSION & 0xff00) >> 8,
+		 DRIVER_VERSION & 0x00ff);
+
+	mis2031 = devm_kzalloc(dev, sizeof(*mis2031), GFP_KERNEL);
+	if (!mis2031)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
+				   &mis2031->module_index);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
+				       &mis2031->module_facing);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
+				       &mis2031->module_name);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
+				       &mis2031->len_name);
+	if (ret) {
+		dev_err(dev, "could not get module information!\n");
+		return -EINVAL;
+	}
+
+	mis2031->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
+	mis2031->client = client;
+	mis2031->cur_mode = &supported_modes[0];
+
+	mis2031->xvclk = devm_clk_get(dev, "xvclk");
+	if (IS_ERR(mis2031->xvclk)) {
+		dev_err(dev, "Failed to get xvclk\n");
+		return -EINVAL;
+	}
+
+	if (mis2031->is_thunderboot) {
+		mis2031->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
+		if (IS_ERR(mis2031->reset_gpio))
+			dev_warn(dev, "Failed to get reset-gpios\n");
+
+		mis2031->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
+		if (IS_ERR(mis2031->pwdn_gpio))
+			dev_warn(dev, "Failed to get pwdn-gpios\n");
+	} else {
+		mis2031->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+		if (IS_ERR(mis2031->reset_gpio))
+			dev_warn(dev, "Failed to get reset-gpios\n");
+
+		mis2031->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
+		if (IS_ERR(mis2031->pwdn_gpio))
+			dev_warn(dev, "Failed to get pwdn-gpios\n");
+	}
+	mis2031->pinctrl = devm_pinctrl_get(dev);
+	if (!IS_ERR(mis2031->pinctrl)) {
+		mis2031->pins_default =
+			pinctrl_lookup_state(mis2031->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_DEFAULT);
+		if (IS_ERR(mis2031->pins_default))
+			dev_err(dev, "could not get default pinstate\n");
+
+		mis2031->pins_sleep =
+			pinctrl_lookup_state(mis2031->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_SLEEP);
+		if (IS_ERR(mis2031->pins_sleep))
+			dev_err(dev, "could not get sleep pinstate\n");
+	} else {
+		dev_err(dev, "no pinctrl\n");
+	}
+
+	ret = mis2031_configure_regulators(mis2031);
+	if (ret) {
+		dev_err(dev, "Failed to get power regulators\n");
+		return ret;
+	}
+
+	mutex_init(&mis2031->mutex);
+
+	sd = &mis2031->subdev;
+	v4l2_i2c_subdev_init(sd, client, &mis2031_subdev_ops);
+	ret = mis2031_initialize_controls(mis2031);
+	if (ret)
+		goto err_destroy_mutex;
+
+	ret = __mis2031_power_on(mis2031);
+	if (ret)
+		goto err_free_handler;
+
+	ret = mis2031_check_sensor_id(mis2031, client);
+	if (ret)
+		goto err_power_off;
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	sd->internal_ops = &mis2031_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+		     V4L2_SUBDEV_FL_HAS_EVENTS;
+#endif
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	mis2031->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &mis2031->pad);
+	if (ret < 0)
+		goto err_power_off;
+#endif
+
+	memset(facing, 0, sizeof(facing));
+	if (strcmp(mis2031->module_facing, "back") == 0)
+		facing[0] = 'b';
+	else
+		facing[0] = 'f';
+
+	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
+		 mis2031->module_index, facing,
+		 MIS2031_NAME, dev_name(sd->dev));
+	ret = v4l2_async_register_subdev_sensor_common(sd);
+	if (ret) {
+		dev_err(dev, "v4l2 async register subdev failed\n");
+		goto err_clean_entity;
+	}
+
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	if (mis2031->is_thunderboot)
+		pm_runtime_get_sync(dev);
+	else
+		pm_runtime_idle(dev);
+
+	return 0;
+
+err_clean_entity:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+err_power_off:
+	__mis2031_power_off(mis2031);
+err_free_handler:
+	v4l2_ctrl_handler_free(&mis2031->ctrl_handler);
+err_destroy_mutex:
+	mutex_destroy(&mis2031->mutex);
+
+	return ret;
+}
+
+static int mis2031_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct mis2031 *mis2031 = to_mis2031(sd);
+
+	v4l2_async_unregister_subdev(sd);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+	v4l2_ctrl_handler_free(&mis2031->ctrl_handler);
+	mutex_destroy(&mis2031->mutex);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		__mis2031_power_off(mis2031);
+	pm_runtime_set_suspended(&client->dev);
+
+	return 0;
+}
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id mis2031_of_match[] = {
+	{ .compatible = "imagedesign,mis2031" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mis2031_of_match);
+#endif
+
+static const struct i2c_device_id mis2031_match_id[] = {
+	{ "imagedesign,mis2031", 0 },
+	{ },
+};
+
+static struct i2c_driver mis2031_i2c_driver = {
+	.driver = {
+		.name = MIS2031_NAME,
+		.pm = &mis2031_pm_ops,
+		.of_match_table = of_match_ptr(mis2031_of_match),
+	},
+	.probe = &mis2031_probe,
+	.remove = &mis2031_remove,
+	.id_table = mis2031_match_id,
+};
+
+static int __init sensor_mod_init(void)
+{
+	return i2c_add_driver(&mis2031_i2c_driver);
+}
+
+static void __exit sensor_mod_exit(void)
+{
+	i2c_del_driver(&mis2031_i2c_driver);
+}
+
+#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
+subsys_initcall(sensor_mod_init);
+#else
+device_initcall_sync(sensor_mod_init);
+#endif
+module_exit(sensor_mod_exit);
+
+MODULE_DESCRIPTION("chengdu image design mis2031 sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/mis4001.c b/kernel/drivers/media/i2c/mis4001.c
new file mode 100644
index 0000000..a23f73a
--- /dev/null
+++ b/kernel/drivers/media/i2c/mis4001.c
@@ -0,0 +1,1643 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mis4001 driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * V0.0X01.0X01 first version
+ */
+
+//#define DEBUG
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/rk-camera-module.h>
+#include <linux/rk-preisp.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <linux/pinctrl/consumer.h>
+
+#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x02)
+
+#ifndef V4L2_CID_DIGITAL_GAIN
+#define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
+#endif
+
+#define MIS4001_LANES			2
+#define MIS4001_BITS_PER_SAMPLE		10
+#define MIS4001_LINK_FREQ		337500000
+#define PIXEL_RATE_WITH_337M_10BIT	(MIS4001_LINK_FREQ * 2 * \
+                            MIS4001_LANES / MIS4001_BITS_PER_SAMPLE)
+#define MIS4001_XVCLK_FREQ		    27000000
+
+#define MIS4001_CHIP_ID			0x1311
+#define MIS4001_REG_CHIP_ID		0x3000
+
+#define MIS4001_REG_CTRL_MODE		0x3006
+#define MIS4001_MODE_SW_STANDBY		0x3
+#define MIS4001_MODE_STREAMING		0x0
+
+#define MIS4001_REG_EXPOSURE_H		0x3100
+#define MIS4001_REG_EXPOSURE_L		0x3101
+#define	MIS4001_EXPOSURE_MIN		2
+#define	MIS4001_EXPOSURE_STEP		1
+#define MIS4001_VTS_MAX			0x7fff
+
+#define MIS4001_REG_DIG_GAIN		0x3A00
+#define MIS4001_REG_DIG_FINE_GAIN	0x3A01
+#define MIS4001_REG_ANA_GAIN		0x3102
+#define MIS4001_GAIN_MIN		0x0080
+#define MIS4001_GAIN_MAX		32768
+#define MIS4001_GAIN_STEP		1
+#define MIS4001_GAIN_DEFAULT		0x80
+
+#define MIS4001_REG_TEST_PATTERN	0x3400
+#define MIS4001_TEST_PATTERN_BIT_MASK	BIT(3)
+
+#define MIS4001_REG_VTS_H		0x310c
+#define MIS4001_REG_VTS_L		0x310d
+
+#define MIS4001_FLIP_MIRROR_REG		0x3007
+#define MIRROR_BIT_MASK			BIT(0)
+#define FLIP_BIT_MASK			BIT(1)
+
+
+#define MIS4001_FETCH_EXP_H(VAL)	(((VAL) >> 8) & 0xFF)
+#define MIS4001_FETCH_EXP_L(VAL)	((VAL) & 0xFF)
+
+#define MIS4001_FETCH_AGAIN_H(VAL)	(((VAL) >> 8) & 0xFF)
+#define MIS4001_FETCH_AGAIN_L(VAL)	((VAL) & 0xFF)
+
+#define MIS4001_FETCH_MIRROR(VAL, ENABLE)	(ENABLE ? VAL | 0x01 : VAL & 0xFE)
+#define MIS4001_FETCH_FLIP(VAL, ENABLE)		(ENABLE ? VAL | 0x02 : VAL & 0xFD)
+
+#define REG_NULL			0xFFFF
+
+#define MIS4001_REG_VALUE_08BIT		1
+#define MIS4001_REG_VALUE_16BIT		2
+#define MIS4001_REG_VALUE_24BIT		3
+
+#define OF_CAMERA_PINCTRL_STATE_DEFAULT	"rockchip,camera_default"
+#define OF_CAMERA_PINCTRL_STATE_SLEEP	"rockchip,camera_sleep"
+#define MIS4001_NAME			"mis4001"
+
+
+static const char * const mis4001_supply_names[] = {
+	"avdd",		/* Analog power */
+	"dovdd",	/* Digital I/O power */
+	"dvdd",		/* Digital core power */
+};
+
+#define MIS4001_NUM_SUPPLIES ARRAY_SIZE(mis4001_supply_names)
+
+struct regval {
+	u16 addr;
+	u8 val;
+};
+
+struct mis4001_mode {
+	u32 bus_fmt;
+	u32 width;
+	u32 height;
+	struct v4l2_fract max_fps;
+	u32 hts_def;
+	u32 vts_def;
+	u32 exp_def;
+	const struct regval *reg_list;
+	u32 hdr_mode;
+	u32 vc[PAD_MAX];
+};
+
+struct mis4001 {
+	struct i2c_client	*client;
+	struct clk		*xvclk;
+	struct gpio_desc	*reset_gpio;
+	struct gpio_desc	*pwdn_gpio;
+	struct regulator_bulk_data supplies[MIS4001_NUM_SUPPLIES];
+
+	struct pinctrl		*pinctrl;
+	struct pinctrl_state	*pins_default;
+	struct pinctrl_state	*pins_sleep;
+
+	struct v4l2_subdev	subdev;
+	struct media_pad	pad;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl	*exposure;
+	struct v4l2_ctrl	*anal_gain;
+	struct v4l2_ctrl	*digi_gain;
+	struct v4l2_ctrl	*hblank;
+	struct v4l2_ctrl	*vblank;
+	struct v4l2_ctrl	*test_pattern;
+	struct mutex		mutex;
+	bool			streaming;
+	bool			power_on;
+	const struct mis4001_mode *cur_mode;
+	struct v4l2_fract	cur_fps;
+	u32			module_index;
+	const char		*module_facing;
+	const char		*module_name;
+	const char		*len_name;
+	u32			cur_vts;
+};
+
+#define to_mis4001(sd) container_of(sd, struct mis4001, subdev)
+
+/*
+ * Xclk 27Mhz
+ */
+static const struct regval mis4001_global_regs[] = {
+	{REG_NULL, 0x00},
+};
+
+/*
+ * Xclk 27Mhz
+ * max_framerate 25fps
+ * mipi_datarate per lane 337.5Mbps, 2lane
+ */
+static const struct regval mis4001_linear_10_2560x1440_regs[] = {
+	{0x300a, 0x01},
+	{0x3006, 0x02},
+	{0x4220, 0x2b},
+	{0x4221, 0x6b},
+	{0x4222, 0xab},
+	{0x4223, 0xeb},
+	{0x3011, 0x2b},
+	{0x3302, 0x02},
+	{0x3307, 0x64},
+	{0x3306, 0x01},
+	{0x3309, 0x01},
+	{0x3308, 0x03},
+	{0x330a, 0x04},
+	{0x330b, 0x09},
+	{0x310f, 0x68},
+	{0x310e, 0x0d},
+	{0x310d, 0x25},
+	{0x310c, 0x06},
+	{0x3115, 0x10},
+	{0x3114, 0x00},
+	{0x3117, 0x0f},
+	{0x3116, 0x0a},
+	{0x3111, 0xfc},
+	{0x3110, 0x00},
+	{0x3113, 0x9d},
+	{0x3112, 0x06},
+	{0x3128, 0x0f},//FW<4096 FFF
+	{0x3129, 0xff},
+	{0x3012, 0x03},
+	{0x3f00, 0x01},
+	{0x3f02, 0x07},
+	{0x3f01, 0x00},
+	{0x3f04, 0x2a},
+	{0x3f03, 0x00},
+	{0x3f06, 0xa5},
+	{0x3f05, 0x04},
+	{0x3f08, 0xff},
+	{0x3f07, 0x1f},
+	{0x3f0a, 0xa4},
+	{0x3f09, 0x01},
+	{0x3f0c, 0x38},
+	{0x3f0b, 0x00},
+	{0x3f0e, 0xff},
+	{0x3f0d, 0x1f},
+	{0x3f10, 0xff},
+	{0x3f0f, 0x1f},
+	{0x3f13, 0x07},
+	{0x3f12, 0x00},
+	{0x3f15, 0x9d},
+	{0x3f14, 0x01},
+	{0x3f17, 0x31},
+	{0x3f16, 0x00},
+	{0x3f19, 0x73},
+	{0x3f18, 0x01},
+	{0x3f1b, 0x00},
+	{0x3f1a, 0x00},
+	{0x3f1d, 0xa9},
+	{0x3f1c, 0x04},
+	{0x3f1f, 0xff},
+	{0x3f1e, 0x1f},
+	{0x3f21, 0xff},
+	{0x3f20, 0x1f},
+	{0x3f23, 0x85},
+	{0x3f22, 0x00},
+	{0x3f25, 0x27},
+	{0x3f24, 0x01},
+	{0x3f28, 0x46},
+	{0x3f27, 0x00},
+	{0x3f2a, 0x07},
+	{0x3f29, 0x00},
+	{0x3f2c, 0x3f},
+	{0x3f2b, 0x00},
+	{0x3f2e, 0x70},
+	{0x3f2d, 0x01},
+	{0x3f30, 0x38},
+	{0x3f2f, 0x00},
+	{0x3f32, 0x3f},
+	{0x3f31, 0x00},
+	{0x3f34, 0xd1},
+	{0x3f33, 0x00},
+	{0x3f36, 0xc0},
+	{0x3f35, 0x00},
+	{0x3f38, 0x2f},
+	{0x3f37, 0x02},
+	{0x3f3a, 0x5d},
+	{0x3f39, 0x02},
+	{0x3f4f, 0x5d},
+	{0x3f4e, 0x02},
+	{0x3f51, 0x5d},
+	{0x3f50, 0x02},
+	{0x3f53, 0x5d},
+	{0x3f52, 0x02},
+	{0x3f55, 0x5d},
+	{0x3f54, 0x02},
+	{0x3f3c, 0x9a},
+	{0x3f3b, 0x00},
+	{0x3f3e, 0x09},
+	{0x3f3d, 0x04},
+	{0x3f40, 0x93},
+	{0x3f3f, 0x01},
+	{0x3f42, 0x8f},
+	{0x3f41, 0x00},
+	{0x3f44, 0xb0},
+	{0x3f43, 0x04},
+	{0x3129, 0x45},
+	{0x3128, 0x00},
+	{0x312b, 0x4a},
+	{0x312a, 0x00},
+	{0x312f, 0xb2},
+	{0x312e, 0x00},
+	{0x3124, 0x09},
+	{0x4200, 0x09},
+	{0x4201, 0x00},
+	{0x4214, 0x60},
+	{0x420E, 0x94},
+	{0x4240, 0x8d},
+	{0x4242, 0x03},
+	{0x4224, 0x00},
+	{0x4225, 0x0a},
+	{0x4226, 0xa0},
+	{0x4227, 0x05},
+	{0x4228, 0x00},
+	{0x4229, 0x0a},
+	{0x422a, 0xa0},
+	{0x422b, 0x05},
+	{0x422c, 0x00},
+	{0x422d, 0x0a},
+	{0x422e, 0xa0},
+	{0x422f, 0x05},
+	{0x4230, 0x00},
+	{0x4231, 0x0a},
+	{0x4232, 0xa0},
+	{0x4233, 0x05},
+	{0x4509, 0x0f},
+	{0x4505, 0x00},
+	{0x4501, 0xff},
+	{0x4502, 0x33},
+	{0x4503, 0x11},
+	{0x4501, 0xf0},
+	{0x4502, 0x30},
+	{0x4503, 0x10},
+	{0x3A01, 0xA0},
+	{0x401E, 0x3C},
+	{0x401d, 0xa0},
+	{0x3012, 0x03},
+	{0x3E00, 0x00},
+	{0x3E01, 0x10},
+	{0x400D, 0x30},
+	{0x3500, 0x1b},  //1b/13
+	{0x3501, 0x03},
+	{0x3508, 0x0a},
+	{0x3508, 0x04},
+	{0x3513, 0x01},
+	{0x3514, 0x09},
+	{0x3515, 0x0b},
+	{0x3702, 0x80},
+	{0x3704, 0x80},
+	{0x3706, 0x80},
+	{0x3708, 0x80},
+	{0x400D, 0x30},  //优化奇偶行及行噪
+	{0x4004, 0x20},  //RCS CM电流最小优化横带
+	{0x4005, 0x0c},
+	{0x4009, 0x09},
+	{0x400a, 0x48},
+	{0x4006, 0x86},
+	{0x4019, 0x08},
+	{0x4003, 0x0a},
+	{0x3f42, 0x58},
+	{0x3f49, 0x60},
+	{0x3f38, 0x4d},
+	{REG_NULL, 0x00},
+};
+
+static const struct mis4001_mode supported_modes[] = {
+	{
+		.width = 2560,
+		.height = 1440,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 250000,
+		},
+		.exp_def = 0x0040,
+		.hts_def = 3432,
+		.vts_def = 1573,
+		.bus_fmt = MEDIA_BUS_FMT_SGRBG10_1X10,
+		.reg_list = mis4001_linear_10_2560x1440_regs,
+		.hdr_mode = NO_HDR,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	}
+};
+
+static const s64 link_freq_menu_items[] = {
+	MIS4001_LINK_FREQ
+};
+
+static const char * const mis4001_test_pattern_menu[] = {
+	"Disabled",
+	"Vertical Color Bar Type 1",
+	"Vertical Color Bar Type 2",
+	"Vertical Color Bar Type 3",
+	"Vertical Color Bar Type 4"
+};
+
+static int mis4001_write_reg(struct i2c_client *client, u16 reg,
+			    u32 len, u32 val)
+{
+	u32 buf_i, val_i;
+	u8 buf[6];
+	u8 *val_p;
+	__be32 val_be;
+
+	if (len > 4)
+		return -EINVAL;
+
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xff;
+
+	val_be = cpu_to_be32(val);
+	val_p = (u8 *)&val_be;
+	buf_i = 2;
+	val_i = 4 - len;
+
+	while (val_i < 4)
+		buf[buf_i++] = val_p[val_i++];
+
+	if (i2c_master_send(client, buf, len + 2) != len + 2)
+		return -EIO;
+	return 0;
+}
+
+static int mis4001_write_array(struct i2c_client *client,
+			       const struct regval *regs)
+{
+	u32 i;
+	int ret = 0;
+
+	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++)
+		ret = mis4001_write_reg(client, regs[i].addr,
+					MIS4001_REG_VALUE_08BIT, regs[i].val);
+
+	return ret;
+}
+
+/* Read registers up to 4 at a time */
+static int mis4001_read_reg(struct i2c_client *client, u16 reg, unsigned int len,
+			    u32 *val)
+{
+	struct i2c_msg msgs[2];
+	u8 *data_be_p;
+	__be32 data_be = 0;
+	__be16 reg_addr_be = cpu_to_be16(reg);
+	int ret;
+
+	if (len > 4 || !len)
+		return -EINVAL;
+
+	data_be_p = (u8 *)&data_be;
+	/* Write register address */
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = 2;
+	msgs[0].buf = (u8 *)&reg_addr_be;
+
+	/* Read data from register */
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = len;
+	msgs[1].buf = &data_be_p[4 - len];
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs))
+		return -EIO;
+
+	*val = be32_to_cpu(data_be);
+
+	return 0;
+}
+
+static void mis4001_set_orientation_reg(struct mis4001 *mis4001, u32 en_flip_mir)
+{
+	switch (en_flip_mir) {
+	case  0:
+		mis4001_write_reg(mis4001->client, 0x3007, MIS4001_REG_VALUE_08BIT, 0x00);
+		mis4001_write_reg(mis4001->client, 0x3111, MIS4001_REG_VALUE_08BIT, 0xFC);
+		mis4001_write_reg(mis4001->client, 0x3113, MIS4001_REG_VALUE_08BIT, 0x9D);
+		mis4001_write_reg(mis4001->client, 0x3115, MIS4001_REG_VALUE_08BIT, 0x10);
+		mis4001_write_reg(mis4001->client, 0x3117, MIS4001_REG_VALUE_08BIT, 0x0F);
+		break;
+	case  1:
+		mis4001_write_reg(mis4001->client, 0x3007, MIS4001_REG_VALUE_08BIT, 0x01);
+		mis4001_write_reg(mis4001->client, 0x3111, MIS4001_REG_VALUE_08BIT, 0xFC);
+		mis4001_write_reg(mis4001->client, 0x3113, MIS4001_REG_VALUE_08BIT, 0x9D);
+		mis4001_write_reg(mis4001->client, 0x3115, MIS4001_REG_VALUE_08BIT, 0x11);
+		mis4001_write_reg(mis4001->client, 0x3117, MIS4001_REG_VALUE_08BIT, 0x10);
+		break;
+	case  2:
+		mis4001_write_reg(mis4001->client, 0x3007, MIS4001_REG_VALUE_08BIT, 0x01);
+		mis4001_write_reg(mis4001->client, 0x3111, MIS4001_REG_VALUE_08BIT, 0xFD);
+		mis4001_write_reg(mis4001->client, 0x3113, MIS4001_REG_VALUE_08BIT, 0x9E);
+		mis4001_write_reg(mis4001->client, 0x3115, MIS4001_REG_VALUE_08BIT, 0x10);
+		mis4001_write_reg(mis4001->client, 0x3117, MIS4001_REG_VALUE_08BIT, 0x0F);
+		break;
+	case  3:
+		mis4001_write_reg(mis4001->client, 0x3007, MIS4001_REG_VALUE_08BIT, 0x03);
+		mis4001_write_reg(mis4001->client, 0x3113, MIS4001_REG_VALUE_08BIT, 0XFD);
+		mis4001_write_reg(mis4001->client, 0x3207, MIS4001_REG_VALUE_08BIT, 0x9E);
+		mis4001_write_reg(mis4001->client, 0x3115, MIS4001_REG_VALUE_08BIT, 0x11);
+		mis4001_write_reg(mis4001->client, 0x3117, MIS4001_REG_VALUE_08BIT, 0x0F);
+		break;
+	default:
+		break;
+	}
+}
+
+static int mis4001_set_gain_reg(struct mis4001 *mis4001, u32 gain)
+{
+	u8 gain_h, gain_l, u8Reg0x3102, u8Reg0x3a00, u8Reg0x3a01, u8Reg0x4003;
+	int ret = 0;
+	u8 u8Reg0x401d = 0;
+
+	if (gain < 128)
+		gain = 128;
+	else if (gain > MIS4001_GAIN_MAX)
+		gain = MIS4001_GAIN_MAX;
+
+	if (128 <= gain && gain < 256) {//128 * 2
+		gain_h = 0;
+		gain_l = (gain - 128) / 4;
+		u8Reg0x3a00 = 0;
+		u8Reg0x3a01 = 160;  //128->160, 高亮偏粉
+	} else if (gain >= 256 && gain < 512) {//128 * 4
+		gain_h = 1;
+		gain_l = (gain - 256) / 8;
+		u8Reg0x3a00 = 0;
+		u8Reg0x3a01 = 160;
+	} else if (gain >= 512 && gain < 1024) {//128 * 8
+		gain_h = 2;
+		gain_l = (gain - 512) / 16;
+		u8Reg0x3a00 = 0;
+		u8Reg0x3a01 = 160;
+	} else if (gain >= 1024 && gain < 2048) {//128 * 16
+		gain_h = 3;
+		gain_l = (gain - 1024) / 32;
+		u8Reg0x3a00 = 0;
+		u8Reg0x3a01 = 160;
+	} else if (gain >= 2048 && gain < 4096) {//128 * 32  Dgain
+		gain_h = 3;
+		gain_l = 31;
+		u8Reg0x3a00 = 0;
+		u8Reg0x3a01 = ((gain - 2048) / 16 + 128);
+		u8Reg0x3a01 = (u8Reg0x3a01 < 160) ? 160 : u8Reg0x3a01;
+	} else if (gain >= 4096 && gain < 8192) {//128 * 64
+		gain_h = 3;
+		gain_l = 31;
+		u8Reg0x3a00 = 1;
+		u8Reg0x3a01 = ((gain - 4096) / 16);
+	} else if (gain >= 8192 && gain < 12288) {//128 * 96
+		gain_h = 3;
+		gain_l = 31;
+		u8Reg0x3a00 = 2;
+		u8Reg0x3a01 = ((gain - 8192) / 16);
+	} else if (gain >= 12288 && gain < 16384) {//128 * 128
+		gain_h = 3;
+		gain_l = 31;
+		u8Reg0x3a00 = 3;
+		u8Reg0x3a01 = ((gain - 12288) / 16);
+	} else if (gain >= 16384 && gain < 20480) {//128 * 160
+		gain_h = 3;
+		gain_l = 31;
+		u8Reg0x3a00 = 4;
+		u8Reg0x3a01 = ((gain - 16384) / 16);
+	} else if (gain >= 20480 && gain < 24576) {//128 * 192
+		gain_h = 3;
+		gain_l = 31;
+		u8Reg0x3a00 = 5;
+		u8Reg0x3a01 = ((gain - 20480) / 16);
+	} else if (gain >= 24576 && gain < 28672) {//128 * 224
+		gain_h = 3;
+		gain_l = 31;
+		u8Reg0x3a00 = 6;
+		u8Reg0x3a01 = ((gain - 24576) / 16);
+	} else if (gain >= 28672 && gain < 32768) {//128 * 256
+		gain_h = 3;
+		gain_l = 31;
+		u8Reg0x3a00 = 7;
+		u8Reg0x3a01 = ((gain - 28672) / 16);
+	} else {
+		gain_h = 3;
+		gain_l = 31;
+		u8Reg0x3a00 = 7;
+		u8Reg0x3a01 = 255;
+	}
+
+	u8Reg0x3102 = ((gain_h << 5) | gain_l);
+
+	// 竖条纹优化,但低增益下需添加防止太阳黑子逻辑
+	if (gain >= 128 && gain <= 256) {
+		u8Reg0x4003 = 0xb;
+		u8Reg0x401d = 0xa0;
+	} else {
+		u8Reg0x4003 = 0xa;
+		u8Reg0x401d = 0xa7;
+	}
+
+	ret = mis4001_write_reg(mis4001->client,
+				0x401d,
+				MIS4001_REG_VALUE_08BIT,
+				u8Reg0x401d);
+
+	ret |= mis4001_write_reg(mis4001->client,
+				 0x4003,
+				 MIS4001_REG_VALUE_08BIT,
+				 u8Reg0x4003);
+	ret |= mis4001_write_reg(mis4001->client,
+				 MIS4001_REG_DIG_GAIN,
+				 MIS4001_REG_VALUE_08BIT,
+				 u8Reg0x3a00);
+	ret |= mis4001_write_reg(mis4001->client,
+				 MIS4001_REG_DIG_FINE_GAIN,
+				 MIS4001_REG_VALUE_08BIT,
+				 u8Reg0x3a01);
+	ret |= mis4001_write_reg(mis4001->client,
+				 MIS4001_REG_ANA_GAIN,
+				 MIS4001_REG_VALUE_08BIT,
+				 u8Reg0x3102);
+
+	return ret;
+}
+
+
+static int mis4001_get_reso_dist(const struct mis4001_mode *mode,
+				 struct v4l2_mbus_framefmt *framefmt)
+{
+	return abs(mode->width - framefmt->width) +
+	       abs(mode->height - framefmt->height);
+}
+
+static const struct mis4001_mode *
+mis4001_find_best_fit(struct v4l2_subdev_format *fmt)
+{
+	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
+	int dist;
+	int cur_best_fit = 0;
+	int cur_best_fit_dist = -1;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+		dist = mis4001_get_reso_dist(&supported_modes[i], framefmt);
+		if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
+			cur_best_fit_dist = dist;
+			cur_best_fit = i;
+		}
+	}
+
+	return &supported_modes[cur_best_fit];
+}
+
+static int mis4001_set_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct mis4001 *mis4001 = to_mis4001(sd);
+	const struct mis4001_mode *mode;
+	s64 h_blank, vblank_def;
+
+	mutex_lock(&mis4001->mutex);
+
+	mode = mis4001_find_best_fit(fmt);
+	fmt->format.code = mode->bus_fmt;
+	fmt->format.width = mode->width;
+	fmt->format.height = mode->height;
+	fmt->format.field = V4L2_FIELD_NONE;
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+#else
+		mutex_unlock(&mis4001->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		mis4001->cur_mode = mode;
+		h_blank = mode->hts_def - mode->width;
+		__v4l2_ctrl_modify_range(mis4001->hblank, h_blank,
+					 h_blank, 1, h_blank);
+		vblank_def = mode->vts_def - mode->height;
+		__v4l2_ctrl_modify_range(mis4001->vblank, vblank_def,
+					 MIS4001_VTS_MAX - mode->height,
+					 1, vblank_def);
+		mis4001->cur_fps = mode->max_fps;
+	}
+
+	mutex_unlock(&mis4001->mutex);
+
+	return 0;
+}
+
+static int mis4001_get_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct mis4001 *mis4001 = to_mis4001(sd);
+	const struct mis4001_mode *mode = mis4001->cur_mode;
+
+	mutex_lock(&mis4001->mutex);
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+#else
+		mutex_unlock(&mis4001->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		fmt->format.width = mode->width;
+		fmt->format.height = mode->height;
+		fmt->format.code = mode->bus_fmt;
+		fmt->format.field = V4L2_FIELD_NONE;
+		/* format info: width/height/data type/virctual channel */
+		if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
+			fmt->reserved[0] = mode->vc[fmt->pad];
+		else
+			fmt->reserved[0] = mode->vc[PAD0];
+	}
+	mutex_unlock(&mis4001->mutex);
+
+	return 0;
+}
+
+static int mis4001_enum_mbus_code(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_pad_config *cfg,
+				  struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct mis4001 *mis4001 = to_mis4001(sd);
+
+	if (code->index != 0)
+		return -EINVAL;
+	code->code = mis4001->cur_mode->bus_fmt;
+
+	return 0;
+}
+
+static int mis4001_enum_frame_sizes(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_pad_config *cfg,
+				    struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	if (fse->code != supported_modes[0].bus_fmt)
+		return -EINVAL;
+
+	fse->min_width  = supported_modes[fse->index].width;
+	fse->max_width  = supported_modes[fse->index].width;
+	fse->max_height = supported_modes[fse->index].height;
+	fse->min_height = supported_modes[fse->index].height;
+
+	return 0;
+}
+
+static int mis4001_enable_test_pattern(struct mis4001 *mis4001, u32 pattern)
+{
+	u32 val = 0;
+	int ret = 0;
+
+	ret = mis4001_read_reg(mis4001->client, MIS4001_REG_TEST_PATTERN,
+			       MIS4001_REG_VALUE_08BIT, &val);
+	if (pattern)
+		val |= MIS4001_TEST_PATTERN_BIT_MASK;
+	else
+		val &= ~MIS4001_TEST_PATTERN_BIT_MASK;
+
+	ret |= mis4001_write_reg(mis4001->client, MIS4001_REG_TEST_PATTERN,
+				 MIS4001_REG_VALUE_08BIT, val);
+	return ret;
+}
+
+static int mis4001_g_frame_interval(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_frame_interval *fi)
+{
+	struct mis4001 *mis4001 = to_mis4001(sd);
+	const struct mis4001_mode *mode = mis4001->cur_mode;
+
+	if (mis4001->streaming)
+		fi->interval = mis4001->cur_fps;
+	else
+		fi->interval = mode->max_fps;
+
+	return 0;
+}
+
+static int mis4001_g_mbus_config(struct v4l2_subdev *sd,
+				unsigned int pad_id,
+				struct v4l2_mbus_config *config)
+{
+	struct mis4001 *mis4001 = to_mis4001(sd);
+	const struct mis4001_mode *mode = mis4001->cur_mode;
+	u32 val = 1 << (MIS4001_LANES - 1) |
+		V4L2_MBUS_CSI2_CHANNEL_0 |
+		V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+
+	if (mode->hdr_mode != NO_HDR)
+		val |= V4L2_MBUS_CSI2_CHANNEL_1;
+	if (mode->hdr_mode == HDR_X3)
+		val |= V4L2_MBUS_CSI2_CHANNEL_2;
+
+	config->type = V4L2_MBUS_CSI2_DPHY;
+	config->flags = val;
+
+	return 0;
+}
+
+static void mis4001_get_module_inf(struct mis4001 *mis4001,
+				   struct rkmodule_inf *inf)
+{
+	memset(inf, 0, sizeof(*inf));
+	strscpy(inf->base.sensor, MIS4001_NAME, sizeof(inf->base.sensor));
+	strscpy(inf->base.module, mis4001->module_name,
+		sizeof(inf->base.module));
+	strscpy(inf->base.lens, mis4001->len_name, sizeof(inf->base.lens));
+}
+
+static long mis4001_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	struct mis4001 *mis4001 = to_mis4001(sd);
+	struct rkmodule_hdr_cfg *hdr;
+	u32 i, h, w;
+	long ret = 0;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		mis4001_get_module_inf(mis4001, (struct rkmodule_inf *)arg);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr = (struct rkmodule_hdr_cfg *)arg;
+		hdr->esp.mode = HDR_NORMAL_VC;
+		hdr->hdr_mode = mis4001->cur_mode->hdr_mode;
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		hdr = (struct rkmodule_hdr_cfg *)arg;
+		w = mis4001->cur_mode->width;
+		h = mis4001->cur_mode->height;
+		for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+			if (w == supported_modes[i].width &&
+			    h == supported_modes[i].height &&
+			    supported_modes[i].hdr_mode == hdr->hdr_mode) {
+				mis4001->cur_mode = &supported_modes[i];
+				break;
+			}
+		}
+		if (i == ARRAY_SIZE(supported_modes)) {
+			dev_err(&mis4001->client->dev,
+				"not find hdr mode:%d %dx%d config\n",
+				hdr->hdr_mode, w, h);
+			ret = -EINVAL;
+		} else {
+			w = mis4001->cur_mode->hts_def - mis4001->cur_mode->width;
+			h = mis4001->cur_mode->vts_def - mis4001->cur_mode->height;
+			__v4l2_ctrl_modify_range(mis4001->hblank, w, w, 1, w);
+			__v4l2_ctrl_modify_range(mis4001->vblank, h,
+						 MIS4001_VTS_MAX - mis4001->cur_mode->height, 1, h);
+		}
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+
+		stream = *((u32 *)arg);
+
+		if (stream)
+			ret = mis4001_write_reg(mis4001->client, MIS4001_REG_CTRL_MODE,
+				 MIS4001_REG_VALUE_08BIT, MIS4001_MODE_STREAMING);
+		else
+			ret = mis4001_write_reg(mis4001->client, MIS4001_REG_CTRL_MODE,
+				 MIS4001_REG_VALUE_08BIT, MIS4001_MODE_SW_STANDBY);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long mis4001_compat_ioctl32(struct v4l2_subdev *sd,
+				   unsigned int cmd, unsigned long arg)
+{
+	void __user *up = compat_ptr(arg);
+	struct rkmodule_inf *inf;
+	struct rkmodule_hdr_cfg *hdr;
+	struct preisp_hdrae_exp_s *hdrae;
+	long ret;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
+		if (!inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = mis4001_ioctl(sd, cmd, inf);
+		if (!ret) {
+			if (copy_to_user(up, inf, sizeof(*inf)))
+				ret = -EFAULT;
+		}
+		kfree(inf);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = mis4001_ioctl(sd, cmd, hdr);
+		if (!ret) {
+			if (copy_to_user(up, hdr, sizeof(*hdr)))
+				ret = -EFAULT;
+		}
+		kfree(hdr);
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(hdr, up, sizeof(*hdr));
+		if (!ret)
+			ret = mis4001_ioctl(sd, cmd, hdr);
+		else
+			ret = -EFAULT;
+		kfree(hdr);
+		break;
+	case PREISP_CMD_SET_HDRAE_EXP:
+		hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
+		if (!hdrae) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(hdrae, up, sizeof(*hdrae));
+		if (!ret)
+			ret = mis4001_ioctl(sd, cmd, hdrae);
+		else
+			ret = -EFAULT;
+		kfree(hdrae);
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		ret = copy_from_user(&stream, up, sizeof(u32));
+		if (!ret)
+			ret = mis4001_ioctl(sd, cmd, &stream);
+		else
+			ret = -EFAULT;
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+#endif
+
+static int __mis4001_start_stream(struct mis4001 *mis4001)
+{
+	int ret;
+
+	ret = mis4001_write_array(mis4001->client, mis4001->cur_mode->reg_list);
+	if (ret)
+		return ret;
+
+	/* In case these controls are set before streaming */
+	ret = __v4l2_ctrl_handler_setup(&mis4001->ctrl_handler);
+	if (ret)
+		return ret;
+
+	return mis4001_write_reg(mis4001->client, MIS4001_REG_CTRL_MODE,
+				 MIS4001_REG_VALUE_08BIT, MIS4001_MODE_STREAMING);
+}
+
+static int __mis4001_stop_stream(struct mis4001 *mis4001)
+{
+	return mis4001_write_reg(mis4001->client, MIS4001_REG_CTRL_MODE,
+				 MIS4001_REG_VALUE_08BIT, MIS4001_MODE_SW_STANDBY);
+}
+
+static int mis4001_s_stream(struct v4l2_subdev *sd, int on)
+{
+	struct mis4001 *mis4001 = to_mis4001(sd);
+	struct i2c_client *client = mis4001->client;
+	int ret = 0;
+
+	mutex_lock(&mis4001->mutex);
+	on = !!on;
+	if (on == mis4001->streaming)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		ret = __mis4001_start_stream(mis4001);
+		if (ret) {
+			v4l2_err(sd, "start stream failed while write regs\n");
+			pm_runtime_put(&client->dev);
+			goto unlock_and_return;
+		}
+	} else {
+		__mis4001_stop_stream(mis4001);
+		pm_runtime_put(&client->dev);
+	}
+
+	mis4001->streaming = on;
+
+unlock_and_return:
+	mutex_unlock(&mis4001->mutex);
+
+	return ret;
+}
+
+static int mis4001_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct mis4001 *mis4001 = to_mis4001(sd);
+	struct i2c_client *client = mis4001->client;
+	int ret = 0;
+
+	mutex_lock(&mis4001->mutex);
+
+	/* If the power state is not modified - no work to do. */
+	if (mis4001->power_on == !!on)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		ret = mis4001_write_array(mis4001->client, mis4001_global_regs);
+		if (ret) {
+			v4l2_err(sd, "could not set init registers\n");
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		mis4001->power_on = true;
+	} else {
+		pm_runtime_put(&client->dev);
+		mis4001->power_on = false;
+	}
+
+unlock_and_return:
+	mutex_unlock(&mis4001->mutex);
+
+	return ret;
+}
+
+/* Calculate the delay in us by clock rate and clock cycles */
+static inline u32 mis4001_cal_delay(u32 cycles)
+{
+	return DIV_ROUND_UP(cycles, MIS4001_XVCLK_FREQ / 1000 / 1000);
+}
+
+static int __mis4001_power_on(struct mis4001 *mis4001)
+{
+	int ret;
+	u32 delay_us;
+	struct device *dev = &mis4001->client->dev;
+
+	if (!IS_ERR_OR_NULL(mis4001->pins_default)) {
+		ret = pinctrl_select_state(mis4001->pinctrl,
+					   mis4001->pins_default);
+		if (ret < 0)
+			dev_err(dev, "could not set pins\n");
+	}
+	ret = clk_set_rate(mis4001->xvclk, MIS4001_XVCLK_FREQ);
+	if (ret < 0)
+		dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
+	if (clk_get_rate(mis4001->xvclk) != MIS4001_XVCLK_FREQ)
+		dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
+	ret = clk_prepare_enable(mis4001->xvclk);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable xvclk\n");
+		return ret;
+	}
+	if (!IS_ERR(mis4001->reset_gpio))
+		gpiod_set_value_cansleep(mis4001->reset_gpio, 0);
+
+	ret = regulator_bulk_enable(MIS4001_NUM_SUPPLIES, mis4001->supplies);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable regulators\n");
+		goto disable_clk;
+	}
+
+	if (!IS_ERR(mis4001->reset_gpio))
+		gpiod_set_value_cansleep(mis4001->reset_gpio, 1);
+
+	usleep_range(500, 1000);
+	if (!IS_ERR(mis4001->pwdn_gpio))
+		gpiod_set_value_cansleep(mis4001->pwdn_gpio, 1);
+
+	if (!IS_ERR(mis4001->reset_gpio))
+		usleep_range(6000, 8000);
+	else
+		usleep_range(12000, 16000);
+
+	/* 8192 cycles prior to first SCCB transaction */
+	delay_us = mis4001_cal_delay(8192);
+	usleep_range(delay_us, delay_us * 2);
+
+	return 0;
+
+disable_clk:
+	clk_disable_unprepare(mis4001->xvclk);
+
+	return ret;
+}
+
+static void __mis4001_power_off(struct mis4001 *mis4001)
+{
+	int ret;
+	struct device *dev = &mis4001->client->dev;
+
+	if (!IS_ERR(mis4001->pwdn_gpio))
+		gpiod_set_value_cansleep(mis4001->pwdn_gpio, 0);
+	clk_disable_unprepare(mis4001->xvclk);
+	if (!IS_ERR(mis4001->reset_gpio))
+		gpiod_set_value_cansleep(mis4001->reset_gpio, 0);
+	if (!IS_ERR_OR_NULL(mis4001->pins_sleep)) {
+		ret = pinctrl_select_state(mis4001->pinctrl,
+					   mis4001->pins_sleep);
+		if (ret < 0)
+			dev_dbg(dev, "could not set pins\n");
+	}
+	regulator_bulk_disable(MIS4001_NUM_SUPPLIES, mis4001->supplies);
+}
+
+static int mis4001_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct mis4001 *mis4001 = to_mis4001(sd);
+
+	return __mis4001_power_on(mis4001);
+}
+
+static int mis4001_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct mis4001 *mis4001 = to_mis4001(sd);
+
+	__mis4001_power_off(mis4001);
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int mis4001_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct mis4001 *mis4001 = to_mis4001(sd);
+	struct v4l2_mbus_framefmt *try_fmt =
+				v4l2_subdev_get_try_format(sd, fh->pad, 0);
+	const struct mis4001_mode *def_mode = &supported_modes[0];
+
+	mutex_lock(&mis4001->mutex);
+	/* Initialize try_fmt */
+	try_fmt->width = def_mode->width;
+	try_fmt->height = def_mode->height;
+	try_fmt->code = def_mode->bus_fmt;
+	try_fmt->field = V4L2_FIELD_NONE;
+
+	mutex_unlock(&mis4001->mutex);
+	/* No crop or compose */
+
+	return 0;
+}
+#endif
+
+static int mis4001_enum_frame_interval(struct v4l2_subdev *sd,
+				       struct v4l2_subdev_pad_config *cfg,
+				       struct v4l2_subdev_frame_interval_enum *fie)
+{
+	if (fie->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	fie->code = supported_modes[fie->index].bus_fmt;
+	fie->width = supported_modes[fie->index].width;
+	fie->height = supported_modes[fie->index].height;
+	fie->interval = supported_modes[fie->index].max_fps;
+	fie->reserved[0] = supported_modes[fie->index].hdr_mode;
+	return 0;
+}
+
+static const struct dev_pm_ops mis4001_pm_ops = {
+	SET_RUNTIME_PM_OPS(mis4001_runtime_suspend,
+			   mis4001_runtime_resume, NULL)
+};
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static const struct v4l2_subdev_internal_ops mis4001_internal_ops = {
+	.open = mis4001_open,
+};
+#endif
+
+static const struct v4l2_subdev_core_ops mis4001_core_ops = {
+	.s_power = mis4001_s_power,
+	.ioctl = mis4001_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl32 = mis4001_compat_ioctl32,
+#endif
+};
+
+static const struct v4l2_subdev_video_ops mis4001_video_ops = {
+	.s_stream = mis4001_s_stream,
+	.g_frame_interval = mis4001_g_frame_interval,
+};
+
+static const struct v4l2_subdev_pad_ops mis4001_pad_ops = {
+	.enum_mbus_code = mis4001_enum_mbus_code,
+	.enum_frame_size = mis4001_enum_frame_sizes,
+	.enum_frame_interval = mis4001_enum_frame_interval,
+	.get_fmt = mis4001_get_fmt,
+	.set_fmt = mis4001_set_fmt,
+	.get_mbus_config = mis4001_g_mbus_config,
+};
+
+static const struct v4l2_subdev_ops mis4001_subdev_ops = {
+	.core	= &mis4001_core_ops,
+	.video	= &mis4001_video_ops,
+	.pad	= &mis4001_pad_ops,
+};
+
+static void mis4001_modify_fps_info(struct mis4001 *mis4001)
+{
+	const struct mis4001_mode *mode = mis4001->cur_mode;
+
+	mis4001->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
+				      mis4001->cur_vts;
+}
+
+static int mis4001_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct mis4001 *mis4001 = container_of(ctrl->handler,
+					       struct mis4001, ctrl_handler);
+	struct i2c_client *client = mis4001->client;
+	s64 max;
+	int ret = 0;
+	u32 val = 0;
+	u32 u32Reg0x4007, expmin, expmax;
+	u64 sleep_time = 0;
+
+	/* Propagate change of current control to all related controls */
+	switch (ctrl->id) {
+	case V4L2_CID_VBLANK:
+		/* Update max exposure while meeting expected vblanking */
+		max = mis4001->cur_mode->height + ctrl->val - 4;
+		__v4l2_ctrl_modify_range(mis4001->exposure,
+					 mis4001->exposure->minimum, max,
+					 mis4001->exposure->step,
+					 mis4001->exposure->default_value);
+		break;
+	}
+
+	if (!pm_runtime_get_if_in_use(&client->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		dev_dbg(&client->dev, "set exposure 0x%x\n", ctrl->val);
+		if (mis4001->cur_mode->hdr_mode == NO_HDR) {
+			val = ctrl->val;
+			/* 4 least significant bits of expsoure are fractional part */
+			ret = mis4001_write_reg(mis4001->client,
+						MIS4001_REG_EXPOSURE_H,
+						MIS4001_REG_VALUE_08BIT,
+						MIS4001_FETCH_EXP_H(val));
+			ret |= mis4001_write_reg(mis4001->client,
+						MIS4001_REG_EXPOSURE_L,
+						MIS4001_REG_VALUE_08BIT,
+						MIS4001_FETCH_EXP_L(val));
+
+			/* Special strategy: To solve the problem of exposure layering:
+			 * When the exposure is not fully filled, the gain will be increased,
+			 * resulting in layering phenomenon
+			 */
+
+			//When the exposure time is 1/200 (0.005) s, the exp register is 196
+			expmin = (mis4001->cur_mode->max_fps.denominator / mis4001->cur_mode->max_fps.numerator)
+				 * mis4001->cur_mode->vts_def * 1 / 200;
+			expmax = mis4001->cur_mode->vts_def - expmin;
+			if (((expmin <= val) && (expmax >= val)))
+				u32Reg0x4007 = 0x78;
+			else
+				u32Reg0x4007 = 0xc4;
+
+			ret |= mis4001_write_reg(mis4001->client,
+						 0x4007,
+						 MIS4001_REG_VALUE_08BIT,
+						 u32Reg0x4007);
+		}
+		break;
+	case V4L2_CID_ANALOGUE_GAIN:
+		dev_dbg(&client->dev, "set gain 0x%x\n", ctrl->val);
+		if (mis4001->cur_mode->hdr_mode == NO_HDR)
+			ret = mis4001_set_gain_reg(mis4001, ctrl->val);
+		break;
+	case V4L2_CID_VBLANK:
+		dev_dbg(&client->dev, "set vblank 0x%x\n", ctrl->val);
+		mis4001->cur_vts = ctrl->val + mis4001->cur_mode->height;
+		ret = mis4001_write_reg(mis4001->client,
+					MIS4001_REG_CTRL_MODE,
+					MIS4001_REG_VALUE_08BIT,
+					0x02);
+		sleep_time = mis4001->cur_mode->max_fps.denominator / mis4001->cur_mode->max_fps.numerator *
+			     mis4001->cur_mode->vts_def / mis4001->cur_vts;
+		sleep_time = div_u64(1000000, sleep_time);
+		usleep_range(sleep_time, sleep_time + 1000);
+		ret |= mis4001_write_reg(mis4001->client,
+					 MIS4001_REG_VTS_H,
+					 MIS4001_REG_VALUE_08BIT,
+					 (ctrl->val + mis4001->cur_mode->height)
+					 >> 8);
+		ret |= mis4001_write_reg(mis4001->client,
+					 MIS4001_REG_VTS_L,
+					 MIS4001_REG_VALUE_08BIT,
+					 (ctrl->val + mis4001->cur_mode->height)
+					 & 0xff);
+		ret |= mis4001_write_reg(mis4001->client,
+					 MIS4001_REG_CTRL_MODE,
+					 MIS4001_REG_VALUE_08BIT,
+					 0x00);
+		if (mis4001->cur_vts != mis4001->cur_mode->vts_def)
+			mis4001_modify_fps_info(mis4001);
+		break;
+	case V4L2_CID_TEST_PATTERN:
+		ret = mis4001_enable_test_pattern(mis4001, ctrl->val);
+		break;
+	case V4L2_CID_HFLIP:
+		ret = mis4001_read_reg(mis4001->client, MIS4001_FLIP_MIRROR_REG,
+				       MIS4001_REG_VALUE_08BIT, &val);
+		if (ctrl->val)
+			val |= MIRROR_BIT_MASK;
+		else
+			val &= ~MIRROR_BIT_MASK;
+		mis4001_set_orientation_reg(mis4001, val);
+		break;
+	case V4L2_CID_VFLIP:
+		ret = mis4001_read_reg(mis4001->client, MIS4001_FLIP_MIRROR_REG,
+				       MIS4001_REG_VALUE_08BIT, &val);
+		if (ctrl->val)
+			val |= FLIP_BIT_MASK;
+		else
+			val &= ~FLIP_BIT_MASK;
+		mis4001_set_orientation_reg(mis4001, val);
+		break;
+	default:
+		dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
+			 __func__, ctrl->id, ctrl->val);
+		break;
+	}
+
+	pm_runtime_put(&client->dev);
+
+	return ret;
+
+}
+
+static const struct v4l2_ctrl_ops mis4001_ctrl_ops = {
+	.s_ctrl = mis4001_set_ctrl,
+};
+
+static int mis4001_initialize_controls(struct mis4001 *mis4001)
+{
+	const struct mis4001_mode *mode;
+	struct v4l2_ctrl_handler *handler;
+	struct v4l2_ctrl *ctrl;
+	s64 exposure_max, vblank_def;
+	u32 h_blank;
+	int ret;
+
+	handler = &mis4001->ctrl_handler;
+	mode = mis4001->cur_mode;
+	ret = v4l2_ctrl_handler_init(handler, 9);
+	if (ret)
+		return ret;
+	handler->lock = &mis4001->mutex;
+
+	ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
+				      0, 0, link_freq_menu_items);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
+			  0, PIXEL_RATE_WITH_337M_10BIT, 1, PIXEL_RATE_WITH_337M_10BIT);
+
+	h_blank = mode->hts_def - mode->width;
+	mis4001->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
+					    h_blank, h_blank, 1, h_blank);
+	if (mis4001->hblank)
+		mis4001->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+	vblank_def = mode->vts_def - mode->height;
+	mis4001->vblank = v4l2_ctrl_new_std(handler, &mis4001_ctrl_ops,
+					    V4L2_CID_VBLANK, vblank_def,
+					    MIS4001_VTS_MAX - mode->height,
+					    1, vblank_def);
+	mis4001->cur_fps = mode->max_fps;
+	exposure_max = mode->vts_def - 4;
+	mis4001->exposure = v4l2_ctrl_new_std(handler, &mis4001_ctrl_ops,
+					      V4L2_CID_EXPOSURE, MIS4001_EXPOSURE_MIN,
+					      exposure_max, MIS4001_EXPOSURE_STEP,
+					      mode->exp_def);
+	mis4001->anal_gain = v4l2_ctrl_new_std(handler, &mis4001_ctrl_ops,
+					       V4L2_CID_ANALOGUE_GAIN, MIS4001_GAIN_MIN,
+					       MIS4001_GAIN_MAX, MIS4001_GAIN_STEP,
+					       MIS4001_GAIN_DEFAULT);
+	mis4001->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
+							    &mis4001_ctrl_ops,
+					V4L2_CID_TEST_PATTERN,
+					ARRAY_SIZE(mis4001_test_pattern_menu) - 1,
+					0, 0, mis4001_test_pattern_menu);
+	v4l2_ctrl_new_std(handler, &mis4001_ctrl_ops,
+				V4L2_CID_HFLIP, 0, 1, 1, 0);
+	v4l2_ctrl_new_std(handler, &mis4001_ctrl_ops,
+				V4L2_CID_VFLIP, 0, 1, 1, 0);
+	if (handler->error) {
+		ret = handler->error;
+		dev_err(&mis4001->client->dev,
+			"Failed to init controls(%d)\n", ret);
+		goto err_free_handler;
+	}
+
+	mis4001->subdev.ctrl_handler = handler;
+
+	return 0;
+
+err_free_handler:
+	v4l2_ctrl_handler_free(handler);
+
+	return ret;
+}
+
+/* sensor id check */
+static int mis4001_check_sensor_id(struct mis4001 *mis4001,
+				   struct i2c_client *client)
+{
+	struct device *dev = &mis4001->client->dev;
+	u32 id = 0;
+	int ret;
+
+	ret = mis4001_read_reg(client, MIS4001_REG_CHIP_ID,
+					MIS4001_REG_VALUE_16BIT, &id);
+
+	if (id != MIS4001_CHIP_ID) {
+		dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
+		return -ENODEV;
+	}
+
+	dev_info(dev, "Detected 0x%04x sensor\n", MIS4001_CHIP_ID);
+
+	return 0;
+}
+
+static int mis4001_configure_regulators(struct mis4001 *mis4001)
+{
+	unsigned int i;
+
+	for (i = 0; i < MIS4001_NUM_SUPPLIES; i++)
+		mis4001->supplies[i].supply = mis4001_supply_names[i];
+
+	return devm_regulator_bulk_get(&mis4001->client->dev,
+				       MIS4001_NUM_SUPPLIES,
+				       mis4001->supplies);
+}
+
+static int mis4001_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct device_node *node = dev->of_node;
+	struct mis4001 *mis4001;
+	struct v4l2_subdev *sd;
+	char facing[2];
+	int ret;
+
+	dev_info(dev, "driver version: %02x.%02x.%02x",
+		 DRIVER_VERSION >> 16,
+		 (DRIVER_VERSION & 0xff00) >> 8,
+		 DRIVER_VERSION & 0x00ff);
+
+	mis4001 = devm_kzalloc(dev, sizeof(*mis4001), GFP_KERNEL);
+	if (!mis4001)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
+				   &mis4001->module_index);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
+				       &mis4001->module_facing);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
+				       &mis4001->module_name);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
+				       &mis4001->len_name);
+	if (ret) {
+		dev_err(dev, "could not get module information!\n");
+		return -EINVAL;
+	}
+
+	mis4001->client = client;
+	mis4001->cur_mode = &supported_modes[0];
+
+	mis4001->xvclk = devm_clk_get(dev, "xvclk");
+	if (IS_ERR(mis4001->xvclk)) {
+		dev_err(dev, "Failed to get xvclk\n");
+		return -EINVAL;
+	}
+
+	mis4001->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(mis4001->reset_gpio))
+		dev_warn(dev, "Failed to get reset-gpios\n");
+
+	mis4001->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
+	if (IS_ERR(mis4001->pwdn_gpio))
+		dev_warn(dev, "Failed to get pwdn-gpios\n");
+
+	mis4001->pinctrl = devm_pinctrl_get(dev);
+	if (!IS_ERR(mis4001->pinctrl)) {
+		mis4001->pins_default =
+			pinctrl_lookup_state(mis4001->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_DEFAULT);
+		if (IS_ERR(mis4001->pins_default))
+			dev_err(dev, "could not get default pinstate\n");
+
+		mis4001->pins_sleep =
+			pinctrl_lookup_state(mis4001->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_SLEEP);
+		if (IS_ERR(mis4001->pins_sleep))
+			dev_err(dev, "could not get sleep pinstate\n");
+	} else {
+		dev_err(dev, "no pinctrl\n");
+	}
+
+	ret = mis4001_configure_regulators(mis4001);
+	if (ret) {
+		dev_err(dev, "Failed to get power regulators\n");
+		return ret;
+	}
+
+	mutex_init(&mis4001->mutex);
+
+	sd = &mis4001->subdev;
+	v4l2_i2c_subdev_init(sd, client, &mis4001_subdev_ops);
+	ret = mis4001_initialize_controls(mis4001);
+	if (ret)
+		goto err_destroy_mutex;
+
+	ret = __mis4001_power_on(mis4001);
+	if (ret)
+		goto err_free_handler;
+
+	ret = mis4001_check_sensor_id(mis4001, client);
+	if (ret)
+		goto err_power_off;
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	sd->internal_ops = &mis4001_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+		     V4L2_SUBDEV_FL_HAS_EVENTS;
+#endif
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	mis4001->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &mis4001->pad);
+	if (ret < 0)
+		goto err_power_off;
+#endif
+
+	memset(facing, 0, sizeof(facing));
+	if (strcmp(mis4001->module_facing, "back") == 0)
+		facing[0] = 'b';
+	else
+		facing[0] = 'f';
+
+	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
+		 mis4001->module_index, facing,
+		 MIS4001_NAME, dev_name(sd->dev));
+	ret = v4l2_async_register_subdev_sensor_common(sd);
+	if (ret) {
+		dev_err(dev, "v4l2 async register subdev failed\n");
+		goto err_clean_entity;
+	}
+
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_idle(dev);
+
+	return 0;
+
+err_clean_entity:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+err_power_off:
+	__mis4001_power_off(mis4001);
+err_free_handler:
+	v4l2_ctrl_handler_free(&mis4001->ctrl_handler);
+err_destroy_mutex:
+	mutex_destroy(&mis4001->mutex);
+
+	return ret;
+}
+
+static int mis4001_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct mis4001 *mis4001 = to_mis4001(sd);
+
+	v4l2_async_unregister_subdev(sd);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+	v4l2_ctrl_handler_free(&mis4001->ctrl_handler);
+	mutex_destroy(&mis4001->mutex);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		__mis4001_power_off(mis4001);
+	pm_runtime_set_suspended(&client->dev);
+
+	return 0;
+}
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id mis4001_of_match[] = {
+	{ .compatible = "imagedesign,mis4001" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mis4001_of_match);
+#endif
+
+static const struct i2c_device_id mis4001_match_id[] = {
+	{ "imagedesign,mis4001", 0 },
+	{ },
+};
+
+static struct i2c_driver mis4001_i2c_driver = {
+	.driver = {
+		.name = MIS4001_NAME,
+		.pm = &mis4001_pm_ops,
+		.of_match_table = of_match_ptr(mis4001_of_match),
+	},
+	.probe = &mis4001_probe,
+	.remove = &mis4001_remove,
+	.id_table = mis4001_match_id,
+};
+
+static int __init sensor_mod_init(void)
+{
+	return i2c_add_driver(&mis4001_i2c_driver);
+}
+
+static void __exit sensor_mod_exit(void)
+{
+	i2c_del_driver(&mis4001_i2c_driver);
+}
+
+device_initcall_sync(sensor_mod_init);
+module_exit(sensor_mod_exit);
+
+MODULE_DESCRIPTION("chengdu image design mis4001 sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/og01a10.c b/kernel/drivers/media/i2c/og01a10.c
new file mode 100644
index 0000000..1f5d73c
--- /dev/null
+++ b/kernel/drivers/media/i2c/og01a10.c
@@ -0,0 +1,1437 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * og01a10 driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ * V0.1.0: MIPI is ok.
+ * V0.0X01.0X02 fix mclk issue when probe multiple camera.
+ * V0.0X01.0X03 add enum_frame_interval function.
+ * V0.0X01.0X04 add quick stream on/off
+ * V0.0X01.0X05 add function g_mbus_config
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/rk-camera-module.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <linux/pinctrl/consumer.h>
+
+#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x05)
+#ifndef V4L2_CID_DIGITAL_GAIN
+#define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
+#endif
+
+#define MIPI_FREQ_600M			600000000
+
+#define OG01A10_PIXEL_RATE		(MIPI_FREQ_600M * 2 / 10 * 2)
+#define OG01A10_XVCLK_FREQ		24000000
+
+#define CHIP_ID				0x4701
+#define OG01A10_REG_CHIP_ID		0x300a
+
+#define OG01A10_REG_CTRL_MODE		0x0100
+#define OG01A10_MODE_SW_STANDBY		0x0
+#define OG01A10_MODE_STREAMING		BIT(0)
+
+#define OG01A10_REG_EXPOSURE		0x3501
+#define	OG01A10_EXPOSURE_MIN		1
+#define	OG01A10_EXPOSURE_STEP		1
+#define OG01A10_VTS_MAX			0xffff
+
+#define OG01A10_REG_AGAIN		0x3508
+#define OG01A10_REG_DGAIN		0x350A
+#define	ANALOG_GAIN_MIN			0x100
+#define	ANALOG_GAIN_MAX			0xE880 //0X100*15.5*15
+#define	ANALOG_GAIN_STEP		1
+#define	ANALOG_GAIN_DEFAULT		0x400
+
+#define OG01A10_REG_TEST_PATTERN	0x5100
+#define	OG01A10_TEST_PATTERN_ENABLE	0x80
+#define	OG01A10_TEST_PATTERN_DISABLE	0x00
+
+#define OG01A10_REG_VTS			0x320e
+
+#define REG_NULL			0xFFFF
+
+#define OG01A10_REG_VALUE_08BIT		1
+#define OG01A10_REG_VALUE_16BIT		2
+#define OG01A10_REG_VALUE_24BIT		3
+
+#define OG01A10_NAME			"og01a10"
+
+#define PIX_FORMAT MEDIA_BUS_FMT_SRGGB10_1X10
+
+#define OF_CAMERA_PINCTRL_STATE_DEFAULT	"rockchip,camera_default"
+#define OF_CAMERA_PINCTRL_STATE_SLEEP	"rockchip,camera_sleep"
+
+#define OG01A10_LANES			2
+#define OG01A10_BITS_PER_SAMPLE		10
+
+static const char * const og01a10_supply_names[] = {
+	"avdd",		/* Analog power */
+	"dovdd",	/* Digital I/O power */
+	"dvdd",		/* Digital core power */
+};
+
+#define OG01A10_NUM_SUPPLIES ARRAY_SIZE(og01a10_supply_names)
+
+struct regval {
+	u16 addr;
+	u8 val;
+};
+
+struct og01a10_mode {
+	u32 width;
+	u32 height;
+	struct v4l2_fract max_fps;
+	u32 hts_def;
+	u32 vts_def;
+	u32 exp_def;
+	const struct regval *reg_list;
+	u32 hdr_mode;
+	u32 vc[PAD_MAX];
+};
+
+struct og01a10 {
+	struct i2c_client	*client;
+	struct clk		*xvclk;
+	struct gpio_desc	*pwdn_gpio;
+	struct gpio_desc	*reset_gpio;
+	struct regulator_bulk_data supplies[OG01A10_NUM_SUPPLIES];
+	struct pinctrl		*pinctrl;
+	struct pinctrl_state	*pins_default;
+	struct pinctrl_state	*pins_sleep;
+	struct v4l2_subdev	subdev;
+	struct media_pad	pad;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl	*exposure;
+	struct v4l2_ctrl	*anal_gain;
+	struct v4l2_ctrl	*digi_gain;
+	struct v4l2_ctrl	*hblank;
+	struct v4l2_ctrl	*vblank;
+	struct v4l2_ctrl	*pixel_rate;
+	struct v4l2_ctrl	*link_freq;
+	struct v4l2_ctrl	*test_pattern;
+	struct mutex		mutex;
+	bool			streaming;
+	bool			power_on;
+	const struct og01a10_mode *cur_mode;
+	u32			module_index;
+	const char		*module_facing;
+	const char		*module_name;
+	const char		*len_name;
+};
+
+#define to_og01a10(sd) container_of(sd, struct og01a10, subdev)
+
+/*
+ * Xclk 24Mhz
+ * Pclk 120Mhz
+ * linelength 1696(0x06a0)
+ * framelength 2832(0x0b10)
+ * grabwindow_width 1280
+ * grabwindow_height 1024
+ * mipi 2 lane
+ * max_framerate 25fps
+ * mipi_datarate per lane 1000Mbps
+ */
+static const struct regval og01a10_global_regs[] = {
+	{0x0103, 0x01},
+	{0x0100, 0x00},
+	{0x0300, 0x0a},
+	{0x0301, 0x29},
+	{0x0302, 0x31},
+	{0x0303, 0x04},
+	{0x0304, 0x00},
+	{0x0305, 0xfa},
+	{0x0306, 0x00},
+	{0x0307, 0x01},
+	{0x0308, 0x02},
+	{0x0309, 0x00},
+	{0x0310, 0x00},
+	{0x0311, 0x00},
+	{0x0312, 0x07},
+	{0x0313, 0x00},
+	{0x0314, 0x00},
+	{0x0315, 0x00},
+	{0x0320, 0x02},
+	{0x0321, 0x01},
+	{0x0322, 0x01},
+	{0x0323, 0x04},
+	{0x0324, 0x01},
+	{0x0325, 0xc2},
+	{0x0326, 0xce},
+	{0x0327, 0x04},
+	{0x0329, 0x02},
+	{0x032a, 0x04},
+	{0x032b, 0x04},
+	{0x032c, 0x02},
+	{0x032d, 0x01},
+	{0x032e, 0x00},
+	{0x300d, 0x02},
+	{0x300e, 0x04},
+	{0x3021, 0x08},
+	{0x301e, 0x03},
+	{0x3103, 0x00},
+	{0x3106, 0x08},
+	{0x3107, 0x40},
+	{0x3216, 0x01},
+	{0x3217, 0x00},
+	{0x3218, 0xc0},
+	{0x3219, 0x55},
+	{0x3500, 0x00},
+	{0x3501, 0x01},
+	{0x3502, 0x8a},
+	{0x3506, 0x01},
+	{0x3507, 0x72},
+	{0x3508, 0x04},
+	{0x3509, 0x00},
+	{0x350a, 0x01},
+	{0x350b, 0x00},
+	{0x350c, 0x00},
+	{0x3541, 0x00},
+	{0x3542, 0x40},
+	{0x3605, 0xe0},
+	{0x3606, 0x41},
+	{0x3614, 0x20},
+	{0x3620, 0x0b},
+	{0x3630, 0x07},
+	{0x3636, 0xa0},
+	{0x3637, 0xf9},
+	{0x3638, 0x09},
+	{0x3639, 0x38},
+	{0x363f, 0x09},
+	{0x3640, 0x17},
+	{0x3662, 0x04},
+	{0x3665, 0x80},
+	{0x3670, 0x68},
+	{0x3674, 0x00},
+	{0x3677, 0x3f},
+	{0x3679, 0x00},
+	{0x369f, 0x19},
+	{0x36a0, 0x03},
+	{0x36a2, 0x19},
+	{0x36a3, 0x03},
+	{0x370d, 0x66},
+	{0x370f, 0x00},
+	{0x3710, 0x03},
+	{0x3715, 0x03},
+	{0x3716, 0x03},
+	{0x3717, 0x06},
+	{0x3733, 0x00},
+	{0x3778, 0x00},
+	{0x37a8, 0x0f},
+	{0x37a9, 0x01},
+	{0x37aa, 0x07},
+	{0x37bd, 0x1c},
+	{0x37c1, 0x2f},
+	{0x37c3, 0x09},
+	{0x37c8, 0x1d},
+	{0x37ca, 0x30},
+	{0x37df, 0x00},
+	{0x3800, 0x00},
+	{0x3801, 0x00},
+	{0x3802, 0x00},
+	{0x3803, 0x00},
+	{0x3804, 0x05},
+	{0x3805, 0x0f},
+	{0x3806, 0x04},
+	{0x3807, 0x0f},
+	{0x3808, 0x05},
+	{0x3809, 0x00},
+	{0x380a, 0x04},
+	{0x380b, 0x00},
+	{0x380c, 0x06},
+	{0x380d, 0xa0},
+	{0x380e, 0x0b},
+	{0x380f, 0x10},
+	{0x3810, 0x00},
+	{0x3811, 0x08},
+	{0x3812, 0x00},
+	{0x3813, 0x08},
+	{0x3814, 0x11},
+	{0x3815, 0x11},
+	{0x3820, 0x44},
+	{0x3821, 0x04},
+	{0x3826, 0x00},
+	{0x3827, 0x00},
+	{0x382a, 0x08},
+	{0x382b, 0x52},
+	{0x382d, 0xba},
+	{0x383d, 0x14},
+	{0x384a, 0xa2},
+	{0x3866, 0x0e},
+	{0x3867, 0x07},
+	{0x3884, 0x00},
+	{0x3885, 0x08},
+	{0x3893, 0x68},
+	{0x3894, 0x2a},
+	{0x3898, 0x00},
+	{0x3899, 0x31},
+	{0x389a, 0x04},
+	{0x389b, 0x00},
+	{0x389c, 0x0b},
+	{0x389d, 0xad},
+	{0x389f, 0x08},
+	{0x38a0, 0x00},
+	{0x38a1, 0x00},
+	{0x38a8, 0x70},
+	{0x38ac, 0xea},
+	{0x38b2, 0x00},
+	{0x38b3, 0x08},
+	{0x38bc, 0x20},
+	{0x38c4, 0x0c},
+	{0x38c5, 0x3a},
+	{0x38c7, 0x3a},
+	{0x38e1, 0xc0},
+	{0x38ec, 0x3c},
+	{0x38f0, 0x09},
+	{0x38f1, 0x6f},
+	{0x38fe, 0x3c},
+	{0x391e, 0x01},
+	{0x391f, 0x00},
+	{0x3920, 0xff},
+	{0x3921, 0x00},
+	{0x3922, 0x00},
+	{0x3923, 0x00},
+	{0x3924, 0x05},
+	{0x3925, 0x00},
+	{0x3926, 0x00},
+	{0x3927, 0x00},
+	{0x3928, 0x1a},
+	{0x3929, 0x01},
+	{0x392a, 0xb4},
+	{0x392b, 0x00},
+	{0x392c, 0x10},
+	{0x392f, 0x40},
+	{0x4000, 0xcf},
+	{0x4003, 0x40},
+	{0x4008, 0x00},
+	{0x4009, 0x07},
+	{0x400a, 0x02},
+	{0x400b, 0x54},
+	{0x400c, 0x00},
+	{0x400d, 0x07},
+	{0x4010, 0xc0},
+	{0x4012, 0x02},
+	{0x4014, 0x04},
+	{0x4015, 0x04},
+	{0x4017, 0x02},
+	{0x4042, 0x01},
+	{0x4306, 0x04},
+	{0x4307, 0x12},
+	{0x4509, 0x00},
+	{0x450b, 0x83},
+	{0x4604, 0x68},
+	{0x4608, 0x0a},
+	{0x4700, 0x06},
+	{0x4800, 0x64},
+	{0x481b, 0x3c},
+	{0x4825, 0x32},
+	{0x4833, 0x18},
+	{0x4837, 0x10},
+	{0x4850, 0x40},
+	{0x4860, 0x00},
+	{0x4861, 0xec},
+	{0x4864, 0x00},
+	{0x4883, 0x00},
+	{0x4888, 0x90},
+	{0x4889, 0x05},
+	{0x488b, 0x04},
+	{0x4f00, 0x04},
+	{0x4f10, 0x04},
+	{0x4f21, 0x01},
+	{0x4f22, 0x40},
+	{0x4f23, 0x44},
+	{0x4f24, 0x51},
+	{0x4f25, 0x41},
+	{0x5000, 0x1f},
+	{0x500a, 0x00},
+	{0x5100, 0x00},
+	{0x5111, 0x20},
+	{0x3020, 0x20},
+	{0x3613, 0x03},
+	{0x38c9, 0x02},
+	{0x5304, 0x01},
+	{0x3620, 0x08},
+	{0x3639, 0x58},
+	{0x363a, 0x10},
+	{0x3674, 0x04},
+	{0x3780, 0xff},
+	{0x3781, 0xff},
+	{0x3782, 0x00},
+	{0x3783, 0x01},
+	{0x3798, 0xa3},
+	{0x37aa, 0x10},
+	{0x38a8, 0xf0},
+	{0x38c4, 0x09},
+	{0x38c5, 0xb0},
+	{0x38df, 0x80},
+	{0x38ff, 0x05},
+	{0x4010, 0xf1},
+	{0x4011, 0x70},
+	{0x3667, 0x80},
+	{0x4d00, 0x4a},
+	{0x4d01, 0x18},
+	{0x4d02, 0xbb},
+	{0x4d03, 0xde},
+	{0x4d04, 0x93},
+	{0x4d05, 0xff},
+	{0x4d09, 0x0a},
+	{0x4f22, 0x00},
+	{0x37aa, 0x16},
+	{0x3606, 0x42},
+	{0x3605, 0x00},
+	{0x36a2, 0x17},
+	{0x300d, 0x0a},
+	{0x4d00, 0x4d},
+	{0x4d01, 0x95},
+	{0x3d8C, 0x70},
+	{0x3d8d, 0xE9},
+	{0x5300, 0x00},
+	{0x5301, 0x10},
+	{0x5302, 0x00},
+	{0x5303, 0xE3},
+	{0x3d88, 0x00},
+	{0x3d89, 0x10},
+	{0x3d8a, 0x00},
+	{0x3d8b, 0xE3},
+	{REG_NULL, 0x00},
+};
+
+static const struct og01a10_mode supported_modes[] = {
+	{
+		.width = 1280,
+		.height = 1024,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 250000,
+		},
+		.exp_def = 0x0b00,
+		.hts_def = 0x06a0,
+		.vts_def = 0x0b10,
+		.reg_list = og01a10_global_regs,
+		.hdr_mode = NO_HDR,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	},
+};
+
+static const char * const og01a10_test_pattern_menu[] = {
+	"Disabled",
+	"Vertical Color Bar Type 1",
+	"Vertical Color Bar Type 2",
+	"Vertical Color Bar Type 3",
+	"Vertical Color Bar Type 4"
+};
+
+#define OG01A10_LINK_FREQ_240MHZ	(240 * 1000 * 1000)
+
+static const s64 link_freq_menu_items[] = {
+	OG01A10_LINK_FREQ_240MHZ
+};
+
+/* Write registers up to 4 at a time */
+static int og01a10_write_reg(struct i2c_client *client,
+	u16 reg, u32 len, u32 val)
+{
+	u32 buf_i, val_i;
+	u8 buf[6];
+	u8 *val_p;
+	__be32 val_be;
+	u32 ret;
+
+	if (len > 4)
+		return -EINVAL;
+
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xff;
+
+	val_be = cpu_to_be32(val);
+	val_p = (u8 *)&val_be;
+	buf_i = 2;
+	val_i = 4 - len;
+
+	while (val_i < 4)
+		buf[buf_i++] = val_p[val_i++];
+
+	ret = i2c_master_send(client, buf, len + 2);
+	if (ret != len + 2)
+		return -EIO;
+
+	return 0;
+}
+
+static int og01a10_write_array(struct i2c_client *client,
+	const struct regval *regs)
+{
+	u32 i;
+	int ret = 0;
+
+	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) {
+		ret = og01a10_write_reg(client, regs[i].addr,
+					OG01A10_REG_VALUE_08BIT, regs[i].val);
+	}
+
+	return ret;
+}
+
+/* Read registers up to 4 at a time */
+static int og01a10_read_reg(struct i2c_client *client,
+	u16 reg, unsigned int len, u32 *val)
+{
+	struct i2c_msg msgs[2];
+	u8 *data_be_p;
+	__be32 data_be = 0;
+	__be16 reg_addr_be = cpu_to_be16(reg);
+	int ret;
+
+	if (len > 4 || !len)
+		return -EINVAL;
+
+	data_be_p = (u8 *)&data_be;
+	/* Write register address */
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = 2;
+	msgs[0].buf = (u8 *)&reg_addr_be;
+
+	/* Read data from register */
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = len;
+	msgs[1].buf = &data_be_p[4 - len];
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs))
+		return -EIO;
+
+	*val = be32_to_cpu(data_be);
+
+	return 0;
+}
+
+static int og01a10_get_reso_dist(const struct og01a10_mode *mode,
+	struct v4l2_mbus_framefmt *framefmt)
+{
+	return abs(mode->width - framefmt->width) +
+	       abs(mode->height - framefmt->height);
+}
+
+static const struct og01a10_mode *
+	og01a10_find_best_fit(struct v4l2_subdev_format *fmt)
+{
+	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
+	int dist;
+	int cur_best_fit = 0;
+	int cur_best_fit_dist = -1;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+		dist = og01a10_get_reso_dist(&supported_modes[i], framefmt);
+		if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
+			cur_best_fit_dist = dist;
+			cur_best_fit = i;
+		}
+	}
+	return &supported_modes[cur_best_fit];
+}
+
+static int og01a10_set_fmt(struct v4l2_subdev *sd,
+			  struct v4l2_subdev_pad_config *cfg,
+			  struct v4l2_subdev_format *fmt)
+{
+	struct og01a10 *og01a10 = to_og01a10(sd);
+	const struct og01a10_mode *mode;
+	s64 h_blank, vblank_def;
+	u64 dst_link_freq = 0;
+	u64 dst_pixel_rate = 0;
+
+	mutex_lock(&og01a10->mutex);
+
+	mode = og01a10_find_best_fit(fmt);
+	fmt->format.code = PIX_FORMAT;
+	fmt->format.width = mode->width;
+	fmt->format.height = mode->height;
+	fmt->format.field = V4L2_FIELD_NONE;
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+#else
+		mutex_unlock(&og01a10->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		og01a10->cur_mode = mode;
+		h_blank = mode->hts_def - mode->width;
+		__v4l2_ctrl_modify_range(og01a10->hblank, h_blank,
+					 h_blank, 1, h_blank);
+		vblank_def = mode->vts_def - mode->height;
+		__v4l2_ctrl_modify_range(og01a10->vblank, vblank_def,
+					 OG01A10_VTS_MAX - mode->height,
+					 1, vblank_def);
+		if (mode->hdr_mode == NO_HDR) {
+			dst_link_freq = 0;
+			dst_pixel_rate = OG01A10_PIXEL_RATE;
+		}
+		__v4l2_ctrl_s_ctrl_int64(og01a10->pixel_rate,
+					 dst_pixel_rate);
+		__v4l2_ctrl_s_ctrl(og01a10->link_freq,
+				   dst_link_freq);
+	}
+
+	mutex_unlock(&og01a10->mutex);
+
+	return 0;
+}
+
+static int og01a10_get_fmt(struct v4l2_subdev *sd,
+			  struct v4l2_subdev_pad_config *cfg,
+			  struct v4l2_subdev_format *fmt)
+{
+	struct og01a10 *og01a10 = to_og01a10(sd);
+	const struct og01a10_mode *mode = og01a10->cur_mode;
+
+	mutex_lock(&og01a10->mutex);
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+#else
+		mutex_unlock(&og01a10->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		fmt->format.width = mode->width;
+		fmt->format.height = mode->height;
+		fmt->format.code = PIX_FORMAT;
+		fmt->format.field = V4L2_FIELD_NONE;
+		if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
+			fmt->reserved[0] = mode->vc[fmt->pad];
+		else
+			fmt->reserved[0] = mode->vc[PAD0];
+	}
+	mutex_unlock(&og01a10->mutex);
+
+	return 0;
+}
+
+static int og01a10_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_pad_config *cfg,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index != 0)
+		return -EINVAL;
+	code->code = PIX_FORMAT;
+
+	return 0;
+}
+
+static int og01a10_enum_frame_sizes(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_pad_config *cfg,
+				   struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	if (fse->code != PIX_FORMAT)
+		return -EINVAL;
+
+	fse->min_width = supported_modes[fse->index].width;
+	fse->max_width = supported_modes[fse->index].width;
+	fse->max_height = supported_modes[fse->index].height;
+	fse->min_height = supported_modes[fse->index].height;
+
+	return 0;
+}
+
+static int og01a10_enable_test_pattern(struct og01a10 *og01a10, u32 pattern)
+{
+	u32 val;
+
+	if (pattern)
+		val = (pattern - 1) | OG01A10_TEST_PATTERN_ENABLE;
+	else
+		val = OG01A10_TEST_PATTERN_DISABLE;
+
+	return og01a10_write_reg(og01a10->client, OG01A10_REG_TEST_PATTERN,
+				 OG01A10_REG_VALUE_08BIT, val);
+}
+
+static void og01a10_get_module_inf(struct og01a10 *og01a10,
+				   struct rkmodule_inf *inf)
+{
+	memset(inf, 0, sizeof(*inf));
+	strscpy(inf->base.sensor, OG01A10_NAME, sizeof(inf->base.sensor));
+	strscpy(inf->base.module, og01a10->module_name,
+		sizeof(inf->base.module));
+	strscpy(inf->base.lens, og01a10->len_name, sizeof(inf->base.lens));
+}
+
+static long og01a10_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	struct og01a10 *og01a10 = to_og01a10(sd);
+	struct rkmodule_hdr_cfg *hdr_cfg;
+	long ret = 0;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		og01a10_get_module_inf(og01a10, (struct rkmodule_inf *)arg);
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
+		if (hdr_cfg->hdr_mode != 0)
+			ret = -1;
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
+		hdr_cfg->esp.mode = HDR_NORMAL_VC;
+		hdr_cfg->hdr_mode = og01a10->cur_mode->hdr_mode;
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		stream = *((u32 *)arg);
+
+		if (stream)
+			ret = og01a10_write_reg(og01a10->client, OG01A10_REG_CTRL_MODE,
+				OG01A10_REG_VALUE_08BIT, OG01A10_MODE_STREAMING);
+		else
+			ret = og01a10_write_reg(og01a10->client, OG01A10_REG_CTRL_MODE,
+				OG01A10_REG_VALUE_08BIT, OG01A10_MODE_SW_STANDBY);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long og01a10_compat_ioctl32(struct v4l2_subdev *sd,
+				   unsigned int cmd, unsigned long arg)
+{
+	void __user *up = compat_ptr(arg);
+	struct rkmodule_inf *inf;
+	struct rkmodule_hdr_cfg *hdr;
+	long ret;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
+		if (!inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+		ret = og01a10_ioctl(sd, cmd, inf);
+		if (!ret) {
+			ret = copy_to_user(up, inf, sizeof(*inf));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(inf);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+		ret = og01a10_ioctl(sd, cmd, hdr);
+		if (!ret) {
+			ret = copy_to_user(up, hdr, sizeof(*hdr));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(hdr);
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+		if (copy_from_user(hdr, up, sizeof(*hdr)))
+			return -EFAULT;
+		ret = og01a10_ioctl(sd, cmd, hdr);
+		kfree(hdr);
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		ret = copy_from_user(&stream, up, sizeof(u32));
+		if (!ret)
+			ret = og01a10_ioctl(sd, cmd, &stream);
+		else
+			ret = -EFAULT;
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+#endif
+
+static int __og01a10_start_stream(struct og01a10 *og01a10)
+{
+	int ret;
+
+	ret = og01a10_write_array(og01a10->client, og01a10->cur_mode->reg_list);
+	if (ret)
+		return ret;
+
+	/* In case these controls are set before streaming */
+	mutex_unlock(&og01a10->mutex);
+	ret = v4l2_ctrl_handler_setup(&og01a10->ctrl_handler);
+	mutex_lock(&og01a10->mutex);
+	if (ret)
+		return ret;
+
+	return og01a10_write_reg(og01a10->client, OG01A10_REG_CTRL_MODE,
+			OG01A10_REG_VALUE_08BIT, OG01A10_MODE_STREAMING);
+}
+
+static int __og01a10_stop_stream(struct og01a10 *og01a10)
+{
+	return og01a10_write_reg(og01a10->client, OG01A10_REG_CTRL_MODE,
+			OG01A10_REG_VALUE_08BIT, OG01A10_MODE_SW_STANDBY);
+}
+
+static int og01a10_s_stream(struct v4l2_subdev *sd, int on)
+{
+	struct og01a10 *og01a10 = to_og01a10(sd);
+	struct i2c_client *client = og01a10->client;
+	int ret = 0;
+
+	mutex_lock(&og01a10->mutex);
+	on = !!on;
+	if (on == og01a10->streaming)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		ret = __og01a10_start_stream(og01a10);
+		if (ret) {
+			v4l2_err(sd, "start stream failed while write regs\n");
+			pm_runtime_put(&client->dev);
+			goto unlock_and_return;
+		}
+	} else {
+		__og01a10_stop_stream(og01a10);
+		pm_runtime_put(&client->dev);
+	}
+
+	og01a10->streaming = on;
+
+unlock_and_return:
+	mutex_unlock(&og01a10->mutex);
+
+	return ret;
+}
+
+static int og01a10_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct og01a10 *og01a10 = to_og01a10(sd);
+	struct i2c_client *client = og01a10->client;
+	int ret = 0;
+
+	mutex_lock(&og01a10->mutex);
+
+	/* If the power state is not modified - no work to do. */
+	if (og01a10->power_on == !!on)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+		og01a10->power_on = true;
+	} else {
+		pm_runtime_put(&client->dev);
+		og01a10->power_on = false;
+	}
+
+unlock_and_return:
+	mutex_unlock(&og01a10->mutex);
+
+	return ret;
+}
+
+static int og01a10_g_frame_interval(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_frame_interval *fi)
+{
+	struct og01a10 *og01a10 = to_og01a10(sd);
+	const struct og01a10_mode *mode = og01a10->cur_mode;
+
+	fi->interval = mode->max_fps;
+	return 0;
+}
+
+/* Calculate the delay in us by clock rate and clock cycles */
+static inline u32 og01a10_cal_delay(u32 cycles)
+{
+	return DIV_ROUND_UP(cycles, OG01A10_XVCLK_FREQ / 1000 / 1000);
+}
+
+static int __og01a10_power_on(struct og01a10 *og01a10)
+{
+	int ret;
+	u32 delay_us;
+	struct device *dev = &og01a10->client->dev;
+
+	if (!IS_ERR_OR_NULL(og01a10->pins_default)) {
+		ret = pinctrl_select_state(og01a10->pinctrl,
+					   og01a10->pins_default);
+		if (ret < 0)
+			dev_err(dev, "could not set pins\n");
+	}
+
+	ret = clk_set_rate(og01a10->xvclk, OG01A10_XVCLK_FREQ);
+	if (ret < 0)
+		dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
+	if (clk_get_rate(og01a10->xvclk) != OG01A10_XVCLK_FREQ)
+		dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
+	ret = clk_prepare_enable(og01a10->xvclk);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable xvclk\n");
+		return ret;
+	}
+
+	ret = regulator_bulk_enable(OG01A10_NUM_SUPPLIES, og01a10->supplies);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable regulators\n");
+		goto disable_clk;
+	}
+	if (!IS_ERR(og01a10->reset_gpio))
+		gpiod_set_value_cansleep(og01a10->reset_gpio, 1);
+	if (!IS_ERR(og01a10->reset_gpio))
+		gpiod_set_value_cansleep(og01a10->reset_gpio, 1);
+	usleep_range(1000, 2000);
+	if (!IS_ERR(og01a10->pwdn_gpio))
+		gpiod_set_value_cansleep(og01a10->pwdn_gpio, 0);
+	else
+		dev_err(dev, "Failed to pwdn_gpio 1\n");
+	if (!IS_ERR(og01a10->reset_gpio))
+		gpiod_set_value_cansleep(og01a10->reset_gpio, 0);
+	else
+		dev_err(dev, "Failed to reset_gpio 1\n");
+	usleep_range(10000, 20000);
+
+	/* 8192 cycles prior to first SCCB transaction */
+	delay_us = og01a10_cal_delay(8192);
+	usleep_range(delay_us, delay_us * 2);
+
+	return 0;
+
+disable_clk:
+	clk_disable_unprepare(og01a10->xvclk);
+
+	return ret;
+}
+
+static void __og01a10_power_off(struct og01a10 *og01a10)
+{
+	int ret;
+
+	if (!IS_ERR(og01a10->reset_gpio))
+		gpiod_set_value_cansleep(og01a10->reset_gpio, 1);
+
+	if (!IS_ERR(og01a10->pwdn_gpio))
+		gpiod_set_value_cansleep(og01a10->pwdn_gpio, 0);
+
+	clk_disable_unprepare(og01a10->xvclk);
+	if (!IS_ERR_OR_NULL(og01a10->pins_sleep)) {
+		ret = pinctrl_select_state(og01a10->pinctrl,
+					   og01a10->pins_sleep);
+		if (ret < 0)
+			dev_dbg(&og01a10->client->dev, "could not set pins\n");
+	}
+	regulator_bulk_disable(OG01A10_NUM_SUPPLIES, og01a10->supplies);
+}
+
+static int og01a10_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct og01a10 *og01a10 = to_og01a10(sd);
+
+	return __og01a10_power_on(og01a10);
+}
+
+static int og01a10_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct og01a10 *og01a10 = to_og01a10(sd);
+
+	__og01a10_power_off(og01a10);
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int og01a10_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct og01a10 *og01a10 = to_og01a10(sd);
+	struct v4l2_mbus_framefmt *try_fmt =
+				v4l2_subdev_get_try_format(sd, fh->pad, 0);
+	const struct og01a10_mode *def_mode = &supported_modes[0];
+
+	mutex_lock(&og01a10->mutex);
+	/* Initialize try_fmt */
+	try_fmt->width = def_mode->width;
+	try_fmt->height = def_mode->height;
+	try_fmt->code = PIX_FORMAT;
+	try_fmt->field = V4L2_FIELD_NONE;
+
+	mutex_unlock(&og01a10->mutex);
+	/* No crop or compose */
+
+	return 0;
+}
+#endif
+
+static int og01a10_enum_frame_interval(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_pad_config *cfg,
+				      struct v4l2_subdev_frame_interval_enum *fie)
+{
+	if (fie->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	if (fie->code != PIX_FORMAT)
+		return -EINVAL;
+
+	fie->width = supported_modes[fie->index].width;
+	fie->height = supported_modes[fie->index].height;
+	fie->interval = supported_modes[fie->index].max_fps;
+	fie->reserved[0] = supported_modes[fie->index].hdr_mode;
+	return 0;
+}
+
+static int og01a10_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
+				struct v4l2_mbus_config *config)
+{
+	u32 val = 0;
+
+	val = 1 << (OG01A10_LANES - 1) |
+	      V4L2_MBUS_CSI2_CHANNEL_0 |
+	      V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+	config->type = V4L2_MBUS_CSI2_DPHY;
+	config->flags = val;
+
+	return 0;
+}
+
+static const struct dev_pm_ops og01a10_pm_ops = {
+	SET_RUNTIME_PM_OPS(og01a10_runtime_suspend,
+			   og01a10_runtime_resume, NULL)
+};
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static const struct v4l2_subdev_internal_ops og01a10_internal_ops = {
+	.open = og01a10_open,
+};
+#endif
+
+static const struct v4l2_subdev_core_ops og01a10_core_ops = {
+	.s_power = og01a10_s_power,
+	.ioctl = og01a10_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl32 = og01a10_compat_ioctl32,
+#endif
+};
+
+static const struct v4l2_subdev_video_ops og01a10_video_ops = {
+	.s_stream = og01a10_s_stream,
+	.g_frame_interval = og01a10_g_frame_interval,
+};
+
+static const struct v4l2_subdev_pad_ops og01a10_pad_ops = {
+	.enum_mbus_code = og01a10_enum_mbus_code,
+	.enum_frame_size = og01a10_enum_frame_sizes,
+	.enum_frame_interval = og01a10_enum_frame_interval,
+	.get_fmt = og01a10_get_fmt,
+	.set_fmt = og01a10_set_fmt,
+	.get_mbus_config = og01a10_g_mbus_config,
+};
+
+static const struct v4l2_subdev_ops og01a10_subdev_ops = {
+	.core	= &og01a10_core_ops,
+	.video	= &og01a10_video_ops,
+	.pad	= &og01a10_pad_ops,
+};
+
+static int og01a10_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct og01a10 *og01a10 = container_of(ctrl->handler,
+					       struct og01a10, ctrl_handler);
+	struct i2c_client *client = og01a10->client;
+	s64 max;
+	int ret = 0;
+	u32 again, dgain;
+
+	/* Propagate change of current control to all related controls */
+	switch (ctrl->id) {
+	case V4L2_CID_VBLANK:
+		/* Update max exposure while meeting expected vblanking */
+		max = og01a10->cur_mode->height + ctrl->val - 6;
+		__v4l2_ctrl_modify_range(og01a10->exposure,
+					 og01a10->exposure->minimum, max,
+					 og01a10->exposure->step,
+					 og01a10->exposure->default_value);
+		break;
+	}
+
+	if (!pm_runtime_get_if_in_use(&client->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		/* 4 least significant bits of expsoure are fractional part */
+		ret = og01a10_write_reg(og01a10->client, OG01A10_REG_EXPOSURE,
+			OG01A10_REG_VALUE_16BIT, ctrl->val);
+		break;
+	case V4L2_CID_ANALOGUE_GAIN:
+		if (ctrl->val > 3968) {
+			again = 3968;
+			dgain = 1024 * ctrl->val / 3968;
+		} else {
+			again = ctrl->val;
+			dgain = 1024;
+		}
+		ret = og01a10_write_reg(og01a10->client, OG01A10_REG_AGAIN,
+			OG01A10_REG_VALUE_16BIT, again);
+		ret |= og01a10_write_reg(og01a10->client, OG01A10_REG_DGAIN,
+			OG01A10_REG_VALUE_24BIT, dgain << 6);
+		break;
+	case V4L2_CID_VBLANK:
+		ret = og01a10_write_reg(og01a10->client, OG01A10_REG_VTS,
+					OG01A10_REG_VALUE_16BIT,
+					ctrl->val + og01a10->cur_mode->height);
+		break;
+	case V4L2_CID_TEST_PATTERN:
+		ret = og01a10_enable_test_pattern(og01a10, ctrl->val);
+		break;
+	default:
+		dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
+			 __func__, ctrl->id, ctrl->val);
+		break;
+	}
+
+	pm_runtime_put(&client->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops og01a10_ctrl_ops = {
+	.s_ctrl = og01a10_set_ctrl,
+};
+
+static int og01a10_initialize_controls(struct og01a10 *og01a10)
+{
+	const struct og01a10_mode *mode;
+	struct v4l2_ctrl_handler *handler;
+	s64 exposure_max, vblank_def;
+	u32 h_blank;
+	int ret;
+
+	handler = &og01a10->ctrl_handler;
+	mode = og01a10->cur_mode;
+	ret = v4l2_ctrl_handler_init(handler, 8);
+	if (ret)
+		return ret;
+	handler->lock = &og01a10->mutex;
+
+	og01a10->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
+		V4L2_CID_LINK_FREQ,
+		ARRAY_SIZE(link_freq_menu_items) - 1, 0,
+		link_freq_menu_items);
+	__v4l2_ctrl_s_ctrl(og01a10->link_freq, 0);
+
+	og01a10->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
+		V4L2_CID_PIXEL_RATE, 0, OG01A10_PIXEL_RATE, 1, OG01A10_PIXEL_RATE);
+
+	h_blank = mode->hts_def - mode->width;
+	og01a10->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
+				h_blank, h_blank, 1, h_blank);
+	if (og01a10->hblank)
+		og01a10->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	vblank_def = mode->vts_def - mode->height;
+	og01a10->vblank = v4l2_ctrl_new_std(handler, &og01a10_ctrl_ops,
+				V4L2_CID_VBLANK, vblank_def,
+				OG01A10_VTS_MAX - mode->height,
+				1, vblank_def);
+
+	exposure_max = mode->vts_def - 6;
+	og01a10->exposure = v4l2_ctrl_new_std(handler, &og01a10_ctrl_ops,
+				V4L2_CID_EXPOSURE, OG01A10_EXPOSURE_MIN,
+				exposure_max, OG01A10_EXPOSURE_STEP,
+				mode->exp_def);
+
+	og01a10->anal_gain = v4l2_ctrl_new_std(handler, &og01a10_ctrl_ops,
+				V4L2_CID_ANALOGUE_GAIN, ANALOG_GAIN_MIN,
+				ANALOG_GAIN_MAX, ANALOG_GAIN_STEP,
+				ANALOG_GAIN_DEFAULT);
+
+	og01a10->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
+				&og01a10_ctrl_ops, V4L2_CID_TEST_PATTERN,
+				ARRAY_SIZE(og01a10_test_pattern_menu) - 1,
+				0, 0, og01a10_test_pattern_menu);
+
+	if (handler->error) {
+		ret = handler->error;
+		dev_err(&og01a10->client->dev,
+			"Failed to init controls(%d)\n", ret);
+		goto err_free_handler;
+	}
+
+	og01a10->subdev.ctrl_handler = handler;
+
+	return 0;
+
+err_free_handler:
+	v4l2_ctrl_handler_free(handler);
+
+	return ret;
+}
+
+static int og01a10_check_sensor_id(struct og01a10 *og01a10,
+				  struct i2c_client *client)
+{
+	struct device *dev = &og01a10->client->dev;
+	u32 id = 0;
+	int ret;
+
+	ret = og01a10_read_reg(client, OG01A10_REG_CHIP_ID,
+			       OG01A10_REG_VALUE_16BIT, &id);
+	if (id != CHIP_ID) {
+		dev_err(dev, "Unexpected sensor id(%04x), ret(%d)\n", id, ret);
+		return -ENODEV;
+	}
+
+	dev_info(dev, "Detected OG01A10 CHIP ID = 0x%04x sensor\n", CHIP_ID);
+
+	return 0;
+}
+
+static int og01a10_configure_regulators(struct og01a10 *og01a10)
+{
+	unsigned int i;
+
+	for (i = 0; i < OG01A10_NUM_SUPPLIES; i++)
+		og01a10->supplies[i].supply = og01a10_supply_names[i];
+
+	return devm_regulator_bulk_get(&og01a10->client->dev,
+				       OG01A10_NUM_SUPPLIES,
+				       og01a10->supplies);
+}
+
+static int og01a10_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct device_node *node = dev->of_node;
+	struct og01a10 *og01a10;
+	struct v4l2_subdev *sd;
+	char facing[2];
+	int ret;
+
+	dev_info(dev, "driver version: %02x.%02x.%02x",
+		 DRIVER_VERSION >> 16,
+		 (DRIVER_VERSION & 0xff00) >> 8,
+		 DRIVER_VERSION & 0x00ff);
+
+	og01a10 = devm_kzalloc(dev, sizeof(*og01a10), GFP_KERNEL);
+	if (!og01a10)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
+				   &og01a10->module_index);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
+				       &og01a10->module_facing);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
+				       &og01a10->module_name);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
+				       &og01a10->len_name);
+	if (ret) {
+		dev_err(dev, "could not get module information!\n");
+		return -EINVAL;
+	}
+	og01a10->client = client;
+	og01a10->cur_mode = &supported_modes[0];
+
+	og01a10->xvclk = devm_clk_get(dev, "xvclk");
+	if (IS_ERR(og01a10->xvclk)) {
+		dev_err(dev, "Failed to get xvclk\n");
+		return -EINVAL;
+	}
+
+	og01a10->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(og01a10->reset_gpio))
+		dev_err(dev, "Failed to get reset-gpios\n");
+
+	og01a10->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
+	if (IS_ERR(og01a10->pwdn_gpio))
+		dev_warn(dev, "Failed to get pwdn-gpios\n");
+	ret = og01a10_configure_regulators(og01a10);
+	if (ret) {
+		dev_err(dev, "Failed to get power regulators\n");
+		return ret;
+	}
+
+	og01a10->pinctrl = devm_pinctrl_get(dev);
+	if (!IS_ERR(og01a10->pinctrl)) {
+		og01a10->pins_default =
+			pinctrl_lookup_state(og01a10->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_DEFAULT);
+		if (IS_ERR(og01a10->pins_default))
+			dev_err(dev, "could not get default pinstate\n");
+
+		og01a10->pins_sleep =
+			pinctrl_lookup_state(og01a10->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_SLEEP);
+		if (IS_ERR(og01a10->pins_sleep))
+			dev_err(dev, "could not get sleep pinstate\n");
+	}
+	mutex_init(&og01a10->mutex);
+
+	sd = &og01a10->subdev;
+	v4l2_i2c_subdev_init(sd, client, &og01a10_subdev_ops);
+	ret = og01a10_initialize_controls(og01a10);
+	if (ret)
+		goto err_destroy_mutex;
+
+	ret = __og01a10_power_on(og01a10);
+	if (ret)
+		goto err_free_handler;
+
+	ret = og01a10_check_sensor_id(og01a10, client);
+	if (ret)
+		goto err_power_off;
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	sd->internal_ops = &og01a10_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+		     V4L2_SUBDEV_FL_HAS_EVENTS;
+#endif
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	og01a10->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &og01a10->pad);
+	if (ret < 0)
+		goto err_power_off;
+#endif
+
+	memset(facing, 0, sizeof(facing));
+	if (strcmp(og01a10->module_facing, "back") == 0)
+		facing[0] = 'b';
+	else
+		facing[0] = 'f';
+
+	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
+		 og01a10->module_index, facing,
+		 OG01A10_NAME, dev_name(sd->dev));
+	ret = v4l2_async_register_subdev_sensor_common(sd);
+	if (ret) {
+		dev_err(dev, "v4l2 async register subdev failed\n");
+		goto err_clean_entity;
+	}
+
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_idle(dev);
+
+	return 0;
+
+err_clean_entity:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+err_power_off:
+	__og01a10_power_off(og01a10);
+err_free_handler:
+	v4l2_ctrl_handler_free(&og01a10->ctrl_handler);
+err_destroy_mutex:
+	mutex_destroy(&og01a10->mutex);
+
+	return ret;
+}
+
+static int og01a10_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct og01a10 *og01a10 = to_og01a10(sd);
+
+	v4l2_async_unregister_subdev(sd);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+	v4l2_ctrl_handler_free(&og01a10->ctrl_handler);
+	mutex_destroy(&og01a10->mutex);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		__og01a10_power_off(og01a10);
+	pm_runtime_set_suspended(&client->dev);
+
+	return 0;
+}
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id og01a10_of_match[] = {
+	{ .compatible = "ovti,og01a10" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, og01a10_of_match);
+#endif
+
+static const struct i2c_device_id og01a10_match_id[] = {
+	{ "ovti,og01a10", 0 },
+	{ },
+};
+
+static struct i2c_driver og01a10_i2c_driver = {
+	.driver = {
+		.name = OG01A10_NAME,
+		.pm = &og01a10_pm_ops,
+		.of_match_table = of_match_ptr(og01a10_of_match),
+	},
+	.probe		= &og01a10_probe,
+	.remove		= &og01a10_remove,
+	.id_table	= og01a10_match_id,
+};
+
+static int __init sensor_mod_init(void)
+{
+	return i2c_add_driver(&og01a10_i2c_driver);
+}
+
+static void __exit sensor_mod_exit(void)
+{
+	i2c_del_driver(&og01a10_i2c_driver);
+}
+
+device_initcall_sync(sensor_mod_init);
+module_exit(sensor_mod_exit);
+
+MODULE_DESCRIPTION("Ovti og01a10 sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/og02b10.c b/kernel/drivers/media/i2c/og02b10.c
new file mode 100644
index 0000000..7d333de
--- /dev/null
+++ b/kernel/drivers/media/i2c/og02b10.c
@@ -0,0 +1,1774 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * og02b10 driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * V0.0X01.0X00 first version.
+ */
+//#define DEBUG
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/rk-camera-module.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/rk-preisp.h>
+#include "../platform/rockchip/isp/rkisp_tb_helper.h"
+
+#include <linux/of_gpio.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <linux/gpio.h>
+
+#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x00)
+
+/* The base for the og driver controls.
+ * We reserve 16 controls for this driver.
+ */
+#define V4L2_CID_USER_OG_BASE			(V4L2_CID_USER_BASE + 0x10c0)
+#define V4L2_CID_OG_LOW_POWER_MODE		(V4L2_CID_USER_OG_BASE + 0)
+
+#define OG02B10_LANES				2
+#define MIPI_FREQ_400M				400000000
+#define PIXEL_RATE_WITH_400M			(MIPI_FREQ_400M * 2 / 10 * OG02B10_LANES)
+#define OG02B10_XVCLK_FREQ			24000000
+
+#define OG02B10_SYS_CLK				80000000
+#define OG02B10_VTS_MAX				0x14DDE
+
+#define OG02B10_CHIP_ID0			0x20
+#define OG02B10_CHIP_ID1			0xC0
+#define OG02B10_CHIP_ID2			0xE0
+#define OG02B10_REG_SC_SCCB_ID0			0x0107
+#define OG02B10_REG_SC_SCCB_ID1			0x0109
+#define OG02B10_REG_SC_SCCB_ID2			0x302B
+
+#define OG02B10_GAIN_MIN			16
+#define OG02B10_GAIN_MAX			988
+#define OG02B10_GAIN_STEP			1
+#define OG02B10_GAIN_DEFAULT			0x80
+
+#define OG02B10_EXPOSURE_MIN			1
+#define OG02B10_EXPOSURE_STEP			1
+
+#define OG02B10_REG_GROUP_HOLD			0x3208
+#define OG02B10_GROUP0_HOLD_START		0x00
+#define OG02B10_GROUP0_HOLD_END			0x10
+#define OG02B10_GROUP_LAUNCH			0xA0
+
+#define OG02B10_REG_EXP_H			0x3501
+#define OG02B10_REG_EXP_L			0x3502
+
+#define OG02B10_REG_HTS_H			0x380C
+#define OG02B10_REG_HTS_L			0x380D
+#define OG02B10_REG_VTS_H			0x380E
+#define OG02B10_REG_VTS_L			0x380F
+
+#define OG02B10_REG_AGAIN_COARSE		0x3508
+#define OG02B10_REG_AGAIN_FINE			0x3509
+
+#define OG02B10_REG_DGAIN_COARSE		0x350A
+#define OG02B10_REG_DGAIN_FINE_H		0x350B
+#define OG02B10_REG_DGAIN_FINE_L		0x350C
+
+#define OG02B10_REG_CTRL_MODE			0x0100
+#define OG02B10_MODE_SW_STANDBY			0x0
+#define OG02B10_MODE_STREAMING			BIT(0)
+
+#define OG02B10_REG_SOFTWARE_RESET		0x0103
+#define OG02B10_SOFTWARE_RESET_VAL		0x1
+
+#define OG02B10_REG_TEST_PATTERN		0x5E00
+#define OG02B10_TEST_PATTERN_DISABLE_VAL	0x00
+#define OG02B10_TEST_PATTERN_ENABLE_VAL		0x80
+
+#define OG02B10_REG_FILP			0x3820
+#define OG02B10_REG_MIRROR			0x3821
+#define OG02B10_FILP_ENABLE_VAL			0x44
+#define OG02B10_FILP_DISABLE_VAL		0x00
+#define OG02B10_MIRROR_ENABLE_VAL		0x04
+#define OG02B10_MIRROR_DISABLE_VAL		0x00
+
+
+//disable FSIN output, bit operation, set 0x3006[1]=0
+//enable  FSIN output, bit operation, set 0x3006[1]=1
+#define OG02B10_REG_IO_PAD_OUT_EN		0x3006
+#define OG02B10_IO_PAD_OUT_EN_DEFAULT		0x0a
+#define OG02B10_FSIN_OUTPUT_ENABLE		BIT(1)
+
+//r_frame_on_num(active frames after wake-up)
+#define OG02B10_REG_R_FRAME_ON_NUM		0x303F
+
+#define OG02B10_REG_SCCB_SEL			0x31FF
+#define OG02B10_CLOCKLESS_SCCB			0X0
+
+#define OG02B10_REG_LOW_POWER_MODE_CTRL		0x3030
+#define OG02B10_LOW_FRAME_RATE_VAL		BIT(4)
+#define OG02B10_EXTERNAL_TRIGGER_VAL		BIT(2)
+
+#define OG02B10_REG_POWER_CTRL_OPTIONS		0x4F00
+#define OG02B10_NORMAL_MODE			0
+#define OG02B10_LOW_POWER_MODE			1
+
+#define OG02B10_NAME				"og02b10"
+
+#define OF_CAMERA_HDR_MODE			"rockchip,camera-hdr-mode"
+#define OF_CAMERA_PINCTRL_STATE_DEFAULT		"default"
+#define OF_CAMERA_PINCTRL_STATE_MCLK		"mclk"
+
+#define REG_NULL				0xFFFF
+
+static const char * const OG02B10_supply_names[] = {
+	"avdd",		/* Analog power */
+	"dovdd",	/* Digital I/O power */
+	"dvdd",		/* Digital core power */
+};
+
+#define OG02B10_NUM_SUPPLIES ARRAY_SIZE(OG02B10_supply_names)
+
+enum og02b10_low_power_mode_em {
+	LOW_POWER_MODE_DISABLE = 0,
+	LOW_FRAME_RATE_MODE,
+	INTERNAL_TRIGGER_MODE,
+	EXTERNAL_TRIGGER_MODE,
+	LOW_POWER_MODE_MAX
+};
+
+struct regval {
+	u16 addr;
+	u8 val;
+};
+
+struct og02b10_mode {
+	u32 bus_fmt;
+	u32 width;
+	u32 height;
+	struct v4l2_fract max_fps;
+	u32 hts_def;
+	u32 vts_def;
+	u32 exp_def;
+	const struct regval *reg_list;
+	u32 hdr_mode;
+	u32 vc[PAD_MAX];
+};
+
+struct og02b10 {
+	struct i2c_client	*client;
+	struct clk		*xvclk;
+	struct gpio_desc	*reset_gpio;
+	struct gpio_desc	*pwdn_gpio;
+	struct regulator_bulk_data supplies[OG02B10_NUM_SUPPLIES];
+
+	struct pinctrl		*pinctrl;
+	struct pinctrl_state	*pins_default;
+	struct pinctrl_state	*pins_mclk;
+
+	struct v4l2_subdev	subdev;
+	struct media_pad	pad;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl	*exposure;
+	struct v4l2_ctrl	*anal_gain;
+	struct v4l2_ctrl	*digi_gain;
+	struct v4l2_ctrl	*hblank;
+	struct v4l2_ctrl	*vblank;
+	struct v4l2_ctrl	*pixel_rate;
+	struct v4l2_ctrl	*link_freq;
+	struct v4l2_ctrl	*h_flip;
+	struct v4l2_ctrl	*v_flip;
+	struct v4l2_ctrl	*test_pattern;
+	struct v4l2_ctrl	*low_power_mode;
+	struct mutex		mutex;
+	bool			streaming;
+	bool			power_on;
+	bool			slave_mode;
+
+	const struct og02b10_mode *cur_mode;
+	u32			cfg_num;
+	u32			module_index;
+	const char		*module_facing;
+	const char		*module_name;
+	const char		*len_name;
+	bool			has_init_exp;
+	struct preisp_hdrae_exp_s init_hdrae_exp;
+};
+
+#define to_og02b10(sd) container_of(sd, struct og02b10, subdev)
+
+/*
+ * Xclk 24Mhz
+ */
+static const struct regval og02b10_linear10bit_1600x1200_regs[] = {
+	// SOFTWARE RESET(0:off, 1:on)
+	{0x0103, 0x01},
+	// MODE SELECT(0:software_standby, 1:streaming)
+	{0x0100, 0x00},
+	//ENTER SAFE MODE(0:Keep, 1:Enter safe mode)
+	{0x010c, 0x02},
+	//ENTER SOFTWARE STANDBY(0:Keep, 1:Enter software standby)
+	{0x010b, 0x01},
+
+	// PLL control
+	{0x0300, 0x01},
+	{0x0302, 0x32},
+	{0x0303, 0x00},
+	{0x0304, 0x03},
+	{0x0305, 0x02},
+	{0x0306, 0x01},
+	{0x030d, 0x5a},
+	{0x030e, 0x04},
+
+	// SC registers
+	{0x3001, 0x02},
+	{0x3004, 0x00},
+	{0x3005, 0x00},
+	{0x3006, 0x0a},
+	{0x3011, 0x0d},
+	{0x3014, 0x04},
+	{0x301c, 0xf0},
+	{0x3020, 0x20},
+	{0x302c, 0x00},
+	{0x302d, 0x00},
+	{0x302e, 0x00},
+	{0x302f, 0x03},
+	{0x3030, 0x10},
+
+	{0x303f, 0x03},
+
+	// SCCB control registers
+	{0x3103, 0x00},
+	{0x3106, 0x08},
+	{0x31ff, 0x01},
+
+	//aec_pk registers
+	{0x3501, 0x05},
+	{0x3502, 0x7c},
+	{0x3506, 0x00},
+	{0x3507, 0x00},
+
+	//ana control registers
+	{0x3620, 0x67},
+	{0x3633, 0x78},
+	{0x3662, 0x65},
+	{0x3664, 0xb0},
+	{0x3666, 0x70},
+	{0x3670, 0x68},
+	{0x3674, 0x10},
+	{0x3675, 0x00},
+	{0x367e, 0x90},
+	{0x3680, 0x84},
+	{0x3683, 0x96},
+	{0x36a2, 0x04},
+	{0x36a3, 0x80},
+	{0x36b0, 0x00},
+
+	//sensor control registers
+	{0x3700, 0x35},
+	{0x3704, 0x39},
+	{0x370a, 0x50},
+	{0x3712, 0x00},
+	{0x3713, 0x02},
+	{0x3778, 0x00},
+	{0x379b, 0x01},
+	{0x379c, 0x10},
+
+	//timing control registers
+	// horizontal start
+	{0x3800, 0x00},
+	{0x3801, 0x00},
+	// vertical start
+	{0x3802, 0x00},
+	{0x3803, 0x00},
+	// horizontal end
+	{0x3804, 0x06},
+	{0x3805, 0x4f},
+	// vertical end
+	{0x3806, 0x05},
+	{0x3807, 0x23},
+	// ISP output
+	{0x3808, 0x06},
+	{0x3809, 0x40},
+	{0x380a, 0x04},
+	{0x380b, 0xb0},
+	// HTS VTS
+	{0x380c, 0x03},
+	{0x380d, 0xa8},
+	{0x380e, 0x0b},
+	{0x380f, 0x10},
+	// ISP X/Y WIN
+	{0x3810, 0x00},
+	{0x3811, 0x08},
+	{0x3812, 0x00},
+	{0x3813, 0x08},
+	// X/Y odd/even
+	{0x3814, 0x11},
+	{0x3815, 0x11},
+	// HSYNC start/end
+	{0x3816, 0x00},
+	{0x3817, 0x01},
+	{0x3818, 0x00},
+	{0x3819, 0x05},
+	// vflip
+	{0x3820, 0x00},
+	{0x3821, 0x00},
+	// grp_wr_start/grp_wr_start
+	{0x382b, 0x32},
+	// hts_global_tx
+	{0x382c, 0x0a},
+	{0x382d, 0xf8},
+
+	//global shutter control registers
+	{0x3881, 0x44},
+	{0x3882, 0x02},
+	{0x3883, 0x8c},
+	{0x3885, 0x07},
+	{0x389d, 0x03},
+	{0x38a6, 0x00},
+	{0x38a7, 0x01},
+	{0x38b3, 0x07},
+	{0x38b1, 0x00},
+	{0x38e5, 0x02},
+	{0x38e7, 0x00},
+	{0x38e8, 0x00},
+	{0x3910, 0xff},
+	{0x3911, 0xff},
+	{0x3912, 0x08},
+	{0x3913, 0x00},
+	{0x3914, 0x00},
+	{0x3915, 0x00},
+	{0x391c, 0x00},
+	{0x3920, 0xff},
+	{0x3921, 0x80},
+	{0x3922, 0x00},
+	{0x3923, 0x00},
+	{0x3924, 0x05},
+	{0x3925, 0x00},
+	{0x3926, 0x00},
+	{0x3927, 0x00},
+	{0x3928, 0x1a},
+	{0x392d, 0x03},
+	{0x392e, 0xa8},
+	{0x392f, 0x08},
+
+	//BLC control registers
+	{0x4001, 0x00},
+	{0x4003, 0x40},
+	{0x4008, 0x04},
+	{0x4009, 0x1b},
+	{0x400c, 0x04},
+	{0x400d, 0x1b},
+	{0x4010, 0xf4},
+	{0x4011, 0x00},
+	{0x4016, 0x00},
+	{0x4017, 0x04},
+	{0x4042, 0x11},
+	{0x4043, 0x70},
+	{0x4045, 0x00},
+
+	// TPM registers
+	{0x4409, 0x5f},
+
+	// column_sync registers
+	{0x4509, 0x00},
+	{0x450b, 0x00},
+
+	// VFIFO registers
+	{0x4600, 0x00},
+	{0x4601, 0xa0},
+
+	// DVP registers
+	{0x4708, 0x09},
+	{0x470c, 0x81},
+	{0x4710, 0x06},
+	{0x4711, 0x00},
+
+	// MIPI control registers
+	{0x4800, 0x00},
+	{0x481f, 0x30},
+	{0x4837, 0x14},
+
+	// PSV control registers
+	{0x4f00, 0x00},
+	{0x4f07, 0x00},
+	{0x4f08, 0x03},
+	{0x4f09, 0x08},
+	{0x4f0c, 0x05},
+	{0x4f0d, 0xb4},
+	{0x4f10, 0x00},
+	{0x4f11, 0x00},
+	{0x4f12, 0x07},
+	{0x4f13, 0xe2},
+
+	// isp_main control registers
+	{0x5000, 0x1f},
+	{0x5001, 0x20},
+	{0x5026, 0x00},
+
+	// isp_otp_dpc control registers
+	{0x5c00, 0x00},
+	{0x5c01, 0x2c},
+	{0x5c02, 0x00},
+	{0x5c03, 0x7f},
+
+	// isp_pre control registers
+	{0x5e00, 0x00},
+	{0x5e01, 0x41},
+
+	// GLOBAL_SHUTTER_CTRL_31
+	{0x38b1, 0x03},
+
+	{REG_NULL, 0x00},
+};
+
+/*
+ * The width and height must be configured to be
+ * the same as the current output resolution of the sensor.
+ * The input width of the isp needs to be 16 aligned.
+ * The input height of the isp needs to be 8 aligned.
+ * If the width or height does not meet the alignment rules,
+ * you can configure the cropping parameters with the following function to
+ * crop out the appropriate resolution.
+ * struct v4l2_subdev_pad_ops {
+ *    .get_selection
+ * }
+ */
+static const struct og02b10_mode supported_modes[] = {
+	{
+		.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.width = 1600,
+		.height = 1200,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 300000,
+		},
+		/*
+		 * line_time = h_size / pclk
+		 *	    = hts_def  / 80Mhz = 0x3a8 / 80Mhz = 0.0117ms
+		 *
+		 * exposure time = int_t * line_time
+		 *		= exp_def * line_time
+		 *		= 0x02ea * 0.0117ms
+		 *		= 8.7282ms
+		 * max exposure time = vts_def * line_time
+		 *		    = 0x0b10 * 0.0117ms
+		 *		    = 33.1344ms
+		 */
+		.exp_def = 0x02ea,
+		.hts_def = 0x03a8,
+		.vts_def = 0x0b10,
+		.reg_list = og02b10_linear10bit_1600x1200_regs,
+		.hdr_mode = NO_HDR,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	},
+};
+
+static const s64 link_freq_menu_items[] = {
+	MIPI_FREQ_400M,
+};
+
+static int __og02b10_power_on(struct og02b10 *og02b10);
+
+static int og02b10_check_sensor_id(struct og02b10 *og02b10,
+				   struct i2c_client *client);
+
+/* sensor register write */
+static int og02b10_write_reg(struct i2c_client *client, u16 reg, u8 val)
+{
+	struct i2c_msg msg;
+	u8 buf[3];
+	int ret;
+
+	buf[0] = (reg >> 8) & 0xFF;
+	buf[1] = reg & 0xFF;
+	buf[2] = val;
+
+	msg.addr = client->addr;
+	msg.flags = client->flags;
+	msg.buf = buf;
+	msg.len = sizeof(buf);
+
+	ret = i2c_transfer(client->adapter, &msg, 1);
+	if (ret >= 0)
+		return 0;
+
+	dev_err(&client->dev,
+		"og02b10 write reg(0x%x val:0x%x) failed !\n", reg, val);
+
+	return ret;
+}
+
+static int og02b10_write_array(struct i2c_client *client,
+			       const struct regval *regs)
+{
+	int i, ret = 0;
+
+	i = 0;
+	while (regs[i].addr != REG_NULL) {
+		ret = og02b10_write_reg(client, regs[i].addr, regs[i].val);
+		if (ret) {
+			dev_err(&client->dev, "%s failed !\n", __func__);
+			break;
+		}
+		i++;
+	}
+
+	return ret;
+}
+
+/* sensor register read */
+static int og02b10_read_reg(struct i2c_client *client, u16 reg, u8 *val)
+{
+	struct i2c_msg msg[2];
+	u8 buf[2];
+	int ret;
+
+	buf[0] = (reg >> 8) & 0xFF;
+	buf[1] = reg & 0xFF;
+
+	msg[0].addr = client->addr;
+	msg[0].flags = client->flags;
+	msg[0].buf = buf;
+	msg[0].len = sizeof(buf);
+
+	msg[1].addr = client->addr;
+	msg[1].flags = client->flags | I2C_M_RD;
+	msg[1].buf = buf;
+	msg[1].len = 1;
+
+	ret = i2c_transfer(client->adapter, msg, 2);
+	if (ret >= 0) {
+		*val = buf[0];
+		return 0;
+	}
+
+	dev_err(&client->dev,
+		"og02b10 read reg(0x%x val:0x%x) failed !\n", reg, *val);
+
+	return ret;
+}
+
+static int og02b10_get_reso_dist(const struct og02b10_mode *mode,
+				 struct v4l2_mbus_framefmt *framefmt)
+{
+	return abs(mode->width - framefmt->width) +
+		abs(mode->height - framefmt->height);
+}
+
+static const struct og02b10_mode *
+og02b10_find_best_fit(struct og02b10 *og02b10, struct v4l2_subdev_format *fmt)
+{
+	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
+	int dist;
+	int cur_best_fit = 0;
+	int cur_best_fit_dist = -1;
+	unsigned int i;
+
+	for (i = 0; i < og02b10->cfg_num; i++) {
+		dist = og02b10_get_reso_dist(&supported_modes[i], framefmt);
+		if ((cur_best_fit_dist == -1 || dist <= cur_best_fit_dist) &&
+		    (supported_modes[i].bus_fmt == framefmt->code)) {
+			cur_best_fit_dist = dist;
+			cur_best_fit = i;
+		}
+	}
+
+	return &supported_modes[cur_best_fit];
+}
+
+static int og02b10_set_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct og02b10 *og02b10 = to_og02b10(sd);
+	const struct og02b10_mode *mode;
+	s64 h_blank, v_blank;
+	u64 dst_link_freq = 0;
+	u64 dst_pixel_rate = 0;
+
+	mutex_lock(&og02b10->mutex);
+	mode = og02b10_find_best_fit(og02b10, fmt);
+	fmt->format.code = mode->bus_fmt;
+	fmt->format.width = mode->width;
+	fmt->format.height = mode->height;
+	fmt->format.field = V4L2_FIELD_NONE;
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+#else
+		mutex_unlock(&og02b10->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		og02b10->cur_mode = mode;
+		h_blank = mode->hts_def;
+		__v4l2_ctrl_modify_range(og02b10->hblank, h_blank,
+					 h_blank, 1, h_blank);
+
+		v_blank = mode->vts_def;
+		__v4l2_ctrl_modify_range(og02b10->vblank, v_blank,
+					 v_blank, 1, v_blank);
+		if (mode->hdr_mode == NO_HDR) {
+			if (mode->bus_fmt == MEDIA_BUS_FMT_SBGGR10_1X10) {
+				dst_link_freq = 0;
+				dst_pixel_rate = PIXEL_RATE_WITH_400M;
+			}
+		}
+		__v4l2_ctrl_s_ctrl_int64(og02b10->pixel_rate,
+					 dst_pixel_rate);
+		__v4l2_ctrl_s_ctrl(og02b10->link_freq,
+				   dst_link_freq);
+	}
+
+	mutex_unlock(&og02b10->mutex);
+
+	return 0;
+}
+
+static int og02b10_get_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct og02b10 *og02b10 = to_og02b10(sd);
+	const struct og02b10_mode *mode = og02b10->cur_mode;
+
+	mutex_lock(&og02b10->mutex);
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+		v4l2_info(sd, "get format try.\n");
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+#else
+		mutex_unlock(&og02b10->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		fmt->format.width = mode->width;
+		fmt->format.height = mode->height;
+		fmt->format.code = mode->bus_fmt;
+		fmt->format.field = V4L2_FIELD_NONE;
+		if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
+			fmt->reserved[0] = mode->vc[fmt->pad];
+		else
+			fmt->reserved[0] = mode->vc[PAD0];
+	}
+	mutex_unlock(&og02b10->mutex);
+
+	v4l2_info(sd, "get format, width: %d, height: %d, code: %d, field: %d.\n",
+		  fmt->format.width, fmt->format.height,
+		  fmt->format.code, fmt->format.field);
+
+	return 0;
+}
+
+static int og02b10_enum_mbus_code(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_pad_config *cfg,
+				  struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct og02b10 *og02b10 = to_og02b10(sd);
+
+	if (code->index != 0)
+		return -EINVAL;
+	code->code = og02b10->cur_mode->bus_fmt;
+
+	return 0;
+}
+
+static int og02b10_enum_frame_sizes(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_pad_config *cfg,
+				    struct v4l2_subdev_frame_size_enum *fse)
+{
+	struct og02b10 *og02b10 = to_og02b10(sd);
+
+	if (fse->index >= og02b10->cfg_num)
+		return -EINVAL;
+
+	if (fse->code != supported_modes[fse->index].bus_fmt)
+		return -EINVAL;
+
+	fse->min_width	= supported_modes[fse->index].width;
+	fse->max_width	= supported_modes[fse->index].width;
+	fse->max_height = supported_modes[fse->index].height;
+	fse->min_height = supported_modes[fse->index].height;
+
+	return 0;
+}
+
+static int og02b10_g_frame_interval(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_frame_interval *fi)
+{
+	struct og02b10 *og02b10 = to_og02b10(sd);
+	const struct og02b10_mode *mode = og02b10->cur_mode;
+
+	fi->interval = mode->max_fps;
+
+	return 0;
+}
+
+static int og02b10_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
+		struct v4l2_mbus_config *config)
+{
+	struct og02b10 *og02b10 = to_og02b10(sd);
+	const struct og02b10_mode *mode = og02b10->cur_mode;
+	u32 val = 0;
+
+	if (mode->hdr_mode == NO_HDR)
+		val = 1 << (OG02B10_LANES - 1) |
+		      V4L2_MBUS_CSI2_CHANNEL_0 |
+		      V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+
+	if (mode->hdr_mode == HDR_X2)
+		val = 1 << (OG02B10_LANES - 1) |
+		      V4L2_MBUS_CSI2_CHANNEL_0 |
+		      V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
+		      V4L2_MBUS_CSI2_CHANNEL_1;
+
+	config->type = V4L2_MBUS_CSI2_DPHY;
+	config->flags = val;
+
+	return 0;
+}
+
+static void og02b10_get_module_inf(struct og02b10 *og02b10,
+		  struct rkmodule_inf *inf)
+{
+	memset(inf, 0, sizeof(*inf));
+	strscpy(inf->base.sensor, OG02B10_NAME, sizeof(inf->base.sensor));
+	strscpy(inf->base.module, og02b10->module_name,
+	sizeof(inf->base.module));
+	strscpy(inf->base.lens, og02b10->len_name, sizeof(inf->base.lens));
+}
+
+static long og02b10_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	struct og02b10 *og02b10 = to_og02b10(sd);
+	struct rkmodule_hdr_cfg *hdr_cfg;
+	long ret = 0;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_SET_HDR_CFG:
+		v4l2_info(sd, "cmd: RKMODULE_SET_HDR_CFG\n");
+		hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
+		if (hdr_cfg->hdr_mode != 0)
+			ret = -1;
+		break;
+	case RKMODULE_GET_MODULE_INFO:
+		v4l2_info(sd, "cmd: RKMODULE_GET_MODULE_INFO\n");
+		og02b10_get_module_inf(og02b10, (struct rkmodule_inf *)arg);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		v4l2_info(sd, "cmd: RKMODULE_GET_HDR_CFG\n");
+		hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
+		hdr_cfg->hdr_mode = og02b10->cur_mode->hdr_mode;
+		hdr_cfg->esp.mode = HDR_NORMAL_VC;
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		v4l2_info(sd, "cmd: RKMODULE_SET_QUICK_STREAM\n");
+		stream = *((u32 *)arg);
+		if (stream)
+			ret = og02b10_write_reg(og02b10->client, OG02B10_REG_CTRL_MODE,
+						OG02B10_MODE_STREAMING);
+		else
+			ret = og02b10_write_reg(og02b10->client, OG02B10_REG_CTRL_MODE,
+						OG02B10_MODE_SW_STANDBY);
+		break;
+	default:
+		v4l2_info(sd, "cmd missing\n");
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long og02b10_compat_ioctl32(struct v4l2_subdev *sd,
+		  unsigned int cmd, unsigned long arg)
+{
+	void __user *up = compat_ptr(arg);
+	struct rkmodule_inf *inf;
+	struct rkmodule_awb_cfg *cfg;
+	struct rkmodule_hdr_cfg *hdr;
+	struct preisp_hdrae_exp_s *hdrae;
+	long ret;
+	u32 cg = 0;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
+		if (!inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = og02b10_ioctl(sd, cmd, inf);
+		if (!ret) {
+			ret = copy_to_user(up, inf, sizeof(*inf));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(inf);
+		break;
+	case RKMODULE_AWB_CFG:
+		cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+		if (!cfg) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(cfg, up, sizeof(*cfg));
+		if (!ret)
+			ret = og02b10_ioctl(sd, cmd, cfg);
+		else
+			ret = -EFAULT;
+		kfree(cfg);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = og02b10_ioctl(sd, cmd, hdr);
+		if (!ret) {
+			ret = copy_to_user(up, hdr, sizeof(*hdr));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(hdr);
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(hdr, up, sizeof(*hdr));
+		if (!ret)
+			ret = og02b10_ioctl(sd, cmd, hdr);
+		else
+			ret = -EFAULT;
+		kfree(hdr);
+		break;
+	case PREISP_CMD_SET_HDRAE_EXP:
+		hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
+		if (!hdrae) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(hdrae, up, sizeof(*hdrae));
+		if (!ret)
+			ret = og02b10_ioctl(sd, cmd, hdrae);
+		else
+			ret = -EFAULT;
+		kfree(hdrae);
+		break;
+	case RKMODULE_SET_CONVERSION_GAIN:
+		ret = copy_from_user(&cg, up, sizeof(cg));
+		if (!ret)
+			ret = og02b10_ioctl(sd, cmd, &cg);
+		else
+			ret = -EFAULT;
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		ret = copy_from_user(&stream, up, sizeof(u32));
+		if (!ret)
+			ret = og02b10_ioctl(sd, cmd, &stream);
+		else
+			ret = -EFAULT;
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+#endif
+
+static int __og02b10_start_stream(struct og02b10 *og02b10)
+{
+	int ret;
+
+	ret = og02b10_write_array(og02b10->client, og02b10->cur_mode->reg_list);
+	if (ret)
+		return ret;
+
+	/* In case these controls are set before streaming */
+	ret = __v4l2_ctrl_handler_setup(&og02b10->ctrl_handler);
+	if (ret)
+		return ret;
+
+	usleep_range(1000, 5000);
+
+	if (!og02b10->slave_mode)
+		ret = og02b10_write_reg(og02b10->client,
+					OG02B10_REG_CTRL_MODE,
+					OG02B10_MODE_STREAMING);
+
+	return ret;
+}
+
+static int __og02b10_stop_stream(struct og02b10 *og02b10)
+{
+	og02b10->has_init_exp = false;
+	og02b10->slave_mode = false;
+	return og02b10_write_reg(og02b10->client, OG02B10_REG_CTRL_MODE, OG02B10_MODE_SW_STANDBY);
+}
+
+static int og02b10_s_stream(struct v4l2_subdev *sd, int on)
+{
+	struct og02b10 *og02b10 = to_og02b10(sd);
+	struct i2c_client *client = og02b10->client;
+	int ret = 0;
+
+	mutex_lock(&og02b10->mutex);
+	on = !!on;
+	if (on == og02b10->streaming)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			v4l2_err(sd, "pm runtime get sync failed\n");
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		ret = __og02b10_start_stream(og02b10);
+		if (ret) {
+			v4l2_err(sd, "start stream failed while write regs\n");
+			pm_runtime_put(&client->dev);
+			goto unlock_and_return;
+		}
+	} else {
+		__og02b10_stop_stream(og02b10);
+		pm_runtime_put(&client->dev);
+	}
+
+	og02b10->streaming = on;
+
+unlock_and_return:
+	mutex_unlock(&og02b10->mutex);
+
+	return ret;
+}
+
+static int og02b10_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct og02b10 *og02b10 = to_og02b10(sd);
+	struct i2c_client *client = og02b10->client;
+	int ret = 0;
+
+	mutex_lock(&og02b10->mutex);
+
+	/* If the power state is not modified - no work to do. */
+	if (og02b10->power_on == !!on)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		usleep_range(100, 200);
+
+		og02b10->power_on = true;
+	} else {
+		pm_runtime_put(&client->dev);
+		og02b10->power_on = false;
+	}
+
+unlock_and_return:
+	mutex_unlock(&og02b10->mutex);
+
+	return ret;
+}
+
+static int __og02b10_power_on(struct og02b10 *og02b10)
+{
+	int ret = 0;
+	struct device *dev = &og02b10->client->dev;
+
+	ret = clk_set_rate(og02b10->xvclk, OG02B10_XVCLK_FREQ);
+	if (ret < 0)
+		dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
+	if (clk_get_rate(og02b10->xvclk) != OG02B10_XVCLK_FREQ)
+		dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
+	ret = clk_prepare_enable(og02b10->xvclk);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable xvclk\n");
+		return ret;
+	}
+
+	ret = regulator_bulk_enable(OG02B10_NUM_SUPPLIES, og02b10->supplies);
+	if (ret < 0)
+		dev_err(dev, "Failed to enable regulators\n");
+
+	if (!IS_ERR(og02b10->pwdn_gpio)) {
+		ret = gpiod_direction_output(og02b10->pwdn_gpio, 1);
+		if (ret < 0)
+			dev_err(dev, "Failed to set pwdn gpio\n");
+		usleep_range(3000, 5000);
+	}
+
+	if (!IS_ERR(og02b10->reset_gpio)) {
+		ret = gpiod_direction_output(og02b10->reset_gpio, 1);
+		if (ret < 0)
+			dev_err(dev, "Failed to set reset gpio\n");
+		usleep_range(3000, 5000);
+	}
+
+	return ret;
+}
+
+static void __og02b10_power_off(struct og02b10 *og02b10)
+{
+	struct device *dev = &og02b10->client->dev;
+	int ret = 0;
+
+	if (!IS_ERR(og02b10->reset_gpio)) {
+		ret = gpiod_direction_output(og02b10->reset_gpio, 0);
+		if (ret < 0)
+			dev_err(dev, "Failed to set reset gpio\n");
+		usleep_range(500, 1000);
+	}
+	if (!IS_ERR(og02b10->pwdn_gpio)) {
+		ret = gpiod_direction_output(og02b10->pwdn_gpio, 0);
+		if (ret < 0)
+			dev_err(dev, "Failed to set pwdn gpio\n");
+		usleep_range(500, 1000);
+	}
+	clk_disable_unprepare(og02b10->xvclk);
+	regulator_bulk_disable(OG02B10_NUM_SUPPLIES, og02b10->supplies);
+}
+
+static int og02b10_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct og02b10 *og02b10 = to_og02b10(sd);
+
+	return __og02b10_power_on(og02b10);
+}
+
+static int og02b10_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct og02b10 *og02b10 = to_og02b10(sd);
+
+	__og02b10_power_off(og02b10);
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int og02b10_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct og02b10 *og02b10 = to_og02b10(sd);
+	struct v4l2_mbus_framefmt *try_fmt =
+		v4l2_subdev_get_try_format(sd, fh->pad, 0);
+	const struct og02b10_mode *def_mode = &supported_modes[0];
+
+	mutex_lock(&og02b10->mutex);
+	/* Initialize try_fmt */
+	try_fmt->width = def_mode->width;
+	try_fmt->height = def_mode->height;
+	try_fmt->code = def_mode->bus_fmt;
+	try_fmt->field = V4L2_FIELD_NONE;
+
+	mutex_unlock(&og02b10->mutex);
+	/* No crop or compose */
+
+	return 0;
+}
+#endif
+
+static int og02b10_enum_frame_interval(struct v4l2_subdev *sd,
+				       struct v4l2_subdev_pad_config *cfg,
+				       struct v4l2_subdev_frame_interval_enum *fie)
+{
+	struct og02b10 *og02b10 = to_og02b10(sd);
+
+	if (fie->index >= og02b10->cfg_num)
+		return -EINVAL;
+
+	fie->code = supported_modes[fie->index].bus_fmt;
+	fie->width = supported_modes[fie->index].width;
+	fie->height = supported_modes[fie->index].height;
+	fie->interval = supported_modes[fie->index].max_fps;
+	fie->reserved[0] = supported_modes[fie->index].hdr_mode;
+	return 0;
+}
+
+static const struct dev_pm_ops og02b10_pm_ops = {
+	SET_RUNTIME_PM_OPS(og02b10_runtime_suspend,
+			   og02b10_runtime_resume, NULL)
+};
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static const struct v4l2_subdev_internal_ops og02b10_internal_ops = {
+	.open = og02b10_open,
+};
+#endif
+
+static const struct v4l2_subdev_core_ops og02b10_core_ops = {
+	.s_power = og02b10_s_power,
+	.ioctl = og02b10_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl32 = og02b10_compat_ioctl32,
+#endif
+};
+
+static const struct v4l2_subdev_video_ops og02b10_video_ops = {
+	.s_stream = og02b10_s_stream,
+	.g_frame_interval = og02b10_g_frame_interval,
+};
+
+static const struct v4l2_subdev_pad_ops og02b10_pad_ops = {
+	.enum_mbus_code = og02b10_enum_mbus_code,
+	.enum_frame_size = og02b10_enum_frame_sizes,
+	.enum_frame_interval = og02b10_enum_frame_interval,
+	.get_fmt = og02b10_get_fmt,
+	.set_fmt = og02b10_set_fmt,
+	.get_mbus_config = og02b10_g_mbus_config,
+};
+
+static const struct v4l2_subdev_ops og02b10_subdev_ops = {
+	.core = &og02b10_core_ops,
+	.video = &og02b10_video_ops,
+	.pad = &og02b10_pad_ops,
+};
+
+static int og02b10_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct og02b10 *og02b10 = container_of(ctrl->handler,
+			 struct og02b10, ctrl_handler);
+	struct i2c_client *client = og02b10->client;
+	int ret = 0;
+	u8 again = 0, dgain = 1;
+	u8 again_fin = 0, dgain_fin_l = 0, dgain_fin_h = 0;
+	u32 dgain_fin = 0;
+
+	u16 vts_val = 0;
+	s64 max;
+
+	/* Propagate change of current control to all related controls */
+	switch (ctrl->id) {
+	case V4L2_CID_VBLANK:
+		/* Update max exposure while meeting expected vblanking */
+		max = og02b10->cur_mode->height + ctrl->val - 12;
+		__v4l2_ctrl_modify_range(og02b10->exposure,
+					 og02b10->exposure->minimum, max,
+					 og02b10->exposure->step,
+					 og02b10->exposure->default_value);
+		break;
+	}
+
+	dev_dbg(&client->dev, "set ctrl %#x\n", ctrl->id);
+	if (!pm_runtime_get_if_in_use(&client->dev)) {
+		dev_dbg(&client->dev, "powe is not on!!!!\n");
+		return 0;
+	}
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		ret = og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_GROUP_HOLD, OG02B10_GROUP0_HOLD_START);
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_EXP_H, (ctrl->val >> 8) & 0xFF);
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_EXP_L, ctrl->val & 0xFF);
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_GROUP_HOLD, OG02B10_GROUP0_HOLD_END);
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_GROUP_HOLD, OG02B10_GROUP_LAUNCH);
+		dev_dbg(&client->dev, "set exposure %#x(%d)\n", ctrl->val, ctrl->val);
+		break;
+	case V4L2_CID_ANALOGUE_GAIN:
+		/* val = again * dgain
+		 * again = 1 ~ 15.5
+		 * dgain = 1 ~ 3.98
+		 *
+		 * val = rounddown(again * dgain * 16 + 0.5)
+		 *
+		 * val:
+		 * 1 ~ 248     again: val / 16
+		 *	       dgain: 1
+		 * 248 ~ 988   again: 15.5
+		 *	       dgain: val / 248
+		 *
+		 * again_value	      again_fine_step_value
+		 * 1.0000 ~ 1.9375	  1/16
+		 * 2.000  ~ 3.875	  1/8
+		 * 4.00	  ~ 7.75	  1/4
+		 * 8.0	  ~ 15.5	  1/2
+		 *
+		 * dgain_value	      dgain_fine_step_value
+		 * 1 ~ 3.98		 1/1024
+		 */
+		if (ctrl->val > 248) {
+			again = 15;
+			again_fin = 1;
+
+			dgain = ctrl->val / 248;
+			dgain_fin = ((ctrl->val - dgain * 248) << 10) / 248;
+			dgain_fin_h = (dgain_fin >> 2) & 0xff;
+			dgain_fin_l = dgain_fin & 0x3;
+		} else {
+			again = ctrl->val >> 4;
+			if (again == 1)
+				again_fin = ctrl->val & 0xf;
+			else if (again >= 2 && again < 4)
+				again_fin = (ctrl->val & 0xf) >> 1;
+			else if (again >= 4 && again < 8)
+				again_fin = (ctrl->val & 0xf) >> 2;
+			else if (again >= 8)
+				again_fin = (ctrl->val & 0xf) >> 3;
+
+			dgain = 1;
+			dgain_fin_l = 0;
+			dgain_fin_h = 0;
+		}
+
+		ret = og02b10_write_reg(og02b10->client,
+					OG02B10_REG_GROUP_HOLD, OG02B10_GROUP0_HOLD_START);
+
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_AGAIN_COARSE, again);
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_AGAIN_FINE, (again_fin << 4));
+
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_DGAIN_COARSE, dgain);
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_DGAIN_FINE_H, dgain_fin_h);
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_DGAIN_FINE_L, dgain_fin_l);
+
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_GROUP_HOLD, OG02B10_GROUP0_HOLD_END);
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_GROUP_HOLD, OG02B10_GROUP_LAUNCH);
+
+		dev_dbg(&client->dev,
+			"set gain %#x, again = %#x(%u), again fine = %#x(%u), dgain = %#x(%u), dgain fine = %#x(%u)\n",
+			ctrl->val, again, again, again_fin, again_fin,
+			dgain, dgain, dgain_fin, dgain_fin);
+		break;
+	case V4L2_CID_VBLANK:
+		vts_val = og02b10->cur_mode->height + ctrl->val;
+		ret = og02b10_write_reg(og02b10->client,
+					OG02B10_REG_GROUP_HOLD, OG02B10_GROUP0_HOLD_START);
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_VTS_H, (vts_val >> 8) & 0xFF);
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_VTS_L, vts_val & 0xFF);
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_GROUP_HOLD, OG02B10_GROUP0_HOLD_END);
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_GROUP_HOLD, OG02B10_GROUP_LAUNCH);
+		dev_dbg(&client->dev, "set vblank %#x\n", vts_val);
+		break;
+	case V4L2_CID_TEST_PATTERN:
+		if (ctrl->val)
+			ret = og02b10_write_reg(og02b10->client,
+						OG02B10_REG_TEST_PATTERN,
+						OG02B10_TEST_PATTERN_ENABLE_VAL);
+		else
+			ret = og02b10_write_reg(og02b10->client,
+						OG02B10_REG_TEST_PATTERN,
+						OG02B10_TEST_PATTERN_DISABLE_VAL);
+		dev_dbg(&client->dev, "set test pattern %#x\n", ctrl->val);
+		break;
+	case V4L2_CID_HFLIP:
+		if (ctrl->val) {
+			ret = og02b10_write_reg(og02b10->client,
+						OG02B10_REG_MIRROR, OG02B10_MIRROR_ENABLE_VAL);
+		} else {
+			ret = og02b10_write_reg(og02b10->client,
+						OG02B10_REG_MIRROR, OG02B10_MIRROR_DISABLE_VAL);
+		}
+		dev_dbg(&client->dev, "set mirror %#x\n", ctrl->val);
+		break;
+	case V4L2_CID_VFLIP:
+		if (ctrl->val) {
+			ret = og02b10_write_reg(og02b10->client,
+						OG02B10_REG_FILP, OG02B10_FILP_ENABLE_VAL);
+		} else {
+			ret = og02b10_write_reg(og02b10->client,
+						OG02B10_REG_FILP, OG02B10_FILP_DISABLE_VAL);
+		}
+		dev_dbg(&client->dev, "set flip %#x\n", ctrl->val);
+		break;
+	case V4L2_CID_OG_LOW_POWER_MODE:
+		/* slave mode
+		 * C0 3006 00 02 ;disable FSIN output, bit operation, set 0x3006[1]=0
+		 * C0 303F 01 ;r_frame_on_num. (active frames after wake-up)
+		 * C0 31FF 00 ;Change to Clockless SCCB
+		 * C0 0100 00
+		 * ;FSIN trigger wake => active certain frames => sleep
+		 * C0 3030 10
+		 * C0 3030 84
+		 */
+		ret = og02b10_write_reg(og02b10->client,
+					OG02B10_REG_GROUP_HOLD,
+					OG02B10_GROUP0_HOLD_START);
+
+		if (ctrl->val == EXTERNAL_TRIGGER_MODE) {
+			if (!og02b10->slave_mode) {
+				ret |= og02b10_write_reg(og02b10->client,
+							 OG02B10_REG_IO_PAD_OUT_EN,
+							 OG02B10_IO_PAD_OUT_EN_DEFAULT &
+							 (~OG02B10_FSIN_OUTPUT_ENABLE));
+				ret |= og02b10_write_reg(og02b10->client,
+							 OG02B10_REG_R_FRAME_ON_NUM, 0x1);
+				ret |= og02b10_write_reg(og02b10->client,
+							 OG02B10_REG_SCCB_SEL,
+							 OG02B10_CLOCKLESS_SCCB);
+
+				if (og02b10->streaming) {
+					ret |= og02b10_write_reg(og02b10->client,
+								 OG02B10_REG_CTRL_MODE,
+								 OG02B10_MODE_SW_STANDBY);
+				}
+
+				// FSIN trigger wake => active certain frames => sleep
+				ret |= og02b10_write_reg(og02b10->client,
+							 OG02B10_REG_LOW_POWER_MODE_CTRL,
+							 OG02B10_LOW_FRAME_RATE_VAL);
+				ret |= og02b10_write_reg(og02b10->client,
+							 OG02B10_REG_LOW_POWER_MODE_CTRL,
+							 OG02B10_EXTERNAL_TRIGGER_VAL | 0x80);
+				if (ret == 0)
+					og02b10->slave_mode = true;
+			}
+		} else if (ctrl->val == LOW_POWER_MODE_DISABLE) {
+			if (og02b10->slave_mode) {
+				ret |= og02b10_write_reg(og02b10->client,
+							 OG02B10_REG_IO_PAD_OUT_EN,
+							 OG02B10_IO_PAD_OUT_EN_DEFAULT);
+				ret |= og02b10_write_reg(og02b10->client,
+							 OG02B10_REG_R_FRAME_ON_NUM, 0x3);
+				ret |= og02b10_write_reg(og02b10->client,
+							 OG02B10_REG_SCCB_SEL, 0x1);
+				if (ret == 0)
+					og02b10->slave_mode = false;
+			}
+		} else {
+			dev_warn(&client->dev, "Not support low power mode %#x\n", ctrl->val);
+		}
+
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_GROUP_HOLD, OG02B10_GROUP0_HOLD_END);
+		ret |= og02b10_write_reg(og02b10->client,
+					 OG02B10_REG_GROUP_HOLD, OG02B10_GROUP_LAUNCH);
+
+		dev_dbg(&client->dev, "set low power mode %#x\n", ctrl->val);
+		break;
+	default:
+		dev_warn(&client->dev, "%s Unhandled id: %#x, val :%#x\n",
+			 __func__, ctrl->id, ctrl->val);
+		break;
+	}
+
+	pm_runtime_put(&client->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops og02b10_ctrl_ops = {
+	.s_ctrl = og02b10_set_ctrl,
+};
+
+static const struct v4l2_ctrl_config og02b10_test_pattern_ctrl_cfg = {
+	.ops = &og02b10_ctrl_ops,
+	.id = V4L2_CID_TEST_PATTERN,
+	.name = "Test Pattern",
+	.type = V4L2_CTRL_TYPE_INTEGER,
+	.min = 0x0,
+	.max = 0x1,
+	.step = 0x1,
+	.def = 0x0,
+};
+
+static const struct v4l2_ctrl_config og02b10_low_power_mode_ctrl_cfg = {
+	.ops = &og02b10_ctrl_ops,
+	.id = V4L2_CID_OG_LOW_POWER_MODE,
+	.name = "low power mode",
+	.type = V4L2_CTRL_TYPE_INTEGER,
+	.min = LOW_POWER_MODE_DISABLE,
+	.max = LOW_POWER_MODE_MAX - 1,
+	.step = 0x1,
+	.def = LOW_POWER_MODE_DISABLE,
+};
+
+static int og02b10_initialize_controls(struct og02b10 *og02b10)
+{
+	const struct og02b10_mode *mode;
+	struct v4l2_ctrl_handler *handler;
+	s64 exposure_max, vblank_def;
+	u32 h_blank;
+	int ret;
+	u64 dst_link_freq = 0;
+	u64 dst_pixel_rate = 0;
+
+	handler = &og02b10->ctrl_handler;
+	mode = og02b10->cur_mode;
+	ret = v4l2_ctrl_handler_init(handler, 10);
+	if (ret)
+		return ret;
+	handler->lock = &og02b10->mutex;
+
+	og02b10->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
+						    V4L2_CID_LINK_FREQ,
+						    1, 0, link_freq_menu_items);
+
+	if (og02b10->cur_mode->bus_fmt == MEDIA_BUS_FMT_SBGGR10_1X10) {
+		dst_link_freq = 0;
+		dst_pixel_rate = PIXEL_RATE_WITH_400M;
+	}
+	/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
+	og02b10->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
+						V4L2_CID_PIXEL_RATE,
+						0, PIXEL_RATE_WITH_400M,
+						1, dst_pixel_rate);
+
+	__v4l2_ctrl_s_ctrl(og02b10->link_freq,
+			   dst_link_freq);
+
+	h_blank = mode->hts_def;
+	og02b10->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
+					    h_blank, h_blank, 1, h_blank);
+	if (og02b10->hblank)
+		og02b10->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	vblank_def = mode->vts_def - mode->height;
+	og02b10->vblank = v4l2_ctrl_new_std(handler, &og02b10_ctrl_ops,
+					    V4L2_CID_VBLANK, vblank_def,
+					    OG02B10_VTS_MAX - mode->height, 1, vblank_def);
+
+	exposure_max = mode->vts_def - 12;
+	og02b10->exposure = v4l2_ctrl_new_std(handler, &og02b10_ctrl_ops,
+					      V4L2_CID_EXPOSURE, OG02B10_EXPOSURE_MIN,
+					      exposure_max, OG02B10_EXPOSURE_STEP,
+					      mode->exp_def);
+
+	og02b10->anal_gain = v4l2_ctrl_new_std(handler, &og02b10_ctrl_ops,
+					       V4L2_CID_ANALOGUE_GAIN, OG02B10_GAIN_MIN,
+					       OG02B10_GAIN_MAX, OG02B10_GAIN_STEP,
+					       OG02B10_GAIN_DEFAULT);
+
+	og02b10->h_flip = v4l2_ctrl_new_std(handler, &og02b10_ctrl_ops,
+					    V4L2_CID_HFLIP, 0, 1, 1, 0);
+
+	og02b10->v_flip = v4l2_ctrl_new_std(handler, &og02b10_ctrl_ops,
+					    V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+	og02b10->test_pattern = v4l2_ctrl_new_custom(handler, &og02b10_test_pattern_ctrl_cfg, NULL);
+
+	og02b10->low_power_mode = v4l2_ctrl_new_custom(handler, &og02b10_low_power_mode_ctrl_cfg, NULL);
+	if (handler->error) {
+		ret = handler->error;
+		dev_err(&og02b10->client->dev,
+			"Failed to init controls(%d)\n", ret);
+		goto err_free_handler;
+	}
+
+	og02b10->subdev.ctrl_handler = handler;
+	og02b10->has_init_exp = false;
+	og02b10->slave_mode = false;
+
+	return 0;
+
+err_free_handler:
+	v4l2_ctrl_handler_free(handler);
+
+	return ret;
+}
+
+static int og02b10_check_sensor_id(struct og02b10 *og02b10,
+		  struct i2c_client *client)
+{
+	struct device *dev = &og02b10->client->dev;
+	u8 id0 = 0, id1 = 0, id2 = 0;
+	int ret;
+
+	ret = og02b10_read_reg(client, OG02B10_REG_SC_SCCB_ID0, &id0);
+	if (id0 != OG02B10_CHIP_ID0) {
+		dev_err(dev, "Unexpected sensor SCCB ID: id0(%06x), ret(%d)\n", id0, ret);
+		return -ENODEV;
+	}
+
+	ret = og02b10_read_reg(client, OG02B10_REG_SC_SCCB_ID1, &id1);
+	if (id1 != OG02B10_CHIP_ID1) {
+		dev_err(dev, "Unexpected sensor SCCB ID: id1(%06x), ret(%d)\n", id0, ret);
+		return -ENODEV;
+	}
+
+	ret = og02b10_read_reg(client, OG02B10_REG_SC_SCCB_ID2, &id2);
+	if (id2 != OG02B10_CHIP_ID2) {
+		dev_err(dev, "Unexpected sensor SCCB ID: id2(%06x), ret(%d)\n", id0, ret);
+		return -ENODEV;
+	}
+
+	dev_info(dev,
+		 "Detected OG02B10 sensor success, id0(%06x), id1(%06x), id2(%06x).\n",
+		 id0, id1, id2);
+	return 0;
+}
+
+static int og02b10_configure_regulators(struct og02b10 *og02b10)
+{
+	unsigned int i;
+
+	for (i = 0; i < OG02B10_NUM_SUPPLIES; i++)
+		og02b10->supplies[i].supply = OG02B10_supply_names[i];
+
+	return devm_regulator_bulk_get(&og02b10->client->dev,
+				       OG02B10_NUM_SUPPLIES,
+				       og02b10->supplies);
+}
+
+static int og02b10_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct device_node *node = dev->of_node;
+	struct og02b10 *og02b10;
+	struct v4l2_subdev *sd;
+	char facing[2];
+	int ret;
+	u32 i, hdr_mode = 0;
+
+	dev_info(dev, "driver version: %02x.%02x.%02x",
+		 DRIVER_VERSION >> 16,
+		 (DRIVER_VERSION & 0xff00) >> 8,
+		 DRIVER_VERSION & 0x00ff);
+
+	og02b10 = devm_kzalloc(dev, sizeof(*og02b10), GFP_KERNEL);
+	if (!og02b10)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
+				   &og02b10->module_index);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
+				       &og02b10->module_facing);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
+				       &og02b10->module_name);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
+				       &og02b10->len_name);
+	if (ret) {
+		dev_err(dev, "could not get module information!\n");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(node, OF_CAMERA_HDR_MODE,
+				   &hdr_mode);
+	if (ret) {
+		hdr_mode = NO_HDR;
+		dev_warn(dev, " Get hdr mode failed! no hdr default\n");
+	}
+
+	og02b10->cfg_num = ARRAY_SIZE(supported_modes);
+	for (i = 0; i < og02b10->cfg_num; i++) {
+		if (hdr_mode == supported_modes[i].hdr_mode) {
+			og02b10->cur_mode = &supported_modes[i];
+			break;
+		}
+	}
+	og02b10->client = client;
+	og02b10->xvclk = devm_clk_get(dev, "xvclk");
+	if (IS_ERR(og02b10->xvclk)) {
+		dev_err(dev, "Failed to get xvclk\n");
+		return -EINVAL;
+	}
+
+	og02b10->pinctrl = devm_pinctrl_get(dev);
+	if (!IS_ERR(og02b10->pinctrl)) {
+		og02b10->pins_default = pinctrl_lookup_state(og02b10->pinctrl,
+							     OF_CAMERA_PINCTRL_STATE_DEFAULT);
+		if (IS_ERR(og02b10->pins_default)) {
+			dev_err(dev, "could not get default pinstate\n");
+		} else {
+			ret = pinctrl_select_state(og02b10->pinctrl, og02b10->pins_default);
+			if (ret < 0)
+				dev_err(dev, "could not set default pins\n");
+		}
+
+		og02b10->pins_mclk = pinctrl_lookup_state(og02b10->pinctrl,
+							  OF_CAMERA_PINCTRL_STATE_MCLK);
+		if (IS_ERR(og02b10->pins_mclk)) {
+			dev_err(dev, "could not get mclk pinstate\n");
+		} else {
+			if (!IS_ERR_OR_NULL(og02b10->pins_mclk)) {
+				ret = pinctrl_select_state(og02b10->pinctrl, og02b10->pins_mclk);
+				if (ret < 0)
+					dev_err(dev, "could not set mclk pins\n");
+			}
+		}
+	} else {
+		dev_err(dev, "no pinctrl\n");
+	}
+
+	og02b10->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(og02b10->reset_gpio))
+		dev_warn(dev, "Failed to get reset-gpios\n");
+
+	og02b10->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
+	if (IS_ERR(og02b10->pwdn_gpio))
+		dev_warn(dev, "Failed to get pwdn-gpios\n");
+
+	ret = og02b10_configure_regulators(og02b10);
+	if (ret) {
+		dev_err(dev, "Failed to get power regulators\n");
+		return ret;
+	}
+
+	og02b10->slave_mode = false;
+	mutex_init(&og02b10->mutex);
+
+	sd = &og02b10->subdev;
+	v4l2_i2c_subdev_init(sd, client, &og02b10_subdev_ops);
+	ret = og02b10_initialize_controls(og02b10);
+	if (ret)
+		goto err_destroy_mutex;
+
+	ret = __og02b10_power_on(og02b10);
+	if (ret)
+		goto err_free_handler;
+
+	ret = og02b10_check_sensor_id(og02b10, client);
+	if (ret)
+		goto err_power_off;
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	sd->internal_ops = &og02b10_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+#endif
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	og02b10->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &og02b10->pad);
+	if (ret < 0) {
+		dev_err(dev, "media entity pads init failed.\n");
+		goto err_power_off;
+	}
+#endif
+
+	memset(facing, 0, sizeof(facing));
+	if (strcmp(og02b10->module_facing, "back") == 0)
+		facing[0] = 'b';
+	else
+		facing[0] = 'f';
+
+	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
+		 og02b10->module_index, facing,
+		 OG02B10_NAME, dev_name(sd->dev));
+	ret = v4l2_async_register_subdev_sensor_common(sd);
+	if (ret) {
+		dev_err(dev, "v4l2 async register subdev failed\n");
+		goto err_clean_entity;
+	}
+
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_idle(dev);
+
+	dev_info(dev, "probe success\n");
+	return 0;
+
+err_clean_entity:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+err_power_off:
+	__og02b10_power_off(og02b10);
+err_free_handler:
+	v4l2_ctrl_handler_free(&og02b10->ctrl_handler);
+err_destroy_mutex:
+	mutex_destroy(&og02b10->mutex);
+
+	return ret;
+}
+
+static int og02b10_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct og02b10 *og02b10 = to_og02b10(sd);
+
+	v4l2_async_unregister_subdev(sd);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+	v4l2_ctrl_handler_free(&og02b10->ctrl_handler);
+	mutex_destroy(&og02b10->mutex);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		__og02b10_power_off(og02b10);
+	pm_runtime_set_suspended(&client->dev);
+
+	return 0;
+}
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id og02b10_of_match[] = {
+	{ .compatible = "ovti,og02b10" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, og02b10_of_match);
+#endif
+
+static const struct i2c_device_id og02b10_match_id[] = {
+	{ "ovti,og02b10", 0 },
+	{ },
+};
+
+static struct i2c_driver og02b10_i2c_driver = {
+	.driver = {
+		.name = OG02B10_NAME,
+		.pm = &og02b10_pm_ops,
+		.of_match_table = of_match_ptr(og02b10_of_match),
+	},
+	.probe = &og02b10_probe,
+	.remove = &og02b10_remove,
+	.id_table = og02b10_match_id,
+};
+
+#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
+module_i2c_driver(og02b10_i2c_driver);
+#else
+static int __init sensor_mod_init(void)
+{
+	return i2c_add_driver(&og02b10_i2c_driver);
+}
+
+static void __exit sensor_mod_exit(void)
+{
+	i2c_del_driver(&og02b10_i2c_driver);
+}
+
+device_initcall_sync(sensor_mod_init);
+module_exit(sensor_mod_exit);
+#endif
+
+MODULE_DESCRIPTION("OmniVision og02b10 sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/os02k10.c b/kernel/drivers/media/i2c/os02k10.c
index 3988053..0a064cd 100644
--- a/kernel/drivers/media/i2c/os02k10.c
+++ b/kernel/drivers/media/i2c/os02k10.c
@@ -47,7 +47,7 @@
 
 #define OS02K10_XVCLK_FREQ		24000000
 
-#define CHIP_ID				0x530243
+#define CHIP_ID				0x005302
 #define OS02K10_REG_CHIP_ID		0x300a
 
 #define OS02K10_REG_CTRL_MODE		0x0100
@@ -1806,6 +1806,7 @@
 	s64 max;
 	int ret = 0;
 	u32 val = 0;
+	u32 reg_data;
 
 	/* Propagate change of current control to all related controls */
 	switch (ctrl->id) {
@@ -1835,23 +1836,53 @@
 		}
 		break;
 	case V4L2_CID_ANALOGUE_GAIN:
+		/*
+		 * dgain reg format is 4.10bits, again reg format is 4.4bits
+		 * 1x is 64, 6 decimal places
+		 */
 		if (ctrl->val > 992) {
-			dgain = ctrl->val * 1024 / 992;
+			dgain = ctrl->val * 1024 / 992;	//15.5X * 64 = 992
 			again = 992;
 		} else {
-			dgain = 1024;
+			dgain = 1024;	//move 10 bits left
 			again = ctrl->val;
 		}
 		dev_dbg(&client->dev, "gain %d, ag 0x%x, dg 0x%x\n",
 			ctrl->val, again, dgain);
-		ret = os02k10_write_reg(os02k10->client,
+
+		ret |= os02k10_read_reg(os02k10->client, OS02K10_AEC_LONG_REL_GAIN_REG_H,
+			       OS02K10_REG_VALUE_08BIT, &reg_data);
+		reg_data = reg_data & 0xf0;
+		ret |= os02k10_write_reg(os02k10->client,
 					OS02K10_AEC_LONG_REL_GAIN_REG_H,
-					OS02K10_REG_VALUE_16BIT,
-					(again << 2) & 0xff0);
+					OS02K10_REG_VALUE_08BIT,
+					((again >> 6) & 0x0f) | reg_data);
+		ret |= os02k10_read_reg(os02k10->client, OS02K10_AEC_LONG_REL_GAIN_REG_L,
+			       OS02K10_REG_VALUE_08BIT, &reg_data);
+		reg_data = reg_data & 0x0f;
+		ret |= os02k10_write_reg(os02k10->client,
+					OS02K10_AEC_LONG_REL_GAIN_REG_L,
+					OS02K10_REG_VALUE_08BIT,
+					(((again >> 2) & 0x0f) << 4) | reg_data);
+
+		ret |= os02k10_read_reg(os02k10->client, OS02K10_AEC_LONG_DIG_GAIN_REG_H,
+			       OS02K10_REG_VALUE_08BIT, &reg_data);
+		reg_data = reg_data & 0xf0;
 		ret |= os02k10_write_reg(os02k10->client,
 					 OS02K10_AEC_LONG_DIG_GAIN_REG_H,
-					 OS02K10_REG_VALUE_24BIT,
-					 (dgain << 6) & 0xfffc0);
+					 OS02K10_REG_VALUE_08BIT,
+					 ((dgain >> 10) & 0x0f) | reg_data);
+		ret |= os02k10_write_reg(os02k10->client,
+					 OS02K10_AEC_LONG_DIG_GAIN_REG_M,
+					 OS02K10_REG_VALUE_08BIT,
+					 (dgain >> 2) & 0xff);
+		ret |= os02k10_read_reg(os02k10->client, OS02K10_AEC_LONG_DIG_GAIN_REG_L,
+			       OS02K10_REG_VALUE_08BIT, &reg_data);
+		reg_data = reg_data & 0x3f;
+		ret |= os02k10_write_reg(os02k10->client,
+					 OS02K10_AEC_LONG_DIG_GAIN_REG_L,
+					 OS02K10_REG_VALUE_08BIT,
+					 ((dgain & 0x03) << 6) | reg_data);
 		break;
 	case V4L2_CID_VBLANK:
 		dev_dbg(&client->dev, "set blank value 0x%x\n", ctrl->val);
@@ -2095,11 +2126,11 @@
 		return -EINVAL;
 	}
 
-	os02k10->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
+	os02k10->reset_gpio = devm_gpiod_get(dev, "reset", os02k10->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
 	if (IS_ERR(os02k10->reset_gpio))
 		dev_warn(dev, "Failed to get reset-gpios\n");
 
-	os02k10->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
+	os02k10->pwdn_gpio = devm_gpiod_get(dev, "pwdn", os02k10->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
 	if (IS_ERR(os02k10->pwdn_gpio))
 		dev_warn(dev, "Failed to get pwdn-gpios\n");
 
diff --git a/kernel/drivers/media/i2c/os04d10.c b/kernel/drivers/media/i2c/os04d10.c
new file mode 100644
index 0000000..e14b53d
--- /dev/null
+++ b/kernel/drivers/media/i2c/os04d10.c
@@ -0,0 +1,1510 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * os04d10 driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * V0.0X01.0X01 first version
+ */
+
+// #define DEBUG
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/rk-camera-module.h>
+#include <linux/rk-preisp.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <linux/pinctrl/consumer.h>
+#include "../platform/rockchip/isp/rkisp_tb_helper.h"
+
+#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x01)
+
+#ifndef V4L2_CID_DIGITAL_GAIN
+#define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
+#endif
+
+#define OS04D10_LANES			2
+#define OS04D10_BITS_PER_SAMPLE		10
+#define OS04D10_LINK_FREQ_360		360000000
+
+#define PIXEL_RATE_WITH_360M_10BIT	(OS04D10_LINK_FREQ_360 * 2 * \
+					OS04D10_LANES / OS04D10_BITS_PER_SAMPLE)
+#define OS04D10_XVCLK_FREQ		24000000
+
+#define OS04D10_REG_PAGE_SEL		0xfd
+#define OS04D10_REG_EXP_UPDATE		0x01
+
+#define OS04D10_REG_PAGE_SYS_CTRL	0
+#define OS04D10_REG_PAGE_CIS_TIMING	1
+#define OS04D10_REG_PAGE_ISP_MIPI	2
+#define OS04D10_REG_PAGE_DAC_CODE	3
+#define OS04D10_REG_PAGE_DPC_SRAM	4
+#define OS04D10_REG_PAGE_CIS_CTRL	5
+#define OS04D10_REG_PAGE_OTP_CTRL	6
+#define OS04D10_REG_PAGE_CIS_SRAM	7
+
+#define CHIP_ID				0x53044410
+#define OS04D10_REG_CHIP_ID		0x02
+
+#define OS04D10_REG_CTRL_MODE		0x20
+#define OS04D10_MODE_SW_STANDBY		0x01
+#define OS04D10_MODE_STREAMING		0x03
+
+#define OS04D10_REG_EXPOSURE_H		0x03
+#define OS04D10_REG_EXPOSURE_L		0x04
+#define	OS04D10_EXPOSURE_MIN		1
+#define	OS04D10_EXPOSURE_STEP		1
+#define OS04D10_VTS_MAX			0x7fff
+
+#define OS04D10_REG_DIG_GAIN_H		0x37
+#define OS04D10_REG_DIG_GAIN_L		0x39
+#define OS04D10_REG_ANA_GAIN		0x24
+#define OS04D10_GAIN_MIN		0x40
+#define OS04D10_GAIN_MAX		(31744)	//15.5 * 32 * 64
+#define OS04D10_GAIN_STEP		1
+#define OS04D10_GAIN_DEFAULT		0x40
+
+#define OS04D10_REG_TEST_PATTERN	0x0c
+#define OS04D10_TEST_PATTERN_BIT_MASK	0x01
+
+#define OS04D10_REG_VTS_H		0x05
+#define OS04D10_REG_VTS_L		0x06
+
+#define OS04D10_FLIP_MIRROR_REG		0x32
+
+#define OS04D10_FETCH_EXP_H(VAL)		(((VAL) >> 8) & 0xFF)
+#define OS04D10_FETCH_EXP_L(VAL)		((VAL) & 0xFF)
+
+#define OS04D10_FETCH_MIRROR(VAL, ENABLE)	(ENABLE ? VAL | 0x01 : VAL & 0xfe)
+#define OS04D10_FETCH_FLIP(VAL, ENABLE)		(ENABLE ? VAL | 0x02 : VAL & 0xfd)
+
+#define REG_DELAY			0xFE
+#define REG_NULL			0xFF
+
+#define OS04D10_REG_VALUE_08BIT		1
+#define OS04D10_REG_VALUE_16BIT		2
+#define OS04D10_REG_VALUE_24BIT		3
+#define OS04D10_REG_VALUE_32BIT		4
+
+#define OF_CAMERA_PINCTRL_STATE_DEFAULT	"rockchip,camera_default"
+#define OF_CAMERA_PINCTRL_STATE_SLEEP	"rockchip,camera_sleep"
+#define OS04D10_NAME			"os04d10"
+
+static const char * const os04d10_supply_names[] = {
+	"avdd",		/* Analog power */
+	"dovdd",	/* Digital I/O power */
+	"dvdd",		/* Digital core power */
+};
+
+#define OS04D10_NUM_SUPPLIES ARRAY_SIZE(os04d10_supply_names)
+
+struct regval {
+	u16 addr;
+	u8 val;
+};
+
+struct os04d10_mode {
+	u32 bus_fmt;
+	u32 width;
+	u32 height;
+	struct v4l2_fract max_fps;
+	u32 hts_def;
+	u32 vts_def;
+	u32 exp_def;
+	const struct regval *reg_list;
+	u32 hdr_mode;
+	u32 vc[PAD_MAX];
+};
+
+struct os04d10 {
+	struct i2c_client	*client;
+	struct clk		*xvclk;
+	struct gpio_desc	*reset_gpio;
+	struct regulator_bulk_data supplies[OS04D10_NUM_SUPPLIES];
+
+	struct pinctrl		*pinctrl;
+	struct pinctrl_state	*pins_default;
+	struct pinctrl_state	*pins_sleep;
+
+	struct v4l2_subdev	subdev;
+	struct media_pad	pad;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl	*exposure;
+	struct v4l2_ctrl	*anal_gain;
+	struct v4l2_ctrl	*digi_gain;
+	struct v4l2_ctrl	*hblank;
+	struct v4l2_ctrl	*vblank;
+	struct v4l2_ctrl	*test_pattern;
+	struct mutex		mutex;
+	struct v4l2_fract	cur_fps;
+	bool			streaming;
+	bool			power_on;
+	const struct os04d10_mode *cur_mode;
+	u32			module_index;
+	const char		*module_facing;
+	const char		*module_name;
+	const char		*len_name;
+	u32			cur_vts;
+	bool			has_init_exp;
+	bool			is_thunderboot;
+	bool			is_first_streamoff;
+	struct preisp_hdrae_exp_s init_hdrae_exp;
+};
+
+#define to_os04d10(sd) container_of(sd, struct os04d10, subdev)
+
+/*
+ * Xclk 24Mhz
+ */
+static const struct regval os04d10_global_regs[] = {
+	{REG_NULL, 0x00},
+};
+
+/*
+ * Xclk 24Mhz
+ * max_framerate 15fps
+ * mipi_datarate per lane 720Mbps, 2lane
+ */
+static const struct regval os04d10_linear_10_2568x1448_regs[] = {
+	{0xfd, 0x00},
+	{0x20, 0x00},
+	{0x20, 0x01},
+	{0x20, 0x01},
+	{0x20, 0x01},
+	{0x20, 0x01},
+	{0x41, 0xa8},
+	{0x45, 0x24},
+	{0x31, 0x20},
+	{0x38, 0x15},
+	{0xfd, 0x01},
+	{0x03, 0x00},
+	{0x04, 0x04},
+	{0x05, 0x05},
+	{0x06, 0xc3},
+	{0x24, 0xff},
+	{0x02, 0x01},
+	{0x42, 0x5a},
+	{0x47, 0x0c},
+	{0x45, 0x02},
+	{0x48, 0x0c},
+	{0x4b, 0x88},
+	{0xd4, 0x05},
+	{0xd5, 0xd2},
+	{0xd7, 0x05},
+	{0xd8, 0xd2},
+	{0x50, 0x01},
+	{0x51, 0x11},
+	{0x52, 0x18},
+	{0x53, 0x01},
+	{0x54, 0x01},
+	{0x55, 0x01},
+	{0x57, 0x08},
+	{0x5c, 0x40},
+	{0x7c, 0x06},
+	{0x7d, 0x05},
+	{0x7e, 0x05},
+	{0x7f, 0x05},
+	{0x90, 0x60},
+	{0x91, 0x0f},
+	{0x92, 0x35},
+	{0x93, 0x36},
+	{0x94, 0x0f},
+	{0x95, 0x7e},
+	{0x98, 0x5d},
+	{0xa8, 0x50},
+	{0xaa, 0x14},
+	{0xab, 0x05},
+	{0xac, 0x14},
+	{0xad, 0x05},
+	{0xae, 0x4a},
+	{0xaf, 0x0e},
+	{0xb2, 0x07},
+	{0xb3, 0x0c},
+	{0xc9, 0x28},
+	{0xca, 0x5e},
+	{0xcb, 0x5e},
+	{0xcc, 0x5e},
+	{0xcd, 0x5e},
+	{0xce, 0x5c},
+	{0xcf, 0x5c},
+	{0xd0, 0x5c},
+	{0xd1, 0x5c},
+	{0xd2, 0x7c},
+	{0xd3, 0x7c},
+	{0xdb, 0x0f},
+	{0xfd, 0x01},
+	{0x46, 0x77},
+	{0xdd, 0x00},
+	{0xde, 0x3f},
+	{0xfd, 0x03},
+	{0x2b, 0x0a},
+	{0x01, 0x22},
+	{0x02, 0x03},
+	{0x00, 0x06},
+	{0x2a, 0x22},
+	{0x29, 0x0b},
+	{0x1e, 0x10},
+	{0x1f, 0x02},
+	{0x1a, 0x24},
+	{0x1b, 0x62},
+	{0x1c, 0xce},
+	{0x1d, 0xd3},
+	{0x04, 0x0f},
+	{0x36, 0x00},
+	{0x37, 0x05},
+	{0x38, 0x09},
+	{0x39, 0x19},
+	{0x3a, 0x38},
+	{0x3b, 0x22},
+	{0x3c, 0x22},
+	{0x3d, 0x22},
+	{0x3e, 0x03},
+	{0xfd, 0x02},
+	{0xce, 0x65},
+	{0xfd, 0x03},
+	{0x03, 0x30},
+	{0x05, 0x00},
+	{0x12, 0x70},
+	{0x13, 0x70},
+	{0x16, 0x13},
+	{0x21, 0xca},
+	{0x27, 0x95},
+	{0x2c, 0x55},
+	{0x2d, 0x08},
+	{0x2e, 0xca},
+	{0x3f, 0xe7},
+	{0xfd, 0x00},
+	{0x8b, 0x01},
+	{0x8d, 0x00},
+	{0xfd, 0x01},
+	{0x01, 0x02},
+	{0xfd, 0x05},
+	{0xc4, 0x62},
+	{0xc5, 0x62},
+	{0xc6, 0x62},
+	{0xc7, 0x62},
+	{0xf0, 0x40},
+	{0xf1, 0x40},
+	{0xf2, 0x40},
+	{0xf3, 0x40},
+	{0xf4, 0x00},
+	{0xf9, 0x03},
+	{0xfa, 0x5d},
+	{0xfb, 0x6b},
+	{0xb1, 0x01},
+	{REG_NULL, 0x00},
+};
+
+static const struct os04d10_mode supported_modes[] = {
+	{
+		.width = 2568,
+		.height = 1448,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 150000,
+		},
+		.exp_def = 0x0080,
+		.hts_def = 0x05dc * 2,
+		.vts_def = 0xB83,
+		.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.reg_list = os04d10_linear_10_2568x1448_regs,
+		.hdr_mode = NO_HDR,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	}
+};
+
+static const s64 link_freq_menu_items[] = {
+	OS04D10_LINK_FREQ_360
+};
+
+static const char * const os04d10_test_pattern_menu[] = {
+	"Disabled",
+	"Vertical Color Bar Type 1",
+	"Vertical Color Bar Type 2",
+	"Vertical Color Bar Type 3",
+	"Vertical Color Bar Type 4"
+};
+
+/* Write registers up to 4 at a time */
+static int os04d10_write_reg(struct i2c_client *client, u8 reg, u8 val)
+{
+	struct i2c_msg msg;
+	u8 buf[2];
+	int ret;
+
+	buf[0] = reg & 0xFF;
+	buf[1] = val;
+
+	msg.addr = client->addr;
+	msg.flags = client->flags;
+	msg.buf = buf;
+	msg.len = sizeof(buf);
+
+	ret = i2c_transfer(client->adapter, &msg, 1);
+	if (ret >= 0)
+		return 0;
+
+	dev_err(&client->dev,
+		"os04d10 write reg(0x%x val:0x%x) failed !\n", reg, val);
+
+	return ret;
+}
+
+static int os04d10_write_array(struct i2c_client *client,
+			       const struct regval *regs)
+{
+	u32 i;
+	int ret = 0;
+
+	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++)
+		ret = os04d10_write_reg(client, regs[i].addr, regs[i].val);
+
+	return ret;
+}
+
+/* Read registers up to 4 at a time */
+static int os04d10_read_reg(struct i2c_client *client, u8 reg, u8 *val)
+{
+	struct i2c_msg msg[2];
+	u8 buf[1];
+	int ret;
+
+	buf[0] = reg & 0xFF;
+
+	msg[0].addr = client->addr;
+	msg[0].flags = client->flags;
+	msg[0].buf = buf;
+	msg[0].len = sizeof(buf);
+
+	msg[1].addr = client->addr;
+	msg[1].flags = client->flags | I2C_M_RD;
+	msg[1].buf = buf;
+	msg[1].len = 1;
+
+	ret = i2c_transfer(client->adapter, msg, 2);
+	if (ret >= 0) {
+		*val = buf[0];
+		return 0;
+	}
+
+	dev_err(&client->dev,
+		"os04d10 read reg:0x%x failed !\n", reg);
+
+	return ret;
+}
+
+static int os04d10_set_gain_reg(struct os04d10 *os04d10, u32 gain)
+{
+	struct i2c_client *client = os04d10->client;
+	u32 again = 0, dgain = 0;
+	int ret = 0;
+
+	/* again max is 15.5 gain convert thread is 15.5 * 1 * 64 = 992*/
+	if (gain < OS04D10_GAIN_MIN) {
+		again = 0x10;
+		dgain = 0x0040;
+	} else if (gain < 992) {
+		again = gain >> 2;
+		dgain = 0x0040;
+	} else if (gain < OS04D10_GAIN_MAX) {
+		again = 0xF8;
+		dgain = gain * 64 / 992;
+	} else {
+		again = 0xF8;
+		dgain = 0x07ff;
+	}
+
+	dev_dbg(&client->dev, "again: 0x%04x dgain: 0x%08x\n", again, dgain);
+	ret = os04d10_write_reg(os04d10->client, OS04D10_REG_PAGE_SEL, OS04D10_REG_PAGE_CIS_TIMING);
+	ret |= os04d10_write_reg(os04d10->client,
+				 OS04D10_REG_ANA_GAIN,
+				 again);
+	ret |= os04d10_write_reg(os04d10->client, OS04D10_REG_EXP_UPDATE, 0x01);
+	ret |= os04d10_write_reg(os04d10->client, OS04D10_REG_PAGE_SEL, OS04D10_REG_PAGE_CIS_CTRL);
+	ret |= os04d10_write_reg(os04d10->client,
+				 OS04D10_REG_DIG_GAIN_H,
+				 (dgain >> 8) & 0xff);
+	ret |= os04d10_write_reg(os04d10->client,
+				 OS04D10_REG_DIG_GAIN_L,
+				 dgain & 0xff);
+	ret |= os04d10_write_reg(os04d10->client, OS04D10_REG_EXP_UPDATE, 0x01);
+
+	return ret;
+}
+
+static int os04d10_get_reso_dist(const struct os04d10_mode *mode,
+				 struct v4l2_mbus_framefmt *framefmt)
+{
+	return abs(mode->width - framefmt->width) +
+	       abs(mode->height - framefmt->height);
+}
+
+static const struct os04d10_mode *
+os04d10_find_best_fit(struct v4l2_subdev_format *fmt)
+{
+	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
+	int dist;
+	int cur_best_fit = 0;
+	int cur_best_fit_dist = -1;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+		dist = os04d10_get_reso_dist(&supported_modes[i], framefmt);
+		if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
+			cur_best_fit_dist = dist;
+			cur_best_fit = i;
+		}
+	}
+
+	return &supported_modes[cur_best_fit];
+}
+
+static int os04d10_set_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct os04d10 *os04d10 = to_os04d10(sd);
+	const struct os04d10_mode *mode;
+	s64 h_blank, vblank_def;
+
+	mutex_lock(&os04d10->mutex);
+
+	mode = os04d10_find_best_fit(fmt);
+	fmt->format.code = mode->bus_fmt;
+	fmt->format.width = mode->width;
+	fmt->format.height = mode->height;
+	fmt->format.field = V4L2_FIELD_NONE;
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+#else
+		mutex_unlock(&os04d10->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		os04d10->cur_mode = mode;
+		h_blank = mode->hts_def - mode->width;
+		__v4l2_ctrl_modify_range(os04d10->hblank, h_blank,
+					 h_blank, 1, h_blank);
+		vblank_def = mode->vts_def - mode->height;
+		__v4l2_ctrl_modify_range(os04d10->vblank, vblank_def,
+					 OS04D10_VTS_MAX - mode->height,
+					 1, vblank_def);
+		os04d10->cur_fps = mode->max_fps;
+	}
+
+	mutex_unlock(&os04d10->mutex);
+
+	return 0;
+}
+
+static int os04d10_get_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct os04d10 *os04d10 = to_os04d10(sd);
+	const struct os04d10_mode *mode = os04d10->cur_mode;
+
+	mutex_lock(&os04d10->mutex);
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+#else
+		mutex_unlock(&os04d10->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		fmt->format.width = mode->width;
+		fmt->format.height = mode->height;
+		fmt->format.code = mode->bus_fmt;
+		fmt->format.field = V4L2_FIELD_NONE;
+		/* format info: width/height/data type/virctual channel */
+		if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
+			fmt->reserved[0] = mode->vc[fmt->pad];
+		else
+			fmt->reserved[0] = mode->vc[PAD0];
+	}
+	mutex_unlock(&os04d10->mutex);
+
+	return 0;
+}
+
+static int os04d10_enum_mbus_code(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_pad_config *cfg,
+				  struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct os04d10 *os04d10 = to_os04d10(sd);
+
+	if (code->index != 0)
+		return -EINVAL;
+	code->code = os04d10->cur_mode->bus_fmt;
+
+	return 0;
+}
+
+static int os04d10_enum_frame_sizes(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_pad_config *cfg,
+				    struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	if (fse->code != supported_modes[0].bus_fmt)
+		return -EINVAL;
+
+	fse->min_width  = supported_modes[fse->index].width;
+	fse->max_width  = supported_modes[fse->index].width;
+	fse->max_height = supported_modes[fse->index].height;
+	fse->min_height = supported_modes[fse->index].height;
+
+	return 0;
+}
+
+static int os04d10_enable_test_pattern(struct os04d10 *os04d10, u32 pattern)
+{
+	u8 val = 0;
+	int ret = 0;
+
+	ret = os04d10_write_reg(os04d10->client,
+				OS04D10_REG_PAGE_SEL,
+				OS04D10_REG_PAGE_CIS_CTRL);
+	ret |= os04d10_read_reg(os04d10->client, OS04D10_REG_TEST_PATTERN, &val);
+	if (pattern)
+		val |= OS04D10_TEST_PATTERN_BIT_MASK;
+	else
+		val &= ~OS04D10_TEST_PATTERN_BIT_MASK;
+
+	ret |= os04d10_write_reg(os04d10->client, OS04D10_REG_TEST_PATTERN, val);
+	return ret;
+}
+
+static int os04d10_g_frame_interval(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_frame_interval *fi)
+{
+	struct os04d10 *os04d10 = to_os04d10(sd);
+	const struct os04d10_mode *mode = os04d10->cur_mode;
+
+	if (os04d10->streaming)
+		fi->interval = os04d10->cur_fps;
+	else
+		fi->interval = mode->max_fps;
+
+	return 0;
+}
+
+static int os04d10_g_mbus_config(struct v4l2_subdev *sd,
+				unsigned int pad_id,
+				struct v4l2_mbus_config *config)
+{
+	struct os04d10 *os04d10 = to_os04d10(sd);
+	const struct os04d10_mode *mode = os04d10->cur_mode;
+
+	u32 val = 1 << (OS04D10_LANES - 1) |
+		V4L2_MBUS_CSI2_CHANNEL_0 |
+		V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+
+	if (mode->hdr_mode != NO_HDR)
+		val |= V4L2_MBUS_CSI2_CHANNEL_1;
+	if (mode->hdr_mode == HDR_X3)
+		val |= V4L2_MBUS_CSI2_CHANNEL_2;
+
+	config->type = V4L2_MBUS_CSI2_DPHY;
+	config->flags = val;
+
+	return 0;
+}
+
+static void os04d10_get_module_inf(struct os04d10 *os04d10,
+				   struct rkmodule_inf *inf)
+{
+	memset(inf, 0, sizeof(*inf));
+	strscpy(inf->base.sensor, OS04D10_NAME, sizeof(inf->base.sensor));
+	strscpy(inf->base.module, os04d10->module_name,
+		sizeof(inf->base.module));
+	strscpy(inf->base.lens, os04d10->len_name, sizeof(inf->base.lens));
+}
+
+static long os04d10_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	struct os04d10 *os04d10 = to_os04d10(sd);
+	struct rkmodule_hdr_cfg *hdr;
+	long ret = 0;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		os04d10_get_module_inf(os04d10, (struct rkmodule_inf *)arg);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr = (struct rkmodule_hdr_cfg *)arg;
+		hdr->esp.mode = HDR_NORMAL_VC;
+		hdr->hdr_mode = os04d10->cur_mode->hdr_mode;
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		break;
+	case PREISP_CMD_SET_HDRAE_EXP:
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+
+		stream = *((u32 *)arg);
+
+		if (stream)
+			ret = os04d10_write_reg(os04d10->client,
+						OS04D10_REG_CTRL_MODE,
+						OS04D10_MODE_STREAMING);
+		else
+			ret = os04d10_write_reg(os04d10->client,
+						OS04D10_REG_CTRL_MODE,
+						OS04D10_MODE_SW_STANDBY);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long os04d10_compat_ioctl32(struct v4l2_subdev *sd,
+				   unsigned int cmd, unsigned long arg)
+{
+	void __user *up = compat_ptr(arg);
+	struct rkmodule_inf *inf;
+	struct rkmodule_hdr_cfg *hdr;
+	long ret = 0;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
+		if (!inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = os04d10_ioctl(sd, cmd, inf);
+		if (!ret) {
+			if (copy_to_user(up, inf, sizeof(*inf)))
+				ret = -EFAULT;
+		}
+		kfree(inf);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = os04d10_ioctl(sd, cmd, hdr);
+		if (!ret) {
+			if (copy_to_user(up, hdr, sizeof(*hdr)))
+				ret = -EFAULT;
+		}
+		kfree(hdr);
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		break;
+	case PREISP_CMD_SET_HDRAE_EXP:
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		ret = copy_from_user(&stream, up, sizeof(u32));
+		if (!ret)
+			ret = os04d10_ioctl(sd, cmd, &stream);
+		else
+			ret = -EFAULT;
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+#endif
+
+static int __os04d10_start_stream(struct os04d10 *os04d10)
+{
+	int ret;
+
+	if (!os04d10->is_thunderboot) {
+		ret = os04d10_write_array(os04d10->client, os04d10->cur_mode->reg_list);
+		if (ret)
+			return ret;
+		/* In case these controls are set before streaming */
+		ret = __v4l2_ctrl_handler_setup(&os04d10->ctrl_handler);
+		if (ret)
+			return ret;
+		if (os04d10->has_init_exp && os04d10->cur_mode->hdr_mode != NO_HDR) {
+			ret = os04d10_ioctl(&os04d10->subdev, PREISP_CMD_SET_HDRAE_EXP,
+				&os04d10->init_hdrae_exp);
+			if (ret) {
+				dev_err(&os04d10->client->dev,
+					"init exp fail in hdr mode\n");
+				return ret;
+			}
+		}
+	}
+
+	os04d10_write_reg(os04d10->client, OS04D10_REG_PAGE_SEL, OS04D10_REG_PAGE_SYS_CTRL);
+	return os04d10_write_reg(os04d10->client, OS04D10_REG_CTRL_MODE, OS04D10_MODE_STREAMING);
+}
+
+static int __os04d10_stop_stream(struct os04d10 *os04d10)
+{
+	os04d10->has_init_exp = false;
+	if (os04d10->is_thunderboot) {
+		os04d10->is_first_streamoff = true;
+		pm_runtime_put(&os04d10->client->dev);
+	}
+
+	os04d10_write_reg(os04d10->client, OS04D10_REG_PAGE_SEL, OS04D10_REG_PAGE_SYS_CTRL);
+	return os04d10_write_reg(os04d10->client, OS04D10_REG_CTRL_MODE, OS04D10_MODE_SW_STANDBY);
+}
+
+static int __os04d10_power_on(struct os04d10 *os04d10);
+static int os04d10_s_stream(struct v4l2_subdev *sd, int on)
+{
+	struct os04d10 *os04d10 = to_os04d10(sd);
+	struct i2c_client *client = os04d10->client;
+	int ret = 0;
+
+	mutex_lock(&os04d10->mutex);
+	on = !!on;
+	if (on == os04d10->streaming)
+		goto unlock_and_return;
+	if (on) {
+		if (os04d10->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
+			os04d10->is_thunderboot = false;
+			__os04d10_power_on(os04d10);
+		}
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+		ret = __os04d10_start_stream(os04d10);
+		if (ret) {
+			v4l2_err(sd, "start stream failed while write regs\n");
+			pm_runtime_put(&client->dev);
+			goto unlock_and_return;
+		}
+	} else {
+		__os04d10_stop_stream(os04d10);
+		pm_runtime_put(&client->dev);
+	}
+
+	os04d10->streaming = on;
+unlock_and_return:
+	mutex_unlock(&os04d10->mutex);
+	return ret;
+}
+
+static int os04d10_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct os04d10 *os04d10 = to_os04d10(sd);
+	struct i2c_client *client = os04d10->client;
+	int ret = 0;
+
+	mutex_lock(&os04d10->mutex);
+
+	/* If the power state is not modified - no work to do. */
+	if (os04d10->power_on == !!on)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		if (!os04d10->is_thunderboot) {
+			ret = os04d10_write_array(os04d10->client, os04d10_global_regs);
+			if (ret) {
+				v4l2_err(sd, "could not set init registers\n");
+				pm_runtime_put_noidle(&client->dev);
+				goto unlock_and_return;
+			}
+		}
+
+		os04d10->power_on = true;
+	} else {
+		pm_runtime_put(&client->dev);
+		os04d10->power_on = false;
+	}
+
+unlock_and_return:
+	mutex_unlock(&os04d10->mutex);
+
+	return ret;
+}
+
+/* Calculate the delay in us by clock rate and clock cycles */
+static inline u32 os04d10_cal_delay(u32 cycles)
+{
+	return DIV_ROUND_UP(cycles, OS04D10_XVCLK_FREQ / 1000 / 1000);
+}
+
+static int __os04d10_power_on(struct os04d10 *os04d10)
+{
+	int ret;
+	u32 delay_us;
+	struct device *dev = &os04d10->client->dev;
+
+	if (!IS_ERR_OR_NULL(os04d10->pins_default)) {
+		ret = pinctrl_select_state(os04d10->pinctrl,
+					   os04d10->pins_default);
+		if (ret < 0)
+			dev_err(dev, "could not set pins\n");
+	}
+
+	if (os04d10->is_thunderboot)
+		return 0;
+
+	if (!IS_ERR(os04d10->reset_gpio))
+		gpiod_set_value_cansleep(os04d10->reset_gpio, 0);
+
+	usleep_range(5000, 6000);
+
+	ret = regulator_bulk_enable(OS04D10_NUM_SUPPLIES, os04d10->supplies);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable regulators\n");
+		goto disable_clk;
+	}
+
+	if (!IS_ERR(os04d10->reset_gpio))
+		gpiod_set_value_cansleep(os04d10->reset_gpio, 1);
+
+	usleep_range(500, 1000);
+
+	if (!IS_ERR(os04d10->reset_gpio))
+		usleep_range(8000, 10000);
+	else
+		usleep_range(12000, 16000);
+
+	usleep_range(12000, 16000);
+
+	ret = clk_set_rate(os04d10->xvclk, OS04D10_XVCLK_FREQ);
+	if (ret < 0)
+		dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
+	if (clk_get_rate(os04d10->xvclk) != OS04D10_XVCLK_FREQ)
+		dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
+	ret = clk_prepare_enable(os04d10->xvclk);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable xvclk\n");
+		return ret;
+	}
+
+	/* 8192 cycles prior to first SCCB transaction */
+	delay_us = os04d10_cal_delay(8192);
+	usleep_range(delay_us, delay_us * 2);
+
+	return 0;
+
+disable_clk:
+	clk_disable_unprepare(os04d10->xvclk);
+
+	return ret;
+}
+
+static void __os04d10_power_off(struct os04d10 *os04d10)
+{
+	int ret;
+	struct device *dev = &os04d10->client->dev;
+
+	clk_disable_unprepare(os04d10->xvclk);
+	if (os04d10->is_thunderboot) {
+		if (os04d10->is_first_streamoff) {
+			os04d10->is_thunderboot = false;
+			os04d10->is_first_streamoff = false;
+		} else {
+			return;
+		}
+	}
+
+	clk_disable_unprepare(os04d10->xvclk);
+	if (!IS_ERR(os04d10->reset_gpio))
+		gpiod_set_value_cansleep(os04d10->reset_gpio, 0);
+	if (!IS_ERR_OR_NULL(os04d10->pins_sleep)) {
+		ret = pinctrl_select_state(os04d10->pinctrl,
+					   os04d10->pins_sleep);
+		if (ret < 0)
+			dev_dbg(dev, "could not set pins\n");
+	}
+	regulator_bulk_disable(OS04D10_NUM_SUPPLIES, os04d10->supplies);
+}
+
+static int os04d10_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct os04d10 *os04d10 = to_os04d10(sd);
+
+	return __os04d10_power_on(os04d10);
+}
+
+static int os04d10_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct os04d10 *os04d10 = to_os04d10(sd);
+
+	__os04d10_power_off(os04d10);
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int os04d10_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct os04d10 *os04d10 = to_os04d10(sd);
+	struct v4l2_mbus_framefmt *try_fmt =
+				v4l2_subdev_get_try_format(sd, fh->pad, 0);
+	const struct os04d10_mode *def_mode = &supported_modes[0];
+
+	mutex_lock(&os04d10->mutex);
+	/* Initialize try_fmt */
+	try_fmt->width = def_mode->width;
+	try_fmt->height = def_mode->height;
+	try_fmt->code = def_mode->bus_fmt;
+	try_fmt->field = V4L2_FIELD_NONE;
+
+	mutex_unlock(&os04d10->mutex);
+	/* No crop or compose */
+
+	return 0;
+}
+#endif
+
+#define DST_WIDTH 2560
+#define DST_HEIGHT 1440
+
+/*
+ * The resolution of the driver configuration needs to be exactly
+ * the same as the current output resolution of the sensor,
+ * the input width of the isp needs to be 16 aligned,
+ * the input height of the isp needs to be 8 aligned.
+ * Can be cropped to standard resolution by this function,
+ * otherwise it will crop out strange resolution according
+ * to the alignment rules.
+ */
+static int os04d10_get_selection(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_pad_config *cfg,
+				 struct v4l2_subdev_selection *sel)
+{
+	if (sel->target == V4L2_SEL_TGT_CROP_BOUNDS) {
+		sel->r.left = 0;
+		sel->r.width = DST_WIDTH;
+		sel->r.top = 0;
+		sel->r.height = DST_HEIGHT;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static int os04d10_enum_frame_interval(struct v4l2_subdev *sd,
+				       struct v4l2_subdev_pad_config *cfg,
+				       struct v4l2_subdev_frame_interval_enum *fie)
+{
+	if (fie->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	fie->code = supported_modes[fie->index].bus_fmt;
+	fie->width = supported_modes[fie->index].width;
+	fie->height = supported_modes[fie->index].height;
+	fie->interval = supported_modes[fie->index].max_fps;
+	fie->reserved[0] = supported_modes[fie->index].hdr_mode;
+	return 0;
+}
+
+static const struct dev_pm_ops os04d10_pm_ops = {
+	SET_RUNTIME_PM_OPS(os04d10_runtime_suspend,
+			   os04d10_runtime_resume, NULL)
+};
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static const struct v4l2_subdev_internal_ops os04d10_internal_ops = {
+	.open = os04d10_open,
+};
+#endif
+
+static const struct v4l2_subdev_core_ops os04d10_core_ops = {
+	.s_power = os04d10_s_power,
+	.ioctl = os04d10_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl32 = os04d10_compat_ioctl32,
+#endif
+};
+
+static const struct v4l2_subdev_video_ops os04d10_video_ops = {
+	.s_stream = os04d10_s_stream,
+	.g_frame_interval = os04d10_g_frame_interval,
+};
+
+static const struct v4l2_subdev_pad_ops os04d10_pad_ops = {
+	.enum_mbus_code = os04d10_enum_mbus_code,
+	.enum_frame_size = os04d10_enum_frame_sizes,
+	.enum_frame_interval = os04d10_enum_frame_interval,
+	.get_fmt = os04d10_get_fmt,
+	.set_fmt = os04d10_set_fmt,
+	.get_selection = os04d10_get_selection,
+	.get_mbus_config = os04d10_g_mbus_config,
+};
+
+static const struct v4l2_subdev_ops os04d10_subdev_ops = {
+	.core	= &os04d10_core_ops,
+	.video	= &os04d10_video_ops,
+	.pad	= &os04d10_pad_ops,
+};
+
+static void os04d10_modify_fps_info(struct os04d10 *os04d10)
+{
+	const struct os04d10_mode *mode = os04d10->cur_mode;
+
+	os04d10->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
+				      os04d10->cur_vts;
+}
+
+static int os04d10_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct os04d10 *os04d10 = container_of(ctrl->handler,
+					       struct os04d10, ctrl_handler);
+	struct i2c_client *client = os04d10->client;
+	s64 max;
+	int ret = 0;
+	u8 val = 0;
+
+	/* Propagate change of current control to all related controls */
+	switch (ctrl->id) {
+	case V4L2_CID_VBLANK:
+		/* Update max exposure while meeting expected vblanking */
+		max = os04d10->cur_mode->height + ctrl->val - 9;
+		__v4l2_ctrl_modify_range(os04d10->exposure,
+					 os04d10->exposure->minimum, max,
+					 os04d10->exposure->step,
+					 os04d10->exposure->default_value);
+		break;
+	}
+
+	if (!pm_runtime_get_if_in_use(&client->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		dev_dbg(&client->dev, "set exposure 0x%x\n", ctrl->val);
+		if (os04d10->cur_mode->hdr_mode == NO_HDR) {
+
+			ret = os04d10_write_reg(os04d10->client,
+						OS04D10_REG_PAGE_SEL,
+						OS04D10_REG_PAGE_CIS_TIMING);
+			/* 4 least significant bits of expsoure are fractional part */
+			ret |= os04d10_write_reg(os04d10->client,
+						 OS04D10_REG_EXPOSURE_H,
+						 (u8)OS04D10_FETCH_EXP_H(ctrl->val));
+			ret |= os04d10_write_reg(os04d10->client,
+						 OS04D10_REG_EXPOSURE_L,
+						 (u8)OS04D10_FETCH_EXP_L(ctrl->val));
+			ret |= os04d10_write_reg(os04d10->client,
+						 OS04D10_REG_EXP_UPDATE,
+						 0x01);
+		}
+		break;
+	case V4L2_CID_ANALOGUE_GAIN:
+		dev_dbg(&client->dev, "set gain 0x%x\n", ctrl->val);
+		if (os04d10->cur_mode->hdr_mode == NO_HDR)
+			ret = os04d10_set_gain_reg(os04d10, ctrl->val);
+		break;
+	case V4L2_CID_VBLANK:
+		dev_dbg(&client->dev, "set vblank 0x%x\n", ctrl->val);
+		ret = os04d10_write_reg(os04d10->client,
+					OS04D10_REG_PAGE_SEL,
+					OS04D10_REG_PAGE_CIS_TIMING);
+		ret |= os04d10_write_reg(os04d10->client,
+					 OS04D10_REG_VTS_H,
+					 ((ctrl->val + os04d10->cur_mode->height) >> 8) & 0xff);
+		ret |= os04d10_write_reg(os04d10->client,
+					 OS04D10_REG_VTS_L,
+					 (ctrl->val + os04d10->cur_mode->height) & 0xff);
+		ret |= os04d10_write_reg(os04d10->client, OS04D10_REG_EXP_UPDATE, 0x01);
+		os04d10->cur_vts = ctrl->val + os04d10->cur_mode->height;
+		os04d10_modify_fps_info(os04d10);
+		break;
+	case V4L2_CID_TEST_PATTERN:
+		ret = os04d10_enable_test_pattern(os04d10, ctrl->val);
+		break;
+	case V4L2_CID_HFLIP:
+		dev_dbg(&client->dev, "set hflip 0x%x\n", ctrl->val);
+		ret = os04d10_write_reg(os04d10->client,
+					OS04D10_REG_PAGE_SEL,
+					OS04D10_REG_PAGE_CIS_TIMING);
+		ret |= os04d10_read_reg(os04d10->client,
+				       OS04D10_FLIP_MIRROR_REG,
+				       &val);
+		ret |= os04d10_write_reg(os04d10->client,
+					 OS04D10_FLIP_MIRROR_REG,
+					 OS04D10_FETCH_MIRROR(val, ctrl->val));
+		ret |= os04d10_write_reg(os04d10->client, OS04D10_REG_EXP_UPDATE, 0x01);
+		break;
+	case V4L2_CID_VFLIP:
+		dev_dbg(&client->dev, "set vflip 0x%x\n", ctrl->val);
+		ret = os04d10_write_reg(os04d10->client,
+					OS04D10_REG_PAGE_SEL,
+					OS04D10_REG_PAGE_CIS_TIMING);
+		ret |= os04d10_read_reg(os04d10->client,
+				       OS04D10_FLIP_MIRROR_REG,
+				       &val);
+		ret |= os04d10_write_reg(os04d10->client,
+					 OS04D10_FLIP_MIRROR_REG,
+					 OS04D10_FETCH_FLIP(val, ctrl->val));
+		ret |= os04d10_write_reg(os04d10->client, OS04D10_REG_EXP_UPDATE, 0x01);
+		break;
+	default:
+		dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
+			 __func__, ctrl->id, ctrl->val);
+		break;
+	}
+
+	pm_runtime_put(&client->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops os04d10_ctrl_ops = {
+	.s_ctrl = os04d10_set_ctrl,
+};
+
+static int os04d10_initialize_controls(struct os04d10 *os04d10)
+{
+	const struct os04d10_mode *mode;
+	struct v4l2_ctrl_handler *handler;
+	struct v4l2_ctrl *ctrl;
+	s64 exposure_max, vblank_def;
+	u32 h_blank;
+	int ret;
+
+	handler = &os04d10->ctrl_handler;
+	mode = os04d10->cur_mode;
+	ret = v4l2_ctrl_handler_init(handler, 9);
+	if (ret)
+		return ret;
+	handler->lock = &os04d10->mutex;
+
+	ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
+				      0, 0, link_freq_menu_items);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
+			  0, PIXEL_RATE_WITH_360M_10BIT, 1, PIXEL_RATE_WITH_360M_10BIT);
+
+	h_blank = mode->hts_def - mode->width;
+	os04d10->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
+					    h_blank, h_blank, 1, h_blank);
+	if (os04d10->hblank)
+		os04d10->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+	vblank_def = mode->vts_def - mode->height;
+	os04d10->vblank = v4l2_ctrl_new_std(handler, &os04d10_ctrl_ops,
+					    V4L2_CID_VBLANK, vblank_def,
+					    OS04D10_VTS_MAX - mode->height,
+					    1, vblank_def);
+	exposure_max = mode->vts_def - 9;
+	os04d10->exposure = v4l2_ctrl_new_std(handler, &os04d10_ctrl_ops,
+					      V4L2_CID_EXPOSURE, OS04D10_EXPOSURE_MIN,
+					      exposure_max, OS04D10_EXPOSURE_STEP,
+					      mode->exp_def);
+	os04d10->anal_gain = v4l2_ctrl_new_std(handler, &os04d10_ctrl_ops,
+					       V4L2_CID_ANALOGUE_GAIN, OS04D10_GAIN_MIN,
+					       OS04D10_GAIN_MAX, OS04D10_GAIN_STEP,
+					       OS04D10_GAIN_DEFAULT);
+	os04d10->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
+							    &os04d10_ctrl_ops,
+					V4L2_CID_TEST_PATTERN,
+					ARRAY_SIZE(os04d10_test_pattern_menu) - 1,
+					0, 0, os04d10_test_pattern_menu);
+	v4l2_ctrl_new_std(handler, &os04d10_ctrl_ops,
+				V4L2_CID_HFLIP, 0, 1, 1, 0);
+	v4l2_ctrl_new_std(handler, &os04d10_ctrl_ops,
+				V4L2_CID_VFLIP, 0, 1, 1, 0);
+	if (handler->error) {
+		ret = handler->error;
+		dev_err(&os04d10->client->dev,
+			"Failed to init controls(%d)\n", ret);
+		goto err_free_handler;
+	}
+
+	os04d10->subdev.ctrl_handler = handler;
+	os04d10->has_init_exp = false;
+	os04d10->cur_fps = mode->max_fps;
+
+	return 0;
+
+err_free_handler:
+	v4l2_ctrl_handler_free(handler);
+
+	return ret;
+}
+
+static int os04d10_check_sensor_id(struct os04d10 *os04d10,
+				   struct i2c_client *client)
+{
+	struct device *dev = &os04d10->client->dev;
+	u8 id = 0;
+	u32 val = 0;
+	int ret = 0, i = 0;
+
+	if (os04d10->is_thunderboot) {
+		dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
+		return 0;
+	}
+
+	for (i = 0; i < OS04D10_REG_VALUE_32BIT; i++) {
+		ret |= os04d10_read_reg(client, OS04D10_REG_CHIP_ID + i, &id);
+		val = (val << 8) | id;
+	}
+
+	if (val != CHIP_ID) {
+		dev_err(dev, "Unexpected sensor id(%08x), ret(%d)\n", val, ret);
+		return -ENODEV;
+	}
+
+	dev_info(dev, "Detected OV%08x sensor\n", CHIP_ID);
+
+	return 0;
+}
+
+static int os04d10_configure_regulators(struct os04d10 *os04d10)
+{
+	unsigned int i;
+
+	for (i = 0; i < OS04D10_NUM_SUPPLIES; i++)
+		os04d10->supplies[i].supply = os04d10_supply_names[i];
+
+	return devm_regulator_bulk_get(&os04d10->client->dev,
+				       OS04D10_NUM_SUPPLIES,
+				       os04d10->supplies);
+}
+
+static int os04d10_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct device_node *node = dev->of_node;
+	struct os04d10 *os04d10;
+	struct v4l2_subdev *sd;
+	char facing[2];
+	int ret;
+	int i, hdr_mode = 0;
+
+	dev_info(dev, "driver version: %02x.%02x.%02x",
+		 DRIVER_VERSION >> 16,
+		 (DRIVER_VERSION & 0xff00) >> 8,
+		 DRIVER_VERSION & 0x00ff);
+
+	os04d10 = devm_kzalloc(dev, sizeof(*os04d10), GFP_KERNEL);
+	if (!os04d10)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
+				   &os04d10->module_index);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
+				       &os04d10->module_facing);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
+				       &os04d10->module_name);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
+				       &os04d10->len_name);
+	if (ret) {
+		dev_err(dev, "could not get module information!\n");
+		return -EINVAL;
+	}
+
+	os04d10->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
+
+	os04d10->client = client;
+	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+		if (hdr_mode == supported_modes[i].hdr_mode) {
+			os04d10->cur_mode = &supported_modes[i];
+			break;
+		}
+	}
+	if (i == ARRAY_SIZE(supported_modes))
+		os04d10->cur_mode = &supported_modes[0];
+
+	os04d10->xvclk = devm_clk_get(dev, "xvclk");
+	if (IS_ERR(os04d10->xvclk)) {
+		dev_err(dev, "Failed to get xvclk\n");
+		return -EINVAL;
+	}
+
+	os04d10->reset_gpio = devm_gpiod_get(dev, "reset", os04d10->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
+	if (IS_ERR(os04d10->reset_gpio))
+		dev_warn(dev, "Failed to get reset-gpios\n");
+
+	if (!IS_ERR(os04d10->reset_gpio))
+		gpiod_set_value_cansleep(os04d10->reset_gpio, 0);
+
+	os04d10->pinctrl = devm_pinctrl_get(dev);
+	if (!IS_ERR(os04d10->pinctrl)) {
+		os04d10->pins_default =
+			pinctrl_lookup_state(os04d10->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_DEFAULT);
+		if (IS_ERR(os04d10->pins_default))
+			dev_err(dev, "could not get default pinstate\n");
+
+		os04d10->pins_sleep =
+			pinctrl_lookup_state(os04d10->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_SLEEP);
+		if (IS_ERR(os04d10->pins_sleep))
+			dev_err(dev, "could not get sleep pinstate\n");
+	} else {
+		dev_err(dev, "no pinctrl\n");
+	}
+
+	ret = os04d10_configure_regulators(os04d10);
+	if (ret) {
+		dev_err(dev, "Failed to get power regulators\n");
+		return ret;
+	}
+
+	mutex_init(&os04d10->mutex);
+
+	sd = &os04d10->subdev;
+	v4l2_i2c_subdev_init(sd, client, &os04d10_subdev_ops);
+	ret = os04d10_initialize_controls(os04d10);
+	if (ret)
+		goto err_destroy_mutex;
+
+	ret = __os04d10_power_on(os04d10);
+	if (ret)
+		goto err_free_handler;
+
+	ret = os04d10_check_sensor_id(os04d10, client);
+	if (ret)
+		goto err_power_off;
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	sd->internal_ops = &os04d10_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+		     V4L2_SUBDEV_FL_HAS_EVENTS;
+#endif
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	os04d10->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &os04d10->pad);
+	if (ret < 0)
+		goto err_power_off;
+#endif
+
+	memset(facing, 0, sizeof(facing));
+	if (strcmp(os04d10->module_facing, "back") == 0)
+		facing[0] = 'b';
+	else
+		facing[0] = 'f';
+
+	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
+		 os04d10->module_index, facing,
+		 OS04D10_NAME, dev_name(sd->dev));
+	ret = v4l2_async_register_subdev_sensor_common(sd);
+	if (ret) {
+		dev_err(dev, "v4l2 async register subdev failed\n");
+		goto err_clean_entity;
+	}
+
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	if (os04d10->is_thunderboot)
+		pm_runtime_get_sync(dev);
+	else
+		pm_runtime_idle(dev);
+
+	return 0;
+
+err_clean_entity:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+err_power_off:
+	__os04d10_power_off(os04d10);
+err_free_handler:
+	v4l2_ctrl_handler_free(&os04d10->ctrl_handler);
+err_destroy_mutex:
+	mutex_destroy(&os04d10->mutex);
+
+	return ret;
+}
+
+static int os04d10_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct os04d10 *os04d10 = to_os04d10(sd);
+
+	v4l2_async_unregister_subdev(sd);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+	v4l2_ctrl_handler_free(&os04d10->ctrl_handler);
+	mutex_destroy(&os04d10->mutex);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		__os04d10_power_off(os04d10);
+	pm_runtime_set_suspended(&client->dev);
+
+	return 0;
+}
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id os04d10_of_match[] = {
+	{ .compatible = "ovti,os04d10" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, os04d10_of_match);
+#endif
+
+static const struct i2c_device_id os04d10_match_id[] = {
+	{ "ovti,os04d10", 0 },
+	{ },
+};
+
+static struct i2c_driver os04d10_i2c_driver = {
+	.driver = {
+		.name = OS04D10_NAME,
+		.pm = &os04d10_pm_ops,
+		.of_match_table = of_match_ptr(os04d10_of_match),
+	},
+	.probe		= &os04d10_probe,
+	.remove		= &os04d10_remove,
+	.id_table	= os04d10_match_id,
+};
+
+static int __init sensor_mod_init(void)
+{
+	return i2c_add_driver(&os04d10_i2c_driver);
+}
+
+static void __exit sensor_mod_exit(void)
+{
+	i2c_del_driver(&os04d10_i2c_driver);
+}
+
+#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
+subsys_initcall(sensor_mod_init);
+#else
+device_initcall_sync(sensor_mod_init);
+#endif
+module_exit(sensor_mod_exit);
+
+MODULE_DESCRIPTION("ovti os04d10 sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/ov16885.c b/kernel/drivers/media/i2c/ov16885.c
new file mode 100644
index 0000000..cc91a0b
--- /dev/null
+++ b/kernel/drivers/media/i2c/ov16885.c
@@ -0,0 +1,2165 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ov16885 camera driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * V0.0X01.0X00 first version.
+ *
+ */
+//#define DEBUG
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/compat.h>
+#include <linux/rk-camera-module.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <linux/pinctrl/consumer.h>
+
+#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x00)
+#define OV16885_MAJOR_I2C_ADDR		0x36
+#define OV16885_MINOR_I2C_ADDR		0x10
+
+#ifndef V4L2_CID_DIGITAL_GAIN
+#define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
+#endif
+
+#define OV16885_LINK_FREQ_736MHZ	736000000U
+
+/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
+#define OV16885_PIXEL_RATE		(OV16885_LINK_FREQ_736MHZ * 2LL * 4LL / 10LL)
+#define OV16885_XVCLK_FREQ		24000000
+
+#define CHIP_ID				0x016885
+#define OV16885_REG_CHIP_ID		0x300a
+
+#define OV16885_REG_CTRL_MODE		0x0100
+#define OV16885_MODE_SW_STANDBY		0x0
+#define OV16885_MODE_STREAMING		BIT(0)
+
+#define OV16885_REG_EXPOSURE_H		0x3500
+#define OV16885_REG_EXPOSURE_M		0x3501
+#define OV16885_REG_EXPOSURE_L		0x3502
+#define	OV16885_EXPOSURE_MIN		8
+#define	OV16885_EXPOSURE_STEP		1
+#define OV16885_VTS_MAX			0x7fff
+
+#define OV16885_LF_AGAIN_REG_H		0x3508
+#define OV16885_LF_AGAIN_REG_L		0x3509
+#define OV16885_SF_AGAIN_REG_H		0x350C
+#define OV16885_SF_AGAIN_REG_L		0x350D
+#define OV16885_GAIN_H_MASK		0x1f
+#define OV16885_GAIN_H_SHIFT		8
+
+
+#define OV16885_GAIN_MIN		0x80
+#define OV16885_GAIN_MAX		0x07FF
+#define OV16885_GAIN_STEP		1
+#define OV16885_GAIN_DEFAULT		0x80
+
+#define OV16885_SOFTWARE_RESET_REG	0x0103
+#define OV16885_REG_ISP_X_WIN		0x3810
+
+#define OV16885_GROUP_UPDATE_ADDRESS	0x3208
+#define OV16885_GROUP_UPDATE_START_DATA	0x00
+#define OV16885_GROUP_UPDATE_END_DATA	0x10
+#define OV16885_GROUP_UPDATE_LAUNCH	0xA0
+
+#define OV16885_REG_TEST_PATTERN	0x5081
+#define	OV16885_TEST_PATTERN_ENABLE	0x01
+#define	OV16885_TEST_PATTERN_DISABLE	0x0
+
+#define OV16885_REG_VTS_H		0x380e
+#define OV16885_REG_VTS_L		0x380f
+
+#define OV16885_FLIP_REG		0x3820
+#define OV16885_MIRROR_REG		0x3674
+#define MIRROR_BIT_MASK			BIT(2)
+#define FLIP_BIT_MASK			BIT(2)
+
+#define OV16885_FETCH_EXP_H(VAL)	(((VAL) >> 16) & 0x7F)
+#define OV16885_FETCH_EXP_M(VAL)	(((VAL) >> 8) & 0xFF)
+#define OV16885_FETCH_EXP_L(VAL)	((VAL) & 0xFF)
+
+#define OV16885_FETCH_AGAIN_H(VAL)	(((VAL) >> 8) & 0x7F)
+#define OV16885_FETCH_AGAIN_L(VAL)	((VAL) & 0xFE)
+
+#define OV16885_FETCH_DGAIN_H(VAL)	(((VAL) >> 16) & 0x0F)
+#define OV16885_FETCH_DGAIN_M(VAL)	(((VAL) >> 8) & 0xFF)
+#define OV16885_FETCH_DGAIN_L(VAL)	((VAL) & 0xC0)
+
+#define OV16885_FETCH_VTS_H(VAL)	(((VAL) >> 8) & 0x7F)
+#define OV16885_FETCH_VTS_L(VAL)	((VAL) & 0xFF)
+
+#define REG_NULL			0xFFFF
+
+#define OV16885_REG_VALUE_08BIT		1
+#define OV16885_REG_VALUE_16BIT		2
+#define OV16885_REG_VALUE_24BIT		3
+
+#define OV16885_LANES			4
+#define OV16885_BITS_PER_SAMPLE		10
+
+#define OF_CAMERA_PINCTRL_STATE_DEFAULT	"rockchip,camera_default"
+#define OF_CAMERA_PINCTRL_STATE_SLEEP	"rockchip,camera_sleep"
+#define OF_CAMERA_HDR_MODE		"rockchip,camera-hdr-mode"
+
+#define OV16885_NAME			"ov16885"
+#define OV16885_MEDIA_BUS_FMT		MEDIA_BUS_FMT_SBGGR10_1X10
+
+static const char * const ov16885_supply_names[] = {
+	"avdd",		/* Analog power */
+	"dovdd",	/* Digital I/O power */
+	"dvdd",		/* Digital core power */
+};
+
+#define OV16885_NUM_SUPPLIES ARRAY_SIZE(ov16885_supply_names)
+
+struct regval {
+	u16 addr;
+	u8 val;
+};
+
+struct ov16885_mode {
+	u32 width;
+	u32 height;
+	struct v4l2_fract max_fps;
+	u32 hts_def;
+	u32 vts_def;
+	u32 exp_def;
+	u32 link_freq_idx;
+	u32 bpp;
+	const struct regval *reg_list;
+	u32 hdr_mode;
+	u32 vc[PAD_MAX];
+};
+
+struct ov16885 {
+	struct i2c_client	*client;
+	struct clk		*xvclk;
+	struct gpio_desc	*power_gpio;
+	struct gpio_desc	*reset_gpio;
+	struct gpio_desc	*pwdn_gpio;
+	struct regulator_bulk_data supplies[OV16885_NUM_SUPPLIES];
+
+	struct pinctrl		*pinctrl;
+	struct pinctrl_state	*pins_default;
+	struct pinctrl_state	*pins_sleep;
+
+	struct v4l2_subdev	subdev;
+	struct media_pad	pad;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl	*exposure;
+	struct v4l2_ctrl	*anal_gain;
+	struct v4l2_ctrl	*digi_gain;
+	struct v4l2_ctrl	*hblank;
+	struct v4l2_ctrl	*vblank;
+	struct v4l2_ctrl	*pixel_rate;
+	struct v4l2_ctrl	*link_freq;
+	struct v4l2_ctrl	*test_pattern;
+	struct v4l2_ctrl	*h_flip;
+	struct v4l2_ctrl	*v_flip;
+	struct mutex		mutex;
+	bool			streaming;
+	bool			power_on;
+	const struct ov16885_mode *cur_mode;
+	u32			cfg_num;
+	u32			module_index;
+	const char		*module_facing;
+	const char		*module_name;
+	const char		*len_name;
+};
+
+#define to_ov16885(sd) container_of(sd, struct ov16885, subdev)
+
+/*
+ * Xclk 24Mhz
+ */
+static const struct regval ov16885_global_regs[] = {
+	// init_setting
+	{0x0103,0x01},
+	{0x0102,0x01},
+	{0x0300,0xf3},
+	{0x0301,0xa5},
+	{0x0302,0x10},
+	{0x0304,0x4b},
+	{0x0314,0x02},
+	{0x0316,0xa0},
+	{0x0319,0x00},
+	{0x031a,0x01},
+	{0x031e,0x09},
+	{0x0320,0x0f},
+	{0x300d,0x11},
+	{0x3011,0xfc},
+	{0x3012,0x41},
+	{0x3016,0xf0},
+	{0x3018,0xf0},
+	{0x301b,0x3c},
+	{0x3025,0x03},
+	{0x3026,0x10},
+	{0x3027,0x08},
+	{0x301e,0x98},
+	{0x3031,0x88},
+	{0x3400,0x00},
+	{0x3406,0x08},
+	{0x3408,0x03},
+	{0x3410,0x00},
+	{0x3412,0x00},
+	{0x3413,0x00},
+	{0x3414,0x00},
+	{0x3415,0x00},
+	{0x3500,0x00},
+	{0x3501,0xec},
+	{0x3502,0x00},
+	{0x3503,0x08},
+	{0x3505,0x8c},
+	{0x3507,0x00},
+	{0x3508,0x02},
+	{0x3509,0x00},
+	{0x350c,0x02},
+	{0x350d,0x00},
+	{0x3510,0x00},
+	{0x3511,0xec},
+	{0x3512,0x00},
+	{0x3600,0x00},
+	{0x3601,0x00},
+	{0x3602,0x86},
+	{0x3608,0xc7},
+	{0x3609,0xd0},
+	{0x360a,0xff},
+	{0x360b,0x6c},
+	{0x360c,0x00},
+	{0x3611,0x00},
+	{0x3612,0x00},
+	{0x3613,0x8e},
+	{0x3618,0x00},
+	{0x3619,0x90},
+	{0x361a,0x00},
+	{0x361b,0x01},
+	{0x361c,0xc5},
+	{0x3620,0x50},
+	{0x3621,0x88},
+	{0x3622,0x88},
+	{0x3623,0x88},
+	{0x3624,0x88},
+	{0x3625,0x88},
+	{0x3626,0x03},
+	{0x3627,0x88},
+	{0x3628,0x1c},
+	{0x3629,0x00},
+	{0x362a,0x00},
+	{0x3632,0x00},
+	{0x3633,0x10},
+	{0x3634,0x10},
+	{0x3635,0x10},
+	{0x3636,0x10},
+	{0x3637,0x77},
+	{0x3638,0x77},
+	{0x3639,0x66},
+	{0x363a,0x66},
+	{0x3652,0x00},
+	{0x3653,0x00},
+	{0x3654,0x77},
+	{0x3655,0x77},
+	{0x3656,0x77},
+	{0x3657,0x77},
+	{0x3658,0x00},
+	{0x3659,0x84},
+	{0x365a,0x81},
+	{0x365b,0x8e},
+	{0x365c,0x1c},
+	{0x3660,0x40},
+	{0x3661,0x0c},
+	{0x3662,0x00},
+	{0x3663,0x40},
+	{0x3664,0x03},
+	{0x3666,0xac},
+	{0x3668,0xf0},
+	{0x3669,0x0e},
+	{0x366a,0x10},
+	{0x366b,0x42},
+	{0x366c,0x53},
+	{0x366d,0x05},
+	{0x366e,0x05},
+	{0x3674,0x04},
+	{0x3675,0x16},
+	{0x3680,0x00},
+	{0x3681,0x33},
+	{0x3682,0x33},
+	{0x3683,0x33},
+	{0x368a,0x04},
+	{0x368b,0x04},
+	{0x368c,0x04},
+	{0x368d,0x04},
+	{0x368e,0x04},
+	{0x368f,0x04},
+	{0x3694,0x10},
+	{0x3696,0x30},
+	{0x3698,0x30},
+	{0x3699,0x00},
+	{0x369a,0x44},
+	{0x369c,0x28},
+	{0x369e,0x28},
+	{0x36a0,0x28},
+	{0x36a2,0x30},
+	{0x36a4,0x3b},
+	{0x36a5,0x00},
+	{0x36a6,0x43},
+	{0x36a7,0x00},
+	{0x36a8,0x48},
+	{0x36a9,0x00},
+	{0x36aa,0x48},
+	{0x36ab,0x00},
+	{0x36ac,0x48},
+	{0x36c1,0x33},
+	{0x36c3,0x33},
+	{0x36ca,0x04},
+	{0x36cb,0x04},
+	{0x36cc,0x04},
+	{0x36cd,0x04},
+	{0x36ce,0x04},
+	{0x36cf,0x04},
+	{0x3700,0x13},
+	{0x3701,0x0e},
+	{0x3702,0x12},
+	{0x3704,0x0e},
+	{0x3706,0x23},
+	{0x3708,0x17},
+	{0x3709,0x30},
+	{0x370b,0x63},
+	{0x3713,0x00},
+	{0x3714,0x64},
+	{0x371d,0x10},
+	{0x371f,0x05},
+	{0x3726,0x20},
+	{0x3727,0x23},
+	{0x373b,0x06},
+	{0x373d,0x07},
+	{0x374f,0x0d},
+	{0x3754,0x88},
+	{0x375a,0x08},
+	{0x3764,0x12},
+	{0x3765,0x0b},
+	{0x3767,0x0c},
+	{0x3768,0x18},
+	{0x3769,0x08},
+	{0x376a,0x0c},
+	{0x376b,0x80},
+	{0x37a2,0x04},
+	{0x37b1,0x40},
+	{0x37d0,0x06},
+	{0x37d9,0x88},
+	{0x37f4,0x00},
+	{0x37fc,0x05},
+	{0x37fd,0x00},
+	{0x37fe,0x0b},
+	{0x37ff,0x00},
+	{0x3800,0x00},
+	{0x3801,0x00},
+	{0x3802,0x00},
+	{0x3803,0x00},
+	{0x3804,0x12},
+	{0x3805,0x5f},
+	{0x3806,0x0d},
+	{0x3807,0xcf},
+	{0x3808,0x12},
+	{0x3809,0x40},
+	{0x380a,0x0d},
+	{0x380b,0xb0},
+	{0x380c,0x05},
+	{0x380d,0x78},
+	{0x380e,0x0e},
+	{0x380f,0xe0},
+	{0x3810,0x00},
+	{0x3811,0x11},
+	{0x3812,0x00},
+	{0x3813,0x08},
+	{0x3814,0x11},
+	{0x3815,0x11},
+	{0x3820,0x00},
+	{0x3821,0x00},
+	{0x382b,0x08},
+	{0x3834,0xf0},
+	{0x3836,0x28},
+	{0x383d,0x80},
+	{0x3841,0x20},
+	{0x3883,0x02},
+	{0x3886,0x02},
+	{0x3889,0x02},
+	{0x3891,0x0f},
+	{0x38a0,0x04},
+	{0x38a1,0x00},
+	{0x38a2,0x04},
+	{0x38a3,0x04},
+	{0x38b0,0x02},
+	{0x38b1,0x02},
+	{0x3b8e,0x00},
+	{0x3d84,0x80},
+	{0x3d85,0x1b},
+	{0x3d8c,0x67},
+	{0x3d8d,0xc0},
+	{0x3f00,0xca},
+	{0x3f03,0x10},
+	{0x3f05,0x66},
+	{0x4008,0x00},
+	{0x4009,0x02},
+	{0x400e,0x00},
+	{0x4010,0x28},
+	{0x4011,0x01},
+	{0x4012,0x6d},
+	{0x4013,0x28},
+	{0x4014,0x10},
+	{0x4015,0x02},
+	{0x4016,0x25},
+	{0x4017,0x00},
+	{0x4018,0x0f},
+	{0x4019,0x00},
+	{0x401a,0x40},
+	{0x4020,0x04},
+	{0x4021,0x00},
+	{0x4022,0x04},
+	{0x4023,0x00},
+	{0x4024,0x04},
+	{0x4025,0x00},
+	{0x4026,0x04},
+	{0x4027,0x00},
+	{0x4056,0x05},
+	{0x4202,0x00},
+	{0x4500,0x00},
+	{0x4501,0x05},
+	{0x4502,0x80},
+	{0x4503,0x31},
+	{0x450c,0x05},
+	{0x450e,0x16},
+	{0x450f,0x80},
+	{0x4540,0x99},
+	{0x4541,0x1b},
+	{0x4542,0x18},
+	{0x4543,0x1a},
+	{0x4544,0x1d},
+	{0x4545,0x1f},
+	{0x4546,0x1c},
+	{0x4547,0x1e},
+	{0x4548,0x09},
+	{0x4549,0x0b},
+	{0x454a,0x08},
+	{0x454b,0x0a},
+	{0x454c,0x0d},
+	{0x454d,0x0f},
+	{0x454e,0x0c},
+	{0x454f,0x0e},
+	{0x4550,0x09},
+	{0x4551,0x0b},
+	{0x4552,0x08},
+	{0x4553,0x0a},
+	{0x4554,0x0d},
+	{0x4555,0x0f},
+	{0x4556,0x0c},
+	{0x4557,0x0e},
+	{0x4558,0x19},
+	{0x4559,0x1b},
+	{0x455a,0x18},
+	{0x455b,0x1a},
+	{0x455c,0x1d},
+	{0x455d,0x1f},
+	{0x455e,0x1c},
+	{0x455f,0x1e},
+	{0x4640,0x01},
+	{0x4641,0x04},
+	{0x4642,0x02},
+	{0x4643,0x00},
+	{0x4645,0x03},
+	{0x4800,0x00},
+	{0x4809,0x2b},
+	{0x480e,0x02},
+	{0x4813,0x90},
+	{0x4817,0x00},
+	{0x481f,0x36},
+	{0x4837,0x0b},
+	{0x484b,0x01},
+	{0x4850,0x7c},
+	{0x4852,0x03},
+	{0x4853,0x12},
+	{0x4856,0x58},
+	{0x4857,0x02},
+	{0x4d00,0x04},
+	{0x4d01,0x5a},
+	{0x4d02,0xb3},
+	{0x4d03,0xf1},
+	{0x4d04,0xaa},
+	{0x4d05,0xc9},
+	{0x5080,0x00},
+	{0x5084,0x00},
+	{0x5085,0x00},
+	{0x5086,0x00},
+	{0x5087,0x00},
+	{0x5000,0x8b},
+	{0x5001,0x52},
+	{0x5002,0x01},
+	{0x5004,0x00},
+	{0x5020,0x00},
+	{0x5021,0x10},
+	{0x5022,0x12},
+	{0x5023,0x50},
+	{0x5024,0x00},
+	{0x5025,0x08},
+	{0x5026,0x0d},
+	{0x5027,0xb8},
+	{0x5028,0x00},
+	{0x5081,0x00},
+	{0x5180,0x03},
+	{0x5181,0xb0},
+	{0x5184,0x03},
+	{0x5185,0x07},
+	{0x518c,0x01},
+	{0x518d,0x01},
+	{0x518e,0x01},
+	{0x518f,0x01},
+	{0x5190,0x00},
+	{0x5191,0x00},
+	{0x5192,0x12},
+	{0x5193,0x5f},
+	{0x5194,0x00},
+	{0x5195,0x00},
+	{0x5200,0xbf},
+	{0x5201,0xf3},
+	{0x5202,0x09},
+	{0x5203,0x1b},
+	{0x5204,0xe0},
+	{0x5205,0x10},
+	{0x5206,0x3f},
+	{0x5207,0x3c},
+	{0x5208,0x24},
+	{0x5209,0x0f},
+	{0x520a,0x43},
+	{0x520b,0x3b},
+	{0x520c,0x33},
+	{0x520d,0x33},
+	{0x520e,0x63},
+	{0x5210,0x06},
+	{0x5211,0x03},
+	{0x5212,0x08},
+	{0x5213,0x08},
+	{0x5217,0x04},
+	{0x5218,0x02},
+	{0x5219,0x01},
+	{0x521a,0x04},
+	{0x521b,0x02},
+	{0x521c,0x01},
+	{0x5297,0x04},
+	{0x5298,0x02},
+	{0x5299,0x01},
+	{0x529a,0x04},
+	{0x529b,0x02},
+	{0x529c,0x01},
+	{0x5404,0x00},
+	{0x5405,0x00},
+	{0x5406,0x01},
+	{0x5407,0xe1},
+	{0x5408,0x01},
+	{0x5409,0x41},
+	{0x5410,0x02},
+	{0x5413,0xa0},
+	{0x5820,0x18},
+	{0x5821,0x08},
+	{0x5822,0x08},
+	{0x5823,0x18},
+	{0x5824,0x18},
+	{0x5825,0x08},
+	{0x5826,0x08},
+	{0x5827,0x18},
+	{0x582c,0x08},
+	{0x582d,0x18},
+	{0x582e,0x00},
+	{0x582f,0x00},
+	{0x5830,0x08},
+	{0x5831,0x18},
+	{0x5836,0x08},
+	{0x5837,0x18},
+	{0x5838,0x00},
+	{0x5839,0x00},
+	{0x583a,0x08},
+	{0x583b,0x18},
+	{0x583c,0x55},
+	{0x583e,0x03},
+	{0x5860,0x02},
+	{0x58a1,0x04},
+	{0x58a2,0x00},
+	{0x58a3,0x00},
+	{0x58a4,0x02},
+	{0x58a5,0x00},
+	{0x58a6,0x02},
+	{0x58a7,0x00},
+	{0x58a8,0x00},
+	{0x58a9,0x00},
+	{0x58aa,0x00},
+	{0x58ab,0x00},
+	{0x58ac,0x14},
+	{0x58ad,0x60},
+	{0x58ae,0x0f},
+	{0x58af,0x50},
+	{0x58c4,0x12},
+	{0x58c5,0x60},
+	{0x58c6,0x0d},
+	{0x58c7,0xd0},
+	{0x5900,0x3e},
+	{0x5901,0x3e},
+	{0x5902,0x3e},
+	{0x5903,0x3e},
+	{0x5904,0x3e},
+	{0x5905,0x3e},
+	{0x5906,0x3e},
+	{0x5907,0x3e},
+	{0x5908,0x3e},
+	{0x5909,0x3e},
+	{0x590a,0x3e},
+	{0x590b,0x3e},
+	{0x590c,0x3e},
+	{0x590d,0x3e},
+	{0x590e,0x3e},
+	{0x590f,0x3e},
+	{0x5910,0x3e},
+	{0x5911,0x3e},
+	{0x5912,0x3e},
+	{0x5913,0x3e},
+	{0x5914,0x3e},
+	{0x5915,0x3e},
+	{0x5916,0x3e},
+	{0x5917,0x3e},
+	{0x5918,0x3e},
+	{0x5919,0x3e},
+	{0x591a,0x3e},
+	{0x591b,0x3e},
+	{0x591c,0x3e},
+	{0x591d,0x3e},
+	{0x591e,0x3e},
+	{0x591f,0x3e},
+	{0x5920,0x3e},
+	{0x5921,0x3e},
+	{0x5922,0x3e},
+	{0x5923,0x3e},
+	{0x5924,0x3e},
+	{0x5925,0x3e},
+	{0x5926,0x3e},
+	{0x5927,0x3e},
+	{0x5928,0x3e},
+	{0x5929,0x3e},
+	{0x592a,0x3e},
+	{0x592b,0x3e},
+	{0x592c,0x3e},
+	{0x592d,0x40},
+	{0x592e,0x40},
+	{0x592f,0x40},
+	{0x5930,0x40},
+	{0x5931,0x40},
+	{0x5932,0x40},
+	{0x5933,0x40},
+	{0x5934,0x40},
+	{0x5935,0x40},
+	{0x5936,0x40},
+	{0x5937,0x40},
+	{0x5938,0x40},
+	{0x5939,0x40},
+	{0x593a,0x40},
+	{0x593b,0x40},
+	{0x593c,0x40},
+	{0x593d,0x40},
+	{0x593e,0x40},
+	{0x593f,0x40},
+	{0x5940,0x40},
+	{0x5941,0x40},
+	{0x5942,0x40},
+	{0x5943,0x40},
+	{0x5944,0x40},
+	{0x5945,0x40},
+	{0x5946,0x40},
+	{0x5947,0x40},
+	{0x5948,0x40},
+	{0x5949,0x40},
+	{0x594a,0x40},
+	{0x594b,0x40},
+	{0x594c,0x40},
+	{0x594d,0x40},
+	{0x594e,0x40},
+	{0x594f,0x40},
+	{0x5950,0x40},
+	{0x5951,0x40},
+	{0x5952,0x40},
+	{0x5953,0x40},
+	{0x5954,0x40},
+	{0x5955,0x40},
+	{0x5956,0x40},
+	{0x5957,0x40},
+	{0x5958,0x40},
+	{0x5959,0x40},
+	{0x595a,0x40},
+	{0x595b,0x40},
+	{0x595c,0x40},
+	{0x595d,0x40},
+	{0x595e,0x40},
+	{0x595f,0x40},
+	{0x5960,0x40},
+	{0x5961,0x40},
+	{0x5962,0x40},
+	{0x5963,0x40},
+	{0x5964,0x40},
+	{0x5965,0x40},
+	{0x5966,0x40},
+	{0x5967,0x40},
+	{0x5968,0x40},
+	{0x5969,0x40},
+	{0x596a,0x40},
+	{0x596b,0x40},
+	{0x596c,0x40},
+	{0x596d,0x40},
+	{0x596e,0x40},
+	{0x596f,0x40},
+	{0x5970,0x40},
+	{0x5971,0x40},
+	{0x5972,0x40},
+	{0x5973,0x40},
+	{0x5974,0x40},
+	{0x5975,0x40},
+	{0x5976,0x40},
+	{0x5977,0x40},
+	{0x5978,0x40},
+	{0x5979,0x40},
+	{0x597a,0x40},
+	{0x597b,0x40},
+	{0x597c,0x40},
+	{0x597d,0x40},
+	{0x597e,0x40},
+	{0x597f,0x40},
+	{0x5980,0x40},
+	{0x5981,0x40},
+	{0x5982,0x40},
+	{0x5983,0x40},
+	{0x5984,0x40},
+	{0x5985,0x40},
+	{0x5986,0x40},
+	{0x5987,0x40},
+	{0x5988,0x40},
+	{0x5989,0x40},
+	{0x598a,0x40},
+	{0x598b,0x40},
+	{0x598c,0x40},
+	{0x598d,0x40},
+	{0x598e,0x40},
+	{0x598f,0x40},
+	{0x5990,0x40},
+	{0x5991,0x40},
+	{0x5992,0x40},
+	{0x5993,0x40},
+	{0x5994,0x40},
+	{0x5995,0x40},
+	{0x5996,0x40},
+	{0x5997,0x40},
+	{0x5998,0x40},
+	{0x5999,0x40},
+	{0x599a,0x40},
+	{0x599b,0x40},
+	{0x599c,0x40},
+	{0x599d,0x40},
+	{0x599e,0x40},
+	{0x599f,0x40},
+	{0x59a0,0x40},
+	{0x59a1,0x40},
+	{0x59a2,0x40},
+	{0x59a3,0x40},
+	{0x59a4,0x40},
+	{0x59a5,0x40},
+	{0x59a6,0x40},
+	{0x59a7,0x40},
+	{0x59a8,0x40},
+	{0x59a9,0x40},
+	{0x59aa,0x40},
+	{0x59ab,0x40},
+	{0x59ac,0x40},
+	{0x59ad,0x40},
+	{0x59ae,0x40},
+	{0x59af,0x40},
+	{0x59b0,0x40},
+	{0x59b1,0x40},
+	{0x59b2,0x40},
+	{0x59b3,0x40},
+	{0x59b4,0x01},
+	{0x59b5,0x02},
+	{0x59b8,0x00},
+	{0x59b9,0x7c},
+	{0x59ba,0x00},
+	{0x59bb,0xa8},
+	{0x59bc,0x12},
+	{0x59bd,0x60},
+	{0x59be,0x0d},
+	{0x59bf,0xd0},
+	{0x59c4,0x00},
+	{0x59c5,0x10},
+	{0x59c6,0x12},
+	{0x59c7,0x50},
+	{0x59c8,0x00},
+	{0x59c9,0x08},
+	{0x59ca,0x0d},
+	{0x59cb,0xb8},
+	{0x59dc,0x20},
+	{0x59de,0x20},
+	{0x59ec,0x20},
+	{0x59ee,0x20},
+	{0x59fd,0x20},
+	{0x59ff,0x20},
+	{0x5a0d,0x20},
+	{0x5a0f,0x20},
+	{0x5a1c,0x20},
+	{0x5a1e,0x20},
+	{0x5a2c,0x20},
+	{0x5a2e,0x20},
+	{0x5a3d,0x20},
+	{0x5a3f,0x20},
+	{0x5a4d,0x20},
+	{0x5a4f,0x20},
+	{0x5a64,0x08},
+	{0x5a68,0x08},
+	{0x5a84,0x0c},
+	{0x5a88,0x0c},
+	{0x5aa6,0x08},
+	{0x5aaa,0x08},
+	{0x5ac6,0x0c},
+	{0x5aca,0x0c},
+	{0x5ae4,0x08},
+	{0x5ae8,0x08},
+	{0x5b04,0x0c},
+	{0x5b08,0x0c},
+	{0x5b26,0x08},
+	{0x5b2a,0x08},
+	{0x5b46,0x0c},
+	{0x5b4a,0x0c},
+	{0x5b56,0x00},
+	{0x5b57,0x0b},
+	{REG_NULL, 0x00},
+};
+
+/*
+ * Xclk 24Mhz
+ * max_framerate 30fps
+ * resolution = 4672*3504
+ * bayer pattern = BGGR"
+*/
+static const struct regval ov16885_4672x3504_30fps_regs[] = {
+	{0x0304,0x4b},
+	{0x3501,0xec},
+	{0x3511,0xec},
+	{0x3600,0x00},
+	{0x3602,0x86},
+	{0x3621,0x88},
+	{0x366c,0x53},
+	{0x3701,0x0e},
+	{0x3726,0x20},
+	{0x3709,0x30},
+	{0x3800,0x00},
+	{0x3801,0x00},
+	{0x3802,0x00},
+	{0x3803,0x00},
+	{0x3804,0x12},
+	{0x3805,0x5f},
+	{0x3806,0x0d},
+	{0x3807,0xcf},
+	{0x3808,0x12},
+	{0x3809,0x40},
+	{0x380a,0x0d},
+	{0x380b,0xb0},
+	{0x380c,0x05},
+	{0x380d,0x78},
+	{0x380e,0x0e},
+	{0x380f,0xe0},
+	{0x3811,0x11},
+	{0x3813,0x08},
+	{0x3815,0x11},
+	{0x3820,0x00},
+	{0x3834,0xf0},
+	{0x3f03,0x10},
+	{0x3f05,0x66},
+	{0x4013,0x28},
+	{0x4014,0x10},
+	{0x4016,0x25},
+	{0x4018,0x0f},
+	{0x4500,0x00},
+	{0x4501,0x05},
+	{0x4503,0x31},
+	{0x4837,0x0b},
+	{0x5000,0x8b},
+	{0x5001,0x52},
+	{0x583e,0x03},
+	{REG_NULL, 0x00},
+};
+
+static const struct ov16885_mode supported_modes[] = {
+	{
+		.width = 4672,
+		.height = 3504,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 300000,
+		},
+		.exp_def = 0x0e40,
+		.hts_def = 0x0578 * 4,
+		.vts_def = 0x0ee0,
+		.bpp = 10,
+		.reg_list = ov16885_4672x3504_30fps_regs,
+		.link_freq_idx = 0,
+		.hdr_mode = NO_HDR,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	},
+};
+
+static const s64 link_freq_items[] = {
+	OV16885_LINK_FREQ_736MHZ,
+};
+
+static const char * const ov16885_test_pattern_menu[] = {
+	"Disabled",
+	"Vertical Color Bar Type 1",
+	"Vertical Color Bar Type 2",
+	"Vertical Color Bar Type 3",
+	"Vertical Color Bar Type 4"
+};
+
+/* Write registers up to 4 at a time */
+static int ov16885_write_reg(struct i2c_client *client, u16 reg,
+			     u32 len, u32 val)
+{
+	u32 buf_i, val_i;
+	u8 buf[6];
+	u8 *val_p;
+	__be32 val_be;
+
+	dev_dbg(&client->dev, "write reg(0x%x val:0x%x)!\n", reg, val);
+
+	if (len > 4)
+		return -EINVAL;
+
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xff;
+
+	val_be = cpu_to_be32(val);
+	val_p = (u8 *)&val_be;
+	buf_i = 2;
+	val_i = 4 - len;
+
+	while (val_i < 4)
+		buf[buf_i++] = val_p[val_i++];
+
+	if (i2c_master_send(client, buf, len + 2) != len + 2)
+		return -EIO;
+
+	return 0;
+}
+
+static int ov16885_write_array(struct i2c_client *client,
+			       const struct regval *regs)
+{
+	u32 i;
+	int ret = 0;
+
+	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++)
+		ret = ov16885_write_reg(client, regs[i].addr,
+					OV16885_REG_VALUE_08BIT,
+					regs[i].val);
+
+	return ret;
+}
+
+/* Read registers up to 4 at a time */
+static int ov16885_read_reg(struct i2c_client *client, u16 reg,
+			    unsigned int len, u32 *val)
+{
+	struct i2c_msg msgs[2];
+	u8 *data_be_p;
+	__be32 data_be = 0;
+	__be16 reg_addr_be = cpu_to_be16(reg);
+	int ret;
+
+	if (len > 4 || !len)
+		return -EINVAL;
+
+	data_be_p = (u8 *)&data_be;
+	/* Write register address */
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = 2;
+	msgs[0].buf = (u8 *)&reg_addr_be;
+
+	/* Read data from register */
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = len;
+	msgs[1].buf = &data_be_p[4 - len];
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs))
+		return -EIO;
+
+	*val = be32_to_cpu(data_be);
+
+	return 0;
+}
+
+static int ov16885_get_reso_dist(const struct ov16885_mode *mode,
+				 struct v4l2_mbus_framefmt *framefmt)
+{
+	return abs(mode->width - framefmt->width) +
+	       abs(mode->height - framefmt->height);
+}
+
+static const struct ov16885_mode *
+ov16885_find_best_fit(struct v4l2_subdev_format *fmt)
+{
+	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
+	int dist;
+	int cur_best_fit = 0;
+	int cur_best_fit_dist = -1;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+		dist = ov16885_get_reso_dist(&supported_modes[i], framefmt);
+		if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
+			cur_best_fit_dist = dist;
+			cur_best_fit = i;
+		}
+	}
+
+	return &supported_modes[cur_best_fit];
+}
+
+static int ov16885_set_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg,
+			  struct v4l2_subdev_format *fmt)
+{
+	struct ov16885 *ov16885 = to_ov16885(sd);
+	const struct ov16885_mode *mode;
+	s64 h_blank, vblank_def;
+	u64 pixel_rate = 0;
+	u32 lane_num = OV16885_LANES;
+
+	mutex_lock(&ov16885->mutex);
+
+	mode = ov16885_find_best_fit(fmt);
+	fmt->format.code = OV16885_MEDIA_BUS_FMT;
+	fmt->format.width = mode->width;
+	fmt->format.height = mode->height;
+	fmt->format.field = V4L2_FIELD_NONE;
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+#else
+		mutex_unlock(&ov16885->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		ov16885->cur_mode = mode;
+		h_blank = mode->hts_def - mode->width;
+		__v4l2_ctrl_modify_range(ov16885->hblank, h_blank,
+					 h_blank, 1, h_blank);
+		vblank_def = mode->vts_def - mode->height;
+		__v4l2_ctrl_modify_range(ov16885->vblank, vblank_def,
+					 OV16885_VTS_MAX - mode->height,
+					 1, vblank_def);
+		__v4l2_ctrl_s_ctrl(ov16885->vblank, vblank_def);
+		pixel_rate = (u32)link_freq_items[mode->link_freq_idx] / mode->bpp * 2 * lane_num;
+
+		__v4l2_ctrl_s_ctrl_int64(ov16885->pixel_rate,
+					 pixel_rate);
+		__v4l2_ctrl_s_ctrl(ov16885->link_freq,
+				   mode->link_freq_idx);
+	}
+	dev_info(&ov16885->client->dev, "%s: mode->link_freq_idx(%d)",
+		 __func__, mode->link_freq_idx);
+
+	mutex_unlock(&ov16885->mutex);
+
+	return 0;
+}
+
+static int ov16885_get_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct ov16885 *ov16885 = to_ov16885(sd);
+	const struct ov16885_mode *mode = ov16885->cur_mode;
+
+	mutex_lock(&ov16885->mutex);
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+#else
+		mutex_unlock(&ov16885->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		fmt->format.width = mode->width;
+		fmt->format.height = mode->height;
+		fmt->format.code = OV16885_MEDIA_BUS_FMT;
+		fmt->format.field = V4L2_FIELD_NONE;
+		if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
+			fmt->reserved[0] = mode->vc[fmt->pad];
+		else
+			fmt->reserved[0] = mode->vc[PAD0];
+	}
+	mutex_unlock(&ov16885->mutex);
+
+	return 0;
+}
+
+static int ov16885_enum_mbus_code(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_pad_config *cfg,
+				  struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index != 0)
+		return -EINVAL;
+	code->code = OV16885_MEDIA_BUS_FMT;
+
+	return 0;
+}
+
+static int ov16885_enum_frame_sizes(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_pad_config *cfg,
+				   struct v4l2_subdev_frame_size_enum *fse)
+{
+	struct ov16885 *ov16885 = to_ov16885(sd);
+
+	if (fse->index >= ov16885->cfg_num)
+		return -EINVAL;
+
+	if (fse->code != OV16885_MEDIA_BUS_FMT)
+		return -EINVAL;
+
+	fse->min_width  = supported_modes[fse->index].width;
+	fse->max_width  = supported_modes[fse->index].width;
+	fse->max_height = supported_modes[fse->index].height;
+	fse->min_height = supported_modes[fse->index].height;
+
+	return 0;
+}
+
+static int ov16885_enable_test_pattern(struct ov16885 *ov16885, u32 pattern)
+{
+	u32 val;
+
+	if (pattern)
+		val = ((pattern - 1) << 4) | OV16885_TEST_PATTERN_ENABLE;
+	else
+		val = OV16885_TEST_PATTERN_DISABLE;
+
+	return ov16885_write_reg(ov16885->client,
+				 OV16885_REG_TEST_PATTERN,
+				 OV16885_REG_VALUE_08BIT,
+				 val);
+}
+
+static int ov16885_g_frame_interval(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_frame_interval *fi)
+{
+	struct ov16885 *ov16885 = to_ov16885(sd);
+	const struct ov16885_mode *mode = ov16885->cur_mode;
+
+	fi->interval = mode->max_fps;
+
+	return 0;
+}
+
+static void ov16885_get_module_inf(struct ov16885 *ov16885,
+				   struct rkmodule_inf *inf)
+{
+	memset(inf, 0, sizeof(*inf));
+	strscpy(inf->base.sensor, OV16885_NAME, sizeof(inf->base.sensor));
+	strscpy(inf->base.module, ov16885->module_name,
+		sizeof(inf->base.module));
+	strscpy(inf->base.lens, ov16885->len_name, sizeof(inf->base.lens));
+}
+
+static long ov16885_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	struct ov16885 *ov16885 = to_ov16885(sd);
+	struct rkmodule_hdr_cfg *hdr_cfg;
+	long ret = 0;
+	u32 i, h, w;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_SET_HDR_CFG:
+		hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
+		w = ov16885->cur_mode->width;
+		h = ov16885->cur_mode->height;
+		for (i = 0; i < ov16885->cfg_num; i++) {
+			if (w == supported_modes[i].width &&
+			h == supported_modes[i].height &&
+			supported_modes[i].hdr_mode == hdr_cfg->hdr_mode) {
+				ov16885->cur_mode = &supported_modes[i];
+				break;
+			}
+		}
+		if (i == ov16885->cfg_num) {
+			dev_err(&ov16885->client->dev,
+				"not find hdr mode:%d %dx%d config\n",
+				hdr_cfg->hdr_mode, w, h);
+			ret = -EINVAL;
+		} else {
+			w = ov16885->cur_mode->hts_def - ov16885->cur_mode->width;
+			h = ov16885->cur_mode->vts_def - ov16885->cur_mode->height;
+			mutex_lock(&ov16885->mutex);
+			__v4l2_ctrl_modify_range(ov16885->hblank, w, w, 1, w);
+			__v4l2_ctrl_modify_range(ov16885->vblank, h,
+						 OV16885_VTS_MAX - ov16885->cur_mode->height,
+						 1, h);
+			mutex_unlock(&ov16885->mutex);
+			dev_info(&ov16885->client->dev,
+				"sensor mode: %d\n",
+				ov16885->cur_mode->hdr_mode);
+		}
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
+		hdr_cfg->esp.mode = HDR_NORMAL_VC;
+		hdr_cfg->hdr_mode = ov16885->cur_mode->hdr_mode;
+		break;
+	case RKMODULE_GET_MODULE_INFO:
+		ov16885_get_module_inf(ov16885, (struct rkmodule_inf *)arg);
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+
+		stream = *((u32 *)arg);
+
+		if (stream)
+			ret = ov16885_write_reg(ov16885->client,
+				 OV16885_REG_CTRL_MODE,
+				 OV16885_REG_VALUE_08BIT,
+				 OV16885_MODE_STREAMING);
+		else
+			ret = ov16885_write_reg(ov16885->client,
+				 OV16885_REG_CTRL_MODE,
+				 OV16885_REG_VALUE_08BIT,
+				 OV16885_MODE_SW_STANDBY);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long ov16885_compat_ioctl32(struct v4l2_subdev *sd,
+				   unsigned int cmd, unsigned long arg)
+{
+	void __user *up = compat_ptr(arg);
+	struct rkmodule_inf *inf;
+	struct rkmodule_awb_cfg *cfg;
+	struct rkmodule_hdr_cfg *hdr;
+	long ret = 0;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
+		if (!inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = ov16885_ioctl(sd, cmd, inf);
+		if (!ret) {
+			ret = copy_to_user(up, inf, sizeof(*inf));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(inf);
+		break;
+	case RKMODULE_AWB_CFG:
+		cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+		if (!cfg) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(cfg, up, sizeof(*cfg));
+		if (!ret)
+			ret = ov16885_ioctl(sd, cmd, cfg);
+		else
+			ret = -EFAULT;
+		kfree(cfg);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = ov16885_ioctl(sd, cmd, hdr);
+		if (!ret) {
+			if (copy_to_user(up, hdr, sizeof(*hdr))) {
+				kfree(hdr);
+				return -EFAULT;
+			}
+		}
+		kfree(hdr);
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		if (copy_from_user(hdr, up, sizeof(*hdr))) {
+			kfree(hdr);
+			return -EFAULT;
+		}
+		ret = ov16885_ioctl(sd, cmd, hdr);
+		kfree(hdr);
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		ret = copy_from_user(&stream, up, sizeof(u32));
+		if (!ret)
+			ret = ov16885_ioctl(sd, cmd, &stream);
+		else
+			ret = -EFAULT;
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+#endif
+
+static int __ov16885_start_stream(struct ov16885 *ov16885)
+{
+	int ret;
+
+	ret = ov16885_write_array(ov16885->client, ov16885->cur_mode->reg_list);
+	if (ret)
+		return ret;
+
+	/* In case these controls are set before streaming */
+	mutex_unlock(&ov16885->mutex);
+	ret = v4l2_ctrl_handler_setup(&ov16885->ctrl_handler);
+	mutex_lock(&ov16885->mutex);
+	if (ret)
+		return ret;
+
+	return ov16885_write_reg(ov16885->client,
+				 OV16885_REG_CTRL_MODE,
+				 OV16885_REG_VALUE_08BIT,
+				 OV16885_MODE_STREAMING);
+}
+
+static int __ov16885_stop_stream(struct ov16885 *ov16885)
+{
+	return ov16885_write_reg(ov16885->client,
+				 OV16885_REG_CTRL_MODE,
+				 OV16885_REG_VALUE_08BIT,
+				 OV16885_MODE_SW_STANDBY);
+}
+
+static int ov16885_s_stream(struct v4l2_subdev *sd, int on)
+{
+	struct ov16885 *ov16885 = to_ov16885(sd);
+	struct i2c_client *client = ov16885->client;
+	int ret = 0;
+
+	dev_info(&client->dev, "%s: on: %d, %dx%d@%d\n", __func__, on,
+				ov16885->cur_mode->width,
+				ov16885->cur_mode->height,
+		DIV_ROUND_CLOSEST(ov16885->cur_mode->max_fps.denominator,
+				  ov16885->cur_mode->max_fps.numerator));
+
+	mutex_lock(&ov16885->mutex);
+	on = !!on;
+	if (on == ov16885->streaming)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		ret = __ov16885_start_stream(ov16885);
+		if (ret) {
+			v4l2_err(sd, "start stream failed while write regs\n");
+			pm_runtime_put(&client->dev);
+			goto unlock_and_return;
+		}
+	} else {
+		__ov16885_stop_stream(ov16885);
+		pm_runtime_put(&client->dev);
+	}
+
+	ov16885->streaming = on;
+
+unlock_and_return:
+	mutex_unlock(&ov16885->mutex);
+
+	return ret;
+}
+
+static int ov16885_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct ov16885 *ov16885 = to_ov16885(sd);
+	struct i2c_client *client = ov16885->client;
+	int ret = 0;
+
+	mutex_lock(&ov16885->mutex);
+
+	/* If the power state is not modified - no work to do. */
+	if (ov16885->power_on == !!on)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		ret = ov16885_write_array(ov16885->client, ov16885_global_regs);
+		if (ret) {
+			v4l2_err(sd, "could not set init registers\n");
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		ov16885->power_on = true;
+	} else {
+		pm_runtime_put(&client->dev);
+		ov16885->power_on = false;
+	}
+
+unlock_and_return:
+	mutex_unlock(&ov16885->mutex);
+
+	return ret;
+}
+
+/* Calculate the delay in us by clock rate and clock cycles */
+static inline u32 ov16885_cal_delay(u32 cycles)
+{
+	return DIV_ROUND_UP(cycles, OV16885_XVCLK_FREQ / 1000 / 1000);
+}
+
+static int __ov16885_power_on(struct ov16885 *ov16885)
+{
+	int ret;
+	u32 delay_us;
+	struct device *dev = &ov16885->client->dev;
+
+	if (!IS_ERR(ov16885->power_gpio))
+		gpiod_set_value_cansleep(ov16885->power_gpio, 1);
+
+	usleep_range(1000, 2000);
+
+	if (!IS_ERR_OR_NULL(ov16885->pins_default)) {
+		ret = pinctrl_select_state(ov16885->pinctrl,
+					   ov16885->pins_default);
+		if (ret < 0)
+			dev_err(dev, "could not set pins\n");
+	}
+	ret = clk_set_rate(ov16885->xvclk, OV16885_XVCLK_FREQ);
+	if (ret < 0)
+		dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
+	if (clk_get_rate(ov16885->xvclk) != OV16885_XVCLK_FREQ)
+		dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
+	ret = clk_prepare_enable(ov16885->xvclk);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable xvclk\n");
+		return ret;
+	}
+	if (!IS_ERR(ov16885->reset_gpio))
+		gpiod_set_value_cansleep(ov16885->reset_gpio, 0);
+
+	ret = regulator_bulk_enable(OV16885_NUM_SUPPLIES, ov16885->supplies);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable regulators\n");
+		goto disable_clk;
+	}
+
+	if (!IS_ERR(ov16885->reset_gpio))
+		gpiod_set_value_cansleep(ov16885->reset_gpio, 1);
+
+	usleep_range(5000, 6000);
+	if (!IS_ERR(ov16885->pwdn_gpio))
+		gpiod_set_value_cansleep(ov16885->pwdn_gpio, 1);
+
+	/* 8192 cycles prior to first SCCB transaction */
+	delay_us = ov16885_cal_delay(8192);
+	usleep_range(delay_us * 2, delay_us * 3);
+
+	return 0;
+
+disable_clk:
+	clk_disable_unprepare(ov16885->xvclk);
+
+	return ret;
+}
+
+static void __ov16885_power_off(struct ov16885 *ov16885)
+{
+	int ret;
+	struct device *dev = &ov16885->client->dev;
+
+	if (!IS_ERR(ov16885->pwdn_gpio))
+		gpiod_set_value_cansleep(ov16885->pwdn_gpio, 0);
+	clk_disable_unprepare(ov16885->xvclk);
+	if (!IS_ERR(ov16885->reset_gpio))
+		gpiod_set_value_cansleep(ov16885->reset_gpio, 0);
+
+	if (!IS_ERR_OR_NULL(ov16885->pins_sleep)) {
+		ret = pinctrl_select_state(ov16885->pinctrl,
+					   ov16885->pins_sleep);
+		if (ret < 0)
+			dev_dbg(dev, "could not set pins\n");
+	}
+	if (!IS_ERR(ov16885->power_gpio))
+		gpiod_set_value_cansleep(ov16885->power_gpio, 0);
+
+	regulator_bulk_disable(OV16885_NUM_SUPPLIES, ov16885->supplies);
+}
+
+static int ov16885_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ov16885 *ov16885 = to_ov16885(sd);
+
+	return __ov16885_power_on(ov16885);
+}
+
+static int ov16885_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ov16885 *ov16885 = to_ov16885(sd);
+
+	__ov16885_power_off(ov16885);
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int ov16885_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct ov16885 *ov16885 = to_ov16885(sd);
+	struct v4l2_mbus_framefmt *try_fmt =
+				v4l2_subdev_get_try_format(sd, fh->pad, 0);
+	const struct ov16885_mode *def_mode = &supported_modes[0];
+
+	mutex_lock(&ov16885->mutex);
+	/* Initialize try_fmt */
+	try_fmt->width = def_mode->width;
+	try_fmt->height = def_mode->height;
+	try_fmt->code = OV16885_MEDIA_BUS_FMT;
+	try_fmt->field = V4L2_FIELD_NONE;
+
+	mutex_unlock(&ov16885->mutex);
+	/* No crop or compose */
+
+	return 0;
+}
+#endif
+
+static int ov16885_enum_frame_interval(struct v4l2_subdev *sd,
+				       struct v4l2_subdev_pad_config *cfg,
+				       struct v4l2_subdev_frame_interval_enum *fie)
+{
+	if (fie->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	fie->code = OV16885_MEDIA_BUS_FMT;
+	fie->width = supported_modes[fie->index].width;
+	fie->height = supported_modes[fie->index].height;
+	fie->interval = supported_modes[fie->index].max_fps;
+	fie->reserved[0] = supported_modes[fie->index].hdr_mode;
+
+	return 0;
+}
+
+static int ov16885_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
+				struct v4l2_mbus_config *config)
+{
+	if (2 == OV16885_LANES) {
+		config->type = V4L2_MBUS_CSI2_DPHY;
+		config->flags = V4L2_MBUS_CSI2_2_LANE |
+				V4L2_MBUS_CSI2_CHANNEL_0 |
+				V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+	} else if (4 == OV16885_LANES) {
+		config->type = V4L2_MBUS_CSI2_DPHY;
+		config->flags = V4L2_MBUS_CSI2_4_LANE |
+				V4L2_MBUS_CSI2_CHANNEL_0 |
+				V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+	}
+
+	return 0;
+}
+
+#define CROP_START(SRC, DST) (((SRC) - (DST)) / 2 / 4 * 4)
+#define DST_WIDTH_2320 2320
+#define DST_HEIGHT_1744 1744
+/*
+ * The resolution of the driver configuration needs to be exactly
+ * the same as the current output resolution of the sensor,
+ * the input width of the isp needs to be 16 aligned,
+ * the input height of the isp needs to be 8 aligned.
+ * Can be cropped to standard resolution by this function,
+ * otherwise it will crop out strange resolution according
+ * to the alignment rules.
+ */
+static int ov16885_get_selection(struct v4l2_subdev *sd,
+				struct v4l2_subdev_pad_config *cfg,
+				struct v4l2_subdev_selection *sel)
+{
+	struct ov16885 *ov16885 = to_ov16885(sd);
+
+	if (sel->target == V4L2_SEL_TGT_CROP_BOUNDS) {
+		if (ov16885->cur_mode->width == 2328) {
+			sel->r.left = CROP_START(ov16885->cur_mode->width, DST_WIDTH_2320);
+			sel->r.width = DST_WIDTH_2320;
+			sel->r.top = CROP_START(ov16885->cur_mode->height, DST_HEIGHT_1744);
+			sel->r.height = DST_HEIGHT_1744;
+		} else {
+			sel->r.left = 0;
+			sel->r.width = ov16885->cur_mode->width;
+			sel->r.top = 0;
+			sel->r.height = ov16885->cur_mode->height;
+		}
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static const struct dev_pm_ops ov16885_pm_ops = {
+	SET_RUNTIME_PM_OPS(ov16885_runtime_suspend,
+			   ov16885_runtime_resume, NULL)
+};
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static const struct v4l2_subdev_internal_ops ov16885_internal_ops = {
+	.open = ov16885_open,
+};
+#endif
+
+static const struct v4l2_subdev_core_ops ov16885_core_ops = {
+	.s_power = ov16885_s_power,
+	.ioctl = ov16885_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl32 = ov16885_compat_ioctl32,
+#endif
+};
+
+static const struct v4l2_subdev_video_ops ov16885_video_ops = {
+	.s_stream = ov16885_s_stream,
+	.g_frame_interval = ov16885_g_frame_interval,
+};
+
+static const struct v4l2_subdev_pad_ops ov16885_pad_ops = {
+	.enum_mbus_code = ov16885_enum_mbus_code,
+	.enum_frame_size = ov16885_enum_frame_sizes,
+	.enum_frame_interval = ov16885_enum_frame_interval,
+	.get_fmt = ov16885_get_fmt,
+	.set_fmt = ov16885_set_fmt,
+	.get_selection = ov16885_get_selection,
+	.get_mbus_config = ov16885_g_mbus_config,
+};
+
+static const struct v4l2_subdev_ops ov16885_subdev_ops = {
+	.core	= &ov16885_core_ops,
+	.video	= &ov16885_video_ops,
+	.pad	= &ov16885_pad_ops,
+};
+
+static int ov16885_set_gain_reg(struct ov16885 *ov16885, u32 a_gain)
+{
+	int ret = 0;
+
+	ret = ov16885_write_reg(ov16885->client,
+				 OV16885_GROUP_UPDATE_ADDRESS,
+				 OV16885_REG_VALUE_08BIT,
+				 OV16885_GROUP_UPDATE_START_DATA);
+
+	ret |= ov16885_write_reg(ov16885->client,
+				 OV16885_SF_AGAIN_REG_H,
+				 OV16885_REG_VALUE_16BIT,
+				 a_gain & 0x1fff);
+	ret |= ov16885_write_reg(ov16885->client,
+				 OV16885_LF_AGAIN_REG_H,
+				 OV16885_REG_VALUE_16BIT,
+				 a_gain & 0x1fff);
+	ret |= ov16885_write_reg(ov16885->client,
+				 OV16885_GROUP_UPDATE_ADDRESS,
+				 OV16885_REG_VALUE_08BIT,
+				 OV16885_GROUP_UPDATE_END_DATA);
+	ret |= ov16885_write_reg(ov16885->client,
+				 OV16885_GROUP_UPDATE_ADDRESS,
+				 OV16885_REG_VALUE_08BIT,
+				 OV16885_GROUP_UPDATE_LAUNCH);
+	return ret;
+
+};
+
+static int ov16885_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct ov16885 *ov16885 = container_of(ctrl->handler,
+					     struct ov16885, ctrl_handler);
+	struct i2c_client *client = ov16885->client;
+	s64 max;
+	int ret = 0;
+	u32 val = 0, x_win = 0;
+
+	/* Propagate change of current control to all related controls */
+	switch (ctrl->id) {
+	case V4L2_CID_VBLANK:
+		/* Update max exposure while meeting expected vblanking */
+		max = ov16885->cur_mode->height + ctrl->val - 12;
+		__v4l2_ctrl_modify_range(ov16885->exposure,
+					 ov16885->exposure->minimum, max,
+					 ov16885->exposure->step,
+					 ov16885->exposure->default_value);
+		break;
+	}
+
+	if (!pm_runtime_get_if_in_use(&client->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		/* 4 least significant bits of expsoure are fractional part */
+		ret = ov16885_write_reg(ov16885->client,
+					OV16885_REG_EXPOSURE_H,
+					OV16885_REG_VALUE_24BIT,
+					ctrl->val << 4);
+		dev_dbg(&client->dev, "set exposure 0x%x\n",
+			ctrl->val);
+		break;
+	case V4L2_CID_ANALOGUE_GAIN:
+		ret = ov16885_set_gain_reg(ov16885, ctrl->val);
+		dev_dbg(&client->dev, "set analog gain value 0x%x\n", ctrl->val);
+		break;
+	case V4L2_CID_VBLANK:
+		ret = ov16885_write_reg(ov16885->client,
+					OV16885_REG_VTS_H,
+					OV16885_REG_VALUE_16BIT,
+					ctrl->val + ov16885->cur_mode->height);
+		break;
+	case V4L2_CID_TEST_PATTERN:
+		ret = ov16885_enable_test_pattern(ov16885, ctrl->val);
+		break;
+	case V4L2_CID_HFLIP:
+		ret = ov16885_read_reg(ov16885->client, OV16885_MIRROR_REG,
+				       OV16885_REG_VALUE_08BIT,
+				       &val);
+		if (ctrl->val)
+			val |= MIRROR_BIT_MASK;
+		else
+			val &= ~MIRROR_BIT_MASK;
+
+		ret |= ov16885_read_reg(ov16885->client, OV16885_REG_ISP_X_WIN,
+					OV16885_REG_VALUE_16BIT,
+					&x_win);
+
+		if ((x_win == 0x0010) && (val & 0x04))
+			x_win = 0x0011;
+		else if ((x_win == 0x0011) && (!(val & 0x04)))
+			x_win = 0x0010;
+
+		ret |= ov16885_write_reg(ov16885->client,
+					 OV16885_GROUP_UPDATE_ADDRESS,
+					 OV16885_REG_VALUE_08BIT,
+					 OV16885_GROUP_UPDATE_START_DATA);
+
+		ret |= ov16885_write_reg(ov16885->client, OV16885_MIRROR_REG,
+					 OV16885_REG_VALUE_08BIT,
+					 val);
+		ret |= ov16885_write_reg(ov16885->client, OV16885_REG_ISP_X_WIN,
+					 OV16885_REG_VALUE_16BIT,
+					 x_win);
+
+		ret |= ov16885_write_reg(ov16885->client,
+					 OV16885_GROUP_UPDATE_ADDRESS,
+					 OV16885_REG_VALUE_08BIT,
+					 OV16885_GROUP_UPDATE_END_DATA);
+		ret |= ov16885_write_reg(ov16885->client,
+					 OV16885_GROUP_UPDATE_ADDRESS,
+					 OV16885_REG_VALUE_08BIT,
+					 OV16885_GROUP_UPDATE_LAUNCH);
+		break;
+	case V4L2_CID_VFLIP:
+		ret = ov16885_read_reg(ov16885->client, OV16885_FLIP_REG,
+				       OV16885_REG_VALUE_08BIT,
+				       &val);
+		if (ctrl->val)
+			val |= FLIP_BIT_MASK;
+		else
+			val &= ~FLIP_BIT_MASK;
+		ret |= ov16885_write_reg(ov16885->client, OV16885_FLIP_REG,
+					 OV16885_REG_VALUE_08BIT,
+					 val);
+		break;
+	default:
+		dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
+			 __func__, ctrl->id, ctrl->val);
+		break;
+	}
+
+	pm_runtime_put(&client->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops ov16885_ctrl_ops = {
+	.s_ctrl = ov16885_set_ctrl,
+};
+
+static int ov16885_initialize_controls(struct ov16885 *ov16885)
+{
+	const struct ov16885_mode *mode;
+	struct v4l2_ctrl_handler *handler;
+	s64 exposure_max, vblank_def;
+	u32 h_blank;
+	int ret;
+	u64 dst_pixel_rate = 0;
+	u32 lane_num = OV16885_LANES;
+
+	handler = &ov16885->ctrl_handler;
+	mode = ov16885->cur_mode;
+	ret = v4l2_ctrl_handler_init(handler, 9);
+	if (ret)
+		return ret;
+	handler->lock = &ov16885->mutex;
+
+	ov16885->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
+			V4L2_CID_LINK_FREQ,
+			0, 0, link_freq_items);
+
+	dst_pixel_rate = (u32)link_freq_items[mode->link_freq_idx] / mode->bpp * 2 * lane_num;
+
+	ov16885->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
+			V4L2_CID_PIXEL_RATE,
+			0, OV16885_PIXEL_RATE,
+			1, dst_pixel_rate);
+
+	__v4l2_ctrl_s_ctrl(ov16885->link_freq,
+			   mode->link_freq_idx);
+
+	h_blank = mode->hts_def - mode->width;
+	ov16885->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
+				h_blank, h_blank, 1, h_blank);
+	if (ov16885->hblank)
+		ov16885->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	vblank_def = mode->vts_def - mode->height;
+	ov16885->vblank = v4l2_ctrl_new_std(handler, &ov16885_ctrl_ops,
+				V4L2_CID_VBLANK, vblank_def,
+				OV16885_VTS_MAX - mode->height,
+				1, vblank_def);
+
+	exposure_max = mode->vts_def - 12;
+	ov16885->exposure = v4l2_ctrl_new_std(handler, &ov16885_ctrl_ops,
+				V4L2_CID_EXPOSURE, OV16885_EXPOSURE_MIN,
+				exposure_max, OV16885_EXPOSURE_STEP,
+				mode->exp_def);
+
+	ov16885->anal_gain = v4l2_ctrl_new_std(handler, &ov16885_ctrl_ops,
+				V4L2_CID_ANALOGUE_GAIN, OV16885_GAIN_MIN,
+				OV16885_GAIN_MAX, OV16885_GAIN_STEP,
+				OV16885_GAIN_DEFAULT);
+
+	ov16885->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
+				&ov16885_ctrl_ops, V4L2_CID_TEST_PATTERN,
+				ARRAY_SIZE(ov16885_test_pattern_menu) - 1,
+				0, 0, ov16885_test_pattern_menu);
+
+	ov16885->h_flip = v4l2_ctrl_new_std(handler, &ov16885_ctrl_ops,
+					    V4L2_CID_HFLIP, 0, 1, 1, 0);
+
+	ov16885->v_flip = v4l2_ctrl_new_std(handler, &ov16885_ctrl_ops,
+					    V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+	if (handler->error) {
+		ret = handler->error;
+		dev_err(&ov16885->client->dev,
+			"Failed to init controls(%d)\n", ret);
+		goto err_free_handler;
+	}
+
+	ov16885->subdev.ctrl_handler = handler;
+
+	return 0;
+
+err_free_handler:
+	v4l2_ctrl_handler_free(handler);
+
+	return ret;
+}
+
+static int ov16885_check_sensor_id(struct ov16885 *ov16885,
+				   struct i2c_client *client)
+{
+	struct device *dev = &ov16885->client->dev;
+	u32 id = 0;
+	int ret;
+
+	client->addr = OV16885_MAJOR_I2C_ADDR;
+
+	ret = ov16885_read_reg(client, OV16885_REG_CHIP_ID,
+			       OV16885_REG_VALUE_24BIT, &id);
+	if (id != CHIP_ID) {
+		dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
+		client->addr = OV16885_MINOR_I2C_ADDR;
+		ret = ov16885_read_reg(client, OV16885_REG_CHIP_ID,
+				       OV16885_REG_VALUE_24BIT, &id);
+		if (id != CHIP_ID) {
+			dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
+			return -ENODEV;
+		}
+	}
+
+	dev_info(dev, "Detected OV%06x sensor\n", CHIP_ID);
+
+	return 0;
+}
+
+static int ov16885_configure_regulators(struct ov16885 *ov16885)
+{
+	unsigned int i;
+
+	for (i = 0; i < OV16885_NUM_SUPPLIES; i++)
+		ov16885->supplies[i].supply = ov16885_supply_names[i];
+
+	return devm_regulator_bulk_get(&ov16885->client->dev,
+				       OV16885_NUM_SUPPLIES,
+				       ov16885->supplies);
+}
+
+static int ov16885_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct device_node *node = dev->of_node;
+	struct ov16885 *ov16885;
+	struct v4l2_subdev *sd;
+	char facing[2];
+	int ret;
+	u32 i, hdr_mode = 0;
+
+	dev_info(dev, "driver version: %02x.%02x.%02x",
+		DRIVER_VERSION >> 16,
+		(DRIVER_VERSION & 0xff00) >> 8,
+		DRIVER_VERSION & 0x00ff);
+
+	ov16885 = devm_kzalloc(dev, sizeof(*ov16885), GFP_KERNEL);
+	if (!ov16885)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
+				   &ov16885->module_index);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
+				       &ov16885->module_facing);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
+				       &ov16885->module_name);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
+				       &ov16885->len_name);
+	if (ret) {
+		dev_err(dev, "could not get module information!\n");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(node, OF_CAMERA_HDR_MODE,
+			&hdr_mode);
+	if (ret) {
+		hdr_mode = NO_HDR;
+		dev_warn(dev, " Get hdr mode failed! no hdr default\n");
+	}
+	ov16885->cfg_num = ARRAY_SIZE(supported_modes);
+	for (i = 0; i < ov16885->cfg_num; i++) {
+		if (hdr_mode == supported_modes[i].hdr_mode) {
+			ov16885->cur_mode = &supported_modes[i];
+			break;
+		}
+	}
+
+	ov16885->client = client;
+
+	ov16885->xvclk = devm_clk_get(dev, "xvclk");
+	if (IS_ERR(ov16885->xvclk)) {
+		dev_err(dev, "Failed to get xvclk\n");
+		return -EINVAL;
+	}
+
+	ov16885->power_gpio = devm_gpiod_get(dev, "power", GPIOD_OUT_LOW);
+	if (IS_ERR(ov16885->power_gpio))
+		dev_warn(dev, "Failed to get power-gpios, maybe no use\n");
+
+	ov16885->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(ov16885->reset_gpio))
+		dev_warn(dev, "Failed to get reset-gpios\n");
+
+	ov16885->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
+	if (IS_ERR(ov16885->pwdn_gpio))
+		dev_warn(dev, "Failed to get pwdn-gpios\n");
+
+	ret = ov16885_configure_regulators(ov16885);
+	if (ret) {
+		dev_err(dev, "Failed to get power regulators\n");
+		return ret;
+	}
+
+	ov16885->pinctrl = devm_pinctrl_get(dev);
+	if (!IS_ERR(ov16885->pinctrl)) {
+		ov16885->pins_default =
+			pinctrl_lookup_state(ov16885->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_DEFAULT);
+		if (IS_ERR(ov16885->pins_default))
+			dev_err(dev, "could not get default pinstate\n");
+
+		ov16885->pins_sleep =
+			pinctrl_lookup_state(ov16885->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_SLEEP);
+		if (IS_ERR(ov16885->pins_sleep))
+			dev_err(dev, "could not get sleep pinstate\n");
+	}
+
+	mutex_init(&ov16885->mutex);
+
+	sd = &ov16885->subdev;
+	v4l2_i2c_subdev_init(sd, client, &ov16885_subdev_ops);
+	ret = ov16885_initialize_controls(ov16885);
+	if (ret)
+		goto err_destroy_mutex;
+
+	ret = __ov16885_power_on(ov16885);
+	if (ret)
+		goto err_free_handler;
+
+	ret = ov16885_check_sensor_id(ov16885, client);
+	if (ret)
+		goto err_power_off;
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	sd->internal_ops = &ov16885_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+#endif
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	ov16885->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &ov16885->pad);
+	if (ret < 0)
+		goto err_power_off;
+#endif
+
+	memset(facing, 0, sizeof(facing));
+	if (strcmp(ov16885->module_facing, "back") == 0)
+		facing[0] = 'b';
+	else
+		facing[0] = 'f';
+
+	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
+		 ov16885->module_index, facing,
+		 OV16885_NAME, dev_name(sd->dev));
+	ret = v4l2_async_register_subdev_sensor_common(sd);
+	if (ret) {
+		dev_err(dev, "v4l2 async register subdev failed\n");
+		goto err_clean_entity;
+	}
+
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_idle(dev);
+
+	return 0;
+
+err_clean_entity:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+err_power_off:
+	__ov16885_power_off(ov16885);
+err_free_handler:
+	v4l2_ctrl_handler_free(&ov16885->ctrl_handler);
+err_destroy_mutex:
+	mutex_destroy(&ov16885->mutex);
+
+	return ret;
+}
+
+static int ov16885_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ov16885 *ov16885 = to_ov16885(sd);
+
+	v4l2_async_unregister_subdev(sd);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+	v4l2_ctrl_handler_free(&ov16885->ctrl_handler);
+	mutex_destroy(&ov16885->mutex);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		__ov16885_power_off(ov16885);
+	pm_runtime_set_suspended(&client->dev);
+
+	return 0;
+}
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id ov16885_of_match[] = {
+	{ .compatible = "ovti,ov16885" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, ov16885_of_match);
+#endif
+
+static const struct i2c_device_id ov16885_match_id[] = {
+	{ "ovti,ov16885", 0 },
+	{},
+};
+
+static struct i2c_driver ov16885_i2c_driver = {
+	.driver = {
+		.name = OV16885_NAME,
+		.pm = &ov16885_pm_ops,
+		.of_match_table = of_match_ptr(ov16885_of_match),
+	},
+	.probe		= &ov16885_probe,
+	.remove		= &ov16885_remove,
+	.id_table	= ov16885_match_id,
+};
+
+static int __init sensor_mod_init(void)
+{
+	return i2c_add_driver(&ov16885_i2c_driver);
+}
+
+static void __exit sensor_mod_exit(void)
+{
+	i2c_del_driver(&ov16885_i2c_driver);
+}
+
+device_initcall_sync(sensor_mod_init);
+module_exit(sensor_mod_exit);
+
+MODULE_DESCRIPTION("OmniVision ov16885 sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/ov2680.c b/kernel/drivers/media/i2c/ov2680.c
index 59cdbc3..731a60f 100644
--- a/kernel/drivers/media/i2c/ov2680.c
+++ b/kernel/drivers/media/i2c/ov2680.c
@@ -85,15 +85,8 @@
 
 struct ov2680_ctrls {
 	struct v4l2_ctrl_handler handler;
-	struct {
-		struct v4l2_ctrl *auto_exp;
-		struct v4l2_ctrl *exposure;
-	};
-	struct {
-		struct v4l2_ctrl *auto_gain;
-		struct v4l2_ctrl *gain;
-	};
-
+	struct v4l2_ctrl *exposure;
+	struct v4l2_ctrl *gain;
 	struct v4l2_ctrl *hflip;
 	struct v4l2_ctrl *vflip;
 	struct v4l2_ctrl *test_pattern;
@@ -143,6 +136,7 @@
 	{0x380e, 0x02}, {0x380f, 0x84}, {0x3811, 0x04}, {0x3813, 0x04},
 	{0x3814, 0x31}, {0x3815, 0x31}, {0x3820, 0xc0}, {0x4008, 0x00},
 	{0x4009, 0x03}, {0x4837, 0x1e}, {0x3501, 0x4e}, {0x3502, 0xe0},
+	{0x3503, 0x03},
 };
 
 static const struct reg_value ov2680_setting_30fps_720P_1280_720[] = {
@@ -321,70 +315,49 @@
 	usleep_range(5000, 10000);
 }
 
-static int ov2680_bayer_order(struct ov2680_dev *sensor)
+static void ov2680_set_bayer_order(struct ov2680_dev *sensor)
 {
-	u32 format1;
-	u32 format2;
-	u32 hv_flip;
-	int ret;
+	int hv_flip = 0;
 
-	ret = ov2680_read_reg(sensor, OV2680_REG_FORMAT1, &format1);
-	if (ret < 0)
-		return ret;
+	if (sensor->ctrls.vflip && sensor->ctrls.vflip->val)
+		hv_flip += 1;
 
-	ret = ov2680_read_reg(sensor, OV2680_REG_FORMAT2, &format2);
-	if (ret < 0)
-		return ret;
-
-	hv_flip = (format2 & BIT(2)  << 1) | (format1 & BIT(2));
+	if (sensor->ctrls.hflip && sensor->ctrls.hflip->val)
+		hv_flip += 2;
 
 	sensor->fmt.code = ov2680_hv_flip_bayer_order[hv_flip];
+}
 
+static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val)
+{
+	int ret;
+
+	if (sensor->is_streaming)
+		return -EBUSY;
+
+	ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1,
+			     BIT(2), val ? BIT(2) : 0);
+	if (ret < 0)
+		return ret;
+
+	ov2680_set_bayer_order(sensor);
 	return 0;
 }
 
-static int ov2680_vflip_enable(struct ov2680_dev *sensor)
+static int ov2680_set_hflip(struct ov2680_dev *sensor, s32 val)
 {
 	int ret;
 
-	ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, BIT(2), BIT(2));
+	if (sensor->is_streaming)
+		return -EBUSY;
+
+	ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2,
+			     BIT(2), val ? BIT(2) : 0);
 	if (ret < 0)
 		return ret;
 
-	return ov2680_bayer_order(sensor);
-}
-
-static int ov2680_vflip_disable(struct ov2680_dev *sensor)
-{
-	int ret;
-
-	ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, BIT(2), BIT(0));
-	if (ret < 0)
-		return ret;
-
-	return ov2680_bayer_order(sensor);
-}
-
-static int ov2680_hflip_enable(struct ov2680_dev *sensor)
-{
-	int ret;
-
-	ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, BIT(2), BIT(2));
-	if (ret < 0)
-		return ret;
-
-	return ov2680_bayer_order(sensor);
-}
-
-static int ov2680_hflip_disable(struct ov2680_dev *sensor)
-{
-	int ret;
-
-	ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, BIT(2), BIT(0));
-	if (ret < 0)
-		return ret;
-
-	return ov2680_bayer_order(sensor);
+	ov2680_set_bayer_order(sensor);
+	return 0;
 }
 
 static int ov2680_test_pattern_set(struct ov2680_dev *sensor, int value)
@@ -405,69 +378,15 @@
 	return 0;
 }
 
-static int ov2680_gain_set(struct ov2680_dev *sensor, bool auto_gain)
+static int ov2680_gain_set(struct ov2680_dev *sensor, u32 gain)
 {
-	struct ov2680_ctrls *ctrls = &sensor->ctrls;
-	u32 gain;
-	int ret;
-
-	ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(1),
-			     auto_gain ? 0 : BIT(1));
-	if (ret < 0)
-		return ret;
-
-	if (auto_gain || !ctrls->gain->is_new)
-		return 0;
-
-	gain = ctrls->gain->val;
-
-	ret = ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain);
-
-	return 0;
+	return ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain);
 }
 
-static int ov2680_gain_get(struct ov2680_dev *sensor)
+static int ov2680_exposure_set(struct ov2680_dev *sensor, u32 exp)
 {
-	u32 gain;
-	int ret;
-
-	ret = ov2680_read_reg16(sensor, OV2680_REG_GAIN_PK, &gain);
-	if (ret)
-		return ret;
-
-	return gain;
-}
-
-static int ov2680_exposure_set(struct ov2680_dev *sensor, bool auto_exp)
-{
-	struct ov2680_ctrls *ctrls = &sensor->ctrls;
-	u32 exp;
-	int ret;
-
-	ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(0),
-			     auto_exp ? 0 : BIT(0));
-	if (ret < 0)
-		return ret;
-
-	if (auto_exp || !ctrls->exposure->is_new)
-		return 0;
-
-	exp = (u32)ctrls->exposure->val;
-	exp <<= 4;
-
-	return ov2680_write_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, exp);
-}
-
-static int ov2680_exposure_get(struct ov2680_dev *sensor)
-{
-	int ret;
-	u32 exp;
-
-	ret = ov2680_read_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, &exp);
-	if (ret)
-		return ret;
-
-	return exp >> 4;
+	return ov2680_write_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH,
+				  exp << 4);
 }
 
 static int ov2680_stream_enable(struct ov2680_dev *sensor)
@@ -482,32 +401,16 @@
 
 static int ov2680_mode_set(struct ov2680_dev *sensor)
 {
-	struct ov2680_ctrls *ctrls = &sensor->ctrls;
 	int ret;
-
-	ret = ov2680_gain_set(sensor, false);
-	if (ret < 0)
-		return ret;
-
-	ret = ov2680_exposure_set(sensor, false);
-	if (ret < 0)
-		return ret;
 
 	ret = ov2680_load_regs(sensor, sensor->current_mode);
 	if (ret < 0)
 		return ret;
 
-	if (ctrls->auto_gain->val) {
-		ret = ov2680_gain_set(sensor, true);
-		if (ret < 0)
-			return ret;
-	}
-
-	if (ctrls->auto_exp->val == V4L2_EXPOSURE_AUTO) {
-		ret = ov2680_exposure_set(sensor, true);
-		if (ret < 0)
-			return ret;
-	}
+	/* Restore value of all ctrls */
+	ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
+	if (ret < 0)
+		return ret;
 
 	sensor->mode_pending_changes = false;
 
@@ -556,7 +459,7 @@
 		ret = ov2680_write_reg(sensor, OV2680_REG_SOFT_RESET, 0x01);
 		if (ret != 0) {
 			dev_err(dev, "sensor soft reset failed\n");
-			return ret;
+			goto err_disable_regulators;
 		}
 		usleep_range(1000, 2000);
 	} else {
@@ -566,7 +469,7 @@
 
 	ret = clk_prepare_enable(sensor->xvclk);
 	if (ret < 0)
-		return ret;
+		goto err_disable_regulators;
 
 	sensor->is_enabled = true;
 
@@ -576,6 +479,10 @@
 	ov2680_stream_disable(sensor);
 
 	return 0;
+
+err_disable_regulators:
+	regulator_bulk_disable(OV2680_NUM_SUPPLIES, sensor->supplies);
+	return ret;
 }
 
 static int ov2680_s_power(struct v4l2_subdev *sd, int on)
@@ -590,15 +497,10 @@
 	else
 		ret = ov2680_power_off(sensor);
 
-	mutex_unlock(&sensor->lock);
-
-	if (on && ret == 0) {
-		ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
-		if (ret < 0)
-			return ret;
-
+	if (on && ret == 0)
 		ret = ov2680_mode_restore(sensor);
-	}
+
+	mutex_unlock(&sensor->lock);
 
 	return ret;
 }
@@ -793,66 +695,23 @@
 	return 0;
 }
 
-static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
-	struct ov2680_dev *sensor = to_ov2680_dev(sd);
-	struct ov2680_ctrls *ctrls = &sensor->ctrls;
-	int val;
-
-	if (!sensor->is_enabled)
-		return 0;
-
-	switch (ctrl->id) {
-	case V4L2_CID_GAIN:
-		val = ov2680_gain_get(sensor);
-		if (val < 0)
-			return val;
-		ctrls->gain->val = val;
-		break;
-	case V4L2_CID_EXPOSURE:
-		val = ov2680_exposure_get(sensor);
-		if (val < 0)
-			return val;
-		ctrls->exposure->val = val;
-		break;
-	}
-
-	return 0;
-}
-
 static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
 {
 	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
 	struct ov2680_dev *sensor = to_ov2680_dev(sd);
-	struct ov2680_ctrls *ctrls = &sensor->ctrls;
 
 	if (!sensor->is_enabled)
 		return 0;
 
 	switch (ctrl->id) {
-	case V4L2_CID_AUTOGAIN:
-		return ov2680_gain_set(sensor, !!ctrl->val);
 	case V4L2_CID_GAIN:
-		return ov2680_gain_set(sensor, !!ctrls->auto_gain->val);
-	case V4L2_CID_EXPOSURE_AUTO:
-		return ov2680_exposure_set(sensor, !!ctrl->val);
+		return ov2680_gain_set(sensor, ctrl->val);
 	case V4L2_CID_EXPOSURE:
-		return ov2680_exposure_set(sensor, !!ctrls->auto_exp->val);
+		return ov2680_exposure_set(sensor, ctrl->val);
 	case V4L2_CID_VFLIP:
-		if (sensor->is_streaming)
-			return -EBUSY;
-		if (ctrl->val)
-			return ov2680_vflip_enable(sensor);
-		else
-			return ov2680_vflip_disable(sensor);
+		return ov2680_set_vflip(sensor, ctrl->val);
 	case V4L2_CID_HFLIP:
-		if (sensor->is_streaming)
-			return -EBUSY;
-		if (ctrl->val)
-			return ov2680_hflip_enable(sensor);
-		else
-			return ov2680_hflip_disable(sensor);
+		return ov2680_set_hflip(sensor, ctrl->val);
 	case V4L2_CID_TEST_PATTERN:
 		return ov2680_test_pattern_set(sensor, ctrl->val);
 	default:
@@ -863,7 +722,6 @@
 }
 
 static const struct v4l2_ctrl_ops ov2680_ctrl_ops = {
-	.g_volatile_ctrl = ov2680_g_volatile_ctrl,
 	.s_ctrl = ov2680_s_ctrl,
 };
 
@@ -935,7 +793,7 @@
 	if (ret < 0)
 		return ret;
 
-	v4l2_ctrl_handler_init(hdl, 7);
+	v4l2_ctrl_handler_init(hdl, 5);
 
 	hdl->lock = &sensor->lock;
 
@@ -947,16 +805,9 @@
 					ARRAY_SIZE(test_pattern_menu) - 1,
 					0, 0, test_pattern_menu);
 
-	ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
-						 V4L2_CID_EXPOSURE_AUTO,
-						 V4L2_EXPOSURE_MANUAL, 0,
-						 V4L2_EXPOSURE_AUTO);
-
 	ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
 					    0, 32767, 1, 0);
 
-	ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN,
-					     0, 1, 1, 1);
 	ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 2047, 1, 0);
 
 	if (hdl->error) {
@@ -964,11 +815,8 @@
 		goto cleanup_entity;
 	}
 
-	ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
-	ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
-
-	v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true);
-	v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true);
+	ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+	ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
 
 	sensor->sd.ctrl_handler = hdl;
 
diff --git a/kernel/drivers/media/i2c/ov2740.c b/kernel/drivers/media/i2c/ov2740.c
index bd0d45b..34d74e5 100644
--- a/kernel/drivers/media/i2c/ov2740.c
+++ b/kernel/drivers/media/i2c/ov2740.c
@@ -577,8 +577,10 @@
 				     V4L2_CID_TEST_PATTERN,
 				     ARRAY_SIZE(ov2740_test_pattern_menu) - 1,
 				     0, 0, ov2740_test_pattern_menu);
-	if (ctrl_hdlr->error)
+	if (ctrl_hdlr->error) {
+		v4l2_ctrl_handler_free(ctrl_hdlr);
 		return ctrl_hdlr->error;
+	}
 
 	ov2740->sd.ctrl_handler = ctrl_hdlr;
 
diff --git a/kernel/drivers/media/i2c/ov5640.c b/kernel/drivers/media/i2c/ov5640.c
index 8f0812e..db4b609 100644
--- a/kernel/drivers/media/i2c/ov5640.c
+++ b/kernel/drivers/media/i2c/ov5640.c
@@ -1942,9 +1942,9 @@
 	 *		  "ov5640_set_stream_mipi()")
 	 * [4] = 0	: Power up MIPI HS Tx
 	 * [3] = 0	: Power up MIPI LS Rx
-	 * [2] = 0	: MIPI interface disabled
+	 * [2] = 1	: MIPI interface enabled
 	 */
-	ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x40);
+	ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x44);
 	if (ret)
 		return ret;
 
@@ -2748,7 +2748,7 @@
 	/* Auto/manual gain */
 	ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN,
 					     0, 1, 1, 1);
-	ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
+	ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN,
 					0, 1023, 1, 0);
 
 	ctrls->saturation = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION,
diff --git a/kernel/drivers/media/i2c/ov5675.c b/kernel/drivers/media/i2c/ov5675.c
index 9540ce8..aa35a95 100644
--- a/kernel/drivers/media/i2c/ov5675.c
+++ b/kernel/drivers/media/i2c/ov5675.c
@@ -791,8 +791,10 @@
 	v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
 			  V4L2_CID_VFLIP, 0, 1, 1, 0);
 
-	if (ctrl_hdlr->error)
+	if (ctrl_hdlr->error) {
+		v4l2_ctrl_handler_free(ctrl_hdlr);
 		return ctrl_hdlr->error;
+	}
 
 	ov5675->sd.ctrl_handler = ctrl_hdlr;
 
diff --git a/kernel/drivers/media/i2c/ov7670.c b/kernel/drivers/media/i2c/ov7670.c
index 154776d..e47800c 100644
--- a/kernel/drivers/media/i2c/ov7670.c
+++ b/kernel/drivers/media/i2c/ov7670.c
@@ -1824,7 +1824,7 @@
 
 	if (bus_cfg.bus_type != V4L2_MBUS_PARALLEL) {
 		dev_err(dev, "Unsupported media bus type\n");
-		return ret;
+		return -EINVAL;
 	}
 	info->mbus_config = bus_cfg.bus.parallel.flags;
 
diff --git a/kernel/drivers/media/i2c/ov772x.c b/kernel/drivers/media/i2c/ov772x.c
index 2cc6a67..5033950 100644
--- a/kernel/drivers/media/i2c/ov772x.c
+++ b/kernel/drivers/media/i2c/ov772x.c
@@ -1397,7 +1397,7 @@
 	priv->subdev.ctrl_handler = &priv->hdl;
 	if (priv->hdl.error) {
 		ret = priv->hdl.error;
-		goto error_mutex_destroy;
+		goto error_ctrl_free;
 	}
 
 	priv->clk = clk_get(&client->dev, NULL);
@@ -1446,7 +1446,6 @@
 	clk_put(priv->clk);
 error_ctrl_free:
 	v4l2_ctrl_handler_free(&priv->hdl);
-error_mutex_destroy:
 	mutex_destroy(&priv->lock);
 
 	return ret;
diff --git a/kernel/drivers/media/i2c/sc200ai.c b/kernel/drivers/media/i2c/sc200ai.c
index daa7e4e..44c7156 100644
--- a/kernel/drivers/media/i2c/sc200ai.c
+++ b/kernel/drivers/media/i2c/sc200ai.c
@@ -11,8 +11,11 @@
  * V0.0X01.0X05 add quick stream on/off.
  * V0.0X01.0X06 fix set vflip/hflip failed bug.
  * V0.0X01.0X07
- * 1. fix set double times exposue value failed issue.
- * 2. add some debug info.
+ *	1. fix set double times exposue value failed issue.
+ *	2. add some debug info.
+ * V0.0X01.0X08
+ *	1. add support wakeup & sleep for aov function
+ *	2. using 60fps output default
  */
 
 #include <linux/clk.h>
@@ -34,8 +37,10 @@
 #include <media/v4l2-subdev.h>
 #include <linux/pinctrl/consumer.h>
 #include "../platform/rockchip/isp/rkisp_tb_helper.h"
+#include "cam-tb-setup.h"
+#include "cam-sleep-wakeup.h"
 
-#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x07)
+#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x08)
 
 #ifndef V4L2_CID_DIGITAL_GAIN
 #define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
@@ -179,6 +184,7 @@
 	bool			is_thunderboot;
 	bool			is_first_streamoff;
 	struct preisp_hdrae_exp_s init_hdrae_exp;
+	struct cam_sw_info	*cam_sw_inf;
 };
 
 #define to_sc200ai(sd) container_of(sd, struct sc200ai, subdev)
@@ -611,20 +617,6 @@
 		.height = 1080,
 		.max_fps = {
 			.numerator = 10000,
-			.denominator = 300000,
-		},
-		.exp_def = 0x0080,
-		.hts_def = 0x44C * 2,
-		.vts_def = 0x0465,
-		.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
-		.reg_list = sc200ai_linear_10_1920x1080_30fps_regs,
-		.hdr_mode = NO_HDR,
-		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
-	}, {
-		.width = 1920,
-		.height = 1080,
-		.max_fps = {
-			.numerator = 10000,
 			.denominator = 600000,
 		},
 		.exp_def = 0x0080,
@@ -634,7 +626,23 @@
 		.reg_list = sc200ai_linear_10_1920x1080_60fps_regs,
 		.hdr_mode = NO_HDR,
 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
-	}, {
+	},
+	{
+		.width = 1920,
+		.height = 1080,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 300000,
+		},
+		.exp_def = 0x0080,
+		.hts_def = 0x44C * 2,
+		.vts_def = 0x0465,
+		.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.reg_list = sc200ai_linear_10_1920x1080_30fps_regs,
+		.hdr_mode = NO_HDR,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	},
+	{
 		.width = 1920,
 		.height = 1080,
 		.max_fps = {
@@ -1215,17 +1223,23 @@
 		break;
 	case PREISP_CMD_SET_HDRAE_EXP:
 		sc200ai_set_hdrae(sc200ai, arg);
+		if (sc200ai->cam_sw_inf)
+			memcpy(&sc200ai->cam_sw_inf->hdr_ae, (struct preisp_hdrae_exp_s *)(arg),
+				sizeof(struct preisp_hdrae_exp_s));
 		break;
 	case RKMODULE_SET_QUICK_STREAM:
 
 		stream = *((u32 *)arg);
 
-		if (stream)
+		if (stream) {
+			gpiod_set_value_cansleep(sc200ai->pwdn_gpio, 1);
 			ret = sc200ai_write_reg(sc200ai->client, SC200AI_REG_CTRL_MODE,
 				 SC200AI_REG_VALUE_08BIT, SC200AI_MODE_STREAMING);
-		else
+		} else {
 			ret = sc200ai_write_reg(sc200ai->client, SC200AI_REG_CTRL_MODE,
 				 SC200AI_REG_VALUE_08BIT, SC200AI_MODE_SW_STANDBY);
+			gpiod_set_value_cansleep(sc200ai->pwdn_gpio, 0);
+		}
 		break;
 	case RKMODULE_GET_CHANNEL_INFO:
 		ch_info = (struct rkmodule_channel_info *)arg;
@@ -1512,6 +1526,9 @@
 		dev_err(dev, "Failed to enable xvclk\n");
 		return ret;
 	}
+
+	cam_sw_regulator_bulk_init(sc200ai->cam_sw_inf, SC200AI_NUM_SUPPLIES, sc200ai->supplies);
+
 	if (sc200ai->is_thunderboot)
 		return 0;
 
@@ -1576,6 +1593,51 @@
 	regulator_bulk_disable(SC200AI_NUM_SUPPLIES, sc200ai->supplies);
 }
 
+#if IS_REACHABLE(CONFIG_VIDEO_CAM_SLEEP_WAKEUP)
+static int __maybe_unused sc200ai_resume(struct device *dev)
+{
+	int ret;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct sc200ai *sc200ai = to_sc200ai(sd);
+
+	cam_sw_prepare_wakeup(sc200ai->cam_sw_inf, dev);
+
+	usleep_range(4000, 5000);
+	cam_sw_write_array(sc200ai->cam_sw_inf);
+
+	if (__v4l2_ctrl_handler_setup(&sc200ai->ctrl_handler))
+		dev_err(dev, "__v4l2_ctrl_handler_setup fail!");
+
+	if (sc200ai->has_init_exp && sc200ai->cur_mode != NO_HDR) {	// hdr mode
+		ret = sc200ai_ioctl(&sc200ai->subdev, PREISP_CMD_SET_HDRAE_EXP,
+				    &sc200ai->cam_sw_inf->hdr_ae);
+		if (ret) {
+			dev_err(&sc200ai->client->dev, "set exp fail in hdr mode\n");
+			return ret;
+		}
+	}
+	return 0;
+}
+
+static int __maybe_unused sc200ai_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct sc200ai *sc200ai = to_sc200ai(sd);
+
+	cam_sw_write_array_cb_init(sc200ai->cam_sw_inf, client,
+				   (void *)sc200ai->cur_mode->reg_list,
+				   (sensor_write_array)sc200ai_write_array);
+	cam_sw_prepare_sleep(sc200ai->cam_sw_inf);
+
+	return 0;
+}
+#else
+#define sc200ai_resume NULL
+#define sc200ai_suspend NULL
+#endif
+
 static int sc200ai_runtime_resume(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
@@ -1636,6 +1698,7 @@
 static const struct dev_pm_ops sc200ai_pm_ops = {
 	SET_RUNTIME_PM_OPS(sc200ai_runtime_suspend,
 			   sc200ai_runtime_resume, NULL)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(sc200ai_suspend, sc200ai_resume)
 };
 
 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
@@ -1889,109 +1952,28 @@
 }
 
 #ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
-static u32 rk_cam_hdr;
-static u32 rk_cam_w;
-static u32 rk_cam_h;
-static u32 rk_cam_fps;
-
-static int __init __maybe_unused rk_cam_hdr_setup(char *str)
-{
-	int ret = 0;
-	unsigned long val = 0;
-
-	ret = kstrtoul(str, 0, &val);
-	if (!ret)
-		rk_cam_hdr = (u32)val;
-	else
-		pr_err("get rk_cam_hdr fail\n");
-	return 1;
-}
-
-static int __init __maybe_unused rk_cam_w_setup(char *str)
-{
-	int ret = 0;
-	unsigned long val = 0;
-
-	ret = kstrtoul(str, 0, &val);
-	if (!ret)
-		rk_cam_w = (u32)val;
-	else
-		pr_err("get rk_cam_w fail\n");
-	return 1;
-}
-
-static int __init __maybe_unused rk_cam_h_setup(char *str)
-{
-	int ret = 0;
-	unsigned long val = 0;
-
-	ret = kstrtoul(str, 0, &val);
-	if (!ret)
-		rk_cam_h = (u32)val;
-	else
-		pr_err("get rk_cam_h fail\n");
-	return 1;
-}
-
-static int __init __maybe_unused rk_cam_fps_setup(char *str)
-{
-	int ret = 0;
-	unsigned long val = 0;
-
-	ret = kstrtoul(str, 0, &val);
-	if (!ret)
-		rk_cam_fps = (u32)val;
-	else
-		pr_err("get rk_cam_fps fail\n");
-	return 1;
-}
-
-__setup("rk_cam_hdr=", rk_cam_hdr_setup);
-__setup("rk_cam_w=", rk_cam_w_setup);
-__setup("rk_cam_h=", rk_cam_h_setup);
-__setup("rk_cam_fps=", rk_cam_fps_setup);
-
 static void find_terminal_resolution(struct sc200ai *sc200ai)
 {
 	int i = 0;
 	const struct sc200ai_mode *mode = NULL;
-	const struct sc200ai_mode *fit_mode = NULL;
-	u32 cur_fps = 0;
-	u32 dst_fps = 0;
-	u32 tmp_fps = 0;
+	u32 rk_cam_hdr = get_rk_cam_hdr();
+	u32 rk_cam_w = get_rk_cam_w();
+	u32 rk_cam_h = get_rk_cam_h();
 
-	if (rk_cam_w == 0 || rk_cam_h == 0 ||
-	    rk_cam_fps == 0)
+	if (rk_cam_w == 0 || rk_cam_h == 0)
 		goto err_find_res;
 
-	dst_fps = rk_cam_fps;
 	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
 		mode = &supported_modes[i];
-		cur_fps = mode->max_fps.denominator / mode->max_fps.numerator;
 		if (mode->width == rk_cam_w && mode->height == rk_cam_h &&
 		    mode->hdr_mode == rk_cam_hdr) {
-			if (cur_fps == dst_fps) {
-				sc200ai->cur_mode = mode;
-				return;
-			}
-			if (cur_fps >= dst_fps) {
-				if (fit_mode) {
-					tmp_fps = fit_mode->max_fps.denominator / fit_mode->max_fps.numerator;
-					if (tmp_fps - dst_fps > cur_fps - dst_fps)
-						fit_mode = mode;
-				} else {
-					fit_mode = mode;
-				}
-			}
+			sc200ai->cur_mode = mode;
+			return;
 		}
 	}
-	if (fit_mode) {
-		sc200ai->cur_mode = fit_mode;
-		return;
-	}
 err_find_res:
-	dev_err(&sc200ai->client->dev, "not match %dx%d@%dfps mode %d\n!",
-		rk_cam_w, rk_cam_h, dst_fps, rk_cam_hdr);
+	dev_err(&sc200ai->client->dev, "not match %dx%d mode %d\n!",
+		rk_cam_w, rk_cam_h, rk_cam_hdr);
 	sc200ai->cur_mode = &supported_modes[0];
 }
 #else
@@ -2057,11 +2039,11 @@
 		return -EINVAL;
 	}
 
-	sc200ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
+	sc200ai->reset_gpio = devm_gpiod_get(dev, "reset", sc200ai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
 	if (IS_ERR(sc200ai->reset_gpio))
 		dev_warn(dev, "Failed to get reset-gpios\n");
 
-	sc200ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
+	sc200ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", sc200ai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
 	if (IS_ERR(sc200ai->pwdn_gpio))
 		dev_warn(dev, "Failed to get pwdn-gpios\n");
 
@@ -2117,6 +2099,13 @@
 		goto err_power_off;
 #endif
 
+	if (!sc200ai->cam_sw_inf) {
+		sc200ai->cam_sw_inf = cam_sw_init();
+		cam_sw_clk_init(sc200ai->cam_sw_inf, sc200ai->xvclk, SC200AI_XVCLK_FREQ);
+		cam_sw_reset_pin_init(sc200ai->cam_sw_inf, sc200ai->reset_gpio, 0);
+		cam_sw_pwdn_pin_init(sc200ai->cam_sw_inf, sc200ai->pwdn_gpio, 1);
+	}
+
 	memset(facing, 0, sizeof(facing));
 	if (strcmp(sc200ai->module_facing, "back") == 0)
 		facing[0] = 'b';
@@ -2167,6 +2156,8 @@
 	v4l2_ctrl_handler_free(&sc200ai->ctrl_handler);
 	mutex_destroy(&sc200ai->mutex);
 
+	cam_sw_deinit(sc200ai->cam_sw_inf);
+
 	pm_runtime_disable(&client->dev);
 	if (!pm_runtime_status_suspended(&client->dev))
 		__sc200ai_power_off(sc200ai);
diff --git a/kernel/drivers/media/i2c/sc223a.c b/kernel/drivers/media/i2c/sc223a.c
index e578ac9..fd82b3e 100644
--- a/kernel/drivers/media/i2c/sc223a.c
+++ b/kernel/drivers/media/i2c/sc223a.c
@@ -40,6 +40,8 @@
 
 #define PIXEL_RATE_WITH_405M_10BIT	(SC223A_LINK_FREQ_405 * 2 * \
 					SC223A_LANES / SC223A_BITS_PER_SAMPLE)
+/* 79.2Mhz */
+#define SC223A_PIXEL_RATE		(79200000)
 #define SC223A_XVCLK_FREQ		24000000
 
 #define CHIP_ID				0xcb3e
@@ -93,10 +95,12 @@
 #define SC223A_REG_VALUE_16BIT		2
 #define SC223A_REG_VALUE_24BIT		3
 
+#define RKMODULE_CAMERA_MODULE_MODE	"rockchip,camera_mode"
 #define OF_CAMERA_PINCTRL_STATE_DEFAULT	"rockchip,camera_default"
 #define OF_CAMERA_PINCTRL_STATE_SLEEP	"rockchip,camera_sleep"
 #define SC223A_NAME			"sc223a"
-
+#define CAMERA_MIPI_MODE		"mipi_mode"
+#define CAMERA_DVP_MODE			"dvp_mode"
 static const char * const sc223a_supply_names[] = {
 	"avdd",		/* Analog power */
 	"dovdd",	/* Digital I/O power */
@@ -104,6 +108,17 @@
 };
 
 #define SC223A_NUM_SUPPLIES ARRAY_SIZE(sc223a_supply_names)
+
+enum sc223a_support_mode_id {
+	SC223A_MIPI_1920X1080 = 0,
+	SC223A_DVP_1920X1080,
+	SC223A_MODE_ID_MAX = SC223A_DVP_1920X1080,
+};
+
+enum sc223a_mode_id {
+	SC223A_MIPI_MODE = 0,
+	SC223A_DVP_MODE,
+};
 
 struct regval {
 	u16 addr;
@@ -121,6 +136,7 @@
 	const struct regval *reg_list;
 	u32 hdr_mode;
 	u32 vc[PAD_MAX];
+	u8 mode_id;
 };
 
 struct sc223a {
@@ -152,6 +168,7 @@
 	const char		*module_facing;
 	const char		*module_name;
 	const char		*len_name;
+	const char		*mode;
 	u32			cur_vts;
 	bool			has_init_exp;
 	bool			is_thunderboot;
@@ -353,8 +370,223 @@
 	{REG_NULL, 0x00},
 };
 
+/*
+ * Xclk 24Mhz
+ * Pclk 79.2Mhz
+ * max_framerate 30fps
+ * 1920x1080
+ * dvp 10bit, 2lane
+ */
+static const struct regval sc223a_linear_10_1920x1080_dvp_30fps_regs[] = {
+	{0x0100, 0x00},
+	{0x36e9, 0x80},
+	{0x37f9, 0x80},
+	{0x3001, 0xff},
+	{0x3002, 0xf0},
+	{0x300a, 0x24},
+	{0x3018, 0x0f},
+	{0x301a, 0xf8},
+	{0x301c, 0x94},
+	{0x301f, 0x40},
+	{0x303f, 0x81},
+	{0x30b8, 0x44},
+	{0x3200, 0x00},
+	{0x3201, 0x00},
+	{0x3202, 0x00},
+	{0x3203, 0x00},
+	{0x3204, 0x07},
+	{0x3205, 0x87},
+	{0x3206, 0x04},
+	{0x3207, 0x3f},
+	{0x3208, 0x07},
+	{0x3209, 0x80},
+	{0x320a, 0x04},
+	{0x320b, 0x38},
+	{0x320c, 0x09},
+	{0x320d, 0x60},
+	{0x320e, 0x04},
+	{0x320f, 0x65},
+	{0x3210, 0x00},
+	{0x3211, 0x04},
+	{0x3212, 0x00},
+	{0x3213, 0x04},
+	{0x3227, 0x03},
+	{0x3250, 0x00},
+	{0x3253, 0x0c},
+	{0x3281, 0x80},
+	{0x3301, 0x06},
+	{0x3302, 0x12},
+	{0x3306, 0x84},
+	{0x3309, 0x60},
+	{0x330a, 0x00},
+	{0x330b, 0xe0},
+	{0x330d, 0x20},
+	{0x3314, 0x15},
+	{0x331e, 0x41},
+	{0x331f, 0x51},
+	{0x3320, 0x0a},
+	{0x3326, 0x0e},
+	{0x3333, 0x10},
+	{0x3334, 0x40},
+	{0x335d, 0x60},
+	{0x335e, 0x06},
+	{0x335f, 0x08},
+	{0x3364, 0x56},
+	{0x337a, 0x06},
+	{0x337b, 0x0e},
+	{0x337c, 0x02},
+	{0x337d, 0x0a},
+	{0x3390, 0x03},
+	{0x3391, 0x0f},
+	{0x3392, 0x1f},
+	{0x3393, 0x06},
+	{0x3394, 0x06},
+	{0x3395, 0x06},
+	{0x3396, 0x48},
+	{0x3397, 0x4b},
+	{0x3398, 0x5f},
+	{0x3399, 0x06},
+	{0x339a, 0x06},
+	{0x339b, 0x9c},
+	{0x339c, 0x9c},
+	{0x33a2, 0x04},
+	{0x33a3, 0x0a},
+	{0x33ad, 0x1c},
+	{0x33af, 0x40},
+	{0x33b1, 0x80},
+	{0x33b3, 0x20},
+	{0x349f, 0x02},
+	{0x34a6, 0x48},
+	{0x34a7, 0x4b},
+	{0x34a8, 0x20},
+	{0x34a9, 0x20},
+	{0x34f8, 0x5f},
+	{0x34f9, 0x10},
+	{0x3616, 0xac},
+	{0x3630, 0xc0},
+	{0x3631, 0x86},
+	{0x3632, 0x26},
+	{0x3633, 0x32},
+	{0x3637, 0x29},
+	{0x363a, 0x84},
+	{0x363b, 0x04},
+	{0x363c, 0x08},
+	{0x3641, 0x3a},
+	{0x364f, 0x39},
+	{0x3670, 0xce},
+	{0x3674, 0xc0},
+	{0x3675, 0xc0},
+	{0x3676, 0xc0},
+	{0x3677, 0x86},
+	{0x3678, 0x8b},
+	{0x3679, 0x8c},
+	{0x367c, 0x4b},
+	{0x367d, 0x5f},
+	{0x367e, 0x4b},
+	{0x367f, 0x5f},
+	{0x3690, 0x62},
+	{0x3691, 0x63},
+	{0x3692, 0x63},
+	{0x3699, 0x86},
+	{0x369a, 0x92},
+	{0x369b, 0xa4},
+	{0x369c, 0x48},
+	{0x369d, 0x4b},
+	{0x36a2, 0x4b},
+	{0x36a3, 0x4f},
+	{0x36ea, 0x09},
+	{0x36eb, 0x0c},
+	{0x36ec, 0x1c},
+	{0x36ed, 0x28},
+	{0x370f, 0x01},
+	{0x3721, 0x6c},
+	{0x3722, 0x09},
+	{0x3724, 0x41},
+	{0x3725, 0xc4},
+	{0x37b0, 0x09},
+	{0x37b1, 0x09},
+	{0x37b2, 0x09},
+	{0x37b3, 0x48},
+	{0x37b4, 0x5f},
+	{0x37fa, 0x09},
+	{0x37fb, 0x32},
+	{0x37fc, 0x10},
+	{0x37fd, 0x37},
+	{0x3900, 0x19},
+	{0x3901, 0x02},
+	{0x3905, 0xb8},
+	{0x391b, 0x82},
+	{0x391c, 0x00},
+	{0x391f, 0x04},
+	{0x3928, 0xc1},
+	{0x3933, 0x81},
+	{0x3934, 0x4c},
+	{0x393f, 0xff},
+	{0x3940, 0x73},
+	{0x3942, 0x01},
+	{0x3943, 0x4d},
+	{0x3946, 0x20},
+	{0x3957, 0x86},
+	{0x3e01, 0x8c},
+	{0x3e02, 0x00},
+	{0x3e28, 0xc4},
+	{0x440e, 0x02},
+	{0x4501, 0xc0},
+	{0x4509, 0x14},
+	{0x450d, 0x11},
+	{0x4518, 0x00},
+	{0x451b, 0x0a},
+	{0x4603, 0x09},
+	{0x4819, 0x07},
+	{0x481b, 0x04},
+	{0x481d, 0x0e},
+	{0x3000, 0xff},
+	{0x481f, 0x03},
+	{0x4821, 0x09},
+	{0x4823, 0x04},
+	{0x4825, 0x03},
+	{0x4827, 0x03},
+	{0x4829, 0x06},
+	{0x501c, 0x00},
+	{0x501d, 0x60},
+	{0x501e, 0x00},
+	{0x501f, 0x40},
+	{0x5799, 0x06},
+	{0x5ae0, 0xfe},
+	{0x5ae1, 0x40},
+	{0x5ae2, 0x38},
+	{0x5ae3, 0x30},
+	{0x5ae4, 0x28},
+	{0x5ae5, 0x38},
+	{0x5ae6, 0x30},
+	{0x5ae7, 0x28},
+	{0x5ae8, 0x3f},
+	{0x5ae9, 0x34},
+	{0x5aea, 0x2c},
+	{0x5aeb, 0x3f},
+	{0x5aec, 0x34},
+	{0x5aed, 0x2c},
+	{0x5aee, 0xfe},
+	{0x5aef, 0x40},
+	{0x5af4, 0x38},
+	{0x5af5, 0x30},
+	{0x5af6, 0x28},
+	{0x5af7, 0x38},
+	{0x5af8, 0x30},
+	{0x5af9, 0x28},
+	{0x5afa, 0x3f},
+	{0x5afb, 0x34},
+	{0x5afc, 0x2c},
+	{0x5afd, 0x3f},
+	{0x5afe, 0x34},
+	{0x5aff, 0x2c},
+	{0x36e9, 0x53},
+	{0x37f9, 0x53},
+	{REG_NULL, 0x00},
+};
+
 static const struct sc223a_mode supported_modes[] = {
-	{
+	[SC223A_MIPI_1920X1080] = {
 		.width = 1920,
 		.height = 1080,
 		.max_fps = {
@@ -367,11 +599,28 @@
 		.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
 		.reg_list = sc223a_linear_10_1920x1080_30fps_regs,
 		.hdr_mode = NO_HDR,
+		.mode_id = SC223A_MIPI_MODE,
 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
-	}
+	},
+	[SC223A_DVP_1920X1080] = {
+		.width = 1920,
+		.height = 1080,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 300000,
+		},
+		.exp_def = 0x0080,
+		.hts_def = 0x0960,
+		.vts_def = 0x0465,
+		.bus_fmt = MEDIA_BUS_FMT_SBGGR8_1X8,
+		.reg_list = sc223a_linear_10_1920x1080_dvp_30fps_regs,
+		.hdr_mode = NO_HDR,
+		.mode_id = SC223A_DVP_MODE,
+		.vc[PAD0] = 0,
+	},
 };
 
-static const s64 link_freq_menu_items[] = {
+static const __maybe_unused s64 link_freq_menu_items[] = {
 	SC223A_LINK_FREQ_405
 };
 
@@ -694,17 +943,25 @@
 	struct sc223a *sc223a = to_sc223a(sd);
 	const struct sc223a_mode *mode = sc223a->cur_mode;
 
-	u32 val = 1 << (SC223A_LANES - 1) |
-		V4L2_MBUS_CSI2_CHANNEL_0 |
-		V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+	u32 val;
 
-	if (mode->hdr_mode != NO_HDR)
-		val |= V4L2_MBUS_CSI2_CHANNEL_1;
-	if (mode->hdr_mode == HDR_X3)
-		val |= V4L2_MBUS_CSI2_CHANNEL_2;
+	if (!strcmp(sc223a->mode, CAMERA_MIPI_MODE)) {
+		val = 1 << (SC223A_LANES - 1) |
+		      V4L2_MBUS_CSI2_CHANNEL_0 |
+		      V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+		if (mode->hdr_mode != NO_HDR)
+			val |= V4L2_MBUS_CSI2_CHANNEL_1;
+		if (mode->hdr_mode == HDR_X3)
+			val |= V4L2_MBUS_CSI2_CHANNEL_2;
 
-	config->type = V4L2_MBUS_CSI2_DPHY;
-	config->flags = val;
+		config->type = V4L2_MBUS_CSI2_DPHY;
+		config->flags = val;
+	} else if (!strcmp(sc223a->mode, CAMERA_DVP_MODE)) {
+		config->type = V4L2_MBUS_PARALLEL;
+		config->flags = V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+				V4L2_MBUS_VSYNC_ACTIVE_LOW |
+				V4L2_MBUS_PCLK_SAMPLE_RISING;
+	}
 
 	return 0;
 }
@@ -724,6 +981,7 @@
 	struct sc223a *sc223a = to_sc223a(sd);
 	struct rkmodule_hdr_cfg *hdr;
 	u32 i, h, w;
+	u8 mode;
 	long ret = 0;
 	u32 stream = 0;
 
@@ -740,9 +998,11 @@
 		hdr = (struct rkmodule_hdr_cfg *)arg;
 		w = sc223a->cur_mode->width;
 		h = sc223a->cur_mode->height;
+		mode = sc223a->cur_mode->mode_id;
 		for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
 			if (w == supported_modes[i].width &&
 			    h == supported_modes[i].height &&
+			    mode == supported_modes[i].mode_id &&
 			    supported_modes[i].hdr_mode == hdr->hdr_mode) {
 				sc223a->cur_mode = &supported_modes[i];
 				break;
@@ -889,6 +1149,7 @@
 			}
 		}
 	}
+
 	return sc223a_write_reg(sc223a->client, SC223A_REG_CTRL_MODE,
 				SC223A_REG_VALUE_08BIT, SC223A_MODE_STREAMING);
 }
@@ -1293,13 +1554,18 @@
 		return ret;
 	handler->lock = &sc223a->mutex;
 
-	ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
-				      0, 0, link_freq_menu_items);
-	if (ctrl)
-		ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+	if (!strcmp(sc223a->mode, CAMERA_MIPI_MODE)) {
+		ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
+					      0, 0, link_freq_menu_items);
+		if (ctrl)
+			ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+		v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
+				  0, PIXEL_RATE_WITH_405M_10BIT, 1, PIXEL_RATE_WITH_405M_10BIT);
+	} else if (!strcmp(sc223a->mode, CAMERA_DVP_MODE)) {
+		v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
+				  0, SC223A_PIXEL_RATE, 1, SC223A_PIXEL_RATE);
+	}
 
-	v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
-			  0, PIXEL_RATE_WITH_405M_10BIT, 1, PIXEL_RATE_WITH_405M_10BIT);
 
 	h_blank = mode->hts_def - mode->width;
 	sc223a->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
@@ -1412,6 +1678,8 @@
 				       &sc223a->module_name);
 	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
 				       &sc223a->len_name);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_MODE,
+				       &sc223a->mode);
 	if (ret) {
 		dev_err(dev, "could not get module information!\n");
 		return -EINVAL;
@@ -1420,14 +1688,18 @@
 	sc223a->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
 
 	sc223a->client = client;
-	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
-		if (hdr_mode == supported_modes[i].hdr_mode) {
-			sc223a->cur_mode = &supported_modes[i];
-			break;
+	if (!strcmp(sc223a->mode, CAMERA_MIPI_MODE)) {
+		for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+			if (hdr_mode == supported_modes[i].hdr_mode) {
+				sc223a->cur_mode = &supported_modes[i];
+				break;
+			}
 		}
+		if (i == ARRAY_SIZE(supported_modes))
+			sc223a->cur_mode = &supported_modes[SC223A_MIPI_1920X1080];
+	} else if (!strcmp(sc223a->mode, CAMERA_DVP_MODE)) {
+		sc223a->cur_mode = &supported_modes[SC223A_DVP_1920X1080];
 	}
-	if (i == ARRAY_SIZE(supported_modes))
-		sc223a->cur_mode = &supported_modes[0];
 
 	sc223a->xvclk = devm_clk_get(dev, "xvclk");
 	if (IS_ERR(sc223a->xvclk)) {
diff --git a/kernel/drivers/media/i2c/sc230ai.c b/kernel/drivers/media/i2c/sc230ai.c
index 084f5bf..0394914 100644
--- a/kernel/drivers/media/i2c/sc230ai.c
+++ b/kernel/drivers/media/i2c/sc230ai.c
@@ -173,6 +173,7 @@
 	const char		*module_facing;
 	const char		*module_name;
 	const char		*len_name;
+	enum rkmodule_sync_mode	sync_mode;
 	u32			cur_vts;
 	bool			has_init_exp;
 	bool			is_thunderboot;
@@ -534,6 +535,28 @@
 	{REG_NULL, 0x00},
 };
 
+static __maybe_unused const struct regval sc230ai_interal_sync_master_start_regs[] = {
+	{0x300a, 0x24}, //sync as output PAD
+	{0x3032, 0xa0},
+	{0x3222, 0x00}, //master mode
+	{REG_NULL, 0x00},
+};
+
+static __maybe_unused const struct regval sc230ai_interal_sync_master_stop_regs[] = {
+	{REG_NULL, 0x00},
+};
+
+static __maybe_unused const struct regval sc230ai_interal_sync_slaver_start_regs[] = {
+	{0x300a, 0x20}, //sync as input PAD
+	{0x3222, 0x01}, //slave mode
+	{0x3224, 0x92}, //fsync trigger
+	{0x3614, 0x01},
+	{REG_NULL, 0x00},
+};
+
+static __maybe_unused const struct regval sc230ai_interal_sync_slaver_stop_regs[] = {
+	{REG_NULL, 0x00},
+};
 
 static const struct sc230ai_mode supported_modes[] = {
 	{
@@ -930,6 +953,7 @@
 	u32 i, h, w;
 	long ret = 0;
 	u32 stream = 0;
+	u32 *sync_mode = NULL;
 
 	switch (cmd) {
 	case RKMODULE_GET_MODULE_INFO:
@@ -980,6 +1004,14 @@
 			ret = sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE,
 				 SC230AI_REG_VALUE_08BIT, SC230AI_MODE_SW_STANDBY);
 		break;
+	case RKMODULE_GET_SYNC_MODE:
+		sync_mode = (u32 *)arg;
+		*sync_mode = sc230ai->sync_mode;
+		break;
+	case RKMODULE_SET_SYNC_MODE:
+		sync_mode = (u32 *)arg;
+		sc230ai->sync_mode = *sync_mode;
+		break;
 	default:
 		ret = -ENOIOCTLCMD;
 		break;
@@ -998,6 +1030,7 @@
 	struct preisp_hdrae_exp_s *hdrae;
 	long ret;
 	u32 stream = 0;
+	u32 sync_mode;
 
 	switch (cmd) {
 	case RKMODULE_GET_MODULE_INFO:
@@ -1066,6 +1099,21 @@
 
 		ret = sc230ai_ioctl(sd, cmd, &stream);
 		break;
+	case RKMODULE_GET_SYNC_MODE:
+		ret = sc230ai_ioctl(sd, cmd, &sync_mode);
+		if (!ret) {
+			ret = copy_to_user(up, &sync_mode, sizeof(u32));
+			if (ret)
+				ret = -EFAULT;
+		}
+		break;
+	case RKMODULE_SET_SYNC_MODE:
+		ret = copy_from_user(&sync_mode, up, sizeof(u32));
+		if (!ret)
+			ret = sc230ai_ioctl(sd, cmd, &sync_mode);
+		else
+			ret = -EFAULT;
+		break;
 	default:
 		ret = -ENOIOCTLCMD;
 		break;
@@ -1077,7 +1125,7 @@
 
 static int __sc230ai_start_stream(struct sc230ai *sc230ai)
 {
-	int ret;
+	int ret = 0;
 
 	if (!sc230ai->is_thunderboot) {
 		ret = sc230ai_write_array(sc230ai->client, sc230ai->cur_mode->reg_list);
@@ -1096,20 +1144,36 @@
 				return ret;
 			}
 		}
+		if (sc230ai->sync_mode == INTERNAL_MASTER_MODE)
+			ret |= sc230ai_write_array(sc230ai->client,
+				sc230ai_interal_sync_master_start_regs);
+		else if (sc230ai->sync_mode == SLAVE_MODE)
+			ret |= sc230ai_write_array(sc230ai->client,
+				sc230ai_interal_sync_slaver_start_regs);
 	}
-	return sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE,
+	ret |= sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE,
 				 SC230AI_REG_VALUE_08BIT, SC230AI_MODE_STREAMING);
+	return ret;
 }
 
 static int __sc230ai_stop_stream(struct sc230ai *sc230ai)
 {
+	int ret = 0;
 	sc230ai->has_init_exp = false;
 	if (sc230ai->is_thunderboot) {
 		sc230ai->is_first_streamoff = true;
 		pm_runtime_put(&sc230ai->client->dev);
+	} else {
+		if (sc230ai->sync_mode == INTERNAL_MASTER_MODE)
+			ret |= sc230ai_write_array(sc230ai->client,
+				sc230ai_interal_sync_master_stop_regs);
+		else if (sc230ai->sync_mode == SLAVE_MODE)
+			ret |= sc230ai_write_array(sc230ai->client,
+				sc230ai_interal_sync_slaver_stop_regs);
 	}
-	return sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE,
+	ret |= sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE,
 				 SC230AI_REG_VALUE_08BIT, SC230AI_MODE_SW_STANDBY);
+	return ret;
 }
 
 static int __sc230ai_power_on(struct sc230ai *sc230ai);
@@ -1625,6 +1689,7 @@
 	char facing[2];
 	int ret;
 	u32 i, hdr_mode = 0;
+	const char *sync_mode_name = NULL;
 
 	dev_info(dev, "driver version: %02x.%02x.%02x",
 		 DRIVER_VERSION >> 16,
@@ -1648,6 +1713,25 @@
 		dev_err(dev, "could not get module information!\n");
 		return -EINVAL;
 	}
+
+	ret = of_property_read_string(node, RKMODULE_CAMERA_SYNC_MODE,
+				      &sync_mode_name);
+	if (ret) {
+		sc230ai->sync_mode = NO_SYNC_MODE;
+		dev_err(dev, "could not get sync mode!\n");
+	} else {
+		if (strcmp(sync_mode_name, RKMODULE_EXTERNAL_MASTER_MODE) == 0) {
+			sc230ai->sync_mode = EXTERNAL_MASTER_MODE;
+			dev_info(dev, "external master mode\n");
+		} else if (strcmp(sync_mode_name, RKMODULE_INTERNAL_MASTER_MODE) == 0) {
+			sc230ai->sync_mode = INTERNAL_MASTER_MODE;
+			dev_info(dev, "internal master mode\n");
+		} else if (strcmp(sync_mode_name, RKMODULE_SLAVE_MODE) == 0) {
+			sc230ai->sync_mode = SLAVE_MODE;
+			dev_info(dev, "slave mode\n");
+		}
+	}
+
 	sc230ai->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
 	sc230ai->client = client;
 	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
diff --git a/kernel/drivers/media/i2c/sc2336.c b/kernel/drivers/media/i2c/sc2336.c
index ca948d6..f1aeaef 100644
--- a/kernel/drivers/media/i2c/sc2336.c
+++ b/kernel/drivers/media/i2c/sc2336.c
@@ -7,7 +7,7 @@
  * V0.0X01.0X01 first version
  */
 
-//#define DEBUG
+// #define DEBUG
 #include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/delay.h>
@@ -192,10 +192,10 @@
 	{0x3301, 0x09},
 	{0x3302, 0xff},
 	{0x3303, 0x10},
-	{0x3306, 0x60},
+	{0x3306, 0x68},
 	{0x3307, 0x02},
 	{0x330a, 0x01},
-	{0x330b, 0x10},
+	{0x330b, 0x18},
 	{0x330c, 0x16},
 	{0x330d, 0xff},
 	{0x3318, 0x02},
@@ -219,8 +219,8 @@
 	{0x33b1, 0x80},
 	{0x33b2, 0x68},
 	{0x33b3, 0x42},
-	{0x33f9, 0x70},
-	{0x33fb, 0xd0},
+	{0x33f9, 0x78},
+	{0x33fb, 0xe0},
 	{0x33fc, 0x0f},
 	{0x33fd, 0x1f},
 	{0x349f, 0x03},
@@ -229,9 +229,9 @@
 	{0x34a8, 0x42},
 	{0x34a9, 0x06},
 	{0x34aa, 0x01},
-	{0x34ab, 0x23},
+	{0x34ab, 0x28},
 	{0x34ac, 0x01},
-	{0x34ad, 0x84},
+	{0x34ad, 0x90},
 	{0x3630, 0xf4},
 	{0x3633, 0x22},
 	{0x3639, 0xf4},
@@ -242,9 +242,9 @@
 	{0x3676, 0xed},
 	{0x367c, 0x09},
 	{0x367d, 0x0f},
-	{0x3690, 0x33},
-	{0x3691, 0x33},
-	{0x3692, 0x43},
+	{0x3690, 0x22},
+	{0x3691, 0x22},
+	{0x3692, 0x22},
 	{0x3698, 0x89},
 	{0x3699, 0x96},
 	{0x369a, 0xd0},
@@ -452,15 +452,15 @@
 		coarse_dgain = 0x00;
 		fine_dgain = gain_factor * 128 / 1000;
 	} else if (gain_factor < 1000 * 4) {			/*2x ~ 4x gain*/
-		coarse_again = 0x01;
+		coarse_again = 0x08;
 		coarse_dgain = 0x00;
 		fine_dgain = gain_factor * 128 / 1000 / 2;
 	} else if (gain_factor < 1000 * 8) {			/*4x ~ 8x gain*/
-		coarse_again = 0x03;
+		coarse_again = 0x09;
 		coarse_dgain = 0x00;
 		fine_dgain = gain_factor * 128 / 1000 / 4;
 	} else if (gain_factor < 1000 * 16) {			/*8x ~ 16x gain*/
-		coarse_again = 0x07;
+		coarse_again = 0x0b;
 		coarse_dgain = 0x00;
 		fine_dgain = gain_factor * 128 / 1000 / 8;
 	} else if (gain_factor < 1000 * 32) {			/*16x ~ 32x gain*/
@@ -481,6 +481,7 @@
 		coarse_dgain = 0x03;
 		fine_dgain = 0x80;
 	}
+	fine_dgain = fine_dgain / 4 * 4;
 	dev_dbg(&sc2336->client->dev,
 		"total_gain: 0x%x, d_gain: 0x%x, d_fine_gain: 0x%x, c_gain: 0x%x\n",
 		gain, coarse_dgain, fine_dgain, coarse_again);
@@ -1159,7 +1160,7 @@
 	switch (ctrl->id) {
 	case V4L2_CID_VBLANK:
 		/* Update max exposure while meeting expected vblanking */
-		max = sc2336->cur_mode->height + ctrl->val - 8;
+		max = sc2336->cur_mode->height + ctrl->val - 6;
 		__v4l2_ctrl_modify_range(sc2336->exposure,
 					 sc2336->exposure->minimum, max,
 					 sc2336->exposure->step,
@@ -1282,7 +1283,7 @@
 					    V4L2_CID_VBLANK, vblank_def,
 					    SC2336_VTS_MAX - mode->height,
 					    1, vblank_def);
-	exposure_max = mode->vts_def - 8;
+	exposure_max = mode->vts_def - 6;
 	sc2336->exposure = v4l2_ctrl_new_std(handler, &sc2336_ctrl_ops,
 					      V4L2_CID_EXPOSURE, SC2336_EXPOSURE_MIN,
 					      exposure_max, SC2336_EXPOSURE_STEP,
diff --git a/kernel/drivers/media/i2c/sc2355.c b/kernel/drivers/media/i2c/sc2355.c
new file mode 100644
index 0000000..680d279
--- /dev/null
+++ b/kernel/drivers/media/i2c/sc2355.c
@@ -0,0 +1,1522 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SC2355 driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ * V0.1.0: MIPI is ok.
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/rk-camera-module.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <linux/pinctrl/consumer.h>
+
+#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x00)
+#ifndef V4L2_CID_DIGITAL_GAIN
+#define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
+#endif
+
+#define MIPI_FREQ_180M			180000000
+#define MIPI_FREQ_360M			360000000
+
+#define PIXEL_RATE_WITH_180M		(MIPI_FREQ_180M * 2 / 10)
+#define PIXEL_RATE_WITH_360M		(MIPI_FREQ_360M * 2 / 10)
+
+#define SC2355_XVCLK_FREQ		24000000
+
+#define CHIP_ID				    0xeb2c
+#define SC2355_REG_CHIP_ID		0x3107
+
+#define SC2355_REG_CTRL_MODE	0x0100
+#define SC2355_MODE_SW_STANDBY	0x0
+#define SC2355_MODE_STREAMING	BIT(0)
+
+#define SC2355_REG_EXPOSURE		0x3e01
+#define	SC2355_EXPOSURE_MIN		6
+#define	SC2355_EXPOSURE_STEP	1
+#define SC2355_VTS_MAX			0xffff
+
+#define SC2355_REG_COARSE_AGAIN	0x3e09
+
+#define	ANALOG_GAIN_MIN			0x01
+#define	ANALOG_GAIN_MAX			0xF8
+#define	ANALOG_GAIN_STEP		1
+#define	ANALOG_GAIN_DEFAULT		0x1f
+
+#define SC2355_REG_TEST_PATTERN	0x4501
+#define	SC2355_TEST_PATTERN_ENABLE	0xcc
+#define	SC2355_TEST_PATTERN_DISABLE	0xc4
+
+#define SC2355_REG_VTS			0x320e
+
+#define REG_NULL			0xFFFF
+
+#define SC2355_REG_VALUE_08BIT		1
+#define SC2355_REG_VALUE_16BIT		2
+#define SC2355_REG_VALUE_24BIT		3
+
+#define SC2355_NAME			"sc2355"
+
+#define OF_CAMERA_PINCTRL_STATE_DEFAULT	"rockchip,camera_default"
+#define OF_CAMERA_PINCTRL_STATE_SLEEP	"rockchip,camera_sleep"
+
+#define SC2355_FETCH_3RD_BYTE_EXP(VAL) (((VAL) >> 16) & 0xF)	/* 4 Bits */
+#define SC2355_FETCH_2ND_BYTE_EXP(VAL) (((VAL) >> 8) & 0xFF)	/* 8 Bits */
+#define SC2355_FETCH_1ST_BYTE_EXP(VAL) ((VAL) & 0xFF)	/* 4 Bits */
+
+//fps set
+#define SC2355_FPS  (20)
+
+//default exposure
+#define EXP_DEFAULT_TIME_US (8000)
+
+#define SC2355_VTS_30_FPS   0x4e2
+
+#define TIME_MS          1000
+#define SC2355_VTS       (SC2355_VTS_30_FPS * 30 / SC2355_FPS)
+
+#define SC2355_TIME_TO_EXP_LINE_US(time_us) \
+	(uint16_t)(time_us/1000*30*SC2355_VTS_30_FPS/TIME_MS)
+
+#define SC2355_DEFAULT_EXP_REG \
+	SC2355_TIME_TO_EXP_LINE_US(EXP_DEFAULT_TIME_US)
+
+#define SC2355_FSYNC_RISING_MARGIN_TIME (600)//us
+#define SC2355_FSYNC_RISING_MARGIN \
+	SC2355_TIME_TO_EXP_LINE_US(SC2355_FSYNC_RISING_MARGIN_TIME)
+
+#define SC2355_EXP_REG_TO_FSYNC_RISING(exp_reg) \
+	(exp_reg - 15 + SC2355_FSYNC_RISING_MARGIN)
+
+#define SC2355_DEFAULT_FSYNC_RISING \
+	SC2355_EXP_REG_TO_FSYNC_RISING(SC2355_DEFAULT_EXP_REG)
+
+#define SC2355_DEFAULT_FSYNC_FALLING (0x4c0)
+#define SC2355_DEFAULT_FSYNC_FALLING_BINNING (0x4c0/2 + 2)
+#define SC2355_FSYNC_RISING_REG (0x3217)
+
+#define SLAVE_MODE
+//slave mode max exp time (RB_ROW)
+#define EXP_MAX_TIME_US (13*1000)
+#define SC2355_SLAVE_RB_ROW SC2355_TIME_TO_EXP_LINE_US(EXP_MAX_TIME_US)
+
+#define BINNING_MODE
+
+static const char *const SC2355_supply_names[] = {
+	"avdd",		/* Analog power */
+	"dovdd",	/* Digital I/O power */
+	"dvdd",		/* Digital core power */
+};
+
+#define SC2355_NUM_SUPPLIES ARRAY_SIZE(SC2355_supply_names)
+
+enum {
+	LINK_FREQ_180M_INDEX,
+	LINK_FREQ_360M_INDEX,
+};
+
+struct regval {
+	u16 addr;
+	u8 val;
+};
+
+struct SC2355_mode {
+	u32 width;
+	u32 height;
+	struct v4l2_fract max_fps;
+	u32 hts_def;
+	u32 vts_def;
+	u32 exp_def;
+	u32 link_freq_index;
+	u64 pixel_rate;
+	const struct regval *reg_list;
+	u32 lanes;
+	u32 bus_fmt;
+};
+
+struct SC2355 {
+	struct i2c_client	*client;
+	struct clk		*xvclk;
+	struct gpio_desc	*reset_gpio;
+	struct gpio_desc	*pwdn_gpio;
+	struct regulator_bulk_data supplies[SC2355_NUM_SUPPLIES];
+	struct pinctrl		*pinctrl;
+	struct pinctrl_state	*pins_default;
+	struct pinctrl_state	*pins_sleep;
+	struct v4l2_subdev	subdev;
+	struct media_pad	pad;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl	*exposure;
+	struct v4l2_ctrl	*anal_gain;
+	struct v4l2_ctrl	*digi_gain;
+	struct v4l2_ctrl	*hblank;
+	struct v4l2_ctrl	*vblank;
+	struct v4l2_ctrl	*test_pattern;
+	struct v4l2_ctrl	*pixel_rate;
+	struct v4l2_ctrl	*link_freq;
+	struct mutex		mutex;
+	struct v4l2_fract	cur_fps;
+	u32			cur_vts;
+	bool			streaming;
+	bool			power_on;
+	const struct SC2355_mode *cur_mode;
+	u32			module_index;
+	const char		*module_facing;
+	const char		*module_name;
+	const char		*len_name;
+};
+
+#define to_SC2355(sd) container_of(sd, struct SC2355, subdev)
+
+/*
+ * Xclk 24Mhz
+ * Pclk 72Mhz
+ * linelength ()
+ * framelength ()
+ * grabwindow_width 800
+ * grabwindow_height 600
+ * mipi 1 lane
+ * max_framerate 30fps
+ * mipi_datarate per lane 360Mbps
+ */
+static const struct regval SC2355_1lane_10bit_360Mbps_800x600_30fps_regs[] = {
+	{0x0103,0x01},
+	{0x0100,0x00},
+	{0x36e9,0x80},
+	{0x36ea,0x0f},
+	{0x36eb,0x24},
+	{0x36ed,0x14},
+	{0x36e9,0x01},
+	{0x301f,0x0c},
+	{0x303f,0x82},
+	{0x3208,0x03},
+	{0x3209,0x20},
+	{0x320a,0x02},
+	{0x320b,0x58},
+	{0x3211,0x02},
+	{0x3213,0x02},
+	{0x3215,0x31},
+	{0x3220,0x01},
+	{0x3248,0x02},
+	{0x3253,0x0a},
+	{0x3301,0xff},
+	{0x3302,0xff},
+	{0x3303,0x10},
+	{0x3306,0x28},
+	{0x3307,0x02},
+	{0x330a,0x00},
+	{0x330b,0xb0},
+	{0x3318,0x02},
+	{0x3320,0x06},
+	{0x3321,0x02},
+	{0x3326,0x12},
+	{0x3327,0x0e},
+	{0x3328,0x03},
+	{0x3329,0x0f},
+	{0x3364,0x4f},
+	{0x33b3,0x40},
+	{0x33f9,0x2c},
+	{0x33fb,0x38},
+	{0x33fc,0x0f},
+	{0x33fd,0x1f},
+	{0x349f,0x03},
+	{0x34a6,0x01},
+	{0x34a7,0x1f},
+	{0x34a8,0x40},
+	{0x34a9,0x30},
+	{0x34ab,0xa6},
+	{0x34ad,0xa6},
+	{0x3622,0x60},
+	{0x3623,0x40},
+	{0x3624,0x61},
+	{0x3625,0x08},
+	{0x3626,0x03},
+	{0x3630,0xa8},
+	{0x3631,0x84},
+	{0x3632,0x90},
+	{0x3633,0x43},
+	{0x3634,0x09},
+	{0x3635,0x82},
+	{0x3636,0x48},
+	{0x3637,0xe4},
+	{0x3641,0x22},
+	{0x3670,0x0f},
+	{0x3674,0xc0},
+	{0x3675,0xc0},
+	{0x3676,0xc0},
+	{0x3677,0x86},
+	{0x3678,0x88},
+	{0x3679,0x8c},
+	{0x367c,0x01},
+	{0x367d,0x0f},
+	{0x367e,0x01},
+	{0x367f,0x0f},
+	{0x3690,0x63},
+	{0x3691,0x63},
+	{0x3692,0x73},
+	{0x369c,0x01},
+	{0x369d,0x1f},
+	{0x369e,0x8a},
+	{0x369f,0x9e},
+	{0x36a0,0xda},
+	{0x36a1,0x01},
+	{0x36a2,0x03},
+	{0x3900,0x0d},
+	{0x3904,0x04},
+	{0x3905,0x98},
+	{0x391b,0x81},
+	{0x391c,0x10},
+	{0x391d,0x19},
+	{0x3933,0x01},
+	{0x3934,0x82},
+	{0x3940,0x5d},
+	{0x3942,0x01},
+	{0x3943,0x82},
+	{0x3949,0xc8},
+	{0x394b,0x64},
+	{0x3952,0x02},
+	{0x3e00,0x00},
+	{0x3e01,0x4d},
+	{0x3e02,0xe0},
+	{0x4502,0x34},
+	{0x4509,0x30},
+	{0x450a,0x71},
+	{0x4819,0x09},
+	{0x481b,0x05},
+	{0x481d,0x13},
+	{0x481f,0x04},
+	{0x4821,0x0a},
+	{0x4823,0x05},
+	{0x4825,0x04},
+	{0x4827,0x05},
+	{0x4829,0x08},
+	{0x5000,0x46},
+	{0x5900,0xf1}, //fix noise
+	{0x5901,0x04},
+
+	//vts
+	{0x320e,(SC2355_VTS>>8)&0xff},
+	{0x320f,SC2355_VTS&0xff},
+
+	//exp
+	{0x3e00,SC2355_FETCH_3RD_BYTE_EXP(SC2355_DEFAULT_EXP_REG)},
+	{0x3e01,SC2355_FETCH_2ND_BYTE_EXP(SC2355_DEFAULT_EXP_REG)},
+	{0x3e02,SC2355_FETCH_1ST_BYTE_EXP(SC2355_DEFAULT_EXP_REG)},
+
+	//[flip]
+	{0x3221,0x3 << 5},
+
+	//[gain=1]
+	{0x3e09,0x00},
+
+	//fsync
+#ifndef SLAVE_MODE
+	{0x300b,0x44},//FSYNC out
+	{0x3217,SC2355_DEFAULT_FSYNC_RISING},
+	{0x322e,(SC2355_DEFAULT_FSYNC_FALLING_BINNING>>8)&0xff},
+	{0x322f,SC2355_DEFAULT_FSYNC_FALLING_BINNING&0xff},
+#else
+	{0x3222, 0x01 << 1},//slave mode
+	{0x300a, 0x00 << 2},//input mode
+
+	{0x3230, (SC2355_SLAVE_RB_ROW >> 8)&0xff},
+	{0x3231, SC2355_SLAVE_RB_ROW & 0xff},
+#endif
+
+	{REG_NULL, 0x00},
+};
+
+
+/*
+ * Xclk 24Mhz
+ * Pclk 72Mhz
+ * linelength ()
+ * framelength ()
+ * grabwindow_width 1600
+ * grabwindow_height 1200
+ * mipi 1 lane
+ * max_framerate 30fps
+ */
+static const struct regval SC2355_1lane_10bit_1600x1200_30fps_regs[] = {
+	{0x0103,0x01},
+	{0x0100,0x00},
+
+	{0x301f,0x01},
+	{0x3248,0x02},
+	{0x3253,0x0a},
+	{0x3301,0xff},
+	{0x3302,0xff},
+	{0x3303,0x10},
+	{0x3306,0x28},
+	{0x3307,0x02},
+	{0x330a,0x00},
+	{0x330b,0xb0},
+	{0x3318,0x02},
+	{0x3320,0x06},
+	{0x3321,0x02},
+	{0x3326,0x12},
+	{0x3327,0x0e},
+	{0x3328,0x03},
+	{0x3329,0x0f},
+	{0x3364,0x4f},
+	{0x33b3,0x40},
+	{0x33f9,0x2c},
+	{0x33fb,0x38},
+	{0x33fc,0x0f},
+	{0x33fd,0x1f},
+	{0x349f,0x03},
+	{0x34a6,0x01},
+	{0x34a7,0x1f},
+	{0x34a8,0x40},
+	{0x34a9,0x30},
+	{0x34ab,0xa6},
+	{0x34ad,0xa6},
+	{0x3622,0x60},
+	{0x3623,0x40},
+	{0x3624,0x61},
+	{0x3625,0x08},
+	{0x3626,0x03},
+	{0x3630,0xa8},
+	{0x3631,0x84},
+	{0x3632,0x90},
+	{0x3633,0x43},
+	{0x3634,0x09},
+	{0x3635,0x82},
+	{0x3636,0x48},
+	{0x3637,0xe4},
+	{0x3641,0x22},
+	{0x3670,0x0f},
+	{0x3674,0xc0},
+	{0x3675,0xc0},
+	{0x3676,0xc0},
+	{0x3677,0x86},
+	{0x3678,0x88},
+	{0x3679,0x8c},
+	{0x367c,0x01},
+	{0x367d,0x0f},
+	{0x367e,0x01},
+	{0x367f,0x0f},
+	{0x3690,0x63},
+	{0x3691,0x63},
+	{0x3692,0x73},
+	{0x369c,0x01},
+	{0x369d,0x1f},
+	{0x369e,0x8a},
+	{0x369f,0x9e},
+	{0x36a0,0xda},
+	{0x36a1,0x01},
+	{0x36a2,0x03},
+	{0x36e9,0x01},
+	{0x36ea,0x0f},
+	{0x36eb,0x25},
+	{0x36ed,0x04},
+	{0x3900,0x0d},
+	{0x3904,0x06},
+	{0x3905,0x98},
+	{0x391b,0x81},
+	{0x391c,0x10},
+	{0x391d,0x19},
+	{0x3933,0x01},
+	{0x3934,0x82},
+	{0x3940,0x5d},
+	{0x3942,0x01},
+	{0x3943,0x82},
+	{0x3949,0xc8},
+	{0x394b,0x64},
+	{0x3952,0x02},
+
+	//vts
+	{0x320e,(SC2355_VTS>>8)&0xff},
+	{0x320f,SC2355_VTS&0xff},
+
+	{0x3e00, SC2355_FETCH_3RD_BYTE_EXP(SC2355_DEFAULT_EXP_REG)},
+	{0x3e01, SC2355_FETCH_2ND_BYTE_EXP(SC2355_DEFAULT_EXP_REG)},
+	{0x3e02, SC2355_FETCH_1ST_BYTE_EXP(SC2355_DEFAULT_EXP_REG)},
+	{0x4502,0x34},
+	{0x4509,0x30},
+	{0x450a,0x71},
+
+	//[flip]
+	{0x3221,0x3 << 5},
+	//[gain=2]
+	{0x3e09,0x01},
+
+#ifndef SLAVE_MODE
+	{0x300b,0x44},//FSYNC out
+	{0x3217,SC2355_DEFAULT_FSYNC_RISING},
+	{0x322e,(SC2355_DEFAULT_FSYNC_FALLING>>8)&0xff},
+	{0x322f,SC2355_DEFAULT_FSYNC_FALLING&0xff},
+#else
+	{0x3222, 0x01 << 1},//slave mode
+	{0x300a, 0x00 << 2},//input mode
+
+	{0x3230, (SC2355_SLAVE_RB_ROW >> 8)&0xff},//input mode
+	{0x3231, SC2355_SLAVE_RB_ROW & 0xff},//input mode
+#endif
+};
+
+static const struct SC2355_mode supported_modes[] = {
+#ifdef BINNING_MODE
+	{
+		.width = 800,
+		.height = 600,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 300000,
+		},
+		.exp_def = SC2355_DEFAULT_EXP_REG,
+		.hts_def = 0x640,
+		.vts_def = SC2355_VTS,
+		.link_freq_index = LINK_FREQ_360M_INDEX,
+		.pixel_rate      = PIXEL_RATE_WITH_360M,
+		.reg_list = SC2355_1lane_10bit_360Mbps_800x600_30fps_regs,
+		.lanes    = 1,
+		.bus_fmt  = MEDIA_BUS_FMT_Y10_1X10,
+	},
+#else
+	{
+		.width = 1600,
+		.height = 1200,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 300000,
+		},
+		.exp_def = SC2355_DEFAULT_EXP_REG,
+		.hts_def = 0x640,
+		.vts_def = SC2355_VTS,
+		.link_freq_index = LINK_FREQ_360M_INDEX,
+		.pixel_rate      = PIXEL_RATE_WITH_360M,
+		.reg_list = SC2355_1lane_10bit_1600x1200_30fps_regs,
+		.lanes    = 1,
+		.bus_fmt  = MEDIA_BUS_FMT_Y10_1X10,
+	},
+#endif
+};
+
+static const char *const SC2355_test_pattern_menu[] = {
+	"Disabled",
+	"Vertical Color Bar Type 1",
+	"Vertical Color Bar Type 2",
+	"Vertical Color Bar Type 3",
+	"Vertical Color Bar Type 4"
+};
+
+static const s64 link_freq_menu_items[] = {
+	MIPI_FREQ_180M,
+	MIPI_FREQ_360M,
+};
+
+/* Write registers up to 4 at a time */
+static int SC2355_write_reg(struct i2c_client *client,
+			     u16 reg, u32 len, u32 val)
+{
+	u32 buf_i, val_i;
+	u8 buf[6];
+	u8 *val_p;
+	__be32 val_be;
+	u32 ret;
+
+	if (len > 4)
+		return -EINVAL;
+
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xff;
+
+	val_be = cpu_to_be32(val);
+	val_p = (u8 *)&val_be;
+	buf_i = 2;
+	val_i = 4 - len;
+
+	while (val_i < 4)
+		buf[buf_i++] = val_p[val_i++];
+
+	ret = i2c_master_send(client, buf, len + 2);
+	if (ret != len + 2)
+		return -EIO;
+
+	return 0;
+}
+
+static int SC2355_write_array(struct i2c_client *client,
+			       const struct regval *regs)
+{
+	u32 i;
+	int ret = 0;
+
+	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) {
+		ret = SC2355_write_reg(client, regs[i].addr,
+					SC2355_REG_VALUE_08BIT, regs[i].val);
+	}
+
+	return ret;
+}
+
+/* Read registers up to 4 at a time */
+static int SC2355_read_reg(struct i2c_client *client,
+			    u16 reg, unsigned int len, u32 *val)
+{
+	struct i2c_msg msgs[2];
+	u8 *data_be_p;
+	__be32 data_be = 0;
+	__be16 reg_addr_be = cpu_to_be16(reg);
+	int ret;
+
+	if (len > 4 || !len)
+		return -EINVAL;
+
+	data_be_p = (u8 *)&data_be;
+	/* Write register address */
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = 2;
+	msgs[0].buf = (u8 *)&reg_addr_be;
+
+	/* Read data from register */
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = len;
+	msgs[1].buf = &data_be_p[4 - len];
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs))
+		return -EIO;
+
+	*val = be32_to_cpu(data_be);
+
+	return 0;
+}
+
+static int SC2355_get_reso_dist(const struct SC2355_mode *mode,
+				 struct v4l2_mbus_framefmt *framefmt)
+{
+	return abs(mode->width - framefmt->width) +
+	       abs(mode->height - framefmt->height);
+}
+
+static const struct SC2355_mode *
+SC2355_find_best_fit(struct v4l2_subdev_format *fmt)
+{
+	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
+	int dist;
+	int cur_best_fit = 0;
+	int cur_best_fit_dist = -1;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+		dist = SC2355_get_reso_dist(&supported_modes[i], framefmt);
+		if ((cur_best_fit_dist == -1 || dist < cur_best_fit_dist) &&
+		    (supported_modes[i].bus_fmt == framefmt->code)) {
+			cur_best_fit_dist = dist;
+			cur_best_fit = i;
+		}
+	}
+	return &supported_modes[cur_best_fit];
+}
+
+static int SC2355_set_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct SC2355 *SC2355 = to_SC2355(sd);
+	const struct SC2355_mode *mode;
+	s64 h_blank, vblank_def;
+
+	mutex_lock(&SC2355->mutex);
+
+	mode = SC2355_find_best_fit(fmt);
+	fmt->format.code = mode->bus_fmt;
+	fmt->format.width = mode->width;
+	fmt->format.height = mode->height;
+	fmt->format.field = V4L2_FIELD_NONE;
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+#else
+		mutex_unlock(&SC2355->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		SC2355->cur_mode = mode;
+		h_blank = mode->hts_def - mode->width;
+		__v4l2_ctrl_modify_range(SC2355->hblank, h_blank,
+					 h_blank, 1, h_blank);
+		vblank_def = mode->vts_def - mode->height;
+		__v4l2_ctrl_modify_range(SC2355->vblank, vblank_def,
+					 SC2355_VTS_MAX - mode->height,
+					 1, vblank_def);
+		__v4l2_ctrl_s_ctrl_int64(SC2355->pixel_rate, mode->pixel_rate);
+		__v4l2_ctrl_s_ctrl(SC2355->link_freq, mode->link_freq_index);
+		SC2355->cur_vts = mode->vts_def;
+		SC2355->cur_fps = mode->max_fps;
+	}
+
+	mutex_unlock(&SC2355->mutex);
+
+	return 0;
+}
+
+static int SC2355_get_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct SC2355 *SC2355 = to_SC2355(sd);
+	const struct SC2355_mode *mode = SC2355->cur_mode;
+
+	mutex_lock(&SC2355->mutex);
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+#else
+		mutex_unlock(&SC2355->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		fmt->format.width = mode->width;
+		fmt->format.height = mode->height;
+		fmt->format.code = mode->bus_fmt;
+		fmt->format.field = V4L2_FIELD_NONE;
+	}
+	mutex_unlock(&SC2355->mutex);
+
+	return 0;
+}
+
+static int SC2355_enum_mbus_code(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_pad_config *cfg,
+				  struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct SC2355 *SC2355 = to_SC2355(sd);
+
+	if (code->index != 0)
+		return -EINVAL;
+	code->code = SC2355->cur_mode->bus_fmt;
+
+	return 0;
+}
+
+static int SC2355_enum_frame_sizes(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_pad_config *cfg,
+				    struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	if (fse->code != supported_modes[fse->index].bus_fmt)
+		return -EINVAL;
+
+	fse->min_width = supported_modes[fse->index].width;
+	fse->max_width = supported_modes[fse->index].width;
+	fse->max_height = supported_modes[fse->index].height;
+	fse->min_height = supported_modes[fse->index].height;
+
+	return 0;
+}
+
+static int SC2355_enable_test_pattern(struct SC2355 *SC2355, u32 pattern)
+{
+	u32 val;
+
+	if (pattern)
+		val = (pattern - 1) | SC2355_TEST_PATTERN_ENABLE;
+	else
+		val = SC2355_TEST_PATTERN_DISABLE;
+
+	return SC2355_write_reg(SC2355->client, SC2355_REG_TEST_PATTERN,
+				 SC2355_REG_VALUE_08BIT, val);
+}
+
+static void SC2355_get_module_inf(struct SC2355 *SC2355,
+				   struct rkmodule_inf *inf)
+{
+	memset(inf, 0, sizeof(*inf));
+	strscpy(inf->base.sensor, SC2355_NAME, sizeof(inf->base.sensor));
+	strscpy(inf->base.module, SC2355->module_name,
+		sizeof(inf->base.module));
+	strscpy(inf->base.lens, SC2355->len_name, sizeof(inf->base.lens));
+}
+
+static long SC2355_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	struct SC2355 *SC2355 = to_SC2355(sd);
+	long ret = 0;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		SC2355_get_module_inf(SC2355, (struct rkmodule_inf *)arg);
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+
+		stream = *((u32 *)arg);
+
+		if (stream)
+			ret = SC2355_write_reg(SC2355->client, SC2355_REG_CTRL_MODE,
+						SC2355_REG_VALUE_08BIT, SC2355_MODE_STREAMING);
+		else
+			ret = SC2355_write_reg(SC2355->client, SC2355_REG_CTRL_MODE,
+						SC2355_REG_VALUE_08BIT, SC2355_MODE_SW_STANDBY);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long SC2355_compat_ioctl32(struct v4l2_subdev *sd,
+				   unsigned int cmd, unsigned long arg)
+{
+	void __user *up = compat_ptr(arg);
+	struct rkmodule_inf *inf;
+	long ret = 0;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
+		if (!inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = SC2355_ioctl(sd, cmd, inf);
+		if (!ret) {
+			ret = copy_to_user(up, inf, sizeof(*inf));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(inf);
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		if (copy_from_user(&stream, up, sizeof(u32)))
+			return -EFAULT;
+
+		ret = SC2355_ioctl(sd, cmd, &stream);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+#endif
+
+static int SC2355_set_ctrl_gain(struct SC2355 *SC2355, u32 a_gain)
+{
+	int ret = 0;
+
+	if (a_gain > 1)
+		a_gain = ((a_gain + 1) >> 1) << 1;
+	a_gain -=1;
+
+	ret |= SC2355_write_reg(SC2355->client,
+				 SC2355_REG_COARSE_AGAIN,
+				 SC2355_REG_VALUE_08BIT,
+				 a_gain);
+
+	return ret;
+}
+
+
+static int __SC2355_start_stream(struct SC2355 *SC2355)
+{
+	int ret;
+
+	ret = SC2355_write_array(SC2355->client, SC2355->cur_mode->reg_list);
+	if (ret)
+		return ret;
+
+	/* In case these controls are set before streaming */
+	mutex_unlock(&SC2355->mutex);
+	ret = v4l2_ctrl_handler_setup(&SC2355->ctrl_handler);
+	mutex_lock(&SC2355->mutex);
+	if (ret)
+		return ret;
+
+	ret = SC2355_write_reg(SC2355->client, SC2355_REG_CTRL_MODE,
+			SC2355_REG_VALUE_08BIT, SC2355_MODE_STREAMING);
+
+	return ret;
+}
+
+static int __SC2355_stop_stream(struct SC2355 *SC2355)
+{
+	return SC2355_write_reg(SC2355->client, SC2355_REG_CTRL_MODE,
+				 SC2355_REG_VALUE_08BIT, SC2355_MODE_SW_STANDBY);
+}
+
+static int SC2355_s_stream(struct v4l2_subdev *sd, int on)
+{
+	struct SC2355 *SC2355 = to_SC2355(sd);
+	struct i2c_client *client = SC2355->client;
+	unsigned int fps;
+	int ret = 0;
+
+	mutex_lock(&SC2355->mutex);
+	on = !!on;
+	if (on == SC2355->streaming)
+		goto unlock_and_return;
+
+	fps = DIV_ROUND_CLOSEST(SC2355->cur_mode->max_fps.denominator,
+				SC2355->cur_mode->max_fps.numerator);
+
+	dev_info(&SC2355->client->dev, "%s: on: %d, %dx%d@%d\n", __func__, on,
+		 SC2355->cur_mode->width,
+		 SC2355->cur_mode->height,
+		 fps);
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		ret = __SC2355_start_stream(SC2355);
+		if (ret) {
+			v4l2_err(sd, "start stream failed while write regs\n");
+			pm_runtime_put(&client->dev);
+			goto unlock_and_return;
+		}
+	} else {
+		__SC2355_stop_stream(SC2355);
+		pm_runtime_put(&client->dev);
+	}
+
+	SC2355->streaming = on;
+
+unlock_and_return:
+	mutex_unlock(&SC2355->mutex);
+
+	return ret;
+}
+
+static int SC2355_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct SC2355 *SC2355 = to_SC2355(sd);
+	struct i2c_client *client = SC2355->client;
+	int ret = 0;
+
+	mutex_lock(&SC2355->mutex);
+
+	/* If the power state is not modified - no work to do. */
+	if (SC2355->power_on == !!on)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+		SC2355->power_on = true;
+	} else {
+		pm_runtime_put(&client->dev);
+		SC2355->power_on = false;
+	}
+
+unlock_and_return:
+	mutex_unlock(&SC2355->mutex);
+
+	return ret;
+}
+
+static int SC2355_g_frame_interval(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_frame_interval *fi)
+{
+	struct SC2355 *SC2355 = to_SC2355(sd);
+	const struct SC2355_mode *mode = SC2355->cur_mode;
+
+	if (SC2355->streaming)
+		fi->interval = SC2355->cur_fps;
+	else
+		fi->interval = mode->max_fps;
+
+	return 0;
+}
+
+/* Calculate the delay in us by clock rate and clock cycles */
+static inline u32 SC2355_cal_delay(u32 cycles)
+{
+	return DIV_ROUND_UP(cycles, SC2355_XVCLK_FREQ / 1000 / 1000);
+}
+
+static int __SC2355_power_on(struct SC2355 *SC2355)
+{
+	int ret;
+	u32 delay_us;
+	struct device *dev = &SC2355->client->dev;
+
+	if (!IS_ERR_OR_NULL(SC2355->pins_default)) {
+		ret = pinctrl_select_state(SC2355->pinctrl,
+					   SC2355->pins_default);
+		if (ret < 0)
+			dev_err(dev, "could not set pins\n");
+	}
+
+	ret = clk_set_rate(SC2355->xvclk, SC2355_XVCLK_FREQ);
+	if (ret < 0)
+		dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
+	if (clk_get_rate(SC2355->xvclk) != SC2355_XVCLK_FREQ)
+		dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
+	ret = clk_prepare_enable(SC2355->xvclk);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable xvclk\n");
+		return ret;
+	}
+
+	ret = regulator_bulk_enable(SC2355_NUM_SUPPLIES, SC2355->supplies);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable regulators\n");
+		goto disable_clk;
+	}
+
+	if (!IS_ERR(SC2355->reset_gpio))
+		gpiod_set_value_cansleep(SC2355->reset_gpio, 1);
+
+	usleep_range(1000, 2000);
+
+	if (!IS_ERR(SC2355->pwdn_gpio))
+		gpiod_set_value_cansleep(SC2355->pwdn_gpio, 1);
+
+	if (!IS_ERR(SC2355->reset_gpio))
+		gpiod_set_value_cansleep(SC2355->reset_gpio, 0);
+
+	/* 8192 cycles prior to first SCCB transaction */
+	delay_us = SC2355_cal_delay(8192);
+	usleep_range(delay_us, delay_us * 2);
+
+	return 0;
+
+disable_clk:
+	clk_disable_unprepare(SC2355->xvclk);
+
+	return ret;
+}
+
+static void __SC2355_power_off(struct SC2355 *SC2355)
+{
+	int ret;
+
+	if (!IS_ERR(SC2355->reset_gpio))
+		gpiod_set_value_cansleep(SC2355->reset_gpio, 1);
+
+	if (!IS_ERR(SC2355->pwdn_gpio))
+		gpiod_set_value_cansleep(SC2355->pwdn_gpio, 0);
+	clk_disable_unprepare(SC2355->xvclk);
+	if (!IS_ERR_OR_NULL(SC2355->pins_sleep)) {
+		ret = pinctrl_select_state(SC2355->pinctrl,
+					   SC2355->pins_sleep);
+		if (ret < 0)
+			dev_dbg(&SC2355->client->dev, "could not set pins\n");
+	}
+	regulator_bulk_disable(SC2355_NUM_SUPPLIES, SC2355->supplies);
+}
+
+static int SC2355_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct SC2355 *SC2355 = to_SC2355(sd);
+
+	return __SC2355_power_on(SC2355);
+}
+
+static int SC2355_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct SC2355 *SC2355 = to_SC2355(sd);
+
+	__SC2355_power_off(SC2355);
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int SC2355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct SC2355 *SC2355 = to_SC2355(sd);
+	struct v4l2_mbus_framefmt *try_fmt =
+		v4l2_subdev_get_try_format(sd, fh->pad, 0);
+	const struct SC2355_mode *def_mode = &supported_modes[0];
+
+	mutex_lock(&SC2355->mutex);
+	/* Initialize try_fmt */
+	try_fmt->width = def_mode->width;
+	try_fmt->height = def_mode->height;
+	try_fmt->code = def_mode->bus_fmt;
+	try_fmt->field = V4L2_FIELD_NONE;
+
+	mutex_unlock(&SC2355->mutex);
+	/* No crop or compose */
+
+	return 0;
+}
+#endif
+
+static int SC2355_enum_frame_interval(struct v4l2_subdev *sd,
+				       struct v4l2_subdev_pad_config *cfg,
+				       struct v4l2_subdev_frame_interval_enum *fie)
+{
+	if (fie->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	fie->code = supported_modes[fie->index].bus_fmt;
+	fie->width = supported_modes[fie->index].width;
+	fie->height = supported_modes[fie->index].height;
+	fie->interval = supported_modes[fie->index].max_fps;
+	return 0;
+}
+
+static int SC2355_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
+				 struct v4l2_mbus_config *config)
+{
+	u32 val = 0;
+	struct SC2355 *SC2355 = to_SC2355(sd);
+
+	val = 1 << (SC2355->cur_mode->lanes - 1) |
+	      V4L2_MBUS_CSI2_CHANNEL_0 |
+	      V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+	config->type = V4L2_MBUS_CSI2_DPHY;
+	config->flags = val;
+
+	return 0;
+}
+
+static const struct dev_pm_ops SC2355_pm_ops = {
+	SET_RUNTIME_PM_OPS(SC2355_runtime_suspend,
+			   SC2355_runtime_resume, NULL)
+};
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static const struct v4l2_subdev_internal_ops SC2355_internal_ops = {
+	.open = SC2355_open,
+};
+#endif
+
+static const struct v4l2_subdev_core_ops SC2355_core_ops = {
+	.s_power = SC2355_s_power,
+	.ioctl = SC2355_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl32 = SC2355_compat_ioctl32,
+#endif
+};
+
+static const struct v4l2_subdev_video_ops SC2355_video_ops = {
+	.s_stream = SC2355_s_stream,
+	.g_frame_interval = SC2355_g_frame_interval,
+};
+
+static const struct v4l2_subdev_pad_ops SC2355_pad_ops = {
+	.enum_mbus_code = SC2355_enum_mbus_code,
+	.enum_frame_size = SC2355_enum_frame_sizes,
+	.enum_frame_interval = SC2355_enum_frame_interval,
+	.get_fmt = SC2355_get_fmt,
+	.set_fmt = SC2355_set_fmt,
+	.get_mbus_config = SC2355_g_mbus_config,
+};
+
+static const struct v4l2_subdev_ops SC2355_subdev_ops = {
+	.core	= &SC2355_core_ops,
+	.video	= &SC2355_video_ops,
+	.pad	= &SC2355_pad_ops,
+};
+
+static void SC2355_modify_fps_info(struct SC2355 *SC2355)
+{
+	const struct SC2355_mode *mode = SC2355->cur_mode;
+
+	SC2355->cur_fps.denominator = mode->max_fps.denominator * SC2355->cur_vts /
+				       mode->vts_def;
+}
+
+static int SC2355_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct SC2355 *SC2355 = container_of(ctrl->handler,
+					       struct SC2355, ctrl_handler);
+	struct i2c_client *client = SC2355->client;
+	s64 max;
+	int ret = 0;
+#ifndef SLAVE_MODE
+	u16 rising_reg;
+#endif
+
+	/* Propagate change of current control to all related controls */
+	switch (ctrl->id) {
+	case V4L2_CID_VBLANK:
+		/* Update max exposure while meeting expected vblanking */
+		max = SC2355->cur_mode->height + ctrl->val - 6;
+		__v4l2_ctrl_modify_range(SC2355->exposure,
+					 SC2355->exposure->minimum, max,
+					 SC2355->exposure->step,
+					 SC2355->exposure->default_value);
+		break;
+	}
+
+	if (!pm_runtime_get_if_in_use(&client->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		/* 4 least significant bits of expsoure are fractional part */
+		ret = SC2355_write_reg(SC2355->client, SC2355_REG_EXPOSURE,
+					SC2355_REG_VALUE_16BIT, ctrl->val << 4);
+
+#ifndef SLAVE_MODE
+		/* set fsync rising */
+		rising_reg = SC2355_EXP_REG_TO_FSYNC_RISING(ctrl->val);
+		if (rising_reg > 0xff) {
+			rising_reg = 0xff;
+			dev_warn(&client->dev,
+					"error: rising reg exceed max val 0xff.\n");
+		}
+
+		dev_info(&client->dev, "rising: reg:%d\n", rising_reg);
+
+		ret |= SC2355_write_reg(SC2355->client, SC2355_FSYNC_RISING_REG,
+					SC2355_REG_VALUE_08BIT, rising_reg);
+#endif
+
+		break;
+	case V4L2_CID_ANALOGUE_GAIN:
+		ret = SC2355_set_ctrl_gain(SC2355, ctrl->val);
+		break;
+	case V4L2_CID_VBLANK:
+		ret = SC2355_write_reg(SC2355->client, SC2355_REG_VTS,
+					SC2355_REG_VALUE_16BIT,
+					ctrl->val + SC2355->cur_mode->height);
+		if (!ret)
+			SC2355->cur_vts = ctrl->val + SC2355->cur_mode->height;
+		if (SC2355->cur_vts != SC2355->cur_mode->vts_def)
+			SC2355_modify_fps_info(SC2355);
+		break;
+	case V4L2_CID_TEST_PATTERN:
+		ret = SC2355_enable_test_pattern(SC2355, ctrl->val);
+		break;
+	default:
+		dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
+			 __func__, ctrl->id, ctrl->val);
+		break;
+	}
+
+	pm_runtime_put(&client->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops SC2355_ctrl_ops = {
+	.s_ctrl = SC2355_set_ctrl,
+};
+
+static int SC2355_initialize_controls(struct SC2355 *SC2355)
+{
+	const struct SC2355_mode *mode;
+	struct v4l2_ctrl_handler *handler;
+	s64 exposure_max, vblank_def;
+	u32 h_blank;
+	int ret;
+
+	handler = &SC2355->ctrl_handler;
+	mode = SC2355->cur_mode;
+	ret = v4l2_ctrl_handler_init(handler, 8);
+	if (ret)
+		return ret;
+	handler->lock = &SC2355->mutex;
+
+	SC2355->link_freq = v4l2_ctrl_new_int_menu(handler,
+						NULL, V4L2_CID_LINK_FREQ,
+						ARRAY_SIZE(link_freq_menu_items) - 1, 0,
+						link_freq_menu_items);
+
+	SC2355->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
+						V4L2_CID_PIXEL_RATE,
+						0, PIXEL_RATE_WITH_360M,
+						1, mode->pixel_rate);
+
+	__v4l2_ctrl_s_ctrl(SC2355->link_freq, mode->pixel_rate);
+
+	h_blank = mode->hts_def - mode->width;
+	SC2355->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
+					    h_blank, h_blank, 1, h_blank);
+	if (SC2355->hblank)
+		SC2355->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	vblank_def = mode->vts_def - mode->height;
+	SC2355->cur_vts = mode->vts_def;
+	SC2355->cur_fps = mode->max_fps;
+	SC2355->vblank = v4l2_ctrl_new_std(handler, &SC2355_ctrl_ops,
+					    V4L2_CID_VBLANK, vblank_def,
+					    SC2355_VTS_MAX - mode->height,
+					    1, vblank_def);
+
+	exposure_max = mode->vts_def - 6;
+	SC2355->exposure = v4l2_ctrl_new_std(handler, &SC2355_ctrl_ops,
+					      V4L2_CID_EXPOSURE, SC2355_EXPOSURE_MIN,
+					      exposure_max, SC2355_EXPOSURE_STEP,
+					      mode->exp_def);
+
+	SC2355->anal_gain = v4l2_ctrl_new_std(handler, &SC2355_ctrl_ops,
+					       V4L2_CID_ANALOGUE_GAIN, ANALOG_GAIN_MIN,
+					       ANALOG_GAIN_MAX, ANALOG_GAIN_STEP,
+					       ANALOG_GAIN_DEFAULT);
+
+	SC2355->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
+							     &SC2355_ctrl_ops, V4L2_CID_TEST_PATTERN,
+							     ARRAY_SIZE(SC2355_test_pattern_menu) - 1,
+							     0, 0, SC2355_test_pattern_menu);
+
+	if (handler->error) {
+		ret = handler->error;
+		dev_err(&SC2355->client->dev,
+			"Failed to init controls(%d)\n", ret);
+		goto err_free_handler;
+	}
+
+	SC2355->subdev.ctrl_handler = handler;
+
+	return 0;
+
+err_free_handler:
+	v4l2_ctrl_handler_free(handler);
+
+	return ret;
+}
+
+static int SC2355_check_sensor_id(struct SC2355 *SC2355,
+				   struct i2c_client *client)
+{
+	struct device *dev = &SC2355->client->dev;
+	u32 id = 0;
+	int ret;
+
+	ret = SC2355_read_reg(client, SC2355_REG_CHIP_ID,
+			       SC2355_REG_VALUE_16BIT, &id);
+	if (ret || id != CHIP_ID) {
+		dev_err(dev, "Unexpected sensor id(%04x), ret(%d)\n", id, ret);
+		return -ENODEV;
+	}
+
+	dev_info(dev, "Detected SC2355 CHIP ID = 0x%04x sensor\n", CHIP_ID);
+
+	return 0;
+}
+
+static int SC2355_configure_regulators(struct SC2355 *SC2355)
+{
+	unsigned int i;
+
+	for (i = 0; i < SC2355_NUM_SUPPLIES; i++)
+		SC2355->supplies[i].supply = SC2355_supply_names[i];
+
+	return devm_regulator_bulk_get(&SC2355->client->dev,
+				       SC2355_NUM_SUPPLIES,
+				       SC2355->supplies);
+}
+
+static int SC2355_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct device_node *node = dev->of_node;
+	struct SC2355 *SC2355;
+	struct v4l2_subdev *sd;
+	char facing[2];
+	int ret;
+
+	dev_info(dev, "driver version: %02x.%02x.%02x",
+		 DRIVER_VERSION >> 16,
+		 (DRIVER_VERSION & 0xff00) >> 8,
+		 DRIVER_VERSION & 0x00ff);
+
+	SC2355 = devm_kzalloc(dev, sizeof(*SC2355), GFP_KERNEL);
+	if (!SC2355)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
+				   &SC2355->module_index);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
+				       &SC2355->module_facing);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
+				       &SC2355->module_name);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
+				       &SC2355->len_name);
+	if (ret) {
+		dev_err(dev, "could not get module information!\n");
+		return -EINVAL;
+	}
+	SC2355->client = client;
+	SC2355->cur_mode = &supported_modes[0];
+
+	SC2355->xvclk = devm_clk_get(dev, "xvclk");
+	if (IS_ERR(SC2355->xvclk)) {
+		dev_err(dev, "Failed to get xvclk\n");
+		return -EINVAL;
+	}
+
+	SC2355->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(SC2355->reset_gpio))
+		dev_warn(dev, "Failed to get reset-gpios\n");
+
+	SC2355->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
+	if (IS_ERR(SC2355->pwdn_gpio))
+		dev_warn(dev, "Failed to get pwdn-gpios\n");
+	ret = SC2355_configure_regulators(SC2355);
+	if (ret) {
+		dev_err(dev, "Failed to get power regulators\n");
+		return ret;
+	}
+
+	SC2355->pinctrl = devm_pinctrl_get(dev);
+	if (!IS_ERR(SC2355->pinctrl)) {
+		SC2355->pins_default =
+			pinctrl_lookup_state(SC2355->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_DEFAULT);
+		if (IS_ERR(SC2355->pins_default))
+			dev_err(dev, "could not get default pinstate\n");
+
+		SC2355->pins_sleep =
+			pinctrl_lookup_state(SC2355->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_SLEEP);
+		if (IS_ERR(SC2355->pins_sleep))
+			dev_err(dev, "could not get sleep pinstate\n");
+	}
+	mutex_init(&SC2355->mutex);
+
+	sd = &SC2355->subdev;
+	v4l2_i2c_subdev_init(sd, client, &SC2355_subdev_ops);
+	ret = SC2355_initialize_controls(SC2355);
+	if (ret)
+		goto err_destroy_mutex;
+
+	ret = __SC2355_power_on(SC2355);
+	if (ret)
+		goto err_free_handler;
+
+	ret = SC2355_check_sensor_id(SC2355, client);
+	if (ret)
+		goto err_power_off;
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	sd->internal_ops = &SC2355_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+		     V4L2_SUBDEV_FL_HAS_EVENTS;
+#endif
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	SC2355->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &SC2355->pad);
+	if (ret < 0)
+		goto err_power_off;
+#endif
+
+	memset(facing, 0, sizeof(facing));
+	if (strcmp(SC2355->module_facing, "back") == 0)
+		facing[0] = 'b';
+	else
+		facing[0] = 'f';
+
+	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
+		 SC2355->module_index, facing,
+		 SC2355_NAME, dev_name(sd->dev));
+	ret = v4l2_async_register_subdev_sensor_common(sd);
+	if (ret) {
+		dev_err(dev, "v4l2 async register subdev failed\n");
+		goto err_clean_entity;
+	}
+
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_idle(dev);
+
+	return 0;
+
+err_clean_entity:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+err_power_off:
+	__SC2355_power_off(SC2355);
+err_free_handler:
+	v4l2_ctrl_handler_free(&SC2355->ctrl_handler);
+err_destroy_mutex:
+	mutex_destroy(&SC2355->mutex);
+
+	return ret;
+}
+
+static int SC2355_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct SC2355 *SC2355 = to_SC2355(sd);
+
+	v4l2_async_unregister_subdev(sd);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+	v4l2_ctrl_handler_free(&SC2355->ctrl_handler);
+	mutex_destroy(&SC2355->mutex);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		__SC2355_power_off(SC2355);
+	pm_runtime_set_suspended(&client->dev);
+
+	return 0;
+}
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id SC2355_of_match[] = {
+	{ .compatible = "smartsens,sc2355" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, SC2355_of_match);
+#endif
+
+static const struct i2c_device_id SC2355_match_id[] = {
+	{ "smartsens,sc2355", 0 },
+	{ },
+};
+
+static struct i2c_driver SC2355_i2c_driver = {
+	.driver = {
+		.name = SC2355_NAME,
+		.pm = &SC2355_pm_ops,
+		.of_match_table = of_match_ptr(SC2355_of_match),
+	},
+	.probe		= &SC2355_probe,
+	.remove		= &SC2355_remove,
+	.id_table	= SC2355_match_id,
+};
+
+static int __init sensor_mod_init(void)
+{
+	return i2c_add_driver(&SC2355_i2c_driver);
+}
+
+static void __exit sensor_mod_exit(void)
+{
+	i2c_del_driver(&SC2355_i2c_driver);
+}
+
+device_initcall_sync(sensor_mod_init);
+module_exit(sensor_mod_exit);
+
+MODULE_DESCRIPTION("Smartsens SC2355 sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/sc3338.c b/kernel/drivers/media/i2c/sc3338.c
index 8120f40..95452c1 100644
--- a/kernel/drivers/media/i2c/sc3338.c
+++ b/kernel/drivers/media/i2c/sc3338.c
@@ -27,6 +27,7 @@
 #include <media/v4l2-subdev.h>
 #include <linux/pinctrl/consumer.h>
 #include "../platform/rockchip/isp/rkisp_tb_helper.h"
+#include "cam-sleep-wakeup.h"
 
 #define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x01)
 
@@ -158,6 +159,7 @@
 	bool			is_thunderboot;
 	bool			is_first_streamoff;
 	struct preisp_hdrae_exp_s init_hdrae_exp;
+	struct cam_sw_info *cam_sw_inf;
 };
 
 #define to_sc3338(sd) container_of(sd, struct sc3338, subdev)
@@ -722,6 +724,9 @@
 		}
 		break;
 	case PREISP_CMD_SET_HDRAE_EXP:
+		if (sc3338->cam_sw_inf)
+			memcpy(&sc3338->cam_sw_inf->hdr_ae, (struct preisp_hdrae_exp_s *)(arg),
+				sizeof(struct preisp_hdrae_exp_s));
 		break;
 	case RKMODULE_SET_QUICK_STREAM:
 
@@ -970,6 +975,8 @@
 		return ret;
 	}
 
+	cam_sw_regulator_bulk_init(sc3338->cam_sw_inf, SC3338_NUM_SUPPLIES, sc3338->supplies);
+
 	if (sc3338->is_thunderboot)
 		return 0;
 
@@ -1036,6 +1043,47 @@
 	regulator_bulk_disable(SC3338_NUM_SUPPLIES, sc3338->supplies);
 }
 
+#if IS_REACHABLE(CONFIG_VIDEO_CAM_SLEEP_WAKEUP)
+static int sc3338_resume(struct device *dev)
+{
+	int ret;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct sc3338 *sc3338 = to_sc3338(sd);
+
+	cam_sw_prepare_wakeup(sc3338->cam_sw_inf, dev);
+
+	usleep_range(6000, 8000);
+	cam_sw_write_array(sc3338->cam_sw_inf);
+
+	if (__v4l2_ctrl_handler_setup(&sc3338->ctrl_handler))
+		dev_err(dev, "__v4l2_ctrl_handler_setup fail!");
+
+	if (sc3338->has_init_exp && sc3338->cur_mode != NO_HDR) {	// hdr mode
+		ret = sc3338_ioctl(&sc3338->subdev, PREISP_CMD_SET_HDRAE_EXP,
+				&sc3338->cam_sw_inf->hdr_ae);
+		if (ret) {
+			dev_err(&sc3338->client->dev, "set exp fail in hdr mode\n");
+			return ret;
+		}
+	}
+	return 0;
+}
+
+static int sc3338_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct sc3338 *sc3338 = to_sc3338(sd);
+
+	cam_sw_write_array_cb_init(sc3338->cam_sw_inf, client,
+		(void *)sc3338->cur_mode->reg_list, (sensor_write_array)sc3338_write_array);
+	cam_sw_prepare_sleep(sc3338->cam_sw_inf);
+
+	return 0;
+}
+#endif
+
 static int sc3338_runtime_resume(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
@@ -1094,8 +1142,10 @@
 }
 
 static const struct dev_pm_ops sc3338_pm_ops = {
-	SET_RUNTIME_PM_OPS(sc3338_runtime_suspend,
-			   sc3338_runtime_resume, NULL)
+	SET_RUNTIME_PM_OPS(sc3338_runtime_suspend, sc3338_runtime_resume, NULL)
+#if IS_REACHABLE(CONFIG_VIDEO_CAM_SLEEP_WAKEUP)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(sc3338_suspend, sc3338_resume)
+#endif
 };
 
 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
@@ -1454,6 +1504,13 @@
 		goto err_power_off;
 #endif
 
+	if (!sc3338->cam_sw_inf) {
+		sc3338->cam_sw_inf = cam_sw_init();
+		cam_sw_clk_init(sc3338->cam_sw_inf, sc3338->xvclk, SC3338_XVCLK_FREQ);
+		cam_sw_reset_pin_init(sc3338->cam_sw_inf, sc3338->reset_gpio, 0);
+		cam_sw_pwdn_pin_init(sc3338->cam_sw_inf, sc3338->pwdn_gpio, 1);
+	}
+
 	memset(facing, 0, sizeof(facing));
 	if (strcmp(sc3338->module_facing, "back") == 0)
 		facing[0] = 'b';
@@ -1504,6 +1561,8 @@
 	v4l2_ctrl_handler_free(&sc3338->ctrl_handler);
 	mutex_destroy(&sc3338->mutex);
 
+	cam_sw_deinit(sc3338->cam_sw_inf);
+
 	pm_runtime_disable(&client->dev);
 	if (!pm_runtime_status_suspended(&client->dev))
 		__sc3338_power_off(sc3338);
diff --git a/kernel/drivers/media/i2c/sc401ai.c b/kernel/drivers/media/i2c/sc401ai.c
index e4f965d..0eac2d3 100644
--- a/kernel/drivers/media/i2c/sc401ai.c
+++ b/kernel/drivers/media/i2c/sc401ai.c
@@ -9,6 +9,7 @@
  * V0.0X01.0X03 fix gain range.
  * V0.0X01.0X04 add enum_frame_interval function.
  * V0.0X01.0X05 add quick stream on/off
+ * V0.0X01.0X06 support thunder boot function.
  */
 
 #include <linux/clk.h>
@@ -31,8 +32,9 @@
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-subdev.h>
 #include <linux/pinctrl/consumer.h>
+#include "../platform/rockchip/isp/rkisp_tb_helper.h"
 
-#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x05)
+#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x06)
 
 #ifndef V4L2_CID_DIGITAL_GAIN
 #define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
@@ -173,6 +175,8 @@
 	const char		*module_name;
 	const char		*len_name;
 	u32			cur_vts;
+	bool			is_thunderboot;
+	bool			is_first_streamoff;
 	struct preisp_hdrae_exp_s init_hdrae_exp;
 };
 
@@ -447,6 +451,8 @@
 	SC401AI_LINK_FREQ_630,
 };
 
+static int __sc401ai_power_on(struct sc401ai *sc401ai);
+
 /* Write registers up to 4 at a time */
 static int sc401ai_write_reg(struct i2c_client *client, u16 reg,
 			    u32 len, u32 val)
@@ -623,6 +629,11 @@
 	else
 		DIG_Fine_gain_reg = abs(800 * gain / (Dcg_gainx100 * Coarse_gain *
 							DIG_gain) / ANA_Fine_gainx64);
+
+	if (sc401ai->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
+		sc401ai->is_thunderboot = false;
+		__sc401ai_power_on(sc401ai);
+	}
 
 	ret = sc401ai_write_reg(sc401ai->client,
 				SC401AI_REG_DIG_GAIN,
@@ -989,23 +1000,31 @@
 {
 	int ret;
 
-	ret = sc401ai_write_array(sc401ai->client, sc401ai->cur_mode->reg_list);
-	if (ret)
-		return ret;
+	if (!sc401ai->is_thunderboot) {
+		ret = sc401ai_write_array(sc401ai->client, sc401ai->cur_mode->reg_list);
+		if (ret)
+			return ret;
 
-	/* In case these controls are set before streaming */
-	ret = __v4l2_ctrl_handler_setup(&sc401ai->ctrl_handler);
-	if (ret)
-		return ret;
+		/* In case these controls are set before streaming */
+		ret = __v4l2_ctrl_handler_setup(&sc401ai->ctrl_handler);
+		if (ret)
+			return ret;
+	}
 
 	return sc401ai_write_reg(sc401ai->client,
-				 SC401AI_REG_CTRL_MODE,
-				 SC401AI_REG_VALUE_08BIT,
-				 SC401AI_MODE_STREAMING);
+				SC401AI_REG_CTRL_MODE,
+				SC401AI_REG_VALUE_08BIT,
+				SC401AI_MODE_STREAMING);
+
 }
 
 static int __sc401ai_stop_stream(struct sc401ai *sc401ai)
 {
+	if (sc401ai->is_thunderboot) {
+		sc401ai->is_first_streamoff = true;
+		pm_runtime_put(&sc401ai->client->dev);
+	}
+
 	return sc401ai_write_reg(sc401ai->client,
 				 SC401AI_REG_CTRL_MODE,
 				 SC401AI_REG_VALUE_08BIT,
@@ -1024,6 +1043,10 @@
 		goto unlock_and_return;
 
 	if (on) {
+		if (sc401ai->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
+			sc401ai->is_thunderboot = false;
+			__sc401ai_power_on(sc401ai);
+		}
 		ret = pm_runtime_get_sync(&client->dev);
 		if (ret < 0) {
 			pm_runtime_put_noidle(&client->dev);
@@ -1115,6 +1138,10 @@
 		dev_err(dev, "Failed to enable xvclk\n");
 		return ret;
 	}
+
+	if (sc401ai->is_thunderboot)
+		return 0;
+
 	if (!IS_ERR(sc401ai->reset_gpio))
 		gpiod_set_value_cansleep(sc401ai->reset_gpio, 0);
 
@@ -1152,6 +1179,15 @@
 {
 	int ret;
 	struct device *dev = &sc401ai->client->dev;
+
+	if (sc401ai->is_thunderboot) {
+		if (sc401ai->is_first_streamoff) {
+			sc401ai->is_thunderboot = false;
+			sc401ai->is_first_streamoff = false;
+		} else {
+			return;
+		}
+	}
 
 	if (!IS_ERR(sc401ai->pwdn_gpio))
 		gpiod_set_value_cansleep(sc401ai->pwdn_gpio, 0);
@@ -1491,6 +1527,11 @@
 	u32 id = 0;
 	int ret;
 
+	if (sc401ai->is_thunderboot) {
+		dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
+		return 0;
+	}
+
 	ret = sc401ai_read_reg(client, SC401AI_REG_CHIP_ID,
 			       SC401AI_REG_VALUE_16BIT, &id);
 	if (id != CHIP_ID) {
@@ -1549,6 +1590,8 @@
 		return -EINVAL;
 	}
 
+	sc401ai->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
+
 	sc401ai->client = client;
 	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
 		if (hdr_mode == supported_modes[i].hdr_mode) {
@@ -1565,13 +1608,23 @@
 		return -EINVAL;
 	}
 
-	sc401ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
-	if (IS_ERR(sc401ai->reset_gpio))
-		dev_warn(dev, "Failed to get reset-gpios\n");
+	if (sc401ai->is_thunderboot) {
+		sc401ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
+		if (IS_ERR(sc401ai->reset_gpio))
+			dev_warn(dev, "Failed to get reset-gpios\n");
 
-	sc401ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
-	if (IS_ERR(sc401ai->pwdn_gpio))
-		dev_warn(dev, "Failed to get pwdn-gpios\n");
+		sc401ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
+		if (IS_ERR(sc401ai->pwdn_gpio))
+			dev_warn(dev, "Failed to get pwdn-gpios\n");
+	} else {
+		sc401ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+		if (IS_ERR(sc401ai->reset_gpio))
+			dev_warn(dev, "Failed to get reset-gpios\n");
+
+		sc401ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
+		if (IS_ERR(sc401ai->pwdn_gpio))
+			dev_warn(dev, "Failed to get pwdn-gpios\n");
+	}
 
 	sc401ai->pinctrl = devm_pinctrl_get(dev);
 	if (!IS_ERR(sc401ai->pinctrl)) {
@@ -1646,7 +1699,10 @@
 
 	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
-	pm_runtime_idle(dev);
+	if (sc401ai->is_thunderboot)
+		pm_runtime_get_sync(dev);
+	else
+		pm_runtime_idle(dev);
 
 	return 0;
 
@@ -1718,7 +1774,12 @@
 	i2c_del_driver(&sc401ai_i2c_driver);
 }
 
+#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
+subsys_initcall(sensor_mod_init);
+#else
 device_initcall_sync(sensor_mod_init);
+#endif
+
 module_exit(sensor_mod_exit);
 
 MODULE_DESCRIPTION("smartsens sc401ai sensor driver");
diff --git a/kernel/drivers/media/i2c/sc4336p.c b/kernel/drivers/media/i2c/sc4336p.c
new file mode 100644
index 0000000..2aa0178
--- /dev/null
+++ b/kernel/drivers/media/i2c/sc4336p.c
@@ -0,0 +1,1586 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * sc4336pp driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * V0.0X01.0X01 first version
+ */
+
+//#define DEBUG
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/rk-camera-module.h>
+#include <linux/rk-preisp.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <linux/pinctrl/consumer.h>
+#include "../platform/rockchip/isp/rkisp_tb_helper.h"
+
+#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x01)
+
+#ifndef V4L2_CID_DIGITAL_GAIN
+#define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
+#endif
+
+#define SC4336P_LANES			2
+#define SC4336P_BITS_PER_SAMPLE		10
+#define SC4336P_LINK_FREQ_315		315000000
+
+#define PIXEL_RATE_WITH_315M_10BIT	(SC4336P_LINK_FREQ_315 * 2 * \
+					SC4336P_LANES / SC4336P_BITS_PER_SAMPLE)
+#define SC4336P_XVCLK_FREQ		24000000
+
+#define CHIP_ID				0x9c42
+#define SC4336P_REG_CHIP_ID		0x3107
+
+#define SC4336P_REG_CTRL_MODE		0x0100
+#define SC4336P_MODE_SW_STANDBY		0x0
+#define SC4336P_MODE_STREAMING		BIT(0)
+
+#define SC4336P_REG_EXPOSURE_H		0x3e00
+#define SC4336P_REG_EXPOSURE_M		0x3e01
+#define SC4336P_REG_EXPOSURE_L		0x3e02
+#define	SC4336P_EXPOSURE_MIN		2
+#define	SC4336P_EXPOSURE_STEP		1
+#define SC4336P_VTS_MAX			0x7fff
+
+#define SC4336P_REG_DIG_GAIN		0x3e06
+#define SC4336P_REG_DIG_FINE_GAIN	0x3e07
+#define SC4336P_REG_ANA_GAIN		0x3e09
+#define SC4336P_GAIN_MIN			0x0020
+#define SC4336P_GAIN_MAX			(16128)    //32 * 15.75 * 32
+#define SC4336P_GAIN_STEP		1
+#define SC4336P_GAIN_DEFAULT		0x20
+
+
+#define SC4336P_REG_GROUP_HOLD		0x3812
+#define SC4336P_GROUP_HOLD_START		0x00
+#define SC4336P_GROUP_HOLD_END		0x30
+
+#define SC4336P_REG_TEST_PATTERN		0x4501
+#define SC4336P_TEST_PATTERN_BIT_MASK	BIT(3)
+
+#define SC4336P_REG_VTS_H		0x320e
+#define SC4336P_REG_VTS_L		0x320f
+
+#define SC4336P_FLIP_MIRROR_REG		0x3221
+
+#define SC4336P_FETCH_EXP_H(VAL)		(((VAL) >> 12) & 0xF)
+#define SC4336P_FETCH_EXP_M(VAL)		(((VAL) >> 4) & 0xFF)
+#define SC4336P_FETCH_EXP_L(VAL)		(((VAL) & 0xF) << 4)
+
+#define SC4336P_FETCH_AGAIN_H(VAL)	(((VAL) >> 8) & 0x03)
+#define SC4336P_FETCH_AGAIN_L(VAL)	((VAL) & 0xFF)
+
+#define SC4336P_FETCH_MIRROR(VAL, ENABLE)	(ENABLE ? VAL | 0x06 : VAL & 0xf9)
+#define SC4336P_FETCH_FLIP(VAL, ENABLE)		(ENABLE ? VAL | 0x60 : VAL & 0x9f)
+
+#define REG_DELAY			0xFFFE
+#define REG_NULL			0xFFFF
+
+#define SC4336P_REG_VALUE_08BIT		1
+#define SC4336P_REG_VALUE_16BIT		2
+#define SC4336P_REG_VALUE_24BIT		3
+
+#define OF_CAMERA_PINCTRL_STATE_DEFAULT	"rockchip,camera_default"
+#define OF_CAMERA_PINCTRL_STATE_SLEEP	"rockchip,camera_sleep"
+#define SC4336P_NAME			"sc4336p"
+
+static const char * const sc4336p_supply_names[] = {
+	"avdd",		/* Analog power */
+	"dovdd",	/* Digital I/O power */
+	"dvdd",		/* Digital core power */
+};
+
+#define SC4336P_NUM_SUPPLIES ARRAY_SIZE(sc4336p_supply_names)
+
+struct regval {
+	u16 addr;
+	u8 val;
+};
+
+struct sc4336p_mode {
+	u32 bus_fmt;
+	u32 width;
+	u32 height;
+	struct v4l2_fract max_fps;
+	u32 hts_def;
+	u32 vts_def;
+	u32 exp_def;
+	const struct regval *reg_list;
+	u32 hdr_mode;
+	u32 vc[PAD_MAX];
+};
+
+struct sc4336p {
+	struct i2c_client	*client;
+	struct clk		*xvclk;
+	struct gpio_desc	*reset_gpio;
+	struct gpio_desc	*pwdn_gpio;
+	struct regulator_bulk_data supplies[SC4336P_NUM_SUPPLIES];
+
+	struct pinctrl		*pinctrl;
+	struct pinctrl_state	*pins_default;
+	struct pinctrl_state	*pins_sleep;
+
+	struct v4l2_subdev	subdev;
+	struct media_pad	pad;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl	*exposure;
+	struct v4l2_ctrl	*anal_gain;
+	struct v4l2_ctrl	*digi_gain;
+	struct v4l2_ctrl	*hblank;
+	struct v4l2_ctrl	*vblank;
+	struct v4l2_ctrl	*test_pattern;
+	struct mutex		mutex;
+	bool			streaming;
+	bool			power_on;
+	const struct sc4336p_mode *cur_mode;
+	struct v4l2_fract	cur_fps;
+	u32			module_index;
+	const char		*module_facing;
+	const char		*module_name;
+	const char		*len_name;
+	u32			cur_vts;
+	bool			is_thunderboot;
+	bool			is_first_streamoff;
+};
+
+#define to_sc4336p(sd) container_of(sd, struct sc4336p, subdev)
+
+/*
+ * Xclk 24Mhz
+ */
+static const struct regval sc4336p_global_regs[] = {
+	{REG_NULL, 0x00},
+};
+
+/*
+ * Xclk 24Mhz
+ * max_framerate 30fps
+ * mipi_datarate per lane 630Mbps, 2lane
+ */
+static const struct regval sc4336p_linear_10_2560x1440_regs[] = {
+	{0x0103, 0x01},
+	{0x36e9, 0x80},
+	{0x37f9, 0x80},
+	{0x301f, 0x05},
+	{0x30b8, 0x44},
+	{0x320e, 0x05},
+	{0x320f, 0xdc},
+	{0x3253, 0x10},
+	{0x3301, 0x0a},
+	{0x3302, 0xff},
+	{0x3305, 0x00},
+	{0x3306, 0x90},
+	{0x3308, 0x08},
+	{0x330a, 0x01},
+	{0x330b, 0xb0},
+	{0x330d, 0xf0},
+	{0x3314, 0x14},
+	{0x3333, 0x10},
+	{0x3334, 0x40},
+	{0x335e, 0x06},
+	{0x335f, 0x0a},
+	{0x3364, 0x5e},
+	{0x337d, 0x0e},
+	{0x338f, 0x20},
+	{0x3390, 0x08},
+	{0x3391, 0x09},
+	{0x3392, 0x0f},
+	{0x3393, 0x18},
+	{0x3394, 0x60},
+	{0x3395, 0xff},
+	{0x3396, 0x08},
+	{0x3397, 0x09},
+	{0x3398, 0x0f},
+	{0x3399, 0x0a},
+	{0x339a, 0x18},
+	{0x339b, 0x60},
+	{0x339c, 0xff},
+	{0x33a2, 0x04},
+	{0x33ad, 0x0c},
+	{0x33b2, 0x40},
+	{0x33b3, 0x30},
+	{0x33f8, 0x00},
+	{0x33f9, 0xb0},
+	{0x33fa, 0x00},
+	{0x33fb, 0xf8},
+	{0x33fc, 0x09},
+	{0x33fd, 0x1f},
+	{0x349f, 0x03},
+	{0x34a6, 0x09},
+	{0x34a7, 0x1f},
+	{0x34a8, 0x28},
+	{0x34a9, 0x28},
+	{0x34aa, 0x01},
+	{0x34ab, 0xe0},
+	{0x34ac, 0x02},
+	{0x34ad, 0x28},
+	{0x34f8, 0x1f},
+	{0x34f9, 0x20},
+	{0x3630, 0xc0},
+	{0x3631, 0x84},
+	{0x3632, 0x54},
+	{0x3633, 0x44},
+	{0x3637, 0x49},
+	{0x363f, 0xc0},
+	{0x3641, 0x28},
+	{0x3670, 0x56},
+	{0x3674, 0xb0},
+	{0x3675, 0xa0},
+	{0x3676, 0xa0},
+	{0x3677, 0x84},
+	{0x3678, 0x88},
+	{0x3679, 0x8d},
+	{0x367c, 0x09},
+	{0x367d, 0x0b},
+	{0x367e, 0x08},
+	{0x367f, 0x0f},
+	{0x3696, 0x24},
+	{0x3697, 0x34},
+	{0x3698, 0x34},
+	{0x36a0, 0x0f},
+	{0x36a1, 0x1f},
+	{0x36b0, 0x81},
+	{0x36b1, 0x83},
+	{0x36b2, 0x85},
+	{0x36b3, 0x8b},
+	{0x36b4, 0x09},
+	{0x36b5, 0x0b},
+	{0x36b6, 0x0f},
+	{0x370f, 0x01},
+	{0x3722, 0x09},
+	{0x3724, 0x21},
+	{0x3771, 0x09},
+	{0x3772, 0x05},
+	{0x3773, 0x05},
+	{0x377a, 0x0f},
+	{0x377b, 0x1f},
+	{0x3905, 0x8c},
+	{0x391d, 0x02},
+	{0x391f, 0x49},
+	{0x3926, 0x21},
+	{0x3933, 0x80},
+	{0x3934, 0x03},
+	{0x3937, 0x7b},
+	{0x3939, 0x00},
+	{0x393a, 0x00},
+	{0x39dc, 0x02},
+	{0x3e00, 0x00},
+	{0x3e01, 0x5d},
+	{0x3e02, 0x40},
+	{0x440d, 0x10},
+	{0x440e, 0x01},
+	{0x4509, 0x28},
+	{0x450d, 0x32},
+	{0x5000, 0x06},
+	{0x5780, 0x76},
+	{0x5784, 0x10},
+	{0x5785, 0x04},
+	{0x5787, 0x0a},
+	{0x5788, 0x0a},
+	{0x5789, 0x08},
+	{0x578a, 0x0a},
+	{0x578b, 0x0a},
+	{0x578c, 0x08},
+	{0x578d, 0x40},
+	{0x5790, 0x08},
+	{0x5791, 0x04},
+	{0x5792, 0x04},
+	{0x5793, 0x08},
+	{0x5794, 0x04},
+	{0x5795, 0x04},
+	{0x5799, 0x46},
+	{0x579a, 0x77},
+	{0x57a1, 0x04},
+	{0x57a8, 0xd2},
+	{0x57aa, 0x2a},
+	{0x57ab, 0x7f},
+	{0x57ac, 0x00},
+	{0x57ad, 0x00},
+	{0x57d9, 0x46},
+	{0x57da, 0x77},
+	{0x59e2, 0x08},
+	{0x59e3, 0x03},
+	{0x59e4, 0x00},
+	{0x59e5, 0x10},
+	{0x59e6, 0x06},
+	{0x59e7, 0x00},
+	{0x59e8, 0x08},
+	{0x59e9, 0x02},
+	{0x59ea, 0x00},
+	{0x59eb, 0x10},
+	{0x59ec, 0x04},
+	{0x59ed, 0x00},
+	{0x5ae0, 0xfe},
+	{0x5ae1, 0x40},
+	{0x5ae2, 0x38},
+	{0x5ae3, 0x30},
+	{0x5ae4, 0x28},
+	{0x5ae5, 0x38},
+	{0x5ae6, 0x30},
+	{0x5ae7, 0x28},
+	{0x5ae8, 0x3f},
+	{0x5ae9, 0x34},
+	{0x5aea, 0x2c},
+	{0x5aeb, 0x3f},
+	{0x5aec, 0x34},
+	{0x5aed, 0x2c},
+	{0x36e9, 0x53},
+	{0x37f9, 0x53},
+	{REG_NULL, 0x00},
+};
+
+static const struct sc4336p_mode supported_modes[] = {
+	{
+		.width = 2560,
+		.height = 1440,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 250000,
+		},
+		.exp_def = 0x0080,
+		.hts_def = 0x0578 * 2,
+		.vts_def = 0x0708,
+		.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.reg_list = sc4336p_linear_10_2560x1440_regs,
+		.hdr_mode = NO_HDR,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	}
+};
+
+static const s64 link_freq_menu_items[] = {
+	SC4336P_LINK_FREQ_315
+};
+
+static const char * const sc4336p_test_pattern_menu[] = {
+	"Disabled",
+	"Vertical Color Bar Type 1",
+	"Vertical Color Bar Type 2",
+	"Vertical Color Bar Type 3",
+	"Vertical Color Bar Type 4"
+};
+
+/* Write registers up to 4 at a time */
+static int sc4336p_write_reg(struct i2c_client *client, u16 reg,
+			    u32 len, u32 val)
+{
+	u32 buf_i, val_i;
+	u8 buf[6];
+	u8 *val_p;
+	__be32 val_be;
+
+	if (len > 4)
+		return -EINVAL;
+
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xff;
+
+	val_be = cpu_to_be32(val);
+	val_p = (u8 *)&val_be;
+	buf_i = 2;
+	val_i = 4 - len;
+
+	while (val_i < 4)
+		buf[buf_i++] = val_p[val_i++];
+
+	if (i2c_master_send(client, buf, len + 2) != len + 2)
+		return -EIO;
+	return 0;
+}
+
+static int sc4336p_write_array(struct i2c_client *client,
+			       const struct regval *regs)
+{
+	u32 i;
+	int ret = 0;
+
+	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++)
+		ret = sc4336p_write_reg(client, regs[i].addr,
+					SC4336P_REG_VALUE_08BIT, regs[i].val);
+
+	return ret;
+}
+
+/* Read registers up to 4 at a time */
+static int sc4336p_read_reg(struct i2c_client *client, u16 reg, unsigned int len,
+			    u32 *val)
+{
+	struct i2c_msg msgs[2];
+	u8 *data_be_p;
+	__be32 data_be = 0;
+	__be16 reg_addr_be = cpu_to_be16(reg);
+	int ret;
+
+	if (len > 4 || !len)
+		return -EINVAL;
+
+	data_be_p = (u8 *)&data_be;
+	/* Write register address */
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = 2;
+	msgs[0].buf = (u8 *)&reg_addr_be;
+
+	/* Read data from register */
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = len;
+	msgs[1].buf = &data_be_p[4 - len];
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs))
+		return -EIO;
+
+	*val = be32_to_cpu(data_be);
+
+	return 0;
+}
+
+static int sc4336p_set_gain_reg(struct sc4336p *sc4336p, u32 gain)
+{
+	u32 coarse_again = 0, coarse_dgian = 0, fine_dgian = 0;
+	u32 gain_factor;
+	int ret = 0;
+
+	if (gain < 32)
+		gain = 32;
+	else if (gain > SC4336P_GAIN_MAX)
+		gain = SC4336P_GAIN_MAX;
+
+	gain_factor = gain * 1000 / 32;
+	if (gain_factor < 2000) {
+		coarse_again = 0x00;
+		coarse_dgian = 0x00;
+		fine_dgian = gain_factor * 128 / 1000;
+	} else if (gain_factor < 4000) {
+		coarse_again = 0x08;
+		coarse_dgian = 0x00;
+		fine_dgian = gain_factor * 128 / 2000;
+	} else if (gain_factor < 8000) {
+		coarse_again = 0x09;
+		coarse_dgian = 0x00;
+		fine_dgian = gain_factor * 128 / 4000;
+	} else if (gain_factor < 16000) {
+		coarse_again = 0x0b;
+		coarse_dgian = 0x00;
+		fine_dgian = gain_factor * 128 / 8000;
+	} else if (gain_factor < 32000) {
+		coarse_again = 0x0f;
+		coarse_dgian = 0x00;
+		fine_dgian = gain_factor * 128 / 16000;
+	} else if (gain_factor < 32000 * 2) {
+		coarse_again = 0x1f;
+		coarse_dgian = 0x00;
+		fine_dgian = gain_factor * 128 / 32000;
+	} else if (gain_factor < 32000 * 4) {
+		//open dgain begin  max digital gain 4X
+		coarse_again = 0x1f;
+		coarse_dgian = 0x01;
+		fine_dgian = gain_factor * 128 / 32000 / 2;
+	} else if (gain_factor < 32000 * 8) {
+		coarse_again = 0x1f;
+		coarse_dgian = 0x03;
+		fine_dgian = gain_factor * 128 / 32000 / 4;
+	} else if (gain_factor < 32000 * 15) {
+		coarse_again = 0x1f;
+		coarse_dgian = 0x07;
+		fine_dgian = gain_factor * 128 / 32000 / 8;
+	} else {
+		coarse_again = 0x1f;
+		coarse_dgian = 0x07;
+		fine_dgian = 0xf0;
+	}
+
+	ret = sc4336p_write_reg(sc4336p->client,
+				SC4336P_REG_DIG_GAIN,
+				SC4336P_REG_VALUE_08BIT,
+				coarse_dgian);
+	ret |= sc4336p_write_reg(sc4336p->client,
+				 SC4336P_REG_DIG_FINE_GAIN,
+				 SC4336P_REG_VALUE_08BIT,
+				 fine_dgian);
+	ret |= sc4336p_write_reg(sc4336p->client,
+				 SC4336P_REG_ANA_GAIN,
+				 SC4336P_REG_VALUE_08BIT,
+				 coarse_again);
+
+	return ret;
+}
+
+static int sc4336p_get_reso_dist(const struct sc4336p_mode *mode,
+				 struct v4l2_mbus_framefmt *framefmt)
+{
+	return abs(mode->width - framefmt->width) +
+	       abs(mode->height - framefmt->height);
+}
+
+static const struct sc4336p_mode *
+sc4336p_find_best_fit(struct v4l2_subdev_format *fmt)
+{
+	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
+	int dist;
+	int cur_best_fit = 0;
+	int cur_best_fit_dist = -1;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+		dist = sc4336p_get_reso_dist(&supported_modes[i], framefmt);
+		if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
+			cur_best_fit_dist = dist;
+			cur_best_fit = i;
+		}
+	}
+
+	return &supported_modes[cur_best_fit];
+}
+
+static int sc4336p_set_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct sc4336p *sc4336p = to_sc4336p(sd);
+	const struct sc4336p_mode *mode;
+	s64 h_blank, vblank_def;
+
+	mutex_lock(&sc4336p->mutex);
+
+	mode = sc4336p_find_best_fit(fmt);
+	fmt->format.code = mode->bus_fmt;
+	fmt->format.width = mode->width;
+	fmt->format.height = mode->height;
+	fmt->format.field = V4L2_FIELD_NONE;
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+#else
+		mutex_unlock(&sc4336p->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		sc4336p->cur_mode = mode;
+		h_blank = mode->hts_def - mode->width;
+		__v4l2_ctrl_modify_range(sc4336p->hblank, h_blank,
+					 h_blank, 1, h_blank);
+		vblank_def = mode->vts_def - mode->height;
+		__v4l2_ctrl_modify_range(sc4336p->vblank, vblank_def,
+					 SC4336P_VTS_MAX - mode->height,
+					 1, vblank_def);
+		sc4336p->cur_fps = mode->max_fps;
+	}
+
+	mutex_unlock(&sc4336p->mutex);
+
+	return 0;
+}
+
+static int sc4336p_get_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct sc4336p *sc4336p = to_sc4336p(sd);
+	const struct sc4336p_mode *mode = sc4336p->cur_mode;
+
+	mutex_lock(&sc4336p->mutex);
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+#else
+		mutex_unlock(&sc4336p->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		fmt->format.width = mode->width;
+		fmt->format.height = mode->height;
+		fmt->format.code = mode->bus_fmt;
+		fmt->format.field = V4L2_FIELD_NONE;
+		/* format info: width/height/data type/virctual channel */
+		if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
+			fmt->reserved[0] = mode->vc[fmt->pad];
+		else
+			fmt->reserved[0] = mode->vc[PAD0];
+	}
+	mutex_unlock(&sc4336p->mutex);
+
+	return 0;
+}
+
+static int sc4336p_enum_mbus_code(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_pad_config *cfg,
+				  struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct sc4336p *sc4336p = to_sc4336p(sd);
+
+	if (code->index != 0)
+		return -EINVAL;
+	code->code = sc4336p->cur_mode->bus_fmt;
+
+	return 0;
+}
+
+static int sc4336p_enum_frame_sizes(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_pad_config *cfg,
+				    struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	if (fse->code != supported_modes[0].bus_fmt)
+		return -EINVAL;
+
+	fse->min_width  = supported_modes[fse->index].width;
+	fse->max_width  = supported_modes[fse->index].width;
+	fse->max_height = supported_modes[fse->index].height;
+	fse->min_height = supported_modes[fse->index].height;
+
+	return 0;
+}
+
+static int sc4336p_enable_test_pattern(struct sc4336p *sc4336p, u32 pattern)
+{
+	u32 val = 0;
+	int ret = 0;
+
+	ret = sc4336p_read_reg(sc4336p->client, SC4336P_REG_TEST_PATTERN,
+			       SC4336P_REG_VALUE_08BIT, &val);
+	if (pattern)
+		val |= SC4336P_TEST_PATTERN_BIT_MASK;
+	else
+		val &= ~SC4336P_TEST_PATTERN_BIT_MASK;
+
+	ret |= sc4336p_write_reg(sc4336p->client, SC4336P_REG_TEST_PATTERN,
+				 SC4336P_REG_VALUE_08BIT, val);
+	return ret;
+}
+
+static int sc4336p_g_frame_interval(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_frame_interval *fi)
+{
+	struct sc4336p *sc4336p = to_sc4336p(sd);
+	const struct sc4336p_mode *mode = sc4336p->cur_mode;
+
+	if (sc4336p->streaming)
+		fi->interval = sc4336p->cur_fps;
+	else
+		fi->interval = mode->max_fps;
+
+	return 0;
+}
+
+static int sc4336p_g_mbus_config(struct v4l2_subdev *sd,
+				unsigned int pad_id,
+				struct v4l2_mbus_config *config)
+{
+	struct sc4336p *sc4336p = to_sc4336p(sd);
+	const struct sc4336p_mode *mode = sc4336p->cur_mode;
+	u32 val = 1 << (SC4336P_LANES - 1) |
+		V4L2_MBUS_CSI2_CHANNEL_0 |
+		V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+
+	if (mode->hdr_mode != NO_HDR)
+		val |= V4L2_MBUS_CSI2_CHANNEL_1;
+	if (mode->hdr_mode == HDR_X3)
+		val |= V4L2_MBUS_CSI2_CHANNEL_2;
+
+	config->type = V4L2_MBUS_CSI2_DPHY;
+	config->flags = val;
+
+	return 0;
+}
+
+static void sc4336p_get_module_inf(struct sc4336p *sc4336p,
+				   struct rkmodule_inf *inf)
+{
+	memset(inf, 0, sizeof(*inf));
+	strscpy(inf->base.sensor, SC4336P_NAME, sizeof(inf->base.sensor));
+	strscpy(inf->base.module, sc4336p->module_name,
+		sizeof(inf->base.module));
+	strscpy(inf->base.lens, sc4336p->len_name, sizeof(inf->base.lens));
+}
+
+static long sc4336p_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	struct sc4336p *sc4336p = to_sc4336p(sd);
+	struct rkmodule_hdr_cfg *hdr;
+	u32 i, h, w;
+	long ret = 0;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		sc4336p_get_module_inf(sc4336p, (struct rkmodule_inf *)arg);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr = (struct rkmodule_hdr_cfg *)arg;
+		hdr->esp.mode = HDR_NORMAL_VC;
+		hdr->hdr_mode = sc4336p->cur_mode->hdr_mode;
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		hdr = (struct rkmodule_hdr_cfg *)arg;
+		w = sc4336p->cur_mode->width;
+		h = sc4336p->cur_mode->height;
+		for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+			if (w == supported_modes[i].width &&
+			    h == supported_modes[i].height &&
+			    supported_modes[i].hdr_mode == hdr->hdr_mode) {
+				sc4336p->cur_mode = &supported_modes[i];
+				break;
+			}
+		}
+		if (i == ARRAY_SIZE(supported_modes)) {
+			dev_err(&sc4336p->client->dev,
+				"not find hdr mode:%d %dx%d config\n",
+				hdr->hdr_mode, w, h);
+			ret = -EINVAL;
+		} else {
+			w = sc4336p->cur_mode->hts_def - sc4336p->cur_mode->width;
+			h = sc4336p->cur_mode->vts_def - sc4336p->cur_mode->height;
+			__v4l2_ctrl_modify_range(sc4336p->hblank, w, w, 1, w);
+			__v4l2_ctrl_modify_range(sc4336p->vblank, h,
+						 SC4336P_VTS_MAX - sc4336p->cur_mode->height, 1, h);
+		}
+		break;
+	case PREISP_CMD_SET_HDRAE_EXP:
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+
+		stream = *((u32 *)arg);
+
+		if (stream)
+			ret = sc4336p_write_reg(sc4336p->client, SC4336P_REG_CTRL_MODE,
+				 SC4336P_REG_VALUE_08BIT, SC4336P_MODE_STREAMING);
+		else
+			ret = sc4336p_write_reg(sc4336p->client, SC4336P_REG_CTRL_MODE,
+				 SC4336P_REG_VALUE_08BIT, SC4336P_MODE_SW_STANDBY);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long sc4336p_compat_ioctl32(struct v4l2_subdev *sd,
+				   unsigned int cmd, unsigned long arg)
+{
+	void __user *up = compat_ptr(arg);
+	struct rkmodule_inf *inf;
+	struct rkmodule_hdr_cfg *hdr;
+	struct preisp_hdrae_exp_s *hdrae;
+	long ret;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
+		if (!inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = sc4336p_ioctl(sd, cmd, inf);
+		if (!ret) {
+			if (copy_to_user(up, inf, sizeof(*inf)))
+				ret = -EFAULT;
+		}
+		kfree(inf);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = sc4336p_ioctl(sd, cmd, hdr);
+		if (!ret) {
+			if (copy_to_user(up, hdr, sizeof(*hdr)))
+				ret = -EFAULT;
+		}
+		kfree(hdr);
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(hdr, up, sizeof(*hdr));
+		if (!ret)
+			ret = sc4336p_ioctl(sd, cmd, hdr);
+		else
+			ret = -EFAULT;
+		kfree(hdr);
+		break;
+	case PREISP_CMD_SET_HDRAE_EXP:
+		hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
+		if (!hdrae) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(hdrae, up, sizeof(*hdrae));
+		if (!ret)
+			ret = sc4336p_ioctl(sd, cmd, hdrae);
+		else
+			ret = -EFAULT;
+		kfree(hdrae);
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		ret = copy_from_user(&stream, up, sizeof(u32));
+		if (!ret)
+			ret = sc4336p_ioctl(sd, cmd, &stream);
+		else
+			ret = -EFAULT;
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+#endif
+
+static int __sc4336p_start_stream(struct sc4336p *sc4336p)
+{
+	int ret;
+
+	if (!sc4336p->is_thunderboot) {
+		ret = sc4336p_write_array(sc4336p->client, sc4336p->cur_mode->reg_list);
+		if (ret)
+			return ret;
+
+		/* In case these controls are set before streaming */
+		ret = __v4l2_ctrl_handler_setup(&sc4336p->ctrl_handler);
+		if (ret)
+			return ret;
+	}
+
+	return sc4336p_write_reg(sc4336p->client, SC4336P_REG_CTRL_MODE,
+				 SC4336P_REG_VALUE_08BIT, SC4336P_MODE_STREAMING);
+}
+
+static int __sc4336p_stop_stream(struct sc4336p *sc4336p)
+{
+	if (sc4336p->is_thunderboot) {
+		sc4336p->is_first_streamoff = true;
+		pm_runtime_put(&sc4336p->client->dev);
+	}
+	return sc4336p_write_reg(sc4336p->client, SC4336P_REG_CTRL_MODE,
+				 SC4336P_REG_VALUE_08BIT, SC4336P_MODE_SW_STANDBY);
+}
+
+static int __sc4336p_power_on(struct sc4336p *sc4336p);
+static int sc4336p_s_stream(struct v4l2_subdev *sd, int on)
+{
+	struct sc4336p *sc4336p = to_sc4336p(sd);
+	struct i2c_client *client = sc4336p->client;
+	int ret = 0;
+
+	mutex_lock(&sc4336p->mutex);
+	on = !!on;
+	if (on == sc4336p->streaming)
+		goto unlock_and_return;
+
+	if (on) {
+		if (sc4336p->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
+			sc4336p->is_thunderboot = false;
+			__sc4336p_power_on(sc4336p);
+		}
+
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		ret = __sc4336p_start_stream(sc4336p);
+		if (ret) {
+			v4l2_err(sd, "start stream failed while write regs\n");
+			pm_runtime_put(&client->dev);
+			goto unlock_and_return;
+		}
+	} else {
+		__sc4336p_stop_stream(sc4336p);
+		pm_runtime_put(&client->dev);
+	}
+
+	sc4336p->streaming = on;
+
+unlock_and_return:
+	mutex_unlock(&sc4336p->mutex);
+
+	return ret;
+}
+
+static int sc4336p_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct sc4336p *sc4336p = to_sc4336p(sd);
+	struct i2c_client *client = sc4336p->client;
+	int ret = 0;
+
+	mutex_lock(&sc4336p->mutex);
+
+	/* If the power state is not modified - no work to do. */
+	if (sc4336p->power_on == !!on)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		if (!sc4336p->is_thunderboot) {
+			ret = sc4336p_write_array(sc4336p->client, sc4336p_global_regs);
+			if (ret) {
+				v4l2_err(sd, "could not set init registers\n");
+				pm_runtime_put_noidle(&client->dev);
+				goto unlock_and_return;
+			}
+		}
+
+		sc4336p->power_on = true;
+	} else {
+		pm_runtime_put(&client->dev);
+		sc4336p->power_on = false;
+	}
+
+unlock_and_return:
+	mutex_unlock(&sc4336p->mutex);
+
+	return ret;
+}
+
+/* Calculate the delay in us by clock rate and clock cycles */
+static inline u32 sc4336p_cal_delay(u32 cycles)
+{
+	return DIV_ROUND_UP(cycles, SC4336P_XVCLK_FREQ / 1000 / 1000);
+}
+
+static int __sc4336p_power_on(struct sc4336p *sc4336p)
+{
+	int ret;
+	u32 delay_us;
+	struct device *dev = &sc4336p->client->dev;
+
+	if (!IS_ERR_OR_NULL(sc4336p->pins_default)) {
+		ret = pinctrl_select_state(sc4336p->pinctrl,
+					   sc4336p->pins_default);
+		if (ret < 0)
+			dev_err(dev, "could not set pins\n");
+	}
+	ret = clk_set_rate(sc4336p->xvclk, SC4336P_XVCLK_FREQ);
+	if (ret < 0)
+		dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
+	if (clk_get_rate(sc4336p->xvclk) != SC4336P_XVCLK_FREQ)
+		dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
+	ret = clk_prepare_enable(sc4336p->xvclk);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable xvclk\n");
+		return ret;
+	}
+	if (sc4336p->is_thunderboot)
+		return 0;
+
+	if (!IS_ERR(sc4336p->reset_gpio))
+		gpiod_set_value_cansleep(sc4336p->reset_gpio, 0);
+
+	ret = regulator_bulk_enable(SC4336P_NUM_SUPPLIES, sc4336p->supplies);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable regulators\n");
+		goto disable_clk;
+	}
+
+	if (!IS_ERR(sc4336p->reset_gpio))
+		gpiod_set_value_cansleep(sc4336p->reset_gpio, 1);
+
+	usleep_range(500, 1000);
+	if (!IS_ERR(sc4336p->pwdn_gpio))
+		gpiod_set_value_cansleep(sc4336p->pwdn_gpio, 1);
+
+	if (!IS_ERR(sc4336p->reset_gpio))
+		usleep_range(6000, 8000);
+	else
+		usleep_range(12000, 16000);
+
+	/* 8192 cycles prior to first SCCB transaction */
+	delay_us = sc4336p_cal_delay(8192);
+	usleep_range(delay_us, delay_us * 2);
+
+	return 0;
+
+disable_clk:
+	clk_disable_unprepare(sc4336p->xvclk);
+
+	return ret;
+}
+
+static void __sc4336p_power_off(struct sc4336p *sc4336p)
+{
+	int ret;
+	struct device *dev = &sc4336p->client->dev;
+
+	clk_disable_unprepare(sc4336p->xvclk);
+	if (sc4336p->is_thunderboot) {
+		if (sc4336p->is_first_streamoff) {
+			sc4336p->is_thunderboot = false;
+			sc4336p->is_first_streamoff = false;
+		} else {
+			return;
+		}
+	}
+
+	if (!IS_ERR(sc4336p->pwdn_gpio))
+		gpiod_set_value_cansleep(sc4336p->pwdn_gpio, 0);
+	if (!IS_ERR(sc4336p->reset_gpio))
+		gpiod_set_value_cansleep(sc4336p->reset_gpio, 0);
+	if (!IS_ERR_OR_NULL(sc4336p->pins_sleep)) {
+		ret = pinctrl_select_state(sc4336p->pinctrl,
+					   sc4336p->pins_sleep);
+		if (ret < 0)
+			dev_dbg(dev, "could not set pins\n");
+	}
+	regulator_bulk_disable(SC4336P_NUM_SUPPLIES, sc4336p->supplies);
+}
+
+static int __maybe_unused sc4336p_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct sc4336p *sc4336p = to_sc4336p(sd);
+
+	return __sc4336p_power_on(sc4336p);
+}
+
+static int __maybe_unused sc4336p_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct sc4336p *sc4336p = to_sc4336p(sd);
+
+	__sc4336p_power_off(sc4336p);
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int sc4336p_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct sc4336p *sc4336p = to_sc4336p(sd);
+	struct v4l2_mbus_framefmt *try_fmt =
+				v4l2_subdev_get_try_format(sd, fh->pad, 0);
+	const struct sc4336p_mode *def_mode = &supported_modes[0];
+
+	mutex_lock(&sc4336p->mutex);
+	/* Initialize try_fmt */
+	try_fmt->width = def_mode->width;
+	try_fmt->height = def_mode->height;
+	try_fmt->code = def_mode->bus_fmt;
+	try_fmt->field = V4L2_FIELD_NONE;
+
+	mutex_unlock(&sc4336p->mutex);
+	/* No crop or compose */
+
+	return 0;
+}
+#endif
+
+static int sc4336p_enum_frame_interval(struct v4l2_subdev *sd,
+				       struct v4l2_subdev_pad_config *cfg,
+				       struct v4l2_subdev_frame_interval_enum *fie)
+{
+	if (fie->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	fie->code = supported_modes[fie->index].bus_fmt;
+	fie->width = supported_modes[fie->index].width;
+	fie->height = supported_modes[fie->index].height;
+	fie->interval = supported_modes[fie->index].max_fps;
+	fie->reserved[0] = supported_modes[fie->index].hdr_mode;
+	return 0;
+}
+
+static const struct dev_pm_ops sc4336p_pm_ops = {
+	SET_RUNTIME_PM_OPS(sc4336p_runtime_suspend,
+			   sc4336p_runtime_resume, NULL)
+};
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static const struct v4l2_subdev_internal_ops sc4336p_internal_ops = {
+	.open = sc4336p_open,
+};
+#endif
+
+static const struct v4l2_subdev_core_ops sc4336p_core_ops = {
+	.s_power = sc4336p_s_power,
+	.ioctl = sc4336p_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl32 = sc4336p_compat_ioctl32,
+#endif
+};
+
+static const struct v4l2_subdev_video_ops sc4336p_video_ops = {
+	.s_stream = sc4336p_s_stream,
+	.g_frame_interval = sc4336p_g_frame_interval,
+};
+
+static const struct v4l2_subdev_pad_ops sc4336p_pad_ops = {
+	.enum_mbus_code = sc4336p_enum_mbus_code,
+	.enum_frame_size = sc4336p_enum_frame_sizes,
+	.enum_frame_interval = sc4336p_enum_frame_interval,
+	.get_fmt = sc4336p_get_fmt,
+	.set_fmt = sc4336p_set_fmt,
+	.get_mbus_config = sc4336p_g_mbus_config,
+};
+
+static const struct v4l2_subdev_ops sc4336p_subdev_ops = {
+	.core	= &sc4336p_core_ops,
+	.video	= &sc4336p_video_ops,
+	.pad	= &sc4336p_pad_ops,
+};
+
+static void sc4336p_modify_fps_info(struct sc4336p *sc4336p)
+{
+	const struct sc4336p_mode *mode = sc4336p->cur_mode;
+
+	sc4336p->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
+				      sc4336p->cur_vts;
+}
+
+static int sc4336p_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct sc4336p *sc4336p = container_of(ctrl->handler,
+					       struct sc4336p, ctrl_handler);
+	struct i2c_client *client = sc4336p->client;
+	s64 max;
+	int ret = 0;
+	u32 val = 0;
+
+	/* Propagate change of current control to all related controls */
+	switch (ctrl->id) {
+	case V4L2_CID_VBLANK:
+		/* Update max exposure while meeting expected vblanking */
+		max = sc4336p->cur_mode->height + ctrl->val - 8;
+		__v4l2_ctrl_modify_range(sc4336p->exposure,
+					 sc4336p->exposure->minimum, max,
+					 sc4336p->exposure->step,
+					 sc4336p->exposure->default_value);
+		break;
+	}
+
+	if (!pm_runtime_get_if_in_use(&client->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		dev_dbg(&client->dev, "set exposure 0x%x\n", ctrl->val);
+		if (sc4336p->cur_mode->hdr_mode == NO_HDR) {
+			val = ctrl->val;
+			/* 4 least significant bits of expsoure are fractional part */
+			ret = sc4336p_write_reg(sc4336p->client,
+						SC4336P_REG_EXPOSURE_H,
+						SC4336P_REG_VALUE_08BIT,
+						SC4336P_FETCH_EXP_H(val));
+			ret |= sc4336p_write_reg(sc4336p->client,
+						 SC4336P_REG_EXPOSURE_M,
+						 SC4336P_REG_VALUE_08BIT,
+						 SC4336P_FETCH_EXP_M(val));
+			ret |= sc4336p_write_reg(sc4336p->client,
+						 SC4336P_REG_EXPOSURE_L,
+						 SC4336P_REG_VALUE_08BIT,
+						 SC4336P_FETCH_EXP_L(val));
+		}
+		break;
+	case V4L2_CID_ANALOGUE_GAIN:
+		dev_dbg(&client->dev, "set gain 0x%x\n", ctrl->val);
+		if (sc4336p->cur_mode->hdr_mode == NO_HDR)
+			ret = sc4336p_set_gain_reg(sc4336p, ctrl->val);
+		break;
+	case V4L2_CID_VBLANK:
+		dev_dbg(&client->dev, "set vblank 0x%x\n", ctrl->val);
+		ret = sc4336p_write_reg(sc4336p->client,
+					SC4336P_REG_VTS_H,
+					SC4336P_REG_VALUE_08BIT,
+					(ctrl->val + sc4336p->cur_mode->height)
+					>> 8);
+		ret |= sc4336p_write_reg(sc4336p->client,
+					 SC4336P_REG_VTS_L,
+					 SC4336P_REG_VALUE_08BIT,
+					 (ctrl->val + sc4336p->cur_mode->height)
+					 & 0xff);
+		sc4336p->cur_vts = ctrl->val + sc4336p->cur_mode->height;
+		sc4336p_modify_fps_info(sc4336p);
+		break;
+	case V4L2_CID_TEST_PATTERN:
+		ret = sc4336p_enable_test_pattern(sc4336p, ctrl->val);
+		break;
+	case V4L2_CID_HFLIP:
+		ret = sc4336p_read_reg(sc4336p->client, SC4336P_FLIP_MIRROR_REG,
+				       SC4336P_REG_VALUE_08BIT, &val);
+		ret |= sc4336p_write_reg(sc4336p->client, SC4336P_FLIP_MIRROR_REG,
+					 SC4336P_REG_VALUE_08BIT,
+					 SC4336P_FETCH_MIRROR(val, ctrl->val));
+		break;
+	case V4L2_CID_VFLIP:
+		ret = sc4336p_read_reg(sc4336p->client, SC4336P_FLIP_MIRROR_REG,
+				       SC4336P_REG_VALUE_08BIT, &val);
+		ret |= sc4336p_write_reg(sc4336p->client, SC4336P_FLIP_MIRROR_REG,
+					 SC4336P_REG_VALUE_08BIT,
+					 SC4336P_FETCH_FLIP(val, ctrl->val));
+		break;
+	default:
+		dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
+			 __func__, ctrl->id, ctrl->val);
+		break;
+	}
+
+	pm_runtime_put(&client->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops sc4336p_ctrl_ops = {
+	.s_ctrl = sc4336p_set_ctrl,
+};
+
+static int sc4336p_initialize_controls(struct sc4336p *sc4336p)
+{
+	const struct sc4336p_mode *mode;
+	struct v4l2_ctrl_handler *handler;
+	struct v4l2_ctrl *ctrl;
+	s64 exposure_max, vblank_def;
+	u32 h_blank;
+	int ret;
+
+	handler = &sc4336p->ctrl_handler;
+	mode = sc4336p->cur_mode;
+	ret = v4l2_ctrl_handler_init(handler, 9);
+	if (ret)
+		return ret;
+	handler->lock = &sc4336p->mutex;
+
+	ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
+				      0, 0, link_freq_menu_items);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
+			  0, PIXEL_RATE_WITH_315M_10BIT, 1, PIXEL_RATE_WITH_315M_10BIT);
+
+	h_blank = mode->hts_def - mode->width;
+	sc4336p->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
+					    h_blank, h_blank, 1, h_blank);
+	if (sc4336p->hblank)
+		sc4336p->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+	vblank_def = mode->vts_def - mode->height;
+	sc4336p->vblank = v4l2_ctrl_new_std(handler, &sc4336p_ctrl_ops,
+					    V4L2_CID_VBLANK, vblank_def,
+					    SC4336P_VTS_MAX - mode->height,
+					    1, vblank_def);
+	sc4336p->cur_fps = mode->max_fps;
+	exposure_max = mode->vts_def - 8;
+	sc4336p->exposure = v4l2_ctrl_new_std(handler, &sc4336p_ctrl_ops,
+					      V4L2_CID_EXPOSURE, SC4336P_EXPOSURE_MIN,
+					      exposure_max, SC4336P_EXPOSURE_STEP,
+					      mode->exp_def);
+	sc4336p->anal_gain = v4l2_ctrl_new_std(handler, &sc4336p_ctrl_ops,
+					       V4L2_CID_ANALOGUE_GAIN, SC4336P_GAIN_MIN,
+					       SC4336P_GAIN_MAX, SC4336P_GAIN_STEP,
+					       SC4336P_GAIN_DEFAULT);
+	sc4336p->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
+							    &sc4336p_ctrl_ops,
+					V4L2_CID_TEST_PATTERN,
+					ARRAY_SIZE(sc4336p_test_pattern_menu) - 1,
+					0, 0, sc4336p_test_pattern_menu);
+	v4l2_ctrl_new_std(handler, &sc4336p_ctrl_ops,
+				V4L2_CID_HFLIP, 0, 1, 1, 0);
+	v4l2_ctrl_new_std(handler, &sc4336p_ctrl_ops,
+				V4L2_CID_VFLIP, 0, 1, 1, 0);
+	if (handler->error) {
+		ret = handler->error;
+		dev_err(&sc4336p->client->dev,
+			"Failed to init controls(%d)\n", ret);
+		goto err_free_handler;
+	}
+
+	sc4336p->subdev.ctrl_handler = handler;
+
+	return 0;
+
+err_free_handler:
+	v4l2_ctrl_handler_free(handler);
+
+	return ret;
+}
+
+static int sc4336p_check_sensor_id(struct sc4336p *sc4336p,
+				   struct i2c_client *client)
+{
+	struct device *dev = &sc4336p->client->dev;
+	u32 id = 0;
+	int ret;
+
+	if (sc4336p->is_thunderboot) {
+		dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
+		return 0;
+	}
+
+	sc4336p_write_reg(client, 0x440d, SC4336P_REG_VALUE_08BIT, 0x10);
+	sc4336p_write_reg(client, 0x4400, SC4336P_REG_VALUE_08BIT, 0x11);
+	usleep_range(3000, 4000);
+
+	ret = sc4336p_read_reg(client, SC4336P_REG_CHIP_ID,
+			       SC4336P_REG_VALUE_16BIT, &id);
+	if (id != CHIP_ID) {
+		dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
+		return -ENODEV;
+	}
+
+	dev_info(dev, "Detected OV%06x sensor\n", CHIP_ID);
+
+	return 0;
+}
+
+static int sc4336p_configure_regulators(struct sc4336p *sc4336p)
+{
+	unsigned int i;
+
+	for (i = 0; i < SC4336P_NUM_SUPPLIES; i++)
+		sc4336p->supplies[i].supply = sc4336p_supply_names[i];
+
+	return devm_regulator_bulk_get(&sc4336p->client->dev,
+				       SC4336P_NUM_SUPPLIES,
+				       sc4336p->supplies);
+}
+
+static int sc4336p_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct device_node *node = dev->of_node;
+	struct sc4336p *sc4336p;
+	struct v4l2_subdev *sd;
+	char facing[2];
+	int ret;
+
+	dev_info(dev, "driver version: %02x.%02x.%02x",
+		 DRIVER_VERSION >> 16,
+		 (DRIVER_VERSION & 0xff00) >> 8,
+		 DRIVER_VERSION & 0x00ff);
+
+	sc4336p = devm_kzalloc(dev, sizeof(*sc4336p), GFP_KERNEL);
+	if (!sc4336p)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
+				   &sc4336p->module_index);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
+				       &sc4336p->module_facing);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
+				       &sc4336p->module_name);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
+				       &sc4336p->len_name);
+	if (ret) {
+		dev_err(dev, "could not get module information!\n");
+		return -EINVAL;
+	}
+
+	sc4336p->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
+	sc4336p->client = client;
+	sc4336p->cur_mode = &supported_modes[0];
+
+	sc4336p->xvclk = devm_clk_get(dev, "xvclk");
+	if (IS_ERR(sc4336p->xvclk)) {
+		dev_err(dev, "Failed to get xvclk\n");
+		return -EINVAL;
+	}
+
+	if (sc4336p->is_thunderboot) {
+		sc4336p->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
+		if (IS_ERR(sc4336p->reset_gpio))
+			dev_warn(dev, "Failed to get reset-gpios\n");
+
+		sc4336p->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
+		if (IS_ERR(sc4336p->pwdn_gpio))
+			dev_warn(dev, "Failed to get pwdn-gpios\n");
+	} else {
+		sc4336p->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+		if (IS_ERR(sc4336p->reset_gpio))
+			dev_warn(dev, "Failed to get reset-gpios\n");
+
+		sc4336p->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
+		if (IS_ERR(sc4336p->pwdn_gpio))
+			dev_warn(dev, "Failed to get pwdn-gpios\n");
+	}
+	sc4336p->pinctrl = devm_pinctrl_get(dev);
+	if (!IS_ERR(sc4336p->pinctrl)) {
+		sc4336p->pins_default =
+			pinctrl_lookup_state(sc4336p->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_DEFAULT);
+		if (IS_ERR(sc4336p->pins_default))
+			dev_err(dev, "could not get default pinstate\n");
+
+		sc4336p->pins_sleep =
+			pinctrl_lookup_state(sc4336p->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_SLEEP);
+		if (IS_ERR(sc4336p->pins_sleep))
+			dev_err(dev, "could not get sleep pinstate\n");
+	} else {
+		dev_err(dev, "no pinctrl\n");
+	}
+
+	ret = sc4336p_configure_regulators(sc4336p);
+	if (ret) {
+		dev_err(dev, "Failed to get power regulators\n");
+		return ret;
+	}
+
+	mutex_init(&sc4336p->mutex);
+
+	sd = &sc4336p->subdev;
+	v4l2_i2c_subdev_init(sd, client, &sc4336p_subdev_ops);
+	ret = sc4336p_initialize_controls(sc4336p);
+	if (ret)
+		goto err_destroy_mutex;
+
+	ret = __sc4336p_power_on(sc4336p);
+	if (ret)
+		goto err_free_handler;
+
+	ret = sc4336p_check_sensor_id(sc4336p, client);
+	if (ret)
+		goto err_power_off;
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	sd->internal_ops = &sc4336p_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+		     V4L2_SUBDEV_FL_HAS_EVENTS;
+#endif
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	sc4336p->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &sc4336p->pad);
+	if (ret < 0)
+		goto err_power_off;
+#endif
+
+	memset(facing, 0, sizeof(facing));
+	if (strcmp(sc4336p->module_facing, "back") == 0)
+		facing[0] = 'b';
+	else
+		facing[0] = 'f';
+
+	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
+		 sc4336p->module_index, facing,
+		 SC4336P_NAME, dev_name(sd->dev));
+	ret = v4l2_async_register_subdev_sensor_common(sd);
+	if (ret) {
+		dev_err(dev, "v4l2 async register subdev failed\n");
+		goto err_clean_entity;
+	}
+
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	if (sc4336p->is_thunderboot)
+		pm_runtime_get_sync(dev);
+	else
+		pm_runtime_idle(dev);
+
+	return 0;
+
+err_clean_entity:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+err_power_off:
+	__sc4336p_power_off(sc4336p);
+err_free_handler:
+	v4l2_ctrl_handler_free(&sc4336p->ctrl_handler);
+err_destroy_mutex:
+	mutex_destroy(&sc4336p->mutex);
+
+	return ret;
+}
+
+static int sc4336p_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct sc4336p *sc4336p = to_sc4336p(sd);
+
+	v4l2_async_unregister_subdev(sd);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+	v4l2_ctrl_handler_free(&sc4336p->ctrl_handler);
+	mutex_destroy(&sc4336p->mutex);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		__sc4336p_power_off(sc4336p);
+	pm_runtime_set_suspended(&client->dev);
+
+	return 0;
+}
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id sc4336p_of_match[] = {
+	{ .compatible = "smartsens,sc4336p" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, sc4336p_of_match);
+#endif
+
+static const struct i2c_device_id sc4336p_match_id[] = {
+	{ "smartsens,sc4336p", 0 },
+	{ },
+};
+
+static struct i2c_driver sc4336p_i2c_driver = {
+	.driver = {
+		.name = SC4336P_NAME,
+		.pm = &sc4336p_pm_ops,
+		.of_match_table = of_match_ptr(sc4336p_of_match),
+	},
+	.probe		= &sc4336p_probe,
+	.remove		= &sc4336p_remove,
+	.id_table	= sc4336p_match_id,
+};
+
+static int __init sensor_mod_init(void)
+{
+	return i2c_add_driver(&sc4336p_i2c_driver);
+}
+
+static void __exit sensor_mod_exit(void)
+{
+	i2c_del_driver(&sc4336p_i2c_driver);
+}
+
+#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
+subsys_initcall(sensor_mod_init);
+#else
+device_initcall_sync(sensor_mod_init);
+#endif
+module_exit(sensor_mod_exit);
+
+MODULE_DESCRIPTION("smartsens sc4336p sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/sc450ai.c b/kernel/drivers/media/i2c/sc450ai.c
new file mode 100644
index 0000000..254f516
--- /dev/null
+++ b/kernel/drivers/media/i2c/sc450ai.c
@@ -0,0 +1,1640 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * sc450ai driver
+ *
+ * Copyright (C) 2020 Rockchip Electronics Co., Ltd.
+ *
+ * V0.0X01.0X01 first version
+ */
+
+//#define DEBUG
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/rk-camera-module.h>
+#include <linux/rk-preisp.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <linux/pinctrl/consumer.h>
+#include "../platform/rockchip/isp/rkisp_tb_helper.h"
+
+#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x01)
+
+#ifndef V4L2_CID_DIGITAL_GAIN
+#define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
+#endif
+
+#define SC450AI_LANES			2
+#define SC450AI_BITS_PER_SAMPLE		10
+#define SC450AI_LINK_FREQ_360		360000000
+
+#define PIXEL_RATE_WITH_360M_10BIT	(SC450AI_LINK_FREQ_360 * 2 * \
+					SC450AI_LANES / SC450AI_BITS_PER_SAMPLE)
+
+#define SC450AI_XVCLK_FREQ		27000000
+
+#define CHIP_ID				0xbd2f
+#define SC450AI_REG_CHIP_ID		0x3107
+
+#define SC450AI_REG_CTRL_MODE		0x0100
+#define SC450AI_MODE_SW_STANDBY		0x0
+#define SC450AI_MODE_STREAMING		BIT(0)
+
+#define SC450AI_REG_EXPOSURE_H		0x3e00
+#define SC450AI_REG_EXPOSURE_M		0x3e01
+#define SC450AI_REG_EXPOSURE_L		0x3e02
+#define	SC450AI_EXPOSURE_MIN		1
+#define	SC450AI_EXPOSURE_STEP		1
+#define SC450AI_VTS_MAX			0x7fff
+
+#define SC450AI_REG_DIG_GAIN		0x3e06
+#define SC450AI_REG_DIG_FINE_GAIN	0x3e07
+#define SC450AI_REG_ANA_GAIN		0x3e08
+#define SC450AI_REG_ANA_FINE_GAIN	0x3e09
+#define SC450AI_GAIN_MIN		0x40	//0x0080
+#define SC450AI_GAIN_MAX		61975 //60.523*16*64	(99614)	//48.64*16*128
+#define SC450AI_GAIN_STEP		1
+#define SC450AI_GAIN_DEFAULT		0x40 //0x80 // Note that the benchmark is 0x40
+
+#define SC450AI_REG_GROUP_HOLD		0x3800//0x3812
+#define SC450AI_GROUP_HOLD_START	0x00
+#define SC450AI_GROUP_HOLD_END		0x30 // Not used
+
+#define SC450AI_REG_TEST_PATTERN		0x4501
+#define SC450AI_TEST_PATTERN_BIT_MASK	BIT(3)
+
+#define SC450AI_REG_VTS_H		0x320e
+#define SC450AI_REG_VTS_L		0x320f
+
+#define SC450AI_FLIP_MIRROR_REG		0x3221
+
+#define SC450AI_FETCH_EXP_H(VAL)		(((VAL) >> 12) & 0xF)
+#define SC450AI_FETCH_EXP_M(VAL)		(((VAL) >> 4) & 0xFF)
+#define SC450AI_FETCH_EXP_L(VAL)		(((VAL) & 0xF) << 4)
+
+//#define SC450AI_FETCH_AGAIN_H(VAL)	(((VAL) >> 8) & 0x7f)//(((VAL) >> 8) & 0x03)
+//#define SC450AI_FETCH_AGAIN_L(VAL)	((VAL) & 0xFF)
+
+#define SC450AI_FETCH_MIRROR(VAL, ENABLE)	(ENABLE ? VAL | 0x06 : VAL & 0xf9)
+#define SC450AI_FETCH_FLIP(VAL, ENABLE)		(ENABLE ? VAL | 0x60 : VAL & 0x9f)
+
+#define REG_DELAY			0xFFFE
+#define REG_NULL			0xFFFF
+
+#define SC450AI_REG_VALUE_08BIT		1
+#define SC450AI_REG_VALUE_16BIT		2
+#define SC450AI_REG_VALUE_24BIT		3
+
+#define OF_CAMERA_PINCTRL_STATE_DEFAULT	"rockchip,camera_default"
+#define OF_CAMERA_PINCTRL_STATE_SLEEP	"rockchip,camera_sleep"
+#define SC450AI_NAME			"sc450ai"
+
+static const char * const sc450ai_supply_names[] = {
+	"avdd",		/* Analog power */
+	"dovdd",	/* Digital I/O power */
+	"dvdd",		/* Digital core power */
+};
+
+#define SC450AI_NUM_SUPPLIES ARRAY_SIZE(sc450ai_supply_names)
+
+struct regval {
+	u16 addr;
+	u8 val;
+};
+
+struct sc450ai_mode {
+	u32 bus_fmt;
+	u32 width;
+	u32 height;
+	struct v4l2_fract max_fps;
+	u32 hts_def;
+	u32 vts_def;
+	u32 exp_def;
+	const struct regval *reg_list;
+	u32 hdr_mode;
+	u32 xvclk_freq;
+	u32 link_freq_idx;
+	u32 vc[PAD_MAX];
+};
+
+struct sc450ai {
+	struct i2c_client	*client;
+	struct clk		*xvclk;
+	struct gpio_desc	*reset_gpio;
+	struct gpio_desc	*pwdn_gpio;
+	struct regulator_bulk_data supplies[SC450AI_NUM_SUPPLIES];
+
+	struct pinctrl		*pinctrl;
+	struct pinctrl_state	*pins_default;
+	struct pinctrl_state	*pins_sleep;
+
+	struct v4l2_subdev	subdev;
+	struct media_pad	pad;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl	*exposure;
+	struct v4l2_ctrl	*anal_gain;
+	struct v4l2_ctrl	*digi_gain;
+	struct v4l2_ctrl	*hblank;
+	struct v4l2_ctrl	*vblank;
+	struct v4l2_ctrl	*pixel_rate;
+	struct v4l2_ctrl	*link_freq;
+	struct v4l2_ctrl	*test_pattern;
+	struct mutex		mutex;
+	struct v4l2_fract	cur_fps;
+	bool			streaming;
+	bool			power_on;
+	const struct sc450ai_mode *cur_mode;
+	u32			module_index;
+	const char		*module_facing;
+	const char		*module_name;
+	const char		*len_name;
+	u32			cur_vts;
+	bool			has_init_exp;
+	bool			is_thunderboot;
+	bool			is_first_streamoff;
+	struct preisp_hdrae_exp_s init_hdrae_exp;
+};
+
+#define to_sc450ai(sd) container_of(sd, struct sc450ai, subdev)
+
+/*
+ * Xclk 24Mhz
+ */
+static const struct regval sc450ai_global_regs[] = {
+	{REG_NULL, 0x00},
+};
+
+/*
+ * Xclk 27Mhz
+ * max_framerate 60fps
+ * mipi_datarate per lane 720Mbps, 2lane
+ */
+static const struct regval sc450ai_linear_10_2688x1520_30fps_regs[] = {
+	{0x0103, 0x01},
+	{0x0100, 0x00},
+	{0x36e9, 0x80},
+	{0x36f9, 0x80},
+	{0x3018, 0x3a},
+	{0x3019, 0x0c},
+	{0x301c, 0x78},
+	{0x301f, 0x3c},
+	{0x302e, 0x00},
+	{0x3208, 0x0a},
+	{0x3209, 0x80},
+	{0x320a, 0x05},
+	{0x320b, 0xf0},
+	{0x320c, 0x02},
+	{0x320d, 0xee},
+	{0x320e, 0x06},
+	{0x320f, 0x18},
+	{0x3214, 0x11},
+	{0x3215, 0x11},
+	{0x3220, 0x00},
+	{0x3223, 0xc0},
+	{0x3253, 0x10},
+	{0x325f, 0x44},
+	{0x3274, 0x09},
+	{0x3280, 0x01},
+	{0x3301, 0x07},
+	{0x3306, 0x20},
+	{0x3308, 0x08},
+	{0x330b, 0x58},
+	{0x330e, 0x18},
+	{0x3315, 0x00},
+	{0x335d, 0x60},
+	{0x3364, 0x56},
+	{0x338f, 0x80},
+	{0x3390, 0x08},
+	{0x3391, 0x18},
+	{0x3392, 0x38},
+	{0x3393, 0x07},
+	{0x3394, 0x10},
+	{0x3395, 0x18},
+	{0x3396, 0x08},
+	{0x3397, 0x18},
+	{0x3398, 0x38},
+	{0x3399, 0x10},
+	{0x339a, 0x13},
+	{0x339b, 0x15},
+	{0x339c, 0x18},
+	{0x33af, 0x18},
+	{0x360f, 0x13},
+	{0x3621, 0xec},
+	{0x3622, 0x00},
+	{0x3625, 0x0b},
+	{0x3627, 0x20},
+	{0x3630, 0x90},
+	{0x3633, 0x56},
+	{0x3637, 0x1d},
+	{0x3638, 0x12},
+	{0x363c, 0x0f},
+	{0x363d, 0x0f},
+	{0x363e, 0x08},
+	{0x3670, 0x4a},
+	{0x3671, 0xe0},
+	{0x3672, 0xe0},
+	{0x3673, 0xe0},
+	{0x3674, 0xc0},
+	{0x3675, 0x87},
+	{0x3676, 0x8c},
+	{0x367a, 0x48},
+	{0x367b, 0x58},
+	{0x367c, 0x48},
+	{0x367d, 0x58},
+	{0x3690, 0x22},
+	{0x3691, 0x33},
+	{0x3692, 0x44},
+	{0x3699, 0x03},
+	{0x369a, 0x0f},
+	{0x369b, 0x1f},
+	{0x369c, 0x40},
+	{0x369d, 0x78},
+	{0x36a2, 0x48},
+	{0x36a3, 0x78},
+	{0x36b0, 0x53},
+	{0x36b1, 0x74},
+	{0x36b2, 0x34},
+	{0x36b3, 0x40},
+	{0x36b4, 0x78},
+	{0x36b7, 0xa0},
+	{0x36b8, 0xa0},
+	{0x36b9, 0x20},
+	{0x36bd, 0x40},
+	{0x36be, 0x48},
+	{0x36d0, 0x20},
+	{0x36e0, 0x08},
+	{0x36e1, 0x08},
+	{0x36e2, 0x12},
+	{0x36e3, 0x48},
+	{0x36e4, 0x78},
+	{0x36ec, 0x43},
+	{0x36fc, 0x00},
+	{0x3907, 0x00},
+	{0x3908, 0x41},
+	{0x391e, 0xf1},
+	{0x391f, 0x11},
+	{0x3933, 0x82},
+	{0x3934, 0x30},
+	{0x3935, 0x02},
+	{0x3936, 0xc7},
+	{0x3937, 0x76},
+	{0x3938, 0x76},
+	{0x3939, 0x00},
+	{0x393a, 0x28},
+	{0x393b, 0x00},
+	{0x393c, 0x23},
+	{0x3e01, 0xc2},
+	{0x3e02, 0x60},
+	{0x3e03, 0x0b},
+	{0x3e08, 0x03},
+	{0x3e1b, 0x2a},
+	{0x440e, 0x02},
+	{0x4509, 0x20},
+	{0x4837, 0x16},
+	{0x5000, 0x0e},
+	{0x5001, 0x44},
+	{0x5784, 0x08},
+	{0x5785, 0x04},
+	{0x5787, 0x0a},
+	{0x5788, 0x0a},
+	{0x5789, 0x0a},
+	{0x578a, 0x0a},
+	{0x578b, 0x0a},
+	{0x578c, 0x0a},
+	{0x578d, 0x40},
+	{0x5790, 0x08},
+	{0x5791, 0x04},
+	{0x5792, 0x04},
+	{0x5793, 0x08},
+	{0x5794, 0x04},
+	{0x5795, 0x04},
+	{0x5799, 0x06},
+	{0x57aa, 0x28},
+	{0x57ab, 0x00},
+	{0x57ac, 0x00},
+	{0x57ad, 0x00},
+	{0x59e0, 0xfe},
+	{0x59e1, 0x40},
+	{0x59e2, 0x3f},
+	{0x59e3, 0x38},
+	{0x59e4, 0x30},
+	{0x59e5, 0x3f},
+	{0x59e6, 0x38},
+	{0x59e7, 0x30},
+	{0x59e8, 0x3f},
+	{0x59e9, 0x3c},
+	{0x59ea, 0x38},
+	{0x59eb, 0x3f},
+	{0x59ec, 0x3c},
+	{0x59ed, 0x38},
+	{0x59ee, 0xfe},
+	{0x59ef, 0x40},
+	{0x59f4, 0x3f},
+	{0x59f5, 0x38},
+	{0x59f6, 0x30},
+	{0x59f7, 0x3f},
+	{0x59f8, 0x38},
+	{0x59f9, 0x30},
+	{0x59fa, 0x3f},
+	{0x59fb, 0x3c},
+	{0x59fc, 0x38},
+	{0x59fd, 0x3f},
+	{0x59fe, 0x3c},
+	{0x59ff, 0x38},
+	{0x36e9, 0x44},
+	{0x36f9, 0x20},
+	{REG_NULL, 0x00},
+};
+
+static const struct sc450ai_mode supported_modes[] = {
+	{
+		.width = 2688,
+		.height = 1520,
+		.max_fps = {
+			.numerator = 10000,
+			.denominator = 300000,
+		},
+		.exp_def = 0x0080,//mark
+		.hts_def = 0x2ee * 4,
+		.vts_def = 0x0618,
+		.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.reg_list = sc450ai_linear_10_2688x1520_30fps_regs,
+		.hdr_mode = NO_HDR,
+		.xvclk_freq = 27000000,
+		.link_freq_idx = 0,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	},
+};
+
+static const s64 link_freq_menu_items[] = {
+	SC450AI_LINK_FREQ_360,
+};
+
+static const char * const sc450ai_test_pattern_menu[] = {
+	"Disabled",
+	"Vertical Color Bar Type 1",
+	"Vertical Color Bar Type 2",
+	"Vertical Color Bar Type 3",
+	"Vertical Color Bar Type 4",
+};
+
+/* Write registers up to 4 at a time */
+static int sc450ai_write_reg(struct i2c_client *client, u16 reg,
+			    u32 len, u32 val)
+{
+	u32 buf_i, val_i;
+	u8 buf[6];
+	u8 *val_p;
+	__be32 val_be;
+
+	if (len > 4)
+		return -EINVAL;
+
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xff;
+
+	val_be = cpu_to_be32(val);
+	val_p = (u8 *)&val_be;
+	buf_i = 2;
+	val_i = 4 - len;
+
+	while (val_i < 4)
+		buf[buf_i++] = val_p[val_i++];
+
+	if (i2c_master_send(client, buf, len + 2) != len + 2)
+		return -EIO;
+	return 0;
+}
+
+static int sc450ai_write_array(struct i2c_client *client,
+			       const struct regval *regs)
+{
+	u32 i;
+	int ret = 0;
+
+	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++)
+		ret = sc450ai_write_reg(client, regs[i].addr,
+					SC450AI_REG_VALUE_08BIT, regs[i].val);
+
+	return ret;
+}
+
+/* Read registers up to 4 at a time */
+static int sc450ai_read_reg(struct i2c_client *client, u16 reg, unsigned int len,
+			    u32 *val)
+{
+	struct i2c_msg msgs[2];
+	u8 *data_be_p;
+	__be32 data_be = 0;
+	__be16 reg_addr_be = cpu_to_be16(reg);
+	int ret;
+
+	if (len > 4 || !len)
+		return -EINVAL;
+
+	data_be_p = (u8 *)&data_be;
+	/* Write register address */
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = 2;
+	msgs[0].buf = (u8 *)&reg_addr_be;
+
+	/* Read data from register */
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = len;
+	msgs[1].buf = &data_be_p[4 - len];
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs))
+		return -EIO;
+
+	*val = be32_to_cpu(data_be);
+
+	return 0;
+}
+
+static int sc450ai_set_gain_reg(struct sc450ai *sc450ai, u32 gain)
+{
+	struct i2c_client *client = sc450ai->client;
+	u32 coarse_again = 0, coarse_dgain = 0, fine_again = 0, fine_dgain = 0;
+	int ret = 0, gain_factor;
+
+	if (gain < 64)
+		gain = 64;
+	else if (gain > SC450AI_GAIN_MAX)
+		gain = SC450AI_GAIN_MAX;
+
+	gain_factor = gain * 1000 / 64;
+	if (gain_factor < 2000) {
+		coarse_again = 0x03;
+		coarse_dgain = 0x00;
+		fine_dgain = 0x80;
+		fine_again = gain_factor * 64 / 1000;
+	} else if (gain_factor < 3813) {//mark
+		coarse_again = 0x07;
+		coarse_dgain = 0x00;
+		fine_dgain = 0x80;
+		fine_again = gain_factor * 64 / 2000;
+	} else if (gain_factor < 7625) {
+		coarse_again = 0x23;
+		coarse_dgain = 0x00;
+		fine_dgain = 0x80;
+		fine_again = gain_factor * 64 / 3813;
+	} else if (gain_factor < 15250) {
+		coarse_again = 0x27;
+		coarse_dgain = 0x00;
+		fine_dgain = 0x80;
+		fine_again = gain_factor * 64 / 7625;
+	} else if (gain_factor < 30500) {
+		coarse_again = 0x2f;
+		coarse_dgain = 0x00;
+		fine_dgain = 0x80;
+		fine_again = gain_factor * 64 / 15250;
+	} else if (gain_factor <= 60523) {
+		coarse_again = 0x3f;
+		coarse_dgain = 0x00;
+		fine_dgain = 0x80;
+		fine_again = gain_factor * 64 / 30500;
+	} else if (gain_factor < 60523 * 2) {
+		//open dgain begin  max digital gain 4X
+		coarse_again = 0x3f;
+		coarse_dgain = 0x00;
+		fine_again = 0x7f;
+		fine_dgain = gain_factor * 128 / 60523;
+	} else if (gain_factor < 60523 * 4) {
+		coarse_again = 0x3f;
+		coarse_dgain = 0x01;
+		fine_again = 0x7f;
+		fine_dgain = gain_factor * 128 / 60523 / 2;
+	} else if (gain_factor < 60523 * 8) {
+		coarse_again = 0x3f;
+		coarse_dgain = 0x03;
+		fine_again = 0x7f;
+		fine_dgain = gain_factor * 128 / 60523 / 4;
+	} else if (gain_factor < 60523 * 16) {
+		coarse_again = 0x3f;
+		coarse_dgain = 0x07;
+		fine_again = 0x7f;
+		fine_dgain = gain_factor * 128 / 60523 / 8;
+	}
+	dev_dbg(&client->dev, "c_again: 0x%x, c_dgain: 0x%x, f_again: 0x%x, f_dgain: 0x%0x\n",
+		    coarse_again, coarse_dgain, fine_again, fine_dgain);
+
+	ret = sc450ai_write_reg(sc450ai->client,
+				SC450AI_REG_DIG_GAIN,
+				SC450AI_REG_VALUE_08BIT,
+				coarse_dgain);
+	ret |= sc450ai_write_reg(sc450ai->client,
+				 SC450AI_REG_DIG_FINE_GAIN,
+				 SC450AI_REG_VALUE_08BIT,
+				 fine_dgain);
+	ret |= sc450ai_write_reg(sc450ai->client,
+				 SC450AI_REG_ANA_GAIN,
+				 SC450AI_REG_VALUE_08BIT,
+				 coarse_again);
+	ret |= sc450ai_write_reg(sc450ai->client,
+				 SC450AI_REG_ANA_FINE_GAIN,
+				 SC450AI_REG_VALUE_08BIT,
+				 fine_again);
+	return ret;
+}
+
+static int sc450ai_get_reso_dist(const struct sc450ai_mode *mode,
+				 struct v4l2_mbus_framefmt *framefmt)
+{
+	return abs(mode->width - framefmt->width) +
+	       abs(mode->height - framefmt->height);
+}
+
+static const struct sc450ai_mode *
+sc450ai_find_best_fit(struct v4l2_subdev_format *fmt)
+{
+	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
+	int dist;
+	int cur_best_fit = 0;
+	int cur_best_fit_dist = -1;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+		dist = sc450ai_get_reso_dist(&supported_modes[i], framefmt);
+		if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
+			cur_best_fit_dist = dist;
+			cur_best_fit = i;
+		}
+	}
+
+	return &supported_modes[cur_best_fit];
+}
+
+static int sc450ai_set_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct sc450ai *sc450ai = to_sc450ai(sd);
+	const struct sc450ai_mode *mode;
+	s64 h_blank, vblank_def;
+	u64 dst_link_freq = 0;
+	u64 dst_pixel_rate = 0;
+
+	mutex_lock(&sc450ai->mutex);
+
+	mode = sc450ai_find_best_fit(fmt);
+	fmt->format.code = mode->bus_fmt;
+	fmt->format.width = mode->width;
+	fmt->format.height = mode->height;
+	fmt->format.field = V4L2_FIELD_NONE;
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+#else
+		mutex_unlock(&sc450ai->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		sc450ai->cur_mode = mode;
+		h_blank = mode->hts_def - mode->width;
+		__v4l2_ctrl_modify_range(sc450ai->hblank, h_blank,
+					 h_blank, 1, h_blank);
+		vblank_def = mode->vts_def - mode->height;
+		__v4l2_ctrl_modify_range(sc450ai->vblank, vblank_def,
+					 SC450AI_VTS_MAX - mode->height,
+					 1, vblank_def);
+		dst_link_freq = mode->link_freq_idx;
+		dst_pixel_rate = (u32)link_freq_menu_items[mode->link_freq_idx] /
+						 SC450AI_BITS_PER_SAMPLE * 2 * SC450AI_LANES;
+		__v4l2_ctrl_s_ctrl_int64(sc450ai->pixel_rate,
+					 dst_pixel_rate);
+		__v4l2_ctrl_s_ctrl(sc450ai->link_freq,
+				   dst_link_freq);
+		sc450ai->cur_fps = mode->max_fps;
+	}
+
+	mutex_unlock(&sc450ai->mutex);
+
+	return 0;
+}
+
+static int sc450ai_get_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_pad_config *cfg,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct sc450ai *sc450ai = to_sc450ai(sd);
+	const struct sc450ai_mode *mode = sc450ai->cur_mode;
+
+	mutex_lock(&sc450ai->mutex);
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+#else
+		mutex_unlock(&sc450ai->mutex);
+		return -ENOTTY;
+#endif
+	} else {
+		fmt->format.width = mode->width;
+		fmt->format.height = mode->height;
+		fmt->format.code = mode->bus_fmt;
+		fmt->format.field = V4L2_FIELD_NONE;
+		/* format info: width/height/data type/virctual channel */
+		if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
+			fmt->reserved[0] = mode->vc[fmt->pad];
+		else
+			fmt->reserved[0] = mode->vc[PAD0];
+	}
+	mutex_unlock(&sc450ai->mutex);
+
+	return 0;
+}
+
+static int sc450ai_enum_mbus_code(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_pad_config *cfg,
+				  struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct sc450ai *sc450ai = to_sc450ai(sd);
+
+	if (code->index != 0)
+		return -EINVAL;
+	code->code = sc450ai->cur_mode->bus_fmt;
+
+	return 0;
+}
+
+static int sc450ai_enum_frame_sizes(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_pad_config *cfg,
+				    struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	if (fse->code != supported_modes[0].bus_fmt)
+		return -EINVAL;
+
+	fse->min_width  = supported_modes[fse->index].width;
+	fse->max_width  = supported_modes[fse->index].width;
+	fse->max_height = supported_modes[fse->index].height;
+	fse->min_height = supported_modes[fse->index].height;
+
+	return 0;
+}
+
+static int sc450ai_enable_test_pattern(struct sc450ai *sc450ai, u32 pattern)
+{
+	u32 val = 0;
+	int ret = 0;
+
+	ret = sc450ai_read_reg(sc450ai->client, SC450AI_REG_TEST_PATTERN,
+			       SC450AI_REG_VALUE_08BIT, &val);
+	if (pattern)
+		val |= SC450AI_TEST_PATTERN_BIT_MASK;
+	else
+		val &= ~SC450AI_TEST_PATTERN_BIT_MASK;
+
+	ret |= sc450ai_write_reg(sc450ai->client, SC450AI_REG_TEST_PATTERN,
+				 SC450AI_REG_VALUE_08BIT, val);
+	return ret;
+}
+
+static int sc450ai_g_frame_interval(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_frame_interval *fi)
+{
+	struct sc450ai *sc450ai = to_sc450ai(sd);
+	const struct sc450ai_mode *mode = sc450ai->cur_mode;
+
+	if (sc450ai->streaming)
+		fi->interval = sc450ai->cur_fps;
+	else
+		fi->interval = mode->max_fps;
+	return 0;
+}
+
+static int sc450ai_g_mbus_config(struct v4l2_subdev *sd,
+				unsigned int pad_id,
+				struct v4l2_mbus_config *config)
+{
+	struct sc450ai *sc450ai = to_sc450ai(sd);
+	const struct sc450ai_mode *mode = sc450ai->cur_mode;
+
+	u32 val = 1 << (SC450AI_LANES - 1) |
+		V4L2_MBUS_CSI2_CHANNEL_0 |
+		V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+
+	if (mode->hdr_mode != NO_HDR)
+		val |= V4L2_MBUS_CSI2_CHANNEL_1;
+	if (mode->hdr_mode == HDR_X3)
+		val |= V4L2_MBUS_CSI2_CHANNEL_2;
+
+	config->type = V4L2_MBUS_CSI2_DPHY;
+	config->flags = val;
+
+	return 0;
+}
+
+static void sc450ai_get_module_inf(struct sc450ai *sc450ai,
+				   struct rkmodule_inf *inf)
+{
+	memset(inf, 0, sizeof(*inf));
+	strscpy(inf->base.sensor, SC450AI_NAME, sizeof(inf->base.sensor));
+	strscpy(inf->base.module, sc450ai->module_name,
+		sizeof(inf->base.module));
+	strscpy(inf->base.lens, sc450ai->len_name, sizeof(inf->base.lens));
+}
+
+static long sc450ai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	struct sc450ai *sc450ai = to_sc450ai(sd);
+	struct rkmodule_hdr_cfg *hdr;
+	u32 i, h, w;
+	long ret = 0;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		sc450ai_get_module_inf(sc450ai, (struct rkmodule_inf *)arg);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr = (struct rkmodule_hdr_cfg *)arg;
+		hdr->esp.mode = HDR_NORMAL_VC;
+		hdr->hdr_mode = sc450ai->cur_mode->hdr_mode;
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		hdr = (struct rkmodule_hdr_cfg *)arg;
+		w = sc450ai->cur_mode->width;
+		h = sc450ai->cur_mode->height;
+		for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+			if (w == supported_modes[i].width &&
+			    h == supported_modes[i].height &&
+			    supported_modes[i].hdr_mode == hdr->hdr_mode) {
+				sc450ai->cur_mode = &supported_modes[i];
+				break;
+			}
+		}
+		if (i == ARRAY_SIZE(supported_modes)) {
+			dev_err(&sc450ai->client->dev,
+				"not find hdr mode:%d %dx%d config\n",
+				hdr->hdr_mode, w, h);
+			ret = -EINVAL;
+		} else {
+			w = sc450ai->cur_mode->hts_def - sc450ai->cur_mode->width;
+			h = sc450ai->cur_mode->vts_def - sc450ai->cur_mode->height;
+			__v4l2_ctrl_modify_range(sc450ai->hblank, w, w, 1, w);
+			__v4l2_ctrl_modify_range(sc450ai->vblank, h,
+						 SC450AI_VTS_MAX - sc450ai->cur_mode->height, 1, h);
+			sc450ai->cur_fps = sc450ai->cur_mode->max_fps;
+		}
+		break;
+	case PREISP_CMD_SET_HDRAE_EXP:
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+
+		stream = *((u32 *)arg);
+
+		if (stream)
+			ret = sc450ai_write_reg(sc450ai->client, SC450AI_REG_CTRL_MODE,
+				 SC450AI_REG_VALUE_08BIT, SC450AI_MODE_STREAMING);
+		else
+			ret = sc450ai_write_reg(sc450ai->client, SC450AI_REG_CTRL_MODE,
+				 SC450AI_REG_VALUE_08BIT, SC450AI_MODE_SW_STANDBY);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long sc450ai_compat_ioctl32(struct v4l2_subdev *sd,
+				   unsigned int cmd, unsigned long arg)
+{
+	void __user *up = compat_ptr(arg);
+	struct rkmodule_inf *inf;
+	struct rkmodule_hdr_cfg *hdr;
+	struct preisp_hdrae_exp_s *hdrae;
+	long ret;
+	u32 stream = 0;
+
+	switch (cmd) {
+	case RKMODULE_GET_MODULE_INFO:
+		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
+		if (!inf) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = sc450ai_ioctl(sd, cmd, inf);
+		if (!ret) {
+			if (copy_to_user(up, inf, sizeof(*inf)))
+				ret = -EFAULT;
+		}
+		kfree(inf);
+		break;
+	case RKMODULE_GET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = sc450ai_ioctl(sd, cmd, hdr);
+		if (!ret) {
+			if (copy_to_user(up, hdr, sizeof(*hdr)))
+				ret = -EFAULT;
+		}
+		kfree(hdr);
+		break;
+	case RKMODULE_SET_HDR_CFG:
+		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+		if (!hdr) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(hdr, up, sizeof(*hdr));
+		if (!ret)
+			ret = sc450ai_ioctl(sd, cmd, hdr);
+		else
+			ret = -EFAULT;
+		kfree(hdr);
+		break;
+	case PREISP_CMD_SET_HDRAE_EXP:
+		hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
+		if (!hdrae) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = copy_from_user(hdrae, up, sizeof(*hdrae));
+		if (!ret)
+			ret = sc450ai_ioctl(sd, cmd, hdrae);
+		else
+			ret = -EFAULT;
+		kfree(hdrae);
+		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		ret = copy_from_user(&stream, up, sizeof(u32));
+		if (!ret)
+			ret = sc450ai_ioctl(sd, cmd, &stream);
+		else
+			ret = -EFAULT;
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+#endif
+
+static int __sc450ai_start_stream(struct sc450ai *sc450ai)
+{
+	int ret;
+
+	if (!sc450ai->is_thunderboot) {
+		ret = sc450ai_write_array(sc450ai->client, sc450ai->cur_mode->reg_list);
+		if (ret)
+			return ret;
+		/* In case these controls are set before streaming */
+		ret = __v4l2_ctrl_handler_setup(&sc450ai->ctrl_handler);
+		if (ret)
+			return ret;
+		if (sc450ai->has_init_exp && sc450ai->cur_mode->hdr_mode != NO_HDR) {
+			ret = sc450ai_ioctl(&sc450ai->subdev, PREISP_CMD_SET_HDRAE_EXP,
+				&sc450ai->init_hdrae_exp);
+			if (ret) {
+				dev_err(&sc450ai->client->dev,
+					"init exp fail in hdr mode\n");
+				return ret;
+			}
+		}
+	}
+	ret = sc450ai_write_reg(sc450ai->client, SC450AI_REG_CTRL_MODE,
+				 SC450AI_REG_VALUE_08BIT, SC450AI_MODE_STREAMING);
+	return ret;
+}
+
+static int __sc450ai_stop_stream(struct sc450ai *sc450ai)
+{
+	sc450ai->has_init_exp = false;
+	if (sc450ai->is_thunderboot)
+		sc450ai->is_first_streamoff = true;
+	return sc450ai_write_reg(sc450ai->client, SC450AI_REG_CTRL_MODE,
+				 SC450AI_REG_VALUE_08BIT, SC450AI_MODE_SW_STANDBY);
+}
+
+static int __sc450ai_power_on(struct sc450ai *sc450ai);
+static int sc450ai_s_stream(struct v4l2_subdev *sd, int on)
+{
+	struct sc450ai *sc450ai = to_sc450ai(sd);
+	struct i2c_client *client = sc450ai->client;
+	int ret = 0;
+
+	mutex_lock(&sc450ai->mutex);
+	on = !!on;
+	if (on == sc450ai->streaming)
+		goto unlock_and_return;
+	if (on) {
+		if (sc450ai->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
+			sc450ai->is_thunderboot = false;
+			__sc450ai_power_on(sc450ai);
+		}
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+		ret = __sc450ai_start_stream(sc450ai);
+		if (ret) {
+			v4l2_err(sd, "start stream failed while write regs\n");
+			pm_runtime_put(&client->dev);
+			goto unlock_and_return;
+		}
+	} else {
+		__sc450ai_stop_stream(sc450ai);
+		pm_runtime_put(&client->dev);
+	}
+
+	sc450ai->streaming = on;
+unlock_and_return:
+	mutex_unlock(&sc450ai->mutex);
+	return ret;
+}
+
+static int sc450ai_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct sc450ai *sc450ai = to_sc450ai(sd);
+	struct i2c_client *client = sc450ai->client;
+	int ret = 0;
+
+	mutex_lock(&sc450ai->mutex);
+
+	/* If the power state is not modified - no work to do. */
+	if (sc450ai->power_on == !!on)
+		goto unlock_and_return;
+
+	if (on) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto unlock_and_return;
+		}
+
+		if (!sc450ai->is_thunderboot) {
+			ret = sc450ai_write_array(sc450ai->client, sc450ai_global_regs);
+			if (ret) {
+				v4l2_err(sd, "could not set init registers\n");
+				pm_runtime_put_noidle(&client->dev);
+				goto unlock_and_return;
+			}
+		}
+
+		sc450ai->power_on = true;
+	} else {
+		pm_runtime_put(&client->dev);
+		sc450ai->power_on = false;
+	}
+
+unlock_and_return:
+	mutex_unlock(&sc450ai->mutex);
+
+	return ret;
+}
+
+/* Calculate the delay in us by clock rate and clock cycles */
+static inline u32 sc450ai_cal_delay(u32 cycles, struct sc450ai *sc450ai)
+{
+	return DIV_ROUND_UP(cycles, sc450ai->cur_mode->xvclk_freq / 1000 / 1000);
+}
+
+static int __sc450ai_power_on(struct sc450ai *sc450ai)
+{
+	int ret;
+	u32 delay_us;
+	struct device *dev = &sc450ai->client->dev;
+
+	if (!IS_ERR_OR_NULL(sc450ai->pins_default)) {
+		ret = pinctrl_select_state(sc450ai->pinctrl,
+					   sc450ai->pins_default);
+		if (ret < 0)
+			dev_err(dev, "could not set pins\n");
+	}
+	ret = clk_set_rate(sc450ai->xvclk, sc450ai->cur_mode->xvclk_freq);
+	if (ret < 0)
+		dev_warn(dev, "Failed to set xvclk rate (%dHz)\n", sc450ai->cur_mode->xvclk_freq);
+	if (clk_get_rate(sc450ai->xvclk) != sc450ai->cur_mode->xvclk_freq)
+		dev_warn(dev, "xvclk mismatched, modes are based on %dHz\n",
+			 sc450ai->cur_mode->xvclk_freq);
+	ret = clk_prepare_enable(sc450ai->xvclk);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable xvclk\n");
+		return ret;
+	}
+
+	if (sc450ai->is_thunderboot)
+		return 0;
+
+	if (!IS_ERR(sc450ai->reset_gpio))
+		gpiod_set_value_cansleep(sc450ai->reset_gpio, 0);
+
+	ret = regulator_bulk_enable(SC450AI_NUM_SUPPLIES, sc450ai->supplies);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable regulators\n");
+		goto disable_clk;
+	}
+
+	if (!IS_ERR(sc450ai->reset_gpio))
+		gpiod_set_value_cansleep(sc450ai->reset_gpio, 1);
+
+	usleep_range(500, 1000);
+
+	if (!IS_ERR(sc450ai->pwdn_gpio))
+		gpiod_set_value_cansleep(sc450ai->pwdn_gpio, 1);
+
+	if (!IS_ERR(sc450ai->reset_gpio))
+		usleep_range(6000, 8000);
+	else
+		usleep_range(12000, 16000);
+
+	/* 8192 cycles prior to first SCCB transaction */
+	delay_us = sc450ai_cal_delay(8192, sc450ai);
+	usleep_range(delay_us, delay_us * 2);
+
+	return 0;
+
+disable_clk:
+	clk_disable_unprepare(sc450ai->xvclk);
+
+	return ret;
+}
+
+static void __sc450ai_power_off(struct sc450ai *sc450ai)
+{
+	int ret;
+	struct device *dev = &sc450ai->client->dev;
+
+	clk_disable_unprepare(sc450ai->xvclk);
+	if (sc450ai->is_thunderboot) {
+		if (sc450ai->is_first_streamoff) {
+			sc450ai->is_thunderboot = false;
+			sc450ai->is_first_streamoff = false;
+		} else {
+			return;
+		}
+	}
+
+	if (!IS_ERR(sc450ai->pwdn_gpio))
+		gpiod_set_value_cansleep(sc450ai->pwdn_gpio, 0);
+	clk_disable_unprepare(sc450ai->xvclk);
+	if (!IS_ERR(sc450ai->reset_gpio))
+		gpiod_set_value_cansleep(sc450ai->reset_gpio, 0);
+	if (!IS_ERR_OR_NULL(sc450ai->pins_sleep)) {
+		ret = pinctrl_select_state(sc450ai->pinctrl,
+					   sc450ai->pins_sleep);
+		if (ret < 0)
+			dev_dbg(dev, "could not set pins\n");
+	}
+	regulator_bulk_disable(SC450AI_NUM_SUPPLIES, sc450ai->supplies);
+}
+
+static int __maybe_unused sc450ai_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct sc450ai *sc450ai = to_sc450ai(sd);
+
+	return __sc450ai_power_on(sc450ai);
+}
+
+static int __maybe_unused sc450ai_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct sc450ai *sc450ai = to_sc450ai(sd);
+
+	__sc450ai_power_off(sc450ai);
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int sc450ai_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct sc450ai *sc450ai = to_sc450ai(sd);
+	struct v4l2_mbus_framefmt *try_fmt =
+				v4l2_subdev_get_try_format(sd, fh->pad, 0);
+	const struct sc450ai_mode *def_mode = &supported_modes[0];
+
+	mutex_lock(&sc450ai->mutex);
+	/* Initialize try_fmt */
+	try_fmt->width = def_mode->width;
+	try_fmt->height = def_mode->height;
+	try_fmt->code = def_mode->bus_fmt;
+	try_fmt->field = V4L2_FIELD_NONE;
+
+	mutex_unlock(&sc450ai->mutex);
+	/* No crop or compose */
+
+	return 0;
+}
+#endif
+
+static int sc450ai_enum_frame_interval(struct v4l2_subdev *sd,
+				       struct v4l2_subdev_pad_config *cfg,
+				       struct v4l2_subdev_frame_interval_enum *fie)
+{
+	if (fie->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	fie->code = supported_modes[fie->index].bus_fmt;
+	fie->width = supported_modes[fie->index].width;
+	fie->height = supported_modes[fie->index].height;
+	fie->interval = supported_modes[fie->index].max_fps;
+	fie->reserved[0] = supported_modes[fie->index].hdr_mode;
+	return 0;
+}
+
+static const struct dev_pm_ops sc450ai_pm_ops = {
+	SET_RUNTIME_PM_OPS(sc450ai_runtime_suspend,
+			   sc450ai_runtime_resume, NULL)
+};
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static const struct v4l2_subdev_internal_ops sc450ai_internal_ops = {
+	.open = sc450ai_open,
+};
+#endif
+
+static const struct v4l2_subdev_core_ops sc450ai_core_ops = {
+	.s_power = sc450ai_s_power,
+	.ioctl = sc450ai_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl32 = sc450ai_compat_ioctl32,
+#endif
+};
+
+static const struct v4l2_subdev_video_ops sc450ai_video_ops = {
+	.s_stream = sc450ai_s_stream,
+	.g_frame_interval = sc450ai_g_frame_interval,
+};
+
+static const struct v4l2_subdev_pad_ops sc450ai_pad_ops = {
+	.enum_mbus_code = sc450ai_enum_mbus_code,
+	.enum_frame_size = sc450ai_enum_frame_sizes,
+	.enum_frame_interval = sc450ai_enum_frame_interval,
+	.get_fmt = sc450ai_get_fmt,
+	.set_fmt = sc450ai_set_fmt,
+	.get_mbus_config = sc450ai_g_mbus_config,
+};
+
+static const struct v4l2_subdev_ops sc450ai_subdev_ops = {
+	.core	= &sc450ai_core_ops,
+	.video	= &sc450ai_video_ops,
+	.pad	= &sc450ai_pad_ops,
+};
+
+static void sc450ai_modify_fps_info(struct sc450ai *sc450ai)
+{
+	const struct sc450ai_mode *mode = sc450ai->cur_mode;
+
+	sc450ai->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
+				      sc450ai->cur_vts;
+}
+
+static int sc450ai_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct sc450ai *sc450ai = container_of(ctrl->handler,
+					       struct sc450ai, ctrl_handler);
+	struct i2c_client *client = sc450ai->client;
+	s64 max;
+	int ret = 0;
+	u32 val = 0;
+
+	/* Propagate change of current control to all related controls */
+	switch (ctrl->id) {
+	case V4L2_CID_VBLANK:
+		/* Update max exposure while meeting expected vblanking */
+		max = sc450ai->cur_mode->height + ctrl->val - 5;
+		__v4l2_ctrl_modify_range(sc450ai->exposure,
+					 sc450ai->exposure->minimum, max,
+					 sc450ai->exposure->step,
+					 sc450ai->exposure->default_value);
+		break;
+	}
+
+	if (!pm_runtime_get_if_in_use(&client->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		dev_dbg(&client->dev, "set exposure 0x%x\n", ctrl->val);
+		if (sc450ai->cur_mode->hdr_mode == NO_HDR) {
+			val = ctrl->val<<1;
+			/* 4 least significant bits of expsoure are fractional part */
+			ret = sc450ai_write_reg(sc450ai->client,
+						SC450AI_REG_EXPOSURE_H,
+						SC450AI_REG_VALUE_08BIT,
+						SC450AI_FETCH_EXP_H(val));
+			ret |= sc450ai_write_reg(sc450ai->client,
+						 SC450AI_REG_EXPOSURE_M,
+						 SC450AI_REG_VALUE_08BIT,
+						 SC450AI_FETCH_EXP_M(val));
+			ret |= sc450ai_write_reg(sc450ai->client,
+						 SC450AI_REG_EXPOSURE_L,
+						 SC450AI_REG_VALUE_08BIT,
+						 SC450AI_FETCH_EXP_L(val));
+		}
+		break;
+	case V4L2_CID_ANALOGUE_GAIN:
+		dev_dbg(&client->dev, "set gain 0x%x\n", ctrl->val);
+		if (sc450ai->cur_mode->hdr_mode == NO_HDR)
+			ret = sc450ai_set_gain_reg(sc450ai, ctrl->val);
+		break;
+	case V4L2_CID_VBLANK:
+		dev_dbg(&client->dev, "set vblank 0x%x\n", ctrl->val);
+		ret = sc450ai_write_reg(sc450ai->client,
+					SC450AI_REG_VTS_H,
+					SC450AI_REG_VALUE_08BIT,
+					(ctrl->val + sc450ai->cur_mode->height)
+					>> 8);
+		ret |= sc450ai_write_reg(sc450ai->client,
+					 SC450AI_REG_VTS_L,
+					 SC450AI_REG_VALUE_08BIT,
+					 (ctrl->val + sc450ai->cur_mode->height)
+					 & 0xff);
+		sc450ai->cur_vts = ctrl->val + sc450ai->cur_mode->height;
+		if (sc450ai->cur_vts != sc450ai->cur_mode->vts_def)
+			sc450ai_modify_fps_info(sc450ai);
+		break;
+	case V4L2_CID_TEST_PATTERN:
+		ret = sc450ai_enable_test_pattern(sc450ai, ctrl->val);
+		break;
+	case V4L2_CID_HFLIP:
+		ret = sc450ai_read_reg(sc450ai->client, SC450AI_FLIP_MIRROR_REG,
+				       SC450AI_REG_VALUE_08BIT, &val);
+		ret |= sc450ai_write_reg(sc450ai->client, SC450AI_FLIP_MIRROR_REG,
+					 SC450AI_REG_VALUE_08BIT,
+					 SC450AI_FETCH_MIRROR(val, ctrl->val));
+		break;
+	case V4L2_CID_VFLIP:
+		ret = sc450ai_read_reg(sc450ai->client, SC450AI_FLIP_MIRROR_REG,
+				       SC450AI_REG_VALUE_08BIT, &val);
+		ret |= sc450ai_write_reg(sc450ai->client, SC450AI_FLIP_MIRROR_REG,
+					 SC450AI_REG_VALUE_08BIT,
+					 SC450AI_FETCH_FLIP(val, ctrl->val));
+		break;
+	default:
+		dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
+			 __func__, ctrl->id, ctrl->val);
+		break;
+	}
+
+	pm_runtime_put(&client->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops sc450ai_ctrl_ops = {
+	.s_ctrl = sc450ai_set_ctrl,
+};
+
+static int sc450ai_initialize_controls(struct sc450ai *sc450ai)
+{
+	const struct sc450ai_mode *mode;
+	struct v4l2_ctrl_handler *handler;
+	s64 exposure_max, vblank_def;
+	u32 h_blank;
+	int ret;
+	u64 dst_link_freq = 0;
+	u64 dst_pixel_rate = 0;
+
+	handler = &sc450ai->ctrl_handler;
+	mode = sc450ai->cur_mode;
+	ret = v4l2_ctrl_handler_init(handler, 9);
+	if (ret)
+		return ret;
+	handler->lock = &sc450ai->mutex;
+
+	sc450ai->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
+			V4L2_CID_LINK_FREQ,
+			ARRAY_SIZE(link_freq_menu_items) - 1, 0, link_freq_menu_items);
+	if (sc450ai->link_freq)
+		sc450ai->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	dst_link_freq = mode->link_freq_idx;
+	dst_pixel_rate = (u32)link_freq_menu_items[mode->link_freq_idx] /
+					 SC450AI_BITS_PER_SAMPLE * 2 * SC450AI_LANES;
+	sc450ai->pixel_rate = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
+			  0, PIXEL_RATE_WITH_360M_10BIT, 1, dst_pixel_rate);
+
+	__v4l2_ctrl_s_ctrl(sc450ai->link_freq, dst_link_freq);
+
+	h_blank = mode->hts_def - mode->width;
+	sc450ai->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
+					    h_blank, h_blank, 1, h_blank);
+	if (sc450ai->hblank)
+		sc450ai->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+	vblank_def = mode->vts_def - mode->height;
+	sc450ai->vblank = v4l2_ctrl_new_std(handler, &sc450ai_ctrl_ops,
+					    V4L2_CID_VBLANK, vblank_def,
+					    SC450AI_VTS_MAX - mode->height,
+					    1, vblank_def);
+	exposure_max = mode->vts_def - 8;
+	sc450ai->exposure = v4l2_ctrl_new_std(handler, &sc450ai_ctrl_ops,
+					      V4L2_CID_EXPOSURE, SC450AI_EXPOSURE_MIN,
+					      exposure_max, SC450AI_EXPOSURE_STEP,
+					      mode->exp_def);
+	sc450ai->anal_gain = v4l2_ctrl_new_std(handler, &sc450ai_ctrl_ops,
+					       V4L2_CID_ANALOGUE_GAIN, SC450AI_GAIN_MIN,
+					       SC450AI_GAIN_MAX, SC450AI_GAIN_STEP,
+					       SC450AI_GAIN_DEFAULT);
+	sc450ai->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
+							    &sc450ai_ctrl_ops,
+					V4L2_CID_TEST_PATTERN,
+					ARRAY_SIZE(sc450ai_test_pattern_menu) - 1,
+					0, 0, sc450ai_test_pattern_menu);
+	v4l2_ctrl_new_std(handler, &sc450ai_ctrl_ops,
+				V4L2_CID_HFLIP, 0, 1, 1, 0);
+	v4l2_ctrl_new_std(handler, &sc450ai_ctrl_ops,
+				V4L2_CID_VFLIP, 0, 1, 1, 0);
+	if (handler->error) {
+		ret = handler->error;
+		dev_err(&sc450ai->client->dev,
+			"Failed to init controls(%d)\n", ret);
+		goto err_free_handler;
+	}
+
+	sc450ai->subdev.ctrl_handler = handler;
+	sc450ai->has_init_exp = false;
+	sc450ai->cur_fps = mode->max_fps;
+
+	return 0;
+
+err_free_handler:
+	v4l2_ctrl_handler_free(handler);
+
+	return ret;
+}
+
+static int sc450ai_check_sensor_id(struct sc450ai *sc450ai,
+				   struct i2c_client *client)
+{
+	struct device *dev = &sc450ai->client->dev;
+	u32 id = 0;
+	int ret;
+
+	if (sc450ai->is_thunderboot) {
+		dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
+		return 0;
+	}
+
+	ret = sc450ai_read_reg(client, SC450AI_REG_CHIP_ID,
+			       SC450AI_REG_VALUE_16BIT, &id);
+	if (id != CHIP_ID) {
+		dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
+		return -ENODEV;
+	}
+
+	dev_info(dev, "Detected OV%06x sensor\n", CHIP_ID);
+
+	return 0;
+}
+
+static int sc450ai_configure_regulators(struct sc450ai *sc450ai)
+{
+	unsigned int i;
+
+	for (i = 0; i < SC450AI_NUM_SUPPLIES; i++)
+		sc450ai->supplies[i].supply = sc450ai_supply_names[i];
+
+	return devm_regulator_bulk_get(&sc450ai->client->dev,
+				       SC450AI_NUM_SUPPLIES,
+				       sc450ai->supplies);
+}
+
+static int sc450ai_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct device_node *node = dev->of_node;
+	struct sc450ai *sc450ai;
+	struct v4l2_subdev *sd;
+	char facing[2];
+	int ret;
+	int i, hdr_mode = 0;
+
+	dev_info(dev, "driver version: %02x.%02x.%02x",
+		 DRIVER_VERSION >> 16,
+		 (DRIVER_VERSION & 0xff00) >> 8,
+		 DRIVER_VERSION & 0x00ff);
+
+	sc450ai = devm_kzalloc(dev, sizeof(*sc450ai), GFP_KERNEL);
+	if (!sc450ai)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
+				   &sc450ai->module_index);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
+				       &sc450ai->module_facing);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
+				       &sc450ai->module_name);
+	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
+				       &sc450ai->len_name);
+	if (ret) {
+		dev_err(dev, "could not get module information!\n");
+		return -EINVAL;
+	}
+
+	sc450ai->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
+
+	sc450ai->client = client;
+	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
+		if (hdr_mode == supported_modes[i].hdr_mode) {
+			sc450ai->cur_mode = &supported_modes[i];
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(supported_modes))
+		sc450ai->cur_mode = &supported_modes[0];
+
+	sc450ai->xvclk = devm_clk_get(dev, "xvclk");
+	if (IS_ERR(sc450ai->xvclk)) {
+		dev_err(dev, "Failed to get xvclk\n");
+		return -EINVAL;
+	}
+
+	if (!sc450ai->is_thunderboot)
+		sc450ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	else
+		sc450ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
+	if (IS_ERR(sc450ai->reset_gpio))
+		dev_warn(dev, "Failed to get reset-gpios\n");
+
+	if (!sc450ai->is_thunderboot)
+		sc450ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
+	else
+		sc450ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
+	if (IS_ERR(sc450ai->pwdn_gpio))
+		dev_warn(dev, "Failed to get pwdn-gpios\n");
+
+	sc450ai->pinctrl = devm_pinctrl_get(dev);
+	if (!IS_ERR(sc450ai->pinctrl)) {
+		sc450ai->pins_default =
+			pinctrl_lookup_state(sc450ai->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_DEFAULT);
+		if (IS_ERR(sc450ai->pins_default))
+			dev_err(dev, "could not get default pinstate\n");
+
+		sc450ai->pins_sleep =
+			pinctrl_lookup_state(sc450ai->pinctrl,
+					     OF_CAMERA_PINCTRL_STATE_SLEEP);
+		if (IS_ERR(sc450ai->pins_sleep))
+			dev_err(dev, "could not get sleep pinstate\n");
+	} else {
+		dev_err(dev, "no pinctrl\n");
+	}
+
+	ret = sc450ai_configure_regulators(sc450ai);
+	if (ret) {
+		dev_err(dev, "Failed to get power regulators\n");
+		return ret;
+	}
+
+	mutex_init(&sc450ai->mutex);
+
+	sd = &sc450ai->subdev;
+	v4l2_i2c_subdev_init(sd, client, &sc450ai_subdev_ops);
+	ret = sc450ai_initialize_controls(sc450ai);
+	if (ret)
+		goto err_destroy_mutex;
+
+	ret = __sc450ai_power_on(sc450ai);
+	if (ret)
+		goto err_free_handler;
+
+	ret = sc450ai_check_sensor_id(sc450ai, client);
+	if (ret)
+		goto err_power_off;
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	sd->internal_ops = &sc450ai_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+		     V4L2_SUBDEV_FL_HAS_EVENTS;
+#endif
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	sc450ai->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &sc450ai->pad);
+	if (ret < 0)
+		goto err_power_off;
+#endif
+
+	memset(facing, 0, sizeof(facing));
+	if (strcmp(sc450ai->module_facing, "back") == 0)
+		facing[0] = 'b';
+	else
+		facing[0] = 'f';
+
+	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
+		 sc450ai->module_index, facing,
+		 SC450AI_NAME, dev_name(sd->dev));
+	ret = v4l2_async_register_subdev_sensor_common(sd);
+	if (ret) {
+		dev_err(dev, "v4l2 async register subdev failed\n");
+		goto err_clean_entity;
+	}
+
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_idle(dev);
+
+	return 0;
+
+err_clean_entity:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+err_power_off:
+	__sc450ai_power_off(sc450ai);
+err_free_handler:
+	v4l2_ctrl_handler_free(&sc450ai->ctrl_handler);
+err_destroy_mutex:
+	mutex_destroy(&sc450ai->mutex);
+
+	return ret;
+}
+
+static int sc450ai_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct sc450ai *sc450ai = to_sc450ai(sd);
+
+	v4l2_async_unregister_subdev(sd);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&sd->entity);
+#endif
+	v4l2_ctrl_handler_free(&sc450ai->ctrl_handler);
+	mutex_destroy(&sc450ai->mutex);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		__sc450ai_power_off(sc450ai);
+	pm_runtime_set_suspended(&client->dev);
+
+	return 0;
+}
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id sc450ai_of_match[] = {
+	{ .compatible = "smartsens,sc450ai" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, sc450ai_of_match);
+#endif
+
+static const struct i2c_device_id sc450ai_match_id[] = {
+	{ "smartsens,sc450ai", 0 },
+	{ },
+};
+
+static struct i2c_driver sc450ai_i2c_driver = {
+	.driver = {
+		.name = SC450AI_NAME,
+		.pm = &sc450ai_pm_ops,
+		.of_match_table = of_match_ptr(sc450ai_of_match),
+	},
+	.probe		= &sc450ai_probe,
+	.remove		= &sc450ai_remove,
+	.id_table	= sc450ai_match_id,
+};
+
+static int __init sensor_mod_init(void)
+{
+	return i2c_add_driver(&sc450ai_i2c_driver);
+}
+
+static void __exit sensor_mod_exit(void)
+{
+	i2c_del_driver(&sc450ai_i2c_driver);
+}
+
+#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
+subsys_initcall(sensor_mod_init);
+#else
+device_initcall_sync(sensor_mod_init);
+#endif
+module_exit(sensor_mod_exit);
+
+MODULE_DESCRIPTION("smartsens sc450ai sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/media/i2c/sc530ai.c b/kernel/drivers/media/i2c/sc530ai.c
index 7738dc5..d8e3548 100644
--- a/kernel/drivers/media/i2c/sc530ai.c
+++ b/kernel/drivers/media/i2c/sc530ai.c
@@ -43,6 +43,7 @@
 #include <linux/printk.h>
 
 #include <linux/rk-camera-module.h>
+#include "../platform/rockchip/isp/rkisp_tb_helper.h"
 #define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x01)
 
 #ifndef V4L2_CID_DIGITAL_GAIN
@@ -195,6 +196,8 @@
 	const char		*module_name;
 	const char		*len_name;
 	bool			has_init_exp;
+	bool			is_thunderboot;
+	bool			is_first_streamoff;
 	struct preisp_hdrae_exp_s init_hdrae_exp;
 };
 
@@ -1351,21 +1354,23 @@
 {
 	int ret;
 
-	ret = sc530ai_write_array(sc530ai->client, sc530ai->cur_mode->reg_list);
-	if (ret)
-		return ret;
-
-	/* In case these controls are set before streaming */
-	ret = __v4l2_ctrl_handler_setup(&sc530ai->ctrl_handler);
-	if (ret)
-		return ret;
-	if (sc530ai->has_init_exp && sc530ai->cur_mode->hdr_mode != NO_HDR) {
-		ret = sc530ai_ioctl(&sc530ai->subdev, PREISP_CMD_SET_HDRAE_EXP,
-				    &sc530ai->init_hdrae_exp);
-		if (ret) {
-			dev_err(&sc530ai->client->dev,
-				"init exp fail in hdr mode\n");
+	if (!sc530ai->is_thunderboot) {
+		ret = sc530ai_write_array(sc530ai->client, sc530ai->cur_mode->reg_list);
+		if (ret)
 			return ret;
+
+		/* In case these controls are set before streaming */
+		ret = __v4l2_ctrl_handler_setup(&sc530ai->ctrl_handler);
+		if (ret)
+			return ret;
+		if (sc530ai->has_init_exp && sc530ai->cur_mode->hdr_mode != NO_HDR) {
+			ret = sc530ai_ioctl(&sc530ai->subdev, PREISP_CMD_SET_HDRAE_EXP,
+						&sc530ai->init_hdrae_exp);
+			if (ret) {
+				dev_err(&sc530ai->client->dev,
+					"init exp fail in hdr mode\n");
+				return ret;
+			}
 		}
 	}
 	return sc530ai_write_reg(sc530ai->client, SC530AI_REG_CTRL_MODE,
@@ -1376,11 +1381,16 @@
 static int __sc530ai_stop_stream(struct sc530ai *sc530ai)
 {
 	sc530ai->has_init_exp = false;
+	if (sc530ai->is_thunderboot) {
+		sc530ai->is_first_streamoff = true;
+		pm_runtime_put(&sc530ai->client->dev);
+	}
 	return sc530ai_write_reg(sc530ai->client, SC530AI_REG_CTRL_MODE,
 				 SC530AI_REG_VALUE_08BIT,
 				 SC530AI_MODE_SW_STANDBY);
 }
 
+static int __sc530ai_power_on(struct sc530ai *sc530ai);
 static int sc530ai_s_stream(struct v4l2_subdev *sd, int on)
 {
 	struct sc530ai *sc530ai = to_sc530ai(sd);
@@ -1392,6 +1402,10 @@
 	if (on == sc530ai->streaming)
 		goto unlock_and_return;
 	if (on) {
+		if (sc530ai->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
+			sc530ai->is_thunderboot = false;
+			__sc530ai_power_on(sc530ai);
+		}
 		ret = pm_runtime_get_sync(&client->dev);
 		if (ret < 0) {
 			pm_runtime_put_noidle(&client->dev);
@@ -1434,13 +1448,18 @@
 			pm_runtime_put_noidle(&client->dev);
 			goto unlock_and_return;
 		}
-
-		ret |= sc530ai_write_reg(sc530ai->client,
-					 SC530AI_SOFTWARE_RESET_REG,
-					 SC530AI_REG_VALUE_08BIT,
-					 0x01);
-		usleep_range(100, 200);
-
+		if (!sc530ai->is_thunderboot) {
+			ret |= sc530ai_write_reg(sc530ai->client,
+						SC530AI_SOFTWARE_RESET_REG,
+						SC530AI_REG_VALUE_08BIT,
+						0x01);
+			if (ret) {
+				v4l2_err(sd, "could not set init registers\n");
+				pm_runtime_put_noidle(&client->dev);
+				goto unlock_and_return;
+			}
+			usleep_range(100, 200);
+		}
 		sc530ai->power_on = true;
 	} else {
 		pm_runtime_put(&client->dev);
@@ -1474,6 +1493,10 @@
 		dev_err(dev, "Failed to enable xvclk\n");
 		return ret;
 	}
+
+	if (sc530ai->is_thunderboot)
+		return 0;
+
 	if (!IS_ERR(sc530ai->reset_gpio))
 		gpiod_set_value_cansleep(sc530ai->reset_gpio, 0);
 
@@ -1503,6 +1526,15 @@
 {
 	int ret;
 	struct device *dev = &sc530ai->client->dev;
+
+	if (sc530ai->is_thunderboot) {
+		if (sc530ai->is_first_streamoff) {
+			sc530ai->is_thunderboot = false;
+			sc530ai->is_first_streamoff = false;
+		} else {
+			return;
+		}
+	}
 
 	if (!IS_ERR(sc530ai->pwdn_gpio))
 		gpiod_set_value_cansleep(sc530ai->pwdn_gpio, 0);
@@ -1903,6 +1935,10 @@
 	u32 id = 0;
 	int ret;
 
+	if (sc530ai->is_thunderboot) {
+		dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
+		return 0;
+	}
 	ret = sc530ai_read_reg(client, SC530AI_REG_CHIP_ID,
 			       SC530AI_REG_VALUE_16BIT, &id);
 	if (id != SC530AI_CHIP_ID) {
@@ -1961,6 +1997,7 @@
 		return -EINVAL;
 	}
 
+	sc530ai->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
 	sc530ai->client = client;
 
 	ret = sc530ai_parse_of(sc530ai);
@@ -1973,11 +2010,13 @@
 		return -EINVAL;
 	}
 
-	sc530ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	sc530ai->reset_gpio = devm_gpiod_get(dev, "reset",
+		sc530ai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
 	if (IS_ERR(sc530ai->reset_gpio))
 		dev_warn(dev, "Failed to get reset-gpios\n");
 
-	sc530ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
+	sc530ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn",
+		sc530ai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
 	if (IS_ERR(sc530ai->pwdn_gpio))
 		dev_warn(dev, "Failed to get pwdn-gpios\n");
 
@@ -2051,7 +2090,10 @@
 
 	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
-	pm_runtime_idle(dev);
+	if (sc530ai->is_thunderboot)
+		pm_runtime_get_sync(dev);
+	else
+		pm_runtime_idle(dev);
 
 	return 0;
 
diff --git a/kernel/drivers/media/i2c/sc5336.c b/kernel/drivers/media/i2c/sc5336.c
index eb0b925..9420ac1 100644
--- a/kernel/drivers/media/i2c/sc5336.c
+++ b/kernel/drivers/media/i2c/sc5336.c
@@ -51,7 +51,7 @@
 #define SC5336_REG_EXPOSURE_H		0x3e00
 #define SC5336_REG_EXPOSURE_M		0x3e01
 #define SC5336_REG_EXPOSURE_L		0x3e02
-#define	SC5336_EXPOSURE_MIN		1
+#define	SC5336_EXPOSURE_MIN		2
 #define	SC5336_EXPOSURE_STEP		1
 #define SC5336_VTS_MAX			0x7fff
 
@@ -244,7 +244,7 @@
 	{0x3633, 0x33},
 	{0x3638, 0xcf},
 	{0x363f, 0xc0},
-	{0x3641, 0x20},
+	{0x3641, 0x38},
 	{0x3670, 0x56},
 	{0x3674, 0xc0},
 	{0x3675, 0xa0},
@@ -287,6 +287,7 @@
 	{0x37fb, 0x24},
 	{0x37fc, 0x01},
 	{0x37fd, 0x36},
+	{0x3900, 0x0d},
 	{0x3901, 0x00},
 	{0x3904, 0x04},
 	{0x3905, 0x8c},
@@ -866,6 +867,7 @@
 static int __sc5336_start_stream(struct sc5336 *sc5336)
 {
 	int ret;
+	u32 chip_version = 0;
 
 	if (!sc5336->is_thunderboot) {
 		ret = sc5336_write_array(sc5336->client, sc5336->cur_mode->reg_list);
@@ -877,6 +879,22 @@
 		if (ret)
 			return ret;
 	}
+	ret = sc5336_read_reg(sc5336->client, 0x3040, SC5336_REG_VALUE_08BIT, &chip_version);
+	if (chip_version == 0x00) {
+		ret |= sc5336_write_reg(sc5336->client, 0x3258, SC5336_REG_VALUE_08BIT, 0x0c);
+		ret |= sc5336_write_reg(sc5336->client, 0x3249, SC5336_REG_VALUE_08BIT, 0x0b);
+		ret |= sc5336_write_reg(sc5336->client, 0x3934, SC5336_REG_VALUE_08BIT, 0x0a);
+		ret |= sc5336_write_reg(sc5336->client, 0x3935, SC5336_REG_VALUE_08BIT, 0x00);
+		ret |= sc5336_write_reg(sc5336->client, 0x3937, SC5336_REG_VALUE_08BIT, 0x75);
+	} else if (chip_version == 0x03) {
+		ret |= sc5336_write_reg(sc5336->client, 0x3258, SC5336_REG_VALUE_08BIT, 0x08);
+		ret |= sc5336_write_reg(sc5336->client, 0x3249, SC5336_REG_VALUE_08BIT, 0x07);
+		ret |= sc5336_write_reg(sc5336->client, 0x3934, SC5336_REG_VALUE_08BIT, 0x05);
+		ret |= sc5336_write_reg(sc5336->client, 0x3935, SC5336_REG_VALUE_08BIT, 0x07);
+		ret |= sc5336_write_reg(sc5336->client, 0x3937, SC5336_REG_VALUE_08BIT, 0x74);
+	}
+	if (ret)
+		return ret;
 
 	return sc5336_write_reg(sc5336->client, SC5336_REG_CTRL_MODE,
 				 SC5336_REG_VALUE_08BIT, SC5336_MODE_STREAMING);
diff --git a/kernel/drivers/media/i2c/techpoint/Makefile b/kernel/drivers/media/i2c/techpoint/Makefile
index f7dc0e8..68a8201 100644
--- a/kernel/drivers/media/i2c/techpoint/Makefile
+++ b/kernel/drivers/media/i2c/techpoint/Makefile
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 techpoint-objs	+= techpoint_v4l2.o techpoint_dev.o \
 		   techpoint_tp9930.o techpoint_tp2855.o \
-		   techpoint_tp9950.o
+		   techpoint_tp9950.o techpoint_tp9951.o
 obj-$(CONFIG_VIDEO_TECHPOINT)	+= techpoint.o
diff --git a/kernel/drivers/media/i2c/techpoint/techpoint_common.h b/kernel/drivers/media/i2c/techpoint/techpoint_common.h
index db556c0..c7310f3 100644
--- a/kernel/drivers/media/i2c/techpoint/techpoint_common.h
+++ b/kernel/drivers/media/i2c/techpoint/techpoint_common.h
@@ -52,6 +52,7 @@
 	CHIP_TP2815,
 	CHIP_TP9930,
 	CHIP_TP9950,
+	CHIP_TP9951,
 };
 
 enum techpoint_input_type {
diff --git a/kernel/drivers/media/i2c/techpoint/techpoint_dev.c b/kernel/drivers/media/i2c/techpoint/techpoint_dev.c
index 33115f0..5692fbc 100644
--- a/kernel/drivers/media/i2c/techpoint/techpoint_dev.c
+++ b/kernel/drivers/media/i2c/techpoint/techpoint_dev.c
@@ -12,6 +12,7 @@
 #include "techpoint_tp9950.h"
 #include "techpoint_tp2855.h"
 #include "techpoint_tp2815.h"
+#include "techpoint_tp9951.h"
 
 static DEFINE_MUTEX(reg_sem);
 
@@ -99,31 +100,38 @@
 	techpoint_read_reg(client, CHIP_ID_L_REG, &chip_id_l);
 	dev_err(dev, "chip_id_h:0x%2x chip_id_l:0x%2x\n", chip_id_h, chip_id_l);
 	if (chip_id_h == TP9930_CHIP_ID_H_VALUE &&
-	    chip_id_l == TP9930_CHIP_ID_L_VALUE) {
+	    chip_id_l == TP9930_CHIP_ID_L_VALUE) {		//tp2832
 		dev_info(&client->dev,
 			 "techpoint check chip id CHIP_TP9930 !\n");
 		techpoint->chip_id = CHIP_TP9930;
 		techpoint->input_type = TECHPOINT_DVP_BT1120;
 		return 0;
 	} else if (chip_id_h == TP2855_CHIP_ID_H_VALUE &&
-		   chip_id_l == TP2855_CHIP_ID_L_VALUE) {
+		   chip_id_l == TP2855_CHIP_ID_L_VALUE) {	//tp2855
 		dev_info(&client->dev,
 			 "techpoint check chip id CHIP_TP2855 !\n");
 		techpoint->chip_id = CHIP_TP2855;
 		techpoint->input_type = TECHPOINT_MIPI;
 		return 0;
 	} else if (chip_id_h == TP2815_CHIP_ID_H_VALUE &&
-		   chip_id_l == TP2815_CHIP_ID_L_VALUE) {
+		   chip_id_l == TP2815_CHIP_ID_L_VALUE) {	//tp2815
 		dev_info(&client->dev,
 			 "techpoint check chip id CHIP_TP2815 !\n");
 		techpoint->chip_id = CHIP_TP2855;
 		techpoint->input_type = TECHPOINT_MIPI;
 		return 0;
 	} else if (chip_id_h == TP9950_CHIP_ID_H_VALUE &&
-		   chip_id_l == TP9950_CHIP_ID_L_VALUE) {
+		   chip_id_l == TP9950_CHIP_ID_L_VALUE) {	//tp2850
 		dev_info(&client->dev,
 			 "techpoint check chip id CHIP_TP9950 !\n");
 		techpoint->chip_id = CHIP_TP9950;
+		techpoint->input_type = TECHPOINT_MIPI;
+		return 0;
+	} else if (chip_id_h == TP9951_CHIP_ID_H_VALUE &&
+		   chip_id_l == TP9951_CHIP_ID_L_VALUE) {	//tp2860
+		dev_info(&client->dev,
+			 "techpoint check chip id CHIP_TP9951 !\n");
+		techpoint->chip_id = CHIP_TP9951;
 		techpoint->input_type = TECHPOINT_MIPI;
 		return 0;
 	}
@@ -143,6 +151,8 @@
 		tp2855_initialize(techpoint);
 	else if (techpoint->chip_id == CHIP_TP9950)
 		tp9950_initialize(techpoint);
+	else if (techpoint->chip_id == CHIP_TP9951)
+		tp9951_initialize(techpoint);
 
 	return 0;
 }
@@ -185,6 +195,10 @@
 					detect_status =
 					    tp2855_get_channel_input_status
 					    (techpoint, i);
+				else if (techpoint->chip_id == CHIP_TP9951)
+					detect_status =
+					    tp9951_get_channel_input_status
+					    (techpoint, i);
 
 				if (techpoint->detect_status[i] !=
 				    detect_status) {
@@ -202,8 +216,7 @@
 					else if (techpoint->chip_id == CHIP_TP2855)
 						tp2855_set_decoder_mode(client, i, detect_status);
 
-					techpoint->detect_status[i] =
-					    detect_status;
+					techpoint->detect_status[i] = detect_status;
 					need_reset_wait = 5;
 				}
 			}
@@ -273,6 +286,11 @@
 		tp9950_set_channel_reso(client, 0, reso);
 	}
 
+	if (techpoint->chip_id == CHIP_TP9951) {
+		reso = tp9951_get_channel_reso(client, 0);
+		tp9951_set_channel_reso(client, 0, reso);
+	}
+
 	mutex_unlock(&reg_sem);
 
 	return 0;
diff --git a/kernel/drivers/media/i2c/techpoint/techpoint_tp9951.c b/kernel/drivers/media/i2c/techpoint/techpoint_tp9951.c
new file mode 100644
index 0000000..8ad43fa
--- /dev/null
+++ b/kernel/drivers/media/i2c/techpoint/techpoint_tp9951.c
@@ -0,0 +1,638 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * techpoint lib
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+#include "techpoint_tp9951.h"
+#include "techpoint_dev.h"
+
+static struct techpoint_video_modes supported_modes[] = {
+#if TP9951_DEF_PAL
+	{
+	 .bus_fmt = MEDIA_BUS_FMT_UYVY8_2X8,
+	 .width = 960,
+	 .height = 576,
+	 .max_fps = {
+			.numerator = 10000,
+			.denominator = 250000,
+			},
+	 .link_freq_value = TP9951_LINK_FREQ_148M,
+	 .common_reg_list = NULL,
+	 .common_reg_size = 0,
+	 .bpp = TP9951_BITS_PER_SAMPLE,
+	 .lane = TP9951_LANES,
+	 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,
+	 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_2,
+	 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_3,
+	},
+#endif
+#if TP9951_DEF_NTSC
+	{
+	 .bus_fmt = MEDIA_BUS_FMT_UYVY8_2X8,
+	 .width = 960,
+	 .height = 480,
+	 .max_fps = {
+			.numerator = 10000,
+			.denominator = 250000,
+			},
+	 .link_freq_value = TP9951_LINK_FREQ_148M,
+	 .common_reg_list = NULL,
+	 .common_reg_size = 0,
+	 .bpp = TP9951_BITS_PER_SAMPLE,
+	 .lane = TP9951_LANES,
+	 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,
+	 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_2,
+	 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_3,
+	},
+#endif
+#if TP9951_DEF_1080P
+	{
+	 .bus_fmt = MEDIA_BUS_FMT_UYVY8_2X8,
+	 .width = 1920,
+	 .height = 1080,
+	 .max_fps = {
+			.numerator = 10000,
+			.denominator = 250000,
+			},
+	//	.link_freq_value = TP9951_LINK_FREQ_594M,
+	 .link_freq_value = TP9951_LINK_FREQ_297M,
+	 .common_reg_list = NULL,
+	 .common_reg_size = 0,
+	 .bpp = TP9951_BITS_PER_SAMPLE,
+	 .lane = TP9951_LANES,
+	 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,
+	 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_2,
+	 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_3,
+	},
+#endif
+#if TP9951_DEF_720P
+	{
+	 .bus_fmt = MEDIA_BUS_FMT_UYVY8_2X8,
+	 .width = 1280,
+	 .height = 720,
+	 .max_fps = {
+			.numerator = 10000,
+			.denominator = 250000,
+			},
+	 .link_freq_value = TP9951_LINK_FREQ_297M,
+	 .common_reg_list = NULL,
+	 .common_reg_size = 0,
+	 .bpp = TP9951_BITS_PER_SAMPLE,
+	 .lane = TP9951_LANES,
+	 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+	 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,
+	 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_2,
+	 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_3,
+	},
+#endif
+};
+
+int tp9951_initialize(struct techpoint *techpoint)
+{
+	int array_size = 0;
+	struct i2c_client *client = techpoint->client;
+	struct device *dev = &client->dev;
+
+	techpoint->video_modes_num = ARRAY_SIZE(supported_modes);
+	array_size =
+		sizeof(struct techpoint_video_modes) * techpoint->video_modes_num;
+	techpoint->video_modes = devm_kzalloc(dev, array_size, GFP_KERNEL);
+	memcpy(techpoint->video_modes, supported_modes, array_size);
+
+	techpoint->cur_video_mode = &techpoint->video_modes[0];
+
+	return 0;
+}
+
+int tp9951_get_channel_input_status(struct techpoint *techpoint, u8 ch)
+{
+	u8 val = 0;
+	struct i2c_client *client = techpoint->client;
+
+	if (ch != 0)	// tp9951 just support 1 chn
+		return 0;
+	techpoint_write_reg(client, PAGE_REG, ch);
+	techpoint_read_reg(client, INPUT_STATUS_REG, &val);
+	dev_dbg(&client->dev, "input_status ch %d : %x\n", ch, val);
+
+	return (val & INPUT_STATUS_MASK) ? 0 : 1;
+}
+
+int tp9951_get_all_input_status(struct techpoint *techpoint, u8 *detect_status)
+{
+	u8 val = 0;
+	struct i2c_client *client = techpoint->client;
+
+	// tp9951 just support 1 chn
+	techpoint_write_reg(client, PAGE_REG, 0);
+	techpoint_read_reg(client, INPUT_STATUS_REG, &val);
+	detect_status[0] = tp9951_get_channel_input_status(techpoint, 0);
+	return 0;
+}
+
+static void tp9951_set_mipi_out(struct i2c_client *client,
+								enum techpoint_support_reso reso,
+								unsigned char lane)
+{
+	u8 tmp;
+	//mipi setting
+	techpoint_write_reg(client, 0x40, 0x08); //select MIPI page
+	techpoint_write_reg(client, 0x02, 0x7d);
+	techpoint_write_reg(client, 0x03, 0x75);
+	techpoint_write_reg(client, 0x04, 0x75);
+	techpoint_write_reg(client, 0x13, 0xef);
+	techpoint_write_reg(client, 0x20, 0x00);
+	techpoint_write_reg(client, 0x23, 0x9e);
+
+	if (lane == MIPI_1LANE) {
+		techpoint_write_reg(client, 0x21, 0x11);
+
+		if (TECHPOINT_S_RESO_1080P_30 == reso || TECHPOINT_S_RESO_1080P_25 == reso) {
+			techpoint_write_reg(client, 0x12, 0x54);
+			techpoint_write_reg(client, 0x14, 0x00);
+			techpoint_write_reg(client, 0x15, 0x02);
+
+			techpoint_write_reg(client, 0x2a, 0x08);
+			techpoint_write_reg(client, 0x2b, 0x06);
+			techpoint_write_reg(client, 0x2c, 0x12);
+			techpoint_write_reg(client, 0x2e, 0x0a);
+		} else if (TECHPOINT_S_RESO_720P_30 == reso || TECHPOINT_S_RESO_720P_25 == reso) {
+			techpoint_write_reg(client, 0x12, 0x54);
+			techpoint_write_reg(client, 0x14, 0x00);
+			techpoint_write_reg(client, 0x15, 0x12);
+
+			techpoint_write_reg(client, 0x2a, 0x04);
+			techpoint_write_reg(client, 0x2b, 0x03);
+			techpoint_write_reg(client, 0x2c, 0x0a);
+			techpoint_write_reg(client, 0x2e, 0x02);
+		} else if (TECHPOINT_S_RESO_NTSC == reso || TECHPOINT_S_RESO_PAL == reso) {
+			techpoint_write_reg(client, 0x12, 0x54);
+			techpoint_write_reg(client, 0x14, 0x51);
+			techpoint_write_reg(client, 0x15, 0x07);
+
+			techpoint_write_reg(client, 0x2a, 0x02);
+			techpoint_write_reg(client, 0x2b, 0x01);
+			techpoint_write_reg(client, 0x2c, 0x06);
+			techpoint_write_reg(client, 0x2e, 0x02);
+		}
+	} else {	// 2 lane
+		techpoint_write_reg(client, 0x21, 0x12);
+
+		if (TECHPOINT_S_RESO_1080P_30 == reso || TECHPOINT_S_RESO_1080P_25 == reso) {
+			techpoint_write_reg(client, 0x12, 0x54);
+			techpoint_write_reg(client, 0x14, 0x41);
+			techpoint_write_reg(client, 0x15, 0x02);
+
+			techpoint_write_reg(client, 0x2a, 0x04);
+			techpoint_write_reg(client, 0x2b, 0x03);
+			techpoint_write_reg(client, 0x2c, 0x0a);
+			techpoint_write_reg(client, 0x2e, 0x02);
+		} else if (TECHPOINT_S_RESO_720P_30 == reso || TECHPOINT_S_RESO_720P_25 == reso) {
+			techpoint_write_reg(client, 0x12, 0x54);
+			techpoint_write_reg(client, 0x14, 0x41);
+			techpoint_write_reg(client, 0x15, 0x12);
+
+			techpoint_write_reg(client, 0x2a, 0x02);
+			techpoint_write_reg(client, 0x2b, 0x01);
+			techpoint_write_reg(client, 0x2c, 0x06);
+			techpoint_write_reg(client, 0x2e, 0x02);
+		} else if (TECHPOINT_S_RESO_NTSC == reso || TECHPOINT_S_RESO_PAL == reso) {
+			techpoint_write_reg(client, 0x12, 0x54);
+			techpoint_write_reg(client, 0x14, 0x62);
+			techpoint_write_reg(client, 0x15, 0x07);
+
+			techpoint_write_reg(client, 0x2a, 0x02);
+			techpoint_write_reg(client, 0x2b, 0x00);
+			techpoint_write_reg(client, 0x2c, 0x04);
+			techpoint_write_reg(client, 0x2e, 0x02);
+		}
+	}
+
+	techpoint_write_reg(client, 0x40, 0x00); //back to decoder page
+	techpoint_read_reg(client, 0x06, &tmp); //PLL reset
+	techpoint_write_reg(client, 0x06, 0x80 | tmp);
+
+	techpoint_write_reg(client, 0x40, 0x08); //back to mipi page
+
+	techpoint_read_reg(client, 0x14, &tmp); //PLL reset
+	techpoint_write_reg(client, 0x14, 0x80 | tmp);
+	techpoint_write_reg(client, 0x14, tmp);
+
+	/* Enable MIPI CSI2 output */
+	techpoint_write_reg(client, 0x28, 0x02);	 //stream off
+	techpoint_write_reg(client, 0x28, 0x00);	 //stream on
+	techpoint_write_reg(client, 0x40, 0x00);	 //back to decoder page
+}
+
+int tp9951_set_channel_reso(struct i2c_client *client, int ch,
+				enum techpoint_support_reso reso)
+{
+	int val = reso;
+
+	dev_info(&client->dev, "##$$ %s", __func__);
+	techpoint_write_reg(client, 0x40, 0x00);	 //select decoder page
+	techpoint_write_reg(client, 0x06, 0x12);	 //default value
+	techpoint_write_reg(client, 0x42, 0x00);	 //common setting for all format
+	techpoint_write_reg(client, 0x4e, 0x00);	 //common setting for MIPI output
+	techpoint_write_reg(client, 0x54, 0x00);	 //common setting for MIPI output
+	techpoint_write_reg(client, 0x41, ch);		 //video MUX select
+
+	switch (val) {
+	case TECHPOINT_S_RESO_720P_25:
+#if TP9951_DEF_720P
+	default:
+#endif
+		dev_err(&client->dev, "set channel 720P_25\n");
+		techpoint_write_reg(client, 0x02, 0x42);
+		techpoint_write_reg(client, 0x07, 0xc0);
+		techpoint_write_reg(client, 0x0b, 0xc0);
+		techpoint_write_reg(client, 0x0c, 0x13);
+		techpoint_write_reg(client, 0x0d, 0x50);
+
+		techpoint_write_reg(client, 0x15, 0x13);
+		techpoint_write_reg(client, 0x16, 0x15);
+		techpoint_write_reg(client, 0x17, 0x00);
+		techpoint_write_reg(client, 0x18, 0x19);
+		techpoint_write_reg(client, 0x19, 0xd0);
+		techpoint_write_reg(client, 0x1a, 0x25);
+		techpoint_write_reg(client, 0x1c, 0x07);//1280*720, 25fps
+		techpoint_write_reg(client, 0x1d, 0xbc);//1280*720, 25fps
+
+		techpoint_write_reg(client, 0x20, 0x30);
+		techpoint_write_reg(client, 0x21, 0x84);
+		techpoint_write_reg(client, 0x22, 0x36);
+		techpoint_write_reg(client, 0x23, 0x3c);
+
+		techpoint_write_reg(client, 0x2b, 0x60);
+		techpoint_write_reg(client, 0x2c, 0x2a);
+		techpoint_write_reg(client, 0x2d, 0x30);
+		techpoint_write_reg(client, 0x2e, 0x70);
+
+		techpoint_write_reg(client, 0x30, 0x48);
+		techpoint_write_reg(client, 0x31, 0xbb);
+		techpoint_write_reg(client, 0x32, 0x2e);
+		techpoint_write_reg(client, 0x33, 0x90);
+		techpoint_write_reg(client, 0x35, 0x25);
+		techpoint_write_reg(client, 0x38, 0x00);
+		techpoint_write_reg(client, 0x39, 0x18);
+		if (STD_HDA) {
+			techpoint_write_reg(client, 0x02, 0x46);
+			techpoint_write_reg(client, 0x0d, 0x71);
+			techpoint_write_reg(client, 0x18, 0x1b);
+			techpoint_write_reg(client, 0x20, 0x40);
+			techpoint_write_reg(client, 0x21, 0x46);
+			techpoint_write_reg(client, 0x25, 0xfe);
+			techpoint_write_reg(client, 0x26, 0x01);
+			techpoint_write_reg(client, 0x2c, 0x3a);
+			techpoint_write_reg(client, 0x2d, 0x5a);
+			techpoint_write_reg(client, 0x2e, 0x40);
+			techpoint_write_reg(client, 0x30, 0x9e);
+			techpoint_write_reg(client, 0x31, 0x20);
+			techpoint_write_reg(client, 0x32, 0x10);
+			techpoint_write_reg(client, 0x33, 0x90);
+		}
+
+		tp9951_set_mipi_out(client, reso, MIPI_2LANE);	// 2 lane
+
+		break;
+	case TECHPOINT_S_RESO_1080P_25:		// FHD25
+#if TP9951_DEF_1080P
+	default:
+#endif
+		dev_err(&client->dev, "set channel 1080P_25\n");
+		techpoint_write_reg(client, 0x02, 0x40);
+		techpoint_write_reg(client, 0x07, 0xc0);
+		techpoint_write_reg(client, 0x0b, 0xc0);
+		techpoint_write_reg(client, 0x0c, 0x03);
+		techpoint_write_reg(client, 0x0d, 0x50);
+
+		techpoint_write_reg(client, 0x15, 0x03);
+		techpoint_write_reg(client, 0x16, 0xd2);
+		techpoint_write_reg(client, 0x17, 0x80);
+		techpoint_write_reg(client, 0x18, 0x29);
+		techpoint_write_reg(client, 0x19, 0x38);
+		techpoint_write_reg(client, 0x1a, 0x47);
+		techpoint_write_reg(client, 0x1c, 0x0a);//1920*1080, 25fps
+		techpoint_write_reg(client, 0x1d, 0x50);//
+
+		techpoint_write_reg(client, 0x20, 0x30);
+		techpoint_write_reg(client, 0x21, 0x84);
+		techpoint_write_reg(client, 0x22, 0x36);
+		techpoint_write_reg(client, 0x23, 0x3c);
+
+		techpoint_write_reg(client, 0x2b, 0x60);
+		techpoint_write_reg(client, 0x2c, 0x2a);
+		techpoint_write_reg(client, 0x2d, 0x30);
+		techpoint_write_reg(client, 0x2e, 0x70);
+
+		techpoint_write_reg(client, 0x30, 0x48);
+		techpoint_write_reg(client, 0x31, 0xbb);
+		techpoint_write_reg(client, 0x32, 0x2e);
+		techpoint_write_reg(client, 0x33, 0x90);
+		techpoint_write_reg(client, 0x35, 0x05);
+		techpoint_write_reg(client, 0x38, 0x00);
+		techpoint_write_reg(client, 0x39, 0x1C);
+		if (STD_HDA) {
+			techpoint_write_reg(client, 0x02, 0x44);
+			techpoint_write_reg(client, 0x0d, 0x73);
+			techpoint_write_reg(client, 0x15, 0x01);
+			techpoint_write_reg(client, 0x16, 0xf0);
+			techpoint_write_reg(client, 0x18, 0x2a);
+			techpoint_write_reg(client, 0x20, 0x3c);
+			techpoint_write_reg(client, 0x21, 0x46);
+			techpoint_write_reg(client, 0x25, 0xfe);
+			techpoint_write_reg(client, 0x26, 0x0d);
+			techpoint_write_reg(client, 0x2c, 0x3a);
+			techpoint_write_reg(client, 0x2d, 0x54);
+			techpoint_write_reg(client, 0x2e, 0x40);
+			techpoint_write_reg(client, 0x30, 0xa5);
+			techpoint_write_reg(client, 0x31, 0x86);
+			techpoint_write_reg(client, 0x32, 0xfb);
+			techpoint_write_reg(client, 0x33, 0x60);
+		}
+
+		tp9951_set_mipi_out(client, reso, MIPI_2LANE);	// 2 lane
+
+		break;
+	case TECHPOINT_S_RESO_1080P_30:		// FHD30
+		dev_err(&client->dev, "set channel PAL\n");
+			techpoint_write_reg(client, 0x02, 0x40);
+			techpoint_write_reg(client, 0x07, 0xc0);
+			techpoint_write_reg(client, 0x0b, 0xc0);
+			techpoint_write_reg(client, 0x0c, 0x03);
+			techpoint_write_reg(client, 0x0d, 0x50);
+
+			techpoint_write_reg(client, 0x15, 0x03);
+			techpoint_write_reg(client, 0x16, 0xd2);
+			techpoint_write_reg(client, 0x17, 0x80);
+			techpoint_write_reg(client, 0x18, 0x29);
+			techpoint_write_reg(client, 0x19, 0x38);
+			techpoint_write_reg(client, 0x1a, 0x47);
+			techpoint_write_reg(client, 0x1c, 0x08);  //1920*1080, 30fps
+			techpoint_write_reg(client, 0x1d, 0x98);  //
+
+			techpoint_write_reg(client, 0x20, 0x30);
+			techpoint_write_reg(client, 0x21, 0x84);
+			techpoint_write_reg(client, 0x22, 0x36);
+			techpoint_write_reg(client, 0x23, 0x3c);
+
+			techpoint_write_reg(client, 0x2b, 0x60);
+			techpoint_write_reg(client, 0x2c, 0x2a);
+			techpoint_write_reg(client, 0x2d, 0x30);
+			techpoint_write_reg(client, 0x2e, 0x70);
+
+			techpoint_write_reg(client, 0x30, 0x48);
+			techpoint_write_reg(client, 0x31, 0xbb);
+			techpoint_write_reg(client, 0x32, 0x2e);
+			techpoint_write_reg(client, 0x33, 0x90);
+
+			techpoint_write_reg(client, 0x35, 0x05);
+			techpoint_write_reg(client, 0x38, 0x00);
+			techpoint_write_reg(client, 0x39, 0x1C);
+
+			if (STD_HDA) { //AHD1080p30 extra
+				techpoint_write_reg(client, 0x02, 0x44);
+				techpoint_write_reg(client, 0x0d, 0x72);
+
+				techpoint_write_reg(client, 0x15, 0x01);
+				techpoint_write_reg(client, 0x16, 0xf0);
+				techpoint_write_reg(client, 0x18, 0x2a);
+
+				techpoint_write_reg(client, 0x20, 0x38);
+				techpoint_write_reg(client, 0x21, 0x46);
+
+				techpoint_write_reg(client, 0x25, 0xfe);
+				techpoint_write_reg(client, 0x26, 0x0d);
+
+				techpoint_write_reg(client, 0x2c, 0x3a);
+				techpoint_write_reg(client, 0x2d, 0x54);
+				techpoint_write_reg(client, 0x2e, 0x40);
+
+				techpoint_write_reg(client, 0x30, 0xa5);
+				techpoint_write_reg(client, 0x31, 0x95);
+				techpoint_write_reg(client, 0x32, 0xe0);
+				techpoint_write_reg(client, 0x33, 0x60);
+			}
+
+			tp9951_set_mipi_out(client, reso, MIPI_2LANE);	// 2 lane
+	break;
+
+	case TECHPOINT_S_RESO_PAL:
+#if TP9951_DEF_PAL
+	default:
+#endif
+
+#if CVBS_960H
+		dev_err(&client->dev, "set channel CVBS_960H\n");
+
+		techpoint_write_reg(client, 0x02, 0x47);
+		techpoint_write_reg(client, 0x0c, 0x13);
+		techpoint_write_reg(client, 0x0d, 0x51);
+
+		techpoint_write_reg(client, 0x15, 0x13);
+		techpoint_write_reg(client, 0x16, 0x76);
+		techpoint_write_reg(client, 0x17, 0x80);
+		techpoint_write_reg(client, 0x18, 0x17);
+		techpoint_write_reg(client, 0x19, 0x20);
+		techpoint_write_reg(client, 0x1a, 0x17);
+		techpoint_write_reg(client, 0x1c, 0x09);
+		techpoint_write_reg(client, 0x1d, 0x48);
+
+		techpoint_write_reg(client, 0x20, 0x48);
+		techpoint_write_reg(client, 0x21, 0x84);
+		techpoint_write_reg(client, 0x22, 0x37);
+		techpoint_write_reg(client, 0x23, 0x3f);
+
+		techpoint_write_reg(client, 0x2b, 0x70);
+		techpoint_write_reg(client, 0x2c, 0x2a);
+		techpoint_write_reg(client, 0x2d, 0x64);
+		techpoint_write_reg(client, 0x2e, 0x56);
+
+		techpoint_write_reg(client, 0x30, 0x7a);
+		techpoint_write_reg(client, 0x31, 0x4a);
+		techpoint_write_reg(client, 0x32, 0x4d);
+		techpoint_write_reg(client, 0x33, 0xf0);
+
+		techpoint_write_reg(client, 0x35, 0x65);
+		techpoint_write_reg(client, 0x38, 0x00);
+		techpoint_write_reg(client, 0x39, 0x04);
+
+#else	 //PAL 720H
+		dev_err(&client->dev, "set channel PAL 720H\n");
+		techpoint_write_reg(client, 0x02, 0x47);
+		techpoint_write_reg(client, 0x06, 0x32);
+		techpoint_write_reg(client, 0x0c, 0x13);
+		techpoint_write_reg(client, 0x0d, 0x51);
+
+		techpoint_write_reg(client, 0x15, 0x03);
+		techpoint_write_reg(client, 0x16, 0xf0);
+		techpoint_write_reg(client, 0x17, 0xa0);
+		techpoint_write_reg(client, 0x18, 0x17);
+		techpoint_write_reg(client, 0x19, 0x20);
+		techpoint_write_reg(client, 0x1a, 0x15);
+		techpoint_write_reg(client, 0x1c, 0x06);
+		techpoint_write_reg(client, 0x1d, 0xc0);
+
+		techpoint_write_reg(client, 0x20, 0x48);
+		techpoint_write_reg(client, 0x21, 0x84);
+		techpoint_write_reg(client, 0x22, 0x37);
+		techpoint_write_reg(client, 0x23, 0x3f);
+
+		techpoint_write_reg(client, 0x2b, 0x70);
+		techpoint_write_reg(client, 0x2c, 0x2a);
+		techpoint_write_reg(client, 0x2d, 0x4b);
+		techpoint_write_reg(client, 0x2e, 0x56);
+
+		techpoint_write_reg(client, 0x30, 0x7a);
+		techpoint_write_reg(client, 0x31, 0x4a);
+		techpoint_write_reg(client, 0x32, 0x4d);
+		techpoint_write_reg(client, 0x33, 0xfb);
+
+		techpoint_write_reg(client, 0x35, 0x65);
+		techpoint_write_reg(client, 0x38, 0x00);
+		techpoint_write_reg(client, 0x39, 0x04);
+#endif
+		tp9951_set_mipi_out(client, reso, MIPI_2LANE);	// 2 lane
+
+		break;
+	case TECHPOINT_S_RESO_NTSC:
+#if TP9951_DEF_NTSC
+	default:
+#endif
+
+#if CVBS_960H
+		dev_err(&client->dev, "set channel NTSC CVBS_960H\n");
+		techpoint_write_reg(client, 0x02, 0x47);
+		techpoint_write_reg(client, 0x0c, 0x13);
+		techpoint_write_reg(client, 0x0d, 0x50);
+
+		techpoint_write_reg(client, 0x15, 0x13);
+		techpoint_write_reg(client, 0x16, 0x60);
+		techpoint_write_reg(client, 0x17, 0x80);
+		techpoint_write_reg(client, 0x18, 0x12);
+		techpoint_write_reg(client, 0x19, 0xf0);
+		techpoint_write_reg(client, 0x1a, 0x07);
+		techpoint_write_reg(client, 0x1c, 0x09);
+		techpoint_write_reg(client, 0x1d, 0x38);
+
+		techpoint_write_reg(client, 0x20, 0x40);
+		techpoint_write_reg(client, 0x21, 0x84);
+		techpoint_write_reg(client, 0x22, 0x36);
+		techpoint_write_reg(client, 0x23, 0x3c);
+
+		techpoint_write_reg(client, 0x2b, 0x70);
+		techpoint_write_reg(client, 0x2c, 0x2a);
+		techpoint_write_reg(client, 0x2d, 0x68);
+		techpoint_write_reg(client, 0x2e, 0x57);
+
+		techpoint_write_reg(client, 0x30, 0x62);
+		techpoint_write_reg(client, 0x31, 0xbb);
+		techpoint_write_reg(client, 0x32, 0x96);
+		techpoint_write_reg(client, 0x33, 0xc0);
+
+		techpoint_write_reg(client, 0x35, 0x65);
+		techpoint_write_reg(client, 0x38, 0x00);
+		techpoint_write_reg(client, 0x39, 0x04);
+#else
+		dev_err(&client->dev, "set channel NTSC 720H\n");
+		techpoint_write_reg(client, 0x02, 0x47);
+		techpoint_write_reg(client, 0x0c, 0x13);
+		techpoint_write_reg(client, 0x0d, 0x50);
+
+		techpoint_write_reg(client, 0x15, 0x03);
+		techpoint_write_reg(client, 0x16, 0xd6);
+		techpoint_write_reg(client, 0x17, 0xa0);
+		techpoint_write_reg(client, 0x18, 0x12);
+		techpoint_write_reg(client, 0x19, 0xf0);
+		techpoint_write_reg(client, 0x1a, 0x05);
+		techpoint_write_reg(client, 0x1c, 0x06);
+		techpoint_write_reg(client, 0x1d, 0xb4);
+
+		techpoint_write_reg(client, 0x20, 0x40);
+		techpoint_write_reg(client, 0x21, 0x84);
+		techpoint_write_reg(client, 0x22, 0x36);
+		techpoint_write_reg(client, 0x23, 0x3c);
+
+		techpoint_write_reg(client, 0x2b, 0x70);
+		techpoint_write_reg(client, 0x2c, 0x2a);
+		techpoint_write_reg(client, 0x2d, 0x4b);
+		techpoint_write_reg(client, 0x2e, 0x57);
+
+		techpoint_write_reg(client, 0x30, 0x62);
+		techpoint_write_reg(client, 0x31, 0xbb);
+		techpoint_write_reg(client, 0x32, 0x96);
+		techpoint_write_reg(client, 0x33, 0xcb);
+
+		techpoint_write_reg(client, 0x35, 0x65);
+		techpoint_write_reg(client, 0x38, 0x00);
+		techpoint_write_reg(client, 0x39, 0x04);
+#endif
+		break;
+	}
+
+#if TECHPOINT_TEST_PATTERN
+	techpoint_write_reg(client, 0x2a, 0x3c);
+#endif
+
+	return 0;
+}
+
+// detect for reference only, the accuracy may be affected by the current invoked decoding standard.
+int tp9951_get_channel_reso(struct i2c_client *client, int ch)
+{
+	u8 detect_fmt = 0xff;
+	u8 reso = 0xff;
+
+	techpoint_write_reg(client, 0x40, ch);
+	techpoint_read_reg(client, 0x03, &detect_fmt);
+	reso = detect_fmt & 0x7;
+
+	switch (reso) {
+	case TP9951_CVSTD_720P_25:
+#if TP9951_DEF_720P
+	default:
+#endif
+		dev_err(&client->dev, "detect channel %d 720P_25\n", ch);
+		return TECHPOINT_S_RESO_720P_25;
+	case TP9951_CVSTD_1080P_25:
+#if TP9951_DEF_1080P
+	default:
+#endif
+		dev_err(&client->dev, "detect channel %d 1080P_25\n", ch);
+		return TECHPOINT_S_RESO_1080P_25;
+	case TP9951_CVSTD_PAL:
+#if TP9951_DEF_PAL
+	default:
+#endif
+		dev_err(&client->dev, "detect channel %d PAL\n", ch);
+		return TECHPOINT_S_RESO_PAL;
+	case TP9951_CVSTD_NTSC:
+#if TP9951_DEF_NTSC
+	default:
+#endif
+		dev_err(&client->dev, "detect channel %d NTSC\n", ch);
+		return TECHPOINT_S_RESO_NTSC;
+	}
+
+	return reso;
+}
+
+int tp9951_set_quick_stream(struct i2c_client *client, u32 stream)
+{
+	// mutex_lock(&techpoint->mutex);
+	if (stream) {
+		techpoint_write_reg(client, 0x40, 0x8);
+		techpoint_write_reg(client, 0x28, 0x0);
+	} else {
+		techpoint_write_reg(client, 0x40, 0x8);
+		techpoint_write_reg(client, 0x28, 0x2);
+		usleep_range(40 * 1000, 50 * 1000);
+	}
+	// mutex_unlock(&techpoint->mutex);
+	return 0;
+}
diff --git a/kernel/drivers/media/i2c/techpoint/techpoint_tp9951.h b/kernel/drivers/media/i2c/techpoint/techpoint_tp9951.h
new file mode 100644
index 0000000..76cbda2
--- /dev/null
+++ b/kernel/drivers/media/i2c/techpoint/techpoint_tp9951.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * techpoint tp9951 regs
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef _TECHPOINT_TP9951_H
+#define _TECHPOINT_TP9951_H
+
+#include "techpoint_common.h"
+
+#define DEBUG
+
+#define TP9951_DEF_1080P 1
+#define TP9951_DEF_720P 0
+#define TP9951_DEF_PAL 0
+#define TP9951_DEF_NTSC 0
+
+#define STD_TVI 0
+#define STD_HDA 1
+
+// device id 0x2860
+#define TP9951_CHIP_ID_H_REG	  0xFE
+#define TP9951_CHIP_ID_H_VALUE	  0x28
+#define TP9951_CHIP_ID_L_REG	  0xFF
+#define TP9951_CHIP_ID_L_VALUE	  0x60
+
+#define TP9951_LINK_FREQ_148M		(148500000UL >> 1)
+#define TP9951_LINK_FREQ_297M		(297000000UL >> 1)
+#define TP9951_LINK_FREQ_594M		(594000000UL >> 1)
+#define TP9951_LANES				2
+#define TP9951_BITS_PER_SAMPLE		8
+
+enum tp9952_support_mipi_lane {
+	MIPI_2LANE,
+	MIPI_1LANE,
+};
+
+#define CVBS_960H					(0) //1->960H 0->720H
+
+enum tp9951_support_reso {
+	TP9951_CVSTD_720P_60 = 0,
+	TP9951_CVSTD_720P_50,
+	TP9951_CVSTD_1080P_30,
+	TP9951_CVSTD_1080P_25,
+	TP9951_CVSTD_720P_30,
+	TP9951_CVSTD_720P_25,
+	TP9951_CVSTD_SD,
+	TP9951_CVSTD_OTHER,
+	TP9951_CVSTD_720P_275,
+	TP9951_CVSTD_QHD30,	//960×540 only support with 2lane mode
+	TP9951_CVSTD_QHD25,	 //960×540 only support with 2lane mode
+	TP9951_CVSTD_PAL,
+	TP9951_CVSTD_NTSC,
+	TP9951_CVSTD_UVGA25,  //1280x960p25, must use with MIPI_4CH4LANE_445M
+	TP9951_CVSTD_UVGA30,  //1280x960p30, must use with MIPI_4CH4LANE_445M
+	TP9951_CVSTD_A_UVGA30,	//HDA 1280x960p30, must use with MIPI_4CH4LANE_378M
+	TP9951_CVSTD_F_UVGA30,	//FH 1280x960p30, 1800x1000
+	TP9951_CVSTD_HD30864, //total 1600x900 86.4M
+	TP9951_CVSTD_HD30HDR, //special 720p30 with ISX019/SC120AT,total 1650x900
+	TP9951_CVSTD_1080P_60,//only support with 2lane mode
+	TP9951_CVSTD_1080P_50,//only support with 2lane mode
+	TP9951_CVSTD_1080P_28,
+	TP9951_CVSTD_1080P_275,
+};
+
+int tp9951_initialize(struct techpoint *techpoint);
+int tp9951_get_channel_input_status(struct techpoint *techpoint, u8 ch);
+int tp9951_get_all_input_status(struct techpoint *techpoint, u8 *detect_status);
+int tp9951_set_channel_reso(struct i2c_client *client, int ch,
+				enum techpoint_support_reso reso);
+int tp9951_get_channel_reso(struct i2c_client *client, int ch);
+int tp9951_set_quick_stream(struct i2c_client *client, u32 stream);
+
+#endif // _TECHPOINT_TP9951_H
diff --git a/kernel/drivers/media/i2c/techpoint/techpoint_v4l2.c b/kernel/drivers/media/i2c/techpoint/techpoint_v4l2.c
index 82ef448..39f6a3b 100644
--- a/kernel/drivers/media/i2c/techpoint/techpoint_v4l2.c
+++ b/kernel/drivers/media/i2c/techpoint/techpoint_v4l2.c
@@ -860,6 +860,7 @@
 	{ .compatible = "techpoint,tp2815" },
 	{ .compatible = "techpoint,tp9930" },
 	{ .compatible = "techpoint,tp9950" },
+	{ .compatible = "techpoint,tp9951" },
 	{ },
 };
 
@@ -1297,7 +1298,6 @@
 	}
 
 	if (techpoint->chip_id == CHIP_TP9930) {
-
 		techpoint_write_reg(techpoint->client, 0x40, 0x00);
 		for (i = 0; i < 0xff; i++)
 			techpoint_write_reg(techpoint->client, i, 0xbb);
diff --git a/kernel/drivers/media/i2c/tvp5150.c b/kernel/drivers/media/i2c/tvp5150.c
index 3b3221f..cf0570a 100644
--- a/kernel/drivers/media/i2c/tvp5150.c
+++ b/kernel/drivers/media/i2c/tvp5150.c
@@ -2078,6 +2078,10 @@
 		tvpc->ent.name = devm_kasprintf(dev, GFP_KERNEL, "%s %s",
 						v4l2c->name, v4l2c->label ?
 						v4l2c->label : "");
+		if (!tvpc->ent.name) {
+			ret = -ENOMEM;
+			goto err_free;
+		}
 	}
 
 	ep_np = of_graph_get_endpoint_by_regs(np, TVP5150_PAD_VID_OUT, 0);
diff --git a/kernel/drivers/media/pci/bt8xx/dst.c b/kernel/drivers/media/pci/bt8xx/dst.c
index 3e52a51..110651e 100644
--- a/kernel/drivers/media/pci/bt8xx/dst.c
+++ b/kernel/drivers/media/pci/bt8xx/dst.c
@@ -1722,7 +1722,7 @@
 	return state;				/*	Manu (DST is a card not a frontend)	*/
 }
 
-EXPORT_SYMBOL(dst_attach);
+EXPORT_SYMBOL_GPL(dst_attach);
 
 static const struct dvb_frontend_ops dst_dvbt_ops = {
 	.delsys = { SYS_DVBT },
diff --git a/kernel/drivers/media/pci/bt8xx/dst_ca.c b/kernel/drivers/media/pci/bt8xx/dst_ca.c
index 85fcdc5..571392d 100644
--- a/kernel/drivers/media/pci/bt8xx/dst_ca.c
+++ b/kernel/drivers/media/pci/bt8xx/dst_ca.c
@@ -668,7 +668,7 @@
 	return NULL;
 }
 
-EXPORT_SYMBOL(dst_ca_attach);
+EXPORT_SYMBOL_GPL(dst_ca_attach);
 
 MODULE_DESCRIPTION("DST DVB-S/T/C Combo CA driver");
 MODULE_AUTHOR("Manu Abraham");
diff --git a/kernel/drivers/media/pci/cx23885/cx23885-dvb.c b/kernel/drivers/media/pci/cx23885/cx23885-dvb.c
index 45c2f4a..9b437fa 100644
--- a/kernel/drivers/media/pci/cx23885/cx23885-dvb.c
+++ b/kernel/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -2459,16 +2459,10 @@
 			request_module("%s", info.type);
 			client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
 			if (!i2c_client_has_driver(client_tuner)) {
-				module_put(client_demod->dev.driver->owner);
-				i2c_unregister_device(client_demod);
-				port->i2c_client_demod = NULL;
 				goto frontend_detach;
 			}
 			if (!try_module_get(client_tuner->dev.driver->owner)) {
 				i2c_unregister_device(client_tuner);
-				module_put(client_demod->dev.driver->owner);
-				i2c_unregister_device(client_demod);
-				port->i2c_client_demod = NULL;
 				goto frontend_detach;
 			}
 			port->i2c_client_tuner = client_tuner;
@@ -2505,16 +2499,10 @@
 			request_module("%s", info.type);
 			client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
 			if (!i2c_client_has_driver(client_tuner)) {
-				module_put(client_demod->dev.driver->owner);
-				i2c_unregister_device(client_demod);
-				port->i2c_client_demod = NULL;
 				goto frontend_detach;
 			}
 			if (!try_module_get(client_tuner->dev.driver->owner)) {
 				i2c_unregister_device(client_tuner);
-				module_put(client_demod->dev.driver->owner);
-				i2c_unregister_device(client_demod);
-				port->i2c_client_demod = NULL;
 				goto frontend_detach;
 			}
 			port->i2c_client_tuner = client_tuner;
diff --git a/kernel/drivers/media/pci/cx23885/cx23885-video.c b/kernel/drivers/media/pci/cx23885/cx23885-video.c
index a380e09..86e3bb5 100644
--- a/kernel/drivers/media/pci/cx23885/cx23885-video.c
+++ b/kernel/drivers/media/pci/cx23885/cx23885-video.c
@@ -412,7 +412,7 @@
 				dev->height >> 1);
 		break;
 	default:
-		BUG();
+		return -EINVAL; /* should not happen */
 	}
 	dprintk(2, "[%p/%d] buffer_init - %dx%d %dbpp 0x%08x - dma=0x%08lx\n",
 		buf, buf->vb.vb2_buf.index,
diff --git a/kernel/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c b/kernel/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c
index 6868a0c..520ebd1 100644
--- a/kernel/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c
+++ b/kernel/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c
@@ -112,7 +112,7 @@
 	state->frontend.demodulator_priv = state;
 	return &state->frontend;
 }
-EXPORT_SYMBOL(ddbridge_dummy_fe_qam_attach);
+EXPORT_SYMBOL_GPL(ddbridge_dummy_fe_qam_attach);
 
 static const struct dvb_frontend_ops ddbridge_dummy_fe_qam_ops = {
 	.delsys = { SYS_DVBC_ANNEX_A },
diff --git a/kernel/drivers/media/pci/dm1105/dm1105.c b/kernel/drivers/media/pci/dm1105/dm1105.c
index 9dce31d..d2e194a 100644
--- a/kernel/drivers/media/pci/dm1105/dm1105.c
+++ b/kernel/drivers/media/pci/dm1105/dm1105.c
@@ -1178,6 +1178,7 @@
 	struct dvb_demux *dvbdemux = &dev->demux;
 	struct dmx_demux *dmx = &dvbdemux->dmx;
 
+	cancel_work_sync(&dev->ir.work);
 	dm1105_ir_exit(dev);
 	dmx->close(dmx);
 	dvb_net_release(&dev->dvbnet);
diff --git a/kernel/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/kernel/drivers/media/pci/intel/ipu3/ipu3-cio2.c
index 2fe4a0b..f8dca47 100644
--- a/kernel/drivers/media/pci/intel/ipu3/ipu3-cio2.c
+++ b/kernel/drivers/media/pci/intel/ipu3/ipu3-cio2.c
@@ -355,7 +355,7 @@
 	void __iomem *const base = cio2->base;
 	u8 lanes, csi2bus = q->csi2.port;
 	u8 sensor_vc = SENSOR_VIR_CH_DFLT;
-	struct cio2_csi2_timing timing;
+	struct cio2_csi2_timing timing = { 0 };
 	int i, r;
 
 	fmt = cio2_find_format(NULL, &q->subdev_fmt.code);
@@ -1831,6 +1831,9 @@
 	v4l2_device_unregister(&cio2->v4l2_dev);
 	media_device_cleanup(&cio2->media_dev);
 	mutex_destroy(&cio2->lock);
+
+	pm_runtime_forbid(&pci_dev->dev);
+	pm_runtime_get_noresume(&pci_dev->dev);
 }
 
 static int __maybe_unused cio2_runtime_suspend(struct device *dev)
diff --git a/kernel/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/kernel/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
index 77bae14..7c50619 100644
--- a/kernel/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
+++ b/kernel/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
@@ -697,7 +697,7 @@
 	netup_unidvb_dma_enable(dma, 0);
 	msleep(50);
 	cancel_work_sync(&dma->work);
-	del_timer(&dma->timeout);
+	del_timer_sync(&dma->timeout);
 }
 
 static int netup_unidvb_dma_setup(struct netup_unidvb_dev *ndev)
@@ -887,12 +887,7 @@
 		ndev->lmmio0, (u32)pci_resource_len(pci_dev, 0),
 		ndev->lmmio1, (u32)pci_resource_len(pci_dev, 1),
 		pci_dev->irq);
-	if (request_irq(pci_dev->irq, netup_unidvb_isr, IRQF_SHARED,
-			"netup_unidvb", pci_dev) < 0) {
-		dev_err(&pci_dev->dev,
-			"%s(): can't get IRQ %d\n", __func__, pci_dev->irq);
-		goto irq_request_err;
-	}
+
 	ndev->dma_size = 2 * 188 *
 		NETUP_DMA_BLOCKS_COUNT * NETUP_DMA_PACKETS_COUNT;
 	ndev->dma_virt = dma_alloc_coherent(&pci_dev->dev,
@@ -933,6 +928,14 @@
 		dev_err(&pci_dev->dev, "netup_unidvb: DMA setup failed\n");
 		goto dma_setup_err;
 	}
+
+	if (request_irq(pci_dev->irq, netup_unidvb_isr, IRQF_SHARED,
+			"netup_unidvb", pci_dev) < 0) {
+		dev_err(&pci_dev->dev,
+			"%s(): can't get IRQ %d\n", __func__, pci_dev->irq);
+		goto dma_setup_err;
+	}
+
 	dev_info(&pci_dev->dev,
 		"netup_unidvb: device has been initialized\n");
 	return 0;
@@ -951,8 +954,6 @@
 	dma_free_coherent(&pci_dev->dev, ndev->dma_size,
 			ndev->dma_virt, ndev->dma_phys);
 dma_alloc_err:
-	free_irq(pci_dev->irq, pci_dev);
-irq_request_err:
 	iounmap(ndev->lmmio1);
 pci_bar1_error:
 	iounmap(ndev->lmmio0);
diff --git a/kernel/drivers/media/pci/saa7134/saa7134-core.c b/kernel/drivers/media/pci/saa7134/saa7134-core.c
index efb757d..e97c300 100644
--- a/kernel/drivers/media/pci/saa7134/saa7134-core.c
+++ b/kernel/drivers/media/pci/saa7134/saa7134-core.c
@@ -977,7 +977,7 @@
 	}
 	if (dev->radio_dev) {
 		if (video_is_registered(dev->radio_dev))
-			vb2_video_unregister_device(dev->radio_dev);
+			video_unregister_device(dev->radio_dev);
 		else
 			video_device_release(dev->radio_dev);
 		dev->radio_dev = NULL;
diff --git a/kernel/drivers/media/pci/saa7134/saa7134-ts.c b/kernel/drivers/media/pci/saa7134/saa7134-ts.c
index 6a50531..437dbe5 100644
--- a/kernel/drivers/media/pci/saa7134/saa7134-ts.c
+++ b/kernel/drivers/media/pci/saa7134/saa7134-ts.c
@@ -300,6 +300,7 @@
 
 int saa7134_ts_fini(struct saa7134_dev *dev)
 {
+	del_timer_sync(&dev->ts_q.timeout);
 	saa7134_pgtable_free(dev->pci, &dev->ts_q.pt);
 	return 0;
 }
diff --git a/kernel/drivers/media/pci/saa7134/saa7134-vbi.c b/kernel/drivers/media/pci/saa7134/saa7134-vbi.c
index 3f0b093..3e77369 100644
--- a/kernel/drivers/media/pci/saa7134/saa7134-vbi.c
+++ b/kernel/drivers/media/pci/saa7134/saa7134-vbi.c
@@ -185,6 +185,7 @@
 int saa7134_vbi_fini(struct saa7134_dev *dev)
 {
 	/* nothing */
+	del_timer_sync(&dev->vbi_q.timeout);
 	return 0;
 }
 
diff --git a/kernel/drivers/media/pci/saa7134/saa7134-video.c b/kernel/drivers/media/pci/saa7134/saa7134-video.c
index 9a6a6b6..2bf18a0 100644
--- a/kernel/drivers/media/pci/saa7134/saa7134-video.c
+++ b/kernel/drivers/media/pci/saa7134/saa7134-video.c
@@ -2153,6 +2153,7 @@
 
 void saa7134_video_fini(struct saa7134_dev *dev)
 {
+	del_timer_sync(&dev->video_q.timeout);
 	/* free stuff */
 	saa7134_pgtable_free(dev->pci, &dev->video_q.pt);
 	saa7134_pgtable_free(dev->pci, &dev->vbi_q.pt);
diff --git a/kernel/drivers/media/pci/saa7164/saa7164-core.c b/kernel/drivers/media/pci/saa7164/saa7164-core.c
index 6c08b77..3cadfbe 100644
--- a/kernel/drivers/media/pci/saa7164/saa7164-core.c
+++ b/kernel/drivers/media/pci/saa7164/saa7164-core.c
@@ -1270,7 +1270,7 @@
 
 	if (saa7164_dev_setup(dev) < 0) {
 		err = -EINVAL;
-		goto fail_free;
+		goto fail_dev;
 	}
 
 	/* print pci info */
@@ -1438,6 +1438,8 @@
 
 fail_irq:
 	saa7164_dev_unregister(dev);
+fail_dev:
+	pci_disable_device(pci_dev);
 fail_free:
 	v4l2_device_unregister(&dev->v4l2_dev);
 	kfree(dev);
diff --git a/kernel/drivers/media/pci/solo6x10/solo6x10-core.c b/kernel/drivers/media/pci/solo6x10/solo6x10-core.c
index d497afc..4ebb1e0 100644
--- a/kernel/drivers/media/pci/solo6x10/solo6x10-core.c
+++ b/kernel/drivers/media/pci/solo6x10/solo6x10-core.c
@@ -420,6 +420,7 @@
 		     solo_dev->nr_chans);
 
 	if (device_register(dev)) {
+		put_device(dev);
 		dev->parent = NULL;
 		return -ENOMEM;
 	}
diff --git a/kernel/drivers/media/platform/coda/coda-bit.c b/kernel/drivers/media/platform/coda/coda-bit.c
index 159c9de..6ffa12e 100644
--- a/kernel/drivers/media/platform/coda/coda-bit.c
+++ b/kernel/drivers/media/platform/coda/coda-bit.c
@@ -852,7 +852,7 @@
 		/* 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 @@
 
 		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;
 
@@ -1082,10 +1082,16 @@
 	}
 
 	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);
 	}
 
diff --git a/kernel/drivers/media/platform/coda/coda-jpeg.c b/kernel/drivers/media/platform/coda/coda-jpeg.c
index a72f465..b7bf529 100644
--- a/kernel/drivers/media/platform/coda/coda-jpeg.c
+++ b/kernel/drivers/media/platform/coda/coda-jpeg.c
@@ -1052,10 +1052,16 @@
 		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;
diff --git a/kernel/drivers/media/platform/exynos4-is/fimc-core.c b/kernel/drivers/media/platform/exynos4-is/fimc-core.c
index 08d1f39..60b28e6 100644
--- a/kernel/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/kernel/drivers/media/platform/exynos4-is/fimc-core.c
@@ -1174,7 +1174,7 @@
 	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/kernel/drivers/media/platform/exynos4-is/media-dev.c b/kernel/drivers/media/platform/exynos4-is/media-dev.c
index a9a8f04..bd37011 100644
--- a/kernel/drivers/media/platform/exynos4-is/media-dev.c
+++ b/kernel/drivers/media/platform/exynos4-is/media-dev.c
@@ -401,6 +401,7 @@
 	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 @@
 	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 @@
 	 * 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 @@
 	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,8 +1378,7 @@
 
 	/* Find platform data for this sensor subdev */
 	for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
-		if (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)
@@ -1470,7 +1470,7 @@
 	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;
 	}
@@ -1582,7 +1582,11 @@
 	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)
diff --git a/kernel/drivers/media/platform/exynos4-is/media-dev.h b/kernel/drivers/media/platform/exynos4-is/media-dev.h
index 9447faf..a3876d6 100644
--- a/kernel/drivers/media/platform/exynos4-is/media-dev.h
+++ b/kernel/drivers/media/platform/exynos4-is/media-dev.h
@@ -83,7 +83,7 @@
  */
 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;
 };
diff --git a/kernel/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/kernel/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index 21de143..2c2be43 100644
--- a/kernel/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/kernel/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -729,6 +729,8 @@
 		return -EINVAL;
 
 	if (*nplanes) {
+		if (*nplanes != q_data->fmt->num_planes)
+			return -EINVAL;
 		for (i = 0; i < *nplanes; i++)
 			if (sizes[i] < q_data->sizeimage[i])
 				return -EINVAL;
diff --git a/kernel/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c b/kernel/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
index d988021..43c108b 100644
--- a/kernel/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
+++ b/kernel/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
@@ -226,10 +226,11 @@
 		if (fb->base_y.va == addr) {
 			list_move_tail(&node->list,
 				       &inst->available_fb_node_list);
-			break;
+			return fb;
 		}
 	}
-	return fb;
+
+	return NULL;
 }
 
 static void vp9_add_to_fb_free_list(struct vdec_vp9_inst *inst,
diff --git a/kernel/drivers/media/platform/mtk-vpu/mtk_vpu.c b/kernel/drivers/media/platform/mtk-vpu/mtk_vpu.c
index c62eb21..e7c4b0d 100644
--- a/kernel/drivers/media/platform/mtk-vpu/mtk_vpu.c
+++ b/kernel/drivers/media/platform/mtk-vpu/mtk_vpu.c
@@ -539,15 +539,17 @@
 int vpu_load_firmware(struct platform_device *pdev)
 {
 	struct mtk_vpu *vpu;
-	struct device *dev = &pdev->dev;
+	struct device *dev;
 	struct vpu_run *run;
 	int ret;
 
 	if (!pdev) {
-		dev_err(dev, "VPU platform device is invalid\n");
+		pr_err("VPU platform device is invalid\n");
 		return -EINVAL;
 	}
 
+	dev = &pdev->dev;
+
 	vpu = platform_get_drvdata(pdev);
 	run = &vpu->run;
 
diff --git a/kernel/drivers/media/platform/omap3isp/isp.c b/kernel/drivers/media/platform/omap3isp/isp.c
index 1311b49..21c1669 100644
--- a/kernel/drivers/media/platform/omap3isp/isp.c
+++ b/kernel/drivers/media/platform/omap3isp/isp.c
@@ -2297,7 +2297,16 @@
 
 	/* Regulators */
 	isp->isp_csiphy1.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy1");
+	if (IS_ERR(isp->isp_csiphy1.vdd)) {
+		ret = PTR_ERR(isp->isp_csiphy1.vdd);
+		goto error;
+	}
+
 	isp->isp_csiphy2.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy2");
+	if (IS_ERR(isp->isp_csiphy2.vdd)) {
+		ret = PTR_ERR(isp->isp_csiphy2.vdd);
+		goto error;
+	}
 
 	/* Clocks
 	 *
diff --git a/kernel/drivers/media/platform/qcom/camss/camss-video.c b/kernel/drivers/media/platform/qcom/camss/camss-video.c
index 15965e6..9333a7a 100644
--- a/kernel/drivers/media/platform/qcom/camss/camss-video.c
+++ b/kernel/drivers/media/platform/qcom/camss/camss-video.c
@@ -444,7 +444,7 @@
 
 	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 @@
 error:
 	media_pipeline_stop(&vdev->entity);
 
+flush_buffers:
 	video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED);
 
 	return ret;
diff --git a/kernel/drivers/media/platform/qcom/venus/core.c b/kernel/drivers/media/platform/qcom/venus/core.c
index 62d11c6..5f7ac28 100644
--- a/kernel/drivers/media/platform/qcom/venus/core.c
+++ b/kernel/drivers/media/platform/qcom/venus/core.c
@@ -21,6 +21,7 @@
 #include "core.h"
 #include "firmware.h"
 #include "pm_helpers.h"
+#include "hfi_venus_io.h"
 
 static void venus_event_notify(struct venus_core *core, u32 event)
 {
@@ -210,6 +211,15 @@
 	return ret;
 }
 
+static void venus_assign_register_offsets(struct venus_core *core)
+{
+	core->vbif_base = core->base + VBIF_BASE;
+	core->cpu_base = core->base + CPU_BASE;
+	core->cpu_cs_base = core->base + CPU_CS_BASE;
+	core->cpu_ic_base = core->base + CPU_IC_BASE;
+	core->wrapper_base = core->base + WRAPPER_BASE;
+}
+
 static int venus_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -276,6 +286,8 @@
 	if (ret)
 		goto err_core_put;
 
+	venus_assign_register_offsets(core);
+
 	ret = v4l2_device_register(dev, &core->v4l2_dev);
 	if (ret)
 		goto err_core_deinit;
diff --git a/kernel/drivers/media/platform/qcom/venus/core.h b/kernel/drivers/media/platform/qcom/venus/core.h
index f2a0ef9..75d0068 100644
--- a/kernel/drivers/media/platform/qcom/venus/core.h
+++ b/kernel/drivers/media/platform/qcom/venus/core.h
@@ -119,6 +119,11 @@
  * struct venus_core - holds core parameters valid for all instances
  *
  * @base:	IO memory base address
+ * @vbif_base	IO memory vbif base address
+ * @cpu_base	IO memory cpu base address
+ * @cpu_cs_base	IO memory cpu_cs base address
+ * @cpu_ic_base	IO memory cpu_ic base address
+ * @wrapper_base	IO memory wrapper base address
  * @irq:		Venus irq
  * @clks:	an array of struct clk pointers
  * @vcodec0_clks: an array of vcodec0 struct clk pointers
@@ -152,6 +157,11 @@
  */
 struct venus_core {
 	void __iomem *base;
+	void __iomem *vbif_base;
+	void __iomem *cpu_base;
+	void __iomem *cpu_cs_base;
+	void __iomem *cpu_ic_base;
+	void __iomem *wrapper_base;
 	int irq;
 	struct clk *clks[VIDC_CLKS_NUM_MAX];
 	struct clk *vcodec0_clks[VIDC_VCODEC_CLKS_NUM_MAX];
@@ -283,7 +293,6 @@
 	VENUS_DEC_STATE_DRAIN		= 5,
 	VENUS_DEC_STATE_DECODING	= 6,
 	VENUS_DEC_STATE_DRC		= 7,
-	VENUS_DEC_STATE_DRC_FLUSH_DONE	= 8,
 };
 
 struct venus_ts_metadata {
@@ -348,7 +357,7 @@
  * @priv:	a private for HFI operations callbacks
  * @session_type:	the type of the session (decoder or encoder)
  * @hprop:	a union used as a holder by get property
- * @last_buf:	last capture buffer for dynamic-resoluton-change
+ * @next_buf_last: a flag to mark next queued capture buffer as last
  */
 struct venus_inst {
 	struct list_head list;
@@ -410,12 +419,14 @@
 	union hfi_get_property hprop;
 	unsigned int core_acquired: 1;
 	unsigned int bit_depth;
-	struct vb2_buffer *last_buf;
+	bool next_buf_last;
+	bool drain_active;
 };
 
 #define IS_V1(core)	((core)->res->hfi_version == HFI_VERSION_1XX)
 #define IS_V3(core)	((core)->res->hfi_version == HFI_VERSION_3XX)
 #define IS_V4(core)	((core)->res->hfi_version == HFI_VERSION_4XX)
+#define IS_V6(core)	((core)->res->hfi_version == HFI_VERSION_6XX)
 
 #define ctrl_to_inst(ctrl)	\
 	container_of((ctrl)->handler, struct venus_inst, ctrl_handler)
diff --git a/kernel/drivers/media/platform/qcom/venus/firmware.c b/kernel/drivers/media/platform/qcom/venus/firmware.c
index 1db64a8..67b9138 100644
--- a/kernel/drivers/media/platform/qcom/venus/firmware.c
+++ b/kernel/drivers/media/platform/qcom/venus/firmware.c
@@ -27,19 +27,19 @@
 static void venus_reset_cpu(struct venus_core *core)
 {
 	u32 fw_size = core->fw.mapped_mem_size;
-	void __iomem *base = core->base;
+	void __iomem *wrapper_base = core->wrapper_base;
 
-	writel(0, base + WRAPPER_FW_START_ADDR);
-	writel(fw_size, base + WRAPPER_FW_END_ADDR);
-	writel(0, base + WRAPPER_CPA_START_ADDR);
-	writel(fw_size, base + WRAPPER_CPA_END_ADDR);
-	writel(fw_size, base + WRAPPER_NONPIX_START_ADDR);
-	writel(fw_size, base + WRAPPER_NONPIX_END_ADDR);
-	writel(0x0, base + WRAPPER_CPU_CGC_DIS);
-	writel(0x0, base + WRAPPER_CPU_CLOCK_CONFIG);
+	writel(0, wrapper_base + WRAPPER_FW_START_ADDR);
+	writel(fw_size, wrapper_base + WRAPPER_FW_END_ADDR);
+	writel(0, wrapper_base + WRAPPER_CPA_START_ADDR);
+	writel(fw_size, wrapper_base + WRAPPER_CPA_END_ADDR);
+	writel(fw_size, wrapper_base + WRAPPER_NONPIX_START_ADDR);
+	writel(fw_size, wrapper_base + WRAPPER_NONPIX_END_ADDR);
+	writel(0x0, wrapper_base + WRAPPER_CPU_CGC_DIS);
+	writel(0x0, wrapper_base + WRAPPER_CPU_CLOCK_CONFIG);
 
 	/* Bring ARM9 out of reset */
-	writel(0, base + WRAPPER_A9SS_SW_RESET);
+	writel(0, wrapper_base + WRAPPER_A9SS_SW_RESET);
 }
 
 int venus_set_hw_state(struct venus_core *core, bool resume)
@@ -56,7 +56,7 @@
 	if (resume)
 		venus_reset_cpu(core);
 	else
-		writel(1, core->base + WRAPPER_A9SS_SW_RESET);
+		writel(1, core->wrapper_base + WRAPPER_A9SS_SW_RESET);
 
 	return 0;
 }
@@ -159,12 +159,12 @@
 	size_t unmapped;
 	u32 reg;
 	struct device *dev = core->fw.dev;
-	void __iomem *base = core->base;
+	void __iomem *wrapper_base = core->wrapper_base;
 
 	/* Assert the reset to ARM9 */
-	reg = readl_relaxed(base + WRAPPER_A9SS_SW_RESET);
+	reg = readl_relaxed(wrapper_base + WRAPPER_A9SS_SW_RESET);
 	reg |= WRAPPER_A9SS_SW_RESET_BIT;
-	writel_relaxed(reg, base + WRAPPER_A9SS_SW_RESET);
+	writel_relaxed(reg, wrapper_base + WRAPPER_A9SS_SW_RESET);
 
 	/* Make sure reset is asserted before the mapping is removed */
 	mb();
diff --git a/kernel/drivers/media/platform/qcom/venus/helpers.c b/kernel/drivers/media/platform/qcom/venus/helpers.c
index 50439eb..5fdce5f 100644
--- a/kernel/drivers/media/platform/qcom/venus/helpers.c
+++ b/kernel/drivers/media/platform/qcom/venus/helpers.c
@@ -917,8 +917,8 @@
 	u32 extradata = SZ_16K;
 	u32 size;
 
-	y_stride = ALIGN(ALIGN(width, 192) * 4 / 3, 256);
-	uv_stride = ALIGN(ALIGN(width, 192) * 4 / 3, 256);
+	y_stride = ALIGN(width * 4 / 3, 256);
+	uv_stride = ALIGN(width * 4 / 3, 256);
 	y_sclines = ALIGN(height, 16);
 	uv_sclines = ALIGN((height + 1) >> 1, 16);
 
@@ -1347,6 +1347,12 @@
 
 	v4l2_m2m_buf_queue(m2m_ctx, vbuf);
 
+	/* Skip processing queued capture buffers after LAST flag */
+	if (inst->session_type == VIDC_SESSION_TYPE_DEC &&
+	    V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) &&
+	    inst->codec_state == VENUS_DEC_STATE_DRC)
+		goto unlock;
+
 	cache_payload(inst, vb);
 
 	if (inst->session_type == VIDC_SESSION_TYPE_ENC &&
diff --git a/kernel/drivers/media/platform/qcom/venus/hfi_venus.c b/kernel/drivers/media/platform/qcom/venus/hfi_venus.c
index 4be4a75..9d939f6 100644
--- a/kernel/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/kernel/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -345,16 +345,6 @@
 	dma_free_attrs(dev, mem->size, mem->kva, mem->da, mem->attrs);
 }
 
-static void venus_writel(struct venus_hfi_device *hdev, u32 reg, u32 value)
-{
-	writel(value, hdev->core->base + reg);
-}
-
-static u32 venus_readl(struct venus_hfi_device *hdev, u32 reg)
-{
-	return readl(hdev->core->base + reg);
-}
-
 static void venus_set_registers(struct venus_hfi_device *hdev)
 {
 	const struct venus_resources *res = hdev->core->res;
@@ -363,12 +353,14 @@
 	unsigned int i;
 
 	for (i = 0; i < count; i++)
-		venus_writel(hdev, tbl[i].reg, tbl[i].value);
+		writel(tbl[i].value, hdev->core->base + tbl[i].reg);
 }
 
 static void venus_soft_int(struct venus_hfi_device *hdev)
 {
-	venus_writel(hdev, CPU_IC_SOFTINT, BIT(CPU_IC_SOFTINT_H2A_SHIFT));
+	void __iomem *cpu_ic_base = hdev->core->cpu_ic_base;
+
+	writel(BIT(CPU_IC_SOFTINT_H2A_SHIFT), cpu_ic_base + CPU_IC_SOFTINT);
 }
 
 static int venus_iface_cmdq_write_nolock(struct venus_hfi_device *hdev,
@@ -439,16 +431,25 @@
 {
 	struct device *dev = hdev->core->dev;
 	static const unsigned int max_tries = 100;
-	u32 ctrl_status = 0;
+	u32 ctrl_status = 0, mask_val;
 	unsigned int count = 0;
+	void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
+	void __iomem *wrapper_base = hdev->core->wrapper_base;
 	int ret = 0;
 
-	venus_writel(hdev, VIDC_CTRL_INIT, BIT(VIDC_CTRL_INIT_CTRL_SHIFT));
-	venus_writel(hdev, WRAPPER_INTR_MASK, WRAPPER_INTR_MASK_A2HVCODEC_MASK);
-	venus_writel(hdev, CPU_CS_SCIACMDARG3, 1);
+	if (IS_V6(hdev->core)) {
+		mask_val = readl(wrapper_base + WRAPPER_INTR_MASK);
+		mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BASK_V6 |
+			      WRAPPER_INTR_MASK_A2HCPU_MASK);
+	} else {
+		mask_val = WRAPPER_INTR_MASK_A2HVCODEC_MASK;
+	}
+	writel(mask_val, wrapper_base + WRAPPER_INTR_MASK);
+	writel(1, cpu_cs_base + CPU_CS_SCIACMDARG3);
 
+	writel(BIT(VIDC_CTRL_INIT_CTRL_SHIFT), cpu_cs_base + VIDC_CTRL_INIT);
 	while (!ctrl_status && count < max_tries) {
-		ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
+		ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0);
 		if ((ctrl_status & CPU_CS_SCIACMDARG0_ERROR_STATUS_MASK) == 4) {
 			dev_err(dev, "invalid setting for UC_REGION\n");
 			ret = -EINVAL;
@@ -462,15 +463,20 @@
 	if (count >= max_tries)
 		ret = -ETIMEDOUT;
 
+	if (IS_V6(hdev->core))
+		writel(0x0, cpu_cs_base + CPU_CS_X2RPMH_V6);
+
 	return ret;
 }
 
 static u32 venus_hwversion(struct venus_hfi_device *hdev)
 {
 	struct device *dev = hdev->core->dev;
-	u32 ver = venus_readl(hdev, WRAPPER_HW_VERSION);
+	void __iomem *wrapper_base = hdev->core->wrapper_base;
+	u32 ver;
 	u32 major, minor, step;
 
+	ver = readl(wrapper_base + WRAPPER_HW_VERSION);
 	major = ver & WRAPPER_HW_VERSION_MAJOR_VERSION_MASK;
 	major = major >> WRAPPER_HW_VERSION_MAJOR_VERSION_SHIFT;
 	minor = ver & WRAPPER_HW_VERSION_MINOR_VERSION_MASK;
@@ -485,6 +491,7 @@
 static int venus_run(struct venus_hfi_device *hdev)
 {
 	struct device *dev = hdev->core->dev;
+	void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
 	int ret;
 
 	/*
@@ -493,12 +500,12 @@
 	 */
 	venus_set_registers(hdev);
 
-	venus_writel(hdev, UC_REGION_ADDR, hdev->ifaceq_table.da);
-	venus_writel(hdev, UC_REGION_SIZE, SHARED_QSIZE);
-	venus_writel(hdev, CPU_CS_SCIACMDARG2, hdev->ifaceq_table.da);
-	venus_writel(hdev, CPU_CS_SCIACMDARG1, 0x01);
+	writel(hdev->ifaceq_table.da, cpu_cs_base + UC_REGION_ADDR);
+	writel(SHARED_QSIZE, cpu_cs_base + UC_REGION_SIZE);
+	writel(hdev->ifaceq_table.da, cpu_cs_base + CPU_CS_SCIACMDARG2);
+	writel(0x01, cpu_cs_base + CPU_CS_SCIACMDARG1);
 	if (hdev->sfr.da)
-		venus_writel(hdev, SFR_ADDR, hdev->sfr.da);
+		writel(hdev->sfr.da, cpu_cs_base + SFR_ADDR);
 
 	ret = venus_boot_core(hdev);
 	if (ret) {
@@ -513,17 +520,18 @@
 
 static int venus_halt_axi(struct venus_hfi_device *hdev)
 {
-	void __iomem *base = hdev->core->base;
+	void __iomem *wrapper_base = hdev->core->wrapper_base;
+	void __iomem *vbif_base = hdev->core->vbif_base;
 	struct device *dev = hdev->core->dev;
 	u32 val;
 	int ret;
 
 	if (IS_V4(hdev->core)) {
-		val = venus_readl(hdev, WRAPPER_CPU_AXI_HALT);
+		val = readl(wrapper_base + WRAPPER_CPU_AXI_HALT);
 		val |= WRAPPER_CPU_AXI_HALT_HALT;
-		venus_writel(hdev, WRAPPER_CPU_AXI_HALT, val);
+		writel(val, wrapper_base + WRAPPER_CPU_AXI_HALT);
 
-		ret = readl_poll_timeout(base + WRAPPER_CPU_AXI_HALT_STATUS,
+		ret = readl_poll_timeout(wrapper_base + WRAPPER_CPU_AXI_HALT_STATUS,
 					 val,
 					 val & WRAPPER_CPU_AXI_HALT_STATUS_IDLE,
 					 POLL_INTERVAL_US,
@@ -537,12 +545,12 @@
 	}
 
 	/* Halt AXI and AXI IMEM VBIF Access */
-	val = venus_readl(hdev, VBIF_AXI_HALT_CTRL0);
+	val = readl(vbif_base + VBIF_AXI_HALT_CTRL0);
 	val |= VBIF_AXI_HALT_CTRL0_HALT_REQ;
-	venus_writel(hdev, VBIF_AXI_HALT_CTRL0, val);
+	writel(val, vbif_base + VBIF_AXI_HALT_CTRL0);
 
 	/* Request for AXI bus port halt */
-	ret = readl_poll_timeout(base + VBIF_AXI_HALT_CTRL1, val,
+	ret = readl_poll_timeout(vbif_base + VBIF_AXI_HALT_CTRL1, val,
 				 val & VBIF_AXI_HALT_CTRL1_HALT_ACK,
 				 POLL_INTERVAL_US,
 				 VBIF_AXI_HALT_ACK_TIMEOUT_US);
@@ -1035,19 +1043,21 @@
 {
 	struct venus_hfi_device *hdev = to_hfi_priv(core);
 	u32 status;
+	void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
+	void __iomem *wrapper_base = hdev->core->wrapper_base;
 
 	if (!hdev)
 		return IRQ_NONE;
 
-	status = venus_readl(hdev, WRAPPER_INTR_STATUS);
+	status = readl(wrapper_base + WRAPPER_INTR_STATUS);
 
 	if (status & WRAPPER_INTR_STATUS_A2H_MASK ||
 	    status & WRAPPER_INTR_STATUS_A2HWD_MASK ||
 	    status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK)
 		hdev->irq_status = status;
 
-	venus_writel(hdev, CPU_CS_A2HSOFTINTCLR, 1);
-	venus_writel(hdev, WRAPPER_INTR_CLEAR, status);
+	writel(1, cpu_cs_base + CPU_CS_A2HSOFTINTCLR);
+	writel(status, wrapper_base + WRAPPER_INTR_CLEAR);
 
 	return IRQ_WAKE_THREAD;
 }
@@ -1380,6 +1390,7 @@
 {
 	struct venus_hfi_device *hdev = to_hfi_priv(core);
 	struct device *dev = core->dev;
+	void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
 	u32 ctrl_status;
 	int ret;
 
@@ -1414,7 +1425,7 @@
 		return -EINVAL;
 	}
 
-	ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
+	ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0);
 	if (!(ctrl_status & CPU_CS_SCIACMDARG0_PC_READY)) {
 		mutex_unlock(&hdev->lock);
 		return -EINVAL;
@@ -1435,10 +1446,12 @@
 
 static bool venus_cpu_and_video_core_idle(struct venus_hfi_device *hdev)
 {
+	void __iomem *wrapper_base = hdev->core->wrapper_base;
+	void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
 	u32 ctrl_status, cpu_status;
 
-	cpu_status = venus_readl(hdev, WRAPPER_CPU_STATUS);
-	ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
+	cpu_status = readl(wrapper_base + WRAPPER_CPU_STATUS);
+	ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0);
 
 	if (cpu_status & WRAPPER_CPU_STATUS_WFI &&
 	    ctrl_status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK)
@@ -1449,10 +1462,12 @@
 
 static bool venus_cpu_idle_and_pc_ready(struct venus_hfi_device *hdev)
 {
+	void __iomem *wrapper_base = hdev->core->wrapper_base;
+	void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
 	u32 ctrl_status, cpu_status;
 
-	cpu_status = venus_readl(hdev, WRAPPER_CPU_STATUS);
-	ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
+	cpu_status = readl(wrapper_base + WRAPPER_CPU_STATUS);
+	ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0);
 
 	if (cpu_status & WRAPPER_CPU_STATUS_WFI &&
 	    ctrl_status & CPU_CS_SCIACMDARG0_PC_READY)
@@ -1465,6 +1480,7 @@
 {
 	struct venus_hfi_device *hdev = to_hfi_priv(core);
 	struct device *dev = core->dev;
+	void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
 	u32 ctrl_status;
 	bool val;
 	int ret;
@@ -1481,7 +1497,7 @@
 		return -EINVAL;
 	}
 
-	ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
+	ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0);
 	if (ctrl_status & CPU_CS_SCIACMDARG0_PC_READY)
 		goto power_off;
 
diff --git a/kernel/drivers/media/platform/qcom/venus/hfi_venus_io.h b/kernel/drivers/media/platform/qcom/venus/hfi_venus_io.h
index 3b52f98..9cad15e 100644
--- a/kernel/drivers/media/platform/qcom/venus/hfi_venus_io.h
+++ b/kernel/drivers/media/platform/qcom/venus/hfi_venus_io.h
@@ -8,27 +8,28 @@
 
 #define VBIF_BASE				0x80000
 
-#define VBIF_AXI_HALT_CTRL0			(VBIF_BASE + 0x208)
-#define VBIF_AXI_HALT_CTRL1			(VBIF_BASE + 0x20c)
+#define VBIF_AXI_HALT_CTRL0			0x208
+#define VBIF_AXI_HALT_CTRL1			0x20c
 
 #define VBIF_AXI_HALT_CTRL0_HALT_REQ		BIT(0)
 #define VBIF_AXI_HALT_CTRL1_HALT_ACK		BIT(0)
 #define VBIF_AXI_HALT_ACK_TIMEOUT_US		500000
 
 #define CPU_BASE				0xc0000
+
 #define CPU_CS_BASE				(CPU_BASE + 0x12000)
 #define CPU_IC_BASE				(CPU_BASE + 0x1f000)
 
-#define CPU_CS_A2HSOFTINTCLR			(CPU_CS_BASE + 0x1c)
+#define CPU_CS_A2HSOFTINTCLR			0x1c
 
-#define VIDC_CTRL_INIT				(CPU_CS_BASE + 0x48)
+#define VIDC_CTRL_INIT				0x48
 #define VIDC_CTRL_INIT_RESERVED_BITS31_1_MASK	0xfffffffe
 #define VIDC_CTRL_INIT_RESERVED_BITS31_1_SHIFT	1
 #define VIDC_CTRL_INIT_CTRL_MASK		0x1
 #define VIDC_CTRL_INIT_CTRL_SHIFT		0
 
 /* HFI control status */
-#define CPU_CS_SCIACMDARG0			(CPU_CS_BASE + 0x4c)
+#define CPU_CS_SCIACMDARG0			0x4c
 #define CPU_CS_SCIACMDARG0_MASK			0xff
 #define CPU_CS_SCIACMDARG0_SHIFT		0x0
 #define CPU_CS_SCIACMDARG0_ERROR_STATUS_MASK	0xfe
@@ -39,42 +40,55 @@
 #define CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK	BIT(30)
 
 /* HFI queue table info */
-#define CPU_CS_SCIACMDARG1			(CPU_CS_BASE + 0x50)
+#define CPU_CS_SCIACMDARG1			0x50
 
 /* HFI queue table address */
-#define CPU_CS_SCIACMDARG2			(CPU_CS_BASE + 0x54)
+#define CPU_CS_SCIACMDARG2			0x54
 
 /* Venus cpu */
-#define CPU_CS_SCIACMDARG3			(CPU_CS_BASE + 0x58)
+#define CPU_CS_SCIACMDARG3			0x58
 
-#define SFR_ADDR				(CPU_CS_BASE + 0x5c)
-#define MMAP_ADDR				(CPU_CS_BASE + 0x60)
-#define UC_REGION_ADDR				(CPU_CS_BASE + 0x64)
-#define UC_REGION_SIZE				(CPU_CS_BASE + 0x68)
+#define SFR_ADDR				0x5c
+#define MMAP_ADDR				0x60
+#define UC_REGION_ADDR				0x64
+#define UC_REGION_SIZE				0x68
 
-#define CPU_IC_SOFTINT				(CPU_IC_BASE + 0x18)
+#define CPU_CS_H2XSOFTINTEN_V6			0x148
+
+#define CPU_CS_X2RPMH_V6			0x168
+#define CPU_CS_X2RPMH_MASK0_BMSK_V6		0x1
+#define CPU_CS_X2RPMH_MASK0_SHFT_V6		0x0
+#define CPU_CS_X2RPMH_MASK1_BMSK_V6		0x2
+#define CPU_CS_X2RPMH_MASK1_SHFT_V6		0x1
+#define CPU_CS_X2RPMH_SWOVERRIDE_BMSK_V6	0x4
+#define CPU_CS_X2RPMH_SWOVERRIDE_SHFT_V6	0x3
+
+/* Relative to CPU_IC_BASE */
+#define CPU_IC_SOFTINT				0x18
+#define CPU_IC_SOFTINT_V6			0x150
 #define CPU_IC_SOFTINT_H2A_MASK			0x8000
 #define CPU_IC_SOFTINT_H2A_SHIFT		0xf
+#define CPU_IC_SOFTINT_H2A_SHIFT_V6		0x0
 
 /* Venus wrapper */
 #define WRAPPER_BASE				0x000e0000
 
-#define WRAPPER_HW_VERSION			(WRAPPER_BASE + 0x00)
+#define WRAPPER_HW_VERSION			0x00
 #define WRAPPER_HW_VERSION_MAJOR_VERSION_MASK	0x78000000
 #define WRAPPER_HW_VERSION_MAJOR_VERSION_SHIFT	28
 #define WRAPPER_HW_VERSION_MINOR_VERSION_MASK	0xfff0000
 #define WRAPPER_HW_VERSION_MINOR_VERSION_SHIFT	16
 #define WRAPPER_HW_VERSION_STEP_VERSION_MASK	0xffff
 
-#define WRAPPER_CLOCK_CONFIG			(WRAPPER_BASE + 0x04)
+#define WRAPPER_CLOCK_CONFIG			0x04
 
-#define WRAPPER_INTR_STATUS			(WRAPPER_BASE + 0x0c)
+#define WRAPPER_INTR_STATUS			0x0c
 #define WRAPPER_INTR_STATUS_A2HWD_MASK		0x10
 #define WRAPPER_INTR_STATUS_A2HWD_SHIFT		0x4
 #define WRAPPER_INTR_STATUS_A2H_MASK		0x4
 #define WRAPPER_INTR_STATUS_A2H_SHIFT		0x2
 
-#define WRAPPER_INTR_MASK			(WRAPPER_BASE + 0x10)
+#define WRAPPER_INTR_MASK			0x10
 #define WRAPPER_INTR_MASK_A2HWD_BASK		0x10
 #define WRAPPER_INTR_MASK_A2HWD_SHIFT		0x4
 #define WRAPPER_INTR_MASK_A2HVCODEC_MASK	0x8
@@ -82,41 +96,59 @@
 #define WRAPPER_INTR_MASK_A2HCPU_MASK		0x4
 #define WRAPPER_INTR_MASK_A2HCPU_SHIFT		0x2
 
-#define WRAPPER_INTR_CLEAR			(WRAPPER_BASE + 0x14)
+#define WRAPPER_INTR_STATUS_A2HWD_MASK_V6	0x8
+#define WRAPPER_INTR_MASK_A2HWD_BASK_V6		0x8
+
+#define WRAPPER_INTR_CLEAR			0x14
 #define WRAPPER_INTR_CLEAR_A2HWD_MASK		0x10
 #define WRAPPER_INTR_CLEAR_A2HWD_SHIFT		0x4
 #define WRAPPER_INTR_CLEAR_A2H_MASK		0x4
 #define WRAPPER_INTR_CLEAR_A2H_SHIFT		0x2
 
-#define WRAPPER_POWER_STATUS			(WRAPPER_BASE + 0x44)
-#define WRAPPER_VDEC_VCODEC_POWER_CONTROL	(WRAPPER_BASE + 0x48)
-#define WRAPPER_VENC_VCODEC_POWER_CONTROL	(WRAPPER_BASE + 0x4c)
-#define WRAPPER_VDEC_VENC_AHB_BRIDGE_SYNC_RESET	(WRAPPER_BASE + 0x64)
+#define WRAPPER_POWER_STATUS			0x44
+#define WRAPPER_VDEC_VCODEC_POWER_CONTROL	0x48
+#define WRAPPER_VENC_VCODEC_POWER_CONTROL	0x4c
+#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_V6	0x54
+#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS_V6	0x58
+#define WRAPPER_VDEC_VENC_AHB_BRIDGE_SYNC_RESET	0x64
 
-#define WRAPPER_CPU_CLOCK_CONFIG		(WRAPPER_BASE + 0x2000)
-#define WRAPPER_CPU_AXI_HALT			(WRAPPER_BASE + 0x2008)
+#define WRAPPER_CPU_CLOCK_CONFIG		0x2000
+#define WRAPPER_CPU_AXI_HALT			0x2008
 #define WRAPPER_CPU_AXI_HALT_HALT		BIT(16)
-#define WRAPPER_CPU_AXI_HALT_STATUS		(WRAPPER_BASE + 0x200c)
+#define WRAPPER_CPU_AXI_HALT_STATUS		0x200c
 #define WRAPPER_CPU_AXI_HALT_STATUS_IDLE	BIT(24)
 
-#define WRAPPER_CPU_CGC_DIS			(WRAPPER_BASE + 0x2010)
-#define WRAPPER_CPU_STATUS			(WRAPPER_BASE + 0x2014)
+#define WRAPPER_CPU_CGC_DIS			0x2010
+#define WRAPPER_CPU_STATUS			0x2014
 #define WRAPPER_CPU_STATUS_WFI			BIT(0)
-#define WRAPPER_SW_RESET			(WRAPPER_BASE + 0x3000)
-#define WRAPPER_CPA_START_ADDR			(WRAPPER_BASE + 0x1020)
-#define WRAPPER_CPA_END_ADDR			(WRAPPER_BASE + 0x1024)
-#define WRAPPER_FW_START_ADDR			(WRAPPER_BASE + 0x1028)
-#define WRAPPER_FW_END_ADDR			(WRAPPER_BASE + 0x102C)
-#define WRAPPER_NONPIX_START_ADDR		(WRAPPER_BASE + 0x1030)
-#define WRAPPER_NONPIX_END_ADDR			(WRAPPER_BASE + 0x1034)
-#define WRAPPER_A9SS_SW_RESET			(WRAPPER_BASE + 0x3000)
+#define WRAPPER_SW_RESET			0x3000
+#define WRAPPER_CPA_START_ADDR			0x1020
+#define WRAPPER_CPA_END_ADDR			0x1024
+#define WRAPPER_FW_START_ADDR			0x1028
+#define WRAPPER_FW_END_ADDR			0x102C
+#define WRAPPER_NONPIX_START_ADDR		0x1030
+#define WRAPPER_NONPIX_END_ADDR			0x1034
+#define WRAPPER_A9SS_SW_RESET			0x3000
 #define WRAPPER_A9SS_SW_RESET_BIT		BIT(4)
 
 /* Venus 4xx */
-#define WRAPPER_VCODEC0_MMCC_POWER_STATUS	(WRAPPER_BASE + 0x90)
-#define WRAPPER_VCODEC0_MMCC_POWER_CONTROL	(WRAPPER_BASE + 0x94)
+#define WRAPPER_VCODEC0_MMCC_POWER_STATUS	0x90
+#define WRAPPER_VCODEC0_MMCC_POWER_CONTROL	0x94
 
-#define WRAPPER_VCODEC1_MMCC_POWER_STATUS	(WRAPPER_BASE + 0x110)
-#define WRAPPER_VCODEC1_MMCC_POWER_CONTROL	(WRAPPER_BASE + 0x114)
+#define WRAPPER_VCODEC1_MMCC_POWER_STATUS	0x110
+#define WRAPPER_VCODEC1_MMCC_POWER_CONTROL	0x114
+
+/* Venus 6xx */
+#define WRAPPER_CORE_POWER_STATUS_V6		0x80
+#define WRAPPER_CORE_POWER_CONTROL_V6		0x84
+
+/* Wrapper TZ 6xx */
+#define WRAPPER_TZ_BASE_V6			0x000c0000
+#define WRAPPER_TZ_CPU_STATUS_V6		0x10
+
+/* Venus AON */
+#define AON_BASE_V6				0x000e0000
+#define AON_WRAPPER_MVP_NOC_LPI_CONTROL		0x00
+#define AON_WRAPPER_MVP_NOC_LPI_STATUS		0x04
 
 #endif
diff --git a/kernel/drivers/media/platform/qcom/venus/pm_helpers.c b/kernel/drivers/media/platform/qcom/venus/pm_helpers.c
index 710f9a2..6bf9c5c 100644
--- a/kernel/drivers/media/platform/qcom/venus/pm_helpers.c
+++ b/kernel/drivers/media/platform/qcom/venus/pm_helpers.c
@@ -304,9 +304,9 @@
 	void __iomem *ctrl;
 
 	if (session_type == VIDC_SESSION_TYPE_DEC)
-		ctrl = core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL;
+		ctrl = core->wrapper_base + WRAPPER_VDEC_VCODEC_POWER_CONTROL;
 	else
-		ctrl = core->base + WRAPPER_VENC_VCODEC_POWER_CONTROL;
+		ctrl = core->wrapper_base + WRAPPER_VENC_VCODEC_POWER_CONTROL;
 
 	if (enable)
 		writel(0, ctrl);
@@ -381,11 +381,11 @@
 	int ret;
 
 	if (coreid == VIDC_CORE_ID_1) {
-		ctrl = core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL;
-		stat = core->base + WRAPPER_VCODEC0_MMCC_POWER_STATUS;
+		ctrl = core->wrapper_base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL;
+		stat = core->wrapper_base + WRAPPER_VCODEC0_MMCC_POWER_STATUS;
 	} else {
-		ctrl = core->base + WRAPPER_VCODEC1_MMCC_POWER_CONTROL;
-		stat = core->base + WRAPPER_VCODEC1_MMCC_POWER_STATUS;
+		ctrl = core->wrapper_base + WRAPPER_VCODEC1_MMCC_POWER_CONTROL;
+		stat = core->wrapper_base + WRAPPER_VCODEC1_MMCC_POWER_STATUS;
 	}
 
 	if (enable) {
@@ -764,8 +764,8 @@
 	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;
 	}
 
diff --git a/kernel/drivers/media/platform/qcom/venus/vdec.c b/kernel/drivers/media/platform/qcom/venus/vdec.c
index de34a87..c437a92 100644
--- a/kernel/drivers/media/platform/qcom/venus/vdec.c
+++ b/kernel/drivers/media/platform/qcom/venus/vdec.c
@@ -495,6 +495,7 @@
 vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
 {
 	struct venus_inst *inst = to_inst(file);
+	struct vb2_queue *dst_vq;
 	struct hfi_frame_data fdata = {0};
 	int ret;
 
@@ -518,8 +519,17 @@
 
 		ret = hfi_session_process_buf(inst, &fdata);
 
-		if (!ret && inst->codec_state == VENUS_DEC_STATE_DECODING)
+		if (!ret && inst->codec_state == VENUS_DEC_STATE_DECODING) {
 			inst->codec_state = VENUS_DEC_STATE_DRAIN;
+			inst->drain_active = true;
+		}
+	} else if (cmd->cmd == V4L2_DEC_CMD_START &&
+		   inst->codec_state == VENUS_DEC_STATE_STOPPED) {
+		dst_vq = v4l2_m2m_get_vq(inst->fh.m2m_ctx,
+					 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+		vb2_clear_last_buffer_dequeued(dst_vq);
+
+		inst->codec_state = VENUS_DEC_STATE_DECODING;
 	}
 
 unlock:
@@ -636,6 +646,7 @@
 {
 	struct venus_core *core = inst->core;
 	struct hfi_enable en = { .enable = 1 };
+	struct hfi_buffer_requirements bufreq;
 	u32 width = inst->out_width;
 	u32 height = inst->out_height;
 	u32 out_fmt, out2_fmt;
@@ -711,6 +722,23 @@
 	}
 
 	if (IS_V3(core) || IS_V4(core)) {
+		ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq);
+		if (ret)
+			return ret;
+
+		if (bufreq.size > inst->output_buf_size)
+			return -EINVAL;
+
+		if (inst->dpb_fmt) {
+			ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT2,
+						      &bufreq);
+			if (ret)
+				return ret;
+
+			if (bufreq.size > inst->output2_buf_size)
+				return -EINVAL;
+		}
+
 		if (inst->output2_buf_size) {
 			ret = venus_helper_set_bufsize(inst,
 						       inst->output2_buf_size,
@@ -916,10 +944,6 @@
 		return 0;
 
 reconfigure:
-	ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, true);
-	if (ret)
-		return ret;
-
 	ret = vdec_output_conf(inst);
 	if (ret)
 		return ret;
@@ -947,15 +971,21 @@
 
 	venus_pm_load_scale(inst);
 
+	inst->next_buf_last = false;
+
 	ret = hfi_session_continue(inst);
 	if (ret)
 		goto free_dpb_bufs;
 
 	inst->codec_state = VENUS_DEC_STATE_DECODING;
 
+	if (inst->drain_active)
+		inst->codec_state = VENUS_DEC_STATE_DRAIN;
+
 	inst->streamon_cap = 1;
 	inst->sequence_cap = 0;
 	inst->reconfig = false;
+	inst->drain_active = false;
 
 	return 0;
 
@@ -971,7 +1001,10 @@
 
 	if (inst->codec_state == VENUS_DEC_STATE_SEEK) {
 		ret = venus_helper_process_initial_out_bufs(inst);
-		inst->codec_state = VENUS_DEC_STATE_DECODING;
+		if (inst->next_buf_last)
+			inst->codec_state = VENUS_DEC_STATE_DRC;
+		else
+			inst->codec_state = VENUS_DEC_STATE_DECODING;
 		goto done;
 	}
 
@@ -987,6 +1020,7 @@
 	venus_helper_init_instance(inst);
 	inst->sequence_out = 0;
 	inst->reconfig = false;
+	inst->next_buf_last = false;
 
 	ret = vdec_set_properties(inst);
 	if (ret)
@@ -1076,13 +1110,14 @@
 		ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true);
 		fallthrough;
 	case VENUS_DEC_STATE_DRAIN:
-		vdec_cancel_dst_buffers(inst);
 		inst->codec_state = VENUS_DEC_STATE_STOPPED;
+		inst->drain_active = false;
+		fallthrough;
+	case VENUS_DEC_STATE_SEEK:
+		vdec_cancel_dst_buffers(inst);
 		break;
 	case VENUS_DEC_STATE_DRC:
-		WARN_ON(1);
-		fallthrough;
-	case VENUS_DEC_STATE_DRC_FLUSH_DONE:
+		ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, true);
 		inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP;
 		venus_helper_free_dpb_bufs(inst);
 		break;
@@ -1101,6 +1136,7 @@
 	case VENUS_DEC_STATE_DECODING:
 	case VENUS_DEC_STATE_DRAIN:
 	case VENUS_DEC_STATE_STOPPED:
+	case VENUS_DEC_STATE_DRC:
 		ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true);
 		inst->codec_state = VENUS_DEC_STATE_SEEK;
 		break;
@@ -1206,8 +1242,27 @@
 static void vdec_vb2_buf_queue(struct vb2_buffer *vb)
 {
 	struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	static const struct v4l2_event eos = { .type = V4L2_EVENT_EOS };
 
 	vdec_pm_get_put(inst);
+
+	mutex_lock(&inst->lock);
+
+	if (inst->next_buf_last && V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) &&
+	    inst->codec_state == VENUS_DEC_STATE_DRC) {
+		vbuf->flags |= V4L2_BUF_FLAG_LAST;
+		vbuf->sequence = inst->sequence_cap++;
+		vbuf->field = V4L2_FIELD_NONE;
+		vb2_set_plane_payload(vb, 0, 0);
+		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+		v4l2_event_queue_fh(&inst->fh, &eos);
+		inst->next_buf_last = false;
+		mutex_unlock(&inst->lock);
+		return;
+	}
+
+	mutex_unlock(&inst->lock);
 
 	venus_helper_vb2_buf_queue(vb);
 }
@@ -1252,20 +1307,15 @@
 		vb->timestamp = timestamp_us * NSEC_PER_USEC;
 		vbuf->sequence = inst->sequence_cap++;
 
-		if (inst->last_buf == vb) {
-			inst->last_buf = NULL;
-			vbuf->flags |= V4L2_BUF_FLAG_LAST;
-			vb2_set_plane_payload(vb, 0, 0);
-			vb->timestamp = 0;
-		}
-
 		if (vbuf->flags & V4L2_BUF_FLAG_LAST) {
 			const struct v4l2_event ev = { .type = V4L2_EVENT_EOS };
 
 			v4l2_event_queue_fh(&inst->fh, &ev);
 
-			if (inst->codec_state == VENUS_DEC_STATE_DRAIN)
+			if (inst->codec_state == VENUS_DEC_STATE_DRAIN) {
+				inst->drain_active = false;
 				inst->codec_state = VENUS_DEC_STATE_STOPPED;
+			}
 		}
 
 		if (!bytesused)
@@ -1321,19 +1371,16 @@
 	dev_dbg(dev, VDBGM "event %s sufficient resources (%ux%u)\n",
 		sufficient ? "" : "not", ev_data->width, ev_data->height);
 
-	if (sufficient) {
-		hfi_session_continue(inst);
-	} else {
-		switch (inst->codec_state) {
-		case VENUS_DEC_STATE_INIT:
-			inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP;
-			break;
-		case VENUS_DEC_STATE_DECODING:
-			inst->codec_state = VENUS_DEC_STATE_DRC;
-			break;
-		default:
-			break;
-		}
+	switch (inst->codec_state) {
+	case VENUS_DEC_STATE_INIT:
+		inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP;
+		break;
+	case VENUS_DEC_STATE_DECODING:
+	case VENUS_DEC_STATE_DRAIN:
+		inst->codec_state = VENUS_DEC_STATE_DRC;
+		break;
+	default:
+		break;
 	}
 
 	/*
@@ -1342,19 +1389,17 @@
 	 * itself doesn't mark the last decoder output buffer with HFI EOS flag.
 	 */
 
-	if (!sufficient && inst->codec_state == VENUS_DEC_STATE_DRC) {
-		struct vb2_v4l2_buffer *last;
+	if (inst->codec_state == VENUS_DEC_STATE_DRC) {
 		int ret;
 
-		last = v4l2_m2m_last_dst_buf(inst->m2m_ctx);
-		if (last)
-			inst->last_buf = &last->vb2_buf;
+		inst->next_buf_last = true;
 
 		ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, false);
 		if (ret)
 			dev_dbg(dev, VDBGH "flush output error %d\n", ret);
 	}
 
+	inst->next_buf_last = true;
 	inst->reconfig = true;
 	v4l2_event_queue_fh(&inst->fh, &ev);
 	wake_up(&inst->reconf_wait);
@@ -1397,8 +1442,7 @@
 
 static void vdec_flush_done(struct venus_inst *inst)
 {
-	if (inst->codec_state == VENUS_DEC_STATE_DRC)
-		inst->codec_state = VENUS_DEC_STATE_DRC_FLUSH_DONE;
+	dev_dbg(inst->core->dev_dec, VDBGH "flush done\n");
 }
 
 static const struct hfi_inst_ops vdec_hfi_ops = {
diff --git a/kernel/drivers/media/platform/rcar-vin/rcar-dma.c b/kernel/drivers/media/platform/rcar-vin/rcar-dma.c
index 692dea3..63c61c7 100644
--- a/kernel/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/kernel/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -645,11 +645,9 @@
 	case V4L2_FIELD_SEQ_TB:
 	case V4L2_FIELD_SEQ_BT:
 	case V4L2_FIELD_NONE:
-		vnmc = VNMC_IM_ODD_EVEN;
-		progressive = true;
-		break;
 	case V4L2_FIELD_ALTERNATE:
 		vnmc = VNMC_IM_ODD_EVEN;
+		progressive = true;
 		break;
 	default:
 		vnmc = VNMC_IM_ODD;
diff --git a/kernel/drivers/media/platform/rcar_fdp1.c b/kernel/drivers/media/platform/rcar_fdp1.c
index c9448de..44a57fa 100644
--- a/kernel/drivers/media/platform/rcar_fdp1.c
+++ b/kernel/drivers/media/platform/rcar_fdp1.c
@@ -2121,9 +2121,7 @@
 
 	if (ctx->hdl.error) {
 		ret = ctx->hdl.error;
-		v4l2_ctrl_handler_free(&ctx->hdl);
-		kfree(ctx);
-		goto done;
+		goto error_ctx;
 	}
 
 	ctx->fh.ctrl_handler = &ctx->hdl;
@@ -2137,20 +2135,27 @@
 
 	if (IS_ERR(ctx->fh.m2m_ctx)) {
 		ret = PTR_ERR(ctx->fh.m2m_ctx);
-
-		v4l2_ctrl_handler_free(&ctx->hdl);
-		kfree(ctx);
-		goto done;
+		goto error_ctx;
 	}
 
 	/* Perform any power management required */
-	pm_runtime_get_sync(fdp1->dev);
+	ret = pm_runtime_resume_and_get(fdp1->dev);
+	if (ret < 0)
+		goto error_pm;
 
 	v4l2_fh_add(&ctx->fh);
 
 	dprintk(fdp1, "Created instance: %p, m2m_ctx: %p\n",
 		ctx, ctx->fh.m2m_ctx);
 
+	mutex_unlock(&fdp1->dev_mutex);
+	return 0;
+
+error_pm:
+       v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
+error_ctx:
+	v4l2_ctrl_handler_free(&ctx->hdl);
+	kfree(ctx);
 done:
 	mutex_unlock(&fdp1->dev_mutex);
 	return ret;
@@ -2255,7 +2260,6 @@
 	struct fdp1_dev *fdp1;
 	struct video_device *vfd;
 	struct device_node *fcp_node;
-	struct resource *res;
 	struct clk *clk;
 	unsigned int i;
 
@@ -2282,17 +2286,15 @@
 	platform_set_drvdata(pdev, fdp1);
 
 	/* Memory-mapped registers */
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	fdp1->regs = devm_ioremap_resource(&pdev->dev, res);
+	fdp1->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(fdp1->regs))
 		return PTR_ERR(fdp1->regs);
 
 	/* Interrupt service routine registration */
-	fdp1->irq = ret = platform_get_irq(pdev, 0);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "cannot find IRQ\n");
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
 		return ret;
-	}
+	fdp1->irq = ret;
 
 	ret = devm_request_irq(&pdev->dev, fdp1->irq, fdp1_irq_handler, 0,
 			       dev_name(&pdev->dev), fdp1);
@@ -2315,8 +2317,10 @@
 
 	/* Determine our clock rate */
 	clk = clk_get(&pdev->dev, NULL);
-	if (IS_ERR(clk))
-		return PTR_ERR(clk);
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		goto put_dev;
+	}
 
 	fdp1->clk_rate = clk_get_rate(clk);
 	clk_put(clk);
@@ -2325,7 +2329,7 @@
 	ret = v4l2_device_register(&pdev->dev, &fdp1->v4l2_dev);
 	if (ret) {
 		v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n");
-		return ret;
+		goto put_dev;
 	}
 
 	/* M2M registration */
@@ -2355,7 +2359,9 @@
 
 	/* Power up the cells to read HW */
 	pm_runtime_enable(&pdev->dev);
-	pm_runtime_get_sync(fdp1->dev);
+	ret = pm_runtime_resume_and_get(fdp1->dev);
+	if (ret < 0)
+		goto disable_pm;
 
 	hw_version = fdp1_read(fdp1, FD1_IP_INTDATA);
 	switch (hw_version) {
@@ -2384,12 +2390,17 @@
 
 	return 0;
 
+disable_pm:
+	pm_runtime_disable(fdp1->dev);
+
 release_m2m:
 	v4l2_m2m_release(fdp1->m2m_dev);
 
 unreg_dev:
 	v4l2_device_unregister(&fdp1->v4l2_dev);
 
+put_dev:
+	rcar_fcp_put(fdp1->fcp);
 	return ret;
 }
 
@@ -2401,6 +2412,7 @@
 	video_unregister_device(&fdp1->vfd);
 	v4l2_device_unregister(&fdp1->v4l2_dev);
 	pm_runtime_disable(&pdev->dev);
+	rcar_fcp_put(fdp1->fcp);
 
 	return 0;
 }
diff --git a/kernel/drivers/media/platform/rockchip/cif/capture.c b/kernel/drivers/media/platform/rockchip/cif/capture.c
index 983d675..dfa9d8e 100644
--- a/kernel/drivers/media/platform/rockchip/cif/capture.c
+++ b/kernel/drivers/media/platform/rockchip/cif/capture.c
@@ -18,8 +18,8 @@
 #include <media/videobuf2-dma-contig.h>
 #include <media/videobuf2-dma-sg.h>
 #include <soc/rockchip/rockchip-system-status.h>
-#include <dt-bindings/soc/rockchip-system-status.h>
 #include <soc/rockchip/rockchip_iommu.h>
+#include <linux/rk-isp32-config.h>
 
 #include "dev.h"
 #include "mipi-csi2.h"
@@ -515,6 +515,10 @@
 		.csi_fmt_val	= CSI_WRDDR_TYPE_RGB888,
 		.field		= V4L2_FIELD_NONE,
 	}, {
+		.mbus_code	= MEDIA_BUS_FMT_GBR888_1X24,
+		.csi_fmt_val	= CSI_WRDDR_TYPE_RGB888,
+		.field		= V4L2_FIELD_NONE,
+	}, {
 		.mbus_code	= MEDIA_BUS_FMT_RGB565_1X16,
 		.csi_fmt_val	= CSI_WRDDR_TYPE_RGB565,
 		.field		= V4L2_FIELD_NONE,
@@ -611,6 +615,7 @@
 		break;
 	case MEDIA_BUS_FMT_RGB888_1X24:
 	case MEDIA_BUS_FMT_BGR888_1X24:
+	case MEDIA_BUS_FMT_GBR888_1X24:
 		if (output_fmt->fourcc == V4L2_PIX_FMT_RGB24 ||
 		    output_fmt->fourcc == V4L2_PIX_FMT_BGR24)
 			ret = 0;
@@ -671,7 +676,7 @@
 		break;
 	}
 	if (ret)
-		v4l2_err(&stream->cifdev->v4l2_dev,
+		v4l2_dbg(4, rkcif_debug, &stream->cifdev->v4l2_dev,
 			 "input mbus_code 0x%x, can't transform to %c%c%c%c\n",
 			 input_fmt->mbus_code,
 			 output_fmt->fourcc & 0xff,
@@ -801,6 +806,7 @@
 		return 0x1e;
 	case MEDIA_BUS_FMT_RGB888_1X24:
 	case MEDIA_BUS_FMT_BGR888_1X24:
+	case MEDIA_BUS_FMT_GBR888_1X24:
 		if (dsi_input) {
 			if (cmd_mode_en) /* dsi command mode*/
 				return 0x39;
@@ -1608,25 +1614,29 @@
 	return ret;
 }
 
-static void rkcif_rx_buffer_free(struct rkcif_stream *stream)
+static struct v4l2_subdev *get_rkisp_sd(struct sditf_priv *priv)
 {
 	struct media_pad *pad = NULL;
+
+	if (priv && priv->pads[0].entity->num_links) {
+		if (priv->is_combine_mode)
+			pad = media_entity_remote_pad(&priv->pads[1]);
+		else
+			pad = media_entity_remote_pad(&priv->pads[0]);
+		if (pad)
+			return media_entity_to_v4l2_subdev(pad->entity);
+	}
+	return NULL;
+}
+
+static void rkcif_rx_buffer_free(struct rkcif_stream *stream)
+{
 	struct v4l2_subdev *sd;
 	struct rkisp_rx_buf *dbufs;
 	struct rkcif_device *dev = stream->cifdev;
 
-	if (dev->sditf[0] && dev->sditf[0]->sd.entity.num_links) {
-		if (dev->sditf[0]->is_combine_mode)
-			pad = media_entity_remote_pad(&dev->sditf[0]->pads[1]);
-		else
-			pad = media_entity_remote_pad(&dev->sditf[0]->pads[0]);
-	} else {
-		return;
-	}
-
-	if (pad)
-		sd = media_entity_to_v4l2_subdev(pad->entity);
-	else
+	sd = get_rkisp_sd(dev->sditf[0]);
+	if (!sd)
 		return;
 
 	while (!list_empty(&stream->rx_buf_head_vicap)) {
@@ -1640,31 +1650,23 @@
 	}
 }
 
-static void rkcif_s_rx_buffer(struct rkcif_device *dev, struct rkisp_rx_buf *dbufs)
+static void rkcif_s_rx_buffer(struct rkcif_stream *stream, struct rkisp_rx_buf *dbufs)
 {
-	struct media_pad *pad = NULL;
+	struct rkcif_device *dev = stream->cifdev;
 	struct v4l2_subdev *sd;
 	struct rkcif_rx_buffer *rx_buf = NULL;
 
-	if (dev->sditf[0]) {
-		if (dev->sditf[0]->is_combine_mode)
-			pad = media_entity_remote_pad(&dev->sditf[0]->pads[1]);
-		else
-			pad = media_entity_remote_pad(&dev->sditf[0]->pads[0]);
-	} else {
+	sd = get_rkisp_sd(dev->sditf[0]);
+	if (!sd)
 		return;
-	}
-	if (pad)
-		sd = media_entity_to_v4l2_subdev(pad->entity);
-	else
-		return;
-	if (dev->rdbk_debug &&
-	    dbufs->sequence < 15) {
+	if ((dev->rdbk_debug &&
+	     dbufs->sequence < 15) ||
+	    rkcif_debug == 3) {
 		rx_buf = to_cif_rx_buf(dbufs);
 		v4l2_info(&dev->v4l2_dev,
 			  "s_buf seq %d type %d, dma addr %x, %lld\n",
 			  dbufs->sequence, dbufs->type, (u32)rx_buf->dummy.dma_addr,
-			  ktime_get_ns());
+			  rkcif_time_get_ns(dev));
 	}
 	v4l2_subdev_call(sd, video, s_rx_buffer, dbufs, NULL);
 }
@@ -1766,9 +1768,9 @@
 		}
 		dev->rdbk_rx_buf[RDBK_M]->dbufs.sequence = dev->rdbk_rx_buf[RDBK_L]->dbufs.sequence;
 		dev->rdbk_rx_buf[RDBK_S]->dbufs.sequence = dev->rdbk_rx_buf[RDBK_L]->dbufs.sequence;
-		rkcif_s_rx_buffer(dev, &dev->rdbk_rx_buf[RDBK_L]->dbufs);
-		rkcif_s_rx_buffer(dev, &dev->rdbk_rx_buf[RDBK_M]->dbufs);
-		rkcif_s_rx_buffer(dev, &dev->rdbk_rx_buf[RDBK_S]->dbufs);
+		rkcif_s_rx_buffer(&dev->stream[RDBK_L], &dev->rdbk_rx_buf[RDBK_L]->dbufs);
+		rkcif_s_rx_buffer(&dev->stream[RDBK_M], &dev->rdbk_rx_buf[RDBK_M]->dbufs);
+		rkcif_s_rx_buffer(&dev->stream[RDBK_S], &dev->rdbk_rx_buf[RDBK_S]->dbufs);
 		rkcif_rdbk_with_tools(&dev->stream[RDBK_L], dev->rdbk_rx_buf[RDBK_L]);
 		rkcif_rdbk_with_tools(&dev->stream[RDBK_M], dev->rdbk_rx_buf[RDBK_M]);
 		rkcif_rdbk_with_tools(&dev->stream[RDBK_S], dev->rdbk_rx_buf[RDBK_S]);
@@ -1811,8 +1813,8 @@
 			}
 		}
 		dev->rdbk_rx_buf[RDBK_M]->dbufs.sequence = dev->rdbk_rx_buf[RDBK_L]->dbufs.sequence;
-		rkcif_s_rx_buffer(dev, &dev->rdbk_rx_buf[RDBK_L]->dbufs);
-		rkcif_s_rx_buffer(dev, &dev->rdbk_rx_buf[RDBK_M]->dbufs);
+		rkcif_s_rx_buffer(&dev->stream[RDBK_L], &dev->rdbk_rx_buf[RDBK_L]->dbufs);
+		rkcif_s_rx_buffer(&dev->stream[RDBK_M], &dev->rdbk_rx_buf[RDBK_M]->dbufs);
 		rkcif_rdbk_with_tools(&dev->stream[RDBK_L], dev->rdbk_rx_buf[RDBK_L]);
 		rkcif_rdbk_with_tools(&dev->stream[RDBK_M], dev->rdbk_rx_buf[RDBK_M]);
 		atomic_dec(&dev->stream[RDBK_L].buf_cnt);
@@ -1907,6 +1909,9 @@
 		} else {
 			rkcif_write_register(dev, frm0_addr_y, buff_addr_y);
 		}
+	} else {
+		if (stream->lack_buf_cnt < 2)
+			stream->lack_buf_cnt++;
 	}
 
 	if (!stream->next_buf_toisp) {
@@ -1932,10 +1937,33 @@
 		} else {
 			rkcif_write_register(dev, frm1_addr_y, buff_addr_y);
 		}
+	} else {
+		if (stream->lack_buf_cnt < 2)
+			stream->lack_buf_cnt++;
 	}
 
 	spin_unlock_irqrestore(&stream->vbq_lock, flags);
 	stream->buf_owner = RKCIF_DMAEN_BY_ISP;
+}
+
+static void rkcif_dphy_quick_stream(struct rkcif_device *dev, int on)
+{
+	struct rkcif_pipeline *p = NULL;
+	int j = 0;
+
+	if (dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_DPHY ||
+	    dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_CPHY ||
+	    dev->active_sensor->mbus.type == V4L2_MBUS_CCP2) {
+		p = &dev->pipe;
+		for (j = 0; j < p->num_subdevs; j++) {
+			if (p->subdevs[j] != dev->terminal_sensor.sd &&
+			    p->subdevs[j] != dev->active_sensor->sd) {
+				v4l2_subdev_call(p->subdevs[j], core, ioctl,
+						 RKMODULE_SET_QUICK_STREAM, &on);
+				break;
+			}
+		}
+	}
 }
 
 static int rkcif_assign_new_buffer_update_toisp(struct rkcif_stream *stream,
@@ -1950,6 +1978,7 @@
 	u32 frm_addr_y, buff_addr_y;
 	unsigned long flags;
 
+
 	if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY ||
 	    mbus_cfg->type == V4L2_MBUS_CSI2_CPHY ||
 	    mbus_cfg->type == V4L2_MBUS_CCP2) {
@@ -1961,13 +1990,19 @@
 			     get_dvp_reg_index_of_frm0_y_addr(channel_id) :
 			     get_dvp_reg_index_of_frm1_y_addr(channel_id);
 	}
+
 	spin_lock_irqsave(&stream->vbq_lock, flags);
+	if (stream->cur_skip_frame)
+		goto out_get_buf;
+	memset(&stream->toisp_buf_state, 0, sizeof(stream->toisp_buf_state));
 	if (!list_empty(&stream->rx_buf_head)) {
+		if (stream->curr_buf_toisp && stream->next_buf_toisp &&
+		    stream->curr_buf_toisp != stream->next_buf_toisp)
+			stream->toisp_buf_state.state = RKCIF_TOISP_BUF_ROTATE;
+		else
+			stream->toisp_buf_state.state = RKCIF_TOISP_BUF_LOSS;
 		if (stream->frame_phase == CIF_CSI_FRAME0_READY) {
-			if (stream->curr_buf_toisp == stream->next_buf_toisp)
-				active_buf = NULL;
-			else
-				active_buf = stream->curr_buf_toisp;
+			active_buf = stream->curr_buf_toisp;
 
 			buffer = list_first_entry(&stream->rx_buf_head,
 						 struct rkcif_rx_buffer, list);
@@ -1982,10 +2017,10 @@
 					active_buf->dbufs.is_first = true;
 				active_buf->dbufs.sequence = stream->frame_idx - 1;
 				active_buf->dbufs.timestamp = stream->readout.fs_timestamp;
-				active_buf->fe_timestamp = ktime_get_ns();
+				active_buf->fe_timestamp = rkcif_time_get_ns(dev);
 				stream->last_frame_idx = stream->frame_idx;
 				if (dev->hdr.hdr_mode == NO_HDR) {
-					rkcif_s_rx_buffer(dev, &active_buf->dbufs);
+					rkcif_s_rx_buffer(stream, &active_buf->dbufs);
 					if (dev->is_support_tools && stream->tools_vdev)
 						rkcif_rdbk_with_tools(stream, active_buf);
 					atomic_dec(&stream->buf_cnt);
@@ -1993,15 +2028,13 @@
 					rkcif_rdbk_frame_end_toisp(stream, active_buf);
 				}
 			} else {
-				rkcif_s_rx_buffer(dev, &active_buf->dbufs);
+				if (active_buf)
+					rkcif_s_rx_buffer(stream, &active_buf->dbufs);
 				if (dev->is_support_tools && stream->tools_vdev)
 					rkcif_rdbk_with_tools(stream, active_buf);
 			}
 		} else if (stream->frame_phase == CIF_CSI_FRAME1_READY) {
-			if (stream->curr_buf_toisp == stream->next_buf_toisp)
-				active_buf = NULL;
-			else
-				active_buf = stream->next_buf_toisp;
+			active_buf = stream->next_buf_toisp;
 			buffer = list_first_entry(&stream->rx_buf_head,
 						 struct rkcif_rx_buffer, list);
 			if (buffer) {
@@ -2015,10 +2048,10 @@
 					active_buf->dbufs.is_first = true;
 				active_buf->dbufs.sequence = stream->frame_idx - 1;
 				active_buf->dbufs.timestamp = stream->readout.fs_timestamp;
-				active_buf->fe_timestamp = ktime_get_ns();
+				active_buf->fe_timestamp = rkcif_time_get_ns(dev);
 				stream->last_frame_idx = stream->frame_idx;
 				if (dev->hdr.hdr_mode == NO_HDR) {
-					rkcif_s_rx_buffer(dev, &active_buf->dbufs);
+					rkcif_s_rx_buffer(stream, &active_buf->dbufs);
 					if (dev->is_support_tools && stream->tools_vdev)
 						rkcif_rdbk_with_tools(stream, active_buf);
 					atomic_dec(&stream->buf_cnt);
@@ -2026,7 +2059,8 @@
 					rkcif_rdbk_frame_end_toisp(stream, active_buf);
 				}
 			} else {
-				rkcif_s_rx_buffer(dev, &active_buf->dbufs);
+				if (active_buf)
+					rkcif_s_rx_buffer(stream, &active_buf->dbufs);
 				if (dev->is_support_tools && stream->tools_vdev)
 					rkcif_rdbk_with_tools(stream, active_buf);
 			}
@@ -2041,10 +2075,8 @@
 		if (dev->hw_dev->dummy_buf.vaddr) {
 			if (stream->frame_phase == CIF_CSI_FRAME0_READY) {
 				active_buf = stream->curr_buf_toisp;
-				stream->curr_buf_toisp = NULL;
 			} else {
 				active_buf = stream->next_buf_toisp;
-				stream->next_buf_toisp = NULL;
 			}
 		} else if (stream->curr_buf_toisp && stream->next_buf_toisp &&
 			   stream->curr_buf_toisp != stream->next_buf_toisp) {
@@ -2057,23 +2089,30 @@
 				stream->next_buf_toisp = stream->curr_buf_toisp;
 				buffer = stream->curr_buf_toisp;
 			}
+			stream->toisp_buf_state.state = RKCIF_TOISP_BUF_THESAME;
 			if (stream->cifdev->rdbk_debug)
 				v4l2_info(&stream->cifdev->v4l2_dev,
 					  "stream[%d] hold buf %x\n",
 					  stream->id,
 					  (u32)stream->next_buf_toisp->dummy.dma_addr);
+		} else {
+			stream->toisp_buf_state.state = RKCIF_TOISP_BUF_LOSS;
+			if (stream->is_single_cap) {
+				active_buf = stream->curr_buf_toisp;
+				stream->curr_buf_toisp = NULL;
+				stream->next_buf_toisp = NULL;
+			}
 		}
+
 		if (active_buf) {
 			if (stream->frame_idx == 1)
 				active_buf->dbufs.is_first = true;
 			active_buf->dbufs.sequence = stream->frame_idx - 1;
 			active_buf->dbufs.timestamp = stream->readout.fs_timestamp;
-			active_buf->fe_timestamp = ktime_get_ns();
+			active_buf->fe_timestamp = rkcif_time_get_ns(dev);
 			stream->last_frame_idx = stream->frame_idx;
 			if (dev->hdr.hdr_mode == NO_HDR) {
-				rkcif_s_rx_buffer(dev, &active_buf->dbufs);
-				if (dev->is_support_tools && stream->tools_vdev)
-					rkcif_rdbk_with_tools(stream, active_buf);
+				rkcif_s_rx_buffer(stream, &active_buf->dbufs);
 				atomic_dec(&stream->buf_cnt);
 			} else {
 				rkcif_rdbk_frame_end_toisp(stream, active_buf);
@@ -2085,10 +2124,9 @@
 					  stream->id,
 					  stream->frame_idx - 1);
 		}
-		if (dev->is_support_tools && stream->tools_vdev && stream->curr_buf_toisp)
-			rkcif_rdbk_with_tools(stream, stream->curr_buf_toisp);
+		if (dev->is_support_tools && stream->tools_vdev && active_buf)
+			rkcif_rdbk_with_tools(stream, active_buf);
 	}
-
 out_get_buf:
 	stream->frame_phase_cache = stream->frame_phase;
 	if (buffer) {
@@ -2145,9 +2183,12 @@
 	u64 cur_time = 0;
 	int frame_phase = 0;
 	int frame_phase_next = 0;
-	bool is_early_update = false;
 
-	if (stream->curr_buf_toisp != stream->next_buf_toisp) {
+	if (stream->toisp_buf_state.state == RKCIF_TOISP_BUF_ROTATE ||
+	    (stream->toisp_buf_state.state == RKCIF_TOISP_BUF_THESAME &&
+	     stream->toisp_buf_state.check_cnt >= 1) ||
+	    (stream->toisp_buf_state.state == RKCIF_TOISP_BUF_LOSS &&
+	     stream->toisp_buf_state.check_cnt >= 2)) {
 		if (dev->rdbk_debug > 2 &&
 		    stream->frame_idx < 15)
 			v4l2_info(&dev->v4l2_dev,
@@ -2161,20 +2202,26 @@
 		dev->sensor_linetime = rkcif_get_linetime(stream);
 	vblank = rkcif_get_sensor_vblank(dev);
 	vblank_ns = vblank * dev->sensor_linetime;
-	cur_time = ktime_get_ns();
+	cur_time = rkcif_time_get_ns(dev);
 
-	if (dev->chip_id > CHIP_RK3568_CIF &&
-	    dev->hdr.hdr_mode == NO_HDR &&
-	    cur_time - stream->readout.fe_timestamp < (vblank_ns - 500000) &&
-	    stream->lack_buf_cnt == 2 &&
-	    stream->frame_idx > stream->last_frame_idx) {
-		is_early_update = true;
-		frame_phase = stream->frame_phase & CIF_CSI_FRAME0_READY ?
-			CIF_CSI_FRAME1_READY : CIF_CSI_FRAME0_READY;
-		frame_phase_next = stream->frame_phase & CIF_CSI_FRAME0_READY ?
-			CIF_CSI_FRAME0_READY : CIF_CSI_FRAME1_READY;
-	} else {
+	if (stream->toisp_buf_state.state == RKCIF_TOISP_BUF_THESAME) {
 		frame_phase = stream->frame_phase;
+	} else {
+		if (stream->toisp_buf_state.state == RKCIF_TOISP_BUF_LOSS &&
+		    stream->toisp_buf_state.check_cnt == 0 &&
+		    cur_time - stream->readout.fe_timestamp < (vblank_ns - 500000)) {
+			stream->toisp_buf_state.is_early_update = true;
+			frame_phase = stream->frame_phase & CIF_CSI_FRAME0_READY ?
+				CIF_CSI_FRAME1_READY : CIF_CSI_FRAME0_READY;
+			frame_phase_next = stream->frame_phase & CIF_CSI_FRAME0_READY ?
+				CIF_CSI_FRAME0_READY : CIF_CSI_FRAME1_READY;
+		} else {
+			if (stream->toisp_buf_state.check_cnt == 1 &&
+			    (!stream->toisp_buf_state.is_early_update))
+				return;
+			frame_phase = stream->frame_phase;
+			stream->toisp_buf_state.is_early_update = false;
+		}
 	}
 	if (dev->rdbk_debug > 2 &&
 	    stream->frame_idx < 15)
@@ -2247,7 +2294,7 @@
 		if (stream->lack_buf_cnt)
 			stream->lack_buf_cnt--;
 	}
-	if (is_early_update) {
+	if (stream->toisp_buf_state.is_early_update) {
 		if (dev->rdbk_debug > 1 &&
 		    stream->frame_idx < 15)
 			v4l2_info(&dev->v4l2_dev,
@@ -2263,7 +2310,7 @@
 			active_buf->dbufs.sequence = stream->frame_idx - 1;
 			active_buf->dbufs.timestamp = stream->readout.fs_timestamp;
 			stream->last_frame_idx = stream->frame_idx;
-			rkcif_s_rx_buffer(dev, &active_buf->dbufs);
+			rkcif_s_rx_buffer(stream, &active_buf->dbufs);
 		}
 		if (dev->hw_dev->dummy_buf.vaddr)
 			return;
@@ -2290,6 +2337,7 @@
 			rkcif_write_register(dev, frm_addr_y, buff_addr_y);
 		}
 	}
+	stream->toisp_buf_state.check_cnt++;
 }
 
 static void rkcif_assign_new_buffer_init(struct rkcif_stream *stream,
@@ -2304,6 +2352,7 @@
 	struct rkcif_dummy_buffer *dummy_buf = &dev->hw_dev->dummy_buf;
 	struct csi_channel_info *channel = &dev->channels[channel_id];
 
+	stream->lack_buf_cnt = 0;
 	if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY ||
 	    mbus_cfg->type == V4L2_MBUS_CSI2_CPHY ||
 	    mbus_cfg->type == V4L2_MBUS_CCP2) {
@@ -2398,6 +2447,8 @@
 				v4l2_dbg(4, rkcif_debug, &dev->v4l2_dev, "%s %d, stream[%d] buf idx %d\n",
 					 __func__, __LINE__, stream->id, stream->next_buf->vb.vb2_buf.index);
 				list_del(&stream->next_buf->queue);
+			} else if (stream->curr_buf) {
+				stream->next_buf = stream->curr_buf;
 			}
 		}
 
@@ -2504,18 +2555,9 @@
 			      get_dvp_reg_index_of_frm1_uv_addr(channel_id);
 	}
 
-	if (stream->to_stop_dma) {
-		if (stream->dma_en & RKCIF_DMAEN_BY_ISP) {
-			v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev, "%s %d\n", __func__, __LINE__);
-			goto stop_dma;
-		} else {
-			if (stream->frame_phase == CIF_CSI_FRAME0_READY)
-				stream->curr_buf = NULL;
-			else
-				stream->next_buf = NULL;
-			v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev, "%s %d\n", __func__, __LINE__);
-			return -EINVAL;
-		}
+	if (stream->to_stop_dma && (stream->dma_en & RKCIF_DMAEN_BY_ISP)) {
+		v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev, "%s %d\n", __func__, __LINE__);
+		goto stop_dma;
 	}
 
 	spin_lock_irqsave(&stream->vbq_lock, flags);
@@ -2561,9 +2603,9 @@
 				}
 			}
 		}
-	} else if (!(stream->dma_en & RKCIF_DMAEN_BY_ISP)) {
+	} else {
 		buffer = NULL;
-		if (dummy_buf->vaddr) {
+		if (!(stream->cur_stream_mode & RKCIF_STREAM_MODE_TOISP) && dummy_buf->vaddr) {
 			if (stream->frame_phase == CIF_CSI_FRAME0_READY) {
 				stream->curr_buf  = NULL;
 			} else if (stream->frame_phase == CIF_CSI_FRAME1_READY) {
@@ -2574,12 +2616,11 @@
 					stream->next_buf = NULL;
 				}
 			}
-		} else if (stream->curr_buf && stream->next_buf &&
-			   stream->curr_buf != stream->next_buf) {
-			if (stream->frame_phase == CIF_CSI_FRAME0_READY) {
+		} else if (stream->curr_buf != stream->next_buf) {
+			if (stream->frame_phase == CIF_CSI_FRAME0_READY && stream->next_buf) {
 				stream->curr_buf = stream->next_buf;
 				buffer = stream->next_buf;
-			} else if (stream->frame_phase == CIF_CSI_FRAME1_READY) {
+			} else if (stream->frame_phase == CIF_CSI_FRAME1_READY && stream->curr_buf) {
 				stream->next_buf = stream->curr_buf;
 				buffer = stream->curr_buf;
 			}
@@ -2644,66 +2685,7 @@
 				}
 			}
 			if (dbufs)
-				rkcif_s_rx_buffer(dev, dbufs);
-		}
-	} else {
-		if (stream->dma_en & RKCIF_DMAEN_BY_ISP) {
-			buff_addr_y = stream->curr_buf_toisp->dummy.dma_addr;
-			if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE)
-				rkcif_write_buff_addr_multi_dev_combine(stream,
-									frm_addr_y, 0,
-									buff_addr_y, 0, false);
-			else
-				rkcif_write_register(dev, frm_addr_y, buff_addr_y);
-			if (stream->frame_phase == CIF_CSI_FRAME0_READY &&
-			    stream->next_buf)
-				dbuf = stream->next_buf->dbuf;
-			else if (stream->frame_phase == CIF_CSI_FRAME1_READY &&
-				 stream->curr_buf)
-				dbuf = stream->curr_buf->dbuf;
-
-			if (dbuf) {
-				list_for_each_entry(dbufs, &stream->rx_buf_head_vicap, list)
-					if (dbufs->dbuf == dbuf)
-						break;
-			} else {
-				dbufs = &stream->curr_buf_toisp->dbufs;
-			}
-			rkcif_s_rx_buffer(dev, dbufs);
-			if (stream->curr_buf && stream->frame_phase == CIF_CSI_FRAME0_READY) {
-				stream->curr_buf = NULL;
-				if (stream->buf_replace_cnt)
-					stream->buf_replace_cnt--;
-			} else if (stream->next_buf && stream->frame_phase == CIF_CSI_FRAME1_READY) {
-				stream->next_buf = NULL;
-				if (stream->buf_replace_cnt)
-					stream->buf_replace_cnt--;
-			}
-		} else if (dummy_buf->vaddr) {
-
-			if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
-				buff_addr_y = dummy_buf->dma_addr;
-				buff_addr_cbcr = dummy_buf->dma_addr;
-				rkcif_write_buff_addr_multi_dev_combine(stream,
-									frm_addr_y,
-									frm_addr_uv,
-									buff_addr_y,
-									buff_addr_cbcr,
-									true);
-			} else {
-				rkcif_write_register(dev, frm_addr_y, dummy_buf->dma_addr);
-				if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW)
-					rkcif_write_register(dev, frm_addr_uv, dummy_buf->dma_addr);
-			}
-			dev->err_state |= (RKCIF_ERR_ID0_NOT_BUF << stream->id);
-			dev->irq_stats.not_active_buf_cnt[stream->id]++;
-
-		} else {
-			ret = -EINVAL;
-			stream->curr_buf = NULL;
-			stream->next_buf = NULL;
-			dev->err_state |= (RKCIF_ERR_ID0_NOT_BUF << stream->id);
-			dev->irq_stats.not_active_buf_cnt[stream->id]++;
+				rkcif_s_rx_buffer(stream, dbufs);
 		}
 	}
 	spin_unlock_irqrestore(&stream->vbq_lock, flags);
@@ -2733,7 +2715,7 @@
 			dbufs = &stream->curr_buf_toisp->dbufs;
 		}
 		if (dbufs)
-			rkcif_s_rx_buffer(dev, dbufs);
+			rkcif_s_rx_buffer(stream, dbufs);
 
 		if (stream->frame_phase == CIF_CSI_FRAME0_READY &&
 		    stream->curr_buf) {
@@ -2898,7 +2880,13 @@
 	int frame_phase = 0;
 
 	spin_lock_irqsave(&stream->vbq_lock, flags);
+	memset(&stream->toisp_buf_state, 0, sizeof(stream->toisp_buf_state));
 	if (!list_empty(&stream->rx_buf_head)) {
+		if (stream->curr_buf_toisp && stream->next_buf_toisp &&
+		    stream->curr_buf_toisp != stream->next_buf_toisp)
+			stream->toisp_buf_state.state = RKCIF_TOISP_BUF_ROTATE;
+		else
+			stream->toisp_buf_state.state = RKCIF_TOISP_BUF_LOSS;
 		if (stream->line_int_cnt % 2) {
 			buffer = list_first_entry(&stream->rx_buf_head,
 						 struct rkcif_rx_buffer, list);
@@ -2934,8 +2922,10 @@
 					  "stream[%d] hold buf %x\n",
 					  stream->id,
 					  (u32)stream->next_buf_toisp->dummy.dma_addr);
+			stream->toisp_buf_state.state = RKCIF_TOISP_BUF_THESAME;
 		} else {
 			ret = -EINVAL;
+			stream->toisp_buf_state.state = RKCIF_TOISP_BUF_LOSS;
 		}
 	}
 	if (buffer) {
@@ -3647,6 +3637,7 @@
 		val &= ~CSI_HIGH_ALIGN;
 	rkcif_write_register(dev, get_reg_index_of_id_ctrl0(channel->id), val);
 
+	dev->intr_mask = rkcif_read_register(dev, CIF_REG_MIPI_LVDS_INTEN);
 	return 0;
 }
 
@@ -4035,6 +4026,7 @@
 						       RKCIF_YUV_ADDR_STATE_INIT,
 						       channel->id);
 	}
+	dev->intr_mask = rkcif_read_register(dev, CIF_REG_MIPI_LVDS_INTEN);
 	return 0;
 }
 
@@ -4557,7 +4549,8 @@
 		list_add_tail(&dbufs->list, &stream->rx_buf_head_vicap);
 	}
 	if (stream->cifdev->workmode == RKCIF_WORKMODE_PINGPONG &&
-	    stream->lack_buf_cnt)
+	    stream->lack_buf_cnt &&
+	    stream->cur_stream_mode & RKCIF_STREAM_MODE_CAPTURE)
 		rkcif_check_buffer_update_pingpong(stream, stream->id);
 	v4l2_dbg(3, rkcif_debug, &stream->cifdev->v4l2_dev,
 		 "stream[%d] buf queue, index: %d, dma_addr 0x%x\n",
@@ -4570,11 +4563,54 @@
 	struct rkcif_rx_buffer *buf;
 	struct rkcif_device *dev = stream->cifdev;
 	struct sditf_priv *priv = dev->sditf[0];
+	struct v4l2_subdev *sd;
 	int i = 0;
 	unsigned long flags;
+	phys_addr_t resmem_free_start;
+	phys_addr_t resmem_free_end;
+	u32 share_head_size = 0;
 
 	if (!priv)
 		return;
+
+	sd = get_rkisp_sd(dev->sditf[0]);
+	if (!sd)
+		return;
+
+	if (dev->is_rtt_suspend && dev->is_thunderboot) {
+		stream->curr_buf_toisp = NULL;
+		stream->next_buf_toisp = NULL;
+		INIT_LIST_HEAD(&stream->rx_buf_head);
+
+		for (i = 0; i < buf_num; i++) {
+			buf = &stream->rx_buf[i];
+			if (buf->dbufs.is_init)
+				v4l2_subdev_call(sd, core, ioctl,
+						 RKISP_VICAP_CMD_RX_BUFFER_FREE, &buf->dbufs);
+			buf->dummy.is_free = true;
+		}
+
+		if (IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) {
+			share_head_size = dev->thunderboot_sensor_num * sizeof(struct rkisp32_thunderboot_resmem_head);
+			if (share_head_size != dev->share_mem_size)
+				v4l2_info(&stream->cifdev->v4l2_dev,
+					  "share mem head error, rtt head size %d, arm head size %d\n",
+					  dev->share_mem_size, share_head_size);
+			resmem_free_start = dev->resmem_pa + share_head_size + dev->nr_buf_size;
+			resmem_free_end = dev->resmem_pa + dev->resmem_size;
+			v4l2_info(&stream->cifdev->v4l2_dev,
+				  "free reserved mem start 0x%x, end 0x%x, share_head_size 0x%x, nr_buf_size 0x%x\n",
+				  (u32)resmem_free_start, (u32)resmem_free_end, share_head_size, dev->nr_buf_size);
+			free_reserved_area(phys_to_virt(resmem_free_start),
+					   phys_to_virt(resmem_free_end),
+					   -1, "rkisp_thunderboot");
+		}
+		atomic_set(&stream->buf_cnt, 0);
+		stream->total_buf_num = 0;
+		stream->rx_buf_num = 0;
+
+		return;
+	}
 
 	spin_lock_irqsave(&stream->vbq_lock, flags);
 	stream->curr_buf_toisp = NULL;
@@ -4588,6 +4624,9 @@
 		buf = &stream->rx_buf[i];
 		if (buf->dummy.is_free)
 			continue;
+		if (buf->dbufs.is_init)
+			v4l2_subdev_call(sd, core, ioctl,
+					 RKISP_VICAP_CMD_RX_BUFFER_FREE, &buf->dbufs);
 		if (!dev->is_thunderboot)
 			rkcif_free_buffer(dev, &buf->dummy);
 		else
@@ -4595,6 +4634,7 @@
 		atomic_dec(&stream->buf_cnt);
 		stream->total_buf_num--;
 	}
+	stream->rx_buf_num = 0;
 
 	if (dev->is_thunderboot) {
 		spin_unlock_irqrestore(&dev->buffree_lock, flags);
@@ -4605,6 +4645,7 @@
 		 "free rx_buf, buf_num %d\n", buf_num);
 }
 
+static void rkcif_get_resmem_head(struct rkcif_device *cif_dev);
 int rkcif_init_rx_buf(struct rkcif_stream *stream, int buf_num)
 {
 	struct rkcif_device *dev = stream->cifdev;
@@ -4652,10 +4693,12 @@
 		dummy->is_need_vaddr = true;
 		dummy->is_need_dbuf = true;
 		if (dev->is_thunderboot) {
+			if (i == 0)
+				rkcif_get_resmem_head(dev);
 			buf->buf_idx = i;
 			ret = rkcif_alloc_reserved_mem_buf(dev, buf);
 			if (ret) {
-				priv->buf_num = i;
+				stream->rx_buf_num = i;
 				v4l2_info(&dev->v4l2_dev,
 					 "reserved mem support alloc buf num %d, require buf num %d\n",
 					 i, buf_num);
@@ -4668,7 +4711,7 @@
 		} else {
 			ret = rkcif_alloc_buffer(dev, dummy);
 			if (ret) {
-				priv->buf_num = i;
+				stream->rx_buf_num = i;
 				v4l2_info(&dev->v4l2_dev,
 					 "alloc buf num %d, require buf num %d\n",
 					 i, buf_num);
@@ -4684,15 +4727,17 @@
 			buf->dbufs.is_uncompact = false;
 		else
 			buf->dbufs.is_uncompact = true;
-		if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE && i == 0) {
+		if (priv && i == 0) {
 			buf->dbufs.is_first = true;
-			rkcif_s_rx_buffer(dev, &buf->dbufs);
+			if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE)
+				rkcif_s_rx_buffer(stream, &buf->dbufs);
 		}
 		i++;
 		if (!dev->is_thunderboot && i >= buf_num) {
+			stream->rx_buf_num = buf_num;
 			break;
 		} else if (i >= RKISP_VICAP_BUF_CNT_MAX) {
-			priv->buf_num = i;
+			stream->rx_buf_num = i;
 			v4l2_info(&dev->v4l2_dev,
 				  "reserved mem alloc buf num %d\n", i);
 			break;
@@ -4701,9 +4746,9 @@
 			"init rx_buf,dma_addr 0x%llx size: 0x%x\n",
 			(u64)dummy->dma_addr, pixm->plane_fmt[0].sizeimage);
 	}
-	if (priv->buf_num) {
-		stream->total_buf_num = priv->buf_num;
-		atomic_set(&stream->buf_cnt, priv->buf_num);
+	if (stream->rx_buf_num) {
+		stream->total_buf_num = stream->rx_buf_num;
+		atomic_set(&stream->buf_cnt, stream->rx_buf_num);
 		return 0;
 	} else {
 		return -EINVAL;
@@ -4735,7 +4780,9 @@
 						       pad, enum_frame_interval,
 						       NULL, &fie);
 				if (!ret) {
-					if (fie.code == MEDIA_BUS_FMT_RGB888_1X24)
+					if (fie.code == MEDIA_BUS_FMT_RGB888_1X24 ||
+					    fie.code == MEDIA_BUS_FMT_BGR888_1X24 ||
+					    fie.code == MEDIA_BUS_FMT_GBR888_1X24)
 						size = fie.width * fie.height * 3;
 					else
 						size = fie.width * fie.height * 2;
@@ -4758,7 +4805,9 @@
 		ret = v4l2_subdev_call(dev->terminal_sensor.sd,
 				       pad, get_fmt, NULL, &fmt);
 		if (!ret) {
-			if (fmt.format.code == MEDIA_BUS_FMT_RGB888_1X24)
+			if (fmt.format.code == MEDIA_BUS_FMT_RGB888_1X24 ||
+			    fmt.format.code == MEDIA_BUS_FMT_BGR888_1X24 ||
+			    fmt.format.code == MEDIA_BUS_FMT_GBR888_1X24)
 				size = fmt.format.width  * fmt.format.height * 3;
 			else
 				size = fmt.format.width * fmt.format.height * 2;
@@ -4964,7 +5013,7 @@
 				spin_lock_irqsave(&stream->fps_lock, flags);
 				fs_time = stream->readout.fs_timestamp;
 				spin_unlock_irqrestore(&stream->fps_lock, flags);
-				cur_time = ktime_get_ns();
+				cur_time = rkcif_time_get_ns(dev);
 				if (cur_time > fs_time &&
 				    cur_time - fs_time < (frame_time_ns - 10000000)) {
 					spin_lock_irqsave(&stream->vbq_lock, flags);
@@ -5024,12 +5073,12 @@
 			list_add_tail(&stream->next_buf->queue, &stream->buf_head);
 		spin_unlock_irqrestore(&stream->vbq_lock, flags);
 
-		stream->curr_buf = NULL;
-		stream->next_buf = NULL;
-
 		if (dev->hdr.hdr_mode == HDR_X2 ||
 		    dev->hdr.hdr_mode == HDR_X3)
 			rkcif_release_rdbk_buf(stream);
+
+		stream->curr_buf = NULL;
+		stream->next_buf = NULL;
 
 		rkcif_rx_buffer_free(stream);
 		list_for_each_entry(buf, &stream->buf_head, queue) {
@@ -5079,8 +5128,10 @@
 			}
 		}
 		mutex_unlock(&hw_dev->dev_lock);
-		if (dev->can_be_reset && dev->chip_id >= CHIP_RK3588_CIF)
+		if (dev->can_be_reset && dev->chip_id >= CHIP_RK3588_CIF) {
 			rkcif_do_soft_reset(dev);
+			atomic_set(&dev->streamoff_cnt, 0);
+		}
 		if (dev->can_be_reset && can_reset) {
 			dev->can_be_reset = false;
 			dev->reset_work_cancel = true;
@@ -5938,6 +5989,7 @@
 		rkcif_write_register(dev, CIF_REG_DVP_CTRL,
 				     AXI_BURST_16 | workmode | ENABLE_CAPTURE);
 	}
+	dev->intr_mask = rkcif_read_register(dev, CIF_REG_DVP_INTSTAT);
 #if IS_ENABLED(CONFIG_CPU_RV1106)
 	rv1106_sdmmc_put_lock();
 #endif
@@ -6121,6 +6173,7 @@
 	int rkmodule_stream_seq = RKMODULE_START_STREAM_DEFAULT;
 	int ret;
 	int i = 0;
+	u32 skip_frame = 0;
 
 	v4l2_info(&dev->v4l2_dev, "stream[%d] start streaming\n", stream->id);
 
@@ -6248,6 +6301,15 @@
 			if (ret < 0)
 				goto destroy_buf;
 		}
+		ret = v4l2_subdev_call(terminal_sensor->sd,
+				       core, ioctl,
+				       RKMODULE_GET_SKIP_FRAME,
+				       &skip_frame);
+		if (!ret && skip_frame < RKCIF_SKIP_FRAME_MAX)
+			stream->skip_frame = skip_frame;
+		else
+			stream->skip_frame = 0;
+		stream->cur_skip_frame = stream->skip_frame;
 	}
 	if (dev->chip_id >= CHIP_RK1808_CIF) {
 		if (dev->active_sensor  &&
@@ -6632,7 +6694,11 @@
 	stream->buf_owner = 0;
 	stream->buf_replace_cnt = 0;
 	stream->is_stop_capture = false;
+	stream->is_single_cap = false;
 	atomic_set(&stream->buf_cnt, 0);
+	stream->rx_buf_num = 0;
+	init_completion(&stream->stop_complete);
+	stream->is_wait_stop_complete = false;
 }
 
 static int rkcif_fh_open(struct file *filp)
@@ -7218,8 +7284,18 @@
 			skip_n);
 }
 
+static bool rkcif_check_can_be_online(struct rkcif_device *cif_dev)
+{
+	if (cif_dev->sditf[0] == NULL || cif_dev->sditf[0]->mode.name == NULL ||
+	    (cif_dev->chip_id == CHIP_RV1106_CIF &&
+	     strstr(cif_dev->sditf[0]->mode.name, "unite")))
+		return false;
+	return true;
+}
+
 static int rkcif_do_reset_work(struct rkcif_device *cif_dev,
 			       enum rkmodule_reset_src reset_src);
+static bool rkcif_check_single_dev_stream_on(struct rkcif_hw *hw);
 
 static long rkcif_ioctl_default(struct file *file, void *fh,
 				bool valid_prio, unsigned int cmd, void *arg)
@@ -7231,6 +7307,13 @@
 	struct csi_channel_info csi_info;
 	struct rkcif_fps fps;
 	int reset_src;
+	struct rkcif_quick_stream_param *stream_param;
+	bool is_single_dev = false;
+	struct v4l2_subdev *sd;
+	int ret = -EINVAL;
+	int i = 0;
+	int stream_num = 0;
+	bool is_can_be_online = false;
 
 	switch (cmd) {
 	case RKCIF_CMD_GET_CSI_MEMORY_MODE:
@@ -7279,6 +7362,91 @@
 	case RKCIF_CMD_SET_RESET:
 		reset_src = *(int *)arg;
 		return rkcif_do_reset_work(dev, reset_src);
+	case RKCIF_CMD_SET_QUICK_STREAM:
+		stream_param = (struct rkcif_quick_stream_param *)arg;
+		if (!dev->sditf[0])
+			return -EINVAL;
+		if (dev->hdr.hdr_mode == HDR_X2)
+			stream_num = 2;
+		else if (dev->hdr.hdr_mode == HDR_X3)
+			stream_num = 3;
+		else
+			stream_num = 1;
+		if (stream_param->on) {
+			for (i = 0; i < stream_num; i++)
+				dev->stream[i].cur_skip_frame = dev->stream[i].skip_frame;
+			is_single_dev = rkcif_check_single_dev_stream_on(dev->hw_dev);
+			is_can_be_online = rkcif_check_can_be_online(dev);
+			if (is_single_dev && is_can_be_online) {
+				for (i = 0; i < stream_num - 1; i++) {
+					dev->stream[i].to_en_dma = RKCIF_DMAEN_BY_ISP;
+					rkcif_enable_dma_capture(&dev->stream[i], true);
+				}
+				dev->sditf[0]->mode.rdbk_mode = RKISP_VICAP_ONLINE;
+				sditf_change_to_online(dev->sditf[0]);
+				sd = get_rkisp_sd(dev->sditf[0]);
+				if (sd)
+					ret = v4l2_subdev_call(sd, core, ioctl,
+							       RKISP_VICAP_CMD_MODE, &dev->sditf[0]->mode);
+				if (ret) {
+					v4l2_err(&dev->v4l2_dev, "set isp work mode online fail\n");
+					return -EINVAL;
+				}
+			} else {
+				sditf_disable_immediately(dev->sditf[0]);
+				dev->sditf[0]->mode.rdbk_mode = RKISP_VICAP_RDBK_AUTO;
+				sd = get_rkisp_sd(dev->sditf[0]);
+				if (sd)
+					ret = v4l2_subdev_call(sd, core, ioctl,
+							       RKISP_VICAP_CMD_MODE, &dev->sditf[0]->mode);
+				for (i = 0; i < stream_num; i++) {
+					if (dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO)
+						dev->stream[i].to_en_dma = RKCIF_DMAEN_BY_ISP;
+					else
+						dev->stream[i].to_en_dma = RKCIF_DMAEN_BY_VICAP;
+					rkcif_enable_dma_capture(&dev->stream[i], true);
+				}
+			}
+			rkcif_dphy_quick_stream(dev, stream_param->on);
+			v4l2_subdev_call(dev->terminal_sensor.sd, core, ioctl,
+					 RKMODULE_SET_QUICK_STREAM, &stream_param->on);
+		} else {
+			if (dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_ONLINE) {
+				for (i = 0; i < stream_num - 1; i++) {
+					reinit_completion(&dev->stream[i].stop_complete);
+					dev->stream[i].is_wait_stop_complete = true;
+					dev->stream[i].to_stop_dma = RKCIF_DMAEN_BY_ISP;
+					wait_for_completion_timeout(&dev->stream[i].stop_complete,
+								    msecs_to_jiffies(RKCIF_STOP_MAX_WAIT_TIME_MS));
+				}
+				stream->cifdev->sensor_state = stream_param->on;
+				stream->cifdev->sensor_state_change = true;
+				dev->stream[i].is_wait_stop_complete = true;
+				wait_for_completion_timeout(&dev->stream[i].stop_complete,
+							    msecs_to_jiffies(RKCIF_STOP_MAX_WAIT_TIME_MS));
+			} else {
+				for (i = 0; i < stream_num; i++) {
+					dev->stream[i].is_wait_stop_complete = true;
+					reinit_completion(&dev->stream[i].stop_complete);
+					if (dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO)
+						dev->stream[i].to_stop_dma = RKCIF_DMAEN_BY_ISP;
+					else
+						dev->stream[i].to_stop_dma = RKCIF_DMAEN_BY_VICAP;
+					wait_for_completion_timeout(&dev->stream[i].stop_complete,
+								    msecs_to_jiffies(RKCIF_STOP_MAX_WAIT_TIME_MS));
+				}
+				rkcif_dphy_quick_stream(dev, stream_param->on);
+				v4l2_subdev_call(dev->terminal_sensor.sd, core, ioctl,
+						 RKMODULE_SET_QUICK_STREAM, &stream_param->on);
+			}
+			stream_param->frame_num = dev->stream[0].frame_idx - 1;
+			if (!dev->is_rtt_suspend) {
+				dev->resume_mode = stream_param->resume_mode;
+				v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev,
+					 "set resume mode %d\n", dev->resume_mode);
+			}
+		}
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -8082,7 +8250,7 @@
 		timer->csi2_err_triggered_cnt++;
 		if (timer->csi2_err_triggered_cnt == 1) {
 			is_first_err = true;
-			timer->csi2_first_err_timestamp = ktime_get_ns();
+			timer->csi2_first_err_timestamp = rkcif_time_get_ns(dev);
 		}
 
 		is_assign_triggered = true;
@@ -8094,7 +8262,7 @@
 
 	if (!is_first_err) {
 		if (timer->csi2_err_triggered_cnt >= 1) {
-			cur_time = ktime_get_ns();
+			cur_time = rkcif_time_get_ns(dev);
 			diff_time = cur_time - timer->csi2_first_err_timestamp;
 			diff_time = div_u64(diff_time, 1000000);
 			if (diff_time >= timer->err_time_interval) {
@@ -8437,7 +8605,7 @@
 				v4l2_err(&dev->v4l2_dev,
 					 "s/m/l frame err, timestamp s:%lld m:%lld l:%lld\n",
 					 s_ts, m_ts, l_ts);
-				goto RDBK_FRM_UNMATCH;
+				return;
 			}
 
 			if ((m_ts - l_ts) > time || (s_ts - m_ts) > time) {
@@ -8458,7 +8626,7 @@
 					v4l2_err(&dev->v4l2_dev,
 						 "timestamp no match, s:%lld m:%lld l:%lld, fps:%d\n",
 						 s_ts, m_ts, l_ts, fps);
-					goto RDBK_FRM_UNMATCH;
+					return;
 				}
 			}
 			dev->rdbk_buf[RDBK_M]->vb.sequence = dev->rdbk_buf[RDBK_L]->vb.sequence;
@@ -8487,7 +8655,7 @@
 				v4l2_err(&dev->v4l2_dev, "lost medium frames\n");
 			if (!dev->rdbk_buf[RDBK_S])
 				v4l2_err(&dev->v4l2_dev, "lost short frames\n");
-			goto RDBK_FRM_UNMATCH;
+			return;
 		}
 	} else if (dev->hdr.hdr_mode == HDR_X2) {
 		if (dev->rdbk_buf[RDBK_L] && dev->rdbk_buf[RDBK_M]) {
@@ -8498,7 +8666,7 @@
 				v4l2_err(&dev->v4l2_dev,
 					 "s/l frame err, timestamp s:%lld l:%lld\n",
 					 s_ts, l_ts);
-				goto RDBK_FRM_UNMATCH;
+				return;
 			}
 
 			if ((s_ts - l_ts) > time) {
@@ -8518,7 +8686,7 @@
 					v4l2_err(&dev->v4l2_dev,
 						 "timestamp no match, s:%lld l:%lld, fps:%d\n",
 						 s_ts, l_ts, fps);
-					goto RDBK_FRM_UNMATCH;
+					return;
 				}
 			}
 			dev->rdbk_buf[RDBK_M]->vb.sequence = dev->rdbk_buf[RDBK_L]->vb.sequence;
@@ -8542,27 +8710,8 @@
 				v4l2_err(&dev->v4l2_dev, "lost long frames\n");
 			if (!dev->rdbk_buf[RDBK_M])
 				v4l2_err(&dev->v4l2_dev, "lost short frames\n");
-			goto RDBK_FRM_UNMATCH;
+			return;
 		}
-	}
-
-	dev->rdbk_buf[RDBK_L] = NULL;
-	dev->rdbk_buf[RDBK_M] = NULL;
-	dev->rdbk_buf[RDBK_S] = NULL;
-	return;
-
-RDBK_FRM_UNMATCH:
-	if (dev->rdbk_buf[RDBK_L]) {
-		dev->rdbk_buf[RDBK_L]->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
-		rkcif_buf_queue(&dev->rdbk_buf[RDBK_L]->vb.vb2_buf);
-	}
-	if (dev->rdbk_buf[RDBK_M]) {
-		dev->rdbk_buf[RDBK_M]->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
-		rkcif_buf_queue(&dev->rdbk_buf[RDBK_M]->vb.vb2_buf);
-	}
-	if (dev->rdbk_buf[RDBK_S]) {
-		dev->rdbk_buf[RDBK_S]->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
-		rkcif_buf_queue(&dev->rdbk_buf[RDBK_S]->vb.vb2_buf);
 	}
 
 	dev->rdbk_buf[RDBK_L] = NULL;
@@ -8603,7 +8752,7 @@
 		else
 			vb_done->vb2_buf.timestamp = stream->readout.fs_timestamp;
 		vb_done->sequence = stream->frame_idx - 1;
-		active_buf->fe_timestamp = ktime_get_ns();
+		active_buf->fe_timestamp = rkcif_time_get_ns(cif_dev);
 		if (stream->is_line_wake_up) {
 			spin_lock_irqsave(&stream->fps_lock, flags);
 			if (mode)
@@ -8615,6 +8764,19 @@
 		}
 		if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED)
 			vb_done->sequence /= 2;
+		if (stream->cur_skip_frame) {
+			rkcif_buf_queue(&active_buf->vb.vb2_buf);
+			return;
+		}
+	} else if (cif_dev->rdbk_buf[stream->id]) {
+		vb_done = &cif_dev->rdbk_buf[stream->id]->vb;
+		if (cif_dev->chip_id < CHIP_RK3588_CIF &&
+		    cif_dev->active_sensor->mbus.type == V4L2_MBUS_BT656)
+			vb_done->vb2_buf.timestamp = stream->readout.fe_timestamp;
+		else
+			vb_done->vb2_buf.timestamp = stream->readout.fs_timestamp;
+		vb_done->sequence = stream->frame_idx - 1;
+		cif_dev->rdbk_buf[stream->id]->fe_timestamp = rkcif_time_get_ns(cif_dev);
 	}
 
 	if (cif_dev->hdr.hdr_mode == NO_HDR || cif_dev->hdr.hdr_mode == HDR_COMPR) {
@@ -8638,7 +8800,7 @@
 		if (cif_dev->is_start_hdr) {
 			spin_lock_irqsave(&cif_dev->hdr_lock, flags);
 			if (mipi_id == RKCIF_STREAM_MIPI_ID0) {
-				if (cif_dev->rdbk_buf[RDBK_L]) {
+				if (cif_dev->rdbk_buf[RDBK_L] && active_buf) {
 					v4l2_err(&cif_dev->v4l2_dev,
 						 "multiple long data in %s frame,frm_idx:%d,state:0x%x\n",
 						 cif_dev->hdr.hdr_mode == HDR_X2 ? "hdr_x2" : "hdr_x3",
@@ -8651,7 +8813,7 @@
 				if (active_buf)
 					cif_dev->rdbk_buf[RDBK_L] = active_buf;
 			} else if (mipi_id == RKCIF_STREAM_MIPI_ID1) {
-				if (cif_dev->rdbk_buf[RDBK_M]) {
+				if (cif_dev->rdbk_buf[RDBK_M] && active_buf) {
 					v4l2_err(&cif_dev->v4l2_dev,
 						 "multiple %s frame,frm_idx:%d,state:0x%x\n",
 						 cif_dev->hdr.hdr_mode == HDR_X2 ? "short data in hdr_x2" : "medium data in hdr_x3",
@@ -8666,7 +8828,7 @@
 				if (cif_dev->hdr.hdr_mode == HDR_X2)
 					rkcif_rdbk_frame_end(stream);
 			} else if (mipi_id == RKCIF_STREAM_MIPI_ID2) {
-				if (cif_dev->rdbk_buf[RDBK_S]) {
+				if (cif_dev->rdbk_buf[RDBK_S] && active_buf) {
 					v4l2_err(&cif_dev->v4l2_dev,
 						 "multiple %s frame, frm_idx:%d,state:0x%x\n",
 						 cif_dev->hdr.hdr_mode == HDR_X2 ? "err short data in hdr_x3" : "short data in hdr_x3",
@@ -8833,10 +8995,10 @@
 			spin_unlock_irqrestore(&stream->vbq_lock, flags);
 			active_buf->dbufs.sequence = stream->frame_idx - 1;
 			active_buf->dbufs.timestamp = stream->readout.fs_timestamp;
-			active_buf->fe_timestamp = ktime_get_ns();
+			active_buf->fe_timestamp = rkcif_time_get_ns(stream->cifdev);
 			stream->last_frame_idx = stream->frame_idx;
 			if (stream->cifdev->hdr.hdr_mode == NO_HDR) {
-				rkcif_s_rx_buffer(stream->cifdev, &active_buf->dbufs);
+				rkcif_s_rx_buffer(stream, &active_buf->dbufs);
 				if (stream->cifdev->is_support_tools && stream->tools_vdev)
 					rkcif_rdbk_with_tools(stream, active_buf);
 			} else {
@@ -8853,7 +9015,7 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&stream->fps_lock, flags);
-	stream->readout.fe_timestamp = ktime_get_ns();
+	stream->readout.fe_timestamp = rkcif_time_get_ns(cif_dev);
 
 	if (cif_dev->inf_id == RKCIF_DVP) {
 		spin_unlock_irqrestore(&stream->fps_lock, flags);
@@ -8900,11 +9062,11 @@
 		if (stream->frame_phase & CIF_CSI_FRAME0_READY) {
 			if (stream->curr_buf)
 				active_buf = stream->curr_buf;
-			stream->fps_stats.frm0_timestamp = ktime_get_ns();
+			stream->fps_stats.frm0_timestamp = rkcif_time_get_ns(cif_dev);
 		} else if (stream->frame_phase & CIF_CSI_FRAME1_READY) {
 			if (stream->next_buf)
 				active_buf = stream->next_buf;
-			stream->fps_stats.frm1_timestamp = ktime_get_ns();
+			stream->fps_stats.frm1_timestamp = rkcif_time_get_ns(cif_dev);
 		}
 		spin_unlock_irqrestore(&stream->fps_lock, flags);
 	}
@@ -8926,7 +9088,7 @@
 	    cif_dev->active_sensor->mbus.type == V4L2_MBUS_BT656 &&
 	    stream->id != 0)
 		stream->frame_idx++;
-	if (!stream->is_line_wake_up && stream->dma_en & RKCIF_DMAEN_BY_VICAP)
+	if (!stream->is_line_wake_up)
 		rkcif_buf_done_prepare(stream, active_buf, mipi_id, 0);
 
 	if (cif_dev->chip_id == CHIP_RV1126_CIF ||
@@ -8948,9 +9110,9 @@
 
 	spin_lock(&stream->fps_lock);
 	if (stream->frame_phase & CIF_CSI_FRAME0_READY)
-		stream->fps_stats.frm0_timestamp = ktime_get_ns();
+		stream->fps_stats.frm0_timestamp = rkcif_time_get_ns(cif_dev);
 	else if (stream->frame_phase & CIF_CSI_FRAME1_READY)
-		stream->fps_stats.frm1_timestamp = ktime_get_ns();
+		stream->fps_stats.frm1_timestamp = rkcif_time_get_ns(cif_dev);
 	spin_unlock(&stream->fps_lock);
 
 	if (cif_dev->inf_id == RKCIF_MIPI_LVDS)
@@ -8982,11 +9144,11 @@
 		if (stream->frame_phase & CIF_CSI_FRAME0_READY) {
 			if (stream->curr_buf_rockit)
 				active_buf = stream->curr_buf_rockit;
-			stream->fps_stats.frm0_timestamp = ktime_get_ns();
+			stream->fps_stats.frm0_timestamp = rkcif_time_get_ns(cif_dev);
 		} else if (stream->frame_phase & CIF_CSI_FRAME1_READY) {
 			if (stream->next_buf_rockit)
 				active_buf = stream->next_buf_rockit;
-			stream->fps_stats.frm1_timestamp = ktime_get_ns();
+			stream->fps_stats.frm1_timestamp = rkcif_time_get_ns(cif_dev);
 		}
 		spin_unlock_irqrestore(&stream->fps_lock, flags);
 	}
@@ -9041,6 +9203,15 @@
 		   sensor->mbus.type == V4L2_MBUS_BT656) {
 		rkcif_dvp_set_sof(cif_dev, seq);
 	}
+}
+
+static void rkcif_toisp_set_stream(struct rkcif_device *dev, int on)
+{
+	struct v4l2_subdev *sd = get_rkisp_sd(dev->sditf[0]);
+
+	if (sd)
+		v4l2_subdev_call(sd, core, ioctl,
+				 RKISP_VICAP_CMD_SET_STREAM, &on);
 }
 
 static int rkcif_do_reset_work(struct rkcif_device *cif_dev,
@@ -9148,6 +9319,9 @@
 			goto unlock_stream;
 		}
 	}
+
+	if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE)
+		rkcif_toisp_set_stream(cif_dev, 1);
 
 	for (i = 0; i < j; i++) {
 		stream = resume_stream[i];
@@ -9287,7 +9461,7 @@
 	v4l2_dbg(3, rkcif_debug, &dev->v4l2_dev, "diff_time:%lld,devi_t:%ld,devi_h:%d\n",
 		  diff_time, timer->line_end_cycle * deviation, deviation);
 
-	cur_time = ktime_get_ns();
+	cur_time = rkcif_time_get_ns(dev);
 	time_distance = timestamp0 > timestamp1 ?
 			cur_time - timestamp0 : cur_time - timestamp1;
 	time_distance = div_u64(time_distance, 1000);
@@ -9396,6 +9570,7 @@
 	timer->csi2_err_cnt_even = 0;
 	timer->csi2_err_fs_fe_cnt = 0;
 	timer->notifer_called_cnt = 0;
+	dev->is_toisp_reset = false;
 	for (i = 0; i < dev->num_channels; i++) {
 		stream = &dev->stream[i];
 		if (stream->state == RKCIF_STATE_STREAMING)
@@ -9405,10 +9580,10 @@
 	if (timer->is_ctrl_by_user) {
 		rkcif_send_reset_event(dev, timer->reset_src);
 	} else {
+		dev->reset_work.reset_src = timer->reset_src;
 		if (!schedule_work(&dev->reset_work.work))
 			v4l2_info(&dev->v4l2_dev,
 				  "schedule reset work failed\n");
-		dev->reset_work.reset_src = timer->reset_src;
 	}
 }
 
@@ -9422,6 +9597,15 @@
 	unsigned long flags;
 	int ret, is_reset = 0;
 	struct rkmodule_vicap_reset_info rst_info;
+
+	if (dev->is_toisp_reset) {
+		is_reset = 1;
+		timer->reset_src = RKCIF_RESET_SRC_ERR_ISP;
+	}
+	if (is_reset) {
+		rkcif_init_reset_work(timer);
+		return is_reset;
+	}
 
 	if (timer->last_buf_wakeup_cnt[stream->id] < stream->buf_wake_up_cnt &&
 	    check_cnt == 0) {
@@ -9796,6 +9980,7 @@
 	if (stream->buf_owner == RKCIF_DMAEN_BY_ISP)
 		stream->buf_owner = RKCIF_DMAEN_BY_ISP_TO_VICAP;
 
+	atomic_dec(&cif_dev->streamoff_cnt);
 	if (stream->dma_en) {
 		stream->dma_en |= stream->to_en_dma;
 		stream->to_en_dma = 0;
@@ -9866,7 +10051,7 @@
 		return -EINVAL;
 
 	stream->dma_en &= ~stream->to_stop_dma;
-
+	atomic_inc(&cif_dev->streamoff_cnt);
 	if (stream->dma_en != 0) {
 		if (stream->dma_en & RKCIF_DMAEN_BY_ISP)
 			stream->buf_owner = RKCIF_DMAEN_BY_ISP;
@@ -9962,6 +10147,7 @@
 	int i = 0;
 	u32 val = 0;
 	u64 cur_time = 0;
+	int on = 0;
 
 	for (i = 0; i < TOISP_CH_MAX; i++) {
 		ch = rkcif_g_toisp_ch(intstat_glb, index);
@@ -9979,7 +10165,30 @@
 				stream->stopping = false;
 				wake_up(&stream->wq_stopped);
 			}
-
+			if (stream->cifdev->sensor_state_change) {
+				rkcif_dphy_quick_stream(stream->cifdev, on);
+				stream->cifdev->sensor_work.on = stream->cifdev->sensor_state;
+				schedule_work(&stream->cifdev->sensor_work.work);
+				stream->cifdev->sensor_state_change = false;
+				if (stream->is_wait_stop_complete) {
+					stream->is_wait_stop_complete = false;
+					complete(&stream->stop_complete);
+				}
+			}
+			if (stream->is_single_cap && (!stream->cur_skip_frame) &&
+			    (stream->cifdev->hdr.hdr_mode == NO_HDR ||
+			    (stream->cifdev->hdr.hdr_mode == HDR_X2 && stream->id == 1) ||
+			    (stream->cifdev->hdr.hdr_mode == HDR_X3 && stream->id == 2))) {
+				rkcif_dphy_quick_stream(stream->cifdev, on);
+				stream->cifdev->sensor_work.on = 0;
+				schedule_work(&stream->cifdev->sensor_work.work);
+				stream->is_single_cap = false;
+			}
+			if (stream->cur_skip_frame &&
+			    (stream->cifdev->hdr.hdr_mode == NO_HDR ||
+			     (stream->cifdev->hdr.hdr_mode == HDR_X2 && stream->id == 1) ||
+			     (stream->cifdev->hdr.hdr_mode == HDR_X3 && stream->id == 2)))
+				stream->cur_skip_frame--;
 			if (stream->cifdev->chip_id >= CHIP_RV1106_CIF)
 				rkcif_modify_frame_skip_config(stream);
 			if (stream->cifdev->rdbk_debug &&
@@ -10016,9 +10225,14 @@
 			if (stream->id == 0)
 				rkcif_send_sof(stream->cifdev);
 			stream->frame_idx++;
-			cur_time = ktime_get_ns();
+			cur_time = rkcif_time_get_ns(stream->cifdev);
 			stream->readout.readout_time = cur_time - stream->readout.fs_timestamp;
 			stream->readout.fs_timestamp = cur_time;
+			stream->buf_wake_up_cnt++;
+			if (stream->frame_idx % 2)
+				stream->fps_stats.frm0_timestamp = rkcif_time_get_ns(stream->cifdev);
+			else
+				stream->fps_stats.frm1_timestamp = rkcif_time_get_ns(stream->cifdev);
 			if (stream->cifdev->rdbk_debug &&
 			    stream->frame_idx < 15)
 				v4l2_info(&priv->cif_dev->v4l2_dev,
@@ -10143,7 +10357,7 @@
 	if (cif_dev->chip_id < CHIP_RK3588_CIF)
 		detect_stream->fs_cnt_in_single_frame++;
 	spin_lock_irqsave(&detect_stream->fps_lock, flags);
-	detect_stream->readout.fs_timestamp = ktime_get_ns();
+	detect_stream->readout.fs_timestamp = rkcif_time_get_ns(cif_dev);
 	spin_unlock_irqrestore(&detect_stream->fps_lock, flags);
 
 	if (cif_dev->sync_cfg.type != RKCIF_NOSYNC_MODE) {
@@ -10194,7 +10408,7 @@
 				  "stream[%d] sof %d %lld\n",
 				  detect_stream->id,
 				  detect_stream->frame_idx - 1,
-				  ktime_get_ns());
+				  rkcif_time_get_ns(cif_dev));
 	}
 }
 
@@ -10253,6 +10467,425 @@
 	return is_update;
 }
 
+static bool rkcif_check_single_dev_stream_on(struct rkcif_hw *hw)
+{
+	struct rkcif_device *cif_dev = NULL;
+	struct rkcif_stream *stream = NULL;
+	int i = 0, j = 0;
+	int stream_cnt = 0;
+
+	if (hw->dev_num == 1)
+		return true;
+	for (i = 0; i < hw->dev_num; i++) {
+		cif_dev = hw->cif_dev[i];
+		for (j = 0; j < RKCIF_MAX_STREAM_MIPI; j++) {
+			stream = &cif_dev->stream[j];
+			if (stream->state == RKCIF_STATE_STREAMING ||
+			    stream->state ==  RKCIF_STATE_RESET_IN_STREAMING) {
+				stream_cnt++;
+				break;
+			}
+		}
+	}
+	if (stream_cnt > 1)
+		return false;
+	return true;
+}
+
+static void rkcif_get_resmem_head(struct rkcif_device *cif_dev)
+{
+	void *resmem_va = phys_to_virt(cif_dev->resmem_pa);
+	struct rkisp_thunderboot_resmem_head *head = NULL;
+	int size = 0;
+	int offset = 0;
+	int ret = 0;
+	int cam_idx = 0;
+	char cam_idx_str[3] = {0};
+
+	if (!cif_dev->is_rtt_suspend)
+		return;
+	strscpy(cam_idx_str, cif_dev->terminal_sensor.sd->name + 1, 2);
+	cam_idx_str[2] = '\0';
+	ret = kstrtoint(cam_idx_str, 0, &cam_idx);
+	if (ret) {
+		v4l2_err(&cif_dev->v4l2_dev,
+			 "get camera index fail\n");
+		return;
+	}
+
+	if (cif_dev->chip_id == CHIP_RV1106_CIF) {
+		size = sizeof(struct rkisp32_thunderboot_resmem_head);
+		offset = size * cam_idx;
+	}
+	/* currently, thunderboot with mcu only run one camera */
+	offset = 0;
+
+	if (size && size < cif_dev->resmem_size) {
+		dma_sync_single_for_cpu(cif_dev->dev, cif_dev->resmem_addr + offset,
+					size, DMA_FROM_DEVICE);
+		if (cif_dev->chip_id == CHIP_RV1106_CIF) {
+			struct rkisp32_thunderboot_resmem_head *tmp = resmem_va + offset;
+
+			head = &tmp->head;
+			cif_dev->resume_mode = head->rtt_mode;
+			cif_dev->nr_buf_size = head->nr_buf_size;
+			cif_dev->share_mem_size = head->share_mem_size;
+			cif_dev->thunderboot_sensor_num = head->camera_num;
+		}
+	}
+	v4l2_err(&cif_dev->v4l2_dev,
+		 "get camera index %02x, resume_mode 0x%x, nr_buf_size %d\n",
+		 cam_idx, cif_dev->resume_mode, cif_dev->nr_buf_size);
+}
+
+static int rkcif_subdevs_set_power(struct rkcif_device *cif_dev, int on)
+{
+	struct sditf_priv *priv = cif_dev->sditf[0];
+	int ret = 0;
+	int i = 0;
+
+	if (cif_dev->terminal_sensor.sd)
+		ret = v4l2_subdev_call(cif_dev->terminal_sensor.sd,
+				       core, s_power, on);
+	if (priv && priv->is_combine_mode && cif_dev->sditf_cnt <= RKCIF_MAX_SDITF) {
+		for (i = 0; i < cif_dev->sditf_cnt; i++) {
+			if (cif_dev->sditf[i] && cif_dev->sditf[i]->sensor_sd)
+				v4l2_subdev_call(cif_dev->sditf[i]->sensor_sd, core,
+						 s_power, on);
+		}
+	}
+	return ret;
+}
+
+static void rkcif_sensor_quick_streaming_cb(void *data)
+{
+	struct v4l2_subdev *subdevs = (struct v4l2_subdev *)data;
+	int on = 1;
+
+	v4l2_subdev_call(subdevs, core, ioctl,
+			 RKMODULE_SET_QUICK_STREAM, &on);
+}
+
+static int rkcif_subdevs_set_stream(struct rkcif_device *cif_dev, int on)
+{
+	struct rkcif_pipeline *p = &cif_dev->pipe;
+	struct rkcif_sensor_info *terminal_sensor = &cif_dev->terminal_sensor;
+	struct sditf_priv *priv = cif_dev->sditf[0];
+	int i = 0;
+	int ret = 0;
+
+	for (i = 0; i < p->num_subdevs; i++) {
+		if (p->subdevs[i] == terminal_sensor->sd && on)
+			rkcif_set_sof(cif_dev, cif_dev->stream[0].frame_idx);
+		if (p->subdevs[i] == terminal_sensor->sd &&
+		    cif_dev->chip_id == CHIP_RV1106_CIF) {
+			if (!rk_tb_mcu_is_done() && on) {
+				cif_dev->tb_client.data = p->subdevs[i];
+				cif_dev->tb_client.cb = rkcif_sensor_quick_streaming_cb;
+				rk_tb_client_register_cb(&cif_dev->tb_client);
+			} else {
+				ret = v4l2_subdev_call(p->subdevs[i], core, ioctl,
+						       RKMODULE_SET_QUICK_STREAM, &on);
+				if (ret)
+					v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
+						 "%s:quick stream %s subdev:%s failed\n",
+						 __func__, on ? "on" : "off",
+						 p->subdevs[i]->name);
+			}
+		} else {
+			ret = v4l2_subdev_call(p->subdevs[i], video, s_stream, on);
+			if (ret)
+				v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
+					 "%s:stream %s subdev:%s failed\n",
+					 __func__, on ? "on" : "off", p->subdevs[i]->name);
+		}
+	}
+
+	if (priv && priv->is_combine_mode && cif_dev->sditf_cnt <= RKCIF_MAX_SDITF) {
+		for (i = 0; i < cif_dev->sditf_cnt; i++) {
+			if (cif_dev->sditf[i] && cif_dev->sditf[i]->sensor_sd) {
+				ret = v4l2_subdev_call(cif_dev->sditf[i]->sensor_sd, video, s_stream, on);
+				if (ret)
+					v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
+						 "%s:stream %s subdev:%s failed\n",
+						 __func__, on ? "on" : "off",
+						 cif_dev->sditf[i]->sensor_sd->name);
+			}
+		}
+	}
+	return ret;
+}
+
+int rkcif_stream_suspend(struct rkcif_device *cif_dev, int mode)
+{
+	struct rkcif_stream *stream = NULL;
+	struct rkcif_resume_info *resume_info = &cif_dev->reset_work.resume_info;
+	struct sditf_priv *priv = cif_dev->sditf[0];
+	int ret = 0;
+	int i = 0;
+	int sof_cnt = 0;
+	int on = 0;
+	int suspend_cnt = 0;
+
+	mutex_lock(&cif_dev->stream_lock);
+
+	if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE && mode == RKCIF_RESUME_CIF)
+		goto out_suspend;
+
+	for (i = 0; i < RKCIF_MAX_STREAM_MIPI; i++) {
+		stream = &cif_dev->stream[i];
+
+		if (stream->state == RKCIF_STATE_STREAMING) {
+			suspend_cnt++;
+			v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
+				 "stream[%d] stopping\n", stream->id);
+			if (stream->dma_en) {
+				stream->stopping = true;
+				ret = wait_event_timeout(stream->wq_stopped,
+							 stream->state != RKCIF_STATE_STREAMING,
+							 msecs_to_jiffies(500));
+				if (!ret) {
+					rkcif_stream_stop(stream);
+					stream->stopping = false;
+				}
+			} else {
+				rkcif_stream_stop(stream);
+			}
+
+			if (stream->id == RKCIF_STREAM_MIPI_ID0) {
+				sof_cnt = rkcif_get_sof(cif_dev);
+				v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
+					 "%s: stream[%d] sync frmid & csi_sof, frm_id:%d, csi_sof:%d\n",
+					 __func__,
+					 stream->id,
+					 stream->frame_idx,
+					 sof_cnt);
+
+				resume_info->frm_sync_seq = stream->frame_idx;
+			}
+
+			stream->state = RKCIF_STATE_RESET_IN_STREAMING;
+			stream->is_fs_fe_not_paired = false;
+			stream->fs_cnt_in_single_frame = 0;
+
+			v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
+				 "%s stop stream[%d] in streaming, frm_id:%d, csi_sof:%d\n",
+				 __func__, stream->id, stream->frame_idx, rkcif_get_sof(cif_dev));
+
+		}
+	}
+
+	if (suspend_cnt == 0)
+		goto out_suspend;
+
+	if (!cif_dev->resume_mode)
+		rkcif_subdevs_set_power(cif_dev, on);
+
+	rkcif_subdevs_set_stream(cif_dev, on);
+
+out_suspend:
+	mutex_unlock(&cif_dev->stream_lock);
+	return 0;
+}
+
+int rkcif_stream_resume(struct rkcif_device *cif_dev, int mode)
+{
+	struct rkcif_stream *stream = NULL;
+	struct sditf_priv *priv = cif_dev->sditf[0];
+	struct v4l2_subdev *sd = NULL;
+	int ret = 0;
+	int i = 0;
+	u32 capture_mode = 0;
+	int on = 1;
+	int resume_cnt = 0;
+	unsigned long flags;
+	bool is_single_dev = false;
+	bool is_can_be_online = false;
+	struct rkisp_vicap_mode vicap_mode;
+
+	mutex_lock(&cif_dev->stream_lock);
+
+	rkcif_get_resmem_head(cif_dev);
+	is_single_dev = rkcif_check_single_dev_stream_on(cif_dev->hw_dev);
+	is_can_be_online = rkcif_check_can_be_online(cif_dev);
+	if (cif_dev->resume_mode == RKISP_RTT_MODE_ONE_FRAME) {
+		if (cif_dev->is_rtt_suspend) {
+			capture_mode = RKCIF_STREAM_MODE_TOISP_RDBK;
+			if (priv)
+				priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AUTO;
+		} else {
+			if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) {
+				if (cif_dev->chip_id == CHIP_RV1106_CIF) {
+					capture_mode = RKCIF_STREAM_MODE_TOISP_RDBK;
+					priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AUTO;
+				} else {
+					capture_mode = RKCIF_STREAM_MODE_TOISP;
+				}
+			} else if (priv &&
+				   (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO ||
+				    priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO_ONE_FRAME)) {
+				capture_mode = RKCIF_STREAM_MODE_TOISP_RDBK;
+			} else {
+				capture_mode = RKCIF_STREAM_MODE_CAPTURE;
+			}
+		}
+	} else if (cif_dev->resume_mode == RKISP_RTT_MODE_MULTI_FRAME) {
+		if (is_single_dev && is_can_be_online) {
+			capture_mode = RKCIF_STREAM_MODE_TOISP;
+			if (priv)
+				priv->mode.rdbk_mode = RKISP_VICAP_ONLINE;
+		} else {
+			if (cif_dev->is_thunderboot) {
+				capture_mode = RKCIF_STREAM_MODE_TOISP_RDBK;
+				if (priv)
+					priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AUTO;
+			} else {
+				capture_mode = RKCIF_STREAM_MODE_CAPTURE;
+				if (priv)
+					priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ;
+			}
+		}
+	} else {
+		if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE)
+			capture_mode = RKCIF_STREAM_MODE_TOISP;
+		else if (priv &&
+			 (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO ||
+			  priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO_ONE_FRAME))
+			capture_mode = RKCIF_STREAM_MODE_TOISP_RDBK;
+		else
+			capture_mode = RKCIF_STREAM_MODE_CAPTURE;
+	}
+	if (priv && priv->mode.rdbk_mode == RKISP_VICAP_ONLINE && mode == RKCIF_RESUME_CIF)
+		goto out_resume;
+
+	for (i = 0; i < RKCIF_MAX_STREAM_MIPI; i++) {
+		stream = &cif_dev->stream[i];
+		if (stream->state != RKCIF_STATE_RESET_IN_STREAMING)
+			continue;
+
+		stream->fs_cnt_in_single_frame = 0;
+		if (cif_dev->resume_mode == RKISP_RTT_MODE_ONE_FRAME)
+			stream->is_single_cap = true;
+		spin_lock_irqsave(&stream->vbq_lock, flags);
+		if (!priv || priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AIQ) {
+			if (stream->cif_fmt_in->field == V4L2_FIELD_INTERLACED) {
+				if (stream->curr_buf == stream->next_buf) {
+					if (stream->curr_buf)
+						list_add_tail(&stream->curr_buf->queue, &stream->buf_head);
+				} else {
+					if (stream->curr_buf)
+						list_add_tail(&stream->curr_buf->queue, &stream->buf_head);
+					if (stream->next_buf)
+						list_add_tail(&stream->next_buf->queue, &stream->buf_head);
+				}
+				stream->curr_buf = NULL;
+				stream->next_buf = NULL;
+			}
+		} else {
+			if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) {
+				if (stream->curr_buf_toisp == stream->next_buf_toisp) {
+					if (stream->curr_buf_toisp)
+						list_add_tail(&stream->curr_buf_toisp->list, &stream->rx_buf_head);
+				} else {
+					if (stream->curr_buf_toisp)
+						list_add_tail(&stream->curr_buf_toisp->list, &stream->rx_buf_head);
+					if (stream->next_buf_toisp)
+						list_add_tail(&stream->next_buf_toisp->list, &stream->rx_buf_head);
+				}
+				stream->curr_buf_toisp = NULL;
+				stream->next_buf_toisp = NULL;
+			} else {
+				if (stream->curr_buf_toisp == stream->next_buf_toisp) {
+					if (stream->curr_buf_toisp)
+						list_add_tail(&stream->curr_buf_toisp->list, &stream->rx_buf_head);
+				} else {
+					if (stream->curr_buf_toisp)
+						list_add_tail(&stream->curr_buf_toisp->list, &stream->rx_buf_head);
+					if (stream->next_buf_toisp)
+						list_add_tail(&stream->next_buf_toisp->list, &stream->rx_buf_head);
+				}
+				stream->curr_buf_toisp = NULL;
+				stream->next_buf_toisp = NULL;
+			}
+		}
+
+		spin_unlock_irqrestore(&stream->vbq_lock, flags);
+
+		if (priv) {
+			if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) {
+				sditf_change_to_online(priv);
+				if (cif_dev->resume_mode == RKISP_RTT_MODE_MULTI_FRAME &&
+				    stream->rx_buf_num &&
+				    (priv->hdr_cfg.hdr_mode == NO_HDR ||
+				     (priv->hdr_cfg.hdr_mode == HDR_X2 && stream->id == 1) ||
+				     (priv->hdr_cfg.hdr_mode == HDR_X3 && stream->id == 2)))
+					rkcif_free_rx_buf(stream, priv->buf_num);
+				else if (!stream->rx_buf_num &&
+					 ((priv->hdr_cfg.hdr_mode == HDR_X2 && stream->id == 0) ||
+					 (priv->hdr_cfg.hdr_mode == HDR_X3 && (stream->id == 0 || stream->id == 1))))
+					rkcif_init_rx_buf(stream, 1);
+			} else {
+				if (stream->is_single_cap && stream->id == 0) {
+					vicap_mode = priv->mode;
+					vicap_mode.rdbk_mode = RKISP_VICAP_RDBK_AUTO_ONE_FRAME;
+					sd = get_rkisp_sd(priv);
+					if (sd) {
+						ret = v4l2_subdev_call(sd, core, ioctl,
+								       RKISP_VICAP_CMD_MODE, &vicap_mode);
+						if (ret)
+							v4l2_err(&cif_dev->v4l2_dev,
+								 "set isp work mode rdbk aotu oneframe fail\n");
+
+					}
+				}
+				sditf_disable_immediately(priv);
+				if (!stream->rx_buf_num &&
+				    capture_mode == RKCIF_STREAM_MODE_TOISP_RDBK) {
+					if (cif_dev->resume_mode == RKISP_RTT_MODE_ONE_FRAME)
+						rkcif_init_rx_buf(stream, 1);
+					else
+						rkcif_init_rx_buf(stream, priv->buf_num);
+				}
+			}
+		}
+
+		stream->lack_buf_cnt = 0;
+		if (cif_dev->active_sensor  &&
+		    (cif_dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_DPHY ||
+		    cif_dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_CPHY ||
+		    cif_dev->active_sensor->mbus.type == V4L2_MBUS_CCP2))
+			ret = rkcif_csi_stream_start(stream, capture_mode);
+		else
+			ret = rkcif_stream_start(stream, capture_mode);
+		if (ret)
+			v4l2_err(&cif_dev->v4l2_dev, "%s:resume stream[%d] failed\n",
+				 __func__, stream->id);
+
+		resume_cnt++;
+		stream->cur_skip_frame = stream->skip_frame;
+		v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
+			 "resume stream[%d], frm_idx:%d, csi_sof:%d\n",
+			 stream->id, stream->frame_idx,
+			 rkcif_get_sof(cif_dev));
+	}
+
+	if (resume_cnt == 0)
+		goto out_resume;
+
+	if (!cif_dev->resume_mode)
+		rkcif_subdevs_set_power(cif_dev, on);
+
+	atomic_set(&cif_dev->streamoff_cnt, 0);
+	rkcif_subdevs_set_stream(cif_dev, on);
+
+	if (cif_dev->chip_id < CHIP_RK3588_CIF)
+		rkcif_start_luma(&cif_dev->luma_vdev,
+				 cif_dev->stream[RKCIF_STREAM_MIPI_ID0].cif_fmt_in);
+out_resume:
+	mutex_unlock(&cif_dev->stream_lock);
+	return 0;
+}
+
 void rkcif_err_print_work(struct work_struct *work)
 {
 	struct rkcif_err_state_work *err_state_work = container_of(work,
@@ -10268,7 +10901,7 @@
 	u64 cur_time = 0;
 	bool is_print = false;
 
-	cur_time = ktime_get_ns();
+	cur_time = rkcif_time_get_ns(dev);
 	if (err_state_work->last_timestamp == 0) {
 		is_print = true;
 	} else {
@@ -10312,10 +10945,18 @@
 		v4l2_err(&dev->v4l2_dev,
 			 "stream[3], frm0/frm1 end simultaneously,frm id:%d, cnt %llu\n",
 			 dev->stream[3].frame_idx, dev->irq_stats.trig_simult_cnt[3]);
-	if (err_state & RKCIF_ERR_SIZE)
-		v4l2_err(&dev->v4l2_dev,
-			 "ERROR: csi size err, intstat:0x%x, lastline:0x%x, cnt %llu\n",
-			 intstat, lastline, dev->irq_stats.csi_size_err_cnt);
+	if (err_state & RKCIF_ERR_SIZE) {
+		if (dev->chip_id >= CHIP_RK3588_CIF)
+			v4l2_err(&dev->v4l2_dev,
+				 "ERROR: csi size err, intstat:0x%x, size:0x%x,0x%x,0x%x,0x%x, cnt %llu\n",
+				 intstat, err_state_work->size_id0, err_state_work->size_id1,
+				 err_state_work->size_id2, err_state_work->size_id3,
+				 dev->irq_stats.csi_size_err_cnt);
+		else
+			v4l2_err(&dev->v4l2_dev,
+				 "ERROR: csi size err, intstat:0x%x, lastline:0x%x, cnt %llu\n",
+				 intstat, lastline, dev->irq_stats.csi_size_err_cnt);
+	}
 	if (err_state & RKCIF_ERR_OVERFLOW)
 		v4l2_err(&dev->v4l2_dev,
 			 "ERROR: csi fifo overflow, intstat:0x%x, lastline:0x%x, cnt %llu\n",
@@ -10349,6 +10990,7 @@
 	unsigned long flags;
 	bool is_update = false;
 	int ret = 0;
+	int on = 0;
 
 	if (!cif_dev->active_sensor)
 		return;
@@ -10369,13 +11011,22 @@
 		if (intstat) {
 			rkcif_write_register(cif_dev, CIF_REG_MIPI_LVDS_INTSTAT, intstat);
 			v4l2_dbg(2, rkcif_debug, &cif_dev->v4l2_dev,
-				 "intstat 0x%x\n",
-				 intstat);
+				 "intstat 0x%x\n", intstat);
 		} else {
 			return;
 		}
 
 		if (intstat & CSI_SIZE_ERR) {
+			if (cif_dev->chip_id >= CHIP_RK3588_CIF) {
+				cif_dev->err_state_work.size_id0 = rkcif_read_register(cif_dev,
+					CIF_REG_MIPI_FRAME_SIZE_ID0);
+				cif_dev->err_state_work.size_id1 = rkcif_read_register(cif_dev,
+					CIF_REG_MIPI_FRAME_SIZE_ID1);
+				cif_dev->err_state_work.size_id2 = rkcif_read_register(cif_dev,
+					CIF_REG_MIPI_FRAME_SIZE_ID2);
+				cif_dev->err_state_work.size_id3 = rkcif_read_register(cif_dev,
+					CIF_REG_MIPI_FRAME_SIZE_ID3);
+			}
 			cif_dev->irq_stats.csi_size_err_cnt++;
 			cif_dev->err_state |= RKCIF_ERR_SIZE;
 			rkcif_write_register_or(cif_dev, CIF_REG_MIPI_LVDS_CTRL, 0x000A0000);
@@ -10388,9 +11039,15 @@
 			return;
 		}
 
-		if (intstat & CSI_BANDWIDTH_LACK_V1) {
+		if (intstat & CSI_BANDWIDTH_LACK_V1 &&
+		    cif_dev->intr_mask & CSI_BANDWIDTH_LACK_V1) {
 			cif_dev->irq_stats.csi_bwidth_lack_cnt++;
 			cif_dev->err_state |= RKCIF_ERR_BANDWIDTH_LACK;
+			if (cif_dev->irq_stats.csi_bwidth_lack_cnt > 10) {
+				rkcif_write_register_and(cif_dev, CIF_REG_MIPI_LVDS_INTEN, ~(CSI_BANDWIDTH_LACK_V1));
+				cif_dev->intr_mask &= ~(CSI_BANDWIDTH_LACK_V1);
+				schedule_delayed_work(&cif_dev->work_deal_err, msecs_to_jiffies(1000));
+			}
 		}
 
 		if (intstat & CSI_ALL_ERROR_INTEN_V1) {
@@ -10445,13 +11102,20 @@
 					  stream->id,
 					  stream->frame_idx - 1,
 					  stream->frame_phase,
-					  ktime_get_ns());
+					  rkcif_time_get_ns(cif_dev));
 			if (stream->is_finish_stop_dma && stream->is_wait_dma_stop) {
 				stream->is_wait_dma_stop = false;
 				wake_up(&stream->wq_stopped);
 				stream->is_finish_stop_dma = false;
 				continue;
 			}
+
+			if (stream->is_finish_stop_dma && stream->is_wait_stop_complete) {
+				stream->is_finish_stop_dma = false;
+				stream->is_wait_stop_complete = false;
+				complete(&stream->stop_complete);
+			}
+
 			if (stream->crop_dyn_en)
 				rkcif_dynamic_crop(stream);
 
@@ -10476,6 +11140,26 @@
 					 stream->dma_en);
 				rkcif_update_stream_rockit(cif_dev, stream, mipi_id);
 			}
+			if (stream->is_single_cap && !stream->cur_skip_frame) {
+				if (stream->dma_en & RKCIF_DMAEN_BY_ISP)
+					stream->to_stop_dma = RKCIF_DMAEN_BY_ISP;
+				else if (stream->dma_en & RKCIF_DMAEN_BY_VICAP)
+					stream->to_stop_dma = RKCIF_DMAEN_BY_VICAP;
+				else if (stream->dma_en & RKCIF_DMAEN_BY_ROCKIT)
+					stream->to_stop_dma = RKCIF_DMAEN_BY_ROCKIT;
+				rkcif_stop_dma_capture(stream);
+				stream->is_single_cap = false;
+				if ((cif_dev->hdr.hdr_mode == NO_HDR && atomic_read(&cif_dev->streamoff_cnt) == 1) ||
+				    (cif_dev->hdr.hdr_mode == HDR_X2 && atomic_read(&cif_dev->streamoff_cnt) == 2) ||
+				    (cif_dev->hdr.hdr_mode == HDR_X3 && atomic_read(&cif_dev->streamoff_cnt) == 3)) {
+					rkcif_dphy_quick_stream(stream->cifdev, on);
+					cif_dev->sensor_work.on = 0;
+					schedule_work(&cif_dev->sensor_work.work);
+				}
+			}
+
+			if (stream->cur_skip_frame)
+				stream->cur_skip_frame--;
 
 			if (cif_dev->chip_id >= CHIP_RV1106_CIF)
 				rkcif_modify_frame_skip_config(stream);
@@ -10490,12 +11174,13 @@
 			}
 
 			spin_lock_irqsave(&stream->vbq_lock, flags);
-			if (!(stream->dma_en & RKCIF_DMAEN_BY_ISP) && stream->lack_buf_cnt == 2) {
+			if (!(stream->cur_stream_mode & RKCIF_STREAM_MODE_TOISP) &&
+			    stream->lack_buf_cnt == 2) {
+				stream->to_stop_dma = RKCIF_DMAEN_BY_VICAP;
+				rkcif_stop_dma_capture(stream);
 				v4l2_dbg(4, rkcif_debug, &cif_dev->v4l2_dev,
 					 "stream[%d] to stop dma, lack_buf_cnt %d\n",
 					 stream->id, stream->lack_buf_cnt);
-				stream->to_stop_dma = RKCIF_DMAEN_BY_VICAP;
-				rkcif_stop_dma_capture(stream);
 			}
 			spin_unlock_irqrestore(&stream->vbq_lock, flags);
 			if (stream->to_en_scale) {
@@ -10522,10 +11207,11 @@
 			if (intstat & CSI_START_INTSTAT(i)) {
 				stream = &cif_dev->stream[i];
 				if (i == 0) {
-					rkcif_deal_sof(cif_dev);
+					if (!stream->cur_skip_frame)
+						rkcif_deal_sof(cif_dev);
 				} else {
 					spin_lock_irqsave(&stream->fps_lock, flags);
-					stream->readout.fs_timestamp = ktime_get_ns();
+					stream->readout.fs_timestamp = rkcif_time_get_ns(cif_dev);
 					stream->frame_idx++;
 					spin_unlock_irqrestore(&stream->fps_lock, flags);
 				}
@@ -10556,7 +11242,8 @@
 						v4l2_info(&cif_dev->v4l2_dev,
 							  "line int %lld\n",
 							  stream->line_int_cnt);
-					if (cif_dev->sditf[0] && cif_dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO)
+					if (cif_dev->sditf[0] && (cif_dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO ||
+					    cif_dev->sditf[0]->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO_ONE_FRAME))
 						rkcif_line_wake_up_rdbk(stream, stream->id);
 					else
 						rkcif_line_wake_up(stream, stream->id);
@@ -10665,7 +11352,8 @@
 
 		if (intstat & DVP_FRAME0_START_ID0 || intstat & DVP_FRAME1_START_ID0) {
 			stream->is_in_vblank = false;
-			rkcif_deal_sof(cif_dev);
+			if (!stream->cur_skip_frame)
+				rkcif_deal_sof(cif_dev);
 		}
 
 		if (stream->crop_dyn_en)
@@ -10777,10 +11465,11 @@
 			if (intstat & CSI_START_INTSTAT(i)) {
 				stream = &cif_dev->stream[i];
 				if (i == 0) {
-					rkcif_deal_sof(cif_dev);
+					if (!stream->cur_skip_frame)
+						rkcif_deal_sof(cif_dev);
 				} else {
 					spin_lock_irqsave(&stream->fps_lock, flags);
-					stream->readout.fs_timestamp = ktime_get_ns();
+					stream->readout.fs_timestamp = rkcif_time_get_ns(cif_dev);
 					stream->frame_idx++;
 					spin_unlock_irqrestore(&stream->fps_lock, flags);
 				}
@@ -10907,9 +11596,9 @@
 
 				spin_lock_irqsave(&stream->fps_lock, flags);
 				if (stream->frame_phase & CIF_CSI_FRAME0_READY)
-					stream->fps_stats.frm0_timestamp = ktime_get_ns();
+					stream->fps_stats.frm0_timestamp = rkcif_time_get_ns(cif_dev);
 				else if (stream->frame_phase & CIF_CSI_FRAME1_READY)
-					stream->fps_stats.frm1_timestamp = ktime_get_ns();
+					stream->fps_stats.frm1_timestamp = rkcif_time_get_ns(cif_dev);
 				spin_unlock_irqrestore(&stream->fps_lock, flags);
 
 				ret = rkcif_assign_new_buffer_oneframe(stream,
@@ -10980,7 +11669,8 @@
 		    (cif_dev->dvp_sof_in_oneframe == 0)) {
 			if ((intstat & (PRE_INF_FRAME_END | PST_INF_FRAME_END)) == 0x0) {
 				if ((intstat & INTSTAT_ERR) == 0x0) {
-					rkcif_deal_sof(cif_dev);
+					if (!stream->cur_skip_frame)
+						rkcif_deal_sof(cif_dev);
 					int_en = rkcif_read_register(cif_dev, CIF_REG_DVP_INTEN);
 					int_en &= ~LINE_INT_EN;
 					rkcif_write_register(cif_dev, CIF_REG_DVP_INTEN, int_en);
diff --git a/kernel/drivers/media/platform/rockchip/cif/cif-luma.c b/kernel/drivers/media/platform/rockchip/cif/cif-luma.c
index 9d751df..5a3c228 100644
--- a/kernel/drivers/media/platform/rockchip/cif/cif-luma.c
+++ b/kernel/drivers/media/platform/rockchip/cif/cif-luma.c
@@ -361,7 +361,7 @@
 
 	if (send_task) {
 		luma_vdev->work.readout = RKCIF_READOUT_LUMA;
-		luma_vdev->work.timestamp = ktime_get_ns();
+		luma_vdev->work.timestamp = rkcif_time_get_ns(luma_vdev->cifdev);
 		luma_vdev->work.frame_id = frame_id;
 
 		if (frm_mode == RKCIF_LUMA_THREEFRM)
diff --git a/kernel/drivers/media/platform/rockchip/cif/cif-scale.c b/kernel/drivers/media/platform/rockchip/cif/cif-scale.c
index 3beede6..a9b97a6 100644
--- a/kernel/drivers/media/platform/rockchip/cif/cif-scale.c
+++ b/kernel/drivers/media/platform/rockchip/cif/cif-scale.c
@@ -968,7 +968,7 @@
 				      scale_vdev->pixm.plane_fmt[i].sizeimage);
 	}
 
-	vb_done->vb2_buf.timestamp = ktime_get_ns();
+	vb_done->vb2_buf.timestamp = rkcif_time_get_ns(scale_vdev->cifdev);
 
 	vb2_buffer_done(&vb_done->vb2_buf, VB2_BUF_STATE_DONE);
 }
diff --git a/kernel/drivers/media/platform/rockchip/cif/dev.c b/kernel/drivers/media/platform/rockchip/cif/dev.c
index 6f41ab3..260fb83 100644
--- a/kernel/drivers/media/platform/rockchip/cif/dev.c
+++ b/kernel/drivers/media/platform/rockchip/cif/dev.c
@@ -20,7 +20,6 @@
 #include <media/videobuf2-dma-contig.h>
 #include <media/v4l2-fwnode.h>
 #include <linux/iommu.h>
-#include <dt-bindings/soc/rockchip-system-status.h>
 #include <soc/rockchip/rockchip-system-status.h>
 #include <linux/io.h>
 #include <linux/mfd/syscon.h>
@@ -1134,6 +1133,7 @@
 			cif_dev->reset_watchdog_timer.is_triggered = false;
 			cif_dev->reset_watchdog_timer.is_running = false;
 			cif_dev->err_state_work.last_timestamp = 0;
+			cif_dev->is_toisp_reset = false;
 			for (i = 0; i < cif_dev->num_channels; i++)
 				cif_dev->reset_watchdog_timer.last_buf_wakeup_cnt[i] = 0;
 			cif_dev->reset_watchdog_timer.run_cnt = 0;
@@ -1218,6 +1218,7 @@
 				cif_dev->is_start_hdr = true;
 				cif_dev->reset_watchdog_timer.is_triggered = false;
 				cif_dev->reset_watchdog_timer.is_running = false;
+				cif_dev->is_toisp_reset = false;
 				for (i = 0; i < cif_dev->num_channels; i++)
 					cif_dev->reset_watchdog_timer.last_buf_wakeup_cnt[i] = 0;
 				cif_dev->reset_watchdog_timer.run_cnt = 0;
@@ -1908,6 +1909,32 @@
 	INIT_WORK(&dev->reset_work.work, rkcif_reset_work);
 }
 
+void rkcif_set_sensor_stream(struct work_struct *work)
+{
+	struct rkcif_sensor_work *sensor_work = container_of(work,
+						struct rkcif_sensor_work,
+						work);
+	struct rkcif_device *cif_dev = container_of(sensor_work,
+						    struct rkcif_device,
+						    sensor_work);
+
+	v4l2_subdev_call(cif_dev->terminal_sensor.sd,
+			core, ioctl,
+			RKMODULE_SET_QUICK_STREAM,
+			&sensor_work->on);
+}
+
+static void rkcif_deal_err_intr(struct work_struct *work)
+{
+	struct delayed_work *dwork = to_delayed_work(work);
+	struct rkcif_device *cif_dev = container_of(dwork,
+						    struct rkcif_device,
+						    work_deal_err);
+
+	cif_dev->intr_mask |= CSI_BANDWIDTH_LACK_V1;
+	rkcif_write_register_or(cif_dev, CIF_REG_MIPI_LVDS_INTEN, CSI_BANDWIDTH_LACK_V1);
+}
+
 int rkcif_plat_init(struct rkcif_device *cif_dev, struct device_node *node, int inf_id)
 {
 	struct device *dev = cif_dev->dev;
@@ -1927,6 +1954,7 @@
 	atomic_set(&cif_dev->pipe.power_cnt, 0);
 	atomic_set(&cif_dev->pipe.stream_cnt, 0);
 	atomic_set(&cif_dev->power_cnt, 0);
+	atomic_set(&cif_dev->streamoff_cnt, 0);
 	cif_dev->is_start_hdr = false;
 	cif_dev->pipe.open = rkcif_pipeline_open;
 	cif_dev->pipe.close = rkcif_pipeline_close;
@@ -1940,11 +1968,15 @@
 	cif_dev->early_line = 0;
 	cif_dev->is_thunderboot = false;
 	cif_dev->rdbk_debug = 0;
+
+	cif_dev->resume_mode = 0;
 	memset(&cif_dev->channels[0].capture_info, 0, sizeof(cif_dev->channels[0].capture_info));
 	if (cif_dev->chip_id == CHIP_RV1126_CIF_LITE)
 		cif_dev->isr_hdl = rkcif_irq_lite_handler;
 
 	INIT_WORK(&cif_dev->err_state_work.work, rkcif_err_print_work);
+	INIT_WORK(&cif_dev->sensor_work.work, rkcif_set_sensor_stream);
+	INIT_DELAYED_WORK(&cif_dev->work_deal_err, rkcif_deal_err_intr);
 
 	if (cif_dev->chip_id < CHIP_RV1126_CIF) {
 		if (cif_dev->inf_id == RKCIF_MIPI_LVDS) {
@@ -2118,6 +2150,8 @@
 	struct resource r;
 	int ret;
 
+	cif_dev->is_thunderboot = false;
+	cif_dev->is_rtt_suspend = false;
 	/* Get reserved memory region from Device-tree */
 	np = of_parse_phandle(dev->of_node, "memory-region-thunderboot", 0);
 	if (!np) {
@@ -2133,7 +2167,14 @@
 
 	cif_dev->resmem_pa = r.start;
 	cif_dev->resmem_size = resource_size(&r);
-	cif_dev->is_thunderboot = true;
+	cif_dev->resmem_addr = dma_map_single(dev, phys_to_virt(r.start),
+					      sizeof(struct rkisp_thunderboot_resmem_head),
+					      DMA_BIDIRECTIONAL);
+
+	if (device_property_read_bool(dev, "rtt-suspend"))
+		cif_dev->is_rtt_suspend = true;
+	if (IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP))
+		cif_dev->is_thunderboot = true;
 	dev_info(dev, "Allocated reserved memory, paddr: 0x%x, size 0x%x\n",
 		 (u32)cif_dev->resmem_pa,
 		 (u32)cif_dev->resmem_size);
@@ -2211,6 +2252,22 @@
 	return 0;
 }
 
+static int __maybe_unused rkcif_sleep_suspend(struct device *dev)
+{
+	struct rkcif_device *cif_dev = dev_get_drvdata(dev);
+
+	rkcif_stream_suspend(cif_dev, RKCIF_RESUME_CIF);
+	return 0;
+}
+
+static int __maybe_unused rkcif_sleep_resume(struct device *dev)
+{
+	struct rkcif_device *cif_dev = dev_get_drvdata(dev);
+
+	rkcif_stream_resume(cif_dev, RKCIF_RESUME_CIF);
+	return 0;
+}
+
 static int __maybe_unused rkcif_runtime_suspend(struct device *dev)
 {
 	struct rkcif_device *cif_dev = dev_get_drvdata(dev);
@@ -2281,8 +2338,7 @@
 #endif
 
 static const struct dev_pm_ops rkcif_plat_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
-				pm_runtime_force_resume)
+	SET_SYSTEM_SLEEP_PM_OPS(rkcif_sleep_suspend, rkcif_sleep_resume)
 	SET_RUNTIME_PM_OPS(rkcif_runtime_suspend, rkcif_runtime_resume, NULL)
 };
 
diff --git a/kernel/drivers/media/platform/rockchip/cif/dev.h b/kernel/drivers/media/platform/rockchip/cif/dev.h
index d995f58..31316c0 100644
--- a/kernel/drivers/media/platform/rockchip/cif/dev.h
+++ b/kernel/drivers/media/platform/rockchip/cif/dev.h
@@ -94,6 +94,13 @@
 #define CROP_SRC_SENSOR_MASK		(0x1 << 0)
 #define CROP_SRC_USR_MASK		(0x1 << 1)
 
+/*
+ * max wait time for stream stop
+ */
+#define RKCIF_STOP_MAX_WAIT_TIME_MS	(500)
+
+#define RKCIF_SKIP_FRAME_MAX		(16)
+
 enum rkcif_workmode {
 	RKCIF_WORKMODE_ONEFRAME = 0x00,
 	RKCIF_WORKMODE_PINGPONG = 0x01,
@@ -471,6 +478,18 @@
 	u32 group;
 };
 
+enum rkcif_toisp_buf_update_state {
+	RKCIF_TOISP_BUF_ROTATE,
+	RKCIF_TOISP_BUF_THESAME,
+	RKCIF_TOISP_BUF_LOSS,
+};
+
+struct rkcif_toisp_buf_state {
+	enum rkcif_toisp_buf_update_state state;
+	int check_cnt;
+	bool is_early_update;
+};
+
 /*
  * struct rkcif_stream - Stream states TODO
  *
@@ -530,6 +549,7 @@
 	struct rkcif_rx_buffer		rx_buf[RKISP_VICAP_BUF_CNT_MAX];
 	struct list_head		rx_buf_head;
 	int				total_buf_num;
+	int				rx_buf_num;
 	u64				line_int_cnt;
 	int				lack_buf_cnt;
 	unsigned int			buf_wake_up_cnt;
@@ -540,6 +560,10 @@
 	int				last_frame_idx;
 	int				new_fource_idx;
 	atomic_t			buf_cnt;
+	struct completion		stop_complete;
+	struct rkcif_toisp_buf_state	toisp_buf_state;
+	u32				skip_frame;
+	u32				cur_skip_frame;
 	bool				stopping;
 	bool				crop_enable;
 	bool				crop_dyn_en;
@@ -557,6 +581,8 @@
 	bool				is_change_toisp;
 	bool				is_stop_capture;
 	bool				is_wait_dma_stop;
+	bool				is_single_cap;
+	bool				is_wait_stop_complete;
 };
 
 struct rkcif_lvds_subdev {
@@ -792,6 +818,20 @@
 	u32 intstat;
 	u32 lastline;
 	u32 lastpixel;
+	u32 size_id0;
+	u32 size_id1;
+	u32 size_id2;
+	u32 size_id3;
+};
+
+enum rkcif_resume_user {
+	RKCIF_RESUME_CIF,
+	RKCIF_RESUME_ISP,
+};
+
+struct rkcif_sensor_work {
+	struct work_struct work;
+	int on;
 };
 
 /*
@@ -822,6 +862,7 @@
 	int				chip_id;
 	atomic_t			stream_cnt;
 	atomic_t			power_cnt;
+	atomic_t			streamoff_cnt;
 	struct mutex			stream_lock; /* lock between streams */
 	struct mutex			scale_lock; /* lock between scale dev */
 	struct mutex			tools_lock; /* lock between tools dev */
@@ -854,6 +895,7 @@
 	struct completion		cmpl_ntf;
 	struct csi2_dphy_hw		*dphy_hw;
 	phys_addr_t			resmem_pa;
+	dma_addr_t			resmem_addr;
 	size_t				resmem_size;
 	struct rk_tb_client		tb_client;
 	bool				is_start_hdr;
@@ -864,6 +906,9 @@
 	bool				is_thunderboot;
 	bool				is_rdbk_to_online;
 	bool				is_support_tools;
+	bool				is_rtt_suspend;
+	bool				sensor_state_change;
+	bool				is_toisp_reset;
 	int				rdbk_debug;
 	struct rkcif_sync_cfg		sync_cfg;
 	int				sditf_cnt;
@@ -872,6 +917,14 @@
 	int				sensor_linetime;
 	u32				err_state;
 	struct rkcif_err_state_work	err_state_work;
+	struct rkcif_sensor_work	sensor_work;
+	int				resume_mode;
+	u32				nr_buf_size;
+	u32				share_mem_size;
+	u32				thunderboot_sensor_num;
+	int				sensor_state;
+	u32				intr_mask;
+	struct delayed_work		work_deal_err;
 };
 
 extern struct platform_driver rkcif_plat_drv;
@@ -968,5 +1021,15 @@
 void rkcif_rockit_dev_deinit(void);
 
 void rkcif_err_print_work(struct work_struct *work);
+int rkcif_stream_suspend(struct rkcif_device *cif_dev, int mode);
+int rkcif_stream_resume(struct rkcif_device *cif_dev, int mode);
+
+static inline u64 rkcif_time_get_ns(struct rkcif_device *dev)
+{
+	if (dev->chip_id == CHIP_RV1106_CIF)
+		return ktime_get_boottime_ns();
+	else
+		return ktime_get_ns();
+}
 
 #endif
diff --git a/kernel/drivers/media/platform/rockchip/cif/hw.c b/kernel/drivers/media/platform/rockchip/cif/hw.c
index bf56539..9b4a1c3 100644
--- a/kernel/drivers/media/platform/rockchip/cif/hw.c
+++ b/kernel/drivers/media/platform/rockchip/cif/hw.c
@@ -23,7 +23,6 @@
 #include <media/videobuf2-dma-sg.h>
 #include <media/v4l2-fwnode.h>
 #include <linux/iommu.h>
-#include <dt-bindings/soc/rockchip-system-status.h>
 #include <soc/rockchip/rockchip-system-status.h>
 #include <linux/io.h>
 #include <linux/mfd/syscon.h>
@@ -699,6 +698,10 @@
 	[CIF_REG_MIPI_EFFECT_CODE_ID1] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID1),
 	[CIF_REG_MIPI_EFFECT_CODE_ID2] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID2),
 	[CIF_REG_MIPI_EFFECT_CODE_ID3] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID3),
+	[CIF_REG_MIPI_FRAME_SIZE_ID0] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID0),
+	[CIF_REG_MIPI_FRAME_SIZE_ID1] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID1),
+	[CIF_REG_MIPI_FRAME_SIZE_ID2] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID2),
+	[CIF_REG_MIPI_FRAME_SIZE_ID3] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID3),
 	[CIF_REG_MIPI_ON_PAD] = CIF_REG(CSI_MIPI0_ON_PAD),
 
 	[CIF_REG_GLB_CTRL] = CIF_REG(GLB_CTRL),
@@ -823,6 +826,10 @@
 	[CIF_REG_MIPI_EFFECT_CODE_ID1] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID1),
 	[CIF_REG_MIPI_EFFECT_CODE_ID2] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID2),
 	[CIF_REG_MIPI_EFFECT_CODE_ID3] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID3),
+	[CIF_REG_MIPI_FRAME_SIZE_ID0] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID0),
+	[CIF_REG_MIPI_FRAME_SIZE_ID1] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID1),
+	[CIF_REG_MIPI_FRAME_SIZE_ID2] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID2),
+	[CIF_REG_MIPI_FRAME_SIZE_ID3] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID3),
 	[CIF_REG_MIPI_ON_PAD] = CIF_REG(CSI_MIPI0_ON_PAD),
 	[CIF_REG_LVDS_ID0_CTRL0] = CIF_REG(CIF_LVDS0_ID0_CTRL0),
 	[CIF_REG_LVDS_ID1_CTRL0] = CIF_REG(CIF_LVDS0_ID1_CTRL0),
@@ -942,6 +949,10 @@
 	[CIF_REG_MIPI_EFFECT_CODE_ID1] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID1),
 	[CIF_REG_MIPI_EFFECT_CODE_ID2] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID2),
 	[CIF_REG_MIPI_EFFECT_CODE_ID3] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID3),
+	[CIF_REG_MIPI_FRAME_SIZE_ID0] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID0),
+	[CIF_REG_MIPI_FRAME_SIZE_ID1] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID1),
+	[CIF_REG_MIPI_FRAME_SIZE_ID2] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID2),
+	[CIF_REG_MIPI_FRAME_SIZE_ID3] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID3),
 	[CIF_REG_MIPI_ON_PAD] = CIF_REG(CSI_MIPI0_ON_PAD),
 
 	[CIF_REG_GLB_CTRL] = CIF_REG(GLB_CTRL),
@@ -1538,7 +1549,38 @@
 	return 0;
 }
 
+static int __maybe_unused rkcif_sleep_suspend(struct device *dev)
+{
+	struct rkcif_hw *cif_hw = dev_get_drvdata(dev);
+
+	if (atomic_read(&cif_hw->power_cnt) == 0)
+		return 0;
+
+	rkcif_disable_sys_clk(cif_hw);
+
+	return pinctrl_pm_select_sleep_state(dev);
+}
+
+static int __maybe_unused rkcif_sleep_resume(struct device *dev)
+{
+	struct rkcif_hw *cif_hw = dev_get_drvdata(dev);
+	int ret;
+
+	if (atomic_read(&cif_hw->power_cnt) == 0)
+		return 0;
+
+	ret = pinctrl_pm_select_default_state(dev);
+	if (ret < 0)
+		return ret;
+	rkcif_enable_sys_clk(cif_hw);
+	rkcif_hw_soft_reset(cif_hw, true);
+
+	return 0;
+}
+
 static const struct dev_pm_ops rkcif_plat_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(rkcif_sleep_suspend,
+				rkcif_sleep_resume)
 	SET_RUNTIME_PM_OPS(rkcif_runtime_suspend, rkcif_runtime_resume, NULL)
 };
 
diff --git a/kernel/drivers/media/platform/rockchip/cif/mipi-csi2.c b/kernel/drivers/media/platform/rockchip/cif/mipi-csi2.c
index f526b43..57d8166 100644
--- a/kernel/drivers/media/platform/rockchip/cif/mipi-csi2.c
+++ b/kernel/drivers/media/platform/rockchip/cif/mipi-csi2.c
@@ -141,7 +141,7 @@
 		break;
 	default:
 		v4l2_warn(&csi2->sd, "lane num is invalid\n");
-		csi2->bus.num_data_lanes = 0;
+		csi2->bus.num_data_lanes = 4;
 		break;
 	}
 
@@ -252,6 +252,8 @@
 			v4l2_err(&csi2->sd, "%s: enable clks failed\n", __func__);
 			return ret;
 		}
+		enable_irq(csi2->csi2_hw[csi_idx]->irq1);
+		enable_irq(csi2->csi2_hw[csi_idx]->irq2);
 		csi2_enable(csi2->csi2_hw[csi_idx], host_type);
 	}
 
@@ -269,6 +271,8 @@
 err_assert_reset:
 	for (i = 0; i < csi2->csi_info.csi_num; i++) {
 		csi_idx = csi2->csi_info.csi_idx[i];
+		disable_irq(csi2->csi2_hw[csi_idx]->irq1);
+		disable_irq(csi2->csi2_hw[csi_idx]->irq2);
 		csi2_disable(csi2->csi2_hw[csi_idx]);
 		csi2_disable_clks(csi2->csi2_hw[csi_idx]);
 	}
@@ -286,6 +290,8 @@
 
 	for (i = 0; i < csi2->csi_info.csi_num; i++) {
 		csi_idx = csi2->csi_info.csi_idx[i];
+		disable_irq(csi2->csi2_hw[csi_idx]->irq1);
+		disable_irq(csi2->csi2_hw[csi_idx]->irq2);
 		csi2_disable(csi2->csi2_hw[csi_idx]);
 		csi2_hw_do_reset(csi2->csi2_hw[csi_idx]);
 		csi2_disable_clks(csi2->csi2_hw[csi_idx]);
@@ -399,6 +405,7 @@
 	csi2->crop.left = 0;
 	csi2->crop.width = RKCIF_DEFAULT_WIDTH;
 	csi2->crop.height = RKCIF_DEFAULT_HEIGHT;
+	csi2->bus.num_data_lanes = 4;
 
 	return media_entity_pads_init(&sd->entity, num_pads, csi2->pad);
 }
@@ -664,15 +671,10 @@
 			       struct v4l2_fwnode_endpoint *vep,
 			       struct v4l2_async_subdev *asd)
 {
-	struct v4l2_subdev *sd = dev_get_drvdata(dev);
-	struct csi2_dev *csi2 = sd_to_dev(sd);
-
 	if (vep->base.port != 0) {
 		dev_err(dev, "The csi host node needs to parse port 0\n");
 		return -EINVAL;
 	}
-
-	csi2->bus = vep->bus.mipi_csi2;
 
 	return 0;
 }
@@ -777,7 +779,7 @@
 {
 	struct device *dev = ctx;
 	struct csi2_hw *csi2_hw = dev_get_drvdata(dev);
-	struct csi2_dev *csi2 = csi2_hw->csi2;
+	struct csi2_dev *csi2 = NULL;
 	struct csi2_err_stats *err_list = NULL;
 	unsigned long err_stat = 0;
 	u32 val;
@@ -786,6 +788,16 @@
 	char vc_info[CSI_VCINFO_LEN] = {0};
 	bool is_add_cnt = false;
 
+	if (!csi2_hw) {
+		disable_irq_nosync(irq);
+		return IRQ_HANDLED;
+	}
+
+	csi2 = csi2_hw->csi2;
+	if (!csi2) {
+		disable_irq_nosync(irq);
+		return IRQ_HANDLED;
+	}
 	val = read_csihost_reg(csi2_hw->base, CSIHOST_ERR1);
 	if (val) {
 		if (val & CSIHOST_ERR1_PHYERR_SPTSYNCHS) {
@@ -885,6 +897,11 @@
 	char cur_str[CSI_ERRSTR_LEN] = {0};
 	char err_str[CSI_ERRSTR_LEN] = {0};
 	char vc_info[CSI_VCINFO_LEN] = {0};
+
+	if (!csi2_hw) {
+		disable_irq_nosync(irq);
+		return IRQ_HANDLED;
+	}
 
 	val = read_csihost_reg(csi2_hw->base, CSIHOST_ERR2);
 	if (val) {
@@ -1262,6 +1279,7 @@
 
 	irq = platform_get_irq_byname(pdev, "csi-intr1");
 	if (irq > 0) {
+		irq_set_status_flags(irq, IRQ_NOAUTOEN);
 		ret = devm_request_irq(&pdev->dev, irq,
 				       rk_csirx_irq1_handler, 0,
 				       dev_driver_string(&pdev->dev),
@@ -1276,6 +1294,7 @@
 
 	irq = platform_get_irq_byname(pdev, "csi-intr2");
 	if (irq > 0) {
+		irq_set_status_flags(irq, IRQ_NOAUTOEN);
 		ret = devm_request_irq(&pdev->dev, irq,
 				       rk_csirx_irq2_handler, 0,
 				       dev_driver_string(&pdev->dev),
diff --git a/kernel/drivers/media/platform/rockchip/cif/regs.h b/kernel/drivers/media/platform/rockchip/cif/regs.h
index fccd005..68bc6ef 100644
--- a/kernel/drivers/media/platform/rockchip/cif/regs.h
+++ b/kernel/drivers/media/platform/rockchip/cif/regs.h
@@ -145,6 +145,10 @@
 	CIF_REG_LVDS_ID1_CTRL0,
 	CIF_REG_LVDS_ID2_CTRL0,
 	CIF_REG_LVDS_ID3_CTRL0,
+	CIF_REG_MIPI_FRAME_SIZE_ID0,
+	CIF_REG_MIPI_FRAME_SIZE_ID1,
+	CIF_REG_MIPI_FRAME_SIZE_ID2,
+	CIF_REG_MIPI_FRAME_SIZE_ID3,
 	CIF_REG_MIPI_ON_PAD,
 
 	CIF_REG_Y_STAT_CONTROL,
@@ -421,6 +425,11 @@
 #define CSI_MIPI0_EFFECT_CODE_ID3	0x1B8
 #define CSI_MIPI0_ON_PAD		0x1BC
 
+#define CSI_MIPI0_FRAME_SIZE_ID0	0x1C0
+#define CSI_MIPI0_FRAME_SIZE_ID1	0x1C4
+#define CSI_MIPI0_FRAME_SIZE_ID2	0x1C8
+#define CSI_MIPI0_FRAME_SIZE_ID3	0x1CC
+
 /* RV1106 CONTROL Registers Offset */
 #define CIF_LVDS0_ID0_CTRL0		0x1D0
 #define CIF_LVDS0_ID1_CTRL0		0x1D4
diff --git a/kernel/drivers/media/platform/rockchip/cif/subdev-itf.c b/kernel/drivers/media/platform/rockchip/cif/subdev-itf.c
index 01aefd4..441b7df 100644
--- a/kernel/drivers/media/platform/rockchip/cif/subdev-itf.c
+++ b/kernel/drivers/media/platform/rockchip/cif/subdev-itf.c
@@ -283,14 +283,14 @@
 	struct rkcif_device *cif_dev = priv->cif_dev;
 
 	if (priv->hdr_cfg.hdr_mode == HDR_X2) {
-		rkcif_free_rx_buf(&cif_dev->stream[0], priv->buf_num);
-		rkcif_free_rx_buf(&cif_dev->stream[1], priv->buf_num);
+		rkcif_free_rx_buf(&cif_dev->stream[0], cif_dev->stream[0].rx_buf_num);
+		rkcif_free_rx_buf(&cif_dev->stream[1], cif_dev->stream[1].rx_buf_num);
 	} else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
-		rkcif_free_rx_buf(&cif_dev->stream[0], priv->buf_num);
-		rkcif_free_rx_buf(&cif_dev->stream[1], priv->buf_num);
-		rkcif_free_rx_buf(&cif_dev->stream[2], priv->buf_num);
+		rkcif_free_rx_buf(&cif_dev->stream[0], cif_dev->stream[0].rx_buf_num);
+		rkcif_free_rx_buf(&cif_dev->stream[1], cif_dev->stream[1].rx_buf_num);
+		rkcif_free_rx_buf(&cif_dev->stream[2], cif_dev->stream[2].rx_buf_num);
 	} else {
-		rkcif_free_rx_buf(&cif_dev->stream[0], priv->buf_num);
+		rkcif_free_rx_buf(&cif_dev->stream[0], cif_dev->stream[0].rx_buf_num);
 	}
 	if (cif_dev->is_thunderboot) {
 		cif_dev->wait_line_cache = 0;
@@ -327,6 +327,7 @@
 		 __func__, mode->rdbk_mode, mode->name, priv->toisp_inf.link_mode);
 }
 
+static void sditf_channel_disable(struct sditf_priv *priv, int user);
 static long sditf_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
 	struct sditf_priv *priv = to_sditf_priv(sd);
@@ -336,11 +337,14 @@
 	struct v4l2_subdev *sensor_sd;
 	int *pbuf_num = NULL;
 	int ret = 0;
+	int *on = NULL;
 
 	switch (cmd) {
 	case RKISP_VICAP_CMD_MODE:
 		mode = (struct rkisp_vicap_mode *)arg;
+		mutex_lock(&cif_dev->stream_lock);
 		memcpy(&priv->mode, mode, sizeof(*mode));
+		mutex_unlock(&cif_dev->stream_lock);
 		sditf_reinit_mode(priv, &priv->mode);
 		if (priv->is_combine_mode)
 			mode->input.merge_num = cif_dev->sditf_cnt;
@@ -363,6 +367,28 @@
 			return v4l2_subdev_call(sensor_sd, core, ioctl, cmd, arg);
 		}
 		break;
+	case RKISP_VICAP_CMD_QUICK_STREAM:
+		on = (int *)arg;
+		if (*on) {
+			rkcif_stream_resume(cif_dev, RKCIF_RESUME_ISP);
+		} else {
+			if (priv->toisp_inf.link_mode == TOISP0) {
+				sditf_channel_disable(priv, 0);
+			} else if (priv->toisp_inf.link_mode == TOISP1) {
+				sditf_channel_disable(priv, 1);
+			} else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
+				sditf_channel_disable(priv, 0);
+				sditf_channel_disable(priv, 1);
+			}
+			rkcif_stream_suspend(cif_dev, RKCIF_RESUME_ISP);
+		}
+		break;
+	case RKISP_VICAP_CMD_SET_RESET:
+		if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) {
+			cif_dev->is_toisp_reset = true;
+			return 0;
+		}
+		break;
 	default:
 		break;
 	}
@@ -382,6 +408,7 @@
 	struct rkmodule_hdr_cfg	*hdr_cfg;
 	int buf_num;
 	int ret = 0;
+	int on;
 
 	switch (cmd) {
 	case RKISP_VICAP_CMD_MODE:
@@ -413,6 +440,14 @@
 			return -EFAULT;
 		}
 		ret = sditf_ioctl(sd, cmd, hdr_cfg);
+		return ret;
+	case RKISP_VICAP_CMD_QUICK_STREAM:
+		if (copy_from_user(&on, up, sizeof(int)))
+			return -EFAULT;
+		ret = sditf_ioctl(sd, cmd, &on);
+		return ret;
+	case RKISP_VICAP_CMD_SET_RESET:
+		ret = sditf_ioctl(sd, cmd, NULL);
 		return ret;
 	default:
 		break;
@@ -464,9 +499,9 @@
 			ch0 = 24;//dvp
 		ctrl_val = (ch0 << 3) | 0x1;
 		if (user == 0)
-			int_en = CIF_TOISP0_FS(0);
+			int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FE(0);
 		else
-			int_en = CIF_TOISP1_FS(0);
+			int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FE(0);
 		priv->toisp_inf.ch_info[0].is_valid = true;
 		priv->toisp_inf.ch_info[0].id = ch0;
 	} else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
@@ -475,9 +510,11 @@
 		ctrl_val = (ch0 << 3) | 0x1;
 		ctrl_val |= (ch1 << 11) | 0x100;
 		if (user == 0)
-			int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FS(1);
+			int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FS(1) |
+				 CIF_TOISP0_FE(0) | CIF_TOISP0_FE(1);
 		else
-			int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FS(1);
+			int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FS(1) |
+				 CIF_TOISP1_FE(0) | CIF_TOISP1_FE(1);
 		priv->toisp_inf.ch_info[0].is_valid = true;
 		priv->toisp_inf.ch_info[0].id = ch0;
 		priv->toisp_inf.ch_info[1].is_valid = true;
@@ -490,9 +527,11 @@
 		ctrl_val |= (ch1 << 11) | 0x100;
 		ctrl_val |= (ch2 << 19) | 0x10000;
 		if (user == 0)
-			int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FS(1) | CIF_TOISP0_FS(2);
+			int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FS(1) | CIF_TOISP0_FS(2) |
+				 CIF_TOISP0_FE(0) | CIF_TOISP0_FE(1) | CIF_TOISP0_FE(2);
 		else
-			int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FS(1) | CIF_TOISP1_FS(2);
+			int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FS(1) | CIF_TOISP1_FS(2) |
+				 CIF_TOISP1_FE(0) | CIF_TOISP1_FE(1) | CIF_TOISP1_FE(2);
 		priv->toisp_inf.ch_info[0].is_valid = true;
 		priv->toisp_inf.ch_info[0].id = ch0;
 		priv->toisp_inf.ch_info[1].is_valid = true;
@@ -587,22 +626,41 @@
 		sditf_channel_enable(priv, 0);
 		sditf_channel_enable(priv, 1);
 	}
-	if (priv->hdr_cfg.hdr_mode == NO_HDR) {
-		rkcif_free_rx_buf(&cif_dev->stream[0], priv->buf_num);
-		cif_dev->stream[0].is_line_wake_up = false;
-	} else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
-		rkcif_free_rx_buf(&cif_dev->stream[1], priv->buf_num);
-		cif_dev->stream[0].is_line_wake_up = false;
-		cif_dev->stream[1].is_line_wake_up = false;
-	} else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
-		rkcif_free_rx_buf(&cif_dev->stream[2], priv->buf_num);
-		cif_dev->stream[0].is_line_wake_up = false;
-		cif_dev->stream[1].is_line_wake_up = false;
-		cif_dev->stream[2].is_line_wake_up = false;
+
+	if (cif_dev->is_thunderboot) {
+		if (priv->hdr_cfg.hdr_mode == NO_HDR) {
+			rkcif_free_rx_buf(&cif_dev->stream[0], cif_dev->stream[0].rx_buf_num);
+			cif_dev->stream[0].is_line_wake_up = false;
+		} else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
+			rkcif_free_rx_buf(&cif_dev->stream[1], cif_dev->stream[1].rx_buf_num);
+			cif_dev->stream[0].is_line_wake_up = false;
+			cif_dev->stream[1].is_line_wake_up = false;
+		} else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
+			rkcif_free_rx_buf(&cif_dev->stream[2], cif_dev->stream[2].rx_buf_num);
+			cif_dev->stream[0].is_line_wake_up = false;
+			cif_dev->stream[1].is_line_wake_up = false;
+			cif_dev->stream[2].is_line_wake_up = false;
+		}
+		cif_dev->wait_line_cache = 0;
+		cif_dev->wait_line = 0;
+		cif_dev->wait_line_bak = 0;
+		cif_dev->is_thunderboot = false;
 	}
-	cif_dev->wait_line_cache = 0;
-	cif_dev->wait_line = 0;
-	cif_dev->wait_line_bak = 0;
+}
+
+void sditf_disable_immediately(struct sditf_priv *priv)
+{
+	struct rkcif_device *cif_dev = priv->cif_dev;
+	u32 ctrl_val = 0x10101;
+
+	if (priv->toisp_inf.link_mode == TOISP0) {
+		rkcif_write_register_and(cif_dev, CIF_REG_TOISP0_CTRL, ~ctrl_val);
+	} else if (priv->toisp_inf.link_mode == TOISP1) {
+		rkcif_write_register_and(cif_dev, CIF_REG_TOISP1_CTRL, ~ctrl_val);
+	} else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
+		rkcif_write_register_and(cif_dev, CIF_REG_TOISP0_CTRL, ~ctrl_val);
+		rkcif_write_register_and(cif_dev, CIF_REG_TOISP1_CTRL, ~ctrl_val);
+	}
 }
 
 static void sditf_check_capture_mode(struct rkcif_device *cif_dev)
@@ -627,39 +685,36 @@
 	struct rkcif_device *cif_dev = priv->cif_dev;
 	struct v4l2_subdev_format fmt;
 	unsigned int mode = RKCIF_STREAM_MODE_TOISP;
-	int ret = 0;
 
 	sditf_check_capture_mode(cif_dev);
 	sditf_get_set_fmt(&priv->sd, NULL, &fmt);
 	if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) {
 		if (priv->toisp_inf.link_mode == TOISP0) {
-			ret = sditf_channel_enable(priv, 0);
+			sditf_channel_enable(priv, 0);
 		} else if (priv->toisp_inf.link_mode == TOISP1) {
-			ret = sditf_channel_enable(priv, 1);
+			sditf_channel_enable(priv, 1);
 		} else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
-			ret = sditf_channel_enable(priv, 0);
-			ret |= sditf_channel_enable(priv, 1);
+			sditf_channel_enable(priv, 0);
+			sditf_channel_enable(priv, 1);
 		}
 		mode = RKCIF_STREAM_MODE_TOISP;
 	} else if (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) {
 		mode = RKCIF_STREAM_MODE_TOISP_RDBK;
 	}
-	if (ret)
-		return ret;
 
 	if (priv->hdr_cfg.hdr_mode == NO_HDR ||
 	    priv->hdr_cfg.hdr_mode == HDR_COMPR) {
-		ret = rkcif_do_start_stream(&cif_dev->stream[0], mode);
+		rkcif_do_start_stream(&cif_dev->stream[0], mode);
 	} else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
-		ret = rkcif_do_start_stream(&cif_dev->stream[0], mode);
-		ret |= rkcif_do_start_stream(&cif_dev->stream[1], mode);
+		rkcif_do_start_stream(&cif_dev->stream[0], mode);
+		rkcif_do_start_stream(&cif_dev->stream[1], mode);
 	} else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
-		ret = rkcif_do_start_stream(&cif_dev->stream[0], mode);
-		ret |= rkcif_do_start_stream(&cif_dev->stream[1], mode);
-		ret |= rkcif_do_start_stream(&cif_dev->stream[2], mode);
+		rkcif_do_start_stream(&cif_dev->stream[0], mode);
+		rkcif_do_start_stream(&cif_dev->stream[1], mode);
+		rkcif_do_start_stream(&cif_dev->stream[2], mode);
 	}
 	INIT_LIST_HEAD(&priv->buf_free_list);
-	return ret;
+	return 0;
 }
 
 static int sditf_stop_stream(struct sditf_priv *priv)
@@ -718,6 +773,7 @@
 		} else {
 			ret = sditf_stop_stream(priv);
 			sditf_free_buf(priv);
+			priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ;
 		}
 
 	}
@@ -806,7 +862,7 @@
 		return -EINVAL;
 
 	rx_buf = to_cif_rx_buf(dbufs);
-	v4l2_dbg(rkcif_debug, 3, &cif_dev->v4l2_dev, "buf back to vicap 0x%x\n",
+	v4l2_dbg(3, rkcif_debug, &cif_dev->v4l2_dev, "buf back to vicap 0x%x\n",
 		 (u32)rx_buf->dummy.dma_addr);
 	spin_lock_irqsave(&stream->vbq_lock, flags);
 	stream->last_rx_buf_idx = dbufs->sequence + 1;
@@ -814,6 +870,7 @@
 
 	if (!list_empty(&stream->rx_buf_head) &&
 	    cif_dev->is_thunderboot &&
+	    (!cif_dev->is_rtt_suspend) &&
 	    (dbufs->type == BUF_SHORT ||
 	     (dbufs->type != BUF_SHORT && (!dbufs->is_switch)))) {
 		spin_lock_irqsave(&cif_dev->buffree_lock, buffree_flags);
@@ -827,7 +884,15 @@
 
 	if (!is_free && (!dbufs->is_switch)) {
 		list_add_tail(&rx_buf->list, &stream->rx_buf_head);
-		rkcif_assign_check_buffer_update_toisp(stream);
+		if (cif_dev->resume_mode != RKISP_RTT_MODE_ONE_FRAME) {
+			rkcif_assign_check_buffer_update_toisp(stream);
+			if (!stream->dma_en) {
+				stream->to_en_dma = RKCIF_DMAEN_BY_ISP;
+				rkcif_enable_dma_capture(stream, true);
+				cif_dev->sensor_work.on = 1;
+				schedule_work(&cif_dev->sensor_work.work);
+			}
+		}
 		if (cif_dev->rdbk_debug) {
 			u32 offset = 0;
 
@@ -855,6 +920,10 @@
 	}
 	spin_unlock_irqrestore(&stream->vbq_lock, flags);
 
+	if (!cif_dev->is_thunderboot ||
+	    cif_dev->is_rdbk_to_online == false)
+		return 0;
+
 	if (dbufs->runtime_us && cif_dev->early_line == 0) {
 		if (!cif_dev->sensor_linetime)
 			cif_dev->sensor_linetime = rkcif_get_linetime(stream);
diff --git a/kernel/drivers/media/platform/rockchip/cif/subdev-itf.h b/kernel/drivers/media/platform/rockchip/cif/subdev-itf.h
index 1c917f2..58c6309 100644
--- a/kernel/drivers/media/platform/rockchip/cif/subdev-itf.h
+++ b/kernel/drivers/media/platform/rockchip/cif/subdev-itf.h
@@ -84,5 +84,6 @@
 
 extern struct platform_driver rkcif_subdev_driver;
 void sditf_change_to_online(struct sditf_priv *priv);
+void sditf_disable_immediately(struct sditf_priv *priv);
 
 #endif
diff --git a/kernel/drivers/media/platform/rockchip/hdmirx/Kconfig b/kernel/drivers/media/platform/rockchip/hdmirx/Kconfig
index be9ea70..aa4d7a4 100644
--- a/kernel/drivers/media/platform/rockchip/hdmirx/Kconfig
+++ b/kernel/drivers/media/platform/rockchip/hdmirx/Kconfig
@@ -20,6 +20,7 @@
 	select VIDEOBUF2_DMA_CONTIG
 	select HDMI
 	select VIDEO_ROCKCHIP_HDMIRX_CLASS
+	select CEC_CORE
 	help
 	  Support for Rockchip HDMI RX PHY and Controller.
 	  This driver supports HDMI 2.0 version.
diff --git a/kernel/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c b/kernel/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c
index dcd49b6..d3c54ba 100644
--- a/kernel/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c
+++ b/kernel/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c
@@ -5,11 +5,11 @@
  * Author: Dingxian Wen <shawn.wen@rock-chips.com>
  */
 
-#include <dt-bindings/soc/rockchip-system-status.h>
 #include <linux/clk.h>
 #include <linux/cpufreq.h>
 #include <linux/debugfs.h>
 #include <linux/delay.h>
+#include <linux/dma-fence.h>
 #include <linux/dma-mapping.h>
 #include <linux/extcon-provider.h>
 #include <linux/fs.h>
@@ -30,11 +30,13 @@
 #include <linux/rk_hdmirx_config.h>
 #include <linux/rockchip/rockchip_sip.h>
 #include <linux/seq_file.h>
+#include <linux/sync_file.h>
 #include <linux/v4l2-dv-timings.h>
 #include <linux/workqueue.h>
 #include <media/cec.h>
 #include <media/cec-notifier.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-controls_rockchip.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-dv-timings.h>
@@ -52,7 +54,11 @@
 
 static int debug;
 module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "debug level (0-3)");
+MODULE_PARM_DESC(debug, "debug level (0-4)");
+
+static bool low_latency;
+module_param(low_latency, bool, 0644);
+MODULE_PARM_DESC(low_latency, "low_latency en(0-1)");
 
 #define	RK_HDMIRX_DRVNAME		"rk_hdmirx"
 #define EDID_NUM_BLOCKS_MAX		2
@@ -143,6 +149,12 @@
 	enum hdmirx_reg_attr attr;
 };
 
+struct hdmirx_fence_context {
+	u64 context;
+	u64 seqno;
+	spinlock_t spinlock;
+};
+
 struct hdmirx_buffer {
 	struct vb2_v4l2_buffer vb;
 	struct list_head queue;
@@ -177,6 +189,12 @@
 	u32 irq_stat;
 };
 
+struct hdmirx_fence {
+	struct list_head fence_list;
+	struct dma_fence *fence;
+	int fence_fd;
+};
+
 struct rk_hdmirx_dev {
 	struct cec_notifier *cec_notifier;
 	struct cpufreq_policy *policy;
@@ -188,6 +206,8 @@
 	struct v4l2_device v4l2_dev;
 	struct v4l2_ctrl_handler hdl;
 	struct v4l2_ctrl *detect_tx_5v_ctrl;
+	struct v4l2_ctrl *audio_sampling_rate_ctrl;
+	struct v4l2_ctrl *audio_present_ctrl;
 	struct v4l2_dv_timings timings;
 	struct gpio_desc *hdmirx_det_gpio;
 	struct work_struct work_wdt_config;
@@ -201,6 +221,7 @@
 	struct hdmirx_audiostate audio_state;
 	struct extcon_dev *extcon;
 	struct hdmirx_cec *cec;
+	struct hdmirx_fence_context fence_ctx;
 	struct mutex stream_lock;
 	struct mutex work_lock;
 	struct pm_qos_request pm_qos;
@@ -212,6 +233,9 @@
 	struct regmap *grf;
 	struct regmap *vo1_grf;
 	struct rk_hdmirx_hdcp *hdcp;
+	struct hdmirx_fence *hdmirx_fence;
+	struct list_head qbuf_fence_list_head;
+	struct list_head done_fence_list_head;
 	void __iomem *regs;
 	int edid_version;
 	int audio_present;
@@ -243,11 +267,13 @@
 	u32 color_depth;
 	u32 cpu_freq_khz;
 	u32 bound_cpu;
+	u32 phy_cpuid;
 	u32 fps;
 	u32 wdt_cfg_bound_cpu;
 	u8 edid[EDID_BLOCK_SIZE * 2];
 	hdmi_codec_plugged_cb plugged_cb;
 	spinlock_t rst_lock;
+	spinlock_t fence_lock;
 };
 
 static const unsigned int hdmirx_extcon_cable[] = {
@@ -410,6 +436,64 @@
 	return val;
 }
 
+static const char *hdmirx_fence_get_name(struct dma_fence *fence)
+{
+	return RK_HDMIRX_DRVNAME;
+}
+
+static const struct dma_fence_ops hdmirx_fence_ops = {
+	.get_driver_name = hdmirx_fence_get_name,
+	.get_timeline_name = hdmirx_fence_get_name,
+};
+
+static void hdmirx_fence_context_init(struct hdmirx_fence_context *fence_ctx)
+{
+	fence_ctx->context = dma_fence_context_alloc(1);
+	spin_lock_init(&fence_ctx->spinlock);
+}
+
+static struct dma_fence *hdmirx_dma_fence_alloc(struct hdmirx_fence_context *fence_ctx)
+{
+	struct dma_fence *fence = NULL;
+
+	if (fence_ctx == NULL) {
+		pr_err("fence_context is NULL!\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	fence = kzalloc(sizeof(*fence), GFP_KERNEL);
+	if (!fence)
+		return ERR_PTR(-ENOMEM);
+
+	dma_fence_init(fence, &hdmirx_fence_ops, &fence_ctx->spinlock,
+		       fence_ctx->context, ++fence_ctx->seqno);
+
+	return fence;
+}
+
+static int hdmirx_dma_fence_get_fd(struct dma_fence *fence)
+{
+	struct sync_file *sync_file = NULL;
+	int fence_fd = -1;
+
+	if (!fence)
+		return -EINVAL;
+
+	fence_fd = get_unused_fd_flags(O_CLOEXEC);
+	if (fence_fd < 0)
+		return fence_fd;
+
+	sync_file = sync_file_create(fence);
+	if (!sync_file) {
+		put_unused_fd(fence_fd);
+		return -ENOMEM;
+	}
+
+	fd_install(fence_fd, sync_file->file);
+
+	return fence_fd;
+}
+
 static void hdmirx_reset_dma(struct rk_hdmirx_dev *hdmirx_dev)
 {
 	unsigned long lock_flags = 0;
@@ -471,6 +555,7 @@
 	case V4L2_EVENT_CTRL:
 		return v4l2_ctrl_subscribe_event(fh, sub);
 	case RK_HDMIRX_V4L2_EVENT_SIGNAL_LOST:
+	case RK_HDMIRX_V4L2_EVENT_AUDIOINFO:
 		return v4l2_event_subscribe(fh, sub, 0, NULL);
 
 	default:
@@ -1931,6 +2016,39 @@
 	return 0;
 }
 
+static void hdmirx_qbuf_alloc_fence(struct rk_hdmirx_dev *hdmirx_dev)
+{
+	struct dma_fence *fence;
+	int fence_fd;
+	struct hdmirx_fence *hdmirx_fence;
+	unsigned long lock_flags = 0;
+	struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
+
+	fence = hdmirx_dma_fence_alloc(&hdmirx_dev->fence_ctx);
+	if (!IS_ERR(fence)) {
+		fence_fd = hdmirx_dma_fence_get_fd(fence);
+		if (fence_fd >= 0) {
+			hdmirx_fence = kzalloc(sizeof(struct hdmirx_fence), GFP_KERNEL);
+			if (!hdmirx_fence) {
+				v4l2_err(v4l2_dev, "%s: failed to alloc hdmirx_fence!\n", __func__);
+				return;
+			}
+			hdmirx_fence->fence = fence;
+			hdmirx_fence->fence_fd = fence_fd;
+			spin_lock_irqsave(&hdmirx_dev->fence_lock, lock_flags);
+			list_add_tail(&hdmirx_fence->fence_list, &hdmirx_dev->qbuf_fence_list_head);
+			spin_unlock_irqrestore(&hdmirx_dev->fence_lock, lock_flags);
+			v4l2_dbg(3, debug, v4l2_dev, "%s: fence:%p, fence_fd:%d\n",
+				 __func__, fence, fence_fd);
+		} else {
+			dma_fence_put(fence);
+			v4l2_err(v4l2_dev, "%s: failed to get fence fd!\n", __func__);
+		}
+	} else {
+		v4l2_err(v4l2_dev, "%s: alloc fence failed!\n", __func__);
+	}
+}
+
 /*
  * The vb2_buffer are stored in hdmirx_buffer, in order to unify
  * mplane buffer and none-mplane buffer.
@@ -1945,6 +2063,8 @@
 	const struct hdmirx_output_fmt *out_fmt;
 	unsigned long lock_flags = 0;
 	int i;
+	struct rk_hdmirx_dev *hdmirx_dev;
+	struct v4l2_device *v4l2_dev;
 
 	if (vb == NULL) {
 		pr_err("%s: vb null pointer err!\n", __func__);
@@ -1957,6 +2077,9 @@
 	stream = vb2_get_drv_priv(queue);
 	pixm = &stream->pixm;
 	out_fmt = stream->out_fmt;
+
+	hdmirx_dev = stream->hdmirx_dev;
+	v4l2_dev = &hdmirx_dev->v4l2_dev;
 
 	memset(hdmirx_buf->buff_addr, 0, sizeof(hdmirx_buf->buff_addr));
 	/*
@@ -1979,9 +2102,58 @@
 		}
 	}
 
+	v4l2_dbg(4, debug, v4l2_dev, "qbuf fd:%d\n", vb->planes[0].m.fd);
+
 	spin_lock_irqsave(&stream->vbq_lock, lock_flags);
 	list_add_tail(&hdmirx_buf->queue, &stream->buf_head);
 	spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
+
+	if (low_latency)
+		hdmirx_qbuf_alloc_fence(hdmirx_dev);
+}
+
+static void hdmirx_free_fence(struct rk_hdmirx_dev *hdmirx_dev)
+{
+	unsigned long lock_flags = 0;
+	struct hdmirx_fence *vb_fence, *done_fence;
+	struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
+	LIST_HEAD(local_list);
+
+	spin_lock_irqsave(&hdmirx_dev->fence_lock, lock_flags);
+	if (hdmirx_dev->hdmirx_fence) {
+		v4l2_dbg(2, debug, v4l2_dev, "%s: signal hdmirx_fence fd:%d\n",
+			 __func__, hdmirx_dev->hdmirx_fence->fence_fd);
+		dma_fence_signal(hdmirx_dev->hdmirx_fence->fence);
+		dma_fence_put(hdmirx_dev->hdmirx_fence->fence);
+		kfree(hdmirx_dev->hdmirx_fence);
+		hdmirx_dev->hdmirx_fence = NULL;
+	}
+
+	list_replace_init(&hdmirx_dev->qbuf_fence_list_head, &local_list);
+	spin_unlock_irqrestore(&hdmirx_dev->fence_lock, lock_flags);
+
+	while (!list_empty(&local_list)) {
+		vb_fence = list_first_entry(&local_list, struct hdmirx_fence, fence_list);
+		list_del(&vb_fence->fence_list);
+		v4l2_dbg(2, debug, v4l2_dev, "%s: free qbuf_fence fd:%d\n",
+			 __func__, vb_fence->fence_fd);
+		dma_fence_put(vb_fence->fence);
+		put_unused_fd(vb_fence->fence_fd);
+		kfree(vb_fence);
+	}
+
+	spin_lock_irqsave(&hdmirx_dev->fence_lock, lock_flags);
+	list_replace_init(&hdmirx_dev->done_fence_list_head, &local_list);
+	spin_unlock_irqrestore(&hdmirx_dev->fence_lock, lock_flags);
+	while (!list_empty(&local_list)) {
+		done_fence = list_first_entry(&local_list, struct hdmirx_fence, fence_list);
+		list_del(&done_fence->fence_list);
+		v4l2_dbg(2, debug, v4l2_dev, "%s: free done_fence fd:%d\n",
+			 __func__, done_fence->fence_fd);
+		dma_fence_put(done_fence->fence);
+		put_unused_fd(done_fence->fence_fd);
+		kfree(done_fence);
+	}
 }
 
 static void return_all_buffers(struct hdmirx_stream *stream,
@@ -1989,6 +2161,7 @@
 {
 	struct hdmirx_buffer *buf;
 	unsigned long flags;
+	struct rk_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev;
 
 	spin_lock_irqsave(&stream->vbq_lock, flags);
 	if (stream->curr_buf)
@@ -2007,6 +2180,8 @@
 		spin_lock_irqsave(&stream->vbq_lock, flags);
 	}
 	spin_unlock_irqrestore(&stream->vbq_lock, flags);
+
+	hdmirx_free_fence(hdmirx_dev);
 }
 
 static void hdmirx_stop_streaming(struct vb2_queue *queue)
@@ -2055,6 +2230,7 @@
 	struct v4l2_dv_timings timings = hdmirx_dev->timings;
 	struct v4l2_bt_timings *bt = &timings.bt;
 	int line_flag;
+	int delay_line;
 	uint32_t touch_flag;
 
 	if (!hdmirx_dev->get_timing) {
@@ -2069,7 +2245,7 @@
 	}
 
 	mutex_lock(&hdmirx_dev->stream_lock);
-	touch_flag = (hdmirx_dev->bound_cpu << 1) | 0x1;
+	touch_flag = (hdmirx_dev->phy_cpuid << 1) | 0x1;
 	sip_hdmirx_config(HDMIRX_AUTO_TOUCH_EN, 0, touch_flag, 100);
 	stream->frame_idx = 0;
 	stream->line_flag_int_cnt = 0;
@@ -2106,12 +2282,19 @@
 
 	if (bt->height) {
 		if (bt->interlaced == V4L2_DV_INTERLACED)
-			line_flag = bt->height / 4;
-		else
 			line_flag = bt->height / 2;
+		else
+			line_flag = bt->height;
+
+		if (low_latency && hdmirx_dev->fps >= 59)
+			delay_line = 10;
+		else
+			delay_line = line_flag * 2 / 3;
+
+		v4l2_info(v4l2_dev, "%s: delay_line:%d\n", __func__, delay_line);
 		hdmirx_update_bits(hdmirx_dev, DMA_CONFIG7,
 				LINE_FLAG_NUM_MASK,
-				LINE_FLAG_NUM(line_flag));
+				LINE_FLAG_NUM(delay_line));
 	} else {
 		v4l2_err(v4l2_dev, "height err: %d\n", bt->height);
 	}
@@ -2170,6 +2353,57 @@
 	val = hdmirx_readl(hdmirx_dev, HDCP_INT_STATUS) & 0x40;
 
 	return val ? 1 : 0;
+}
+
+static void hdmirx_dqbuf_get_done_fence(struct rk_hdmirx_dev *hdmirx_dev)
+{
+	unsigned long lock_flags = 0;
+	struct hdmirx_fence *done_fence;
+	struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
+
+	spin_lock_irqsave(&hdmirx_dev->fence_lock, lock_flags);
+	if (!list_empty(&hdmirx_dev->done_fence_list_head)) {
+		done_fence = list_first_entry(&hdmirx_dev->done_fence_list_head,
+				struct hdmirx_fence, fence_list);
+		list_del(&done_fence->fence_list);
+	} else {
+		done_fence = NULL;
+	}
+	spin_unlock_irqrestore(&hdmirx_dev->fence_lock, lock_flags);
+
+	if (done_fence) {
+		spin_lock_irqsave(&hdmirx_dev->fence_lock, lock_flags);
+		if (hdmirx_dev->hdmirx_fence) {
+			v4l2_err(v4l2_dev, "%s: last fence not signal, signal now!\n", __func__);
+			dma_fence_signal(hdmirx_dev->hdmirx_fence->fence);
+			dma_fence_put(hdmirx_dev->hdmirx_fence->fence);
+			v4l2_dbg(2, debug, v4l2_dev, "%s: signal fence:%p, old_fd:%d\n",
+				 __func__,
+				 hdmirx_dev->hdmirx_fence->fence,
+				 hdmirx_dev->hdmirx_fence->fence_fd);
+			kfree(hdmirx_dev->hdmirx_fence);
+			hdmirx_dev->hdmirx_fence = NULL;
+		}
+		hdmirx_dev->hdmirx_fence = done_fence;
+		spin_unlock_irqrestore(&hdmirx_dev->fence_lock, lock_flags);
+		v4l2_dbg(3, debug, v4l2_dev, "%s: fence:%p, fence_fd:%d\n",
+			 __func__, done_fence->fence, done_fence->fence_fd);
+	}
+}
+
+static int hdmirx_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	int ret;
+	struct hdmirx_stream *stream = video_drvdata(file);
+	struct rk_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev;
+
+	if (!hdmirx_dev->get_timing)
+		return -EINVAL;
+
+	ret = vb2_ioctl_dqbuf(file, priv, p);
+	hdmirx_dqbuf_get_done_fence(hdmirx_dev);
+
+	return ret;
 }
 
 static long hdmirx_ioctl_default(struct file *file, void *fh,
@@ -2290,7 +2524,7 @@
 	.vidioc_create_bufs = vb2_ioctl_create_bufs,
 	.vidioc_qbuf = vb2_ioctl_qbuf,
 	.vidioc_expbuf = vb2_ioctl_expbuf,
-	.vidioc_dqbuf = vb2_ioctl_dqbuf,
+	.vidioc_dqbuf = hdmirx_dqbuf,
 	.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
 	.vidioc_streamon = vb2_ioctl_streamon,
 	.vidioc_streamoff = vb2_ioctl_streamoff,
@@ -2353,12 +2587,23 @@
 	return 0;
 }
 
+static void process_audio_change(struct rk_hdmirx_dev *hdmirx_dev)
+{
+	struct hdmirx_stream *stream = &hdmirx_dev->stream;
+	const struct v4l2_event evt_audio_info = {
+		.type = RK_HDMIRX_V4L2_EVENT_AUDIOINFO,
+	};
+	v4l2_event_queue(&stream->vdev, &evt_audio_info);
+}
+
 static void process_signal_change(struct rk_hdmirx_dev *hdmirx_dev)
 {
+	unsigned long lock_flags = 0;
 	struct hdmirx_stream *stream = &hdmirx_dev->stream;
 	const struct v4l2_event evt_signal_lost = {
 		.type = RK_HDMIRX_V4L2_EVENT_SIGNAL_LOST,
 	};
+	struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
 
 	hdmirx_dev->get_timing = false;
 	sip_hdmirx_config(HDMIRX_INFO_NOTIFY, 0, DMA_CONFIG6, 0);
@@ -2376,6 +2621,18 @@
 	v4l2_event_queue(&stream->vdev, &evt_signal_lost);
 	if (hdmirx_dev->hdcp && hdmirx_dev->hdcp->hdcp_stop)
 		hdmirx_dev->hdcp->hdcp_stop(hdmirx_dev->hdcp);
+	spin_lock_irqsave(&hdmirx_dev->fence_lock, lock_flags);
+	if (hdmirx_dev->hdmirx_fence) {
+		dma_fence_signal(hdmirx_dev->hdmirx_fence->fence);
+		dma_fence_put(hdmirx_dev->hdmirx_fence->fence);
+		v4l2_dbg(2, debug, v4l2_dev, "%s: signal fence:%p, old_fd:%d\n",
+			 __func__,
+			 hdmirx_dev->hdmirx_fence->fence,
+			 hdmirx_dev->hdmirx_fence->fence_fd);
+		kfree(hdmirx_dev->hdmirx_fence);
+		hdmirx_dev->hdmirx_fence = NULL;
+	}
+	spin_unlock_irqrestore(&hdmirx_dev->fence_lock, lock_flags);
 	schedule_delayed_work_on(hdmirx_dev->bound_cpu,
 			&hdmirx_dev->delayed_work_res_change,
 			msecs_to_jiffies(1000));
@@ -2608,6 +2865,8 @@
 {
 	const struct hdmirx_output_fmt *fmt = stream->out_fmt;
 	u32 i;
+	struct rk_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev;
+	struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
 
 	/* Dequeue a filled buffer */
 	for (i = 0; i < fmt->mplanes; i++) {
@@ -2617,10 +2876,12 @@
 
 	vb_done->vb2_buf.timestamp = ktime_get_ns();
 	vb2_buffer_done(&vb_done->vb2_buf, VB2_BUF_STATE_DONE);
+	v4l2_dbg(4, debug, v4l2_dev, "vb_done fd:%d", vb_done->vb2_buf.planes[0].m.fd);
 }
 
 static void dma_idle_int_handler(struct rk_hdmirx_dev *hdmirx_dev, bool *handled)
 {
+	unsigned long lock_flags = 0;
 	struct hdmirx_stream *stream = &hdmirx_dev->stream;
 	struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
 	struct v4l2_dv_timings timings = hdmirx_dev->timings;
@@ -2630,6 +2891,22 @@
 	if (!(stream->irq_stat) && !(stream->irq_stat & LINE_FLAG_INT_EN))
 		v4l2_dbg(1, debug, v4l2_dev,
 			 "%s: last time have no line_flag_irq\n", __func__);
+
+	if (low_latency) {
+		spin_lock_irqsave(&hdmirx_dev->fence_lock, lock_flags);
+		if (hdmirx_dev->hdmirx_fence) {
+			dma_fence_signal(hdmirx_dev->hdmirx_fence->fence);
+			dma_fence_put(hdmirx_dev->hdmirx_fence->fence);
+			v4l2_dbg(3, debug, v4l2_dev, "%s: signal fence:%p, old_fd:%d\n",
+				 __func__,
+				 hdmirx_dev->hdmirx_fence->fence,
+				 hdmirx_dev->hdmirx_fence->fence_fd);
+			kfree(hdmirx_dev->hdmirx_fence);
+			hdmirx_dev->hdmirx_fence = NULL;
+		}
+		spin_unlock_irqrestore(&hdmirx_dev->fence_lock, lock_flags);
+		goto DMA_IDLE_OUT;
+	}
 
 	if (stream->line_flag_int_cnt <= FILTER_FRAME_CNT)
 		goto DMA_IDLE_OUT;
@@ -2643,6 +2920,9 @@
 			if (vb_done) {
 				vb_done->vb2_buf.timestamp = ktime_get_ns();
 				vb_done->sequence = stream->frame_idx;
+				/* config userbits 0 or 0xffffffff as invalid fence_fd*/
+				memset(vb_done->timecode.userbits, 0xff,
+				       sizeof(vb_done->timecode.userbits));
 				hdmirx_vb_done(stream, vb_done);
 				stream->frame_idx++;
 				if (stream->frame_idx == 30)
@@ -2664,13 +2944,50 @@
 	*handled = true;
 }
 
+static void hdmirx_add_fence_to_vb_done(struct hdmirx_stream *stream,
+					struct vb2_v4l2_buffer *vb_done)
+{
+	unsigned long lock_flags = 0;
+	struct hdmirx_fence *vb_fence;
+	struct rk_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev;
+	struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
+
+	spin_lock_irqsave(&hdmirx_dev->fence_lock, lock_flags);
+	if (!list_empty(&hdmirx_dev->qbuf_fence_list_head)) {
+		vb_fence = list_first_entry(&hdmirx_dev->qbuf_fence_list_head,
+				struct hdmirx_fence, fence_list);
+		list_del(&vb_fence->fence_list);
+	} else {
+		vb_fence = NULL;
+	}
+
+	if (vb_fence)
+		list_add_tail(&vb_fence->fence_list, &hdmirx_dev->done_fence_list_head);
+	spin_unlock_irqrestore(&hdmirx_dev->fence_lock, lock_flags);
+
+	if (vb_fence) {
+		/*  pass the fence_fd to userspace through timecode.userbits */
+		if (put_user(vb_fence->fence_fd, vb_done->timecode.userbits))
+			v4l2_err(v4l2_dev, "%s: failed to trans fence fd!\n", __func__);
+
+		v4l2_dbg(3, debug, v4l2_dev, "%s: fence:%p, fence_fd:%d\n",
+			 __func__, vb_fence->fence, vb_fence->fence_fd);
+	} else {
+		/* config userbits 0 or 0xffffffff as invalid fence_fd*/
+		memset(vb_done->timecode.userbits, 0xff, sizeof(vb_done->timecode.userbits));
+		v4l2_err(v4l2_dev, "%s: failed to get fence fd!\n", __func__);
+	}
+}
+
 static void line_flag_int_handler(struct rk_hdmirx_dev *hdmirx_dev, bool *handled)
 {
+	unsigned long lock_flags = 0;
 	struct hdmirx_stream *stream = &hdmirx_dev->stream;
 	struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
 	struct v4l2_dv_timings timings = hdmirx_dev->timings;
 	struct v4l2_bt_timings *bt = &timings.bt;
 	u32 dma_cfg6;
+	struct vb2_v4l2_buffer *vb_done = NULL;
 
 	stream->line_flag_int_cnt++;
 	if (!(stream->irq_stat) && !(stream->irq_stat & HDMIRX_DMA_IDLE_INT))
@@ -2687,6 +3004,19 @@
 
 	if ((bt->interlaced != V4L2_DV_INTERLACED) ||
 			(stream->line_flag_int_cnt % 2 == 0)) {
+		spin_lock_irqsave(&hdmirx_dev->fence_lock, lock_flags);
+		if (hdmirx_dev->hdmirx_fence) {
+			dma_fence_signal(hdmirx_dev->hdmirx_fence->fence);
+			dma_fence_put(hdmirx_dev->hdmirx_fence->fence);
+			v4l2_dbg(2, debug, v4l2_dev, "%s: signal last fence:%p, old_fd:%d\n",
+				 __func__,
+				 hdmirx_dev->hdmirx_fence->fence,
+				 hdmirx_dev->hdmirx_fence->fence_fd);
+			kfree(hdmirx_dev->hdmirx_fence);
+			hdmirx_dev->hdmirx_fence = NULL;
+		}
+		spin_unlock_irqrestore(&hdmirx_dev->fence_lock, lock_flags);
+
 		if (!stream->next_buf) {
 			spin_lock(&stream->vbq_lock);
 			if (!list_empty(&stream->buf_head)) {
@@ -2698,15 +3028,44 @@
 			}
 			spin_unlock(&stream->vbq_lock);
 
-			if (stream->next_buf) {
-				hdmirx_writel(hdmirx_dev, DMA_CONFIG2,
-					stream->next_buf->buff_addr[HDMIRX_PLANE_Y]);
-				hdmirx_writel(hdmirx_dev, DMA_CONFIG3,
-					stream->next_buf->buff_addr[HDMIRX_PLANE_CBCR]);
-			} else {
-				v4l2_dbg(3, debug, v4l2_dev,
-					 "%s: No buffer is available\n", __func__);
+		}
+
+		if (stream->next_buf) {
+			hdmirx_writel(hdmirx_dev, DMA_CONFIG2,
+				stream->next_buf->buff_addr[HDMIRX_PLANE_Y]);
+			hdmirx_writel(hdmirx_dev, DMA_CONFIG3,
+				stream->next_buf->buff_addr[HDMIRX_PLANE_CBCR]);
+
+			if (low_latency) {
+				if (stream->curr_buf)
+					vb_done = &stream->curr_buf->vb;
+
+				if (vb_done) {
+					hdmirx_add_fence_to_vb_done(stream, vb_done);
+					vb_done->vb2_buf.timestamp = ktime_get_ns();
+					vb_done->sequence = stream->frame_idx;
+					hdmirx_vb_done(stream, vb_done);
+					stream->frame_idx++;
+					if (stream->frame_idx == 30)
+						v4l2_info(v4l2_dev, "rcv frames\n");
+				}
+
+				stream->curr_buf = stream->next_buf;
+				stream->next_buf = NULL;
 			}
+		} else {
+			v4l2_dbg(3, debug, v4l2_dev,
+				 "%s: next_buf NULL, drop the frame!\n", __func__);
+		}
+
+		if (stream->curr_buf) {
+			v4l2_dbg(4, debug, v4l2_dev, "%s: curr_fd:%d\n",
+				 __func__, stream->curr_buf->vb.vb2_buf.planes[0].m.fd);
+		}
+
+		if (stream->next_buf) {
+			v4l2_dbg(4, debug, v4l2_dev, "%s: next_fd:%d\n",
+				 __func__, stream->next_buf->vb.vb2_buf.planes[0].m.fd);
 		}
 	} else {
 		v4l2_dbg(3, debug, v4l2_dev, "%s: interlace:%d, line_flag_int_cnt:%d\n",
@@ -3248,6 +3607,7 @@
 		if (!hdmirx_dev->audio_present) {
 			dev_info(hdmirx_dev->dev, "audio on");
 			hdmirx_audio_handle_plugged_change(hdmirx_dev, 1);
+			process_audio_change(hdmirx_dev);
 			hdmirx_dev->audio_present = true;
 		}
 		if (cur_state - init_state > 16 && cur_state - pre_state > 0)
@@ -3258,6 +3618,7 @@
 		if (hdmirx_dev->audio_present) {
 			dev_info(hdmirx_dev->dev, "audio off");
 			hdmirx_audio_handle_plugged_change(hdmirx_dev, 0);
+			process_audio_change(hdmirx_dev);
 			hdmirx_dev->audio_present = false;
 		}
 	}
@@ -4175,6 +4536,50 @@
 		dev_err(hdmirx_dev->dev, "%s freq qos nod add\n", __func__);
 }
 
+static int hdmirx_get_custom_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct rk_hdmirx_dev *hdmirx_dev = container_of(ctrl->handler, struct rk_hdmirx_dev, hdl);
+	int ret = 0;
+
+	if (ctrl->id == RK_V4L2_CID_AUDIO_SAMPLING_RATE) {
+		*ctrl->p_new.p_s32 = hdmirx_dev->audio_state.fs_audio;
+	} else if (ctrl->id == RK_V4L2_CID_AUDIO_PRESENT) {
+		*ctrl->p_new.p_s32 = tx_5v_power_present(hdmirx_dev) ?
+					hdmirx_dev->audio_present : 0;
+	} else {
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops hdmirx_custom_ctrl_ops = {
+	.g_volatile_ctrl = hdmirx_get_custom_ctrl,
+};
+
+static const struct v4l2_ctrl_config hdmirx_ctrl_audio_sampling_rate = {
+	.ops = &hdmirx_custom_ctrl_ops,
+	.id = RK_V4L2_CID_AUDIO_SAMPLING_RATE,
+	.name = "Audio sampling rate",
+	.type = V4L2_CTRL_TYPE_INTEGER,
+	.min = 0,
+	.max = 768000,
+	.step = 1,
+	.def = 0,
+	.flags = V4L2_CTRL_FLAG_READ_ONLY,
+};
+
+static const struct v4l2_ctrl_config hdmirx_ctrl_audio_present = {
+	.ops = &hdmirx_custom_ctrl_ops,
+	.id = RK_V4L2_CID_AUDIO_PRESENT,
+	.name = "Audio present",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.min = 0,
+	.max = 1,
+	.step = 1,
+	.def = 0,
+	.flags = V4L2_CTRL_FLAG_READ_ONLY,
+};
+
 static int hdmirx_probe(struct platform_device *pdev)
 {
 	const struct v4l2_dv_timings timings_def = HDMIRX_DEFAULT_TIMING;
@@ -4208,23 +4613,35 @@
 		return PTR_ERR(hdmirx_dev->regs);
 	}
 
-	if (sip_cpu_logical_map_mpidr(0) == 0)
-		cpu_aff = sip_cpu_logical_map_mpidr(4); // big cpu0
-	else
-		cpu_aff = sip_cpu_logical_map_mpidr(1); // big cpu1
+	/*
+	 * Bind HDMIRX's FIQ and driver interrupt processing to big cpu1
+	 * in order to quickly respond to FIQ and prevent them from affecting
+	 * each other.
+	 */
+	if (sip_cpu_logical_map_mpidr(0) == 0) {
+		cpu_aff = sip_cpu_logical_map_mpidr(5);
+		hdmirx_dev->bound_cpu = 5;
+	} else {
+		cpu_aff = sip_cpu_logical_map_mpidr(1);
+		hdmirx_dev->bound_cpu = 1;
+	}
 
 	sip_fiq_control(RK_SIP_FIQ_CTRL_SET_AFF, RK_IRQ_HDMIRX_HDMI, cpu_aff);
-	hdmirx_dev->bound_cpu = (cpu_aff >> 8) & 0xf;
+	hdmirx_dev->phy_cpuid = (cpu_aff >> 8) & 0xf;
 	hdmirx_dev->wdt_cfg_bound_cpu = hdmirx_dev->bound_cpu + 1;
-	dev_info(dev, "%s: cpu_aff:%#x, Bound_cpu:%d, wdt_cfg_bound_cpu:%d\n",
+	dev_info(dev, "%s: cpu_aff:%#x, Bound_cpu:%d, wdt_cfg_bound_cpu:%d, phy_cpuid:%d\n",
 			__func__, cpu_aff,
 			hdmirx_dev->bound_cpu,
-			hdmirx_dev->wdt_cfg_bound_cpu);
+			hdmirx_dev->wdt_cfg_bound_cpu,
+			hdmirx_dev->phy_cpuid);
 	cpu_latency_qos_add_request(&hdmirx_dev->pm_qos, PM_QOS_DEFAULT_VALUE);
 
 	mutex_init(&hdmirx_dev->stream_lock);
 	mutex_init(&hdmirx_dev->work_lock);
 	spin_lock_init(&hdmirx_dev->rst_lock);
+	spin_lock_init(&hdmirx_dev->fence_lock);
+	INIT_LIST_HEAD(&hdmirx_dev->qbuf_fence_list_head);
+	INIT_LIST_HEAD(&hdmirx_dev->done_fence_list_head);
 	INIT_WORK(&hdmirx_dev->work_wdt_config,
 			hdmirx_work_wdt_config);
 	INIT_DELAYED_WORK(&hdmirx_dev->delayed_work_hotplug,
@@ -4288,10 +4705,19 @@
 	strscpy(v4l2_dev->name, dev_name(dev), sizeof(v4l2_dev->name));
 
 	hdl = &hdmirx_dev->hdl;
-	v4l2_ctrl_handler_init(hdl, 1);
+	v4l2_ctrl_handler_init(hdl, 3);
 	hdmirx_dev->detect_tx_5v_ctrl = v4l2_ctrl_new_std(hdl,
 			NULL, V4L2_CID_DV_RX_POWER_PRESENT,
 			0, 1, 0, 0);
+	/* custom controls */
+	hdmirx_dev->audio_sampling_rate_ctrl = v4l2_ctrl_new_custom(hdl,
+			&hdmirx_ctrl_audio_sampling_rate, NULL);
+	if (hdmirx_dev->audio_sampling_rate_ctrl)
+		hdmirx_dev->audio_sampling_rate_ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	hdmirx_dev->audio_present_ctrl = v4l2_ctrl_new_custom(hdl,
+			&hdmirx_ctrl_audio_present, NULL);
+	if (hdmirx_dev->audio_present_ctrl)
+		hdmirx_dev->audio_present_ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
 	if (hdl->error) {
 		dev_err(dev, "v4l2 ctrl handler init failed!\n");
 		ret = hdl->error;
@@ -4399,7 +4825,8 @@
 	hdmirx_register_hdcp(dev, hdmirx_dev, hdmirx_dev->hdcp_enable);
 
 	hdmirx_register_debugfs(hdmirx_dev->dev, hdmirx_dev);
-
+	hdmirx_fence_context_init(&hdmirx_dev->fence_ctx);
+	hdmirx_dev->hdmirx_fence = NULL;
 	hdmirx_dev->initialized = true;
 	dev_info(dev, "%s driver probe ok!\n", dev_name(dev));
 
@@ -4430,7 +4857,6 @@
 	struct rk_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev);
 
 	debugfs_remove_recursive(hdmirx_dev->debugfs_dir);
-
 	cpu_latency_qos_remove_request(&hdmirx_dev->pm_qos);
 	cancel_delayed_work(&hdmirx_dev->delayed_work_hotplug);
 	cancel_delayed_work(&hdmirx_dev->delayed_work_res_change);
diff --git a/kernel/drivers/media/platform/rockchip/isp/bridge_v20.c b/kernel/drivers/media/platform/rockchip/isp/bridge_v20.c
index c637b00..75184a3 100644
--- a/kernel/drivers/media/platform/rockchip/isp/bridge_v20.c
+++ b/kernel/drivers/media/platform/rockchip/isp/bridge_v20.c
@@ -669,7 +669,7 @@
 	struct rkisp_hw_dev *hw = ispdev->hw_dev;
 	struct v4l2_subdev *sd = v4l2_get_subdev_hostdata(&dev->sd);
 	unsigned long lock_flags = 0;
-	u64 ns = ktime_get_ns();
+	u64 ns = rkisp_time_get_ns(ispdev);
 	struct rkisp_bridge_buf *buf;
 	u32 val;
 
@@ -711,7 +711,7 @@
 			if (!sof_ns)
 				sof_ns = 0;
 			if (!ns)
-				ns = ktime_get_ns();
+				ns = rkisp_time_get_ns(ispdev);
 			hw->cur_buf->frame_timestamp = ns;
 			hw->cur_buf->index = ispdev->dev_id;
 			v4l2_subdev_call(sd, core, ioctl, RKISP_ISPP_CMD_REQUEST_REGBUF,
@@ -744,11 +744,11 @@
 				buf = to_bridge_buf(hw->cur_buf);
 				vaddr = buf->dummy[GROUP_BUF_PIC].vaddr;
 				size = buf->dummy[GROUP_BUF_PIC].size;
-				*(u64 *)(vaddr + size / 4 - 2) = ktime_get_ns();
+				*(u64 *)(vaddr + size / 4 - 2) = rkisp_time_get_ns(ispdev);
 
 				vaddr = buf->dummy[GROUP_BUF_GAIN].vaddr;
 				size = buf->dummy[GROUP_BUF_GAIN].size;
-				*(u64 *)(vaddr + size / 4 - 2) = ktime_get_ns();
+				*(u64 *)(vaddr + size / 4 - 2) = rkisp_time_get_ns(ispdev);
 				hw->cur_buf->mfbc_dmaidx = hw->cur_buf->didx[GROUP_BUF_PIC];
 				hw->cur_buf->gain_dmaidx = hw->cur_buf->didx[GROUP_BUF_GAIN];
 				hw->cur_buf->is_move_judge = true;
diff --git a/kernel/drivers/media/platform/rockchip/isp/bridge_v30.c b/kernel/drivers/media/platform/rockchip/isp/bridge_v30.c
index c0b639b..976aca8 100644
--- a/kernel/drivers/media/platform/rockchip/isp/bridge_v30.c
+++ b/kernel/drivers/media/platform/rockchip/isp/bridge_v30.c
@@ -114,7 +114,7 @@
 	struct rkisp_hw_dev *hw = ispdev->hw_dev;
 	struct v4l2_subdev *sd = v4l2_get_subdev_hostdata(&dev->sd);
 	unsigned long lock_flags = 0;
-	u64 ns = ktime_get_ns();
+	u64 ns = rkisp_time_get_ns(ispdev);
 
 	if (dev->stopping) {
 		if (!hw->is_single) {
@@ -148,7 +148,7 @@
 			rkisp_dmarx_get_frame(ispdev, &hw->cur_buf->frame_id,
 					      NULL, &ns, true);
 			if (!ns)
-				ns = ktime_get_ns();
+				ns = rkisp_time_get_ns(ispdev);
 			hw->cur_buf->frame_timestamp = ns;
 			hw->cur_buf->index = ispdev->dev_id;
 			v4l2_subdev_call(sd, video, s_rx_buffer, hw->cur_buf, NULL);
diff --git a/kernel/drivers/media/platform/rockchip/isp/capture_v20.c b/kernel/drivers/media/platform/rockchip/isp/capture_v20.c
index 2092981..a349bdd 100644
--- a/kernel/drivers/media/platform/rockchip/isp/capture_v20.c
+++ b/kernel/drivers/media/platform/rockchip/isp/capture_v20.c
@@ -1392,10 +1392,10 @@
 			stream->curr_buf->vb.sequence =
 				atomic_read(&stream->sequence) - 1;
 		if (!ns)
-			ns = ktime_get_ns();
+			ns = rkisp_time_get_ns(dev);
 		vb2_buf->timestamp = ns;
 
-		ns = ktime_get_ns();
+		ns = rkisp_time_get_ns(dev);
 		stream->dbg.interval = ns - stream->dbg.timestamp;
 		stream->dbg.timestamp = ns;
 		stream->dbg.id = stream->curr_buf->vb.sequence;
@@ -1439,7 +1439,7 @@
 				u32 sizeimage = vb2_plane_size(&stream->curr_buf->vb.vb2_buf, 0);
 				u32 *buf = (u32 *)vb2_plane_vaddr(&stream->curr_buf->vb.vb2_buf, 0);
 
-				*(u64 *)(buf + sizeimage / 4 - 2) = ktime_get_ns();
+				*(u64 *)(buf + sizeimage / 4 - 2) = rkisp_time_get_ns(dev);
 				stream->curr_buf->dev_id = dev->dev_id;
 				rkisp_bridge_save_spbuf(dev, stream->curr_buf);
 			} else {
diff --git a/kernel/drivers/media/platform/rockchip/isp/capture_v21.c b/kernel/drivers/media/platform/rockchip/isp/capture_v21.c
index 67cb9f6..7aeef97 100644
--- a/kernel/drivers/media/platform/rockchip/isp/capture_v21.c
+++ b/kernel/drivers/media/platform/rockchip/isp/capture_v21.c
@@ -1150,7 +1150,8 @@
 			if (!ret) {
 				denominator = sensor->fi.interval.denominator;
 				numerator = sensor->fi.interval.numerator;
-				time = numerator * 1000 / denominator * 1000 * 1000;
+				if (denominator)
+					time = numerator * 1000 / denominator * 1000 * 1000;
 				if (numerator)
 					fps = denominator / numerator;
 			}
@@ -1225,6 +1226,15 @@
 		struct vb2_buffer *vb2_buf = &stream->curr_buf->vb.vb2_buf;
 		u64 ns = 0;
 
+		if (stream->skip_frame) {
+			spin_lock_irqsave(&stream->vbq_lock, lock_flags);
+			list_add_tail(&stream->curr_buf->queue, &stream->buf_queue);
+			spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
+			if (stream->skip_frame)
+				stream->skip_frame--;
+			goto end;
+		}
+
 		/* Dequeue a filled buffer */
 		for (i = 0; i < isp_fmt->mplanes; i++) {
 			u32 payload_size =
@@ -1241,10 +1251,10 @@
 				atomic_read(&stream->sequence) - 1;
 		}
 		if (!ns)
-			ns = ktime_get_ns();
+			ns = rkisp_time_get_ns(dev);
 		vb2_buf->timestamp = ns;
 
-		ns = ktime_get_ns();
+		ns = rkisp_time_get_ns(dev);
 		stream->dbg.interval = ns - stream->dbg.timestamp;
 		stream->dbg.timestamp = ns;
 		stream->dbg.id = stream->curr_buf->vb.sequence;
@@ -1287,6 +1297,7 @@
 		stream->curr_buf = NULL;
 	}
 
+end:
 	if (!interlaced ||
 		(stream->curr_buf == stream->next_buf &&
 		stream->u.sp.field == RKISP_FIELD_ODD)) {
@@ -1505,7 +1516,7 @@
 	if (stream->id == RKISP_STREAM_MP || stream->id == RKISP_STREAM_SP)
 		hdr_config_dmatx(dev);
 	stream->streaming = true;
-
+	stream->skip_frame = 0;
 	return 0;
 }
 
diff --git a/kernel/drivers/media/platform/rockchip/isp/capture_v30.c b/kernel/drivers/media/platform/rockchip/isp/capture_v30.c
index 5f6616c..78b06ec 100644
--- a/kernel/drivers/media/platform/rockchip/isp/capture_v30.c
+++ b/kernel/drivers/media/platform/rockchip/isp/capture_v30.c
@@ -977,6 +977,15 @@
 		struct vb2_buffer *vb2_buf = &buf->vb.vb2_buf;
 		u64 ns = 0;
 
+		if (stream->skip_frame) {
+			spin_lock_irqsave(&stream->vbq_lock, lock_flags);
+			list_add_tail(&buf->queue, &stream->buf_queue);
+			spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
+			if (stream->skip_frame)
+				stream->skip_frame--;
+			goto end;
+		}
+
 		/* Dequeue a filled buffer */
 		for (i = 0; i < isp_fmt->mplanes; i++) {
 			u32 payload_size = stream->out_fmt.plane_fmt[i].sizeimage;
@@ -987,10 +996,10 @@
 		rkisp_dmarx_get_frame(dev, &i, NULL, &ns, true);
 		buf->vb.sequence = i;
 		if (!ns)
-			ns = ktime_get_ns();
+			ns = rkisp_time_get_ns(dev);
 		vb2_buf->timestamp = ns;
 
-		ns = ktime_get_ns();
+		ns = rkisp_time_get_ns(dev);
 		stream->dbg.interval = ns - stream->dbg.timestamp;
 		stream->dbg.timestamp = ns;
 		stream->dbg.id = buf->vb.sequence;
@@ -1097,7 +1106,7 @@
 
 	stream->ops->enable_mi(stream);
 	stream->streaming = true;
-
+	stream->skip_frame = 0;
 	return 0;
 }
 
diff --git a/kernel/drivers/media/platform/rockchip/isp/capture_v32.c b/kernel/drivers/media/platform/rockchip/isp/capture_v32.c
index c71a701..a5f2505 100644
--- a/kernel/drivers/media/platform/rockchip/isp/capture_v32.c
+++ b/kernel/drivers/media/platform/rockchip/isp/capture_v32.c
@@ -1240,7 +1240,7 @@
 		data++;
 	}
 	if (!ns)
-		ns = ktime_get_ns();
+		ns = rkisp_time_get_ns(dev);
 	stream->curr_buf->vb.vb2_buf.timestamp = ns;
 	stream->curr_buf->vb.sequence = seq;
 	vb2_set_plane_payload(&stream->curr_buf->vb.vb2_buf, 0, val * 4);
@@ -1455,10 +1455,10 @@
 
 		rkisp_dmarx_get_frame(dev, &i, NULL, &ns, true);
 		if (!ns)
-			ns = ktime_get_ns();
+			ns = rkisp_time_get_ns(dev);
 		buf->vb.sequence = i;
 		buf->vb.vb2_buf.timestamp = ns;
-		ns = ktime_get_ns();
+		ns = rkisp_time_get_ns(dev);
 		stream->dbg.interval = ns - stream->dbg.timestamp;
 		stream->dbg.delay = ns - dev->isp_sdev.frm_timestamp;
 		stream->dbg.timestamp = ns;
@@ -2325,7 +2325,7 @@
 				wake_up(&stream->done);
 			}
 		} else if (stream->id == RKISP_STREAM_MP && dev->cap_dev.wrap_line) {
-			ns = ktime_get_ns();
+			ns = rkisp_time_get_ns(dev);
 			rkisp_dmarx_get_frame(dev, &seq, NULL, NULL, true);
 			stream->dbg.interval = ns - stream->dbg.timestamp;
 			stream->dbg.delay = ns - dev->isp_sdev.frm_timestamp;
diff --git a/kernel/drivers/media/platform/rockchip/isp/common.c b/kernel/drivers/media/platform/rockchip/isp/common.c
index e7421ab..80536de 100644
--- a/kernel/drivers/media/platform/rockchip/isp/common.c
+++ b/kernel/drivers/media/platform/rockchip/isp/common.c
@@ -169,8 +169,10 @@
 				continue;
 		}
 
-		if (hw->unite == ISP_UNITE_ONE && dev->unite_index == ISP_UNITE_RIGHT)
+		if (hw->unite == ISP_UNITE_ONE && dev->unite_index == ISP_UNITE_RIGHT) {
 			val = dev->sw_base_addr + i + RKISP_ISP_SW_MAX_SIZE;
+			flag = dev->sw_base_addr + i + RKISP_ISP_SW_MAX_SIZE + RKISP_ISP_SW_REG_SIZE;
+		}
 
 		if (*flag == SW_REG_CACHE) {
 			if ((i == ISP3X_MAIN_RESIZE_CTRL ||
@@ -316,6 +318,11 @@
 		return -EINVAL;
 	}
 
+	if (hw->dev_num >= DEV_MAX) {
+		dev_err(isp->dev, "failed attach isp hw, max dev:%d\n", DEV_MAX);
+		return -EINVAL;
+	}
+
 	isp->dev_id = hw->dev_num;
 	hw->isp[hw->dev_num] = isp;
 	hw->dev_num++;
@@ -449,3 +456,14 @@
 	else
 		rkisp_free_buffer(dev, &hw->dummy_buf);
 }
+
+u64 rkisp_time_get_ns(struct rkisp_device *dev)
+{
+	u64 ns;
+
+	if (dev->isp_ver == ISP_V32)
+		ns = ktime_get_boottime_ns();
+	else
+		ns = ktime_get_ns();
+	return ns;
+}
diff --git a/kernel/drivers/media/platform/rockchip/isp/common.h b/kernel/drivers/media/platform/rockchip/isp/common.h
index 66c7ad8..ebd4095 100644
--- a/kernel/drivers/media/platform/rockchip/isp/common.h
+++ b/kernel/drivers/media/platform/rockchip/isp/common.h
@@ -196,4 +196,5 @@
 void rkisp_free_common_dummy_buf(struct rkisp_device *dev);
 
 void rkisp_set_clk_rate(struct clk *clk, unsigned long rate);
+u64 rkisp_time_get_ns(struct rkisp_device *dev);
 #endif /* _RKISP_COMMON_H */
diff --git a/kernel/drivers/media/platform/rockchip/isp/csi.c b/kernel/drivers/media/platform/rockchip/isp/csi.c
index a747d67..efa3714 100644
--- a/kernel/drivers/media/platform/rockchip/isp/csi.c
+++ b/kernel/drivers/media/platform/rockchip/isp/csi.c
@@ -15,7 +15,7 @@
 #include "isp_external.h"
 #include "regs.h"
 
-static void get_remote_mipi_sensor(struct rkisp_device *dev,
+void rkisp_get_remote_mipi_sensor(struct rkisp_device *dev,
 				  struct v4l2_subdev **sensor_sd, u32 function)
 {
 	struct media_graph graph;
@@ -82,6 +82,8 @@
 		id = local->index - 1;
 		if (id && id < RKISP_STREAM_DMATX3)
 			stream = &csi->ispdev->cap_dev.stream[id + 1];
+		if (id >= ARRAY_SIZE(csi->sink))
+			return -EINVAL;
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (csi->sink[id].linked) {
 				ret = -EBUSY;
@@ -210,7 +212,7 @@
 	emd_vc = 0xFF;
 	emd_dt = 0;
 	dev->hdr.sensor = NULL;
-	get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_CAM_SENSOR);
+	rkisp_get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_CAM_SENSOR);
 	if (mipi_sensor) {
 		ctrl = v4l2_ctrl_find(mipi_sensor->ctrl_handler,
 				      CIFISP_CID_EMB_VC);
@@ -546,7 +548,7 @@
 		}
 		return 0;
 	}
-	get_remote_mipi_sensor(dev, &sd, type);
+	rkisp_get_remote_mipi_sensor(dev, &sd, type);
 	if (!sd) {
 		v4l2_err(&dev->v4l2_dev, "%s don't find subdev\n", __func__);
 		return -EINVAL;
@@ -577,7 +579,7 @@
 			memset(&mode, 0, sizeof(mode));
 			mode.name = dev->name;
 
-			get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_PROC_VIDEO_COMPOSER);
+			rkisp_get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_PROC_VIDEO_COMPOSER);
 			if (!mipi_sensor)
 				return -EINVAL;
 			dev->hdr.op_mode = HDR_NORMAL;
diff --git a/kernel/drivers/media/platform/rockchip/isp/csi.h b/kernel/drivers/media/platform/rockchip/isp/csi.h
index 98bf251..9fbdc35 100644
--- a/kernel/drivers/media/platform/rockchip/isp/csi.h
+++ b/kernel/drivers/media/platform/rockchip/isp/csi.h
@@ -80,4 +80,6 @@
 int rkisp_csi_get_hdr_cfg(struct rkisp_device *dev, void *arg);
 int rkisp_csi_config_patch(struct rkisp_device *dev);
 void rkisp_csi_sof(struct rkisp_device *dev, u8 id);
+void rkisp_get_remote_mipi_sensor(struct rkisp_device *dev,
+				  struct v4l2_subdev **sensor_sd, u32 function);
 #endif
diff --git a/kernel/drivers/media/platform/rockchip/isp/dev.c b/kernel/drivers/media/platform/rockchip/isp/dev.c
index 7da2c73..ebf4a8c 100644
--- a/kernel/drivers/media/platform/rockchip/isp/dev.c
+++ b/kernel/drivers/media/platform/rockchip/isp/dev.c
@@ -45,13 +45,13 @@
 #include <linux/pm_runtime.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/regmap.h>
-#include <dt-bindings/soc/rockchip-system-status.h>
 #include <soc/rockchip/rockchip-system-status.h>
 #include "common.h"
 #include "isp_ispp.h"
 #include "regs.h"
 #include "rkisp.h"
 #include "version.h"
+#include "csi.h"
 
 #define RKISP_VERNO_LEN		10
 
@@ -224,12 +224,14 @@
 
 	if (i == p->num_subdevs) {
 		v4l2_warn(&dev->v4l2_dev, "No active sensor\n");
+		hw_dev->isp_size[dev->dev_id].is_on = false;
 		return -EPIPE;
 	}
 
 	ctrl = v4l2_ctrl_find(sd->ctrl_handler, V4L2_CID_PIXEL_RATE);
 	if (!ctrl) {
 		v4l2_warn(&dev->v4l2_dev, "No pixel rate control in subdev\n");
+		hw_dev->isp_size[dev->dev_id].is_on = false;
 		return -EPIPE;
 	}
 
@@ -280,16 +282,22 @@
 	if (prepare) {
 		ret = __isp_pipeline_prepare(p, me);
 		if (ret < 0)
-			return ret;
+			goto err;
 	}
 
 	ret = __isp_pipeline_s_isp_clk(p);
 	if (ret < 0)
-		return ret;
+		goto err;
+
+	if (!dev->hw_dev->monitor.is_en)
+		dev->hw_dev->monitor.is_en = rkisp_monitor;
 
 	if (dev->isp_inp & (INP_CSI | INP_RAWRD0 | INP_RAWRD1 | INP_RAWRD2 | INP_CIF))
 		rkisp_csi_config_patch(dev);
 	return 0;
+err:
+	atomic_dec(&p->power_cnt);
+	return ret;
 }
 
 static int rkisp_pipeline_close(struct rkisp_pipeline *p)
@@ -313,7 +321,7 @@
 static int rkisp_pipeline_set_stream(struct rkisp_pipeline *p, bool on)
 {
 	struct rkisp_device *dev = container_of(p, struct rkisp_device, pipe);
-	int i, ret;
+	int i, ret, open_num = 0;
 
 	if ((on && atomic_inc_return(&p->stream_cnt) > 1) ||
 	    (!on && atomic_dec_return(&p->stream_cnt) > 0))
@@ -336,7 +344,11 @@
 				goto err_stream_off;
 		}
 	} else {
-		if (dev->hw_dev->monitor.is_en) {
+		for (i = 0; i < dev->hw_dev->dev_num; i++) {
+			if (dev->hw_dev->isp_size[i].is_on)
+				open_num++;
+		}
+		if (dev->hw_dev->monitor.is_en && open_num == 1) {
 			dev->hw_dev->monitor.is_en = 0;
 			dev->hw_dev->monitor.state = ISP_STOP;
 			if (!completion_done(&dev->hw_dev->monitor.cmpl))
@@ -815,6 +827,15 @@
 					      DMA_BIDIRECTIONAL);
 	ret = dma_mapping_error(dev, isp_dev->resmem_addr);
 	isp_dev->is_thunderboot = true;
+	isp_dev->is_rtt_suspend = false;
+	isp_dev->is_rtt_first = true;
+	if (device_property_read_bool(dev, "rtt-suspend")) {
+		isp_dev->is_rtt_suspend = true;
+		if (!isp_dev->hw_dev->is_thunderboot) {
+			isp_dev->is_thunderboot = false;
+			isp_dev->is_rtt_first = false;
+		}
+	}
 	dev_info(dev, "Allocated reserved memory, paddr: 0x%x\n", (u32)isp_dev->resmem_pa);
 	return ret;
 }
@@ -1006,9 +1027,168 @@
 late_initcall_sync(rkisp_clr_unready_dev);
 #endif
 
+static int rkisp_pm_prepare(struct device *dev)
+{
+	struct rkisp_device *isp_dev = dev_get_drvdata(dev);
+	struct rkisp_hw_dev *hw = isp_dev->hw_dev;
+	struct rkisp_pipeline *p = &isp_dev->pipe;
+	unsigned long lock_flags = 0;
+	int i, on = 0, time = 100;
+
+	if (isp_dev->isp_state & ISP_STOP) {
+		if (pm_runtime_active(dev) &&
+		    rkisp_link_sensor(isp_dev->isp_inp)) {
+			struct v4l2_subdev *mipi_sensor = NULL;
+
+			rkisp_get_remote_mipi_sensor(isp_dev, &mipi_sensor, MEDIA_ENT_F_CAM_SENSOR);
+			if (mipi_sensor)
+				v4l2_subdev_call(mipi_sensor, core, s_power, 0);
+		}
+		return 0;
+	}
+
+	isp_dev->suspend_sync = false;
+	isp_dev->is_suspend = true;
+	if (rkisp_link_sensor(isp_dev->isp_inp)) {
+		for (i = p->num_subdevs - 1; i >= 0; i--)
+			v4l2_subdev_call(p->subdevs[i], video, s_stream, on);
+	} else if (isp_dev->isp_inp & INP_CIF && !(IS_HDR_RDBK(isp_dev->rd_mode))) {
+		v4l2_subdev_call(p->subdevs[0], core, ioctl, RKISP_VICAP_CMD_QUICK_STREAM, &on);
+	}
+	if (IS_HDR_RDBK(isp_dev->rd_mode)) {
+		spin_lock_irqsave(&hw->rdbk_lock, lock_flags);
+		if (!hw->is_idle && hw->cur_dev_id == isp_dev->dev_id)
+			isp_dev->suspend_sync = true;
+		spin_unlock_irqrestore(&hw->rdbk_lock, lock_flags);
+	}
+
+	if (isp_dev->suspend_sync) {
+		wait_for_completion_timeout(&isp_dev->pm_cmpl, msecs_to_jiffies(time));
+		isp_dev->suspend_sync = false;
+	}
+
+	if (rkisp_link_sensor(isp_dev->isp_inp)) {
+		for (i = p->num_subdevs - 1; i >= 0; i--)
+			v4l2_subdev_call(p->subdevs[i], core, s_power, 0);
+	}
+	return 0;
+}
+
+static void rkisp_pm_complete(struct device *dev)
+{
+	struct rkisp_device *isp_dev = dev_get_drvdata(dev);
+	struct rkisp_hw_dev *hw = isp_dev->hw_dev;
+	struct rkisp_pipeline *p = &isp_dev->pipe;
+	struct rkisp_stream *stream;
+	int i, on = 1, rd_mode = isp_dev->rd_mode;
+	u32 val;
+
+	if (isp_dev->isp_state & ISP_STOP) {
+		if (pm_runtime_active(dev) &&
+		    rkisp_link_sensor(isp_dev->isp_inp)) {
+			struct v4l2_subdev *mipi_sensor = NULL;
+
+			rkisp_get_remote_mipi_sensor(isp_dev, &mipi_sensor, MEDIA_ENT_F_CAM_SENSOR);
+			if (mipi_sensor)
+				v4l2_subdev_call(mipi_sensor, core, s_power, 1);
+		}
+		return;
+	}
+
+	if (isp_dev->is_rtt_suspend) {
+		rkisp_save_tb_info(isp_dev);
+		v4l2_info(&isp_dev->v4l2_dev,
+			  "tb info en:%d comp:%d cnt:%d w:%d h:%d cam:%d idx:%d mode:%d\n",
+			  isp_dev->tb_head.enable, isp_dev->tb_head.complete,
+			  isp_dev->tb_head.frm_total, isp_dev->tb_head.width,
+			  isp_dev->tb_head.height, isp_dev->tb_head.camera_num,
+			  isp_dev->tb_head.camera_index, isp_dev->tb_head.rtt_mode);
+		isp_dev->is_first_double = false;
+		switch (isp_dev->tb_head.rtt_mode) {
+		case RKISP_RTT_MODE_ONE_FRAME:
+			isp_dev->is_first_double = true;
+			/* switch to readback mode */
+			switch (rd_mode) {
+			case HDR_LINEX3_DDR:
+				isp_dev->rd_mode = HDR_RDBK_FRAME3;
+				break;
+			case HDR_LINEX2_DDR:
+				isp_dev->rd_mode = HDR_RDBK_FRAME2;
+				break;
+			default:
+				isp_dev->rd_mode = HDR_RDBK_FRAME1;
+			}
+			break;
+		case RKISP_RTT_MODE_MULTI_FRAME:
+		default:
+			if (isp_dev->tb_head.rtt_mode != RKISP_RTT_MODE_MULTI_FRAME)
+				v4l2_warn(&isp_dev->v4l2_dev,
+					  "invalid rtt mode:%d, change to mode:%d\n",
+					  isp_dev->tb_head.rtt_mode, RKISP_RTT_MODE_MULTI_FRAME);
+			if (!hw->is_single)
+				break;
+			/* switch to online mode for single sensor */
+			switch (rd_mode) {
+			case HDR_RDBK_FRAME3:
+				isp_dev->rd_mode = HDR_LINEX3_DDR;
+				break;
+			case HDR_RDBK_FRAME2:
+				isp_dev->rd_mode = HDR_LINEX2_DDR;
+				break;
+			default:
+				isp_dev->rd_mode = HDR_NORMAL;
+			}
+		}
+		isp_dev->hdr.op_mode = isp_dev->rd_mode;
+		if (rd_mode != isp_dev->rd_mode && hw->cur_dev_id == isp_dev->dev_id) {
+			rkisp_unite_write(isp_dev, CSI2RX_CTRL0,
+					  SW_IBUF_OP_MODE(isp_dev->rd_mode), true);
+			if (IS_HDR_RDBK(isp_dev->rd_mode))
+				rkisp_unite_set_bits(isp_dev, CTRL_SWS_CFG, 0,
+						     SW_MPIP_DROP_FRM_DIS, true);
+			else
+				rkisp_unite_clear_bits(isp_dev, CTRL_SWS_CFG,
+						       SW_MPIP_DROP_FRM_DIS, true);
+		}
+	}
+
+	isp_dev->is_suspend = false;
+	isp_dev->isp_state = ISP_START | ISP_FRAME_END;
+	if (!hw->is_single && hw->is_multi_overflow)
+		hw->pre_dev_id++;
+	if (isp_dev->is_suspend_one_frame && !hw->is_multi_overflow)
+		isp_dev->is_first_double = true;
+	if (hw->isp_ver > ISP_V20) {
+		val = ISP3X_YNR_FST_FRAME | ISP3X_CNR_FST_FRAME |
+		      ISP3X_DHAZ_FST_FRAME | ISP3X_ADRC_FST_FRAME;
+		if (hw->isp_ver == ISP_V32)
+			val |= ISP32_SHP_FST_FRAME;
+		rkisp_unite_set_bits(isp_dev, ISP3X_ISP_CTRL1, 0, val, false);
+	}
+	for (i = 0; i < RKISP_MAX_STREAM; i++) {
+		stream = &isp_dev->cap_dev.stream[i];
+		if (i == RKISP_STREAM_VIR || !stream->streaming || !stream->curr_buf)
+			continue;
+		/* skip first frame due to hw no reference frame information */
+		if (isp_dev->is_first_double)
+			stream->skip_frame = 1;
+	}
+	if (hw->cur_dev_id == isp_dev->dev_id)
+		rkisp_rdbk_trigger_event(isp_dev, T_CMD_QUEUE, NULL);
+
+	if (rkisp_link_sensor(isp_dev->isp_inp)) {
+		for (i = 0; i < p->num_subdevs; i++)
+			v4l2_subdev_call(p->subdevs[i], core, s_power, 1);
+		for (i = 0; i < p->num_subdevs; i++)
+			v4l2_subdev_call(p->subdevs[i], video, s_stream, on);
+	} else if (isp_dev->isp_inp & INP_CIF && !(IS_HDR_RDBK(isp_dev->rd_mode))) {
+		v4l2_subdev_call(p->subdevs[0], core, ioctl, RKISP_VICAP_CMD_QUICK_STREAM, &on);
+	}
+}
+
 static const struct dev_pm_ops rkisp_plat_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
-				pm_runtime_force_resume)
+	.prepare = rkisp_pm_prepare,
+	.complete = rkisp_pm_complete,
 	SET_RUNTIME_PM_OPS(rkisp_runtime_suspend, rkisp_runtime_resume, NULL)
 };
 
diff --git a/kernel/drivers/media/platform/rockchip/isp/dev.h b/kernel/drivers/media/platform/rockchip/isp/dev.h
index 4510f9e..3e65864 100644
--- a/kernel/drivers/media/platform/rockchip/isp/dev.h
+++ b/kernel/drivers/media/platform/rockchip/isp/dev.h
@@ -81,6 +81,7 @@
 	ISP_START = BIT(9),
 	ISP_ERROR = BIT(10),
 	ISP_MIPI_ERROR = BIT(11),
+	ISP_CIF_RESET = BIT(12),
 };
 
 enum rkisp_isp_inp {
@@ -235,6 +236,10 @@
 	size_t resmem_size;
 	struct rkisp_thunderboot_resmem_head tb_head;
 	bool is_thunderboot;
+	/* first frame for rtt */
+	bool is_rtt_first;
+	/* suspend/resume with rtt */
+	bool is_rtt_suspend;
 	struct rkisp_tb_stream_info tb_stream_info;
 	unsigned int tb_addr_idx;
 
@@ -245,6 +250,8 @@
 	bool send_fbcgain;
 	struct rkisp_ispp_buf *cur_fbcgain;
 	struct rkisp_buffer *cur_spbuf;
+
+	struct completion pm_cmpl;
 
 	struct work_struct rdbk_work;
 	struct kfifo rdbk_kfifo;
@@ -269,6 +276,9 @@
 	bool is_first_double;
 	bool is_probe_end;
 	bool is_frame_double;
+	bool is_suspend;
+	bool suspend_sync;
+	bool is_suspend_one_frame;
 
 	struct rkisp_vicap_input vicap_in;
 
@@ -304,4 +314,8 @@
 		rkisp_next_clear_bits(dev, reg, mask, is_direct);
 }
 
+static inline bool rkisp_link_sensor(u32 isp_inp)
+{
+	return isp_inp & (INP_CSI | INP_DVP | INP_LVDS);
+}
 #endif
diff --git a/kernel/drivers/media/platform/rockchip/isp/dmarx.c b/kernel/drivers/media/platform/rockchip/isp/dmarx.c
index 529c099..1f1c028 100644
--- a/kernel/drivers/media/platform/rockchip/isp/dmarx.c
+++ b/kernel/drivers/media/platform/rockchip/isp/dmarx.c
@@ -1156,9 +1156,10 @@
 	u64 sof_time = 0, frame_timestamp = 0;
 	u32 frame_id = 0;
 
-	if (!IS_HDR_RDBK(dev->rd_mode) && id) {
-		*id = atomic_read(&dev->isp_sdev.frm_sync_seq) - 1;
-		return;
+	if (!IS_HDR_RDBK(dev->rd_mode)) {
+		frame_id = atomic_read(&dev->isp_sdev.frm_sync_seq) - 1;
+		frame_timestamp = dev->isp_sdev.frm_timestamp;
+		goto end;
 	}
 
 	spin_lock_irqsave(&dev->rdbk_lock, flag);
@@ -1172,6 +1173,7 @@
 		frame_timestamp = dev->dmarx_dev.pre_frame.timestamp;
 	}
 	spin_unlock_irqrestore(&dev->rdbk_lock, flag);
+end:
 	if (id)
 		*id = frame_id;
 	if (sof_timestamp)
diff --git a/kernel/drivers/media/platform/rockchip/isp/hw.c b/kernel/drivers/media/platform/rockchip/isp/hw.c
index d9d1627..5b0f291 100644
--- a/kernel/drivers/media/platform/rockchip/isp/hw.c
+++ b/kernel/drivers/media/platform/rockchip/isp/hw.c
@@ -35,6 +35,12 @@
  *                     rkisp_hw
  */
 
+struct backup_reg {
+	const u32 base;
+	const u32 shd;
+	u32 val;
+};
+
 struct isp_irqs_data {
 	const char *name;
 	irqreturn_t (*irq_hdl)(int irq, void *ctx);
@@ -346,6 +352,192 @@
 	}
 
 	return 0;
+}
+
+void rkisp_hw_reg_save(struct rkisp_hw_dev *dev)
+{
+	void *buf = dev->sw_reg;
+
+	memcpy_fromio(buf, dev->base_addr, RKISP_ISP_SW_REG_SIZE);
+	if (dev->unite == ISP_UNITE_TWO) {
+		buf += RKISP_ISP_SW_REG_SIZE;
+		memcpy_fromio(buf, dev->base_next_addr, RKISP_ISP_SW_REG_SIZE);
+	}
+}
+
+void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev)
+{
+	struct rkisp_device *isp = dev->isp[dev->cur_dev_id];
+	void __iomem *base = dev->base_addr;
+	void *reg_buf = dev->sw_reg;
+	u32 val, *reg, *reg1, i, j;
+	u32 self_upd_reg[] = {
+		ISP21_BAY3D_BASE, ISP21_DRC_BASE, ISP3X_BAY3D_CTRL,
+		ISP_DHAZ_CTRL, ISP3X_3DLUT_BASE, ISP_RAWAE_LITE_BASE,
+		RAWAE_BIG1_BASE, RAWAE_BIG2_BASE, RAWAE_BIG3_BASE,
+		ISP_RAWHIST_LITE_BASE, ISP_RAWHIST_BIG1_BASE,
+		ISP_RAWHIST_BIG2_BASE, ISP_RAWHIST_BIG3_BASE,
+		ISP_RAWAF_BASE, ISP_RAWAWB_BASE, ISP_LDCH_BASE,
+		ISP3X_CAC_BASE,
+	};
+	struct backup_reg backup[] = {
+		{
+			.base = MI_MP_WR_Y_BASE,
+			.shd = MI_MP_WR_Y_BASE_SHD,
+		}, {
+			.base = MI_MP_WR_CB_BASE,
+			.shd = MI_MP_WR_CB_BASE_SHD,
+		}, {
+			.base = MI_MP_WR_CR_BASE,
+			.shd = MI_MP_WR_CR_BASE_SHD,
+		}, {
+			.base = MI_SP_WR_Y_BASE,
+			.shd = MI_SP_WR_Y_BASE_SHD,
+		}, {
+			.base = MI_SP_WR_CB_BASE,
+			.shd = MI_SP_WR_CB_BASE_AD_SHD,
+		}, {
+			.base = MI_SP_WR_CR_BASE,
+			.shd = MI_SP_WR_CR_BASE_AD_SHD,
+		}, {
+			.base = ISP3X_MI_BP_WR_Y_BASE,
+			.shd = ISP3X_MI_BP_WR_Y_BASE_SHD,
+		}, {
+			.base = ISP3X_MI_BP_WR_CB_BASE,
+			.shd = ISP3X_MI_BP_WR_CB_BASE_SHD,
+		}, {
+			.base = ISP32_MI_MPDS_WR_Y_BASE,
+			.shd = ISP32_MI_MPDS_WR_Y_BASE_SHD,
+		}, {
+			.base = ISP32_MI_MPDS_WR_CB_BASE,
+			.shd = ISP32_MI_MPDS_WR_CB_BASE_SHD,
+		}, {
+			.base = ISP32_MI_BPDS_WR_Y_BASE,
+			.shd = ISP32_MI_BPDS_WR_Y_BASE_SHD,
+		}, {
+			.base = ISP32_MI_BPDS_WR_CB_BASE,
+			.shd = ISP32_MI_BPDS_WR_CB_BASE_SHD,
+		}, {
+			.base = MI_RAW0_WR_BASE,
+			.shd = MI_RAW0_WR_BASE_SHD,
+		}, {
+			.base = MI_RAW1_WR_BASE,
+			.shd = MI_RAW1_WR_BASE_SHD,
+		}, {
+			.base = MI_RAW2_WR_BASE,
+			.shd = MI_RAW2_WR_BASE_SHD,
+		}, {
+			.base = MI_RAW3_WR_BASE,
+			.shd = MI_RAW3_WR_BASE_SHD,
+		}, {
+			.base = MI_RAW0_RD_BASE,
+			.shd = MI_RAW0_RD_BASE_SHD,
+		}, {
+			.base = MI_RAW1_RD_BASE,
+			.shd = MI_RAW1_RD_BASE_SHD,
+		}, {
+			.base = MI_RAW2_RD_BASE,
+			.shd = MI_RAW2_RD_BASE_SHD,
+		}, {
+			.base = MI_GAIN_WR_BASE,
+			.shd = MI_GAIN_WR_BASE_SHD,
+		}
+	};
+
+	for (i = 0; i <= !!dev->unite; i++) {
+		if (dev->unite != ISP_UNITE_TWO && i)
+			break;
+
+		if (i) {
+			reg_buf += RKISP_ISP_SW_REG_SIZE;
+			base = dev->base_next_addr;
+		}
+
+		/* process special reg */
+		for (j = 0; j < ARRAY_SIZE(self_upd_reg); j++) {
+			reg = reg_buf + self_upd_reg[j];
+			*reg &= ~ISP21_SELF_FORCE_UPD;
+			if (self_upd_reg[j] == ISP3X_3DLUT_BASE && *reg & ISP_3DLUT_EN) {
+				reg = reg_buf + ISP3X_3DLUT_UPDATE;
+				*reg = 1;
+			}
+		}
+		reg = reg_buf + ISP_CTRL;
+		*reg &= ~(CIF_ISP_CTRL_ISP_ENABLE |
+			  CIF_ISP_CTRL_ISP_INFORM_ENABLE |
+			  CIF_ISP_CTRL_ISP_CFG_UPD);
+		reg = reg_buf + MI_WR_INIT;
+		*reg = 0;
+		reg = reg_buf + CSI2RX_CTRL0;
+		*reg &= ~SW_CSI2RX_EN;
+		for (j = 0; j < RKISP_ISP_SW_REG_SIZE; j += 4) {
+			/* skip table RAM */
+			if ((j > ISP3X_LSC_CTRL && j < ISP3X_LSC_XGRAD_01) ||
+			    (j > ISP32_CAC_OFFSET && j < ISP3X_CAC_RO_CNT) ||
+			    (j > ISP3X_3DLUT_UPDATE && j < ISP3X_GAIN_BASE) ||
+			    (j == 0x4840 || j == 0x4a80 || j == 0x4b40 || j == 0x5660))
+				continue;
+			/* skip mmu range */
+			if (dev->isp_ver < ISP_V30 &&
+			    j > ISP21_MI_BAY3D_RD_BASE_SHD && j < CSI2RX_CTRL0)
+				continue;
+			/* reg value of read diff to write */
+			if (j == ISP_MPFBC_CTRL ||
+			    j == ISP32_ISP_AWB1_GAIN_G || j == ISP32_ISP_AWB1_GAIN_RB)
+				reg = isp->sw_base_addr + j;
+			else
+				reg = reg_buf + j;
+			writel(*reg, base + j);
+		}
+
+		/* config shd_reg to base_reg */
+		for (j = 0; j < ARRAY_SIZE(backup); j++) {
+			reg = reg_buf + backup[j].base;
+			reg1 = reg_buf + backup[j].shd;
+			backup[j].val = *reg;
+			writel(*reg1, base + backup[j].base);
+		}
+
+		/* update module */
+		reg = reg_buf + DUAL_CROP_CTRL;
+		if (*reg & 0xf)
+			writel(*reg | CIF_DUAL_CROP_CFG_UPD, base + DUAL_CROP_CTRL);
+		reg = reg_buf + SELF_RESIZE_CTRL;
+		if (*reg & 0xf) {
+			if (dev->isp_ver == ISP_V32_L)
+				writel(*reg | ISP32_SCALE_FORCE_UPD, base + ISP32_SELF_SCALE_UPDATE);
+			else
+				writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + SELF_RESIZE_CTRL);
+		}
+		reg = reg_buf + MAIN_RESIZE_CTRL;
+		if (*reg & 0xf)
+			writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + MAIN_RESIZE_CTRL);
+		reg = reg_buf + ISP32_BP_RESIZE_CTRL;
+		if (*reg & 0xf)
+			writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + ISP32_BP_RESIZE_CTRL);
+
+		/* update mi and isp, base_reg will update to shd_reg */
+		writel(CIF_MI_INIT_SOFT_UPD, base + MI_WR_INIT);
+
+		/* config base_reg */
+		for (j = 0; j < ARRAY_SIZE(backup); j++)
+			writel(backup[j].val, base + backup[j].base);
+		/* base_reg = shd_reg, write is base but read is shd */
+		val = rkisp_read_reg_cache(isp, ISP_MPFBC_HEAD_PTR);
+		writel(val, base + ISP_MPFBC_HEAD_PTR);
+		val = rkisp_read_reg_cache(isp, MI_SWS_3A_WR_BASE);
+		writel(val, base + MI_SWS_3A_WR_BASE);
+	}
+
+	rkisp_params_cfgsram(&isp->params_vdev, false);
+
+	reg = reg_buf + ISP_CTRL;
+	*reg |= CIF_ISP_CTRL_ISP_ENABLE |
+		CIF_ISP_CTRL_ISP_CFG_UPD |
+		CIF_ISP_CTRL_ISP_INFORM_ENABLE;
+	writel(*reg, dev->base_addr + ISP_CTRL);
+	if (dev->unite == ISP_UNITE_TWO)
+		writel(*reg, dev->base_next_addr + ISP_CTRL);
 }
 
 static const char * const rk3562_isp_clks[] = {
@@ -779,7 +971,6 @@
 static int enable_sys_clk(struct rkisp_hw_dev *dev)
 {
 	int i, ret = -EINVAL;
-	unsigned long rate;
 
 	for (i = 0; i < dev->num_clks; i++) {
 		if (!IS_ERR(dev->clks[i])) {
@@ -789,12 +980,6 @@
 		}
 	}
 
-	if (!dev->is_assigned_clk) {
-		rate = dev->clk_rate_tbl[0].clk_rate * 1000000UL;
-		rkisp_set_clk_rate(dev->clks[0], rate);
-		if (dev->unite == ISP_UNITE_TWO)
-			rkisp_set_clk_rate(dev->clks[5], rate);
-	}
 	rkisp_soft_reset(dev, false);
 	isp_config_clk(dev, true);
 	return 0;
@@ -851,19 +1036,24 @@
 	struct device *dev = &pdev->dev;
 	struct rkisp_hw_dev *hw_dev;
 	struct resource *res;
-	int i, ret;
+	int i, ret, mult = 1;
 	bool is_mem_reserved = true;
 	u32 clk_rate = 0;
 
 	match = of_match_node(rkisp_hw_of_match, node);
 	if (IS_ERR(match))
 		return PTR_ERR(match);
+	match_data = match->data;
 
 	hw_dev = devm_kzalloc(dev, sizeof(*hw_dev), GFP_KERNEL);
 	if (!hw_dev)
 		return -ENOMEM;
 
-	match_data = match->data;
+	if (match_data->unite)
+		mult = 2;
+	hw_dev->sw_reg = devm_kzalloc(dev, RKISP_ISP_SW_REG_SIZE * mult, GFP_KERNEL);
+	if (!hw_dev->sw_reg)
+		return -ENOMEM;
 	dev_set_drvdata(dev, hw_dev);
 	hw_dev->dev = dev;
 	hw_dev->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
@@ -1041,11 +1231,23 @@
 static int __maybe_unused rkisp_runtime_suspend(struct device *dev)
 {
 	struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev);
+	int i;
 
-	hw_dev->dev_link_num = 0;
-	hw_dev->is_single = true;
-	hw_dev->is_multi_overflow = false;
-	hw_dev->is_frm_buf = false;
+	hw_dev->is_idle = true;
+	if (dev->power.runtime_status) {
+		hw_dev->dev_link_num = 0;
+		hw_dev->is_single = true;
+		hw_dev->is_multi_overflow = false;
+		hw_dev->is_frm_buf = false;
+	} else {
+		/* system suspend */
+		for (i = 0; i < hw_dev->dev_num; i++) {
+			if (hw_dev->isp_size[i].is_on) {
+				rkisp_hw_reg_save(hw_dev);
+				break;
+			}
+		}
+	}
 	disable_sys_clk(hw_dev);
 	return pinctrl_pm_select_sleep_state(dev);
 }
@@ -1055,7 +1257,6 @@
 	struct rkisp_device *isp;
 	u32 w, h, i;
 
-	memset(hw_dev->isp_size, 0, sizeof(hw_dev->isp_size));
 	if (!hw_dev->max_in.is_fix) {
 		hw_dev->max_in.w = 0;
 		hw_dev->max_in.h = 0;
@@ -1108,28 +1309,45 @@
 		return ret;
 
 	enable_sys_clk(hw_dev);
-	for (i = 0; i < hw_dev->dev_num; i++) {
-		isp = hw_dev->isp[i];
-		if (!isp || !isp->sw_base_addr)
-			continue;
-		buf = isp->sw_base_addr;
-		memset(buf, 0, RKISP_ISP_SW_MAX_SIZE * mult);
-		memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE);
-		if (hw_dev->unite) {
-			buf += RKISP_ISP_SW_MAX_SIZE;
-			base = hw_dev->base_next_addr;
-			memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE);
+	if (dev->power.runtime_status) {
+		if (!hw_dev->is_assigned_clk) {
+			unsigned long rate = hw_dev->clk_rate_tbl[0].clk_rate * 1000000UL;
+
+			rkisp_set_clk_rate(hw_dev->clks[0], rate);
+			if (hw_dev->unite == ISP_UNITE_TWO)
+				rkisp_set_clk_rate(hw_dev->clks[5], rate);
 		}
-		default_sw_reg_flag(hw_dev->isp[i]);
+		for (i = 0; i < hw_dev->dev_num; i++) {
+			isp = hw_dev->isp[i];
+			if (!isp || !isp->sw_base_addr)
+				continue;
+			buf = isp->sw_base_addr;
+			memset(buf, 0, RKISP_ISP_SW_MAX_SIZE * mult);
+			memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE);
+			if (hw_dev->unite) {
+				buf += RKISP_ISP_SW_MAX_SIZE;
+				base = hw_dev->base_next_addr;
+				memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE);
+			}
+			default_sw_reg_flag(hw_dev->isp[i]);
+		}
+		rkisp_hw_enum_isp_size(hw_dev);
+		hw_dev->monitor.is_en = rkisp_monitor;
+	} else {
+		/* system resume */
+		for (i = 0; i < hw_dev->dev_num; i++) {
+			if (hw_dev->isp_size[i].is_on) {
+				rkisp_hw_reg_restore(hw_dev);
+				break;
+			}
+		}
 	}
-	rkisp_hw_enum_isp_size(hw_dev);
-	hw_dev->monitor.is_en = rkisp_monitor;
 	return 0;
 }
 
 static const struct dev_pm_ops rkisp_hw_pm_ops = {
-	SET_RUNTIME_PM_OPS(rkisp_runtime_suspend,
-			   rkisp_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+	SET_RUNTIME_PM_OPS(rkisp_runtime_suspend, rkisp_runtime_resume, NULL)
 };
 
 static struct platform_driver rkisp_hw_drv = {
diff --git a/kernel/drivers/media/platform/rockchip/isp/hw.h b/kernel/drivers/media/platform/rockchip/isp/hw.h
index 5c71294..657c77c 100644
--- a/kernel/drivers/media/platform/rockchip/isp/hw.h
+++ b/kernel/drivers/media/platform/rockchip/isp/hw.h
@@ -29,7 +29,6 @@
 	struct rkisp_hw_dev *dev;
 	struct work_struct work;
 	struct completion cmpl;
-	int (*reset_handle)(struct rkisp_device *dev);
 	u32 state;
 	u8 retry;
 	bool is_en;
@@ -53,6 +52,7 @@
 	struct platform_device *pdev;
 	struct device *dev;
 	struct regmap *grf;
+	void *sw_reg;
 	void __iomem *base_addr;
 	void __iomem *base_next_addr;
 	struct clk *clks[RKISP_MAX_BUS_CLK];
@@ -110,4 +110,6 @@
 int rkisp_register_irq(struct rkisp_hw_dev *dev);
 void rkisp_soft_reset(struct rkisp_hw_dev *dev, bool is_secure);
 void rkisp_hw_enum_isp_size(struct rkisp_hw_dev *hw_dev);
+void rkisp_hw_reg_save(struct rkisp_hw_dev *dev);
+void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev);
 #endif
diff --git a/kernel/drivers/media/platform/rockchip/isp/isp_external.h b/kernel/drivers/media/platform/rockchip/isp/isp_external.h
index 6e117d4..6d49074 100644
--- a/kernel/drivers/media/platform/rockchip/isp/isp_external.h
+++ b/kernel/drivers/media/platform/rockchip/isp/isp_external.h
@@ -13,6 +13,15 @@
 #define RKISP_VICAP_CMD_RX_BUFFER_FREE \
 	 _IOW('V', BASE_VIDIOC_PRIVATE + 2, struct rkisp_rx_buf)
 
+#define RKISP_VICAP_CMD_QUICK_STREAM \
+	_IOW('V', BASE_VIDIOC_PRIVATE + 3, int)
+
+#define RKISP_VICAP_CMD_SET_RESET \
+	 _IOW('V', BASE_VIDIOC_PRIVATE + 4, int)
+
+#define RKISP_VICAP_CMD_SET_STREAM \
+	 _IOW('V', BASE_VIDIOC_PRIVATE + 5, int)
+
 #define RKISP_VICAP_BUF_CNT 3
 #define RKISP_VICAP_BUF_CNT_MAX 8
 #define RKISP_RX_BUF_POOL_MAX (RKISP_VICAP_BUF_CNT_MAX * 3)
@@ -26,6 +35,7 @@
 	RKISP_VICAP_ONLINE,
 	RKISP_VICAP_RDBK_AIQ,
 	RKISP_VICAP_RDBK_AUTO,
+	RKISP_VICAP_RDBK_AUTO_ONE_FRAME,
 };
 
 struct rkisp_vicap_mode {
diff --git a/kernel/drivers/media/platform/rockchip/isp/isp_mipi_luma.c b/kernel/drivers/media/platform/rockchip/isp/isp_mipi_luma.c
index 8328398..1e2039e 100644
--- a/kernel/drivers/media/platform/rockchip/isp/isp_mipi_luma.c
+++ b/kernel/drivers/media/platform/rockchip/isp/isp_mipi_luma.c
@@ -396,7 +396,7 @@
 
 	if (send_task) {
 		luma_vdev->work.readout = RKISP_ISP_READOUT_LUMA;
-		luma_vdev->work.timestamp = ktime_get_ns();
+		luma_vdev->work.timestamp = rkisp_time_get_ns(luma_vdev->dev);
 		luma_vdev->work.frame_id = cur_frame_id;
 
 		if (frm_mode == RKISP_LUMA_THREEFRM)
diff --git a/kernel/drivers/media/platform/rockchip/isp/isp_params.c b/kernel/drivers/media/platform/rockchip/isp/isp_params.c
index 3db85a2..03fd7fc 100644
--- a/kernel/drivers/media/platform/rockchip/isp/isp_params.c
+++ b/kernel/drivers/media/platform/rockchip/isp/isp_params.c
@@ -185,6 +185,28 @@
 	spin_lock_irqsave(&params_vdev->config_lock, flags);
 	list_add_tail(&params_buf->queue, &params_vdev->params);
 	spin_unlock_irqrestore(&params_vdev->config_lock, flags);
+
+	if (params_vdev->dev->is_first_double) {
+		struct isp32_isp_params_cfg *params = params_buf->vaddr[0];
+		struct rkisp_buffer *buf;
+
+		if (!(params->module_cfg_update & ISP32_MODULE_RTT_FST))
+			return;
+		spin_lock_irqsave(&params_vdev->config_lock, flags);
+		while (!list_empty(&params_vdev->params)) {
+			buf = list_first_entry(&params_vdev->params,
+					       struct rkisp_buffer, queue);
+			if (buf == params_buf)
+				break;
+			list_del(&buf->queue);
+			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+		}
+		spin_unlock_irqrestore(&params_vdev->config_lock, flags);
+		dev_info(params_vdev->dev->dev,
+			 "first params:%d for rtt resume\n", params->frame_id);
+		params_vdev->dev->is_first_double = false;
+		rkisp_trigger_read_back(params_vdev->dev, false, false, false);
+	}
 }
 
 static void rkisp_params_vb2_stop_streaming(struct vb2_queue *vq)
@@ -193,36 +215,23 @@
 	struct rkisp_device *dev = params_vdev->dev;
 	struct rkisp_buffer *buf;
 	unsigned long flags;
-	int i;
 
 	/* stop params input firstly */
 	spin_lock_irqsave(&params_vdev->config_lock, flags);
 	params_vdev->streamon = false;
 	wake_up(&dev->sync_onoff);
-	spin_unlock_irqrestore(&params_vdev->config_lock, flags);
-
-	for (i = 0; i < RKISP_ISP_PARAMS_REQ_BUFS_MAX; i++) {
-		spin_lock_irqsave(&params_vdev->config_lock, flags);
-		if (!list_empty(&params_vdev->params)) {
-			buf = list_first_entry(&params_vdev->params,
-					       struct rkisp_buffer, queue);
-			list_del(&buf->queue);
-			spin_unlock_irqrestore(&params_vdev->config_lock,
-					       flags);
-		} else {
-			spin_unlock_irqrestore(&params_vdev->config_lock,
-					       flags);
-			break;
-		}
-
+	while (!list_empty(&params_vdev->params)) {
+		buf = list_first_entry(&params_vdev->params,
+				       struct rkisp_buffer, queue);
+		list_del(&buf->queue);
 		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
 	}
-
 	if (params_vdev->cur_buf) {
 		buf = params_vdev->cur_buf;
 		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
 		params_vdev->cur_buf = NULL;
 	}
+	spin_unlock_irqrestore(&params_vdev->config_lock, flags);
 
 	if (dev->is_pre_on) {
 		params_vdev->first_cfg_params = true;
@@ -368,15 +377,16 @@
 		params_vdev->ops->param_cfg(params_vdev, frame_id, RKISP_PARAMS_IMD);
 }
 
-void rkisp_params_cfgsram(struct rkisp_isp_params_vdev *params_vdev)
+void rkisp_params_cfgsram(struct rkisp_isp_params_vdev *params_vdev, bool is_check)
 {
-	if (params_vdev->dev->procfs.mode & RKISP_PROCFS_FIL_SW)
-		return;
+	if (is_check) {
+		if (params_vdev->dev->procfs.mode & RKISP_PROCFS_FIL_SW)
+			return;
 
-	/* multi device to switch sram config */
-	if (params_vdev->dev->hw_dev->is_single)
-		return;
-
+		/* multi device to switch sram config */
+		if (params_vdev->dev->hw_dev->is_single)
+			return;
+	}
 	if (params_vdev->ops->param_cfgsram)
 		params_vdev->ops->param_cfgsram(params_vdev);
 }
@@ -455,6 +465,7 @@
 		params_vdev->ops->stream_stop(params_vdev);
 	if (params_vdev->ops->fop_release)
 		params_vdev->ops->fop_release(params_vdev);
+	params_vdev->first_cfg_params = false;
 }
 
 bool rkisp_params_check_bigmode(struct rkisp_isp_params_vdev *params_vdev)
diff --git a/kernel/drivers/media/platform/rockchip/isp/isp_params.h b/kernel/drivers/media/platform/rockchip/isp/isp_params.h
index d38c0df..2d58aba 100644
--- a/kernel/drivers/media/platform/rockchip/isp/isp_params.h
+++ b/kernel/drivers/media/platform/rockchip/isp/isp_params.h
@@ -140,7 +140,7 @@
 
 void rkisp_params_cfg(struct rkisp_isp_params_vdev *params_vdev, u32 frame_id);
 
-void rkisp_params_cfgsram(struct rkisp_isp_params_vdev *params_vdev);
+void rkisp_params_cfgsram(struct rkisp_isp_params_vdev *params_vdev, bool is_check);
 void rkisp_params_get_meshbuf_inf(struct rkisp_isp_params_vdev *params_vdev, void *meshbuf);
 int rkisp_params_set_meshbuf_size(struct rkisp_isp_params_vdev *params_vdev, void *meshsize);
 void rkisp_params_meshbuf_free(struct rkisp_isp_params_vdev *params_vdev, u64 id);
diff --git a/kernel/drivers/media/platform/rockchip/isp/isp_params_v21.c b/kernel/drivers/media/platform/rockchip/isp/isp_params_v21.c
index 19f2a62..e13e97c 100644
--- a/kernel/drivers/media/platform/rockchip/isp/isp_params_v21.c
+++ b/kernel/drivers/media/platform/rockchip/isp/isp_params_v21.c
@@ -460,10 +460,9 @@
 {
 	int i, j;
 	unsigned int sram_addr;
-	unsigned int data;
+	unsigned int data = rkisp_ioread32(params_vdev, ISP_LSC_CTRL);
 
-	if (is_check &&
-	    !(rkisp_ioread32(params_vdev, ISP_LSC_CTRL) & ISP_LSC_EN))
+	if (is_check && (data & ISP_LSC_LUT_EN || !(data & ISP_LSC_EN)))
 		return;
 
 	/* CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */
@@ -603,12 +602,13 @@
 	 * readback mode lsc lut AHB config to sram, once for single device,
 	 * need record to switch for multi-device.
 	 */
-	if (!IS_HDR_RDBK(dev->rd_mode))
+	if (!IS_HDR_RDBK(dev->rd_mode)) {
 		isp_lsc_matrix_cfg_ddr(params_vdev, arg);
-	else if (dev->hw_dev->is_single)
-		isp_lsc_matrix_cfg_sram(params_vdev, arg, false);
-	else
+	} else {
+		if (dev->hw_dev->is_single)
+			isp_lsc_matrix_cfg_sram(params_vdev, arg, false);
 		params_rec->others.lsc_cfg = *arg;
+	}
 
 	for (i = 0; i < 4; i++) {
 		/* program x size tables */
@@ -1178,6 +1178,12 @@
 		   ISP2X_REG_WR_MASK);
 
 	wnd_num_idx = arg->wnd_num;
+	if (wnd_num_idx >= ARRAY_SIZE(ae_wnd_num)) {
+		wnd_num_idx = ARRAY_SIZE(ae_wnd_num) - 1;
+		dev_err(params_vdev->dev->dev,
+			"%s invalid wnd_num:%d, set to %d\n",
+			__func__, arg->wnd_num, wnd_num_idx);
+	}
 	value |= ISP2X_RAWAEBIG_WNDNUM_SET(wnd_num_idx);
 
 	if (arg->subwin_en[0])
@@ -1327,8 +1333,8 @@
 		      (arg->sw_rawawb_wp_blk_wei_w[5 * i + 1] & 0x3f) << 6 |
 		      (arg->sw_rawawb_wp_blk_wei_w[5 * i + 2] & 0x3f) << 12 |
 		      (arg->sw_rawawb_wp_blk_wei_w[5 * i + 3] & 0x3f) << 18 |
-		      (arg->sw_rawawb_wp_blk_wei_w[5 * i + 4] & 0x3f) << 24,
-		rkisp_iowrite32(params_vdev, val, ISP21_RAWAWB_WRAM_DATA_BASE);
+		      (arg->sw_rawawb_wp_blk_wei_w[5 * i + 4] & 0x3f) << 24;
+		rkisp_write(params_vdev->dev, ISP21_RAWAWB_WRAM_DATA_BASE, val, true);
 	}
 }
 
@@ -2143,10 +2149,9 @@
 
 	if (params_vdev->dev->hw_dev->is_single)
 		isp_rawawb_cfg_sram(params_vdev, arg, false);
-	else
-		memcpy(arg_rec->sw_rawawb_wp_blk_wei_w,
-		       arg->sw_rawawb_wp_blk_wei_w,
-		       ISP21_RAWAWB_WEIGHT_NUM);
+	memcpy(arg_rec->sw_rawawb_wp_blk_wei_w,
+	       arg->sw_rawawb_wp_blk_wei_w,
+	       ISP21_RAWAWB_WEIGHT_NUM);
 
 	/* avoid to override the old enable value */
 	value = rkisp_ioread32(params_vdev, ISP21_RAWAWB_CTRL);
@@ -2292,6 +2297,12 @@
 		return;
 
 	wnd_num_idx = arg->wnd_num;
+	if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
+		wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
+		dev_err(params_vdev->dev->dev,
+			"%s invalid wnd_num:%d, set to %d\n",
+			__func__, arg->wnd_num, wnd_num_idx);
+	}
 	memset(weight15x15, 0, sizeof(weight15x15));
 	for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) {
 		for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) {
@@ -2339,6 +2350,12 @@
 	}
 
 	wnd_num_idx = arg->wnd_num;
+	if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
+		wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
+		dev_err(params_vdev->dev->dev,
+			"%s invalid wnd_num:%d, set to %d\n",
+			__func__, arg->wnd_num, wnd_num_idx);
+	}
 	/* avoid to override the old enable value */
 	hist_ctrl = rkisp_ioread32(params_vdev, addr + ISP_RAWHIST_BIG_CTRL);
 	hist_ctrl &= ISP2X_RAWHSTBIG_CTRL_EN_MASK;
@@ -2370,8 +2387,7 @@
 
 	if (dev->hw_dev->is_single)
 		isp_rawhstbig_cfg_sram(params_vdev, arg, blk_no, false);
-	else
-		*arg_rec = *arg;
+	*arg_rec = *arg;
 }
 
 static void
@@ -4339,7 +4355,7 @@
 		ret = rkisp_alloc_buffer(params_vdev->dev, &priv_val->buf_3dlut[i]);
 		if (ret) {
 			dev_err(dev, "can not alloc buffer\n");
-			goto err;
+			goto err_3dlut;
 		}
 	}
 
@@ -4350,7 +4366,7 @@
 		ret = rkisp_alloc_buffer(params_vdev->dev, &priv_val->buf_lsclut[i]);
 		if (ret) {
 			dev_err(dev, "can not alloc buffer\n");
-			goto err;
+			goto err_lsclut;
 		}
 	}
 
@@ -4359,15 +4375,16 @@
 	params_vdev->priv_ops = &rkisp_v21_isp_params_ops;
 	rkisp_clear_first_param_v2x(params_vdev);
 	return 0;
-
-err:
-	for (i = 0; i < RKISP_PARAM_3DLUT_BUF_NUM; i++)
+err_lsclut:
+	for (i -= 1; i >= 0; i--)
+		rkisp_free_buffer(params_vdev->dev, &priv_val->buf_lsclut[i]);
+	i = RKISP_PARAM_3DLUT_BUF_NUM;
+err_3dlut:
+	for (i -= 1; i >= 0; i--)
 		rkisp_free_buffer(params_vdev->dev, &priv_val->buf_3dlut[i]);
 
-	for (i = 0; i < RKISP_PARAM_LSC_LUT_BUF_NUM; i++)
-		rkisp_free_buffer(params_vdev->dev, &priv_val->buf_lsclut[i]);
 	vfree(params_vdev->isp21_params);
-
+	kfree(priv_val);
 	return ret;
 }
 
diff --git a/kernel/drivers/media/platform/rockchip/isp/isp_params_v2x.c b/kernel/drivers/media/platform/rockchip/isp/isp_params_v2x.c
index b4525b3..c1497a9 100644
--- a/kernel/drivers/media/platform/rockchip/isp/isp_params_v2x.c
+++ b/kernel/drivers/media/platform/rockchip/isp/isp_params_v2x.c
@@ -461,6 +461,12 @@
 	};
 
 	wnd_num_idx = arg->wnd_num;
+	if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
+		wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
+		dev_err(params_vdev->dev->dev,
+			"%s invalid wnd_num:%d, set to %d\n",
+			__func__, arg->wnd_num, wnd_num_idx);
+	}
 	for (i = 0; i < ISP2X_SIHIST_WIN_NUM; i++) {
 		/* avoid to override the old enable value */
 		hist_ctrl = rkisp_ioread32(params_vdev, ISP_HIST_HIST_CTRL + i * 0x10);
@@ -536,10 +542,9 @@
 {
 	int i, j;
 	unsigned int sram_addr;
-	unsigned int data;
+	unsigned int data = rkisp_ioread32(params_vdev, ISP_LSC_CTRL);
 
-	if (is_check &&
-	    !(rkisp_ioread32(params_vdev, ISP_LSC_CTRL) & ISP_LSC_EN))
+	if (is_check && (data & ISP_LSC_LUT_EN || !(data & ISP_LSC_EN)))
 		return;
 
 	/* CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */
@@ -679,12 +684,13 @@
 	 * readback mode lsc lut AHB config to sram, once for single device,
 	 * need record to switch for multi-device.
 	 */
-	if (!IS_HDR_RDBK(dev->rd_mode))
+	if (!IS_HDR_RDBK(dev->rd_mode)) {
 		isp_lsc_matrix_cfg_ddr(params_vdev, arg);
-	else if (dev->hw_dev->is_single)
-		isp_lsc_matrix_cfg_sram(params_vdev, arg, false);
-	else
+	} else {
 		params_rec->others.lsc_cfg = *arg;
+		if (dev->hw_dev->is_single)
+			isp_lsc_matrix_cfg_sram(params_vdev, arg, false);
+	}
 
 	for (i = 0; i < 4; i++) {
 		/* program x size tables */
@@ -1758,6 +1764,12 @@
 		   ISP2X_REG_WR_MASK);
 
 	wnd_num_idx = arg->wnd_num;
+	if (wnd_num_idx >= ARRAY_SIZE(ae_wnd_num)) {
+		wnd_num_idx = ARRAY_SIZE(ae_wnd_num) - 1;
+		dev_err(params_vdev->dev->dev,
+			"%s invalid wnd_num:%d, set to %d\n",
+			__func__, arg->wnd_num, wnd_num_idx);
+	}
 	value |= ISP2X_RAWAEBIG_WNDNUM_SET(wnd_num_idx);
 
 	if (arg->subwin_en[0])
@@ -2831,6 +2843,12 @@
 		return;
 
 	wnd_num_idx = arg->wnd_num;
+	if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
+		wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
+		dev_err(params_vdev->dev->dev,
+			"%s invalid wnd_num:%d, set to %d\n",
+			__func__, arg->wnd_num, wnd_num_idx);
+	}
 	memset(weight15x15, 0, sizeof(weight15x15));
 	for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) {
 		for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) {
@@ -2879,6 +2897,12 @@
 	}
 
 	wnd_num_idx = arg->wnd_num;
+	if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
+		wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
+		dev_err(params_vdev->dev->dev,
+			"%s invalid wnd_num:%d, set to %d\n",
+			__func__, arg->wnd_num, wnd_num_idx);
+	}
 	/* avoid to override the old enable value */
 	hist_ctrl = rkisp_ioread32(params_vdev, addr + ISP_RAWHIST_BIG_CTRL);
 	hist_ctrl &= ISP2X_RAWHSTBIG_CTRL_EN_MASK;
@@ -2910,8 +2934,7 @@
 
 	if (dev->hw_dev->is_single)
 		isp_rawhstbig_cfg_sram(params_vdev, arg, blk_no, false);
-	else
-		*arg_rec = *arg;
+	*arg_rec = *arg;
 }
 
 static void
diff --git a/kernel/drivers/media/platform/rockchip/isp/isp_params_v32.c b/kernel/drivers/media/platform/rockchip/isp/isp_params_v32.c
index 4343412..23072b4 100644
--- a/kernel/drivers/media/platform/rockchip/isp/isp_params_v32.c
+++ b/kernel/drivers/media/platform/rockchip/isp/isp_params_v32.c
@@ -555,11 +555,11 @@
 			bool is_check, u32 id)
 {
 	struct rkisp_device *dev = params_vdev->dev;
-	u32 sram_addr, data, table;
+	u32 data = isp3_param_read(params_vdev, ISP3X_LSC_CTRL, id);
+	u32 sram_addr, table;
 	int i, j;
 
-	if (is_check &&
-	    !(isp3_param_read(params_vdev, ISP3X_LSC_CTRL, id) & ISP_LSC_EN))
+	if (is_check && (data & ISP3X_LSC_LUT_EN || !(data & ISP_LSC_EN)))
 		return;
 
 	table = isp3_param_read_direct(params_vdev, ISP3X_LSC_STATUS);
@@ -643,12 +643,13 @@
 		 * readback mode lsc lut AHB config to sram, once for single device,
 		 * need record to switch for multi-device.
 		 */
-		if (!IS_HDR_RDBK(dev->rd_mode))
+		if (!IS_HDR_RDBK(dev->rd_mode)) {
 			isp_lsc_matrix_cfg_ddr(params_vdev, arg);
-		else if (dev->hw_dev->is_single)
-			isp_lsc_matrix_cfg_sram(params_vdev, arg, false, id);
-		else
+		} else {
+			if (dev->hw_dev->is_single)
+				isp_lsc_matrix_cfg_sram(params_vdev, arg, false, id);
 			params_rec->others.lsc_cfg = *arg;
+		}
 	} else {
 		/* two lsc sram table */
 		params_rec->others.lsc_cfg = *arg;
@@ -1435,6 +1436,12 @@
 	value &= ISP3X_RAWAE_BIG_EN;
 
 	wnd_num_idx = arg->wnd_num;
+	if (wnd_num_idx >= ARRAY_SIZE(ae_wnd_num)) {
+		wnd_num_idx = ARRAY_SIZE(ae_wnd_num) - 1;
+		dev_err(params_vdev->dev->dev,
+			"%s invalid wnd_num:%d, set to %d\n",
+			__func__, arg->wnd_num, wnd_num_idx);
+	}
 	value |= ISP3X_RAWAE_BIG_WND0_NUM(wnd_num_idx);
 
 	if (arg->subwin_en[0])
@@ -1576,20 +1583,19 @@
 isp_rawawb_cfg_sram(struct rkisp_isp_params_vdev *params_vdev,
 		    const struct isp32_rawawb_meas_cfg *arg, bool is_check, u32 id)
 {
-	u32 i, val = ISP32_MODULE_EN;
+	u32 i, val = isp3_param_read(params_vdev, ISP3X_RAWAWB_CTRL, id);
 
-	if (params_vdev->dev->isp_ver == ISP_V32 && is_check &&
-	    !(isp3_param_read(params_vdev, ISP3X_RAWAWB_CTRL, id) & val))
+	if (params_vdev->dev->isp_ver != ISP_V32 ||
+	    (is_check && !(val & ISP32_MODULE_EN)))
 		return;
 
 	for (i = 0; i < ISP32_RAWAWB_WEIGHT_NUM / 5; i++) {
-		isp3_param_write_direct(params_vdev,
-					(arg->wp_blk_wei_w[5 * i] & 0x3f) |
-					(arg->wp_blk_wei_w[5 * i + 1] & 0x3f) << 6 |
-					(arg->wp_blk_wei_w[5 * i + 2] & 0x3f) << 12 |
-					(arg->wp_blk_wei_w[5 * i + 3] & 0x3f) << 18 |
-					(arg->wp_blk_wei_w[5 * i + 4] & 0x3f) << 24,
-					ISP3X_RAWAWB_WRAM_DATA_BASE);
+		val = (arg->wp_blk_wei_w[5 * i] & 0x3f) |
+		      (arg->wp_blk_wei_w[5 * i + 1] & 0x3f) << 6 |
+		      (arg->wp_blk_wei_w[5 * i + 2] & 0x3f) << 12 |
+		      (arg->wp_blk_wei_w[5 * i + 3] & 0x3f) << 18 |
+		      (arg->wp_blk_wei_w[5 * i + 4] & 0x3f) << 24;
+		isp3_param_write_direct(params_vdev, val, ISP3X_RAWAWB_WRAM_DATA_BASE);
 	}
 }
 
@@ -2255,9 +2261,7 @@
 	if (params_vdev->dev->isp_ver == ISP_V32) {
 		if (params_vdev->dev->hw_dev->is_single)
 			isp_rawawb_cfg_sram(params_vdev, arg, false, id);
-		else
-			memcpy(arg_rec->wp_blk_wei_w, arg->wp_blk_wei_w,
-			       ISP32_RAWAWB_WEIGHT_NUM);
+		memcpy(arg_rec->wp_blk_wei_w, arg->wp_blk_wei_w, ISP32_RAWAWB_WEIGHT_NUM);
 	} else {
 		for (i = 0; i < ISP32L_RAWAWB_WEIGHT_NUM; i++)
 			isp3_param_write(params_vdev, arg->win_weight[i],
@@ -2415,6 +2419,12 @@
 		return;
 
 	wnd_num_idx = arg->wnd_num;
+	if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
+		wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
+		dev_err(params_vdev->dev->dev,
+			"%s invalid wnd_num:%d, set to %d\n",
+			__func__, arg->wnd_num, wnd_num_idx);
+	}
 	memset(weight15x15, 0, sizeof(weight15x15));
 	for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) {
 		for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) {
@@ -2465,6 +2475,12 @@
 	}
 
 	wnd_num_idx = arg->wnd_num;
+	if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
+		wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
+		dev_err(params_vdev->dev->dev,
+			"%s invalid wnd_num:%d, set to %d\n",
+			__func__, arg->wnd_num, wnd_num_idx);
+	}
 	/* avoid to override the old enable value */
 	hist_ctrl = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_CTRL, id);
 	hist_ctrl &= ISP3X_RAWHIST_EN;
@@ -2503,8 +2519,7 @@
 
 	if (dev->hw_dev->is_single)
 		isp_rawhstbig_cfg_sram(params_vdev, arg, blk_no, false, id);
-	else
-		*arg_rec = *arg;
+	*arg_rec = *arg;
 }
 
 static void
@@ -4269,8 +4284,6 @@
 {
 	struct rkisp_isp_params_ops_v32 *ops =
 		(struct rkisp_isp_params_ops_v32 *)params_vdev->priv_ops;
-	struct rkisp_isp_params_val_v32 *priv_val =
-		(struct rkisp_isp_params_val_v32 *)params_vdev->priv_val;
 	u64 module_cfg_update = new_params->module_cfg_update;
 
 	params_vdev->cur_frame_id = new_params->frame_id;
@@ -4314,9 +4327,7 @@
 	if ((module_cfg_update & ISP32_MODULE_RAWHIST3))
 		ops->rawhst3_config(params_vdev, &new_params->meas.rawhist3, id);
 
-	if ((module_cfg_update & ISP32_MODULE_RAWAWB) ||
-	    ((priv_val->buf_info_owner == RKISP_INFO2DRR_OWNER_AWB) &&
-	     !(isp3_param_read(params_vdev, ISP3X_RAWAWB_CTRL, id) & ISP32_RAWAWB_2DDR_PATH_EN)))
+	if ((module_cfg_update & ISP32_MODULE_RAWAWB))
 		ops->rawawb_config(params_vdev, &new_params->meas.rawawb, id);
 }
 
@@ -5399,18 +5410,18 @@
 			else if (new_params->module_en_update ||
 				 (new_params->module_cfg_update & ISP32_MODULE_FORCE)) {
 				/* update en immediately */
-				__isp_isr_meas_config(params_vdev, new_params, type, 0);
-				__isp_isr_other_config(params_vdev, new_params, type, 0);
-				__isp_isr_other_en(params_vdev, new_params, type, 0);
-				__isp_isr_meas_en(params_vdev, new_params, type, 0);
+				__isp_isr_meas_config(params_vdev, new_params, RKISP_PARAMS_ALL, 0);
+				__isp_isr_other_config(params_vdev, new_params, RKISP_PARAMS_ALL, 0);
+				__isp_isr_other_en(params_vdev, new_params, RKISP_PARAMS_ALL, 0);
+				__isp_isr_meas_en(params_vdev, new_params, RKISP_PARAMS_ALL, 0);
 				new_params->module_cfg_update = 0;
 				if (hw->unite) {
 					struct isp32_isp_params_cfg *params = new_params + 1;
 
-					__isp_isr_meas_config(params_vdev, params, type, 1);
-					__isp_isr_other_config(params_vdev, params, type, 1);
-					__isp_isr_other_en(params_vdev, params, type, 1);
-					__isp_isr_meas_en(params_vdev, params, type, 1);
+					__isp_isr_meas_config(params_vdev, params, RKISP_PARAMS_ALL, 1);
+					__isp_isr_other_config(params_vdev, params, RKISP_PARAMS_ALL, 1);
+					__isp_isr_other_en(params_vdev, params, RKISP_PARAMS_ALL, 1);
+					__isp_isr_meas_en(params_vdev, params, RKISP_PARAMS_ALL, 1);
 					params->module_cfg_update = 0;
 				}
 			}
diff --git a/kernel/drivers/media/platform/rockchip/isp/isp_params_v3x.c b/kernel/drivers/media/platform/rockchip/isp/isp_params_v3x.c
index bd1e557..0491cc9 100644
--- a/kernel/drivers/media/platform/rockchip/isp/isp_params_v3x.c
+++ b/kernel/drivers/media/platform/rockchip/isp/isp_params_v3x.c
@@ -1291,6 +1291,12 @@
 	value &= ISP3X_RAWAE_BIG_EN;
 
 	wnd_num_idx = arg->wnd_num;
+	if (wnd_num_idx >= ARRAY_SIZE(ae_wnd_num)) {
+		wnd_num_idx = ARRAY_SIZE(ae_wnd_num) - 1;
+		dev_err(params_vdev->dev->dev,
+			"%s invalid wnd_num:%d, set to %d\n",
+			__func__, arg->wnd_num, wnd_num_idx);
+	}
 	value |= ISP3X_RAWAE_BIG_WND0_NUM(wnd_num_idx);
 
 	if (arg->subwin_en[0])
@@ -1430,13 +1436,12 @@
 		return;
 
 	for (i = 0; i < ISP3X_RAWAWB_WEIGHT_NUM / 5; i++) {
-		isp3_param_write(params_vdev,
-				 (arg->sw_rawawb_wp_blk_wei_w[5 * i] & 0x3f) << 0 |
-				 (arg->sw_rawawb_wp_blk_wei_w[5 * i + 1] & 0x3f) << 6 |
-				 (arg->sw_rawawb_wp_blk_wei_w[5 * i + 2] & 0x3f) << 12 |
-				 (arg->sw_rawawb_wp_blk_wei_w[5 * i + 3] & 0x3f) << 18 |
-				 (arg->sw_rawawb_wp_blk_wei_w[5 * i + 4] & 0x3f) << 24,
-				 ISP3X_RAWAWB_WRAM_DATA_BASE, id);
+		val = (arg->sw_rawawb_wp_blk_wei_w[5 * i] & 0x3f) << 0 |
+		      (arg->sw_rawawb_wp_blk_wei_w[5 * i + 1] & 0x3f) << 6 |
+		      (arg->sw_rawawb_wp_blk_wei_w[5 * i + 2] & 0x3f) << 12 |
+		      (arg->sw_rawawb_wp_blk_wei_w[5 * i + 3] & 0x3f) << 18 |
+		      (arg->sw_rawawb_wp_blk_wei_w[5 * i + 4] & 0x3f) << 24;
+		isp3_param_write_direct(params_vdev, val, ISP3X_RAWAWB_WRAM_DATA_BASE, id);
 	}
 }
 
@@ -2288,10 +2293,9 @@
 
 	if (params_vdev->dev->hw_dev->is_single)
 		isp_rawawb_cfg_sram(params_vdev, arg, false, id);
-	else
-		memcpy(arg_rec->sw_rawawb_wp_blk_wei_w,
-		       arg->sw_rawawb_wp_blk_wei_w,
-		       ISP3X_RAWAWB_WEIGHT_NUM);
+	memcpy(arg_rec->sw_rawawb_wp_blk_wei_w,
+	       arg->sw_rawawb_wp_blk_wei_w,
+	       ISP3X_RAWAWB_WEIGHT_NUM);
 
 	/* avoid to override the old enable value */
 	value = isp3_param_read(params_vdev, ISP3X_RAWAWB_CTRL, id);
@@ -2426,6 +2430,12 @@
 		return;
 
 	wnd_num_idx = arg->wnd_num;
+	if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
+		wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
+		dev_err(params_vdev->dev->dev,
+			"%s invalid wnd_num:%d, set to %d\n",
+			__func__, arg->wnd_num, wnd_num_idx);
+	}
 	memset(weight15x15, 0, sizeof(weight15x15));
 	for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) {
 		for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) {
@@ -2473,6 +2483,12 @@
 	}
 
 	wnd_num_idx = arg->wnd_num;
+	if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) {
+		wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1;
+		dev_err(params_vdev->dev->dev,
+			"%s invalid wnd_num:%d, set to %d\n",
+			__func__, arg->wnd_num, wnd_num_idx);
+	}
 	/* avoid to override the old enable value */
 	hist_ctrl = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_CTRL, id);
 	hist_ctrl &= ISP3X_RAWHIST_EN;
@@ -2502,8 +2518,7 @@
 
 	if (dev->hw_dev->is_single)
 		isp_rawhstbig_cfg_sram(params_vdev, arg, blk_no, false, id);
-	else
-		*arg_rec = *arg;
+	*arg_rec = *arg;
 }
 
 static void
diff --git a/kernel/drivers/media/platform/rockchip/isp/isp_rockit.c b/kernel/drivers/media/platform/rockchip/isp/isp_rockit.c
index d97cc27..6a5fa40 100644
--- a/kernel/drivers/media/platform/rockchip/isp/isp_rockit.c
+++ b/kernel/drivers/media/platform/rockchip/isp/isp_rockit.c
@@ -240,10 +240,16 @@
 		rockit_cfg->frame.u64PTS = stream->curr_buf->vb.vb2_buf.timestamp;
 
 		rockit_cfg->frame.u32TimeRef = stream->curr_buf->vb.sequence;
+		v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev,
+			 "%s stream:%d seq:%d buf:0x%x done\n",
+			 __func__, stream->id,
+			 stream->curr_buf->vb.sequence,
+			 stream->curr_buf->buff_addr[0]);
 	} else {
 		if (stream->ispdev->cap_dev.wrap_line &&
 		    stream->id == RKISP_STREAM_MP) {
-			if (stream_cfg->is_discard || stream->ops->is_stream_stopped(stream))
+			if (dev->is_first_double || stream_cfg->is_discard ||
+			    stream->ops->is_stream_stopped(stream))
 				return 0;
 		} else if (stream_cfg->dst_fps) {
 			if (!stream_cfg->is_discard && !stream->curr_buf) {
@@ -259,7 +265,7 @@
 		rkisp_dmarx_get_frame(stream->ispdev, &seq, NULL, &ns, true);
 
 		if (!ns)
-			ns = ktime_get_ns();
+			ns = rkisp_time_get_ns(dev);
 
 		rockit_cfg->frame.u64PTS = ns;
 
@@ -316,8 +322,9 @@
 				int width, int height, int wrap_line)
 {
 	struct rkisp_stream *stream = NULL;
-	struct rkisp_buffer *isp_buf;
+	struct rkisp_buffer *isp_buf, *buf_temp;
 	int offset, i, ret;
+	unsigned long lock_flags = 0;
 
 	stream = rkisp_rockit_get_stream(input_rockit_cfg);
 
@@ -337,16 +344,18 @@
 	if (stream->ispdev->cap_dev.wrap_line && stream->id == RKISP_STREAM_MP)
 		rkisp_dvbm_init(stream);
 
+	spin_lock_irqsave(&stream->vbq_lock, lock_flags);
 	if (stream->curr_buf) {
 		list_add_tail(&stream->curr_buf->queue, &stream->buf_queue);
+		if (stream->curr_buf == stream->next_buf)
+			stream->next_buf = NULL;
 		stream->curr_buf = NULL;
 	}
 	if (stream->next_buf) {
 		list_add_tail(&stream->next_buf->queue, &stream->buf_queue);
 		stream->next_buf = NULL;
 	}
-
-	list_for_each_entry(isp_buf, &stream->buf_queue, queue) {
+	list_for_each_entry_safe(isp_buf, buf_temp, &stream->buf_queue, queue) {
 		if (stream->out_isp_fmt.mplanes == 1) {
 			for (i = 0; i < stream->out_isp_fmt.cplanes - 1; i++) {
 				height = stream->out_fmt.height;
@@ -358,6 +367,7 @@
 			}
 		}
 	}
+	spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
 
 	return 0;
 }
@@ -421,6 +431,46 @@
 }
 EXPORT_SYMBOL(rkisp_rockit_free_tb_stream_buf);
 
+int rkisp_rockit_free_stream_buf(struct rockit_cfg *input_rockit_cfg)
+{
+	struct rkisp_stream *stream;
+	struct rkisp_buffer *buf;
+	unsigned long lock_flags = 0;
+
+	if (!input_rockit_cfg)
+		return -EINVAL;
+	stream = rkisp_rockit_get_stream(input_rockit_cfg);
+	if (!stream)
+		return -EINVAL;
+
+	if (stream->streaming)
+		return 0;
+
+	spin_lock_irqsave(&stream->vbq_lock, lock_flags);
+	if (stream->curr_buf) {
+		list_add_tail(&stream->curr_buf->queue, &stream->buf_queue);
+		if (stream->curr_buf == stream->next_buf)
+			stream->next_buf = NULL;
+		stream->curr_buf = NULL;
+	}
+	if (stream->next_buf) {
+		list_add_tail(&stream->next_buf->queue, &stream->buf_queue);
+		stream->next_buf = NULL;
+	}
+
+	while (!list_empty(&stream->buf_queue)) {
+		buf = list_first_entry(&stream->buf_queue,
+			struct rkisp_buffer, queue);
+		list_del(&buf->queue);
+	}
+	rkisp_rockit_buf_state_clear(stream);
+	spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
+	rkisp_rockit_buf_free(stream);
+
+	return 0;
+}
+EXPORT_SYMBOL(rkisp_rockit_free_stream_buf);
+
 void rkisp_rockit_buf_state_clear(struct rkisp_stream *stream)
 {
 	struct rkisp_stream_cfg *stream_cfg;
@@ -446,6 +496,7 @@
 		return -EINVAL;
 
 	stream_cfg = &rockit_cfg->rkisp_dev_cfg[dev_id].rkisp_stream_cfg[stream->id];
+	mutex_lock(&stream_cfg->freebuf_lock);
 	for (i = 0; i < ROCKIT_BUF_NUM_MAX; i++) {
 		if (stream_cfg->rkisp_buff[i]) {
 			isprk_buf = (struct rkisp_rockit_buffer *)stream_cfg->rkisp_buff[i];
@@ -458,12 +509,14 @@
 			stream_cfg->rkisp_buff[i] = NULL;
 		}
 	}
+	mutex_unlock(&stream_cfg->freebuf_lock);
 	return 0;
 }
 
 void rkisp_rockit_dev_init(struct rkisp_device *dev)
 {
-	int i;
+	struct rkisp_stream_cfg *stream_cfg;
+	int i, j;
 
 	if (rockit_cfg == NULL) {
 		rockit_cfg = kzalloc(sizeof(struct rockit_cfg), GFP_KERNEL);
@@ -477,6 +530,10 @@
 				dev->hw_dev->isp[i]->name;
 			rockit_cfg->rkisp_dev_cfg[i].isp_dev =
 				dev->hw_dev->isp[i];
+			for (j = 0; j < RKISP_MAX_STREAM; j++) {
+				stream_cfg = &rockit_cfg->rkisp_dev_cfg[i].rkisp_stream_cfg[j];
+				mutex_init(&stream_cfg->freebuf_lock);
+			}
 		}
 	}
 }
diff --git a/kernel/drivers/media/platform/rockchip/isp/isp_stats_v21.c b/kernel/drivers/media/platform/rockchip/isp/isp_stats_v21.c
index cb835ee..c630864 100644
--- a/kernel/drivers/media/platform/rockchip/isp/isp_stats_v21.c
+++ b/kernel/drivers/media/platform/rockchip/isp/isp_stats_v21.c
@@ -1100,7 +1100,7 @@
 		work.frame_id = cur_frame_id;
 		work.isp_ris = temp_isp_ris | isp_ris;
 		work.isp3a_ris = temp_isp3a_ris | iq_3a_mask;
-		work.timestamp = ktime_get_ns();
+		work.timestamp = rkisp_time_get_ns(dev);
 
 		rkisp_stats_send_meas_v21(stats_vdev, &work);
 	}
diff --git a/kernel/drivers/media/platform/rockchip/isp/isp_stats_v2x.c b/kernel/drivers/media/platform/rockchip/isp/isp_stats_v2x.c
index 6e458a5..b69b48f 100644
--- a/kernel/drivers/media/platform/rockchip/isp/isp_stats_v2x.c
+++ b/kernel/drivers/media/platform/rockchip/isp/isp_stats_v2x.c
@@ -1406,7 +1406,7 @@
 		work.frame_id = cur_frame_id;
 		work.isp_ris = temp_isp_ris | isp_ris;
 		work.isp3a_ris = temp_isp3a_ris | iq_3a_mask;
-		work.timestamp = ktime_get_ns();
+		work.timestamp = rkisp_time_get_ns(dev);
 
 		if (!IS_HDR_RDBK(dev->hdr.op_mode)) {
 			if (!kfifo_is_full(&stats_vdev->rd_kfifo))
diff --git a/kernel/drivers/media/platform/rockchip/isp/isp_stats_v32.c b/kernel/drivers/media/platform/rockchip/isp/isp_stats_v32.c
index cd0a490..6e73379 100644
--- a/kernel/drivers/media/platform/rockchip/isp/isp_stats_v32.c
+++ b/kernel/drivers/media/platform/rockchip/isp/isp_stats_v32.c
@@ -468,7 +468,7 @@
 	struct rkisp_isp_params_val_v32 *priv_val;
 	struct rkisp_dummy_buffer *buf;
 	int idx, buf_fd = -1;
-	u32 reg = 0, ctrl;
+	u32 reg = 0, ctrl, mask;
 
 	priv_val = (struct rkisp_isp_params_val_v32 *)dev->params_vdev.priv_val;
 	if (!priv_val->buf_info_owner && priv_val->buf_info_idx >= 0) {
@@ -481,9 +481,11 @@
 	if (priv_val->buf_info_owner == RKISP_INFO2DRR_OWNER_GAIN) {
 		reg = ISP3X_GAIN_CTRL;
 		ctrl = ISP3X_GAIN_2DDR_EN;
+		mask = ISP3X_GAIN_2DDR_EN;
 	} else {
 		reg = ISP3X_RAWAWB_CTRL;
 		ctrl = ISP32_RAWAWB_2DDR_PATH_EN;
+		mask = ISP32_RAWAWB_2DDR_PATH_EN | ISP32_RAWAWB_2DDR_PATH_DS;
 	}
 
 	idx = priv_val->buf_info_idx;
@@ -510,6 +512,12 @@
 		} else if (reg == ISP3X_RAWAWB_CTRL &&
 			   rkisp_read(dev, reg, true) & ISP32_RAWAWB_2DDR_PATH_ERR) {
 			v4l2_warn(&dev->v4l2_dev, "rawawb2ddr path error idx:%d\n", idx);
+		} else {
+			u32 v0 = rkisp_read(dev, reg, false);
+			u32 v1 = rkisp_read_reg_cache(dev, reg);
+
+			if ((v0 & mask) != (v1 & mask))
+				rkisp_write(dev, reg, v0 | (v1 & mask), false);
 		}
 
 		if (buf_fd == -1)
@@ -627,6 +635,9 @@
 		ops->get_dhaz_stats(stats_vdev, cur_stat_buf);
 		ops->get_vsm_stats(stats_vdev, cur_stat_buf);
 	}
+
+	if (cur_stat_buf && stats_vdev->dev->is_first_double)
+		cur_stat_buf->meas_type |= ISP32_STAT_RTT_FST;
 
 	if (is_dummy) {
 		spin_lock_irqsave(&stats_vdev->rd_lock, flags);
@@ -1035,7 +1046,7 @@
 		work.frame_id = cur_frame_id;
 		work.isp_ris = temp_isp_ris | isp_ris;
 		work.isp3a_ris = temp_isp3a_ris;
-		work.timestamp = ktime_get_ns();
+		work.timestamp = rkisp_time_get_ns(stats_vdev->dev);
 		rkisp_stats_send_meas_v32(stats_vdev, &work);
 	}
 
diff --git a/kernel/drivers/media/platform/rockchip/isp/isp_stats_v3x.c b/kernel/drivers/media/platform/rockchip/isp/isp_stats_v3x.c
index 12bac61..b74736d 100644
--- a/kernel/drivers/media/platform/rockchip/isp/isp_stats_v3x.c
+++ b/kernel/drivers/media/platform/rockchip/isp/isp_stats_v3x.c
@@ -1149,7 +1149,7 @@
 		work.frame_id = cur_frame_id;
 		work.isp_ris = temp_isp_ris | isp_ris;
 		work.isp3a_ris = temp_isp3a_ris | iq_3a_mask;
-		work.timestamp = ktime_get_ns();
+		work.timestamp = rkisp_time_get_ns(dev);
 
 		rkisp_stats_send_meas_v3x(stats_vdev, &work);
 	}
diff --git a/kernel/drivers/media/platform/rockchip/isp/rkisp.c b/kernel/drivers/media/platform/rockchip/isp/rkisp.c
index 6bab4e5..ac40adf 100644
--- a/kernel/drivers/media/platform/rockchip/isp/rkisp.c
+++ b/kernel/drivers/media/platform/rockchip/isp/rkisp.c
@@ -87,12 +87,6 @@
 
 static void rkisp_config_cmsk(struct rkisp_device *dev);
 
-struct backup_reg {
-	const u32 base;
-	const u32 shd;
-	u32 val;
-};
-
 static inline struct rkisp_device *sd_to_isp_dev(struct v4l2_subdev *sd)
 {
 	return container_of(sd->v4l2_dev, struct rkisp_device, v4l2_dev);
@@ -730,7 +724,7 @@
 		params_vdev->rdbk_times = dma2frm + 1;
 
 run_next:
-	rkisp_params_cfgsram(params_vdev);
+	rkisp_params_cfgsram(params_vdev, true);
 	stats_vdev->rdbk_drop = false;
 	if (dev->is_frame_double) {
 		is_upd = true;
@@ -753,6 +747,16 @@
 			writel(val, hw->base_addr + ISP3X_DRC_EXPLRATIO);
 			if (hw->unite == ISP_UNITE_TWO)
 				writel(val, hw->base_next_addr + ISP3X_DRC_EXPLRATIO);
+			val = rkisp_read_reg_cache(dev, ISP3X_YNR_GLOBAL_CTRL);
+			writel(val, hw->base_addr + ISP3X_YNR_GLOBAL_CTRL);
+			if (hw->unite == ISP_UNITE_TWO)
+				writel(val, hw->base_next_addr + ISP3X_YNR_GLOBAL_CTRL);
+			if (dev->isp_ver == ISP_V21 || dev->isp_ver == ISP_V30) {
+				val = rkisp_read_reg_cache(dev, ISP3X_CNR_CTRL);
+				writel(val, hw->base_addr + ISP3X_CNR_CTRL);
+				if (hw->unite == ISP_UNITE_TWO)
+					writel(val, hw->base_next_addr + ISP3X_CNR_CTRL);
+			}
 		} else {
 			/* the frame first running to off mi to save bandwidth */
 			rkisp_multi_overflow_hdl(dev, false);
@@ -869,6 +873,9 @@
 	struct rkisp_buffer *buf;
 	u32 i, val;
 
+	if (!dev->is_rtt_first)
+		return;
+
 	for (i = RKISP_STREAM_RAWRD0; i < RKISP_MAX_DMARX_STREAM; i++) {
 		stream = &dev->dmarx_dev.stream[i];
 		if (!stream->ops)
@@ -933,11 +940,16 @@
 		goto end;
 	if (!IS_HDR_RDBK(dev->rd_mode))
 		goto end;
+	if (dev->is_suspend) {
+		if (dev->suspend_sync)
+			complete(&dev->pm_cmpl);
+		goto end;
+	}
 
 	for (i = 0; i < hw->dev_num; i++) {
 		isp = hw->isp[i];
 		if (!isp ||
-		    (isp && !(isp->isp_state & ISP_START)))
+		    (isp && (!(isp->isp_state & ISP_START) || isp->is_suspend)))
 			continue;
 		rkisp_rdbk_trigger_event(isp, T_CMD_LEN, &len[i]);
 		if (max < len[i]) {
@@ -947,7 +959,7 @@
 	}
 
 	/* wait 2 frame to start isp for fast */
-	if (dev->is_pre_on && max == 1 && !atomic_read(&dev->isp_sdev.frm_sync_seq))
+	if (dev->is_rtt_first && max == 1 && !atomic_read(&dev->isp_sdev.frm_sync_seq))
 		goto end;
 
 	if (max) {
@@ -993,7 +1005,7 @@
 		/* first frame handle twice for thunderboot
 		 * first output stats to AIQ and wait new params to run second
 		 */
-		if (isp->is_pre_on && t.frame_id == 0) {
+		if (isp->is_rtt_first && t.frame_id == 0) {
 			isp->is_first_double = true;
 			isp->skip_frame = 1;
 			if (hw->unite != ISP_UNITE_ONE) {
@@ -1001,6 +1013,8 @@
 				isp->is_frame_double = false;
 			}
 			rkisp_fast_switch_rx_buf(isp, false);
+		} else {
+			isp->is_rtt_first = false;
 		}
 		isp->params_vdev.rdbk_times = isp->sw_rd_cnt + 1;
 	}
@@ -1079,6 +1093,7 @@
 
 	if (dev->is_first_double) {
 		rkisp_fast_switch_rx_buf(dev, true);
+		dev->is_rtt_first = false;
 		dev->skip_frame = 0;
 		dev->irq_ends = 0;
 		return;
@@ -1170,86 +1185,19 @@
 	rkisp_write(dev, CIF_ISP_IS_CTRL, 1, false);
 }
 
-static int rkisp_reset_handle_v2x(struct rkisp_device *dev)
+static int rkisp_reset_handle(struct rkisp_device *dev)
 {
-	void __iomem *base = dev->base_addr;
-	void *reg_buf = NULL;
-	u32 *reg, *reg1, i;
-	struct backup_reg backup[] = {
-		{
-			.base = MI_MP_WR_Y_BASE,
-			.shd = MI_MP_WR_Y_BASE_SHD,
-		}, {
-			.base = MI_MP_WR_CB_BASE,
-			.shd = MI_MP_WR_CB_BASE_SHD,
-		}, {
-			.base = MI_MP_WR_CR_BASE,
-			.shd = MI_MP_WR_CR_BASE_SHD,
-		}, {
-			.base = MI_SP_WR_Y_BASE,
-			.shd = MI_SP_WR_Y_BASE_SHD,
-		}, {
-			.base = MI_SP_WR_CB_BASE,
-			.shd = MI_SP_WR_CB_BASE_AD_SHD,
-		}, {
-			.base = MI_SP_WR_CR_BASE,
-			.shd = MI_SP_WR_CR_BASE_AD_SHD,
-		}, {
-			.base = MI_RAW0_WR_BASE,
-			.shd = MI_RAW0_WR_BASE_SHD,
-		}, {
-			.base = MI_RAW1_WR_BASE,
-			.shd = MI_RAW1_WR_BASE_SHD,
-		}, {
-			.base = MI_RAW2_WR_BASE,
-			.shd = MI_RAW2_WR_BASE_SHD,
-		}, {
-			.base = MI_RAW3_WR_BASE,
-			.shd = MI_RAW3_WR_BASE_SHD,
-		}, {
-			.base = MI_RAW0_RD_BASE,
-			.shd = MI_RAW0_RD_BASE_SHD,
-		}, {
-			.base = MI_RAW1_RD_BASE,
-			.shd = MI_RAW1_RD_BASE_SHD,
-		}, {
-			.base = MI_RAW2_RD_BASE,
-			.shd = MI_RAW2_RD_BASE_SHD,
-		}, {
-			.base = MI_GAIN_WR_BASE,
-			.shd = MI_GAIN_WR_BASE_SHD,
-		}
-	};
-
-	reg_buf = kzalloc(RKISP_ISP_SW_REG_SIZE, GFP_KERNEL);
-	if (!reg_buf)
-		return -ENOMEM;
+	u32 val;
 
 	dev_info(dev->dev, "%s enter\n", __func__);
+	rkisp_hw_reg_save(dev->hw_dev);
 
-	memcpy_fromio(reg_buf, base, RKISP_ISP_SW_REG_SIZE);
 	rkisp_soft_reset(dev->hw_dev, true);
 
-	/* process special reg */
-	reg = reg_buf + ISP_CTRL;
-	*reg &= ~(CIF_ISP_CTRL_ISP_ENABLE |
-		  CIF_ISP_CTRL_ISP_INFORM_ENABLE |
-		  CIF_ISP_CTRL_ISP_CFG_UPD);
-	reg = reg_buf + MI_WR_INIT;
-	*reg = 0;
-	reg = reg_buf + CSI2RX_CTRL0;
-	*reg &= ~SW_CSI2RX_EN;
-	/* skip mmu range */
-	memcpy_toio(base, reg_buf, ISP21_MI_BAY3D_RD_BASE_SHD);
-	memcpy_toio(base + CSI2RX_CTRL0, reg_buf + CSI2RX_CTRL0,
-		    RKISP_ISP_SW_REG_SIZE - CSI2RX_CTRL0);
-	/* config shd_reg to base_reg */
-	for (i = 0; i < ARRAY_SIZE(backup); i++) {
-		reg = reg_buf + backup[i].base;
-		reg1 = reg_buf + backup[i].shd;
-		backup[i].val = *reg;
-		writel(*reg1, base + backup[i].base);
-	}
+	rkisp_hw_reg_restore(dev->hw_dev);
+
+	val = CIF_ISP_DATA_LOSS | CIF_ISP_PIC_SIZE_ERROR;
+	rkisp_unite_set_bits(dev, CIF_ISP_IMSC, 0, val, true);
 
 	/* clear state */
 	dev->isp_err_cnt = 0;
@@ -1257,40 +1205,12 @@
 	rkisp_set_state(&dev->isp_state, ISP_FRAME_END);
 	dev->hw_dev->monitor.state = ISP_FRAME_END;
 
-	/* update module */
-	reg = reg_buf + DUAL_CROP_CTRL;
-	if (*reg & 0xf)
-		writel(*reg | CIF_DUAL_CROP_CFG_UPD, base + DUAL_CROP_CTRL);
-	reg = reg_buf + SELF_RESIZE_CTRL;
-	if (*reg & 0xf)
-		writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + SELF_RESIZE_CTRL);
-	reg = reg_buf + MAIN_RESIZE_CTRL;
-	if (*reg & 0xf)
-		writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + MAIN_RESIZE_CTRL);
-
-	/* update mi and isp, base_reg will update to shd_reg */
-	force_cfg_update(dev);
-	reg = reg_buf + ISP_CTRL;
-	*reg |= CIF_ISP_CTRL_ISP_ENABLE |
-		CIF_ISP_CTRL_ISP_INFORM_ENABLE |
-		CIF_ISP_CTRL_ISP_CFG_UPD;
-	writel(*reg, base + ISP_CTRL);
-	udelay(50);
-	/* config base_reg */
-	for (i = 0; i < ARRAY_SIZE(backup); i++)
-		writel(backup[i].val, base + backup[i].base);
-	/* mpfbc base_reg = shd_reg, write is base but read is shd */
-	if (dev->isp_ver == ISP_V20)
-		writel(rkisp_read_reg_cache(dev, ISP_MPFBC_HEAD_PTR),
-		       base + ISP_MPFBC_HEAD_PTR);
-	rkisp_set_bits(dev, CIF_ISP_IMSC, 0, CIF_ISP_DATA_LOSS | CIF_ISP_PIC_SIZE_ERROR, true);
 	if (IS_HDR_RDBK(dev->hdr.op_mode)) {
 		if (!dev->hw_dev->is_idle)
 			rkisp_trigger_read_back(dev, 1, 0, true);
 		else
 			rkisp_rdbk_trigger_event(dev, T_CMD_QUEUE, NULL);
 	}
-	kfree(reg_buf);
 	dev_info(dev->dev, "%s exit\n", __func__);
 	return 0;
 }
@@ -1304,11 +1224,6 @@
 	struct rkisp_pipeline *p;
 	int ret, i, j, timeout = 5, mipi_irq_cnt = 0;
 
-	if (!monitor->reset_handle) {
-		monitor->is_en = false;
-		return;
-	}
-
 	dev_info(hw->dev, "%s enter\n", __func__);
 	while (!(monitor->state & ISP_STOP) && monitor->is_en) {
 		ret = wait_for_completion_timeout(&monitor->cmpl,
@@ -1316,8 +1231,11 @@
 		/* isp stop to exit
 		 * isp err to reset
 		 * mipi err wait isp idle, then reset
+		 * online vicap if isp err, notify vicap reset, then vicap notify isp reset
+		 * by ioctl RKISP_VICAP_CMD_SET_STREAM
 		 */
 		if (monitor->state & ISP_STOP ||
+		    monitor->state & ISP_CIF_RESET ||
 		    (ret && !(monitor->state & ISP_ERROR)) ||
 		    (!ret &&
 		     monitor->state & ISP_FRAME_END &&
@@ -1366,10 +1284,22 @@
 
 		/* restart isp */
 		isp = hw->isp[hw->cur_dev_id];
-		ret = monitor->reset_handle(isp);
-		if (ret) {
-			monitor->is_en = false;
-			break;
+		if (!IS_HDR_RDBK(isp->hdr.op_mode) && isp->isp_ver >= ISP_V30) {
+			struct v4l2_subdev *remote = NULL;
+			struct v4l2_subdev *isp_subdev = NULL;
+
+			isp_subdev = &(isp->isp_sdev.sd);
+			remote = get_remote_sensor(isp_subdev);
+			v4l2_subdev_call(remote, core, ioctl,
+				RKISP_VICAP_CMD_SET_RESET, NULL);
+			monitor->state |= ISP_CIF_RESET;
+			continue;
+		} else {
+			ret = rkisp_reset_handle(isp);
+			if (ret) {
+				monitor->is_en = false;
+				break;
+			}
 		}
 
 		for (i = 0; i < hw->dev_num; i++) {
@@ -1403,9 +1333,6 @@
 	struct rkisp_monitor *monitor = &dev->hw_dev->monitor;
 
 	monitor->dev = dev->hw_dev;
-	monitor->reset_handle = NULL;
-	if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21)
-		monitor->reset_handle = rkisp_reset_handle_v2x;
 
 	init_completion(&monitor->cmpl);
 	INIT_WORK(&monitor->work, rkisp_restart_monitor);
@@ -1570,6 +1497,7 @@
 			left.win[0].win_en &= ~BIT(i);
 			left.win[1].win_en &= ~BIT(i);
 			left.win[2].win_en &= ~BIT(i);
+			right.win[i].h_offs = h_offs - w + RKMOUDLE_UNITE_EXTEND_PIXEL;
 		} else {
 			/* cmsk window at dual isp */
 			left.win[i].h_size = ALIGN(w - h_offs, 8);
@@ -2927,6 +2855,7 @@
 {
 	struct rkisp_device *isp_dev = sd_to_isp_dev(sd);
 	struct rkisp_hw_dev *hw_dev = isp_dev->hw_dev;
+	int ret;
 
 	if (!on) {
 		if (IS_HDR_RDBK(isp_dev->rd_mode)) {
@@ -2939,10 +2868,13 @@
 					wake_up(&s->done);
 			}
 		}
-		wait_event_timeout(isp_dev->sync_onoff,
-				   isp_dev->isp_state & ISP_STOP ||
-				   !IS_HDR_RDBK(isp_dev->rd_mode),
-				   msecs_to_jiffies(50));
+		ret = wait_event_timeout(isp_dev->sync_onoff,
+					 isp_dev->isp_state & ISP_STOP ||
+					 !IS_HDR_RDBK(isp_dev->rd_mode),
+					 msecs_to_jiffies(500));
+		if (!ret)
+			v4l2_warn(&isp_dev->v4l2_dev, "%s wait timeout, mode:%d state:0x%x\n",
+				  __func__, isp_dev->rd_mode, isp_dev->isp_state);
 		rkisp_isp_stop(isp_dev);
 		atomic_dec(&hw_dev->refcnt);
 		rkisp_params_stream_stop(&isp_dev->params_vdev);
@@ -3117,7 +3049,8 @@
 
 	pool->dbufs = dbufs;
 	v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
-		 "%s type:0x%x dbufs[%d]:%p", __func__, dbufs->type, i, dbufs);
+		 "%s type:0x%x first:%d dbufs[%d]:%p", __func__,
+		 dbufs->type, dbufs->is_first, i, dbufs);
 
 	if (dbufs->is_resmem) {
 		dma = dbufs->dma;
@@ -3483,6 +3416,59 @@
 	return 0;
 }
 
+static int rkisp_set_work_mode_by_vicap(struct rkisp_device *isp_dev,
+					struct rkisp_vicap_mode *vicap_mode)
+{
+	struct rkisp_hw_dev *hw = isp_dev->hw_dev;
+	int rd_mode = isp_dev->rd_mode;
+
+	isp_dev->is_suspend_one_frame = false;
+	if (vicap_mode->rdbk_mode == RKISP_VICAP_ONLINE) {
+		if (!hw->is_single)
+			return -EINVAL;
+		/* switch to online mode for single sensor */
+		switch (rd_mode) {
+		case HDR_RDBK_FRAME3:
+			isp_dev->rd_mode = HDR_LINEX3_DDR;
+			break;
+		case HDR_RDBK_FRAME2:
+			isp_dev->rd_mode = HDR_LINEX2_DDR;
+			break;
+		default:
+			isp_dev->rd_mode = HDR_NORMAL;
+		}
+	} else if (vicap_mode->rdbk_mode == RKISP_VICAP_RDBK_AUTO ||
+		   vicap_mode->rdbk_mode == RKISP_VICAP_RDBK_AUTO_ONE_FRAME) {
+		/* switch to readback mode */
+		switch (rd_mode) {
+		case HDR_LINEX3_DDR:
+			isp_dev->rd_mode = HDR_RDBK_FRAME3;
+			break;
+		case HDR_LINEX2_DDR:
+			isp_dev->rd_mode = HDR_RDBK_FRAME2;
+			break;
+		default:
+			isp_dev->rd_mode = HDR_RDBK_FRAME1;
+		}
+		if (vicap_mode->rdbk_mode == RKISP_VICAP_RDBK_AUTO_ONE_FRAME)
+			isp_dev->is_suspend_one_frame = true;
+	} else {
+		return -EINVAL;
+	}
+	isp_dev->hdr.op_mode = isp_dev->rd_mode;
+	if (rd_mode != isp_dev->rd_mode && hw->cur_dev_id == isp_dev->dev_id) {
+		rkisp_unite_write(isp_dev, CSI2RX_CTRL0,
+				  SW_IBUF_OP_MODE(isp_dev->rd_mode), true);
+		if (IS_HDR_RDBK(isp_dev->rd_mode))
+			rkisp_unite_set_bits(isp_dev, CTRL_SWS_CFG, 0,
+					     SW_MPIP_DROP_FRM_DIS, true);
+		else
+			rkisp_unite_clear_bits(isp_dev, CTRL_SWS_CFG,
+					       SW_MPIP_DROP_FRM_DIS, true);
+	}
+	return 0;
+}
+
 static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
 	struct rkisp_device *isp_dev = sd_to_isp_dev(sd);
@@ -3508,7 +3494,7 @@
 		rkisp_get_info(isp_dev, arg);
 		break;
 	case RKISP_CMD_GET_TB_HEAD_V32:
-		if (isp_dev->tb_head.complete != RKISP_TB_OK || !isp_dev->is_pre_on) {
+		if (isp_dev->tb_head.complete != RKISP_TB_OK) {
 			ret = -EINVAL;
 			break;
 		}
@@ -3606,6 +3592,16 @@
 			isp_dev->hw_dev->is_multi_overflow = false;
 			rkisp_hw_enum_isp_size(isp_dev->hw_dev);
 		}
+		break;
+	case RKISP_VICAP_CMD_SET_STREAM:
+		ret = rkisp_reset_handle(isp_dev);
+		if (!ret) {
+			if (isp_dev->hw_dev->monitor.state & ISP_CIF_RESET)
+				isp_dev->hw_dev->monitor.state &= ~ISP_CIF_RESET;
+		}
+		break;
+	case RKISP_VICAP_CMD_MODE:
+		ret = rkisp_set_work_mode_by_vicap(isp_dev, arg);
 		break;
 	default:
 		ret = -ENOIOCTLCMD;
@@ -3707,6 +3703,9 @@
 		ret = rkisp_ioctl(sd, cmd, &module_id);
 		break;
 	case RKISP_CMD_MULTI_DEV_FORCE_ENUM:
+		ret = rkisp_ioctl(sd, cmd, NULL);
+		break;
+	case RKISP_VICAP_CMD_SET_STREAM:
 		ret = rkisp_ioctl(sd, cmd, NULL);
 		break;
 	default:
@@ -3828,6 +3827,7 @@
 	atomic_set(&isp_sdev->frm_sync_seq, 0);
 	rkisp_monitor_init(isp_dev);
 	INIT_WORK(&isp_dev->rdbk_work, rkisp_rdbk_work);
+	init_completion(&isp_dev->pm_cmpl);
 	return 0;
 err_cleanup_media_entity:
 	media_entity_cleanup(&sd->entity);
@@ -3867,8 +3867,7 @@
 	(cond) ? 0 : -ETIMEDOUT; \
 })
 
-#ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
-static void rkisp_save_tb_info(struct rkisp_device *isp_dev)
+void rkisp_save_tb_info(struct rkisp_device *isp_dev)
 {
 	struct rkisp_isp_params_vdev *params_vdev = &isp_dev->params_vdev;
 	void *resmem_va = phys_to_virt(isp_dev->resmem_pa);
@@ -3888,7 +3887,8 @@
 	if (size && size < isp_dev->resmem_size) {
 		dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr + offset,
 					size, DMA_FROM_DEVICE);
-		params_vdev->is_first_cfg = true;
+		if (isp_dev->is_rtt_first)
+			params_vdev->is_first_cfg = true;
 		if (isp_dev->isp_ver == ISP_V32) {
 			struct rkisp32_thunderboot_resmem_head *tmp = resmem_va + offset;
 
@@ -3900,7 +3900,7 @@
 				  tmp->cfg.module_ens,
 				  tmp->cfg.module_cfg_update);
 		}
-		if (param)
+		if (param && (isp_dev->isp_state & ISP_STOP))
 			params_vdev->ops->save_first_param(params_vdev, param);
 	} else if (size > isp_dev->resmem_size) {
 		v4l2_err(&isp_dev->v4l2_dev,
@@ -3911,6 +3911,7 @@
 	memcpy(&isp_dev->tb_head, head, sizeof(*head));
 }
 
+#ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
 void rkisp_chk_tb_over(struct rkisp_device *isp_dev)
 {
 	struct rkisp_isp_params_vdev *params_vdev = &isp_dev->params_vdev;
@@ -3958,11 +3959,10 @@
 end:
 	head = &isp_dev->tb_head;
 	v4l2_info(&isp_dev->v4l2_dev,
-		  "thunderboot info: %d, %d, %d, %d, %d, %d | %d %d\n",
+		  "tb info en:%d comp:%d cnt:%d w:%d h:%d cam:%d idx:%d\n",
 		  head->enable,
 		  head->complete,
 		  head->frm_total,
-		  head->hdr_mode,
 		  head->width,
 		  head->height,
 		  head->camera_num,
@@ -4176,7 +4176,7 @@
 		if (isp_mis & CIF_ISP_FRAME)
 			sof_event_later = true;
 		if (dev->vs_irq < 0 && !sof_event_later) {
-			dev->isp_sdev.frm_timestamp = ktime_get_ns();
+			dev->isp_sdev.frm_timestamp = rkisp_time_get_ns(dev);
 			rkisp_isp_queue_event_sof(&dev->isp_sdev);
 			rkisp_stream_frame_start(dev, isp_mis);
 		}
@@ -4244,7 +4244,7 @@
 	/* sampled input frame is complete */
 	if (isp_mis & CIF_ISP_FRAME_IN) {
 		dev->isp_sdev.dbg.interval =
-			ktime_get_ns() - dev->isp_sdev.dbg.timestamp;
+			rkisp_time_get_ns(dev) - dev->isp_sdev.dbg.timestamp;
 		rkisp_set_state(&dev->isp_state, ISP_FRAME_IN);
 		writel(CIF_ISP_FRAME_IN, base + CIF_ISP_ICR);
 		isp_mis_tmp = readl(base + CIF_ISP_MIS);
@@ -4258,7 +4258,7 @@
 		dev->rawaf_irq_cnt = 0;
 		if (!dev->is_pre_on || !IS_HDR_RDBK(dev->rd_mode))
 			dev->isp_sdev.dbg.interval =
-				ktime_get_ns() - dev->isp_sdev.dbg.timestamp;
+				rkisp_time_get_ns(dev) - dev->isp_sdev.dbg.timestamp;
 		/* Clear Frame In (ISP) */
 		rkisp_set_state(&dev->isp_state, ISP_FRAME_END);
 		writel(CIF_ISP_FRAME, base + CIF_ISP_ICR);
@@ -4278,7 +4278,7 @@
 			u64 tmp = dev->isp_sdev.dbg.interval +
 					dev->isp_sdev.dbg.timestamp;
 
-			dev->isp_sdev.dbg.timestamp = ktime_get_ns();
+			dev->isp_sdev.dbg.timestamp = rkisp_time_get_ns(dev);
 			/* v-blank: frame(N)start - frame(N-1)end */
 			dev->isp_sdev.dbg.delay = dev->isp_sdev.dbg.timestamp - tmp;
 		}
@@ -4330,7 +4330,7 @@
 
 	/* cur frame end and next frame start irq togeter */
 	if (dev->vs_irq < 0 && sof_event_later) {
-		dev->isp_sdev.frm_timestamp = ktime_get_ns();
+		dev->isp_sdev.frm_timestamp = rkisp_time_get_ns(dev);
 		rkisp_isp_queue_event_sof(&dev->isp_sdev);
 		rkisp_stream_frame_start(dev, isp_mis);
 	}
diff --git a/kernel/drivers/media/platform/rockchip/isp/rkisp.h b/kernel/drivers/media/platform/rockchip/isp/rkisp.h
index 54f32b9..76f8ce0 100644
--- a/kernel/drivers/media/platform/rockchip/isp/rkisp.h
+++ b/kernel/drivers/media/platform/rockchip/isp/rkisp.h
@@ -153,6 +153,8 @@
 static inline void rkisp_chk_tb_over(struct rkisp_device *isp_dev) {}
 #endif
 
+void rkisp_save_tb_info(struct rkisp_device *isp_dev);
+
 void rkisp_mipi_isr(unsigned int mipi_mis, struct rkisp_device *dev);
 
 void rkisp_mipi_v13_isr(unsigned int err1, unsigned int err2,
diff --git a/kernel/drivers/media/platform/rockchip/isp/version.h b/kernel/drivers/media/platform/rockchip/isp/version.h
index c4c7254..8981e47 100644
--- a/kernel/drivers/media/platform/rockchip/isp/version.h
+++ b/kernel/drivers/media/platform/rockchip/isp/version.h
@@ -459,6 +459,30 @@
  * 11.fix image effect for frame two-run
  * 12.fix underperformance for frame two-run
  * 13.support unite mode for isp32
+ *
+ * v2.4.0 (AIQ v5.4.0)
+ * 1.fix rv1106g3 4k cmsk right
+ * 2.fix image effect for rv1106 4k
+ * 3.add RKISP_VICAP_CMD_QUICK_STREAM CMD
+ * 4.support suspend and resume
+ * 5.pm add call sensor s_power
+ * 6.suspend resume with rtt
+ * 7.fix resume hold by lut error
+ * 8.fix rv1106g3 4k can't cmsk rightmost
+ * 9.fix rv1106 resume no output
+ * 10.support to do reset in online mode
+ * 11.support change work mode to online with quick stream
+ * 12.fix build warning
+ * 13.frame timestamp change to sof
+ * 14.fix wnd_num cause array access out of bounds
+ * 15.fix rv1106 cycle kill rkipc null pointer
+ * 16.fix power_cnt if error
+ * 17.fix rockit set_fmt stuck
+ * 18.fix info2ddr no enable
+ * 19.fix reset can't open
+ * 20.more time to wait isp end
+ * 21.add mode for rv1106 suspend without rtt
+ * 22.fix is_on false cause pm isp die
  */
 
 #define RKISP_DRIVER_VERSION RKISP_API_VERSION
diff --git a/kernel/drivers/media/platform/rockchip/isp1/dev.c b/kernel/drivers/media/platform/rockchip/isp1/dev.c
index cc97366..653ce1b 100644
--- a/kernel/drivers/media/platform/rockchip/isp1/dev.c
+++ b/kernel/drivers/media/platform/rockchip/isp1/dev.c
@@ -45,7 +45,6 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/regmap.h>
 #include <media/videobuf2-dma-contig.h>
-#include <dt-bindings/soc/rockchip-system-status.h>
 #include <soc/rockchip/rockchip-system-status.h>
 #include "regs.h"
 #include "rkisp1.h"
diff --git a/kernel/drivers/media/platform/s5p-mfc/s5p_mfc.c b/kernel/drivers/media/platform/s5p-mfc/s5p_mfc.c
index f336a95..6cbec3b 100644
--- a/kernel/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/kernel/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1584,8 +1584,18 @@
 	.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 = {
@@ -1656,6 +1666,9 @@
 		.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,
 	}, {
diff --git a/kernel/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/kernel/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
index da138c3..58822ec 100644
--- a/kernel/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
+++ b/kernel/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
@@ -468,8 +468,10 @@
 	s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
 	/* Wait until instance is returned or timeout occurred */
 	if (s5p_mfc_wait_for_done_ctx(ctx,
-				S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0))
+				S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)){
+		clear_work_bit_irqsave(ctx);
 		mfc_err("Err returning instance\n");
+	}
 
 	/* Free resources */
 	s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx);
diff --git a/kernel/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/kernel/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
index acc2217..62a1ad3 100644
--- a/kernel/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+++ b/kernel/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
@@ -1218,6 +1218,7 @@
 	unsigned long mb_y_addr, mb_c_addr;
 	int slice_type;
 	unsigned int strm_size;
+	bool src_ready;
 
 	slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev);
 	strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev);
@@ -1257,7 +1258,8 @@
 			}
 		}
 	}
-	if ((ctx->src_queue_cnt > 0) && (ctx->state == MFCINST_RUNNING)) {
+	if (ctx->src_queue_cnt > 0 && (ctx->state == MFCINST_RUNNING ||
+				       ctx->state == MFCINST_FINISHING)) {
 		mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
 									list);
 		if (mb_entry->flags & MFC_BUF_FLAG_USED) {
@@ -1288,7 +1290,13 @@
 		vb2_set_plane_payload(&mb_entry->b->vb2_buf, 0, strm_size);
 		vb2_buffer_done(&mb_entry->b->vb2_buf, VB2_BUF_STATE_DONE);
 	}
-	if ((ctx->src_queue_cnt == 0) || (ctx->dst_queue_cnt == 0))
+
+	src_ready = true;
+	if (ctx->state == MFCINST_RUNNING && ctx->src_queue_cnt == 0)
+		src_ready = false;
+	if (ctx->state == MFCINST_FINISHING && ctx->ref_queue_cnt == 0)
+		src_ready = false;
+	if (!src_ready || ctx->dst_queue_cnt == 0)
 		clear_work_bit(ctx);
 
 	return 0;
diff --git a/kernel/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/kernel/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
index a145305..ef8169f 100644
--- a/kernel/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/kernel/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
@@ -1060,7 +1060,7 @@
 	}
 
 	/* aspect ratio VUI */
-	readl(mfc_regs->e_h264_options);
+	reg = readl(mfc_regs->e_h264_options);
 	reg &= ~(0x1 << 5);
 	reg |= ((p_h264->vui_sar & 0x1) << 5);
 	writel(reg, mfc_regs->e_h264_options);
@@ -1083,7 +1083,7 @@
 
 	/* intra picture period for H.264 open GOP */
 	/* control */
-	readl(mfc_regs->e_h264_options);
+	reg = readl(mfc_regs->e_h264_options);
 	reg &= ~(0x1 << 4);
 	reg |= ((p_h264->open_gop & 0x1) << 4);
 	writel(reg, mfc_regs->e_h264_options);
@@ -1097,23 +1097,23 @@
 	}
 
 	/* 'WEIGHTED_BI_PREDICTION' for B is disable */
-	readl(mfc_regs->e_h264_options);
+	reg = readl(mfc_regs->e_h264_options);
 	reg &= ~(0x3 << 9);
 	writel(reg, mfc_regs->e_h264_options);
 
 	/* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */
-	readl(mfc_regs->e_h264_options);
+	reg = readl(mfc_regs->e_h264_options);
 	reg &= ~(0x1 << 14);
 	writel(reg, mfc_regs->e_h264_options);
 
 	/* ASO */
-	readl(mfc_regs->e_h264_options);
+	reg = readl(mfc_regs->e_h264_options);
 	reg &= ~(0x1 << 6);
 	reg |= ((p_h264->aso & 0x1) << 6);
 	writel(reg, mfc_regs->e_h264_options);
 
 	/* hier qp enable */
-	readl(mfc_regs->e_h264_options);
+	reg = readl(mfc_regs->e_h264_options);
 	reg &= ~(0x1 << 8);
 	reg |= ((p_h264->open_gop & 0x1) << 8);
 	writel(reg, mfc_regs->e_h264_options);
@@ -1134,7 +1134,7 @@
 	writel(reg, mfc_regs->e_h264_num_t_layer);
 
 	/* frame packing SEI generation */
-	readl(mfc_regs->e_h264_options);
+	reg = readl(mfc_regs->e_h264_options);
 	reg &= ~(0x1 << 25);
 	reg |= ((p_h264->sei_frame_packing & 0x1) << 25);
 	writel(reg, mfc_regs->e_h264_options);
diff --git a/kernel/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/kernel/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
index 85288da..182e5a4 100644
--- a/kernel/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
+++ b/kernel/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
@@ -1310,6 +1310,8 @@
 	init_waitqueue_head(&bdisp->irq_queue);
 	INIT_DELAYED_WORK(&bdisp->timeout_work, bdisp_irq_timeout);
 	bdisp->work_queue = create_workqueue(BDISP_NAME);
+	if (!bdisp->work_queue)
+		return -ENOMEM;
 
 	spin_lock_init(&bdisp->slock);
 	mutex_init(&bdisp->lock);
diff --git a/kernel/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/kernel/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
index dbe7788..b7e0ec2 100644
--- a/kernel/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+++ b/kernel/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
@@ -937,6 +937,7 @@
 		if (ret) {
 			dev_err(fei->dev,
 				"configure_memdma_and_inputblock failed\n");
+			of_node_put(child);
 			goto err_unmap;
 		}
 		index++;
diff --git a/kernel/drivers/media/platform/ti-vpe/cal.h b/kernel/drivers/media/platform/ti-vpe/cal.h
index 4123405..20d0731 100644
--- a/kernel/drivers/media/platform/ti-vpe/cal.h
+++ b/kernel/drivers/media/platform/ti-vpe/cal.h
@@ -215,7 +215,7 @@
 	iowrite32(val, cal->base + offset);
 }
 
-static inline u32 cal_read_field(struct cal_dev *cal, u32 offset, u32 mask)
+static __always_inline u32 cal_read_field(struct cal_dev *cal, u32 offset, u32 mask)
 {
 	return FIELD_GET(mask, cal_read(cal, offset));
 }
diff --git a/kernel/drivers/media/radio/radio-shark.c b/kernel/drivers/media/radio/radio-shark.c
index 8230da8..127a3be 100644
--- a/kernel/drivers/media/radio/radio-shark.c
+++ b/kernel/drivers/media/radio/radio-shark.c
@@ -316,6 +316,16 @@
 {
 	struct shark_device *shark;
 	int retval = -ENOMEM;
+	static const u8 ep_addresses[] = {
+		SHARK_IN_EP | USB_DIR_IN,
+		SHARK_OUT_EP | USB_DIR_OUT,
+		0};
+
+	/* Are the expected endpoints present? */
+	if (!usb_check_int_endpoints(intf, ep_addresses)) {
+		dev_err(&intf->dev, "Invalid radioSHARK device\n");
+		return -EINVAL;
+	}
 
 	shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL);
 	if (!shark)
diff --git a/kernel/drivers/media/radio/radio-shark2.c b/kernel/drivers/media/radio/radio-shark2.c
index d150f12..f1c5c0a 100644
--- a/kernel/drivers/media/radio/radio-shark2.c
+++ b/kernel/drivers/media/radio/radio-shark2.c
@@ -282,6 +282,16 @@
 {
 	struct shark_device *shark;
 	int retval = -ENOMEM;
+	static const u8 ep_addresses[] = {
+		SHARK_IN_EP | USB_DIR_IN,
+		SHARK_OUT_EP | USB_DIR_OUT,
+		0};
+
+	/* Are the expected endpoints present? */
+	if (!usb_check_int_endpoints(intf, ep_addresses)) {
+		dev_err(&intf->dev, "Invalid radioSHARK2 device\n");
+		return -EINVAL;
+	}
 
 	shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL);
 	if (!shark)
diff --git a/kernel/drivers/media/radio/si470x/radio-si470x-usb.c b/kernel/drivers/media/radio/si470x/radio-si470x-usb.c
index 3f8634a..1365ae7 100644
--- a/kernel/drivers/media/radio/si470x/radio-si470x-usb.c
+++ b/kernel/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -733,8 +733,10 @@
 
 	/* 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 */
diff --git a/kernel/drivers/media/rc/ene_ir.c b/kernel/drivers/media/rc/ene_ir.c
index 6049e5c..5aa3953 100644
--- a/kernel/drivers/media/rc/ene_ir.c
+++ b/kernel/drivers/media/rc/ene_ir.c
@@ -1106,6 +1106,8 @@
 	struct ene_device *dev = pnp_get_drvdata(pnp_dev);
 	unsigned long flags;
 
+	rc_unregister_device(dev->rdev);
+	del_timer_sync(&dev->tx_sim_timer);
 	spin_lock_irqsave(&dev->hw_lock, flags);
 	ene_rx_disable(dev);
 	ene_rx_restore_hw_buffer(dev);
@@ -1113,7 +1115,6 @@
 
 	free_irq(dev->irq, dev);
 	release_region(dev->hw_io, ENE_IO_SIZE);
-	rc_unregister_device(dev->rdev);
 	kfree(dev);
 }
 
diff --git a/kernel/drivers/media/rc/gpio-ir-recv.c b/kernel/drivers/media/rc/gpio-ir-recv.c
index 22e524b..16795e0 100644
--- a/kernel/drivers/media/rc/gpio-ir-recv.c
+++ b/kernel/drivers/media/rc/gpio-ir-recv.c
@@ -107,6 +107,8 @@
 		rcdev->map_name = RC_MAP_EMPTY;
 
 	gpio_dev->rcdev = rcdev;
+	if (of_property_read_bool(np, "wakeup-source"))
+		device_init_wakeup(dev, true);
 
 	rc = devm_rc_register_device(dev, rcdev);
 	if (rc < 0) {
@@ -128,6 +130,23 @@
 	return devm_request_irq(dev, gpio_dev->irq, gpio_ir_recv_irq,
 				IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
 				"gpio-ir-recv-irq", gpio_dev);
+}
+
+static int gpio_ir_recv_remove(struct platform_device *pdev)
+{
+	struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
+	struct device *pmdev = gpio_dev->pmdev;
+
+	if (pmdev) {
+		pm_runtime_get_sync(pmdev);
+		cpu_latency_qos_remove_request(&gpio_dev->qos);
+
+		pm_runtime_disable(pmdev);
+		pm_runtime_put_noidle(pmdev);
+		pm_runtime_set_suspended(pmdev);
+	}
+
+	return 0;
 }
 
 #ifdef CONFIG_PM
@@ -189,6 +208,7 @@
 
 static struct platform_driver gpio_ir_recv_driver = {
 	.probe  = gpio_ir_recv_probe,
+	.remove = gpio_ir_recv_remove,
 	.driver = {
 		.name   = KBUILD_MODNAME,
 		.of_match_table = of_match_ptr(gpio_ir_recv_of_match),
diff --git a/kernel/drivers/media/rc/imon.c b/kernel/drivers/media/rc/imon.c
index bc9ac60..98a3875 100644
--- a/kernel/drivers/media/rc/imon.c
+++ b/kernel/drivers/media/rc/imon.c
@@ -646,15 +646,14 @@
 		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 @@
 	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");
diff --git a/kernel/drivers/media/test-drivers/vidtv/vidtv_bridge.c b/kernel/drivers/media/test-drivers/vidtv/vidtv_bridge.c
index fc64d0c..3c28126 100644
--- a/kernel/drivers/media/test-drivers/vidtv/vidtv_bridge.c
+++ b/kernel/drivers/media/test-drivers/vidtv/vidtv_bridge.c
@@ -456,26 +456,20 @@
 	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_fe:
-	for (j = i; j >= 0; --j)
-		dvb_unregister_frontend(dvb->fe[j]);
-fail_tuner_probe:
-	for (j = i; j >= 0; --j)
-		if (dvb->i2c_client_tuner[j])
-			dvb_module_release(dvb->i2c_client_tuner[j]);
-
+fail_dmx:
 fail_demod_probe:
-	for (j = i; j >= 0; --j)
-		if (dvb->i2c_client_demod[j])
-			dvb_module_release(dvb->i2c_client_demod[j]);
-
+	for (i = i - 1; i >= 0; --i) {
+		dvb_unregister_frontend(dvb->fe[i]);
+fail_fe:
+		dvb_module_release(dvb->i2c_client_tuner[i]);
+fail_tuner_probe:
+		dvb_module_release(dvb->i2c_client_demod[i]);
+	}
 fail_adapter:
 	dvb_unregister_adapter(&dvb->adapter);
-
 fail_i2c:
 	i2c_del_adapter(&dvb->i2c_adapter);
 
diff --git a/kernel/drivers/media/test-drivers/vimc/vimc-core.c b/kernel/drivers/media/test-drivers/vimc/vimc-core.c
index 4b0ae6f..857529c 100644
--- a/kernel/drivers/media/test-drivers/vimc/vimc-core.c
+++ b/kernel/drivers/media/test-drivers/vimc/vimc-core.c
@@ -357,7 +357,7 @@
 	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;
 	}
 
diff --git a/kernel/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/kernel/drivers/media/test-drivers/vivid/vivid-vid-cap.c
index d493bd1..437889e 100644
--- a/kernel/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+++ b/kernel/drivers/media/test-drivers/vivid/vivid-vid-cap.c
@@ -961,6 +961,7 @@
 			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);
diff --git a/kernel/drivers/media/tuners/fc0011.c b/kernel/drivers/media/tuners/fc0011.c
index eaa3bbc..3d3b54b 100644
--- a/kernel/drivers/media/tuners/fc0011.c
+++ b/kernel/drivers/media/tuners/fc0011.c
@@ -499,7 +499,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(fc0011_attach);
+EXPORT_SYMBOL_GPL(fc0011_attach);
 
 MODULE_DESCRIPTION("Fitipower FC0011 silicon tuner driver");
 MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
diff --git a/kernel/drivers/media/tuners/fc0012.c b/kernel/drivers/media/tuners/fc0012.c
index 4429d5e..81e65ac 100644
--- a/kernel/drivers/media/tuners/fc0012.c
+++ b/kernel/drivers/media/tuners/fc0012.c
@@ -495,7 +495,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(fc0012_attach);
+EXPORT_SYMBOL_GPL(fc0012_attach);
 
 MODULE_DESCRIPTION("Fitipower FC0012 silicon tuner driver");
 MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
diff --git a/kernel/drivers/media/tuners/fc0013.c b/kernel/drivers/media/tuners/fc0013.c
index 29dd9b5..1006a27 100644
--- a/kernel/drivers/media/tuners/fc0013.c
+++ b/kernel/drivers/media/tuners/fc0013.c
@@ -608,7 +608,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(fc0013_attach);
+EXPORT_SYMBOL_GPL(fc0013_attach);
 
 MODULE_DESCRIPTION("Fitipower FC0013 silicon tuner driver");
 MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
diff --git a/kernel/drivers/media/tuners/max2165.c b/kernel/drivers/media/tuners/max2165.c
index 1c746be..1575ab9 100644
--- a/kernel/drivers/media/tuners/max2165.c
+++ b/kernel/drivers/media/tuners/max2165.c
@@ -410,7 +410,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(max2165_attach);
+EXPORT_SYMBOL_GPL(max2165_attach);
 
 MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
 MODULE_DESCRIPTION("Maxim MAX2165 silicon tuner driver");
diff --git a/kernel/drivers/media/tuners/mc44s803.c b/kernel/drivers/media/tuners/mc44s803.c
index 0c91615..ed8bdf7 100644
--- a/kernel/drivers/media/tuners/mc44s803.c
+++ b/kernel/drivers/media/tuners/mc44s803.c
@@ -356,7 +356,7 @@
 	kfree(priv);
 	return NULL;
 }
-EXPORT_SYMBOL(mc44s803_attach);
+EXPORT_SYMBOL_GPL(mc44s803_attach);
 
 MODULE_AUTHOR("Jochen Friedrich");
 MODULE_DESCRIPTION("Freescale MC44S803 silicon tuner driver");
diff --git a/kernel/drivers/media/tuners/mt2060.c b/kernel/drivers/media/tuners/mt2060.c
index 0e7ac2b..b59c5ba 100644
--- a/kernel/drivers/media/tuners/mt2060.c
+++ b/kernel/drivers/media/tuners/mt2060.c
@@ -440,7 +440,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(mt2060_attach);
+EXPORT_SYMBOL_GPL(mt2060_attach);
 
 static int mt2060_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
diff --git a/kernel/drivers/media/tuners/mt2131.c b/kernel/drivers/media/tuners/mt2131.c
index 37f50ff..eebc060 100644
--- a/kernel/drivers/media/tuners/mt2131.c
+++ b/kernel/drivers/media/tuners/mt2131.c
@@ -274,7 +274,7 @@
 	fe->tuner_priv = priv;
 	return fe;
 }
-EXPORT_SYMBOL(mt2131_attach);
+EXPORT_SYMBOL_GPL(mt2131_attach);
 
 MODULE_AUTHOR("Steven Toth");
 MODULE_DESCRIPTION("Microtune MT2131 silicon tuner driver");
diff --git a/kernel/drivers/media/tuners/mt2266.c b/kernel/drivers/media/tuners/mt2266.c
index 6136f20..2e92885 100644
--- a/kernel/drivers/media/tuners/mt2266.c
+++ b/kernel/drivers/media/tuners/mt2266.c
@@ -336,7 +336,7 @@
 	mt2266_calibrate(priv);
 	return fe;
 }
-EXPORT_SYMBOL(mt2266_attach);
+EXPORT_SYMBOL_GPL(mt2266_attach);
 
 MODULE_AUTHOR("Olivier DANET");
 MODULE_DESCRIPTION("Microtune MT2266 silicon tuner driver");
diff --git a/kernel/drivers/media/tuners/mxl5005s.c b/kernel/drivers/media/tuners/mxl5005s.c
index 1c07e22..cae6ded 100644
--- a/kernel/drivers/media/tuners/mxl5005s.c
+++ b/kernel/drivers/media/tuners/mxl5005s.c
@@ -4114,7 +4114,7 @@
 	fe->tuner_priv = state;
 	return fe;
 }
-EXPORT_SYMBOL(mxl5005s_attach);
+EXPORT_SYMBOL_GPL(mxl5005s_attach);
 
 MODULE_DESCRIPTION("MaxLinear MXL5005S silicon tuner driver");
 MODULE_AUTHOR("Steven Toth");
diff --git a/kernel/drivers/media/tuners/qt1010.c b/kernel/drivers/media/tuners/qt1010.c
index 3853a3d..48fc79c 100644
--- a/kernel/drivers/media/tuners/qt1010.c
+++ b/kernel/drivers/media/tuners/qt1010.c
@@ -345,11 +345,12 @@
 			else
 				valptr = &tmpval;
 
-			BUG_ON(i >= ARRAY_SIZE(i2c_data) - 1);
-
-			err = qt1010_init_meas1(priv, i2c_data[i+1].reg,
-						i2c_data[i].reg,
-						i2c_data[i].val, valptr);
+			if (i >= ARRAY_SIZE(i2c_data) - 1)
+				err = -EIO;
+			else
+				err = qt1010_init_meas1(priv, i2c_data[i + 1].reg,
+							i2c_data[i].reg,
+							i2c_data[i].val, valptr);
 			i++;
 			break;
 		}
@@ -440,7 +441,7 @@
 	fe->tuner_priv = priv;
 	return fe;
 }
-EXPORT_SYMBOL(qt1010_attach);
+EXPORT_SYMBOL_GPL(qt1010_attach);
 
 MODULE_DESCRIPTION("Quantek QT1010 silicon tuner driver");
 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
diff --git a/kernel/drivers/media/tuners/tda18218.c b/kernel/drivers/media/tuners/tda18218.c
index 4ed9464..7d8d84d 100644
--- a/kernel/drivers/media/tuners/tda18218.c
+++ b/kernel/drivers/media/tuners/tda18218.c
@@ -336,7 +336,7 @@
 
 	return fe;
 }
-EXPORT_SYMBOL(tda18218_attach);
+EXPORT_SYMBOL_GPL(tda18218_attach);
 
 MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver");
 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
diff --git a/kernel/drivers/media/tuners/xc4000.c b/kernel/drivers/media/tuners/xc4000.c
index d960673..ef9af05 100644
--- a/kernel/drivers/media/tuners/xc4000.c
+++ b/kernel/drivers/media/tuners/xc4000.c
@@ -1744,7 +1744,7 @@
 	xc4000_release(fe);
 	return NULL;
 }
-EXPORT_SYMBOL(xc4000_attach);
+EXPORT_SYMBOL_GPL(xc4000_attach);
 
 MODULE_AUTHOR("Steven Toth, Davide Ferri");
 MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver");
diff --git a/kernel/drivers/media/tuners/xc5000.c b/kernel/drivers/media/tuners/xc5000.c
index 7b7d9fe..2182e5b 100644
--- a/kernel/drivers/media/tuners/xc5000.c
+++ b/kernel/drivers/media/tuners/xc5000.c
@@ -1460,7 +1460,7 @@
 	xc5000_release(fe);
 	return NULL;
 }
-EXPORT_SYMBOL(xc5000_attach);
+EXPORT_SYMBOL_GPL(xc5000_attach);
 
 MODULE_AUTHOR("Steven Toth");
 MODULE_DESCRIPTION("Xceive xc5000 silicon tuner driver");
diff --git a/kernel/drivers/media/usb/dvb-usb-v2/af9035.c b/kernel/drivers/media/usb/dvb-usb-v2/af9035.c
index b1f69c1..8cbaab9 100644
--- a/kernel/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/kernel/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -269,6 +269,7 @@
 	struct dvb_usb_device *d = i2c_get_adapdata(adap);
 	struct state *state = d_to_priv(d);
 	int ret;
+	u32 reg;
 
 	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 		return -EAGAIN;
@@ -321,8 +322,10 @@
 			ret = -EOPNOTSUPP;
 		} else if ((msg[0].addr == state->af9033_i2c_addr[0]) ||
 			   (msg[0].addr == state->af9033_i2c_addr[1])) {
+			if (msg[0].len < 3 || msg[1].len < 1)
+				return -EOPNOTSUPP;
 			/* demod access via firmware interface */
-			u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
+			reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
 					msg[0].buf[2];
 
 			if (msg[0].addr == state->af9033_i2c_addr[1])
@@ -380,17 +383,16 @@
 			ret = -EOPNOTSUPP;
 		} else if ((msg[0].addr == state->af9033_i2c_addr[0]) ||
 			   (msg[0].addr == state->af9033_i2c_addr[1])) {
+			if (msg[0].len < 3)
+				return -EOPNOTSUPP;
 			/* demod access via firmware interface */
-			u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
+			reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
 					msg[0].buf[2];
 
 			if (msg[0].addr == state->af9033_i2c_addr[1])
 				reg |= 0x100000;
 
-			ret = (msg[0].len >= 3) ? af9035_wr_regs(d, reg,
-							         &msg[0].buf[3],
-							         msg[0].len - 3)
-					        : -EOPNOTSUPP;
+			ret = af9035_wr_regs(d, reg, &msg[0].buf[3], msg[0].len - 3);
 		} else {
 			/* I2C write */
 			u8 buf[MAX_XFER_SIZE];
diff --git a/kernel/drivers/media/usb/dvb-usb-v2/anysee.c b/kernel/drivers/media/usb/dvb-usb-v2/anysee.c
index 89a1b20..3dacf39 100644
--- a/kernel/drivers/media/usb/dvb-usb-v2/anysee.c
+++ b/kernel/drivers/media/usb/dvb-usb-v2/anysee.c
@@ -202,7 +202,7 @@
 
 	while (i < num) {
 		if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
-			if (msg[i].len > 2 || msg[i+1].len > 60) {
+			if (msg[i].len != 2 || msg[i + 1].len > 60) {
 				ret = -EOPNOTSUPP;
 				break;
 			}
diff --git a/kernel/drivers/media/usb/dvb-usb-v2/az6007.c b/kernel/drivers/media/usb/dvb-usb-v2/az6007.c
index 62ee09f..6cbfe75 100644
--- a/kernel/drivers/media/usb/dvb-usb-v2/az6007.c
+++ b/kernel/drivers/media/usb/dvb-usb-v2/az6007.c
@@ -202,7 +202,8 @@
 	unsigned code;
 	enum rc_proto proto;
 
-	az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10);
+	if (az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10) < 0)
+		return -EIO;
 
 	if (st->data[1] == 0x44)
 		return 0;
@@ -787,6 +788,10 @@
 			if (az6007_xfer_debug)
 				printk(KERN_DEBUG "az6007: I2C W addr=0x%x len=%d\n",
 				       addr, msgs[i].len);
+			if (msgs[i].len < 1) {
+				ret = -EIO;
+				goto err;
+			}
 			req = AZ6007_I2C_WR;
 			index = msgs[i].buf[0];
 			value = addr | (1 << 8);
@@ -801,6 +806,10 @@
 			if (az6007_xfer_debug)
 				printk(KERN_DEBUG "az6007: I2C R addr=0x%x len=%d\n",
 				       addr, msgs[i].len);
+			if (msgs[i].len < 1) {
+				ret = -EIO;
+				goto err;
+			}
 			req = AZ6007_I2C_RD;
 			index = msgs[i].buf[0];
 			value = addr;
diff --git a/kernel/drivers/media/usb/dvb-usb-v2/ce6230.c b/kernel/drivers/media/usb/dvb-usb-v2/ce6230.c
index 44540de..d3b5cb4 100644
--- a/kernel/drivers/media/usb/dvb-usb-v2/ce6230.c
+++ b/kernel/drivers/media/usb/dvb-usb-v2/ce6230.c
@@ -101,6 +101,10 @@
 		if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
 			if (msg[i].addr ==
 				ce6230_zl10353_config.demod_address) {
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				req.cmd = DEMOD_READ;
 				req.value = msg[i].addr >> 1;
 				req.index = msg[i].buf[0];
@@ -117,6 +121,10 @@
 		} else {
 			if (msg[i].addr ==
 				ce6230_zl10353_config.demod_address) {
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				req.cmd = DEMOD_WRITE;
 				req.value = msg[i].addr >> 1;
 				req.index = msg[i].buf[0];
diff --git a/kernel/drivers/media/usb/dvb-usb-v2/ec168.c b/kernel/drivers/media/usb/dvb-usb-v2/ec168.c
index 7ed0ab9..0e4773f 100644
--- a/kernel/drivers/media/usb/dvb-usb-v2/ec168.c
+++ b/kernel/drivers/media/usb/dvb-usb-v2/ec168.c
@@ -115,6 +115,10 @@
 	while (i < num) {
 		if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
 			if (msg[i].addr == ec168_ec100_config.demod_address) {
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				req.cmd = READ_DEMOD;
 				req.value = 0;
 				req.index = 0xff00 + msg[i].buf[0]; /* reg */
@@ -131,6 +135,10 @@
 			}
 		} else {
 			if (msg[i].addr == ec168_ec100_config.demod_address) {
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				req.cmd = WRITE_DEMOD;
 				req.value = msg[i].buf[1]; /* val */
 				req.index = 0xff00 + msg[i].buf[0]; /* reg */
@@ -139,6 +147,10 @@
 				ret = ec168_ctrl_msg(d, &req);
 				i += 1;
 			} else {
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				req.cmd = WRITE_I2C;
 				req.value = msg[i].buf[0]; /* val */
 				req.index = 0x0100 + msg[i].addr; /* I2C addr */
diff --git a/kernel/drivers/media/usb/dvb-usb-v2/gl861.c b/kernel/drivers/media/usb/dvb-usb-v2/gl861.c
index 0c43425..c71e7b9 100644
--- a/kernel/drivers/media/usb/dvb-usb-v2/gl861.c
+++ b/kernel/drivers/media/usb/dvb-usb-v2/gl861.c
@@ -120,7 +120,7 @@
 	} else if (num == 2 && !(msg[0].flags & I2C_M_RD) &&
 		   (msg[1].flags & I2C_M_RD)) {
 		/* I2C write + read */
-		if (msg[0].len > 1 || msg[1].len > sizeof(ctx->buf)) {
+		if (msg[0].len != 1 || msg[1].len > sizeof(ctx->buf)) {
 			ret = -EOPNOTSUPP;
 			goto err;
 		}
diff --git a/kernel/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/kernel/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index c278b9b..70a2f04 100644
--- a/kernel/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/kernel/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -176,6 +176,10 @@
 			ret = -EOPNOTSUPP;
 			goto err_mutex_unlock;
 		} else if (msg[0].addr == 0x10) {
+			if (msg[0].len < 1 || msg[1].len < 1) {
+				ret = -EOPNOTSUPP;
+				goto err_mutex_unlock;
+			}
 			/* method 1 - integrated demod */
 			if (msg[0].buf[0] == 0x00) {
 				/* return demod page from driver cache */
@@ -189,6 +193,10 @@
 				ret = rtl28xxu_ctrl_msg(d, &req);
 			}
 		} else if (msg[0].len < 2) {
+			if (msg[0].len < 1) {
+				ret = -EOPNOTSUPP;
+				goto err_mutex_unlock;
+			}
 			/* method 2 - old I2C */
 			req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
 			req.index = CMD_I2C_RD;
@@ -217,8 +225,16 @@
 			ret = -EOPNOTSUPP;
 			goto err_mutex_unlock;
 		} else if (msg[0].addr == 0x10) {
+			if (msg[0].len < 1) {
+				ret = -EOPNOTSUPP;
+				goto err_mutex_unlock;
+			}
 			/* method 1 - integrated demod */
 			if (msg[0].buf[0] == 0x00) {
+				if (msg[0].len < 2) {
+					ret = -EOPNOTSUPP;
+					goto err_mutex_unlock;
+				}
 				/* save demod page for later demod access */
 				dev->page = msg[0].buf[1];
 				ret = 0;
@@ -231,6 +247,10 @@
 				ret = rtl28xxu_ctrl_msg(d, &req);
 			}
 		} else if ((msg[0].len < 23) && (!dev->new_i2c_write)) {
+			if (msg[0].len < 1) {
+				ret = -EOPNOTSUPP;
+				goto err_mutex_unlock;
+			}
 			/* method 2 - old I2C */
 			req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
 			req.index = CMD_I2C_WR;
diff --git a/kernel/drivers/media/usb/dvb-usb/af9005.c b/kernel/drivers/media/usb/dvb-usb/af9005.c
index b6a2436..9af54fc 100644
--- a/kernel/drivers/media/usb/dvb-usb/af9005.c
+++ b/kernel/drivers/media/usb/dvb-usb/af9005.c
@@ -422,6 +422,10 @@
 		if (ret == 0)
 			ret = 2;
 	} else {
+		if (msg[0].len < 2) {
+			ret = -EOPNOTSUPP;
+			goto unlock;
+		}
 		/* write one or more registers */
 		reg = msg[0].buf[0];
 		addr = msg[0].addr;
@@ -431,6 +435,7 @@
 			ret = 1;
 	}
 
+unlock:
 	mutex_unlock(&d->i2c_mutex);
 	return ret;
 }
diff --git a/kernel/drivers/media/usb/dvb-usb/az6027.c b/kernel/drivers/media/usb/dvb-usb/az6027.c
index 8678877..991f451 100644
--- a/kernel/drivers/media/usb/dvb-usb/az6027.c
+++ b/kernel/drivers/media/usb/dvb-usb/az6027.c
@@ -975,6 +975,10 @@
 		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);
@@ -984,6 +988,10 @@
 			/* write/read request */
 			if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
 				req = 0xB9;
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
 				value = msg[i].addr + (msg[i].len << 8);
 				length = msg[i + 1].len + 6;
@@ -997,6 +1005,10 @@
 
 				/* demod 16bit addr */
 				req = 0xBD;
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
 				value = msg[i].addr + (2 << 8);
 				length = msg[i].len - 2;
@@ -1022,6 +1034,10 @@
 			} else {
 
 				req = 0xBD;
+				if (msg[i].len < 1) {
+					i = -EOPNOTSUPP;
+					break;
+				}
 				index = msg[i].buf[0] & 0x00FF;
 				value = msg[i].addr + (1 << 8);
 				length = msg[i].len - 1;
diff --git a/kernel/drivers/media/usb/dvb-usb/digitv.c b/kernel/drivers/media/usb/dvb-usb/digitv.c
index 4e3b3c0..e56efeb 100644
--- a/kernel/drivers/media/usb/dvb-usb/digitv.c
+++ b/kernel/drivers/media/usb/dvb-usb/digitv.c
@@ -63,6 +63,10 @@
 		warn("more than 2 i2c messages at a time is not handled yet. TODO.");
 
 	for (i = 0; i < num; i++) {
+		if (msg[i].len < 1) {
+			i = -EOPNOTSUPP;
+			break;
+		}
 		/* write/read request */
 		if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
 			if (digitv_ctrl_msg(d, USB_READ_COFDM, msg[i].buf[0], NULL, 0,
diff --git a/kernel/drivers/media/usb/dvb-usb/dvb-usb-init.c b/kernel/drivers/media/usb/dvb-usb/dvb-usb-init.c
index 61439c8..58eea8a 100644
--- a/kernel/drivers/media/usb/dvb-usb/dvb-usb-init.c
+++ b/kernel/drivers/media/usb/dvb-usb/dvb-usb-init.c
@@ -81,7 +81,7 @@
 
 		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 @@
 	dvb_usb_adapter_dvb_exit(adap);
 dvb_init_err:
 	dvb_usb_adapter_stream_exit(adap);
+stream_init_err:
+	kfree(adap->priv);
 	return ret;
 }
 
diff --git a/kernel/drivers/media/usb/dvb-usb/dw2102.c b/kernel/drivers/media/usb/dvb-usb/dw2102.c
index aa929db..2290f13 100644
--- a/kernel/drivers/media/usb/dvb-usb/dw2102.c
+++ b/kernel/drivers/media/usb/dvb-usb/dw2102.c
@@ -128,6 +128,10 @@
 
 	switch (num) {
 	case 2:
+		if (msg[0].len < 1) {
+			num = -EOPNOTSUPP;
+			break;
+		}
 		/* read stv0299 register */
 		value = msg[0].buf[0];/* register */
 		for (i = 0; i < msg[1].len; i++) {
@@ -139,6 +143,10 @@
 	case 1:
 		switch (msg[0].addr) {
 		case 0x68:
+			if (msg[0].len < 2) {
+				num = -EOPNOTSUPP;
+				break;
+			}
 			/* write to stv0299 register */
 			buf6[0] = 0x2a;
 			buf6[1] = msg[0].buf[0];
@@ -148,6 +156,10 @@
 			break;
 		case 0x60:
 			if (msg[0].flags == 0) {
+				if (msg[0].len < 4) {
+					num = -EOPNOTSUPP;
+					break;
+				}
 			/* write to tuner pll */
 				buf6[0] = 0x2c;
 				buf6[1] = 5;
@@ -159,6 +171,10 @@
 				dw210x_op_rw(d->udev, 0xb2, 0, 0,
 						buf6, 7, DW210X_WRITE_MSG);
 			} else {
+				if (msg[0].len < 1) {
+					num = -EOPNOTSUPP;
+					break;
+				}
 			/* read from tuner */
 				dw210x_op_rw(d->udev, 0xb5, 0, 0,
 						buf6, 1, DW210X_READ_MSG);
@@ -166,12 +182,20 @@
 			}
 			break;
 		case (DW2102_RC_QUERY):
+			if (msg[0].len < 2) {
+				num = -EOPNOTSUPP;
+				break;
+			}
 			dw210x_op_rw(d->udev, 0xb8, 0, 0,
 					buf6, 2, DW210X_READ_MSG);
 			msg[0].buf[0] = buf6[0];
 			msg[0].buf[1] = buf6[1];
 			break;
 		case (DW2102_VOLTAGE_CTRL):
+			if (msg[0].len < 1) {
+				num = -EOPNOTSUPP;
+				break;
+			}
 			buf6[0] = 0x30;
 			buf6[1] = msg[0].buf[0];
 			dw210x_op_rw(d->udev, 0xb2, 0, 0,
@@ -946,7 +970,7 @@
 	for (i = 0; i < 6; i++) {
 		obuf[1] = 0xf0 + i;
 		if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
-			break;
+			return -1;
 		else
 			mac[i] = ibuf[0];
 	}
diff --git a/kernel/drivers/media/usb/dvb-usb/m920x.c b/kernel/drivers/media/usb/dvb-usb/m920x.c
index 691e058..da81fa1 100644
--- a/kernel/drivers/media/usb/dvb-usb/m920x.c
+++ b/kernel/drivers/media/usb/dvb-usb/m920x.c
@@ -277,7 +277,6 @@
 			char *read = kmalloc(1, GFP_KERNEL);
 			if (!read) {
 				ret = -ENOMEM;
-				kfree(read);
 				goto unlock;
 			}
 
@@ -288,8 +287,10 @@
 
 				if ((ret = m920x_read(d->udev, M9206_I2C, 0x0,
 						      0x20 | stop,
-						      read, 1)) != 0)
+						      read, 1)) != 0) {
+					kfree(read);
 					goto unlock;
+				}
 				msg[i].buf[j] = read[0];
 			}
 
diff --git a/kernel/drivers/media/usb/go7007/go7007-i2c.c b/kernel/drivers/media/usb/go7007/go7007-i2c.c
index 38339dd..2880370 100644
--- a/kernel/drivers/media/usb/go7007/go7007-i2c.c
+++ b/kernel/drivers/media/usb/go7007/go7007-i2c.c
@@ -165,8 +165,6 @@
 		} else if (msgs[i].len == 3) {
 			if (msgs[i].flags & I2C_M_RD)
 				return -EIO;
-			if (msgs[i].len != 3)
-				return -EIO;
 			if (go7007_i2c_xfer(go, msgs[i].addr, 0,
 					(msgs[i].buf[0] << 8) | msgs[i].buf[1],
 					0x01, &msgs[i].buf[2]) < 0)
diff --git a/kernel/drivers/media/usb/siano/smsusb.c b/kernel/drivers/media/usb/siano/smsusb.c
index df4c5dc..6036ad3 100644
--- a/kernel/drivers/media/usb/siano/smsusb.c
+++ b/kernel/drivers/media/usb/siano/smsusb.c
@@ -179,6 +179,8 @@
 
 	for (i = 0; i < MAX_URBS; i++) {
 		usb_kill_urb(&dev->surbs[i].urb);
+		if (dev->surbs[i].wq.func)
+			cancel_work_sync(&dev->surbs[i].wq);
 
 		if (dev->surbs[i].cb) {
 			smscore_putbuffer(dev->coredev, dev->surbs[i].cb);
@@ -453,12 +455,7 @@
 	rc = smscore_register_device(&params, &dev->coredev, 0, mdev);
 	if (rc < 0) {
 		pr_err("smscore_register_device(...) failed, rc %d\n", rc);
-		smsusb_term_device(intf);
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-		media_device_unregister(mdev);
-#endif
-		kfree(mdev);
-		return rc;
+		goto err_unregister_device;
 	}
 
 	smscore_set_board_id(dev->coredev, board_id);
@@ -475,8 +472,7 @@
 	rc = smsusb_start_streaming(dev);
 	if (rc < 0) {
 		pr_err("smsusb_start_streaming(...) failed\n");
-		smsusb_term_device(intf);
-		return rc;
+		goto err_unregister_device;
 	}
 
 	dev->state = SMSUSB_ACTIVE;
@@ -484,13 +480,20 @@
 	rc = smscore_start_device(dev->coredev);
 	if (rc < 0) {
 		pr_err("smscore_start_device(...) failed\n");
-		smsusb_term_device(intf);
-		return rc;
+		goto err_unregister_device;
 	}
 
 	pr_debug("device 0x%p created\n", dev);
 
 	return rc;
+
+err_unregister_device:
+	smsusb_term_device(intf);
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	media_device_unregister(mdev);
+#endif
+	kfree(mdev);
+	return rc;
 }
 
 static int smsusb_probe(struct usb_interface *intf,
diff --git a/kernel/drivers/media/usb/ttusb-dec/ttusb_dec.c b/kernel/drivers/media/usb/ttusb-dec/ttusb_dec.c
index df6c5e4..68f8814 100644
--- a/kernel/drivers/media/usb/ttusb-dec/ttusb_dec.c
+++ b/kernel/drivers/media/usb/ttusb-dec/ttusb_dec.c
@@ -1551,8 +1551,7 @@
 	dvb_dmx_release(&dec->demux);
 	if (dec->fe) {
 		dvb_unregister_frontend(dec->fe);
-		if (dec->fe->ops.release)
-			dec->fe->ops.release(dec->fe);
+		dvb_frontend_detach(dec->fe);
 	}
 	dvb_unregister_adapter(&dec->adapter);
 }
diff --git a/kernel/drivers/media/usb/uvc/uvc_ctrl.c b/kernel/drivers/media/usb/uvc/uvc_ctrl.c
index f479d89..5e0acab 100644
--- a/kernel/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/kernel/drivers/media/usb/uvc/uvc_ctrl.c
@@ -6,6 +6,7 @@
  *          Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  */
 
+#include <asm/barrier.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/module.h>
@@ -1275,17 +1276,12 @@
 	uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes);
 }
 
-static void uvc_ctrl_status_event_work(struct work_struct *work)
+void uvc_ctrl_status_event(struct uvc_video_chain *chain,
+			   struct uvc_control *ctrl, const u8 *data)
 {
-	struct uvc_device *dev = container_of(work, struct uvc_device,
-					      async_ctrl.work);
-	struct uvc_ctrl_work *w = &dev->async_ctrl;
-	struct uvc_video_chain *chain = w->chain;
 	struct uvc_control_mapping *mapping;
-	struct uvc_control *ctrl = w->ctrl;
 	struct uvc_fh *handle;
 	unsigned int i;
-	int ret;
 
 	mutex_lock(&chain->ctrl_mutex);
 
@@ -1293,7 +1289,7 @@
 	ctrl->handle = NULL;
 
 	list_for_each_entry(mapping, &ctrl->info.mappings, list) {
-		s32 value = __uvc_ctrl_get_value(mapping, w->data);
+		s32 value = __uvc_ctrl_get_value(mapping, data);
 
 		/*
 		 * handle may be NULL here if the device sends auto-update
@@ -1312,6 +1308,20 @@
 	}
 
 	mutex_unlock(&chain->ctrl_mutex);
+}
+
+static void uvc_ctrl_status_event_work(struct work_struct *work)
+{
+	struct uvc_device *dev = container_of(work, struct uvc_device,
+					      async_ctrl.work);
+	struct uvc_ctrl_work *w = &dev->async_ctrl;
+	int ret;
+
+	uvc_ctrl_status_event(w->chain, w->ctrl, w->data);
+
+	/* The barrier is needed to synchronize with uvc_status_stop(). */
+	if (smp_load_acquire(&dev->flush_status))
+		return;
 
 	/* Resubmit the URB. */
 	w->urb->interval = dev->int_ep->desc.bInterval;
@@ -1321,8 +1331,8 @@
 			   ret);
 }
 
-bool uvc_ctrl_status_event(struct urb *urb, struct uvc_video_chain *chain,
-			   struct uvc_control *ctrl, const u8 *data)
+bool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain,
+				 struct uvc_control *ctrl, const u8 *data)
 {
 	struct uvc_device *dev = chain->dev;
 	struct uvc_ctrl_work *w = &dev->async_ctrl;
diff --git a/kernel/drivers/media/usb/uvc/uvc_driver.c b/kernel/drivers/media/usb/uvc/uvc_driver.c
index 34b1ca6..8b974fe 100644
--- a/kernel/drivers/media/usb/uvc/uvc_driver.c
+++ b/kernel/drivers/media/usb/uvc/uvc_driver.c
@@ -1127,10 +1127,8 @@
 					       + n;
 		memcpy(unit->extension.bmControls, &buffer[23+p], 2*n);
 
-		if (buffer[24+p+2*n] != 0)
-			usb_string(udev, buffer[24+p+2*n], unit->name,
-				   sizeof(unit->name));
-		else
+		if (buffer[24+p+2*n] == 0 ||
+		    usb_string(udev, buffer[24+p+2*n], unit->name, sizeof(unit->name)) < 0)
 			sprintf(unit->name, "Extension %u", buffer[3]);
 
 		list_add_tail(&unit->list, &dev->entities);
@@ -1255,15 +1253,15 @@
 			memcpy(term->media.bmTransportModes, &buffer[10+n], p);
 		}
 
-		if (buffer[7] != 0)
-			usb_string(udev, buffer[7], term->name,
-				   sizeof(term->name));
-		else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA)
-			sprintf(term->name, "Camera %u", buffer[3]);
-		else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT)
-			sprintf(term->name, "Media %u", buffer[3]);
-		else
-			sprintf(term->name, "Input %u", buffer[3]);
+		if (buffer[7] == 0 ||
+		    usb_string(udev, buffer[7], term->name, sizeof(term->name)) < 0) {
+			if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA)
+				sprintf(term->name, "Camera %u", buffer[3]);
+			if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT)
+				sprintf(term->name, "Media %u", buffer[3]);
+			else
+				sprintf(term->name, "Input %u", buffer[3]);
+		}
 
 		list_add_tail(&term->list, &dev->entities);
 		break;
@@ -1295,10 +1293,8 @@
 
 		memcpy(term->baSourceID, &buffer[7], 1);
 
-		if (buffer[8] != 0)
-			usb_string(udev, buffer[8], term->name,
-				   sizeof(term->name));
-		else
+		if (buffer[8] == 0 ||
+		    usb_string(udev, buffer[8], term->name, sizeof(term->name)) < 0)
 			sprintf(term->name, "Output %u", buffer[3]);
 
 		list_add_tail(&term->list, &dev->entities);
@@ -1320,10 +1316,8 @@
 
 		memcpy(unit->baSourceID, &buffer[5], p);
 
-		if (buffer[5+p] != 0)
-			usb_string(udev, buffer[5+p], unit->name,
-				   sizeof(unit->name));
-		else
+		if (buffer[5+p] == 0 ||
+		    usb_string(udev, buffer[5+p], unit->name, sizeof(unit->name)) < 0)
 			sprintf(unit->name, "Selector %u", buffer[3]);
 
 		list_add_tail(&unit->list, &dev->entities);
@@ -1353,10 +1347,8 @@
 		if (dev->uvc_version >= 0x0110)
 			unit->processing.bmVideoStandards = buffer[9+n];
 
-		if (buffer[8+n] != 0)
-			usb_string(udev, buffer[8+n], unit->name,
-				   sizeof(unit->name));
-		else
+		if (buffer[8+n] == 0 ||
+		    usb_string(udev, buffer[8+n], unit->name, sizeof(unit->name)) < 0)
 			sprintf(unit->name, "Processing %u", buffer[3]);
 
 		list_add_tail(&unit->list, &dev->entities);
@@ -1384,10 +1376,8 @@
 		unit->extension.bmControls = (u8 *)unit + sizeof(*unit);
 		memcpy(unit->extension.bmControls, &buffer[23+p], n);
 
-		if (buffer[23+p+n] != 0)
-			usb_string(udev, buffer[23+p+n], unit->name,
-				   sizeof(unit->name));
-		else
+		if (buffer[23+p+n] == 0 ||
+		    usb_string(udev, buffer[23+p+n], unit->name, sizeof(unit->name)) < 0)
 			sprintf(unit->name, "Extension %u", buffer[3]);
 
 		list_add_tail(&unit->list, &dev->entities);
@@ -2575,6 +2565,24 @@
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_minmax },
+	/* Logitech, Webcam C910 */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x046d,
+	  .idProduct		= 0x0821,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_INFO_QUIRK(UVC_QUIRK_WAKE_AUTOSUSPEND)},
+	/* Logitech, Webcam B910 */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x046d,
+	  .idProduct		= 0x0823,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_INFO_QUIRK(UVC_QUIRK_WAKE_AUTOSUSPEND)},
 	/* Logitech Quickcam Fusion */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/kernel/drivers/media/usb/uvc/uvc_entity.c b/kernel/drivers/media/usb/uvc/uvc_entity.c
index ca3a9c2..7c98953 100644
--- a/kernel/drivers/media/usb/uvc/uvc_entity.c
+++ b/kernel/drivers/media/usb/uvc/uvc_entity.c
@@ -37,7 +37,7 @@
 			continue;
 
 		remote = uvc_entity_by_id(chain->dev, entity->baSourceID[i]);
-		if (remote == NULL)
+		if (remote == NULL || remote->num_pads == 0)
 			return -EINVAL;
 
 		source = (UVC_ENTITY_TYPE(remote) == UVC_TT_STREAMING)
diff --git a/kernel/drivers/media/usb/uvc/uvc_status.c b/kernel/drivers/media/usb/uvc/uvc_status.c
index 2bdb0ff..7372505 100644
--- a/kernel/drivers/media/usb/uvc/uvc_status.c
+++ b/kernel/drivers/media/usb/uvc/uvc_status.c
@@ -6,6 +6,7 @@
  *          Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  */
 
+#include <asm/barrier.h>
 #include <linux/kernel.h>
 #include <linux/input.h>
 #include <linux/slab.h>
@@ -179,7 +180,8 @@
 
 	switch (status->bAttribute) {
 	case UVC_CTRL_VALUE_CHANGE:
-		return uvc_ctrl_status_event(urb, chain, ctrl, status->bValue);
+		return uvc_ctrl_status_event_async(urb, chain, ctrl,
+						   status->bValue);
 
 	case UVC_CTRL_INFO_CHANGE:
 	case UVC_CTRL_FAILURE_CHANGE:
@@ -309,5 +311,41 @@
 
 void uvc_status_stop(struct uvc_device *dev)
 {
+	struct uvc_ctrl_work *w = &dev->async_ctrl;
+
+	/*
+	 * Prevent the asynchronous control handler from requeing the URB. The
+	 * barrier is needed so the flush_status change is visible to other
+	 * CPUs running the asynchronous handler before usb_kill_urb() is
+	 * called below.
+	 */
+	smp_store_release(&dev->flush_status, true);
+
+	/*
+	 * Cancel any pending asynchronous work. If any status event was queued,
+	 * process it synchronously.
+	 */
+	if (cancel_work_sync(&w->work))
+		uvc_ctrl_status_event(w->chain, w->ctrl, w->data);
+
+	/* Kill the urb. */
 	usb_kill_urb(dev->int_urb);
+
+	/*
+	 * The URB completion handler may have queued asynchronous work. This
+	 * won't resubmit the URB as flush_status is set, but it needs to be
+	 * cancelled before returning or it could then race with a future
+	 * uvc_status_start() call.
+	 */
+	if (cancel_work_sync(&w->work))
+		uvc_ctrl_status_event(w->chain, w->ctrl, w->data);
+
+	/*
+	 * From this point, there are no events on the queue and the status URB
+	 * is dead. No events will be queued until uvc_status_start() is called.
+	 * The barrier is needed to make sure that flush_status is visible to
+	 * uvc_ctrl_status_event_work() when uvc_status_start() will be called
+	 * again.
+	 */
+	smp_store_release(&dev->flush_status, false);
 }
diff --git a/kernel/drivers/media/usb/uvc/uvc_video.c b/kernel/drivers/media/usb/uvc/uvc_video.c
index f6373d6..5344e67 100644
--- a/kernel/drivers/media/usb/uvc/uvc_video.c
+++ b/kernel/drivers/media/usb/uvc/uvc_video.c
@@ -20,6 +20,7 @@
 #include <media/v4l2-common.h>
 
 #include "uvcvideo.h"
+#include <soc/rockchip/rockchip-system-status.h>
 
 /* ------------------------------------------------------------------------
  * UVC Controls
@@ -1308,7 +1309,9 @@
 	if (has_scr)
 		memcpy(stream->clock.last_scr, scr, 6);
 
-	memcpy(&meta->length, mem, length);
+	meta->length = mem[0];
+	meta->flags  = mem[1];
+	memcpy(meta->buf, &mem[2], length - 2);
 	meta_buf->bytesused += length + sizeof(meta->ns) + sizeof(meta->sof);
 
 	uvc_trace(UVC_TRACE_FRAME,
@@ -1903,6 +1906,17 @@
 		uvc_trace(UVC_TRACE_VIDEO, "Selecting alternate setting %u "
 			"(%u B/frame bandwidth).\n", altsetting, best_psize);
 
+		/*
+		 * Some devices, namely the Logitech C910 and B910, are unable
+		 * to recover from a USB autosuspend, unless the alternate
+		 * setting of the streaming interface is toggled.
+		 */
+		if (stream->dev->quirks & UVC_QUIRK_WAKE_AUTOSUSPEND) {
+			usb_set_interface(stream->dev->udev, intfnum,
+					  altsetting);
+			usb_set_interface(stream->dev->udev, intfnum, 0);
+		}
+
 		ret = usb_set_interface(stream->dev->udev, intfnum, altsetting);
 		if (ret < 0)
 			return ret;
@@ -2126,6 +2140,8 @@
 	if (ret < 0)
 		goto error_commit;
 
+	rockchip_set_system_status(SYS_STATUS_PERFORMANCE);
+
 	ret = uvc_video_start_transfer(stream, GFP_KERNEL);
 	if (ret < 0)
 		goto error_video;
@@ -2133,6 +2149,7 @@
 	return 0;
 
 error_video:
+	rockchip_clear_system_status(SYS_STATUS_PERFORMANCE);
 	usb_set_interface(stream->dev->udev, stream->intfnum, 0);
 error_commit:
 	uvc_video_clock_cleanup(stream);
@@ -2163,4 +2180,5 @@
 	}
 
 	uvc_video_clock_cleanup(stream);
+	rockchip_clear_system_status(SYS_STATUS_PERFORMANCE);
 }
diff --git a/kernel/drivers/media/usb/uvc/uvcvideo.h b/kernel/drivers/media/usb/uvc/uvcvideo.h
index 372de34..9dd8d41 100644
--- a/kernel/drivers/media/usb/uvc/uvcvideo.h
+++ b/kernel/drivers/media/usb/uvc/uvcvideo.h
@@ -206,6 +206,7 @@
 #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT	0x00000400
 #define UVC_QUIRK_FORCE_Y8		0x00000800
 #define UVC_QUIRK_FORCE_BPP		0x00001000
+#define UVC_QUIRK_WAKE_AUTOSUSPEND	0x00002000
 
 /* Format flags */
 #define UVC_FMT_FLAG_COMPRESSED		0x00000001
@@ -672,6 +673,7 @@
 	/* Status Interrupt Endpoint */
 	struct usb_host_endpoint *int_ep;
 	struct urb *int_urb;
+	bool flush_status;
 	u8 *status;
 	struct input_dev *input;
 	char input_phys[64];
@@ -841,7 +843,9 @@
 int uvc_ctrl_init_device(struct uvc_device *dev);
 void uvc_ctrl_cleanup_device(struct uvc_device *dev);
 int uvc_ctrl_restore_values(struct uvc_device *dev);
-bool uvc_ctrl_status_event(struct urb *urb, struct uvc_video_chain *chain,
+bool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain,
+				 struct uvc_control *ctrl, const u8 *data);
+void uvc_ctrl_status_event(struct uvc_video_chain *chain,
 			   struct uvc_control *ctrl, const u8 *data);
 
 int uvc_ctrl_begin(struct uvc_video_chain *chain);
diff --git a/kernel/drivers/media/v4l2-core/v4l2-fwnode.c b/kernel/drivers/media/v4l2-core/v4l2-fwnode.c
index dfc53d1..1977ce0 100644
--- a/kernel/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/kernel/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -572,19 +572,29 @@
 	link->local_id = fwep.id;
 	link->local_port = fwep.port;
 	link->local_node = fwnode_graph_get_port_parent(fwnode);
+	if (!link->local_node)
+		return -ENOLINK;
 
 	fwnode = fwnode_graph_get_remote_endpoint(fwnode);
-	if (!fwnode) {
-		fwnode_handle_put(fwnode);
-		return -ENOLINK;
-	}
+	if (!fwnode)
+		goto err_put_local_node;
 
 	fwnode_graph_parse_endpoint(fwnode, &fwep);
 	link->remote_id = fwep.id;
 	link->remote_port = fwep.port;
 	link->remote_node = fwnode_graph_get_port_parent(fwnode);
+	if (!link->remote_node)
+		goto err_put_remote_endpoint;
 
 	return 0;
+
+err_put_remote_endpoint:
+	fwnode_handle_put(fwnode);
+
+err_put_local_node:
+	fwnode_handle_put(link->local_node);
+
+	return -ENOLINK;
 }
 EXPORT_SYMBOL_GPL(v4l2_fwnode_parse_link);
 
diff --git a/kernel/drivers/media/v4l2-core/videobuf-dma-contig.c b/kernel/drivers/media/v4l2-core/videobuf-dma-contig.c
index 52312ce..f2c4393 100644
--- a/kernel/drivers/media/v4l2-core/videobuf-dma-contig.c
+++ b/kernel/drivers/media/v4l2-core/videobuf-dma-contig.c
@@ -36,12 +36,11 @@
 
 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 @@
 			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 @@
 	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);
diff --git a/kernel/drivers/memory/atmel-sdramc.c b/kernel/drivers/memory/atmel-sdramc.c
index 9c49d00..ea6e9e1 100644
--- a/kernel/drivers/memory/atmel-sdramc.c
+++ b/kernel/drivers/memory/atmel-sdramc.c
@@ -47,19 +47,17 @@
 	caps = of_device_get_match_data(&pdev->dev);
 
 	if (caps->has_ddrck) {
-		clk = devm_clk_get(&pdev->dev, "ddrck");
+		clk = devm_clk_get_enabled(&pdev->dev, "ddrck");
 		if (IS_ERR(clk))
 			return PTR_ERR(clk);
-		clk_prepare_enable(clk);
 	}
 
 	if (caps->has_mpddr_clk) {
-		clk = devm_clk_get(&pdev->dev, "mpddr");
+		clk = devm_clk_get_enabled(&pdev->dev, "mpddr");
 		if (IS_ERR(clk)) {
 			pr_err("AT91 RAMC: couldn't get mpddr clock\n");
 			return PTR_ERR(clk);
 		}
-		clk_prepare_enable(clk);
 	}
 
 	return 0;
diff --git a/kernel/drivers/memory/brcmstb_dpfe.c b/kernel/drivers/memory/brcmstb_dpfe.c
index f43ba69..2daae2e 100644
--- a/kernel/drivers/memory/brcmstb_dpfe.c
+++ b/kernel/drivers/memory/brcmstb_dpfe.c
@@ -434,15 +434,17 @@
 static int __send_command(struct brcmstb_dpfe_priv *priv, unsigned int cmd,
 			  u32 result[])
 {
-	const u32 *msg = priv->dpfe_api->command[cmd];
 	void __iomem *regs = priv->regs;
 	unsigned int i, chksum, chksum_idx;
+	const u32 *msg;
 	int ret = 0;
 	u32 resp;
 
 	if (cmd >= DPFE_CMD_MAX)
 		return -1;
 
+	msg = priv->dpfe_api->command[cmd];
+
 	mutex_lock(&priv->lock);
 
 	/* Wait for DCPU to become ready */
diff --git a/kernel/drivers/memory/mvebu-devbus.c b/kernel/drivers/memory/mvebu-devbus.c
index 8450638..efc6c08 100644
--- a/kernel/drivers/memory/mvebu-devbus.c
+++ b/kernel/drivers/memory/mvebu-devbus.c
@@ -280,10 +280,9 @@
 	if (IS_ERR(devbus->base))
 		return PTR_ERR(devbus->base);
 
-	clk = devm_clk_get(&pdev->dev, NULL);
+	clk = devm_clk_get_enabled(&pdev->dev, NULL);
 	if (IS_ERR(clk))
 		return PTR_ERR(clk);
-	clk_prepare_enable(clk);
 
 	/*
 	 * Obtain clock period in picoseconds,
diff --git a/kernel/drivers/memstick/core/memstick.c b/kernel/drivers/memstick/core/memstick.c
index 12bc3f5..1c7a9dc 100644
--- a/kernel/drivers/memstick/core/memstick.c
+++ b/kernel/drivers/memstick/core/memstick.c
@@ -412,6 +412,7 @@
 	return card;
 err_out:
 	host->card = old_card;
+	kfree_const(card->dev.kobj.name);
 	kfree(card);
 	return NULL;
 }
@@ -470,8 +471,10 @@
 				put_device(&card->dev);
 				host->card = NULL;
 			}
-		} else
+		} else {
+			kfree_const(card->dev.kobj.name);
 			kfree(card);
+		}
 	}
 
 out_power_off:
diff --git a/kernel/drivers/memstick/host/r592.c b/kernel/drivers/memstick/host/r592.c
index eaa2a94..0e37c6a 100644
--- a/kernel/drivers/memstick/host/r592.c
+++ b/kernel/drivers/memstick/host/r592.c
@@ -44,12 +44,10 @@
  * memstick_debug_get_tpc_name - debug helper that returns string for
  * a TPC number
  */
-const char *memstick_debug_get_tpc_name(int tpc)
+static __maybe_unused const char *memstick_debug_get_tpc_name(int tpc)
 {
 	return tpc_names[tpc-1];
 }
-EXPORT_SYMBOL(memstick_debug_get_tpc_name);
-
 
 /* Read a register*/
 static inline u32 r592_read_reg(struct r592_device *dev, int address)
@@ -828,7 +826,7 @@
 	/* Stop the processing thread.
 	That ensures that we won't take any more requests */
 	kthread_stop(dev->io_thread);
-
+	del_timer_sync(&dev->detect_timer);
 	r592_enable_device(dev, false);
 
 	while (!error && dev->req) {
diff --git a/kernel/drivers/message/fusion/mptlan.c b/kernel/drivers/message/fusion/mptlan.c
index 7d3784a..90cc3cd 100644
--- a/kernel/drivers/message/fusion/mptlan.c
+++ b/kernel/drivers/message/fusion/mptlan.c
@@ -1430,7 +1430,9 @@
 {
 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
 	struct net_device	*dev = ioc->netdev;
+	struct mpt_lan_priv *priv = netdev_priv(dev);
 
+	cancel_delayed_work_sync(&priv->post_buckets_task);
 	if(dev != NULL) {
 		unregister_netdev(dev);
 		free_netdev(dev);
diff --git a/kernel/drivers/mfd/Kconfig b/kernel/drivers/mfd/Kconfig
index aa1fe3b..0ace442 100644
--- a/kernel/drivers/mfd/Kconfig
+++ b/kernel/drivers/mfd/Kconfig
@@ -1188,6 +1188,14 @@
 	  through SPI interface. The device supports multiple sub-devices
 	  including interrupts, LDO & DCDC regulators, and onkey.
 
+config MFD_RK806_I2C
+	tristate "RK806 Power Management chip with I2C"
+	select MFD_RK806
+	select REGMAP_I2C
+	select REGMAP_IRQ
+	help
+	  If you say yes here you get support for the RK806 PM chips with I2c interface.
+
 config MFD_RK806_SPI
 	tristate "RK806 Power Management chip with SPI"
 	select MFD_RK806
diff --git a/kernel/drivers/mfd/Makefile b/kernel/drivers/mfd/Makefile
index 17c7220..57f62d3 100644
--- a/kernel/drivers/mfd/Makefile
+++ b/kernel/drivers/mfd/Makefile
@@ -227,6 +227,7 @@
 obj-$(CONFIG_MFD_RK630_I2C)	+= rk630-i2c.o
 obj-$(CONFIG_MFD_RK630_SPI)	+= rk630-spi.o
 obj-$(CONFIG_MFD_RK806)		+= rk806-core.o
+obj-$(CONFIG_MFD_RK806_I2C)	+= rk806-i2c.o
 obj-$(CONFIG_MFD_RK806_SPI)	+= rk806-spi.o
 obj-$(CONFIG_MFD_RK808)		+= rk808.o
 obj-$(CONFIG_MFD_RK1000)	+= rk1000-core.o
diff --git a/kernel/drivers/mfd/arizona-core.c b/kernel/drivers/mfd/arizona-core.c
index 000cb82..afdc490 100644
--- a/kernel/drivers/mfd/arizona-core.c
+++ b/kernel/drivers/mfd/arizona-core.c
@@ -45,7 +45,7 @@
 	if (arizona->clk32k_ref == 1) {
 		switch (arizona->pdata.clk32k_src) {
 		case ARIZONA_32KZ_MCLK1:
-			ret = pm_runtime_get_sync(arizona->dev);
+			ret = pm_runtime_resume_and_get(arizona->dev);
 			if (ret != 0)
 				goto err_ref;
 			ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK1]);
diff --git a/kernel/drivers/mfd/display-serdes/Makefile b/kernel/drivers/mfd/display-serdes/Makefile
index 420076c..f5a5a15 100644
--- a/kernel/drivers/mfd/display-serdes/Makefile
+++ b/kernel/drivers/mfd/display-serdes/Makefile
@@ -10,4 +10,4 @@
 
 serdes-mfd-display-$(CONFIG_MFD_SERDES_DISPLAY) += serdes-core.o serdes-irq.o
 
-obj-$(CONFIG_MFD_SERDES_DISPLAY) += serdes-mfd-display.o serdes-i2c.o serdes-bridge.o serdes-panel.o serdes-gpio.o serdes-pinctrl.o
+obj-$(CONFIG_MFD_SERDES_DISPLAY) += serdes-mfd-display.o serdes-i2c.o serdes-bridge.o serdes-bridge-split.o serdes-panel.o serdes-panel-split.o serdes-gpio.o serdes-pinctrl.o
diff --git a/kernel/drivers/mfd/display-serdes/core.h b/kernel/drivers/mfd/display-serdes/core.h
index 28f9945..8563ae5 100644
--- a/kernel/drivers/mfd/display-serdes/core.h
+++ b/kernel/drivers/mfd/display-serdes/core.h
@@ -46,6 +46,7 @@
 #include <drm/drm_of.h>
 #include <drm/drm_connector.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_dp_helper.h>
 #include <drm/drm_device.h>
 #include <drm/drm_modes.h>
 #include <drm/drm_atomic_state_helper.h>
@@ -69,6 +70,8 @@
 #include "../../../../drivers/pinctrl/pinconf.h"
 #include "../../../../drivers/pinctrl/pinmux.h"
 #include "../../../../drivers/gpio/gpiolib.h"
+#include "../../../../drivers/extcon/extcon.h"
+#include "../../../../drivers/base/regmap/internal.h"
 
 /*
 * if enable all the debug information,
@@ -99,8 +102,15 @@
 #endif
 
 #define MFD_SERDES_DISPLAY_VERSION "serdes-mfd-displaly-v10-230901"
-
+#define MAX_NUM_SERDES_SPLIT 8
 struct serdes;
+enum ser_link_mode {
+	SER_DUAL_LINK,
+	SER_LINKA,
+	SER_LINKB,
+	SER_SPLITTER_MODE,
+};
+
 struct serdes_chip_pinctrl_info {
 	struct pinctrl_pin_desc *pins;
 	unsigned int num_pins;
@@ -160,6 +170,12 @@
 	int (*to_irq)(struct serdes *serdes, int gpio);
 };
 
+struct serdes_chip_split_ops {
+	int (*select)(struct serdes *serdes, int chan);
+	int (*deselect)(struct serdes *serdes, int chan);
+	int (*set_i2c_addr)(struct serdes *serdes, int address, int link);
+};
+
 struct serdes_chip_pm_ops {
 	/* serdes chip function for suspend and resume */
 	int (*suspend)(struct serdes *serdes);
@@ -188,12 +204,14 @@
 	int same_chip_count;
 	u8 bank_num;
 
+	int (*chip_init)(struct serdes *serdes);
 	struct regmap_config *regmap_config;
 	struct serdes_chip_pinctrl_info *pinctrl_info;
 	struct serdes_chip_bridge_ops *bridge_ops;
 	struct serdes_chip_panel_ops *panel_ops;
 	struct serdes_chip_pinctrl_ops *pinctrl_ops;
 	struct serdes_chip_gpio_ops *gpio_ops;
+	struct serdes_chip_split_ops *split_ops;
 	struct serdes_chip_pm_ops *pm_ops;
 	struct serdes_chip_irq_ops *irq_ops;
 };
@@ -237,7 +255,35 @@
 	struct serdes *parent;
 	struct regmap *regmap;
 	struct mipi_dsi_device *dsi;
-	struct device_node *dsi_node;
+	struct device_node *remote_node;
+	struct drm_display_mode mode;
+	struct backlight_device *backlight;
+	struct serdes_init_seq *serdes_init_seq;
+	bool sel_mipi;
+	bool dv_swp_ab;
+	bool dpi_deskew_en;
+	bool split_mode;
+	u32 num_lanes;
+	u32 dsi_lane_map[4];
+};
+
+struct serdes_panel_split {
+	struct drm_panel panel;
+	enum drm_connector_status status;
+	struct drm_connector connector;
+
+	const char *name;
+	u32 width_mm;
+	u32 height_mm;
+	u32 link_rate;
+	u32 lane_count;
+	bool ssc;
+
+	struct device *dev;
+	struct serdes *parent;
+	struct regmap *regmap;
+	struct mipi_dsi_device *dsi;
+	struct device_node *remote_node;
 	struct drm_display_mode mode;
 	struct backlight_device *backlight;
 	struct serdes_init_seq *serdes_init_seq;
@@ -261,7 +307,7 @@
 	struct serdes *parent;
 	struct regmap *regmap;
 	struct mipi_dsi_device *dsi;
-	struct device_node *dsi_node;
+	struct device_node *remote_node;
 	struct drm_display_mode mode;
 	struct backlight_device *backlight;
 
@@ -269,6 +315,29 @@
 	bool dv_swp_ab;
 	bool dpi_deskew_en;
 	bool split_mode;
+	u32 num_lanes;
+	u32 dsi_lane_map[4];
+};
+
+struct serdes_bridge_split {
+	struct drm_bridge base_bridge;
+	struct drm_bridge *next_bridge;
+	enum drm_connector_status status;
+	atomic_t triggered;
+	struct drm_connector connector;
+	struct drm_panel *panel;
+
+	struct device *dev;
+	struct serdes *parent;
+	struct regmap *regmap;
+	struct mipi_dsi_device *dsi;
+	struct device_node *remote_node;
+	struct drm_display_mode mode;
+	struct backlight_device *backlight;
+
+	bool sel_mipi;
+	bool dv_swp_ab;
+	bool dpi_deskew_en;
 	u32 num_lanes;
 	u32 dsi_lane_map[4];
 };
@@ -303,13 +372,25 @@
 	struct delayed_work mfd_delay_work;
 	bool route_enable;
 	bool use_delay_work;
+
+	bool split_mode_enable;
+	unsigned int reg_hw;
+	unsigned int reg_use;
+	unsigned int link_use;
+	unsigned int id_serdes_bridge_split;
+	unsigned int id_serdes_panel_split;
+	struct serdes *g_serdes_bridge_split;
+
 	struct pinctrl *pinctrl_node;
 	struct pinctrl_state *pins_default;
+	struct pinctrl_state *pins_init;
 	struct pinctrl_state *pins_sleep;
 
 	struct serdes_init_seq *serdes_init_seq;
 	struct serdes_bridge *serdes_bridge;
+	struct serdes_bridge_split *serdes_bridge_split;
 	struct serdes_panel *serdes_panel;
+	struct serdes_panel_split *serdes_panel_split;
 	struct serdes_pinctrl *pinctrl;
 	struct serdes_chip_data *chip_data;
 };
@@ -334,7 +415,8 @@
 int serdes_set_pinctrl_sleep(struct serdes *serdes);
 int serdes_device_suspend(struct serdes *serdes);
 int serdes_device_resume(struct serdes *serdes);
-void serdes_device_shutdown(struct serdes *serdes);
+void serdes_device_poweroff(struct serdes *serdes);
+int serdes_device_shutdown(struct serdes *serdes);
 int serdes_irq_init(struct serdes *serdes);
 void serdes_irq_exit(struct serdes *serdes);
 void serdes_auxadc_init(struct serdes *serdes);
diff --git a/kernel/drivers/mfd/display-serdes/gpio.h b/kernel/drivers/mfd/display-serdes/gpio.h
index 7a9d630..66708b8 100644
--- a/kernel/drivers/mfd/display-serdes/gpio.h
+++ b/kernel/drivers/mfd/display-serdes/gpio.h
@@ -108,22 +108,22 @@
 };
 
 enum max96752_gpio_list {
-	MAXIM_MAX96752_MFP0 = 0,
-	MAXIM_MAX96752_MFP1,
-	MAXIM_MAX96752_MFP2,
-	MAXIM_MAX96752_MFP3,
-	MAXIM_MAX96752_MFP4,
-	MAXIM_MAX96752_MFP5,
-	MAXIM_MAX96752_MFP6,
-	MAXIM_MAX96752_MFP7,
-	MAXIM_MAX96752_MFP8,
-	MAXIM_MAX96752_MFP9,
-	MAXIM_MAX96752_MFP10,
-	MAXIM_MAX96752_MFP11,
-	MAXIM_MAX96752_MFP12,
-	MAXIM_MAX96752_MFP13,
-	MAXIM_MAX96752_MFP14,
-	MAXIM_MAX96752_MFP15,
+	MAXIM_MAX96752_GPIO0 = 0,
+	MAXIM_MAX96752_GPIO1,
+	MAXIM_MAX96752_GPIO2,
+	MAXIM_MAX96752_GPIO3,
+	MAXIM_MAX96752_GPIO4,
+	MAXIM_MAX96752_GPIO5,
+	MAXIM_MAX96752_GPIO6,
+	MAXIM_MAX96752_GPIO7,
+	MAXIM_MAX96752_GPIO8,
+	MAXIM_MAX96752_GPIO9,
+	MAXIM_MAX96752_GPIO10,
+	MAXIM_MAX96752_GPIO11,
+	MAXIM_MAX96752_GPIO12,
+	MAXIM_MAX96752_GPIO13,
+	MAXIM_MAX96752_GPIO14,
+	MAXIM_MAX96752_GPIO15,
 };
 
 enum max96755_gpio_list {
@@ -151,22 +151,22 @@
 };
 
 enum max96722_gpio_list {
-	MAXIM_MAX96772_MFP0 = 0,
-	MAXIM_MAX96772_MFP1,
-	MAXIM_MAX96772_MFP2,
-	MAXIM_MAX96772_MFP3,
-	MAXIM_MAX96772_MFP4,
-	MAXIM_MAX96772_MFP5,
-	MAXIM_MAX96772_MFP6,
-	MAXIM_MAX96772_MFP7,
-	MAXIM_MAX96772_MFP8,
-	MAXIM_MAX96772_MFP9,
-	MAXIM_MAX96772_MFP10,
-	MAXIM_MAX96772_MFP11,
-	MAXIM_MAX96772_MFP12,
-	MAXIM_MAX96772_MFP13,
-	MAXIM_MAX96772_MFP14,
-	MAXIM_MAX96772_MFP15,
+	MAXIM_MAX96772_GPIO0 = 0,
+	MAXIM_MAX96772_GPIO1,
+	MAXIM_MAX96772_GPIO2,
+	MAXIM_MAX96772_GPIO3,
+	MAXIM_MAX96772_GPIO4,
+	MAXIM_MAX96772_GPIO5,
+	MAXIM_MAX96772_GPIO6,
+	MAXIM_MAX96772_GPIO7,
+	MAXIM_MAX96772_GPIO8,
+	MAXIM_MAX96772_GPIO9,
+	MAXIM_MAX96772_GPIO10,
+	MAXIM_MAX96772_GPIO11,
+	MAXIM_MAX96772_GPIO12,
+	MAXIM_MAX96772_GPIO13,
+	MAXIM_MAX96772_GPIO14,
+	MAXIM_MAX96772_GPIO15,
 };
 
 enum max96789_gpio_list {
diff --git a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96745.c b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96745.c
index 2736936..c0db61f 100644
--- a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96745.c
+++ b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96745.c
@@ -121,7 +121,7 @@
 
 #define FUNCTION_DESC_GPIO_OUTPUT_A(id) \
 { \
-	.name = "DES_GPIO"#id"_OUTPUT_A", \
+	.name = "SER_TXID"#id"_TO_DES_LINKA", \
 	.group_names = serdes_gpio_groups, \
 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
 	.data = (void *)(const struct serdes_function_data []) { \
@@ -132,7 +132,7 @@
 
 #define FUNCTION_DESC_GPIO_OUTPUT_B(id) \
 { \
-	.name = "DES_GPIO"#id"_OUTPUT_B", \
+	.name = "SER_TXID"#id"_TO_DES_LINKB", \
 	.group_names = serdes_gpio_groups, \
 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
 	.data = (void *)(const struct serdes_function_data []) { \
@@ -143,7 +143,7 @@
 
 #define FUNCTION_DESC_GPIO_INPUT_A(id) \
 { \
-	.name = "DES_GPIO"#id"_INPUT_A", \
+	.name = "DES_RXID"#id"_TO_SER_LINKA", \
 	.group_names = serdes_gpio_groups, \
 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
 	.data = (void *)(const struct serdes_function_data []) { \
@@ -153,7 +153,7 @@
 
 #define FUNCTION_DESC_GPIO_INPUT_B(id) \
 { \
-	.name = "DES_GPIO"#id"_INPUT_B", \
+	.name = "DES_RXID"#id"_TO_SER_LINKB", \
 	.group_names = serdes_gpio_groups, \
 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
 	.data = (void *)(const struct serdes_function_data []) { \
@@ -377,12 +377,26 @@
 static bool max96745_vid_tx_active(struct serdes *serdes)
 {
 	u32 val;
+	int i = 0, ret = 0;
 
-	if (serdes_reg_read(serdes, 0x0107, &val))
-		return false;
+	for (i = 0; i < 5; i++) {
+		ret = serdes_reg_read(serdes, 0x0107, &val);
+		if (!ret)
+			break;
 
-	if (!FIELD_GET(VID_TX_ACTIVE_A | VID_TX_ACTIVE_B, val))
+		SERDES_DBG_CHIP("serdes %s: false val=%d i=%d ret=%d\n", __func__, val, i, ret);
+		msleep(20);
+	}
+
+	if (ret) {
+		SERDES_DBG_CHIP("serdes %s: false val=%d ret=%d\n", __func__, val, ret);
 		return false;
+	}
+
+	if (!FIELD_GET(VID_TX_ACTIVE_A | VID_TX_ACTIVE_B, val)) {
+		SERDES_DBG_CHIP("serdes %s: false val=%d\n", __func__, val);
+		return false;
+	}
 
 	return true;
 }
@@ -391,9 +405,9 @@
 {
 	if (max96745_vid_tx_active(serdes)) {
 		extcon_set_state(serdes->extcon, EXTCON_JACK_VIDEO_OUT, true);
-		pr_info("%s, extcon is true\n", __func__);
+		pr_info("serdes %s, extcon is true state=%d\n", __func__, serdes->extcon->state);
 	} else {
-		pr_info("%s, extcon is false\n", __func__);
+		pr_info("serdes %s, extcon is false\n", __func__);
 	}
 
 	return 0;
@@ -403,14 +417,21 @@
 {
 	u32 val;
 
-	if (serdes->lock_gpio)
-		return gpiod_get_value_cansleep(serdes->lock_gpio);
+	if (serdes->lock_gpio) {
+		val = gpiod_get_value_cansleep(serdes->lock_gpio);
+		SERDES_DBG_CHIP("serdes %s:val=%d\n", __func__, val);
+		return val;
+	}
 
-	if (serdes_reg_read(serdes, 0x002a, &val))
+	if (serdes_reg_read(serdes, 0x002a, &val)) {
+		SERDES_DBG_CHIP("serdes %s: false val=%d\n", __func__, val);
 		return false;
+	}
 
-	if (!FIELD_GET(LINK_LOCKED, val))
+	if (!FIELD_GET(LOCKED, val)) {
+		SERDES_DBG_CHIP("serdes %s: false val=%d\n", __func__, val);
 		return false;
+	}
 
 	return true;
 }
@@ -444,11 +465,13 @@
 
 		if (atomic_cmpxchg(&serdes_bridge->triggered, 1, 0)) {
 			status = connector_status_disconnected;
+			SERDES_DBG_CHIP("1 status=%d state=%d\n", status, serdes->extcon->state);
 			goto out;
 		}
 
 		if (serdes_reg_read(serdes, 0x641a, &dprx_trn_status2)) {
 			status = connector_status_disconnected;
+			SERDES_DBG_CHIP("2 status=%d state=%d\n", status, serdes->extcon->state);
 			goto out;
 		}
 
@@ -456,15 +479,20 @@
 			dev_err(serdes->dev, "Training State: 0x%lx\n",
 				FIELD_GET(DPRX_TRAIN_STATE, dprx_trn_status2));
 			status = connector_status_disconnected;
+			SERDES_DBG_CHIP("3 status=%d state=%d\n", status, serdes->extcon->state);
 			goto out;
 		}
 	} else {
 		atomic_set(&serdes_bridge->triggered, 0);
+		SERDES_DBG_CHIP("4 status=%d state=%d\n", status, serdes->extcon->state);
 	}
+
+	if (serdes_bridge->next_bridge && (serdes_bridge->next_bridge->ops & DRM_BRIDGE_OP_DETECT))
+		return drm_bridge_detect(serdes_bridge->next_bridge);
 
 out:
 	serdes_bridge->status = status;
-	SERDES_DBG_MFD("%s: status=%d\n", __func__, status);
+	SERDES_DBG_CHIP("5 status=%d state=%d\n", status, serdes->extcon->state);
 	return status;
 }
 
@@ -472,7 +500,8 @@
 {
 	int ret = 0;
 
-	SERDES_DBG_CHIP("%s: serdes chip %s ret=%d\n", __func__, serdes->chip_data->name, ret);
+	SERDES_DBG_CHIP("%s: serdes chip %s ret=%d state=%d\n",
+				__func__, serdes->chip_data->name, ret, serdes->extcon->state);
 	return ret;
 }
 
@@ -490,6 +519,59 @@
 	.enable = max96745_bridge_enable,
 	.disable = max96745_bridge_disable,
 };
+
+static int max96745_pinctrl_set_mux(struct serdes *serdes,
+				    unsigned int function, unsigned int group)
+{
+	struct serdes_pinctrl *pinctrl = serdes->pinctrl;
+	struct function_desc *func;
+	struct group_desc *grp;
+	int i;
+
+	func = pinmux_generic_get_function(pinctrl->pctl, function);
+	if (!func)
+		return -EINVAL;
+
+	grp = pinctrl_generic_get_group(pinctrl->pctl, group);
+	if (!grp)
+		return -EINVAL;
+
+	SERDES_DBG_CHIP("%s: serdes chip %s func=%s data=%p group=%s data=%p, num_pin=%d\n",
+			__func__, serdes->chip_data->name,
+			func->name, func->data, grp->name, grp->data, grp->num_pins);
+
+	if (func->data) {
+		struct serdes_function_data *data = func->data;
+
+		for (i = 0; i < grp->num_pins; i++) {
+			serdes_set_bits(serdes,
+					GPIO_A_REG(grp->pins[i] - pinctrl->pin_base),
+					GPIO_OUT_DIS,
+					FIELD_PREP(GPIO_OUT_DIS, data->gpio_out_dis));
+			if (data->gpio_tx_en_a || data->gpio_tx_en_b)
+				serdes_set_bits(serdes,
+						GPIO_B_REG(grp->pins[i] - pinctrl->pin_base),
+						GPIO_TX_ID,
+						FIELD_PREP(GPIO_TX_ID, data->gpio_tx_id));
+			if (data->gpio_rx_en_a || data->gpio_rx_en_b)
+				serdes_set_bits(serdes,
+						GPIO_C_REG(grp->pins[i] - pinctrl->pin_base),
+						GPIO_RX_ID,
+						FIELD_PREP(GPIO_RX_ID, data->gpio_rx_id));
+			serdes_set_bits(serdes,
+					GPIO_D_REG(grp->pins[i] - pinctrl->pin_base),
+					GPIO_TX_EN_A | GPIO_TX_EN_B | GPIO_IO_RX_EN |
+					GPIO_RX_EN_A | GPIO_RX_EN_B,
+					FIELD_PREP(GPIO_TX_EN_A, data->gpio_tx_en_a) |
+					FIELD_PREP(GPIO_TX_EN_B, data->gpio_tx_en_b) |
+					FIELD_PREP(GPIO_RX_EN_A, data->gpio_rx_en_a) |
+					FIELD_PREP(GPIO_RX_EN_B, data->gpio_rx_en_b) |
+					FIELD_PREP(GPIO_IO_RX_EN, data->gpio_io_rx_en));
+		}
+	}
+
+	return 0;
+}
 
 static int max96745_pinctrl_config_get(struct serdes *serdes,
 				       unsigned int pin, unsigned long *config)
@@ -635,59 +717,6 @@
 	return 0;
 }
 
-static int max96745_pinctrl_set_mux(struct serdes *serdes,
-				    unsigned int function, unsigned int group)
-{
-	struct serdes_pinctrl *pinctrl = serdes->pinctrl;
-	struct function_desc *func;
-	struct group_desc *grp;
-	int i;
-
-	func = pinmux_generic_get_function(pinctrl->pctl, function);
-	if (!func)
-		return -EINVAL;
-
-	grp = pinctrl_generic_get_group(pinctrl->pctl, group);
-	if (!grp)
-		return -EINVAL;
-
-	SERDES_DBG_CHIP("%s: serdes chip %s func=%s data=%p group=%s data=%p, num_pin=%d\n",
-			__func__, serdes->chip_data->name,
-			func->name, func->data, grp->name, grp->data, grp->num_pins);
-
-	if (func->data) {
-		struct serdes_function_data *data = func->data;
-
-		for (i = 0; i < grp->num_pins; i++) {
-			serdes_set_bits(serdes,
-					GPIO_A_REG(grp->pins[i] - pinctrl->pin_base),
-					GPIO_OUT_DIS,
-					FIELD_PREP(GPIO_OUT_DIS, data->gpio_out_dis));
-			if (data->gpio_tx_en_a || data->gpio_tx_en_b)
-				serdes_set_bits(serdes,
-						GPIO_B_REG(grp->pins[i] - pinctrl->pin_base),
-						GPIO_TX_ID,
-						FIELD_PREP(GPIO_TX_ID, data->gpio_tx_id));
-			if (data->gpio_rx_en_a || data->gpio_rx_en_b)
-				serdes_set_bits(serdes,
-						GPIO_C_REG(grp->pins[i] - pinctrl->pin_base),
-						GPIO_RX_ID,
-						FIELD_PREP(GPIO_RX_ID, data->gpio_rx_id));
-			serdes_set_bits(serdes,
-					GPIO_D_REG(grp->pins[i] - pinctrl->pin_base),
-					GPIO_TX_EN_A | GPIO_TX_EN_B | GPIO_IO_RX_EN |
-					GPIO_RX_EN_A | GPIO_RX_EN_B,
-					FIELD_PREP(GPIO_TX_EN_A, data->gpio_tx_en_a) |
-					FIELD_PREP(GPIO_TX_EN_B, data->gpio_tx_en_b) |
-					FIELD_PREP(GPIO_RX_EN_A, data->gpio_rx_en_a) |
-					FIELD_PREP(GPIO_RX_EN_B, data->gpio_rx_en_b) |
-					FIELD_PREP(GPIO_IO_RX_EN, data->gpio_io_rx_en));
-		}
-	}
-
-	return 0;
-}
-
 static struct serdes_chip_pinctrl_ops max96745_pinctrl_ops = {
 	.pin_config_get = max96745_pinctrl_config_get,
 	.pin_config_set = max96745_pinctrl_config_set,
@@ -733,6 +762,84 @@
 	.to_irq = max96745_gpio_to_irq,
 };
 
+static int max96745_select(struct serdes *serdes, int chan)
+{
+	/*0076 for linkA and 0086 for linkB*/
+	if (chan == DUAL_LINK) {
+		serdes_set_bits(serdes, 0x0076, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 0));
+		serdes_set_bits(serdes, 0x0086, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 0));
+		SERDES_DBG_CHIP("%s: enable %s remote i2c of linkA and linkB\n", __func__,
+				serdes->chip_data->name);
+	} else if (chan == LINKA) {
+		serdes_set_bits(serdes, 0x0076, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 0));
+		serdes_set_bits(serdes, 0x0086, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 1));
+		SERDES_DBG_CHIP("%s: only enable %s remote i2c of linkA\n", __func__,
+				serdes->chip_data->name);
+	} else if (chan == LINKB) {
+		serdes_set_bits(serdes, 0x0076, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 1));
+		serdes_set_bits(serdes, 0x0086, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 0));
+		SERDES_DBG_CHIP("%s: only enable %s remote i2c of linkB\n", __func__,
+				serdes->chip_data->name);
+	} else if (chan == SPLITTER_MODE) {
+		serdes_set_bits(serdes, 0x0076, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 0));
+		serdes_set_bits(serdes, 0x0086, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 0));
+		SERDES_DBG_CHIP("%s: enable %s remote i2c of linkA and linkB\n", __func__,
+				serdes->chip_data->name);
+	}
+
+	return 0;
+}
+
+static int max96745_deselect(struct serdes *serdes, int chan)
+{
+
+	if (chan == DUAL_LINK) {
+		serdes_set_bits(serdes, 0x0076, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 1));
+		serdes_set_bits(serdes, 0x0086, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 1));
+		SERDES_DBG_CHIP("%s: disable %s remote i2c of linkA and linkB\n", __func__,
+				serdes->chip_data->name);
+	} else if (chan == LINKA) {
+		serdes_set_bits(serdes, 0x0076, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 1));
+		serdes_set_bits(serdes, 0x0086, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 0));
+		SERDES_DBG_CHIP("%s: only disable %s remote i2c of linkA\n", __func__,
+				serdes->chip_data->name);
+	} else if (chan == LINKB) {
+		serdes_set_bits(serdes, 0x0076, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 0));
+		serdes_set_bits(serdes, 0x0086, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 1));
+		SERDES_DBG_CHIP("%s: only disable %s remote i2c of linkB\n", __func__,
+				serdes->chip_data->name);
+	} else if (chan == SPLITTER_MODE) {
+		serdes_set_bits(serdes, 0x0076, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 1));
+		serdes_set_bits(serdes, 0x0086, DIS_REM_CC,
+				   FIELD_PREP(DIS_REM_CC, 1));
+		SERDES_DBG_CHIP("%s: disable %s remote i2c of linkA and linkB\n", __func__,
+				serdes->chip_data->name);
+	}
+
+	return 0;
+}
+
+
+static struct serdes_chip_split_ops max96745_split_ops = {
+	.select = max96745_select,
+	.deselect = max96745_deselect,
+};
+
 static int max96745_pm_suspend(struct serdes *serdes)
 {
 	return 0;
@@ -773,6 +880,7 @@
 	.bridge_ops	= &max96745_bridge_ops,
 	.pinctrl_ops	= &max96745_pinctrl_ops,
 	.gpio_ops	= &max96745_gpio_ops,
+	.split_ops	= &max96745_split_ops,
 	.pm_ops		= &max96745_pm_ops,
 	.irq_ops	= &max96745_irq_ops,
 };
diff --git a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96745.h b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96745.h
index 031f4f9..5d17fe5 100644
--- a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96745.h
+++ b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96745.h
@@ -136,4 +136,11 @@
 /* 7074h */
 #define MAX_LINK_RATE		GENMASK(7, 0)
 
+enum link_mode {
+	DUAL_LINK,
+	LINKA,
+	LINKB,
+	SPLITTER_MODE,
+};
+
 #endif
diff --git a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96752.c b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96752.c
index 2eddb39..8da93ea 100644
--- a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96752.c
+++ b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96752.c
@@ -27,23 +27,34 @@
 	.rd_table = &max96752_readable_table,
 };
 
-static int MAX96752_MFP0_pins[] = {0};
-static int MAX96752_MFP1_pins[] = {1};
-static int MAX96752_MFP2_pins[] = {2};
-static int MAX96752_MFP3_pins[] = {3};
-static int MAX96752_MFP4_pins[] = {4};
-static int MAX96752_MFP5_pins[] = {5};
-static int MAX96752_MFP6_pins[] = {6};
-static int MAX96752_MFP7_pins[] = {7};
+struct config_desc {
+	u16 reg;
+	u8 mask;
+	u8 val;
+};
 
-static int MAX96752_MFP8_pins[] = {8};
-static int MAX96752_MFP9_pins[] = {9};
-static int MAX96752_MFP10_pins[] = {10};
-static int MAX96752_MFP11_pins[] = {11};
-static int MAX96752_MFP12_pins[] = {12};
-static int MAX96752_MFP13_pins[] = {13};
-static int MAX96752_MFP14_pins[] = {14};
-static int MAX96752_MFP15_pins[] = {15};
+struct serdes_group_data {
+	const struct config_desc *configs;
+	int num_configs;
+};
+
+static int MAX96752_GPIO0_pins[] = {0};
+static int MAX96752_GPIO1_pins[] = {1};
+static int MAX96752_GPIO2_pins[] = {2};
+static int MAX96752_GPIO3_pins[] = {3};
+static int MAX96752_GPIO4_pins[] = {4};
+static int MAX96752_GPIO5_pins[] = {5};
+static int MAX96752_GPIO6_pins[] = {6};
+static int MAX96752_GPIO7_pins[] = {7};
+
+static int MAX96752_GPIO8_pins[] = {8};
+static int MAX96752_GPIO9_pins[] = {9};
+static int MAX96752_GPIO10_pins[] = {10};
+static int MAX96752_GPIO11_pins[] = {11};
+static int MAX96752_GPIO12_pins[] = {12};
+static int MAX96752_GPIO13_pins[] = {13};
+static int MAX96752_GPIO14_pins[] = {14};
+static int MAX96752_GPIO15_pins[] = {15};
 
 #define GROUP_DESC(nm) \
 { \
@@ -56,21 +67,24 @@
 	u8 gpio_out_dis:1;
 	u8 gpio_tx_en:1;
 	u8 gpio_rx_en:1;
+	u8 gpio_in_level:1;
+	u8 gpio_out_level:1;
 	u8 gpio_tx_id;
 	u8 gpio_rx_id;
+	u16 mdelay;
 };
 
 static const char *serdes_gpio_groups[] = {
-	"MAX96752_MFP0", "MAX96752_MFP1", "MAX96752_MFP2", "MAX96752_MFP3",
-	"MAX96752_MFP4", "MAX96752_MFP5", "MAX96752_MFP6", "MAX96752_MFP7",
+	"MAX96752_GPIO0", "MAX96752_GPIO1", "MAX96752_GPIO2", "MAX96752_GPIO3",
+	"MAX96752_GPIO4", "MAX96752_GPIO5", "MAX96752_GPIO6", "MAX96752_GPIO7",
 
-	"MAX96752_MFP8", "MAX96752_MFP9", "MAX96752_MFP10", "MAX96752_MFP11",
-	"MAX96752_MFP12", "MAX96752_MFP13", "MAX96752_MFP14", "MAX96752_MFP15",
+	"MAX96752_GPIO8", "MAX96752_GPIO9", "MAX96752_GPIO10", "MAX96752_GPIO11",
+	"MAX96752_GPIO12", "MAX96752_GPIO13", "MAX96752_GPIO14", "MAX96752_GPIO15",
 };
 
-#define FUNCTION_DESC_GPIO_INPUT(id) \
+#define FUNCTION_DESC_GPIO_INPUT_BYPASS(id) \
 { \
-	.name = "MFP"#id"_INPUT", \
+	.name = "SER_TO_DES_RXID"#id, \
 	.group_names = serdes_gpio_groups, \
 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
 	.data = (void *)(const struct serdes_function_data []) { \
@@ -78,9 +92,9 @@
 	}, \
 } \
 
-#define FUNCTION_DESC_GPIO_OUTPUT(id) \
+#define FUNCTION_DESC_GPIO_OUTPUT_BYPASS(id) \
 { \
-	.name = "MFP"#id"_OUTPUT", \
+	.name = "DES_TXID"#id"_TO_SER", \
 	.group_names = serdes_gpio_groups, \
 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
 	.data = (void *)(const struct serdes_function_data []) { \
@@ -88,83 +102,156 @@
 	}, \
 } \
 
-static struct pinctrl_pin_desc max96752_pins_desc[] = {
-	PINCTRL_PIN(MAXIM_MAX96752_MFP0, "MAX96752_MFP0"),
-	PINCTRL_PIN(MAXIM_MAX96752_MFP1, "MAX96752_MFP1"),
-	PINCTRL_PIN(MAXIM_MAX96752_MFP2, "MAX96752_MFP2"),
-	PINCTRL_PIN(MAXIM_MAX96752_MFP3, "MAX96752_MFP3"),
-	PINCTRL_PIN(MAXIM_MAX96752_MFP4, "MAX96752_MFP4"),
-	PINCTRL_PIN(MAXIM_MAX96752_MFP5, "MAX96752_MFP5"),
-	PINCTRL_PIN(MAXIM_MAX96752_MFP6, "MAX96752_MFP6"),
-	PINCTRL_PIN(MAXIM_MAX96752_MFP7, "MAX96752_MFP7"),
+#define FUNCTION_DESC_GPIO_OUTPUT_LOW(id) \
+{ \
+	.name = "DES_TXID"#id"_OUTPUT_LOW", \
+	.group_names = serdes_gpio_groups, \
+	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
+	.data = (void *)(const struct serdes_function_data []) { \
+		{ .gpio_out_dis = 0, .gpio_tx_en = 0, \
+		  .gpio_rx_en = 0, .gpio_out_level = 0, .gpio_tx_id = id } \
+	}, \
+} \
 
-	PINCTRL_PIN(MAXIM_MAX96752_MFP8, "MAX96752_MFP8"),
-	PINCTRL_PIN(MAXIM_MAX96752_MFP9, "MAX96752_MFP9"),
-	PINCTRL_PIN(MAXIM_MAX96752_MFP10, "MAX96752_MFP10"),
-	PINCTRL_PIN(MAXIM_MAX96752_MFP11, "MAX96752_MFP11"),
-	PINCTRL_PIN(MAXIM_MAX96752_MFP12, "MAX96752_MFP12"),
-	PINCTRL_PIN(MAXIM_MAX96752_MFP13, "MAX96752_MFP13"),
-	PINCTRL_PIN(MAXIM_MAX96752_MFP14, "MAX96752_MFP14"),
-	PINCTRL_PIN(MAXIM_MAX96752_MFP15, "MAX96752_MFP15"),
+#define FUNCTION_DESC_GPIO_OUTPUT_HIGH(id) \
+{ \
+	.name = "DES_TXID"#id"_OUTPUT_HIGH", \
+	.group_names = serdes_gpio_groups, \
+	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
+	.data = (void *)(const struct serdes_function_data []) { \
+		{ .gpio_out_dis = 0, .gpio_tx_en = 0, \
+		  .gpio_rx_en = 0, .gpio_out_level = 1, .gpio_tx_id = id } \
+	}, \
+} \
+
+#define FUNCTION_DES_DELAY_MS(ms) \
+{ \
+	.name = "DELAY_"#ms"MS", \
+	.group_names = serdes_gpio_groups, \
+	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
+	.data = (void *)(const struct serdes_function_data []) { \
+		{ .mdelay = ms, } \
+	}, \
+} \
+
+static struct pinctrl_pin_desc max96752_pins_desc[] = {
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO0, "MAX96752_GPIO0"),
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO1, "MAX96752_GPIO1"),
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO2, "MAX96752_GPIO2"),
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO3, "MAX96752_GPIO3"),
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO4, "MAX96752_GPIO4"),
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO5, "MAX96752_GPIO5"),
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO6, "MAX96752_GPIO6"),
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO7, "MAX96752_GPIO7"),
+
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO8, "MAX96752_GPIO8"),
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO9, "MAX96752_GPIO9"),
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO10, "MAX96752_GPIO10"),
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO11, "MAX96752_GPIO11"),
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO12, "MAX96752_GPIO12"),
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO13, "MAX96752_GPIO13"),
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO14, "MAX96752_GPIO14"),
+	PINCTRL_PIN(MAXIM_MAX96752_GPIO15, "MAX96752_GPIO15"),
 };
 
 static struct group_desc max96752_groups_desc[] = {
-	GROUP_DESC(MAX96752_MFP0),
-	GROUP_DESC(MAX96752_MFP1),
-	GROUP_DESC(MAX96752_MFP2),
-	GROUP_DESC(MAX96752_MFP3),
-	GROUP_DESC(MAX96752_MFP4),
-	GROUP_DESC(MAX96752_MFP5),
-	GROUP_DESC(MAX96752_MFP6),
-	GROUP_DESC(MAX96752_MFP7),
+	GROUP_DESC(MAX96752_GPIO0),
+	GROUP_DESC(MAX96752_GPIO1),
+	GROUP_DESC(MAX96752_GPIO2),
+	GROUP_DESC(MAX96752_GPIO3),
+	GROUP_DESC(MAX96752_GPIO4),
+	GROUP_DESC(MAX96752_GPIO5),
+	GROUP_DESC(MAX96752_GPIO6),
+	GROUP_DESC(MAX96752_GPIO7),
 
-	GROUP_DESC(MAX96752_MFP8),
-	GROUP_DESC(MAX96752_MFP9),
-	GROUP_DESC(MAX96752_MFP10),
-	GROUP_DESC(MAX96752_MFP11),
-	GROUP_DESC(MAX96752_MFP12),
-	GROUP_DESC(MAX96752_MFP13),
-	GROUP_DESC(MAX96752_MFP14),
-	GROUP_DESC(MAX96752_MFP15),
+	GROUP_DESC(MAX96752_GPIO8),
+	GROUP_DESC(MAX96752_GPIO9),
+	GROUP_DESC(MAX96752_GPIO10),
+	GROUP_DESC(MAX96752_GPIO11),
+	GROUP_DESC(MAX96752_GPIO12),
+	GROUP_DESC(MAX96752_GPIO13),
+	GROUP_DESC(MAX96752_GPIO14),
+	GROUP_DESC(MAX96752_GPIO15),
 };
 
 static struct function_desc max96752_functions_desc[] = {
-	FUNCTION_DESC_GPIO_INPUT(0),
-	FUNCTION_DESC_GPIO_INPUT(1),
-	FUNCTION_DESC_GPIO_INPUT(2),
-	FUNCTION_DESC_GPIO_INPUT(3),
-	FUNCTION_DESC_GPIO_INPUT(4),
-	FUNCTION_DESC_GPIO_INPUT(5),
-	FUNCTION_DESC_GPIO_INPUT(6),
-	FUNCTION_DESC_GPIO_INPUT(7),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(0),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(1),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(2),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(3),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(4),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(5),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(6),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(7),
 
-	FUNCTION_DESC_GPIO_INPUT(8),
-	FUNCTION_DESC_GPIO_INPUT(9),
-	FUNCTION_DESC_GPIO_INPUT(10),
-	FUNCTION_DESC_GPIO_INPUT(11),
-	FUNCTION_DESC_GPIO_INPUT(12),
-	FUNCTION_DESC_GPIO_INPUT(13),
-	FUNCTION_DESC_GPIO_INPUT(14),
-	FUNCTION_DESC_GPIO_INPUT(15),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(8),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(9),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(10),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(11),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(12),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(13),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(14),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(15),
 
-	FUNCTION_DESC_GPIO_OUTPUT(0),
-	FUNCTION_DESC_GPIO_OUTPUT(1),
-	FUNCTION_DESC_GPIO_OUTPUT(2),
-	FUNCTION_DESC_GPIO_OUTPUT(3),
-	FUNCTION_DESC_GPIO_OUTPUT(4),
-	FUNCTION_DESC_GPIO_OUTPUT(5),
-	FUNCTION_DESC_GPIO_OUTPUT(6),
-	FUNCTION_DESC_GPIO_OUTPUT(7),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(0),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(1),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(2),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(3),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(4),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(5),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(6),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(7),
 
-	FUNCTION_DESC_GPIO_OUTPUT(8),
-	FUNCTION_DESC_GPIO_OUTPUT(9),
-	FUNCTION_DESC_GPIO_OUTPUT(10),
-	FUNCTION_DESC_GPIO_OUTPUT(11),
-	FUNCTION_DESC_GPIO_OUTPUT(12),
-	FUNCTION_DESC_GPIO_OUTPUT(13),
-	FUNCTION_DESC_GPIO_OUTPUT(14),
-	FUNCTION_DESC_GPIO_OUTPUT(15),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(8),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(9),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(10),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(11),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(12),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(13),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(14),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(15),
 
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(0),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(1),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(2),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(3),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(4),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(5),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(6),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(7),
+
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(8),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(9),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(10),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(11),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(12),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(13),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(14),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(15),
+
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(0),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(1),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(2),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(3),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(4),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(5),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(6),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(7),
+
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(8),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(9),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(10),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(11),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(12),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(13),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(14),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(15),
+
+	FUNCTION_DES_DELAY_MS(10),
+	FUNCTION_DES_DELAY_MS(50),
+	FUNCTION_DES_DELAY_MS(100),
+	FUNCTION_DES_DELAY_MS(200),
+	FUNCTION_DES_DELAY_MS(500),
 };
 
 static struct serdes_chip_pinctrl_info max96752_pinctrl_info = {
@@ -205,24 +292,233 @@
 	.disable = max96752_panel_disable,
 };
 
-static int max96752_pinctrl_config_get(struct serdes *serdes,
-				       unsigned int pin,
-				       unsigned long *config)
+static int max96752_bridge_pre_enable(struct serdes *serdes)
 {
+	int ret = 0;
+
+	SERDES_DBG_CHIP("%s: serdes %s ret=%d\n", __func__,
+			serdes->chip_data->name, ret);
+	return ret;
+}
+
+static int max96752_bridge_post_disable(struct serdes *serdes)
+{
+	return 0;
+}
+
+static struct serdes_chip_bridge_ops max96752_bridge_ops = {
+	.enable = max96752_bridge_pre_enable,
+	.disable = max96752_bridge_post_disable,
+};
+
+
+static int max96752_pinctrl_set_mux(struct serdes *serdes,
+				    unsigned int function, unsigned int group)
+{
+	struct serdes_pinctrl *pinctrl = serdes->pinctrl;
+	struct function_desc *func;
+	struct group_desc *grp;
+	int i;
+	u16 ms;
+
+	func = pinmux_generic_get_function(pinctrl->pctl, function);
+	if (!func)
+		return -EINVAL;
+
+	grp = pinctrl_generic_get_group(pinctrl->pctl, group);
+	if (!grp)
+		return -EINVAL;
+
+	SERDES_DBG_CHIP("%s: serdes chip %s func=%s data=%p group=%s data=%p, num_pin=%d\n",
+			__func__, serdes->chip_data->name, func->name,
+			func->data, grp->name, grp->data, grp->num_pins);
+
+	if (func->data) {
+		struct serdes_function_data *fdata = func->data;
+
+		ms = fdata->mdelay;
+		for (i = 0; i < grp->num_pins; i++) {
+			if (!ms) {
+				serdes_set_bits(serdes, GPIO_A_REG(grp->pins[i] - pinctrl->pin_base),
+						GPIO_OUT_DIS | GPIO_RX_EN | GPIO_TX_EN | GPIO_OUT,
+						FIELD_PREP(GPIO_OUT_DIS, fdata->gpio_out_dis) |
+						FIELD_PREP(GPIO_RX_EN, fdata->gpio_rx_en) |
+						FIELD_PREP(GPIO_TX_EN, fdata->gpio_tx_en) |
+						FIELD_PREP(GPIO_OUT, fdata->gpio_out_level));
+				if (fdata->gpio_tx_en)
+					serdes_set_bits(serdes,
+							GPIO_B_REG(grp->pins[i] - pinctrl->pin_base),
+							GPIO_TX_ID,
+							FIELD_PREP(GPIO_TX_ID, fdata->gpio_tx_id));
+				if (fdata->gpio_rx_en)
+					serdes_set_bits(serdes,
+							GPIO_C_REG(grp->pins[i] - pinctrl->pin_base),
+							GPIO_RX_ID,
+							FIELD_PREP(GPIO_RX_ID, fdata->gpio_rx_id));
+			} else {
+				mdelay(ms);
+				SERDES_DBG_CHIP("%s: delay %d ms\n",
+						__func__, ms);
+			}
+		}
+	}
+
+	if (grp->data) {
+		struct serdes_group_data *gdata = grp->data;
+
+		for (i = 0; i < gdata->num_configs; i++) {
+			const struct config_desc *config = &gdata->configs[i];
+
+			serdes_set_bits(serdes, config->reg,
+					config->mask, config->val);
+		}
+	}
+
+	return 0;
+}
+
+static int max96752_pinctrl_config_get(struct serdes *serdes,
+				       unsigned int pin, unsigned long *config)
+{
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	unsigned int gpio_a_reg, gpio_b_reg;
+	u16 arg = 0;
+
+	serdes_reg_read(serdes, GPIO_A_REG(pin), &gpio_a_reg);
+	serdes_reg_read(serdes, GPIO_B_REG(pin), &gpio_b_reg);
+
+	SERDES_DBG_CHIP("%s: serdes chip %s pin=%d param=%d\n", __func__,
+			serdes->chip_data->name, pin, param);
+
+	switch (param) {
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		if (FIELD_GET(OUT_TYPE, gpio_b_reg))
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_DRIVE_PUSH_PULL:
+		if (!FIELD_GET(OUT_TYPE, gpio_b_reg))
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (FIELD_GET(PULL_UPDN_SEL, gpio_b_reg) != 0)
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (FIELD_GET(PULL_UPDN_SEL, gpio_b_reg) != 1)
+			return -EINVAL;
+		switch (FIELD_GET(RES_CFG, gpio_a_reg)) {
+		case 0:
+			arg = 40000;
+			break;
+		case 1:
+			arg = 10000;
+			break;
+		}
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if (FIELD_GET(PULL_UPDN_SEL, gpio_b_reg) != 2)
+			return -EINVAL;
+		switch (FIELD_GET(RES_CFG, gpio_a_reg)) {
+		case 0:
+			arg = 40000;
+			break;
+		case 1:
+			arg = 10000;
+			break;
+		}
+		break;
+	case PIN_CONFIG_OUTPUT:
+		if (FIELD_GET(GPIO_OUT_DIS, gpio_a_reg))
+			return -EINVAL;
+
+		arg = FIELD_GET(GPIO_OUT, gpio_a_reg);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	*config = pinconf_to_config_packed(param, arg);
+
 	return 0;
 }
 
 static int max96752_pinctrl_config_set(struct serdes *serdes,
-				       unsigned int pin,
-				       unsigned long *configs,
+				       unsigned int pin, unsigned long *configs,
 				       unsigned int num_configs)
 {
-	return 0;
-}
+	enum pin_config_param param;
+	u32 arg;
+	u8 res_cfg;
+	int i;
 
-static int max96752_pinctrl_set_mux(struct serdes *serdes, unsigned int func_selector,
-				    unsigned int group_selector)
-{
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		SERDES_DBG_CHIP("%s: serdes chip %s pin=%d param=%d\n", __func__,
+				serdes->chip_data->name, pin, param);
+
+		switch (param) {
+		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+			serdes_set_bits(serdes, GPIO_B_REG(pin),
+					OUT_TYPE, FIELD_PREP(OUT_TYPE, 0));
+			break;
+		case PIN_CONFIG_DRIVE_PUSH_PULL:
+			serdes_set_bits(serdes, GPIO_B_REG(pin),
+					OUT_TYPE, FIELD_PREP(OUT_TYPE, 1));
+			break;
+		case PIN_CONFIG_BIAS_DISABLE:
+			serdes_set_bits(serdes, GPIO_C_REG(pin),
+					PULL_UPDN_SEL,
+					FIELD_PREP(PULL_UPDN_SEL, 0));
+			break;
+		case PIN_CONFIG_BIAS_PULL_UP:
+			switch (arg) {
+			case 40000:
+				res_cfg = 0;
+				break;
+			case 1000000:
+				res_cfg = 1;
+				break;
+			default:
+				return -EINVAL;
+			}
+
+			serdes_set_bits(serdes, GPIO_A_REG(pin),
+					RES_CFG, FIELD_PREP(RES_CFG, res_cfg));
+			serdes_set_bits(serdes, GPIO_C_REG(pin),
+					PULL_UPDN_SEL,
+					FIELD_PREP(PULL_UPDN_SEL, 1));
+			break;
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			switch (arg) {
+			case 40000:
+				res_cfg = 0;
+				break;
+			case 1000000:
+				res_cfg = 1;
+				break;
+			default:
+				return -EINVAL;
+			}
+
+			serdes_set_bits(serdes, GPIO_A_REG(pin),
+					RES_CFG, FIELD_PREP(RES_CFG, res_cfg));
+			serdes_set_bits(serdes, GPIO_C_REG(pin),
+					PULL_UPDN_SEL,
+					FIELD_PREP(PULL_UPDN_SEL, 2));
+			break;
+		case PIN_CONFIG_OUTPUT:
+			serdes_set_bits(serdes, GPIO_A_REG(pin),
+					GPIO_OUT_DIS | GPIO_OUT,
+					FIELD_PREP(GPIO_OUT_DIS, 0) |
+					FIELD_PREP(GPIO_OUT, arg));
+			break;
+		default:
+			return -EOPNOTSUPP;
+		}
+	}
+
 	return 0;
 }
 
@@ -271,6 +567,37 @@
 	.to_irq = max96752_gpio_to_irq,
 };
 
+static int max96752_set_i2c_addr(struct serdes *serdes, int address, int link)
+{
+	int ret;
+
+	if (link == LINKA) {
+		/* TX_SRC_ID[1] = 0 */
+		ret = serdes_reg_write(serdes, 0x73, 0x31);
+		/* Receive packets with this stream ID = 0 */
+		ret = serdes_reg_write(serdes, 0x50, 0x00);
+		ret = serdes_reg_write(serdes, 0x00, address << 1);
+	} else if (link == LINKB) {
+		/* TX_SRC_ID[1] = 1 */
+		ret = serdes_reg_write(serdes, 0x73, 0x32);
+		/* Receive packets with this stream ID = 1 */
+		ret = serdes_reg_write(serdes, 0x50, 0x01);
+		ret = serdes_reg_write(serdes, 0x00, address << 1);
+	} else {
+		dev_info(serdes->dev, "link %d is error\n", link);
+		ret = -1;
+	}
+
+	SERDES_DBG_CHIP("%s: set serdes chip %s i2c 7bit address to 0x%x\n", __func__,
+			serdes->chip_data->name, address);
+
+	return ret;
+}
+
+static struct serdes_chip_split_ops max96752_split_ops = {
+	.set_i2c_addr = max96752_set_i2c_addr,
+};
+
 static int max96752_pm_suspend(struct serdes *serdes)
 {
 	return 0;
@@ -309,7 +636,9 @@
 	.regmap_config	= &max96752_regmap_config,
 	.pinctrl_info	= &max96752_pinctrl_info,
 	.panel_ops	= &max96752_panel_ops,
+	.bridge_ops	= &max96752_bridge_ops,
 	.pinctrl_ops	= &max96752_pinctrl_ops,
+	.split_ops	= &max96752_split_ops,
 	.gpio_ops	= &max96752_gpio_ops,
 	.pm_ops		= &max96752_pm_ops,
 	.irq_ops	= &max96752_irq_ops,
diff --git a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96752.h b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96752.h
index 079be4c..dc1e960 100644
--- a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96752.h
+++ b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96752.h
@@ -11,4 +11,35 @@
 #ifndef __MFD_SERDES_MAXIM_MAX96752_H__
 #define __MFD_SERDES_MAXIM_MAX96752_H__
 
+#define GPIO_A_REG(gpio)	(0x0200 + ((gpio) * 3))
+#define GPIO_B_REG(gpio)	(0x0201 + ((gpio) * 3))
+#define GPIO_C_REG(gpio)	(0x0202 + ((gpio) * 3))
+
+
+/* 0200h */
+#define RES_CFG			BIT(7)
+#define RSVD			BIT(6)
+#define TX_COMP_EN		BIT(5)
+#define GPIO_OUT		BIT(4)
+#define GPIO_IN			BIT(3)
+#define GPIO_RX_EN		BIT(2)
+#define GPIO_TX_EN		BIT(1)
+#define GPIO_OUT_DIS		BIT(0)
+
+/* 0201h */
+#define PULL_UPDN_SEL		GENMASK(7, 6)
+#define OUT_TYPE		BIT(5)
+#define GPIO_TX_ID		GENMASK(4, 0)
+
+/* 0202h */
+#define OVR_RES_CFG		BIT(7)
+#define GPIO_RX_ID		GENMASK(4, 0)
+
+enum link_mode {
+	DUAL_LINK,
+	LINKA,
+	LINKB,
+	SPLITTER_MODE,
+};
+
 #endif
diff --git a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96755.c b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96755.c
index c042eb3..0ea8ea0 100644
--- a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96755.c
+++ b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96755.c
@@ -34,7 +34,7 @@
 	.name = "max96755",
 	.reg_bits = 16,
 	.val_bits = 8,
-	.max_register = 0x8000,
+	.max_register = 0x2000,
 	.volatile_reg = max96755_volatile_reg,
 	.cache_type = REGCACHE_RBTREE,
 };
@@ -202,17 +202,17 @@
 
 #define FUNCTION_DESC_GPIO_INPUT(id) \
 { \
-	.name = "DES_GPIO"#id"_INPUT", \
+	.name = "DES_RXID"#id"_TO_SER", \
 	.group_names = serdes_gpio_groups, \
 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
 	.data = (void *)(const struct serdes_function_data []) { \
-		{ .gpio_rx_en = 1, .gpio_rx_id = id } \
+		{ .gpio_out_dis = 0, .gpio_rx_en = 1, .gpio_rx_id = id } \
 	}, \
 } \
 
 #define FUNCTION_DESC_GPIO_OUTPUT(id) \
 { \
-	.name = "DES_GPIO"#id"_OUTPUT", \
+	.name = "SER_TO_DES_TXID"#id, \
 	.group_names = serdes_gpio_groups, \
 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
 	.data = (void *)(const struct serdes_function_data []) { \
@@ -345,14 +345,23 @@
 {
 	u32 val;
 
-	if (serdes->lock_gpio)
-		return gpiod_get_value_cansleep(serdes->lock_gpio);
+	if (serdes->lock_gpio) {
+		val = gpiod_get_value_cansleep(serdes->lock_gpio);
+		SERDES_DBG_CHIP("%s: lock_gpio val=%d\n", __func__, val);
+		return val;
+	}
 
-	if (serdes_reg_read(serdes, 0x0013, &val))
+	if (serdes_reg_read(serdes, 0x0013, &val)) {
+		SERDES_DBG_CHIP("%s: false val=%d\n", __func__, val);
 		return false;
+	}
 
-	if (!FIELD_GET(LOCKED, val))
+	if (!FIELD_GET(LOCKED, val)) {
+		SERDES_DBG_CHIP("%s: false val=%d\n", __func__, val);
 		return false;
+	}
+
+	SERDES_DBG_CHIP("%s: return true\n", __func__);
 
 	return true;
 }
@@ -396,7 +405,7 @@
 
 out:
 	serdes_bridge->status = status;
-	SERDES_DBG_MFD("%s: status=%d\n", __func__, status);
+	SERDES_DBG_CHIP("%s: status=%d\n", __func__, status);
 	return status;
 }
 
diff --git a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96772.c b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96772.c
index c9b1394..2059962 100644
--- a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96772.c
+++ b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96772.c
@@ -32,23 +32,34 @@
 	.rd_table = &max96772_readable_table,
 };
 
-static int MAX96772_MFP0_pins[] = {0};
-static int MAX96772_MFP1_pins[] = {1};
-static int MAX96772_MFP2_pins[] = {2};
-static int MAX96772_MFP3_pins[] = {3};
-static int MAX96772_MFP4_pins[] = {4};
-static int MAX96772_MFP5_pins[] = {5};
-static int MAX96772_MFP6_pins[] = {6};
-static int MAX96772_MFP7_pins[] = {7};
+struct config_desc {
+	u16 reg;
+	u8 mask;
+	u8 val;
+};
 
-static int MAX96772_MFP8_pins[] = {8};
-static int MAX96772_MFP9_pins[] = {9};
-static int MAX96772_MFP10_pins[] = {10};
-static int MAX96772_MFP11_pins[] = {11};
-static int MAX96772_MFP12_pins[] = {12};
-static int MAX96772_MFP13_pins[] = {13};
-static int MAX96772_MFP14_pins[] = {14};
-static int MAX96772_MFP15_pins[] = {15};
+struct serdes_group_data {
+	const struct config_desc *configs;
+	int num_configs;
+};
+
+static int MAX96772_GPIO0_pins[] = {0};
+static int MAX96772_GPIO1_pins[] = {1};
+static int MAX96772_GPIO2_pins[] = {2};
+static int MAX96772_GPIO3_pins[] = {3};
+static int MAX96772_GPIO4_pins[] = {4};
+static int MAX96772_GPIO5_pins[] = {5};
+static int MAX96772_GPIO6_pins[] = {6};
+static int MAX96772_GPIO7_pins[] = {7};
+
+static int MAX96772_GPIO8_pins[] = {8};
+static int MAX96772_GPIO9_pins[] = {9};
+static int MAX96772_GPIO10_pins[] = {10};
+static int MAX96772_GPIO11_pins[] = {11};
+static int MAX96772_GPIO12_pins[] = {12};
+static int MAX96772_GPIO13_pins[] = {13};
+static int MAX96772_GPIO14_pins[] = {14};
+static int MAX96772_GPIO15_pins[] = {15};
 
 #define GROUP_DESC(nm) \
 { \
@@ -61,21 +72,24 @@
 	u8 gpio_out_dis:1;
 	u8 gpio_tx_en:1;
 	u8 gpio_rx_en:1;
+	u8 gpio_in_level:1;
+	u8 gpio_out_level:1;
 	u8 gpio_tx_id;
 	u8 gpio_rx_id;
+	u16 mdelay;
 };
 
 static const char *serdes_gpio_groups[] = {
-	"MAX96772_MFP0", "MAX96772_MFP1", "MAX96772_MFP2", "MAX96772_MFP3",
-	"MAX96772_MFP4", "MAX96772_MFP5", "MAX96772_MFP6", "MAX96772_MFP7",
+	"MAX96772_GPIO0", "MAX96772_GPIO1", "MAX96772_GPIO2", "MAX96772_GPIO3",
+	"MAX96772_GPIO4", "MAX96772_GPIO5", "MAX96772_GPIO6", "MAX96772_GPIO7",
 
-	"MAX96772_MFP8", "MAX96772_MFP9", "MAX96772_MFP10", "MAX96772_MFP11",
-	"MAX96772_MFP12", "MAX96772_MFP13", "MAX96772_MFP14", "MAX96772_MFP15",
+	"MAX96772_GPIO8", "MAX96772_GPIO9", "MAX96772_GPIO10", "MAX96772_GPIO11",
+	"MAX96772_GPIO12", "MAX96772_GPIO13", "MAX96772_GPIO14", "MAX96772_GPIO15",
 };
 
-#define FUNCTION_DESC_GPIO_INPUT(id) \
+#define FUNCTION_DESC_GPIO_INPUT_BYPASS(id) \
 { \
-	.name = "MFP"#id"_INPUT", \
+	.name = "SER_TO_DES_RXID"#id, \
 	.group_names = serdes_gpio_groups, \
 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
 	.data = (void *)(const struct serdes_function_data []) { \
@@ -83,9 +97,9 @@
 	}, \
 } \
 
-#define FUNCTION_DESC_GPIO_OUTPUT(id) \
+#define FUNCTION_DESC_GPIO_OUTPUT_BYPASS(id) \
 { \
-	.name = "MFP"#id"_OUTPUT", \
+	.name = "DES_TXID"#id"_TO_SER", \
 	.group_names = serdes_gpio_groups, \
 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
 	.data = (void *)(const struct serdes_function_data []) { \
@@ -93,83 +107,156 @@
 	}, \
 } \
 
-static struct pinctrl_pin_desc max96772_pins_desc[] = {
-	PINCTRL_PIN(MAXIM_MAX96772_MFP0, "MAX96772_MFP0"),
-	PINCTRL_PIN(MAXIM_MAX96772_MFP1, "MAX96772_MFP1"),
-	PINCTRL_PIN(MAXIM_MAX96772_MFP2, "MAX96772_MFP2"),
-	PINCTRL_PIN(MAXIM_MAX96772_MFP3, "MAX96772_MFP3"),
-	PINCTRL_PIN(MAXIM_MAX96772_MFP4, "MAX96772_MFP4"),
-	PINCTRL_PIN(MAXIM_MAX96772_MFP5, "MAX96772_MFP5"),
-	PINCTRL_PIN(MAXIM_MAX96772_MFP6, "MAX96772_MFP6"),
-	PINCTRL_PIN(MAXIM_MAX96772_MFP7, "MAX96772_MFP7"),
+#define FUNCTION_DESC_GPIO_OUTPUT_LOW(id) \
+{ \
+	.name = "DES_TXID"#id"_OUTPUT_LOW", \
+	.group_names = serdes_gpio_groups, \
+	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
+	.data = (void *)(const struct serdes_function_data []) { \
+		{ .gpio_out_dis = 0, .gpio_tx_en = 0, \
+		  .gpio_rx_en = 0, .gpio_out_level = 0, .gpio_tx_id = id } \
+	}, \
+} \
 
-	PINCTRL_PIN(MAXIM_MAX96772_MFP8, "MAX96772_MFP8"),
-	PINCTRL_PIN(MAXIM_MAX96772_MFP9, "MAX96772_MFP9"),
-	PINCTRL_PIN(MAXIM_MAX96772_MFP10, "MAX96772_MFP10"),
-	PINCTRL_PIN(MAXIM_MAX96772_MFP11, "MAX96772_MFP11"),
-	PINCTRL_PIN(MAXIM_MAX96772_MFP12, "MAX96772_MFP12"),
-	PINCTRL_PIN(MAXIM_MAX96772_MFP13, "MAX96772_MFP13"),
-	PINCTRL_PIN(MAXIM_MAX96772_MFP14, "MAX96772_MFP14"),
-	PINCTRL_PIN(MAXIM_MAX96772_MFP15, "MAX96772_MFP15"),
+#define FUNCTION_DESC_GPIO_OUTPUT_HIGH(id) \
+{ \
+	.name = "DES_TXID"#id"_OUTPUT_HIGH", \
+	.group_names = serdes_gpio_groups, \
+	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
+	.data = (void *)(const struct serdes_function_data []) { \
+		{ .gpio_out_dis = 0, .gpio_tx_en = 0, \
+		  .gpio_rx_en = 0, .gpio_out_level = 1, .gpio_tx_id = id } \
+	}, \
+} \
+
+#define FUNCTION_DES_DELAY_MS(ms) \
+{ \
+	.name = "DELAY_"#ms"MS", \
+	.group_names = serdes_gpio_groups, \
+	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
+	.data = (void *)(const struct serdes_function_data []) { \
+		{ .mdelay = ms, } \
+	}, \
+} \
+
+static struct pinctrl_pin_desc max96772_pins_desc[] = {
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO0, "MAX96772_GPIO0"),
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO1, "MAX96772_GPIO1"),
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO2, "MAX96772_GPIO2"),
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO3, "MAX96772_GPIO3"),
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO4, "MAX96772_GPIO4"),
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO5, "MAX96772_GPIO5"),
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO6, "MAX96772_GPIO6"),
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO7, "MAX96772_GPIO7"),
+
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO8, "MAX96772_GPIO8"),
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO9, "MAX96772_GPIO9"),
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO10, "MAX96772_GPIO10"),
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO11, "MAX96772_GPIO11"),
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO12, "MAX96772_GPIO12"),
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO13, "MAX96772_GPIO13"),
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO14, "MAX96772_GPIO14"),
+	PINCTRL_PIN(MAXIM_MAX96772_GPIO15, "MAX96772_GPIO15"),
 };
 
 static struct group_desc max96772_groups_desc[] = {
-	GROUP_DESC(MAX96772_MFP0),
-	GROUP_DESC(MAX96772_MFP1),
-	GROUP_DESC(MAX96772_MFP2),
-	GROUP_DESC(MAX96772_MFP3),
-	GROUP_DESC(MAX96772_MFP4),
-	GROUP_DESC(MAX96772_MFP5),
-	GROUP_DESC(MAX96772_MFP6),
-	GROUP_DESC(MAX96772_MFP7),
+	GROUP_DESC(MAX96772_GPIO0),
+	GROUP_DESC(MAX96772_GPIO1),
+	GROUP_DESC(MAX96772_GPIO2),
+	GROUP_DESC(MAX96772_GPIO3),
+	GROUP_DESC(MAX96772_GPIO4),
+	GROUP_DESC(MAX96772_GPIO5),
+	GROUP_DESC(MAX96772_GPIO6),
+	GROUP_DESC(MAX96772_GPIO7),
 
-	GROUP_DESC(MAX96772_MFP8),
-	GROUP_DESC(MAX96772_MFP9),
-	GROUP_DESC(MAX96772_MFP10),
-	GROUP_DESC(MAX96772_MFP11),
-	GROUP_DESC(MAX96772_MFP12),
-	GROUP_DESC(MAX96772_MFP13),
-	GROUP_DESC(MAX96772_MFP14),
-	GROUP_DESC(MAX96772_MFP15),
+	GROUP_DESC(MAX96772_GPIO8),
+	GROUP_DESC(MAX96772_GPIO9),
+	GROUP_DESC(MAX96772_GPIO10),
+	GROUP_DESC(MAX96772_GPIO11),
+	GROUP_DESC(MAX96772_GPIO12),
+	GROUP_DESC(MAX96772_GPIO13),
+	GROUP_DESC(MAX96772_GPIO14),
+	GROUP_DESC(MAX96772_GPIO15),
 };
 
 static struct function_desc max96772_functions_desc[] = {
-	FUNCTION_DESC_GPIO_INPUT(0),
-	FUNCTION_DESC_GPIO_INPUT(1),
-	FUNCTION_DESC_GPIO_INPUT(2),
-	FUNCTION_DESC_GPIO_INPUT(3),
-	FUNCTION_DESC_GPIO_INPUT(4),
-	FUNCTION_DESC_GPIO_INPUT(5),
-	FUNCTION_DESC_GPIO_INPUT(6),
-	FUNCTION_DESC_GPIO_INPUT(7),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(0),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(1),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(2),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(3),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(4),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(5),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(6),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(7),
 
-	FUNCTION_DESC_GPIO_INPUT(8),
-	FUNCTION_DESC_GPIO_INPUT(9),
-	FUNCTION_DESC_GPIO_INPUT(10),
-	FUNCTION_DESC_GPIO_INPUT(11),
-	FUNCTION_DESC_GPIO_INPUT(12),
-	FUNCTION_DESC_GPIO_INPUT(13),
-	FUNCTION_DESC_GPIO_INPUT(14),
-	FUNCTION_DESC_GPIO_INPUT(15),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(8),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(9),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(10),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(11),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(12),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(13),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(14),
+	FUNCTION_DESC_GPIO_INPUT_BYPASS(15),
 
-	FUNCTION_DESC_GPIO_OUTPUT(0),
-	FUNCTION_DESC_GPIO_OUTPUT(1),
-	FUNCTION_DESC_GPIO_OUTPUT(2),
-	FUNCTION_DESC_GPIO_OUTPUT(3),
-	FUNCTION_DESC_GPIO_OUTPUT(4),
-	FUNCTION_DESC_GPIO_OUTPUT(5),
-	FUNCTION_DESC_GPIO_OUTPUT(6),
-	FUNCTION_DESC_GPIO_OUTPUT(7),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(0),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(1),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(2),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(3),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(4),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(5),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(6),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(7),
 
-	FUNCTION_DESC_GPIO_OUTPUT(8),
-	FUNCTION_DESC_GPIO_OUTPUT(9),
-	FUNCTION_DESC_GPIO_OUTPUT(10),
-	FUNCTION_DESC_GPIO_OUTPUT(11),
-	FUNCTION_DESC_GPIO_OUTPUT(12),
-	FUNCTION_DESC_GPIO_OUTPUT(13),
-	FUNCTION_DESC_GPIO_OUTPUT(14),
-	FUNCTION_DESC_GPIO_OUTPUT(15),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(8),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(9),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(10),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(11),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(12),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(13),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(14),
+	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(15),
 
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(0),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(1),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(2),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(3),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(4),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(5),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(6),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(7),
+
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(8),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(9),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(10),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(11),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(12),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(13),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(14),
+	FUNCTION_DESC_GPIO_OUTPUT_LOW(15),
+
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(0),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(1),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(2),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(3),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(4),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(5),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(6),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(7),
+
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(8),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(9),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(10),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(11),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(12),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(13),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(14),
+	FUNCTION_DESC_GPIO_OUTPUT_HIGH(15),
+
+	FUNCTION_DES_DELAY_MS(10),
+	FUNCTION_DES_DELAY_MS(50),
+	FUNCTION_DES_DELAY_MS(100),
+	FUNCTION_DES_DELAY_MS(200),
+	FUNCTION_DES_DELAY_MS(500),
 };
 
 static struct serdes_chip_pinctrl_info max96772_pinctrl_info = {
@@ -181,6 +268,69 @@
 	.num_functions = ARRAY_SIZE(max96772_functions_desc),
 };
 
+static const struct reg_sequence max96772_clk_ref[3][14] = {
+	{
+		{ 0xe7b2, 0x50 },
+		{ 0xe7b3, 0x00 },
+		{ 0xe7b4, 0xcc },
+		{ 0xe7b5, 0x44 },
+		{ 0xe7b6, 0x81 },
+		{ 0xe7b7, 0x30 },
+		{ 0xe7b8, 0x07 },
+		{ 0xe7b9, 0x10 },
+		{ 0xe7ba, 0x01 },
+		{ 0xe7bb, 0x00 },
+		{ 0xe7bc, 0x00 },
+		{ 0xe7bd, 0x00 },
+		{ 0xe7be, 0x52 },
+		{ 0xe7bf, 0x00 },
+	}, {
+		{ 0xe7b2, 0x50 },
+		{ 0xe7b3, 0x00 },
+		{ 0xe7b4, 0x00 },
+		{ 0xe7b5, 0x40 },
+		{ 0xe7b6, 0x6c },
+		{ 0xe7b7, 0x20 },
+		{ 0xe7b8, 0x07 },
+		{ 0xe7b9, 0x00 },
+		{ 0xe7ba, 0x01 },
+		{ 0xe7bb, 0x00 },
+		{ 0xe7bc, 0x00 },
+		{ 0xe7bd, 0x00 },
+		{ 0xe7be, 0x52 },
+		{ 0xe7bf, 0x00 },
+	}, {
+		{ 0xe7b2, 0x30 },
+		{ 0xe7b3, 0x00 },
+		{ 0xe7b4, 0x00 },
+		{ 0xe7b5, 0x40 },
+		{ 0xe7b6, 0x6c },
+		{ 0xe7b7, 0x20 },
+		{ 0xe7b8, 0x14 },
+		{ 0xe7b9, 0x00 },
+		{ 0xe7ba, 0x2e },
+		{ 0xe7bb, 0x00 },
+		{ 0xe7bc, 0x00 },
+		{ 0xe7bd, 0x01 },
+		{ 0xe7be, 0x32 },
+		{ 0xe7bf, 0x00 },
+	}
+};
+
+static int max96772_aux_dpcd_read(struct serdes *serdes, unsigned int reg, unsigned int *value)
+{
+	serdes_reg_write(serdes, 0xe778, reg & 0xff);
+	serdes_reg_write(serdes, 0xe779, (reg >> 8) & 0xff);
+	serdes_reg_write(serdes, 0xe77c, (reg >> 16) & 0xff);
+	serdes_reg_write(serdes, 0xe776, 0x10);
+	serdes_reg_write(serdes, 0xe777, 0x80);
+	/* FIXME */
+	msleep(50);
+	serdes_reg_read(serdes, 0xe77a, value);
+
+	return 0;
+}
+
 static int max96772_panel_init(struct serdes *serdes)
 {
 	return 0;
@@ -188,6 +338,86 @@
 
 static int max96772_panel_prepare(struct serdes *serdes)
 {
+	const struct drm_display_mode *mode = &serdes->serdes_panel->mode;
+	u32 hfp, hsa, hbp, hact;
+	u32 vact, vsa, vfp, vbp;
+	u64 hwords, mvid;
+	bool hsync_pol, vsync_pol;
+
+	serdes_reg_write(serdes, 0xe790, serdes->serdes_panel->link_rate);
+	serdes_reg_write(serdes, 0xe792, serdes->serdes_panel->lane_count);
+
+	if (serdes->serdes_panel->ssc) {
+		serdes_reg_write(serdes, 0xe7b0, 0x01);
+		serdes_reg_write(serdes, 0xe7b1, 0x10);
+	} else {
+		serdes_reg_write(serdes, 0xe7b1, 0x00);
+	}
+
+	switch (serdes->serdes_panel->link_rate) {
+	case DP_LINK_BW_5_4:
+		serdes_multi_reg_write(serdes, max96772_clk_ref[2],
+				       ARRAY_SIZE(max96772_clk_ref[2]));
+		break;
+	case DP_LINK_BW_2_7:
+		serdes_multi_reg_write(serdes, max96772_clk_ref[1],
+				       ARRAY_SIZE(max96772_clk_ref[1]));
+		break;
+	case DP_LINK_BW_1_62:
+	default:
+		serdes_multi_reg_write(serdes, max96772_clk_ref[0],
+				       ARRAY_SIZE(max96772_clk_ref[0]));
+		break;
+	}
+
+	vact = mode->vdisplay;
+	vsa = mode->vsync_end - mode->vsync_start;
+	vfp = mode->vsync_start - mode->vdisplay;
+	vbp = mode->vtotal - mode->vsync_end;
+	hact = mode->hdisplay;
+	hsa = mode->hsync_end - mode->hsync_start;
+	hfp = mode->hsync_start - mode->hdisplay;
+	hbp = mode->htotal - mode->hsync_end;
+
+	serdes_reg_write(serdes, 0xe794, hact & 0xff);
+	serdes_reg_write(serdes, 0xe795, (hact >> 8) & 0xff);
+	serdes_reg_write(serdes, 0xe796, hfp & 0xff);
+	serdes_reg_write(serdes, 0xe797, (hfp >> 8) & 0xff);
+	serdes_reg_write(serdes, 0xe798, hsa & 0xff);
+	serdes_reg_write(serdes, 0xe799, (hsa >> 8) & 0xff);
+	serdes_reg_write(serdes, 0xe79a, hbp & 0xff);
+	serdes_reg_write(serdes, 0xe79b, (hbp >> 8) & 0xff);
+	serdes_reg_write(serdes, 0xe79c, vact & 0xff);
+	serdes_reg_write(serdes, 0xe79d, (vact >> 8) & 0xff);
+	serdes_reg_write(serdes, 0xe79e, vfp & 0xff);
+	serdes_reg_write(serdes, 0xe79f, (vfp >> 8) & 0xff);
+	serdes_reg_write(serdes, 0xe7a0, vsa & 0xff);
+	serdes_reg_write(serdes, 0xe7a1, (vsa >> 8) & 0xff);
+	serdes_reg_write(serdes, 0xe7a2, vbp & 0xff);
+	serdes_reg_write(serdes, 0xe7a3, (vbp >> 8) & 0xff);
+
+	hsync_pol = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
+	vsync_pol = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
+	serdes_reg_write(serdes, 0xe7ac, hsync_pol | (vsync_pol << 1));
+
+	/* NVID should always be set to 0x8000 */
+	serdes_reg_write(serdes, 0xe7a8, 0);
+	serdes_reg_write(serdes, 0xe7a9, 0x80);
+
+	/* HWORDS = ((HRES x bits / pixel) / 16) - LANE_COUNT */
+	hwords = DIV_ROUND_CLOSEST_ULL(hact * 24, 16) - serdes->serdes_panel->lane_count;
+	serdes_reg_write(serdes, 0xe7a4, hwords);
+	serdes_reg_write(serdes, 0xe7a5, hwords >> 8);
+
+	/* MVID = (PCLK x NVID) x 10 / Link Rate */
+	mvid = DIV_ROUND_CLOSEST_ULL((u64)mode->clock * 32768,
+				     drm_dp_bw_code_to_link_rate(serdes->serdes_panel->link_rate));
+	serdes_reg_write(serdes, 0xe7a6, mvid & 0xff);
+	serdes_reg_write(serdes, 0xe7a7, (mvid >> 8) & 0xff);
+
+	serdes_reg_write(serdes, 0xe7aa, 0x40);
+	serdes_reg_write(serdes, 0xe7ab, 0x00);
+
 	return 0;
 }
 
@@ -198,6 +428,31 @@
 
 static int max96772_panel_enable(struct serdes *serdes)
 {
+	u32 status[2];
+	u32 val;
+	int ret;
+
+	/* Run link training */
+	serdes_reg_write(serdes, 0xe776, 0x02);
+	serdes_reg_write(serdes, 0xe777, 0x80);
+
+	ret = regmap_read_poll_timeout(serdes->regmap, 0x07f0, val,
+				       val & 0x01, MSEC_PER_SEC,
+				       500 * MSEC_PER_SEC);
+	if (!ret)
+		return 0;
+
+	ret = max96772_aux_dpcd_read(serdes, DP_LANE0_1_STATUS, &status[0]);
+	if (ret)
+		return ret;
+
+	ret = max96772_aux_dpcd_read(serdes, DP_LANE2_3_STATUS, &status[1]);
+	if (ret)
+		return ret;
+
+	dev_err(serdes->dev, "Link Training failed: LANE0_1_STATUS=0x%02x, LANE2_3_STATUS=0x%02x\n",
+		status[0], status[1]);
+
 	return 0;
 }
 
@@ -214,24 +469,213 @@
 	.disable = max96772_panel_disable,
 };
 
-static int max96772_pinctrl_config_get(struct serdes *serdes,
-				       unsigned int pin,
-				       unsigned long *config)
+static int max96772_pinctrl_set_mux(struct serdes *serdes,
+				    unsigned int function, unsigned int group)
 {
+	struct serdes_pinctrl *pinctrl = serdes->pinctrl;
+	struct function_desc *func;
+	struct group_desc *grp;
+	int i;
+	u16 ms;
+
+	func = pinmux_generic_get_function(pinctrl->pctl, function);
+	if (!func)
+		return -EINVAL;
+
+	grp = pinctrl_generic_get_group(pinctrl->pctl, group);
+	if (!grp)
+		return -EINVAL;
+
+	SERDES_DBG_CHIP("%s: serdes chip %s func=%s data=%p group=%s data=%p, num_pin=%d\n",
+			__func__, serdes->chip_data->name, func->name,
+			func->data, grp->name, grp->data, grp->num_pins);
+
+	if (func->data) {
+		struct serdes_function_data *fdata = func->data;
+
+		ms = fdata->mdelay;
+		for (i = 0; i < grp->num_pins; i++) {
+			if (!ms) {
+				serdes_set_bits(serdes, GPIO_A_REG(grp->pins[i] - pinctrl->pin_base),
+						GPIO_OUT_DIS | GPIO_RX_EN | GPIO_TX_EN | GPIO_OUT,
+						FIELD_PREP(GPIO_OUT_DIS, fdata->gpio_out_dis) |
+						FIELD_PREP(GPIO_RX_EN, fdata->gpio_rx_en) |
+						FIELD_PREP(GPIO_TX_EN, fdata->gpio_tx_en) |
+						FIELD_PREP(GPIO_OUT, fdata->gpio_out_level));
+				if (fdata->gpio_tx_en)
+					serdes_set_bits(serdes,
+							GPIO_B_REG(grp->pins[i] - pinctrl->pin_base),
+							GPIO_TX_ID,
+							FIELD_PREP(GPIO_TX_ID, fdata->gpio_tx_id));
+				if (fdata->gpio_rx_en)
+					serdes_set_bits(serdes,
+							GPIO_C_REG(grp->pins[i] - pinctrl->pin_base),
+							GPIO_RX_ID,
+							FIELD_PREP(GPIO_RX_ID, fdata->gpio_rx_id));
+			} else {
+				mdelay(ms);
+				SERDES_DBG_CHIP("%s: delay %d ms\n",
+						__func__, ms);
+			}
+		}
+	}
+
+	if (grp->data) {
+		struct serdes_group_data *gdata = grp->data;
+
+		for (i = 0; i < gdata->num_configs; i++) {
+			const struct config_desc *config = &gdata->configs[i];
+
+			serdes_set_bits(serdes, config->reg,
+					config->mask, config->val);
+		}
+	}
+
+	return 0;
+}
+
+static int max96772_pinctrl_config_get(struct serdes *serdes,
+				       unsigned int pin, unsigned long *config)
+{
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	unsigned int gpio_a_reg, gpio_b_reg;
+	u16 arg = 0;
+
+	serdes_reg_read(serdes, GPIO_A_REG(pin), &gpio_a_reg);
+	serdes_reg_read(serdes, GPIO_B_REG(pin), &gpio_b_reg);
+
+	SERDES_DBG_CHIP("%s: serdes chip %s pin=%d param=%d\n", __func__,
+			serdes->chip_data->name, pin, param);
+
+	switch (param) {
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		if (FIELD_GET(OUT_TYPE, gpio_b_reg))
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_DRIVE_PUSH_PULL:
+		if (!FIELD_GET(OUT_TYPE, gpio_b_reg))
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (FIELD_GET(PULL_UPDN_SEL, gpio_b_reg) != 0)
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (FIELD_GET(PULL_UPDN_SEL, gpio_b_reg) != 1)
+			return -EINVAL;
+		switch (FIELD_GET(RES_CFG, gpio_a_reg)) {
+		case 0:
+			arg = 40000;
+			break;
+		case 1:
+			arg = 10000;
+			break;
+		}
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if (FIELD_GET(PULL_UPDN_SEL, gpio_b_reg) != 2)
+			return -EINVAL;
+		switch (FIELD_GET(RES_CFG, gpio_a_reg)) {
+		case 0:
+			arg = 40000;
+			break;
+		case 1:
+			arg = 10000;
+			break;
+		}
+		break;
+	case PIN_CONFIG_OUTPUT:
+		if (FIELD_GET(GPIO_OUT_DIS, gpio_a_reg))
+			return -EINVAL;
+
+		arg = FIELD_GET(GPIO_OUT, gpio_a_reg);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	*config = pinconf_to_config_packed(param, arg);
+
 	return 0;
 }
 
 static int max96772_pinctrl_config_set(struct serdes *serdes,
-				       unsigned int pin,
-				       unsigned long *configs,
+				       unsigned int pin, unsigned long *configs,
 				       unsigned int num_configs)
 {
-	return 0;
-}
+	enum pin_config_param param;
+	u32 arg;
+	u8 res_cfg;
+	int i;
 
-static int max96772_pinctrl_set_mux(struct serdes *serdes, unsigned int func_selector,
-				    unsigned int group_selector)
-{
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		SERDES_DBG_CHIP("%s: serdes chip %s pin=%d param=%d\n", __func__,
+				serdes->chip_data->name, pin, param);
+
+		switch (param) {
+		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+			serdes_set_bits(serdes, GPIO_B_REG(pin),
+					OUT_TYPE, FIELD_PREP(OUT_TYPE, 0));
+			break;
+		case PIN_CONFIG_DRIVE_PUSH_PULL:
+			serdes_set_bits(serdes, GPIO_B_REG(pin),
+					OUT_TYPE, FIELD_PREP(OUT_TYPE, 1));
+			break;
+		case PIN_CONFIG_BIAS_DISABLE:
+			serdes_set_bits(serdes, GPIO_C_REG(pin),
+					PULL_UPDN_SEL,
+					FIELD_PREP(PULL_UPDN_SEL, 0));
+			break;
+		case PIN_CONFIG_BIAS_PULL_UP:
+			switch (arg) {
+			case 40000:
+				res_cfg = 0;
+				break;
+			case 1000000:
+				res_cfg = 1;
+				break;
+			default:
+				return -EINVAL;
+			}
+
+			serdes_set_bits(serdes, GPIO_A_REG(pin),
+					RES_CFG, FIELD_PREP(RES_CFG, res_cfg));
+			serdes_set_bits(serdes, GPIO_C_REG(pin),
+					PULL_UPDN_SEL,
+					FIELD_PREP(PULL_UPDN_SEL, 1));
+			break;
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			switch (arg) {
+			case 40000:
+				res_cfg = 0;
+				break;
+			case 1000000:
+				res_cfg = 1;
+				break;
+			default:
+				return -EINVAL;
+			}
+
+			serdes_set_bits(serdes, GPIO_A_REG(pin),
+					RES_CFG, FIELD_PREP(RES_CFG, res_cfg));
+			serdes_set_bits(serdes, GPIO_C_REG(pin),
+					PULL_UPDN_SEL,
+					FIELD_PREP(PULL_UPDN_SEL, 2));
+			break;
+		case PIN_CONFIG_OUTPUT:
+			serdes_set_bits(serdes, GPIO_A_REG(pin),
+					GPIO_OUT_DIS | GPIO_OUT,
+					FIELD_PREP(GPIO_OUT_DIS, 0) |
+					FIELD_PREP(GPIO_OUT, arg));
+			break;
+		default:
+			return -EOPNOTSUPP;
+		}
+	}
+
 	return 0;
 }
 
diff --git a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96772.h b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96772.h
index 1a961e6..df5da53 100644
--- a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96772.h
+++ b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96772.h
@@ -11,4 +11,28 @@
 #ifndef __MFD_SERDES_MAXIM_MAX96772_H__
 #define __MFD_SERDES_MAXIM_MAX96772_H__
 
+#define GPIO_A_REG(gpio)	(0x02b0 + ((gpio) * 3))
+#define GPIO_B_REG(gpio)	(0x02b1 + ((gpio) * 3))
+#define GPIO_C_REG(gpio)	(0x02b2 + ((gpio) * 3))
+
+
+/* 02b0h */
+#define RES_CFG			BIT(7)
+#define RSVD			BIT(6)
+#define TX_COMP_EN		BIT(5)
+#define GPIO_OUT		BIT(4)
+#define GPIO_IN			BIT(3)
+#define GPIO_RX_EN		BIT(2)
+#define GPIO_TX_EN		BIT(1)
+#define GPIO_OUT_DIS		BIT(0)
+
+/* 02b1h */
+#define PULL_UPDN_SEL		GENMASK(7, 6)
+#define OUT_TYPE		BIT(5)
+#define GPIO_TX_ID		GENMASK(4, 0)
+
+/* 02b2h */
+#define OVR_RES_CFG		BIT(7)
+#define GPIO_RX_ID		GENMASK(4, 0)
+
 #endif
diff --git a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96789.c b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96789.c
index 494763e..d47e2d5 100644
--- a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96789.c
+++ b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96789.c
@@ -13,13 +13,17 @@
 static bool max96789_volatile_reg(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
-	case 0x0076:
-	case 0x0086:
-	case 0x0100:
-	case 0x0200 ... 0x02ce:
-	case 0x7000:
-	case 0x7070:
-	case 0x7074:
+	case 0x0002:
+	case 0x0010:
+	case 0x0013:
+	case 0x0053:
+	case 0x0057:
+	case 0x02be ... 0x02fc:
+	case 0x0311:
+	case 0x032a:
+	case 0x0330 ... 0x0331:
+	case 0x0385 ... 0x0387:
+	case 0x03a4 ... 0x03ae:
 		return false;
 	default:
 		return true;
@@ -30,9 +34,28 @@
 	.name = "max96789",
 	.reg_bits = 16,
 	.val_bits = 8,
-	.max_register = 0x8000,
+	.max_register = 0x2000,
 	.volatile_reg = max96789_volatile_reg,
 	.cache_type = REGCACHE_RBTREE,
+};
+
+struct serdes_function_data {
+	u8 gpio_out_dis:1;
+	u8 gpio_tx_en:1;
+	u8 gpio_rx_en:1;
+	u8 gpio_tx_id;
+	u8 gpio_rx_id;
+};
+
+struct config_desc {
+	u16 reg;
+	u8 mask;
+	u8 val;
+};
+
+struct serdes_group_data {
+	const struct config_desc *configs;
+	int num_configs;
 };
 
 static int MAX96789_MFP0_pins[] = {0};
@@ -58,6 +81,8 @@
 static int MAX96789_MFP18_pins[] = {18};
 static int MAX96789_MFP19_pins[] = {19};
 static int MAX96789_MFP20_pins[] = {20};
+static int MAX96789_I2C_pins[] = {19, 20};
+static int MAX96789_UART_pins[] = {19, 20};
 
 #define GROUP_DESC(nm) \
 { \
@@ -66,12 +91,91 @@
 	.num_pins = ARRAY_SIZE(nm ## _pins), \
 }
 
-struct serdes_function_data {
-	u8 gpio_out_dis:1;
-	u8 gpio_tx_en:1;
-	u8 gpio_rx_en:1;
-	u8 gpio_tx_id;
-	u8 gpio_rx_id;
+#define GROUP_DESC_CONFIG(nm) \
+{ \
+	.name = #nm, \
+	.pins = nm ## _pins, \
+	.num_pins = ARRAY_SIZE(nm ## _pins), \
+	.data = (void *)(const struct serdes_group_data []) { \
+		{ \
+			.configs = nm ## _configs, \
+			.num_configs = ARRAY_SIZE(nm ## _configs), \
+		} \
+	}, \
+}
+
+static const struct config_desc MAX96789_MFP0_configs[] = {
+	{ 0x0005, LOCK_EN, 0 },
+	{ 0x0048, LOC_MS_EN, 0 },
+};
+
+static const struct config_desc MAX96789_MFP1_configs[] = {
+	{ 0x0005, ERRB_EN, 0 },
+};
+
+static const struct config_desc MAX96789_MFP4_configs[] = {
+	{ 0x070, SPI_EN, 0 },
+};
+
+static const struct config_desc MAX96789_MFP5_configs[] = {
+	{ 0x006, RCLKEN, 0 },
+};
+
+static const struct config_desc MAX96789_MFP7_configs[] = {
+	{ 0x0002, AUD_TX_EN_X, 0 },
+	{ 0x0002, AUD_TX_EN_Y, 0 }
+};
+
+static const struct config_desc MAX96789_MFP8_configs[] = {
+	{ 0x0002, AUD_TX_EN_X, 0 },
+	{ 0x0002, AUD_TX_EN_Y, 0 }
+};
+
+static const struct config_desc MAX96789_MFP9_configs[] = {
+	{ 0x0002, AUD_TX_EN_X, 0 },
+	{ 0x0002, AUD_TX_EN_Y, 0 }
+};
+
+static const struct config_desc MAX96789_MFP10_configs[] = {
+	{ 0x0001, IIC_2_EN, 0 },
+	{ 0x0003, UART_2_EN, 0 },
+	{ 0x0140, AUD_RX_EN, 0 },
+};
+
+static const struct config_desc MAX96789_MFP11_configs[] = {
+	{ 0x0001, IIC_2_EN, 0 },
+	{ 0x0003, UART_2_EN, 0 },
+	{ 0x0140, AUD_RX_EN, 0 },
+};
+
+static const struct config_desc MAX96789_MFP12_configs[] = {
+	{ 0x0140, AUD_RX_EN, 0 },
+};
+
+static const struct config_desc MAX96789_MFP13_configs[] = {
+	{ 0x0005, PU_LF0, 0 },
+};
+
+static const struct config_desc MAX96789_MFP14_configs[] = {
+	{ 0x0005, PU_LF1, 0 },
+};
+
+static const struct config_desc MAX96789_MFP15_configs[] = {
+	{ 0x0005, PU_LF2, 0 },
+};
+
+static const struct config_desc MAX96789_MFP16_configs[] = {
+	{ 0x0005, PU_LF3, 0 },
+};
+
+static const struct config_desc MAX96789_MFP17_configs[] = {
+	{ 0x0001, IIC_1_EN, 0 },
+	{ 0x0003, UART_1_EN, 0 },
+};
+
+static const struct config_desc MAX96789_MFP18_configs[] = {
+	{ 0x0001, IIC_1_EN, 0 },
+	{ 0x0003, UART_1_EN, 0 },
 };
 
 static const char *serdes_gpio_groups[] = {
@@ -85,19 +189,29 @@
 	"MAX96789_MFP20",
 };
 
+static const char *MAX96789_I2C_groups[] = { "MAX96789_I2C" };
+static const char *MAX96789_UART_groups[] = { "MAX96789_UART" };
+
+#define FUNCTION_DESC(nm) \
+{ \
+	.name = #nm, \
+	.group_names = nm##_groups, \
+	.num_group_names = ARRAY_SIZE(nm##_groups), \
+} \
+
 #define FUNCTION_DESC_GPIO_INPUT(id) \
 { \
-	.name = "DES_GPIO"#id"_INPUT", \
+	.name = "DES_RXID"#id"_TO_SER", \
 	.group_names = serdes_gpio_groups, \
 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
 	.data = (void *)(const struct serdes_function_data []) { \
-		{ .gpio_rx_en = 1, .gpio_rx_id = id } \
+		{ .gpio_out_dis = 0, .gpio_rx_en = 1, .gpio_rx_id = id } \
 	}, \
 } \
 
 #define FUNCTION_DESC_GPIO_OUTPUT(id) \
 { \
-	.name = "DES_GPIO"#id"_OUTPUT", \
+	.name = "SER_TXID"#id"_TO_DES", \
 	.group_names = serdes_gpio_groups, \
 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
 	.data = (void *)(const struct serdes_function_data []) { \
@@ -132,29 +246,31 @@
 };
 
 static struct group_desc max96789_groups_desc[] = {
-	GROUP_DESC(MAX96789_MFP0),
-	GROUP_DESC(MAX96789_MFP1),
+	GROUP_DESC_CONFIG(MAX96789_MFP0),
+	GROUP_DESC_CONFIG(MAX96789_MFP1),
 	GROUP_DESC(MAX96789_MFP2),
 	GROUP_DESC(MAX96789_MFP3),
-	GROUP_DESC(MAX96789_MFP4),
-	GROUP_DESC(MAX96789_MFP5),
+	GROUP_DESC_CONFIG(MAX96789_MFP4),
+	GROUP_DESC_CONFIG(MAX96789_MFP5),
 	GROUP_DESC(MAX96789_MFP6),
-	GROUP_DESC(MAX96789_MFP7),
+	GROUP_DESC_CONFIG(MAX96789_MFP7),
 
-	GROUP_DESC(MAX96789_MFP8),
-	GROUP_DESC(MAX96789_MFP9),
-	GROUP_DESC(MAX96789_MFP10),
-	GROUP_DESC(MAX96789_MFP11),
-	GROUP_DESC(MAX96789_MFP12),
-	GROUP_DESC(MAX96789_MFP13),
-	GROUP_DESC(MAX96789_MFP14),
-	GROUP_DESC(MAX96789_MFP15),
+	GROUP_DESC_CONFIG(MAX96789_MFP8),
+	GROUP_DESC_CONFIG(MAX96789_MFP9),
+	GROUP_DESC_CONFIG(MAX96789_MFP10),
+	GROUP_DESC_CONFIG(MAX96789_MFP11),
+	GROUP_DESC_CONFIG(MAX96789_MFP12),
+	GROUP_DESC_CONFIG(MAX96789_MFP13),
+	GROUP_DESC_CONFIG(MAX96789_MFP14),
+	GROUP_DESC_CONFIG(MAX96789_MFP15),
 
-	GROUP_DESC(MAX96789_MFP16),
-	GROUP_DESC(MAX96789_MFP17),
-	GROUP_DESC(MAX96789_MFP18),
+	GROUP_DESC_CONFIG(MAX96789_MFP16),
+	GROUP_DESC_CONFIG(MAX96789_MFP17),
+	GROUP_DESC_CONFIG(MAX96789_MFP18),
 	GROUP_DESC(MAX96789_MFP19),
 	GROUP_DESC(MAX96789_MFP20),
+	GROUP_DESC(MAX96789_I2C),
+	GROUP_DESC(MAX96789_UART),
 };
 
 static struct function_desc max96789_functions_desc[] = {
@@ -206,6 +322,8 @@
 	FUNCTION_DESC_GPIO_OUTPUT(19),
 	FUNCTION_DESC_GPIO_OUTPUT(20),
 
+	FUNCTION_DESC(MAX96789_I2C),
+	FUNCTION_DESC(MAX96789_UART),
 };
 
 static struct serdes_chip_pinctrl_info max96789_pinctrl_info = {
@@ -222,40 +340,297 @@
 	return 0;
 }
 
+static bool max96789_bridge_link_locked(struct serdes *serdes)
+{
+	u32 val;
+
+	if (serdes->lock_gpio) {
+		val = gpiod_get_value_cansleep(serdes->lock_gpio);
+		SERDES_DBG_CHIP("%s: lock_gpio val=%d\n", __func__, val);
+		return val;
+	}
+
+	if (serdes_reg_read(serdes, 0x0013, &val)) {
+		SERDES_DBG_CHIP("%s: false val=%d\n", __func__, val);
+		return false;
+	}
+
+	if (!FIELD_GET(LOCKED, val)) {
+		SERDES_DBG_CHIP("%s: false val=%d\n", __func__, val);
+		return false;
+	}
+
+	SERDES_DBG_CHIP("%s: return true\n", __func__);
+
+	return true;
+}
+
+static int max96789_bridge_attach(struct serdes *serdes)
+{
+	if (max96789_bridge_link_locked(serdes))
+		serdes->serdes_bridge->status = connector_status_connected;
+	else
+		serdes->serdes_bridge->status = connector_status_disconnected;
+
+	return 0;
+}
+
+static enum drm_connector_status
+max96789_bridge_detect(struct serdes *serdes)
+{
+	struct serdes_bridge *serdes_bridge = serdes->serdes_bridge;
+	enum drm_connector_status status = connector_status_connected;
+
+	if (!drm_kms_helper_is_poll_worker())
+		return serdes_bridge->status;
+
+	if (!max96789_bridge_link_locked(serdes)) {
+		status = connector_status_disconnected;
+		goto out;
+	}
+
+	if (extcon_get_state(serdes->extcon, EXTCON_JACK_VIDEO_OUT)) {
+		if (atomic_cmpxchg(&serdes_bridge->triggered, 1, 0)) {
+			status = connector_status_disconnected;
+			goto out;
+		}
+
+	} else {
+		atomic_set(&serdes_bridge->triggered, 0);
+	}
+
+	if (serdes_bridge->next_bridge && (serdes_bridge->next_bridge->ops & DRM_BRIDGE_OP_DETECT))
+		return drm_bridge_detect(serdes_bridge->next_bridge);
+
+out:
+	serdes_bridge->status = status;
+	SERDES_DBG_CHIP("%s: status=%d\n", __func__, status);
+	return status;
+}
+
 static int max96789_bridge_enable(struct serdes *serdes)
 {
-	return 0;
+	int ret = 0;
+
+	SERDES_DBG_CHIP("%s: serdes chip %s ret=%d\n", __func__, serdes->chip_data->name, ret);
+	return ret;
 }
 
 static int max96789_bridge_disable(struct serdes *serdes)
 {
-	return 0;
+	int ret = 0;
+
+	return ret;
 }
 
 static struct serdes_chip_bridge_ops max96789_bridge_ops = {
 	.init = max96789_bridge_init,
+	.attach = max96789_bridge_attach,
+	.detect = max96789_bridge_detect,
 	.enable = max96789_bridge_enable,
 	.disable = max96789_bridge_disable,
 };
 
-static int max96789_pinctrl_config_get(struct serdes *serdes,
-				       unsigned int pin,
-				       unsigned long *config)
+static int max96789_pinctrl_set_mux(struct serdes *serdes,
+				    unsigned int function, unsigned int group)
 {
+	struct serdes_pinctrl *pinctrl = serdes->pinctrl;
+	struct function_desc *func;
+	struct group_desc *grp;
+	int i;
+
+	func = pinmux_generic_get_function(pinctrl->pctl, function);
+	if (!func)
+		return -EINVAL;
+
+	grp = pinctrl_generic_get_group(pinctrl->pctl, group);
+	if (!grp)
+		return -EINVAL;
+
+	SERDES_DBG_CHIP("%s: serdes chip %s func=%s data=%p group=%s data=%p, num_pin=%d\n",
+			__func__, serdes->chip_data->name, func->name,
+			func->data, grp->name, grp->data, grp->num_pins);
+
+	if (func->data) {
+		struct serdes_function_data *fdata = func->data;
+
+		for (i = 0; i < grp->num_pins; i++) {
+			serdes_set_bits(serdes, GPIO_A_REG(grp->pins[i] - pinctrl->pin_base),
+					GPIO_OUT_DIS | GPIO_RX_EN | GPIO_TX_EN,
+					FIELD_PREP(GPIO_OUT_DIS, fdata->gpio_out_dis) |
+					FIELD_PREP(GPIO_RX_EN, fdata->gpio_rx_en) |
+					FIELD_PREP(GPIO_TX_EN, fdata->gpio_tx_en));
+
+			if (fdata->gpio_tx_en)
+				serdes_set_bits(serdes,
+						GPIO_B_REG(grp->pins[i] - pinctrl->pin_base),
+						GPIO_TX_ID,
+						FIELD_PREP(GPIO_TX_ID, fdata->gpio_tx_id));
+
+			if (fdata->gpio_rx_en)
+				serdes_set_bits(serdes,
+						GPIO_C_REG(grp->pins[i] - pinctrl->pin_base),
+						GPIO_RX_ID,
+						FIELD_PREP(GPIO_RX_ID, fdata->gpio_rx_id));
+		}
+	}
+
+	if (grp->data) {
+		struct serdes_group_data *gdata = grp->data;
+
+		for (i = 0; i < gdata->num_configs; i++) {
+			const struct config_desc *config = &gdata->configs[i];
+
+			serdes_set_bits(serdes, config->reg,
+					config->mask, config->val);
+		}
+	}
+
+	return 0;
+}
+
+static int max96789_pinctrl_config_get(struct serdes *serdes,
+				       unsigned int pin, unsigned long *config)
+{
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	unsigned int gpio_a_reg, gpio_b_reg;
+	u16 arg = 0;
+
+	serdes_reg_read(serdes, GPIO_A_REG(pin), &gpio_a_reg);
+	serdes_reg_read(serdes, GPIO_B_REG(pin), &gpio_b_reg);
+
+	SERDES_DBG_CHIP("%s: serdes chip %s pin=%d param=%d\n", __func__,
+			serdes->chip_data->name, pin, param);
+
+	switch (param) {
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		if (FIELD_GET(OUT_TYPE, gpio_b_reg))
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_DRIVE_PUSH_PULL:
+		if (!FIELD_GET(OUT_TYPE, gpio_b_reg))
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (FIELD_GET(PULL_UPDN_SEL, gpio_b_reg) != 0)
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (FIELD_GET(PULL_UPDN_SEL, gpio_b_reg) != 1)
+			return -EINVAL;
+		switch (FIELD_GET(RES_CFG, gpio_a_reg)) {
+		case 0:
+			arg = 40000;
+			break;
+		case 1:
+			arg = 10000;
+			break;
+		}
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if (FIELD_GET(PULL_UPDN_SEL, gpio_b_reg) != 2)
+			return -EINVAL;
+		switch (FIELD_GET(RES_CFG, gpio_a_reg)) {
+		case 0:
+			arg = 40000;
+			break;
+		case 1:
+			arg = 10000;
+			break;
+		}
+		break;
+	case PIN_CONFIG_OUTPUT:
+		if (FIELD_GET(GPIO_OUT_DIS, gpio_a_reg))
+			return -EINVAL;
+
+		arg = FIELD_GET(GPIO_OUT, gpio_a_reg);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	*config = pinconf_to_config_packed(param, arg);
+
 	return 0;
 }
 
 static int max96789_pinctrl_config_set(struct serdes *serdes,
-				       unsigned int pin,
-				       unsigned long *configs,
+				       unsigned int pin, unsigned long *configs,
 				       unsigned int num_configs)
 {
-	return 0;
-}
+	enum pin_config_param param;
+	u32 arg;
+	u8 res_cfg;
+	int i;
 
-static int max96789_pinctrl_set_mux(struct serdes *serdes, unsigned int func_selector,
-				    unsigned int group_selector)
-{
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		SERDES_DBG_CHIP("%s: serdes chip %s pin=%d param=%d\n", __func__,
+				serdes->chip_data->name, pin, param);
+
+		switch (param) {
+		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+			serdes_set_bits(serdes, GPIO_B_REG(pin),
+					OUT_TYPE, FIELD_PREP(OUT_TYPE, 0));
+			break;
+		case PIN_CONFIG_DRIVE_PUSH_PULL:
+			serdes_set_bits(serdes, GPIO_B_REG(pin),
+					OUT_TYPE, FIELD_PREP(OUT_TYPE, 1));
+			break;
+		case PIN_CONFIG_BIAS_DISABLE:
+			serdes_set_bits(serdes, GPIO_C_REG(pin),
+					PULL_UPDN_SEL,
+					FIELD_PREP(PULL_UPDN_SEL, 0));
+			break;
+		case PIN_CONFIG_BIAS_PULL_UP:
+			switch (arg) {
+			case 40000:
+				res_cfg = 0;
+				break;
+			case 1000000:
+				res_cfg = 1;
+				break;
+			default:
+				return -EINVAL;
+			}
+
+			serdes_set_bits(serdes, GPIO_A_REG(pin),
+					RES_CFG, FIELD_PREP(RES_CFG, res_cfg));
+			serdes_set_bits(serdes, GPIO_C_REG(pin),
+					PULL_UPDN_SEL,
+					FIELD_PREP(PULL_UPDN_SEL, 1));
+			break;
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			switch (arg) {
+			case 40000:
+				res_cfg = 0;
+				break;
+			case 1000000:
+				res_cfg = 1;
+				break;
+			default:
+				return -EINVAL;
+			}
+
+			serdes_set_bits(serdes, GPIO_A_REG(pin),
+					RES_CFG, FIELD_PREP(RES_CFG, res_cfg));
+			serdes_set_bits(serdes, GPIO_C_REG(pin),
+					PULL_UPDN_SEL,
+					FIELD_PREP(PULL_UPDN_SEL, 2));
+			break;
+		case PIN_CONFIG_OUTPUT:
+			serdes_set_bits(serdes, GPIO_A_REG(pin),
+					GPIO_OUT_DIS | GPIO_OUT,
+					FIELD_PREP(GPIO_OUT_DIS, 0) |
+					FIELD_PREP(GPIO_OUT, arg));
+			break;
+		default:
+			return -EOPNOTSUPP;
+		}
+	}
+
 	return 0;
 }
 
@@ -304,6 +679,89 @@
 	.to_irq = max96789_gpio_to_irq,
 };
 
+static int max96789_select(struct serdes *serdes, int chan)
+{
+	u32 link_cfg, val;
+	int ret;
+
+	serdes_set_bits(serdes, 0x0001, DIS_REM_CC,
+			   FIELD_PREP(DIS_REM_CC, 0));
+
+	serdes_reg_read(serdes, 0x0010, &link_cfg);
+	if ((link_cfg & LINK_CFG) == SPLITTER_MODE)
+		SERDES_DBG_CHIP("%s: serdes chip %s already split mode cfg=0x%x\n", __func__,
+				serdes->chip_data->name, link_cfg);
+
+	if (chan == 0 && (link_cfg & LINK_CFG) != DUAL_LINK) {
+		serdes_set_bits(serdes, 0x0004,
+				   LINK_EN_B | LINK_EN_A,
+				   FIELD_PREP(LINK_EN_A, 1) |
+				   FIELD_PREP(LINK_EN_B, 1));
+		serdes_set_bits(serdes, 0x0010,
+				   RESET_ONESHOT | AUTO_LINK | LINK_CFG,
+				   FIELD_PREP(RESET_ONESHOT, 1) |
+				   FIELD_PREP(AUTO_LINK, 0) |
+				   FIELD_PREP(LINK_CFG, DUAL_LINK));
+		SERDES_DBG_CHIP("%s: change to use dual link\n", __func__);
+	} else if (chan == 1 && (link_cfg & LINK_CFG) != LINKA) {
+		serdes_set_bits(serdes, 0x0004,
+				   LINK_EN_B | LINK_EN_A,
+				   FIELD_PREP(LINK_EN_A, 1) |
+				   FIELD_PREP(LINK_EN_B, 0));
+		serdes_set_bits(serdes, 0x0010,
+				   RESET_ONESHOT | AUTO_LINK | LINK_CFG,
+				   FIELD_PREP(RESET_ONESHOT, 1) |
+				   FIELD_PREP(AUTO_LINK, 0) |
+				   FIELD_PREP(LINK_CFG, LINKA));
+		SERDES_DBG_CHIP("%s: change to use linkA\n", __func__);
+	} else if (chan == 2 && (link_cfg & LINK_CFG) != LINKB) {
+		serdes_set_bits(serdes, 0x0004,
+				   LINK_EN_B | LINK_EN_A,
+				   FIELD_PREP(LINK_EN_A, 0) |
+				   FIELD_PREP(LINK_EN_B, 1));
+		serdes_set_bits(serdes, 0x0010,
+				   RESET_ONESHOT | AUTO_LINK | LINK_CFG,
+				   FIELD_PREP(RESET_ONESHOT, 1) |
+				   FIELD_PREP(AUTO_LINK, 0) |
+				   FIELD_PREP(LINK_CFG, LINKB));
+		SERDES_DBG_CHIP("%s: change to use linkB\n", __func__);
+	} else if (chan == 3 && (link_cfg & LINK_CFG) != SPLITTER_MODE) {
+		serdes_set_bits(serdes, 0x0004,
+				   LINK_EN_B | LINK_EN_A,
+				   FIELD_PREP(LINK_EN_A, 1) |
+				   FIELD_PREP(LINK_EN_B, 1));
+		serdes_set_bits(serdes, 0x0010,
+				   RESET_ONESHOT | AUTO_LINK | LINK_CFG,
+				   FIELD_PREP(RESET_ONESHOT, 1) |
+				   FIELD_PREP(AUTO_LINK, 0) |
+				   FIELD_PREP(LINK_CFG, SPLITTER_MODE));
+		SERDES_DBG_CHIP("%s: change to use split mode\n", __func__);
+	}
+
+	ret = regmap_read_poll_timeout(serdes->regmap, 0x0013, val,
+				       val & LOCKED, 100,
+				       50 * USEC_PER_MSEC);
+	if (ret < 0) {
+		dev_err(serdes->dev, "GMSL2 link lock timeout\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int max96789_deselect(struct serdes *serdes, int chan)
+{
+	//serdes_set_bits(serdes, 0x0001, DIS_REM_CC,
+	//		   FIELD_PREP(DIS_REM_CC, 1));
+
+	return 0;
+}
+
+static struct serdes_chip_split_ops max96789_split_ops = {
+	.select = max96789_select,
+	.deselect = max96789_deselect,
+};
+
 static int max96789_pm_suspend(struct serdes *serdes)
 {
 	return 0;
@@ -344,6 +802,7 @@
 	.bridge_ops	= &max96789_bridge_ops,
 	.pinctrl_ops	= &max96789_pinctrl_ops,
 	.gpio_ops	= &max96789_gpio_ops,
+	.split_ops	= &max96789_split_ops,
 	.pm_ops		= &max96789_pm_ops,
 	.irq_ops	= &max96789_irq_ops,
 };
diff --git a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96789.h b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96789.h
index 1988b37..97beb6d 100644
--- a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96789.h
+++ b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96789.h
@@ -11,4 +11,188 @@
 #ifndef __MFD_SERDES_MAXIM_MAX96789_H__
 #define __MFD_SERDES_MAXIM_MAX96789_H__
 
+#include <linux/bitfield.h>
+
+#define GPIO_A_REG(gpio)	(0x02be + ((gpio) * 3))
+#define GPIO_B_REG(gpio)	(0x02bf + ((gpio) * 3))
+#define GPIO_C_REG(gpio)	(0x02c0 + ((gpio) * 3))
+
+/* 0000h */
+#define DEV_ADDR		GENMASK(7, 1)
+#define CFG_BLOCK		BIT(0)
+
+/* 0001h */
+#define IIC_2_EN		BIT(7)
+#define IIC_1_EN		BIT(6)
+#define DIS_REM_CC		BIT(4)
+#define TX_RATE			GENMASK(3, 2)
+
+/* 0002h */
+#define VID_TX_EN_U		BIT(7)
+#define VID_TX_EN_Z		BIT(6)
+#define VID_TX_EN_Y		BIT(5)
+#define VID_TX_EN_X		BIT(4)
+#define AUD_TX_EN_Y		BIT(3)
+#define AUD_TX_EN_X		BIT(2)
+
+/* 0003h */
+#define UART_2_EN		BIT(5)
+#define UART_1_EN		BIT(4)
+
+/* 0004h */
+#define GMSL2_B			BIT(7)
+#define GMSL2_A			BIT(6)
+#define LINK_EN_B		BIT(5)
+#define LINK_EN_A		BIT(4)
+#define AUD_TX_SRC_Y	BIT(1)
+#define AUD_TX_SRC_X	BIT(0)
+
+
+/* 0005h */
+#define LOCK_EN			BIT(7)
+#define ERRB_EN			BIT(6)
+#define PU_LF3			BIT(3)
+#define PU_LF2			BIT(2)
+#define PU_LF1			BIT(1)
+#define PU_LF0			BIT(0)
+
+/* 0006h */
+#define RCLKEN			BIT(5)
+
+/* 0010h */
+#define RESET_ALL		BIT(7)
+#define RESET_LINK		BIT(6)
+#define RESET_ONESHOT		BIT(5)
+#define AUTO_LINK		BIT(4)
+#define SLEEP			BIT(3)
+#define REG_ENABLE		BIT(2)
+#define LINK_CFG		GENMASK(1, 0)
+
+/* 0013h */
+#define LINK_MODE		GENMASK(5, 4)
+#define	LOCKED			BIT(3)
+
+/* 0026h */
+#define LF_1			GENMASK(6, 4)
+#define LF_0			GENMASK(2, 0)
+
+/* 0048h */
+#define REM_MS_EN		BIT(5)
+#define LOC_MS_EN		BIT(4)
+
+/* 0053h */
+#define TX_SPLIT_MASK_B		BIT(5)
+#define TX_SPLIT_MASK_A		BIT(4)
+#define TX_STR_SEL		GENMASK(1, 0)
+
+/* 0140h */
+#define AUD_RX_EN		BIT(0)
+
+/* 0170h */
+#define SPI_EN			BIT(0)
+
+/* 01e5h */
+#define PATGEN_MODE		GENMASK(1, 0)
+
+/* 02beh */
+#define RES_CFG			BIT(7)
+#define TX_PRIO			BIT(6)
+#define TX_COMP_EN		BIT(5)
+#define GPIO_OUT		BIT(4)
+#define GPIO_IN			BIT(3)
+#define GPIO_RX_EN		BIT(2)
+#define GPIO_TX_EN		BIT(1)
+#define GPIO_OUT_DIS		BIT(0)
+
+/* 02bfh */
+#define PULL_UPDN_SEL		GENMASK(7, 6)
+#define OUT_TYPE		BIT(5)
+#define GPIO_TX_ID		GENMASK(4, 0)
+
+/* 02c0h */
+#define OVR_RES_CFG		BIT(7)
+#define GPIO_RX_ID		GENMASK(4, 0)
+
+/* 0311h */
+#define START_PORTBU		BIT(7)
+#define START_PORTBZ		BIT(6)
+#define START_PORTBY		BIT(5)
+#define START_PORTBX		BIT(4)
+#define START_PORTAU		BIT(3)
+#define START_PORTAZ		BIT(2)
+#define START_PORTAY		BIT(1)
+#define START_PORTAX		BIT(0)
+
+/* 032ah */
+#define DV_LOCK			BIT(7)
+#define DV_SWP_AB		BIT(6)
+#define LINE_ALT		BIT(5)
+#define DV_CONV			BIT(2)
+#define DV_SPL			BIT(1)
+#define DV_EN			BIT(0)
+
+/* 0330h */
+#define PHY_CONFIG		GENMASK(2, 0)
+#define MIPI_RX_RESET		BIT(3)
+
+/* 0331h */
+#define NUM_LANES		GENMASK(1, 0)
+
+/* 0385h */
+#define DPI_HSYNC_WIDTH_L	GENMASK(7, 0)
+
+/* 0386h */
+#define DPI_VYSNC_WIDTH_L	GENMASK(7, 0)
+
+/* 0387h */
+#define	DPI_HSYNC_WIDTH_H	GENMASK(3, 0)
+#define DPI_VSYNC_WIDTH_H	GENMASK(7, 4)
+
+/* 03a4h */
+#define DPI_DE_SKEW_SEL		BIT(1)
+#define DPI_DESKEW_EN		BIT(0)
+
+/* 03a5h */
+#define DPI_VFP_L		GENMASK(7, 0)
+
+/* 03a6h */
+#define DPI_VFP_H		GENMASK(3, 0)
+#define DPI_VBP_L		GENMASK(7, 4)
+
+/* 03a7h */
+#define DPI_VBP_H		GENMASK(7, 0)
+
+/* 03a8h */
+#define DPI_VACT_L		GENMASK(7, 0)
+
+/* 03a9h */
+#define DPI_VACT_H		GENMASK(3, 0)
+
+/* 03aah */
+#define DPI_HFP_L		GENMASK(7, 0)
+
+/* 03abh */
+#define DPI_HFP_H		GENMASK(3, 0)
+#define DPI_HBP_L		GENMASK(7, 4)
+
+/* 03ach */
+#define DPI_HBP_H		GENMASK(7, 0)
+
+/* 03adh */
+#define DPI_HACT_L		GENMASK(7, 0)
+
+/* 03aeh */
+#define DPI_HACT_H		GENMASK(4, 0)
+
+/* 055dh */
+#define VS_DET			BIT(5)
+#define HS_DET			BIT(4)
+
+enum link_mode {
+	DUAL_LINK,
+	LINKA,
+	LINKB,
+	SPLITTER_MODE,
+};
+
 #endif
diff --git a/kernel/drivers/mfd/display-serdes/rohm/rohm-bu18rl82.c b/kernel/drivers/mfd/display-serdes/rohm/rohm-bu18rl82.c
index d0e8f71..385b266 100644
--- a/kernel/drivers/mfd/display-serdes/rohm/rohm-bu18rl82.c
+++ b/kernel/drivers/mfd/display-serdes/rohm/rohm-bu18rl82.c
@@ -45,6 +45,7 @@
 struct serdes_function_data {
 	u8 gpio_rx_en:1;
 	u16 gpio_id;
+	u16 mdelay;
 };
 
 static const char *serdes_gpio_groups[] = {
@@ -71,6 +72,16 @@
 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
 	.data = (void *)(const struct serdes_function_data []) { \
 		{ .gpio_rx_en = 0, .gpio_id = id + 2 } \
+	}, \
+} \
+
+#define FUNCTION_DES_DELAY_MS(ms) \
+{ \
+	.name = "DELAY_"#ms"MS", \
+	.group_names = serdes_gpio_groups, \
+	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
+	.data = (void *)(const struct serdes_function_data []) { \
+		{ .mdelay = ms, } \
 	}, \
 } \
 
@@ -154,6 +165,12 @@
 
 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(),
 	FUNCTION_DESC_GPIO_OUTPUT_LOW(),
+
+	FUNCTION_DES_DELAY_MS(10),
+	FUNCTION_DES_DELAY_MS(50),
+	FUNCTION_DES_DELAY_MS(100),
+	FUNCTION_DES_DELAY_MS(200),
+	FUNCTION_DES_DELAY_MS(500),
 };
 
 static struct serdes_chip_pinctrl_info bu18rl82_pinctrl_info = {
@@ -203,34 +220,33 @@
 
 static int bu18rl82_bridge_init(struct serdes *serdes)
 {
-	return 0;
-
 	bu18rl82_bridge_swrst(serdes);
 
 	return 0;
 }
 
-static int bu18rl82_bridge_enable(struct serdes *serdes)
+static int bu18rl82_bridge_pre_enable(struct serdes *serdes)
 {
 	int ret = 0;
 
 	/* 1:enable 0:disable */
 	bu18rl82_enable_hwint(serdes, 0);
 
+	msleep(100);
+
 	SERDES_DBG_CHIP("%s: serdes %s ret=%d\n", __func__,
 			serdes->chip_data->name, ret);
 	return ret;
 }
 
-static int bu18rl82_bridge_disable(struct serdes *serdes)
+static int bu18rl82_bridge_post_disable(struct serdes *serdes)
 {
 	return 0;
 }
 
 static struct serdes_chip_bridge_ops bu18rl82_bridge_ops = {
-	.init = bu18rl82_bridge_init,
-	.enable = bu18rl82_bridge_enable,
-	.disable = bu18rl82_bridge_disable,
+	.enable = bu18rl82_bridge_pre_enable,
+	.disable = bu18rl82_bridge_post_disable,
 };
 
 static int bu18rl82_pinctrl_config_get(struct serdes *serdes,
@@ -320,6 +336,7 @@
 	struct function_desc *func;
 	struct group_desc *grp;
 	int i, offset;
+	u16 ms;
 
 	func = pinmux_generic_get_function(pinctrl->pctl, function);
 	if (!func)
@@ -335,6 +352,7 @@
 
 	if (func->data) {
 		struct serdes_function_data *fdata = func->data;
+		ms = fdata->mdelay;
 
 		for (i = 0; i < grp->num_pins; i++) {
 			offset = grp->pins[i] - pinctrl->pin_base;
@@ -344,22 +362,29 @@
 			else
 				SERDES_DBG_CHIP("%s: serdes chip %s gpio_id=0x%x, offset=%d\n",
 						__func__, serdes->chip_data->name, fdata->gpio_id, offset);
-			serdes_set_bits(serdes, bu18rl82_gpio_oen[offset].reg,
-					bu18rl82_gpio_oen[offset].mask,
-					FIELD_PREP(BIT(3), fdata->gpio_rx_en));
 
-			serdes_set_bits(serdes, bu18rl82_gpio_id_low[offset].reg,
-					bu18rl82_gpio_id_low[offset].mask,
-					FIELD_PREP(GENMASK(7, 0),
-					(fdata->gpio_id & 0xff)));
+			if (!ms) {
+				serdes_set_bits(serdes, bu18rl82_gpio_oen[offset].reg,
+						bu18rl82_gpio_oen[offset].mask,
+						FIELD_PREP(BIT(3), fdata->gpio_rx_en));
 
-			serdes_set_bits(serdes, bu18rl82_gpio_id_high[offset].reg,
-					bu18rl82_gpio_id_high[offset].mask,
-					FIELD_PREP(GENMASK(2, 0),
-					((fdata->gpio_id >> 8) & 0x7)));
-			serdes_set_bits(serdes, bu18rl82_gpio_pden[offset].reg,
-					bu18rl82_gpio_pden[offset].mask,
-					FIELD_PREP(BIT(4), 0));
+				serdes_set_bits(serdes, bu18rl82_gpio_id_low[offset].reg,
+						bu18rl82_gpio_id_low[offset].mask,
+						FIELD_PREP(GENMASK(7, 0),
+						(fdata->gpio_id & 0xff)));
+
+				serdes_set_bits(serdes, bu18rl82_gpio_id_high[offset].reg,
+						bu18rl82_gpio_id_high[offset].mask,
+						FIELD_PREP(GENMASK(2, 0),
+						((fdata->gpio_id >> 8) & 0x7)));
+				serdes_set_bits(serdes, bu18rl82_gpio_pden[offset].reg,
+						bu18rl82_gpio_pden[offset].mask,
+						FIELD_PREP(BIT(4), 0));
+			} else {
+				mdelay(ms);
+				SERDES_DBG_CHIP("%s: delay %d ms\n",
+						__func__, ms);
+			}
 		}
 	}
 
@@ -447,6 +472,7 @@
 	.serdes_id	= ROHM_ID_BU18RL82,
 	.bridge_type	= TYPE_BRIDGE_BRIDGE,
 	.connector_type	= DRM_MODE_CONNECTOR_LVDS,
+	.chip_init	= bu18rl82_bridge_init,
 	.regmap_config	= &bu18rl82_regmap_config,
 	.pinctrl_info	= &bu18rl82_pinctrl_info,
 	.bridge_ops	= &bu18rl82_bridge_ops,
diff --git a/kernel/drivers/mfd/display-serdes/rohm/rohm-bu18tl82.c b/kernel/drivers/mfd/display-serdes/rohm/rohm-bu18tl82.c
index 824ea38..1e23cd4 100644
--- a/kernel/drivers/mfd/display-serdes/rohm/rohm-bu18tl82.c
+++ b/kernel/drivers/mfd/display-serdes/rohm/rohm-bu18tl82.c
@@ -146,8 +146,6 @@
 	struct device *dev = serdes->dev;
 	int ret;
 
-	return;
-
 	ret = serdes_reg_write(serdes, BU18TL82_REG_SWRST_INTERNAL, 0x00ef);
 	if (ret < 0)
 		dev_err(dev, "%s: failed to reset serdes 0x11 ret=%d\n", __func__, ret);
@@ -229,7 +227,6 @@
 }
 
 static struct serdes_chip_bridge_ops bu18tl82_bridge_ops = {
-	.init = bu18tl82_bridge_init,
 	.get_modes = bu18tl82_bridge_get_modes,
 	.pre_enable = bu18tl82_bridge_pre_enable,
 	.enable = bu18tl82_bridge_enable,
@@ -445,9 +442,10 @@
 	.name		= "bu18tl82",
 	.serdes_type	= TYPE_SER,
 	.serdes_id	= ROHM_ID_BU18TL82,
-	.sequence_init = 1,
+	.sequence_init	= 1,
 	.bridge_type	= TYPE_BRIDGE_BRIDGE,
 	.connector_type	= DRM_MODE_CONNECTOR_eDP,
+	.chip_init	= bu18tl82_bridge_init,
 	.regmap_config	= &bu18tl82_regmap_config,
 	.pinctrl_info	= &bu18tl82_pinctrl_info,
 	.bridge_ops	= &bu18tl82_bridge_ops,
diff --git a/kernel/drivers/mfd/display-serdes/serdes-bridge-split.c b/kernel/drivers/mfd/display-serdes/serdes-bridge-split.c
new file mode 100644
index 0000000..38d9469
--- /dev/null
+++ b/kernel/drivers/mfd/display-serdes/serdes-bridge-split.c
@@ -0,0 +1,371 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * serdes-bridge.c  --  drm bridge access for different serdes chips
+ *
+ * Copyright (c) 2023-2028 Rockchip Electronics Co. Ltd.
+ *
+ * Author: luowei <lw@rock-chips.com>
+ */
+
+#include "core.h"
+
+static struct serdes_bridge_split *to_serdes_bridge_split(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct serdes_bridge_split, base_bridge);
+}
+
+static struct mipi_dsi_device *serdes_attach_dsi(struct serdes_bridge_split *serdes_bridge_split,
+						 struct device_node *remote_node)
+{
+	struct mipi_dsi_device_info info = { "serdes", 0, NULL };
+	struct serdes *serdes = serdes_bridge_split->parent;
+	struct mipi_dsi_device *dsi;
+	struct mipi_dsi_host *host;
+	int ret;
+
+	if (serdes->chip_data->name)
+		memcpy(&info.type, serdes->chip_data->name, ARRAY_SIZE(info.type));
+
+	SERDES_DBG_MFD("%s: type=%s, name=%s\n", __func__,
+		       info.type, serdes->chip_data->name);
+
+	host = of_find_mipi_dsi_host_by_node(remote_node);
+	if (!host) {
+		dev_err(serdes_bridge_split->dev, "failed to find serdes dsi host\n");
+		return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	dsi = mipi_dsi_device_register_full(host, &info);
+	if (IS_ERR(dsi)) {
+		dev_err(serdes_bridge_split->dev, "failed to create serdes dsi device\n");
+		return dsi;
+	}
+
+	dsi->lanes = 4;
+	dsi->format = MIPI_DSI_FMT_RGB888;
+
+	if (serdes->chip_data->name) {
+		if ((!strcmp(serdes->chip_data->name, "bu18tl82")) ||
+		    (!strcmp(serdes->chip_data->name, "bu18rl82"))) {
+			dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+					  MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET;
+			SERDES_DBG_MFD("%s: %s dsi_mode MIPI_DSI_MODE_VIDEO_BURST 0x%lx\n",
+				       __func__, serdes->chip_data->name, dsi->mode_flags);
+		} else {
+			dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
+			SERDES_DBG_MFD("%s: %s dsi_mode MIPI_DSI_MODE_VIDEO_SYNC_PULSE 0x%lx\n",
+			       __func__, serdes->chip_data->name, dsi->mode_flags);
+		}
+	} else {
+		dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
+		SERDES_DBG_MFD("%s: %s dsi_mode MIPI_DSI_MODE_VIDEO_SYNC_PULSE 0x%lx\n",
+			   __func__, serdes->chip_data->name, dsi->mode_flags);
+	}
+
+	ret = mipi_dsi_attach(dsi);
+	if (ret < 0) {
+		dev_err(serdes_bridge_split->dev, "failed to attach serdes dsi to host\n");
+		mipi_dsi_device_unregister(dsi);
+		return ERR_PTR(ret);
+	}
+
+	return dsi;
+}
+
+static int serdes_bridge_split_attach(struct drm_bridge *bridge,
+				enum drm_bridge_attach_flags flags)
+{
+	struct serdes_bridge_split *serdes_bridge_split = to_serdes_bridge_split(bridge);
+	struct serdes *serdes = serdes_bridge_split->parent;
+	int ret = 0;
+
+	ret = drm_of_find_panel_or_bridge(bridge->of_node, 1, -1,
+					  &serdes_bridge_split->panel,
+					  &serdes_bridge_split->next_bridge);
+	if (ret) {
+		dev_err(serdes_bridge_split->dev->parent,
+			"failed to find serdes bridge, ret=%d\n", ret);
+		return ret;
+	}
+
+	if (serdes_bridge_split->sel_mipi) {
+		dev_info(serdes_bridge_split->dev->parent, "serdes sel_mipi %d\n",
+			 serdes_bridge_split->sel_mipi);
+		/* Attach primary DSI */
+		serdes_bridge_split->dsi = serdes_attach_dsi(serdes_bridge_split,
+							     serdes_bridge_split->remote_node);
+		if (IS_ERR(serdes_bridge_split->dsi))
+			return PTR_ERR(serdes_bridge_split->dsi);
+	}
+
+	if (serdes_bridge_split->next_bridge) {
+		ret = drm_bridge_attach(bridge->encoder, serdes_bridge_split->next_bridge,
+					bridge, flags);
+		if (ret) {
+			if (serdes_bridge_split->sel_mipi)
+				mipi_dsi_device_unregister(serdes_bridge_split->dsi);
+
+			dev_err(serdes_bridge_split->dev->parent,
+				"failed to attach bridge, ret=%d\n", ret);
+			return ret;
+		}
+	}
+
+	if (serdes->chip_data->bridge_ops->attach)
+		ret = serdes->chip_data->bridge_ops->attach(serdes);
+
+	SERDES_DBG_MFD("%s: ret=%d\n", __func__, ret);
+
+	return ret;
+}
+
+static void serdes_bridge_split_detach(struct drm_bridge *bridge)
+{
+	struct serdes_bridge_split *serdes_bridge_split = to_serdes_bridge_split(bridge);
+
+	if (serdes_bridge_split->sel_mipi) {
+		mipi_dsi_detach(serdes_bridge_split->dsi);
+		mipi_dsi_device_unregister(serdes_bridge_split->dsi);
+	}
+
+	SERDES_DBG_MFD("%s\n", __func__);
+}
+
+static void serdes_bridge_split_disable(struct drm_bridge *bridge)
+{
+	struct serdes_bridge_split *serdes_bridge_split = to_serdes_bridge_split(bridge);
+	struct serdes *serdes = serdes_bridge_split->parent;
+	int ret = 0;
+
+	if (serdes_bridge_split->panel)
+		drm_panel_disable(serdes_bridge_split->panel);
+
+	if (serdes->chip_data->bridge_ops->disable)
+		ret = serdes->chip_data->bridge_ops->disable(serdes);
+
+	extcon_set_state_sync(serdes->extcon, EXTCON_JACK_VIDEO_OUT, false);
+
+	SERDES_DBG_MFD("%s: ret=%d\n", __func__, ret);
+}
+
+static void serdes_bridge_split_post_disable(struct drm_bridge *bridge)
+{
+	struct serdes_bridge_split *serdes_bridge_split = to_serdes_bridge_split(bridge);
+	struct serdes *serdes = serdes_bridge_split->parent;
+	int ret = 0;
+
+	serdes_set_pinctrl_sleep(serdes);
+
+	if (serdes_bridge_split->panel)
+		ret = drm_panel_unprepare(serdes_bridge_split->panel);
+
+	if (serdes->chip_data->bridge_ops->post_disable)
+		ret = serdes->chip_data->bridge_ops->post_disable(serdes);
+
+	SERDES_DBG_MFD("%s: ret=%d\n", __func__, ret);
+}
+
+static void serdes_bridge_split_pre_enable(struct drm_bridge *bridge)
+{
+	struct serdes_bridge_split *serdes_bridge_split = to_serdes_bridge_split(bridge);
+	struct serdes *serdes = serdes_bridge_split->parent;
+	int ret = 0;
+
+	if (serdes->chip_data->bridge_ops->init)
+		ret = serdes->chip_data->bridge_ops->init(serdes);
+
+	if (serdes->chip_data->serdes_type == TYPE_DES) {
+		if (serdes->chip_data->chip_init)
+			serdes->chip_data->chip_init(serdes);
+		ret = serdes_i2c_set_sequence(serdes);
+	}
+
+	if (serdes->chip_data->bridge_ops->pre_enable)
+		ret = serdes->chip_data->bridge_ops->pre_enable(serdes);
+
+	if (serdes_bridge_split->panel)
+		ret = drm_panel_prepare(serdes_bridge_split->panel);
+
+	serdes_set_pinctrl_default(serdes);
+
+	SERDES_DBG_MFD("%s: %s ret=%d\n", __func__, dev_name(serdes->dev), ret);
+}
+
+static void serdes_bridge_split_enable(struct drm_bridge *bridge)
+{
+	struct serdes_bridge_split *serdes_bridge_split = to_serdes_bridge_split(bridge);
+	struct serdes *serdes = serdes_bridge_split->parent;
+	int ret = 0;
+
+	if (serdes_bridge_split->panel)
+		ret = drm_panel_enable(serdes_bridge_split->panel);
+
+	if (serdes->chip_data->bridge_ops->enable)
+		ret = serdes->chip_data->bridge_ops->enable(serdes);
+
+	if (!ret) {
+		extcon_set_state_sync(serdes->extcon, EXTCON_JACK_VIDEO_OUT, true);
+		SERDES_DBG_MFD("%s: extcon is true\n", __func__);
+	}
+
+	SERDES_DBG_MFD("%s: %s-%s ret=%d\n", __func__, dev_name(serdes->dev),
+		       serdes->chip_data->name, ret);
+}
+
+static enum drm_connector_status
+serdes_bridge_split_detect(struct drm_bridge *bridge)
+{
+	struct serdes_bridge_split *serdes_bridge_split = to_serdes_bridge_split(bridge);
+	struct serdes *serdes = serdes_bridge_split->parent;
+	enum drm_connector_status status = connector_status_connected;
+
+	if (serdes->chip_data->bridge_ops->detect)
+		status = serdes->chip_data->bridge_ops->detect(serdes);
+
+	return status;
+}
+
+static int serdes_bridge_split_get_modes(struct drm_bridge *bridge,
+				   struct drm_connector *connector)
+{
+	struct serdes_bridge_split *serdes_bridge_split = to_serdes_bridge_split(bridge);
+	struct serdes *serdes = serdes_bridge_split->parent;
+	int ret = 0;
+
+	if (serdes->chip_data->bridge_ops->get_modes)
+		ret = serdes->chip_data->bridge_ops->get_modes(serdes);
+
+	if (serdes_bridge_split->next_bridge)
+		ret = drm_bridge_get_modes(serdes_bridge_split->next_bridge, connector);
+
+	if (serdes_bridge_split->panel)
+		ret = drm_panel_get_modes(serdes_bridge_split->panel, connector);
+
+	SERDES_DBG_MFD("%s:name=%s, node=%s\n", __func__,
+		       serdes->chip_data->name, serdes_bridge_split->dev->of_node->name);
+
+	return ret;
+}
+
+static const struct drm_bridge_funcs serdes_bridge_split_funcs = {
+	.attach = serdes_bridge_split_attach,
+	.detach = serdes_bridge_split_detach,
+	.disable = serdes_bridge_split_disable,
+	.post_disable = serdes_bridge_split_post_disable,
+	.pre_enable = serdes_bridge_split_pre_enable,
+	.enable = serdes_bridge_split_enable,
+	.detect = serdes_bridge_split_detect,
+	.get_modes = serdes_bridge_split_get_modes,
+	.atomic_get_input_bus_fmts = drm_atomic_helper_bridge_propagate_bus_fmt,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+};
+
+static int serdes_bridge_split_probe(struct platform_device *pdev)
+{
+	struct serdes *serdes = dev_get_drvdata(pdev->dev.parent);
+	struct device *dev = &pdev->dev;
+	struct serdes_bridge_split *serdes_bridge_split;
+
+	if (!serdes->dev)
+		return -1;
+
+	serdes_bridge_split = devm_kzalloc(dev, sizeof(*serdes_bridge_split), GFP_KERNEL);
+	if (!serdes_bridge_split)
+		return -ENOMEM;
+
+	serdes->serdes_bridge_split = serdes_bridge_split;
+	serdes_bridge_split->dev = dev;
+	serdes_bridge_split->parent = dev_get_drvdata(dev->parent);
+	platform_set_drvdata(pdev, serdes_bridge_split);
+	serdes_bridge_split->regmap = dev_get_regmap(dev->parent, NULL);
+	if (!serdes_bridge_split->regmap)
+		return dev_err_probe(dev, -ENODEV, "failed to get serdes regmap\n");
+
+	serdes_bridge_split->sel_mipi = of_property_read_bool(dev->parent->of_node, "sel-mipi");
+	SERDES_DBG_MFD("%s: sel_mipi=%d\n", __func__, serdes_bridge_split->sel_mipi);
+
+	serdes_bridge_split->base_bridge.of_node = dev->parent->of_node;
+	serdes_bridge_split->remote_node = of_graph_get_remote_node(dev->parent->of_node, 0, -1);
+	if (!serdes_bridge_split->remote_node) {
+		serdes_bridge_split->base_bridge.of_node = dev->of_node;
+		SERDES_DBG_MFD("warning: failed to get remote node for serdes on %s\n",
+			       dev_name(dev->parent));
+		serdes_bridge_split->remote_node = of_graph_get_remote_node(dev->of_node, 0, -1);
+		if (!serdes_bridge_split->remote_node) {
+			return dev_err_probe(dev, -ENODEV,
+				     "failed to get remote node for serdes dsi\n");
+		}
+	}
+
+	serdes_bridge_split->base_bridge.funcs = &serdes_bridge_split_funcs;
+	serdes_bridge_split->base_bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_MODES;
+
+	if (serdes_bridge_split->sel_mipi) {
+		serdes_bridge_split->base_bridge.type = DRM_MODE_CONNECTOR_DSI;
+		SERDES_DBG_MFD("%s: type DRM_MODE_CONNECTOR_DSI\n", __func__);
+	} else if (serdes_bridge_split->parent->chip_data->connector_type) {
+		serdes_bridge_split->base_bridge.type =
+			serdes_bridge_split->parent->chip_data->connector_type;
+		SERDES_DBG_MFD("%s: type %d\n", __func__, serdes_bridge_split->base_bridge.type);
+	} else {
+		serdes_bridge_split->base_bridge.type = DRM_MODE_CONNECTOR_eDP;
+		SERDES_DBG_MFD("%s: type DRM_MODE_CONNECTOR_LVDS\n", __func__);
+	}
+
+	drm_bridge_add(&serdes_bridge_split->base_bridge);
+
+	dev_info(dev, "serdes %s, %s successful mipi=%d, of_node=%s\n",
+		 serdes->chip_data->name, __func__, serdes_bridge_split->sel_mipi,
+		 serdes_bridge_split->base_bridge.of_node->name);
+
+	return 0;
+}
+
+static int serdes_bridge_split_remove(struct platform_device *pdev)
+{
+	struct serdes_bridge_split *serdes_bridge_split = platform_get_drvdata(pdev);
+
+	drm_bridge_remove(&serdes_bridge_split->base_bridge);
+
+	return 0;
+}
+
+static const struct of_device_id serdes_bridge_split_of_match[] = {
+	{ .compatible = "rohm,bu18tl82-bridge-split", },
+	{ .compatible = "rohm,bu18rl82-bridge-split", },
+	{ .compatible = "maxim,max96745-bridge-split", },
+	{ .compatible = "maxim,max96755-bridge-split", },
+	{ .compatible = "maxim,max96752-bridge-split", },
+	{ .compatible = "maxim,max96789-bridge-split", },
+	{ .compatible = "rockchip,rkx111-bridge-split", },
+	{ .compatible = "rockchip,rkx121-bridge-split", },
+	{ }
+};
+
+static struct platform_driver serdes_bridge_split_driver = {
+	.driver = {
+		.name = "serdes-bridge-split",
+		.of_match_table = of_match_ptr(serdes_bridge_split_of_match),
+	},
+	.probe = serdes_bridge_split_probe,
+	.remove = serdes_bridge_split_remove,
+};
+
+static int __init serdes_bridge_split_init(void)
+{
+	return platform_driver_register(&serdes_bridge_split_driver);
+}
+device_initcall(serdes_bridge_split_init);
+
+static void __exit serdes_bridge_split_exit(void)
+{
+	platform_driver_unregister(&serdes_bridge_split_driver);
+}
+module_exit(serdes_bridge_split_exit);
+
+MODULE_AUTHOR("Luo Wei <lw@rock-chips.com>");
+MODULE_DESCRIPTION("display bridge interface for different serdes");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:serdes-bridge-split");
diff --git a/kernel/drivers/mfd/display-serdes/serdes-bridge.c b/kernel/drivers/mfd/display-serdes/serdes-bridge.c
index 235d130..6dc82a8 100644
--- a/kernel/drivers/mfd/display-serdes/serdes-bridge.c
+++ b/kernel/drivers/mfd/display-serdes/serdes-bridge.c
@@ -15,7 +15,7 @@
 }
 
 static struct mipi_dsi_device *serdes_attach_dsi(struct serdes_bridge *serdes_bridge,
-						 struct device_node *dsi_node)
+						 struct device_node *remote_node)
 {
 	struct mipi_dsi_device_info info = { "serdes", 0, NULL };
 	struct serdes *serdes = serdes_bridge->parent;
@@ -29,7 +29,7 @@
 	SERDES_DBG_MFD("%s: type=%s, name=%s\n", __func__,
 		       info.type, serdes->chip_data->name);
 
-	host = of_find_mipi_dsi_host_by_node(dsi_node);
+	host = of_find_mipi_dsi_host_by_node(remote_node);
 	if (!host) {
 		dev_err(serdes_bridge->dev, "failed to find serdes dsi host\n");
 		return ERR_PTR(-EPROBE_DEFER);
@@ -49,13 +49,17 @@
 		    (!strcmp(serdes->chip_data->name, "bu18rl82"))) {
 			dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
 					  MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET;
-			SERDES_DBG_MFD("%s: dsi mode MIPI_DSI_MODE_VIDEO_BURST 0x%lx\n",
-				       __func__, dsi->mode_flags);
+			SERDES_DBG_MFD("%s: %s dsi_mode MIPI_DSI_MODE_VIDEO_BURST 0x%lx\n",
+				       __func__, serdes->chip_data->name, dsi->mode_flags);
+		} else {
+			dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
+			SERDES_DBG_MFD("%s: %s dsi_mode MIPI_DSI_MODE_VIDEO_SYNC_PULSE 0x%lx\n",
+			       __func__, serdes->chip_data->name, dsi->mode_flags);
 		}
 	} else {
 		dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
-		SERDES_DBG_MFD("%s: dsi mode MIPI_DSI_MODE_VIDEO_SYNC_PULSE 0x%lx\n",
-			       __func__, dsi->mode_flags);
+		SERDES_DBG_MFD("%s: %s dsi_mode MIPI_DSI_MODE_VIDEO_SYNC_PULSE 0x%lx\n",
+			   __func__, serdes->chip_data->name, dsi->mode_flags);
 	}
 
 	ret = mipi_dsi_attach(dsi);
@@ -86,7 +90,7 @@
 		dev_info(serdes_bridge->dev->parent, "serdes sel_mipi %d\n",
 			 serdes_bridge->sel_mipi);
 		/* Attach primary DSI */
-		serdes_bridge->dsi = serdes_attach_dsi(serdes_bridge, serdes_bridge->dsi_node);
+		serdes_bridge->dsi = serdes_attach_dsi(serdes_bridge, serdes_bridge->remote_node);
 		if (IS_ERR(serdes_bridge->dsi))
 			return PTR_ERR(serdes_bridge->dsi);
 	}
@@ -167,14 +171,17 @@
 	if (serdes->chip_data->bridge_ops->init)
 		ret = serdes->chip_data->bridge_ops->init(serdes);
 
-	if (serdes->chip_data->serdes_type == TYPE_DES)
-		serdes_i2c_set_sequence(serdes);
-
-	if (serdes_bridge->panel)
-		ret = drm_panel_prepare(serdes_bridge->panel);
+	if (serdes->chip_data->serdes_type == TYPE_DES) {
+		if (serdes->chip_data->chip_init)
+			serdes->chip_data->chip_init(serdes);
+		ret = serdes_i2c_set_sequence(serdes);
+	}
 
 	if (serdes->chip_data->bridge_ops->pre_enable)
 		ret = serdes->chip_data->bridge_ops->pre_enable(serdes);
+
+	if (serdes_bridge->panel)
+		ret = drm_panel_prepare(serdes_bridge->panel);
 
 	serdes_set_pinctrl_default(serdes);
 
@@ -198,7 +205,8 @@
 		SERDES_DBG_MFD("%s: extcon is true\n", __func__);
 	}
 
-	SERDES_DBG_MFD("%s: %s ret=%d\n", __func__, dev_name(serdes->dev), ret);
+	SERDES_DBG_MFD("%s: %s-%s ret=%d\n", __func__, dev_name(serdes->dev),
+		       serdes->chip_data->name, ret);
 }
 
 static enum drm_connector_status
@@ -230,8 +238,8 @@
 	if (serdes_bridge->panel)
 		ret = drm_panel_get_modes(serdes_bridge->panel, connector);
 
-	SERDES_DBG_MFD("%s:name=%s, type=%d\n", __func__,
-		       serdes->chip_data->name, serdes->type);
+	SERDES_DBG_MFD("%s:name=%s, node=%s\n", __func__,
+		       serdes->chip_data->name, serdes_bridge->dev->of_node->name);
 
 	return ret;
 }
@@ -273,17 +281,22 @@
 		return dev_err_probe(dev, -ENODEV, "failed to get serdes regmap\n");
 
 	serdes_bridge->sel_mipi = of_property_read_bool(dev->parent->of_node, "sel-mipi");
-	if (serdes_bridge->sel_mipi) {
-		serdes_bridge->dsi_node = of_graph_get_remote_node(dev->parent->of_node, 0, -1);
-		if (!serdes_bridge->dsi_node)
-			return dev_err_probe(dev->parent, -ENODEV,
-					     "failed to get remote node for serdes dsi\n");
+	SERDES_DBG_MFD("%s: sel_mipi=%d\n", __func__, serdes_bridge->sel_mipi);
 
-		SERDES_DBG_MFD("%s: sel_mipi=%d\n", __func__, serdes_bridge->sel_mipi);
+	serdes_bridge->base_bridge.of_node = dev->parent->of_node;
+	serdes_bridge->remote_node = of_graph_get_remote_node(dev->parent->of_node, 0, -1);
+	if (!serdes_bridge->remote_node) {
+		serdes_bridge->base_bridge.of_node = dev->of_node;
+		SERDES_DBG_MFD("warning: failed to get remote node for serdes on %s\n",
+			       dev_name(dev->parent));
+		serdes_bridge->remote_node = of_graph_get_remote_node(dev->of_node, 0, -1);
+		if (!serdes_bridge->remote_node) {
+			return dev_err_probe(dev, -ENODEV,
+				     "failed to get remote node for serdes dsi\n");
+		}
 	}
 
 	serdes_bridge->base_bridge.funcs = &serdes_bridge_funcs;
-	serdes_bridge->base_bridge.of_node = dev->parent->of_node;
 	serdes_bridge->base_bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_MODES;
 
 	if (serdes_bridge->sel_mipi) {
@@ -291,7 +304,7 @@
 		SERDES_DBG_MFD("%s: type DRM_MODE_CONNECTOR_DSI\n", __func__);
 	} else if (serdes_bridge->parent->chip_data->connector_type) {
 		serdes_bridge->base_bridge.type = serdes_bridge->parent->chip_data->connector_type;
-		SERDES_DBG_MFD("%s: type 0x%x\n", __func__, serdes_bridge->base_bridge.type);
+		SERDES_DBG_MFD("%s: type %d\n", __func__, serdes_bridge->base_bridge.type);
 	} else {
 		serdes_bridge->base_bridge.type = DRM_MODE_CONNECTOR_eDP;
 		SERDES_DBG_MFD("%s: type DRM_MODE_CONNECTOR_LVDS\n", __func__);
@@ -319,9 +332,8 @@
 	{ .compatible = "rohm,bu18tl82-bridge", },
 	{ .compatible = "rohm,bu18rl82-bridge", },
 	{ .compatible = "maxim,max96745-bridge", },
-	{ .compatible = "maxim,max96752-bridge", },
 	{ .compatible = "maxim,max96755-bridge", },
-	{ .compatible = "maxim,max96772-bridge", },
+	{ .compatible = "maxim,max96789-bridge", },
 	{ .compatible = "rockchip,rkx111-bridge", },
 	{ .compatible = "rockchip,rkx121-bridge", },
 	{ }
diff --git a/kernel/drivers/mfd/display-serdes/serdes-core.c b/kernel/drivers/mfd/display-serdes/serdes-core.c
index 5ef62f8..3d9a6e6 100644
--- a/kernel/drivers/mfd/display-serdes/serdes-core.c
+++ b/kernel/drivers/mfd/display-serdes/serdes-core.c
@@ -62,6 +62,10 @@
 		.name = "serdes-bridge",
 		.of_compatible = "maxim,max96789-bridge",
 	},
+	{
+		.name = "serdes-bridge-split",
+		.of_compatible = "maxim,max96789-bridge-split",
+	},
 };
 
 static const struct mfd_cell serdes_max96752_devs[] = {
@@ -72,6 +76,10 @@
 	{
 		.name = "serdes-panel",
 		.of_compatible = "maxim,max96752-panel",
+	},
+	{
+		.name = "serdes-panel-split",
+		.of_compatible = "maxim,max96752-panel-split",
 	},
 };
 
@@ -127,8 +135,8 @@
 	int ret;
 
 	ret = regmap_read(serdes->regmap, reg, val);
-	SERDES_DBG_I2C("%s %s Read Reg%04x %04x\n", __func__,
-		       serdes->chip_data->name, reg, *val);
+	SERDES_DBG_I2C("%s %s %s Read Reg%04x %04x ret=%d\n", __func__, dev_name(serdes->dev),
+		       serdes->chip_data->name, reg, *val, ret);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(serdes_reg_read);
@@ -148,8 +156,9 @@
 
 	ret = regmap_bulk_read(serdes->regmap, reg, buf, count);
 	for (i = 0; i < count; i++) {
-		SERDES_DBG_I2C("%s %s %s Read Reg%04x %04x\n", __func__, dev_name(serdes->dev),
-			       serdes->chip_data->name, reg + i, buf[i]);
+		SERDES_DBG_I2C("%s %s %s Read Reg%04x %04x ret=%d\n",
+			       __func__, dev_name(serdes->dev),
+			       serdes->chip_data->name, reg + i, buf[i], ret);
 	}
 
 	return ret;
@@ -166,9 +175,10 @@
 
 	mutex_lock(&serdes->io_lock);
 	for (i = 0; i < count; i++) {
-		SERDES_DBG_I2C("%s %s %s Write Reg%04x %04x\n", __func__, dev_name(serdes->dev),
-			       serdes->chip_data->name, reg, buf[i]);
 		ret = regmap_write(serdes->regmap, reg, buf[i]);
+		SERDES_DBG_I2C("%s %s %s Write Reg%04x %04x ret=%d\n",
+			       __func__, dev_name(serdes->dev),
+			       serdes->chip_data->name, reg, buf[i], ret);
 		if (ret != 0) {
 			mutex_unlock(&serdes->io_lock);
 			return ret;
@@ -193,12 +203,11 @@
 
 	SERDES_DBG_I2C("%s %s %s num=%d\n", __func__, dev_name(serdes->dev),
 		       serdes->chip_data->name, num_regs);
-	for (i = 0; i < num_regs; i++) {
-		SERDES_DBG_I2C("serdes %s Write Reg%04x %04x\n",
-			       serdes->chip_data->name, regs[i].reg, regs[i].def);
-	}
-
 	ret = regmap_multi_reg_write(serdes->regmap, regs, num_regs);
+	for (i = 0; i < num_regs; i++) {
+		SERDES_DBG_I2C("serdes %s Write Reg%04x %04x ret=%d\n",
+			       serdes->chip_data->name, regs[i].reg, regs[i].def, ret);
+	}
 
 	return ret;
 }
@@ -216,9 +225,9 @@
 {
 	int ret;
 
-	SERDES_DBG_I2C("%s %s %s Write Reg%04x %04x)\n", __func__, dev_name(serdes->dev),
-		       serdes->chip_data->name, reg, val);
 	ret = regmap_write(serdes->regmap, reg, val);
+	SERDES_DBG_I2C("%s %s %s Write Reg%04x %04x ret=%d\n", __func__, dev_name(serdes->dev),
+		       serdes->chip_data->name, reg, val, ret);
 	if (ret != 0)
 		return ret;
 
@@ -322,7 +331,14 @@
 		ret = pinctrl_select_state(serdes->pinctrl_node, serdes->pins_default);
 		if (ret)
 			dev_err(serdes->dev, "could not set default pins\n");
-		SERDES_DBG_MFD("%s: name=%s\n", __func__, dev_name(serdes->dev));
+		SERDES_DBG_MFD("%s: name=%s default\n", __func__, dev_name(serdes->dev));
+	}
+
+	if ((!IS_ERR(serdes->pinctrl_node)) && (!IS_ERR(serdes->pins_init))) {
+		ret = pinctrl_select_state(serdes->pinctrl_node, serdes->pins_init);
+		if (ret)
+			dev_err(serdes->dev, "could not set init pins\n");
+		SERDES_DBG_MFD("%s: name=%s init\n", __func__, dev_name(serdes->dev));
 	}
 
 	return ret;
@@ -376,7 +392,7 @@
 }
 EXPORT_SYMBOL_GPL(serdes_device_resume);
 
-void serdes_device_shutdown(struct serdes *serdes)
+void serdes_device_poweroff(struct serdes *serdes)
 {
 	int ret = 0;
 
@@ -385,6 +401,29 @@
 		if (ret)
 			dev_err(serdes->dev, "could not set sleep pins\n");
 	}
+
+	if (!IS_ERR(serdes->vpower)) {
+		ret = regulator_disable(serdes->vpower);
+		if (ret)
+			dev_err(serdes->dev, "fail to disable vpower regulator\n");
+	}
+
+}
+EXPORT_SYMBOL_GPL(serdes_device_poweroff);
+
+int serdes_device_shutdown(struct serdes *serdes)
+{
+	int ret = 0;
+
+	if (!IS_ERR(serdes->vpower)) {
+		ret = regulator_disable(serdes->vpower);
+		if (ret) {
+			dev_err(serdes->dev, "fail to disable vpower regulator\n");
+			return ret;
+		}
+	}
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(serdes_device_shutdown);
 
diff --git a/kernel/drivers/mfd/display-serdes/serdes-gpio.c b/kernel/drivers/mfd/display-serdes/serdes-gpio.c
index 8e86455..24b0a9b 100644
--- a/kernel/drivers/mfd/display-serdes/serdes-gpio.c
+++ b/kernel/drivers/mfd/display-serdes/serdes-gpio.c
@@ -221,6 +221,7 @@
 	{ .compatible = "maxim,max96752-gpio", },
 	{ .compatible = "maxim,max96755-gpio", },
 	{ .compatible = "maxim,max96772-gpio", },
+	{ .compatible = "maxim,max96789-gpio", },
 	{ .compatible = "rockchip,rkx111-gpio", },
 	{ .compatible = "rockchip,rkx121-gpio", },
 	{ .compatible = "novo,nca9539-gpio", },
diff --git a/kernel/drivers/mfd/display-serdes/serdes-i2c.c b/kernel/drivers/mfd/display-serdes/serdes-i2c.c
index 317126e..951d40d 100644
--- a/kernel/drivers/mfd/display-serdes/serdes-i2c.c
+++ b/kernel/drivers/mfd/display-serdes/serdes-i2c.c
@@ -9,6 +9,8 @@
 
 #include "core.h"
 
+static struct serdes *g_serdes_ser_split[MAX_NUM_SERDES_SPLIT];
+
 int serdes_i2c_set_sequence(struct serdes *serdes)
 {
 	struct device *dev = serdes->dev;
@@ -52,6 +54,42 @@
 	return ret;
 }
 EXPORT_SYMBOL_GPL(serdes_i2c_set_sequence);
+
+static int serdes_set_i2c_address(struct serdes *serdes, u32 reg_hw, u32 reg_use, int link)
+{
+	int ret = 0;
+	struct i2c_client *client_split;
+	struct serdes *serdes_split = serdes->g_serdes_bridge_split;
+
+	if (!serdes_split) {
+		pr_info("%s: serdes_split is null\n", __func__);
+		return -1;
+	}
+
+	client_split = to_i2c_client(serdes->regmap->dev);
+	SERDES_DBG_MFD("%s: %s-%s addr=0x%x reg_hw=0x%x, reg_use=0x%x serdes_split=0x%p\n",
+		       __func__, dev_name(serdes_split->dev), client_split->name,
+		       client_split->addr, serdes->reg_hw, serdes->reg_use, serdes_split);
+
+	client_split->addr = serdes->reg_hw;
+
+	if (serdes_split && serdes_split->chip_data->split_ops &&
+	    serdes_split->chip_data->split_ops->select)
+		ret = serdes_split->chip_data->split_ops->select(serdes_split, link);
+
+	if (serdes->chip_data->split_ops && serdes->chip_data->split_ops->set_i2c_addr)
+		serdes->chip_data->split_ops->set_i2c_addr(serdes, reg_use, link);
+
+	if (serdes_split && serdes_split->chip_data->split_ops &&
+	    serdes_split->chip_data->split_ops->select)
+		ret = serdes_split->chip_data->split_ops->select(serdes_split, SER_SPLITTER_MODE);
+
+	client_split->addr = serdes->reg_use;
+
+	serdes_i2c_set_sequence(serdes);
+
+	return ret;
+}
 
 static void serdes_mfd_work(struct work_struct *work)
 {
@@ -125,8 +163,11 @@
 
 	/* init ser register(not des register) more early if uboot logo disabled */
 	serdes->route_enable = of_property_read_bool(dev->of_node, "route-enable");
-	if ((!serdes->route_enable) && (serdes->chip_data->serdes_type == TYPE_SER))
+	if ((!serdes->route_enable) && (serdes->chip_data->serdes_type == TYPE_SER)) {
+		if (serdes->chip_data->chip_init)
+			serdes->chip_data->chip_init(serdes);
 		ret = serdes_i2c_set_sequence(serdes);
+	}
 
 	return ret;
 }
@@ -146,7 +187,8 @@
 	serdes->chip_data = (struct serdes_chip_data *)of_device_get_match_data(dev);
 	i2c_set_clientdata(client, serdes);
 
-	dev_info(dev, "serdes %s probe start\n", serdes->chip_data->name);
+	dev_info(dev, "serdes %s probe start, id=%d\n", serdes->chip_data->name,
+		 serdes->chip_data->serdes_id);
 
 	serdes->type = serdes->chip_data->serdes_type;
 	serdes->regmap = devm_regmap_init_i2c(client, serdes->chip_data->regmap_config);
@@ -171,7 +213,6 @@
 	if (IS_ERR(serdes->vpower)) {
 		if (PTR_ERR(serdes->vpower) != -ENODEV)
 			return PTR_ERR(serdes->vpower);
-		dev_info(dev, "no vpower regulator found\n");
 	}
 
 	if (!IS_ERR(serdes->vpower)) {
@@ -194,8 +235,7 @@
 
 	ret = serdes_get_init_seq(serdes);
 	if (ret)
-		return dev_err_probe(dev, ret,
-				     "failed to write serdes register with i2c\n");
+		dev_err(dev, "failed to write serdes register with i2c\n");
 
 	mutex_init(&serdes->io_lock);
 	dev_set_drvdata(serdes->dev, serdes);
@@ -203,6 +243,31 @@
 	if (ret != 0) {
 		serdes_irq_exit(serdes);
 		return ret;
+	}
+
+	of_property_read_u32(dev->of_node, "id-serdes-bridge-split",
+			     &serdes->id_serdes_bridge_split);
+	if ((serdes->id_serdes_bridge_split < MAX_NUM_SERDES_SPLIT) && (serdes->type == TYPE_SER)) {
+		g_serdes_ser_split[serdes->id_serdes_bridge_split] = serdes;
+		SERDES_DBG_MFD("%s: %s-%s g_serdes_split[%d]=0x%p\n", __func__,
+			       dev_name(serdes->dev), serdes->chip_data->name,
+			       serdes->id_serdes_bridge_split, serdes);
+	}
+
+	of_property_read_u32(dev->of_node, "reg-hw", &serdes->reg_hw);
+	of_property_read_u32(dev->of_node, "reg", &serdes->reg_use);
+	of_property_read_u32(dev->of_node, "link", &serdes->link_use);
+	of_property_read_u32(dev->of_node, "id-serdes-panel-split", &serdes->id_serdes_panel_split);
+	if ((serdes->id_serdes_panel_split) && (serdes->type == TYPE_DES)) {
+		serdes->g_serdes_bridge_split = g_serdes_ser_split[serdes->id_serdes_panel_split];
+		SERDES_DBG_MFD("%s: id=%d p=0x%p\n", __func__,
+			       serdes->id_serdes_panel_split, serdes->g_serdes_bridge_split);
+	}
+
+	if (serdes->reg_hw) {
+		SERDES_DBG_MFD("%s: %s start change i2c address from 0x%x to 0x%x\n",
+			       __func__, dev->of_node->name, serdes->reg_hw, serdes->reg_use);
+		serdes_set_i2c_address(serdes, serdes->reg_hw, serdes->reg_use, serdes->link_use);
 	}
 
 	serdes->use_delay_work = of_property_read_bool(dev->of_node, "use-delay-work");
@@ -215,14 +280,22 @@
 		queue_delayed_work(serdes->mfd_wq, &serdes->mfd_delay_work, msecs_to_jiffies(300));
 		SERDES_DBG_MFD("%s: use_delay_work=%d\n", __func__, serdes->use_delay_work);
 	} else {
-		ret = serdes_device_init(serdes);
+		serdes_device_init(serdes);
 		SERDES_DBG_MFD("%s: use_delay_work=%d\n", __func__, serdes->use_delay_work);
 	}
 
 	dev_info(dev, "serdes %s serdes_i2c_probe successful version %s\n",
 		 serdes->chip_data->name, MFD_SERDES_DISPLAY_VERSION);
 
-	return ret;
+	return 0;
+}
+
+static void serdes_i2c_shutdown(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	struct serdes *serdes = dev_get_drvdata(dev);
+
+	serdes_device_shutdown(serdes);
 }
 
 static int serdes_i2c_prepare(struct device *dev)
@@ -266,7 +339,7 @@
 {
 	struct serdes *serdes = dev_get_drvdata(dev);
 
-	serdes_device_shutdown(serdes);
+	serdes_device_poweroff(serdes);
 
 	return 0;
 }
@@ -289,6 +362,9 @@
 #endif
 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96772)
 	{ .compatible = "maxim,max96772", .data = &serdes_max96772_data },
+#endif
+#if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96789)
+	{ .compatible = "maxim,max96789", .data = &serdes_max96789_data },
 #endif
 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROCKCHIP_RKX111)
 	{ .compatible = "rockchip,rkx111", .data = &serdes_rkx111_data },
@@ -317,6 +393,7 @@
 		.of_match_table = of_match_ptr(serdes_of_match),
 	},
 	.probe = serdes_i2c_probe,
+	.shutdown = serdes_i2c_shutdown,
 };
 
 static int __init serdes_i2c_init(void)
diff --git a/kernel/drivers/mfd/display-serdes/serdes-irq.c b/kernel/drivers/mfd/display-serdes/serdes-irq.c
index f4d7740..5aa685a 100644
--- a/kernel/drivers/mfd/display-serdes/serdes-irq.c
+++ b/kernel/drivers/mfd/display-serdes/serdes-irq.c
@@ -20,7 +20,8 @@
 	if (extcon_get_state(serdes->extcon, EXTCON_JACK_VIDEO_OUT))
 		atomic_set(&serdes->serdes_bridge->triggered, 1);
 
-	SERDES_DBG_MFD("%s: ret=%d\n", __func__, ret);
+	SERDES_DBG_MFD("%s %s %s ret=%d\n", __func__, dev_name(serdes->dev),
+				   serdes->chip_data->name, ret);
 
 	return IRQ_HANDLED;
 }
@@ -33,14 +34,15 @@
 	if (serdes->chip_data->irq_ops->err_handle)
 		ret = serdes->chip_data->irq_ops->err_handle(serdes);
 
-	SERDES_DBG_MFD("%s: ret=%d\n", __func__, ret);
+	SERDES_DBG_MFD("%s %s %s ret=%d\n", __func__, dev_name(serdes->dev),
+				   serdes->chip_data->name, ret);
 
 	return IRQ_HANDLED;
 }
 
 int serdes_irq_init(struct serdes *serdes)
 {
-	int ret;
+	int ret = 0;
 
 	mutex_init(&serdes->irq_lock);
 
@@ -55,8 +57,9 @@
 		if (serdes->lock_irq < 0)
 			return serdes->lock_irq;
 
-		SERDES_DBG_MFD("%s %s lock_irq=%d\n", __func__,
-			       serdes->chip_data->name, serdes->lock_irq);
+		SERDES_DBG_MFD("%s %s lock_irq=%d gpio=%d\n", __func__,
+			       serdes->chip_data->name, serdes->lock_irq,
+			       desc_to_gpio(serdes->lock_gpio));
 
 		ret = devm_request_threaded_irq(serdes->dev, serdes->lock_irq, NULL,
 						serdes_bridge_lock_irq_handler,
@@ -64,7 +67,7 @@
 						dev_name(serdes->dev), serdes);
 		if (ret)
 			return dev_err_probe(serdes->dev, ret,
-					     "failed to request serdes lock IRQ\n");
+				     "failed to request serdes lock IRQ\n");
 	}
 
 	/* error irq */
diff --git a/kernel/drivers/mfd/display-serdes/serdes-panel-split.c b/kernel/drivers/mfd/display-serdes/serdes-panel-split.c
new file mode 100644
index 0000000..537d282
--- /dev/null
+++ b/kernel/drivers/mfd/display-serdes/serdes-panel-split.c
@@ -0,0 +1,277 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * serdes-panel.c  --  drm panel access for different serdes chips
+ *
+ * Copyright (c) 2023-2028 Rockchip Electronics Co. Ltd.
+ *
+ * Author: luowei <lw@rock-chips.com>
+ */
+
+#include "core.h"
+
+static inline struct serdes_panel_split *to_serdes_panel_split(struct drm_panel *panel)
+{
+	return container_of(panel, struct serdes_panel_split, panel);
+}
+
+static int serdes_panel_split_prepare(struct drm_panel *panel)
+{
+	struct serdes_panel_split *serdes_panel_split = to_serdes_panel_split(panel);
+	struct serdes *serdes = serdes_panel_split->parent;
+	int ret = 0;
+
+	if (serdes->chip_data->panel_ops && serdes->chip_data->panel_ops->init)
+		ret = serdes->chip_data->panel_ops->init(serdes);
+
+	if (serdes->chip_data->serdes_type == TYPE_DES)
+		serdes_i2c_set_sequence(serdes);
+
+	if (serdes->chip_data->panel_ops && serdes->chip_data->panel_ops->prepare)
+		ret = serdes->chip_data->panel_ops->prepare(serdes);
+
+	serdes_set_pinctrl_default(serdes);
+
+	SERDES_DBG_MFD("%s: %s\n", __func__, serdes->chip_data->name);
+
+	return ret;
+}
+
+static int serdes_panel_split_unprepare(struct drm_panel *panel)
+{
+	struct serdes_panel_split *serdes_panel_split = to_serdes_panel_split(panel);
+	struct serdes *serdes = serdes_panel_split->parent;
+	int ret = 0;
+
+	if (serdes->chip_data->panel_ops && serdes->chip_data->panel_ops->unprepare)
+		ret = serdes->chip_data->panel_ops->unprepare(serdes);
+
+	serdes_set_pinctrl_sleep(serdes);
+
+	SERDES_DBG_MFD("%s: %s\n", __func__, serdes->chip_data->name);
+
+	return ret;
+}
+
+static int serdes_panel_split_enable(struct drm_panel *panel)
+{
+	struct serdes_panel_split *serdes_panel_split = to_serdes_panel_split(panel);
+	struct serdes *serdes = serdes_panel_split->parent;
+	int ret = 0;
+
+	if (serdes->chip_data->panel_ops && serdes->chip_data->panel_ops->enable)
+		ret = serdes->chip_data->panel_ops->enable(serdes);
+
+	backlight_enable(serdes_panel_split->backlight);
+
+	SERDES_DBG_MFD("%s: %s\n", __func__, serdes->chip_data->name);
+
+	return ret;
+}
+
+static int serdes_panel_split_disable(struct drm_panel *panel)
+{
+	struct serdes_panel_split *serdes_panel_split = to_serdes_panel_split(panel);
+	struct serdes *serdes = serdes_panel_split->parent;
+	int ret = 0;
+
+	if (serdes->chip_data->panel_ops && serdes->chip_data->panel_ops->disable)
+		ret = serdes->chip_data->panel_ops->disable(serdes);
+
+	backlight_disable(serdes_panel_split->backlight);
+
+	SERDES_DBG_MFD("%s: %s\n", __func__, serdes->chip_data->name);
+
+	return ret;
+}
+
+static int serdes_panel_split_get_modes(struct drm_panel *panel,
+				  struct drm_connector *connector)
+{
+	struct serdes_panel_split *serdes_panel_split = to_serdes_panel_split(panel);
+	struct serdes *serdes = serdes_panel_split->parent;
+	struct drm_display_mode *mode;
+	u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+	int ret = 1;
+
+	connector->display_info.width_mm = serdes_panel_split->width_mm;	//323; //346;
+	connector->display_info.height_mm = serdes_panel_split->height_mm;	//182; //194;
+	drm_display_info_set_bus_formats(&connector->display_info, &bus_format, 1);
+
+	mode = drm_mode_duplicate(connector->dev, &serdes_panel_split->mode);
+	mode->width_mm = serdes_panel_split->width_mm;	//323; //346;
+	mode->height_mm = serdes_panel_split->height_mm;	//182; //194;
+	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+
+	drm_mode_set_name(mode);
+	drm_mode_probed_add(connector, mode);
+
+	if (serdes->chip_data->panel_ops && serdes->chip_data->panel_ops->get_modes)
+		ret = serdes->chip_data->panel_ops->get_modes(serdes);
+
+	pr_info("%s: %s wxh=%dx%d mode clock %u kHz, flags[0x%x]\n"
+	       "    H: %04d %04d %04d %04d\n"
+	       "    V: %04d %04d %04d %04d\n"
+	       "bus_format: 0x%x\n",
+	       dev_name(serdes->dev),
+	       panel->dev->of_node->name,
+	       serdes_panel_split->width_mm, serdes_panel_split->height_mm,
+	       mode->clock, mode->flags,
+	       mode->hdisplay, mode->hsync_start,
+	       mode->hsync_end, mode->htotal,
+	       mode->vdisplay, mode->vsync_start,
+	       mode->vsync_end, mode->vtotal,
+	       bus_format);
+
+	return ret;
+}
+
+static const struct drm_panel_funcs serdes_panel_split_funcs = {
+	.prepare = serdes_panel_split_prepare,
+	.unprepare = serdes_panel_split_unprepare,
+	.enable = serdes_panel_split_enable,
+	.disable = serdes_panel_split_disable,
+	.get_modes = serdes_panel_split_get_modes,
+};
+
+static int serdes_panel_split_parse_dt(struct serdes_panel_split *serdes_panel_split)
+{
+	struct device *dev = serdes_panel_split->dev;
+	struct display_timing dt;
+	struct videomode vm;
+	int ret, len;
+	unsigned int panel_size[2] = {320, 180};
+	unsigned int link_rate_count_ssc[3] = {DP_LINK_BW_2_7, 4, 0};
+
+	//pr_info("%s: node=%s\n", __func__, dev->of_node->name);
+
+	serdes_panel_split->width_mm = panel_size[0];
+	serdes_panel_split->height_mm = panel_size[1];
+
+	serdes_panel_split->link_rate = link_rate_count_ssc[0];
+	serdes_panel_split->lane_count = link_rate_count_ssc[1];
+	serdes_panel_split->ssc = link_rate_count_ssc[2];
+
+	if (of_find_property(dev->of_node, "panel-size", &len)) {
+		len /= sizeof(unsigned int);
+		ret = of_property_read_u32_array(dev->of_node, "panel-size",
+						 panel_size, len);
+		if (!ret) {
+			serdes_panel_split->width_mm = panel_size[0];
+			serdes_panel_split->height_mm = panel_size[1];
+		}
+	}
+
+	if (of_find_property(dev->of_node, "rate-count-ssc", &len)) {
+		len /= sizeof(unsigned int);
+		ret = of_property_read_u32_array(dev->of_node, "rate-count-ssc",
+						 panel_size, len);
+		if (!ret) {
+			serdes_panel_split->link_rate = link_rate_count_ssc[0];
+			serdes_panel_split->lane_count = link_rate_count_ssc[1];
+			serdes_panel_split->ssc = link_rate_count_ssc[2];
+		}
+	}
+
+	dev_info(dev, "panle size %dx%d, rate=%d, cnt=%d, ssc=%d\n",
+		 serdes_panel_split->width_mm, serdes_panel_split->height_mm,
+		 serdes_panel_split->link_rate, serdes_panel_split->lane_count,
+		 serdes_panel_split->ssc);
+
+	ret = of_get_display_timing(dev->of_node, "panel-timing", &dt);
+	if (ret < 0) {
+		dev_err(dev, "%pOF:serdes no panel-timing node found\n", dev->of_node);
+		return ret;
+	}
+
+	videomode_from_timing(&dt, &vm);
+	drm_display_mode_from_videomode(&vm, &serdes_panel_split->mode);
+
+	return 0;
+}
+
+static int serdes_panel_split_probe(struct platform_device *pdev)
+{
+	struct serdes *serdes = dev_get_drvdata(pdev->dev.parent);
+	struct device *dev = &pdev->dev;
+	struct serdes_panel_split *serdes_panel_split;
+	int ret;
+
+	serdes_panel_split = devm_kzalloc(dev, sizeof(*serdes_panel_split), GFP_KERNEL);
+	if (!serdes_panel_split)
+		return -ENOMEM;
+
+	serdes->serdes_panel_split = serdes_panel_split;
+	serdes_panel_split->dev = dev;
+	serdes_panel_split->parent = dev_get_drvdata(dev->parent);
+	platform_set_drvdata(pdev, serdes_panel_split);
+
+	serdes_panel_split->regmap = dev_get_regmap(dev->parent, NULL);
+	if (!serdes_panel_split->regmap)
+		return dev_err_probe(dev, -ENODEV, "failed to get serdes regmap\n");
+
+	ret = serdes_panel_split_parse_dt(serdes_panel_split);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to parse serdes DT\n");
+
+	serdes_panel_split->backlight = devm_of_find_backlight(dev);
+	if (IS_ERR(serdes_panel_split->backlight))
+		return dev_err_probe(dev, PTR_ERR(serdes_panel_split->backlight),
+				     "failed to get serdes backlight\n");
+
+	if (serdes_panel_split->parent->chip_data->connector_type) {
+		drm_panel_init(&serdes_panel_split->panel, dev, &serdes_panel_split_funcs,
+			       serdes_panel_split->parent->chip_data->connector_type);
+	} else {
+		drm_panel_init(&serdes_panel_split->panel, dev, &serdes_panel_split_funcs,
+			       DRM_MODE_CONNECTOR_LVDS);
+	}
+	drm_panel_add(&serdes_panel_split->panel);
+
+	dev_info(dev, "serdes %s-%s %s successful\n", dev_name(serdes->dev),
+		 serdes->chip_data->name, __func__);
+
+	return 0;
+}
+
+static int serdes_panel_split_remove(struct platform_device *pdev)
+{
+	struct serdes_panel_split *serdes_panel_split = platform_get_drvdata(pdev);
+
+	drm_panel_remove(&serdes_panel_split->panel);
+
+	return 0;
+}
+
+static const struct of_device_id serdes_panel_split_of_match[] = {
+	{ .compatible = "rohm,bu18rl82-panel-split" },
+	{ .compatible = "maxim,max96752-panel-split" },
+	{ .compatible = "maxim,max96772-panel-split" },
+	{ .compatible = "rockchip,rkx121-panel-split" },
+	{ }
+};
+
+static struct platform_driver serdes_panel_split_driver = {
+	.driver = {
+		.name = "serdes-panel-split",
+		.of_match_table = of_match_ptr(serdes_panel_split_of_match),
+	},
+	.probe = serdes_panel_split_probe,
+	.remove = serdes_panel_split_remove,
+};
+
+static int __init serdes_panel_split_init(void)
+{
+	return platform_driver_register(&serdes_panel_split_driver);
+}
+device_initcall(serdes_panel_split_init);
+
+static void __exit serdes_panel_split_exit(void)
+{
+	platform_driver_unregister(&serdes_panel_split_driver);
+}
+module_exit(serdes_panel_split_exit);
+
+MODULE_AUTHOR("Luo Wei <lw@rock-chips.com>");
+MODULE_DESCRIPTION("display panel interface for different serdes");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:serdes-panel-split");
diff --git a/kernel/drivers/mfd/display-serdes/serdes-panel.c b/kernel/drivers/mfd/display-serdes/serdes-panel.c
index 9e5cc95..2793220 100644
--- a/kernel/drivers/mfd/display-serdes/serdes-panel.c
+++ b/kernel/drivers/mfd/display-serdes/serdes-panel.c
@@ -91,7 +91,7 @@
 	struct serdes *serdes = serdes_panel->parent;
 	struct drm_display_mode *mode;
 	u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
-	int ret = 0;
+	int ret = 1;
 
 	connector->display_info.width_mm = serdes_panel->width_mm;	//323; //346;
 	connector->display_info.height_mm = serdes_panel->height_mm;	//182; //194;
@@ -108,8 +108,18 @@
 	if (serdes->chip_data->panel_ops && serdes->chip_data->panel_ops->get_modes)
 		ret = serdes->chip_data->panel_ops->get_modes(serdes);
 
-	SERDES_DBG_MFD("%s: %s node=%s\n", __func__,
-		       serdes->chip_data->name, panel->dev->of_node->name);
+	dev_info(serdes->dev, "%s wxh=%dx%d mode clock %u kHz, flags[0x%x]\n"
+	       "    H: %04d %04d %04d %04d\n"
+	       "    V: %04d %04d %04d %04d\n"
+	       "bus_format: 0x%x\n",
+	       panel->dev->of_node->name,
+	       serdes_panel->width_mm, serdes_panel->height_mm,
+	       mode->clock, mode->flags,
+	       mode->hdisplay, mode->hsync_start,
+	       mode->hsync_end, mode->htotal,
+	       mode->vdisplay, mode->vsync_start,
+	       mode->vsync_end, mode->vtotal,
+	       bus_format);
 
 	return ret;
 }
@@ -129,12 +139,24 @@
 	struct videomode vm;
 	int ret, len;
 	unsigned int panel_size[2] = {320, 180};
+	unsigned int link_rate_count_ssc[3] = {DP_LINK_BW_2_7, 4, 0};
+
+	//pr_info("%s: node=%s\n", __func__, dev->of_node->name);
 
 	serdes_panel->width_mm = panel_size[0];
 	serdes_panel->height_mm = panel_size[1];
 
+	serdes_panel->link_rate = link_rate_count_ssc[0];
+	serdes_panel->lane_count = link_rate_count_ssc[1];
+	serdes_panel->ssc = link_rate_count_ssc[2];
+
 	if (of_find_property(dev->of_node, "panel-size", &len)) {
 		len /= sizeof(unsigned int);
+		if (len != 2) {
+			dev_err(dev, "panel-size length is error, set 2 default\n",
+				dev->of_node);
+			len = 2;
+		}
 		ret = of_property_read_u32_array(dev->of_node, "panel-size",
 						 panel_size, len);
 		if (!ret) {
@@ -143,8 +165,25 @@
 		}
 	}
 
-	dev_info(dev, "panle size %dx%d\n",
-		 serdes_panel->width_mm, serdes_panel->height_mm);
+	if (of_find_property(dev->of_node, "rate-count-ssc", &len)) {
+		len /= sizeof(unsigned int);
+		if (len != 3) {
+			dev_err(dev, "rate-count-ssc length is error, set 3 default\n",
+				dev->of_node);
+			len = 3;
+		}
+		ret = of_property_read_u32_array(dev->of_node, "rate-count-ssc",
+						 link_rate_count_ssc, len);
+		if (!ret) {
+			serdes_panel->link_rate = link_rate_count_ssc[0];
+			serdes_panel->lane_count = link_rate_count_ssc[1];
+			serdes_panel->ssc = link_rate_count_ssc[2];
+		}
+	}
+
+	dev_info(dev, "panle size %dx%d, rate=%d, cnt=%d, ssc=%d\n",
+		 serdes_panel->width_mm, serdes_panel->height_mm,
+		 serdes_panel->link_rate, serdes_panel->lane_count, serdes_panel->ssc);
 
 	ret = of_get_display_timing(dev->of_node, "panel-timing", &dt);
 	if (ret < 0) {
@@ -196,7 +235,8 @@
 	}
 	drm_panel_add(&serdes_panel->panel);
 
-	dev_info(dev, "serdes %s serdes_panel_probe successful\n", serdes->chip_data->name);
+	dev_info(dev, "serdes %s-%s serdes_panel_probe successful\n",
+		 dev_name(serdes->dev), serdes->chip_data->name);
 
 	return 0;
 }
@@ -211,7 +251,6 @@
 }
 
 static const struct of_device_id serdes_panel_of_match[] = {
-	{ .compatible = "rohm,bu18tl82-panel" },
 	{ .compatible = "rohm,bu18rl82-panel" },
 	{ .compatible = "maxim,max96752-panel" },
 	{ .compatible = "maxim,max96772-panel" },
diff --git a/kernel/drivers/mfd/display-serdes/serdes-pinctrl.c b/kernel/drivers/mfd/display-serdes/serdes-pinctrl.c
index 9564e3d..d6bc900 100644
--- a/kernel/drivers/mfd/display-serdes/serdes-pinctrl.c
+++ b/kernel/drivers/mfd/display-serdes/serdes-pinctrl.c
@@ -309,7 +309,7 @@
 
 		for (j = 0; j < group->num_pins; j++) {
 			grp_pins[j] = pinctrl_info->groups[i].pins[j] + pin_base;
-			SERDES_DBG_MFD("%s group name %s pin %d base=%d\n", __func__,
+			SERDES_DBG_MFD("%s group name %s pin=%d base=%d\n", __func__,
 				       pinctrl_info->groups[i].name, grp_pins[j], pin_base);
 		}
 
@@ -344,6 +344,8 @@
 	if (!IS_ERR(serdes->pinctrl_node)) {
 		serdes->pins_default =
 			pinctrl_lookup_state(serdes->pinctrl_node, PINCTRL_STATE_DEFAULT);
+		serdes->pins_init =
+			pinctrl_lookup_state(serdes->pinctrl_node, PINCTRL_STATE_INIT);
 		serdes->pins_sleep =
 			pinctrl_lookup_state(serdes->pinctrl_node, PINCTRL_STATE_SLEEP);
 	}
@@ -361,6 +363,7 @@
 	{ .compatible = "maxim,max96752-pinctrl" },
 	{ .compatible = "maxim,max96755-pinctrl" },
 	{ .compatible = "maxim,max96772-pinctrl" },
+	{ .compatible = "maxim,max96789-pinctrl" },
 	{ .compatible = "rockchip,rkx111-pinctrl" },
 	{ .compatible = "rockchip,rkx121-pinctrl" },
 	{ .compatible = "novo,nca9539-pinctrl" },
diff --git a/kernel/drivers/mfd/dln2.c b/kernel/drivers/mfd/dln2.c
index 852129e..fc65f9e 100644
--- a/kernel/drivers/mfd/dln2.c
+++ b/kernel/drivers/mfd/dln2.c
@@ -836,6 +836,7 @@
 	dln2_stop_rx_urbs(dln2);
 
 out_free:
+	usb_put_dev(dln2->usb_dev);
 	dln2_free(dln2);
 
 	return ret;
diff --git a/kernel/drivers/mfd/intel-lpss-acpi.c b/kernel/drivers/mfd/intel-lpss-acpi.c
index 045cbf0..993e305 100644
--- a/kernel/drivers/mfd/intel-lpss-acpi.c
+++ b/kernel/drivers/mfd/intel-lpss-acpi.c
@@ -114,6 +114,9 @@
 		return -ENOMEM;
 
 	info->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!info->mem)
+		return -ENODEV;
+
 	info->irq = platform_get_irq(pdev, 0);
 
 	ret = intel_lpss_probe(&pdev->dev, info);
diff --git a/kernel/drivers/mfd/pcf50633-adc.c b/kernel/drivers/mfd/pcf50633-adc.c
index 5cd653e..191b1bc 100644
--- a/kernel/drivers/mfd/pcf50633-adc.c
+++ b/kernel/drivers/mfd/pcf50633-adc.c
@@ -136,6 +136,7 @@
 			     void *callback_param)
 {
 	struct pcf50633_adc_request *req;
+	int ret;
 
 	/* req is freed when the result is ready, in interrupt handler */
 	req = kmalloc(sizeof(*req), GFP_KERNEL);
@@ -147,7 +148,11 @@
 	req->callback = callback;
 	req->callback_param = callback_param;
 
-	return adc_enqueue_request(pcf, req);
+	ret = adc_enqueue_request(pcf, req);
+	if (ret)
+		kfree(req);
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(pcf50633_adc_async_read);
 
diff --git a/kernel/drivers/mfd/rk630-i2c.c b/kernel/drivers/mfd/rk630-i2c.c
index e31a5b4..9636458 100644
--- a/kernel/drivers/mfd/rk630-i2c.c
+++ b/kernel/drivers/mfd/rk630-i2c.c
@@ -49,6 +49,15 @@
 		return ret;
 	}
 
+	rk630->rtc = devm_regmap_init_i2c(client, &rk630_rtc_regmap_config);
+	if (IS_ERR(rk630->rtc)) {
+		ret = PTR_ERR(rk630->rtc);
+		dev_err(dev, "failed to allocate rtc register map: %d\n", ret);
+		return ret;
+	}
+
+	rk630->irq = client->irq;
+
 	return rk630_core_probe(rk630);
 }
 
diff --git a/kernel/drivers/mfd/rk630-spi.c b/kernel/drivers/mfd/rk630-spi.c
index 9475db9..b12843c 100644
--- a/kernel/drivers/mfd/rk630-spi.c
+++ b/kernel/drivers/mfd/rk630-spi.c
@@ -213,6 +213,16 @@
 		return ret;
 	}
 
+	rk630->rtc = devm_regmap_init(&spi->dev, &rk630_regmap,
+				      &spi->dev, &rk630_rtc_regmap_config);
+	if (IS_ERR(rk630->rtc)) {
+		ret = PTR_ERR(rk630->rtc);
+		dev_err(rk630->dev, "Failed to initialize rtc regmap: %d\n",
+			ret);
+		return ret;
+	}
+	rk630->irq = spi->irq;
+
 	ret = rk630_core_probe(rk630);
 	if (ret)
 		return ret;
diff --git a/kernel/drivers/mfd/rk630.c b/kernel/drivers/mfd/rk630.c
index 732c3c0..b8b8538 100644
--- a/kernel/drivers/mfd/rk630.c
+++ b/kernel/drivers/mfd/rk630.c
@@ -13,7 +13,7 @@
 #include <linux/gpio/consumer.h>
 #include <linux/mfd/rk630.h>
 
-static int rk630_macphy_enable(struct rk630 *rk630)
+static int rk630_macphy_enable(struct rk630 *rk630, unsigned long rate)
 {
 	u32 val;
 	int ret;
@@ -68,8 +68,23 @@
 		return ret;
 	}
 
-	/* mode sel: RMII && clock sel: 24M && BGS value: OTP && id */
-	val = (2 << 14) | (0 << 12) | (0x1 << 8) | (6 << 5) | 1;
+	/* mode sel: RMII && BGS value: OTP && id */
+	val = (2 << 14) | (0 << 12) | (0x1 << 8) | 1;
+	switch (rate) {
+	case 24000000:
+		val |= 0x6 << 5;
+		break;
+	case 25000000:
+		val |= 0x4 << 5;
+		break;
+	case 27000000:
+		val |= 0x5 << 5;
+		break;
+	default:
+		dev_err(rk630->dev, "Unsupported clock rate: %ld\n", rate);
+		return -EINVAL;
+	}
+
 	ret = regmap_write(rk630->grf, GRF_REG(0x404), val | 0xffff0000);
 	if (ret != 0) {
 		dev_err(rk630->dev, "Could not write to GRF: %d\n", ret);
@@ -100,6 +115,10 @@
 	{
 		.name = "rk630-tve",
 		.of_compatible = "rockchip,rk630-tve",
+	},
+	{
+		.name = "rk630-rtc",
+		.of_compatible = "rockchip,rk630-rtc",
 	},
 	{
 		.name = "rk630-macphy",
@@ -164,11 +183,57 @@
 };
 EXPORT_SYMBOL_GPL(rk630_cru_regmap_config);
 
+static const struct regmap_range rk630_rtc_readable_ranges[] = {
+	regmap_reg_range(RTC_SET_SECONDS, RTC_CNT_3),
+};
+
+static const struct regmap_access_table rk630_rtc_readable_table = {
+	.yes_ranges = rk630_rtc_readable_ranges,
+	.n_yes_ranges = ARRAY_SIZE(rk630_rtc_readable_ranges),
+};
+
+const struct regmap_config rk630_rtc_regmap_config = {
+	.name = "rtc",
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = RTC_MAX_REGISTER,
+	.reg_format_endian = REGMAP_ENDIAN_NATIVE,
+	.val_format_endian = REGMAP_ENDIAN_NATIVE,
+	.rd_table = &rk630_rtc_readable_table,
+};
+EXPORT_SYMBOL_GPL(rk630_rtc_regmap_config);
+
 int rk630_core_probe(struct rk630 *rk630)
 {
 	bool macphy_enabled = false;
+	struct clk *ref_clk;
 	struct device_node *np;
+	unsigned long rate;
 	int ret;
+
+	if (!rk630->irq) {
+		dev_err(rk630->dev, "No interrupt support, no core IRQ\n");
+		return -EINVAL;
+	}
+
+	ref_clk = devm_clk_get(rk630->dev, "ref");
+	if (IS_ERR(ref_clk)) {
+		dev_err(rk630->dev, "failed to get ref clk source\n");
+		return PTR_ERR(ref_clk);
+	}
+
+	ret = clk_prepare_enable(ref_clk);
+	if (ret < 0) {
+		dev_err(rk630->dev, "failed to enable ref clk - %d\n", ret);
+		return ret;
+	}
+	rate = clk_get_rate(ref_clk);
+
+	ret = devm_add_action_or_reset(rk630->dev, (void (*) (void *))clk_disable_unprepare,
+				       ref_clk);
+	if (ret)
+		return ret;
 
 	rk630->reset_gpio = devm_gpiod_get(rk630->dev, "reset", 0);
 	if (IS_ERR(rk630->reset_gpio)) {
@@ -182,6 +247,16 @@
 	gpiod_direction_output(rk630->reset_gpio, 1);
 	usleep_range(50000, 60000);
 	gpiod_direction_output(rk630->reset_gpio, 0);
+
+	/**
+	 * If rtc output clamp is enabled, rtc regs can't be accessed,
+	 * RK630 irq add will failed.
+	 */
+	regmap_update_bits(rk630->grf, PLUMAGE_GRF_SOC_CON0,
+			   RTC_CLAMP_EN_MASK, RTC_CLAMP_EN(1));
+
+	/* disable ext_off\vbat_det\msec\sys_int\periodic interrupt by default */
+	regmap_write(rk630->rtc, RTC_INT1_EN, 0);
 
 	ret = devm_mfd_add_devices(rk630->dev, PLATFORM_DEVID_NONE,
 				   rk630_devs, ARRAY_SIZE(rk630_devs),
@@ -204,7 +279,7 @@
 	}
 
 	if (macphy_enabled)
-		rk630_macphy_enable(rk630);
+		rk630_macphy_enable(rk630, rate);
 	else
 		rk630_macphy_disable(rk630);
 
diff --git a/kernel/drivers/mfd/rk806-core.c b/kernel/drivers/mfd/rk806-core.c
index 5421ac9..1ab83fb 100644
--- a/kernel/drivers/mfd/rk806-core.c
+++ b/kernel/drivers/mfd/rk806-core.c
@@ -352,13 +352,13 @@
 	.n_yes_ranges = ARRAY_SIZE(rk806_yes_ranges),
 };
 
-const struct regmap_config rk806_regmap_config_spi = {
+const struct regmap_config rk806_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
 	.cache_type = REGCACHE_RBTREE,
 	.volatile_table = &rk806_volatile_table,
 };
-EXPORT_SYMBOL_GPL(rk806_regmap_config_spi);
+EXPORT_SYMBOL_GPL(rk806_regmap_config);
 
 static struct kobject *rk806_kobj[2];
 static struct rk806 *rk806_master;
@@ -825,6 +825,12 @@
 }
 EXPORT_SYMBOL_GPL(rk806_device_exit);
 
+const struct of_device_id rk806_of_match[] = {
+	{ .compatible = "rockchip,rk806", },
+	{ }
+};
+EXPORT_SYMBOL_GPL(rk806_of_match);
+
 MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
 MODULE_DESCRIPTION("rk806 MFD Driver");
 MODULE_LICENSE("GPL v2");
diff --git a/kernel/drivers/mfd/rk806-i2c.c b/kernel/drivers/mfd/rk806-i2c.c
new file mode 100644
index 0000000..26558e9
--- /dev/null
+++ b/kernel/drivers/mfd/rk806-i2c.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * rk806-i2c.c  --  I2C access for Rockchip RK806
+ *
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ *
+ * Author: Xu Shengfei <xsf@rock-chips.com>
+ */
+
+#include <linux/i2c.h>
+#include <linux/mfd/rk806.h>
+#include <linux/regmap.h>
+
+static int rk806_i2c_probe(struct i2c_client *client,
+			   const struct i2c_device_id *id)
+{
+	struct rk806 *rk806;
+
+	rk806 = devm_kzalloc(&client->dev, sizeof(*rk806), GFP_KERNEL);
+	if (!rk806)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, rk806);
+	rk806->dev = &client->dev;
+	rk806->irq = client->irq;
+
+	if (!client->irq) {
+		dev_err(&client->dev, "No interrupt support, no core IRQ\n");
+		return -EINVAL;
+	}
+
+	rk806->regmap = devm_regmap_init_i2c(client, &rk806_regmap_config);
+	if (IS_ERR(rk806->regmap)) {
+		dev_err(&client->dev, "regmap initialization failed\n");
+		return PTR_ERR(rk806->regmap);
+	}
+
+	return rk806_device_init(rk806);
+}
+
+static int rk806_remove(struct i2c_client *client)
+{
+	struct rk806 *rk806 = i2c_get_clientdata(client);
+
+	rk806_device_exit(rk806);
+
+	return 0;
+}
+
+static struct i2c_driver rk806_i2c_driver = {
+	.driver = {
+		.name = "rk806",
+		.of_match_table = of_match_ptr(rk806_of_match),
+	},
+	.probe    = rk806_i2c_probe,
+	.remove   = rk806_remove,
+};
+module_i2c_driver(rk806_i2c_driver);
+
+MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
+MODULE_DESCRIPTION("RK806 I2C Interface Driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/mfd/rk806-spi.c b/kernel/drivers/mfd/rk806-spi.c
index 2466024..5610378 100644
--- a/kernel/drivers/mfd/rk806-spi.c
+++ b/kernel/drivers/mfd/rk806-spi.c
@@ -12,12 +12,6 @@
 #include <linux/regmap.h>
 #include <linux/spi/spi.h>
 
-static const struct of_device_id rk806_spi_of_match_table[] = {
-	{ .compatible = "rockchip,rk806", },
-	{ }
-};
-MODULE_DEVICE_TABLE(of, rk806_spi_of_match_table);
-
 static int rk806_spi_write(struct spi_device *spi,
 			   char addr,
 			   const char *data,
@@ -101,7 +95,7 @@
 	rk806->regmap = devm_regmap_init(&spi->dev,
 					 &rk806_regmap_bus_spi,
 					 &spi->dev,
-					 &rk806_regmap_config_spi);
+					 &rk806_regmap_config);
 	if (IS_ERR(rk806->regmap)) {
 		dev_err(rk806->dev, "Failed to initialize register map\n");
 		return PTR_ERR(rk806->regmap);
@@ -127,7 +121,7 @@
 	.driver		= {
 		.name	= "rk806",
 		.owner = THIS_MODULE,
-		.of_match_table = rk806_spi_of_match_table,
+		.of_match_table = of_match_ptr(rk806_of_match),
 	},
 	.probe		= rk806_spi_probe,
 	.remove		= rk806_spi_remove,
diff --git a/kernel/drivers/mfd/rkx110_x120/Makefile b/kernel/drivers/mfd/rkx110_x120/Makefile
index c0b23cb..d22fa91 100644
--- a/kernel/drivers/mfd/rkx110_x120/Makefile
+++ b/kernel/drivers/mfd/rkx110_x120/Makefile
@@ -12,12 +12,14 @@
 	rkx110_combrxphy.o \
 	rkx110_dsi_rx.o \
 	rkx110_x120_core.o \
+	rkx110_x120_display.o\
 	rkx110_linktx.o \
 	rkx110.o \
 	rkx120.o \
 	rkx120_combtxphy.o \
 	rkx120_dsi_tx.o \
 	rkx120_linkrx.o \
-	serdes_combphy.o
+	serdes_combphy.o \
+	rkx120_pwm.o
 
 obj-$(CONFIG_ROCKCHIP_SERDES_DRM_PANEL) += rkx110_x120_panel.o
diff --git a/kernel/drivers/mfd/rkx110_x120/hal/cru_rkx111.c b/kernel/drivers/mfd/rkx110_x120/hal/cru_rkx111.c
index 5f24c62..41da74f 100644
--- a/kernel/drivers/mfd/rkx110_x120/hal/cru_rkx111.c
+++ b/kernel/drivers/mfd/rkx110_x120/hal/cru_rkx111.c
@@ -341,6 +341,8 @@
     /* link(dclk): Allowed to change PLL rate if need ! */
     case RKX111_CPS_DCLK_D_DSI_0_REC:
     case RKX111_CPS_DCLK_D_DSI_1_REC:
+    case RKX111_CPS_CLK_D_LVDS0_PATTERN_GEN:
+    case RKX111_CPS_CLK_D_LVDS1_PATTERN_GEN:
     case RKX110_CPS_CLK_2X_LVDS_RKLINK_TX:
     /* i2s */
     case RKX110_CPS_CLK_I2S_SRC_RKLINK_TX:
@@ -384,9 +386,6 @@
     /* bus */
     case RKX110_CPS_DCLK_RX_PRE:
     case RKX111_CPS_DCLK_RX_PRE_200M:
-    /* lvds */
-    case RKX111_CPS_CLK_D_LVDS0_PATTERN_GEN:
-    case RKX111_CPS_CLK_D_LVDS1_PATTERN_GEN:
     /* camera */
     case RKX110_CPS_CLK_CAM0_OUT2IO:
     case RKX110_CPS_CLK_CAM1_OUT2IO:
diff --git a/kernel/drivers/mfd/rkx110_x120/pattern_gen.c b/kernel/drivers/mfd/rkx110_x120/pattern_gen.c
index 488d372..8ad2574 100644
--- a/kernel/drivers/mfd/rkx110_x120/pattern_gen.c
+++ b/kernel/drivers/mfd/rkx110_x120/pattern_gen.c
@@ -8,6 +8,8 @@
 #include <linux/debugfs.h>
 
 #include "rkx110_x120.h"
+#include "rkx110_x120_display.h"
+#include "hal/cru_api.h"
 
 #define PATTERN_GEN_PATTERN_CTRL	0x0000
 #define PATTERN_START_PCLK		BIT(31)
@@ -29,11 +31,10 @@
 #define PATTERN_GEN_VALUE0		0x0014
 #define PATTERN_GEN_VALUE1		0x0018
 
-static void pattern_gen_enable(struct pattern_gen *pattern_gen)
+static void pattern_gen_config(struct i2c_client *client, struct pattern_gen *pattern_gen,
+				struct videomode *vm)
 {
-	struct i2c_client *client = pattern_gen->chip->client;
 	struct rk_serdes *serdes = pattern_gen->chip->serdes;
-	const struct videomode *vm = serdes->vm;
 
 	serdes->i2c_update_bits(client, pattern_gen->base + PATTERN_GEN_PATTERN_CTRL,
 				PATTERN_RECTANGLE_H | PATTERN_RECTANGLE_V,
@@ -53,24 +54,311 @@
 	serdes->i2c_write_reg(client, pattern_gen->base + PATTERN_GEN_PATERN_VH_CFG3,
 			      FIELD_PREP(PATTERN_HSA, vm->hsync_len));
 
-	serdes->i2c_update_bits(client, pattern_gen->base + PATTERN_GEN_PATTERN_CTRL,
-				PATTERN_START_PCLK,
-				FIELD_PREP(PATTERN_START_PCLK, 1));
 	serdes->i2c_write_reg(client, pattern_gen->link_src_reg,
 			      BIT(pattern_gen->link_src_offset + 16) |
 			      BIT(pattern_gen->link_src_offset));
+}
+
+static void pattern_stop_stream(struct pattern_gen *pattern_gen)
+{
+	struct rk_serdes *serdes = pattern_gen->chip->serdes;
+
+	if (serdes->version != SERDES_V1)
+		return;
+
+	if (pattern_gen->chip != &serdes->chip[DEVICE_LOCAL])
+		return;
+
+	rk_serdes_display_video_start(serdes, pattern_gen->route, false);
+
+	if (!strcmp(pattern_gen->name, "lvds0")) {
+		hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+			    RKX110_SRST_RESETN_D_LVDS0_RKLINK_TX);
+	} else if (!strcmp(pattern_gen->name, "lvds1")) {
+		hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+			    RKX110_SRST_RESETN_D_LVDS1_RKLINK_TX);
+	} else if (!strcmp(pattern_gen->name, "dual-lvds")) {
+		rkx110_set_stream_source(serdes, RK_SERDES_RGB_RX, DEVICE_LOCAL);
+		hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+			    RKX110_SRST_RESETN_2X_LVDS_RKLINK_TX);
+		hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+			    RKX110_SRST_RESETN_D_LVDS0_RKLINK_TX);
+		hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+			    RKX110_SRST_RESETN_D_LVDS1_RKLINK_TX);
+	} else if (!strcmp(pattern_gen->name, "dsi0")) {
+		serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
+				      0x1400140);
+		hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+			    RKX111_SRST_RESETN_D_DSI_0_REC_RKLINK_TX);
+		hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+			    RKX110_SRST_RESETN_D_DSI_0_RKLINK_TX);
+		rkx110_linktx_dsi_rec_start(serdes, DEVICE_LOCAL, 0, false);
+	} else if (!strcmp(pattern_gen->name, "dsi1")) {
+		serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
+				      0x2800280);
+		hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+			    RKX111_SRST_RESETN_D_DSI_1_REC_RKLINK_TX);
+		hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+			    RKX110_SRST_RESETN_D_DSI_1_RKLINK_TX);
+		rkx110_linktx_dsi_rec_start(serdes, DEVICE_LOCAL, 1, false);
+	}
+}
+
+static void pattern_start_stream(struct pattern_gen *pattern_gen, bool is_pattern_stream)
+{
+	struct rk_serdes *serdes = pattern_gen->chip->serdes;
+	struct videomode *vm = &pattern_gen->route->vm;
+	u32 delay_length;
+
+	if (serdes->version != SERDES_V1)
+		return;
+
+	if (pattern_gen->chip != &serdes->chip[DEVICE_LOCAL])
+		return;
+
+	if (!strcmp(pattern_gen->name, "lvds0")) {
+		hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+				     RKX110_SRST_RESETN_D_LVDS0_RKLINK_TX);
+	} else if (!strcmp(pattern_gen->name, "lvds1")) {
+		hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+				     RKX110_SRST_RESETN_D_LVDS1_RKLINK_TX);
+	} else if (!strcmp(pattern_gen->name, "dual-lvds")) {
+		hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+				     RKX110_SRST_RESETN_2X_LVDS_RKLINK_TX);
+		hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+				     RKX110_SRST_RESETN_D_LVDS0_RKLINK_TX);
+		hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+				     RKX110_SRST_RESETN_D_LVDS1_RKLINK_TX);
+		rkx110_set_stream_source(serdes, RK_SERDES_DUAL_LVDS_RX,
+					 DEVICE_LOCAL);
+	} else if (!strcmp(pattern_gen->name, "dsi0")) {
+		hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+				     RKX110_SRST_RESETN_D_DSI_0_RKLINK_TX);
+		hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+				     RKX111_SRST_RESETN_D_DSI_0_REC_RKLINK_TX);
+		serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
+				      0x1400000);
+
+		rkx110_linktx_dsi_type_select(serdes, DEVICE_LOCAL, 0,
+					      is_pattern_stream ? false : true);
+		if (is_pattern_stream)
+			delay_length = vm->hsync_len + vm->hback_porch +
+				       vm->hactive + vm->hfront_porch;
+		else
+			delay_length = (vm->vfront_porch + 1) * (vm->hsync_len +
+					vm->hback_porch + vm->hactive + vm->hfront_porch);
+		rkx110_linktx_dsi_deley_length_config(serdes, DEVICE_LOCAL, 0, delay_length);
+		rkx110_linktx_dsi_rec_start(serdes, DEVICE_LOCAL, 0, true);
+	} else if (!strcmp(pattern_gen->name, "dsi1")) {
+		hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+				     RKX110_SRST_RESETN_D_DSI_1_RKLINK_TX);
+		hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+				     RKX111_SRST_RESETN_D_DSI_1_REC_RKLINK_TX);
+		serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
+				      0x2800000);
+
+		rkx110_linktx_dsi_type_select(serdes, DEVICE_LOCAL, 1,
+					      is_pattern_stream ? false : true);
+		if (is_pattern_stream)
+			delay_length = vm->hsync_len + vm->hback_porch +
+				       vm->hactive + vm->hfront_porch;
+		else
+			delay_length = (vm->vfront_porch + 1) * (vm->hsync_len +
+					vm->hback_porch + vm->hactive + vm->hfront_porch);
+		rkx110_linktx_dsi_deley_length_config(serdes, DEVICE_LOCAL, 1, delay_length);
+		rkx110_linktx_dsi_rec_start(serdes, DEVICE_LOCAL, 1, true);
+	}
+
+	rk_serdes_display_video_start(serdes, pattern_gen->route, true);
+}
+
+static void pattern_switch_clk_to_pattern(struct pattern_gen *pattern_gen, struct videomode *vm)
+{
+	struct rk_serdes *serdes = pattern_gen->chip->serdes;
+	struct hwclk *hwclk = serdes->chip[DEVICE_LOCAL].hwclk;
+
+	if (serdes->version != SERDES_V1)
+		return;
+
+	if (pattern_gen->chip != &serdes->chip[DEVICE_LOCAL])
+		return;
+
+	if (!strcmp(pattern_gen->name, "lvds0")) {
+		hwclk_set_rate(hwclk, RKX111_CPS_CLK_D_LVDS0_PATTERN_GEN, vm->pixelclock);
+		dev_info(serdes->dev, "RKX111_CPS_CLK_D_LVDS0_PATTERN_GEN:%d\n",
+			 hwclk_get_rate(hwclk, RKX111_CPS_CLK_D_LVDS0_PATTERN_GEN));
+		hwclk_set_mux(hwclk, RKX111_CLK_D_LVDS0_RKLINK_TX_SEL,
+			      RKX111_CLK_D_LVDS0_RKLINK_TX_SEL_CLK_D_LVDS0_PATTERN_GEN);
+	} else if (!strcmp(pattern_gen->name, "lvds1")) {
+		hwclk_set_rate(hwclk, RKX111_CPS_CLK_D_LVDS1_PATTERN_GEN, vm->pixelclock);
+		dev_info(serdes->dev, "RKX111_CPS_CLK_D_LVDS1_PATTERN_GEN:%d\n",
+			 hwclk_get_rate(hwclk, RKX111_CPS_CLK_D_LVDS1_PATTERN_GEN));
+		hwclk_set_mux(hwclk, RKX111_CLK_D_LVDS1_RKLINK_TX_SEL,
+			      RKX111_CLK_D_LVDS1_RKLINK_TX_SEL_CLK_D_LVDS1_PATTERN_GEN);
+	} else if (!strcmp(pattern_gen->name, "dual-lvds")) {
+		hwclk_set_rate(hwclk, RKX111_CPS_CLK_D_LVDS0_PATTERN_GEN, vm->pixelclock);
+		dev_info(serdes->dev, "RKX111_CPS_CLK_D_LVDS0_PATTERN_GEN:%d\n",
+			 hwclk_get_rate(hwclk, RKX111_CPS_CLK_D_LVDS0_PATTERN_GEN));
+		hwclk_set_rate(hwclk, RKX111_CPS_CLK_D_LVDS1_PATTERN_GEN, vm->pixelclock);
+		dev_info(serdes->dev, "RKX111_CPS_CLK_D_LVDS1_PATTERN_GEN:%d\n",
+			 hwclk_get_rate(hwclk, RKX111_CPS_CLK_D_LVDS1_PATTERN_GEN));
+		hwclk_set_mux(hwclk, RKX111_CLK_D_LVDS0_RKLINK_TX_SEL,
+			      RKX111_CLK_D_LVDS0_RKLINK_TX_SEL_CLK_D_LVDS0_PATTERN_GEN);
+		hwclk_set_mux(hwclk, RKX111_CLK_D_LVDS1_RKLINK_TX_SEL,
+			      RKX111_CLK_D_LVDS1_RKLINK_TX_SEL_CLK_D_LVDS1_PATTERN_GEN);
+	} else if (!strcmp(pattern_gen->name, "dsi0")) {
+		hwclk_set_mux(hwclk, RKX111_CLK_D_DSI_0_RKLINK_TX_SEL,
+			      RKX111_CLK_D_DSI_0_RKLINK_TX_SEL_CLK_D_DSI_0_PATTERN_GEN);
+	} else if (!strcmp(pattern_gen->name, "dsi1")) {
+		hwclk_set_mux(hwclk, RKX111_CLK_D_DSI_1_RKLINK_TX_SEL,
+			      RKX111_CLK_D_DSI_1_RKLINK_TX_SEL_CLK_D_DSI_1_PATTERN_GEN);
+	}
+}
+
+static void pattern_switch_clk_to_stream(struct pattern_gen *pattern_gen)
+{
+	struct rk_serdes *serdes = pattern_gen->chip->serdes;
+	struct hwclk *hwclk = serdes->chip[DEVICE_LOCAL].hwclk;
+
+	if (serdes->version != SERDES_V1)
+		return;
+
+	if (pattern_gen->chip != &serdes->chip[DEVICE_LOCAL])
+		return;
+
+	if (!strcmp(pattern_gen->name, "lvds0")) {
+		hwclk_set_mux(hwclk, RKX111_CLK_D_LVDS0_RKLINK_TX_SEL,
+			      RKX111_CLK_D_LVDS0_RKLINK_TX_SEL_CLK_D_LVDS0_RKLINK_TX_PRE);
+	} else if (!strcmp(pattern_gen->name, "lvds1")) {
+		hwclk_set_mux(hwclk, RKX111_CLK_D_LVDS1_RKLINK_TX_SEL,
+			      RKX111_CLK_D_LVDS1_RKLINK_TX_SEL_CLK_D_LVDS1_RKLINK_TX_PRE);
+	} else if (!strcmp(pattern_gen->name, "dual-lvds")) {
+		hwclk_set_mux(hwclk, RKX111_CLK_D_LVDS0_RKLINK_TX_SEL,
+			      RKX111_CLK_D_LVDS0_RKLINK_TX_SEL_CLK_D_LVDS0_RKLINK_TX_PRE);
+		hwclk_set_mux(hwclk, RKX111_CLK_D_LVDS1_RKLINK_TX_SEL,
+			      RKX111_CLK_D_LVDS1_RKLINK_TX_SEL_CLK_D_LVDS1_RKLINK_TX_PRE);
+	} else if (!strcmp(pattern_gen->name, "dsi0")) {
+		hwclk_set_mux(hwclk, RKX111_CLK_D_DSI_0_RKLINK_TX_SEL,
+			      RKX111_CLK_D_DSI_0_RKLINK_TX_SEL_CLK_D_DSI_0_RKLINK_TX_PRE);
+	} else if (!strcmp(pattern_gen->name, "dsi1")) {
+		hwclk_set_mux(hwclk, RKX111_CLK_D_DSI_1_RKLINK_TX_SEL,
+			      RKX111_CLK_D_DSI_1_RKLINK_TX_SEL_CLK_D_DSI_1_RKLINK_TX_PRE);
+	}
+}
+
+static int pattern_get_route(struct pattern_gen *pattern_gen)
+{
+	struct rk_serdes *serdes = pattern_gen->chip->serdes;
+	struct rk_serdes_route *route;
+	int i;
+
+	for (i = 0; i < serdes->route_nr; i++) {
+		route = serdes->route[i];
+
+		if (pattern_gen->chip == &serdes->chip[DEVICE_LOCAL]) {
+			if ((pattern_gen->type == route->local_port0) ||
+			    (pattern_gen->type == route->local_port1)) {
+				pattern_gen->route = route;
+				break;
+			}
+		}
+		if (pattern_gen->chip == &serdes->chip[DEVICE_REMOTE0]) {
+			if ((pattern_gen->type == route->remote0_port0) ||
+			    (pattern_gen->type == route->remote0_port1)) {
+				pattern_gen->route = route;
+				break;
+			}
+		}
+
+		if (pattern_gen->chip == &serdes->chip[DEVICE_REMOTE1]) {
+			if ((pattern_gen->type == route->remote1_port0) ||
+			    (pattern_gen->type == route->remote1_port1)) {
+				pattern_gen->route = route;
+				break;
+			}
+		}
+	}
+
+	if (i >= serdes->route_nr) {
+		dev_info(serdes->dev, "can't find the %s in route\n", pattern_gen->name);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void pattern_gen_enable(struct pattern_gen *pattern_gen)
+{
+	struct i2c_client *client = pattern_gen->chip->client;
+	struct rk_serdes *serdes = pattern_gen->chip->serdes;
+	struct videomode vm;
+	int ret;
+
+	ret = pattern_get_route(pattern_gen);
+	if (ret)
+		return;
+
+	memcpy(&vm, &pattern_gen->route->vm, sizeof(vm));
+
+	pattern_stop_stream(pattern_gen);
+	if (!strcmp(pattern_gen->name, "dual-lvds")) {
+		struct pattern_gen *lvds0_pat = pattern_gen + 1;
+		struct pattern_gen *lvds1_pat = pattern_gen + 2;
+
+		vm.hactive /= 2;
+		vm.hfront_porch /= 2;
+		vm.hback_porch /= 2;
+		vm.hsync_len /= 2;
+		vm.pixelclock /= 2;
+
+		pattern_switch_clk_to_pattern(pattern_gen, &vm);
+		pattern_gen_config(client, lvds0_pat, &vm);
+		pattern_gen_config(client, lvds1_pat, &vm);
+		serdes->i2c_write_reg(client, pattern_gen->link_src_reg,
+				      BIT(pattern_gen->link_src_offset + 16) |
+				      BIT(pattern_gen->link_src_offset));
+	} else {
+		pattern_switch_clk_to_pattern(pattern_gen, &vm);
+		pattern_gen_config(client, pattern_gen, &vm);
+		serdes->i2c_update_bits(client, pattern_gen->base + PATTERN_GEN_PATTERN_CTRL,
+					PATTERN_START_PCLK,
+					FIELD_PREP(PATTERN_START_PCLK, 1));
+	}
+
+	pattern_start_stream(pattern_gen, true);
 }
 
 static void pattern_gen_disable(struct pattern_gen *pattern_gen)
 {
 	struct i2c_client *client = pattern_gen->chip->client;
 	struct rk_serdes *serdes = pattern_gen->chip->serdes;
+	int ret;
 
-	serdes->i2c_write_reg(client, pattern_gen->link_src_reg,
-			      BIT(pattern_gen->link_src_offset + 16));
-	serdes->i2c_update_bits(client, pattern_gen->base + PATTERN_GEN_PATTERN_CTRL,
-				PATTERN_START_PCLK,
-				FIELD_PREP(PATTERN_START_PCLK, 0));
+	ret = pattern_get_route(pattern_gen);
+	if (ret)
+		return;
+
+	pattern_stop_stream(pattern_gen);
+	if (!strcmp(pattern_gen->name, "dual-lvds")) {
+		struct pattern_gen *lvds0_pat = pattern_gen + 1;
+		struct pattern_gen *lvds1_pat = pattern_gen + 2;
+
+		serdes->i2c_write_reg(client, lvds0_pat->link_src_reg,
+				      BIT(lvds0_pat->link_src_offset + 16));
+		serdes->i2c_write_reg(client, lvds1_pat->link_src_reg,
+				      BIT(lvds1_pat->link_src_offset + 16));
+		serdes->i2c_write_reg(client, pattern_gen->link_src_reg,
+				      BIT(pattern_gen->link_src_offset + 16));
+	} else {
+		serdes->i2c_write_reg(client, pattern_gen->link_src_reg,
+				      BIT(pattern_gen->link_src_offset + 16));
+		serdes->i2c_update_bits(client, pattern_gen->base + PATTERN_GEN_PATTERN_CTRL,
+					PATTERN_START_PCLK,
+					FIELD_PREP(PATTERN_START_PCLK, 0));
+	}
+
+	pattern_switch_clk_to_stream(pattern_gen);
+	pattern_start_stream(pattern_gen, false);
 }
 
 static ssize_t pattern_gen_write(struct file *file, const char __user *ubuf,
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx110.c b/kernel/drivers/mfd/rkx110_x120/rkx110.c
index 0e3fc4f..7a670ce 100644
--- a/kernel/drivers/mfd/rkx110_x120/rkx110.c
+++ b/kernel/drivers/mfd/rkx110_x120/rkx110.c
@@ -15,21 +15,30 @@
 		.base = RKX110_PATTERN_GEN_DSI0_BASE,
 		.link_src_reg = SER_GRF_SOC_CON4,
 		.link_src_offset = 12,
+		.type = RK_SERDES_DSI_RX0,
 	}, {
 		.name = "dsi1",
 		.base = RKX110_PATTERN_GEN_DSI1_BASE,
 		.link_src_reg = SER_GRF_SOC_CON4,
 		.link_src_offset = 13,
+		.type = RK_SERDES_DSI_RX1,
+	}, {
+		.name = "dual-lvds",
+		.link_src_reg = SER_GRF_SOC_CON1,
+		.link_src_offset = 14,
+		.type = RK_SERDES_DUAL_LVDS_RX,
 	}, {
 		.name = "lvds0",
 		.base = RKX110_PATTERN_GEN_LVDS0_BASE,
 		.link_src_reg = SER_GRF_SOC_CON4,
 		.link_src_offset = 14,
+		.type = RK_SERDES_LVDS_RX0,
 	}, {
 		.name = "lvds1",
 		.base = RKX110_PATTERN_GEN_LVDS1_BASE,
 		.link_src_reg = SER_GRF_SOC_CON4,
 		.link_src_offset = 15,
+		.type = RK_SERDES_LVDS_RX1,
 	},
 	{ /* sentinel */ }
 };
@@ -295,9 +304,11 @@
 
 int rkx110_lvds_rx_enable(struct rk_serdes *serdes, struct rk_serdes_route *route, int id)
 {
-	rkx110_combrxphy_set_mode(serdes, COMBRX_PHY_MODE_VIDEO_LVDS);
+	struct rk_serdes_panel *sd_panel = container_of(route, struct rk_serdes_panel, route);
+	struct rkx110_combrxphy *combrxphy = &sd_panel->combrxphy;
 
-	rkx110_combrxphy_power_on(serdes, id ? COMBPHY_1 : COMBPHY_0);
+	rkx110_combrxphy_set_mode(combrxphy, COMBRX_PHY_MODE_VIDEO_LVDS);
+	rkx110_combrxphy_power_on(serdes, combrxphy, DEVICE_LOCAL, id ? COMBPHY_1 : COMBPHY_0);
 
 	return 0;
 }
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx110_combrxphy.c b/kernel/drivers/mfd/rkx110_x120/rkx110_combrxphy.c
index 4152728..fb8eaa0 100644
--- a/kernel/drivers/mfd/rkx110_x120/rkx110_combrxphy.c
+++ b/kernel/drivers/mfd/rkx110_x120/rkx110_combrxphy.c
@@ -114,15 +114,18 @@
 #define LVDS0_MSBSEL(x)		HIWORD_UPDATE(x, BIT(2), 2)
 
 static void
-rkx110_combrxphy_dsi_timing_init(struct rk_serdes *ser, enum comb_phy_id id)
+rkx110_combrxphy_dsi_timing_init(struct rk_serdes *ser,
+				 struct rkx110_combrxphy *combrxphy,
+				 u8 dev_id, enum comb_phy_id id)
 {
 }
 
-static void rkx110_combrxphy_dsi_power_on(struct rk_serdes *ser, enum comb_phy_id id)
+static void rkx110_combrxphy_dsi_power_on(struct rk_serdes *ser,
+					  struct rkx110_combrxphy *combrxphy,
+					  u8 dev_id, enum comb_phy_id id)
 {
-	struct hwclk *hwclk = ser->chip[DEVICE_LOCAL].hwclk;
-	struct rkx110_combrxphy *combrxphy = &ser->combrxphy;
-	struct i2c_client *client = ser->chip[DEVICE_LOCAL].client;
+	struct hwclk *hwclk = ser->chip[dev_id].hwclk;
+	struct i2c_client *client = ser->chip[dev_id].client;
 	u32 val = 0;
 	u32 grf_base;
 
@@ -144,7 +147,7 @@
 	serdes_combphy_get_default_config(combrxphy->rate,
 					  &combrxphy->mipi_dphy_cfg);
 
-	switch (ser->dsi_rx.lanes) {
+	switch (combrxphy->lanes) {
 	case 4:
 		val |= LANE3_ENABLE(1);
 		fallthrough;
@@ -164,12 +167,14 @@
 	ser->i2c_write_reg(client, grf_base + GRF_MIPI_RX_CON0,
 			   PHY_MODE(COMBRX_PHY_MODE_VIDEO_MIPI) | val);
 
-	rkx110_combrxphy_dsi_timing_init(ser, id);
+	rkx110_combrxphy_dsi_timing_init(ser, combrxphy, dev_id, id);
 }
 
-static void rkx110_combrxphy_dsi_power_off(struct rk_serdes *ser, enum comb_phy_id id)
+static void rkx110_combrxphy_dsi_power_off(struct rk_serdes *ser,
+					   struct rkx110_combrxphy *combrxphy,
+					   u8 dev_id, enum comb_phy_id id)
 {
-	struct i2c_client *client = ser->chip[DEVICE_LOCAL].client;
+	struct i2c_client *client = ser->chip[dev_id].client;
 	u32 grf_base;
 
 	grf_base = id ? RKX110_GRF_MIPI1_BASE : RKX110_GRF_MIPI0_BASE;
@@ -178,9 +183,11 @@
 			    LANE1_ENABLE(0) | LANE0_ENABLE(0));
 }
 
-static void rkx110_combrxphy_lvds_power_on(struct rk_serdes *ser, enum comb_phy_id id)
+static void rkx110_combrxphy_lvds_power_on(struct rk_serdes *ser,
+					   struct rkx110_combrxphy *combrxphy,
+					   u8 dev_id, enum comb_phy_id id)
 {
-	struct i2c_client *client = ser->chip[DEVICE_LOCAL].client;
+	struct i2c_client *client = ser->chip[dev_id].client;
 	u32 grf_base = id ? RKX110_GRF_MIPI1_BASE : RKX110_GRF_MIPI0_BASE;
 	u32 val;
 	int ret;
@@ -209,9 +216,11 @@
 			   LVDS_RX1_PD(0) | LVDS_RX0_PD(0));
 }
 
-static void rkx110_combrxphy_lvds_power_off(struct rk_serdes *ser, enum comb_phy_id id)
+static void rkx110_combrxphy_lvds_power_off(struct rk_serdes *ser,
+					    struct rkx110_combrxphy *combrxphy,
+					    u8 dev_id, enum comb_phy_id id)
 {
-	struct i2c_client *client = ser->chip[DEVICE_LOCAL].client;
+	struct i2c_client *client = ser->chip[dev_id].client;
 	u32 grf_base = id ? RKX110_GRF_MIPI1_BASE : RKX110_GRF_MIPI0_BASE;
 
 	ser->i2c_write_reg(client, grf_base + GRF_MIPI_RX_CON0,
@@ -219,62 +228,65 @@
 			   LVDS_RX1_PD(1) | LVDS_RX0_PD(1));
 }
 
-static void rkx110_combrxphy_lvds_camera_power_on(struct rk_serdes *ser, enum comb_phy_id id)
+static void rkx110_combrxphy_lvds_camera_power_on(struct rk_serdes *ser,
+						  struct rkx110_combrxphy *combrxphy,
+						  u8 dev_id, enum comb_phy_id id)
 {
 }
 
-static void rkx110_combrxphy_lvds_camera_power_off(struct rk_serdes *ser, enum comb_phy_id id)
+static void rkx110_combrxphy_lvds_camera_power_off(struct rk_serdes *ser,
+						   struct rkx110_combrxphy *combrxphy,
+						   u8 dev_id, enum comb_phy_id id)
 {
 }
 
-void rkx110_combrxphy_power_on(struct rk_serdes *ser, enum comb_phy_id id)
+void rkx110_combrxphy_power_on(struct rk_serdes *ser, struct rkx110_combrxphy *combrxphy,
+			       u8 dev_id, enum comb_phy_id id)
 {
-	struct rkx110_combrxphy *combrxphy = &ser->combrxphy;
-
 	switch (combrxphy->mode) {
 	case COMBRX_PHY_MODE_VIDEO_MIPI:
-		rkx110_combrxphy_dsi_power_on(ser, id);
+		rkx110_combrxphy_dsi_power_on(ser, combrxphy, dev_id, id);
 		break;
 	case COMBRX_PHY_MODE_VIDEO_LVDS:
-		rkx110_combrxphy_lvds_power_on(ser, id);
+		rkx110_combrxphy_lvds_power_on(ser, combrxphy, dev_id, id);
 		break;
 	case COMBRX_PHY_MODE_LVDS_CAMERA:
-		rkx110_combrxphy_lvds_camera_power_on(ser, id);
+		rkx110_combrxphy_lvds_camera_power_on(ser, combrxphy, dev_id, id);
 		break;
 	default:
 		break;
 	}
 }
 
-void rkx110_combrxphy_power_off(struct rk_serdes *ser, enum comb_phy_id id)
+void rkx110_combrxphy_power_off(struct rk_serdes *ser, struct rkx110_combrxphy *combrxphy,
+				u8 dev_id, enum comb_phy_id id)
 {
-	struct rkx110_combrxphy *combrxphy = &ser->combrxphy;
-
 	switch (combrxphy->mode) {
 	case COMBRX_PHY_MODE_VIDEO_MIPI:
-		rkx110_combrxphy_dsi_power_off(ser, id);
+		rkx110_combrxphy_dsi_power_off(ser, combrxphy, dev_id, id);
 		break;
 	case COMBRX_PHY_MODE_VIDEO_LVDS:
-		rkx110_combrxphy_lvds_power_off(ser, id);
+		rkx110_combrxphy_lvds_power_off(ser, combrxphy, dev_id, id);
 		break;
 	case COMBRX_PHY_MODE_LVDS_CAMERA:
-		rkx110_combrxphy_lvds_camera_power_off(ser, id);
+		rkx110_combrxphy_lvds_camera_power_off(ser, combrxphy, dev_id, id);
 		break;
 	default:
 		break;
 	}
 }
 
-void rkx110_combrxphy_set_rate(struct rk_serdes *ser, u64 rate)
+void rkx110_combrxphy_set_rate(struct rkx110_combrxphy *combrxphy, u64 rate)
 {
-	struct rkx110_combrxphy *combrxphy = &ser->combrxphy;
-
 	combrxphy->rate = rate;
 }
 
-void rkx110_combrxphy_set_mode(struct rk_serdes *ser, enum combrx_phy_mode mode)
+void rkx110_combrxphy_set_lanes(struct rkx110_combrxphy *combrxphy, uint8_t lanes)
 {
-	struct rkx110_combrxphy *combrxphy = &ser->combrxphy;
+	combrxphy->lanes = lanes;
+}
 
+void rkx110_combrxphy_set_mode(struct rkx110_combrxphy *combrxphy, enum combrx_phy_mode mode)
+{
 	combrxphy->mode = mode;
 }
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx110_dsi_rx.c b/kernel/drivers/mfd/rkx110_x120/rkx110_dsi_rx.c
index 8c012ca..eecfe97 100644
--- a/kernel/drivers/mfd/rkx110_x120/rkx110_dsi_rx.c
+++ b/kernel/drivers/mfd/rkx110_x120/rkx110_dsi_rx.c
@@ -55,7 +55,9 @@
 
 void rkx110_dsi_rx_enable(struct rk_serdes *ser, struct rk_serdes_route *route, int id)
 {
-	struct rkx110_dsi_rx *dsi = &ser->dsi_rx;
+	struct rk_serdes_panel *sd_panel = container_of(route, struct rk_serdes_panel, route);
+	struct rkx110_dsi_rx *dsi = &sd_panel->dsi_rx;
+	struct rkx110_combrxphy *combrxphy = &sd_panel->combrxphy;
 	const struct videomode *vm = &route->vm;
 	unsigned long pixelclock;
 	u32 hactive, vactive;
@@ -87,9 +89,10 @@
 
 	rate = DIV_ROUND_CLOSEST_ULL(pixelclock, dsi->lanes);
 
-	rkx110_combrxphy_set_mode(ser, COMBRX_PHY_MODE_VIDEO_MIPI);
-	rkx110_combrxphy_set_rate(ser, rate * MSEC_PER_SEC);
-	rkx110_combrxphy_power_on(ser, id ? COMBPHY_1 : COMBPHY_0);
+	rkx110_combrxphy_set_mode(combrxphy, COMBRX_PHY_MODE_VIDEO_MIPI);
+	rkx110_combrxphy_set_rate(combrxphy, rate * MSEC_PER_SEC);
+	rkx110_combrxphy_set_lanes(combrxphy, dsi->lanes);
+	rkx110_combrxphy_power_on(ser, combrxphy, DEVICE_LOCAL, id ? COMBPHY_1 : COMBPHY_0);
 
 	csi_base = id ? RKX110_CSI2HOST1_BASE : RKX110_CSI2HOST0_BASE;
 	dsirx_base = id ? RKX110_DSI_RX1_BASE : RKX110_DSI_RX0_BASE;
@@ -120,5 +123,8 @@
 
 void rkx110_dsi_rx_disable(struct rk_serdes *ser, struct rk_serdes_route *route, int id)
 {
-	rkx110_combrxphy_power_off(ser, id ? COMBPHY_1 : COMBPHY_0);
+	struct rk_serdes_panel *sd_panel = container_of(route, struct rk_serdes_panel, route);
+	struct rkx110_combrxphy *combrxphy = &sd_panel->combrxphy;
+
+	rkx110_combrxphy_power_off(ser, combrxphy, DEVICE_LOCAL, id ? COMBPHY_1 : COMBPHY_0);
 }
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx110_linktx.c b/kernel/drivers/mfd/rkx110_x120/rkx110_linktx.c
index 007a825..89cb11a 100644
--- a/kernel/drivers/mfd/rkx110_x120/rkx110_linktx.c
+++ b/kernel/drivers/mfd/rkx110_x120/rkx110_linktx.c
@@ -55,6 +55,7 @@
 #define SER_EN				BIT(0)
 
 #define RKLINK_TX_VIDEO_CTRL		LINK_REG(0x0004)
+#define VIDEO_REPKT_LENGTH_MASK		GENMASK(29, 16)
 #define VIDEO_REPKT_LENGTH(x)		UPDATE(x, 29, 16)
 #define DUAL_LVDS_CYCLE_DIFF(x)		UPDATE(x, 13, 4)
 #define PIXEL_VSYNC_SEL			BIT(3)
@@ -86,11 +87,13 @@
  #define DSI_CHANNEL_SWAP		UPDATE(2, 31, 30)
  #define DSI0_SPLIT_MODE		UPDATE(0, 31, 30)
  #define DSI1_SPLIT_MODE		UPDATE(3, 31, 30)
+#define DSI_DST_VPORCH_MASK		GENMASK(29, 0)
  #define DSI_VFP(x)			UPDATE(x, 29, 20)
  #define DSI_VBP(x)			UPDATE(x, 19, 10)
  #define DSI_VSA(x)			UPDATE(x, 9, 0)
 
 #define SER_RKLINK_DSI_REC3(x)		LINK_REG(0x0014 + 0x10 * x)
+ #define DSI_DELAY_LENGTH_MASK		GENMASK(31, 12)
  #define DSI_DELAY_LENGTH(x)		UPDATE(x, 31, 12)
  #define DSI_HSA(x)			UPDATE(x, 11, 0)
 
@@ -101,7 +104,33 @@
 #define SER_RKLINK_AUDIO_RECOVER	LINK_REG(0x0034)
 #define SER_RKLINK_AUDIO_FM_STATUS	LINK_REG(0x0038)
 #define SER_RKLINK_FIFO_STATUS		LINK_REG(0x003C)
+ #define CH1_CMD_FIFO_UNDERRUN		BIT(24)
+ #define CH0_CMD_FIFO_UNDERRUN		BIT(23)
+ #define DATA1_FIFO_UNDERRUN		BIT(22)
+ #define DATA0_FIFO_UNDERRUN		BIT(21)
+ #define AUDIO_FIFO_UNDERRUN		BIT(20)
+ #define LVDS1_FIFO_UNDERRUN		BIT(19)
+ #define LVDS0_FIFO_UNDERRUN		BIT(18)
+ #define DSI_CH1_FIFO_UNDERRUN		BIT(17)
+ #define DSI_CH0_FIFO_UNDERRUN		BIT(16)
+ #define CH1_CMD_FIFO_OVERFLOW		BIT(8)
+ #define CH0_CMD_FIFO_OVERFLOW		BIT(7)
+ #define DATA0_FIFO_OVERFLOW		BIT(6)
+ #define DATA1_FIFO_OVERFLOW		BIT(5)
+ #define AUDIO_FIFO_OVERFLOW		BIT(4)
+ #define LVDS1_FIFO_OVERFLOW		BIT(3)
+ #define LVDS0_FIFO_OVERFLOW		BIT(2)
+ #define DSI_CH1_FIFO_OVERFLOW		BIT(1)
+ #define DSI_CH0_FIFO_OVERFLOW		BIT(0)
 #define SER_RKLINK_SOURCE_IRQ_EN	LINK_REG(0x0040)
+ #define TRAIN_DONE_IRQ_FLAG		BIT(19)
+ #define FIFO_UNDERRUN_IRQ_FLAG		BIT(18)
+ #define FIFO_OVERFLOW_IRQ_FLAG		BIT(17)
+ #define AUDIO_FM_IRQ_OUTPUT_FLAG	BIT(16)
+ #define TRAIN_DONE_IRQ_OUTPUT_EN	BIT(3)
+ #define FIFO_UNDERRUN_IRQ_OUTPUT_EN	BIT(2)
+ #define FIFO_OVERFLOW_IRQ_OUTPUT_EN	BIT(1)
+ #define AUDIO_FM_IRQ_OUTPUT_EN		BIT(0)
 
 #define SER_RKLINK_TRAIN_CTRL		LINK_REG(0x0044)
 #define SER_RKLINK_I2C_CFG		LINK_REG(0x00C0)
@@ -144,7 +173,9 @@
 #define PCS_REG24(id)			PCS_REG(id, 0x24)
 #define PCS_REG28(id)			PCS_REG(id, 0x28)
 #define PCS_REG30(id)			PCS_REG(id, 0x30)
+#define PCS_INT_STARTUP(x)		HIWORD_UPDATE(x, GENMASK(15, 0), 0)
 #define PCS_REG34(id)			PCS_REG(id, 0x34)
+#define PCS_INT_REMOTE_MODE(x)		HIWORD_UPDATE(x, GENMASK(15, 0), 0)
 #define PCS_REG40(id)			PCS_REG(id, 0x40)
 
 #define PMA_REG(id, x)			((x) + RKX110_SER_PMA0_BASE + (id) * RKX110_SER_PMA_OFFSET)
@@ -194,6 +225,15 @@
 #define SER_PMA_LOAD0A(id)		PMA_REG(id, 0x38)
  #define PMA_CLK_8X_DIV_MASK		HIWORD_MASK(7, 1)
  #define PMA_CLK_8X_DIV(x)		HIWORD_UPDATE(x, GENMASK(7, 1), 1)
+
+#define SER_PMA_IRQ_EN(id)		PMA_REG(id, 0xF0)
+ #define FORCE_INITIAL_IRQ_EN		HIWORD_UPDATE(1, BIT(3), 3)
+ #define RTERM_ONCE_TIMEOUT_IRQ_EN	HIWORD_UPDATE(1, BIT(1), 1)
+ #define PLL_LOCK_TIMEOUT_IRQ_EN	HIWORD_UPDATE(1, BIT(0), 0)
+#define SER_PMA_IRQ_STATUS(id)		PMA_REG(id, 0xF4)
+ #define FORCE_INITIAL_PULSE_STATUS	BIT(3)
+ #define RTERM_ONCE_TIMEOUT_STATUS	BIT(1)
+ #define PLL_LOCK_TIMEOUT_STATUS	BIT(0)
 
 enum {
 	SER_LINK_CH_ID0 = 0,
@@ -422,53 +462,124 @@
 	serdes->i2c_write_reg(client, RKLINK_TX_VIDEO_CTRL, val);
 }
 
-static int rk_serdes_link_tx_ctrl_enable(struct rk_serdes *serdes,
-					 struct rk_serdes_route *route,
-					 u8 remote_id)
+static int rkx110_linktx_ser_enable(struct rk_serdes *serdes, u8 dev_id, bool enable)
 {
-	struct hwclk *hwclk = serdes->chip[remote_id].hwclk;
-	struct i2c_client *client;
-	u32 ctrl_val, val;
-	u32 rx_src;
-	u32 stream_type;
+	struct i2c_client *client = serdes->chip[dev_id].client;
 
-	if (route->stream_type == STREAM_DISPLAY) {
-		client = serdes->chip[DEVICE_LOCAL].client;
-		stream_type = SER_STREAM_DISPLAY;
-	} else {
-		client = serdes->chip[remote_id].client;
-		stream_type = SER_STREAM_CAMERA;
-	}
+	serdes->i2c_update_bits(client, RKLINK_TX_SERDES_CTRL, SER_EN, enable ? SER_EN : 0);
 
-	serdes->i2c_read_reg(client, RKLINK_TX_SERDES_CTRL, &ctrl_val);
+	return 0;
+}
 
-	ctrl_val &= ~(SER_EN | SERDES_DUAL_LANE_EN | SER_CH1_EN | SERDES_MIRROR_EN |
-		      CH1_LVDS_SEL_EN);
-	ctrl_val |= stream_type;
-	if (serdes->route_flag & ROUTE_MULTI_LANE)
-		ctrl_val |= SERDES_DUAL_LANE_EN;
-	if (serdes->route_flag & ROUTE_MULTI_CHANNEL)
-		ctrl_val |= SER_CH1_EN;
-	if (serdes->route_flag & ROUTE_MULTI_MIRROR)
-		ctrl_val |= SERDES_MIRROR_EN;
-	if (serdes->route_flag & ROUTE_MULTI_LVDS_INPUT)
-		ctrl_val |= CH1_LVDS_SEL_EN;
+static int rk110_linktx_dual_lane_enable(struct rk_serdes *serdes, u8 dev_id, bool enable)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
 
-	serdes->i2c_write_reg(client, RKLINK_TX_SERDES_CTRL, ctrl_val);
+	serdes->i2c_update_bits(client, RKLINK_TX_SERDES_CTRL, SERDES_DUAL_LANE_EN,
+				enable ? SERDES_DUAL_LANE_EN : 0);
 
-	serdes->i2c_read_reg(client, RKLINK_TX_VIDEO_CTRL, &val);
-	rx_src = rk_serdes_get_stream_source(serdes, route->local_port0);
-	val |= rx_src;
-	serdes->i2c_write_reg(client, RKLINK_TX_VIDEO_CTRL, val);
+	return 0;
+}
 
-	if (route->local_port0 & RK_SERDES_DUAL_LVDS_RX) {
-		hwclk_set_rate(hwclk, RKX110_CPS_CLK_2X_LVDS_RKLINK_TX, route->vm.pixelclock);
-		dev_info(serdes->dev, "RKX110_CPS_CLK_2X_LVDS_RKLINK_TX:%d\n",
-			 hwclk_get_rate(hwclk, RKX110_CPS_CLK_2X_LVDS_RKLINK_TX));
-	}
+void rkx110_linktx_video_enable(struct rk_serdes *serdes, u8 dev_id, bool enable)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
 
-	ctrl_val |= SER_EN;
-	serdes->i2c_write_reg(client, RKLINK_TX_SERDES_CTRL, ctrl_val);
+	serdes->i2c_update_bits(client, RKLINK_TX_SERDES_CTRL, VIDEO_EN, enable ? VIDEO_EN : 0);
+}
+
+static int rk110_linktx_dual_channel_enable(struct rk_serdes *serdes, u8 dev_id, bool enable)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+
+	serdes->i2c_update_bits(client, RKLINK_TX_SERDES_CTRL, SER_CH1_EN,
+				enable ? SER_CH1_EN : 0);
+
+	return 0;
+}
+
+static int rk110_linktx_config_pkg_length(struct rk_serdes *serdes, u8 dev_id, u32 length)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+
+	serdes->i2c_update_bits(client, RKLINK_TX_VIDEO_CTRL, VIDEO_REPKT_LENGTH_MASK,
+				VIDEO_REPKT_LENGTH(length));
+
+	return 0;
+}
+
+static int rk110_linktx_stream_type_cfg(struct rk_serdes *serdes, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+
+	if (serdes->stream_type == STREAM_DISPLAY)
+		serdes->i2c_update_bits(client, RKLINK_TX_SERDES_CTRL, STREAM_TYPE_MASK,
+					SER_STREAM_DISPLAY);
+	else
+		serdes->i2c_update_bits(client, RKLINK_TX_SERDES_CTRL, STREAM_TYPE_MASK,
+					SER_STREAM_CAMERA);
+
+	return 0;
+}
+
+static int rk110_linktx_replicate_enable(struct rk_serdes *serdes, u8 dev_id, bool enable)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+
+	serdes->i2c_update_bits(client, RKLINK_TX_SERDES_CTRL, SERDES_MIRROR_EN,
+				enable ? SERDES_MIRROR_EN : 0);
+
+	return 0;
+}
+
+static int rkx110_linktx_dual_input_cfg(struct rk_serdes *serdes, u8 dev_id, bool is_lvds)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+
+	serdes->i2c_update_bits(client, RKLINK_TX_SERDES_CTRL, CH1_LVDS_SEL_EN,
+				is_lvds ? CH1_LVDS_SEL_EN : 0);
+
+	return 0;
+}
+
+static int rkx110_linktx_input_port_cfg(struct rk_serdes *serdes, u8 dev_id, u32 port)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 val;
+
+	val = rk_serdes_get_stream_source(serdes, port);
+	serdes->i2c_update_bits(client, RKLINK_TX_VIDEO_CTRL, SOURCE_ID_MASK, val);
+
+	return 0;
+}
+
+int rkx110_linktx_dsi_rec_start(struct rk_serdes *serdes, u8 dev_id, u8 dsi_id, bool enable)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+
+	serdes->i2c_update_bits(client, SER_RKLINK_DSI_REC0(dsi_id), DSI_REC_START,
+				enable ? DSI_REC_START : 0);
+
+	return 0;
+}
+
+int rkx110_linktx_dsi_type_select(struct rk_serdes *serdes, u8 dev_id, u8 dsi_id, bool is_cmd)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+
+	serdes->i2c_update_bits(client, SER_RKLINK_DSI_REC0(dsi_id), DSI_CMD_TYPE,
+				is_cmd ? DSI_CMD_TYPE : 0);
+
+	return 0;
+}
+
+int rkx110_linktx_dsi_deley_length_config(struct rk_serdes *serdes, u8 dev_id, u8 dsi_id,
+					  u32 length)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+
+	serdes->i2c_update_bits(client, SER_RKLINK_DSI_REC3(dsi_id), DSI_DELAY_LENGTH_MASK,
+				DSI_DELAY_LENGTH(length));
 
 	return 0;
 }
@@ -479,22 +590,22 @@
 	struct videomode *vm = &route->vm;
 	struct i2c_client *client = serdes->chip[DEVICE_LOCAL].client;
 	struct hwclk *hwclk = serdes->chip[DEVICE_LOCAL].hwclk;
+	struct rk_serdes_panel *sd_panel = container_of(route, struct rk_serdes_panel, route);
+	struct rkx110_dsi_rx *dsi = &sd_panel->dsi_rx;
 	int delay_length;
 	u32 value, type;
 
-	if (id == 0) {
-		hwclk_set_rate(hwclk, RKX110_CPS_DCLK_D_DSI_0_REC_RKLINK_TX,
-			       route->vm.pixelclock);
-		dev_info(serdes->dev, "RKX110_CPS_DCLK_D_DSI_0_REC_RKLINK_TX:%d\n",
-			 hwclk_get_rate(hwclk, RKX110_CPS_DCLK_D_DSI_0_REC_RKLINK_TX));
-	} else if (id == 1) {
+	if (id) {
 		hwclk_set_rate(hwclk, RKX110_CPS_DCLK_D_DSI_1_REC_RKLINK_TX,
 			       route->vm.pixelclock);
 		dev_info(serdes->dev, "RKX110_CPS_DCLK_D_DSI_1_REC_RKLINK_TX:%d\n",
 			 hwclk_get_rate(hwclk, RKX110_CPS_DCLK_D_DSI_1_REC_RKLINK_TX));
 
 	} else {
-		return 0;
+		hwclk_set_rate(hwclk, RKX110_CPS_DCLK_D_DSI_0_REC_RKLINK_TX,
+			       route->vm.pixelclock);
+		dev_info(serdes->dev, "RKX110_CPS_DCLK_D_DSI_0_REC_RKLINK_TX:%d\n",
+			 hwclk_get_rate(hwclk, RKX110_CPS_DCLK_D_DSI_0_REC_RKLINK_TX));
 	}
 
 	/* config SER_RKLINK_DSI_REC1 */
@@ -507,17 +618,25 @@
 	value = DSI_VFP(vm->vfront_porch);
 	value |= DSI_VBP(vm->vback_porch);
 	value |= DSI_VSA(vm->vsync_len);
-	serdes->i2c_write_reg(client, SER_RKLINK_DSI_REC2(id), value);
+	serdes->i2c_update_bits(client, SER_RKLINK_DSI_REC2(id), DSI_DST_VPORCH_MASK, value);
 
-	if (id)
-		type = (serdes->route_flag & ROUTE_MULTI_CHANNEL) ? DSI_0_DST(0) : DSI_0_DST(2);
-	else
-		type = (serdes->route_flag & ROUTE_MULTI_CHANNEL) ? DSI_0_DST(3) : DSI_0_DST(1);
+	if (route->local_port0) {
+		if (serdes->route_nr == 2) {
+			type = id ? DSI_0_DST(2) : DSI_0_DST(1);
+		} else {
+			if (id)
+				type = (serdes->channel_nr == 2) ? DSI_0_DST(0) : DSI_0_DST(2);
+			else
+				type = (serdes->channel_nr == 2) ? DSI_0_DST(3) : DSI_0_DST(1);
+		}
+	} else {
+		type = id ? DSI_0_DST(1) : DSI_0_DST(2);
+	}
 
 	serdes->i2c_update_bits(client, SER_RKLINK_DSI_REC2(0), DSI_0_DST_MASK, type);
 
 	/* config SER_RKLINK_DSI_REC3 */
-	if (serdes->dsi_rx.mode_flags & SERDES_MIPI_DSI_MODE_VIDEO)
+	if (dsi->mode_flags & SERDES_MIPI_DSI_MODE_VIDEO)
 		delay_length = vm->hsync_len + vm->hback_porch +
 			       vm->hactive + vm->hfront_porch;
 	else
@@ -531,33 +650,12 @@
 
 	/* config SER_RKLINK_DSI_REC0 */
 	value = DSI_REC_START;
-	if (!(serdes->dsi_rx.mode_flags & SERDES_MIPI_DSI_MODE_VIDEO))
+	if (!(dsi->mode_flags & SERDES_MIPI_DSI_MODE_VIDEO))
 		value |= DSI_CMD_TYPE;
 
 	value |= DSI_HACT(vm->hactive);
 	value |= DSI_VACT(vm->vactive);
 	serdes->i2c_write_reg(client, SER_RKLINK_DSI_REC0(id), value);
-
-	return 0;
-}
-
-static int rk110_linktx_cfg(struct rk_serdes *serdes, struct rk_serdes_route *route)
-{
-	u8 remote_id = 0;
-
-	rk_serdes_link_tx_ctrl_enable(serdes, route, remote_id);
-
-	if (route->local_port0 & RK_SERDES_DSI_RX0) {
-		rk_serdes_link_tx_dsi_enable(serdes, route, 0);
-		if (serdes->route_flag & ROUTE_MULTI_DSI_INPUT)
-			rk_serdes_link_tx_dsi_enable(serdes, route, 1);
-	}
-
-	if (route->local_port0 & RK_SERDES_DSI_RX1) {
-		rk_serdes_link_tx_dsi_enable(serdes, route, 1);
-		if (serdes->route_flag & ROUTE_MULTI_DSI_INPUT)
-			rk_serdes_link_tx_dsi_enable(serdes, route, 0);
-	}
 
 	return 0;
 }
@@ -583,24 +681,96 @@
 	return 0;
 }
 
-int rkx110_linktx_enable(struct rk_serdes *serdes, struct rk_serdes_route *route)
+static int rkx110_display_linktx_ctrl_enable(struct rk_serdes *serdes,
+					     struct rk_serdes_route *route,
+					     u8 dev_id)
 {
-	rk110_linktx_cfg(serdes, route);
+	struct hwclk *hwclk = serdes->chip[dev_id].hwclk;
+	bool enable;
+	bool is_lvds = false;
+
+	rk110_linktx_stream_type_cfg(serdes, dev_id);
+
+	enable = (serdes->lane_nr == 2) ? true : false;
+	rk110_linktx_dual_lane_enable(serdes, dev_id, enable);
+
+	enable = (serdes->channel_nr == 2) ? true : false;
+	rk110_linktx_dual_channel_enable(serdes, dev_id, enable);
+
+	enable = (route->route_flag & ROUTE_MULTI_MIRROR) ? true : false;
+	rk110_linktx_replicate_enable(serdes, dev_id, enable);
+
+	if (((route->local_port0 == RK_SERDES_LVDS_RX0) ||
+	     (route->local_port0 == RK_SERDES_LVDS_RX1) ||
+	     (route->local_port1 == RK_SERDES_LVDS_RX0) ||
+	     (route->local_port1 == RK_SERDES_LVDS_RX1)) &&
+	    (serdes->route_nr == 2))
+		is_lvds = true;
+	rkx110_linktx_dual_input_cfg(serdes, dev_id, is_lvds);
+
+	if (route->local_port0) {
+		rkx110_linktx_input_port_cfg(serdes, dev_id, route->local_port0);
+	} else {
+		if (route->local_port1 == RK_SERDES_LVDS_RX0)
+			rkx110_linktx_input_port_cfg(serdes, dev_id, RK_SERDES_LVDS_RX1);
+		else if (route->local_port1 == RK_SERDES_LVDS_RX1)
+			rkx110_linktx_input_port_cfg(serdes, dev_id, RK_SERDES_LVDS_RX0);
+		else if (route->local_port1 == RK_SERDES_DSI_RX0)
+			rkx110_linktx_input_port_cfg(serdes, dev_id, RK_SERDES_DSI_RX1);
+		else if (route->local_port1 == RK_SERDES_DSI_RX1)
+			rkx110_linktx_input_port_cfg(serdes, dev_id, RK_SERDES_DSI_RX0);
+
+	}
+
+	if (route->local_port0 & RK_SERDES_DUAL_LVDS_RX) {
+		hwclk_set_rate(hwclk, RKX110_CPS_CLK_2X_LVDS_RKLINK_TX, route->vm.pixelclock);
+		dev_info(serdes->dev, "RKX110_CPS_CLK_2X_LVDS_RKLINK_TX:%d\n",
+			 hwclk_get_rate(hwclk, RKX110_CPS_CLK_2X_LVDS_RKLINK_TX));
+	}
+
+	if (serdes->version == SERDES_V1) {
+		/*
+		 * The serdes v1 have a bug when enable video suspend function, which
+		 * is used to enhance the i2c frequency. A workaround ways to do it is
+		 * reducing the video packet length:
+		 * length = ((hactive x 24 / 32 / 16) + 15) / 16 * 16
+		 */
+		u32 length;
+
+		length = route->vm.hactive * 24 / 32 / 16;
+		length = (length + 15) / 16 * 16;
+		rk110_linktx_config_pkg_length(serdes, dev_id, length);
+	}
+
+	rkx110_linktx_ser_enable(serdes, dev_id, true);
+
+	return 0;
+}
+
+int rkx110_display_linktx_enable(struct rk_serdes *serdes, struct rk_serdes_route *route)
+{
+	rkx110_display_linktx_ctrl_enable(serdes, route, DEVICE_LOCAL);
+
+	if (route->local_port0 & RK_SERDES_DSI_RX0)
+		rk_serdes_link_tx_dsi_enable(serdes, route, 0);
+
+	if (route->local_port0 & RK_SERDES_DSI_RX1)
+		rk_serdes_link_tx_dsi_enable(serdes, route, 1);
+
+	if (route->local_port1 & RK_SERDES_DSI_RX0)
+		rk_serdes_link_tx_dsi_enable(serdes, route, 0);
+
+	if (route->local_port1 & RK_SERDES_DSI_RX1)
+		rk_serdes_link_tx_dsi_enable(serdes, route, 1);
+
 	rk110_ser_pcs_cfg(serdes, route, 0);
 	rk110_ser_pma_cfg(serdes, route, 0);
-	if (serdes->route_flag & ROUTE_MULTI_LANE) {
+	if (serdes->lane_nr == 2) {
 		rk110_ser_pcs_cfg(serdes, route, 1);
 		rk110_ser_pma_cfg(serdes, route, 1);
 	}
 
 	return 0;
-}
-
-void rkx110_linktx_video_enable(struct rk_serdes *serdes, u8 dev_id, bool enable)
-{
-	struct i2c_client *client = serdes->chip[dev_id].client;
-
-	serdes->i2c_update_bits(client, RKLINK_TX_SERDES_CTRL, VIDEO_EN, enable ? VIDEO_EN : 0);
 }
 
 void rkx110_linktx_channel_enable(struct rk_serdes *serdes, u8 ch_id, u8 dev_id, bool enable)
@@ -636,7 +806,7 @@
 	}
 }
 
-void rkx110_linktx_wait_link_ready(struct rk_serdes *serdes, u8 id)
+int rkx110_linktx_wait_link_ready(struct rk_serdes *serdes, u8 id)
 {
 	struct i2c_client *client = serdes->chip[DEVICE_LOCAL].client;
 	u32 val;
@@ -656,6 +826,8 @@
 		dev_err(&client->dev, "wait link ready timeout: 0x%08x\n", val);
 	else
 		dev_info(&client->dev, "link success: 0x%08x\n", val);
+
+	return ret;
 }
 
 void rkx110_pma_set_rate(struct rk_serdes *serdes, struct rk_serdes_pma_pll *pll,
@@ -736,3 +908,346 @@
 
 	serdes->i2c_update_bits(client, SER_GRF_SOC_CON7, mask, val);
 }
+
+static void rkx110_linktx_irq_enable(struct rk_serdes *serdes, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+
+	serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, SER_IRQ_LINK_EN);
+
+	serdes->i2c_write_reg(client, SER_RKLINK_SOURCE_IRQ_EN, TRAIN_DONE_IRQ_OUTPUT_EN |
+			      FIFO_UNDERRUN_IRQ_OUTPUT_EN | FIFO_OVERFLOW_IRQ_OUTPUT_EN);
+}
+
+static void rkx110_linktx_irq_disable(struct rk_serdes *serdes, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 val = 0;
+
+	serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, SER_IRQ_LINK_DIS);
+	serdes->i2c_read_reg(client, SER_RKLINK_SOURCE_IRQ_EN, &val);
+	val &= ~(SER_RKLINK_SOURCE_IRQ_EN | TRAIN_DONE_IRQ_OUTPUT_EN |
+		 FIFO_UNDERRUN_IRQ_OUTPUT_EN | FIFO_OVERFLOW_IRQ_OUTPUT_EN);
+	serdes->i2c_write_reg(client, SER_RKLINK_SOURCE_IRQ_EN, val);
+}
+
+static void rkx110_linktx_fifo_handler(struct rk_serdes *serdes, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 value;
+
+	serdes->i2c_read_reg(client, SER_RKLINK_FIFO_STATUS, &value);
+	dev_err(serdes->dev, "ser rklink fifo status:0x%x\n", value);
+
+	if (value & CH1_CMD_FIFO_UNDERRUN)
+		dev_err(serdes->dev, "linktx ch1 cmd fifo underrun\n");
+	if (value & CH0_CMD_FIFO_UNDERRUN)
+		dev_err(serdes->dev, "linktx ch0 cmd fifo underrun\n");
+	if (value & DATA1_FIFO_UNDERRUN)
+		dev_err(serdes->dev, "linktx data1 fifo underrun\n");
+	if (value & DATA0_FIFO_UNDERRUN)
+		dev_err(serdes->dev, "linktx data0 fifo underrun\n");
+	if (value & AUDIO_FIFO_UNDERRUN)
+		dev_err(serdes->dev, "linktx audio fifo underrun\n");
+	if (value & LVDS1_FIFO_UNDERRUN)
+		dev_err(serdes->dev, "linktx lvds1 fifo underrun\n");
+	if (value & LVDS0_FIFO_UNDERRUN)
+		dev_err(serdes->dev, "linktx lvds0 fifo underrun\n");
+	if (value & DSI_CH1_FIFO_UNDERRUN)
+		dev_err(serdes->dev, "linktx dsi ch1 fifo underrun\n");
+	if (value & DSI_CH0_FIFO_UNDERRUN)
+		dev_err(serdes->dev, "linktx dsi ch0 fifo underrun\n");
+	if (value & CH1_CMD_FIFO_OVERFLOW)
+		dev_err(serdes->dev, "linktx ch1 cmd fifo overflow\n");
+	if (value & CH0_CMD_FIFO_OVERFLOW)
+		dev_err(serdes->dev, "linktx ch0 cmd fifo overflow\n");
+	if (value & DATA1_FIFO_OVERFLOW)
+		dev_err(serdes->dev, "linktx data1 fifo overflow\n");
+	if (value & DATA0_FIFO_OVERFLOW)
+		dev_err(serdes->dev, "linktx data0 fifo overflow\n");
+	if (value & AUDIO_FIFO_OVERFLOW)
+		dev_err(serdes->dev, "linktx audio fifo overflow\n");
+	if (value & LVDS1_FIFO_OVERFLOW)
+		dev_err(serdes->dev, "linktx lvds1 fifo overflow\n");
+	if (value & LVDS0_FIFO_OVERFLOW)
+		dev_err(serdes->dev, "linktx lvds0 fifo overflow\n");
+	if (value & DSI_CH1_FIFO_OVERFLOW)
+		dev_err(serdes->dev, "linktx dsi ch1 fifo overflow\n");
+	if (value & DSI_CH0_FIFO_OVERFLOW)
+		dev_err(serdes->dev, "linktx dsi ch0 fifo overflow\n");
+
+	/* clear fifo status */
+	serdes->i2c_write_reg(client, SER_RKLINK_FIFO_STATUS, value);
+}
+
+static void rkx110_linktx_irq_handler(struct rk_serdes *serdes, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 flag, value;
+	int i = 0;
+
+	serdes->i2c_read_reg(client, SER_RKLINK_SOURCE_IRQ_EN, &flag);
+	flag &= TRAIN_DONE_IRQ_FLAG | FIFO_UNDERRUN_IRQ_FLAG | FIFO_OVERFLOW_IRQ_FLAG |
+		AUDIO_FM_IRQ_OUTPUT_FLAG;
+	dev_info(serdes->dev, "linktx irq flag:0x%08x\n", flag);
+	while (flag) {
+		switch (flag & BIT(i)) {
+		case TRAIN_DONE_IRQ_FLAG:
+			serdes->i2c_read_reg(client, SER_RKLINK_TRAIN_CTRL, &value);
+			dev_info(serdes->dev, "linktx train done, status:0x%08x\n", value);
+			/* write any thing to train ctrl will clear the train done irq flag */
+			serdes->i2c_write_reg(client, SER_RKLINK_TRAIN_CTRL, value);
+			break;
+		case FIFO_UNDERRUN_IRQ_FLAG:
+		case FIFO_OVERFLOW_IRQ_FLAG:
+			flag &= ~(FIFO_UNDERRUN_IRQ_FLAG | FIFO_OVERFLOW_IRQ_FLAG);
+			rkx110_linktx_fifo_handler(serdes, dev_id);
+			break;
+		case AUDIO_FM_IRQ_OUTPUT_FLAG:
+			break;
+		default:
+			break;
+		}
+		flag &= ~BIT(i);
+		i++;
+	}
+}
+
+static void rkx110_pcs_irq_enable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 val;
+
+	val = pcs_id ? SER_IRQ_PCS1_EN : SER_IRQ_PCS0_EN;
+	serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, val);
+
+	serdes->i2c_write_reg(client, PCS_REG30(pcs_id), PCS_INT_STARTUP(0xffff));
+	serdes->i2c_write_reg(client, PCS_REG34(pcs_id), PCS_INT_REMOTE_MODE(0xffff));
+}
+
+static void rkx110_pcs_irq_disable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 val;
+
+	val = pcs_id ? SER_IRQ_PCS1_DIS : SER_IRQ_PCS0_DIS;
+	serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, val);
+
+	serdes->i2c_write_reg(client, PCS_REG30(pcs_id), PCS_INT_STARTUP(0));
+	serdes->i2c_write_reg(client, PCS_REG34(pcs_id), PCS_INT_REMOTE_MODE(0));
+}
+
+static void rkx110_pcs_irq_handler(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 value;
+
+	serdes->i2c_read_reg(client, PCS_REG24(pcs_id), &value);
+	dev_info(serdes->dev, "ser pcs%d startup fatal status:0x%08x\n", pcs_id, value);
+
+	serdes->i2c_read_reg(client, PCS_REG28(pcs_id), &value);
+	dev_info(serdes->dev, "ser pcs%d remote mode fatal status:0x%08x\n", pcs_id, value);
+
+	/* clear startup fatal status */
+	serdes->i2c_write_reg(client, PCS_REG1C(pcs_id), 0xffffffff);
+	serdes->i2c_write_reg(client, PCS_REG1C(pcs_id), 0xffff0000);
+
+	/* clear remote fatal status */
+	serdes->i2c_write_reg(client, PCS_REG14(pcs_id), 0xffffffff);
+	serdes->i2c_write_reg(client, PCS_REG14(pcs_id), 0xffff0000);
+}
+
+static void rkx110_pma_irq_enable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 val;
+
+	val = pcs_id ? SER_IRQ_PMA_ADAPT1_EN : SER_IRQ_PMA_ADAPT0_EN;
+	serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, val);
+
+	serdes->i2c_write_reg(client, SER_PMA_IRQ_EN(pcs_id), FORCE_INITIAL_IRQ_EN |
+			      RTERM_ONCE_TIMEOUT_IRQ_EN | PLL_LOCK_TIMEOUT_IRQ_EN);
+}
+
+static void rkx110_pma_irq_disable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 val;
+
+	val = pcs_id ? SER_IRQ_PMA_ADAPT1_DIS : SER_IRQ_PMA_ADAPT0_DIS;
+	serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, val);
+
+	serdes->i2c_write_reg(client, SER_PMA_IRQ_EN(pcs_id), 0);
+}
+
+static void rkx110_pma_irq_handler(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 value;
+
+	serdes->i2c_read_reg(client, SER_PMA_IRQ_STATUS(pcs_id), &value);
+	dev_info(serdes->dev, "ser pma%d irq status:0x%08x\n", pcs_id, value);
+
+	if (value & FORCE_INITIAL_PULSE_STATUS)
+		dev_info(serdes->dev, "ser pma trig force initial pulse status\n");
+	else if (value & RTERM_ONCE_TIMEOUT_STATUS)
+		dev_info(serdes->dev, "ser pma trig rterm once timeout status\n");
+	else if (value & PLL_LOCK_TIMEOUT_STATUS)
+		dev_info(serdes->dev, "ser pma trig pll lock timeout status\n");
+
+	/* clear pma irq status */
+	serdes->i2c_write_reg(client, SER_PMA_IRQ_STATUS(pcs_id), value);
+}
+
+static void rkx110_remote_irq_enable(struct rk_serdes *serdes, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+
+	if (serdes->stream_type == STREAM_DISPLAY) {
+		serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, SER_IRQ_REMOTE_EN);
+		rkx120_irq_enable(serdes, DEVICE_REMOTE0);
+	}
+}
+
+
+static void rkx110_remote_irq_disable(struct rk_serdes *serdes, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+
+	if (serdes->stream_type == STREAM_DISPLAY) {
+		serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, SER_IRQ_REMOTE_DIS);
+		rkx120_irq_disable(serdes, DEVICE_REMOTE0);
+	}
+}
+
+static void rkx110_remote_irq_handler(struct rk_serdes *serdes, u8 dev_id)
+{
+	if (serdes->stream_type == STREAM_DISPLAY)
+		rkx120_irq_handler(serdes, DEVICE_REMOTE0);
+}
+
+void rkx110_irq_enable(struct rk_serdes *serdes, u8 dev_id)
+{
+	/* enable pcs irq */
+	rkx110_pcs_irq_enable(serdes, 0, dev_id);
+
+	/* enable dsirx irq */
+
+	/* enable gpio irq */
+
+	/* enable csihost irq */
+
+	/* enable pma_adapt irq */
+	rkx110_pma_irq_enable(serdes, 0, dev_id);
+
+	/* enable efuse irq */
+
+	/* enable vicap irq */
+
+	/* enable remote irq */
+	rkx110_remote_irq_enable(serdes, dev_id);
+
+	/* enable ext irq */
+
+	/* enable link irq */
+	rkx110_linktx_irq_enable(serdes, dev_id);
+}
+
+void rkx110_irq_disable(struct rk_serdes *serdes, u8 dev_id)
+{
+	/* disable pcs irq */
+	rkx110_pcs_irq_disable(serdes, 0, dev_id);
+
+	/* disable dsirx irq */
+
+	/* disable gpio irq */
+
+	/* disable csihost irq */
+
+	/* disable pma_adapt irq */
+	rkx110_pma_irq_disable(serdes, 0, dev_id);
+
+	/* disable efuse irq */
+
+	/* disable vicap irq */
+
+	/* disable remote irq and other lane irq*/
+	rkx110_remote_irq_disable(serdes, dev_id);
+
+	/* disable ext irq */
+
+	/* disable link irq */
+	rkx110_linktx_irq_disable(serdes, dev_id);
+}
+
+int rkx110_irq_handler(struct rk_serdes *serdes, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 status, mask;
+	u32 i = 0;
+
+	serdes->i2c_read_reg(client, SER_GRF_IRQ_EN, &mask);
+	serdes->i2c_read_reg(client, SER_GRF_IRQ_STATUS, &status);
+	dev_info(serdes->dev, "dev%d get the ser irq status:0x%08x\n", dev_id, status);
+
+	status &= mask;
+
+	while (status) {
+		switch (status & BIT(i)) {
+		case SER_IRQ_PCS0:
+			rkx110_pcs_irq_handler(serdes, 0, dev_id);
+			break;
+		case SER_IRQ_PCS1:
+			rkx110_pcs_irq_handler(serdes, 1, dev_id);
+			break;
+		case SER_IRQ_DSIRX0:
+			/* TBD */
+			break;
+		case SER_IRQ_DSIRX1:
+			/* TBD */
+			break;
+		case SER_IRQ_GPIO0:
+			/* TBD */
+			break;
+		case SER_IRQ_GPIO1:
+			/* TBD */
+			break;
+		case SER_IRQ_CSIHOST0:
+			/* TBD */
+			break;
+		case SER_IRQ_CSIHOST1:
+			/* TBD */
+			break;
+		case SER_IRQ_PMA_ADAPT0:
+			rkx110_pma_irq_handler(serdes, 0, dev_id);
+			break;
+		case SER_IRQ_PMA_ADAPT1:
+			rkx110_pma_irq_handler(serdes, 1, dev_id);
+			break;
+		case SER_IRQ_EFUSE:
+			/* TBD */
+			break;
+		case SER_IRQ_VICAP:
+			/* TBD */
+			break;
+		case SER_IRQ_REMOTE:
+			rkx110_remote_irq_handler(serdes, dev_id);
+			break;
+		case SER_IRQ_EXT:
+			/* TBD */
+			break;
+		case SER_IRQ_LINK:
+			rkx110_linktx_irq_handler(serdes, dev_id);
+			break;
+		case SER_IRQ_OTHER_LANE:
+			/* TBD */
+			break;
+		default:
+			break;
+		}
+		status &= ~BIT(i);
+		i++;
+	}
+
+	return 0;
+}
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx110_reg.h b/kernel/drivers/mfd/rkx110_x120/rkx110_reg.h
index 4d6db3d..d9e18ec 100644
--- a/kernel/drivers/mfd/rkx110_x120/rkx110_reg.h
+++ b/kernel/drivers/mfd/rkx110_x120/rkx110_reg.h
@@ -357,6 +357,8 @@
 #define SER_GRF_SOC_CON5		GRF_REG(0x114)
 #define SER_GRF_SOC_CON6		GRF_REG(0x118)
 #define SER_GRF_SOC_CON7		GRF_REG(0x11C)
+#define SER_GRF_IRQ_EN			GRF_REG(0x140)
+#define SER_GRF_IRQ_STATUS		GRF_REG(0x150)
 #define SER_GRF_SOC_STATUS0		GRF_REG(0x160)
 
 enum {
@@ -467,6 +469,71 @@
 	PMA0_DISABLE		= HIWORD_UPDATE(0, BIT(8), 8),
 
 	/* SER_GRF_IRQ_EN */
+	SER_IRQ_OTHER_LANE_EN	= HIWORD_UPDATE(1, BIT(15), 15),
+	SER_IRQ_OTHER_LANE_DIS	= HIWORD_UPDATE(0, BIT(15), 15),
+
+	SER_IRQ_LINK_EN		= HIWORD_UPDATE(1, BIT(14), 14),
+	SER_IRQ_LINK_DIS	= HIWORD_UPDATE(0, BIT(14), 14),
+
+	SER_IRQ_EXT_EN		= HIWORD_UPDATE(1, BIT(13), 13),
+	SER_IRQ_EXT_DIS		= HIWORD_UPDATE(0, BIT(13), 13),
+
+	SER_IRQ_REMOTE_EN	= HIWORD_UPDATE(1, BIT(12), 12),
+	SER_IRQ_REMOTE_DIS	= HIWORD_UPDATE(0, BIT(12), 12),
+
+	SER_IRQ_VICAP_EN	= HIWORD_UPDATE(1, BIT(11), 11),
+	SER_IRQ_VICAP_DIS	= HIWORD_UPDATE(0, BIT(11), 11),
+
+	SER_IRQ_EFUSE_EN	= HIWORD_UPDATE(1, BIT(10), 10),
+	SER_IRQ_EFUSE_DIS	= HIWORD_UPDATE(0, BIT(10), 10),
+
+	SER_IRQ_PMA_ADAPT1_EN	= HIWORD_UPDATE(1, BIT(9), 9),
+	SER_IRQ_PMA_ADAPT1_DIS	= HIWORD_UPDATE(0, BIT(9), 9),
+
+	SER_IRQ_PMA_ADAPT0_EN	= HIWORD_UPDATE(1, BIT(8), 8),
+	SER_IRQ_PMA_ADAPT0_DIS	= HIWORD_UPDATE(0, BIT(8), 8),
+
+	SER_IRQ_CSIHOST1_EN	= HIWORD_UPDATE(1, BIT(7), 7),
+	SER_IRQ_CSIHOST1_DIS	= HIWORD_UPDATE(0, BIT(7), 7),
+
+	SER_IRQ_CSIHOST0_EN	= HIWORD_UPDATE(1, BIT(6), 6),
+	SER_IRQ_CSIHOST0_DIS	= HIWORD_UPDATE(0, BIT(6), 6),
+
+	SER_IRQ_GPIO1_EN	= HIWORD_UPDATE(1, BIT(5), 5),
+	SER_IRQ_GPIO1_DIS	= HIWORD_UPDATE(0, BIT(5), 5),
+
+	SER_IRQ_GPIO0_EN	= HIWORD_UPDATE(1, BIT(4), 4),
+	SER_IRQ_GPIO0_DIS	= HIWORD_UPDATE(0, BIT(4), 4),
+
+	SER_IRQ_DSIRX1_EN	= HIWORD_UPDATE(1, BIT(3), 3),
+	SER_IRQ_DSIRX1_DIS	= HIWORD_UPDATE(0, BIT(3), 3),
+
+	SER_IRQ_DSIRX0_EN	= HIWORD_UPDATE(1, BIT(2), 2),
+	SER_IRQ_DSIRX0_DIS	= HIWORD_UPDATE(0, BIT(2), 2),
+
+	SER_IRQ_PCS1_EN		= HIWORD_UPDATE(1, BIT(1), 1),
+	SER_IRQ_PCS1_DIS	= HIWORD_UPDATE(0, BIT(1), 1),
+
+	SER_IRQ_PCS0_EN		= HIWORD_UPDATE(1, BIT(0), 0),
+	SER_IRQ_PCS0_DIS	= HIWORD_UPDATE(0, BIT(0), 0),
+
+	/* SER_GRF_IRQ_STATUS */
+	SER_IRQ_OTHER_LANE	= BIT(15),
+	SER_IRQ_LINK		= BIT(14),
+	SER_IRQ_EXT		= BIT(13),
+	SER_IRQ_REMOTE		= BIT(12),
+	SER_IRQ_VICAP		= BIT(11),
+	SER_IRQ_EFUSE		= BIT(10),
+	SER_IRQ_PMA_ADAPT1	= BIT(9),
+	SER_IRQ_PMA_ADAPT0	= BIT(8),
+	SER_IRQ_CSIHOST1	= BIT(7),
+	SER_IRQ_CSIHOST0	= BIT(6),
+	SER_IRQ_GPIO1		= BIT(5),
+	SER_IRQ_GPIO0		= BIT(4),
+	SER_IRQ_DSIRX1		= BIT(3),
+	SER_IRQ_DSIRX0		= BIT(2),
+	SER_IRQ_PCS1		= BIT(1),
+	SER_IRQ_PCS0		= BIT(0),
 
 	/* SER_GRF_SOC_STATUS0 */
 	SER_PCS1_READY		= BIT(21),
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx110_x120.h b/kernel/drivers/mfd/rkx110_x120/rkx110_x120.h
index 67c2d1f..319a328 100644
--- a/kernel/drivers/mfd/rkx110_x120/rkx110_x120.h
+++ b/kernel/drivers/mfd/rkx110_x120/rkx110_x120.h
@@ -9,11 +9,13 @@
 #define _RKX110_X120_H
 
 #include <drm/drm_panel.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_connector.h>
 #include <dt-bindings/mfd/rockchip-serdes.h>
 #include <linux/i2c.h>
 #include <video/videomode.h>
 
-#define MAX_PANEL 2
+#define RK_SERDES_MAX_ROUTE		2
 #define RK_SERDES_PASSTHROUGH_CNT	11
 
 #define SERDES_VERSION_V0(type)		0x2201
@@ -142,11 +144,14 @@
 
 struct rkx110_combrxphy {
 	enum combrx_phy_mode mode;
+	uint8_t lanes;
 	u64 rate;
 	struct configure_opts_combphy mipi_dphy_cfg;
 };
 
 struct rkx120_dsi_tx {
+	struct rkx120_combtxphy *combtxphy;
+
 	int bpp; /* 24/18/16*/
 	enum serdes_dsi_bus_format bus_format;
 	enum serdes_dsi_mode_flags mode_flags;
@@ -221,6 +226,7 @@
 	u32 remote0_port1;
 	u32 remote1_port0;
 	u32 remote1_port1;
+	u32 route_flag;
 };
 
 struct rk_serdes_chip {
@@ -233,9 +239,11 @@
 struct pattern_gen {
 	const char *name;
 	struct rk_serdes_chip *chip;
+	struct rk_serdes_route *route;
 	u32 base;
 	u32 link_src_reg;
 	u8 link_src_offset;
+	u8 type;
 };
 
 struct rk_serdes_pt_pin {
@@ -259,9 +267,12 @@
 struct rk_serdes {
 	struct device *dev;
 	struct rk_serdes_chip chip[DEVICE_MAX];
+	struct regulator *supply;
 	struct gpio_desc *reset;
 	struct gpio_desc *enable;
+	struct gpio_desc *irq_gpio;
 
+	int irq;
 	/*
 	 * Control by I2C-Debug
 	 */
@@ -276,15 +287,13 @@
 	struct dentry *debugfs_remote1;
 	struct dentry *debugfs_rate;
 
-	struct videomode *vm;
+	struct rk_serdes_route *route[RK_SERDES_MAX_ROUTE];
 	u32 stream_type;
 	u32 version;
-	u32 route_flag;
 	u8 remote_nr;
-	struct rkx110_combrxphy combrxphy;
-	struct rkx110_dsi_rx dsi_rx;
-	struct rkx120_combtxphy combtxphy;
-	struct rkx120_dsi_tx dsi_tx;
+	u8 lane_nr;
+	u8 channel_nr;
+	u8 route_nr;
 
 	int (*i2c_read_reg)(struct i2c_client *client, u32 addr, u32 *value);
 	int (*i2c_write_reg)(struct i2c_client *client, u32 addr, u32 value);
@@ -315,13 +324,14 @@
 	int cmd_cnt;
 };
 
+struct rk_serdes_panel;
 struct rk_serdes_panel {
 	struct drm_panel panel;
+	struct drm_bridge bridge;
+	struct drm_connector connector;
 	struct device *dev;
 	struct rk_serdes *parent;
-	struct rk_serdes_route route;
-	unsigned int bus_format;
-	int link_mode;
+	struct rk_serdes_panel *secondary;
 
 	struct panel_cmds *on_cmds;
 	struct panel_cmds *off_cmds;
@@ -329,14 +339,27 @@
 	struct regulator *supply;
 	struct gpio_desc *enable_gpio;
 	struct gpio_desc *reset_gpio;
+
+	struct rk_serdes_route route;
+	struct rkx110_combrxphy combrxphy;
+	struct rkx110_dsi_rx dsi_rx;
+	struct rkx120_combtxphy combtxphy;
+	struct rkx120_dsi_tx dsi_tx;
+
+	unsigned int bus_format;
+	unsigned int id;
+	u32 connector_type;
+
+	bool multi_panel;
 };
 
-int rkx110_linktx_enable(struct rk_serdes *serdes, struct rk_serdes_route *route);
+int rkx110_display_linktx_enable(struct rk_serdes *serdes, struct rk_serdes_route *route);
 void rkx110_linktx_video_enable(struct rk_serdes *serdes, u8 dev_id, bool enable);
 void rkx110_linktx_channel_enable(struct rk_serdes *serdes, u8 ch_id, u8 dev_id, bool enable);
 void rkx120_linkrx_engine_enable(struct rk_serdes *serdes, u8 en_id, u8 dev_id, bool enable);
 void rkx110_set_stream_source(struct rk_serdes *serdes, int local_port, u8 dev_id);
-int rkx120_linkrx_enable(struct rk_serdes *serdes, struct rk_serdes_route *route, u8 remote_id);
+int rkx120_display_linkrx_enable(struct rk_serdes *serdes,
+				 struct rk_serdes_route *route, u8 remote_id);
 int rkx120_rgb_tx_enable(struct rk_serdes *serdes, struct rk_serdes_route *route, u8 remote_id);
 int rkx120_lvds_tx_enable(struct rk_serdes *serdes, struct rk_serdes_route *route, u8 remote_id,
 			  u8 phy_id);
@@ -354,8 +377,8 @@
 void rkx120_pcs_enable(struct rk_serdes *serdes, bool enable, u8 pcs_id, u8 dev_id);
 void rkx110_ser_pma_enable(struct rk_serdes *serdes, bool enable, u8 pma_id, u8 remote_id);
 void rkx120_des_pma_enable(struct rk_serdes *serdes, bool enable, u8 pma_id, u8 remote_id);
-void rkx110_linktx_wait_link_ready(struct rk_serdes *serdes, u8 id);
-void rkx120_linkrx_wait_link_ready(struct rk_serdes *serdes, u8 id);
+int rkx110_linktx_wait_link_ready(struct rk_serdes *serdes, u8 id);
+int rkx120_linkrx_wait_link_ready(struct rk_serdes *serdes, u8 id);
 void rkx110_x120_pattern_gen_debugfs_create_file(struct pattern_gen *pattern_gen,
 						 struct rk_serdes_chip *chip,
 						 struct dentry *dentry);
@@ -363,4 +386,15 @@
 				   bool is_rx);
 void rkx120_linkrx_passthrough_cfg(struct rk_serdes *serdes, u32 client_id, u32 func_id,
 				   bool is_rx);
+void rkx110_irq_enable(struct rk_serdes *serdes, u8 dev_id);
+void rkx110_irq_disable(struct rk_serdes *serdes, u8 dev_id);
+int rkx110_irq_handler(struct rk_serdes *serdes, u8 dev_id);
+void rkx120_irq_enable(struct rk_serdes *serdes, u8 dev_id);
+void rkx120_irq_disable(struct rk_serdes *serdes, u8 dev_id);
+int rkx120_irq_handler(struct rk_serdes *serdes, u8 dev_id);
+
+int rkx110_linktx_dsi_rec_start(struct rk_serdes *serdes, u8 dev_id, u8 dsi_id, bool enable);
+int rkx110_linktx_dsi_type_select(struct rk_serdes *serdes, u8 dev_id, u8 dsi_id, bool is_cmd);
+int rkx110_linktx_dsi_deley_length_config(struct rk_serdes *serdes, u8 dev_id, u8 dsi_id,
+					  u32 length);
 #endif
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx110_x120_core.c b/kernel/drivers/mfd/rkx110_x120/rkx110_x120_core.c
index 95d875b..ee9e962 100644
--- a/kernel/drivers/mfd/rkx110_x120/rkx110_x120_core.c
+++ b/kernel/drivers/mfd/rkx110_x120/rkx110_x120_core.c
@@ -10,9 +10,12 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
+#include <linux/irq.h>
 #include <linux/gpio/consumer.h>
+#include <linux/regulator/consumer.h>
 #include <linux/mfd/core.h>
 #include "rkx110_x120.h"
+#include "rkx110_x120_display.h"
 #include "rkx110_reg.h"
 #include "rkx110_dsi_rx.h"
 #include "rkx120_dsi_tx.h"
@@ -22,8 +25,44 @@
 static const struct mfd_cell rkx110_x120_devs[] = {
 	/* 2 panel device for rkx110_x120 drm panel */
 	{
-		.name = "serdes-panel",
+		.name = "rockchip-serdes-panel",
 		.of_compatible = "rockchip,serdes-panel",
+	},
+	{
+		.name = "rockchip-serdes-panel1",
+		.of_compatible = "rockchip,serdes-panel",
+	},
+	{
+		.name = "rkx120-pwm0",
+		.of_compatible = "rockchip,rkx120-pwm",
+	},
+	{
+		.name = "rkx120-pwm1",
+		.of_compatible = "rockchip,rkx120-pwm",
+	},
+	{
+		.name = "rkx120-pwm2",
+		.of_compatible = "rockchip,rkx120-pwm",
+	},
+	{
+		.name = "rkx120-pwm3",
+		.of_compatible = "rockchip,rkx120-pwm",
+	},
+	{
+		.name = "rkx120-pwm4",
+		.of_compatible = "rockchip,rkx120-pwm",
+	},
+	{
+		.name = "rkx120-pwm5",
+		.of_compatible = "rockchip,rkx120-pwm",
+	},
+	{
+		.name = "rkx120-pwm6",
+		.of_compatible = "rockchip,rkx120-pwm",
+	},
+	{
+		.name = "rkx120-pwm7",
+		.of_compatible = "rockchip,rkx120-pwm",
 	},
 };
 
@@ -111,26 +150,40 @@
 	return serdes->rkx110_debug || serdes->rkx120_debug;
 }
 
-static void rk_serdes_wait_link_ready(struct rk_serdes *serdes)
+static int rk_serdes_wait_link_ready(struct rk_serdes *serdes)
 {
+	int ret;
+
 	if (serdes->stream_type == STREAM_DISPLAY) {
-		rkx110_linktx_wait_link_ready(serdes, 0);
-		if (serdes->route_flag & ROUTE_MULTI_LANE) {
+		ret = rkx110_linktx_wait_link_ready(serdes, 0);
+		if (ret)
+			return ret;
+
+		if (serdes->lane_nr == 2) {
 			rkx110_ser_pma_enable(serdes, true, 1, DEVICE_LOCAL);
-			if (!(serdes->route_flag & ROUTE_MULTI_REMOTE))
+			if (!(serdes->remote_nr == 2))
 				rkx120_des_pma_enable(serdes, true, 1, DEVICE_REMOTE0);
-			rkx110_linktx_wait_link_ready(serdes, 1);
+			ret = rkx110_linktx_wait_link_ready(serdes, 1);
+			if (ret)
+				return ret;
 		}
 
 	} else {
-		rkx120_linkrx_wait_link_ready(serdes, 0);
-		if (serdes->route_flag & ROUTE_MULTI_LANE) {
+		ret = rkx120_linkrx_wait_link_ready(serdes, 0);
+		if (ret)
+			return ret;
+
+		if (serdes->lane_nr == 2) {
 			rkx120_des_pma_enable(serdes, true, 1, DEVICE_LOCAL);
-			if (!(serdes->route_flag & ROUTE_MULTI_REMOTE))
+			if (!(serdes->remote_nr == 2))
 				rkx110_ser_pma_enable(serdes, true, 1, DEVICE_REMOTE0);
-			rkx120_linkrx_wait_link_ready(serdes, 1);
+			ret = rkx120_linkrx_wait_link_ready(serdes, 1);
+			if (ret)
+				return ret;
 		}
 	}
+
+	return 0;
 }
 
 static void rk_serdes_print_rate(struct rk_serdes *serdes, enum rk_serdes_rate rate)
@@ -302,9 +355,9 @@
 	if (serdes->stream_type == STREAM_DISPLAY) {
 		rkx110_pma_set_rate(serdes, &rkx110_pll, 0, DEVICE_LOCAL);
 		rkx120_pma_set_rate(serdes, &rkx120_pll, 0, DEVICE_REMOTE0);
-		if (serdes->route_flag & ROUTE_MULTI_LANE) {
+		if (serdes->lane_nr == 2) {
 			rkx110_pma_set_rate(serdes, &rkx110_pll, 1, DEVICE_LOCAL);
-			if (serdes->route_flag & ROUTE_MULTI_REMOTE)
+			if (serdes->remote_nr == 2)
 				rkx120_pma_set_rate(serdes, &rkx120_pll, 0, DEVICE_REMOTE1);
 			else
 				rkx120_pma_set_rate(serdes, &rkx120_pll, 1, DEVICE_REMOTE0);
@@ -315,9 +368,9 @@
 	} else {
 		rkx120_pma_set_rate(serdes, &rkx120_pll, 0, DEVICE_LOCAL);
 		rkx110_pma_set_rate(serdes, &rkx110_pll, 0, DEVICE_REMOTE0);
-		if (serdes->route_flag & ROUTE_MULTI_LANE) {
+		if (serdes->lane_nr == 2) {
 			rkx120_pma_set_rate(serdes, &rkx120_pll, 1, DEVICE_LOCAL);
-			if (serdes->route_flag & ROUTE_MULTI_REMOTE)
+			if (serdes->remote_nr == 2)
 				rkx110_pma_set_rate(serdes, &rkx110_pll, 0, DEVICE_REMOTE1);
 			else
 				rkx110_pma_set_rate(serdes, &rkx110_pll, 1, DEVICE_REMOTE0);
@@ -330,225 +383,6 @@
 	rk_serdes_wait_link_ready(serdes);
 
 	serdes->rate = rate;
-}
-
-static int rk_serdes_route_prepare(struct rk_serdes *serdes, struct rk_serdes_route *route)
-{
-	if (rk_serdes_debug_mode(serdes))
-		return 0;
-
-	if (route->stream_type == STREAM_DISPLAY) {
-		switch (route->local_port0) {
-		case RK_SERDES_RGB_RX:
-			rkx110_rgb_rx_enable(serdes, route);
-			break;
-		case RK_SERDES_LVDS_RX0:
-			rkx110_lvds_rx_enable(serdes, route, 0);
-			if (serdes->route_flag & ROUTE_MULTI_LVDS_INPUT)
-				rkx110_lvds_rx_enable(serdes, route, 1);
-			break;
-		case RK_SERDES_LVDS_RX1:
-			rkx110_lvds_rx_enable(serdes, route, 1);
-			if (serdes->route_flag & ROUTE_MULTI_LVDS_INPUT)
-				rkx110_lvds_rx_enable(serdes, route, 0);
-			break;
-		case RK_SERDES_DUAL_LVDS_RX:
-			rkx110_lvds_rx_enable(serdes, route, 0);
-			rkx110_lvds_rx_enable(serdes, route, 1);
-			break;
-		case RK_SERDES_DSI_RX0:
-			rkx110_dsi_rx_enable(serdes, route, 0);
-			if (serdes->route_flag & ROUTE_MULTI_DSI_INPUT)
-				rkx110_dsi_rx_enable(serdes, route, 1);
-			break;
-		case RK_SERDES_DSI_RX1:
-			rkx110_dsi_rx_enable(serdes, route, 1);
-			if (serdes->route_flag & ROUTE_MULTI_DSI_INPUT)
-				rkx110_dsi_rx_enable(serdes, route, 0);
-			break;
-		default:
-			dev_info(serdes->dev, "undefined local port0");
-			return -EINVAL;
-		}
-
-		rkx110_linktx_enable(serdes, route);
-
-		rkx120_linkrx_enable(serdes, route, DEVICE_REMOTE0);
-		if (serdes->route_flag & ROUTE_MULTI_REMOTE)
-			rkx120_linkrx_enable(serdes, route, DEVICE_REMOTE1);
-
-		if (route->remote0_port0 & RK_SERDES_DSI_TX0)
-			rkx120_dsi_tx_pre_enable(serdes, route, DEVICE_REMOTE0);
-		if (route->remote1_port0 & RK_SERDES_DSI_TX0)
-			rkx120_dsi_tx_pre_enable(serdes, route, DEVICE_REMOTE1);
-	} else {
-		/* for camera stream */
-	}
-
-	return 0;
-}
-
-static int rk_serdes_route_enable(struct rk_serdes *serdes, struct rk_serdes_route *route)
-{
-	if (rk_serdes_debug_mode(serdes))
-		return 0;
-
-	if (route->stream_type == STREAM_DISPLAY) {
-		switch (route->remote0_port0) {
-		case RK_SERDES_RGB_TX:
-			rkx120_rgb_tx_enable(serdes, route, DEVICE_REMOTE0);
-			break;
-		case RK_SERDES_LVDS_TX0:
-			rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 0);
-			break;
-		case RK_SERDES_LVDS_TX1:
-			rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 1);
-			break;
-		case RK_SERDES_DUAL_LVDS_TX:
-			rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 0);
-			rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 1);
-			break;
-		case RK_SERDES_DSI_TX0:
-			rkx120_dsi_tx_enable(serdes, route, DEVICE_REMOTE0);
-			break;
-		default:
-			dev_err(serdes->dev, "undefined remote0_port0\n");
-			return -EINVAL;
-		}
-
-		if (serdes->route_flag & ROUTE_MULTI_REMOTE) {
-			switch (route->remote1_port0) {
-			case RK_SERDES_RGB_TX:
-				rkx120_rgb_tx_enable(serdes, route, DEVICE_REMOTE1);
-				break;
-			case RK_SERDES_LVDS_TX0:
-				rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 0);
-				break;
-			case RK_SERDES_LVDS_TX1:
-				rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 1);
-				break;
-			case RK_SERDES_DUAL_LVDS_TX:
-				rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 0);
-				rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 1);
-				break;
-			case RK_SERDES_DSI_TX0:
-				rkx120_dsi_tx_enable(serdes, route, DEVICE_REMOTE1);
-				break;
-			default:
-				dev_err(serdes->dev, "undefined remote1_port0\n");
-				return -EINVAL;
-			}
-		} else if (serdes->route_flag & ROUTE_MULTI_CHANNEL) {
-			if (route->remote0_port1 & RK_SERDES_LVDS_TX0) {
-				rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 0);
-			} else if (route->remote0_port1 & RK_SERDES_LVDS_TX1) {
-				rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 1);
-			} else {
-				dev_err(serdes->dev, "undefined remote0_port1\n");
-				return -EINVAL;
-			}
-		}
-
-		if (serdes->version == SERDES_V1) {
-			rkx120_linkrx_engine_enable(serdes, 0, DEVICE_REMOTE0, true);
-			rkx110_linktx_channel_enable(serdes, 0, DEVICE_LOCAL, true);
-		}
-
-		rkx110_linktx_video_enable(serdes, DEVICE_LOCAL, true);
-	} else {
-		/* for camera stream */
-	}
-
-	return 0;
-}
-
-static int rk_serdes_route_disable(struct rk_serdes *serdes, struct rk_serdes_route *route)
-{
-	if (route->stream_type == STREAM_DISPLAY) {
-		if (route->remote0_port0 & RK_SERDES_DSI_TX0)
-			rkx120_dsi_tx_disable(serdes, route, DEVICE_REMOTE0);
-
-		if (serdes->version == SERDES_V1) {
-			rkx120_linkrx_engine_enable(serdes, 0, DEVICE_REMOTE0, false);
-			rkx110_linktx_channel_enable(serdes, 0, DEVICE_LOCAL, false);
-
-			if (route->local_port0 == RK_SERDES_DUAL_LVDS_RX) {
-				rkx110_set_stream_source(serdes, RK_SERDES_RGB_RX,
-							 DEVICE_LOCAL);
-				hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
-					    RKX110_SRST_RESETN_2X_LVDS_RKLINK_TX);
-				hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
-					    RKX110_SRST_RESETN_D_LVDS0_RKLINK_TX);
-				hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
-					    RKX110_SRST_RESETN_D_LVDS1_RKLINK_TX);
-			}
-
-			if ((route->local_port0 == RK_SERDES_DSI_RX0) ||
-			    (route->local_port1 == RK_SERDES_DSI_RX0)) {
-				serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
-						      0x1400140);
-				hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
-					    RKX111_SRST_RESETN_D_DSI_0_REC_RKLINK_TX);
-				hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
-					    RKX110_SRST_RESETN_D_DSI_0_RKLINK_TX);
-			}
-
-			if ((route->local_port0 == RK_SERDES_DSI_RX1) ||
-			    (route->local_port1 == RK_SERDES_DSI_RX1)) {
-				serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
-						      0x2800280);
-				hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
-					    RKX111_SRST_RESETN_D_DSI_1_REC_RKLINK_TX);
-				hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
-					    RKX110_SRST_RESETN_D_DSI_1_RKLINK_TX);
-			}
-		}
-	}
-
-	return 0;
-}
-
-static int rk_serdes_route_unprepare(struct rk_serdes *serdes, struct rk_serdes_route *route)
-{
-	if (route->stream_type == STREAM_DISPLAY) {
-		if (route->remote0_port0 & RK_SERDES_DSI_TX0)
-			rkx120_dsi_tx_post_disable(serdes, route, DEVICE_REMOTE0);
-
-		if (serdes->version == SERDES_V1) {
-			if (route->local_port0 == RK_SERDES_DUAL_LVDS_RX) {
-				hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
-						     RKX110_SRST_RESETN_2X_LVDS_RKLINK_TX);
-				hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
-						     RKX110_SRST_RESETN_D_LVDS0_RKLINK_TX);
-				hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
-						     RKX110_SRST_RESETN_D_LVDS1_RKLINK_TX);
-				rkx110_set_stream_source(serdes, RK_SERDES_DUAL_LVDS_RX,
-							    DEVICE_LOCAL);
-			}
-
-			if ((route->local_port0 == RK_SERDES_DSI_RX0) ||
-			    (route->local_port1 == RK_SERDES_DSI_RX0)) {
-				hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
-						     RKX110_SRST_RESETN_D_DSI_0_RKLINK_TX);
-				hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
-						     RKX111_SRST_RESETN_D_DSI_0_REC_RKLINK_TX);
-				serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
-						      0x1400000);
-			}
-
-			if ((route->local_port0 == RK_SERDES_DSI_RX1) ||
-			    (route->local_port1 == RK_SERDES_DSI_RX1)) {
-				hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
-						     RKX110_SRST_RESETN_D_DSI_1_RKLINK_TX);
-				hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
-						     RKX111_SRST_RESETN_D_DSI_1_REC_RKLINK_TX);
-				serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
-						      0x2800000);
-			}
-		}
-	}
-
-	return 0;
 }
 
 static int rk_serdes_set_hwpin(struct rk_serdes *serdes, struct i2c_client *client,
@@ -576,11 +410,17 @@
 	serdes->i2c_read_reg = rk_serdes_i2c_read;
 	serdes->i2c_write_reg = rk_serdes_i2c_write;
 	serdes->i2c_update_bits = rk_serdes_i2c_update_bits;
-	serdes->route_prepare = rk_serdes_route_prepare;
-	serdes->route_enable = rk_serdes_route_enable;
-	serdes->route_disable = rk_serdes_route_disable;
-	serdes->route_unprepare = rk_serdes_route_unprepare;
 	serdes->set_hwpin = rk_serdes_set_hwpin;
+
+	if (rk_serdes_debug_mode(serdes))
+		return;
+
+	if (serdes->stream_type == STREAM_DISPLAY) {
+		serdes->route_prepare = rk_serdes_display_route_prepare;
+		serdes->route_enable = rk_serdes_display_route_enable;
+		serdes->route_disable = rk_serdes_display_route_disable;
+		serdes->route_unprepare = rk_serdes_display_route_unprepare;
+	}
 }
 
 static int rk_serdes_passthrough_init(struct rk_serdes *serdes)
@@ -649,6 +489,25 @@
 		}
 
 		kfree(configs);
+	}
+
+	/* config irq passthrough */
+	if (serdes->stream_type == STREAM_DISPLAY) {
+		rkx110_linktx_passthrough_cfg(serdes, DEVICE_LOCAL, RK_SERDES_PASSTHROUGH_IRQ,
+					      false);
+		rkx120_linkrx_passthrough_cfg(serdes, DEVICE_REMOTE0, RK_SERDES_PASSTHROUGH_IRQ,
+					      true);
+		if (serdes->remote_nr == 2)
+			rkx120_linkrx_passthrough_cfg(serdes, DEVICE_REMOTE1,
+						      RK_SERDES_PASSTHROUGH_IRQ, true);
+	} else {
+		rkx120_linkrx_passthrough_cfg(serdes, DEVICE_LOCAL, RK_SERDES_PASSTHROUGH_IRQ,
+					      false);
+		rkx110_linktx_passthrough_cfg(serdes, DEVICE_REMOTE0, RK_SERDES_PASSTHROUGH_IRQ,
+					      true);
+		if (serdes->remote_nr == 2)
+			rkx110_linktx_passthrough_cfg(serdes, DEVICE_REMOTE1,
+						      RK_SERDES_PASSTHROUGH_IRQ, true);
 	}
 
 	return 0;
@@ -903,6 +762,9 @@
 		i2c_set_clientdata(client, serdes);
 	}
 
+	if (serdes->remote_nr == 2)
+		serdes->lane_nr = 2;
+
 	if (serdes->remote_nr == 0)
 		return -ENODEV;
 
@@ -952,14 +814,73 @@
 		kfree(configs);
 	}
 
+	/* config irq pinctrl */
+	if (serdes->stream_type == STREAM_DISPLAY) {
+		serdes->set_hwpin(serdes, serdes->chip[DEVICE_LOCAL].client, PIN_RKX110,
+				  RK_SERDES_SER_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
+				  RK_SERDES_PIN_CONFIG_MUX_FUNC2);
+		serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE0].client, PIN_RKX120,
+				  RK_SERDES_DES_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
+				  RK_SERDES_PIN_CONFIG_MUX_FUNC0);
+		if (serdes->remote_nr == 2)
+			serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE1].client, PIN_RKX120,
+					  RK_SERDES_DES_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
+					  RK_SERDES_PIN_CONFIG_MUX_FUNC0);
+	} else {
+		serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE0].client, PIN_RKX110,
+				  RK_SERDES_SER_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
+				  RK_SERDES_PIN_CONFIG_MUX_FUNC0);
+		serdes->set_hwpin(serdes, serdes->chip[DEVICE_LOCAL].client, PIN_RKX120,
+				  RK_SERDES_DES_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
+				  RK_SERDES_PIN_CONFIG_MUX_FUNC2);
+		if (serdes->remote_nr == 2)
+			serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE1].client, PIN_RKX110,
+					  RK_SERDES_SER_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
+					  RK_SERDES_PIN_CONFIG_MUX_FUNC2);
+	}
+
 	return 0;
+}
+
+static int rk_serdes_irq_enable(struct rk_serdes *serdes)
+{
+	if (serdes->stream_type == STREAM_DISPLAY)
+		rkx110_irq_enable(serdes, DEVICE_LOCAL);
+	else
+		rkx120_irq_enable(serdes, DEVICE_LOCAL);
+
+	return 0;
+}
+
+__maybe_unused static int rk_serdes_irq_disable(struct rk_serdes *serdes)
+{
+	if (serdes->stream_type == STREAM_DISPLAY)
+		rkx110_irq_disable(serdes, DEVICE_LOCAL);
+	else
+		rkx120_irq_disable(serdes, DEVICE_LOCAL);
+
+	return 0;
+}
+
+static irqreturn_t rk_serdes_irq_handler(int irq, void *arg)
+{
+	struct rk_serdes *serdes = arg;
+
+	if (serdes->stream_type == STREAM_DISPLAY)
+		rkx110_irq_handler(serdes, DEVICE_LOCAL);
+	else
+		rkx120_irq_handler(serdes, DEVICE_LOCAL);
+
+	return IRQ_HANDLED;
 }
 
 static int rk_serdes_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	struct device *dev = &client->dev;
+	struct device_node *disp_np;
 	struct rk_serdes *serdes;
 	int ret;
+	bool dual_lane;
 
 	serdes = devm_kzalloc(dev, sizeof(*serdes), GFP_KERNEL);
 	if (!serdes)
@@ -988,6 +909,16 @@
 
 	serdes->rate = RATE_2GBPS_83M;
 
+	serdes->supply = devm_regulator_get_optional(dev, "power");
+	if (IS_ERR(serdes->supply)) {
+		ret = PTR_ERR(serdes->supply);
+
+		if (ret != -ENODEV)
+			return dev_err_probe(dev, ret, "failed to request regulator\n");
+
+		serdes->supply = NULL;
+	}
+
 	serdes->enable = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
 	if (IS_ERR(serdes->enable)) {
 		ret = PTR_ERR(serdes->enable);
@@ -1002,15 +933,34 @@
 		return ret;
 	}
 
-	gpiod_set_value(serdes->enable, 1);
+	serdes->irq_gpio = devm_gpiod_get_optional(dev, "irq", GPIOD_IN);
+	if (IS_ERR(serdes->irq_gpio)) {
+		ret = PTR_ERR(serdes->irq_gpio);
+		dev_err(dev, "failed to request irq GPIO: %d\n", ret);
+		return ret;
+	}
+	if (serdes->irq_gpio) {
+		serdes->irq = gpiod_to_irq(serdes->irq_gpio);
+		if (serdes->irq < 0)
+			return dev_err_probe(dev, serdes->irq, "failed to get irq\n");
 
-	gpiod_set_value(serdes->reset, 1);
-	usleep_range(10000, 11000);
-	gpiod_set_value(serdes->reset, 0);
+		irq_set_status_flags(serdes->irq, IRQ_NOAUTOEN);
+		ret = devm_request_threaded_irq(dev, serdes->irq, NULL,
+						rk_serdes_irq_handler,
+						IRQF_TRIGGER_LOW |
+						IRQF_ONESHOT, "serdes-irq", serdes);
+		if (ret) {
+			dev_err(dev, "failed to request serdes interrupt\n");
+			return ret;
+		}
+	} else {
+		dev_warn(dev, "no support serdes irq function\n");
+	}
 
-	if (of_get_child_by_name(dev->of_node, "serdes-panel")) {
+	disp_np = of_get_child_by_name(dev->of_node, "serdes-panel");
+	if (disp_np) {
 		serdes->stream_type = STREAM_DISPLAY;
-		of_node_put(dev->of_node);
+		of_node_put(disp_np);
 		dev_info(dev, "serdes display stream");
 	} else {
 		serdes->stream_type = STREAM_CAMERA;
@@ -1021,7 +971,10 @@
 	if (ret)
 		return ret;
 
-	msleep(20);
+	if (serdes->remote_nr != 2) {
+		dual_lane = device_property_read_bool(dev, "dual-lane");
+		serdes->lane_nr = dual_lane ? 2 : 1;
+	}
 
 	ret = mfd_add_devices(dev, -1, rkx110_x120_devs, ARRAY_SIZE(rkx110_x120_devs),
 			      NULL, 0, NULL);
@@ -1030,27 +983,58 @@
 		return ret;
 	}
 
+	if (serdes->supply) {
+		ret = regulator_enable(serdes->supply);
+		if (ret < 0) {
+			dev_err(serdes->dev, "failed to enable supply: %d\n", ret);
+			return ret;
+		}
+	}
+
+	gpiod_set_value(serdes->enable, 1);
+
+	gpiod_set_value(serdes->reset, 1);
+	usleep_range(10000, 11000);
+	gpiod_set_value(serdes->reset, 0);
+
+	msleep(20);
+
 	rk_serdes_wait_link_ready(serdes);
 
 	rk_serdes_read_chip_id(serdes);
 
 	ret = rk_serdes_add_hwclk(serdes);
 	if (ret < 0)
-		return ret;
+		goto err;
 
 	rk_serdes_set_rate(serdes, RATE_4GBPS_83M);
 	rk_serdes_pinctrl_init(serdes);
 	rk_serdes_passthrough_init(serdes);
+	rk_serdes_irq_enable(serdes);
+	enable_irq(serdes->irq);
+
+	if (serdes->stream_type == STREAM_DISPLAY)
+		rk_serdes_display_route_init(serdes);
+
 out:
 	rk_serdes_debugfs_init(serdes);
 
 	return 0;
+
+err:
+	if (serdes->supply)
+		ret = regulator_disable(serdes->supply);
+
+	return ret;
 }
 
 static int rk_serdes_i2c_remove(struct i2c_client *client)
 {
 	struct rk_serdes *rk_serdes = i2c_get_clientdata(client);
 
+	if (rk_serdes->supply)
+		regulator_disable(rk_serdes->supply);
+
 	mfd_remove_devices(rk_serdes->dev);
 
 	return 0;
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx110_x120_display.c b/kernel/drivers/mfd/rkx110_x120/rkx110_x120_display.c
new file mode 100644
index 0000000..319edd1
--- /dev/null
+++ b/kernel/drivers/mfd/rkx110_x120/rkx110_x120_display.c
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Rockchip Electronics Co. Ltd.
+ *
+ * Author: Zhang Yubing <yubing.zhang@rock-chips.com>
+ */
+
+#include "hal/cru_api.h"
+#include "rkx110_x120.h"
+#include "rkx110_x120_display.h"
+#include "rkx110_dsi_rx.h"
+#include "rkx120_dsi_tx.h"
+
+int rk_serdes_display_route_prepare(struct rk_serdes *serdes, struct rk_serdes_route *route)
+{
+	u32 local_port;
+
+	local_port = route->local_port0 ? route->local_port0 : route->local_port1;
+
+	switch (local_port) {
+	case RK_SERDES_RGB_RX:
+		rkx110_rgb_rx_enable(serdes, route);
+		break;
+	case RK_SERDES_LVDS_RX0:
+		rkx110_lvds_rx_enable(serdes, route, 0);
+		break;
+	case RK_SERDES_LVDS_RX1:
+		rkx110_lvds_rx_enable(serdes, route, 1);
+		break;
+	case RK_SERDES_DUAL_LVDS_RX:
+		rkx110_lvds_rx_enable(serdes, route, 0);
+		rkx110_lvds_rx_enable(serdes, route, 1);
+		break;
+	case RK_SERDES_DSI_RX0:
+		rkx110_dsi_rx_enable(serdes, route, 0);
+		break;
+	case RK_SERDES_DSI_RX1:
+		rkx110_dsi_rx_enable(serdes, route, 1);
+		break;
+	default:
+		dev_info(serdes->dev, "undefined local port\n");
+	}
+
+	rkx110_display_linktx_enable(serdes, route);
+
+	if (route->local_port0) {
+		rkx120_display_linkrx_enable(serdes, route, DEVICE_REMOTE0);
+		if (serdes->remote_nr == 2 && serdes->route_nr != 2)
+			rkx120_display_linkrx_enable(serdes, route, DEVICE_REMOTE1);
+
+		if (route->remote0_port0 & RK_SERDES_DSI_TX0)
+			rkx120_dsi_tx_pre_enable(serdes, route, DEVICE_REMOTE0);
+		if (route->remote1_port0 & RK_SERDES_DSI_TX0)
+			rkx120_dsi_tx_pre_enable(serdes, route, DEVICE_REMOTE1);
+	}
+
+	if (route->local_port1) {
+		if (serdes->remote_nr == 2)
+			rkx120_display_linkrx_enable(serdes, route, DEVICE_REMOTE1);
+		else
+			rkx120_display_linkrx_enable(serdes, route, DEVICE_REMOTE0);
+
+		if (route->remote1_port0 & RK_SERDES_DSI_TX0)
+			rkx120_dsi_tx_pre_enable(serdes, route, DEVICE_REMOTE1);
+	}
+
+	return 0;
+}
+
+int rk_serdes_display_video_start(struct rk_serdes *serdes,
+					 struct rk_serdes_route *route, bool enable)
+{
+	if (route->local_port0) {
+		if (route->route_flag & ROUTE_MULTI_CHANNEL) {
+			if (route->route_flag & ROUTE_MULTI_REMOTE) {
+				rkx120_linkrx_engine_enable(serdes, 0, DEVICE_REMOTE0, enable);
+				rkx120_linkrx_engine_enable(serdes, 0, DEVICE_REMOTE1, enable);
+			} else {
+				rkx120_linkrx_engine_enable(serdes, 0, DEVICE_REMOTE0, enable);
+				rkx120_linkrx_engine_enable(serdes, 1, DEVICE_REMOTE0, enable);
+			}
+			rkx110_linktx_channel_enable(serdes, 0, DEVICE_LOCAL, enable);
+			rkx110_linktx_channel_enable(serdes, 1, DEVICE_LOCAL, enable);
+		} else {
+			rkx120_linkrx_engine_enable(serdes, 0, DEVICE_REMOTE0, enable);
+			rkx110_linktx_channel_enable(serdes, 0, DEVICE_LOCAL, enable);
+		}
+	} else {
+		if (serdes->remote_nr == 2)
+			rkx120_linkrx_engine_enable(serdes, 0, DEVICE_REMOTE1, enable);
+		else
+			rkx120_linkrx_engine_enable(serdes, 1, DEVICE_REMOTE0, enable);
+
+		rkx110_linktx_channel_enable(serdes, 1, DEVICE_LOCAL, enable);
+	}
+
+	return 0;
+}
+
+int rk_serdes_display_route_init(struct  rk_serdes *serdes)
+{
+	rkx120_linkrx_engine_enable(serdes, 0, DEVICE_REMOTE0, false);
+	if (serdes->remote_nr == 2)
+		rkx120_linkrx_engine_enable(serdes, 0, DEVICE_REMOTE1, false);
+	else
+		rkx120_linkrx_engine_enable(serdes, 1, DEVICE_REMOTE0, false);
+
+	rkx110_linktx_channel_enable(serdes, 0, DEVICE_LOCAL, false);
+	rkx110_linktx_channel_enable(serdes, 1, DEVICE_LOCAL, false);
+
+	return 0;
+}
+
+int rk_serdes_display_route_enable(struct rk_serdes *serdes, struct rk_serdes_route *route)
+{
+	if (route->remote0_port0) {
+		switch (route->remote0_port0) {
+		case RK_SERDES_RGB_TX:
+			rkx120_rgb_tx_enable(serdes, route, DEVICE_REMOTE0);
+			break;
+		case RK_SERDES_LVDS_TX0:
+			rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 0);
+			break;
+		case RK_SERDES_LVDS_TX1:
+			rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 1);
+			break;
+		case RK_SERDES_DUAL_LVDS_TX:
+			rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 0);
+			rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 1);
+			break;
+		case RK_SERDES_DSI_TX0:
+			rkx120_dsi_tx_enable(serdes, route, DEVICE_REMOTE0);
+			break;
+		default:
+			dev_err(serdes->dev, "undefined remote0_port0\n");
+			break;
+		}
+	}
+
+	if (route->remote1_port0) {
+		switch (route->remote1_port0) {
+		case RK_SERDES_RGB_TX:
+			rkx120_rgb_tx_enable(serdes, route, DEVICE_REMOTE1);
+			break;
+		case RK_SERDES_LVDS_TX0:
+			rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 0);
+			break;
+		case RK_SERDES_LVDS_TX1:
+			rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 1);
+			break;
+		case RK_SERDES_DUAL_LVDS_TX:
+			rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 0);
+			rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 1);
+			break;
+		case RK_SERDES_DSI_TX0:
+			rkx120_dsi_tx_enable(serdes, route, DEVICE_REMOTE1);
+			break;
+		default:
+			dev_err(serdes->dev, "undefined remote1_port0\n");
+			break;
+		}
+	}
+
+	if (route->remote0_port1) {
+		switch (route->remote0_port1) {
+		case RK_SERDES_LVDS_TX0:
+			rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 0);
+			break;
+		case RK_SERDES_LVDS_TX1:
+			rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 1);
+			break;
+		default:
+			dev_err(serdes->dev, "undefined remote0_port1\n");
+			break;
+		}
+	}
+
+	if (serdes->version == SERDES_V1)
+		rk_serdes_display_video_start(serdes, route, true);
+
+	rkx110_linktx_video_enable(serdes, DEVICE_LOCAL, true);
+
+	return 0;
+}
+
+int rk_serdes_display_route_disable(struct rk_serdes *serdes, struct rk_serdes_route *route)
+{
+	if (route->remote0_port0 & RK_SERDES_DSI_TX0)
+		rkx120_dsi_tx_disable(serdes, route, DEVICE_REMOTE0);
+
+	if (route->remote1_port0 & RK_SERDES_DSI_TX0)
+		rkx120_dsi_tx_disable(serdes, route, DEVICE_REMOTE1);
+
+	if (serdes->version == SERDES_V1) {
+		rk_serdes_display_video_start(serdes, route, false);
+
+		if (route->local_port0 == RK_SERDES_DUAL_LVDS_RX) {
+			rkx110_set_stream_source(serdes, RK_SERDES_RGB_RX,
+						 DEVICE_LOCAL);
+			hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+				    RKX110_SRST_RESETN_2X_LVDS_RKLINK_TX);
+			hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+				    RKX110_SRST_RESETN_D_LVDS0_RKLINK_TX);
+			hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+				    RKX110_SRST_RESETN_D_LVDS1_RKLINK_TX);
+		}
+
+		if ((route->local_port0 == RK_SERDES_DSI_RX0) ||
+		    (route->local_port1 == RK_SERDES_DSI_RX0)) {
+			serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
+					      0x1400140);
+			hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+				    RKX111_SRST_RESETN_D_DSI_0_REC_RKLINK_TX);
+			hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+				    RKX110_SRST_RESETN_D_DSI_0_RKLINK_TX);
+		}
+
+		if ((route->local_port0 == RK_SERDES_DSI_RX1) ||
+		    (route->local_port1 == RK_SERDES_DSI_RX1)) {
+			serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
+					      0x2800280);
+			hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+				    RKX111_SRST_RESETN_D_DSI_1_REC_RKLINK_TX);
+			hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
+				    RKX110_SRST_RESETN_D_DSI_1_RKLINK_TX);
+		}
+	}
+
+	return 0;
+}
+
+int rk_serdes_display_route_unprepare(struct rk_serdes *serdes, struct rk_serdes_route *route)
+{
+	if (route->remote0_port0 & RK_SERDES_DSI_TX0)
+		rkx120_dsi_tx_post_disable(serdes, route, DEVICE_REMOTE0);
+
+	if (route->remote1_port0 & RK_SERDES_DSI_TX0)
+		rkx120_dsi_tx_post_disable(serdes, route, DEVICE_REMOTE1);
+
+	if (serdes->version == SERDES_V1) {
+		if (route->local_port0 == RK_SERDES_DUAL_LVDS_RX) {
+			hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+					     RKX110_SRST_RESETN_2X_LVDS_RKLINK_TX);
+			hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+					     RKX110_SRST_RESETN_D_LVDS0_RKLINK_TX);
+			hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+					     RKX110_SRST_RESETN_D_LVDS1_RKLINK_TX);
+			rkx110_set_stream_source(serdes, RK_SERDES_DUAL_LVDS_RX,
+						    DEVICE_LOCAL);
+		}
+
+		if ((route->local_port0 == RK_SERDES_DSI_RX0) ||
+		    (route->local_port1 == RK_SERDES_DSI_RX0)) {
+			hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+					     RKX110_SRST_RESETN_D_DSI_0_RKLINK_TX);
+			hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+					     RKX111_SRST_RESETN_D_DSI_0_REC_RKLINK_TX);
+			serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
+					      0x1400000);
+		}
+
+		if ((route->local_port0 == RK_SERDES_DSI_RX1) ||
+		    (route->local_port1 == RK_SERDES_DSI_RX1)) {
+			hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+					     RKX110_SRST_RESETN_D_DSI_1_RKLINK_TX);
+			hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
+					     RKX111_SRST_RESETN_D_DSI_1_REC_RKLINK_TX);
+			serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
+					      0x2800000);
+		}
+	}
+
+	return 0;
+}
+
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx110_x120_display.h b/kernel/drivers/mfd/rkx110_x120/rkx110_x120_display.h
new file mode 100644
index 0000000..6b6c0dc
--- /dev/null
+++ b/kernel/drivers/mfd/rkx110_x120/rkx110_x120_display.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co. Ltd.
+ *
+ * Author: Zhang Yubing <yubing.zhang@rock-chips.com>
+ */
+
+#ifndef _RKX110_RKX120_DISPLAY_H
+#define _RKX110_RKX120_DISPLAY_H
+
+int rk_serdes_display_route_prepare(struct rk_serdes *serdes, struct rk_serdes_route *route);
+int rk_serdes_display_route_enable(struct rk_serdes *serdes, struct rk_serdes_route *route);
+int rk_serdes_display_route_disable(struct rk_serdes *serdes, struct rk_serdes_route *route);
+int rk_serdes_display_route_unprepare(struct rk_serdes *serdes, struct rk_serdes_route *route);
+int rk_serdes_display_route_init(struct  rk_serdes *serdes);
+int rk_serdes_display_video_start(struct rk_serdes *serdes,
+					 struct rk_serdes_route *route, bool enable);
+
+#endif
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx110_x120_panel.c b/kernel/drivers/mfd/rkx110_x120/rkx110_x120_panel.c
index 38b76f0..b8c9f7b 100644
--- a/kernel/drivers/mfd/rkx110_x120/rkx110_x120_panel.c
+++ b/kernel/drivers/mfd/rkx110_x120/rkx110_x120_panel.c
@@ -21,21 +21,159 @@
 #include <drm/drm_crtc.h>
 #include <drm/drm_mipi_dsi.h>
 #include <drm/drm_panel.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_probe_helper.h>
 
 #include "rkx110_x120.h"
 #include "rkx120_dsi_tx.h"
 
-static inline struct rk_serdes_panel *to_serdes_panel(struct drm_panel *panel)
+static inline struct rk_serdes_panel *drm_panel_to_serdes_panel(struct drm_panel *panel)
 {
 	return container_of(panel, struct rk_serdes_panel, panel);
 }
 
-static int serdes_panel_prepare(struct drm_panel *panel)
+static inline struct rk_serdes_panel *drm_bridge_to_serdes_panel(struct drm_bridge *bridge)
 {
-	struct rk_serdes_panel *sd_panel = to_serdes_panel(panel);
-	struct rk_serdes_route *route = &sd_panel->route;
-	struct rk_serdes *serdes = sd_panel->parent;
+	return container_of(bridge, struct rk_serdes_panel, bridge);
+}
 
+static inline struct rk_serdes_panel *drm_connector_to_serdes_panel(struct drm_connector *connector)
+{
+	return container_of(connector, struct rk_serdes_panel, connector);
+}
+
+static int serdes_connector_get_modes(struct drm_connector *connector)
+{
+	struct rk_serdes_panel *sd_panel = drm_connector_to_serdes_panel(connector);
+
+	return drm_panel_get_modes(&sd_panel->panel, connector);
+}
+
+static const struct drm_connector_helper_funcs
+rk_serdes_connector_helper_funcs = {
+	.get_modes = serdes_connector_get_modes,
+};
+
+static enum drm_connector_status
+serdes_connector_detect(struct drm_connector *connector, bool force)
+{
+	struct rk_serdes_panel *sd_panel = drm_connector_to_serdes_panel(connector);
+
+	return drm_bridge_detect(&sd_panel->bridge);
+}
+
+static const struct drm_connector_funcs rk_serdes_connector_funcs = {
+	.detect = serdes_connector_detect,
+	.reset = drm_atomic_helper_connector_reset,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = drm_connector_cleanup,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static int rk_serdes_bridge_attach(struct drm_bridge *bridge,
+				  enum drm_bridge_attach_flags flags)
+{
+	struct rk_serdes_panel *sd_panel = drm_bridge_to_serdes_panel(bridge);
+	struct drm_connector *connector = &sd_panel->connector;
+	int ret;
+
+	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
+		return 0;
+
+	if (!bridge->encoder) {
+		dev_err(sd_panel->dev, "Missing encoder\n");
+		return -ENODEV;
+	}
+
+	connector->polled |= DRM_CONNECTOR_POLL_HPD;
+	drm_connector_helper_add(connector,
+				 &rk_serdes_connector_helper_funcs);
+
+	ret = drm_connector_init(bridge->dev, connector,
+				 &rk_serdes_connector_funcs,
+				 sd_panel->connector_type);
+	if (ret) {
+		dev_err(sd_panel->dev, "Failed to initialize connector\n");
+		return ret;
+	}
+
+	drm_connector_attach_encoder(&sd_panel->connector, bridge->encoder);
+
+	return 0;
+}
+
+static void rk_serdes_bridge_detach(struct drm_bridge *bridge)
+{
+	struct rk_serdes_panel *sd_panel = drm_bridge_to_serdes_panel(bridge);
+	struct drm_connector *connector = &sd_panel->connector;
+
+	/*
+	 * Cleanup the connector if we know it was initialized.
+	 */
+	if (connector->dev)
+		drm_connector_cleanup(connector);
+}
+
+static void rk_serdes_bridge_pre_enable(struct drm_bridge *bridge)
+{
+	struct rk_serdes_panel *sd_panel = drm_bridge_to_serdes_panel(bridge);
+
+	drm_panel_prepare(&sd_panel->panel);
+}
+
+static void rk_serdes_bridge_enable(struct drm_bridge *bridge)
+{
+	struct rk_serdes_panel *sd_panel = drm_bridge_to_serdes_panel(bridge);
+
+	drm_panel_enable(&sd_panel->panel);
+}
+
+static void rk_serdes_bridge_disable(struct drm_bridge *bridge)
+{
+	struct rk_serdes_panel *sd_panel = drm_bridge_to_serdes_panel(bridge);
+
+	drm_panel_disable(&sd_panel->panel);
+}
+
+static void rk_serdes_bridge_post_disable(struct drm_bridge *bridge)
+{
+	struct rk_serdes_panel *sd_panel = drm_bridge_to_serdes_panel(bridge);
+
+	drm_panel_unprepare(&sd_panel->panel);
+}
+
+static int rk_serdes_bridge_get_modes(struct drm_bridge *bridge,
+				      struct drm_connector *connector)
+{
+	struct rk_serdes_panel *sd_panel = drm_bridge_to_serdes_panel(bridge);
+
+	return drm_panel_get_modes(&sd_panel->panel, connector);
+}
+
+static enum drm_connector_status rk_serdes_bridge_detect(struct drm_bridge *bridge)
+{
+	return connector_status_connected;
+}
+
+static const struct drm_bridge_funcs panel_bridge_bridge_funcs = {
+	.attach = rk_serdes_bridge_attach,
+	.detach = rk_serdes_bridge_detach,
+	.pre_enable = rk_serdes_bridge_pre_enable,
+	.enable = rk_serdes_bridge_enable,
+	.disable = rk_serdes_bridge_disable,
+	.post_disable = rk_serdes_bridge_post_disable,
+	.get_modes = rk_serdes_bridge_get_modes,
+	.detect = rk_serdes_bridge_detect,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_get_input_bus_fmts = drm_atomic_helper_bridge_propagate_bus_fmt,
+};
+
+static int serdes_panel_hw_prepare(struct rk_serdes_panel *sd_panel)
+{
 	if (sd_panel->supply) {
 		int err;
 
@@ -58,36 +196,84 @@
 		mdelay(20);
 	}
 
+	return 0;
+}
+
+static int serdes_panel_dsi_prepare(struct rk_serdes_panel *sd_panel)
+{
+	struct rk_serdes *serdes = sd_panel->parent;
+
+	if (sd_panel->id == 0 && sd_panel->route.remote0_port0 == RK_SERDES_DSI_TX0 &&
+	    !!(sd_panel->on_cmds))
+		rkx120_dsi_tx_cmd_seq_xfer(serdes, &sd_panel->dsi_tx, DEVICE_REMOTE0,
+					   sd_panel->on_cmds);
+
+	if (sd_panel->id == 1 && sd_panel->route.remote1_port0 == RK_SERDES_DSI_TX0 &&
+	    !!(sd_panel->on_cmds))
+		rkx120_dsi_tx_cmd_seq_xfer(serdes, &sd_panel->dsi_tx, DEVICE_REMOTE1,
+					   sd_panel->on_cmds);
+
+	return 0;
+}
+
+static int serdes_panel_prepare(struct drm_panel *panel)
+{
+	struct rk_serdes_panel *sd_panel = drm_panel_to_serdes_panel(panel);
+	struct rk_serdes *serdes = sd_panel->parent;
+	int ret;
+
+	ret = serdes_panel_hw_prepare(sd_panel);
+	if (ret)
+		return ret;
+	if (sd_panel->secondary) {
+		ret = serdes_panel_hw_prepare(sd_panel->secondary);
+		if (ret)
+			return ret;
+	}
+
 	if (serdes->route_prepare)
 		serdes->route_prepare(serdes, &sd_panel->route);
 
-	if (route->remote0_port0 == RK_SERDES_DSI_TX0 && !!(sd_panel->on_cmds))
-		rkx120_dsi_tx_cmd_seq_xfer(serdes, DEVICE_REMOTE0,
-					   sd_panel->on_cmds);
-
-	if (route->remote1_port0 == RK_SERDES_DSI_TX0 && !!(sd_panel->on_cmds))
-		rkx120_dsi_tx_cmd_seq_xfer(serdes, DEVICE_REMOTE1,
-					   sd_panel->on_cmds);
+	serdes_panel_dsi_prepare(sd_panel);
+	if (sd_panel->secondary)
+		serdes_panel_dsi_prepare(sd_panel->secondary);
 
 	return 0;
 }
 
 static int serdes_panel_enable(struct drm_panel *panel)
 {
-	struct rk_serdes_panel *sd_panel = to_serdes_panel(panel);
+	struct rk_serdes_panel *sd_panel = drm_panel_to_serdes_panel(panel);
 	struct rk_serdes *serdes = sd_panel->parent;
+	int ret;
 
 	if (serdes->route_enable)
 		serdes->route_enable(serdes, &sd_panel->route);
+
+	if (sd_panel->secondary) {
+		ret = backlight_enable(sd_panel->secondary->panel.backlight);
+		if (ret < 0) {
+			dev_err(sd_panel->dev, "failed to enable backlight: %d\n", ret);
+			return ret;
+		}
+	}
 
 	return 0;
 }
 
 static int serdes_panel_disable(struct drm_panel *panel)
 {
-	struct rk_serdes_panel *sd_panel = to_serdes_panel(panel);
+	struct rk_serdes_panel *sd_panel = drm_panel_to_serdes_panel(panel);
 	struct rk_serdes *serdes = sd_panel->parent;
+	int ret;
 
+	if (sd_panel->secondary) {
+		ret = backlight_disable(sd_panel->secondary->panel.backlight);
+		if (ret < 0) {
+			dev_err(sd_panel->dev, "failed to disable backlight: %d\n", ret);
+			return ret;
+		}
+	}
 
 	if (serdes->route_disable)
 		serdes->route_disable(serdes, &sd_panel->route);
@@ -95,22 +281,8 @@
 	return 0;
 }
 
-static int serdes_panel_unprepare(struct drm_panel *panel)
+static int serdes_panel_hw_unprepare(struct rk_serdes_panel *sd_panel)
 {
-	struct rk_serdes_panel *sd_panel = to_serdes_panel(panel);
-	struct rk_serdes_route *route = &sd_panel->route;
-	struct rk_serdes *serdes = sd_panel->parent;
-
-	if (route->remote0_port0 == RK_SERDES_DSI_TX0 && !!(sd_panel->on_cmds))
-		rkx120_dsi_tx_cmd_seq_xfer(serdes, DEVICE_REMOTE0,
-					   sd_panel->off_cmds);
-
-	if (route->remote1_port0 == RK_SERDES_DSI_TX0 && !!(sd_panel->on_cmds))
-		rkx120_dsi_tx_cmd_seq_xfer(serdes, DEVICE_REMOTE1,
-					   sd_panel->off_cmds);
-	if (serdes->route_unprepare)
-		serdes->route_unprepare(serdes, &sd_panel->route);
-
 	if (sd_panel->reset_gpio) {
 		gpiod_set_value_cansleep(sd_panel->reset_gpio, 0);
 		mdelay(20);
@@ -123,6 +295,42 @@
 
 	if (sd_panel->supply)
 		regulator_disable(sd_panel->supply);
+
+	return 0;
+}
+
+static int serdes_panel_dsi_unprepare(struct rk_serdes_panel *sd_panel)
+{
+	struct rk_serdes *serdes = sd_panel->parent;
+
+	if (sd_panel->id == 0 && sd_panel->route.remote0_port0 == RK_SERDES_DSI_TX0 &&
+	    !!(sd_panel->off_cmds))
+		rkx120_dsi_tx_cmd_seq_xfer(serdes, &sd_panel->dsi_tx, DEVICE_REMOTE0,
+					   sd_panel->off_cmds);
+
+	if (sd_panel->id == 1 && sd_panel->route.remote1_port0 == RK_SERDES_DSI_TX0 &&
+	    !!(sd_panel->off_cmds))
+		rkx120_dsi_tx_cmd_seq_xfer(serdes, &sd_panel->dsi_tx, DEVICE_REMOTE1,
+					   sd_panel->off_cmds);
+
+	return 0;
+}
+
+static int serdes_panel_unprepare(struct drm_panel *panel)
+{
+	struct rk_serdes_panel *sd_panel = drm_panel_to_serdes_panel(panel);
+	struct rk_serdes *serdes = sd_panel->parent;
+
+	serdes_panel_dsi_unprepare(sd_panel);
+	if (sd_panel->secondary)
+		serdes_panel_dsi_unprepare(sd_panel->secondary);
+
+	if (serdes->route_unprepare)
+		serdes->route_unprepare(serdes, &sd_panel->route);
+
+	serdes_panel_hw_unprepare(sd_panel);
+	if (sd_panel->secondary)
+		serdes_panel_hw_unprepare(sd_panel->secondary);
 
 	return 0;
 }
@@ -184,7 +392,7 @@
 static int serdes_panel_get_modes(struct drm_panel *panel,
 				struct drm_connector *connector)
 {
-	struct rk_serdes_panel *sd_panel = to_serdes_panel(panel);
+	struct rk_serdes_panel *sd_panel = drm_panel_to_serdes_panel(panel);
 	int num = 0;
 
 	num += serdes_panel_of_get_native_mode(sd_panel, connector);
@@ -201,6 +409,52 @@
 	.unprepare = serdes_panel_unprepare,
 	.get_modes = serdes_panel_get_modes,
 };
+
+static void rk_serdes_panel_get_connector_type(struct rk_serdes_panel *sd_panel)
+{
+	struct rk_serdes_route *route = &sd_panel->route;
+	u32 local_port;
+
+	if (route->local_port0)
+		local_port = route->local_port0;
+	else
+		local_port = route->local_port1;
+
+	if ((local_port == RK_SERDES_DSI_RX0) ||
+	    (local_port == RK_SERDES_DSI_RX1))
+		sd_panel->connector_type = DRM_MODE_CONNECTOR_DSI;
+	else if (local_port == RK_SERDES_RGB_RX)
+		sd_panel->connector_type = DRM_MODE_CONNECTOR_DPI;
+	else
+		sd_panel->connector_type = DRM_MODE_CONNECTOR_LVDS;
+}
+
+static int rk_serdes_panel_bridge_add(struct rk_serdes_panel *sd_panel)
+{
+	int ret;
+
+	rk_serdes_panel_get_connector_type(sd_panel);
+
+	sd_panel->bridge.funcs = &panel_bridge_bridge_funcs;
+	sd_panel->bridge.of_node = sd_panel->dev->of_node;
+	sd_panel->bridge.ops = DRM_BRIDGE_OP_MODES | DRM_BRIDGE_OP_DETECT;
+	sd_panel->bridge.type = sd_panel->connector_type;
+
+	drm_panel_init(&sd_panel->panel, sd_panel->dev, &serdes_panel_funcs, 0);
+
+	ret = drm_panel_of_backlight(&sd_panel->panel);
+	if (ret)
+		return ret;
+
+	drm_bridge_add(&sd_panel->bridge);
+
+	return 0;
+}
+
+static void rk_serdes_panel_bridge_remove(struct rk_serdes_panel *sd_panel)
+{
+	drm_bridge_remove(&sd_panel->bridge);
+}
 
 static int
 dsi_panel_parse_cmds(struct device *dev, const u8 *data,
@@ -336,11 +590,10 @@
 	return dsi;
 }
 
-static int rkx120_dsi_rx_parse(struct rk_serdes_panel *sd_panel)
+static int rkx110_dsi_rx_parse(struct rk_serdes_panel *sd_panel)
 {
 	struct device_node *np = sd_panel->dev->of_node;
-	struct rk_serdes *serdes = sd_panel->parent;
-	struct rkx110_dsi_rx *dsi_rx = &serdes->dsi_rx;
+	struct rkx110_dsi_rx *dsi_rx = &sd_panel->dsi_rx;
 	struct mipi_dsi_device *dsi;
 	struct device_node *dsi_node;
 	u32 val;
@@ -370,11 +623,12 @@
 static int rkx120_dsi_tx_parse(struct rk_serdes_panel *sd_panel)
 {
 	struct device_node *np = sd_panel->dev->of_node;
-	struct rk_serdes *serdes = sd_panel->parent;
-	struct rkx120_dsi_tx *dsi_tx = &serdes->dsi_tx;
+	struct rkx120_dsi_tx *dsi_tx = &sd_panel->dsi_tx;
 	const char *string;
 	int ret;
 	u32 val;
+
+	dsi_tx->combtxphy = &sd_panel->combtxphy;
 
 	if (of_property_read_u32(np, "dsi-tx,lanes", &val))
 		dsi_tx->lanes = 4;
@@ -418,12 +672,9 @@
 	return 0;
 }
 
-static int serdes_panel_parse_dt(struct rk_serdes_panel *sd_panel)
+static int serdes_panel_parse_route(struct rk_serdes_panel *sd_panel)
 {
 	struct rk_serdes_route *route = &sd_panel->route;
-	struct rk_serdes *serdes = sd_panel->parent;
-	u32 lanes;
-	int ret;
 
 	device_property_read_u32(sd_panel->dev, "local-port0", &route->local_port0);
 	device_property_read_u32(sd_panel->dev, "local-port1", &route->local_port1);
@@ -431,17 +682,19 @@
 	device_property_read_u32(sd_panel->dev, "remote0-port1", &route->remote0_port1);
 	device_property_read_u32(sd_panel->dev, "remote1-port0", &route->remote1_port0);
 	device_property_read_u32(sd_panel->dev, "remote1-port1", &route->remote1_port1);
-	device_property_read_u32(sd_panel->dev, "num-lanes", &lanes);
 
-	serdes->route_flag = 0;
-
-	if (!route->local_port0) {
-		dev_err(sd_panel->dev, "local_port0 should set\n");
+	if (!route->local_port0 && !route->local_port1) {
+		dev_err(sd_panel->dev, "local port should set\n");
 		return -EINVAL;
 	}
 
-	if (!route->remote0_port0) {
+	if (route->local_port0 && !route->remote0_port0) {
 		dev_err(sd_panel->dev, "remote0_port0 should set\n");
+		return -EINVAL;
+	}
+
+	if (route->local_port1 && !route->remote1_port0) {
+		dev_err(sd_panel->dev, "remote1_port0 should set\n");
 		return -EINVAL;
 	}
 
@@ -451,48 +704,28 @@
 	}
 
 	route->frame_mode = SERDES_FRAME_NORMAL_MODE;
+	route->route_flag = 0;
 
-	/* 2 video stream output */
-	if (route->remote1_port0 || route->remote0_port1) {
+	/* 2 video stream output in a route */
+	if (route->local_port0 && (route->remote1_port0 || route->remote0_port1)) {
 		if (route->remote1_port0)
-			serdes->route_flag |= ROUTE_MULTI_REMOTE | ROUTE_MULTI_CHANNEL |
+			route->route_flag |= ROUTE_MULTI_REMOTE | ROUTE_MULTI_CHANNEL|
 					     ROUTE_MULTI_LANE;
 
 		if (route->remote0_port1) {
 			if ((route->remote0_port0 == RK_SERDES_LVDS_TX0) &&
 			    (route->remote0_port1 == RK_SERDES_LVDS_TX1)) {
-				serdes->route_flag |= ROUTE_MULTI_CHANNEL;
+				route->route_flag |= ROUTE_MULTI_CHANNEL;
 			} else if ((route->remote0_port0 == RK_SERDES_LVDS_TX1) &&
 				    (route->remote0_port1 == RK_SERDES_LVDS_TX0)) {
-				serdes->route_flag |= ROUTE_MULTI_CHANNEL;
+				route->route_flag |= ROUTE_MULTI_CHANNEL;
 			} else {
 				dev_err(sd_panel->dev, "invalid multi output type\n");
 				return -EINVAL;
 			}
-
-			if (lanes == 2)
-				serdes->route_flag |= ROUTE_MULTI_LANE;
 		}
 
-		if (route->local_port1) {
-			if ((route->local_port0 == RK_SERDES_DSI_RX0) &&
-			    (route->local_port1 == RK_SERDES_DSI_RX1))
-				serdes->route_flag |= ROUTE_MULTI_DSI_INPUT;
-			else if ((route->local_port0 == RK_SERDES_DSI_RX1) &&
-				 (route->local_port1 == RK_SERDES_DSI_RX0))
-				serdes->route_flag |= ROUTE_MULTI_DSI_INPUT;
-			else if ((route->local_port0 == RK_SERDES_LVDS_RX0) &&
-				 (route->local_port1 == RK_SERDES_LVDS_RX1))
-				serdes->route_flag |= ROUTE_MULTI_LVDS_INPUT;
-			else if ((route->local_port0 == RK_SERDES_LVDS_RX1) &&
-				 (route->local_port1 == RK_SERDES_LVDS_RX0))
-				serdes->route_flag |= ROUTE_MULTI_LVDS_INPUT;
-			else {
-				dev_err(sd_panel->dev, "invalid multi input type\n");
-				return -EINVAL;
-			}
-			serdes->route_flag |= ROUTE_MULTI_SOURCE;
-		} else {
+		if (route->local_port0) {
 			if (device_property_read_bool(sd_panel->dev, "split-mode")) {
 				/* only dsi input support split mode */
 				if ((route->local_port0 != RK_SERDES_DSI_RX0) &&
@@ -510,41 +743,43 @@
 				else
 					route->frame_mode = SERDES_SP_LEFT_RIGHT_SPLIT;
 
-				serdes->route_flag |= ROUTE_MULTI_SPLIT;
+				route->route_flag |= ROUTE_MULTI_SPLIT;
 
 			} else  {
-				serdes->route_flag |= ROUTE_MULTI_MIRROR;
+				route->route_flag |= ROUTE_MULTI_MIRROR;
 			}
 		}
-	} else {
-		if (lanes == 2)
-			serdes->route_flag |= ROUTE_MULTI_LANE;
-	}
-
-	if (route->remote0_port0 & RK_SERDES_DSI_TX0 ||
-	    route->remote1_port0 & RK_SERDES_DSI_TX0) {
-		ret = rkx120_dsi_tx_parse(sd_panel);
-		if (ret) {
-			dev_err(sd_panel->dev, "failed to get cmds\n");
-			return ret;
-		}
-	}
-
-	if (route->local_port0 & RK_SERDES_DSI_RX0 ||
-	    route->local_port0 & RK_SERDES_DSI_TX1) {
-		ret = rkx120_dsi_rx_parse(sd_panel);
-		if (ret < 0)
-			return ret;
 	}
 
 	return 0;
 }
 
+static int serdes_panel_match_by_id(struct device *dev, const void *data)
+{
+	struct rk_serdes_panel *sd_panel = dev_get_drvdata(dev);
+	unsigned int *id = (unsigned int *)data;
+
+	return sd_panel->id == *id;
+}
+
+static struct rk_serdes_panel *serdes_panel_find_by_id(struct device_driver *drv,
+						       unsigned int id)
+{
+	struct device *dev;
+
+	dev = driver_find_device(drv, NULL, &id, serdes_panel_match_by_id);
+	if (!dev)
+		return NULL;
+
+	return dev_get_drvdata(dev);
+}
+
 static int serdes_panel_probe(struct platform_device *pdev)
 {
 	struct rk_serdes *serdes = dev_get_drvdata(pdev->dev.parent);
-	struct rk_serdes_panel *sd_panel;
+	struct rk_serdes_panel *sd_panel, *secondary;
 	int ret;
+	u32 reg;
 
 	sd_panel = devm_kzalloc(&pdev->dev, sizeof(*sd_panel), GFP_KERNEL);
 	if (!sd_panel)
@@ -553,7 +788,20 @@
 	sd_panel->dev = &pdev->dev;
 	sd_panel->parent = serdes;
 	sd_panel->route.stream_type = STREAM_DISPLAY;
-	serdes->vm = &sd_panel->route.vm;
+
+	ret = of_property_read_u32(sd_panel->dev->of_node, "reg", &reg);
+	if (ret)
+		sd_panel->id = 0;
+	sd_panel->id = reg;
+
+	sd_panel->multi_panel = device_property_read_bool(sd_panel->dev, "multi-panel");
+	if (sd_panel->multi_panel) {
+		secondary = serdes_panel_find_by_id(sd_panel->dev->driver, 1);
+		if (!secondary)
+			return -EPROBE_DEFER;
+		sd_panel->secondary = secondary;
+		dev_info(sd_panel->dev, "%s get secondary panel\n", __func__);
+	}
 
 	sd_panel->supply = devm_regulator_get_optional(sd_panel->dev, "power");
 	if (IS_ERR(sd_panel->supply)) {
@@ -588,22 +836,58 @@
 		return ret;
 	}
 
-	/* Register the panel. */
-	drm_panel_init(&sd_panel->panel, sd_panel->dev, &serdes_panel_funcs, 0);
+	ret = serdes_panel_parse_route(sd_panel);
+	if (ret < 0)
+		return ret;
 
-	ret = drm_panel_of_backlight(&sd_panel->panel);
+	if (sd_panel->route.remote0_port0 & RK_SERDES_DSI_TX0 ||
+		sd_panel->route.remote1_port0 & RK_SERDES_DSI_TX0) {
+		ret = rkx120_dsi_tx_parse(sd_panel);
+		if (ret) {
+			dev_err(sd_panel->dev, "failed to get cmds\n");
+			return ret;
+		}
+	}
+
+	ret = rk_serdes_panel_bridge_add(sd_panel);
 	if (ret)
 		return ret;
 
-	drm_panel_add(&sd_panel->panel);
+	if ((sd_panel->route.local_port0 & RK_SERDES_DSI_RX0 ||
+	    sd_panel->route.local_port0 & RK_SERDES_DSI_RX1) && sd_panel->id == 0) {
+		ret = rkx110_dsi_rx_parse(sd_panel);
+		if (ret < 0) {
+			rk_serdes_panel_bridge_remove(sd_panel);
+			return ret;
+		}
+	}
+
+	if ((sd_panel->route.local_port1 & RK_SERDES_DSI_RX0 ||
+		sd_panel->route.local_port1 & RK_SERDES_DSI_RX1) && sd_panel->id == 1) {
+		ret = rkx110_dsi_rx_parse(sd_panel);
+		if (ret < 0) {
+			rk_serdes_panel_bridge_remove(sd_panel);
+			return ret;
+		}
+	}
 
 	dev_set_drvdata(sd_panel->dev, sd_panel);
 
-	ret = serdes_panel_parse_dt(sd_panel);
-	if (ret < 0) {
-		drm_panel_remove(&sd_panel->panel);
-		return ret;
+	if (sd_panel->route.route_flag & ROUTE_MULTI_CHANNEL)
+		serdes->channel_nr = 2;
+
+	if (sd_panel->route.local_port0 && sd_panel->id == 0) {
+		serdes->route[0] = &sd_panel->route;
+		serdes->route_nr++;
 	}
+
+	if (sd_panel->route.local_port1 && sd_panel->id == 1) {
+		serdes->route[1] = &sd_panel->route;
+		serdes->route_nr++;
+	}
+
+	if (serdes->route_nr == 2)
+		serdes->channel_nr = 2;
 
 	return 0;
 }
@@ -612,7 +896,7 @@
 {
 	struct rk_serdes_panel *sd_panel = dev_get_drvdata(&pdev->dev);
 
-	drm_panel_remove(&sd_panel->panel);
+	rk_serdes_panel_bridge_remove(sd_panel);
 
 	drm_panel_disable(&sd_panel->panel);
 
@@ -630,7 +914,7 @@
 	.probe		= serdes_panel_probe,
 	.remove		= serdes_panel_remove,
 	.driver		= {
-		.name	= "serdes-panel",
+		.name	= "rockchip-serdes-panel",
 		.of_match_table = serdes_panel_of_table,
 	},
 };
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx120.c b/kernel/drivers/mfd/rkx110_x120/rkx120.c
index 75150fe..2f38af1 100644
--- a/kernel/drivers/mfd/rkx110_x120/rkx120.c
+++ b/kernel/drivers/mfd/rkx110_x120/rkx120.c
@@ -21,16 +21,24 @@
 		.base = RKX120_PATTERN_GEN_DSI_BASE,
 		.link_src_reg = DES_GRF_SOC_CON2,
 		.link_src_offset = 12,
+		.type = RK_SERDES_DSI_TX0,
+	}, {
+		.name = "dual-lvds",
+		.link_src_reg = DES_GRF_SOC_CON1,
+		.link_src_offset = 14,
+		.type = RK_SERDES_DUAL_LVDS_TX,
 	}, {
 		.name = "lvds0",
 		.base = RKX120_PATTERN_GEN_LVDS0_BASE,
 		.link_src_reg = DES_GRF_SOC_CON2,
 		.link_src_offset = 13,
+		.type = RK_SERDES_LVDS_TX0,
 	}, {
 		.name = "lvds1",
 		.base = RKX120_PATTERN_GEN_LVDS1_BASE,
 		.link_src_reg = DES_GRF_SOC_CON2,
 		.link_src_offset = 14,
+		.type = RK_SERDES_LVDS_TX1,
 	},
 	{ /* sentinel */ }
 };
@@ -111,6 +119,11 @@
 		.name = "pcs1",
 		.reg_base = RKX120_DES_PCS1_BASE,
 		.reg_len = 0x1c0,
+	},
+	{
+		.name = "pwm",
+		.reg_base = RKX120_PWM_BASE,
+		.reg_len = 0x100,
 	},
 	{
 		.name = "pma0",
@@ -231,8 +244,13 @@
 void rkx120_debugfs_init(struct rk_serdes_chip *chip, struct dentry *dentry)
 {
 	const struct rk_serdes_reg *regs = rkx120_regs;
-	struct pattern_gen *pattern_gen = rkx120_pattern_gen;
+	struct pattern_gen *pattern_gen;
 	struct dentry *dir;
+
+	pattern_gen = devm_kmemdup(chip->serdes->dev, &rkx120_pattern_gen,
+				   sizeof(rkx120_pattern_gen), GFP_KERNEL);
+	if (!pattern_gen)
+		return;
 
 	dir = debugfs_create_dir("registers", dentry);
 	if (!IS_ERR(dir)) {
@@ -289,6 +307,8 @@
 			  u8 phy_id)
 {
 	struct i2c_client *client = serdes->chip[remote_id].client;
+	struct rk_serdes_panel *sd_panel = container_of(route, struct rk_serdes_panel, route);
+	struct rkx120_combtxphy *combtxphy = &sd_panel->combtxphy;
 
 	if (phy_id) {
 		serdes->i2c_write_reg(client, DES_GRF_SOC_CON7, 0xfff00630);
@@ -298,12 +318,12 @@
 		serdes->i2c_write_reg(client, DES_GRF_SOC_CON2, 0x00040004);
 	}
 
-	rkx120_combtxphy_set_mode(serdes, COMBTX_PHY_MODE_VIDEO_LVDS);
+	rkx120_combtxphy_set_mode(combtxphy, COMBTX_PHY_MODE_VIDEO_LVDS);
 	if (route->remote0_port0 & RK_SERDES_DUAL_LVDS_TX)
-		rkx120_combtxphy_set_rate(serdes, route->vm.pixelclock * 7 / 2);
+		rkx120_combtxphy_set_rate(combtxphy, route->vm.pixelclock * 7 / 2);
 	else
-		rkx120_combtxphy_set_rate(serdes, route->vm.pixelclock * 7);
-	rkx120_combtxphy_power_on(serdes, remote_id, phy_id);
+		rkx120_combtxphy_set_rate(combtxphy, route->vm.pixelclock * 7);
+	rkx120_combtxphy_power_on(serdes, combtxphy, remote_id, phy_id);
 
 	return 0;
 }
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx120_combtxphy.c b/kernel/drivers/mfd/rkx110_x120/rkx120_combtxphy.c
index 7a44e71..6e516c7 100644
--- a/kernel/drivers/mfd/rkx110_x120/rkx120_combtxphy.c
+++ b/kernel/drivers/mfd/rkx110_x120/rkx120_combtxphy.c
@@ -111,9 +111,10 @@
 #define GRF_MIPI_STATUS		0x0080
 #define PHYLOCK			BIT(0)
 
-static void rkx120_combtxphy_dsi_timing_init(struct rk_serdes *des, u8 remote_id)
+static void rkx120_combtxphy_dsi_timing_init(struct rk_serdes *des,
+					     struct rkx120_combtxphy *combtxphy,
+					     u8 dev_id)
 {
-	struct rkx120_combtxphy *combtxphy = &des->combtxphy;
 	const struct configure_opts_combphy cfg = combtxphy->mipi_dphy_cfg;
 	u32 byte_clk = DIV_ROUND_CLOSEST_ULL(combtxphy->rate, 8);
 	u32 esc_div = DIV_ROUND_UP(byte_clk, 20 * USEC_PER_SEC);
@@ -123,30 +124,30 @@
 	u32 t_tago, t_tasure, t_taget;
 	u32 base = RKX120_MIPI_LVDS_TX_PHY0_BASE;
 
-	serdes_combphy_write(des, remote_id, base + INTERFACE_PARA,
+	serdes_combphy_write(des, dev_id, base + INTERFACE_PARA,
 			     TXREADYESC_VLD(esc_div - 2) |
 			     RXVALIDESC_VLD(esc_div - 2));
-	serdes_combphy_write(des, remote_id, base + COMMON_PARA0, esc_div);
-	serdes_combphy_update_bits(des, remote_id, base + TEST_PARA0, FSET_EN, FSET_EN);
+	serdes_combphy_write(des, dev_id, base + COMMON_PARA0, esc_div);
+	serdes_combphy_update_bits(des, dev_id, base + TEST_PARA0, FSET_EN, FSET_EN);
 
 	t_init = DIV_ROUND_UP(cfg.init, t_byte_clk) - 1;
-	serdes_combphy_write(des, remote_id, base + CLANE_PARA1, T_INITTIME_C(t_init));
-	serdes_combphy_write(des, remote_id, base + DLANE0_PARA1, T_INITTIME_D(t_init));
-	serdes_combphy_write(des, remote_id, base + DLANE_PARA1(1), T_INITTIME_D(t_init));
-	serdes_combphy_write(des, remote_id, base + DLANE_PARA1(2), T_INITTIME_D(t_init));
-	serdes_combphy_write(des, remote_id, base + DLANE_PARA1(3), T_INITTIME_D(t_init));
+	serdes_combphy_write(des, dev_id, base + CLANE_PARA1, T_INITTIME_C(t_init));
+	serdes_combphy_write(des, dev_id, base + DLANE0_PARA1, T_INITTIME_D(t_init));
+	serdes_combphy_write(des, dev_id, base + DLANE_PARA1(1), T_INITTIME_D(t_init));
+	serdes_combphy_write(des, dev_id, base + DLANE_PARA1(2), T_INITTIME_D(t_init));
+	serdes_combphy_write(des, dev_id, base + DLANE_PARA1(3), T_INITTIME_D(t_init));
 
 	t_clkprepare = DIV_ROUND_UP(cfg.clk_prepare, t_byte_clk) - 1;
 	t_clkzero = DIV_ROUND_UP(cfg.clk_zero, t_byte_clk) - 1;
 	t_clkpre = DIV_ROUND_UP(cfg.clk_pre, t_byte_clk) - 1;
-	serdes_combphy_write(des, remote_id, base + CLANE_PARA2,
+	serdes_combphy_write(des, dev_id, base + CLANE_PARA2,
 			     T_CLKPREPARE_C(t_clkprepare) |
 			     T_CLKZERO_C(t_clkzero) | T_CLKPRE_C(t_clkpre));
 
 	t_clkpost = DIV_ROUND_UP(cfg.clk_post, t_byte_clk) - 1;
 	t_clktrail = DIV_ROUND_UP(cfg.clk_trail, t_byte_clk) - 1;
 	t_hsexit = DIV_ROUND_UP(cfg.hs_exit, t_byte_clk) - 1;
-	serdes_combphy_write(des, remote_id, base + CLANE_PARA3,
+	serdes_combphy_write(des, dev_id, base + CLANE_PARA3,
 			     T_CLKPOST_C(t_clkpost) |
 			     T_CLKTRAIL_C(t_clktrail) |
 			     T_HSEXIT_C(t_hsexit));
@@ -154,62 +155,63 @@
 	t_hsprepare = DIV_ROUND_UP(cfg.hs_prepare, t_byte_clk) - 1;
 	t_hszero = DIV_ROUND_UP(cfg.hs_zero, t_byte_clk) - 1;
 	t_hstrail = DIV_ROUND_UP(cfg.hs_trail, t_byte_clk) - 1;
-	serdes_combphy_write(des, remote_id, base + DLANE0_PARA2,
+	serdes_combphy_write(des, dev_id, base + DLANE0_PARA2,
 			     T_HSPREPARE_D(t_hsprepare) |
 			     T_HSZERO_D(t_hszero) |
 			     T_HSTRAIL_D(t_hstrail) |
 			     T_HSEXIT_D(t_hsexit));
 
-	serdes_combphy_write(des, remote_id, base + DLANE_PARA2(1),
+	serdes_combphy_write(des, dev_id, base + DLANE_PARA2(1),
 			     T_HSPREPARE_D(t_hsprepare) |
 			     T_HSZERO_D(t_hszero) |
 			     T_HSTRAIL_D(t_hstrail) |
 			     T_HSEXIT_D(t_hsexit));
 
-	serdes_combphy_write(des, remote_id, base + DLANE_PARA2(2),
+	serdes_combphy_write(des, dev_id, base + DLANE_PARA2(2),
 			     T_HSPREPARE_D(t_hsprepare) |
 			     T_HSZERO_D(t_hszero) |
 			     T_HSTRAIL_D(t_hstrail) |
 			     T_HSEXIT_D(t_hsexit));
 
-	serdes_combphy_write(des, remote_id, base + DLANE_PARA2(3),
+	serdes_combphy_write(des, dev_id, base + DLANE_PARA2(3),
 			     T_HSPREPARE_D(t_hsprepare) |
 			     T_HSZERO_D(t_hszero) |
 			     T_HSTRAIL_D(t_hstrail) |
 			     T_HSEXIT_D(t_hsexit));
 
 	t_wakeup = DIV_ROUND_UP(cfg.wakeup, t_byte_clk) - 1;
-	serdes_combphy_write(des, remote_id, base + DLANE0_PARA3, T_WAKEUP_D(t_wakeup));
-	serdes_combphy_write(des, remote_id, base + DLANE_PARA3(1), T_WAKEUP_D(t_wakeup));
-	serdes_combphy_write(des, remote_id, base + DLANE_PARA3(2), T_WAKEUP_D(t_wakeup));
-	serdes_combphy_write(des, remote_id, base + DLANE_PARA3(3), T_WAKEUP_D(t_wakeup));
-	serdes_combphy_write(des, remote_id, base + CLANE_PARA4, T_WAKEUP_D(t_wakeup));
+	serdes_combphy_write(des, dev_id, base + DLANE0_PARA3, T_WAKEUP_D(t_wakeup));
+	serdes_combphy_write(des, dev_id, base + DLANE_PARA3(1), T_WAKEUP_D(t_wakeup));
+	serdes_combphy_write(des, dev_id, base + DLANE_PARA3(2), T_WAKEUP_D(t_wakeup));
+	serdes_combphy_write(des, dev_id, base + DLANE_PARA3(3), T_WAKEUP_D(t_wakeup));
+	serdes_combphy_write(des, dev_id, base + CLANE_PARA4, T_WAKEUP_D(t_wakeup));
 
 	t_tago = DIV_ROUND_UP(cfg.ta_go, t_byte_clk) - 1;
 	t_tasure = DIV_ROUND_UP(cfg.ta_sure, t_byte_clk) - 1;
 	t_taget = DIV_ROUND_UP(cfg.ta_get, t_byte_clk) - 1;
-	serdes_combphy_write(des, remote_id, base + DLANE0_PARA4,
+	serdes_combphy_write(des, dev_id, base + DLANE0_PARA4,
 			     T_TAGO_D0(t_tago) |
 			     T_TASURE_D0(t_tasure) |
 			     T_TAGET_D0(t_taget));
 }
 
-static void rkx120_combtxphy_dsi_pll_set(struct rk_serdes *des, u8 remote_id)
+static void rkx120_combtxphy_dsi_pll_set(struct rk_serdes *des,
+					 struct rkx120_combtxphy *combtxphy, u8 dev_id)
 {
-	struct rkx120_combtxphy *combtxphy = &des->combtxphy;
 	u32 base = RKX120_MIPI_LVDS_TX_PHY0_BASE;
 
-	serdes_combphy_update_bits(des, remote_id, base + PLL_CTRL_PARA0,
+	serdes_combphy_update_bits(des, dev_id, base + PLL_CTRL_PARA0,
 				   RATE_MASK | REFCLK_DIV_MASK | PLL_DIV_MASK,
 				   RATE(combtxphy->rate_factor) |
 				   REFCLK_DIV(combtxphy->ref_div - 1) |
 				   PLL_DIV(combtxphy->fb_div));
 }
 
-static void rkx120_combtxphy_dsi_power_on(struct rk_serdes *des, u8 remote_id)
+static void rkx120_combtxphy_dsi_power_on(struct rk_serdes *des,
+					  struct rkx120_combtxphy *combtxphy,
+					  u8 dev_id)
 {
-	struct rkx120_combtxphy *combtxphy = &des->combtxphy;
-	struct i2c_client *client = des->chip[remote_id].client;
+	struct i2c_client *client = des->chip[dev_id].client;
 	u32 grf_base = RKX120_GRF_MIPI0_BASE;
 	u32 val;
 	int ret;
@@ -218,8 +220,8 @@
 			   PHY_MODE(COMBTX_PHY_MODE_VIDEO_MIPI));
 
 	serdes_combphy_get_default_config(combtxphy->rate, &combtxphy->mipi_dphy_cfg);
-	rkx120_combtxphy_dsi_timing_init(des, remote_id);
-	rkx120_combtxphy_dsi_pll_set(des, remote_id);
+	rkx120_combtxphy_dsi_timing_init(des, combtxphy, dev_id);
+	rkx120_combtxphy_dsi_pll_set(des, combtxphy, dev_id);
 
 	des->i2c_write_reg(client, grf_base + GRF_MIPITX_CON0, PHYSHUTDWN(1));
 	des->i2c_write_reg(client, grf_base + GRF_MIPITX_CON1, PWON_PLL(1));
@@ -233,19 +235,20 @@
 		dev_err(des->dev, "PLL is not locked\n");
 }
 
-static void rkx120_combtxphy_dsi_power_off(struct rk_serdes *des, u8 remote_id)
+static void rkx120_combtxphy_dsi_power_off(struct rk_serdes *des, u8 dev_id)
 {
-	struct i2c_client *client = des->chip[remote_id].client;
+	struct i2c_client *client = des->chip[dev_id].client;
 	u32 grf_base = RKX120_GRF_MIPI0_BASE;
 
 	des->i2c_write_reg(client, grf_base + GRF_MIPITX_CON0, PHYSHUTDWN(0));
 	des->i2c_write_reg(client, grf_base + GRF_MIPITX_CON1, PWON_PLL(0));
 }
 
-static void rkx120_combtxphy_lvds_power_on(struct rk_serdes *des, u8 remote_id, u8 phy_id)
+static void rkx120_combtxphy_lvds_power_on(struct rk_serdes *des,
+					   struct rkx120_combtxphy *combtxphy,
+					   u8 dev_id, u8 phy_id)
 {
-	struct rkx120_combtxphy *combtxphy = &des->combtxphy;
-	struct i2c_client *client = des->chip[remote_id].client;
+	struct i2c_client *client = des->chip[dev_id].client;
 	u32 grf_base = (phy_id == 0) ?
 			RKX120_GRF_MIPI0_BASE : RKX120_GRF_MIPI1_BASE;
 	const struct {
@@ -304,29 +307,27 @@
 	des->i2c_write_reg(client, grf_base + GRF_MIPITX_CON13, TX_IDLE(0));
 }
 
-void rkx120_combtxphy_power_on(struct rk_serdes *des, u8 remote_id, u8 phy_id)
+void rkx120_combtxphy_power_on(struct rk_serdes *des, struct rkx120_combtxphy *combtxphy,
+			       u8 dev_id, u8 phy_id)
 {
-	struct rkx120_combtxphy *combtxphy = &des->combtxphy;
-
 	switch (combtxphy->mode) {
 	case COMBTX_PHY_MODE_VIDEO_MIPI:
-		rkx120_combtxphy_dsi_power_on(des, remote_id);
+		rkx120_combtxphy_dsi_power_on(des, combtxphy, dev_id);
 		break;
 	case COMBTX_PHY_MODE_VIDEO_LVDS:
-		rkx120_combtxphy_lvds_power_on(des, remote_id, phy_id);
+		rkx120_combtxphy_lvds_power_on(des, combtxphy, dev_id, phy_id);
 		break;
 	default:
 		break;
 	}
 }
 
-void rkx120_combtxphy_power_off(struct rk_serdes *des, u8 remote_id)
+void rkx120_combtxphy_power_off(struct rk_serdes *des, struct rkx120_combtxphy *combtxphy,
+				u8 dev_id, u8 phy_id)
 {
-	struct rkx120_combtxphy *combtxphy = &des->combtxphy;
-
 	switch (combtxphy->mode) {
 	case COMBTX_PHY_MODE_VIDEO_MIPI:
-		rkx120_combtxphy_dsi_power_off(des, remote_id);
+		rkx120_combtxphy_dsi_power_off(des, dev_id);
 		break;
 	case COMBTX_PHY_MODE_VIDEO_LVDS:
 		break;
@@ -385,10 +386,8 @@
 {
 }
 
-void rkx120_combtxphy_set_rate(struct rk_serdes *des, u64 rate)
+void rkx120_combtxphy_set_rate(struct rkx120_combtxphy *combtxphy, u64 rate)
 {
-	struct rkx120_combtxphy *combtxphy = &des->combtxphy;
-
 	switch (combtxphy->mode) {
 	case COMBTX_PHY_MODE_VIDEO_MIPI:
 		rkx120_combtxphy_dsi_pll_calc_rate(combtxphy, rate);
@@ -403,14 +402,12 @@
 	combtxphy->rate = rate;
 }
 
-u64 rkx120_combtxphy_get_rate(struct rk_serdes *des)
+u64 rkx120_combtxphy_get_rate(struct rkx120_combtxphy *combtxphy)
 {
-	return des->combtxphy.rate;
+	return combtxphy->rate;
 }
 
-void rkx120_combtxphy_set_mode(struct rk_serdes *des, enum combtx_phy_mode mode)
+void rkx120_combtxphy_set_mode(struct rkx120_combtxphy *combtxphy, enum combtx_phy_mode mode)
 {
-	struct rkx120_combtxphy *combtxphy = &des->combtxphy;
-
 	combtxphy->mode = mode;
 }
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx120_dsi_tx.c b/kernel/drivers/mfd/rkx110_x120/rkx120_dsi_tx.c
index 70a122e..4e262c4 100644
--- a/kernel/drivers/mfd/rkx110_x120/rkx120_dsi_tx.c
+++ b/kernel/drivers/mfd/rkx110_x120/rkx120_dsi_tx.c
@@ -751,10 +751,9 @@
 	return msg->tx_len;
 }
 
-static int rkx120_mipi_dsi_generic_write(struct rk_serdes *des, u8 remote_id,
-				  const void *payload, size_t size)
+static int rkx120_mipi_dsi_generic_write(struct rk_serdes *des, struct rkx120_dsi_tx *dsi,
+					 u8 remote_id, const void *payload, size_t size)
 {
-	const struct rkx120_dsi_tx *dsi = &des->dsi_tx;
 	struct mipi_dsi_msg msg;
 
 	memset(&msg, 0, sizeof(msg));
@@ -785,10 +784,9 @@
 	return rkx120_dsi_tx_transfer(des, remote_id, dsi, &msg);
 }
 
-static int rkx120_mipi_dsi_dcs_write_buffer(struct rk_serdes *des, u8 remote_id,
-				     const void *data, size_t len)
+static int rkx120_mipi_dsi_dcs_write_buffer(struct rk_serdes *des, struct rkx120_dsi_tx *dsi,
+					    u8 remote_id, const void *data, size_t len)
 {
-	const struct rkx120_dsi_tx *dsi = &des->dsi_tx;
 	struct mipi_dsi_msg msg;
 
 	memset(&msg, 0, sizeof(msg));
@@ -818,10 +816,9 @@
 }
 
 static __maybe_unused int
-rkx120_mipi_dsi_dcs_read(struct rk_serdes *des, u8 remote_id,
+rkx120_mipi_dsi_dcs_read(struct rk_serdes *des, struct rkx120_dsi_tx *dsi, u8 remote_id,
 			 u8 cmd, void *data, size_t len)
 {
-	const struct rkx120_dsi_tx *dsi = &des->dsi_tx;
 	struct mipi_dsi_msg msg;
 
 	memset(&msg, 0, sizeof(msg));
@@ -835,7 +832,7 @@
 	return rkx120_dsi_tx_transfer(des, remote_id, dsi, &msg);
 }
 
-int rkx120_dsi_tx_cmd_seq_xfer(struct rk_serdes *des, u8 remote_id,
+int rkx120_dsi_tx_cmd_seq_xfer(struct rk_serdes *des, struct rkx120_dsi_tx *dsi, u8 remote_id,
 			       struct panel_cmds *cmds)
 {
 	u16 i;
@@ -852,13 +849,13 @@
 		case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
 		case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
 		case MIPI_DSI_GENERIC_LONG_WRITE:
-			err = rkx120_mipi_dsi_generic_write(des, remote_id, cmd->payload,
+			err = rkx120_mipi_dsi_generic_write(des, dsi, remote_id, cmd->payload,
 							    cmd->dchdr.dlen);
 			break;
 		case MIPI_DSI_DCS_SHORT_WRITE:
 		case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
 		case MIPI_DSI_DCS_LONG_WRITE:
-			err = rkx120_mipi_dsi_dcs_write_buffer(des, remote_id, cmd->payload,
+			err = rkx120_mipi_dsi_dcs_write_buffer(des, dsi, remote_id, cmd->payload,
 							       cmd->dchdr.dlen);
 			break;
 		default:
@@ -901,7 +898,8 @@
 }
 
 static void
-mipi_dphy_power_on(struct rk_serdes *des, const struct rkx120_dsi_tx *dsi, u8 remote_id)
+mipi_dphy_power_on(struct rk_serdes *des, const struct rkx120_dsi_tx *dsi,
+		   u8 remote_id)
 {
 	struct i2c_client *client = des->chip[remote_id].client;
 	u32 val, mask;
@@ -920,7 +918,7 @@
 	dsi_update_bits(des, remote_id, DSI_PHY_RSTZ, PHY_RSTZ, PHY_RSTZ);
 	usleep_range(1500, 2000);
 
-	rkx120_combtxphy_power_on(des, remote_id, 0);
+	rkx120_combtxphy_power_on(des, dsi->combtxphy, remote_id, 0);
 
 	ret = read_poll_timeout(des->i2c_read_reg, ret,
 				!(ret < 0) && (val & PHY_LOCK),
@@ -954,9 +952,9 @@
 	//dsi_i2c_write(des, remote_id, CRU_SOFTRST_CON02, 0x400000);
 }
 
-static void rkx120_dsi_tx_bridge_pre_enable(struct rk_serdes *des, u8 remote_id)
+static void rkx120_dsi_tx_bridge_pre_enable(struct rk_serdes *des, struct rkx120_dsi_tx *dsi,
+					    u8 remote_id)
 {
-	struct rkx120_dsi_tx *dsi = &des->dsi_tx;
 	u32 val;
 
 	dsi_write(des, remote_id, DSI_PWR_UP, RESET);
@@ -1064,9 +1062,8 @@
 }
 
 static void
-rkx120_dsi_tx_bridge_enable(struct rk_serdes *des, u8 remote_id)
+rkx120_dsi_tx_bridge_enable(struct rk_serdes *des, struct rkx120_dsi_tx *dsi, u8 remote_id)
 {
-	struct rkx120_dsi_tx *dsi = &des->dsi_tx;
 	const struct videomode *vm = dsi->vm;
 	u32 val;
 
@@ -1117,15 +1114,16 @@
 			      struct rk_serdes_route *route,
 			      u8 remote_id)
 {
-	struct rkx120_dsi_tx *dsi = &des->dsi_tx;
+	struct rk_serdes_panel *sd_panel = container_of(route, struct rk_serdes_panel, route);
+	struct rkx120_dsi_tx *dsi = &sd_panel->dsi_tx;
 	u64 rate;
 
 	dsi->vm = &route->vm;
 	rate = rkx120_dsi_tx_get_lane_rate(dsi);
 
-	rkx120_combtxphy_set_mode(des, COMBTX_PHY_MODE_VIDEO_MIPI);
-	rkx120_combtxphy_set_rate(des, rate);
-	lane_kbps = rkx120_combtxphy_get_rate(des) / MSEC_PER_SEC;
+	rkx120_combtxphy_set_mode(dsi->combtxphy, COMBTX_PHY_MODE_VIDEO_MIPI);
+	rkx120_combtxphy_set_rate(dsi->combtxphy, rate);
+	lane_kbps = rkx120_combtxphy_get_rate(dsi->combtxphy) / MSEC_PER_SEC;
 
 	/* rst for dsi */
 	rkx120_dsi_tx_reset_control_assert(des, remote_id);
@@ -1133,12 +1131,11 @@
 	rkx120_dsi_tx_reset_control_deassert(des, remote_id);
 	usleep_range(20, 40);
 
-	rkx120_dsi_tx_bridge_pre_enable(des, remote_id);
-
+	rkx120_dsi_tx_bridge_pre_enable(des, dsi, remote_id);
 #ifdef DSI_READ_POWER_MODE
 	u8 mode;
 
-	rkx120_mipi_dsi_dcs_read(des, remote_id, MIPI_DCS_GET_POWER_MODE,
+	rkx120_mipi_dsi_dcs_read(des, dsi, remote_id, MIPI_DCS_GET_POWER_MODE,
 				 &mode, sizeof(mode));
 
 	dev_info(rkx120->dev, "dsi: mode: 0x%x\n", mode);
@@ -1149,17 +1146,18 @@
 			  struct rk_serdes_route *route,
 			  u8 remote_id)
 {
-	struct rkx120_dsi_tx *dsi = &des->dsi_tx;
+	struct rk_serdes_panel *sd_panel = container_of(route, struct rk_serdes_panel, route);
+	struct rkx120_dsi_tx *dsi = &sd_panel->dsi_tx;
 
 #ifdef DSI_READ_POWER_MODE
 	u8 mode;
 
-	rkx120_mipi_dsi_dcs_read(des, remote_id, MIPI_DCS_GET_POWER_MODE,
+	rkx120_mipi_dsi_dcs_read(des, dsi, remote_id, MIPI_DCS_GET_POWER_MODE,
 				 &mode, sizeof(mode));
 
 	dev_info(rkx120->dev, "dsi: mode: 0x%x\n", mode);
 #endif
-	rkx120_dsi_tx_bridge_enable(des, remote_id);
+	rkx120_dsi_tx_bridge_enable(des, dsi, remote_id);
 
 	dev_info(des->dev, "rkx120_dsi_tx final DSI-Link bandwidth: %llu Kbps x %d lanes\n",
 		 lane_kbps, dsi->lanes);
@@ -1169,7 +1167,10 @@
 				struct rk_serdes_route *route,
 				u8 remote_id)
 {
-	rkx120_combtxphy_power_off(des, remote_id);
+	struct rk_serdes_panel *sd_panel = container_of(route, struct rk_serdes_panel, route);
+	struct rkx120_dsi_tx *dsi = &sd_panel->dsi_tx;
+
+	rkx120_combtxphy_power_off(des, dsi->combtxphy, remote_id, 0);
 }
 
 void rkx120_dsi_tx_disable(struct rk_serdes *des, struct rk_serdes_route *route, u8 remote_id)
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx120_dsi_tx.h b/kernel/drivers/mfd/rkx110_x120/rkx120_dsi_tx.h
index a7e9528..1703766 100644
--- a/kernel/drivers/mfd/rkx110_x120/rkx120_dsi_tx.h
+++ b/kernel/drivers/mfd/rkx110_x120/rkx120_dsi_tx.h
@@ -10,7 +10,7 @@
 
 #include "rkx110_x120.h"
 
-int rkx120_dsi_tx_cmd_seq_xfer(struct rk_serdes *des, u8 remote_id,
+int rkx120_dsi_tx_cmd_seq_xfer(struct rk_serdes *des, struct rkx120_dsi_tx *dsi, u8 remote_id,
 			       struct panel_cmds *cmds);
 void rkx120_dsi_tx_pre_enable(struct rk_serdes *serdes,
 			      struct rk_serdes_route *route, u8 remote_id);
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx120_linkrx.c b/kernel/drivers/mfd/rkx110_x120/rkx120_linkrx.c
index 45d965b..29f338b 100644
--- a/kernel/drivers/mfd/rkx110_x120/rkx120_linkrx.c
+++ b/kernel/drivers/mfd/rkx110_x120/rkx120_linkrx.c
@@ -24,6 +24,7 @@
  #define TRAIN_CLK_SEL_I2S		UPDATE(2, 31, 30)
  #define DUAL_LVDS_CHANNEL_SWAP		BIT(29)
  #define VIDEO_FREQ_AUTO_EN		BIT(28)
+ #define ENGINE_CFG_MASK		GENMASK(23, 20)
  #define ENGINE1_2_LANE			BIT(23)
  #define ENGINE1_EN			BIT(22)
  #define ENGINE0_2_LANE			BIT(21)
@@ -36,6 +37,9 @@
  #define LANE0_DATA_WIDTH_16BIT		UPDATE(1, 13, 12)
  #define LANE0_DATA_WIDTH_24BIT		UPDATE(2, 13, 12)
  #define LANE0_DATA_WIDTH_32BIT		UPDATE(3, 13, 12)
+ #define LANE1_PKT_LOSE_NUM_CLR		BIT(9)
+ #define LANE0_PKT_LOSE_NUM_CLR		BIT(8)
+ #define LANE_CFG_MASK			GENMASK(5, 4)
  #define LANE0_EN			BIT(4)
  #define LANE1_EN			BIT(5)
  #define DES_EN				BIT(0)
@@ -77,6 +81,7 @@
  #define ORDER_FIFO0_WR_ID(x)		UPDATE(x, 2, 0)
 
 #define RKLINK_DES_SOURCE_CFG		LINK_REG(0x0024)
+ #define E1_STREAM_CFG_MASK		GENMASK(23, 20)
  #define E1_CAMERA_SRC_CSI		UPDATE(0, 23, 21)
  #define E1_CAMERA_SRC_LVDS		UPDATE(1, 23, 21)
  #define E1_CAMERA_SRC_DVP		UPDATE(2, 23, 21)
@@ -87,6 +92,7 @@
  #define E1_DISPLAY_SRC_RGB		UPDATE(5, 23, 21)
  #define E1_STREAM_CAMERA		UPDATE(0, 20, 20)
  #define E1_STREAM_DISPLAY		UPDATE(1, 20, 20)
+ #define E0_STREAM_CFG_MASK		GENMASK(19, 16)
  #define E0_CAMERA_SRC_CSI		UPDATE(0, 19, 17)
  #define E0_CAMERA_SRC_LVDS		UPDATE(1, 19, 17)
  #define E0_CAMERA_SRC_DVP		UPDATE(2, 19, 17)
@@ -97,6 +103,7 @@
  #define E0_DISPLAY_SRC_RGB		UPDATE(5, 19, 17)
  #define E0_STREAM_CAMERA		UPDATE(0, 16, 16)
  #define E0_STREAM_DISPLAY		UPDATE(1, 16, 16)
+ #define LANE_ID_CFG_MASK		GENMASK(7, 0)
  #define LANE1_ENGINE_ID(x)		UPDATE(x, 7, 6)
  #define LANE1_LANE_ID(x)		UPDATE(x, 5, 5)
  #define LNAE1_ID_SEL(x)		UPDATE(x, 4, 4)
@@ -104,6 +111,9 @@
  #define LANE0_LANE_ID(x)		UPDATE(x, 1, 1)
  #define LNAE0_ID_SEL(x)		UPDATE(x, 0, 0)
 
+#define DES_RKLINK_REC01_PKT_LENGTH	LINK_REG(0x0028)
+#define E1_REPKT_LENGTH(x)		UPDATE(x, 29, 16)
+#define E0_REPKT_LENGTH(x)		UPDATE(x, 13, 0)
 #define RKLINK_DES_REG01_ENGIN_DEL	0x0030
 #define E1_ENGINE_DELAY(x)		UPDATE(x, 31, 16)
 #define E0_ENGINE_DELAY(x)		UPDATE(x, 15, 0)
@@ -112,6 +122,42 @@
 #define E2_FIRST_FRAME_DEL		BIT(6)
 #define E1_FIRST_FRAME_DEL		BIT(5)
 #define E0_FIRST_FRAME_DEL		BIT(4)
+#define RKLINK_DES_FIFO_STATUS		LINK_REG(0x0084)
+ #define AUDIO_FIFO_UNDERRUN		BIT(29)
+ #define AUDIO_ORDER_UNDERRUN		BIT(28)
+ #define VIDEO_DATA_FIFO_UNDERRUN	BIT(27)
+ #define VIDEO_ORDER_UNDERRUN		BIT(26)
+ #define CMD_FIFO_UNDERRUN		BIT(25)
+ #define E1_ORDER_MIS			BIT(15)
+ #define E0_ORDER_MIS			BIT(14)
+ #define AUDIO_FIFO_OVERFLOW		BIT(13)
+ #define AUDIO_ORDER_OVERFLOW		BIT(12)
+ #define VIDEO_DATA_FIFO_OVERFLOW	GENMASK(11, 8)
+ #define VIDEO_ORDER_OVERFLOW		GENMASK(7, 4)
+ #define CMD_FIFO_OVERFLOW		GENMASK(3, 0)
+#define RKLINK_DES_SINK_IRQ_EN		LINK_REG(0x0088)
+ #define COMP_NOT_ENOUGH_IRQ_FLAG	BIT(26)
+ #define VIDEO_FM_IRQ_FLAG		BIT(25)
+ #define AUDIO_FM_IRQ_FLAG		BIT(24)
+ #define ORDER_MIS_IRQ_FLAG		BIT(23)
+ #define FIFO_UNDERRUN_IRQ_FLAG		BIT(22)
+ #define FIFO_OVERFLOW_IRQ_FLAG		BIT(21)
+ #define PKT_LOSE_IRQ_FLAG		BIT(20)
+ #define LAST_ERROR_IRQ_FLAG		BIT(19)
+ #define ECC2BIT_ERROR_IRQ_FLAG		BIT(18)
+ #define ECC1BIT_ERROR_IRQ_FLAG		BIT(17)
+ #define CRC_ERROR_IRQ_FLAG		BIT(16)
+ #define COMP_NOT_ENOUGH_IRQ_OUTPUT_EN	BIT(10)
+ #define VIDEO_FM_IRQ_OUTPUT_EN		BIT(9)
+ #define AUDIO_FM_IRQ_OUTPUT_EN		BIT(8)
+ #define ORDER_MIS_IRQ_OUTPUT_EN	BIT(7)
+ #define FIFO_UNDERRUN_IRQ_OUTPUT_EN	BIT(6)
+ #define FIFO_OVERFLOW_IRQ_OUTPUT_EN	BIT(5)
+ #define PKT_LOSE_IRQ_OUTPUT_EN		BIT(4)
+ #define LAST_ERROR_IRQ_OUTPUT_EN	BIT(3)
+ #define ECC2BIT_ERROR_IRQ_OUTPUT_EN	BIT(2)
+ #define ECC1BIT_ERROR_IRQ_OUTPUT_EN	BIT(1)
+ #define CRC_ERROR_IRQ_OUTPUT_EN	BIT(0)
 
 #define DES_RKLINK_STOP_CFG		LINK_REG(0x009C)
  #define STOP_AUDIO			BIT(4)
@@ -144,6 +190,7 @@
 #define PCS_REG24(id)			PCS_REG(id, 0x24)
 #define PCS_REG28(id)			PCS_REG(id, 0x28)
 #define PCS_REG30(id)			PCS_REG(id, 0x30)
+ #define DES_PCS_INI_EN(x)		HIWORD_UPDATE(x, GENMASK(15, 0), 0)
 #define PCS_REG34(id)			PCS_REG(id, 0x34)
 #define PCS_REG40(id)			PCS_REG(id, 0x40)
 
@@ -222,6 +269,19 @@
 
 #define DES_PMA_LOAD0E(id)		PMA_REG(id, 0x48)
 #define DES_PMA_REG100(id)		PMA_REG(id, 0x100)
+
+#define DES_PMA_IRQ_EN(id)		PMA_REG(id, 0xF0)
+ #define FORCE_INITIAL_IRQ_EN		HIWORD_UPDATE(1, BIT(6), 6)
+ #define RX_RDY_NEG_IRQ_EN		HIWORD_UPDATE(1, BIT(5), 5)
+ #define RX_LOS_IRQ_EN			HIWORD_UPDATE(1, BIT(4), 4)
+ #define RX_RDY_TIMEOUT_IRQ_EN		HIWORD_UPDATE(1, BIT(2), 2)
+ #define PLL_LOCK_TIMEOUT_IRQ_EN	HIWORD_UPDATE(1, BIT(0), 0)
+#define DES_PMA_IRQ_STATUS(id)		PMA_REG(id, 0xF4)
+ #define FORCE_INITIAL_IRQ_STATUS	BIT(6)
+ #define RX_RDY_NEG_IRQ_STATUS		BIT(5)
+ #define RX_LOS_IRQ_STATUS		BIT(4)
+ #define RX_RDY_TIMEOUT_IRQ_STATUS	BIT(2)
+ #define PLL_LOCK_TIMEOUT_IRQ_STATUS	BIT(0)
 
 static const struct rk_serdes_pt des_pt[] = {
 	{
@@ -409,9 +469,9 @@
 	},
 };
 
-static int rk_des_get_stream_source(struct rk_serdes_route *route, u32 port, u8 engine_id)
+static int rk_des_get_stream_source(u32 stream_type, u32 port, u8 engine_id)
 {
-	if (route->stream_type == STREAM_DISPLAY) {
+	if (stream_type == STREAM_DISPLAY) {
 		if (port & RK_SERDES_RGB_TX)
 			return engine_id ? E1_DISPLAY_SRC_RGB : E0_DISPLAY_SRC_RGB;
 		else if (port & RK_SERDES_LVDS_TX0)
@@ -472,139 +532,267 @@
 			      E1_FIRST_FRAME_DEL | E0_FIRST_FRAME_DEL);
 }
 
-static int rk120_link_rx_cfg(struct rk_serdes *serdes, struct rk_serdes_route *route, u8 remote_id)
+static int rk120_linkrx_des_enable(struct rk_serdes *serdes, u8 dev_id, bool enable)
 {
-	struct hwclk *hwclk = serdes->chip[remote_id].hwclk;
-	struct i2c_client *client;
-	u32 stream_type;
-	u32 rx_src;
-	u32 ctrl_val, mask, val;
-	u32 lane0_dsource_id, lane1_dsource_id;
-	bool is_rx_dual_lanes;
-	bool is_rx_dual_channels;
+	struct i2c_client *client = serdes->chip[dev_id].client;
 
-	if (route->stream_type == STREAM_DISPLAY) {
-		client = serdes->chip[remote_id].client;
-		stream_type = E0_STREAM_DISPLAY;
+	serdes->i2c_update_bits(client, RKLINK_DES_LANE_ENGINE_CFG, DES_EN, enable ? DES_EN : 0);
+
+	return 0;
+}
+
+static int rk120_linkrx_video_fm_enable(struct rk_serdes *serdes, u8 dev_id, bool enable)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+
+	serdes->i2c_update_bits(client, RKLINK_DES_LANE_ENGINE_CFG, VIDEO_FREQ_AUTO_EN,
+				enable ? VIDEO_FREQ_AUTO_EN : 0);
+
+	return 0;
+}
+
+static int rk120_linkrx_engine_lane_enable(struct rk_serdes *serdes, u8 dev_id,
+					   bool dual_channels, bool dual_lanes)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 val = 0;
+
+	/*
+	 * config engine and lane as fallow:
+	 * 1.linkrx receive 1 channel data in 1 lane, enable engine0 and engine0 use 1 lane.
+	 * 2.linkrx receive 1 channel data in 2 lane, enable engine0 and engine0 user 2 lanes.
+	 * 3.linkrx receive 2 channel data in 1 lane, enable engine0, enagine1. engine0 use
+	 *   1 lane, engine1 use 1 lane.
+	 * 4.linkrx receive 2 channel data in 2 lane, enable engine0, enagine1. engine0 use
+	 *   1 lane, engine1 use 1 lane.
+	 */
+	if (dual_channels) {
+		val |= ENGINE0_EN | ENGINE1_EN;
 	} else {
-		client = serdes->chip[DEVICE_LOCAL].client;
-		stream_type = E0_STREAM_CAMERA;
+		val |= ENGINE0_EN;
+		if (dual_lanes)
+			val |= ENGINE0_2_LANE;
 	}
 
-	is_rx_dual_lanes = (serdes->route_flag & ROUTE_MULTI_LANE) &&
-			   !(serdes->route_flag & ROUTE_MULTI_REMOTE);
-	is_rx_dual_channels = (serdes->route_flag & ROUTE_MULTI_CHANNEL) &&
-			       !(serdes->route_flag & ROUTE_MULTI_REMOTE);
+	serdes->i2c_update_bits(client, RKLINK_DES_LANE_ENGINE_CFG, ENGINE_CFG_MASK, val);
 
-	serdes->i2c_read_reg(client, RKLINK_DES_LANE_ENGINE_CFG, &ctrl_val);
+	return 0;
+}
 
-	ctrl_val &= ~LANE1_EN;
-	ctrl_val |= LANE0_EN;
-	ctrl_val |= ENGINE0_EN;
-	if (is_rx_dual_lanes) {
-		ctrl_val |= LANE1_EN;
-		if (is_rx_dual_channels)
-			ctrl_val |= ENGINE1_EN;
-		else
-			ctrl_val |= ENGINE0_2_LANE;
-	} else {
-		if (is_rx_dual_channels)
-			ctrl_val |= ENGINE1_EN;
-	}
-	serdes->i2c_write_reg(client, RKLINK_DES_LANE_ENGINE_CFG, ctrl_val);
+static int rk120_linkrx_lane_enable(struct rk_serdes *serdes, u8 dev_id, u32 lanes)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 val;
 
-	mask = LANE0_ENGINE_CFG_MASK;
-	val = LANE0_ENGINE0;
-	if (is_rx_dual_lanes) {
-		if (is_rx_dual_channels) {
-			mask |= LANE1_ENGINE_CFG_MASK;
-			val |= LANE1_ENGINE1;
+	/*
+	 * when 1 lane connect to linkrx, enable lane0;
+	 * when 2 lane connect to linkrx, enable lane0 and lane1;
+	 */
+
+	if (lanes == 1)
+		val = LANE0_EN;
+	else if (lanes == 2)
+		val = LANE0_EN | LANE1_EN;
+	else
+		val = 0;
+
+	serdes->i2c_update_bits(client, RKLINK_DES_LANE_ENGINE_CFG, LANE_CFG_MASK, val);
+
+	return 0;
+}
+
+static int rk120_linkrx_lane_engine_dst_cfg(struct rk_serdes *serdes, u8 dev_id,
+					     bool dual_channels, bool dual_lanes)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 mask, val;
+
+	/*
+	 * config lane dst engine as fallow:
+	 * 1. 1 channel 1 lane: lane0 data send to engine0
+	 * 2. 1 channel 2 lane: lane0 data send to engine0, lane1 data send to engine0
+	 * 3. 2 channel 1 lane: lane0 data send to engine0, lane0 data send to engine1
+	 * 4. 2 channel 2 lane: lane0 data send to engine0, lane1 data send to engine1
+	 */
+	if (dual_channels) {
+		if (dual_lanes) {
+			mask = LANE0_ENGINE_CFG_MASK | LANE1_ENGINE_CFG_MASK;
+			val = LANE0_ENGINE0 | LANE1_ENGINE1;
 		} else {
-			mask |= LANE1_ENGINE_CFG_MASK;
-			val |= LANE1_ENGINE0;
+			mask = LANE0_ENGINE_CFG_MASK | LANE1_ENGINE_CFG_MASK;
+			val = LANE0_ENGINE0 | LANE0_ENGINE1;
 		}
 	} else {
-		if (is_rx_dual_channels)
-			val |= LANE0_ENGINE1;
-	}
 
+		if (dual_lanes) {
+			mask = LANE0_ENGINE_CFG_MASK | LANE1_ENGINE_CFG_MASK;
+			val = LANE0_ENGINE0 | LANE1_ENGINE0;
+		} else {
+			mask = LANE0_ENGINE_CFG_MASK | LANE1_ENGINE_CFG_MASK;
+			val = LANE0_ENGINE0 | LANE1_ENGINE1;
+		}
+	}
 	serdes->i2c_update_bits(client, RKLINK_DES_LANE_ENGINE_DST, mask, val);
 
-	serdes->i2c_read_reg(client, RKLINK_DES_SOURCE_CFG, &val);
+	return 0;
+}
 
-	val &= ~(LANE0_ENGINE_ID(1) | LANE0_LANE_ID(1) | LANE1_ENGINE_ID(1) |
-		 LANE1_LANE_ID(1) | LNAE0_ID_SEL(1) | LNAE1_ID_SEL(1));
+static int rk120_linkrx_config_pkt_length(struct rk_serdes *serdes, u8 dev_id, u32 length)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
 
-	if (is_rx_dual_lanes) {
-		if (is_rx_dual_channels) {
-			val |= LANE0_ENGINE_ID(0);
-			val |= LANE0_LANE_ID(0);
-			val |= LNAE0_ID_SEL(1);
-			val |= LANE1_ENGINE_ID(1);
-			val |= LANE1_LANE_ID(0);
-			val |= LNAE1_ID_SEL(1);
-			stream_type |= E1_STREAM_DISPLAY;
+	serdes->i2c_write_reg(client, DES_RKLINK_REC01_PKT_LENGTH, E0_REPKT_LENGTH(length) |
+			      E1_REPKT_LENGTH(length));
+
+	return 0;
+}
+
+static int rk120_linkrx_lane_id_cfg(struct rk_serdes *serdes, u8 dev_id,
+				     bool dual_channels, bool dual_lanes)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 val;
+
+	if (dual_channels) {
+		if (dual_lanes) {
+			val = LANE0_ENGINE_ID(0) | LANE0_LANE_ID(0) | LNAE0_ID_SEL(1) |
+			      LANE1_ENGINE_ID(1) | LANE1_LANE_ID(0) | LNAE1_ID_SEL(1);
 		} else {
-			val |= LANE0_ENGINE_ID(0);
-			val |= LANE0_LANE_ID(0);
-			val |= LNAE0_ID_SEL(1);
-			val |= LANE1_ENGINE_ID(0);
-			val |= LANE1_LANE_ID(1);
-			val |= LNAE0_ID_SEL(1);
+			val = LANE0_ENGINE_ID(0) | LANE0_LANE_ID(0) | LANE1_ENGINE_ID(1) |
+			      LANE1_LANE_ID(0);
 		}
 	} else {
-		if (is_rx_dual_channels) {
-			val |= LANE0_ENGINE_ID(0);
-			val |= LANE0_LANE_ID(0);
-			val |= LANE1_ENGINE_ID(1);
-			val |= LANE1_LANE_ID(0);
-			stream_type |= E1_STREAM_DISPLAY;
+		if (dual_lanes) {
+			val = LANE0_ENGINE_ID(0) | LANE0_LANE_ID(0) | LNAE0_ID_SEL(1) |
+			      LANE1_ENGINE_ID(0) | LANE1_LANE_ID(1) | LNAE1_ID_SEL(1);
 		} else {
-			val |= LNAE0_ID_SEL(1);
+			val = LNAE0_ID_SEL(1);
 		}
 	}
-	val |= stream_type;
-	if (remote_id == DEVICE_REMOTE0)
-		rx_src = rk_des_get_stream_source(route, route->remote0_port0, 0);
-	else
-		rx_src = rk_des_get_stream_source(route, route->remote1_port0, 0);
-	val |= rx_src;
-	if (is_rx_dual_channels) {
-		rx_src = rk_des_get_stream_source(route, route->remote0_port1, 1);
-		val |= rx_src;
-	}
-	serdes->i2c_write_reg(client, RKLINK_DES_SOURCE_CFG, val);
 
-	if (is_rx_dual_lanes || is_rx_dual_channels) {
-		mask = DATA_FIFO0_WR_ID_MASK | DATA_FIFO1_WR_ID_MASK | DATA_FIFO2_WR_ID_MASK |
-			DATA_FIFO3_WR_ID_MASK;
-		mask |= DATA_FIFO0_RD_ID_MASK | DATA_FIFO1_RD_ID_MASK | DATA_FIFO2_RD_ID_MASK |
-			DATA_FIFO3_RD_ID_MASK;
-		if (is_rx_dual_channels) {
-			lane0_dsource_id = (0 << 1) | 0;
-			lane1_dsource_id = (1 << 1) | 0;
-		} else {
+	serdes->i2c_update_bits(client, RKLINK_DES_SOURCE_CFG, LANE_ID_CFG_MASK, val);
+
+	return 0;
+}
+
+static int rk120_linkrx_stream_type_cfg(struct rk_serdes *serdes, u32 stream_type,
+					 u8 dev_id, u32 port, u32 engine_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 val, mask, rx_src;
+
+	mask = engine_id ? E1_STREAM_CFG_MASK : E0_STREAM_CFG_MASK;
+	if (stream_type == STREAM_DISPLAY)
+		val =  engine_id ? E1_STREAM_DISPLAY : E0_STREAM_DISPLAY;
+	else
+		val =  engine_id ? E1_STREAM_CAMERA : E0_STREAM_CAMERA;
+
+	rx_src = rk_des_get_stream_source(stream_type, port, engine_id);
+	val |= rx_src;
+	serdes->i2c_update_bits(client, RKLINK_DES_SOURCE_CFG, mask, val);
+
+	return 0;
+}
+
+static int rk120_linkrx_data_and_order_id_cfg(struct rk_serdes *serdes, u8 dev_id,
+					       bool dual_channels, bool dual_lanes)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 lane0_dsource_id, lane1_dsource_id;
+	u32 data_id_mask;
+	u32 order_id_mask;
+	u32 val;
+
+	data_id_mask = DATA_FIFO0_WR_ID_MASK | DATA_FIFO1_WR_ID_MASK |
+		       DATA_FIFO2_WR_ID_MASK | DATA_FIFO3_WR_ID_MASK |
+		       DATA_FIFO0_RD_ID_MASK | DATA_FIFO1_RD_ID_MASK |
+		       DATA_FIFO2_RD_ID_MASK | DATA_FIFO3_RD_ID_MASK;
+	order_id_mask = ORDER_FIFO0_WR_ID_MASK | ORDER_FIFO1_WR_ID_MASK |
+			ORDER_FIFO0_RD_ID_MASK | ORDER_FIFO1_RD_ID_MASK;
+
+	if (dual_channels) {
+		lane0_dsource_id = (0 << 1) | 0;
+		lane1_dsource_id = (1 << 1) | 0;
+	} else {
+		if (dual_lanes) {
 			lane0_dsource_id = (0 << 1) | 0;
 			lane1_dsource_id = (0 << 1) | 1;
+		} else {
+			lane0_dsource_id = (0 << 1) | 0;
+			lane1_dsource_id = (1 << 1) | 0;
 		}
-		val = DATA_FIFO0_WR_ID(lane0_dsource_id) | DATA_FIFO1_WR_ID(lane0_dsource_id);
-		val |= DATA_FIFO0_RD_ID(lane0_dsource_id) | DATA_FIFO1_RD_ID(lane0_dsource_id);
-
-		val |= DATA_FIFO2_WR_ID(lane1_dsource_id) | DATA_FIFO3_WR_ID(lane1_dsource_id);
-		val |= DATA_FIFO2_RD_ID(lane1_dsource_id) | DATA_FIFO3_RD_ID(lane1_dsource_id);
-
-		serdes->i2c_update_bits(client, RKLINK_DES_DATA_ID_CFG, mask, val);
-
-		mask = ORDER_FIFO0_WR_ID_MASK | ORDER_FIFO1_WR_ID_MASK |
-			ORDER_FIFO0_RD_ID_MASK | ORDER_FIFO1_RD_ID_MASK;
-		val = ORDER_FIFO0_WR_ID(lane0_dsource_id) | ORDER_FIFO1_WR_ID(lane1_dsource_id) |
-			ORDER_FIFO0_RD_ID(lane0_dsource_id) | ORDER_FIFO1_RD_ID(lane1_dsource_id);
-
-		serdes->i2c_update_bits(client, RKLINK_DES_ORDER_ID_CFG, mask, val);
 	}
 
-	ctrl_val |= DES_EN;
-	serdes->i2c_write_reg(client, RKLINK_DES_LANE_ENGINE_CFG, ctrl_val);
+	val = DATA_FIFO0_WR_ID(lane0_dsource_id) | DATA_FIFO1_WR_ID(lane0_dsource_id) |
+	      DATA_FIFO0_RD_ID(lane0_dsource_id) | DATA_FIFO1_RD_ID(lane0_dsource_id) |
+	      DATA_FIFO2_WR_ID(lane1_dsource_id) | DATA_FIFO3_WR_ID(lane1_dsource_id) |
+	      DATA_FIFO2_RD_ID(lane1_dsource_id) | DATA_FIFO3_RD_ID(lane1_dsource_id);
+	serdes->i2c_update_bits(client, RKLINK_DES_DATA_ID_CFG, data_id_mask, val);
+
+	val = ORDER_FIFO0_WR_ID(lane0_dsource_id) | ORDER_FIFO1_WR_ID(lane1_dsource_id) |
+	      ORDER_FIFO0_RD_ID(lane0_dsource_id) | ORDER_FIFO1_RD_ID(lane1_dsource_id);
+
+	serdes->i2c_update_bits(client, RKLINK_DES_ORDER_ID_CFG, order_id_mask, val);
+
+	return 0;
+}
+
+static int rk120_display_linkrx_cfg(struct rk_serdes *serdes,
+				    struct rk_serdes_route *route, u8 dev_id)
+{
+	struct hwclk *hwclk = serdes->chip[dev_id].hwclk;
+	bool is_rx_dual_lanes = false;
+	bool is_rx_dual_channels = false;
+
+	if (serdes->route_nr == 1) {
+		is_rx_dual_lanes = (serdes->lane_nr == 2) &&
+				   !(route->route_flag & ROUTE_MULTI_REMOTE);
+		is_rx_dual_channels = (route->route_flag & ROUTE_MULTI_CHANNEL) &&
+				       !(route->route_flag & ROUTE_MULTI_REMOTE);
+	} else {
+		is_rx_dual_lanes = (serdes->lane_nr == 2) && (serdes->remote_nr == 1);
+		is_rx_dual_channels = (serdes->channel_nr == 2) && (serdes->remote_nr == 1);
+	}
+
+	rk120_linkrx_video_fm_enable(serdes, dev_id, true);
+	rk120_linkrx_engine_lane_enable(serdes, dev_id, is_rx_dual_channels, is_rx_dual_lanes);
+	rk120_linkrx_lane_enable(serdes, dev_id, is_rx_dual_lanes ? 2 : 1);
+
+	rk120_linkrx_lane_engine_dst_cfg(serdes, dev_id, is_rx_dual_channels, is_rx_dual_lanes);
+	rk120_linkrx_lane_id_cfg(serdes, dev_id, is_rx_dual_channels, is_rx_dual_lanes);
+	if (route->local_port0) {
+		if (dev_id == DEVICE_REMOTE0) {
+			rk120_linkrx_stream_type_cfg(serdes, route->stream_type, dev_id,
+						     route->remote0_port0, 0);
+			if (is_rx_dual_channels)
+				rk120_linkrx_stream_type_cfg(serdes, route->stream_type, dev_id,
+						     route->remote0_port1, 1);
+		} else {
+			rk120_linkrx_stream_type_cfg(serdes, route->stream_type, dev_id,
+						     route->remote1_port0, 0);
+		}
+	} else {
+		rk120_linkrx_stream_type_cfg(serdes, route->stream_type, dev_id,
+					     route->remote1_port0, 0);
+	}
+
+	rk120_linkrx_data_and_order_id_cfg(serdes, dev_id, is_rx_dual_channels,
+					    is_rx_dual_lanes);
+	if (serdes->version == SERDES_V1) {
+		/*
+		 * The serdes v1 have a bug when enable video suspend function, which
+		 * is used to enhance the i2c frequency. A workaround ways to do it is
+		 * reducing the video packet length:
+		 * length = ((hactive x 24 / 32 / 16) + 15) / 16 * 16
+		 */
+		u32 length;
+
+		length = route->vm.hactive * 24 / 32 / 16;
+		length = (length + 15) / 16 * 16;
+		rk120_linkrx_config_pkt_length(serdes, dev_id, length);
+	}
+
+	rk120_linkrx_des_enable(serdes, dev_id, true);
 
 	hwclk_set_rate(hwclk, RKX120_CPS_E0_CLK_RKLINK_RX_PRE, route->vm.pixelclock);
 	dev_info(serdes->dev, "RKX120_CPS_E0_CLK_RKLINK_RX_PRE:%d\n",
@@ -616,17 +804,17 @@
 	}
 
 	if (route->remote0_port0 == RK_SERDES_RGB_TX || route->remote1_port0 == RK_SERDES_RGB_TX)
-		rk_serdes_link_rx_rgb_enable(serdes, route, remote_id);
+		rk_serdes_link_rx_rgb_enable(serdes, route, dev_id);
 
 	if (route->remote0_port0 == RK_SERDES_LVDS_TX0 ||
 	    route->remote1_port0 == RK_SERDES_LVDS_TX0 ||
 	    route->remote0_port0 == RK_SERDES_LVDS_TX1 ||
 	    route->remote1_port0 == RK_SERDES_LVDS_TX1 ||
 	    route->remote0_port0 == RK_SERDES_DUAL_LVDS_TX)
-		rk_serdes_link_rx_lvds_enable(serdes, route, remote_id);
+		rk_serdes_link_rx_lvds_enable(serdes, route, dev_id);
 
 	if (route->remote0_port0 == RK_SERDES_DSI_TX0 || route->remote1_port0 == RK_SERDES_DSI_TX0)
-		rk_serdes_link_rx_dsi_enable(serdes, route, remote_id);
+		rk_serdes_link_rx_dsi_enable(serdes, route, dev_id);
 
 	return 0;
 }
@@ -643,17 +831,18 @@
 	return 0;
 }
 
-int rkx120_linkrx_enable(struct rk_serdes *serdes, struct rk_serdes_route *route, u8 remote_id)
+int rkx120_display_linkrx_enable(struct rk_serdes *serdes,
+				 struct rk_serdes_route *route, u8 dev_id)
 {
-	rk120_link_rx_cfg(serdes, route, remote_id);
+	rk120_display_linkrx_cfg(serdes, route, dev_id);
 
-	rk120_des_pcs_cfg(serdes, route, remote_id, 0);
-	rk120_des_pma_cfg(serdes, route, remote_id, 0);
-	if ((serdes->route_flag & ROUTE_MULTI_LANE) &&
-	    !(serdes->route_flag & ROUTE_MULTI_REMOTE)) {
-		rk120_des_pcs_cfg(serdes, route, remote_id, 1);
-		rk120_des_pma_cfg(serdes, route, remote_id, 1);
+	rk120_des_pcs_cfg(serdes, route, dev_id, 0);
+	rk120_des_pma_cfg(serdes, route, dev_id, 0);
+	if ((serdes->lane_nr == 2) && (serdes->remote_nr == 1)) {
+		rk120_des_pcs_cfg(serdes, route, dev_id, 1);
+		rk120_des_pma_cfg(serdes, route, dev_id, 1);
 	}
+
 
 	return 0;
 }
@@ -691,7 +880,7 @@
 	}
 }
 
-void rkx120_linkrx_wait_link_ready(struct rk_serdes *serdes, u8 id)
+int rkx120_linkrx_wait_link_ready(struct rk_serdes *serdes, u8 id)
 {
 	struct i2c_client *client = serdes->chip[DEVICE_LOCAL].client;
 	u32 val;
@@ -711,6 +900,8 @@
 		dev_err(&client->dev, "wait link ready timeout: 0x%08x\n", val);
 	else
 		dev_info(&client->dev, "link success: 0x%08x\n", val);
+
+	return ret;
 }
 
 static void rkx120_pma_link_config(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
@@ -795,3 +986,354 @@
 
 	serdes->i2c_update_bits(client, DES_GRF_SOC_CON4, mask, val);
 }
+
+
+static void rkx120_linkrx_irq_enable(struct rk_serdes *serdes, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+
+	serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, DES_IRQ_LINK_EN);
+
+	serdes->i2c_write_reg(client, RKLINK_DES_SINK_IRQ_EN, FIFO_UNDERRUN_IRQ_OUTPUT_EN |
+			      FIFO_OVERFLOW_IRQ_OUTPUT_EN);
+}
+
+static void rkx120_linkrx_irq_disable(struct rk_serdes *serdes, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 val = 0;
+
+	serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, DES_IRQ_LINK_DIS);
+
+	serdes->i2c_read_reg(client, RKLINK_DES_SINK_IRQ_EN, &val);
+	val &= ~(FIFO_UNDERRUN_IRQ_OUTPUT_EN | FIFO_OVERFLOW_IRQ_OUTPUT_EN);
+	serdes->i2c_write_reg(client, RKLINK_DES_SINK_IRQ_EN, val);
+}
+
+static void rkx120_linkrx_fifo_handler(struct rk_serdes *serdes, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 value;
+
+	serdes->i2c_read_reg(client, RKLINK_DES_FIFO_STATUS, &value);
+	dev_err(serdes->dev, "des rklink fifo status:0x%x\n", value);
+
+	if (value & AUDIO_FIFO_UNDERRUN)
+		dev_err(serdes->dev, "linkrx audio fifo underrun\n");
+	if (value & AUDIO_ORDER_UNDERRUN)
+		dev_err(serdes->dev, "linkrx audio order underrun\n");
+	if (value & VIDEO_DATA_FIFO_UNDERRUN)
+		dev_err(serdes->dev, "linkrx video data fifo underrun\n");
+	if (value & VIDEO_ORDER_UNDERRUN)
+		dev_err(serdes->dev, "linkrx video order underrun\n");
+	if (value & CMD_FIFO_UNDERRUN)
+		dev_err(serdes->dev, "linkrx cmd fifo underrun\n");
+	if (value & E1_ORDER_MIS)
+		dev_err(serdes->dev, "linkrx e1 order miss\n");
+	if (value & E0_ORDER_MIS)
+		dev_err(serdes->dev, "linkrx e0 order miss\n");
+	if (value & AUDIO_FIFO_OVERFLOW)
+		dev_err(serdes->dev, "linkrx audio fifo overflow\n");
+	if (value & AUDIO_ORDER_OVERFLOW)
+		dev_err(serdes->dev, "linkrx audio order overflow\n");
+	if (value & VIDEO_DATA_FIFO_OVERFLOW)
+		dev_err(serdes->dev, "linkrx video data fifo overflow\n");
+	if (value & VIDEO_ORDER_OVERFLOW)
+		dev_err(serdes->dev, "linkrx video order overflow\n");
+	if (value & CMD_FIFO_OVERFLOW)
+		dev_err(serdes->dev, "linkrx cmd fifo overflow\n");
+
+	serdes->i2c_write_reg(client, RKLINK_DES_FIFO_STATUS, value);
+}
+
+static void rkx120_linkrx_irq_handler(struct rk_serdes *serdes, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 flag, value;
+	int i = 0;
+
+	serdes->i2c_read_reg(client, RKLINK_DES_SINK_IRQ_EN, &flag);
+	flag &= COMP_NOT_ENOUGH_IRQ_FLAG | VIDEO_FM_IRQ_FLAG | AUDIO_FM_IRQ_FLAG |
+		ORDER_MIS_IRQ_FLAG | FIFO_UNDERRUN_IRQ_FLAG | FIFO_OVERFLOW_IRQ_FLAG |
+		PKT_LOSE_IRQ_FLAG | LAST_ERROR_IRQ_FLAG | ECC2BIT_ERROR_IRQ_FLAG |
+		ECC1BIT_ERROR_IRQ_FLAG | CRC_ERROR_IRQ_FLAG;
+	dev_info(serdes->dev, "linkrx irq flag:0x%08x\n", flag);
+	while (flag) {
+		switch (flag & BIT(i)) {
+		case COMP_NOT_ENOUGH_IRQ_FLAG:
+			break;
+		case VIDEO_FM_IRQ_FLAG:
+			break;
+		case AUDIO_FM_IRQ_FLAG:
+			break;
+		case ORDER_MIS_IRQ_FLAG:
+		case FIFO_UNDERRUN_IRQ_FLAG:
+		case FIFO_OVERFLOW_IRQ_FLAG:
+			flag &= ~(ORDER_MIS_IRQ_FLAG | FIFO_UNDERRUN_IRQ_FLAG |
+				FIFO_OVERFLOW_IRQ_FLAG);
+			rkx120_linkrx_fifo_handler(serdes, dev_id);
+			break;
+		case PKT_LOSE_IRQ_FLAG:
+			/* clear pkt lost irq flag */
+			serdes->i2c_read_reg(client, RKLINK_DES_LANE_ENGINE_CFG, &value);
+			value |= LANE0_PKT_LOSE_NUM_CLR | LANE1_PKT_LOSE_NUM_CLR;
+			serdes->i2c_write_reg(client, RKLINK_DES_LANE_ENGINE_CFG, value);
+			break;
+		case LAST_ERROR_IRQ_FLAG:
+		case ECC2BIT_ERROR_IRQ_FLAG:
+		case ECC1BIT_ERROR_IRQ_FLAG:
+		case CRC_ERROR_IRQ_FLAG:
+			flag &= ~(LAST_ERROR_IRQ_FLAG | ECC2BIT_ERROR_IRQ_FLAG |
+				ECC1BIT_ERROR_IRQ_FLAG | CRC_ERROR_IRQ_FLAG);
+			serdes->i2c_read_reg(client, RKLINK_DES_SINK_IRQ_EN, &value);
+			dev_info(serdes->dev, "linkrx ecc crc result:0x%08x\n", value);
+			/* clear ecc crc irq flag */
+			serdes->i2c_write_reg(client, RKLINK_DES_SINK_IRQ_EN, value);
+			break;
+		default:
+			break;
+		}
+		flag &= ~BIT(i);
+		i++;
+	}
+}
+static void rkx120_pcs_irq_enable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 val = 0;
+
+	val = pcs_id ? DES_IRQ_PCS1_EN : DES_IRQ_PCS0_EN;
+	serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, val);
+
+	serdes->i2c_write_reg(client, PCS_REG30(pcs_id), DES_PCS_INI_EN(0xffff));
+}
+
+static void rkx120_pcs_irq_disable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 val = 0;
+
+	val = pcs_id ? DES_IRQ_PCS1_DIS : DES_IRQ_PCS0_DIS;
+	serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, val);
+
+	serdes->i2c_write_reg(client, PCS_REG30(pcs_id), DES_PCS_INI_EN(0));
+}
+
+static void rkx120_pcs_irq_handler(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 value;
+
+	serdes->i2c_read_reg(client, PCS_REG20(pcs_id), &value);
+	dev_info(serdes->dev, "des pcs%d fatal status:0x%08x\n", pcs_id, value);
+
+	/* clear fatal status */
+	serdes->i2c_write_reg(client, PCS_REG10(pcs_id), 0xffffffff);
+	serdes->i2c_write_reg(client, PCS_REG10(pcs_id), 0xffff0000);
+}
+
+static void rkx120_pma_irq_enable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 val = 0;
+
+	val = pcs_id ? DES_IRQ_PMA_ADAPT1_EN : DES_IRQ_PMA_ADAPT0_EN;
+	serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, val);
+
+	serdes->i2c_write_reg(client, DES_PMA_IRQ_EN(pcs_id), FORCE_INITIAL_IRQ_EN |
+			      RX_RDY_NEG_IRQ_EN | RX_LOS_IRQ_EN | RX_RDY_TIMEOUT_IRQ_EN |
+			      PLL_LOCK_TIMEOUT_IRQ_EN);
+}
+
+static void rkx120_pma_irq_disable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 val = 0;
+
+	val = pcs_id ? DES_IRQ_PMA_ADAPT1_DIS : DES_IRQ_PMA_ADAPT0_DIS;
+	serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, val);
+
+	serdes->i2c_write_reg(client, DES_PMA_IRQ_EN(pcs_id), 0);
+}
+
+static void rkx120_pma_irq_handler(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 value;
+
+	serdes->i2c_read_reg(client, DES_PMA_IRQ_STATUS(pcs_id), &value);
+	dev_info(serdes->dev, "des pma%d irq status:0x%08x\n", pcs_id, value);
+
+	if (value & FORCE_INITIAL_IRQ_STATUS)
+		dev_info(serdes->dev, "des pma trig force initial pulse status\n");
+	else if (value & RX_RDY_NEG_IRQ_STATUS)
+		dev_info(serdes->dev, "des pma trig rx rdy neg status\n");
+	else if (value & RX_LOS_IRQ_STATUS)
+		dev_info(serdes->dev, "des pma trig rx los status\n");
+	else if (value & RX_RDY_TIMEOUT_IRQ_STATUS)
+		dev_info(serdes->dev, "des pma trig rx rdy timeout status\n");
+	else if (value & PLL_LOCK_TIMEOUT_IRQ_STATUS)
+		dev_info(serdes->dev, "des pma trig pll lock timeout status\n");
+
+	/* clear pma irq status */
+	serdes->i2c_write_reg(client, DES_PMA_IRQ_STATUS(pcs_id), value);
+}
+
+static void rkx120_remote_irq_enable(struct rk_serdes *serdes, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+
+	if (serdes->stream_type == STREAM_CAMERA) {
+		serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, DES_IRQ_REMOTE_EN);
+		rkx110_irq_enable(serdes, DEVICE_REMOTE0);
+	}
+}
+
+static void rkx120_remote_irq_disable(struct rk_serdes *serdes, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+
+	if (serdes->stream_type == STREAM_CAMERA) {
+		serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, DES_IRQ_REMOTE_DIS);
+		rkx110_irq_disable(serdes, DEVICE_REMOTE0);
+	}
+}
+
+static void rkx120_remote_irq_handler(struct rk_serdes *serdes, u8 dev_id)
+{
+	if (serdes->stream_type == STREAM_CAMERA)
+		rkx110_irq_handler(serdes, DEVICE_REMOTE0);
+}
+
+void rkx120_irq_enable(struct rk_serdes *serdes, u8 dev_id)
+{
+	/* enable pcs irq */
+	rkx120_pcs_irq_enable(serdes, 0, dev_id);
+
+	/* enable efuse irq */
+
+	/* enable gpio irq */
+
+	/* enable csitx irq */
+
+	/* enable mipi dsi host irq */
+
+	/* enable pma adapt irq */
+	rkx120_pma_irq_enable(serdes, 0, dev_id);
+
+	/* enable remote irq and other lane irq */
+	rkx120_remote_irq_enable(serdes, dev_id);
+
+	/* enable pwm irq */
+
+	/* enable dvp tx irq */
+
+	/* enable link irq */
+	rkx120_linkrx_irq_enable(serdes, dev_id);
+
+	/* enable ext irq */
+
+	/* enable ext irq */
+}
+
+void rkx120_irq_disable(struct rk_serdes *serdes, u8 dev_id)
+{
+	/* disable pcs irq */
+	rkx120_pcs_irq_disable(serdes, 0, dev_id);
+
+	/* disable efuse irq */
+
+	/* disable gpio irq */
+
+	/* disable csitx irq */
+
+	/* disable mipi dsi host irq */
+
+	/* disable pma adapt irq */
+	rkx120_pma_irq_disable(serdes, 0, dev_id);
+
+	/* disable remote irq */
+	rkx120_remote_irq_disable(serdes, dev_id);
+
+	/* disable pwm irq */
+
+	/* disable dvp tx irq */
+
+	/* disable link irq */
+	rkx120_linkrx_irq_disable(serdes, dev_id);
+
+	/* disable ext irq */
+}
+
+int rkx120_irq_handler(struct rk_serdes *serdes, u8 dev_id)
+{
+	struct i2c_client *client = serdes->chip[dev_id].client;
+	u32 status = 0;
+	u32 mask = 0;
+	u32 i = 0;
+
+	serdes->i2c_read_reg(client, DES_GRF_IRQ_EN, &mask);
+	serdes->i2c_read_reg(client, DES_GRF_IRQ_STATUS, &status);
+	dev_info(serdes->dev, "dev%d get the des irq status:0x%08x\n", dev_id, status);
+	status &= mask;
+
+	while (status) {
+		switch (status & BIT(i)) {
+		case DES_IRQ_PCS0:
+			rkx120_pcs_irq_handler(serdes, 0, dev_id);
+			break;
+		case DES_IRQ_PCS1:
+			rkx120_pcs_irq_handler(serdes, 1, dev_id);
+			break;
+		case DES_IRQ_EFUSE:
+			/* TBD */
+			break;
+		case DES_IRQ_GPIO0:
+			/* TBD */
+			break;
+		case DES_IRQ_GPIO1:
+			/* TBD */
+			break;
+		case DES_IRQ_CSITX0:
+			/* TBD */
+			break;
+		case DES_IRQ_CSITX1:
+			/* TBD */
+			break;
+		case DES_IRQ_MIPI_DSI_HOST:
+			/* TBD */
+			break;
+		case DES_IRQ_PMA_ADAPT0:
+			rkx120_pma_irq_handler(serdes, 0, dev_id);
+			break;
+		case DES_IRQ_PMA_ADAPT1:
+			rkx120_pma_irq_handler(serdes, 1, dev_id);
+			break;
+		case DES_IRQ_REMOTE:
+			rkx120_remote_irq_handler(serdes, dev_id);
+			break;
+		case DES_IRQ_PWM:
+			/* TBD */
+			break;
+		case DES_IRQ_DVP_TX:
+			/* TBD */
+			break;
+		case DES_IRQ_LINK:
+			rkx120_linkrx_irq_handler(serdes, dev_id);
+			break;
+		case DES_IRQ_EXT:
+			/* TBD */
+			break;
+		case DES_IRQ_OTHER_LANE:
+			/* TBD */
+			break;
+		default:
+			break;
+		}
+		status &= ~BIT(i);
+		i++;
+	}
+
+	return 0;
+}
+
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx120_pwm.c b/kernel/drivers/mfd/rkx110_x120/rkx120_pwm.c
new file mode 100644
index 0000000..47fbf8a
--- /dev/null
+++ b/kernel/drivers/mfd/rkx110_x120/rkx120_pwm.c
@@ -0,0 +1,393 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co. Ltd.
+ *
+ * Author: Damon Ding <damon.ding@rock-chips.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/time.h>
+
+#include "rkx110_x120.h"
+#include "rkx120_reg.h"
+
+/*
+ * regs for pwm v1-v3
+ */
+#define PWM_CTRL_TIMER_EN	(1 << 0)
+#define PWM_CTRL_OUTPUT_EN	(1 << 3)
+
+#define PWM_ENABLE		(1 << 0)
+#define PWM_MODE_SHIFT		1
+#define PWM_MODE_MASK		(0x3 << PWM_MODE_SHIFT)
+#define PWM_ONESHOT		(0 << PWM_MODE_SHIFT)
+#define PWM_CONTINUOUS		(1 << PWM_MODE_SHIFT)
+#define PWM_CAPTURE		(2 << PWM_MODE_SHIFT)
+#define PWM_DUTY_POSITIVE	(1 << 3)
+#define PWM_DUTY_NEGATIVE	(0 << 3)
+#define PWM_INACTIVE_NEGATIVE	(0 << 4)
+#define PWM_INACTIVE_POSITIVE	(1 << 4)
+#define PWM_POLARITY_MASK	(PWM_DUTY_POSITIVE | PWM_INACTIVE_POSITIVE)
+#define PWM_OUTPUT_LEFT		(0 << 5)
+#define PWM_OUTPUT_CENTER	(1 << 5)
+#define PWM_LOCK_EN		(1 << 6)
+#define PWM_LP_DISABLE		(0 << 8)
+#define PWM_CLK_SEL_SHIFT	9
+#define PWM_CLK_SEL_MASK	(1 << PWM_CLK_SEL_SHIFT)
+#define PWM_SEL_NO_SCALED_CLOCK	(0 << PWM_CLK_SEL_SHIFT)
+#define PWM_SEL_SCALED_CLOCK	(1 << PWM_CLK_SEL_SHIFT)
+#define PWM_PRESCELE_SHIFT	12
+#define PWM_PRESCALE_MASK	(0x3 << PWM_PRESCELE_SHIFT)
+#define PWM_SCALE_SHIFT		16
+#define PWM_SCALE_MASK		(0xff << PWM_SCALE_SHIFT)
+
+#define PWM_ONESHOT_COUNT_SHIFT	24
+#define PWM_ONESHOT_COUNT_MASK	(0xff << PWM_ONESHOT_COUNT_SHIFT)
+
+#define PWM_REG_INTSTS(n)	((3 - (n)) * 0x10 + 0x10)
+#define PWM_REG_INT_EN(n)	((3 - (n)) * 0x10 + 0x14)
+
+#define PWM_CH_INT(n)		BIT(n)
+
+#define PWM_DCLK_RATE		24000000
+
+struct rkx120_pwm_chip {
+	struct pwm_chip chip;
+	struct rk_serdes *serdes;
+	const struct rkx120_pwm_data *data;
+	unsigned long clk_rate;
+	bool center_aligned;
+	bool oneshot_en;
+	u32 remote_id;
+	u32 channel_id;
+};
+
+struct rkx120_pwm_regs {
+	unsigned long base;
+	unsigned long duty;
+	unsigned long period;
+	unsigned long cntr;
+	unsigned long ctrl;
+};
+
+struct rkx120_pwm_data {
+	struct rkx120_pwm_regs regs;
+	unsigned int prescaler;
+	bool supports_polarity;
+	bool supports_lock;
+	u32 enable_conf;
+	u32 enable_conf_mask;
+	u32 oneshot_cnt_max;
+};
+
+static inline int rkx120_pwm_write(struct rk_serdes *serdes, u8 remote_id, u32 reg, u32 val)
+{
+	struct i2c_client *client = serdes->chip[remote_id].client;
+
+	return serdes->i2c_write_reg(client, reg, val);
+}
+
+static inline int rkx120_pwm_read(struct rk_serdes *serdes, u8 remote_id, u32 reg, u32 *val)
+{
+	struct i2c_client *client = serdes->chip[remote_id].client;
+
+	return serdes->i2c_read_reg(client, reg, val);
+}
+
+static inline struct rkx120_pwm_chip *to_rkx120_pwm_chip(struct pwm_chip *c)
+{
+	return container_of(c, struct rkx120_pwm_chip, chip);
+}
+
+static void rkx120_pwm_get_state(struct pwm_chip *chip,
+				    struct pwm_device *pwm,
+				    struct pwm_state *state)
+{
+	struct rkx120_pwm_chip *pc = to_rkx120_pwm_chip(chip);
+	u32 enable_conf = pc->data->enable_conf;
+	u64 tmp;
+	u32 val;
+
+	rkx120_pwm_read(pc->serdes, pc->remote_id, PWM_PERIOD_HPR(pc->channel_id), &val);
+	tmp = val * pc->data->prescaler * NSEC_PER_SEC;
+	state->period = DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate);
+
+	rkx120_pwm_read(pc->serdes, pc->remote_id, PWM_DUTY_LPR(pc->channel_id), &val);
+	tmp = val * pc->data->prescaler * NSEC_PER_SEC;
+	state->duty_cycle =  DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate);
+
+	rkx120_pwm_read(pc->serdes, pc->remote_id, PWM_CTRL(pc->channel_id), &val);
+	if (pc->oneshot_en)
+		enable_conf &= ~PWM_CONTINUOUS;
+	state->enabled = (val & enable_conf) == enable_conf;
+
+	if (pc->data->supports_polarity && !(val & PWM_DUTY_POSITIVE))
+		state->polarity = PWM_POLARITY_INVERSED;
+	else
+		state->polarity = PWM_POLARITY_NORMAL;
+}
+
+static void rkx120_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+				 const struct pwm_state *state)
+{
+	struct rkx120_pwm_chip *pc = to_rkx120_pwm_chip(chip);
+	unsigned long period, duty, delay_ns;
+	u64 div;
+	u32 ctrl;
+	u8 dclk_div = 1;
+
+#ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
+	if (state->oneshot_count > 0 && state->oneshot_count <= pc->data->oneshot_cnt_max)
+		dclk_div = 2;
+#endif
+
+	/*
+	 * Since period and duty cycle registers have a width of 32
+	 * bits, every possible input period can be obtained using the
+	 * default prescaler value for all practical clock rate values.
+	 */
+	div = (u64)pc->clk_rate * state->period;
+	period = DIV_ROUND_CLOSEST_ULL(div, dclk_div * pc->data->prescaler * NSEC_PER_SEC);
+
+	div = (u64)pc->clk_rate * state->duty_cycle;
+	duty = DIV_ROUND_CLOSEST_ULL(div, dclk_div * pc->data->prescaler * NSEC_PER_SEC);
+
+	if (pc->data->supports_lock) {
+		div = (u64)10 * NSEC_PER_SEC * dclk_div * pc->data->prescaler;
+		delay_ns = DIV_ROUND_UP_ULL(div, pc->clk_rate);
+	}
+
+	/*
+	 * Lock the period and duty of previous configuration, then
+	 * change the duty and period, that would not be effective.
+	 */
+	rkx120_pwm_read(pc->serdes, pc->remote_id, PWM_CTRL(pc->channel_id), &ctrl);
+
+#ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
+	if (state->oneshot_count > 0 && state->oneshot_count <= pc->data->oneshot_cnt_max) {
+		/*
+		 * This is a workaround, an uncertain waveform will be
+		 * generated after oneshot ends. It is needed to enable
+		 * the dclk scale function to resolve it. It doesn't
+		 * matter what the scale factor is, just make sure the
+		 * scale function is turned on, for which we set scale
+		 * factor to 2.
+		 */
+		ctrl &= ~PWM_SCALE_MASK;
+		ctrl |= (dclk_div / 2) << PWM_SCALE_SHIFT;
+		ctrl &= ~PWM_CLK_SEL_MASK;
+		ctrl |= PWM_SEL_SCALED_CLOCK;
+
+		pc->oneshot_en = true;
+		ctrl &= ~PWM_MODE_MASK;
+		ctrl |= PWM_ONESHOT;
+
+		ctrl &= ~PWM_ONESHOT_COUNT_MASK;
+		ctrl |= (state->oneshot_count - 1) << PWM_ONESHOT_COUNT_SHIFT;
+	} else {
+		ctrl &= ~PWM_SCALE_MASK;
+		ctrl &= ~PWM_CLK_SEL_MASK;
+		ctrl |= PWM_SEL_NO_SCALED_CLOCK;
+
+		if (state->oneshot_count)
+			dev_err(chip->dev, "Oneshot_count must be between 1 and %d.\n",
+				pc->data->oneshot_cnt_max);
+
+		pc->oneshot_en = false;
+		ctrl &= ~PWM_MODE_MASK;
+		ctrl |= PWM_CONTINUOUS;
+
+		ctrl &= ~PWM_ONESHOT_COUNT_MASK;
+	}
+#endif
+
+	/*
+	 * Lock the period and duty of previous configuration, then
+	 * change the duty and period, that would not be effective.
+	 */
+	if (pc->data->supports_lock) {
+		ctrl |= PWM_LOCK_EN;
+		rkx120_pwm_write(pc->serdes, pc->remote_id, PWM_CTRL(pc->channel_id), ctrl);
+	}
+
+	rkx120_pwm_write(pc->serdes, pc->remote_id, PWM_PERIOD_HPR(pc->channel_id), period);
+	rkx120_pwm_write(pc->serdes, pc->remote_id, PWM_DUTY_LPR(pc->channel_id), duty);
+
+	if (pc->data->supports_polarity) {
+		ctrl &= ~PWM_POLARITY_MASK;
+		if (state->polarity == PWM_POLARITY_INVERSED)
+			ctrl |= PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSITIVE;
+		else
+			ctrl |= PWM_DUTY_POSITIVE | PWM_INACTIVE_NEGATIVE;
+	}
+
+	/*
+	 * Unlock and set polarity at the same time, the configuration of duty,
+	 * period and polarity would be effective together at next period. It
+	 * takes 10 dclk cycles to make sure lock works before unlocking.
+	 */
+	if (pc->data->supports_lock) {
+		ctrl &= ~PWM_LOCK_EN;
+		ndelay(delay_ns);
+	}
+
+	rkx120_pwm_write(pc->serdes, pc->remote_id, PWM_CTRL(pc->channel_id), ctrl);
+}
+
+static int rkx120_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm, bool enable)
+{
+	struct rkx120_pwm_chip *pc = to_rkx120_pwm_chip(chip);
+	u32 enable_conf = pc->data->enable_conf;
+	u32 val;
+
+	rkx120_pwm_read(pc->serdes, pc->remote_id, PWM_CTRL(pc->channel_id), &val);
+	val &= ~pc->data->enable_conf_mask;
+
+	if (pc->data->enable_conf_mask & PWM_OUTPUT_CENTER) {
+		if (pc->center_aligned)
+			val |= PWM_OUTPUT_CENTER;
+	}
+
+	if (enable) {
+		val |= enable_conf;
+		if (pc->oneshot_en)
+			val &= ~PWM_CONTINUOUS;
+	} else {
+		val &= ~enable_conf;
+	}
+
+	rkx120_pwm_write(pc->serdes, pc->remote_id, PWM_CTRL(pc->channel_id), val);
+
+	return 0;
+}
+
+static int rkx120_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+			       const struct pwm_state *state)
+{
+	struct rkx120_pwm_chip *pc = to_rkx120_pwm_chip(chip);
+	struct pwm_state curstate;
+	bool enabled;
+	int ret = 0;
+
+	pwm_get_state(pwm, &curstate);
+	enabled = curstate.enabled;
+
+	if (state->polarity != curstate.polarity && enabled &&
+	    !pc->data->supports_lock) {
+		ret = rkx120_pwm_enable(chip, pwm, false);
+		if (ret)
+			return ret;
+		enabled = false;
+	}
+
+	rkx120_pwm_config(chip, pwm, state);
+	if (state->enabled != enabled) {
+		ret = rkx120_pwm_enable(chip, pwm, state->enabled);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static const struct pwm_ops rkx120_pwm_ops = {
+	.get_state = rkx120_pwm_get_state,
+	.apply = rkx120_pwm_apply,
+	.owner = THIS_MODULE,
+};
+
+static const struct rkx120_pwm_data rkx120_pwm_data = {
+	.prescaler = 1,
+	.supports_polarity = true,
+	.supports_lock = true,
+	.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
+		       PWM_CONTINUOUS,
+	.enable_conf_mask = GENMASK(2, 0) | BIT(5) | BIT(8),
+	.oneshot_cnt_max = 0x100,
+};
+
+static const struct of_device_id rkx120_pwm_dt_ids[] = {
+	{ .compatible = "rockchip,rkx120-pwm", .data = &rkx120_pwm_data},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, rkx120_pwm_dt_ids);
+
+static int rkx120_pwm_probe(struct platform_device *pdev)
+{
+	struct rk_serdes *serdes = dev_get_drvdata(pdev->dev.parent);
+	const struct of_device_id *id;
+	struct rkx120_pwm_chip *pc;
+	u32 remote_id, channel_id;
+	int ret;
+
+	id = of_match_device(rkx120_pwm_dt_ids, &pdev->dev);
+	if (!id)
+		return -EINVAL;
+
+	pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
+	if (!pc)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, pc);
+
+	pc->data = id->data;
+	pc->chip.dev = &pdev->dev;
+	pc->chip.ops = &rkx120_pwm_ops;
+	pc->chip.base = -1;
+	pc->chip.npwm = 1;
+	if (pc->data->supports_polarity) {
+		pc->chip.of_xlate = of_pwm_xlate_with_flags;
+		pc->chip.of_pwm_n_cells = 3;
+	}
+
+	pc->clk_rate = PWM_DCLK_RATE;
+	pc->serdes = serdes;
+	pc->center_aligned = device_property_read_bool(&pdev->dev, "center-aligned");
+
+	ret = of_property_read_u32(pdev->dev.of_node, "channel-id", &channel_id);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to read pwm channel id\n");
+		return ret;
+	}
+	pc->channel_id = channel_id;
+
+	ret = of_property_read_u32(pdev->dev.of_node, "remote-id", &remote_id);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to read pwm remote id\n");
+		return ret;
+	}
+	pc->remote_id = remote_id;
+
+	ret = pwmchip_add(&pc->chip);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rkx120_pwm_remove(struct platform_device *pdev)
+{
+	struct rkx120_pwm_chip *pc = platform_get_drvdata(pdev);
+
+	return pwmchip_remove(&pc->chip);
+}
+
+static struct platform_driver rkx120_pwm_driver = {
+	.driver = {
+		.name = "rkx120-pwm",
+		.of_match_table = rkx120_pwm_dt_ids,
+	},
+	.probe = rkx120_pwm_probe,
+	.remove = rkx120_pwm_remove,
+};
+module_platform_driver(rkx120_pwm_driver);
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx120_reg.h b/kernel/drivers/mfd/rkx110_x120/rkx120_reg.h
index 91e7c91..de4c94e 100644
--- a/kernel/drivers/mfd/rkx110_x120/rkx120_reg.h
+++ b/kernel/drivers/mfd/rkx110_x120/rkx120_reg.h
@@ -328,6 +328,8 @@
 #define DES_GRF_SOC_CON5		GRF_REG(0x114)
 #define DES_GRF_SOC_CON6		GRF_REG(0x118)
 #define DES_GRF_SOC_CON7		GRF_REG(0x11C)
+#define DES_GRF_IRQ_EN			GRF_REG(0x140)
+#define DES_GRF_IRQ_STATUS		GRF_REG(0x150)
 
 enum {
 	/* SOC_CON0 */
@@ -433,6 +435,71 @@
 	/* SOC_CON9 */
 
 	/* DES_GRF_IRQ_EN */
+	DES_IRQ_OTHER_LANE_EN		= HIWORD_UPDATE(1, BIT(15), 15),
+	DES_IRQ_OTHER_LANE_DIS		= HIWORD_UPDATE(0, BIT(15), 15),
+
+	DES_IRQ_EXT_EN			= HIWORD_UPDATE(1, BIT(14), 14),
+	DES_IRQ_EXT_DIS			= HIWORD_UPDATE(0, BIT(14), 14),
+
+	DES_IRQ_LINK_EN			= HIWORD_UPDATE(1, BIT(13), 13),
+	DES_IRQ_LINK_DIS		= HIWORD_UPDATE(0, BIT(13), 13),
+
+	DES_IRQ_DVP_TX_EN		= HIWORD_UPDATE(1, BIT(12), 12),
+	DES_IRQ_DVP_TX_DIS		= HIWORD_UPDATE(0, BIT(12), 12),
+
+	DES_IRQ_PWM_EN			= HIWORD_UPDATE(1, BIT(11), 11),
+	DES_IRQ_PWM_DIS			= HIWORD_UPDATE(0, BIT(11), 11),
+
+	DES_IRQ_REMOTE_EN		= HIWORD_UPDATE(1, BIT(10), 10),
+	DES_IRQ_REMOTE_DIS		= HIWORD_UPDATE(0, BIT(10), 10),
+
+	DES_IRQ_PMA_ADAPT1_EN		= HIWORD_UPDATE(1, BIT(9), 9),
+	DES_IRQ_PMA_ADAPT1_DIS		= HIWORD_UPDATE(0, BIT(9), 9),
+
+	DES_IRQ_PMA_ADAPT0_EN		= HIWORD_UPDATE(1, BIT(8), 8),
+	DES_IRQ_PMA_ADAPT0_DIS		= HIWORD_UPDATE(0, BIT(8), 8),
+
+	DES_IRQ_MIPI_DSI_HOST_EN	= HIWORD_UPDATE(1, BIT(7), 7),
+	DES_IRQ_MIPI_DSI_HOST_DIS	= HIWORD_UPDATE(0, BIT(7), 7),
+
+	DES_IRQ_CSITX1_EN		= HIWORD_UPDATE(1, BIT(6), 6),
+	DES_IRQ_CSITX1_DIS		= HIWORD_UPDATE(0, BIT(6), 6),
+
+	DES_IRQ_CSITX0_EN		= HIWORD_UPDATE(1, BIT(5), 5),
+	DES_IRQ_CSITX0_DIS		= HIWORD_UPDATE(0, BIT(5), 5),
+
+	DES_IRQ_GPIO1_EN		= HIWORD_UPDATE(1, BIT(4), 4),
+	DES_IRQ_GPIO1_DIS		= HIWORD_UPDATE(0, BIT(4), 4),
+
+	DES_IRQ_GPIO0_EN		= HIWORD_UPDATE(1, BIT(3), 3),
+	DES_IRQ_GPIO0_DIS		= HIWORD_UPDATE(0, BIT(3), 3),
+
+	DES_IRQ_EFUSE_EN		= HIWORD_UPDATE(1, BIT(2), 2),
+	DES_IRQ_EFUSE_DIS		= HIWORD_UPDATE(0, BIT(2), 2),
+
+	DES_IRQ_PCS1_EN			= HIWORD_UPDATE(1, BIT(1), 1),
+	DES_IRQ_PCS1_DIS		= HIWORD_UPDATE(0, BIT(1), 1),
+
+	DES_IRQ_PCS0_EN			= HIWORD_UPDATE(1, BIT(0), 0),
+	DES_IRQ_PCS0_DIS		= HIWORD_UPDATE(0, BIT(0), 0),
+
+	/* DES_GRF_IRQ_STATUS */
+	DES_IRQ_PCS0			= BIT(0),
+	DES_IRQ_PCS1			= BIT(1),
+	DES_IRQ_EFUSE			= BIT(2),
+	DES_IRQ_GPIO0			= BIT(3),
+	DES_IRQ_GPIO1			= BIT(4),
+	DES_IRQ_CSITX0			= BIT(5),
+	DES_IRQ_CSITX1			= BIT(6),
+	DES_IRQ_MIPI_DSI_HOST		= BIT(7),
+	DES_IRQ_PMA_ADAPT0		= BIT(8),
+	DES_IRQ_PMA_ADAPT1		= BIT(9),
+	DES_IRQ_REMOTE			= BIT(10),
+	DES_IRQ_PWM			= BIT(11),
+	DES_IRQ_DVP_TX			= BIT(12),
+	DES_IRQ_LINK			= BIT(13),
+	DES_IRQ_EXT			= BIT(14),
+	DES_IRQ_OTHER_LANE		= BIT(15),
 
 	/* DES_GRF_SOC_STATUS0 */
 	DES_PCS1_READY		= BIT(1),
@@ -452,6 +519,12 @@
 #define RKX120_DES_PCS_OFFSET		0x00001000
 
 #define RKX120_PWM_BASE			0x01080000
+#define PWM_REG(x)			((x) + RKX120_PWM_BASE)
+#define PWM_CNT(ch)			(PWM_REG(0x0000) + 0x10 * ch)
+#define PWM_PERIOD_HPR(ch)		(PWM_REG(0x0004) + 0x10 * ch)
+#define PWM_DUTY_LPR(ch)		(PWM_REG(0x0008) + 0x10 * ch)
+#define PWM_CTRL(ch)			(PWM_REG(0x000C) + 0x10 * ch)
+
 #define RKX120_EFUSE_BASE		0x01090000
 #define RKX120_MIPI_LVDS_TX_PHY0_BASE	0x010A0000
 #define RKX120_MIPI_LVDS_TX_PHY1_BASE	0x010B0000
diff --git a/kernel/drivers/mfd/rkx110_x120/serdes_combphy.h b/kernel/drivers/mfd/rkx110_x120/serdes_combphy.h
index b5447fc..d452632 100644
--- a/kernel/drivers/mfd/rkx110_x120/serdes_combphy.h
+++ b/kernel/drivers/mfd/rkx110_x120/serdes_combphy.h
@@ -14,15 +14,20 @@
 void serdes_combphy_get_default_config(u64 hs_clk_rate,
 				       struct configure_opts_combphy *cfg);
 
-void rkx110_combrxphy_set_mode(struct rk_serdes *ser, enum combrx_phy_mode mode);
-void rkx110_combrxphy_set_rate(struct rk_serdes *ser, u64 rate);
-void rkx110_combrxphy_power_on(struct rk_serdes *ser, enum comb_phy_id id);
-void rkx110_combrxphy_power_off(struct rk_serdes *ser, enum comb_phy_id id);
+void rkx110_combrxphy_set_mode(struct rkx110_combrxphy *combrxphy, enum combrx_phy_mode mode);
+void rkx110_combrxphy_set_rate(struct rkx110_combrxphy *combrxphy, u64 rate);
+void rkx110_combrxphy_set_lanes(struct rkx110_combrxphy *combrxphy, uint8_t lanes);
+void rkx110_combrxphy_power_on(struct rk_serdes *ser, struct rkx110_combrxphy *combrxphy,
+			       u8 dev_id, enum comb_phy_id id);
+void rkx110_combrxphy_power_off(struct rk_serdes *ser, struct rkx110_combrxphy *combrxphy,
+				u8 dev_id, enum comb_phy_id id);
 
-void rkx120_combtxphy_set_mode(struct rk_serdes *des, enum combtx_phy_mode mode);
-void rkx120_combtxphy_set_rate(struct rk_serdes *des, u64 rate);
-u64 rkx120_combtxphy_get_rate(struct rk_serdes *des);
-void rkx120_combtxphy_power_on(struct rk_serdes *des, u8 remote_id, u8 phy_id);
-void rkx120_combtxphy_power_off(struct rk_serdes *des, u8 remote_id);
+void rkx120_combtxphy_set_mode(struct rkx120_combtxphy *combtxphy, enum combtx_phy_mode mode);
+void rkx120_combtxphy_set_rate(struct rkx120_combtxphy *combtxphy, u64 rate);
+u64 rkx120_combtxphy_get_rate(struct rkx120_combtxphy *combtxphy);
+void rkx120_combtxphy_power_on(struct rk_serdes *des, struct rkx120_combtxphy *combtxphy,
+			       u8 dev_id, u8 phy_id);
+void rkx120_combtxphy_power_off(struct rk_serdes *des, struct rkx120_combtxphy *combtxphy,
+				u8 dev_id, u8 phy_id);
 #endif
 
diff --git a/kernel/drivers/mfd/rt5033.c b/kernel/drivers/mfd/rt5033.c
index 48381d9..302115d 100644
--- a/kernel/drivers/mfd/rt5033.c
+++ b/kernel/drivers/mfd/rt5033.c
@@ -42,9 +42,6 @@
 		.name = "rt5033-charger",
 		.of_compatible = "richtek,rt5033-charger",
 	}, {
-		.name = "rt5033-battery",
-		.of_compatible = "richtek,rt5033-battery",
-	}, {
 		.name = "rt5033-led",
 		.of_compatible = "richtek,rt5033-led",
 	},
diff --git a/kernel/drivers/mfd/stmfx.c b/kernel/drivers/mfd/stmfx.c
index 988e2ba..b45d7b0 100644
--- a/kernel/drivers/mfd/stmfx.c
+++ b/kernel/drivers/mfd/stmfx.c
@@ -330,9 +330,8 @@
 	stmfx->vdd = devm_regulator_get_optional(&client->dev, "vdd");
 	ret = PTR_ERR_OR_ZERO(stmfx->vdd);
 	if (ret) {
-		if (ret == -ENODEV)
-			stmfx->vdd = NULL;
-		else
+		stmfx->vdd = NULL;
+		if (ret != -ENODEV)
 			return dev_err_probe(&client->dev, ret, "Failed to get VDD regulator\n");
 	}
 
@@ -387,7 +386,7 @@
 
 err:
 	if (stmfx->vdd)
-		return regulator_disable(stmfx->vdd);
+		regulator_disable(stmfx->vdd);
 
 	return ret;
 }
diff --git a/kernel/drivers/mfd/stmpe.c b/kernel/drivers/mfd/stmpe.c
index 5083493..7f758fb 100644
--- a/kernel/drivers/mfd/stmpe.c
+++ b/kernel/drivers/mfd/stmpe.c
@@ -1494,9 +1494,9 @@
 
 int stmpe_remove(struct stmpe *stmpe)
 {
-	if (!IS_ERR(stmpe->vio))
+	if (!IS_ERR(stmpe->vio) && regulator_is_enabled(stmpe->vio))
 		regulator_disable(stmpe->vio);
-	if (!IS_ERR(stmpe->vcc))
+	if (!IS_ERR(stmpe->vcc) && regulator_is_enabled(stmpe->vcc))
 		regulator_disable(stmpe->vcc);
 
 	__stmpe_disable(stmpe, STMPE_BLOCK_ADC);
diff --git a/kernel/drivers/mfd/tqmx86.c b/kernel/drivers/mfd/tqmx86.c
index 732013f..0498f1b 100644
--- a/kernel/drivers/mfd/tqmx86.c
+++ b/kernel/drivers/mfd/tqmx86.c
@@ -16,8 +16,8 @@
 #include <linux/platform_data/i2c-ocores.h>
 #include <linux/platform_device.h>
 
-#define TQMX86_IOBASE	0x160
-#define TQMX86_IOSIZE	0x3f
+#define TQMX86_IOBASE	0x180
+#define TQMX86_IOSIZE	0x20
 #define TQMX86_IOBASE_I2C	0x1a0
 #define TQMX86_IOSIZE_I2C	0xa
 #define TQMX86_IOBASE_WATCHDOG	0x18b
@@ -25,29 +25,33 @@
 #define TQMX86_IOBASE_GPIO	0x18d
 #define TQMX86_IOSIZE_GPIO	0x4
 
-#define TQMX86_REG_BOARD_ID	0x20
+#define TQMX86_REG_BOARD_ID	0x00
 #define TQMX86_REG_BOARD_ID_E38M	1
 #define TQMX86_REG_BOARD_ID_50UC	2
 #define TQMX86_REG_BOARD_ID_E38C	3
 #define TQMX86_REG_BOARD_ID_60EB	4
-#define TQMX86_REG_BOARD_ID_E39M	5
-#define TQMX86_REG_BOARD_ID_E39C	6
-#define TQMX86_REG_BOARD_ID_E39x	7
+#define TQMX86_REG_BOARD_ID_E39MS	5
+#define TQMX86_REG_BOARD_ID_E39C1	6
+#define TQMX86_REG_BOARD_ID_E39C2	7
 #define TQMX86_REG_BOARD_ID_70EB	8
 #define TQMX86_REG_BOARD_ID_80UC	9
-#define TQMX86_REG_BOARD_ID_90UC	10
-#define TQMX86_REG_BOARD_REV	0x21
-#define TQMX86_REG_IO_EXT_INT	0x26
+#define TQMX86_REG_BOARD_ID_110EB	11
+#define TQMX86_REG_BOARD_ID_E40M	12
+#define TQMX86_REG_BOARD_ID_E40S	13
+#define TQMX86_REG_BOARD_ID_E40C1	14
+#define TQMX86_REG_BOARD_ID_E40C2	15
+#define TQMX86_REG_BOARD_REV	0x01
+#define TQMX86_REG_IO_EXT_INT	0x06
 #define TQMX86_REG_IO_EXT_INT_NONE		0
 #define TQMX86_REG_IO_EXT_INT_7			1
 #define TQMX86_REG_IO_EXT_INT_9			2
 #define TQMX86_REG_IO_EXT_INT_12		3
 #define TQMX86_REG_IO_EXT_INT_MASK		0x3
 #define TQMX86_REG_IO_EXT_INT_GPIO_SHIFT	4
+#define TQMX86_REG_SAUC		0x17
 
-#define TQMX86_REG_I2C_DETECT	0x47
+#define TQMX86_REG_I2C_DETECT	0x1a7
 #define TQMX86_REG_I2C_DETECT_SOFT		0xa5
-#define TQMX86_REG_I2C_INT_EN	0x49
 
 static uint gpio_irq;
 module_param(gpio_irq, uint, 0);
@@ -107,7 +111,7 @@
 	},
 };
 
-static const char *tqmx86_board_id_to_name(u8 board_id)
+static const char *tqmx86_board_id_to_name(u8 board_id, u8 sauc)
 {
 	switch (board_id) {
 	case TQMX86_REG_BOARD_ID_E38M:
@@ -118,18 +122,26 @@
 		return "TQMxE38C";
 	case TQMX86_REG_BOARD_ID_60EB:
 		return "TQMx60EB";
-	case TQMX86_REG_BOARD_ID_E39M:
-		return "TQMxE39M";
-	case TQMX86_REG_BOARD_ID_E39C:
-		return "TQMxE39C";
-	case TQMX86_REG_BOARD_ID_E39x:
-		return "TQMxE39x";
+	case TQMX86_REG_BOARD_ID_E39MS:
+		return (sauc == 0xff) ? "TQMxE39M" : "TQMxE39S";
+	case TQMX86_REG_BOARD_ID_E39C1:
+		return "TQMxE39C1";
+	case TQMX86_REG_BOARD_ID_E39C2:
+		return "TQMxE39C2";
 	case TQMX86_REG_BOARD_ID_70EB:
 		return "TQMx70EB";
 	case TQMX86_REG_BOARD_ID_80UC:
 		return "TQMx80UC";
-	case TQMX86_REG_BOARD_ID_90UC:
-		return "TQMx90UC";
+	case TQMX86_REG_BOARD_ID_110EB:
+		return "TQMx110EB";
+	case TQMX86_REG_BOARD_ID_E40M:
+		return "TQMxE40M";
+	case TQMX86_REG_BOARD_ID_E40S:
+		return "TQMxE40S";
+	case TQMX86_REG_BOARD_ID_E40C1:
+		return "TQMxE40C1";
+	case TQMX86_REG_BOARD_ID_E40C2:
+		return "TQMxE40C2";
 	default:
 		return "Unknown";
 	}
@@ -142,11 +154,15 @@
 	case TQMX86_REG_BOARD_ID_60EB:
 	case TQMX86_REG_BOARD_ID_70EB:
 	case TQMX86_REG_BOARD_ID_80UC:
-	case TQMX86_REG_BOARD_ID_90UC:
+	case TQMX86_REG_BOARD_ID_110EB:
+	case TQMX86_REG_BOARD_ID_E40M:
+	case TQMX86_REG_BOARD_ID_E40S:
+	case TQMX86_REG_BOARD_ID_E40C1:
+	case TQMX86_REG_BOARD_ID_E40C2:
 		return 24000;
-	case TQMX86_REG_BOARD_ID_E39M:
-	case TQMX86_REG_BOARD_ID_E39C:
-	case TQMX86_REG_BOARD_ID_E39x:
+	case TQMX86_REG_BOARD_ID_E39MS:
+	case TQMX86_REG_BOARD_ID_E39C1:
+	case TQMX86_REG_BOARD_ID_E39C2:
 		return 25000;
 	case TQMX86_REG_BOARD_ID_E38M:
 	case TQMX86_REG_BOARD_ID_E38C:
@@ -158,7 +174,7 @@
 
 static int tqmx86_probe(struct platform_device *pdev)
 {
-	u8 board_id, rev, i2c_det, io_ext_int_val;
+	u8 board_id, sauc, rev, i2c_det, io_ext_int_val;
 	struct device *dev = &pdev->dev;
 	u8 gpio_irq_cfg, readback;
 	const char *board_name;
@@ -188,14 +204,20 @@
 		return -ENOMEM;
 
 	board_id = ioread8(io_base + TQMX86_REG_BOARD_ID);
-	board_name = tqmx86_board_id_to_name(board_id);
+	sauc = ioread8(io_base + TQMX86_REG_SAUC);
+	board_name = tqmx86_board_id_to_name(board_id, sauc);
 	rev = ioread8(io_base + TQMX86_REG_BOARD_REV);
 
 	dev_info(dev,
 		 "Found %s - Board ID %d, PCB Revision %d, PLD Revision %d\n",
 		 board_name, board_id, rev >> 4, rev & 0xf);
 
-	i2c_det = ioread8(io_base + TQMX86_REG_I2C_DETECT);
+	/*
+	 * The I2C_DETECT register is in the range assigned to the I2C driver
+	 * later, so we don't extend TQMX86_IOSIZE. Use inb() for this one-off
+	 * access instead of ioport_map + unmap.
+	 */
+	i2c_det = inb(TQMX86_REG_I2C_DETECT);
 
 	if (gpio_irq_cfg) {
 		io_ext_int_val =
diff --git a/kernel/drivers/misc/cxl/guest.c b/kernel/drivers/misc/cxl/guest.c
index 186308f..6334376 100644
--- a/kernel/drivers/misc/cxl/guest.c
+++ b/kernel/drivers/misc/cxl/guest.c
@@ -959,10 +959,10 @@
 	 * 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 @@
 		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 @@
 
 	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 @@
 	 * 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:
diff --git a/kernel/drivers/misc/cxl/pci.c b/kernel/drivers/misc/cxl/pci.c
index 2ba899f..d183836 100644
--- a/kernel/drivers/misc/cxl/pci.c
+++ b/kernel/drivers/misc/cxl/pci.c
@@ -387,6 +387,7 @@
 	rc = get_phb_index(np, phb_index);
 	if (rc) {
 		pr_err("cxl: invalid phb index\n");
+		of_node_put(np);
 		return rc;
 	}
 
@@ -1164,10 +1165,10 @@
 	 * 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 +1177,12 @@
 
 	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 +1670,25 @@
 	 * 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:
diff --git a/kernel/drivers/misc/eeprom/Kconfig b/kernel/drivers/misc/eeprom/Kconfig
index 0f791bf..c92f2cd 100644
--- a/kernel/drivers/misc/eeprom/Kconfig
+++ b/kernel/drivers/misc/eeprom/Kconfig
@@ -6,6 +6,7 @@
 	depends on I2C && SYSFS
 	select NVMEM
 	select NVMEM_SYSFS
+	select REGMAP
 	select REGMAP_I2C
 	help
 	  Enable this driver to get read/write support to most I2C EEPROMs
diff --git a/kernel/drivers/misc/fastrpc.c b/kernel/drivers/misc/fastrpc.c
index 2c3142b..eed047e 100644
--- a/kernel/drivers/misc/fastrpc.c
+++ b/kernel/drivers/misc/fastrpc.c
@@ -247,6 +247,13 @@
 		dma_buf_put(map->buf);
 	}
 
+	if (map->fl) {
+		spin_lock(&map->fl->lock);
+		list_del(&map->node);
+		spin_unlock(&map->fl->lock);
+		map->fl = NULL;
+	}
+
 	kfree(map);
 }
 
@@ -256,10 +263,12 @@
 		kref_put(&map->refcount, fastrpc_free_map);
 }
 
-static void fastrpc_map_get(struct fastrpc_map *map)
+static int fastrpc_map_get(struct fastrpc_map *map)
 {
-	if (map)
-		kref_get(&map->refcount);
+	if (!map)
+		return -ENOENT;
+
+	return kref_get_unless_zero(&map->refcount) ? 0 : -ENOENT;
 }
 
 static int fastrpc_map_find(struct fastrpc_user *fl, int fd,
@@ -1097,7 +1106,7 @@
 
 	sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE, 4, 0);
 	if (init.attrs)
-		sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 6, 0);
+		sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 4, 0);
 
 	err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE,
 				      sc, args);
@@ -1112,12 +1121,7 @@
 	fl->init_mem = NULL;
 	fastrpc_buf_free(imem);
 err_alloc:
-	if (map) {
-		spin_lock(&fl->lock);
-		list_del(&map->node);
-		spin_unlock(&fl->lock);
-		fastrpc_map_put(map);
-	}
+	fastrpc_map_put(map);
 err:
 	kfree(args);
 
@@ -1194,10 +1198,8 @@
 		fastrpc_context_put(ctx);
 	}
 
-	list_for_each_entry_safe(map, m, &fl->maps, node) {
-		list_del(&map->node);
+	list_for_each_entry_safe(map, m, &fl->maps, node)
 		fastrpc_map_put(map);
-	}
 
 	list_for_each_entry_safe(buf, b, &fl->mmaps, node) {
 		list_del(&buf->node);
@@ -1673,8 +1675,10 @@
 	struct fastrpc_invoke_ctx *ctx;
 
 	spin_lock(&user->lock);
-	list_for_each_entry(ctx, &user->pending, node)
+	list_for_each_entry(ctx, &user->pending, node) {
+		ctx->retval = -EPIPE;
 		complete(&ctx->work);
+	}
 	spin_unlock(&user->lock);
 }
 
@@ -1684,7 +1688,9 @@
 	struct fastrpc_user *user;
 	unsigned long flags;
 
+	/* No invocations past this point */
 	spin_lock_irqsave(&cctx->lock, flags);
+	cctx->rpdev = NULL;
 	list_for_each_entry(user, &cctx->users, user)
 		fastrpc_notify_users(user);
 	spin_unlock_irqrestore(&cctx->lock, flags);
@@ -1692,7 +1698,6 @@
 	misc_deregister(&cctx->miscdev);
 	of_platform_depopulate(&rpdev->dev);
 
-	cctx->rpdev = NULL;
 	fastrpc_channel_ctx_put(cctx);
 }
 
diff --git a/kernel/drivers/misc/mei/bus-fixup.c b/kernel/drivers/misc/mei/bus-fixup.c
index 4e30fa9..c4c1275 100644
--- a/kernel/drivers/misc/mei/bus-fixup.c
+++ b/kernel/drivers/misc/mei/bus-fixup.c
@@ -172,7 +172,7 @@
 	ret = __mei_cl_send(cldev->cl, (u8 *)&req, sizeof(req),
 			    MEI_CL_IO_TX_BLOCKING);
 	if (ret < 0) {
-		dev_err(&cldev->dev, "Could not send ReqFWVersion cmd\n");
+		dev_err(&cldev->dev, "Could not send ReqFWVersion cmd ret = %d\n", ret);
 		return ret;
 	}
 
@@ -184,7 +184,7 @@
 		 * Should be at least one version block,
 		 * error out if nothing found
 		 */
-		dev_err(&cldev->dev, "Could not read FW version\n");
+		dev_err(&cldev->dev, "Could not read FW version ret = %d\n", bytes_recv);
 		return -EIO;
 	}
 
@@ -332,7 +332,7 @@
 
 	ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(cmd), MEI_CL_IO_TX_BLOCKING);
 	if (ret < 0) {
-		dev_err(bus->dev, "Could not send IF version cmd\n");
+		dev_err(bus->dev, "Could not send IF version cmd ret = %d\n", ret);
 		return ret;
 	}
 
@@ -346,7 +346,7 @@
 	ret = 0;
 	bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, 0, 0);
 	if (bytes_recv < 0 || (size_t)bytes_recv < if_version_length) {
-		dev_err(bus->dev, "Could not read IF version\n");
+		dev_err(bus->dev, "Could not read IF version ret = %d\n", bytes_recv);
 		ret = -EIO;
 		goto err;
 	}
diff --git a/kernel/drivers/misc/mei/hw-me-regs.h b/kernel/drivers/misc/mei/hw-me-regs.h
index afb2e78..eabbdf1 100644
--- a/kernel/drivers/misc/mei/hw-me-regs.h
+++ b/kernel/drivers/misc/mei/hw-me-regs.h
@@ -111,6 +111,8 @@
 
 #define MEI_DEV_ID_RPL_S      0x7A68  /* Raptor Lake Point S */
 
+#define MEI_DEV_ID_MTL_M      0x7E70  /* Meteor Lake Point M */
+
 /*
  * MEI HW Section
  */
diff --git a/kernel/drivers/misc/mei/pci-me.c b/kernel/drivers/misc/mei/pci-me.c
index 5324b65..f2765d6 100644
--- a/kernel/drivers/misc/mei/pci-me.c
+++ b/kernel/drivers/misc/mei/pci-me.c
@@ -117,6 +117,8 @@
 
 	{MEI_PCI_DEVICE(MEI_DEV_ID_RPL_S, MEI_ME_PCH15_CFG)},
 
+	{MEI_PCI_DEVICE(MEI_DEV_ID_MTL_M, MEI_ME_PCH15_CFG)},
+
 	/* required last entry */
 	{0, }
 };
diff --git a/kernel/drivers/misc/ocxl/config.c b/kernel/drivers/misc/ocxl/config.c
index 4d490b9..3ced98b 100644
--- a/kernel/drivers/misc/ocxl/config.c
+++ b/kernel/drivers/misc/ocxl/config.c
@@ -204,6 +204,18 @@
 	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 @@
 		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 @@
 
 	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 @@
 		reset_reload &= ~BIT(0);
 	pci_write_config_dword(dev0, pos + OCXL_DVSEC_VENDOR_RESET_RELOAD,
 			       reset_reload);
+	pci_dev_put(dev0);
 	return 0;
 }
 
diff --git a/kernel/drivers/misc/ocxl/file.c b/kernel/drivers/misc/ocxl/file.c
index e094809..524ded8 100644
--- a/kernel/drivers/misc/ocxl/file.c
+++ b/kernel/drivers/misc/ocxl/file.c
@@ -543,8 +543,11 @@
 		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)
diff --git a/kernel/drivers/misc/pci_endpoint_test.c b/kernel/drivers/misc/pci_endpoint_test.c
index 48eec5f..6c4c85e 100644
--- a/kernel/drivers/misc/pci_endpoint_test.c
+++ b/kernel/drivers/misc/pci_endpoint_test.c
@@ -727,6 +727,10 @@
 	struct pci_dev *pdev = test->pdev;
 
 	mutex_lock(&test->mutex);
+
+	reinit_completion(&test->irq_raised);
+	test->last_irq = -ENODATA;
+
 	switch (cmd) {
 	case PCITEST_BAR:
 		bar = arg;
@@ -935,6 +939,9 @@
 	if (id < 0)
 		return;
 
+	pci_endpoint_test_release_irq(test);
+	pci_endpoint_test_free_irq_vectors(test);
+
 	misc_deregister(&test->miscdev);
 	kfree(misc_device->name);
 	kfree(test->name);
@@ -943,9 +950,6 @@
 		if (test->bar[bar])
 			pci_iounmap(pdev, test->bar[bar]);
 	}
-
-	pci_endpoint_test_release_irq(test);
-	pci_endpoint_test_free_irq_vectors(test);
 
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
diff --git a/kernel/drivers/misc/rockchip/Kconfig b/kernel/drivers/misc/rockchip/Kconfig
index 3049d71..3329c6c 100644
--- a/kernel/drivers/misc/rockchip/Kconfig
+++ b/kernel/drivers/misc/rockchip/Kconfig
@@ -6,6 +6,7 @@
 	tristate "Rockchip PCIe EP function driver"
 	depends on PCI
 	depends on ARCH_ROCKCHIP
+	select PCIE_DW_DMATEST
 	help
            Enable this configuration option to enable the host side function
 	   driver for Rockchip's EP demo function driver.
diff --git a/kernel/drivers/misc/rockchip/pcie-rkep.c b/kernel/drivers/misc/rockchip/pcie-rkep.c
index 12caa41..7f5ba5a 100644
--- a/kernel/drivers/misc/rockchip/pcie-rkep.c
+++ b/kernel/drivers/misc/rockchip/pcie-rkep.c
@@ -19,10 +19,16 @@
 #include <linux/mutex.h>
 #include <linux/ctype.h>
 #include <linux/of.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+
 #include <uapi/linux/rk-pcie-ep.h>
 
 #include "../../pci/controller/rockchip-pcie-dma.h"
 #include "../../pci/controller/dwc/pcie-dw-dmatest.h"
+#if IS_MODULE(CONFIG_PCIE_FUNC_RKEP) && IS_ENABLED(CONFIG_PCIE_DW_DMATEST)
+#include "../../pci/controller/dwc/pcie-dw-dmatest.c"
+#endif
 
 #define DRV_NAME "pcie-rkep"
 
@@ -34,8 +40,7 @@
 
 static DEFINE_MUTEX(rkep_mutex);
 #define BAR_0_SZ			SZ_4M
-#define RKEP_NUM_MSI_VECTORS		4
-#define RKEP_NUM_MSIX_VECTORS		8
+#define RKEP_NUM_IRQ_VECTORS		4
 
 #define PCIe_CLIENT_MSI_IRQ_OBJ		0	/* rockchip ep object special irq */
 
@@ -50,12 +55,16 @@
 #define PCIE_DMA_WR_SAR_PTR_HI		0x210
 #define PCIE_DMA_WR_DAR_PTR_LO		0x214
 #define PCIE_DMA_WR_DAR_PTR_HI		0x218
+#define PCIE_DMA_WR_LL_PTR_LO		0x21c
+#define PCIE_DMA_WR_LL_PTR_HI		0x220
 #define PCIE_DMA_WR_WEILO		0x18
 #define PCIE_DMA_WR_WEIHI		0x1c
 #define PCIE_DMA_WR_DOORBELL		0x10
 #define PCIE_DMA_WR_INT_STATUS		0x4c
 #define PCIE_DMA_WR_INT_MASK		0x54
 #define PCIE_DMA_WR_INT_CLEAR		0x58
+#define PCIE_DMA_WR_ERR_STATUS		0x5c
+#define PCIE_DMA_WR_LL_ERR_EN		0x90
 
 #define PCIE_DMA_RD_ENB			0x2c
 #define PCIE_DMA_RD_CTRL_LO		0x300
@@ -65,24 +74,36 @@
 #define PCIE_DMA_RD_SAR_PTR_HI		0x310
 #define PCIE_DMA_RD_DAR_PTR_LO		0x314
 #define PCIE_DMA_RD_DAR_PTR_HI		0x318
+#define PCIE_DMA_RD_LL_PTR_LO		0x31c
+#define PCIE_DMA_RD_LL_PTR_HI		0x320
 #define PCIE_DMA_RD_WEILO		0x38
 #define PCIE_DMA_RD_WEIHI		0x3c
 #define PCIE_DMA_RD_DOORBELL		0x30
 #define PCIE_DMA_RD_INT_STATUS		0xa0
 #define PCIE_DMA_RD_INT_MASK		0xa8
 #define PCIE_DMA_RD_INT_CLEAR		0xac
+#define PCIE_DMA_RD_ERR_STATUS_LOW	0xb8
+#define PCIE_DMA_RD_ERR_STATUS_HIGH	0xbc
+#define PCIE_DMA_RD_LL_ERR_EN		0xc4
 
 #define PCIE_DMA_CHANEL_MAX_NUM		2
 
 #define RKEP_USER_MEM_SIZE		SZ_64M
 
 #define PCIE_CFG_ELBI_APP_OFFSET	0xe00
+#define PCIE_CFG_ELBI_USER_DATA_OFF	0x10
+
 #define PCIE_ELBI_REG_NUM		0x2
 
-struct pcie_rkep_msix_context {
+#define RKEP_EP_ELBI_TIEMOUT_US		100000
+
+#define PCIE_RK3568_RC_DBI_BASE		0xf6000000
+#define PCIE_RK3588_RC_DBI_BASE		0xf5000000
+#define PCIE_DBI_SIZE			0x400000
+
+struct pcie_rkep_irq_context {
 	struct pci_dev *dev;
 	u16 msg_id;
-	u8 *name;
 };
 
 struct pcie_rkep {
@@ -90,54 +111,212 @@
 	void __iomem *bar0;
 	void __iomem *bar2;
 	void __iomem *bar4;
-	bool in_used;
+	int cur_mmap_res;
+	struct pcie_rkep_irq_context irq_ctx[RKEP_NUM_IRQ_VECTORS];
+	int irq_valid;
+
 	struct miscdevice dev;
-	struct msix_entry msix_entries[RKEP_NUM_MSIX_VECTORS];
-	struct pcie_rkep_msix_context msix_ctx[RKEP_NUM_MSIX_VECTORS];
-	struct pcie_rkep_msix_context msi_ctx[RKEP_NUM_MSI_VECTORS];
-	bool msi_enable;
-	bool msix_enable;
 	struct dma_trx_obj *dma_obj;
 	struct pcie_ep_obj_info *obj_info;
 	struct page *user_pages; /* Allocated physical memory for user space */
-	struct fasync_struct *async;
+	struct mutex dev_lock_mutex; /* Sync resources in multi-process, such as vid and ELBI0 */
+	DECLARE_BITMAP(virtual_id_bitmap, RKEP_EP_VIRTUAL_ID_MAX);
+	DECLARE_BITMAP(virtual_id_irq_bitmap, RKEP_EP_VIRTUAL_ID_MAX);
+	wait_queue_head_t wq_head;
 };
 
-static int pcie_rkep_fasync(int fd, struct file *file, int mode)
-{
-	struct miscdevice *miscdev = file->private_data;
-	struct pcie_rkep *pcie_rkep = container_of(miscdev, struct pcie_rkep, dev);
+struct pcie_file {
+	struct mutex file_lock_mutex;
+	struct pcie_rkep *pcie_rkep;
+	DECLARE_BITMAP(child_vid_bitmap, RKEP_EP_VIRTUAL_ID_MAX); /* The virtual IDs applied for each task */
+};
 
-	return fasync_helper(fd, file, mode, &pcie_rkep->async);
+static int rkep_ep_dma_xfer(struct pcie_rkep *pcie_rkep, struct pcie_ep_dma_block_req *dma)
+{
+	int ret;
+
+	if (dma->wr)
+		ret = pcie_dw_wired_dma_tobus_block(pcie_rkep->dma_obj, dma->chn, dma->block.bus_paddr, dma->block.local_paddr, dma->block.size);
+	else
+		ret = pcie_dw_wired_dma_frombus_block(pcie_rkep->dma_obj, dma->chn, dma->block.local_paddr, dma->block.bus_paddr, dma->block.size);
+
+	return ret;
+}
+
+static int rkep_ep_request_virtual_id(struct pcie_file *pcie_file)
+{
+	struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep;
+	int index;
+
+	mutex_lock(&pcie_rkep->dev_lock_mutex);
+	index = find_first_zero_bit(pcie_rkep->virtual_id_bitmap, RKEP_EP_VIRTUAL_ID_MAX);
+	if (index >= RKEP_EP_VIRTUAL_ID_MAX) {
+		dev_err(&pcie_rkep->pdev->dev, "request virtual id %d is invalid\n", index);
+		mutex_unlock(&pcie_rkep->dev_lock_mutex);
+		return -EINVAL;
+	}
+	set_bit(index, pcie_rkep->virtual_id_bitmap);
+	mutex_unlock(&pcie_rkep->dev_lock_mutex);
+
+	mutex_lock(&pcie_file->file_lock_mutex);
+	set_bit(index, pcie_file->child_vid_bitmap);
+	mutex_unlock(&pcie_file->file_lock_mutex);
+
+	dev_dbg(&pcie_rkep->pdev->dev, "request virtual id %d\n", index);
+
+	return index;
+}
+
+static int rkep_ep_release_virtual_id(struct pcie_file *pcie_file, int index)
+{
+	struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep;
+
+	if (index >= RKEP_EP_VIRTUAL_ID_MAX) {
+		dev_err(&pcie_rkep->pdev->dev, "release virtual id %d out of range\n", index);
+
+		return -EINVAL;
+	}
+
+	if (!test_bit(index, pcie_rkep->virtual_id_bitmap))
+		dev_err(&pcie_rkep->pdev->dev, "release virtual id %d is already free\n", index);
+
+	mutex_lock(&pcie_file->file_lock_mutex);
+	__clear_bit(index, pcie_file->child_vid_bitmap);
+	mutex_unlock(&pcie_file->file_lock_mutex);
+
+	mutex_lock(&pcie_rkep->dev_lock_mutex);
+	__clear_bit(index, pcie_rkep->virtual_id_bitmap);
+	mutex_unlock(&pcie_rkep->dev_lock_mutex);
+
+	dev_dbg(&pcie_rkep->pdev->dev, "release virtual id %d\n", index);
+
+	return 0;
+}
+
+static int rkep_ep_raise_elbi_irq(struct pcie_file *pcie_file, u32 interrupt_num)
+{
+	struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep;
+	u32 index, off;
+	int i, gap_us = 100;
+	u32 val;
+	int ret;
+
+	if (interrupt_num >= (PCIE_ELBI_REG_NUM * 16)) {
+		dev_err(&pcie_rkep->pdev->dev, "elbi int num out of max count\n");
+		return -EINVAL;
+	}
+
+	index = interrupt_num / 16;
+	off = interrupt_num % 16;
+
+	for (i = 0; i < RKEP_EP_ELBI_TIEMOUT_US; i += gap_us) {
+		pci_read_config_dword(pcie_rkep->pdev, PCIE_CFG_ELBI_APP_OFFSET + 4 * index, &val);
+		if (val & BIT(off))
+			usleep_range(gap_us, gap_us + 10);
+		else
+			break;
+	}
+
+	if (i >= gap_us)
+		dev_err(&pcie_rkep->pdev->dev, "elbi int is not clear, status=%x\n", val);
+
+	ret = pci_write_config_dword(pcie_rkep->pdev, PCIE_CFG_ELBI_APP_OFFSET + 4 * index,
+				      (1 << (off + 16)) | (1 << off));
+
+	return ret;
+}
+
+static int rkep_ep_raise_irq_user_obj(struct pcie_file *pcie_file, u32 index)
+{
+	struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep;
+	int ret;
+
+	if (index >= RKEP_EP_VIRTUAL_ID_MAX) {
+		dev_err(&pcie_rkep->pdev->dev, "raise irq_user, virtual id %d out of range\n", index);
+
+		return -EINVAL;
+	}
+
+	pcie_rkep->obj_info->irq_type_ep = OBJ_IRQ_USER;
+	pcie_rkep->obj_info->irq_user_data_ep = index;
+	mutex_lock(&pcie_rkep->dev_lock_mutex);
+	ret = rkep_ep_raise_elbi_irq(pcie_file, 0);
+	mutex_unlock(&pcie_rkep->dev_lock_mutex);
+
+	return ret;
+}
+
+static int rkep_ep_poll_irq_user(struct pcie_file *pcie_file, struct pcie_ep_obj_poll_virtual_id_cfg *cfg)
+{
+	struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep;
+	u32 index = cfg->virtual_id;
+
+	if (index >= RKEP_EP_VIRTUAL_ID_MAX) {
+		dev_err(&pcie_rkep->pdev->dev, "poll irq_user, virtual id %d out of range\n", index);
+
+		return -EINVAL;
+	}
+
+	cfg->poll_status = NSIGPOLL;
+	if (cfg->sync) {
+		wait_event_interruptible(pcie_rkep->wq_head,
+					 test_bit(index, pcie_rkep->virtual_id_irq_bitmap));
+	} else {
+		wait_event_interruptible_timeout(pcie_rkep->wq_head,
+						 test_bit(index, pcie_rkep->virtual_id_irq_bitmap),
+						 cfg->timeout_ms);
+	}
+	if (test_and_clear_bit(index, pcie_rkep->virtual_id_irq_bitmap))
+		cfg->poll_status = POLL_IN;
+
+	dev_dbg(&pcie_rkep->pdev->dev, "poll virtual id %d, ret=%d\n", index, cfg->poll_status);
+
+	return 0;
 }
 
 static int pcie_rkep_open(struct inode *inode, struct file *file)
 {
 	struct miscdevice *miscdev = file->private_data;
 	struct pcie_rkep *pcie_rkep = container_of(miscdev, struct pcie_rkep, dev);
-	int ret = 0;
+	struct pcie_file *pcie_file = NULL;
 
-	mutex_lock(&rkep_mutex);
+	pcie_file = devm_kzalloc(&pcie_rkep->pdev->dev, sizeof(struct pcie_file), GFP_KERNEL);
+	if (!pcie_file)
+		return -ENOMEM;
 
-	if (pcie_rkep->in_used)
-		ret = -EINVAL;
-	else
-		pcie_rkep->in_used = true;
+	pcie_file->pcie_rkep = pcie_rkep;
 
-	mutex_unlock(&rkep_mutex);
+	mutex_init(&pcie_file->file_lock_mutex);
 
-	return ret;
+	file->private_data = pcie_file;
+
+	return 0;
 }
 
 static int pcie_rkep_release(struct inode *inode, struct file *file)
 {
-	struct miscdevice *miscdev = file->private_data;
-	struct pcie_rkep *pcie_rkep = container_of(miscdev, struct pcie_rkep, dev);
+	struct pcie_file *pcie_file = file->private_data;
+	struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep;
+	int index;
 
-	mutex_lock(&rkep_mutex);
-	pcie_rkep->in_used = false;
-	pcie_rkep_fasync(-1, file, 0);
-	mutex_unlock(&rkep_mutex);
+	while (1) {
+		mutex_lock(&pcie_file->file_lock_mutex);
+		index = find_first_bit(pcie_file->child_vid_bitmap, RKEP_EP_VIRTUAL_ID_MAX);
+
+		if (index >= RKEP_EP_VIRTUAL_ID_MAX)
+			break;
+
+		__clear_bit(index, pcie_file->child_vid_bitmap);
+		mutex_unlock(&pcie_file->file_lock_mutex);
+
+		mutex_lock(&pcie_rkep->dev_lock_mutex);
+		__clear_bit(index, pcie_rkep->virtual_id_bitmap);
+		mutex_unlock(&pcie_rkep->dev_lock_mutex);
+
+		dev_dbg(&pcie_rkep->pdev->dev, "release virtual id %d\n", index);
+	}
+
+	devm_kfree(&pcie_rkep->pdev->dev, pcie_file);
 
 	return 0;
 }
@@ -145,96 +324,240 @@
 static ssize_t pcie_rkep_write(struct file *file, const char __user *buf,
 			       size_t count, loff_t *ppos)
 {
-	struct miscdevice *miscdev = file->private_data;
-	struct pcie_rkep *pcie_rkep = container_of(miscdev, struct pcie_rkep, dev);
-	u32 *bar0_buf;
-	int loop, i = 0;
-	size_t raw_count = count;
+	struct pcie_file *pcie_file = file->private_data;
+	struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep;
+	struct pci_dev *dev = pcie_rkep->pdev;
+	unsigned int size = count;
+	loff_t init_off = *ppos, off = *ppos;
+	u8 *data;
 
-	count = (count % 4) ? (count - count % 4) : count;
-
-	if (count > BAR_0_SZ)
-		return -EINVAL;
-
-	bar0_buf = kzalloc(count, GFP_KERNEL);
-	if (!bar0_buf)
+	data = kzalloc(PCI_CFG_SPACE_EXP_SIZE, GFP_KERNEL);
+	if (!data)
 		return -ENOMEM;
 
-	if (copy_from_user(bar0_buf, buf, count)) {
-		raw_count = -EFAULT;
-		goto exit;
+	if (off > dev->cfg_size) {
+		kfree(data);
+		return 0;
+	}
+	if (off + count > dev->cfg_size) {
+		size = dev->cfg_size - off;
+		count = size;
 	}
 
-	for (loop = 0; loop < count / 4; loop++) {
-		iowrite32(bar0_buf[i], pcie_rkep->bar0 + loop * 4);
-		i++;
+	if (copy_from_user(data, buf, count)) {
+		kfree(data);
+		return -EFAULT;
 	}
 
-exit:
-	kfree(bar0_buf);
+	if ((off & 1) && size) {
+		pci_write_config_byte(dev, off, data[off - init_off]);
+		off++;
+		size--;
+	}
 
-	return raw_count;
+	if ((off & 3) && size > 2) {
+		u16 val = data[off - init_off];
+
+		val |= (u16) data[off - init_off + 1] << 8;
+		pci_write_config_word(dev, off, val);
+		off += 2;
+		size -= 2;
+	}
+
+	while (size > 3) {
+		u32 val = data[off - init_off];
+
+		val |= (u32) data[off - init_off + 1] << 8;
+		val |= (u32) data[off - init_off + 2] << 16;
+		val |= (u32) data[off - init_off + 3] << 24;
+		pci_write_config_dword(dev, off, val);
+		off += 4;
+		size -= 4;
+	}
+
+	if (size >= 2) {
+		u16 val = data[off - init_off];
+
+		val |= (u16) data[off - init_off + 1] << 8;
+		pci_write_config_word(dev, off, val);
+		off += 2;
+		size -= 2;
+	}
+
+	if (size) {
+		pci_write_config_byte(dev, off, data[off - init_off]);
+		off++;
+		--size;
+	}
+
+	kfree(data);
+
+	return count;
 }
 
 static ssize_t pcie_rkep_read(struct file *file, char __user *buf,
 			      size_t count, loff_t *ppos)
 {
-	struct miscdevice *miscdev = file->private_data;
-	struct pcie_rkep *pcie_rkep = container_of(miscdev, struct pcie_rkep, dev);
-	u32 *bar0_buf;
-	int loop, i = 0;
-	size_t raw_count = count;
+	struct pcie_file *pcie_file = file->private_data;
+	struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep;
+	struct pci_dev *dev = pcie_rkep->pdev;
+	unsigned int size = count;
+	loff_t init_off = *ppos, off = *ppos;
+	u8 *data;
 
-	count = (count % 4) ? (count - count % 4) : count;
-
-	if (count > BAR_0_SZ)
-		return -EINVAL;
-
-	bar0_buf = kzalloc(count, GFP_ATOMIC);
-	if (!bar0_buf)
+	data = kzalloc(PCI_CFG_SPACE_EXP_SIZE, GFP_KERNEL);
+	if (!data)
 		return -ENOMEM;
 
-	for (loop = 0; loop < count / 4; loop++) {
-		bar0_buf[i] = ioread32(pcie_rkep->bar0 + loop * 4);
-		i++;
+	if (off > dev->cfg_size) {
+		kfree(data);
+		return 0;
+	}
+	if (off + count > dev->cfg_size) {
+		size = dev->cfg_size - off;
+		count = size;
 	}
 
-	if (copy_to_user(buf, bar0_buf, count)) {
-		raw_count = -EFAULT;
-		goto exit;
+	if ((off & 1) && size) {
+		u8 val;
+
+		pci_read_config_byte(dev, off, &val);
+		data[off - init_off] = val;
+		off++;
+		size--;
 	}
 
-exit:
-	kfree(bar0_buf);
+	if ((off & 3) && size > 2) {
+		u16 val;
 
-	return raw_count;
+		pci_read_config_word(dev, off, &val);
+		data[off - init_off] = val & 0xff;
+		data[off - init_off + 1] = (val >> 8) & 0xff;
+		off += 2;
+		size -= 2;
+	}
+
+	while (size > 3) {
+		u32 val;
+
+		pci_read_config_dword(dev, off, &val);
+		data[off - init_off] = val & 0xff;
+		data[off - init_off + 1] = (val >> 8) & 0xff;
+		data[off - init_off + 2] = (val >> 16) & 0xff;
+		data[off - init_off + 3] = (val >> 24) & 0xff;
+		off += 4;
+		size -= 4;
+	}
+
+	if (size >= 2) {
+		u16 val;
+
+		pci_read_config_word(dev, off, &val);
+		data[off - init_off] = val & 0xff;
+		data[off - init_off + 1] = (val >> 8) & 0xff;
+		off += 2;
+		size -= 2;
+	}
+
+	if (size > 0) {
+		u8 val;
+
+		pci_read_config_byte(dev, off, &val);
+		data[off - init_off] = val;
+		off++;
+		--size;
+	}
+
+	if (copy_to_user(buf, data, count)) {
+		kfree(data);
+		return -EFAULT;
+	}
+
+	kfree(data);
+
+	return count;
 }
 
 static int pcie_rkep_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	u64 addr;
-	struct miscdevice *miscdev = file->private_data;
-	struct pcie_rkep *pcie_rkep = container_of(miscdev, struct pcie_rkep, dev);
+	struct pcie_file *pcie_file = file->private_data;
+	struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep;
+	struct pci_dev *dev = pcie_rkep->pdev;
 	size_t size = vma->vm_end - vma->vm_start;
+	resource_size_t bar_size;
+	int err;
 
-	if (size > RKEP_USER_MEM_SIZE) {
-		dev_warn(&pcie_rkep->pdev->dev, "mmap size is out of limitation\n");
+	switch (pcie_rkep->cur_mmap_res) {
+	case PCIE_EP_MMAP_RESOURCE_RK3568_RC_DBI:
+		if (size > PCIE_DBI_SIZE) {
+			dev_warn(&pcie_rkep->pdev->dev, "dbi mmap size is out of limitation\n");
+			return -EINVAL;
+		}
+		addr = PCIE_RK3568_RC_DBI_BASE;
+		break;
+	case PCIE_EP_MMAP_RESOURCE_RK3588_RC_DBI:
+		if (size > PCIE_DBI_SIZE) {
+			dev_warn(&pcie_rkep->pdev->dev, "dbi mmap size is out of limitation\n");
+			return -EINVAL;
+		}
+		addr = PCIE_RK3588_RC_DBI_BASE;
+		break;
+	case PCIE_EP_MMAP_RESOURCE_BAR0:
+		bar_size = pci_resource_len(dev, 0);
+		if (size > bar_size) {
+			dev_warn(&pcie_rkep->pdev->dev, "bar0 mmap size is out of limitation\n");
+			return -EINVAL;
+		}
+		addr = pci_resource_start(dev, 0);
+		break;
+	case PCIE_EP_MMAP_RESOURCE_BAR2:
+		bar_size = pci_resource_len(dev, 2);
+		if (size > bar_size) {
+			dev_warn(&pcie_rkep->pdev->dev, "bar2 mmap size is out of limitation\n");
+			return -EINVAL;
+		}
+		addr = pci_resource_start(dev, 2);
+		break;
+	case PCIE_EP_MMAP_RESOURCE_BAR4:
+		bar_size = pci_resource_len(dev, 4);
+		if (size > bar_size) {
+			dev_warn(&pcie_rkep->pdev->dev, "bar4 mmap size is out of limitation\n");
+			return -EINVAL;
+		}
+		addr = pci_resource_start(dev, 4);
+		break;
+	case PCIE_EP_MMAP_RESOURCE_USER_MEM:
+		if (size > RKEP_USER_MEM_SIZE) {
+			dev_warn(&pcie_rkep->pdev->dev, "mmap size is out of limitation\n");
+			return -EINVAL;
+		}
+
+		if (!pcie_rkep->user_pages) {
+			dev_warn(&pcie_rkep->pdev->dev, "user_pages has not been allocated yet\n");
+			return -EINVAL;
+		}
+		addr = page_to_phys(pcie_rkep->user_pages);
+		break;
+	default:
+		dev_err(&pcie_rkep->pdev->dev, "cur mmap_res %d is unsurreport\n", pcie_rkep->cur_mmap_res);
 		return -EINVAL;
 	}
 
-	if (!pcie_rkep->user_pages) {
-		dev_warn(&pcie_rkep->pdev->dev, "user_pages has not been allocated yet\n");
-		return -EINVAL;
-	}
-
-	addr = page_to_phys(pcie_rkep->user_pages);
 	vma->vm_flags |= VM_IO;
-	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+	vma->vm_flags |= (VM_DONTEXPAND | VM_DONTDUMP);
 
-	if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, size, vma->vm_page_prot)) {
-		dev_err(&pcie_rkep->pdev->dev, "io_remap_pfn_range failed\n");
+	if (pcie_rkep->cur_mmap_res == PCIE_EP_MMAP_RESOURCE_BAR2 ||
+	    pcie_rkep->cur_mmap_res == PCIE_EP_MMAP_RESOURCE_USER_MEM)
+		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+	else
+		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+	err = remap_pfn_range(vma, vma->vm_start,
+			      __phys_to_pfn(addr),
+			      size, vma->vm_page_prot);
+	if (err)
 		return -EAGAIN;
-	}
 
 	return 0;
 }
@@ -242,11 +565,15 @@
 static long pcie_rkep_ioctl(struct file *file, unsigned int cmd, unsigned long args)
 {
 	void __user *argp;
-	struct miscdevice *miscdev = file->private_data;
-	struct pcie_rkep *pcie_rkep = container_of(miscdev, struct pcie_rkep, dev);
+	struct pcie_file *pcie_file = file->private_data;
+	struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep;
 	struct pcie_ep_dma_cache_cfg cfg;
+	struct pcie_ep_dma_block_req dma;
 	void __user *uarg = (void __user *)args;
+	struct pcie_ep_obj_poll_virtual_id_cfg poll_cfg;
+	int mmap_res;
 	int ret;
+	int index;
 	u64 addr;
 
 	argp = (void __user *)args;
@@ -265,7 +592,8 @@
 	case PCIE_DMA_CACHE_INVALIDE:
 		ret = copy_from_user(&cfg, uarg, sizeof(cfg));
 		if (ret) {
-			dev_err(&pcie_rkep->pdev->dev, "failed to get copy from\n");
+			dev_err(&pcie_rkep->pdev->dev,
+				"failed to get invalid cfg copy from userspace\n");
 			return -EFAULT;
 		}
 		dma_sync_single_for_cpu(&pcie_rkep->pdev->dev, cfg.addr, cfg.size, DMA_FROM_DEVICE);
@@ -273,11 +601,108 @@
 	case PCIE_DMA_CACHE_FLUSH:
 		ret = copy_from_user(&cfg, uarg, sizeof(cfg));
 		if (ret) {
-			dev_err(&pcie_rkep->pdev->dev, "failed to get copy from\n");
+			dev_err(&pcie_rkep->pdev->dev,
+				"failed to get flush cfg copy from userspace\n");
 			return -EFAULT;
 		}
 		dma_sync_single_for_device(&pcie_rkep->pdev->dev, cfg.addr, cfg.size,
 					   DMA_TO_DEVICE);
+		break;
+	case PCIE_EP_DMA_XFER_BLOCK:
+		ret = copy_from_user(&dma, uarg, sizeof(dma));
+		if (ret) {
+			dev_err(&pcie_rkep->pdev->dev,
+				"failed to get dma_data copy from userspace\n");
+			return -EFAULT;
+		}
+		ret = rkep_ep_dma_xfer(pcie_rkep, &dma);
+		if (ret) {
+			dev_err(&pcie_rkep->pdev->dev, "failed to transfer dma, ret=%d\n", ret);
+			return -EFAULT;
+		}
+		break;
+	case PCIE_EP_REQUEST_VIRTUAL_ID:
+		index = rkep_ep_request_virtual_id(pcie_file);
+		if (index < 0) {
+			dev_err(&pcie_rkep->pdev->dev,
+				"request virtual id failed, ret=%d\n", index);
+
+			return -EFAULT;
+		}
+		if (copy_to_user(argp, &index, sizeof(index)))
+			return -EFAULT;
+		break;
+	case PCIE_EP_RELEASE_VIRTUAL_ID:
+		ret = copy_from_user(&index, uarg, sizeof(index));
+		if (ret) {
+			dev_err(&pcie_rkep->pdev->dev,
+				"failed to get release data copy from userspace\n");
+			return -EFAULT;
+		}
+		ret = rkep_ep_release_virtual_id(pcie_file, index);
+		if (ret < 0) {
+			dev_err(&pcie_rkep->pdev->dev,
+				"release virtual id %d failed, ret=%d\n", index, ret);
+
+			return -EFAULT;
+		}
+		break;
+	case PCIE_EP_RAISE_IRQ_USER:
+		ret = copy_from_user(&index, uarg, sizeof(index));
+		if (ret) {
+			dev_err(&pcie_rkep->pdev->dev,
+				"failed to get raise irq data copy from userspace\n");
+			return -EFAULT;
+		}
+
+		ret = rkep_ep_raise_irq_user_obj(pcie_file, index);
+		if (ret < 0)
+			return -EFAULT;
+		break;
+	case PCIE_EP_POLL_IRQ_USER:
+		ret = copy_from_user(&poll_cfg, uarg, sizeof(poll_cfg));
+		if (ret) {
+			dev_err(&pcie_rkep->pdev->dev,
+				"failed to get poll irq data copy from userspace\n");
+
+			return -EFAULT;
+		}
+
+		ret = rkep_ep_poll_irq_user(pcie_file, &poll_cfg);
+		if (ret < 0)
+			return -EFAULT;
+
+		if (copy_to_user(argp, &poll_cfg, sizeof(poll_cfg)))
+			return -EFAULT;
+		break;
+	case PCIE_EP_RAISE_ELBI:
+		ret = copy_from_user(&index, uarg, sizeof(index));
+		if (ret) {
+			dev_err(&pcie_rkep->pdev->dev,
+				"failed to get raise elbi data copy from userspace\n");
+			return -EFAULT;
+		}
+		ret = rkep_ep_raise_elbi_irq(pcie_file, index);
+		if (ret < 0) {
+			dev_err(&pcie_rkep->pdev->dev,
+				"raise elbi %d failed, ret=%d\n", index, ret);
+
+			return -EFAULT;
+		}
+		break;
+	case PCIE_EP_SET_MMAP_RESOURCE:
+		ret = copy_from_user(&mmap_res, uarg, sizeof(mmap_res));
+		if (ret) {
+			dev_err(&pcie_rkep->pdev->dev, "failed to get copy from\n");
+			return -EFAULT;
+		}
+
+		if (mmap_res >= PCIE_EP_MMAP_RESOURCE_MAX || mmap_res < 0) {
+			dev_err(&pcie_rkep->pdev->dev, "mmap index %d is out of number\n", mmap_res);
+			return -EINVAL;
+		}
+
+		pcie_rkep->cur_mmap_res = mmap_res;
 		break;
 	default:
 		break;
@@ -293,9 +718,8 @@
 	.read		= pcie_rkep_read,
 	.unlocked_ioctl = pcie_rkep_ioctl,
 	.mmap		= pcie_rkep_mmap,
-	.fasync		= pcie_rkep_fasync,
 	.release	= pcie_rkep_release,
-	.llseek		= no_llseek,
+	.llseek		= default_llseek,
 };
 
 static inline void pcie_rkep_writel_dbi(struct pcie_rkep *pcie_rkep, u32 reg, u32 val)
@@ -308,29 +732,115 @@
 	return readl(pcie_rkep->bar4 + reg);
 }
 
+static void pcie_rkep_dma_debug(struct dma_trx_obj *obj, struct dma_table *table)
+{
+	struct pci_dev *pdev = container_of(obj->dev, struct pci_dev, dev);
+	struct pcie_rkep *pcie_rkep = pci_get_drvdata(pdev);
+	unsigned int ctr_off = PCIE_DMA_OFFSET + table->chn * 0x200;
+
+	dev_err(&pdev->dev, "chnl=%x\n", table->start.chnl);
+	dev_err(&pdev->dev, "%s\n", table->dir == DMA_FROM_BUS ? "udma read" : "udma write");
+	if (table->dma_mode == RK_PCIE_DMA_BLOCK) {
+		dev_err(&pdev->dev, "src=0x%x %x\n", table->ctx_reg.sarptrhi, table->ctx_reg.sarptrlo);
+		dev_err(&pdev->dev, "dst=0x%x %x\n", table->ctx_reg.darptrhi, table->ctx_reg.darptrlo);
+	} else {
+		dev_err(&pdev->dev, "phys_descs=0x%llx\n", table->phys_descs);
+	}
+	dev_err(&pdev->dev, "xfersize=%x\n", table->ctx_reg.xfersize);
+
+	if (table->dir == DMA_FROM_BUS) {
+		if (table->dma_mode == RK_PCIE_DMA_BLOCK) {
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_INT_MASK = %x\n", PCIE_DMA_RD_INT_MASK, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_INT_MASK));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_ENB = %x\n", PCIE_DMA_RD_ENB, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_ENB));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_CTRL_LO = %x\n", ctr_off + PCIE_DMA_RD_CTRL_LO, pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_LO));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_CTRL_HI = %x\n", ctr_off + PCIE_DMA_RD_CTRL_HI,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_HI));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_XFERSIZE = %x\n", ctr_off + PCIE_DMA_RD_XFERSIZE,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_XFERSIZE));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_SAR_PTR_LO = %x\n", ctr_off + PCIE_DMA_RD_SAR_PTR_LO,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_SAR_PTR_LO));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_SAR_PTR_HI = %x\n", ctr_off + PCIE_DMA_RD_SAR_PTR_HI,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_SAR_PTR_HI));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_DAR_PTR_LO = %x\n", ctr_off + PCIE_DMA_RD_DAR_PTR_LO,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_DAR_PTR_LO));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_DAR_PTR_HI = %x\n", ctr_off + PCIE_DMA_RD_DAR_PTR_HI,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_DAR_PTR_HI));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_DOORBELL = %x\n", PCIE_DMA_RD_DOORBELL, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_DOORBELL));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_INT_STATUS = %x\n", PCIE_DMA_RD_INT_STATUS, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_INT_STATUS));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_ERR_STATUS_LOW = %x\n", PCIE_DMA_RD_ERR_STATUS_LOW, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_ERR_STATUS_LOW));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_ERR_STATUS_HIGH = %x\n", PCIE_DMA_RD_ERR_STATUS_HIGH, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_ERR_STATUS_HIGH));
+		} else {
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_INT_MASK = %x\n", PCIE_DMA_RD_INT_MASK, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_INT_MASK));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_ENB = %x\n", PCIE_DMA_RD_ENB, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_ENB));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_CTRL_LO = %x\n", ctr_off + PCIE_DMA_RD_CTRL_LO, pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_LO));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_CTRL_HI = %x\n", ctr_off + PCIE_DMA_RD_CTRL_HI,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_HI));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_LL_PTR_LO = %x\n", ctr_off + PCIE_DMA_RD_LL_PTR_LO,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_LL_PTR_LO));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_LL_PTR_HI = %x\n", ctr_off + PCIE_DMA_RD_LL_PTR_HI,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_LL_PTR_HI));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_DOORBELL = %x\n", PCIE_DMA_RD_DOORBELL, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_DOORBELL));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_ERR_STATUS_LOW = %x\n", PCIE_DMA_RD_ERR_STATUS_LOW, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_ERR_STATUS_LOW));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_ERR_STATUS_HIGH = %x\n", PCIE_DMA_RD_ERR_STATUS_HIGH, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_ERR_STATUS_HIGH));
+		}
+	} else {
+		if (table->dma_mode == RK_PCIE_DMA_BLOCK) {
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_INT_MASK = %x\n", PCIE_DMA_WR_INT_MASK, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_MASK));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_ENB = %x\n", PCIE_DMA_WR_ENB, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_ENB));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_CTRL_LO = %x\n", ctr_off + PCIE_DMA_WR_CTRL_LO, pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_LO));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_CTRL_HI = %x\n", ctr_off + PCIE_DMA_WR_CTRL_HI,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_HI));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_XFERSIZE = %x\n", ctr_off + PCIE_DMA_WR_XFERSIZE,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_XFERSIZE));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_SAR_PTR_LO = %x\n", ctr_off + PCIE_DMA_WR_SAR_PTR_LO,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_SAR_PTR_LO));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_SAR_PTR_HI = %x\n", ctr_off + PCIE_DMA_WR_SAR_PTR_HI,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_SAR_PTR_HI));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_DAR_PTR_LO = %x\n", ctr_off + PCIE_DMA_WR_DAR_PTR_LO,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_DAR_PTR_LO));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_DAR_PTR_HI = %x\n", ctr_off + PCIE_DMA_WR_DAR_PTR_HI,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_DAR_PTR_HI));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_DOORBELL = %x\n", PCIE_DMA_WR_DOORBELL, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_DOORBELL));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_INT_STATUS = %x\n", PCIE_DMA_WR_INT_STATUS, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_STATUS));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_ERR_STATUS = %x\n", PCIE_DMA_WR_ERR_STATUS, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_ERR_STATUS));
+		} else {
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_INT_MASK = %x\n", PCIE_DMA_WR_INT_MASK, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_MASK));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_ENB = %x\n", PCIE_DMA_WR_ENB, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_ENB));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_CTRL_LO = %x\n", ctr_off + PCIE_DMA_WR_CTRL_LO, pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_LO));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_CTRL_HI = %x\n", ctr_off + PCIE_DMA_WR_CTRL_HI,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_HI));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_LL_PTR_LO = %x\n", ctr_off + PCIE_DMA_WR_LL_PTR_LO,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_LL_PTR_LO));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_LL_PTR_HI = %x\n", ctr_off + PCIE_DMA_WR_LL_PTR_HI,  pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_LL_PTR_HI));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_DOORBELL = %x\n", PCIE_DMA_WR_DOORBELL, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_DOORBELL));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_INT_STATUS = %x\n", PCIE_DMA_WR_INT_STATUS, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_STATUS));
+			dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_ERR_STATUS = %x\n", PCIE_DMA_WR_ERR_STATUS, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_ERR_STATUS));
+		}
+	}
+}
+
 static void pcie_rkep_start_dma_rd(struct dma_trx_obj *obj, struct dma_table *cur, int ctr_off)
 {
 	struct pci_dev *pdev = container_of(obj->dev, struct pci_dev, dev);
 	struct pcie_rkep *pcie_rkep = pci_get_drvdata(pdev);
 
-	pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_ENB,
-			     cur->enb.asdword);
-	pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_LO,
-			     cur->ctx_reg.ctrllo.asdword);
-	pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_HI,
-			     cur->ctx_reg.ctrlhi.asdword);
-	pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_XFERSIZE,
-			     cur->ctx_reg.xfersize);
-	pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_SAR_PTR_LO,
-			     cur->ctx_reg.sarptrlo);
-	pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_SAR_PTR_HI,
-			     cur->ctx_reg.sarptrhi);
-	pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_DAR_PTR_LO,
-			     cur->ctx_reg.darptrlo);
-	pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_DAR_PTR_HI,
-			     cur->ctx_reg.darptrhi);
-	pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_DOORBELL,
-			     cur->start.asdword);
+	if (cur->dma_mode == RK_PCIE_DMA_BLOCK) {
+		pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_ENB,
+				cur->enb.asdword);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_LO,
+				cur->ctx_reg.ctrllo.asdword);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_HI,
+				cur->ctx_reg.ctrlhi.asdword);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_XFERSIZE,
+				cur->ctx_reg.xfersize);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_SAR_PTR_LO,
+				cur->ctx_reg.sarptrlo);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_SAR_PTR_HI,
+				cur->ctx_reg.sarptrhi);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_DAR_PTR_LO,
+				cur->ctx_reg.darptrlo);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_DAR_PTR_HI,
+				cur->ctx_reg.darptrhi);
+		pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_DOORBELL,
+				cur->start.asdword);
+	} else {
+		pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_ENB,
+				cur->enb.asdword);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_LO,
+				cur->ctx_reg.ctrllo.asdword);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_HI,
+				cur->ctx_reg.ctrlhi.asdword);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_LL_PTR_LO,
+				lower_32_bits(cur->phys_descs));
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_LL_PTR_HI,
+				upper_32_bits(cur->phys_descs));
+		pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_DOORBELL,
+				cur->start.asdword);
+	}
+	/* pcie_rkep_dma_debug(obj, cur); */
 }
 
 static void pcie_rkep_start_dma_wr(struct dma_trx_obj *obj, struct dma_table *cur, int ctr_off)
@@ -338,26 +848,42 @@
 	struct pci_dev *pdev = container_of(obj->dev, struct pci_dev, dev);
 	struct pcie_rkep *pcie_rkep = pci_get_drvdata(pdev);
 
-	pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_ENB,
-			     cur->enb.asdword);
-	pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_LO,
-			     cur->ctx_reg.ctrllo.asdword);
-	pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_HI,
-			     cur->ctx_reg.ctrlhi.asdword);
-	pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_XFERSIZE,
-			     cur->ctx_reg.xfersize);
-	pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_SAR_PTR_LO,
-			     cur->ctx_reg.sarptrlo);
-	pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_SAR_PTR_HI,
-			     cur->ctx_reg.sarptrhi);
-	pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_DAR_PTR_LO,
-			     cur->ctx_reg.darptrlo);
-	pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_DAR_PTR_HI,
-			     cur->ctx_reg.darptrhi);
-	pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_WEILO,
-			     cur->weilo.asdword);
-	pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_DOORBELL,
-			     cur->start.asdword);
+	if (cur->dma_mode == RK_PCIE_DMA_BLOCK) {
+		pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_ENB,
+				cur->enb.asdword);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_LO,
+				cur->ctx_reg.ctrllo.asdword);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_HI,
+				cur->ctx_reg.ctrlhi.asdword);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_XFERSIZE,
+				cur->ctx_reg.xfersize);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_SAR_PTR_LO,
+				cur->ctx_reg.sarptrlo);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_SAR_PTR_HI,
+				cur->ctx_reg.sarptrhi);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_DAR_PTR_LO,
+				cur->ctx_reg.darptrlo);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_DAR_PTR_HI,
+				cur->ctx_reg.darptrhi);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_WEILO,
+				cur->weilo.asdword);
+		pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_DOORBELL,
+				cur->start.asdword);
+	} else {
+		pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_ENB,
+				cur->enb.asdword);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_LO,
+				cur->ctx_reg.ctrllo.asdword);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_HI,
+				cur->ctx_reg.ctrlhi.asdword);
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_LL_PTR_LO,
+				lower_32_bits(cur->phys_descs));
+		pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_LL_PTR_HI,
+				upper_32_bits(cur->phys_descs));
+		pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_DOORBELL,
+				cur->start.asdword);
+	}
+	/* pcie_rkep_dma_debug(obj, cur); */
 }
 
 static void pcie_rkep_start_dma_dwc(struct dma_trx_obj *obj, struct dma_table *table)
@@ -375,26 +901,36 @@
 
 static void pcie_rkep_config_dma_dwc(struct dma_table *table)
 {
-	table->enb.enb = 0x1;
-	table->ctx_reg.ctrllo.lie = 0x1;
-	table->ctx_reg.ctrllo.rie = 0x0;
-	table->ctx_reg.ctrllo.td = 0x1;
-	table->ctx_reg.ctrlhi.asdword = 0x0;
-	table->ctx_reg.xfersize = table->buf_size;
-	if (table->dir == DMA_FROM_BUS) {
-		table->ctx_reg.sarptrlo = (u32)(table->bus & 0xffffffff);
-		table->ctx_reg.sarptrhi = (u32)(table->bus >> 32);
-		table->ctx_reg.darptrlo = (u32)(table->local & 0xffffffff);
-		table->ctx_reg.darptrhi = (u32)(table->local >> 32);
-	} else if (table->dir == DMA_TO_BUS) {
-		table->ctx_reg.sarptrlo = (u32)(table->local & 0xffffffff);
-		table->ctx_reg.sarptrhi = (u32)(table->local >> 32);
-		table->ctx_reg.darptrlo = (u32)(table->bus & 0xffffffff);
-		table->ctx_reg.darptrhi = (u32)(table->bus >> 32);
+	if (table->dma_mode == RK_PCIE_DMA_BLOCK) {
+		table->enb.enb = 0x1;
+		table->ctx_reg.ctrllo.lie = 0x1;
+		table->ctx_reg.ctrllo.rie = 0x0;
+		table->ctx_reg.ctrllo.td = 0x1;
+		table->ctx_reg.ctrlhi.asdword = 0x0;
+		table->ctx_reg.xfersize = table->buf_size;
+		if (table->dir == DMA_FROM_BUS) {
+			table->ctx_reg.sarptrlo = (u32)(table->bus & 0xffffffff);
+			table->ctx_reg.sarptrhi = (u32)(table->bus >> 32);
+			table->ctx_reg.darptrlo = (u32)(table->local & 0xffffffff);
+			table->ctx_reg.darptrhi = (u32)(table->local >> 32);
+		} else if (table->dir == DMA_TO_BUS) {
+			table->ctx_reg.sarptrlo = (u32)(table->local & 0xffffffff);
+			table->ctx_reg.sarptrhi = (u32)(table->local >> 32);
+			table->ctx_reg.darptrlo = (u32)(table->bus & 0xffffffff);
+			table->ctx_reg.darptrhi = (u32)(table->bus >> 32);
+		}
+		table->weilo.weight0 = 0x0;
+		table->start.stop = 0x0;
+		table->start.chnl = table->chn;
+	} else {
+		table->enb.enb = 0x1;
+		table->ctx_reg.ctrllo.lie = 0x1;
+		table->ctx_reg.ctrllo.rie = 0x0;
+		table->ctx_reg.ctrllo.ccs = 1;
+		table->ctx_reg.ctrllo.llen = 1;
+		table->ctx_reg.ctrlhi.asdword = 0x0;
+		table->start.chnl = table->chn;
 	}
-	table->weilo.weight0 = 0x0;
-	table->start.stop = 0x0;
-	table->start.chnl = table->chn;
 }
 
 static int pcie_rkep_get_dma_status(struct dma_trx_obj *obj, u8 chn, enum dma_dir dir)
@@ -420,7 +956,7 @@
 		}
 
 		if (status.abortsta & BIT(chn)) {
-			dev_err(&pdev->dev, "%s, write abort\n", __func__);
+			dev_err(&pdev->dev, "%s, write abort %x\n", __func__, status.asdword);
 			clears.abortclr = BIT(chn);
 			pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_CLEAR,
 					     clears.asdword);
@@ -455,8 +991,8 @@
 	u32 irq_type;
 	u32 chn;
 	union int_clear clears;
+	u32 reg;
 
-	kill_fasync(&pcie_rkep->async, SIGIO, POLL_IN);
 	irq_type = pcie_rkep->obj_info->irq_type_rc;
 	if (irq_type == OBJ_IRQ_DMA) {
 		/* DMA helper */
@@ -499,122 +1035,77 @@
 				}
 			}
 		}
+	} else if (irq_type == OBJ_IRQ_USER) {
+		reg = pcie_rkep->obj_info->irq_user_data_rc;
+		if (reg < RKEP_EP_VIRTUAL_ID_MAX) {
+			set_bit(reg, pcie_rkep->virtual_id_irq_bitmap);
+			wake_up_interruptible(&pcie_rkep->wq_head);
+		}
 	}
 
 	return 0;
 }
 
-static int __maybe_unused rockchip_pcie_raise_elbi_irq(struct pcie_rkep *pcie_rkep,
-						       u8 interrupt_num)
-{
-	u32 index, off;
-
-	if (interrupt_num >= (PCIE_ELBI_REG_NUM * 16)) {
-		dev_err(&pcie_rkep->pdev->dev, "elbi int num out of max count\n");
-		return -EINVAL;
-	}
-
-	index = interrupt_num / 16;
-	off = interrupt_num % 16;
-	return pci_write_config_dword(pcie_rkep->pdev, PCIE_CFG_ELBI_APP_OFFSET + 4 * index,
-				      (1 << (off + 16)) | (1 << off));
-}
-
 static irqreturn_t pcie_rkep_pcie_interrupt(int irq, void *context)
 {
-	struct pcie_rkep_msix_context *ctx = context;
+	struct pcie_rkep_irq_context *ctx = context;
 	struct pci_dev *pdev = ctx->dev;
 	struct pcie_rkep *pcie_rkep = pci_get_drvdata(pdev);
 
 	if (!pcie_rkep)
 		return IRQ_HANDLED;
 
-	if (pcie_rkep->msix_enable)
-		dev_info(&pdev->dev, "MSI-X is triggered for 0x%x\n", ctx->msg_id);
-
-	else /* pcie_rkep->msi_enable */ {
-		/*
-		 * The msi 0 is the dedicated interrupt for obj to issue remote rc device.
-		 */
-		if (irq == pci_irq_vector(pcie_rkep->pdev, PCIe_CLIENT_MSI_IRQ_OBJ))
-			pcie_rkep_obj_handler(pcie_rkep, pdev);
-	}
+	/*
+	 * The irq 0 is the dedicated interrupt for obj to issue remote rc device.
+	 */
+	if (irq == pci_irq_vector(pcie_rkep->pdev, PCIe_CLIENT_MSI_IRQ_OBJ))
+		pcie_rkep_obj_handler(pcie_rkep, pdev);
 
 	return IRQ_HANDLED;
 }
 
-static int __maybe_unused pcie_rkep_request_msi_irq(struct pcie_rkep *pcie_rkep)
+static void pcie_rkep_release_irq(struct pcie_rkep *pcie_rkep)
 {
-	int nvec, ret = -EINVAL, i, j;
+	int i;
+
+	if (pcie_rkep->irq_valid) {
+		for (i = 0; i < pcie_rkep->irq_valid; i++)
+			pci_free_irq(pcie_rkep->pdev, i, &pcie_rkep->irq_ctx[i]);
+
+		pci_free_irq_vectors(pcie_rkep->pdev);
+	}
+	pcie_rkep->irq_valid = 0;
+}
+
+static int pcie_rkep_request_irq(struct pcie_rkep *pcie_rkep, u32 irq_type)
+{
+	int nvec, ret = -EINVAL, i;
 
 	/* Using msi as default */
-	nvec = pci_alloc_irq_vectors(pcie_rkep->pdev, 1, RKEP_NUM_MSI_VECTORS, PCI_IRQ_MSI);
+	nvec = pci_alloc_irq_vectors(pcie_rkep->pdev, 1, RKEP_NUM_IRQ_VECTORS, irq_type);
 	if (nvec < 0)
 		return nvec;
 
-	if (nvec != RKEP_NUM_MSI_VECTORS)
-		dev_err(&pcie_rkep->pdev->dev, "only allocate %d msi interrupt\n", nvec);
+	if (nvec != RKEP_NUM_IRQ_VECTORS)
+		dev_err(&pcie_rkep->pdev->dev, "only allocate %d irq interrupt, irq_type=%d\n", nvec, irq_type);
 
+	pcie_rkep->irq_valid = 0;
 	for (i = 0; i < nvec; i++) {
-		pcie_rkep->msi_ctx[i].dev = pcie_rkep->pdev;
-		pcie_rkep->msi_ctx[i].msg_id = i;
-		pcie_rkep->msi_ctx[i].name =
-			devm_kzalloc(&pcie_rkep->pdev->dev, RKEP_NUM_MSIX_VECTORS, GFP_KERNEL);
-		sprintf(pcie_rkep->msi_ctx[i].name, "%s-%d\n", pcie_rkep->dev.name, i);
-		ret = request_irq(pci_irq_vector(pcie_rkep->pdev, i),
-				  pcie_rkep_pcie_interrupt, IRQF_SHARED,
-				  pcie_rkep->msi_ctx[i].name, &pcie_rkep->msi_ctx[i]);
+		pcie_rkep->irq_ctx[i].dev = pcie_rkep->pdev;
+		pcie_rkep->irq_ctx[i].msg_id = i;
+		ret = pci_request_irq(pcie_rkep->pdev, i,
+				      pcie_rkep_pcie_interrupt, NULL,
+				      &pcie_rkep->irq_ctx[i], "%s-%d", pcie_rkep->dev.name, i);
 		if (ret)
 			break;
+		pcie_rkep->irq_valid++;
 	}
 
 	if (ret) {
-		for (j = 0; j < i; j++)
-			free_irq(pci_irq_vector(pcie_rkep->pdev, j), &pcie_rkep->msi_ctx[j]);
-		pci_disable_msi(pcie_rkep->pdev);
+		pcie_rkep_release_irq(pcie_rkep);
 		dev_err(&pcie_rkep->pdev->dev, "fail to allocate msi interrupt\n");
 	} else {
-		pcie_rkep->msi_enable = true;
 		dev_err(&pcie_rkep->pdev->dev, "success to request msi irq\n");
-	}
-
-	return ret;
-}
-
-static int __maybe_unused pcie_rkep_request_msix_irq(struct pcie_rkep *pcie_rkep)
-{
-	int ret, i, j;
-
-	for (i = 0; i < RKEP_NUM_MSIX_VECTORS; i++)
-		pcie_rkep->msix_entries[i].entry = i;
-
-	ret = pci_enable_msix_exact(pcie_rkep->pdev, pcie_rkep->msix_entries,
-				    RKEP_NUM_MSIX_VECTORS);
-	if (ret)
-		return ret;
-
-	for (i = 0; i < RKEP_NUM_MSIX_VECTORS; i++) {
-		pcie_rkep->msix_ctx[i].dev = pcie_rkep->pdev;
-		pcie_rkep->msix_ctx[i].msg_id = i;
-		pcie_rkep->msix_ctx[i].name =
-			devm_kzalloc(&pcie_rkep->pdev->dev, RKEP_NUM_MSIX_VECTORS, GFP_KERNEL);
-		sprintf(pcie_rkep->msix_ctx[i].name, "%s-%d\n", pcie_rkep->dev.name, i);
-		ret = request_irq(pcie_rkep->msix_entries[i].vector,
-				  pcie_rkep_pcie_interrupt, 0, pcie_rkep->msix_ctx[i].name,
-				  &pcie_rkep->msix_ctx[i]);
-
-		if (ret)
-			break;
-	}
-
-	if (ret) {
-		for (j = 0; j < i; j++)
-			free_irq(pcie_rkep->msix_entries[j].vector, &pcie_rkep->msix_ctx[j]);
-		pci_disable_msix(pcie_rkep->pdev);
-		dev_err(&pcie_rkep->pdev->dev, "fail to allocate msi-x interrupt\n");
-	} else {
-		pcie_rkep->msix_enable = true;
-		dev_err(&pcie_rkep->pdev->dev, "success to request msi-x irq\n");
 	}
 
 	return ret;
@@ -637,7 +1128,7 @@
 	dev_info(dev, "%s file %s size %lld to %p\n", __func__, path, size, bar + pos);
 
 	offset = 0;
-	kernel_read(p_file, bar + pos, size, &offset);
+	kernel_read(p_file, (void *)bar + pos, (size_t)size, (loff_t *)&offset);
 
 	dev_info(dev, "kernel_read size %lld from %s to %p\n", size, path, bar + pos);
 
@@ -670,14 +1161,21 @@
 
 static int pcie_rkep_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-	int ret, i;
+	int ret;
 	struct pcie_rkep *pcie_rkep;
 	u8 *name;
 	u16 val;
+	bool dmatest_irq = false;
 
 	pcie_rkep = devm_kzalloc(&pdev->dev, sizeof(*pcie_rkep), GFP_KERNEL);
 	if (!pcie_rkep)
 		return -ENOMEM;
+
+	name = devm_kzalloc(&pdev->dev, MISC_DEV_NAME_MAX_LENGTH, GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+
+	set_bit(0, pcie_rkep->virtual_id_bitmap);
 
 	ret = pci_enable_device(pdev);
 	if (ret) {
@@ -717,16 +1215,13 @@
 
 	dev_dbg(&pdev->dev, "get bar4 address is %p\n", pcie_rkep->bar4);
 
-	name = devm_kzalloc(&pdev->dev, MISC_DEV_NAME_MAX_LENGTH, GFP_KERNEL);
-	if (!name) {
-		ret = -ENOMEM;
-		goto err_pci_iomap;
-	}
 	sprintf(name, "%s-%s", DRV_NAME, dev_name(&pdev->dev));
 	pcie_rkep->dev.minor = MISC_DYNAMIC_MINOR;
 	pcie_rkep->dev.name = name;
 	pcie_rkep->dev.fops = &pcie_rkep_fops;
 	pcie_rkep->dev.parent = NULL;
+
+	mutex_init(&pcie_rkep->dev_lock_mutex);
 
 	ret = misc_register(&pcie_rkep->dev);
 	if (ret) {
@@ -738,11 +1233,12 @@
 
 	pci_set_drvdata(pdev, pcie_rkep);
 
-	ret = pcie_rkep_request_msi_irq(pcie_rkep);
+	init_waitqueue_head(&pcie_rkep->wq_head);
+	ret = pcie_rkep_request_irq(pcie_rkep, PCI_IRQ_MSI);
 	if (ret)
 		goto err_register_irq;
 
-	pcie_rkep->dma_obj = pcie_dw_dmatest_register(&pdev->dev, true);
+	pcie_rkep->dma_obj = pcie_dw_dmatest_register(&pdev->dev, dmatest_irq);
 	if (IS_ERR(pcie_rkep->dma_obj)) {
 		dev_err(&pcie_rkep->pdev->dev, "failed to prepare dmatest\n");
 		ret = -EINVAL;
@@ -750,9 +1246,19 @@
 	}
 
 	if (pcie_rkep->dma_obj) {
+		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
 		pcie_rkep->dma_obj->start_dma_func = pcie_rkep_start_dma_dwc;
 		pcie_rkep->dma_obj->config_dma_func = pcie_rkep_config_dma_dwc;
 		pcie_rkep->dma_obj->get_dma_status = pcie_rkep_get_dma_status;
+		pcie_rkep->dma_obj->dma_debug = pcie_rkep_dma_debug;
+		if (!dmatest_irq) {
+			pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_MASK, 0xffffffff);
+			pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_INT_MASK, 0xffffffff);
+
+			/* Enable linked list err en */
+			pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_LL_ERR_EN, 0xffffffff);
+			pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_LL_ERR_EN, 0xffffffff);
+		}
 	}
 
 #if IS_ENABLED(CONFIG_PCIE_FUNC_RKEP_USERPAGES)
@@ -761,8 +1267,11 @@
 	if (!pcie_rkep->user_pages) {
 		dev_err(&pcie_rkep->pdev->dev, "failed to allocate contiguous pages\n");
 		ret = -EINVAL;
+		if (pcie_rkep->dma_obj)
+			pcie_dw_dmatest_unregister(pcie_rkep->dma_obj);
 		goto err_register_obj;
 	}
+	pcie_rkep->cur_mmap_res = PCIE_EP_MMAP_RESOURCE_USER_MEM;
 	dev_err(&pdev->dev, "successfully allocate continuouse buffer for userspace\n");
 #endif
 
@@ -777,18 +1286,7 @@
 
 	return 0;
 err_register_obj:
-	if (pcie_rkep->msix_enable) {
-		for (i = 0; i < RKEP_NUM_MSIX_VECTORS; i++)
-			free_irq(pcie_rkep->msix_entries[i].vector, &pcie_rkep->msix_ctx[i]);
-		pci_disable_msix(pdev);
-	} else if (pcie_rkep->msi_enable) {
-		for (i = 0; i < RKEP_NUM_MSI_VECTORS; i++) {
-			if (pcie_rkep->msi_ctx[i].dev)
-				free_irq(pci_irq_vector(pdev, i), &pcie_rkep->msi_ctx[i]);
-		}
-
-		pci_disable_msi(pcie_rkep->pdev);
-	}
+	pcie_rkep_release_irq(pcie_rkep);
 err_register_irq:
 	misc_deregister(&pcie_rkep->dev);
 err_pci_iomap:
@@ -809,27 +1307,25 @@
 static void pcie_rkep_remove(struct pci_dev *pdev)
 {
 	struct pcie_rkep *pcie_rkep = pci_get_drvdata(pdev);
-	int i;
+
+	if (pcie_rkep->dma_obj)
+		pcie_dw_dmatest_unregister(pcie_rkep->dma_obj);
 
 	device_remove_file(&pdev->dev, &dev_attr_rkep);
 #if IS_ENABLED(CONFIG_PCIE_FUNC_RKEP_USERPAGES)
 	free_contig_range(page_to_pfn(pcie_rkep->user_pages), RKEP_USER_MEM_SIZE >> PAGE_SHIFT);
 #endif
-	pci_iounmap(pdev, pcie_rkep->bar0);
+	pcie_rkep_release_irq(pcie_rkep);
+
+	if (pcie_rkep->bar0)
+		pci_iounmap(pdev, pcie_rkep->bar0);
+	if (pcie_rkep->bar2)
+		pci_iounmap(pdev, pcie_rkep->bar2);
+	if (pcie_rkep->bar4)
+		pci_iounmap(pdev, pcie_rkep->bar4);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 	misc_deregister(&pcie_rkep->dev);
-
-	if (pcie_rkep->msix_enable) {
-		for (i = 0; i < RKEP_NUM_MSIX_VECTORS; i++)
-			free_irq(pcie_rkep->msix_entries[i].vector, &pcie_rkep->msix_ctx[i]);
-		pci_disable_msix(pdev);
-	} else if (pcie_rkep->msi_enable) {
-		for (i = 0; i < RKEP_NUM_MSI_VECTORS; i++)
-			if (pcie_rkep->msi_ctx[i].dev)
-				free_irq(pci_irq_vector(pdev, i), &pcie_rkep->msi_ctx[i]);
-		pci_disable_msi(pcie_rkep->pdev);
-	}
 }
 
 static const struct pci_device_id pcie_rkep_pcidev_id[] = {
diff --git a/kernel/drivers/misc/sgi-gru/grufault.c b/kernel/drivers/misc/sgi-gru/grufault.c
index 7238255..9c7d475 100644
--- a/kernel/drivers/misc/sgi-gru/grufault.c
+++ b/kernel/drivers/misc/sgi-gru/grufault.c
@@ -648,6 +648,7 @@
 	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 @@
 	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 @@
 		} 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/kernel/drivers/misc/sgi-gru/grumain.c b/kernel/drivers/misc/sgi-gru/grumain.c
index 40ac59d..e2325e3 100644
--- a/kernel/drivers/misc/sgi-gru/grumain.c
+++ b/kernel/drivers/misc/sgi-gru/grumain.c
@@ -716,9 +716,10 @@
  * 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 @@
 	 * 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 @@
 	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/kernel/drivers/misc/sgi-gru/grutables.h b/kernel/drivers/misc/sgi-gru/grutables.h
index 5ce8f30..10f0a08 100644
--- a/kernel/drivers/misc/sgi-gru/grutables.h
+++ b/kernel/drivers/misc/sgi-gru/grutables.h
@@ -637,7 +637,7 @@
 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);
diff --git a/kernel/drivers/misc/tifm_7xx1.c b/kernel/drivers/misc/tifm_7xx1.c
index 228f2eb..2aebbfd 100644
--- a/kernel/drivers/misc/tifm_7xx1.c
+++ b/kernel/drivers/misc/tifm_7xx1.c
@@ -190,7 +190,7 @@
 				spin_unlock_irqrestore(&fm->lock, flags);
 			}
 			if (sock)
-				tifm_free_device(&sock->dev);
+				put_device(&sock->dev);
 		}
 		spin_lock_irqsave(&fm->lock, flags);
 	}
diff --git a/kernel/drivers/misc/uid_sys_stats.c b/kernel/drivers/misc/uid_sys_stats.c
index 4733670..985e7b0 100644
--- a/kernel/drivers/misc/uid_sys_stats.c
+++ b/kernel/drivers/misc/uid_sys_stats.c
@@ -77,12 +77,12 @@
 #endif
 };
 
-static u64 compute_write_bytes(struct task_struct *task)
+static u64 compute_write_bytes(struct task_io_accounting *ioac)
 {
-	if (task->ioac.write_bytes <= task->ioac.cancelled_write_bytes)
+	if (ioac->write_bytes <= ioac->cancelled_write_bytes)
 		return 0;
 
-	return task->ioac.write_bytes - task->ioac.cancelled_write_bytes;
+	return ioac->write_bytes - ioac->cancelled_write_bytes;
 }
 
 static void compute_io_bucket_stats(struct io_stats *io_bucket,
@@ -239,17 +239,16 @@
 	}
 }
 
-static void add_uid_tasks_io_stats(struct uid_entry *uid_entry,
-		struct task_struct *task, int slot)
+static void add_uid_tasks_io_stats(struct task_entry *task_entry,
+				   struct task_io_accounting *ioac, int slot)
 {
-	struct task_entry *task_entry = find_or_register_task(uid_entry, task);
 	struct io_stats *task_io_slot = &task_entry->io[slot];
 
-	task_io_slot->read_bytes += task->ioac.read_bytes;
-	task_io_slot->write_bytes += compute_write_bytes(task);
-	task_io_slot->rchar += task->ioac.rchar;
-	task_io_slot->wchar += task->ioac.wchar;
-	task_io_slot->fsync += task->ioac.syscfs;
+	task_io_slot->read_bytes += ioac->read_bytes;
+	task_io_slot->write_bytes += compute_write_bytes(ioac);
+	task_io_slot->rchar += ioac->rchar;
+	task_io_slot->wchar += ioac->wchar;
+	task_io_slot->fsync += ioac->syscfs;
 }
 
 static void compute_io_uid_tasks(struct uid_entry *uid_entry)
@@ -290,8 +289,6 @@
 #else
 static void remove_uid_tasks(struct uid_entry *uid_entry) {};
 static void set_io_uid_tasks_zero(struct uid_entry *uid_entry) {};
-static void add_uid_tasks_io_stats(struct uid_entry *uid_entry,
-		struct task_struct *task, int slot) {};
 static void compute_io_uid_tasks(struct uid_entry *uid_entry) {};
 static void show_io_uid_tasks(struct seq_file *m,
 		struct uid_entry *uid_entry) {}
@@ -446,23 +443,32 @@
 	.proc_write	= uid_remove_write,
 };
 
+static void __add_uid_io_stats(struct uid_entry *uid_entry,
+			struct task_io_accounting *ioac, int slot)
+{
+	struct io_stats *io_slot = &uid_entry->io[slot];
+
+	io_slot->read_bytes += ioac->read_bytes;
+	io_slot->write_bytes += compute_write_bytes(ioac);
+	io_slot->rchar += ioac->rchar;
+	io_slot->wchar += ioac->wchar;
+	io_slot->fsync += ioac->syscfs;
+}
 
 static void add_uid_io_stats(struct uid_entry *uid_entry,
 			struct task_struct *task, int slot)
 {
-	struct io_stats *io_slot = &uid_entry->io[slot];
+	struct task_entry *task_entry __maybe_unused;
 
 	/* avoid double accounting of dying threads */
 	if (slot != UID_STATE_DEAD_TASKS && (task->flags & PF_EXITING))
 		return;
 
-	io_slot->read_bytes += task->ioac.read_bytes;
-	io_slot->write_bytes += compute_write_bytes(task);
-	io_slot->rchar += task->ioac.rchar;
-	io_slot->wchar += task->ioac.wchar;
-	io_slot->fsync += task->ioac.syscfs;
-
-	add_uid_tasks_io_stats(uid_entry, task, slot);
+#ifdef CONFIG_UID_SYS_STATS_DEBUG
+	task_entry = find_or_register_task(uid_entry, task);
+	add_uid_tasks_io_stats(task_entry, &task->ioac, slot);
+#endif
+	__add_uid_io_stats(uid_entry, &task->ioac, slot);
 }
 
 static void update_io_stats_all_locked(void)
@@ -622,6 +628,48 @@
 	.proc_write	= uid_procstat_write,
 };
 
+struct update_stats_work {
+	struct work_struct work;
+	uid_t uid;
+#ifdef CONFIG_UID_SYS_STATS_DEBUG
+	struct task_struct *task;
+#endif
+	struct task_io_accounting ioac;
+	u64 utime;
+	u64 stime;
+};
+
+static void update_stats_workfn(struct work_struct *work)
+{
+	struct update_stats_work *usw =
+		container_of(work, struct update_stats_work, work);
+	struct uid_entry *uid_entry;
+	struct task_entry *task_entry __maybe_unused;
+
+	rt_mutex_lock(&uid_lock);
+	uid_entry = find_uid_entry(usw->uid);
+	if (!uid_entry)
+		goto exit;
+
+	uid_entry->utime += usw->utime;
+	uid_entry->stime += usw->stime;
+
+#ifdef CONFIG_UID_SYS_STATS_DEBUG
+	task_entry = find_task_entry(uid_entry, usw->task);
+	if (!task_entry)
+		goto exit;
+	add_uid_tasks_io_stats(task_entry, &usw->ioac,
+			       UID_STATE_DEAD_TASKS);
+#endif
+	__add_uid_io_stats(uid_entry, &usw->ioac, UID_STATE_DEAD_TASKS);
+exit:
+	rt_mutex_unlock(&uid_lock);
+#ifdef CONFIG_UID_SYS_STATS_DEBUG
+	put_task_struct(usw->task);
+#endif
+	kfree(usw);
+}
+
 static int process_notifier(struct notifier_block *self,
 			unsigned long cmd, void *v)
 {
@@ -633,8 +681,28 @@
 	if (!task)
 		return NOTIFY_OK;
 
-	rt_mutex_lock(&uid_lock);
 	uid = from_kuid_munged(current_user_ns(), task_uid(task));
+	if (!rt_mutex_trylock(&uid_lock)) {
+		struct update_stats_work *usw;
+
+		usw = kmalloc(sizeof(struct update_stats_work), GFP_KERNEL);
+		if (usw) {
+			INIT_WORK(&usw->work, update_stats_workfn);
+			usw->uid = uid;
+#ifdef CONFIG_UID_SYS_STATS_DEBUG
+			usw->task = get_task_struct(task);
+#endif
+			/*
+			 * Copy task->ioac since task might be destroyed before
+			 * the work is later performed.
+			 */
+			usw->ioac = task->ioac;
+			task_cputime_adjusted(task, &usw->utime, &usw->stime);
+			schedule_work(&usw->work);
+		}
+		return NOTIFY_OK;
+	}
+
 	uid_entry = find_or_register_uid(uid);
 	if (!uid_entry) {
 		pr_err("%s: failed to find uid %d\n", __func__, uid);
diff --git a/kernel/drivers/misc/vmw_vmci/vmci_host.c b/kernel/drivers/misc/vmw_vmci/vmci_host.c
index 2d8328d..4a90377 100644
--- a/kernel/drivers/misc/vmw_vmci/vmci_host.c
+++ b/kernel/drivers/misc/vmw_vmci/vmci_host.c
@@ -165,10 +165,16 @@
 static __poll_t vmci_host_poll(struct file *filp, poll_table *wait)
 {
 	struct vmci_host_dev *vmci_host_dev = filp->private_data;
-	struct vmci_ctx *context = vmci_host_dev->context;
+	struct vmci_ctx *context;
 	__poll_t mask = 0;
 
 	if (vmci_host_dev->ct_type == VMCIOBJ_CONTEXT) {
+		/*
+		 * Read context only if ct_type == VMCIOBJ_CONTEXT to make
+		 * sure that context is initialized
+		 */
+		context = vmci_host_dev->context;
+
 		/* Check for VMCI calls to this VM context. */
 		if (wait)
 			poll_wait(filp, &context->host_context.wait_queue,
diff --git a/kernel/drivers/mmc/core/block.c b/kernel/drivers/mmc/core/block.c
index 5b3d6df..c533fbf 100644
--- a/kernel/drivers/mmc/core/block.c
+++ b/kernel/drivers/mmc/core/block.c
@@ -256,6 +256,7 @@
 		goto out_put;
 	}
 	req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_BOOT_WP;
+	req_to_mmc_queue_req(req)->drv_op_result = -EIO;
 	blk_execute_rq(mq->queue, NULL, req, 0);
 	ret = req_to_mmc_queue_req(req)->drv_op_result;
 	blk_put_request(req);
@@ -415,7 +416,7 @@
 static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms,
 			    u32 *resp_errs)
 {
-	unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
+	unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms > 2000 ? 2000 : timeout_ms);
 	int err = 0;
 	u32 status;
 
@@ -649,6 +650,7 @@
 	idatas[0] = idata;
 	req_to_mmc_queue_req(req)->drv_op =
 		rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL;
+	req_to_mmc_queue_req(req)->drv_op_result = -EIO;
 	req_to_mmc_queue_req(req)->drv_op_data = idatas;
 	req_to_mmc_queue_req(req)->ioc_count = 1;
 	blk_execute_rq(mq->queue, NULL, req, 0);
@@ -718,6 +720,7 @@
 	}
 	req_to_mmc_queue_req(req)->drv_op =
 		rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL;
+	req_to_mmc_queue_req(req)->drv_op_result = -EIO;
 	req_to_mmc_queue_req(req)->drv_op_data = idata;
 	req_to_mmc_queue_req(req)->ioc_count = num_of_cmds;
 	blk_execute_rq(mq->queue, NULL, req, 0);
@@ -1781,8 +1784,15 @@
 	 * bytes transferred to zero in that case.
 	 */
 	err = __mmc_send_status(card, &status, 0);
-	if (err || mmc_blk_status_error(req, status))
+	if (err || mmc_blk_status_error(req, status)) {
 		brq->data.bytes_xfered = 0;
+		if (mmc_card_sd(card) && !mmc_card_removed(card)) {
+			mmc_blk_reset_success(mq->blkdata, type);
+			if (!mmc_blk_reset(md, card->host, type))
+				return;
+			pr_err("%s: pre recovery failed!\n", req->rq_disk->disk_name);
+		}
+	}
 
 	mmc_retune_release(card->host);
 
@@ -1996,14 +2006,14 @@
 	mmc_blk_urgent_bkops(mq, mqrq);
 }
 
-static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, struct request *req)
+static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, enum mmc_issue_type issue_type)
 {
 	unsigned long flags;
 	bool put_card;
 
 	spin_lock_irqsave(&mq->lock, flags);
 
-	mq->in_flight[mmc_issue_type(mq, req)] -= 1;
+	mq->in_flight[issue_type] -= 1;
 
 	put_card = (mmc_tot_in_flight(mq) == 0);
 
@@ -2015,6 +2025,7 @@
 
 static void mmc_blk_mq_post_req(struct mmc_queue *mq, struct request *req)
 {
+	enum mmc_issue_type issue_type = mmc_issue_type(mq, req);
 	struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
 	struct mmc_request *mrq = &mqrq->brq.mrq;
 	struct mmc_host *host = mq->card->host;
@@ -2030,7 +2041,7 @@
 	else if (likely(!blk_should_fake_timeout(req->q)))
 		blk_mq_complete_request(req);
 
-	mmc_blk_mq_dec_in_flight(mq, req);
+	mmc_blk_mq_dec_in_flight(mq, issue_type);
 }
 
 void mmc_blk_mq_recovery(struct mmc_queue *mq)
@@ -2768,6 +2779,7 @@
 	if (IS_ERR(req))
 		return PTR_ERR(req);
 	req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_GET_CARD_STATUS;
+	req_to_mmc_queue_req(req)->drv_op_result = -EIO;
 	blk_execute_rq(mq->queue, NULL, req, 0);
 	ret = req_to_mmc_queue_req(req)->drv_op_result;
 	if (ret >= 0) {
@@ -2806,6 +2818,7 @@
 		goto out_free;
 	}
 	req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_GET_EXT_CSD;
+	req_to_mmc_queue_req(req)->drv_op_result = -EIO;
 	req_to_mmc_queue_req(req)->drv_op_data = &ext_csd;
 	blk_execute_rq(mq->queue, NULL, req, 0);
 	err = req_to_mmc_queue_req(req)->drv_op_result;
diff --git a/kernel/drivers/mmc/core/host.c b/kernel/drivers/mmc/core/host.c
index 10116f7..86c02ff 100644
--- a/kernel/drivers/mmc/core/host.c
+++ b/kernel/drivers/mmc/core/host.c
@@ -516,6 +516,32 @@
 
 EXPORT_SYMBOL(mmc_alloc_host);
 
+static void devm_mmc_host_release(struct device *dev, void *res)
+{
+	mmc_free_host(*(struct mmc_host **)res);
+}
+
+struct mmc_host *devm_mmc_alloc_host(struct device *dev, int extra)
+{
+	struct mmc_host **dr, *host;
+
+	dr = devres_alloc(devm_mmc_host_release, sizeof(*dr), GFP_KERNEL);
+	if (!dr)
+		return ERR_PTR(-ENOMEM);
+
+	host = mmc_alloc_host(extra, dev);
+	if (IS_ERR(host)) {
+		devres_free(dr);
+		return host;
+	}
+
+	*dr = host;
+	devres_add(dev, dr);
+
+	return host;
+}
+EXPORT_SYMBOL(devm_mmc_alloc_host);
+
 static int mmc_validate_host_caps(struct mmc_host *host)
 {
 	if (host->caps & MMC_CAP_SDIO_IRQ && !host->ops->enable_sdio_irq) {
diff --git a/kernel/drivers/mmc/core/quirks.h b/kernel/drivers/mmc/core/quirks.h
index 88b654a..cdcddae 100644
--- a/kernel/drivers/mmc/core/quirks.h
+++ b/kernel/drivers/mmc/core/quirks.h
@@ -102,6 +102,20 @@
 		  MMC_QUIRK_TRIM_BROKEN),
 
 	/*
+	 * Kingston EMMC04G-M627 advertises TRIM but it does not seems to
+	 * support being used to offload WRITE_ZEROES.
+	 */
+	MMC_FIXUP("M62704", CID_MANFID_KINGSTON, 0x0100, add_quirk_mmc,
+		  MMC_QUIRK_TRIM_BROKEN),
+
+	/*
+	 * Micron MTFC4GACAJCN-1M advertises TRIM but it does not seems to
+	 * support being used to offload WRITE_ZEROES.
+	 */
+	MMC_FIXUP("Q2J54A", CID_MANFID_MICRON, 0x014e, add_quirk_mmc,
+		  MMC_QUIRK_TRIM_BROKEN),
+
+	/*
 	 * Some SD cards reports discard support while they don't
 	 */
 	MMC_FIXUP(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, add_quirk_sd,
diff --git a/kernel/drivers/mmc/core/sdio_bus.c b/kernel/drivers/mmc/core/sdio_bus.c
index a448535..89dd492 100644
--- a/kernel/drivers/mmc/core/sdio_bus.c
+++ b/kernel/drivers/mmc/core/sdio_bus.c
@@ -295,6 +295,12 @@
 	if (!(func->card->quirks & MMC_QUIRK_NONSTD_SDIO))
 		sdio_free_func_cis(func);
 
+	/*
+	 * We have now removed the link to the tuples in the
+	 * card structure, so remove the reference.
+	 */
+	put_device(&func->card->dev);
+
 	kfree(func->info);
 	kfree(func->tmpbuf);
 	kfree(func);
@@ -324,6 +330,12 @@
 	func->card = card;
 
 	device_initialize(&func->dev);
+
+	/*
+	 * We may link to tuples in the card structure,
+	 * we need make sure we have a reference to it.
+	 */
+	get_device(&func->card->dev);
 
 	func->dev.parent = &card->dev;
 	func->dev.bus = &sdio_bus_type;
@@ -378,10 +390,9 @@
  */
 void sdio_remove_func(struct sdio_func *func)
 {
-	if (!sdio_func_present(func))
-		return;
+	if (sdio_func_present(func))
+		device_del(&func->dev);
 
-	device_del(&func->dev);
 	of_node_put(func->dev.of_node);
 	put_device(&func->dev);
 }
diff --git a/kernel/drivers/mmc/core/sdio_cis.c b/kernel/drivers/mmc/core/sdio_cis.c
index b237735..ce524f7 100644
--- a/kernel/drivers/mmc/core/sdio_cis.c
+++ b/kernel/drivers/mmc/core/sdio_cis.c
@@ -392,12 +392,6 @@
 		return ret;
 
 	/*
-	 * Since we've linked to tuples in the card structure,
-	 * we must make sure we have a reference to it.
-	 */
-	get_device(&func->card->dev);
-
-	/*
 	 * Vendor/device id is optional for function CIS, so
 	 * copy it from the card structure as needed.
 	 */
@@ -422,11 +416,5 @@
 	}
 
 	func->tuples = NULL;
-
-	/*
-	 * We have now removed the link to the tuples in the
-	 * card structure, so remove the reference.
-	 */
-	put_device(&func->card->dev);
 }
 
diff --git a/kernel/drivers/mmc/host/Kconfig b/kernel/drivers/mmc/host/Kconfig
index c40a1d4..1b642b6 100644
--- a/kernel/drivers/mmc/host/Kconfig
+++ b/kernel/drivers/mmc/host/Kconfig
@@ -521,11 +521,12 @@
 	  of Alcor Micro PCI-E card reader
 
 config MMC_AU1X
-	tristate "Alchemy AU1XX0 MMC Card Interface support"
+	bool "Alchemy AU1XX0 MMC Card Interface support"
 	depends on MIPS_ALCHEMY
+	depends on MMC=y
 	help
 	  This selects the AMD Alchemy(R) Multimedia card interface.
-	  If you have a Alchemy platform with a MMC slot, say Y or M here.
+	  If you have a Alchemy platform with a MMC slot, say Y here.
 
 	  If unsure, say N.
 
diff --git a/kernel/drivers/mmc/host/alcor.c b/kernel/drivers/mmc/host/alcor.c
index bfb8efe..d01df01 100644
--- a/kernel/drivers/mmc/host/alcor.c
+++ b/kernel/drivers/mmc/host/alcor.c
@@ -1114,7 +1114,10 @@
 	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:
diff --git a/kernel/drivers/mmc/host/atmel-mci.c b/kernel/drivers/mmc/host/atmel-mci.c
index 444bd3a..c468f9a 100644
--- a/kernel/drivers/mmc/host/atmel-mci.c
+++ b/kernel/drivers/mmc/host/atmel-mci.c
@@ -1818,7 +1818,6 @@
 				atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
 				state = STATE_WAITING_NOTBUSY;
 			} else if (host->mrq->stop) {
-				atmci_writel(host, ATMCI_IER, ATMCI_CMDRDY);
 				atmci_send_stop_cmd(host, data);
 				state = STATE_SENDING_STOP;
 			} else {
@@ -1851,8 +1850,6 @@
 				 * command to send.
 				 */
 				if (host->mrq->stop) {
-					atmci_writel(host, ATMCI_IER,
-					             ATMCI_CMDRDY);
 					atmci_send_stop_cmd(host, data);
 					state = STATE_SENDING_STOP;
 				} else {
@@ -2223,6 +2220,7 @@
 {
 	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 +2304,13 @@
 
 	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),
diff --git a/kernel/drivers/mmc/host/bcm2835.c b/kernel/drivers/mmc/host/bcm2835.c
index 8c2361e..9850799 100644
--- a/kernel/drivers/mmc/host/bcm2835.c
+++ b/kernel/drivers/mmc/host/bcm2835.c
@@ -1413,8 +1413,8 @@
 	host->max_clk = clk_get_rate(clk);
 
 	host->irq = platform_get_irq(pdev, 0);
-	if (host->irq <= 0) {
-		ret = -EINVAL;
+	if (host->irq < 0) {
+		ret = host->irq;
 		goto err;
 	}
 
diff --git a/kernel/drivers/mmc/host/dw_mmc.c b/kernel/drivers/mmc/host/dw_mmc.c
index a88d9b9..5997010 100644
--- a/kernel/drivers/mmc/host/dw_mmc.c
+++ b/kernel/drivers/mmc/host/dw_mmc.c
@@ -124,6 +124,8 @@
 EXPORT_SYMBOL(rv1106_sdmmc_put_lock);
 #endif
 
+#define RV1106_RAMDON_DATA_SIZE 508
+
 #if defined(CONFIG_DEBUG_FS)
 static int dw_mci_req_show(struct seq_file *s, void *v)
 {
@@ -525,8 +527,7 @@
 		tasklet_schedule(&host->tasklet);
 	}
 
-	if (host->need_xfer_timer &&
-	    host->dir_status == DW_MCI_RECV_STATUS)
+	if (host->need_xfer_timer)
 		del_timer(&host->xfer_timer);
 }
 
@@ -739,7 +740,7 @@
 	if (host->is_rv1106_sd && (data->flags & MMC_DATA_WRITE)) {
 		desc->des0 = desc_last->des0;
 		desc->des2 = desc_last->des2;
-		desc->des1 = 0x8; /* Random dirty data for last one desc */
+		desc->des1 = RV1106_RAMDON_DATA_SIZE; /* Random dirty data for last one desc */
 		desc_last = desc;
 	}
 
@@ -1447,13 +1448,6 @@
 		return;
 	}
 
-	if (host->is_rv1106_sd) {
-		u32 reg;
-
-		readl_poll_timeout(host->regs + SDMMC_STATUS, reg,
-				   reg & BIT(2), USEC_PER_MSEC, 500 * USEC_PER_MSEC);
-	}
-
 	spin_lock_bh(&host->lock);
 
 	if (host->is_rv1106_sd)
@@ -1549,9 +1543,11 @@
 				slot->host->vqmmc_enabled = true;
 			}
 
+#ifndef CONFIG_ROCKCHIP_THUNDER_BOOT_MMC
 			/* Reset our state machine after powering on */
 			dw_mci_ctrl_reset(slot->host,
 					  SDMMC_CTRL_ALL_RESET_FLAGS);
+#endif
 		}
 
 		/* Adjust clock / bus width after power is up */
@@ -1874,6 +1870,9 @@
 
 	WARN_ON(host->cmd || host->data);
 
+	if (host->need_xfer_timer)
+		del_timer(&host->xfer_timer);
+
 	host->slot->mrq = NULL;
 	host->mrq = NULL;
 	if (!list_empty(&host->queue)) {
@@ -2019,8 +2018,10 @@
 				   host->bus_hz);
 
 	/* add a bit spare time */
-	xfer_ms += 100;
-
+	if (host->dir_status == DW_MCI_RECV_STATUS)
+		xfer_ms += 100;
+	else
+		xfer_ms += 2500;
 	spin_lock_irqsave(&host->irq_lock, irqflags);
 	if (!test_bit(EVENT_XFER_COMPLETE, &host->pending_events))
 		mod_timer(&host->xfer_timer,
@@ -2155,6 +2156,13 @@
 					send_stop_abort(host, data);
 				dw_mci_stop_dma(host);
 				state = STATE_DATA_ERROR;
+				if (host->dir_status == DW_MCI_SEND_STATUS) {
+					data->bytes_xfered = 0;
+					data->error = -ETIMEDOUT;
+					host->data = NULL;
+					dw_mci_request_end(host, mrq);
+					goto unlock;
+				}
 				break;
 			}
 
@@ -2166,8 +2174,7 @@
 				 */
 				if (host->dir_status == DW_MCI_RECV_STATUS)
 					dw_mci_set_drto(host);
-				if (host->need_xfer_timer &&
-				    host->dir_status == DW_MCI_RECV_STATUS)
+				if (host->need_xfer_timer)
 					dw_mci_set_xfer_timeout(host);
 				break;
 			}
@@ -2209,6 +2216,8 @@
 				 */
 				if (host->dir_status == DW_MCI_RECV_STATUS)
 					dw_mci_set_drto(host);
+				if (host->need_xfer_timer && host->dir_status == DW_MCI_SEND_STATUS)
+					dw_mci_set_xfer_timeout(host);
 				break;
 			}
 
@@ -2225,8 +2234,19 @@
 				}
 
 				/* stop command for open-ended transfer*/
-				if (data->stop)
+				if (data->stop) {
+					if (host->is_rv1106_sd && (data->flags & MMC_DATA_WRITE)) {
+						int fifo_count;
+
+						if (readl_poll_timeout_atomic(host->regs + SDMMC_STATUS, fifo_count,
+								((fifo_count >> 17) & 0x7FF) <= RV1106_RAMDON_DATA_SIZE / 4,
+								0, 5000 * USEC_PER_MSEC))
+							data->error = -ETIMEDOUT;
+						udelay(1);
+						dw_mci_reset(host);
+					}
 					send_stop_abort(host, data);
+				}
 			} else {
 				/*
 				 * If we don't have a command complete now we'll
@@ -2757,8 +2777,7 @@
 			del_timer(&host->cto_timer);
 			mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS);
 			host->cmd_status = pending;
-			if ((host->need_xfer_timer) &&
-			     host->dir_status == DW_MCI_RECV_STATUS)
+			if (host->need_xfer_timer)
 				del_timer(&host->xfer_timer);
 			smp_wmb(); /* drain writebuffer */
 			set_bit(EVENT_CMD_COMPLETE, &host->pending_events);
@@ -3663,7 +3682,7 @@
 		mci_writel(host, INTMASK, ret);
 	}
 
-	if (host->slot->mmc->pm_flags & MMC_PM_KEEP_POWER)
+	if (host->slot && host->slot->mmc->pm_flags & MMC_PM_KEEP_POWER)
 		dw_mci_set_ios(host->slot->mmc, &host->slot->mmc->ios);
 
 	/* Force setup bus to guarantee available clock output */
diff --git a/kernel/drivers/mmc/host/jz4740_mmc.c b/kernel/drivers/mmc/host/jz4740_mmc.c
index aa3dfb9..62d0023 100644
--- a/kernel/drivers/mmc/host/jz4740_mmc.c
+++ b/kernel/drivers/mmc/host/jz4740_mmc.c
@@ -1041,6 +1041,16 @@
 	mmc->ops = &jz4740_mmc_ops;
 	if (!mmc->f_max)
 		mmc->f_max = JZ_MMC_CLK_RATE;
+
+	/*
+	 * There seems to be a problem with this driver on the JZ4760 and
+	 * JZ4760B SoCs. There, when using the maximum rate supported (50 MHz),
+	 * the communication fails with many SD cards.
+	 * Until this bug is sorted out, limit the maximum rate to 24 MHz.
+	 */
+	if (host->version == JZ_MMC_JZ4760 && mmc->f_max > JZ_MMC_CLK_RATE)
+		mmc->f_max = JZ_MMC_CLK_RATE;
+
 	mmc->f_min = mmc->f_max / 128;
 	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
 
diff --git a/kernel/drivers/mmc/host/meson-gx-mmc.c b/kernel/drivers/mmc/host/meson-gx-mmc.c
index bccc85b..1992eea 100644
--- a/kernel/drivers/mmc/host/meson-gx-mmc.c
+++ b/kernel/drivers/mmc/host/meson-gx-mmc.c
@@ -970,11 +970,8 @@
 	if (status & (IRQ_END_OF_CHAIN | IRQ_RESP_STATUS)) {
 		if (data && !cmd->error)
 			data->bytes_xfered = data->blksz * data->blocks;
-		if (meson_mmc_bounce_buf_read(data) ||
-		    meson_mmc_get_next_command(cmd))
-			ret = IRQ_WAKE_THREAD;
-		else
-			ret = IRQ_HANDLED;
+
+		return IRQ_WAKE_THREAD;
 	}
 
 out:
@@ -985,9 +982,6 @@
 		start &= ~START_DESC_BUSY;
 		writel(start, host->regs + SD_EMMC_START);
 	}
-
-	if (ret == IRQ_HANDLED)
-		meson_mmc_request_done(host->mmc, cmd->mrq);
 
 	return ret;
 }
@@ -1128,7 +1122,7 @@
 	struct mmc_host *mmc;
 	int ret;
 
-	mmc = mmc_alloc_host(sizeof(struct meson_host), &pdev->dev);
+	mmc = devm_mmc_alloc_host(&pdev->dev, sizeof(struct meson_host));
 	if (!mmc)
 		return -ENOMEM;
 	host = mmc_priv(mmc);
@@ -1144,46 +1138,33 @@
 	host->vqmmc_enabled = false;
 	ret = mmc_regulator_get_supply(mmc);
 	if (ret)
-		goto free_host;
+		return ret;
 
 	ret = mmc_of_parse(mmc);
-	if (ret) {
-		if (ret != -EPROBE_DEFER)
-			dev_warn(&pdev->dev, "error parsing DT: %d\n", ret);
-		goto free_host;
-	}
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "error parsing DT\n");
 
 	host->data = (struct meson_mmc_data *)
 		of_device_get_match_data(&pdev->dev);
-	if (!host->data) {
-		ret = -EINVAL;
-		goto free_host;
-	}
+	if (!host->data)
+		return -EINVAL;
 
 	ret = device_reset_optional(&pdev->dev);
-	if (ret) {
-		dev_err_probe(&pdev->dev, ret, "device reset failed\n");
-		goto free_host;
-	}
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "device reset failed\n");
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	host->regs = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(host->regs)) {
-		ret = PTR_ERR(host->regs);
-		goto free_host;
-	}
+	if (IS_ERR(host->regs))
+		return PTR_ERR(host->regs);
 
 	host->irq = platform_get_irq(pdev, 0);
-	if (host->irq <= 0) {
-		ret = -EINVAL;
-		goto free_host;
-	}
+	if (host->irq < 0)
+		return host->irq;
 
 	host->pinctrl = devm_pinctrl_get(&pdev->dev);
-	if (IS_ERR(host->pinctrl)) {
-		ret = PTR_ERR(host->pinctrl);
-		goto free_host;
-	}
+	if (IS_ERR(host->pinctrl))
+		return PTR_ERR(host->pinctrl);
 
 	host->pins_clk_gate = pinctrl_lookup_state(host->pinctrl,
 						   "clk-gate");
@@ -1194,14 +1175,12 @@
 	}
 
 	host->core_clk = devm_clk_get(&pdev->dev, "core");
-	if (IS_ERR(host->core_clk)) {
-		ret = PTR_ERR(host->core_clk);
-		goto free_host;
-	}
+	if (IS_ERR(host->core_clk))
+		return PTR_ERR(host->core_clk);
 
 	ret = clk_prepare_enable(host->core_clk);
 	if (ret)
-		goto free_host;
+		return ret;
 
 	ret = meson_mmc_clk_init(host);
 	if (ret)
@@ -1280,7 +1259,9 @@
 	}
 
 	mmc->ops = &meson_mmc_ops;
-	mmc_add_host(mmc);
+	ret = mmc_add_host(mmc);
+	if (ret)
+		goto err_free_irq;
 
 	return 0;
 
@@ -1294,8 +1275,6 @@
 	clk_disable_unprepare(host->mmc_clk);
 err_core_clk:
 	clk_disable_unprepare(host->core_clk);
-free_host:
-	mmc_free_host(mmc);
 	return ret;
 }
 
@@ -1319,7 +1298,6 @@
 	clk_disable_unprepare(host->mmc_clk);
 	clk_disable_unprepare(host->core_clk);
 
-	mmc_free_host(host->mmc);
 	return 0;
 }
 
diff --git a/kernel/drivers/mmc/host/mmc_spi.c b/kernel/drivers/mmc/host/mmc_spi.c
index 02f4fd2..1d81491 100644
--- a/kernel/drivers/mmc/host/mmc_spi.c
+++ b/kernel/drivers/mmc/host/mmc_spi.c
@@ -1450,7 +1450,7 @@
 
 	status = mmc_add_host(mmc);
 	if (status != 0)
-		goto fail_add_host;
+		goto fail_glue_init;
 
 	/*
 	 * Index 0 is card detect
@@ -1458,7 +1458,7 @@
 	 */
 	status = mmc_gpiod_request_cd(mmc, NULL, 0, false, 1000);
 	if (status == -EPROBE_DEFER)
-		goto fail_add_host;
+		goto fail_gpiod_request;
 	if (!status) {
 		/*
 		 * The platform has a CD GPIO signal that may support
@@ -1473,7 +1473,7 @@
 	/* Index 1 is write protect/read only */
 	status = mmc_gpiod_request_ro(mmc, NULL, 1, 0);
 	if (status == -EPROBE_DEFER)
-		goto fail_add_host;
+		goto fail_gpiod_request;
 	if (!status)
 		has_ro = true;
 
@@ -1487,7 +1487,7 @@
 				? ", cd polling" : "");
 	return 0;
 
-fail_add_host:
+fail_gpiod_request:
 	mmc_remove_host(mmc);
 fail_glue_init:
 	mmc_spi_dma_free(host);
diff --git a/kernel/drivers/mmc/host/mmci.c b/kernel/drivers/mmc/host/mmci.c
index b5684e5..a72ca74 100644
--- a/kernel/drivers/mmc/host/mmci.c
+++ b/kernel/drivers/mmc/host/mmci.c
@@ -1728,7 +1728,8 @@
 		return;
 
 	if (host->variant->busy_timeout && mmc->actual_clock)
-		max_busy_timeout = ~0UL / (mmc->actual_clock / MSEC_PER_SEC);
+		max_busy_timeout = U32_MAX / DIV_ROUND_UP(mmc->actual_clock,
+							  MSEC_PER_SEC);
 
 	mmc->max_busy_timeout = max_busy_timeout;
 }
@@ -2191,7 +2192,9 @@
 	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;
@@ -2383,6 +2386,7 @@
 	.drv		= {
 		.name	= DRIVER_NAME,
 		.pm	= &mmci_dev_pm_ops,
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
 	},
 	.probe		= mmci_probe,
 	.remove		= mmci_remove,
diff --git a/kernel/drivers/mmc/host/moxart-mmc.c b/kernel/drivers/mmc/host/moxart-mmc.c
index c16300b..c4baf8a 100644
--- a/kernel/drivers/mmc/host/moxart-mmc.c
+++ b/kernel/drivers/mmc/host/moxart-mmc.c
@@ -339,13 +339,7 @@
 				return;
 			}
 			for (len = 0; len < remain && len < host->fifo_width;) {
-				/* SCR data must be read in big endian. */
-				if (data->mrq->cmd->opcode == SD_APP_SEND_SCR)
-					*sgp = ioread32be(host->base +
-							  REG_DATA_WINDOW);
-				else
-					*sgp = ioread32(host->base +
-							REG_DATA_WINDOW);
+				*sgp = ioread32(host->base + REG_DATA_WINDOW);
 				sgp++;
 				len += 4;
 			}
@@ -668,7 +662,9 @@
 		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);
 
diff --git a/kernel/drivers/mmc/host/mtk-sd.c b/kernel/drivers/mmc/host/mtk-sd.c
index d71c113..2c9ea5e 100644
--- a/kernel/drivers/mmc/host/mtk-sd.c
+++ b/kernel/drivers/mmc/host/mtk-sd.c
@@ -2443,7 +2443,7 @@
 
 	host->irq = platform_get_irq(pdev, 0);
 	if (host->irq < 0) {
-		ret = -EINVAL;
+		ret = host->irq;
 		goto host_free;
 	}
 
diff --git a/kernel/drivers/mmc/host/mvsdio.c b/kernel/drivers/mmc/host/mvsdio.c
index 629efbe..b4f6a0a 100644
--- a/kernel/drivers/mmc/host/mvsdio.c
+++ b/kernel/drivers/mmc/host/mvsdio.c
@@ -704,7 +704,7 @@
 	}
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
-		return -ENXIO;
+		return irq;
 
 	mmc = mmc_alloc_host(sizeof(struct mvsd_host), &pdev->dev);
 	if (!mmc) {
diff --git a/kernel/drivers/mmc/host/mxcmmc.c b/kernel/drivers/mmc/host/mxcmmc.c
index 12ee072..93a105b 100644
--- a/kernel/drivers/mmc/host/mxcmmc.c
+++ b/kernel/drivers/mmc/host/mxcmmc.c
@@ -1167,7 +1167,9 @@
 
 	timer_setup(&host->watchdog, mxcmci_watchdog, 0);
 
-	mmc_add_host(mmc);
+	ret = mmc_add_host(mmc);
+	if (ret)
+		goto out_free_dma;
 
 	return 0;
 
diff --git a/kernel/drivers/mmc/host/omap.c b/kernel/drivers/mmc/host/omap.c
index 6aa0537..eb978b7 100644
--- a/kernel/drivers/mmc/host/omap.c
+++ b/kernel/drivers/mmc/host/omap.c
@@ -1344,7 +1344,7 @@
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
-		return -ENXIO;
+		return irq;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	host->virt_base = devm_ioremap_resource(&pdev->dev, res);
diff --git a/kernel/drivers/mmc/host/omap_hsmmc.c b/kernel/drivers/mmc/host/omap_hsmmc.c
index aa9cc49..0980754 100644
--- a/kernel/drivers/mmc/host/omap_hsmmc.c
+++ b/kernel/drivers/mmc/host/omap_hsmmc.c
@@ -1832,9 +1832,11 @@
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	irq = platform_get_irq(pdev, 0);
-	if (res == NULL || irq < 0)
+	if (!res)
 		return -ENXIO;
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
 
 	base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(base))
@@ -1987,7 +1989,9 @@
 	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);
diff --git a/kernel/drivers/mmc/host/owl-mmc.c b/kernel/drivers/mmc/host/owl-mmc.c
index 3d4abf1..8a40cf8 100644
--- a/kernel/drivers/mmc/host/owl-mmc.c
+++ b/kernel/drivers/mmc/host/owl-mmc.c
@@ -640,7 +640,7 @@
 
 	owl_host->irq = platform_get_irq(pdev, 0);
 	if (owl_host->irq < 0) {
-		ret = -EINVAL;
+		ret = owl_host->irq;
 		goto err_release_channel;
 	}
 
diff --git a/kernel/drivers/mmc/host/pxamci.c b/kernel/drivers/mmc/host/pxamci.c
index 55868b6..e25e9bb 100644
--- a/kernel/drivers/mmc/host/pxamci.c
+++ b/kernel/drivers/mmc/host/pxamci.c
@@ -763,7 +763,12 @@
 			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;
 
diff --git a/kernel/drivers/mmc/host/renesas_sdhi_core.c b/kernel/drivers/mmc/host/renesas_sdhi_core.c
index ac01fb5..be4c2a8 100644
--- a/kernel/drivers/mmc/host/renesas_sdhi_core.c
+++ b/kernel/drivers/mmc/host/renesas_sdhi_core.c
@@ -537,7 +537,7 @@
 			 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 |
@@ -556,16 +556,18 @@
 {
 	struct renesas_sdhi *priv = host_to_priv(host);
 
-	renesas_sdhi_reset_scc(host, priv);
-	renesas_sdhi_reset_hs400_mode(host, priv);
-	priv->needs_adjust_hs400 = false;
+	if (priv->scc_ctl) {
+		renesas_sdhi_reset_scc(host, priv);
+		renesas_sdhi_reset_hs400_mode(host, priv);
+		priv->needs_adjust_hs400 = false;
 
-	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
-			sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+		sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
+				sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
 
-	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL,
-		       ~SH_MOBILE_SDHI_SCC_RVSCNTL_RVSEN &
-		       sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL));
+		sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL,
+			       ~SH_MOBILE_SDHI_SCC_RVSCNTL_RVSEN &
+			       sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL));
+	}
 
 	if (host->pdata->flags & TMIO_MMC_MIN_RCAR2)
 		sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK,
@@ -1010,11 +1012,9 @@
 		host->ops.start_signal_voltage_switch =
 			renesas_sdhi_start_signal_voltage_switch;
 		host->sdcard_irq_setbit_mask = TMIO_STAT_ALWAYS_SET_27;
-
-		if (of_data && of_data->scc_offset) {
-			priv->scc_ctl = host->ctl + of_data->scc_offset;
-			host->reset = renesas_sdhi_reset;
-		}
+		host->reset = renesas_sdhi_reset;
+	} else {
+		host->sdcard_irq_mask_all = TMIO_MASK_ALL;
 	}
 
 	/* Orginally registers were 16 bit apart, could be 32 or 64 nowadays */
@@ -1070,10 +1070,6 @@
 			quirks->hs400_calib_table + 1);
 	}
 
-	ret = tmio_mmc_host_probe(host);
-	if (ret < 0)
-		goto edisclk;
-
 	/* Enable tuning iff we have an SCC and a supported mode */
 	if (of_data && of_data->scc_offset &&
 	    (host->mmc->caps & MMC_CAP_UHS_SDR104 ||
@@ -1098,12 +1094,15 @@
 		if (!hit)
 			dev_warn(&host->pdev->dev, "Unknown clock rate for tuning\n");
 
+		priv->scc_ctl = host->ctl + of_data->scc_offset;
 		host->check_retune = renesas_sdhi_check_scc_error;
 		host->ops.execute_tuning = renesas_sdhi_execute_tuning;
 		host->ops.prepare_hs400_tuning = renesas_sdhi_prepare_hs400_tuning;
 		host->ops.hs400_downgrade = renesas_sdhi_disable_scc;
 		host->ops.hs400_complete = renesas_sdhi_hs400_complete;
 	}
+
+	sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask_all);
 
 	num_irqs = platform_irq_count(pdev);
 	if (num_irqs < 0) {
@@ -1130,6 +1129,10 @@
 			goto eirq;
 	}
 
+	ret = tmio_mmc_host_probe(host);
+	if (ret < 0)
+		goto edisclk;
+
 	dev_info(&pdev->dev, "%s base at %pa, max clock rate %u MHz\n",
 		 mmc_hostname(host->mmc), &res->start, host->mmc->f_max / 1000000);
 
diff --git a/kernel/drivers/mmc/host/rtsx_usb_sdmmc.c b/kernel/drivers/mmc/host/rtsx_usb_sdmmc.c
index 5fe4528..1be3a35 100644
--- a/kernel/drivers/mmc/host/rtsx_usb_sdmmc.c
+++ b/kernel/drivers/mmc/host/rtsx_usb_sdmmc.c
@@ -1332,6 +1332,7 @@
 #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 @@
 	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;
 }
diff --git a/kernel/drivers/mmc/host/sdhci-acpi.c b/kernel/drivers/mmc/host/sdhci-acpi.c
index a2cdb37..2a28101 100644
--- a/kernel/drivers/mmc/host/sdhci-acpi.c
+++ b/kernel/drivers/mmc/host/sdhci-acpi.c
@@ -876,7 +876,7 @@
 	host->ops	= &sdhci_acpi_ops_dflt;
 	host->irq	= platform_get_irq(pdev, 0);
 	if (host->irq < 0) {
-		err = -EINVAL;
+		err = host->irq;
 		goto err_free;
 	}
 
diff --git a/kernel/drivers/mmc/host/sdhci-esdhc-imx.c b/kernel/drivers/mmc/host/sdhci-esdhc-imx.c
index 9e827bf..b030f65 100644
--- a/kernel/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/kernel/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -103,6 +103,7 @@
 #define ESDHC_TUNING_START_TAP_DEFAULT	0x1
 #define ESDHC_TUNING_START_TAP_MASK	0x7f
 #define ESDHC_TUNING_CMD_CRC_CHECK_DISABLE	(1 << 7)
+#define ESDHC_TUNING_STEP_DEFAULT	0x1
 #define ESDHC_TUNING_STEP_MASK		0x00070000
 #define ESDHC_TUNING_STEP_SHIFT		16
 
@@ -165,8 +166,8 @@
 #define ESDHC_FLAG_HS400		BIT(9)
 /*
  * The IP has errata ERR010450
- * uSDHC: Due to the I/O timing limit, for SDR mode, SD card clock can't
- * exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz.
+ * uSDHC: At 1.8V due to the I/O timing limit, for SDR mode, SD card
+ * clock can't exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz.
  */
 #define ESDHC_FLAG_ERR010450		BIT(10)
 /* The IP supports HS400ES mode */
@@ -872,7 +873,8 @@
 		| ESDHC_CLOCK_MASK);
 	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
 
-	if (imx_data->socdata->flags & ESDHC_FLAG_ERR010450) {
+	if ((imx_data->socdata->flags & ESDHC_FLAG_ERR010450) &&
+	    (!(host->quirks2 & SDHCI_QUIRK2_NO_1_8_V))) {
 		unsigned int max_clock;
 
 		max_clock = imx_data->is_ddr ? 45000000 : 150000000;
@@ -1300,7 +1302,7 @@
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
 	struct cqhci_host *cq_host = host->mmc->cqe_private;
-	int tmp;
+	u32 tmp;
 
 	if (esdhc_is_usdhc(imx_data)) {
 		/*
@@ -1353,17 +1355,24 @@
 
 		if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
 			tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL);
-			tmp |= ESDHC_STD_TUNING_EN |
-				ESDHC_TUNING_START_TAP_DEFAULT;
-			if (imx_data->boarddata.tuning_start_tap) {
-				tmp &= ~ESDHC_TUNING_START_TAP_MASK;
+			tmp |= ESDHC_STD_TUNING_EN;
+
+			/*
+			 * ROM code or bootloader may config the start tap
+			 * and step, unmask them first.
+			 */
+			tmp &= ~(ESDHC_TUNING_START_TAP_MASK | ESDHC_TUNING_STEP_MASK);
+			if (imx_data->boarddata.tuning_start_tap)
 				tmp |= imx_data->boarddata.tuning_start_tap;
-			}
+			else
+				tmp |= ESDHC_TUNING_START_TAP_DEFAULT;
 
 			if (imx_data->boarddata.tuning_step) {
-				tmp &= ~ESDHC_TUNING_STEP_MASK;
 				tmp |= imx_data->boarddata.tuning_step
 					<< ESDHC_TUNING_STEP_SHIFT;
+			} else {
+				tmp |= ESDHC_TUNING_STEP_DEFAULT
+					<< ESDHC_TUNING_STEP_SHIFT;
 			}
 
 			/* Disable the CMD CRC check for tuning, if not, need to
diff --git a/kernel/drivers/mmc/host/sdhci-msm.c b/kernel/drivers/mmc/host/sdhci-msm.c
index 5597955..ea38045 100644
--- a/kernel/drivers/mmc/host/sdhci-msm.c
+++ b/kernel/drivers/mmc/host/sdhci-msm.c
@@ -2488,6 +2488,9 @@
 		msm_host->ddr_config = DDR_CONFIG_POR_VAL;
 
 	of_property_read_u32(node, "qcom,dll-config", &msm_host->dll_config);
+
+	if (of_device_is_compatible(node, "qcom,msm8916-sdhci"))
+		host->quirks2 |= SDHCI_QUIRK2_BROKEN_64_BIT_DMA;
 }
 
 static int sdhci_msm_gcc_reset(struct device *dev, struct sdhci_host *host)
diff --git a/kernel/drivers/mmc/host/sdhci-of-esdhc.c b/kernel/drivers/mmc/host/sdhci-of-esdhc.c
index d533749..5b853f6 100644
--- a/kernel/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/kernel/drivers/mmc/host/sdhci-of-esdhc.c
@@ -126,6 +126,7 @@
 			return ret;
 		}
 	}
+
 	/*
 	 * The DAT[3:0] line signal levels and the CMD line signal level are
 	 * not compatible with standard SDHC register. The line signal levels
@@ -137,6 +138,16 @@
 		ret = value & 0x000fffff;
 		ret |= (value >> 4) & SDHCI_DATA_LVL_MASK;
 		ret |= (value << 1) & SDHCI_CMD_LVL;
+
+		/*
+		 * Some controllers have unreliable Data Line Active
+		 * bit for commands with busy signal. This affects
+		 * Command Inhibit (data) bit. Just ignore it since
+		 * MMC core driver has already polled card status
+		 * with CMD13 after any command with busy siganl.
+		 */
+		if (esdhc->quirk_ignore_data_inhibit)
+			ret &= ~SDHCI_DATA_INHIBIT;
 		return ret;
 	}
 
@@ -148,19 +159,6 @@
 	if (spec_reg == SDHCI_CAPABILITIES_1) {
 		ret = value & ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 |
 				SDHCI_SUPPORT_DDR50);
-		return ret;
-	}
-
-	/*
-	 * Some controllers have unreliable Data Line Active
-	 * bit for commands with busy signal. This affects
-	 * Command Inhibit (data) bit. Just ignore it since
-	 * MMC core driver has already polled card status
-	 * with CMD13 after any command with busy siganl.
-	 */
-	if ((spec_reg == SDHCI_PRESENT_STATE) &&
-	(esdhc->quirk_ignore_data_inhibit == true)) {
-		ret = value & ~SDHCI_DATA_INHIBIT;
 		return ret;
 	}
 
diff --git a/kernel/drivers/mmc/host/sdhci-sprd.c b/kernel/drivers/mmc/host/sdhci-sprd.c
index 110ee0c..540ebcc 100644
--- a/kernel/drivers/mmc/host/sdhci-sprd.c
+++ b/kernel/drivers/mmc/host/sdhci-sprd.c
@@ -224,13 +224,15 @@
 	div = ((div & 0x300) >> 2) | ((div & 0xFF) << 8);
 	sdhci_enable_clk(host, div);
 
-	/* enable auto gate sdhc_enable_auto_gate */
-	val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI);
-	mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN |
-	       SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN;
-	if (mask != (val & mask)) {
-		val |= mask;
-		sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI);
+	/* Enable CLK_AUTO when the clock is greater than 400K. */
+	if (clk > 400000) {
+		val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI);
+		mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN |
+			SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN;
+		if (mask != (val & mask)) {
+			val |= mask;
+			sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI);
+		}
 	}
 }
 
diff --git a/kernel/drivers/mmc/host/sdhci.c b/kernel/drivers/mmc/host/sdhci.c
index 1be23bd..e4c80b6 100644
--- a/kernel/drivers/mmc/host/sdhci.c
+++ b/kernel/drivers/mmc/host/sdhci.c
@@ -1134,6 +1134,8 @@
 		}
 	}
 
+	sdhci_config_dma(host);
+
 	if (host->flags & SDHCI_REQ_USE_DMA) {
 		int sg_cnt = sdhci_pre_dma_transfer(host, data, COOKIE_MAPPED);
 
@@ -1152,8 +1154,6 @@
 			sdhci_set_sdma_addr(host, sdhci_sdma_address(host));
 		}
 	}
-
-	sdhci_config_dma(host);
 
 	if (!(host->flags & SDHCI_REQ_USE_DMA)) {
 		int flags;
diff --git a/kernel/drivers/mmc/host/sdhci_am654.c b/kernel/drivers/mmc/host/sdhci_am654.c
index 24cd6d3..8e52905 100644
--- a/kernel/drivers/mmc/host/sdhci_am654.c
+++ b/kernel/drivers/mmc/host/sdhci_am654.c
@@ -351,8 +351,6 @@
 		 */
 		case MMC_TIMING_SD_HS:
 		case MMC_TIMING_MMC_HS:
-		case MMC_TIMING_UHS_SDR12:
-		case MMC_TIMING_UHS_SDR25:
 			val &= ~SDHCI_CTRL_HISPD;
 		}
 	}
@@ -369,7 +367,7 @@
 					MAX_POWER_ON_TIMEOUT, false, host, val,
 					reg);
 		if (ret)
-			dev_warn(mmc_dev(host->mmc), "Power on failed\n");
+			dev_info(mmc_dev(host->mmc), "Power on failed\n");
 	}
 }
 
diff --git a/kernel/drivers/mmc/host/sdhci_f_sdh30.c b/kernel/drivers/mmc/host/sdhci_f_sdh30.c
index 3f59779..7ede74b 100644
--- a/kernel/drivers/mmc/host/sdhci_f_sdh30.c
+++ b/kernel/drivers/mmc/host/sdhci_f_sdh30.c
@@ -26,9 +26,16 @@
 	bool enable_cmd_dat_delay;
 };
 
+static void *sdhci_f_sdhost_priv(struct sdhci_host *host)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+	return sdhci_pltfm_priv(pltfm_host);
+}
+
 static void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host)
 {
-	struct f_sdhost_priv *priv = sdhci_priv(host);
+	struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host);
 	u32 ctrl = 0;
 
 	usleep_range(2500, 3000);
@@ -61,7 +68,7 @@
 
 static void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask)
 {
-	struct f_sdhost_priv *priv = sdhci_priv(host);
+	struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host);
 	u32 ctl;
 
 	if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0)
@@ -85,29 +92,31 @@
 	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
+static const struct sdhci_pltfm_data sdhci_f_sdh30_pltfm_data = {
+	.ops = &sdhci_f_sdh30_ops,
+	.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
+		| SDHCI_QUIRK_INVERTED_WRITE_PROTECT,
+	.quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE
+		|  SDHCI_QUIRK2_TUNING_WORK_AROUND,
+};
+
 static int sdhci_f_sdh30_probe(struct platform_device *pdev)
 {
 	struct sdhci_host *host;
 	struct device *dev = &pdev->dev;
-	int irq, ctrl = 0, ret = 0;
+	int ctrl = 0, ret = 0;
 	struct f_sdhost_priv *priv;
+	struct sdhci_pltfm_host *pltfm_host;
 	u32 reg = 0;
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
-
-	host = sdhci_alloc_host(dev, sizeof(struct f_sdhost_priv));
+	host = sdhci_pltfm_init(pdev, &sdhci_f_sdh30_pltfm_data,
+				sizeof(struct f_sdhost_priv));
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 
-	priv = sdhci_priv(host);
+	pltfm_host = sdhci_priv(host);
+	priv = sdhci_pltfm_priv(pltfm_host);
 	priv->dev = dev;
-
-	host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
-		       SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
-	host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE |
-			SDHCI_QUIRK2_TUNING_WORK_AROUND;
 
 	priv->enable_cmd_dat_delay = device_property_read_bool(dev,
 						"fujitsu,cmd-dat-delay-select");
@@ -115,18 +124,6 @@
 	ret = mmc_of_parse(host->mmc);
 	if (ret)
 		goto err;
-
-	platform_set_drvdata(pdev, host);
-
-	host->hw_name = "f_sdh30";
-	host->ops = &sdhci_f_sdh30_ops;
-	host->irq = irq;
-
-	host->ioaddr = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(host->ioaddr)) {
-		ret = PTR_ERR(host->ioaddr);
-		goto err;
-	}
 
 	if (dev_of_node(dev)) {
 		sdhci_get_of_property(pdev);
@@ -168,6 +165,9 @@
 	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;
@@ -179,23 +179,22 @@
 err_clk:
 	clk_disable_unprepare(priv->clk_iface);
 err:
-	sdhci_free_host(host);
+	sdhci_pltfm_free(pdev);
+
 	return ret;
 }
 
 static int sdhci_f_sdh30_remove(struct platform_device *pdev)
 {
 	struct sdhci_host *host = platform_get_drvdata(pdev);
-	struct f_sdhost_priv *priv = sdhci_priv(host);
+	struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host);
+	struct clk *clk_iface = priv->clk_iface;
+	struct clk *clk = priv->clk;
 
-	sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) ==
-			  0xffffffff);
+	sdhci_pltfm_unregister(pdev);
 
-	clk_disable_unprepare(priv->clk_iface);
-	clk_disable_unprepare(priv->clk);
-
-	sdhci_free_host(host);
-	platform_set_drvdata(pdev, NULL);
+	clk_disable_unprepare(clk_iface);
+	clk_disable_unprepare(clk);
 
 	return 0;
 }
diff --git a/kernel/drivers/mmc/host/sh_mmcif.c b/kernel/drivers/mmc/host/sh_mmcif.c
index e5e4570..5dec9e2 100644
--- a/kernel/drivers/mmc/host/sh_mmcif.c
+++ b/kernel/drivers/mmc/host/sh_mmcif.c
@@ -1398,7 +1398,7 @@
 	irq[0] = platform_get_irq(pdev, 0);
 	irq[1] = platform_get_irq_optional(pdev, 1);
 	if (irq[0] < 0)
-		return -ENXIO;
+		return irq[0];
 
 	reg = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(reg))
diff --git a/kernel/drivers/mmc/host/sunxi-mmc.c b/kernel/drivers/mmc/host/sunxi-mmc.c
index fc62773..b834fde 100644
--- a/kernel/drivers/mmc/host/sunxi-mmc.c
+++ b/kernel/drivers/mmc/host/sunxi-mmc.c
@@ -1317,8 +1317,8 @@
 		return ret;
 
 	host->irq = platform_get_irq(pdev, 0);
-	if (host->irq <= 0) {
-		ret = -EINVAL;
+	if (host->irq < 0) {
+		ret = host->irq;
 		goto error_disable_mmc;
 	}
 
@@ -1459,9 +1459,11 @@
 	struct sunxi_mmc_host *host = mmc_priv(mmc);
 
 	mmc_remove_host(mmc);
-	pm_runtime_force_suspend(&pdev->dev);
-	disable_irq(host->irq);
-	sunxi_mmc_disable(host);
+	pm_runtime_disable(&pdev->dev);
+	if (!pm_runtime_status_suspended(&pdev->dev)) {
+		disable_irq(host->irq);
+		sunxi_mmc_disable(host);
+	}
 	dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
 	mmc_free_host(mmc);
 
diff --git a/kernel/drivers/mmc/host/tmio_mmc.h b/kernel/drivers/mmc/host/tmio_mmc.h
index 9546e54..d6ed5e1 100644
--- a/kernel/drivers/mmc/host/tmio_mmc.h
+++ b/kernel/drivers/mmc/host/tmio_mmc.h
@@ -161,6 +161,7 @@
 	u32			sdio_irq_mask;
 	unsigned int		clk_cache;
 	u32			sdcard_irq_setbit_mask;
+	u32			sdcard_irq_mask_all;
 
 	spinlock_t		lock;		/* protect host private data */
 	unsigned long		last_req_ts;
diff --git a/kernel/drivers/mmc/host/tmio_mmc_core.c b/kernel/drivers/mmc/host/tmio_mmc_core.c
index ac4e787..abf36ac 100644
--- a/kernel/drivers/mmc/host/tmio_mmc_core.c
+++ b/kernel/drivers/mmc/host/tmio_mmc_core.c
@@ -1158,7 +1158,9 @@
 	tmio_mmc_reset(_host);
 
 	_host->sdcard_irq_mask = sd_ctrl_read16_and_16_as_32(_host, CTL_IRQ_MASK);
-	tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);
+	if (!_host->sdcard_irq_mask_all)
+		_host->sdcard_irq_mask_all = TMIO_MASK_ALL;
+	tmio_mmc_disable_mmc_irqs(_host, _host->sdcard_irq_mask_all);
 
 	if (_host->native_hotplug)
 		tmio_mmc_enable_mmc_irqs(_host,
@@ -1212,7 +1214,7 @@
 	cancel_work_sync(&host->done);
 	cancel_delayed_work_sync(&host->delayed_reset_work);
 	tmio_mmc_release_dma(host);
-	tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL);
+	tmio_mmc_disable_mmc_irqs(host, host->sdcard_irq_mask_all);
 
 	if (host->native_hotplug)
 		pm_runtime_put_noidle(&pdev->dev);
@@ -1242,7 +1244,7 @@
 {
 	struct tmio_mmc_host *host = dev_get_drvdata(dev);
 
-	tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL);
+	tmio_mmc_disable_mmc_irqs(host, host->sdcard_irq_mask_all);
 
 	if (host->clk_cache)
 		host->set_clock(host, 0);
diff --git a/kernel/drivers/mmc/host/toshsd.c b/kernel/drivers/mmc/host/toshsd.c
index 8d037c2..497791f 100644
--- a/kernel/drivers/mmc/host/toshsd.c
+++ b/kernel/drivers/mmc/host/toshsd.c
@@ -651,7 +651,9 @@
 	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 @@
 
 	return 0;
 
+free_irq:
+	free_irq(pdev->irq, host);
 unmap:
 	pci_iounmap(pdev, host->ioaddr);
 release:
diff --git a/kernel/drivers/mmc/host/usdhi6rol0.c b/kernel/drivers/mmc/host/usdhi6rol0.c
index b9b79b1..4f22ece 100644
--- a/kernel/drivers/mmc/host/usdhi6rol0.c
+++ b/kernel/drivers/mmc/host/usdhi6rol0.c
@@ -1747,8 +1747,10 @@
 	irq_cd = platform_get_irq_byname(pdev, "card detect");
 	irq_sd = platform_get_irq_byname(pdev, "data");
 	irq_sdio = platform_get_irq_byname(pdev, "SDIO");
-	if (irq_sd < 0 || irq_sdio < 0)
-		return -ENODEV;
+	if (irq_sd < 0)
+		return irq_sd;
+	if (irq_sdio < 0)
+		return irq_sdio;
 
 	mmc = mmc_alloc_host(sizeof(struct usdhi6_host), dev);
 	if (!mmc)
diff --git a/kernel/drivers/mmc/host/via-sdmmc.c b/kernel/drivers/mmc/host/via-sdmmc.c
index f07c71d..f6b525f 100644
--- a/kernel/drivers/mmc/host/via-sdmmc.c
+++ b/kernel/drivers/mmc/host/via-sdmmc.c
@@ -1154,7 +1154,9 @@
 	    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;
 
diff --git a/kernel/drivers/mmc/host/vub300.c b/kernel/drivers/mmc/host/vub300.c
index 97beece..7dc0e91 100644
--- a/kernel/drivers/mmc/host/vub300.c
+++ b/kernel/drivers/mmc/host/vub300.c
@@ -1715,6 +1715,9 @@
 	int bytes = 3 & less_cmd;
 	int words = less_cmd >> 2;
 	u8 *r = vub300->resp.response.command_response;
+
+	if (!resp_len)
+		return;
 	if (bytes == 3) {
 		cmd->resp[words] = (r[1 + (words << 2)] << 24)
 			| (r[2 + (words << 2)] << 16)
@@ -2049,6 +2052,7 @@
 		return;
 	kref_get(&vub300->kref);
 	if (enable) {
+		set_current_state(TASK_RUNNING);
 		mutex_lock(&vub300->irq_mutex);
 		if (vub300->irqs_queued) {
 			vub300->irqs_queued -= 1;
@@ -2064,6 +2068,7 @@
 			vub300_queue_poll_work(vub300, 0);
 		}
 		mutex_unlock(&vub300->irq_mutex);
+		set_current_state(TASK_INTERRUPTIBLE);
 	} else {
 		vub300->irq_enabled = 0;
 	}
@@ -2299,14 +2304,14 @@
 				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 +2334,13 @@
 			 "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);
 	/*
diff --git a/kernel/drivers/mmc/host/wbsd.c b/kernel/drivers/mmc/host/wbsd.c
index cd63ea8..6db0807 100644
--- a/kernel/drivers/mmc/host/wbsd.c
+++ b/kernel/drivers/mmc/host/wbsd.c
@@ -1703,7 +1703,15 @@
 	 */
 	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);
+		return ret;
+	}
 
 	pr_info("%s: W83L51xD", mmc_hostname(mmc));
 	if (host->chip_id != 0)
diff --git a/kernel/drivers/mmc/host/wmt-sdmmc.c b/kernel/drivers/mmc/host/wmt-sdmmc.c
index 8df722e..3933195 100644
--- a/kernel/drivers/mmc/host/wmt-sdmmc.c
+++ b/kernel/drivers/mmc/host/wmt-sdmmc.c
@@ -859,11 +859,15 @@
 	/* 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:
diff --git a/kernel/drivers/mtd/lpddr/lpddr2_nvm.c b/kernel/drivers/mtd/lpddr/lpddr2_nvm.c
index 72f5c7b..add4386 100644
--- a/kernel/drivers/mtd/lpddr/lpddr2_nvm.c
+++ b/kernel/drivers/mtd/lpddr/lpddr2_nvm.c
@@ -433,6 +433,8 @@
 
 	/* 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) {
diff --git a/kernel/drivers/mtd/maps/pxa2xx-flash.c b/kernel/drivers/mtd/maps/pxa2xx-flash.c
index 7d96758..6e5e557 100644
--- a/kernel/drivers/mtd/maps/pxa2xx-flash.c
+++ b/kernel/drivers/mtd/maps/pxa2xx-flash.c
@@ -66,6 +66,7 @@
 	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 @@
 		iounmap((void *)info->map.virt);
 		if (info->map.cached)
 			iounmap(info->map.cached);
+		kfree(info);
 		return -EIO;
 	}
 	info->mtd->dev.parent = &pdev->dev;
diff --git a/kernel/drivers/mtd/mtdblock.c b/kernel/drivers/mtd/mtdblock.c
index 32e52d8..9e5bbb5 100644
--- a/kernel/drivers/mtd/mtdblock.c
+++ b/kernel/drivers/mtd/mtdblock.c
@@ -153,7 +153,7 @@
 				mtdblk->cache_state = STATE_EMPTY;
 				ret = mtd_read(mtd, sect_start, sect_size,
 					       &retlen, mtdblk->cache_data);
-				if (ret)
+				if (ret && !mtd_is_bitflip(ret))
 					return ret;
 				if (retlen != sect_size)
 					return -EIO;
@@ -188,8 +188,12 @@
 	pr_debug("mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
 			mtd->name, pos, len);
 
-	if (!sect_size)
-		return mtd_read(mtd, pos, len, &retlen, buf);
+	if (!sect_size) {
+		ret = mtd_read(mtd, pos, len, &retlen, buf);
+		if (ret && !mtd_is_bitflip(ret))
+			return ret;
+		return 0;
+	}
 
 	while (len > 0) {
 		unsigned long sect_start = (pos/sect_size)*sect_size;
@@ -209,7 +213,7 @@
 			memcpy (buf, mtdblk->cache_data + offset, size);
 		} else {
 			ret = mtd_read(mtd, pos, size, &retlen, buf);
-			if (ret)
+			if (ret && !mtd_is_bitflip(ret))
 				return ret;
 			if (retlen != size)
 				return -EIO;
diff --git a/kernel/drivers/mtd/mtdcore.c b/kernel/drivers/mtd/mtdcore.c
index a5197a4..b2d88ff 100644
--- a/kernel/drivers/mtd/mtdcore.c
+++ b/kernel/drivers/mtd/mtdcore.c
@@ -667,8 +667,10 @@
 	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);
diff --git a/kernel/drivers/mtd/nand/bbt_store.c b/kernel/drivers/mtd/nand/bbt_store.c
index 37b4708..8687861 100644
--- a/kernel/drivers/mtd/nand/bbt_store.c
+++ b/kernel/drivers/mtd/nand/bbt_store.c
@@ -8,18 +8,78 @@
 #include <linux/slab.h>
 
 #ifdef BBT_DEBUG
-#define BBT_DBG pr_err
+#define bbt_dbg pr_err
 #else
-#define BBT_DBG(args...)
+#define bbt_dbg(args...)
 #endif
+
+#define BBT_VERSION_INVALID		(0xFFFFFFFFU)
+#define BBT_VERSION_BLOCK_ABNORMAL	(BBT_VERSION_INVALID - 1)
+#define BBT_VERSION_MAX			(BBT_VERSION_INVALID - 8)
 
 struct nanddev_bbt_info {
 	u8 pattern[4];
 	unsigned int version;
+	u32 hash;
 };
 
 static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
 
+#if defined(BBT_DEBUG) && defined(BBT_DEBUG_DUMP)
+static void bbt_dbg_hex(char *s, void *buf, u32 len)
+{
+	print_hex_dump(KERN_WARNING, s, DUMP_PREFIX_OFFSET, 4, 4, buf, len, 0);
+}
+#endif
+
+static u32 js_hash(u8 *buf, u32 len)
+{
+	u32 hash = 0x47C6A7E6;
+	u32 i;
+
+	for (i = 0; i < len; i++)
+		hash ^= ((hash << 5) + buf[i] + (hash >> 2));
+
+	return hash;
+}
+
+static bool bbt_check_hash(u8 *buf, u32 len, u32 hash_cmp)
+{
+	u32 hash;
+
+	/* compatible with no-hash version */
+	if (hash_cmp == 0 || hash_cmp == 0xFFFFFFFF)
+		return 1;
+
+	hash = js_hash(buf, len);
+	if (hash != hash_cmp)
+		return 0;
+
+	return 1;
+}
+
+static u32 bbt_nand_isbad_bypass(struct nand_device *nand, u32 block)
+{
+	struct mtd_info *mtd = nanddev_to_mtd(nand);
+	struct nand_pos pos;
+
+	nanddev_bbt_set_block_status(nand, block, NAND_BBT_BLOCK_STATUS_UNKNOWN);
+	nanddev_offs_to_pos(nand, block * mtd->erasesize, &pos);
+
+	return nanddev_isbad(nand, &pos);
+}
+
+/**
+ * nanddev_read_bbt() - Read the BBT (Bad Block Table)
+ * @nand: NAND device
+ * @block: bbt block address
+ * @update: true - get version and overwrite bbt.cache with new version;
+ *	false - get bbt version only;
+ *
+ * Initialize the in-memory BBT.
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
 static int nanddev_read_bbt(struct nand_device *nand, u32 block, bool update)
 {
 	unsigned int bits_per_block = fls(NAND_BBT_BLOCK_NUM_STATUS);
@@ -30,7 +90,7 @@
 	u8 *data_buf, *oob_buf;
 	struct nanddev_bbt_info *bbt_info;
 	struct mtd_oob_ops ops;
-	int bbt_page_num;
+	u32 bbt_page_num;
 	int ret = 0;
 	unsigned int version = 0;
 
@@ -40,7 +100,7 @@
 	if (block >= nblocks)
 		return -EINVAL;
 
-	/* Aligned to page size, and even pages is better */
+	/* aligned to page size, and even pages is better */
 	bbt_page_num = (sizeof(struct nanddev_bbt_info) + nbytes +
 		mtd->writesize - 1) >> (ffs(mtd->writesize) - 1);
 	bbt_page_num = (bbt_page_num + 1) / 2 * 2;
@@ -64,29 +124,72 @@
 	ops.ooblen = bbt_page_num * mtd->oobsize;
 	ops.ooboffs = 0;
 
+	/* store one entry for each block */
 	ret = mtd_read_oob(mtd, block * mtd->erasesize, &ops);
 	if (ret && ret != -EUCLEAN) {
-		pr_err("%s fail %d\n", __func__, ret);
-		ret = -EIO;
+		pr_err("read_bbt blk=%d fail=%d update=%d\n", block, ret, update);
+		ret = 0;
+		version = BBT_VERSION_BLOCK_ABNORMAL;
 		goto out;
 	} else {
 		ret = 0;
 	}
 
-	if (oob_buf[0] != 0xff && !memcmp(bbt_pattern, bbt_info->pattern, 4))
-		version = bbt_info->version;
+	/* bad block or good block without bbt */
+	if (memcmp(bbt_pattern, bbt_info->pattern, 4)) {
+		ret = 0;
+		goto out;
+	}
 
-	BBT_DBG("read_bbt from blk=%d tag=%d ver=%d\n", block, update, version);
+	/* good block with abnornal bbt */
+	if (oob_buf[0] == 0xff ||
+	    !bbt_check_hash(data_buf, nbytes + sizeof(struct nanddev_bbt_info) - 4, bbt_info->hash)) {
+		pr_err("read_bbt check fail blk=%d ret=%d update=%d\n", block, ret, update);
+		ret = 0;
+		version = BBT_VERSION_BLOCK_ABNORMAL;
+		goto out;
+	}
+
+	/* good block with good bbt */
+	version = bbt_info->version;
+	bbt_dbg("read_bbt from blk=%d ver=%d update=%d\n", block, version, update);
 	if (update && version > nand->bbt.version) {
 		memcpy(nand->bbt.cache, data_buf, nbytes);
 		nand->bbt.version = version;
 	}
 
-out:
-	kfree(oob_buf);
-	kfree(data_buf);
+#if defined(BBT_DEBUG) && defined(BBT_DEBUG_DUMP)
+	bbt_dbg_hex("bbt", data_buf, nbytes + sizeof(struct nanddev_bbt_info));
+	if (version) {
+		u8 *temp_buf = kzalloc(bbt_page_num * mtd->writesize, GFP_KERNEL);
+		bool in_scan = nand->bbt.option & NANDDEV_BBT_SCANNED;
 
-	return ret < 0 ? -EIO : version;
+		if (!temp_buf)
+			goto out;
+
+		memcpy(temp_buf, nand->bbt.cache, nbytes);
+		memcpy(nand->bbt.cache, data_buf, nbytes);
+
+		if (!in_scan)
+			nand->bbt.option |= NANDDEV_BBT_SCANNED;
+		for (block = 0; block < nblocks; block++) {
+			ret = nanddev_bbt_get_block_status(nand, block);
+			if (ret != NAND_BBT_BLOCK_GOOD)
+				bbt_dbg("bad block[0x%x], ret=%d\n", block, ret);
+		}
+		if (!in_scan)
+			nand->bbt.option &= ~NANDDEV_BBT_SCANNED;
+		memcpy(nand->bbt.cache, temp_buf, nbytes);
+		kfree(temp_buf);
+		ret = 0;
+	}
+#endif
+
+out:
+	kfree(data_buf);
+	kfree(oob_buf);
+
+	return ret < 0 ? -EIO : (int)version;
 }
 
 static int nanddev_write_bbt(struct nand_device *nand, u32 block)
@@ -99,18 +202,18 @@
 	u8 *data_buf, *oob_buf;
 	struct nanddev_bbt_info *bbt_info;
 	struct mtd_oob_ops ops;
-	int bbt_page_num;
-	int ret = 0;
+	u32 bbt_page_num;
+	int ret = 0, version;
 	struct nand_pos pos;
 
-	BBT_DBG("write_bbt to blk=%d ver=%d\n", block, nand->bbt.version);
+	bbt_dbg("write_bbt to blk=%d ver=%d\n", block, nand->bbt.version);
 	if (!nand->bbt.cache)
 		return -ENOMEM;
 
 	if (block >= nblocks)
 		return -EINVAL;
 
-	/* Aligned to page size, and even pages is better */
+	/* aligned to page size, and even pages is better */
 	bbt_page_num = (sizeof(struct nanddev_bbt_info) + nbytes +
 		mtd->writesize - 1) >> (ffs(mtd->writesize) - 1);
 	bbt_page_num = (bbt_page_num + 1) / 2 * 2;
@@ -130,7 +233,9 @@
 	memcpy(data_buf, nand->bbt.cache, nbytes);
 	memcpy(bbt_info, bbt_pattern, 4);
 	bbt_info->version = nand->bbt.version;
+	bbt_info->hash = js_hash(data_buf, nbytes + sizeof(struct nanddev_bbt_info) - 4);
 
+	/* store one entry for each block */
 	nanddev_offs_to_pos(nand, block * mtd->erasesize, &pos);
 	ret = nand->ops->erase(nand, &pos);
 	if (ret)
@@ -144,10 +249,23 @@
 	ops.ooblen = bbt_page_num * mtd->oobsize;
 	ops.ooboffs = 0;
 	ret = mtd_write_oob(mtd, block * mtd->erasesize, &ops);
+	if (ret) {
+		nand->ops->erase(nand, &pos);
+		goto out;
+	}
 
+	version = nanddev_read_bbt(nand, block, false);
+	if (version != bbt_info->version) {
+		pr_err("bbt_write fail, blk=%d recheck fail %d-%d\n",
+		       block, version, bbt_info->version);
+		nand->ops->erase(nand, &pos);
+		ret = -EIO;
+	} else {
+		ret = 0;
+	}
 out:
-	kfree(oob_buf);
 	kfree(data_buf);
+	kfree(oob_buf);
 
 	return ret;
 }
@@ -158,14 +276,30 @@
 	struct mtd_info *mtd = nanddev_to_mtd(nand);
 	struct nand_pos pos;
 	u32 start_block, block;
+	unsigned int bits_per_block = fls(NAND_BBT_BLOCK_NUM_STATUS);
+	unsigned int nwords = DIV_ROUND_UP(nblocks * bits_per_block,
+					   BITS_PER_LONG);
 
 	start_block = nblocks - NANDDEV_BBT_SCAN_MAXBLOCKS;
 
 	for (block = 0; block < nblocks; block++) {
 		nanddev_offs_to_pos(nand, block * mtd->erasesize, &pos);
-		if (nanddev_isbad(nand, &pos))
+		if (nanddev_isbad(nand, &pos)) {
+			if (bbt_nand_isbad_bypass(nand, 0)) {
+				memset(nand->bbt.cache, 0, nwords * sizeof(*nand->bbt.cache));
+				pr_err("bbt_format fail, test good block %d fail\n", 0);
+				return -EIO;
+			}
+
+			if (!bbt_nand_isbad_bypass(nand, block)) {
+				memset(nand->bbt.cache, 0, nwords * sizeof(*nand->bbt.cache));
+				pr_err("bbt_format fail, test bad block %d fail\n", block);
+				return -EIO;
+			}
+
 			nanddev_bbt_set_block_status(nand, block,
 						     NAND_BBT_BLOCK_FACTORY_BAD);
+		}
 	}
 
 	for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
@@ -197,16 +331,34 @@
 	for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++)
 		nanddev_read_bbt(nand, start_block + block, true);
 
+	nand->bbt.option |= NANDDEV_BBT_SCANNED;
 	if (nand->bbt.version == 0) {
-		nanddev_bbt_format(nand);
+		ret = nanddev_bbt_format(nand);
+		if (ret) {
+			nand->bbt.option = 0;
+			pr_err("%s format fail\n", __func__);
+
+			return ret;
+		}
 		ret = nanddev_bbt_in_flash_update(nand);
 		if (ret) {
 			nand->bbt.option = 0;
-			pr_err("%s fail\n", __func__);
+			pr_err("%s update fail\n", __func__);
+
+			return ret;
 		}
 	}
 
-	nand->bbt.option |= NANDDEV_BBT_SCANNED;
+#if defined(BBT_DEBUG)
+	pr_err("scan_bbt success\n");
+	if (nand->bbt.version) {
+		for (block = 0; block < nblocks; block++) {
+			ret = nanddev_bbt_get_block_status(nand, block);
+			if (ret != NAND_BBT_BLOCK_GOOD)
+				bbt_dbg("bad block[0x%x], ret=%d\n", block, ret);
+		}
+	}
+#endif
 
 	return ret;
 }
@@ -222,31 +374,31 @@
  */
 int nanddev_bbt_in_flash_update(struct nand_device *nand)
 {
+	struct nand_pos pos;
+	struct mtd_info *mtd = nanddev_to_mtd(nand);
+
 	if (nand->bbt.option & NANDDEV_BBT_SCANNED) {
 		unsigned int nblocks = nanddev_neraseblocks(nand);
 		u32 bbt_version[NANDDEV_BBT_SCAN_MAXBLOCKS];
 		int start_block, block;
 		u32 min_version, block_des;
-		int ret, count = 0;
+		int ret, count = 0, status;
 
 		start_block = nblocks - NANDDEV_BBT_SCAN_MAXBLOCKS;
 		for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
-			ret = nanddev_bbt_get_block_status(nand, start_block + block);
-			if (ret == NAND_BBT_BLOCK_FACTORY_BAD) {
-				bbt_version[block] = 0xFFFFFFFF;
-				continue;
-			}
-			ret = nanddev_read_bbt(nand, start_block + block,
-					       false);
-			if (ret < 0)
-				bbt_version[block] = 0xFFFFFFFF;
-			else if (ret == 0)
-				bbt_version[block] = 0;
+			status = nanddev_bbt_get_block_status(nand, start_block + block);
+			ret = nanddev_read_bbt(nand, start_block + block, false);
+			if (ret == 0 && status == NAND_BBT_BLOCK_FACTORY_BAD)
+				bbt_version[block] = BBT_VERSION_INVALID;
+			else if (ret == -EIO)
+				bbt_version[block] = BBT_VERSION_INVALID;
+			else if (ret == BBT_VERSION_BLOCK_ABNORMAL)
+				bbt_version[block] = ret;
 			else
 				bbt_version[block] = ret;
 		}
 get_min_ver:
-		min_version = 0xFFFFFFFF;
+		min_version = BBT_VERSION_MAX;
 		block_des = 0;
 		for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
 			if (bbt_version[block] < min_version) {
@@ -255,25 +407,38 @@
 			}
 		}
 
+		/* Overwrite the BBT_VERSION_BLOCK_ABNORMAL block */
+		if (nand->bbt.version < min_version)
+			nand->bbt.version = min_version + 4;
+
 		if (block_des > 0) {
 			nand->bbt.version++;
 			ret = nanddev_write_bbt(nand, block_des);
-			bbt_version[block_des - start_block] = 0xFFFFFFFF;
 			if (ret) {
-				pr_err("%s blk= %d ret= %d\n", __func__,
-				       block_des, ret);
-				goto get_min_ver;
-			} else {
-				count++;
-				if (count < 2)
-					goto get_min_ver;
-				BBT_DBG("%s success\n", __func__);
-			}
-		} else {
-			pr_err("%s failed\n", __func__);
+				pr_err("bbt_update fail, blk=%d ret= %d\n", block_des, ret);
 
-			return -EINVAL;
+				return -1;
+			}
+
+			bbt_version[block_des - start_block] = BBT_VERSION_INVALID;
+			count++;
+			if (count < 2)
+				goto get_min_ver;
+			bbt_dbg("bbt_update success\n");
+		} else {
+			pr_err("bbt_update failed\n");
+			ret = -1;
 		}
+
+		for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
+			if (bbt_version[block] == BBT_VERSION_BLOCK_ABNORMAL) {
+				block_des = start_block + block;
+				nanddev_offs_to_pos(nand, block_des * mtd->erasesize, &pos);
+				nand->ops->erase(nand, &pos);
+			}
+		}
+
+		return ret;
 	}
 
 	return 0;
diff --git a/kernel/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/kernel/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 580b91c..11d706f 100644
--- a/kernel/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/kernel/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -25,6 +25,7 @@
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/slab.h>
+#include <linux/static_key.h>
 #include <linux/list.h>
 #include <linux/log2.h>
 
@@ -207,6 +208,8 @@
 
 struct brcmnand_host;
 
+static DEFINE_STATIC_KEY_FALSE(brcmnand_soc_has_ops_key);
+
 struct brcmnand_controller {
 	struct device		*dev;
 	struct nand_controller	controller;
@@ -265,6 +268,7 @@
 	const unsigned int	*page_sizes;
 	unsigned int		page_size_shift;
 	unsigned int		max_oob;
+	u32			ecc_level_shift;
 	u32			features;
 
 	/* for low-power standby/resume only */
@@ -589,15 +593,53 @@
 	INTFC_CTLR_READY		= BIT(31),
 };
 
+/***********************************************************************
+ * NAND ACC CONTROL bitfield
+ *
+ * Some bits have remained constant throughout hardware revision, while
+ * others have shifted around.
+ ***********************************************************************/
+
+/* Constant for all versions (where supported) */
+enum {
+	/* See BRCMNAND_HAS_CACHE_MODE */
+	ACC_CONTROL_CACHE_MODE				= BIT(22),
+
+	/* See BRCMNAND_HAS_PREFETCH */
+	ACC_CONTROL_PREFETCH				= BIT(23),
+
+	ACC_CONTROL_PAGE_HIT				= BIT(24),
+	ACC_CONTROL_WR_PREEMPT				= BIT(25),
+	ACC_CONTROL_PARTIAL_PAGE			= BIT(26),
+	ACC_CONTROL_RD_ERASED				= BIT(27),
+	ACC_CONTROL_FAST_PGM_RDIN			= BIT(28),
+	ACC_CONTROL_WR_ECC				= BIT(30),
+	ACC_CONTROL_RD_ECC				= BIT(31),
+};
+
+#define	ACC_CONTROL_ECC_SHIFT			16
+/* Only for v7.2 */
+#define	ACC_CONTROL_ECC_EXT_SHIFT		13
+
+static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl)
+{
+	return static_branch_unlikely(&brcmnand_soc_has_ops_key);
+}
+
 static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs)
 {
+	if (brcmnand_non_mmio_ops(ctrl))
+		return brcmnand_soc_read(ctrl->soc, offs);
 	return brcmnand_readl(ctrl->nand_base + offs);
 }
 
 static inline void nand_writereg(struct brcmnand_controller *ctrl, u32 offs,
 				 u32 val)
 {
-	brcmnand_writel(val, ctrl->nand_base + offs);
+	if (brcmnand_non_mmio_ops(ctrl))
+		brcmnand_soc_write(ctrl->soc, val, offs);
+	else
+		brcmnand_writel(val, ctrl->nand_base + offs);
 }
 
 static int brcmnand_revision_init(struct brcmnand_controller *ctrl)
@@ -716,6 +758,12 @@
 	else if (of_property_read_bool(ctrl->dev->of_node, "brcm,nand-has-wp"))
 		ctrl->features |= BRCMNAND_HAS_WP;
 
+	/* v7.2 has different ecc level shift in the acc register */
+	if (ctrl->nand_version == 0x0702)
+		ctrl->ecc_level_shift = ACC_CONTROL_ECC_EXT_SHIFT;
+	else
+		ctrl->ecc_level_shift = ACC_CONTROL_ECC_SHIFT;
+
 	return 0;
 }
 
@@ -763,13 +811,18 @@
 
 static inline u32 brcmnand_read_fc(struct brcmnand_controller *ctrl, int word)
 {
+	if (brcmnand_non_mmio_ops(ctrl))
+		return brcmnand_soc_read(ctrl->soc, BRCMNAND_NON_MMIO_FC_ADDR);
 	return __raw_readl(ctrl->nand_fc + word * 4);
 }
 
 static inline void brcmnand_write_fc(struct brcmnand_controller *ctrl,
 				     int word, u32 val)
 {
-	__raw_writel(val, ctrl->nand_fc + word * 4);
+	if (brcmnand_non_mmio_ops(ctrl))
+		brcmnand_soc_write(ctrl->soc, val, BRCMNAND_NON_MMIO_FC_ADDR);
+	else
+		__raw_writel(val, ctrl->nand_fc + word * 4);
 }
 
 static inline void edu_writel(struct brcmnand_controller *ctrl,
@@ -899,30 +952,6 @@
 	return 0;
 }
 
-/***********************************************************************
- * NAND ACC CONTROL bitfield
- *
- * Some bits have remained constant throughout hardware revision, while
- * others have shifted around.
- ***********************************************************************/
-
-/* Constant for all versions (where supported) */
-enum {
-	/* See BRCMNAND_HAS_CACHE_MODE */
-	ACC_CONTROL_CACHE_MODE				= BIT(22),
-
-	/* See BRCMNAND_HAS_PREFETCH */
-	ACC_CONTROL_PREFETCH				= BIT(23),
-
-	ACC_CONTROL_PAGE_HIT				= BIT(24),
-	ACC_CONTROL_WR_PREEMPT				= BIT(25),
-	ACC_CONTROL_PARTIAL_PAGE			= BIT(26),
-	ACC_CONTROL_RD_ERASED				= BIT(27),
-	ACC_CONTROL_FAST_PGM_RDIN			= BIT(28),
-	ACC_CONTROL_WR_ECC				= BIT(30),
-	ACC_CONTROL_RD_ECC				= BIT(31),
-};
-
 static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller *ctrl)
 {
 	if (ctrl->nand_version == 0x0702)
@@ -935,18 +964,15 @@
 		return GENMASK(4, 0);
 }
 
-#define NAND_ACC_CONTROL_ECC_SHIFT	16
-#define NAND_ACC_CONTROL_ECC_EXT_SHIFT	13
-
 static inline u32 brcmnand_ecc_level_mask(struct brcmnand_controller *ctrl)
 {
 	u32 mask = (ctrl->nand_version >= 0x0600) ? 0x1f : 0x0f;
 
-	mask <<= NAND_ACC_CONTROL_ECC_SHIFT;
+	mask <<= ACC_CONTROL_ECC_SHIFT;
 
 	/* v7.2 includes additional ECC levels */
-	if (ctrl->nand_version >= 0x0702)
-		mask |= 0x7 << NAND_ACC_CONTROL_ECC_EXT_SHIFT;
+	if (ctrl->nand_version == 0x0702)
+		mask |= 0x7 << ACC_CONTROL_ECC_EXT_SHIFT;
 
 	return mask;
 }
@@ -960,8 +986,8 @@
 
 	if (en) {
 		acc_control |= ecc_flags; /* enable RD/WR ECC */
-		acc_control |= host->hwcfg.ecc_level
-			       << NAND_ACC_CONTROL_ECC_SHIFT;
+		acc_control &= ~brcmnand_ecc_level_mask(ctrl);
+		acc_control |= host->hwcfg.ecc_level << ctrl->ecc_level_shift;
 	} else {
 		acc_control &= ~ecc_flags; /* disable RD/WR ECC */
 		acc_control &= ~brcmnand_ecc_level_mask(ctrl);
@@ -1039,6 +1065,14 @@
 
 		cpu_relax();
 	} while (time_after(limit, jiffies));
+
+	/*
+	 * do a final check after time out in case the CPU was busy and the driver
+	 * did not get enough time to perform the polling to avoid false alarms
+	 */
+	val = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS);
+	if ((val & mask) == expected_val)
+		return 0;
 
 	dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
 		 expected_val, val & mask);
@@ -1429,19 +1463,33 @@
 			     const u8 *oob, int sas, int sector_1k)
 {
 	int tbytes = sas << sector_1k;
-	int j;
+	int j, k = 0;
+	u32 last = 0xffffffff;
+	u8 *plast = (u8 *)&last;
 
 	/* Adjust OOB values for 1K sector size */
 	if (sector_1k && (i & 0x01))
 		tbytes = max(0, tbytes - (int)ctrl->max_oob);
 	tbytes = min_t(int, tbytes, ctrl->max_oob);
 
-	for (j = 0; j < tbytes; j += 4)
+	/*
+	 * tbytes may not be multiple of words. Make sure we don't read out of
+	 * the boundary and stop at last word.
+	 */
+	for (j = 0; (j + 3) < tbytes; j += 4)
 		oob_reg_write(ctrl, j,
 				(oob[j + 0] << 24) |
 				(oob[j + 1] << 16) |
 				(oob[j + 2] <<  8) |
 				(oob[j + 3] <<  0));
+
+	/* handle the remaing bytes */
+	while (j < tbytes)
+		plast[k++] = oob[j++];
+
+	if (tbytes & 0x3)
+		oob_reg_write(ctrl, (tbytes & ~0x3), (__force u32)cpu_to_be32(last));
+
 	return tbytes;
 }
 
@@ -1543,7 +1591,17 @@
 
 	dev_dbg(ctrl->dev, "send native cmd %d addr 0x%llx\n", cmd, cmd_addr);
 
-	BUG_ON(ctrl->cmd_pending != 0);
+	/*
+	 * If we came here through _panic_write and there is a pending
+	 * command, try to wait for it. If it times out, rather than
+	 * hitting BUG_ON, just return so we don't crash while crashing.
+	 */
+	if (oops_in_progress) {
+		if (ctrl->cmd_pending &&
+			bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0))
+			return;
+	} else
+		BUG_ON(ctrl->cmd_pending != 0);
 	ctrl->cmd_pending = cmd;
 
 	ret = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0);
@@ -2483,7 +2541,7 @@
 	tmp &= ~brcmnand_ecc_level_mask(ctrl);
 	tmp &= ~brcmnand_spare_area_mask(ctrl);
 	if (ctrl->nand_version >= 0x0302) {
-		tmp |= cfg->ecc_level << NAND_ACC_CONTROL_ECC_SHIFT;
+		tmp |= cfg->ecc_level << ctrl->ecc_level_shift;
 		tmp |= cfg->spare_area_size;
 	}
 	nand_writereg(ctrl, acc_control_offs, tmp);
@@ -2534,6 +2592,8 @@
 	struct nand_chip *chip = &host->chip;
 	const struct nand_ecc_props *requirements =
 		nanddev_get_ecc_requirements(&chip->base);
+	struct nand_memory_organization *memorg =
+		nanddev_get_memorg(&chip->base);
 	struct brcmnand_controller *ctrl = host->ctrl;
 	struct brcmnand_cfg *cfg = &host->hwcfg;
 	char msg[128];
@@ -2555,10 +2615,11 @@
 	if (cfg->spare_area_size > ctrl->max_oob)
 		cfg->spare_area_size = ctrl->max_oob;
 	/*
-	 * Set oobsize to be consistent with controller's spare_area_size, as
-	 * the rest is inaccessible.
+	 * Set mtd and memorg oobsize to be consistent with controller's
+	 * spare_area_size, as the rest is inaccessible.
 	 */
 	mtd->oobsize = cfg->spare_area_size * (mtd->writesize >> FC_SHIFT);
+	memorg->oobsize = mtd->oobsize;
 
 	cfg->device_size = mtd->size;
 	cfg->block_size = mtd->erasesize;
@@ -2950,6 +3011,12 @@
 	dev_set_drvdata(dev, ctrl);
 	ctrl->dev = dev;
 
+	/* Enable the static key if the soc provides I/O operations indicating
+	 * that a non-memory mapped IO access path must be used
+	 */
+	if (brcmnand_soc_has_ops(ctrl->soc))
+		static_branch_enable(&brcmnand_soc_has_ops_key);
+
 	init_completion(&ctrl->done);
 	init_completion(&ctrl->dma_done);
 	init_completion(&ctrl->edu_done);
diff --git a/kernel/drivers/mtd/nand/raw/brcmnand/brcmnand.h b/kernel/drivers/mtd/nand/raw/brcmnand/brcmnand.h
index eb498fb..f1f93d8 100644
--- a/kernel/drivers/mtd/nand/raw/brcmnand/brcmnand.h
+++ b/kernel/drivers/mtd/nand/raw/brcmnand/brcmnand.h
@@ -11,12 +11,25 @@
 
 struct platform_device;
 struct dev_pm_ops;
+struct brcmnand_io_ops;
+
+/* Special register offset constant to intercept a non-MMIO access
+ * to the flash cache register space. This is intentionally large
+ * not to overlap with an existing offset.
+ */
+#define BRCMNAND_NON_MMIO_FC_ADDR	0xffffffff
 
 struct brcmnand_soc {
 	bool (*ctlrdy_ack)(struct brcmnand_soc *soc);
 	void (*ctlrdy_set_enabled)(struct brcmnand_soc *soc, bool en);
 	void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare,
 				 bool is_param);
+	const struct brcmnand_io_ops *ops;
+};
+
+struct brcmnand_io_ops {
+	u32 (*read_reg)(struct brcmnand_soc *soc, u32 offset);
+	void (*write_reg)(struct brcmnand_soc *soc, u32 val, u32 offset);
 };
 
 static inline void brcmnand_soc_data_bus_prepare(struct brcmnand_soc *soc,
@@ -58,6 +71,22 @@
 		writel_relaxed(val, addr);
 }
 
+static inline bool brcmnand_soc_has_ops(struct brcmnand_soc *soc)
+{
+	return soc && soc->ops && soc->ops->read_reg && soc->ops->write_reg;
+}
+
+static inline u32 brcmnand_soc_read(struct brcmnand_soc *soc, u32 offset)
+{
+	return soc->ops->read_reg(soc, offset);
+}
+
+static inline void brcmnand_soc_write(struct brcmnand_soc *soc, u32 val,
+				      u32 offset)
+{
+	soc->ops->write_reg(soc, val, offset);
+}
+
 int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc);
 int brcmnand_remove(struct platform_device *pdev);
 
diff --git a/kernel/drivers/mtd/nand/raw/fsl_upm.c b/kernel/drivers/mtd/nand/raw/fsl_upm.c
index d5813b9..9f93446 100644
--- a/kernel/drivers/mtd/nand/raw/fsl_upm.c
+++ b/kernel/drivers/mtd/nand/raw/fsl_upm.c
@@ -136,7 +136,7 @@
 	unsigned int i;
 	int ret;
 
-	if (op->cs > NAND_MAX_CHIPS)
+	if (op->cs >= NAND_MAX_CHIPS)
 		return -EINVAL;
 
 	if (check_only)
diff --git a/kernel/drivers/mtd/nand/raw/fsmc_nand.c b/kernel/drivers/mtd/nand/raw/fsmc_nand.c
index 663ff53..3da66e9 100644
--- a/kernel/drivers/mtd/nand/raw/fsmc_nand.c
+++ b/kernel/drivers/mtd/nand/raw/fsmc_nand.c
@@ -1190,9 +1190,14 @@
 static int fsmc_nand_resume(struct device *dev)
 {
 	struct fsmc_nand_data *host = dev_get_drvdata(dev);
+	int ret;
 
 	if (host) {
-		clk_prepare_enable(host->clk);
+		ret = clk_prepare_enable(host->clk);
+		if (ret) {
+			dev_err(dev, "failed to enable clk\n");
+			return ret;
+		}
 		if (host->dev_timings)
 			fsmc_nand_setup(host, host->dev_timings);
 		nand_reset(&host->nand, 0);
diff --git a/kernel/drivers/mtd/nand/raw/ingenic/ingenic_ecc.h b/kernel/drivers/mtd/nand/raw/ingenic/ingenic_ecc.h
index 2cda439..017868f 100644
--- a/kernel/drivers/mtd/nand/raw/ingenic/ingenic_ecc.h
+++ b/kernel/drivers/mtd/nand/raw/ingenic/ingenic_ecc.h
@@ -36,25 +36,25 @@
 void ingenic_ecc_release(struct ingenic_ecc *ecc);
 struct ingenic_ecc *of_ingenic_ecc_get(struct device_node *np);
 #else /* CONFIG_MTD_NAND_INGENIC_ECC */
-int ingenic_ecc_calculate(struct ingenic_ecc *ecc,
+static inline int ingenic_ecc_calculate(struct ingenic_ecc *ecc,
 			  struct ingenic_ecc_params *params,
 			  const u8 *buf, u8 *ecc_code)
 {
 	return -ENODEV;
 }
 
-int ingenic_ecc_correct(struct ingenic_ecc *ecc,
+static inline int ingenic_ecc_correct(struct ingenic_ecc *ecc,
 			struct ingenic_ecc_params *params, u8 *buf,
 			u8 *ecc_code)
 {
 	return -ENODEV;
 }
 
-void ingenic_ecc_release(struct ingenic_ecc *ecc)
+static inline void ingenic_ecc_release(struct ingenic_ecc *ecc)
 {
 }
 
-struct ingenic_ecc *of_ingenic_ecc_get(struct device_node *np)
+static inline struct ingenic_ecc *of_ingenic_ecc_get(struct device_node *np)
 {
 	return ERR_PTR(-ENODEV);
 }
diff --git a/kernel/drivers/mtd/nand/raw/marvell_nand.c b/kernel/drivers/mtd/nand/raw/marvell_nand.c
index dce35f8..2ef1a5a 100644
--- a/kernel/drivers/mtd/nand/raw/marvell_nand.c
+++ b/kernel/drivers/mtd/nand/raw/marvell_nand.c
@@ -2443,6 +2443,12 @@
 			NDTR1_WAIT_MODE;
 	}
 
+	/*
+	 * Reset nfc->selected_chip so the next command will cause the timing
+	 * registers to be updated in marvell_nfc_select_target().
+	 */
+	nfc->selected_chip = NULL;
+
 	return 0;
 }
 
@@ -2885,10 +2891,6 @@
 		regmap_update_bits(sysctrl_base, GENCONF_CLK_GATING_CTRL,
 				   GENCONF_CLK_GATING_CTRL_ND_GATE,
 				   GENCONF_CLK_GATING_CTRL_ND_GATE);
-
-		regmap_update_bits(sysctrl_base, GENCONF_ND_CLK_CTRL,
-				   GENCONF_ND_CLK_CTRL_EN,
-				   GENCONF_ND_CLK_CTRL_EN);
 	}
 
 	/* Configure the DMA if appropriate */
diff --git a/kernel/drivers/mtd/nand/raw/meson_nand.c b/kernel/drivers/mtd/nand/raw/meson_nand.c
index 38f4900..6bb0fca 100644
--- a/kernel/drivers/mtd/nand/raw/meson_nand.c
+++ b/kernel/drivers/mtd/nand/raw/meson_nand.c
@@ -72,6 +72,7 @@
 #define GENCMDIADDRH(aih, addr)		((aih) | (((addr) >> 16) & 0xffff))
 
 #define DMA_DIR(dir)		((dir) ? NFC_CMD_N2M : NFC_CMD_M2N)
+#define DMA_ADDR_ALIGN		8
 
 #define ECC_CHECK_RETURN_FF	(-1)
 
@@ -172,6 +173,7 @@
 
 	dma_addr_t daddr;
 	dma_addr_t iaddr;
+	u32 info_bytes;
 
 	unsigned long assigned_cs;
 };
@@ -275,7 +277,7 @@
 
 	if (raw) {
 		len = mtd->writesize + mtd->oobsize;
-		cmd = (len & GENMASK(5, 0)) | scrambler | DMA_DIR(dir);
+		cmd = (len & GENMASK(13, 0)) | scrambler | DMA_DIR(dir);
 		writel(cmd, nfc->reg_base + NFC_REG_CMD);
 		return;
 	}
@@ -499,6 +501,7 @@
 					 nfc->daddr, datalen, dir);
 			return ret;
 		}
+		nfc->info_bytes = infolen;
 		cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr);
 		writel(cmd, nfc->reg_base + NFC_REG_CMD);
 
@@ -516,8 +519,10 @@
 	struct meson_nfc *nfc = nand_get_controller_data(nand);
 
 	dma_unmap_single(nfc->dev, nfc->daddr, datalen, dir);
-	if (infolen)
+	if (infolen) {
 		dma_unmap_single(nfc->dev, nfc->iaddr, infolen, dir);
+		nfc->info_bytes = 0;
+	}
 }
 
 static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len)
@@ -536,7 +541,7 @@
 	if (ret)
 		goto out;
 
-	cmd = NFC_CMD_N2M | (len & GENMASK(5, 0));
+	cmd = NFC_CMD_N2M | (len & GENMASK(13, 0));
 	writel(cmd, nfc->reg_base + NFC_REG_CMD);
 
 	meson_nfc_drain_cmd(nfc);
@@ -560,7 +565,7 @@
 	if (ret)
 		return ret;
 
-	cmd = NFC_CMD_M2N | (len & GENMASK(5, 0));
+	cmd = NFC_CMD_M2N | (len & GENMASK(13, 0));
 	writel(cmd, nfc->reg_base + NFC_REG_CMD);
 
 	meson_nfc_drain_cmd(nfc);
@@ -706,6 +711,8 @@
 		usleep_range(10, 15);
 		/* info is updated by nfc dma engine*/
 		smp_rmb();
+		dma_sync_single_for_cpu(nfc->dev, nfc->iaddr, nfc->info_bytes,
+					DMA_FROM_DEVICE);
 		ret = *info & ECC_COMPLETE;
 	} while (!ret);
 }
@@ -832,6 +839,9 @@
 
 static bool meson_nfc_is_buffer_dma_safe(const void *buffer)
 {
+	if ((uintptr_t)buffer % DMA_ADDR_ALIGN)
+		return false;
+
 	if (virt_addr_valid(buffer) && (!object_is_on_stack(buffer)))
 		return true;
 	return false;
@@ -1170,7 +1180,6 @@
 	struct meson_nfc *nfc = nand_get_controller_data(nand);
 	struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
 	struct mtd_info *mtd = nand_to_mtd(nand);
-	int nsectors = mtd->writesize / 1024;
 	int ret;
 
 	if (!mtd->name) {
@@ -1188,7 +1197,7 @@
 	nand->options |= NAND_NO_SUBPAGE_WRITE;
 
 	ret = nand_ecc_choose_conf(nand, nfc->data->ecc_caps,
-				   mtd->oobsize - 2 * nsectors);
+				   mtd->oobsize - 2);
 	if (ret) {
 		dev_err(nfc->dev, "failed to ECC init\n");
 		return -EINVAL;
diff --git a/kernel/drivers/mtd/nand/raw/omap_elm.c b/kernel/drivers/mtd/nand/raw/omap_elm.c
index 4b79952..dad17fa 100644
--- a/kernel/drivers/mtd/nand/raw/omap_elm.c
+++ b/kernel/drivers/mtd/nand/raw/omap_elm.c
@@ -174,17 +174,17 @@
 			switch (info->bch_type) {
 			case BCH8_ECC:
 				/* syndrome fragment 0 = ecc[9-12B] */
-				val = cpu_to_be32(*(u32 *) &ecc[9]);
+				val = (__force u32)cpu_to_be32(*(u32 *)&ecc[9]);
 				elm_write_reg(info, offset, val);
 
 				/* syndrome fragment 1 = ecc[5-8B] */
 				offset += 4;
-				val = cpu_to_be32(*(u32 *) &ecc[5]);
+				val = (__force u32)cpu_to_be32(*(u32 *)&ecc[5]);
 				elm_write_reg(info, offset, val);
 
 				/* syndrome fragment 2 = ecc[1-4B] */
 				offset += 4;
-				val = cpu_to_be32(*(u32 *) &ecc[1]);
+				val = (__force u32)cpu_to_be32(*(u32 *)&ecc[1]);
 				elm_write_reg(info, offset, val);
 
 				/* syndrome fragment 3 = ecc[0B] */
@@ -194,35 +194,35 @@
 				break;
 			case BCH4_ECC:
 				/* syndrome fragment 0 = ecc[20-52b] bits */
-				val = (cpu_to_be32(*(u32 *) &ecc[3]) >> 4) |
+				val = ((__force u32)cpu_to_be32(*(u32 *)&ecc[3]) >> 4) |
 					((ecc[2] & 0xf) << 28);
 				elm_write_reg(info, offset, val);
 
 				/* syndrome fragment 1 = ecc[0-20b] bits */
 				offset += 4;
-				val = cpu_to_be32(*(u32 *) &ecc[0]) >> 12;
+				val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 12;
 				elm_write_reg(info, offset, val);
 				break;
 			case BCH16_ECC:
-				val = cpu_to_be32(*(u32 *) &ecc[22]);
+				val = (__force u32)cpu_to_be32(*(u32 *)&ecc[22]);
 				elm_write_reg(info, offset, val);
 				offset += 4;
-				val = cpu_to_be32(*(u32 *) &ecc[18]);
+				val = (__force u32)cpu_to_be32(*(u32 *)&ecc[18]);
 				elm_write_reg(info, offset, val);
 				offset += 4;
-				val = cpu_to_be32(*(u32 *) &ecc[14]);
+				val = (__force u32)cpu_to_be32(*(u32 *)&ecc[14]);
 				elm_write_reg(info, offset, val);
 				offset += 4;
-				val = cpu_to_be32(*(u32 *) &ecc[10]);
+				val = (__force u32)cpu_to_be32(*(u32 *)&ecc[10]);
 				elm_write_reg(info, offset, val);
 				offset += 4;
-				val = cpu_to_be32(*(u32 *) &ecc[6]);
+				val = (__force u32)cpu_to_be32(*(u32 *)&ecc[6]);
 				elm_write_reg(info, offset, val);
 				offset += 4;
-				val = cpu_to_be32(*(u32 *) &ecc[2]);
+				val = (__force u32)cpu_to_be32(*(u32 *)&ecc[2]);
 				elm_write_reg(info, offset, val);
 				offset += 4;
-				val = cpu_to_be32(*(u32 *) &ecc[0]) >> 16;
+				val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 16;
 				elm_write_reg(info, offset, val);
 				break;
 			default:
diff --git a/kernel/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/kernel/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 550bda4..c0c47f3 100644
--- a/kernel/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/kernel/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -1525,6 +1525,9 @@
 	if (IS_ERR(sdrt))
 		return PTR_ERR(sdrt);
 
+	if (conf->timings.mode > 3)
+		return -EOPNOTSUPP;
+
 	if (chipnr == NAND_DATA_IFACE_CHECK_ONLY)
 		return 0;
 
diff --git a/kernel/drivers/mtd/nand/raw/sunxi_nand.c b/kernel/drivers/mtd/nand/raw/sunxi_nand.c
index 2a7ca30..52eb28f 100644
--- a/kernel/drivers/mtd/nand/raw/sunxi_nand.c
+++ b/kernel/drivers/mtd/nand/raw/sunxi_nand.c
@@ -1587,7 +1587,7 @@
 	if (section < ecc->steps)
 		oobregion->length = 4;
 	else
-		oobregion->offset = mtd->oobsize - oobregion->offset;
+		oobregion->length = mtd->oobsize - oobregion->offset;
 
 	return 0;
 }
diff --git a/kernel/drivers/mtd/nand/spi/core.c b/kernel/drivers/mtd/nand/spi/core.c
index f783f2c..f0ba92a 100644
--- a/kernel/drivers/mtd/nand/spi/core.c
+++ b/kernel/drivers/mtd/nand/spi/core.c
@@ -873,6 +873,7 @@
 	&skyhigh_spinand_manufacturer,
 	&toshiba_spinand_manufacturer,
 	&unim_spinand_manufacturer,
+	&unim_zl_spinand_manufacturer,
 	&winbond_spinand_manufacturer,
 	&xincun_spinand_manufacturer,
 	&xtx_spinand_manufacturer,
diff --git a/kernel/drivers/mtd/nand/spi/toshiba.c b/kernel/drivers/mtd/nand/spi/toshiba.c
index 6fe7bd2..daa49c0 100644
--- a/kernel/drivers/mtd/nand/spi/toshiba.c
+++ b/kernel/drivers/mtd/nand/spi/toshiba.c
@@ -73,7 +73,7 @@
 {
 	struct nand_device *nand = spinand_to_nand(spinand);
 	u8 mbf = 0;
-	struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf);
+	struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, spinand->scratchbuf);
 
 	switch (status & STATUS_ECC_MASK) {
 	case STATUS_ECC_NO_BITFLIPS:
@@ -92,7 +92,7 @@
 		if (spi_mem_exec_op(spinand->spimem, &op))
 			return nanddev_get_ecc_requirements(nand)->strength;
 
-		mbf >>= 4;
+		mbf = *(spinand->scratchbuf) >> 4;
 
 		if (WARN_ON(mbf > nanddev_get_ecc_requirements(nand)->strength || !mbf))
 			return nanddev_get_ecc_requirements(nand)->strength;
diff --git a/kernel/drivers/mtd/nand/spi/unim.c b/kernel/drivers/mtd/nand/spi/unim.c
index ee78420..123ee70 100644
--- a/kernel/drivers/mtd/nand/spi/unim.c
+++ b/kernel/drivers/mtd/nand/spi/unim.c
@@ -10,7 +10,8 @@
 #include <linux/kernel.h>
 #include <linux/mtd/spinand.h>
 
-#define SPINAND_MFR_UNIM		0xA1
+#define SPINAND_MFR_UNIM_ZL		0xA1
+#define SPINAND_MFR_UNIM		0xB0
 
 static SPINAND_OP_VARIANTS(read_cache_variants,
 		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
@@ -57,6 +58,59 @@
 	.free = tx25g01_ooblayout_free,
 };
 
+
+static int um19a0xisw_ooblayout_ecc(struct mtd_info *mtd, int section,
+				  struct mtd_oob_region *region)
+{
+	return -ERANGE;
+}
+
+static int um19a0xisw_ooblayout_free(struct mtd_info *mtd, int section,
+				   struct mtd_oob_region *region)
+{
+	if (section)
+		return -ERANGE;
+
+	region->offset = 2;
+	region->length = 62;
+
+	return 0;
+}
+
+static const struct mtd_ooblayout_ops um19a0xisw_ooblayout = {
+	.ecc = um19a0xisw_ooblayout_ecc,
+	.free = um19a0xisw_ooblayout_free,
+};
+
+static int um19a1xisw_ooblayout_ecc(struct mtd_info *mtd, int section,
+				 struct mtd_oob_region *region)
+{
+	if (section)
+		return -ERANGE;
+
+	region->offset = 64;
+	region->length = 64;
+
+	return 0;
+}
+
+static int um19a1xisw_ooblayout_free(struct mtd_info *mtd, int section,
+				  struct mtd_oob_region *region)
+{
+	if (section)
+		return -ERANGE;
+
+	region->offset = 2;
+	region->length = 62;
+
+	return 0;
+}
+
+static const struct mtd_ooblayout_ops um19a1xisw_ooblayout = {
+	.ecc = um19a1xisw_ooblayout_ecc,
+	.free = um19a1xisw_ooblayout_free,
+};
+
 /*
  * ecc bits: 0xC0[4,6]
  * [0b000], No bit errors were detected;
@@ -80,7 +134,32 @@
 		return -EBADMSG;
 }
 
-static const struct spinand_info unim_spinand_table[] = {
+/*
+ * ecc bits: 0xC0[4,6]
+ * [0b000], No bit errors were detected;
+ * [0b001] and [0b011], 1~6 Bit errors were detected and corrected. Not
+ *	reach Flipping Bits;
+ * [0b101], Bit error count equals the bit flip
+ *	detection threshold
+ * [0b010], Multiple bit errors were detected and
+ *	not corrected.
+ * others, Reserved.
+ */
+static int um19axxisw_ecc_ecc_get_status(struct spinand_device *spinand,
+					u8 status)
+{
+	struct nand_device *nand = spinand_to_nand(spinand);
+	u8 eccsr = (status & GENMASK(6, 4)) >> 4;
+
+	if (eccsr <= 1 || eccsr == 3)
+		return eccsr;
+	else if (eccsr == 5)
+		return nanddev_get_ecc_requirements(nand)->strength;
+	else
+		return -EBADMSG;
+}
+
+static const struct spinand_info unim_zl_spinand_table[] = {
 	SPINAND_INFO("TX25G01",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xF1),
 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
@@ -92,9 +171,56 @@
 		     SPINAND_ECCINFO(&tx25g01_ooblayout, tx25g01_ecc_get_status)),
 };
 
+static const struct spinand_info unim_spinand_table[] = {
+	SPINAND_INFO("UM19A1HISW",
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
+		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
+		     NAND_ECCREQ(8, 512),
+		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+					      &write_cache_variants,
+					      &update_cache_variants),
+		     SPINAND_HAS_QE_BIT,
+		     SPINAND_ECCINFO(&um19a1xisw_ooblayout, um19axxisw_ecc_ecc_get_status)),
+	SPINAND_INFO("UM19A0HCSW",
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
+		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
+		     NAND_ECCREQ(8, 512),
+		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+					      &write_cache_variants,
+					      &update_cache_variants),
+		     SPINAND_HAS_QE_BIT,
+		     SPINAND_ECCINFO(&um19a0xisw_ooblayout, um19axxisw_ecc_ecc_get_status)),
+	SPINAND_INFO("UM19A0LCSW",
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15),
+		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
+		     NAND_ECCREQ(8, 512),
+		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+					      &write_cache_variants,
+					      &update_cache_variants),
+		     SPINAND_HAS_QE_BIT,
+		     SPINAND_ECCINFO(&um19a0xisw_ooblayout, um19axxisw_ecc_ecc_get_status)),
+	SPINAND_INFO("UM19A1LISW",
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25),
+		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
+		     NAND_ECCREQ(8, 512),
+		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+					      &write_cache_variants,
+					      &update_cache_variants),
+		     SPINAND_HAS_QE_BIT,
+		     SPINAND_ECCINFO(&um19a1xisw_ooblayout, um19axxisw_ecc_ecc_get_status)),
+};
+
 static const struct spinand_manufacturer_ops unim_spinand_manuf_ops = {
 };
 
+const struct spinand_manufacturer unim_zl_spinand_manufacturer = {
+	.id = SPINAND_MFR_UNIM_ZL,
+	.name = "UNIM_ZL",
+	.chips = unim_zl_spinand_table,
+	.nchips = ARRAY_SIZE(unim_zl_spinand_table),
+	.ops = &unim_spinand_manuf_ops,
+};
+
 const struct spinand_manufacturer unim_spinand_manufacturer = {
 	.id = SPINAND_MFR_UNIM,
 	.name = "UNIM",
diff --git a/kernel/drivers/mtd/nand/spi/xtx.c b/kernel/drivers/mtd/nand/spi/xtx.c
index a40ef58..a6318eb 100644
--- a/kernel/drivers/mtd/nand/spi/xtx.c
+++ b/kernel/drivers/mtd/nand/spi/xtx.c
@@ -343,6 +343,33 @@
 					      &update_cache_variants),
 		     SPINAND_HAS_QE_BIT,
 		     SPINAND_ECCINFO(&xt26g01c_ooblayout, xt26g11c_ecc_get_status)),
+	SPINAND_INFO("XT26G01DWSIGA",
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x31),
+		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
+		     NAND_ECCREQ(8, 512),
+		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+					      &write_cache_variants,
+					      &update_cache_variants),
+		     SPINAND_HAS_QE_BIT,
+		     SPINAND_ECCINFO(&xt26g01b_ooblayout, xt26g11c_ecc_get_status)),
+	SPINAND_INFO("XT26G02DWSIGA",
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x32),
+		     NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
+		     NAND_ECCREQ(8, 512),
+		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+					      &write_cache_variants,
+					      &update_cache_variants),
+		     SPINAND_HAS_QE_BIT,
+		     SPINAND_ECCINFO(&xt26g01b_ooblayout, xt26g11c_ecc_get_status)),
+	SPINAND_INFO("XT26G04DWSIGA",
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x33),
+		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
+		     NAND_ECCREQ(8, 512),
+		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+					      &write_cache_variants,
+					      &update_cache_variants),
+		     SPINAND_HAS_QE_BIT,
+		     SPINAND_ECCINFO(&xt26g01c_ooblayout, xt26g11c_ecc_get_status)),
 };
 
 static const struct spinand_manufacturer_ops xtx_spinand_manuf_ops = {
diff --git a/kernel/drivers/mtd/spi-nor/core.c b/kernel/drivers/mtd/spi-nor/core.c
index 5c29cbf..68a82af 100644
--- a/kernel/drivers/mtd/spi-nor/core.c
+++ b/kernel/drivers/mtd/spi-nor/core.c
@@ -855,21 +855,22 @@
 		ret = spi_nor_read_cr(nor, &sr_cr[1]);
 		if (ret)
 			return ret;
-	} else if (nor->params->quad_enable) {
+	} else if (spi_nor_get_protocol_width(nor->read_proto) == 4 &&
+		   spi_nor_get_protocol_width(nor->write_proto) == 4 &&
+		   nor->params->quad_enable) {
 		/*
 		 * If the Status Register 2 Read command (35h) is not
 		 * supported, we should at least be sure we don't
 		 * change the value of the SR2 Quad Enable bit.
 		 *
-		 * We can safely assume that when the Quad Enable method is
-		 * set, the value of the QE bit is one, as a consequence of the
-		 * nor->params->quad_enable() call.
+		 * When the Quad Enable method is set and the buswidth is 4, we
+		 * can safely assume that the value of the QE bit is one, as a
+		 * consequence of the nor->params->quad_enable() call.
 		 *
-		 * We can safely assume that the Quad Enable bit is present in
-		 * the Status Register 2 at BIT(1). According to the JESD216
-		 * revB standard, BFPT DWORDS[15], bits 22:20, the 16-bit
-		 * Write Status (01h) command is available just for the cases
-		 * in which the QE bit is described in SR2 at BIT(1).
+		 * According to the JESD216 revB standard, BFPT DWORDS[15],
+		 * bits 22:20, the 16-bit Write Status (01h) command is
+		 * available just for the cases in which the QE bit is
+		 * described in SR2 at BIT(1).
 		 */
 		sr_cr[1] = SR2_QUAD_EN_BIT1;
 	} else {
@@ -1314,6 +1315,8 @@
 			continue;
 
 		erase = &map->erase_type[i];
+		if (!erase->size)
+			continue;
 
 		/* Alignment is not mandatory for overlaid regions */
 		if (region->offset & SNOR_OVERLAID_REGION &&
@@ -2566,6 +2569,15 @@
 }
 
 /**
+ * spi_nor_mask_erase_type() - mask out a SPI NOR erase type
+ * @erase:	pointer to a structure that describes a SPI NOR erase type
+ */
+void spi_nor_mask_erase_type(struct spi_nor_erase_type *erase)
+{
+	erase->size = 0;
+}
+
+/**
  * spi_nor_init_uniform_erase_map() - Initialize uniform erase map
  * @map:		the erase map of the SPI NOR
  * @erase_mask:		bitmask encoding erase types that can erase the entire
diff --git a/kernel/drivers/mtd/spi-nor/core.h b/kernel/drivers/mtd/spi-nor/core.h
index f0aee95..bc39118 100644
--- a/kernel/drivers/mtd/spi-nor/core.h
+++ b/kernel/drivers/mtd/spi-nor/core.h
@@ -431,6 +431,7 @@
 
 void spi_nor_set_erase_type(struct spi_nor_erase_type *erase, u32 size,
 			    u8 opcode);
+void spi_nor_mask_erase_type(struct spi_nor_erase_type *erase);
 struct spi_nor_erase_region *
 spi_nor_region_next(struct spi_nor_erase_region *region);
 void spi_nor_init_uniform_erase_map(struct spi_nor_erase_map *map,
diff --git a/kernel/drivers/mtd/spi-nor/gigadevice.c b/kernel/drivers/mtd/spi-nor/gigadevice.c
index 8ca4885..866b2ee 100644
--- a/kernel/drivers/mtd/spi-nor/gigadevice.c
+++ b/kernel/drivers/mtd/spi-nor/gigadevice.c
@@ -58,6 +58,9 @@
 	{ "gd25lq255", INFO(0xc86019, 0, 64 * 1024, 512,
 			    SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			    SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK) },
+	{ "gd25lb256", INFO(0xc86719, 0, 64 * 1024, 512,
+			    SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+			    SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK) },
 	{ "gd25lb512m", INFO(0xc8671a, 0, 64 * 1024, 1024,
 			    SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			    SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK) },
diff --git a/kernel/drivers/mtd/spi-nor/puya.c b/kernel/drivers/mtd/spi-nor/puya.c
index 731bdd2..8889434 100644
--- a/kernel/drivers/mtd/spi-nor/puya.c
+++ b/kernel/drivers/mtd/spi-nor/puya.c
@@ -18,6 +18,8 @@
 			   SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "PY25Q256HB", INFO(0x852019, 0, 64 * 1024, 512,
 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+	{ "PY25Q128LA", INFO(0x856518, 0, 64 * 1024, 256,
+			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 };
 
 const struct spi_nor_manufacturer spi_nor_puya = {
diff --git a/kernel/drivers/mtd/spi-nor/sfdp.c b/kernel/drivers/mtd/spi-nor/sfdp.c
index 08de2a2..9dc0528 100644
--- a/kernel/drivers/mtd/spi-nor/sfdp.c
+++ b/kernel/drivers/mtd/spi-nor/sfdp.c
@@ -852,7 +852,7 @@
 	 */
 	for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++)
 		if (!(regions_erase_type & BIT(erase[i].idx)))
-			spi_nor_set_erase_type(&erase[i], 0, 0xFF);
+			spi_nor_mask_erase_type(&erase[i]);
 
 	return 0;
 }
@@ -1063,7 +1063,7 @@
 			erase_type[i].opcode = (dwords[1] >>
 						erase_type[i].idx * 8) & 0xFF;
 		else
-			spi_nor_set_erase_type(&erase_type[i], 0u, 0xFF);
+			spi_nor_mask_erase_type(&erase_type[i]);
 	}
 
 	/*
diff --git a/kernel/drivers/mtd/ubi/build.c b/kernel/drivers/mtd/ubi/build.c
index 53cdee1..7868d46 100644
--- a/kernel/drivers/mtd/ubi/build.c
+++ b/kernel/drivers/mtd/ubi/build.c
@@ -467,6 +467,7 @@
 			err = ubi_add_volume(ubi, ubi->volumes[i]);
 			if (err) {
 				ubi_err(ubi, "cannot add volume %d", i);
+				ubi->volumes[i] = NULL;
 				goto out_volumes;
 			}
 		}
@@ -681,6 +682,21 @@
 						ubi->vid_hdr_aloffset;
 	}
 
+	/*
+	 * Memory allocation for VID header is ubi->vid_hdr_alsize
+	 * which is described in comments in io.c.
+	 * Make sure VID header shift + UBI_VID_HDR_SIZE not exceeds
+	 * ubi->vid_hdr_alsize, so that all vid header operations
+	 * won't access memory out of bounds.
+	 */
+	if ((ubi->vid_hdr_shift + UBI_VID_HDR_SIZE) > ubi->vid_hdr_alsize) {
+		ubi_err(ubi, "Invalid VID header offset %d, VID header shift(%d)"
+			" + VID header size(%zu) > VID header aligned size(%d).",
+			ubi->vid_hdr_offset, ubi->vid_hdr_shift,
+			UBI_VID_HDR_SIZE, ubi->vid_hdr_alsize);
+		return -EINVAL;
+	}
+
 	/* Similar for the data offset */
 	ubi->leb_start = ubi->vid_hdr_offset + UBI_VID_HDR_SIZE;
 	ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size);
@@ -873,6 +889,13 @@
 		return -EINVAL;
 	}
 
+	/* UBI cannot work on flashes with zero erasesize. */
+	if (!mtd->erasesize) {
+		pr_err("ubi: refuse attaching mtd%d - zero erasesize flash is not supported\n",
+			mtd->index);
+		return -EINVAL;
+	}
+
 	if (ubi_num == UBI_DEV_NUM_AUTO) {
 		/* Search for an empty slot in the @ubi_devices array */
 		for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++)
diff --git a/kernel/drivers/mtd/ubi/eba.c b/kernel/drivers/mtd/ubi/eba.c
index 0edecfd..b4cdf23 100644
--- a/kernel/drivers/mtd/ubi/eba.c
+++ b/kernel/drivers/mtd/ubi/eba.c
@@ -947,7 +947,7 @@
 				  int offset, int len)
 {
 	struct ubi_device *ubi = vol->ubi;
-	int pnum, opnum, err, vol_id = vol->vol_id;
+	int pnum, opnum, err, err2, vol_id = vol->vol_id;
 
 	pnum = ubi_wl_get_peb(ubi);
 	if (pnum < 0) {
@@ -982,10 +982,19 @@
 out_put:
 	up_read(&ubi->fm_eba_sem);
 
-	if (err && pnum >= 0)
-		err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
-	else if (!err && opnum >= 0)
-		err = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0);
+	if (err && pnum >= 0) {
+		err2 = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
+		if (err2) {
+			ubi_warn(ubi, "failed to return physical eraseblock %d, error %d",
+				 pnum, err2);
+		}
+	} else if (!err && opnum >= 0) {
+		err2 = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0);
+		if (err2) {
+			ubi_warn(ubi, "failed to return physical eraseblock %d, error %d",
+				 opnum, err2);
+		}
+	}
 
 	return err;
 }
diff --git a/kernel/drivers/mtd/ubi/fastmap-wl.c b/kernel/drivers/mtd/ubi/fastmap-wl.c
index 053ab52..69592be 100644
--- a/kernel/drivers/mtd/ubi/fastmap-wl.c
+++ b/kernel/drivers/mtd/ubi/fastmap-wl.c
@@ -146,13 +146,15 @@
 	if (ubi->fm_anchor) {
 		wl_tree_add(ubi->fm_anchor, &ubi->free);
 		ubi->free_count++;
+		ubi->fm_anchor = NULL;
 	}
 
-	/*
-	 * All available PEBs are in ubi->free, now is the time to get
-	 * the best anchor PEBs.
-	 */
-	ubi->fm_anchor = ubi_wl_get_fm_peb(ubi, 1);
+	if (!ubi->fm_disabled)
+		/*
+		 * All available PEBs are in ubi->free, now is the time to get
+		 * the best anchor PEBs.
+		 */
+		ubi->fm_anchor = ubi_wl_get_fm_peb(ubi, 1);
 
 	for (;;) {
 		enough = 0;
diff --git a/kernel/drivers/mtd/ubi/vmt.c b/kernel/drivers/mtd/ubi/vmt.c
index 6ea95ad..d79323e 100644
--- a/kernel/drivers/mtd/ubi/vmt.c
+++ b/kernel/drivers/mtd/ubi/vmt.c
@@ -464,7 +464,7 @@
 		for (i = 0; i < -pebs; i++) {
 			err = ubi_eba_unmap_leb(ubi, vol, reserved_pebs + i);
 			if (err)
-				goto out_acc;
+				goto out_free;
 		}
 		spin_lock(&ubi->volumes_lock);
 		ubi->rsvd_pebs += pebs;
@@ -512,8 +512,10 @@
 		ubi->avail_pebs += pebs;
 		spin_unlock(&ubi->volumes_lock);
 	}
+	return err;
+
 out_free:
-	kfree(new_eba_tbl);
+	ubi_eba_destroy_table(new_eba_tbl);
 	return err;
 }
 
@@ -580,6 +582,7 @@
 	if (err) {
 		ubi_err(ubi, "cannot add character device for volume %d, error %d",
 			vol_id, err);
+		vol_release(&vol->dev);
 		return err;
 	}
 
@@ -590,14 +593,13 @@
 	vol->dev.groups = volume_dev_groups;
 	dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id);
 	err = device_register(&vol->dev);
-	if (err)
-		goto out_cdev;
+	if (err) {
+		cdev_del(&vol->cdev);
+		put_device(&vol->dev);
+		return err;
+	}
 
 	self_check_volumes(ubi);
-	return err;
-
-out_cdev:
-	cdev_del(&vol->cdev);
 	return err;
 }
 
diff --git a/kernel/drivers/mtd/ubi/wl.c b/kernel/drivers/mtd/ubi/wl.c
index 820b5c1..4427018 100644
--- a/kernel/drivers/mtd/ubi/wl.c
+++ b/kernel/drivers/mtd/ubi/wl.c
@@ -575,6 +575,7 @@
  * @vol_id: the volume ID that last used this PEB
  * @lnum: the last used logical eraseblock number for the PEB
  * @torture: if the physical eraseblock has to be tortured
+ * @nested: denotes whether the work_sem is already held
  *
  * This function returns zero in case of success and a %-ENOMEM in case of
  * failure.
@@ -885,8 +886,11 @@
 
 	err = do_sync_erase(ubi, e1, vol_id, lnum, 0);
 	if (err) {
-		if (e2)
+		if (e2) {
+			spin_lock(&ubi->wl_lock);
 			wl_entry_destroy(ubi, e2);
+			spin_unlock(&ubi->wl_lock);
+		}
 		goto out_ro;
 	}
 
@@ -968,11 +972,11 @@
 	spin_lock(&ubi->wl_lock);
 	ubi->move_from = ubi->move_to = NULL;
 	ubi->move_to_put = ubi->wl_scheduled = 0;
+	wl_entry_destroy(ubi, e1);
+	wl_entry_destroy(ubi, e2);
 	spin_unlock(&ubi->wl_lock);
 
 	ubi_free_vid_buf(vidb);
-	wl_entry_destroy(ubi, e1);
-	wl_entry_destroy(ubi, e2);
 
 out_ro:
 	ubi_ro_mode(ubi);
@@ -1063,8 +1067,6 @@
  * __erase_worker - physical eraseblock erase worker function.
  * @ubi: UBI device description object
  * @wl_wrk: the work object
- * @shutdown: non-zero if the worker has to free memory and exit
- * because the WL sub-system is shutting down
  *
  * This function erases a physical eraseblock and perform torture testing if
  * needed. It also takes care about marking the physical eraseblock bad if
@@ -1119,16 +1121,20 @@
 		int err1;
 
 		/* Re-schedule the LEB for erasure */
-		err1 = schedule_erase(ubi, e, vol_id, lnum, 0, false);
+		err1 = schedule_erase(ubi, e, vol_id, lnum, 0, true);
 		if (err1) {
+			spin_lock(&ubi->wl_lock);
 			wl_entry_destroy(ubi, e);
+			spin_unlock(&ubi->wl_lock);
 			err = err1;
 			goto out_ro;
 		}
 		return err;
 	}
 
+	spin_lock(&ubi->wl_lock);
 	wl_entry_destroy(ubi, e);
+	spin_unlock(&ubi->wl_lock);
 	if (err != -EIO)
 		/*
 		 * If this is not %-EIO, we have no idea what to do. Scheduling
@@ -1244,6 +1250,18 @@
 retry:
 	spin_lock(&ubi->wl_lock);
 	e = ubi->lookuptbl[pnum];
+	if (!e) {
+		/*
+		 * This wl entry has been removed for some errors by other
+		 * process (eg. wear leveling worker), corresponding process
+		 * (except __erase_worker, which cannot concurrent with
+		 * ubi_wl_put_peb) will set ubi ro_mode at the same time,
+		 * just ignore this wl entry.
+		 */
+		spin_unlock(&ubi->wl_lock);
+		up_read(&ubi->fm_protect);
+		return 0;
+	}
 	if (e == ubi->move_from) {
 		/*
 		 * User is putting the physical eraseblock which was selected to
diff --git a/kernel/drivers/net/Makefile b/kernel/drivers/net/Makefile
index 72e18d5..6443044 100644
--- a/kernel/drivers/net/Makefile
+++ b/kernel/drivers/net/Makefile
@@ -29,7 +29,7 @@
 obj-$(CONFIG_TAP) += tap.o
 obj-$(CONFIG_VETH) += veth.o
 obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
-obj-$(CONFIG_VXLAN) += vxlan.o
+obj-$(CONFIG_VXLAN) += vxlan/
 obj-$(CONFIG_GENEVE) += geneve.o
 obj-$(CONFIG_BAREUDP) += bareudp.o
 obj-$(CONFIG_GTP) += gtp.o
diff --git a/kernel/drivers/net/arcnet/arcnet.c b/kernel/drivers/net/arcnet/arcnet.c
index d76dd7d..a789940 100644
--- a/kernel/drivers/net/arcnet/arcnet.c
+++ b/kernel/drivers/net/arcnet/arcnet.c
@@ -468,7 +468,7 @@
 
 	ret = sock_queue_err_skb(sk, ackskb);
 	if (ret)
-		kfree_skb(ackskb);
+		dev_kfree_skb_irq(ackskb);
 
 	local_irq_enable();
 };
diff --git a/kernel/drivers/net/bonding/bond_3ad.c b/kernel/drivers/net/bonding/bond_3ad.c
index acb6ff0..320e546 100644
--- a/kernel/drivers/net/bonding/bond_3ad.c
+++ b/kernel/drivers/net/bonding/bond_3ad.c
@@ -1520,6 +1520,7 @@
 			slave_err(bond->dev, port->slave->dev,
 				  "Port %d did not find a suitable aggregator\n",
 				  port->actor_port_number);
+			return;
 		}
 	}
 	/* if all aggregator's ports are READY_N == TRUE, set ready=TRUE
diff --git a/kernel/drivers/net/bonding/bond_alb.c b/kernel/drivers/net/bonding/bond_alb.c
index 152f76f..64ba465 100644
--- a/kernel/drivers/net/bonding/bond_alb.c
+++ b/kernel/drivers/net/bonding/bond_alb.c
@@ -656,10 +656,10 @@
 		return NULL;
 	arp = (struct arp_pkt *)skb_network_header(skb);
 
-	/* Don't modify or load balance ARPs that do not originate locally
-	 * (e.g.,arrive via a bridge).
+	/* Don't modify or load balance ARPs that do not originate
+	 * from the bond itself or a VLAN directly above the bond.
 	 */
-	if (!bond_slave_has_mac_rx(bond, arp->mac_src))
+	if (!bond_slave_has_mac_rcu(bond, arp->mac_src))
 		return NULL;
 
 	if (arp->op_code == htons(ARPOP_REPLY)) {
diff --git a/kernel/drivers/net/bonding/bond_debugfs.c b/kernel/drivers/net/bonding/bond_debugfs.c
index f3f86ef..8b6cf2b 100644
--- a/kernel/drivers/net/bonding/bond_debugfs.c
+++ b/kernel/drivers/net/bonding/bond_debugfs.c
@@ -76,7 +76,7 @@
 
 	d = debugfs_rename(bonding_debug_root, bond->debug_dir,
 			   bonding_debug_root, bond->dev->name);
-	if (d) {
+	if (!IS_ERR(d)) {
 		bond->debug_dir = d;
 	} else {
 		netdev_warn(bond->dev, "failed to reregister, so just unregister old one\n");
diff --git a/kernel/drivers/net/bonding/bond_main.c b/kernel/drivers/net/bonding/bond_main.c
index f38a6ce..bcb0191 100644
--- a/kernel/drivers/net/bonding/bond_main.c
+++ b/kernel/drivers/net/bonding/bond_main.c
@@ -1442,6 +1442,11 @@
 
 	memcpy(bond_dev->broadcast, slave_dev->broadcast,
 		slave_dev->addr_len);
+
+	if (slave_dev->flags & IFF_POINTOPOINT) {
+		bond_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
+		bond_dev->flags |= (IFF_POINTOPOINT | IFF_NOARP);
+	}
 }
 
 /* On bonding slaves other than the currently active slave, suppress
@@ -2393,12 +2398,21 @@
 /* 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;
 
-	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);
@@ -3528,7 +3542,11 @@
 		unblock_netpoll_tx();
 		break;
 	case NETDEV_FEAT_CHANGE:
-		bond_compute_features(bond);
+		if (!bond->notifier_ctx) {
+			bond->notifier_ctx = true;
+			bond_compute_features(bond);
+			bond->notifier_ctx = false;
+		}
 		break;
 	case NETDEV_RESEND_IGMP:
 		/* Propagate to master device */
@@ -4902,7 +4920,9 @@
 
 	bond_dev->hw_features = BOND_VLAN_FEATURES |
 				NETIF_F_HW_VLAN_CTAG_RX |
-				NETIF_F_HW_VLAN_CTAG_FILTER;
+				NETIF_F_HW_VLAN_CTAG_FILTER |
+				NETIF_F_HW_VLAN_STAG_RX |
+				NETIF_F_HW_VLAN_STAG_FILTER;
 
 	bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4;
 #ifdef CONFIG_XFRM_OFFLOAD
@@ -5351,6 +5371,8 @@
 	if (!bond->wq)
 		return -ENOMEM;
 
+	bond->notifier_ctx = false;
+
 	spin_lock_init(&bond->stats_lock);
 	netdev_lockdep_set_classes(bond_dev);
 
diff --git a/kernel/drivers/net/can/kvaser_pciefd.c b/kernel/drivers/net/can/kvaser_pciefd.c
index 9d7445f..197390d 100644
--- a/kernel/drivers/net/can/kvaser_pciefd.c
+++ b/kernel/drivers/net/can/kvaser_pciefd.c
@@ -70,10 +70,12 @@
 #define KVASER_PCIEFD_SYSID_BUILD_REG (KVASER_PCIEFD_SYSID_BASE + 0x14)
 /* Shared receive buffer registers */
 #define KVASER_PCIEFD_SRB_BASE 0x1f200
+#define KVASER_PCIEFD_SRB_FIFO_LAST_REG (KVASER_PCIEFD_SRB_BASE + 0x1f4)
 #define KVASER_PCIEFD_SRB_CMD_REG (KVASER_PCIEFD_SRB_BASE + 0x200)
 #define KVASER_PCIEFD_SRB_IEN_REG (KVASER_PCIEFD_SRB_BASE + 0x204)
 #define KVASER_PCIEFD_SRB_IRQ_REG (KVASER_PCIEFD_SRB_BASE + 0x20c)
 #define KVASER_PCIEFD_SRB_STAT_REG (KVASER_PCIEFD_SRB_BASE + 0x210)
+#define KVASER_PCIEFD_SRB_RX_NR_PACKETS_REG (KVASER_PCIEFD_SRB_BASE + 0x214)
 #define KVASER_PCIEFD_SRB_CTRL_REG (KVASER_PCIEFD_SRB_BASE + 0x218)
 /* EPCS flash controller registers */
 #define KVASER_PCIEFD_SPI_BASE 0x1fc00
@@ -109,6 +111,9 @@
 #define KVASER_PCIEFD_SRB_STAT_DI BIT(15)
 /* DMA support */
 #define KVASER_PCIEFD_SRB_STAT_DMA BIT(24)
+
+/* SRB current packet level */
+#define KVASER_PCIEFD_SRB_RX_NR_PACKETS_MASK 0xff
 
 /* DMA Enable */
 #define KVASER_PCIEFD_SRB_CTRL_DMA_ENABLE BIT(0)
@@ -528,7 +533,7 @@
 	      KVASER_PCIEFD_KCAN_IRQ_TOF | KVASER_PCIEFD_KCAN_IRQ_ABD |
 	      KVASER_PCIEFD_KCAN_IRQ_TAE | KVASER_PCIEFD_KCAN_IRQ_TAL |
 	      KVASER_PCIEFD_KCAN_IRQ_FDIC | KVASER_PCIEFD_KCAN_IRQ_BPP |
-	      KVASER_PCIEFD_KCAN_IRQ_TAR | KVASER_PCIEFD_KCAN_IRQ_TFD;
+	      KVASER_PCIEFD_KCAN_IRQ_TAR;
 
 	iowrite32(msk, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
 
@@ -556,6 +561,8 @@
 
 	if (can->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
 		mode |= KVASER_PCIEFD_KCAN_MODE_LOM;
+	else
+		mode &= ~KVASER_PCIEFD_KCAN_MODE_LOM;
 
 	mode |= KVASER_PCIEFD_KCAN_MODE_EEN;
 	mode |= KVASER_PCIEFD_KCAN_MODE_EPEN;
@@ -574,7 +581,7 @@
 
 	spin_lock_irqsave(&can->lock, irq);
 	iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG);
-	iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD | KVASER_PCIEFD_KCAN_IRQ_TFD,
+	iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD,
 		  can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
 
 	status = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_STAT_REG);
@@ -617,7 +624,7 @@
 	iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
 	iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG);
 
-	iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD | KVASER_PCIEFD_KCAN_IRQ_TFD,
+	iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD,
 		  can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
 
 	mode = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG);
@@ -721,6 +728,7 @@
 		iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
 		del_timer(&can->bec_poll_timer);
 	}
+	can->can.state = CAN_STATE_STOPPED;
 	close_candev(netdev);
 
 	return ret;
@@ -1003,8 +1011,7 @@
 		SET_NETDEV_DEV(netdev, &pcie->pci->dev);
 
 		iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG);
-		iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD |
-			  KVASER_PCIEFD_KCAN_IRQ_TFD,
+		iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD,
 			  can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
 
 		pcie->can[i] = can;
@@ -1054,6 +1061,7 @@
 {
 	int i;
 	u32 srb_status;
+	u32 srb_packet_count;
 	dma_addr_t dma_addr[KVASER_PCIEFD_DMA_COUNT];
 
 	/* Disable the DMA */
@@ -1080,6 +1088,15 @@
 	iowrite32(KVASER_PCIEFD_SRB_CMD_FOR | KVASER_PCIEFD_SRB_CMD_RDB0 |
 		  KVASER_PCIEFD_SRB_CMD_RDB1,
 		  pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG);
+
+	/* Empty Rx FIFO */
+	srb_packet_count = ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_RX_NR_PACKETS_REG) &
+			   KVASER_PCIEFD_SRB_RX_NR_PACKETS_MASK;
+	while (srb_packet_count) {
+		/* Drop current packet in FIFO */
+		ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_FIFO_LAST_REG);
+		srb_packet_count--;
+	}
 
 	srb_status = ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_STAT_REG);
 	if (!(srb_status & KVASER_PCIEFD_SRB_STAT_DI)) {
@@ -1423,9 +1440,6 @@
 		cmd = KVASER_PCIEFD_KCAN_CMD_AT;
 		cmd |= ++can->cmd_seq << KVASER_PCIEFD_KCAN_CMD_SEQ_SHIFT;
 		iowrite32(cmd, can->reg_base + KVASER_PCIEFD_KCAN_CMD_REG);
-
-		iowrite32(KVASER_PCIEFD_KCAN_IRQ_TFD,
-			  can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
 	} else if (p->header[0] & KVASER_PCIEFD_SPACK_IDET &&
 		   p->header[0] & KVASER_PCIEFD_SPACK_IRM &&
 		   cmdseq == (p->header[1] & KVASER_PCIEFD_PACKET_SEQ_MSK) &&
@@ -1714,15 +1728,6 @@
 	if (irq & KVASER_PCIEFD_KCAN_IRQ_TOF)
 		netdev_err(can->can.dev, "Tx FIFO overflow\n");
 
-	if (irq & KVASER_PCIEFD_KCAN_IRQ_TFD) {
-		u8 count = ioread32(can->reg_base +
-				    KVASER_PCIEFD_KCAN_TX_NPACKETS_REG) & 0xff;
-
-		if (count == 0)
-			iowrite32(KVASER_PCIEFD_KCAN_CTRL_EFLUSH,
-				  can->reg_base + KVASER_PCIEFD_KCAN_CTRL_REG);
-	}
-
 	if (irq & KVASER_PCIEFD_KCAN_IRQ_BPP)
 		netdev_err(can->can.dev,
 			   "Fail to change bittiming, when not in reset mode\n");
@@ -1824,6 +1829,11 @@
 	if (err)
 		goto err_teardown_can_ctrls;
 
+	err = request_irq(pcie->pci->irq, kvaser_pciefd_irq_handler,
+			  IRQF_SHARED, KVASER_PCIEFD_DRV_NAME, pcie);
+	if (err)
+		goto err_teardown_can_ctrls;
+
 	iowrite32(KVASER_PCIEFD_SRB_IRQ_DPD0 | KVASER_PCIEFD_SRB_IRQ_DPD1,
 		  pcie->reg_base + KVASER_PCIEFD_SRB_IRQ_REG);
 
@@ -1844,11 +1854,6 @@
 	iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1,
 		  pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG);
 
-	err = request_irq(pcie->pci->irq, kvaser_pciefd_irq_handler,
-			  IRQF_SHARED, KVASER_PCIEFD_DRV_NAME, pcie);
-	if (err)
-		goto err_teardown_can_ctrls;
-
 	err = kvaser_pciefd_reg_candev(pcie);
 	if (err)
 		goto err_free_irq;
@@ -1856,6 +1861,8 @@
 	return 0;
 
 err_free_irq:
+	/* Disable PCI interrupts */
+	iowrite32(0, pcie->reg_base + KVASER_PCIEFD_IEN_REG);
 	free_irq(pcie->pci->irq, pcie);
 
 err_teardown_can_ctrls:
diff --git a/kernel/drivers/net/can/m_can/tcan4x5x.c b/kernel/drivers/net/can/m_can/tcan4x5x.c
index f169d90..f903f78 100644
--- a/kernel/drivers/net/can/m_can/tcan4x5x.c
+++ b/kernel/drivers/net/can/m_can/tcan4x5x.c
@@ -294,11 +294,6 @@
 	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)
diff --git a/kernel/drivers/net/can/rockchip/rockchip_canfd.c b/kernel/drivers/net/can/rockchip/rockchip_canfd.c
index abdcdb5..dba7f14 100644
--- a/kernel/drivers/net/can/rockchip/rockchip_canfd.c
+++ b/kernel/drivers/net/can/rockchip/rockchip_canfd.c
@@ -214,6 +214,8 @@
 #define CAN_RXFRD_OFFSET(n)	(CAN_RXFRD + CAN_RF_SIZE * (n))
 
 #define CAN_RX_FILTER_MASK	0x1fffffff
+#define NOACK_ERR_FLAG		0xc200800
+#define CAN_BUSOFF_FLAG		0x20
 
 #define DRV_NAME	"rockchip_canfd"
 
@@ -234,6 +236,7 @@
 	bool txtorx;
 	u32 tx_invalid[4];
 	struct delayed_work tx_err_work;
+	u32 delay_time_ms;
 };
 
 static inline u32 rockchip_canfd_read(const struct rockchip_canfd *priv,
@@ -357,6 +360,12 @@
 
 		rockchip_canfd_write(rcan, CAN_DBTP, reg_btp);
 	}
+	if (bt->bitrate > 200000)
+		rcan->delay_time_ms = 1;
+	else if (bt->bitrate > 50000)
+		rcan->delay_time_ms = 5;
+	else
+		rcan->delay_time_ms = 20;
 
 	netdev_dbg(ndev, "%s NBTP=0x%08x, DBTP=0x%08x, TDCR=0x%08x\n", __func__,
 		   rockchip_canfd_read(rcan, CAN_NBTP),
@@ -428,6 +437,10 @@
 	if (rcan->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
 		val |= MODE_SELF_TEST | MODE_LBACK;
 
+	/* Listen-only mode */
+	if (rcan->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+		val |= MODE_SILENT;
+
 	rockchip_canfd_write(rcan, CAN_MODE, val);
 
 	rockchip_canfd_set_bittiming(ndev);
@@ -487,13 +500,27 @@
 {
 	struct rockchip_canfd *rcan =
 		container_of(work, struct rockchip_canfd, tx_err_work.work);
-	u32 mode;
+	u32 mode, err_code;
 
 	mode = rockchip_canfd_read(rcan, CAN_MODE);
-	rockchip_canfd_write(rcan, CAN_MODE, 0);
-	rockchip_canfd_write(rcan, CAN_MODE, mode);
-	rockchip_canfd_write(rcan, CAN_CMD, CAN_TX0_REQ);
-	schedule_delayed_work(&rcan->tx_err_work, 1);
+	err_code = rockchip_canfd_read(rcan, CAN_ERR_CODE);
+	if ((err_code & NOACK_ERR_FLAG) == NOACK_ERR_FLAG) {
+		rockchip_canfd_write(rcan, CAN_MODE,
+				     rockchip_canfd_read(rcan, CAN_MODE) | MODE_SPACE_RX);
+		rockchip_canfd_write(rcan, CAN_CMD, CAN_TX0_REQ);
+		rockchip_canfd_write(rcan, CAN_MODE,
+				     rockchip_canfd_read(rcan, CAN_MODE) & (~MODE_SPACE_RX));
+		schedule_delayed_work(&rcan->tx_err_work, msecs_to_jiffies(rcan->delay_time_ms));
+	} else {
+		rockchip_canfd_write(rcan, CAN_MODE, 0);
+		rockchip_canfd_write(rcan, CAN_MODE, mode);
+		rockchip_canfd_write(rcan, CAN_MODE,
+				     rockchip_canfd_read(rcan, CAN_MODE) | MODE_SPACE_RX);
+		rockchip_canfd_write(rcan, CAN_CMD, CAN_TX0_REQ);
+		rockchip_canfd_write(rcan, CAN_MODE,
+				     rockchip_canfd_read(rcan, CAN_MODE) & (~MODE_SPACE_RX));
+		schedule_delayed_work(&rcan->tx_err_work, msecs_to_jiffies(rcan->delay_time_ms));
+	}
 }
 
 /* transmit a CAN message
@@ -569,10 +596,9 @@
 		for (i = 0; i < cf->len; i += 4)
 			rockchip_canfd_write(rcan, CAN_TXDAT0 + i,
 					     *(u32 *)(cf->data + i));
+		can_put_echo_skb(skb, ndev, 0);
 		rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ);
 		local_irq_restore(flags);
-		can_put_echo_skb(skb, ndev, 0);
-
 		return NETDEV_TX_OK;
 	}
 
@@ -583,12 +609,13 @@
 		rockchip_canfd_write(rcan, CAN_TXDAT0 + i,
 				     *(u32 *)(cf->data + i));
 
-	rockchip_canfd_write(rcan, CAN_CMD, cmd);
-
-	schedule_delayed_work(&rcan->tx_err_work, 1);
-
 	can_put_echo_skb(skb, ndev, 0);
-
+	rockchip_canfd_write(rcan, CAN_MODE,
+			     rockchip_canfd_read(rcan, CAN_MODE) | MODE_SPACE_RX);
+	rockchip_canfd_write(rcan, CAN_CMD, cmd);
+	rockchip_canfd_write(rcan, CAN_MODE,
+			     rockchip_canfd_read(rcan, CAN_MODE) & (~MODE_SPACE_RX));
+	schedule_delayed_work(&rcan->tx_err_work, msecs_to_jiffies(rcan->delay_time_ms));
 	return NETDEV_TX_OK;
 }
 
@@ -740,9 +767,6 @@
 		cf->data[7] = rxerr;
 	}
 
-	if (isr & TX_LOSTARB_INT)
-		schedule_delayed_work(&rcan->tx_err_work, 1);
-
 	if (isr & BUS_OFF_INT) {
 		rcan->can.state = CAN_STATE_BUS_OFF;
 		rcan->can.can_stats.bus_off++;
@@ -772,8 +796,14 @@
 	}
 
 	if (rcan->can.state >= CAN_STATE_BUS_OFF ||
-	    ((sta_reg & 0x20) == 0x20))
-		can_bus_off(ndev);
+	    ((sta_reg & CAN_BUSOFF_FLAG) == CAN_BUSOFF_FLAG)) {
+		cancel_delayed_work(&rcan->tx_err_work);
+		netif_stop_queue(ndev);
+		rockchip_canfd_stop(ndev);
+		can_free_echo_skb(ndev, 0);
+		rockchip_canfd_start(ndev);
+		netif_start_queue(ndev);
+	}
 
 	stats->rx_packets++;
 	stats->rx_bytes += cf->can_dlc;
@@ -788,13 +818,14 @@
 	struct rockchip_canfd *rcan = netdev_priv(ndev);
 	struct net_device_stats *stats = &ndev->stats;
 	u32 err_int = ERR_WARN_INT | RX_BUF_OV_INT | PASSIVE_ERR_INT |
-		      TX_LOSTARB_INT | BUS_ERR_INT | BUS_OFF_INT;
+		      BUS_ERR_INT | BUS_OFF_INT;
 	u32 isr;
 	u32 dlc = 0;
 	u32 quota, work_done = 0;
 
 	isr = rockchip_canfd_read(rcan, CAN_INT);
 	if (isr & TX_FINISH_INT) {
+		cancel_delayed_work(&rcan->tx_err_work);
 		dlc = rockchip_canfd_read(rcan, CAN_TXFIC);
 		/* transmission complete interrupt */
 		if (dlc & FDF_MASK)
@@ -802,7 +833,6 @@
 		else
 			stats->tx_bytes += (dlc & DLC_MASK);
 		stats->tx_packets++;
-		cancel_delayed_work(&rcan->tx_err_work);
 		if (rcan->txtorx && rcan->mode <= ROCKCHIP_RK3568_CAN_MODE && dlc & FORMAT_MASK) {
 			rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC, FORMAT_MASK);
 			quota = rockchip_canfd_get_rx_fifo_cnt(ndev);
@@ -814,6 +844,10 @@
 				rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ);
 			rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC, 0);
 		}
+		if (read_poll_timeout_atomic(rockchip_canfd_read, quota,
+					     !(quota & 0x3),
+					     0, 5000000, false, rcan, CAN_CMD))
+			netdev_err(ndev, "Warning: wait tx req timeout!\n");
 		rockchip_canfd_write(rcan, CAN_CMD, 0);
 		can_get_echo_skb(ndev, 0);
 		netif_wake_queue(ndev);
@@ -825,7 +859,10 @@
 			rockchip_canfd_write(rcan, CAN_INT_MASK, 0x1);
 			napi_schedule(&rcan->napi);
 		} else {
-			quota = rockchip_canfd_get_rx_fifo_cnt(ndev);
+			work_done = 0;
+			quota = (rockchip_canfd_read(rcan, CAN_RXFC) &
+				 rcan->rx_fifo_mask) >>
+				rcan->rx_fifo_shift;
 			if (quota) {
 				while (work_done < quota)
 					work_done += rockchip_canfd_rx(ndev);
diff --git a/kernel/drivers/net/can/usb/esd_usb2.c b/kernel/drivers/net/can/usb/esd_usb2.c
index 73c5343..c9ccce6 100644
--- a/kernel/drivers/net/can/usb/esd_usb2.c
+++ b/kernel/drivers/net/can/usb/esd_usb2.c
@@ -278,7 +278,6 @@
 				cf->data[2] |= CAN_ERR_PROT_STUFF;
 				break;
 			default:
-				cf->data[3] = ecc & SJA1000_ECC_SEG;
 				break;
 			}
 
@@ -286,6 +285,9 @@
 			if (!(ecc & SJA1000_ECC_DIR))
 				cf->data[2] |= CAN_ERR_PROT_TX;
 
+			/* Bit stream position in CAN frame as the error was detected */
+			cf->data[3] = ecc & SJA1000_ECC_SEG;
+
 			if (priv->can.state == CAN_STATE_ERROR_WARNING ||
 			    priv->can.state == CAN_STATE_ERROR_PASSIVE) {
 				cf->data[1] = (txerr > rxerr) ?
diff --git a/kernel/drivers/net/can/usb/gs_usb.c b/kernel/drivers/net/can/usb/gs_usb.c
index a879200..864db20 100644
--- a/kernel/drivers/net/can/usb/gs_usb.c
+++ b/kernel/drivers/net/can/usb/gs_usb.c
@@ -381,6 +381,9 @@
 	}
 
 	if (hf->flags & GS_CAN_FLAG_OVERFLOW) {
+		stats->rx_over_errors++;
+		stats->rx_errors++;
+
 		skb = alloc_can_err_skb(netdev, &cf);
 		if (!skb)
 			goto resubmit_urb;
@@ -388,8 +391,6 @@
 		cf->can_id |= CAN_ERR_CRTL;
 		cf->can_dlc = CAN_ERR_DLC;
 		cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
-		stats->rx_over_errors++;
-		stats->rx_errors++;
 		netif_rx(skb);
 	}
 
@@ -732,6 +733,8 @@
 	usb_kill_anchored_urbs(&dev->tx_submitted);
 	atomic_set(&dev->active_tx_urbs, 0);
 
+	dev->can.state = CAN_STATE_STOPPED;
+
 	/* reset the device */
 	rc = gs_cmd_reset(dev);
 	if (rc < 0)
diff --git a/kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
index 62958f0..5699531 100644
--- a/kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+++ b/kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
@@ -76,6 +76,14 @@
 	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;
@@ -104,12 +112,18 @@
 	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;
 
-	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;
@@ -120,11 +134,15 @@
  * 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
  * @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
@@ -140,12 +158,18 @@
  */
 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);
 	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/kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
index 7491f85..1f015b4 100644
--- a/kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+++ b/kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
@@ -416,10 +416,6 @@
 	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;
@@ -508,6 +504,93 @@
 	close_candev(priv->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)
@@ -645,6 +728,7 @@
 
 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++) {
@@ -659,6 +743,9 @@
 	for (i = 0; i < dev->nchannels; i++) {
 		if (!dev->nets[i])
 			continue;
+
+		if (ops->dev_remove_channel)
+			ops->dev_remove_channel(dev->nets[i]);
 
 		free_candev(dev->nets[i]->netdev);
 	}
@@ -691,6 +778,7 @@
 	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;
@@ -703,7 +791,7 @@
 	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))
@@ -715,7 +803,7 @@
 
 	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;
@@ -727,17 +815,26 @@
 
 	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/kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
index 45d2787..233bbfe 100644
--- a/kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+++ b/kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
@@ -43,6 +43,8 @@
 
 /* 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,19 +195,24 @@
 #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_nominal;
 	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;
+
+/* 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 */
@@ -278,6 +285,8 @@
 		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;
 
@@ -293,6 +302,7 @@
 #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)
@@ -358,6 +368,10 @@
 		struct kvaser_cmd_ext_tx_ack tx_ack;
 	} __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",
@@ -504,6 +518,7 @@
 					    u8 cmd_no, int channel)
 {
 	struct kvaser_cmd *cmd;
+	size_t cmd_len;
 	int err;
 
 	cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL);
@@ -511,6 +526,7 @@
 		return -ENOMEM;
 
 	cmd->header.cmd_no = cmd_no;
+	cmd_len = kvaser_usb_hydra_cmd_size(cmd);
 	if (channel < 0) {
 		kvaser_usb_hydra_set_cmd_dest_he
 				(cmd, KVASER_USB_HYDRA_HE_ADDRESS_ILLEGAL);
@@ -527,7 +543,7 @@
 	kvaser_usb_hydra_set_cmd_transid
 				(cmd, kvaser_usb_hydra_get_next_transid(dev));
 
-	err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
+	err = kvaser_usb_send_cmd(dev, cmd, cmd_len);
 	if (err)
 		goto end;
 
@@ -543,6 +559,7 @@
 {
 	struct kvaser_cmd *cmd;
 	struct kvaser_usb *dev = priv->dev;
+	size_t cmd_len;
 	int err;
 
 	cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_ATOMIC);
@@ -550,14 +567,14 @@
 		return -ENOMEM;
 
 	cmd->header.cmd_no = cmd_no;
+	cmd_len = kvaser_usb_hydra_cmd_size(cmd);
 
 	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));
 
-	err = kvaser_usb_send_cmd_async(priv, cmd,
-					kvaser_usb_hydra_cmd_size(cmd));
+	err = kvaser_usb_send_cmd_async(priv, cmd, cmd_len);
 	if (err)
 		kfree(cmd);
 
@@ -701,6 +718,7 @@
 {
 	struct kvaser_usb_dev_card_data *card_data = &dev->card_data;
 	struct kvaser_cmd *cmd;
+	size_t cmd_len;
 	u32 value = 0;
 	u32 mask = 0;
 	u16 cap_cmd_res;
@@ -712,13 +730,14 @@
 		return -ENOMEM;
 
 	cmd->header.cmd_no = CMD_GET_CAPABILITIES_REQ;
+	cmd_len = kvaser_usb_hydra_cmd_size(cmd);
 	cmd->cap_req.cap_cmd = cpu_to_le16(cap_cmd_req);
 
 	kvaser_usb_hydra_set_cmd_dest_he(cmd, card_data->hydra.sysdbg_he);
 	kvaser_usb_hydra_set_cmd_transid
 				(cmd, kvaser_usb_hydra_get_next_transid(dev));
 
-	err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
+	err = kvaser_usb_send_cmd(dev, cmd, cmd_len);
 	if (err)
 		goto end;
 
@@ -810,6 +829,39 @@
 		return;
 
 	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
@@ -1099,6 +1151,7 @@
 	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 +1170,13 @@
 			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++;
@@ -1292,6 +1348,10 @@
 
 	case CMD_CHIP_STATE_EVENT:
 		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:
@@ -1494,15 +1554,61 @@
 	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;
+	size_t cmd_len;
+	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;
+	cmd_len = kvaser_usb_hydra_cmd_size(cmd);
+	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, cmd_len);
+	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;
+	size_t cmd_len;
 	int err;
 
 	cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL);
@@ -1510,33 +1616,29 @@
 		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_len = kvaser_usb_hydra_cmd_size(cmd);
+	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]);
 	kvaser_usb_hydra_set_cmd_transid
 				(cmd, kvaser_usb_hydra_get_next_transid(dev));
 
-	err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
+	err = kvaser_usb_send_cmd(dev, cmd, cmd_len);
 
 	kfree(cmd);
 
 	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;
+	size_t cmd_len;
 	int err;
 
 	cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL);
@@ -1544,11 +1646,9 @@
 		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_len = kvaser_usb_hydra_cmd_size(cmd);
+	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)
@@ -1564,7 +1664,7 @@
 	kvaser_usb_hydra_set_cmd_transid
 				(cmd, kvaser_usb_hydra_get_next_transid(dev));
 
-	err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
+	err = kvaser_usb_send_cmd(dev, cmd, cmd_len);
 
 	kfree(cmd);
 
@@ -1655,6 +1755,19 @@
 	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;
@@ -1679,6 +1792,7 @@
 static int kvaser_usb_hydra_get_software_details(struct kvaser_usb *dev)
 {
 	struct kvaser_cmd *cmd;
+	size_t cmd_len;
 	int err;
 	u32 flags;
 	struct kvaser_usb_dev_card_data *card_data = &dev->card_data;
@@ -1688,6 +1802,7 @@
 		return -ENOMEM;
 
 	cmd->header.cmd_no = CMD_GET_SOFTWARE_DETAILS_REQ;
+	cmd_len = kvaser_usb_hydra_cmd_size(cmd);
 	cmd->sw_detail_req.use_ext_cmd = 1;
 	kvaser_usb_hydra_set_cmd_dest_he
 				(cmd, KVASER_USB_HYDRA_HE_ADDRESS_ILLEGAL);
@@ -1695,7 +1810,7 @@
 	kvaser_usb_hydra_set_cmd_transid
 				(cmd, kvaser_usb_hydra_get_next_transid(dev));
 
-	err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
+	err = kvaser_usb_send_cmd(dev, cmd, cmd_len);
 	if (err)
 		goto end;
 
@@ -1811,6 +1926,7 @@
 {
 	struct kvaser_usb *dev = priv->dev;
 	struct kvaser_cmd *cmd;
+	size_t cmd_len;
 	int err;
 
 	if ((priv->can.ctrlmode &
@@ -1826,6 +1942,7 @@
 		return -ENOMEM;
 
 	cmd->header.cmd_no = CMD_SET_DRIVERMODE_REQ;
+	cmd_len = kvaser_usb_hydra_cmd_size(cmd);
 	kvaser_usb_hydra_set_cmd_dest_he
 		(cmd, dev->card_data.hydra.channel_to_he[priv->channel]);
 	kvaser_usb_hydra_set_cmd_transid
@@ -1835,7 +1952,7 @@
 	else
 		cmd->set_ctrlmode.mode = KVASER_USB_HYDRA_CTRLMODE_NORMAL;
 
-	err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
+	err = kvaser_usb_send_cmd(dev, cmd, cmd_len);
 	kfree(cmd);
 
 	return err;
@@ -1997,10 +2114,13 @@
 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/kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
index 15380cc..f06d63d 100644
--- a/kernel/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+++ b/kernel/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,9 @@
 #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
 #define CMD_RESET_CHIP			24
@@ -69,10 +73,13 @@
 #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
 #define CMD_FLUSH_QUEUE_REPLY		68
+#define CMD_GET_CAPABILITIES_REQ	95
+#define CMD_GET_CAPABILITIES_RESP	96
 
 #define CMD_LEAF_LOG_MESSAGE		106
 
@@ -81,6 +88,8 @@
 #define KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK 0
 #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)
@@ -156,11 +165,7 @@
 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 {
@@ -229,7 +234,7 @@
 	u8 tid;
 } __packed;
 
-struct leaf_cmd_error_event {
+struct leaf_cmd_can_error_event {
 	u8 tid;
 	u8 flags;
 	__le16 time[3];
@@ -241,7 +246,7 @@
 	u8 error_factor;
 } __packed;
 
-struct usbcan_cmd_error_event {
+struct usbcan_cmd_can_error_event {
 	u8 tid;
 	u8 padding;
 	u8 tx_errors_count_ch0;
@@ -251,6 +256,28 @@
 	u8 status_ch0;
 	u8 status_ch1;
 	__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 {
@@ -277,6 +304,28 @@
 	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;
@@ -292,14 +341,18 @@
 			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 leaf_cmd_error_event error_event;
+			struct kvaser_cmd_cap_req cap_req;
+			struct kvaser_cmd_cap_res cap_res;
 		} __packed leaf;
 
 		union {
 			struct usbcan_cmd_softinfo softinfo;
 			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;
 
@@ -322,7 +375,10 @@
 	[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),
+	[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,
 };
@@ -336,7 +392,8 @@
 	[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),
+	[CMD_ERROR_EVENT]		= kvaser_fsize(u.usbcan.error_event),
 	/* ignored events: */
 	[CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY,
 };
@@ -362,6 +419,12 @@
 			u8 error_state;
 		} usbcan;
 	};
+};
+
+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 = {
@@ -607,6 +670,9 @@
 	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 +760,116 @@
 	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)
 {
@@ -722,7 +898,7 @@
 	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;
 
@@ -778,6 +954,16 @@
 	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,
@@ -796,20 +982,16 @@
 		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;
@@ -819,7 +1001,7 @@
 	}
 
 	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++;
 
@@ -853,6 +1035,7 @@
 	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) {
@@ -862,7 +1045,12 @@
 	}
 
 	priv = dev->nets[es->channel];
+	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.
@@ -877,6 +1065,14 @@
 	old_state = priv->can.state;
 	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) {
@@ -895,7 +1091,7 @@
 		}
 
 		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);
@@ -995,11 +1191,11 @@
 
 	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.
@@ -1007,13 +1203,13 @@
 		 */
 		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;
@@ -1030,11 +1226,11 @@
 
 	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;
@@ -1166,6 +1362,74 @@
 	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)
 {
@@ -1206,6 +1470,25 @@
 	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)
 {
@@ -1242,6 +1525,14 @@
 
 	case CMD_TX_ACKNOWLEDGE:
 		kvaser_usb_leaf_tx_acknowledge(dev, cmd);
+		break;
+
+	case CMD_ERROR_EVENT:
+		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 */
@@ -1340,9 +1631,12 @@
 
 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);
@@ -1390,10 +1684,35 @@
 	return 0;
 }
 
-static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev)
+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(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;
@@ -1406,20 +1725,34 @@
 	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;
-
-	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
-		cmd->u.busparams.no_samp = 3;
-	else
-		cmd->u.busparams.no_samp = 1;
+	memcpy(&cmd->u.busparams.busparams, busparams,
+	       sizeof(cmd->u.busparams.busparams));
 
 	rc = kvaser_usb_send_cmd(dev, cmd, cmd->len);
 
 	kfree(cmd);
 	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,
@@ -1483,14 +1816,18 @@
 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,
+	.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,
-	.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,
diff --git a/kernel/drivers/net/can/vxcan.c b/kernel/drivers/net/can/vxcan.c
index 282c53e..1bfede4 100644
--- a/kernel/drivers/net/can/vxcan.c
+++ b/kernel/drivers/net/can/vxcan.c
@@ -179,12 +179,7 @@
 
 		nla_peer = data[VXCAN_INFO_PEER];
 		ifmp = nla_data(nla_peer);
-		err = rtnl_nla_parse_ifla(peer_tb,
-					  nla_data(nla_peer) +
-					  sizeof(struct ifinfomsg),
-					  nla_len(nla_peer) -
-					  sizeof(struct ifinfomsg),
-					  NULL);
+		err = rtnl_nla_parse_ifinfomsg(peer_tb, nla_peer, extack);
 		if (err < 0)
 			return err;
 
diff --git a/kernel/drivers/net/dsa/b53/b53_mmap.c b/kernel/drivers/net/dsa/b53/b53_mmap.c
index c628d09..1d52cb3 100644
--- a/kernel/drivers/net/dsa/b53/b53_mmap.c
+++ b/kernel/drivers/net/dsa/b53/b53_mmap.c
@@ -215,6 +215,18 @@
 	return 0;
 }
 
+static int b53_mmap_phy_read16(struct b53_device *dev, int addr, int reg,
+			       u16 *value)
+{
+	return -EIO;
+}
+
+static int b53_mmap_phy_write16(struct b53_device *dev, int addr, int reg,
+				u16 value)
+{
+	return -EIO;
+}
+
 static const struct b53_io_ops b53_mmap_ops = {
 	.read8 = b53_mmap_read8,
 	.read16 = b53_mmap_read16,
@@ -226,6 +238,8 @@
 	.write32 = b53_mmap_write32,
 	.write48 = b53_mmap_write48,
 	.write64 = b53_mmap_write64,
+	.phy_read16 = b53_mmap_phy_read16,
+	.phy_write16 = b53_mmap_phy_write16,
 };
 
 static int b53_mmap_probe(struct platform_device *pdev)
diff --git a/kernel/drivers/net/dsa/bcm_sf2.c b/kernel/drivers/net/dsa/bcm_sf2.c
index c6563d2..f2f890e 100644
--- a/kernel/drivers/net/dsa/bcm_sf2.c
+++ b/kernel/drivers/net/dsa/bcm_sf2.c
@@ -1301,7 +1301,9 @@
 	if (IS_ERR(priv->clk))
 		return PTR_ERR(priv->clk);
 
-	clk_prepare_enable(priv->clk);
+	ret = clk_prepare_enable(priv->clk);
+	if (ret)
+		return ret;
 
 	priv->clk_mdiv = devm_clk_get_optional(&pdev->dev, "sw_switch_mdiv");
 	if (IS_ERR(priv->clk_mdiv)) {
@@ -1309,7 +1311,9 @@
 		goto out_clk;
 	}
 
-	clk_prepare_enable(priv->clk_mdiv);
+	ret = clk_prepare_enable(priv->clk_mdiv);
+	if (ret)
+		goto out_clk;
 
 	ret = bcm_sf2_sw_rst(priv);
 	if (ret) {
diff --git a/kernel/drivers/net/dsa/lan9303-core.c b/kernel/drivers/net/dsa/lan9303-core.c
index c79bb8c..f5ab0bf 100644
--- a/kernel/drivers/net/dsa/lan9303-core.c
+++ b/kernel/drivers/net/dsa/lan9303-core.c
@@ -1002,9 +1002,11 @@
 		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;
 	}
 }
@@ -1185,8 +1187,6 @@
 	struct lan9303 *chip = ds->priv;
 
 	dev_dbg(chip->dev, "%s(%d, %pM, %d)\n", __func__, port, addr, vid);
-	if (vid)
-		return -EOPNOTSUPP;
 
 	return lan9303_alr_add_port(chip, addr, port, false);
 }
@@ -1198,8 +1198,6 @@
 	struct lan9303 *chip = ds->priv;
 
 	dev_dbg(chip->dev, "%s(%d, %pM, %d)\n", __func__, port, addr, vid);
-	if (vid)
-		return -EOPNOTSUPP;
 	lan9303_alr_del_port(chip, addr, port);
 
 	return 0;
diff --git a/kernel/drivers/net/dsa/microchip/ksz9477.c b/kernel/drivers/net/dsa/microchip/ksz9477.c
index ece4c05..f42f2f4 100644
--- a/kernel/drivers/net/dsa/microchip/ksz9477.c
+++ b/kernel/drivers/net/dsa/microchip/ksz9477.c
@@ -678,10 +678,10 @@
 		ksz_read32(dev, REG_SW_ALU_VAL_D, &alu_table[3]);
 
 		/* clear forwarding port */
-		alu_table[2] &= ~BIT(port);
+		alu_table[1] &= ~BIT(port);
 
 		/* if there is no port to forward, clear table */
-		if ((alu_table[2] & ALU_V_PORT_MAP) == 0) {
+		if ((alu_table[1] & ALU_V_PORT_MAP) == 0) {
 			alu_table[0] = 0;
 			alu_table[1] = 0;
 			alu_table[2] = 0;
diff --git a/kernel/drivers/net/dsa/mt7530.c b/kernel/drivers/net/dsa/mt7530.c
index 70155e9..4056ca4 100644
--- a/kernel/drivers/net/dsa/mt7530.c
+++ b/kernel/drivers/net/dsa/mt7530.c
@@ -404,9 +404,9 @@
 	case PHY_INTERFACE_MODE_TRGMII:
 		trgint = 1;
 		if (priv->id == ID_MT7621) {
-			/* PLL frequency: 150MHz: 1.2GBit */
+			/* PLL frequency: 125MHz: 1.0GBit */
 			if (xtal == HWTRAP_XTAL_40MHZ)
-				ncpo1 = 0x0780;
+				ncpo1 = 0x0640;
 			if (xtal == HWTRAP_XTAL_25MHZ)
 				ncpo1 = 0x0a00;
 		} else { /* PLL frequency: 250MHz: 2.0Gbit */
@@ -966,7 +966,7 @@
 	mt7530_rmw(priv, MT7530_MFC, UNM_FFP_MASK, UNM_FFP(BIT(port)));
 
 	/* Set CPU port number */
-	if (priv->id == ID_MT7621)
+	if (priv->id == ID_MT7530 || priv->id == ID_MT7621)
 		mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port));
 
 	/* CPU port gets connected to all user ports of
diff --git a/kernel/drivers/net/dsa/mv88e6xxx/chip.c b/kernel/drivers/net/dsa/mv88e6xxx/chip.c
index 371b345..53fbef9 100644
--- a/kernel/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/kernel/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2310,12 +2310,22 @@
 
 	/* If there is a GPIO connected to the reset pin, toggle it */
 	if (gpiod) {
+		/* If the switch has just been reset and not yet completed
+		 * loading EEPROM, the reset may interrupt the I2C transaction
+		 * mid-byte, causing the first EEPROM read after the reset
+		 * from the wrong location resulting in the switch booting
+		 * to wrong mode and inoperable.
+		 */
+		if (chip->info->ops->get_eeprom)
+			mv88e6xxx_g2_eeprom_wait(chip);
+
 		gpiod_set_value_cansleep(gpiod, 1);
 		usleep_range(10000, 20000);
 		gpiod_set_value_cansleep(gpiod, 0);
 		usleep_range(10000, 20000);
 
-		mv88e6xxx_g1_wait_eeprom_done(chip);
+		if (chip->info->ops->get_eeprom)
+			mv88e6xxx_g2_eeprom_wait(chip);
 	}
 }
 
@@ -2611,9 +2621,14 @@
 	 * If this is the upstream port for this switch, enable
 	 * forwarding of unknown unicasts and multicasts.
 	 */
-	reg = MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP |
-		MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP |
+	reg = MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP |
 		MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
+	/* Forward any IPv4 IGMP or IPv6 MLD frames received
+	 * by a USER port to the CPU port to allow snooping.
+	 */
+	if (dsa_is_user_port(ds, port))
+		reg |= MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP;
+
 	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
 	if (err)
 		return err;
@@ -2734,13 +2749,24 @@
 		return 10240 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
 	else if (chip->info->ops->set_max_frame_size)
 		return 1632 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
-	return 1522 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
+	return ETH_DATA_LEN;
 }
 
 static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
 {
 	struct mv88e6xxx_chip *chip = ds->priv;
 	int ret = 0;
+
+	/* For families where we don't know how to alter the MTU,
+	 * just accept any value up to ETH_DATA_LEN
+	 */
+	if (!chip->info->ops->port_set_jumbo_size &&
+	    !chip->info->ops->set_max_frame_size) {
+		if (new_mtu > ETH_DATA_LEN)
+			return -EINVAL;
+
+		return 0;
+	}
 
 	if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
 		new_mtu += EDSA_HLEN;
@@ -2750,9 +2776,6 @@
 		ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu);
 	else if (chip->info->ops->set_max_frame_size)
 		ret = chip->info->ops->set_max_frame_size(chip, new_mtu);
-	else
-		if (new_mtu > 1522)
-			ret = -EINVAL;
 	mv88e6xxx_reg_unlock(chip);
 
 	return ret;
@@ -4169,6 +4192,7 @@
 	.set_cpu_port = mv88e6095_g1_set_cpu_port,
 	.set_egress_port = mv88e6095_g1_set_egress_port,
 	.watchdog_ops = &mv88e6390_watchdog_ops,
+	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.reset = mv88e6352_g1_reset,
 	.vtu_getnext = mv88e6185_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
@@ -5533,7 +5557,7 @@
 		goto out;
 	}
 	if (chip->reset)
-		usleep_range(1000, 2000);
+		usleep_range(10000, 20000);
 
 	err = mv88e6xxx_detect(chip);
 	if (err)
diff --git a/kernel/drivers/net/dsa/mv88e6xxx/global1.c b/kernel/drivers/net/dsa/mv88e6xxx/global1.c
index 9936ae6..ff43d9c 100644
--- a/kernel/drivers/net/dsa/mv88e6xxx/global1.c
+++ b/kernel/drivers/net/dsa/mv88e6xxx/global1.c
@@ -75,37 +75,6 @@
 	return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1);
 }
 
-void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip)
-{
-	const unsigned long timeout = jiffies + 1 * HZ;
-	u16 val;
-	int err;
-
-	/* Wait up to 1 second for the switch to finish reading the
-	 * EEPROM.
-	 */
-	while (time_before(jiffies, timeout)) {
-		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &val);
-		if (err) {
-			dev_err(chip->dev, "Error reading status");
-			return;
-		}
-
-		/* If the switch is still resetting, it may not
-		 * respond on the bus, and so MDIO read returns
-		 * 0xffff. Differentiate between that, and waiting for
-		 * the EEPROM to be done by bit 0 being set.
-		 */
-		if (val != 0xffff &&
-		    val & BIT(MV88E6XXX_G1_STS_IRQ_EEPROM_DONE))
-			return;
-
-		usleep_range(1000, 2000);
-	}
-
-	dev_err(chip->dev, "Timeout waiting for EEPROM done");
-}
-
 /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1
  * Offset 0x02: Switch MAC Address Register Bytes 2 & 3
  * Offset 0x03: Switch MAC Address Register Bytes 4 & 5
diff --git a/kernel/drivers/net/dsa/mv88e6xxx/global1.h b/kernel/drivers/net/dsa/mv88e6xxx/global1.h
index e05abe6..1e3546f 100644
--- a/kernel/drivers/net/dsa/mv88e6xxx/global1.h
+++ b/kernel/drivers/net/dsa/mv88e6xxx/global1.h
@@ -278,7 +278,6 @@
 int mv88e6185_g1_reset(struct mv88e6xxx_chip *chip);
 int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip);
 int mv88e6250_g1_reset(struct mv88e6xxx_chip *chip);
-void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip);
 
 int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip);
 int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip);
diff --git a/kernel/drivers/net/dsa/mv88e6xxx/global2.c b/kernel/drivers/net/dsa/mv88e6xxx/global2.c
index 75b227d..8607b24 100644
--- a/kernel/drivers/net/dsa/mv88e6xxx/global2.c
+++ b/kernel/drivers/net/dsa/mv88e6xxx/global2.c
@@ -323,7 +323,7 @@
  * Offset 0x15: EEPROM Addr (for 8-bit data access)
  */
 
-static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
+int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
 {
 	int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY);
 	int err;
diff --git a/kernel/drivers/net/dsa/mv88e6xxx/global2.h b/kernel/drivers/net/dsa/mv88e6xxx/global2.h
index 1f42ee6..de63e3f 100644
--- a/kernel/drivers/net/dsa/mv88e6xxx/global2.h
+++ b/kernel/drivers/net/dsa/mv88e6xxx/global2.h
@@ -349,6 +349,7 @@
 
 int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target,
 				      int port);
+int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip);
 
 extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops;
 extern const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops;
diff --git a/kernel/drivers/net/dsa/sja1105/sja1105_main.c b/kernel/drivers/net/dsa/sja1105/sja1105_main.c
index c03d76c..4362fe0 100644
--- a/kernel/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/kernel/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1691,6 +1691,18 @@
 
 #define BYTES_PER_KBIT (1000LL / 8)
 
+static int sja1105_find_cbs_shaper(struct sja1105_private *priv,
+				   int port, int prio)
+{
+	int i;
+
+	for (i = 0; i < priv->info->num_cbs_shapers; i++)
+		if (priv->cbs[i].port == port && priv->cbs[i].prio == prio)
+			return i;
+
+	return -1;
+}
+
 static int sja1105_find_unused_cbs_shaper(struct sja1105_private *priv)
 {
 	int i;
@@ -1725,14 +1737,20 @@
 {
 	struct sja1105_private *priv = ds->priv;
 	struct sja1105_cbs_entry *cbs;
+	s64 port_transmit_rate_kbps;
 	int index;
 
 	if (!offload->enable)
 		return sja1105_delete_cbs_shaper(priv, port, offload->queue);
 
-	index = sja1105_find_unused_cbs_shaper(priv);
-	if (index < 0)
-		return -ENOSPC;
+	/* The user may be replacing an existing shaper */
+	index = sja1105_find_cbs_shaper(priv, port, offload->queue);
+	if (index < 0) {
+		/* That isn't the case - see if we can allocate a new one */
+		index = sja1105_find_unused_cbs_shaper(priv);
+		if (index < 0)
+			return -ENOSPC;
+	}
 
 	cbs = &priv->cbs[index];
 	cbs->port = port;
@@ -1742,9 +1760,17 @@
 	 */
 	cbs->credit_hi = offload->hicredit;
 	cbs->credit_lo = abs(offload->locredit);
-	/* User space is in kbits/sec, hardware in bytes/sec */
-	cbs->idle_slope = offload->idleslope * BYTES_PER_KBIT;
-	cbs->send_slope = abs(offload->sendslope * BYTES_PER_KBIT);
+	/* User space is in kbits/sec, while the hardware in bytes/sec times
+	 * link speed. Since the given offload->sendslope is good only for the
+	 * current link speed anyway, and user space is likely to reprogram it
+	 * when that changes, don't even bother to track the port's link speed,
+	 * but deduce the port transmit rate from idleslope - sendslope.
+	 */
+	port_transmit_rate_kbps = offload->idleslope - offload->sendslope;
+	cbs->idle_slope = div_s64(offload->idleslope * BYTES_PER_KBIT,
+				  port_transmit_rate_kbps);
+	cbs->send_slope = div_s64(abs(offload->sendslope * BYTES_PER_KBIT),
+				  port_transmit_rate_kbps);
 	/* Convert the negative values from 64-bit 2's complement
 	 * to 32-bit 2's complement (for the case of 0x80000000 whose
 	 * negative is still negative).
diff --git a/kernel/drivers/net/dsa/vitesse-vsc73xx-core.c b/kernel/drivers/net/dsa/vitesse-vsc73xx-core.c
index 19ce4aa..80eadf5 100644
--- a/kernel/drivers/net/dsa/vitesse-vsc73xx-core.c
+++ b/kernel/drivers/net/dsa/vitesse-vsc73xx-core.c
@@ -1025,17 +1025,17 @@
 	struct vsc73xx *vsc = ds->priv;
 
 	return vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, port,
-			     VSC73XX_MAXLEN, new_mtu);
+			     VSC73XX_MAXLEN, new_mtu + ETH_HLEN + ETH_FCS_LEN);
 }
 
 /* According to application not "VSC7398 Jumbo Frames" setting
- * up the MTU to 9.6 KB does not affect the performance on standard
+ * up the frame size to 9.6 KB does not affect the performance on standard
  * frames. It is clear from the application note that
  * "9.6 kilobytes" == 9600 bytes.
  */
 static int vsc73xx_get_max_mtu(struct dsa_switch *ds, int port)
 {
-	return 9600;
+	return 9600 - ETH_HLEN - ETH_FCS_LEN;
 }
 
 static const struct dsa_switch_ops vsc73xx_ds_ops = {
diff --git a/kernel/drivers/net/ethernet/3com/3c589_cs.c b/kernel/drivers/net/ethernet/3com/3c589_cs.c
index 09816e8..0197ef6 100644
--- a/kernel/drivers/net/ethernet/3com/3c589_cs.c
+++ b/kernel/drivers/net/ethernet/3com/3c589_cs.c
@@ -195,6 +195,7 @@
 {
 	struct el3_private *lp;
 	struct net_device *dev;
+	int ret;
 
 	dev_dbg(&link->dev, "3c589_attach()\n");
 
@@ -218,7 +219,15 @@
 
 	dev->ethtool_ops = &netdev_ethtool_ops;
 
-	return tc589_config(link);
+	ret = tc589_config(link);
+	if (ret)
+		goto err_free_netdev;
+
+	return 0;
+
+err_free_netdev:
+	free_netdev(dev);
+	return ret;
 }
 
 static void tc589_detach(struct pcmcia_device *link)
diff --git a/kernel/drivers/net/ethernet/amazon/ena/ena_com.c b/kernel/drivers/net/ethernet/amazon/ena/ena_com.c
index 5f8769a..d59ea51 100644
--- a/kernel/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/kernel/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -35,6 +35,8 @@
 
 #define ENA_REGS_ADMIN_INTR_MASK 1
 
+#define ENA_MAX_BACKOFF_DELAY_EXP 16U
+
 #define ENA_MIN_ADMIN_POLL_US 100
 
 #define ENA_MAX_ADMIN_POLL_US 5000
@@ -522,6 +524,7 @@
 
 static void ena_delay_exponential_backoff_us(u32 exp, u32 delay_us)
 {
+	exp = min_t(u32, exp, ENA_MAX_BACKOFF_DELAY_EXP);
 	delay_us = max_t(u32, ENA_MIN_ADMIN_POLL_US, delay_us);
 	delay_us = min_t(u32, delay_us * (1U << exp), ENA_MAX_ADMIN_POLL_US);
 	usleep_range(delay_us, 2 * delay_us);
diff --git a/kernel/drivers/net/ethernet/amd/atarilance.c b/kernel/drivers/net/ethernet/amd/atarilance.c
index 961796a..5e8b72d 100644
--- a/kernel/drivers/net/ethernet/amd/atarilance.c
+++ b/kernel/drivers/net/ethernet/amd/atarilance.c
@@ -825,7 +825,7 @@
 	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/kernel/drivers/net/ethernet/amd/lance.c b/kernel/drivers/net/ethernet/amd/lance.c
index aff4424..9dae225 100644
--- a/kernel/drivers/net/ethernet/amd/lance.c
+++ b/kernel/drivers/net/ethernet/amd/lance.c
@@ -997,7 +997,7 @@
 		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;
diff --git a/kernel/drivers/net/ethernet/amd/nmclan_cs.c b/kernel/drivers/net/ethernet/amd/nmclan_cs.c
index 11c0b13..f348816 100644
--- a/kernel/drivers/net/ethernet/amd/nmclan_cs.c
+++ b/kernel/drivers/net/ethernet/amd/nmclan_cs.c
@@ -650,7 +650,7 @@
     } else {
       pr_notice("mace id not found: %x %x should be 0x40 0x?9\n",
 		sig[0], sig[1]);
-      return -ENODEV;
+      goto failed;
     }
   }
 
diff --git a/kernel/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/kernel/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index d5fd49d..decc1c0 100644
--- a/kernel/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/kernel/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -524,19 +524,28 @@
 	netif_dbg(pdata, drv, pdata->netdev, "VXLAN acceleration disabled\n");
 }
 
+static unsigned int xgbe_get_fc_queue_count(struct xgbe_prv_data *pdata)
+{
+	unsigned int max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
+
+	/* From MAC ver 30H the TFCR is per priority, instead of per queue */
+	if (XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) >= 0x30)
+		return max_q_count;
+	else
+		return min_t(unsigned int, pdata->tx_q_count, max_q_count);
+}
+
 static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata)
 {
-	unsigned int max_q_count, q_count;
 	unsigned int reg, reg_val;
-	unsigned int i;
+	unsigned int i, q_count;
 
 	/* Clear MTL flow control */
 	for (i = 0; i < pdata->rx_q_count; i++)
 		XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 0);
 
 	/* Clear MAC flow control */
-	max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
-	q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count);
+	q_count = xgbe_get_fc_queue_count(pdata);
 	reg = MAC_Q0TFCR;
 	for (i = 0; i < q_count; i++) {
 		reg_val = XGMAC_IOREAD(pdata, reg);
@@ -553,9 +562,8 @@
 {
 	struct ieee_pfc *pfc = pdata->pfc;
 	struct ieee_ets *ets = pdata->ets;
-	unsigned int max_q_count, q_count;
 	unsigned int reg, reg_val;
-	unsigned int i;
+	unsigned int i, q_count;
 
 	/* Set MTL flow control */
 	for (i = 0; i < pdata->rx_q_count; i++) {
@@ -579,8 +587,7 @@
 	}
 
 	/* Set MAC flow control */
-	max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
-	q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count);
+	q_count = xgbe_get_fc_queue_count(pdata);
 	reg = MAC_Q0TFCR;
 	for (i = 0; i < q_count; i++) {
 		reg_val = XGMAC_IOREAD(pdata, reg);
diff --git a/kernel/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/kernel/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index a816b30..a5d6faf 100644
--- a/kernel/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/kernel/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -1064,6 +1064,9 @@
 
 	devm_free_irq(pdata->dev, pdata->dev_irq, pdata);
 
+	tasklet_kill(&pdata->tasklet_dev);
+	tasklet_kill(&pdata->tasklet_ecc);
+
 	if (pdata->vdata->ecc_support && (pdata->dev_irq != pdata->ecc_irq))
 		devm_free_irq(pdata->dev, pdata->ecc_irq, pdata);
 
diff --git a/kernel/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c b/kernel/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c
index 22d4fc5..a9ccc42 100644
--- a/kernel/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c
+++ b/kernel/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c
@@ -447,8 +447,10 @@
 	xgbe_i2c_disable(pdata);
 	xgbe_i2c_clear_all_interrupts(pdata);
 
-	if (pdata->dev_irq != pdata->i2c_irq)
+	if (pdata->dev_irq != pdata->i2c_irq) {
 		devm_free_irq(pdata->dev, pdata->i2c_irq, pdata);
+		tasklet_kill(&pdata->tasklet_i2c);
+	}
 }
 
 static int xgbe_i2c_start(struct xgbe_prv_data *pdata)
diff --git a/kernel/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/kernel/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
index 4e97b48..ca73723 100644
--- a/kernel/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+++ b/kernel/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
@@ -496,6 +496,7 @@
 	reg |= XGBE_KR_TRAINING_ENABLE;
 	reg |= XGBE_KR_TRAINING_START;
 	XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
+	pdata->kr_start_time = jiffies;
 
 	netif_dbg(pdata, link, pdata->netdev,
 		  "KR training initiated\n");
@@ -631,6 +632,8 @@
 	xgbe_an_disable(pdata);
 
 	xgbe_switch_mode(pdata);
+
+	pdata->an_result = XGBE_AN_READY;
 
 	xgbe_an_restart(pdata);
 
@@ -1275,9 +1278,30 @@
 static void xgbe_check_link_timeout(struct xgbe_prv_data *pdata)
 {
 	unsigned long link_timeout;
+	unsigned long kr_time;
+	int wait;
 
 	link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * HZ);
 	if (time_after(jiffies, link_timeout)) {
+		if ((xgbe_cur_mode(pdata) == XGBE_MODE_KR) &&
+		    pdata->phy.autoneg == AUTONEG_ENABLE) {
+			/* AN restart should not happen while KR training is in progress.
+			 * The while loop ensures no AN restart during KR training,
+			 * waits up to 500ms and AN restart is triggered only if KR
+			 * training is failed.
+			 */
+			wait = XGBE_KR_TRAINING_WAIT_ITER;
+			while (wait--) {
+				kr_time = pdata->kr_start_time +
+					  msecs_to_jiffies(XGBE_AN_MS_TIMEOUT);
+				if (time_after(jiffies, kr_time))
+					break;
+				/* AN restart is not required, if AN result is COMPLETE */
+				if (pdata->an_result == XGBE_AN_COMPLETE)
+					return;
+				usleep_range(10000, 11000);
+			}
+		}
 		netif_dbg(pdata, link, pdata->netdev, "AN link timeout\n");
 		xgbe_phy_config_aneg(pdata);
 	}
@@ -1288,7 +1312,7 @@
 	return pdata->phy_if.phy_impl.an_outcome(pdata);
 }
 
-static void xgbe_phy_status_result(struct xgbe_prv_data *pdata)
+static bool xgbe_phy_status_result(struct xgbe_prv_data *pdata)
 {
 	struct ethtool_link_ksettings *lks = &pdata->phy.lks;
 	enum xgbe_mode mode;
@@ -1323,8 +1347,13 @@
 
 	pdata->phy.duplex = DUPLEX_FULL;
 
-	if (xgbe_set_mode(pdata, mode) && pdata->an_again)
+	if (!xgbe_set_mode(pdata, mode))
+		return false;
+
+	if (pdata->an_again)
 		xgbe_phy_reconfig_aneg(pdata);
+
+	return true;
 }
 
 static void xgbe_phy_status(struct xgbe_prv_data *pdata)
@@ -1354,7 +1383,8 @@
 			return;
 		}
 
-		xgbe_phy_status_result(pdata);
+		if (xgbe_phy_status_result(pdata))
+			return;
 
 		if (test_bit(XGBE_LINK_INIT, &pdata->dev_state))
 			clear_bit(XGBE_LINK_INIT, &pdata->dev_state);
@@ -1390,8 +1420,10 @@
 	/* Disable auto-negotiation */
 	xgbe_an_disable_all(pdata);
 
-	if (pdata->dev_irq != pdata->an_irq)
+	if (pdata->dev_irq != pdata->an_irq) {
 		devm_free_irq(pdata->dev, pdata->an_irq, pdata);
+		tasklet_kill(&pdata->tasklet_an);
+	}
 
 	pdata->phy_if.phy_impl.stop(pdata);
 
diff --git a/kernel/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/kernel/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
index a7166cd..97e32c0 100644
--- a/kernel/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+++ b/kernel/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
@@ -189,6 +189,7 @@
 	XGBE_SFP_CABLE_UNKNOWN = 0,
 	XGBE_SFP_CABLE_ACTIVE,
 	XGBE_SFP_CABLE_PASSIVE,
+	XGBE_SFP_CABLE_FIBER,
 };
 
 enum xgbe_sfp_base {
@@ -236,10 +237,7 @@
 
 #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
 
@@ -826,29 +824,22 @@
 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)
@@ -1149,16 +1140,18 @@
 	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)
diff --git a/kernel/drivers/net/ethernet/amd/xgbe/xgbe.h b/kernel/drivers/net/ethernet/amd/xgbe/xgbe.h
index 3305979..e0b8f3c 100644
--- a/kernel/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/kernel/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -289,6 +289,7 @@
 /* Auto-negotiation */
 #define XGBE_AN_MS_TIMEOUT		500
 #define XGBE_LINK_TIMEOUT		5
+#define XGBE_KR_TRAINING_WAIT_ITER	50
 
 #define XGBE_SGMII_AN_LINK_STATUS	BIT(1)
 #define XGBE_SGMII_AN_LINK_SPEED	(BIT(2) | BIT(3))
@@ -1253,6 +1254,7 @@
 	unsigned int parallel_detect;
 	unsigned int fec_ability;
 	unsigned long an_start;
+	unsigned long kr_start_time;
 	enum xgbe_an_mode an_mode;
 
 	/* I2C support */
diff --git a/kernel/drivers/net/ethernet/apple/bmac.c b/kernel/drivers/net/ethernet/apple/bmac.c
index 1e4e402..dd6c44f 100644
--- a/kernel/drivers/net/ethernet/apple/bmac.c
+++ b/kernel/drivers/net/ethernet/apple/bmac.c
@@ -1511,7 +1511,7 @@
 	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;
diff --git a/kernel/drivers/net/ethernet/apple/mace.c b/kernel/drivers/net/ethernet/apple/mace.c
index 9e5006e..6f6530c 100644
--- a/kernel/drivers/net/ethernet/apple/mace.c
+++ b/kernel/drivers/net/ethernet/apple/mace.c
@@ -841,7 +841,7 @@
     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;
diff --git a/kernel/drivers/net/ethernet/atheros/alx/ethtool.c b/kernel/drivers/net/ethernet/atheros/alx/ethtool.c
index 2f4eabf..51e5aa2 100644
--- a/kernel/drivers/net/ethernet/atheros/alx/ethtool.c
+++ b/kernel/drivers/net/ethernet/atheros/alx/ethtool.c
@@ -281,9 +281,8 @@
 	spin_lock(&alx->stats_lock);
 
 	alx_update_hw_stats(hw);
-	BUILD_BUG_ON(sizeof(hw->stats) - offsetof(struct alx_hw_stats, rx_ok) <
-		     ALX_NUM_STATS * sizeof(u64));
-	memcpy(data, &hw->stats.rx_ok, ALX_NUM_STATS * sizeof(u64));
+	BUILD_BUG_ON(sizeof(hw->stats) != ALX_NUM_STATS * sizeof(u64));
+	memcpy(data, &hw->stats, sizeof(hw->stats));
 
 	spin_unlock(&alx->stats_lock);
 }
diff --git a/kernel/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/kernel/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 3f65f2b..2c5af0d 100644
--- a/kernel/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/kernel/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -1987,8 +1987,11 @@
 			real_len = (((unsigned char *)ip_hdr(skb) - skb->data)
 					+ ntohs(ip_hdr(skb)->tot_len));
 
-			if (real_len < skb->len)
-				pskb_trim(skb, real_len);
+			if (real_len < skb->len) {
+				err = pskb_trim(skb, real_len);
+				if (err)
+					return err;
+			}
 
 			hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
 			if (unlikely(skb->len == hdr_len)) {
diff --git a/kernel/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/kernel/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
index ff9f96d..696ce3c 100644
--- a/kernel/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+++ b/kernel/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
@@ -1642,8 +1642,11 @@
 			real_len = (((unsigned char *)ip_hdr(skb) - skb->data)
 					+ ntohs(ip_hdr(skb)->tot_len));
 
-			if (real_len < skb->len)
-				pskb_trim(skb, real_len);
+			if (real_len < skb->len) {
+				err = pskb_trim(skb, real_len);
+				if (err)
+					return err;
+			}
 
 			hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
 			if (unlikely(skb->len == hdr_len)) {
diff --git a/kernel/drivers/net/ethernet/broadcom/bgmac-bcma.c b/kernel/drivers/net/ethernet/broadcom/bgmac-bcma.c
index 2674619..022aebb 100644
--- a/kernel/drivers/net/ethernet/broadcom/bgmac-bcma.c
+++ b/kernel/drivers/net/ethernet/broadcom/bgmac-bcma.c
@@ -228,12 +228,12 @@
 		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
 		bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1;
 		bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY;
-		if (ci->pkg == BCMA_PKG_ID_BCM47188 ||
-		    ci->pkg == BCMA_PKG_ID_BCM47186) {
+		if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == BCMA_PKG_ID_BCM47186) ||
+		    (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg == BCMA_PKG_ID_BCM47188)) {
 			bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII;
 			bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED;
 		}
-		if (ci->pkg == BCMA_PKG_ID_BCM5358)
+		if (ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == BCMA_PKG_ID_BCM5358)
 			bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_EPHYRMII;
 		break;
 	case BCMA_CHIP_ID_BCM53573:
diff --git a/kernel/drivers/net/ethernet/broadcom/bgmac.c b/kernel/drivers/net/ethernet/broadcom/bgmac.c
index 9960127..a4f6143 100644
--- a/kernel/drivers/net/ethernet/broadcom/bgmac.c
+++ b/kernel/drivers/net/ethernet/broadcom/bgmac.c
@@ -890,13 +890,13 @@
 
 		if (iost & BGMAC_BCMA_IOST_ATTACHED) {
 			flags = BGMAC_BCMA_IOCTL_SW_CLKEN;
-			if (!bgmac->has_robosw)
+			if (bgmac->in_init || !bgmac->has_robosw)
 				flags |= BGMAC_BCMA_IOCTL_SW_RESET;
 		}
 		bgmac_clk_enable(bgmac, flags);
 	}
 
-	if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw)
+	if (iost & BGMAC_BCMA_IOST_ATTACHED && (bgmac->in_init || !bgmac->has_robosw))
 		bgmac_idm_write(bgmac, BCMA_IOCTL,
 				bgmac_idm_read(bgmac, BCMA_IOCTL) &
 				~BGMAC_BCMA_IOCTL_SW_RESET);
@@ -1448,7 +1448,7 @@
 	int err;
 
 	phy_dev = fixed_phy_register(PHY_POLL, &fphy_status, NULL);
-	if (!phy_dev || IS_ERR(phy_dev)) {
+	if (IS_ERR(phy_dev)) {
 		dev_err(bgmac->dev, "Failed to register fixed PHY device\n");
 		return -ENODEV;
 	}
@@ -1490,7 +1490,7 @@
 	struct net_device *net_dev = bgmac->net_dev;
 	int err;
 
-	bgmac_chip_intrs_off(bgmac);
+	bgmac->in_init = true;
 
 	net_dev->irq = bgmac->irq;
 	SET_NETDEV_DEV(net_dev, bgmac->dev);
@@ -1508,6 +1508,8 @@
 	 * Broadcom does it in arch PCI code when enabling fake PCI device.
 	 */
 	bgmac_clk_enable(bgmac, 0);
+
+	bgmac_chip_intrs_off(bgmac);
 
 	/* This seems to be fixing IRQ by assigning OOB #6 to the core */
 	if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK)) {
@@ -1542,6 +1544,8 @@
 	/* Omit FCS from max MTU size */
 	net_dev->max_mtu = BGMAC_RX_MAX_FRAME_SIZE - ETH_FCS_LEN;
 
+	bgmac->in_init = false;
+
 	err = register_netdev(bgmac->net_dev);
 	if (err) {
 		dev_err(bgmac->dev, "Cannot register net device\n");
diff --git a/kernel/drivers/net/ethernet/broadcom/bgmac.h b/kernel/drivers/net/ethernet/broadcom/bgmac.h
index 351c598..d1200b2 100644
--- a/kernel/drivers/net/ethernet/broadcom/bgmac.h
+++ b/kernel/drivers/net/ethernet/broadcom/bgmac.h
@@ -512,6 +512,8 @@
 	int irq;
 	u32 int_mask;
 
+	bool in_init;
+
 	/* Current MAC state */
 	int mac_speed;
 	int mac_duplex;
diff --git a/kernel/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/kernel/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index afb6d3e..c8cbf3e 100644
--- a/kernel/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/kernel/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -14372,11 +14372,16 @@
 	bp->fw_seq = SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) &
 							DRV_MSG_SEQ_NUMBER_MASK;
 
-	if (netif_running(dev))
-		bnx2x_nic_load(bp, LOAD_NORMAL);
+	if (netif_running(dev)) {
+		if (bnx2x_nic_load(bp, LOAD_NORMAL)) {
+			netdev_err(bp->dev, "Error during driver initialization, try unloading/reloading the driver\n");
+			goto done;
+		}
+	}
 
 	netif_device_attach(dev);
 
+done:
 	rtnl_unlock();
 }
 
diff --git a/kernel/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/kernel/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 92f54e3..c67a108 100644
--- a/kernel/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/kernel/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -219,12 +219,12 @@
 	{ PCI_VDEVICE(BROADCOM, 0x1750), .driver_data = BCM57508 },
 	{ PCI_VDEVICE(BROADCOM, 0x1751), .driver_data = BCM57504 },
 	{ PCI_VDEVICE(BROADCOM, 0x1752), .driver_data = BCM57502 },
-	{ PCI_VDEVICE(BROADCOM, 0x1800), .driver_data = BCM57508_NPAR },
+	{ PCI_VDEVICE(BROADCOM, 0x1800), .driver_data = BCM57502_NPAR },
 	{ PCI_VDEVICE(BROADCOM, 0x1801), .driver_data = BCM57504_NPAR },
-	{ PCI_VDEVICE(BROADCOM, 0x1802), .driver_data = BCM57502_NPAR },
-	{ PCI_VDEVICE(BROADCOM, 0x1803), .driver_data = BCM57508_NPAR },
+	{ PCI_VDEVICE(BROADCOM, 0x1802), .driver_data = BCM57508_NPAR },
+	{ PCI_VDEVICE(BROADCOM, 0x1803), .driver_data = BCM57502_NPAR },
 	{ PCI_VDEVICE(BROADCOM, 0x1804), .driver_data = BCM57504_NPAR },
-	{ PCI_VDEVICE(BROADCOM, 0x1805), .driver_data = BCM57502_NPAR },
+	{ PCI_VDEVICE(BROADCOM, 0x1805), .driver_data = BCM57508_NPAR },
 	{ PCI_VDEVICE(BROADCOM, 0xd802), .driver_data = BCM58802 },
 	{ PCI_VDEVICE(BROADCOM, 0xd804), .driver_data = BCM58804 },
 #ifdef CONFIG_BNXT_SRIOV
@@ -2404,6 +2404,7 @@
 	struct rx_cmp_ext *rxcmp1;
 	u32 cp_cons, tmp_raw_cons;
 	u32 raw_cons = cpr->cp_raw_cons;
+	bool flush_xdp = false;
 	u32 rx_pkts = 0;
 	u8 event = 0;
 
@@ -2438,6 +2439,8 @@
 				rx_pkts++;
 			else if (rc == -EBUSY)	/* partial completion */
 				break;
+			if (event & BNXT_REDIRECT_EVENT)
+				flush_xdp = true;
 		} else if (unlikely(TX_CMP_TYPE(txcmp) ==
 				    CMPL_BASE_TYPE_HWRM_DONE)) {
 			bnxt_hwrm_handler(bp, txcmp);
@@ -2457,6 +2460,8 @@
 
 	if (event & BNXT_AGG_EVENT)
 		bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod);
+	if (flush_xdp)
+		xdp_do_flush();
 
 	if (!bnxt_has_work(bp, cpr) && rx_pkts < budget) {
 		napi_complete_done(napi, rx_pkts);
@@ -2854,7 +2859,7 @@
 
 static void bnxt_free_tpa_info(struct bnxt *bp)
 {
-	int i;
+	int i, j;
 
 	for (i = 0; i < bp->rx_nr_rings; i++) {
 		struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
@@ -2862,8 +2867,10 @@
 		kfree(rxr->rx_tpa_idx_map);
 		rxr->rx_tpa_idx_map = NULL;
 		if (rxr->rx_tpa) {
-			kfree(rxr->rx_tpa[0].agg_arr);
-			rxr->rx_tpa[0].agg_arr = NULL;
+			for (j = 0; j < bp->max_tpa; j++) {
+				kfree(rxr->rx_tpa[j].agg_arr);
+				rxr->rx_tpa[j].agg_arr = NULL;
+			}
 		}
 		kfree(rxr->rx_tpa);
 		rxr->rx_tpa = NULL;
@@ -2872,14 +2879,13 @@
 
 static int bnxt_alloc_tpa_info(struct bnxt *bp)
 {
-	int i, j, total_aggs = 0;
+	int i, j;
 
 	bp->max_tpa = MAX_TPA;
 	if (bp->flags & BNXT_FLAG_CHIP_P5) {
 		if (!bp->max_tpa_v2)
 			return 0;
 		bp->max_tpa = max_t(u16, bp->max_tpa_v2, MAX_TPA_P5);
-		total_aggs = bp->max_tpa * MAX_SKB_FRAGS;
 	}
 
 	for (i = 0; i < bp->rx_nr_rings; i++) {
@@ -2893,12 +2899,12 @@
 
 		if (!(bp->flags & BNXT_FLAG_CHIP_P5))
 			continue;
-		agg = kcalloc(total_aggs, sizeof(*agg), GFP_KERNEL);
-		rxr->rx_tpa[0].agg_arr = agg;
-		if (!agg)
-			return -ENOMEM;
-		for (j = 1; j < bp->max_tpa; j++)
-			rxr->rx_tpa[j].agg_arr = agg + j * MAX_SKB_FRAGS;
+		for (j = 0; j < bp->max_tpa; j++) {
+			agg = kcalloc(MAX_SKB_FRAGS, sizeof(*agg), GFP_KERNEL);
+			if (!agg)
+				return -ENOMEM;
+			rxr->rx_tpa[j].agg_arr = agg;
+		}
 		rxr->rx_tpa_idx_map = kzalloc(sizeof(*rxr->rx_tpa_idx_map),
 					      GFP_KERNEL);
 		if (!rxr->rx_tpa_idx_map)
@@ -8336,6 +8342,9 @@
 		goto err_out;
 	}
 
+	if (BNXT_VF(bp))
+		bnxt_hwrm_func_qcfg(bp);
+
 	rc = bnxt_setup_vnic(bp, 0);
 	if (rc)
 		goto err_out;
@@ -8761,10 +8770,14 @@
 		netdev_err(bp->dev, "ring reservation/IRQ init failure rc: %d\n", rc);
 		return rc;
 	}
-	if (tcs && (bp->tx_nr_rings_per_tc * tcs != bp->tx_nr_rings)) {
+	if (tcs && (bp->tx_nr_rings_per_tc * tcs !=
+		    bp->tx_nr_rings - bp->tx_nr_rings_xdp)) {
 		netdev_err(bp->dev, "tx ring reservation failure\n");
 		netdev_reset_tc(bp->dev);
-		bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
+		if (bp->tx_nr_rings_xdp)
+			bp->tx_nr_rings_per_tc = bp->tx_nr_rings_xdp;
+		else
+			bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
 		return -ENOMEM;
 	}
 	return 0;
@@ -12096,26 +12109,37 @@
 
 #endif /* CONFIG_RFS_ACCEL */
 
-static int bnxt_udp_tunnel_sync(struct net_device *netdev, unsigned int table)
+static int bnxt_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
+				    unsigned int entry, struct udp_tunnel_info *ti)
 {
 	struct bnxt *bp = netdev_priv(netdev);
-	struct udp_tunnel_info ti;
 	unsigned int cmd;
 
-	udp_tunnel_nic_get_port(netdev, table, 0, &ti);
-	if (ti.type == UDP_TUNNEL_TYPE_VXLAN)
+	if (ti->type == UDP_TUNNEL_TYPE_VXLAN)
 		cmd = TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN;
 	else
 		cmd = TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE;
 
-	if (ti.port)
-		return bnxt_hwrm_tunnel_dst_port_alloc(bp, ti.port, cmd);
+	return bnxt_hwrm_tunnel_dst_port_alloc(bp, ti->port, cmd);
+}
+
+static int bnxt_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table,
+				      unsigned int entry, struct udp_tunnel_info *ti)
+{
+	struct bnxt *bp = netdev_priv(netdev);
+	unsigned int cmd;
+
+	if (ti->type == UDP_TUNNEL_TYPE_VXLAN)
+		cmd = TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN;
+	else
+		cmd = TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE;
 
 	return bnxt_hwrm_tunnel_dst_port_free(bp, cmd);
 }
 
 static const struct udp_tunnel_nic_info bnxt_udp_tunnels = {
-	.sync_table	= bnxt_udp_tunnel_sync,
+	.set_port	= bnxt_udp_tunnel_set_port,
+	.unset_port	= bnxt_udp_tunnel_unset_port,
 	.flags		= UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
 			  UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
 	.tables		= {
diff --git a/kernel/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/kernel/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 34affd1..b7b07be 100644
--- a/kernel/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/kernel/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -1198,6 +1198,7 @@
 #define BNXT_LINK_SPEED_40GB	PORT_PHY_QCFG_RESP_LINK_SPEED_40GB
 #define BNXT_LINK_SPEED_50GB	PORT_PHY_QCFG_RESP_LINK_SPEED_50GB
 #define BNXT_LINK_SPEED_100GB	PORT_PHY_QCFG_RESP_LINK_SPEED_100GB
+#define BNXT_LINK_SPEED_200GB	PORT_PHY_QCFG_RESP_LINK_SPEED_200GB
 	u16			support_speeds;
 	u16			support_pam4_speeds;
 	u16			auto_link_speeds;	/* fw adv setting */
diff --git a/kernel/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/kernel/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index 81b63d1..2984234 100644
--- a/kernel/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/kernel/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -1653,6 +1653,8 @@
 		return SPEED_50000;
 	case BNXT_LINK_SPEED_100GB:
 		return SPEED_100000;
+	case BNXT_LINK_SPEED_200GB:
+		return SPEED_200000;
 	default:
 		return SPEED_UNKNOWN;
 	}
@@ -3438,7 +3440,7 @@
 		}
 	}
 
-	if (req & BNXT_FW_RESET_AP) {
+	if (!BNXT_CHIP_P4_PLUS(bp) && (req & BNXT_FW_RESET_AP)) {
 		/* This feature is not supported in older firmware versions */
 		if (bp->hwrm_spec_code >= 0x10803) {
 			if (!bnxt_firmware_reset_ap(dev)) {
diff --git a/kernel/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/kernel/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index e0a6a2e..1454884 100644
--- a/kernel/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/kernel/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -2263,6 +2263,14 @@
 			  __func__, p_index, ring->c_index,
 			  ring->read_ptr, dma_length_status);
 
+		if (unlikely(len > RX_BUF_LENGTH)) {
+			netif_err(priv, rx_status, dev, "oversized packet\n");
+			dev->stats.rx_length_errors++;
+			dev->stats.rx_errors++;
+			dev_kfree_skb_any(skb);
+			goto next;
+		}
+
 		if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) {
 			netif_err(priv, rx_status, dev,
 				  "dropping fragmented packet!\n");
@@ -3389,7 +3397,7 @@
 	return ret;
 }
 
-static void bcmgenet_netif_stop(struct net_device *dev)
+static void bcmgenet_netif_stop(struct net_device *dev, bool stop_phy)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
 
@@ -3404,7 +3412,8 @@
 	/* Disable MAC transmit. TX DMA disabled must be done before this */
 	umac_enable_set(priv, CMD_TX_EN, false);
 
-	phy_stop(dev->phydev);
+	if (stop_phy)
+		phy_stop(dev->phydev);
 	bcmgenet_disable_rx_napi(priv);
 	bcmgenet_intr_disable(priv);
 
@@ -3430,7 +3439,7 @@
 
 	netif_dbg(priv, ifdown, dev, "bcmgenet_close\n");
 
-	bcmgenet_netif_stop(dev);
+	bcmgenet_netif_stop(dev, false);
 
 	/* Really kill the PHY state machine and disconnect from it */
 	phy_disconnect(dev->phydev);
@@ -4232,7 +4241,7 @@
 
 	netif_device_detach(dev);
 
-	bcmgenet_netif_stop(dev);
+	bcmgenet_netif_stop(dev, true);
 
 	if (!device_may_wakeup(d))
 		phy_suspend(dev->phydev);
diff --git a/kernel/drivers/net/ethernet/broadcom/genet/bcmmii.c b/kernel/drivers/net/ethernet/broadcom/genet/bcmmii.c
index f9e9130..2b0538f 100644
--- a/kernel/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ b/kernel/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -165,15 +165,6 @@
 
 static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
 {
-	u32 reg;
-
-	if (!GENET_IS_V5(priv)) {
-		/* Speed settings are set in bcmgenet_mii_setup() */
-		reg = bcmgenet_sys_readl(priv, SYS_PORT_CTRL);
-		reg |= LED_ACT_SOURCE_MAC;
-		bcmgenet_sys_writel(priv, reg, SYS_PORT_CTRL);
-	}
-
 	if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
 		fixed_phy_set_link_update(priv->dev->phydev,
 					  bcmgenet_fixed_phy_link_update);
@@ -206,6 +197,8 @@
 
 		if (!phy_name) {
 			phy_name = "MoCA";
+			if (!GENET_IS_V5(priv))
+				port_ctrl |= LED_ACT_SOURCE_MAC;
 			bcmgenet_moca_phy_setup(priv);
 		}
 		break;
@@ -575,7 +568,7 @@
 		};
 
 		phydev = fixed_phy_register(PHY_POLL, &fphy_status, NULL);
-		if (!phydev || IS_ERR(phydev)) {
+		if (IS_ERR(phydev)) {
 			dev_err(kdev, "failed to register fixed PHY device\n");
 			return -ENODEV;
 		}
@@ -631,5 +624,7 @@
 	if (of_phy_is_fixed_link(dn))
 		of_phy_deregister_fixed_link(dn);
 	of_node_put(priv->phy_dn);
+	clk_prepare_enable(priv->clk);
 	platform_device_unregister(priv->mii_pdev);
+	clk_disable_unprepare(priv->clk);
 }
diff --git a/kernel/drivers/net/ethernet/broadcom/tg3.c b/kernel/drivers/net/ethernet/broadcom/tg3.c
index be96116..d14f37b 100644
--- a/kernel/drivers/net/ethernet/broadcom/tg3.c
+++ b/kernel/drivers/net/ethernet/broadcom/tg3.c
@@ -224,6 +224,7 @@
 MODULE_DESCRIPTION("Broadcom Tigon3 ethernet driver");
 MODULE_LICENSE("GPL");
 MODULE_FIRMWARE(FIRMWARE_TG3);
+MODULE_FIRMWARE(FIRMWARE_TG357766);
 MODULE_FIRMWARE(FIRMWARE_TG3TSO);
 MODULE_FIRMWARE(FIRMWARE_TG3TSO5);
 
@@ -11185,7 +11186,7 @@
 	rtnl_lock();
 	tg3_full_lock(tp, 0);
 
-	if (!netif_running(tp->dev)) {
+	if (tp->pcierr_recovery || !netif_running(tp->dev)) {
 		tg3_flag_clear(tp, RESET_TASK_PENDING);
 		tg3_full_unlock(tp);
 		rtnl_unlock();
@@ -18179,6 +18180,9 @@
 
 	netdev_info(netdev, "PCI I/O error detected\n");
 
+	/* Want to make sure that the reset task doesn't run */
+	tg3_reset_task_cancel(tp);
+
 	rtnl_lock();
 
 	/* Could be second call or maybe we don't have netdev yet */
@@ -18194,9 +18198,6 @@
 	tg3_netif_stop(tp);
 
 	tg3_timer_stop(tp);
-
-	/* Want to make sure that the reset task doesn't run */
-	tg3_reset_task_cancel(tp);
 
 	netif_device_detach(netdev);
 
diff --git a/kernel/drivers/net/ethernet/cadence/macb_main.c b/kernel/drivers/net/ethernet/cadence/macb_main.c
index 792c814..70d57ef 100644
--- a/kernel/drivers/net/ethernet/cadence/macb_main.c
+++ b/kernel/drivers/net/ethernet/cadence/macb_main.c
@@ -884,6 +884,10 @@
 	}
 #endif
 	addr |= MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, desc->addr));
+#ifdef CONFIG_MACB_USE_HWSTAMP
+	if (bp->hw_dma_cap & HW_DMA_CAP_PTP)
+		addr &= ~GEM_BIT(DMA_RXVALID);
+#endif
 	return addr;
 }
 
@@ -1963,7 +1967,6 @@
 	bool cloned = skb_cloned(*skb) || skb_header_cloned(*skb) ||
 		      skb_is_nonlinear(*skb);
 	int padlen = ETH_ZLEN - (*skb)->len;
-	int headroom = skb_headroom(*skb);
 	int tailroom = skb_tailroom(*skb);
 	struct sk_buff *nskb;
 	u32 fcs;
@@ -1977,9 +1980,6 @@
 		/* FCS could be appeded to tailroom. */
 		if (tailroom >= ETH_FCS_LEN)
 			goto add_fcs;
-		/* FCS could be appeded by moving data to headroom. */
-		else if (!cloned && headroom + tailroom >= ETH_FCS_LEN)
-			padlen = 0;
 		/* No room for FCS, need to reallocate skb. */
 		else
 			padlen = ETH_FCS_LEN;
@@ -1988,10 +1988,7 @@
 		padlen += ETH_FCS_LEN;
 	}
 
-	if (!cloned && headroom + tailroom >= padlen) {
-		(*skb)->data = memmove((*skb)->head, (*skb)->data, (*skb)->len);
-		skb_set_tail_pointer(*skb, (*skb)->len);
-	} else {
+	if (cloned || tailroom < padlen) {
 		nskb = skb_copy_expand(*skb, 0, padlen, GFP_ATOMIC);
 		if (!nskb)
 			return -ENOMEM;
diff --git a/kernel/drivers/net/ethernet/dnet.c b/kernel/drivers/net/ethernet/dnet.c
index 48c6eb1..05a0cc5 100644
--- a/kernel/drivers/net/ethernet/dnet.c
+++ b/kernel/drivers/net/ethernet/dnet.c
@@ -550,10 +550,10 @@
 
 	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;
 }
diff --git a/kernel/drivers/net/ethernet/emulex/benet/be_main.c b/kernel/drivers/net/ethernet/emulex/benet/be_main.c
index 89697cb..52b399a 100644
--- a/kernel/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/kernel/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1136,10 +1136,11 @@
 	eth_hdr_len = ntohs(skb->protocol) == ETH_P_8021Q ?
 						VLAN_ETH_HLEN : ETH_HLEN;
 	if (skb->len <= 60 &&
-	    (lancer_chip(adapter) || skb_vlan_tag_present(skb)) &&
-	    is_ipv4_pkt(skb)) {
+	    (lancer_chip(adapter) || BE3_chip(adapter) ||
+	     skb_vlan_tag_present(skb)) && is_ipv4_pkt(skb)) {
 		ip = (struct iphdr *)ip_hdr(skb);
-		pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len));
+		if (unlikely(pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len))))
+			goto tx_drop;
 	}
 
 	/* If vlan tag is already inlined in the packet, skip HW VLAN
diff --git a/kernel/drivers/net/ethernet/freescale/enetc/enetc.c b/kernel/drivers/net/ethernet/freescale/enetc/enetc.c
index 975762c..5f9603d 100644
--- a/kernel/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/kernel/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 @@
 	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/kernel/drivers/net/ethernet/freescale/enetc/enetc_ptp.c b/kernel/drivers/net/ethernet/freescale/enetc/enetc_ptp.c
index bc59489..8c36615 100644
--- a/kernel/drivers/net/ethernet/freescale/enetc/enetc_ptp.c
+++ b/kernel/drivers/net/ethernet/freescale/enetc/enetc_ptp.c
@@ -8,7 +8,7 @@
 #include "enetc.h"
 
 int enetc_phc_index = -1;
-EXPORT_SYMBOL(enetc_phc_index);
+EXPORT_SYMBOL_GPL(enetc_phc_index);
 
 static struct ptp_clock_info enetc_ptp_caps = {
 	.owner		= THIS_MODULE,
diff --git a/kernel/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/kernel/drivers/net/ethernet/freescale/enetc/enetc_qos.c
index 5841721..d7215bd 100644
--- a/kernel/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+++ b/kernel/drivers/net/ethernet/freescale/enetc/enetc_qos.c
@@ -196,8 +196,8 @@
 	int bw_sum = 0;
 	u8 bw;
 
-	prio_top = netdev_get_prio_tc_map(ndev, tc_nums - 1);
-	prio_next = netdev_get_prio_tc_map(ndev, tc_nums - 2);
+	prio_top = tc_nums - 1;
+	prio_next = tc_nums - 2;
 
 	/* Support highest prio and second prio tc in cbs mode */
 	if (tc != prio_top && tc != prio_next)
@@ -1266,7 +1266,7 @@
 		int index;
 
 		index = enetc_get_free_index(priv);
-		if (sfi->handle < 0) {
+		if (index < 0) {
 			NL_SET_ERR_MSG_MOD(extack, "No Stream Filter resource!");
 			err = -ENOSPC;
 			goto free_fmi;
diff --git a/kernel/drivers/net/ethernet/freescale/fec_main.c b/kernel/drivers/net/ethernet/freescale/fec_main.c
index 686bb87..e18b3b7 100644
--- a/kernel/drivers/net/ethernet/freescale/fec_main.c
+++ b/kernel/drivers/net/ethernet/freescale/fec_main.c
@@ -3850,9 +3850,11 @@
 	struct device_node *np = pdev->dev.of_node;
 	int ret;
 
-	ret = pm_runtime_resume_and_get(&pdev->dev);
+	ret = pm_runtime_get_sync(&pdev->dev);
 	if (ret < 0)
-		return ret;
+		dev_err(&pdev->dev,
+			"Failed to resume device in remove callback (%pe)\n",
+			ERR_PTR(ret));
 
 	cancel_work_sync(&fep->tx_timeout_work);
 	fec_ptp_stop(pdev);
@@ -3865,8 +3867,13 @@
 		of_phy_deregister_fixed_link(np);
 	of_node_put(fep->phy_node);
 
-	clk_disable_unprepare(fep->clk_ahb);
-	clk_disable_unprepare(fep->clk_ipg);
+	/* After pm_runtime_get_sync() failed, the clks are still off, so skip
+	 * disabling them again.
+	 */
+	if (ret >= 0) {
+		clk_disable_unprepare(fep->clk_ahb);
+		clk_disable_unprepare(fep->clk_ipg);
+	}
 	pm_runtime_put_noidle(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
diff --git a/kernel/drivers/net/ethernet/google/gve/gve_ethtool.c b/kernel/drivers/net/ethernet/google/gve/gve_ethtool.c
index c53a043..cbfd007 100644
--- a/kernel/drivers/net/ethernet/google/gve/gve_ethtool.c
+++ b/kernel/drivers/net/ethernet/google/gve/gve_ethtool.c
@@ -510,9 +510,15 @@
 				  struct ethtool_link_ksettings *cmd)
 {
 	struct gve_priv *priv = netdev_priv(netdev);
-	int err = gve_adminq_report_link_speed(priv);
+	int err = 0;
+
+	if (priv->link_speed == 0)
+		err = gve_adminq_report_link_speed(priv);
 
 	cmd->base.speed = priv->link_speed;
+
+	cmd->base.duplex = DUPLEX_FULL;
+
 	return err;
 }
 
diff --git a/kernel/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/kernel/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index cd0d7a5..d35f4b2 100644
--- a/kernel/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/kernel/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -704,7 +704,9 @@
 		hns3_get_ksettings(h, cmd);
 		break;
 	case HNAE3_MEDIA_TYPE_FIBER:
-		if (module_type == HNAE3_MODULE_TYPE_CR)
+		if (module_type == HNAE3_MODULE_TYPE_UNKNOWN)
+			cmd->base.port = PORT_OTHER;
+		else if (module_type == HNAE3_MODULE_TYPE_CR)
 			cmd->base.port = PORT_DA;
 		else
 			cmd->base.port = PORT_FIBRE;
diff --git a/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c b/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
index 5bab885..d60b8df 100644
--- a/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
+++ b/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
@@ -53,7 +53,10 @@
 
 	for (i = 0; i < HNAE3_MAX_TC; i++) {
 		ets->prio_tc[i] = hdev->tm_info.prio_tc[i];
-		ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0].tc_dwrr[i];
+		if (i < hdev->tm_info.num_tc)
+			ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0].tc_dwrr[i];
+		else
+			ets->tc_tx_bw[i] = 0;
 
 		if (hdev->tm_info.tc_info[i].tc_sch_mode ==
 		    HCLGE_SCH_MODE_SP)
@@ -105,26 +108,31 @@
 	return 0;
 }
 
-static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets,
-			      u8 *tc, bool *changed)
+static u8 hclge_ets_tc_changed(struct hclge_dev *hdev, struct ieee_ets *ets,
+			       bool *changed)
 {
-	bool has_ets_tc = false;
-	u32 total_ets_bw = 0;
-	u8 max_tc = 0;
-	int ret;
+	u8 max_tc_id = 0;
 	u8 i;
 
 	for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) {
 		if (ets->prio_tc[i] != hdev->tm_info.prio_tc[i])
 			*changed = true;
 
-		if (ets->prio_tc[i] > max_tc)
-			max_tc = ets->prio_tc[i];
+		if (ets->prio_tc[i] > max_tc_id)
+			max_tc_id = ets->prio_tc[i];
 	}
 
-	ret = hclge_dcb_common_validate(hdev, max_tc + 1, ets->prio_tc);
-	if (ret)
-		return ret;
+	/* return max tc number, max tc id need to plus 1 */
+	return max_tc_id + 1;
+}
+
+static int hclge_ets_sch_mode_validate(struct hclge_dev *hdev,
+				       struct ieee_ets *ets, bool *changed,
+				       u8 tc_num)
+{
+	bool has_ets_tc = false;
+	u32 total_ets_bw = 0;
+	u8 i;
 
 	for (i = 0; i < HNAE3_MAX_TC; i++) {
 		switch (ets->tc_tsa[i]) {
@@ -134,6 +142,13 @@
 				*changed = true;
 			break;
 		case IEEE_8021QAZ_TSA_ETS:
+			if (i >= tc_num) {
+				dev_err(&hdev->pdev->dev,
+					"tc%u is disabled, cannot set ets bw\n",
+					i);
+				return -EINVAL;
+			}
+
 			/* The hardware will switch to sp mode if bandwidth is
 			 * 0, so limit ets bandwidth must be greater than 0.
 			 */
@@ -158,7 +173,26 @@
 	if (has_ets_tc && total_ets_bw != BW_PERCENT)
 		return -EINVAL;
 
-	*tc = max_tc + 1;
+	return 0;
+}
+
+static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets,
+			      u8 *tc, bool *changed)
+{
+	u8 tc_num;
+	int ret;
+
+	tc_num = hclge_ets_tc_changed(hdev, ets, changed);
+
+	ret = hclge_dcb_common_validate(hdev, tc_num, ets->prio_tc);
+	if (ret)
+		return ret;
+
+	ret = hclge_ets_sch_mode_validate(hdev, ets, changed, tc_num);
+	if (ret)
+		return ret;
+
+	*tc = tc_num;
 	if (*tc != hdev->tm_info.num_tc)
 		*changed = true;
 
diff --git a/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 2070e26..deba485 100644
--- a/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -71,6 +71,8 @@
 static void hclge_sync_mac_table(struct hclge_dev *hdev);
 static void hclge_restore_hw_table(struct hclge_dev *hdev);
 static void hclge_sync_promisc_mode(struct hclge_dev *hdev);
+static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret,
+				      int wait_cnt);
 
 static struct hnae3_ae_algo ae_algo;
 
@@ -3123,8 +3125,13 @@
 static void hclge_clear_event_cause(struct hclge_dev *hdev, u32 event_type,
 				    u32 regclr)
 {
+#define HCLGE_IMP_RESET_DELAY		5
+
 	switch (event_type) {
 	case HCLGE_VECTOR0_EVENT_RST:
+		if (regclr == BIT(HCLGE_VECTOR0_IMPRESET_INT_B))
+			mdelay(HCLGE_IMP_RESET_DELAY);
+
 		hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, regclr);
 		break;
 	case HCLGE_VECTOR0_EVENT_MBX:
@@ -6558,6 +6565,8 @@
 
 static void hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable)
 {
+#define HCLGE_LINK_STATUS_WAIT_CNT  3
+
 	struct hclge_desc desc;
 	struct hclge_config_mac_mode_cmd *req =
 		(struct hclge_config_mac_mode_cmd *)desc.data;
@@ -6582,9 +6591,15 @@
 	req->txrx_pad_fcs_loop_en = cpu_to_le32(loop_en);
 
 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
-	if (ret)
+	if (ret) {
 		dev_err(&hdev->pdev->dev,
 			"mac enable fail, ret =%d.\n", ret);
+		return;
+	}
+
+	if (!enable)
+		hclge_mac_link_status_wait(hdev, HCLGE_LINK_STATUS_DOWN,
+					   HCLGE_LINK_STATUS_WAIT_CNT);
 }
 
 static int hclge_config_switch_param(struct hclge_dev *hdev, int vfid,
@@ -6647,10 +6662,9 @@
 	} while (++i < HCLGE_PHY_LINK_STATUS_NUM);
 }
 
-static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret)
+static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret,
+				      int wait_cnt)
 {
-#define HCLGE_MAC_LINK_STATUS_NUM  100
-
 	int link_status;
 	int i = 0;
 	int ret;
@@ -6663,13 +6677,15 @@
 			return 0;
 
 		msleep(HCLGE_LINK_STATUS_MS);
-	} while (++i < HCLGE_MAC_LINK_STATUS_NUM);
+	} while (++i < wait_cnt);
 	return -EBUSY;
 }
 
 static int hclge_mac_phy_link_status_wait(struct hclge_dev *hdev, bool en,
 					  bool is_phy)
 {
+#define HCLGE_MAC_LINK_STATUS_NUM  100
+
 	int link_ret;
 
 	link_ret = en ? HCLGE_LINK_STATUS_UP : HCLGE_LINK_STATUS_DOWN;
@@ -6677,7 +6693,8 @@
 	if (is_phy)
 		hclge_phy_link_status_wait(hdev, link_ret);
 
-	return hclge_mac_link_status_wait(hdev, link_ret);
+	return hclge_mac_link_status_wait(hdev, link_ret,
+					  HCLGE_MAC_LINK_STATUS_NUM);
 }
 
 static int hclge_set_app_loopback(struct hclge_dev *hdev, bool en)
@@ -7023,12 +7040,15 @@
 	/* If it is not PF reset or FLR, the firmware will disable the MAC,
 	 * so it only need to stop phy here.
 	 */
-	if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) &&
-	    hdev->reset_type != HNAE3_FUNC_RESET &&
-	    hdev->reset_type != HNAE3_FLR_RESET) {
-		hclge_mac_stop_phy(hdev);
-		hclge_update_link_status(hdev);
-		return;
+	if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) {
+		hclge_pfc_pause_en_cfg(hdev, HCLGE_PFC_TX_RX_DISABLE,
+				       HCLGE_PFC_DISABLE);
+		if (hdev->reset_type != HNAE3_FUNC_RESET &&
+		    hdev->reset_type != HNAE3_FLR_RESET) {
+			hclge_mac_stop_phy(hdev);
+			hclge_update_link_status(hdev);
+			return;
+		}
 	}
 
 	for (i = 0; i < handle->kinfo.num_tqps; i++)
@@ -7835,7 +7855,7 @@
 	if (mac_type == HCLGE_MAC_ADDR_UC) {
 		if (is_all_added)
 			vport->overflow_promisc_flags &= ~HNAE3_OVERFLOW_UPE;
-		else
+		else if (hclge_is_umv_space_full(vport, true))
 			vport->overflow_promisc_flags |= HNAE3_OVERFLOW_UPE;
 	} else {
 		if (is_all_added)
diff --git a/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index 9168e39..8c5c556 100644
--- a/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -169,8 +169,8 @@
 	return hclge_cmd_send(&hdev->hw, &desc, 1);
 }
 
-static int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap,
-				  u8 pfc_bitmap)
+int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap,
+			   u8 pfc_bitmap)
 {
 	struct hclge_desc desc;
 	struct hclge_pfc_en_cmd *pfc = (struct hclge_pfc_en_cmd *)desc.data;
@@ -651,6 +651,7 @@
 static void hclge_tm_pg_info_init(struct hclge_dev *hdev)
 {
 #define BW_PERCENT	100
+#define DEFAULT_BW_WEIGHT	1
 
 	u8 i;
 
@@ -672,7 +673,7 @@
 		for (k = 0; k < hdev->tm_info.num_tc; k++)
 			hdev->tm_info.pg_info[i].tc_dwrr[k] = BW_PERCENT;
 		for (; k < HNAE3_MAX_TC; k++)
-			hdev->tm_info.pg_info[i].tc_dwrr[k] = 0;
+			hdev->tm_info.pg_info[i].tc_dwrr[k] = DEFAULT_BW_WEIGHT;
 	}
 }
 
diff --git a/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h b/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
index bb2a2d8..42932c8 100644
--- a/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
+++ b/kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
@@ -117,6 +117,9 @@
 	u32 rsvd1;
 };
 
+#define HCLGE_PFC_DISABLE	0
+#define HCLGE_PFC_TX_RX_DISABLE	0
+
 struct hclge_pfc_en_cmd {
 	u8 tx_rx_en_bitmap;
 	u8 pri_en_bitmap;
@@ -164,6 +167,8 @@
 void hclge_tm_pfc_info_update(struct hclge_dev *hdev);
 int hclge_tm_dwrr_cfg(struct hclge_dev *hdev);
 int hclge_tm_init_hw(struct hclge_dev *hdev, bool init);
+int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap,
+			   u8 pfc_bitmap);
 int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx);
 int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr);
 int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats);
diff --git a/kernel/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/kernel/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
index d6580e9..7d05915 100644
--- a/kernel/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+++ b/kernel/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
@@ -1772,7 +1772,10 @@
 	 * might happen in case reset assertion was made by PF. Yes, this also
 	 * means we might end up waiting bit more even for VF reset.
 	 */
-	msleep(5000);
+	if (hdev->reset_type == HNAE3_VF_FULL_RESET)
+		msleep(5000);
+	else
+		msleep(500);
 
 	return 0;
 }
@@ -3089,7 +3092,8 @@
 	struct pci_dev *pdev = hdev->pdev;
 	int ret = 0;
 
-	if (hdev->reset_type == HNAE3_VF_FULL_RESET &&
+	if ((hdev->reset_type == HNAE3_VF_FULL_RESET ||
+	     hdev->reset_type == HNAE3_FLR_RESET) &&
 	    test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) {
 		hclgevf_misc_irq_uninit(hdev);
 		hclgevf_uninit_msi(hdev);
diff --git a/kernel/drivers/net/ethernet/ibm/ibmveth.c b/kernel/drivers/net/ethernet/ibm/ibmveth.c
index c3ec9ce..d80f155 100644
--- a/kernel/drivers/net/ethernet/ibm/ibmveth.c
+++ b/kernel/drivers/net/ethernet/ibm/ibmveth.c
@@ -196,7 +196,7 @@
 	unsigned long offset;
 
 	for (offset = 0; offset < length; offset += SMP_CACHE_BYTES)
-		asm("dcbfl %0,%1" :: "b" (addr), "r" (offset));
+		asm("dcbf %0,%1,1" :: "b" (addr), "r" (offset));
 }
 
 /* replenish the buffers for a pool.  note that we don't need to
diff --git a/kernel/drivers/net/ethernet/ibm/ibmvnic.c b/kernel/drivers/net/ethernet/ibm/ibmvnic.c
index 7fe2e47..84da6cc 100644
--- a/kernel/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/kernel/drivers/net/ethernet/ibm/ibmvnic.c
@@ -929,12 +929,22 @@
 
 static void release_login_buffer(struct ibmvnic_adapter *adapter)
 {
+	if (!adapter->login_buf)
+		return;
+
+	dma_unmap_single(&adapter->vdev->dev, adapter->login_buf_token,
+			 adapter->login_buf_sz, DMA_TO_DEVICE);
 	kfree(adapter->login_buf);
 	adapter->login_buf = NULL;
 }
 
 static void release_login_rsp_buffer(struct ibmvnic_adapter *adapter)
 {
+	if (!adapter->login_rsp_buf)
+		return;
+
+	dma_unmap_single(&adapter->vdev->dev, adapter->login_rsp_buf_token,
+			 adapter->login_rsp_buf_sz, DMA_FROM_DEVICE);
 	kfree(adapter->login_rsp_buf);
 	adapter->login_rsp_buf = NULL;
 }
@@ -3861,11 +3871,14 @@
 	if (rc) {
 		adapter->login_pending = false;
 		netdev_err(adapter->netdev, "Failed to send login, rc=%d\n", rc);
-		goto buf_rsp_map_failed;
+		goto buf_send_failed;
 	}
 
 	return 0;
 
+buf_send_failed:
+	dma_unmap_single(dev, rsp_buffer_token, rsp_buffer_size,
+			 DMA_FROM_DEVICE);
 buf_rsp_map_failed:
 	kfree(login_rsp_buffer);
 	adapter->login_rsp_buf = NULL;
@@ -4430,6 +4443,7 @@
 	int num_tx_pools;
 	int num_rx_pools;
 	u64 *size_array;
+	u32 rsp_len;
 	int i;
 
 	/* CHECK: Test/set of login_pending does not need to be atomic
@@ -4440,11 +4454,6 @@
 		return 0;
 	}
 	adapter->login_pending = false;
-
-	dma_unmap_single(dev, adapter->login_buf_token, adapter->login_buf_sz,
-			 DMA_TO_DEVICE);
-	dma_unmap_single(dev, adapter->login_rsp_buf_token,
-			 adapter->login_rsp_buf_sz, DMA_FROM_DEVICE);
 
 	/* If the number of queues requested can't be allocated by the
 	 * server, the login response will return with code 1. We will need
@@ -4481,6 +4490,23 @@
 		ibmvnic_reset(adapter, VNIC_RESET_FATAL);
 		return -EIO;
 	}
+
+	rsp_len = be32_to_cpu(login_rsp->len);
+	if (be32_to_cpu(login->login_rsp_len) < rsp_len ||
+	    rsp_len <= be32_to_cpu(login_rsp->off_txsubm_subcrqs) ||
+	    rsp_len <= be32_to_cpu(login_rsp->off_rxadd_subcrqs) ||
+	    rsp_len <= be32_to_cpu(login_rsp->off_rxadd_buff_size) ||
+	    rsp_len <= be32_to_cpu(login_rsp->off_supp_tx_desc)) {
+		/* This can happen if a login request times out and there are
+		 * 2 outstanding login requests sent, the LOGIN_RSP crq
+		 * could have been for the older login request. So we are
+		 * parsing the newer response buffer which may be incomplete
+		 */
+		dev_err(dev, "FATAL: Login rsp offsets/lengths invalid\n");
+		ibmvnic_reset(adapter, VNIC_RESET_FATAL);
+		return -EIO;
+	}
+
 	size_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
 		be32_to_cpu(adapter->login_rsp_buf->off_rxadd_buff_size));
 	/* variable buffer sizes are not supported, so just read the
diff --git a/kernel/drivers/net/ethernet/intel/e1000e/netdev.c b/kernel/drivers/net/ethernet/intel/e1000e/netdev.c
index ae0c9aa..b700663 100644
--- a/kernel/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/kernel/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -5294,31 +5294,6 @@
 				ew32(TARC(0), tarc0);
 			}
 
-			/* disable TSO for pcie and 10/100 speeds, to avoid
-			 * some hardware issues
-			 */
-			if (!(adapter->flags & FLAG_TSO_FORCE)) {
-				switch (adapter->link_speed) {
-				case SPEED_10:
-				case SPEED_100:
-					e_info("10/100 speed: disabling TSO\n");
-					netdev->features &= ~NETIF_F_TSO;
-					netdev->features &= ~NETIF_F_TSO6;
-					break;
-				case SPEED_1000:
-					netdev->features |= NETIF_F_TSO;
-					netdev->features |= NETIF_F_TSO6;
-					break;
-				default:
-					/* oops */
-					break;
-				}
-				if (hw->mac.type == e1000_pch_spt) {
-					netdev->features &= ~NETIF_F_TSO;
-					netdev->features &= ~NETIF_F_TSO6;
-				}
-			}
-
 			/* enable transmits in the hardware, need to do this
 			 * after setting TARC(0)
 			 */
@@ -7477,6 +7452,32 @@
 			    NETIF_F_RXCSUM |
 			    NETIF_F_HW_CSUM);
 
+	/* disable TSO for pcie and 10/100 speeds to avoid
+	 * some hardware issues and for i219 to fix transfer
+	 * speed being capped at 60%
+	 */
+	if (!(adapter->flags & FLAG_TSO_FORCE)) {
+		switch (adapter->link_speed) {
+		case SPEED_10:
+		case SPEED_100:
+			e_info("10/100 speed: disabling TSO\n");
+			netdev->features &= ~NETIF_F_TSO;
+			netdev->features &= ~NETIF_F_TSO6;
+			break;
+		case SPEED_1000:
+			netdev->features |= NETIF_F_TSO;
+			netdev->features |= NETIF_F_TSO6;
+			break;
+		default:
+			/* oops */
+			break;
+		}
+		if (hw->mac.type == e1000_pch_spt) {
+			netdev->features &= ~NETIF_F_TSO;
+			netdev->features &= ~NETIF_F_TSO6;
+		}
+	}
+
 	/* Set user-changeable features (subset of all device features) */
 	netdev->hw_features = netdev->features;
 	netdev->hw_features |= NETIF_F_RXFCS;
diff --git a/kernel/drivers/net/ethernet/intel/i40e/i40e_alloc.h b/kernel/drivers/net/ethernet/intel/i40e/i40e_alloc.h
index cb86892..55ba6b6 100644
--- a/kernel/drivers/net/ethernet/intel/i40e/i40e_alloc.h
+++ b/kernel/drivers/net/ethernet/intel/i40e/i40e_alloc.h
@@ -20,16 +20,11 @@
 };
 
 /* prototype for functions used for dynamic memory allocation */
-i40e_status i40e_allocate_dma_mem(struct i40e_hw *hw,
-					    struct i40e_dma_mem *mem,
-					    enum i40e_memory_type type,
-					    u64 size, u32 alignment);
-i40e_status i40e_free_dma_mem(struct i40e_hw *hw,
-					struct i40e_dma_mem *mem);
-i40e_status i40e_allocate_virt_mem(struct i40e_hw *hw,
-					     struct i40e_virt_mem *mem,
-					     u32 size);
-i40e_status i40e_free_virt_mem(struct i40e_hw *hw,
-					 struct i40e_virt_mem *mem);
+int i40e_allocate_dma_mem(struct i40e_hw *hw, struct i40e_dma_mem *mem,
+			  enum i40e_memory_type type, u64 size, u32 alignment);
+int i40e_free_dma_mem(struct i40e_hw *hw, struct i40e_dma_mem *mem);
+int i40e_allocate_virt_mem(struct i40e_hw *hw, struct i40e_virt_mem *mem,
+			   u32 size);
+int i40e_free_virt_mem(struct i40e_hw *hw, struct i40e_virt_mem *mem);
 
 #endif /* _I40E_ALLOC_H_ */
diff --git a/kernel/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/kernel/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
index 989d5c7..8bcf590 100644
--- a/kernel/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+++ b/kernel/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
@@ -1839,7 +1839,7 @@
 void i40e_dbg_init(void)
 {
 	i40e_dbg_root = debugfs_create_dir(i40e_driver_name, NULL);
-	if (!i40e_dbg_root)
+	if (IS_ERR(i40e_dbg_root))
 		pr_info("init of debugfs failed\n");
 }
 
diff --git a/kernel/drivers/net/ethernet/intel/i40e/i40e_diag.c b/kernel/drivers/net/ethernet/intel/i40e/i40e_diag.c
index ef4d376..ca229b0 100644
--- a/kernel/drivers/net/ethernet/intel/i40e/i40e_diag.c
+++ b/kernel/drivers/net/ethernet/intel/i40e/i40e_diag.c
@@ -44,7 +44,7 @@
 	return 0;
 }
 
-struct i40e_diag_reg_test_info i40e_reg_list[] = {
+const struct i40e_diag_reg_test_info i40e_reg_list[] = {
 	/* offset               mask         elements   stride */
 	{I40E_QTX_CTL(0),       0x0000FFBF, 1,
 		I40E_QTX_CTL(1) - I40E_QTX_CTL(0)},
@@ -78,27 +78,28 @@
 {
 	i40e_status ret_code = 0;
 	u32 reg, mask;
+	u32 elements;
 	u32 i, j;
 
 	for (i = 0; i40e_reg_list[i].offset != 0 &&
 					     !ret_code; i++) {
 
+		elements = i40e_reg_list[i].elements;
 		/* set actual reg range for dynamically allocated resources */
 		if (i40e_reg_list[i].offset == I40E_QTX_CTL(0) &&
 		    hw->func_caps.num_tx_qp != 0)
-			i40e_reg_list[i].elements = hw->func_caps.num_tx_qp;
+			elements = hw->func_caps.num_tx_qp;
 		if ((i40e_reg_list[i].offset == I40E_PFINT_ITRN(0, 0) ||
 		     i40e_reg_list[i].offset == I40E_PFINT_ITRN(1, 0) ||
 		     i40e_reg_list[i].offset == I40E_PFINT_ITRN(2, 0) ||
 		     i40e_reg_list[i].offset == I40E_QINT_TQCTL(0) ||
 		     i40e_reg_list[i].offset == I40E_QINT_RQCTL(0)) &&
 		    hw->func_caps.num_msix_vectors != 0)
-			i40e_reg_list[i].elements =
-				hw->func_caps.num_msix_vectors - 1;
+			elements = hw->func_caps.num_msix_vectors - 1;
 
 		/* test register access */
 		mask = i40e_reg_list[i].mask;
-		for (j = 0; j < i40e_reg_list[i].elements && !ret_code; j++) {
+		for (j = 0; j < elements && !ret_code; j++) {
 			reg = i40e_reg_list[i].offset +
 			      (j * i40e_reg_list[i].stride);
 			ret_code = i40e_diag_reg_pattern_test(hw, reg, mask);
diff --git a/kernel/drivers/net/ethernet/intel/i40e/i40e_diag.h b/kernel/drivers/net/ethernet/intel/i40e/i40e_diag.h
index c3340f3..1db7c6d 100644
--- a/kernel/drivers/net/ethernet/intel/i40e/i40e_diag.h
+++ b/kernel/drivers/net/ethernet/intel/i40e/i40e_diag.h
@@ -20,7 +20,7 @@
 	u32 stride;	/* bytes between each element */
 };
 
-extern struct i40e_diag_reg_test_info i40e_reg_list[];
+extern const struct i40e_diag_reg_test_info i40e_reg_list[];
 
 i40e_status i40e_diag_reg_test(struct i40e_hw *hw);
 i40e_status i40e_diag_eeprom_test(struct i40e_hw *hw);
diff --git a/kernel/drivers/net/ethernet/intel/i40e/i40e_main.c b/kernel/drivers/net/ethernet/intel/i40e/i40e_main.c
index 2c60d2a..d23a467 100644
--- a/kernel/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/kernel/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -2788,7 +2788,7 @@
 	struct i40e_pf *pf = vsi->back;
 
 	if (i40e_enabled_xdp_vsi(vsi)) {
-		int frame_size = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+		int frame_size = new_mtu + I40E_PACKET_HDR_PAD;
 
 		if (frame_size > i40e_max_xdp_frame_size(vsi))
 			return -EINVAL;
@@ -10448,8 +10448,11 @@
 					     pf->hw.aq.asq_last_status));
 	}
 	/* reinit the misc interrupt */
-	if (pf->flags & I40E_FLAG_MSIX_ENABLED)
+	if (pf->flags & I40E_FLAG_MSIX_ENABLED) {
 		ret = i40e_setup_misc_vector(pf);
+		if (ret)
+			goto end_unlock;
+	}
 
 	/* Add a filter to drop all Flow control frames from any VSI from being
 	 * transmitted. By doing so we stop a malicious VF from sending out
@@ -12520,6 +12523,8 @@
 	}
 
 	br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
+	if (!br_spec)
+		return -EINVAL;
 
 	nla_for_each_nested(attr, br_spec, rem) {
 		__u16 mode;
@@ -13456,15 +13461,15 @@
 		vsi->id = ctxt.vsi_number;
 	}
 
-	vsi->active_filters = 0;
-	clear_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
 	spin_lock_bh(&vsi->mac_filter_hash_lock);
+	vsi->active_filters = 0;
 	/* If macvlan filters already exist, force them to get loaded */
 	hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) {
 		f->state = I40E_FILTER_NEW;
 		f_count++;
 	}
 	spin_unlock_bh(&vsi->mac_filter_hash_lock);
+	clear_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
 
 	if (f_count) {
 		vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
@@ -14849,6 +14854,7 @@
 	int err;
 	int v_idx;
 
+	pci_set_drvdata(pf->pdev, pf);
 	pci_save_state(pf->pdev);
 
 	/* set up periodic task facility */
diff --git a/kernel/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/kernel/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 7164f4a..6b19964 100644
--- a/kernel/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/kernel/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -210,11 +210,11 @@
  * @hw: pointer to the HW structure.
  * @module_pointer: module pointer location in words from the NVM beginning
  * @offset: offset in words from module start
- * @words: number of words to write
- * @data: buffer with words to write to the Shadow RAM
+ * @words: number of words to read
+ * @data: buffer with words to read to the Shadow RAM
  * @last_command: tells the AdminQ that this is the last command
  *
- * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
+ * Reads a 16 bit words buffer to the Shadow RAM using the admin command.
  **/
 static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw,
 				    u8 module_pointer, u32 offset,
@@ -234,18 +234,18 @@
 	 */
 	if ((offset + words) > hw->nvm.sr_size)
 		i40e_debug(hw, I40E_DEBUG_NVM,
-			   "NVM write error: offset %d beyond Shadow RAM limit %d\n",
+			   "NVM read error: offset %d beyond Shadow RAM limit %d\n",
 			   (offset + words), hw->nvm.sr_size);
 	else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
-		/* We can write only up to 4KB (one sector), in one AQ write */
+		/* We can read only up to 4KB (one sector), in one AQ write */
 		i40e_debug(hw, I40E_DEBUG_NVM,
-			   "NVM write fail error: tried to write %d words, limit is %d.\n",
+			   "NVM read fail error: tried to read %d words, limit is %d.\n",
 			   words, I40E_SR_SECTOR_SIZE_IN_WORDS);
 	else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
 		 != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
-		/* A single write cannot spread over two sectors */
+		/* A single read cannot spread over two sectors */
 		i40e_debug(hw, I40E_DEBUG_NVM,
-			   "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n",
+			   "NVM read error: cannot spread over two sectors in a single read offset=%d words=%d\n",
 			   offset, words);
 	else
 		ret_code = i40e_aq_read_nvm(hw, module_pointer,
diff --git a/kernel/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/kernel/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index bb2a79b..dfaa34f 100644
--- a/kernel/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/kernel/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -4332,9 +4332,6 @@
 		/* duplicate request, so just return success */
 		goto error_pvid;
 
-	i40e_vc_reset_vf(vf, true);
-	/* During reset the VF got a new VSI, so refresh a pointer. */
-	vsi = pf->vsi[vf->lan_vsi_idx];
 	/* Locked once because multiple functions below iterate list */
 	spin_lock_bh(&vsi->mac_filter_hash_lock);
 
@@ -4420,6 +4417,10 @@
 	 */
 	vf->port_vlan_id = le16_to_cpu(vsi->info.pvid);
 
+	i40e_vc_reset_vf(vf, true);
+	/* During reset the VF got a new VSI, so refresh a pointer. */
+	vsi = pf->vsi[vf->lan_vsi_idx];
+
 	ret = i40e_config_vf_promiscuous_mode(vf, vsi->id, allmulti, alluni);
 	if (ret) {
 		dev_err(&pf->pdev->dev, "Unable to config vf promiscuous mode\n");
diff --git a/kernel/drivers/net/ethernet/intel/iavf/iavf.h b/kernel/drivers/net/ethernet/intel/iavf/iavf.h
index a994a29..6a6b5f6 100644
--- a/kernel/drivers/net/ethernet/intel/iavf/iavf.h
+++ b/kernel/drivers/net/ethernet/intel/iavf/iavf.h
@@ -398,7 +398,7 @@
 void iavf_update_stats(struct iavf_adapter *adapter);
 void iavf_reset_interrupt_capability(struct iavf_adapter *adapter);
 int iavf_init_interrupt_scheme(struct iavf_adapter *adapter);
-void iavf_irq_enable_queues(struct iavf_adapter *adapter, u32 mask);
+void iavf_irq_enable_queues(struct iavf_adapter *adapter);
 void iavf_free_all_tx_resources(struct iavf_adapter *adapter);
 void iavf_free_all_rx_resources(struct iavf_adapter *adapter);
 
diff --git a/kernel/drivers/net/ethernet/intel/iavf/iavf_common.c b/kernel/drivers/net/ethernet/intel/iavf/iavf_common.c
index 8547fc8..78423ca 100644
--- a/kernel/drivers/net/ethernet/intel/iavf/iavf_common.c
+++ b/kernel/drivers/net/ethernet/intel/iavf/iavf_common.c
@@ -662,7 +662,7 @@
 	/* Non Tunneled IPv6 */
 	IAVF_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3),
 	IAVF_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3),
-	IAVF_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP,  PAY3),
+	IAVF_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP,  PAY4),
 	IAVF_PTT_UNUSED_ENTRY(91),
 	IAVF_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP,  PAY4),
 	IAVF_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4),
diff --git a/kernel/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/kernel/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
index 4680a2f..05cd705 100644
--- a/kernel/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
+++ b/kernel/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
@@ -968,7 +968,7 @@
 	}
 	if (i == IAVF_RESET_WAIT_COMPLETE_COUNT) {
 		adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
-		adapter->num_active_queues = num_req;
+		adapter->num_req_queues = 0;
 		return -EOPNOTSUPP;
 	}
 
diff --git a/kernel/drivers/net/ethernet/intel/iavf/iavf_main.c b/kernel/drivers/net/ethernet/intel/iavf/iavf_main.c
index ae96b55..b64801b 100644
--- a/kernel/drivers/net/ethernet/intel/iavf/iavf_main.c
+++ b/kernel/drivers/net/ethernet/intel/iavf/iavf_main.c
@@ -234,21 +234,18 @@
 }
 
 /**
- * iavf_irq_enable_queues - Enable interrupt for specified queues
+ * iavf_irq_enable_queues - Enable interrupt for all queues
  * @adapter: board private structure
- * @mask: bitmap of queues to enable
  **/
-void iavf_irq_enable_queues(struct iavf_adapter *adapter, u32 mask)
+void iavf_irq_enable_queues(struct iavf_adapter *adapter)
 {
 	struct iavf_hw *hw = &adapter->hw;
 	int i;
 
 	for (i = 1; i < adapter->num_msix_vectors; i++) {
-		if (mask & BIT(i - 1)) {
-			wr32(hw, IAVF_VFINT_DYN_CTLN1(i - 1),
-			     IAVF_VFINT_DYN_CTLN1_INTENA_MASK |
-			     IAVF_VFINT_DYN_CTLN1_ITR_INDX_MASK);
-		}
+		wr32(hw, IAVF_VFINT_DYN_CTLN1(i - 1),
+		     IAVF_VFINT_DYN_CTLN1_INTENA_MASK |
+		     IAVF_VFINT_DYN_CTLN1_ITR_INDX_MASK);
 	}
 }
 
@@ -262,7 +259,7 @@
 	struct iavf_hw *hw = &adapter->hw;
 
 	iavf_misc_irq_enable(adapter);
-	iavf_irq_enable_queues(adapter, ~0);
+	iavf_irq_enable_queues(adapter);
 
 	if (flush)
 		iavf_flush(hw);
@@ -1380,19 +1377,16 @@
 static void iavf_free_q_vectors(struct iavf_adapter *adapter)
 {
 	int q_idx, num_q_vectors;
-	int napi_vectors;
 
 	if (!adapter->q_vectors)
 		return;
 
 	num_q_vectors = adapter->num_msix_vectors - NONQ_VECS;
-	napi_vectors = adapter->num_active_queues;
 
 	for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
 		struct iavf_q_vector *q_vector = &adapter->q_vectors[q_idx];
 
-		if (q_idx < napi_vectors)
-			netif_napi_del(&q_vector->napi);
+		netif_napi_del(&q_vector->napi);
 	}
 	kfree(adapter->q_vectors);
 	adapter->q_vectors = NULL;
diff --git a/kernel/drivers/net/ethernet/intel/iavf/iavf_register.h b/kernel/drivers/net/ethernet/intel/iavf/iavf_register.h
index bf79333..a19e888 100644
--- a/kernel/drivers/net/ethernet/intel/iavf/iavf_register.h
+++ b/kernel/drivers/net/ethernet/intel/iavf/iavf_register.h
@@ -40,7 +40,7 @@
 #define IAVF_VFINT_DYN_CTL01_INTENA_MASK IAVF_MASK(0x1, IAVF_VFINT_DYN_CTL01_INTENA_SHIFT)
 #define IAVF_VFINT_DYN_CTL01_ITR_INDX_SHIFT 3
 #define IAVF_VFINT_DYN_CTL01_ITR_INDX_MASK IAVF_MASK(0x3, IAVF_VFINT_DYN_CTL01_ITR_INDX_SHIFT)
-#define IAVF_VFINT_DYN_CTLN1(_INTVF) (0x00003800 + ((_INTVF) * 4)) /* _i=0...15 */ /* Reset: VFR */
+#define IAVF_VFINT_DYN_CTLN1(_INTVF) (0x00003800 + ((_INTVF) * 4)) /* _i=0...63 */ /* Reset: VFR */
 #define IAVF_VFINT_DYN_CTLN1_INTENA_SHIFT 0
 #define IAVF_VFINT_DYN_CTLN1_INTENA_MASK IAVF_MASK(0x1, IAVF_VFINT_DYN_CTLN1_INTENA_SHIFT)
 #define IAVF_VFINT_DYN_CTLN1_SWINT_TRIG_SHIFT 2
diff --git a/kernel/drivers/net/ethernet/intel/iavf/iavf_txrx.c b/kernel/drivers/net/ethernet/intel/iavf/iavf_txrx.c
index d481a92..f411e68 100644
--- a/kernel/drivers/net/ethernet/intel/iavf/iavf_txrx.c
+++ b/kernel/drivers/net/ethernet/intel/iavf/iavf_txrx.c
@@ -1061,7 +1061,7 @@
 		cpu_to_le64((u64)IAVF_RX_DESC_FLTSTAT_RSS_HASH <<
 			    IAVF_RX_DESC_STATUS_FLTSTAT_SHIFT);
 
-	if (ring->netdev->features & NETIF_F_RXHASH)
+	if (!(ring->netdev->features & NETIF_F_RXHASH))
 		return;
 
 	if ((rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask) {
diff --git a/kernel/drivers/net/ethernet/intel/ice/ice_base.c b/kernel/drivers/net/ethernet/intel/ice/ice_base.c
index 1929847..59df4c9 100644
--- a/kernel/drivers/net/ethernet/intel/ice/ice_base.c
+++ b/kernel/drivers/net/ethernet/intel/ice/ice_base.c
@@ -353,7 +353,8 @@
 	/* Receive Packet Data Buffer Size.
 	 * The Packet Data Buffer Size is defined in 128 byte units.
 	 */
-	rlan_ctx.dbuf = ring->rx_buf_len >> ICE_RLAN_CTX_DBUF_S;
+	rlan_ctx.dbuf = DIV_ROUND_UP(ring->rx_buf_len,
+				     BIT_ULL(ICE_RLAN_CTX_DBUF_S));
 
 	/* use 32 byte descriptors */
 	rlan_ctx.dsize = 1;
diff --git a/kernel/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c b/kernel/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c
index 1927295..a122a26 100644
--- a/kernel/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c
+++ b/kernel/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c
@@ -1135,16 +1135,21 @@
 				     ICE_FLOW_FLD_OFF_INVAL);
 	}
 
-	/* add filter for outer headers */
 	fltr_idx = ice_ethtool_flow_to_fltr(fsp->flow_type & ~FLOW_EXT);
+
+	assign_bit(fltr_idx, hw->fdir_perfect_fltr, perfect_filter);
+
+	/* add filter for outer headers */
 	ret = ice_fdir_set_hw_fltr_rule(pf, seg, fltr_idx,
 					ICE_FD_HW_SEG_NON_TUN);
-	if (ret == -EEXIST)
-		/* Rule already exists, free memory and continue */
-		devm_kfree(dev, seg);
-	else if (ret)
+	if (ret == -EEXIST) {
+		/* Rule already exists, free memory and count as success */
+		ret = 0;
+		goto err_exit;
+	} else if (ret) {
 		/* could not write filter, free memory */
 		goto err_exit;
+	}
 
 	/* make tunneled filter HW entries if possible */
 	memcpy(&tun_seg[1], seg, sizeof(*seg));
@@ -1159,18 +1164,13 @@
 		devm_kfree(dev, tun_seg);
 	}
 
-	if (perfect_filter)
-		set_bit(fltr_idx, hw->fdir_perfect_fltr);
-	else
-		clear_bit(fltr_idx, hw->fdir_perfect_fltr);
-
 	return ret;
 
 err_exit:
 	devm_kfree(dev, tun_seg);
 	devm_kfree(dev, seg);
 
-	return -EOPNOTSUPP;
+	return ret;
 }
 
 /**
@@ -1680,7 +1680,9 @@
 	}
 
 	/* input struct is added to the HW filter list */
-	ice_fdir_update_list_entry(pf, input, fsp->location);
+	ret = ice_fdir_update_list_entry(pf, input, fsp->location);
+	if (ret)
+		goto release_lock;
 
 	ret = ice_fdir_write_all_fltr(pf, input, true);
 	if (ret)
diff --git a/kernel/drivers/net/ethernet/intel/ice/ice_fltr.c b/kernel/drivers/net/ethernet/intel/ice/ice_fltr.c
index 2418d4f..e27b4de 100644
--- a/kernel/drivers/net/ethernet/intel/ice/ice_fltr.c
+++ b/kernel/drivers/net/ethernet/intel/ice/ice_fltr.c
@@ -128,7 +128,7 @@
  * @mac: MAC address to add
  * @action: filter action
  */
-int
+enum ice_status
 ice_fltr_add_mac_to_list(struct ice_vsi *vsi, struct list_head *list,
 			 const u8 *mac, enum ice_sw_fwd_act_type action)
 {
diff --git a/kernel/drivers/net/ethernet/intel/ice/ice_main.c b/kernel/drivers/net/ethernet/intel/ice/ice_main.c
index f193709..d2ee760 100644
--- a/kernel/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/kernel/drivers/net/ethernet/intel/ice/ice_main.c
@@ -1137,6 +1137,7 @@
 static void ice_aq_check_events(struct ice_pf *pf, u16 opcode,
 				struct ice_rq_event_info *event)
 {
+	struct ice_rq_event_info *task_ev;
 	struct ice_aq_task *task;
 	bool found = false;
 
@@ -1145,15 +1146,15 @@
 		if (task->state || task->opcode != opcode)
 			continue;
 
-		memcpy(&task->event->desc, &event->desc, sizeof(event->desc));
-		task->event->msg_len = event->msg_len;
+		task_ev = task->event;
+		memcpy(&task_ev->desc, &event->desc, sizeof(event->desc));
+		task_ev->msg_len = event->msg_len;
 
 		/* Only copy the data buffer if a destination was set */
-		if (task->event->msg_buf &&
-		    task->event->buf_len > event->buf_len) {
-			memcpy(task->event->msg_buf, event->msg_buf,
+		if (task_ev->msg_buf && task_ev->buf_len >= event->buf_len) {
+			memcpy(task_ev->msg_buf, event->msg_buf,
 			       event->buf_len);
-			task->event->buf_len = event->buf_len;
+			task_ev->buf_len = event->buf_len;
 		}
 
 		task->state = ICE_AQ_TASK_COMPLETE;
@@ -4853,7 +4854,7 @@
 	pr_info("%s\n", ice_driver_string);
 	pr_info("%s\n", ice_copyright);
 
-	ice_wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, KBUILD_MODNAME);
+	ice_wq = alloc_workqueue("%s", 0, 0, KBUILD_MODNAME);
 	if (!ice_wq) {
 		pr_err("Failed to create workqueue\n");
 		return -ENOMEM;
@@ -5200,15 +5201,12 @@
 {
 	int err;
 
-	if (vsi->netdev) {
+	if (vsi->netdev && vsi->type == ICE_VSI_PF) {
 		ice_set_rx_mode(vsi->netdev);
 
-		if (vsi->type != ICE_VSI_LB) {
-			err = ice_vsi_vlan_setup(vsi);
-
-			if (err)
-				return err;
-		}
+		err = ice_vsi_vlan_setup(vsi);
+		if (err)
+			return err;
 	}
 	ice_vsi_cfg_dcb_rings(vsi);
 
@@ -5267,7 +5265,7 @@
 
 	if (vsi->port_info &&
 	    (vsi->port_info->phy.link_info.link_info & ICE_AQ_LINK_UP) &&
-	    vsi->netdev) {
+	    vsi->netdev && vsi->type == ICE_VSI_PF) {
 		ice_print_link_msg(vsi, true);
 		netif_tx_start_all_queues(vsi->netdev);
 		netif_carrier_on(vsi->netdev);
@@ -5277,7 +5275,9 @@
 	 * set the baseline so counters are ready when interface is up
 	 */
 	ice_update_eth_stats(vsi);
-	ice_service_task_schedule(pf);
+
+	if (vsi->type == ICE_VSI_PF)
+		ice_service_task_schedule(pf);
 
 	return 0;
 }
diff --git a/kernel/drivers/net/ethernet/intel/ice/ice_xsk.c b/kernel/drivers/net/ethernet/intel/ice/ice_xsk.c
index 59963b9..e0790df 100644
--- a/kernel/drivers/net/ethernet/intel/ice/ice_xsk.c
+++ b/kernel/drivers/net/ethernet/intel/ice/ice_xsk.c
@@ -169,8 +169,6 @@
 	}
 	netif_tx_stop_queue(netdev_get_tx_queue(vsi->netdev, q_idx));
 
-	ice_qvec_dis_irq(vsi, rx_ring, q_vector);
-
 	ice_fill_txq_meta(vsi, tx_ring, &txq_meta);
 	err = ice_vsi_stop_tx_ring(vsi, ICE_NO_RESET, 0, tx_ring, &txq_meta);
 	if (err)
@@ -185,6 +183,8 @@
 		if (err)
 			return err;
 	}
+	ice_qvec_dis_irq(vsi, rx_ring, q_vector);
+
 	err = ice_vsi_ctrl_one_rx_ring(vsi, false, q_idx, true);
 	if (err)
 		return err;
diff --git a/kernel/drivers/net/ethernet/intel/igb/e1000_mac.c b/kernel/drivers/net/ethernet/intel/igb/e1000_mac.c
index fd8eb2f..57e8134 100644
--- a/kernel/drivers/net/ethernet/intel/igb/e1000_mac.c
+++ b/kernel/drivers/net/ethernet/intel/igb/e1000_mac.c
@@ -426,7 +426,7 @@
 static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
 {
 	u32 hash_value, hash_mask;
-	u8 bit_shift = 0;
+	u8 bit_shift = 1;
 
 	/* Register count multiplied by bits per register */
 	hash_mask = (hw->mac.mta_reg_count * 32) - 1;
@@ -434,7 +434,7 @@
 	/* For a mc_filter_type of 0, bit_shift is the number of left-shifts
 	 * where 0xFF would still fall within the hash mask.
 	 */
-	while (hash_mask >> bit_shift != 0xFF)
+	while (hash_mask >> bit_shift != 0xFF && bit_shift < 4)
 		bit_shift++;
 
 	/* The portion of the address that is used for the hash table
diff --git a/kernel/drivers/net/ethernet/intel/igb/igb.h b/kernel/drivers/net/ethernet/intel/igb/igb.h
index e6d2800..da0e389 100644
--- a/kernel/drivers/net/ethernet/intel/igb/igb.h
+++ b/kernel/drivers/net/ethernet/intel/igb/igb.h
@@ -34,11 +34,11 @@
 /* TX/RX descriptor defines */
 #define IGB_DEFAULT_TXD		256
 #define IGB_DEFAULT_TX_WORK	128
-#define IGB_MIN_TXD		80
+#define IGB_MIN_TXD		64
 #define IGB_MAX_TXD		4096
 
 #define IGB_DEFAULT_RXD		256
-#define IGB_MIN_RXD		80
+#define IGB_MIN_RXD		64
 #define IGB_MAX_RXD		4096
 
 #define IGB_DEFAULT_ITR		3 /* dynamic */
diff --git a/kernel/drivers/net/ethernet/intel/igb/igb_ethtool.c b/kernel/drivers/net/ethernet/intel/igb/igb_ethtool.c
index 5e3b0a5..d9de3b8 100644
--- a/kernel/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/kernel/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -822,6 +822,8 @@
 		 */
 		ret_val = hw->nvm.ops.read(hw, last_word, 1,
 				   &eeprom_buff[last_word - first_word]);
+		if (ret_val)
+			goto out;
 	}
 
 	/* Device's eeprom is always little-endian, word addressable */
@@ -841,6 +843,7 @@
 		hw->nvm.ops.update(hw);
 
 	igb_set_fw_version(adapter);
+out:
 	kfree(eeprom_buff);
 	return ret_val;
 }
diff --git a/kernel/drivers/net/ethernet/intel/igb/igb_main.c b/kernel/drivers/net/ethernet/intel/igb/igb_main.c
index f24f1a8..01176c8 100644
--- a/kernel/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/kernel/drivers/net/ethernet/intel/igb/igb_main.c
@@ -1204,8 +1204,12 @@
 	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);
 	}
@@ -3817,9 +3821,7 @@
 	igb_release_hw_control(adapter);
 
 #ifdef CONFIG_PCI_IOV
-	rtnl_lock();
 	igb_disable_sriov(pdev);
-	rtnl_unlock();
 #endif
 
 	unregister_netdev(netdev);
@@ -3855,8 +3857,9 @@
 	struct pci_dev *pdev = adapter->pdev;
 	struct e1000_hw *hw = &adapter->hw;
 
-	/* Virtualization features not supported on i210 family. */
-	if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211))
+	/* Virtualization features not supported on i210 and 82580 family. */
+	if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211) ||
+	    (hw->mac.type == e1000_82580))
 		return;
 
 	/* Of the below we really only want the effect of getting
@@ -4729,6 +4732,10 @@
 static void igb_set_rx_buffer_len(struct igb_adapter *adapter,
 				  struct igb_ring *rx_ring)
 {
+#if (PAGE_SIZE < 8192)
+	struct e1000_hw *hw = &adapter->hw;
+#endif
+
 	/* set build_skb and buffer size flags */
 	clear_ring_build_skb_enabled(rx_ring);
 	clear_ring_uses_large_buffer(rx_ring);
@@ -4739,10 +4746,9 @@
 	set_ring_build_skb_enabled(rx_ring);
 
 #if (PAGE_SIZE < 8192)
-	if (adapter->max_frame_size <= IGB_MAX_FRAME_BUILD_SKB)
-		return;
-
-	set_ring_uses_large_buffer(rx_ring);
+	if (adapter->max_frame_size > IGB_MAX_FRAME_BUILD_SKB ||
+	    rd32(E1000_RCTL) & E1000_RCTL_SBP)
+		set_ring_uses_large_buffer(rx_ring);
 #endif
 }
 
@@ -5879,7 +5885,7 @@
 	 */
 	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;
@@ -9451,6 +9457,11 @@
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct igb_adapter *adapter = netdev_priv(netdev);
 
+	if (state == pci_channel_io_normal) {
+		dev_warn(&pdev->dev, "Non-correctable non-fatal error reported.\n");
+		return PCI_ERS_RESULT_CAN_RECOVER;
+	}
+
 	netif_device_detach(netdev);
 
 	if (state == pci_channel_io_perm_failure)
diff --git a/kernel/drivers/net/ethernet/intel/igb/igb_ptp.c b/kernel/drivers/net/ethernet/intel/igb/igb_ptp.c
index 86a5762..0dbbb32 100644
--- a/kernel/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/kernel/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -1262,18 +1262,6 @@
 		return;
 	}
 
-	spin_lock_init(&adapter->tmreg_lock);
-	INIT_WORK(&adapter->ptp_tx_work, igb_ptp_tx_work);
-
-	if (adapter->ptp_flags & IGB_PTP_OVERFLOW_CHECK)
-		INIT_DELAYED_WORK(&adapter->ptp_overflow_work,
-				  igb_ptp_overflow_check);
-
-	adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
-	adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF;
-
-	igb_ptp_reset(adapter);
-
 	adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps,
 						&adapter->pdev->dev);
 	if (IS_ERR(adapter->ptp_clock)) {
@@ -1283,6 +1271,18 @@
 		dev_info(&adapter->pdev->dev, "added PHC on %s\n",
 			 adapter->netdev->name);
 		adapter->ptp_flags |= IGB_PTP_ENABLED;
+
+		spin_lock_init(&adapter->tmreg_lock);
+		INIT_WORK(&adapter->ptp_tx_work, igb_ptp_tx_work);
+
+		if (adapter->ptp_flags & IGB_PTP_OVERFLOW_CHECK)
+			INIT_DELAYED_WORK(&adapter->ptp_overflow_work,
+					  igb_ptp_overflow_check);
+
+		adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
+		adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF;
+
+		igb_ptp_reset(adapter);
 	}
 }
 
diff --git a/kernel/drivers/net/ethernet/intel/igbvf/igbvf.h b/kernel/drivers/net/ethernet/intel/igbvf/igbvf.h
index 975eb47..b39fca9 100644
--- a/kernel/drivers/net/ethernet/intel/igbvf/igbvf.h
+++ b/kernel/drivers/net/ethernet/intel/igbvf/igbvf.h
@@ -39,11 +39,11 @@
 /* Tx/Rx descriptor defines */
 #define IGBVF_DEFAULT_TXD	256
 #define IGBVF_MAX_TXD		4096
-#define IGBVF_MIN_TXD		80
+#define IGBVF_MIN_TXD		64
 
 #define IGBVF_DEFAULT_RXD	256
 #define IGBVF_MAX_RXD		4096
-#define IGBVF_MIN_RXD		80
+#define IGBVF_MIN_RXD		64
 
 #define IGBVF_MIN_ITR_USECS	10 /* 100000 irq/sec */
 #define IGBVF_MAX_ITR_USECS	10000 /* 100    irq/sec */
diff --git a/kernel/drivers/net/ethernet/intel/igbvf/netdev.c b/kernel/drivers/net/ethernet/intel/igbvf/netdev.c
index fe8c0a2..037ec90 100644
--- a/kernel/drivers/net/ethernet/intel/igbvf/netdev.c
+++ b/kernel/drivers/net/ethernet/intel/igbvf/netdev.c
@@ -1074,7 +1074,7 @@
 			  igbvf_intr_msix_rx, 0, adapter->rx_ring->name,
 			  netdev);
 	if (err)
-		goto out;
+		goto free_irq_tx;
 
 	adapter->rx_ring->itr_register = E1000_EITR(vector);
 	adapter->rx_ring->itr_val = adapter->current_itr;
@@ -1083,10 +1083,14 @@
 	err = request_irq(adapter->msix_entries[vector].vector,
 			  igbvf_msix_other, 0, netdev->name, netdev);
 	if (err)
-		goto out;
+		goto free_irq_rx;
 
 	igbvf_configure_msix(adapter);
 	return 0;
+free_irq_rx:
+	free_irq(adapter->msix_entries[--vector].vector, netdev);
+free_irq_tx:
+	free_irq(adapter->msix_entries[--vector].vector, netdev);
 out:
 	return err;
 }
diff --git a/kernel/drivers/net/ethernet/intel/igbvf/vf.c b/kernel/drivers/net/ethernet/intel/igbvf/vf.c
index b8ba3f9..a47a2e3 100644
--- a/kernel/drivers/net/ethernet/intel/igbvf/vf.c
+++ b/kernel/drivers/net/ethernet/intel/igbvf/vf.c
@@ -1,6 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright(c) 2009 - 2018 Intel Corporation. */
 
+#include <linux/etherdevice.h>
+
 #include "vf.h"
 
 static s32 e1000_check_for_link_vf(struct e1000_hw *hw);
@@ -131,11 +133,16 @@
 		/* set our "perm_addr" based on info provided by PF */
 		ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
 		if (!ret_val) {
-			if (msgbuf[0] == (E1000_VF_RESET |
-					  E1000_VT_MSGTYPE_ACK))
+			switch (msgbuf[0]) {
+			case E1000_VF_RESET | E1000_VT_MSGTYPE_ACK:
 				memcpy(hw->mac.perm_addr, addr, ETH_ALEN);
-			else
+				break;
+			case E1000_VF_RESET | E1000_VT_MSGTYPE_NACK:
+				eth_zero_addr(hw->mac.perm_addr);
+				break;
+			default:
 				ret_val = -E1000_ERR_MAC_INIT;
+			}
 		}
 	}
 
diff --git a/kernel/drivers/net/ethernet/intel/igc/igc.h b/kernel/drivers/net/ethernet/intel/igc/igc.h
index a97bf7a..31af08c 100644
--- a/kernel/drivers/net/ethernet/intel/igc/igc.h
+++ b/kernel/drivers/net/ethernet/intel/igc/igc.h
@@ -13,6 +13,7 @@
 #include <linux/ptp_clock_kernel.h>
 #include <linux/timecounter.h>
 #include <linux/net_tstamp.h>
+#include <linux/bitfield.h>
 
 #include "igc_hw.h"
 
@@ -87,6 +88,8 @@
 	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;
@@ -207,6 +210,10 @@
 	struct ptp_clock *ptp_clock;
 	struct ptp_clock_info ptp_caps;
 	struct work_struct ptp_tx_work;
+	/* Access to ptp_tx_skb and ptp_tx_start are protected by the
+	 * ptp_tx_lock.
+	 */
+	spinlock_t ptp_tx_lock;
 	struct sk_buff *ptp_tx_skb;
 	struct hwtstamp_config tstamp_config;
 	unsigned long ptp_tx_start;
@@ -270,6 +277,33 @@
 #define IGC_MRQC_RSS_FIELD_IPV4_UDP	0x00400000
 #define IGC_MRQC_RSS_FIELD_IPV6_UDP	0x00800000
 
+/* RX-desc Write-Back format RSS Type's */
+enum igc_rss_type_num {
+	IGC_RSS_TYPE_NO_HASH		= 0,
+	IGC_RSS_TYPE_HASH_TCP_IPV4	= 1,
+	IGC_RSS_TYPE_HASH_IPV4		= 2,
+	IGC_RSS_TYPE_HASH_TCP_IPV6	= 3,
+	IGC_RSS_TYPE_HASH_IPV6_EX	= 4,
+	IGC_RSS_TYPE_HASH_IPV6		= 5,
+	IGC_RSS_TYPE_HASH_TCP_IPV6_EX	= 6,
+	IGC_RSS_TYPE_HASH_UDP_IPV4	= 7,
+	IGC_RSS_TYPE_HASH_UDP_IPV6	= 8,
+	IGC_RSS_TYPE_HASH_UDP_IPV6_EX	= 9,
+	IGC_RSS_TYPE_MAX		= 10,
+};
+#define IGC_RSS_TYPE_MAX_TABLE		16
+#define IGC_RSS_TYPE_MASK		GENMASK(3,0) /* 4-bits (3:0) = mask 0x0F */
+
+/* igc_rss_type - Rx descriptor RSS type field */
+static inline u32 igc_rss_type(const union igc_adv_rx_desc *rx_desc)
+{
+	/* RSS Type 4-bits (3:0) number: 0-9 (above 9 is reserved)
+	 * Accessing the same bits via u16 (wb.lower.lo_dword.hs_rss.pkt_info)
+	 * is slightly slower than via u32 (wb.lower.lo_dword.data)
+	 */
+	return le32_get_bits(rx_desc->wb.lower.lo_dword.data, IGC_RSS_TYPE_MASK);
+}
+
 /* Interrupt defines */
 #define IGC_START_ITR			648 /* ~6000 ints/sec */
 #define IGC_4K_ITR			980
@@ -285,11 +319,11 @@
 /* TX/RX descriptor defines */
 #define IGC_DEFAULT_TXD		256
 #define IGC_DEFAULT_TX_WORK	128
-#define IGC_MIN_TXD		80
+#define IGC_MIN_TXD		64
 #define IGC_MAX_TXD		4096
 
 #define IGC_DEFAULT_RXD		256
-#define IGC_MIN_RXD		80
+#define IGC_MIN_RXD		64
 #define IGC_MAX_RXD		4096
 
 /* Supported Rx Buffer Sizes */
@@ -359,7 +393,6 @@
 	__IGC_TESTING,
 	__IGC_RESETTING,
 	__IGC_DOWN,
-	__IGC_PTP_TX_IN_PROGRESS,
 };
 
 enum igc_tx_flags {
diff --git a/kernel/drivers/net/ethernet/intel/igc/igc_defines.h b/kernel/drivers/net/ethernet/intel/igc/igc_defines.h
index 32f5fd6..352b50d 100644
--- a/kernel/drivers/net/ethernet/intel/igc/igc_defines.h
+++ b/kernel/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/kernel/drivers/net/ethernet/intel/igc/igc_ethtool.c b/kernel/drivers/net/ethernet/intel/igc/igc_ethtool.c
index da259cd..d28ac3a 100644
--- a/kernel/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/kernel/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -1673,6 +1673,8 @@
 	/* twisted pair */
 	cmd->base.port = PORT_TP;
 	cmd->base.phy_address = hw->phy.addr;
+	ethtool_link_ksettings_add_link_mode(cmd, supported, TP);
+	ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);
 
 	/* advertising link modes */
 	if (hw->phy.autoneg_advertised & ADVERTISE_10_HALF)
diff --git a/kernel/drivers/net/ethernet/intel/igc/igc_main.c b/kernel/drivers/net/ethernet/intel/igc/igc_main.c
index e7ffe63..631ce79 100644
--- a/kernel/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/kernel/drivers/net/ethernet/intel/igc/igc_main.c
@@ -600,7 +600,6 @@
 	/* disable the queue */
 	wr32(IGC_TXDCTL(reg_idx), 0);
 	wrfl();
-	mdelay(10);
 
 	wr32(IGC_TDLEN(reg_idx),
 	     ring->count * sizeof(union igc_adv_tx_desc));
@@ -898,25 +897,118 @@
 	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;
-	u32 launchtime;
+	ktime_t now = ktime_get_clocktai();
+	ktime_t baset_est, end_of_cycle;
+	s32 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(end_of_cycle, 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,35 +1027,17 @@
 	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;
-
-		first->skb->tstamp = ktime_set(0, 0);
-		context_desc->launch_time = igc_tx_launchtime(adapter,
-							      txtime);
-	} else {
-		context_desc->launch_time = 0;
-	}
+	context_desc->launch_time	= launch_time;
 }
 
-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)
+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;
@@ -985,10 +1059,7 @@
 		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;
 		}
@@ -1006,7 +1077,8 @@
 	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)
@@ -1230,6 +1302,7 @@
 
 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;
@@ -1316,8 +1389,8 @@
 	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;
 }
@@ -1325,11 +1398,14 @@
 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;
 
@@ -1343,11 +1419,40 @@
 		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;
@@ -1361,9 +1466,10 @@
 		 * the other timer registers before skipping the
 		 * timestamping request.
 		 */
-		if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON &&
-		    !test_and_set_bit_lock(__IGC_PTP_TX_IN_PROGRESS,
-					   &adapter->state)) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&adapter->ptp_tx_lock, flags);
+		if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON && !adapter->ptp_tx_skb) {
 			skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
 			tx_flags |= IGC_TX_FLAGS_TSTAMP;
 
@@ -1372,17 +1478,19 @@
 		} else {
 			adapter->tx_hwtstamp_skipped++;
 		}
+
+		spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags);
 	}
 
 	/* record initial flags and protocol */
 	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);
 
@@ -1463,14 +1571,36 @@
 		   le32_to_cpu(rx_desc->wb.upper.status_error));
 }
 
+/* Mapping HW RSS Type to enum pkt_hash_types */
+static const enum pkt_hash_types igc_rss_type_table[IGC_RSS_TYPE_MAX_TABLE] = {
+	[IGC_RSS_TYPE_NO_HASH]		= PKT_HASH_TYPE_L2,
+	[IGC_RSS_TYPE_HASH_TCP_IPV4]	= PKT_HASH_TYPE_L4,
+	[IGC_RSS_TYPE_HASH_IPV4]	= PKT_HASH_TYPE_L3,
+	[IGC_RSS_TYPE_HASH_TCP_IPV6]	= PKT_HASH_TYPE_L4,
+	[IGC_RSS_TYPE_HASH_IPV6_EX]	= PKT_HASH_TYPE_L3,
+	[IGC_RSS_TYPE_HASH_IPV6]	= PKT_HASH_TYPE_L3,
+	[IGC_RSS_TYPE_HASH_TCP_IPV6_EX] = PKT_HASH_TYPE_L4,
+	[IGC_RSS_TYPE_HASH_UDP_IPV4]	= PKT_HASH_TYPE_L4,
+	[IGC_RSS_TYPE_HASH_UDP_IPV6]	= PKT_HASH_TYPE_L4,
+	[IGC_RSS_TYPE_HASH_UDP_IPV6_EX] = PKT_HASH_TYPE_L4,
+	[10] = PKT_HASH_TYPE_NONE, /* RSS Type above 9 "Reserved" by HW  */
+	[11] = PKT_HASH_TYPE_NONE, /* keep array sized for SW bit-mask   */
+	[12] = PKT_HASH_TYPE_NONE, /* to handle future HW revisons       */
+	[13] = PKT_HASH_TYPE_NONE,
+	[14] = PKT_HASH_TYPE_NONE,
+	[15] = PKT_HASH_TYPE_NONE,
+};
+
 static inline void igc_rx_hash(struct igc_ring *ring,
 			       union igc_adv_rx_desc *rx_desc,
 			       struct sk_buff *skb)
 {
-	if (ring->netdev->features & NETIF_F_RXHASH)
-		skb_set_hash(skb,
-			     le32_to_cpu(rx_desc->wb.lower.hi_dword.rss),
-			     PKT_HASH_TYPE_L3);
+	if (ring->netdev->features & NETIF_F_RXHASH) {
+		u32 rss_hash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);
+		u32 rss_type = igc_rss_type(rx_desc);
+
+		skb_set_hash(skb, rss_hash, igc_rss_type_table[rss_type]);
+	}
 }
 
 /**
@@ -4756,9 +4886,10 @@
 		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
@@ -4767,13 +4898,18 @@
 		if (e->command != TC_TAPRIO_CMD_SET_GATES)
 			return false;
 
-		for (i = 0; i < adapter->num_tx_queues; i++) {
-			if (e->gate_mask & BIT(i))
+		for (i = 0; i < adapter->num_tx_queues; i++)
+			if (e->gate_mask & BIT(i)) {
 				queue_uses[i]++;
 
-			if (queue_uses[i] > 1)
-				return false;
-		}
+				/* 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;
+			}
 	}
 
 	return true;
@@ -4798,13 +4934,18 @@
 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;
+	int i;
 
 	if (!qopt->enable) {
 		adapter->base_time = 0;
 		return 0;
 	}
+
+	if (qopt->base_time < 0)
+		return -ERANGE;
 
 	if (adapter->base_time)
 		return -EALREADY;
@@ -4815,14 +4956,25 @@
 	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;
 
 		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];
@@ -4830,11 +4982,30 @@
 			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;
+	}
+
+	/* 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;
@@ -5110,6 +5281,7 @@
 	netdev->features |= NETIF_F_TSO;
 	netdev->features |= NETIF_F_TSO6;
 	netdev->features |= NETIF_F_TSO_ECN;
+	netdev->features |= NETIF_F_RXHASH;
 	netdev->features |= NETIF_F_RXCSUM;
 	netdev->features |= NETIF_F_HW_CSUM;
 	netdev->features |= NETIF_F_SCTP_CRC;
diff --git a/kernel/drivers/net/ethernet/intel/igc/igc_ptp.c b/kernel/drivers/net/ethernet/intel/igc/igc_ptp.c
index 4ab46ee..25b238c 100644
--- a/kernel/drivers/net/ethernet/intel/igc/igc_ptp.c
+++ b/kernel/drivers/net/ethernet/intel/igc/igc_ptp.c
@@ -134,10 +134,12 @@
  *
  * We need to convert the system time value stored in the RX/TXSTMP registers
  * into a hwtstamp which can be used by the upper level timestamping functions.
+ *
+ * Returns 0 on success.
  **/
-static void igc_ptp_systim_to_hwtstamp(struct igc_adapter *adapter,
-				       struct skb_shared_hwtstamps *hwtstamps,
-				       u64 systim)
+static int igc_ptp_systim_to_hwtstamp(struct igc_adapter *adapter,
+				      struct skb_shared_hwtstamps *hwtstamps,
+				      u64 systim)
 {
 	switch (adapter->hw.mac.type) {
 	case igc_i225:
@@ -147,8 +149,9 @@
 						systim & 0xFFFFFFFF);
 		break;
 	default:
-		break;
+		return -EINVAL;
 	}
+	return 0;
 }
 
 /**
@@ -320,6 +323,7 @@
 	return 0;
 }
 
+/* Requires adapter->ptp_tx_lock held by caller. */
 static void igc_ptp_tx_timeout(struct igc_adapter *adapter)
 {
 	struct igc_hw *hw = &adapter->hw;
@@ -327,7 +331,6 @@
 	dev_kfree_skb_any(adapter->ptp_tx_skb);
 	adapter->ptp_tx_skb = NULL;
 	adapter->tx_hwtstamp_timeouts++;
-	clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);
 	/* Clear the tx valid bit in TSYNCTXCTL register to enable interrupt. */
 	rd32(IGC_TXSTMPH);
 	netdev_warn(adapter->netdev, "Tx timestamp timeout\n");
@@ -335,20 +338,20 @@
 
 void igc_ptp_tx_hang(struct igc_adapter *adapter)
 {
-	bool timeout = time_is_before_jiffies(adapter->ptp_tx_start +
-					      IGC_PTP_TX_TIMEOUT);
+	unsigned long flags;
 
-	if (!test_bit(__IGC_PTP_TX_IN_PROGRESS, &adapter->state))
-		return;
+	spin_lock_irqsave(&adapter->ptp_tx_lock, flags);
 
-	/* If we haven't received a timestamp within the timeout, it is
-	 * reasonable to assume that it will never occur, so we can unlock the
-	 * timestamp bit when this occurs.
-	 */
-	if (timeout) {
-		cancel_work_sync(&adapter->ptp_tx_work);
-		igc_ptp_tx_timeout(adapter);
-	}
+	if (!adapter->ptp_tx_skb)
+		goto unlock;
+
+	if (time_is_after_jiffies(adapter->ptp_tx_start + IGC_PTP_TX_TIMEOUT))
+		goto unlock;
+
+	igc_ptp_tx_timeout(adapter);
+
+unlock:
+	spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags);
 }
 
 /**
@@ -358,6 +361,8 @@
  * If we were asked to do hardware stamping and such a time stamp is
  * available, then it must have been for this skb here because we only
  * allow only one such packet into the queue.
+ *
+ * Context: Expects adapter->ptp_tx_lock to be held by caller.
  */
 static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter)
 {
@@ -372,7 +377,8 @@
 
 	regval = rd32(IGC_TXSTMPL);
 	regval |= (u64)rd32(IGC_TXSTMPH) << 32;
-	igc_ptp_systim_to_hwtstamp(adapter, &shhwtstamps, regval);
+	if (igc_ptp_systim_to_hwtstamp(adapter, &shhwtstamps, regval))
+		return;
 
 	switch (adapter->link_speed) {
 	case SPEED_10:
@@ -392,13 +398,7 @@
 	shhwtstamps.hwtstamp =
 		ktime_add_ns(shhwtstamps.hwtstamp, adjust);
 
-	/* Clear the lock early before calling skb_tstamp_tx so that
-	 * applications are not woken up before the lock bit is clear. We use
-	 * a copy of the skb pointer to ensure other threads can't change it
-	 * while we're notifying the stack.
-	 */
 	adapter->ptp_tx_skb = NULL;
-	clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);
 
 	/* Notify the stack and free the skb after we've unlocked */
 	skb_tstamp_tx(skb, &shhwtstamps);
@@ -409,24 +409,33 @@
  * igc_ptp_tx_work
  * @work: pointer to work struct
  *
- * This work function polls the TSYNCTXCTL valid bit to determine when a
- * timestamp has been taken for the current stored skb.
+ * This work function checks the TSYNCTXCTL valid bit to determine when
+ * a timestamp has been taken for the current stored skb.
  */
 static void igc_ptp_tx_work(struct work_struct *work)
 {
 	struct igc_adapter *adapter = container_of(work, struct igc_adapter,
 						   ptp_tx_work);
 	struct igc_hw *hw = &adapter->hw;
+	unsigned long flags;
 	u32 tsynctxctl;
 
-	if (!test_bit(__IGC_PTP_TX_IN_PROGRESS, &adapter->state))
-		return;
+	spin_lock_irqsave(&adapter->ptp_tx_lock, flags);
+
+	if (!adapter->ptp_tx_skb)
+		goto unlock;
 
 	tsynctxctl = rd32(IGC_TSYNCTXCTL);
-	if (WARN_ON_ONCE(!(tsynctxctl & IGC_TSYNCTXCTL_TXTT_0)))
-		return;
+	tsynctxctl &= IGC_TSYNCTXCTL_TXTT_0;
+	if (!tsynctxctl) {
+		WARN_ONCE(1, "Received a TSTAMP interrupt but no TSTAMP is ready.\n");
+		goto unlock;
+	}
 
 	igc_ptp_tx_hwtstamp(adapter);
+
+unlock:
+	spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags);
 }
 
 /**
@@ -502,6 +511,7 @@
 		return;
 	}
 
+	spin_lock_init(&adapter->ptp_tx_lock);
 	spin_lock_init(&adapter->tmreg_lock);
 	INIT_WORK(&adapter->ptp_tx_work, igc_ptp_tx_work);
 
@@ -555,7 +565,6 @@
 	cancel_work_sync(&adapter->ptp_tx_work);
 	dev_kfree_skb_any(adapter->ptp_tx_skb);
 	adapter->ptp_tx_skb = NULL;
-	clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);
 
 	if (pci_device_is_present(adapter->pdev))
 		igc_ptp_time_save(adapter);
diff --git a/kernel/drivers/net/ethernet/intel/igc/igc_tsn.c b/kernel/drivers/net/ethernet/intel/igc/igc_tsn.c
index 174103c..2d4db2a 100644
--- a/kernel/drivers/net/ethernet/intel/igc/igc_tsn.c
+++ b/kernel/drivers/net/ethernet/intel/igc/igc_tsn.c
@@ -92,15 +92,8 @@
 		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;
diff --git a/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 27c6f91..18251ed 100644
--- a/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -67,6 +67,8 @@
 #define IXGBE_RXBUFFER_4K    4096
 #define IXGBE_MAX_RXBUFFER  16384  /* largest size for a single descriptor */
 
+#define IXGBE_PKT_HDR_PAD   (ETH_HLEN + ETH_FCS_LEN + (VLAN_HLEN * 2))
+
 /* Attempt to maximize the headroom available for incoming frames.  We
  * use a 2K buffer for receives and need 1536/1534 to store the data for
  * the frame.  This leaves us with 512 bytes of room.  From that we need
diff --git a/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index 5598390..2eb1331 100644
--- a/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -2641,6 +2641,14 @@
 	return 0;
 }
 
+static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter)
+{
+	if (adapter->hw.mac.type < ixgbe_mac_X550)
+		return 16;
+	else
+		return 64;
+}
+
 static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
 			   u32 *rule_locs)
 {
@@ -2649,7 +2657,8 @@
 
 	switch (cmd->cmd) {
 	case ETHTOOL_GRXRINGS:
-		cmd->data = adapter->num_rx_queues;
+		cmd->data = min_t(int, adapter->num_rx_queues,
+				  ixgbe_rss_indir_tbl_max(adapter));
 		ret = 0;
 		break;
 	case ETHTOOL_GRXCLSRLCNT:
@@ -3051,14 +3060,6 @@
 	return ret;
 }
 
-static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter)
-{
-	if (adapter->hw.mac.type < ixgbe_mac_X550)
-		return 16;
-	else
-		return 64;
-}
-
 static u32 ixgbe_get_rxfh_key_size(struct net_device *netdev)
 {
 	return IXGBE_RSS_KEY_SIZE;
@@ -3107,8 +3108,8 @@
 	int i;
 	u32 reta_entries = ixgbe_rss_indir_tbl_entries(adapter);
 
-	if (hfunc)
-		return -EINVAL;
+	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
+		return -EOPNOTSUPP;
 
 	/* Fill out the redirection table */
 	if (indir) {
diff --git a/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index b5b8be4..2b100b7 100644
--- a/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -6729,6 +6729,18 @@
 }
 
 /**
+ * ixgbe_max_xdp_frame_size - returns the maximum allowed frame size for XDP
+ * @adapter: device handle, pointer to adapter
+ */
+static int ixgbe_max_xdp_frame_size(struct ixgbe_adapter *adapter)
+{
+	if (PAGE_SIZE >= 8192 || adapter->flags2 & IXGBE_FLAG2_RX_LEGACY)
+		return IXGBE_RXBUFFER_2K;
+	else
+		return IXGBE_RXBUFFER_3K;
+}
+
+/**
  * ixgbe_change_mtu - Change the Maximum Transfer Unit
  * @netdev: network interface device structure
  * @new_mtu: new value for maximum frame size
@@ -6739,18 +6751,12 @@
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
-	if (adapter->xdp_prog) {
-		int new_frame_size = new_mtu + ETH_HLEN + ETH_FCS_LEN +
-				     VLAN_HLEN;
-		int i;
+	if (ixgbe_enabled_xdp_adapter(adapter)) {
+		int new_frame_size = new_mtu + IXGBE_PKT_HDR_PAD;
 
-		for (i = 0; i < adapter->num_rx_queues; i++) {
-			struct ixgbe_ring *ring = adapter->rx_ring[i];
-
-			if (new_frame_size > ixgbe_rx_bufsz(ring)) {
-				e_warn(probe, "Requested MTU size is not supported with XDP\n");
-				return -EINVAL;
-			}
+		if (new_frame_size > ixgbe_max_xdp_frame_size(adapter)) {
+			e_warn(probe, "Requested MTU size is not supported with XDP\n");
+			return -EINVAL;
 		}
 	}
 
@@ -8403,7 +8409,7 @@
 		struct ixgbe_adapter *adapter = q_vector->adapter;
 
 		if (unlikely(skb_tail_pointer(skb) < hdr.network +
-			     VXLAN_HEADROOM))
+			     vxlan_headroom(0)))
 			return;
 
 		/* verify the port is recognized as VXLAN */
diff --git a/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
index fc389ee..b041390 100644
--- a/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
+++ b/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
@@ -851,9 +851,11 @@
 	rp_pdev = pci_get_domain_bus_and_slot(0, 0, devfn);
 	if (rp_pdev && rp_pdev->subordinate) {
 		bus = rp_pdev->subordinate->number;
+		pci_dev_put(rp_pdev);
 		return pci_get_domain_bus_and_slot(0, bus, 0);
 	}
 
+	pci_dev_put(rp_pdev);
 	return NULL;
 }
 
@@ -870,6 +872,7 @@
 	struct ixgbe_adapter *adapter = hw->back;
 	struct pci_dev *pdev = adapter->pdev;
 	struct pci_dev *func0_pdev;
+	bool has_mii = false;
 
 	/* For the C3000 family of SoCs (x550em_a) the internal ixgbe devices
 	 * are always downstream of root ports @ 0000:00:16.0 & 0000:00:17.0
@@ -880,15 +883,16 @@
 	func0_pdev = ixgbe_get_first_secondary_devfn(PCI_DEVFN(0x16, 0));
 	if (func0_pdev) {
 		if (func0_pdev == pdev)
-			return true;
-		else
-			return false;
+			has_mii = true;
+		goto out;
 	}
 	func0_pdev = ixgbe_get_first_secondary_devfn(PCI_DEVFN(0x17, 0));
 	if (func0_pdev == pdev)
-		return true;
+		has_mii = true;
 
-	return false;
+out:
+	pci_dev_put(func0_pdev);
+	return has_mii;
 }
 
 /**
diff --git a/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index 8b7f300..3eb2c05 100644
--- a/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ b/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -989,6 +989,7 @@
 	u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED;
 	u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED;
 	u32 tsync_rx_mtrl = PTP_EV_PORT << 16;
+	u32 aflags = adapter->flags;
 	bool is_l2 = false;
 	u32 regval;
 
@@ -1009,20 +1010,20 @@
 	case HWTSTAMP_FILTER_NONE:
 		tsync_rx_ctl = 0;
 		tsync_rx_mtrl = 0;
-		adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
-				    IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
+		aflags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
+			    IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
 		break;
 	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
 		tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
 		tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG;
-		adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
-				   IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
+		aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
+			   IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
 		break;
 	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
 		tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
 		tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG;
-		adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
-				   IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
+		aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
+			   IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
 		break;
 	case HWTSTAMP_FILTER_PTP_V2_EVENT:
 	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
@@ -1036,8 +1037,8 @@
 		tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2;
 		is_l2 = true;
 		config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
-		adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
-				   IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
+		aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
+			   IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
 		break;
 	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
 	case HWTSTAMP_FILTER_NTP_ALL:
@@ -1048,7 +1049,7 @@
 		if (hw->mac.type >= ixgbe_mac_X550) {
 			tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_ALL;
 			config->rx_filter = HWTSTAMP_FILTER_ALL;
-			adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED;
+			aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED;
 			break;
 		}
 		fallthrough;
@@ -1059,8 +1060,6 @@
 		 * Delay_Req messages and hardware does not support
 		 * timestamping all packets => return error
 		 */
-		adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED |
-				    IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);
 		config->rx_filter = HWTSTAMP_FILTER_NONE;
 		return -ERANGE;
 	}
@@ -1092,8 +1091,8 @@
 			       IXGBE_TSYNCRXCTL_TYPE_ALL |
 			       IXGBE_TSYNCRXCTL_TSIP_UT_EN;
 		config->rx_filter = HWTSTAMP_FILTER_ALL;
-		adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED;
-		adapter->flags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER;
+		aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED;
+		aflags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER;
 		is_l2 = true;
 		break;
 	default:
@@ -1126,6 +1125,9 @@
 
 	IXGBE_WRITE_FLUSH(hw);
 
+	/* configure adapter flags only when HW is actually configured */
+	adapter->flags = aflags;
+
 	/* clear TX/RX time stamp registers, just to be sure */
 	ixgbe_ptp_clear_tx_timestamp(adapter);
 	IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
diff --git a/kernel/drivers/net/ethernet/marvell/mvneta.c b/kernel/drivers/net/ethernet/marvell/mvneta.c
index f5567d4..3656a39 100644
--- a/kernel/drivers/net/ethernet/marvell/mvneta.c
+++ b/kernel/drivers/net/ethernet/marvell/mvneta.c
@@ -1471,7 +1471,7 @@
 			 */
 			if (txq_number == 1)
 				txq_map = (cpu == pp->rxq_def) ?
-					MVNETA_CPU_TXQ_ACCESS(1) : 0;
+					MVNETA_CPU_TXQ_ACCESS(0) : 0;
 
 		} else {
 			txq_map = MVNETA_CPU_TXQ_ACCESS_ALL_MASK;
@@ -4165,7 +4165,7 @@
 		 */
 		if (txq_number == 1)
 			txq_map = (cpu == elected_cpu) ?
-				MVNETA_CPU_TXQ_ACCESS(1) : 0;
+				MVNETA_CPU_TXQ_ACCESS(0) : 0;
 		else
 			txq_map = mvreg_read(pp, MVNETA_CPU_MAP(cpu)) &
 				MVNETA_CPU_TXQ_ACCESS_ALL_MASK;
diff --git a/kernel/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/kernel/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 68c5ed8..e0e6275 100644
--- a/kernel/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/kernel/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -5201,6 +5201,11 @@
 		break;
 	case ETHTOOL_GRXCLSRLALL:
 		for (i = 0; i < MVPP2_N_RFS_ENTRIES_PER_FLOW; i++) {
+			if (loc == info->rule_cnt) {
+				ret = -EMSGSIZE;
+				break;
+			}
+
 			if (port->rfs_rules[i])
 				rules[loc++] = i;
 		}
diff --git a/kernel/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/kernel/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
index fc27a40..c0a0a31 100644
--- a/kernel/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+++ b/kernel/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
@@ -145,6 +145,16 @@
 	return cgx->cgx_id;
 }
 
+u8 cgx_lmac_get_p2x(int cgx_id, int lmac_id)
+{
+	struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
+	u64 cfg;
+
+	cfg = cgx_read(cgx_dev, lmac_id, CGXX_CMRX_CFG);
+
+	return (cfg & CMR_P2X_SEL_MASK) >> CMR_P2X_SEL_SHIFT;
+}
+
 /* Ensure the required lock for event queue(where asynchronous events are
  * posted) is acquired before calling this API. Else an asynchronous event(with
  * latest link status) can reach the destination before this function returns
@@ -340,9 +350,9 @@
 
 	cfg = cgx_read(cgx, lmac_id, CGXX_CMRX_CFG);
 	if (enable)
-		cfg |= CMR_EN | DATA_PKT_RX_EN | DATA_PKT_TX_EN;
+		cfg |= DATA_PKT_RX_EN | DATA_PKT_TX_EN;
 	else
-		cfg &= ~(CMR_EN | DATA_PKT_RX_EN | DATA_PKT_TX_EN);
+		cfg &= ~(DATA_PKT_RX_EN | DATA_PKT_TX_EN);
 	cgx_write(cgx, lmac_id, CGXX_CMRX_CFG, cfg);
 	return 0;
 }
@@ -814,8 +824,7 @@
 	minor_ver = FIELD_GET(RESP_MINOR_VER, resp);
 	dev_dbg(dev, "Firmware command interface version = %d.%d\n",
 		major_ver, minor_ver);
-	if (major_ver != CGX_FIRMWARE_MAJOR_VER ||
-	    minor_ver != CGX_FIRMWARE_MINOR_VER)
+	if (major_ver != CGX_FIRMWARE_MAJOR_VER)
 		return -EIO;
 	else
 		return 0;
diff --git a/kernel/drivers/net/ethernet/marvell/octeontx2/af/cgx.h b/kernel/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
index 27ca329..e176a6c 100644
--- a/kernel/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
+++ b/kernel/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
@@ -27,7 +27,10 @@
 
 /* Registers */
 #define CGXX_CMRX_CFG			0x00
-#define CMR_EN				BIT_ULL(55)
+#define CMR_P2X_SEL_MASK		GENMASK_ULL(61, 59)
+#define CMR_P2X_SEL_SHIFT		59ULL
+#define CMR_P2X_SEL_NIX0		1ULL
+#define CMR_P2X_SEL_NIX1		2ULL
 #define DATA_PKT_TX_EN			BIT_ULL(53)
 #define DATA_PKT_RX_EN			BIT_ULL(54)
 #define CGX_LMAC_TYPE_SHIFT		40
@@ -142,5 +145,6 @@
 int cgx_lmac_set_pause_frm(void *cgxd, int lmac_id,
 			   u8 tx_pause, u8 rx_pause);
 void cgx_lmac_ptp_config(void *cgxd, int lmac_id, bool enable);
+u8 cgx_lmac_get_p2x(int cgx_id, int lmac_id);
 
 #endif /* CGX_H */
diff --git a/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
index c266524..acbc670 100644
--- a/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+++ b/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
@@ -316,30 +316,35 @@
 
 	block->fn_map[lf] = attach ? pcifunc : 0;
 
-	switch (block->type) {
-	case BLKTYPE_NPA:
+	switch (block->addr) {
+	case BLKADDR_NPA:
 		pfvf->npalf = attach ? true : false;
 		num_lfs = pfvf->npalf;
 		break;
-	case BLKTYPE_NIX:
+	case BLKADDR_NIX0:
+	case BLKADDR_NIX1:
 		pfvf->nixlf = attach ? true : false;
 		num_lfs = pfvf->nixlf;
 		break;
-	case BLKTYPE_SSO:
+	case BLKADDR_SSO:
 		attach ? pfvf->sso++ : pfvf->sso--;
 		num_lfs = pfvf->sso;
 		break;
-	case BLKTYPE_SSOW:
+	case BLKADDR_SSOW:
 		attach ? pfvf->ssow++ : pfvf->ssow--;
 		num_lfs = pfvf->ssow;
 		break;
-	case BLKTYPE_TIM:
+	case BLKADDR_TIM:
 		attach ? pfvf->timlfs++ : pfvf->timlfs--;
 		num_lfs = pfvf->timlfs;
 		break;
-	case BLKTYPE_CPT:
+	case BLKADDR_CPT0:
 		attach ? pfvf->cptlfs++ : pfvf->cptlfs--;
 		num_lfs = pfvf->cptlfs;
+		break;
+	case BLKADDR_CPT1:
+		attach ? pfvf->cpt1_lfs++ : pfvf->cpt1_lfs--;
+		num_lfs = pfvf->cpt1_lfs;
 		break;
 	}
 
@@ -1035,7 +1040,30 @@
 /* Get current count of a RVU block's LF/slots
  * provisioned to a given RVU func.
  */
-static u16 rvu_get_rsrc_mapcount(struct rvu_pfvf *pfvf, int blktype)
+u16 rvu_get_rsrc_mapcount(struct rvu_pfvf *pfvf, int blkaddr)
+{
+	switch (blkaddr) {
+	case BLKADDR_NPA:
+		return pfvf->npalf ? 1 : 0;
+	case BLKADDR_NIX0:
+	case BLKADDR_NIX1:
+		return pfvf->nixlf ? 1 : 0;
+	case BLKADDR_SSO:
+		return pfvf->sso;
+	case BLKADDR_SSOW:
+		return pfvf->ssow;
+	case BLKADDR_TIM:
+		return pfvf->timlfs;
+	case BLKADDR_CPT0:
+		return pfvf->cptlfs;
+	case BLKADDR_CPT1:
+		return pfvf->cpt1_lfs;
+	}
+	return 0;
+}
+
+/* Return true if LFs of block type are attached to pcifunc */
+static bool is_blktype_attached(struct rvu_pfvf *pfvf, int blktype)
 {
 	switch (blktype) {
 	case BLKTYPE_NPA:
@@ -1043,15 +1071,16 @@
 	case BLKTYPE_NIX:
 		return pfvf->nixlf ? 1 : 0;
 	case BLKTYPE_SSO:
-		return pfvf->sso;
+		return !!pfvf->sso;
 	case BLKTYPE_SSOW:
-		return pfvf->ssow;
+		return !!pfvf->ssow;
 	case BLKTYPE_TIM:
-		return pfvf->timlfs;
+		return !!pfvf->timlfs;
 	case BLKTYPE_CPT:
-		return pfvf->cptlfs;
+		return pfvf->cptlfs || pfvf->cpt1_lfs;
 	}
-	return 0;
+
+	return false;
 }
 
 bool is_pffunc_map_valid(struct rvu *rvu, u16 pcifunc, int blktype)
@@ -1064,7 +1093,7 @@
 	pfvf = rvu_get_pfvf(rvu, pcifunc);
 
 	/* Check if this PFFUNC has a LF of type blktype attached */
-	if (!rvu_get_rsrc_mapcount(pfvf, blktype))
+	if (!is_blktype_attached(pfvf, blktype))
 		return false;
 
 	return true;
@@ -1105,7 +1134,7 @@
 
 	block = &hw->block[blkaddr];
 
-	num_lfs = rvu_get_rsrc_mapcount(pfvf, block->type);
+	num_lfs = rvu_get_rsrc_mapcount(pfvf, block->addr);
 	if (!num_lfs)
 		return;
 
@@ -1179,6 +1208,58 @@
 	return rvu_detach_rsrcs(rvu, detach, detach->hdr.pcifunc);
 }
 
+static int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc)
+{
+	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+	int blkaddr = BLKADDR_NIX0, vf;
+	struct rvu_pfvf *pf;
+
+	/* All CGX mapped PFs are set with assigned NIX block during init */
+	if (is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc))) {
+		pf = rvu_get_pfvf(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK);
+		blkaddr = pf->nix_blkaddr;
+	} else if (is_afvf(pcifunc)) {
+		vf = pcifunc - 1;
+		/* Assign NIX based on VF number. All even numbered VFs get
+		 * NIX0 and odd numbered gets NIX1
+		 */
+		blkaddr = (vf & 1) ? BLKADDR_NIX1 : BLKADDR_NIX0;
+		/* NIX1 is not present on all silicons */
+		if (!is_block_implemented(rvu->hw, BLKADDR_NIX1))
+			blkaddr = BLKADDR_NIX0;
+	}
+
+	switch (blkaddr) {
+	case BLKADDR_NIX1:
+		pfvf->nix_blkaddr = BLKADDR_NIX1;
+		break;
+	case BLKADDR_NIX0:
+	default:
+		pfvf->nix_blkaddr = BLKADDR_NIX0;
+		break;
+	}
+
+	return pfvf->nix_blkaddr;
+}
+
+static int rvu_get_attach_blkaddr(struct rvu *rvu, int blktype, u16 pcifunc)
+{
+	int blkaddr;
+
+	switch (blktype) {
+	case BLKTYPE_NIX:
+		blkaddr = rvu_get_nix_blkaddr(rvu, pcifunc);
+		break;
+	default:
+		return rvu_get_blkaddr(rvu, blktype, 0);
+	};
+
+	if (is_block_implemented(rvu->hw, blkaddr))
+		return blkaddr;
+
+	return -ENODEV;
+}
+
 static void rvu_attach_block(struct rvu *rvu, int pcifunc,
 			     int blktype, int num_lfs)
 {
@@ -1192,7 +1273,7 @@
 	if (!num_lfs)
 		return;
 
-	blkaddr = rvu_get_blkaddr(rvu, blktype, 0);
+	blkaddr = rvu_get_attach_blkaddr(rvu, blktype, pcifunc);
 	if (blkaddr < 0)
 		return;
 
@@ -1221,12 +1302,12 @@
 				       struct rsrc_attach *req, u16 pcifunc)
 {
 	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+	int free_lfs, mappedlfs, blkaddr;
 	struct rvu_hwinfo *hw = rvu->hw;
 	struct rvu_block *block;
-	int free_lfs, mappedlfs;
 
 	/* Only one NPA LF can be attached */
-	if (req->npalf && !rvu_get_rsrc_mapcount(pfvf, BLKTYPE_NPA)) {
+	if (req->npalf && !is_blktype_attached(pfvf, BLKTYPE_NPA)) {
 		block = &hw->block[BLKADDR_NPA];
 		free_lfs = rvu_rsrc_free_count(&block->lf);
 		if (!free_lfs)
@@ -1239,8 +1320,11 @@
 	}
 
 	/* Only one NIX LF can be attached */
-	if (req->nixlf && !rvu_get_rsrc_mapcount(pfvf, BLKTYPE_NIX)) {
-		block = &hw->block[BLKADDR_NIX0];
+	if (req->nixlf && !is_blktype_attached(pfvf, BLKTYPE_NIX)) {
+		blkaddr = rvu_get_attach_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
+		if (blkaddr < 0)
+			return blkaddr;
+		block = &hw->block[blkaddr];
 		free_lfs = rvu_rsrc_free_count(&block->lf);
 		if (!free_lfs)
 			goto fail;
@@ -1260,7 +1344,7 @@
 				 pcifunc, req->sso, block->lf.max);
 			return -EINVAL;
 		}
-		mappedlfs = rvu_get_rsrc_mapcount(pfvf, block->type);
+		mappedlfs = rvu_get_rsrc_mapcount(pfvf, block->addr);
 		free_lfs = rvu_rsrc_free_count(&block->lf);
 		/* Check if additional resources are available */
 		if (req->sso > mappedlfs &&
@@ -1276,7 +1360,7 @@
 				 pcifunc, req->sso, block->lf.max);
 			return -EINVAL;
 		}
-		mappedlfs = rvu_get_rsrc_mapcount(pfvf, block->type);
+		mappedlfs = rvu_get_rsrc_mapcount(pfvf, block->addr);
 		free_lfs = rvu_rsrc_free_count(&block->lf);
 		if (req->ssow > mappedlfs &&
 		    ((req->ssow - mappedlfs) > free_lfs))
@@ -1291,7 +1375,7 @@
 				 pcifunc, req->timlfs, block->lf.max);
 			return -EINVAL;
 		}
-		mappedlfs = rvu_get_rsrc_mapcount(pfvf, block->type);
+		mappedlfs = rvu_get_rsrc_mapcount(pfvf, block->addr);
 		free_lfs = rvu_rsrc_free_count(&block->lf);
 		if (req->timlfs > mappedlfs &&
 		    ((req->timlfs - mappedlfs) > free_lfs))
@@ -1306,7 +1390,7 @@
 				 pcifunc, req->cptlfs, block->lf.max);
 			return -EINVAL;
 		}
-		mappedlfs = rvu_get_rsrc_mapcount(pfvf, block->type);
+		mappedlfs = rvu_get_rsrc_mapcount(pfvf, block->addr);
 		free_lfs = rvu_rsrc_free_count(&block->lf);
 		if (req->cptlfs > mappedlfs &&
 		    ((req->cptlfs - mappedlfs) > free_lfs))
@@ -1942,7 +2026,7 @@
 
 	block = &rvu->hw->block[blkaddr];
 	num_lfs = rvu_get_rsrc_mapcount(rvu_get_pfvf(rvu, pcifunc),
-					block->type);
+					block->addr);
 	if (!num_lfs)
 		return;
 	for (slot = 0; slot < num_lfs; slot++) {
diff --git a/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
index 90eed31..ec9a291 100644
--- a/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ b/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -20,6 +20,7 @@
 #define	PCI_DEVID_OCTEONTX2_RVU_AF		0xA065
 
 /* Subsystem Device ID */
+#define PCI_SUBSYS_DEVID_98XX                  0xB100
 #define PCI_SUBSYS_DEVID_96XX                  0xB200
 
 /* PCI BAR nos */
@@ -137,6 +138,7 @@
 	u16		ssow;
 	u16		cptlfs;
 	u16		timlfs;
+	u16		cpt1_lfs;
 	u8		cgx_lmac;
 
 	/* Block LF's MSIX vector info */
@@ -182,6 +184,8 @@
 
 	bool	cgx_in_use; /* this PF/VF using CGX? */
 	int	cgx_users;  /* number of cgx users - used only by PFs */
+
+	u8	nix_blkaddr; /* BLKADDR_NIX0/1 assigned to this PF */
 };
 
 struct nix_txsch {
@@ -400,6 +404,16 @@
 		(pdev->subsystem_device == PCI_SUBSYS_DEVID_96XX);
 }
 
+static inline bool is_rvu_supports_nix1(struct rvu *rvu)
+{
+	struct pci_dev *pdev = rvu->pdev;
+
+	if (pdev->subsystem_device == PCI_SUBSYS_DEVID_98XX)
+		return true;
+
+	return false;
+}
+
 /* Function Prototypes
  * RVU
  */
@@ -420,6 +434,7 @@
 int rvu_rsrc_free_count(struct rsrc_bmap *rsrc);
 int rvu_alloc_rsrc_contig(struct rsrc_bmap *rsrc, int nrsrc);
 bool rvu_rsrc_check_contig(struct rsrc_bmap *rsrc, int nrsrc);
+u16 rvu_get_rsrc_mapcount(struct rvu_pfvf *pfvf, int blkaddr);
 int rvu_get_pf(u16 pcifunc);
 struct rvu_pfvf *rvu_get_pfvf(struct rvu *rvu, int pcifunc);
 void rvu_get_pf_numvfs(struct rvu *rvu, int pf, int *numvfs, int *hwvf);
diff --git a/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
index f4ecc75..83743e1 100644
--- a/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+++ b/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
@@ -74,6 +74,20 @@
 	return rvu->cgx_idmap[cgx_id];
 }
 
+/* Based on P2X connectivity find mapped NIX block for a PF */
+static void rvu_map_cgx_nix_block(struct rvu *rvu, int pf,
+				  int cgx_id, int lmac_id)
+{
+	struct rvu_pfvf *pfvf = &rvu->pf[pf];
+	u8 p2x;
+
+	p2x = cgx_lmac_get_p2x(cgx_id, lmac_id);
+	/* Firmware sets P2X_SELECT as either NIX0 or NIX1 */
+	pfvf->nix_blkaddr = BLKADDR_NIX0;
+	if (is_rvu_supports_nix1(rvu) && p2x == CMR_P2X_SEL_NIX1)
+		pfvf->nix_blkaddr = BLKADDR_NIX1;
+}
+
 static int rvu_map_cgx_lmac_pf(struct rvu *rvu)
 {
 	struct npc_pkind *pkind = &rvu->hw->pkind;
@@ -117,6 +131,7 @@
 			rvu->cgxlmac2pf_map[CGX_OFFSET(cgx) + lmac] = 1 << pf;
 			free_pkind = rvu_alloc_rsrc(&pkind->rsrc);
 			pkind->pfchan_map[free_pkind] = ((pf) & 0x3F) << 16;
+			rvu_map_cgx_nix_block(rvu, pf, cgx, lmac);
 			rvu->cgx_mapped_pfs++;
 		}
 	}
diff --git a/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index f6a3cf3..e549b09 100644
--- a/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/kernel/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -187,8 +187,8 @@
 static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf)
 {
 	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+	int pkind, pf, vf, lbkid;
 	u8 cgx_id, lmac_id;
-	int pkind, pf, vf;
 	int err;
 
 	pf = rvu_get_pf(pcifunc);
@@ -221,13 +221,24 @@
 	case NIX_INTF_TYPE_LBK:
 		vf = (pcifunc & RVU_PFVF_FUNC_MASK) - 1;
 
+		/* If NIX1 block is present on the silicon then NIXes are
+		 * assigned alternatively for lbk interfaces. NIX0 should
+		 * send packets on lbk link 1 channels and NIX1 should send
+		 * on lbk link 0 channels for the communication between
+		 * NIX0 and NIX1.
+		 */
+		lbkid = 0;
+		if (rvu->hw->lbk_links > 1)
+			lbkid = vf & 0x1 ? 0 : 1;
+
 		/* Note that AF's VFs work in pairs and talk over consecutive
 		 * loopback channels.Therefore if odd number of AF VFs are
 		 * enabled then the last VF remains with no pair.
 		 */
-		pfvf->rx_chan_base = NIX_CHAN_LBK_CHX(0, vf);
-		pfvf->tx_chan_base = vf & 0x1 ? NIX_CHAN_LBK_CHX(0, vf - 1) :
-						NIX_CHAN_LBK_CHX(0, vf + 1);
+		pfvf->rx_chan_base = NIX_CHAN_LBK_CHX(lbkid, vf);
+		pfvf->tx_chan_base = vf & 0x1 ?
+					NIX_CHAN_LBK_CHX(lbkid, vf - 1) :
+					NIX_CHAN_LBK_CHX(lbkid, vf + 1);
 		pfvf->rx_chan_cnt = 1;
 		pfvf->tx_chan_cnt = 1;
 		rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf,
@@ -1374,7 +1385,8 @@
 		free_cnt = rvu_rsrc_free_count(&txsch->schq);
 	}
 
-	if (free_cnt < req_schq || req_schq > MAX_TXSCHQ_PER_FUNC)
+	if (free_cnt < req_schq || req->schq[lvl] > MAX_TXSCHQ_PER_FUNC ||
+	    req->schq_contig[lvl] > MAX_TXSCHQ_PER_FUNC)
 		return NIX_AF_ERR_TLX_ALLOC_FAIL;
 
 	/* If contiguous queues are needed, check for availability */
@@ -2864,9 +2876,10 @@
 	if (link < 0)
 		return NIX_AF_ERR_RX_LINK_INVALID;
 
-	nix_find_link_frs(rvu, req, pcifunc);
 
 linkcfg:
+	nix_find_link_frs(rvu, req, pcifunc);
+
 	cfg = rvu_read64(rvu, blkaddr, NIX_AF_RX_LINKX_CFG(link));
 	cfg = (cfg & ~(0xFFFFULL << 16)) | ((u64)req->maxlen << 16);
 	if (req->update_minlen)
@@ -3157,7 +3170,7 @@
 	hw->cgx = (cfg >> 12) & 0xF;
 	hw->lmac_per_cgx = (cfg >> 8) & 0xF;
 	hw->cgx_links = hw->cgx * hw->lmac_per_cgx;
-	hw->lbk_links = 1;
+	hw->lbk_links = (cfg >> 24) & 0xF;
 	hw->sdp_links = 1;
 
 	/* Initialize admin queue */
diff --git a/kernel/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/kernel/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
index 161174b..000dd89 100644
--- a/kernel/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+++ b/kernel/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
@@ -1311,8 +1311,9 @@
 	if (err)
 		goto err_free_npa_lf;
 
-	/* Enable backpressure */
-	otx2_nix_config_bp(pf, true);
+	/* Enable backpressure for CGX mapped PF/VFs */
+	if (!is_otx2_lbkvf(pf->pdev))
+		otx2_nix_config_bp(pf, true);
 
 	/* Init Auras and pools used by NIX RQ, for free buffer ptrs */
 	err = otx2_rq_aura_pool_init(pf);
@@ -1589,11 +1590,20 @@
 	otx2_config_pause_frm(pf);
 
 	err = otx2_rxtx_enable(pf, true);
-	if (err)
+	/* If a mbox communication error happens at this point then interface
+	 * will end up in a state such that it is in down state but hardware
+	 * mcam entries are enabled to receive the packets. Hence disable the
+	 * packet I/O.
+	 */
+	if (err == EIO)
+		goto err_disable_rxtx;
+	else if (err)
 		goto err_tx_stop_queues;
 
 	return 0;
 
+err_disable_rxtx:
+	otx2_rxtx_enable(pf, false);
 err_tx_stop_queues:
 	netif_tx_stop_all_queues(netdev);
 	netif_carrier_off(netdev);
diff --git a/kernel/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/kernel/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
index d5d7a2f..a0a6dad 100644
--- a/kernel/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+++ b/kernel/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
@@ -526,9 +526,7 @@
 				htons(ext->lso_sb - skb_network_offset(skb));
 		} else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) {
 			ext->lso_format = pfvf->hw.lso_tsov6_idx;
-
-			ipv6_hdr(skb)->payload_len =
-				htons(ext->lso_sb - skb_network_offset(skb));
+			ipv6_hdr(skb)->payload_len = htons(tcp_hdrlen(skb));
 		} else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) {
 			__be16 l3_proto = vlan_get_protocol(skb);
 			struct udphdr *udph = udp_hdr(skb);
diff --git a/kernel/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/kernel/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
index 67fabf2..5310b71 100644
--- a/kernel/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
+++ b/kernel/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
@@ -542,7 +542,7 @@
 
 	err = otx2vf_realloc_msix_vectors(vf);
 	if (err)
-		goto err_mbox_destroy;
+		goto err_detach_rsrc;
 
 	err = otx2_set_real_num_queues(netdev, qcount, qcount);
 	if (err)
diff --git a/kernel/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/kernel/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 217dc67..aa9e616 100644
--- a/kernel/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/kernel/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -354,7 +354,8 @@
 	mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
 	mcr_new = mcr_cur;
 	mcr_new |= MAC_MCR_MAX_RX_1536 | MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE |
-		   MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK;
+		   MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK |
+		   MAC_MCR_RX_FIFO_CLR_DIS;
 
 	/* Only update control register when needed! */
 	if (mcr_new != mcr_cur)
@@ -2012,6 +2013,9 @@
 	int i;
 
 	for (i = 0; i < MTK_MAX_LRO_IP_CNT; i++) {
+		if (cnt == cmd->rule_cnt)
+			return -EMSGSIZE;
+
 		if (mac->hwlro_ip[i]) {
 			rule_locs[cnt] = i;
 			cnt++;
diff --git a/kernel/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/kernel/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 54a7cd9..0ca3223 100644
--- a/kernel/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/kernel/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -339,6 +339,7 @@
 #define MAC_MCR_FORCE_MODE	BIT(15)
 #define MAC_MCR_TX_EN		BIT(14)
 #define MAC_MCR_RX_EN		BIT(13)
+#define MAC_MCR_RX_FIFO_CLR_DIS	BIT(12)
 #define MAC_MCR_BACKOFF_EN	BIT(9)
 #define MAC_MCR_BACKPR_EN	BIT(8)
 #define MAC_MCR_FORCE_RX_FC	BIT(5)
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
index f800e1c..5273644 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
@@ -64,6 +64,7 @@
 			MLX5_GET(mtrc_cap, out, num_string_trace);
 	tracer->str_db.num_string_db = MLX5_GET(mtrc_cap, out, num_string_db);
 	tracer->owner = !!MLX5_GET(mtrc_cap, out, trace_owner);
+	tracer->str_db.loaded = false;
 
 	for (i = 0; i < tracer->str_db.num_string_db; i++) {
 		mtrc_cap_sp = MLX5_ADDR_OF(mtrc_cap, out, string_db_param[i]);
@@ -482,7 +483,7 @@
 				(u64)timestamp_low;
 		break;
 	default:
-		if (tracer_event->event_id >= tracer->str_db.first_string_trace ||
+		if (tracer_event->event_id >= tracer->str_db.first_string_trace &&
 		    tracer_event->event_id <= tracer->str_db.first_string_trace +
 					      tracer->str_db.num_string_trace) {
 			tracer_event->type = TRACER_EVENT_TYPE_STRING;
@@ -602,7 +603,7 @@
 	} else {
 		cur_string = mlx5_tracer_message_get(tracer, tracer_event);
 		if (!cur_string) {
-			pr_debug("%s Got string event for unknown string tdsm: %d\n",
+			pr_debug("%s Got string event for unknown string tmsn: %d\n",
 				 __func__, tracer_event->string_event.tmsn);
 			return -1;
 		}
@@ -756,6 +757,7 @@
 	if (err)
 		mlx5_core_warn(dev, "FWTracer: Failed to set tracer configurations %d\n", err);
 
+	tracer->buff.consumer_index = 0;
 	return err;
 }
 
@@ -820,7 +822,6 @@
 	mlx5_core_dbg(tracer->dev, "FWTracer: ownership changed, current=(%d)\n", tracer->owner);
 	if (tracer->owner) {
 		tracer->owner = false;
-		tracer->buff.consumer_index = 0;
 		return;
 	}
 
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c
index 038a0f1..e44281a 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c
@@ -88,6 +88,8 @@
 	struct udphdr *udp = (struct udphdr *)(buf);
 	struct vxlanhdr *vxh;
 
+	if (tun_key->tun_flags & TUNNEL_VXLAN_OPT)
+		return -EOPNOTSUPP;
 	vxh = (struct vxlanhdr *)((char *)udp + sizeof(struct udphdr));
 	*ip_proto = IPPROTO_UDP;
 
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c
index e51f60b..2da90f6 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c
@@ -194,6 +194,7 @@
 	in = kvzalloc(inlen, GFP_KERNEL);
 	if  (!in || !ft->g) {
 		kfree(ft->g);
+		ft->g = NULL;
 		kvfree(in);
 		return -ENOMEM;
 	}
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
index a9b4560..76ef8a0 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
@@ -121,7 +121,9 @@
 
 	trailer_len = alen + plen + 2;
 
-	pskb_trim(skb, skb->len - trailer_len);
+	ret = pskb_trim(skb, skb->len - trailer_len);
+	if (unlikely(ret))
+		return ret;
 	if (skb->protocol == htons(ETH_P_IP)) {
 		ipv4hdr->tot_len = htons(ntohs(ipv4hdr->tot_len) - trailer_len);
 		ip_send_check(ipv4hdr);
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
index 7c0ae7c..c25fb0c 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
@@ -117,12 +117,14 @@
 	if (!MLX5_CAP_GEN(priv->mdev, ets))
 		return -EOPNOTSUPP;
 
-	ets->ets_cap = mlx5_max_tc(priv->mdev) + 1;
-	for (i = 0; i < ets->ets_cap; i++) {
+	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
 		err = mlx5_query_port_prio_tc(mdev, i, &ets->prio_tc[i]);
 		if (err)
 			return err;
+	}
 
+	ets->ets_cap = mlx5_max_tc(priv->mdev) + 1;
+	for (i = 0; i < ets->ets_cap; i++) {
 		err = mlx5_query_port_tc_group(mdev, i, &tc_group[i]);
 		if (err)
 			return err;
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index cfc3bfc..5673a41 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -992,7 +992,7 @@
 	sq->channel   = c;
 	sq->uar_map   = mdev->mlx5e_res.bfreg.map;
 	sq->min_inline_mode = params->tx_min_inline_mode;
-	sq->hw_mtu    = MLX5E_SW2HW_MTU(params, params->sw_mtu);
+	sq->hw_mtu    = MLX5E_SW2HW_MTU(params, params->sw_mtu) - ETH_FCS_LEN;
 	sq->xsk_pool  = xsk_pool;
 
 	sq->stats = sq->xsk_pool ?
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index f1bf7f6..c6a81a5 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -1334,7 +1334,8 @@
 	uplink_priv = &rpriv->uplink_priv;
 
 	mutex_lock(&uplink_priv->unready_flows_lock);
-	unready_flow_del(flow);
+	if (flow_flag_test(flow, NOT_READY))
+		unready_flow_del(flow);
 	mutex_unlock(&uplink_priv->unready_flows_lock);
 }
 
@@ -1344,9 +1345,9 @@
 		      struct netlink_ext_ack *extack)
 {
 	struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
-	struct net_device *out_dev, *encap_dev = NULL;
 	struct mlx5e_tc_flow_parse_attr *parse_attr;
 	struct mlx5_flow_attr *attr = flow->attr;
+	struct net_device *encap_dev = NULL;
 	struct mlx5_esw_flow_attr *esw_attr;
 	struct mlx5_fc *counter = NULL;
 	struct mlx5e_rep_priv *rpriv;
@@ -1391,16 +1392,22 @@
 	esw_attr = attr->esw_attr;
 
 	for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) {
+		struct net_device *out_dev;
 		int mirred_ifindex;
 
 		if (!(esw_attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP))
 			continue;
 
 		mirred_ifindex = parse_attr->mirred_ifindex[out_index];
-		out_dev = __dev_get_by_index(dev_net(priv->netdev),
-					     mirred_ifindex);
+		out_dev = dev_get_by_index(dev_net(priv->netdev), mirred_ifindex);
+		if (!out_dev) {
+			NL_SET_ERR_MSG_MOD(extack, "Requested mirred device not found");
+			err = -ENODEV;
+			return err;
+		}
 		err = mlx5e_attach_encap(priv, flow, out_dev, out_index,
 					 extack, &encap_dev, &encap_valid);
+		dev_put(out_dev);
 		if (err)
 			return err;
 
@@ -1469,8 +1476,7 @@
 
 	mlx5e_put_flow_tunnel_id(flow);
 
-	if (flow_flag_test(flow, NOT_READY))
-		remove_unready_flow(flow);
+	remove_unready_flow(flow);
 
 	if (mlx5e_is_offloaded_flow(flow)) {
 		if (flow_flag_test(flow, SLOW))
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c
index d586867..53ac238 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c
@@ -137,20 +137,22 @@
 	for (i = 0; i < c->num_tc; i++)
 		busy |= mlx5e_poll_tx_cq(&c->sq[i].cq, budget);
 
+	/* budget=0 means we may be in IRQ context, do as little as possible */
+	if (unlikely(!budget))
+		goto out;
+
 	busy |= mlx5e_poll_xdpsq_cq(&c->xdpsq.cq);
 
 	if (c->xdp)
 		busy |= mlx5e_poll_xdpsq_cq(&c->rq_xdpsq.cq);
 
-	if (likely(budget)) { /* budget=0 means: don't poll rx rings */
-		if (xsk_open)
-			work_done = mlx5e_poll_rx_cq(&xskrq->cq, budget);
+	if (xsk_open)
+		work_done = mlx5e_poll_rx_cq(&xskrq->cq, budget);
 
-		if (likely(budget - work_done))
-			work_done += mlx5e_poll_rx_cq(&rq->cq, budget - work_done);
+	if (likely(budget - work_done))
+		work_done += mlx5e_poll_rx_cq(&rq->cq, budget - work_done);
 
-		busy |= work_done == budget;
-	}
+	busy |= work_done == budget;
 
 	mlx5e_poll_ico_cq(&c->icosq.cq);
 	if (mlx5e_poll_ico_cq(&c->async_icosq.cq))
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c
index 548c005..90a1023 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c
@@ -301,8 +301,7 @@
 
 	if (WARN_ON_ONCE(IS_ERR(vport))) {
 		esw_warn(esw->dev, "vport(%d) invalid!\n", vport_num);
-		err = PTR_ERR(vport);
-		goto out;
+		return PTR_ERR(vport);
 	}
 
 	esw_acl_ingress_ofld_rules_destroy(esw, vport);
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index 78cc6f0..3ae082c 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -1339,6 +1339,7 @@
 	 */
 	esw_vport_change_handle_locked(vport);
 	vport->enabled_events = 0;
+	esw_apply_vport_rx_mode(esw, vport, false, false);
 	esw_vport_cleanup(esw, vport);
 	esw->enabled_vports--;
 
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
index 4bdccef..4e8e379 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
@@ -802,7 +802,7 @@
 	struct fs_node *iter = list_entry(start, struct fs_node, list);
 	struct mlx5_flow_table *ft = NULL;
 
-	if (!root || root->type == FS_TYPE_PRIO_CHAINS)
+	if (!root)
 		return NULL;
 
 	list_for_each_advance_continue(iter, &root->children, reverse) {
@@ -818,20 +818,42 @@
 	return ft;
 }
 
-/* If reverse is false then return the first flow table in next priority of
- * prio in the tree, else return the last flow table in the previous priority
- * of prio in the tree.
- */
-static struct mlx5_flow_table *find_closest_ft(struct fs_prio *prio, bool reverse)
+static struct fs_node *find_prio_chains_parent(struct fs_node *parent,
+					       struct fs_node **child)
 {
+	struct fs_node *node = NULL;
+
+	while (parent && parent->type != FS_TYPE_PRIO_CHAINS) {
+		node = parent;
+		parent = parent->parent;
+	}
+
+	if (child)
+		*child = node;
+
+	return parent;
+}
+
+/* If reverse is false then return the first flow table next to the passed node
+ * in the tree, else return the last flow table before the node in the tree.
+ * If skip is true, skip the flow tables in the same prio_chains prio.
+ */
+static struct mlx5_flow_table *find_closest_ft(struct fs_node *node, bool reverse,
+					       bool skip)
+{
+	struct fs_node *prio_chains_parent = NULL;
 	struct mlx5_flow_table *ft = NULL;
 	struct fs_node *curr_node;
 	struct fs_node *parent;
 
-	parent = prio->node.parent;
-	curr_node = &prio->node;
+	if (skip)
+		prio_chains_parent = find_prio_chains_parent(node, NULL);
+	parent = node->parent;
+	curr_node = node;
 	while (!ft && parent) {
-		ft = find_closest_ft_recursive(parent, &curr_node->list, reverse);
+		if (parent != prio_chains_parent)
+			ft = find_closest_ft_recursive(parent, &curr_node->list,
+						       reverse);
 		curr_node = parent;
 		parent = curr_node->parent;
 	}
@@ -839,15 +861,15 @@
 }
 
 /* Assuming all the tree is locked by mutex chain lock */
-static struct mlx5_flow_table *find_next_chained_ft(struct fs_prio *prio)
+static struct mlx5_flow_table *find_next_chained_ft(struct fs_node *node)
 {
-	return find_closest_ft(prio, false);
+	return find_closest_ft(node, false, true);
 }
 
 /* Assuming all the tree is locked by mutex chain lock */
-static struct mlx5_flow_table *find_prev_chained_ft(struct fs_prio *prio)
+static struct mlx5_flow_table *find_prev_chained_ft(struct fs_node *node)
 {
-	return find_closest_ft(prio, true);
+	return find_closest_ft(node, true, true);
 }
 
 static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft,
@@ -859,7 +881,7 @@
 	next_ns = flow_act->action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS;
 	fs_get_obj(prio, next_ns ? ft->ns->node.parent : ft->node.parent);
 
-	return find_next_chained_ft(prio);
+	return find_next_chained_ft(&prio->node);
 }
 
 static int connect_fts_in_prio(struct mlx5_core_dev *dev,
@@ -883,21 +905,55 @@
 	return 0;
 }
 
+static struct mlx5_flow_table *find_closet_ft_prio_chains(struct fs_node *node,
+							  struct fs_node *parent,
+							  struct fs_node **child,
+							  bool reverse)
+{
+	struct mlx5_flow_table *ft;
+
+	ft = find_closest_ft(node, reverse, false);
+
+	if (ft && parent == find_prio_chains_parent(&ft->node, child))
+		return ft;
+
+	return NULL;
+}
+
 /* Connect flow tables from previous priority of prio to ft */
 static int connect_prev_fts(struct mlx5_core_dev *dev,
 			    struct mlx5_flow_table *ft,
 			    struct fs_prio *prio)
 {
+	struct fs_node *prio_parent, *parent = NULL, *child, *node;
 	struct mlx5_flow_table *prev_ft;
+	int err = 0;
 
-	prev_ft = find_prev_chained_ft(prio);
-	if (prev_ft) {
+	prio_parent = find_prio_chains_parent(&prio->node, &child);
+
+	/* return directly if not under the first sub ns of prio_chains prio */
+	if (prio_parent && !list_is_first(&child->list, &prio_parent->children))
+		return 0;
+
+	prev_ft = find_prev_chained_ft(&prio->node);
+	while (prev_ft) {
 		struct fs_prio *prev_prio;
 
 		fs_get_obj(prev_prio, prev_ft->node.parent);
-		return connect_fts_in_prio(dev, prev_prio, ft);
+		err = connect_fts_in_prio(dev, prev_prio, ft);
+		if (err)
+			break;
+
+		if (!parent) {
+			parent = find_prio_chains_parent(&prev_prio->node, &child);
+			if (!parent)
+				break;
+		}
+
+		node = child;
+		prev_ft = find_closet_ft_prio_chains(node, parent, &child, true);
 	}
-	return 0;
+	return err;
 }
 
 static int update_root_ft_create(struct mlx5_flow_table *ft, struct fs_prio
@@ -1036,7 +1092,7 @@
 		if (err)
 			return err;
 
-		next_ft = first_ft ? first_ft : find_next_chained_ft(prio);
+		next_ft = first_ft ? first_ft : find_next_chained_ft(&prio->node);
 		err = connect_fwd_rules(dev, ft, next_ft);
 		if (err)
 			return err;
@@ -1114,7 +1170,7 @@
 	tree_init_node(&ft->node, del_hw_flow_table, del_sw_flow_table);
 	log_table_sz = ft->max_fte ? ilog2(ft->max_fte) : 0;
 	next_ft = unmanaged ? ft_attr->next_ft :
-			      find_next_chained_ft(fs_prio);
+			      find_next_chained_ft(&fs_prio->node);
 	ft->def_miss_action = ns->def_miss_action;
 	ft->ns = ns;
 	err = root->cmds->create_flow_table(root, ft, log_table_sz, next_ft);
@@ -2073,13 +2129,20 @@
 /* Assuming prio->node.children(flow tables) is sorted by level */
 static struct mlx5_flow_table *find_next_ft(struct mlx5_flow_table *ft)
 {
+	struct fs_node *prio_parent, *child;
 	struct fs_prio *prio;
 
 	fs_get_obj(prio, ft->node.parent);
 
 	if (!list_is_last(&ft->node.list, &prio->node.children))
 		return list_next_entry(ft, node.list);
-	return find_next_chained_ft(prio);
+
+	prio_parent = find_prio_chains_parent(&prio->node, &child);
+
+	if (prio_parent && list_is_first(&child->list, &prio_parent->children))
+		return find_closest_ft(&prio->node, false, false);
+
+	return find_next_chained_ft(&prio->node);
 }
 
 static int update_root_ft_destroy(struct mlx5_flow_table *ft)
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
index e29db4c..a2d9904 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
@@ -279,16 +279,11 @@
 		pci_cfg_access_lock(sdev);
 	}
 	/* PCI link toggle */
-	err = pci_read_config_word(bridge, cap + PCI_EXP_LNKCTL, &reg16);
-	if (err)
-		return err;
-	reg16 |= PCI_EXP_LNKCTL_LD;
-	err = pci_write_config_word(bridge, cap + PCI_EXP_LNKCTL, reg16);
+	err = pcie_capability_set_word(bridge, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_LD);
 	if (err)
 		return err;
 	msleep(500);
-	reg16 &= ~PCI_EXP_LNKCTL_LD;
-	err = pci_write_config_word(bridge, cap + PCI_EXP_LNKCTL, reg16);
+	err = pcie_capability_clear_word(bridge, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_LD);
 	if (err)
 		return err;
 
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/health.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/health.c
index 0c32c48..f42e118 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/health.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/health.c
@@ -618,6 +618,13 @@
 	priv = container_of(health, struct mlx5_priv, health);
 	dev = container_of(priv, struct mlx5_core_dev, priv);
 
+	mutex_lock(&dev->intf_state_mutex);
+	if (test_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags)) {
+		mlx5_core_err(dev, "health works are not permitted at this stage\n");
+		mutex_unlock(&dev->intf_state_mutex);
+		return;
+	}
+	mutex_unlock(&dev->intf_state_mutex);
 	enter_error_state(dev, false);
 	if (IS_ERR_OR_NULL(health->fw_fatal_reporter)) {
 		if (mlx5_health_try_recover(dev))
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
index cac8f08..2cf7f0f 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
@@ -166,16 +166,16 @@
 	}
 }
 
-static int mlx5i_get_speed_settings(u16 ib_link_width_oper, u16 ib_proto_oper)
+static u32 mlx5i_get_speed_settings(u16 ib_link_width_oper, u16 ib_proto_oper)
 {
 	int rate, width;
 
 	rate = mlx5_ptys_rate_enum_to_int(ib_proto_oper);
 	if (rate < 0)
-		return -EINVAL;
+		return SPEED_UNKNOWN;
 	width = mlx5_ptys_width_enum_to_int(ib_link_width_oper);
 	if (width < 0)
-		return -EINVAL;
+		return SPEED_UNKNOWN;
 
 	return rate * width;
 }
@@ -198,15 +198,12 @@
 	ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
 
 	speed = mlx5i_get_speed_settings(ib_link_width_oper, ib_proto_oper);
-	if (speed < 0)
-		return -EINVAL;
+	link_ksettings->base.speed = speed;
+	link_ksettings->base.duplex = speed == SPEED_UNKNOWN ? DUPLEX_UNKNOWN : DUPLEX_FULL;
 
-	link_ksettings->base.duplex = DUPLEX_FULL;
 	link_ksettings->base.port = PORT_OTHER;
 
 	link_ksettings->base.autoneg = AUTONEG_DISABLE;
-
-	link_ksettings->base.speed = speed;
 
 	return 0;
 }
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
index 5c6a376..0e7fd20 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
@@ -69,6 +69,10 @@
 	params->lro_en = false;
 	params->hard_mtu = MLX5_IB_GRH_BYTES + MLX5_IPOIB_HARD_LEN;
 	params->tunneled_offload_en = false;
+
+	/* CQE compression is not supported for IPoIB */
+	params->rx_cqe_compress_def = false;
+	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS, params->rx_cqe_compress_def);
 }
 
 /* Called directly after IPoIB netdevice was created to initialize SW structs */
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
index c70c1f0..80dee8c 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
@@ -89,7 +89,8 @@
 
 static u64 read_internal_timer(const struct cyclecounter *cc)
 {
-	struct mlx5_clock *clock = container_of(cc, struct mlx5_clock, cycles);
+	struct mlx5_timer *timer = container_of(cc, struct mlx5_timer, cycles);
+	struct mlx5_clock *clock = container_of(timer, struct mlx5_clock, timer);
 	struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev,
 						  clock);
 
@@ -100,6 +101,7 @@
 {
 	struct mlx5_ib_clock_info *clock_info = mdev->clock_info;
 	struct mlx5_clock *clock = &mdev->clock;
+	struct mlx5_timer *timer;
 	u32 sign;
 
 	if (!clock_info)
@@ -109,10 +111,11 @@
 	smp_store_mb(clock_info->sign,
 		     sign | MLX5_IB_CLOCK_INFO_KERNEL_UPDATING);
 
-	clock_info->cycles = clock->tc.cycle_last;
-	clock_info->mult   = clock->cycles.mult;
-	clock_info->nsec   = clock->tc.nsec;
-	clock_info->frac   = clock->tc.frac;
+	timer = &clock->timer;
+	clock_info->cycles = timer->tc.cycle_last;
+	clock_info->mult   = timer->cycles.mult;
+	clock_info->nsec   = timer->tc.nsec;
+	clock_info->frac   = timer->tc.frac;
 
 	smp_store_release(&clock_info->sign,
 			  sign + MLX5_IB_CLOCK_INFO_KERNEL_UPDATING * 2);
@@ -151,28 +154,37 @@
 {
 	struct delayed_work *dwork = to_delayed_work(work);
 	struct mlx5_core_dev *mdev;
+	struct mlx5_timer *timer;
 	struct mlx5_clock *clock;
 	unsigned long flags;
 
-	clock = container_of(dwork, struct mlx5_clock, overflow_work);
+	timer = container_of(dwork, struct mlx5_timer, overflow_work);
+	clock = container_of(timer, struct mlx5_clock, timer);
 	mdev = container_of(clock, struct mlx5_core_dev, clock);
+
+	if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
+		goto out;
+
 	write_seqlock_irqsave(&clock->lock, flags);
-	timecounter_read(&clock->tc);
+	timecounter_read(&timer->tc);
 	mlx5_update_clock_info_page(mdev);
 	write_sequnlock_irqrestore(&clock->lock, flags);
-	schedule_delayed_work(&clock->overflow_work, clock->overflow_period);
+
+out:
+	schedule_delayed_work(&timer->overflow_work, timer->overflow_period);
 }
 
 static int mlx5_ptp_settime(struct ptp_clock_info *ptp, const struct timespec64 *ts)
 {
 	struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info);
+	struct mlx5_timer *timer = &clock->timer;
 	u64 ns = timespec64_to_ns(ts);
 	struct mlx5_core_dev *mdev;
 	unsigned long flags;
 
 	mdev = container_of(clock, struct mlx5_core_dev, clock);
 	write_seqlock_irqsave(&clock->lock, flags);
-	timecounter_init(&clock->tc, &clock->cycles, ns);
+	timecounter_init(&timer->tc, &timer->cycles, ns);
 	mlx5_update_clock_info_page(mdev);
 	write_sequnlock_irqrestore(&clock->lock, flags);
 
@@ -183,6 +195,7 @@
 			     struct ptp_system_timestamp *sts)
 {
 	struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info);
+	struct mlx5_timer *timer = &clock->timer;
 	struct mlx5_core_dev *mdev;
 	unsigned long flags;
 	u64 cycles, ns;
@@ -190,7 +203,7 @@
 	mdev = container_of(clock, struct mlx5_core_dev, clock);
 	write_seqlock_irqsave(&clock->lock, flags);
 	cycles = mlx5_read_internal_timer(mdev, sts);
-	ns = timecounter_cyc2time(&clock->tc, cycles);
+	ns = timecounter_cyc2time(&timer->tc, cycles);
 	write_sequnlock_irqrestore(&clock->lock, flags);
 
 	*ts = ns_to_timespec64(ns);
@@ -201,12 +214,13 @@
 static int mlx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
 {
 	struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info);
+	struct mlx5_timer *timer = &clock->timer;
 	struct mlx5_core_dev *mdev;
 	unsigned long flags;
 
 	mdev = container_of(clock, struct mlx5_core_dev, clock);
 	write_seqlock_irqsave(&clock->lock, flags);
-	timecounter_adjtime(&clock->tc, delta);
+	timecounter_adjtime(&timer->tc, delta);
 	mlx5_update_clock_info_page(mdev);
 	write_sequnlock_irqrestore(&clock->lock, flags);
 
@@ -216,27 +230,27 @@
 static int mlx5_ptp_adjfreq(struct ptp_clock_info *ptp, s32 delta)
 {
 	struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info);
+	struct mlx5_timer *timer = &clock->timer;
 	struct mlx5_core_dev *mdev;
 	unsigned long flags;
 	int neg_adj = 0;
 	u32 diff;
 	u64 adj;
 
-
 	if (delta < 0) {
 		neg_adj = 1;
 		delta = -delta;
 	}
 
-	adj = clock->nominal_c_mult;
+	adj = timer->nominal_c_mult;
 	adj *= delta;
 	diff = div_u64(adj, 1000000000ULL);
 
 	mdev = container_of(clock, struct mlx5_core_dev, clock);
 	write_seqlock_irqsave(&clock->lock, flags);
-	timecounter_read(&clock->tc);
-	clock->cycles.mult = neg_adj ? clock->nominal_c_mult - diff :
-				       clock->nominal_c_mult + diff;
+	timecounter_read(&timer->tc);
+	timer->cycles.mult = neg_adj ? timer->nominal_c_mult - diff :
+				       timer->nominal_c_mult + diff;
 	mlx5_update_clock_info_page(mdev);
 	write_sequnlock_irqrestore(&clock->lock, flags);
 
@@ -313,6 +327,7 @@
 			container_of(ptp, struct mlx5_clock, ptp_info);
 	struct mlx5_core_dev *mdev =
 			container_of(clock, struct mlx5_core_dev, clock);
+	struct mlx5_timer *timer = &clock->timer;
 	u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0};
 	u64 nsec_now, nsec_delta, time_stamp = 0;
 	u64 cycles_now, cycles_delta;
@@ -355,10 +370,10 @@
 		ns = timespec64_to_ns(&ts);
 		cycles_now = mlx5_read_internal_timer(mdev, NULL);
 		write_seqlock_irqsave(&clock->lock, flags);
-		nsec_now = timecounter_cyc2time(&clock->tc, cycles_now);
+		nsec_now = timecounter_cyc2time(&timer->tc, cycles_now);
 		nsec_delta = ns - nsec_now;
-		cycles_delta = div64_u64(nsec_delta << clock->cycles.shift,
-					 clock->cycles.mult);
+		cycles_delta = div64_u64(nsec_delta << timer->cycles.shift,
+					 timer->cycles.mult);
 		write_sequnlock_irqrestore(&clock->lock, flags);
 		time_stamp = cycles_now + cycles_delta;
 		field_select = MLX5_MTPPS_FS_PIN_MODE |
@@ -440,7 +455,7 @@
 static const struct ptp_clock_info mlx5_ptp_clock_info = {
 	.owner		= THIS_MODULE,
 	.name		= "mlx5_ptp",
-	.max_adj	= 100000000,
+	.max_adj	= 50000000,
 	.n_alarm	= 0,
 	.n_ext_ts	= 0,
 	.n_per_out	= 0,
@@ -541,6 +556,7 @@
 			  unsigned long type, void *data)
 {
 	struct mlx5_clock *clock = mlx5_nb_cof(nb, struct mlx5_clock, pps_nb);
+	struct mlx5_timer *timer = &clock->timer;
 	struct ptp_clock_event ptp_event;
 	u64 cycles_now, cycles_delta;
 	u64 nsec_now, nsec_delta, ns;
@@ -575,10 +591,10 @@
 		ts.tv_nsec = 0;
 		ns = timespec64_to_ns(&ts);
 		write_seqlock_irqsave(&clock->lock, flags);
-		nsec_now = timecounter_cyc2time(&clock->tc, cycles_now);
+		nsec_now = timecounter_cyc2time(&timer->tc, cycles_now);
 		nsec_delta = ns - nsec_now;
-		cycles_delta = div64_u64(nsec_delta << clock->cycles.shift,
-					 clock->cycles.mult);
+		cycles_delta = div64_u64(nsec_delta << timer->cycles.shift,
+					 timer->cycles.mult);
 		clock->pps_info.start[pin] = cycles_now + cycles_delta;
 		write_sequnlock_irqrestore(&clock->lock, flags);
 		schedule_work(&clock->pps_info.out_work);
@@ -591,29 +607,32 @@
 	return NOTIFY_OK;
 }
 
-void mlx5_init_clock(struct mlx5_core_dev *mdev)
+static void mlx5_timecounter_init(struct mlx5_core_dev *mdev)
 {
 	struct mlx5_clock *clock = &mdev->clock;
-	u64 overflow_cycles;
-	u64 ns;
-	u64 frac = 0;
+	struct mlx5_timer *timer = &clock->timer;
 	u32 dev_freq;
 
 	dev_freq = MLX5_CAP_GEN(mdev, device_frequency_khz);
-	if (!dev_freq) {
-		mlx5_core_warn(mdev, "invalid device_frequency_khz, aborting HW clock init\n");
-		return;
-	}
-	seqlock_init(&clock->lock);
-	clock->cycles.read = read_internal_timer;
-	clock->cycles.shift = MLX5_CYCLES_SHIFT;
-	clock->cycles.mult = clocksource_khz2mult(dev_freq,
-						  clock->cycles.shift);
-	clock->nominal_c_mult = clock->cycles.mult;
-	clock->cycles.mask = CLOCKSOURCE_MASK(41);
+	timer->cycles.read = read_internal_timer;
+	timer->cycles.shift = MLX5_CYCLES_SHIFT;
+	timer->cycles.mult = clocksource_khz2mult(dev_freq,
+						  timer->cycles.shift);
+	timer->nominal_c_mult = timer->cycles.mult;
+	timer->cycles.mask = CLOCKSOURCE_MASK(41);
 
-	timecounter_init(&clock->tc, &clock->cycles,
+	timecounter_init(&timer->tc, &timer->cycles,
 			 ktime_to_ns(ktime_get_real()));
+}
+
+static void mlx5_init_overflow_period(struct mlx5_clock *clock)
+{
+	struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev, clock);
+	struct mlx5_ib_clock_info *clock_info = mdev->clock_info;
+	struct mlx5_timer *timer = &clock->timer;
+	u64 overflow_cycles;
+	u64 frac = 0;
+	u64 ns;
 
 	/* Calculate period in seconds to call the overflow watchdog - to make
 	 * sure counter is checked at least twice every wrap around.
@@ -622,32 +641,63 @@
 	 * multiplied by clock multiplier where the result doesn't exceed
 	 * 64bits.
 	 */
-	overflow_cycles = div64_u64(~0ULL >> 1, clock->cycles.mult);
-	overflow_cycles = min(overflow_cycles, div_u64(clock->cycles.mask, 3));
+	overflow_cycles = div64_u64(~0ULL >> 1, timer->cycles.mult);
+	overflow_cycles = min(overflow_cycles, div_u64(timer->cycles.mask, 3));
 
-	ns = cyclecounter_cyc2ns(&clock->cycles, overflow_cycles,
+	ns = cyclecounter_cyc2ns(&timer->cycles, overflow_cycles,
 				 frac, &frac);
 	do_div(ns, NSEC_PER_SEC / HZ);
-	clock->overflow_period = ns;
+	timer->overflow_period = ns;
 
-	mdev->clock_info =
-		(struct mlx5_ib_clock_info *)get_zeroed_page(GFP_KERNEL);
-	if (mdev->clock_info) {
-		mdev->clock_info->nsec = clock->tc.nsec;
-		mdev->clock_info->cycles = clock->tc.cycle_last;
-		mdev->clock_info->mask = clock->cycles.mask;
-		mdev->clock_info->mult = clock->nominal_c_mult;
-		mdev->clock_info->shift = clock->cycles.shift;
-		mdev->clock_info->frac = clock->tc.frac;
-		mdev->clock_info->overflow_period = clock->overflow_period;
+	INIT_DELAYED_WORK(&timer->overflow_work, mlx5_timestamp_overflow);
+	if (timer->overflow_period)
+		schedule_delayed_work(&timer->overflow_work, 0);
+	else
+		mlx5_core_warn(mdev,
+			       "invalid overflow period, overflow_work is not scheduled\n");
+
+	if (clock_info)
+		clock_info->overflow_period = timer->overflow_period;
+}
+
+static void mlx5_init_clock_info(struct mlx5_core_dev *mdev)
+{
+	struct mlx5_clock *clock = &mdev->clock;
+	struct mlx5_ib_clock_info *info;
+	struct mlx5_timer *timer;
+
+	mdev->clock_info = (struct mlx5_ib_clock_info *)get_zeroed_page(GFP_KERNEL);
+	if (!mdev->clock_info) {
+		mlx5_core_warn(mdev, "Failed to allocate IB clock info page\n");
+		return;
 	}
 
+	info = mdev->clock_info;
+	timer = &clock->timer;
+
+	info->nsec = timer->tc.nsec;
+	info->cycles = timer->tc.cycle_last;
+	info->mask = timer->cycles.mask;
+	info->mult = timer->nominal_c_mult;
+	info->shift = timer->cycles.shift;
+	info->frac = timer->tc.frac;
+}
+
+void mlx5_init_clock(struct mlx5_core_dev *mdev)
+{
+	struct mlx5_clock *clock = &mdev->clock;
+
+	if (!MLX5_CAP_GEN(mdev, device_frequency_khz)) {
+		mlx5_core_warn(mdev, "invalid device_frequency_khz, aborting HW clock init\n");
+		return;
+	}
+
+	seqlock_init(&clock->lock);
+
+	mlx5_timecounter_init(mdev);
+	mlx5_init_clock_info(mdev);
+	mlx5_init_overflow_period(clock);
 	INIT_WORK(&clock->pps_info.out_work, mlx5_pps_out);
-	INIT_DELAYED_WORK(&clock->overflow_work, mlx5_timestamp_overflow);
-	if (clock->overflow_period)
-		schedule_delayed_work(&clock->overflow_work, 0);
-	else
-		mlx5_core_warn(mdev, "invalid overflow period, overflow_work is not scheduled\n");
 
 	/* Configure the PHC */
 	clock->ptp_info = mlx5_ptp_clock_info;
@@ -684,7 +734,7 @@
 	}
 
 	cancel_work_sync(&clock->pps_info.out_work);
-	cancel_delayed_work_sync(&clock->overflow_work);
+	cancel_delayed_work_sync(&clock->timer.overflow_work);
 
 	if (mdev->clock_info) {
 		free_page((unsigned long)mdev->clock_info);
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h b/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h
index 3160092..6e8804e 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h
@@ -45,12 +45,13 @@
 static inline ktime_t mlx5_timecounter_cyc2time(struct mlx5_clock *clock,
 						u64 timestamp)
 {
+	struct mlx5_timer *timer = &clock->timer;
 	unsigned int seq;
 	u64 nsec;
 
 	do {
 		seq = read_seqbegin(&clock->lock);
-		nsec = timecounter_cyc2time(&clock->tc, timestamp);
+		nsec = timecounter_cyc2time(&timer->tc, timestamp);
 	} while (read_seqretry(&clock->lock, seq));
 
 	return ns_to_ktime(nsec);
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
index bced2ef..438be21 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
@@ -3,6 +3,7 @@
 
 #include <linux/mlx5/vport.h>
 #include "lib/devcom.h"
+#include "mlx5_core.h"
 
 static LIST_HEAD(devcom_list);
 
@@ -14,7 +15,7 @@
 struct mlx5_devcom_component {
 	struct {
 		void *data;
-	} device[MLX5_MAX_PORTS];
+	} device[MLX5_DEVCOM_PORTS_SUPPORTED];
 
 	mlx5_devcom_event_handler_t handler;
 	struct rw_semaphore sem;
@@ -25,7 +26,7 @@
 	struct list_head list;
 
 	struct mlx5_devcom_component components[MLX5_DEVCOM_NUM_COMPONENTS];
-	struct mlx5_core_dev *devs[MLX5_MAX_PORTS];
+	struct mlx5_core_dev *devs[MLX5_DEVCOM_PORTS_SUPPORTED];
 };
 
 struct mlx5_devcom {
@@ -74,13 +75,16 @@
 
 	if (!mlx5_core_is_pf(dev))
 		return NULL;
+	if (MLX5_CAP_GEN(dev, num_lag_ports) != MLX5_DEVCOM_PORTS_SUPPORTED)
+		return NULL;
 
+	mlx5_dev_list_lock();
 	sguid0 = mlx5_query_nic_system_image_guid(dev);
 	list_for_each_entry(iter, &devcom_list, list) {
 		struct mlx5_core_dev *tmp_dev = NULL;
 
 		idx = -1;
-		for (i = 0; i < MLX5_MAX_PORTS; i++) {
+		for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++) {
 			if (iter->devs[i])
 				tmp_dev = iter->devs[i];
 			else
@@ -100,8 +104,10 @@
 
 	if (!priv) {
 		priv = mlx5_devcom_list_alloc();
-		if (!priv)
-			return ERR_PTR(-ENOMEM);
+		if (!priv) {
+			devcom = ERR_PTR(-ENOMEM);
+			goto out;
+		}
 
 		idx = 0;
 		new_priv = true;
@@ -110,13 +116,16 @@
 	priv->devs[idx] = dev;
 	devcom = mlx5_devcom_alloc(priv, idx);
 	if (!devcom) {
-		kfree(priv);
-		return ERR_PTR(-ENOMEM);
+		if (new_priv)
+			kfree(priv);
+		devcom = ERR_PTR(-ENOMEM);
+		goto out;
 	}
 
 	if (new_priv)
 		list_add(&priv->list, &devcom_list);
-
+out:
+	mlx5_dev_list_unlock();
 	return devcom;
 }
 
@@ -129,20 +138,23 @@
 	if (IS_ERR_OR_NULL(devcom))
 		return;
 
+	mlx5_dev_list_lock();
 	priv = devcom->priv;
 	priv->devs[devcom->idx] = NULL;
 
 	kfree(devcom);
 
-	for (i = 0; i < MLX5_MAX_PORTS; i++)
+	for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++)
 		if (priv->devs[i])
 			break;
 
-	if (i != MLX5_MAX_PORTS)
-		return;
+	if (i != MLX5_DEVCOM_PORTS_SUPPORTED)
+		goto out;
 
 	list_del(&priv->list);
 	kfree(priv);
+out:
+	mlx5_dev_list_unlock();
 }
 
 void mlx5_devcom_register_component(struct mlx5_devcom *devcom,
@@ -191,7 +203,7 @@
 
 	comp = &devcom->priv->components[id];
 	down_write(&comp->sem);
-	for (i = 0; i < MLX5_MAX_PORTS; i++)
+	for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++)
 		if (i != devcom->idx && comp->device[i].data) {
 			err = comp->handler(event, comp->device[i].data,
 					    event_data);
@@ -239,7 +251,7 @@
 		return NULL;
 	}
 
-	for (i = 0; i < MLX5_MAX_PORTS; i++)
+	for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++)
 		if (i != devcom->idx)
 			break;
 
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h b/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h
index 939d5bf..94313c1 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h
@@ -6,6 +6,8 @@
 
 #include <linux/mlx5/driver.h>
 
+#define MLX5_DEVCOM_PORTS_SUPPORTED 2
+
 enum mlx5_devcom_components {
 	MLX5_DEVCOM_ESW_OFFLOADS,
 
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c
index 23361a9..6dc83e8 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c
@@ -105,6 +105,7 @@
 		geneve->opt_type = opt->type;
 		geneve->obj_id = res;
 		geneve->refcount++;
+		res = 0;
 	}
 
 unlock:
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/main.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/main.c
index 8246b62..22907f6 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -783,7 +783,6 @@
 	}
 
 	mlx5_pci_vsc_init(dev);
-	dev->caps.embedded_cpu = mlx5_read_embedded_cpu(dev);
 	return 0;
 
 err_clr_master:
@@ -887,7 +886,7 @@
 
 	dev->dm = mlx5_dm_create(dev);
 	if (IS_ERR(dev->dm))
-		mlx5_core_warn(dev, "Failed to init device memory%d\n", err);
+		mlx5_core_warn(dev, "Failed to init device memory %ld\n", PTR_ERR(dev->dm));
 
 	dev->tracer = mlx5_fw_tracer_create(dev);
 	dev->hv_vhca = mlx5_hv_vhca_create(dev);
@@ -906,6 +905,8 @@
 err_tables_cleanup:
 	mlx5_geneve_destroy(dev->geneve);
 	mlx5_vxlan_destroy(dev->vxlan);
+	mlx5_cleanup_clock(dev);
+	mlx5_cleanup_reserved_gids(dev);
 	mlx5_cq_debugfs_cleanup(dev);
 	mlx5_fw_reset_cleanup(dev);
 err_events_cleanup:
@@ -976,6 +977,7 @@
 		goto err_cmd_cleanup;
 	}
 
+	dev->caps.embedded_cpu = mlx5_read_embedded_cpu(dev);
 	mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_UP);
 
 	err = mlx5_core_enable_hca(dev, 0);
@@ -1640,7 +1642,7 @@
 	}
 }
 
-static int __init init(void)
+static int __init mlx5_init(void)
 {
 	int err;
 
@@ -1665,7 +1667,7 @@
 	return err;
 }
 
-static void __exit cleanup(void)
+static void __exit mlx5_cleanup(void)
 {
 #ifdef CONFIG_MLX5_CORE_EN
 	mlx5e_cleanup();
@@ -1674,5 +1676,5 @@
 	mlx5_unregister_debugfs();
 }
 
-module_init(init);
-module_exit(cleanup);
+module_init(mlx5_init);
+module_exit(mlx5_cleanup);
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
index a44a2ba..1ea71f0 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
@@ -216,7 +216,8 @@
 
 	n = find_first_bit(&fp->bitmask, 8 * sizeof(fp->bitmask));
 	if (n >= MLX5_NUM_4K_IN_PAGE) {
-		mlx5_core_warn(dev, "alloc 4k bug\n");
+		mlx5_core_warn(dev, "alloc 4k bug: fw page = 0x%llx, n = %u, bitmask: %lu, max num of 4K pages: %d\n",
+			       fp->addr, n, fp->bitmask,  MLX5_NUM_4K_IN_PAGE);
 		return -ENOENT;
 	}
 	clear_bit(n, &fp->bitmask);
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/sriov.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
index 3094d20..ee9287d 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
@@ -211,8 +211,7 @@
 		host_total_vfs = MLX5_GET(query_esw_functions_out, out,
 					  host_params_context.host_total_vfs);
 		kvfree(out);
-		if (host_total_vfs)
-			return host_total_vfs;
+		return host_total_vfs;
 	}
 
 done:
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c
index fd56cae..4549840 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c
@@ -425,11 +425,12 @@
 
 	err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
 	if (err)
-		return err;
+		goto err_free_in;
 
 	*reformat_id = MLX5_GET(alloc_packet_reformat_context_out, out, packet_reformat_id);
-	kvfree(in);
 
+err_free_in:
+	kvfree(in);
 	return err;
 }
 
diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c
index b01aaec..3b5deb0 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c
@@ -112,7 +112,8 @@
 {
 	u32 crc = crc32(0, input_data, length);
 
-	return (__force u32)htonl(crc);
+	return (__force u32)((crc >> 24) & 0xff) | ((crc << 8) & 0xff0000) |
+			    ((crc >> 8) & 0xff00) | ((crc << 24) & 0xff000000);
 }
 
 u32 mlx5dr_ste_calc_hash_index(u8 *hw_ste_p, struct mlx5dr_ste_htbl *htbl)
diff --git a/kernel/drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2_tlv_multi.c b/kernel/drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2_tlv_multi.c
index 017d68f..972c571 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2_tlv_multi.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2_tlv_multi.c
@@ -31,6 +31,8 @@
 
 	if (tlv->type == MLXFW_MFA2_TLV_MULTI_PART) {
 		multi = mlxfw_mfa2_tlv_multi_get(mfa2_file, tlv);
+		if (!multi)
+			return NULL;
 		tlv_len = NLA_ALIGN(tlv_len + be16_to_cpu(multi->total_len));
 	}
 
diff --git a/kernel/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/kernel/drivers/net/ethernet/mellanox/mlxsw/i2c.c
index ce843ea..61d2f62 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlxsw/i2c.c
+++ b/kernel/drivers/net/ethernet/mellanox/mlxsw/i2c.c
@@ -47,6 +47,7 @@
 #define MLXSW_I2C_MBOX_SIZE_BITS	12
 #define MLXSW_I2C_ADDR_BUF_SIZE		4
 #define MLXSW_I2C_BLK_DEF		32
+#define MLXSW_I2C_BLK_MAX		100
 #define MLXSW_I2C_RETRY			5
 #define MLXSW_I2C_TIMEOUT_MSECS		5000
 #define MLXSW_I2C_MAX_DATA_SIZE		256
@@ -428,7 +429,7 @@
 	} else {
 		/* No input mailbox is case of initialization query command. */
 		reg_size = MLXSW_I2C_MAX_DATA_SIZE;
-		num = reg_size / mlxsw_i2c->block_size;
+		num = DIV_ROUND_UP(reg_size, mlxsw_i2c->block_size);
 
 		if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
 			dev_err(&client->dev, "Could not acquire lock");
@@ -576,7 +577,7 @@
 			return -EOPNOTSUPP;
 		}
 
-		mlxsw_i2c->block_size = max_t(u16, MLXSW_I2C_BLK_DEF,
+		mlxsw_i2c->block_size = min_t(u16, MLXSW_I2C_BLK_MAX,
 					      min_t(u16, quirks->max_read_len,
 						    quirks->max_write_len));
 	} else {
diff --git a/kernel/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h b/kernel/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
index a2c1fbd..0225c8f 100644
--- a/kernel/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
+++ b/kernel/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
@@ -26,7 +26,7 @@
 #define MLXSW_PCI_CIR_TIMEOUT_MSECS		1000
 
 #define MLXSW_PCI_SW_RESET_TIMEOUT_MSECS	900000
-#define MLXSW_PCI_SW_RESET_WAIT_MSECS		200
+#define MLXSW_PCI_SW_RESET_WAIT_MSECS		400
 #define MLXSW_PCI_FW_READY			0xA1844
 #define MLXSW_PCI_FW_READY_MASK			0xFFFF
 #define MLXSW_PCI_FW_READY_MAGIC		0x5E
diff --git a/kernel/drivers/net/ethernet/microchip/lan743x_main.c b/kernel/drivers/net/ethernet/microchip/lan743x_main.c
index 481f89d..50cb1c5 100644
--- a/kernel/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/kernel/drivers/net/ethernet/microchip/lan743x_main.c
@@ -83,6 +83,18 @@
 				  !(data & HW_CFG_LRST_), 100000, 10000000);
 }
 
+static int lan743x_csr_wait_for_bit_atomic(struct lan743x_adapter *adapter,
+					   int offset, u32 bit_mask,
+					   int target_value, int udelay_min,
+					   int udelay_max, int count)
+{
+	u32 data;
+
+	return readx_poll_timeout_atomic(LAN743X_CSR_READ_OP, offset, data,
+					 target_value == !!(data & bit_mask),
+					 udelay_max, udelay_min * count);
+}
+
 static int lan743x_csr_wait_for_bit(struct lan743x_adapter *adapter,
 				    int offset, u32 bit_mask,
 				    int target_value, int usleep_min,
@@ -678,8 +690,8 @@
 	u32 dp_sel;
 	int i;
 
-	if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_,
-				     1, 40, 100, 100))
+	if (lan743x_csr_wait_for_bit_atomic(adapter, DP_SEL, DP_SEL_DPRDY_,
+					    1, 40, 100, 100))
 		return -EIO;
 	dp_sel = lan743x_csr_read(adapter, DP_SEL);
 	dp_sel &= ~DP_SEL_MASK_;
@@ -690,8 +702,9 @@
 		lan743x_csr_write(adapter, DP_ADDR, addr + i);
 		lan743x_csr_write(adapter, DP_DATA_0, buf[i]);
 		lan743x_csr_write(adapter, DP_CMD, DP_CMD_WRITE_);
-		if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_,
-					     1, 40, 100, 100))
+		if (lan743x_csr_wait_for_bit_atomic(adapter, DP_SEL,
+						    DP_SEL_DPRDY_,
+						    1, 40, 100, 100))
 			return -EIO;
 	}
 
diff --git a/kernel/drivers/net/ethernet/mscc/ocelot_flower.c b/kernel/drivers/net/ethernet/mscc/ocelot_flower.c
index b221b83..e56e540 100644
--- a/kernel/drivers/net/ethernet/mscc/ocelot_flower.c
+++ b/kernel/drivers/net/ethernet/mscc/ocelot_flower.c
@@ -468,6 +468,18 @@
 		flow_rule_match_control(rule, &match);
 	}
 
+	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
+		struct flow_match_vlan match;
+
+		flow_rule_match_vlan(rule, &match);
+		filter->key_type = OCELOT_VCAP_KEY_ANY;
+		filter->vlan.vid.value = match.key->vlan_id;
+		filter->vlan.vid.mask = match.mask->vlan_id;
+		filter->vlan.pcp.value[0] = match.key->vlan_priority;
+		filter->vlan.pcp.mask[0] = match.mask->vlan_priority;
+		match_protocol = false;
+	}
+
 	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
 		struct flow_match_eth_addrs match;
 
@@ -597,18 +609,6 @@
 		filter->key.ipv4.sport.mask = ntohs(match.mask->src);
 		filter->key.ipv4.dport.value = ntohs(match.key->dst);
 		filter->key.ipv4.dport.mask = ntohs(match.mask->dst);
-		match_protocol = false;
-	}
-
-	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
-		struct flow_match_vlan match;
-
-		flow_rule_match_vlan(rule, &match);
-		filter->key_type = OCELOT_VCAP_KEY_ANY;
-		filter->vlan.vid.value = match.key->vlan_id;
-		filter->vlan.vid.mask = match.mask->vlan_id;
-		filter->vlan.pcp.value[0] = match.key->vlan_priority;
-		filter->vlan.pcp.mask[0] = match.mask->vlan_priority;
 		match_protocol = false;
 	}
 
diff --git a/kernel/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/kernel/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 1664e91..5a1ed48 100644
--- a/kernel/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/kernel/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -3920,6 +3920,7 @@
 	myri10ge_free_slices(mgp);
 
 abort_with_firmware:
+	kfree(mgp->msix_vectors);
 	myri10ge_dummy_rdma(mgp, 0);
 
 abort_with_ioremap:
diff --git a/kernel/drivers/net/ethernet/natsemi/sonic.c b/kernel/drivers/net/ethernet/natsemi/sonic.c
index d17d1b4..825356e 100644
--- a/kernel/drivers/net/ethernet/natsemi/sonic.c
+++ b/kernel/drivers/net/ethernet/natsemi/sonic.c
@@ -292,7 +292,7 @@
 	 */
 
 	laddr = dma_map_single(lp->device, skb->data, length, DMA_TO_DEVICE);
-	if (!laddr) {
+	if (dma_mapping_error(lp->device, laddr)) {
 		pr_err_ratelimited("%s: failed to map tx DMA buffer.\n", dev->name);
 		dev_kfree_skb_any(skb);
 		return NETDEV_TX_OK;
@@ -509,7 +509,7 @@
 
 	*new_addr = dma_map_single(lp->device, skb_put(*new_skb, SONIC_RBSIZE),
 				   SONIC_RBSIZE, DMA_FROM_DEVICE);
-	if (!*new_addr) {
+	if (dma_mapping_error(lp->device, *new_addr)) {
 		dev_kfree_skb(*new_skb);
 		*new_skb = NULL;
 		return false;
diff --git a/kernel/drivers/net/ethernet/neterion/s2io.c b/kernel/drivers/net/ethernet/neterion/s2io.c
index 8a30be6..ff46b08 100644
--- a/kernel/drivers/net/ethernet/neterion/s2io.c
+++ b/kernel/drivers/net/ethernet/neterion/s2io.c
@@ -2384,7 +2384,7 @@
 			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++;
 			}
 		}
diff --git a/kernel/drivers/net/ethernet/nvidia/forcedeth.c b/kernel/drivers/net/ethernet/nvidia/forcedeth.c
index 2fc10a3..e14dd10 100644
--- a/kernel/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/kernel/drivers/net/ethernet/nvidia/forcedeth.c
@@ -6138,6 +6138,7 @@
 	return 0;
 
 out_error:
+	nv_mgmt_release_sema(dev);
 	if (phystate_orig)
 		writel(phystate|NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl);
 out_freering:
diff --git a/kernel/drivers/net/ethernet/pasemi/pasemi_mac.c b/kernel/drivers/net/ethernet/pasemi/pasemi_mac.c
index 040a15a..c1d7bd1 100644
--- a/kernel/drivers/net/ethernet/pasemi/pasemi_mac.c
+++ b/kernel/drivers/net/ethernet/pasemi/pasemi_mac.c
@@ -1423,7 +1423,7 @@
 	write_dma_reg(PAS_DMA_TXCHAN_INCR(txring->chan.chno), 2);
 }
 
-static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct pasemi_mac * const mac = netdev_priv(dev);
 	struct pasemi_mac_txring * const txring = tx_ring(mac);
diff --git a/kernel/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c b/kernel/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
index 35c72d4..8e5b01a 100644
--- a/kernel/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
+++ b/kernel/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
@@ -693,7 +693,7 @@
 		info->data = lif->nxqs;
 		break;
 	default:
-		netdev_err(netdev, "Command parameter %d is not supported\n",
+		netdev_dbg(netdev, "Command parameter %d is not supported\n",
 			   info->cmd);
 		err = -EOPNOTSUPP;
 	}
diff --git a/kernel/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/kernel/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index cb12d01..0987726 100644
--- a/kernel/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/kernel/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -257,6 +257,7 @@
 			.oper = IONIC_Q_ENABLE,
 		},
 	};
+	int ret;
 
 	idev = &lif->ionic->idev;
 	dev = lif->ionic->dev;
@@ -264,16 +265,24 @@
 	dev_dbg(dev, "q_enable.index %d q_enable.qtype %d\n",
 		ctx.cmd.q_control.index, ctx.cmd.q_control.type);
 
+	if (qcq->flags & IONIC_QCQ_F_INTR)
+		ionic_intr_clean(idev->intr_ctrl, qcq->intr.index);
+
+	ret = ionic_adminq_post_wait(lif, &ctx);
+	if (ret)
+		return ret;
+
+	if (qcq->napi.poll)
+		napi_enable(&qcq->napi);
+
 	if (qcq->flags & IONIC_QCQ_F_INTR) {
 		irq_set_affinity_hint(qcq->intr.vector,
 				      &qcq->intr.affinity_mask);
-		napi_enable(&qcq->napi);
-		ionic_intr_clean(idev->intr_ctrl, qcq->intr.index);
 		ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
 				IONIC_INTR_MASK_CLEAR);
 	}
 
-	return ionic_adminq_post_wait(lif, &ctx);
+	return 0;
 }
 
 static int ionic_qcq_disable(struct ionic_qcq *qcq, bool send_to_hw)
@@ -424,11 +433,6 @@
 static void ionic_link_qcq_interrupts(struct ionic_qcq *src_qcq,
 				      struct ionic_qcq *n_qcq)
 {
-	if (WARN_ON(n_qcq->flags & IONIC_QCQ_F_INTR)) {
-		ionic_intr_free(n_qcq->cq.lif->ionic, n_qcq->intr.index);
-		n_qcq->flags &= ~IONIC_QCQ_F_INTR;
-	}
-
 	n_qcq->intr.vector = src_qcq->intr.vector;
 	n_qcq->intr.index = src_qcq->intr.index;
 }
diff --git a/kernel/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/kernel/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 46dbb49..5463c8b 100644
--- a/kernel/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/kernel/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -986,7 +986,7 @@
 		stats->vlan_inserted++;
 	}
 
-	if (skb->csum_not_inet)
+	if (skb_csum_is_sctp(skb))
 		stats->crc32_csum++;
 	else
 		stats->csum++;
diff --git a/kernel/drivers/net/ethernet/qlogic/qed/qed_debug.c b/kernel/drivers/net/ethernet/qlogic/qed/qed_debug.c
index 6ab3e60..4b4077c 100644
--- a/kernel/drivers/net/ethernet/qlogic/qed/qed_debug.c
+++ b/kernel/drivers/net/ethernet/qlogic/qed/qed_debug.c
@@ -1796,9 +1796,10 @@
 				   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;
diff --git a/kernel/drivers/net/ethernet/qlogic/qed/qed_dev.c b/kernel/drivers/net/ethernet/qlogic/qed/qed_dev.c
index d2f5855..895b6f0 100644
--- a/kernel/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/kernel/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -4986,6 +4986,11 @@
 
 	num_vports = p_hwfn->qm_info.num_vports;
 
+	if (num_vports < 2) {
+		DP_NOTICE(p_hwfn, "Unexpected num_vports: %d\n", num_vports);
+		return -EINVAL;
+	}
+
 	/* Accounting for the vports which are configured for WFQ explicitly */
 	for (i = 0; i < num_vports; i++) {
 		u32 tmp_speed;
diff --git a/kernel/drivers/net/ethernet/qlogic/qed/qed_l2.c b/kernel/drivers/net/ethernet/qlogic/qed/qed_l2.c
index 07824bf..0157bcd 100644
--- a/kernel/drivers/net/ethernet/qlogic/qed/qed_l2.c
+++ b/kernel/drivers/net/ethernet/qlogic/qed/qed_l2.c
@@ -1902,7 +1902,7 @@
 {
 	u32 i;
 
-	if (!cdev) {
+	if (!cdev || cdev->recov_in_prog) {
 		memset(stats, 0, sizeof(*stats));
 		return;
 	}
diff --git a/kernel/drivers/net/ethernet/qlogic/qed/qed_ll2.h b/kernel/drivers/net/ethernet/qlogic/qed/qed_ll2.h
index df88d00..efd025d 100644
--- a/kernel/drivers/net/ethernet/qlogic/qed/qed_ll2.h
+++ b/kernel/drivers/net/ethernet/qlogic/qed/qed_ll2.h
@@ -111,9 +111,9 @@
 	enum core_tx_dest tx_dest;
 	u8 tx_stats_en;
 	bool main_func_queue;
+	struct qed_ll2_cbs cbs;
 	struct qed_ll2_rx_queue rx_queue;
 	struct qed_ll2_tx_queue tx_queue;
-	struct qed_ll2_cbs cbs;
 };
 
 extern const struct qed_ll2_ops qed_ll2_ops_pass;
diff --git a/kernel/drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c b/kernel/drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c
index 3e3192a..fdbd5f0 100644
--- a/kernel/drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c
+++ b/kernel/drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c
@@ -422,7 +422,7 @@
 	if (p_time->hour > 23)
 		p_time->hour = 0;
 	if (p_time->min > 59)
-		p_time->hour = 0;
+		p_time->min = 0;
 	if (p_time->msec > 999)
 		p_time->msec = 0;
 	if (p_time->usec > 999)
diff --git a/kernel/drivers/net/ethernet/qlogic/qed/qed_sriov.c b/kernel/drivers/net/ethernet/qlogic/qed/qed_sriov.c
index 3541bc9..b2a2beb 100644
--- a/kernel/drivers/net/ethernet/qlogic/qed/qed_sriov.c
+++ b/kernel/drivers/net/ethernet/qlogic/qed/qed_sriov.c
@@ -4378,6 +4378,9 @@
 	}
 
 	vf = qed_iov_get_vf_info(QED_LEADING_HWFN(cdev), (u16)vfid, true);
+	if (!vf)
+		return -EINVAL;
+
 	vport_id = vf->vport_id;
 
 	return qed_configure_vport_wfq(cdev, vport_id, rate);
@@ -5123,7 +5126,7 @@
 
 		/* Validate that the VF has a configured vport */
 		vf = qed_iov_get_vf_info(hwfn, i, true);
-		if (!vf->vport_instance)
+		if (!vf || !vf->vport_instance)
 			continue;
 
 		memset(&params, 0, sizeof(params));
diff --git a/kernel/drivers/net/ethernet/qlogic/qede/qede.h b/kernel/drivers/net/ethernet/qlogic/qede/qede.h
index f313fd7..3251d58 100644
--- a/kernel/drivers/net/ethernet/qlogic/qede/qede.h
+++ b/kernel/drivers/net/ethernet/qlogic/qede/qede.h
@@ -273,6 +273,10 @@
 #define QEDE_ERR_WARN			3
 
 	struct qede_dump_info		dump_info;
+	struct delayed_work		periodic_task;
+	unsigned long			stats_coal_ticks;
+	u32				stats_coal_usecs;
+	spinlock_t			stats_lock; /* lock for vport stats access */
 };
 
 enum QEDE_STATE {
diff --git a/kernel/drivers/net/ethernet/qlogic/qede/qede_ethtool.c b/kernel/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
index bedbb85..db104e0 100644
--- a/kernel/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
+++ b/kernel/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
@@ -426,6 +426,8 @@
 		}
 	}
 
+	spin_lock(&edev->stats_lock);
+
 	for (i = 0; i < QEDE_NUM_STATS; i++) {
 		if (qede_is_irrelevant_stat(edev, i))
 			continue;
@@ -434,6 +436,8 @@
 
 		buf++;
 	}
+
+	spin_unlock(&edev->stats_lock);
 
 	__qede_unlock(edev);
 }
@@ -815,6 +819,7 @@
 
 	coal->rx_coalesce_usecs = rx_coal;
 	coal->tx_coalesce_usecs = tx_coal;
+	coal->stats_block_coalesce_usecs = edev->stats_coal_usecs;
 
 	return rc;
 }
@@ -826,6 +831,19 @@
 	struct qede_fastpath *fp;
 	int i, rc = 0;
 	u16 rxc, txc;
+
+	if (edev->stats_coal_usecs != coal->stats_block_coalesce_usecs) {
+		edev->stats_coal_usecs = coal->stats_block_coalesce_usecs;
+		if (edev->stats_coal_usecs) {
+			edev->stats_coal_ticks = usecs_to_jiffies(edev->stats_coal_usecs);
+			schedule_delayed_work(&edev->periodic_task, 0);
+
+			DP_INFO(edev, "Configured stats coal ticks=%lu jiffies\n",
+				edev->stats_coal_ticks);
+		} else {
+			cancel_delayed_work_sync(&edev->periodic_task);
+		}
+	}
 
 	if (!netif_running(dev)) {
 		DP_INFO(edev, "Interface is down\n");
@@ -2106,7 +2124,8 @@
 }
 
 static const struct ethtool_ops qede_ethtool_ops = {
-	.supported_coalesce_params	= ETHTOOL_COALESCE_USECS,
+	.supported_coalesce_params	= ETHTOOL_COALESCE_USECS |
+					  ETHTOOL_COALESCE_STATS_BLOCK_USECS,
 	.get_link_ksettings		= qede_get_link_ksettings,
 	.set_link_ksettings		= qede_set_link_ksettings,
 	.get_drvinfo			= qede_get_drvinfo,
@@ -2155,7 +2174,8 @@
 };
 
 static const struct ethtool_ops qede_vf_ethtool_ops = {
-	.supported_coalesce_params	= ETHTOOL_COALESCE_USECS,
+	.supported_coalesce_params	= ETHTOOL_COALESCE_USECS |
+					  ETHTOOL_COALESCE_STATS_BLOCK_USECS,
 	.get_link_ksettings		= qede_get_link_ksettings,
 	.get_drvinfo			= qede_get_drvinfo,
 	.get_msglevel			= qede_get_msglevel,
diff --git a/kernel/drivers/net/ethernet/qlogic/qede/qede_fp.c b/kernel/drivers/net/ethernet/qlogic/qede/qede_fp.c
index d210632..a632de2 100644
--- a/kernel/drivers/net/ethernet/qlogic/qede/qede_fp.c
+++ b/kernel/drivers/net/ethernet/qlogic/qede/qede_fp.c
@@ -1456,7 +1456,12 @@
 	rx_work_done = (likely(fp->type & QEDE_FASTPATH_RX) &&
 			qede_has_rx_work(fp->rxq)) ?
 			qede_rx_int(fp, budget) : 0;
-	if (rx_work_done < budget) {
+
+	if (fp->xdp_xmit & QEDE_XDP_REDIRECT)
+		xdp_do_flush();
+
+	/* Handle case where we are called by netpoll with a budget of 0 */
+	if (rx_work_done < budget || !budget) {
 		if (!qede_poll_is_more_work(fp)) {
 			napi_complete_done(napi, rx_work_done);
 
@@ -1473,9 +1478,6 @@
 		fp->xdp_tx->tx_db.data.bd_prod = cpu_to_le16(xdp_prod);
 		qede_update_tx_producer(fp->xdp_tx);
 	}
-
-	if (fp->xdp_xmit & QEDE_XDP_REDIRECT)
-		xdp_do_flush_map();
 
 	return rx_work_done;
 }
diff --git a/kernel/drivers/net/ethernet/qlogic/qede/qede_main.c b/kernel/drivers/net/ethernet/qlogic/qede/qede_main.c
index e93f06e..681ec14 100644
--- a/kernel/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/kernel/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -313,6 +313,8 @@
 
 	edev->ops->get_vport_stats(edev->cdev, &stats);
 
+	spin_lock(&edev->stats_lock);
+
 	p_common->no_buff_discards = stats.common.no_buff_discards;
 	p_common->packet_too_big_discard = stats.common.packet_too_big_discard;
 	p_common->ttl0_discard = stats.common.ttl0_discard;
@@ -410,6 +412,8 @@
 		p_ah->tx_1519_to_max_byte_packets =
 		    stats.ah.tx_1519_to_max_byte_packets;
 	}
+
+	spin_unlock(&edev->stats_lock);
 }
 
 static void qede_get_stats64(struct net_device *dev,
@@ -418,8 +422,9 @@
 	struct qede_dev *edev = netdev_priv(dev);
 	struct qede_stats_common *p_common;
 
-	qede_fill_by_demand_stats(edev);
 	p_common = &edev->stats.common;
+
+	spin_lock(&edev->stats_lock);
 
 	stats->rx_packets = p_common->rx_ucast_pkts + p_common->rx_mcast_pkts +
 			    p_common->rx_bcast_pkts;
@@ -440,6 +445,8 @@
 		stats->collisions = edev->stats.bb.tx_total_collisions;
 	stats->rx_crc_errors = p_common->rx_crc_errors;
 	stats->rx_frame_errors = p_common->rx_align_errors;
+
+	spin_unlock(&edev->stats_lock);
 }
 
 #ifdef CONFIG_QED_SRIOV
@@ -1001,6 +1008,23 @@
 	rtnl_unlock();
 }
 
+static void qede_periodic_task(struct work_struct *work)
+{
+	struct qede_dev *edev = container_of(work, struct qede_dev,
+					     periodic_task.work);
+
+	qede_fill_by_demand_stats(edev);
+	schedule_delayed_work(&edev->periodic_task, edev->stats_coal_ticks);
+}
+
+static void qede_init_periodic_task(struct qede_dev *edev)
+{
+	INIT_DELAYED_WORK(&edev->periodic_task, qede_periodic_task);
+	spin_lock_init(&edev->stats_lock);
+	edev->stats_coal_usecs = USEC_PER_SEC;
+	edev->stats_coal_ticks = usecs_to_jiffies(USEC_PER_SEC);
+}
+
 static void qede_sp_task(struct work_struct *work)
 {
 	struct qede_dev *edev = container_of(work, struct qede_dev,
@@ -1020,6 +1044,7 @@
 	 */
 
 	if (test_and_clear_bit(QEDE_SP_RECOVERY, &edev->sp_flags)) {
+		cancel_delayed_work_sync(&edev->periodic_task);
 #ifdef CONFIG_QED_SRIOV
 		/* SRIOV must be disabled outside the lock to avoid a deadlock.
 		 * The recovery of the active VFs is currently not supported.
@@ -1216,6 +1241,7 @@
 		 */
 		INIT_DELAYED_WORK(&edev->sp_task, qede_sp_task);
 		mutex_init(&edev->qede_lock);
+		qede_init_periodic_task(edev);
 
 		rc = register_netdev(edev->ndev);
 		if (rc) {
@@ -1240,6 +1266,11 @@
 	edev->rx_copybreak = QEDE_RX_HDR_SIZE;
 
 	qede_log_probe(edev);
+
+	/* retain user config (for example - after recovery) */
+	if (edev->stats_coal_usecs)
+		schedule_delayed_work(&edev->periodic_task, 0);
+
 	return 0;
 
 err4:
@@ -1308,6 +1339,7 @@
 		unregister_netdev(ndev);
 
 		cancel_delayed_work_sync(&edev->sp_task);
+		cancel_delayed_work_sync(&edev->periodic_task);
 
 		edev->ops->common->set_power_state(cdev, PCI_D0);
 
diff --git a/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index d2c1907..beeeec8 100644
--- a/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -2505,7 +2505,13 @@
 		goto disable_mbx_intr;
 
 	qlcnic_83xx_clear_function_resources(adapter);
-	qlcnic_dcb_enable(adapter->dcb);
+
+	err = qlcnic_dcb_enable(adapter->dcb);
+	if (err) {
+		qlcnic_dcb_free(adapter->dcb);
+		goto disable_mbx_intr;
+	}
+
 	qlcnic_83xx_initialize_nic(adapter, 1);
 	qlcnic_dcb_get_info(adapter->dcb);
 
diff --git a/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
index 87f76ba..eb827b8 100644
--- a/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
+++ b/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
@@ -628,7 +628,13 @@
 	int i, err, ring;
 
 	if (dev->flags & QLCNIC_NEED_FLR) {
-		pci_reset_function(dev->pdev);
+		err = pci_reset_function(dev->pdev);
+		if (err) {
+			dev_err(&dev->pdev->dev,
+				"Adapter reset failed (%d). Please reboot\n",
+				err);
+			return err;
+		}
 		dev->flags &= ~QLCNIC_NEED_FLR;
 	}
 
diff --git a/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h b/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
index 7519773..22afa2b 100644
--- a/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
+++ b/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
@@ -41,11 +41,6 @@
 	unsigned long			state;
 };
 
-static inline void qlcnic_clear_dcb_ops(struct qlcnic_dcb *dcb)
-{
-	kfree(dcb);
-}
-
 static inline int qlcnic_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
 {
 	if (dcb && dcb->ops->get_hw_capability)
@@ -112,9 +107,8 @@
 		dcb->ops->init_dcbnl_ops(dcb);
 }
 
-static inline void qlcnic_dcb_enable(struct qlcnic_dcb *dcb)
+static inline int qlcnic_dcb_enable(struct qlcnic_dcb *dcb)
 {
-	if (dcb && qlcnic_dcb_attach(dcb))
-		qlcnic_clear_dcb_ops(dcb);
+	return dcb ? qlcnic_dcb_attach(dcb) : 0;
 }
 #endif
diff --git a/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 27c07b2..44b7452 100644
--- a/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -2622,7 +2622,13 @@
 			 "Device does not support MSI interrupts\n");
 
 	if (qlcnic_82xx_check(adapter)) {
-		qlcnic_dcb_enable(adapter->dcb);
+		err = qlcnic_dcb_enable(adapter->dcb);
+		if (err) {
+			qlcnic_dcb_free(adapter->dcb);
+			dev_err(&pdev->dev, "Failed to enable DCB\n");
+			goto err_out_free_hw;
+		}
+
 		qlcnic_dcb_get_info(adapter->dcb);
 		err = qlcnic_setup_intr(adapter);
 
diff --git a/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
index 8367891..e864c45 100644
--- a/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+++ b/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
@@ -221,6 +221,8 @@
 	return 0;
 
 qlcnic_destroy_async_wq:
+	while (i--)
+		kfree(sriov->vf_info[i].vp);
 	destroy_workqueue(bc->bc_async_wq);
 
 qlcnic_destroy_trans_wq:
diff --git a/kernel/drivers/net/ethernet/qualcomm/emac/emac.c b/kernel/drivers/net/ethernet/qualcomm/emac/emac.c
index ad655f0..e1aa56b 100644
--- a/kernel/drivers/net/ethernet/qualcomm/emac/emac.c
+++ b/kernel/drivers/net/ethernet/qualcomm/emac/emac.c
@@ -728,9 +728,15 @@
 	struct net_device *netdev = dev_get_drvdata(&pdev->dev);
 	struct emac_adapter *adpt = netdev_priv(netdev);
 
+	netif_carrier_off(netdev);
+	netif_tx_disable(netdev);
+
 	unregister_netdev(netdev);
 	netif_napi_del(&adpt->rx_q.napi);
 
+	free_irq(adpt->irq.irq, &adpt->irq);
+	cancel_work_sync(&adpt->work_thread);
+
 	emac_clks_teardown(adpt);
 
 	put_device(&adpt->phydev->mdio.dev);
diff --git a/kernel/drivers/net/ethernet/qualcomm/qca_spi.c b/kernel/drivers/net/ethernet/qualcomm/qca_spi.c
index 36bcb5d..44fa959 100644
--- a/kernel/drivers/net/ethernet/qualcomm/qca_spi.c
+++ b/kernel/drivers/net/ethernet/qualcomm/qca_spi.c
@@ -574,8 +574,7 @@
 	while (!kthread_should_stop()) {
 		set_current_state(TASK_INTERRUPTIBLE);
 		if ((qca->intr_req == qca->intr_svc) &&
-		    (qca->txr.skb[qca->txr.head] == NULL) &&
-		    (qca->sync == QCASPI_SYNC_READY))
+		    !qca->txr.skb[qca->txr.head])
 			schedule();
 
 		set_current_state(TASK_RUNNING);
diff --git a/kernel/drivers/net/ethernet/rdc/r6040.c b/kernel/drivers/net/ethernet/rdc/r6040.c
index ccdfa93..4cff544 100644
--- a/kernel/drivers/net/ethernet/rdc/r6040.c
+++ b/kernel/drivers/net/ethernet/rdc/r6040.c
@@ -1158,10 +1158,12 @@
 	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 @@
 	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);
diff --git a/kernel/drivers/net/ethernet/realtek/r8169_phy_config.c b/kernel/drivers/net/ethernet/realtek/r8169_phy_config.c
index 913d030..e18a76f 100644
--- a/kernel/drivers/net/ethernet/realtek/r8169_phy_config.c
+++ b/kernel/drivers/net/ethernet/realtek/r8169_phy_config.c
@@ -970,6 +970,9 @@
 	/* disable phy pfm mode */
 	phy_modify_paged(phydev, 0x0a44, 0x11, BIT(7), 0);
 
+	/* disable 10m pll off */
+	phy_modify_paged(phydev, 0x0a43, 0x10, BIT(0), 0);
+
 	rtl8168g_disable_aldps(phydev);
 	rtl8168g_config_eee_phy(phydev);
 }
diff --git a/kernel/drivers/net/ethernet/renesas/ravb_main.c b/kernel/drivers/net/ethernet/renesas/ravb_main.c
index 9e7b85e..f218bac 100644
--- a/kernel/drivers/net/ethernet/renesas/ravb_main.c
+++ b/kernel/drivers/net/ethernet/renesas/ravb_main.c
@@ -736,14 +736,14 @@
 	ravb_write(ndev, ~(EIS_QFS | EIS_RESERVED), EIS);
 	if (eis & EIS_QFS) {
 		ris2 = ravb_read(ndev, RIS2);
-		ravb_write(ndev, ~(RIS2_QFF0 | RIS2_RFFF | RIS2_RESERVED),
+		ravb_write(ndev, ~(RIS2_QFF0 | RIS2_QFF1 | RIS2_RFFF | RIS2_RESERVED),
 			   RIS2);
 
 		/* Receive Descriptor Empty int */
 		if (ris2 & RIS2_QFF0)
 			priv->stats[RAVB_BE].rx_over_errors++;
 
-		    /* Receive Descriptor Empty int */
+		/* Receive Descriptor Empty int */
 		if (ris2 & RIS2_QFF1)
 			priv->stats[RAVB_NC].rx_over_errors++;
 
@@ -1706,6 +1706,8 @@
 			of_phy_deregister_fixed_link(np);
 	}
 
+	cancel_work_sync(&priv->work);
+
 	if (priv->chip_id != RCAR_GEN2) {
 		free_irq(priv->tx_irqs[RAVB_NC], ndev);
 		free_irq(priv->rx_irqs[RAVB_NC], ndev);
@@ -2249,15 +2251,15 @@
 	if (priv->chip_id != RCAR_GEN2)
 		ravb_ptp_stop(ndev);
 
-	dma_free_coherent(ndev->dev.parent, priv->desc_bat_size, priv->desc_bat,
-			  priv->desc_bat_dma);
 	/* Set reset mode */
 	ravb_write(ndev, CCC_OPC_RESET, CCC);
-	pm_runtime_put_sync(&pdev->dev);
 	unregister_netdev(ndev);
 	netif_napi_del(&priv->napi[RAVB_NC]);
 	netif_napi_del(&priv->napi[RAVB_BE]);
 	ravb_mdio_release(priv);
+	dma_free_coherent(ndev->dev.parent, priv->desc_bat_size, priv->desc_bat,
+			  priv->desc_bat_dma);
+	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 	free_netdev(ndev);
 	platform_set_drvdata(pdev, NULL);
diff --git a/kernel/drivers/net/ethernet/sfc/ef10.c b/kernel/drivers/net/ethernet/sfc/ef10.c
index eb1be73..3f53b5e 100644
--- a/kernel/drivers/net/ethernet/sfc/ef10.c
+++ b/kernel/drivers/net/ethernet/sfc/ef10.c
@@ -1297,14 +1297,17 @@
 {
 	struct efx_ef10_nic_data *nic_data = efx->nic_data;
 
+	spin_lock_bh(&efx->stats_lock);
 	kfree(nic_data->mc_stats);
 	nic_data->mc_stats = NULL;
+	spin_unlock_bh(&efx->stats_lock);
 }
 
 static int efx_ef10_init_nic(struct efx_nic *efx)
 {
 	struct efx_ef10_nic_data *nic_data = efx->nic_data;
-	netdev_features_t hw_enc_features = 0;
+	struct net_device *net_dev = efx->net_dev;
+	netdev_features_t tun_feats, tso_feats;
 	int rc;
 
 	if (nic_data->must_check_datapath_caps) {
@@ -1349,20 +1352,30 @@
 		nic_data->must_restore_piobufs = false;
 	}
 
-	/* add encapsulated checksum offload features */
+	/* encap features might change during reset if fw variant changed */
 	if (efx_has_cap(efx, VXLAN_NVGRE) && !efx_ef10_is_vf(efx))
-		hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-	/* add encapsulated TSO features */
+		net_dev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+	else
+		net_dev->hw_enc_features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+
+	tun_feats = NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
+		    NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM;
+	tso_feats = NETIF_F_TSO | NETIF_F_TSO6;
+
 	if (efx_has_cap(efx, TX_TSO_V2_ENCAP)) {
-		netdev_features_t encap_tso_features;
-
-		encap_tso_features = NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
-			NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM;
-
-		hw_enc_features |= encap_tso_features | NETIF_F_TSO;
-		efx->net_dev->features |= encap_tso_features;
+		/* If this is first nic_init, or if it is a reset and a new fw
+		 * variant has added new features, enable them by default.
+		 * If the features are not new, maintain their current value.
+		 */
+		if (!(net_dev->hw_features & tun_feats))
+			net_dev->features |= tun_feats;
+		net_dev->hw_enc_features |= tun_feats | tso_feats;
+		net_dev->hw_features |= tun_feats;
+	} else {
+		net_dev->hw_enc_features &= ~(tun_feats | tso_feats);
+		net_dev->hw_features &= ~tun_feats;
+		net_dev->features &= ~tun_feats;
 	}
-	efx->net_dev->hw_enc_features = hw_enc_features;
 
 	/* don't fail init if RSS setup doesn't work */
 	rc = efx->type->rx_push_rss_config(efx, false,
@@ -1825,9 +1838,14 @@
 
 	efx_ef10_get_stat_mask(efx, mask);
 
-	efx_nic_copy_stats(efx, nic_data->mc_stats);
-	efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT,
-			     mask, stats, nic_data->mc_stats, false);
+	/* If NIC was fini'd (probably resetting), then we can't read
+	 * updated stats right now.
+	 */
+	if (nic_data->mc_stats) {
+		efx_nic_copy_stats(efx, nic_data->mc_stats);
+		efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT,
+				     mask, stats, nic_data->mc_stats, false);
+	}
 
 	/* Update derived statistics */
 	efx_nic_fix_nodesc_drop_stat(efx,
@@ -3977,7 +3995,10 @@
 	 NETIF_F_HW_VLAN_CTAG_FILTER |	\
 	 NETIF_F_IPV6_CSUM |		\
 	 NETIF_F_RXHASH |		\
-	 NETIF_F_NTUPLE)
+	 NETIF_F_NTUPLE |		\
+	 NETIF_F_SG |			\
+	 NETIF_F_RXCSUM |		\
+	 NETIF_F_RXALL)
 
 const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
 	.is_vf = true,
diff --git a/kernel/drivers/net/ethernet/sfc/ef100_netdev.c b/kernel/drivers/net/ethernet/sfc/ef100_netdev.c
index 63a44ee..b9429e8 100644
--- a/kernel/drivers/net/ethernet/sfc/ef100_netdev.c
+++ b/kernel/drivers/net/ethernet/sfc/ef100_netdev.c
@@ -96,6 +96,8 @@
 	efx_mcdi_free_vis(efx);
 	efx_remove_interrupts(efx);
 
+	efx->state = STATE_NET_DOWN;
+
 	return 0;
 }
 
@@ -171,6 +173,8 @@
 	if (efx_mcdi_phy_poll(efx))
 		efx_link_status_changed(efx);
 	mutex_unlock(&efx->mac_lock);
+
+	efx->state = STATE_NET_UP;
 
 	return 0;
 
@@ -272,7 +276,7 @@
 	/* Always start with carrier off; PHY events will detect the link */
 	netif_carrier_off(net_dev);
 
-	efx->state = STATE_READY;
+	efx->state = STATE_NET_DOWN;
 	rtnl_unlock();
 	efx_init_mcdi_logging(efx);
 
diff --git a/kernel/drivers/net/ethernet/sfc/ef100_tx.c b/kernel/drivers/net/ethernet/sfc/ef100_tx.c
index a90e5a9..6ddda1a 100644
--- a/kernel/drivers/net/ethernet/sfc/ef100_tx.c
+++ b/kernel/drivers/net/ethernet/sfc/ef100_tx.c
@@ -333,7 +333,8 @@
  * Returns 0 on success, error code otherwise. In case of an error this
  * function will free the SKB.
  */
-int ef100_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
+netdev_tx_t ef100_enqueue_skb(struct efx_tx_queue *tx_queue,
+			      struct sk_buff *skb)
 {
 	unsigned int old_insert_count = tx_queue->insert_count;
 	struct efx_nic *efx = tx_queue->efx;
diff --git a/kernel/drivers/net/ethernet/sfc/efx.c b/kernel/drivers/net/ethernet/sfc/efx.c
index 7183080..7cf52fc 100644
--- a/kernel/drivers/net/ethernet/sfc/efx.c
+++ b/kernel/drivers/net/ethernet/sfc/efx.c
@@ -105,14 +105,6 @@
 static int efx_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **xdpfs,
 			u32 flags);
 
-#define EFX_ASSERT_RESET_SERIALISED(efx)		\
-	do {						\
-		if ((efx->state == STATE_READY) ||	\
-		    (efx->state == STATE_RECOVERY) ||	\
-		    (efx->state == STATE_DISABLED))	\
-			ASSERT_RTNL();			\
-	} while (0)
-
 /**************************************************************************
  *
  * Port handling
@@ -377,6 +369,8 @@
 	if (rc)
 		goto fail5;
 
+	efx->state = STATE_NET_DOWN;
+
 	return 0;
 
  fail5:
@@ -543,7 +537,9 @@
 	efx_start_all(efx);
 	if (efx->state == STATE_DISABLED || efx->reset_pending)
 		netif_device_detach(efx->net_dev);
-	efx_selftest_async_start(efx);
+	else
+		efx->state = STATE_NET_UP;
+
 	return 0;
 }
 
@@ -721,8 +717,6 @@
 	 * already requested.  If so, the NIC is probably hosed so we
 	 * abort.
 	 */
-	efx->state = STATE_READY;
-	smp_mb(); /* ensure we change state before checking reset_pending */
 	if (efx->reset_pending) {
 		netif_err(efx, probe, efx->net_dev,
 			  "aborting probe due to scheduled reset\n");
@@ -749,6 +743,8 @@
 	}
 
 	efx_associate(efx);
+
+	efx->state = STATE_NET_DOWN;
 
 	rtnl_unlock();
 
@@ -851,7 +847,7 @@
 	/* Flush reset_work. It can no longer be scheduled since we
 	 * are not READY.
 	 */
-	BUG_ON(efx->state == STATE_READY);
+	WARN_ON(efx_net_active(efx->state));
 	efx_flush_reset_workqueue(efx);
 
 	efx_disable_interrupts(efx);
@@ -1045,18 +1041,18 @@
 	}
 
 	/* Determine netdevice features */
-	net_dev->features |= (efx->type->offload_features | NETIF_F_SG |
-			      NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_RXALL);
-	if (efx->type->offload_features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
-		net_dev->features |= NETIF_F_TSO6;
-	/* Check whether device supports TSO */
-	if (!efx->type->tso_versions || !efx->type->tso_versions(efx))
-		net_dev->features &= ~NETIF_F_ALL_TSO;
+	net_dev->features |= efx->type->offload_features;
+
+	/* Add TSO features */
+	if (efx->type->tso_versions && efx->type->tso_versions(efx))
+		net_dev->features |= NETIF_F_TSO | NETIF_F_TSO6;
+
 	/* Mask for features that also apply to VLAN devices */
 	net_dev->vlan_features |= (NETIF_F_HW_CSUM | NETIF_F_SG |
 				   NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
 				   NETIF_F_RXCSUM);
 
+	/* Determine user configurable features */
 	net_dev->hw_features |= net_dev->features & ~efx->fixed_features;
 
 	/* Disable receiving frames with bad FCS, by default. */
@@ -1196,13 +1192,13 @@
 
 	rtnl_lock();
 
-	if (efx->state != STATE_DISABLED) {
-		efx->state = STATE_UNINIT;
-
+	if (efx_net_active(efx->state)) {
 		efx_device_detach_sync(efx);
 
 		efx_stop_all(efx);
 		efx_disable_interrupts(efx);
+
+		efx->state = efx_freeze(efx->state);
 	}
 
 	rtnl_unlock();
@@ -1217,7 +1213,7 @@
 
 	rtnl_lock();
 
-	if (efx->state != STATE_DISABLED) {
+	if (efx_frozen(efx->state)) {
 		rc = efx_enable_interrupts(efx);
 		if (rc)
 			goto fail;
@@ -1230,7 +1226,7 @@
 
 		efx_device_attach_if_not_resetting(efx);
 
-		efx->state = STATE_READY;
+		efx->state = efx_thaw(efx->state);
 
 		efx->type->resume_wol(efx);
 	}
diff --git a/kernel/drivers/net/ethernet/sfc/efx_common.c b/kernel/drivers/net/ethernet/sfc/efx_common.c
index de797e1..476ef1c 100644
--- a/kernel/drivers/net/ethernet/sfc/efx_common.c
+++ b/kernel/drivers/net/ethernet/sfc/efx_common.c
@@ -542,6 +542,8 @@
 	/* Start the hardware monitor if there is one */
 	efx_start_monitor(efx);
 
+	efx_selftest_async_start(efx);
+
 	/* Link state detection is normally event-driven; we have
 	 * to poll now because we could have missed a change
 	 */
@@ -897,7 +899,7 @@
 	 * have changed by now.  Now that we have the RTNL lock,
 	 * it cannot change again.
 	 */
-	if (efx->state == STATE_READY)
+	if (efx_net_active(efx->state))
 		(void)efx_reset(efx, method);
 
 	rtnl_unlock();
@@ -907,7 +909,7 @@
 {
 	enum reset_type method;
 
-	if (efx->state == STATE_RECOVERY) {
+	if (efx_recovering(efx->state)) {
 		netif_dbg(efx, drv, efx->net_dev,
 			  "recovering: skip scheduling %s reset\n",
 			  RESET_TYPE(type));
@@ -942,7 +944,7 @@
 	/* If we're not READY then just leave the flags set as the cue
 	 * to abort probing or reschedule the reset later.
 	 */
-	if (READ_ONCE(efx->state) != STATE_READY)
+	if (!efx_net_active(READ_ONCE(efx->state)))
 		return;
 
 	/* efx_process_channel() will no longer read events once a
@@ -1214,7 +1216,7 @@
 	rtnl_lock();
 
 	if (efx->state != STATE_DISABLED) {
-		efx->state = STATE_RECOVERY;
+		efx->state = efx_recover(efx->state);
 		efx->reset_pending = 0;
 
 		efx_device_detach_sync(efx);
@@ -1268,7 +1270,7 @@
 		netif_err(efx, hw, efx->net_dev,
 			  "efx_reset failed after PCI error (%d)\n", rc);
 	} else {
-		efx->state = STATE_READY;
+		efx->state = efx_recovered(efx->state);
 		netif_dbg(efx, hw, efx->net_dev,
 			  "Done resetting and resuming IO after PCI error.\n");
 	}
diff --git a/kernel/drivers/net/ethernet/sfc/efx_common.h b/kernel/drivers/net/ethernet/sfc/efx_common.h
index 65513fd..c72e819 100644
--- a/kernel/drivers/net/ethernet/sfc/efx_common.h
+++ b/kernel/drivers/net/ethernet/sfc/efx_common.h
@@ -45,9 +45,7 @@
 
 #define EFX_ASSERT_RESET_SERIALISED(efx)		\
 	do {						\
-		if ((efx->state == STATE_READY) ||	\
-		    (efx->state == STATE_RECOVERY) ||	\
-		    (efx->state == STATE_DISABLED))	\
+		if (efx->state != STATE_UNINIT)		\
 			ASSERT_RTNL();			\
 	} while (0)
 
@@ -64,7 +62,7 @@
 
 static inline int efx_check_disabled(struct efx_nic *efx)
 {
-	if (efx->state == STATE_DISABLED || efx->state == STATE_RECOVERY) {
+	if (efx->state == STATE_DISABLED || efx_recovering(efx->state)) {
 		netif_err(efx, drv, efx->net_dev,
 			  "device is disabled due to earlier errors\n");
 		return -EIO;
diff --git a/kernel/drivers/net/ethernet/sfc/ethtool_common.c b/kernel/drivers/net/ethernet/sfc/ethtool_common.c
index bd552c7..3846b76 100644
--- a/kernel/drivers/net/ethernet/sfc/ethtool_common.c
+++ b/kernel/drivers/net/ethernet/sfc/ethtool_common.c
@@ -137,7 +137,7 @@
 	if (!efx_tests)
 		goto fail;
 
-	if (efx->state != STATE_READY) {
+	if (!efx_net_active(efx->state)) {
 		rc = -EBUSY;
 		goto out;
 	}
diff --git a/kernel/drivers/net/ethernet/sfc/mcdi_port_common.c b/kernel/drivers/net/ethernet/sfc/mcdi_port_common.c
index c4fe3c4..eccb97a 100644
--- a/kernel/drivers/net/ethernet/sfc/mcdi_port_common.c
+++ b/kernel/drivers/net/ethernet/sfc/mcdi_port_common.c
@@ -974,12 +974,15 @@
 
 	/* A QSFP+ NIC may actually have an SFP+ module attached.
 	 * The ID is page 0, byte 0.
+	 * QSFP28 is of type SFF_8636, however, this is treated
+	 * the same by ethtool, so we can also treat them the same.
 	 */
 	switch (efx_mcdi_phy_get_module_eeprom_byte(efx, 0, 0)) {
-	case 0x3:
+	case 0x3: /* SFP */
 		return MC_CMD_MEDIA_SFP_PLUS;
-	case 0xc:
-	case 0xd:
+	case 0xc: /* QSFP */
+	case 0xd: /* QSFP+ */
+	case 0x11: /* QSFP28 */
 		return MC_CMD_MEDIA_QSFP_PLUS;
 	default:
 		return 0;
@@ -1077,7 +1080,7 @@
 
 	case MC_CMD_MEDIA_QSFP_PLUS:
 		modinfo->type = ETH_MODULE_SFF_8436;
-		modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
+		modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
 		break;
 
 	default:
diff --git a/kernel/drivers/net/ethernet/sfc/net_driver.h b/kernel/drivers/net/ethernet/sfc/net_driver.h
index 8aecb4b..39f9792 100644
--- a/kernel/drivers/net/ethernet/sfc/net_driver.h
+++ b/kernel/drivers/net/ethernet/sfc/net_driver.h
@@ -627,12 +627,54 @@
 #define EFX_INT_MODE_USE_MSI(x) (((x)->interrupt_mode) <= EFX_INT_MODE_MSI)
 
 enum nic_state {
-	STATE_UNINIT = 0,	/* device being probed/removed or is frozen */
-	STATE_READY = 1,	/* hardware ready and netdev registered */
-	STATE_DISABLED = 2,	/* device disabled due to hardware errors */
-	STATE_RECOVERY = 3,	/* device recovering from PCI error */
+	STATE_UNINIT = 0,	/* device being probed/removed */
+	STATE_NET_DOWN,		/* hardware probed and netdev registered */
+	STATE_NET_UP,		/* ready for traffic */
+	STATE_DISABLED,		/* device disabled due to hardware errors */
+
+	STATE_RECOVERY = 0x100,/* recovering from PCI error */
+	STATE_FROZEN = 0x200,	/* frozen by power management */
 };
 
+static inline bool efx_net_active(enum nic_state state)
+{
+	return state == STATE_NET_DOWN || state == STATE_NET_UP;
+}
+
+static inline bool efx_frozen(enum nic_state state)
+{
+	return state & STATE_FROZEN;
+}
+
+static inline bool efx_recovering(enum nic_state state)
+{
+	return state & STATE_RECOVERY;
+}
+
+static inline enum nic_state efx_freeze(enum nic_state state)
+{
+	WARN_ON(!efx_net_active(state));
+	return state | STATE_FROZEN;
+}
+
+static inline enum nic_state efx_thaw(enum nic_state state)
+{
+	WARN_ON(!efx_frozen(state));
+	return state & ~STATE_FROZEN;
+}
+
+static inline enum nic_state efx_recover(enum nic_state state)
+{
+	WARN_ON(!efx_net_active(state));
+	return state | STATE_RECOVERY;
+}
+
+static inline enum nic_state efx_recovered(enum nic_state state)
+{
+	WARN_ON(!efx_recovering(state));
+	return state & ~STATE_RECOVERY;
+}
+
 /* Forward declaration */
 struct efx_nic;
 
diff --git a/kernel/drivers/net/ethernet/socionext/netsec.c b/kernel/drivers/net/ethernet/socionext/netsec.c
index b9acee2..bb86315 100644
--- a/kernel/drivers/net/ethernet/socionext/netsec.c
+++ b/kernel/drivers/net/ethernet/socionext/netsec.c
@@ -1845,6 +1845,17 @@
 		return err;
 	}
 
+	/*
+	 * SynQuacer is physically configured with TX and RX delays
+	 * but the standard firmware claimed otherwise for a long
+	 * time, ignore it.
+	 */
+	if (of_machine_is_compatible("socionext,developer-box") &&
+	    priv->phy_interface != PHY_INTERFACE_MODE_RGMII_ID) {
+		dev_warn(&pdev->dev, "Outdated firmware reports incorrect PHY mode, overriding\n");
+		priv->phy_interface = PHY_INTERFACE_MODE_RGMII_ID;
+	}
+
 	priv->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
 	if (!priv->phy_np) {
 		dev_err(&pdev->dev, "missing required property 'phy-handle'\n");
diff --git a/kernel/drivers/net/ethernet/stmicro/stmmac/common.h b/kernel/drivers/net/ethernet/stmicro/stmmac/common.h
index 37658d7..b6eac66 100644
--- a/kernel/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/kernel/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -488,7 +488,6 @@
 	unsigned int xlgmac;
 	unsigned int num_vlan;
 	u32 vlan_filter[32];
-	unsigned int promisc;
 	bool vlan_fail_q_en;
 	u8 vlan_fail_q;
 };
diff --git a/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index bfc4a92..78be62e 100644
--- a/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -505,6 +505,8 @@
 	plat_dat->has_gmac4 = 1;
 	plat_dat->pmt = 1;
 	plat_dat->tso_en = of_property_read_bool(np, "snps,tso");
+	if (of_device_is_compatible(np, "qcom,qcs404-ethqos"))
+		plat_dat->rx_clk_runs_in_lpi = 1;
 
 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
 	if (ret)
diff --git a/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
index 5d4df4c..6623f5a 100644
--- a/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -105,6 +105,7 @@
 	int (*parse_data)(struct stm32_dwmac *dwmac,
 			  struct device *dev);
 	u32 syscfg_eth_mask;
+	bool clk_rx_enable_in_suspend;
 };
 
 static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat)
@@ -122,7 +123,8 @@
 	if (ret)
 		return ret;
 
-	if (!dwmac->dev->power.is_suspended) {
+	if (!dwmac->ops->clk_rx_enable_in_suspend ||
+	    !dwmac->dev->power.is_suspended) {
 		ret = clk_prepare_enable(dwmac->clk_rx);
 		if (ret) {
 			clk_disable_unprepare(dwmac->clk_tx);
@@ -515,7 +517,8 @@
 	.suspend = stm32mp1_suspend,
 	.resume = stm32mp1_resume,
 	.parse_data = stm32mp1_parse_data,
-	.syscfg_eth_mask = SYSCFG_MP1_ETH_MASK
+	.syscfg_eth_mask = SYSCFG_MP1_ETH_MASK,
+	.clk_rx_enable_in_suspend = true
 };
 
 static const struct of_device_id stm32_dwmac_match[] = {
diff --git a/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index b248c80..ec3ecb5 100644
--- a/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -453,12 +453,6 @@
 	if (vid > 4095)
 		return -EINVAL;
 
-	if (hw->promisc) {
-		netdev_err(dev,
-			   "Adding VLAN in promisc mode not supported\n");
-		return -EPERM;
-	}
-
 	/* Single Rx VLAN Filter */
 	if (hw->num_vlan == 1) {
 		/* For single VLAN filter, VID 0 means VLAN promiscuous */
@@ -508,12 +502,6 @@
 {
 	int i, ret = 0;
 
-	if (hw->promisc) {
-		netdev_err(dev,
-			   "Deleting VLAN in promisc mode not supported\n");
-		return -EPERM;
-	}
-
 	/* Single Rx VLAN Filter */
 	if (hw->num_vlan == 1) {
 		if ((hw->vlan_filter[0] & GMAC_VLAN_TAG_VID) == vid) {
@@ -536,39 +524,6 @@
 	}
 
 	return ret;
-}
-
-static void dwmac4_vlan_promisc_enable(struct net_device *dev,
-				       struct mac_device_info *hw)
-{
-	void __iomem *ioaddr = hw->pcsr;
-	u32 value;
-	u32 hash;
-	u32 val;
-	int i;
-
-	/* Single Rx VLAN Filter */
-	if (hw->num_vlan == 1) {
-		dwmac4_write_single_vlan(dev, 0);
-		return;
-	}
-
-	/* Extended Rx VLAN Filter Enable */
-	for (i = 0; i < hw->num_vlan; i++) {
-		if (hw->vlan_filter[i] & GMAC_VLAN_TAG_DATA_VEN) {
-			val = hw->vlan_filter[i] & ~GMAC_VLAN_TAG_DATA_VEN;
-			dwmac4_write_vlan_filter(dev, hw, i, val);
-		}
-	}
-
-	hash = readl(ioaddr + GMAC_VLAN_HASH_TABLE);
-	if (hash & GMAC_VLAN_VLHT) {
-		value = readl(ioaddr + GMAC_VLAN_TAG);
-		if (value & GMAC_VLAN_VTHM) {
-			value &= ~GMAC_VLAN_VTHM;
-			writel(value, ioaddr + GMAC_VLAN_TAG);
-		}
-	}
 }
 
 static void dwmac4_restore_hw_vlan_rx_fltr(struct net_device *dev,
@@ -690,22 +645,12 @@
 	}
 
 	/* VLAN filtering */
-	if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
+	if (dev->flags & IFF_PROMISC && !hw->vlan_fail_q_en)
+		value &= ~GMAC_PACKET_FILTER_VTFE;
+	else if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
 		value |= GMAC_PACKET_FILTER_VTFE;
 
 	writel(value, ioaddr + GMAC_PACKET_FILTER);
-
-	if (dev->flags & IFF_PROMISC && !hw->vlan_fail_q_en) {
-		if (!hw->promisc) {
-			hw->promisc = 1;
-			dwmac4_vlan_promisc_enable(dev, hw);
-		}
-	} else {
-		if (hw->promisc) {
-			hw->promisc = 0;
-			dwmac4_restore_hw_vlan_rx_fltr(dev, hw);
-		}
-	}
 }
 
 static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
diff --git a/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac5.c b/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
index de5255b..d1b8b51 100644
--- a/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
+++ b/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
@@ -520,9 +520,9 @@
 		return 0;
 	}
 
-	val |= PPSCMDx(index, 0x2);
 	val |= TRGTMODSELx(index, 0x2);
 	val |= PPSEN0;
+	writel(val, ioaddr + MAC_PPS_CONTROL);
 
 	writel(cfg->start.tv_sec, ioaddr + MAC_PPSx_TARGET_TIME_SEC(index));
 
@@ -547,6 +547,7 @@
 	writel(period - 1, ioaddr + MAC_PPSx_WIDTH(index));
 
 	/* Finally, activate it */
+	val |= PPSCMDx(index, 0x2);
 	writel(val, ioaddr + MAC_PPS_CONTROL);
 	return 0;
 }
diff --git a/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
index 53efcc9..0ad5ce8 100644
--- a/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
+++ b/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
@@ -44,7 +44,8 @@
 	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/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 471c8c3..de691d4 100644
--- a/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -562,7 +562,7 @@
 	dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst");
 
 	plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode");
-	if (plat->force_thresh_dma_mode) {
+	if (plat->force_thresh_dma_mode && plat->force_sf_dma_mode) {
 		plat->force_sf_dma_mode = 0;
 		dev_warn(&pdev->dev,
 			 "force_sf_dma_mode is ignored if force_thresh_dma_mode is set.\n");
diff --git a/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h b/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
index 7abb1d4..60e6b08 100644
--- a/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
+++ b/kernel/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__ */
diff --git a/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
index dd5c4ef..ea7200b 100644
--- a/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+++ b/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
@@ -1654,12 +1654,16 @@
 	}
 
 	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)
diff --git a/kernel/drivers/net/ethernet/sun/cassini.c b/kernel/drivers/net/ethernet/sun/cassini.c
index 9ff894b..b929c6f 100644
--- a/kernel/drivers/net/ethernet/sun/cassini.c
+++ b/kernel/drivers/net/ethernet/sun/cassini.c
@@ -1325,7 +1325,7 @@
 	writel(val, cp->regs + REG_RX_PAGE_SIZE);
 
 	/* enable the header parser if desired */
-	if (CAS_HP_FIRMWARE == cas_prog_null)
+	if (&CAS_HP_FIRMWARE[0] == &cas_prog_null[0])
 		return;
 
 	val = CAS_BASE(HP_CFG_NUM_CPU, CAS_NCPUS > 63 ? 0 : CAS_NCPUS);
@@ -3793,7 +3793,7 @@
 
 	/* program header parser */
 	if ((cp->cas_flags & CAS_FLAG_TARGET_ABORT) ||
-	    (CAS_HP_ALT_FIRMWARE == cas_prog_null)) {
+	    (&CAS_HP_ALT_FIRMWARE[0] == &cas_prog_null[0])) {
 		cas_load_firmware(cp, CAS_HP_FIRMWARE);
 	} else {
 		cas_load_firmware(cp, CAS_HP_ALT_FIRMWARE);
@@ -5122,6 +5122,8 @@
 		cas_shutdown(cp);
 	mutex_unlock(&cp->pm_mutex);
 
+	vfree(cp->fw_data);
+
 	pci_iounmap(pdev, cp->regs);
 
 
diff --git a/kernel/drivers/net/ethernet/sun/ldmvsw.c b/kernel/drivers/net/ethernet/sun/ldmvsw.c
index 01ea0d6..934a4b5 100644
--- a/kernel/drivers/net/ethernet/sun/ldmvsw.c
+++ b/kernel/drivers/net/ethernet/sun/ldmvsw.c
@@ -290,6 +290,9 @@
 
 	hp = mdesc_grab();
 
+	if (!hp)
+		return -ENODEV;
+
 	rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len);
 	err = -ENODEV;
 	if (!rmac) {
diff --git a/kernel/drivers/net/ethernet/sun/niu.c b/kernel/drivers/net/ethernet/sun/niu.c
index 860644d..1a269fa 100644
--- a/kernel/drivers/net/ethernet/sun/niu.c
+++ b/kernel/drivers/net/ethernet/sun/niu.c
@@ -4503,7 +4503,7 @@
 
 		err = niu_rbr_fill(np, rp, GFP_KERNEL);
 		if (err)
-			return err;
+			goto out_err;
 	}
 
 	tx_rings = kcalloc(num_tx_rings, sizeof(struct tx_ring_info),
diff --git a/kernel/drivers/net/ethernet/sun/sunvnet.c b/kernel/drivers/net/ethernet/sun/sunvnet.c
index 96b883f..b6c03ad 100644
--- a/kernel/drivers/net/ethernet/sun/sunvnet.c
+++ b/kernel/drivers/net/ethernet/sun/sunvnet.c
@@ -431,6 +431,9 @@
 
 	hp = mdesc_grab();
 
+	if (!hp)
+		return -ENODEV;
+
 	vp = vnet_find_parent(hp, vdev->mp, vdev);
 	if (IS_ERR(vp)) {
 		pr_err("Cannot find port parent vnet\n");
diff --git a/kernel/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/kernel/drivers/net/ethernet/ti/am65-cpsw-nuss.c
index 059d68d..d103244 100644
--- a/kernel/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+++ b/kernel/drivers/net/ethernet/ti/am65-cpsw-nuss.c
@@ -426,9 +426,7 @@
 	writel(common->rx_flow_id_base,
 	       host_p->port_base + AM65_CPSW_PORT0_REG_FLOW_ID_OFFSET);
 	/* en tx crc offload */
-	if (features & NETIF_F_HW_CSUM)
-		writel(AM65_CPSW_P0_REG_CTL_RX_CHECKSUM_EN,
-		       host_p->port_base + AM65_CPSW_P0_REG_CTL);
+	writel(AM65_CPSW_P0_REG_CTL_RX_CHECKSUM_EN, host_p->port_base + AM65_CPSW_P0_REG_CTL);
 
 	am65_cpsw_nuss_set_p0_ptype(common);
 
@@ -1369,31 +1367,6 @@
 	stats->tx_dropped	= dev->stats.tx_dropped;
 }
 
-static int am65_cpsw_nuss_ndo_slave_set_features(struct net_device *ndev,
-						 netdev_features_t features)
-{
-	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
-	netdev_features_t changes = features ^ ndev->features;
-	struct am65_cpsw_host *host_p;
-
-	host_p = am65_common_get_host(common);
-
-	if (changes & NETIF_F_HW_CSUM) {
-		bool enable = !!(features & NETIF_F_HW_CSUM);
-
-		dev_info(common->dev, "Turn %s tx-checksum-ip-generic\n",
-			 enable ? "ON" : "OFF");
-		if (enable)
-			writel(AM65_CPSW_P0_REG_CTL_RX_CHECKSUM_EN,
-			       host_p->port_base + AM65_CPSW_P0_REG_CTL);
-		else
-			writel(0,
-			       host_p->port_base + AM65_CPSW_P0_REG_CTL);
-	}
-
-	return 0;
-}
-
 static const struct net_device_ops am65_cpsw_nuss_netdev_ops_2g = {
 	.ndo_open		= am65_cpsw_nuss_ndo_slave_open,
 	.ndo_stop		= am65_cpsw_nuss_ndo_slave_stop,
@@ -1406,7 +1379,6 @@
 	.ndo_vlan_rx_add_vid	= am65_cpsw_nuss_ndo_slave_add_vid,
 	.ndo_vlan_rx_kill_vid	= am65_cpsw_nuss_ndo_slave_kill_vid,
 	.ndo_do_ioctl		= am65_cpsw_nuss_ndo_slave_ioctl,
-	.ndo_set_features	= am65_cpsw_nuss_ndo_slave_set_features,
 	.ndo_setup_tc           = am65_cpsw_qos_ndo_setup_tc,
 };
 
@@ -1515,9 +1487,8 @@
 						    tx_chn->tx_chn_name,
 						    &tx_cfg);
 		if (IS_ERR(tx_chn->tx_chn)) {
-			ret = PTR_ERR(tx_chn->tx_chn);
-			dev_err(dev, "Failed to request tx dma channel %d\n",
-				ret);
+			ret = dev_err_probe(dev, PTR_ERR(tx_chn->tx_chn),
+					    "Failed to request tx dma channel\n");
 			goto err;
 		}
 
@@ -1525,6 +1496,7 @@
 		if (tx_chn->irq <= 0) {
 			dev_err(dev, "Failed to get tx dma irq %d\n",
 				tx_chn->irq);
+			ret = tx_chn->irq ?: -ENXIO;
 			goto err;
 		}
 
@@ -1588,8 +1560,8 @@
 
 	rx_chn->rx_chn = k3_udma_glue_request_rx_chn(dev, "rx", &rx_cfg);
 	if (IS_ERR(rx_chn->rx_chn)) {
-		ret = PTR_ERR(rx_chn->rx_chn);
-		dev_err(dev, "Failed to request rx dma channel %d\n", ret);
+		ret = dev_err_probe(dev, PTR_ERR(rx_chn->rx_chn),
+				    "Failed to request rx dma channel\n");
 		goto err;
 	}
 
@@ -1753,13 +1725,14 @@
 		if (ret < 0) {
 			dev_err(dev, "%pOF error reading port_id %d\n",
 				port_np, ret);
-			return ret;
+			goto of_node_put;
 		}
 
 		if (!port_id || port_id > common->port_num) {
 			dev_err(dev, "%pOF has invalid port_id %u %s\n",
 				port_np, port_id, port_np->name);
-			return -EINVAL;
+			ret = -EINVAL;
+			goto of_node_put;
 		}
 
 		port = am65_common_get_port(common, port_id);
@@ -1775,8 +1748,10 @@
 				(AM65_CPSW_NU_FRAM_PORT_OFFSET * (port_id - 1));
 
 		port->slave.mac_sl = cpsw_sl_get("am65", dev, port->port_base);
-		if (IS_ERR(port->slave.mac_sl))
-			return PTR_ERR(port->slave.mac_sl);
+		if (IS_ERR(port->slave.mac_sl)) {
+			ret = PTR_ERR(port->slave.mac_sl);
+			goto of_node_put;
+		}
 
 		port->disabled = !of_device_is_available(port_np);
 		if (port->disabled)
@@ -1787,7 +1762,7 @@
 			ret = PTR_ERR(port->slave.ifphy);
 			dev_err(dev, "%pOF error retrieving port phy: %d\n",
 				port_np, ret);
-			return ret;
+			goto of_node_put;
 		}
 
 		port->slave.mac_only =
@@ -1797,10 +1772,10 @@
 		if (of_phy_is_fixed_link(port_np)) {
 			ret = of_phy_register_fixed_link(port_np);
 			if (ret) {
-				if (ret != -EPROBE_DEFER)
-					dev_err(dev, "%pOF failed to register fixed-link phy: %d\n",
-						port_np, ret);
-				return ret;
+				ret = dev_err_probe(dev, ret,
+						     "failed to register fixed-link phy %pOF\n",
+						     port_np);
+				goto of_node_put;
 			}
 			port->slave.phy_node = of_node_get(port_np);
 		} else {
@@ -1811,14 +1786,15 @@
 		if (!port->slave.phy_node) {
 			dev_err(dev,
 				"slave[%d] no phy found\n", port_id);
-			return -ENODEV;
+			ret = -ENODEV;
+			goto of_node_put;
 		}
 
 		ret = of_get_phy_mode(port_np, &port->slave.phy_if);
 		if (ret) {
 			dev_err(dev, "%pOF read phy-mode err %d\n",
 				port_np, ret);
-			return ret;
+			goto of_node_put;
 		}
 
 		mac_addr = of_get_mac_address(port_np);
@@ -1835,6 +1811,11 @@
 	of_node_put(node);
 
 	return 0;
+
+of_node_put:
+	of_node_put(port_np);
+	of_node_put(node);
+	return ret;
 }
 
 static void am65_cpsw_pcpu_stats_free(void *data)
@@ -2090,13 +2071,8 @@
 		return -ENOMEM;
 
 	clk = devm_clk_get(dev, "fck");
-	if (IS_ERR(clk)) {
-		ret = PTR_ERR(clk);
-
-		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "error getting fck clock %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(clk))
+		return dev_err_probe(dev, PTR_ERR(clk), "getting fck clock\n");
 	common->bus_freq = clk_get_rate(clk);
 
 	pm_runtime_enable(dev);
@@ -2178,7 +2154,8 @@
 	return 0;
 
 err_of_clear:
-	of_platform_device_destroy(common->mdio_dev, NULL);
+	if (common->mdio_dev)
+		of_platform_device_destroy(common->mdio_dev, NULL);
 err_pm_clear:
 	pm_runtime_put_sync(dev);
 	pm_runtime_disable(dev);
@@ -2204,7 +2181,8 @@
 	 */
 	am65_cpsw_nuss_cleanup_ndev(common);
 
-	of_platform_device_destroy(common->mdio_dev, NULL);
+	if (common->mdio_dev)
+		of_platform_device_destroy(common->mdio_dev, NULL);
 
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
diff --git a/kernel/drivers/net/ethernet/ti/cpsw_ale.c b/kernel/drivers/net/ethernet/ti/cpsw_ale.c
index a6a455c..73efc8b 100644
--- a/kernel/drivers/net/ethernet/ti/cpsw_ale.c
+++ b/kernel/drivers/net/ethernet/ti/cpsw_ale.c
@@ -104,23 +104,37 @@
 
 static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
 {
-	int idx;
+	int idx, idx2;
+	u32 hi_val = 0;
 
 	idx    = start / 32;
+	idx2 = (start + bits - 1) / 32;
+	/* Check if bits to be fetched exceed a word */
+	if (idx != idx2) {
+		idx2 = 2 - idx2; /* flip */
+		hi_val = ale_entry[idx2] << ((idx2 * 32) - start);
+	}
 	start -= idx * 32;
 	idx    = 2 - idx; /* flip */
-	return (ale_entry[idx] >> start) & BITMASK(bits);
+	return (hi_val + (ale_entry[idx] >> start)) & BITMASK(bits);
 }
 
 static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
 				      u32 value)
 {
-	int idx;
+	int idx, idx2;
 
 	value &= BITMASK(bits);
-	idx    = start / 32;
+	idx = start / 32;
+	idx2 = (start + bits - 1) / 32;
+	/* Check if bits to be set exceed a word */
+	if (idx != idx2) {
+		idx2 = 2 - idx2; /* flip */
+		ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32)));
+		ale_entry[idx2] |= (value >> ((idx2 * 32) - start));
+	}
 	start -= idx * 32;
-	idx    = 2 - idx; /* flip */
+	idx = 2 - idx; /* flip */
 	ale_entry[idx] &= ~(BITMASK(bits) << start);
 	ale_entry[idx] |=  (value << start);
 }
diff --git a/kernel/drivers/net/ethernet/ti/netcp_core.c b/kernel/drivers/net/ethernet/ti/netcp_core.c
index dc50e94..f145abb 100644
--- a/kernel/drivers/net/ethernet/ti/netcp_core.c
+++ b/kernel/drivers/net/ethernet/ti/netcp_core.c
@@ -1262,7 +1262,7 @@
 }
 
 /* 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;
diff --git a/kernel/drivers/net/ethernet/toshiba/ps3_gelic_net.c b/kernel/drivers/net/ethernet/toshiba/ps3_gelic_net.c
index d9a5722..524098a 100644
--- a/kernel/drivers/net/ethernet/toshiba/ps3_gelic_net.c
+++ b/kernel/drivers/net/ethernet/toshiba/ps3_gelic_net.c
@@ -317,15 +317,17 @@
 
 	/* set up the hardware pointers in each descriptor */
 	for (i = 0; i < no; i++, descr++) {
-		gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
-		descr->bus_addr =
-			dma_map_single(ctodev(card), descr,
-				       GELIC_DESCR_SIZE,
-				       DMA_BIDIRECTIONAL);
+		dma_addr_t cpu_addr;
 
-		if (!descr->bus_addr)
+		gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
+
+		cpu_addr = dma_map_single(ctodev(card), descr,
+					  GELIC_DESCR_SIZE, DMA_BIDIRECTIONAL);
+
+		if (dma_mapping_error(ctodev(card), cpu_addr))
 			goto iommu_error;
 
+		descr->bus_addr = cpu_to_be32(cpu_addr);
 		descr->next = descr + 1;
 		descr->prev = descr - 1;
 	}
@@ -365,26 +367,28 @@
  *
  * allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
  * Activate the descriptor state-wise
+ *
+ * Gelic RX sk_buffs must be aligned to GELIC_NET_RXBUF_ALIGN and the length
+ * must be a multiple of GELIC_NET_RXBUF_ALIGN.
  */
 static int gelic_descr_prepare_rx(struct gelic_card *card,
 				  struct gelic_descr *descr)
 {
+	static const unsigned int rx_skb_size =
+		ALIGN(GELIC_NET_MAX_FRAME, GELIC_NET_RXBUF_ALIGN) +
+		GELIC_NET_RXBUF_ALIGN - 1;
+	dma_addr_t cpu_addr;
 	int offset;
-	unsigned int bufsize;
 
 	if (gelic_descr_get_status(descr) !=  GELIC_DESCR_DMA_NOT_IN_USE)
 		dev_info(ctodev(card), "%s: ERROR status\n", __func__);
-	/* we need to round up the buffer size to a multiple of 128 */
-	bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN);
 
-	/* and we need to have it 128 byte aligned, therefore we allocate a
-	 * bit more */
-	descr->skb = dev_alloc_skb(bufsize + GELIC_NET_RXBUF_ALIGN - 1);
+	descr->skb = netdev_alloc_skb(*card->netdev, rx_skb_size);
 	if (!descr->skb) {
 		descr->buf_addr = 0; /* tell DMAC don't touch memory */
 		return -ENOMEM;
 	}
-	descr->buf_size = cpu_to_be32(bufsize);
+	descr->buf_size = cpu_to_be32(rx_skb_size);
 	descr->dmac_cmd_status = 0;
 	descr->result_size = 0;
 	descr->valid_size = 0;
@@ -395,11 +399,10 @@
 	if (offset)
 		skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset);
 	/* io-mmu-map the skb */
-	descr->buf_addr = cpu_to_be32(dma_map_single(ctodev(card),
-						     descr->skb->data,
-						     GELIC_NET_MAX_MTU,
-						     DMA_FROM_DEVICE));
-	if (!descr->buf_addr) {
+	cpu_addr = dma_map_single(ctodev(card), descr->skb->data,
+				  GELIC_NET_MAX_FRAME, DMA_FROM_DEVICE);
+	descr->buf_addr = cpu_to_be32(cpu_addr);
+	if (dma_mapping_error(ctodev(card), cpu_addr)) {
 		dev_kfree_skb_any(descr->skb);
 		descr->skb = NULL;
 		dev_info(ctodev(card),
@@ -779,7 +782,7 @@
 
 	buf = dma_map_single(ctodev(card), skb->data, skb->len, DMA_TO_DEVICE);
 
-	if (!buf) {
+	if (dma_mapping_error(ctodev(card), buf)) {
 		dev_err(ctodev(card),
 			"dma map 2 failed (%p, %i). Dropping packet\n",
 			skb->data, skb->len);
@@ -915,7 +918,7 @@
 	data_error = be32_to_cpu(descr->data_error);
 	/* unmap skb buffer */
 	dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr),
-			 GELIC_NET_MAX_MTU,
+			 GELIC_NET_MAX_FRAME,
 			 DMA_FROM_DEVICE);
 
 	skb_put(skb, be32_to_cpu(descr->valid_size)?
diff --git a/kernel/drivers/net/ethernet/toshiba/ps3_gelic_net.h b/kernel/drivers/net/ethernet/toshiba/ps3_gelic_net.h
index 68f324e..0d98def 100644
--- a/kernel/drivers/net/ethernet/toshiba/ps3_gelic_net.h
+++ b/kernel/drivers/net/ethernet/toshiba/ps3_gelic_net.h
@@ -19,8 +19,9 @@
 #define GELIC_NET_RX_DESCRIPTORS        128 /* num of descriptors */
 #define GELIC_NET_TX_DESCRIPTORS        128 /* num of descriptors */
 
-#define GELIC_NET_MAX_MTU               VLAN_ETH_FRAME_LEN
-#define GELIC_NET_MIN_MTU               VLAN_ETH_ZLEN
+#define GELIC_NET_MAX_FRAME             2312
+#define GELIC_NET_MAX_MTU               2294
+#define GELIC_NET_MIN_MTU               64
 #define GELIC_NET_RXBUF_ALIGN           128
 #define GELIC_CARD_RX_CSUM_DEFAULT      1 /* hw chksum */
 #define GELIC_NET_WATCHDOG_TIMEOUT      5*HZ
diff --git a/kernel/drivers/net/ethernet/xilinx/ll_temac_main.c b/kernel/drivers/net/ethernet/xilinx/ll_temac_main.c
index 130f4b7..da136ab 100644
--- a/kernel/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/kernel/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -1550,15 +1550,15 @@
 	}
 
 	/* Error handle returned DMA RX and TX interrupts */
-	if (lp->rx_irq < 0) {
-		if (lp->rx_irq != -EPROBE_DEFER)
-			dev_err(&pdev->dev, "could not get DMA RX irq\n");
-		return lp->rx_irq;
+	if (lp->rx_irq <= 0) {
+		rc = lp->rx_irq ?: -EINVAL;
+		return dev_err_probe(&pdev->dev, rc,
+				     "could not get DMA RX irq\n");
 	}
-	if (lp->tx_irq < 0) {
-		if (lp->tx_irq != -EPROBE_DEFER)
-			dev_err(&pdev->dev, "could not get DMA TX irq\n");
-		return lp->tx_irq;
+	if (lp->tx_irq <= 0) {
+		rc = lp->tx_irq ?: -EINVAL;
+		return dev_err_probe(&pdev->dev, rc,
+				     "could not get DMA TX irq\n");
 	}
 
 	if (temac_np) {
diff --git a/kernel/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/kernel/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 3d91baf..9d36228 100644
--- a/kernel/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/kernel/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -2009,6 +2009,11 @@
 		goto cleanup_clk;
 	}
 
+	/* Reset core now that clocks are enabled, prior to accessing MDIO */
+	ret = __axienet_device_reset(lp);
+	if (ret)
+		goto cleanup_clk;
+
 	/* Autodetect the need for 64-bit DMA pointers.
 	 * When the IP is configured for a bus width bigger than 32 bits,
 	 * writing the MSB registers is mandatory, even if they are all 0.
@@ -2054,11 +2059,6 @@
 
 	lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD;
 	lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD;
-
-	/* Reset core now that clocks are enabled, prior to accessing MDIO */
-	ret = __axienet_device_reset(lp);
-	if (ret)
-		goto cleanup_clk;
 
 	ret = axienet_mdio_setup(lp);
 	if (ret)
diff --git a/kernel/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/kernel/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index f6ea4a0..02b95af 100644
--- a/kernel/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/kernel/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -541,7 +541,7 @@
 	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++;
 	}
diff --git a/kernel/drivers/net/ethernet/xircom/xirc2ps_cs.c b/kernel/drivers/net/ethernet/xircom/xirc2ps_cs.c
index 3e33714..56cef59 100644
--- a/kernel/drivers/net/ethernet/xircom/xirc2ps_cs.c
+++ b/kernel/drivers/net/ethernet/xircom/xirc2ps_cs.c
@@ -503,6 +503,11 @@
 xirc2ps_detach(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
+    struct local_info *local = netdev_priv(dev);
+
+    netif_carrier_off(dev);
+    netif_tx_disable(dev);
+    cancel_work_sync(&local->tx_timeout_task);
 
     dev_dbg(&link->dev, "detach\n");
 
diff --git a/kernel/drivers/net/fddi/defxx.c b/kernel/drivers/net/fddi/defxx.c
index c7ce6d5..442bdc6 100644
--- a/kernel/drivers/net/fddi/defxx.c
+++ b/kernel/drivers/net/fddi/defxx.c
@@ -3844,10 +3844,24 @@
 	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;
 }
 
diff --git a/kernel/drivers/net/gtp.c b/kernel/drivers/net/gtp.c
index 1c46bc4..05ea3a1 100644
--- a/kernel/drivers/net/gtp.c
+++ b/kernel/drivers/net/gtp.c
@@ -291,7 +291,9 @@
 			gtp->sk1u = NULL;
 		udp_sk(sk)->encap_type = 0;
 		rcu_assign_sk_user_data(sk, NULL);
+		release_sock(sk);
 		sock_put(sk);
+		return;
 	}
 	release_sock(sk);
 }
diff --git a/kernel/drivers/net/hamradio/baycom_epp.c b/kernel/drivers/net/hamradio/baycom_epp.c
index e4e4981..eea9d47 100644
--- a/kernel/drivers/net/hamradio/baycom_epp.c
+++ b/kernel/drivers/net/hamradio/baycom_epp.c
@@ -758,7 +758,7 @@
  * ===================== 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);
 
diff --git a/kernel/drivers/net/hamradio/scc.c b/kernel/drivers/net/hamradio/scc.c
index 36eeb80..eeb6c47 100644
--- a/kernel/drivers/net/hamradio/scc.c
+++ b/kernel/drivers/net/hamradio/scc.c
@@ -300,12 +300,12 @@
 	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 @@
 	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);
diff --git a/kernel/drivers/net/ieee802154/ca8210.c b/kernel/drivers/net/ieee802154/ca8210.c
index 95ef3b6..1c5d70c 100644
--- a/kernel/drivers/net/ieee802154/ca8210.c
+++ b/kernel/drivers/net/ieee802154/ca8210.c
@@ -1945,10 +1945,9 @@
 	struct ca8210_priv  *priv
 )
 {
-	int status;
 	struct ieee802154_hdr header = { };
 	struct secspec secspec;
-	unsigned int mac_len;
+	int mac_len, status;
 
 	dev_dbg(&priv->spi->dev, "%s called\n", __func__);
 
@@ -1956,6 +1955,8 @@
 	 * packet
 	 */
 	mac_len = ieee802154_hdr_peek_addrs(skb, &header);
+	if (mac_len < 0)
+		return mac_len;
 
 	secspec.security_level = header.sec.level;
 	secspec.key_id_mode = header.sec.key_id_mode;
diff --git a/kernel/drivers/net/ieee802154/mac802154_hwsim.c b/kernel/drivers/net/ieee802154/mac802154_hwsim.c
index 97981cf..344f63b 100644
--- a/kernel/drivers/net/ieee802154/mac802154_hwsim.c
+++ b/kernel/drivers/net/ieee802154/mac802154_hwsim.c
@@ -522,7 +522,7 @@
 static int hwsim_set_edge_lqi(struct sk_buff *msg, struct genl_info *info)
 {
 	struct nlattr *edge_attrs[MAC802154_HWSIM_EDGE_ATTR_MAX + 1];
-	struct hwsim_edge_info *einfo;
+	struct hwsim_edge_info *einfo, *einfo_old;
 	struct hwsim_phy *phy_v0;
 	struct hwsim_edge *e;
 	u32 v0, v1;
@@ -560,8 +560,10 @@
 	list_for_each_entry_rcu(e, &phy_v0->edges, list) {
 		if (e->endpoint->idx == v1) {
 			einfo->lqi = lqi;
-			rcu_assign_pointer(e->info, einfo);
+			einfo_old = rcu_replace_pointer(e->info, einfo,
+							lockdep_is_held(&hwsim_phys_lock));
 			rcu_read_unlock();
+			kfree_rcu(einfo_old, rcu);
 			mutex_unlock(&hwsim_phys_lock);
 			return 0;
 		}
diff --git a/kernel/drivers/net/ipa/gsi_trans.c b/kernel/drivers/net/ipa/gsi_trans.c
index 70c2b58..1e0d626 100644
--- a/kernel/drivers/net/ipa/gsi_trans.c
+++ b/kernel/drivers/net/ipa/gsi_trans.c
@@ -159,7 +159,7 @@
 	 * gsi_trans_pool_exit_dma() can assume the total allocated
 	 * size is exactly (count * size).
 	 */
-	total_size = get_order(total_size) << PAGE_SHIFT;
+	total_size = PAGE_SIZE << get_order(total_size);
 
 	virt = dma_alloc_coherent(dev, total_size, &addr, GFP_KERNEL);
 	if (!virt)
diff --git a/kernel/drivers/net/ipvlan/ipvlan_core.c b/kernel/drivers/net/ipvlan/ipvlan_core.c
index a33149e..ab09d11 100644
--- a/kernel/drivers/net/ipvlan/ipvlan_core.c
+++ b/kernel/drivers/net/ipvlan/ipvlan_core.c
@@ -437,6 +437,9 @@
 		goto err;
 	}
 	skb_dst_set(skb, &rt->dst);
+
+	memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
+
 	err = ip_local_out(net, skb->sk, skb);
 	if (unlikely(net_xmit_eval(err)))
 		dev->stats.tx_errors++;
@@ -475,6 +478,9 @@
 		goto err;
 	}
 	skb_dst_set(skb, dst);
+
+	memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
+
 	err = ip6_local_out(net, skb->sk, skb);
 	if (unlikely(net_xmit_eval(err)))
 		dev->stats.tx_errors++;
@@ -580,7 +586,8 @@
 				consume_skb(skb);
 				return NET_XMIT_DROP;
 			}
-			return ipvlan_rcv_frame(addr, &skb, true);
+			ipvlan_rcv_frame(addr, &skb, true);
+			return NET_XMIT_SUCCESS;
 		}
 	}
 out:
@@ -606,7 +613,8 @@
 					consume_skb(skb);
 					return NET_XMIT_DROP;
 				}
-				return ipvlan_rcv_frame(addr, &skb, true);
+				ipvlan_rcv_frame(addr, &skb, true);
+				return NET_XMIT_SUCCESS;
 			}
 		}
 		skb = skb_share_check(skb, GFP_ATOMIC);
@@ -618,7 +626,8 @@
 		 * the skb for the main-dev. At the RX side we just return
 		 * RX_PASS for it to be processed further on the stack.
 		 */
-		return dev_forward_skb(ipvlan->phy_dev, skb);
+		dev_forward_skb(ipvlan->phy_dev, skb);
+		return NET_XMIT_SUCCESS;
 
 	} else if (is_multicast_ether_addr(eth->h_dest)) {
 		skb_reset_mac_header(skb);
diff --git a/kernel/drivers/net/ipvlan/ipvlan_l3s.c b/kernel/drivers/net/ipvlan/ipvlan_l3s.c
index 943d26c..d5b05e8 100644
--- a/kernel/drivers/net/ipvlan/ipvlan_l3s.c
+++ b/kernel/drivers/net/ipvlan/ipvlan_l3s.c
@@ -101,6 +101,11 @@
 		goto out;
 
 	skb->dev = addr->master->dev;
+	skb->skb_iif = skb->dev->ifindex;
+#if IS_ENABLED(CONFIG_IPV6)
+	if (addr->atype == IPVL_IPV6)
+		IP6CB(skb)->iif = skb->dev->ifindex;
+#endif
 	len = skb->len + ETH_HLEN;
 	ipvlan_count_rx(addr->master, len, true, false);
 out:
diff --git a/kernel/drivers/net/ipvlan/ipvlan_main.c b/kernel/drivers/net/ipvlan/ipvlan_main.c
index 60b7d93..93be7dd 100644
--- a/kernel/drivers/net/ipvlan/ipvlan_main.c
+++ b/kernel/drivers/net/ipvlan/ipvlan_main.c
@@ -745,7 +745,8 @@
 
 		write_pnet(&port->pnet, newnet);
 
-		ipvlan_migrate_l3s_hook(oldnet, newnet);
+		if (port->mode == IPVLAN_MODE_L3S)
+			ipvlan_migrate_l3s_hook(oldnet, newnet);
 		break;
 	}
 	case NETDEV_UNREGISTER:
diff --git a/kernel/drivers/net/macsec.c b/kernel/drivers/net/macsec.c
index eb02945..bc57832 100644
--- a/kernel/drivers/net/macsec.c
+++ b/kernel/drivers/net/macsec.c
@@ -1308,8 +1308,7 @@
 	struct crypto_aead *tfm;
 	int ret;
 
-	/* Pick a sync gcm(aes) cipher to ensure order is preserved. */
-	tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
+	tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
 
 	if (IS_ERR(tfm))
 		return tfm;
@@ -2584,7 +2583,7 @@
 	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 +2596,36 @@
 					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 +2660,7 @@
 
 rollback:
 	macsec->offload = prev_offload;
-
+out:
 	rtnl_unlock();
 	return ret;
 }
diff --git a/kernel/drivers/net/mdio/mdio-mux-meson-g12a.c b/kernel/drivers/net/mdio/mdio-mux-meson-g12a.c
index bf86c9c..ab86353 100644
--- a/kernel/drivers/net/mdio/mdio-mux-meson-g12a.c
+++ b/kernel/drivers/net/mdio/mdio-mux-meson-g12a.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/device.h>
@@ -150,6 +151,7 @@
 
 static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv)
 {
+	u32 value;
 	int ret;
 
 	/* Enable the phy clock */
@@ -163,18 +165,25 @@
 
 	/* Initialize ephy control */
 	writel(EPHY_G12A_ID, priv->regs + ETH_PHY_CNTL0);
-	writel(FIELD_PREP(PHY_CNTL1_ST_MODE, 3) |
-	       FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) |
-	       FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) |
-	       PHY_CNTL1_CLK_EN |
-	       PHY_CNTL1_CLKFREQ |
-	       PHY_CNTL1_PHY_ENB,
-	       priv->regs + ETH_PHY_CNTL1);
+
+	/* Make sure we get a 0 -> 1 transition on the enable bit */
+	value = FIELD_PREP(PHY_CNTL1_ST_MODE, 3) |
+		FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) |
+		FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) |
+		PHY_CNTL1_CLK_EN |
+		PHY_CNTL1_CLKFREQ;
+	writel(value, priv->regs + ETH_PHY_CNTL1);
 	writel(PHY_CNTL2_USE_INTERNAL |
 	       PHY_CNTL2_SMI_SRC_MAC |
 	       PHY_CNTL2_RX_CLK_EPHY,
 	       priv->regs + ETH_PHY_CNTL2);
 
+	value |= PHY_CNTL1_PHY_ENB;
+	writel(value, priv->regs + ETH_PHY_CNTL1);
+
+	/* The phy needs a bit of time to power up */
+	mdelay(10);
+
 	return 0;
 }
 
diff --git a/kernel/drivers/net/mdio/mdio-mvusb.c b/kernel/drivers/net/mdio/mdio-mvusb.c
index d5eabdd..11e0481 100644
--- a/kernel/drivers/net/mdio/mdio-mvusb.c
+++ b/kernel/drivers/net/mdio/mdio-mvusb.c
@@ -73,6 +73,7 @@
 	struct device *dev = &interface->dev;
 	struct mvusb_mdio *mvusb;
 	struct mii_bus *mdio;
+	int ret;
 
 	mdio = devm_mdiobus_alloc_size(dev, sizeof(*mvusb));
 	if (!mdio)
@@ -93,7 +94,15 @@
 	mdio->write = mvusb_mdio_write;
 
 	usb_set_intfdata(interface, mvusb);
-	return of_mdiobus_register(mdio, dev->of_node);
+	ret = of_mdiobus_register(mdio, dev->of_node);
+	if (ret)
+		goto put_dev;
+
+	return 0;
+
+put_dev:
+	usb_put_dev(mvusb->udev);
+	return ret;
 }
 
 static void mvusb_mdio_disconnect(struct usb_interface *interface)
diff --git a/kernel/drivers/net/mdio/mdio-thunder.c b/kernel/drivers/net/mdio/mdio-thunder.c
index 822d2cd..394b864 100644
--- a/kernel/drivers/net/mdio/mdio-thunder.c
+++ b/kernel/drivers/net/mdio/mdio-thunder.c
@@ -104,6 +104,7 @@
 		if (i >= ARRAY_SIZE(nexus->buses))
 			break;
 	}
+	fwnode_handle_put(fwn);
 	return 0;
 
 err_release_regions:
diff --git a/kernel/drivers/net/net_failover.c b/kernel/drivers/net/net_failover.c
index fb182be..6b7bba7 100644
--- a/kernel/drivers/net/net_failover.c
+++ b/kernel/drivers/net/net_failover.c
@@ -130,13 +130,9 @@
 			txq = ops->ndo_select_queue(primary_dev, skb, sb_dev);
 		else
 			txq = netdev_pick_tx(primary_dev, skb, NULL);
-
-		qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping;
-
-		return txq;
+	} else {
+		txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
 	}
-
-	txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
 
 	/* Save the original txq to restore before passing to the driver */
 	qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping;
diff --git a/kernel/drivers/net/netdevsim/dev.c b/kernel/drivers/net/netdevsim/dev.c
index 9bbecf4..bcf3547 100644
--- a/kernel/drivers/net/netdevsim/dev.c
+++ b/kernel/drivers/net/netdevsim/dev.c
@@ -149,13 +149,10 @@
 	cookie_len = (count - 1) / 2;
 	if ((count - 1) % 2)
 		return -EINVAL;
-	buf = kmalloc(count, GFP_KERNEL | __GFP_NOWARN);
-	if (!buf)
-		return -ENOMEM;
 
-	ret = simple_write_to_buffer(buf, count, ppos, data, count);
-	if (ret < 0)
-		goto free_buf;
+	buf = memdup_user(data, count);
+	if (IS_ERR(buf))
+		return PTR_ERR(buf);
 
 	fa_cookie = kmalloc(sizeof(*fa_cookie) + cookie_len,
 			    GFP_KERNEL | __GFP_NOWARN);
diff --git a/kernel/drivers/net/ntb_netdev.c b/kernel/drivers/net/ntb_netdev.c
index 1b7d588..b701ee8 100644
--- a/kernel/drivers/net/ntb_netdev.c
+++ b/kernel/drivers/net/ntb_netdev.c
@@ -137,7 +137,7 @@
 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 @@
 		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
diff --git a/kernel/drivers/net/phy/at803x.c b/kernel/drivers/net/phy/at803x.c
index ed601a7..ac37351 100644
--- a/kernel/drivers/net/phy/at803x.c
+++ b/kernel/drivers/net/phy/at803x.c
@@ -1115,8 +1115,6 @@
 	.flags			= PHY_POLL_CABLE_TEST,
 	.config_init		= at803x_config_init,
 	.link_change_notify	= at803x_link_change_notify,
-	.set_wol		= at803x_set_wol,
-	.get_wol		= at803x_get_wol,
 	.suspend		= at803x_suspend,
 	.resume			= at803x_resume,
 	/* PHY_BASIC_FEATURES */
diff --git a/kernel/drivers/net/phy/broadcom.c b/kernel/drivers/net/phy/broadcom.c
index 0cde17b..a664faa 100644
--- a/kernel/drivers/net/phy/broadcom.c
+++ b/kernel/drivers/net/phy/broadcom.c
@@ -404,6 +404,17 @@
 	return bcm54xx_config_init(phydev);
 }
 
+static int bcm54810_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
+{
+	return -EOPNOTSUPP;
+}
+
+static int bcm54810_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
+			      u16 val)
+{
+	return -EOPNOTSUPP;
+}
+
 static int bcm54811_config_init(struct phy_device *phydev)
 {
 	int err, reg;
@@ -841,6 +852,8 @@
 	.phy_id_mask    = 0xfffffff0,
 	.name           = "Broadcom BCM54810",
 	/* PHY_GBIT_FEATURES */
+	.read_mmd	= bcm54810_read_mmd,
+	.write_mmd	= bcm54810_write_mmd,
 	.config_init    = bcm54xx_config_init,
 	.config_aneg    = bcm5481_config_aneg,
 	.ack_interrupt  = bcm_phy_ack_intr,
diff --git a/kernel/drivers/net/phy/dp83822.c b/kernel/drivers/net/phy/dp83822.c
index db65164..8141299 100644
--- a/kernel/drivers/net/phy/dp83822.c
+++ b/kernel/drivers/net/phy/dp83822.c
@@ -247,7 +247,8 @@
 				DP83822_ENERGY_DET_INT_EN |
 				DP83822_LINK_QUAL_INT_EN);
 
-		if (!dp83822->fx_enabled)
+		/* Private data pointer is NULL on DP83825/26 */
+		if (!dp83822 || !dp83822->fx_enabled)
 			misr_status |= DP83822_ANEG_COMPLETE_INT_EN |
 				       DP83822_DUP_MODE_CHANGE_INT_EN |
 				       DP83822_SPEED_CHANGED_INT_EN;
@@ -267,7 +268,8 @@
 				DP83822_PAGE_RX_INT_EN |
 				DP83822_EEE_ERROR_CHANGE_INT_EN);
 
-		if (!dp83822->fx_enabled)
+		/* Private data pointer is NULL on DP83825/26 */
+		if (!dp83822 || !dp83822->fx_enabled)
 			misr_status |= DP83822_ANEG_ERR_INT_EN |
 				       DP83822_WOL_PKT_INT_EN;
 
diff --git a/kernel/drivers/net/phy/dp83867.c b/kernel/drivers/net/phy/dp83867.c
index c8031e2..834bf63 100644
--- a/kernel/drivers/net/phy/dp83867.c
+++ b/kernel/drivers/net/phy/dp83867.c
@@ -41,6 +41,7 @@
 #define DP83867_STRAP_STS1	0x006E
 #define DP83867_STRAP_STS2	0x006f
 #define DP83867_RGMIIDCTL	0x0086
+#define DP83867_DSP_FFE_CFG	0x012c
 #define DP83867_RXFCFG		0x0134
 #define DP83867_RXFPMD1	0x0136
 #define DP83867_RXFPMD2	0x0137
@@ -801,14 +802,33 @@
 {
 	int err;
 
+	err = phy_write(phydev, DP83867_CTRL, DP83867_SW_RESET);
+	if (err < 0)
+		return err;
+
+	usleep_range(10, 20);
+
+	err = phy_modify(phydev, MII_DP83867_PHYCTRL,
+			 DP83867_PHYCR_FORCE_LINK_GOOD, 0);
+	if (err < 0)
+		return err;
+
+	/* Configure the DSP Feedforward Equalizer Configuration register to
+	 * improve short cable (< 1 meter) performance. This will not affect
+	 * long cable performance.
+	 */
+	err = phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_DSP_FFE_CFG,
+			    0x0e81);
+	if (err < 0)
+		return err;
+
 	err = phy_write(phydev, DP83867_CTRL, DP83867_SW_RESTART);
 	if (err < 0)
 		return err;
 
 	usleep_range(10, 20);
 
-	return phy_modify(phydev, MII_DP83867_PHYCTRL,
-			 DP83867_PHYCR_FORCE_LINK_GOOD, 0);
+	return 0;
 }
 
 static void dp83867_link_change_notify(struct phy_device *phydev)
diff --git a/kernel/drivers/net/phy/dp83869.c b/kernel/drivers/net/phy/dp83869.c
index a9daff8..65b69ff 100644
--- a/kernel/drivers/net/phy/dp83869.c
+++ b/kernel/drivers/net/phy/dp83869.c
@@ -553,15 +553,13 @@
 						       &dp83869_internal_delay[0],
 						       delay_size, true);
 	if (dp83869->rx_int_delay < 0)
-		dp83869->rx_int_delay =
-				dp83869_internal_delay[DP83869_CLK_DELAY_DEF];
+		dp83869->rx_int_delay = DP83869_CLK_DELAY_DEF;
 
 	dp83869->tx_int_delay = phy_get_internal_delay(phydev, dev,
 						       &dp83869_internal_delay[0],
 						       delay_size, false);
 	if (dp83869->tx_int_delay < 0)
-		dp83869->tx_int_delay =
-				dp83869_internal_delay[DP83869_CLK_DELAY_DEF];
+		dp83869->tx_int_delay = DP83869_CLK_DELAY_DEF;
 
 	return ret;
 }
diff --git a/kernel/drivers/net/phy/marvell10g.c b/kernel/drivers/net/phy/marvell10g.c
index 2b64318..42b48d0 100644
--- a/kernel/drivers/net/phy/marvell10g.c
+++ b/kernel/drivers/net/phy/marvell10g.c
@@ -263,6 +263,13 @@
 	ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
 				 MV_V2_PORT_CTRL_PWRDOWN);
 
+	/* Sometimes, the power down bit doesn't clear immediately, and
+	 * a read of this register causes the bit not to clear. Delay
+	 * 100us to allow the PHY to come out of power down mode before
+	 * the next access.
+	 */
+	udelay(100);
+
 	if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310 ||
 	    priv->firmware_ver < 0x00030000)
 		return ret;
diff --git a/kernel/drivers/net/phy/mdio_bus.c b/kernel/drivers/net/phy/mdio_bus.c
index 77ba6c3..e9303be 100644
--- a/kernel/drivers/net/phy/mdio_bus.c
+++ b/kernel/drivers/net/phy/mdio_bus.c
@@ -108,7 +108,12 @@
 
 struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr)
 {
-	struct mdio_device *mdiodev = bus->mdio_map[addr];
+	struct mdio_device *mdiodev;
+
+	if (addr < 0 || addr >= ARRAY_SIZE(bus->mdio_map))
+		return NULL;
+
+	mdiodev = bus->mdio_map[addr];
 
 	if (!mdiodev)
 		return NULL;
diff --git a/kernel/drivers/net/phy/meson-gxl.c b/kernel/drivers/net/phy/meson-gxl.c
index e8f2ca6..39151ec 100644
--- a/kernel/drivers/net/phy/meson-gxl.c
+++ b/kernel/drivers/net/phy/meson-gxl.c
@@ -235,6 +235,8 @@
 		.config_intr	= meson_gxl_config_intr,
 		.suspend        = genphy_suspend,
 		.resume         = genphy_resume,
+		.read_mmd	= genphy_read_mmd_unsupported,
+		.write_mmd	= genphy_write_mmd_unsupported,
 	}, {
 		PHY_ID_MATCH_EXACT(0x01803301),
 		.name		= "Meson G12A Internal PHY",
@@ -245,6 +247,8 @@
 		.config_intr	= meson_gxl_config_intr,
 		.suspend        = genphy_suspend,
 		.resume         = genphy_resume,
+		.read_mmd	= genphy_read_mmd_unsupported,
+		.write_mmd	= genphy_write_mmd_unsupported,
 	},
 };
 
diff --git a/kernel/drivers/net/phy/microchip.c b/kernel/drivers/net/phy/microchip.c
index a644e8e..375bbd6 100644
--- a/kernel/drivers/net/phy/microchip.c
+++ b/kernel/drivers/net/phy/microchip.c
@@ -326,6 +326,37 @@
 	return genphy_config_aneg(phydev);
 }
 
+static void lan88xx_link_change_notify(struct phy_device *phydev)
+{
+	int temp;
+
+	/* At forced 100 F/H mode, chip may fail to set mode correctly
+	 * when cable is switched between long(~50+m) and short one.
+	 * As workaround, set to 10 before setting to 100
+	 * at forced 100 F/H mode.
+	 */
+	if (!phydev->autoneg && phydev->speed == 100) {
+		/* disable phy interrupt */
+		temp = phy_read(phydev, LAN88XX_INT_MASK);
+		temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_;
+		phy_write(phydev, LAN88XX_INT_MASK, temp);
+
+		temp = phy_read(phydev, MII_BMCR);
+		temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000);
+		phy_write(phydev, MII_BMCR, temp); /* set to 10 first */
+		temp |= BMCR_SPEED100;
+		phy_write(phydev, MII_BMCR, temp); /* set to 100 later */
+
+		/* clear pending interrupt generated while workaround */
+		temp = phy_read(phydev, LAN88XX_INT_STS);
+
+		/* enable phy interrupt back */
+		temp = phy_read(phydev, LAN88XX_INT_MASK);
+		temp |= LAN88XX_INT_MASK_MDINTPIN_EN_;
+		phy_write(phydev, LAN88XX_INT_MASK, temp);
+	}
+}
+
 static struct phy_driver microchip_phy_driver[] = {
 {
 	.phy_id		= 0x0007c130,
@@ -339,6 +370,7 @@
 
 	.config_init	= lan88xx_config_init,
 	.config_aneg	= lan88xx_config_aneg,
+	.link_change_notify = lan88xx_link_change_notify,
 
 	.ack_interrupt	= lan88xx_phy_ack_interrupt,
 	.config_intr	= lan88xx_phy_config_intr,
diff --git a/kernel/drivers/net/phy/mscc/mscc.h b/kernel/drivers/net/phy/mscc/mscc.h
index c2023f9..79117d2 100644
--- a/kernel/drivers/net/phy/mscc/mscc.h
+++ b/kernel/drivers/net/phy/mscc/mscc.h
@@ -175,6 +175,7 @@
 #define VSC8502_RGMII_CNTL		  20
 #define VSC8502_RGMII_RX_DELAY_MASK	  0x0070
 #define VSC8502_RGMII_TX_DELAY_MASK	  0x0007
+#define VSC8502_RGMII_RX_CLK_DISABLE	  0x0800
 
 #define MSCC_PHY_WOL_LOWER_MAC_ADDR	  21
 #define MSCC_PHY_WOL_MID_MAC_ADDR	  22
diff --git a/kernel/drivers/net/phy/mscc/mscc_main.c b/kernel/drivers/net/phy/mscc/mscc_main.c
index e14fa72..c64ac14 100644
--- a/kernel/drivers/net/phy/mscc/mscc_main.c
+++ b/kernel/drivers/net/phy/mscc/mscc_main.c
@@ -527,14 +527,27 @@
  *  * 2.0 ns (which causes the data to be sampled at exactly half way between
  *    clock transitions at 1000 Mbps) if delays should be enabled
  */
-static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl,
-				   u16 rgmii_rx_delay_mask,
-				   u16 rgmii_tx_delay_mask)
+static int vsc85xx_update_rgmii_cntl(struct phy_device *phydev, u32 rgmii_cntl,
+				     u16 rgmii_rx_delay_mask,
+				     u16 rgmii_tx_delay_mask)
 {
 	u16 rgmii_rx_delay_pos = ffs(rgmii_rx_delay_mask) - 1;
 	u16 rgmii_tx_delay_pos = ffs(rgmii_tx_delay_mask) - 1;
 	u16 reg_val = 0;
-	int rc;
+	u16 mask = 0;
+	int rc = 0;
+
+	/* For traffic to pass, the VSC8502 family needs the RX_CLK disable bit
+	 * to be unset for all PHY modes, so do that as part of the paged
+	 * register modification.
+	 * For some family members (like VSC8530/31/40/41) this bit is reserved
+	 * and read-only, and the RX clock is enabled by default.
+	 */
+	if (rgmii_cntl == VSC8502_RGMII_CNTL)
+		mask |= VSC8502_RGMII_RX_CLK_DISABLE;
+
+	if (phy_interface_is_rgmii(phydev))
+		mask |= rgmii_rx_delay_mask | rgmii_tx_delay_mask;
 
 	mutex_lock(&phydev->lock);
 
@@ -545,10 +558,9 @@
 	    phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
 		reg_val |= RGMII_CLK_DELAY_2_0_NS << rgmii_tx_delay_pos;
 
-	rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
-			      rgmii_cntl,
-			      rgmii_rx_delay_mask | rgmii_tx_delay_mask,
-			      reg_val);
+	if (mask)
+		rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
+				      rgmii_cntl, mask, reg_val);
 
 	mutex_unlock(&phydev->lock);
 
@@ -557,19 +569,11 @@
 
 static int vsc85xx_default_config(struct phy_device *phydev)
 {
-	int rc;
-
 	phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
 
-	if (phy_interface_mode_is_rgmii(phydev->interface)) {
-		rc = vsc85xx_rgmii_set_skews(phydev, VSC8502_RGMII_CNTL,
-					     VSC8502_RGMII_RX_DELAY_MASK,
-					     VSC8502_RGMII_TX_DELAY_MASK);
-		if (rc)
-			return rc;
-	}
-
-	return 0;
+	return vsc85xx_update_rgmii_cntl(phydev, VSC8502_RGMII_CNTL,
+					 VSC8502_RGMII_RX_DELAY_MASK,
+					 VSC8502_RGMII_TX_DELAY_MASK);
 }
 
 static int vsc85xx_get_tunable(struct phy_device *phydev,
@@ -1646,13 +1650,11 @@
 	if (ret)
 		return ret;
 
-	if (phy_interface_is_rgmii(phydev)) {
-		ret = vsc85xx_rgmii_set_skews(phydev, VSC8572_RGMII_CNTL,
-					      VSC8572_RGMII_RX_DELAY_MASK,
-					      VSC8572_RGMII_TX_DELAY_MASK);
-		if (ret)
-			return ret;
-	}
+	ret = vsc85xx_update_rgmii_cntl(phydev, VSC8572_RGMII_CNTL,
+					VSC8572_RGMII_RX_DELAY_MASK,
+					VSC8572_RGMII_TX_DELAY_MASK);
+	if (ret)
+		return ret;
 
 	ret = genphy_soft_reset(phydev);
 	if (ret)
@@ -2563,6 +2565,7 @@
 module_phy_driver(vsc85xx_driver);
 
 static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
+	{ PHY_ID_VSC8502, 0xfffffff0, },
 	{ PHY_ID_VSC8504, 0xfffffff0, },
 	{ PHY_ID_VSC8514, 0xfffffff0, },
 	{ PHY_ID_VSC8530, 0xfffffff0, },
diff --git a/kernel/drivers/net/phy/phy.c b/kernel/drivers/net/phy/phy.c
index 18e67eb..f3e606b 100644
--- a/kernel/drivers/net/phy/phy.c
+++ b/kernel/drivers/net/phy/phy.c
@@ -56,6 +56,18 @@
 	return NULL;
 }
 
+static void phy_process_state_change(struct phy_device *phydev,
+				     enum phy_state old_state)
+{
+	if (old_state != phydev->state) {
+		phydev_dbg(phydev, "PHY state change %s -> %s\n",
+			   phy_state_to_str(old_state),
+			   phy_state_to_str(phydev->state));
+		if (phydev->drv && phydev->drv->link_change_notify)
+			phydev->drv->link_change_notify(phydev);
+	}
+}
+
 static void phy_link_up(struct phy_device *phydev)
 {
 	phydev->phy_link_change(phydev, true);
@@ -1110,6 +1122,7 @@
 void phy_stop(struct phy_device *phydev)
 {
 	struct net_device *dev = phydev->attached_dev;
+	enum phy_state old_state;
 
 	if (!phy_is_started(phydev) && phydev->state != PHY_DOWN) {
 		WARN(1, "called from state %s\n",
@@ -1118,6 +1131,7 @@
 	}
 
 	mutex_lock(&phydev->lock);
+	old_state = phydev->state;
 
 	if (phydev->state == PHY_CABLETEST) {
 		phy_abort_cable_test(phydev);
@@ -1128,6 +1142,7 @@
 		sfp_upstream_stop(phydev->sfp_bus);
 
 	phydev->state = PHY_HALTED;
+	phy_process_state_change(phydev, old_state);
 
 	mutex_unlock(&phydev->lock);
 
@@ -1242,13 +1257,7 @@
 	if (err < 0)
 		phy_error(phydev);
 
-	if (old_state != phydev->state) {
-		phydev_dbg(phydev, "PHY state change %s -> %s\n",
-			   phy_state_to_str(old_state),
-			   phy_state_to_str(phydev->state));
-		if (phydev->drv && phydev->drv->link_change_notify)
-			phydev->drv->link_change_notify(phydev);
-	}
+	phy_process_state_change(phydev, old_state);
 
 	/* Only re-schedule a PHY state machine change if we are polling the
 	 * PHY, if PHY_IGNORE_INTERRUPT is set, then we will be moving
diff --git a/kernel/drivers/net/phy/phy_device.c b/kernel/drivers/net/phy/phy_device.c
index e83428c..bebc57e 100644
--- a/kernel/drivers/net/phy/phy_device.c
+++ b/kernel/drivers/net/phy/phy_device.c
@@ -2891,8 +2891,6 @@
 	if (phydrv->flags & PHY_IS_INTERNAL)
 		phydev->is_internal = true;
 
-	mutex_lock(&phydev->lock);
-
 	/* Deassert the reset signal */
 	phy_device_reset(phydev, 0);
 
@@ -2961,11 +2959,9 @@
 	phydev->state = PHY_READY;
 
 out:
-	/* Assert the reset signal */
+	/* Re-assert the reset signal on error */
 	if (err)
 		phy_device_reset(phydev, 1);
-
-	mutex_unlock(&phydev->lock);
 
 	return err;
 }
@@ -2976,9 +2972,7 @@
 
 	cancel_delayed_work_sync(&phydev->state_queue);
 
-	mutex_lock(&phydev->lock);
 	phydev->state = PHY_DOWN;
-	mutex_unlock(&phydev->lock);
 
 	sfp_bus_del_upstream(phydev->sfp_bus);
 	phydev->sfp_bus = NULL;
@@ -3088,23 +3082,30 @@
 {
 	int rc;
 
+	ethtool_set_ethtool_phy_ops(&phy_ethtool_phy_ops);
+
 	rc = mdio_bus_init();
 	if (rc)
-		return rc;
+		goto err_ethtool_phy_ops;
 
-	ethtool_set_ethtool_phy_ops(&phy_ethtool_phy_ops);
 	features_init();
 
 	rc = phy_driver_register(&genphy_c45_driver, THIS_MODULE);
 	if (rc)
-		goto err_c45;
+		goto err_mdio_bus;
 
 	rc = phy_driver_register(&genphy_driver, THIS_MODULE);
-	if (rc) {
-		phy_driver_unregister(&genphy_c45_driver);
+	if (rc)
+		goto err_c45;
+
+	return 0;
+
 err_c45:
-		mdio_bus_exit();
-	}
+	phy_driver_unregister(&genphy_c45_driver);
+err_mdio_bus:
+	mdio_bus_exit();
+err_ethtool_phy_ops:
+	ethtool_set_ethtool_phy_ops(NULL);
 
 	return rc;
 }
diff --git a/kernel/drivers/net/phy/rk630phy.c b/kernel/drivers/net/phy/rk630phy.c
index 471baec..de76196 100644
--- a/kernel/drivers/net/phy/rk630phy.c
+++ b/kernel/drivers/net/phy/rk630phy.c
@@ -238,7 +238,7 @@
 	/* Switch to page 6 */
 	phy_write(phydev, REG_PAGE_SEL, 0x0600);
 	/* PHYAFE ADC optimization */
-	phy_write(phydev, REG_PAGE6_ADC_ANONTROL, 0x555e);
+	phy_write(phydev, REG_PAGE6_ADC_ANONTROL, 0x5540);
 	/* PHYAFE Gain optimization */
 	phy_write(phydev, REG_PAGE6_GAIN_ANONTROL, 0x0400);
 	/* PHYAFE EQ optimization */
@@ -291,8 +291,8 @@
 		break;
 	case PHY_ADDR_T22:
 		rk630_phy_t22_config_init(phydev);
-		rk630_phy_set_aps(phydev, true);
-		rk630_phy_set_uaps(phydev, true);
+		rk630_phy_set_aps(phydev, false);
+		rk630_phy_set_uaps(phydev, false);
 		break;
 	default:
 		phydev_err(phydev, "Unsupported address for current phy: %d\n",
diff --git a/kernel/drivers/net/phy/sfp.c b/kernel/drivers/net/phy/sfp.c
index dcbe278..6a5f40f 100644
--- a/kernel/drivers/net/phy/sfp.c
+++ b/kernel/drivers/net/phy/sfp.c
@@ -207,6 +207,12 @@
  */
 #define SFP_PHY_ADDR	22
 
+/* SFP_EEPROM_BLOCK_SIZE is the size of data chunk to read the EEPROM
+ * at a time. Some SFP modules and also some Linux I2C drivers do not like
+ * reads longer than 16 bytes.
+ */
+#define SFP_EEPROM_BLOCK_SIZE	16
+
 struct sff_data {
 	unsigned int gpios;
 	bool (*module_supported)(const struct sfp_eeprom_id *id);
@@ -1754,11 +1760,7 @@
 	u8 check;
 	int ret;
 
-	/* Some SFP modules and also some Linux I2C drivers do not like reads
-	 * longer than 16 bytes, so read the EEPROM in chunks of 16 bytes at
-	 * a time.
-	 */
-	sfp->i2c_block_size = 16;
+	sfp->i2c_block_size = SFP_EEPROM_BLOCK_SIZE;
 
 	ret = sfp_read(sfp, false, 0, &id.base, sizeof(id.base));
 	if (ret < 0) {
@@ -2385,6 +2387,7 @@
 		return ERR_PTR(-ENOMEM);
 
 	sfp->dev = dev;
+	sfp->i2c_block_size = SFP_EEPROM_BLOCK_SIZE;
 
 	mutex_init(&sfp->sm_mutex);
 	mutex_init(&sfp->st_mutex);
diff --git a/kernel/drivers/net/phy/smsc.c b/kernel/drivers/net/phy/smsc.c
index caf7291..b67de3f 100644
--- a/kernel/drivers/net/phy/smsc.c
+++ b/kernel/drivers/net/phy/smsc.c
@@ -181,8 +181,11 @@
 static int lan87xx_read_status(struct phy_device *phydev)
 {
 	struct smsc_phy_priv *priv = phydev->priv;
+	int err;
 
-	int err = genphy_read_status(phydev);
+	err = genphy_read_status(phydev);
+	if (err)
+		return err;
 
 	if (!phydev->link && priv->energy_enable) {
 		/* Disable EDPD to wake up PHY */
diff --git a/kernel/drivers/net/phy/xilinx_gmii2rgmii.c b/kernel/drivers/net/phy/xilinx_gmii2rgmii.c
index 151c2a3..7a78dfd 100644
--- a/kernel/drivers/net/phy/xilinx_gmii2rgmii.c
+++ b/kernel/drivers/net/phy/xilinx_gmii2rgmii.c
@@ -82,6 +82,7 @@
 
 	if (!priv->phy_dev->drv) {
 		dev_info(dev, "Attached phy not ready\n");
+		put_device(&priv->phy_dev->mdio.dev);
 		return -EPROBE_DEFER;
 	}
 
diff --git a/kernel/drivers/net/ppp/ppp_generic.c b/kernel/drivers/net/ppp/ppp_generic.c
index 2b9815e..b825c6a 100644
--- a/kernel/drivers/net/ppp/ppp_generic.c
+++ b/kernel/drivers/net/ppp/ppp_generic.c
@@ -1610,6 +1610,8 @@
 	int len;
 	unsigned char *cp;
 
+	skb->dev = ppp->dev;
+
 	if (proto < 0x8000) {
 #ifdef CONFIG_PPP_FILTER
 		/* check if we should pass this packet */
diff --git a/kernel/drivers/net/ppp/pptp.c b/kernel/drivers/net/ppp/pptp.c
index ee50584..05a75b5 100644
--- a/kernel/drivers/net/ppp/pptp.c
+++ b/kernel/drivers/net/ppp/pptp.c
@@ -24,6 +24,7 @@
 #include <linux/in.h>
 #include <linux/ip.h>
 #include <linux/rcupdate.h>
+#include <linux/security.h>
 #include <linux/spinlock.h>
 
 #include <net/sock.h>
@@ -128,6 +129,23 @@
 	spin_unlock(&chan_lock);
 }
 
+static struct rtable *pptp_route_output(struct pppox_sock *po,
+					struct flowi4 *fl4)
+{
+	struct sock *sk = &po->sk;
+	struct net *net;
+
+	net = sock_net(sk);
+	flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark, 0,
+			   RT_SCOPE_UNIVERSE, IPPROTO_GRE, 0,
+			   po->proto.pptp.dst_addr.sin_addr.s_addr,
+			   po->proto.pptp.src_addr.sin_addr.s_addr,
+			   0, 0, sock_net_uid(net, sk));
+	security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4));
+
+	return ip_route_output_flow(net, fl4, sk);
+}
+
 static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
 {
 	struct sock *sk = (struct sock *) chan->private;
@@ -151,11 +169,7 @@
 	if (sk_pppox(po)->sk_state & PPPOX_DEAD)
 		goto tx_error;
 
-	rt = ip_route_output_ports(net, &fl4, NULL,
-				   opt->dst_addr.sin_addr.s_addr,
-				   opt->src_addr.sin_addr.s_addr,
-				   0, 0, IPPROTO_GRE,
-				   RT_TOS(0), sk->sk_bound_dev_if);
+	rt = pptp_route_output(po, &fl4);
 	if (IS_ERR(rt))
 		goto tx_error;
 
@@ -440,12 +454,7 @@
 	po->chan.private = sk;
 	po->chan.ops = &pptp_chan_ops;
 
-	rt = ip_route_output_ports(sock_net(sk), &fl4, sk,
-				   opt->dst_addr.sin_addr.s_addr,
-				   opt->src_addr.sin_addr.s_addr,
-				   0, 0,
-				   IPPROTO_GRE, RT_CONN_FLAGS(sk),
-				   sk->sk_bound_dev_if);
+	rt = pptp_route_output(po, &fl4);
 	if (IS_ERR(rt)) {
 		error = -EHOSTUNREACH;
 		goto end;
diff --git a/kernel/drivers/net/tap.c b/kernel/drivers/net/tap.c
index 8f7bb15..41ee560 100644
--- a/kernel/drivers/net/tap.c
+++ b/kernel/drivers/net/tap.c
@@ -523,7 +523,7 @@
 	q->sock.state = SS_CONNECTED;
 	q->sock.file = file;
 	q->sock.ops = &tap_socket_ops;
-	sock_init_data(&q->sock, &q->sk);
+	sock_init_data_uid(&q->sock, &q->sk, current_fsuid());
 	q->sk.sk_write_space = tap_sock_write_space;
 	q->sk.sk_destruct = tap_sock_destruct;
 	q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP;
@@ -713,9 +713,8 @@
 	skb_probe_transport_header(skb);
 
 	/* Move network header to the right position for VLAN tagged packets */
-	if ((skb->protocol == htons(ETH_P_8021Q) ||
-	     skb->protocol == htons(ETH_P_8021AD)) &&
-	    __vlan_get_protocol(skb, skb->protocol, &depth) != 0)
+	if (eth_type_vlan(skb->protocol) &&
+	    vlan_get_protocol_and_depth(skb, skb->protocol, &depth) != 0)
 		skb_set_network_header(skb, depth);
 
 	rcu_read_lock();
@@ -1165,9 +1164,8 @@
 	}
 
 	/* Move network header to the right position for VLAN tagged packets */
-	if ((skb->protocol == htons(ETH_P_8021Q) ||
-	     skb->protocol == htons(ETH_P_8021AD)) &&
-	    __vlan_get_protocol(skb, skb->protocol, &depth) != 0)
+	if (eth_type_vlan(skb->protocol) &&
+	    vlan_get_protocol_and_depth(skb, skb->protocol, &depth) != 0)
 		skb_set_network_header(skb, depth);
 
 	rcu_read_lock();
diff --git a/kernel/drivers/net/team/team.c b/kernel/drivers/net/team/team.c
index 7117d55..97a77da 100644
--- a/kernel/drivers/net/team/team.c
+++ b/kernel/drivers/net/team/team.c
@@ -1624,6 +1624,7 @@
 
 	team->dev = dev;
 	team_set_no_mode(team);
+	team->notifier_ctx = false;
 
 	team->pcpu_stats = netdev_alloc_pcpu_stats(struct team_pcpu_stats);
 	if (!team->pcpu_stats)
@@ -2121,7 +2122,12 @@
 static void team_setup_by_port(struct net_device *dev,
 			       struct net_device *port_dev)
 {
-	dev->header_ops	= port_dev->header_ops;
+	struct team *team = netdev_priv(dev);
+
+	if (port_dev->type == ARPHRD_ETHER)
+		dev->header_ops	= team->header_ops_cache;
+	else
+		dev->header_ops	= port_dev->header_ops;
 	dev->type = port_dev->type;
 	dev->hard_header_len = port_dev->hard_header_len;
 	dev->needed_headroom = port_dev->needed_headroom;
@@ -2129,6 +2135,15 @@
 	dev->mtu = port_dev->mtu;
 	memcpy(dev->broadcast, port_dev->broadcast, port_dev->addr_len);
 	eth_hw_addr_inherit(dev, port_dev);
+
+	if (port_dev->flags & IFF_POINTOPOINT) {
+		dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
+		dev->flags |= (IFF_POINTOPOINT | IFF_NOARP);
+	} else if ((port_dev->flags & (IFF_BROADCAST | IFF_MULTICAST)) ==
+		    (IFF_BROADCAST | IFF_MULTICAST)) {
+		dev->flags |= (IFF_BROADCAST | IFF_MULTICAST);
+		dev->flags &= ~(IFF_POINTOPOINT | IFF_NOARP);
+	}
 }
 
 static int team_dev_type_check_change(struct net_device *dev,
@@ -2159,8 +2174,11 @@
 
 static void team_setup(struct net_device *dev)
 {
+	struct team *team = netdev_priv(dev);
+
 	ether_setup(dev);
 	dev->max_mtu = ETH_MAX_MTU;
+	team->header_ops_cache = dev->header_ops;
 
 	dev->netdev_ops = &team_netdev_ops;
 	dev->ethtool_ops = &team_ethtool_ops;
@@ -2185,7 +2203,9 @@
 
 	dev->hw_features = TEAM_VLAN_FEATURES |
 			   NETIF_F_HW_VLAN_CTAG_RX |
-			   NETIF_F_HW_VLAN_CTAG_FILTER;
+			   NETIF_F_HW_VLAN_CTAG_FILTER |
+			   NETIF_F_HW_VLAN_STAG_RX |
+			   NETIF_F_HW_VLAN_STAG_FILTER;
 
 	dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4;
 	dev->features |= dev->hw_features;
@@ -3016,7 +3036,11 @@
 		team_del_slave(port->team->dev, dev);
 		break;
 	case NETDEV_FEAT_CHANGE:
-		team_compute_features(port->team);
+		if (!port->team->notifier_ctx) {
+			port->team->notifier_ctx = true;
+			team_compute_features(port->team);
+			port->team->notifier_ctx = false;
+		}
 		break;
 	case NETDEV_PRECHANGEMTU:
 		/* Forbid to change mtu of underlaying device */
diff --git a/kernel/drivers/net/thunderbolt.c b/kernel/drivers/net/thunderbolt.c
index 5d96dc1..e05bcf8 100644
--- a/kernel/drivers/net/thunderbolt.c
+++ b/kernel/drivers/net/thunderbolt.c
@@ -958,12 +958,11 @@
 		*tucso = ~csum_tcpudp_magic(ip_hdr(skb)->saddr,
 					    ip_hdr(skb)->daddr, 0,
 					    ip_hdr(skb)->protocol, 0);
-	} else if (skb_is_gso_v6(skb)) {
+	} else if (skb_is_gso(skb) && skb_is_gso_v6(skb)) {
 		tucso = dest + ((void *)&(tcp_hdr(skb)->check) - data);
 		*tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
 					  &ipv6_hdr(skb)->daddr, 0,
 					  IPPROTO_TCP, 0);
-		return false;
 	} else if (protocol == htons(ETH_P_IPV6)) {
 		tucso = dest + skb_checksum_start_offset(skb) + skb->csum_offset;
 		*tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
diff --git a/kernel/drivers/net/tun.c b/kernel/drivers/net/tun.c
index 67ce7b7..191bf0d 100644
--- a/kernel/drivers/net/tun.c
+++ b/kernel/drivers/net/tun.c
@@ -1604,7 +1604,7 @@
 	if (zerocopy)
 		return false;
 
-	if (SKB_DATA_ALIGN(len + TUN_RX_PAD) +
+	if (SKB_DATA_ALIGN(len + TUN_RX_PAD + XDP_PACKET_HEADROOM) +
 	    SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) > PAGE_SIZE)
 		return false;
 
@@ -3457,7 +3457,7 @@
 	tfile->socket.file = file;
 	tfile->socket.ops = &tun_socket_ops;
 
-	sock_init_data(&tfile->socket, &tfile->sk);
+	sock_init_data_uid(&tfile->socket, &tfile->sk, current_fsuid());
 
 	tfile->sk.sk_write_space = tun_sock_write_space;
 	tfile->sk.sk_sndbuf = INT_MAX;
diff --git a/kernel/drivers/net/usb/cdc_ether.c b/kernel/drivers/net/usb/cdc_ether.c
index 935cd29..9f3446d 100644
--- a/kernel/drivers/net/usb/cdc_ether.c
+++ b/kernel/drivers/net/usb/cdc_ether.c
@@ -604,6 +604,13 @@
 	.match_flags	=   USB_DEVICE_ID_MATCH_INT_INFO
 			  | USB_DEVICE_ID_MATCH_DEVICE,
 	.idVendor		= 0x04DD,
+	.idProduct		= 0x8005,   /* A-300 */
+	ZAURUS_FAKE_INTERFACE,
+	.driver_info        = 0,
+}, {
+	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+			  | USB_DEVICE_ID_MATCH_DEVICE,
+	.idVendor		= 0x04DD,
 	.idProduct		= 0x8006,	/* B-500/SL-5600 */
 	ZAURUS_MASTER_INTERFACE,
 	.driver_info		= 0,
@@ -611,11 +618,25 @@
 	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 			  | USB_DEVICE_ID_MATCH_DEVICE,
 	.idVendor		= 0x04DD,
+	.idProduct		= 0x8006,   /* B-500/SL-5600 */
+	ZAURUS_FAKE_INTERFACE,
+	.driver_info        = 0,
+}, {
+	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+			  | USB_DEVICE_ID_MATCH_DEVICE,
+	.idVendor		= 0x04DD,
 	.idProduct		= 0x8007,	/* C-700 */
 	ZAURUS_MASTER_INTERFACE,
 	.driver_info		= 0,
 }, {
 	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+			  | USB_DEVICE_ID_MATCH_DEVICE,
+	.idVendor		= 0x04DD,
+	.idProduct		= 0x8007,   /* C-700 */
+	ZAURUS_FAKE_INTERFACE,
+	.driver_info        = 0,
+}, {
+	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 		 | USB_DEVICE_ID_MATCH_DEVICE,
 	.idVendor               = 0x04DD,
 	.idProduct              = 0x9031,	/* C-750 C-760 */
diff --git a/kernel/drivers/net/usb/cdc_mbim.c b/kernel/drivers/net/usb/cdc_mbim.c
index 414341c..6ad1fb0 100644
--- a/kernel/drivers/net/usb/cdc_mbim.c
+++ b/kernel/drivers/net/usb/cdc_mbim.c
@@ -663,6 +663,11 @@
 	  .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
 	},
 
+	/* Telit FE990 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1081, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
+	  .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
+	},
+
 	/* default entry */
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
 	  .driver_info = (unsigned long)&cdc_mbim_info_zlp,
diff --git a/kernel/drivers/net/usb/cdc_ncm.c b/kernel/drivers/net/usb/cdc_ncm.c
index 913d913..7345564 100644
--- a/kernel/drivers/net/usb/cdc_ncm.c
+++ b/kernel/drivers/net/usb/cdc_ncm.c
@@ -180,9 +180,12 @@
 	else
 		min = ctx->max_datagram_size + ctx->max_ndp_size + sizeof(struct usb_cdc_ncm_nth32);
 
-	max = min_t(u32, CDC_NCM_NTB_MAX_SIZE_TX, le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize));
-	if (max == 0)
+	if (le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize) == 0)
 		max = CDC_NCM_NTB_MAX_SIZE_TX; /* dwNtbOutMaxSize not set */
+	else
+		max = clamp_t(u32, le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize),
+			      USB_CDC_NCM_NTB_MIN_OUT_SIZE,
+			      CDC_NCM_NTB_MAX_SIZE_TX);
 
 	/* some devices set dwNtbOutMaxSize too low for the above default */
 	min = min(min, max);
@@ -1230,6 +1233,9 @@
 			 * further.
 			 */
 			if (skb_out == NULL) {
+				/* If even the smallest allocation fails, abort. */
+				if (ctx->tx_curr_size == USB_CDC_NCM_NTB_MIN_OUT_SIZE)
+					goto alloc_failed;
 				ctx->tx_low_mem_max_cnt = min(ctx->tx_low_mem_max_cnt + 1,
 							      (unsigned)CDC_NCM_LOW_MEM_MAX_CNT);
 				ctx->tx_low_mem_val = ctx->tx_low_mem_max_cnt;
@@ -1248,13 +1254,8 @@
 			skb_out = alloc_skb(ctx->tx_curr_size, GFP_ATOMIC);
 
 			/* No allocation possible so we will abort */
-			if (skb_out == NULL) {
-				if (skb != NULL) {
-					dev_kfree_skb_any(skb);
-					dev->net->stats.tx_dropped++;
-				}
-				goto exit_no_skb;
-			}
+			if (!skb_out)
+				goto alloc_failed;
 			ctx->tx_low_mem_val--;
 		}
 		if (ctx->is_ndp16) {
@@ -1447,6 +1448,11 @@
 
 	return skb_out;
 
+alloc_failed:
+	if (skb) {
+		dev_kfree_skb_any(skb);
+		dev->net->stats.tx_dropped++;
+	}
 exit_no_skb:
 	/* Start timer, if there is a remaining non-empty skb */
 	if (ctx->tx_curr_skb != NULL && n > 0)
diff --git a/kernel/drivers/net/usb/kalmia.c b/kernel/drivers/net/usb/kalmia.c
index fc5895f..a552bb1 100644
--- a/kernel/drivers/net/usb/kalmia.c
+++ b/kernel/drivers/net/usb/kalmia.c
@@ -65,8 +65,8 @@
 		init_msg, init_msg_len, &act_len, KALMIA_USB_TIMEOUT);
 	if (status != 0) {
 		netdev_err(dev->net,
-			"Error sending init packet. Status %i, length %i\n",
-			status, act_len);
+			"Error sending init packet. Status %i\n",
+			status);
 		return status;
 	}
 	else if (act_len != init_msg_len) {
@@ -83,8 +83,8 @@
 
 	if (status != 0)
 		netdev_err(dev->net,
-			"Error receiving init result. Status %i, length %i\n",
-			status, act_len);
+			"Error receiving init result. Status %i\n",
+			status);
 	else if (act_len != expected_len)
 		netdev_err(dev->net, "Unexpected init result length: %i\n",
 			act_len);
diff --git a/kernel/drivers/net/usb/lan78xx.c b/kernel/drivers/net/usb/lan78xx.c
index 6f7b705..667984e 100644
--- a/kernel/drivers/net/usb/lan78xx.c
+++ b/kernel/drivers/net/usb/lan78xx.c
@@ -824,20 +824,19 @@
 				u32 length, u8 *data)
 {
 	int i;
-	int ret;
 	u32 buf;
 	unsigned long timeout;
 
-	ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf);
+	lan78xx_read_reg(dev, OTP_PWR_DN, &buf);
 
 	if (buf & OTP_PWR_DN_PWRDN_N_) {
 		/* clear it and wait to be cleared */
-		ret = lan78xx_write_reg(dev, OTP_PWR_DN, 0);
+		lan78xx_write_reg(dev, OTP_PWR_DN, 0);
 
 		timeout = jiffies + HZ;
 		do {
 			usleep_range(1, 10);
-			ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf);
+			lan78xx_read_reg(dev, OTP_PWR_DN, &buf);
 			if (time_after(jiffies, timeout)) {
 				netdev_warn(dev->net,
 					    "timeout on OTP_PWR_DN");
@@ -847,18 +846,18 @@
 	}
 
 	for (i = 0; i < length; i++) {
-		ret = lan78xx_write_reg(dev, OTP_ADDR1,
+		lan78xx_write_reg(dev, OTP_ADDR1,
 					((offset + i) >> 8) & OTP_ADDR1_15_11);
-		ret = lan78xx_write_reg(dev, OTP_ADDR2,
+		lan78xx_write_reg(dev, OTP_ADDR2,
 					((offset + i) & OTP_ADDR2_10_3));
 
-		ret = lan78xx_write_reg(dev, OTP_FUNC_CMD, OTP_FUNC_CMD_READ_);
-		ret = lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_);
+		lan78xx_write_reg(dev, OTP_FUNC_CMD, OTP_FUNC_CMD_READ_);
+		lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_);
 
 		timeout = jiffies + HZ;
 		do {
 			udelay(1);
-			ret = lan78xx_read_reg(dev, OTP_STATUS, &buf);
+			lan78xx_read_reg(dev, OTP_STATUS, &buf);
 			if (time_after(jiffies, timeout)) {
 				netdev_warn(dev->net,
 					    "timeout on OTP_STATUS");
@@ -866,7 +865,7 @@
 			}
 		} while (buf & OTP_STATUS_BUSY_);
 
-		ret = lan78xx_read_reg(dev, OTP_RD_DATA, &buf);
+		lan78xx_read_reg(dev, OTP_RD_DATA, &buf);
 
 		data[i] = (u8)(buf & 0xFF);
 	}
@@ -878,20 +877,19 @@
 				 u32 length, u8 *data)
 {
 	int i;
-	int ret;
 	u32 buf;
 	unsigned long timeout;
 
-	ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf);
+	lan78xx_read_reg(dev, OTP_PWR_DN, &buf);
 
 	if (buf & OTP_PWR_DN_PWRDN_N_) {
 		/* clear it and wait to be cleared */
-		ret = lan78xx_write_reg(dev, OTP_PWR_DN, 0);
+		lan78xx_write_reg(dev, OTP_PWR_DN, 0);
 
 		timeout = jiffies + HZ;
 		do {
 			udelay(1);
-			ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf);
+			lan78xx_read_reg(dev, OTP_PWR_DN, &buf);
 			if (time_after(jiffies, timeout)) {
 				netdev_warn(dev->net,
 					    "timeout on OTP_PWR_DN completion");
@@ -901,21 +899,21 @@
 	}
 
 	/* set to BYTE program mode */
-	ret = lan78xx_write_reg(dev, OTP_PRGM_MODE, OTP_PRGM_MODE_BYTE_);
+	lan78xx_write_reg(dev, OTP_PRGM_MODE, OTP_PRGM_MODE_BYTE_);
 
 	for (i = 0; i < length; i++) {
-		ret = lan78xx_write_reg(dev, OTP_ADDR1,
+		lan78xx_write_reg(dev, OTP_ADDR1,
 					((offset + i) >> 8) & OTP_ADDR1_15_11);
-		ret = lan78xx_write_reg(dev, OTP_ADDR2,
+		lan78xx_write_reg(dev, OTP_ADDR2,
 					((offset + i) & OTP_ADDR2_10_3));
-		ret = lan78xx_write_reg(dev, OTP_PRGM_DATA, data[i]);
-		ret = lan78xx_write_reg(dev, OTP_TST_CMD, OTP_TST_CMD_PRGVRFY_);
-		ret = lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_);
+		lan78xx_write_reg(dev, OTP_PRGM_DATA, data[i]);
+		lan78xx_write_reg(dev, OTP_TST_CMD, OTP_TST_CMD_PRGVRFY_);
+		lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_);
 
 		timeout = jiffies + HZ;
 		do {
 			udelay(1);
-			ret = lan78xx_read_reg(dev, OTP_STATUS, &buf);
+			lan78xx_read_reg(dev, OTP_STATUS, &buf);
 			if (time_after(jiffies, timeout)) {
 				netdev_warn(dev->net,
 					    "Timeout on OTP_STATUS completion");
@@ -1040,7 +1038,6 @@
 			container_of(param, struct lan78xx_priv, set_multicast);
 	struct lan78xx_net *dev = pdata->dev;
 	int i;
-	int ret;
 
 	netif_dbg(dev, drv, dev->net, "deferred multicast write 0x%08x\n",
 		  pdata->rfe_ctl);
@@ -1049,14 +1046,14 @@
 			       DP_SEL_VHF_HASH_LEN, pdata->mchash_table);
 
 	for (i = 1; i < NUM_OF_MAF; i++) {
-		ret = lan78xx_write_reg(dev, MAF_HI(i), 0);
-		ret = lan78xx_write_reg(dev, MAF_LO(i),
+		lan78xx_write_reg(dev, MAF_HI(i), 0);
+		lan78xx_write_reg(dev, MAF_LO(i),
 					pdata->pfilter_table[i][1]);
-		ret = lan78xx_write_reg(dev, MAF_HI(i),
+		lan78xx_write_reg(dev, MAF_HI(i),
 					pdata->pfilter_table[i][0]);
 	}
 
-	ret = lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+	lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
 }
 
 static void lan78xx_set_multicast(struct net_device *netdev)
@@ -1126,7 +1123,6 @@
 				      u16 lcladv, u16 rmtadv)
 {
 	u32 flow = 0, fct_flow = 0;
-	int ret;
 	u8 cap;
 
 	if (dev->fc_autoneg)
@@ -1149,10 +1145,10 @@
 		  (cap & FLOW_CTRL_RX ? "enabled" : "disabled"),
 		  (cap & FLOW_CTRL_TX ? "enabled" : "disabled"));
 
-	ret = lan78xx_write_reg(dev, FCT_FLOW, fct_flow);
+	lan78xx_write_reg(dev, FCT_FLOW, fct_flow);
 
 	/* threshold value should be set before enabling flow */
-	ret = lan78xx_write_reg(dev, FLOW, flow);
+	lan78xx_write_reg(dev, FLOW, flow);
 
 	return 0;
 }
@@ -1673,11 +1669,10 @@
 static void lan78xx_init_mac_address(struct lan78xx_net *dev)
 {
 	u32 addr_lo, addr_hi;
-	int ret;
 	u8 addr[6];
 
-	ret = lan78xx_read_reg(dev, RX_ADDRL, &addr_lo);
-	ret = lan78xx_read_reg(dev, RX_ADDRH, &addr_hi);
+	lan78xx_read_reg(dev, RX_ADDRL, &addr_lo);
+	lan78xx_read_reg(dev, RX_ADDRH, &addr_hi);
 
 	addr[0] = addr_lo & 0xFF;
 	addr[1] = (addr_lo >> 8) & 0xFF;
@@ -1710,12 +1705,12 @@
 			  (addr[2] << 16) | (addr[3] << 24);
 		addr_hi = addr[4] | (addr[5] << 8);
 
-		ret = lan78xx_write_reg(dev, RX_ADDRL, addr_lo);
-		ret = lan78xx_write_reg(dev, RX_ADDRH, addr_hi);
+		lan78xx_write_reg(dev, RX_ADDRL, addr_lo);
+		lan78xx_write_reg(dev, RX_ADDRH, addr_hi);
 	}
 
-	ret = lan78xx_write_reg(dev, MAF_LO(0), addr_lo);
-	ret = lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_);
+	lan78xx_write_reg(dev, MAF_LO(0), addr_lo);
+	lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_);
 
 	ether_addr_copy(dev->net->dev_addr, addr);
 }
@@ -1848,33 +1843,8 @@
 static void lan78xx_link_status_change(struct net_device *net)
 {
 	struct phy_device *phydev = net->phydev;
-	int ret, temp;
 
-	/* At forced 100 F/H mode, chip may fail to set mode correctly
-	 * when cable is switched between long(~50+m) and short one.
-	 * As workaround, set to 10 before setting to 100
-	 * at forced 100 F/H mode.
-	 */
-	if (!phydev->autoneg && (phydev->speed == 100)) {
-		/* disable phy interrupt */
-		temp = phy_read(phydev, LAN88XX_INT_MASK);
-		temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_;
-		ret = phy_write(phydev, LAN88XX_INT_MASK, temp);
-
-		temp = phy_read(phydev, MII_BMCR);
-		temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000);
-		phy_write(phydev, MII_BMCR, temp); /* set to 10 first */
-		temp |= BMCR_SPEED100;
-		phy_write(phydev, MII_BMCR, temp); /* set to 100 later */
-
-		/* clear pending interrupt generated while workaround */
-		temp = phy_read(phydev, LAN88XX_INT_STS);
-
-		/* enable phy interrupt back */
-		temp = phy_read(phydev, LAN88XX_INT_MASK);
-		temp |= LAN88XX_INT_MASK_MDINTPIN_EN_;
-		ret = phy_write(phydev, LAN88XX_INT_MASK, temp);
-	}
+	phy_print_status(phydev);
 }
 
 static int irq_map(struct irq_domain *d, unsigned int irq,
@@ -1927,14 +1897,13 @@
 	struct lan78xx_net *dev =
 			container_of(data, struct lan78xx_net, domain_data);
 	u32 buf;
-	int ret;
 
 	/* call register access here because irq_bus_lock & irq_bus_sync_unlock
 	 * are only two callbacks executed in non-atomic contex.
 	 */
-	ret = lan78xx_read_reg(dev, INT_EP_CTL, &buf);
+	lan78xx_read_reg(dev, INT_EP_CTL, &buf);
 	if (buf != data->irqenable)
-		ret = lan78xx_write_reg(dev, INT_EP_CTL, data->irqenable);
+		lan78xx_write_reg(dev, INT_EP_CTL, data->irqenable);
 
 	mutex_unlock(&data->irq_lock);
 }
@@ -2001,7 +1970,6 @@
 static int lan8835_fixup(struct phy_device *phydev)
 {
 	int buf;
-	int ret;
 	struct lan78xx_net *dev = netdev_priv(phydev->attached_dev);
 
 	/* LED2/PME_N/IRQ_N/RGMII_ID pin to IRQ_N mode */
@@ -2011,11 +1979,11 @@
 	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8010, buf);
 
 	/* RGMII MAC TXC Delay Enable */
-	ret = lan78xx_write_reg(dev, MAC_RGMII_ID,
+	lan78xx_write_reg(dev, MAC_RGMII_ID,
 				MAC_RGMII_ID_TXC_DELAY_EN_);
 
 	/* RGMII TX DLL Tune Adjust */
-	ret = lan78xx_write_reg(dev, RGMII_TX_BYP_DLL, 0x3D00);
+	lan78xx_write_reg(dev, RGMII_TX_BYP_DLL, 0x3D00);
 
 	dev->interface = PHY_INTERFACE_MODE_RGMII_TXID;
 
@@ -2199,28 +2167,27 @@
 
 static int lan78xx_set_rx_max_frame_length(struct lan78xx_net *dev, int size)
 {
-	int ret = 0;
 	u32 buf;
 	bool rxenabled;
 
-	ret = lan78xx_read_reg(dev, MAC_RX, &buf);
+	lan78xx_read_reg(dev, MAC_RX, &buf);
 
 	rxenabled = ((buf & MAC_RX_RXEN_) != 0);
 
 	if (rxenabled) {
 		buf &= ~MAC_RX_RXEN_;
-		ret = lan78xx_write_reg(dev, MAC_RX, buf);
+		lan78xx_write_reg(dev, MAC_RX, buf);
 	}
 
 	/* add 4 to size for FCS */
 	buf &= ~MAC_RX_MAX_SIZE_MASK_;
 	buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT_) & MAC_RX_MAX_SIZE_MASK_);
 
-	ret = lan78xx_write_reg(dev, MAC_RX, buf);
+	lan78xx_write_reg(dev, MAC_RX, buf);
 
 	if (rxenabled) {
 		buf |= MAC_RX_RXEN_;
-		ret = lan78xx_write_reg(dev, MAC_RX, buf);
+		lan78xx_write_reg(dev, MAC_RX, buf);
 	}
 
 	return 0;
@@ -2277,13 +2244,12 @@
 	int ll_mtu = new_mtu + netdev->hard_header_len;
 	int old_hard_mtu = dev->hard_mtu;
 	int old_rx_urb_size = dev->rx_urb_size;
-	int ret;
 
 	/* no second zero-length packet read wanted after mtu-sized packets */
 	if ((ll_mtu % dev->maxpacket) == 0)
 		return -EDOM;
 
-	ret = lan78xx_set_rx_max_frame_length(dev, new_mtu + VLAN_ETH_HLEN);
+	lan78xx_set_rx_max_frame_length(dev, new_mtu + VLAN_ETH_HLEN);
 
 	netdev->mtu = new_mtu;
 
@@ -2306,7 +2272,6 @@
 	struct lan78xx_net *dev = netdev_priv(netdev);
 	struct sockaddr *addr = p;
 	u32 addr_lo, addr_hi;
-	int ret;
 
 	if (netif_running(netdev))
 		return -EBUSY;
@@ -2323,12 +2288,12 @@
 	addr_hi = netdev->dev_addr[4] |
 		  netdev->dev_addr[5] << 8;
 
-	ret = lan78xx_write_reg(dev, RX_ADDRL, addr_lo);
-	ret = lan78xx_write_reg(dev, RX_ADDRH, addr_hi);
+	lan78xx_write_reg(dev, RX_ADDRL, addr_lo);
+	lan78xx_write_reg(dev, RX_ADDRH, addr_hi);
 
 	/* Added to support MAC address changes */
-	ret = lan78xx_write_reg(dev, MAF_LO(0), addr_lo);
-	ret = lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_);
+	lan78xx_write_reg(dev, MAF_LO(0), addr_lo);
+	lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_);
 
 	return 0;
 }
@@ -2340,7 +2305,6 @@
 	struct lan78xx_net *dev = netdev_priv(netdev);
 	struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]);
 	unsigned long flags;
-	int ret;
 
 	spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);
 
@@ -2364,7 +2328,7 @@
 
 	spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);
 
-	ret = lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+	lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
 
 	return 0;
 }
@@ -3820,7 +3784,6 @@
 static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol)
 {
 	u32 buf;
-	int ret;
 	int mask_index;
 	u16 crc;
 	u32 temp_wucsr;
@@ -3829,26 +3792,26 @@
 	const u8 ipv6_multicast[3] = { 0x33, 0x33 };
 	const u8 arp_type[2] = { 0x08, 0x06 };
 
-	ret = lan78xx_read_reg(dev, MAC_TX, &buf);
+	lan78xx_read_reg(dev, MAC_TX, &buf);
 	buf &= ~MAC_TX_TXEN_;
-	ret = lan78xx_write_reg(dev, MAC_TX, buf);
-	ret = lan78xx_read_reg(dev, MAC_RX, &buf);
+	lan78xx_write_reg(dev, MAC_TX, buf);
+	lan78xx_read_reg(dev, MAC_RX, &buf);
 	buf &= ~MAC_RX_RXEN_;
-	ret = lan78xx_write_reg(dev, MAC_RX, buf);
+	lan78xx_write_reg(dev, MAC_RX, buf);
 
-	ret = lan78xx_write_reg(dev, WUCSR, 0);
-	ret = lan78xx_write_reg(dev, WUCSR2, 0);
-	ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL);
+	lan78xx_write_reg(dev, WUCSR, 0);
+	lan78xx_write_reg(dev, WUCSR2, 0);
+	lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL);
 
 	temp_wucsr = 0;
 
 	temp_pmt_ctl = 0;
-	ret = lan78xx_read_reg(dev, PMT_CTL, &temp_pmt_ctl);
+	lan78xx_read_reg(dev, PMT_CTL, &temp_pmt_ctl);
 	temp_pmt_ctl &= ~PMT_CTL_RES_CLR_WKP_EN_;
 	temp_pmt_ctl |= PMT_CTL_RES_CLR_WKP_STS_;
 
 	for (mask_index = 0; mask_index < NUM_OF_WUF_CFG; mask_index++)
-		ret = lan78xx_write_reg(dev, WUF_CFG(mask_index), 0);
+		lan78xx_write_reg(dev, WUF_CFG(mask_index), 0);
 
 	mask_index = 0;
 	if (wol & WAKE_PHY) {
@@ -3877,30 +3840,30 @@
 
 		/* set WUF_CFG & WUF_MASK for IPv4 Multicast */
 		crc = lan78xx_wakeframe_crc16(ipv4_multicast, 3);
-		ret = lan78xx_write_reg(dev, WUF_CFG(mask_index),
+		lan78xx_write_reg(dev, WUF_CFG(mask_index),
 					WUF_CFGX_EN_ |
 					WUF_CFGX_TYPE_MCAST_ |
 					(0 << WUF_CFGX_OFFSET_SHIFT_) |
 					(crc & WUF_CFGX_CRC16_MASK_));
 
-		ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 7);
-		ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0);
-		ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0);
-		ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0);
+		lan78xx_write_reg(dev, WUF_MASK0(mask_index), 7);
+		lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0);
+		lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0);
+		lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0);
 		mask_index++;
 
 		/* for IPv6 Multicast */
 		crc = lan78xx_wakeframe_crc16(ipv6_multicast, 2);
-		ret = lan78xx_write_reg(dev, WUF_CFG(mask_index),
+		lan78xx_write_reg(dev, WUF_CFG(mask_index),
 					WUF_CFGX_EN_ |
 					WUF_CFGX_TYPE_MCAST_ |
 					(0 << WUF_CFGX_OFFSET_SHIFT_) |
 					(crc & WUF_CFGX_CRC16_MASK_));
 
-		ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 3);
-		ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0);
-		ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0);
-		ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0);
+		lan78xx_write_reg(dev, WUF_MASK0(mask_index), 3);
+		lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0);
+		lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0);
+		lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0);
 		mask_index++;
 
 		temp_pmt_ctl |= PMT_CTL_WOL_EN_;
@@ -3921,16 +3884,16 @@
 		 * for packettype (offset 12,13) = ARP (0x0806)
 		 */
 		crc = lan78xx_wakeframe_crc16(arp_type, 2);
-		ret = lan78xx_write_reg(dev, WUF_CFG(mask_index),
+		lan78xx_write_reg(dev, WUF_CFG(mask_index),
 					WUF_CFGX_EN_ |
 					WUF_CFGX_TYPE_ALL_ |
 					(0 << WUF_CFGX_OFFSET_SHIFT_) |
 					(crc & WUF_CFGX_CRC16_MASK_));
 
-		ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 0x3000);
-		ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0);
-		ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0);
-		ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0);
+		lan78xx_write_reg(dev, WUF_MASK0(mask_index), 0x3000);
+		lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0);
+		lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0);
+		lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0);
 		mask_index++;
 
 		temp_pmt_ctl |= PMT_CTL_WOL_EN_;
@@ -3938,7 +3901,7 @@
 		temp_pmt_ctl |= PMT_CTL_SUS_MODE_0_;
 	}
 
-	ret = lan78xx_write_reg(dev, WUCSR, temp_wucsr);
+	lan78xx_write_reg(dev, WUCSR, temp_wucsr);
 
 	/* when multiple WOL bits are set */
 	if (hweight_long((unsigned long)wol) > 1) {
@@ -3946,16 +3909,16 @@
 		temp_pmt_ctl &= ~PMT_CTL_SUS_MODE_MASK_;
 		temp_pmt_ctl |= PMT_CTL_SUS_MODE_0_;
 	}
-	ret = lan78xx_write_reg(dev, PMT_CTL, temp_pmt_ctl);
+	lan78xx_write_reg(dev, PMT_CTL, temp_pmt_ctl);
 
 	/* clear WUPS */
-	ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
+	lan78xx_read_reg(dev, PMT_CTL, &buf);
 	buf |= PMT_CTL_WUPS_MASK_;
-	ret = lan78xx_write_reg(dev, PMT_CTL, buf);
+	lan78xx_write_reg(dev, PMT_CTL, buf);
 
-	ret = lan78xx_read_reg(dev, MAC_RX, &buf);
+	lan78xx_read_reg(dev, MAC_RX, &buf);
 	buf |= MAC_RX_RXEN_;
-	ret = lan78xx_write_reg(dev, MAC_RX, buf);
+	lan78xx_write_reg(dev, MAC_RX, buf);
 
 	return 0;
 }
diff --git a/kernel/drivers/net/usb/plusb.c b/kernel/drivers/net/usb/plusb.c
index 17c9c63..ce7862d 100644
--- a/kernel/drivers/net/usb/plusb.c
+++ b/kernel/drivers/net/usb/plusb.c
@@ -57,9 +57,7 @@
 static inline int
 pl_vendor_req(struct usbnet *dev, u8 req, u8 val, u8 index)
 {
-	return usbnet_read_cmd(dev, req,
-				USB_DIR_IN | USB_TYPE_VENDOR |
-				USB_RECIP_DEVICE,
+	return usbnet_write_cmd(dev, req, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 				val, index, NULL, 0);
 }
 
diff --git a/kernel/drivers/net/usb/qmi_wwan.c b/kernel/drivers/net/usb/qmi_wwan.c
index bce151e..5cf7f38 100644
--- a/kernel/drivers/net/usb/qmi_wwan.c
+++ b/kernel/drivers/net/usb/qmi_wwan.c
@@ -1156,7 +1156,9 @@
 	{QMI_FIXED_INTF(0x05c6, 0x9080, 8)},
 	{QMI_FIXED_INTF(0x05c6, 0x9083, 3)},
 	{QMI_FIXED_INTF(0x05c6, 0x9084, 4)},
+	{QMI_QUIRK_SET_DTR(0x05c6, 0x9091, 2)},	/* Compal RXM-G1 */
 	{QMI_FIXED_INTF(0x05c6, 0x90b2, 3)},    /* ublox R410M */
+	{QMI_QUIRK_SET_DTR(0x05c6, 0x90db, 2)},	/* Compal RXM-G1 */
 	{QMI_FIXED_INTF(0x05c6, 0x920d, 0)},
 	{QMI_FIXED_INTF(0x05c6, 0x920d, 5)},
 	{QMI_QUIRK_SET_DTR(0x05c6, 0x9625, 4)},	/* YUGA CLM920-NC5 */
@@ -1260,7 +1262,7 @@
 	{QMI_FIXED_INTF(0x2001, 0x7e3d, 4)},	/* D-Link DWM-222 A2 */
 	{QMI_FIXED_INTF(0x2020, 0x2031, 4)},	/* Olicard 600 */
 	{QMI_FIXED_INTF(0x2020, 0x2033, 4)},	/* BroadMobi BM806U */
-	{QMI_FIXED_INTF(0x2020, 0x2060, 4)},	/* BroadMobi BM818 */
+	{QMI_QUIRK_SET_DTR(0x2020, 0x2060, 4)},	/* BroadMobi BM818 */
 	{QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)},    /* Sierra Wireless MC7700 */
 	{QMI_FIXED_INTF(0x114f, 0x68a2, 8)},    /* Sierra Wireless MC7750 */
 	{QMI_FIXED_INTF(0x1199, 0x68a2, 8)},	/* Sierra Wireless MC7710 in QMI mode */
@@ -1297,6 +1299,7 @@
 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)},	/* Telit FN980 */
 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1060, 2)},	/* Telit LN920 */
 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1070, 2)},	/* Telit FN990 */
+	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1080, 2)}, /* Telit FE990 */
 	{QMI_FIXED_INTF(0x1bc7, 0x1100, 3)},	/* Telit ME910 */
 	{QMI_FIXED_INTF(0x1bc7, 0x1101, 3)},	/* Telit ME910 dual modem */
 	{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},	/* Telit LE920 */
@@ -1348,6 +1351,7 @@
 	{QMI_QUIRK_SET_DTR(0x2c7c, 0x0191, 4)},	/* Quectel EG91 */
 	{QMI_QUIRK_SET_DTR(0x2c7c, 0x0195, 4)},	/* Quectel EG95 */
 	{QMI_FIXED_INTF(0x2c7c, 0x0296, 4)},	/* Quectel BG96 */
+	{QMI_QUIRK_SET_DTR(0x2c7c, 0x030e, 4)},	/* Quectel EM05GV2 */
 	{QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)},	/* Fibocom NL678 series */
 	{QMI_FIXED_INTF(0x0489, 0xe0b4, 0)},	/* Foxconn T77W968 LTE */
 	{QMI_FIXED_INTF(0x0489, 0xe0b5, 0)},	/* Foxconn T77W968 LTE with eSIM support*/
diff --git a/kernel/drivers/net/usb/r8152.c b/kernel/drivers/net/usb/r8152.c
index f9a79d6..cc7c86d 100644
--- a/kernel/drivers/net/usb/r8152.c
+++ b/kernel/drivers/net/usb/r8152.c
@@ -2439,6 +2439,9 @@
 	struct r8152 *tp = container_of(napi, struct r8152, napi);
 	int work_done;
 
+	if (!budget)
+		return 0;
+
 	work_done = rx_bottom(tp, budget);
 
 	if (work_done < budget) {
diff --git a/kernel/drivers/net/usb/rndis_host.c b/kernel/drivers/net/usb/rndis_host.c
index 1505fe3..1ff723e 100644
--- a/kernel/drivers/net/usb/rndis_host.c
+++ b/kernel/drivers/net/usb/rndis_host.c
@@ -255,7 +255,8 @@
 
 	off = le32_to_cpu(u.get_c->offset);
 	len = le32_to_cpu(u.get_c->len);
-	if (unlikely((8 + off + len) > CONTROL_BUFFER_SIZE))
+	if (unlikely((off > CONTROL_BUFFER_SIZE - 8) ||
+		     (len > CONTROL_BUFFER_SIZE - 8 - off)))
 		goto response_error;
 
 	if (*reply_len != -1 && len != *reply_len)
diff --git a/kernel/drivers/net/usb/smsc75xx.c b/kernel/drivers/net/usb/smsc75xx.c
index 378a12a..6310841 100644
--- a/kernel/drivers/net/usb/smsc75xx.c
+++ b/kernel/drivers/net/usb/smsc75xx.c
@@ -90,7 +90,9 @@
 	ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN
 		 | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 		 0, index, &buf, 4);
-	if (unlikely(ret < 0)) {
+	if (unlikely(ret < 4)) {
+		ret = ret < 0 ? ret : -ENODATA;
+
 		netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n",
 			    index, ret);
 		return ret;
@@ -2199,6 +2201,13 @@
 		size = (rx_cmd_a & RX_CMD_A_LEN) - RXW_PADDING;
 		align_count = (4 - ((size + RXW_PADDING) % 4)) % 4;
 
+		if (unlikely(size > skb->len)) {
+			netif_dbg(dev, rx_err, dev->net,
+				  "size err rx_cmd_a=0x%08x\n",
+				  rx_cmd_a);
+			return 0;
+		}
+
 		if (unlikely(rx_cmd_a & RX_CMD_A_RED)) {
 			netif_dbg(dev, rx_err, dev->net,
 				  "Error rx_cmd_a=0x%08x\n", rx_cmd_a);
diff --git a/kernel/drivers/net/usb/smsc95xx.c b/kernel/drivers/net/usb/smsc95xx.c
index e1cd4c2..975f526 100644
--- a/kernel/drivers/net/usb/smsc95xx.c
+++ b/kernel/drivers/net/usb/smsc95xx.c
@@ -1824,6 +1824,12 @@
 		size = (u16)((header & RX_STS_FL_) >> 16);
 		align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4;
 
+		if (unlikely(size > skb->len)) {
+			netif_dbg(dev, rx_err, dev->net,
+				  "size err header=0x%08x\n", header);
+			return 0;
+		}
+
 		if (unlikely(header & RX_STS_ES_)) {
 			netif_dbg(dev, rx_err, dev->net,
 				  "Error header=0x%08x\n", header);
diff --git a/kernel/drivers/net/usb/sr9700.c b/kernel/drivers/net/usb/sr9700.c
index fce6713..811c875 100644
--- a/kernel/drivers/net/usb/sr9700.c
+++ b/kernel/drivers/net/usb/sr9700.c
@@ -410,7 +410,7 @@
 		/* ignore the CRC length */
 		len = (skb->data[1] | (skb->data[2] << 8)) - 4;
 
-		if (len > ETH_FRAME_LEN || len > skb->len)
+		if (len > ETH_FRAME_LEN || len > skb->len || len < 0)
 			return 0;
 
 		/* the last packet of current skb */
diff --git a/kernel/drivers/net/usb/usbnet.c b/kernel/drivers/net/usb/usbnet.c
index 43d7034..481a41d 100644
--- a/kernel/drivers/net/usb/usbnet.c
+++ b/kernel/drivers/net/usb/usbnet.c
@@ -1738,6 +1738,10 @@
 	} else if (!info->in || !info->out)
 		status = usbnet_get_endpoints (dev, udev);
 	else {
+		u8 ep_addrs[3] = {
+			info->in + USB_DIR_IN, info->out + USB_DIR_OUT, 0
+		};
+
 		dev->in = usb_rcvbulkpipe (xdev, info->in);
 		dev->out = usb_sndbulkpipe (xdev, info->out);
 		if (!(info->flags & FLAG_NO_SETINT))
@@ -1747,6 +1751,8 @@
 		else
 			status = 0;
 
+		if (status == 0 && !usb_check_bulk_endpoints(udev, ep_addrs))
+			status = -EINVAL;
 	}
 	if (status >= 0 && dev->status)
 		status = init_status (dev, udev);
diff --git a/kernel/drivers/net/usb/zaurus.c b/kernel/drivers/net/usb/zaurus.c
index 7984f21..df3617c 100644
--- a/kernel/drivers/net/usb/zaurus.c
+++ b/kernel/drivers/net/usb/zaurus.c
@@ -289,9 +289,23 @@
 	.match_flags	=   USB_DEVICE_ID_MATCH_INT_INFO
 			  | USB_DEVICE_ID_MATCH_DEVICE,
 	.idVendor		= 0x04DD,
+	.idProduct		= 0x8005,	/* A-300 */
+	ZAURUS_FAKE_INTERFACE,
+	.driver_info = (unsigned long)&bogus_mdlm_info,
+}, {
+	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+			  | USB_DEVICE_ID_MATCH_DEVICE,
+	.idVendor		= 0x04DD,
 	.idProduct		= 0x8006,	/* B-500/SL-5600 */
 	ZAURUS_MASTER_INTERFACE,
 	.driver_info = ZAURUS_PXA_INFO,
+}, {
+	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+			  | USB_DEVICE_ID_MATCH_DEVICE,
+	.idVendor		= 0x04DD,
+	.idProduct		= 0x8006,	/* B-500/SL-5600 */
+	ZAURUS_FAKE_INTERFACE,
+	.driver_info = (unsigned long)&bogus_mdlm_info,
 }, {
 	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 	          | USB_DEVICE_ID_MATCH_DEVICE,
@@ -301,6 +315,13 @@
 	.driver_info = ZAURUS_PXA_INFO,
 }, {
 	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+			  | USB_DEVICE_ID_MATCH_DEVICE,
+	.idVendor		= 0x04DD,
+	.idProduct		= 0x8007,	/* C-700 */
+	ZAURUS_FAKE_INTERFACE,
+	.driver_info = (unsigned long)&bogus_mdlm_info,
+}, {
+	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 		 | USB_DEVICE_ID_MATCH_DEVICE,
 	.idVendor               = 0x04DD,
 	.idProduct              = 0x9031,	/* C-750 C-760 */
diff --git a/kernel/drivers/net/veth.c b/kernel/drivers/net/veth.c
index 5be8ed9..743716e 100644
--- a/kernel/drivers/net/veth.c
+++ b/kernel/drivers/net/veth.c
@@ -285,6 +285,7 @@
 {
 	struct veth_priv *rcv_priv, *priv = netdev_priv(dev);
 	struct veth_rq *rq = NULL;
+	int ret = NETDEV_TX_OK;
 	struct net_device *rcv;
 	int length = skb->len;
 	bool rcv_xdp = false;
@@ -311,6 +312,7 @@
 	} else {
 drop:
 		atomic64_inc(&priv->dropped);
+		ret = NET_XMIT_DROP;
 	}
 
 	if (rcv_xdp)
@@ -318,7 +320,7 @@
 
 	rcu_read_unlock();
 
-	return NETDEV_TX_OK;
+	return ret;
 }
 
 static u64 veth_stats_tx(struct net_device *dev, u64 *packets, u64 *bytes)
@@ -849,6 +851,9 @@
 	xdp_set_return_frame_no_direct();
 	done = veth_xdp_rcv(rq, budget, &bq, &stats);
 
+	if (stats.xdp_redirect > 0)
+		xdp_do_flush();
+
 	if (done < budget && napi_complete_done(napi, done)) {
 		/* Write rx_notify_masked before reading ptr_ring */
 		smp_store_mb(rq->rx_notify_masked, false);
@@ -862,8 +867,6 @@
 
 	if (stats.xdp_tx > 0)
 		veth_xdp_flush(rq, &bq);
-	if (stats.xdp_redirect > 0)
-		xdp_do_flush();
 	xdp_clear_return_frame_no_direct();
 
 	return done;
@@ -1312,10 +1315,7 @@
 
 		nla_peer = data[VETH_INFO_PEER];
 		ifmp = nla_data(nla_peer);
-		err = rtnl_nla_parse_ifla(peer_tb,
-					  nla_data(nla_peer) + sizeof(struct ifinfomsg),
-					  nla_len(nla_peer) - sizeof(struct ifinfomsg),
-					  NULL);
+		err = rtnl_nla_parse_ifinfomsg(peer_tb, nla_peer, extack);
 		if (err < 0)
 			return err;
 
diff --git a/kernel/drivers/net/virtio_net.c b/kernel/drivers/net/virtio_net.c
index ca69936..61d83d5 100644
--- a/kernel/drivers/net/virtio_net.c
+++ b/kernel/drivers/net/virtio_net.c
@@ -646,8 +646,13 @@
 				       int page_off,
 				       unsigned int *len)
 {
-	struct page *page = alloc_page(GFP_ATOMIC);
+	int tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+	struct page *page;
 
+	if (page_off + *len + tailroom > PAGE_SIZE)
+		return NULL;
+
+	page = alloc_page(GFP_ATOMIC);
 	if (!page)
 		return NULL;
 
@@ -655,7 +660,6 @@
 	page_off += *len;
 
 	while (--*num_buf) {
-		int tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 		unsigned int buflen;
 		void *buf;
 		int off;
@@ -1525,12 +1529,12 @@
 
 	received = virtnet_receive(rq, budget, &xdp_xmit);
 
+	if (xdp_xmit & VIRTIO_XDP_REDIR)
+		xdp_do_flush();
+
 	/* Out of packets? */
 	if (received < budget)
 		virtqueue_napi_complete(napi, rq->vq, received);
-
-	if (xdp_xmit & VIRTIO_XDP_REDIR)
-		xdp_do_flush();
 
 	if (xdp_xmit & VIRTIO_XDP_TX) {
 		sq = virtnet_xdp_get_sq(vi);
@@ -1928,8 +1932,8 @@
 	cancel_delayed_work_sync(&vi->refill);
 
 	for (i = 0; i < vi->max_queue_pairs; i++) {
-		xdp_rxq_info_unreg(&vi->rq[i].xdp_rxq);
 		napi_disable(&vi->rq[i].napi);
+		xdp_rxq_info_unreg(&vi->rq[i].xdp_rxq);
 		virtnet_napi_tx_disable(&vi->sq[i].napi);
 	}
 
@@ -2746,6 +2750,27 @@
 			put_page(vi->rq[i].alloc_frag.page);
 }
 
+static void virtnet_sq_free_unused_buf(struct virtqueue *vq, void *buf)
+{
+	if (!is_xdp_frame(buf))
+		dev_kfree_skb(buf);
+	else
+		xdp_return_frame(ptr_to_xdp(buf));
+}
+
+static void virtnet_rq_free_unused_buf(struct virtqueue *vq, void *buf)
+{
+	struct virtnet_info *vi = vq->vdev->priv;
+	int i = vq2rxq(vq);
+
+	if (vi->mergeable_rx_bufs)
+		put_page(virt_to_head_page(buf));
+	else if (vi->big_packets)
+		give_pages(&vi->rq[i], buf);
+	else
+		put_page(virt_to_head_page(buf));
+}
+
 static void free_unused_bufs(struct virtnet_info *vi)
 {
 	void *buf;
@@ -2753,26 +2778,16 @@
 
 	for (i = 0; i < vi->max_queue_pairs; i++) {
 		struct virtqueue *vq = vi->sq[i].vq;
-		while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) {
-			if (!is_xdp_frame(buf))
-				dev_kfree_skb(buf);
-			else
-				xdp_return_frame(ptr_to_xdp(buf));
-		}
+		while ((buf = virtqueue_detach_unused_buf(vq)) != NULL)
+			virtnet_sq_free_unused_buf(vq, buf);
+		cond_resched();
 	}
 
 	for (i = 0; i < vi->max_queue_pairs; i++) {
 		struct virtqueue *vq = vi->rq[i].vq;
-
-		while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) {
-			if (vi->mergeable_rx_bufs) {
-				put_page(virt_to_head_page(buf));
-			} else if (vi->big_packets) {
-				give_pages(&vi->rq[i], buf);
-			} else {
-				put_page(virt_to_head_page(buf));
-			}
-		}
+		while ((buf = virtqueue_detach_unused_buf(vq)) != NULL)
+			virtnet_rq_free_unused_buf(vq, buf);
+		cond_resched();
 	}
 }
 
@@ -3220,6 +3235,8 @@
 
 	virtio_device_ready(vdev);
 
+	_virtnet_set_queues(vi, vi->curr_queue_pairs);
+
 	rtnl_unlock();
 
 	err = virtnet_cpu_notif_add(vi);
@@ -3227,8 +3244,6 @@
 		pr_debug("virtio_net: registering cpu notifier failed\n");
 		goto free_unregister_netdev;
 	}
-
-	virtnet_set_queues(vi, vi->curr_queue_pairs);
 
 	/* Assume link up if device can't report link status,
 	   otherwise get link status from config. */
diff --git a/kernel/drivers/net/vmxnet3/vmxnet3_drv.c b/kernel/drivers/net/vmxnet3/vmxnet3_drv.c
index 43a4bcd..3b889fe 100644
--- a/kernel/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/kernel/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -1236,6 +1236,10 @@
 		    (le32_to_cpu(gdesc->dword[3]) &
 		     VMXNET3_RCD_CSUM_OK) == VMXNET3_RCD_CSUM_OK) {
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
+			if ((le32_to_cpu(gdesc->dword[0]) &
+				     (1UL << VMXNET3_RCD_HDR_INNER_SHIFT))) {
+				skb->csum_level = 1;
+			}
 			WARN_ON_ONCE(!(gdesc->rcd.tcp || gdesc->rcd.udp) &&
 				     !(le32_to_cpu(gdesc->dword[0]) &
 				     (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
@@ -1245,6 +1249,10 @@
 		} else if (gdesc->rcd.v6 && (le32_to_cpu(gdesc->dword[3]) &
 					     (1 << VMXNET3_RCD_TUC_SHIFT))) {
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
+			if ((le32_to_cpu(gdesc->dword[0]) &
+				     (1UL << VMXNET3_RCD_HDR_INNER_SHIFT))) {
+				skb->csum_level = 1;
+			}
 			WARN_ON_ONCE(!(gdesc->rcd.tcp || gdesc->rcd.udp) &&
 				     !(le32_to_cpu(gdesc->dword[0]) &
 				     (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
diff --git a/kernel/drivers/net/vxlan/Makefile b/kernel/drivers/net/vxlan/Makefile
new file mode 100644
index 0000000..5672661
--- /dev/null
+++ b/kernel/drivers/net/vxlan/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the vxlan driver
+#
+
+obj-$(CONFIG_VXLAN) += vxlan.o
+
+vxlan-objs := vxlan_core.o
diff --git a/kernel/drivers/net/vxlan.c b/kernel/drivers/net/vxlan/vxlan_core.c
similarity index 98%
rename from kernel/drivers/net/vxlan.c
rename to kernel/drivers/net/vxlan/vxlan_core.c
index 72d6706..3096769 100644
--- a/kernel/drivers/net/vxlan.c
+++ b/kernel/drivers/net/vxlan/vxlan_core.c
@@ -729,6 +729,32 @@
 	return 1;
 }
 
+static bool vxlan_parse_gpe_proto(struct vxlanhdr *hdr, __be16 *protocol)
+{
+	struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)hdr;
+
+	/* Need to have Next Protocol set for interfaces in GPE mode. */
+	if (!gpe->np_applied)
+		return false;
+	/* "The initial version is 0. If a receiver does not support the
+	 * version indicated it MUST drop the packet.
+	 */
+	if (gpe->version != 0)
+		return false;
+	/* "When the O bit is set to 1, the packet is an OAM packet and OAM
+	 * processing MUST occur." However, we don't implement OAM
+	 * processing, thus drop the packet.
+	 */
+	if (gpe->oam_flag)
+		return false;
+
+	*protocol = tun_p_to_eth_p(gpe->next_protocol);
+	if (!*protocol)
+		return false;
+
+	return true;
+}
+
 static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb,
 					  unsigned int off,
 					  struct vxlanhdr *vh, size_t hdrlen,
@@ -1737,35 +1763,6 @@
 	unparsed->vx_flags &= ~VXLAN_GBP_USED_BITS;
 }
 
-static bool vxlan_parse_gpe_hdr(struct vxlanhdr *unparsed,
-				__be16 *protocol,
-				struct sk_buff *skb, u32 vxflags)
-{
-	struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)unparsed;
-
-	/* Need to have Next Protocol set for interfaces in GPE mode. */
-	if (!gpe->np_applied)
-		return false;
-	/* "The initial version is 0. If a receiver does not support the
-	 * version indicated it MUST drop the packet.
-	 */
-	if (gpe->version != 0)
-		return false;
-	/* "When the O bit is set to 1, the packet is an OAM packet and OAM
-	 * processing MUST occur." However, we don't implement OAM
-	 * processing, thus drop the packet.
-	 */
-	if (gpe->oam_flag)
-		return false;
-
-	*protocol = tun_p_to_eth_p(gpe->next_protocol);
-	if (!*protocol)
-		return false;
-
-	unparsed->vx_flags &= ~VXLAN_GPE_USED_BITS;
-	return true;
-}
-
 static bool vxlan_set_mac(struct vxlan_dev *vxlan,
 			  struct vxlan_sock *vs,
 			  struct sk_buff *skb, __be32 vni)
@@ -1866,8 +1863,9 @@
 	 * used by VXLAN extensions if explicitly requested.
 	 */
 	if (vs->flags & VXLAN_F_GPE) {
-		if (!vxlan_parse_gpe_hdr(&unparsed, &protocol, skb, vs->flags))
+		if (!vxlan_parse_gpe_proto(&unparsed, &protocol))
 			goto drop;
+		unparsed.vx_flags &= ~VXLAN_GPE_USED_BITS;
 		raw_proto = true;
 	}
 
@@ -2720,7 +2718,7 @@
 		}
 
 		ndst = &rt->dst;
-		err = skb_tunnel_check_pmtu(skb, ndst, VXLAN_HEADROOM,
+		err = skb_tunnel_check_pmtu(skb, ndst, vxlan_headroom(flags & VXLAN_F_GPE),
 					    netif_is_any_bridge_port(dev));
 		if (err < 0) {
 			goto tx_error;
@@ -2781,7 +2779,8 @@
 				goto out_unlock;
 		}
 
-		err = skb_tunnel_check_pmtu(skb, ndst, VXLAN6_HEADROOM,
+		err = skb_tunnel_check_pmtu(skb, ndst,
+					    vxlan_headroom((flags & VXLAN_F_GPE) | VXLAN_F_IPV6),
 					    netif_is_any_bridge_port(dev));
 		if (err < 0) {
 			goto tx_error;
@@ -3158,14 +3157,12 @@
 	struct vxlan_rdst *dst = &vxlan->default_dst;
 	struct net_device *lowerdev = __dev_get_by_index(vxlan->net,
 							 dst->remote_ifindex);
-	bool use_ipv6 = !!(vxlan->cfg.flags & VXLAN_F_IPV6);
 
 	/* This check is different than dev->max_mtu, because it looks at
 	 * the lowerdev->mtu, rather than the static dev->max_mtu
 	 */
 	if (lowerdev) {
-		int max_mtu = lowerdev->mtu -
-			      (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
+		int max_mtu = lowerdev->mtu - vxlan_headroom(vxlan->cfg.flags);
 		if (new_mtu > max_mtu)
 			return -EINVAL;
 	}
@@ -3784,11 +3781,11 @@
 	struct vxlan_dev *vxlan = netdev_priv(dev);
 	struct vxlan_rdst *dst = &vxlan->default_dst;
 	unsigned short needed_headroom = ETH_HLEN;
-	bool use_ipv6 = !!(conf->flags & VXLAN_F_IPV6);
 	int max_mtu = ETH_MAX_MTU;
+	u32 flags = conf->flags;
 
 	if (!changelink) {
-		if (conf->flags & VXLAN_F_GPE)
+		if (flags & VXLAN_F_GPE)
 			vxlan_raw_setup(dev);
 		else
 			vxlan_ether_setup(dev);
@@ -3814,8 +3811,7 @@
 
 		dev->needed_tailroom = lowerdev->needed_tailroom;
 
-		max_mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM :
-					   VXLAN_HEADROOM);
+		max_mtu = lowerdev->mtu - vxlan_headroom(flags);
 		if (max_mtu < ETH_MIN_MTU)
 			max_mtu = ETH_MIN_MTU;
 
@@ -3826,10 +3822,9 @@
 	if (dev->mtu > max_mtu)
 		dev->mtu = max_mtu;
 
-	if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA)
-		needed_headroom += VXLAN6_HEADROOM;
-	else
-		needed_headroom += VXLAN_HEADROOM;
+	if (flags & VXLAN_F_COLLECT_METADATA)
+		flags |= VXLAN_F_IPV6;
+	needed_headroom += vxlan_headroom(flags);
 	dev->needed_headroom = needed_headroom;
 
 	memcpy(&vxlan->cfg, conf, sizeof(*conf));
diff --git a/kernel/drivers/net/wan/farsync.c b/kernel/drivers/net/wan/farsync.c
index b50cf11..36a6958 100644
--- a/kernel/drivers/net/wan/farsync.c
+++ b/kernel/drivers/net/wan/farsync.c
@@ -2612,6 +2612,7 @@
 	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 @@
 				  card->tx_dma_handle_card);
 	}
 	fst_card_array[card->card_no] = NULL;
+	kfree(card);
 }
 
 static struct pci_driver fst_driver = {
diff --git a/kernel/drivers/net/wan/fsl_ucc_hdlc.c b/kernel/drivers/net/wan/fsl_ucc_hdlc.c
index 7eac6a3..bc3650c 100644
--- a/kernel/drivers/net/wan/fsl_ucc_hdlc.c
+++ b/kernel/drivers/net/wan/fsl_ucc_hdlc.c
@@ -34,6 +34,8 @@
 #define TDM_PPPOHT_SLIC_MAXIN
 #define RX_BD_ERRORS (R_CD_S | R_OV_S | R_CR_S | R_AB_S | R_NO_S | R_LG_S)
 
+static int uhdlc_close(struct net_device *dev);
+
 static struct ucc_tdm_info utdm_primary_info = {
 	.uf_info = {
 		.tsa = 0,
@@ -708,6 +710,7 @@
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 	struct ucc_hdlc_private *priv = hdlc->priv;
 	struct ucc_tdm *utdm = priv->utdm;
+	int rc = 0;
 
 	if (priv->hdlc_busy != 1) {
 		if (request_irq(priv->ut_info->uf_info.irq,
@@ -731,10 +734,13 @@
 		napi_enable(&priv->napi);
 		netdev_reset_queue(dev);
 		netif_start_queue(dev);
-		hdlc_open(dev);
+
+		rc = hdlc_open(dev);
+		if (rc)
+			uhdlc_close(dev);
 	}
 
-	return 0;
+	return rc;
 }
 
 static void uhdlc_memclean(struct ucc_hdlc_private *priv)
@@ -823,6 +829,8 @@
 	netif_stop_queue(dev);
 	netdev_reset_queue(dev);
 	priv->hdlc_busy = 0;
+
+	hdlc_close(dev);
 
 	return 0;
 }
@@ -1245,9 +1253,11 @@
 free_dev:
 	free_netdev(dev);
 undo_uhdlc_init:
-	iounmap(utdm->siram);
+	if (utdm)
+		iounmap(utdm->siram);
 unmap_si_regs:
-	iounmap(utdm->si_regs);
+	if (utdm)
+		iounmap(utdm->si_regs);
 free_utdm:
 	if (uhdlc_priv->tsa)
 		kfree(utdm);
diff --git a/kernel/drivers/net/wan/lapbether.c b/kernel/drivers/net/wan/lapbether.c
index b965eb6..24c53cc 100644
--- a/kernel/drivers/net/wan/lapbether.c
+++ b/kernel/drivers/net/wan/lapbether.c
@@ -341,6 +341,9 @@
 
 	ASSERT_RTNL();
 
+	if (dev->type != ARPHRD_ETHER)
+		return -EINVAL;
+
 	ndev = alloc_netdev(sizeof(*lapbeth), "lapb%d", NET_NAME_UNKNOWN,
 			    lapbeth_setup);
 	if (!ndev)
diff --git a/kernel/drivers/net/wireguard/allowedips.c b/kernel/drivers/net/wireguard/allowedips.c
index 5bf7822..0ba714c 100644
--- a/kernel/drivers/net/wireguard/allowedips.c
+++ b/kernel/drivers/net/wireguard/allowedips.c
@@ -6,7 +6,7 @@
 #include "allowedips.h"
 #include "peer.h"
 
-enum { MAX_ALLOWEDIPS_BITS = 128 };
+enum { MAX_ALLOWEDIPS_DEPTH = 129 };
 
 static struct kmem_cache *node_cache;
 
@@ -42,7 +42,7 @@
 		     struct allowedips_node __rcu *p, unsigned int *len)
 {
 	if (rcu_access_pointer(p)) {
-		if (WARN_ON(IS_ENABLED(DEBUG) && *len >= MAX_ALLOWEDIPS_BITS))
+		if (WARN_ON(IS_ENABLED(DEBUG) && *len >= MAX_ALLOWEDIPS_DEPTH))
 			return;
 		stack[(*len)++] = rcu_dereference_raw(p);
 	}
@@ -55,7 +55,7 @@
 
 static void root_free_rcu(struct rcu_head *rcu)
 {
-	struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = {
+	struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_DEPTH] = {
 		container_of(rcu, struct allowedips_node, rcu) };
 	unsigned int len = 1;
 
@@ -68,7 +68,7 @@
 
 static void root_remove_peer_lists(struct allowedips_node *root)
 {
-	struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = { root };
+	struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_DEPTH] = { root };
 	unsigned int len = 1;
 
 	while (len > 0 && (node = stack[--len])) {
diff --git a/kernel/drivers/net/wireguard/netlink.c b/kernel/drivers/net/wireguard/netlink.c
index 5c804bc..f5bc279 100644
--- a/kernel/drivers/net/wireguard/netlink.c
+++ b/kernel/drivers/net/wireguard/netlink.c
@@ -546,6 +546,7 @@
 		u8 *private_key = nla_data(info->attrs[WGDEVICE_A_PRIVATE_KEY]);
 		u8 public_key[NOISE_PUBLIC_KEY_LEN];
 		struct wg_peer *peer, *temp;
+		bool send_staged_packets;
 
 		if (!crypto_memneq(wg->static_identity.static_private,
 				   private_key, NOISE_PUBLIC_KEY_LEN))
@@ -564,14 +565,17 @@
 		}
 
 		down_write(&wg->static_identity.lock);
-		wg_noise_set_static_identity_private_key(&wg->static_identity,
-							 private_key);
-		list_for_each_entry_safe(peer, temp, &wg->peer_list,
-					 peer_list) {
+		send_staged_packets = !wg->static_identity.has_identity && netif_running(wg->dev);
+		wg_noise_set_static_identity_private_key(&wg->static_identity, private_key);
+		send_staged_packets = send_staged_packets && wg->static_identity.has_identity;
+
+		wg_cookie_checker_precompute_device_keys(&wg->cookie_checker);
+		list_for_each_entry_safe(peer, temp, &wg->peer_list, peer_list) {
 			wg_noise_precompute_static_static(peer);
 			wg_noise_expire_current_peer_keypairs(peer);
+			if (send_staged_packets)
+				wg_packet_send_staged_packets(peer);
 		}
-		wg_cookie_checker_precompute_device_keys(&wg->cookie_checker);
 		up_write(&wg->static_identity.lock);
 	}
 skip_set_private_key:
diff --git a/kernel/drivers/net/wireguard/queueing.c b/kernel/drivers/net/wireguard/queueing.c
index 8084e74..26d235d 100644
--- a/kernel/drivers/net/wireguard/queueing.c
+++ b/kernel/drivers/net/wireguard/queueing.c
@@ -28,6 +28,7 @@
 	int ret;
 
 	memset(queue, 0, sizeof(*queue));
+	queue->last_cpu = -1;
 	ret = ptr_ring_init(&queue->ring, len, GFP_KERNEL);
 	if (ret)
 		return ret;
diff --git a/kernel/drivers/net/wireguard/queueing.h b/kernel/drivers/net/wireguard/queueing.h
index e238810..a2e702f 100644
--- a/kernel/drivers/net/wireguard/queueing.h
+++ b/kernel/drivers/net/wireguard/queueing.h
@@ -119,20 +119,17 @@
 	return cpu;
 }
 
-/* This function is racy, in the sense that next is unlocked, so it could return
- * the same CPU twice. A race-free version of this would be to instead store an
- * atomic sequence number, do an increment-and-return, and then iterate through
- * every possible CPU until we get to that index -- choose_cpu. However that's
- * a bit slower, and it doesn't seem like this potential race actually
- * introduces any performance loss, so we live with it.
+/* This function is racy, in the sense that it's called while last_cpu is
+ * unlocked, so it could return the same CPU twice. Adding locking or using
+ * atomic sequence numbers is slower though, and the consequences of racing are
+ * harmless, so live with it.
  */
-static inline int wg_cpumask_next_online(int *next)
+static inline int wg_cpumask_next_online(int *last_cpu)
 {
-	int cpu = *next;
-
-	while (unlikely(!cpumask_test_cpu(cpu, cpu_online_mask)))
-		cpu = cpumask_next(cpu, cpu_online_mask) % nr_cpumask_bits;
-	*next = cpumask_next(cpu, cpu_online_mask) % nr_cpumask_bits;
+	int cpu = cpumask_next(*last_cpu, cpu_online_mask);
+	if (cpu >= nr_cpu_ids)
+		cpu = cpumask_first(cpu_online_mask);
+	*last_cpu = cpu;
 	return cpu;
 }
 
@@ -161,7 +158,7 @@
 
 static inline int wg_queue_enqueue_per_device_and_peer(
 	struct crypt_queue *device_queue, struct prev_queue *peer_queue,
-	struct sk_buff *skb, struct workqueue_struct *wq, int *next_cpu)
+	struct sk_buff *skb, struct workqueue_struct *wq)
 {
 	int cpu;
 
@@ -175,7 +172,7 @@
 	/* Then we queue it up in the device queue, which consumes the
 	 * packet as soon as it can.
 	 */
-	cpu = wg_cpumask_next_online(next_cpu);
+	cpu = wg_cpumask_next_online(&device_queue->last_cpu);
 	if (unlikely(ptr_ring_produce_bh(&device_queue->ring, skb)))
 		return -EPIPE;
 	queue_work_on(cpu, wq, &per_cpu_ptr(device_queue->worker, cpu)->work);
diff --git a/kernel/drivers/net/wireguard/receive.c b/kernel/drivers/net/wireguard/receive.c
index 7b8df40..f500aaf 100644
--- a/kernel/drivers/net/wireguard/receive.c
+++ b/kernel/drivers/net/wireguard/receive.c
@@ -531,7 +531,7 @@
 		goto err;
 
 	ret = wg_queue_enqueue_per_device_and_peer(&wg->decrypt_queue, &peer->rx_queue, skb,
-						   wg->packet_crypt_wq, &wg->decrypt_queue.last_cpu);
+						   wg->packet_crypt_wq);
 	if (unlikely(ret == -EPIPE))
 		wg_queue_enqueue_per_peer_rx(skb, PACKET_STATE_DEAD);
 	if (likely(!ret || ret == -EPIPE)) {
diff --git a/kernel/drivers/net/wireguard/selftest/allowedips.c b/kernel/drivers/net/wireguard/selftest/allowedips.c
index 41db10f..2c9eec2 100644
--- a/kernel/drivers/net/wireguard/selftest/allowedips.c
+++ b/kernel/drivers/net/wireguard/selftest/allowedips.c
@@ -593,16 +593,20 @@
 	wg_allowedips_remove_by_peer(&t, a, &mutex);
 	test_negative(4, a, 192, 168, 0, 1);
 
-	/* These will hit the WARN_ON(len >= MAX_ALLOWEDIPS_BITS) in free_node
+	/* These will hit the WARN_ON(len >= MAX_ALLOWEDIPS_DEPTH) in free_node
 	 * if something goes wrong.
 	 */
-	for (i = 0; i < MAX_ALLOWEDIPS_BITS; ++i) {
-		part = cpu_to_be64(~(1LLU << (i % 64)));
-		memset(&ip, 0xff, 16);
-		memcpy((u8 *)&ip + (i < 64) * 8, &part, 8);
+	for (i = 0; i < 64; ++i) {
+		part = cpu_to_be64(~0LLU << i);
+		memset(&ip, 0xff, 8);
+		memcpy((u8 *)&ip + 8, &part, 8);
+		wg_allowedips_insert_v6(&t, &ip, 128, a, &mutex);
+		memcpy(&ip, &part, 8);
+		memset((u8 *)&ip + 8, 0, 8);
 		wg_allowedips_insert_v6(&t, &ip, 128, a, &mutex);
 	}
-
+	memset(&ip, 0, 16);
+	wg_allowedips_insert_v6(&t, &ip, 128, a, &mutex);
 	wg_allowedips_free(&t, &mutex);
 
 	wg_allowedips_init(&t);
diff --git a/kernel/drivers/net/wireguard/send.c b/kernel/drivers/net/wireguard/send.c
index 5368f7c..95c853b 100644
--- a/kernel/drivers/net/wireguard/send.c
+++ b/kernel/drivers/net/wireguard/send.c
@@ -318,7 +318,7 @@
 		goto err;
 
 	ret = wg_queue_enqueue_per_device_and_peer(&wg->encrypt_queue, &peer->tx_queue, first,
-						   wg->packet_crypt_wq, &wg->encrypt_queue.last_cpu);
+						   wg->packet_crypt_wq);
 	if (unlikely(ret == -EPIPE))
 		wg_queue_enqueue_per_peer_tx(first, PACKET_STATE_DEAD);
 err:
diff --git a/kernel/drivers/net/wireguard/timers.c b/kernel/drivers/net/wireguard/timers.c
index d54d32a..91f5d6d 100644
--- a/kernel/drivers/net/wireguard/timers.c
+++ b/kernel/drivers/net/wireguard/timers.c
@@ -46,7 +46,7 @@
 	if (peer->timer_handshake_attempts > MAX_TIMER_HANDSHAKES) {
 		pr_debug("%s: Handshake for peer %llu (%pISpfsc) did not complete after %d attempts, giving up\n",
 			 peer->device->dev->name, peer->internal_id,
-			 &peer->endpoint.addr, MAX_TIMER_HANDSHAKES + 2);
+			 &peer->endpoint.addr, (int)MAX_TIMER_HANDSHAKES + 2);
 
 		del_timer(&peer->timer_send_keepalive);
 		/* We drop all packets without a keypair and don't try again,
@@ -64,7 +64,7 @@
 		++peer->timer_handshake_attempts;
 		pr_debug("%s: Handshake for peer %llu (%pISpfsc) did not complete after %d seconds, retrying (try %d)\n",
 			 peer->device->dev->name, peer->internal_id,
-			 &peer->endpoint.addr, REKEY_TIMEOUT,
+			 &peer->endpoint.addr, (int)REKEY_TIMEOUT,
 			 peer->timer_handshake_attempts + 1);
 
 		/* We clear the endpoint address src address, in case this is
@@ -94,7 +94,7 @@
 
 	pr_debug("%s: Retrying handshake with peer %llu (%pISpfsc) because we stopped hearing back after %d seconds\n",
 		 peer->device->dev->name, peer->internal_id,
-		 &peer->endpoint.addr, KEEPALIVE_TIMEOUT + REKEY_TIMEOUT);
+		 &peer->endpoint.addr, (int)(KEEPALIVE_TIMEOUT + REKEY_TIMEOUT));
 	/* We clear the endpoint address src address, in case this is the cause
 	 * of trouble.
 	 */
@@ -126,7 +126,7 @@
 
 	pr_debug("%s: Zeroing out all keys for peer %llu (%pISpfsc), since we haven't received a new one in %d seconds\n",
 		 peer->device->dev->name, peer->internal_id,
-		 &peer->endpoint.addr, REJECT_AFTER_TIME * 3);
+		 &peer->endpoint.addr, (int)REJECT_AFTER_TIME * 3);
 	wg_noise_handshake_clear(&peer->handshake);
 	wg_noise_keypairs_clear(&peer->keypairs);
 	wg_peer_put(peer);
diff --git a/kernel/drivers/net/wireless/ath/ar5523/ar5523.c b/kernel/drivers/net/wireless/ath/ar5523/ar5523.c
index 1baec4b..efe38b2 100644
--- a/kernel/drivers/net/wireless/ath/ar5523/ar5523.c
+++ b/kernel/drivers/net/wireless/ath/ar5523/ar5523.c
@@ -241,6 +241,11 @@
 	}
 }
 
+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 @@
 	}
 
 	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);
diff --git a/kernel/drivers/net/wireless/ath/ath.h b/kernel/drivers/net/wireless/ath/ath.h
index f083fb9..f02a308 100644
--- a/kernel/drivers/net/wireless/ath/ath.h
+++ b/kernel/drivers/net/wireless/ath/ath.h
@@ -96,11 +96,13 @@
 	u8 kv_type;
 	u8 kv_pad;
 	u16 kv_len;
-	u8 kv_val[16]; /* TK */
-	u8 kv_mic[8]; /* Michael MIC key */
-	u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
-			 * supports both MIC keys in the same key cache entry;
-			 * in that case, kv_mic is the RX key) */
+	struct_group(kv_values,
+		u8 kv_val[16]; /* TK */
+		u8 kv_mic[8]; /* Michael MIC key */
+		u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
+				 * supports both MIC keys in the same key cache entry;
+				 * in that case, kv_mic is the RX key) */
+	);
 };
 
 enum ath_cipher {
diff --git a/kernel/drivers/net/wireless/ath/ath10k/pci.c b/kernel/drivers/net/wireless/ath/ath10k/pci.c
index 86f52bc..2c8f04b 100644
--- a/kernel/drivers/net/wireless/ath/ath10k/pci.c
+++ b/kernel/drivers/net/wireless/ath/ath10k/pci.c
@@ -1963,8 +1963,9 @@
 	ath10k_pci_irq_enable(ar);
 	ath10k_pci_rx_post(ar);
 
-	pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL,
-				   ar_pci->link_ctl);
+	pcie_capability_clear_and_set_word(ar_pci->pdev, PCI_EXP_LNKCTL,
+					   PCI_EXP_LNKCTL_ASPMC,
+					   ar_pci->link_ctl & PCI_EXP_LNKCTL_ASPMC);
 
 	return 0;
 }
@@ -2820,8 +2821,8 @@
 
 	pcie_capability_read_word(ar_pci->pdev, PCI_EXP_LNKCTL,
 				  &ar_pci->link_ctl);
-	pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL,
-				   ar_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC);
+	pcie_capability_clear_word(ar_pci->pdev, PCI_EXP_LNKCTL,
+				   PCI_EXP_LNKCTL_ASPMC);
 
 	/*
 	 * Bring the target up cleanly.
@@ -3799,18 +3800,22 @@
 
 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);
 
diff --git a/kernel/drivers/net/wireless/ath/ath11k/core.h b/kernel/drivers/net/wireless/ath/ath11k/core.h
index d2f2898..a66e275 100644
--- a/kernel/drivers/net/wireless/ath/ath11k/core.h
+++ b/kernel/drivers/net/wireless/ath/ath11k/core.h
@@ -712,7 +712,6 @@
 	enum ath11k_dfs_region dfs_region;
 #ifdef CONFIG_ATH11K_DEBUGFS
 	struct dentry *debugfs_soc;
-	struct dentry *debugfs_ath11k;
 #endif
 	struct ath11k_soc_dp_stats soc_stats;
 
diff --git a/kernel/drivers/net/wireless/ath/ath11k/debugfs.c b/kernel/drivers/net/wireless/ath/ath11k/debugfs.c
index 1b914e6..196314a 100644
--- a/kernel/drivers/net/wireless/ath/ath11k/debugfs.c
+++ b/kernel/drivers/net/wireless/ath/ath11k/debugfs.c
@@ -836,10 +836,6 @@
 	if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
 		return 0;
 
-	ab->debugfs_soc = debugfs_create_dir(ab->hw_params.name, ab->debugfs_ath11k);
-	if (IS_ERR(ab->debugfs_soc))
-		return PTR_ERR(ab->debugfs_soc);
-
 	debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
 			    &fops_simulate_fw_crash);
 
@@ -857,15 +853,51 @@
 
 int ath11k_debugfs_soc_create(struct ath11k_base *ab)
 {
-	ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL);
+	struct dentry *root;
+	bool dput_needed;
+	char name[64];
+	int ret;
 
-	return PTR_ERR_OR_ZERO(ab->debugfs_ath11k);
+	root = debugfs_lookup("ath11k", NULL);
+	if (!root) {
+		root = debugfs_create_dir("ath11k", NULL);
+		if (IS_ERR_OR_NULL(root))
+			return PTR_ERR(root);
+
+		dput_needed = false;
+	} else {
+		/* a dentry from lookup() needs dput() after we don't use it */
+		dput_needed = true;
+	}
+
+	scnprintf(name, sizeof(name), "%s-%s", ath11k_bus_str(ab->hif.bus),
+		  dev_name(ab->dev));
+
+	ab->debugfs_soc = debugfs_create_dir(name, root);
+	if (IS_ERR_OR_NULL(ab->debugfs_soc)) {
+		ret = PTR_ERR(ab->debugfs_soc);
+		goto out;
+	}
+
+	ret = 0;
+
+out:
+	if (dput_needed)
+		dput(root);
+
+	return ret;
 }
 
 void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
 {
-	debugfs_remove_recursive(ab->debugfs_ath11k);
-	ab->debugfs_ath11k = NULL;
+	debugfs_remove_recursive(ab->debugfs_soc);
+	ab->debugfs_soc = NULL;
+
+	/* We are not removing ath11k directory on purpose, even if it
+	 * would be empty. This simplifies the directory handling and it's
+	 * a minor cosmetic issue to leave an empty ath11k directory to
+	 * debugfs.
+	 */
 }
 
 void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
diff --git a/kernel/drivers/net/wireless/ath/ath11k/dp_rx.c b/kernel/drivers/net/wireless/ath/ath11k/dp_rx.c
index 2e77dca..583bcf1 100644
--- a/kernel/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/kernel/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -324,10 +324,10 @@
 			goto fail_free_skb;
 
 		spin_lock_bh(&rx_ring->idr_lock);
-		buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 0,
-				   rx_ring->bufs_max * 3, GFP_ATOMIC);
+		buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 1,
+				   (rx_ring->bufs_max * 3) + 1, GFP_ATOMIC);
 		spin_unlock_bh(&rx_ring->idr_lock);
-		if (buf_id < 0)
+		if (buf_id <= 0)
 			goto fail_dma_unmap;
 
 		desc = ath11k_hal_srng_src_get_next_entry(ab, srng);
@@ -2564,6 +2564,9 @@
 				   cookie);
 		mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie);
 
+		if (unlikely(buf_id == 0))
+			continue;
+
 		ar = ab->pdevs[mac_id].ar;
 		rx_ring = &ar->dp.rx_refill_buf_ring;
 		spin_lock_bh(&rx_ring->idr_lock);
@@ -3022,6 +3025,7 @@
 	if (!peer) {
 		ath11k_warn(ab, "failed to find the peer to set up fragment info\n");
 		spin_unlock_bh(&ab->base_lock);
+		crypto_free_shash(tfm);
 		return -ENOENT;
 	}
 
diff --git a/kernel/drivers/net/wireless/ath/ath11k/mac.c b/kernel/drivers/net/wireless/ath/ath11k/mac.c
index 67faf62..3170c54 100644
--- a/kernel/drivers/net/wireless/ath/ath11k/mac.c
+++ b/kernel/drivers/net/wireless/ath/ath11k/mac.c
@@ -6044,7 +6044,7 @@
 	}
 
 	if (supported_bands & WMI_HOST_WLAN_5G_CAP) {
-		if (reg_cap->high_5ghz_chan >= ATH11K_MAX_6G_FREQ) {
+		if (reg_cap->high_5ghz_chan >= ATH11K_MIN_6G_FREQ) {
 			channels = kmemdup(ath11k_6ghz_channels,
 					   sizeof(ath11k_6ghz_channels), GFP_KERNEL);
 			if (!channels) {
diff --git a/kernel/drivers/net/wireless/ath/ath5k/eeprom.c b/kernel/drivers/net/wireless/ath/ath5k/eeprom.c
index d444b3d..58d3e86 100644
--- a/kernel/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/kernel/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -529,7 +529,7 @@
 		ee->ee_n_piers[mode]++;
 
 		freq2 = (val >> 8) & 0xff;
-		if (!freq2)
+		if (!freq2 || i >= max)
 			break;
 
 		pc[i++].freq = ath5k_eeprom_bin2freq(ee,
diff --git a/kernel/drivers/net/wireless/ath/ath6kl/bmi.c b/kernel/drivers/net/wireless/ath/ath6kl/bmi.c
index bde5a10..af98e87 100644
--- a/kernel/drivers/net/wireless/ath/ath6kl/bmi.c
+++ b/kernel/drivers/net/wireless/ath/ath6kl/bmi.c
@@ -246,7 +246,7 @@
 		return -EACCES;
 	}
 
-	size = sizeof(cid) + sizeof(addr) + sizeof(param);
+	size = sizeof(cid) + sizeof(addr) + sizeof(*param);
 	if (size > ar->bmi.max_cmd_size) {
 		WARN_ON(1);
 		return -EINVAL;
diff --git a/kernel/drivers/net/wireless/ath/ath6kl/htc.h b/kernel/drivers/net/wireless/ath/ath6kl/htc.h
index 112d8a9..d3534a2 100644
--- a/kernel/drivers/net/wireless/ath/ath6kl/htc.h
+++ b/kernel/drivers/net/wireless/ath/ath6kl/htc.h
@@ -153,12 +153,19 @@
  * implementations.
  */
 struct htc_frame_hdr {
-	u8 eid;
-	u8 flags;
+	struct_group_tagged(htc_frame_look_ahead, header,
+		union {
+			struct {
+				u8 eid;
+				u8 flags;
 
-	/* length of data (including trailer) that follows the header */
-	__le16 payld_len;
+				/* length of data (including trailer) that follows the header */
+				__le16 payld_len;
 
+			};
+			u32 word;
+		};
+	);
 	/* end of 4-byte lookahead */
 
 	u8 ctrl[2];
diff --git a/kernel/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/kernel/drivers/net/wireless/ath/ath6kl/htc_mbox.c
index 998947e..e387442 100644
--- a/kernel/drivers/net/wireless/ath/ath6kl/htc_mbox.c
+++ b/kernel/drivers/net/wireless/ath/ath6kl/htc_mbox.c
@@ -2260,19 +2260,16 @@
 static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target)
 {
 	struct htc_packet *packet = NULL;
-	struct htc_frame_hdr *htc_hdr;
-	u32 look_ahead;
+	struct htc_frame_look_ahead look_ahead;
 
-	if (ath6kl_hif_poll_mboxmsg_rx(target->dev, &look_ahead,
+	if (ath6kl_hif_poll_mboxmsg_rx(target->dev, &look_ahead.word,
 				       HTC_TARGET_RESPONSE_TIMEOUT))
 		return NULL;
 
 	ath6kl_dbg(ATH6KL_DBG_HTC,
-		   "htc rx wait ctrl look_ahead 0x%X\n", look_ahead);
+		   "htc rx wait ctrl look_ahead 0x%X\n", look_ahead.word);
 
-	htc_hdr = (struct htc_frame_hdr *)&look_ahead;
-
-	if (htc_hdr->eid != ENDPOINT_0)
+	if (look_ahead.eid != ENDPOINT_0)
 		return NULL;
 
 	packet = htc_get_control_buf(target, false);
@@ -2281,8 +2278,8 @@
 		return NULL;
 
 	packet->info.rx.rx_flags = 0;
-	packet->info.rx.exp_hdr = look_ahead;
-	packet->act_len = le16_to_cpu(htc_hdr->payld_len) + HTC_HDR_LENGTH;
+	packet->info.rx.exp_hdr = look_ahead.word;
+	packet->act_len = le16_to_cpu(look_ahead.payld_len) + HTC_HDR_LENGTH;
 
 	if (packet->act_len > packet->buf_len)
 		goto fail_ctrl_rx;
diff --git a/kernel/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/kernel/drivers/net/wireless/ath/ath6kl/htc_pipe.c
index c688488..9b88d96 100644
--- a/kernel/drivers/net/wireless/ath/ath6kl/htc_pipe.c
+++ b/kernel/drivers/net/wireless/ath/ath6kl/htc_pipe.c
@@ -960,8 +960,8 @@
 	 * Thus the possibility of ar->htc_target being NULL
 	 * via ath6kl_recv_complete -> ath6kl_usb_io_comp_work.
 	 */
-	if (WARN_ON_ONCE(!target)) {
-		ath6kl_err("Target not yet initialized\n");
+	if (!target) {
+		ath6kl_dbg(ATH6KL_DBG_HTC, "Target not yet initialized\n");
 		status = -EINVAL;
 		goto free_skb;
 	}
diff --git a/kernel/drivers/net/wireless/ath/ath9k/ahb.c b/kernel/drivers/net/wireless/ath/ath9k/ahb.c
index cdefb8e..05fb76a 100644
--- a/kernel/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/kernel/drivers/net/wireless/ath/ath9k/ahb.c
@@ -136,8 +136,8 @@
 
 	ah = sc->sc_ah;
 	ath9k_hw_name(ah, hw_name, sizeof(hw_name));
-	wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
-		   hw_name, (unsigned long)mem, irq);
+	wiphy_info(hw->wiphy, "%s mem=0x%p, irq=%d\n",
+		   hw_name, mem, irq);
 
 	return 0;
 
diff --git a/kernel/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/kernel/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 42f00a2..cf56481 100644
--- a/kernel/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/kernel/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -1099,17 +1099,22 @@
 {
 	u32 dma_dbg_chain, dma_dbg_complete;
 	u8 dcu_chain_state, dcu_complete_state;
+	unsigned int dbg_reg, reg_offset;
 	int i;
 
-	for (i = 0; i < NUM_STATUS_READS; i++) {
-		if (queue < 6)
-			dma_dbg_chain = REG_READ(ah, AR_DMADBG_4);
-		else
-			dma_dbg_chain = REG_READ(ah, AR_DMADBG_5);
+	if (queue < 6) {
+		dbg_reg = AR_DMADBG_4;
+		reg_offset = queue * 5;
+	} else {
+		dbg_reg = AR_DMADBG_5;
+		reg_offset = (queue - 6) * 5;
+	}
 
+	for (i = 0; i < NUM_STATUS_READS; i++) {
+		dma_dbg_chain = REG_READ(ah, dbg_reg);
 		dma_dbg_complete = REG_READ(ah, AR_DMADBG_6);
 
-		dcu_chain_state = (dma_dbg_chain >> (5 * queue)) & 0x1f;
+		dcu_chain_state = (dma_dbg_chain >> reg_offset) & 0x1f;
 		dcu_complete_state = dma_dbg_complete & 0x3;
 
 		if ((dcu_chain_state != 0x6) || (dcu_complete_state != 0x1))
@@ -1128,6 +1133,7 @@
 	u8 dcu_chain_state, dcu_complete_state;
 	bool dcu_wait_frdone = false;
 	unsigned long chk_dcu = 0;
+	unsigned int reg_offset;
 	unsigned int i = 0;
 
 	dma_dbg_4 = REG_READ(ah, AR_DMADBG_4);
@@ -1139,12 +1145,15 @@
 		goto exit;
 
 	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-		if (i < 6)
+		if (i < 6) {
 			chk_dbg = dma_dbg_4;
-		else
+			reg_offset = i * 5;
+		} else {
 			chk_dbg = dma_dbg_5;
+			reg_offset = (i - 6) * 5;
+		}
 
-		dcu_chain_state = (chk_dbg >> (5 * i)) & 0x1f;
+		dcu_chain_state = (chk_dbg >> reg_offset) & 0x1f;
 		if (dcu_chain_state == 0x6) {
 			dcu_wait_frdone = true;
 			chk_dcu |= BIT(i);
diff --git a/kernel/drivers/net/wireless/ath/ath9k/hif_usb.c b/kernel/drivers/net/wireless/ath/ath9k/hif_usb.c
index f06eec9..e0130be 100644
--- a/kernel/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/kernel/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -244,11 +244,11 @@
 		ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
 					  skb, txok);
 		if (txok) {
-			TX_STAT_INC(skb_success);
-			TX_STAT_ADD(skb_success_bytes, ln);
+			TX_STAT_INC(hif_dev, skb_success);
+			TX_STAT_ADD(hif_dev, skb_success_bytes, ln);
 		}
 		else
-			TX_STAT_INC(skb_failed);
+			TX_STAT_INC(hif_dev, skb_failed);
 	}
 }
 
@@ -302,7 +302,7 @@
 	hif_dev->tx.tx_buf_cnt++;
 	if (!(hif_dev->tx.flags & HIF_USB_TX_STOP))
 		__hif_usb_tx(hif_dev); /* Check for pending SKBs */
-	TX_STAT_INC(buf_completed);
+	TX_STAT_INC(hif_dev, buf_completed);
 	spin_unlock(&hif_dev->tx.tx_lock);
 }
 
@@ -353,7 +353,7 @@
 			tx_buf->len += tx_buf->offset;
 
 		__skb_queue_tail(&tx_buf->skb_queue, nskb);
-		TX_STAT_INC(skb_queued);
+		TX_STAT_INC(hif_dev, skb_queued);
 	}
 
 	usb_fill_bulk_urb(tx_buf->urb, hif_dev->udev,
@@ -368,10 +368,9 @@
 		__skb_queue_head_init(&tx_buf->skb_queue);
 		list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
 		hif_dev->tx.tx_buf_cnt++;
+	} else {
+		TX_STAT_INC(hif_dev, buf_queued);
 	}
-
-	if (!ret)
-		TX_STAT_INC(buf_queued);
 
 	return ret;
 }
@@ -515,7 +514,7 @@
 			ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
 						  skb, false);
 			hif_dev->tx.tx_skb_cnt--;
-			TX_STAT_INC(skb_failed);
+			TX_STAT_INC(hif_dev, skb_failed);
 		}
 	}
 
@@ -534,6 +533,24 @@
 	.sta_drain = hif_usb_sta_drain,
 	.send = hif_usb_send,
 };
+
+/* Need to free remain_skb allocated in ath9k_hif_usb_rx_stream
+ * in case ath9k_hif_usb_rx_stream wasn't called next time to
+ * process the buffer and subsequently free it.
+ */
+static void ath9k_hif_usb_free_rx_remain_skb(struct hif_device_usb *hif_dev)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&hif_dev->rx_lock, flags);
+	if (hif_dev->remain_skb) {
+		dev_kfree_skb_any(hif_dev->remain_skb);
+		hif_dev->remain_skb = NULL;
+		hif_dev->rx_remain_len = 0;
+		RX_STAT_INC(hif_dev, skb_dropped);
+	}
+	spin_unlock_irqrestore(&hif_dev->rx_lock, flags);
+}
 
 static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 				    struct sk_buff *skb)
@@ -562,11 +579,11 @@
 			memcpy(ptr, skb->data, rx_remain_len);
 
 			rx_pkt_len += rx_remain_len;
-			hif_dev->rx_remain_len = 0;
 			skb_put(remain_skb, rx_pkt_len);
 
 			skb_pool[pool_index++] = remain_skb;
-
+			hif_dev->remain_skb = NULL;
+			hif_dev->rx_remain_len = 0;
 		} else {
 			index = rx_remain_len;
 		}
@@ -585,16 +602,21 @@
 		pkt_len = get_unaligned_le16(ptr + index);
 		pkt_tag = get_unaligned_le16(ptr + index + 2);
 
+		/* It is supposed that if we have an invalid pkt_tag or
+		 * pkt_len then the whole input SKB is considered invalid
+		 * and dropped; the associated packets already in skb_pool
+		 * are dropped, too.
+		 */
 		if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) {
-			RX_STAT_INC(skb_dropped);
-			return;
+			RX_STAT_INC(hif_dev, skb_dropped);
+			goto invalid_pkt;
 		}
 
 		if (pkt_len > 2 * MAX_RX_BUF_SIZE) {
 			dev_err(&hif_dev->udev->dev,
 				"ath9k_htc: invalid pkt_len (%x)\n", pkt_len);
-			RX_STAT_INC(skb_dropped);
-			return;
+			RX_STAT_INC(hif_dev, skb_dropped);
+			goto invalid_pkt;
 		}
 
 		pad_len = 4 - (pkt_len & 0x3);
@@ -606,11 +628,6 @@
 
 		if (index > MAX_RX_BUF_SIZE) {
 			spin_lock(&hif_dev->rx_lock);
-			hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
-			hif_dev->rx_transfer_len =
-				MAX_RX_BUF_SIZE - chk_idx - 4;
-			hif_dev->rx_pad_len = pad_len;
-
 			nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
 			if (!nskb) {
 				dev_err(&hif_dev->udev->dev,
@@ -618,8 +635,14 @@
 				spin_unlock(&hif_dev->rx_lock);
 				goto err;
 			}
+
+			hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
+			hif_dev->rx_transfer_len =
+				MAX_RX_BUF_SIZE - chk_idx - 4;
+			hif_dev->rx_pad_len = pad_len;
+
 			skb_reserve(nskb, 32);
-			RX_STAT_INC(skb_allocated);
+			RX_STAT_INC(hif_dev, skb_allocated);
 
 			memcpy(nskb->data, &(skb->data[chk_idx+4]),
 			       hif_dev->rx_transfer_len);
@@ -640,7 +663,7 @@
 				goto err;
 			}
 			skb_reserve(nskb, 32);
-			RX_STAT_INC(skb_allocated);
+			RX_STAT_INC(hif_dev, skb_allocated);
 
 			memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
 			skb_put(nskb, pkt_len);
@@ -650,11 +673,18 @@
 
 err:
 	for (i = 0; i < pool_index; i++) {
-		RX_STAT_ADD(skb_completed_bytes, skb_pool[i]->len);
+		RX_STAT_ADD(hif_dev, skb_completed_bytes, skb_pool[i]->len);
 		ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i],
 				 skb_pool[i]->len, USB_WLAN_RX_PIPE);
-		RX_STAT_INC(skb_completed);
+		RX_STAT_INC(hif_dev, skb_completed);
 	}
+	return;
+invalid_pkt:
+	for (i = 0; i < pool_index; i++) {
+		dev_kfree_skb_any(skb_pool[i]);
+		RX_STAT_INC(hif_dev, skb_dropped);
+	}
+	return;
 }
 
 static void ath9k_hif_usb_rx_cb(struct urb *urb)
@@ -709,14 +739,13 @@
 	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 +754,7 @@
 	case -ECONNRESET:
 	case -ENODEV:
 	case -ESHUTDOWN:
-		goto free;
+		goto free_skb;
 	default:
 		skb_reset_tail_pointer(skb);
 		skb_trim(skb, 0);
@@ -736,25 +765,27 @@
 	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 +794,13 @@
 	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;
 }
@@ -781,14 +813,10 @@
 	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);
 
@@ -858,6 +886,7 @@
 static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
 {
 	usb_kill_anchored_urbs(&hif_dev->rx_submitted);
+	ath9k_hif_usb_free_rx_remain_skb(hif_dev);
 }
 
 static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
@@ -1330,9 +1359,23 @@
 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);
@@ -1400,8 +1443,6 @@
 
 	if (hif_dev->flags & HIF_USB_READY) {
 		ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
-		ath9k_hif_usb_dev_deinit(hif_dev);
-		ath9k_destroy_wmi(hif_dev->htc_handle->drv_priv);
 		ath9k_htc_hw_free(hif_dev->htc_handle);
 	}
 
diff --git a/kernel/drivers/net/wireless/ath/ath9k/htc.h b/kernel/drivers/net/wireless/ath/ath9k/htc.h
index e3d546e..237f4ec 100644
--- a/kernel/drivers/net/wireless/ath/ath9k/htc.h
+++ b/kernel/drivers/net/wireless/ath/ath9k/htc.h
@@ -327,14 +327,18 @@
 }
 
 #ifdef CONFIG_ATH9K_HTC_DEBUGFS
-#define __STAT_SAFE(expr) (hif_dev->htc_handle->drv_priv ? (expr) : 0)
-#define TX_STAT_INC(c) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
-#define TX_STAT_ADD(c, a) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a)
-#define RX_STAT_INC(c) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c++)
-#define RX_STAT_ADD(c, a) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c += a)
-#define CAB_STAT_INC   priv->debug.tx_stats.cab_queued++
+#define __STAT_SAFE(hif_dev, expr)	do { ((hif_dev)->htc_handle->drv_priv ? (expr) : 0); } while (0)
+#define CAB_STAT_INC(priv)		do { ((priv)->debug.tx_stats.cab_queued++); } while (0)
+#define TX_QSTAT_INC(priv, q)		do { ((priv)->debug.tx_stats.queue_stats[q]++); } while (0)
 
-#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
+#define TX_STAT_INC(hif_dev, c) \
+		__STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.tx_stats.c++)
+#define TX_STAT_ADD(hif_dev, c, a) \
+		__STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.tx_stats.c += a)
+#define RX_STAT_INC(hif_dev, c) \
+		__STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.skbrx_stats.c++)
+#define RX_STAT_ADD(hif_dev, c, a) \
+		__STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.skbrx_stats.c += a)
 
 void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
 			   struct ath_rx_status *rs);
@@ -374,13 +378,13 @@
 			    struct ethtool_stats *stats, u64 *data);
 #else
 
-#define TX_STAT_INC(c) do { } while (0)
-#define TX_STAT_ADD(c, a) do { } while (0)
-#define RX_STAT_INC(c) do { } while (0)
-#define RX_STAT_ADD(c, a) do { } while (0)
-#define CAB_STAT_INC   do { } while (0)
+#define TX_STAT_INC(hif_dev, c)		do { } while (0)
+#define TX_STAT_ADD(hif_dev, c, a)	do { } while (0)
+#define RX_STAT_INC(hif_dev, c)		do { } while (0)
+#define RX_STAT_ADD(hif_dev, c, a)	do { } while (0)
 
-#define TX_QSTAT_INC(c) do { } while (0)
+#define CAB_STAT_INC(priv)
+#define TX_QSTAT_INC(priv, c)
 
 static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
 					 struct ath_rx_status *rs)
diff --git a/kernel/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/kernel/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
index b3ed65e..c55aab0 100644
--- a/kernel/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+++ b/kernel/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -491,7 +491,7 @@
 
 	priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME,
 					     priv->hw->wiphy->debugfsdir);
-	if (!priv->debug.debugfs_phy)
+	if (IS_ERR(priv->debug.debugfs_phy))
 		return -ENOMEM;
 
 	ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy);
diff --git a/kernel/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/kernel/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 07ac88f..96a3185 100644
--- a/kernel/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/kernel/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -988,6 +988,8 @@
 
 		ath9k_deinit_device(htc_handle->drv_priv);
 		ath9k_stop_wmi(htc_handle->drv_priv);
+		ath9k_hif_usb_dealloc_urbs((struct hif_device_usb *)htc_handle->hif_dev);
+		ath9k_destroy_wmi(htc_handle->drv_priv);
 		ieee80211_free_hw(htc_handle->drv_priv->hw);
 	}
 }
diff --git a/kernel/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/kernel/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 43a743e..622fc7f 100644
--- a/kernel/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/kernel/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -106,20 +106,20 @@
 
 	switch (qnum) {
 	case 0:
-		TX_QSTAT_INC(IEEE80211_AC_VO);
+		TX_QSTAT_INC(priv, IEEE80211_AC_VO);
 		epid = priv->data_vo_ep;
 		break;
 	case 1:
-		TX_QSTAT_INC(IEEE80211_AC_VI);
+		TX_QSTAT_INC(priv, IEEE80211_AC_VI);
 		epid = priv->data_vi_ep;
 		break;
 	case 2:
-		TX_QSTAT_INC(IEEE80211_AC_BE);
+		TX_QSTAT_INC(priv, IEEE80211_AC_BE);
 		epid = priv->data_be_ep;
 		break;
 	case 3:
 	default:
-		TX_QSTAT_INC(IEEE80211_AC_BK);
+		TX_QSTAT_INC(priv, IEEE80211_AC_BK);
 		epid = priv->data_bk_ep;
 		break;
 	}
@@ -323,7 +323,7 @@
 	memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
 
 	if (is_cab) {
-		CAB_STAT_INC;
+		CAB_STAT_INC(priv);
 		tx_ctl->epid = priv->cab_ep;
 		return;
 	}
diff --git a/kernel/drivers/net/wireless/ath/ath9k/htc_hst.c b/kernel/drivers/net/wireless/ath/ath9k/htc_hst.c
index ca05b07..99667ab 100644
--- a/kernel/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/kernel/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -114,7 +114,13 @@
 
 	if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) {
 		epid = svc_rspmsg->endpoint_id;
-		if (epid < 0 || epid >= ENDPOINT_MAX)
+
+		/* Check that the received epid for the endpoint to attach
+		 * a new service is valid. ENDPOINT0 can't be used here as it
+		 * is already reserved for HTC_CTRL_RSVD_SVC service and thus
+		 * should not be modified.
+		 */
+		if (epid <= ENDPOINT0 || epid >= ENDPOINT_MAX)
 			return;
 
 		service_id = be16_to_cpu(svc_rspmsg->service_id);
@@ -391,7 +397,7 @@
  * HTC Messages are handled directly here and the obtained SKB
  * is freed.
  *
- * Service messages (Data, WMI) passed to the corresponding
+ * Service messages (Data, WMI) are passed to the corresponding
  * endpoint RX handlers, which have to free the SKB.
  */
 void ath9k_htc_rx_msg(struct htc_target *htc_handle,
@@ -478,6 +484,8 @@
 		if (endpoint->ep_callbacks.rx)
 			endpoint->ep_callbacks.rx(endpoint->ep_callbacks.priv,
 						  skb, epid);
+		else
+			goto invalid;
 	}
 }
 
diff --git a/kernel/drivers/net/wireless/ath/ath9k/mac.h b/kernel/drivers/net/wireless/ath/ath9k/mac.h
index fd6aa49..9b00e77 100644
--- a/kernel/drivers/net/wireless/ath/ath9k/mac.h
+++ b/kernel/drivers/net/wireless/ath/ath9k/mac.h
@@ -113,8 +113,10 @@
 	u8 qid;
 	u16 desc_id;
 	u8 tid;
-	u32 ba_low;
-	u32 ba_high;
+	struct_group(ba,
+		u32 ba_low;
+		u32 ba_high;
+	);
 	u32 evm0;
 	u32 evm1;
 	u32 evm2;
diff --git a/kernel/drivers/net/wireless/ath/ath9k/main.c b/kernel/drivers/net/wireless/ath/ath9k/main.c
index ac354df..b2cfc48 100644
--- a/kernel/drivers/net/wireless/ath/ath9k/main.c
+++ b/kernel/drivers/net/wireless/ath/ath9k/main.c
@@ -203,7 +203,7 @@
 void ath_restart_work(struct ath_softc *sc)
 {
 	ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work,
-				     ATH_HW_CHECK_POLL_INT);
+				     msecs_to_jiffies(ATH_HW_CHECK_POLL_INT));
 
 	if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9330(sc->sc_ah))
 		ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work,
@@ -850,7 +850,7 @@
 static bool ath9k_txq_has_key(struct ath_softc *sc, u32 keyix)
 {
 	struct ath_hw *ah = sc->sc_ah;
-	int i;
+	int i, j;
 	struct ath_txq *txq;
 	bool key_in_use = false;
 
@@ -868,8 +868,9 @@
 		if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
 			int idx = txq->txq_tailidx;
 
-			while (!key_in_use &&
-			       !list_empty(&txq->txq_fifo[idx])) {
+			for (j = 0; !key_in_use &&
+			     !list_empty(&txq->txq_fifo[idx]) &&
+			     j < ATH_TXFIFO_DEPTH; j++) {
 				key_in_use = ath9k_txq_list_has_key(
 					&txq->txq_fifo[idx], keyix);
 				INCR(idx, ATH_TXFIFO_DEPTH);
@@ -2243,7 +2244,7 @@
 	}
 
 	ieee80211_queue_delayed_work(hw, &sc->hw_check_work,
-				     ATH_HW_CHECK_POLL_INT);
+				     msecs_to_jiffies(ATH_HW_CHECK_POLL_INT));
 }
 
 static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
diff --git a/kernel/drivers/net/wireless/ath/ath9k/pci.c b/kernel/drivers/net/wireless/ath/ath9k/pci.c
index cff9af3..4f90c30 100644
--- a/kernel/drivers/net/wireless/ath/ath9k/pci.c
+++ b/kernel/drivers/net/wireless/ath/ath9k/pci.c
@@ -994,8 +994,8 @@
 	sc->sc_ah->msi_reg = 0;
 
 	ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name));
-	wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
-		   hw_name, (unsigned long)sc->mem, pdev->irq);
+	wiphy_info(hw->wiphy, "%s mem=0x%p, irq=%d\n",
+		   hw_name, sc->mem, pdev->irq);
 
 	return 0;
 
diff --git a/kernel/drivers/net/wireless/ath/ath9k/wmi.c b/kernel/drivers/net/wireless/ath/ath9k/wmi.c
index f315c54..1476b42 100644
--- a/kernel/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/kernel/drivers/net/wireless/ath/ath9k/wmi.c
@@ -221,6 +221,10 @@
 	if (unlikely(wmi->stopped))
 		goto free_skb;
 
+	/* Validate the obtained SKB. */
+	if (unlikely(skb->len < sizeof(struct wmi_cmd_hdr)))
+		goto free_skb;
+
 	hdr = (struct wmi_cmd_hdr *) skb->data;
 	cmd_id = be16_to_cpu(hdr->command_id);
 
@@ -238,10 +242,10 @@
 		spin_unlock_irqrestore(&wmi->wmi_lock, flags);
 		goto free_skb;
 	}
-	spin_unlock_irqrestore(&wmi->wmi_lock, flags);
 
 	/* WMI command response */
 	ath9k_wmi_rsp_callback(wmi, skb);
+	spin_unlock_irqrestore(&wmi->wmi_lock, flags);
 
 free_skb:
 	kfree_skb(skb);
@@ -279,7 +283,8 @@
 
 static int ath9k_wmi_cmd_issue(struct wmi *wmi,
 			       struct sk_buff *skb,
-			       enum wmi_cmd_id cmd, u16 len)
+			       enum wmi_cmd_id cmd, u16 len,
+			       u8 *rsp_buf, u32 rsp_len)
 {
 	struct wmi_cmd_hdr *hdr;
 	unsigned long flags;
@@ -289,6 +294,11 @@
 	hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id);
 
 	spin_lock_irqsave(&wmi->wmi_lock, flags);
+
+	/* record the rsp buffer and length */
+	wmi->cmd_rsp_buf = rsp_buf;
+	wmi->cmd_rsp_len = rsp_len;
+
 	wmi->last_seq_id = wmi->tx_seq_id;
 	spin_unlock_irqrestore(&wmi->wmi_lock, flags);
 
@@ -304,8 +314,8 @@
 	struct ath_common *common = ath9k_hw_common(ah);
 	u16 headroom = sizeof(struct htc_frame_hdr) +
 		       sizeof(struct wmi_cmd_hdr);
+	unsigned long time_left, flags;
 	struct sk_buff *skb;
-	unsigned long time_left;
 	int ret = 0;
 
 	if (ah->ah_flags & AH_UNPLUGGED)
@@ -329,11 +339,7 @@
 		goto out;
 	}
 
-	/* record the rsp buffer and length */
-	wmi->cmd_rsp_buf = rsp_buf;
-	wmi->cmd_rsp_len = rsp_len;
-
-	ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len);
+	ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len, rsp_buf, rsp_len);
 	if (ret)
 		goto out;
 
@@ -341,6 +347,9 @@
 	if (!time_left) {
 		ath_dbg(common, WMI, "Timeout waiting for WMI command: %s\n",
 			wmi_cmd_to_name(cmd_id));
+		spin_lock_irqsave(&wmi->wmi_lock, flags);
+		wmi->last_seq_id = 0;
+		spin_unlock_irqrestore(&wmi->wmi_lock, flags);
 		mutex_unlock(&wmi->op_mutex);
 		return -ETIMEDOUT;
 	}
diff --git a/kernel/drivers/net/wireless/ath/ath9k/xmit.c b/kernel/drivers/net/wireless/ath/ath9k/xmit.c
index 6555abf..84c68ae 100644
--- a/kernel/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/kernel/drivers/net/wireless/ath/ath9k/xmit.c
@@ -421,7 +421,7 @@
 	isaggr = bf_isaggr(bf);
 	if (isaggr) {
 		seq_st = ts->ts_seqnum;
-		memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
+		memcpy(ba, &ts->ba, WME_BA_BMP_SIZE >> 3);
 	}
 
 	while (bf) {
@@ -504,7 +504,7 @@
 	if (isaggr && txok) {
 		if (ts->ts_flags & ATH9K_TX_BA) {
 			seq_st = ts->ts_seqnum;
-			memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
+			memcpy(ba, &ts->ba, WME_BA_BMP_SIZE >> 3);
 		} else {
 			/*
 			 * AR5416 can become deaf/mute when BA
diff --git a/kernel/drivers/net/wireless/ath/key.c b/kernel/drivers/net/wireless/ath/key.c
index 61b59a8..b7b61d4 100644
--- a/kernel/drivers/net/wireless/ath/key.c
+++ b/kernel/drivers/net/wireless/ath/key.c
@@ -503,7 +503,7 @@
 
 	hk.kv_len = key->keylen;
 	if (key->keylen)
-		memcpy(hk.kv_val, key->key, key->keylen);
+		memcpy(&hk.kv_values, key->key, key->keylen);
 
 	if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
 		switch (vif->type) {
diff --git a/kernel/drivers/net/wireless/ath/wil6210/txrx.c b/kernel/drivers/net/wireless/ath/wil6210/txrx.c
index cc830c7..5b2de4f 100644
--- a/kernel/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/kernel/drivers/net/wireless/ath/wil6210/txrx.c
@@ -666,7 +666,7 @@
 	struct wil_tid_crypto_rx *c = mc ? &s->group_crypto_rx :
 				      &s->tid_crypto_rx[tid];
 	struct wil_tid_crypto_rx_single *cc = &c->key_id[key_id];
-	const u8 *pn = (u8 *)&d->mac.pn_15_0;
+	const u8 *pn = (u8 *)&d->mac.pn;
 
 	if (!cc->key_set) {
 		wil_err_ratelimited(wil,
diff --git a/kernel/drivers/net/wireless/ath/wil6210/txrx.h b/kernel/drivers/net/wireless/ath/wil6210/txrx.h
index 1f4c8ec..0f6f6b6 100644
--- a/kernel/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/kernel/drivers/net/wireless/ath/wil6210/txrx.h
@@ -343,8 +343,10 @@
 	u32 d0;
 	u32 d1;
 	u16 w4;
-	u16 pn_15_0;
-	u32 pn_47_16;
+	struct_group_attr(pn, __packed,
+		u16 pn_15_0;
+		u32 pn_47_16;
+	);
 } __packed;
 
 /* Rx descriptor - DMA part
diff --git a/kernel/drivers/net/wireless/ath/wil6210/txrx_edma.c b/kernel/drivers/net/wireless/ath/wil6210/txrx_edma.c
index 8ca2ce5..b23c05f 100644
--- a/kernel/drivers/net/wireless/ath/wil6210/txrx_edma.c
+++ b/kernel/drivers/net/wireless/ath/wil6210/txrx_edma.c
@@ -548,7 +548,7 @@
 	s = &wil->sta[cid];
 	c = mc ? &s->group_crypto_rx : &s->tid_crypto_rx[tid];
 	cc = &c->key_id[key_id];
-	pn = (u8 *)&st->ext.pn_15_0;
+	pn = (u8 *)&st->ext.pn;
 
 	if (!cc->key_set) {
 		wil_err_ratelimited(wil,
diff --git a/kernel/drivers/net/wireless/ath/wil6210/txrx_edma.h b/kernel/drivers/net/wireless/ath/wil6210/txrx_edma.h
index c736f74..ee90e22 100644
--- a/kernel/drivers/net/wireless/ath/wil6210/txrx_edma.h
+++ b/kernel/drivers/net/wireless/ath/wil6210/txrx_edma.h
@@ -330,8 +330,10 @@
 	u32 d0;
 	u32 d1;
 	__le16 seq_num; /* only lower 12 bits */
-	u16 pn_15_0;
-	u32 pn_47_16;
+	struct_group_attr(pn, __packed,
+		u16 pn_15_0;
+		u32 pn_47_16;
+	);
 } __packed;
 
 struct wil_rx_status_extended {
diff --git a/kernel/drivers/net/wireless/atmel/atmel_cs.c b/kernel/drivers/net/wireless/atmel/atmel_cs.c
index 368eebe..e64f108 100644
--- a/kernel/drivers/net/wireless/atmel/atmel_cs.c
+++ b/kernel/drivers/net/wireless/atmel/atmel_cs.c
@@ -73,6 +73,7 @@
 static int atmel_probe(struct pcmcia_device *p_dev)
 {
 	struct local_info *local;
+	int ret;
 
 	dev_dbg(&p_dev->dev, "atmel_attach()\n");
 
@@ -83,8 +84,16 @@
 
 	p_dev->priv = local;
 
-	return atmel_config(p_dev);
-} /* atmel_attach */
+	ret = atmel_config(p_dev);
+	if (ret)
+		goto err_free_priv;
+
+	return 0;
+
+err_free_priv:
+	kfree(p_dev->priv);
+	return ret;
+}
 
 static void atmel_detach(struct pcmcia_device *link)
 {
diff --git a/kernel/drivers/net/wireless/broadcom/b43/b43.h b/kernel/drivers/net/wireless/broadcom/b43/b43.h
index 9fc7c08..67b4bac 100644
--- a/kernel/drivers/net/wireless/broadcom/b43/b43.h
+++ b/kernel/drivers/net/wireless/broadcom/b43/b43.h
@@ -651,7 +651,7 @@
 	union {
 		__be16 d16;
 		__be32 d32;
-	} data __packed;
+	} __packed data;
 } __packed;
 
 
diff --git a/kernel/drivers/net/wireless/broadcom/b43legacy/b43legacy.h b/kernel/drivers/net/wireless/broadcom/b43legacy/b43legacy.h
index 6b0cec4..f49365d 100644
--- a/kernel/drivers/net/wireless/broadcom/b43legacy/b43legacy.h
+++ b/kernel/drivers/net/wireless/broadcom/b43legacy/b43legacy.h
@@ -379,7 +379,7 @@
 	union {
 		__be16 d16;
 		__be32 d32;
-	} data __packed;
+	} __packed data;
 } __packed;
 
 #define B43legacy_PHYMODE(phytype)	(1 << (phytype))
diff --git a/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index c2b6e5c..baf5f0a 100644
--- a/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -90,6 +90,9 @@
 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
 	(sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
 
+#define BRCMF_MAX_CHANSPEC_LIST \
+	(BRCMF_DCMD_MEDLEN / sizeof(__le32) - 1)
+
 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
 {
 	if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
@@ -1347,13 +1350,14 @@
 {
 	struct brcmf_pub *drvr = ifp->drvr;
 	struct brcmf_wsec_pmk_le pmk;
-	int i, err;
+	int err;
 
-	/* convert to firmware key format */
-	pmk.key_len = cpu_to_le16(pmk_len << 1);
-	pmk.flags = cpu_to_le16(BRCMF_WSEC_PASSPHRASE);
-	for (i = 0; i < pmk_len; i++)
-		snprintf(&pmk.key[2 * i], 3, "%02x", pmk_data[i]);
+	memset(&pmk, 0, sizeof(pmk));
+
+	/* pass pmk directly */
+	pmk.key_len = cpu_to_le16(pmk_len);
+	pmk.flags = cpu_to_le16(0);
+	memcpy(pmk.key, pmk_data, pmk_len);
 
 	/* store psk in firmware */
 	err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK,
@@ -5831,6 +5835,11 @@
 		(struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
 	req_len = le32_to_cpu(assoc_info->req_len);
 	resp_len = le32_to_cpu(assoc_info->resp_len);
+	if (req_len > WL_EXTRA_BUF_MAX || resp_len > WL_EXTRA_BUF_MAX) {
+		bphy_err(drvr, "invalid lengths in assoc info: req %u resp %u\n",
+			 req_len, resp_len);
+		return -EINVAL;
+	}
 	if (req_len) {
 		err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
 					       cfg->extra_buf,
@@ -6459,6 +6468,13 @@
 			band->channels[i].flags = IEEE80211_CHAN_DISABLED;
 
 	total = le32_to_cpu(list->count);
+	if (total > BRCMF_MAX_CHANSPEC_LIST) {
+		bphy_err(drvr, "Invalid count of channel Spec. (%u)\n",
+			 total);
+		err = -EINVAL;
+		goto fail_pbuf;
+	}
+
 	for (i = 0; i < total; i++) {
 		ch.chspec = (u16)le32_to_cpu(list->element[i]);
 		cfg->d11inf.decchspec(&ch);
@@ -6604,6 +6620,13 @@
 		band = cfg_to_wiphy(cfg)->bands[NL80211_BAND_2GHZ];
 		list = (struct brcmf_chanspec_list *)pbuf;
 		num_chan = le32_to_cpu(list->count);
+		if (num_chan > BRCMF_MAX_CHANSPEC_LIST) {
+			bphy_err(drvr, "Invalid count of channel Spec. (%u)\n",
+				 num_chan);
+			kfree(pbuf);
+			return -EINVAL;
+		}
+
 		for (i = 0; i < num_chan; i++) {
 			ch.chspec = (u16)le32_to_cpu(list->element[i]);
 			cfg->d11inf.decchspec(&ch);
diff --git a/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index e3758bd..f29de63 100644
--- a/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -264,6 +264,7 @@
 			 err);
 		goto done;
 	}
+	buf[sizeof(buf) - 1] = '\0';
 	ptr = (char *)buf;
 	strsep(&ptr, "\n");
 
@@ -280,15 +281,17 @@
 	if (err) {
 		brcmf_dbg(TRACE, "retrieving clmver failed, %d\n", err);
 	} else {
+		buf[sizeof(buf) - 1] = '\0';
 		clmver = (char *)buf;
-		/* store CLM version for adding it to revinfo debugfs file */
-		memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver));
 
 		/* Replace all newline/linefeed characters with space
 		 * character
 		 */
 		strreplace(clmver, '\n', ' ');
 
+		/* store CLM version for adding it to revinfo debugfs file */
+		memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver));
+
 		brcmf_dbg(INFO, "CLM version = %s\n", clmver);
 	}
 
diff --git a/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index c8e1d50..3d544ee 100644
--- a/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -333,6 +333,7 @@
 			bphy_err(drvr, "%s: failed to expand headroom\n",
 				 brcmf_ifname(ifp));
 			atomic_inc(&drvr->bus_if->stats.pktcow_failed);
+			dev_kfree_skb(skb);
 			goto done;
 		}
 	}
diff --git a/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
index a2b8d91..060889b 100644
--- a/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -703,6 +703,11 @@
 	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))
diff --git a/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index 7c8e08e..bd3b234 100644
--- a/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -346,8 +346,11 @@
 		count++;
 	} while (count < pktids->array_size);
 
-	if (count == pktids->array_size)
+	if (count == pktids->array_size) {
+		dma_unmap_single(dev, *physaddr, skb->len - data_offset,
+				 pktids->direction);
 		return -ENOMEM;
+	}
 
 	array[*idx].data_offset = data_offset;
 	array[*idx].physaddr = *physaddr;
diff --git a/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 61febc9..721d587 100644
--- a/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -618,7 +618,7 @@
 	}
 
 	if (!brcmf_chip_set_active(devinfo->ci, resetintr))
-		return -EINVAL;
+		return -EIO;
 	return 0;
 }
 
@@ -1109,6 +1109,10 @@
 				BRCMF_NROF_H2D_COMMON_MSGRINGS;
 		max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS;
 	}
+	if (max_flowrings > 512) {
+		brcmf_err(bus, "invalid max_flowrings(%d)\n", max_flowrings);
+		return -EIO;
+	}
 
 	if (devinfo->dma_idx_sz != 0) {
 		bufsz = (max_submissionrings + max_completionrings) *
diff --git a/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 9929e90..3c0d5c6 100644
--- a/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3401,6 +3401,7 @@
 	/* 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;
 	}
 
diff --git a/kernel/drivers/net/wireless/cisco/airo.c b/kernel/drivers/net/wireless/cisco/airo.c
index 8c9c6bf..aa1d12f 100644
--- a/kernel/drivers/net/wireless/cisco/airo.c
+++ b/kernel/drivers/net/wireless/cisco/airo.c
@@ -6150,8 +6150,11 @@
 {
 	struct airo_info *local = dev->ml_priv;
 	StatusRid status_rid;		/* Card status info */
+	int ret;
 
-	readStatusRid(local, &status_rid, 1);
+	ret = readStatusRid(local, &status_rid, 1);
+	if (ret)
+		return -EBUSY;
 
 	vwrq->value = le16_to_cpu(status_rid.currentXmitRate) * 500000;
 	/* If more than one rate, set auto */
diff --git a/kernel/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/kernel/drivers/net/wireless/intel/ipw2x00/ipw2200.c
index ada6ce3..bb728fb 100644
--- a/kernel/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+++ b/kernel/drivers/net/wireless/intel/ipw2x00/ipw2200.c
@@ -3444,7 +3444,7 @@
 			dma_unmap_single(&priv->pci_dev->dev,
 					 rxq->pool[i].dma_addr,
 					 IPW_RX_BUF_SIZE, DMA_FROM_DEVICE);
-			dev_kfree_skb(rxq->pool[i].skb);
+			dev_kfree_skb_irq(rxq->pool[i].skb);
 			rxq->pool[i].skb = NULL;
 		}
 		list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
@@ -11400,9 +11400,14 @@
 	set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
 
 	/* With that information in place, we can now register the wiphy... */
-	if (wiphy_register(wdev->wiphy))
-		rc = -EIO;
+	rc = wiphy_register(wdev->wiphy);
+	if (rc)
+		goto out;
+
+	return 0;
 out:
+	kfree(priv->ieee->a_band.channels);
+	kfree(priv->ieee->bg_band.channels);
 	return rc;
 }
 
diff --git a/kernel/drivers/net/wireless/intel/iwlegacy/3945-mac.c b/kernel/drivers/net/wireless/intel/iwlegacy/3945-mac.c
index 4ca8212..ef0ac42 100644
--- a/kernel/drivers/net/wireless/intel/iwlegacy/3945-mac.c
+++ b/kernel/drivers/net/wireless/intel/iwlegacy/3945-mac.c
@@ -3380,10 +3380,12 @@
  *
  *****************************************************************************/
 
-static void
+static int
 il3945_setup_deferred_work(struct il_priv *il)
 {
 	il->workqueue = create_singlethread_workqueue(DRV_NAME);
+	if (!il->workqueue)
+		return -ENOMEM;
 
 	init_waitqueue_head(&il->wait_command_queue);
 
@@ -3400,6 +3402,8 @@
 	timer_setup(&il->watchdog, il_bg_watchdog, 0);
 
 	tasklet_setup(&il->irq_tasklet, il3945_irq_tasklet);
+
+	return 0;
 }
 
 static void
@@ -3721,7 +3725,10 @@
 	}
 
 	il_set_rxon_channel(il, &il->bands[NL80211_BAND_2GHZ].channels[5]);
-	il3945_setup_deferred_work(il);
+	err = il3945_setup_deferred_work(il);
+	if (err)
+		goto out_remove_sysfs;
+
 	il3945_setup_handlers(il);
 	il_power_initialize(il);
 
@@ -3733,7 +3740,7 @@
 
 	err = il3945_setup_mac(il);
 	if (err)
-		goto out_remove_sysfs;
+		goto out_destroy_workqueue;
 
 	il_dbgfs_register(il, DRV_NAME);
 
@@ -3742,9 +3749,10 @@
 
 	return 0;
 
-out_remove_sysfs:
+out_destroy_workqueue:
 	destroy_workqueue(il->workqueue);
 	il->workqueue = NULL;
+out_remove_sysfs:
 	sysfs_remove_group(&pdev->dev.kobj, &il3945_attribute_group);
 out_release_irq:
 	free_irq(il->pci_dev->irq, il);
diff --git a/kernel/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/kernel/drivers/net/wireless/intel/iwlegacy/4965-mac.c
index 28675a4..12cf22d 100644
--- a/kernel/drivers/net/wireless/intel/iwlegacy/4965-mac.c
+++ b/kernel/drivers/net/wireless/intel/iwlegacy/4965-mac.c
@@ -6212,10 +6212,12 @@
 	mutex_unlock(&il->mutex);
 }
 
-static void
+static int
 il4965_setup_deferred_work(struct il_priv *il)
 {
 	il->workqueue = create_singlethread_workqueue(DRV_NAME);
+	if (!il->workqueue)
+		return -ENOMEM;
 
 	init_waitqueue_head(&il->wait_command_queue);
 
@@ -6234,6 +6236,8 @@
 	timer_setup(&il->watchdog, il_bg_watchdog, 0);
 
 	tasklet_setup(&il->irq_tasklet, il4965_irq_tasklet);
+
+	return 0;
 }
 
 static void
@@ -6623,7 +6627,10 @@
 		goto out_disable_msi;
 	}
 
-	il4965_setup_deferred_work(il);
+	err = il4965_setup_deferred_work(il);
+	if (err)
+		goto out_free_irq;
+
 	il4965_setup_handlers(il);
 
 	/*********************************************
@@ -6661,6 +6668,7 @@
 out_destroy_workqueue:
 	destroy_workqueue(il->workqueue);
 	il->workqueue = NULL;
+out_free_irq:
 	free_irq(il->pci_dev->irq, il);
 out_disable_msi:
 	pci_disable_msi(il->pci_dev);
diff --git a/kernel/drivers/net/wireless/intel/iwlegacy/common.c b/kernel/drivers/net/wireless/intel/iwlegacy/common.c
index 0651a6a..4b55779 100644
--- a/kernel/drivers/net/wireless/intel/iwlegacy/common.c
+++ b/kernel/drivers/net/wireless/intel/iwlegacy/common.c
@@ -5176,7 +5176,7 @@
 	memset(&il->current_ht_config, 0, sizeof(struct il_ht_config));
 
 	/* new association get rid of ibss beacon skb */
-	dev_kfree_skb(il->beacon_skb);
+	dev_consume_skb_irq(il->beacon_skb);
 	il->beacon_skb = NULL;
 	il->timestamp = 0;
 
@@ -5295,7 +5295,7 @@
 	}
 
 	spin_lock_irqsave(&il->lock, flags);
-	dev_kfree_skb(il->beacon_skb);
+	dev_consume_skb_irq(il->beacon_skb);
 	il->beacon_skb = skb;
 
 	timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
diff --git a/kernel/drivers/net/wireless/intel/iwlwifi/dvm/sta.c b/kernel/drivers/net/wireless/intel/iwlwifi/dvm/sta.c
index e622948..b307f0e 100644
--- a/kernel/drivers/net/wireless/intel/iwlwifi/dvm/sta.c
+++ b/kernel/drivers/net/wireless/intel/iwlwifi/dvm/sta.c
@@ -1086,6 +1086,7 @@
 {
 	__le16 key_flags;
 	struct iwl_addsta_cmd sta_cmd;
+	size_t to_copy;
 	int i;
 
 	spin_lock_bh(&priv->sta_lock);
@@ -1105,7 +1106,9 @@
 		sta_cmd.key.tkip_rx_tsc_byte2 = tkip_iv32;
 		for (i = 0; i < 5; i++)
 			sta_cmd.key.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]);
-		memcpy(sta_cmd.key.key, keyconf->key, keyconf->keylen);
+		/* keyconf may contain MIC rx/tx keys which iwl does not use */
+		to_copy = min_t(size_t, sizeof(sta_cmd.key.key), keyconf->keylen);
+		memcpy(sta_cmd.key.key, keyconf->key, to_copy);
 		break;
 	case WLAN_CIPHER_SUITE_WEP104:
 		key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
diff --git a/kernel/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/kernel/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 419eaa5..79d08e5 100644
--- a/kernel/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/kernel/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -1372,12 +1372,12 @@
 	if (!data)
 		return;
 
+	memset(data, 0, sizeof(*data));
+
 	/* make sure only one bit is set in only one fid */
 	if (WARN_ONCE(hweight_long(fid1) + hweight_long(fid2) != 1,
 		      "fid1=%x, fid2=%x\n", fid1, fid2))
 		return;
-
-	memset(data, 0, sizeof(*data));
 
 	if (fid1) {
 		fifo_idx = ffs(fid1) - 1;
diff --git a/kernel/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/kernel/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
index 267ad4e..24d6ed3 100644
--- a/kernel/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
+++ b/kernel/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
@@ -344,8 +344,10 @@
 	const struct iwl_fw *fw = priv->fwrt->fw;
 
 	*pos = ++state->pos;
-	if (*pos >= fw->ucode_capa.n_cmd_versions)
+	if (*pos >= fw->ucode_capa.n_cmd_versions) {
+		kfree(state);
 		return NULL;
+	}
 
 	return state;
 }
diff --git a/kernel/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/kernel/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
index cb40f50..d08750a 100644
--- a/kernel/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
+++ b/kernel/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
@@ -334,9 +334,9 @@
 struct iwl_fw_ini_error_dump_range {
 	__le32 range_data_size;
 	union {
-		__le32 internal_base_addr;
-		__le64 dram_base_addr;
-		__le32 page_num;
+		__le32 internal_base_addr __packed;
+		__le64 dram_base_addr __packed;
+		__le32 page_num __packed;
 		struct iwl_fw_ini_fifo_hdr fifo_hdr;
 		struct iwl_cmd_header fw_pkt_hdr;
 	};
diff --git a/kernel/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/kernel/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
index 3c931b1..fdf2c6e 100644
--- a/kernel/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+++ b/kernel/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -191,6 +191,12 @@
 	    alloc_id != IWL_FW_INI_ALLOCATION_ID_INTERNAL)
 		goto err;
 
+	if (buf_location == IWL_FW_INI_LOCATION_DRAM_PATH &&
+	    alloc->req_size == 0) {
+		IWL_ERR(trans, "WRT: Invalid DRAM buffer allocation requested size (0)\n");
+		return -EINVAL;
+	}
+
 	trans->dbg.fw_mon_cfg[alloc_id] = *alloc;
 
 	return 0;
diff --git a/kernel/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/kernel/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
index 3395c46..36f75d5 100644
--- a/kernel/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+++ b/kernel/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
@@ -1885,6 +1885,11 @@
 	if (ret < 0)
 		return ret;
 
+	if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) {
+		ret = -EIO;
+		goto out;
+	}
+
 	rsp = (void *)hcmd.resp_pkt->data;
 	if (le32_to_cpu(rsp->status) != DEBUG_MEM_STATUS_SUCCESS) {
 		ret = -ENXIO;
@@ -1962,6 +1967,11 @@
 	if (ret < 0)
 		return ret;
 
+	if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) {
+		ret = -EIO;
+		goto out;
+	}
+
 	rsp = (void *)hcmd.resp_pkt->data;
 	if (rsp->status != DEBUG_MEM_STATUS_SUCCESS) {
 		ret = -ENXIO;
diff --git a/kernel/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/kernel/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
index 60296a7..34be3f7 100644
--- a/kernel/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+++ b/kernel/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
@@ -502,6 +502,11 @@
 		struct iwl_mcc_update_resp *mcc_resp = (void *)pkt->data;
 
 		n_channels =  __le32_to_cpu(mcc_resp->n_channels);
+		if (iwl_rx_packet_payload_len(pkt) !=
+		    struct_size(mcc_resp, channels, n_channels)) {
+			resp_cp = ERR_PTR(-EINVAL);
+			goto exit;
+		}
 		resp_len = sizeof(struct iwl_mcc_update_resp) +
 			   n_channels * sizeof(__le32);
 		resp_cp = kmemdup(mcc_resp, resp_len, GFP_KERNEL);
@@ -513,6 +518,11 @@
 		struct iwl_mcc_update_resp_v3 *mcc_resp_v3 = (void *)pkt->data;
 
 		n_channels =  __le32_to_cpu(mcc_resp_v3->n_channels);
+		if (iwl_rx_packet_payload_len(pkt) !=
+		    struct_size(mcc_resp_v3, channels, n_channels)) {
+			resp_cp = ERR_PTR(-EINVAL);
+			goto exit;
+		}
 		resp_len = sizeof(struct iwl_mcc_update_resp) +
 			   n_channels * sizeof(__le32);
 		resp_cp = kzalloc(resp_len, GFP_KERNEL);
diff --git a/kernel/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/kernel/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 7c61d17..5b173f2 100644
--- a/kernel/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/kernel/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -1174,8 +1174,11 @@
 		mvmtxq = iwl_mvm_txq_from_mac80211(txq);
 		mvmtxq->stopped = !start;
 
-		if (start && mvmsta->sta_state != IEEE80211_STA_NOTEXIST)
+		if (start && mvmsta->sta_state != IEEE80211_STA_NOTEXIST) {
+			local_bh_disable();
 			iwl_mvm_mac_itxq_xmit(mvm->hw, txq);
+			local_bh_enable();
+		}
 	}
 
 out:
diff --git a/kernel/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/kernel/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 09f870c..141581f 100644
--- a/kernel/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/kernel/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -2590,7 +2590,7 @@
 	}
 
 	if (iwl_mvm_has_new_rx_api(mvm) && start) {
-		u16 reorder_buf_size = buf_size * sizeof(baid_data->entries[0]);
+		u32 reorder_buf_size = buf_size * sizeof(baid_data->entries[0]);
 
 		/* sparse doesn't like the __align() so don't check */
 #ifndef __CHECKER__
diff --git a/kernel/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/kernel/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 7186e1d..d310337 100644
--- a/kernel/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/kernel/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -1203,6 +1203,7 @@
 	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 @@
 
 		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;
 		}
 	}
 
diff --git a/kernel/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/kernel/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 4e43efd..dc0a507 100644
--- a/kernel/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/kernel/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -1214,6 +1214,9 @@
 {
 	struct iwl_trans *trans = pci_get_drvdata(pdev);
 
+	if (!trans)
+		return;
+
 	iwl_drv_stop(trans->drv);
 
 	iwl_trans_pcie_free(trans);
diff --git a/kernel/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/kernel/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index daec61a..fac7cc7 100644
--- a/kernel/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/kernel/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -620,7 +620,6 @@
 int iwl_pcie_prepare_card_hw(struct iwl_trans *trans)
 {
 	int ret;
-	int t = 0;
 	int iter;
 
 	IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n");
@@ -635,6 +634,8 @@
 	usleep_range(1000, 2000);
 
 	for (iter = 0; iter < 10; iter++) {
+		int t = 0;
+
 		/* If HW is not ready, prepare the conditions to check again */
 		iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
 			    CSR_HW_IF_CONFIG_REG_PREPARE);
@@ -2834,7 +2835,7 @@
 				  void *buf, ssize_t *size,
 				  ssize_t *bytes_copied)
 {
-	int buf_size_left = count - *bytes_copied;
+	ssize_t buf_size_left = count - *bytes_copied;
 
 	buf_size_left = buf_size_left - (buf_size_left % sizeof(u32));
 	if (*size > buf_size_left)
diff --git a/kernel/drivers/net/wireless/intersil/orinoco/hw.c b/kernel/drivers/net/wireless/intersil/orinoco/hw.c
index 61af5a2..af49aa4 100644
--- a/kernel/drivers/net/wireless/intersil/orinoco/hw.c
+++ b/kernel/drivers/net/wireless/intersil/orinoco/hw.c
@@ -931,6 +931,8 @@
 			err = hermes_write_wordrec(hw, USER_BAP,
 					HERMES_RID_CNFAUTHENTICATION_AGERE,
 					auth_flag);
+			if (err)
+				return err;
 		}
 		err = hermes_write_wordrec(hw, USER_BAP,
 					   HERMES_RID_CNFWEPENABLED_AGERE,
diff --git a/kernel/drivers/net/wireless/intersil/orinoco/orinoco_cs.c b/kernel/drivers/net/wireless/intersil/orinoco/orinoco_cs.c
index a956f96..03bfd24 100644
--- a/kernel/drivers/net/wireless/intersil/orinoco/orinoco_cs.c
+++ b/kernel/drivers/net/wireless/intersil/orinoco/orinoco_cs.c
@@ -96,6 +96,7 @@
 {
 	struct orinoco_private *priv;
 	struct orinoco_pccard *card;
+	int ret;
 
 	priv = alloc_orinocodev(sizeof(*card), &link->dev,
 				orinoco_cs_hard_reset, NULL);
@@ -107,8 +108,16 @@
 	card->p_dev = link;
 	link->priv = priv;
 
-	return orinoco_cs_config(link);
-}				/* orinoco_cs_attach */
+	ret = orinoco_cs_config(link);
+	if (ret)
+		goto err_free_orinocodev;
+
+	return 0;
+
+err_free_orinocodev:
+	free_orinocodev(priv);
+	return ret;
+}
 
 static void orinoco_cs_detach(struct pcmcia_device *link)
 {
diff --git a/kernel/drivers/net/wireless/intersil/orinoco/spectrum_cs.c b/kernel/drivers/net/wireless/intersil/orinoco/spectrum_cs.c
index 291ef97..841d623 100644
--- a/kernel/drivers/net/wireless/intersil/orinoco/spectrum_cs.c
+++ b/kernel/drivers/net/wireless/intersil/orinoco/spectrum_cs.c
@@ -157,6 +157,7 @@
 {
 	struct orinoco_private *priv;
 	struct orinoco_pccard *card;
+	int ret;
 
 	priv = alloc_orinocodev(sizeof(*card), &link->dev,
 				spectrum_cs_hard_reset,
@@ -169,8 +170,16 @@
 	card->p_dev = link;
 	link->priv = priv;
 
-	return spectrum_cs_config(link);
-}				/* spectrum_cs_attach */
+	ret = spectrum_cs_config(link);
+	if (ret)
+		goto err_free_orinocodev;
+
+	return 0;
+
+err_free_orinocodev:
+	free_orinocodev(priv);
+	return ret;
+}
 
 static void spectrum_cs_detach(struct pcmcia_device *link)
 {
diff --git a/kernel/drivers/net/wireless/mac80211_hwsim.c b/kernel/drivers/net/wireless/mac80211_hwsim.c
index 3da8ff7..552253d 100644
--- a/kernel/drivers/net/wireless/mac80211_hwsim.c
+++ b/kernel/drivers/net/wireless/mac80211_hwsim.c
@@ -3625,12 +3625,13 @@
 	frame_data_len = nla_len(info->attrs[HWSIM_ATTR_FRAME]);
 	frame_data = (void *)nla_data(info->attrs[HWSIM_ATTR_FRAME]);
 
+	if (frame_data_len < sizeof(struct ieee80211_hdr_3addr) ||
+	    frame_data_len > IEEE80211_MAX_DATA_LEN)
+		goto err;
+
 	/* Allocate new skb here */
 	skb = alloc_skb(frame_data_len, GFP_KERNEL);
 	if (skb == NULL)
-		goto err;
-
-	if (frame_data_len > IEEE80211_MAX_DATA_LEN)
 		goto err;
 
 	/* Copy the data */
diff --git a/kernel/drivers/net/wireless/marvell/libertas/cmdresp.c b/kernel/drivers/net/wireless/marvell/libertas/cmdresp.c
index cb515c5..74cb755 100644
--- a/kernel/drivers/net/wireless/marvell/libertas/cmdresp.c
+++ b/kernel/drivers/net/wireless/marvell/libertas/cmdresp.c
@@ -48,7 +48,7 @@
 
 	/* Free Tx and Rx packets */
 	spin_lock_irqsave(&priv->driver_lock, flags);
-	kfree_skb(priv->currenttxskb);
+	dev_kfree_skb_irq(priv->currenttxskb);
 	priv->currenttxskb = NULL;
 	priv->tx_pending_len = 0;
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
diff --git a/kernel/drivers/net/wireless/marvell/libertas/if_usb.c b/kernel/drivers/net/wireless/marvell/libertas/if_usb.c
index 32fdc41..2240b4d 100644
--- a/kernel/drivers/net/wireless/marvell/libertas/if_usb.c
+++ b/kernel/drivers/net/wireless/marvell/libertas/if_usb.c
@@ -637,7 +637,7 @@
 	priv->resp_len[i] = (recvlength - MESSAGE_HEADER_LEN);
 	memcpy(priv->resp_buf[i], recvbuff + MESSAGE_HEADER_LEN,
 		priv->resp_len[i]);
-	kfree_skb(skb);
+	dev_kfree_skb_irq(skb);
 	lbs_notify_command_response(priv, i);
 
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
diff --git a/kernel/drivers/net/wireless/marvell/libertas/main.c b/kernel/drivers/net/wireless/marvell/libertas/main.c
index ee4cf34..1c56cc2 100644
--- a/kernel/drivers/net/wireless/marvell/libertas/main.c
+++ b/kernel/drivers/net/wireless/marvell/libertas/main.c
@@ -217,7 +217,7 @@
 
 	spin_lock_irqsave(&priv->driver_lock, flags);
 	priv->iface_running = false;
-	kfree_skb(priv->currenttxskb);
+	dev_kfree_skb_irq(priv->currenttxskb);
 	priv->currenttxskb = NULL;
 	priv->tx_pending_len = 0;
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
@@ -870,6 +870,7 @@
 	ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
 	if (ret) {
 		pr_err("Out of memory allocating event FIFO buffer\n");
+		lbs_free_cmd_buffer(priv);
 		goto out;
 	}
 
diff --git a/kernel/drivers/net/wireless/marvell/libertas_tf/if_usb.c b/kernel/drivers/net/wireless/marvell/libertas_tf/if_usb.c
index ecce8b5..2c45ef6 100644
--- a/kernel/drivers/net/wireless/marvell/libertas_tf/if_usb.c
+++ b/kernel/drivers/net/wireless/marvell/libertas_tf/if_usb.c
@@ -613,7 +613,7 @@
 	spin_lock_irqsave(&priv->driver_lock, flags);
 	memcpy(priv->cmd_resp_buff, recvbuff + MESSAGE_HEADER_LEN,
 	       recvlength - MESSAGE_HEADER_LEN);
-	kfree_skb(skb);
+	dev_kfree_skb_irq(skb);
 	lbtf_cmd_response_rx(priv);
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 }
diff --git a/kernel/drivers/net/wireless/marvell/mwifiex/11n.c b/kernel/drivers/net/wireless/marvell/mwifiex/11n.c
index cf08a4a..b99381e 100644
--- a/kernel/drivers/net/wireless/marvell/mwifiex/11n.c
+++ b/kernel/drivers/net/wireless/marvell/mwifiex/11n.c
@@ -890,7 +890,7 @@
  */
 void mwifiex_update_ampdu_txwinsize(struct mwifiex_adapter *adapter)
 {
-	u8 i;
+	u8 i, j;
 	u32 tx_win_size;
 	struct mwifiex_private *priv;
 
@@ -921,8 +921,8 @@
 		if (tx_win_size != priv->add_ba_param.tx_win_size) {
 			if (!priv->media_connected)
 				continue;
-			for (i = 0; i < MAX_NUM_TID; i++)
-				mwifiex_send_delba_txbastream_tbl(priv, i);
+			for (j = 0; j < MAX_NUM_TID; j++)
+				mwifiex_send_delba_txbastream_tbl(priv, j);
 		}
 	}
 }
diff --git a/kernel/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/kernel/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
index 1046b59..cbe4a20 100644
--- a/kernel/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
+++ b/kernel/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
@@ -977,8 +977,8 @@
 			}
 		}
 
-		tlv_buf_left -= (sizeof(*tlv_rxba) + tlv_len);
-		tmp = (u8 *)tlv_rxba + tlv_len + sizeof(*tlv_rxba);
+		tlv_buf_left -= (sizeof(tlv_rxba->header) + tlv_len);
+		tmp = (u8 *)tlv_rxba  + sizeof(tlv_rxba->header) + tlv_len;
 		tlv_rxba = (struct mwifiex_ie_types_rxba_sync *)tmp;
 	}
 }
diff --git a/kernel/drivers/net/wireless/marvell/mwifiex/debugfs.c b/kernel/drivers/net/wireless/marvell/mwifiex/debugfs.c
index dded92d..1e7dc72 100644
--- a/kernel/drivers/net/wireless/marvell/mwifiex/debugfs.c
+++ b/kernel/drivers/net/wireless/marvell/mwifiex/debugfs.c
@@ -265,8 +265,11 @@
 	if (!p)
 		return -ENOMEM;
 
-	if (!priv || !priv->hist_data)
-		return -EFAULT;
+	if (!priv || !priv->hist_data) {
+		ret = -EFAULT;
+		goto free_and_exit;
+	}
+
 	phist_data = priv->hist_data;
 
 	p += sprintf(p, "\n"
@@ -321,6 +324,8 @@
 	ret = simple_read_from_buffer(ubuf, count, ppos, (char *)page,
 				      (unsigned long)p - page);
 
+free_and_exit:
+	free_page(page);
 	return ret;
 }
 
diff --git a/kernel/drivers/net/wireless/marvell/mwifiex/pcie.c b/kernel/drivers/net/wireless/marvell/mwifiex/pcie.c
index b002489..7cec639 100644
--- a/kernel/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/kernel/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -183,7 +183,7 @@
 	.can_ext_scan = true,
 };
 
-static const struct of_device_id mwifiex_pcie_of_match_table[] = {
+static const struct of_device_id mwifiex_pcie_of_match_table[] __maybe_unused = {
 	{ .compatible = "pci11ab,2b42" },
 	{ .compatible = "pci1b4b,2b42" },
 	{ }
@@ -200,6 +200,8 @@
 }
 
 static void mwifiex_pcie_work(struct work_struct *work);
+static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter);
+static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter);
 
 static int
 mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
@@ -794,14 +796,15 @@
 		if (!skb) {
 			mwifiex_dbg(adapter, ERROR,
 				    "Unable to allocate skb for RX ring.\n");
-			kfree(card->rxbd_ring_vbase);
 			return -ENOMEM;
 		}
 
 		if (mwifiex_map_pci_memory(adapter, skb,
 					   MWIFIEX_RX_DATA_BUF_SIZE,
-					   DMA_FROM_DEVICE))
-			return -1;
+					   DMA_FROM_DEVICE)) {
+			kfree_skb(skb);
+			return -ENOMEM;
+		}
 
 		buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
 
@@ -851,7 +854,6 @@
 		if (!skb) {
 			mwifiex_dbg(adapter, ERROR,
 				    "Unable to allocate skb for EVENT buf.\n");
-			kfree(card->evtbd_ring_vbase);
 			return -ENOMEM;
 		}
 		skb_put(skb, MAX_EVENT_SIZE);
@@ -859,8 +861,7 @@
 		if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
 					   DMA_FROM_DEVICE)) {
 			kfree_skb(skb);
-			kfree(card->evtbd_ring_vbase);
-			return -1;
+			return -ENOMEM;
 		}
 
 		buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
@@ -1060,6 +1061,7 @@
  */
 static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
 {
+	int ret;
 	struct pcie_service_card *card = adapter->card;
 	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
 
@@ -1098,7 +1100,10 @@
 		    (u32)((u64)card->rxbd_ring_pbase >> 32),
 		    card->rxbd_ring_size);
 
-	return mwifiex_init_rxq_ring(adapter);
+	ret = mwifiex_init_rxq_ring(adapter);
+	if (ret)
+		mwifiex_pcie_delete_rxbd_ring(adapter);
+	return ret;
 }
 
 /*
@@ -1129,6 +1134,7 @@
  */
 static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
 {
+	int ret;
 	struct pcie_service_card *card = adapter->card;
 	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
 
@@ -1163,7 +1169,10 @@
 		    (u32)((u64)card->evtbd_ring_pbase >> 32),
 		    card->evtbd_ring_size);
 
-	return mwifiex_pcie_init_evt_ring(adapter);
+	ret = mwifiex_pcie_init_evt_ring(adapter);
+	if (ret)
+		mwifiex_pcie_delete_evtbd_ring(adapter);
+	return ret;
 }
 
 /*
diff --git a/kernel/drivers/net/wireless/marvell/mwifiex/scan.c b/kernel/drivers/net/wireless/marvell/mwifiex/scan.c
index c2a685f..78ef40e 100644
--- a/kernel/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/kernel/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -2200,9 +2200,9 @@
 
 	if (nd_config) {
 		adapter->nd_info =
-			kzalloc(sizeof(struct cfg80211_wowlan_nd_match) +
-				sizeof(struct cfg80211_wowlan_nd_match *) *
-				scan_rsp->number_of_sets, GFP_ATOMIC);
+			kzalloc(struct_size(adapter->nd_info, matches,
+					    scan_rsp->number_of_sets),
+				GFP_ATOMIC);
 
 		if (adapter->nd_info)
 			adapter->nd_info->n_matches = scan_rsp->number_of_sets;
diff --git a/kernel/drivers/net/wireless/marvell/mwifiex/sdio.c b/kernel/drivers/net/wireless/marvell/mwifiex/sdio.c
index bde9e4b..b09e60f 100644
--- a/kernel/drivers/net/wireless/marvell/mwifiex/sdio.c
+++ b/kernel/drivers/net/wireless/marvell/mwifiex/sdio.c
@@ -484,7 +484,8 @@
 	{"EXTLAST", NULL, 0, 0xFE},
 };
 
-static const struct of_device_id mwifiex_sdio_of_match_table[] = {
+static const struct of_device_id mwifiex_sdio_of_match_table[] __maybe_unused = {
+	{ .compatible = "marvell,sd8787" },
 	{ .compatible = "marvell,sd8897" },
 	{ .compatible = "marvell,sd8997" },
 	{ }
diff --git a/kernel/drivers/net/wireless/marvell/mwifiex/sta_rx.c b/kernel/drivers/net/wireless/marvell/mwifiex/sta_rx.c
index 0d2adf8..5b16e33 100644
--- a/kernel/drivers/net/wireless/marvell/mwifiex/sta_rx.c
+++ b/kernel/drivers/net/wireless/marvell/mwifiex/sta_rx.c
@@ -98,12 +98,23 @@
 	rx_pkt_len = le16_to_cpu(local_rx_pd->rx_pkt_length);
 	rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_off;
 
-	if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
-		     sizeof(bridge_tunnel_header))) ||
-	    (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
-		     sizeof(rfc1042_header)) &&
-	     ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP &&
-	     ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX)) {
+	if (sizeof(rx_pkt_hdr->eth803_hdr) + sizeof(rfc1042_header) +
+	    rx_pkt_off > skb->len) {
+		mwifiex_dbg(priv->adapter, ERROR,
+			    "wrong rx packet offset: len=%d, rx_pkt_off=%d\n",
+			    skb->len, rx_pkt_off);
+		priv->stats.rx_dropped++;
+		dev_kfree_skb_any(skb);
+		return -1;
+	}
+
+	if (sizeof(*rx_pkt_hdr) + rx_pkt_off <= skb->len &&
+	    ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
+		      sizeof(bridge_tunnel_header))) ||
+	     (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
+		      sizeof(rfc1042_header)) &&
+	      ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP &&
+	      ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX))) {
 		/*
 		 *  Replace the 803 header and rfc1042 header (llc/snap) with an
 		 *    EthernetII header, keep the src/dst and snap_type
@@ -206,7 +217,8 @@
 
 	rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_offset;
 
-	if ((rx_pkt_offset + rx_pkt_length) > (u16) skb->len) {
+	if ((rx_pkt_offset + rx_pkt_length) > skb->len ||
+	    sizeof(rx_pkt_hdr->eth803_hdr) + rx_pkt_offset > skb->len) {
 		mwifiex_dbg(adapter, ERROR,
 			    "wrong rx packet: len=%d, rx_pkt_offset=%d, rx_pkt_length=%d\n",
 			    skb->len, rx_pkt_offset, rx_pkt_length);
diff --git a/kernel/drivers/net/wireless/marvell/mwifiex/tdls.c b/kernel/drivers/net/wireless/marvell/mwifiex/tdls.c
index 97bb87c..6c60621 100644
--- a/kernel/drivers/net/wireless/marvell/mwifiex/tdls.c
+++ b/kernel/drivers/net/wireless/marvell/mwifiex/tdls.c
@@ -735,6 +735,7 @@
 	int ret;
 	u16 capab;
 	struct ieee80211_ht_cap *ht_cap;
+	unsigned int extra;
 	u8 radio, *pos;
 
 	capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap;
@@ -753,7 +754,10 @@
 
 	switch (action_code) {
 	case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
-		skb_put(skb, sizeof(mgmt->u.action.u.tdls_discover_resp) + 1);
+		/* See the layout of 'struct ieee80211_mgmt'. */
+		extra = sizeof(mgmt->u.action.u.tdls_discover_resp) +
+			sizeof(mgmt->u.action.category);
+		skb_put(skb, extra);
 		mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
 		mgmt->u.action.u.tdls_discover_resp.action_code =
 					      WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
@@ -762,8 +766,7 @@
 		mgmt->u.action.u.tdls_discover_resp.capability =
 							     cpu_to_le16(capab);
 		/* move back for addr4 */
-		memmove(pos + ETH_ALEN, &mgmt->u.action.category,
-			sizeof(mgmt->u.action.u.tdls_discover_resp));
+		memmove(pos + ETH_ALEN, &mgmt->u.action, extra);
 		/* init address 4 */
 		eth_broadcast_addr(pos);
 
diff --git a/kernel/drivers/net/wireless/marvell/mwifiex/uap_txrx.c b/kernel/drivers/net/wireless/marvell/mwifiex/uap_txrx.c
index 9bbdb8d..780ea46 100644
--- a/kernel/drivers/net/wireless/marvell/mwifiex/uap_txrx.c
+++ b/kernel/drivers/net/wireless/marvell/mwifiex/uap_txrx.c
@@ -115,6 +115,16 @@
 		return;
 	}
 
+	if (sizeof(*rx_pkt_hdr) +
+	    le16_to_cpu(uap_rx_pd->rx_pkt_offset) > skb->len) {
+		mwifiex_dbg(adapter, ERROR,
+			    "wrong rx packet offset: len=%d,rx_pkt_offset=%d\n",
+			    skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset));
+		priv->stats.rx_dropped++;
+		dev_kfree_skb_any(skb);
+		return;
+	}
+
 	if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
 		     sizeof(bridge_tunnel_header))) ||
 	    (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
@@ -255,7 +265,15 @@
 
 	if (is_multicast_ether_addr(ra)) {
 		skb_uap = skb_copy(skb, GFP_ATOMIC);
-		mwifiex_uap_queue_bridged_pkt(priv, skb_uap);
+		if (likely(skb_uap)) {
+			mwifiex_uap_queue_bridged_pkt(priv, skb_uap);
+		} else {
+			mwifiex_dbg(adapter, ERROR,
+				    "failed to copy skb for uAP\n");
+			priv->stats.rx_dropped++;
+			dev_kfree_skb_any(skb);
+			return -1;
+		}
 	} else {
 		if (mwifiex_get_sta_entry(priv, ra)) {
 			/* Requeue Intra-BSS packet */
@@ -379,6 +397,16 @@
 	rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type);
 	rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
 
+	if (le16_to_cpu(uap_rx_pd->rx_pkt_offset) +
+	    sizeof(rx_pkt_hdr->eth803_hdr) > skb->len) {
+		mwifiex_dbg(adapter, ERROR,
+			    "wrong rx packet for struct ethhdr: len=%d, offset=%d\n",
+			    skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset));
+		priv->stats.rx_dropped++;
+		dev_kfree_skb_any(skb);
+		return 0;
+	}
+
 	ether_addr_copy(ta, rx_pkt_hdr->eth803_hdr.h_source);
 
 	if ((le16_to_cpu(uap_rx_pd->rx_pkt_offset) +
diff --git a/kernel/drivers/net/wireless/marvell/mwifiex/util.c b/kernel/drivers/net/wireless/marvell/mwifiex/util.c
index d583fa6..1f5a6da 100644
--- a/kernel/drivers/net/wireless/marvell/mwifiex/util.c
+++ b/kernel/drivers/net/wireless/marvell/mwifiex/util.c
@@ -405,11 +405,15 @@
 	}
 
 	rx_pd = (struct rxpd *)skb->data;
+	pkt_len = le16_to_cpu(rx_pd->rx_pkt_length);
+	if (pkt_len < sizeof(struct ieee80211_hdr) + sizeof(pkt_len)) {
+		mwifiex_dbg(priv->adapter, ERROR, "invalid rx_pkt_length");
+		return -1;
+	}
 
 	skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset));
 	skb_pull(skb, sizeof(pkt_len));
-
-	pkt_len = le16_to_cpu(rx_pd->rx_pkt_length);
+	pkt_len -= sizeof(pkt_len);
 
 	ieee_hdr = (void *)skb->data;
 	if (ieee80211_is_mgmt(ieee_hdr->frame_control)) {
@@ -422,7 +426,7 @@
 		skb->data + sizeof(struct ieee80211_hdr),
 		pkt_len - sizeof(struct ieee80211_hdr));
 
-	pkt_len -= ETH_ALEN + sizeof(pkt_len);
+	pkt_len -= ETH_ALEN;
 	rx_pd->rx_pkt_length = cpu_to_le16(pkt_len);
 
 	cfg80211_rx_mgmt(&priv->wdev, priv->roc_cfg.chan.center_freq,
diff --git a/kernel/drivers/net/wireless/mediatek/mt76/dma.c b/kernel/drivers/net/wireless/mediatek/mt76/dma.c
index f01b455..7991705 100644
--- a/kernel/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/kernel/drivers/net/wireless/mediatek/mt76/dma.c
@@ -476,6 +476,7 @@
 	bool more;
 
 	spin_lock_bh(&q->lock);
+
 	do {
 		buf = mt76_dma_dequeue(dev, q, true, NULL, NULL, &more);
 		if (!buf)
@@ -483,6 +484,12 @@
 
 		skb_free_frag(buf);
 	} while (1);
+
+	if (q->rx_head) {
+		dev_kfree_skb(q->rx_head);
+		q->rx_head = NULL;
+	}
+
 	spin_unlock_bh(&q->lock);
 
 	if (!q->rx_page.va)
@@ -505,12 +512,6 @@
 	mt76_dma_rx_cleanup(dev, q);
 	mt76_dma_sync_idx(dev, q);
 	mt76_dma_rx_fill(dev, q);
-
-	if (!q->rx_head)
-		return;
-
-	dev_kfree_skb(q->rx_head);
-	q->rx_head = NULL;
 }
 
 static void
diff --git a/kernel/drivers/net/wireless/mediatek/mt76/mac80211.c b/kernel/drivers/net/wireless/mediatek/mt76/mac80211.c
index 81ff3b4..dc1191a 100644
--- a/kernel/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/kernel/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -160,9 +160,9 @@
 
 void mt76_set_stream_caps(struct mt76_phy *phy, bool vht)
 {
-	if (phy->dev->cap.has_2ghz)
+	if (phy->cap.has_2ghz)
 		mt76_init_stream_cap(phy, &phy->sband_2g.sband, false);
-	if (phy->dev->cap.has_5ghz)
+	if (phy->cap.has_5ghz)
 		mt76_init_stream_cap(phy, &phy->sband_5g.sband, vht);
 }
 EXPORT_SYMBOL_GPL(mt76_set_stream_caps);
@@ -463,13 +463,13 @@
 	dev_set_drvdata(dev->dev, dev);
 	mt76_phy_init(dev, hw);
 
-	if (dev->cap.has_2ghz) {
+	if (phy->cap.has_2ghz) {
 		ret = mt76_init_sband_2g(dev, rates, n_rates);
 		if (ret)
 			return ret;
 	}
 
-	if (dev->cap.has_5ghz) {
+	if (phy->cap.has_5ghz) {
 		ret = mt76_init_sband_5g(dev, rates + 4, n_rates - 4, vht);
 		if (ret)
 			return ret;
diff --git a/kernel/drivers/net/wireless/mediatek/mt76/mt76.h b/kernel/drivers/net/wireless/mediatek/mt76/mt76.h
index a5be66d..16e6502 100644
--- a/kernel/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/kernel/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -561,6 +561,7 @@
 	struct mt76_channel_state *chan_state;
 	ktime_t survey_time;
 
+	struct mt76_hw_cap cap;
 	struct mt76_sband sband_2g;
 	struct mt76_sband sband_5g;
 
@@ -630,7 +631,6 @@
 
 	struct debugfs_blob_wrapper eeprom;
 	struct debugfs_blob_wrapper otp;
-	struct mt76_hw_cap cap;
 
 	struct mt76_rate_power rate_power;
 
@@ -884,8 +884,9 @@
 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)
diff --git a/kernel/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c b/kernel/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
index 01f1e0d..a6df733 100644
--- a/kernel/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
+++ b/kernel/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
@@ -170,7 +170,7 @@
 	}
 
 	eeprom = (u8 *)dev->mt76.eeprom.data;
-	dev->mt76.cap.has_2ghz = true;
+	dev->mphy.cap.has_2ghz = true;
 	memcpy(dev->mt76.macaddr, eeprom + MT_EE_MAC_ADDR, ETH_ALEN);
 
 	/* Check for 1SS devices */
diff --git a/kernel/drivers/net/wireless/mediatek/mt76/mt7615/dma.c b/kernel/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
index bf8ae14..637ef08 100644
--- a/kernel/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
+++ b/kernel/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
@@ -202,7 +202,7 @@
 	int ret;
 
 	/* Increase buffer size to receive large VHT MPDUs */
-	if (dev->mt76.cap.has_5ghz)
+	if (dev->mphy.cap.has_5ghz)
 		rx_buf_size *= 2;
 
 	mt76_dma_attach(&dev->mt76);
diff --git a/kernel/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c b/kernel/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
index e9cdcdc..85f5648 100644
--- a/kernel/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
+++ b/kernel/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
@@ -100,20 +100,20 @@
 
 	if (is_mt7663(&dev->mt76)) {
 		/* dual band */
-		dev->mt76.cap.has_2ghz = true;
-		dev->mt76.cap.has_5ghz = true;
+		dev->mphy.cap.has_2ghz = true;
+		dev->mphy.cap.has_5ghz = true;
 		return;
 	}
 
 	if (is_mt7622(&dev->mt76)) {
 		/* 2GHz only */
-		dev->mt76.cap.has_2ghz = true;
+		dev->mphy.cap.has_2ghz = true;
 		return;
 	}
 
 	if (is_mt7611(&dev->mt76)) {
 		/* 5GHz only */
-		dev->mt76.cap.has_5ghz = true;
+		dev->mphy.cap.has_5ghz = true;
 		return;
 	}
 
@@ -121,17 +121,17 @@
 			eeprom[MT_EE_WIFI_CONF]);
 	switch (val) {
 	case MT_EE_5GHZ:
-		dev->mt76.cap.has_5ghz = true;
-		break;
-	case MT_EE_2GHZ:
-		dev->mt76.cap.has_2ghz = true;
+		dev->mphy.cap.has_5ghz = true;
 		break;
 	case MT_EE_DBDC:
 		dev->dbdc_support = true;
-		/* fall through */
+		fallthrough;
+	case MT_EE_2GHZ:
+		dev->mphy.cap.has_2ghz = true;
+		break;
 	default:
-		dev->mt76.cap.has_2ghz = true;
-		dev->mt76.cap.has_5ghz = true;
+		dev->mphy.cap.has_2ghz = true;
+		dev->mphy.cap.has_5ghz = true;
 		break;
 	}
 }
diff --git a/kernel/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/kernel/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
index b266170..4364f73 100644
--- a/kernel/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+++ b/kernel/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
@@ -779,7 +779,10 @@
 
 		msta = list_first_entry(&sta_poll_list, struct mt7615_sta,
 					poll_list);
+
+		spin_lock_bh(&dev->sta_poll_lock);
 		list_del_init(&msta->poll_list);
+		spin_unlock_bh(&dev->sta_poll_lock);
 
 		addr = mt7615_mac_wtbl_addr(dev, msta->wcid.idx) + 19 * 4;
 
diff --git a/kernel/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c b/kernel/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
index 9087607..ebf4c96 100644
--- a/kernel/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
+++ b/kernel/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
@@ -52,15 +52,15 @@
 
 	mt76x02_eeprom_parse_hw_cap(dev);
 	dev_dbg(dev->mt76.dev, "2GHz %d 5GHz %d\n",
-		dev->mt76.cap.has_2ghz, dev->mt76.cap.has_5ghz);
+		dev->mphy.cap.has_2ghz, dev->mphy.cap.has_5ghz);
 
 	if (dev->no_2ghz) {
-		dev->mt76.cap.has_2ghz = false;
+		dev->mphy.cap.has_2ghz = false;
 		dev_dbg(dev->mt76.dev, "mask out 2GHz support\n");
 	}
 
 	if (is_mt7630(dev)) {
-		dev->mt76.cap.has_5ghz = false;
+		dev->mphy.cap.has_5ghz = false;
 		dev_dbg(dev->mt76.dev, "mask out 5GHz support\n");
 	}
 
diff --git a/kernel/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/kernel/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
index d78866b..0bac39b 100644
--- a/kernel/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
+++ b/kernel/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
@@ -245,7 +245,7 @@
 	if (ret)
 		return ret;
 
-	if (dev->mt76.cap.has_5ghz) {
+	if (dev->mphy.cap.has_5ghz) {
 		struct ieee80211_supported_band *sband;
 
 		sband = &dev->mphy.sband_5g.sband;
@@ -253,7 +253,7 @@
 		mt76x0_init_txpower(dev, sband);
 	}
 
-	if (dev->mt76.cap.has_2ghz)
+	if (dev->mphy.cap.has_2ghz)
 		mt76x0_init_txpower(dev, &dev->mphy.sband_2g.sband);
 
 	mt76x02_init_debugfs(dev);
diff --git a/kernel/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c b/kernel/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index 3de33aa..e91c314c 100644
--- a/kernel/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/kernel/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -447,11 +447,11 @@
 		else
 			coex3 |= BIT(4);
 		coex3 |= BIT(3);
-		if (dev->mt76.cap.has_2ghz)
+		if (dev->mphy.cap.has_2ghz)
 			wlan |= BIT(6);
 	} else {
 		/* sigle antenna mode */
-		if (dev->mt76.cap.has_5ghz) {
+		if (dev->mphy.cap.has_5ghz) {
 			coex3 |= BIT(3) | BIT(4);
 		} else {
 			wlan |= BIT(6);
diff --git a/kernel/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c b/kernel/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c
index c54c50f..5d402cf 100644
--- a/kernel/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c
+++ b/kernel/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c
@@ -75,14 +75,14 @@
 
 	switch (FIELD_GET(MT_EE_NIC_CONF_0_BOARD_TYPE, val)) {
 	case BOARD_TYPE_5GHZ:
-		dev->mt76.cap.has_5ghz = true;
+		dev->mphy.cap.has_5ghz = true;
 		break;
 	case BOARD_TYPE_2GHZ:
-		dev->mt76.cap.has_2ghz = true;
+		dev->mphy.cap.has_2ghz = true;
 		break;
 	default:
-		dev->mt76.cap.has_2ghz = true;
-		dev->mt76.cap.has_5ghz = true;
+		dev->mphy.cap.has_2ghz = true;
+		dev->mphy.cap.has_5ghz = true;
 		break;
 	}
 }
@@ -131,14 +131,7 @@
 			s8 *lna_2g, s8 *lna_5g,
 			struct ieee80211_channel *chan)
 {
-	u16 val;
 	u8 lna;
-
-	val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1);
-	if (val & MT_EE_NIC_CONF_1_LNA_EXT_2G)
-		*lna_2g = 0;
-	if (val & MT_EE_NIC_CONF_1_LNA_EXT_5G)
-		memset(lna_5g, 0, sizeof(s8) * 3);
 
 	if (chan->band == NL80211_BAND_2GHZ)
 		lna = *lna_2g;
diff --git a/kernel/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c b/kernel/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c
index 410ffce..6047811 100644
--- a/kernel/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c
+++ b/kernel/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c
@@ -256,7 +256,8 @@
 	struct ieee80211_channel *chan = dev->mphy.chandef.chan;
 	int channel = chan->hw_value;
 	s8 lna_5g[3], lna_2g;
-	u8 lna;
+	bool use_lna;
+	u8 lna = 0;
 	u16 val;
 
 	if (chan->band == NL80211_BAND_2GHZ)
@@ -275,7 +276,15 @@
 	dev->cal.rx.mcu_gain |= (lna_5g[1] & 0xff) << 16;
 	dev->cal.rx.mcu_gain |= (lna_5g[2] & 0xff) << 24;
 
-	lna = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan);
+	val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1);
+	if (chan->band == NL80211_BAND_2GHZ)
+		use_lna = !(val & MT_EE_NIC_CONF_1_LNA_EXT_2G);
+	else
+		use_lna = !(val & MT_EE_NIC_CONF_1_LNA_EXT_5G);
+
+	if (use_lna)
+		lna = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan);
+
 	dev->cal.rx.lna_gain = mt76x02_sign_extend(lna, 8);
 }
 EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain);
diff --git a/kernel/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/kernel/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
index e4c5f96..5f6c527 100644
--- a/kernel/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
+++ b/kernel/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
@@ -57,14 +57,14 @@
 	val = FIELD_GET(MT_EE_WIFI_CONF_BAND_SEL, val);
 	switch (val) {
 	case MT_EE_5GHZ:
-		dev->mt76.cap.has_5ghz = true;
+		dev->mphy.cap.has_5ghz = true;
 		break;
 	case MT_EE_2GHZ:
-		dev->mt76.cap.has_2ghz = true;
+		dev->mphy.cap.has_2ghz = true;
 		break;
 	default:
-		dev->mt76.cap.has_2ghz = true;
-		dev->mt76.cap.has_5ghz = true;
+		dev->mphy.cap.has_2ghz = true;
+		dev->mphy.cap.has_5ghz = true;
 		break;
 	}
 
diff --git a/kernel/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/kernel/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index 8f01ca1..9968368 100644
--- a/kernel/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/kernel/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -528,10 +528,9 @@
 {
 	struct ieee80211_sband_iftype_data *data;
 	struct ieee80211_supported_band *band;
-	struct mt76_dev *mdev = &phy->dev->mt76;
 	int n;
 
-	if (mdev->cap.has_2ghz) {
+	if (phy->mt76->cap.has_2ghz) {
 		data = phy->iftype[NL80211_BAND_2GHZ];
 		n = mt7915_init_he_caps(phy, NL80211_BAND_2GHZ, data);
 
@@ -540,7 +539,7 @@
 		band->n_iftype_data = n;
 	}
 
-	if (mdev->cap.has_5ghz) {
+	if (phy->mt76->cap.has_5ghz) {
 		data = phy->iftype[NL80211_BAND_5GHZ];
 		n = mt7915_init_he_caps(phy, NL80211_BAND_5GHZ, data);
 
diff --git a/kernel/drivers/net/wireless/mediatek/mt76/testmode.c b/kernel/drivers/net/wireless/mediatek/mt76/testmode.c
index 883f59c..7ab99ef 100644
--- a/kernel/drivers/net/wireless/mediatek/mt76/testmode.c
+++ b/kernel/drivers/net/wireless/mediatek/mt76/testmode.c
@@ -6,6 +6,7 @@
 	[MT76_TM_ATTR_RESET] = { .type = NLA_FLAG },
 	[MT76_TM_ATTR_STATE] = { .type = NLA_U8 },
 	[MT76_TM_ATTR_TX_COUNT] = { .type = NLA_U32 },
+	[MT76_TM_ATTR_TX_LENGTH] = { .type = NLA_U32 },
 	[MT76_TM_ATTR_TX_RATE_MODE] = { .type = NLA_U8 },
 	[MT76_TM_ATTR_TX_RATE_NSS] = { .type = NLA_U8 },
 	[MT76_TM_ATTR_TX_RATE_IDX] = { .type = NLA_U8 },
diff --git a/kernel/drivers/net/wireless/mediatek/mt7601u/dma.c b/kernel/drivers/net/wireless/mediatek/mt7601u/dma.c
index 1107151..8ba291a 100644
--- a/kernel/drivers/net/wireless/mediatek/mt7601u/dma.c
+++ b/kernel/drivers/net/wireless/mediatek/mt7601u/dma.c
@@ -118,7 +118,8 @@
 	if (data_len < min_seg_len ||
 	    WARN_ON_ONCE(!dma_len) ||
 	    WARN_ON_ONCE(dma_len + MT_DMA_HDRS > data_len) ||
-	    WARN_ON_ONCE(dma_len & 0x3))
+	    WARN_ON_ONCE(dma_len & 0x3) ||
+	    WARN_ON_ONCE(dma_len < min_seg_len))
 		return 0;
 
 	return MT_DMA_HDRS + dma_len;
diff --git a/kernel/drivers/net/wireless/microchip/wilc1000/hif.c b/kernel/drivers/net/wireless/microchip/wilc1000/hif.c
index b258477..884f45e 100644
--- a/kernel/drivers/net/wireless/microchip/wilc1000/hif.c
+++ b/kernel/drivers/net/wireless/microchip/wilc1000/hif.c
@@ -470,6 +470,9 @@
 		int rsn_ie_len = sizeof(struct element) + rsn_ie[1];
 		int offset = 8;
 
+		param->mode_802_11i = 2;
+		param->rsn_found = true;
+
 		/* extract RSN capabilities */
 		if (offset < rsn_ie_len) {
 			/* skip over pairwise suites */
@@ -479,11 +482,8 @@
 				/* skip over authentication suites */
 				offset += (rsn_ie[offset] * 4) + 2;
 
-				if (offset + 1 < rsn_ie_len) {
-					param->mode_802_11i = 2;
-					param->rsn_found = true;
+				if (offset + 1 < rsn_ie_len)
 					memcpy(param->rsn_cap, &rsn_ie[offset], 2);
-				}
 			}
 		}
 	}
diff --git a/kernel/drivers/net/wireless/microchip/wilc1000/netdev.c b/kernel/drivers/net/wireless/microchip/wilc1000/netdev.c
index 20615c7..c508f42 100644
--- a/kernel/drivers/net/wireless/microchip/wilc1000/netdev.c
+++ b/kernel/drivers/net/wireless/microchip/wilc1000/netdev.c
@@ -684,6 +684,7 @@
 
 	if (skb->dev != ndev) {
 		netdev_err(ndev, "Packet not destined to this device\n");
+		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
 	}
 
diff --git a/kernel/drivers/net/wireless/microchip/wilc1000/sdio.c b/kernel/drivers/net/wireless/microchip/wilc1000/sdio.c
index e14b9fc..58d9231 100644
--- a/kernel/drivers/net/wireless/microchip/wilc1000/sdio.c
+++ b/kernel/drivers/net/wireless/microchip/wilc1000/sdio.c
@@ -20,6 +20,7 @@
 	{ SDIO_DEVICE(SDIO_VENDOR_ID_MICROCHIP_WILC, SDIO_DEVICE_ID_MICROCHIP_WILC1000) },
 	{ },
 };
+MODULE_DEVICE_TABLE(sdio, wilc_sdio_ids);
 
 #define WILC_SDIO_BLOCK_SIZE 512
 
diff --git a/kernel/drivers/net/wireless/ray_cs.c b/kernel/drivers/net/wireless/ray_cs.c
index 091eea0..bf12827 100644
--- a/kernel/drivers/net/wireless/ray_cs.c
+++ b/kernel/drivers/net/wireless/ray_cs.c
@@ -270,13 +270,14 @@
 {
 	ray_dev_t *local;
 	struct net_device *dev;
+	int ret;
 
 	dev_dbg(&p_dev->dev, "ray_attach()\n");
 
 	/* Allocate space for private device-specific data */
 	dev = alloc_etherdev(sizeof(ray_dev_t));
 	if (!dev)
-		goto fail_alloc_dev;
+		return -ENOMEM;
 
 	local = netdev_priv(dev);
 	local->finder = p_dev;
@@ -313,11 +314,16 @@
 	timer_setup(&local->timer, NULL, 0);
 
 	this_device = p_dev;
-	return ray_config(p_dev);
+	ret = ray_config(p_dev);
+	if (ret)
+		goto err_free_dev;
 
-fail_alloc_dev:
-	return -ENOMEM;
-} /* ray_attach */
+	return 0;
+
+err_free_dev:
+	free_netdev(dev);
+	return ret;
+}
 
 static void ray_detach(struct pcmcia_device *link)
 {
@@ -1641,38 +1647,34 @@
 /*===========================================================================*/
 static int parse_addr(char *in_str, UCHAR *out)
 {
+	int i, k;
 	int len;
-	int i, j, k;
-	int status;
 
 	if (in_str == NULL)
 		return 0;
-	if ((len = strlen(in_str)) < 2)
+	len = strnlen(in_str, ADDRLEN * 2 + 1) - 1;
+	if (len < 1)
 		return 0;
 	memset(out, 0, ADDRLEN);
 
-	status = 1;
-	j = len - 1;
-	if (j > 12)
-		j = 12;
 	i = 5;
 
-	while (j > 0) {
-		if ((k = hex_to_bin(in_str[j--])) != -1)
+	while (len > 0) {
+		if ((k = hex_to_bin(in_str[len--])) != -1)
 			out[i] = k;
 		else
 			return 0;
 
-		if (j == 0)
+		if (len == 0)
 			break;
-		if ((k = hex_to_bin(in_str[j--])) != -1)
+		if ((k = hex_to_bin(in_str[len--])) != -1)
 			out[i] += k << 4;
 		else
 			return 0;
 		if (!i--)
 			break;
 	}
-	return status;
+	return 1;
 }
 
 /*===========================================================================*/
diff --git a/kernel/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/kernel/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
index b28fa0c..fe1e4c4 100644
--- a/kernel/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+++ b/kernel/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
@@ -1190,7 +1190,7 @@
 			u8 bw;
 		} __packed ra_report;
 	};
-};
+} __packed;
 
 struct rtl8xxxu_fileops;
 
@@ -1346,6 +1346,7 @@
 	u32 rege9c;
 	u32 regeb4;
 	u32 regebc;
+	u32 regrcr;
 	int next_mbox;
 	int nr_out_eps;
 
diff --git a/kernel/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c b/kernel/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
index 199e7e0..6d13327 100644
--- a/kernel/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
+++ b/kernel/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
@@ -1671,6 +1671,11 @@
 	val8 = rtl8xxxu_read8(priv, REG_PAD_CTRL1);
 	val8 &= ~BIT(0);
 	rtl8xxxu_write8(priv, REG_PAD_CTRL1, val8);
+
+	/*
+	 * Fix transmission failure of rtl8192e.
+	 */
+	rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00);
 }
 
 struct rtl8xxxu_fileops rtl8192eu_fops = {
@@ -1697,6 +1702,7 @@
 	.rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24),
 	.has_s0s1 = 0,
 	.gen2_thermal_meter = 1,
+	.needs_full_init = 1,
 	.adda_1t_init = 0x0fc01616,
 	.adda_1t_path_on = 0x0fc01616,
 	.adda_2t_path_on_a = 0x0fc01616,
diff --git a/kernel/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/kernel/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
index e34cd6f..004778f 100644
--- a/kernel/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+++ b/kernel/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
@@ -1607,18 +1607,18 @@
 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 @@
 		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 @@
 	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 @@
 		}
 		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 {
@@ -4045,6 +4045,7 @@
 		RCR_ACCEPT_MGMT_FRAME | RCR_HTC_LOC_CTRL |
 		RCR_APPEND_PHYSTAT | RCR_APPEND_ICV | RCR_APPEND_MIC;
 	rtl8xxxu_write32(priv, REG_RCR, val32);
+	priv->regrcr = val32;
 
 	/*
 	 * Accept all multicast
@@ -4369,12 +4370,9 @@
 void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
 				  u8 macid, bool connect)
 {
-#ifdef RTL8XXXU_GEN2_REPORT_CONNECT
 	/*
-	 * Barry Day reports this causes issues with 8192eu and 8723bu
-	 * devices reconnecting. The reason for this is unclear, but
-	 * until it is better understood, leave the code in place but
-	 * disabled, so it is not lost.
+	 * The firmware turns on the rate control when it knows it's
+	 * connected to a network.
 	 */
 	struct h2c_cmd h2c;
 
@@ -4387,7 +4385,6 @@
 		h2c.media_status_rpt.parm &= ~BIT(0);
 
 	rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.media_status_rpt));
-#endif
 }
 
 void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv)
@@ -5188,7 +5185,7 @@
 		pending = priv->rx_urb_pending_count;
 	} else {
 		skb = (struct sk_buff *)rx_urb->urb.context;
-		dev_kfree_skb(skb);
+		dev_kfree_skb_irq(skb);
 		usb_free_urb(&rx_urb->urb);
 	}
 
@@ -5495,9 +5492,6 @@
 	btcoex = &priv->bt_coex;
 	rarpt = &priv->ra_report;
 
-	if (priv->rf_paths > 1)
-		goto out;
-
 	while (!skb_queue_empty(&priv->c2hcmd_queue)) {
 		spin_lock_irqsave(&priv->c2hcmd_lock, flags);
 		skb = __skb_dequeue(&priv->c2hcmd_queue);
@@ -5520,7 +5514,6 @@
 			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 +5530,13 @@
 						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;
@@ -5547,10 +5545,9 @@
 		default:
 			break;
 		}
-	}
 
-out:
-	dev_kfree_skb(skb);
+		dev_kfree_skb(skb);
+	}
 }
 
 static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv,
@@ -5912,7 +5909,6 @@
 {
 	struct rtl8xxxu_priv *priv = hw->priv;
 	struct device *dev = &priv->udev->dev;
-	u16 val16;
 	int ret = 0, channel;
 	bool ht40;
 
@@ -5921,14 +5917,6 @@
 			 "%s: channel: %i (changed %08x chandef.width %02x)\n",
 			 __func__, hw->conf.chandef.chan->hw_value,
 			 changed, hw->conf.chandef.width);
-
-	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
-		val16 = ((hw->conf.long_frame_max_tx_count <<
-			  RETRY_LIMIT_LONG_SHIFT) & RETRY_LIMIT_LONG_MASK) |
-			((hw->conf.short_frame_max_tx_count <<
-			  RETRY_LIMIT_SHORT_SHIFT) & RETRY_LIMIT_SHORT_MASK);
-		rtl8xxxu_write16(priv, REG_RETRY_LIMIT, val16);
-	}
 
 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
 		switch (hw->conf.chandef.width) {
@@ -6012,7 +6000,7 @@
 				      unsigned int *total_flags, u64 multicast)
 {
 	struct rtl8xxxu_priv *priv = hw->priv;
-	u32 rcr = rtl8xxxu_read32(priv, REG_RCR);
+	u32 rcr = priv->regrcr;
 
 	dev_dbg(&priv->udev->dev, "%s: changed_flags %08x, total_flags %08x\n",
 		__func__, changed_flags, *total_flags);
@@ -6058,6 +6046,7 @@
 	 */
 
 	rtl8xxxu_write32(priv, REG_RCR, rcr);
+	priv->regrcr = rcr;
 
 	*total_flags &= (FIF_ALLMULTI | FIF_FCSFAIL | FIF_BCN_PRBRESP_PROMISC |
 			 FIF_CONTROL | FIF_OTHER_BSS | FIF_PSPOLL |
diff --git a/kernel/drivers/net/wireless/realtek/rtlwifi/debug.c b/kernel/drivers/net/wireless/realtek/rtlwifi/debug.c
index 0b1bc04..9eb26df 100644
--- a/kernel/drivers/net/wireless/realtek/rtlwifi/debug.c
+++ b/kernel/drivers/net/wireless/realtek/rtlwifi/debug.c
@@ -278,8 +278,8 @@
 
 	tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
 
-	if (!buffer || copy_from_user(tmp, buffer, tmp_len))
-		return count;
+	if (copy_from_user(tmp, buffer, tmp_len))
+		return -EFAULT;
 
 	tmp[tmp_len] = '\0';
 
@@ -287,7 +287,7 @@
 	num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
 
 	if (num !=  3)
-		return count;
+		return -EINVAL;
 
 	switch (len) {
 	case 1:
@@ -375,8 +375,8 @@
 
 	tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
 
-	if (!buffer || copy_from_user(tmp, buffer, tmp_len))
-		return count;
+	if (copy_from_user(tmp, buffer, tmp_len))
+		return -EFAULT;
 
 	tmp[tmp_len] = '\0';
 
@@ -386,7 +386,7 @@
 	if (num != 4) {
 		rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG,
 			"Format is <path> <addr> <mask> <data>\n");
-		return count;
+		return -EINVAL;
 	}
 
 	rtl_set_rfreg(hw, path, addr, bitmask, data);
diff --git a/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c b/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c
index 63f9ea2..335a3c9 100644
--- a/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c
+++ b/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c
@@ -68,8 +68,10 @@
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
+	struct sk_buff_head free_list;
 	unsigned long flags;
 
+	skb_queue_head_init(&free_list);
 	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
 	while (skb_queue_len(&ring->queue)) {
 		struct rtl_tx_desc *entry = &ring->desc[ring->idx];
@@ -79,10 +81,12 @@
 				 rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
 						true, HW_DESC_TXBUFF_ADDR),
 				 skb->len, DMA_TO_DEVICE);
-		kfree_skb(skb);
+		__skb_queue_tail(&free_list, skb);
 		ring->idx = (ring->idx + 1) % ring->entries;
 	}
 	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+	__skb_queue_purge(&free_list);
 }
 
 static void _rtl88ee_disable_bcn_sub_func(struct ieee80211_hw *hw)
diff --git a/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c b/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
index e34d33e..d3027f8 100644
--- a/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
+++ b/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
@@ -2385,14 +2385,10 @@
 			rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD,
 				"Just Read IQK Matrix reg for channel:%d....\n",
 				channel);
-			if ((rtlphy->iqk_matrix[indexforchannel].
-			     value[0] != NULL)
-				/*&&(regea4 != 0) */)
+			if (rtlphy->iqk_matrix[indexforchannel].value[0][0] != 0)
 				_rtl92d_phy_patha_fill_iqk_matrix(hw, true,
-					rtlphy->iqk_matrix[
-					indexforchannel].value,	0,
-					(rtlphy->iqk_matrix[
-					indexforchannel].value[0][2] == 0));
+					rtlphy->iqk_matrix[indexforchannel].value, 0,
+					rtlphy->iqk_matrix[indexforchannel].value[0][2] == 0);
 			if (IS_92D_SINGLEPHY(rtlhal->version)) {
 				if ((rtlphy->iqk_matrix[
 					indexforchannel].value[0][4] != 0)
diff --git a/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
index 0748aed..ccbb082 100644
--- a/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
+++ b/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
@@ -30,8 +30,10 @@
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
+	struct sk_buff_head free_list;
 	unsigned long flags;
 
+	skb_queue_head_init(&free_list);
 	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
 	while (skb_queue_len(&ring->queue)) {
 		struct rtl_tx_desc *entry = &ring->desc[ring->idx];
@@ -41,10 +43,12 @@
 				 rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
 						true, HW_DESC_TXBUFF_ADDR),
 				 skb->len, DMA_TO_DEVICE);
-		kfree_skb(skb);
+		__skb_queue_tail(&free_list, skb);
 		ring->idx = (ring->idx + 1) % ring->entries;
 	}
 	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+	__skb_queue_purge(&free_list);
 }
 
 static void _rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
diff --git a/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
index 33ffc24..c4ee65c 100644
--- a/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
+++ b/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
@@ -26,8 +26,10 @@
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
+	struct sk_buff_head free_list;
 	unsigned long flags;
 
+	skb_queue_head_init(&free_list);
 	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
 	while (skb_queue_len(&ring->queue)) {
 		struct rtl_tx_desc *entry = &ring->desc[ring->idx];
@@ -37,10 +39,12 @@
 				 rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
 						true, HW_DESC_TXBUFF_ADDR),
 				 skb->len, DMA_TO_DEVICE);
-		kfree_skb(skb);
+		__skb_queue_tail(&free_list, skb);
 		ring->idx = (ring->idx + 1) % ring->entries;
 	}
 	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+	__skb_queue_purge(&free_list);
 }
 
 static void _rtl8821ae_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
diff --git a/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c b/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
index f41a764..c0c06ab 100644
--- a/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
+++ b/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
@@ -1581,7 +1581,7 @@
 }
 
 /* string is in decimal */
-static bool _rtl8812ae_get_integer_from_string(char *str, u8 *pint)
+static bool _rtl8812ae_get_integer_from_string(const char *str, u8 *pint)
 {
 	u16 i = 0;
 	*pint = 0;
@@ -1596,18 +1596,6 @@
 		++i;
 	}
 
-	return true;
-}
-
-static bool _rtl8812ae_eq_n_byte(u8 *str1, u8 *str2, u32 num)
-{
-	if (num == 0)
-		return false;
-	while (num > 0) {
-		num--;
-		if (str1[num] != str2[num])
-			return false;
-	}
 	return true;
 }
 
@@ -1637,10 +1625,11 @@
 	return channel_index;
 }
 
-static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
-				      u8 *pband, u8 *pbandwidth,
-				      u8 *prate_section, u8 *prf_path,
-				      u8 *pchannel, u8 *ppower_limit)
+static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw,
+				      const char *pregulation,
+				      const char *pband, const char *pbandwidth,
+				      const char *prate_section, const char *prf_path,
+				      const char *pchannel, const char *ppower_limit)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &rtlpriv->phy;
@@ -1648,8 +1637,8 @@
 	u8 channel_index;
 	s8 power_limit = 0, prev_power_limit, ret;
 
-	if (!_rtl8812ae_get_integer_from_string((char *)pchannel, &channel) ||
-	    !_rtl8812ae_get_integer_from_string((char *)ppower_limit,
+	if (!_rtl8812ae_get_integer_from_string(pchannel, &channel) ||
+	    !_rtl8812ae_get_integer_from_string(ppower_limit,
 						&power_limit)) {
 		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 			"Illegal index of pwr_lmt table [chnl %d][val %d]\n",
@@ -1659,42 +1648,42 @@
 	power_limit = power_limit > MAX_POWER_INDEX ?
 		      MAX_POWER_INDEX : power_limit;
 
-	if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
+	if (strcmp(pregulation, "FCC") == 0)
 		regulation = 0;
-	else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
+	else if (strcmp(pregulation, "MKK") == 0)
 		regulation = 1;
-	else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
+	else if (strcmp(pregulation, "ETSI") == 0)
 		regulation = 2;
-	else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
+	else if (strcmp(pregulation, "WW13") == 0)
 		regulation = 3;
 
-	if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
+	if (strcmp(prate_section, "CCK") == 0)
 		rate_section = 0;
-	else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
+	else if (strcmp(prate_section, "OFDM") == 0)
 		rate_section = 1;
-	else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
-		 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
+	else if (strcmp(prate_section, "HT") == 0 &&
+		 strcmp(prf_path, "1T") == 0)
 		rate_section = 2;
-	else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
-		 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
+	else if (strcmp(prate_section, "HT") == 0 &&
+		 strcmp(prf_path, "2T") == 0)
 		rate_section = 3;
-	else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
-		 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
+	else if (strcmp(prate_section, "VHT") == 0 &&
+		 strcmp(prf_path, "1T") == 0)
 		rate_section = 4;
-	else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
-		 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
+	else if (strcmp(prate_section, "VHT") == 0 &&
+		 strcmp(prf_path, "2T") == 0)
 		rate_section = 5;
 
-	if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
+	if (strcmp(pbandwidth, "20M") == 0)
 		bandwidth = 0;
-	else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
+	else if (strcmp(pbandwidth, "40M") == 0)
 		bandwidth = 1;
-	else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
+	else if (strcmp(pbandwidth, "80M") == 0)
 		bandwidth = 2;
-	else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
+	else if (strcmp(pbandwidth, "160M") == 0)
 		bandwidth = 3;
 
-	if (_rtl8812ae_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
+	if (strcmp(pband, "2.4G") == 0) {
 		ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
 							       BAND_ON_2_4G,
 							       channel);
@@ -1718,7 +1707,7 @@
 			regulation, bandwidth, rate_section, channel_index,
 			rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
 				[rate_section][channel_index][RF90_PATH_A]);
-	} else if (_rtl8812ae_eq_n_byte(pband, (u8 *)("5G"), 2)) {
+	} else if (strcmp(pband, "5G") == 0) {
 		ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
 							       BAND_ON_5G,
 							       channel);
@@ -1749,10 +1738,10 @@
 }
 
 static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw,
-					  u8 *regulation, u8 *band,
-					  u8 *bandwidth, u8 *rate_section,
-					  u8 *rf_path, u8 *channel,
-					  u8 *power_limit)
+					  const char *regulation, const char *band,
+					  const char *bandwidth, const char *rate_section,
+					  const char *rf_path, const char *channel,
+					  const char *power_limit)
 {
 	_rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth,
 					 rate_section, rf_path, channel,
@@ -1765,7 +1754,7 @@
 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 	u32 i = 0;
 	u32 array_len;
-	u8 **array;
+	const char **array;
 
 	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
 		array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN;
@@ -1778,13 +1767,13 @@
 	rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "\n");
 
 	for (i = 0; i < array_len; i += 7) {
-		u8 *regulation = array[i];
-		u8 *band = array[i+1];
-		u8 *bandwidth = array[i+2];
-		u8 *rate = array[i+3];
-		u8 *rf_path = array[i+4];
-		u8 *chnl = array[i+5];
-		u8 *val = array[i+6];
+		const char *regulation = array[i];
+		const char *band = array[i+1];
+		const char *bandwidth = array[i+2];
+		const char *rate = array[i+3];
+		const char *rf_path = array[i+4];
+		const char *chnl = array[i+5];
+		const char *val = array[i+6];
 
 		_rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band,
 						   bandwidth, rate, rf_path,
diff --git a/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c b/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c
index ed72a2a..fcaaf66 100644
--- a/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c
+++ b/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c
@@ -2894,7 +2894,7 @@
 *                           TXPWR_LMT.TXT
 ******************************************************************************/
 
-u8 *RTL8812AE_TXPWR_LMT[] = {
+const char *RTL8812AE_TXPWR_LMT[] = {
 	"FCC", "2.4G", "20M", "CCK", "1T", "01", "36",
 	"ETSI", "2.4G", "20M", "CCK", "1T", "01", "32",
 	"MKK", "2.4G", "20M", "CCK", "1T", "01", "32",
@@ -3463,7 +3463,7 @@
 
 u32 RTL8812AE_TXPWR_LMT_ARRAY_LEN = ARRAY_SIZE(RTL8812AE_TXPWR_LMT);
 
-u8 *RTL8821AE_TXPWR_LMT[] = {
+const char *RTL8821AE_TXPWR_LMT[] = {
 	"FCC", "2.4G", "20M", "CCK", "1T", "01", "32",
 	"ETSI", "2.4G", "20M", "CCK", "1T", "01", "32",
 	"MKK", "2.4G", "20M", "CCK", "1T", "01", "32",
diff --git a/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h b/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h
index 540159c..76c62b7 100644
--- a/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h
+++ b/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h
@@ -28,7 +28,7 @@
 extern u32 RTL8812AE_AGC_TAB_1TARRAYLEN;
 extern u32 RTL8812AE_AGC_TAB_ARRAY[];
 extern u32 RTL8812AE_TXPWR_LMT_ARRAY_LEN;
-extern u8 *RTL8812AE_TXPWR_LMT[];
+extern const char *RTL8812AE_TXPWR_LMT[];
 extern u32 RTL8821AE_TXPWR_LMT_ARRAY_LEN;
-extern u8 *RTL8821AE_TXPWR_LMT[];
+extern const char *RTL8821AE_TXPWR_LMT[];
 #endif
diff --git a/kernel/drivers/net/wireless/realtek/rtw88/mac.c b/kernel/drivers/net/wireless/realtek/rtw88/mac.c
index 59028b1..a6d554a 100644
--- a/kernel/drivers/net/wireless/realtek/rtw88/mac.c
+++ b/kernel/drivers/net/wireless/realtek/rtw88/mac.c
@@ -233,7 +233,7 @@
 
 		ret = rtw_sub_pwr_seq_parser(rtwdev, intf_mask, cut_mask, cmd);
 		if (ret)
-			return -EBUSY;
+			return ret;
 
 		idx++;
 	} while (1);
@@ -247,6 +247,7 @@
 	const struct rtw_pwr_seq_cmd **pwr_seq;
 	u8 rpwm;
 	bool cur_pwr;
+	int ret;
 
 	if (rtw_chip_wcpu_11ac(rtwdev)) {
 		rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr);
@@ -270,8 +271,9 @@
 		return -EALREADY;
 
 	pwr_seq = pwr_on ? chip->pwr_on_seq : chip->pwr_off_seq;
-	if (rtw_pwr_seq_parser(rtwdev, pwr_seq))
-		return -EINVAL;
+	ret = rtw_pwr_seq_parser(rtwdev, pwr_seq);
+	if (ret)
+		return ret;
 
 	return 0;
 }
diff --git a/kernel/drivers/net/wireless/rndis_wlan.c b/kernel/drivers/net/wireless/rndis_wlan.c
index 75b5d54..dc076d8 100644
--- a/kernel/drivers/net/wireless/rndis_wlan.c
+++ b/kernel/drivers/net/wireless/rndis_wlan.c
@@ -694,8 +694,8 @@
 		struct rndis_query	*get;
 		struct rndis_query_c	*get_c;
 	} u;
-	int ret, buflen;
-	int resplen, respoffs, copylen;
+	int ret;
+	size_t buflen, resplen, respoffs, copylen;
 
 	buflen = *len + sizeof(*u.get);
 	if (buflen < CONTROL_BUFFER_SIZE)
@@ -730,22 +730,15 @@
 
 		if (respoffs > buflen) {
 			/* Device returned data offset outside buffer, error. */
-			netdev_dbg(dev->net, "%s(%s): received invalid "
-				"data offset: %d > %d\n", __func__,
-				oid_to_string(oid), respoffs, buflen);
+			netdev_dbg(dev->net,
+				   "%s(%s): received invalid data offset: %zu > %zu\n",
+				   __func__, oid_to_string(oid), respoffs, buflen);
 
 			ret = -EINVAL;
 			goto exit_unlock;
 		}
 
-		if ((resplen + respoffs) > buflen) {
-			/* Device would have returned more data if buffer would
-			 * have been big enough. Copy just the bits that we got.
-			 */
-			copylen = buflen - respoffs;
-		} else {
-			copylen = resplen;
-		}
+		copylen = min(resplen, buflen - respoffs);
 
 		if (copylen > *len)
 			copylen = *len;
diff --git a/kernel/drivers/net/wireless/rsi/rsi_91x_coex.c b/kernel/drivers/net/wireless/rsi/rsi_91x_coex.c
index a0c5d02..7395359 100644
--- a/kernel/drivers/net/wireless/rsi/rsi_91x_coex.c
+++ b/kernel/drivers/net/wireless/rsi/rsi_91x_coex.c
@@ -160,6 +160,7 @@
 			       rsi_coex_scheduler_thread,
 			       "Coex-Tx-Thread")) {
 		rsi_dbg(ERR_ZONE, "%s: Unable to init tx thrd\n", __func__);
+		kfree(coex_cb);
 		return -EINVAL;
 	}
 	return 0;
diff --git a/kernel/drivers/net/wireless/rsi/rsi_91x_core.c b/kernel/drivers/net/wireless/rsi/rsi_91x_core.c
index 9c4c585..b7fa038 100644
--- a/kernel/drivers/net/wireless/rsi/rsi_91x_core.c
+++ b/kernel/drivers/net/wireless/rsi/rsi_91x_core.c
@@ -466,7 +466,9 @@
 							      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/kernel/drivers/net/wireless/rsi/rsi_91x_hal.c b/kernel/drivers/net/wireless/rsi/rsi_91x_hal.c
index dca81a4..30d2ecc 100644
--- a/kernel/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/kernel/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -162,11 +162,15 @@
 	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)) {
@@ -231,7 +235,7 @@
 		}
 	}
 
-	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);
diff --git a/kernel/drivers/net/wireless/rsi/rsi_91x_sdio.c b/kernel/drivers/net/wireless/rsi/rsi_91x_sdio.c
index 8108f94..b1d3aea 100644
--- a/kernel/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/kernel/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -1463,10 +1463,8 @@
 
 	rsi_dbg(ERR_ZONE, "SDIO Bus shutdown =====>\n");
 
-	if (hw) {
-		struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config;
-
-		if (rsi_config_wowlan(adapter, wowlan))
+	if (hw && hw->wiphy && hw->wiphy->wowlan_config) {
+		if (rsi_config_wowlan(adapter, hw->wiphy->wowlan_config))
 			rsi_dbg(ERR_ZONE, "Failed to configure WoWLAN\n");
 	}
 
@@ -1480,9 +1478,6 @@
 
 	if (sdev->write_fail)
 		rsi_dbg(INFO_ZONE, "###### Device is not ready #######\n");
-
-	if (rsi_set_sdio_pm_caps(adapter))
-		rsi_dbg(INFO_ZONE, "Setting power management caps failed\n");
 
 	rsi_dbg(INFO_ZONE, "***** RSI module shut down *****\n");
 }
diff --git a/kernel/drivers/net/wireless/wl3501_cs.c b/kernel/drivers/net/wireless/wl3501_cs.c
index ff1701a..4c408fd 100644
--- a/kernel/drivers/net/wireless/wl3501_cs.c
+++ b/kernel/drivers/net/wireless/wl3501_cs.c
@@ -134,7 +134,7 @@
 
 /**
  * iw_valid_channel - validate channel in regulatory domain
- * @reg_comain: regulatory domain
+ * @reg_domain: regulatory domain
  * @channel: channel to validate
  *
  * Returns 0 if invalid in the specified regulatory domain, non-zero if valid.
@@ -458,11 +458,9 @@
 /**
  * wl3501_send_pkt - Send a packet.
  * @this: Card
- *
- * Send a packet.
- *
- * data = Ethernet raw frame.  (e.g. data[0] - data[5] is Dest MAC Addr,
+ * @data: Ethernet raw frame.  (e.g. data[0] - data[5] is Dest MAC Addr,
  *                                   data[6] - data[11] is Src MAC Addr)
+ * @len: Packet length
  * Ref: IEEE 802.11
  */
 static int wl3501_send_pkt(struct wl3501_card *this, u8 *data, u16 len)
@@ -1330,7 +1328,7 @@
 	} else {
 		++dev->stats.tx_packets;
 		dev->stats.tx_bytes += skb->len;
-		kfree_skb(skb);
+		dev_kfree_skb_irq(skb);
 
 		if (this->tx_buffer_cnt < 2)
 			netif_stop_queue(dev);
@@ -1864,6 +1862,7 @@
 {
 	struct net_device *dev;
 	struct wl3501_card *this;
+	int ret;
 
 	/* The io structure describes IO port mapping */
 	p_dev->resource[0]->end	= 16;
@@ -1875,8 +1874,7 @@
 
 	dev = alloc_etherdev(sizeof(struct wl3501_card));
 	if (!dev)
-		goto out_link;
-
+		return -ENOMEM;
 
 	dev->netdev_ops		= &wl3501_netdev_ops;
 	dev->watchdog_timeo	= 5 * HZ;
@@ -1889,9 +1887,15 @@
 	netif_stop_queue(dev);
 	p_dev->priv = dev;
 
-	return wl3501_config(p_dev);
-out_link:
-	return -ENOMEM;
+	ret = wl3501_config(p_dev);
+	if (ret)
+		goto out_free_etherdev;
+
+	return 0;
+
+out_free_etherdev:
+	free_netdev(dev);
+	return ret;
 }
 
 static int wl3501_config(struct pcmcia_device *link)
@@ -1947,8 +1951,7 @@
 		goto failed;
 	}
 
-	for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = ((char *)&this->mac_addr)[i];
+	eth_hw_addr_set(dev, this->mac_addr);
 
 	/* print probe information */
 	printk(KERN_INFO "%s: wl3501 @ 0x%3.3x, IRQ %d, "
diff --git a/kernel/drivers/net/xen-netback/common.h b/kernel/drivers/net/xen-netback/common.h
index 1ba9749..fe99439 100644
--- a/kernel/drivers/net/xen-netback/common.h
+++ b/kernel/drivers/net/xen-netback/common.h
@@ -166,7 +166,7 @@
 	struct pending_tx_info pending_tx_info[MAX_PENDING_REQS];
 	grant_handle_t grant_tx_handle[MAX_PENDING_REQS];
 
-	struct gnttab_copy tx_copy_ops[MAX_PENDING_REQS];
+	struct gnttab_copy tx_copy_ops[2 * MAX_PENDING_REQS];
 	struct gnttab_map_grant_ref tx_map_ops[MAX_PENDING_REQS];
 	struct gnttab_unmap_grant_ref tx_unmap_ops[MAX_PENDING_REQS];
 	/* passed to gnttab_[un]map_refs with pages under (un)mapping */
diff --git a/kernel/drivers/net/xen-netback/netback.c b/kernel/drivers/net/xen-netback/netback.c
index f9373a8..1c366dd 100644
--- a/kernel/drivers/net/xen-netback/netback.c
+++ b/kernel/drivers/net/xen-netback/netback.c
@@ -334,6 +334,7 @@
 struct xenvif_tx_cb {
 	u16 copy_pending_idx[XEN_NETBK_LEGACY_SLOTS_MAX + 1];
 	u8 copy_count;
+	u32 split_mask;
 };
 
 #define XENVIF_TX_CB(skb) ((struct xenvif_tx_cb *)(skb)->cb)
@@ -361,6 +362,8 @@
 	struct sk_buff *skb =
 		alloc_skb(size + NET_SKB_PAD + NET_IP_ALIGN,
 			  GFP_ATOMIC | __GFP_NOWARN);
+
+	BUILD_BUG_ON(sizeof(*XENVIF_TX_CB(skb)) > sizeof(skb->cb));
 	if (unlikely(skb == NULL))
 		return NULL;
 
@@ -393,14 +396,16 @@
 	struct gnttab_map_grant_ref *gop = queue->tx_map_ops + *map_ops;
 	struct xen_netif_tx_request *txp = first;
 
-	nr_slots = shinfo->nr_frags + 1;
+	nr_slots = shinfo->nr_frags + frag_overflow + 1;
 
 	copy_count(skb) = 0;
+	XENVIF_TX_CB(skb)->split_mask = 0;
 
 	/* Create copy ops for exactly data_len bytes into the skb head. */
 	__skb_put(skb, data_len);
 	while (data_len > 0) {
 		int amount = data_len > txp->size ? txp->size : data_len;
+		bool split = false;
 
 		cop->source.u.ref = txp->gref;
 		cop->source.domid = queue->vif->domid;
@@ -413,6 +418,13 @@
 		cop->dest.u.gmfn = virt_to_gfn(skb->data + skb_headlen(skb)
 				               - data_len);
 
+		/* Don't cross local page boundary! */
+		if (cop->dest.offset + amount > XEN_PAGE_SIZE) {
+			amount = XEN_PAGE_SIZE - cop->dest.offset;
+			XENVIF_TX_CB(skb)->split_mask |= 1U << copy_count(skb);
+			split = true;
+		}
+
 		cop->len = amount;
 		cop->flags = GNTCOPY_source_gref;
 
@@ -420,7 +432,8 @@
 		pending_idx = queue->pending_ring[index];
 		callback_param(queue, pending_idx).ctx = NULL;
 		copy_pending_idx(skb, copy_count(skb)) = pending_idx;
-		copy_count(skb)++;
+		if (!split)
+			copy_count(skb)++;
 
 		cop++;
 		data_len -= amount;
@@ -441,15 +454,16 @@
 			nr_slots--;
 		} else {
 			/* The copy op partially covered the tx_request.
-			 * The remainder will be mapped.
+			 * The remainder will be mapped or copied in the next
+			 * iteration.
 			 */
 			txp->offset += amount;
 			txp->size -= amount;
 		}
 	}
 
-	for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots;
-	     shinfo->nr_frags++, gop++) {
+	for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS;
+	     shinfo->nr_frags++, gop++, nr_slots--) {
 		index = pending_index(queue->pending_cons++);
 		pending_idx = queue->pending_ring[index];
 		xenvif_tx_create_map_op(queue, pending_idx, txp,
@@ -462,12 +476,12 @@
 			txp++;
 	}
 
-	if (frag_overflow) {
+	if (nr_slots > 0) {
 
 		shinfo = skb_shinfo(nskb);
 		frags = shinfo->frags;
 
-		for (shinfo->nr_frags = 0; shinfo->nr_frags < frag_overflow;
+		for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots;
 		     shinfo->nr_frags++, txp++, gop++) {
 			index = pending_index(queue->pending_cons++);
 			pending_idx = queue->pending_ring[index];
@@ -478,6 +492,11 @@
 		}
 
 		skb_shinfo(skb)->frag_list = nskb;
+	} else if (nskb) {
+		/* A frag_list skb was allocated but it is no longer needed
+		 * because enough slots were converted to copy ops above.
+		 */
+		kfree_skb(nskb);
 	}
 
 	(*copy_ops) = cop - queue->tx_copy_ops;
@@ -539,6 +558,13 @@
 		pending_idx = copy_pending_idx(skb, i);
 
 		newerr = (*gopp_copy)->status;
+
+		/* Split copies need to be handled together. */
+		if (XENVIF_TX_CB(skb)->split_mask & (1U << i)) {
+			(*gopp_copy)++;
+			if (!newerr)
+				newerr = (*gopp_copy)->status;
+		}
 		if (likely(!newerr)) {
 			/* The first frag might still have this slot mapped */
 			if (i < copy_count(skb) - 1 || !sharedslot)
@@ -975,10 +1001,8 @@
 
 		/* No crossing a page as the payload mustn't fragment. */
 		if (unlikely((txreq.offset + txreq.size) > XEN_PAGE_SIZE)) {
-			netdev_err(queue->vif->dev,
-				   "txreq.offset: %u, size: %u, end: %lu\n",
-				   txreq.offset, txreq.size,
-				   (unsigned long)(txreq.offset&~XEN_PAGE_MASK) + txreq.size);
+			netdev_err(queue->vif->dev, "Cross page boundary, txreq.offset: %u, size: %u\n",
+				   txreq.offset, txreq.size);
 			xenvif_fatal_tx_err(queue->vif);
 			break;
 		}
diff --git a/kernel/drivers/nfc/fdp/i2c.c b/kernel/drivers/nfc/fdp/i2c.c
index 5e30078..808d730 100644
--- a/kernel/drivers/nfc/fdp/i2c.c
+++ b/kernel/drivers/nfc/fdp/i2c.c
@@ -249,6 +249,9 @@
 					   len, sizeof(**fw_vsc_cfg),
 					   GFP_KERNEL);
 
+		if (!*fw_vsc_cfg)
+			goto alloc_err;
+
 		r = device_property_read_u8_array(dev, FDP_DP_FW_VSC_CFG_NAME,
 						  *fw_vsc_cfg, len);
 
@@ -262,6 +265,7 @@
 		*fw_vsc_cfg = NULL;
 	}
 
+alloc_err:
 	dev_dbg(dev, "Clock type: %d, clock frequency: %d, VSC: %s",
 		*clock_type, *clock_freq, *fw_vsc_cfg != NULL ? "yes" : "no");
 }
diff --git a/kernel/drivers/nfc/nfcsim.c b/kernel/drivers/nfc/nfcsim.c
index dd27c85..b42d386 100644
--- a/kernel/drivers/nfc/nfcsim.c
+++ b/kernel/drivers/nfc/nfcsim.c
@@ -336,10 +336,6 @@
 static void nfcsim_debugfs_init(void)
 {
 	nfcsim_debugfs_root = debugfs_create_dir("nfcsim", NULL);
-
-	if (!nfcsim_debugfs_root)
-		pr_err("Could not create debugfs entry\n");
-
 }
 
 static void nfcsim_debugfs_remove(void)
diff --git a/kernel/drivers/nfc/pn533/pn533.c b/kernel/drivers/nfc/pn533/pn533.c
index 8d7e29d..87e1296 100644
--- a/kernel/drivers/nfc/pn533/pn533.c
+++ b/kernel/drivers/nfc/pn533/pn533.c
@@ -1319,6 +1319,8 @@
 	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 @@
 
 		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);
diff --git a/kernel/drivers/nfc/pn533/usb.c b/kernel/drivers/nfc/pn533/usb.c
index 84f2983..68eb125 100644
--- a/kernel/drivers/nfc/pn533/usb.c
+++ b/kernel/drivers/nfc/pn533/usb.c
@@ -153,10 +153,17 @@
 	return usb_submit_urb(phy->ack_urb, flags);
 }
 
+struct pn533_out_arg {
+	struct pn533_usb_phy *phy;
+	struct completion done;
+};
+
 static int pn533_usb_send_frame(struct pn533 *dev,
 				struct sk_buff *out)
 {
 	struct pn533_usb_phy *phy = dev->phy;
+	struct pn533_out_arg arg;
+	void *cntx;
 	int rc;
 
 	if (phy->priv == NULL)
@@ -168,9 +175,17 @@
 	print_hex_dump_debug("PN533 TX: ", DUMP_PREFIX_NONE, 16, 1,
 			     out->data, out->len, false);
 
+	arg.phy = phy;
+	init_completion(&arg.done);
+	cntx = phy->out_urb->context;
+	phy->out_urb->context = &arg;
+
 	rc = usb_submit_urb(phy->out_urb, GFP_KERNEL);
 	if (rc)
 		return rc;
+
+	wait_for_completion(&arg.done);
+	phy->out_urb->context = cntx;
 
 	if (dev->protocol_type == PN533_PROTO_REQ_RESP) {
 		/* request for response for sent packet directly */
@@ -412,7 +427,31 @@
 	return arg.rc;
 }
 
-static void pn533_send_complete(struct urb *urb)
+static void pn533_out_complete(struct urb *urb)
+{
+	struct pn533_out_arg *arg = urb->context;
+	struct pn533_usb_phy *phy = arg->phy;
+
+	switch (urb->status) {
+	case 0:
+		break; /* success */
+	case -ECONNRESET:
+	case -ENOENT:
+		dev_dbg(&phy->udev->dev,
+			"The urb has been stopped (status %d)\n",
+			urb->status);
+		break;
+	case -ESHUTDOWN:
+	default:
+		nfc_err(&phy->udev->dev,
+			"Urb failure (status %d)\n",
+			urb->status);
+	}
+
+	complete(&arg->done);
+}
+
+static void pn533_ack_complete(struct urb *urb)
 {
 	struct pn533_usb_phy *phy = urb->context;
 
@@ -500,10 +539,10 @@
 
 	usb_fill_bulk_urb(phy->out_urb, phy->udev,
 			  usb_sndbulkpipe(phy->udev, out_endpoint),
-			  NULL, 0, pn533_send_complete, phy);
+			  NULL, 0, pn533_out_complete, phy);
 	usb_fill_bulk_urb(phy->ack_urb, phy->udev,
 			  usb_sndbulkpipe(phy->udev, out_endpoint),
-			  NULL, 0, pn533_send_complete, phy);
+			  NULL, 0, pn533_ack_complete, phy);
 
 	switch (id->driver_info) {
 	case PN533_DEVICE_STD:
diff --git a/kernel/drivers/nfc/st-nci/ndlc.c b/kernel/drivers/nfc/st-nci/ndlc.c
index 5d74c67..8ccf5a8 100644
--- a/kernel/drivers/nfc/st-nci/ndlc.c
+++ b/kernel/drivers/nfc/st-nci/ndlc.c
@@ -286,13 +286,15 @@
 
 void ndlc_remove(struct llt_ndlc *ndlc)
 {
-	st_nci_remove(ndlc->ndev);
-
 	/* cancel timers */
 	del_timer_sync(&ndlc->t1_timer);
 	del_timer_sync(&ndlc->t2_timer);
 	ndlc->t2_active = false;
 	ndlc->t1_active = false;
+	/* cancel work */
+	cancel_work_sync(&ndlc->sm_work);
+
+	st_nci_remove(ndlc->ndev);
 
 	skb_queue_purge(&ndlc->rcv_q);
 	skb_queue_purge(&ndlc->send_q);
diff --git a/kernel/drivers/nfc/st-nci/se.c b/kernel/drivers/nfc/st-nci/se.c
index 37d397a..a14afce 100644
--- a/kernel/drivers/nfc/st-nci/se.c
+++ b/kernel/drivers/nfc/st-nci/se.c
@@ -664,6 +664,12 @@
 					ST_NCI_EVT_TRANSMIT_DATA, apdu,
 					apdu_length);
 	default:
+		/* Need to free cb_context here as at the moment we can't
+		 * clearly indicate to the caller if the callback function
+		 * would be called (and free it) or not. In both cases a
+		 * negative value may be returned to the caller.
+		 */
+		kfree(cb_context);
 		return -ENODEV;
 	}
 }
diff --git a/kernel/drivers/nfc/st21nfca/se.c b/kernel/drivers/nfc/st21nfca/se.c
index d416365..6a1d3b2 100644
--- a/kernel/drivers/nfc/st21nfca/se.c
+++ b/kernel/drivers/nfc/st21nfca/se.c
@@ -236,6 +236,12 @@
 					ST21NFCA_EVT_TRANSMIT_DATA,
 					apdu, apdu_length);
 	default:
+		/* Need to free cb_context here as at the moment we can't
+		 * clearly indicate to the caller if the callback function
+		 * would be called (and free it) or not. In both cases a
+		 * negative value may be returned to the caller.
+		 */
+		kfree(cb_context);
 		return -ENODEV;
 	}
 }
diff --git a/kernel/drivers/ntb/hw/amd/ntb_hw_amd.c b/kernel/drivers/ntb/hw/amd/ntb_hw_amd.c
index 71428d8..ac401ad 100644
--- a/kernel/drivers/ntb/hw/amd/ntb_hw_amd.c
+++ b/kernel/drivers/ntb/hw/amd/ntb_hw_amd.c
@@ -1344,12 +1344,17 @@
 
 static int __init amd_ntb_pci_driver_init(void)
 {
+	int ret;
 	pr_info("%s %s\n", NTB_DESC, NTB_VER);
 
 	if (debugfs_initialized())
 		debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
 
-	return pci_register_driver(&amd_ntb_pci_driver);
+	ret = pci_register_driver(&amd_ntb_pci_driver);
+	if (ret)
+		debugfs_remove_recursive(debugfs_dir);
+
+	return ret;
 }
 module_init(amd_ntb_pci_driver_init);
 
diff --git a/kernel/drivers/ntb/hw/idt/ntb_hw_idt.c b/kernel/drivers/ntb/hw/idt/ntb_hw_idt.c
index d54261f..99711dd 100644
--- a/kernel/drivers/ntb/hw/idt/ntb_hw_idt.c
+++ b/kernel/drivers/ntb/hw/idt/ntb_hw_idt.c
@@ -2902,6 +2902,7 @@
 
 static int __init idt_pci_driver_init(void)
 {
+	int ret;
 	pr_info("%s %s\n", NTB_DESC, NTB_VER);
 
 	/* Create the top DebugFS directory if the FS is initialized */
@@ -2909,7 +2910,11 @@
 		dbgfs_topdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
 
 	/* Register the NTB hardware driver to handle the PCI device */
-	return pci_register_driver(&idt_pci_driver);
+	ret = pci_register_driver(&idt_pci_driver);
+	if (ret)
+		debugfs_remove_recursive(dbgfs_topdir);
+
+	return ret;
 }
 module_init(idt_pci_driver_init);
 
diff --git a/kernel/drivers/ntb/hw/intel/ntb_hw_gen1.c b/kernel/drivers/ntb/hw/intel/ntb_hw_gen1.c
index 093dd20..4f1add5 100644
--- a/kernel/drivers/ntb/hw/intel/ntb_hw_gen1.c
+++ b/kernel/drivers/ntb/hw/intel/ntb_hw_gen1.c
@@ -2068,12 +2068,17 @@
 
 static int __init intel_ntb_pci_driver_init(void)
 {
+	int ret;
 	pr_info("%s %s\n", NTB_DESC, NTB_VER);
 
 	if (debugfs_initialized())
 		debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
 
-	return pci_register_driver(&intel_ntb_pci_driver);
+	ret = pci_register_driver(&intel_ntb_pci_driver);
+	if (ret)
+		debugfs_remove_recursive(debugfs_dir);
+
+	return ret;
 }
 module_init(intel_ntb_pci_driver_init);
 
diff --git a/kernel/drivers/ntb/ntb_transport.c b/kernel/drivers/ntb/ntb_transport.c
index 4a02561..8595700 100644
--- a/kernel/drivers/ntb/ntb_transport.c
+++ b/kernel/drivers/ntb/ntb_transport.c
@@ -412,7 +412,7 @@
 
 		rc = device_register(dev);
 		if (rc) {
-			kfree(client_dev);
+			put_device(dev);
 			goto err;
 		}
 
@@ -911,7 +911,7 @@
 	return 0;
 }
 
-static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp)
+static void ntb_qp_link_context_reset(struct ntb_transport_qp *qp)
 {
 	qp->link_is_up = false;
 	qp->active = false;
@@ -932,6 +932,13 @@
 	qp->tx_err_no_buf = 0;
 	qp->tx_memcpy = 0;
 	qp->tx_async = 0;
+}
+
+static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp)
+{
+	ntb_qp_link_context_reset(qp);
+	if (qp->remote_rx_info)
+		qp->remote_rx_info->entry = qp->rx_max_entry - 1;
 }
 
 static void ntb_qp_link_cleanup(struct ntb_transport_qp *qp)
@@ -1176,7 +1183,7 @@
 	qp->ndev = nt->ndev;
 	qp->client_ready = false;
 	qp->event_handler = NULL;
-	ntb_qp_link_down_reset(qp);
+	ntb_qp_link_context_reset(qp);
 
 	if (mw_num < qp_count % mw_count)
 		num_qps_mw = qp_count / mw_count + 1;
@@ -2278,8 +2285,12 @@
 	struct ntb_queue_entry *entry;
 	int rc;
 
-	if (!qp || !qp->link_is_up || !len)
+	if (!qp || !len)
 		return -EINVAL;
+
+	/* If the qp link is down already, just ignore. */
+	if (!qp->link_is_up)
+		return 0;
 
 	entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q);
 	if (!entry) {
@@ -2420,7 +2431,7 @@
 	unsigned int head = qp->tx_index;
 	unsigned int tail = qp->remote_rx_info->entry;
 
-	return tail > head ? tail - head : qp->tx_max_entry + tail - head;
+	return tail >= head ? tail - head : qp->tx_max_entry + tail - head;
 }
 EXPORT_SYMBOL_GPL(ntb_transport_tx_free_entry);
 
diff --git a/kernel/drivers/nubus/proc.c b/kernel/drivers/nubus/proc.c
index 88e1f9a..78cf0e7 100644
--- a/kernel/drivers/nubus/proc.c
+++ b/kernel/drivers/nubus/proc.c
@@ -137,6 +137,18 @@
 	return 0;
 }
 
+static int nubus_rsrc_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, nubus_proc_rsrc_show, inode);
+}
+
+static const struct proc_ops nubus_rsrc_proc_ops = {
+	.proc_open	= nubus_rsrc_proc_open,
+	.proc_read	= seq_read,
+	.proc_lseek	= seq_lseek,
+	.proc_release	= single_release,
+};
+
 void nubus_proc_add_rsrc_mem(struct proc_dir_entry *procdir,
 			     const struct nubus_dirent *ent,
 			     unsigned int size)
@@ -152,8 +164,8 @@
 		pde_data = nubus_proc_alloc_pde_data(nubus_dirptr(ent), size);
 	else
 		pde_data = NULL;
-	proc_create_single_data(name, S_IFREG | 0444, procdir,
-			nubus_proc_rsrc_show, pde_data);
+	proc_create_data(name, S_IFREG | 0444, procdir,
+			 &nubus_rsrc_proc_ops, pde_data);
 }
 
 void nubus_proc_add_rsrc(struct proc_dir_entry *procdir,
@@ -166,9 +178,9 @@
 		return;
 
 	snprintf(name, sizeof(name), "%x", ent->type);
-	proc_create_single_data(name, S_IFREG | 0444, procdir,
-			nubus_proc_rsrc_show,
-			nubus_proc_alloc_pde_data(data, 0));
+	proc_create_data(name, S_IFREG | 0444, procdir,
+			 &nubus_rsrc_proc_ops,
+			 nubus_proc_alloc_pde_data(data, 0));
 }
 
 /*
diff --git a/kernel/drivers/nvme/host/core.c b/kernel/drivers/nvme/host/core.c
index e162f1d..07c41a1 100644
--- a/kernel/drivers/nvme/host/core.c
+++ b/kernel/drivers/nvme/host/core.c
@@ -723,16 +723,26 @@
 		range = page_address(ns->ctrl->discard_page);
 	}
 
-	__rq_for_each_bio(bio, req) {
-		u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector);
-		u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift;
+	if (queue_max_discard_segments(req->q) == 1) {
+		u64 slba = nvme_sect_to_lba(ns, blk_rq_pos(req));
+		u32 nlb = blk_rq_sectors(req) >> (ns->lba_shift - 9);
 
-		if (n < segments) {
-			range[n].cattr = cpu_to_le32(0);
-			range[n].nlb = cpu_to_le32(nlb);
-			range[n].slba = cpu_to_le64(slba);
+		range[0].cattr = cpu_to_le32(0);
+		range[0].nlb = cpu_to_le32(nlb);
+		range[0].slba = cpu_to_le64(slba);
+		n = 1;
+	} else {
+		__rq_for_each_bio(bio, req) {
+			u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector);
+			u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift;
+
+			if (n < segments) {
+				range[n].cattr = cpu_to_le32(0);
+				range[n].nlb = cpu_to_le32(nlb);
+				range[n].slba = cpu_to_le64(slba);
+			}
+			n++;
 		}
-		n++;
 	}
 
 	if (WARN_ON_ONCE(n != segments)) {
@@ -4406,11 +4416,19 @@
 	nvme_get_fw_slot_info(ctrl);
 }
 
+static u32 nvme_aer_type(u32 result)
+{
+	return result & 0x7;
+}
+
+static u32 nvme_aer_subtype(u32 result)
+{
+	return (result & 0xff00) >> 8;
+}
+
 static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
 {
-	u32 aer_notice_type = (result & 0xff00) >> 8;
-
-	trace_nvme_async_event(ctrl, aer_notice_type);
+	u32 aer_notice_type = nvme_aer_subtype(result);
 
 	switch (aer_notice_type) {
 	case NVME_AER_NOTICE_NS_CHANGED:
@@ -4441,24 +4459,40 @@
 	}
 }
 
+static void nvme_handle_aer_persistent_error(struct nvme_ctrl *ctrl)
+{
+	dev_warn(ctrl->device, "resetting controller due to AER\n");
+	nvme_reset_ctrl(ctrl);
+}
+
 void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status,
 		volatile union nvme_result *res)
 {
 	u32 result = le32_to_cpu(res->u32);
-	u32 aer_type = result & 0x07;
+	u32 aer_type = nvme_aer_type(result);
+	u32 aer_subtype = nvme_aer_subtype(result);
 
 	if (le16_to_cpu(status) >> 1 != NVME_SC_SUCCESS)
 		return;
 
+	trace_nvme_async_event(ctrl, result);
 	switch (aer_type) {
 	case NVME_AER_NOTICE:
 		nvme_handle_aen_notice(ctrl, result);
 		break;
 	case NVME_AER_ERROR:
+		/*
+		 * For a persistent internal error, don't run async_event_work
+		 * to submit a new AER. The controller reset will do it.
+		 */
+		if (aer_subtype == NVME_AER_ERROR_PERSIST_INT_ERR) {
+			nvme_handle_aer_persistent_error(ctrl);
+			return;
+		}
+		fallthrough;
 	case NVME_AER_SMART:
 	case NVME_AER_CSS:
 	case NVME_AER_VS:
-		trace_nvme_async_event(ctrl, aer_type);
 		ctrl->aen_result = result;
 		break;
 	default:
diff --git a/kernel/drivers/nvme/host/nvme.h b/kernel/drivers/nvme/host/nvme.h
index 9324a38..18306d4 100644
--- a/kernel/drivers/nvme/host/nvme.h
+++ b/kernel/drivers/nvme/host/nvme.h
@@ -754,7 +754,7 @@
 {
 	struct nvme_ns *ns = req->q->queuedata;
 
-	if (req->cmd_flags & REQ_NVME_MPATH)
+	if ((req->cmd_flags & REQ_NVME_MPATH) && req->bio)
 		trace_block_bio_complete(ns->head->disk->queue, req->bio);
 }
 
diff --git a/kernel/drivers/nvme/host/pci.c b/kernel/drivers/nvme/host/pci.c
index 0cefbe9..7afdab8 100644
--- a/kernel/drivers/nvme/host/pci.c
+++ b/kernel/drivers/nvme/host/pci.c
@@ -33,7 +33,7 @@
 #define SQ_SIZE(q)	((q)->q_depth << (q)->sqes)
 #define CQ_SIZE(q)	((q)->q_depth * sizeof(struct nvme_completion))
 
-#define SGES_PER_PAGE	(PAGE_SIZE / sizeof(struct nvme_sgl_desc))
+#define SGES_PER_PAGE	(NVME_CTRL_PAGE_SIZE / sizeof(struct nvme_sgl_desc))
 
 /*
  * These can be higher, but we need to ensure that any command doesn't
@@ -139,9 +139,9 @@
 	mempool_t *iod_mempool;
 
 	/* shadow doorbell buffer support: */
-	u32 *dbbuf_dbs;
+	__le32 *dbbuf_dbs;
 	dma_addr_t dbbuf_dbs_dma_addr;
-	u32 *dbbuf_eis;
+	__le32 *dbbuf_eis;
 	dma_addr_t dbbuf_eis_dma_addr;
 
 	/* host memory buffer support: */
@@ -209,10 +209,10 @@
 #define NVMEQ_SQ_CMB		1
 #define NVMEQ_DELETE_ERROR	2
 #define NVMEQ_POLLED		3
-	u32 *dbbuf_sq_db;
-	u32 *dbbuf_cq_db;
-	u32 *dbbuf_sq_ei;
-	u32 *dbbuf_cq_ei;
+	__le32 *dbbuf_sq_db;
+	__le32 *dbbuf_cq_db;
+	__le32 *dbbuf_sq_ei;
+	__le32 *dbbuf_cq_ei;
 	struct completion delete_done;
 };
 
@@ -334,11 +334,11 @@
 }
 
 /* Update dbbuf and return true if an MMIO is required */
-static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
-					      volatile u32 *dbbuf_ei)
+static bool nvme_dbbuf_update_and_check_event(u16 value, __le32 *dbbuf_db,
+					      volatile __le32 *dbbuf_ei)
 {
 	if (dbbuf_db) {
-		u16 old_value;
+		u16 old_value, event_idx;
 
 		/*
 		 * Ensure that the queue is written before updating
@@ -346,8 +346,8 @@
 		 */
 		wmb();
 
-		old_value = *dbbuf_db;
-		*dbbuf_db = value;
+		old_value = le32_to_cpu(*dbbuf_db);
+		*dbbuf_db = cpu_to_le32(value);
 
 		/*
 		 * Ensure that the doorbell is updated before reading the event
@@ -357,7 +357,8 @@
 		 */
 		mb();
 
-		if (!nvme_dbbuf_need_event(*dbbuf_ei, value, old_value))
+		event_idx = le32_to_cpu(*dbbuf_ei);
+		if (!nvme_dbbuf_need_event(event_idx, value, old_value))
 			return false;
 	}
 
@@ -371,9 +372,9 @@
  */
 static int nvme_pci_npages_prp(void)
 {
-	unsigned nprps = DIV_ROUND_UP(NVME_MAX_KB_SZ + NVME_CTRL_PAGE_SIZE,
-				      NVME_CTRL_PAGE_SIZE);
-	return DIV_ROUND_UP(8 * nprps, PAGE_SIZE - 8);
+	unsigned max_bytes = (NVME_MAX_KB_SZ * 1024) + NVME_CTRL_PAGE_SIZE;
+	unsigned nprps = DIV_ROUND_UP(max_bytes, NVME_CTRL_PAGE_SIZE);
+	return DIV_ROUND_UP(8 * nprps, NVME_CTRL_PAGE_SIZE - 8);
 }
 
 /*
@@ -383,15 +384,7 @@
 static int nvme_pci_npages_sgl(void)
 {
 	return DIV_ROUND_UP(NVME_MAX_SEGS * sizeof(struct nvme_sgl_desc),
-			PAGE_SIZE);
-}
-
-static size_t nvme_pci_iod_alloc_size(void)
-{
-	size_t npages = max(nvme_pci_npages_prp(), nvme_pci_npages_sgl());
-
-	return sizeof(__le64 *) * npages +
-		sizeof(struct scatterlist) * NVME_MAX_SEGS;
+			NVME_CTRL_PAGE_SIZE);
 }
 
 static int nvme_admin_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
@@ -734,7 +727,7 @@
 		sge->length = cpu_to_le32(entries * sizeof(*sge));
 		sge->type = NVME_SGL_FMT_LAST_SEG_DESC << 4;
 	} else {
-		sge->length = cpu_to_le32(PAGE_SIZE);
+		sge->length = cpu_to_le32(NVME_CTRL_PAGE_SIZE);
 		sge->type = NVME_SGL_FMT_SEG_DESC << 4;
 	}
 }
@@ -967,7 +960,8 @@
 
 	if (blk_integrity_rq(req))
 		dma_unmap_page(dev->dev, iod->meta_dma,
-			       rq_integrity_vec(req)->bv_len, rq_data_dir(req));
+			       rq_integrity_vec(req)->bv_len, rq_dma_dir(req));
+
 	if (blk_rq_nr_phys_segments(req))
 		nvme_unmap_data(dev, req);
 	nvme_complete_rq(req);
@@ -1291,7 +1285,7 @@
 	else
 		nvme_poll_irqdisable(nvmeq);
 
-	if (blk_mq_request_completed(req)) {
+	if (blk_mq_rq_state(req) != MQ_RQ_IN_FLIGHT) {
 		dev_warn(dev->ctrl.device,
 			 "I/O %d QID %d timeout, completion polled\n",
 			 req->tag, nvmeq->qid);
@@ -2558,6 +2552,22 @@
 	dma_pool_destroy(dev->prp_small_pool);
 }
 
+static int nvme_pci_alloc_iod_mempool(struct nvme_dev *dev)
+{
+	size_t npages = max(nvme_pci_npages_prp(), nvme_pci_npages_sgl());
+	size_t alloc_size = sizeof(__le64 *) * npages +
+			    sizeof(struct scatterlist) * NVME_MAX_SEGS;
+
+	WARN_ON_ONCE(alloc_size > PAGE_SIZE);
+	dev->iod_mempool = mempool_create_node(1,
+			mempool_kmalloc, mempool_kfree,
+			(void *)alloc_size, GFP_KERNEL,
+			dev_to_node(dev->dev));
+	if (!dev->iod_mempool)
+		return -ENOMEM;
+	return 0;
+}
+
 static void nvme_free_tagset(struct nvme_dev *dev)
 {
 	if (dev->tagset.tags)
@@ -2565,6 +2575,7 @@
 	dev->ctrl.tagset = NULL;
 }
 
+/* pairs with nvme_pci_alloc_dev */
 static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl)
 {
 	struct nvme_dev *dev = to_nvme_dev(ctrl);
@@ -2841,32 +2852,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_ACPI
-static bool nvme_acpi_storage_d3(struct pci_dev *dev)
-{
-	struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
-	u8 val;
-
-	/*
-	 * Look for _DSD property specifying that the storage device on the port
-	 * must use D3 to support deep platform power savings during
-	 * suspend-to-idle.
-	 */
-
-	if (!adev)
-		return false;
-	if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable",
-			&val))
-		return false;
-	return val == 1;
-}
-#else
-static inline bool nvme_acpi_storage_d3(struct pci_dev *dev)
-{
-	return false;
-}
-#endif /* CONFIG_ACPI */
-
 static void nvme_async_probe(void *data, async_cookie_t cookie)
 {
 	struct nvme_dev *dev = data;
@@ -2876,20 +2861,20 @@
 	nvme_put_ctrl(&dev->ctrl);
 }
 
-static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+static struct nvme_dev *nvme_pci_alloc_dev(struct pci_dev *pdev,
+		const struct pci_device_id *id)
 {
-	int node, result = -ENOMEM;
-	struct nvme_dev *dev;
 	unsigned long quirks = id->driver_data;
-	size_t alloc_size;
-
-	node = dev_to_node(&pdev->dev);
-	if (node == NUMA_NO_NODE)
-		set_dev_node(&pdev->dev, first_memory_node);
+	int node = dev_to_node(&pdev->dev);
+	struct nvme_dev *dev;
+	int ret = -ENOMEM;
 
 	dev = kzalloc_node(sizeof(*dev), GFP_KERNEL, node);
 	if (!dev)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
+	INIT_WORK(&dev->ctrl.reset_work, nvme_reset_work);
+	INIT_WORK(&dev->remove_work, nvme_remove_dead_ctrl_work);
+	mutex_init(&dev->shutdown_lock);
 
 	dev->nr_write_queues = write_queues;
 	dev->nr_poll_queues = poll_queues;
@@ -2897,26 +2882,12 @@
 	dev->queues = kcalloc_node(dev->nr_allocated_queues,
 			sizeof(struct nvme_queue), GFP_KERNEL, node);
 	if (!dev->queues)
-		goto free;
+		goto out_free_dev;
 
 	dev->dev = get_device(&pdev->dev);
-	pci_set_drvdata(pdev, dev);
-
-	result = nvme_dev_map(dev);
-	if (result)
-		goto put_pci;
-
-	INIT_WORK(&dev->ctrl.reset_work, nvme_reset_work);
-	INIT_WORK(&dev->remove_work, nvme_remove_dead_ctrl_work);
-	mutex_init(&dev->shutdown_lock);
-
-	result = nvme_setup_prp_pools(dev);
-	if (result)
-		goto unmap;
 
 	quirks |= check_vendor_combination_bug(pdev);
-
-	if (!noacpi && nvme_acpi_storage_d3(pdev)) {
+	if (!noacpi && acpi_storage_d3(&pdev->dev)) {
 		/*
 		 * Some systems use a bios work around to ask for D3 on
 		 * platforms that support kernel managed suspend.
@@ -2925,46 +2896,54 @@
 			 "platform quirk: setting simple suspend\n");
 		quirks |= NVME_QUIRK_SIMPLE_SUSPEND;
 	}
+	ret = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_pci_ctrl_ops,
+			     quirks);
+	if (ret)
+		goto out_put_device;
+	return dev;
 
-	/*
-	 * Double check that our mempool alloc size will cover the biggest
-	 * command we support.
-	 */
-	alloc_size = nvme_pci_iod_alloc_size();
-	WARN_ON_ONCE(alloc_size > PAGE_SIZE);
+out_put_device:
+	put_device(dev->dev);
+	kfree(dev->queues);
+out_free_dev:
+	kfree(dev);
+	return ERR_PTR(ret);
+}
 
-	dev->iod_mempool = mempool_create_node(1, mempool_kmalloc,
-						mempool_kfree,
-						(void *) alloc_size,
-						GFP_KERNEL, node);
-	if (!dev->iod_mempool) {
-		result = -ENOMEM;
-		goto release_pools;
-	}
+static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct nvme_dev *dev;
+	int result = -ENOMEM;
 
-	result = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_pci_ctrl_ops,
-			quirks);
+	dev = nvme_pci_alloc_dev(pdev, id);
+	if (IS_ERR(dev))
+		return PTR_ERR(dev);
+
+	result = nvme_dev_map(dev);
 	if (result)
-		goto release_mempool;
+		goto out_uninit_ctrl;
+
+	result = nvme_setup_prp_pools(dev);
+	if (result)
+		goto out_dev_unmap;
+
+	result = nvme_pci_alloc_iod_mempool(dev);
+	if (result)
+		goto out_release_prp_pools;
 
 	dev_info(dev->ctrl.device, "pci function %s\n", dev_name(&pdev->dev));
+	pci_set_drvdata(pdev, dev);
 
 	nvme_reset_ctrl(&dev->ctrl);
 	async_schedule(nvme_async_probe, dev);
-
 	return 0;
 
- release_mempool:
-	mempool_destroy(dev->iod_mempool);
- release_pools:
+out_release_prp_pools:
 	nvme_release_prp_pools(dev);
- unmap:
+out_dev_unmap:
 	nvme_dev_unmap(dev);
- put_pci:
-	put_device(dev->dev);
- free:
-	kfree(dev->queues);
-	kfree(dev);
+out_uninit_ctrl:
+	nvme_uninit_ctrl(&dev->ctrl);
 	return result;
 }
 
diff --git a/kernel/drivers/nvme/host/rdma.c b/kernel/drivers/nvme/host/rdma.c
index b619243..825c961 100644
--- a/kernel/drivers/nvme/host/rdma.c
+++ b/kernel/drivers/nvme/host/rdma.c
@@ -989,6 +989,7 @@
 		goto out_cleanup_connect_q;
 
 	if (!new) {
+		nvme_start_freeze(&ctrl->ctrl);
 		nvme_start_queues(&ctrl->ctrl);
 		if (!nvme_wait_freeze_timeout(&ctrl->ctrl, NVME_IO_TIMEOUT)) {
 			/*
@@ -997,6 +998,7 @@
 			 * to be safe.
 			 */
 			ret = -ENODEV;
+			nvme_unfreeze(&ctrl->ctrl);
 			goto out_wait_freeze_timed_out;
 		}
 		blk_mq_update_nr_hw_queues(ctrl->ctrl.tagset,
@@ -1042,7 +1044,6 @@
 		bool remove)
 {
 	if (ctrl->ctrl.queue_count > 1) {
-		nvme_start_freeze(&ctrl->ctrl);
 		nvme_stop_queues(&ctrl->ctrl);
 		nvme_sync_io_queues(&ctrl->ctrl);
 		nvme_rdma_stop_io_queues(ctrl);
diff --git a/kernel/drivers/nvme/host/tcp.c b/kernel/drivers/nvme/host/tcp.c
index 57df87d..ea4d317 100644
--- a/kernel/drivers/nvme/host/tcp.c
+++ b/kernel/drivers/nvme/host/tcp.c
@@ -1535,22 +1535,7 @@
 	if (ret)
 		goto err_init_connect;
 
-	queue->rd_enabled = true;
 	set_bit(NVME_TCP_Q_ALLOCATED, &queue->flags);
-	nvme_tcp_init_recv_ctx(queue);
-
-	write_lock_bh(&queue->sock->sk->sk_callback_lock);
-	queue->sock->sk->sk_user_data = queue;
-	queue->state_change = queue->sock->sk->sk_state_change;
-	queue->data_ready = queue->sock->sk->sk_data_ready;
-	queue->write_space = queue->sock->sk->sk_write_space;
-	queue->sock->sk->sk_data_ready = nvme_tcp_data_ready;
-	queue->sock->sk->sk_state_change = nvme_tcp_state_change;
-	queue->sock->sk->sk_write_space = nvme_tcp_write_space;
-#ifdef CONFIG_NET_RX_BUSY_POLL
-	queue->sock->sk->sk_ll_usec = 1;
-#endif
-	write_unlock_bh(&queue->sock->sk->sk_callback_lock);
 
 	return 0;
 
@@ -1569,7 +1554,7 @@
 	return ret;
 }
 
-static void nvme_tcp_restore_sock_calls(struct nvme_tcp_queue *queue)
+static void nvme_tcp_restore_sock_ops(struct nvme_tcp_queue *queue)
 {
 	struct socket *sock = queue->sock;
 
@@ -1584,7 +1569,7 @@
 static void __nvme_tcp_stop_queue(struct nvme_tcp_queue *queue)
 {
 	kernel_sock_shutdown(queue->sock, SHUT_RDWR);
-	nvme_tcp_restore_sock_calls(queue);
+	nvme_tcp_restore_sock_ops(queue);
 	cancel_work_sync(&queue->io_work);
 }
 
@@ -1599,10 +1584,31 @@
 	mutex_unlock(&queue->queue_lock);
 }
 
+static void nvme_tcp_setup_sock_ops(struct nvme_tcp_queue *queue)
+{
+	write_lock_bh(&queue->sock->sk->sk_callback_lock);
+	queue->sock->sk->sk_user_data = queue;
+	queue->state_change = queue->sock->sk->sk_state_change;
+	queue->data_ready = queue->sock->sk->sk_data_ready;
+	queue->write_space = queue->sock->sk->sk_write_space;
+	queue->sock->sk->sk_data_ready = nvme_tcp_data_ready;
+	queue->sock->sk->sk_state_change = nvme_tcp_state_change;
+	queue->sock->sk->sk_write_space = nvme_tcp_write_space;
+#ifdef CONFIG_NET_RX_BUSY_POLL
+	queue->sock->sk->sk_ll_usec = 1;
+#endif
+	write_unlock_bh(&queue->sock->sk->sk_callback_lock);
+}
+
 static int nvme_tcp_start_queue(struct nvme_ctrl *nctrl, int idx)
 {
 	struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
+	struct nvme_tcp_queue *queue = &ctrl->queues[idx];
 	int ret;
+
+	queue->rd_enabled = true;
+	nvme_tcp_init_recv_ctx(queue);
+	nvme_tcp_setup_sock_ops(queue);
 
 	if (idx)
 		ret = nvmf_connect_io_queue(nctrl, idx, false);
@@ -1610,10 +1616,10 @@
 		ret = nvmf_connect_admin_queue(nctrl);
 
 	if (!ret) {
-		set_bit(NVME_TCP_Q_LIVE, &ctrl->queues[idx].flags);
+		set_bit(NVME_TCP_Q_LIVE, &queue->flags);
 	} else {
-		if (test_bit(NVME_TCP_Q_ALLOCATED, &ctrl->queues[idx].flags))
-			__nvme_tcp_stop_queue(&ctrl->queues[idx]);
+		if (test_bit(NVME_TCP_Q_ALLOCATED, &queue->flags))
+			__nvme_tcp_stop_queue(queue);
 		dev_err(nctrl->device,
 			"failed to connect queue: %d ret=%d\n", idx, ret);
 	}
@@ -1853,6 +1859,7 @@
 		goto out_cleanup_connect_q;
 
 	if (!new) {
+		nvme_start_freeze(ctrl);
 		nvme_start_queues(ctrl);
 		if (!nvme_wait_freeze_timeout(ctrl, NVME_IO_TIMEOUT)) {
 			/*
@@ -1861,6 +1868,7 @@
 			 * to be safe.
 			 */
 			ret = -ENODEV;
+			nvme_unfreeze(ctrl);
 			goto out_wait_freeze_timed_out;
 		}
 		blk_mq_update_nr_hw_queues(ctrl->tagset,
@@ -1983,7 +1991,6 @@
 	if (ctrl->queue_count <= 1)
 		return;
 	blk_mq_quiesce_queue(ctrl->admin_q);
-	nvme_start_freeze(ctrl);
 	nvme_stop_queues(ctrl);
 	nvme_sync_io_queues(ctrl);
 	nvme_tcp_stop_io_queues(ctrl);
diff --git a/kernel/drivers/nvme/host/trace.h b/kernel/drivers/nvme/host/trace.h
index aa8b0f8..b258f7b 100644
--- a/kernel/drivers/nvme/host/trace.h
+++ b/kernel/drivers/nvme/host/trace.h
@@ -127,15 +127,12 @@
 	),
 	TP_printk("nvme%d: NVME_AEN=%#08x [%s]",
 		__entry->ctrl_id, __entry->result,
-		__print_symbolic(__entry->result,
-		aer_name(NVME_AER_NOTICE_NS_CHANGED),
-		aer_name(NVME_AER_NOTICE_ANA),
-		aer_name(NVME_AER_NOTICE_FW_ACT_STARTING),
-		aer_name(NVME_AER_NOTICE_DISC_CHANGED),
-		aer_name(NVME_AER_ERROR),
-		aer_name(NVME_AER_SMART),
-		aer_name(NVME_AER_CSS),
-		aer_name(NVME_AER_VS))
+		__print_symbolic(__entry->result & 0x7,
+			aer_name(NVME_AER_ERROR),
+			aer_name(NVME_AER_SMART),
+			aer_name(NVME_AER_NOTICE),
+			aer_name(NVME_AER_CSS),
+			aer_name(NVME_AER_VS))
 	)
 );
 
diff --git a/kernel/drivers/nvme/target/core.c b/kernel/drivers/nvme/target/core.c
index fa04d97..6f17a34 100644
--- a/kernel/drivers/nvme/target/core.c
+++ b/kernel/drivers/nvme/target/core.c
@@ -749,8 +749,10 @@
 
 void nvmet_req_complete(struct nvmet_req *req, u16 status)
 {
+	struct nvmet_sq *sq = req->sq;
+
 	__nvmet_req_complete(req, status);
-	percpu_ref_put(&req->sq->ref);
+	percpu_ref_put(&sq->ref);
 }
 EXPORT_SYMBOL_GPL(nvmet_req_complete);
 
diff --git a/kernel/drivers/nvme/target/fc.c b/kernel/drivers/nvme/target/fc.c
index 640031c..46fc44c 100644
--- a/kernel/drivers/nvme/target/fc.c
+++ b/kernel/drivers/nvme/target/fc.c
@@ -1675,8 +1675,10 @@
 		else {
 			queue = nvmet_fc_alloc_target_queue(iod->assoc, 0,
 					be16_to_cpu(rqst->assoc_cmd.sqsize));
-			if (!queue)
+			if (!queue) {
 				ret = VERR_QUEUE_ALLOC_FAIL;
+				nvmet_fc_tgt_a_put(iod->assoc);
+			}
 		}
 	}
 
diff --git a/kernel/drivers/nvme/target/fcloop.c b/kernel/drivers/nvme/target/fcloop.c
index 3da067a..80a208f 100644
--- a/kernel/drivers/nvme/target/fcloop.c
+++ b/kernel/drivers/nvme/target/fcloop.c
@@ -570,10 +570,11 @@
 	struct fcloop_fcpreq *tfcp_req =
 		container_of(work, struct fcloop_fcpreq, fcp_rcv_work);
 	struct nvmefc_fcp_req *fcpreq = tfcp_req->fcpreq;
+	unsigned long flags;
 	int ret = 0;
 	bool aborted = false;
 
-	spin_lock_irq(&tfcp_req->reqlock);
+	spin_lock_irqsave(&tfcp_req->reqlock, flags);
 	switch (tfcp_req->inistate) {
 	case INI_IO_START:
 		tfcp_req->inistate = INI_IO_ACTIVE;
@@ -582,11 +583,11 @@
 		aborted = true;
 		break;
 	default:
-		spin_unlock_irq(&tfcp_req->reqlock);
+		spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
 		WARN_ON(1);
 		return;
 	}
-	spin_unlock_irq(&tfcp_req->reqlock);
+	spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
 
 	if (unlikely(aborted))
 		ret = -ECANCELED;
@@ -607,8 +608,9 @@
 		container_of(work, struct fcloop_fcpreq, abort_rcv_work);
 	struct nvmefc_fcp_req *fcpreq;
 	bool completed = false;
+	unsigned long flags;
 
-	spin_lock_irq(&tfcp_req->reqlock);
+	spin_lock_irqsave(&tfcp_req->reqlock, flags);
 	fcpreq = tfcp_req->fcpreq;
 	switch (tfcp_req->inistate) {
 	case INI_IO_ABORTED:
@@ -617,11 +619,11 @@
 		completed = true;
 		break;
 	default:
-		spin_unlock_irq(&tfcp_req->reqlock);
+		spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
 		WARN_ON(1);
 		return;
 	}
-	spin_unlock_irq(&tfcp_req->reqlock);
+	spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
 
 	if (unlikely(completed)) {
 		/* remove reference taken in original abort downcall */
@@ -633,9 +635,9 @@
 		nvmet_fc_rcv_fcp_abort(tfcp_req->tport->targetport,
 					&tfcp_req->tgt_fcp_req);
 
-	spin_lock_irq(&tfcp_req->reqlock);
+	spin_lock_irqsave(&tfcp_req->reqlock, flags);
 	tfcp_req->fcpreq = NULL;
-	spin_unlock_irq(&tfcp_req->reqlock);
+	spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
 
 	fcloop_call_host_done(fcpreq, tfcp_req, -ECANCELED);
 	/* call_host_done releases reference for abort downcall */
@@ -651,11 +653,12 @@
 	struct fcloop_fcpreq *tfcp_req =
 		container_of(work, struct fcloop_fcpreq, tio_done_work);
 	struct nvmefc_fcp_req *fcpreq;
+	unsigned long flags;
 
-	spin_lock_irq(&tfcp_req->reqlock);
+	spin_lock_irqsave(&tfcp_req->reqlock, flags);
 	fcpreq = tfcp_req->fcpreq;
 	tfcp_req->inistate = INI_IO_COMPLETED;
-	spin_unlock_irq(&tfcp_req->reqlock);
+	spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
 
 	fcloop_call_host_done(fcpreq, tfcp_req, tfcp_req->status);
 }
@@ -759,13 +762,14 @@
 	u32 rsplen = 0, xfrlen = 0;
 	int fcp_err = 0, active, aborted;
 	u8 op = tgt_fcpreq->op;
+	unsigned long flags;
 
-	spin_lock_irq(&tfcp_req->reqlock);
+	spin_lock_irqsave(&tfcp_req->reqlock, flags);
 	fcpreq = tfcp_req->fcpreq;
 	active = tfcp_req->active;
 	aborted = tfcp_req->aborted;
 	tfcp_req->active = true;
-	spin_unlock_irq(&tfcp_req->reqlock);
+	spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
 
 	if (unlikely(active))
 		/* illegal - call while i/o active */
@@ -773,9 +777,9 @@
 
 	if (unlikely(aborted)) {
 		/* target transport has aborted i/o prior */
-		spin_lock_irq(&tfcp_req->reqlock);
+		spin_lock_irqsave(&tfcp_req->reqlock, flags);
 		tfcp_req->active = false;
-		spin_unlock_irq(&tfcp_req->reqlock);
+		spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
 		tgt_fcpreq->transferred_length = 0;
 		tgt_fcpreq->fcp_error = -ECANCELED;
 		tgt_fcpreq->done(tgt_fcpreq);
@@ -832,9 +836,9 @@
 		break;
 	}
 
-	spin_lock_irq(&tfcp_req->reqlock);
+	spin_lock_irqsave(&tfcp_req->reqlock, flags);
 	tfcp_req->active = false;
-	spin_unlock_irq(&tfcp_req->reqlock);
+	spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
 
 	tgt_fcpreq->transferred_length = xfrlen;
 	tgt_fcpreq->fcp_error = fcp_err;
@@ -848,15 +852,16 @@
 			struct nvmefc_tgt_fcp_req *tgt_fcpreq)
 {
 	struct fcloop_fcpreq *tfcp_req = tgt_fcp_req_to_fcpreq(tgt_fcpreq);
+	unsigned long flags;
 
 	/*
 	 * mark aborted only in case there were 2 threads in transport
 	 * (one doing io, other doing abort) and only kills ops posted
 	 * after the abort request
 	 */
-	spin_lock_irq(&tfcp_req->reqlock);
+	spin_lock_irqsave(&tfcp_req->reqlock, flags);
 	tfcp_req->aborted = true;
-	spin_unlock_irq(&tfcp_req->reqlock);
+	spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
 
 	tfcp_req->status = NVME_SC_INTERNAL;
 
@@ -898,6 +903,7 @@
 	struct fcloop_ini_fcpreq *inireq = fcpreq->private;
 	struct fcloop_fcpreq *tfcp_req;
 	bool abortio = true;
+	unsigned long flags;
 
 	spin_lock(&inireq->inilock);
 	tfcp_req = inireq->tfcp_req;
@@ -910,7 +916,7 @@
 		return;
 
 	/* break initiator/target relationship for io */
-	spin_lock_irq(&tfcp_req->reqlock);
+	spin_lock_irqsave(&tfcp_req->reqlock, flags);
 	switch (tfcp_req->inistate) {
 	case INI_IO_START:
 	case INI_IO_ACTIVE:
@@ -920,11 +926,11 @@
 		abortio = false;
 		break;
 	default:
-		spin_unlock_irq(&tfcp_req->reqlock);
+		spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
 		WARN_ON(1);
 		return;
 	}
-	spin_unlock_irq(&tfcp_req->reqlock);
+	spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
 
 	if (abortio)
 		/* leave the reference while the work item is scheduled */
diff --git a/kernel/drivers/nvme/target/passthru.c b/kernel/drivers/nvme/target/passthru.c
index d24251e..f76d010 100644
--- a/kernel/drivers/nvme/target/passthru.c
+++ b/kernel/drivers/nvme/target/passthru.c
@@ -259,14 +259,13 @@
 	}
 
 	/*
-	 * If there are effects for the command we are about to execute, or
-	 * an end_req function we need to use nvme_execute_passthru_rq()
-	 * synchronously in a work item seeing the end_req function and
-	 * nvme_passthru_end() can't be called in the request done callback
-	 * which is typically in interrupt context.
+	 * If a command needs post-execution fixups, or there are any
+	 * non-trivial effects, make sure to execute the command synchronously
+	 * in a workqueue so that nvme_passthru_end gets called.
 	 */
 	effects = nvme_command_effects(ctrl, ns, req->cmd->common.opcode);
-	if (req->p.use_workqueue || effects) {
+	if (req->p.use_workqueue ||
+	    (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC))) {
 		INIT_WORK(&req->p.work, nvmet_passthru_execute_cmd_work);
 		req->p.rq = rq;
 		schedule_work(&req->p.work);
diff --git a/kernel/drivers/nvmem/core.c b/kernel/drivers/nvmem/core.c
index c8db5f9..b9a0326 100644
--- a/kernel/drivers/nvmem/core.c
+++ b/kernel/drivers/nvmem/core.c
@@ -625,6 +625,8 @@
 		return ERR_PTR(rval);
 	}
 
+	nvmem->id = rval;
+
 	if (config->wp_gpio)
 		nvmem->wp_gpio = config->wp_gpio;
 	else
@@ -640,7 +642,6 @@
 	kref_init(&nvmem->refcnt);
 	INIT_LIST_HEAD(&nvmem->cells);
 
-	nvmem->id = rval;
 	nvmem->owner = config->owner;
 	if (!nvmem->owner && config->dev->driver)
 		nvmem->owner = config->dev->driver->owner;
@@ -660,16 +661,22 @@
 
 	switch (config->id) {
 	case NVMEM_DEVID_NONE:
-		dev_set_name(&nvmem->dev, "%s", config->name);
+		rval = dev_set_name(&nvmem->dev, "%s", config->name);
 		break;
 	case NVMEM_DEVID_AUTO:
-		dev_set_name(&nvmem->dev, "%s%d", config->name, nvmem->id);
+		rval = dev_set_name(&nvmem->dev, "%s%d", config->name, nvmem->id);
 		break;
 	default:
-		dev_set_name(&nvmem->dev, "%s%d",
+		rval = dev_set_name(&nvmem->dev, "%s%d",
 			     config->name ? : "nvmem",
 			     config->name ? config->id : nvmem->id);
 		break;
+	}
+
+	if (rval) {
+		ida_free(&nvmem_ida, nvmem->id);
+		kfree(nvmem);
+		return ERR_PTR(rval);
 	}
 
 	nvmem->read_only = device_property_present(config->dev, "read-only") ||
@@ -694,7 +701,7 @@
 	if (config->cells) {
 		rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
 		if (rval)
-			goto err_teardown_compat;
+			goto err_remove_cells;
 	}
 
 	rval = nvmem_add_cells_from_table(nvmem);
@@ -711,7 +718,6 @@
 
 err_remove_cells:
 	nvmem_device_remove_all_cells(nvmem);
-err_teardown_compat:
 	if (config->compat)
 		nvmem_sysfs_remove_compat(nvmem, config);
 err_device_del:
diff --git a/kernel/drivers/nvmem/qcom-spmi-sdam.c b/kernel/drivers/nvmem/qcom-spmi-sdam.c
index f6e9f96..1549bfc 100644
--- a/kernel/drivers/nvmem/qcom-spmi-sdam.c
+++ b/kernel/drivers/nvmem/qcom-spmi-sdam.c
@@ -166,6 +166,7 @@
 	{ .compatible = "qcom,spmi-sdam" },
 	{},
 };
+MODULE_DEVICE_TABLE(of, sdam_match_table);
 
 static struct platform_driver sdam_driver = {
 	.driver = {
diff --git a/kernel/drivers/of/address.c b/kernel/drivers/of/address.c
index 73ddf25..f686fb5 100644
--- a/kernel/drivers/of/address.c
+++ b/kernel/drivers/of/address.c
@@ -990,8 +990,19 @@
 	}
 
 	of_dma_range_parser_init(&parser, node);
-	for_each_of_range(&parser, &range)
+	for_each_of_range(&parser, &range) {
+		if (range.cpu_addr == OF_BAD_ADDR) {
+			pr_err("translation of DMA address(%llx) to CPU address failed node(%pOF)\n",
+			       range.bus_addr, node);
+			continue;
+		}
 		num_ranges++;
+	}
+
+	if (!num_ranges) {
+		ret = -EINVAL;
+		goto out;
+	}
 
 	r = kcalloc(num_ranges + 1, sizeof(*r), GFP_KERNEL);
 	if (!r) {
@@ -1000,18 +1011,16 @@
 	}
 
 	/*
-	 * Record all info in the generic DMA ranges array for struct device.
+	 * Record all info in the generic DMA ranges array for struct device,
+	 * returning an error if we don't find any parsable ranges.
 	 */
 	*map = r;
 	of_dma_range_parser_init(&parser, node);
 	for_each_of_range(&parser, &range) {
 		pr_debug("dma_addr(%llx) cpu_addr(%llx) size(%llx)\n",
 			 range.bus_addr, range.cpu_addr, range.size);
-		if (range.cpu_addr == OF_BAD_ADDR) {
-			pr_err("translation of DMA address(%llx) to CPU address failed node(%pOF)\n",
-			       range.bus_addr, node);
+		if (range.cpu_addr == OF_BAD_ADDR)
 			continue;
-		}
 		r->cpu_start = range.cpu_addr;
 		r->dma_start = range.bus_addr;
 		r->size = range.size;
diff --git a/kernel/drivers/of/base.c b/kernel/drivers/of/base.c
index bcc88cb..bcb37c3 100644
--- a/kernel/drivers/of/base.c
+++ b/kernel/drivers/of/base.c
@@ -628,6 +628,28 @@
 EXPORT_SYMBOL(of_device_is_available);
 
 /**
+ *  __of_device_is_fail - check if a device has status "fail" or "fail-..."
+ *
+ *  @device: Node to check status for, with locks already held
+ *
+ *  Return: True if the status property is set to "fail" or "fail-..." (for any
+ *  error code suffix), false otherwise
+ */
+static bool __of_device_is_fail(const struct device_node *device)
+{
+	const char *status;
+
+	if (!device)
+		return false;
+
+	status = __of_get_property(device, "status", NULL);
+	if (status == NULL)
+		return false;
+
+	return !strcmp(status, "fail") || !strncmp(status, "fail-", 5);
+}
+
+/**
  *  of_device_is_big_endian - check if a device has BE registers
  *
  *  @device: Node to check for endianness
@@ -775,6 +797,9 @@
  *	of_get_next_cpu_node - Iterate on cpu nodes
  *	@prev:	previous child of the /cpus node, or NULL to get first
  *
+ *	Unusable CPUs (those with the status property set to "fail" or "fail-...")
+ * 	will be skipped.
+ *
  *	Returns a cpu node pointer with refcount incremented, use of_node_put()
  *	on it when done. Returns NULL when prev is the last child. Decrements
  *	the refcount of prev.
@@ -796,6 +821,8 @@
 		of_node_put(node);
 	}
 	for (; next; next = next->sibling) {
+		if (__of_device_is_fail(next))
+			continue;
 		if (!(of_node_name_eq(next, "cpu") ||
 		      __of_node_is_type(next, "cpu")))
 			continue;
diff --git a/kernel/drivers/of/device.c b/kernel/drivers/of/device.c
index 1122daa..3a54779 100644
--- a/kernel/drivers/of/device.c
+++ b/kernel/drivers/of/device.c
@@ -264,12 +264,15 @@
 	if (size < 0)
 		return size;
 
-	str = kmalloc(size + 1, GFP_KERNEL);
+	/* Reserve an additional byte for the trailing '\0' */
+	size++;
+
+	str = kmalloc(size, GFP_KERNEL);
 	if (!str)
 		return -ENOMEM;
 
 	of_device_get_modalias(dev, str, size);
-	str[size] = '\0';
+	str[size - 1] = '\0';
 	ret = request_module(str);
 	kfree(str);
 
diff --git a/kernel/drivers/of/dynamic.c b/kernel/drivers/of/dynamic.c
index 9a824de..129aa97 100644
--- a/kernel/drivers/of/dynamic.c
+++ b/kernel/drivers/of/dynamic.c
@@ -63,15 +63,14 @@
 }
 EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister);
 
-#ifdef DEBUG
-const char *action_names[] = {
+static const char *action_names[] = {
+	[0] = "INVALID",
 	[OF_RECONFIG_ATTACH_NODE] = "ATTACH_NODE",
 	[OF_RECONFIG_DETACH_NODE] = "DETACH_NODE",
 	[OF_RECONFIG_ADD_PROPERTY] = "ADD_PROPERTY",
 	[OF_RECONFIG_REMOVE_PROPERTY] = "REMOVE_PROPERTY",
 	[OF_RECONFIG_UPDATE_PROPERTY] = "UPDATE_PROPERTY",
 };
-#endif
 
 int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p)
 {
@@ -590,21 +589,9 @@
 		}
 
 		ret = __of_add_property(ce->np, ce->prop);
-		if (ret) {
-			pr_err("changeset: add_property failed @%pOF/%s\n",
-				ce->np,
-				ce->prop->name);
-			break;
-		}
 		break;
 	case OF_RECONFIG_REMOVE_PROPERTY:
 		ret = __of_remove_property(ce->np, ce->prop);
-		if (ret) {
-			pr_err("changeset: remove_property failed @%pOF/%s\n",
-				ce->np,
-				ce->prop->name);
-			break;
-		}
 		break;
 
 	case OF_RECONFIG_UPDATE_PROPERTY:
@@ -618,20 +605,17 @@
 		}
 
 		ret = __of_update_property(ce->np, ce->prop, &old_prop);
-		if (ret) {
-			pr_err("changeset: update_property failed @%pOF/%s\n",
-				ce->np,
-				ce->prop->name);
-			break;
-		}
 		break;
 	default:
 		ret = -EINVAL;
 	}
 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
 
-	if (ret)
+	if (ret) {
+		pr_err("changeset: apply failed: %-15s %pOF:%s\n",
+		       action_names[ce->action], ce->np, ce->prop->name);
 		return ret;
+	}
 
 	switch (ce->action) {
 	case OF_RECONFIG_ATTACH_NODE:
@@ -910,6 +894,9 @@
 {
 	struct of_changeset_entry *ce;
 
+	if (WARN_ON(action >= ARRAY_SIZE(action_names)))
+		return -EINVAL;
+
 	ce = kzalloc(sizeof(*ce), GFP_KERNEL);
 	if (!ce)
 		return -ENOMEM;
diff --git a/kernel/drivers/of/overlay.c b/kernel/drivers/of/overlay.c
index c8a0c0e..67b404f 100644
--- a/kernel/drivers/of/overlay.c
+++ b/kernel/drivers/of/overlay.c
@@ -547,7 +547,7 @@
 
 		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 @@
 
 		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 &&
diff --git a/kernel/drivers/of/unittest.c b/kernel/drivers/of/unittest.c
index 5407bbd..412d7dd 100644
--- a/kernel/drivers/of/unittest.c
+++ b/kernel/drivers/of/unittest.c
@@ -69,7 +69,7 @@
 
 	np = of_find_node_by_path("/testcase-data");
 	name = kasprintf(GFP_KERNEL, "%pOF", np);
-	unittest(np && !strcmp("/testcase-data", name),
+	unittest(np && name && !strcmp("/testcase-data", name),
 		"find /testcase-data failed\n");
 	of_node_put(np);
 	kfree(name);
@@ -80,14 +80,14 @@
 
 	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
 	name = kasprintf(GFP_KERNEL, "%pOF", np);
-	unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name),
+	unittest(np && name && !strcmp("/testcase-data/phandle-tests/consumer-a", name),
 		"find /testcase-data/phandle-tests/consumer-a failed\n");
 	of_node_put(np);
 	kfree(name);
 
 	np = of_find_node_by_path("testcase-alias");
 	name = kasprintf(GFP_KERNEL, "%pOF", np);
-	unittest(np && !strcmp("/testcase-data", name),
+	unittest(np && name && !strcmp("/testcase-data", name),
 		"find testcase-alias failed\n");
 	of_node_put(np);
 	kfree(name);
@@ -98,7 +98,7 @@
 
 	np = of_find_node_by_path("testcase-alias/phandle-tests/consumer-a");
 	name = kasprintf(GFP_KERNEL, "%pOF", np);
-	unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name),
+	unittest(np && name && !strcmp("/testcase-data/phandle-tests/consumer-a", name),
 		"find testcase-alias/phandle-tests/consumer-a failed\n");
 	of_node_put(np);
 	kfree(name);
@@ -1376,6 +1376,8 @@
 	const char *full_name;
 
 	full_name = kasprintf(GFP_KERNEL, "%pOF", np);
+	if (!full_name)
+		return;
 
 	if (!strcmp(full_name, "/__local_fixups__") ||
 	    !strcmp(full_name, "/__fixups__")) {
@@ -2065,7 +2067,7 @@
 	of_unittest_untrack_overlay(save_id);
 
 	/* unittest device must be again in before state */
-	if (of_unittest_device_exists(unittest_nr, PDEV_OVERLAY) != before) {
+	if (of_unittest_device_exists(unittest_nr, ovtype) != before) {
 		unittest(0, "%s with device @\"%s\" %s\n",
 				overlay_name_from_nr(overlay_nr),
 				unittest_path(unittest_nr, ovtype),
diff --git a/kernel/drivers/opp/core.c b/kernel/drivers/opp/core.c
index 7ed605f..7999baa 100644
--- a/kernel/drivers/opp/core.c
+++ b/kernel/drivers/opp/core.c
@@ -2053,7 +2053,7 @@
 
 		virt_dev = dev_pm_domain_attach_by_name(dev, *name);
 		if (IS_ERR_OR_NULL(virt_dev)) {
-			ret = PTR_ERR(virt_dev) ? : -ENODEV;
+			ret = virt_dev ? PTR_ERR(virt_dev) : -ENODEV;
 			dev_err(dev, "Couldn't attach to pm_domain: %d\n", ret);
 			goto err;
 		}
diff --git a/kernel/drivers/opp/debugfs.c b/kernel/drivers/opp/debugfs.c
index 7507605..d4270ae 100644
--- a/kernel/drivers/opp/debugfs.c
+++ b/kernel/drivers/opp/debugfs.c
@@ -204,7 +204,7 @@
 
 	dentry = debugfs_rename(rootdir, opp_dev->dentry, rootdir,
 				opp_table->dentry_name);
-	if (!dentry) {
+	if (IS_ERR(dentry)) {
 		dev_err(dev, "%s: Failed to rename link from: %s to %s\n",
 			__func__, dev_name(opp_dev->dev), dev_name(dev));
 		return;
diff --git a/kernel/drivers/parisc/iosapic.c b/kernel/drivers/parisc/iosapic.c
index fd99735..6ef663b 100644
--- a/kernel/drivers/parisc/iosapic.c
+++ b/kernel/drivers/parisc/iosapic.c
@@ -202,9 +202,9 @@
 
 static DEFINE_SPINLOCK(iosapic_lock);
 
-static inline void iosapic_eoi(void __iomem *addr, unsigned int data)
+static inline void iosapic_eoi(__le32 __iomem *addr, __le32 data)
 {
-	__raw_writel(data, addr);
+	__raw_writel((__force u32)data, addr);
 }
 
 /*
diff --git a/kernel/drivers/parisc/iosapic_private.h b/kernel/drivers/parisc/iosapic_private.h
index 73ecc65..bd8ff40 100644
--- a/kernel/drivers/parisc/iosapic_private.h
+++ b/kernel/drivers/parisc/iosapic_private.h
@@ -118,8 +118,8 @@
 struct vector_info {
 	struct iosapic_info *iosapic;	/* I/O SAPIC this vector is on */
 	struct irt_entry *irte;		/* IRT entry */
-	u32 __iomem *eoi_addr;		/* precalculate EOI reg address */
-	u32	eoi_data;		/* IA64: ?       PA: swapped txn_data */
+	__le32 __iomem *eoi_addr;	/* precalculate EOI reg address */
+	__le32	eoi_data;		/* IA64: ?       PA: swapped txn_data */
 	int	txn_irq;		/* virtual IRQ number for processor */
 	ulong	txn_addr;		/* IA64: id_eid  PA: partial HPA */
 	u32	txn_data;		/* CPU interrupt bit */
diff --git a/kernel/drivers/parisc/led.c b/kernel/drivers/parisc/led.c
index 36c6613..81e5e7a 100644
--- a/kernel/drivers/parisc/led.c
+++ b/kernel/drivers/parisc/led.c
@@ -56,8 +56,8 @@
 static int led_type __read_mostly = -1;
 static unsigned char lastleds;	/* LED state from most recent update */
 static unsigned int led_heartbeat __read_mostly = 1;
-static unsigned int led_diskio    __read_mostly = 1;
-static unsigned int led_lanrxtx   __read_mostly = 1;
+static unsigned int led_diskio    __read_mostly;
+static unsigned int led_lanrxtx   __read_mostly;
 static char lcd_text[32]          __read_mostly;
 static char lcd_text_default[32]  __read_mostly;
 static int  lcd_no_led_support    __read_mostly = 0; /* KittyHawk doesn't support LED on its LCD */
@@ -137,6 +137,9 @@
 
 	/* Create the work queue and queue the LED task */
 	led_wq = create_singlethread_workqueue("led_wq");	
+	if (!led_wq)
+		return -ENOMEM;
+
 	queue_delayed_work(led_wq, &led_task, 0);
 
 	return 0;
diff --git a/kernel/drivers/pci/controller/cadence/pcie-cadence-host.c b/kernel/drivers/pci/controller/cadence/pcie-cadence-host.c
index a40ed9e..a4607fd 100644
--- a/kernel/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/kernel/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -12,6 +12,8 @@
 
 #include "pcie-cadence.h"
 
+#define LINK_RETRAIN_TIMEOUT HZ
+
 static u64 bar_max_size[] = {
 	[RP_BAR0] = _ULL(128 * SZ_2G),
 	[RP_BAR1] = SZ_2G,
@@ -77,6 +79,27 @@
 	.write		= pci_generic_config_write,
 };
 
+static int cdns_pcie_host_training_complete(struct cdns_pcie *pcie)
+{
+	u32 pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET;
+	unsigned long end_jiffies;
+	u16 lnk_stat;
+
+	/* Wait for link training to complete. Exit after timeout. */
+	end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT;
+	do {
+		lnk_stat = cdns_pcie_rp_readw(pcie, pcie_cap_off + PCI_EXP_LNKSTA);
+		if (!(lnk_stat & PCI_EXP_LNKSTA_LT))
+			break;
+		usleep_range(0, 1000);
+	} while (time_before(jiffies, end_jiffies));
+
+	if (!(lnk_stat & PCI_EXP_LNKSTA_LT))
+		return 0;
+
+	return -ETIMEDOUT;
+}
+
 static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie)
 {
 	struct device *dev = pcie->dev;
@@ -118,6 +141,10 @@
 		cdns_pcie_rp_writew(pcie, pcie_cap_off + PCI_EXP_LNKCTL,
 				    lnk_ctl);
 
+		ret = cdns_pcie_host_training_complete(pcie);
+		if (ret)
+			return ret;
+
 		ret = cdns_pcie_host_wait_for_link(pcie);
 	}
 	return ret;
diff --git a/kernel/drivers/pci/controller/dwc/pci-imx6.c b/kernel/drivers/pci/controller/dwc/pci-imx6.c
index ceb4815..8117f2d 100644
--- a/kernel/drivers/pci/controller/dwc/pci-imx6.c
+++ b/kernel/drivers/pci/controller/dwc/pci-imx6.c
@@ -1272,6 +1272,13 @@
 static int __init imx6_pcie_init(void)
 {
 #ifdef CONFIG_ARM
+	struct device_node *np;
+
+	np = of_find_matching_node(NULL, imx6_pcie_of_match);
+	if (!np)
+		return -ENODEV;
+	of_node_put(np);
+
 	/*
 	 * Since probe() can be deferred we need to make sure that
 	 * hook_fault_code is not called after __init memory is freed
diff --git a/kernel/drivers/pci/controller/dwc/pcie-designware.c b/kernel/drivers/pci/controller/dwc/pcie-designware.c
index daa8885..45f467f 100644
--- a/kernel/drivers/pci/controller/dwc/pcie-designware.c
+++ b/kernel/drivers/pci/controller/dwc/pcie-designware.c
@@ -591,7 +591,7 @@
 	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);
 	}
 
diff --git a/kernel/drivers/pci/controller/dwc/pcie-dw-dmatest.c b/kernel/drivers/pci/controller/dwc/pcie-dw-dmatest.c
index 4b0d4d3..3d5b44f 100644
--- a/kernel/drivers/pci/controller/dwc/pcie-dw-dmatest.c
+++ b/kernel/drivers/pci/controller/dwc/pcie-dw-dmatest.c
@@ -3,8 +3,6 @@
  * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include <linux/init.h>
 #include <linux/ktime.h>
 #include <linux/module.h>
@@ -14,8 +12,9 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
 
-#include "pcie-designware.h"
 #include "pcie-dw-dmatest.h"
 #include "../rockchip-pcie-dma.h"
 
@@ -35,25 +34,26 @@
 module_param(rw_test, uint, 0644);
 MODULE_PARM_DESC(rw_test, "Read/Write test, 1-read 2-write 3-both(default 3)");
 
-static unsigned int bus_addr = 0x3c000000;
-module_param(bus_addr, uint, 0644);
+static unsigned long bus_addr = 0x3c000000;
+module_param(bus_addr, ulong, 0644);
 MODULE_PARM_DESC(bus_addr, "Dmatest chn0 bus_addr(remote), chn1 add offset 0x100000, (default 0x3c000000)");
 
-static unsigned int local_addr = 0x3c000000;
-module_param(local_addr, uint, 0644);
+static unsigned long local_addr = 0x3c000000;
+module_param(local_addr, ulong, 0644);
 MODULE_PARM_DESC(local_addr, "Dmatest chn0 local_addr(local), chn1 add offset 0x100000, (default 0x3c000000)");
 
 static unsigned int test_dev;
 module_param(test_dev, uint, 0644);
 MODULE_PARM_DESC(test_dev, "Choose dma_obj device,(default 0)");
 
-static bool is_rc = true;
-module_param_named(is_rc, is_rc, bool, 0644);
-MODULE_PARM_DESC(is_rc, "Test port is rc(default true)");
+static bool is_wired;
+module_param_named(is_wired, is_wired, bool, 0644);
+MODULE_PARM_DESC(is_wired, "Transfer is triggered by wired DMA(default false)");
 
-#define PCIE_DW_MISC_DMATEST_DEV_MAX 5
+#define PCIE_DW_MISC_DMATEST_DEV_MAX	1
 
 #define PCIE_DMA_CHANEL_MAX_NUM		2
+#define PCIE_DMA_LL_MAX_NUM		1024 /* Unrestricted, tentative value */
 
 struct pcie_dw_dmatest_dev {
 	struct dma_trx_obj *obj;
@@ -64,51 +64,70 @@
 
 	struct mutex rd_lock[PCIE_DMA_CHANEL_MAX_NUM];	/* Corresponding to each read DMA channel */
 	struct mutex wr_lock[PCIE_DMA_CHANEL_MAX_NUM];	/* Corresponding to each write DMA channel */
+
+	struct dma_table rd_tbl_buf[PCIE_DMA_CHANEL_MAX_NUM];
+	struct dma_table wr_tbl_buf[PCIE_DMA_CHANEL_MAX_NUM];
 };
 
-static struct pcie_dw_dmatest_dev s_dmatest_dev[PCIE_DW_MISC_DMATEST_DEV_MAX];
-static int cur_dmatest_dev;
+static struct pcie_dw_dmatest_dev *s_dmatest_dev;
 
 static void pcie_dw_dmatest_show(void)
 {
 	int i;
 
 	for (i = 0; i < PCIE_DW_MISC_DMATEST_DEV_MAX; i++) {
-		if (s_dmatest_dev[i].obj)
-			dev_info(s_dmatest_dev[i].obj->dev, " test_dev index %d\n", i);
+		if (s_dmatest_dev)
+			dev_info(s_dmatest_dev->obj->dev, " test_dev index %d\n", i);
 		else
 			break;
 	}
 
-	dev_info(s_dmatest_dev[test_dev].obj->dev, " is current test_dev\n");
+	dev_info(s_dmatest_dev->obj->dev, " is current test_dev\n");
 }
 
-static int rk_pcie_dma_wait_for_finised(struct dma_trx_obj *obj, struct dma_table *table)
+static int rk_pcie_dma_wait_for_finished(struct dma_trx_obj *obj, struct dma_table *table)
 {
-	int ret;
+	int ret = 0, timeout_us, i;
 
-	do {
+	timeout_us = table->buf_size / 100 + 1000; /* 100MB/s for redundant calculate */
+
+	for (i = 0; i < timeout_us; i++) {
 		ret = obj->get_dma_status(obj, table->chn, table->dir);
-	} while (!ret);
+		if (ret == 1) {
+			ret = 0;
+			break;
+		} else if (ret < 0) {
+			ret = -EFAULT;
+			break;
+		}
+		udelay(1);
+	}
+
+	if (i >= timeout_us || ret) {
+		dev_err(obj->dev, "%s timeout\n", __func__);
+		if (obj->dma_debug)
+			obj->dma_debug(obj, table);
+		return -EFAULT;
+	}
 
 	return ret;
 }
 
-static int rk_pcie_ep_dma_frombus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn,
-				  u32 local_paddr, u32 bus_paddr, u32 size)
+static int rk_pcie_local_dma_frombus_block(struct dma_trx_obj *obj, u32 chn,
+					   u64 local_paddr, u64 bus_paddr, u32 size)
 {
+	struct pcie_dw_dmatest_dev *dmatest_dev = (struct pcie_dw_dmatest_dev *)obj->priv;
 	struct dma_table *table;
-	struct dma_trx_obj *obj = dmatest_dev->obj;
 	int ret;
 
 	if (chn >= PCIE_DMA_CHANEL_MAX_NUM)
 		return -1;
 
-	table = kzalloc(sizeof(struct dma_table), GFP_KERNEL);
-	if (!table)
-		return -ENOMEM;
-
 	mutex_lock(&dmatest_dev->rd_lock[chn]);
+
+	table = &dmatest_dev->rd_tbl_buf[chn];
+	memset(table, 0, sizeof(struct dma_table));
+
 	if (dmatest_dev->irq_en)
 		reinit_completion(&dmatest_dev->rd_done[chn]);
 
@@ -128,30 +147,28 @@
 		else if (ret == 0)
 			dev_err(obj->dev, "%s timed out\n", __func__);
 	} else {
-		ret = rk_pcie_dma_wait_for_finised(obj, table);
+		ret = rk_pcie_dma_wait_for_finished(obj, table);
 	}
 	mutex_unlock(&dmatest_dev->rd_lock[chn]);
-
-	kfree(table);
 
 	return ret;
 }
 
-static int rk_pcie_ep_dma_tobus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn,
-				u32 bus_paddr, u32 local_paddr, u32 size)
+int rk_pcie_local_dma_tobus_block(struct dma_trx_obj *obj, u32 chn,
+				  u64 bus_paddr, u64 local_paddr, u32 size)
 {
+	struct pcie_dw_dmatest_dev *dmatest_dev = (struct pcie_dw_dmatest_dev *)obj->priv;
 	struct dma_table *table;
-	struct dma_trx_obj *obj = dmatest_dev->obj;
 	int ret;
 
 	if (chn >= PCIE_DMA_CHANEL_MAX_NUM)
 		return -1;
 
-	table = kzalloc(sizeof(struct dma_table), GFP_KERNEL);
-	if (!table)
-		return -ENOMEM;
-
 	mutex_lock(&dmatest_dev->wr_lock[chn]);
+
+	table = &dmatest_dev->wr_tbl_buf[chn];
+	memset(table, 0, sizeof(struct dma_table));
+
 	if (dmatest_dev->irq_en)
 		reinit_completion(&dmatest_dev->wr_done[chn]);
 
@@ -171,25 +188,11 @@
 		else if (ret == 0)
 			dev_err(obj->dev, "%s timed out\n", __func__);
 	} else {
-		ret = rk_pcie_dma_wait_for_finised(obj, table);
+		ret = rk_pcie_dma_wait_for_finished(obj, table);
 	}
 	mutex_unlock(&dmatest_dev->wr_lock[chn]);
 
-	kfree(table);
-
 	return ret;
-}
-
-static int rk_pcie_rc_dma_frombus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn,
-				  u32 local_paddr, u32 bus_paddr, u32 size)
-{
-	return rk_pcie_ep_dma_tobus(dmatest_dev, chn, local_paddr, bus_paddr, size);
-}
-
-static int rk_pcie_rc_dma_tobus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn,
-				u32 bus_paddr, u32 local_paddr, u32 size)
-{
-	return rk_pcie_ep_dma_frombus(dmatest_dev, chn, bus_paddr, local_paddr, size);
 }
 
 static int rk_pcie_dma_interrupt_handler_call_back(struct dma_trx_obj *obj, u32 chn, enum dma_dir dir)
@@ -210,8 +213,12 @@
 struct dma_trx_obj *pcie_dw_dmatest_register(struct device *dev, bool irq_en)
 {
 	struct dma_trx_obj *obj;
-	struct pcie_dw_dmatest_dev *dmatest_dev = &s_dmatest_dev[cur_dmatest_dev];
+	struct pcie_dw_dmatest_dev *dmatest_dev;
 	int i;
+
+	dmatest_dev = devm_kzalloc(dev, sizeof(struct pcie_dw_dmatest_dev), GFP_KERNEL);
+	if (!dmatest_dev)
+		return ERR_PTR(-ENOMEM);
 
 	obj = devm_kzalloc(dev, sizeof(struct dma_trx_obj), GFP_KERNEL);
 	if (!obj)
@@ -232,13 +239,30 @@
 
 	/* Enable IRQ transfer as default */
 	dmatest_dev->irq_en = irq_en;
-	cur_dmatest_dev++;
+	s_dmatest_dev = dmatest_dev;
 
 	return obj;
 }
 
+void pcie_dw_dmatest_unregister(struct dma_trx_obj *obj)
+{
+	s_dmatest_dev = NULL;
+}
+
+int pcie_dw_wired_dma_frombus_block(struct dma_trx_obj *obj, u32 chn,
+				  u64 local_paddr, u64 bus_paddr, u32 size)
+{
+	return rk_pcie_local_dma_tobus_block(obj, chn, local_paddr, bus_paddr, size);
+}
+
+int pcie_dw_wired_dma_tobus_block(struct dma_trx_obj *obj, u32 chn,
+				u64 bus_paddr, u64 local_paddr, u32 size)
+{
+	return rk_pcie_local_dma_frombus_block(obj, chn, bus_paddr, local_paddr, size);
+}
+
 static int dma_test(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn,
-		    u32 bus_paddr, u32 local_paddr, u32 size, u32 loop, u8 rd_en, u8 wr_en)
+		    u64 bus_paddr, u64 local_paddr, u32 size, u32 loop, u8 rd_en, u8 wr_en)
 {
 	ktime_t start_time;
 	ktime_t end_time;
@@ -259,19 +283,19 @@
 	start_time = ktime_get();
 	for (i = 0; i < loop; i++) {
 		if (rd_en) {
-			if (is_rc)
-				rk_pcie_rc_dma_frombus(dmatest_dev, chn, local_paddr, bus_paddr, size);
+			if (is_wired)
+				pcie_dw_wired_dma_frombus_block(dmatest_dev->obj, chn, local_paddr, bus_paddr, size);
 			else
-				rk_pcie_ep_dma_frombus(dmatest_dev, chn, local_paddr, bus_paddr, size);
+				rk_pcie_local_dma_frombus_block(dmatest_dev->obj, chn, local_paddr, bus_paddr, size);
 			dma_sync_single_for_cpu(obj->dev, local_paddr, size, DMA_FROM_DEVICE);
 		}
 
 		if (wr_en) {
 			dma_sync_single_for_device(obj->dev, local_paddr, size, DMA_TO_DEVICE);
-			if (is_rc)
-				rk_pcie_rc_dma_tobus(dmatest_dev, chn, bus_paddr, local_paddr, size);
+			if (is_wired)
+				pcie_dw_wired_dma_tobus_block(dmatest_dev->obj, chn, bus_paddr, local_paddr, size);
 			else
-				rk_pcie_ep_dma_tobus(dmatest_dev, chn, bus_paddr, local_paddr, size);
+				rk_pcie_local_dma_tobus_block(dmatest_dev->obj, chn, bus_paddr, local_paddr, size);
 		}
 	}
 	end_time = ktime_get();
@@ -288,7 +312,7 @@
 
 static int dma_test_ch0(void *p)
 {
-	dma_test(&s_dmatest_dev[test_dev], 0, bus_addr, local_addr, test_size,
+	dma_test(s_dmatest_dev, 0, bus_addr, local_addr, test_size,
 		 cycles_count, rw_test & 0x1, (rw_test & 0x2) >> 1);
 
 	return 0;
@@ -298,10 +322,10 @@
 {
 	/* Test in different area with ch0 */
 	if (chn_en == 3)
-		dma_test(&s_dmatest_dev[test_dev], 1, bus_addr + test_size, local_addr + test_size, test_size,
+		dma_test(s_dmatest_dev, 1, bus_addr + test_size, local_addr + test_size, test_size,
 			 cycles_count, rw_test & 0x1, (rw_test & 0x2) >> 1);
 	else
-		dma_test(&s_dmatest_dev[test_dev], 1, bus_addr, local_addr, test_size,
+		dma_test(s_dmatest_dev, 1, bus_addr, local_addr, test_size,
 			 cycles_count, rw_test & 0x1, (rw_test & 0x2) >> 1);
 
 	return 0;
@@ -325,21 +349,19 @@
 {
 	char tmp[8];
 
-	if (!s_dmatest_dev[0].obj) {
+	if (!s_dmatest_dev) {
 		pr_err("dmatest dev not exits\n");
-		kfree(tmp);
 
 		return -1;
 	}
 
 	strncpy(tmp, val, 8);
-	if (!strncmp(tmp, "run", 3)) {
+	if (!strncmp(tmp, "run", 3))
 		dma_run();
-	} else if (!strncmp(tmp, "show", 4)) {
+	else if (!strncmp(tmp, "show", 4))
 		pcie_dw_dmatest_show();
-	} else {
+	else
 		pr_info("input error\n");
-	}
 
 	return 0;
 }
diff --git a/kernel/drivers/pci/controller/dwc/pcie-dw-dmatest.h b/kernel/drivers/pci/controller/dwc/pcie-dw-dmatest.h
index cfed7aa..07aa27c 100644
--- a/kernel/drivers/pci/controller/dwc/pcie-dw-dmatest.h
+++ b/kernel/drivers/pci/controller/dwc/pcie-dw-dmatest.h
@@ -10,11 +10,26 @@
 
 #if IS_ENABLED(CONFIG_PCIE_DW_DMATEST)
 struct dma_trx_obj *pcie_dw_dmatest_register(struct device *dev, bool irq_en);
+void pcie_dw_dmatest_unregister(struct dma_trx_obj *obj);
+int pcie_dw_wired_dma_frombus_block(struct dma_trx_obj *obj, u32 chn, u64 local_paddr, u64 bus_paddr, u32 size);
+int pcie_dw_wired_dma_tobus_block(struct dma_trx_obj *obj, u32 chn, u64 bus_paddr, u64 local_paddr, u32 size);
 #else
 static inline struct dma_trx_obj *pcie_dw_dmatest_register(struct device *dev, bool irq_en)
 {
 	return NULL;
 }
+
+static inline void pcie_dw_dmatest_unregister(struct dma_trx_obj *obj) { }
+
+static inline int pcie_dw_wired_dma_frombus_block(struct dma_trx_obj *obj, u32 chn, u64 local_paddr, u64 bus_paddr, u32 size)
+{
+	return -1;
+}
+
+static inline int pcie_dw_wired_dma_tobus_block(struct dma_trx_obj *obj, u32 chn, u64 bus_paddr, u64 local_paddr, u32 size)
+{
+	return -1;
+}
 #endif
 
 #endif
diff --git a/kernel/drivers/pci/controller/dwc/pcie-dw-ep-rockchip.c b/kernel/drivers/pci/controller/dwc/pcie-dw-ep-rockchip.c
index 31e84f7..1addd6c 100644
--- a/kernel/drivers/pci/controller/dwc/pcie-dw-ep-rockchip.c
+++ b/kernel/drivers/pci/controller/dwc/pcie-dw-ep-rockchip.c
@@ -94,11 +94,13 @@
 #define PCIE_ELBI_LOCAL_BASE		0x200e00
 
 #define PCIE_ELBI_APP_ELBI_INT_GEN0		0x0
-#define PCIE_ELBI_APP_ELBI_INT_GEN0_SIGIO	BIT(0)
+#define PCIE_ELBI_APP_ELBI_INT_GEN0_IRQ_USER	BIT(0)
 
 #define PCIE_ELBI_APP_ELBI_INT_GEN1		0x4
 
 #define PCIE_ELBI_LOCAL_ENABLE_OFF	0x8
+
+#define PCIE_ELBI_USER_DATA_OFF	0x10
 
 #define PCIE_DIRECT_SPEED_CHANGE	BIT(17)
 
@@ -131,12 +133,14 @@
 	u32				ib_target_size[PCIE_BAR_MAX_NUM];
 	void				*ib_target_base[PCIE_BAR_MAX_NUM];
 	struct dma_trx_obj		*dma_obj;
-	struct fasync_struct		*async;
 	phys_addr_t			dbi_base_physical;
 	struct pcie_ep_obj_info		*obj_info;
 	enum pcie_ep_mmap_resource	cur_mmap_res;
 	struct workqueue_struct		*hot_rst_wq;
 	struct work_struct		hot_rst_work;
+	struct mutex			file_mutex;
+	DECLARE_BITMAP(virtual_id_irq_bitmap, RKEP_EP_VIRTUAL_ID_MAX);
+	wait_queue_head_t wq_head;
 };
 
 struct rockchip_pcie_misc_dev {
@@ -528,18 +532,18 @@
 
 	/* Resize BAR0 4M 32bits, BAR2 64M 64bits-pref, BAR4 1MB 32bits */
 	bar = BAR_0;
-	dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0xfffff0);
+	dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0x40);
 	dw_pcie_writel_dbi(pci, resbar_base + 0x8 + bar * 0x8, 0x2c0);
 	rockchip_pcie_ep_set_bar_flag(rockchip, bar, PCI_BASE_ADDRESS_MEM_TYPE_32);
 
 	bar = BAR_2;
-	dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0xfffff0);
+	dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0x400);
 	dw_pcie_writel_dbi(pci, resbar_base + 0x8 + bar * 0x8, 0x6c0);
 	rockchip_pcie_ep_set_bar_flag(rockchip, bar,
 				      PCI_BASE_ADDRESS_MEM_PREFETCH | PCI_BASE_ADDRESS_MEM_TYPE_64);
 
 	bar = BAR_4;
-	dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0xfffff0);
+	dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0x10);
 	dw_pcie_writel_dbi(pci, resbar_base + 0x8 + bar * 0x8, 0xc0);
 	rockchip_pcie_ep_set_bar_flag(rockchip, bar, PCI_BASE_ADDRESS_MEM_TYPE_32);
 
@@ -642,6 +646,49 @@
 	rockchip_pcie_writel_apb(rockchip, BIT(interrupt_num), PCIE_CLIENT_MSI_GEN_CON);
 }
 
+static int rockchip_pcie_raise_irq_user(struct rockchip_pcie *rockchip, u32 index)
+{
+	if (index >= RKEP_EP_VIRTUAL_ID_MAX) {
+		dev_err(rockchip->pci.dev, "raise irq_user, virtual id %d out of range\n", index);
+
+		return -EINVAL;
+	}
+
+	mutex_lock(&rockchip->file_mutex);
+	rockchip->obj_info->irq_type_rc = OBJ_IRQ_USER;
+	rockchip->obj_info->irq_user_data_rc = index;
+	rockchip_pcie_raise_msi_irq(rockchip, PCIe_CLIENT_MSI_OBJ_IRQ);
+	mutex_unlock(&rockchip->file_mutex);
+
+	return 0;
+}
+
+static int rockchip_pcie_poll_irq_user(struct rockchip_pcie *rockchip, struct pcie_ep_obj_poll_virtual_id_cfg *cfg)
+{
+	u32 index = cfg->virtual_id;
+
+	if (index >= RKEP_EP_VIRTUAL_ID_MAX) {
+		dev_err(rockchip->pci.dev, "poll irq_user, virtual id %d out of range\n", index);
+
+		return -EINVAL;
+	}
+
+	cfg->poll_status = NSIGPOLL;
+	if (cfg->sync)
+		wait_event_interruptible(rockchip->wq_head,
+					 test_bit(index, rockchip->virtual_id_irq_bitmap));
+	else
+		wait_event_interruptible_timeout(rockchip->wq_head,
+						 test_bit(index, rockchip->virtual_id_irq_bitmap),
+						 cfg->timeout_ms);
+	if (test_and_clear_bit(index, rockchip->virtual_id_irq_bitmap))
+		cfg->poll_status = POLL_IN;
+
+	dev_dbg(rockchip->pci.dev, "poll virtual id %d, ret=%d\n", index, cfg->poll_status);
+
+	return 0;
+}
+
 static irqreturn_t rockchip_pcie_sys_irq_handler(int irq, void *arg)
 {
 	struct rockchip_pcie *rockchip = arg;
@@ -651,14 +698,19 @@
 	union int_status wr_status, rd_status;
 	union int_clear clears;
 	u32 reg, mask;
-	bool sigio = false;
 
 	/* ELBI helper, only check the valid bits, and discard the rest interrupts */
 	elbi_reg = dw_pcie_readl_dbi(pci, PCIE_ELBI_LOCAL_BASE + PCIE_ELBI_APP_ELBI_INT_GEN0);
-	if (elbi_reg & PCIE_ELBI_APP_ELBI_INT_GEN0_SIGIO) {
-		sigio = true;
-		rockchip->obj_info->irq_type_ep = OBJ_IRQ_ELBI;
+	if (elbi_reg & PCIE_ELBI_APP_ELBI_INT_GEN0_IRQ_USER) {
 		rockchip_pcie_elbi_clear(rockchip);
+
+		if (rockchip->obj_info->irq_type_ep == OBJ_IRQ_USER) {
+			reg = rockchip->obj_info->irq_user_data_ep;
+			if (reg < RKEP_EP_VIRTUAL_ID_MAX) {
+				set_bit(reg, rockchip->virtual_id_irq_bitmap);
+				wake_up_interruptible(&rockchip->wq_head);
+			}
+		}
 		goto out;
 	}
 
@@ -711,15 +763,9 @@
 		rockchip->obj_info->irq_type_ep = OBJ_IRQ_DMA;
 		rockchip->obj_info->dma_status_ep.wr |= wr_status.asdword;
 		rockchip->obj_info->dma_status_ep.rd |= rd_status.asdword;
-		sigio = true;
 	}
 
 out:
-	if (sigio) {
-		dev_dbg(rockchip->pci.dev, "SIGIO\n");
-		kill_fasync(&rockchip->async, SIGIO, POLL_IN);
-	}
-
 	reg = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_STATUS_MISC);
 	if (reg & BIT(2))
 		queue_work(rockchip->hot_rst_wq, &rockchip->hot_rst_work);
@@ -944,13 +990,6 @@
 	.link_up = rockchip_pcie_link_up,
 };
 
-static int pcie_ep_fasync(int fd, struct file *file, int mode)
-{
-	struct rockchip_pcie *rockchip = (struct rockchip_pcie *)file->private_data;
-
-	return fasync_helper(fd, file, mode, &rockchip->async);
-}
-
 static int pcie_ep_open(struct inode *inode, struct file *file)
 {
 	struct miscdevice *miscdev = file->private_data;
@@ -962,35 +1001,16 @@
 	return 0;
 }
 
-static int pcie_ep_release(struct inode *inode, struct file *file)
-{
-	return pcie_ep_fasync(-1, file, 0);
-}
-
 static long pcie_ep_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct rockchip_pcie *rockchip = (struct rockchip_pcie *)file->private_data;
-	struct pcie_ep_user_data msg;
 	struct pcie_ep_dma_cache_cfg cfg;
 	void __user *uarg = (void __user *)arg;
-	int i, ret;
+	struct pcie_ep_obj_poll_virtual_id_cfg poll_cfg;
 	enum pcie_ep_mmap_resource mmap_res;
+	int ret, index;
 
 	switch (cmd) {
-	case PCIE_DMA_GET_ELBI_DATA:
-		for (i = 4; i <= 6; i++)
-			msg.elbi_app_user[i - 4] = dw_pcie_readl_dbi(&rockchip->pci,
-								     PCIE_ELBI_LOCAL_BASE + i * 4);
-		for (i = 8; i <= 15; i++)
-			msg.elbi_app_user[i - 5] = dw_pcie_readl_dbi(&rockchip->pci,
-								     PCIE_ELBI_LOCAL_BASE + i * 4);
-
-		ret = copy_to_user(uarg, &msg, sizeof(msg));
-		if (ret) {
-			dev_err(rockchip->pci.dev, "failed to get elbi data\n");
-			return -EFAULT;
-		}
-		break;
 	case PCIE_DMA_CACHE_INVALIDE:
 		ret = copy_from_user(&cfg, uarg, sizeof(cfg));
 		if (ret) {
@@ -1013,18 +1033,8 @@
 		dw_pcie_writel_dbi(&rockchip->pci, PCIE_DMA_OFFSET + PCIE_DMA_RD_INT_MASK,
 				   0xffffffff);
 		break;
-	case PCIE_DMA_RAISE_MSI_OBJ_IRQ_USER:
-		rockchip->obj_info->irq_type_rc = OBJ_IRQ_USER;
+	case PCIE_EP_RAISE_MSI:
 		rockchip_pcie_raise_msi_irq(rockchip, PCIe_CLIENT_MSI_OBJ_IRQ);
-		break;
-	case PCIE_EP_GET_USER_INFO:
-		msg.bar0_phys_addr = rockchip->ib_target_address[0];
-
-		ret = copy_to_user(uarg, &msg, sizeof(msg));
-		if (ret) {
-			dev_err(rockchip->pci.dev, "failed to get elbi data\n");
-			return -EFAULT;
-		}
 		break;
 	case PCIE_EP_SET_MMAP_RESOURCE:
 		ret = copy_from_user(&mmap_res, uarg, sizeof(mmap_res));
@@ -1039,6 +1049,34 @@
 		}
 
 		rockchip->cur_mmap_res = mmap_res;
+		break;
+	case PCIE_EP_RAISE_IRQ_USER:
+		ret = copy_from_user(&index, uarg, sizeof(index));
+		if (ret) {
+			dev_err(rockchip->pci.dev,
+				"failed to get raise irq data copy from userspace\n");
+			return -EFAULT;
+		}
+
+		ret = rockchip_pcie_raise_irq_user(rockchip, index);
+		if (ret < 0)
+			return -EFAULT;
+		break;
+	case PCIE_EP_POLL_IRQ_USER:
+		ret = copy_from_user(&poll_cfg, uarg, sizeof(poll_cfg));
+		if (ret) {
+			dev_err(rockchip->pci.dev,
+				"failed to get poll irq data copy from userspace\n");
+
+			return -EFAULT;
+		}
+
+		ret = rockchip_pcie_poll_irq_user(rockchip, &poll_cfg);
+		if (ret < 0)
+			return -EFAULT;
+
+		if (copy_to_user(uarg, &poll_cfg, sizeof(poll_cfg)))
+			return -EFAULT;
 		break;
 	default:
 		break;
@@ -1100,9 +1138,7 @@
 static const struct file_operations pcie_ep_ops = {
 	.owner = THIS_MODULE,
 	.open = pcie_ep_open,
-	.release = pcie_ep_release,
 	.unlocked_ioctl = pcie_ep_ioctl,
-	.fasync = pcie_ep_fasync,
 	.mmap = pcie_ep_mmap,
 };
 
@@ -1265,12 +1301,14 @@
 		rockchip->dma_obj->config_dma_func = rockchip_pcie_config_dma_dwc;
 		rockchip->dma_obj->get_dma_status = rockchip_pcie_get_dma_status;
 	}
+	mutex_init(&rockchip->file_mutex);
 
 	/* Enable client ELBI interrupt */
 	rockchip_pcie_writel_apb(rockchip, 0x80000000, PCIE_CLIENT_INTR_MASK);
 	/* Enable ELBI interrupt */
 	rockchip_pcie_local_elbi_enable(rockchip);
 
+	init_waitqueue_head(&rockchip->wq_head);
 	ret = rockchip_pcie_request_sys_irq(rockchip, pdev);
 	if (ret)
 		goto deinit_phy;
diff --git a/kernel/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/kernel/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 4e5a225..e22295e 100644
--- a/kernel/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/kernel/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -8,6 +8,7 @@
  * Author: Simon Xue <xxm@rock-chips.com>
  */
 
+#include <dt-bindings/phy/phy.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/fs.h>
@@ -142,6 +143,7 @@
 #define PCIE_PL_ORDER_RULE_CTRL_OFF	0x8B4
 #define RK_PCIE_L2_TMOUT_US		5000
 #define RK_PCIE_HOTRESET_TMOUT_US	10000
+#define RK_PCIE_ENUM_HW_RETRYIES	2
 
 enum rk_pcie_ltssm_code {
 	S_L0 = 0x11,
@@ -202,6 +204,8 @@
 };
 
 #define to_rk_pcie(x)	dev_get_drvdata((x)->dev)
+static int rk_pcie_disable_power(struct rk_pcie *rk_pcie);
+static int rk_pcie_enable_power(struct rk_pcie *rk_pcie);
 
 static int rk_pcie_read(void __iomem *addr, int size, u32 *val)
 {
@@ -702,24 +706,6 @@
 	rk_pcie_writel_apb(rk_pcie, 0x0, 0xC000C);
 }
 
-static int rk_pcie_link_up(struct dw_pcie *pci)
-{
-	struct rk_pcie *rk_pcie = to_rk_pcie(pci);
-	u32 val;
-
-	if (rk_pcie->is_rk1808) {
-		val = rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_GENERAL_DEBUG);
-		if ((val & (PCIE_PHY_LINKUP | PCIE_DATA_LINKUP)) == 0x3)
-			return 1;
-	} else {
-		val = rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS);
-		if ((val & (RDLH_LINKUP | SMLH_LINKUP)) == 0x30000)
-			return 1;
-	}
-
-	return 0;
-}
-
 static void rk_pcie_enable_debug(struct rk_pcie *rk_pcie)
 {
 	if (!IS_ENABLED(CONFIG_DEBUG_FS))
@@ -758,6 +744,8 @@
 	int retries, power;
 	struct rk_pcie *rk_pcie = to_rk_pcie(pci);
 	bool std_rc = rk_pcie->mode == RK_PCIE_RC_TYPE && !rk_pcie->dma_obj;
+	int hw_retries = 0;
+	u32 ltssm;
 
 	/*
 	 * For standard RC, even if the link has been setup by firmware,
@@ -769,77 +757,92 @@
 		return 0;
 	}
 
-	/* Rest the device */
-	gpiod_set_value_cansleep(rk_pcie->rst_gpio, 0);
+	for (hw_retries = 0; hw_retries < RK_PCIE_ENUM_HW_RETRYIES; hw_retries++) {
+		/* Rest the device */
+		gpiod_set_value_cansleep(rk_pcie->rst_gpio, 0);
 
-	rk_pcie_disable_ltssm(rk_pcie);
-	rk_pcie_link_status_clear(rk_pcie);
-	rk_pcie_enable_debug(rk_pcie);
+		rk_pcie_disable_ltssm(rk_pcie);
+		rk_pcie_link_status_clear(rk_pcie);
+		rk_pcie_enable_debug(rk_pcie);
 
-	/* Enable client reset or link down interrupt */
-	rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK, 0x40000);
+		/* Enable client reset or link down interrupt */
+		rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK, 0x40000);
 
-	/* Enable LTSSM */
-	rk_pcie_enable_ltssm(rk_pcie);
+		/* Enable LTSSM */
+		rk_pcie_enable_ltssm(rk_pcie);
 
-	/*
-	 * In resume routine, function devices' resume function must be late after
-	 * controllers'. Some devices, such as Wi-Fi, need special IO setting before
-	 * finishing training. So there must be timeout here. These kinds of devices
-	 * need rescan devices by its driver when used. So no need to waste time waiting
-	 * for training pass.
-	 */
-	if (rk_pcie->in_suspend && rk_pcie->skip_scan_in_resume) {
-		rfkill_get_wifi_power_state(&power);
-		if (!power) {
-			gpiod_set_value_cansleep(rk_pcie->rst_gpio, 1);
-			return 0;
-		}
-	}
-
-	/*
-	 * PCIe requires the refclk to be stable for 100µs prior to releasing
-	 * PERST and T_PVPERL (Power stable to PERST# inactive) should be a
-	 * minimum of 100ms.  See table 2-4 in section 2.6.2 AC, the PCI Express
-	 * Card Electromechanical Specification 3.0. So 100ms in total is the min
-	 * requuirement here. We add a 200ms by default for sake of hoping everthings
-	 * work fine. If it doesn't, please add more in DT node by add rockchip,perst-inactive-ms.
-	 */
-	msleep(rk_pcie->perst_inactive_ms);
-	gpiod_set_value_cansleep(rk_pcie->rst_gpio, 1);
-
-	/*
-	 * Add this 1ms delay because we observe link is always up stably after it and
-	 * could help us save 20ms for scanning devices.
-	 */
-	usleep_range(1000, 1100);
-
-	for (retries = 0; retries < 100; retries++) {
-		if (dw_pcie_link_up(pci)) {
-			/*
-			 * We may be here in case of L0 in Gen1. But if EP is capable
-			 * of Gen2 or Gen3, Gen switch may happen just in this time, but
-			 * we keep on accessing devices in unstable link status. Given
-			 * that LTSSM max timeout is 24ms per period, we can wait a bit
-			 * more for Gen switch.
-			 */
-			msleep(50);
-			/* In case link drop after linkup, double check it */
-			if (dw_pcie_link_up(pci)) {
-				dev_info(pci->dev, "PCIe Link up, LTSSM is 0x%x\n",
-					 rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS));
-				rk_pcie_debug_dump(rk_pcie);
+		/*
+		 * In resume routine, function devices' resume function must be late after
+		 * controllers'. Some devices, such as Wi-Fi, need special IO setting before
+		 * finishing training. So there must be timeout here. These kinds of devices
+		 * need rescan devices by its driver when used. So no need to waste time waiting
+		 * for training pass.
+		 */
+		if (rk_pcie->in_suspend && rk_pcie->skip_scan_in_resume) {
+			rfkill_get_wifi_power_state(&power);
+			if (!power) {
+				gpiod_set_value_cansleep(rk_pcie->rst_gpio, 1);
 				return 0;
 			}
 		}
 
-		dev_info_ratelimited(pci->dev, "PCIe Linking... LTSSM is 0x%x\n",
-				     rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS));
-		rk_pcie_debug_dump(rk_pcie);
-		msleep(20);
-	}
+		/*
+		 * PCIe requires the refclk to be stable for 100µs prior to releasing
+		 * PERST and T_PVPERL (Power stable to PERST# inactive) should be a
+		 * minimum of 100ms.  See table 2-4 in section 2.6.2 AC, the PCI Express
+		 * Card Electromechanical Specification 3.0. So 100ms in total is the min
+		 * requuirement here. We add a 200ms by default for sake of hoping everthings
+		 * work fine. If it doesn't, please add more in DT node by add rockchip,perst-inactive-ms.
+		 */
+		msleep(rk_pcie->perst_inactive_ms);
+		gpiod_set_value_cansleep(rk_pcie->rst_gpio, 1);
 
-	dev_err(pci->dev, "PCIe Link Fail\n");
+		/*
+		 * Add this 1ms delay because we observe link is always up stably after it and
+		 * could help us save 20ms for scanning devices.
+		 */
+		usleep_range(1000, 1100);
+
+		for (retries = 0; retries < 100; retries++) {
+			if (dw_pcie_link_up(pci)) {
+				/*
+				 * We may be here in case of L0 in Gen1. But if EP is capable
+				 * of Gen2 or Gen3, Gen switch may happen just in this time, but
+				 * we keep on accessing devices in unstable link status. Given
+				 * that LTSSM max timeout is 24ms per period, we can wait a bit
+				 * more for Gen switch.
+				 */
+				msleep(50);
+				/* In case link drop after linkup, double check it */
+				if (dw_pcie_link_up(pci)) {
+					dev_info(pci->dev, "PCIe Link up, LTSSM is 0x%x\n",
+						rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS));
+					rk_pcie_debug_dump(rk_pcie);
+					return 0;
+				}
+			}
+
+			dev_info_ratelimited(pci->dev, "PCIe Linking... LTSSM is 0x%x\n",
+					rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS));
+			rk_pcie_debug_dump(rk_pcie);
+			msleep(20);
+		}
+
+		/*
+		 * In response to the situation where PCIe peripherals cannot be
+		 * enumerated due tosignal abnormalities, reset PERST# and reset
+		 * the peripheral power supply, then restart the enumeration.
+		 */
+		ltssm = rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS);
+		dev_err(pci->dev, "PCIe Link Fail, LTSSM is 0x%x, hw_retries=%d\n", ltssm, hw_retries);
+		if (ltssm >= 3 && !rk_pcie->is_signal_test) {
+			rk_pcie_disable_power(rk_pcie);
+			msleep(1000);
+			rk_pcie_enable_power(rk_pcie);
+		} else {
+			break;
+		}
+	}
 
 	return rk_pcie->is_signal_test == true ? 0 : -EINVAL;
 }
@@ -1129,8 +1132,8 @@
 	dw_pcie_setup_rc(pp);
 
 	/* Disable BAR0 BAR1 */
-	dw_pcie_writel_dbi(pci, PCIE_TYPE0_HDR_DBI2_OFFSET + 0x10 + BAR_0 * 4, 0);
-	dw_pcie_writel_dbi(pci, PCIE_TYPE0_HDR_DBI2_OFFSET + 0x10 + BAR_1 * 4, 0);
+	dw_pcie_writel_dbi2(pci, PCI_BASE_ADDRESS_0, 0x0);
+	dw_pcie_writel_dbi2(pci, PCI_BASE_ADDRESS_1, 0x0);
 
 	ret = rk_pcie_establish_link(pci);
 
@@ -1203,7 +1206,6 @@
 		return ret;
 	}
 
-	rk_pcie->pci->dbi_base2 = rk_pcie->pci->dbi_base + PCIE_TYPE0_HDR_DBI2_OFFSET;
 	rk_pcie->pci->atu_base = rk_pcie->pci->dbi_base + DEFAULT_DBI_ATU_OFFSET;
 	rk_pcie->pci->iatu_unroll_enabled = rk_pcie_iatu_unroll_enabled(rk_pcie->pci);
 
@@ -1263,6 +1265,7 @@
 		return PTR_ERR(rk_pcie->dbi_base);
 
 	rk_pcie->pci->dbi_base = rk_pcie->dbi_base;
+	rk_pcie->pci->dbi_base2 = rk_pcie->pci->dbi_base + PCIE_TYPE0_HDR_DBI2_OFFSET;
 
 	apb_base = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 						"pcie-apb");
@@ -1601,7 +1604,6 @@
 
 static const struct dw_pcie_ops dw_pcie_ops = {
 	.start_link = rk_pcie_establish_link,
-	.link_up = rk_pcie_link_up,
 };
 
 static int rk1808_pcie_fixup(struct rk_pcie *rk_pcie, struct device_node *np)
@@ -1988,6 +1990,7 @@
 
 	if (!IS_ERR_OR_NULL(rk_pcie->prsnt_gpio)) {
 		if (!gpiod_get_value(rk_pcie->prsnt_gpio)) {
+			dev_info(dev, "device isn't present\n");
 			ret = -ENODEV;
 			goto release_driver;
 		}
@@ -2354,6 +2357,12 @@
 no_l2:
 	rk_pcie_disable_ltssm(rk_pcie);
 
+	ret = phy_validate(rk_pcie->phy, PHY_TYPE_PCIE, 0, NULL);
+	if (ret && ret != -EOPNOTSUPP) {
+		dev_err(dev, "PHY is reused by other controller, check the dts!\n");
+		return ret;
+	}
+
 	/* make sure assert phy success */
 	usleep_range(200, 300);
 
diff --git a/kernel/drivers/pci/controller/dwc/pcie-qcom.c b/kernel/drivers/pci/controller/dwc/pcie-qcom.c
index 5fbd809..c68e142 100644
--- a/kernel/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/kernel/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1210,11 +1210,9 @@
 	val |= BIT(4);
 	writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
 
-	if (IS_ENABLED(CONFIG_PCI_MSI)) {
-		val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
-		val |= BIT(31);
-		writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
-	}
+	val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
+	val |= BIT(31);
+	writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
 
 	return 0;
 err_disable_clocks:
diff --git a/kernel/drivers/pci/controller/dwc/pcie-tegra194.c b/kernel/drivers/pci/controller/dwc/pcie-tegra194.c
index 1222f57..a215777 100644
--- a/kernel/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/kernel/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -239,6 +239,7 @@
 #define EP_STATE_ENABLED	1
 
 static const unsigned int pcie_gen_freq[] = {
+	GEN1_CORE_CLK_FREQ,	/* PCI_EXP_LNKSTA_CLS == 0; undefined */
 	GEN1_CORE_CLK_FREQ,
 	GEN2_CORE_CLK_FREQ,
 	GEN3_CORE_CLK_FREQ,
@@ -470,7 +471,11 @@
 
 	speed = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA) &
 		PCI_EXP_LNKSTA_CLS;
-	clk_set_rate(pcie->core_clk, pcie_gen_freq[speed - 1]);
+
+	if (speed >= ARRAY_SIZE(pcie_gen_freq))
+		speed = 0;
+
+	clk_set_rate(pcie->core_clk, pcie_gen_freq[speed]);
 
 	/* If EP doesn't advertise L1SS, just return */
 	val = dw_pcie_readl_dbi(pci, pcie->cfg_link_cap_l1sub);
@@ -973,7 +978,11 @@
 
 	speed = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA) &
 		PCI_EXP_LNKSTA_CLS;
-	clk_set_rate(pcie->core_clk, pcie_gen_freq[speed - 1]);
+
+	if (speed >= ARRAY_SIZE(pcie_gen_freq))
+		speed = 0;
+
+	clk_set_rate(pcie->core_clk, pcie_gen_freq[speed]);
 
 	tegra_pcie_enable_interrupts(pp);
 
diff --git a/kernel/drivers/pci/controller/pci-ftpci100.c b/kernel/drivers/pci/controller/pci-ftpci100.c
index aefef19..80cfea5 100644
--- a/kernel/drivers/pci/controller/pci-ftpci100.c
+++ b/kernel/drivers/pci/controller/pci-ftpci100.c
@@ -442,22 +442,12 @@
 	p->dev = dev;
 
 	/* Retrieve and enable optional clocks */
-	clk = devm_clk_get(dev, "PCLK");
+	clk = devm_clk_get_enabled(dev, "PCLK");
 	if (IS_ERR(clk))
 		return PTR_ERR(clk);
-	ret = clk_prepare_enable(clk);
-	if (ret) {
-		dev_err(dev, "could not prepare PCLK\n");
-		return ret;
-	}
-	p->bus_clk = devm_clk_get(dev, "PCICLK");
+	p->bus_clk = devm_clk_get_enabled(dev, "PCICLK");
 	if (IS_ERR(p->bus_clk))
 		return PTR_ERR(p->bus_clk);
-	ret = clk_prepare_enable(p->bus_clk);
-	if (ret) {
-		dev_err(dev, "could not prepare PCICLK\n");
-		return ret;
-	}
 
 	p->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(p->base))
diff --git a/kernel/drivers/pci/controller/pci-hyperv.c b/kernel/drivers/pci/controller/pci-hyperv.c
index 4353443..2d6c77d 100644
--- a/kernel/drivers/pci/controller/pci-hyperv.c
+++ b/kernel/drivers/pci/controller/pci-hyperv.c
@@ -520,19 +520,10 @@
 	struct hv_pcidev_description func[];
 };
 
-enum hv_pcichild_state {
-	hv_pcichild_init = 0,
-	hv_pcichild_requirements,
-	hv_pcichild_resourced,
-	hv_pcichild_ejecting,
-	hv_pcichild_maximum
-};
-
 struct hv_pci_dev {
 	/* List protected by pci_rescan_remove_lock */
 	struct list_head list_entry;
 	refcount_t refs;
-	enum hv_pcichild_state state;
 	struct pci_slot *pci_slot;
 	struct hv_pcidev_description desc;
 	bool reported_missing;
@@ -1237,6 +1228,11 @@
 	pbus = pdev->bus;
 	hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata);
 	int_desc = data->chip_data;
+	if (!int_desc) {
+		dev_warn(&hbus->hdev->device, "%s() can not unmask irq %u\n",
+			 __func__, data->irq);
+		return;
+	}
 
 	spin_lock_irqsave(&hbus->retarget_msi_interrupt_lock, flags);
 
@@ -1552,12 +1548,6 @@
 		}
 		hv_pci_onchannelcallback(hbus);
 		spin_unlock_irqrestore(&channel->sched_lock, flags);
-
-		if (hpdev->state == hv_pcichild_ejecting) {
-			dev_err_once(&hbus->hdev->device,
-				     "the device is being ejected\n");
-			goto enable_tasklet;
-		}
 
 		udelay(100);
 	}
@@ -2378,8 +2368,6 @@
 	hpdev = container_of(work, struct hv_pci_dev, wrk);
 	hbus = hpdev->hbus;
 
-	WARN_ON(hpdev->state != hv_pcichild_ejecting);
-
 	/*
 	 * Ejection can come before or after the PCI bus has been set up, so
 	 * attempt to find it and tear down the bus state, if it exists.  This
@@ -2438,7 +2426,6 @@
 		return;
 	}
 
-	hpdev->state = hv_pcichild_ejecting;
 	get_pcichild(hpdev);
 	INIT_WORK(&hpdev->wrk, hv_eject_device_work);
 	get_hvpcibus(hbus);
@@ -2842,8 +2829,10 @@
 	struct pci_bus_d0_entry *d0_entry;
 	struct hv_pci_compl comp_pkt;
 	struct pci_packet *pkt;
+	bool retry = true;
 	int ret;
 
+enter_d0_retry:
 	/*
 	 * Tell the host that the bus is ready to use, and moved into the
 	 * powered-on state.  This includes telling the host which region
@@ -2869,6 +2858,38 @@
 
 	if (ret)
 		goto exit;
+
+	/*
+	 * In certain case (Kdump) the pci device of interest was
+	 * not cleanly shut down and resource is still held on host
+	 * side, the host could return invalid device status.
+	 * We need to explicitly request host to release the resource
+	 * and try to enter D0 again.
+	 */
+	if (comp_pkt.completion_status < 0 && retry) {
+		retry = false;
+
+		dev_err(&hdev->device, "Retrying D0 Entry\n");
+
+		/*
+		 * Hv_pci_bus_exit() calls hv_send_resource_released()
+		 * to free up resources of its child devices.
+		 * In the kdump kernel we need to set the
+		 * wslot_res_allocated to 255 so it scans all child
+		 * devices to release resources allocated in the
+		 * normal kernel before panic happened.
+		 */
+		hbus->wslot_res_allocated = 255;
+
+		ret = hv_pci_bus_exit(hdev, true);
+
+		if (ret == 0) {
+			kfree(pkt);
+			goto enter_d0_retry;
+		}
+		dev_err(&hdev->device,
+			"Retrying D0 failed with ret %d\n", ret);
+	}
 
 	if (comp_pkt.completion_status < 0) {
 		dev_err(&hdev->device,
@@ -2911,6 +2932,24 @@
 			       0, VM_PKT_DATA_INBAND, 0);
 	if (!ret)
 		ret = wait_for_response(hdev, &comp);
+
+	/*
+	 * In the case of fast device addition/removal, it's possible that
+	 * vmbus_sendpacket() or wait_for_response() returns -ENODEV but we
+	 * already got a PCI_BUS_RELATIONS* message from the host and the
+	 * channel callback already scheduled a work to hbus->wq, which can be
+	 * running pci_devices_present_work() -> survey_child_resources() ->
+	 * complete(&hbus->survey_event), even after hv_pci_query_relations()
+	 * exits and the stack variable 'comp' is no longer valid; as a result,
+	 * a hang or a page fault may happen when the complete() calls
+	 * raw_spin_lock_irqsave(). Flush hbus->wq before we exit from
+	 * hv_pci_query_relations() to avoid the issues. Note: if 'ret' is
+	 * -ENODEV, there can't be any more work item scheduled to hbus->wq
+	 * after the flush_workqueue(): see vmbus_onoffer_rescind() ->
+	 * vmbus_reset_channel_cb(), vmbus_rescind_cleanup() ->
+	 * channel->rescind = true.
+	 */
+	flush_workqueue(hbus->wq);
 
 	return ret;
 }
@@ -3107,7 +3146,6 @@
 	struct hv_pcibus_device *hbus;
 	u16 dom_req, dom;
 	char *name;
-	bool enter_d0_retry = true;
 	int ret;
 
 	/*
@@ -3228,47 +3266,11 @@
 	if (ret)
 		goto free_fwnode;
 
-retry:
 	ret = hv_pci_query_relations(hdev);
 	if (ret)
 		goto free_irq_domain;
 
 	ret = hv_pci_enter_d0(hdev);
-	/*
-	 * In certain case (Kdump) the pci device of interest was
-	 * not cleanly shut down and resource is still held on host
-	 * side, the host could return invalid device status.
-	 * We need to explicitly request host to release the resource
-	 * and try to enter D0 again.
-	 * Since the hv_pci_bus_exit() call releases structures
-	 * of all its child devices, we need to start the retry from
-	 * hv_pci_query_relations() call, requesting host to send
-	 * the synchronous child device relations message before this
-	 * information is needed in hv_send_resources_allocated()
-	 * call later.
-	 */
-	if (ret == -EPROTO && enter_d0_retry) {
-		enter_d0_retry = false;
-
-		dev_err(&hdev->device, "Retrying D0 Entry\n");
-
-		/*
-		 * Hv_pci_bus_exit() calls hv_send_resources_released()
-		 * to free up resources of its child devices.
-		 * In the kdump kernel we need to set the
-		 * wslot_res_allocated to 255 so it scans all child
-		 * devices to release resources allocated in the
-		 * normal kernel before panic happened.
-		 */
-		hbus->wslot_res_allocated = 255;
-		ret = hv_pci_bus_exit(hdev, true);
-
-		if (ret == 0)
-			goto retry;
-
-		dev_err(&hdev->device,
-			"Retrying D0 failed with ret %d\n", ret);
-	}
 	if (ret)
 		goto free_irq_domain;
 
diff --git a/kernel/drivers/pci/controller/pcie-rockchip-ep.c b/kernel/drivers/pci/controller/pcie-rockchip-ep.c
index 379cde5..dba8bdc 100644
--- a/kernel/drivers/pci/controller/pcie-rockchip-ep.c
+++ b/kernel/drivers/pci/controller/pcie-rockchip-ep.c
@@ -125,6 +125,7 @@
 static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
 					 struct pci_epf_header *hdr)
 {
+	u32 reg;
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
 	struct rockchip_pcie *rockchip = &ep->rockchip;
 
@@ -137,8 +138,9 @@
 				    PCIE_CORE_CONFIG_VENDOR);
 	}
 
-	rockchip_pcie_write(rockchip, hdr->deviceid << 16,
-			    ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + PCI_VENDOR_ID);
+	reg = rockchip_pcie_read(rockchip, PCIE_EP_CONFIG_DID_VID);
+	reg = (reg & 0xFFFF) | (hdr->deviceid << 16);
+	rockchip_pcie_write(rockchip, reg, PCIE_EP_CONFIG_DID_VID);
 
 	rockchip_pcie_write(rockchip,
 			    hdr->revid |
@@ -312,15 +314,15 @@
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
 	struct rockchip_pcie *rockchip = &ep->rockchip;
-	u16 flags;
+	u32 flags;
 
 	flags = rockchip_pcie_read(rockchip,
 				   ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
 				   ROCKCHIP_PCIE_EP_MSI_CTRL_REG);
 	flags &= ~ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_MASK;
 	flags |=
-	   ((multi_msg_cap << 1) <<  ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET) |
-	   PCI_MSI_FLAGS_64BIT;
+	   (multi_msg_cap << ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET) |
+	   (PCI_MSI_FLAGS_64BIT << ROCKCHIP_PCIE_EP_MSI_FLAGS_OFFSET);
 	flags &= ~ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP;
 	rockchip_pcie_write(rockchip, flags,
 			    ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
@@ -332,7 +334,7 @@
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
 	struct rockchip_pcie *rockchip = &ep->rockchip;
-	u16 flags;
+	u32 flags;
 
 	flags = rockchip_pcie_read(rockchip,
 				   ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
@@ -345,48 +347,25 @@
 }
 
 static void rockchip_pcie_ep_assert_intx(struct rockchip_pcie_ep *ep, u8 fn,
-					 u8 intx, bool is_asserted)
+					 u8 intx, bool do_assert)
 {
 	struct rockchip_pcie *rockchip = &ep->rockchip;
-	u32 r = ep->max_regions - 1;
-	u32 offset;
-	u32 status;
-	u8 msg_code;
-
-	if (unlikely(ep->irq_pci_addr != ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR ||
-		     ep->irq_pci_fn != fn)) {
-		rockchip_pcie_prog_ep_ob_atu(rockchip, fn, r,
-					     AXI_WRAPPER_NOR_MSG,
-					     ep->irq_phys_addr, 0, 0);
-		ep->irq_pci_addr = ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR;
-		ep->irq_pci_fn = fn;
-	}
 
 	intx &= 3;
-	if (is_asserted) {
+
+	if (do_assert) {
 		ep->irq_pending |= BIT(intx);
-		msg_code = ROCKCHIP_PCIE_MSG_CODE_ASSERT_INTA + intx;
+		rockchip_pcie_write(rockchip,
+				    PCIE_CLIENT_INT_IN_ASSERT |
+				    PCIE_CLIENT_INT_PEND_ST_PEND,
+				    PCIE_CLIENT_LEGACY_INT_CTRL);
 	} else {
 		ep->irq_pending &= ~BIT(intx);
-		msg_code = ROCKCHIP_PCIE_MSG_CODE_DEASSERT_INTA + intx;
+		rockchip_pcie_write(rockchip,
+				    PCIE_CLIENT_INT_IN_DEASSERT |
+				    PCIE_CLIENT_INT_PEND_ST_NORMAL,
+				    PCIE_CLIENT_LEGACY_INT_CTRL);
 	}
-
-	status = rockchip_pcie_read(rockchip,
-				    ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
-				    ROCKCHIP_PCIE_EP_CMD_STATUS);
-	status &= ROCKCHIP_PCIE_EP_CMD_STATUS_IS;
-
-	if ((status != 0) ^ (ep->irq_pending != 0)) {
-		status ^= ROCKCHIP_PCIE_EP_CMD_STATUS_IS;
-		rockchip_pcie_write(rockchip, status,
-				    ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
-				    ROCKCHIP_PCIE_EP_CMD_STATUS);
-	}
-
-	offset =
-	   ROCKCHIP_PCIE_MSG_ROUTING(ROCKCHIP_PCIE_MSG_ROUTING_LOCAL_INTX) |
-	   ROCKCHIP_PCIE_MSG_CODE(msg_code) | ROCKCHIP_PCIE_MSG_NO_DATA;
-	writel(0, ep->irq_cpu_addr + offset);
 }
 
 static int rockchip_pcie_ep_send_legacy_irq(struct rockchip_pcie_ep *ep, u8 fn,
@@ -416,7 +395,7 @@
 					 u8 interrupt_num)
 {
 	struct rockchip_pcie *rockchip = &ep->rockchip;
-	u16 flags, mme, data, data_mask;
+	u32 flags, mme, data, data_mask;
 	u8 msi_count;
 	u64 pci_addr, pci_addr_mask = 0xff;
 
@@ -506,6 +485,7 @@
 	.linkup_notifier = false,
 	.msi_capable = true,
 	.msix_capable = false,
+	.align = 256,
 };
 
 static const struct pci_epc_features*
@@ -631,6 +611,9 @@
 
 	ep->irq_pci_addr = ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR;
 
+	rockchip_pcie_write(rockchip, PCIE_CLIENT_CONF_ENABLE,
+			    PCIE_CLIENT_CONFIG);
+
 	return 0;
 err_epc_mem_exit:
 	pci_epc_mem_exit(epc);
diff --git a/kernel/drivers/pci/controller/pcie-rockchip.c b/kernel/drivers/pci/controller/pcie-rockchip.c
index 92cced7..064e54d 100644
--- a/kernel/drivers/pci/controller/pcie-rockchip.c
+++ b/kernel/drivers/pci/controller/pcie-rockchip.c
@@ -14,6 +14,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of_pci.h>
 #include <linux/phy/phy.h>
@@ -154,6 +155,12 @@
 }
 EXPORT_SYMBOL_GPL(rockchip_pcie_parse_dt);
 
+#define rockchip_pcie_read_addr(addr) rockchip_pcie_read(rockchip, addr)
+/* 100 ms max wait time for PHY PLLs to lock */
+#define RK_PHY_PLL_LOCK_TIMEOUT_US 100000
+/* Sleep should be less than 20ms */
+#define RK_PHY_PLL_LOCK_SLEEP_US 1000
+
 int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
 {
 	struct device *dev = rockchip->dev;
@@ -255,6 +262,16 @@
 		}
 	}
 
+	err = readx_poll_timeout(rockchip_pcie_read_addr,
+				 PCIE_CLIENT_SIDE_BAND_STATUS,
+				 regs, !(regs & PCIE_CLIENT_PHY_ST),
+				 RK_PHY_PLL_LOCK_SLEEP_US,
+				 RK_PHY_PLL_LOCK_TIMEOUT_US);
+	if (err) {
+		dev_err(dev, "PHY PLLs could not lock, %d\n", err);
+		goto err_power_off_phy;
+	}
+
 	/*
 	 * Please don't reorder the deassert sequence of the following
 	 * four reset pins.
diff --git a/kernel/drivers/pci/controller/pcie-rockchip.h b/kernel/drivers/pci/controller/pcie-rockchip.h
index e34d332..44039bf 100644
--- a/kernel/drivers/pci/controller/pcie-rockchip.h
+++ b/kernel/drivers/pci/controller/pcie-rockchip.h
@@ -38,6 +38,13 @@
 #define   PCIE_CLIENT_MODE_EP            HIWORD_UPDATE(0x0040, 0)
 #define   PCIE_CLIENT_GEN_SEL_1		  HIWORD_UPDATE(0x0080, 0)
 #define   PCIE_CLIENT_GEN_SEL_2		  HIWORD_UPDATE_BIT(0x0080)
+#define PCIE_CLIENT_LEGACY_INT_CTRL	(PCIE_CLIENT_BASE + 0x0c)
+#define   PCIE_CLIENT_INT_IN_ASSERT		HIWORD_UPDATE_BIT(0x0002)
+#define   PCIE_CLIENT_INT_IN_DEASSERT		HIWORD_UPDATE(0x0002, 0)
+#define   PCIE_CLIENT_INT_PEND_ST_PEND		HIWORD_UPDATE_BIT(0x0001)
+#define   PCIE_CLIENT_INT_PEND_ST_NORMAL	HIWORD_UPDATE(0x0001, 0)
+#define PCIE_CLIENT_SIDE_BAND_STATUS	(PCIE_CLIENT_BASE + 0x20)
+#define   PCIE_CLIENT_PHY_ST			BIT(12)
 #define PCIE_CLIENT_DEBUG_OUT_0		(PCIE_CLIENT_BASE + 0x3c)
 #define   PCIE_CLIENT_DEBUG_LTSSM_MASK		GENMASK(5, 0)
 #define   PCIE_CLIENT_DEBUG_LTSSM_L0		0x10
@@ -147,6 +154,8 @@
 #define PCIE_RC_RP_ATS_BASE		0x400000
 #define PCIE_RC_CONFIG_NORMAL_BASE	0x800000
 #define PCIE_RC_CONFIG_BASE		0xa00000
+#define PCIE_EP_CONFIG_BASE		0xa00000
+#define PCIE_EP_CONFIG_DID_VID		(PCIE_EP_CONFIG_BASE + 0x00)
 #define PCIE_RC_CONFIG_RID_CCR		(PCIE_RC_CONFIG_BASE + 0x08)
 #define   PCIE_RC_CONFIG_SCC_SHIFT		16
 #define PCIE_RC_CONFIG_DCR		(PCIE_RC_CONFIG_BASE + 0xc4)
@@ -240,6 +249,7 @@
 #define ROCKCHIP_PCIE_EP_CMD_STATUS			0x4
 #define   ROCKCHIP_PCIE_EP_CMD_STATUS_IS		BIT(19)
 #define ROCKCHIP_PCIE_EP_MSI_CTRL_REG			0x90
+#define   ROCKCHIP_PCIE_EP_MSI_FLAGS_OFFSET		16
 #define   ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET		17
 #define   ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_MASK		GENMASK(19, 17)
 #define   ROCKCHIP_PCIE_EP_MSI_CTRL_MME_OFFSET		20
@@ -247,7 +257,6 @@
 #define   ROCKCHIP_PCIE_EP_MSI_CTRL_ME				BIT(16)
 #define   ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP	BIT(24)
 #define ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR				0x1
-#define ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR		0x3
 #define ROCKCHIP_PCIE_EP_FUNC_BASE(fn)	(((fn) << 12) & GENMASK(19, 12))
 #define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \
 	(PCIE_RC_RP_ATS_BASE + 0x0840 + (fn) * 0x0040 + (bar) * 0x0008)
diff --git a/kernel/drivers/pci/controller/rockchip-pcie-dma.h b/kernel/drivers/pci/controller/rockchip-pcie-dma.h
index e9da2d0..f06222e 100644
--- a/kernel/drivers/pci/controller/rockchip-pcie-dma.h
+++ b/kernel/drivers/pci/controller/rockchip-pcie-dma.h
@@ -20,9 +20,29 @@
 #define PCIE_DMA_DATA_FREE_ACK_TABLE_OFFSET	0x10
 #define PCIE_DMA_DATA_READ_REMOTE_TABLE_OFFSET	0x18
 
+/* DMA linked list register filed */
+#define PCIE_DWC_DMA_CB				BIT(0)
+#define PCIE_DWC_DMA_TCB			BIT(1)
+#define PCIE_DWC_DMA_LLP			BIT(2)
+#define PCIE_DWC_DMA_LIE			BIT(3)
+#define PCIE_DWC_DMA_RIE			BIT(4)
+#define PCIE_DWC_DMA_CCS			BIT(8)
+#define PCIE_DWC_DMA_LLE			BIT(9)
+
+#define SET_LL_32(ll, value) \
+	writel(value, ll)
+
+#define SET_LL_64(ll, value) \
+	writeq(value, ll)
+
 enum dma_dir {
 	DMA_FROM_BUS,
 	DMA_TO_BUS,
+};
+
+enum dma_mode {
+	RK_PCIE_DMA_BLOCK,
+	RK_PCIE_DMA_LL,
 };
 
 /**
@@ -155,7 +175,39 @@
 	phys_addr_t			local;
 	phys_addr_t			bus;
 	size_t				buf_size;
+	u32				dma_mode;
 };
+
+struct rk_edma_lli {
+	u32 control;
+	u32 transfer_size;
+	union {
+		u64 reg;
+		struct {
+			u32 lsb;
+			u32 msb;
+		};
+	} sar;
+	union {
+		u64 reg;
+		struct {
+			u32 lsb;
+			u32 msb;
+		};
+	} dar;
+} __packed;
+
+struct rk_edma_llp {
+	u32 control;
+	u32 reserved;
+	union {
+		u64 reg;
+		struct {
+			u32 lsb;
+			u32 msb;
+		};
+	} llp;
+} __packed;
 
 struct dma_trx_obj {
 	struct device			*dev;
@@ -192,6 +244,7 @@
 	void				(*config_dma_func)(struct dma_table *table);
 	int				(*get_dma_status)(struct dma_trx_obj *obj, u8 chn, enum dma_dir dir);
 	int				(*cb)(struct dma_trx_obj *obj, u32 chn, enum dma_dir dir);
+	void				(*dma_debug)(struct dma_trx_obj *obj, struct dma_table *table);
 	ktime_t				begin;
 	ktime_t				end;
 	u64				cache_time_total;
diff --git a/kernel/drivers/pci/endpoint/functions/pci-epf-test.c b/kernel/drivers/pci/endpoint/functions/pci-epf-test.c
index ddfeca9..ef52f50 100644
--- a/kernel/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/kernel/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -870,7 +870,7 @@
 	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 {
diff --git a/kernel/drivers/pci/hotplug/acpiphp_glue.c b/kernel/drivers/pci/hotplug/acpiphp_glue.c
index f031302..0a37967 100644
--- a/kernel/drivers/pci/hotplug/acpiphp_glue.c
+++ b/kernel/drivers/pci/hotplug/acpiphp_glue.c
@@ -503,12 +503,15 @@
 				if (pass && dev->subordinate) {
 					check_hotplug_bridge(slot, dev);
 					pcibios_resource_survey_bus(dev->subordinate);
-					__pci_bus_size_bridges(dev->subordinate,
-							       &add_list);
+					if (pci_is_root_bus(bus))
+						__pci_bus_size_bridges(dev->subordinate, &add_list);
 				}
 			}
 		}
-		__pci_bus_assign_resources(bus, &add_list, NULL);
+		if (pci_is_root_bus(bus))
+			__pci_bus_assign_resources(bus, &add_list, NULL);
+		else
+			pci_assign_unassigned_bridge_resources(bus->self);
 	}
 
 	acpiphp_sanitize_bus(bus);
diff --git a/kernel/drivers/pci/hotplug/pciehp_ctrl.c b/kernel/drivers/pci/hotplug/pciehp_ctrl.c
index 529c348..32baba1 100644
--- a/kernel/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/kernel/drivers/pci/hotplug/pciehp_ctrl.c
@@ -256,6 +256,14 @@
 	present = pciehp_card_present(ctrl);
 	link_active = pciehp_check_link_active(ctrl);
 	if (present <= 0 && link_active <= 0) {
+		if (ctrl->state == BLINKINGON_STATE) {
+			ctrl->state = OFF_STATE;
+			cancel_delayed_work(&ctrl->button_work);
+			pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
+					      INDICATOR_NOOP);
+			ctrl_info(ctrl, "Slot(%s): Card not present\n",
+				  slot_name(ctrl));
+		}
 		mutex_unlock(&ctrl->state_lock);
 		return;
 	}
diff --git a/kernel/drivers/pci/hotplug/pciehp_hpc.c b/kernel/drivers/pci/hotplug/pciehp_hpc.c
index dda9523..75c6c72 100644
--- a/kernel/drivers/pci/hotplug/pciehp_hpc.c
+++ b/kernel/drivers/pci/hotplug/pciehp_hpc.c
@@ -332,17 +332,11 @@
 static int __pciehp_link_set(struct controller *ctrl, bool enable)
 {
 	struct pci_dev *pdev = ctrl_dev(ctrl);
-	u16 lnk_ctrl;
 
-	pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &lnk_ctrl);
+	pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL,
+					   PCI_EXP_LNKCTL_LD,
+					   enable ? 0 : PCI_EXP_LNKCTL_LD);
 
-	if (enable)
-		lnk_ctrl &= ~PCI_EXP_LNKCTL_LD;
-	else
-		lnk_ctrl |= PCI_EXP_LNKCTL_LD;
-
-	pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, lnk_ctrl);
-	ctrl_dbg(ctrl, "%s: lnk_ctrl = %x\n", __func__, lnk_ctrl);
 	return 0;
 }
 
diff --git a/kernel/drivers/pci/hotplug/pciehp_pci.c b/kernel/drivers/pci/hotplug/pciehp_pci.c
index d17f3bf..ad12515 100644
--- a/kernel/drivers/pci/hotplug/pciehp_pci.c
+++ b/kernel/drivers/pci/hotplug/pciehp_pci.c
@@ -63,7 +63,14 @@
 
 	pci_assign_unassigned_bridge_resources(bridge);
 	pcie_bus_configure_settings(parent);
+
+	/*
+	 * Release reset_lock during driver binding
+	 * to avoid AB-BA deadlock with device_lock.
+	 */
+	up_read(&ctrl->reset_lock);
 	pci_bus_add_devices(parent);
+	down_read_nested(&ctrl->reset_lock, ctrl->depth);
 
  out:
 	pci_unlock_rescan_remove();
@@ -104,7 +111,15 @@
 	list_for_each_entry_safe_reverse(dev, temp, &parent->devices,
 					 bus_list) {
 		pci_dev_get(dev);
+
+		/*
+		 * Release reset_lock during driver unbinding
+		 * to avoid AB-BA deadlock with device_lock.
+		 */
+		up_read(&ctrl->reset_lock);
 		pci_stop_and_remove_bus_device(dev);
+		down_read_nested(&ctrl->reset_lock, ctrl->depth);
+
 		/*
 		 * Ensure that no new Requests will be generated from
 		 * the device.
diff --git a/kernel/drivers/pci/irq.c b/kernel/drivers/pci/irq.c
index 12ecd0a..0050e8f 100644
--- a/kernel/drivers/pci/irq.c
+++ b/kernel/drivers/pci/irq.c
@@ -44,6 +44,8 @@
 	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);
diff --git a/kernel/drivers/pci/pci-driver.c b/kernel/drivers/pci/pci-driver.c
index 8b587fc..c22cc20 100644
--- a/kernel/drivers/pci/pci-driver.c
+++ b/kernel/drivers/pci/pci-driver.c
@@ -911,7 +911,7 @@
 	pcie_pme_root_status_cleanup(pci_dev);
 
 	if (!skip_bus_pm && prev_state == PCI_D3cold)
-		pci_bridge_wait_for_secondary_bus(pci_dev);
+		pci_bridge_wait_for_secondary_bus(pci_dev, "resume", PCI_RESET_WAIT);
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return 0;
@@ -1298,7 +1298,7 @@
 	pci_pm_default_resume(pci_dev);
 
 	if (prev_state == PCI_D3cold)
-		pci_bridge_wait_for_secondary_bus(pci_dev);
+		pci_bridge_wait_for_secondary_bus(pci_dev, "resume", PCI_RESET_WAIT);
 
 	if (pm && pm->runtime_resume)
 		error = pm->runtime_resume(dev);
diff --git a/kernel/drivers/pci/pci-sysfs.c b/kernel/drivers/pci/pci-sysfs.c
index 8f845b8..bc1cad0 100644
--- a/kernel/drivers/pci/pci-sysfs.c
+++ b/kernel/drivers/pci/pci-sysfs.c
@@ -1141,11 +1141,9 @@
 
 	sysfs_bin_attr_init(res_attr);
 	if (write_combine) {
-		pdev->res_attr_wc[num] = res_attr;
 		sprintf(res_attr_name, "resource%d_wc", num);
 		res_attr->mmap = pci_mmap_resource_wc;
 	} else {
-		pdev->res_attr[num] = res_attr;
 		sprintf(res_attr_name, "resource%d", num);
 		if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
 			res_attr->read = pci_read_resource_io;
@@ -1161,10 +1159,17 @@
 	res_attr->size = pci_resource_len(pdev, num);
 	res_attr->private = (void *)(unsigned long)num;
 	retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
-	if (retval)
+	if (retval) {
 		kfree(res_attr);
+		return retval;
+	}
 
-	return retval;
+	if (write_combine)
+		pdev->res_attr_wc[num] = res_attr;
+	else
+		pdev->res_attr[num] = res_attr;
+
+	return 0;
 }
 
 /**
diff --git a/kernel/drivers/pci/pci.c b/kernel/drivers/pci/pci.c
index c909cc7..e7b45d8 100644
--- a/kernel/drivers/pci/pci.c
+++ b/kernel/drivers/pci/pci.c
@@ -164,9 +164,6 @@
 }
 __setup("pcie_port_pm=", pcie_port_pm_setup);
 
-/* Time to wait after a reset for device to become responsive */
-#define PCIE_RESET_READY_POLL_MS 60000
-
 /**
  * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
  * @bus: pointer to PCI bus structure to search
@@ -1228,7 +1225,7 @@
 			return -ENOTTY;
 		}
 
-		if (delay > 1000)
+		if (delay > PCI_RESET_WAIT)
 			pci_info(dev, "not ready %dms after %s; waiting\n",
 				 delay - 1, reset_type);
 
@@ -1237,7 +1234,7 @@
 		pci_read_config_dword(dev, PCI_COMMAND, &id);
 	}
 
-	if (delay > 1000)
+	if (delay > PCI_RESET_WAIT)
 		pci_info(dev, "ready %dms after %s\n", delay - 1,
 			 reset_type);
 
@@ -2840,13 +2837,13 @@
 	{
 		/*
 		 * Downstream device is not accessible after putting a root port
-		 * into D3cold and back into D0 on Elo i2.
+		 * into D3cold and back into D0 on Elo Continental Z2 board
 		 */
-		.ident = "Elo i2",
+		.ident = "Elo Continental Z2",
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Elo Touch Solutions"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Elo i2"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "RevB"),
+			DMI_MATCH(DMI_BOARD_VENDOR, "Elo Touch Solutions"),
+			DMI_MATCH(DMI_BOARD_NAME, "Geminilake"),
+			DMI_MATCH(DMI_BOARD_VERSION, "Continental Z2"),
 		},
 	},
 #endif
@@ -4799,24 +4796,31 @@
 /**
  * pci_bridge_wait_for_secondary_bus - Wait for secondary bus to be accessible
  * @dev: PCI bridge
+ * @reset_type: reset type in human-readable form
+ * @timeout: maximum time to wait for devices on secondary bus (milliseconds)
  *
  * Handle necessary delays before access to the devices on the secondary
- * side of the bridge are permitted after D3cold to D0 transition.
+ * side of the bridge are permitted after D3cold to D0 transition
+ * or Conventional Reset.
  *
  * For PCIe this means the delays in PCIe 5.0 section 6.6.1. For
  * conventional PCI it means Tpvrh + Trhfa specified in PCI 3.0 section
  * 4.3.2.
+ *
+ * Return 0 on success or -ENOTTY if the first device on the secondary bus
+ * failed to become accessible.
  */
-void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev)
+int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type,
+				      int timeout)
 {
 	struct pci_dev *child;
 	int delay;
 
 	if (pci_dev_is_disconnected(dev))
-		return;
+		return 0;
 
-	if (!pci_is_bridge(dev) || !dev->bridge_d3)
-		return;
+	if (!pci_is_bridge(dev))
+		return 0;
 
 	down_read(&pci_bus_sem);
 
@@ -4828,14 +4832,14 @@
 	 */
 	if (!dev->subordinate || list_empty(&dev->subordinate->devices)) {
 		up_read(&pci_bus_sem);
-		return;
+		return 0;
 	}
 
 	/* Take d3cold_delay requirements into account */
 	delay = pci_bus_max_d3cold_delay(dev->subordinate);
 	if (!delay) {
 		up_read(&pci_bus_sem);
-		return;
+		return 0;
 	}
 
 	child = list_first_entry(&dev->subordinate->devices, struct pci_dev,
@@ -4844,14 +4848,12 @@
 
 	/*
 	 * Conventional PCI and PCI-X we need to wait Tpvrh + Trhfa before
-	 * accessing the device after reset (that is 1000 ms + 100 ms). In
-	 * practice this should not be needed because we don't do power
-	 * management for them (see pci_bridge_d3_possible()).
+	 * accessing the device after reset (that is 1000 ms + 100 ms).
 	 */
 	if (!pci_is_pcie(dev)) {
 		pci_dbg(dev, "waiting %d ms for secondary bus\n", 1000 + delay);
 		msleep(1000 + delay);
-		return;
+		return 0;
 	}
 
 	/*
@@ -4868,11 +4870,11 @@
 	 * configuration requests if we only wait for 100 ms (see
 	 * https://bugzilla.kernel.org/show_bug.cgi?id=203885).
 	 *
-	 * Therefore we wait for 100 ms and check for the device presence.
-	 * If it is still not present give it an additional 100 ms.
+	 * Therefore we wait for 100 ms and check for the device presence
+	 * until the timeout expires.
 	 */
 	if (!pcie_downstream_port(dev))
-		return;
+		return 0;
 
 	if (pcie_get_speed_cap(dev) <= PCIE_SPEED_5_0GT) {
 		pci_dbg(dev, "waiting %d ms for downstream link\n", delay);
@@ -4883,14 +4885,11 @@
 		if (!pcie_wait_for_link_delay(dev, true, delay)) {
 			/* Did not train, no need to wait any further */
 			pci_info(dev, "Data Link Layer Link Active not set in 1000 msec\n");
-			return;
+			return -ENOTTY;
 		}
 	}
 
-	if (!pci_device_is_present(child)) {
-		pci_dbg(child, "waiting additional %d ms to become accessible\n", delay);
-		msleep(delay);
-	}
+	return pci_dev_wait(child, reset_type, timeout - delay);
 }
 
 void pci_reset_secondary_bus(struct pci_dev *dev)
@@ -4909,15 +4908,6 @@
 
 	ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
 	pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl);
-
-	/*
-	 * Trhfa for conventional PCI is 2^25 clock cycles.
-	 * Assuming a minimum 33MHz clock this results in a 1s
-	 * delay before we can consider subordinate devices to
-	 * be re-initialized.  PCIe has some ways to shorten this,
-	 * but we don't make use of them yet.
-	 */
-	ssleep(1);
 }
 
 void __weak pcibios_reset_secondary_bus(struct pci_dev *dev)
@@ -4936,7 +4926,8 @@
 {
 	pcibios_reset_secondary_bus(dev);
 
-	return pci_dev_wait(dev, "bus reset", PCIE_RESET_READY_POLL_MS);
+	return pci_bridge_wait_for_secondary_bus(dev, "bus reset",
+						 PCIE_RESET_READY_POLL_MS);
 }
 EXPORT_SYMBOL_GPL(pci_bridge_secondary_bus_reset);
 
@@ -6159,6 +6150,8 @@
 {
 	u32 v;
 
+	/* Check PF if pdev is a VF, since VF Vendor/Device IDs are 0xffff */
+	pdev = pci_physfn(pdev);
 	if (pci_dev_is_disconnected(pdev))
 		return false;
 	return pci_bus_read_dev_vendor_id(pdev->bus, pdev->devfn, &v, 0);
diff --git a/kernel/drivers/pci/pci.h b/kernel/drivers/pci/pci.h
index 4e38fdb..43f5082 100644
--- a/kernel/drivers/pci/pci.h
+++ b/kernel/drivers/pci/pci.h
@@ -48,6 +48,19 @@
 #define PCI_PM_D3HOT_WAIT       10	/* msec */
 #define PCI_PM_D3COLD_WAIT      100	/* msec */
 
+/*
+ * Following exit from Conventional Reset, devices must be ready within 1 sec
+ * (PCIe r6.0 sec 6.6.1).  A D3cold to D0 transition implies a Conventional
+ * Reset (PCIe r6.0 sec 5.8).
+ */
+#define PCI_RESET_WAIT		1000	/* msec */
+/*
+ * Devices may extend the 1 sec period through Request Retry Status completions
+ * (PCIe r6.0 sec 2.3.1).  The spec does not provide an upper limit, but 60 sec
+ * ought to be enough for any device to become responsive.
+ */
+#define PCIE_RESET_READY_POLL_MS 60000	/* msec */
+
 /**
  * struct pci_platform_pm_ops - Firmware PM callbacks
  *
@@ -109,7 +122,8 @@
 void pci_free_cap_save_buffers(struct pci_dev *dev);
 bool pci_bridge_d3_possible(struct pci_dev *dev);
 void pci_bridge_d3_update(struct pci_dev *dev);
-void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev);
+int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type,
+				      int timeout);
 
 static inline void pci_wakeup_event(struct pci_dev *dev)
 {
@@ -357,53 +371,36 @@
  * @dev - pci device to set new error_state
  * @new - the state we want dev to be in
  *
- * Must be called with device_lock held.
+ * If the device is experiencing perm_failure, it has to remain in that state.
+ * Any other transition is allowed.
  *
  * Returns true if state has been changed to the requested state.
  */
 static inline bool pci_dev_set_io_state(struct pci_dev *dev,
 					pci_channel_state_t new)
 {
-	bool changed = false;
+	pci_channel_state_t old;
 
-	device_lock_assert(&dev->dev);
 	switch (new) {
 	case pci_channel_io_perm_failure:
-		switch (dev->error_state) {
-		case pci_channel_io_frozen:
-		case pci_channel_io_normal:
-		case pci_channel_io_perm_failure:
-			changed = true;
-			break;
-		}
-		break;
+		xchg(&dev->error_state, pci_channel_io_perm_failure);
+		return true;
 	case pci_channel_io_frozen:
-		switch (dev->error_state) {
-		case pci_channel_io_frozen:
-		case pci_channel_io_normal:
-			changed = true;
-			break;
-		}
-		break;
+		old = cmpxchg(&dev->error_state, pci_channel_io_normal,
+			      pci_channel_io_frozen);
+		return old != pci_channel_io_perm_failure;
 	case pci_channel_io_normal:
-		switch (dev->error_state) {
-		case pci_channel_io_frozen:
-		case pci_channel_io_normal:
-			changed = true;
-			break;
-		}
-		break;
+		old = cmpxchg(&dev->error_state, pci_channel_io_frozen,
+			      pci_channel_io_normal);
+		return old != pci_channel_io_perm_failure;
+	default:
+		return false;
 	}
-	if (changed)
-		dev->error_state = new;
-	return changed;
 }
 
 static inline int pci_dev_set_disconnected(struct pci_dev *dev, void *unused)
 {
-	device_lock(&dev->dev);
 	pci_dev_set_io_state(dev, pci_channel_io_perm_failure);
-	device_unlock(&dev->dev);
 
 	return 0;
 }
diff --git a/kernel/drivers/pci/pcie/aspm.c b/kernel/drivers/pci/pcie/aspm.c
index ac0557a..ef6f0ce 100644
--- a/kernel/drivers/pci/pcie/aspm.c
+++ b/kernel/drivers/pci/pcie/aspm.c
@@ -192,11 +192,38 @@
 	link->clkpm_disable = blacklist ? 1 : 0;
 }
 
-static bool pcie_retrain_link(struct pcie_link_state *link)
+static int pcie_wait_for_retrain(struct pci_dev *pdev)
 {
-	struct pci_dev *parent = link->pdev;
 	unsigned long end_jiffies;
 	u16 reg16;
+
+	/* Wait for Link Training to be cleared by hardware */
+	end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT;
+	do {
+		pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &reg16);
+		if (!(reg16 & PCI_EXP_LNKSTA_LT))
+			return 0;
+		msleep(1);
+	} while (time_before(jiffies, end_jiffies));
+
+	return -ETIMEDOUT;
+}
+
+static int pcie_retrain_link(struct pcie_link_state *link)
+{
+	struct pci_dev *parent = link->pdev;
+	int rc;
+	u16 reg16;
+
+	/*
+	 * Ensure the updated LNKCTL parameters are used during link
+	 * training by checking that there is no ongoing link training to
+	 * avoid LTSSM race as recommended in Implementation Note at the
+	 * end of PCIe r6.0.1 sec 7.5.3.7.
+	 */
+	rc = pcie_wait_for_retrain(parent);
+	if (rc)
+		return rc;
 
 	pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &reg16);
 	reg16 |= PCI_EXP_LNKCTL_RL;
@@ -211,15 +238,7 @@
 		pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16);
 	}
 
-	/* Wait for link training end. Break out after waiting for timeout */
-	end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT;
-	do {
-		pcie_capability_read_word(parent, PCI_EXP_LNKSTA, &reg16);
-		if (!(reg16 & PCI_EXP_LNKSTA_LT))
-			break;
-		msleep(1);
-	} while (time_before(jiffies, end_jiffies));
-	return !(reg16 & PCI_EXP_LNKSTA_LT);
+	return pcie_wait_for_retrain(parent);
 }
 
 /*
@@ -230,7 +249,7 @@
 static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
 {
 	int same_clock = 1;
-	u16 reg16, parent_reg, child_reg[8];
+	u16 reg16, ccc, parent_old_ccc, child_old_ccc[8];
 	struct pci_dev *child, *parent = link->pdev;
 	struct pci_bus *linkbus = parent->subordinate;
 	/*
@@ -252,6 +271,7 @@
 
 	/* Port might be already in common clock mode */
 	pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &reg16);
+	parent_old_ccc = reg16 & PCI_EXP_LNKCTL_CCC;
 	if (same_clock && (reg16 & PCI_EXP_LNKCTL_CCC)) {
 		bool consistent = true;
 
@@ -268,35 +288,30 @@
 		pci_info(parent, "ASPM: current common clock configuration is inconsistent, reconfiguring\n");
 	}
 
+	ccc = same_clock ? PCI_EXP_LNKCTL_CCC : 0;
 	/* Configure downstream component, all functions */
 	list_for_each_entry(child, &linkbus->devices, bus_list) {
 		pcie_capability_read_word(child, PCI_EXP_LNKCTL, &reg16);
-		child_reg[PCI_FUNC(child->devfn)] = reg16;
-		if (same_clock)
-			reg16 |= PCI_EXP_LNKCTL_CCC;
-		else
-			reg16 &= ~PCI_EXP_LNKCTL_CCC;
-		pcie_capability_write_word(child, PCI_EXP_LNKCTL, reg16);
+		child_old_ccc[PCI_FUNC(child->devfn)] = reg16 & PCI_EXP_LNKCTL_CCC;
+		pcie_capability_clear_and_set_word(child, PCI_EXP_LNKCTL,
+						   PCI_EXP_LNKCTL_CCC, ccc);
 	}
 
 	/* Configure upstream component */
-	pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &reg16);
-	parent_reg = reg16;
-	if (same_clock)
-		reg16 |= PCI_EXP_LNKCTL_CCC;
-	else
-		reg16 &= ~PCI_EXP_LNKCTL_CCC;
-	pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16);
+	pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL,
+					   PCI_EXP_LNKCTL_CCC, ccc);
 
-	if (pcie_retrain_link(link))
-		return;
+	if (pcie_retrain_link(link)) {
 
-	/* Training failed. Restore common clock configurations */
-	pci_err(parent, "ASPM: Could not configure common clock\n");
-	list_for_each_entry(child, &linkbus->devices, bus_list)
-		pcie_capability_write_word(child, PCI_EXP_LNKCTL,
-					   child_reg[PCI_FUNC(child->devfn)]);
-	pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg);
+		/* Training failed. Restore common clock configurations */
+		pci_err(parent, "ASPM: Could not configure common clock\n");
+		list_for_each_entry(child, &linkbus->devices, bus_list)
+			pcie_capability_clear_and_set_word(child, PCI_EXP_LNKCTL,
+							   PCI_EXP_LNKCTL_CCC,
+							   child_old_ccc[PCI_FUNC(child->devfn)]);
+		pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL,
+						   PCI_EXP_LNKCTL_CCC, parent_old_ccc);
+	}
 }
 
 /* Convert L0s latency encoding to ns */
@@ -993,21 +1008,24 @@
 
 	down_read(&pci_bus_sem);
 	mutex_lock(&aspm_lock);
-	/*
-	 * All PCIe functions are in one slot, remove one function will remove
-	 * the whole slot, so just wait until we are the last function left.
-	 */
-	if (!list_empty(&parent->subordinate->devices))
-		goto out;
 
 	link = parent->link_state;
 	root = link->root;
 	parent_link = link->parent;
 
-	/* All functions are removed, so just disable ASPM for the link */
+	/*
+	 * link->downstream is a pointer to the pci_dev of function 0.  If
+	 * we remove that function, the pci_dev is about to be deallocated,
+	 * so we can't use link->downstream again.  Free the link state to
+	 * avoid this.
+	 *
+	 * If we're removing a non-0 function, it's possible we could
+	 * retain the link state, but PCIe r6.0, sec 7.5.3.7, recommends
+	 * programming the same ASPM Control value for all functions of
+	 * multi-function devices, so disable ASPM for all of them.
+	 */
 	pcie_config_aspm_link(link, 0);
 	list_del(&link->sibling);
-	/* Clock PM is for endpoint device */
 	free_link_state(link);
 
 	/* Recheck latencies and configure upstream links */
@@ -1015,7 +1033,7 @@
 		pcie_update_aspm_capable(root);
 		pcie_config_aspm_path(parent_link);
 	}
-out:
+
 	mutex_unlock(&aspm_lock);
 	up_read(&pci_bus_sem);
 }
diff --git a/kernel/drivers/pci/pcie/dpc.c b/kernel/drivers/pci/pcie/dpc.c
index c556e7b..f21d64a 100644
--- a/kernel/drivers/pci/pcie/dpc.c
+++ b/kernel/drivers/pci/pcie/dpc.c
@@ -170,8 +170,8 @@
 	pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
 			      PCI_EXP_DPC_STATUS_TRIGGER);
 
-	if (!pcie_wait_for_link(pdev, true)) {
-		pci_info(pdev, "Data Link Layer Link Active not set in 1000 msec\n");
+	if (pci_bridge_wait_for_secondary_bus(pdev, "DPC",
+					      PCIE_RESET_READY_POLL_MS)) {
 		clear_bit(PCI_DPC_RECOVERED, &pdev->priv_flags);
 		ret = PCI_ERS_RESULT_DISCONNECT;
 	} else {
diff --git a/kernel/drivers/pci/pcie/edr.c b/kernel/drivers/pci/pcie/edr.c
index a6b9b47..87734e4 100644
--- a/kernel/drivers/pci/pcie/edr.c
+++ b/kernel/drivers/pci/pcie/edr.c
@@ -193,6 +193,7 @@
 	 */
 	if (estate == PCI_ERS_RESULT_RECOVERED) {
 		pci_dbg(edev, "DPC port successfully recovered\n");
+		pcie_clear_device_status(edev);
 		acpi_send_edr_status(pdev, edev, EDR_OST_SUCCESS);
 	} else {
 		pci_dbg(edev, "DPC port recovery failed\n");
diff --git a/kernel/drivers/pci/quirks.c b/kernel/drivers/pci/quirks.c
index 4399912..3d2ccf0 100644
--- a/kernel/drivers/pci/quirks.c
+++ b/kernel/drivers/pci/quirks.c
@@ -4130,6 +4130,8 @@
 /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c49 */
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9230,
 			 quirk_dma_func1_alias);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9235,
+			 quirk_dma_func1_alias);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0642,
 			 quirk_dma_func1_alias);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0645,
@@ -4804,6 +4806,26 @@
 		PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
 }
 
+/*
+ * Wangxun 10G/1G NICs have no ACS capability, and on multi-function
+ * devices, peer-to-peer transactions are not be used between the functions.
+ * So add an ACS quirk for below devices to isolate functions.
+ * SFxxx 1G NICs(em).
+ * RP1000/RP2000 10G NICs(sp).
+ */
+static int  pci_quirk_wangxun_nic_acs(struct pci_dev *dev, u16 acs_flags)
+{
+	switch (dev->device) {
+	case 0x0100 ... 0x010F:
+	case 0x1001:
+	case 0x2001:
+		return pci_acs_ctrl_enabled(acs_flags,
+			PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
+	}
+
+	return false;
+}
+
 static const struct pci_dev_acs_enabled {
 	u16 vendor;
 	u16 device;
@@ -4949,6 +4971,8 @@
 	{ PCI_VENDOR_ID_NXP, 0x8d9b, pci_quirk_nxp_rp_acs },
 	/* Zhaoxin Root/Downstream Ports */
 	{ PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs },
+	/* Wangxun nics */
+	{ PCI_VENDOR_ID_WANGXUN, PCI_ANY_ID, pci_quirk_wangxun_nic_acs },
 	{ 0 }
 };
 
@@ -5309,6 +5333,7 @@
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x1487, quirk_no_flr);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x148c, quirk_no_flr);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x149c, quirk_no_flr);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x7901, quirk_no_flr);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1502, quirk_no_flr);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1503, quirk_no_flr);
 
diff --git a/kernel/drivers/pci/setup-bus.c b/kernel/drivers/pci/setup-bus.c
index 2ce6369..16d291e 100644
--- a/kernel/drivers/pci/setup-bus.c
+++ b/kernel/drivers/pci/setup-bus.c
@@ -1878,12 +1878,67 @@
 		add_size = size - new_size;
 		pci_dbg(bridge, "bridge window %pR shrunken by %pa\n", res,
 			&add_size);
+	} else {
+		return;
 	}
 
 	res->end = res->start + new_size - 1;
 	remove_from_list(add_list, res);
 }
 
+static void remove_dev_resource(struct resource *avail, struct pci_dev *dev,
+				struct resource *res)
+{
+	resource_size_t size, align, tmp;
+
+	size = resource_size(res);
+	if (!size)
+		return;
+
+	align = pci_resource_alignment(dev, res);
+	align = align ? ALIGN(avail->start, align) - avail->start : 0;
+	tmp = align + size;
+	avail->start = min(avail->start + tmp, avail->end + 1);
+}
+
+static void remove_dev_resources(struct pci_dev *dev, struct resource *io,
+				 struct resource *mmio,
+				 struct resource *mmio_pref)
+{
+	int i;
+
+	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+		struct resource *res = &dev->resource[i];
+
+		if (resource_type(res) == IORESOURCE_IO) {
+			remove_dev_resource(io, dev, res);
+		} else if (resource_type(res) == IORESOURCE_MEM) {
+
+			/*
+			 * Make sure prefetchable memory is reduced from
+			 * the correct resource. Specifically we put 32-bit
+			 * prefetchable memory in non-prefetchable window
+			 * if there is an 64-bit pretchable window.
+			 *
+			 * See comments in __pci_bus_size_bridges() for
+			 * more information.
+			 */
+			if ((res->flags & IORESOURCE_PREFETCH) &&
+			    ((res->flags & IORESOURCE_MEM_64) ==
+			     (mmio_pref->flags & IORESOURCE_MEM_64)))
+				remove_dev_resource(mmio_pref, dev, res);
+			else
+				remove_dev_resource(mmio, dev, res);
+		}
+	}
+}
+
+/*
+ * io, mmio and mmio_pref contain the total amount of bridge window space
+ * available. This includes the minimal space needed to cover all the
+ * existing devices on the bus and the possible extra space that can be
+ * shared with the bridges.
+ */
 static void pci_bus_distribute_available_resources(struct pci_bus *bus,
 					    struct list_head *add_list,
 					    struct resource io,
@@ -1893,7 +1948,7 @@
 	unsigned int normal_bridges = 0, hotplug_bridges = 0;
 	struct resource *io_res, *mmio_res, *mmio_pref_res;
 	struct pci_dev *dev, *bridge = bus->self;
-	resource_size_t io_per_hp, mmio_per_hp, mmio_pref_per_hp, align;
+	resource_size_t io_per_b, mmio_per_b, mmio_pref_per_b, align;
 
 	io_res = &bridge->resource[PCI_BRIDGE_IO_WINDOW];
 	mmio_res = &bridge->resource[PCI_BRIDGE_MEM_WINDOW];
@@ -1937,94 +1992,88 @@
 			normal_bridges++;
 	}
 
-	/*
-	 * There is only one bridge on the bus so it gets all available
-	 * resources which it can then distribute to the possible hotplug
-	 * bridges below.
-	 */
-	if (hotplug_bridges + normal_bridges == 1) {
-		dev = list_first_entry(&bus->devices, struct pci_dev, bus_list);
-		if (dev->subordinate)
-			pci_bus_distribute_available_resources(dev->subordinate,
-				add_list, io, mmio, mmio_pref);
+	if (!(hotplug_bridges + normal_bridges))
 		return;
+
+	/*
+	 * Calculate the amount of space we can forward from "bus" to any
+	 * downstream buses, i.e., the space left over after assigning the
+	 * BARs and windows on "bus".
+	 */
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		if (!dev->is_virtfn)
+			remove_dev_resources(dev, &io, &mmio, &mmio_pref);
 	}
 
-	if (hotplug_bridges == 0)
-		return;
-
 	/*
-	 * Calculate the total amount of extra resource space we can
-	 * pass to bridges below this one.  This is basically the
-	 * extra space reduced by the minimal required space for the
-	 * non-hotplug bridges.
+	 * If there is at least one hotplug bridge on this bus it gets all
+	 * the extra resource space that was left after the reductions
+	 * above.
+	 *
+	 * If there are no hotplug bridges the extra resource space is
+	 * split between non-hotplug bridges. This is to allow possible
+	 * hotplug bridges below them to get the extra space as well.
 	 */
+	if (hotplug_bridges) {
+		io_per_b = div64_ul(resource_size(&io), hotplug_bridges);
+		mmio_per_b = div64_ul(resource_size(&mmio), hotplug_bridges);
+		mmio_pref_per_b = div64_ul(resource_size(&mmio_pref),
+					   hotplug_bridges);
+	} else {
+		io_per_b = div64_ul(resource_size(&io), normal_bridges);
+		mmio_per_b = div64_ul(resource_size(&mmio), normal_bridges);
+		mmio_pref_per_b = div64_ul(resource_size(&mmio_pref),
+					   normal_bridges);
+	}
+
 	for_each_pci_bridge(dev, bus) {
-		resource_size_t used_size;
 		struct resource *res;
-
-		if (dev->is_hotplug_bridge)
-			continue;
-
-		/*
-		 * Reduce the available resource space by what the
-		 * bridge and devices below it occupy.
-		 */
-		res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
-		align = pci_resource_alignment(dev, res);
-		align = align ? ALIGN(io.start, align) - io.start : 0;
-		used_size = align + resource_size(res);
-		if (!res->parent)
-			io.start = min(io.start + used_size, io.end + 1);
-
-		res = &dev->resource[PCI_BRIDGE_MEM_WINDOW];
-		align = pci_resource_alignment(dev, res);
-		align = align ? ALIGN(mmio.start, align) - mmio.start : 0;
-		used_size = align + resource_size(res);
-		if (!res->parent)
-			mmio.start = min(mmio.start + used_size, mmio.end + 1);
-
-		res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
-		align = pci_resource_alignment(dev, res);
-		align = align ? ALIGN(mmio_pref.start, align) -
-			mmio_pref.start : 0;
-		used_size = align + resource_size(res);
-		if (!res->parent)
-			mmio_pref.start = min(mmio_pref.start + used_size,
-				mmio_pref.end + 1);
-	}
-
-	io_per_hp = div64_ul(resource_size(&io), hotplug_bridges);
-	mmio_per_hp = div64_ul(resource_size(&mmio), hotplug_bridges);
-	mmio_pref_per_hp = div64_ul(resource_size(&mmio_pref),
-		hotplug_bridges);
-
-	/*
-	 * Go over devices on this bus and distribute the remaining
-	 * resource space between hotplug bridges.
-	 */
-	for_each_pci_bridge(dev, bus) {
 		struct pci_bus *b;
 
 		b = dev->subordinate;
-		if (!b || !dev->is_hotplug_bridge)
+		if (!b)
+			continue;
+		if (hotplug_bridges && !dev->is_hotplug_bridge)
 			continue;
 
+		res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
+
 		/*
-		 * Distribute available extra resources equally between
-		 * hotplug-capable downstream ports taking alignment into
-		 * account.
+		 * Make sure the split resource space is properly aligned
+		 * for bridge windows (align it down to avoid going above
+		 * what is available).
 		 */
-		io.end = io.start + io_per_hp - 1;
-		mmio.end = mmio.start + mmio_per_hp - 1;
-		mmio_pref.end = mmio_pref.start + mmio_pref_per_hp - 1;
+		align = pci_resource_alignment(dev, res);
+		io.end = align ? io.start + ALIGN_DOWN(io_per_b, align) - 1
+			       : io.start + io_per_b - 1;
+
+		/*
+		 * The x_per_b holds the extra resource space that can be
+		 * added for each bridge but there is the minimal already
+		 * reserved as well so adjust x.start down accordingly to
+		 * cover the whole space.
+		 */
+		io.start -= resource_size(res);
+
+		res = &dev->resource[PCI_BRIDGE_MEM_WINDOW];
+		align = pci_resource_alignment(dev, res);
+		mmio.end = align ? mmio.start + ALIGN_DOWN(mmio_per_b, align) - 1
+				 : mmio.start + mmio_per_b - 1;
+		mmio.start -= resource_size(res);
+
+		res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
+		align = pci_resource_alignment(dev, res);
+		mmio_pref.end = align ? mmio_pref.start +
+					ALIGN_DOWN(mmio_pref_per_b, align) - 1
+				      : mmio_pref.start + mmio_pref_per_b - 1;
+		mmio_pref.start -= resource_size(res);
 
 		pci_bus_distribute_available_resources(b, add_list, io, mmio,
 						       mmio_pref);
 
-		io.start += io_per_hp;
-		mmio.start += mmio_per_hp;
-		mmio_pref.start += mmio_pref_per_hp;
+		io.start += io.end + 1;
+		mmio.start += mmio.end + 1;
+		mmio_pref.start += mmio_pref.end + 1;
 	}
 }
 
diff --git a/kernel/drivers/pcmcia/rsrc_nonstatic.c b/kernel/drivers/pcmcia/rsrc_nonstatic.c
index 69a6e9a..6e90927 100644
--- a/kernel/drivers/pcmcia/rsrc_nonstatic.c
+++ b/kernel/drivers/pcmcia/rsrc_nonstatic.c
@@ -1053,6 +1053,8 @@
 		q = p->next;
 		kfree(p);
 	}
+
+	kfree(data);
 }
 
 
diff --git a/kernel/drivers/perf/arm-cmn.c b/kernel/drivers/perf/arm-cmn.c
index bb019e3..36061aa 100644
--- a/kernel/drivers/perf/arm-cmn.c
+++ b/kernel/drivers/perf/arm-cmn.c
@@ -1254,9 +1254,10 @@
 	if (dtc->irq < 0)
 		return dtc->irq;
 
-	writel_relaxed(0, dtc->base + CMN_DT_PMCR);
+	writel_relaxed(CMN_DT_DTC_CTL_DT_EN, dtc->base + CMN_DT_DTC_CTL);
+	writel_relaxed(CMN_DT_PMCR_PMU_EN | CMN_DT_PMCR_OVFL_INTR_EN, dtc->base + CMN_DT_PMCR);
+	writeq_relaxed(0, dtc->base + CMN_DT_PMCCNTR);
 	writel_relaxed(0x1ff, dtc->base + CMN_DT_PMOVSR_CLR);
-	writel_relaxed(CMN_DT_PMCR_OVFL_INTR_EN, dtc->base + CMN_DT_PMCR);
 
 	/* We do at least know that a DTC's XP must be in that DTC's domain */
 	xp = arm_cmn_node_to_xp(dn);
@@ -1303,7 +1304,7 @@
 			dn->type = CMN_TYPE_RNI;
 	}
 
-	writel_relaxed(CMN_DT_DTC_CTL_DT_EN, cmn->dtc[0].base + CMN_DT_DTC_CTL);
+	arm_cmn_set_state(cmn, CMN_STATE_DISABLED);
 
 	return 0;
 }
diff --git a/kernel/drivers/perf/arm_dsu_pmu.c b/kernel/drivers/perf/arm_dsu_pmu.c
index 98e68ed..1db8ecc 100644
--- a/kernel/drivers/perf/arm_dsu_pmu.c
+++ b/kernel/drivers/perf/arm_dsu_pmu.c
@@ -866,7 +866,11 @@
 	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)
diff --git a/kernel/drivers/perf/arm_smmuv3_pmu.c b/kernel/drivers/perf/arm_smmuv3_pmu.c
index afa8efb..6ebe72b 100644
--- a/kernel/drivers/perf/arm_smmuv3_pmu.c
+++ b/kernel/drivers/perf/arm_smmuv3_pmu.c
@@ -95,6 +95,7 @@
 #define SMMU_PMCG_PA_SHIFT              12
 
 #define SMMU_PMCG_EVCNTR_RDONLY         BIT(0)
+#define SMMU_PMCG_HARDEN_DISABLE        BIT(1)
 
 static int cpuhp_state_num;
 
@@ -138,12 +139,42 @@
 	writel(SMMU_PMCG_CR_ENABLE, smmu_pmu->reg_base + SMMU_PMCG_CR);
 }
 
+static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu,
+				       struct perf_event *event, int idx);
+
+static inline void smmu_pmu_enable_quirk_hip08_09(struct pmu *pmu)
+{
+	struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu);
+	unsigned int idx;
+
+	for_each_set_bit(idx, smmu_pmu->used_counters, smmu_pmu->num_counters)
+		smmu_pmu_apply_event_filter(smmu_pmu, smmu_pmu->events[idx], idx);
+
+	smmu_pmu_enable(pmu);
+}
+
 static inline void smmu_pmu_disable(struct pmu *pmu)
 {
 	struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu);
 
 	writel(0, smmu_pmu->reg_base + SMMU_PMCG_CR);
 	writel(0, smmu_pmu->reg_base + SMMU_PMCG_IRQ_CTRL);
+}
+
+static inline void smmu_pmu_disable_quirk_hip08_09(struct pmu *pmu)
+{
+	struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu);
+	unsigned int idx;
+
+	/*
+	 * The global disable of PMU sometimes fail to stop the counting.
+	 * Harden this by writing an invalid event type to each used counter
+	 * to forcibly stop counting.
+	 */
+	for_each_set_bit(idx, smmu_pmu->used_counters, smmu_pmu->num_counters)
+		writel(0xffff, smmu_pmu->reg_base + SMMU_PMCG_EVTYPER(idx));
+
+	smmu_pmu_disable(pmu);
 }
 
 static inline void smmu_pmu_counter_set_value(struct smmu_pmu *smmu_pmu,
@@ -719,7 +750,10 @@
 	switch (model) {
 	case IORT_SMMU_V3_PMCG_HISI_HIP08:
 		/* HiSilicon Erratum 162001800 */
-		smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY;
+		smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY | SMMU_PMCG_HARDEN_DISABLE;
+		break;
+	case IORT_SMMU_V3_PMCG_HISI_HIP09:
+		smmu_pmu->options |= SMMU_PMCG_HARDEN_DISABLE;
 		break;
 	}
 
@@ -806,6 +840,16 @@
 
 	smmu_pmu_get_acpi_options(smmu_pmu);
 
+	/*
+	 * For platforms suffer this quirk, the PMU disable sometimes fails to
+	 * stop the counters. This will leads to inaccurate or error counting.
+	 * Forcibly disable the counters with these quirk handler.
+	 */
+	if (smmu_pmu->options & SMMU_PMCG_HARDEN_DISABLE) {
+		smmu_pmu->pmu.pmu_enable = smmu_pmu_enable_quirk_hip08_09;
+		smmu_pmu->pmu.pmu_disable = smmu_pmu_disable_quirk_hip08_09;
+	}
+
 	/* Pick one CPU to be the preferred one to use */
 	smmu_pmu->on_cpu = raw_smp_processor_id();
 	WARN_ON(irq_set_affinity_hint(smmu_pmu->irq,
@@ -870,6 +914,8 @@
 
 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 +923,11 @@
 	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);
 
diff --git a/kernel/drivers/perf/fsl_imx8_ddr_perf.c b/kernel/drivers/perf/fsl_imx8_ddr_perf.c
index e09bbf3..8dfb675 100644
--- a/kernel/drivers/perf/fsl_imx8_ddr_perf.c
+++ b/kernel/drivers/perf/fsl_imx8_ddr_perf.c
@@ -82,6 +82,7 @@
 	const struct fsl_ddr_devtype_data *devtype_data;
 	int irq;
 	int id;
+	int active_counter;
 };
 
 enum ddr_perf_filter_capabilities {
@@ -414,6 +415,10 @@
 
 	ddr_perf_counter_enable(pmu, event->attr.config, counter, true);
 
+	if (!pmu->active_counter++)
+		ddr_perf_counter_enable(pmu, EVENT_CYCLES_ID,
+			EVENT_CYCLES_COUNTER, true);
+
 	hwc->state = 0;
 }
 
@@ -468,6 +473,10 @@
 	ddr_perf_counter_enable(pmu, event->attr.config, counter, false);
 	ddr_perf_event_update(event);
 
+	if (!--pmu->active_counter)
+		ddr_perf_counter_enable(pmu, EVENT_CYCLES_ID,
+			EVENT_CYCLES_COUNTER, false);
+
 	hwc->state |= PERF_HES_STOPPED;
 }
 
@@ -486,25 +495,10 @@
 
 static void ddr_perf_pmu_enable(struct pmu *pmu)
 {
-	struct ddr_pmu *ddr_pmu = to_ddr_pmu(pmu);
-
-	/* enable cycle counter if cycle is not active event list */
-	if (ddr_pmu->events[EVENT_CYCLES_COUNTER] == NULL)
-		ddr_perf_counter_enable(ddr_pmu,
-				      EVENT_CYCLES_ID,
-				      EVENT_CYCLES_COUNTER,
-				      true);
 }
 
 static void ddr_perf_pmu_disable(struct pmu *pmu)
 {
-	struct ddr_pmu *ddr_pmu = to_ddr_pmu(pmu);
-
-	if (ddr_pmu->events[EVENT_CYCLES_COUNTER] == NULL)
-		ddr_perf_counter_enable(ddr_pmu,
-				      EVENT_CYCLES_ID,
-				      EVENT_CYCLES_COUNTER,
-				      false);
 }
 
 static int ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base,
diff --git a/kernel/drivers/phy/broadcom/phy-brcm-usb.c b/kernel/drivers/phy/broadcom/phy-brcm-usb.c
index b901a0d..cd2240e 100644
--- a/kernel/drivers/phy/broadcom/phy-brcm-usb.c
+++ b/kernel/drivers/phy/broadcom/phy-brcm-usb.c
@@ -101,9 +101,9 @@
 
 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 @@
 	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);
diff --git a/kernel/drivers/phy/hisilicon/phy-hisi-inno-usb2.c b/kernel/drivers/phy/hisilicon/phy-hisi-inno-usb2.c
index 34a6a9a..897c6bb 100644
--- a/kernel/drivers/phy/hisilicon/phy-hisi-inno-usb2.c
+++ b/kernel/drivers/phy/hisilicon/phy-hisi-inno-usb2.c
@@ -153,7 +153,7 @@
 		phy_set_drvdata(phy, &priv->ports[i]);
 		i++;
 
-		if (i > INNO_PHY_PORT_NUM) {
+		if (i >= INNO_PHY_PORT_NUM) {
 			dev_warn(dev, "Support %d ports in maximum\n", i);
 			break;
 		}
diff --git a/kernel/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/kernel/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
index 7e61202..173d166 100644
--- a/kernel/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
+++ b/kernel/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
@@ -68,29 +68,61 @@
 /**
  * struct qcom_snps_hsphy - snps hs phy attributes
  *
+ * @dev: device structure
+ *
  * @phy: generic phy
  * @base: iomapped memory space for snps hs phy
  *
- * @cfg_ahb_clk: AHB2PHY interface clock
- * @ref_clk: phy reference clock
- * @iface_clk: phy interface clock
+ * @num_clks: number of clocks
+ * @clks: array of clocks
  * @phy_reset: phy reset control
  * @vregs: regulator supplies bulk data
  * @phy_initialized: if PHY has been initialized correctly
  * @mode: contains the current mode the PHY is in
+ * @update_seq_cfg: tuning parameters for phy init
  */
 struct qcom_snps_hsphy {
+	struct device *dev;
+
 	struct phy *phy;
 	void __iomem *base;
 
-	struct clk *cfg_ahb_clk;
-	struct clk *ref_clk;
+	int num_clks;
+	struct clk_bulk_data *clks;
 	struct reset_control *phy_reset;
 	struct regulator_bulk_data vregs[SNPS_HS_NUM_VREGS];
 
 	bool phy_initialized;
 	enum phy_mode mode;
 };
+
+static int qcom_snps_hsphy_clk_init(struct qcom_snps_hsphy *hsphy)
+{
+	struct device *dev = hsphy->dev;
+
+	hsphy->num_clks = 2;
+	hsphy->clks = devm_kcalloc(dev, hsphy->num_clks, sizeof(*hsphy->clks), GFP_KERNEL);
+	if (!hsphy->clks)
+		return -ENOMEM;
+
+	/*
+	 * TODO: Currently no device tree instantiation of the PHY is using the clock.
+	 * This needs to be fixed in order for this code to be able to use devm_clk_bulk_get().
+	 */
+	hsphy->clks[0].id = "cfg_ahb";
+	hsphy->clks[0].clk = devm_clk_get_optional(dev, "cfg_ahb");
+	if (IS_ERR(hsphy->clks[0].clk))
+		return dev_err_probe(dev, PTR_ERR(hsphy->clks[0].clk),
+				     "failed to get cfg_ahb clk\n");
+
+	hsphy->clks[1].id = "ref";
+	hsphy->clks[1].clk = devm_clk_get(dev, "ref");
+	if (IS_ERR(hsphy->clks[1].clk))
+		return dev_err_probe(dev, PTR_ERR(hsphy->clks[1].clk),
+				     "failed to get ref clk\n");
+
+	return 0;
+}
 
 static inline void qcom_snps_hsphy_write_mask(void __iomem *base, u32 offset,
 						u32 mask, u32 val)
@@ -122,21 +154,12 @@
 					   0, USB2_AUTO_RESUME);
 	}
 
-	clk_disable_unprepare(hsphy->cfg_ahb_clk);
 	return 0;
 }
 
 static int qcom_snps_hsphy_resume(struct qcom_snps_hsphy *hsphy)
 {
-	int ret;
-
 	dev_dbg(&hsphy->phy->dev, "Resume QCOM SNPS PHY, mode\n");
-
-	ret = clk_prepare_enable(hsphy->cfg_ahb_clk);
-	if (ret) {
-		dev_err(&hsphy->phy->dev, "failed to enable cfg ahb clock\n");
-		return ret;
-	}
 
 	return 0;
 }
@@ -148,8 +171,7 @@
 	if (!hsphy->phy_initialized)
 		return 0;
 
-	qcom_snps_hsphy_suspend(hsphy);
-	return 0;
+	return qcom_snps_hsphy_suspend(hsphy);
 }
 
 static int __maybe_unused qcom_snps_hsphy_runtime_resume(struct device *dev)
@@ -159,8 +181,7 @@
 	if (!hsphy->phy_initialized)
 		return 0;
 
-	qcom_snps_hsphy_resume(hsphy);
-	return 0;
+	return qcom_snps_hsphy_resume(hsphy);
 }
 
 static int qcom_snps_hsphy_set_mode(struct phy *phy, enum phy_mode mode,
@@ -183,16 +204,16 @@
 	if (ret)
 		return ret;
 
-	ret = clk_prepare_enable(hsphy->cfg_ahb_clk);
+	ret = clk_bulk_prepare_enable(hsphy->num_clks, hsphy->clks);
 	if (ret) {
-		dev_err(&phy->dev, "failed to enable cfg ahb clock, %d\n", ret);
+		dev_err(&phy->dev, "failed to enable clocks, %d\n", ret);
 		goto poweroff_phy;
 	}
 
 	ret = reset_control_assert(hsphy->phy_reset);
 	if (ret) {
 		dev_err(&phy->dev, "failed to assert phy_reset, %d\n", ret);
-		goto disable_ahb_clk;
+		goto disable_clks;
 	}
 
 	usleep_range(100, 150);
@@ -200,7 +221,7 @@
 	ret = reset_control_deassert(hsphy->phy_reset);
 	if (ret) {
 		dev_err(&phy->dev, "failed to de-assert phy_reset, %d\n", ret);
-		goto disable_ahb_clk;
+		goto disable_clks;
 	}
 
 	qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_CFG0,
@@ -246,8 +267,8 @@
 
 	return 0;
 
-disable_ahb_clk:
-	clk_disable_unprepare(hsphy->cfg_ahb_clk);
+disable_clks:
+	clk_bulk_disable_unprepare(hsphy->num_clks, hsphy->clks);
 poweroff_phy:
 	regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs);
 
@@ -259,7 +280,7 @@
 	struct qcom_snps_hsphy *hsphy = phy_get_drvdata(phy);
 
 	reset_control_assert(hsphy->phy_reset);
-	clk_disable_unprepare(hsphy->cfg_ahb_clk);
+	clk_bulk_disable_unprepare(hsphy->num_clks, hsphy->clks);
 	regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs);
 	hsphy->phy_initialized = false;
 
@@ -299,17 +320,15 @@
 	if (!hsphy)
 		return -ENOMEM;
 
+	hsphy->dev = dev;
+
 	hsphy->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(hsphy->base))
 		return PTR_ERR(hsphy->base);
 
-	hsphy->ref_clk = devm_clk_get(dev, "ref");
-	if (IS_ERR(hsphy->ref_clk)) {
-		ret = PTR_ERR(hsphy->ref_clk);
-		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "failed to get ref clk, %d\n", ret);
-		return ret;
-	}
+	ret = qcom_snps_hsphy_clk_init(hsphy);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to initialize clocks\n");
 
 	hsphy->phy_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 	if (IS_ERR(hsphy->phy_reset)) {
@@ -322,12 +341,9 @@
 		hsphy->vregs[i].supply = qcom_snps_hsphy_vreg_names[i];
 
 	ret = devm_regulator_bulk_get(dev, num, hsphy->vregs);
-	if (ret) {
-		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "failed to get regulator supplies: %d\n",
-				ret);
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to get regulator supplies\n");
 
 	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
diff --git a/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-common.h b/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-common.h
index 3811d6f..7af000b 100644
--- a/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-common.h
+++ b/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-common.h
@@ -98,8 +98,9 @@
 	const struct hsfreq_range *hsfreq_ranges_cphy;
 	int num_hsfreq_ranges_cphy;
 	const struct grf_reg *grf_regs;
-	const struct txrx_reg *txrx_regs;
+	int num_grf_regs;
 	const struct csi2dphy_reg *csi2dphy_regs;
+	int num_csi2dphy_regs;
 	void (*individual_init)(struct csi2_dphy_hw *hw);
 	int (*stream_on)(struct csi2_dphy *dphy, struct v4l2_subdev *sd);
 	int (*stream_off)(struct csi2_dphy *dphy, struct v4l2_subdev *sd);
@@ -111,7 +112,6 @@
 	struct regmap *regmap_grf;
 	struct regmap *regmap_sys_grf;
 	const struct grf_reg *grf_regs;
-	const struct txrx_reg *txrx_regs;
 	const struct csi2dphy_reg *csi2dphy_regs;
 	const struct dphy_hw_drv_data *drv_data;
 	void __iomem *hw_base_addr;
@@ -130,6 +130,8 @@
 	int (*stream_off)(struct csi2_dphy *dphy, struct v4l2_subdev *sd);
 	int (*ttl_mode_enable)(struct csi2_dphy_hw *hw);
 	void (*ttl_mode_disable)(struct csi2_dphy_hw *hw);
+	int (*quick_stream_on)(struct csi2_dphy *dphy, struct v4l2_subdev *sd);
+	int (*quick_stream_off)(struct csi2_dphy *dphy, struct v4l2_subdev *sd);
 };
 
 int rockchip_csi2_dphy_hw_init(void);
diff --git a/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c b/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c
index e0a9fd6..4aada19 100644
--- a/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c
+++ b/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c
@@ -54,6 +54,7 @@
 #define CSI2_DPHY_DUAL_CAL_EN		(0x80)
 #define CSI2_DPHY_CLK_INV		(0X84)
 
+#define CSI2_DPHY_CLK_CONTINUE_MODE	(0x128)
 #define CSI2_DPHY_CLK_WR_THS_SETTLE	(0x160)
 #define CSI2_DPHY_CLK_CALIB_EN		(0x168)
 #define CSI2_DPHY_LANE0_WR_THS_SETTLE	(0x1e0)
@@ -64,6 +65,7 @@
 #define CSI2_DPHY_LANE2_CALIB_EN	(0x2e8)
 #define CSI2_DPHY_LANE3_WR_THS_SETTLE	(0x360)
 #define CSI2_DPHY_LANE3_CALIB_EN	(0x368)
+#define CSI2_DPHY_CLK1_CONTINUE_MODE	(0x3a8)
 #define CSI2_DPHY_CLK1_WR_THS_SETTLE	(0x3e0)
 #define CSI2_DPHY_CLK1_CALIB_EN		(0x3e8)
 
@@ -213,6 +215,8 @@
 	CSI2PHY_PATH1_MODEL,
 	CSI2PHY_PATH1_LVDS_MODEL,
 	CSI2PHY_CLK_INV,
+	CSI2PHY_CLK_CONTINUE_MODE,
+	CSI2PHY_CLK1_CONTINUE_MODE,
 };
 
 #define HIWORD_UPDATE(val, mask, shift) \
@@ -232,9 +236,14 @@
 static inline void write_sys_grf_reg(struct csi2_dphy_hw *hw,
 				     int index, u8 value)
 {
-	const struct grf_reg *reg = &hw->grf_regs[index];
-	unsigned int val = HIWORD_UPDATE(value, reg->mask, reg->shift);
+	const struct grf_reg *reg = NULL;
+	unsigned int val = 0;
 
+	if (index >= hw->drv_data->num_grf_regs)
+		return;
+
+	reg = &hw->grf_regs[index];
+	val = HIWORD_UPDATE(value, reg->mask, reg->shift);
 	if (reg->mask)
 		regmap_write(hw->regmap_sys_grf, reg->offset, val);
 }
@@ -242,18 +251,27 @@
 static inline void write_grf_reg(struct csi2_dphy_hw *hw,
 				     int index, u8 value)
 {
-	const struct grf_reg *reg = &hw->grf_regs[index];
-	unsigned int val = HIWORD_UPDATE(value, reg->mask, reg->shift);
+	const struct grf_reg *reg = NULL;
+	unsigned int val = 0;
 
+	if (index >= hw->drv_data->num_grf_regs)
+		return;
+
+	reg = &hw->grf_regs[index];
+	val = HIWORD_UPDATE(value, reg->mask, reg->shift);
 	if (reg->mask)
 		regmap_write(hw->regmap_grf, reg->offset, val);
 }
 
 static inline u32 read_grf_reg(struct csi2_dphy_hw *hw, int index)
 {
-	const struct grf_reg *reg = &hw->grf_regs[index];
+	const struct grf_reg *reg = NULL;
 	unsigned int val = 0;
 
+	if (index >= hw->drv_data->num_grf_regs)
+		return -EINVAL;
+
+	reg = &hw->grf_regs[index];
 	if (reg->mask) {
 		regmap_read(hw->regmap_grf, reg->offset, &val);
 		val = (val >> reg->shift) & reg->mask;
@@ -265,8 +283,12 @@
 static inline void write_csi2_dphy_reg(struct csi2_dphy_hw *hw,
 					    int index, u32 value)
 {
-	const struct csi2dphy_reg *reg = &hw->csi2dphy_regs[index];
+	const struct csi2dphy_reg *reg = NULL;
 
+	if (index >= hw->drv_data->num_csi2dphy_regs)
+		return;
+
+	reg = &hw->csi2dphy_regs[index];
 	if ((index == CSI2PHY_REG_CTRL_LANE_ENABLE) ||
 	    (index == CSI2PHY_CLK_LANE_ENABLE) ||
 	    (index != CSI2PHY_REG_CTRL_LANE_ENABLE &&
@@ -277,9 +299,13 @@
 static inline void write_csi2_dphy_reg_mask(struct csi2_dphy_hw *hw,
 					    int index, u32 value, u32 mask)
 {
-	const struct csi2dphy_reg *reg = &hw->csi2dphy_regs[index];
+	const struct csi2dphy_reg *reg = NULL;
 	u32 read_val = 0;
 
+	if (index >= hw->drv_data->num_csi2dphy_regs)
+		return;
+
+	reg = &hw->csi2dphy_regs[index];
 	read_val = readl(hw->hw_base_addr + reg->offset);
 	read_val &= ~mask;
 	read_val |= value;
@@ -289,8 +315,12 @@
 static inline void read_csi2_dphy_reg(struct csi2_dphy_hw *hw,
 					   int index, u32 *value)
 {
-	const struct csi2dphy_reg *reg = &hw->csi2dphy_regs[index];
+	const struct csi2dphy_reg *reg = NULL;
 
+	if (index >= hw->drv_data->num_csi2dphy_regs)
+		return;
+
+	reg = &hw->csi2dphy_regs[index];
 	if ((index == CSI2PHY_REG_CTRL_LANE_ENABLE) ||
 	    (index == CSI2PHY_CLK_LANE_ENABLE) ||
 	    (index != CSI2PHY_REG_CTRL_LANE_ENABLE &&
@@ -397,6 +427,8 @@
 	[CSI2PHY_CLK1_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_WR_THS_SETTLE),
 	[CSI2PHY_CLK1_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_CALIB_EN),
 	[CSI2PHY_CLK1_LANE_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_LANE_EN),
+	[CSI2PHY_CLK_CONTINUE_MODE] = CSI2PHY_REG(CSI2_DPHY_CLK_CONTINUE_MODE),
+	[CSI2PHY_CLK1_CONTINUE_MODE] = CSI2PHY_REG(CSI2_DPHY_CLK1_CONTINUE_MODE),
 };
 
 static const struct grf_reg rv1106_grf_dphy_regs[] = {
@@ -709,19 +741,30 @@
 		val |= (GENMASK(sensor->lanes - 1, 0) <<
 			CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT) |
 			(0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT);
+		if (sensor->mbus.flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK)
+			write_csi2_dphy_reg(hw, CSI2PHY_CLK_CONTINUE_MODE, 0x30);
 	} else {
 		if (!(pre_val & (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT)))
 			val |= (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT);
 
-		if (dphy->phy_index % 3 == DPHY1)
+		if (dphy->phy_index % 3 == DPHY1) {
 			val |= (GENMASK(sensor->lanes - 1, 0) <<
 				CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT);
+			if (sensor->mbus.flags &
+			    V4L2_MBUS_CSI2_CONTINUOUS_CLOCK)
+				write_csi2_dphy_reg(
+					hw, CSI2PHY_CLK_CONTINUE_MODE, 0x30);
+		}
 
 		if (dphy->phy_index % 3 == DPHY2) {
 			val |= (GENMASK(sensor->lanes - 1, 0) <<
 				CSI2_DPHY_CTRL_DATALANE_SPLIT_LANE2_3_OFFSET_BIT);
 			if (hw->drv_data->chip_id >= CHIP_ID_RK3588)
 				write_csi2_dphy_reg(hw, CSI2PHY_CLK1_LANE_ENABLE, BIT(6));
+			if (sensor->mbus.flags &
+			    V4L2_MBUS_CSI2_CONTINUOUS_CLOCK)
+				write_csi2_dphy_reg(
+					hw, CSI2PHY_CLK1_CONTINUE_MODE, 0x30);
 		}
 	}
 	val |= pre_val;
@@ -859,10 +902,87 @@
 
 	write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, 0x01);
 	csi2_dphy_hw_do_reset(hw);
-	usleep_range(500, 1000);
 
 	mutex_unlock(&hw->mutex);
 
+	return 0;
+}
+
+static int csi2_dphy_hw_quick_stream_on(struct csi2_dphy *dphy,
+					struct v4l2_subdev *sd)
+{
+	struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
+	struct csi2_sensor *sensor;
+	struct csi2_dphy_hw *hw = dphy->dphy_hw;
+	u32 val = 0, pre_val = 0;
+
+	if (!sensor_sd)
+		return -ENODEV;
+	sensor = sd_to_sensor(dphy, sensor_sd);
+	if (!sensor)
+		return -ENODEV;
+
+	read_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, &pre_val);
+	if (hw->lane_mode == LANE_MODE_FULL) {
+		val |= (GENMASK(sensor->lanes - 1, 0) <<
+			CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT) |
+			(0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT);
+	} else {
+		if (!(pre_val & (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT)))
+			val |= (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT);
+
+		if (dphy->phy_index % 3 == DPHY1)
+			val |= (GENMASK(sensor->lanes - 1, 0) <<
+				CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT);
+
+		if (dphy->phy_index % 3 == DPHY2) {
+			val |= (GENMASK(sensor->lanes - 1, 0) <<
+				CSI2_DPHY_CTRL_DATALANE_SPLIT_LANE2_3_OFFSET_BIT);
+			if (hw->drv_data->chip_id >= CHIP_ID_RK3588)
+				write_csi2_dphy_reg(hw, CSI2PHY_CLK1_LANE_ENABLE, BIT(6));
+		}
+	}
+	pre_val |= val;
+	write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, pre_val);
+	return 0;
+}
+
+static int csi2_dphy_hw_quick_stream_off(struct csi2_dphy *dphy,
+					 struct v4l2_subdev *sd)
+{
+	struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
+	struct csi2_sensor *sensor;
+	struct csi2_dphy_hw *hw = dphy->dphy_hw;
+	u32 val = 0, pre_val = 0;
+
+	if (!sensor_sd)
+		return -ENODEV;
+	sensor = sd_to_sensor(dphy, sensor_sd);
+	if (!sensor)
+		return -ENODEV;
+
+	read_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, &pre_val);
+	if (hw->lane_mode == LANE_MODE_FULL) {
+		val |= (GENMASK(sensor->lanes - 1, 0) <<
+			CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT) |
+			(0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT);
+	} else {
+		if (!(pre_val & (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT)))
+			val |= (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT);
+
+		if (dphy->phy_index % 3 == DPHY1)
+			val |= (GENMASK(sensor->lanes - 1, 0) <<
+				CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT);
+
+		if (dphy->phy_index % 3 == DPHY2) {
+			val |= (GENMASK(sensor->lanes - 1, 0) <<
+				CSI2_DPHY_CTRL_DATALANE_SPLIT_LANE2_3_OFFSET_BIT);
+			if (hw->drv_data->chip_id >= CHIP_ID_RK3588)
+				write_csi2_dphy_reg(hw, CSI2PHY_CLK1_LANE_ENABLE, BIT(6));
+		}
+	}
+	pre_val &= ~val;
+	write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, pre_val);
 	return 0;
 }
 
@@ -913,7 +1033,9 @@
 	.hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges,
 	.num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges),
 	.csi2dphy_regs = rk3568_csi2dphy_regs,
+	.num_csi2dphy_regs = ARRAY_SIZE(rk3568_csi2dphy_regs),
 	.grf_regs = rk3568_grf_dphy_regs,
+	.num_grf_regs = ARRAY_SIZE(rk3568_grf_dphy_regs),
 	.individual_init = rk3568_csi2_dphy_hw_individual_init,
 	.chip_id = CHIP_ID_RK3568,
 	.stream_on = csi2_dphy_hw_stream_on,
@@ -924,7 +1046,9 @@
 	.hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges,
 	.num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges),
 	.csi2dphy_regs = rk3588_csi2dphy_regs,
+	.num_csi2dphy_regs = ARRAY_SIZE(rk3588_csi2dphy_regs),
 	.grf_regs = rk3588_grf_dphy_regs,
+	.num_grf_regs = ARRAY_SIZE(rk3588_grf_dphy_regs),
 	.individual_init = rk3588_csi2_dphy_hw_individual_init,
 	.chip_id = CHIP_ID_RK3588,
 	.stream_on = csi2_dphy_hw_stream_on,
@@ -935,7 +1059,9 @@
 	.hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges,
 	.num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges),
 	.csi2dphy_regs = rv1106_csi2dphy_regs,
+	.num_csi2dphy_regs = ARRAY_SIZE(rv1106_csi2dphy_regs),
 	.grf_regs = rv1106_grf_dphy_regs,
+	.num_grf_regs = ARRAY_SIZE(rv1106_grf_dphy_regs),
 	.individual_init = rv1106_csi2_dphy_hw_individual_init,
 	.chip_id = CHIP_ID_RV1106,
 	.stream_on = csi2_dphy_hw_stream_on,
@@ -946,7 +1072,9 @@
 	.hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges,
 	.num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges),
 	.csi2dphy_regs = rk3562_csi2dphy_regs,
+	.num_csi2dphy_regs = ARRAY_SIZE(rk3562_csi2dphy_regs),
 	.grf_regs = rk3562_grf_dphy_regs,
+	.num_grf_regs = ARRAY_SIZE(rk3562_grf_dphy_regs),
 	.individual_init = rk3562_csi2_dphy_hw_individual_init,
 	.chip_id = CHIP_ID_RK3562,
 	.stream_on = csi2_dphy_hw_stream_on,
@@ -1024,7 +1152,6 @@
 	dphy_hw->drv_data = drv_data;
 	dphy_hw->lane_mode = LANE_MODE_UNDEF;
 	dphy_hw->grf_regs = drv_data->grf_regs;
-	dphy_hw->txrx_regs = drv_data->txrx_regs;
 	dphy_hw->csi2dphy_regs = drv_data->csi2dphy_regs;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1041,6 +1168,8 @@
 	}
 	dphy_hw->stream_on = drv_data->stream_on;
 	dphy_hw->stream_off = drv_data->stream_off;
+	dphy_hw->quick_stream_on = csi2_dphy_hw_quick_stream_on;
+	dphy_hw->quick_stream_off = csi2_dphy_hw_quick_stream_off;
 
 	if (drv_data->chip_id == CHIP_ID_RV1106) {
 		dphy_hw->ttl_mode_enable = csi2_dphy_hw_ttl_mode_enable;
diff --git a/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy.c b/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy.c
index 373818c..6ce85e8 100644
--- a/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy.c
+++ b/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy.c
@@ -160,6 +160,7 @@
 		if (csi_idx < 2) {
 			dcphy_hw = dphy->samsung_phy_group[csi_idx];
 			mutex_lock(&dcphy_hw->mutex);
+			dcphy_hw->dphy_dev[dcphy_hw->dphy_dev_num] = dphy;
 			dcphy_hw->dphy_dev_num++;
 			mutex_unlock(&dcphy_hw->mutex);
 			dphy->samsung_phy = dcphy_hw;
@@ -199,6 +200,7 @@
 				else
 					dphy->phy_index = 5;
 			}
+			dphy_hw->dphy_dev[dphy_hw->dphy_dev_num] = dphy;
 			dphy_hw->dphy_dev_num++;
 			dphy->dphy_hw = dphy_hw;
 			dphy->phy_hw[index] = (void *)dphy_hw;
@@ -253,12 +255,56 @@
 	return 0;
 }
 
+static void rockchip_csi2_samsung_phy_remove_dphy_dev(struct csi2_dphy *dphy,
+						   struct samsung_mipi_dcphy *dcphy_hw)
+{
+	int i = 0;
+	bool is_find_dev = false;
+	struct csi2_dphy *csi2_dphy = NULL;
+
+	for (i = 0; i < dcphy_hw->dphy_dev_num; i++) {
+		csi2_dphy = dcphy_hw->dphy_dev[i];
+		if (csi2_dphy &&
+		    csi2_dphy->phy_index == dphy->phy_index)
+			is_find_dev = true;
+		if (is_find_dev) {
+			if (i < dcphy_hw->dphy_dev_num - 1)
+				dcphy_hw->dphy_dev[i] = dcphy_hw->dphy_dev[i + 1];
+			else
+				dcphy_hw->dphy_dev[i] = NULL;
+		}
+	}
+	if (is_find_dev)
+		dcphy_hw->dphy_dev_num--;
+}
+
+static void rockchip_csi2_inno_phy_remove_dphy_dev(struct csi2_dphy *dphy,
+						   struct csi2_dphy_hw *dphy_hw)
+{
+	int i = 0;
+	bool is_find_dev = false;
+	struct csi2_dphy *csi2_dphy = NULL;
+
+	for (i = 0; i < dphy_hw->dphy_dev_num; i++) {
+		csi2_dphy = dphy_hw->dphy_dev[i];
+		if (csi2_dphy &&
+		    csi2_dphy->phy_index == dphy->phy_index)
+			is_find_dev = true;
+		if (is_find_dev) {
+			if (i < dphy_hw->dphy_dev_num - 1)
+				dphy_hw->dphy_dev[i] = dphy_hw->dphy_dev[i + 1];
+			else
+				dphy_hw->dphy_dev[i] = NULL;
+		}
+	}
+	if (is_find_dev)
+		dphy_hw->dphy_dev_num--;
+}
+
 static int rockchip_csi2_dphy_detach_hw(struct csi2_dphy *dphy, int csi_idx, int index)
 {
 	struct csi2_dphy_hw *dphy_hw = NULL;
 	struct samsung_mipi_dcphy *dcphy_hw = NULL;
-	struct csi2_dphy *csi2_dphy = NULL;
-	int i = 0;
 
 	if (dphy->drv_data->chip_id == CHIP_ID_RK3568 ||
 	    dphy->drv_data->chip_id == CHIP_ID_RV1106) {
@@ -269,15 +315,7 @@
 			return -EINVAL;
 		}
 		mutex_lock(&dphy_hw->mutex);
-		for (i = 0; i < dphy_hw->dphy_dev_num; i++) {
-			csi2_dphy = dphy_hw->dphy_dev[i];
-			if (csi2_dphy &&
-			    csi2_dphy->phy_index == dphy->phy_index) {
-				dphy_hw->dphy_dev[i] = NULL;
-				dphy_hw->dphy_dev_num--;
-				break;
-			}
-		}
+		rockchip_csi2_inno_phy_remove_dphy_dev(dphy, dphy_hw);
 		mutex_unlock(&dphy_hw->mutex);
 	} else if (dphy->drv_data->chip_id == CHIP_ID_RK3588) {
 		if (csi_idx < 2) {
@@ -288,7 +326,7 @@
 				return -EINVAL;
 			}
 			mutex_lock(&dcphy_hw->mutex);
-			dcphy_hw->dphy_dev_num--;
+			rockchip_csi2_samsung_phy_remove_dphy_dev(dphy, dcphy_hw);
 			mutex_unlock(&dcphy_hw->mutex);
 		} else {
 			dphy_hw = (struct csi2_dphy_hw *)dphy->phy_hw[index];
@@ -298,7 +336,7 @@
 				return -EINVAL;
 			}
 			mutex_lock(&dphy_hw->mutex);
-			dphy_hw->dphy_dev_num--;
+			rockchip_csi2_inno_phy_remove_dphy_dev(dphy, dphy_hw);
 			mutex_unlock(&dphy_hw->mutex);
 		}
 	} else {
@@ -309,7 +347,7 @@
 			return -EINVAL;
 		}
 		mutex_lock(&dphy_hw->mutex);
-		dphy_hw->dphy_dev_num--;
+		rockchip_csi2_inno_phy_remove_dphy_dev(dphy, dphy_hw);
 		mutex_unlock(&dphy_hw->mutex);
 	}
 
@@ -651,6 +689,8 @@
 {
 	struct csi2_dphy *dphy = to_csi2_dphy(sd);
 	long ret = 0;
+	int i = 0;
+	int on = 0;
 
 	switch (cmd) {
 	case RKCIF_CMD_SET_CSI_IDX:
@@ -658,6 +698,24 @@
 		    dphy->drv_data->chip_id != CHIP_ID_RV1106)
 			dphy->csi_info = *((struct rkcif_csi_info *)arg);
 		break;
+	case RKMODULE_SET_QUICK_STREAM:
+		for (i = 0; i < dphy->csi_info.csi_num; i++) {
+			if (dphy->csi_info.dphy_vendor[i] == PHY_VENDOR_INNO) {
+				dphy->dphy_hw = (struct csi2_dphy_hw *)dphy->phy_hw[i];
+				if (!dphy->dphy_hw ||
+				    !dphy->dphy_hw->quick_stream_off ||
+				    !dphy->dphy_hw->quick_stream_on) {
+					ret = -EINVAL;
+					break;
+				}
+				on = *(int *)arg;
+				if (on)
+					dphy->dphy_hw->quick_stream_on(dphy, sd);
+				else
+					dphy->dphy_hw->quick_stream_off(dphy, sd);
+			}
+		}
+		break;
 	default:
 		ret = -ENOIOCTLCMD;
 		break;
diff --git a/kernel/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/kernel/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
index 365d562..f3380b0 100644
--- a/kernel/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
+++ b/kernel/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
@@ -343,6 +343,9 @@
 	 * PLL_Output_Frequency: it is equal to DDR-Clock-Frequency * 2
 	 */
 	fref = prate / 2;
+	if (!fref)
+		return 0;
+
 	if (rate > 1000000000UL)
 		fout = 1000000000UL;
 	else
@@ -356,6 +359,9 @@
 		u64 tmp;
 		u32 delta;
 
+		if (!_prediv)
+			continue;
+
 		tmp = (u64)fout * _prediv;
 		do_div(tmp, fref);
 		_fbdiv = tmp;
diff --git a/kernel/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/kernel/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
index 9ca20c9..2b0f5f2 100644
--- a/kernel/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
+++ b/kernel/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
@@ -745,10 +745,12 @@
 		do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2));
 	}
 
-	inno->pixclock = vco;
-	dev_dbg(inno->dev, "%s rate %lu\n", __func__, inno->pixclock);
+	inno->pixclock = DIV_ROUND_CLOSEST((unsigned long)vco, 1000) * 1000;
 
-	return vco;
+	dev_dbg(inno->dev, "%s rate %lu vco %llu\n",
+		__func__, inno->pixclock, vco);
+
+	return inno->pixclock;
 }
 
 static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw,
@@ -790,8 +792,8 @@
 			 RK3328_PRE_PLL_POWER_DOWN);
 
 	/* Configure pre-pll */
-	inno_update_bits(inno, 0xa0, RK3228_PCLK_VCO_DIV_5_MASK,
-			 RK3228_PCLK_VCO_DIV_5(cfg->vco_div_5_en));
+	inno_update_bits(inno, 0xa0, RK3328_PCLK_VCO_DIV_5_MASK,
+			 RK3328_PCLK_VCO_DIV_5(cfg->vco_div_5_en));
 	inno_write(inno, 0xa1, RK3328_PRE_PLL_PRE_DIV(cfg->prediv));
 
 	val = RK3328_SPREAD_SPECTRUM_MOD_DISABLE;
@@ -1021,9 +1023,10 @@
 
 	inno_write(inno, 0xac, RK3328_POST_PLL_FB_DIV_7_0(cfg->fbdiv));
 	if (cfg->postdiv == 1) {
-		inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS);
 		inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) |
 			   RK3328_POST_PLL_PRE_DIV(cfg->prediv));
+		inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS |
+			   RK3328_POST_PLL_POWER_DOWN);
 	} else {
 		v = (cfg->postdiv / 2) - 1;
 		v &= RK3328_POST_PLL_POST_DIV_MASK;
@@ -1031,7 +1034,8 @@
 		inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) |
 			   RK3328_POST_PLL_PRE_DIV(cfg->prediv));
 		inno_write(inno, 0xaa, RK3328_POST_PLL_POST_DIV_ENABLE |
-			   RK3328_POST_PLL_REFCLK_SEL_TMDS);
+			   RK3328_POST_PLL_REFCLK_SEL_TMDS |
+			   RK3328_POST_PLL_POWER_DOWN);
 	}
 
 	for (v = 0; v < 14; v++)
diff --git a/kernel/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/kernel/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 20cbf30..b75f14b 100644
--- a/kernel/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/kernel/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -888,8 +888,10 @@
 		goto unlock;
 
 	ret = property_enable(base, &rport->port_cfg->phy_sus, false);
-	if (ret)
+	if (ret) {
+		clk_disable_unprepare(rphy->clk480m);
 		goto unlock;
+	}
 
 	/*
 	 * For rk3588, it needs to reset phy when exit from
@@ -902,8 +904,10 @@
 	if (rport->port_id == USB2PHY_PORT_OTG &&
 	    of_device_is_compatible(rphy->dev->of_node, "rockchip,rk3588-usb2phy")) {
 		ret = rockchip_usb2phy_reset(rphy);
-		if (ret)
+		if (ret) {
+			clk_disable_unprepare(rphy->clk480m);
 			goto unlock;
+		}
 	}
 
 	/* waiting for the utmi_clk to become stable */
diff --git a/kernel/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/kernel/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
index 3e8e436..c844328 100644
--- a/kernel/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+++ b/kernel/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
@@ -287,9 +287,42 @@
 	return 0;
 }
 
+static const char *rockchip_combphy_mode2str(enum phy_mode mode)
+{
+	switch (mode) {
+	case PHY_TYPE_SATA:
+		return "SATA";
+	case PHY_TYPE_PCIE:
+		return "PCIe";
+	case PHY_TYPE_USB3:
+		return "USB3";
+	case PHY_TYPE_SGMII:
+	case PHY_TYPE_QSGMII:
+		return "GMII";
+	default:
+		return "Unknown";
+	}
+}
+
+static int rockchip_combphy_validate(struct phy *phy, enum phy_mode mode, int submode,
+			      union phy_configure_opts *opts)
+{
+	struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
+
+	if (mode != priv->mode) {
+		dev_err(priv->dev, "expected mode is %s, but current mode is %s\n",
+			rockchip_combphy_mode2str(mode),
+			rockchip_combphy_mode2str(priv->mode));
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static const struct phy_ops rochchip_combphy_ops = {
 	.init = rockchip_combphy_init,
 	.exit = rockchip_combphy_exit,
+	.validate = rockchip_combphy_validate,
 	.owner = THIS_MODULE,
 };
 
diff --git a/kernel/drivers/phy/rockchip/phy-rockchip-naneng-usb2.c b/kernel/drivers/phy/rockchip/phy-rockchip-naneng-usb2.c
index e051b1a..7edd532 100644
--- a/kernel/drivers/phy/rockchip/phy-rockchip-naneng-usb2.c
+++ b/kernel/drivers/phy/rockchip/phy-rockchip-naneng-usb2.c
@@ -1755,6 +1755,10 @@
 	if (rphy->phy_cfg->phy_lowpower)
 		ret = rphy->phy_cfg->phy_lowpower(rphy, true);
 
+	/* Set gpio output low to avoid leakage */
+	if (rphy->vup_gpio && !wakeup_enable)
+		gpiod_set_value(rphy->vup_gpio, 1);
+
 	return ret;
 }
 
@@ -1770,6 +1774,10 @@
 	if (device_may_wakeup(rphy->dev))
 		wakeup_enable = true;
 
+	/* Set gpio output high to disable pull-up circuit on DM */
+	if (rphy->vup_gpio && !wakeup_enable)
+		gpiod_set_value(rphy->vup_gpio, 0);
+
 	/* exit low power state */
 	if (rphy->phy_cfg->phy_lowpower)
 		ret = rphy->phy_cfg->phy_lowpower(rphy, false);
diff --git a/kernel/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c b/kernel/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
index 125e58d..bd8a0ac 100644
--- a/kernel/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
+++ b/kernel/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
@@ -1744,7 +1744,7 @@
 	reset_control_assert(samsung->apb_rst);
 	udelay(1);
 	reset_control_deassert(samsung->apb_rst);
-	if (atomic_read(&samsung->stream_cnt)) {
+	if (atomic_read(&samsung->stream_cnt) && samsung->dphy_dev[0]) {
 		sensor_sd = get_remote_sensor(&samsung->dphy_dev[0]->sd);
 		samsung->stream_off(samsung->dphy_dev[0], &samsung->dphy_dev[0]->sd);
 		if (sensor_sd)
diff --git a/kernel/drivers/phy/st/phy-miphy28lp.c b/kernel/drivers/phy/st/phy-miphy28lp.c
index 068160a..e30305b 100644
--- a/kernel/drivers/phy/st/phy-miphy28lp.c
+++ b/kernel/drivers/phy/st/phy-miphy28lp.c
@@ -9,6 +9,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -484,19 +485,11 @@
 
 static inline int miphy28lp_wait_compensation(struct miphy28lp_phy *miphy_phy)
 {
-	unsigned long finish = jiffies + 5 * HZ;
 	u8 val;
 
 	/* Waiting for Compensation to complete */
-	do {
-		val = readb_relaxed(miphy_phy->base + MIPHY_COMP_FSM_6);
-
-		if (time_after_eq(jiffies, finish))
-			return -EBUSY;
-		cpu_relax();
-	} while (!(val & COMP_DONE));
-
-	return 0;
+	return readb_relaxed_poll_timeout(miphy_phy->base + MIPHY_COMP_FSM_6,
+					  val, val & COMP_DONE, 1, 5 * USEC_PER_SEC);
 }
 
 
@@ -805,7 +798,6 @@
 
 static inline int miphy_is_ready(struct miphy28lp_phy *miphy_phy)
 {
-	unsigned long finish = jiffies + 5 * HZ;
 	u8 mask = HFC_PLL | HFC_RDY;
 	u8 val;
 
@@ -816,21 +808,14 @@
 	if (miphy_phy->type == PHY_TYPE_SATA)
 		mask |= PHY_RDY;
 
-	do {
-		val = readb_relaxed(miphy_phy->base + MIPHY_STATUS_1);
-		if ((val & mask) != mask)
-			cpu_relax();
-		else
-			return 0;
-	} while (!time_after_eq(jiffies, finish));
-
-	return -EBUSY;
+	return readb_relaxed_poll_timeout(miphy_phy->base + MIPHY_STATUS_1,
+					  val, (val & mask) == mask, 1,
+					  5 * USEC_PER_SEC);
 }
 
 static int miphy_osc_is_ready(struct miphy28lp_phy *miphy_phy)
 {
 	struct miphy28lp_dev *miphy_dev = miphy_phy->phydev;
-	unsigned long finish = jiffies + 5 * HZ;
 	u32 val;
 
 	if (!miphy_phy->osc_rdy)
@@ -839,17 +824,10 @@
 	if (!miphy_phy->syscfg_reg[SYSCFG_STATUS])
 		return -EINVAL;
 
-	do {
-		regmap_read(miphy_dev->regmap,
-				miphy_phy->syscfg_reg[SYSCFG_STATUS], &val);
-
-		if ((val & MIPHY_OSC_RDY) != MIPHY_OSC_RDY)
-			cpu_relax();
-		else
-			return 0;
-	} while (!time_after_eq(jiffies, finish));
-
-	return -EBUSY;
+	return regmap_read_poll_timeout(miphy_dev->regmap,
+					miphy_phy->syscfg_reg[SYSCFG_STATUS],
+					val, val & MIPHY_OSC_RDY, 1,
+					5 * USEC_PER_SEC);
 }
 
 static int miphy28lp_get_resource_byname(struct device_node *child,
diff --git a/kernel/drivers/phy/tegra/xusb.c b/kernel/drivers/phy/tegra/xusb.c
index 181a1be..8f11b29 100644
--- a/kernel/drivers/phy/tegra/xusb.c
+++ b/kernel/drivers/phy/tegra/xusb.c
@@ -556,6 +556,7 @@
 		usb_role_switch_unregister(port->usb_role_sw);
 		cancel_work_sync(&port->usb_phy_work);
 		usb_remove_phy(&port->usb_phy);
+		port->usb_phy.dev->driver = NULL;
 	}
 
 	if (port->ops->remove)
@@ -662,6 +663,9 @@
 	port->dev.driver = devm_kzalloc(&port->dev,
 					sizeof(struct device_driver),
 					GFP_KERNEL);
+	if (!port->dev.driver)
+		return -ENOMEM;
+
 	port->dev.driver->owner	 = THIS_MODULE;
 
 	port->usb_role_sw = usb_role_switch_register(&port->dev,
@@ -775,6 +779,7 @@
 	usb2->base.lane = usb2->base.ops->map(&usb2->base);
 	if (IS_ERR(usb2->base.lane)) {
 		err = PTR_ERR(usb2->base.lane);
+		tegra_xusb_port_unregister(&usb2->base);
 		goto out;
 	}
 
@@ -841,6 +846,7 @@
 	ulpi->base.lane = ulpi->base.ops->map(&ulpi->base);
 	if (IS_ERR(ulpi->base.lane)) {
 		err = PTR_ERR(ulpi->base.lane);
+		tegra_xusb_port_unregister(&ulpi->base);
 		goto out;
 	}
 
diff --git a/kernel/drivers/phy/ti/Kconfig b/kernel/drivers/phy/ti/Kconfig
index 15a3bcf..b905902 100644
--- a/kernel/drivers/phy/ti/Kconfig
+++ b/kernel/drivers/phy/ti/Kconfig
@@ -23,7 +23,7 @@
 
 config PHY_AM654_SERDES
 	tristate "TI AM654 SERDES support"
-	depends on OF && ARCH_K3 || COMPILE_TEST
+	depends on OF && (ARCH_K3 || COMPILE_TEST)
 	depends on COMMON_CLK
 	select GENERIC_PHY
 	select MULTIPLEXER
@@ -35,7 +35,7 @@
 
 config PHY_J721E_WIZ
 	tristate "TI J721E WIZ (SERDES Wrapper) support"
-	depends on OF && ARCH_K3 || COMPILE_TEST
+	depends on OF && (ARCH_K3 || COMPILE_TEST)
 	depends on HAS_IOMEM && OF_ADDRESS
 	depends on COMMON_CLK
 	select GENERIC_PHY
diff --git a/kernel/drivers/pinctrl/aspeed/pinctrl-aspeed.c b/kernel/drivers/pinctrl/aspeed/pinctrl-aspeed.c
index e792318..d26d859 100644
--- a/kernel/drivers/pinctrl/aspeed/pinctrl-aspeed.c
+++ b/kernel/drivers/pinctrl/aspeed/pinctrl-aspeed.c
@@ -121,7 +121,7 @@
 	int ret = 0;
 
 	if (!exprs)
-		return true;
+		return -EINVAL;
 
 	while (*exprs && !ret) {
 		ret = aspeed_sig_expr_disable(ctx, *exprs);
diff --git a/kernel/drivers/pinctrl/intel/pinctrl-cherryview.c b/kernel/drivers/pinctrl/intel/pinctrl-cherryview.c
index 2ed17cd..18b85ae 100644
--- a/kernel/drivers/pinctrl/intel/pinctrl-cherryview.c
+++ b/kernel/drivers/pinctrl/intel/pinctrl-cherryview.c
@@ -945,11 +945,6 @@
 
 		break;
 
-	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
-		if (!(ctrl1 & CHV_PADCTRL1_ODEN))
-			return -EINVAL;
-		break;
-
 	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: {
 		u32 cfg;
 
@@ -958,6 +953,16 @@
 		if (cfg != CHV_PADCTRL0_GPIOCFG_HIZ)
 			return -EINVAL;
 
+		break;
+
+	case PIN_CONFIG_DRIVE_PUSH_PULL:
+		if (ctrl1 & CHV_PADCTRL1_ODEN)
+			return -EINVAL;
+		break;
+
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		if (!(ctrl1 & CHV_PADCTRL1_ODEN))
+			return -EINVAL;
 		break;
 	}
 
@@ -1620,7 +1625,6 @@
 	const struct intel_pinctrl_soc_data *soc_data;
 	struct intel_community *community;
 	struct device *dev = &pdev->dev;
-	struct acpi_device *adev = ACPI_COMPANION(dev);
 	struct intel_pinctrl *pctrl;
 	acpi_status status;
 	int ret, irq;
@@ -1683,7 +1687,7 @@
 	if (ret)
 		return ret;
 
-	status = acpi_install_address_space_handler(adev->handle,
+	status = acpi_install_address_space_handler(ACPI_HANDLE(dev),
 					community->acpi_space_id,
 					chv_pinctrl_mmio_access_handler,
 					NULL, pctrl);
@@ -1700,7 +1704,7 @@
 	struct intel_pinctrl *pctrl = platform_get_drvdata(pdev);
 	const struct intel_community *community = &pctrl->communities[0];
 
-	acpi_remove_address_space_handler(ACPI_COMPANION(&pdev->dev),
+	acpi_remove_address_space_handler(ACPI_HANDLE(&pdev->dev),
 					  community->acpi_space_id,
 					  chv_pinctrl_mmio_access_handler);
 
diff --git a/kernel/drivers/pinctrl/intel/pinctrl-intel.c b/kernel/drivers/pinctrl/intel/pinctrl-intel.c
index db9087c..2ef9e2d 100644
--- a/kernel/drivers/pinctrl/intel/pinctrl-intel.c
+++ b/kernel/drivers/pinctrl/intel/pinctrl-intel.c
@@ -1606,6 +1606,12 @@
 EXPORT_SYMBOL_GPL(intel_pinctrl_get_soc_data);
 
 #ifdef CONFIG_PM_SLEEP
+static bool __intel_gpio_is_direct_irq(u32 value)
+{
+	return (value & PADCFG0_GPIROUTIOXAPIC) && (value & PADCFG0_GPIOTXDIS) &&
+	       (__intel_gpio_get_gpio_mode(value) == PADCFG0_PMODE_GPIO);
+}
+
 static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int pin)
 {
 	const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin);
@@ -1639,8 +1645,7 @@
 	 * See https://bugzilla.kernel.org/show_bug.cgi?id=214749.
 	 */
 	value = readl(intel_get_padcfg(pctrl, pin, PADCFG0));
-	if ((value & PADCFG0_GPIROUTIOXAPIC) && (value & PADCFG0_GPIOTXDIS) &&
-	    (__intel_gpio_get_gpio_mode(value) == PADCFG0_PMODE_GPIO))
+	if (__intel_gpio_is_direct_irq(value))
 		return true;
 
 	return false;
@@ -1770,7 +1775,12 @@
 	for (i = 0; i < pctrl->soc->npins; i++) {
 		const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i];
 
-		if (!intel_pinctrl_should_save(pctrl, desc->number))
+		if (!(intel_pinctrl_should_save(pctrl, desc->number) ||
+		      /*
+		       * If the firmware mangled the register contents too much,
+		       * check the saved value for the Direct IRQ mode.
+		       */
+		      __intel_gpio_is_direct_irq(pads[i].padcfg0)))
 			continue;
 
 		intel_restore_padcfg(pctrl, desc->number, PADCFG0, pads[i].padcfg0);
diff --git a/kernel/drivers/pinctrl/mediatek/pinctrl-paris.c b/kernel/drivers/pinctrl/mediatek/pinctrl-paris.c
index d0a4ebb..e486d66 100644
--- a/kernel/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/kernel/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -574,7 +574,7 @@
 ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
 	unsigned int gpio, char *buf, unsigned int bufLen)
 {
-	int pinmux, pullup, pullen, len = 0, r1 = -1, r0 = -1;
+	int pinmux, pullup = 0, pullen = 0, len = 0, r1 = -1, r0 = -1;
 	const struct mtk_pin_desc *desc;
 
 	if (gpio >= hw->soc->npins)
@@ -637,7 +637,7 @@
 			  unsigned int gpio)
 {
 	struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
-	char buf[PIN_DBG_BUF_SZ];
+	char buf[PIN_DBG_BUF_SZ] = { 0 };
 
 	(void)mtk_pctrl_show_one_pin(hw, gpio, buf, PIN_DBG_BUF_SZ);
 
diff --git a/kernel/drivers/pinctrl/meson/pinctrl-meson-axg.c b/kernel/drivers/pinctrl/meson/pinctrl-meson-axg.c
index 7bfecdf..d249a03 100644
--- a/kernel/drivers/pinctrl/meson/pinctrl-meson-axg.c
+++ b/kernel/drivers/pinctrl/meson/pinctrl-meson-axg.c
@@ -400,6 +400,7 @@
 	GPIO_GROUP(GPIOA_15),
 	GPIO_GROUP(GPIOA_16),
 	GPIO_GROUP(GPIOA_17),
+	GPIO_GROUP(GPIOA_18),
 	GPIO_GROUP(GPIOA_19),
 	GPIO_GROUP(GPIOA_20),
 
diff --git a/kernel/drivers/pinctrl/pinconf-generic.c b/kernel/drivers/pinctrl/pinconf-generic.c
index 42e27db..762abb0 100644
--- a/kernel/drivers/pinctrl/pinconf-generic.c
+++ b/kernel/drivers/pinctrl/pinconf-generic.c
@@ -393,8 +393,10 @@
 	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;
 
diff --git a/kernel/drivers/pinctrl/pinctrl-amd.c b/kernel/drivers/pinctrl/pinctrl-amd.c
index 82b658a..71576dc 100644
--- a/kernel/drivers/pinctrl/pinctrl-amd.c
+++ b/kernel/drivers/pinctrl/pinctrl-amd.c
@@ -126,6 +126,14 @@
 	struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
 
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
+
+	/* Use special handling for Pin0 debounce */
+	if (offset == 0) {
+		pin_reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
+		if (pin_reg & INTERNAL_GPIO0_DEBOUNCE)
+			debounce = 0;
+	}
+
 	pin_reg = readl(gpio_dev->base + offset * 4);
 
 	if (debounce) {
@@ -181,18 +189,6 @@
 	return ret;
 }
 
-static int amd_gpio_set_config(struct gpio_chip *gc, unsigned offset,
-			       unsigned long config)
-{
-	u32 debounce;
-
-	if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)
-		return -ENOTSUPP;
-
-	debounce = pinconf_to_config_argument(config);
-	return amd_gpio_set_debounce(gc, offset, debounce);
-}
-
 #ifdef CONFIG_DEBUG_FS
 static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc)
 {
@@ -215,6 +211,7 @@
 	char *output_value;
 	char *output_enable;
 
+	seq_printf(s, "WAKE_INT_MASTER_REG: 0x%08x\n", readl(gpio_dev->base + WAKE_INT_MASTER_REG));
 	for (bank = 0; bank < gpio_dev->hwbank_num; bank++) {
 		seq_printf(s, "GPIO bank%d\t", bank);
 
@@ -656,7 +653,7 @@
 		break;
 
 	default:
-		dev_err(&gpio_dev->pdev->dev, "Invalid config param %04x\n",
+		dev_dbg(&gpio_dev->pdev->dev, "Invalid config param %04x\n",
 			param);
 		return -ENOTSUPP;
 	}
@@ -667,7 +664,7 @@
 }
 
 static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
-				unsigned long *configs, unsigned num_configs)
+			   unsigned long *configs, unsigned int num_configs)
 {
 	int i;
 	u32 arg;
@@ -709,7 +706,7 @@
 			break;
 
 		default:
-			dev_err(&gpio_dev->pdev->dev,
+			dev_dbg(&gpio_dev->pdev->dev,
 				"Invalid config param %04x\n", param);
 			ret = -ENOTSUPP;
 		}
@@ -757,6 +754,20 @@
 	return 0;
 }
 
+static int amd_gpio_set_config(struct gpio_chip *gc, unsigned int pin,
+			       unsigned long config)
+{
+	struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
+
+	if (pinconf_to_config_param(config) == PIN_CONFIG_INPUT_DEBOUNCE) {
+		u32 debounce = pinconf_to_config_argument(config);
+
+		return amd_gpio_set_debounce(gc, pin, debounce);
+	}
+
+	return amd_pinconf_set(gpio_dev->pctrl, pin, &config, 1);
+}
+
 static const struct pinconf_ops amd_pinconf_ops = {
 	.pin_config_get		= amd_pinconf_get,
 	.pin_config_set		= amd_pinconf_set,
@@ -784,9 +795,9 @@
 
 		raw_spin_lock_irqsave(&gpio_dev->lock, flags);
 
-		pin_reg = readl(gpio_dev->base + i * 4);
+		pin_reg = readl(gpio_dev->base + pin * 4);
 		pin_reg &= ~mask;
-		writel(pin_reg, gpio_dev->base + i * 4);
+		writel(pin_reg, gpio_dev->base + pin * 4);
 
 		raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 	}
diff --git a/kernel/drivers/pinctrl/pinctrl-amd.h b/kernel/drivers/pinctrl/pinctrl-amd.h
index 95e7634..9f95ec9 100644
--- a/kernel/drivers/pinctrl/pinctrl-amd.h
+++ b/kernel/drivers/pinctrl/pinctrl-amd.h
@@ -17,6 +17,7 @@
 #define AMD_GPIO_PINS_BANK3     32
 
 #define WAKE_INT_MASTER_REG 0xfc
+#define INTERNAL_GPIO0_DEBOUNCE (1 << 15)
 #define EOI_MASK (1 << 29)
 
 #define WAKE_INT_STATUS_REG0 0x2f8
diff --git a/kernel/drivers/pinctrl/pinctrl-at91-pio4.c b/kernel/drivers/pinctrl/pinctrl-at91-pio4.c
index 578b387..bf8aa0e 100644
--- a/kernel/drivers/pinctrl/pinctrl-at91-pio4.c
+++ b/kernel/drivers/pinctrl/pinctrl-at91-pio4.c
@@ -1081,8 +1081,10 @@
 
 		pin_desc[i].number = i;
 		/* Pin naming convention: P(bank_name)(bank_pin_number). */
-		pin_desc[i].name = kasprintf(GFP_KERNEL, "P%c%d",
-					     bank + 'A', line);
+		pin_desc[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "P%c%d",
+						  bank + 'A', line);
+		if (!pin_desc[i].name)
+			return -ENOMEM;
 
 		group->name = group_names[i] = pin_desc[i].name;
 		group->pin = pin_desc[i].number;
@@ -1139,7 +1141,6 @@
 		dev_err(dev, "can't add the irq domain\n");
 		return -ENODEV;
 	}
-	atmel_pioctrl->irq_domain->name = "atmel gpio";
 
 	for (i = 0; i < atmel_pioctrl->npins; i++) {
 		int irq = irq_create_mapping(atmel_pioctrl->irq_domain, i);
diff --git a/kernel/drivers/pinctrl/pinctrl-at91.c b/kernel/drivers/pinctrl/pinctrl-at91.c
index 9015486..52ecd47 100644
--- a/kernel/drivers/pinctrl/pinctrl-at91.c
+++ b/kernel/drivers/pinctrl/pinctrl-at91.c
@@ -1891,7 +1891,7 @@
 	}
 
 	for (i = 0; i < chip->ngpio; i++)
-		names[i] = kasprintf(GFP_KERNEL, "pio%c%d", alias_idx + 'A', i);
+		names[i] = devm_kasprintf(&pdev->dev, GFP_KERNEL, "pio%c%d", alias_idx + 'A', i);
 
 	chip->names = (const char *const *)names;
 
diff --git a/kernel/drivers/pinctrl/pinctrl-ingenic.c b/kernel/drivers/pinctrl/pinctrl-ingenic.c
index e0df5ad..4d07c53 100644
--- a/kernel/drivers/pinctrl/pinctrl-ingenic.c
+++ b/kernel/drivers/pinctrl/pinctrl-ingenic.c
@@ -11,6 +11,7 @@
 #include <linux/gpio/driver.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/kernel.h>
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
@@ -2826,6 +2827,8 @@
 	return 0;
 }
 
+#define IF_ENABLED(cfg, ptr)	PTR_IF(IS_ENABLED(cfg), (ptr))
+
 static const struct of_device_id ingenic_pinctrl_of_match[] = {
 	{ .compatible = "ingenic,jz4740-pinctrl", .data = &jz4740_chip_info },
 	{ .compatible = "ingenic,jz4725b-pinctrl", .data = &jz4725b_chip_info },
diff --git a/kernel/drivers/pinctrl/pinctrl-mcp23s08_spi.c b/kernel/drivers/pinctrl/pinctrl-mcp23s08_spi.c
index 9ae1031..ea059b9 100644
--- a/kernel/drivers/pinctrl/pinctrl-mcp23s08_spi.c
+++ b/kernel/drivers/pinctrl/pinctrl-mcp23s08_spi.c
@@ -91,18 +91,28 @@
 		mcp->reg_shift = 0;
 		mcp->chip.ngpio = 8;
 		mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL, "mcp23s08.%d", addr);
+		if (!mcp->chip.label)
+			return -ENOMEM;
 
 		config = &mcp23x08_regmap;
 		name = devm_kasprintf(dev, GFP_KERNEL, "%d", addr);
+		if (!name)
+			return -ENOMEM;
+
 		break;
 
 	case MCP_TYPE_S17:
 		mcp->reg_shift = 1;
 		mcp->chip.ngpio = 16;
 		mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL, "mcp23s17.%d", addr);
+		if (!mcp->chip.label)
+			return -ENOMEM;
 
 		config = &mcp23x17_regmap;
 		name = devm_kasprintf(dev, GFP_KERNEL, "%d", addr);
+		if (!name)
+			return -ENOMEM;
+
 		break;
 
 	case MCP_TYPE_S18:
diff --git a/kernel/drivers/pinctrl/pinctrl-ocelot.c b/kernel/drivers/pinctrl/pinctrl-ocelot.c
index a4a1b00..c42a5b0 100644
--- a/kernel/drivers/pinctrl/pinctrl-ocelot.c
+++ b/kernel/drivers/pinctrl/pinctrl-ocelot.c
@@ -575,7 +575,7 @@
 	regmap_update_bits(info->map, REG_ALT(0, info, pin->pin),
 			   BIT(p), f << p);
 	regmap_update_bits(info->map, REG_ALT(1, info, pin->pin),
-			   BIT(p), f << (p - 1));
+			   BIT(p), (f >> 1) << p);
 
 	return 0;
 }
diff --git a/kernel/drivers/pinctrl/pinctrl-rockchip.c b/kernel/drivers/pinctrl/pinctrl-rockchip.c
index 01a5c1a..858192d 100644
--- a/kernel/drivers/pinctrl/pinctrl-rockchip.c
+++ b/kernel/drivers/pinctrl/pinctrl-rockchip.c
@@ -3193,6 +3193,14 @@
 		pull_type = bank->pull_type[pin_num / 8];
 		data >>= bit;
 		data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
+		/*
+		 * In the TRM, pull-up being 1 for everything except the GPIO0_D3-D6,
+		 * where that pull up value becomes 3.
+		 */
+		if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) {
+			if (data == 3)
+				data = 1;
+		}
 
 		return rockchip_pull_list[pull_type][data];
 	default:
@@ -3886,6 +3894,7 @@
 		np_config = of_find_node_by_phandle(be32_to_cpup(phandle));
 		ret = pinconf_generic_parse_dt_config(np_config, NULL,
 				&grp->data[j].configs, &grp->data[j].nconfigs);
+		of_node_put(np_config);
 		if (ret)
 			return ret;
 	}
diff --git a/kernel/drivers/pinctrl/pinctrl-single.c b/kernel/drivers/pinctrl/pinctrl-single.c
index d139cd9..22e4719 100644
--- a/kernel/drivers/pinctrl/pinctrl-single.c
+++ b/kernel/drivers/pinctrl/pinctrl-single.c
@@ -372,6 +372,8 @@
 	if (!pcs->fmask)
 		return 0;
 	function = pinmux_generic_get_function(pctldev, fselector);
+	if (!function)
+		return -EINVAL;
 	func = function->data;
 	if (!func)
 		return -EINVAL;
diff --git a/kernel/drivers/pinctrl/qcom/pinctrl-msm8976.c b/kernel/drivers/pinctrl/qcom/pinctrl-msm8976.c
index ec43edf..e11d845 100644
--- a/kernel/drivers/pinctrl/qcom/pinctrl-msm8976.c
+++ b/kernel/drivers/pinctrl/qcom/pinctrl-msm8976.c
@@ -733,7 +733,7 @@
 	"gpio74",
 };
 static const char * const wcss_bt_groups[] = {
-	"gpio39", "gpio47", "gpio88",
+	"gpio39", "gpio47", "gpio48",
 };
 static const char * const sdc3_groups[] = {
 	"gpio39", "gpio40", "gpio41",
@@ -958,9 +958,9 @@
 	PINGROUP(37, NA, NA, NA, qdss_tracedata_b, NA, NA, NA, NA, NA),
 	PINGROUP(38, NA, NA, NA, NA, NA, NA, NA, qdss_tracedata_b, NA),
 	PINGROUP(39, wcss_bt, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
-	PINGROUP(40, wcss_wlan, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
-	PINGROUP(41, wcss_wlan, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
-	PINGROUP(42, wcss_wlan, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
+	PINGROUP(40, wcss_wlan2, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
+	PINGROUP(41, wcss_wlan1, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
+	PINGROUP(42, wcss_wlan0, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
 	PINGROUP(43, wcss_wlan, sdc3, NA, NA, qdss_tracedata_a, NA, NA, NA, NA),
 	PINGROUP(44, wcss_wlan, sdc3, NA, NA, NA, NA, NA, NA, NA),
 	PINGROUP(45, wcss_fm, NA, qdss_tracectl_a, NA, NA, NA, NA, NA, NA),
diff --git a/kernel/drivers/pinctrl/renesas/pinctrl-rza2.c b/kernel/drivers/pinctrl/renesas/pinctrl-rza2.c
index 32829eb..ddd8ee6 100644
--- a/kernel/drivers/pinctrl/renesas/pinctrl-rza2.c
+++ b/kernel/drivers/pinctrl/renesas/pinctrl-rza2.c
@@ -14,6 +14,7 @@
 #include <linux/gpio/driver.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/of_device.h>
 #include <linux/pinctrl/pinmux.h>
 
@@ -46,6 +47,7 @@
 	struct pinctrl_dev *pctl;
 	struct pinctrl_gpio_range gpio_range;
 	int npins;
+	struct mutex mutex; /* serialize adding groups and functions */
 };
 
 #define RZA2_PDR(port)		(0x0000 + (port) * 2)	/* Direction 16-bit */
@@ -359,10 +361,14 @@
 		psel_val[i] = MUX_FUNC(value);
 	}
 
+	mutex_lock(&priv->mutex);
+
 	/* Register a single pin group listing all the pins we read from DT */
 	gsel = pinctrl_generic_add_group(pctldev, np->name, pins, npins, NULL);
-	if (gsel < 0)
-		return gsel;
+	if (gsel < 0) {
+		ret = gsel;
+		goto unlock;
+	}
 
 	/*
 	 * Register a single group function where the 'data' is an array PSEL
@@ -391,6 +397,8 @@
 	(*map)->data.mux.function = np->name;
 	*num_maps = 1;
 
+	mutex_unlock(&priv->mutex);
+
 	return 0;
 
 remove_function:
@@ -398,6 +406,9 @@
 
 remove_group:
 	pinctrl_generic_remove_group(pctldev, gsel);
+
+unlock:
+	mutex_unlock(&priv->mutex);
 
 	dev_err(priv->dev, "Unable to parse DT node %s\n", np->name);
 
@@ -474,6 +485,8 @@
 	if (IS_ERR(priv->base))
 		return PTR_ERR(priv->base);
 
+	mutex_init(&priv->mutex);
+
 	platform_set_drvdata(pdev, priv);
 
 	priv->npins = (int)(uintptr_t)of_device_get_match_data(&pdev->dev) *
diff --git a/kernel/drivers/pinctrl/stm32/pinctrl-stm32.c b/kernel/drivers/pinctrl/stm32/pinctrl-stm32.c
index 60406f1..2d852f1 100644
--- a/kernel/drivers/pinctrl/stm32/pinctrl-stm32.c
+++ b/kernel/drivers/pinctrl/stm32/pinctrl-stm32.c
@@ -1338,6 +1338,7 @@
 		return ERR_PTR(-ENXIO);
 
 	domain = irq_find_host(parent);
+	of_node_put(parent);
 	if (!domain)
 		/* domain not registered yet */
 		return ERR_PTR(-EPROBE_DEFER);
diff --git a/kernel/drivers/platform/chrome/cros_ec_chardev.c b/kernel/drivers/platform/chrome/cros_ec_chardev.c
index 0de7c25..d6de5a2 100644
--- a/kernel/drivers/platform/chrome/cros_ec_chardev.c
+++ b/kernel/drivers/platform/chrome/cros_ec_chardev.c
@@ -284,7 +284,7 @@
 	    u_cmd.insize > EC_MAX_MSG_BYTES)
 		return -EINVAL;
 
-	s_cmd = kmalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize),
+	s_cmd = kzalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize),
 			GFP_KERNEL);
 	if (!s_cmd)
 		return -ENOMEM;
diff --git a/kernel/drivers/platform/chrome/cros_usbpd_notify.c b/kernel/drivers/platform/chrome/cros_usbpd_notify.c
index 7f36142..1939014 100644
--- a/kernel/drivers/platform/chrome/cros_usbpd_notify.c
+++ b/kernel/drivers/platform/chrome/cros_usbpd_notify.c
@@ -284,7 +284,11 @@
 		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;
 }
diff --git a/kernel/drivers/platform/mellanox/Kconfig b/kernel/drivers/platform/mellanox/Kconfig
index 916b39d..1a11d1a 100644
--- a/kernel/drivers/platform/mellanox/Kconfig
+++ b/kernel/drivers/platform/mellanox/Kconfig
@@ -48,6 +48,7 @@
 	tristate "Mellanox BlueField Firmware Boot Control driver"
 	depends on ARM64
 	depends on ACPI
+	depends on NET
 	help
 	  The Mellanox BlueField firmware implements functionality to
 	  request swapping the primary and alternate eMMC boot partition,
diff --git a/kernel/drivers/platform/mellanox/mlxbf-tmfifo.c b/kernel/drivers/platform/mellanox/mlxbf-tmfifo.c
index 38800e8..194f320 100644
--- a/kernel/drivers/platform/mellanox/mlxbf-tmfifo.c
+++ b/kernel/drivers/platform/mellanox/mlxbf-tmfifo.c
@@ -56,6 +56,7 @@
  * @vq: pointer to the virtio virtqueue
  * @desc: current descriptor of the pending packet
  * @desc_head: head descriptor of the pending packet
+ * @drop_desc: dummy desc for packet dropping
  * @cur_len: processed length of the current descriptor
  * @rem_len: remaining length of the pending packet
  * @pkt_len: total length of the pending packet
@@ -72,6 +73,7 @@
 	struct virtqueue *vq;
 	struct vring_desc *desc;
 	struct vring_desc *desc_head;
+	struct vring_desc drop_desc;
 	int cur_len;
 	int rem_len;
 	u32 pkt_len;
@@ -82,6 +84,14 @@
 	int vdev_id;
 	struct mlxbf_tmfifo *fifo;
 };
+
+/* Check whether vring is in drop mode. */
+#define IS_VRING_DROP(_r) ({ \
+	typeof(_r) (r) = (_r); \
+	(r->desc_head == &r->drop_desc ? true : false); })
+
+/* A stub length to drop maximum length packet. */
+#define VRING_DROP_DESC_MAX_LEN		GENMASK(15, 0)
 
 /* Interrupt types. */
 enum {
@@ -195,7 +205,7 @@
 static efi_char16_t mlxbf_tmfifo_efi_name[] = L"RshimMacAddr";
 
 /* Maximum L2 header length. */
-#define MLXBF_TMFIFO_NET_L2_OVERHEAD	36
+#define MLXBF_TMFIFO_NET_L2_OVERHEAD	(ETH_HLEN + VLAN_HLEN)
 
 /* Supported virtio-net features. */
 #define MLXBF_TMFIFO_NET_FEATURES \
@@ -243,6 +253,7 @@
 		vring->align = SMP_CACHE_BYTES;
 		vring->index = i;
 		vring->vdev_id = tm_vdev->vdev.id.device;
+		vring->drop_desc.len = VRING_DROP_DESC_MAX_LEN;
 		dev = &tm_vdev->vdev.dev;
 
 		size = vring_size(vring->num, vring->align);
@@ -348,7 +359,7 @@
 	return len;
 }
 
-static void mlxbf_tmfifo_release_pending_pkt(struct mlxbf_tmfifo_vring *vring)
+static void mlxbf_tmfifo_release_pkt(struct mlxbf_tmfifo_vring *vring)
 {
 	struct vring_desc *desc_head;
 	u32 len = 0;
@@ -577,19 +588,25 @@
 
 	if (vring->cur_len + sizeof(u64) <= len) {
 		/* The whole word. */
-		if (is_rx)
-			memcpy(addr + vring->cur_len, &data, sizeof(u64));
-		else
-			memcpy(&data, addr + vring->cur_len, sizeof(u64));
+		if (!IS_VRING_DROP(vring)) {
+			if (is_rx)
+				memcpy(addr + vring->cur_len, &data,
+				       sizeof(u64));
+			else
+				memcpy(&data, addr + vring->cur_len,
+				       sizeof(u64));
+		}
 		vring->cur_len += sizeof(u64);
 	} else {
 		/* Leftover bytes. */
-		if (is_rx)
-			memcpy(addr + vring->cur_len, &data,
-			       len - vring->cur_len);
-		else
-			memcpy(&data, addr + vring->cur_len,
-			       len - vring->cur_len);
+		if (!IS_VRING_DROP(vring)) {
+			if (is_rx)
+				memcpy(addr + vring->cur_len, &data,
+				       len - vring->cur_len);
+			else
+				memcpy(&data, addr + vring->cur_len,
+				       len - vring->cur_len);
+		}
 		vring->cur_len = len;
 	}
 
@@ -606,13 +623,14 @@
  * flag is set.
  */
 static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring,
-				     struct vring_desc *desc,
+				     struct vring_desc **desc,
 				     bool is_rx, bool *vring_change)
 {
 	struct mlxbf_tmfifo *fifo = vring->fifo;
 	struct virtio_net_config *config;
 	struct mlxbf_tmfifo_msg_hdr hdr;
 	int vdev_id, hdr_len;
+	bool drop_rx = false;
 
 	/* Read/Write packet header. */
 	if (is_rx) {
@@ -632,8 +650,8 @@
 			if (ntohs(hdr.len) >
 			    __virtio16_to_cpu(virtio_legacy_is_little_endian(),
 					      config->mtu) +
-			    MLXBF_TMFIFO_NET_L2_OVERHEAD)
-				return;
+					      MLXBF_TMFIFO_NET_L2_OVERHEAD)
+				drop_rx = true;
 		} else {
 			vdev_id = VIRTIO_ID_CONSOLE;
 			hdr_len = 0;
@@ -648,16 +666,25 @@
 
 			if (!tm_dev2)
 				return;
-			vring->desc = desc;
+			vring->desc = *desc;
 			vring = &tm_dev2->vrings[MLXBF_TMFIFO_VRING_RX];
 			*vring_change = true;
 		}
+
+		if (drop_rx && !IS_VRING_DROP(vring)) {
+			if (vring->desc_head)
+				mlxbf_tmfifo_release_pkt(vring);
+			*desc = &vring->drop_desc;
+			vring->desc_head = *desc;
+			vring->desc = *desc;
+		}
+
 		vring->pkt_len = ntohs(hdr.len) + hdr_len;
 	} else {
 		/* Network virtio has an extra header. */
 		hdr_len = (vring->vdev_id == VIRTIO_ID_NET) ?
 			   sizeof(struct virtio_net_hdr) : 0;
-		vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, desc);
+		vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, *desc);
 		hdr.type = (vring->vdev_id == VIRTIO_ID_NET) ?
 			    VIRTIO_ID_NET : VIRTIO_ID_CONSOLE;
 		hdr.len = htons(vring->pkt_len - hdr_len);
@@ -690,15 +717,23 @@
 	/* Get the descriptor of the next packet. */
 	if (!vring->desc) {
 		desc = mlxbf_tmfifo_get_next_pkt(vring, is_rx);
-		if (!desc)
-			return false;
+		if (!desc) {
+			/* Drop next Rx packet to avoid stuck. */
+			if (is_rx) {
+				desc = &vring->drop_desc;
+				vring->desc_head = desc;
+				vring->desc = desc;
+			} else {
+				return false;
+			}
+		}
 	} else {
 		desc = vring->desc;
 	}
 
 	/* Beginning of a packet. Start to Rx/Tx packet header. */
 	if (vring->pkt_len == 0) {
-		mlxbf_tmfifo_rxtx_header(vring, desc, is_rx, &vring_change);
+		mlxbf_tmfifo_rxtx_header(vring, &desc, is_rx, &vring_change);
 		(*avail)--;
 
 		/* Return if new packet is for another ring. */
@@ -724,17 +759,24 @@
 		vring->rem_len -= len;
 
 		/* Get the next desc on the chain. */
-		if (vring->rem_len > 0 &&
+		if (!IS_VRING_DROP(vring) && vring->rem_len > 0 &&
 		    (virtio16_to_cpu(vdev, desc->flags) & VRING_DESC_F_NEXT)) {
 			idx = virtio16_to_cpu(vdev, desc->next);
 			desc = &vr->desc[idx];
 			goto mlxbf_tmfifo_desc_done;
 		}
 
-		/* Done and release the pending packet. */
-		mlxbf_tmfifo_release_pending_pkt(vring);
+		/* Done and release the packet. */
 		desc = NULL;
 		fifo->vring[is_rx] = NULL;
+		if (!IS_VRING_DROP(vring)) {
+			mlxbf_tmfifo_release_pkt(vring);
+		} else {
+			vring->pkt_len = 0;
+			vring->desc_head = NULL;
+			vring->desc = NULL;
+			return false;
+		}
 
 		/*
 		 * Make sure the load/store are in order before
@@ -868,6 +910,7 @@
 			tm_vdev = fifo->vdev[VIRTIO_ID_CONSOLE];
 			mlxbf_tmfifo_console_output(tm_vdev, vring);
 			spin_unlock_irqrestore(&fifo->spin_lock[0], flags);
+			set_bit(MLXBF_TM_TX_LWM_IRQ, &fifo->pend_events);
 		} else if (test_and_set_bit(MLXBF_TM_TX_LWM_IRQ,
 					    &fifo->pend_events)) {
 			return true;
@@ -913,7 +956,7 @@
 
 		/* Release the pending packet. */
 		if (vring->desc)
-			mlxbf_tmfifo_release_pending_pkt(vring);
+			mlxbf_tmfifo_release_pkt(vring);
 		vq = vring->vq;
 		if (vq) {
 			vring->vq = NULL;
diff --git a/kernel/drivers/platform/x86/Kconfig b/kernel/drivers/platform/x86/Kconfig
index a185868..84c5b92 100644
--- a/kernel/drivers/platform/x86/Kconfig
+++ b/kernel/drivers/platform/x86/Kconfig
@@ -1195,7 +1195,8 @@
 
 config MLX_PLATFORM
 	tristate "Mellanox Technologies platform support"
-	depends on I2C && REGMAP
+	depends on I2C
+	select REGMAP
 	help
 	  This option enables system support for the Mellanox Technologies
 	  platform. The Mellanox systems provide data center networking
diff --git a/kernel/drivers/platform/x86/asus-nb-wmi.c b/kernel/drivers/platform/x86/asus-nb-wmi.c
index 949ddeb..b4a5cbd 100644
--- a/kernel/drivers/platform/x86/asus-nb-wmi.c
+++ b/kernel/drivers/platform/x86/asus-nb-wmi.c
@@ -478,6 +478,7 @@
 	{ KE_KEY, 0x30, { KEY_VOLUMEUP } },
 	{ KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
 	{ KE_KEY, 0x32, { KEY_MUTE } },
+	{ KE_KEY, 0x33, { KEY_SCREENLOCK } },
 	{ KE_KEY, 0x35, { KEY_SCREENLOCK } },
 	{ KE_KEY, 0x40, { KEY_PREVIOUSSONG } },
 	{ KE_KEY, 0x41, { KEY_NEXTSONG } },
@@ -506,6 +507,7 @@
 	{ KE_KEY, 0x71, { KEY_F13 } }, /* General-purpose button */
 	{ KE_IGNORE, 0x79, },  /* Charger type dectection notification */
 	{ KE_KEY, 0x7a, { KEY_ALS_TOGGLE } }, /* Ambient Light Sensor Toggle */
+	{ KE_IGNORE, 0x7B, }, /* Charger connect/disconnect notification */
 	{ KE_KEY, 0x7c, { KEY_MICMUTE } },
 	{ KE_KEY, 0x7D, { KEY_BLUETOOTH } }, /* Bluetooth Enable */
 	{ KE_KEY, 0x7E, { KEY_BLUETOOTH } }, /* Bluetooth Disable */
@@ -531,6 +533,7 @@
 	{ KE_KEY, 0xA6, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + HDMI */
 	{ KE_KEY, 0xA7, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + HDMI */
 	{ KE_KEY, 0xB5, { KEY_CALC } },
+	{ KE_IGNORE, 0xC0, }, /* External display connect/disconnect notification */
 	{ KE_KEY, 0xC4, { KEY_KBDILLUMUP } },
 	{ KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } },
 	{ KE_IGNORE, 0xC6, },  /* Ambient Light Sensor notification */
diff --git a/kernel/drivers/platform/x86/dell-wmi.c b/kernel/drivers/platform/x86/dell-wmi.c
index bbdb3e8..6ef327a 100644
--- a/kernel/drivers/platform/x86/dell-wmi.c
+++ b/kernel/drivers/platform/x86/dell-wmi.c
@@ -259,6 +259,9 @@
 	{ KE_KEY,    0x57, { KEY_BRIGHTNESSDOWN } },
 	{ KE_KEY,    0x58, { KEY_BRIGHTNESSUP } },
 
+	/*Speaker Mute*/
+	{ KE_KEY, 0x109, { KEY_MUTE} },
+
 	/* Mic mute */
 	{ KE_KEY, 0x150, { KEY_MICMUTE } },
 
diff --git a/kernel/drivers/platform/x86/huawei-wmi.c b/kernel/drivers/platform/x86/huawei-wmi.c
index eac3e6b..23ebd0c 100644
--- a/kernel/drivers/platform/x86/huawei-wmi.c
+++ b/kernel/drivers/platform/x86/huawei-wmi.c
@@ -86,6 +86,8 @@
 	{ KE_IGNORE, 0x293, { KEY_KBDILLUMTOGGLE } },
 	{ KE_IGNORE, 0x294, { KEY_KBDILLUMUP } },
 	{ KE_IGNORE, 0x295, { KEY_KBDILLUMUP } },
+	// Ignore Ambient Light Sensoring
+	{ KE_KEY,    0x2c1, { KEY_RESERVED } },
 	{ KE_END,	 0 }
 };
 
@@ -760,6 +762,9 @@
 		const char *guid,
 		struct input_dev **idev)
 {
+	acpi_status status;
+	int err;
+
 	*idev = devm_input_allocate_device(dev);
 	if (!*idev)
 		return -ENOMEM;
@@ -769,10 +774,19 @@
 	(*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)
diff --git a/kernel/drivers/platform/x86/intel-hid.c b/kernel/drivers/platform/x86/intel-hid.c
index cebddef..0b0602f 100644
--- a/kernel/drivers/platform/x86/intel-hid.c
+++ b/kernel/drivers/platform/x86/intel-hid.c
@@ -458,7 +458,7 @@
 static int intel_hid_probe(struct platform_device *device)
 {
 	acpi_handle handle = ACPI_HANDLE(&device->dev);
-	unsigned long long mode;
+	unsigned long long mode, dummy;
 	struct intel_hid_priv *priv;
 	acpi_status status;
 	int err;
@@ -510,18 +510,15 @@
 	if (err)
 		goto err_remove_notify;
 
-	if (priv->array) {
-		unsigned long long dummy;
+	intel_button_array_enable(&device->dev, true);
 
-		intel_button_array_enable(&device->dev, true);
-
-		/* Call button load method to enable HID power button */
-		if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN,
-					       &dummy)) {
-			dev_warn(&device->dev,
-				 "failed to enable HID power button\n");
-		}
-	}
+	/*
+	 * Call button load method to enable HID power button
+	 * Always do this since it activates events on some devices without
+	 * a button array too.
+	 */
+	if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN, &dummy))
+		dev_warn(&device->dev, "failed to enable HID power button\n");
 
 	device_init_wakeup(&device->dev, true);
 	/*
diff --git a/kernel/drivers/platform/x86/intel_scu_ipc.c b/kernel/drivers/platform/x86/intel_scu_ipc.c
index 69d7060..84ed828 100644
--- a/kernel/drivers/platform/x86/intel_scu_ipc.c
+++ b/kernel/drivers/platform/x86/intel_scu_ipc.c
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 
@@ -232,19 +233,15 @@
 /* Wait till scu status is busy */
 static inline int busy_loop(struct intel_scu_ipc_dev *scu)
 {
-	unsigned long end = jiffies + IPC_TIMEOUT;
+	u8 status;
+	int err;
 
-	do {
-		u32 status;
+	err = readx_poll_timeout(ipc_read_status, scu, status, !(status & IPC_STATUS_BUSY),
+				 100, jiffies_to_usecs(IPC_TIMEOUT));
+	if (err)
+		return err;
 
-		status = ipc_read_status(scu);
-		if (!(status & IPC_STATUS_BUSY))
-			return (status & IPC_STATUS_ERR) ? -EIO : 0;
-
-		usleep_range(50, 100);
-	} while (time_before(jiffies, end));
-
-	return -ETIMEDOUT;
+	return (status & IPC_STATUS_ERR) ? -EIO : 0;
 }
 
 /* Wait till ipc ioc interrupt is received or timeout in 10 HZ */
@@ -252,10 +249,12 @@
 {
 	int status;
 
-	if (!wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT))
-		return -ETIMEDOUT;
+	wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT);
 
 	status = ipc_read_status(scu);
+	if (status & IPC_STATUS_BUSY)
+		return -ETIMEDOUT;
+
 	if (status & IPC_STATUS_ERR)
 		return -EIO;
 
@@ -265,6 +264,24 @@
 static int intel_scu_ipc_check_status(struct intel_scu_ipc_dev *scu)
 {
 	return scu->irq > 0 ? ipc_wait_for_interrupt(scu) : busy_loop(scu);
+}
+
+static struct intel_scu_ipc_dev *intel_scu_ipc_get(struct intel_scu_ipc_dev *scu)
+{
+	u8 status;
+
+	if (!scu)
+		scu = ipcdev;
+	if (!scu)
+		return ERR_PTR(-ENODEV);
+
+	status = ipc_read_status(scu);
+	if (status & IPC_STATUS_BUSY) {
+		dev_dbg(&scu->dev, "device is busy\n");
+		return ERR_PTR(-EBUSY);
+	}
+
+	return scu;
 }
 
 /* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */
@@ -280,11 +297,10 @@
 	memset(cbuf, 0, sizeof(cbuf));
 
 	mutex_lock(&ipclock);
-	if (!scu)
-		scu = ipcdev;
-	if (!scu) {
+	scu = intel_scu_ipc_get(scu);
+	if (IS_ERR(scu)) {
 		mutex_unlock(&ipclock);
-		return -ENODEV;
+		return PTR_ERR(scu);
 	}
 
 	for (nc = 0; nc < count; nc++, offset += 2) {
@@ -439,13 +455,12 @@
 	int err;
 
 	mutex_lock(&ipclock);
-	if (!scu)
-		scu = ipcdev;
-	if (!scu) {
+	scu = intel_scu_ipc_get(scu);
+	if (IS_ERR(scu)) {
 		mutex_unlock(&ipclock);
-		return -ENODEV;
+		return PTR_ERR(scu);
 	}
-	scu = ipcdev;
+
 	cmdval = sub << 12 | cmd;
 	ipc_command(scu, cmdval);
 	err = intel_scu_ipc_check_status(scu);
@@ -485,11 +500,10 @@
 		return -EINVAL;
 
 	mutex_lock(&ipclock);
-	if (!scu)
-		scu = ipcdev;
-	if (!scu) {
+	scu = intel_scu_ipc_get(scu);
+	if (IS_ERR(scu)) {
 		mutex_unlock(&ipclock);
-		return -ENODEV;
+		return PTR_ERR(scu);
 	}
 
 	memcpy(inbuf, in, inlen);
@@ -583,7 +597,6 @@
 	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 +625,7 @@
 	 * 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);
diff --git a/kernel/drivers/platform/x86/msi-laptop.c b/kernel/drivers/platform/x86/msi-laptop.c
index 0e804b6..dfb4af7 100644
--- a/kernel/drivers/platform/x86/msi-laptop.c
+++ b/kernel/drivers/platform/x86/msi-laptop.c
@@ -210,7 +210,7 @@
 		return -EINVAL;
 
 	if (quirks->ec_read_only)
-		return -EOPNOTSUPP;
+		return 0;
 
 	/* read current device state */
 	result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata);
@@ -841,15 +841,15 @@
 static void msi_init_rfkill(struct work_struct *ignored)
 {
 	if (rfk_wlan) {
-		rfkill_set_sw_state(rfk_wlan, !wlan_s);
+		msi_rfkill_set_state(rfk_wlan, !wlan_s);
 		rfkill_wlan_set(NULL, !wlan_s);
 	}
 	if (rfk_bluetooth) {
-		rfkill_set_sw_state(rfk_bluetooth, !bluetooth_s);
+		msi_rfkill_set_state(rfk_bluetooth, !bluetooth_s);
 		rfkill_bluetooth_set(NULL, !bluetooth_s);
 	}
 	if (rfk_threeg) {
-		rfkill_set_sw_state(rfk_threeg, !threeg_s);
+		msi_rfkill_set_state(rfk_threeg, !threeg_s);
 		rfkill_threeg_set(NULL, !threeg_s);
 	}
 }
diff --git a/kernel/drivers/platform/x86/mxm-wmi.c b/kernel/drivers/platform/x86/mxm-wmi.c
index 9a19fbd..9a45795 100644
--- a/kernel/drivers/platform/x86/mxm-wmi.c
+++ b/kernel/drivers/platform/x86/mxm-wmi.c
@@ -35,13 +35,11 @@
 		.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 @@
 		.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;
diff --git a/kernel/drivers/platform/x86/sony-laptop.c b/kernel/drivers/platform/x86/sony-laptop.c
index e5a1b55..f070e4e 100644
--- a/kernel/drivers/platform/x86/sony-laptop.c
+++ b/kernel/drivers/platform/x86/sony-laptop.c
@@ -1892,14 +1892,21 @@
 		break;
 	}
 
-	ret = sony_call_snc_handle(handle, probe_base, &result);
-	if (ret)
-		return ret;
+	/*
+	 * Only probe if there is a separate probe_base, otherwise the probe call
+	 * is equivalent to __sony_nc_kbd_backlight_mode_set(0), resulting in
+	 * the keyboard backlight being turned off.
+	 */
+	if (probe_base) {
+		ret = sony_call_snc_handle(handle, probe_base, &result);
+		if (ret)
+			return ret;
 
-	if ((handle == 0x0137 && !(result & 0x02)) ||
-			!(result & 0x01)) {
-		dprintk("no backlight keyboard found\n");
-		return 0;
+		if ((handle == 0x0137 && !(result & 0x02)) ||
+				!(result & 0x01)) {
+			dprintk("no backlight keyboard found\n");
+			return 0;
+		}
 	}
 
 	kbdbl_ctl = kzalloc(sizeof(*kbdbl_ctl), GFP_KERNEL);
diff --git a/kernel/drivers/platform/x86/touchscreen_dmi.c b/kernel/drivers/platform/x86/touchscreen_dmi.c
index 110ff1e..55a18cd 100644
--- a/kernel/drivers/platform/x86/touchscreen_dmi.c
+++ b/kernel/drivers/platform/x86/touchscreen_dmi.c
@@ -255,6 +255,23 @@
 	.properties     = connect_tablet9_props,
 };
 
+static const struct property_entry csl_panther_tab_hd_props[] = {
+	PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
+	PROPERTY_ENTRY_U32("touchscreen-min-y", 20),
+	PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
+	PROPERTY_ENTRY_U32("touchscreen-size-y", 1526),
+	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
+	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+	PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-csl-panther-tab-hd.fw"),
+	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+	{ }
+};
+
+static const struct ts_dmi_data csl_panther_tab_hd_data = {
+	.acpi_name      = "MSSL1680:00",
+	.properties     = csl_panther_tab_hd_props,
+};
+
 static const struct property_entry cube_iwork8_air_props[] = {
 	PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
 	PROPERTY_ENTRY_U32("touchscreen-min-y", 3),
@@ -310,6 +327,22 @@
 	.properties	= dexp_ursus_7w_props,
 };
 
+static const struct property_entry dexp_ursus_kx210i_props[] = {
+	PROPERTY_ENTRY_U32("touchscreen-min-x", 5),
+	PROPERTY_ENTRY_U32("touchscreen-min-y",  2),
+	PROPERTY_ENTRY_U32("touchscreen-size-x", 1720),
+	PROPERTY_ENTRY_U32("touchscreen-size-y", 1137),
+	PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-dexp-ursus-kx210i.fw"),
+	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+	PROPERTY_ENTRY_BOOL("silead,home-button"),
+	{ }
+};
+
+static const struct ts_dmi_data dexp_ursus_kx210i_data = {
+	.acpi_name	= "MSSL1680:00",
+	.properties	= dexp_ursus_kx210i_props,
+};
+
 static const struct property_entry digma_citi_e200_props[] = {
 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
@@ -362,6 +395,11 @@
 static const struct ts_dmi_data glavey_tm800a550l_data = {
 	.acpi_name	= "GDIX1001:00",
 	.properties	= glavey_tm800a550l_props,
+};
+
+static const struct ts_dmi_data gdix1002_00_upside_down_data = {
+	.acpi_name	= "GDIX1002:00",
+	.properties	= gdix1001_upside_down_props,
 };
 
 static const struct property_entry gp_electronic_t701_props[] = {
@@ -1014,6 +1052,15 @@
 		},
 	},
 	{
+		/* Chuwi Vi8 (CWI501) */
+		.driver_data = (void *)&chuwi_vi8_data,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "i86"),
+			DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.W86JLBNR01"),
+		},
+	},
+	{
 		/* Chuwi Vi8 (CWI506) */
 		.driver_data = (void *)&chuwi_vi8_data,
 		.matches = {
@@ -1058,6 +1105,14 @@
 		},
 	},
 	{
+		/* CSL Panther Tab HD */
+		.driver_data = (void *)&csl_panther_tab_hd_data,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "CSL Computer GmbH & Co. KG"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "CSL Panther Tab HD"),
+		},
+	},
+	{
 		/* CUBE iwork8 Air */
 		.driver_data = (void *)&cube_iwork8_air_data,
 		.matches = {
@@ -1082,6 +1137,14 @@
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "7W"),
+		},
+	},
+	{
+		/* DEXP Ursus KX210i */
+		.driver_data = (void *)&dexp_ursus_kx210i_data,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "INSYDE Corp."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "S107I"),
 		},
 	},
 	{
@@ -1194,6 +1257,18 @@
 		},
 	},
 	{
+		/* Juno Tablet */
+		.driver_data = (void *)&gdix1002_00_upside_down_data,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Default string"),
+			/* Both product- and board-name being "Default string" is somewhat rare */
+			DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
+			DMI_MATCH(DMI_BOARD_NAME, "Default string"),
+			/* Above matches are too generic, add partial bios-version match */
+			DMI_MATCH(DMI_BIOS_VERSION, "JP2V1."),
+		},
+	},
+	{
 		/* Mediacom WinPad 7.0 W700 (same hw as Wintron surftab 7") */
 		.driver_data = (void *)&trekstor_surftab_wintron70_data,
 		.matches = {
diff --git a/kernel/drivers/platform/x86/wmi.c b/kernel/drivers/platform/x86/wmi.c
index 1f80b26..567c287 100644
--- a/kernel/drivers/platform/x86/wmi.c
+++ b/kernel/drivers/platform/x86/wmi.c
@@ -40,7 +40,7 @@
 static LIST_HEAD(wmi_block_list);
 
 struct guid_block {
-	char guid[16];
+	guid_t guid;
 	union {
 		char object_id[2];
 		struct {
@@ -121,7 +121,7 @@
 	list_for_each_entry(wblock, &wmi_block_list, list) {
 		block = &wblock->gblock;
 
-		if (memcmp(block->guid, &guid_input, 16) == 0) {
+		if (guid_equal(&block->guid, &guid_input)) {
 			if (out)
 				*out = wblock;
 			return true;
@@ -130,11 +130,20 @@
 	return false;
 }
 
+static bool guid_parse_and_compare(const char *string, const guid_t *guid)
+{
+	guid_t guid_input;
+
+	if (guid_parse(string, &guid_input))
+		return false;
+
+	return guid_equal(&guid_input, guid);
+}
+
 static const void *find_guid_context(struct wmi_block *wblock,
 				      struct wmi_driver *wdriver)
 {
 	const struct wmi_device_id *id;
-	guid_t guid_input;
 
 	if (wblock == NULL || wdriver == NULL)
 		return NULL;
@@ -143,9 +152,7 @@
 
 	id = wdriver->id_table;
 	while (*id->guid_string) {
-		if (guid_parse(id->guid_string, &guid_input))
-			continue;
-		if (!memcmp(wblock->gblock.guid, &guid_input, 16))
+		if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid))
 			return id->context;
 		id++;
 	}
@@ -457,7 +464,7 @@
 
 static void wmi_dump_wdg(const struct guid_block *g)
 {
-	pr_info("%pUL:\n", g->guid);
+	pr_info("%pUL:\n", &g->guid);
 	if (g->flags & ACPI_WMI_EVENT)
 		pr_info("\tnotify_id: 0x%02X\n", g->notify_id);
 	else
@@ -539,7 +546,7 @@
 	list_for_each_entry(block, &wmi_block_list, list) {
 		acpi_status wmi_status;
 
-		if (memcmp(block->gblock.guid, &guid_input, 16) == 0) {
+		if (guid_equal(&block->gblock.guid, &guid_input)) {
 			if (block->handler &&
 			    block->handler != wmi_notify_debug)
 				return AE_ALREADY_ACQUIRED;
@@ -579,7 +586,7 @@
 	list_for_each_entry(block, &wmi_block_list, list) {
 		acpi_status wmi_status;
 
-		if (memcmp(block->gblock.guid, &guid_input, 16) == 0) {
+		if (guid_equal(&block->gblock.guid, &guid_input)) {
 			if (!block->handler ||
 			    block->handler == wmi_notify_debug)
 				return AE_NULL_ENTRY;
@@ -615,7 +622,6 @@
 {
 	struct acpi_object_list input;
 	union acpi_object params[1];
-	struct guid_block *gblock;
 	struct wmi_block *wblock;
 
 	input.count = 1;
@@ -624,7 +630,7 @@
 	params[0].integer.value = event;
 
 	list_for_each_entry(wblock, &wmi_block_list, list) {
-		gblock = &wblock->gblock;
+		struct guid_block *gblock = &wblock->gblock;
 
 		if ((gblock->flags & ACPI_WMI_EVENT) &&
 			(gblock->notify_id == event))
@@ -685,7 +691,7 @@
 {
 	struct wmi_block *wblock = dev_to_wblock(dev);
 
-	return sprintf(buf, "wmi:%pUL\n", wblock->gblock.guid);
+	return sprintf(buf, "wmi:%pUL\n", &wblock->gblock.guid);
 }
 static DEVICE_ATTR_RO(modalias);
 
@@ -694,7 +700,7 @@
 {
 	struct wmi_block *wblock = dev_to_wblock(dev);
 
-	return sprintf(buf, "%pUL\n", wblock->gblock.guid);
+	return sprintf(buf, "%pUL\n", &wblock->gblock.guid);
 }
 static DEVICE_ATTR_RO(guid);
 
@@ -777,10 +783,10 @@
 {
 	struct wmi_block *wblock = dev_to_wblock(dev);
 
-	if (add_uevent_var(env, "MODALIAS=wmi:%pUL", wblock->gblock.guid))
+	if (add_uevent_var(env, "MODALIAS=wmi:%pUL", &wblock->gblock.guid))
 		return -ENOMEM;
 
-	if (add_uevent_var(env, "WMI_GUID=%pUL", wblock->gblock.guid))
+	if (add_uevent_var(env, "WMI_GUID=%pUL", &wblock->gblock.guid))
 		return -ENOMEM;
 
 	return 0;
@@ -804,11 +810,7 @@
 		return 0;
 
 	while (*id->guid_string) {
-		guid_t driver_guid;
-
-		if (WARN_ON(guid_parse(id->guid_string, &driver_guid)))
-			continue;
-		if (!memcmp(&driver_guid, wblock->gblock.guid, 16))
+		if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid))
 			return 1;
 
 		id++;
@@ -1042,7 +1044,6 @@
 };
 
 static int wmi_create_device(struct device *wmi_bus_dev,
-			     const struct guid_block *gblock,
 			     struct wmi_block *wblock,
 			     struct acpi_device *device)
 {
@@ -1050,12 +1051,12 @@
 	char method[5];
 	int result;
 
-	if (gblock->flags & ACPI_WMI_EVENT) {
+	if (wblock->gblock.flags & ACPI_WMI_EVENT) {
 		wblock->dev.dev.type = &wmi_type_event;
 		goto out_init;
 	}
 
-	if (gblock->flags & ACPI_WMI_METHOD) {
+	if (wblock->gblock.flags & ACPI_WMI_METHOD) {
 		wblock->dev.dev.type = &wmi_type_method;
 		mutex_init(&wblock->char_mutex);
 		goto out_init;
@@ -1105,7 +1106,7 @@
 	wblock->dev.dev.bus = &wmi_bus_type;
 	wblock->dev.dev.parent = wmi_bus_dev;
 
-	dev_set_name(&wblock->dev.dev, "%pUL", gblock->guid);
+	dev_set_name(&wblock->dev.dev, "%pUL", &wblock->gblock.guid);
 
 	device_initialize(&wblock->dev.dev);
 
@@ -1125,12 +1126,12 @@
 	}
 }
 
-static bool guid_already_parsed(struct acpi_device *device, const u8 *guid)
+static bool guid_already_parsed(struct acpi_device *device, const guid_t *guid)
 {
 	struct wmi_block *wblock;
 
 	list_for_each_entry(wblock, &wmi_block_list, list) {
-		if (memcmp(wblock->gblock.guid, guid, 16) == 0) {
+		if (guid_equal(&wblock->gblock.guid, guid)) {
 			/*
 			 * Because we historically didn't track the relationship
 			 * between GUIDs and ACPI nodes, we don't know whether
@@ -1185,7 +1186,7 @@
 		 * case yet, so for now, we'll just ignore the duplicate
 		 * for device creation.
 		 */
-		if (guid_already_parsed(device, gblock[i].guid))
+		if (guid_already_parsed(device, &gblock[i].guid))
 			continue;
 
 		wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL);
@@ -1197,7 +1198,7 @@
 		wblock->acpi_device = device;
 		wblock->gblock = gblock[i];
 
-		retval = wmi_create_device(wmi_bus_dev, &gblock[i], wblock, device);
+		retval = wmi_create_device(wmi_bus_dev, wblock, device);
 		if (retval) {
 			kfree(wblock);
 			continue;
@@ -1222,7 +1223,7 @@
 		retval = device_add(&wblock->dev.dev);
 		if (retval) {
 			dev_err(wmi_bus_dev, "failed to register %pUL\n",
-				wblock->gblock.guid);
+				&wblock->gblock.guid);
 			if (debug_event)
 				wmi_method_enable(wblock, 0);
 			list_del(&wblock->list);
@@ -1282,12 +1283,11 @@
 static void acpi_wmi_notify_handler(acpi_handle handle, u32 event,
 				    void *context)
 {
-	struct guid_block *block;
 	struct wmi_block *wblock;
 	bool found_it = false;
 
 	list_for_each_entry(wblock, &wmi_block_list, list) {
-		block = &wblock->gblock;
+		struct guid_block *block = &wblock->gblock;
 
 		if (wblock->acpi_device->handle == handle &&
 		    (block->flags & ACPI_WMI_EVENT) &&
@@ -1336,7 +1336,7 @@
 	}
 
 	if (debug_event)
-		pr_info("DEBUG Event GUID: %pUL\n", wblock->gblock.guid);
+		pr_info("DEBUG Event GUID: %pUL\n", &wblock->gblock.guid);
 
 	acpi_bus_generate_netlink_event(
 		wblock->acpi_device->pnp.device_class,
diff --git a/kernel/drivers/pnp/core.c b/kernel/drivers/pnp/core.c
index a50ab00..14bf75b 100644
--- a/kernel/drivers/pnp/core.c
+++ b/kernel/drivers/pnp/core.c
@@ -160,14 +160,14 @@
 	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;
 }
 
diff --git a/kernel/drivers/power/supply/ab8500_btemp.c b/kernel/drivers/power/supply/ab8500_btemp.c
index 4417d64..5a1adce 100644
--- a/kernel/drivers/power/supply/ab8500_btemp.c
+++ b/kernel/drivers/power/supply/ab8500_btemp.c
@@ -921,10 +921,8 @@
  */
 static void ab8500_btemp_external_power_changed(struct power_supply *psy)
 {
-	struct ab8500_btemp *di = power_supply_get_drvdata(psy);
-
-	class_for_each_device(power_supply_class, NULL,
-		di->btemp_psy, ab8500_btemp_get_ext_psy_data);
+	class_for_each_device(power_supply_class, NULL, psy,
+			      ab8500_btemp_get_ext_psy_data);
 }
 
 /* ab8500 btemp driver interrupts and their respective isr */
diff --git a/kernel/drivers/power/supply/ab8500_fg.c b/kernel/drivers/power/supply/ab8500_fg.c
index a6b4a94..a885905 100644
--- a/kernel/drivers/power/supply/ab8500_fg.c
+++ b/kernel/drivers/power/supply/ab8500_fg.c
@@ -2380,10 +2380,8 @@
  */
 static void ab8500_fg_external_power_changed(struct power_supply *psy)
 {
-	struct ab8500_fg *di = power_supply_get_drvdata(psy);
-
-	class_for_each_device(power_supply_class, NULL,
-		di->fg_psy, ab8500_fg_get_ext_psy_data);
+	class_for_each_device(power_supply_class, NULL, psy,
+			      ab8500_fg_get_ext_psy_data);
 }
 
 /**
diff --git a/kernel/drivers/power/supply/bq24190_charger.c b/kernel/drivers/power/supply/bq24190_charger.c
index 8c3c378..5769b36 100644
--- a/kernel/drivers/power/supply/bq24190_charger.c
+++ b/kernel/drivers/power/supply/bq24190_charger.c
@@ -448,11 +448,9 @@
 	if (!info)
 		return -EINVAL;
 
-	ret = pm_runtime_get_sync(bdi->dev);
-	if (ret < 0) {
-		pm_runtime_put_noidle(bdi->dev);
+	ret = pm_runtime_resume_and_get(bdi->dev);
+	if (ret < 0)
 		return ret;
-	}
 
 	ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
 	if (ret)
@@ -483,11 +481,9 @@
 	if (ret < 0)
 		return ret;
 
-	ret = pm_runtime_get_sync(bdi->dev);
-	if (ret < 0) {
-		pm_runtime_put_noidle(bdi->dev);
+	ret = pm_runtime_resume_and_get(bdi->dev);
+	if (ret < 0)
 		return ret;
-	}
 
 	ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
 	if (ret)
@@ -506,10 +502,9 @@
 	struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
 	int ret;
 
-	ret = pm_runtime_get_sync(bdi->dev);
+	ret = pm_runtime_resume_and_get(bdi->dev);
 	if (ret < 0) {
 		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
-		pm_runtime_put_noidle(bdi->dev);
 		return ret;
 	}
 
@@ -539,10 +534,9 @@
 	int ret;
 	u8 val;
 
-	ret = pm_runtime_get_sync(bdi->dev);
+	ret = pm_runtime_resume_and_get(bdi->dev);
 	if (ret < 0) {
 		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
-		pm_runtime_put_noidle(bdi->dev);
 		return ret;
 	}
 
@@ -1083,11 +1077,9 @@
 
 	dev_dbg(bdi->dev, "prop: %d\n", psp);
 
-	ret = pm_runtime_get_sync(bdi->dev);
-	if (ret < 0) {
-		pm_runtime_put_noidle(bdi->dev);
+	ret = pm_runtime_resume_and_get(bdi->dev);
+	if (ret < 0)
 		return ret;
-	}
 
 	switch (psp) {
 	case POWER_SUPPLY_PROP_CHARGE_TYPE:
@@ -1157,11 +1149,9 @@
 
 	dev_dbg(bdi->dev, "prop: %d\n", psp);
 
-	ret = pm_runtime_get_sync(bdi->dev);
-	if (ret < 0) {
-		pm_runtime_put_noidle(bdi->dev);
+	ret = pm_runtime_resume_and_get(bdi->dev);
+	if (ret < 0)
 		return ret;
-	}
 
 	switch (psp) {
 	case POWER_SUPPLY_PROP_ONLINE:
@@ -1213,8 +1203,19 @@
 	struct bq24190_dev_info *bdi =
 		container_of(work, struct bq24190_dev_info,
 			     input_current_limit_work.work);
+	union power_supply_propval val;
+	int ret;
 
-	power_supply_set_input_current_limit_from_supplier(bdi->charger);
+	ret = power_supply_get_property_from_supplier(bdi->charger,
+						      POWER_SUPPLY_PROP_CURRENT_MAX,
+						      &val);
+	if (ret)
+		return;
+
+	bq24190_charger_set_property(bdi->charger,
+				     POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
+				     &val);
+	power_supply_changed(bdi->charger);
 }
 
 /* Sync the input-current-limit with our parent supply (if we have one) */
@@ -1420,11 +1421,9 @@
 	dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
 	dev_dbg(bdi->dev, "prop: %d\n", psp);
 
-	ret = pm_runtime_get_sync(bdi->dev);
-	if (ret < 0) {
-		pm_runtime_put_noidle(bdi->dev);
+	ret = pm_runtime_resume_and_get(bdi->dev);
+	if (ret < 0)
 		return ret;
-	}
 
 	switch (psp) {
 	case POWER_SUPPLY_PROP_STATUS:
@@ -1468,11 +1467,9 @@
 	dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
 	dev_dbg(bdi->dev, "prop: %d\n", psp);
 
-	ret = pm_runtime_get_sync(bdi->dev);
-	if (ret < 0) {
-		pm_runtime_put_noidle(bdi->dev);
+	ret = pm_runtime_resume_and_get(bdi->dev);
+	if (ret < 0)
 		return ret;
-	}
 
 	switch (psp) {
 	case POWER_SUPPLY_PROP_ONLINE:
@@ -1626,10 +1623,9 @@
 	int error;
 
 	bdi->irq_event = true;
-	error = pm_runtime_get_sync(bdi->dev);
+	error = pm_runtime_resume_and_get(bdi->dev);
 	if (error < 0) {
 		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
-		pm_runtime_put_noidle(bdi->dev);
 		return IRQ_NONE;
 	}
 	bq24190_check_status(bdi);
@@ -1849,11 +1845,10 @@
 	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
 	int error;
 
-	error = pm_runtime_get_sync(bdi->dev);
-	if (error < 0) {
+	cancel_delayed_work_sync(&bdi->input_current_limit_work);
+	error = pm_runtime_resume_and_get(bdi->dev);
+	if (error < 0)
 		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
-		pm_runtime_put_noidle(bdi->dev);
-	}
 
 	bq24190_register_reset(bdi);
 	if (bdi->battery)
@@ -1902,11 +1897,9 @@
 	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
 	int error;
 
-	error = pm_runtime_get_sync(bdi->dev);
-	if (error < 0) {
+	error = pm_runtime_resume_and_get(bdi->dev);
+	if (error < 0)
 		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
-		pm_runtime_put_noidle(bdi->dev);
-	}
 
 	bq24190_register_reset(bdi);
 
@@ -1927,11 +1920,9 @@
 	bdi->f_reg = 0;
 	bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
 
-	error = pm_runtime_get_sync(bdi->dev);
-	if (error < 0) {
+	error = pm_runtime_resume_and_get(bdi->dev);
+	if (error < 0)
 		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
-		pm_runtime_put_noidle(bdi->dev);
-	}
 
 	bq24190_register_reset(bdi);
 	bq24190_set_config(bdi);
diff --git a/kernel/drivers/power/supply/bq27xxx_battery.c b/kernel/drivers/power/supply/bq27xxx_battery.c
index 72a2bcf..0673e0f 100644
--- a/kernel/drivers/power/supply/bq27xxx_battery.c
+++ b/kernel/drivers/power/supply/bq27xxx_battery.c
@@ -1018,10 +1018,8 @@
 		return ret;
 
 	mutex_lock(&bq27xxx_list_lock);
-	list_for_each_entry(di, &bq27xxx_battery_devices, list) {
-		cancel_delayed_work_sync(&di->work);
-		schedule_delayed_work(&di->work, 0);
-	}
+	list_for_each_entry(di, &bq27xxx_battery_devices, list)
+		mod_delayed_work(system_wq, &di->work, 0);
 	mutex_unlock(&bq27xxx_list_lock);
 
 	return ret;
@@ -1507,14 +1505,6 @@
  */
 static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
 {
-	int flags;
-
-	if (di->opts & BQ27XXX_O_ZERO) {
-		flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
-		if (flags >= 0 && (flags & BQ27000_FLAG_CI))
-			return -ENODATA;
-	}
-
 	return bq27xxx_battery_read_charge(di, BQ27XXX_REG_NAC);
 }
 
@@ -1668,6 +1658,18 @@
 		return flags & (BQ27XXX_FLAG_SOC1 | BQ27XXX_FLAG_SOCF);
 }
 
+/*
+ * Returns true if reported battery capacity is inaccurate
+ */
+static bool bq27xxx_battery_capacity_inaccurate(struct bq27xxx_device_info *di,
+						 u16 flags)
+{
+	if (di->opts & BQ27XXX_O_HAS_CI)
+		return (flags & BQ27000_FLAG_CI);
+	else
+		return false;
+}
+
 static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
 {
 	/* Unlikely but important to return first */
@@ -1677,14 +1679,89 @@
 		return POWER_SUPPLY_HEALTH_COLD;
 	if (unlikely(bq27xxx_battery_dead(di, di->cache.flags)))
 		return POWER_SUPPLY_HEALTH_DEAD;
+	if (unlikely(bq27xxx_battery_capacity_inaccurate(di, di->cache.flags)))
+		return POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED;
 
 	return POWER_SUPPLY_HEALTH_GOOD;
 }
 
-void bq27xxx_battery_update(struct bq27xxx_device_info *di)
+static bool bq27xxx_battery_is_full(struct bq27xxx_device_info *di, int flags)
 {
+	if (di->opts & BQ27XXX_O_ZERO)
+		return (flags & BQ27000_FLAG_FC);
+	else if (di->opts & BQ27Z561_O_BITS)
+		return (flags & BQ27Z561_FLAG_FC);
+	else
+		return (flags & BQ27XXX_FLAG_FC);
+}
+
+/*
+ * Return the battery average current in µA and the status
+ * Note that current can be negative signed as well
+ * Or 0 if something fails.
+ */
+static int bq27xxx_battery_current_and_status(
+	struct bq27xxx_device_info *di,
+	union power_supply_propval *val_curr,
+	union power_supply_propval *val_status,
+	struct bq27xxx_reg_cache *cache)
+{
+	bool single_flags = (di->opts & BQ27XXX_O_ZERO);
+	int curr;
+	int flags;
+
+	curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);
+	if (curr < 0) {
+		dev_err(di->dev, "error reading current\n");
+		return curr;
+	}
+
+	if (cache) {
+		flags = cache->flags;
+	} else {
+		flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, single_flags);
+		if (flags < 0) {
+			dev_err(di->dev, "error reading flags\n");
+			return flags;
+		}
+	}
+
+	if (di->opts & BQ27XXX_O_ZERO) {
+		if (!(flags & BQ27000_FLAG_CHGS)) {
+			dev_dbg(di->dev, "negative current!\n");
+			curr = -curr;
+		}
+
+		curr = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
+	} else {
+		/* Other gauges return signed value */
+		curr = (int)((s16)curr) * 1000;
+	}
+
+	if (val_curr)
+		val_curr->intval = curr;
+
+	if (val_status) {
+		if (curr > 0) {
+			val_status->intval = POWER_SUPPLY_STATUS_CHARGING;
+		} else if (curr < 0) {
+			val_status->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+		} else {
+			if (bq27xxx_battery_is_full(di, flags))
+				val_status->intval = POWER_SUPPLY_STATUS_FULL;
+			else
+				val_status->intval =
+					POWER_SUPPLY_STATUS_NOT_CHARGING;
+		}
+	}
+
+	return 0;
+}
+
+static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
+{
+	union power_supply_propval status = di->last_status;
 	struct bq27xxx_reg_cache cache = {0, };
-	bool has_ci_flag = di->opts & BQ27XXX_O_HAS_CI;
 	bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
 
 	cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
@@ -1692,32 +1769,28 @@
 		cache.flags = -1; /* read error */
 	if (cache.flags >= 0) {
 		cache.temperature = bq27xxx_battery_read_temperature(di);
-		if (has_ci_flag && (cache.flags & BQ27000_FLAG_CI)) {
-			dev_info_once(di->dev, "battery is not calibrated! ignoring capacity values\n");
-			cache.capacity = -ENODATA;
-			cache.energy = -ENODATA;
-			cache.time_to_empty = -ENODATA;
-			cache.time_to_empty_avg = -ENODATA;
-			cache.time_to_full = -ENODATA;
-			cache.charge_full = -ENODATA;
-			cache.health = -ENODATA;
-		} else {
-			if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
-				cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
-			if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
-				cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
-			if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
-				cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
+		if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
+			cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
+		if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
+			cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
+		if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
+			cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
 
-			cache.charge_full = bq27xxx_battery_read_fcc(di);
-			cache.capacity = bq27xxx_battery_read_soc(di);
-			if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
-				cache.energy = bq27xxx_battery_read_energy(di);
-			di->cache.flags = cache.flags;
-			cache.health = bq27xxx_battery_read_health(di);
-		}
+		cache.charge_full = bq27xxx_battery_read_fcc(di);
+		cache.capacity = bq27xxx_battery_read_soc(di);
+		if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
+			cache.energy = bq27xxx_battery_read_energy(di);
+		di->cache.flags = cache.flags;
+		cache.health = bq27xxx_battery_read_health(di);
 		if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
 			cache.cycle_count = bq27xxx_battery_read_cyct(di);
+
+		/*
+		 * On gauges with signed current reporting the current must be
+		 * checked to detect charging <-> discharging status changes.
+		 */
+		if (!(di->opts & BQ27XXX_O_ZERO))
+			bq27xxx_battery_current_and_status(di, NULL, &status, &cache);
 
 		/* We only have to read charge design full once */
 		if (di->charge_design_full <= 0)
@@ -1725,13 +1798,26 @@
 	}
 
 	if ((di->cache.capacity != cache.capacity) ||
-	    (di->cache.flags != cache.flags))
+	    (di->cache.flags != cache.flags) ||
+	    (di->last_status.intval != status.intval)) {
+		di->last_status.intval = status.intval;
 		power_supply_changed(di->bat);
+	}
 
 	if (memcmp(&di->cache, &cache, sizeof(cache)) != 0)
 		di->cache = cache;
 
 	di->last_update = jiffies;
+
+	if (!di->removed && poll_interval > 0)
+		mod_delayed_work(system_wq, &di->work, poll_interval * HZ);
+}
+
+void bq27xxx_battery_update(struct bq27xxx_device_info *di)
+{
+	mutex_lock(&di->lock);
+	bq27xxx_battery_update_unlocked(di);
+	mutex_unlock(&di->lock);
 }
 EXPORT_SYMBOL_GPL(bq27xxx_battery_update);
 
@@ -1742,42 +1828,6 @@
 				     work.work);
 
 	bq27xxx_battery_update(di);
-
-	if (poll_interval > 0)
-		schedule_delayed_work(&di->work, poll_interval * HZ);
-}
-
-/*
- * Return the battery average current in µA
- * Note that current can be negative signed as well
- * Or 0 if something fails.
- */
-static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
-				   union power_supply_propval *val)
-{
-	int curr;
-	int flags;
-
-	curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);
-	if (curr < 0) {
-		dev_err(di->dev, "error reading current\n");
-		return curr;
-	}
-
-	if (di->opts & BQ27XXX_O_ZERO) {
-		flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
-		if (flags & BQ27000_FLAG_CHGS) {
-			dev_dbg(di->dev, "negative current!\n");
-			curr = -curr;
-		}
-
-		val->intval = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
-	} else {
-		/* Other gauges return signed value */
-		val->intval = (int)((s16)curr) * 1000;
-	}
-
-	return 0;
 }
 
 /*
@@ -1802,43 +1852,6 @@
 	else
 		/* Other gauges return a signed value in units of 10mW */
 		val->intval = (int)((s16)power) * 10000;
-
-	return 0;
-}
-
-static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
-				  union power_supply_propval *val)
-{
-	int status;
-
-	if (di->opts & BQ27XXX_O_ZERO) {
-		if (di->cache.flags & BQ27000_FLAG_FC)
-			status = POWER_SUPPLY_STATUS_FULL;
-		else if (di->cache.flags & BQ27000_FLAG_CHGS)
-			status = POWER_SUPPLY_STATUS_CHARGING;
-		else
-			status = POWER_SUPPLY_STATUS_DISCHARGING;
-	} else if (di->opts & BQ27Z561_O_BITS) {
-		if (di->cache.flags & BQ27Z561_FLAG_FC)
-			status = POWER_SUPPLY_STATUS_FULL;
-		else if (di->cache.flags & BQ27Z561_FLAG_DIS_CH)
-			status = POWER_SUPPLY_STATUS_DISCHARGING;
-		else
-			status = POWER_SUPPLY_STATUS_CHARGING;
-	} else {
-		if (di->cache.flags & BQ27XXX_FLAG_FC)
-			status = POWER_SUPPLY_STATUS_FULL;
-		else if (di->cache.flags & BQ27XXX_FLAG_DSC)
-			status = POWER_SUPPLY_STATUS_DISCHARGING;
-		else
-			status = POWER_SUPPLY_STATUS_CHARGING;
-	}
-
-	if ((status == POWER_SUPPLY_STATUS_DISCHARGING) &&
-	    (power_supply_am_i_supplied(di->bat) > 0))
-		status = POWER_SUPPLY_STATUS_NOT_CHARGING;
-
-	val->intval = status;
 
 	return 0;
 }
@@ -1919,10 +1932,8 @@
 	struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
 
 	mutex_lock(&di->lock);
-	if (time_is_before_jiffies(di->last_update + 5 * HZ)) {
-		cancel_delayed_work_sync(&di->work);
-		bq27xxx_battery_poll(&di->work.work);
-	}
+	if (time_is_before_jiffies(di->last_update + 5 * HZ))
+		bq27xxx_battery_update_unlocked(di);
 	mutex_unlock(&di->lock);
 
 	if (psp != POWER_SUPPLY_PROP_PRESENT && di->cache.flags < 0)
@@ -1930,7 +1941,7 @@
 
 	switch (psp) {
 	case POWER_SUPPLY_PROP_STATUS:
-		ret = bq27xxx_battery_status(di, val);
+		ret = bq27xxx_battery_current_and_status(di, NULL, val, NULL);
 		break;
 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 		ret = bq27xxx_battery_voltage(di, val);
@@ -1939,7 +1950,7 @@
 		val->intval = di->cache.flags < 0 ? 0 : 1;
 		break;
 	case POWER_SUPPLY_PROP_CURRENT_NOW:
-		ret = bq27xxx_battery_current(di, val);
+		ret = bq27xxx_battery_current_and_status(di, val, NULL, NULL);
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY:
 		ret = bq27xxx_simple_value(di->cache.capacity, val);
@@ -2009,8 +2020,8 @@
 {
 	struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
 
-	cancel_delayed_work_sync(&di->work);
-	schedule_delayed_work(&di->work, 0);
+	/* After charger plug in/out wait 0.5s for things to stabilize */
+	mod_delayed_work(system_wq, &di->work, HZ / 2);
 }
 
 int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
@@ -2058,22 +2069,18 @@
 
 void bq27xxx_battery_teardown(struct bq27xxx_device_info *di)
 {
-	/*
-	 * power_supply_unregister call bq27xxx_battery_get_property which
-	 * call bq27xxx_battery_poll.
-	 * Make sure that bq27xxx_battery_poll will not call
-	 * schedule_delayed_work again after unregister (which cause OOPS).
-	 */
-	poll_interval = 0;
-
-	cancel_delayed_work_sync(&di->work);
-
-	power_supply_unregister(di->bat);
-
 	mutex_lock(&bq27xxx_list_lock);
 	list_del(&di->list);
 	mutex_unlock(&bq27xxx_list_lock);
 
+	/* Set removed to avoid bq27xxx_battery_update() re-queuing the work */
+	mutex_lock(&di->lock);
+	di->removed = true;
+	mutex_unlock(&di->lock);
+
+	cancel_delayed_work_sync(&di->work);
+
+	power_supply_unregister(di->bat);
 	mutex_destroy(&di->lock);
 }
 EXPORT_SYMBOL_GPL(bq27xxx_battery_teardown);
diff --git a/kernel/drivers/power/supply/bq27xxx_battery_i2c.c b/kernel/drivers/power/supply/bq27xxx_battery_i2c.c
index 3012eb1..0e32efb 100644
--- a/kernel/drivers/power/supply/bq27xxx_battery_i2c.c
+++ b/kernel/drivers/power/supply/bq27xxx_battery_i2c.c
@@ -179,7 +179,7 @@
 	i2c_set_clientdata(client, di);
 
 	if (client->irq) {
-		ret = devm_request_threaded_irq(&client->dev, client->irq,
+		ret = request_threaded_irq(client->irq,
 				NULL, bq27xxx_battery_irq_handler_thread,
 				IRQF_ONESHOT,
 				di->name, di);
@@ -209,6 +209,7 @@
 {
 	struct bq27xxx_device_info *di = i2c_get_clientdata(client);
 
+	free_irq(client->irq, di);
 	bq27xxx_battery_teardown(di);
 
 	mutex_lock(&battery_mutex);
diff --git a/kernel/drivers/power/supply/cros_usbpd-charger.c b/kernel/drivers/power/supply/cros_usbpd-charger.c
index d89e08e..0a4f02e 100644
--- a/kernel/drivers/power/supply/cros_usbpd-charger.c
+++ b/kernel/drivers/power/supply/cros_usbpd-charger.c
@@ -276,7 +276,7 @@
 		port->psy_current_max = 0;
 		break;
 	default:
-		dev_err(dev, "Port %d: default case!\n", port->port_number);
+		dev_dbg(dev, "Port %d: default case!\n", port->port_number);
 		port->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP;
 	}
 
diff --git a/kernel/drivers/power/supply/da9150-charger.c b/kernel/drivers/power/supply/da9150-charger.c
index f9314cc..6b987da 100644
--- a/kernel/drivers/power/supply/da9150-charger.c
+++ b/kernel/drivers/power/supply/da9150-charger.c
@@ -662,6 +662,7 @@
 
 	if (!IS_ERR_OR_NULL(charger->usb_phy))
 		usb_unregister_notifier(charger->usb_phy, &charger->otg_nb);
+	cancel_work_sync(&charger->otg_work);
 
 	power_supply_unregister(charger->battery);
 	power_supply_unregister(charger->usb);
diff --git a/kernel/drivers/power/supply/generic-adc-battery.c b/kernel/drivers/power/supply/generic-adc-battery.c
index 58f0931..09bb4ff 100644
--- a/kernel/drivers/power/supply/generic-adc-battery.c
+++ b/kernel/drivers/power/supply/generic-adc-battery.c
@@ -138,6 +138,9 @@
 			result);
 	if (ret < 0)
 		pr_err("read channel error\n");
+	else
+		*result *= 1000;
+
 	return ret;
 }
 
diff --git a/kernel/drivers/power/supply/power_supply_core.c b/kernel/drivers/power/supply/power_supply_core.c
index eaf7781..bd49ae7 100644
--- a/kernel/drivers/power/supply/power_supply_core.c
+++ b/kernel/drivers/power/supply/power_supply_core.c
@@ -358,6 +358,10 @@
 	struct power_supply *psy = dev_get_drvdata(dev);
 	unsigned int *count = data;
 
+	if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_SCOPE, &ret))
+		if (ret.intval == POWER_SUPPLY_SCOPE_DEVICE)
+			return 0;
+
 	(*count)++;
 	if (psy->desc->type != POWER_SUPPLY_TYPE_BATTERY)
 		if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_ONLINE,
@@ -376,8 +380,8 @@
 				      __power_supply_is_system_supplied);
 
 	/*
-	 * If no power class device was found at all, most probably we are
-	 * running on a desktop system, so assume we are on mains power.
+	 * If no system scope power class device was found at all, most probably we
+	 * are running on a desktop system, so assume we are on mains power.
 	 */
 	if (count == 0)
 		return 1;
@@ -386,46 +390,49 @@
 }
 EXPORT_SYMBOL_GPL(power_supply_is_system_supplied);
 
-static int __power_supply_get_supplier_max_current(struct device *dev,
-						   void *data)
+struct psy_get_supplier_prop_data {
+	struct power_supply *psy;
+	enum power_supply_property psp;
+	union power_supply_propval *val;
+};
+
+static int __power_supply_get_supplier_property(struct device *dev, void *_data)
 {
-	union power_supply_propval ret = {0,};
 	struct power_supply *epsy = dev_get_drvdata(dev);
-	struct power_supply *psy = data;
+	struct psy_get_supplier_prop_data *data = _data;
 
-	if (__power_supply_is_supplied_by(epsy, psy))
-		if (!epsy->desc->get_property(epsy,
-					      POWER_SUPPLY_PROP_CURRENT_MAX,
-					      &ret))
-			return ret.intval;
+	if (__power_supply_is_supplied_by(epsy, data->psy))
+		if (!epsy->desc->get_property(epsy, data->psp, data->val))
+			return 1; /* Success */
 
-	return 0;
+	return 0; /* Continue iterating */
 }
 
-int power_supply_set_input_current_limit_from_supplier(struct power_supply *psy)
+int power_supply_get_property_from_supplier(struct power_supply *psy,
+					    enum power_supply_property psp,
+					    union power_supply_propval *val)
 {
-	union power_supply_propval val = {0,};
-	int curr;
-
-	if (!psy->desc->set_property)
-		return -EINVAL;
+	struct psy_get_supplier_prop_data data = {
+		.psy = psy,
+		.psp = psp,
+		.val = val,
+	};
+	int ret;
 
 	/*
 	 * This function is not intended for use with a supply with multiple
-	 * suppliers, we simply pick the first supply to report a non 0
-	 * max-current.
+	 * suppliers, we simply pick the first supply to report the psp.
 	 */
-	curr = class_for_each_device(power_supply_class, NULL, psy,
-				      __power_supply_get_supplier_max_current);
-	if (curr <= 0)
-		return (curr == 0) ? -ENODEV : curr;
+	ret = class_for_each_device(power_supply_class, NULL, &data,
+				    __power_supply_get_supplier_property);
+	if (ret < 0)
+		return ret;
+	if (ret == 0)
+		return -ENODEV;
 
-	val.intval = curr;
-
-	return psy->desc->set_property(psy,
-				POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val);
+	return 0;
 }
-EXPORT_SYMBOL_GPL(power_supply_set_input_current_limit_from_supplier);
+EXPORT_SYMBOL_GPL(power_supply_get_property_from_supplier);
 
 int power_supply_set_battery_charged(struct power_supply *psy)
 {
@@ -759,6 +766,11 @@
 		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);
@@ -1283,8 +1295,8 @@
 create_triggers_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:
diff --git a/kernel/drivers/power/supply/power_supply_leds.c b/kernel/drivers/power/supply/power_supply_leds.c
index d69880c..b7a2778 100644
--- a/kernel/drivers/power/supply/power_supply_leds.c
+++ b/kernel/drivers/power/supply/power_supply_leds.c
@@ -34,8 +34,9 @@
 		led_trigger_event(psy->charging_full_trig, LED_FULL);
 		led_trigger_event(psy->charging_trig, LED_OFF);
 		led_trigger_event(psy->full_trig, LED_FULL);
-		led_trigger_event(psy->charging_blink_full_solid_trig,
-			LED_FULL);
+		/* Going from blink to LED on requires a LED_OFF event to stop blink */
+		led_trigger_event(psy->charging_blink_full_solid_trig, LED_OFF);
+		led_trigger_event(psy->charging_blink_full_solid_trig, LED_FULL);
 		break;
 	case POWER_SUPPLY_STATUS_CHARGING:
 		led_trigger_event(psy->charging_full_trig, LED_FULL);
diff --git a/kernel/drivers/power/supply/power_supply_sysfs.c b/kernel/drivers/power/supply/power_supply_sysfs.c
index aba8246..ca6fa09 100644
--- a/kernel/drivers/power/supply/power_supply_sysfs.c
+++ b/kernel/drivers/power/supply/power_supply_sysfs.c
@@ -315,7 +315,8 @@
 
 		if (ret < 0) {
 			if (ret == -ENODATA)
-				dev_dbg(dev, "driver has no data for `%s' property\n",
+				dev_dbg_ratelimited(dev,
+					"driver has no data for `%s' property\n",
 					attr->attr.name);
 			else if (ret != -ENODEV && ret != -EAGAIN)
 				dev_err_ratelimited(dev,
diff --git a/kernel/drivers/power/supply/rk816_battery.c b/kernel/drivers/power/supply/rk816_battery.c
index d204a01..1e4f6cd 100644
--- a/kernel/drivers/power/supply/rk816_battery.c
+++ b/kernel/drivers/power/supply/rk816_battery.c
@@ -328,6 +328,9 @@
 	u8 i;
 	u16 d;
 
+	if (size < 2)
+		return 0;
+
 	for (i = 0; i < size; i++) {
 		if (value < table[i])
 			break;
@@ -2965,6 +2968,8 @@
 					FINISH_CHRG_CUR2 : FINISH_CHRG_CUR1;
 		finish_sec = base2sec(di->chrg_finish_base);
 		soc_sec = di->fcc * 3600 / 100 / DIV(finish_current);
+		if (soc_sec == 0)
+			soc_sec = 1;
 		plus_soc = finish_sec / DIV(soc_sec);
 		if (finish_sec > soc_sec) {
 			rest = finish_sec % soc_sec;
@@ -4671,7 +4676,7 @@
 	}
 
 	pdata->ocv_size = length / sizeof(u32);
-	if (pdata->ocv_size <= 0) {
+	if (pdata->ocv_size < 2) {
 		dev_err(dev, "invalid ocv table\n");
 		return -EINVAL;
 	}
diff --git a/kernel/drivers/power/supply/rk817_battery.c b/kernel/drivers/power/supply/rk817_battery.c
index 6979531..f6d4345 100644
--- a/kernel/drivers/power/supply/rk817_battery.c
+++ b/kernel/drivers/power/supply/rk817_battery.c
@@ -651,6 +651,9 @@
 	u8 i;
 	u16 d;
 
+	if (size < 2)
+		return 0;
+
 	for (i = 0; i < size; i++) {
 		if (value < table[i])
 			break;
@@ -1599,6 +1602,9 @@
 				     battery->pwron_voltage) * 1000;/* uAH */
 	battery->dsoc = battery->rsoc;
 	battery->fcc	= battery->pdata->design_capacity;
+	if (battery->fcc < MIN_FCC)
+		battery->fcc = MIN_FCC;
+
 	battery->nac = rk817_bat_vol_to_cap(battery, battery->pwron_voltage);
 
 	rk817_bat_update_qmax(battery, battery->qmax);
@@ -1801,7 +1807,7 @@
 	}
 
 	pdata->ocv_size = length / sizeof(u32);
-	if (pdata->ocv_size <= 0) {
+	if (pdata->ocv_size < 2) {
 		dev_err(dev, "invalid ocv table\n");
 		return -EINVAL;
 	}
@@ -2773,6 +2779,8 @@
 		finish_sec = base2sec(battery->finish_base);
 
 		soc_sec = battery->fcc * 3600 / 100 / DIV(finish_current);
+		if (soc_sec == 0)
+			soc_sec = 1;
 		plus_soc = finish_sec / DIV(soc_sec);
 		if (finish_sec > soc_sec) {
 			rest = finish_sec % soc_sec;
diff --git a/kernel/drivers/power/supply/rk818_battery.c b/kernel/drivers/power/supply/rk818_battery.c
index 67cabe0..a538407 100644
--- a/kernel/drivers/power/supply/rk818_battery.c
+++ b/kernel/drivers/power/supply/rk818_battery.c
@@ -287,6 +287,9 @@
 	u8 i;
 	u16 d;
 
+	if (size < 2)
+		return 0;
+
 	for (i = 0; i < size; i++) {
 		if (value < table[i])
 			break;
@@ -2101,6 +2104,8 @@
 					FINISH_CHRG_CUR2 : FINISH_CHRG_CUR1;
 		finish_sec = base2sec(di->finish_base);
 		soc_sec = di->fcc * 3600 / 100 / DIV(finish_current);
+		if (soc_sec == 0)
+			soc_sec = 1;
 		plus_soc = finish_sec / DIV(soc_sec);
 		if (finish_sec > soc_sec) {
 			rest = finish_sec % soc_sec;
@@ -3240,7 +3245,7 @@
 	}
 
 	pdata->ocv_size = length / sizeof(u32);
-	if (pdata->ocv_size <= 0) {
+	if (pdata->ocv_size < 2) {
 		dev_err(dev, "invalid ocv table\n");
 		return -EINVAL;
 	}
diff --git a/kernel/drivers/power/supply/sbs-charger.c b/kernel/drivers/power/supply/sbs-charger.c
index fbfb6a6..a30eb42 100644
--- a/kernel/drivers/power/supply/sbs-charger.c
+++ b/kernel/drivers/power/supply/sbs-charger.c
@@ -25,7 +25,7 @@
 #define SBS_CHARGER_REG_STATUS			0x13
 #define SBS_CHARGER_REG_ALARM_WARNING		0x16
 
-#define SBS_CHARGER_STATUS_CHARGE_INHIBITED	BIT(1)
+#define SBS_CHARGER_STATUS_CHARGE_INHIBITED	BIT(0)
 #define SBS_CHARGER_STATUS_RES_COLD		BIT(9)
 #define SBS_CHARGER_STATUS_RES_HOT		BIT(10)
 #define SBS_CHARGER_STATUS_BATTERY_PRESENT	BIT(14)
diff --git a/kernel/drivers/power/supply/sc27xx_fuel_gauge.c b/kernel/drivers/power/supply/sc27xx_fuel_gauge.c
index 1ae8374..3bf4b26 100644
--- a/kernel/drivers/power/supply/sc27xx_fuel_gauge.c
+++ b/kernel/drivers/power/supply/sc27xx_fuel_gauge.c
@@ -733,13 +733,6 @@
 	return ret;
 }
 
-static void sc27xx_fgu_external_power_changed(struct power_supply *psy)
-{
-	struct sc27xx_fgu_data *data = power_supply_get_drvdata(psy);
-
-	power_supply_changed(data->battery);
-}
-
 static int sc27xx_fgu_property_is_writeable(struct power_supply *psy,
 					    enum power_supply_property psp)
 {
@@ -774,7 +767,7 @@
 	.num_properties		= ARRAY_SIZE(sc27xx_fgu_props),
 	.get_property		= sc27xx_fgu_get_property,
 	.set_property		= sc27xx_fgu_set_property,
-	.external_power_changed	= sc27xx_fgu_external_power_changed,
+	.external_power_changed	= power_supply_changed,
 	.property_is_writeable	= sc27xx_fgu_property_is_writeable,
 	.no_thermal		= true,
 };
diff --git a/kernel/drivers/power/supply/test_power.c b/kernel/drivers/power/supply/test_power.c
index d302a31..06c023f 100644
--- a/kernel/drivers/power/supply/test_power.c
+++ b/kernel/drivers/power/supply/test_power.c
@@ -33,7 +33,7 @@
 static int battery_present		= 1; /* true */
 static int battery_technology		= POWER_SUPPLY_TECHNOLOGY_LION;
 static int battery_capacity		= 50;
-static int battery_voltage		= 3300;
+static int battery_voltage		= 3300000;
 static int battery_charge_counter	= -1000;
 static int battery_current		= -1600;
 
diff --git a/kernel/drivers/power/supply/ucs1002_power.c b/kernel/drivers/power/supply/ucs1002_power.c
index ef673ec..332cb50 100644
--- a/kernel/drivers/power/supply/ucs1002_power.c
+++ b/kernel/drivers/power/supply/ucs1002_power.c
@@ -384,7 +384,8 @@
 	case POWER_SUPPLY_PROP_USB_TYPE:
 		return ucs1002_get_usb_type(info, val);
 	case POWER_SUPPLY_PROP_HEALTH:
-		return val->intval = info->health;
+		val->intval = info->health;
+		return 0;
 	case POWER_SUPPLY_PROP_PRESENT:
 		val->intval = info->present;
 		return 0;
diff --git a/kernel/drivers/powercap/Kconfig b/kernel/drivers/powercap/Kconfig
index 8242e8c..503797b 100644
--- a/kernel/drivers/powercap/Kconfig
+++ b/kernel/drivers/powercap/Kconfig
@@ -18,10 +18,12 @@
 # Client driver configurations go here.
 config INTEL_RAPL_CORE
 	tristate
+	depends on PCI
+	select IOSF_MBI
 
 config INTEL_RAPL
 	tristate "Intel RAPL Support via MSR Interface"
-	depends on X86 && IOSF_MBI
+	depends on X86 && PCI
 	select INTEL_RAPL_CORE
 	help
 	  This enables support for the Intel Running Average Power Limit (RAPL)
diff --git a/kernel/drivers/powercap/intel_rapl_msr.c b/kernel/drivers/powercap/intel_rapl_msr.c
index 1646808..6b68e5e 100644
--- a/kernel/drivers/powercap/intel_rapl_msr.c
+++ b/kernel/drivers/powercap/intel_rapl_msr.c
@@ -22,7 +22,6 @@
 #include <linux/processor.h>
 #include <linux/platform_device.h>
 
-#include <asm/iosf_mbi.h>
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
 
diff --git a/kernel/drivers/powercap/powercap_sys.c b/kernel/drivers/powercap/powercap_sys.c
index 3f0b8e2..7a3109a 100644
--- a/kernel/drivers/powercap/powercap_sys.c
+++ b/kernel/drivers/powercap/powercap_sys.c
@@ -530,9 +530,6 @@
 	power_zone->name = kstrdup(name, GFP_KERNEL);
 	if (!power_zone->name)
 		goto err_name_alloc;
-	dev_set_name(&power_zone->dev, "%s:%x",
-					dev_name(power_zone->dev.parent),
-					power_zone->id);
 	power_zone->constraints = kcalloc(nr_constraints,
 					  sizeof(*power_zone->constraints),
 					  GFP_KERNEL);
@@ -555,9 +552,16 @@
 	power_zone->dev_attr_groups[0] = &power_zone->dev_zone_attr_group;
 	power_zone->dev_attr_groups[1] = NULL;
 	power_zone->dev.groups = power_zone->dev_attr_groups;
+	dev_set_name(&power_zone->dev, "%s:%x",
+					dev_name(power_zone->dev.parent),
+					power_zone->id);
 	result = device_register(&power_zone->dev);
-	if (result)
-		goto err_dev_ret;
+	if (result) {
+		put_device(&power_zone->dev);
+		mutex_unlock(&control_type->lock);
+
+		return ERR_PTR(result);
+	}
 
 	control_type->nr_zones++;
 	mutex_unlock(&control_type->lock);
diff --git a/kernel/drivers/ptp/ptp_qoriq.c b/kernel/drivers/ptp/ptp_qoriq.c
index 08f4cf0..8fa9772 100644
--- a/kernel/drivers/ptp/ptp_qoriq.c
+++ b/kernel/drivers/ptp/ptp_qoriq.c
@@ -601,7 +601,7 @@
 	return 0;
 
 no_clock:
-	iounmap(ptp_qoriq->base);
+	iounmap(base);
 no_ioremap:
 	release_resource(ptp_qoriq->rsrc);
 no_resource:
diff --git a/kernel/drivers/pwm/core.c b/kernel/drivers/pwm/core.c
index f12dd01..4397e54 100644
--- a/kernel/drivers/pwm/core.c
+++ b/kernel/drivers/pwm/core.c
@@ -587,6 +587,8 @@
 	    state->polarity == pwm->state.polarity &&
 #ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
 	    state->oneshot_count == pwm->state.oneshot_count &&
+	    state->oneshot_repeat == pwm->state.oneshot_repeat &&
+	    state->duty_offset == pwm->state.duty_offset &&
 #endif
 	    state->enabled == pwm->state.enabled)
 		return 0;
diff --git a/kernel/drivers/pwm/pwm-cros-ec.c b/kernel/drivers/pwm/pwm-cros-ec.c
index c1c3379..d4f4a13 100644
--- a/kernel/drivers/pwm/pwm-cros-ec.c
+++ b/kernel/drivers/pwm/pwm-cros-ec.c
@@ -154,6 +154,7 @@
 
 	state->enabled = (ret > 0);
 	state->period = EC_PWM_MAX_DUTY;
+	state->polarity = PWM_POLARITY_NORMAL;
 
 	/*
 	 * Note that "disabled" and "duty cycle == 0" are treated the same. If
diff --git a/kernel/drivers/pwm/pwm-hibvt.c b/kernel/drivers/pwm/pwm-hibvt.c
index ad205fd..286e9b1 100644
--- a/kernel/drivers/pwm/pwm-hibvt.c
+++ b/kernel/drivers/pwm/pwm-hibvt.c
@@ -146,6 +146,7 @@
 
 	value = readl(base + PWM_CTRL_ADDR(pwm->hwpwm));
 	state->enabled = (PWM_ENABLE_MASK & value);
+	state->polarity = (PWM_POLARITY_MASK & value) ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL;
 }
 
 static int hibvt_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
diff --git a/kernel/drivers/pwm/pwm-imx-tpm.c b/kernel/drivers/pwm/pwm-imx-tpm.c
index fcdf6be..871527b 100644
--- a/kernel/drivers/pwm/pwm-imx-tpm.c
+++ b/kernel/drivers/pwm/pwm-imx-tpm.c
@@ -403,6 +403,13 @@
 	if (tpm->enable_count > 0)
 		return -EBUSY;
 
+	/*
+	 * Force 'real_period' to be zero to force period update code
+	 * can be executed after system resume back, since suspend causes
+	 * the period related registers to become their reset values.
+	 */
+	tpm->real_period = 0;
+
 	clk_disable_unprepare(tpm->clk);
 
 	return 0;
diff --git a/kernel/drivers/pwm/pwm-iqs620a.c b/kernel/drivers/pwm/pwm-iqs620a.c
index 3e967a1..a2aef00 100644
--- a/kernel/drivers/pwm/pwm-iqs620a.c
+++ b/kernel/drivers/pwm/pwm-iqs620a.c
@@ -132,6 +132,7 @@
 	mutex_unlock(&iqs620_pwm->lock);
 
 	state->period = IQS620_PWM_PERIOD_NS;
+	state->polarity = PWM_POLARITY_NORMAL;
 }
 
 static int iqs620_pwm_notifier(struct notifier_block *notifier,
diff --git a/kernel/drivers/pwm/pwm-lpc32xx.c b/kernel/drivers/pwm/pwm-lpc32xx.c
index 522f862..504a8f5 100644
--- a/kernel/drivers/pwm/pwm-lpc32xx.c
+++ b/kernel/drivers/pwm/pwm-lpc32xx.c
@@ -51,10 +51,10 @@
 	if (duty_cycles > 255)
 		duty_cycles = 255;
 
-	val = readl(lpc32xx->base + (pwm->hwpwm << 2));
+	val = readl(lpc32xx->base);
 	val &= ~0xFFFF;
 	val |= (period_cycles << 8) | duty_cycles;
-	writel(val, lpc32xx->base + (pwm->hwpwm << 2));
+	writel(val, lpc32xx->base);
 
 	return 0;
 }
@@ -69,9 +69,9 @@
 	if (ret)
 		return ret;
 
-	val = readl(lpc32xx->base + (pwm->hwpwm << 2));
+	val = readl(lpc32xx->base);
 	val |= PWM_ENABLE;
-	writel(val, lpc32xx->base + (pwm->hwpwm << 2));
+	writel(val, lpc32xx->base);
 
 	return 0;
 }
@@ -81,9 +81,9 @@
 	struct lpc32xx_pwm_chip *lpc32xx = to_lpc32xx_pwm_chip(chip);
 	u32 val;
 
-	val = readl(lpc32xx->base + (pwm->hwpwm << 2));
+	val = readl(lpc32xx->base);
 	val &= ~PWM_ENABLE;
-	writel(val, lpc32xx->base + (pwm->hwpwm << 2));
+	writel(val, lpc32xx->base);
 
 	clk_disable_unprepare(lpc32xx->clk);
 }
@@ -121,9 +121,9 @@
 	lpc32xx->chip.base = -1;
 
 	/* If PWM is disabled, configure the output to the default value */
-	val = readl(lpc32xx->base + (lpc32xx->chip.pwms[0].hwpwm << 2));
+	val = readl(lpc32xx->base);
 	val &= ~PWM_PIN_LEVEL;
-	writel(val, lpc32xx->base + (lpc32xx->chip.pwms[0].hwpwm << 2));
+	writel(val, lpc32xx->base);
 
 	ret = pwmchip_add(&lpc32xx->chip);
 	if (ret < 0) {
diff --git a/kernel/drivers/pwm/pwm-meson.c b/kernel/drivers/pwm/pwm-meson.c
index bd0d733..5b5fd16 100644
--- a/kernel/drivers/pwm/pwm-meson.c
+++ b/kernel/drivers/pwm/pwm-meson.c
@@ -147,12 +147,13 @@
 		return err;
 	}
 
-	return pwm_set_chip_data(pwm, channel);
+	return 0;
 }
 
 static void meson_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
 {
-	struct meson_pwm_channel *channel = pwm_get_chip_data(pwm);
+	struct meson_pwm *meson = to_meson_pwm(chip);
+	struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
 
 	if (channel)
 		clk_disable_unprepare(channel->clk);
@@ -161,13 +162,20 @@
 static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
 			  const struct pwm_state *state)
 {
-	struct meson_pwm_channel *channel = pwm_get_chip_data(pwm);
-	unsigned int duty, period, pre_div, cnt, duty_cnt;
+	struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
+	unsigned int pre_div, cnt, duty_cnt;
 	unsigned long fin_freq;
+	u64 duty, period;
 
 	duty = state->duty_cycle;
 	period = state->period;
 
+	/*
+	 * Note this is wrong. The result is an output wave that isn't really
+	 * inverted and so is wrongly identified by .get_state as normal.
+	 * Fixing this needs some care however as some machines might rely on
+	 * this.
+	 */
 	if (state->polarity == PWM_POLARITY_INVERSED)
 		duty = period - duty;
 
@@ -179,19 +187,19 @@
 
 	dev_dbg(meson->chip.dev, "fin_freq: %lu Hz\n", fin_freq);
 
-	pre_div = div64_u64(fin_freq * (u64)period, NSEC_PER_SEC * 0xffffLL);
+	pre_div = div64_u64(fin_freq * period, NSEC_PER_SEC * 0xffffLL);
 	if (pre_div > MISC_CLK_DIV_MASK) {
 		dev_err(meson->chip.dev, "unable to get period pre_div\n");
 		return -EINVAL;
 	}
 
-	cnt = div64_u64(fin_freq * (u64)period, NSEC_PER_SEC * (pre_div + 1));
+	cnt = div64_u64(fin_freq * period, NSEC_PER_SEC * (pre_div + 1));
 	if (cnt > 0xffff) {
 		dev_err(meson->chip.dev, "unable to get period cnt\n");
 		return -EINVAL;
 	}
 
-	dev_dbg(meson->chip.dev, "period=%u pre_div=%u cnt=%u\n", period,
+	dev_dbg(meson->chip.dev, "period=%llu pre_div=%u cnt=%u\n", period,
 		pre_div, cnt);
 
 	if (duty == period) {
@@ -204,14 +212,13 @@
 		channel->lo = cnt;
 	} else {
 		/* Then check is we can have the duty with the same pre_div */
-		duty_cnt = div64_u64(fin_freq * (u64)duty,
-				     NSEC_PER_SEC * (pre_div + 1));
+		duty_cnt = div64_u64(fin_freq * duty, NSEC_PER_SEC * (pre_div + 1));
 		if (duty_cnt > 0xffff) {
 			dev_err(meson->chip.dev, "unable to get duty cycle\n");
 			return -EINVAL;
 		}
 
-		dev_dbg(meson->chip.dev, "duty=%u pre_div=%u duty_cnt=%u\n",
+		dev_dbg(meson->chip.dev, "duty=%llu pre_div=%u duty_cnt=%u\n",
 			duty, pre_div, duty_cnt);
 
 		channel->pre_div = pre_div;
@@ -224,7 +231,7 @@
 
 static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
 {
-	struct meson_pwm_channel *channel = pwm_get_chip_data(pwm);
+	struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
 	struct meson_pwm_channel_data *channel_data;
 	unsigned long flags;
 	u32 value;
@@ -267,8 +274,8 @@
 static int meson_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 			   const struct pwm_state *state)
 {
-	struct meson_pwm_channel *channel = pwm_get_chip_data(pwm);
 	struct meson_pwm *meson = to_meson_pwm(chip);
+	struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
 	int err = 0;
 
 	if (!state)
@@ -366,6 +373,7 @@
 		state->period = 0;
 		state->duty_cycle = 0;
 	}
+	state->polarity = PWM_POLARITY_NORMAL;
 }
 
 static const struct pwm_ops meson_pwm_ops = {
@@ -417,7 +425,7 @@
 };
 
 static const char * const pwm_axg_ao_parent_names[] = {
-	"aoclk81", "xtal", "fclk_div4", "fclk_div5"
+	"xtal", "axg_ao_clk81", "fclk_div4", "fclk_div5"
 };
 
 static const struct meson_pwm_data pwm_axg_ao_data = {
@@ -426,7 +434,7 @@
 };
 
 static const char * const pwm_g12a_ao_ab_parent_names[] = {
-	"xtal", "aoclk81", "fclk_div4", "fclk_div5"
+	"xtal", "g12a_ao_clk81", "fclk_div4", "fclk_div5"
 };
 
 static const struct meson_pwm_data pwm_g12a_ao_ab_data = {
@@ -435,7 +443,7 @@
 };
 
 static const char * const pwm_g12a_ao_cd_parent_names[] = {
-	"xtal", "aoclk81",
+	"xtal", "g12a_ao_clk81",
 };
 
 static const struct meson_pwm_data pwm_g12a_ao_cd_data = {
diff --git a/kernel/drivers/pwm/pwm-mtk-disp.c b/kernel/drivers/pwm/pwm-mtk-disp.c
index 83b8be0..327c780 100644
--- a/kernel/drivers/pwm/pwm-mtk-disp.c
+++ b/kernel/drivers/pwm/pwm-mtk-disp.c
@@ -74,6 +74,19 @@
 	u64 div, rate;
 	int err;
 
+	err = clk_prepare_enable(mdp->clk_main);
+	if (err < 0) {
+		dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
+		return err;
+	}
+
+	err = clk_prepare_enable(mdp->clk_mm);
+	if (err < 0) {
+		dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
+		clk_disable_unprepare(mdp->clk_main);
+		return err;
+	}
+
 	/*
 	 * Find period, high_width and clk_div to suit duty_ns and period_ns.
 	 * Calculate proper div value to keep period value in the bound.
@@ -87,8 +100,11 @@
 	rate = clk_get_rate(mdp->clk_main);
 	clk_div = div_u64(rate * period_ns, NSEC_PER_SEC) >>
 			  PWM_PERIOD_BIT_WIDTH;
-	if (clk_div > PWM_CLKDIV_MAX)
+	if (clk_div > PWM_CLKDIV_MAX) {
+		clk_disable_unprepare(mdp->clk_mm);
+		clk_disable_unprepare(mdp->clk_main);
 		return -EINVAL;
+	}
 
 	div = NSEC_PER_SEC * (clk_div + 1);
 	period = div64_u64(rate * period_ns, div);
@@ -98,14 +114,17 @@
 	high_width = div64_u64(rate * duty_ns, div);
 	value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
 
-	err = clk_enable(mdp->clk_main);
-	if (err < 0)
-		return err;
-
-	err = clk_enable(mdp->clk_mm);
-	if (err < 0) {
-		clk_disable(mdp->clk_main);
-		return err;
+	if (mdp->data->bls_debug && !mdp->data->has_commit) {
+		/*
+		 * For MT2701, disable double buffer before writing register
+		 * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
+		 */
+		mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
+					 mdp->data->bls_debug_mask,
+					 mdp->data->bls_debug_mask);
+		mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
+					 mdp->data->con0_sel,
+					 mdp->data->con0_sel);
 	}
 
 	mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
@@ -124,8 +143,8 @@
 					 0x0);
 	}
 
-	clk_disable(mdp->clk_mm);
-	clk_disable(mdp->clk_main);
+	clk_disable_unprepare(mdp->clk_mm);
+	clk_disable_unprepare(mdp->clk_main);
 
 	return 0;
 }
@@ -135,13 +154,16 @@
 	struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
 	int err;
 
-	err = clk_enable(mdp->clk_main);
-	if (err < 0)
-		return err;
-
-	err = clk_enable(mdp->clk_mm);
+	err = clk_prepare_enable(mdp->clk_main);
 	if (err < 0) {
-		clk_disable(mdp->clk_main);
+		dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
+		return err;
+	}
+
+	err = clk_prepare_enable(mdp->clk_mm);
+	if (err < 0) {
+		dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
+		clk_disable_unprepare(mdp->clk_main);
 		return err;
 	}
 
@@ -158,8 +180,8 @@
 	mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
 				 0x0);
 
-	clk_disable(mdp->clk_mm);
-	clk_disable(mdp->clk_main);
+	clk_disable_unprepare(mdp->clk_mm);
+	clk_disable_unprepare(mdp->clk_main);
 }
 
 static const struct pwm_ops mtk_disp_pwm_ops = {
@@ -194,14 +216,6 @@
 	if (IS_ERR(mdp->clk_mm))
 		return PTR_ERR(mdp->clk_mm);
 
-	ret = clk_prepare(mdp->clk_main);
-	if (ret < 0)
-		return ret;
-
-	ret = clk_prepare(mdp->clk_mm);
-	if (ret < 0)
-		goto disable_clk_main;
-
 	mdp->chip.dev = &pdev->dev;
 	mdp->chip.ops = &mtk_disp_pwm_ops;
 	mdp->chip.base = -1;
@@ -209,44 +223,22 @@
 
 	ret = pwmchip_add(&mdp->chip);
 	if (ret < 0) {
-		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
-		goto disable_clk_mm;
+		dev_err(&pdev->dev, "pwmchip_add() failed: %pe\n", ERR_PTR(ret));
+		return ret;
 	}
 
 	platform_set_drvdata(pdev, mdp);
 
-	/*
-	 * For MT2701, disable double buffer before writing register
-	 * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
-	 */
-	if (!mdp->data->has_commit) {
-		mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
-					 mdp->data->bls_debug_mask,
-					 mdp->data->bls_debug_mask);
-		mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
-					 mdp->data->con0_sel,
-					 mdp->data->con0_sel);
-	}
-
 	return 0;
-
-disable_clk_mm:
-	clk_unprepare(mdp->clk_mm);
-disable_clk_main:
-	clk_unprepare(mdp->clk_main);
-	return ret;
 }
 
 static int mtk_disp_pwm_remove(struct platform_device *pdev)
 {
 	struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev);
-	int ret;
 
-	ret = pwmchip_remove(&mdp->chip);
-	clk_unprepare(mdp->clk_mm);
-	clk_unprepare(mdp->clk_main);
+	pwmchip_remove(&mdp->chip);
 
-	return ret;
+	return 0;
 }
 
 static const struct mtk_pwm_data mt2701_pwm_data = {
diff --git a/kernel/drivers/pwm/pwm-rockchip-irq-callbacks.h b/kernel/drivers/pwm/pwm-rockchip-irq-callbacks.h
new file mode 100644
index 0000000..191c62e
--- /dev/null
+++ b/kernel/drivers/pwm/pwm-rockchip-irq-callbacks.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef _PWM_ROCKCHIP_IRQ_CALLBACKS_H_
+#define _PWM_ROCKCHIP_IRQ_CALLBACKS_H_
+
+#include <linux/pwm.h>
+#include <linux/pwm-rockchip.h>
+
+static void rockchip_pwm_oneshot_callback(struct pwm_device *pwm, struct pwm_state *state)
+{
+	/*
+	 * If you want to enable oneshot mode again, config and call
+	 * pwm_apply_state().
+	 *
+	 * struct pwm_state new_state;
+	 *
+	 * pwm_get_state(pwm, &new_state);
+	 * new_state.enabled = true;
+	 * ......
+	 * pwm_apply_state(pwm, &new_state);
+	 *
+	 */
+}
+
+static void rockchip_pwm_wave_middle_callback(struct pwm_device *pwm)
+{
+	/*
+	 * If you want to update the configuration of wave table, set
+	 * struct rockchip_pwm_wave_table and call rockchip_pwm_set_wave().
+	 *
+	 * struct rockchip_pwm_wave_config wave_config;
+	 * struct rockchip_pwm_wave_table duty_table;
+	 *
+	 * //fill the duty table
+	 * ......
+	 * wave_config.duty_table = &duty_table;
+	 * wave_config.enable = true;
+	 * rockchip_pwm_set_wave(pwm, &wave_config);
+	 *
+	 */
+}
+
+static void rockchip_pwm_wave_max_callback(struct pwm_device *pwm)
+{
+	/*
+	 * If you want to update the configuration of wave table, set
+	 * struct rockchip_pwm_wave_table and call rockchip_pwm_set_wave().
+	 *
+	 * struct rockchip_pwm_wave_config wave_config;
+	 * struct rockchip_pwm_wave_table duty_table;
+	 *
+	 * //fill the duty table
+	 * ......
+	 * wave_config.duty_table = &duty_table;
+	 * wave_config.enable = true;
+	 * rockchip_pwm_set_wave(pwm, &wave_config);
+	 *
+	 */
+}
+
+#endif
diff --git a/kernel/drivers/pwm/pwm-rockchip.c b/kernel/drivers/pwm/pwm-rockchip.c
index fa455fb..98d5f21 100644
--- a/kernel/drivers/pwm/pwm-rockchip.c
+++ b/kernel/drivers/pwm/pwm-rockchip.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/debugfs.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
@@ -17,11 +18,15 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/pwm.h>
+#include <linux/pwm-rockchip.h>
 #include <linux/time.h>
-#include "pwm-rockchip.h"
+#include "pwm-rockchip-irq-callbacks.h"
 
-#define PWM_MAX_CHANNEL_NUM	4
+#define PWM_MAX_CHANNEL_NUM	8
 
+/*
+ * regs for pwm v1-v3
+ */
 #define PWM_CTRL_TIMER_EN	(1 << 0)
 #define PWM_CTRL_OUTPUT_EN	(1 << 3)
 
@@ -51,12 +56,161 @@
 
 #define PWM_ONESHOT_COUNT_SHIFT	24
 #define PWM_ONESHOT_COUNT_MASK	(0xff << PWM_ONESHOT_COUNT_SHIFT)
-#define PWM_ONESHOT_COUNT_MAX	256
 
 #define PWM_REG_INTSTS(n)	((3 - (n)) * 0x10 + 0x10)
 #define PWM_REG_INT_EN(n)	((3 - (n)) * 0x10 + 0x14)
 
 #define PWM_CH_INT(n)		BIT(n)
+
+/*
+ * regs for pwm v4
+ */
+#define HIWORD_UPDATE(v, l, h)	(((v) << (l)) | (GENMASK(h, l) << 16))
+
+/* VERSION_ID */
+#define CHANNEL_NUM_SUPPORT_SHIFT	0
+#define CHANNEL_NUM_SUPPORT_MASK	(0xf << CHANNEL_NUM_SUPPORT_SHIFT)
+#define CHANNLE_INDEX_SHIFT		4
+#define CHANNLE_INDEX_MASK		(0xf << CHANNLE_INDEX_SHIFT)
+#define IR_TRANS_SUPPORT		BIT(8)
+#define POWER_KEY_SUPPORT		BIT(9)
+#define FREQ_METER_SUPPORT		BIT(10)
+#define COUNTER_SUPPORT			BIT(11)
+#define WAVE_SUPPORT			BIT(12)
+#define FILTER_SUPPORT			BIT(13)
+#define MINOR_VERSION_SHIFT		16
+#define MINOR_VERSION_MASK		(0xff << MINOR_VERSION_SHIFT)
+#define MAIN_VERSION_SHIFT		24
+#define MAIN_VERSION_MASK		(0xff << MAIN_VERSION_SHIFT)
+/* PWM_ENABLE */
+#define PWM_ENABLE_V4			(0x3 << 0)
+#define PWM_CLK_EN(v)			HIWORD_UPDATE(v, 0, 0)
+#define PWM_EN(v)			HIWORD_UPDATE(v, 1, 1)
+#define PWM_CTRL_UPDATE_EN(v)		HIWORD_UPDATE(v, 2, 2)
+#define PWM_GLOBAL_JOIN_EN(v)		HIWORD_UPDATE(v, 4, 4)
+/* PWM_CLK_CTRL */
+#define CLK_PRESCALE(v)			HIWORD_UPDATE(v, 0, 2)
+#define CLK_SCALE(v)			HIWORD_UPDATE(v, 4, 12)
+#define CLK_SRC_SEL(v)			HIWORD_UPDATE(v, 13, 14)
+#define CLK_GLOBAL_SEL(v)		HIWORD_UPDATE(v, 15, 15)
+/* PWM_CTRL */
+#define PWM_MODE(v)			HIWORD_UPDATE(v, 0, 1)
+#define ONESHOT_MODE			0
+#define CONTINUOUS_MODE			1
+#define CAPTURE_MODE			2
+#define PWM_POLARITY(v)			HIWORD_UPDATE(v, 2, 3)
+#define DUTY_NEGATIVE			(0 << 0)
+#define DUTY_POSITIVE			(1 << 0)
+#define INACTIVE_NEGATIVE		(0 << 1)
+#define INACTIVE_POSITIVE		(1 << 1)
+#define PWM_ALIGNED_INVALID(v)		HIWORD_UPDATE(v, 5, 5)
+#define PWM_IN_SEL(v)			HIWORD_UPDATE(v, 6, 8)
+/* PWM_RPT */
+#define FIRST_DIMENSIONAL_SHIFT		0
+#define SECOND_DIMENSINAL_SHIFT		16
+/* INTSTS*/
+#define CAP_LPR_INTSTS_SHIFT		0
+#define CAP_HPR_INTSTS_SHIFT		1
+#define ONESHOT_END_INTSTS_SHIFT	2
+#define RELOAD_INTSTS_SHIFT		3
+#define FREQ_INTSTS_SHIFT		4
+#define PWR_INTSTS_SHIFT		5
+#define IR_TRANS_END_INTSTS_SHIFT	6
+#define WAVE_MAX_INT_SHIFT		7
+#define WAVE_MIDDLE_INT_SHIFT		8
+#define CAP_LPR_INT			BIT(CAP_LPR_INTSTS_SHIFT)
+#define CAP_HPR_INT			BIT(CAP_HPR_INTSTS_SHIFT)
+#define ONESHOT_END_INT			BIT(ONESHOT_END_INTSTS_SHIFT)
+#define RELOAD_INT			BIT(RELOAD_INTSTS_SHIFT)
+#define FREQ_INT			BIT(FREQ_INTSTS_SHIFT)
+#define PWR_INT				BIT(PWR_INTSTS_SHIFT)
+#define IR_TRANS_END_INT		BIT(IR_TRANS_END_INTSTS_SHIFT)
+#define WAVE_MAX_INT			BIT(WAVE_MAX_INT_SHIFT)
+#define WAVE_MIDDLE_INT			BIT(WAVE_MIDDLE_INT_SHIFT)
+/* INT_EN */
+#define CAP_LPR_INT_EN(v)		HIWORD_UPDATE(v, 0, 0)
+#define CAP_HPR_INT_EN(v)		HIWORD_UPDATE(v, 1, 1)
+#define ONESHOT_END_INT_EN(v)		HIWORD_UPDATE(v, 2, 2)
+#define RELOAD_INT_EN(v)		HIWORD_UPDATE(v, 3, 3)
+#define FREQ_INT_EN(v)			HIWORD_UPDATE(v, 4, 4)
+#define PWR_INT_EN(v)			HIWORD_UPDATE(v, 5, 5)
+#define IR_TRANS_END_INT_EN(v)		HIWORD_UPDATE(v, 6, 6)
+#define WAVE_MAX_INT_EN(v)		HIWORD_UPDATE(v, 7, 7)
+#define WAVE_MIDDLE_INT_EN(v)		HIWORD_UPDATE(v, 8, 8)
+/* WAVE_MEM_ARBITER */
+#define WAVE_MEM_ARBITER		0x80
+#define WAVE_MEM_GRANT_SHIFT		0
+#define WAVE_MEM_READ_LOCK_SHIFT	16
+/* WAVE_MEM_STATUS */
+#define WAVE_MEM_STATUS			0x84
+#define WAVE_MEM_STATUS_SHIFT		0
+/* WAVE_CTRL */
+#define WAVE_CTRL			0x88
+#define WAVE_DUTY_EN(v)			HIWORD_UPDATE(v, 0, 0)
+#define WAVE_PERIOD_EN(v)		HIWORD_UPDATE(v, 1, 1)
+#define WAVE_WIDTH_MODE(v)		HIWORD_UPDATE(v, 2, 2)
+#define WAVE_UPDATE_MODE(v)		HIWORD_UPDATE(v, 3, 3)
+#define WAVE_MEM_CLK_SEL(v)		HIWORD_UPDATE(v, 4, 5)
+#define WAVE_DUTY_AMPLIFY(v)		HIWORD_UPDATE(v, 6, 10)
+#define WAVE_PERIOD_AMPLIFY(v)		HIWORD_UPDATE(v, 11, 15)
+/* WAVE_MAX */
+#define WAVE_MAX			0x8c
+#define WAVE_DUTY_MAX_SHIFT		0
+#define WAVE_PERIOD_MAX_SHIFT		16
+/* WAVE_MIN */
+#define WAVE_MIN			0x90
+#define WAVE_DUTY_MIN_SHIFT		0
+#define WAVE_PERIOD_MIN_SHIFT		16
+/* WAVE_OFFSET */
+#define WAVE_OFFSET			0x94
+#define WAVE_OFFSET_SHIFT		0
+/* WAVE_MIDDLE */
+#define WAVE_MIDDLE			0x98
+#define WAVE_MIDDLE_SHIFT		0
+/* WAVE_HOLD */
+#define WAVE_HOLD			0x9c
+#define MAX_HOLD_SHIFT			0
+#define MIN_HOLD_SHIFT			8
+#define MIDDLE_HOLD_SHIFT		16
+/* GLOBAL_ARBITER */
+#define GLOBAL_ARBITER			0xc0
+#define GLOBAL_GRANT_SHIFT		0
+#define GLOBAL_READ_LOCK_SHIFT		16
+/* GLOBAL_CTRL */
+#define GLOBAL_CTRL			0xc4
+#define GLOBAL_PWM_EN(v)		HIWORD_UPDATE(v, 0, 0)
+#define GLOBAL_PWM_UPDATE_EN(v)		HIWORD_UPDATE(v, 1, 1)
+/* FREQ_ARBITER */
+#define FREQ_ARBITER			0x1c0
+#define FREQ_GRANT_SHIFT		0
+#define FREQ_READ_LOCK_SHIFT		16
+/* FREQ_CTRL */
+#define FREQ_CTRL			0x1c4
+#define FREQ_EN(v)			HIWORD_UPDATE(v, 0, 0)
+#define FREQ_CLK_SEL(v)			HIWORD_UPDATE(v, 1, 2)
+#define FREQ_CHANNEL_SEL(v)		HIWORD_UPDATE(v, 3, 5)
+#define FREQ_CLK_SWITCH_MODE(v)		HIWORD_UPDATE(v, 6, 6)
+#define FREQ_TIMIER_CLK_SEL(v)		HIWORD_UPDATE(v, 7, 7)
+/* FREQ_TIMER_VALUE */
+#define FREQ_TIMER_VALUE		0x1c8
+/* FREQ_RESULT_VALUE */
+#define FREQ_RESULT_VALUE		0x1cc
+/* COUNTER_ARBITER */
+#define COUNTER_ARBITER			0x200
+#define COUNTER_GRANT_SHIFT		0
+#define COUNTER_READ_LOCK_SHIFT		16
+/* COUNTER_CTRL */
+#define COUNTER_CTRL			0x204
+#define COUNTER_EN(v)			HIWORD_UPDATE(v, 0, 0)
+#define COUNTER_CLK_SEL(v)		HIWORD_UPDATE(v, 1, 2)
+#define COUNTER_CHANNEL_SEL(v)		HIWORD_UPDATE(v, 3, 5)
+#define COUNTER_CLR(v)			HIWORD_UPDATE(v, 6, 6)
+/* COUNTER_LOW */
+#define COUNTER_LOW			0x208
+/* COUNTER_HIGH */
+#define COUNTER_HIGH			0x20c
+/* WAVE_MEM */
+#define WAVE_MEM			0x400
 
 struct rockchip_pwm_chip {
 	struct pwm_chip chip;
@@ -64,14 +218,24 @@
 	struct clk *pclk;
 	struct pinctrl *pinctrl;
 	struct pinctrl_state *active_state;
+	struct delayed_work pwm_work;
 	const struct rockchip_pwm_data *data;
+	struct resource *res;
+	struct dentry *debugfs;
 	void __iomem *base;
 	unsigned long clk_rate;
 	bool vop_pwm_en; /* indicate voppwm mirror register state */
 	bool center_aligned;
 	bool oneshot_en;
+	bool wave_en;
+	bool global_ctrl_grant;
+	bool freq_meter_support;
+	bool counter_support;
+	bool wave_support;
 	int channel_id;
 	int irq;
+	u8 main_version;
+	u8 capture_cnt;
 };
 
 struct rockchip_pwm_regs {
@@ -79,16 +243,56 @@
 	unsigned long period;
 	unsigned long cntr;
 	unsigned long ctrl;
+	unsigned long version;
+
+	unsigned long enable;
+	unsigned long clk_ctrl;
+	unsigned long offset;
+	unsigned long rpt;
+	unsigned long hpr;
+	unsigned long lpr;
+	unsigned long intsts;
+	unsigned long int_en;
+	unsigned long int_mask;
+};
+
+struct rockchip_pwm_funcs {
+	int (*enable)(struct pwm_chip *chip, struct pwm_device *pwm, bool enable);
+	void (*config)(struct pwm_chip *chip, struct pwm_device *pwm,
+		       const struct pwm_state *state);
+	void (*set_capture)(struct pwm_chip *chip, struct pwm_device *pwm, bool enable);
+	int (*get_capture_result)(struct pwm_chip *chip, struct pwm_device *pwm,
+				  struct pwm_capture *catpure_res);
+	int (*set_counter)(struct pwm_chip *chip, struct pwm_device *pwm, bool enable);
+	int (*get_counter_result)(struct pwm_chip *chip, struct pwm_device *pwm,
+				  unsigned long *counter_res, bool is_clear);
+	int (*set_freq_meter)(struct pwm_chip *chip, struct pwm_device *pwm,
+			      bool enable, unsigned long delay_ms);
+	int (*get_freq_meter_result)(struct pwm_chip *chip, struct pwm_device *pwm,
+				     unsigned long delay_ms, unsigned long *freq_hz);
+	int (*global_ctrl)(struct pwm_chip *chip, struct pwm_device *pwm,
+			   enum rockchip_pwm_global_ctrl_cmd cmd);
+	int (*set_wave_table)(struct pwm_chip *chip, struct pwm_device *pwm,
+			      struct rockchip_pwm_wave_table *table_config,
+			      enum rockchip_pwm_wave_table_width_mode width_mode);
+	int (*set_wave)(struct pwm_chip *chip, struct pwm_device *pwm,
+			struct rockchip_pwm_wave_config *config);
+	irqreturn_t (*irq_handler)(int irq, void *data);
 };
 
 struct rockchip_pwm_data {
 	struct rockchip_pwm_regs regs;
+	struct rockchip_pwm_funcs funcs;
 	unsigned int prescaler;
 	bool supports_polarity;
 	bool supports_lock;
 	bool vop_pwm;
+	u8 main_version;
 	u32 enable_conf;
 	u32 enable_conf_mask;
+	u32 oneshot_cnt_max;
+	u32 oneshot_rpt_max;
+	u32 wave_table_max;
 };
 
 static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip *c)
@@ -104,7 +308,7 @@
 	u32 enable_conf = pc->data->enable_conf;
 	u64 tmp;
 	u32 val;
-	u32 dclk_div;
+	u32 dclk_div = 1;
 	int ret;
 
 	if (!pc->oneshot_en) {
@@ -113,7 +317,8 @@
 			return;
 	}
 
-	dclk_div = pc->oneshot_en ? 2 : 1;
+	if (pc->main_version < 4)
+		dclk_div = pc->oneshot_en ? 2 : 1;
 
 	tmp = readl_relaxed(pc->base + pc->data->regs.period);
 	tmp *= dclk_div * pc->data->prescaler * NSEC_PER_SEC;
@@ -123,9 +328,13 @@
 	tmp *= dclk_div * pc->data->prescaler * NSEC_PER_SEC;
 	state->duty_cycle =  DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate);
 
-	val = readl_relaxed(pc->base + pc->data->regs.ctrl);
-	if (pc->oneshot_en)
-		enable_conf &= ~PWM_CONTINUOUS;
+	if (pc->main_version >= 4) {
+		val = readl_relaxed(pc->base + pc->data->regs.enable);
+	} else {
+		val = readl_relaxed(pc->base + pc->data->regs.ctrl);
+		if (pc->oneshot_en)
+			enable_conf &= ~PWM_CONTINUOUS;
+	}
 	state->enabled = (val & enable_conf) == enable_conf;
 
 	if (pc->data->supports_polarity && !(val & PWM_DUTY_POSITIVE))
@@ -137,7 +346,7 @@
 		clk_disable(pc->pclk);
 }
 
-static irqreturn_t rockchip_pwm_oneshot_irq(int irq, void *data)
+static irqreturn_t rockchip_pwm_irq_v1(int irq, void *data)
 {
 	struct rockchip_pwm_chip *pc = data;
 	struct pwm_state state;
@@ -165,8 +374,8 @@
 	return IRQ_HANDLED;
 }
 
-static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
-			       const struct pwm_state *state)
+static void rockchip_pwm_config_v1(struct pwm_chip *chip, struct pwm_device *pwm,
+				   const struct pwm_state *state)
 {
 	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
 	unsigned long period, duty, delay_ns;
@@ -176,7 +385,7 @@
 	u8 dclk_div = 1;
 
 #ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
-	if (state->oneshot_count > 0 && state->oneshot_count <= PWM_ONESHOT_COUNT_MAX)
+	if (state->oneshot_count > 0 && state->oneshot_count <= pc->data->oneshot_cnt_max)
 		dclk_div = 2;
 #endif
 
@@ -207,7 +416,7 @@
 	}
 
 #ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
-	if (state->oneshot_count > 0 && state->oneshot_count <= PWM_ONESHOT_COUNT_MAX) {
+	if (state->oneshot_count > 0 && state->oneshot_count <= pc->data->oneshot_cnt_max) {
 		u32 int_ctrl;
 
 		/*
@@ -230,9 +439,11 @@
 		ctrl &= ~PWM_ONESHOT_COUNT_MASK;
 		ctrl |= (state->oneshot_count - 1) << PWM_ONESHOT_COUNT_SHIFT;
 
-		int_ctrl = readl_relaxed(pc->base + PWM_REG_INT_EN(pc->channel_id));
-		int_ctrl |= PWM_CH_INT(pc->channel_id);
-		writel_relaxed(int_ctrl, pc->base + PWM_REG_INT_EN(pc->channel_id));
+		if (pc->irq >= 0) {
+			int_ctrl = readl_relaxed(pc->base + PWM_REG_INT_EN(pc->channel_id));
+			int_ctrl |= PWM_CH_INT(pc->channel_id);
+			writel_relaxed(int_ctrl, pc->base + PWM_REG_INT_EN(pc->channel_id));
+		}
 	} else {
 		u32 int_ctrl;
 
@@ -241,7 +452,8 @@
 		ctrl |= PWM_SEL_NO_SCALED_CLOCK;
 
 		if (state->oneshot_count)
-			dev_err(chip->dev, "Oneshot_count must be between 1 and 256.\n");
+			dev_err(chip->dev, "Oneshot_count must be between 1 and %d.\n",
+				pc->data->oneshot_cnt_max);
 
 		pc->oneshot_en = false;
 		ctrl &= ~PWM_MODE_MASK;
@@ -289,9 +501,7 @@
 	local_irq_restore(flags);
 }
 
-static int rockchip_pwm_enable(struct pwm_chip *chip,
-			       struct pwm_device *pwm,
-			       bool enable)
+static int rockchip_pwm_enable_v1(struct pwm_chip *chip, struct pwm_device *pwm, bool enable)
 {
 	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
 	u32 enable_conf = pc->data->enable_conf;
@@ -328,6 +538,192 @@
 		clk_disable(pc->clk);
 
 	return 0;
+}
+
+static irqreturn_t rockchip_pwm_irq_v4(int irq, void *data)
+{
+	struct rockchip_pwm_chip *pc = data;
+	int val;
+	irqreturn_t ret = IRQ_NONE;
+
+	val = readl_relaxed(pc->base + pc->data->regs.intsts);
+#ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
+	if (val & ONESHOT_END_INT) {
+		struct pwm_state state;
+
+		writel_relaxed(ONESHOT_END_INT, pc->base + pc->data->regs.intsts);
+
+		/*
+		 * Set pwm state to disabled when the oneshot mode finished.
+		 */
+		pwm_get_state(&pc->chip.pwms[0], &state);
+		state.enabled = false;
+		state.oneshot_count = 0;
+		state.oneshot_repeat = 0;
+		pwm_apply_state(&pc->chip.pwms[0], &state);
+
+		rockchip_pwm_oneshot_callback(&pc->chip.pwms[0], &state);
+
+		ret = IRQ_HANDLED;
+	}
+#endif
+	if (val & CAP_LPR_INT) {
+		writel_relaxed(CAP_LPR_INT, pc->base + pc->data->regs.intsts);
+		pc->capture_cnt++;
+
+		ret = IRQ_HANDLED;
+	} else if (val & CAP_HPR_INT) {
+		writel_relaxed(CAP_HPR_INT, pc->base + pc->data->regs.intsts);
+		pc->capture_cnt++;
+
+		ret = IRQ_HANDLED;
+	}
+
+	/*
+	 * Capture input waveform:
+	 *    _______                 _______
+	 *   |       |               |       |
+	 * __|       |_______________|       |________
+	 *   ^0      ^1              ^2
+	 *
+	 * At position 0, the LPR interrupt comes, and PERIOD_LPR reg shows
+	 * the low polarity cycles which should be ignored. The effective
+	 * high and low polarity cycles will be calculated in position 1 and
+	 * position 2, where the HPR and LPR interrupts come again.
+	 */
+	if (pc->capture_cnt > 3) {
+		writel_relaxed(CAP_LPR_INT | CAP_HPR_INT, pc->base + pc->data->regs.intsts);
+		writel_relaxed(CAP_LPR_INT_EN(false) | CAP_HPR_INT_EN(false),
+			       pc->base + pc->data->regs.int_en);
+	}
+
+	if (val & WAVE_MIDDLE_INT) {
+		writel_relaxed(WAVE_MIDDLE_INT, pc->base + pc->data->regs.intsts);
+
+		rockchip_pwm_wave_middle_callback(&pc->chip.pwms[0]);
+
+		ret = IRQ_HANDLED;
+	}
+
+	if (val & WAVE_MAX_INT) {
+		writel_relaxed(WAVE_MAX_INT, pc->base + pc->data->regs.intsts);
+
+		rockchip_pwm_wave_max_callback(&pc->chip.pwms[0]);
+
+		ret = IRQ_HANDLED;
+	}
+
+	return ret;
+}
+
+static void rockchip_pwm_config_v4(struct pwm_chip *chip, struct pwm_device *pwm,
+				   const struct pwm_state *state)
+{
+	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+	unsigned long period, duty;
+	u64 div = 0;
+	u32 rpt = 0;
+	u32 offset = 0;
+
+	/*
+	 * Since period and duty cycle registers have a width of 32
+	 * bits, every possible input period can be obtained using the
+	 * default prescaler value for all practical clock rate values.
+	 */
+	div = (u64)pc->clk_rate * state->period;
+	period = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC);
+
+	div = (u64)pc->clk_rate * state->duty_cycle;
+	duty = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC);
+
+	writel_relaxed(period, pc->base + pc->data->regs.period);
+	writel_relaxed(duty, pc->base + pc->data->regs.duty);
+
+	if (pc->data->supports_polarity) {
+		if (state->polarity == PWM_POLARITY_INVERSED)
+			writel_relaxed(PWM_POLARITY(DUTY_NEGATIVE | INACTIVE_POSITIVE),
+				       pc->base + pc->data->regs.ctrl);
+		else
+			writel_relaxed(PWM_POLARITY(DUTY_POSITIVE | INACTIVE_NEGATIVE),
+				       pc->base + pc->data->regs.ctrl);
+	}
+
+#ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
+	if ((state->oneshot_count > 0 && state->oneshot_count <= pc->data->oneshot_cnt_max) &&
+	    (state->oneshot_repeat <= pc->data->oneshot_rpt_max)) {
+		rpt |= (state->oneshot_count - 1) << FIRST_DIMENSIONAL_SHIFT;
+		if (state->oneshot_repeat)
+			rpt |= (state->oneshot_repeat - 1) << SECOND_DIMENSINAL_SHIFT;
+
+		if (state->duty_offset > 0 &&
+		    state->duty_offset <= (state->period - state->duty_cycle)) {
+			div = (u64)pc->clk_rate * state->duty_offset;
+			offset = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC);
+		} else if (state->duty_offset > (state->period - state->duty_cycle)) {
+			dev_err(chip->dev, "Duty_offset must be between %lld and %lld.\n",
+				state->duty_cycle, state->period);
+		}
+
+		pc->oneshot_en = true;
+	} else {
+		if (state->oneshot_count)
+			dev_err(chip->dev, "Oneshot_count must be between 1 and %d.\n",
+				pc->data->oneshot_cnt_max);
+
+		pc->oneshot_en = false;
+	}
+#endif
+
+	if (pc->oneshot_en) {
+		writel_relaxed(PWM_MODE(ONESHOT_MODE) | PWM_ALIGNED_INVALID(true),
+			       pc->base + pc->data->regs.ctrl);
+		writel_relaxed(offset, pc->base + pc->data->regs.offset);
+		writel_relaxed(rpt, pc->base + pc->data->regs.rpt);
+		writel_relaxed(ONESHOT_END_INT_EN(true), pc->base + pc->data->regs.int_en);
+	} else {
+		writel_relaxed(PWM_MODE(CONTINUOUS_MODE) | PWM_ALIGNED_INVALID(false),
+			       pc->base + pc->data->regs.ctrl);
+		writel_relaxed(0, pc->base + pc->data->regs.offset);
+		if (!pc->wave_en)
+			writel_relaxed(0, pc->base + pc->data->regs.rpt);
+		writel_relaxed(ONESHOT_END_INT_EN(false), pc->base + pc->data->regs.int_en);
+	}
+
+	writel_relaxed(PWM_CTRL_UPDATE_EN(true), pc->base + pc->data->regs.enable);
+}
+
+static int rockchip_pwm_enable_v4(struct pwm_chip *chip, struct pwm_device *pwm, bool enable)
+{
+	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+	int ret;
+
+	if (enable) {
+		ret = clk_enable(pc->clk);
+		if (ret)
+			return ret;
+	}
+
+	writel_relaxed(PWM_EN(enable) | PWM_CLK_EN(enable), pc->base + pc->data->regs.enable);
+
+	if (!enable)
+		clk_disable(pc->clk);
+
+	return 0;
+}
+
+static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+				const struct pwm_state *state)
+{
+	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+
+	pc->data->funcs.config(chip, pwm, state);
+}
+
+static int rockchip_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm, bool enable)
+{
+	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+
+	return pc->data->funcs.enable(chip, pwm, enable);
 }
 
 static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -371,14 +767,703 @@
 	return ret;
 }
 
+static void rockchip_pwm_set_capture_v4(struct pwm_chip *chip, struct pwm_device *pwm,
+					bool enable)
+{
+	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+	u32 channel_sel = 0;
+
+	if (enable)
+		channel_sel = pc->channel_id;
+
+	pc->capture_cnt = 0;
+
+	writel_relaxed(enable ? PWM_MODE(CAPTURE_MODE) : PWM_MODE(CONTINUOUS_MODE),
+		       pc->base + pc->data->regs.ctrl);
+	writel_relaxed(CAP_LPR_INT_EN(enable) | CAP_HPR_INT_EN(enable) | PWM_IN_SEL(channel_sel),
+		       pc->base + pc->data->regs.int_en);
+}
+
+static int rockchip_pwm_get_capture_result_v4(struct pwm_chip *chip, struct pwm_device *pwm,
+					      struct pwm_capture *capture_res)
+{
+	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+	u64 tmp;
+
+	tmp = readl_relaxed(pc->base + pc->data->regs.hpr);
+	tmp *= pc->data->prescaler * NSEC_PER_SEC;
+	capture_res->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate);
+
+	tmp = readl_relaxed(pc->base + pc->data->regs.lpr);
+	tmp *= pc->data->prescaler * NSEC_PER_SEC;
+	capture_res->period =  DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate) + capture_res->duty_cycle;
+
+	if (!capture_res->duty_cycle || !capture_res->period)
+		return -EINVAL;
+
+	writel_relaxed(0, pc->base + pc->data->regs.hpr);
+	writel_relaxed(0, pc->base + pc->data->regs.lpr);
+
+	return 0;
+}
+
+static u8 rockchip_pwm_get_capture_cnt(struct rockchip_pwm_chip *pc)
+{
+	return pc->capture_cnt;
+}
+
+static int rockchip_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
+				struct pwm_capture *capture_res, unsigned long timeout_ms)
+{
+	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+	struct pwm_state curstate;
+	u8 capture_cnt;
+	int ret = 0;
+
+	if (!pc->data->funcs.set_capture || !pc->data->funcs.get_capture_result) {
+		dev_err(chip->dev, "Unsupported capture mode\n");
+		return -EINVAL;
+	}
+
+	pwm_get_state(pwm, &curstate);
+	if (curstate.enabled) {
+		dev_err(chip->dev, "Failed to enable capture mode because PWM%d is busy\n",
+			pc->channel_id);
+		return -EBUSY;
+	}
+
+	ret = clk_enable(pc->pclk);
+	if (ret)
+		return ret;
+
+	pc->data->funcs.set_capture(chip, pwm, true);
+	ret = pc->data->funcs.enable(chip, pwm, true);
+	if (ret) {
+		dev_err(chip->dev, "Failed to enable capture mode\n");
+		goto err_disable_pclk;
+	}
+
+	ret = readx_poll_timeout(rockchip_pwm_get_capture_cnt, pc, capture_cnt,
+				 capture_cnt > 3, 0, timeout_ms * 1000);
+	if (!ret) {
+		dev_err(chip->dev, "Failed to wait for LPR/HPR interrupt\n");
+		ret = -ETIMEDOUT;
+	} else {
+		ret = pc->data->funcs.get_capture_result(chip, pwm, capture_res);
+		if (ret)
+			dev_err(chip->dev, "Failed to get capture result\n");
+	}
+
+	pc->data->funcs.enable(chip, pwm, false);
+	pc->data->funcs.set_capture(chip, pwm, false);
+
+err_disable_pclk:
+	clk_disable(pc->pclk);
+
+	return ret;
+}
+
+static int rockchip_pwm_set_counter_v4(struct pwm_chip *chip, struct pwm_device *pwm,
+				       bool enable)
+{
+	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+	u32 arbiter = 0;
+	u32 channel_sel = 0;
+	u32 val;
+
+	if (enable) {
+		arbiter = BIT(pc->channel_id) << COUNTER_READ_LOCK_SHIFT |
+			  BIT(pc->channel_id) << COUNTER_GRANT_SHIFT,
+		channel_sel = pc->channel_id;
+	}
+
+	writel_relaxed(arbiter, pc->base + COUNTER_ARBITER);
+	if (enable) {
+		val = readl_relaxed(pc->base + COUNTER_ARBITER);
+		if (!(val & arbiter))
+			return -EINVAL;
+	}
+
+	writel_relaxed(COUNTER_EN(enable) | COUNTER_CHANNEL_SEL(channel_sel),
+		       pc->base + COUNTER_CTRL);
+
+	return 0;
+}
+
+int rockchip_pwm_set_counter(struct pwm_device *pwm, bool enable)
+{
+	struct pwm_chip *chip;
+	struct rockchip_pwm_chip *pc;
+	struct pwm_state curstate;
+	int ret = 0;
+
+	if (!pwm)
+		return -EINVAL;
+
+	chip = pwm->chip;
+	pc = to_rockchip_pwm_chip(chip);
+
+	if (!pc->counter_support ||
+	    !pc->data->funcs.set_counter || !pc->data->funcs.get_counter_result) {
+		dev_err(chip->dev, "Unsupported counter mode\n");
+		return -EINVAL;
+	}
+
+	pwm_get_state(pwm, &curstate);
+	if (curstate.enabled) {
+		dev_err(chip->dev, "Failed to enable counter mode because PWM%d is busy\n",
+			pc->channel_id);
+		return -EBUSY;
+	}
+
+	ret = clk_enable(pc->pclk);
+	if (ret)
+		return ret;
+
+	ret = pc->data->funcs.set_counter(chip, pwm, enable);
+	if (ret) {
+		dev_err(chip->dev, "Failed to abtain counter arbitration for PWM%d\n",
+			pc->channel_id);
+		goto err_disable_pclk;
+	}
+
+err_disable_pclk:
+	clk_disable(pc->pclk);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(rockchip_pwm_set_counter);
+
+static int rockchip_pwm_get_counter_result_v4(struct pwm_chip *chip, struct pwm_device *pwm,
+					      unsigned long *counter_res, bool is_clear)
+{
+	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+	u64 low, high;
+
+	low = readl_relaxed(pc->base + COUNTER_LOW);
+	high = readl_relaxed(pc->base + COUNTER_HIGH);
+
+	*counter_res = (high << 32) | low;
+	if (!*counter_res)
+		return -EINVAL;
+
+	if (is_clear)
+		writel_relaxed(COUNTER_CLR(true), pc->base + COUNTER_CTRL);
+
+	return 0;
+}
+
+int rockchip_pwm_get_counter_result(struct pwm_device *pwm,
+				    unsigned long *counter_res, bool is_clear)
+{
+	struct pwm_chip *chip;
+	struct rockchip_pwm_chip *pc;
+	int ret = 0;
+
+	if (!pwm || !counter_res)
+		return -EINVAL;
+
+	chip = pwm->chip;
+	pc = to_rockchip_pwm_chip(chip);
+
+	if (!pc->counter_support ||
+	    !pc->data->funcs.set_counter || !pc->data->funcs.get_counter_result) {
+		dev_err(chip->dev, "Unsupported counter mode\n");
+		return -EINVAL;
+	}
+
+	ret = clk_enable(pc->pclk);
+	if (ret)
+		return ret;
+
+	ret = pc->data->funcs.get_counter_result(chip, pwm, counter_res, is_clear);
+	if (ret) {
+		dev_err(chip->dev, "Failed to get counter result for PWM%d\n",
+			pc->channel_id);
+		goto err_disable_pclk;
+	}
+
+err_disable_pclk:
+	clk_disable(pc->pclk);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(rockchip_pwm_get_counter_result);
+
+static int rockchip_pwm_set_freq_meter_v4(struct pwm_chip *chip, struct pwm_device *pwm,
+					  bool enable, unsigned long delay_ms)
+{
+	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+	u64 div = 0;
+	u64 timer_val = 0;
+	u32 arbiter = 0;
+	u32 channel_sel = 0;
+	u32 val;
+
+	if (enable) {
+		arbiter = BIT(pc->channel_id) << FREQ_READ_LOCK_SHIFT |
+			  BIT(pc->channel_id) << FREQ_GRANT_SHIFT;
+		channel_sel = pc->channel_id;
+
+		div = (u64)pc->clk_rate * delay_ms;
+		timer_val = DIV_ROUND_CLOSEST_ULL(div, MSEC_PER_SEC);
+	}
+
+	writel_relaxed(arbiter, pc->base + FREQ_ARBITER);
+	if (enable) {
+		val = readl_relaxed(pc->base + FREQ_ARBITER);
+		if (!(val & arbiter))
+			return -EINVAL;
+	}
+
+	writel_relaxed(FREQ_INT_EN(enable), pc->base + pc->data->regs.int_en);
+	writel_relaxed(timer_val, pc->base + FREQ_TIMER_VALUE);
+	writel_relaxed(FREQ_EN(enable) | FREQ_CHANNEL_SEL(channel_sel),
+		       pc->base + FREQ_CTRL);
+
+	return 0;
+}
+
+static int rockchip_pwm_get_freq_meter_result_v4(struct pwm_chip *chip, struct pwm_device *pwm,
+						 unsigned long delay_ms, unsigned long *freq_hz)
+{
+	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+	int ret;
+	u32 val;
+
+	ret = readl_relaxed_poll_timeout(pc->base + pc->data->regs.intsts, val, val & FREQ_INT,
+					 0, delay_ms * 1000);
+	if (!ret) {
+		dev_err(chip->dev, "failed to wait for freq_meter interrupt\n");
+		return -ETIMEDOUT;
+	}
+
+	*freq_hz = readl_relaxed(pc->base + FREQ_RESULT_VALUE);
+	if (!*freq_hz)
+		return -EINVAL;
+
+	return 0;
+}
+
+int rockchip_pwm_set_freq_meter(struct pwm_device *pwm, unsigned long delay_ms,
+				unsigned long *freq_hz)
+{
+	struct pwm_chip *chip;
+	struct rockchip_pwm_chip *pc;
+	struct pwm_state curstate;
+	int ret = 0;
+
+	if (!pwm || !freq_hz)
+		return -EINVAL;
+
+	chip = pwm->chip;
+	pc = to_rockchip_pwm_chip(chip);
+
+	if (!pc->freq_meter_support ||
+	    !pc->data->funcs.set_freq_meter || !pc->data->funcs.get_freq_meter_result) {
+		dev_err(chip->dev, "Unsupported frequency meter mode\n");
+		return -EINVAL;
+	}
+
+	pwm_get_state(pwm, &curstate);
+	if (curstate.enabled) {
+		dev_err(chip->dev, "Failed to enable frequency meter mode because PWM%d is busy\n",
+			pc->channel_id);
+		return -EBUSY;
+	}
+
+	ret = clk_enable(pc->pclk);
+	if (ret)
+		return ret;
+
+	ret = pc->data->funcs.set_freq_meter(chip, pwm, true, delay_ms);
+	if (ret) {
+		dev_err(chip->dev, "Failed to abtain frequency meter arbitration for PWM%d\n",
+			pc->channel_id);
+	} else {
+		ret = pc->data->funcs.get_freq_meter_result(chip, pwm, delay_ms, freq_hz);
+		if (ret) {
+			dev_err(chip->dev, "Failed to get frequency meter result for PWM%d\n",
+				pc->channel_id);
+		}
+	}
+	pc->data->funcs.set_freq_meter(chip, pwm, false, 0);
+
+	clk_disable(pc->pclk);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(rockchip_pwm_set_freq_meter);
+
+static int rockchip_pwm_global_ctrl_v4(struct pwm_chip *chip, struct pwm_device *pwm,
+				       enum rockchip_pwm_global_ctrl_cmd cmd)
+{
+	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+	u32 arbiter = 0;
+	u32 val = 0;
+
+	switch (cmd) {
+	case PWM_GLOBAL_CTRL_JOIN:
+		writel_relaxed(PWM_GLOBAL_JOIN_EN(true), pc->base + pc->data->regs.enable);
+		writel_relaxed(CLK_GLOBAL_SEL(true), pc->base + pc->data->regs.clk_ctrl);
+		break;
+	case PWM_GLOBAL_CTRL_EXIT:
+		writel_relaxed(PWM_GLOBAL_JOIN_EN(false), pc->base + pc->data->regs.enable);
+		writel_relaxed(CLK_GLOBAL_SEL(false), pc->base + pc->data->regs.clk_ctrl);
+		break;
+	case PWM_GLOBAL_CTRL_GRANT:
+		arbiter = BIT(pc->channel_id) << GLOBAL_READ_LOCK_SHIFT |
+			  BIT(pc->channel_id) << GLOBAL_GRANT_SHIFT;
+
+		writel_relaxed(arbiter, pc->base + GLOBAL_ARBITER);
+		val = readl_relaxed(pc->base + GLOBAL_ARBITER);
+		if (!(val & arbiter)) {
+			dev_err(chip->dev, "Failed to abtain global ctrl arbitration for PWM%d\n",
+				pc->channel_id);
+			return -EINVAL;
+		}
+
+		pc->global_ctrl_grant = true;
+		break;
+	case PWM_GLOBAL_CTRL_RECLAIM:
+		writel_relaxed(0, pc->base + GLOBAL_ARBITER);
+
+		pc->global_ctrl_grant = false;
+		break;
+	case PWM_GLOBAL_CTRL_UPDATE:
+		if (!pc->global_ctrl_grant) {
+			dev_err(chip->dev, "CMD %d: get global ctrl arbitration first for PWM%d\n",
+				cmd, pc->channel_id);
+			return -EINVAL;
+		}
+
+		writel_relaxed(GLOBAL_PWM_UPDATE_EN(true), pc->base + GLOBAL_CTRL);
+		break;
+	case PWM_GLOBAL_CTRL_ENABLE:
+		if (!pc->global_ctrl_grant) {
+			dev_err(chip->dev, "CMD %d: get global ctrl arbitration first for PWM%d\n",
+				cmd, pc->channel_id);
+			return -EINVAL;
+		}
+
+		writel_relaxed(PWM_CLK_EN(true), pc->base + pc->data->regs.enable);
+		writel_relaxed(GLOBAL_PWM_EN(true), pc->base + GLOBAL_CTRL);
+		break;
+	case PWM_GLOBAL_CTRL_DISABLE:
+		if (!pc->global_ctrl_grant) {
+			dev_err(chip->dev, "CMD %d: get global ctrl arbitration first for PWM%d\n",
+				cmd, pc->channel_id);
+			return -EINVAL;
+		}
+
+		writel_relaxed(PWM_CLK_EN(false), pc->base + pc->data->regs.enable);
+		writel_relaxed(GLOBAL_PWM_EN(false), pc->base + GLOBAL_CTRL);
+		break;
+	default:
+		dev_err(chip->dev, "Unsupported global ctrl cmd %d\n", cmd);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int rockchip_pwm_global_ctrl(struct pwm_device *pwm, enum rockchip_pwm_global_ctrl_cmd cmd)
+{
+	struct pwm_chip *chip;
+	struct rockchip_pwm_chip *pc;
+	struct pwm_state curstate;
+	int ret = 0;
+
+	if (!pwm)
+		return -EINVAL;
+
+	chip = pwm->chip;
+	pc = to_rockchip_pwm_chip(chip);
+
+	if (!pc->data->funcs.global_ctrl) {
+		dev_err(chip->dev, "Unsupported global control\n");
+		return -EINVAL;
+	}
+
+	pwm_get_state(pwm, &curstate);
+	if (curstate.enabled) {
+		dev_err(chip->dev, "Failed to execute global ctrl cmd %d because PWM%d is busy\n",
+			cmd, pc->channel_id);
+		return -EBUSY;
+	}
+
+	ret = clk_enable(pc->pclk);
+	if (ret)
+		return ret;
+
+	ret = pc->data->funcs.global_ctrl(chip, pwm, cmd);
+	if (ret) {
+		dev_err(chip->dev, "Failed to execute global ctrl cmd %d for PWM%d\n",
+			cmd, pc->channel_id);
+		goto err_disable_pclk;
+	}
+
+err_disable_pclk:
+	clk_disable(pc->pclk);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(rockchip_pwm_global_ctrl);
+
+static int rockchip_pwm_set_wave_table_v4(struct pwm_chip *chip, struct pwm_device *pwm,
+					  struct rockchip_pwm_wave_table *table_config,
+					  enum rockchip_pwm_wave_table_width_mode width_mode)
+{
+	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+	u64 table_val = 0;
+	u64 div = 0;
+	u32 arbiter = 0;
+	u32 val;
+	u16 table_max;
+	int i;
+
+	if (width_mode == PWM_WAVE_TABLE_16BITS_WIDTH)
+		table_max = pc->data->wave_table_max / 2;
+	else
+		table_max = pc->data->wave_table_max;
+
+	if (!table_config->table ||
+	    table_config->offset > table_max || table_config->len > table_max) {
+		dev_err(chip->dev, "The wave table to set is out of range for PWM%d\n",
+			pc->channel_id);
+		return -EINVAL;
+	}
+
+	arbiter = BIT(pc->channel_id) << WAVE_MEM_GRANT_SHIFT |
+		  BIT(pc->channel_id) << WAVE_MEM_READ_LOCK_SHIFT;
+	writel_relaxed(arbiter, pc->base + WAVE_MEM_ARBITER);
+
+	val = readl_relaxed(pc->base + WAVE_MEM_ARBITER);
+	if (!(val & arbiter)) {
+		dev_err(chip->dev, "Failed to abtain wave memory arbitration for PWM%d\n",
+			pc->channel_id);
+		return -EINVAL;
+	}
+
+	if (width_mode == PWM_WAVE_TABLE_16BITS_WIDTH) {
+		for (i = 0; i < table_config->len; i++) {
+			div = (u64)pc->clk_rate * table_config->table[i];
+			table_val = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC);
+			writel_relaxed(table_val & 0xff,
+				       pc->base + WAVE_MEM + (table_config->offset + i) * 2 * 4);
+			if (readl_poll_timeout(pc->base + WAVE_MEM_STATUS,
+					       val, (val & BIT(WAVE_MEM_STATUS_SHIFT)),
+					       1000, 10 * 1000)) {
+				dev_err(chip->dev,
+					"Wait for wave mem(offset 0x%08x) to update failed\n",
+					(table_config->offset + i) * 2 * 4);
+				return -ETIMEDOUT;
+			}
+
+			writel_relaxed((table_val >> 8) & 0xff,
+				       pc->base + WAVE_MEM +
+				       ((table_config->offset + i) * 2 + 1) * 4);
+			if (readl_poll_timeout(pc->base + WAVE_MEM_STATUS,
+					       val, (val & BIT(WAVE_MEM_STATUS_SHIFT)),
+					       1000, 10 * 1000)) {
+				dev_err(chip->dev,
+					"Wait for wave mem(offset 0x%08x) to update failed\n",
+					((table_config->offset + i) * 2 + 1) * 4);
+				return -ETIMEDOUT;
+			}
+		}
+	} else {
+		for (i = 0; i < table_config->len; i++) {
+			div = (u64)pc->clk_rate * table_config->table[i];
+			table_val = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC);
+			writel_relaxed(table_val,
+				       pc->base + WAVE_MEM + (table_config->offset + i) * 4);
+			if (readl_poll_timeout(pc->base + WAVE_MEM_STATUS,
+					       val, (val & BIT(WAVE_MEM_STATUS_SHIFT)),
+					       1000, 10 * 1000)) {
+				dev_err(chip->dev,
+					"Wait for wave mem(offset 0x%08x) to update failed\n",
+					(table_config->offset + i) * 4);
+				return -ETIMEDOUT;
+			}
+		}
+	}
+
+	writel_relaxed(0, pc->base + WAVE_MEM_ARBITER);
+
+	return 0;
+}
+
+static int rockchip_pwm_set_wave_v4(struct pwm_chip *chip, struct pwm_device *pwm,
+				    struct rockchip_pwm_wave_config *config)
+{
+	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+	u32 ctrl = 0;
+	u32 max_val = 0;
+	u32 min_val = 0;
+	u32 offset = 0;
+	u32 middle = 0;
+	u32 rpt = 0;
+	u8 factor = 0;
+
+	if (config->enable) {
+		/*
+		 * If the width mode is 16-bits mode, two 8-bits table units
+		 * are combined into one 16-bits unit.
+		 */
+		if (config->width_mode == PWM_WAVE_TABLE_16BITS_WIDTH)
+			factor = 2;
+		else
+			factor = 1;
+
+		ctrl = WAVE_DUTY_EN(config->duty_en) |
+		       WAVE_PERIOD_EN(config->period_en) |
+		       WAVE_WIDTH_MODE(config->width_mode) |
+		       WAVE_UPDATE_MODE(config->update_mode);
+		max_val = config->duty_max * factor << WAVE_DUTY_MAX_SHIFT |
+			  config->period_max * factor << WAVE_PERIOD_MAX_SHIFT;
+		min_val = config->duty_min * factor << WAVE_DUTY_MIN_SHIFT |
+			  config->period_min * factor << WAVE_PERIOD_MIN_SHIFT;
+		offset = config->offset * factor << WAVE_OFFSET_SHIFT;
+		middle = config->middle * factor << WAVE_MIDDLE_SHIFT;
+
+		rpt = config->rpt << FIRST_DIMENSIONAL_SHIFT;
+	} else {
+		ctrl = WAVE_DUTY_EN(false) | WAVE_PERIOD_EN(false);
+	}
+
+	writel_relaxed(ctrl, pc->base + WAVE_CTRL);
+	writel_relaxed(max_val, pc->base + WAVE_MAX);
+	writel_relaxed(min_val, pc->base + WAVE_MIN);
+	writel_relaxed(offset, pc->base + WAVE_OFFSET);
+	writel_relaxed(middle, pc->base + WAVE_MIDDLE);
+
+	writel_relaxed(rpt, pc->base + pc->data->regs.rpt);
+	writel_relaxed(WAVE_MAX_INT_EN(config->enable) | WAVE_MIDDLE_INT_EN(config->enable),
+		       pc->base + pc->data->regs.int_en);
+
+	pc->wave_en = config->enable;
+
+	return 0;
+}
+
+int rockchip_pwm_set_wave(struct pwm_device *pwm, struct rockchip_pwm_wave_config *config)
+{
+	struct pwm_chip *chip;
+	struct rockchip_pwm_chip *pc;
+	int ret = 0;
+
+	if (!pwm || !config)
+		return -EINVAL;
+
+	chip = pwm->chip;
+	pc = to_rockchip_pwm_chip(chip);
+
+	if (!pc->wave_support ||
+	    !pc->data->funcs.set_wave_table || !pc->data->funcs.set_wave) {
+		dev_err(chip->dev, "Unsupported wave generator mode\n");
+		return -EINVAL;
+	}
+
+	ret = clk_enable(pc->pclk);
+	if (ret)
+		return ret;
+
+	if (config->duty_table) {
+		ret = pc->data->funcs.set_wave_table(chip, pwm, config->duty_table,
+						     config->width_mode);
+		if (ret) {
+			dev_err(chip->dev, "Failed to set wave duty table for PWM%d\n",
+				pc->channel_id);
+			goto err_disable_pclk;
+		}
+	}
+
+	if (config->period_table) {
+		ret = pc->data->funcs.set_wave_table(chip, pwm, config->period_table,
+						     config->width_mode);
+		if (ret) {
+			dev_err(chip->dev, "Failed to set wave period table for PWM%d\n",
+				pc->channel_id);
+			goto err_disable_pclk;
+		}
+	}
+
+	ret = pc->data->funcs.set_wave(chip, pwm, config);
+	if (ret) {
+		dev_err(chip->dev, "Failed to set wave generator for PWM%d\n", pc->channel_id);
+		goto err_disable_pclk;
+	}
+
+err_disable_pclk:
+	clk_disable(pc->pclk);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(rockchip_pwm_set_wave);
+
+#ifdef CONFIG_DEBUG_FS
+static int rockchip_pwm_debugfs_show(struct seq_file *s, void *data)
+{
+	struct rockchip_pwm_chip *pc = s->private;
+	u32 regs_start;
+	int i;
+	int ret = 0;
+
+	if (!pc->oneshot_en) {
+		ret = clk_enable(pc->pclk);
+		if (ret)
+			return ret;
+	}
+
+	regs_start = (u32)pc->res->start - pc->channel_id * 0x10;
+	for (i = 0; i < 0x40; i += 4) {
+		seq_printf(s, "%08x:  %08x %08x %08x %08x\n", regs_start + i * 4,
+			   readl_relaxed(pc->base + (4 * i)),
+			   readl_relaxed(pc->base + (4 * (i + 1))),
+			   readl_relaxed(pc->base + (4 * (i + 2))),
+			   readl_relaxed(pc->base + (4 * (i + 3))));
+	}
+
+	if (!pc->oneshot_en)
+		clk_disable(pc->pclk);
+
+	return ret;
+}
+DEFINE_SHOW_ATTRIBUTE(rockchip_pwm_debugfs);
+
+static inline void rockchip_pwm_debugfs_init(struct rockchip_pwm_chip *pc)
+{
+	pc->debugfs = debugfs_create_file(dev_name(pc->chip.dev),
+					  S_IFREG | 0444, NULL, pc,
+					  &rockchip_pwm_debugfs_fops);
+}
+
+static inline void rockchip_pwm_debugfs_deinit(struct rockchip_pwm_chip *pc)
+{
+	debugfs_remove(pc->debugfs);
+}
+#else
+static inline void rockchip_pwm_debugfs_init(struct rockchip_pwm_chip *pc)
+{
+}
+
+static inline void rockchip_pwm_debugfs_deinit(struct rockchip_pwm_chip *pc)
+{
+}
+#endif
+
 static const struct pwm_ops rockchip_pwm_ops = {
-	.get_state = rockchip_pwm_get_state,
+	.capture = rockchip_pwm_capture,
 	.apply = rockchip_pwm_apply,
+	.get_state = rockchip_pwm_get_state,
 	.owner = THIS_MODULE,
 };
 
 static const struct rockchip_pwm_data pwm_data_v1 = {
+	.main_version = 0x01,
 	.regs = {
+		.version = 0x5c,
 		.duty = 0x04,
 		.period = 0x08,
 		.cntr = 0x00,
@@ -390,10 +1475,17 @@
 	.vop_pwm = false,
 	.enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN,
 	.enable_conf_mask = BIT(1) | BIT(3),
+	.oneshot_cnt_max = 0x100,
+	.funcs = {
+		.enable = rockchip_pwm_enable_v1,
+		.config = rockchip_pwm_config_v1,
+	},
 };
 
 static const struct rockchip_pwm_data pwm_data_v2 = {
+	.main_version = 0x02,
 	.regs = {
+		.version = 0x5c,
 		.duty = 0x08,
 		.period = 0x04,
 		.cntr = 0x00,
@@ -406,10 +1498,17 @@
 	.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
 		       PWM_CONTINUOUS,
 	.enable_conf_mask = GENMASK(2, 0) | BIT(5) | BIT(8),
+	.oneshot_cnt_max = 0x100,
+	.funcs = {
+		.enable = rockchip_pwm_enable_v1,
+		.config = rockchip_pwm_config_v1,
+	},
 };
 
 static const struct rockchip_pwm_data pwm_data_vop = {
+	.main_version = 0x02,
 	.regs = {
+		.version = 0x5c,
 		.duty = 0x08,
 		.period = 0x04,
 		.cntr = 0x0c,
@@ -422,10 +1521,17 @@
 	.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
 		       PWM_CONTINUOUS,
 	.enable_conf_mask = GENMASK(2, 0) | BIT(5) | BIT(8),
+	.oneshot_cnt_max = 0x100,
+	.funcs = {
+		.enable = rockchip_pwm_enable_v1,
+		.config = rockchip_pwm_config_v1,
+	},
 };
 
 static const struct rockchip_pwm_data pwm_data_v3 = {
+	.main_version = 0x03,
 	.regs = {
+		.version = 0x5c,
 		.duty = 0x08,
 		.period = 0x04,
 		.cntr = 0x00,
@@ -438,6 +1544,53 @@
 	.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
 		       PWM_CONTINUOUS,
 	.enable_conf_mask = GENMASK(2, 0) | BIT(5) | BIT(8),
+	.oneshot_cnt_max = 0x100,
+	.funcs = {
+		.enable = rockchip_pwm_enable_v1,
+		.config = rockchip_pwm_config_v1,
+		.irq_handler = rockchip_pwm_irq_v1,
+	},
+};
+
+static const struct rockchip_pwm_data pwm_data_v4 = {
+	.main_version = 0x04,
+	.regs = {
+		.version = 0x0,
+		.enable = 0x4,
+		.clk_ctrl = 0x8,
+		.ctrl = 0xc,
+		.period = 0x10,
+		.duty = 0x14,
+		.offset = 0x18,
+		.rpt = 0x1c,
+		.hpr = 0x2c,
+		.lpr = 0x30,
+		.intsts = 0x70,
+		.int_en = 0x74,
+		.int_mask = 0x78,
+	},
+	.prescaler = 1,
+	.supports_polarity = true,
+	.supports_lock = true,
+	.vop_pwm = false,
+	.oneshot_cnt_max = 0x10000,
+	.oneshot_rpt_max = 0x10000,
+	.wave_table_max = 0x300,
+	.enable_conf = PWM_ENABLE_V4,
+	.funcs = {
+		.enable = rockchip_pwm_enable_v4,
+		.config = rockchip_pwm_config_v4,
+		.set_capture = rockchip_pwm_set_capture_v4,
+		.get_capture_result = rockchip_pwm_get_capture_result_v4,
+		.set_counter = rockchip_pwm_set_counter_v4,
+		.get_counter_result = rockchip_pwm_get_counter_result_v4,
+		.set_freq_meter = rockchip_pwm_set_freq_meter_v4,
+		.get_freq_meter_result = rockchip_pwm_get_freq_meter_result_v4,
+		.global_ctrl = rockchip_pwm_global_ctrl_v4,
+		.set_wave_table = rockchip_pwm_set_wave_table_v4,
+		.set_wave = rockchip_pwm_set_wave_v4,
+		.irq_handler = rockchip_pwm_irq_v4,
+	},
 };
 
 static const struct of_device_id rockchip_pwm_dt_ids[] = {
@@ -461,7 +1614,7 @@
 	const struct of_device_id *id;
 	struct rockchip_pwm_chip *pc;
 	struct resource *r;
-	u32 enable_conf, ctrl;
+	u32 enable_conf, ctrl, version;
 	bool enabled;
 	int ret, count;
 
@@ -474,8 +1627,14 @@
 		return -ENOMEM;
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	pc->base = devm_ioremap(&pdev->dev, r->start,
-				resource_size(r));
+	if (!r) {
+		dev_err(&pdev->dev, "Failed to get pwm register\n");
+		return -EINVAL;
+	}
+	pc->res = r;
+
+	pc->base = devm_ioremap(&pdev->dev, pc->res->start,
+				resource_size(pc->res));
 	if (IS_ERR(pc->base))
 		return PTR_ERR(pc->base);
 
@@ -513,30 +1672,6 @@
 		goto err_clk;
 	}
 
-	pc->channel_id = rockchip_pwm_get_channel_id(pdev->dev.of_node->full_name);
-	if (pc->channel_id < 0 || pc->channel_id >= PWM_MAX_CHANNEL_NUM) {
-		dev_err(&pdev->dev, "Channel id is out of range: %d\n", pc->channel_id);
-		ret = -EINVAL;
-		goto err_pclk;
-	}
-
-	if (IS_ENABLED(CONFIG_PWM_ROCKCHIP_ONESHOT)) {
-		pc->irq = platform_get_irq(pdev, 0);
-		if (pc->irq < 0) {
-			dev_err(&pdev->dev, "Get oneshot mode irq failed\n");
-			ret = pc->irq;
-			goto err_pclk;
-		}
-
-		ret = devm_request_irq(&pdev->dev, pc->irq, rockchip_pwm_oneshot_irq,
-				       IRQF_NO_SUSPEND | IRQF_SHARED,
-				       "rk_pwm_oneshot_irq", pc);
-		if (ret) {
-			dev_err(&pdev->dev, "Claim oneshot IRQ failed\n");
-			goto err_pclk;
-		}
-	}
-
 	pc->pinctrl = devm_pinctrl_get(&pdev->dev);
 	if (IS_ERR(pc->pinctrl)) {
 		dev_err(&pdev->dev, "Get pinctrl failed!\n");
@@ -559,6 +1694,56 @@
 	pc->chip.base = of_alias_get_id(pdev->dev.of_node, "pwm");
 	pc->chip.npwm = 1;
 	pc->clk_rate = clk_get_rate(pc->clk);
+	pc->main_version = pc->data->main_version;
+	if (pc->main_version >= 4) {
+		version = readl_relaxed(pc->base + pc->data->regs.version);
+		pc->channel_id = (version & CHANNLE_INDEX_MASK) >> CHANNLE_INDEX_SHIFT;
+		pc->freq_meter_support = !!(version & FREQ_METER_SUPPORT);
+		pc->counter_support = !!(version & COUNTER_SUPPORT);
+		pc->wave_support = !!(version & WAVE_SUPPORT);
+	} else {
+		pc->channel_id = rockchip_pwm_get_channel_id(pdev->dev.of_node->full_name);
+	}
+	if (pc->channel_id < 0 || pc->channel_id >= PWM_MAX_CHANNEL_NUM) {
+		dev_err(&pdev->dev, "Channel id is out of range: %d\n", pc->channel_id);
+		ret = -EINVAL;
+		goto err_pclk;
+	}
+
+	if (pc->data->funcs.irq_handler) {
+		if (pc->main_version >= 4) {
+			pc->irq = platform_get_irq(pdev, 0);
+			if (pc->irq < 0) {
+				dev_err(&pdev->dev, "Get irq failed\n");
+				ret = pc->irq;
+				goto err_pclk;
+			}
+
+			ret = devm_request_irq(&pdev->dev, pc->irq, pc->data->funcs.irq_handler,
+					       IRQF_NO_SUSPEND, "rk_pwm_irq", pc);
+			if (ret) {
+				dev_err(&pdev->dev, "Claim IRQ failed\n");
+				goto err_pclk;
+			}
+		} else {
+			if (IS_ENABLED(CONFIG_PWM_ROCKCHIP_ONESHOT)) {
+				pc->irq = platform_get_irq_optional(pdev, 0);
+				if (pc->irq < 0) {
+					dev_warn(&pdev->dev,
+						 "Can't get oneshot mode irq and oneshot interrupt is unsupported\n");
+				} else {
+					ret = devm_request_irq(&pdev->dev, pc->irq,
+							       pc->data->funcs.irq_handler,
+							       IRQF_NO_SUSPEND | IRQF_SHARED,
+							       "rk_pwm_oneshot_irq", pc);
+					if (ret) {
+						dev_err(&pdev->dev, "Claim oneshot IRQ failed\n");
+						goto err_pclk;
+					}
+				}
+			}
+		}
+	}
 
 	if (pc->data->supports_polarity) {
 		pc->chip.of_xlate = of_pwm_xlate_with_flags;
@@ -566,7 +1751,10 @@
 	}
 
 	enable_conf = pc->data->enable_conf;
-	ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
+	if (pc->main_version >= 4)
+		ctrl = readl_relaxed(pc->base + pc->data->regs.enable);
+	else
+		ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
 	enabled = (ctrl & enable_conf) == enable_conf;
 
 	pc->center_aligned =
@@ -577,6 +1765,8 @@
 		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
 		goto err_pclk;
 	}
+
+	rockchip_pwm_debugfs_init(pc);
 
 	/* Keep the PWM clk enabled if the PWM appears to be up and running. */
 	if (!enabled)
@@ -600,6 +1790,8 @@
 	struct pwm_state state;
 	u32 val;
 
+	rockchip_pwm_debugfs_deinit(pc);
+
 	/*
 	 * For oneshot mode, it is needed to wait for bit PWM_ENABLE
 	 * to 0, which is automatic if all periods have been sent.
diff --git a/kernel/drivers/pwm/pwm-rockchip.h b/kernel/drivers/pwm/pwm-rockchip.h
deleted file mode 100644
index 1995b9d..0000000
--- a/kernel/drivers/pwm/pwm-rockchip.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
-/*
- * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
- */
-
-#ifndef _PWM_ROCKCHIP_H_
-#define _PWM_ROCKCHIP_H_
-
-#include <linux/pwm.h>
-
-static void rockchip_pwm_oneshot_callback(struct pwm_device *pwm, struct pwm_state *state)
-{
-	/*
-	 * If you want to enable oneshot mode again, config and call
-	 * pwm_apply_state().
-	 *
-	 * struct pwm_state new_state;
-	 *
-	 * pwm_get_state(pwm, &new_state);
-	 * new_state.enabled = true;
-	 * ......
-	 * pwm_apply_state(pwm, &new_state);
-	 *
-	 */
-}
-
-#endif
diff --git a/kernel/drivers/pwm/pwm-sifive.c b/kernel/drivers/pwm/pwm-sifive.c
index 9cc0612..52a55ba 100644
--- a/kernel/drivers/pwm/pwm-sifive.c
+++ b/kernel/drivers/pwm/pwm-sifive.c
@@ -41,7 +41,7 @@
 
 struct pwm_sifive_ddata {
 	struct pwm_chip	chip;
-	struct mutex lock; /* lock to protect user_count */
+	struct mutex lock; /* lock to protect user_count and approx_period */
 	struct notifier_block notifier;
 	struct clk *clk;
 	void __iomem *regs;
@@ -76,6 +76,7 @@
 	mutex_unlock(&ddata->lock);
 }
 
+/* Called holding ddata->lock */
 static void pwm_sifive_update_clock(struct pwm_sifive_ddata *ddata,
 				    unsigned long rate)
 {
@@ -163,7 +164,6 @@
 		return ret;
 	}
 
-	mutex_lock(&ddata->lock);
 	cur_state = pwm->state;
 	enabled = cur_state.enabled;
 
@@ -182,14 +182,23 @@
 	/* The hardware cannot generate a 100% duty cycle */
 	frac = min(frac, (1U << PWM_SIFIVE_CMPWIDTH) - 1);
 
+	mutex_lock(&ddata->lock);
 	if (state->period != ddata->approx_period) {
-		if (ddata->user_count != 1) {
+		/*
+		 * Don't let a 2nd user change the period underneath the 1st user.
+		 * However if ddate->approx_period == 0 this is the first time we set
+		 * any period, so let whoever gets here first set the period so other
+		 * users who agree on the period won't fail.
+		 */
+		if (ddata->user_count != 1 && ddata->approx_period) {
+			mutex_unlock(&ddata->lock);
 			ret = -EBUSY;
 			goto exit;
 		}
 		ddata->approx_period = state->period;
 		pwm_sifive_update_clock(ddata, clk_get_rate(ddata->clk));
 	}
+	mutex_unlock(&ddata->lock);
 
 	writel(frac, ddata->regs + PWM_SIFIVE_PWMCMP(pwm->hwpwm));
 
@@ -198,7 +207,6 @@
 
 exit:
 	clk_disable(ddata->clk);
-	mutex_unlock(&ddata->lock);
 	return ret;
 }
 
@@ -217,8 +225,11 @@
 	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;
 }
diff --git a/kernel/drivers/pwm/pwm-sprd.c b/kernel/drivers/pwm/pwm-sprd.c
index 9eeb59c..b23456d 100644
--- a/kernel/drivers/pwm/pwm-sprd.c
+++ b/kernel/drivers/pwm/pwm-sprd.c
@@ -109,6 +109,7 @@
 	duty = val & SPRD_PWM_DUTY_MSK;
 	tmp = (prescale + 1) * NSEC_PER_SEC * duty;
 	state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, chn->clk_rate);
+	state->polarity = PWM_POLARITY_NORMAL;
 
 	/* Disable PWM clocks if the PWM channel is not in enable state. */
 	if (!state->enabled)
diff --git a/kernel/drivers/pwm/pwm-stm32-lp.c b/kernel/drivers/pwm/pwm-stm32-lp.c
index 945a8b2..c8a847f 100644
--- a/kernel/drivers/pwm/pwm-stm32-lp.c
+++ b/kernel/drivers/pwm/pwm-stm32-lp.c
@@ -127,7 +127,7 @@
 
 	/* 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) {
 		dev_err(priv->chip.dev, "ARR/CMP registers write issue\n");
diff --git a/kernel/drivers/pwm/pwm-tegra.c b/kernel/drivers/pwm/pwm-tegra.c
index 8c4e665..f3528c5 100644
--- a/kernel/drivers/pwm/pwm-tegra.c
+++ b/kernel/drivers/pwm/pwm-tegra.c
@@ -142,8 +142,8 @@
 		 * 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((u64)NSEC_PER_SEC << PWM_DUTY_WIDTH,
+						     period_ns);
 
 		err = clk_set_rate(pc->clk, required_clk_rate);
 		if (err < 0)
diff --git a/kernel/drivers/pwm/sysfs.c b/kernel/drivers/pwm/sysfs.c
index ca47570..b1b2a61 100644
--- a/kernel/drivers/pwm/sysfs.c
+++ b/kernel/drivers/pwm/sysfs.c
@@ -138,6 +138,76 @@
 
 	return ret ? : size;
 }
+
+static ssize_t oneshot_repeat_show(struct device *child,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	const struct pwm_device *pwm = child_to_pwm_device(child);
+	struct pwm_state state;
+
+	pwm_get_state(pwm, &state);
+
+	return sprintf(buf, "%u\n", state.oneshot_repeat);
+}
+
+static ssize_t oneshot_repeat_store(struct device *child,
+				    struct device_attribute *attr,
+				    const char *buf, size_t size)
+{
+	struct pwm_export *export = child_to_pwm_export(child);
+	struct pwm_device *pwm = export->pwm;
+	struct pwm_state state;
+	unsigned int val;
+	int ret;
+
+	ret = kstrtouint(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&export->lock);
+	pwm_get_state(pwm, &state);
+	state.oneshot_repeat = val;
+	ret = pwm_apply_state(pwm, &state);
+	mutex_unlock(&export->lock);
+
+	return ret ? : size;
+}
+
+static ssize_t duty_offset_show(struct device *child,
+				struct device_attribute *attr,
+				char *buf)
+{
+	const struct pwm_device *pwm = child_to_pwm_device(child);
+	struct pwm_state state;
+
+	pwm_get_state(pwm, &state);
+
+	return sprintf(buf, "%llu\n", state.duty_offset);
+}
+
+static ssize_t duty_offset_store(struct device *child,
+				 struct device_attribute *attr,
+				 const char *buf, size_t size)
+{
+	struct pwm_export *export = child_to_pwm_export(child);
+	struct pwm_device *pwm = export->pwm;
+	struct pwm_state state;
+	u64 val;
+	int ret;
+
+	ret = kstrtou64(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&export->lock);
+	pwm_get_state(pwm, &state);
+	state.duty_offset = val;
+	ret = pwm_apply_state(pwm, &state);
+	mutex_unlock(&export->lock);
+
+	return ret ? : size;
+}
 #endif
 
 static ssize_t enable_show(struct device *child,
@@ -279,6 +349,8 @@
 static DEVICE_ATTR_RW(duty_cycle);
 #ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
 static DEVICE_ATTR_RW(oneshot_count);
+static DEVICE_ATTR_RW(oneshot_repeat);
+static DEVICE_ATTR_RW(duty_offset);
 #endif
 static DEVICE_ATTR_RW(enable);
 static DEVICE_ATTR_RW(polarity);
@@ -290,6 +362,8 @@
 	&dev_attr_duty_cycle.attr,
 #ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
 	&dev_attr_oneshot_count.attr,
+	&dev_attr_oneshot_repeat.attr,
+	&dev_attr_duty_offset.attr,
 #endif
 	&dev_attr_enable.attr,
 	&dev_attr_polarity.attr,
@@ -492,6 +566,13 @@
 		if (!export)
 			continue;
 
+		/* If pwmchip was not enabled before suspend, do nothing. */
+		if (!export->suspend.enabled) {
+			/* release lock taken in pwm_class_get_state */
+			mutex_unlock(&export->lock);
+			continue;
+		}
+
 		state.enabled = export->suspend.enabled;
 		ret = pwm_class_apply_state(export, pwm, &state);
 		if (ret < 0)
@@ -516,7 +597,17 @@
 		if (!export)
 			continue;
 
+		/*
+		 * If pwmchip was not enabled before suspend, save
+		 * state for resume time and do nothing else.
+		 */
 		export->suspend = state;
+		if (!state.enabled) {
+			/* release lock taken in pwm_class_get_state */
+			mutex_unlock(&export->lock);
+			continue;
+		}
+
 		state.enabled = false;
 		ret = pwm_class_apply_state(export, pwm, &state);
 		if (ret < 0) {
diff --git a/kernel/drivers/rapidio/devices/rio_mport_cdev.c b/kernel/drivers/rapidio/devices/rio_mport_cdev.c
index 94331d9..5ac2dc1 100644
--- a/kernel/drivers/rapidio/devices/rio_mport_cdev.c
+++ b/kernel/drivers/rapidio/devices/rio_mport_cdev.c
@@ -1803,8 +1803,11 @@
 		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;
@@ -1900,10 +1903,6 @@
 
 	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);
@@ -1912,6 +1911,7 @@
 			  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;
@@ -1922,6 +1922,9 @@
 	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;
diff --git a/kernel/drivers/rapidio/rio-scan.c b/kernel/drivers/rapidio/rio-scan.c
index 19b0c33..fdcf742 100644
--- a/kernel/drivers/rapidio/rio-scan.c
+++ b/kernel/drivers/rapidio/rio-scan.c
@@ -454,8 +454,12 @@
 				   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);
 
diff --git a/kernel/drivers/rapidio/rio.c b/kernel/drivers/rapidio/rio.c
index 606986c..fcab174 100644
--- a/kernel/drivers/rapidio/rio.c
+++ b/kernel/drivers/rapidio/rio.c
@@ -2267,11 +2267,16 @@
 	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;
 }
diff --git a/kernel/drivers/regulator/core.c b/kernel/drivers/regulator/core.c
index 0e2824f..7105e1b 100644
--- a/kernel/drivers/regulator/core.c
+++ b/kernel/drivers/regulator/core.c
@@ -222,6 +222,78 @@
 	mutex_unlock(&regulator_nesting_mutex);
 }
 
+/**
+ * regulator_lock_two - lock two regulators
+ * @rdev1:		first regulator
+ * @rdev2:		second regulator
+ * @ww_ctx:		w/w mutex acquire context
+ *
+ * Locks both rdevs using the regulator_ww_class.
+ */
+static void regulator_lock_two(struct regulator_dev *rdev1,
+			       struct regulator_dev *rdev2,
+			       struct ww_acquire_ctx *ww_ctx)
+{
+	struct regulator_dev *tmp;
+	int ret;
+
+	ww_acquire_init(ww_ctx, &regulator_ww_class);
+
+	/* Try to just grab both of them */
+	ret = regulator_lock_nested(rdev1, ww_ctx);
+	WARN_ON(ret);
+	ret = regulator_lock_nested(rdev2, ww_ctx);
+	if (ret != -EDEADLOCK) {
+		WARN_ON(ret);
+		goto exit;
+	}
+
+	while (true) {
+		/*
+		 * Start of loop: rdev1 was locked and rdev2 was contended.
+		 * Need to unlock rdev1, slowly lock rdev2, then try rdev1
+		 * again.
+		 */
+		regulator_unlock(rdev1);
+
+		ww_mutex_lock_slow(&rdev2->mutex, ww_ctx);
+		rdev2->ref_cnt++;
+		rdev2->mutex_owner = current;
+		ret = regulator_lock_nested(rdev1, ww_ctx);
+
+		if (ret == -EDEADLOCK) {
+			/* More contention; swap which needs to be slow */
+			tmp = rdev1;
+			rdev1 = rdev2;
+			rdev2 = tmp;
+		} else {
+			WARN_ON(ret);
+			break;
+		}
+	}
+
+exit:
+	ww_acquire_done(ww_ctx);
+}
+
+/**
+ * regulator_unlock_two - unlock two regulators
+ * @rdev1:		first regulator
+ * @rdev2:		second regulator
+ * @ww_ctx:		w/w mutex acquire context
+ *
+ * The inverse of regulator_lock_two().
+ */
+
+static void regulator_unlock_two(struct regulator_dev *rdev1,
+				 struct regulator_dev *rdev2,
+				 struct ww_acquire_ctx *ww_ctx)
+{
+	regulator_unlock(rdev2);
+	regulator_unlock(rdev1);
+	ww_acquire_fini(ww_ctx);
+}
+
 static bool regulator_supply_is_couple(struct regulator_dev *rdev)
 {
 	struct regulator_dev *c_rdev;
@@ -349,6 +421,7 @@
 			ww_mutex_lock_slow(&new_contended_rdev->mutex, ww_ctx);
 			old_contended_rdev = new_contended_rdev;
 			old_contended_rdev->ref_cnt++;
+			old_contended_rdev->mutex_owner = current;
 		}
 
 		err = regulator_lock_recursive(rdev,
@@ -986,7 +1059,7 @@
 		/* get input voltage */
 		input_uV = 0;
 		if (rdev->supply)
-			input_uV = regulator_get_voltage(rdev->supply);
+			input_uV = regulator_get_voltage_rdev(rdev->supply->rdev);
 		if (input_uV <= 0)
 			input_uV = rdev->constraints->input_uV;
 		if (input_uV <= 0) {
@@ -1434,7 +1507,13 @@
 		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);
@@ -1459,8 +1538,8 @@
 
 /**
  * set_supply - set regulator supply regulator
- * @rdev: regulator name
- * @supply_rdev: supply regulator name
+ * @rdev: regulator (locked)
+ * @supply_rdev: supply regulator (locked))
  *
  * Called by platform initialisation code to set the supply regulator for this
  * regulator. This ensures that a regulators supply will also be enabled by the
@@ -1478,6 +1557,7 @@
 
 	rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
 	if (rdev->supply == NULL) {
+		module_put(supply_rdev->owner);
 		err = -ENOMEM;
 		return err;
 	}
@@ -1631,6 +1711,8 @@
 	struct regulator *regulator;
 	int err = 0;
 
+	lockdep_assert_held_once(&rdev->mutex.base);
+
 	if (dev) {
 		char buf[REG_STR_SIZE];
 		int size;
@@ -1651,16 +1733,14 @@
 
 	regulator = kzalloc(sizeof(*regulator), GFP_KERNEL);
 	if (regulator == NULL) {
-		kfree(supply_name);
+		kfree_const(supply_name);
 		return NULL;
 	}
 
 	regulator->rdev = rdev;
 	regulator->supply_name = supply_name;
 
-	regulator_lock(rdev);
 	list_add(&regulator->list, &rdev->consumer_list);
-	regulator_unlock(rdev);
 
 	if (dev) {
 		regulator->dev = dev;
@@ -1677,19 +1757,19 @@
 
 	if (err != -EEXIST)
 		regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs);
-	if (!regulator->debugfs) {
+	else
+		regulator->debugfs = ERR_PTR(err);
+	if (IS_ERR(regulator->debugfs))
 		rdev_dbg(rdev, "Failed to create debugfs directory\n");
-	} else {
-		debugfs_create_u32("uA_load", 0444, regulator->debugfs,
-				   &regulator->uA_load);
-		debugfs_create_u32("min_uV", 0444, regulator->debugfs,
-				   &regulator->voltage[PM_SUSPEND_ON].min_uV);
-		debugfs_create_u32("max_uV", 0444, regulator->debugfs,
-				   &regulator->voltage[PM_SUSPEND_ON].max_uV);
-		debugfs_create_file("constraint_flags", 0444,
-				    regulator->debugfs, regulator,
-				    &constraint_flags_fops);
-	}
+
+	debugfs_create_u32("uA_load", 0444, regulator->debugfs,
+			   &regulator->uA_load);
+	debugfs_create_u32("min_uV", 0444, regulator->debugfs,
+			   &regulator->voltage[PM_SUSPEND_ON].min_uV);
+	debugfs_create_u32("max_uV", 0444, regulator->debugfs,
+			   &regulator->voltage[PM_SUSPEND_ON].max_uV);
+	debugfs_create_file("constraint_flags", 0444, regulator->debugfs,
+			    regulator, &constraint_flags_fops);
 
 	/*
 	 * Check now if the regulator is an always on regulator - if
@@ -1781,6 +1861,7 @@
 		node = of_get_regulator(dev, supply);
 		if (node) {
 			r = of_find_regulator_by_node(node);
+			of_node_put(node);
 			if (r)
 				return r;
 
@@ -1825,6 +1906,7 @@
 {
 	struct regulator_dev *r;
 	struct device *dev = rdev->dev.parent;
+	struct ww_acquire_ctx ww_ctx;
 	int ret = 0;
 
 	/* No supply to resolve? */
@@ -1891,23 +1973,23 @@
 	 * between rdev->supply null check and setting rdev->supply in
 	 * set_supply() from concurrent tasks.
 	 */
-	regulator_lock(rdev);
+	regulator_lock_two(rdev, r, &ww_ctx);
 
 	/* Supply just resolved by a concurrent task? */
 	if (rdev->supply) {
-		regulator_unlock(rdev);
+		regulator_unlock_two(rdev, r, &ww_ctx);
 		put_device(&r->dev);
 		goto out;
 	}
 
 	ret = set_supply(rdev, r);
 	if (ret < 0) {
-		regulator_unlock(rdev);
+		regulator_unlock_two(rdev, r, &ww_ctx);
 		put_device(&r->dev);
 		goto out;
 	}
 
-	regulator_unlock(rdev);
+	regulator_unlock_two(rdev, r, &ww_ctx);
 
 	/*
 	 * In set_machine_constraints() we may have turned this regulator on
@@ -2020,7 +2102,9 @@
 		return regulator;
 	}
 
+	regulator_lock(rdev);
 	regulator = create_regulator(rdev, dev, id);
+	regulator_unlock(rdev);
 	if (regulator == NULL) {
 		regulator = ERR_PTR(-ENOMEM);
 		module_put(rdev->owner);
@@ -5216,10 +5300,8 @@
 	}
 
 	rdev->debugfs = debugfs_create_dir(rname, debugfs_root);
-	if (!rdev->debugfs) {
-		rdev_warn(rdev, "Failed to create debugfs directory\n");
-		return;
-	}
+	if (IS_ERR(rdev->debugfs))
+		rdev_dbg(rdev, "Failed to create debugfs directory\n");
 
 	debugfs_create_u32("use_count", 0444, rdev->debugfs,
 			   &rdev->use_count);
@@ -5742,6 +5824,7 @@
 	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);
@@ -6135,6 +6218,7 @@
 			ww_mutex_lock_slow(&new_contended_rdev->mutex, ww_ctx);
 			old_contended_rdev = new_contended_rdev;
 			old_contended_rdev->ref_cnt++;
+			old_contended_rdev->mutex_owner = current;
 		}
 
 		err = regulator_summary_lock_all(ww_ctx,
@@ -6195,8 +6279,8 @@
 	ret = class_register(&regulator_class);
 
 	debugfs_root = debugfs_create_dir("regulator", NULL);
-	if (!debugfs_root)
-		pr_warn("regulator: Failed to create debugfs directory\n");
+	if (IS_ERR(debugfs_root))
+		pr_debug("regulator: Failed to create debugfs directory\n");
 
 #ifdef CONFIG_DEBUG_FS
 	debugfs_create_file("supply_map", 0444, debugfs_root, NULL,
diff --git a/kernel/drivers/regulator/da9211-regulator.c b/kernel/drivers/regulator/da9211-regulator.c
index e01b32d..00828f5 100644
--- a/kernel/drivers/regulator/da9211-regulator.c
+++ b/kernel/drivers/regulator/da9211-regulator.c
@@ -498,6 +498,12 @@
 
 	chip->chip_irq = i2c->irq;
 
+	ret = da9211_regulator_init(chip);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to initialize regulator: %d\n", ret);
+		return ret;
+	}
+
 	if (chip->chip_irq != 0) {
 		ret = devm_request_threaded_irq(chip->dev, chip->chip_irq, NULL,
 					da9211_irq_handler,
@@ -511,11 +517,6 @@
 	} else {
 		dev_warn(chip->dev, "No IRQ configured\n");
 	}
-
-	ret = da9211_regulator_init(chip);
-
-	if (ret < 0)
-		dev_err(chip->dev, "Failed to initialize regulator: %d\n", ret);
 
 	return ret;
 }
diff --git a/kernel/drivers/regulator/fan53555.c b/kernel/drivers/regulator/fan53555.c
index eca3e3a..4860a6b 100644
--- a/kernel/drivers/regulator/fan53555.c
+++ b/kernel/drivers/regulator/fan53555.c
@@ -8,18 +8,19 @@
 // Copyright (c) 2012 Marvell Technology Ltd.
 // Yunfan Zhang <yfzhang@marvell.com>
 
-#include <linux/module.h>
-#include <linux/param.h>
+#include <linux/bits.h>
 #include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/param.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/regulator/driver.h>
+#include <linux/regulator/fan53555.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/of_regulator.h>
-#include <linux/of_device.h>
-#include <linux/i2c.h>
 #include <linux/slab.h>
-#include <linux/regmap.h>
-#include <linux/regulator/fan53555.h>
 
 /* Voltage setting */
 #define FAN53555_VSEL0		0x00
diff --git a/kernel/drivers/regulator/fixed.c b/kernel/drivers/regulator/fixed.c
index 3de7709..4acfff1 100644
--- a/kernel/drivers/regulator/fixed.c
+++ b/kernel/drivers/regulator/fixed.c
@@ -175,7 +175,7 @@
 		drvdata->enable_clock = devm_clk_get(dev, NULL);
 		if (IS_ERR(drvdata->enable_clock)) {
 			dev_err(dev, "Can't get enable-clock from devicetree\n");
-			return -ENOENT;
+			return PTR_ERR(drvdata->enable_clock);
 		}
 	} else {
 		drvdata->desc.ops = &fixed_voltage_ops;
diff --git a/kernel/drivers/regulator/max77802-regulator.c b/kernel/drivers/regulator/max77802-regulator.c
index 7b8ec8c..660e179 100644
--- a/kernel/drivers/regulator/max77802-regulator.c
+++ b/kernel/drivers/regulator/max77802-regulator.c
@@ -95,9 +95,11 @@
 {
 	unsigned int val = MAX77802_OFF_PWRREQ;
 	struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
-	int id = rdev_get_id(rdev);
+	unsigned int id = rdev_get_id(rdev);
 	int shift = max77802_get_opmode_shift(id);
 
+	if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode)))
+		return -EINVAL;
 	max77802->opmode[id] = val;
 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
 				  rdev->desc->enable_mask, val << shift);
@@ -111,7 +113,7 @@
 static int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode)
 {
 	struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
-	int id = rdev_get_id(rdev);
+	unsigned int id = rdev_get_id(rdev);
 	unsigned int val;
 	int shift = max77802_get_opmode_shift(id);
 
@@ -128,6 +130,9 @@
 		return -EINVAL;
 	}
 
+	if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode)))
+		return -EINVAL;
+
 	max77802->opmode[id] = val;
 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
 				  rdev->desc->enable_mask, val << shift);
@@ -136,8 +141,10 @@
 static unsigned max77802_get_mode(struct regulator_dev *rdev)
 {
 	struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
-	int id = rdev_get_id(rdev);
+	unsigned int id = rdev_get_id(rdev);
 
+	if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode)))
+		return -EINVAL;
 	return max77802_map_mode(max77802->opmode[id]);
 }
 
@@ -161,9 +168,12 @@
 				     unsigned int mode)
 {
 	struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
-	int id = rdev_get_id(rdev);
+	unsigned int id = rdev_get_id(rdev);
 	unsigned int val;
 	int shift = max77802_get_opmode_shift(id);
+
+	if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode)))
+		return -EINVAL;
 
 	/*
 	 * If the regulator has been disabled for suspend
@@ -210,9 +220,11 @@
 static int max77802_enable(struct regulator_dev *rdev)
 {
 	struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
-	int id = rdev_get_id(rdev);
+	unsigned int id = rdev_get_id(rdev);
 	int shift = max77802_get_opmode_shift(id);
 
+	if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode)))
+		return -EINVAL;
 	if (max77802->opmode[id] == MAX77802_OFF_PWRREQ)
 		max77802->opmode[id] = MAX77802_OPMODE_NORMAL;
 
@@ -541,7 +553,7 @@
 
 	for (i = 0; i < MAX77802_REG_MAX; i++) {
 		struct regulator_dev *rdev;
-		int id = regulators[i].id;
+		unsigned int id = regulators[i].id;
 		int shift = max77802_get_opmode_shift(id);
 		int ret;
 
@@ -559,10 +571,12 @@
 		 * the hardware reports OFF as the regulator operating mode.
 		 * Default to operating mode NORMAL in that case.
 		 */
-		if (val == MAX77802_STATUS_OFF)
-			max77802->opmode[id] = MAX77802_OPMODE_NORMAL;
-		else
-			max77802->opmode[id] = val;
+		if (id < ARRAY_SIZE(max77802->opmode)) {
+			if (val == MAX77802_STATUS_OFF)
+				max77802->opmode[id] = MAX77802_OPMODE_NORMAL;
+			else
+				max77802->opmode[id] = val;
+		}
 
 		rdev = devm_regulator_register(&pdev->dev,
 					       &regulators[i], &config);
diff --git a/kernel/drivers/regulator/rk806-regulator.c b/kernel/drivers/regulator/rk806-regulator.c
index a01d700..3e33b3f 100644
--- a/kernel/drivers/regulator/rk806-regulator.c
+++ b/kernel/drivers/regulator/rk806-regulator.c
@@ -759,7 +759,7 @@
 	struct rk806 *rk806 = pdata->rk806;
 	int rid = rdev_get_id(rdev);
 	int gpio_level, pid;
-	unsigned int val;
+	int ret, val;
 	int mode;
 
 	mode = get_dvs_mode(rdev);
@@ -770,7 +770,12 @@
 			return rk806_field_read(rk806, pdata->dvs_field[rid].sleep_en);
 	}
 
-	val = rk806_field_read(rk806, pdata->dvs_field[rid].en_reg);
+	ret = rk806_field_read(rk806, pdata->dvs_field[rid].en_reg);
+	if (ret < 0)
+		return ret;
+
+	val = ret;
+
 	return (val & rdev->desc->enable_val) != 0;
 }
 
@@ -942,6 +947,20 @@
 	.set_suspend_disable	= rk806_set_suspend_disable,
 };
 
+static const struct regulator_ops rk806_ops_ldo6 = {
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+
+	.get_voltage_sel	= rk806_get_voltage_sel_regmap,
+	.set_voltage		= rk806_set_voltage,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+
+	.set_ramp_delay		= rk806_set_ramp_delay,
+
+	.set_suspend_voltage	= rk806_set_suspend_voltage_range,
+	.resume			= rk806_regulator_resume,
+};
+
 #define RK806_REGULATOR(_name, _supply_name, _id, _ops,\
 			_n_voltages, _vr, _er, _lr, ctrl_bit)\
 [_id] = {\
@@ -1033,7 +1052,7 @@
 			RK806_LDO_SEL_CNT, RK806_PLDO5_ON_VSEL,
 			RK806_POWER_EN5, rk806_ldo_voltage_ranges, 1),
 
-	RK806_REGULATOR("PLDO_REG6", "vcca", RK806_ID_PLDO6, rk806_ops_ldo,
+	RK806_REGULATOR("PLDO_REG6", "vcca", RK806_ID_PLDO6, rk806_ops_ldo6,
 			RK806_LDO_SEL_CNT, RK806_PLDO6_ON_VSEL,
 			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 0),
 };
diff --git a/kernel/drivers/regulator/s5m8767.c b/kernel/drivers/regulator/s5m8767.c
index 35269f9..754c6fc 100644
--- a/kernel/drivers/regulator/s5m8767.c
+++ b/kernel/drivers/regulator/s5m8767.c
@@ -923,10 +923,14 @@
 
 	for (i = 0; i < pdata->num_regulators; i++) {
 		const struct sec_voltage_desc *desc;
-		int id = pdata->regulators[i].id;
+		unsigned int id = pdata->regulators[i].id;
 		int enable_reg, enable_val;
 		struct regulator_dev *rdev;
 
+		BUILD_BUG_ON(ARRAY_SIZE(regulators) != ARRAY_SIZE(reg_voltage_map));
+		if (WARN_ON_ONCE(id >= ARRAY_SIZE(regulators)))
+			continue;
+
 		desc = reg_voltage_map[id];
 		if (desc) {
 			regulators[id].n_voltages =
diff --git a/kernel/drivers/regulator/stm32-pwr.c b/kernel/drivers/regulator/stm32-pwr.c
index 2a42acb..e5dd4db 100644
--- a/kernel/drivers/regulator/stm32-pwr.c
+++ b/kernel/drivers/regulator/stm32-pwr.c
@@ -129,17 +129,16 @@
 
 static int stm32_pwr_regulator_probe(struct platform_device *pdev)
 {
-	struct device_node *np = pdev->dev.of_node;
 	struct stm32_pwr_reg *priv;
 	void __iomem *base;
 	struct regulator_dev *rdev;
 	struct regulator_config config = { };
 	int i, ret = 0;
 
-	base = of_iomap(np, 0);
-	if (!base) {
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base)) {
 		dev_err(&pdev->dev, "Unable to map IO memory\n");
-		return -ENOMEM;
+		return PTR_ERR(base);
 	}
 
 	config.dev = &pdev->dev;
diff --git a/kernel/drivers/remoteproc/mtk_scp_ipi.c b/kernel/drivers/remoteproc/mtk_scp_ipi.c
index 6dc955e..968128b 100644
--- a/kernel/drivers/remoteproc/mtk_scp_ipi.c
+++ b/kernel/drivers/remoteproc/mtk_scp_ipi.c
@@ -164,13 +164,13 @@
 	    WARN_ON(len > sizeof(send_obj->share_buf)) || WARN_ON(!buf))
 		return -EINVAL;
 
-	mutex_lock(&scp->send_lock);
-
 	ret = clk_prepare_enable(scp->clk);
 	if (ret) {
 		dev_err(scp->dev, "failed to enable clock\n");
-		goto unlock_mutex;
+		return ret;
 	}
+
+	mutex_lock(&scp->send_lock);
 
 	 /* Wait until SCP receives the last command */
 	timeout = jiffies + msecs_to_jiffies(2000);
@@ -178,7 +178,7 @@
 		if (time_after(jiffies, timeout)) {
 			dev_err(scp->dev, "%s: IPI timeout!\n", __func__);
 			ret = -ETIMEDOUT;
-			goto clock_disable;
+			goto unlock_mutex;
 		}
 	} while (readl(scp->reg_base + scp->data->host_to_scp_reg));
 
@@ -205,10 +205,9 @@
 			ret = 0;
 	}
 
-clock_disable:
-	clk_disable_unprepare(scp->clk);
 unlock_mutex:
 	mutex_unlock(&scp->send_lock);
+	clk_disable_unprepare(scp->clk);
 
 	return ret;
 }
diff --git a/kernel/drivers/remoteproc/qcom_q6v5_mss.c b/kernel/drivers/remoteproc/qcom_q6v5_mss.c
index 1b3aa84..3d975ec 100644
--- a/kernel/drivers/remoteproc/qcom_q6v5_mss.c
+++ b/kernel/drivers/remoteproc/qcom_q6v5_mss.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/of_reserved_mem.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
@@ -189,6 +190,9 @@
 	void *mba_region;
 	size_t mba_size;
 	size_t dp_size;
+
+	phys_addr_t mdata_phys;
+	size_t mdata_size;
 
 	phys_addr_t mpss_phys;
 	phys_addr_t mpss_reloc;
@@ -816,14 +820,34 @@
 	if (IS_ERR(metadata))
 		return PTR_ERR(metadata);
 
-	ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs);
-	if (!ptr) {
-		kfree(metadata);
-		dev_err(qproc->dev, "failed to allocate mdt buffer\n");
-		return -ENOMEM;
+	if (qproc->mdata_phys) {
+		if (size > qproc->mdata_size) {
+			ret = -EINVAL;
+			dev_err(qproc->dev, "metadata size outside memory range\n");
+			goto free_metadata;
+		}
+
+		phys = qproc->mdata_phys;
+		ptr = memremap(qproc->mdata_phys, size, MEMREMAP_WC);
+		if (!ptr) {
+			ret = -EBUSY;
+			dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
+				&qproc->mdata_phys, size);
+			goto free_metadata;
+		}
+	} else {
+		ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs);
+		if (!ptr) {
+			ret = -ENOMEM;
+			dev_err(qproc->dev, "failed to allocate mdt buffer\n");
+			goto free_metadata;
+		}
 	}
 
 	memcpy(ptr, metadata, size);
+
+	if (qproc->mdata_phys)
+		memunmap(ptr);
 
 	/* Hypervisor mapping to access metadata by modem */
 	mdata_perm = BIT(QCOM_SCM_VMID_HLOS);
@@ -853,7 +877,9 @@
 			 "mdt buffer not reclaimed system may become unstable\n");
 
 free_dma_attrs:
-	dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs);
+	if (!qproc->mdata_phys)
+		dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs);
+free_metadata:
 	kfree(metadata);
 
 	return ret < 0 ? ret : 0;
@@ -1585,6 +1611,7 @@
 static int q6v5_alloc_memory_region(struct q6v5 *qproc)
 {
 	struct device_node *child;
+	struct reserved_mem *rmem;
 	struct device_node *node;
 	struct resource r;
 	int ret;
@@ -1637,6 +1664,26 @@
 	qproc->mpss_phys = qproc->mpss_reloc = r.start;
 	qproc->mpss_size = resource_size(&r);
 
+	if (!child) {
+		node = of_parse_phandle(qproc->dev->of_node, "memory-region", 2);
+	} else {
+		child = of_get_child_by_name(qproc->dev->of_node, "metadata");
+		node = of_parse_phandle(child, "memory-region", 0);
+		of_node_put(child);
+	}
+
+	if (!node)
+		return 0;
+
+	rmem = of_reserved_mem_lookup(node);
+	if (!rmem) {
+		dev_err(qproc->dev, "unable to resolve metadata region\n");
+		return -EINVAL;
+	}
+
+	qproc->mdata_phys = rmem->base;
+	qproc->mdata_size = rmem->size;
+
 	return 0;
 }
 
diff --git a/kernel/drivers/remoteproc/qcom_q6v5_pas.c b/kernel/drivers/remoteproc/qcom_q6v5_pas.c
index 47fb1fa..b752f01 100644
--- a/kernel/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/kernel/drivers/remoteproc/qcom_q6v5_pas.c
@@ -365,6 +365,7 @@
 	}
 
 	ret = of_address_to_resource(node, 0, &r);
+	of_node_put(node);
 	if (ret)
 		return ret;
 
@@ -472,6 +473,7 @@
 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 +489,8 @@
 	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);
 
 	return 0;
diff --git a/kernel/drivers/remoteproc/qcom_sysmon.c b/kernel/drivers/remoteproc/qcom_sysmon.c
index a26221a..c348ea3 100644
--- a/kernel/drivers/remoteproc/qcom_sysmon.c
+++ b/kernel/drivers/remoteproc/qcom_sysmon.c
@@ -625,7 +625,9 @@
 		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 @@
 		if (ret) {
 			dev_err(sysmon->dev,
 				"failed to acquire shutdown-ack IRQ\n");
+			kfree(sysmon);
 			return ERR_PTR(ret);
 		}
 	}
diff --git a/kernel/drivers/remoteproc/remoteproc_core.c b/kernel/drivers/remoteproc/remoteproc_core.c
index 45cc99d..2c01a01 100644
--- a/kernel/drivers/remoteproc/remoteproc_core.c
+++ b/kernel/drivers/remoteproc/remoteproc_core.c
@@ -1751,10 +1751,16 @@
 
 	mutex_lock(&rproc->lock);
 
-	if (rproc->state == RPROC_CRASHED || rproc->state == RPROC_OFFLINE) {
+	if (rproc->state == RPROC_CRASHED) {
 		/* handle only the first crash detected */
 		mutex_unlock(&rproc->lock);
 		return;
+	}
+
+	if (rproc->state == RPROC_OFFLINE) {
+		/* Don't recover if the remote processor was stopped */
+		mutex_unlock(&rproc->lock);
+		goto out;
 	}
 
 	rproc->state = RPROC_CRASHED;
@@ -1766,6 +1772,7 @@
 	if (!rproc->recovery_disabled)
 		rproc_trigger_recovery(rproc);
 
+out:
 	pm_relax(rproc->dev.parent);
 }
 
diff --git a/kernel/drivers/remoteproc/st_remoteproc.c b/kernel/drivers/remoteproc/st_remoteproc.c
index a3268d9..e6bd3c7 100644
--- a/kernel/drivers/remoteproc/st_remoteproc.c
+++ b/kernel/drivers/remoteproc/st_remoteproc.c
@@ -129,6 +129,7 @@
 	while (of_phandle_iterator_next(&it) == 0) {
 		rmem = of_reserved_mem_lookup(it.node);
 		if (!rmem) {
+			of_node_put(it.node);
 			dev_err(dev, "unable to acquire memory-region\n");
 			return -EINVAL;
 		}
@@ -150,8 +151,10 @@
 							   it.node->name);
 		}
 
-		if (!mem)
+		if (!mem) {
+			of_node_put(it.node);
 			return -ENOMEM;
+		}
 
 		rproc_add_carveout(rproc, mem);
 		index++;
diff --git a/kernel/drivers/remoteproc/stm32_rproc.c b/kernel/drivers/remoteproc/stm32_rproc.c
index d2414cc..df784fe 100644
--- a/kernel/drivers/remoteproc/stm32_rproc.c
+++ b/kernel/drivers/remoteproc/stm32_rproc.c
@@ -231,11 +231,13 @@
 	while (of_phandle_iterator_next(&it) == 0) {
 		rmem = of_reserved_mem_lookup(it.node);
 		if (!rmem) {
+			of_node_put(it.node);
 			dev_err(dev, "unable to acquire memory-region\n");
 			return -EINVAL;
 		}
 
 		if (stm32_rproc_pa_to_da(rproc, rmem->base, &da) < 0) {
+			of_node_put(it.node);
 			dev_err(dev, "memory region not valid %pa\n",
 				&rmem->base);
 			return -EINVAL;
@@ -262,8 +264,10 @@
 							   it.node->name);
 		}
 
-		if (!mem)
+		if (!mem) {
+			of_node_put(it.node);
 			return -ENOMEM;
+		}
 
 		rproc_add_carveout(rproc, mem);
 		index++;
@@ -297,8 +301,16 @@
 	struct stm32_mbox *mb = container_of(work, struct stm32_mbox, vq_work);
 	struct rproc *rproc = dev_get_drvdata(mb->client.dev);
 
+	mutex_lock(&rproc->lock);
+
+	if (rproc->state != RPROC_RUNNING)
+		goto unlock_mutex;
+
 	if (rproc_vq_interrupt(rproc, mb->vq_id) == IRQ_NONE)
 		dev_dbg(&rproc->dev, "no message found in vq%d\n", mb->vq_id);
+
+unlock_mutex:
+	mutex_unlock(&rproc->lock);
 }
 
 static void stm32_rproc_mb_callback(struct mbox_client *cl, void *data)
diff --git a/kernel/drivers/rkflash/Kconfig b/kernel/drivers/rkflash/Kconfig
index 5c2f429..67527b2 100644
--- a/kernel/drivers/rkflash/Kconfig
+++ b/kernel/drivers/rkflash/Kconfig
@@ -22,7 +22,7 @@
 config RK_SFTL
 	tristate "Rockchip Slc Nand FTL support"
 	default y
-	depends on (RK_NAND || (RK_SFC_NAND && RK_SFC_NAND_MTD !=y))
+	depends on (RK_NANDC_NAND || (RK_SFC_NAND && RK_SFC_NAND_MTD !=y))
 	help
 	  This enables support for Slc Nand FTL.
 
diff --git a/kernel/drivers/rkflash/sfc_nand_mtd_bbt.c b/kernel/drivers/rkflash/sfc_nand_mtd_bbt.c
index eb641f8..0fce0b9 100644
--- a/kernel/drivers/rkflash/sfc_nand_mtd_bbt.c
+++ b/kernel/drivers/rkflash/sfc_nand_mtd_bbt.c
@@ -21,12 +21,118 @@
 #define BBT_DBG(args...)
 #endif
 
+#define BBT_VERSION_INVALID		(0xFFFFFFFFU)
+#define BBT_VERSION_BLOCK_ABNORMAL	(BBT_VERSION_INVALID - 1)
+#define BBT_VERSION_MAX			(BBT_VERSION_INVALID - 8)
 struct nanddev_bbt_info {
 	u8 pattern[4];
 	unsigned int version;
+	u32 hash;
 };
 
 static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
+
+#if defined(BBT_DEBUG) && defined(BBT_DEBUG_DUMP)
+static void bbt_dbg_hex(char *s, void *buf, u32 len)
+{
+	print_hex_dump(KERN_WARNING, s, DUMP_PREFIX_OFFSET, 4, 4, buf, len, 0);
+}
+#endif
+
+static u32 js_hash(u8 *buf, u32 len)
+{
+	u32 hash = 0x47C6A7E6;
+	u32 i;
+
+	for (i = 0; i < len; i++)
+		hash ^= ((hash << 5) + buf[i] + (hash >> 2));
+
+	return hash;
+}
+
+static bool bbt_check_hash(u8 *buf, u32 len, u32 hash_cmp)
+{
+	u32 hash;
+
+	/* compatible with no-hash version */
+	if (hash_cmp == 0 || hash_cmp == 0xFFFFFFFF)
+		return 1;
+
+	hash = js_hash(buf, len);
+	if (hash != hash_cmp)
+		return 0;
+
+	return 1;
+}
+
+static u32 bbt_nand_isbad_bypass(struct snand_mtd_dev *nand, u32 block)
+{
+	struct mtd_info *mtd = snanddev_to_mtd(nand);
+
+	return sfc_nand_isbad_mtd(mtd, block * mtd->erasesize);
+}
+
+static int bbt_mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
+{
+	int i, ret = 0, bbt_page_num, page_addr, block;
+	u8 *temp_buf;
+
+	bbt_page_num = ops->len >> mtd->writesize_shift;
+	block = from >> mtd->erasesize_shift;
+
+	temp_buf = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
+	if (!temp_buf)
+		return -ENOMEM;
+
+	page_addr = (u32)(block << (mtd->erasesize_shift - mtd->writesize_shift));
+	for (i = 0; i < bbt_page_num; i++) {
+		ret = sfc_nand_read_page_raw(0, page_addr + i, (u32 *)temp_buf);
+		if (ret < 0) {
+			pr_err("%s fail %d\n", __func__, ret);
+			ret = -EIO;
+			goto out;
+		}
+
+		memcpy(ops->datbuf + i * mtd->writesize, temp_buf, mtd->writesize);
+		memcpy(ops->oobbuf + i * mtd->oobsize, temp_buf + mtd->writesize, mtd->oobsize);
+	}
+
+out:
+	kfree(temp_buf);
+
+	return ret;
+}
+
+static int bbt_mtd_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
+{
+	int i, ret = 0, bbt_page_num, page_addr, block;
+	u8 *temp_buf;
+
+	bbt_page_num = ops->len >> mtd->writesize_shift;
+	block = to >> mtd->erasesize_shift;
+
+	temp_buf = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
+	if (!temp_buf)
+		return -ENOMEM;
+
+	page_addr = (u32)(block << (mtd->erasesize_shift - mtd->writesize_shift));
+	for (i = 0; i < bbt_page_num; i++) {
+		memcpy(temp_buf, ops->datbuf + i * mtd->writesize, mtd->writesize);
+		memcpy(temp_buf + mtd->writesize, ops->oobbuf + i * mtd->oobsize, mtd->oobsize);
+
+		ret = sfc_nand_prog_page_raw(0, page_addr + i, (u32 *)temp_buf);
+		if (ret < 0) {
+			pr_err("%s fail %d\n", __func__, ret);
+			ret = -EIO;
+			goto out;
+		}
+	}
+
+out:
+	kfree(temp_buf);
+
+	return ret;
+}
 
 /**
  * nanddev_read_bbt() - Read the BBT (Bad Block Table)
@@ -37,7 +143,7 @@
  *
  * Initialize the in-memory BBT.
  *
- * Return: 0 in case of success, a negative error code otherwise.
+ * Return: positive value means success, 0 means abnornal data, a negative error code otherwise.
  */
 static int nanddev_read_bbt(struct snand_mtd_dev *nand, u32 block, bool update)
 {
@@ -46,13 +152,12 @@
 	unsigned int nbytes = DIV_ROUND_UP(nblocks * bits_per_block,
 					   BITS_PER_LONG) * sizeof(*nand->bbt.cache);
 	struct mtd_info *mtd = snanddev_to_mtd(nand);
-	u8 *data_buf, *oob_buf, *temp_buf;
+	u8 *data_buf, *oob_buf;
 	struct nanddev_bbt_info *bbt_info;
 	struct mtd_oob_ops ops;
 	u32 bbt_page_num;
 	int ret = 0;
 	unsigned int version = 0;
-	u32 page_addr, i;
 
 	if (!nand->bbt.cache)
 		return -ENOMEM;
@@ -85,36 +190,64 @@
 	ops.ooboffs = 0;
 
 	/* Store one entry for each block */
-	temp_buf = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
-	if (!temp_buf) {
-		kfree(data_buf);
-		kfree(oob_buf);
-
-		return -ENOMEM;
+	ret = bbt_mtd_read_oob(mtd, block * mtd->erasesize, &ops);
+	if (ret && ret != -EUCLEAN) {
+		pr_err("read_bbt blk=%d fail=%d update=%d\n", block, ret, update);
+		ret = 0;
+		version = BBT_VERSION_BLOCK_ABNORMAL;
+		goto out;
+	} else {
+		ret = 0;
 	}
-	page_addr = (u32)(block << (mtd->erasesize_shift - mtd->writesize_shift));
-	for (i = 0; i < bbt_page_num; i++) {
-		ret = sfc_nand_read_page_raw(0, page_addr + i, (u32 *)temp_buf);
-		if (ret < 0) {
-			pr_err("%s fail %d\n", __func__, ret);
-			ret = -EIO;
-			kfree(temp_buf);
-			goto out;
-		}
-
-		memcpy(ops.datbuf + i * mtd->writesize, temp_buf, mtd->writesize);
-		memcpy(ops.oobbuf + i * mtd->oobsize, temp_buf + mtd->writesize, mtd->oobsize);
+	/* bad block or good block without bbt */
+	if (memcmp(bbt_pattern, bbt_info->pattern, 4)) {
+		ret = 0;
+		goto out;
 	}
-	kfree(temp_buf);
 
-	if (oob_buf[0] != 0xff && !memcmp(bbt_pattern, bbt_info->pattern, 4))
-		version = bbt_info->version;
+	/* good block with abnornal bbt */
+	if (oob_buf[0] == 0xff ||
+	    !bbt_check_hash(data_buf, nbytes + sizeof(struct nanddev_bbt_info) - 4, bbt_info->hash)) {
+		pr_err("read_bbt check fail blk=%d ret=%d update=%d\n", block, ret, update);
+		ret = 0;
+		version = BBT_VERSION_BLOCK_ABNORMAL;
+		goto out;
+	}
 
-	BBT_DBG("read_bbt from blk=%d tag=%d ver=%d\n", block, update, version);
+	/* good block with good bbt */
+	version = bbt_info->version;
+	BBT_DBG("read_bbt from blk=%d ver=%d update=%d\n", block, version, update);
 	if (update && version > nand->bbt.version) {
 		memcpy(nand->bbt.cache, data_buf, nbytes);
 		nand->bbt.version = version;
 	}
+
+#if defined(BBT_DEBUG) && defined(BBT_DEBUG_DUMP)
+	bbt_dbg_hex("bbt", data_buf, nbytes + sizeof(struct nanddev_bbt_info));
+	if (version) {
+		u8 *temp_buf = kzalloc(bbt_page_num * mtd->writesize, GFP_KERNEL);
+		bool in_scan = nand->bbt.option & NANDDEV_BBT_SCANNED;
+
+		if (!temp_buf)
+			goto out;
+
+		memcpy(temp_buf, nand->bbt.cache, nbytes);
+		memcpy(nand->bbt.cache, data_buf, nbytes);
+
+		if (!in_scan)
+			nand->bbt.option |= NANDDEV_BBT_SCANNED;
+		for (block = 0; block < nblocks; block++) {
+			ret = snanddev_bbt_get_block_status(nand, block);
+			if (ret != NAND_BBT_BLOCK_GOOD)
+				BBT_DBG("bad block[0x%x], ret=%d\n", block, ret);
+		}
+		if (!in_scan)
+			nand->bbt.option &= ~NANDDEV_BBT_SCANNED;
+		memcpy(nand->bbt.cache, temp_buf, nbytes);
+		kfree(temp_buf);
+		ret = 0;
+	}
+#endif
 
 out:
 	kfree(data_buf);
@@ -130,12 +263,11 @@
 	unsigned int nbytes = DIV_ROUND_UP(nblocks * bits_per_block,
 					   BITS_PER_LONG) * sizeof(*nand->bbt.cache);
 	struct mtd_info *mtd = snanddev_to_mtd(nand);
-	u8 *data_buf, *oob_buf, *temp_buf;
+	u8 *data_buf, *oob_buf;
 	struct nanddev_bbt_info *bbt_info;
 	struct mtd_oob_ops ops;
 	u32 bbt_page_num;
-	int ret = 0;
-	u32 page_addr, i;
+	int ret = 0, version;
 
 	BBT_DBG("write_bbt to blk=%d ver=%d\n", block, nand->bbt.version);
 	if (!nand->bbt.cache)
@@ -164,6 +296,7 @@
 	memcpy(data_buf, nand->bbt.cache, nbytes);
 	memcpy(bbt_info, bbt_pattern, 4);
 	bbt_info->version = nand->bbt.version;
+	bbt_info->hash = js_hash(data_buf, nbytes + sizeof(struct nanddev_bbt_info) - 4);
 
 	/* Store one entry for each block */
 	ret = sfc_nand_erase_mtd(mtd, block * mtd->erasesize);
@@ -171,34 +304,27 @@
 		goto out;
 
 	memset(&ops, 0, sizeof(struct mtd_oob_ops));
+	ops.mode = MTD_OPS_PLACE_OOB;
 	ops.datbuf = data_buf;
 	ops.len = bbt_page_num * mtd->writesize;
 	ops.oobbuf = oob_buf;
 	ops.ooblen = bbt_page_num * mtd->oobsize;
 	ops.ooboffs = 0;
-
-	temp_buf = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
-	if (!temp_buf) {
-		kfree(data_buf);
-		kfree(oob_buf);
-
-		return -ENOMEM;
+	ret = bbt_mtd_write_oob(mtd, block * mtd->erasesize, &ops);
+	if (ret) {
+		sfc_nand_erase_mtd(mtd, block * mtd->erasesize);
+		goto out;
 	}
-	page_addr = (u32)(block << (mtd->erasesize_shift - mtd->writesize_shift));
-	for (i = 0; i < bbt_page_num; i++) {
-		memcpy(temp_buf, ops.datbuf + i * mtd->writesize, mtd->writesize);
-		memcpy(temp_buf + mtd->writesize, ops.oobbuf + i * mtd->oobsize, mtd->oobsize);
 
-		ret = sfc_nand_prog_page_raw(0, page_addr + i, (u32 *)temp_buf);
-		if (ret < 0) {
-			pr_err("%s fail %d\n", __func__, ret);
-			ret = -EIO;
-			kfree(temp_buf);
-			goto out;
-		}
+	version = nanddev_read_bbt(nand, block, false);
+	if (version != bbt_info->version) {
+		pr_err("bbt_write fail, blk=%d recheck fail %d-%d\n",
+		       block, version, bbt_info->version);
+		sfc_nand_erase_mtd(mtd, block * mtd->erasesize);
+		ret = -EIO;
+	} else {
+		ret = 0;
 	}
-	kfree(temp_buf);
-
 out:
 	kfree(data_buf);
 	kfree(oob_buf);
@@ -211,13 +337,29 @@
 	unsigned int nblocks = snanddev_neraseblocks(nand);
 	struct mtd_info *mtd = snanddev_to_mtd(nand);
 	u32 start_block, block;
+	unsigned int bits_per_block = fls(NAND_BBT_BLOCK_NUM_STATUS);
+	unsigned int nwords = DIV_ROUND_UP(nblocks * bits_per_block,
+					   BITS_PER_LONG);
 
 	start_block = nblocks - NANDDEV_BBT_SCAN_MAXBLOCKS;
 
 	for (block = 0; block < nblocks; block++) {
-		if (sfc_nand_isbad_mtd(mtd, block * mtd->erasesize))
+		if (sfc_nand_isbad_mtd(mtd, block * mtd->erasesize)) {
+			if (bbt_nand_isbad_bypass(nand, 0)) {
+				memset(nand->bbt.cache, 0, nwords * sizeof(*nand->bbt.cache));
+				pr_err("bbt_format fail, test good block %d fail\n", 0);
+				return -EIO;
+			}
+
+			if (!bbt_nand_isbad_bypass(nand, block)) {
+				memset(nand->bbt.cache, 0, nwords * sizeof(*nand->bbt.cache));
+				pr_err("bbt_format fail, test bad block %d fail\n", block);
+				return -EIO;
+			}
+
 			snanddev_bbt_set_block_status(nand, block,
-						      NAND_BBT_BLOCK_FACTORY_BAD);
+						     NAND_BBT_BLOCK_FACTORY_BAD);
+		}
 	}
 
 	for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
@@ -243,13 +385,33 @@
 
 	nand->bbt.option |= NANDDEV_BBT_SCANNED;
 	if (nand->bbt.version == 0) {
-		nanddev_bbt_format(nand);
+		ret = nanddev_bbt_format(nand);
+		if (ret) {
+			nand->bbt.option = 0;
+			pr_err("%s format fail\n", __func__);
+
+			return ret;
+		}
+
 		ret = snanddev_bbt_update(nand);
 		if (ret) {
 			nand->bbt.option = 0;
-			pr_err("%s fail\n", __func__);
+			pr_err("%s update fail\n", __func__);
+
+			return ret;
 		}
 	}
+
+#if defined(BBT_DEBUG)
+	pr_err("scan_bbt success\n");
+	if (nand->bbt.version) {
+		for (block = 0; block < nblocks; block++) {
+			ret = snanddev_bbt_get_block_status(nand, block);
+			if (ret != NAND_BBT_BLOCK_GOOD)
+				BBT_DBG("bad block[0x%x], ret=%d\n", block, ret);
+		}
+	}
+#endif
 
 	return ret;
 }
@@ -304,32 +466,32 @@
 int snanddev_bbt_update(struct snand_mtd_dev *nand)
 {
 #ifdef CONFIG_MTD_NAND_BBT_USING_FLASH
+	struct mtd_info *mtd = snanddev_to_mtd(nand);
+
 	if (nand->bbt.cache &&
 	    nand->bbt.option & NANDDEV_BBT_USE_FLASH) {
 		unsigned int nblocks = snanddev_neraseblocks(nand);
 		u32 bbt_version[NANDDEV_BBT_SCAN_MAXBLOCKS];
 		int start_block, block;
 		u32 min_version, block_des;
-		int ret, count = 0;
+		int ret, count = 0, status;
 
 		start_block = nblocks - NANDDEV_BBT_SCAN_MAXBLOCKS;
 		for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
-			ret = snanddev_bbt_get_block_status(nand, start_block + block);
-			if (ret == NAND_BBT_BLOCK_FACTORY_BAD) {
-				bbt_version[block] = 0xFFFFFFFF;
-				continue;
-			}
-			ret = nanddev_read_bbt(nand, start_block + block,
-					       false);
-			if (ret < 0)
-				bbt_version[block] = 0xFFFFFFFF;
-			else if (ret == 0)
-				bbt_version[block] = 0;
+			status = snanddev_bbt_get_block_status(nand, start_block + block);
+			ret = nanddev_read_bbt(nand, start_block + block, false);
+
+			if (ret == 0 && status == NAND_BBT_BLOCK_FACTORY_BAD)
+				bbt_version[block] = BBT_VERSION_INVALID;
+			else if (ret == -EIO)
+				bbt_version[block] = BBT_VERSION_INVALID;
+			else if (ret == BBT_VERSION_BLOCK_ABNORMAL)
+				bbt_version[block] = ret;
 			else
 				bbt_version[block] = ret;
 		}
 get_min_ver:
-		min_version = 0xFFFFFFFF;
+		min_version = BBT_VERSION_MAX;
 		block_des = 0;
 		for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
 			if (bbt_version[block] < min_version) {
@@ -338,25 +500,37 @@
 			}
 		}
 
+		/* Overwrite the BBT_VERSION_BLOCK_ABNORMAL block */
+		if (nand->bbt.version < min_version)
+			nand->bbt.version = min_version + 4;
+
 		if (block_des > 0) {
 			nand->bbt.version++;
 			ret = nanddev_write_bbt(nand, block_des);
-			bbt_version[block_des - start_block] = 0xFFFFFFFF;
 			if (ret) {
-				pr_err("%s blk= %d ret= %d\n", __func__,
-				       block_des, ret);
-				goto get_min_ver;
-			} else {
-				count++;
-				if (count < 2)
-					goto get_min_ver;
-				BBT_DBG("%s success\n", __func__);
-			}
-		} else {
-			pr_err("%s failed\n", __func__);
+				pr_err("bbt_update fail, blk=%d ret= %d\n", block_des, ret);
 
-			return -1;
+				return -1;
+			}
+
+			bbt_version[block_des - start_block] = BBT_VERSION_INVALID;
+			count++;
+			if (count < 2)
+				goto get_min_ver;
+			BBT_DBG("bbt_update success\n");
+		} else {
+			pr_err("bbt_update failed\n");
+			ret = -1;
 		}
+
+		for (block = 0; block < NANDDEV_BBT_SCAN_MAXBLOCKS; block++) {
+			if (bbt_version[block] == BBT_VERSION_BLOCK_ABNORMAL) {
+				block_des = start_block + block;
+				sfc_nand_erase_mtd(mtd, block_des * mtd->erasesize);
+			}
+		}
+
+		return ret;
 	}
 #endif
 	return 0;
diff --git a/kernel/drivers/rknpu/Makefile b/kernel/drivers/rknpu/Makefile
index a8d265d..d73563d 100644
--- a/kernel/drivers/rknpu/Makefile
+++ b/kernel/drivers/rknpu/Makefile
@@ -10,6 +10,7 @@
 rknpu-y += rknpu_job.o
 rknpu-y += rknpu_debugger.o
 rknpu-y += rknpu_iommu.o
+rknpu-$(CONFIG_PM_DEVFREQ) += rknpu_devfreq.o
 rknpu-$(CONFIG_ROCKCHIP_RKNPU_SRAM) += rknpu_mm.o
 rknpu-$(CONFIG_ROCKCHIP_RKNPU_FENCE) += rknpu_fence.o
 rknpu-$(CONFIG_ROCKCHIP_RKNPU_DRM_GEM) += rknpu_gem.o
diff --git a/kernel/drivers/rknpu/include/rknpu_devfreq.h b/kernel/drivers/rknpu/include/rknpu_devfreq.h
new file mode 100644
index 0000000..3edeb1f
--- /dev/null
+++ b/kernel/drivers/rknpu/include/rknpu_devfreq.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) Rockchip Electronics Co.Ltd
+ * Author: Finley Xiao <finley.xiao@rock-chips.com>
+ */
+
+#ifndef __LINUX_RKNPU_DEVFREQ_H
+#define __LINUX_RKNPU_DEVFREQ_H
+
+#ifdef CONFIG_PM_DEVFREQ
+void rknpu_devfreq_lock(struct rknpu_device *rknpu_dev);
+void rknpu_devfreq_unlock(struct rknpu_device *rknpu_dev);
+int rknpu_devfreq_init(struct rknpu_device *rknpu_dev);
+void rknpu_devfreq_remove(struct rknpu_device *rknpu_dev);
+int rknpu_devfreq_runtime_suspend(struct device *dev);
+int rknpu_devfreq_runtime_resume(struct device *dev);
+#else
+static inline int rknpu_devfreq_init(struct rknpu_device *rknpu_dev)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline void rknpu_devfreq_remove(struct rknpu_device *rknpu_dev)
+{
+}
+
+static inline void rknpu_devfreq_lock(struct rknpu_device *rknpu_dev)
+{
+}
+
+static inline void rknpu_devfreq_unlock(struct rknpu_device *rknpu_dev)
+{
+}
+
+static inline int rknpu_devfreq_runtime_suspend(struct device *dev)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int rknpu_devfreq_runtime_resume(struct device *dev)
+{
+	return -EOPNOTSUPP;
+}
+#endif /* CONFIG_PM_DEVFREQ */
+
+#endif /* __LINUX_RKNPU_DEVFREQ_H_ */
diff --git a/kernel/drivers/rknpu/include/rknpu_drv.h b/kernel/drivers/rknpu/include/rknpu_drv.h
index 2f7de54..98fba97 100644
--- a/kernel/drivers/rknpu/include/rknpu_drv.h
+++ b/kernel/drivers/rknpu/include/rknpu_drv.h
@@ -17,11 +17,9 @@
 #include <linux/hrtimer.h>
 #include <linux/miscdevice.h>
 
-#ifndef FPGA_PLATFORM
-#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE
 #include <soc/rockchip/rockchip_opp_select.h>
-#endif
-#endif
+#include <soc/rockchip/rockchip_system_monitor.h>
+#include <soc/rockchip/rockchip_ipa.h>
 
 #include "rknpu_job.h"
 #include "rknpu_fence.h"
@@ -30,10 +28,10 @@
 
 #define DRIVER_NAME "rknpu"
 #define DRIVER_DESC "RKNPU driver"
-#define DRIVER_DATE "20230825"
+#define DRIVER_DATE "20231121"
 #define DRIVER_MAJOR 0
 #define DRIVER_MINOR 9
-#define DRIVER_PATCHLEVEL 2
+#define DRIVER_PATCHLEVEL 3
 
 #define LOG_TAG "RKNPU"
 
@@ -76,11 +74,12 @@
 	__u64 nbuf_phyaddr;
 	__u64 nbuf_size;
 	__u64 max_submit_number;
+	__u32 core_mask;
 };
 
 struct rknpu_timer {
-	__u32 busy_time;
-	__u32 busy_time_record;
+	ktime_t busy_time;
+	ktime_t total_busy_time;
 };
 
 struct rknpu_subcore_data {
@@ -130,11 +129,7 @@
 	struct thermal_cooling_device *devfreq_cooling;
 	struct devfreq *devfreq;
 	unsigned long ondemand_freq;
-#ifndef FPGA_PLATFORM
-#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE
 	struct rockchip_opp_info opp_info;
-#endif
-#endif
 	unsigned long current_freq;
 	unsigned long current_volt;
 	int bypass_irq_handler;
diff --git a/kernel/drivers/rknpu/include/rknpu_ioctl.h b/kernel/drivers/rknpu/include/rknpu_ioctl.h
index 3b0b857..35b4670 100644
--- a/kernel/drivers/rknpu/include/rknpu_ioctl.h
+++ b/kernel/drivers/rknpu/include/rknpu_ioctl.h
@@ -251,7 +251,7 @@
  * @task_obj_addr: address of task object
  * @regcfg_obj_addr: address of register config object
  * @task_base_addr: task base address
- * @user_data: (optional) user data
+ * @hw_elapse_time: hardware elapse time
  * @core_mask: core mask of rknpu
  * @fence_fd: dma fence fd
  * @subcore_task: subcore task
@@ -267,7 +267,7 @@
 	__u64 task_obj_addr;
 	__u64 regcfg_obj_addr;
 	__u64 task_base_addr;
-	__u64 user_data;
+	__s64 hw_elapse_time;
 	__u32 core_mask;
 	__s32 fence_fd;
 	struct rknpu_subcore_task subcore_task[5];
diff --git a/kernel/drivers/rknpu/include/rknpu_job.h b/kernel/drivers/rknpu/include/rknpu_job.h
index c62b1bf..cd0d1df 100644
--- a/kernel/drivers/rknpu/include/rknpu_job.h
+++ b/kernel/drivers/rknpu/include/rknpu_job.h
@@ -44,8 +44,9 @@
 	uint32_t use_core_num;
 	atomic_t run_count;
 	atomic_t interrupt_count;
+	ktime_t hw_commit_time;
 	ktime_t hw_recoder_time;
-	ktime_t commit_pc_time;
+	ktime_t hw_elapse_time;
 	atomic_t submit_count[RKNPU_MAX_CORES];
 };
 
diff --git a/kernel/drivers/rknpu/rknpu_debugger.c b/kernel/drivers/rknpu/rknpu_debugger.c
index 97c8752..0cfec7f 100644
--- a/kernel/drivers/rknpu/rknpu_debugger.c
+++ b/kernel/drivers/rknpu/rknpu_debugger.c
@@ -46,7 +46,7 @@
 	unsigned long flags;
 	int i;
 	int load;
-	uint64_t busy_time_total, div_value;
+	uint64_t total_busy_time, div_value;
 
 	seq_puts(m, "NPU load: ");
 	for (i = 0; i < rknpu_dev->config->num_irqs; i++) {
@@ -57,13 +57,13 @@
 
 		spin_lock_irqsave(&rknpu_dev->irq_lock, flags);
 
-		busy_time_total = subcore_data->timer.busy_time_record;
+		total_busy_time = subcore_data->timer.total_busy_time;
 
 		spin_unlock_irqrestore(&rknpu_dev->irq_lock, flags);
 
-		div_value = (RKNPU_LOAD_INTERVAL / 100000);
-		do_div(busy_time_total, div_value);
-		load = busy_time_total > 100 ? 100 : busy_time_total;
+		div_value = (RKNPU_LOAD_INTERVAL / 100);
+		do_div(total_busy_time, div_value);
+		load = total_busy_time > 100 ? 100 : total_busy_time;
 
 		if (rknpu_dev->config->num_irqs > 1)
 			seq_printf(m, "%2.d%%,", load);
diff --git a/kernel/drivers/rknpu/rknpu_devfreq.c b/kernel/drivers/rknpu/rknpu_devfreq.c
new file mode 100644
index 0000000..a2a83a9
--- /dev/null
+++ b/kernel/drivers/rknpu/rknpu_devfreq.c
@@ -0,0 +1,765 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) Rockchip Electronics Co.Ltd
+ * Author: Finley Xiao <finley.xiao@rock-chips.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/devfreq_cooling.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <../drivers/devfreq/governor.h>
+#include "rknpu_drv.h"
+#include "rknpu_devfreq.h"
+
+#define POWER_DOWN_FREQ 200000000
+
+static int npu_devfreq_target(struct device *dev, unsigned long *freq,
+			      u32 flags);
+
+static struct monitor_dev_profile npu_mdevp = {
+	.type = MONITOR_TYPE_DEV,
+	.low_temp_adjust = rockchip_monitor_dev_low_temp_adjust,
+	.high_temp_adjust = rockchip_monitor_dev_high_temp_adjust,
+#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE
+	.check_rate_volt = rockchip_monitor_check_rate_volt,
+#else
+	.update_volt = rockchip_monitor_check_rate_volt,
+#endif
+};
+
+static int npu_devfreq_get_dev_status(struct device *dev,
+				      struct devfreq_dev_status *stat)
+{
+	return 0;
+}
+
+static int npu_devfreq_get_cur_freq(struct device *dev, unsigned long *freq)
+{
+	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
+
+	*freq = rknpu_dev->current_freq;
+
+	return 0;
+}
+
+static struct devfreq_dev_profile npu_devfreq_profile = {
+	.polling_ms = 50,
+	.target = npu_devfreq_target,
+	.get_dev_status = npu_devfreq_get_dev_status,
+	.get_cur_freq = npu_devfreq_get_cur_freq,
+};
+
+static int devfreq_rknpu_ondemand_func(struct devfreq *df, unsigned long *freq)
+{
+	struct rknpu_device *rknpu_dev = df->data;
+
+	if (rknpu_dev && rknpu_dev->ondemand_freq)
+		*freq = rknpu_dev->ondemand_freq;
+	else
+		*freq = df->previous_freq;
+
+	return 0;
+}
+
+static int devfreq_rknpu_ondemand_handler(struct devfreq *devfreq,
+					  unsigned int event, void *data)
+{
+	return 0;
+}
+
+static struct devfreq_governor devfreq_rknpu_ondemand = {
+	.name = "rknpu_ondemand",
+	.get_target_freq = devfreq_rknpu_ondemand_func,
+	.event_handler = devfreq_rknpu_ondemand_handler,
+};
+
+static int rk3588_npu_get_soc_info(struct device *dev, struct device_node *np,
+				   int *bin, int *process)
+{
+	int ret = 0;
+	u8 value = 0;
+
+	if (!bin)
+		return 0;
+
+	if (of_property_match_string(np, "nvmem-cell-names",
+				     "specification_serial_number") >= 0) {
+		ret = rockchip_nvmem_cell_read_u8(
+			np, "specification_serial_number", &value);
+		if (ret) {
+			LOG_DEV_ERROR(
+				dev,
+				"Failed to get specification_serial_number\n");
+			return ret;
+		}
+		/* RK3588M */
+		if (value == 0xd)
+			*bin = 1;
+		/* RK3588J */
+		else if (value == 0xa)
+			*bin = 2;
+	}
+	if (*bin < 0)
+		*bin = 0;
+	LOG_DEV_INFO(dev, "bin=%d\n", *bin);
+
+	return ret;
+}
+
+#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE
+static int rk3588_npu_set_soc_info(struct device *dev, struct device_node *np,
+				   struct rockchip_opp_info *opp_info)
+{
+	int bin = opp_info->bin;
+
+	if (opp_info->volt_sel < 0)
+		return 0;
+	if (bin < 0)
+		bin = 0;
+
+	if (!of_property_read_bool(np, "rockchip,supported-hw"))
+		return 0;
+
+	/* SoC Version */
+	opp_info->supported_hw[0] = BIT(bin);
+	/* Speed Grade */
+	opp_info->supported_hw[1] = BIT(opp_info->volt_sel);
+
+	return 0;
+}
+#else
+static int rk3588_npu_set_soc_info(struct device *dev, struct device_node *np,
+				   int bin, int process, int volt_sel)
+{
+	struct opp_table *opp_table;
+	u32 supported_hw[2];
+
+	if (volt_sel < 0)
+		return 0;
+	if (bin < 0)
+		bin = 0;
+
+	if (!of_property_read_bool(np, "rockchip,supported-hw"))
+		return 0;
+
+	/* SoC Version */
+	supported_hw[0] = BIT(bin);
+	/* Speed Grade */
+	supported_hw[1] = BIT(volt_sel);
+	opp_table = dev_pm_opp_set_supported_hw(dev, supported_hw, 2);
+	if (IS_ERR(opp_table)) {
+		LOG_DEV_ERROR(dev, "failed to set supported opp\n");
+		return PTR_ERR(opp_table);
+	}
+
+	return 0;
+}
+#endif
+
+static int rk3588_npu_set_read_margin(struct device *dev,
+				      struct rockchip_opp_info *opp_info,
+				      u32 rm)
+{
+	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
+	u32 offset = 0, val = 0;
+	int i, ret = 0;
+
+	if (!opp_info->grf || !opp_info->volt_rm_tbl)
+		return 0;
+
+	if (rm == opp_info->current_rm || rm == UINT_MAX)
+		return 0;
+
+	LOG_DEV_DEBUG(dev, "set rm to %d\n", rm);
+
+	for (i = 0; i < rknpu_dev->config->num_irqs; i++) {
+		ret = regmap_read(opp_info->grf, offset, &val);
+		if (ret < 0) {
+			LOG_DEV_ERROR(dev, "failed to get rm from 0x%x\n",
+				      offset);
+			return ret;
+		}
+		val &= ~0x1c;
+		regmap_write(opp_info->grf, offset, val | (rm << 2));
+		offset += 4;
+	}
+	opp_info->current_rm = rm;
+
+	return 0;
+}
+
+#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE
+static int npu_opp_config_regulators(struct device *dev,
+				     struct dev_pm_opp *old_opp,
+				     struct dev_pm_opp *new_opp,
+				     struct regulator **regulators,
+				     unsigned int count)
+{
+	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
+
+	return rockchip_opp_config_regulators(dev, old_opp, new_opp, regulators,
+					      count, &rknpu_dev->opp_info);
+}
+
+static int npu_opp_config_clks(struct device *dev, struct opp_table *opp_table,
+			       struct dev_pm_opp *opp, void *data,
+			       bool scaling_down)
+{
+	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
+
+	return rockchip_opp_config_clks(dev, opp_table, opp, data, scaling_down,
+					&rknpu_dev->opp_info);
+}
+#endif
+
+static const struct rockchip_opp_data rk3588_npu_opp_data = {
+	.get_soc_info = rk3588_npu_get_soc_info,
+	.set_soc_info = rk3588_npu_set_soc_info,
+	.set_read_margin = rk3588_npu_set_read_margin,
+#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE
+	.config_regulators = npu_opp_config_regulators,
+	.config_clks = npu_opp_config_clks,
+#endif
+};
+
+static const struct of_device_id rockchip_npu_of_match[] = {
+	{
+		.compatible = "rockchip,rk3588",
+		.data = (void *)&rk3588_npu_opp_data,
+	},
+	{},
+};
+
+#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE
+void rknpu_devfreq_lock(struct rknpu_device *rknpu_dev)
+{
+	if (rknpu_dev->devfreq)
+		rockchip_opp_dvfs_lock(&rknpu_dev->opp_info);
+}
+EXPORT_SYMBOL(rknpu_devfreq_lock);
+
+void rknpu_devfreq_unlock(struct rknpu_device *rknpu_dev)
+{
+	if (rknpu_dev->devfreq)
+		rockchip_opp_dvfs_unlock(&rknpu_dev->opp_info);
+}
+EXPORT_SYMBOL(rknpu_devfreq_unlock);
+
+static int npu_devfreq_target(struct device *dev, unsigned long *freq,
+			      u32 flags)
+{
+	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
+	struct rockchip_opp_info *opp_info = &rknpu_dev->opp_info;
+	struct dev_pm_opp *opp;
+	unsigned long opp_volt;
+	int ret = 0;
+
+	if (!opp_info->is_rate_volt_checked)
+		return -EINVAL;
+
+	opp = devfreq_recommended_opp(dev, freq, flags);
+	if (IS_ERR(opp))
+		return PTR_ERR(opp);
+	opp_volt = dev_pm_opp_get_voltage(opp);
+	dev_pm_opp_put(opp);
+
+	if (*freq == rknpu_dev->current_freq)
+		return 0;
+
+	rockchip_opp_dvfs_lock(opp_info);
+	if (pm_runtime_active(dev))
+		opp_info->is_runtime_active = true;
+	else
+		opp_info->is_runtime_active = false;
+	ret = dev_pm_opp_set_rate(dev, *freq);
+	if (!ret) {
+		rknpu_dev->current_freq = *freq;
+		if (rknpu_dev->devfreq)
+			rknpu_dev->devfreq->last_status.current_frequency =
+				*freq;
+		rknpu_dev->current_volt = opp_volt;
+		LOG_DEV_DEBUG(dev, "set rknpu freq: %lu, volt: %lu\n",
+			      rknpu_dev->current_freq, rknpu_dev->current_volt);
+	}
+	rockchip_opp_dvfs_unlock(opp_info);
+
+	return ret;
+}
+
+static const struct rockchip_opp_data rockchip_npu_opp_data = {
+	.config_clks = npu_opp_config_clks,
+};
+
+int rknpu_devfreq_init(struct rknpu_device *rknpu_dev)
+{
+	struct rockchip_opp_info *info = &rknpu_dev->opp_info;
+	struct device *dev = rknpu_dev->dev;
+	struct devfreq_dev_profile *dp;
+	struct dev_pm_opp *opp;
+	unsigned int dyn_power_coeff = 0;
+	int ret = 0;
+
+	info->data = &rockchip_npu_opp_data;
+	rockchip_get_opp_data(rockchip_npu_of_match, info);
+	ret = rockchip_init_opp_table(dev, info, "clk_npu", "rknpu");
+	if (ret) {
+		LOG_DEV_ERROR(dev, "failed to init_opp_table\n");
+		return -EINVAL;
+	}
+
+	rknpu_dev->current_freq = clk_get_rate(rknpu_dev->clks[0].clk);
+	opp = devfreq_recommended_opp(dev, &rknpu_dev->current_freq, 0);
+	if (IS_ERR(opp)) {
+		ret = PTR_ERR(opp);
+		goto err_uinit_table;
+	}
+	dev_pm_opp_put(opp);
+
+	dp = &npu_devfreq_profile;
+	dp->initial_freq = rknpu_dev->current_freq;
+	of_property_read_u32(dev->of_node, "dynamic-power-coefficient",
+			     &dyn_power_coeff);
+	if (dyn_power_coeff)
+		dp->is_cooling_device = true;
+
+	ret = devfreq_add_governor(&devfreq_rknpu_ondemand);
+	if (ret) {
+		LOG_DEV_ERROR(dev, "failed to add rknpu_ondemand governor\n");
+		goto err_uinit_table;
+	}
+
+	rknpu_dev->devfreq = devm_devfreq_add_device(dev, dp, "rknpu_ondemand",
+						     (void *)rknpu_dev);
+	if (IS_ERR(rknpu_dev->devfreq)) {
+		LOG_DEV_ERROR(dev, "failed to add devfreq\n");
+		ret = PTR_ERR(rknpu_dev->devfreq);
+		rknpu_dev->devfreq = NULL;
+		goto err_remove_governor;
+	}
+
+	npu_mdevp.data = rknpu_dev->devfreq;
+	npu_mdevp.opp_info = &rknpu_dev->opp_info;
+	rknpu_dev->mdev_info =
+		rockchip_system_monitor_register(dev, &npu_mdevp);
+	if (IS_ERR(rknpu_dev->mdev_info)) {
+		dev_dbg(dev, "without system monitor\n");
+		rknpu_dev->mdev_info = NULL;
+	}
+
+	rknpu_dev->current_freq = clk_get_rate(rknpu_dev->clks[0].clk);
+	rknpu_dev->ondemand_freq = rknpu_dev->current_freq;
+	rknpu_dev->current_volt = regulator_get_voltage(rknpu_dev->vdd);
+
+	rknpu_dev->devfreq->previous_freq = rknpu_dev->current_freq;
+	if (rknpu_dev->devfreq->suspend_freq)
+		rknpu_dev->devfreq->resume_freq = rknpu_dev->current_freq;
+	rknpu_dev->devfreq->last_status.current_frequency =
+		rknpu_dev->current_freq;
+	rknpu_dev->devfreq->last_status.total_time = 1;
+	rknpu_dev->devfreq->last_status.busy_time = 1;
+
+	return 0;
+
+err_remove_governor:
+	devfreq_remove_governor(&devfreq_rknpu_ondemand);
+err_uinit_table:
+	rockchip_uninit_opp_table(dev, info);
+
+	return ret;
+}
+EXPORT_SYMBOL(rknpu_devfreq_init);
+
+int rknpu_devfreq_runtime_suspend(struct device *dev)
+{
+	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
+	struct rockchip_opp_info *opp_info = &rknpu_dev->opp_info;
+
+	if (opp_info->is_scmi_clk) {
+		if (clk_set_rate(opp_info->clk, POWER_DOWN_FREQ))
+			LOG_DEV_ERROR(dev, "failed to restore clk rate\n");
+	}
+	opp_info->current_rm = UINT_MAX;
+
+	return 0;
+}
+EXPORT_SYMBOL(rknpu_devfreq_runtime_suspend);
+
+int rknpu_devfreq_runtime_resume(struct device *dev)
+{
+	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
+	struct rockchip_opp_info *opp_info = &rknpu_dev->opp_info;
+	int ret = 0;
+
+	if (!rknpu_dev->current_freq || !rknpu_dev->current_volt)
+		return 0;
+
+	ret = clk_bulk_prepare_enable(opp_info->nclocks, opp_info->clocks);
+	if (ret) {
+		LOG_DEV_INFO(dev, "failed to enable opp clks\n");
+		return ret;
+	}
+
+	if (opp_info->data && opp_info->data->set_read_margin)
+		opp_info->data->set_read_margin(dev, opp_info,
+						opp_info->target_rm);
+	if (opp_info->is_scmi_clk) {
+		if (clk_set_rate(opp_info->clk, rknpu_dev->current_freq))
+			LOG_DEV_ERROR(dev, "failed to set power down rate\n");
+	}
+
+	clk_bulk_disable_unprepare(opp_info->nclocks, opp_info->clocks);
+
+	return ret;
+}
+EXPORT_SYMBOL(rknpu_devfreq_runtime_resume);
+#else
+void rknpu_devfreq_lock(struct rknpu_device *rknpu_dev)
+{
+	rockchip_monitor_volt_adjust_lock(rknpu_dev->mdev_info);
+}
+EXPORT_SYMBOL(rknpu_devfreq_lock);
+
+void rknpu_devfreq_unlock(struct rknpu_device *rknpu_dev)
+{
+	rockchip_monitor_volt_adjust_unlock(rknpu_dev->mdev_info);
+}
+EXPORT_SYMBOL(rknpu_devfreq_unlock);
+
+static int npu_opp_helper(struct dev_pm_set_opp_data *data)
+{
+	struct device *dev = data->dev;
+	struct dev_pm_opp_supply *old_supply_vdd = &data->old_opp.supplies[0];
+	struct dev_pm_opp_supply *old_supply_mem = &data->old_opp.supplies[1];
+	struct dev_pm_opp_supply *new_supply_vdd = &data->new_opp.supplies[0];
+	struct dev_pm_opp_supply *new_supply_mem = &data->new_opp.supplies[1];
+	struct regulator *vdd_reg = data->regulators[0];
+	struct regulator *mem_reg = data->regulators[1];
+	struct clk *clk = data->clk;
+	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
+	struct rockchip_opp_info *opp_info = &rknpu_dev->opp_info;
+	unsigned long old_freq = data->old_opp.rate;
+	unsigned long new_freq = data->new_opp.rate;
+	bool is_set_rm = true;
+	bool is_set_clk = true;
+	u32 target_rm = UINT_MAX;
+	int ret = 0;
+
+	if (!pm_runtime_active(dev)) {
+		is_set_rm = false;
+		if (opp_info->scmi_clk)
+			is_set_clk = false;
+	}
+
+	ret = clk_bulk_prepare_enable(opp_info->num_clks, opp_info->clks);
+	if (ret < 0) {
+		LOG_DEV_ERROR(dev, "failed to enable opp clks\n");
+		return ret;
+	}
+	rockchip_get_read_margin(dev, opp_info, new_supply_vdd->u_volt,
+				 &target_rm);
+
+	/* Change frequency */
+	LOG_DEV_DEBUG(dev, "switching OPP: %lu Hz --> %lu Hz\n", old_freq,
+		      new_freq);
+	/* Scaling up? Scale voltage before frequency */
+	if (new_freq >= old_freq) {
+		rockchip_set_intermediate_rate(dev, opp_info, clk, old_freq,
+					       new_freq, true, is_set_clk);
+		ret = regulator_set_voltage(mem_reg, new_supply_mem->u_volt,
+					    INT_MAX);
+		if (ret) {
+			LOG_DEV_ERROR(dev,
+				      "failed to set volt %lu uV for mem reg\n",
+				      new_supply_mem->u_volt);
+			goto restore_voltage;
+		}
+		ret = regulator_set_voltage(vdd_reg, new_supply_vdd->u_volt,
+					    INT_MAX);
+		if (ret) {
+			LOG_DEV_ERROR(dev,
+				      "failed to set volt %lu uV for vdd reg\n",
+				      new_supply_vdd->u_volt);
+			goto restore_voltage;
+		}
+		rockchip_set_read_margin(dev, opp_info, target_rm, is_set_rm);
+		if (is_set_clk && clk_set_rate(clk, new_freq)) {
+			ret = -EINVAL;
+			LOG_DEV_ERROR(dev, "failed to set clk rate: %d\n", ret);
+			goto restore_rm;
+		}
+		/* Scaling down? Scale voltage after frequency */
+	} else {
+		rockchip_set_intermediate_rate(dev, opp_info, clk, old_freq,
+					       new_freq, false, is_set_clk);
+		rockchip_set_read_margin(dev, opp_info, target_rm, is_set_rm);
+		if (is_set_clk && clk_set_rate(clk, new_freq)) {
+			ret = -EINVAL;
+			LOG_DEV_ERROR(dev, "failed to set clk rate: %d\n", ret);
+			goto restore_rm;
+		}
+		ret = regulator_set_voltage(vdd_reg, new_supply_vdd->u_volt,
+					    INT_MAX);
+		if (ret) {
+			LOG_DEV_ERROR(dev,
+				      "failed to set volt %lu uV for vdd reg\n",
+				      new_supply_vdd->u_volt);
+			goto restore_freq;
+		}
+		ret = regulator_set_voltage(mem_reg, new_supply_mem->u_volt,
+					    INT_MAX);
+		if (ret) {
+			LOG_DEV_ERROR(dev,
+				      "failed to set volt %lu uV for mem reg\n",
+				      new_supply_mem->u_volt);
+			goto restore_freq;
+		}
+	}
+
+	clk_bulk_disable_unprepare(opp_info->num_clks, opp_info->clks);
+
+	return 0;
+
+restore_freq:
+	if (is_set_clk && clk_set_rate(clk, old_freq))
+		LOG_DEV_ERROR(dev, "failed to restore old-freq %lu Hz\n",
+			      old_freq);
+restore_rm:
+	rockchip_get_read_margin(dev, opp_info, old_supply_vdd->u_volt,
+				 &target_rm);
+	rockchip_set_read_margin(dev, opp_info, opp_info->current_rm,
+				 is_set_rm);
+restore_voltage:
+	regulator_set_voltage(mem_reg, old_supply_mem->u_volt, INT_MAX);
+	regulator_set_voltage(vdd_reg, old_supply_vdd->u_volt, INT_MAX);
+	clk_bulk_disable_unprepare(opp_info->num_clks, opp_info->clks);
+
+	return ret;
+}
+
+static int npu_devfreq_target(struct device *dev, unsigned long *freq,
+			      u32 flags)
+{
+	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
+	struct dev_pm_opp *opp;
+	unsigned long opp_volt;
+	int ret = 0;
+
+	if (!npu_mdevp.is_checked)
+		return -EINVAL;
+
+	opp = devfreq_recommended_opp(dev, freq, flags);
+	if (IS_ERR(opp))
+		return PTR_ERR(opp);
+	opp_volt = dev_pm_opp_get_voltage(opp);
+	dev_pm_opp_put(opp);
+
+	rockchip_monitor_volt_adjust_lock(rknpu_dev->mdev_info);
+
+	ret = dev_pm_opp_set_rate(dev, *freq);
+	if (!ret) {
+		rknpu_dev->current_freq = *freq;
+		if (rknpu_dev->devfreq)
+			rknpu_dev->devfreq->last_status.current_frequency =
+				*freq;
+		rknpu_dev->current_volt = opp_volt;
+		LOG_DEV_DEBUG(dev, "set rknpu freq: %lu, volt: %lu\n",
+			      rknpu_dev->current_freq, rknpu_dev->current_volt);
+	}
+
+	rockchip_monitor_volt_adjust_unlock(rknpu_dev->mdev_info);
+
+	return ret;
+}
+
+static unsigned long npu_get_static_power(struct devfreq *devfreq,
+					  unsigned long voltage)
+{
+	struct device *dev = devfreq->dev.parent;
+	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
+
+	if (!rknpu_dev->model_data)
+		return 0;
+
+	return rockchip_ipa_get_static_power(rknpu_dev->model_data, voltage);
+}
+
+static struct devfreq_cooling_power npu_cooling_power = {
+	.get_static_power = &npu_get_static_power,
+};
+
+int rknpu_devfreq_init(struct rknpu_device *rknpu_dev)
+{
+	struct device *dev = rknpu_dev->dev;
+	struct devfreq_dev_profile *dp = &npu_devfreq_profile;
+	struct dev_pm_opp *opp;
+	struct opp_table *reg_table = NULL;
+	struct opp_table *opp_table = NULL;
+	const char *const reg_names[] = { "rknpu", "mem" };
+	int ret = -EINVAL;
+
+	if (strstr(__clk_get_name(rknpu_dev->clks[0].clk), "scmi"))
+		rknpu_dev->opp_info.scmi_clk = rknpu_dev->clks[0].clk;
+
+	if (of_find_property(dev->of_node, "rknpu-supply", NULL) &&
+	    of_find_property(dev->of_node, "mem-supply", NULL)) {
+		reg_table = dev_pm_opp_set_regulators(dev, reg_names, 2);
+		if (IS_ERR(reg_table))
+			return PTR_ERR(reg_table);
+		opp_table =
+			dev_pm_opp_register_set_opp_helper(dev, npu_opp_helper);
+		if (IS_ERR(opp_table)) {
+			dev_pm_opp_put_regulators(reg_table);
+			return PTR_ERR(opp_table);
+		}
+	} else {
+		reg_table = dev_pm_opp_set_regulators(dev, reg_names, 1);
+		if (IS_ERR(reg_table))
+			return PTR_ERR(reg_table);
+	}
+
+	rockchip_get_opp_data(rockchip_npu_of_match, &rknpu_dev->opp_info);
+	ret = rockchip_init_opp_table(dev, &rknpu_dev->opp_info, "npu_leakage",
+				      "rknpu");
+	if (ret) {
+		LOG_DEV_ERROR(dev, "failed to init_opp_table\n");
+		return ret;
+	}
+
+	rknpu_dev->current_freq = clk_get_rate(rknpu_dev->clks[0].clk);
+
+	opp = devfreq_recommended_opp(dev, &rknpu_dev->current_freq, 0);
+	if (IS_ERR(opp)) {
+		ret = PTR_ERR(opp);
+		goto err_remove_table;
+	}
+	dev_pm_opp_put(opp);
+	dp->initial_freq = rknpu_dev->current_freq;
+
+	ret = devfreq_add_governor(&devfreq_rknpu_ondemand);
+	if (ret) {
+		LOG_DEV_ERROR(dev, "failed to add rknpu_ondemand governor\n");
+		goto err_remove_table;
+	}
+
+	rknpu_dev->devfreq = devm_devfreq_add_device(dev, dp, "rknpu_ondemand",
+						     (void *)rknpu_dev);
+	if (IS_ERR(rknpu_dev->devfreq)) {
+		LOG_DEV_ERROR(dev, "failed to add devfreq\n");
+		ret = PTR_ERR(rknpu_dev->devfreq);
+		goto err_remove_governor;
+	}
+
+	npu_mdevp.data = rknpu_dev->devfreq;
+	npu_mdevp.opp_info = &rknpu_dev->opp_info;
+	rknpu_dev->mdev_info =
+		rockchip_system_monitor_register(dev, &npu_mdevp);
+	if (IS_ERR(rknpu_dev->mdev_info)) {
+		LOG_DEV_DEBUG(dev, "without system monitor\n");
+		rknpu_dev->mdev_info = NULL;
+		npu_mdevp.is_checked = true;
+	}
+	rknpu_dev->current_freq = clk_get_rate(rknpu_dev->clks[0].clk);
+	rknpu_dev->ondemand_freq = rknpu_dev->current_freq;
+	rknpu_dev->current_volt = regulator_get_voltage(rknpu_dev->vdd);
+
+	rknpu_dev->devfreq->previous_freq = rknpu_dev->current_freq;
+	if (rknpu_dev->devfreq->suspend_freq)
+		rknpu_dev->devfreq->resume_freq = rknpu_dev->current_freq;
+	rknpu_dev->devfreq->last_status.current_frequency =
+		rknpu_dev->current_freq;
+	rknpu_dev->devfreq->last_status.total_time = 1;
+	rknpu_dev->devfreq->last_status.busy_time = 1;
+
+	of_property_read_u32(dev->of_node, "dynamic-power-coefficient",
+			     (u32 *)&npu_cooling_power.dyn_power_coeff);
+	rknpu_dev->model_data =
+		rockchip_ipa_power_model_init(dev, "npu_leakage");
+	if (IS_ERR_OR_NULL(rknpu_dev->model_data)) {
+		rknpu_dev->model_data = NULL;
+		LOG_DEV_ERROR(dev, "failed to initialize power model\n");
+	} else if (rknpu_dev->model_data->dynamic_coefficient) {
+		npu_cooling_power.dyn_power_coeff =
+			rknpu_dev->model_data->dynamic_coefficient;
+	}
+	if (!npu_cooling_power.dyn_power_coeff) {
+		LOG_DEV_ERROR(dev, "failed to get dynamic-coefficient\n");
+		goto out;
+	}
+
+	rknpu_dev->devfreq_cooling = of_devfreq_cooling_register_power(
+		dev->of_node, rknpu_dev->devfreq, &npu_cooling_power);
+	if (IS_ERR_OR_NULL(rknpu_dev->devfreq_cooling))
+		LOG_DEV_ERROR(dev, "failed to register cooling device\n");
+
+out:
+	return 0;
+
+err_remove_governor:
+	devfreq_remove_governor(&devfreq_rknpu_ondemand);
+err_remove_table:
+	rockchip_uninit_opp_table(dev, &rknpu_dev->opp_info);
+
+	rknpu_dev->devfreq = NULL;
+
+	return ret;
+}
+EXPORT_SYMBOL(rknpu_devfreq_init);
+
+int rknpu_devfreq_runtime_suspend(struct device *dev)
+{
+	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
+	struct rockchip_opp_info *opp_info = &rknpu_dev->opp_info;
+
+	if (opp_info->scmi_clk) {
+		if (clk_set_rate(opp_info->scmi_clk, POWER_DOWN_FREQ))
+			LOG_DEV_ERROR(dev, "failed to restore clk rate\n");
+	}
+	opp_info->current_rm = UINT_MAX;
+
+	return 0;
+}
+EXPORT_SYMBOL(rknpu_devfreq_runtime_suspend);
+
+int rknpu_devfreq_runtime_resume(struct device *dev)
+{
+	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
+	struct rockchip_opp_info *opp_info = &rknpu_dev->opp_info;
+	int ret = 0;
+
+	if (!rknpu_dev->current_freq || !rknpu_dev->current_volt)
+		return 0;
+
+	ret = clk_bulk_prepare_enable(opp_info->num_clks, opp_info->clks);
+	if (ret) {
+		LOG_DEV_INFO(dev, "failed to enable opp clks\n");
+		return ret;
+	}
+
+	if (opp_info->data && opp_info->data->set_read_margin)
+		opp_info->data->set_read_margin(dev, opp_info,
+						opp_info->target_rm);
+	if (opp_info->scmi_clk) {
+		if (clk_set_rate(opp_info->scmi_clk, rknpu_dev->current_freq))
+			LOG_DEV_ERROR(dev, "failed to set power down rate\n");
+	}
+
+	clk_bulk_disable_unprepare(opp_info->num_clks, opp_info->clks);
+
+	return ret;
+}
+EXPORT_SYMBOL(rknpu_devfreq_runtime_resume);
+#endif
+
+void rknpu_devfreq_remove(struct rknpu_device *rknpu_dev)
+{
+	if (rknpu_dev->mdev_info) {
+		rockchip_system_monitor_unregister(rknpu_dev->mdev_info);
+		rknpu_dev->mdev_info = NULL;
+	}
+	if (rknpu_dev->devfreq)
+		devfreq_remove_governor(&devfreq_rknpu_ondemand);
+	rockchip_uninit_opp_table(rknpu_dev->dev, &rknpu_dev->opp_info);
+}
+EXPORT_SYMBOL(rknpu_devfreq_remove);
diff --git a/kernel/drivers/rknpu/rknpu_drv.c b/kernel/drivers/rknpu/rknpu_drv.c
index 867212c..1df364f 100644
--- a/kernel/drivers/rknpu/rknpu_drv.c
+++ b/kernel/drivers/rknpu/rknpu_drv.c
@@ -31,18 +31,11 @@
 #include <linux/clk-provider.h>
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
-#include <linux/devfreq_cooling.h>
 #include <linux/regmap.h>
 #include <linux/of_address.h>
 
 #ifndef FPGA_PLATFORM
 #include <soc/rockchip/rockchip_iommu.h>
-#include <soc/rockchip/rockchip_opp_select.h>
-#include <soc/rockchip/rockchip_system_monitor.h>
-#include <soc/rockchip/rockchip_ipa.h>
-#ifdef CONFIG_PM_DEVFREQ
-#include <../drivers/devfreq/governor.h>
-#endif
 #endif
 
 #include "rknpu_ioctl.h"
@@ -50,6 +43,7 @@
 #include "rknpu_fence.h"
 #include "rknpu_drv.h"
 #include "rknpu_gem.h"
+#include "rknpu_devfreq.h"
 
 #ifdef CONFIG_ROCKCHIP_RKNPU_DRM_GEM
 #include <drm/drm_device.h>
@@ -118,7 +112,8 @@
 	.num_resets = ARRAY_SIZE(rknpu_resets),
 	.nbuf_phyaddr = 0,
 	.nbuf_size = 0,
-	.max_submit_number = (1 << 12) - 1
+	.max_submit_number = (1 << 12) - 1,
+	.core_mask = 0x1,
 };
 
 static const struct rknpu_config rk3588_rknpu_config = {
@@ -137,7 +132,28 @@
 	.num_resets = ARRAY_SIZE(rk3588_npu_resets),
 	.nbuf_phyaddr = 0,
 	.nbuf_size = 0,
-	.max_submit_number = (1 << 12) - 1
+	.max_submit_number = (1 << 12) - 1,
+	.core_mask = 0x7,
+};
+
+static const struct rknpu_config rk3583_rknpu_config = {
+	.bw_priority_addr = 0x0,
+	.bw_priority_length = 0x0,
+	.dma_mask = DMA_BIT_MASK(40),
+	.pc_data_amount_scale = 2,
+	.pc_task_number_bits = 12,
+	.pc_task_number_mask = 0xfff,
+	.pc_task_status_offset = 0x3c,
+	.pc_dma_ctrl = 0,
+	.bw_enable = 0,
+	.irqs = rk3588_npu_irqs,
+	.resets = rk3588_npu_resets,
+	.num_irqs = 2,
+	.num_resets = 2,
+	.nbuf_phyaddr = 0,
+	.nbuf_size = 0,
+	.max_submit_number = (1 << 12) - 1,
+	.core_mask = 0x3,
 };
 
 static const struct rknpu_config rv1106_rknpu_config = {
@@ -156,7 +172,8 @@
 	.num_resets = ARRAY_SIZE(rknpu_resets),
 	.nbuf_phyaddr = 0,
 	.nbuf_size = 0,
-	.max_submit_number = (1 << 16) - 1
+	.max_submit_number = (1 << 16) - 1,
+	.core_mask = 0x1,
 };
 
 static const struct rknpu_config rk3562_rknpu_config = {
@@ -175,7 +192,8 @@
 	.num_resets = ARRAY_SIZE(rknpu_resets),
 	.nbuf_phyaddr = 0xfe400000,
 	.nbuf_size = 256 * 1024,
-	.max_submit_number = (1 << 16) - 1
+	.max_submit_number = (1 << 16) - 1,
+	.core_mask = 0x1,
 };
 
 /* driver probe and init */
@@ -627,13 +645,14 @@
 		if (job) {
 			now = ktime_get();
 			subcore_data->timer.busy_time +=
-				ktime_us_delta(now, job->hw_recoder_time);
+				ktime_sub(now, job->hw_recoder_time);
 			job->hw_recoder_time = now;
 		}
 
-		subcore_data->timer.busy_time_record =
+		subcore_data->timer.total_busy_time =
 			subcore_data->timer.busy_time;
 		subcore_data->timer.busy_time = 0;
+
 		spin_unlock_irqrestore(&rknpu_dev->irq_lock, flags);
 	}
 
@@ -801,10 +820,7 @@
 	}
 
 #ifndef FPGA_PLATFORM
-#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE &&                          \
-	KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
-	rockchip_monitor_volt_adjust_lock(rknpu_dev->mdev_info);
-#endif
+	rknpu_devfreq_lock(rknpu_dev);
 #endif
 
 	if (rknpu_dev->multiple_domains) {
@@ -863,10 +879,7 @@
 
 out:
 #ifndef FPGA_PLATFORM
-#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE &&                          \
-	KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
-	rockchip_monitor_volt_adjust_unlock(rknpu_dev->mdev_info);
-#endif
+	rknpu_devfreq_unlock(rknpu_dev);
 #endif
 
 	return ret;
@@ -880,10 +893,7 @@
 	int ret;
 	bool val;
 
-#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE &&                          \
-	KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
-	rockchip_monitor_volt_adjust_lock(rknpu_dev->mdev_info);
-#endif
+	rknpu_devfreq_lock(rknpu_dev);
 #endif
 
 	pm_runtime_put_sync(dev);
@@ -905,11 +915,7 @@
 		if (ret) {
 			LOG_DEV_ERROR(dev, "iommu still enabled\n");
 			pm_runtime_get_sync(dev);
-#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE &&                          \
-	KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
-			rockchip_monitor_volt_adjust_unlock(
-				rknpu_dev->mdev_info);
-#endif
+			rknpu_devfreq_unlock(rknpu_dev);
 			return ret;
 		}
 #else
@@ -925,10 +931,7 @@
 	}
 
 #ifndef FPGA_PLATFORM
-#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE &&                          \
-	KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
-	rockchip_monitor_volt_adjust_unlock(rknpu_dev->mdev_info);
-#endif
+	rknpu_devfreq_unlock(rknpu_dev);
 #endif
 
 	clk_bulk_disable_unprepare(rknpu_dev->num_clks, rknpu_dev->clks);
@@ -944,701 +947,14 @@
 	return 0;
 }
 
-#ifndef FPGA_PLATFORM
-#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
-static struct monitor_dev_profile npu_mdevp = {
-	.type = MONITOR_TYPE_DEV,
-	.low_temp_adjust = rockchip_monitor_dev_low_temp_adjust,
-	.high_temp_adjust = rockchip_monitor_dev_high_temp_adjust,
-#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE
-	.update_volt = rockchip_monitor_check_rate_volt,
-#endif
-};
-
-#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE
-static int npu_opp_helper(struct dev_pm_set_opp_data *data)
-{
-	struct device *dev = data->dev;
-	struct dev_pm_opp_supply *old_supply_vdd = &data->old_opp.supplies[0];
-	struct dev_pm_opp_supply *old_supply_mem = &data->old_opp.supplies[1];
-	struct dev_pm_opp_supply *new_supply_vdd = &data->new_opp.supplies[0];
-	struct dev_pm_opp_supply *new_supply_mem = &data->new_opp.supplies[1];
-	struct regulator *vdd_reg = data->regulators[0];
-	struct regulator *mem_reg = data->regulators[1];
-	struct clk *clk = data->clk;
-	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
-	struct rockchip_opp_info *opp_info = &rknpu_dev->opp_info;
-	unsigned long old_freq = data->old_opp.rate;
-	unsigned long new_freq = data->new_opp.rate;
-	bool is_set_rm = true;
-	bool is_set_clk = true;
-	u32 target_rm = UINT_MAX;
-	int ret = 0;
-
-	if (!pm_runtime_active(dev)) {
-		is_set_rm = false;
-		if (opp_info->scmi_clk)
-			is_set_clk = false;
-	}
-
-	ret = clk_bulk_prepare_enable(opp_info->num_clks, opp_info->clks);
-	if (ret < 0) {
-		LOG_DEV_ERROR(dev, "failed to enable opp clks\n");
-		return ret;
-	}
-	rockchip_get_read_margin(dev, opp_info, new_supply_vdd->u_volt,
-				 &target_rm);
-
-	/* Change frequency */
-	LOG_DEV_DEBUG(dev, "switching OPP: %lu Hz --> %lu Hz\n", old_freq,
-		      new_freq);
-	/* Scaling up? Scale voltage before frequency */
-	if (new_freq >= old_freq) {
-		rockchip_set_intermediate_rate(dev, opp_info, clk, old_freq,
-					       new_freq, true, is_set_clk);
-		ret = regulator_set_voltage(mem_reg, new_supply_mem->u_volt,
-					    INT_MAX);
-		if (ret) {
-			LOG_DEV_ERROR(dev,
-				      "failed to set volt %lu uV for mem reg\n",
-				      new_supply_mem->u_volt);
-			goto restore_voltage;
-		}
-		ret = regulator_set_voltage(vdd_reg, new_supply_vdd->u_volt,
-					    INT_MAX);
-		if (ret) {
-			LOG_DEV_ERROR(dev,
-				      "failed to set volt %lu uV for vdd reg\n",
-				      new_supply_vdd->u_volt);
-			goto restore_voltage;
-		}
-		rockchip_set_read_margin(dev, opp_info, target_rm, is_set_rm);
-		if (is_set_clk && clk_set_rate(clk, new_freq)) {
-			ret = -EINVAL;
-			LOG_DEV_ERROR(dev, "failed to set clk rate: %d\n", ret);
-			goto restore_rm;
-		}
-		/* Scaling down? Scale voltage after frequency */
-	} else {
-		rockchip_set_intermediate_rate(dev, opp_info, clk, old_freq,
-					       new_freq, false, is_set_clk);
-		rockchip_set_read_margin(dev, opp_info, target_rm, is_set_rm);
-		if (is_set_clk && clk_set_rate(clk, new_freq)) {
-			ret = -EINVAL;
-			LOG_DEV_ERROR(dev, "failed to set clk rate: %d\n", ret);
-			goto restore_rm;
-		}
-		ret = regulator_set_voltage(vdd_reg, new_supply_vdd->u_volt,
-					    INT_MAX);
-		if (ret) {
-			LOG_DEV_ERROR(dev,
-				      "failed to set volt %lu uV for vdd reg\n",
-				      new_supply_vdd->u_volt);
-			goto restore_freq;
-		}
-		ret = regulator_set_voltage(mem_reg, new_supply_mem->u_volt,
-					    INT_MAX);
-		if (ret) {
-			LOG_DEV_ERROR(dev,
-				      "failed to set volt %lu uV for mem reg\n",
-				      new_supply_mem->u_volt);
-			goto restore_freq;
-		}
-	}
-
-	clk_bulk_disable_unprepare(opp_info->num_clks, opp_info->clks);
-
-	return 0;
-
-restore_freq:
-	if (is_set_clk && clk_set_rate(clk, old_freq))
-		LOG_DEV_ERROR(dev, "failed to restore old-freq %lu Hz\n",
-			      old_freq);
-restore_rm:
-	rockchip_get_read_margin(dev, opp_info, old_supply_vdd->u_volt,
-				 &target_rm);
-	rockchip_set_read_margin(dev, opp_info, opp_info->current_rm,
-				 is_set_rm);
-restore_voltage:
-	regulator_set_voltage(mem_reg, old_supply_mem->u_volt, INT_MAX);
-	regulator_set_voltage(vdd_reg, old_supply_vdd->u_volt, INT_MAX);
-	clk_bulk_disable_unprepare(opp_info->num_clks, opp_info->clks);
-
-	return ret;
-}
-
-static int npu_devfreq_target(struct device *dev, unsigned long *freq,
-			      u32 flags)
-{
-	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
-	struct dev_pm_opp *opp;
-	unsigned long opp_volt;
-	int ret = 0;
-
-	if (!npu_mdevp.is_checked)
-		return -EINVAL;
-
-	opp = devfreq_recommended_opp(dev, freq, flags);
-	if (IS_ERR(opp))
-		return PTR_ERR(opp);
-	opp_volt = dev_pm_opp_get_voltage(opp);
-	dev_pm_opp_put(opp);
-
-#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE
-	rockchip_monitor_volt_adjust_lock(rknpu_dev->mdev_info);
-#endif
-	ret = dev_pm_opp_set_rate(dev, *freq);
-	if (!ret) {
-		rknpu_dev->current_freq = *freq;
-		if (rknpu_dev->devfreq)
-			rknpu_dev->devfreq->last_status.current_frequency =
-				*freq;
-		rknpu_dev->current_volt = opp_volt;
-		LOG_DEV_INFO(dev, "set rknpu freq: %lu, volt: %lu\n",
-			     rknpu_dev->current_freq, rknpu_dev->current_volt);
-	}
-#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE
-	rockchip_monitor_volt_adjust_unlock(rknpu_dev->mdev_info);
-#endif
-
-	return ret;
-}
-
-#else
-
-static int npu_devfreq_target(struct device *dev, unsigned long *target_freq,
-			      u32 flags)
-{
-	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
-	struct dev_pm_opp *opp = NULL;
-	unsigned long freq = *target_freq;
-	unsigned long old_freq = rknpu_dev->current_freq;
-	unsigned long volt, old_volt = rknpu_dev->current_volt;
-	int ret = -EINVAL;
-
-#if KERNEL_VERSION(4, 11, 0) > LINUX_VERSION_CODE
-	rcu_read_lock();
-#endif
-
-	opp = devfreq_recommended_opp(dev, &freq, flags);
-	if (IS_ERR(opp)) {
-#if KERNEL_VERSION(4, 11, 0) > LINUX_VERSION_CODE
-		rcu_read_unlock();
-#endif
-		LOG_DEV_ERROR(dev, "failed to get opp (%ld)\n", PTR_ERR(opp));
-		return PTR_ERR(opp);
-	}
-	volt = dev_pm_opp_get_voltage(opp);
-#if KERNEL_VERSION(4, 11, 0) > LINUX_VERSION_CODE
-	rcu_read_unlock();
-#endif
-
-	/*
-	 * Only update if there is a change of frequency
-	 */
-	if (old_freq == freq) {
-		*target_freq = freq;
-		if (old_volt == volt)
-			return 0;
-		ret = regulator_set_voltage(rknpu_dev->vdd, volt, INT_MAX);
-		if (ret) {
-			LOG_DEV_ERROR(dev, "failed to set volt %lu\n", volt);
-			return ret;
-		}
-		rknpu_dev->current_volt = volt;
-		return 0;
-	}
-
-	if (rknpu_dev->vdd && old_volt != volt && old_freq < freq) {
-		ret = regulator_set_voltage(rknpu_dev->vdd, volt, INT_MAX);
-		if (ret) {
-			LOG_DEV_ERROR(dev, "failed to increase volt %lu\n",
-				      volt);
-			return ret;
-		}
-	}
-	LOG_DEV_DEBUG(dev, "%luHz %luuV -> %luHz %luuV\n", old_freq, old_volt,
-		      freq, volt);
-	ret = clk_set_rate(rknpu_dev->clks[0].clk, freq);
-	if (ret) {
-		LOG_DEV_ERROR(dev, "failed to set clock %lu\n", freq);
-		return ret;
-	}
-	*target_freq = freq;
-	rknpu_dev->current_freq = freq;
-
-	if (rknpu_dev->devfreq)
-		rknpu_dev->devfreq->last_status.current_frequency = freq;
-
-	if (rknpu_dev->vdd && old_volt != volt && old_freq > freq) {
-		ret = regulator_set_voltage(rknpu_dev->vdd, volt, INT_MAX);
-		if (ret) {
-			LOG_DEV_ERROR(dev, "failed to decrease volt %lu\n",
-				      volt);
-			return ret;
-		}
-	}
-	rknpu_dev->current_volt = volt;
-
-	LOG_DEV_INFO(dev, "set rknpu freq: %lu, volt: %lu\n",
-		     rknpu_dev->current_freq, rknpu_dev->current_volt);
-
-	return ret;
-}
-#endif
-
-static int npu_devfreq_get_dev_status(struct device *dev,
-				      struct devfreq_dev_status *stat)
-{
-	return 0;
-}
-
-static int npu_devfreq_get_cur_freq(struct device *dev, unsigned long *freq)
-{
-	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
-
-	*freq = rknpu_dev->current_freq;
-
-	return 0;
-}
-
-static struct devfreq_dev_profile npu_devfreq_profile = {
-	.polling_ms = 50,
-	.target = npu_devfreq_target,
-	.get_dev_status = npu_devfreq_get_dev_status,
-	.get_cur_freq = npu_devfreq_get_cur_freq,
-};
-#endif
-
-#ifdef CONFIG_PM_DEVFREQ
-static int devfreq_rknpu_ondemand_func(struct devfreq *df, unsigned long *freq)
-{
-	struct rknpu_device *rknpu_dev = df->data;
-
-	if (rknpu_dev)
-		*freq = rknpu_dev->ondemand_freq;
-	else
-		*freq = df->previous_freq;
-
-	return 0;
-}
-
-static int devfreq_rknpu_ondemand_handler(struct devfreq *devfreq,
-					  unsigned int event, void *data)
-{
-	return 0;
-}
-
-static struct devfreq_governor devfreq_rknpu_ondemand = {
-	.name = "rknpu_ondemand",
-	.get_target_freq = devfreq_rknpu_ondemand_func,
-	.event_handler = devfreq_rknpu_ondemand_handler,
-};
-#endif
-
-#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
-static unsigned long npu_get_static_power(struct devfreq *devfreq,
-					  unsigned long voltage)
-{
-	struct device *dev = devfreq->dev.parent;
-	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
-
-	if (!rknpu_dev->model_data)
-		return 0;
-
-	return rockchip_ipa_get_static_power(rknpu_dev->model_data, voltage);
-}
-
-static struct devfreq_cooling_power npu_cooling_power = {
-	.get_static_power = &npu_get_static_power,
-};
-
-#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE
-static int rk3588_npu_get_soc_info(struct device *dev, struct device_node *np,
-				   int *bin, int *process)
-{
-	int ret = 0;
-	u8 value = 0;
-
-	if (!bin)
-		return 0;
-
-	if (of_property_match_string(np, "nvmem-cell-names",
-				     "specification_serial_number") >= 0) {
-		ret = rockchip_nvmem_cell_read_u8(
-			np, "specification_serial_number", &value);
-		if (ret) {
-			LOG_DEV_ERROR(
-				dev,
-				"Failed to get specification_serial_number\n");
-			return ret;
-		}
-		/* RK3588M */
-		if (value == 0xd)
-			*bin = 1;
-		/* RK3588J */
-		else if (value == 0xa)
-			*bin = 2;
-	}
-	if (*bin < 0)
-		*bin = 0;
-	LOG_DEV_INFO(dev, "bin=%d\n", *bin);
-
-	return ret;
-}
-
-static int rk3588_npu_set_soc_info(struct device *dev, struct device_node *np,
-				   int bin, int process, int volt_sel)
-{
-	struct opp_table *opp_table;
-	u32 supported_hw[2];
-
-	if (volt_sel < 0)
-		return 0;
-	if (bin < 0)
-		bin = 0;
-
-	if (!of_property_read_bool(np, "rockchip,supported-hw"))
-		return 0;
-
-	/* SoC Version */
-	supported_hw[0] = BIT(bin);
-	/* Speed Grade */
-	supported_hw[1] = BIT(volt_sel);
-	opp_table = dev_pm_opp_set_supported_hw(dev, supported_hw, 2);
-	if (IS_ERR(opp_table)) {
-		LOG_DEV_ERROR(dev, "failed to set supported opp\n");
-		return PTR_ERR(opp_table);
-	}
-
-	return 0;
-}
-
-static int rk3588_npu_set_read_margin(struct device *dev,
-				      struct rockchip_opp_info *opp_info,
-				      u32 rm)
-{
-	u32 offset = 0, val = 0;
-	int i, ret = 0;
-
-	if (!opp_info->grf || !opp_info->volt_rm_tbl)
-		return 0;
-
-	if (rm == opp_info->current_rm || rm == UINT_MAX)
-		return 0;
-
-	LOG_DEV_DEBUG(dev, "set rm to %d\n", rm);
-
-	for (i = 0; i < 3; i++) {
-		ret = regmap_read(opp_info->grf, offset, &val);
-		if (ret < 0) {
-			LOG_DEV_ERROR(dev, "failed to get rm from 0x%x\n",
-				      offset);
-			return ret;
-		}
-		val &= ~0x1c;
-		regmap_write(opp_info->grf, offset, val | (rm << 2));
-		offset += 4;
-	}
-	opp_info->current_rm = rm;
-
-	return 0;
-}
-
-static const struct rockchip_opp_data rk3588_npu_opp_data = {
-	.get_soc_info = rk3588_npu_get_soc_info,
-	.set_soc_info = rk3588_npu_set_soc_info,
-	.set_read_margin = rk3588_npu_set_read_margin,
-};
-
-static const struct of_device_id rockchip_npu_of_match[] = {
-	{
-		.compatible = "rockchip,rk3588",
-		.data = (void *)&rk3588_npu_opp_data,
-	},
-	{},
-};
-
-static int rknpu_devfreq_init(struct rknpu_device *rknpu_dev)
-{
-	struct device *dev = rknpu_dev->dev;
-	struct devfreq_dev_profile *dp = &npu_devfreq_profile;
-	struct dev_pm_opp *opp;
-	struct opp_table *reg_table = NULL;
-	struct opp_table *opp_table = NULL;
-	const char *const reg_names[] = { "rknpu", "mem" };
-	int ret = -EINVAL;
-
-	if (of_find_property(dev->of_node, "rknpu-supply", NULL) &&
-	    of_find_property(dev->of_node, "mem-supply", NULL)) {
-		reg_table = dev_pm_opp_set_regulators(dev, reg_names, 2);
-		if (IS_ERR(reg_table))
-			return PTR_ERR(reg_table);
-		opp_table =
-			dev_pm_opp_register_set_opp_helper(dev, npu_opp_helper);
-		if (IS_ERR(opp_table)) {
-			dev_pm_opp_put_regulators(reg_table);
-			return PTR_ERR(opp_table);
-		}
-	} else {
-		reg_table = dev_pm_opp_set_regulators(dev, reg_names, 1);
-		if (IS_ERR(reg_table))
-			return PTR_ERR(reg_table);
-	}
-
-	rockchip_get_opp_data(rockchip_npu_of_match, &rknpu_dev->opp_info);
-	ret = rockchip_init_opp_table(dev, &rknpu_dev->opp_info, "npu_leakage",
-				      "rknpu");
-	if (ret) {
-		LOG_DEV_ERROR(dev, "failed to init_opp_table\n");
-		return ret;
-	}
-
-	rknpu_dev->current_freq = clk_get_rate(rknpu_dev->clks[0].clk);
-
-	opp = devfreq_recommended_opp(dev, &rknpu_dev->current_freq, 0);
-	if (IS_ERR(opp)) {
-		ret = PTR_ERR(opp);
-		goto err_remove_table;
-	}
-	dev_pm_opp_put(opp);
-	dp->initial_freq = rknpu_dev->current_freq;
-
-#ifdef CONFIG_PM_DEVFREQ
-	ret = devfreq_add_governor(&devfreq_rknpu_ondemand);
-	if (ret) {
-		LOG_DEV_ERROR(dev, "failed to add rknpu_ondemand governor\n");
-		goto err_remove_table;
-	}
-#endif
-
-	rknpu_dev->devfreq = devm_devfreq_add_device(dev, dp, "rknpu_ondemand",
-						     (void *)rknpu_dev);
-	if (IS_ERR(rknpu_dev->devfreq)) {
-		LOG_DEV_ERROR(dev, "failed to add devfreq\n");
-		ret = PTR_ERR(rknpu_dev->devfreq);
-		goto err_remove_governor;
-	}
-	devm_devfreq_register_opp_notifier(dev, rknpu_dev->devfreq);
-
-	rknpu_dev->devfreq->last_status.current_frequency = dp->initial_freq;
-	rknpu_dev->devfreq->last_status.total_time = 1;
-	rknpu_dev->devfreq->last_status.busy_time = 1;
-
-	npu_mdevp.data = rknpu_dev->devfreq;
-	npu_mdevp.opp_info = &rknpu_dev->opp_info;
-	rknpu_dev->mdev_info =
-		rockchip_system_monitor_register(dev, &npu_mdevp);
-	if (IS_ERR(rknpu_dev->mdev_info)) {
-		LOG_DEV_DEBUG(dev, "without system monitor\n");
-		rknpu_dev->mdev_info = NULL;
-		npu_mdevp.is_checked = true;
-	}
-	rknpu_dev->current_freq = clk_get_rate(rknpu_dev->clks[0].clk);
-	rknpu_dev->current_volt = regulator_get_voltage(rknpu_dev->vdd);
-
-	of_property_read_u32(dev->of_node, "dynamic-power-coefficient",
-			     (u32 *)&npu_cooling_power.dyn_power_coeff);
-	rknpu_dev->model_data =
-		rockchip_ipa_power_model_init(dev, "npu_leakage");
-	if (IS_ERR_OR_NULL(rknpu_dev->model_data)) {
-		rknpu_dev->model_data = NULL;
-		LOG_DEV_ERROR(dev, "failed to initialize power model\n");
-	} else if (rknpu_dev->model_data->dynamic_coefficient) {
-		npu_cooling_power.dyn_power_coeff =
-			rknpu_dev->model_data->dynamic_coefficient;
-	}
-	if (!npu_cooling_power.dyn_power_coeff) {
-		LOG_DEV_ERROR(dev, "failed to get dynamic-coefficient\n");
-		goto out;
-	}
-
-	rknpu_dev->devfreq_cooling = of_devfreq_cooling_register_power(
-		dev->of_node, rknpu_dev->devfreq, &npu_cooling_power);
-	if (IS_ERR_OR_NULL(rknpu_dev->devfreq_cooling))
-		LOG_DEV_ERROR(dev, "failed to register cooling device\n");
-
-out:
-	return 0;
-
-err_remove_governor:
-#ifdef CONFIG_PM_DEVFREQ
-	devfreq_remove_governor(&devfreq_rknpu_ondemand);
-#endif
-err_remove_table:
-	dev_pm_opp_of_remove_table(dev);
-
-	rknpu_dev->devfreq = NULL;
-
-	return ret;
-}
-
-#else
-
-static int npu_devfreq_adjust_current_freq_volt(struct device *dev,
-						struct rknpu_device *rknpu_dev)
-{
-	unsigned long volt, old_freq, freq;
-	struct dev_pm_opp *opp = NULL;
-	int ret = -EINVAL;
-
-	old_freq = clk_get_rate(rknpu_dev->clks[0].clk);
-	freq = old_freq;
-
-#if KERNEL_VERSION(4, 11, 0) > LINUX_VERSION_CODE
-	rcu_read_lock();
-#endif
-
-	opp = devfreq_recommended_opp(dev, &freq, 0);
-	volt = dev_pm_opp_get_voltage(opp);
-
-#if KERNEL_VERSION(4, 11, 0) > LINUX_VERSION_CODE
-	rcu_read_unlock();
-#endif
-
-	if (freq >= old_freq && rknpu_dev->vdd) {
-		ret = regulator_set_voltage(rknpu_dev->vdd, volt, INT_MAX);
-		if (ret) {
-			LOG_DEV_ERROR(dev, "failed to set volt %lu\n", volt);
-			return ret;
-		}
-	}
-	LOG_DEV_DEBUG(dev, "adjust current freq=%luHz, volt=%luuV\n", freq,
-		      volt);
-	ret = clk_set_rate(rknpu_dev->clks[0].clk, freq);
-	if (ret) {
-		LOG_DEV_ERROR(dev, "failed to set clock %lu\n", freq);
-		return ret;
-	}
-	if (freq < old_freq && rknpu_dev->vdd) {
-		ret = regulator_set_voltage(rknpu_dev->vdd, volt, INT_MAX);
-		if (ret) {
-			LOG_DEV_ERROR(dev, "failed to set volt %lu\n", volt);
-			return ret;
-		}
-	}
-	rknpu_dev->current_freq = freq;
-	rknpu_dev->current_volt = volt;
-
-	return 0;
-}
-
-static int rknpu_devfreq_init(struct rknpu_device *rknpu_dev)
-{
-	struct device *dev = rknpu_dev->dev;
-	struct devfreq_dev_profile *dp = &npu_devfreq_profile;
-	int ret = -EINVAL;
-
-	ret = rockchip_init_opp_table(dev, NULL, "npu_leakage", "rknpu");
-	if (ret) {
-		LOG_DEV_ERROR(dev, "failed to init_opp_table\n");
-		return ret;
-	}
-
-	ret = npu_devfreq_adjust_current_freq_volt(dev, rknpu_dev);
-	if (ret) {
-		LOG_DEV_ERROR(dev, "failed to adjust current freq volt\n");
-		goto err_remove_table;
-	}
-	dp->initial_freq = rknpu_dev->current_freq;
-
-#ifdef CONFIG_PM_DEVFREQ
-	ret = devfreq_add_governor(&devfreq_rknpu_ondemand);
-	if (ret) {
-		LOG_DEV_ERROR(dev, "failed to add rknpu_ondemand governor\n");
-		goto err_remove_table;
-	}
-#endif
-
-	rknpu_dev->devfreq = devm_devfreq_add_device(dev, dp, "rknpu_ondemand",
-						     (void *)rknpu_dev);
-	if (IS_ERR(rknpu_dev->devfreq)) {
-		LOG_DEV_ERROR(dev, "failed to add devfreq\n");
-		ret = PTR_ERR(rknpu_dev->devfreq);
-		goto err_remove_governor;
-	}
-	devm_devfreq_register_opp_notifier(dev, rknpu_dev->devfreq);
-
-	rknpu_dev->devfreq->last_status.current_frequency = dp->initial_freq;
-	rknpu_dev->devfreq->last_status.total_time = 1;
-	rknpu_dev->devfreq->last_status.busy_time = 1;
-
-	npu_mdevp.data = rknpu_dev->devfreq;
-	rknpu_dev->mdev_info =
-		rockchip_system_monitor_register(dev, &npu_mdevp);
-	if (IS_ERR(rknpu_dev->mdev_info)) {
-		LOG_DEV_DEBUG(dev, "without system monitor\n");
-		rknpu_dev->mdev_info = NULL;
-	}
-	rknpu_dev->current_freq = clk_get_rate(rknpu_dev->clks[0].clk);
-	rknpu_dev->current_volt = regulator_get_voltage(rknpu_dev->vdd);
-
-	of_property_read_u32(dev->of_node, "dynamic-power-coefficient",
-			     (u32 *)&npu_cooling_power.dyn_power_coeff);
-	rknpu_dev->model_data =
-		rockchip_ipa_power_model_init(dev, "npu_leakage");
-	if (IS_ERR_OR_NULL(rknpu_dev->model_data)) {
-		rknpu_dev->model_data = NULL;
-		LOG_DEV_ERROR(dev, "failed to initialize power model\n");
-	} else if (rknpu_dev->model_data->dynamic_coefficient) {
-		npu_cooling_power.dyn_power_coeff =
-			rknpu_dev->model_data->dynamic_coefficient;
-	}
-
-	if (!npu_cooling_power.dyn_power_coeff) {
-		LOG_DEV_ERROR(dev, "failed to get dynamic-coefficient\n");
-		goto out;
-	}
-
-	rknpu_dev->devfreq_cooling = of_devfreq_cooling_register_power(
-		dev->of_node, rknpu_dev->devfreq, &npu_cooling_power);
-	if (IS_ERR_OR_NULL(rknpu_dev->devfreq_cooling))
-		LOG_DEV_ERROR(dev, "failed to register cooling device\n");
-
-out:
-	return 0;
-
-err_remove_governor:
-#ifdef CONFIG_PM_DEVFREQ
-	devfreq_remove_governor(&devfreq_rknpu_ondemand);
-#endif
-err_remove_table:
-	dev_pm_opp_of_remove_table(dev);
-
-	rknpu_dev->devfreq = NULL;
-
-	return ret;
-}
-#endif
-#endif
-
-static int rknpu_devfreq_remove(struct rknpu_device *rknpu_dev)
-{
-	if (rknpu_dev->devfreq) {
-		devfreq_unregister_opp_notifier(rknpu_dev->dev,
-						rknpu_dev->devfreq);
-		dev_pm_opp_of_remove_table(rknpu_dev->dev);
-#ifdef CONFIG_PM_DEVFREQ
-		devfreq_remove_governor(&devfreq_rknpu_ondemand);
-#endif
-	}
-
-	return 0;
-}
-
-#endif
-
 static int rknpu_register_irq(struct platform_device *pdev,
 			      struct rknpu_device *rknpu_dev)
 {
 	const struct rknpu_config *config = rknpu_dev->config;
 	struct device *dev = &pdev->dev;
-#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
 	struct resource *res;
-#endif
 	int i, ret, irq;
 
-#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
 	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
 					   config->irqs[0].name);
 	if (res) {
@@ -1677,25 +993,6 @@
 			return ret;
 		}
 	}
-#else
-	/* there are irq names in dts */
-	for (i = 0; i < config->num_irqs; i++) {
-		irq = platform_get_irq_byname(pdev, config->irqs[i].name);
-		if (irq < 0) {
-			LOG_DEV_ERROR(dev, "no npu %s in dts\n",
-				      config->irqs[i].name);
-			return irq;
-		}
-
-		ret = devm_request_irq(dev, irq, config->irqs[i].irq_hdl,
-				       IRQF_SHARED, dev_name(dev), rknpu_dev);
-		if (ret < 0) {
-			LOG_DEV_ERROR(dev, "request %s failed: %d\n",
-				      config->irqs[i].name, ret);
-			return ret;
-		}
-	}
-#endif
 
 	return 0;
 }
@@ -1775,6 +1072,28 @@
 	return 0;
 }
 
+static int rknpu_get_invalid_core_mask(struct device *dev)
+{
+	int ret = 0;
+	u8 invalid_core_mask = 0;
+
+	if (of_property_match_string(dev->of_node, "nvmem-cell-names",
+				     "cores") >= 0) {
+		ret = rockchip_nvmem_cell_read_u8(dev->of_node, "cores",
+						  &invalid_core_mask);
+		/* The default valid npu cores for RK3583 are core0 and core1 */
+		invalid_core_mask |= RKNPU_CORE2_MASK;
+		if (ret) {
+			LOG_DEV_ERROR(
+				dev,
+				"failed to get specification_serial_number\n");
+			return invalid_core_mask;
+		}
+	}
+
+	return (int)invalid_core_mask;
+}
+
 static int rknpu_probe(struct platform_device *pdev)
 {
 	struct resource *res = NULL;
@@ -1806,6 +1125,22 @@
 	if (!config)
 		return -EINVAL;
 
+	if (match->data == (void *)&rk3588_rknpu_config) {
+		int invalid_core_mask = rknpu_get_invalid_core_mask(dev);
+		/* The default valid npu cores for RK3583 are core0 and core1 */
+		if (invalid_core_mask & RKNPU_CORE2_MASK) {
+			if ((invalid_core_mask & RKNPU_CORE0_MASK) ||
+			    (invalid_core_mask & RKNPU_CORE1_MASK)) {
+				LOG_DEV_ERROR(
+					dev,
+					"rknpu core invalid, invalid core mask: %#x\n",
+					invalid_core_mask);
+				return -ENODEV;
+			}
+			config = &rk3583_rknpu_config;
+		}
+	}
+
 	rknpu_dev->config = config;
 	rknpu_dev->dev = dev;
 
@@ -1834,12 +1169,6 @@
 	}
 
 #ifndef FPGA_PLATFORM
-#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE &&                          \
-	KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
-	if (strstr(__clk_get_name(rknpu_dev->clks[0].clk), "scmi"))
-		rknpu_dev->opp_info.scmi_clk = rknpu_dev->clks[0].clk;
-#endif
-
 	rknpu_dev->vdd = devm_regulator_get_optional(dev, "rknpu");
 	if (IS_ERR(rknpu_dev->vdd)) {
 		if (PTR_ERR(rknpu_dev->vdd) != -ENODEV) {
@@ -1966,9 +1295,11 @@
 		virt_dev = dev_pm_domain_attach_by_name(dev, "npu1");
 		if (!IS_ERR(virt_dev))
 			rknpu_dev->genpd_dev_npu1 = virt_dev;
-		virt_dev = dev_pm_domain_attach_by_name(dev, "npu2");
-		if (!IS_ERR(virt_dev))
-			rknpu_dev->genpd_dev_npu2 = virt_dev;
+		if (config->num_irqs > 2) {
+			virt_dev = dev_pm_domain_attach_by_name(dev, "npu2");
+			if (!IS_ERR(virt_dev))
+				rknpu_dev->genpd_dev_npu2 = virt_dev;
+		}
 		rknpu_dev->multiple_domains = true;
 	}
 
@@ -1977,9 +1308,7 @@
 		goto err_remove_drv;
 
 #ifndef FPGA_PLATFORM
-#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
 	rknpu_devfreq_init(rknpu_dev);
-#endif
 #endif
 
 	// set default power put delay to 3s
@@ -2088,48 +1417,14 @@
 }
 
 #ifndef FPGA_PLATFORM
-#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE &&                          \
-	KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
 static int rknpu_runtime_suspend(struct device *dev)
 {
-	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
-	struct rockchip_opp_info *opp_info = &rknpu_dev->opp_info;
-
-	if (opp_info->scmi_clk) {
-		if (clk_set_rate(opp_info->scmi_clk, POWER_DOWN_FREQ))
-			LOG_DEV_ERROR(dev, "failed to restore clk rate\n");
-	}
-	opp_info->current_rm = UINT_MAX;
-
-	return 0;
+	return rknpu_devfreq_runtime_suspend(dev);
 }
 
 static int rknpu_runtime_resume(struct device *dev)
 {
-	struct rknpu_device *rknpu_dev = dev_get_drvdata(dev);
-	struct rockchip_opp_info *opp_info = &rknpu_dev->opp_info;
-	int ret = 0;
-
-	if (!rknpu_dev->current_freq || !rknpu_dev->current_volt)
-		return 0;
-
-	ret = clk_bulk_prepare_enable(opp_info->num_clks, opp_info->clks);
-	if (ret) {
-		LOG_DEV_ERROR(dev, "failed to enable opp clks\n");
-		return ret;
-	}
-
-	if (opp_info->data && opp_info->data->set_read_margin)
-		opp_info->data->set_read_margin(dev, opp_info,
-						opp_info->target_rm);
-	if (opp_info->scmi_clk) {
-		if (clk_set_rate(opp_info->scmi_clk, rknpu_dev->current_freq))
-			LOG_DEV_ERROR(dev, "failed to set power down rate\n");
-	}
-
-	clk_bulk_disable_unprepare(opp_info->num_clks, opp_info->clks);
-
-	return ret;
+	return rknpu_devfreq_runtime_resume(dev);
 }
 
 static const struct dev_pm_ops rknpu_pm_ops = {
@@ -2139,7 +1434,6 @@
 				   NULL)
 };
 #endif
-#endif
 
 static struct platform_driver rknpu_driver = {
 	.probe = rknpu_probe,
@@ -2148,10 +1442,7 @@
 		.owner = THIS_MODULE,
 		.name = "RKNPU",
 #ifndef FPGA_PLATFORM
-#if KERNEL_VERSION(5, 5, 0) < LINUX_VERSION_CODE &&                            \
-	KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
 		.pm = &rknpu_pm_ops,
-#endif
 #endif
 		.of_match_table = of_match_ptr(rknpu_of_match),
 	},
diff --git a/kernel/drivers/rknpu/rknpu_job.c b/kernel/drivers/rknpu/rknpu_job.c
index f0f1dd7..6dc94b5 100644
--- a/kernel/drivers/rknpu/rknpu_job.c
+++ b/kernel/drivers/rknpu/rknpu_job.c
@@ -27,7 +27,7 @@
 {
 	int index = 0;
 
-	switch (core_mask & ((1 << RKNPU_MAX_CORES) - 1)) {
+	switch (core_mask) {
 	case RKNPU_CORE0_MASK:
 	case RKNPU_CORE0_MASK | RKNPU_CORE1_MASK:
 	case RKNPU_CORE0_MASK | RKNPU_CORE1_MASK | RKNPU_CORE2_MASK:
@@ -73,7 +73,7 @@
 	int task_num = job->args->task_number;
 
 	if (core_index >= RKNPU_MAX_CORES || core_index < 0) {
-		LOG_ERROR("core_index: %d set error!", core_index);
+		LOG_ERROR("invalid rknpu core index: %d", core_index);
 		return 0;
 	}
 
@@ -131,8 +131,6 @@
 #ifdef CONFIG_ROCKCHIP_RKNPU_DRM_GEM
 	struct rknpu_gem_object *task_obj = NULL;
 #endif
-	if (rknpu_dev->config->num_irqs == 1)
-		args->core_mask = RKNPU_CORE0_MASK;
 
 	job = kzalloc(sizeof(*job), GFP_KERNEL);
 	if (!job)
@@ -197,19 +195,19 @@
 			break;
 
 		if (ret == 0) {
-			int64_t commit_time = 0;
+			int64_t elapse_time_us = 0;
 			spin_lock_irqsave(&rknpu_dev->irq_lock, flags);
-			commit_time = ktime_us_delta(ktime_get(),
-						     job->commit_pc_time);
+			elapse_time_us = ktime_us_delta(ktime_get(),
+							job->hw_commit_time);
 			continue_wait =
-				job->commit_pc_time == 0 ?
+				job->hw_commit_time == 0 ?
 					true :
-					(commit_time < args->timeout * 1000);
+					(elapse_time_us < args->timeout * 1000);
 			spin_unlock_irqrestore(&rknpu_dev->irq_lock, flags);
 			LOG_ERROR(
-				"job: %p, wait_count: %d, continue_wait: %d, commit time: %lldus, wait time: %lldus, timeout time: %uus\n",
+				"job: %p, wait_count: %d, continue wait: %d, commit elapse time: %lldus, wait time: %lldus, timeout: %uus\n",
 				job, wait_count, continue_wait,
-				(job->commit_pc_time == 0 ? 0 : commit_time),
+				(job->hw_commit_time == 0 ? 0 : elapse_time_us),
 				ktime_us_delta(ktime_get(), job->timestamp),
 				args->timeout * 1000);
 		}
@@ -217,7 +215,7 @@
 
 	last_task = job->last_task;
 	if (!last_task) {
-		spin_lock_irqsave(&rknpu_dev->lock, flags);
+		spin_lock_irqsave(&rknpu_dev->irq_lock, flags);
 		for (i = 0; i < job->use_core_num; i++) {
 			subcore_data = &rknpu_dev->subcore_datas[i];
 			list_for_each_entry_safe(
@@ -259,6 +257,7 @@
 		return -EINVAL;
 
 	args->task_counter = args->task_number;
+	args->hw_elapse_time = job->hw_elapse_time;
 
 	return 0;
 }
@@ -289,6 +288,7 @@
 	int i = 0;
 	int submit_index = atomic_read(&job->submit_count[core_index]);
 	int max_submit_number = rknpu_dev->config->max_submit_number;
+	unsigned long flags;
 
 	if (!task_obj) {
 		job->ret = -EINVAL;
@@ -334,9 +334,13 @@
 	first_task = &task_base[task_start];
 	last_task = &task_base[task_end];
 
-	spin_lock(&rknpu_dev->lock);
-	REG_WRITE(first_task->regcmd_addr, RKNPU_OFFSET_PC_DATA_ADDR);
-	spin_unlock(&rknpu_dev->lock);
+	if (rknpu_dev->config->pc_dma_ctrl) {
+		spin_lock_irqsave(&rknpu_dev->irq_lock, flags);
+		REG_WRITE(first_task->regcmd_addr, RKNPU_OFFSET_PC_DATA_ADDR);
+		spin_unlock_irqrestore(&rknpu_dev->irq_lock, flags);
+	} else {
+		REG_WRITE(first_task->regcmd_addr, RKNPU_OFFSET_PC_DATA_ADDR);
+	}
 
 	REG_WRITE((first_task->regcfg_amount + RKNPU_PC_DATA_EXTRA_AMOUNT +
 		   pc_data_amount_scale - 1) /
@@ -363,16 +367,22 @@
 	return 0;
 }
 
-static inline int rknpu_job_subcore_commit(struct rknpu_job *job, int core_index)
+static inline int rknpu_job_subcore_commit(struct rknpu_job *job,
+					   int core_index)
 {
 	struct rknpu_device *rknpu_dev = job->rknpu_dev;
 	struct rknpu_submit *args = job->args;
 	void __iomem *rknpu_core_base = rknpu_dev->base[core_index];
+	unsigned long flags;
 
 	// switch to slave mode
-	spin_lock(&rknpu_dev->lock);
-	REG_WRITE(0x1, RKNPU_OFFSET_PC_DATA_ADDR);
-	spin_unlock(&rknpu_dev->lock);
+	if (rknpu_dev->config->pc_dma_ctrl) {
+		spin_lock_irqsave(&rknpu_dev->irq_lock, flags);
+		REG_WRITE(0x1, RKNPU_OFFSET_PC_DATA_ADDR);
+		spin_unlock_irqrestore(&rknpu_dev->irq_lock, flags);
+	} else {
+		REG_WRITE(0x1, RKNPU_OFFSET_PC_DATA_ADDR);
+	}
 
 	if (!(args->flags & RKNPU_JOB_PC)) {
 		job->ret = -EINVAL;
@@ -384,7 +394,7 @@
 
 static void rknpu_job_commit(struct rknpu_job *job)
 {
-	switch (job->args->core_mask & ((1 << RKNPU_MAX_CORES) - 1)) {
+	switch (job->args->core_mask) {
 	case RKNPU_CORE0_MASK:
 		rknpu_job_subcore_commit(job, 0);
 		break;
@@ -432,8 +442,8 @@
 
 	list_del_init(&job->head[core_index]);
 	subcore_data->job = job;
-	job->hw_recoder_time = ktime_get();
-	job->commit_pc_time = job->hw_recoder_time;
+	job->hw_commit_time = ktime_get();
+	job->hw_recoder_time = job->hw_commit_time;
 	spin_unlock_irqrestore(&rknpu_dev->irq_lock, flags);
 
 	if (atomic_dec_and_test(&job->run_count)) {
@@ -445,13 +455,14 @@
 {
 	struct rknpu_device *rknpu_dev = job->rknpu_dev;
 	struct rknpu_subcore_data *subcore_data = NULL;
+	ktime_t now;
 	unsigned long flags;
 	int max_submit_number = rknpu_dev->config->max_submit_number;
 
 	if (atomic_inc_return(&job->submit_count[core_index]) <
 	    (rknpu_get_task_number(job, core_index) + max_submit_number - 1) /
 		    max_submit_number) {
-		rknpu_job_commit(job);
+		rknpu_job_subcore_commit(job, core_index);
 		return;
 	}
 
@@ -460,8 +471,9 @@
 	spin_lock_irqsave(&rknpu_dev->irq_lock, flags);
 	subcore_data->job = NULL;
 	subcore_data->task_num -= rknpu_get_task_number(job, core_index);
-	subcore_data->timer.busy_time +=
-		ktime_us_delta(ktime_get(), job->hw_recoder_time);
+	now = ktime_get();
+	job->hw_elapse_time = ktime_sub(now, job->hw_commit_time);
+	subcore_data->timer.busy_time += ktime_sub(now, job->hw_recoder_time);
 	spin_unlock_irqrestore(&rknpu_dev->irq_lock, flags);
 
 	if (atomic_dec_and_test(&job->interrupt_count)) {
@@ -485,44 +497,32 @@
 	rknpu_job_next(rknpu_dev, core_index);
 }
 
+static int rknpu_schedule_core_index(struct rknpu_device *rknpu_dev)
+{
+	int core_num = rknpu_dev->config->num_irqs;
+	int task_num = rknpu_dev->subcore_datas[0].task_num;
+	int core_index = 0;
+	int i = 0;
+
+	for (i = 1; i < core_num; i++) {
+		if (task_num > rknpu_dev->subcore_datas[i].task_num) {
+			core_index = i;
+			task_num = rknpu_dev->subcore_datas[i].task_num;
+		}
+	}
+
+	return core_index;
+}
+
 static void rknpu_job_schedule(struct rknpu_job *job)
 {
 	struct rknpu_device *rknpu_dev = job->rknpu_dev;
 	struct rknpu_subcore_data *subcore_data = NULL;
 	int i = 0, core_index = 0;
 	unsigned long flags;
-	int task_num_list[3] = { 0, 1, 2 };
-	int tmp = 0;
 
-	if ((job->args->core_mask & ((1 << RKNPU_MAX_CORES) - 1)) ==
-	    RKNPU_CORE_AUTO_MASK) {
-		if (rknpu_dev->subcore_datas[0].task_num >
-		    rknpu_dev->subcore_datas[1].task_num) {
-			tmp = task_num_list[1];
-			task_num_list[1] = task_num_list[0];
-			task_num_list[0] = tmp;
-		}
-		if (rknpu_dev->subcore_datas[task_num_list[0]].task_num >
-		    rknpu_dev->subcore_datas[2].task_num) {
-			tmp = task_num_list[2];
-			task_num_list[2] = task_num_list[1];
-			task_num_list[1] = task_num_list[0];
-			task_num_list[0] = tmp;
-		} else if (rknpu_dev->subcore_datas[task_num_list[1]].task_num >
-			   rknpu_dev->subcore_datas[2].task_num) {
-			tmp = task_num_list[2];
-			task_num_list[2] = task_num_list[1];
-			task_num_list[1] = tmp;
-		}
-		if (!rknpu_dev->subcore_datas[task_num_list[0]].job)
-			core_index = task_num_list[0];
-		else if (!rknpu_dev->subcore_datas[task_num_list[1]].job)
-			core_index = task_num_list[1];
-		else if (!rknpu_dev->subcore_datas[task_num_list[2]].job)
-			core_index = task_num_list[2];
-		else
-			core_index = task_num_list[0];
-
+	if (job->args->core_mask == RKNPU_CORE_AUTO_MASK) {
+		core_index = rknpu_schedule_core_index(rknpu_dev);
 		job->args->core_mask = rknpu_core_mask(core_index);
 		job->use_core_num = 1;
 		atomic_set(&job->run_count, job->use_core_num);
@@ -739,6 +739,11 @@
 		return -EINVAL;
 	}
 
+	if (args->core_mask > rknpu_dev->config->core_mask) {
+		LOG_ERROR("invalid rknpu core mask: %#x", args->core_mask);
+		return -EINVAL;
+	}
+
 	job = rknpu_job_alloc(rknpu_dev, args);
 	if (!job) {
 		LOG_ERROR("failed to allocate rknpu job!\n");
@@ -936,27 +941,30 @@
 int rknpu_clear_rw_amount(struct rknpu_device *rknpu_dev)
 {
 	void __iomem *rknpu_core_base = rknpu_dev->base[0];
+	unsigned long flags;
 
 	if (!rknpu_dev->config->bw_enable) {
 		LOG_WARN("Clear rw_amount is not supported on this device!\n");
 		return 0;
 	}
 
-	spin_lock(&rknpu_dev->lock);
-
 	if (rknpu_dev->config->pc_dma_ctrl) {
-		uint32_t pc_data_addr = REG_READ(RKNPU_OFFSET_PC_DATA_ADDR);
+		uint32_t pc_data_addr = 0;
+
+		spin_lock_irqsave(&rknpu_dev->irq_lock, flags);
+		pc_data_addr = REG_READ(RKNPU_OFFSET_PC_DATA_ADDR);
 
 		REG_WRITE(0x1, RKNPU_OFFSET_PC_DATA_ADDR);
 		REG_WRITE(0x80000101, RKNPU_OFFSET_CLR_ALL_RW_AMOUNT);
 		REG_WRITE(0x00000101, RKNPU_OFFSET_CLR_ALL_RW_AMOUNT);
 		REG_WRITE(pc_data_addr, RKNPU_OFFSET_PC_DATA_ADDR);
+		spin_unlock_irqrestore(&rknpu_dev->irq_lock, flags);
 	} else {
+		spin_lock(&rknpu_dev->lock);
 		REG_WRITE(0x80000101, RKNPU_OFFSET_CLR_ALL_RW_AMOUNT);
 		REG_WRITE(0x00000101, RKNPU_OFFSET_CLR_ALL_RW_AMOUNT);
+		spin_unlock(&rknpu_dev->lock);
 	}
-
-	spin_unlock(&rknpu_dev->lock);
 
 	return 0;
 }
diff --git a/kernel/drivers/rknpu/rknpu_mem.c b/kernel/drivers/rknpu/rknpu_mem.c
index 5242f15..858c21f 100644
--- a/kernel/drivers/rknpu/rknpu_mem.c
+++ b/kernel/drivers/rknpu/rknpu_mem.c
@@ -109,22 +109,27 @@
 			  __LINE__, &phys, length);
 	}
 
-	page_count = length >> PAGE_SHIFT;
-	pages = vmalloc(page_count * sizeof(struct page));
-	if (!pages) {
-		LOG_ERROR("alloc pages failed\n");
-		ret = -ENOMEM;
-		goto err_detach_dma_buf;
-	}
+	if (args.flags & RKNPU_MEM_KERNEL_MAPPING) {
+		page_count = length >> PAGE_SHIFT;
+		pages = vmalloc(page_count * sizeof(struct page));
+		if (!pages) {
+			LOG_ERROR("alloc pages failed\n");
+			ret = -ENOMEM;
+			goto err_detach_dma_buf;
+		}
 
-	for (i = 0; i < page_count; i++)
-		pages[i] = &page[i];
+		for (i = 0; i < page_count; i++)
+			pages[i] = &page[i];
 
-	rknpu_obj->kv_addr = vmap(pages, page_count, VM_MAP, PAGE_KERNEL);
-	if (!rknpu_obj->kv_addr) {
-		LOG_ERROR("vmap pages addr failed\n");
-		ret = -ENOMEM;
-		goto err_free_pages;
+		rknpu_obj->kv_addr =
+			vmap(pages, page_count, VM_MAP, PAGE_KERNEL);
+		if (!rknpu_obj->kv_addr) {
+			LOG_ERROR("vmap pages addr failed\n");
+			ret = -ENOMEM;
+			goto err_free_pages;
+		}
+		vfree(pages);
+		pages = NULL;
 	}
 
 	rknpu_obj->size = PAGE_ALIGN(args.size);
@@ -148,8 +153,6 @@
 		goto err_unmap_kv_addr;
 	}
 
-	vfree(pages);
-	pages = NULL;
 	dma_buf_unmap_attachment(attachment, table, DMA_BIDIRECTIONAL);
 	dma_buf_detach(dmabuf, attachment);
 
diff --git a/kernel/drivers/rpmsg/Kconfig b/kernel/drivers/rpmsg/Kconfig
index 3b547a7..267443a 100644
--- a/kernel/drivers/rpmsg/Kconfig
+++ b/kernel/drivers/rpmsg/Kconfig
@@ -58,8 +58,8 @@
 	  providing communication channels to remote processors in Qualcomm
 	  platforms.
 
-config RPMSG_ROCKCHIP
-	tristate "Rockchip Platform RPMsg Support"
+config RPMSG_ROCKCHIP_MBOX
+	tristate "Rockchip Platform RPMsg Mailbox Mode Support"
 	depends on ARCH_ROCKCHIP
 	depends on MAILBOX
 	depends on ROCKCHIP_MBOX
@@ -67,11 +67,20 @@
 	select VIRTIO
 	help
 	  Say y here to enable support for The Remote Processors Messasing
-	  in Rockchip Platform.
+	  using mailbox mode in Rockchip Platform.
+
+config RPMSG_ROCKCHIP_SOFTIRQ
+	tristate "Rockchip Platform RPMsg Soft IRQ Mode Support"
+	depends on ARCH_ROCKCHIP
+	select RPMSG
+	select VIRTIO
+	help
+	  Say y here to enable support for The Remote Processors Messasing
+	  using softirq mode in Rockchip Platform.
 
 config RPMSG_ROCKCHIP_TEST
 	tristate "Rockchip RPMsg Test"
-	depends on RPMSG_ROCKCHIP
+	depends on (RPMSG_ROCKCHIP_MBOX || RPMSG_ROCKCHIP_SOFTIRQ)
 	help
 	  Say y here to enable Rockchip RPMsg Test.
 
diff --git a/kernel/drivers/rpmsg/Makefile b/kernel/drivers/rpmsg/Makefile
index bb767a4..d7cf1db 100644
--- a/kernel/drivers/rpmsg/Makefile
+++ b/kernel/drivers/rpmsg/Makefile
@@ -7,6 +7,7 @@
 obj-$(CONFIG_RPMSG_QCOM_GLINK_RPM) += qcom_glink_rpm.o
 obj-$(CONFIG_RPMSG_QCOM_GLINK_SMEM) += qcom_glink_smem.o
 obj-$(CONFIG_RPMSG_QCOM_SMD)	+= qcom_smd.o
-obj-$(CONFIG_RPMSG_ROCKCHIP)	+= rockchip_rpmsg.o
+obj-$(CONFIG_RPMSG_ROCKCHIP_MBOX)	+= rockchip_rpmsg_mbox.o
+obj-$(CONFIG_RPMSG_ROCKCHIP_SOFTIRQ)    += rockchip_rpmsg_softirq.o
 obj-$(CONFIG_RPMSG_ROCKCHIP_TEST)	+= rockchip_rpmsg_test.o
 obj-$(CONFIG_RPMSG_VIRTIO)	+= virtio_rpmsg_bus.o
diff --git a/kernel/drivers/rpmsg/qcom_glink_native.c b/kernel/drivers/rpmsg/qcom_glink_native.c
index 7cbed03..e776d1b 100644
--- a/kernel/drivers/rpmsg/qcom_glink_native.c
+++ b/kernel/drivers/rpmsg/qcom_glink_native.c
@@ -222,6 +222,10 @@
 
 	channel->glink = glink;
 	channel->name = kstrdup(name, GFP_KERNEL);
+	if (!channel->name) {
+		kfree(channel);
+		return ERR_PTR(-ENOMEM);
+	}
 
 	init_completion(&channel->open_req);
 	init_completion(&channel->open_ack);
@@ -929,6 +933,7 @@
 	spin_unlock_irqrestore(&glink->idr_lock, flags);
 	if (!channel) {
 		dev_err(glink->dev, "intents for non-existing channel\n");
+		qcom_glink_rx_advance(glink, ALIGN(msglen, 8));
 		return;
 	}
 
diff --git a/kernel/drivers/rpmsg/rockchip_rpmsg.c b/kernel/drivers/rpmsg/rockchip_rpmsg_mbox.c
similarity index 97%
rename from kernel/drivers/rpmsg/rockchip_rpmsg.c
rename to kernel/drivers/rpmsg/rockchip_rpmsg_mbox.c
index 8977125..c70e89b 100644
--- a/kernel/drivers/rpmsg/rockchip_rpmsg.c
+++ b/kernel/drivers/rpmsg/rockchip_rpmsg_mbox.c
@@ -383,8 +383,16 @@
 
 static int rockchip_rpmsg_remove(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
 	struct rk_rpmsg_dev *rpdev = platform_get_drvdata(pdev);
 
+	int i;
+
+	for (i = 0; i < rpdev->vdev_nums; i++)
+		unregister_virtio_device(&rpdev->rpvdev[i]->vdev);
+
+	of_reserved_mem_device_release(dev);
+
 	mbox_free_channel(rpdev->mbox_rx_chan);
 	mbox_free_channel(rpdev->mbox_tx_chan);
 
diff --git a/kernel/drivers/rpmsg/rockchip_rpmsg.c b/kernel/drivers/rpmsg/rockchip_rpmsg_softirq.c
similarity index 78%
copy from kernel/drivers/rpmsg/rockchip_rpmsg.c
copy to kernel/drivers/rpmsg/rockchip_rpmsg_softirq.c
index 8977125..df3c77b 100644
--- a/kernel/drivers/rpmsg/rockchip_rpmsg.c
+++ b/kernel/drivers/rpmsg/rockchip_rpmsg_softirq.c
@@ -2,17 +2,18 @@
 /*
  * Rockchip Remote Processors Messaging Platform Support.
  *
- * Copyright (c) 2022 Rockchip Electronics Co. Ltd.
- * Author: Steven Liu <steven.liu@rock-chips.com>
+ * Copyright (c) 2023 Rockchip Electronics Co. Ltd.
+ * Author: Hongming Zou <hongming.zou@rock-chips.com>
  */
 
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqreturn.h>
+#include <linux/of_irq.h>
 #include <linux/kernel.h>
-#include <linux/mailbox_client.h>
-#include <linux/mailbox_controller.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/of_reserved_mem.h>
@@ -22,7 +23,6 @@
 #include <linux/virtio_config.h>
 #include <linux/virtio_ids.h>
 #include <linux/virtio_ring.h>
-#include <soc/rockchip/rockchip-mailbox.h>
 
 #include "rpmsg_internal.h"
 
@@ -35,6 +35,11 @@
 	struct rk_rpmsg_dev *rpdev;
 };
 
+struct rk_rpmsg_irqs {
+	int irq_tx;
+	int irq_rx;
+};
+
 #define to_rk_rpvdev(vd)	container_of(vd, struct rk_virtio_dev, vdev)
 
 struct rk_rpmsg_dev {
@@ -43,10 +48,8 @@
 	unsigned int link_id;
 	int first_notify;
 	u32 flags;
-	struct mbox_client mbox_cl;
-	struct mbox_chan *mbox_rx_chan;
-	struct mbox_chan *mbox_tx_chan;
 	struct rk_virtio_dev *rpvdev[RPMSG_MAX_INSTANCE_NUM];
+	struct rk_rpmsg_irqs irqs;
 };
 
 struct rk_rpmsg_vq_info {
@@ -55,26 +58,21 @@
 	struct rk_rpmsg_dev *rpdev;
 };
 
-static void rk_rpmsg_rx_callback(struct mbox_client *client, void *message)
+static irqreturn_t rk_rpmsg_rx_callback(int irq, void *_pdev)
 {
 	u32 link_id;
+	struct platform_device *pdev = _pdev;
 	struct rk_virtio_dev *rpvdev;
-	struct rk_rpmsg_dev *rpdev = container_of(client, struct rk_rpmsg_dev, mbox_cl);
-	struct platform_device *pdev = rpdev->pdev;
+	struct rk_rpmsg_dev *rpdev = platform_get_drvdata(pdev);
 	struct device *dev = &pdev->dev;
-	struct rockchip_mbox_msg *rx_msg;
 
-	rx_msg = message;
-	dev_dbg(dev, "rpmsg master: receive cmd=0x%x data=0x%x\n",
-		rx_msg->cmd, rx_msg->data);
-	if (rx_msg->data != RPMSG_MBOX_MAGIC)
-		dev_err(dev, "rpmsg master: mailbox data error!\n");
-	link_id = rx_msg->cmd & 0xFFU;
-	/* TODO: only support one remote core now */
+	link_id = rpdev->link_id;
 	rpvdev = rpdev->rpvdev[0];
 	rpdev->flags |= RPMSG_REMOTE_IS_READY;
 	dev_dbg(dev, "rpmsg master: rx link_id=0x%x flag=0x%x\n", link_id, rpdev->flags);
 	vring_interrupt(0, rpvdev->vq[0]);
+
+	return IRQ_HANDLED;
 }
 
 static bool rk_rpmsg_notify(struct virtqueue *vq)
@@ -83,17 +81,12 @@
 	struct rk_rpmsg_dev *rpdev = rpvq->rpdev;
 	struct platform_device *pdev = rpdev->pdev;
 	struct device *dev = &pdev->dev;
-	u32 link_id;
-	int ret;
-	struct rockchip_mbox_msg tx_msg;
+	struct irq_chip *chip;
 
-	memset(&tx_msg, 0, sizeof(tx_msg));
+	chip = irq_get_chip(rpdev->irqs.irq_tx);
+
 	dev_dbg(dev, "queue_id-0x%x virt_vring_addr 0x%p\n",
 		rpvq->queue_id, rpvq->vring_addr);
-
-	link_id = rpdev->link_id;
-	tx_msg.cmd = link_id & 0xFFU;
-	tx_msg.data = RPMSG_MBOX_MAGIC;
 
 	if ((rpdev->first_notify == 0) && (rpvq->queue_id % 2 == 0)) {
 		/* first_notify is used in the master init handshake phase. */
@@ -103,11 +96,9 @@
 		/* tx done is not supported, so ignored */
 		return true;
 	}
-	ret = mbox_send_message(rpdev->mbox_tx_chan, &tx_msg);
-	if (ret < 0) {
-		dev_err(dev, "mbox send failed!\n");
-		return false;
-	}
+
+	if (chip && chip->irq_retrigger)
+		chip->irq_retrigger(irq_get_irq_data(rpdev->irqs.irq_tx));
 
 	return true;
 }
@@ -292,7 +283,7 @@
 {
 	struct device *dev = &pdev->dev;
 	struct rk_rpmsg_dev *rpdev = NULL;
-	struct mbox_client *cl;
+
 	int i, ret = 0;
 
 	rpdev = devm_kzalloc(dev, sizeof(*rpdev), GFP_KERNEL);
@@ -303,44 +294,46 @@
 	rpdev->pdev = pdev;
 	rpdev->first_notify = 0;
 
-	cl = &rpdev->mbox_cl;
-	cl->dev = dev;
-	cl->rx_callback = rk_rpmsg_rx_callback;
-
-	rpdev->mbox_rx_chan = mbox_request_channel_byname(cl, "rpmsg-rx");
-	if (IS_ERR(rpdev->mbox_rx_chan)) {
-		ret = PTR_ERR(rpdev->mbox_rx_chan);
-		dev_err(dev, "failed to request mbox rx chan, ret %d\n", ret);
-		return ret;
-	}
-	rpdev->mbox_tx_chan = mbox_request_channel_byname(cl, "rpmsg-tx");
-	if (IS_ERR(rpdev->mbox_tx_chan)) {
-		ret = PTR_ERR(rpdev->mbox_tx_chan);
-		dev_err(dev, "failed to request mbox tx chan, ret %d\n", ret);
-		return ret;
-	}
-
 	ret = device_property_read_u32(dev, "rockchip,link-id", &rpdev->link_id);
 	if (ret) {
 		dev_err(dev, "failed to get link_id, ret %d\n", ret);
-		goto free_channel;
+
+		return ret;
 	}
 	ret = device_property_read_u32(dev, "rockchip,vdev-nums", &rpdev->vdev_nums);
 	if (ret) {
 		dev_info(dev, "vdev-nums default 1\n");
 		rpdev->vdev_nums = 1;
+
+		return ret;
 	}
 	if (rpdev->vdev_nums > RPMSG_MAX_INSTANCE_NUM) {
 		dev_err(dev, "vdev-nums exceed the max %d\n", RPMSG_MAX_INSTANCE_NUM);
-		ret = -EINVAL;
-		goto free_channel;
+
+		return -EINVAL;
+	}
+
+	rpdev->irqs.irq_tx = platform_get_irq(pdev, 0);
+	if (rpdev->irqs.irq_tx < 0)
+		return rpdev->irqs.irq_tx;
+
+	rpdev->irqs.irq_rx = platform_get_irq(pdev, 1);
+	if (rpdev->irqs.irq_rx < 0)
+		return rpdev->irqs.irq_rx;
+
+	ret = devm_request_threaded_irq(&pdev->dev, rpdev->irqs.irq_rx, NULL, rk_rpmsg_rx_callback,
+		IRQF_ONESHOT, "rockchip-rpmsg", pdev);
+	if (ret) {
+		dev_err(dev, "could not install irq");
+
+		return ret;
 	}
 
 	ret = rk_set_vring_phy_buf(pdev, rpdev, rpdev->vdev_nums);
 	if (ret) {
 		dev_err(dev, "No vring buffer.\n");
-		ret = -ENOMEM;
-		goto free_channel;
+
+		return -EINVAL;
 	}
 	if (of_reserved_mem_device_init(dev)) {
 		dev_info(dev, "No shared DMA pool.\n");
@@ -374,41 +367,41 @@
 	if (rpdev->flags & RPMSG_SHARED_DMA_POOL)
 		of_reserved_mem_device_release(dev);
 
-free_channel:
-	mbox_free_channel(rpdev->mbox_rx_chan);
-	mbox_free_channel(rpdev->mbox_tx_chan);
-
 	return ret;
 }
 
 static int rockchip_rpmsg_remove(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
 	struct rk_rpmsg_dev *rpdev = platform_get_drvdata(pdev);
 
-	mbox_free_channel(rpdev->mbox_rx_chan);
-	mbox_free_channel(rpdev->mbox_tx_chan);
+	int i;
+
+	for (i = 0; i < rpdev->vdev_nums; i++)
+		unregister_virtio_device(&rpdev->rpvdev[i]->vdev);
+
+	of_reserved_mem_device_release(dev);
 
 	return 0;
 }
 
 static const struct of_device_id rockchip_rpmsg_match[] = {
-	{ .compatible = "rockchip,rpmsg", },
+	{ .compatible = "rockchip,rpmsg-softirq", },
 	{ /* sentinel */ },
 };
 
 MODULE_DEVICE_TABLE(of, rockchip_rpmsg_match);
 
-static struct platform_driver rockchip_rpmsg_driver = {
+static struct platform_driver rockchip_rpmsg_softirq_driver = {
 	.probe = rockchip_rpmsg_probe,
 	.remove = rockchip_rpmsg_remove,
 	.driver = {
-		.name = "rockchip-rpmsg",
+		.name = "rockchip-rpmsg-softirq",
 		.of_match_table = rockchip_rpmsg_match,
 	},
 };
-module_platform_driver(rockchip_rpmsg_driver);
+module_platform_driver(rockchip_rpmsg_softirq_driver);
 
 MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Rockchip Remote Processors Messaging Platform Support");
-MODULE_AUTHOR("Steven Liu <steven.liu@rock-chips.com>");
-
+MODULE_DESCRIPTION("Rockchip Using Softirq Mode Remote Processors Messaging Platform Support");
+MODULE_AUTHOR("Hongming Zou <hongming.zou@rock-chips.com>");
diff --git a/kernel/drivers/rpmsg/rpmsg_core.c b/kernel/drivers/rpmsg/rpmsg_core.c
index 2037a46..dc9e9d2 100644
--- a/kernel/drivers/rpmsg/rpmsg_core.c
+++ b/kernel/drivers/rpmsg/rpmsg_core.c
@@ -319,6 +319,29 @@
 }
 EXPORT_SYMBOL(rpmsg_set_signals);
 
+#ifdef CONFIG_NO_GKI
+/**
+ * rpmsg_get_mtu() - get maximum transmission buffer size for sending message.
+ * @ept: the rpmsg endpoint
+ *
+ * This function returns maximum buffer size available for a single outgoing message.
+ *
+ * Return: the maximum transmission size on success and an appropriate error
+ * value on failure.
+ */
+
+ssize_t rpmsg_get_mtu(struct rpmsg_endpoint *ept)
+{
+	if (WARN_ON(!ept))
+		return -EINVAL;
+	if (!ept->ops->get_mtu)
+		return -ENOTSUPP;
+
+	return ept->ops->get_mtu(ept);
+}
+EXPORT_SYMBOL(rpmsg_get_mtu);
+#endif
+
 /*
  * match a rpmsg channel with a channel info struct.
  * this is used to make sure we're not creating rpmsg devices for channels
diff --git a/kernel/drivers/rpmsg/rpmsg_internal.h b/kernel/drivers/rpmsg/rpmsg_internal.h
index 03356e8..70f5667 100644
--- a/kernel/drivers/rpmsg/rpmsg_internal.h
+++ b/kernel/drivers/rpmsg/rpmsg_internal.h
@@ -50,6 +50,7 @@
  * @poll:		see @rpmsg_poll(), optional
  * @get_signals:	see @rpmsg_get_signals(), optional
  * @set_signals:	see @rpmsg_set_signals(), optional
+ * @get_mtu:		see @rpmsg_get_mtu(), optional
  *
  * Indirection table for the operations that a rpmsg backend should implement.
  * In addition to @destroy_ept, the backend must at least implement @send and
@@ -71,6 +72,9 @@
 			     poll_table *wait);
 	int (*get_signals)(struct rpmsg_endpoint *ept);
 	int (*set_signals)(struct rpmsg_endpoint *ept, u32 set, u32 clear);
+#ifdef CONFIG_NO_GKI
+	ssize_t (*get_mtu)(struct rpmsg_endpoint *ept);
+#endif
 };
 
 int rpmsg_register_device(struct rpmsg_device *rpdev);
diff --git a/kernel/drivers/rpmsg/virtio_rpmsg_bus.c b/kernel/drivers/rpmsg/virtio_rpmsg_bus.c
index 7d7ed4e..4abc861 100644
--- a/kernel/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/kernel/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -181,6 +181,7 @@
 				  int len, u32 dst);
 static int virtio_rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src,
 					   u32 dst, void *data, int len);
+static ssize_t virtio_rpmsg_get_mtu(struct rpmsg_endpoint *ept);
 
 static const struct rpmsg_endpoint_ops virtio_endpoint_ops = {
 	.destroy_ept = virtio_rpmsg_destroy_ept,
@@ -190,6 +191,7 @@
 	.trysend = virtio_rpmsg_trysend,
 	.trysendto = virtio_rpmsg_trysendto,
 	.trysend_offchannel = virtio_rpmsg_trysend_offchannel,
+	.get_mtu = virtio_rpmsg_get_mtu,
 };
 
 /**
@@ -705,6 +707,14 @@
 	return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false);
 }
 
+static ssize_t virtio_rpmsg_get_mtu(struct rpmsg_endpoint *ept)
+{
+	struct rpmsg_device *rpdev = ept->rpdev;
+	struct virtio_rpmsg_channel *vch = to_virtio_rpmsg_channel(rpdev);
+
+	return vch->vrp->buf_size - sizeof(struct rpmsg_hdr);
+}
+
 static int rpmsg_recv_single(struct virtproc_info *vrp, struct device *dev,
 			     struct rpmsg_hdr *msg, unsigned int len)
 {
diff --git a/kernel/drivers/rtc/Kconfig b/kernel/drivers/rtc/Kconfig
index 0cfdb71..ca270c7 100644
--- a/kernel/drivers/rtc/Kconfig
+++ b/kernel/drivers/rtc/Kconfig
@@ -374,6 +374,16 @@
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-max77686.
 
+config RTC_DRV_RK630
+	tristate "Rockchip RK630 RTC"
+	depends on MFD_RK630
+	help
+	  If you say yes here you will get support for the
+	  RTC of RK630.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-rk630.
+
 config RTC_DRV_RK808
 	tristate "Rockchip RK805/RK808/RK809/RK816/RK817/RK818 RTC"
 	depends on MFD_RK808
diff --git a/kernel/drivers/rtc/Makefile b/kernel/drivers/rtc/Makefile
index ae1e53e..80b2c1a 100644
--- a/kernel/drivers/rtc/Makefile
+++ b/kernel/drivers/rtc/Makefile
@@ -133,6 +133,7 @@
 obj-$(CONFIG_RTC_DRV_R9701)	+= rtc-r9701.o
 obj-$(CONFIG_RTC_DRV_RC5T583)	+= rtc-rc5t583.o
 obj-$(CONFIG_RTC_DRV_RC5T619)	+= rtc-rc5t619.o
+obj-$(CONFIG_RTC_DRV_RK630)	+= rtc-rk630.o
 obj-$(CONFIG_RTC_DRV_RK808)	+= rtc-rk808.o
 obj-$(CONFIG_RTC_DRV_ROCKCHIP)	+= rtc-rockchip.o
 obj-$(CONFIG_RTC_DRV_RP5C01)	+= rtc-rp5c01.o
diff --git a/kernel/drivers/rtc/rtc-cmos.c b/kernel/drivers/rtc/rtc-cmos.c
index d4f6c4d..7f56093 100644
--- a/kernel/drivers/rtc/rtc-cmos.c
+++ b/kernel/drivers/rtc/rtc-cmos.c
@@ -750,6 +750,168 @@
 		return IRQ_NONE;
 }
 
+#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 acpi_rtc_event_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 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);
+	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 acpi_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 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)
+{
+}
+
+static inline void cmos_check_acpi_rtc_status(struct device *dev,
+					      unsigned char *rtc_control)
+{
+}
+#endif /* CONFIG_ACPI */
+
 #ifdef	CONFIG_PNP
 #define	INITSECTION
 
@@ -833,18 +995,26 @@
 		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 {
+		acpi_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);
@@ -933,6 +1103,13 @@
 	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)
+		acpi_rtc_event_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" :
@@ -977,6 +1154,9 @@
 		if (use_hpet_alarm())
 			hpet_unregister_irq_handler(cmos_interrupt);
 	}
+
+	if (!dev_get_platdata(dev))
+		acpi_rtc_event_cleanup();
 
 	cmos->rtc = NULL;
 
@@ -1127,9 +1307,6 @@
 	}
 }
 
-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);
@@ -1196,174 +1373,16 @@
  * 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)
-{
-	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 (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0))
-		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
-
-/* 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)
-		return;
-
-	use_acpi_alarm_quirks();
-
-	rtc_wake_setup(dev);
-	acpi_rtc_info.wake_on = rtc_wake_on;
-	acpi_rtc_info.wake_off = rtc_wake_off;
-
-	/* workaround bug in some ACPI tables */
-	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;
-
-	/* 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);
-}
-
-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)
-{
-}
-
-#endif
-
 #ifdef	CONFIG_PNP
 
 #include <linux/pnp.h>
 
 static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
 {
-	cmos_wake_setup(&pnp->dev);
+	int irq;
 
 	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
@@ -1372,13 +1391,11 @@
 		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);
 	}
+
+	return cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
 }
 
 static void cmos_pnp_remove(struct pnp_dev *pnp)
@@ -1465,7 +1482,6 @@
 	int irq;
 
 	cmos_of_init(pdev);
-	cmos_wake_setup(&pdev->dev);
 
 	if (RTC_IOMAPPED)
 		resource = platform_get_resource(pdev, IORESOURCE_IO, 0);
diff --git a/kernel/drivers/rtc/rtc-ds1347.c b/kernel/drivers/rtc/rtc-ds1347.c
index 7025cf3..03267ac 100644
--- a/kernel/drivers/rtc/rtc-ds1347.c
+++ b/kernel/drivers/rtc/rtc-ds1347.c
@@ -112,7 +112,7 @@
 		return err;
 
 	century = (dt->tm_year / 100) + 19;
-	err = regmap_write(map, DS1347_CENTURY_REG, century);
+	err = regmap_write(map, DS1347_CENTURY_REG, bin2bcd(century));
 	if (err)
 		return err;
 
diff --git a/kernel/drivers/rtc/rtc-ds1685.c b/kernel/drivers/rtc/rtc-ds1685.c
index dfbd7b8..98932ab 100644
--- a/kernel/drivers/rtc/rtc-ds1685.c
+++ b/kernel/drivers/rtc/rtc-ds1685.c
@@ -1441,7 +1441,7 @@
 		unreachable();
 	}
 }
-EXPORT_SYMBOL(ds1685_rtc_poweroff);
+EXPORT_SYMBOL_GPL(ds1685_rtc_poweroff);
 /* ----------------------------------------------------------------------- */
 
 
diff --git a/kernel/drivers/rtc/rtc-meson-vrtc.c b/kernel/drivers/rtc/rtc-meson-vrtc.c
index e6bd080..18ff843 100644
--- a/kernel/drivers/rtc/rtc-meson-vrtc.c
+++ b/kernel/drivers/rtc/rtc-meson-vrtc.c
@@ -23,7 +23,7 @@
 	struct timespec64 time;
 
 	dev_dbg(dev, "%s\n", __func__);
-	ktime_get_raw_ts64(&time);
+	ktime_get_real_ts64(&time);
 	rtc_time64_to_tm(time.tv_sec, tm);
 
 	return 0;
@@ -96,7 +96,7 @@
 		long alarm_secs;
 		struct timespec64 time;
 
-		ktime_get_raw_ts64(&time);
+		ktime_get_real_ts64(&time);
 		local_time = time.tv_sec;
 
 		dev_dbg(dev, "alarm_time = %lus, local_time=%lus\n",
diff --git a/kernel/drivers/rtc/rtc-mxc_v2.c b/kernel/drivers/rtc/rtc-mxc_v2.c
index d349cef..48595b0 100644
--- a/kernel/drivers/rtc/rtc-mxc_v2.c
+++ b/kernel/drivers/rtc/rtc-mxc_v2.c
@@ -337,8 +337,10 @@
 	}
 
 	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;
diff --git a/kernel/drivers/rtc/rtc-omap.c b/kernel/drivers/rtc/rtc-omap.c
index c20fc79..18ae2a4 100644
--- a/kernel/drivers/rtc/rtc-omap.c
+++ b/kernel/drivers/rtc/rtc-omap.c
@@ -25,6 +25,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/rtc.h>
+#include <linux/rtc/rtc-omap.h>
 
 /*
  * The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock
diff --git a/kernel/drivers/rtc/rtc-pcf85063.c b/kernel/drivers/rtc/rtc-pcf85063.c
index 62684ca..449204d 100644
--- a/kernel/drivers/rtc/rtc-pcf85063.c
+++ b/kernel/drivers/rtc/rtc-pcf85063.c
@@ -167,10 +167,10 @@
 	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)
@@ -430,7 +430,7 @@
 	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;
diff --git a/kernel/drivers/rtc/rtc-pic32.c b/kernel/drivers/rtc/rtc-pic32.c
index 2b69467..7be1ca1 100644
--- a/kernel/drivers/rtc/rtc-pic32.c
+++ b/kernel/drivers/rtc/rtc-pic32.c
@@ -324,15 +324,15 @@
 
 	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;
diff --git a/kernel/drivers/rtc/rtc-pm8xxx.c b/kernel/drivers/rtc/rtc-pm8xxx.c
index b45ee2c..3417eef 100644
--- a/kernel/drivers/rtc/rtc-pm8xxx.c
+++ b/kernel/drivers/rtc/rtc-pm8xxx.c
@@ -219,7 +219,6 @@
 {
 	int rc, i;
 	u8 value[NUM_8_BIT_RTC_REGS];
-	unsigned int ctrl_reg;
 	unsigned long secs, irq_flags;
 	struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
 	const struct pm8xxx_rtc_regs *regs = rtc_dd->regs;
@@ -231,6 +230,11 @@
 		secs >>= 8;
 	}
 
+	rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl,
+				regs->alarm_en, 0);
+	if (rc)
+		return rc;
+
 	spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags);
 
 	rc = regmap_bulk_write(rtc_dd->regmap, regs->alarm_rw, value,
@@ -240,19 +244,11 @@
 		goto rtc_rw_fail;
 	}
 
-	rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg);
-	if (rc)
-		goto rtc_rw_fail;
-
-	if (alarm->enabled)
-		ctrl_reg |= regs->alarm_en;
-	else
-		ctrl_reg &= ~regs->alarm_en;
-
-	rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg);
-	if (rc) {
-		dev_err(dev, "Write to RTC alarm control register failed\n");
-		goto rtc_rw_fail;
+	if (alarm->enabled) {
+		rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl,
+					regs->alarm_en, regs->alarm_en);
+		if (rc)
+			goto rtc_rw_fail;
 	}
 
 	dev_dbg(dev, "Alarm Set for h:m:s=%ptRt, y-m-d=%ptRdr\n",
diff --git a/kernel/drivers/rtc/rtc-rk630.c b/kernel/drivers/rtc/rtc-rk630.c
new file mode 100644
index 0000000..c9c0891
--- /dev/null
+++ b/kernel/drivers/rtc/rtc-rk630.c
@@ -0,0 +1,637 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd
+ */
+#include <linux/bcd.h>
+#include <linux/kernel.h>
+#include <linux/mfd/rk630.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+/* RTC_CTRL_REG bitfields */
+#define RTC_CTRL_REG_START_RTC		BIT(0)
+
+/* RK630 has a shadowed register for saving a "frozen" RTC time.
+ * When user setting "GET_TIME" to 1, the time will save in this shadowed
+ * register. If set "READSEL" to 1, user read rtc time register, actually
+ * get the time of that moment. If we need the real time, clr this bit.
+ */
+#define RTC_CTRL_REG_RTC_GET_TIME	BIT(6)
+#define RTC_CTRL_REG_RTC_READSEL_M	BIT(7)
+#define RTC_INT_REG_ALARM_EN		BIT(7)
+
+#define RTC_STATUS_MASK			0xFF
+
+#define SECONDS_REG_MSK			0x7F
+#define MINUTES_REG_MAK			0x7F
+#define HOURS_REG_MSK			0x3F
+#define DAYS_REG_MSK			0x3F
+#define MONTHS_REG_MSK			0x1F
+#define YEARS_REG_MSK			0xFF
+#define WEEKS_REG_MSK			0x7
+
+#define RTC_VREF_INIT			0x40
+#define RTC_XO_START_MIR		0x40
+
+#define NUM_TIME_REGS			8
+#define NUM_ALARM_REGS			7
+
+#define DISABLE_ALARM_INT		0x3F
+#define ENABLE_ALARM_INT		0xFF
+#define ALARM_INT_STATUS		BIT(4)
+
+#define CLK32K_TEST_EN			BIT(0)
+#define CLK32K_TEST_START		BIT(0)
+#define CLK32K_TEST_STATUS		BIT(1)
+#define CLK32K_TEST_DONE		BIT(2)
+#define CLK32K_TEST_LEN			2
+
+#define CLK32K_COMP_DIR_ADD		BIT(7)
+#define CLK32K_COMP_EN			BIT(2)
+#define CLK32K_NO_COMP			0x1
+
+#define CLK32K_TEST_REF_CLK		25000000
+
+struct rk630_rtc {
+	struct rk630 *rk630;
+	struct rtc_device *rtc;
+	int irq;
+	unsigned int flag;
+};
+
+/* Read current time and date in RTC */
+static int rk630_rtc_readtime(struct device *dev, struct rtc_time *tm)
+{
+	struct rk630_rtc *rk630_rtc = dev_get_drvdata(dev);
+	struct rk630 *rk630 = rk630_rtc->rk630;
+	u32 rtc_data[NUM_TIME_REGS];
+	int ret;
+	int yearl, yearh;
+
+	/* Force an update of the shadowed registers right now */
+	ret = regmap_update_bits(rk630->rtc, RTC_CTRL,
+				 RTC_CTRL_REG_RTC_GET_TIME,
+				 RTC_CTRL_REG_RTC_GET_TIME);
+	if (ret) {
+		dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret);
+		return ret;
+	}
+
+	/*
+	 * After we set the GET_TIME bit, the rtc time can't be read
+	 * immediately. So we should wait up to 31.25 us, about one cycle of
+	 * 32khz. If we clear the GET_TIME bit here, the time of i2c transfer
+	 * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
+	 */
+	ret = regmap_update_bits(rk630->rtc, RTC_CTRL,
+				 RTC_CTRL_REG_RTC_GET_TIME,
+				 0);
+	if (ret) {
+		dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret);
+		return ret;
+	}
+
+	ret = regmap_bulk_read(rk630->rtc, RTC_SET_SECONDS,
+			       rtc_data, NUM_TIME_REGS);
+	if (ret) {
+		dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret);
+		return ret;
+	}
+
+	tm->tm_sec = bcd2bin(rtc_data[0] & SECONDS_REG_MSK);
+	tm->tm_min = bcd2bin(rtc_data[1] & MINUTES_REG_MAK);
+	tm->tm_hour = bcd2bin(rtc_data[2] & HOURS_REG_MSK);
+	tm->tm_mday = bcd2bin(rtc_data[3] & DAYS_REG_MSK);
+	tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK)) - 1;
+	yearl = (bcd2bin(rtc_data[5] & YEARS_REG_MSK));
+	yearh = (bcd2bin(rtc_data[6] & YEARS_REG_MSK));
+	tm->tm_year = yearh * 100 + yearl + 100;
+	tm->tm_wday = bcd2bin(rtc_data[7] & WEEKS_REG_MSK);
+
+	dev_dbg(dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+		1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
+		tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	return ret;
+}
+
+/* Set current time and date in RTC */
+static int rk630_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct rk630_rtc *rk630_rtc = dev_get_drvdata(dev);
+	struct rk630 *rk630 = rk630_rtc->rk630;
+	u32 rtc_data[NUM_TIME_REGS];
+	int ret;
+	int yearl, yearh;
+
+	dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+		1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
+		tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	rtc_data[0] = bin2bcd(tm->tm_sec);
+	rtc_data[1] = bin2bcd(tm->tm_min);
+	rtc_data[2] = bin2bcd(tm->tm_hour);
+	rtc_data[3] = bin2bcd(tm->tm_mday);
+	rtc_data[4] = bin2bcd(tm->tm_mon + 1);
+	if (tm->tm_year > 199) {
+		yearh = (tm->tm_year - 100) / 100;
+		yearl = tm->tm_year - 100 - yearh * 100;
+	} else {
+		yearh = 0;
+		yearl = tm->tm_year - 100 - yearh * 100;
+	}
+	rtc_data[5] = bin2bcd(yearl);
+	rtc_data[6] = bin2bcd(yearh);
+	rtc_data[7] = bin2bcd(tm->tm_wday);
+
+	/* Stop RTC while updating the RTC registers */
+	ret = regmap_update_bits(rk630->rtc, RTC_CTRL,
+				 RTC_CTRL_REG_START_RTC, 0);
+	if (ret) {
+		dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret);
+		return ret;
+	}
+	ret = regmap_bulk_write(rk630->rtc, RTC_SET_SECONDS,
+				rtc_data, NUM_TIME_REGS);
+	if (ret) {
+		dev_err(dev, "Failed to bull write rtc_data: %d\n", ret);
+		return ret;
+	}
+
+	/* Start RTC again */
+	ret = regmap_update_bits(rk630->rtc, RTC_CTRL,
+				 RTC_CTRL_REG_RTC_READSEL_M |
+				 RTC_CTRL_REG_START_RTC,
+				 RTC_CTRL_REG_RTC_READSEL_M |
+				 RTC_CTRL_REG_START_RTC);
+	if (ret) {
+		dev_err(dev, "Failed to update bits RTC control: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/* Read alarm time and date in RTC */
+static int rk630_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct rk630_rtc *rk630_rtc = dev_get_drvdata(dev);
+	struct rk630 *rk630 = rk630_rtc->rk630;
+	u32 alrm_data[NUM_ALARM_REGS];
+	u32 int_reg;
+	int yearl, yearh;
+	int ret;
+
+	ret = regmap_bulk_read(rk630->rtc,
+			       RTC_ALARM_SECONDS,
+			       alrm_data, NUM_ALARM_REGS);
+	if (ret) {
+		dev_err(dev, "Failed to read RTC alarm date REG: %d\n", ret);
+		return ret;
+	}
+
+	alrm->time.tm_sec = bcd2bin(alrm_data[0] & SECONDS_REG_MSK);
+	alrm->time.tm_min = bcd2bin(alrm_data[1] & MINUTES_REG_MAK);
+	alrm->time.tm_hour = bcd2bin(alrm_data[2] & HOURS_REG_MSK);
+	alrm->time.tm_mday = bcd2bin(alrm_data[3] & DAYS_REG_MSK);
+	alrm->time.tm_mon = (bcd2bin(alrm_data[4] & MONTHS_REG_MSK)) - 1;
+	yearl = (bcd2bin(alrm_data[5] & YEARS_REG_MSK));
+	yearh = (bcd2bin(alrm_data[6] & YEARS_REG_MSK));
+	alrm->time.tm_year = yearh * 100 + yearl + 100;
+
+	ret = regmap_read(rk630->rtc, RTC_INT0_EN, &int_reg);
+	if (ret) {
+		dev_err(dev, "Failed to read RTC INT REG: %d\n", ret);
+		return ret;
+	}
+
+	dev_dbg(dev, "alrm read RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+		1900 + alrm->time.tm_year, alrm->time.tm_mon + 1,
+		alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour,
+		alrm->time.tm_min, alrm->time.tm_sec);
+
+	alrm->enabled = (int_reg & RTC_INT_REG_ALARM_EN) ? 1 : 0;
+
+	return 0;
+}
+
+static int rk630_rtc_stop_alarm(struct rk630_rtc *rk630_rtc)
+{
+	struct rk630 *rk630 = rk630_rtc->rk630;
+	int ret;
+
+	ret = regmap_write(rk630->rtc, RTC_INT0_EN, DISABLE_ALARM_INT);
+
+	return ret;
+}
+
+static int rk630_rtc_start_alarm(struct rk630_rtc *rk630_rtc)
+{
+	struct rk630 *rk630 = rk630_rtc->rk630;
+	int ret = 0;
+
+	ret = regmap_write(rk630->rtc, RTC_STATUS0, RTC_STATUS_MASK);
+	if (ret) {
+		dev_err(rk630->dev, "Failed to write RTC_STATUS0: %d\n", ret);
+		return ret;
+	}
+	ret = regmap_write(rk630->rtc, RTC_STATUS0, 0);
+	if (ret) {
+		dev_err(rk630->dev, "Failed to write RTC_STATUS0: %d\n", ret);
+		return ret;
+	}
+	ret = regmap_write(rk630->rtc, RTC_INT0_EN, ENABLE_ALARM_INT);
+	if (ret) {
+		dev_err(rk630->dev, "Failed to write RTC_INT0_EN: %d\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int rk630_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct rk630_rtc *rk630_rtc = dev_get_drvdata(dev);
+	struct rk630 *rk630 = rk630_rtc->rk630;
+	u32 alrm_data[NUM_ALARM_REGS];
+	int yearl, yearh;
+	int ret;
+
+	ret = rk630_rtc_stop_alarm(rk630_rtc);
+	if (ret) {
+		dev_err(dev, "Failed to stop alarm: %d\n", ret);
+		return ret;
+	}
+	dev_dbg(dev, "alrm set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+		1900 + alrm->time.tm_year, alrm->time.tm_mon + 1,
+		alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour,
+		alrm->time.tm_min, alrm->time.tm_sec);
+
+	alrm_data[0] = bin2bcd(alrm->time.tm_sec);
+	alrm_data[1] = bin2bcd(alrm->time.tm_min);
+	alrm_data[2] = bin2bcd(alrm->time.tm_hour);
+	alrm_data[3] = bin2bcd(alrm->time.tm_mday);
+	alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1);
+	if (alrm->time.tm_year > 199) {
+		yearh = (alrm->time.tm_year - 100) / 100;
+		yearl = alrm->time.tm_year - 100 - yearh * 100;
+	} else {
+		yearh = 0;
+		yearl = alrm->time.tm_year - 100 - yearh * 100;
+	}
+	alrm_data[5] = bin2bcd(yearl);
+	alrm_data[6] = bin2bcd(yearh);
+
+	ret = regmap_bulk_write(rk630->rtc,
+				RTC_ALARM_SECONDS,
+				alrm_data, NUM_ALARM_REGS);
+	if (ret) {
+		dev_err(dev, "Failed to bulk write: %d\n", ret);
+		return ret;
+	}
+
+	if (alrm->enabled) {
+		ret = rk630_rtc_start_alarm(rk630_rtc);
+		if (ret) {
+			dev_err(dev, "Failed to start alarm: %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int rk630_rtc_alarm_irq_enable(struct device *dev,
+				      unsigned int enabled)
+{
+	struct rk630_rtc *rk630_rtc = dev_get_drvdata(dev);
+
+	if (enabled)
+		return rk630_rtc_start_alarm(rk630_rtc);
+
+	return rk630_rtc_stop_alarm(rk630_rtc);
+}
+
+/*
+ * We will just handle setting the frequency and make use the framework for
+ * reading the periodic interrupts.
+ *
+ */
+static irqreturn_t rk630_alarm_irq(int irq, void *data)
+{
+	struct rk630_rtc *rk630_rtc = data;
+	struct rk630 *rk630 = rk630_rtc->rk630;
+	int ret, status;
+
+	ret = regmap_read(rk630->rtc, RTC_STATUS0, &status);
+	if (ret) {
+		pr_err("Failed to read RTC INT REG: %d\n", ret);
+		return ret;
+	}
+
+	ret = regmap_write(rk630->rtc, RTC_STATUS0, status);
+	if (ret) {
+		pr_err("%s:Failed to update RTC status: %d\n", __func__, ret);
+		return ret;
+	}
+	ret = regmap_write(rk630->rtc, RTC_STATUS0, 0x0);
+	if (ret) {
+		pr_err("%s:Failed to update RTC status: %d\n", __func__, ret);
+		return ret;
+	}
+	if (status & ALARM_INT_STATUS) {
+		pr_info("Alarm by: %s\n", __func__);
+		rtc_update_irq(rk630_rtc->rtc, 1, RTC_IRQF | RTC_AF);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static const struct rtc_class_ops rk630_rtc_ops = {
+	.read_time = rk630_rtc_readtime,
+	.set_time = rk630_rtc_set_time,
+	.read_alarm = rk630_rtc_readalarm,
+	.set_alarm = rk630_rtc_setalarm,
+	.alarm_irq_enable = rk630_rtc_alarm_irq_enable,
+};
+
+/*
+ * Due to the analog generator 32k clock affected by
+ * temperature, voltage, clock precision need test
+ * with the environment change. In rtc test,
+ * use 24M clock as reference clock to measure the 32k clock.
+ * Before start test 32k clock, we should enable clk32k test(0x80),
+ * and configure test length, when rtc test done(0x84[2]),
+ * latch the 24M clock domain counter,
+ * and read out the counter from rtc_test
+ * registers(0x8c~0x98) via apb bus.
+ * In RTC digital design, we set three level compensation,
+ * the compensation value due to the
+ * RTC 32k clock test result, and if we need compensation,
+ * we need configure the compensation enable bit.
+ * Comp every hour, compensation at last minute every hour,
+ * and support add time and sub time by the MSB bit.
+ * Comp every day, compensation at last minute in last hour every day,
+ * and support add time and sub time by the MSB bit.
+ * Comp every month, compensation at last minute
+ * in last hour in last day every month,
+ * and support add time and sub time by the MSB bit.
+ */
+static int rk630_rtc_compensation(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rk630_rtc *rk630_rtc = dev_get_drvdata(&pdev->dev);
+	struct rk630 *rk630 = rk630_rtc->rk630;
+	u64 camp;
+	u32 count[4], counts, g_ref, tcamp;
+	int ret, done = 0, trim_dir, c_hour,
+	    c_day, c_det_day, c_mon, c_det_mon;
+
+	ret = regmap_write(rk630->rtc, RTC_CLK32K_TEST, CLK32K_TEST_EN);
+	if (ret) {
+		dev_err(dev,
+			"%s:Failed to update RTC CLK32K TEST: %d\n",
+			__func__, ret);
+		return ret;
+	}
+	ret = regmap_write(rk630->rtc, RTC_TEST_LEN, CLK32K_TEST_LEN);
+	if (ret) {
+		dev_err(dev,
+			"%s:Failed to update RTC CLK32K TEST LEN: %d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	ret = regmap_write(rk630->rtc, RTC_TEST_ST, CLK32K_TEST_START);
+	if (ret) {
+		dev_err(dev,
+			"%s:Failed to update RTC CLK32K TEST STATUS : %d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	while (!done) {
+		ret = regmap_read(rk630->rtc, RTC_TEST_ST, &done);
+		if (ret) {
+			dev_err(dev,
+				"Failed to read RTC CLK32K TEST STATUS: %d\n",
+				ret);
+			return ret;
+		}
+		done = (done & CLK32K_TEST_DONE) >> 2;
+		udelay(1);
+	}
+
+	ret = regmap_bulk_read(rk630->rtc, RTC_CNT_0, count, 4);
+	if (ret) {
+		dev_err(dev, "Failed to read RTC count REG: %d\n", ret);
+		return ret;
+	}
+
+	counts = count[0] | (count[1] << 8) |
+		 (count[2] << 16) | (count[3] << 24);
+	g_ref = CLK32K_TEST_REF_CLK * (CLK32K_TEST_LEN + 1);
+
+	if (counts > g_ref) {
+		trim_dir = 0;
+		camp = 36ULL * (32768 * (counts - g_ref));
+		do_div(camp, (g_ref / 100));
+	} else {
+		trim_dir = CLK32K_COMP_DIR_ADD;
+		camp = 36ULL * (32768 * (g_ref - counts));
+		do_div(camp, (g_ref / 100));
+	}
+	tcamp = (u32)camp;
+	c_hour = DIV_ROUND_CLOSEST(tcamp, 32768);
+	c_day = DIV_ROUND_CLOSEST(24 * tcamp, 32768);
+	c_mon = DIV_ROUND_CLOSEST(30 * 24 * tcamp, 32768);
+
+	if (c_hour > 1)
+		regmap_write(rk630->rtc, RTC_COMP_H, bin2bcd((c_hour - 1)) | trim_dir);
+	else
+		regmap_write(rk630->rtc, RTC_COMP_H, CLK32K_NO_COMP);
+
+	if (c_day > c_hour * 23) {
+		c_det_day = c_day - c_hour * 23;
+		trim_dir = CLK32K_COMP_DIR_ADD;
+	} else {
+		c_det_day = c_hour * 24 - c_day;
+		trim_dir = 0;
+	}
+
+	if (c_det_day > 1)
+		regmap_write(rk630->rtc, RTC_COMP_D,
+			     bin2bcd((c_det_day - 1)) | trim_dir);
+	else
+		regmap_write(rk630->rtc, RTC_COMP_D, CLK32K_NO_COMP);
+
+	if (c_mon > (29 * c_day + 23 * c_hour)) {
+		c_det_mon = c_mon - 29 * c_day - 23 * c_hour;
+		trim_dir = CLK32K_COMP_DIR_ADD;
+	} else {
+		c_det_mon = 29 * c_day + 23 * c_hour - c_mon;
+		trim_dir = 0;
+	}
+
+	if (c_det_mon)
+		regmap_write(rk630->rtc, RTC_COMP_M,
+			     bin2bcd((c_det_mon - 1)) | trim_dir);
+	else
+		regmap_write(rk630->rtc, RTC_COMP_M, CLK32K_NO_COMP);
+
+	ret = regmap_read(rk630->rtc, RTC_CTRL, &done);
+	if (ret) {
+		dev_err(dev, "Failed to read RTC_CTRL: %d\n",
+			ret);
+		return ret;
+	}
+
+	ret = regmap_update_bits(rk630->rtc, RTC_CTRL,
+				 CLK32K_COMP_EN,
+				 CLK32K_COMP_EN);
+	if (ret) {
+		dev_err(dev,
+			"%s:Failed to update RTC CTRL : %d\n", __func__, ret);
+		return ret;
+	}
+	return 0;
+}
+
+/* Enable the alarm if it should be enabled (in case it was disabled to
+ * prevent use as a wake source).
+ */
+#ifdef CONFIG_PM_SLEEP
+/* Turn off the alarm if it should not be a wake source. */
+static int rk630_rtc_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rk630_rtc *rk630_rtc = dev_get_drvdata(&pdev->dev);
+
+	if (device_may_wakeup(dev))
+		enable_irq_wake(rk630_rtc->irq);
+
+	regmap_write(rk630_rtc->rk630->grf,
+		     PLUMAGE_GRF_SOC_CON0,
+		     RTC_CLAMP_EN(0));
+
+	return 0;
+}
+
+/* Enable the alarm if it should be enabled (in case it was disabled to
+ * prevent use as a wake source).
+ */
+static int rk630_rtc_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rk630_rtc *rk630_rtc = dev_get_drvdata(&pdev->dev);
+
+	if (device_may_wakeup(dev))
+		disable_irq_wake(rk630_rtc->irq);
+
+	regmap_write(rk630_rtc->rk630->grf,
+		     PLUMAGE_GRF_SOC_CON0,
+		     RTC_CLAMP_EN(1));
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(rk630_rtc_pm_ops, rk630_rtc_suspend, rk630_rtc_resume);
+
+static int rk630_rtc_probe(struct platform_device *pdev)
+{
+	struct rk630 *rk630 = dev_get_drvdata(pdev->dev.parent);
+	struct rk630_rtc *rk630_rtc;
+	int ret;
+	struct rtc_time tm_read, tm = {
+		.tm_wday = 0,
+		.tm_year = 121,
+		.tm_mon = 0,
+		.tm_mday = 1,
+		.tm_hour = 12,
+		.tm_min = 0,
+		.tm_sec = 0,
+	};
+
+	rk630_rtc = devm_kzalloc(&pdev->dev, sizeof(*rk630_rtc), GFP_KERNEL);
+	if (!rk630_rtc)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, rk630_rtc);
+	rk630_rtc->rk630 = rk630;
+
+	regmap_write(rk630->grf, PLUMAGE_GRF_SOC_CON0, RTC_CLAMP_EN(1));
+	/* setting d2a_lp_xo_start_mir */
+	regmap_write(rk630->rtc, RTC_XO_TRIM0, RTC_XO_START_MIR);
+	regmap_write(rk630->rtc, RTC_ANALOG_TEST, RTC_VREF_INIT);
+
+	rk630_rtc_compensation(&pdev->dev);
+
+	/* start rtc running by default, and use shadowed timer. */
+	ret = regmap_update_bits(rk630->rtc, RTC_CTRL,
+			   RTC_CTRL_REG_RTC_READSEL_M |
+			   RTC_CTRL_REG_START_RTC,
+			   RTC_CTRL_REG_RTC_READSEL_M |
+			   RTC_CTRL_REG_START_RTC);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to write RTC control: %d\n", ret);
+		return ret;
+	}
+
+	ret = regmap_write(rk630->rtc, RTC_STATUS0,
+			   RTC_STATUS_MASK);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to write RTC status0: %d\n", ret);
+			return ret;
+	}
+
+	ret = regmap_write(rk630->rtc, RTC_STATUS0, 0);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to write RTC status0: %d\n", ret);
+			return ret;
+	}
+
+	device_init_wakeup(&pdev->dev, 1);
+
+	rk630_rtc_readtime(&pdev->dev, &tm_read);
+	if (rtc_valid_tm(&tm_read) != 0)
+		rk630_rtc_set_time(&pdev->dev, &tm);
+
+	rk630_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
+	if (IS_ERR(rk630_rtc->rtc))
+		return PTR_ERR(rk630_rtc->rtc);
+
+	rk630_rtc->rtc->ops = &rk630_rtc_ops;
+
+	/* request alarm irq of rk630 */
+	ret = devm_request_threaded_irq(&pdev->dev, rk630->irq, NULL,
+					rk630_alarm_irq,
+					IRQF_TRIGGER_LOW | IRQF_ONESHOT |
+					IRQF_SHARED,
+					"RTC alarm", rk630_rtc);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",
+			rk630_rtc->irq, ret);
+		return ret;
+	}
+
+	return rtc_register_device(rk630_rtc->rtc);
+}
+
+static struct platform_driver rk630_rtc_driver = {
+	.probe = rk630_rtc_probe,
+	.driver = {
+		.name = "rk630-rtc",
+		.pm = &rk630_rtc_pm_ops,
+	},
+};
+
+module_platform_driver(rk630_rtc_driver);
+
+MODULE_DESCRIPTION("RTC driver for the rk630");
+MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/rtc/rtc-rockchip.c b/kernel/drivers/rtc/rtc-rockchip.c
index 8dd82ef..7175ffe 100644
--- a/kernel/drivers/rtc/rtc-rockchip.c
+++ b/kernel/drivers/rtc/rtc-rockchip.c
@@ -555,6 +555,31 @@
 	return;
 }
 
+static bool rockchip_rtc_is_trimed(struct rockchip_rtc *rtc)
+{
+	int ret, comp_done;
+
+	ret = regmap_read(rtc->regmap, RTC_CTRL, &comp_done);
+	if (ret) {
+		pr_err("%s: Failed to read RTC_CTRL: %d\n", __func__, ret);
+		return false;
+	}
+	return (comp_done & CLK32K_COMP_EN) == CLK32K_COMP_EN;
+}
+
+static void rockchip_rtc_trim_start(struct rockchip_rtc *rtc)
+{
+	if (!rockchip_rtc_is_trimed(rtc))
+		queue_delayed_work(system_long_wq, &rtc->trim_work,
+				   msecs_to_jiffies(5000));
+}
+
+static void __maybe_unused rockchip_rtc_trim_close(struct rockchip_rtc *rtc)
+{
+	if (!rockchip_rtc_is_trimed(rtc))
+		cancel_delayed_work_sync(&rtc->trim_work);
+}
+
 /* Enable the alarm if it should be enabled (in case it was disabled to
  * prevent use as a wake source).
  */
@@ -567,6 +592,8 @@
 
 	if (device_may_wakeup(dev))
 		enable_irq_wake(rtc->irq);
+
+	rockchip_rtc_trim_close(rtc);
 
 	if (rtc->grf) {
 		switch (rtc->mode) {
@@ -610,6 +637,7 @@
 		dev_err(dev, "Cannot enable clock.\n");
 		return ret;
 	}
+	rockchip_rtc_trim_start(rtc);
 
 	return 0;
 }
@@ -761,7 +789,7 @@
 				     rtc->irq);
 
 	INIT_DELAYED_WORK(&rtc->trim_work, rockchip_rtc_compensation_delay_work);
-	queue_delayed_work(system_long_wq, &rtc->trim_work, 3000);
+	rockchip_rtc_trim_start(rtc);
 
 	return rtc_register_device(rtc->rtc);
 }
diff --git a/kernel/drivers/rtc/rtc-snvs.c b/kernel/drivers/rtc/rtc-snvs.c
index 0263d99..cc7f6c4 100644
--- a/kernel/drivers/rtc/rtc-snvs.c
+++ b/kernel/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 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 @@
 	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 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;
diff --git a/kernel/drivers/rtc/rtc-st-lpc.c b/kernel/drivers/rtc/rtc-st-lpc.c
index 0c65448..c4ea3f3 100644
--- a/kernel/drivers/rtc/rtc-st-lpc.c
+++ b/kernel/drivers/rtc/rtc-st-lpc.c
@@ -228,7 +228,7 @@
 	enable_irq_wake(rtc->irq);
 	disable_irq(rtc->irq);
 
-	rtc->clk = clk_get(&pdev->dev, NULL);
+	rtc->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(rtc->clk)) {
 		dev_err(&pdev->dev, "Unable to request clock\n");
 		return PTR_ERR(rtc->clk);
@@ -238,6 +238,7 @@
 
 	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;
 	}
diff --git a/kernel/drivers/rtc/rtc-sun6i.c b/kernel/drivers/rtc/rtc-sun6i.c
index 52b36b7..a72856f 100644
--- a/kernel/drivers/rtc/rtc-sun6i.c
+++ b/kernel/drivers/rtc/rtc-sun6i.c
@@ -128,7 +128,6 @@
 	unsigned int fixed_prescaler : 16;
 	unsigned int has_prescaler : 1;
 	unsigned int has_out_clk : 1;
-	unsigned int export_iosc : 1;
 	unsigned int has_losc_en : 1;
 	unsigned int has_auto_swt : 1;
 };
@@ -260,10 +259,8 @@
 	/* Yes, I know, this is ugly. */
 	sun6i_rtc = rtc;
 
-	/* Only read IOSC name from device tree if it is exported */
-	if (rtc->data->export_iosc)
-		of_property_read_string_index(node, "clock-output-names", 2,
-					      &iosc_name);
+	of_property_read_string_index(node, "clock-output-names", 2,
+				      &iosc_name);
 
 	rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL,
 								iosc_name,
@@ -304,13 +301,10 @@
 		goto err_register;
 	}
 
-	clk_data->num = 2;
+	clk_data->num = 3;
 	clk_data->hws[0] = &rtc->hw;
 	clk_data->hws[1] = __clk_get_hw(rtc->ext_losc);
-	if (rtc->data->export_iosc) {
-		clk_data->hws[2] = rtc->int_osc;
-		clk_data->num = 3;
-	}
+	clk_data->hws[2] = rtc->int_osc;
 	of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
 	return;
 
@@ -350,7 +344,6 @@
 	.fixed_prescaler = 32,
 	.has_prescaler = 1,
 	.has_out_clk = 1,
-	.export_iosc = 1,
 };
 
 static void __init sun8i_h3_rtc_clk_init(struct device_node *node)
@@ -368,7 +361,6 @@
 	.fixed_prescaler = 32,
 	.has_prescaler = 1,
 	.has_out_clk = 1,
-	.export_iosc = 1,
 	.has_losc_en = 1,
 	.has_auto_swt = 1,
 };
diff --git a/kernel/drivers/s390/block/dasd.c b/kernel/drivers/s390/block/dasd.c
index f4edfe3..09e932a 100644
--- a/kernel/drivers/s390/block/dasd.c
+++ b/kernel/drivers/s390/block/dasd.c
@@ -2128,8 +2128,8 @@
 	if (device->stopped &
 	    ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM))
 		return;
-	rc = device->discipline->verify_path(device,
-					     dasd_path_get_tbvpm(device));
+	rc = device->discipline->pe_handler(device,
+					    dasd_path_get_tbvpm(device));
 	if (rc)
 		dasd_device_set_timer(device, 50);
 	else
@@ -2985,41 +2985,32 @@
  * Requeue a request back to the block request queue
  * only works for block requests
  */
-static int _dasd_requeue_request(struct dasd_ccw_req *cqr)
+static void _dasd_requeue_request(struct dasd_ccw_req *cqr)
 {
-	struct dasd_block *block = cqr->block;
 	struct request *req;
 
-	if (!block)
-		return -EINVAL;
 	/*
 	 * If the request is an ERP request there is nothing to requeue.
 	 * This will be done with the remaining original request.
 	 */
 	if (cqr->refers)
-		return 0;
+		return;
 	spin_lock_irq(&cqr->dq->lock);
 	req = (struct request *) cqr->callback_data;
-	blk_mq_requeue_request(req, false);
+	blk_mq_requeue_request(req, true);
 	spin_unlock_irq(&cqr->dq->lock);
 
-	return 0;
+	return;
 }
 
-/*
- * Go through all request on the dasd_block request queue, cancel them
- * on the respective dasd_device, and return them to the generic
- * block layer.
- */
-static int dasd_flush_block_queue(struct dasd_block *block)
+static int _dasd_requests_to_flushqueue(struct dasd_block *block,
+					struct list_head *flush_queue)
 {
 	struct dasd_ccw_req *cqr, *n;
-	int rc, i;
-	struct list_head flush_queue;
 	unsigned long flags;
+	int rc, i;
 
-	INIT_LIST_HEAD(&flush_queue);
-	spin_lock_bh(&block->queue_lock);
+	spin_lock_irqsave(&block->queue_lock, flags);
 	rc = 0;
 restart:
 	list_for_each_entry_safe(cqr, n, &block->ccw_queue, blocklist) {
@@ -3034,13 +3025,32 @@
 		 * is returned from the dasd_device layer.
 		 */
 		cqr->callback = _dasd_wake_block_flush_cb;
-		for (i = 0; cqr != NULL; cqr = cqr->refers, i++)
-			list_move_tail(&cqr->blocklist, &flush_queue);
+		for (i = 0; cqr; cqr = cqr->refers, i++)
+			list_move_tail(&cqr->blocklist, flush_queue);
 		if (i > 1)
 			/* moved more than one request - need to restart */
 			goto restart;
 	}
-	spin_unlock_bh(&block->queue_lock);
+	spin_unlock_irqrestore(&block->queue_lock, flags);
+
+	return rc;
+}
+
+/*
+ * Go through all request on the dasd_block request queue, cancel them
+ * on the respective dasd_device, and return them to the generic
+ * block layer.
+ */
+static int dasd_flush_block_queue(struct dasd_block *block)
+{
+	struct dasd_ccw_req *cqr, *n;
+	struct list_head flush_queue;
+	unsigned long flags;
+	int rc;
+
+	INIT_LIST_HEAD(&flush_queue);
+	rc = _dasd_requests_to_flushqueue(block, &flush_queue);
+
 	/* Now call the callback function of flushed requests */
 restart_cb:
 	list_for_each_entry_safe(cqr, n, &flush_queue, blocklist) {
@@ -3977,74 +3987,35 @@
  */
 static int dasd_generic_requeue_all_requests(struct dasd_device *device)
 {
+	struct dasd_block *block = device->block;
 	struct list_head requeue_queue;
 	struct dasd_ccw_req *cqr, *n;
-	struct dasd_ccw_req *refers;
 	int rc;
 
+	if (!block)
+		return 0;
+
 	INIT_LIST_HEAD(&requeue_queue);
-	spin_lock_irq(get_ccwdev_lock(device->cdev));
-	rc = 0;
-	list_for_each_entry_safe(cqr, n, &device->ccw_queue, devlist) {
-		/* Check status and move request to flush_queue */
-		if (cqr->status == DASD_CQR_IN_IO) {
-			rc = device->discipline->term_IO(cqr);
-			if (rc) {
-				/* unable to terminate requeust */
-				dev_err(&device->cdev->dev,
-					"Unable to terminate request %p "
-					"on suspend\n", cqr);
-				spin_unlock_irq(get_ccwdev_lock(device->cdev));
-				dasd_put_device(device);
-				return rc;
-			}
+	rc = _dasd_requests_to_flushqueue(block, &requeue_queue);
+
+	/* Now call the callback function of flushed requests */
+restart_cb:
+	list_for_each_entry_safe(cqr, n, &requeue_queue, blocklist) {
+		wait_event(dasd_flush_wq, (cqr->status < DASD_CQR_QUEUED));
+		/* Process finished ERP request. */
+		if (cqr->refers) {
+			spin_lock_bh(&block->queue_lock);
+			__dasd_process_erp(block->base, cqr);
+			spin_unlock_bh(&block->queue_lock);
+			/* restart list_for_xx loop since dasd_process_erp
+			 * might remove multiple elements
+			 */
+			goto restart_cb;
 		}
-		list_move_tail(&cqr->devlist, &requeue_queue);
-	}
-	spin_unlock_irq(get_ccwdev_lock(device->cdev));
-
-	list_for_each_entry_safe(cqr, n, &requeue_queue, devlist) {
-		wait_event(dasd_flush_wq,
-			   (cqr->status != DASD_CQR_CLEAR_PENDING));
-
-		/*
-		 * requeue requests to blocklayer will only work
-		 * for block device requests
-		 */
-		if (_dasd_requeue_request(cqr))
-			continue;
-
-		/* remove requests from device and block queue */
-		list_del_init(&cqr->devlist);
-		while (cqr->refers != NULL) {
-			refers = cqr->refers;
-			/* remove the request from the block queue */
-			list_del(&cqr->blocklist);
-			/* free the finished erp request */
-			dasd_free_erp_request(cqr, cqr->memdev);
-			cqr = refers;
-		}
-
-		/*
-		 * _dasd_requeue_request already checked for a valid
-		 * blockdevice, no need to check again
-		 * all erp requests (cqr->refers) have a cqr->block
-		 * pointer copy from the original cqr
-		 */
+		_dasd_requeue_request(cqr);
 		list_del_init(&cqr->blocklist);
 		cqr->block->base->discipline->free_cp(
 			cqr, (struct request *) cqr->callback_data);
-	}
-
-	/*
-	 * if requests remain then they are internal request
-	 * and go back to the device queue
-	 */
-	if (!list_empty(&requeue_queue)) {
-		/* move freeze_queue to start of the ccw_queue */
-		spin_lock_irq(get_ccwdev_lock(device->cdev));
-		list_splice_tail(&requeue_queue, &device->ccw_queue);
-		spin_unlock_irq(get_ccwdev_lock(device->cdev));
 	}
 	dasd_schedule_device_bh(device);
 	return rc;
diff --git a/kernel/drivers/s390/block/dasd_3990_erp.c b/kernel/drivers/s390/block/dasd_3990_erp.c
index 4691a3c..c2d4ea7 100644
--- a/kernel/drivers/s390/block/dasd_3990_erp.c
+++ b/kernel/drivers/s390/block/dasd_3990_erp.c
@@ -2436,7 +2436,7 @@
 	erp->block    = cqr->block;
 	erp->magic    = cqr->magic;
 	erp->expires  = cqr->expires;
-	erp->retries  = 256;
+	erp->retries  = device->default_retries;
 	erp->buildclk = get_tod_clock();
 	erp->status = DASD_CQR_FILLED;
 
diff --git a/kernel/drivers/s390/block/dasd_diag.c b/kernel/drivers/s390/block/dasd_diag.c
index 1b9e144..d5c7b70 100644
--- a/kernel/drivers/s390/block/dasd_diag.c
+++ b/kernel/drivers/s390/block/dasd_diag.c
@@ -642,12 +642,17 @@
 	blk_queue_segment_boundary(q, PAGE_SIZE - 1);
 }
 
+static int dasd_diag_pe_handler(struct dasd_device *device, __u8 tbvpm)
+{
+	return dasd_generic_verify_path(device, tbvpm);
+}
+
 static struct dasd_discipline dasd_diag_discipline = {
 	.owner = THIS_MODULE,
 	.name = "DIAG",
 	.ebcname = "DIAG",
 	.check_device = dasd_diag_check_device,
-	.verify_path = dasd_generic_verify_path,
+	.pe_handler = dasd_diag_pe_handler,
 	.fill_geometry = dasd_diag_fill_geometry,
 	.setup_blk_queue = dasd_diag_setup_blk_queue,
 	.start_IO = dasd_start_diag,
diff --git a/kernel/drivers/s390/block/dasd_eckd.c b/kernel/drivers/s390/block/dasd_eckd.c
index 53d2297..c6930c1 100644
--- a/kernel/drivers/s390/block/dasd_eckd.c
+++ b/kernel/drivers/s390/block/dasd_eckd.c
@@ -103,7 +103,7 @@
 };
 
 /* definitions for the path verification worker */
-struct path_verification_work_data {
+struct pe_handler_work_data {
 	struct work_struct worker;
 	struct dasd_device *device;
 	struct dasd_ccw_req cqr;
@@ -112,8 +112,8 @@
 	int isglobal;
 	__u8 tbvpm;
 };
-static struct path_verification_work_data *path_verification_worker;
-static DEFINE_MUTEX(dasd_path_verification_mutex);
+static struct pe_handler_work_data *pe_handler_worker;
+static DEFINE_MUTEX(dasd_pe_handler_mutex);
 
 struct check_attention_work_data {
 	struct work_struct worker;
@@ -1219,7 +1219,7 @@
 }
 
 static int rebuild_device_uid(struct dasd_device *device,
-			      struct path_verification_work_data *data)
+			      struct pe_handler_work_data *data)
 {
 	struct dasd_eckd_private *private = device->private;
 	__u8 lpm, opm = dasd_path_get_opm(device);
@@ -1257,10 +1257,9 @@
 	return rc;
 }
 
-static void do_path_verification_work(struct work_struct *work)
+static void dasd_eckd_path_available_action(struct dasd_device *device,
+					    struct pe_handler_work_data *data)
 {
-	struct path_verification_work_data *data;
-	struct dasd_device *device;
 	struct dasd_eckd_private path_private;
 	struct dasd_uid *uid;
 	__u8 path_rcd_buf[DASD_ECKD_RCD_DATA_SIZE];
@@ -1269,19 +1268,6 @@
 	char print_uid[60];
 	int rc;
 
-	data = container_of(work, struct path_verification_work_data, worker);
-	device = data->device;
-
-	/* delay path verification until device was resumed */
-	if (test_bit(DASD_FLAG_SUSPENDED, &device->flags)) {
-		schedule_work(work);
-		return;
-	}
-	/* check if path verification already running and delay if so */
-	if (test_and_set_bit(DASD_FLAG_PATH_VERIFY, &device->flags)) {
-		schedule_work(work);
-		return;
-	}
 	opm = 0;
 	npm = 0;
 	ppm = 0;
@@ -1418,30 +1404,54 @@
 		dasd_path_add_nohpfpm(device, hpfpm);
 		spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	}
+}
+
+static void do_pe_handler_work(struct work_struct *work)
+{
+	struct pe_handler_work_data *data;
+	struct dasd_device *device;
+
+	data = container_of(work, struct pe_handler_work_data, worker);
+	device = data->device;
+
+	/* delay path verification until device was resumed */
+	if (test_bit(DASD_FLAG_SUSPENDED, &device->flags)) {
+		schedule_work(work);
+		return;
+	}
+	/* check if path verification already running and delay if so */
+	if (test_and_set_bit(DASD_FLAG_PATH_VERIFY, &device->flags)) {
+		schedule_work(work);
+		return;
+	}
+
+	dasd_eckd_path_available_action(device, data);
+
 	clear_bit(DASD_FLAG_PATH_VERIFY, &device->flags);
 	dasd_put_device(device);
 	if (data->isglobal)
-		mutex_unlock(&dasd_path_verification_mutex);
+		mutex_unlock(&dasd_pe_handler_mutex);
 	else
 		kfree(data);
 }
 
-static int dasd_eckd_verify_path(struct dasd_device *device, __u8 lpm)
+static int dasd_eckd_pe_handler(struct dasd_device *device, __u8 lpm)
 {
-	struct path_verification_work_data *data;
+	struct pe_handler_work_data *data;
 
 	data = kmalloc(sizeof(*data), GFP_ATOMIC | GFP_DMA);
 	if (!data) {
-		if (mutex_trylock(&dasd_path_verification_mutex)) {
-			data = path_verification_worker;
+		if (mutex_trylock(&dasd_pe_handler_mutex)) {
+			data = pe_handler_worker;
 			data->isglobal = 1;
-		} else
+		} else {
 			return -ENOMEM;
+		}
 	} else {
 		memset(data, 0, sizeof(*data));
 		data->isglobal = 0;
 	}
-	INIT_WORK(&data->worker, do_path_verification_work);
+	INIT_WORK(&data->worker, do_pe_handler_work);
 	dasd_get_device(device);
 	data->device = device;
 	data->tbvpm = lpm;
@@ -6694,7 +6704,7 @@
 	.check_device = dasd_eckd_check_characteristics,
 	.uncheck_device = dasd_eckd_uncheck_device,
 	.do_analysis = dasd_eckd_do_analysis,
-	.verify_path = dasd_eckd_verify_path,
+	.pe_handler = dasd_eckd_pe_handler,
 	.basic_to_ready = dasd_eckd_basic_to_ready,
 	.online_to_ready = dasd_eckd_online_to_ready,
 	.basic_to_known = dasd_eckd_basic_to_known,
@@ -6753,18 +6763,20 @@
 		return -ENOMEM;
 	dasd_vol_info_req = kmalloc(sizeof(*dasd_vol_info_req),
 				    GFP_KERNEL | GFP_DMA);
-	if (!dasd_vol_info_req)
+	if (!dasd_vol_info_req) {
+		kfree(dasd_reserve_req);
 		return -ENOMEM;
-	path_verification_worker = kmalloc(sizeof(*path_verification_worker),
-				   GFP_KERNEL | GFP_DMA);
-	if (!path_verification_worker) {
+	}
+	pe_handler_worker = kmalloc(sizeof(*pe_handler_worker),
+				    GFP_KERNEL | GFP_DMA);
+	if (!pe_handler_worker) {
 		kfree(dasd_reserve_req);
 		kfree(dasd_vol_info_req);
 		return -ENOMEM;
 	}
 	rawpadpage = (void *)__get_free_page(GFP_KERNEL);
 	if (!rawpadpage) {
-		kfree(path_verification_worker);
+		kfree(pe_handler_worker);
 		kfree(dasd_reserve_req);
 		kfree(dasd_vol_info_req);
 		return -ENOMEM;
@@ -6773,7 +6785,7 @@
 	if (!ret)
 		wait_for_device_probe();
 	else {
-		kfree(path_verification_worker);
+		kfree(pe_handler_worker);
 		kfree(dasd_reserve_req);
 		kfree(dasd_vol_info_req);
 		free_page((unsigned long)rawpadpage);
@@ -6785,7 +6797,7 @@
 dasd_eckd_cleanup(void)
 {
 	ccw_driver_unregister(&dasd_eckd_driver);
-	kfree(path_verification_worker);
+	kfree(pe_handler_worker);
 	kfree(dasd_reserve_req);
 	free_page((unsigned long)rawpadpage);
 }
diff --git a/kernel/drivers/s390/block/dasd_fba.c b/kernel/drivers/s390/block/dasd_fba.c
index 1a44e32..b159575 100644
--- a/kernel/drivers/s390/block/dasd_fba.c
+++ b/kernel/drivers/s390/block/dasd_fba.c
@@ -803,13 +803,18 @@
 	blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
 }
 
+static int dasd_fba_pe_handler(struct dasd_device *device, __u8 tbvpm)
+{
+	return dasd_generic_verify_path(device, tbvpm);
+}
+
 static struct dasd_discipline dasd_fba_discipline = {
 	.owner = THIS_MODULE,
 	.name = "FBA ",
 	.ebcname = "FBA ",
 	.check_device = dasd_fba_check_characteristics,
 	.do_analysis = dasd_fba_do_analysis,
-	.verify_path = dasd_generic_verify_path,
+	.pe_handler = dasd_fba_pe_handler,
 	.setup_blk_queue = dasd_fba_setup_blk_queue,
 	.fill_geometry = dasd_fba_fill_geometry,
 	.start_IO = dasd_start_IO,
diff --git a/kernel/drivers/s390/block/dasd_int.h b/kernel/drivers/s390/block/dasd_int.h
index 9d9685c..5d7d35ca 100644
--- a/kernel/drivers/s390/block/dasd_int.h
+++ b/kernel/drivers/s390/block/dasd_int.h
@@ -298,7 +298,7 @@
 	 * e.g. verify that new path is compatible with the current
 	 * configuration.
 	 */
-	int (*verify_path)(struct dasd_device *, __u8);
+	int (*pe_handler)(struct dasd_device *, __u8);
 
 	/*
 	 * Last things to do when a device is set online, and first things
diff --git a/kernel/drivers/s390/block/dasd_ioctl.c b/kernel/drivers/s390/block/dasd_ioctl.c
index cb6427f..99b1b01 100644
--- a/kernel/drivers/s390/block/dasd_ioctl.c
+++ b/kernel/drivers/s390/block/dasd_ioctl.c
@@ -133,6 +133,7 @@
 	spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
 
 	dasd_schedule_block_bh(block);
+	dasd_schedule_device_bh(base);
 	return 0;
 }
 
@@ -505,10 +506,10 @@
 
 	memcpy(dasd_info->type, base->discipline->name, 4);
 
-	spin_lock_irqsave(&block->queue_lock, flags);
+	spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
 	list_for_each(l, &base->ccw_queue)
 		dasd_info->chanq_len++;
-	spin_unlock_irqrestore(&block->queue_lock, flags);
+	spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
 	return 0;
 }
 
diff --git a/kernel/drivers/s390/cio/device.c b/kernel/drivers/s390/cio/device.c
index 33280ca..6f9c81d 100644
--- a/kernel/drivers/s390/cio/device.c
+++ b/kernel/drivers/s390/cio/device.c
@@ -1385,6 +1385,7 @@
 enum io_sch_action {
 	IO_SCH_UNREG,
 	IO_SCH_ORPH_UNREG,
+	IO_SCH_UNREG_CDEV,
 	IO_SCH_ATTACH,
 	IO_SCH_UNREG_ATTACH,
 	IO_SCH_ORPH_ATTACH,
@@ -1417,7 +1418,7 @@
 	}
 	if ((sch->schib.pmcw.pam & sch->opm) == 0) {
 		if (ccw_device_notify(cdev, CIO_NO_PATH) != NOTIFY_OK)
-			return IO_SCH_UNREG;
+			return IO_SCH_UNREG_CDEV;
 		return IO_SCH_DISC;
 	}
 	if (device_is_disconnected(cdev))
@@ -1479,6 +1480,7 @@
 	case IO_SCH_ORPH_ATTACH:
 		ccw_device_set_disconnected(cdev);
 		break;
+	case IO_SCH_UNREG_CDEV:
 	case IO_SCH_UNREG_ATTACH:
 	case IO_SCH_UNREG:
 		if (!cdev)
@@ -1512,6 +1514,7 @@
 		if (rc)
 			goto out;
 		break;
+	case IO_SCH_UNREG_CDEV:
 	case IO_SCH_UNREG_ATTACH:
 		spin_lock_irqsave(sch->lock, flags);
 		if (cdev->private->flags.resuming) {
diff --git a/kernel/drivers/s390/cio/qdio.h b/kernel/drivers/s390/cio/qdio.h
index cd2df4f..919d106 100644
--- a/kernel/drivers/s390/cio/qdio.h
+++ b/kernel/drivers/s390/cio/qdio.h
@@ -88,15 +88,15 @@
 static inline int do_sqbs(u64 token, unsigned char state, int queue,
 			  int *start, int *count)
 {
-	register unsigned long _ccq asm ("0") = *count;
-	register unsigned long _token asm ("1") = token;
 	unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
+	unsigned long _ccq = *count;
 
 	asm volatile(
-		"	.insn	rsy,0xeb000000008A,%1,0,0(%2)"
-		: "+d" (_ccq), "+d" (_queuestart)
-		: "d" ((unsigned long)state), "d" (_token)
-		: "memory", "cc");
+		"	lgr	1,%[token]\n"
+		"	.insn	rsy,0xeb000000008a,%[qs],%[ccq],0(%[state])"
+		: [ccq] "+&d" (_ccq), [qs] "+&d" (_queuestart)
+		: [state] "a" ((unsigned long)state), [token] "d" (token)
+		: "memory", "cc", "1");
 	*count = _ccq & 0xff;
 	*start = _queuestart & 0xff;
 
@@ -106,16 +106,17 @@
 static inline int do_eqbs(u64 token, unsigned char *state, int queue,
 			  int *start, int *count, int ack)
 {
-	register unsigned long _ccq asm ("0") = *count;
-	register unsigned long _token asm ("1") = token;
 	unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
 	unsigned long _state = (unsigned long)ack << 63;
+	unsigned long _ccq = *count;
 
 	asm volatile(
-		"	.insn	rrf,0xB99c0000,%1,%2,0,0"
-		: "+d" (_ccq), "+d" (_queuestart), "+d" (_state)
-		: "d" (_token)
-		: "memory", "cc");
+		"	lgr	1,%[token]\n"
+		"	.insn	rrf,0xb99c0000,%[qs],%[state],%[ccq],0"
+		: [ccq] "+&d" (_ccq), [qs] "+&d" (_queuestart),
+		  [state] "+&d" (_state)
+		: [token] "d" (token)
+		: "memory", "cc", "1");
 	*count = _ccq & 0xff;
 	*start = _queuestart & 0xff;
 	*state = _state & 0xff;
diff --git a/kernel/drivers/s390/cio/qdio_main.c b/kernel/drivers/s390/cio/qdio_main.c
index 3e29c26..e3c55fc 100644
--- a/kernel/drivers/s390/cio/qdio_main.c
+++ b/kernel/drivers/s390/cio/qdio_main.c
@@ -31,38 +31,41 @@
 MODULE_LICENSE("GPL");
 
 static inline int do_siga_sync(unsigned long schid,
-			       unsigned int out_mask, unsigned int in_mask,
+			       unsigned long out_mask, unsigned long in_mask,
 			       unsigned int fc)
 {
-	register unsigned long __fc asm ("0") = fc;
-	register unsigned long __schid asm ("1") = schid;
-	register unsigned long out asm ("2") = out_mask;
-	register unsigned long in asm ("3") = in_mask;
 	int cc;
 
 	asm volatile(
+		"	lgr	0,%[fc]\n"
+		"	lgr	1,%[schid]\n"
+		"	lgr	2,%[out]\n"
+		"	lgr	3,%[in]\n"
 		"	siga	0\n"
-		"	ipm	%0\n"
-		"	srl	%0,28\n"
-		: "=d" (cc)
-		: "d" (__fc), "d" (__schid), "d" (out), "d" (in) : "cc");
+		"	ipm	%[cc]\n"
+		"	srl	%[cc],28\n"
+		: [cc] "=&d" (cc)
+		: [fc] "d" (fc), [schid] "d" (schid),
+		  [out] "d" (out_mask), [in] "d" (in_mask)
+		: "cc", "0", "1", "2", "3");
 	return cc;
 }
 
-static inline int do_siga_input(unsigned long schid, unsigned int mask,
-				unsigned int fc)
+static inline int do_siga_input(unsigned long schid, unsigned long mask,
+				unsigned long fc)
 {
-	register unsigned long __fc asm ("0") = fc;
-	register unsigned long __schid asm ("1") = schid;
-	register unsigned long __mask asm ("2") = mask;
 	int cc;
 
 	asm volatile(
+		"	lgr	0,%[fc]\n"
+		"	lgr	1,%[schid]\n"
+		"	lgr	2,%[mask]\n"
 		"	siga	0\n"
-		"	ipm	%0\n"
-		"	srl	%0,28\n"
-		: "=d" (cc)
-		: "d" (__fc), "d" (__schid), "d" (__mask) : "cc");
+		"	ipm	%[cc]\n"
+		"	srl	%[cc],28\n"
+		: [cc] "=&d" (cc)
+		: [fc] "d" (fc), [schid] "d" (schid), [mask] "d" (mask)
+		: "cc", "0", "1", "2");
 	return cc;
 }
 
@@ -78,23 +81,24 @@
  * Note: For IQDC unicast queues only the highest priority queue is processed.
  */
 static inline int do_siga_output(unsigned long schid, unsigned long mask,
-				 unsigned int *bb, unsigned int fc,
+				 unsigned int *bb, unsigned long fc,
 				 unsigned long aob)
 {
-	register unsigned long __fc asm("0") = fc;
-	register unsigned long __schid asm("1") = schid;
-	register unsigned long __mask asm("2") = mask;
-	register unsigned long __aob asm("3") = aob;
 	int cc;
 
 	asm volatile(
+		"	lgr	0,%[fc]\n"
+		"	lgr	1,%[schid]\n"
+		"	lgr	2,%[mask]\n"
+		"	lgr	3,%[aob]\n"
 		"	siga	0\n"
-		"	ipm	%0\n"
-		"	srl	%0,28\n"
-		: "=d" (cc), "+d" (__fc), "+d" (__aob)
-		: "d" (__schid), "d" (__mask)
-		: "cc");
-	*bb = __fc >> 31;
+		"	lgr	%[fc],0\n"
+		"	ipm	%[cc]\n"
+		"	srl	%[cc],28\n"
+		: [cc] "=&d" (cc), [fc] "+&d" (fc)
+		: [schid] "d" (schid), [mask] "d" (mask), [aob] "d" (aob)
+		: "cc", "0", "1", "2", "3");
+	*bb = fc >> 31;
 	return cc;
 }
 
diff --git a/kernel/drivers/s390/crypto/pkey_api.c b/kernel/drivers/s390/crypto/pkey_api.c
index dd84995..69882ff 100644
--- a/kernel/drivers/s390/crypto/pkey_api.c
+++ b/kernel/drivers/s390/crypto/pkey_api.c
@@ -735,7 +735,7 @@
 		if (ktype)
 			*ktype = PKEY_TYPE_EP11;
 		if (ksize)
-			*ksize = kb->head.keybitlen;
+			*ksize = kb->head.bitlen;
 
 		rc = ep11_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain,
 				    ZCRYPT_CEX7, EP11_API_V, kb->wkvp);
@@ -1271,6 +1271,7 @@
 			return PTR_ERR(kkey);
 		rc = pkey_keyblob2pkey(kkey, ktp.keylen, &ktp.protkey);
 		DEBUG_DBG("%s pkey_keyblob2pkey()=%d\n", __func__, rc);
+		memzero_explicit(kkey, ktp.keylen);
 		kfree(kkey);
 		if (rc)
 			break;
@@ -1404,6 +1405,7 @@
 					kkey, ktp.keylen, &ktp.protkey);
 		DEBUG_DBG("%s pkey_keyblob2pkey2()=%d\n", __func__, rc);
 		kfree(apqns);
+		memzero_explicit(kkey, ktp.keylen);
 		kfree(kkey);
 		if (rc)
 			break;
@@ -1530,6 +1532,7 @@
 					protkey, &protkeylen);
 		DEBUG_DBG("%s pkey_keyblob2pkey3()=%d\n", __func__, rc);
 		kfree(apqns);
+		memzero_explicit(kkey, ktp.keylen);
 		kfree(kkey);
 		if (rc) {
 			kfree(protkey);
diff --git a/kernel/drivers/s390/crypto/vfio_ap_drv.c b/kernel/drivers/s390/crypto/vfio_ap_drv.c
index 7dc72cb..22128eb 100644
--- a/kernel/drivers/s390/crypto/vfio_ap_drv.c
+++ b/kernel/drivers/s390/crypto/vfio_ap_drv.c
@@ -82,8 +82,9 @@
 
 static void vfio_ap_matrix_dev_release(struct device *dev)
 {
-	struct ap_matrix_dev *matrix_dev = dev_get_drvdata(dev);
+	struct ap_matrix_dev *matrix_dev;
 
+	matrix_dev = container_of(dev, struct ap_matrix_dev, device);
 	kfree(matrix_dev);
 }
 
diff --git a/kernel/drivers/s390/crypto/zcrypt_api.c b/kernel/drivers/s390/crypto/zcrypt_api.c
index 3b9eda3..b518009 100644
--- a/kernel/drivers/s390/crypto/zcrypt_api.c
+++ b/kernel/drivers/s390/crypto/zcrypt_api.c
@@ -399,6 +399,7 @@
 			 ZCRYPT_NAME "_%d", (int) MINOR(devt));
 	nodename[sizeof(nodename)-1] = '\0';
 	if (dev_set_name(&zcdndev->device, nodename)) {
+		kfree(zcdndev);
 		rc = -EINVAL;
 		goto unlockout;
 	}
diff --git a/kernel/drivers/s390/crypto/zcrypt_ep11misc.c b/kernel/drivers/s390/crypto/zcrypt_ep11misc.c
index 9ce5a71..3daf259 100644
--- a/kernel/drivers/s390/crypto/zcrypt_ep11misc.c
+++ b/kernel/drivers/s390/crypto/zcrypt_ep11misc.c
@@ -788,7 +788,7 @@
 	kb->head.type = TOKTYPE_NON_CCA;
 	kb->head.len = rep_pl->data_len;
 	kb->head.version = TOKVER_EP11_AES;
-	kb->head.keybitlen = keybitsize;
+	kb->head.bitlen = keybitsize;
 
 out:
 	kfree(req);
@@ -1056,7 +1056,7 @@
 	kb->head.type = TOKTYPE_NON_CCA;
 	kb->head.len = rep_pl->data_len;
 	kb->head.version = TOKVER_EP11_AES;
-	kb->head.keybitlen = keybitsize;
+	kb->head.bitlen = keybitsize;
 
 out:
 	kfree(req);
diff --git a/kernel/drivers/s390/crypto/zcrypt_ep11misc.h b/kernel/drivers/s390/crypto/zcrypt_ep11misc.h
index 1e02b19..d424fa9 100644
--- a/kernel/drivers/s390/crypto/zcrypt_ep11misc.h
+++ b/kernel/drivers/s390/crypto/zcrypt_ep11misc.h
@@ -29,14 +29,7 @@
 	union {
 		u8 session[32];
 		/* only used for PKEY_TYPE_EP11: */
-		struct {
-			u8  type;      /* 0x00 (TOKTYPE_NON_CCA) */
-			u8  res0;      /* unused */
-			u16 len;       /* total length in bytes of this blob */
-			u8  version;   /* 0x03 (TOKVER_EP11_AES) */
-			u8  res1;      /* unused */
-			u16 keybitlen; /* clear key bit len, 0 for unknown */
-		} head;
+		struct ep11kblob_header head;
 	};
 	u8  wkvp[16];  /* wrapping key verification pattern */
 	u64 attr;      /* boolean key attributes */
diff --git a/kernel/drivers/s390/net/ctcm_main.c b/kernel/drivers/s390/net/ctcm_main.c
index d06809e..fb0e8f1 100644
--- a/kernel/drivers/s390/net/ctcm_main.c
+++ b/kernel/drivers/s390/net/ctcm_main.c
@@ -865,16 +865,9 @@
 /**
  * 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 @@
 }
 
 /* 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;
diff --git a/kernel/drivers/s390/net/lcs.c b/kernel/drivers/s390/net/lcs.c
index 06a322b..7e743f4 100644
--- a/kernel/drivers/s390/net/lcs.c
+++ b/kernel/drivers/s390/net/lcs.c
@@ -1518,9 +1518,8 @@
 /**
  * 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 @@
 	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;
diff --git a/kernel/drivers/s390/net/netiucv.c b/kernel/drivers/s390/net/netiucv.c
index 260860c..a2f403c 100644
--- a/kernel/drivers/s390/net/netiucv.c
+++ b/kernel/drivers/s390/net/netiucv.c
@@ -1260,15 +1260,8 @@
 /**
  * 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;
diff --git a/kernel/drivers/s390/net/qeth_core.h b/kernel/drivers/s390/net/qeth_core.h
index bf8404b..2544edd 100644
--- a/kernel/drivers/s390/net/qeth_core.h
+++ b/kernel/drivers/s390/net/qeth_core.h
@@ -719,7 +719,6 @@
 	u16 chid;
 	u8 ids_valid:1; /* cssid,iid,chid */
 	u8 dev_addr_is_registered:1;
-	u8 open_when_online:1;
 	u8 promisc_mode:1;
 	u8 use_v1_blkt:1;
 	u8 is_vm_nic:1;
diff --git a/kernel/drivers/s390/net/qeth_core_main.c b/kernel/drivers/s390/net/qeth_core_main.c
index 7b0155b..73d5649 100644
--- a/kernel/drivers/s390/net/qeth_core_main.c
+++ b/kernel/drivers/s390/net/qeth_core_main.c
@@ -5351,8 +5351,6 @@
 	qeth_clear_ipacmd_list(card);
 
 	rtnl_lock();
-	card->info.open_when_online = card->dev->flags & IFF_UP;
-	dev_close(card->dev);
 	netif_device_detach(card->dev);
 	netif_carrier_off(card->dev);
 	rtnl_unlock();
diff --git a/kernel/drivers/s390/net/qeth_l2_main.c b/kernel/drivers/s390/net/qeth_l2_main.c
index cfc931f..1797add 100644
--- a/kernel/drivers/s390/net/qeth_l2_main.c
+++ b/kernel/drivers/s390/net/qeth_l2_main.c
@@ -2270,9 +2270,12 @@
 		qeth_enable_hw_features(dev);
 		qeth_l2_enable_brport_features(card);
 
-		if (card->info.open_when_online) {
-			card->info.open_when_online = 0;
-			dev_open(dev, NULL);
+		if (netif_running(dev)) {
+			local_bh_disable();
+			napi_schedule(&card->napi);
+			/* kick-start the NAPI softirq: */
+			local_bh_enable();
+			qeth_l2_set_rx_mode(dev);
 		}
 		rtnl_unlock();
 	}
diff --git a/kernel/drivers/s390/net/qeth_l3_main.c b/kernel/drivers/s390/net/qeth_l3_main.c
index 291861c..d8cdf90 100644
--- a/kernel/drivers/s390/net/qeth_l3_main.c
+++ b/kernel/drivers/s390/net/qeth_l3_main.c
@@ -2037,9 +2037,11 @@
 		netif_device_attach(dev);
 		qeth_enable_hw_features(dev);
 
-		if (card->info.open_when_online) {
-			card->info.open_when_online = 0;
-			dev_open(dev, NULL);
+		if (netif_running(dev)) {
+			local_bh_disable();
+			napi_schedule(&card->napi);
+			/* kick-start the NAPI softirq: */
+			local_bh_enable();
 		}
 		rtnl_unlock();
 	}
diff --git a/kernel/drivers/s390/net/qeth_l3_sys.c b/kernel/drivers/s390/net/qeth_l3_sys.c
index 997fbb7..316f862 100644
--- a/kernel/drivers/s390/net/qeth_l3_sys.c
+++ b/kernel/drivers/s390/net/qeth_l3_sys.c
@@ -652,7 +652,7 @@
 static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
-	return qeth_l3_vipa_store(dev, buf, true, count, QETH_PROT_IPV4);
+	return qeth_l3_vipa_store(dev, buf, false, count, QETH_PROT_IPV4);
 }
 
 static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
diff --git a/kernel/drivers/s390/scsi/zfcp_aux.c b/kernel/drivers/s390/scsi/zfcp_aux.c
index 18b713a..36c2bd2 100644
--- a/kernel/drivers/s390/scsi/zfcp_aux.c
+++ b/kernel/drivers/s390/scsi/zfcp_aux.c
@@ -497,12 +497,12 @@
 	if (port) {
 		put_device(&port->dev);
 		retval = -EEXIST;
-		goto err_out;
+		goto err_put;
 	}
 
 	port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
 	if (!port)
-		goto err_out;
+		goto err_put;
 
 	rwlock_init(&port->unit_list_lock);
 	INIT_LIST_HEAD(&port->unit_list);
@@ -525,7 +525,7 @@
 
 	if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) {
 		kfree(port);
-		goto err_out;
+		goto err_put;
 	}
 	retval = -EINVAL;
 
@@ -542,7 +542,8 @@
 
 	return port;
 
-err_out:
+err_put:
 	zfcp_ccw_adapter_put(adapter);
+err_out:
 	return ERR_PTR(retval);
 }
diff --git a/kernel/drivers/s390/scsi/zfcp_fc.c b/kernel/drivers/s390/scsi/zfcp_fc.c
index b61acbb..d323f99 100644
--- a/kernel/drivers/s390/scsi/zfcp_fc.c
+++ b/kernel/drivers/s390/scsi/zfcp_fc.c
@@ -534,8 +534,7 @@
 
 	/* re-init to undo drop from zfcp_fc_adisc() */
 	port->d_id = ntoh24(adisc_resp->adisc_port_id);
-	/* port is good, unblock rport without going through erp */
-	zfcp_scsi_schedule_rport_register(port);
+	/* port is still good, nothing to do */
  out:
 	atomic_andnot(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
 	put_device(&port->dev);
@@ -595,9 +594,6 @@
 	int retval;
 
 	set_worker_desc("zadisc%16llx", port->wwpn); /* < WORKER_DESC_LEN=24 */
-	get_device(&port->dev);
-	port->rport_task = RPORT_DEL;
-	zfcp_scsi_rport_work(&port->rport_work);
 
 	/* only issue one test command at one time per port */
 	if (atomic_read(&port->status) & ZFCP_STATUS_PORT_LINK_TEST)
diff --git a/kernel/drivers/scsi/3w-xxxx.c b/kernel/drivers/scsi/3w-xxxx.c
index fb6444d..211a253 100644
--- a/kernel/drivers/scsi/3w-xxxx.c
+++ b/kernel/drivers/scsi/3w-xxxx.c
@@ -2308,8 +2308,10 @@
 	TW_DISABLE_INTERRUPTS(tw_dev);
 
 	/* Initialize the card */
-	if (tw_reset_sequence(tw_dev))
+	if (tw_reset_sequence(tw_dev)) {
+		retval = -EINVAL;
 		goto out_release_mem_region;
+	}
 
 	/* Set host specific parameters */
 	host->max_id = TW_MAX_UNITS;
diff --git a/kernel/drivers/scsi/53c700.c b/kernel/drivers/scsi/53c700.c
index 3242ff6..37e1994 100644
--- a/kernel/drivers/scsi/53c700.c
+++ b/kernel/drivers/scsi/53c700.c
@@ -1600,7 +1600,7 @@
 				printk("scsi%d (%d:%d) PHASE MISMATCH IN SEND MESSAGE %d remain, return %p[%04x], phase %s\n", host->host_no, pun, lun, count, (void *)temp, temp - hostdata->pScript, sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
 #endif
 				resume_offset = hostdata->pScript + Ent_SendMessagePhaseMismatch;
-			} else if(dsp >= to32bit(&slot->pSG[0].ins) &&
+			} else if (slot && dsp >= to32bit(&slot->pSG[0].ins) &&
 				  dsp <= to32bit(&slot->pSG[NCR_700_SG_SEGMENTS].ins)) {
 				int data_transfer = NCR_700_readl(host, DBC_REG) & 0xffffff;
 				int SGcount = (dsp - to32bit(&slot->pSG[0].ins))/sizeof(struct NCR_700_SG_List);
diff --git a/kernel/drivers/scsi/Kconfig b/kernel/drivers/scsi/Kconfig
index 701b61e..6524e1f 100644
--- a/kernel/drivers/scsi/Kconfig
+++ b/kernel/drivers/scsi/Kconfig
@@ -444,7 +444,7 @@
 
 config SCSI_DPT_I2O
 	tristate "Adaptec I2O RAID support "
-	depends on SCSI && PCI && VIRT_TO_BUS
+	depends on SCSI && PCI
 	help
 	  This driver supports all of Adaptec's I2O based RAID controllers as 
 	  well as the DPT SmartRaid V cards.  This is an Adaptec maintained
diff --git a/kernel/drivers/scsi/aic94xx/aic94xx_task.c b/kernel/drivers/scsi/aic94xx/aic94xx_task.c
index f923ed0..2eb2885 100644
--- a/kernel/drivers/scsi/aic94xx/aic94xx_task.c
+++ b/kernel/drivers/scsi/aic94xx/aic94xx_task.c
@@ -50,6 +50,9 @@
 		dma_addr_t dma = dma_map_single(&asd_ha->pcidev->dev, p,
 						task->total_xfer_len,
 						task->data_dir);
+		if (dma_mapping_error(&asd_ha->pcidev->dev, dma))
+			return -ENOMEM;
+
 		sg_arr[0].bus_addr = cpu_to_le64((u64)dma);
 		sg_arr[0].size = cpu_to_le32(task->total_xfer_len);
 		sg_arr[0].flags |= ASD_SG_EL_LIST_EOL;
@@ -205,7 +208,7 @@
 	switch (opcode) {
 	case TC_NO_ERROR:
 		ts->resp = SAS_TASK_COMPLETE;
-		ts->stat = SAM_STAT_GOOD;
+		ts->stat = SAS_SAM_STAT_GOOD;
 		break;
 	case TC_UNDERRUN:
 		ts->resp = SAS_TASK_COMPLETE;
diff --git a/kernel/drivers/scsi/be2iscsi/be_iscsi.c b/kernel/drivers/scsi/be2iscsi/be_iscsi.c
index c488165..e07052f 100644
--- a/kernel/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/kernel/drivers/scsi/be2iscsi/be_iscsi.c
@@ -450,6 +450,10 @@
 	}
 
 	nla_for_each_attr(attrib, data, dt_len, rm_len) {
+		/* ignore nla_type as it is never used */
+		if (nla_len(attrib) < sizeof(*iface_param))
+			return -EINVAL;
+
 		iface_param = nla_data(attrib);
 
 		if (iface_param->param_type != ISCSI_NET_PARAM)
diff --git a/kernel/drivers/scsi/device_handler/scsi_dh_alua.c b/kernel/drivers/scsi/device_handler/scsi_dh_alua.c
index fe8a5e5..bf0b317 100644
--- a/kernel/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/kernel/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -1036,10 +1036,12 @@
 	rcu_read_unlock();
 	mutex_unlock(&h->init_mutex);
 
-	if (alua_rtpg_queue(pg, sdev, qdata, true))
+	if (alua_rtpg_queue(pg, sdev, qdata, true)) {
 		fn = NULL;
-	else
+	} else {
+		kfree(qdata);
 		err = SCSI_DH_DEV_OFFLINED;
+	}
 	kref_put(&pg->kref, release_port_group);
 out:
 	if (fn)
diff --git a/kernel/drivers/scsi/dpt_i2o.c b/kernel/drivers/scsi/dpt_i2o.c
index 4251212..43ec565 100644
--- a/kernel/drivers/scsi/dpt_i2o.c
+++ b/kernel/drivers/scsi/dpt_i2o.c
@@ -56,7 +56,7 @@
 #include <linux/mutex.h>
 
 #include <asm/processor.h>	/* for boot_cpu_data */
-#include <asm/io.h>		/* for virt_to_bus, etc. */
+#include <asm/io.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -580,51 +580,6 @@
 		}
 	}
 	return 0;
-}
-
-/*
- *	Turn a pointer to ioctl reply data into an u32 'context'
- */
-static u32 adpt_ioctl_to_context(adpt_hba * pHba, void *reply)
-{
-#if BITS_PER_LONG == 32
-	return (u32)(unsigned long)reply;
-#else
-	ulong flags = 0;
-	u32 nr, i;
-
-	spin_lock_irqsave(pHba->host->host_lock, flags);
-	nr = ARRAY_SIZE(pHba->ioctl_reply_context);
-	for (i = 0; i < nr; i++) {
-		if (pHba->ioctl_reply_context[i] == NULL) {
-			pHba->ioctl_reply_context[i] = reply;
-			break;
-		}
-	}
-	spin_unlock_irqrestore(pHba->host->host_lock, flags);
-	if (i >= nr) {
-		printk(KERN_WARNING"%s: Too many outstanding "
-				"ioctl commands\n", pHba->name);
-		return (u32)-1;
-	}
-
-	return i;
-#endif
-}
-
-/*
- *	Go from an u32 'context' to a pointer to ioctl reply data.
- */
-static void *adpt_ioctl_from_context(adpt_hba *pHba, u32 context)
-{
-#if BITS_PER_LONG == 32
-	return (void *)(unsigned long)context;
-#else
-	void *p = pHba->ioctl_reply_context[context];
-	pHba->ioctl_reply_context[context] = NULL;
-
-	return p;
-#endif
 }
 
 /*===========================================================================
@@ -1648,208 +1603,6 @@
 	return 0;
 }
 
-
-static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
-{
-	u32 msg[MAX_MESSAGE_SIZE];
-	u32* reply = NULL;
-	u32 size = 0;
-	u32 reply_size = 0;
-	u32 __user *user_msg = arg;
-	u32 __user * user_reply = NULL;
-	void **sg_list = NULL;
-	u32 sg_offset = 0;
-	u32 sg_count = 0;
-	int sg_index = 0;
-	u32 i = 0;
-	u32 rcode = 0;
-	void *p = NULL;
-	dma_addr_t addr;
-	ulong flags = 0;
-
-	memset(&msg, 0, MAX_MESSAGE_SIZE*4);
-	// get user msg size in u32s 
-	if(get_user(size, &user_msg[0])){
-		return -EFAULT;
-	}
-	size = size>>16;
-
-	user_reply = &user_msg[size];
-	if(size > MAX_MESSAGE_SIZE){
-		return -EFAULT;
-	}
-	size *= 4; // Convert to bytes
-
-	/* Copy in the user's I2O command */
-	if(copy_from_user(msg, user_msg, size)) {
-		return -EFAULT;
-	}
-	get_user(reply_size, &user_reply[0]);
-	reply_size = reply_size>>16;
-	if(reply_size > REPLY_FRAME_SIZE){
-		reply_size = REPLY_FRAME_SIZE;
-	}
-	reply_size *= 4;
-	reply = kzalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL);
-	if(reply == NULL) {
-		printk(KERN_WARNING"%s: Could not allocate reply buffer\n",pHba->name);
-		return -ENOMEM;
-	}
-	sg_offset = (msg[0]>>4)&0xf;
-	msg[2] = 0x40000000; // IOCTL context
-	msg[3] = adpt_ioctl_to_context(pHba, reply);
-	if (msg[3] == (u32)-1) {
-		rcode = -EBUSY;
-		goto free;
-	}
-
-	sg_list = kcalloc(pHba->sg_tablesize, sizeof(*sg_list), GFP_KERNEL);
-	if (!sg_list) {
-		rcode = -ENOMEM;
-		goto free;
-	}
-	if(sg_offset) {
-		// TODO add 64 bit API
-		struct sg_simple_element *sg =  (struct sg_simple_element*) (msg+sg_offset);
-		sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
-		if (sg_count > pHba->sg_tablesize){
-			printk(KERN_DEBUG"%s:IOCTL SG List too large (%u)\n", pHba->name,sg_count);
-			rcode = -EINVAL;
-			goto free;
-		}
-
-		for(i = 0; i < sg_count; i++) {
-			int sg_size;
-
-			if (!(sg[i].flag_count & 0x10000000 /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT*/)) {
-				printk(KERN_DEBUG"%s:Bad SG element %d - not simple (%x)\n",pHba->name,i,  sg[i].flag_count);
-				rcode = -EINVAL;
-				goto cleanup;
-			}
-			sg_size = sg[i].flag_count & 0xffffff;      
-			/* Allocate memory for the transfer */
-			p = dma_alloc_coherent(&pHba->pDev->dev, sg_size, &addr, GFP_KERNEL);
-			if(!p) {
-				printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
-						pHba->name,sg_size,i,sg_count);
-				rcode = -ENOMEM;
-				goto cleanup;
-			}
-			sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame.
-			/* Copy in the user's SG buffer if necessary */
-			if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) {
-				// sg_simple_element API is 32 bit
-				if (copy_from_user(p,(void __user *)(ulong)sg[i].addr_bus, sg_size)) {
-					printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i);
-					rcode = -EFAULT;
-					goto cleanup;
-				}
-			}
-			/* sg_simple_element API is 32 bit, but addr < 4GB */
-			sg[i].addr_bus = addr;
-		}
-	}
-
-	do {
-		/*
-		 * Stop any new commands from enterring the
-		 * controller while processing the ioctl
-		 */
-		if (pHba->host) {
-			scsi_block_requests(pHba->host);
-			spin_lock_irqsave(pHba->host->host_lock, flags);
-		}
-		rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER);
-		if (rcode != 0)
-			printk("adpt_i2o_passthru: post wait failed %d %p\n",
-					rcode, reply);
-		if (pHba->host) {
-			spin_unlock_irqrestore(pHba->host->host_lock, flags);
-			scsi_unblock_requests(pHba->host);
-		}
-	} while (rcode == -ETIMEDOUT);
-
-	if(rcode){
-		goto cleanup;
-	}
-
-	if(sg_offset) {
-	/* Copy back the Scatter Gather buffers back to user space */
-		u32 j;
-		// TODO add 64 bit API
-		struct sg_simple_element* sg;
-		int sg_size;
-
-		// re-acquire the original message to handle correctly the sg copy operation
-		memset(&msg, 0, MAX_MESSAGE_SIZE*4); 
-		// get user msg size in u32s 
-		if(get_user(size, &user_msg[0])){
-			rcode = -EFAULT; 
-			goto cleanup; 
-		}
-		size = size>>16;
-		size *= 4;
-		if (size > MAX_MESSAGE_SIZE) {
-			rcode = -EINVAL;
-			goto cleanup;
-		}
-		/* Copy in the user's I2O command */
-		if (copy_from_user (msg, user_msg, size)) {
-			rcode = -EFAULT;
-			goto cleanup;
-		}
-		sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
-
-		// TODO add 64 bit API
-		sg 	 = (struct sg_simple_element*)(msg + sg_offset);
-		for (j = 0; j < sg_count; j++) {
-			/* Copy out the SG list to user's buffer if necessary */
-			if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) {
-				sg_size = sg[j].flag_count & 0xffffff; 
-				// sg_simple_element API is 32 bit
-				if (copy_to_user((void __user *)(ulong)sg[j].addr_bus,sg_list[j], sg_size)) {
-					printk(KERN_WARNING"%s: Could not copy %p TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus);
-					rcode = -EFAULT;
-					goto cleanup;
-				}
-			}
-		}
-	} 
-
-	/* Copy back the reply to user space */
-	if (reply_size) {
-		// we wrote our own values for context - now restore the user supplied ones
-		if(copy_from_user(reply+2, user_msg+2, sizeof(u32)*2)) {
-			printk(KERN_WARNING"%s: Could not copy message context FROM user\n",pHba->name);
-			rcode = -EFAULT;
-		}
-		if(copy_to_user(user_reply, reply, reply_size)) {
-			printk(KERN_WARNING"%s: Could not copy reply TO user\n",pHba->name);
-			rcode = -EFAULT;
-		}
-	}
-
-
-cleanup:
-	if (rcode != -ETIME && rcode != -EINTR) {
-		struct sg_simple_element *sg =
-				(struct sg_simple_element*) (msg +sg_offset);
-		while(sg_index) {
-			if(sg_list[--sg_index]) {
-				dma_free_coherent(&pHba->pDev->dev,
-					sg[sg_index].flag_count & 0xffffff,
-					sg_list[sg_index],
-					sg[sg_index].addr_bus);
-			}
-		}
-	}
-
-free:
-	kfree(sg_list);
-	kfree(reply);
-	return rcode;
-}
-
 #if defined __ia64__ 
 static void adpt_ia64_info(sysInfo_S* si)
 {
@@ -1976,8 +1729,6 @@
 			return -EFAULT;
 		}
 		break;
-	case I2OUSRCMD:
-		return adpt_i2o_passthru(pHba, argp);
 
 	case DPT_CTRLINFO:{
 		drvrHBAinfo_S HbaInfo;
@@ -2114,7 +1865,7 @@
 		} else {
 			/* Ick, we should *never* be here */
 			printk(KERN_ERR "dpti: reply frame not from pool\n");
-			reply = (u8 *)bus_to_virt(m);
+			continue;
 		}
 
 		if (readl(reply) & MSG_FAIL) {
@@ -2134,13 +1885,6 @@
 			adpt_send_nop(pHba, old_m);
 		} 
 		context = readl(reply+8);
-		if(context & 0x40000000){ // IOCTL
-			void *p = adpt_ioctl_from_context(pHba, readl(reply+12));
-			if( p != NULL) {
-				memcpy_fromio(p, reply, REPLY_FRAME_SIZE * 4);
-			}
-			// All IOCTLs will also be post wait
-		}
 		if(context & 0x80000000){ // Post wait message
 			status = readl(reply+16);
 			if(status  >> 24){
@@ -2148,16 +1892,14 @@
 			} else {
 				status = I2O_POST_WAIT_OK;
 			}
-			if(!(context & 0x40000000)) {
-				/*
-				 * The request tag is one less than the command tag
-				 * as the firmware might treat a 0 tag as invalid
-				 */
-				cmd = scsi_host_find_tag(pHba->host,
-							 readl(reply + 12) - 1);
-				if(cmd != NULL) {
-					printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
-				}
+			/*
+			 * The request tag is one less than the command tag
+			 * as the firmware might treat a 0 tag as invalid
+			 */
+			cmd = scsi_host_find_tag(pHba->host,
+						 readl(reply + 12) - 1);
+			if(cmd != NULL) {
+				printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
 			}
 			adpt_i2o_post_wait_complete(context, status);
 		} else { // SCSI message
diff --git a/kernel/drivers/scsi/dpti.h b/kernel/drivers/scsi/dpti.h
index 8a079e8..0565533 100644
--- a/kernel/drivers/scsi/dpti.h
+++ b/kernel/drivers/scsi/dpti.h
@@ -248,7 +248,6 @@
 	void __iomem *FwDebugBLEDflag_P;// Virtual Addr Of FW Debug BLED
 	void __iomem *FwDebugBLEDvalue_P;// Virtual Addr Of FW Debug BLED
 	u32 FwDebugFlags;
-	u32 *ioctl_reply_context[4];
 } adpt_hba;
 
 struct sg_simple_element {
diff --git a/kernel/drivers/scsi/fcoe/fcoe.c b/kernel/drivers/scsi/fcoe/fcoe.c
index 0f92749..30afcbb 100644
--- a/kernel/drivers/scsi/fcoe/fcoe.c
+++ b/kernel/drivers/scsi/fcoe/fcoe.c
@@ -2504,6 +2504,7 @@
 
 out_free:
 	mutex_unlock(&fcoe_config_mutex);
+	fcoe_transport_detach(&fcoe_sw_transport);
 out_destroy:
 	destroy_workqueue(fcoe_wq);
 	return rc;
diff --git a/kernel/drivers/scsi/fcoe/fcoe_ctlr.c b/kernel/drivers/scsi/fcoe/fcoe_ctlr.c
index bbc5d6b..a2d60ad 100644
--- a/kernel/drivers/scsi/fcoe/fcoe_ctlr.c
+++ b/kernel/drivers/scsi/fcoe/fcoe_ctlr.c
@@ -319,16 +319,17 @@
 {
 	struct fcoe_fcf *sel;
 	struct fcoe_fcf *fcf;
+	unsigned long flags;
 
 	mutex_lock(&fip->ctlr_mutex);
-	spin_lock_bh(&fip->ctlr_lock);
+	spin_lock_irqsave(&fip->ctlr_lock, flags);
 
 	kfree_skb(fip->flogi_req);
 	fip->flogi_req = NULL;
 	list_for_each_entry(fcf, &fip->fcfs, list)
 		fcf->flogi_sent = 0;
 
-	spin_unlock_bh(&fip->ctlr_lock);
+	spin_unlock_irqrestore(&fip->ctlr_lock, flags);
 	sel = fip->sel_fcf;
 
 	if (sel && ether_addr_equal(sel->fcf_mac, fip->dest_addr))
@@ -699,6 +700,7 @@
 {
 	struct fc_frame *fp;
 	struct fc_frame_header *fh;
+	unsigned long flags;
 	u16 old_xid;
 	u8 op;
 	u8 mac[ETH_ALEN];
@@ -732,11 +734,11 @@
 		op = FIP_DT_FLOGI;
 		if (fip->mode == FIP_MODE_VN2VN)
 			break;
-		spin_lock_bh(&fip->ctlr_lock);
+		spin_lock_irqsave(&fip->ctlr_lock, flags);
 		kfree_skb(fip->flogi_req);
 		fip->flogi_req = skb;
 		fip->flogi_req_send = 1;
-		spin_unlock_bh(&fip->ctlr_lock);
+		spin_unlock_irqrestore(&fip->ctlr_lock, flags);
 		schedule_work(&fip->timer_work);
 		return -EINPROGRESS;
 	case ELS_FDISC:
@@ -1713,10 +1715,11 @@
 static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip)
 {
 	struct fcoe_fcf *fcf;
+	unsigned long flags;
 	int error;
 
 	mutex_lock(&fip->ctlr_mutex);
-	spin_lock_bh(&fip->ctlr_lock);
+	spin_lock_irqsave(&fip->ctlr_lock, flags);
 	LIBFCOE_FIP_DBG(fip, "re-sending FLOGI - reselect\n");
 	fcf = fcoe_ctlr_select(fip);
 	if (!fcf || fcf->flogi_sent) {
@@ -1727,7 +1730,7 @@
 		fcoe_ctlr_solicit(fip, NULL);
 		error = fcoe_ctlr_flogi_send_locked(fip);
 	}
-	spin_unlock_bh(&fip->ctlr_lock);
+	spin_unlock_irqrestore(&fip->ctlr_lock, flags);
 	mutex_unlock(&fip->ctlr_mutex);
 	return error;
 }
@@ -1744,8 +1747,9 @@
 static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip)
 {
 	struct fcoe_fcf *fcf;
+	unsigned long flags;
 
-	spin_lock_bh(&fip->ctlr_lock);
+	spin_lock_irqsave(&fip->ctlr_lock, flags);
 	fcf = fip->sel_fcf;
 	if (!fcf || !fip->flogi_req_send)
 		goto unlock;
@@ -1772,7 +1776,7 @@
 	} else /* XXX */
 		LIBFCOE_FIP_DBG(fip, "No FCF selected - defer send\n");
 unlock:
-	spin_unlock_bh(&fip->ctlr_lock);
+	spin_unlock_irqrestore(&fip->ctlr_lock, flags);
 }
 
 /**
diff --git a/kernel/drivers/scsi/fcoe/fcoe_sysfs.c b/kernel/drivers/scsi/fcoe/fcoe_sysfs.c
index ffef2c8..68d8027 100644
--- a/kernel/drivers/scsi/fcoe/fcoe_sysfs.c
+++ b/kernel/drivers/scsi/fcoe/fcoe_sysfs.c
@@ -830,14 +830,15 @@
 
 	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 @@
 	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;
 }
diff --git a/kernel/drivers/scsi/hisi_sas/hisi_sas_main.c b/kernel/drivers/scsi/hisi_sas/hisi_sas_main.c
index 1feca45..e5b9229 100644
--- a/kernel/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/kernel/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -1408,7 +1408,7 @@
 				device->linkrate = phy->sas_phy.linkrate;
 
 			hisi_hba->hw->setup_itct(hisi_hba, sas_dev);
-		} else
+		} else if (!port->port_attached)
 			port->id = 0xff;
 	}
 }
diff --git a/kernel/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/kernel/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
index 2c10281..5b54cdd 100644
--- a/kernel/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+++ b/kernel/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
@@ -1152,14 +1152,14 @@
 		}
 		default:
 		{
-			ts->stat = SAM_STAT_CHECK_CONDITION;
+			ts->stat = SAS_SAM_STAT_CHECK_CONDITION;
 			break;
 		}
 		}
 	}
 		break;
 	case SAS_PROTOCOL_SMP:
-		ts->stat = SAM_STAT_CHECK_CONDITION;
+		ts->stat = SAS_SAM_STAT_CHECK_CONDITION;
 		break;
 
 	case SAS_PROTOCOL_SATA:
@@ -1281,7 +1281,7 @@
 		struct scatterlist *sg_resp = &task->smp_task.smp_resp;
 		void *to = page_address(sg_page(sg_resp));
 
-		ts->stat = SAM_STAT_GOOD;
+		ts->stat = SAS_SAM_STAT_GOOD;
 
 		dma_unmap_sg(dev, &task->smp_task.smp_req, 1,
 			     DMA_TO_DEVICE);
@@ -1298,7 +1298,7 @@
 		break;
 
 	default:
-		ts->stat = SAM_STAT_CHECK_CONDITION;
+		ts->stat = SAS_SAM_STAT_CHECK_CONDITION;
 		break;
 	}
 
diff --git a/kernel/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/kernel/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index b75d543..f6e9114 100644
--- a/kernel/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/kernel/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -2026,6 +2026,11 @@
 	u16 dma_tx_err_type = le16_to_cpu(err_record->dma_tx_err_type);
 	u16 sipc_rx_err_type = le16_to_cpu(err_record->sipc_rx_err_type);
 	u32 dma_rx_err_type = le32_to_cpu(err_record->dma_rx_err_type);
+	struct hisi_sas_complete_v2_hdr *complete_queue =
+			hisi_hba->complete_hdr[slot->cmplt_queue];
+	struct hisi_sas_complete_v2_hdr *complete_hdr =
+			&complete_queue[slot->cmplt_queue_slot];
+	u32 dw0 = le32_to_cpu(complete_hdr->dw0);
 	int error = -1;
 
 	if (err_phase == 1) {
@@ -2168,7 +2173,7 @@
 	}
 		break;
 	case SAS_PROTOCOL_SMP:
-		ts->stat = SAM_STAT_CHECK_CONDITION;
+		ts->stat = SAS_SAM_STAT_CHECK_CONDITION;
 		break;
 
 	case SAS_PROTOCOL_SATA:
@@ -2310,7 +2315,8 @@
 			break;
 		}
 		}
-		hisi_sas_sata_done(task, slot);
+		if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)
+			hisi_sas_sata_done(task, slot);
 	}
 		break;
 	default:
@@ -2427,7 +2433,7 @@
 		struct scatterlist *sg_resp = &task->smp_task.smp_resp;
 		void *to = page_address(sg_page(sg_resp));
 
-		ts->stat = SAM_STAT_GOOD;
+		ts->stat = SAS_SAM_STAT_GOOD;
 
 		dma_unmap_sg(dev, &task->smp_task.smp_req, 1,
 			     DMA_TO_DEVICE);
@@ -2441,12 +2447,13 @@
 	case SAS_PROTOCOL_STP:
 	case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
 	{
-		ts->stat = SAM_STAT_GOOD;
-		hisi_sas_sata_done(task, slot);
+		ts->stat = SAS_SAM_STAT_GOOD;
+		if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)
+			hisi_sas_sata_done(task, slot);
 		break;
 	}
 	default:
-		ts->stat = SAM_STAT_CHECK_CONDITION;
+		ts->stat = SAS_SAM_STAT_CHECK_CONDITION;
 		break;
 	}
 
diff --git a/kernel/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/kernel/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index cd41dc0..0d21c64 100644
--- a/kernel/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/kernel/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -392,6 +392,8 @@
 #define CMPLT_HDR_ERROR_PHASE_MSK   (0xff << CMPLT_HDR_ERROR_PHASE_OFF)
 #define CMPLT_HDR_RSPNS_XFRD_OFF	10
 #define CMPLT_HDR_RSPNS_XFRD_MSK	(0x1 << CMPLT_HDR_RSPNS_XFRD_OFF)
+#define CMPLT_HDR_RSPNS_GOOD_OFF	11
+#define CMPLT_HDR_RSPNS_GOOD_MSK	(0x1 << CMPLT_HDR_RSPNS_GOOD_OFF)
 #define CMPLT_HDR_ERX_OFF		12
 #define CMPLT_HDR_ERX_MSK		(0x1 << CMPLT_HDR_ERX_OFF)
 #define CMPLT_HDR_ABORT_STAT_OFF	13
@@ -464,6 +466,9 @@
 
 #define RX_DATA_LEN_UNDERFLOW_OFF	6
 #define RX_DATA_LEN_UNDERFLOW_MSK	(1 << RX_DATA_LEN_UNDERFLOW_OFF)
+
+#define RX_FIS_STATUS_ERR_OFF		0
+#define RX_FIS_STATUS_ERR_MSK		(1 << RX_FIS_STATUS_ERR_OFF)
 
 #define HISI_SAS_COMMAND_ENTRIES_V3_HW 4096
 #define HISI_SAS_MSI_COUNT_V3_HW 32
@@ -2115,7 +2120,7 @@
 	return IRQ_HANDLED;
 }
 
-static void
+static bool
 slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
 	       struct hisi_sas_slot *slot)
 {
@@ -2128,11 +2133,22 @@
 			hisi_sas_status_buf_addr_mem(slot);
 	u32 dma_rx_err_type = le32_to_cpu(record->dma_rx_err_type);
 	u32 trans_tx_fail_type = le32_to_cpu(record->trans_tx_fail_type);
+	u16 sipc_rx_err_type = le16_to_cpu(record->sipc_rx_err_type);
 	u32 dw3 = le32_to_cpu(complete_hdr->dw3);
+	u32 dw0 = le32_to_cpu(complete_hdr->dw0);
 
 	switch (task->task_proto) {
 	case SAS_PROTOCOL_SSP:
 		if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) {
+			/*
+			 * If returned response frame is incorrect because of data underflow,
+			 * but I/O information has been written to the host memory, we examine
+			 * response IU.
+			 */
+			if (!(dw0 & CMPLT_HDR_RSPNS_GOOD_MSK) &&
+			    (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK))
+				return false;
+
 			ts->residual = trans_tx_fail_type;
 			ts->stat = SAS_DATA_UNDERRUN;
 		} else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
@@ -2146,7 +2162,10 @@
 	case SAS_PROTOCOL_SATA:
 	case SAS_PROTOCOL_STP:
 	case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
-		if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) {
+		if ((dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) &&
+		    (sipc_rx_err_type & RX_FIS_STATUS_ERR_MSK)) {
+			ts->stat = SAS_PROTO_RESPONSE;
+		} else if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) {
 			ts->residual = trans_tx_fail_type;
 			ts->stat = SAS_DATA_UNDERRUN;
 		} else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
@@ -2156,14 +2175,16 @@
 			ts->stat = SAS_OPEN_REJECT;
 			ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
 		}
-		hisi_sas_sata_done(task, slot);
+		if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)
+			hisi_sas_sata_done(task, slot);
 		break;
 	case SAS_PROTOCOL_SMP:
-		ts->stat = SAM_STAT_CHECK_CONDITION;
+		ts->stat = SAS_SAM_STAT_CHECK_CONDITION;
 		break;
 	default:
 		break;
 	}
+	return true;
 }
 
 static void slot_complete_v3_hw(struct hisi_hba *hisi_hba,
@@ -2238,18 +2259,20 @@
 	if ((dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) {
 		u32 *error_info = hisi_sas_status_buf_addr_mem(slot);
 
-		slot_err_v3_hw(hisi_hba, task, slot);
-		if (ts->stat != SAS_DATA_UNDERRUN)
-			dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n",
-				 slot->idx, task, sas_dev->device_id,
-				 dw0, dw1, complete_hdr->act, dw3,
-				 error_info[0], error_info[1],
-				 error_info[2], error_info[3]);
-		if (unlikely(slot->abort)) {
-			sas_task_abort(task);
-			return;
+		if (slot_err_v3_hw(hisi_hba, task, slot)) {
+			if (ts->stat != SAS_DATA_UNDERRUN)
+				dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d addr=%016llx CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n",
+					slot->idx, task, sas_dev->device_id,
+					SAS_ADDR(device->sas_addr),
+					dw0, dw1, complete_hdr->act, dw3,
+					error_info[0], error_info[1],
+					error_info[2], error_info[3]);
+			if (unlikely(slot->abort)) {
+				sas_task_abort(task);
+				return;
+			}
+			goto out;
 		}
-		goto out;
 	}
 
 	switch (task->task_proto) {
@@ -2265,7 +2288,7 @@
 		struct scatterlist *sg_resp = &task->smp_task.smp_resp;
 		void *to = page_address(sg_page(sg_resp));
 
-		ts->stat = SAM_STAT_GOOD;
+		ts->stat = SAS_SAM_STAT_GOOD;
 
 		dma_unmap_sg(dev, &task->smp_task.smp_req, 1,
 			     DMA_TO_DEVICE);
@@ -2278,11 +2301,12 @@
 	case SAS_PROTOCOL_SATA:
 	case SAS_PROTOCOL_STP:
 	case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
-		ts->stat = SAM_STAT_GOOD;
-		hisi_sas_sata_done(task, slot);
+		ts->stat = SAS_SAM_STAT_GOOD;
+		if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)
+			hisi_sas_sata_done(task, slot);
 		break;
 	default:
-		ts->stat = SAM_STAT_CHECK_CONDITION;
+		ts->stat = SAS_SAM_STAT_CHECK_CONDITION;
 		break;
 	}
 
@@ -2402,8 +2426,7 @@
 	hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW;
 	shost->nr_hw_queues = hisi_hba->cq_nvecs;
 
-	devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev);
-	return 0;
+	return devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev);
 }
 
 static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
diff --git a/kernel/drivers/scsi/hosts.c b/kernel/drivers/scsi/hosts.c
index d664c46..18321cf 100644
--- a/kernel/drivers/scsi/hosts.c
+++ b/kernel/drivers/scsi/hosts.c
@@ -180,6 +180,7 @@
 	scsi_forget_host(shost);
 	mutex_unlock(&shost->scan_mutex);
 	scsi_proc_host_rm(shost);
+	scsi_proc_hostdir_rm(shost->hostt);
 
 	spin_lock_irqsave(shost->host_lock, flags);
 	if (scsi_host_set_state(shost, SHOST_DEL))
@@ -321,9 +322,7 @@
 	struct Scsi_Host *shost = dev_to_shost(dev);
 	struct device *parent = dev->parent;
 
-	scsi_proc_hostdir_rm(shost->hostt);
-
-	/* Wait for functions invoked through call_rcu(&shost->rcu, ...) */
+	/* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */
 	rcu_barrier();
 
 	if (shost->tmf_work_q)
diff --git a/kernel/drivers/scsi/hpsa.c b/kernel/drivers/scsi/hpsa.c
index 8df70c9..a44a098 100644
--- a/kernel/drivers/scsi/hpsa.c
+++ b/kernel/drivers/scsi/hpsa.c
@@ -5834,7 +5834,7 @@
 {
 	struct Scsi_Host *sh;
 
-	sh = scsi_host_alloc(&hpsa_driver_template, sizeof(h));
+	sh = scsi_host_alloc(&hpsa_driver_template, sizeof(struct ctlr_info));
 	if (sh == NULL) {
 		dev_err(&h->pdev->dev, "scsi_host_alloc failed\n");
 		return -ENOMEM;
@@ -8904,7 +8904,7 @@
 		destroy_workqueue(h->monitor_ctlr_wq);
 		h->monitor_ctlr_wq = NULL;
 	}
-	kfree(h);
+	hpda_free_ctlr_info(h);
 	return rc;
 }
 
@@ -9764,7 +9764,8 @@
 	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:
@@ -9800,10 +9801,12 @@
 
 	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;
diff --git a/kernel/drivers/scsi/ipr.c b/kernel/drivers/scsi/ipr.c
index 90e8a53..8c37673 100644
--- a/kernel/drivers/scsi/ipr.c
+++ b/kernel/drivers/scsi/ipr.c
@@ -1516,23 +1516,22 @@
 }
 
 /**
- * strip_and_pad_whitespace - Strip and pad trailing whitespace.
- * @i:		index into buffer
- * @buf:		string to modify
+ * strip_whitespace - Strip and pad trailing whitespace.
+ * @i:		size of buffer
+ * @buf:	string to modify
  *
- * This function will strip all trailing whitespace, pad the end
- * of the string with a single space, and NULL terminate the string.
+ * This function will strip all trailing whitespace and
+ * NUL terminate the string.
  *
- * Return value:
- * 	new length of string
  **/
-static int strip_and_pad_whitespace(int i, char *buf)
+static void strip_whitespace(int i, char *buf)
 {
+	if (i < 1)
+		return;
+	i--;
 	while (i && buf[i] == ' ')
 		i--;
-	buf[i+1] = ' ';
-	buf[i+2] = '\0';
-	return i + 2;
+	buf[i+1] = '\0';
 }
 
 /**
@@ -1547,19 +1546,21 @@
 static void ipr_log_vpd_compact(char *prefix, struct ipr_hostrcb *hostrcb,
 				struct ipr_vpd *vpd)
 {
-	char buffer[IPR_VENDOR_ID_LEN + IPR_PROD_ID_LEN + IPR_SERIAL_NUM_LEN + 3];
-	int i = 0;
+	char vendor_id[IPR_VENDOR_ID_LEN + 1];
+	char product_id[IPR_PROD_ID_LEN + 1];
+	char sn[IPR_SERIAL_NUM_LEN + 1];
 
-	memcpy(buffer, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN);
-	i = strip_and_pad_whitespace(IPR_VENDOR_ID_LEN - 1, buffer);
+	memcpy(vendor_id, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN);
+	strip_whitespace(IPR_VENDOR_ID_LEN, vendor_id);
 
-	memcpy(&buffer[i], vpd->vpids.product_id, IPR_PROD_ID_LEN);
-	i = strip_and_pad_whitespace(i + IPR_PROD_ID_LEN - 1, buffer);
+	memcpy(product_id, vpd->vpids.product_id, IPR_PROD_ID_LEN);
+	strip_whitespace(IPR_PROD_ID_LEN, product_id);
 
-	memcpy(&buffer[i], vpd->sn, IPR_SERIAL_NUM_LEN);
-	buffer[IPR_SERIAL_NUM_LEN + i] = '\0';
+	memcpy(sn, vpd->sn, IPR_SERIAL_NUM_LEN);
+	strip_whitespace(IPR_SERIAL_NUM_LEN, sn);
 
-	ipr_hcam_err(hostrcb, "%s VPID/SN: %s\n", prefix, buffer);
+	ipr_hcam_err(hostrcb, "%s VPID/SN: %s %s %s\n", prefix,
+		     vendor_id, product_id, sn);
 }
 
 /**
@@ -10870,11 +10871,19 @@
  **/
 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;
 }
 
 /**
diff --git a/kernel/drivers/scsi/isci/request.c b/kernel/drivers/scsi/isci/request.c
index 6e08179..b6d68d8 100644
--- a/kernel/drivers/scsi/isci/request.c
+++ b/kernel/drivers/scsi/isci/request.c
@@ -2574,7 +2574,7 @@
 			if (!idev)
 				*status_ptr = SAS_DEVICE_UNKNOWN;
 			else
-				*status_ptr = SAM_STAT_TASK_ABORTED;
+				*status_ptr = SAS_SAM_STAT_TASK_ABORTED;
 
 			clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
 		}
@@ -2704,7 +2704,7 @@
 	default:
 		/* Task in the target is not done. */
 		*response_ptr = SAS_TASK_UNDELIVERED;
-		*status_ptr = SAM_STAT_TASK_ABORTED;
+		*status_ptr = SAS_SAM_STAT_TASK_ABORTED;
 
 		if (task->task_proto == SAS_PROTOCOL_SMP)
 			set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
@@ -2727,7 +2727,7 @@
 	if (ac_err_mask(fis->status))
 		ts->stat = SAS_PROTO_RESPONSE;
 	else
-		ts->stat = SAM_STAT_GOOD;
+		ts->stat = SAS_SAM_STAT_GOOD;
 
 	ts->resp = SAS_TASK_COMPLETE;
 }
@@ -2790,7 +2790,7 @@
 	case SCI_IO_SUCCESS_IO_DONE_EARLY:
 
 		response = SAS_TASK_COMPLETE;
-		status   = SAM_STAT_GOOD;
+		status   = SAS_SAM_STAT_GOOD;
 		set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
 
 		if (completion_status == SCI_IO_SUCCESS_IO_DONE_EARLY) {
@@ -2860,7 +2860,7 @@
 
 		/* Fail the I/O. */
 		response = SAS_TASK_UNDELIVERED;
-		status = SAM_STAT_TASK_ABORTED;
+		status = SAS_SAM_STAT_TASK_ABORTED;
 
 		clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
 		break;
diff --git a/kernel/drivers/scsi/isci/task.c b/kernel/drivers/scsi/isci/task.c
index 26fa1a4..1d1db40 100644
--- a/kernel/drivers/scsi/isci/task.c
+++ b/kernel/drivers/scsi/isci/task.c
@@ -160,7 +160,7 @@
 
 			isci_task_refuse(ihost, task,
 					 SAS_TASK_UNDELIVERED,
-					 SAM_STAT_TASK_ABORTED);
+					 SAS_SAM_STAT_TASK_ABORTED);
 		} else {
 			task->task_state_flags |= SAS_TASK_AT_INITIATOR;
 			spin_unlock_irqrestore(&task->task_state_lock, flags);
diff --git a/kernel/drivers/scsi/iscsi_tcp.c b/kernel/drivers/scsi/iscsi_tcp.c
index 6485c1a..def9fac 100644
--- a/kernel/drivers/scsi/iscsi_tcp.c
+++ b/kernel/drivers/scsi/iscsi_tcp.c
@@ -721,13 +721,12 @@
 		iscsi_set_param(cls_conn, param, buf, buflen);
 		break;
 	case ISCSI_PARAM_DATADGST_EN:
-		iscsi_set_param(cls_conn, param, buf, buflen);
-
 		mutex_lock(&tcp_sw_conn->sock_lock);
 		if (!tcp_sw_conn->sock) {
 			mutex_unlock(&tcp_sw_conn->sock_lock);
 			return -ENOTCONN;
 		}
+		iscsi_set_param(cls_conn, param, buf, buflen);
 		tcp_sw_conn->sendpage = conn->datadgst_en ?
 			sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage;
 		mutex_unlock(&tcp_sw_conn->sock_lock);
@@ -802,7 +801,7 @@
 				       enum iscsi_host_param param, char *buf)
 {
 	struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(shost);
-	struct iscsi_session *session = tcp_sw_host->session;
+	struct iscsi_session *session;
 	struct iscsi_conn *conn;
 	struct iscsi_tcp_conn *tcp_conn;
 	struct iscsi_sw_tcp_conn *tcp_sw_conn;
@@ -812,6 +811,7 @@
 
 	switch (param) {
 	case ISCSI_HOST_PARAM_IPADDRESS:
+		session = tcp_sw_host->session;
 		if (!session)
 			return -ENOTCONN;
 
@@ -906,12 +906,14 @@
 	if (!cls_session)
 		goto remove_host;
 	session = cls_session->dd_data;
-	tcp_sw_host = iscsi_host_priv(shost);
-	tcp_sw_host->session = session;
 
 	shost->can_queue = session->scsi_cmds_max;
 	if (iscsi_tcp_r2tpool_alloc(session))
 		goto remove_session;
+
+	/* We are now fully setup so expose the session to sysfs. */
+	tcp_sw_host = iscsi_host_priv(shost);
+	tcp_sw_host->session = session;
 	return cls_session;
 
 remove_session:
diff --git a/kernel/drivers/scsi/libsas/sas_ata.c b/kernel/drivers/scsi/libsas/sas_ata.c
index a1a06a8..f92b889 100644
--- a/kernel/drivers/scsi/libsas/sas_ata.c
+++ b/kernel/drivers/scsi/libsas/sas_ata.c
@@ -122,9 +122,10 @@
 		}
 	}
 
-	if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD ||
-	    ((stat->stat == SAM_STAT_CHECK_CONDITION &&
-	      dev->sata_dev.class == ATA_DEV_ATAPI))) {
+	if (stat->stat == SAS_PROTO_RESPONSE ||
+	    stat->stat == SAS_SAM_STAT_GOOD ||
+	    (stat->stat == SAS_SAM_STAT_CHECK_CONDITION &&
+	      dev->sata_dev.class == ATA_DEV_ATAPI)) {
 		memcpy(dev->sata_dev.fis, resp->ending_fis, ATA_RESP_FIS_SIZE);
 
 		if (!link->sactive) {
diff --git a/kernel/drivers/scsi/libsas/sas_expander.c b/kernel/drivers/scsi/libsas/sas_expander.c
index 51485d0..8444a42 100644
--- a/kernel/drivers/scsi/libsas/sas_expander.c
+++ b/kernel/drivers/scsi/libsas/sas_expander.c
@@ -101,7 +101,7 @@
 			}
 		}
 		if (task->task_status.resp == SAS_TASK_COMPLETE &&
-		    task->task_status.stat == SAM_STAT_GOOD) {
+		    task->task_status.stat == SAS_SAM_STAT_GOOD) {
 			res = 0;
 			break;
 		}
diff --git a/kernel/drivers/scsi/libsas/sas_task.c b/kernel/drivers/scsi/libsas/sas_task.c
index e2d4259..2966ead 100644
--- a/kernel/drivers/scsi/libsas/sas_task.c
+++ b/kernel/drivers/scsi/libsas/sas_task.c
@@ -20,7 +20,7 @@
 	else if (iu->datapres == 1)
 		tstat->stat = iu->resp_data[3];
 	else if (iu->datapres == 2) {
-		tstat->stat = SAM_STAT_CHECK_CONDITION;
+		tstat->stat = SAS_SAM_STAT_CHECK_CONDITION;
 		tstat->buf_valid_size =
 			min_t(int, SAS_STATUS_BUF_SIZE,
 			      be32_to_cpu(iu->sense_data_len));
@@ -32,7 +32,7 @@
 	}
 	else
 		/* when datapres contains corrupt/unknown value... */
-		tstat->stat = SAM_STAT_CHECK_CONDITION;
+		tstat->stat = SAS_SAM_STAT_CHECK_CONDITION;
 }
 EXPORT_SYMBOL_GPL(sas_ssp_task_response);
 
diff --git a/kernel/drivers/scsi/lpfc/lpfc_debugfs.c b/kernel/drivers/scsi/lpfc/lpfc_debugfs.c
index fbc76d6..f91eee0 100644
--- a/kernel/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/kernel/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -2159,10 +2159,13 @@
 	char mybuf[64];
 	char *pbuf;
 	int i;
+	size_t bsize;
 
 	memset(mybuf, 0, sizeof(mybuf));
 
-	if (copy_from_user(mybuf, buf, nbytes))
+	bsize = min(nbytes, (sizeof(mybuf) - 1));
+
+	if (copy_from_user(mybuf, buf, bsize))
 		return -EFAULT;
 	pbuf = &mybuf[0];
 
@@ -2183,7 +2186,7 @@
 			qp->lock_conflict.wq_access = 0;
 		}
 	}
-	return nbytes;
+	return bsize;
 }
 #endif
 
@@ -5906,7 +5909,7 @@
 					    phba->hba_debugfs_root,
 					    phba,
 					    &lpfc_debugfs_op_multixripools);
-		if (!phba->debug_multixri_pools) {
+		if (IS_ERR(phba->debug_multixri_pools)) {
 			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 					 "0527 Cannot create debugfs multixripools\n");
 			goto debug_failed;
@@ -5918,7 +5921,7 @@
 			debugfs_create_file(name, 0644,
 					    phba->hba_debugfs_root,
 					    phba, &lpfc_debugfs_ras_log);
-		if (!phba->debug_ras_log) {
+		if (IS_ERR(phba->debug_ras_log)) {
 			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 					 "6148 Cannot create debugfs"
 					 " ras_log\n");
@@ -5939,7 +5942,7 @@
 			debugfs_create_file(name, S_IFREG | 0644,
 					    phba->hba_debugfs_root,
 					    phba, &lpfc_debugfs_op_lockstat);
-		if (!phba->debug_lockstat) {
+		if (IS_ERR(phba->debug_lockstat)) {
 			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 					 "4610 Can't create debugfs lockstat\n");
 			goto debug_failed;
@@ -6168,7 +6171,7 @@
 		debugfs_create_file(name, 0644,
 				    vport->vport_debugfs_root,
 				    vport, &lpfc_debugfs_op_scsistat);
-	if (!vport->debug_scsistat) {
+	if (IS_ERR(vport->debug_scsistat)) {
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 				 "4611 Cannot create debugfs scsistat\n");
 		goto debug_failed;
@@ -6179,7 +6182,7 @@
 		debugfs_create_file(name, 0644,
 				    vport->vport_debugfs_root,
 				    vport, &lpfc_debugfs_op_ioktime);
-	if (!vport->debug_ioktime) {
+	if (IS_ERR(vport->debug_ioktime)) {
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 				 "0815 Cannot create debugfs ioktime\n");
 		goto debug_failed;
diff --git a/kernel/drivers/scsi/lpfc/lpfc_init.c b/kernel/drivers/scsi/lpfc/lpfc_init.c
index 17200b4..1bb3c96 100644
--- a/kernel/drivers/scsi/lpfc/lpfc_init.c
+++ b/kernel/drivers/scsi/lpfc/lpfc_init.c
@@ -10477,7 +10477,7 @@
 				goto out_iounmap_all;
 		} else {
 			error = -ENOMEM;
-			goto out_iounmap_all;
+			goto out_iounmap_ctrl;
 		}
 	}
 
@@ -10495,7 +10495,7 @@
 			dev_err(&pdev->dev,
 			   "ioremap failed for SLI4 HBA dpp registers.\n");
 			error = -ENOMEM;
-			goto out_iounmap_ctrl;
+			goto out_iounmap_all;
 		}
 		phba->pci_bar4_memmap_p = phba->sli4_hba.dpp_regs_memmap_p;
 	}
@@ -10520,9 +10520,11 @@
 	return 0;
 
 out_iounmap_all:
-	iounmap(phba->sli4_hba.drbl_regs_memmap_p);
+	if (phba->sli4_hba.drbl_regs_memmap_p)
+		iounmap(phba->sli4_hba.drbl_regs_memmap_p);
 out_iounmap_ctrl:
-	iounmap(phba->sli4_hba.ctrl_regs_memmap_p);
+	if (phba->sli4_hba.ctrl_regs_memmap_p)
+		iounmap(phba->sli4_hba.ctrl_regs_memmap_p);
 out_iounmap_conf:
 	iounmap(phba->sli4_hba.conf_regs_memmap_p);
 
diff --git a/kernel/drivers/scsi/lpfc/lpfc_sli.c b/kernel/drivers/scsi/lpfc/lpfc_sli.c
index 755d68b..923ceab 100644
--- a/kernel/drivers/scsi/lpfc/lpfc_sli.c
+++ b/kernel/drivers/scsi/lpfc/lpfc_sli.c
@@ -20816,20 +20816,20 @@
 static struct lpfc_io_buf *
 lpfc_get_io_buf_from_expedite_pool(struct lpfc_hba *phba)
 {
-	struct lpfc_io_buf *lpfc_ncmd;
+	struct lpfc_io_buf *lpfc_ncmd = NULL, *iter;
 	struct lpfc_io_buf *lpfc_ncmd_next;
 	unsigned long iflag;
 	struct lpfc_epd_pool *epd_pool;
 
 	epd_pool = &phba->epd_pool;
-	lpfc_ncmd = NULL;
 
 	spin_lock_irqsave(&epd_pool->lock, iflag);
 	if (epd_pool->count > 0) {
-		list_for_each_entry_safe(lpfc_ncmd, lpfc_ncmd_next,
+		list_for_each_entry_safe(iter, lpfc_ncmd_next,
 					 &epd_pool->list, list) {
-			list_del(&lpfc_ncmd->list);
+			list_del(&iter->list);
 			epd_pool->count--;
+			lpfc_ncmd = iter;
 			break;
 		}
 	}
diff --git a/kernel/drivers/scsi/megaraid.c b/kernel/drivers/scsi/megaraid.c
index daffa36..810d803 100644
--- a/kernel/drivers/scsi/megaraid.c
+++ b/kernel/drivers/scsi/megaraid.c
@@ -1443,6 +1443,7 @@
 		 */
 		if (cmdid == CMDID_INT_CMDS) {
 			scb = &adapter->int_scb;
+			cmd = scb->cmd;
 
 			list_del_init(&scb->list);
 			scb->state = SCB_FREE;
diff --git a/kernel/drivers/scsi/megaraid/megaraid_sas.h b/kernel/drivers/scsi/megaraid/megaraid_sas.h
index c088a84..f78cb87 100644
--- a/kernel/drivers/scsi/megaraid/megaraid_sas.h
+++ b/kernel/drivers/scsi/megaraid/megaraid_sas.h
@@ -1517,6 +1517,8 @@
 #define MEGASAS_MAX_LD_IDS			(MEGASAS_MAX_LD_CHANNELS * \
 						MEGASAS_MAX_DEV_PER_CHANNEL)
 
+#define MEGASAS_MAX_SUPPORTED_LD_IDS		240
+
 #define MEGASAS_MAX_SECTORS                    (2*1024)
 #define MEGASAS_MAX_SECTORS_IEEE		(2*128)
 #define MEGASAS_DBG_LVL				1
@@ -2325,7 +2327,7 @@
 	u32 support_morethan256jbod; /* FW support for more than 256 PD/JBOD */
 	bool use_seqnum_jbod_fp;   /* Added for PD sequence */
 	bool smp_affinity_enable;
-	spinlock_t crashdump_lock;
+	struct mutex crashdump_lock;
 
 	struct megasas_register_set __iomem *reg_set;
 	u32 __iomem *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY];
diff --git a/kernel/drivers/scsi/megaraid/megaraid_sas_base.c b/kernel/drivers/scsi/megaraid/megaraid_sas_base.c
index 84a2e92..ec9a19d 100644
--- a/kernel/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/kernel/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -3221,14 +3221,13 @@
 	struct megasas_instance *instance =
 		(struct megasas_instance *) shost->hostdata;
 	int val = 0;
-	unsigned long flags;
 
 	if (kstrtoint(buf, 0, &val) != 0)
 		return -EINVAL;
 
-	spin_lock_irqsave(&instance->crashdump_lock, flags);
+	mutex_lock(&instance->crashdump_lock);
 	instance->fw_crash_buffer_offset = val;
-	spin_unlock_irqrestore(&instance->crashdump_lock, flags);
+	mutex_unlock(&instance->crashdump_lock);
 	return strlen(buf);
 }
 
@@ -3243,24 +3242,23 @@
 	unsigned long dmachunk = CRASH_DMA_BUF_SIZE;
 	unsigned long chunk_left_bytes;
 	unsigned long src_addr;
-	unsigned long flags;
 	u32 buff_offset;
 
-	spin_lock_irqsave(&instance->crashdump_lock, flags);
+	mutex_lock(&instance->crashdump_lock);
 	buff_offset = instance->fw_crash_buffer_offset;
-	if (!instance->crash_dump_buf &&
+	if (!instance->crash_dump_buf ||
 		!((instance->fw_crash_state == AVAILABLE) ||
 		(instance->fw_crash_state == COPYING))) {
 		dev_err(&instance->pdev->dev,
 			"Firmware crash dump is not available\n");
-		spin_unlock_irqrestore(&instance->crashdump_lock, flags);
+		mutex_unlock(&instance->crashdump_lock);
 		return -EINVAL;
 	}
 
 	if (buff_offset > (instance->fw_crash_buffer_size * dmachunk)) {
 		dev_err(&instance->pdev->dev,
 			"Firmware crash dump offset is out of range\n");
-		spin_unlock_irqrestore(&instance->crashdump_lock, flags);
+		mutex_unlock(&instance->crashdump_lock);
 		return 0;
 	}
 
@@ -3272,7 +3270,7 @@
 	src_addr = (unsigned long)instance->crash_buf[buff_offset / dmachunk] +
 		(buff_offset % dmachunk);
 	memcpy(buf, (void *)src_addr, size);
-	spin_unlock_irqrestore(&instance->crashdump_lock, flags);
+	mutex_unlock(&instance->crashdump_lock);
 
 	return size;
 }
@@ -3297,7 +3295,6 @@
 	struct megasas_instance *instance =
 		(struct megasas_instance *) shost->hostdata;
 	int val = 0;
-	unsigned long flags;
 
 	if (kstrtoint(buf, 0, &val) != 0)
 		return -EINVAL;
@@ -3311,9 +3308,9 @@
 	instance->fw_crash_state = val;
 
 	if ((val == COPIED) || (val == COPY_ERROR)) {
-		spin_lock_irqsave(&instance->crashdump_lock, flags);
+		mutex_lock(&instance->crashdump_lock);
 		megasas_free_host_crash_buffer(instance);
-		spin_unlock_irqrestore(&instance->crashdump_lock, flags);
+		mutex_unlock(&instance->crashdump_lock);
 		if (val == COPY_ERROR)
 			dev_info(&instance->pdev->dev, "application failed to "
 				"copy Firmware crash dump\n");
@@ -7325,7 +7322,7 @@
 	init_waitqueue_head(&instance->int_cmd_wait_q);
 	init_waitqueue_head(&instance->abort_cmd_wait_q);
 
-	spin_lock_init(&instance->crashdump_lock);
+	mutex_init(&instance->crashdump_lock);
 	spin_lock_init(&instance->mfi_pool_lock);
 	spin_lock_init(&instance->hba_lock);
 	spin_lock_init(&instance->stream_lock);
diff --git a/kernel/drivers/scsi/megaraid/megaraid_sas_fp.c b/kernel/drivers/scsi/megaraid/megaraid_sas_fp.c
index 83f69c3..ec10d35 100644
--- a/kernel/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/kernel/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -358,7 +358,7 @@
 		ld = MR_TargetIdToLdGet(i, drv_map);
 
 		/* For non existing VDs, iterate to next VD*/
-		if (ld >= (MAX_LOGICAL_DRIVES_EXT - 1))
+		if (ld >= MEGASAS_MAX_SUPPORTED_LD_IDS)
 			continue;
 
 		raid = MR_LdRaidGet(ld, drv_map);
diff --git a/kernel/drivers/scsi/megaraid/megaraid_sas_fusion.c b/kernel/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 7838c79..8eb126d 100644
--- a/kernel/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/kernel/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -4656,7 +4656,7 @@
 	devhandle = megasas_get_tm_devhandle(scmd->device);
 
 	if (devhandle == (u16)ULONG_MAX) {
-		ret = SUCCESS;
+		ret = FAILED;
 		sdev_printk(KERN_INFO, scmd->device,
 			"task abort issued for invalid devhandle\n");
 		mutex_unlock(&instance->reset_mutex);
@@ -4726,7 +4726,7 @@
 	devhandle = megasas_get_tm_devhandle(scmd->device);
 
 	if (devhandle == (u16)ULONG_MAX) {
-		ret = SUCCESS;
+		ret = FAILED;
 		sdev_printk(KERN_INFO, scmd->device,
 			"target reset issued for invalid devhandle\n");
 		mutex_unlock(&instance->reset_mutex);
diff --git a/kernel/drivers/scsi/mpt3sas/mpt3sas_base.c b/kernel/drivers/scsi/mpt3sas/mpt3sas_base.c
index c1b76cd..3728e4c 100644
--- a/kernel/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/kernel/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -131,6 +131,9 @@
 static void
 _base_clear_outstanding_commands(struct MPT3SAS_ADAPTER *ioc);
 
+static u32
+_base_readl_ext_retry(const volatile void __iomem *addr);
+
 /**
  * mpt3sas_base_check_cmd_timeout - Function
  *		to check timeout and command termination due
@@ -202,6 +205,20 @@
 		ret_val = readl(addr);
 		i++;
 	} while (ret_val == 0 && i < 3);
+
+	return ret_val;
+}
+
+static u32
+_base_readl_ext_retry(const volatile void __iomem *addr)
+{
+	u32 i, ret_val;
+
+	for (i = 0 ; i < 30 ; i++) {
+		ret_val = readl(addr);
+		if (ret_val == 0)
+			continue;
+	}
 
 	return ret_val;
 }
@@ -861,7 +878,7 @@
 
 	dump_stack();
 
-	doorbell = ioc->base_readl(&ioc->chip->Doorbell);
+	doorbell = ioc->base_readl_ext_retry(&ioc->chip->Doorbell);
 	if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
 		mpt3sas_print_fault_code(ioc, doorbell &
 		    MPI2_DOORBELL_DATA_MASK);
@@ -2822,19 +2839,25 @@
 _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev)
 {
 	struct sysinfo s;
+	u64 coherent_dma_mask, dma_mask;
 
-	if (ioc->is_mcpu_endpoint ||
-	    sizeof(dma_addr_t) == 4 || ioc->use_32bit_dma ||
-	    dma_get_required_mask(&pdev->dev) <= DMA_BIT_MASK(32))
+	if (ioc->is_mcpu_endpoint || sizeof(dma_addr_t) == 4) {
 		ioc->dma_mask = 32;
+		coherent_dma_mask = dma_mask = DMA_BIT_MASK(32);
 	/* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */
-	else if (ioc->hba_mpi_version_belonged > MPI2_VERSION)
+	} else if (ioc->hba_mpi_version_belonged > MPI2_VERSION) {
 		ioc->dma_mask = 63;
-	else
+		coherent_dma_mask = dma_mask = DMA_BIT_MASK(63);
+	} else {
 		ioc->dma_mask = 64;
+		coherent_dma_mask = dma_mask = DMA_BIT_MASK(64);
+	}
 
-	if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(ioc->dma_mask)) ||
-	    dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(ioc->dma_mask)))
+	if (ioc->use_32bit_dma)
+		coherent_dma_mask = DMA_BIT_MASK(32);
+
+	if (dma_set_mask(&pdev->dev, dma_mask) ||
+	    dma_set_coherent_mask(&pdev->dev, coherent_dma_mask))
 		return -ENODEV;
 
 	if (ioc->dma_mask > 32) {
@@ -4905,6 +4928,9 @@
 		}
 		dma_pool_destroy(ioc->pcie_sgl_dma_pool);
 	}
+	kfree(ioc->pcie_sg_lookup);
+	ioc->pcie_sg_lookup = NULL;
+
 	if (ioc->config_page) {
 		dexitprintk(ioc,
 			    ioc_info(ioc, "config_page(0x%p): free\n",
@@ -5658,7 +5684,7 @@
 {
 	u32 s, sc;
 
-	s = ioc->base_readl(&ioc->chip->Doorbell);
+	s = ioc->base_readl_ext_retry(&ioc->chip->Doorbell);
 	sc = s & MPI2_IOC_STATE_MASK;
 	return cooked ? sc : s;
 }
@@ -5803,7 +5829,7 @@
 					   __func__, count, timeout));
 			return 0;
 		} else if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) {
-			doorbell = ioc->base_readl(&ioc->chip->Doorbell);
+			doorbell = ioc->base_readl_ext_retry(&ioc->chip->Doorbell);
 			if ((doorbell & MPI2_IOC_STATE_MASK) ==
 			    MPI2_IOC_STATE_FAULT) {
 				mpt3sas_print_fault_code(ioc, doorbell);
@@ -5843,7 +5869,7 @@
 	count = 0;
 	cntdn = 1000 * timeout;
 	do {
-		doorbell_reg = ioc->base_readl(&ioc->chip->Doorbell);
+		doorbell_reg = ioc->base_readl_ext_retry(&ioc->chip->Doorbell);
 		if (!(doorbell_reg & MPI2_DOORBELL_USED)) {
 			dhsprintk(ioc,
 				  ioc_info(ioc, "%s: successful count(%d), timeout(%d)\n",
@@ -5980,7 +6006,7 @@
 	__le32 *mfp;
 
 	/* make sure doorbell is not in use */
-	if ((ioc->base_readl(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) {
+	if ((ioc->base_readl_ext_retry(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) {
 		ioc_err(ioc, "doorbell is in use (line=%d)\n", __LINE__);
 		return -EFAULT;
 	}
@@ -6029,7 +6055,7 @@
 	}
 
 	/* read the first two 16-bits, it gives the total length of the reply */
-	reply[0] = le16_to_cpu(ioc->base_readl(&ioc->chip->Doorbell)
+	reply[0] = le16_to_cpu(ioc->base_readl_ext_retry(&ioc->chip->Doorbell)
 	    & MPI2_DOORBELL_DATA_MASK);
 	writel(0, &ioc->chip->HostInterruptStatus);
 	if ((_base_wait_for_doorbell_int(ioc, 5))) {
@@ -6037,7 +6063,7 @@
 			__LINE__);
 		return -EFAULT;
 	}
-	reply[1] = le16_to_cpu(ioc->base_readl(&ioc->chip->Doorbell)
+	reply[1] = le16_to_cpu(ioc->base_readl_ext_retry(&ioc->chip->Doorbell)
 	    & MPI2_DOORBELL_DATA_MASK);
 	writel(0, &ioc->chip->HostInterruptStatus);
 
@@ -6048,10 +6074,10 @@
 			return -EFAULT;
 		}
 		if (i >=  reply_bytes/2) /* overflow case */
-			ioc->base_readl(&ioc->chip->Doorbell);
+			ioc->base_readl_ext_retry(&ioc->chip->Doorbell);
 		else
 			reply[i] = le16_to_cpu(
-			    ioc->base_readl(&ioc->chip->Doorbell)
+			    ioc->base_readl_ext_retry(&ioc->chip->Doorbell)
 			    & MPI2_DOORBELL_DATA_MASK);
 		writel(0, &ioc->chip->HostInterruptStatus);
 	}
@@ -6897,7 +6923,7 @@
 			goto out;
 		}
 
-		host_diagnostic = ioc->base_readl(&ioc->chip->HostDiagnostic);
+		host_diagnostic = ioc->base_readl_ext_retry(&ioc->chip->HostDiagnostic);
 		drsprintk(ioc,
 			  ioc_info(ioc, "wrote magic sequence: count(%d), host_diagnostic(0x%08x)\n",
 				   count, host_diagnostic));
@@ -6917,7 +6943,7 @@
 	for (count = 0; count < (300000000 /
 		MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC); count++) {
 
-		host_diagnostic = ioc->base_readl(&ioc->chip->HostDiagnostic);
+		host_diagnostic = ioc->base_readl_ext_retry(&ioc->chip->HostDiagnostic);
 
 		if (host_diagnostic == 0xFFFFFFFF) {
 			ioc_info(ioc,
@@ -7304,10 +7330,13 @@
 	ioc->rdpq_array_enable_assigned = 0;
 	ioc->use_32bit_dma = false;
 	ioc->dma_mask = 64;
-	if (ioc->is_aero_ioc)
+	if (ioc->is_aero_ioc) {
 		ioc->base_readl = &_base_readl_aero;
-	else
+		ioc->base_readl_ext_retry = &_base_readl_ext_retry;
+	} else {
 		ioc->base_readl = &_base_readl;
+		ioc->base_readl_ext_retry = &_base_readl;
+	}
 	r = mpt3sas_base_map_resources(ioc);
 	if (r)
 		goto out_free_resources;
diff --git a/kernel/drivers/scsi/mpt3sas/mpt3sas_base.h b/kernel/drivers/scsi/mpt3sas/mpt3sas_base.h
index 823bbe6..dc0e130 100644
--- a/kernel/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/kernel/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1469,6 +1469,7 @@
 	u8		diag_trigger_active;
 	u8		atomic_desc_capable;
 	BASE_READ_REG	base_readl;
+	BASE_READ_REG	base_readl_ext_retry;
 	struct SL_WH_MASTER_TRIGGER_T diag_trigger_master;
 	struct SL_WH_EVENT_TRIGGERS_T diag_trigger_event;
 	struct SL_WH_SCSI_TRIGGERS_T diag_trigger_scsi;
diff --git a/kernel/drivers/scsi/mpt3sas/mpt3sas_transport.c b/kernel/drivers/scsi/mpt3sas/mpt3sas_transport.c
index 6ec5b7f..326265f 100644
--- a/kernel/drivers/scsi/mpt3sas/mpt3sas_transport.c
+++ b/kernel/drivers/scsi/mpt3sas/mpt3sas_transport.c
@@ -670,7 +670,7 @@
 		goto out_fail;
 	}
 	port = sas_port_alloc_num(sas_node->parent_dev);
-	if ((sas_port_add(port))) {
+	if (!port || (sas_port_add(port))) {
 		ioc_err(ioc, "failure at %s:%d/%s()!\n",
 			__FILE__, __LINE__, __func__);
 		goto out_fail;
@@ -695,6 +695,12 @@
 		rphy = sas_expander_alloc(port,
 		    mpt3sas_port->remote_identify.device_type);
 
+	if (!rphy) {
+		ioc_err(ioc, "failure at %s:%d/%s()!\n",
+			__FILE__, __LINE__, __func__);
+		goto out_delete_port;
+	}
+
 	rphy->identify = mpt3sas_port->remote_identify;
 
 	if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
@@ -712,6 +718,9 @@
 	if ((sas_rphy_add(rphy))) {
 		ioc_err(ioc, "failure at %s:%d/%s()!\n",
 			__FILE__, __LINE__, __func__);
+		sas_rphy_free(rphy);
+		rphy = NULL;
+		goto out_delete_port;
 	}
 
 	if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
@@ -738,7 +747,10 @@
 		    rphy_to_expander_device(rphy));
 	return mpt3sas_port;
 
- out_fail:
+out_delete_port:
+	sas_port_delete(port);
+
+out_fail:
 	list_for_each_entry_safe(mpt3sas_phy, next, &mpt3sas_port->phy_list,
 	    port_siblings)
 		list_del(&mpt3sas_phy->port_siblings);
diff --git a/kernel/drivers/scsi/mvsas/mv_sas.c b/kernel/drivers/scsi/mvsas/mv_sas.c
index 484e014..a2a1396 100644
--- a/kernel/drivers/scsi/mvsas/mv_sas.c
+++ b/kernel/drivers/scsi/mvsas/mv_sas.c
@@ -1314,7 +1314,7 @@
 		}
 
 		if (task->task_status.resp == SAS_TASK_COMPLETE &&
-		    task->task_status.stat == SAM_STAT_GOOD) {
+		    task->task_status.stat == SAS_SAM_STAT_GOOD) {
 			res = TMF_RESP_FUNC_COMPLETE;
 			break;
 		}
@@ -1764,7 +1764,7 @@
 	case SAS_PROTOCOL_SSP:
 		/* hw says status == 0, datapres == 0 */
 		if (rx_desc & RXQ_GOOD) {
-			tstat->stat = SAM_STAT_GOOD;
+			tstat->stat = SAS_SAM_STAT_GOOD;
 			tstat->resp = SAS_TASK_COMPLETE;
 		}
 		/* response frame present */
@@ -1773,12 +1773,12 @@
 						sizeof(struct mvs_err_info);
 			sas_ssp_task_response(mvi->dev, task, iu);
 		} else
-			tstat->stat = SAM_STAT_CHECK_CONDITION;
+			tstat->stat = SAS_SAM_STAT_CHECK_CONDITION;
 		break;
 
 	case SAS_PROTOCOL_SMP: {
 			struct scatterlist *sg_resp = &task->smp_task.smp_resp;
-			tstat->stat = SAM_STAT_GOOD;
+			tstat->stat = SAS_SAM_STAT_GOOD;
 			to = kmap_atomic(sg_page(sg_resp));
 			memcpy(to + sg_resp->offset,
 				slot->response + sizeof(struct mvs_err_info),
@@ -1795,7 +1795,7 @@
 		}
 
 	default:
-		tstat->stat = SAM_STAT_CHECK_CONDITION;
+		tstat->stat = SAS_SAM_STAT_CHECK_CONDITION;
 		break;
 	}
 	if (!slot->port->port_attached) {
diff --git a/kernel/drivers/scsi/pm8001/pm8001_hwi.c b/kernel/drivers/scsi/pm8001/pm8001_hwi.c
index da9fbe6..2b20c6a 100644
--- a/kernel/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/kernel/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1881,7 +1881,7 @@
 			   param);
 		if (param == 0) {
 			ts->resp = SAS_TASK_COMPLETE;
-			ts->stat = SAM_STAT_GOOD;
+			ts->stat = SAS_SAM_STAT_GOOD;
 		} else {
 			ts->resp = SAS_TASK_COMPLETE;
 			ts->stat = SAS_PROTO_RESPONSE;
@@ -2341,7 +2341,7 @@
 		pm8001_dbg(pm8001_ha, IO, "IO_SUCCESS\n");
 		if (param == 0) {
 			ts->resp = SAS_TASK_COMPLETE;
-			ts->stat = SAM_STAT_GOOD;
+			ts->stat = SAS_SAM_STAT_GOOD;
 			/* check if response is for SEND READ LOG */
 			if (pm8001_dev &&
 				(pm8001_dev->id & NCQ_READ_LOG_FLAG)) {
@@ -2864,7 +2864,7 @@
 	case IO_SUCCESS:
 		pm8001_dbg(pm8001_ha, IO, "IO_SUCCESS\n");
 		ts->resp = SAS_TASK_COMPLETE;
-		ts->stat = SAM_STAT_GOOD;
+		ts->stat = SAS_SAM_STAT_GOOD;
 		if (pm8001_dev)
 			atomic_dec(&pm8001_dev->running_req);
 		break;
@@ -2891,17 +2891,17 @@
 	case IO_ERROR_HW_TIMEOUT:
 		pm8001_dbg(pm8001_ha, IO, "IO_ERROR_HW_TIMEOUT\n");
 		ts->resp = SAS_TASK_COMPLETE;
-		ts->stat = SAM_STAT_BUSY;
+		ts->stat = SAS_SAM_STAT_BUSY;
 		break;
 	case IO_XFER_ERROR_BREAK:
 		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n");
 		ts->resp = SAS_TASK_COMPLETE;
-		ts->stat = SAM_STAT_BUSY;
+		ts->stat = SAS_SAM_STAT_BUSY;
 		break;
 	case IO_XFER_ERROR_PHY_NOT_READY:
 		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n");
 		ts->resp = SAS_TASK_COMPLETE;
-		ts->stat = SAM_STAT_BUSY;
+		ts->stat = SAS_SAM_STAT_BUSY;
 		break;
 	case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:
 		pm8001_dbg(pm8001_ha, IO,
@@ -3656,7 +3656,7 @@
 	case IO_SUCCESS:
 		pm8001_dbg(pm8001_ha, EH, "IO_SUCCESS\n");
 		ts->resp = SAS_TASK_COMPLETE;
-		ts->stat = SAM_STAT_GOOD;
+		ts->stat = SAS_SAM_STAT_GOOD;
 		break;
 	case IO_NOT_VALID:
 		pm8001_dbg(pm8001_ha, EH, "IO_NOT_VALID\n");
@@ -4288,7 +4288,7 @@
 
 			spin_lock_irqsave(&task->task_state_lock, flags);
 			ts->resp = SAS_TASK_COMPLETE;
-			ts->stat = SAM_STAT_GOOD;
+			ts->stat = SAS_SAM_STAT_GOOD;
 			task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
 			task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
 			task->task_state_flags |= SAS_TASK_STATE_DONE;
@@ -4344,7 +4344,7 @@
 	payload.sas_identify.dev_type = SAS_END_DEVICE;
 	payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL;
 	memcpy(payload.sas_identify.sas_addr,
-		pm8001_ha->sas_addr, SAS_ADDR_SIZE);
+		&pm8001_ha->phy[phy_id].dev_sas_addr, SAS_ADDR_SIZE);
 	payload.sas_identify.phy_id = phy_id;
 	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload,
 			sizeof(payload), 0);
diff --git a/kernel/drivers/scsi/pm8001/pm8001_init.c b/kernel/drivers/scsi/pm8001/pm8001_init.c
index 01eb2ad..f40db6f 100644
--- a/kernel/drivers/scsi/pm8001/pm8001_init.c
+++ b/kernel/drivers/scsi/pm8001/pm8001_init.c
@@ -255,7 +255,6 @@
 	return ret;
 }
 
-static u32 pm8001_setup_irq(struct pm8001_hba_info *pm8001_ha);
 static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha);
 
 /**
@@ -275,13 +274,6 @@
 	pm8001_dbg(pm8001_ha, INIT, "pm8001_alloc: PHY:%x\n",
 		   pm8001_ha->chip->n_phy);
 
-	/* Setup Interrupt */
-	rc = pm8001_setup_irq(pm8001_ha);
-	if (rc) {
-		pm8001_dbg(pm8001_ha, FAIL,
-			   "pm8001_setup_irq failed [ret: %d]\n", rc);
-		goto err_out;
-	}
 	/* Request Interrupt */
 	rc = pm8001_request_irq(pm8001_ha);
 	if (rc)
@@ -990,47 +982,38 @@
 }
 #endif
 
-static u32 pm8001_setup_irq(struct pm8001_hba_info *pm8001_ha)
-{
-	struct pci_dev *pdev;
-
-	pdev = pm8001_ha->pdev;
-
-#ifdef PM8001_USE_MSIX
-	if (pci_find_capability(pdev, PCI_CAP_ID_MSIX))
-		return pm8001_setup_msix(pm8001_ha);
-	pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n");
-#endif
-	return 0;
-}
-
 /**
  * pm8001_request_irq - register interrupt
  * @pm8001_ha: our ha struct.
  */
 static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha)
 {
-	struct pci_dev *pdev;
+	struct pci_dev *pdev = pm8001_ha->pdev;
+#ifdef PM8001_USE_MSIX
 	int rc;
 
-	pdev = pm8001_ha->pdev;
+	if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) {
+		rc = pm8001_setup_msix(pm8001_ha);
+		if (rc) {
+			pm8001_dbg(pm8001_ha, FAIL,
+				   "pm8001_setup_irq failed [ret: %d]\n", rc);
+			return rc;
+		}
 
-#ifdef PM8001_USE_MSIX
-	if (pdev->msix_cap && pci_msi_enabled())
-		return pm8001_request_msix(pm8001_ha);
-	else {
-		pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n");
-		goto intx;
+		if (pdev->msix_cap && pci_msi_enabled())
+			return pm8001_request_msix(pm8001_ha);
 	}
+
+	pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n");
 #endif
 
-intx:
 	/* initialize the INT-X interrupt */
 	pm8001_ha->irq_vector[0].irq_id = 0;
 	pm8001_ha->irq_vector[0].drv_inst = pm8001_ha;
-	rc = request_irq(pdev->irq, pm8001_interrupt_handler_intx, IRQF_SHARED,
-		pm8001_ha->name, SHOST_TO_SAS_HA(pm8001_ha->shost));
-	return rc;
+
+	return request_irq(pdev->irq, pm8001_interrupt_handler_intx,
+			   IRQF_SHARED, pm8001_ha->name,
+			   SHOST_TO_SAS_HA(pm8001_ha->shost));
 }
 
 /**
diff --git a/kernel/drivers/scsi/pm8001/pm8001_sas.c b/kernel/drivers/scsi/pm8001/pm8001_sas.c
index ba58525..a16ed06 100644
--- a/kernel/drivers/scsi/pm8001/pm8001_sas.c
+++ b/kernel/drivers/scsi/pm8001/pm8001_sas.c
@@ -764,7 +764,7 @@
 		}
 
 		if (task->task_status.resp == SAS_TASK_COMPLETE &&
-			task->task_status.stat == SAM_STAT_GOOD) {
+			task->task_status.stat == SAS_SAM_STAT_GOOD) {
 			res = TMF_RESP_FUNC_COMPLETE;
 			break;
 		}
@@ -846,7 +846,7 @@
 		}
 
 		if (task->task_status.resp == SAS_TASK_COMPLETE &&
-			task->task_status.stat == SAM_STAT_GOOD) {
+			task->task_status.stat == SAS_SAM_STAT_GOOD) {
 			res = TMF_RESP_FUNC_COMPLETE;
 			break;
 
diff --git a/kernel/drivers/scsi/pm8001/pm80xx_hwi.c b/kernel/drivers/scsi/pm8001/pm80xx_hwi.c
index 0305c89..8905172 100644
--- a/kernel/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/kernel/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -1916,7 +1916,7 @@
 			   param);
 		if (param == 0) {
 			ts->resp = SAS_TASK_COMPLETE;
-			ts->stat = SAM_STAT_GOOD;
+			ts->stat = SAS_SAM_STAT_GOOD;
 		} else {
 			ts->resp = SAS_TASK_COMPLETE;
 			ts->stat = SAS_PROTO_RESPONSE;
@@ -2450,7 +2450,7 @@
 		pm8001_dbg(pm8001_ha, IO, "IO_SUCCESS\n");
 		if (param == 0) {
 			ts->resp = SAS_TASK_COMPLETE;
-			ts->stat = SAM_STAT_GOOD;
+			ts->stat = SAS_SAM_STAT_GOOD;
 			/* check if response is for SEND READ LOG */
 			if (pm8001_dev &&
 				(pm8001_dev->id & NCQ_READ_LOG_FLAG)) {
@@ -3004,7 +3004,7 @@
 	case IO_SUCCESS:
 		pm8001_dbg(pm8001_ha, IO, "IO_SUCCESS\n");
 		ts->resp = SAS_TASK_COMPLETE;
-		ts->stat = SAM_STAT_GOOD;
+		ts->stat = SAS_SAM_STAT_GOOD;
 		if (pm8001_dev)
 			atomic_dec(&pm8001_dev->running_req);
 		if (pm8001_ha->smp_exp_mode == SMP_DIRECT) {
@@ -3046,17 +3046,17 @@
 	case IO_ERROR_HW_TIMEOUT:
 		pm8001_dbg(pm8001_ha, IO, "IO_ERROR_HW_TIMEOUT\n");
 		ts->resp = SAS_TASK_COMPLETE;
-		ts->stat = SAM_STAT_BUSY;
+		ts->stat = SAS_SAM_STAT_BUSY;
 		break;
 	case IO_XFER_ERROR_BREAK:
 		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_BREAK\n");
 		ts->resp = SAS_TASK_COMPLETE;
-		ts->stat = SAM_STAT_BUSY;
+		ts->stat = SAS_SAM_STAT_BUSY;
 		break;
 	case IO_XFER_ERROR_PHY_NOT_READY:
 		pm8001_dbg(pm8001_ha, IO, "IO_XFER_ERROR_PHY_NOT_READY\n");
 		ts->resp = SAS_TASK_COMPLETE;
-		ts->stat = SAM_STAT_BUSY;
+		ts->stat = SAS_SAM_STAT_BUSY;
 		break;
 	case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:
 		pm8001_dbg(pm8001_ha, IO,
@@ -3722,10 +3722,12 @@
 			(struct set_ctrl_cfg_resp *)(piomb + 4);
 	u32 status = le32_to_cpu(pPayload->status);
 	u32 err_qlfr_pgcd = le32_to_cpu(pPayload->err_qlfr_pgcd);
+	u32 tag = le32_to_cpu(pPayload->tag);
 
 	pm8001_dbg(pm8001_ha, MSG,
 		   "SET CONTROLLER RESP: status 0x%x qlfr_pgcd 0x%x\n",
 		   status, err_qlfr_pgcd);
+	pm8001_tag_free(pm8001_ha, tag);
 
 	return 0;
 }
@@ -4679,7 +4681,7 @@
 
 			spin_lock_irqsave(&task->task_state_lock, flags);
 			ts->resp = SAS_TASK_COMPLETE;
-			ts->stat = SAM_STAT_GOOD;
+			ts->stat = SAS_SAM_STAT_GOOD;
 			task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
 			task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
 			task->task_state_flags |= SAS_TASK_STATE_DONE;
@@ -4741,7 +4743,7 @@
 	payload.sas_identify.dev_type = SAS_END_DEVICE;
 	payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL;
 	memcpy(payload.sas_identify.sas_addr,
-	  &pm8001_ha->sas_addr, SAS_ADDR_SIZE);
+		&pm8001_ha->phy[phy_id].dev_sas_addr, SAS_ADDR_SIZE);
 	payload.sas_identify.phy_id = phy_id;
 	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload,
 			sizeof(payload), 0);
diff --git a/kernel/drivers/scsi/qedf/qedf_dbg.h b/kernel/drivers/scsi/qedf/qedf_dbg.h
index 2386bfb..4a536c8 100644
--- a/kernel/drivers/scsi/qedf/qedf_dbg.h
+++ b/kernel/drivers/scsi/qedf/qedf_dbg.h
@@ -60,6 +60,8 @@
 #define QEDF_LOG_NOTICE	0x40000000	/* Notice logs */
 #define QEDF_LOG_WARN		0x80000000	/* Warning logs */
 
+#define QEDF_DEBUGFS_LOG_LEN (2 * PAGE_SIZE)
+
 /* Debug context structure */
 struct qedf_dbg_ctx {
 	unsigned int host_no;
diff --git a/kernel/drivers/scsi/qedf/qedf_debugfs.c b/kernel/drivers/scsi/qedf/qedf_debugfs.c
index a3ed681..451fd23 100644
--- a/kernel/drivers/scsi/qedf/qedf_debugfs.c
+++ b/kernel/drivers/scsi/qedf/qedf_debugfs.c
@@ -8,6 +8,7 @@
 #include <linux/uaccess.h>
 #include <linux/debugfs.h>
 #include <linux/module.h>
+#include <linux/vmalloc.h>
 
 #include "qedf.h"
 #include "qedf_dbg.h"
@@ -98,7 +99,9 @@
 qedf_dbg_fp_int_cmd_read(struct file *filp, char __user *buffer, size_t count,
 			 loff_t *ppos)
 {
+	ssize_t ret;
 	size_t cnt = 0;
+	char *cbuf;
 	int id;
 	struct qedf_fastpath *fp = NULL;
 	struct qedf_dbg_ctx *qedf_dbg =
@@ -108,19 +111,25 @@
 
 	QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "entered\n");
 
-	cnt = sprintf(buffer, "\nFastpath I/O completions\n\n");
+	cbuf = vmalloc(QEDF_DEBUGFS_LOG_LEN);
+	if (!cbuf)
+		return 0;
+
+	cnt += scnprintf(cbuf + cnt, QEDF_DEBUGFS_LOG_LEN - cnt, "\nFastpath I/O completions\n\n");
 
 	for (id = 0; id < qedf->num_queues; id++) {
 		fp = &(qedf->fp_array[id]);
 		if (fp->sb_id == QEDF_SB_ID_NULL)
 			continue;
-		cnt += sprintf((buffer + cnt), "#%d: %lu\n", id,
-			       fp->completions);
+		cnt += scnprintf(cbuf + cnt, QEDF_DEBUGFS_LOG_LEN - cnt,
+				 "#%d: %lu\n", id, fp->completions);
 	}
 
-	cnt = min_t(int, count, cnt - *ppos);
-	*ppos += cnt;
-	return cnt;
+	ret = simple_read_from_buffer(buffer, count, ppos, cbuf, cnt);
+
+	vfree(cbuf);
+
+	return ret;
 }
 
 static ssize_t
@@ -138,15 +147,14 @@
 			loff_t *ppos)
 {
 	int cnt;
+	char cbuf[32];
 	struct qedf_dbg_ctx *qedf_dbg =
 				(struct qedf_dbg_ctx *)filp->private_data;
 
 	QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "debug mask=0x%x\n", qedf_debug);
-	cnt = sprintf(buffer, "debug mask = 0x%x\n", qedf_debug);
+	cnt = scnprintf(cbuf, sizeof(cbuf), "debug mask = 0x%x\n", qedf_debug);
 
-	cnt = min_t(int, count, cnt - *ppos);
-	*ppos += cnt;
-	return cnt;
+	return simple_read_from_buffer(buffer, count, ppos, cbuf, cnt);
 }
 
 static ssize_t
@@ -185,18 +193,17 @@
 				   size_t count, loff_t *ppos)
 {
 	int cnt;
+	char cbuf[7];
 	struct qedf_dbg_ctx *qedf_dbg =
 				(struct qedf_dbg_ctx *)filp->private_data;
 	struct qedf_ctx *qedf = container_of(qedf_dbg,
 	    struct qedf_ctx, dbg_ctx);
 
 	QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "entered\n");
-	cnt = sprintf(buffer, "%s\n",
+	cnt = scnprintf(cbuf, sizeof(cbuf), "%s\n",
 	    qedf->stop_io_on_error ? "true" : "false");
 
-	cnt = min_t(int, count, cnt - *ppos);
-	*ppos += cnt;
-	return cnt;
+	return simple_read_from_buffer(buffer, count, ppos, cbuf, cnt);
 }
 
 static ssize_t
diff --git a/kernel/drivers/scsi/qedf/qedf_io.c b/kernel/drivers/scsi/qedf/qedf_io.c
index 472374d..1f8e812 100644
--- a/kernel/drivers/scsi/qedf/qedf_io.c
+++ b/kernel/drivers/scsi/qedf/qedf_io.c
@@ -1924,6 +1924,7 @@
 		goto drop_rdata_kref;
 	}
 
+	spin_lock_irqsave(&fcport->rport_lock, flags);
 	if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) ||
 	    test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) ||
 	    test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) {
@@ -1931,8 +1932,13 @@
 			 "io_req xid=0x%x sc_cmd=%p already in cleanup or abort processing or already completed.\n",
 			 io_req->xid, io_req->sc_cmd);
 		rc = 1;
+		spin_unlock_irqrestore(&fcport->rport_lock, flags);
 		goto drop_rdata_kref;
 	}
+
+	/* Set the command type to abort */
+	io_req->cmd_type = QEDF_ABTS;
+	spin_unlock_irqrestore(&fcport->rport_lock, flags);
 
 	kref_get(&io_req->refcount);
 
@@ -1940,8 +1946,6 @@
 	qedf->control_requests++;
 	qedf->packet_aborts++;
 
-	/* Set the command type to abort */
-	io_req->cmd_type = QEDF_ABTS;
 	io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts;
 
 	set_bit(QEDF_CMD_IN_ABORT, &io_req->flags);
@@ -2230,7 +2234,9 @@
 		  refcount, fcport, fcport->rdata->ids.port_id);
 
 	/* Cleanup cmds re-use the same TID as the original I/O */
+	spin_lock_irqsave(&fcport->rport_lock, flags);
 	io_req->cmd_type = QEDF_CLEANUP;
+	spin_unlock_irqrestore(&fcport->rport_lock, flags);
 	io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts;
 
 	init_completion(&io_req->cleanup_done);
diff --git a/kernel/drivers/scsi/qedf/qedf_main.c b/kernel/drivers/scsi/qedf/qedf_main.c
index f48ef47..6923862 100644
--- a/kernel/drivers/scsi/qedf/qedf_main.c
+++ b/kernel/drivers/scsi/qedf/qedf_main.c
@@ -31,6 +31,7 @@
 static void qedf_shutdown(struct pci_dev *pdev);
 static void qedf_schedule_recovery_handler(void *dev);
 static void qedf_recovery_handler(struct work_struct *work);
+static int qedf_suspend(struct pci_dev *pdev, pm_message_t state);
 
 /*
  * Driver module parameters.
@@ -2802,6 +2803,8 @@
 	struct qedf_ioreq *io_req;
 	struct qedf_rport *fcport;
 	u32 comp_type;
+	u8 io_comp_type;
+	unsigned long flags;
 
 	comp_type = (cqe->cqe_data >> FCOE_CQE_CQE_TYPE_SHIFT) &
 	    FCOE_CQE_CQE_TYPE_MASK;
@@ -2835,11 +2838,14 @@
 		return;
 	}
 
+	spin_lock_irqsave(&fcport->rport_lock, flags);
+	io_comp_type = io_req->cmd_type;
+	spin_unlock_irqrestore(&fcport->rport_lock, flags);
 
 	switch (comp_type) {
 	case FCOE_GOOD_COMPLETION_CQE_TYPE:
 		atomic_inc(&fcport->free_sqes);
-		switch (io_req->cmd_type) {
+		switch (io_comp_type) {
 		case QEDF_SCSI_CMD:
 			qedf_scsi_completion(qedf, cqe, io_req);
 			break;
@@ -3042,9 +3048,8 @@
 	 * addresses of our queues
 	 */
 	if (!qedf->p_cpuq) {
-		status = -EINVAL;
 		QEDF_ERR(&qedf->dbg_ctx, "p_cpuq is NULL.\n");
-		goto mem_alloc_failure;
+		return -EINVAL;
 	}
 
 	qedf->global_queues = kzalloc((sizeof(struct global_queue *)
@@ -3273,6 +3278,7 @@
 	.probe = qedf_probe,
 	.remove = qedf_remove,
 	.shutdown = qedf_shutdown,
+	.suspend = qedf_suspend,
 };
 
 static int __qedf_probe(struct pci_dev *pdev, int mode)
@@ -3987,6 +3993,22 @@
 	__qedf_remove(pdev, QEDF_MODE_NORMAL);
 }
 
+static int qedf_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct qedf_ctx *qedf;
+
+	if (!pdev) {
+		QEDF_ERR(NULL, "pdev is NULL.\n");
+		return -ENODEV;
+	}
+
+	qedf = pci_get_drvdata(pdev);
+
+	QEDF_ERR(&qedf->dbg_ctx, "%s: Device does not support suspend operation\n", __func__);
+
+	return -EPERM;
+}
+
 /*
  * Recovery handler code
  */
diff --git a/kernel/drivers/scsi/qedi/qedi_main.c b/kernel/drivers/scsi/qedi/qedi_main.c
index 299d036..96e4707 100644
--- a/kernel/drivers/scsi/qedi/qedi_main.c
+++ b/kernel/drivers/scsi/qedi/qedi_main.c
@@ -69,6 +69,7 @@
 static void qedi_recovery_handler(struct work_struct *work);
 static void qedi_schedule_hw_err_handler(void *dev,
 					 enum qed_hw_err_type err_type);
+static int qedi_suspend(struct pci_dev *pdev, pm_message_t state);
 
 static int qedi_iscsi_event_cb(void *context, u8 fw_event_code, void *fw_handle)
 {
@@ -1980,8 +1981,9 @@
 	struct qedi_percpu_s *p = this_cpu_ptr(&qedi_percpu);
 	struct qedi_work *work, *tmp;
 	struct task_struct *thread;
+	unsigned long flags;
 
-	spin_lock_bh(&p->p_work_lock);
+	spin_lock_irqsave(&p->p_work_lock, flags);
 	thread = p->iothread;
 	p->iothread = NULL;
 
@@ -1992,7 +1994,7 @@
 			kfree(work);
 	}
 
-	spin_unlock_bh(&p->p_work_lock);
+	spin_unlock_irqrestore(&p->p_work_lock, flags);
 	if (thread)
 		kthread_stop(thread);
 	return 0;
@@ -2456,6 +2458,9 @@
 		qedi_ops->ll2->stop(qedi->cdev);
 	}
 
+	cancel_delayed_work_sync(&qedi->recovery_work);
+	cancel_delayed_work_sync(&qedi->board_disable_work);
+
 	qedi_free_iscsi_pf_param(qedi);
 
 	rval = qedi_ops->common->update_drv_state(qedi->cdev, false);
@@ -2512,6 +2517,22 @@
 	if (test_and_set_bit(QEDI_IN_SHUTDOWN, &qedi->flags))
 		return;
 	__qedi_remove(pdev, QEDI_MODE_SHUTDOWN);
+}
+
+static int qedi_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct qedi_ctx *qedi;
+
+	if (!pdev) {
+		QEDI_ERR(NULL, "pdev is NULL.\n");
+		return -ENODEV;
+	}
+
+	qedi = pci_get_drvdata(pdev);
+
+	QEDI_ERR(&qedi->dbg_ctx, "%s: Device does not support suspend operation\n", __func__);
+
+	return -EPERM;
 }
 
 static int __qedi_probe(struct pci_dev *pdev, int mode)
@@ -2872,6 +2893,7 @@
 	.remove = qedi_remove,
 	.shutdown = qedi_shutdown,
 	.err_handler = &qedi_err_handler,
+	.suspend = qedi_suspend,
 };
 
 static int __init qedi_init(void)
diff --git a/kernel/drivers/scsi/qla2xxx/qla_attr.c b/kernel/drivers/scsi/qla2xxx/qla_attr.c
index 61b9dc5..f919da0 100644
--- a/kernel/drivers/scsi/qla2xxx/qla_attr.c
+++ b/kernel/drivers/scsi/qla2xxx/qla_attr.c
@@ -2698,6 +2698,7 @@
 qla2x00_terminate_rport_io(struct fc_rport *rport)
 {
 	fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
+	scsi_qla_host_t *vha;
 
 	if (!fcport)
 		return;
@@ -2707,9 +2708,12 @@
 
 	if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags))
 		return;
+	vha = fcport->vha;
 
 	if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) {
 		qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
+		qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24,
+			0, WAIT_TARGET);
 		return;
 	}
 	/*
@@ -2723,6 +2727,15 @@
 			    fcport->d_id.b.area, fcport->d_id.b.al_pa);
 		else
 			qla2x00_port_logout(fcport->vha, fcport);
+	}
+
+	/* check for any straggling io left behind */
+	if (qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24, 0, WAIT_TARGET)) {
+		ql_log(ql_log_warn, vha, 0x300b,
+		       "IO not return.  Resetting. \n");
+		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+		qla2xxx_wake_dpc(vha);
+		qla2x00_wait_for_chip_reset(vha);
 	}
 }
 
@@ -3015,8 +3028,6 @@
 			vha->flags.difdix_supported = 1;
 			ql_dbg(ql_dbg_user, vha, 0x7082,
 			    "Registered for DIF/DIX type 1 and 3 protection.\n");
-			if (ql2xenabledif == 1)
-				prot = SHOST_DIX_TYPE0_PROTECTION;
 			scsi_host_set_prot(vha->host,
 			    prot | SHOST_DIF_TYPE1_PROTECTION
 			    | SHOST_DIF_TYPE2_PROTECTION
diff --git a/kernel/drivers/scsi/qla2xxx/qla_bsg.c b/kernel/drivers/scsi/qla2xxx/qla_bsg.c
index 1fd292a..804cac4 100644
--- a/kernel/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/kernel/drivers/scsi/qla2xxx/qla_bsg.c
@@ -268,6 +268,10 @@
 
 	if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
 		rport = fc_bsg_to_rport(bsg_job);
+		if (!rport) {
+			rval = -ENOMEM;
+			goto done;
+		}
 		fcport = *(fc_port_t **) rport->dd_data;
 		host = rport_to_shost(rport);
 		vha = shost_priv(host);
@@ -2541,6 +2545,8 @@
 
 	if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
 		rport = fc_bsg_to_rport(bsg_job);
+		if (!rport)
+			return ret;
 		host = rport_to_shost(rport);
 		vha = shost_priv(host);
 	} else {
diff --git a/kernel/drivers/scsi/qla2xxx/qla_dbg.c b/kernel/drivers/scsi/qla2xxx/qla_dbg.c
index 00b4d03..8e9ffbe 100644
--- a/kernel/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/kernel/drivers/scsi/qla2xxx/qla_dbg.c
@@ -18,7 +18,7 @@
  * | Queue Command and IO tracing |       0x3074       | 0x300b         |
  * |                              |                    | 0x3027-0x3028  |
  * |                              |                    | 0x303d-0x3041  |
- * |                              |                    | 0x302d,0x3033  |
+ * |                              |                    | 0x302e,0x3033  |
  * |                              |                    | 0x3036,0x3038  |
  * |                              |                    | 0x303a		|
  * | DPC Thread                   |       0x4023       | 0x4002,0x4013  |
@@ -112,8 +112,13 @@
 	uint32_t stat;
 	ulong i, j, timer = 6000000;
 	int rval = QLA_FUNCTION_FAILED;
+	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
 
 	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
+
+	if (qla_pci_disconnected(vha, reg))
+		return rval;
+
 	for (i = 0; i < ram_dwords; i += dwords, addr += dwords) {
 		if (i + dwords > ram_dwords)
 			dwords = ram_dwords - i;
@@ -136,6 +141,9 @@
 		ha->flags.mbox_int = 0;
 		while (timer--) {
 			udelay(5);
+
+			if (qla_pci_disconnected(vha, reg))
+				return rval;
 
 			stat = rd_reg_dword(&reg->host_status);
 			/* Check for pending interrupts. */
@@ -191,8 +199,12 @@
 	uint32_t dwords = qla2x00_gid_list_size(ha) / 4;
 	uint32_t stat;
 	ulong i, j, timer = 6000000;
+	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
 
 	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
+
+	if (qla_pci_disconnected(vha, reg))
+		return rval;
 
 	for (i = 0; i < ram_dwords; i += dwords, addr += dwords) {
 		if (i + dwords > ram_dwords)
@@ -215,8 +227,10 @@
 		ha->flags.mbox_int = 0;
 		while (timer--) {
 			udelay(5);
-			stat = rd_reg_dword(&reg->host_status);
+			if (qla_pci_disconnected(vha, reg))
+				return rval;
 
+			stat = rd_reg_dword(&reg->host_status);
 			/* Check for pending interrupts. */
 			if (!(stat & HSRX_RISC_INT))
 				continue;
diff --git a/kernel/drivers/scsi/qla2xxx/qla_def.h b/kernel/drivers/scsi/qla2xxx/qla_def.h
index 6afce45..6645b69 100644
--- a/kernel/drivers/scsi/qla2xxx/qla_def.h
+++ b/kernel/drivers/scsi/qla2xxx/qla_def.h
@@ -396,6 +396,7 @@
 	} b;
 } port_id_t;
 #define INVALID_PORT_ID	0xFFFFFF
+#define ISP_REG16_DISCONNECT 0xFFFF
 
 static inline le_id_t be_id_to_le(be_id_t id)
 {
@@ -639,7 +640,6 @@
 	struct iocb_resource iores;
 	struct kref cmd_kref;	/* need to migrate ref_count over to this */
 	void *priv;
-	wait_queue_head_t nvme_ls_waitq;
 	struct fc_port *fcport;
 	struct scsi_qla_host *vha;
 	unsigned int start_timer:1;
@@ -3849,6 +3849,13 @@
 	u32 num_mpi_reset;
 };
 
+/* refer to pcie_do_recovery reference */
+typedef enum {
+	QLA_PCI_RESUME,
+	QLA_PCI_ERR_DETECTED,
+	QLA_PCI_MMIO_ENABLED,
+	QLA_PCI_SLOT_RESET,
+} pci_error_state_t;
 /*
  * Qlogic host adapter specific data structure.
 */
@@ -4193,7 +4200,6 @@
 	uint8_t		aen_mbx_count;
 	atomic_t	num_pend_mbx_stage1;
 	atomic_t	num_pend_mbx_stage2;
-	atomic_t	num_pend_mbx_stage3;
 	uint16_t	frame_payload_size;
 
 	uint32_t	login_retry_count;
@@ -4587,6 +4593,7 @@
 #define DEFAULT_ZIO_THRESHOLD 5
 
 	struct qla_hw_data_stat stat;
+	pci_error_state_t pci_error_state;
 };
 
 struct active_regions {
@@ -4707,7 +4714,7 @@
 #define FX00_CRITEMP_RECOVERY	25
 #define FX00_HOST_INFO_RESEND	26
 #define QPAIR_ONLINE_CHECK_NEEDED	27
-#define SET_NVME_ZIO_THRESHOLD_NEEDED	28
+#define DO_EEH_RECOVERY		28
 #define DETECT_SFP_CHANGE	29
 #define N2N_LOGIN_NEEDED	30
 #define IOCB_WORK_ACTIVE	31
diff --git a/kernel/drivers/scsi/qla2xxx/qla_dfs.c b/kernel/drivers/scsi/qla2xxx/qla_dfs.c
index d5ebcf7..7d778bf 100644
--- a/kernel/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/kernel/drivers/scsi/qla2xxx/qla_dfs.c
@@ -116,7 +116,7 @@
 
 	sprintf(wwn, "pn-%016llx", wwn_to_u64(fp->port_name));
 	fp->dfs_rport_dir = debugfs_create_dir(wwn, vha->dfs_rport_root);
-	if (!fp->dfs_rport_dir)
+	if (IS_ERR(fp->dfs_rport_dir))
 		return;
 	if (NVME_TARGET(vha->hw, fp))
 		debugfs_create_file("dev_loss_tmo", 0600, fp->dfs_rport_dir,
@@ -571,14 +571,14 @@
 	if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) {
 		ha->tgt.dfs_naqp = debugfs_create_file("naqp",
 		    0400, ha->dfs_dir, vha, &dfs_naqp_ops);
-		if (!ha->tgt.dfs_naqp) {
+		if (IS_ERR(ha->tgt.dfs_naqp)) {
 			ql_log(ql_log_warn, vha, 0xd011,
 			       "Unable to create debugFS naqp node.\n");
 			goto out;
 		}
 	}
 	vha->dfs_rport_root = debugfs_create_dir("rports", ha->dfs_dir);
-	if (!vha->dfs_rport_root) {
+	if (IS_ERR(vha->dfs_rport_root)) {
 		ql_log(ql_log_warn, vha, 0xd012,
 		       "Unable to create debugFS rports node.\n");
 		goto out;
diff --git a/kernel/drivers/scsi/qla2xxx/qla_gbl.h b/kernel/drivers/scsi/qla2xxx/qla_gbl.h
index 7e5ee31..8ef2de6 100644
--- a/kernel/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/kernel/drivers/scsi/qla2xxx/qla_gbl.h
@@ -222,6 +222,7 @@
 
 extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32);
 extern void qla2x00_disable_board_on_pci_error(struct work_struct *);
+extern void qla_eeh_work(struct work_struct *);
 extern void qla2x00_sp_compl(srb_t *sp, int);
 extern void qla2xxx_qpair_sp_free_dma(srb_t *sp);
 extern void qla2xxx_qpair_sp_compl(srb_t *sp, int);
@@ -233,6 +234,8 @@
 void qla2x00_wait_for_sess_deletion(scsi_qla_host_t *);
 void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
 			       struct purex_item *pkt);
+void qla_pci_set_eeh_busy(struct scsi_qla_host *);
+void qla_schedule_eeh_work(struct scsi_qla_host *);
 
 /*
  * Global Functions in qla_mid.c source file.
diff --git a/kernel/drivers/scsi/qla2xxx/qla_init.c b/kernel/drivers/scsi/qla2xxx/qla_init.c
index 422ff67..a8d2c06 100644
--- a/kernel/drivers/scsi/qla2xxx/qla_init.c
+++ b/kernel/drivers/scsi/qla2xxx/qla_init.c
@@ -483,6 +483,7 @@
 void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea)
 {
 	struct fc_port *fcport = ea->fcport;
+	unsigned long flags;
 
 	ql_dbg(ql_dbg_disc, vha, 0x20d2,
 	    "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n",
@@ -497,9 +498,15 @@
 		ql_dbg(ql_dbg_disc, vha, 0x2066,
 		    "%s %8phC: adisc fail: post delete\n",
 		    __func__, ea->fcport->port_name);
+
+		spin_lock_irqsave(&vha->work_lock, flags);
 		/* deleted = 0 & logout_on_delete = force fw cleanup */
-		fcport->deleted = 0;
+		if (fcport->deleted == QLA_SESS_DELETED)
+			fcport->deleted = 0;
+
 		fcport->logout_on_delete = 1;
+		spin_unlock_irqrestore(&vha->work_lock, flags);
+
 		qlt_schedule_sess_for_deletion(ea->fcport);
 		return;
 	}
@@ -1405,7 +1412,6 @@
 
 	spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
 	ea->fcport->login_gen++;
-	ea->fcport->deleted = 0;
 	ea->fcport->logout_on_delete = 1;
 
 	if (!ea->fcport->login_succ && !IS_SW_RESV_ADDR(ea->fcport->d_id)) {
@@ -4336,15 +4342,16 @@
 		memcpy(ha->port_name, ha->init_cb->port_name, WWN_SIZE);
 	}
 
+	QLA_FW_STARTED(ha);
 	rval = qla2x00_init_firmware(vha, ha->init_cb_size);
 next_check:
 	if (rval) {
+		QLA_FW_STOPPED(ha);
 		ql_log(ql_log_fatal, vha, 0x00d2,
 		    "Init Firmware **** FAILED ****.\n");
 	} else {
 		ql_dbg(ql_dbg_init, vha, 0x00d3,
 		    "Init Firmware -- success.\n");
-		QLA_FW_STARTED(ha);
 		vha->u_ql2xexchoffld = vha->u_ql2xiniexchg = 0;
 	}
 
@@ -5639,6 +5646,8 @@
 void
 qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
 {
+	unsigned long flags;
+
 	if (IS_SW_RESV_ADDR(fcport->d_id))
 		return;
 
@@ -5648,7 +5657,11 @@
 	qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT);
 	fcport->login_retry = vha->hw->login_retry_count;
 	fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
+
+	spin_lock_irqsave(&vha->work_lock, flags);
 	fcport->deleted = 0;
+	spin_unlock_irqrestore(&vha->work_lock, flags);
+
 	if (vha->hw->current_topology == ISP_CFG_NL)
 		fcport->logout_on_delete = 0;
 	else
@@ -6913,14 +6926,15 @@
 	}
 
 	/* purge MBox commands */
-	if (atomic_read(&ha->num_pend_mbx_stage3)) {
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags)) {
 		clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
 		complete(&ha->mbx_intr_comp);
 	}
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	i = 0;
-	while (atomic_read(&ha->num_pend_mbx_stage3) ||
-	    atomic_read(&ha->num_pend_mbx_stage2) ||
+	while (atomic_read(&ha->num_pend_mbx_stage2) ||
 	    atomic_read(&ha->num_pend_mbx_stage1)) {
 		msleep(20);
 		i++;
@@ -6969,22 +6983,18 @@
 	}
 	spin_unlock_irqrestore(&ha->vport_slock, flags);
 
-	if (!ha->flags.eeh_busy) {
-		/* Make sure for ISP 82XX IO DMA is complete */
-		if (IS_P3P_TYPE(ha)) {
-			qla82xx_chip_reset_cleanup(vha);
-			ql_log(ql_log_info, vha, 0x00b4,
-			    "Done chip reset cleanup.\n");
+	/* Make sure for ISP 82XX IO DMA is complete */
+	if (IS_P3P_TYPE(ha)) {
+		qla82xx_chip_reset_cleanup(vha);
+		ql_log(ql_log_info, vha, 0x00b4,
+		       "Done chip reset cleanup.\n");
 
-			/* Done waiting for pending commands.
-			 * Reset the online flag.
-			 */
-			vha->flags.online = 0;
-		}
-
-		/* Requeue all commands in outstanding command list. */
-		qla2x00_abort_all_cmds(vha, DID_RESET << 16);
+		/* Done waiting for pending commands. Reset online flag */
+		vha->flags.online = 0;
 	}
+
+	/* Requeue all commands in outstanding command list. */
+	qla2x00_abort_all_cmds(vha, DID_RESET << 16);
 	/* memory barrier */
 	wmb();
 }
@@ -7011,6 +7021,12 @@
 
 	if (vha->flags.online) {
 		qla2x00_abort_isp_cleanup(vha);
+
+		if (qla2x00_isp_reg_stat(ha)) {
+			ql_log(ql_log_info, vha, 0x803f,
+			       "ISP Abort - ISP reg disconnect, exiting.\n");
+			return status;
+		}
 
 		if (test_and_clear_bit(ISP_ABORT_TO_ROM, &vha->dpc_flags)) {
 			ha->flags.chip_reset_done = 1;
@@ -7052,8 +7068,18 @@
 
 		ha->isp_ops->get_flash_version(vha, req->ring);
 
+		if (qla2x00_isp_reg_stat(ha)) {
+			ql_log(ql_log_info, vha, 0x803f,
+			       "ISP Abort - ISP reg disconnect pre nvram config, exiting.\n");
+			return status;
+		}
 		ha->isp_ops->nvram_config(vha);
 
+		if (qla2x00_isp_reg_stat(ha)) {
+			ql_log(ql_log_info, vha, 0x803f,
+			       "ISP Abort - ISP reg disconnect post nvmram config, exiting.\n");
+			return status;
+		}
 		if (!qla2x00_restart_isp(vha)) {
 			clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
 
diff --git a/kernel/drivers/scsi/qla2xxx/qla_inline.h b/kernel/drivers/scsi/qla2xxx/qla_inline.h
index e80e41b..47ee5b9 100644
--- a/kernel/drivers/scsi/qla2xxx/qla_inline.h
+++ b/kernel/drivers/scsi/qla2xxx/qla_inline.h
@@ -109,11 +109,13 @@
 {
 	int old_val;
 	uint8_t shiftbits, mask;
+	uint8_t port_dstate_str_sz;
 
 	/* This will have to change when the max no. of states > 16 */
 	shiftbits = 4;
 	mask = (1 << shiftbits) - 1;
 
+	port_dstate_str_sz = sizeof(port_dstate_str) / sizeof(char *);
 	fcport->disc_state = state;
 	while (1) {
 		old_val = atomic_read(&fcport->shadow_disc_state);
@@ -121,7 +123,8 @@
 		    old_val, (old_val << shiftbits) | state)) {
 			ql_dbg(ql_dbg_disc, fcport->vha, 0x2134,
 			    "FCPort %8phC disc_state transition: %s to %s - portid=%06x.\n",
-			    fcport->port_name, port_dstate_str[old_val & mask],
+			    fcport->port_name, (old_val & mask) < port_dstate_str_sz ?
+				    port_dstate_str[old_val & mask] : "Unknown",
 			    port_dstate_str[state], fcport->d_id.b24);
 			return;
 		}
@@ -432,3 +435,49 @@
 	}
 	iores->res_type = RESOURCE_NONE;
 }
+
+#define ISP_REG_DISCONNECT 0xffffffffU
+/**************************************************************************
+ * qla2x00_isp_reg_stat
+ *
+ * Description:
+ *        Read the host status register of ISP before aborting the command.
+ *
+ * Input:
+ *       ha = pointer to host adapter structure.
+ *
+ *
+ * Returns:
+ *       Either true or false.
+ *
+ * Note: Return true if there is register disconnect.
+ **************************************************************************/
+static inline
+uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
+{
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+	struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82;
+
+	if (IS_P3P_TYPE(ha))
+		return ((rd_reg_dword(&reg82->host_int)) == ISP_REG_DISCONNECT);
+	else
+		return ((rd_reg_dword(&reg->host_status)) ==
+			ISP_REG_DISCONNECT);
+}
+
+static inline
+bool qla_pci_disconnected(struct scsi_qla_host *vha,
+			  struct device_reg_24xx __iomem *reg)
+{
+	uint32_t stat;
+	bool ret = false;
+
+	stat = rd_reg_dword(&reg->host_status);
+	if (stat == 0xffffffff) {
+		ql_log(ql_log_info, vha, 0x8041,
+		       "detected PCI disconnect.\n");
+		qla_schedule_eeh_work(vha);
+		ret = true;
+	}
+	return ret;
+}
diff --git a/kernel/drivers/scsi/qla2xxx/qla_iocb.c b/kernel/drivers/scsi/qla2xxx/qla_iocb.c
index e54cc2a..1752a62 100644
--- a/kernel/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/kernel/drivers/scsi/qla2xxx/qla_iocb.c
@@ -601,7 +601,8 @@
 	put_unaligned_le32(COMMAND_TYPE_6, &cmd_pkt->entry_type);
 
 	/* No data transfer */
-	if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
+	if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE ||
+	    tot_dsds == 0) {
 		cmd_pkt->byte_count = cpu_to_le32(0);
 		return 0;
 	}
@@ -1643,8 +1644,14 @@
 		goto queuing_error;
 
 	if (req->cnt < (req_cnt + 2)) {
-		cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
-		    rd_reg_dword_relaxed(req->req_q_out);
+		if (IS_SHADOW_REG_CAPABLE(ha)) {
+			cnt = *req->out_ptr;
+		} else {
+			cnt = rd_reg_dword_relaxed(req->req_q_out);
+			if (qla2x00_check_reg16_for_disconnect(vha, cnt))
+				goto queuing_error;
+		}
+
 		if (req->ring_index < cnt)
 			req->cnt = cnt - req->ring_index;
 		else
@@ -1835,8 +1842,13 @@
 		goto queuing_error;
 
 	if (req->cnt < (req_cnt + 2)) {
-		cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
-		    rd_reg_dword_relaxed(req->req_q_out);
+		if (IS_SHADOW_REG_CAPABLE(ha)) {
+			cnt = *req->out_ptr;
+		} else {
+			cnt = rd_reg_dword_relaxed(req->req_q_out);
+			if (qla2x00_check_reg16_for_disconnect(vha, cnt))
+				goto queuing_error;
+		}
 		if (req->ring_index < cnt)
 			req->cnt = cnt - req->ring_index;
 		else
@@ -1910,6 +1922,7 @@
 
 	qla_put_iocbs(sp->qpair, &sp->iores);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
 	return QLA_FUNCTION_FAILED;
 }
 
@@ -1977,8 +1990,14 @@
 		goto queuing_error;
 
 	if (req->cnt < (req_cnt + 2)) {
-		cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
-		    rd_reg_dword_relaxed(req->req_q_out);
+		if (IS_SHADOW_REG_CAPABLE(ha)) {
+			cnt = *req->out_ptr;
+		} else {
+			cnt = rd_reg_dword_relaxed(req->req_q_out);
+			if (qla2x00_check_reg16_for_disconnect(vha, cnt))
+				goto queuing_error;
+		}
+
 		if (req->ring_index < cnt)
 			req->cnt = cnt - req->ring_index;
 		else
@@ -2184,8 +2203,14 @@
 		goto queuing_error;
 
 	if (req->cnt < (req_cnt + 2)) {
-		cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
-		    rd_reg_dword_relaxed(req->req_q_out);
+		if (IS_SHADOW_REG_CAPABLE(ha)) {
+			cnt = *req->out_ptr;
+		} else {
+			cnt = rd_reg_dword_relaxed(req->req_q_out);
+			if (qla2x00_check_reg16_for_disconnect(vha, cnt))
+				goto queuing_error;
+		}
+
 		if (req->ring_index < cnt)
 			req->cnt = cnt - req->ring_index;
 		else
@@ -2262,6 +2287,7 @@
 
 	qla_put_iocbs(sp->qpair, &sp->iores);
 	spin_unlock_irqrestore(&qpair->qp_lock, flags);
+
 	return QLA_FUNCTION_FAILED;
 }
 
@@ -2305,6 +2331,11 @@
 		else
 			cnt = qla2x00_debounce_register(
 			    ISP_REQ_Q_OUT(ha, &reg->isp));
+
+		if (!qpair->use_shadow_reg && cnt == ISP_REG16_DISCONNECT) {
+			qla_schedule_eeh_work(vha);
+			return NULL;
+		}
 
 		if  (req->ring_index < cnt)
 			req->cnt = cnt - req->ring_index;
@@ -3710,10 +3741,13 @@
 	void *pkt;
 	unsigned long flags;
 
+	if (vha->hw->flags.eeh_busy)
+		return -EIO;
+
 	spin_lock_irqsave(qp->qp_lock_ptr, flags);
 	pkt = __qla2x00_alloc_iocbs(sp->qpair, sp);
 	if (!pkt) {
-		rval = EAGAIN;
+		rval = -EAGAIN;
 		ql_log(ql_log_warn, vha, 0x700c,
 		    "qla2x00_alloc_iocbs failed.\n");
 		goto done;
@@ -3927,8 +3961,14 @@
 
 	/* Check for room on request queue. */
 	if (req->cnt < req_cnt + 2) {
-		cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
-		    rd_reg_dword_relaxed(req->req_q_out);
+		if (IS_SHADOW_REG_CAPABLE(ha)) {
+			cnt = *req->out_ptr;
+		} else {
+			cnt = rd_reg_dword_relaxed(req->req_q_out);
+			if (qla2x00_check_reg16_for_disconnect(vha, cnt))
+				goto queuing_error;
+		}
+
 		if  (req->ring_index < cnt)
 			req->cnt = cnt - req->ring_index;
 		else
@@ -3967,5 +4007,6 @@
 	qla2x00_start_iocbs(vha, req);
 queuing_error:
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
 	return rval;
 }
diff --git a/kernel/drivers/scsi/qla2xxx/qla_isr.c b/kernel/drivers/scsi/qla2xxx/qla_isr.c
index 7ea73ad..fd0beb1 100644
--- a/kernel/drivers/scsi/qla2xxx/qla_isr.c
+++ b/kernel/drivers/scsi/qla2xxx/qla_isr.c
@@ -269,12 +269,7 @@
 		if (!test_and_set_bit(PFLG_DISCONNECTED, &vha->pci_flags) &&
 		    !test_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags) &&
 		    !test_bit(PFLG_DRIVER_PROBING, &vha->pci_flags)) {
-			/*
-			 * Schedule this (only once) on the default system
-			 * workqueue so that all the adapter workqueues and the
-			 * DPC thread can be shutdown cleanly.
-			 */
-			schedule_work(&vha->hw->board_disable);
+			qla_schedule_eeh_work(vha);
 		}
 		return true;
 	} else
@@ -982,8 +977,12 @@
 	unsigned long	flags;
 	fc_port_t	*fcport = NULL;
 
-	if (!vha->hw->flags.fw_started)
+	if (!vha->hw->flags.fw_started) {
+		ql_log(ql_log_warn, vha, 0x50ff,
+		    "Dropping AEN - %04x %04x %04x %04x.\n",
+		    mb[0], mb[1], mb[2], mb[3]);
 		return;
+	}
 
 	/* Setup to process RIO completion. */
 	handle_cnt = 0;
@@ -1639,8 +1638,6 @@
 	case MBA_TEMPERATURE_ALERT:
 		ql_dbg(ql_dbg_async, vha, 0x505e,
 		    "TEMPERATURE ALERT: %04x %04x %04x\n", mb[1], mb[2], mb[3]);
-		if (mb[1] == 0x12)
-			schedule_work(&ha->board_disable);
 		break;
 
 	case MBA_TRANS_INSERT:
@@ -3139,7 +3136,6 @@
 	case CS_PORT_BUSY:
 	case CS_INCOMPLETE:
 	case CS_PORT_UNAVAILABLE:
-	case CS_TIMEOUT:
 	case CS_RESET:
 
 		/*
diff --git a/kernel/drivers/scsi/qla2xxx/qla_mbx.c b/kernel/drivers/scsi/qla2xxx/qla_mbx.c
index 6ff720d..21ba710 100644
--- a/kernel/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/kernel/drivers/scsi/qla2xxx/qla_mbx.c
@@ -167,7 +167,8 @@
 	/* check if ISP abort is active and return cmd with timeout */
 	if ((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
 	    test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
-	    test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) &&
+	    test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) ||
+	    ha->flags.eeh_busy) &&
 	    !is_rom_cmd(mcp->mb[0])) {
 		ql_log(ql_log_info, vha, 0x1005,
 		    "Cmd 0x%x aborted with timeout since ISP Abort is pending\n",
@@ -268,7 +269,6 @@
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 		wait_time = jiffies;
-		atomic_inc(&ha->num_pend_mbx_stage3);
 		if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
 		    mcp->tov * HZ)) {
 			ql_dbg(ql_dbg_mbx, vha, 0x117a,
@@ -283,7 +283,6 @@
 				spin_unlock_irqrestore(&ha->hardware_lock,
 				    flags);
 				atomic_dec(&ha->num_pend_mbx_stage2);
-				atomic_dec(&ha->num_pend_mbx_stage3);
 				rval = QLA_ABORTED;
 				goto premature_exit;
 			}
@@ -293,11 +292,9 @@
 			ha->flags.mbox_busy = 0;
 			spin_unlock_irqrestore(&ha->hardware_lock, flags);
 			atomic_dec(&ha->num_pend_mbx_stage2);
-			atomic_dec(&ha->num_pend_mbx_stage3);
 			rval = QLA_ABORTED;
 			goto premature_exit;
 		}
-		atomic_dec(&ha->num_pend_mbx_stage3);
 
 		if (time_after(jiffies, wait_time + 5 * HZ))
 			ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n",
diff --git a/kernel/drivers/scsi/qla2xxx/qla_nvme.c b/kernel/drivers/scsi/qla2xxx/qla_nvme.c
index d63ccdf..6dad778 100644
--- a/kernel/drivers/scsi/qla2xxx/qla_nvme.c
+++ b/kernel/drivers/scsi/qla2xxx/qla_nvme.c
@@ -165,18 +165,6 @@
 	qla2xxx_rel_qpair_sp(sp->qpair, sp);
 }
 
-static void qla_nvme_ls_unmap(struct srb *sp, struct nvmefc_ls_req *fd)
-{
-	if (sp->flags & SRB_DMA_VALID) {
-		struct srb_iocb *nvme = &sp->u.iocb_cmd;
-		struct qla_hw_data *ha = sp->fcport->vha->hw;
-
-		dma_unmap_single(&ha->pdev->dev, nvme->u.nvme.cmd_dma,
-				 fd->rqstlen, DMA_TO_DEVICE);
-		sp->flags &= ~SRB_DMA_VALID;
-	}
-}
-
 static void qla_nvme_release_ls_cmd_kref(struct kref *kref)
 {
 	struct srb *sp = container_of(kref, struct srb, cmd_kref);
@@ -194,7 +182,6 @@
 
 	fd = priv->fd;
 
-	qla_nvme_ls_unmap(sp, fd);
 	fd->done(fd, priv->comp_status);
 out:
 	qla2x00_rel_sp(sp);
@@ -336,21 +323,16 @@
 	nvme->u.nvme.rsp_len = fd->rsplen;
 	nvme->u.nvme.rsp_dma = fd->rspdma;
 	nvme->u.nvme.timeout_sec = fd->timeout;
-	nvme->u.nvme.cmd_dma = dma_map_single(&ha->pdev->dev, fd->rqstaddr,
-	    fd->rqstlen, DMA_TO_DEVICE);
+	nvme->u.nvme.cmd_dma = fd->rqstdma;
 	dma_sync_single_for_device(&ha->pdev->dev, nvme->u.nvme.cmd_dma,
 	    fd->rqstlen, DMA_TO_DEVICE);
-
-	sp->flags |= SRB_DMA_VALID;
 
 	rval = qla2x00_start_sp(sp);
 	if (rval != QLA_SUCCESS) {
 		ql_log(ql_log_warn, vha, 0x700e,
 		    "qla2x00_start_sp failed = %d\n", rval);
-		wake_up(&sp->nvme_ls_waitq);
 		sp->priv = NULL;
 		priv->sp = NULL;
-		qla_nvme_ls_unmap(sp, fd);
 		qla2x00_rel_sp(sp);
 		return rval;
 	}
@@ -415,8 +397,13 @@
 	}
 	req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
 	if (req->cnt < (req_cnt + 2)) {
-		cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
-		    rd_reg_dword_relaxed(req->req_q_out);
+		if (IS_SHADOW_REG_CAPABLE(ha)) {
+			cnt = *req->out_ptr;
+		} else {
+			cnt = rd_reg_dword_relaxed(req->req_q_out);
+			if (qla2x00_check_reg16_for_disconnect(vha, cnt))
+				goto queuing_error;
+		}
 
 		if (req->ring_index < cnt)
 			req->cnt = cnt - req->ring_index;
@@ -553,6 +540,7 @@
 
 queuing_error:
 	spin_unlock_irqrestore(&qpair->qp_lock, flags);
+
 	return rval;
 }
 
@@ -607,7 +595,6 @@
 	if (!sp)
 		return -EBUSY;
 
-	init_waitqueue_head(&sp->nvme_ls_waitq);
 	kref_init(&sp->cmd_kref);
 	spin_lock_init(&priv->cmd_lock);
 	sp->priv = priv;
@@ -623,9 +610,8 @@
 
 	rval = qla2x00_start_nvme_mq(sp);
 	if (rval != QLA_SUCCESS) {
-		ql_log(ql_log_warn, vha, 0x212d,
+		ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x212d,
 		    "qla2x00_start_nvme_mq failed = %d\n", rval);
-		wake_up(&sp->nvme_ls_waitq);
 		sp->priv = NULL;
 		priv->sp = NULL;
 		qla2xxx_rel_qpair_sp(sp->qpair, sp);
diff --git a/kernel/drivers/scsi/qla2xxx/qla_os.c b/kernel/drivers/scsi/qla2xxx/qla_os.c
index 4191561..8d199de 100644
--- a/kernel/drivers/scsi/qla2xxx/qla_os.c
+++ b/kernel/drivers/scsi/qla2xxx/qla_os.c
@@ -879,8 +879,8 @@
 			goto qc24_fail_command;
 	}
 
-	if (!fcport) {
-		cmd->result = DID_NO_CONNECT << 16;
+	if (!fcport || fcport->deleted) {
+		cmd->result = DID_IMM_RETRY << 16;
 		goto qc24_fail_command;
 	}
 
@@ -961,8 +961,15 @@
 		goto qc24_fail_command;
 	}
 
-	if (!fcport) {
+	if (!qpair->online) {
+		ql_dbg(ql_dbg_io, vha, 0x3077,
+		       "qpair not online. eeh_busy=%d.\n", ha->flags.eeh_busy);
 		cmd->result = DID_NO_CONNECT << 16;
+		goto qc24_fail_command;
+	}
+
+	if (!fcport || fcport->deleted) {
+		cmd->result = DID_IMM_RETRY << 16;
 		goto qc24_fail_command;
 	}
 
@@ -1190,35 +1197,6 @@
 	return return_status;
 }
 
-#define ISP_REG_DISCONNECT 0xffffffffU
-/**************************************************************************
-* qla2x00_isp_reg_stat
-*
-* Description:
-*	Read the host status register of ISP before aborting the command.
-*
-* Input:
-*	ha = pointer to host adapter structure.
-*
-*
-* Returns:
-*	Either true or false.
-*
-* Note:	Return true if there is register disconnect.
-**************************************************************************/
-static inline
-uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
-{
-	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
-	struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82;
-
-	if (IS_P3P_TYPE(ha))
-		return ((rd_reg_dword(&reg82->host_int)) == ISP_REG_DISCONNECT);
-	else
-		return ((rd_reg_dword(&reg->host_status)) ==
-			ISP_REG_DISCONNECT);
-}
-
 /**************************************************************************
 * qla2xxx_eh_abort
 *
@@ -1253,6 +1231,7 @@
 	if (qla2x00_isp_reg_stat(ha)) {
 		ql_log(ql_log_info, vha, 0x8042,
 		    "PCI/Register disconnect, exiting.\n");
+		qla_pci_set_eeh_busy(vha);
 		return FAILED;
 	}
 
@@ -1444,6 +1423,7 @@
 	if (qla2x00_isp_reg_stat(ha)) {
 		ql_log(ql_log_info, vha, 0x803e,
 		    "PCI/Register disconnect, exiting.\n");
+		qla_pci_set_eeh_busy(vha);
 		return FAILED;
 	}
 
@@ -1460,6 +1440,7 @@
 	if (qla2x00_isp_reg_stat(ha)) {
 		ql_log(ql_log_info, vha, 0x803f,
 		    "PCI/Register disconnect, exiting.\n");
+		qla_pci_set_eeh_busy(vha);
 		return FAILED;
 	}
 
@@ -1495,6 +1476,7 @@
 	if (qla2x00_isp_reg_stat(ha)) {
 		ql_log(ql_log_info, vha, 0x8040,
 		    "PCI/Register disconnect, exiting.\n");
+		qla_pci_set_eeh_busy(vha);
 		return FAILED;
 	}
 
@@ -1572,7 +1554,7 @@
 	if (qla2x00_isp_reg_stat(ha)) {
 		ql_log(ql_log_info, vha, 0x8041,
 		    "PCI/Register disconnect, exiting.\n");
-		schedule_work(&ha->board_disable);
+		qla_pci_set_eeh_busy(vha);
 		return SUCCESS;
 	}
 
@@ -1762,6 +1744,17 @@
 	for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
 		sp = req->outstanding_cmds[cnt];
 		if (sp) {
+			/*
+			 * perform lockless completion during driver unload
+			 */
+			if (qla2x00_chip_is_down(vha)) {
+				req->outstanding_cmds[cnt] = NULL;
+				spin_unlock_irqrestore(qp->qp_lock_ptr, flags);
+				sp->done(sp, res);
+				spin_lock_irqsave(qp->qp_lock_ptr, flags);
+				continue;
+			}
+
 			switch (sp->cmd_type) {
 			case TYPE_SRB:
 				qla2x00_abort_srb(qp, sp, res, &flags);
@@ -2855,7 +2848,6 @@
 	ha->max_exchg = FW_MAX_EXCHANGES_CNT;
 	atomic_set(&ha->num_pend_mbx_stage1, 0);
 	atomic_set(&ha->num_pend_mbx_stage2, 0);
-	atomic_set(&ha->num_pend_mbx_stage3, 0);
 	atomic_set(&ha->zio_threshold, DEFAULT_ZIO_THRESHOLD);
 	ha->last_zio_threshold = DEFAULT_ZIO_THRESHOLD;
 
@@ -3130,6 +3122,13 @@
 	host->max_id = ha->max_fibre_devices;
 	host->cmd_per_lun = 3;
 	host->unique_id = host->host_no;
+
+	if (ql2xenabledif && ql2xenabledif != 2) {
+		ql_log(ql_log_warn, base_vha, 0x302d,
+		       "Invalid value for ql2xenabledif, resetting it to default (2)\n");
+		ql2xenabledif = 2;
+	}
+
 	if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif)
 		host->max_cmd_len = 32;
 	else
@@ -3362,8 +3361,6 @@
 			base_vha->flags.difdix_supported = 1;
 			ql_dbg(ql_dbg_init, base_vha, 0x00f1,
 			    "Registering for DIF/DIX type 1 and 3 protection.\n");
-			if (ql2xenabledif == 1)
-				prot = SHOST_DIX_TYPE0_PROTECTION;
 			if (ql2xprotmask)
 				scsi_host_set_prot(host, ql2xprotmask);
 			else
@@ -4866,7 +4863,8 @@
 	}
 	INIT_DELAYED_WORK(&vha->scan.scan_work, qla_scan_work_fn);
 
-	sprintf(vha->host_str, "%s_%lu", QLA2XXX_DRIVER_NAME, vha->host_no);
+	snprintf(vha->host_str, sizeof(vha->host_str), "%s_%lu",
+		 QLA2XXX_DRIVER_NAME, vha->host_no);
 	ql_dbg(ql_dbg_init, vha, 0x0041,
 	    "Allocated the host=%p hw=%p vha=%p dev_name=%s",
 	    vha->host, vha->hw, vha,
@@ -6660,6 +6658,9 @@
 
 		schedule();
 
+		if (test_and_clear_bit(DO_EEH_RECOVERY, &base_vha->dpc_flags))
+			qla_pci_set_eeh_busy(base_vha);
+
 		if (!base_vha->flags.init_done || ha->flags.mbox_busy)
 			goto end_loop;
 
@@ -6899,9 +6900,12 @@
 			}
 		}
 loop_resync_check:
-		if (test_and_clear_bit(LOOP_RESYNC_NEEDED,
+		if (!qla2x00_reset_active(base_vha) &&
+		    test_and_clear_bit(LOOP_RESYNC_NEEDED,
 		    &base_vha->dpc_flags)) {
-
+			/*
+			 * Allow abort_isp to complete before moving on to scanning.
+			 */
 			ql_dbg(ql_dbg_dpc, base_vha, 0x400f,
 			    "Loop resync scheduled.\n");
 
@@ -6953,26 +6957,21 @@
 			mutex_unlock(&ha->mq_lock);
 		}
 
-		if (test_and_clear_bit(SET_NVME_ZIO_THRESHOLD_NEEDED,
-		    &base_vha->dpc_flags)) {
-			ql_log(ql_log_info, base_vha, 0xffffff,
-				"nvme: SET ZIO Activity exchange threshold to %d.\n",
-						ha->nvme_last_rptd_aen);
-			if (qla27xx_set_zio_threshold(base_vha,
-			    ha->nvme_last_rptd_aen)) {
-				ql_log(ql_log_info, base_vha, 0xffffff,
-				    "nvme: Unable to SET ZIO Activity exchange threshold to %d.\n",
-				    ha->nvme_last_rptd_aen);
-			}
-		}
-
 		if (test_and_clear_bit(SET_ZIO_THRESHOLD_NEEDED,
-		    &base_vha->dpc_flags)) {
+				       &base_vha->dpc_flags)) {
+			u16 threshold = ha->nvme_last_rptd_aen + ha->last_zio_threshold;
+
+			if (threshold > ha->orig_fw_xcb_count)
+				threshold = ha->orig_fw_xcb_count;
+
 			ql_log(ql_log_info, base_vha, 0xffffff,
-			    "SET ZIO Activity exchange threshold to %d.\n",
-			    ha->last_zio_threshold);
-			qla27xx_set_zio_threshold(base_vha,
-			    ha->last_zio_threshold);
+			       "SET ZIO Activity exchange threshold to %d.\n",
+			       threshold);
+			if (qla27xx_set_zio_threshold(base_vha, threshold)) {
+				ql_log(ql_log_info, base_vha, 0xffffff,
+				       "Unable to SET ZIO Activity exchange threshold to %d.\n",
+				       threshold);
+			}
 		}
 
 		if (!IS_QLAFX00(ha))
@@ -7145,7 +7144,7 @@
 
 		/* if the loop has been down for 4 minutes, reinit adapter */
 		if (atomic_dec_and_test(&vha->loop_down_timer) != 0) {
-			if (!(vha->device_flags & DFLG_NO_CABLE)) {
+			if (!(vha->device_flags & DFLG_NO_CABLE) && !vha->vp_idx) {
 				ql_log(ql_log_warn, vha, 0x6009,
 				    "Loop down - aborting ISP.\n");
 
@@ -7190,14 +7189,13 @@
 	index = atomic_read(&ha->nvme_active_aen_cnt);
 	if (!vha->vp_idx &&
 	    (index != ha->nvme_last_rptd_aen) &&
-	    (index >= DEFAULT_ZIO_THRESHOLD) &&
 	    ha->zio_mode == QLA_ZIO_MODE_6 &&
 	    !ha->flags.host_shutting_down) {
+		ha->nvme_last_rptd_aen = atomic_read(&ha->nvme_active_aen_cnt);
 		ql_log(ql_log_info, vha, 0x3002,
 		    "nvme: Sched: Set ZIO exchange threshold to %d.\n",
 		    ha->nvme_last_rptd_aen);
-		ha->nvme_last_rptd_aen = atomic_read(&ha->nvme_active_aen_cnt);
-		set_bit(SET_NVME_ZIO_THRESHOLD_NEEDED, &vha->dpc_flags);
+		set_bit(SET_ZIO_THRESHOLD_NEEDED, &vha->dpc_flags);
 		start_dpc++;
 	}
 
@@ -7370,6 +7368,8 @@
 	int i;
 	unsigned long flags;
 
+	ql_dbg(ql_dbg_aer, vha, 0x9000,
+	       "%s\n", __func__);
 	ha->chip_reset++;
 
 	ha->base_qpair->chip_reset = ha->chip_reset;
@@ -7379,28 +7379,16 @@
 			    ha->base_qpair->chip_reset;
 	}
 
-	/* purge MBox commands */
-	if (atomic_read(&ha->num_pend_mbx_stage3)) {
-		clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
-		complete(&ha->mbx_intr_comp);
-	}
-
-	i = 0;
-
-	while (atomic_read(&ha->num_pend_mbx_stage3) ||
-	    atomic_read(&ha->num_pend_mbx_stage2) ||
-	    atomic_read(&ha->num_pend_mbx_stage1)) {
-		msleep(20);
-		i++;
-		if (i > 50)
-			break;
-	}
-
-	ha->flags.purge_mbox = 0;
+	/*
+	 * purge mailbox might take a while. Slot Reset/chip reset
+	 * will take care of the purge
+	 */
 
 	mutex_lock(&ha->mq_lock);
+	ha->base_qpair->online = 0;
 	list_for_each_entry(qpair, &base_vha->qp_list, qp_list_elem)
 		qpair->online = 0;
+	wmb();
 	mutex_unlock(&ha->mq_lock);
 
 	qla2x00_mark_all_devices_lost(vha);
@@ -7437,14 +7425,17 @@
 {
 	scsi_qla_host_t *vha = pci_get_drvdata(pdev);
 	struct qla_hw_data *ha = vha->hw;
+	pci_ers_result_t ret = PCI_ERS_RESULT_NEED_RESET;
 
-	ql_dbg(ql_dbg_aer, vha, 0x9000,
-	    "PCI error detected, state %x.\n", state);
+	ql_log(ql_log_warn, vha, 0x9000,
+	       "PCI error detected, state %x.\n", state);
+	ha->pci_error_state = QLA_PCI_ERR_DETECTED;
 
 	if (!atomic_read(&pdev->enable_cnt)) {
 		ql_log(ql_log_info, vha, 0xffff,
 			"PCI device is disabled,state %x\n", state);
-		return PCI_ERS_RESULT_NEED_RESET;
+		ret = PCI_ERS_RESULT_NEED_RESET;
+		goto out;
 	}
 
 	switch (state) {
@@ -7454,11 +7445,12 @@
 			set_bit(QPAIR_ONLINE_CHECK_NEEDED, &vha->dpc_flags);
 			qla2xxx_wake_dpc(vha);
 		}
-		return PCI_ERS_RESULT_CAN_RECOVER;
+		ret = PCI_ERS_RESULT_CAN_RECOVER;
+		break;
 	case pci_channel_io_frozen:
-		ha->flags.eeh_busy = 1;
-		qla_pci_error_cleanup(vha);
-		return PCI_ERS_RESULT_NEED_RESET;
+		qla_pci_set_eeh_busy(vha);
+		ret = PCI_ERS_RESULT_NEED_RESET;
+		break;
 	case pci_channel_io_perm_failure:
 		ha->flags.pci_channel_io_perm_failure = 1;
 		qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16);
@@ -7466,9 +7458,12 @@
 			set_bit(QPAIR_ONLINE_CHECK_NEEDED, &vha->dpc_flags);
 			qla2xxx_wake_dpc(vha);
 		}
-		return PCI_ERS_RESULT_DISCONNECT;
+		ret = PCI_ERS_RESULT_DISCONNECT;
 	}
-	return PCI_ERS_RESULT_NEED_RESET;
+out:
+	ql_dbg(ql_dbg_aer, vha, 0x600d,
+	       "PCI error detected returning [%x].\n", ret);
+	return ret;
 }
 
 static pci_ers_result_t
@@ -7482,6 +7477,10 @@
 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 	struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
 
+	ql_log(ql_log_warn, base_vha, 0x9000,
+	       "mmio enabled\n");
+
+	ha->pci_error_state = QLA_PCI_MMIO_ENABLED;
 	if (IS_QLA82XX(ha))
 		return PCI_ERS_RESULT_RECOVERED;
 
@@ -7505,10 +7504,11 @@
 		ql_log(ql_log_info, base_vha, 0x9003,
 		    "RISC paused -- mmio_enabled, Dumping firmware.\n");
 		qla2xxx_dump_fw(base_vha);
-
-		return PCI_ERS_RESULT_NEED_RESET;
-	} else
-		return PCI_ERS_RESULT_RECOVERED;
+	}
+	/* set PCI_ERS_RESULT_NEED_RESET to trigger call to qla2xxx_pci_slot_reset */
+	ql_dbg(ql_dbg_aer, base_vha, 0x600d,
+	       "mmio enabled returning.\n");
+	return PCI_ERS_RESULT_NEED_RESET;
 }
 
 static pci_ers_result_t
@@ -7520,9 +7520,10 @@
 	int rc;
 	struct qla_qpair *qpair = NULL;
 
-	ql_dbg(ql_dbg_aer, base_vha, 0x9004,
-	    "Slot Reset.\n");
+	ql_log(ql_log_warn, base_vha, 0x9004,
+	       "Slot Reset.\n");
 
+	ha->pci_error_state = QLA_PCI_SLOT_RESET;
 	/* Workaround: qla2xxx driver which access hardware earlier
 	 * needs error state to be pci_channel_io_online.
 	 * Otherwise mailbox command timesout.
@@ -7556,16 +7557,24 @@
 		qpair->online = 1;
 	mutex_unlock(&ha->mq_lock);
 
+	ha->flags.eeh_busy = 0;
 	base_vha->flags.online = 1;
 	set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
-	if (ha->isp_ops->abort_isp(base_vha) == QLA_SUCCESS)
-		ret =  PCI_ERS_RESULT_RECOVERED;
+	ha->isp_ops->abort_isp(base_vha);
 	clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
 
+	if (qla2x00_isp_reg_stat(ha)) {
+		ha->flags.eeh_busy = 1;
+		qla_pci_error_cleanup(base_vha);
+		ql_log(ql_log_warn, base_vha, 0x9005,
+		       "Device unable to recover from PCI error.\n");
+	} else {
+		ret =  PCI_ERS_RESULT_RECOVERED;
+	}
 
 exit_slot_reset:
 	ql_dbg(ql_dbg_aer, base_vha, 0x900e,
-	    "slot_reset return %x.\n", ret);
+	    "Slot Reset returning %x.\n", ret);
 
 	return ret;
 }
@@ -7577,16 +7586,55 @@
 	struct qla_hw_data *ha = base_vha->hw;
 	int ret;
 
-	ql_dbg(ql_dbg_aer, base_vha, 0x900f,
-	    "pci_resume.\n");
+	ql_log(ql_log_warn, base_vha, 0x900f,
+	       "Pci Resume.\n");
 
-	ha->flags.eeh_busy = 0;
 
 	ret = qla2x00_wait_for_hba_online(base_vha);
 	if (ret != QLA_SUCCESS) {
 		ql_log(ql_log_fatal, base_vha, 0x9002,
 		    "The device failed to resume I/O from slot/link_reset.\n");
 	}
+	ha->pci_error_state = QLA_PCI_RESUME;
+	ql_dbg(ql_dbg_aer, base_vha, 0x600d,
+	       "Pci Resume returning.\n");
+}
+
+void qla_pci_set_eeh_busy(struct scsi_qla_host *vha)
+{
+	struct qla_hw_data *ha = vha->hw;
+	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
+	bool do_cleanup = false;
+	unsigned long flags;
+
+	if (ha->flags.eeh_busy)
+		return;
+
+	spin_lock_irqsave(&base_vha->work_lock, flags);
+	if (!ha->flags.eeh_busy) {
+		ha->flags.eeh_busy = 1;
+		do_cleanup = true;
+	}
+	spin_unlock_irqrestore(&base_vha->work_lock, flags);
+
+	if (do_cleanup)
+		qla_pci_error_cleanup(base_vha);
+}
+
+/*
+ * this routine will schedule a task to pause IO from interrupt context
+ * if caller sees a PCIE error event (register read = 0xf's)
+ */
+void qla_schedule_eeh_work(struct scsi_qla_host *vha)
+{
+	struct qla_hw_data *ha = vha->hw;
+	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
+
+	if (ha->flags.eeh_busy)
+		return;
+
+	set_bit(DO_EEH_RECOVERY, &base_vha->dpc_flags);
+	qla2xxx_wake_dpc(base_vha);
 }
 
 static void
diff --git a/kernel/drivers/scsi/qla2xxx/qla_target.c b/kernel/drivers/scsi/qla2xxx/qla_target.c
index ecb30c2..fdb4245 100644
--- a/kernel/drivers/scsi/qla2xxx/qla_target.c
+++ b/kernel/drivers/scsi/qla2xxx/qla_target.c
@@ -1044,10 +1044,6 @@
 			(struct imm_ntfy_from_isp *)sess->iocb, SRB_NACK_LOGO);
 	}
 
-	spin_lock_irqsave(&vha->work_lock, flags);
-	sess->flags &= ~FCF_ASYNC_SENT;
-	spin_unlock_irqrestore(&vha->work_lock, flags);
-
 	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 	if (sess->se_sess) {
 		sess->se_sess = NULL;
@@ -1057,7 +1053,6 @@
 
 	qla2x00_set_fcport_disc_state(sess, DSC_DELETED);
 	sess->fw_login_state = DSC_LS_PORT_UNAVAIL;
-	sess->deleted = QLA_SESS_DELETED;
 
 	if (sess->login_succ && !IS_SW_RESV_ADDR(sess->d_id)) {
 		vha->fcport_count--;
@@ -1109,9 +1104,14 @@
 
 	sess->explicit_logout = 0;
 	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
-	sess->free_pending = 0;
 
 	qla2x00_dfs_remove_rport(vha, sess);
+
+	spin_lock_irqsave(&vha->work_lock, flags);
+	sess->flags &= ~FCF_ASYNC_SENT;
+	sess->deleted = QLA_SESS_DELETED;
+	sess->free_pending = 0;
+	spin_unlock_irqrestore(&vha->work_lock, flags);
 
 	ql_dbg(ql_dbg_disc, vha, 0xf001,
 	    "Unregistration of sess %p %8phC finished fcp_cnt %d\n",
@@ -1161,12 +1161,12 @@
 	 * management from being sent.
 	 */
 	sess->flags |= FCF_ASYNC_SENT;
+	sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
 	spin_unlock_irqrestore(&sess->vha->work_lock, flags);
 
 	if (sess->se_sess)
 		vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess);
 
-	sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
 	qla2x00_set_fcport_disc_state(sess, DSC_DELETE_PEND);
 	sess->last_rscn_gen = sess->rscn_gen;
 	sess->last_login_gen = sess->login_gen;
diff --git a/kernel/drivers/scsi/qla4xxx/ql4_os.c b/kernel/drivers/scsi/qla4xxx/ql4_os.c
index 8d82d2a..05ae9b1 100644
--- a/kernel/drivers/scsi/qla4xxx/ql4_os.c
+++ b/kernel/drivers/scsi/qla4xxx/ql4_os.c
@@ -973,6 +973,11 @@
 	memset(&chap_rec, 0, sizeof(chap_rec));
 
 	nla_for_each_attr(attr, data, len, rem) {
+		if (nla_len(attr) < sizeof(*param_info)) {
+			rc = -EINVAL;
+			goto exit_set_chap;
+		}
+
 		param_info = nla_data(attr);
 
 		switch (param_info->param) {
@@ -2755,6 +2760,11 @@
 	}
 
 	nla_for_each_attr(attr, data, len, rem) {
+		if (nla_len(attr) < sizeof(*iface_param)) {
+			rval = -EINVAL;
+			goto exit_init_fw_cb;
+		}
+
 		iface_param = nla_data(attr);
 
 		if (iface_param->param_type == ISCSI_NET_PARAM) {
@@ -8119,6 +8129,11 @@
 
 	memset((void *)&chap_tbl, 0, sizeof(chap_tbl));
 	nla_for_each_attr(attr, data, len, rem) {
+		if (nla_len(attr) < sizeof(*fnode_param)) {
+			rc = -EINVAL;
+			goto exit_set_param;
+		}
+
 		fnode_param = nla_data(attr);
 
 		switch (fnode_param->param) {
diff --git a/kernel/drivers/scsi/raid_class.c b/kernel/drivers/scsi/raid_class.c
index 898a0bd..95a86e0 100644
--- a/kernel/drivers/scsi/raid_class.c
+++ b/kernel/drivers/scsi/raid_class.c
@@ -209,53 +209,6 @@
 raid_attr_ro_fn(resync);
 raid_attr_ro_state_fn(state);
 
-static void raid_component_release(struct device *dev)
-{
-	struct raid_component *rc =
-		container_of(dev, struct raid_component, dev);
-	dev_printk(KERN_ERR, rc->dev.parent, "COMPONENT RELEASE\n");
-	put_device(rc->dev.parent);
-	kfree(rc);
-}
-
-int raid_component_add(struct raid_template *r,struct device *raid_dev,
-		       struct device *component_dev)
-{
-	struct device *cdev =
-		attribute_container_find_class_device(&r->raid_attrs.ac,
-						      raid_dev);
-	struct raid_component *rc;
-	struct raid_data *rd = dev_get_drvdata(cdev);
-	int err;
-
-	rc = kzalloc(sizeof(*rc), GFP_KERNEL);
-	if (!rc)
-		return -ENOMEM;
-
-	INIT_LIST_HEAD(&rc->node);
-	device_initialize(&rc->dev);
-	rc->dev.release = raid_component_release;
-	rc->dev.parent = get_device(component_dev);
-	rc->num = rd->component_count++;
-
-	dev_set_name(&rc->dev, "component-%d", rc->num);
-	list_add_tail(&rc->node, &rd->component_list);
-	rc->dev.class = &raid_class.class;
-	err = device_add(&rc->dev);
-	if (err)
-		goto err_out;
-
-	return 0;
-
-err_out:
-	list_del(&rc->node);
-	rd->component_count--;
-	put_device(component_dev);
-	kfree(rc);
-	return err;
-}
-EXPORT_SYMBOL(raid_component_add);
-
 struct raid_template *
 raid_class_attach(struct raid_function_template *ft)
 {
diff --git a/kernel/drivers/scsi/scsi.c b/kernel/drivers/scsi/scsi.c
index 6ad834d..d6c25a8 100644
--- a/kernel/drivers/scsi/scsi.c
+++ b/kernel/drivers/scsi/scsi.c
@@ -317,11 +317,18 @@
 	if (result)
 		return -EIO;
 
-	/* Sanity check that we got the page back that we asked for */
+	/*
+	 * Sanity check that we got the page back that we asked for and that
+	 * the page size is not 0.
+	 */
 	if (buffer[1] != page)
 		return -EIO;
 
-	return get_unaligned_be16(&buffer[2]) + 4;
+	result = get_unaligned_be16(&buffer[2]);
+	if (!result)
+		return -EIO;
+
+	return result + 4;
 }
 
 /**
diff --git a/kernel/drivers/scsi/scsi_debug.c b/kernel/drivers/scsi/scsi_debug.c
index cc20621..7cfc6db 100644
--- a/kernel/drivers/scsi/scsi_debug.c
+++ b/kernel/drivers/scsi/scsi_debug.c
@@ -3619,7 +3619,7 @@
 		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)
@@ -4275,7 +4275,7 @@
 	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);
@@ -4346,7 +4346,7 @@
 	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);
@@ -7103,7 +7103,10 @@
 		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;
 }
diff --git a/kernel/drivers/scsi/scsi_devinfo.c b/kernel/drivers/scsi/scsi_devinfo.c
index 9a8f9f9..f5e121f 100644
--- a/kernel/drivers/scsi/scsi_devinfo.c
+++ b/kernel/drivers/scsi/scsi_devinfo.c
@@ -232,6 +232,7 @@
 	{"SGI", "RAID5", "*", BLIST_SPARSELUN},
 	{"SGI", "TP9100", "*", BLIST_REPORTLUN2},
 	{"SGI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
+	{"SKhynix", "H28U74301AMR", NULL, BLIST_SKIP_VPD_PAGES},
 	{"IBM", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
 	{"SUN", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
 	{"DELL", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
diff --git a/kernel/drivers/scsi/scsi_error.c b/kernel/drivers/scsi/scsi_error.c
index f11f51e..0c4bc42 100644
--- a/kernel/drivers/scsi/scsi_error.c
+++ b/kernel/drivers/scsi/scsi_error.c
@@ -306,19 +306,11 @@
 
 	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);
diff --git a/kernel/drivers/scsi/scsi_lib.c b/kernel/drivers/scsi/scsi_lib.c
index 6f3d29d..99b9003 100644
--- a/kernel/drivers/scsi/scsi_lib.c
+++ b/kernel/drivers/scsi/scsi_lib.c
@@ -1490,6 +1490,7 @@
 		 */
 		SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
 			"queuecommand : device blocked\n"));
+		atomic_dec(&cmd->device->iorequest_cnt);
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 	}
 
@@ -1522,6 +1523,7 @@
 	trace_scsi_dispatch_cmd_start(cmd);
 	rtn = host->hostt->queuecommand(host, cmd);
 	if (rtn) {
+		atomic_dec(&cmd->device->iorequest_cnt);
 		trace_scsi_dispatch_cmd_error(cmd, rtn);
 		if (rtn != SCSI_MLQUEUE_DEVICE_BUSY &&
 		    rtn != SCSI_MLQUEUE_TARGET_BUSY)
diff --git a/kernel/drivers/scsi/scsi_proc.c b/kernel/drivers/scsi/scsi_proc.c
index d6982d3..94603e6 100644
--- a/kernel/drivers/scsi/scsi_proc.c
+++ b/kernel/drivers/scsi/scsi_proc.c
@@ -311,7 +311,7 @@
 			       size_t length, loff_t *ppos)
 {
 	int host, channel, id, lun;
-	char *buffer, *p;
+	char *buffer, *end, *p;
 	int err;
 
 	if (!buf || length > PAGE_SIZE)
@@ -326,10 +326,14 @@
 		goto out;
 
 	err = -EINVAL;
-	if (length < PAGE_SIZE)
-		buffer[length] = '\0';
-	else if (buffer[PAGE_SIZE-1])
-		goto out;
+	if (length < PAGE_SIZE) {
+		end = buffer + length;
+		*end = '\0';
+	} else {
+		end = buffer + PAGE_SIZE - 1;
+		if (*end)
+			goto out;
+	}
 
 	/*
 	 * Usage: echo "scsi add-single-device 0 1 2 3" >/proc/scsi/scsi
@@ -338,10 +342,10 @@
 	if (!strncmp("scsi add-single-device", buffer, 22)) {
 		p = buffer + 23;
 
-		host = simple_strtoul(p, &p, 0);
-		channel = simple_strtoul(p + 1, &p, 0);
-		id = simple_strtoul(p + 1, &p, 0);
-		lun = simple_strtoul(p + 1, &p, 0);
+		host    = (p     < end) ? simple_strtoul(p, &p, 0) : 0;
+		channel = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
+		id      = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
+		lun     = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
 
 		err = scsi_add_single_device(host, channel, id, lun);
 
@@ -352,10 +356,10 @@
 	} else if (!strncmp("scsi remove-single-device", buffer, 25)) {
 		p = buffer + 26;
 
-		host = simple_strtoul(p, &p, 0);
-		channel = simple_strtoul(p + 1, &p, 0);
-		id = simple_strtoul(p + 1, &p, 0);
-		lun = simple_strtoul(p + 1, &p, 0);
+		host    = (p     < end) ? simple_strtoul(p, &p, 0) : 0;
+		channel = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
+		id      = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
+		lun     = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
 
 		err = scsi_remove_single_device(host, channel, id, lun);
 	}
diff --git a/kernel/drivers/scsi/scsi_scan.c b/kernel/drivers/scsi/scsi_scan.c
index 8e474b1..6f7c4d4 100644
--- a/kernel/drivers/scsi/scsi_scan.c
+++ b/kernel/drivers/scsi/scsi_scan.c
@@ -1129,8 +1129,7 @@
 	 * that no LUN is present, so don't add sdev in these cases.
 	 * Two specific examples are:
 	 * 1) NetApp targets: return PQ=1, PDT=0x1f
-	 * 2) IBM/2145 targets: return PQ=1, PDT=0
-	 * 3) USB UFI: returns PDT=0x1f, with the PQ bits being "reserved"
+	 * 2) USB UFI: returns PDT=0x1f, with the PQ bits being "reserved"
 	 *    in the UFI 1.0 spec (we cannot rely on reserved bits).
 	 *
 	 * References:
@@ -1144,8 +1143,8 @@
 	 * PDT=00h Direct-access device (floppy)
 	 * PDT=1Fh none (no FDD connected to the requested logical unit)
 	 */
-	if (((result[0] >> 5) == 1 ||
-	    (starget->pdt_1f_for_no_lun && (result[0] & 0x1f) == 0x1f)) &&
+	if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) &&
+	    (result[0] & 0x1f) == 0x1f &&
 	    !scsi_is_wlun(lun)) {
 		SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
 					"scsi scan: peripheral device type"
diff --git a/kernel/drivers/scsi/scsi_transport_iscsi.c b/kernel/drivers/scsi/scsi_transport_iscsi.c
index ef7cd75..074cbd6 100644
--- a/kernel/drivers/scsi/scsi_transport_iscsi.c
+++ b/kernel/drivers/scsi/scsi_transport_iscsi.c
@@ -1674,6 +1674,13 @@
 	return name;
 }
 
+static char *iscsi_session_target_state_name[] = {
+	[ISCSI_SESSION_TARGET_UNBOUND]   = "UNBOUND",
+	[ISCSI_SESSION_TARGET_ALLOCATED] = "ALLOCATED",
+	[ISCSI_SESSION_TARGET_SCANNED]   = "SCANNED",
+	[ISCSI_SESSION_TARGET_UNBINDING] = "UNBINDING",
+};
+
 int iscsi_session_chkready(struct iscsi_cls_session *session)
 {
 	unsigned long flags;
@@ -1805,9 +1812,13 @@
 		if ((scan_data->channel == SCAN_WILD_CARD ||
 		     scan_data->channel == 0) &&
 		    (scan_data->id == SCAN_WILD_CARD ||
-		     scan_data->id == id))
+		     scan_data->id == id)) {
 			scsi_scan_target(&session->dev, 0, id,
 					 scan_data->lun, scan_data->rescan);
+			spin_lock_irqsave(&session->lock, flags);
+			session->target_state = ISCSI_SESSION_TARGET_SCANNED;
+			spin_unlock_irqrestore(&session->lock, flags);
+		}
 	}
 
 user_scan_exit:
@@ -1996,31 +2007,41 @@
 	struct iscsi_cls_host *ihost = shost->shost_data;
 	unsigned long flags;
 	unsigned int target_id;
+	bool remove_target = true;
 
 	ISCSI_DBG_TRANS_SESSION(session, "Unbinding session\n");
 
 	/* Prevent new scans and make sure scanning is not in progress */
 	mutex_lock(&ihost->mutex);
 	spin_lock_irqsave(&session->lock, flags);
-	if (session->target_id == ISCSI_MAX_TARGET) {
+	if (session->target_state == ISCSI_SESSION_TARGET_ALLOCATED) {
+		remove_target = false;
+	} else if (session->target_state != ISCSI_SESSION_TARGET_SCANNED) {
 		spin_unlock_irqrestore(&session->lock, flags);
 		mutex_unlock(&ihost->mutex);
-		goto unbind_session_exit;
+		ISCSI_DBG_TRANS_SESSION(session,
+			"Skipping target unbinding: Session is unbound/unbinding.\n");
+		return;
 	}
 
+	session->target_state = ISCSI_SESSION_TARGET_UNBINDING;
 	target_id = session->target_id;
 	session->target_id = ISCSI_MAX_TARGET;
 	spin_unlock_irqrestore(&session->lock, flags);
 	mutex_unlock(&ihost->mutex);
 
-	scsi_remove_target(&session->dev);
+	if (remove_target)
+		scsi_remove_target(&session->dev);
 
 	if (session->ida_used)
 		ida_simple_remove(&iscsi_sess_ida, target_id);
 
-unbind_session_exit:
 	iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
 	ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
+
+	spin_lock_irqsave(&session->lock, flags);
+	session->target_state = ISCSI_SESSION_TARGET_UNBOUND;
+	spin_unlock_irqrestore(&session->lock, flags);
 }
 
 static void __iscsi_destroy_session(struct work_struct *work)
@@ -2089,6 +2110,9 @@
 		session->ida_used = true;
 	} else
 		session->target_id = target_id;
+	spin_lock_irqsave(&session->lock, flags);
+	session->target_state = ISCSI_SESSION_TARGET_ALLOCATED;
+	spin_unlock_irqrestore(&session->lock, flags);
 
 	dev_set_name(&session->dev, "session%u", session->sid);
 	err = device_add(&session->dev);
@@ -2967,19 +2991,24 @@
 }
 
 static int
-iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
+iscsi_if_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev, u32 rlen)
 {
 	char *data = (char*)ev + sizeof(*ev);
 	struct iscsi_cls_conn *conn;
 	struct iscsi_cls_session *session;
 	int err = 0, value = 0, state;
 
-	if (ev->u.set_param.len > PAGE_SIZE)
+	if (ev->u.set_param.len > rlen ||
+	    ev->u.set_param.len > PAGE_SIZE)
 		return -EINVAL;
 
 	session = iscsi_session_lookup(ev->u.set_param.sid);
 	conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid);
 	if (!conn || !session)
+		return -EINVAL;
+
+	/* data will be regarded as NULL-ended string, do length check */
+	if (strlen(data) > ev->u.set_param.len)
 		return -EINVAL;
 
 	switch (ev->u.set_param.param) {
@@ -3071,7 +3100,7 @@
 
 static int
 iscsi_if_transport_ep(struct iscsi_transport *transport,
-		      struct iscsi_uevent *ev, int msg_type)
+		      struct iscsi_uevent *ev, int msg_type, u32 rlen)
 {
 	struct iscsi_endpoint *ep;
 	int rc = 0;
@@ -3079,7 +3108,10 @@
 	switch (msg_type) {
 	case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST:
 	case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
-		rc = iscsi_if_ep_connect(transport, ev, msg_type);
+		if (rlen < sizeof(struct sockaddr))
+			rc = -EINVAL;
+		else
+			rc = iscsi_if_ep_connect(transport, ev, msg_type);
 		break;
 	case ISCSI_UEVENT_TRANSPORT_EP_POLL:
 		if (!transport->ep_poll)
@@ -3103,11 +3135,14 @@
 
 static int
 iscsi_tgt_dscvr(struct iscsi_transport *transport,
-		struct iscsi_uevent *ev)
+		struct iscsi_uevent *ev, u32 rlen)
 {
 	struct Scsi_Host *shost;
 	struct sockaddr *dst_addr;
 	int err;
+
+	if (rlen < sizeof(*dst_addr))
+		return -EINVAL;
 
 	if (!transport->tgt_dscvr)
 		return -EINVAL;
@@ -3129,7 +3164,7 @@
 
 static int
 iscsi_set_host_param(struct iscsi_transport *transport,
-		     struct iscsi_uevent *ev)
+		     struct iscsi_uevent *ev, u32 rlen)
 {
 	char *data = (char*)ev + sizeof(*ev);
 	struct Scsi_Host *shost;
@@ -3138,7 +3173,8 @@
 	if (!transport->set_host_param)
 		return -ENOSYS;
 
-	if (ev->u.set_host_param.len > PAGE_SIZE)
+	if (ev->u.set_host_param.len > rlen ||
+	    ev->u.set_host_param.len > PAGE_SIZE)
 		return -EINVAL;
 
 	shost = scsi_host_lookup(ev->u.set_host_param.host_no);
@@ -3148,6 +3184,10 @@
 		return -ENODEV;
 	}
 
+	/* see similar check in iscsi_if_set_param() */
+	if (strlen(data) > ev->u.set_host_param.len)
+		return -EINVAL;
+
 	err = transport->set_host_param(shost, ev->u.set_host_param.param,
 					data, ev->u.set_host_param.len);
 	scsi_host_put(shost);
@@ -3155,11 +3195,14 @@
 }
 
 static int
-iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev)
+iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev, u32 rlen)
 {
 	struct Scsi_Host *shost;
 	struct iscsi_path *params;
 	int err;
+
+	if (rlen < sizeof(*params))
+		return -EINVAL;
 
 	if (!transport->set_path)
 		return -ENOSYS;
@@ -3220,11 +3263,14 @@
 }
 
 static int
-iscsi_send_ping(struct iscsi_transport *transport, struct iscsi_uevent *ev)
+iscsi_send_ping(struct iscsi_transport *transport, struct iscsi_uevent *ev, u32 rlen)
 {
 	struct Scsi_Host *shost;
 	struct sockaddr *dst_addr;
 	int err;
+
+	if (rlen < sizeof(*dst_addr))
+		return -EINVAL;
 
 	if (!transport->send_ping)
 		return -ENOSYS;
@@ -3723,13 +3769,12 @@
 }
 
 static int iscsi_if_transport_conn(struct iscsi_transport *transport,
-				   struct nlmsghdr *nlh)
+				   struct nlmsghdr *nlh, u32 pdu_len)
 {
 	struct iscsi_uevent *ev = nlmsg_data(nlh);
 	struct iscsi_cls_session *session;
 	struct iscsi_cls_conn *conn = NULL;
 	struct iscsi_endpoint *ep;
-	uint32_t pdu_len;
 	int err = 0;
 
 	switch (nlh->nlmsg_type) {
@@ -3809,8 +3854,6 @@
 
 		break;
 	case ISCSI_UEVENT_SEND_PDU:
-		pdu_len = nlh->nlmsg_len - sizeof(*nlh) - sizeof(*ev);
-
 		if ((ev->u.send_pdu.hdr_size > pdu_len) ||
 		    (ev->u.send_pdu.data_size > (pdu_len - ev->u.send_pdu.hdr_size))) {
 			err = -EINVAL;
@@ -3840,6 +3883,7 @@
 	struct iscsi_internal *priv;
 	struct iscsi_cls_session *session;
 	struct iscsi_endpoint *ep = NULL;
+	u32 rlen;
 
 	if (!netlink_capable(skb, CAP_SYS_ADMIN))
 		return -EPERM;
@@ -3858,6 +3902,13 @@
 		return -EINVAL;
 
 	portid = NETLINK_CB(skb).portid;
+
+	/*
+	 * Even though the remaining payload may not be regarded as nlattr,
+	 * (like address or something else), calculate the remaining length
+	 * here to ease following length checks.
+	 */
+	rlen = nlmsg_attrlen(nlh, sizeof(*ev));
 
 	switch (nlh->nlmsg_type) {
 	case ISCSI_UEVENT_CREATE_SESSION:
@@ -3916,7 +3967,7 @@
 			err = -EINVAL;
 		break;
 	case ISCSI_UEVENT_SET_PARAM:
-		err = iscsi_set_param(transport, ev);
+		err = iscsi_if_set_param(transport, ev, rlen);
 		break;
 	case ISCSI_UEVENT_CREATE_CONN:
 	case ISCSI_UEVENT_DESTROY_CONN:
@@ -3924,7 +3975,7 @@
 	case ISCSI_UEVENT_START_CONN:
 	case ISCSI_UEVENT_BIND_CONN:
 	case ISCSI_UEVENT_SEND_PDU:
-		err = iscsi_if_transport_conn(transport, nlh);
+		err = iscsi_if_transport_conn(transport, nlh, rlen);
 		break;
 	case ISCSI_UEVENT_GET_STATS:
 		err = iscsi_if_get_stats(transport, nlh);
@@ -3933,23 +3984,22 @@
 	case ISCSI_UEVENT_TRANSPORT_EP_POLL:
 	case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
 	case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST:
-		err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type);
+		err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type, rlen);
 		break;
 	case ISCSI_UEVENT_TGT_DSCVR:
-		err = iscsi_tgt_dscvr(transport, ev);
+		err = iscsi_tgt_dscvr(transport, ev, rlen);
 		break;
 	case ISCSI_UEVENT_SET_HOST_PARAM:
-		err = iscsi_set_host_param(transport, ev);
+		err = iscsi_set_host_param(transport, ev, rlen);
 		break;
 	case ISCSI_UEVENT_PATH_UPDATE:
-		err = iscsi_set_path(transport, ev);
+		err = iscsi_set_path(transport, ev, rlen);
 		break;
 	case ISCSI_UEVENT_SET_IFACE_PARAMS:
-		err = iscsi_set_iface_params(transport, ev,
-					     nlmsg_attrlen(nlh, sizeof(*ev)));
+		err = iscsi_set_iface_params(transport, ev, rlen);
 		break;
 	case ISCSI_UEVENT_PING:
-		err = iscsi_send_ping(transport, ev);
+		err = iscsi_send_ping(transport, ev, rlen);
 		break;
 	case ISCSI_UEVENT_GET_CHAP:
 		err = iscsi_get_chap(transport, nlh);
@@ -3958,13 +4008,10 @@
 		err = iscsi_delete_chap(transport, ev);
 		break;
 	case ISCSI_UEVENT_SET_FLASHNODE_PARAMS:
-		err = iscsi_set_flashnode_param(transport, ev,
-						nlmsg_attrlen(nlh,
-							      sizeof(*ev)));
+		err = iscsi_set_flashnode_param(transport, ev, rlen);
 		break;
 	case ISCSI_UEVENT_NEW_FLASHNODE:
-		err = iscsi_new_flashnode(transport, ev,
-					  nlmsg_attrlen(nlh, sizeof(*ev)));
+		err = iscsi_new_flashnode(transport, ev, rlen);
 		break;
 	case ISCSI_UEVENT_DEL_FLASHNODE:
 		err = iscsi_del_flashnode(transport, ev);
@@ -3979,8 +4026,7 @@
 		err = iscsi_logout_flashnode_sid(transport, ev);
 		break;
 	case ISCSI_UEVENT_SET_CHAP:
-		err = iscsi_set_chap(transport, ev,
-				     nlmsg_attrlen(nlh, sizeof(*ev)));
+		err = iscsi_set_chap(transport, ev, rlen);
 		break;
 	case ISCSI_UEVENT_GET_HOST_STATS:
 		err = iscsi_get_host_stats(transport, nlh);
@@ -4344,6 +4390,19 @@
 iscsi_session_attr(discovery_parent_type, ISCSI_PARAM_DISCOVERY_PARENT_TYPE, 0);
 
 static ssize_t
+show_priv_session_target_state(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent);
+
+	return sysfs_emit(buf, "%s\n",
+			iscsi_session_target_state_name[session->target_state]);
+}
+
+static ISCSI_CLASS_ATTR(priv_sess, target_state, S_IRUGO,
+			show_priv_session_target_state, NULL);
+
+static ssize_t
 show_priv_session_state(struct device *dev, struct device_attribute *attr,
 			char *buf)
 {
@@ -4445,6 +4504,7 @@
 	&dev_attr_sess_boot_target.attr,
 	&dev_attr_priv_sess_recovery_tmo.attr,
 	&dev_attr_priv_sess_state.attr,
+	&dev_attr_priv_sess_target_state.attr,
 	&dev_attr_priv_sess_creator.attr,
 	&dev_attr_sess_chap_out_idx.attr,
 	&dev_attr_sess_chap_in_idx.attr,
@@ -4558,6 +4618,8 @@
 		return S_IRUGO | S_IWUSR;
 	else if (attr == &dev_attr_priv_sess_state.attr)
 		return S_IRUGO;
+	else if (attr == &dev_attr_priv_sess_target_state.attr)
+		return S_IRUGO;
 	else if (attr == &dev_attr_priv_sess_creator.attr)
 		return S_IRUGO;
 	else if (attr == &dev_attr_priv_sess_target_id.attr)
diff --git a/kernel/drivers/scsi/ses.c b/kernel/drivers/scsi/ses.c
index 0a1734f..6a1428d 100644
--- a/kernel/drivers/scsi/ses.c
+++ b/kernel/drivers/scsi/ses.c
@@ -433,8 +433,8 @@
 }
 #endif  /*  0  */
 
-static void ses_process_descriptor(struct enclosure_component *ecomp,
-				   unsigned char *desc)
+static int ses_process_descriptor(struct enclosure_component *ecomp,
+				   unsigned char *desc, int max_desc_len)
 {
 	int eip = desc[0] & 0x10;
 	int invalid = desc[0] & 0x80;
@@ -445,22 +445,32 @@
 	unsigned char *d;
 
 	if (invalid)
-		return;
+		return 0;
 
 	switch (proto) {
 	case SCSI_PROTOCOL_FCP:
 		if (eip) {
+			if (max_desc_len <= 7)
+				return 1;
 			d = desc + 4;
 			slot = d[3];
 		}
 		break;
 	case SCSI_PROTOCOL_SAS:
+
 		if (eip) {
+			if (max_desc_len <= 27)
+				return 1;
 			d = desc + 4;
 			slot = d[3];
 			d = desc + 8;
-		} else
+		} else {
+			if (max_desc_len <= 23)
+				return 1;
 			d = desc + 4;
+		}
+
+
 		/* only take the phy0 addr */
 		addr = (u64)d[12] << 56 |
 			(u64)d[13] << 48 |
@@ -477,6 +487,8 @@
 	}
 	ecomp->slot = slot;
 	scomp->addr = addr;
+
+	return 0;
 }
 
 struct efd {
@@ -490,9 +502,6 @@
 	struct efd *efd = data;
 	int i;
 	struct ses_component *scomp;
-
-	if (!edev->component[0].scratch)
-		return 0;
 
 	for (i = 0; i < edev->components; i++) {
 		scomp = edev->component[i].scratch;
@@ -549,7 +558,7 @@
 		/* skip past overall descriptor */
 		desc_ptr += len + 4;
 	}
-	if (ses_dev->page10)
+	if (ses_dev->page10 && ses_dev->page10_len > 9)
 		addl_desc_ptr = ses_dev->page10 + 8;
 	type_ptr = ses_dev->page1_types;
 	components = 0;
@@ -557,17 +566,22 @@
 		for (j = 0; j < type_ptr[1]; j++) {
 			char *name = NULL;
 			struct enclosure_component *ecomp;
+			int max_desc_len;
 
 			if (desc_ptr) {
-				if (desc_ptr >= buf + page7_len) {
+				if (desc_ptr + 3 >= buf + page7_len) {
 					desc_ptr = NULL;
 				} else {
 					len = (desc_ptr[2] << 8) + desc_ptr[3];
 					desc_ptr += 4;
-					/* Add trailing zero - pushes into
-					 * reserved space */
-					desc_ptr[len] = '\0';
-					name = desc_ptr;
+					if (desc_ptr + len > buf + page7_len)
+						desc_ptr = NULL;
+					else {
+						/* Add trailing zero - pushes into
+						 * reserved space */
+						desc_ptr[len] = '\0';
+						name = desc_ptr;
+					}
 				}
 			}
 			if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
@@ -579,14 +593,20 @@
 						components++,
 						type_ptr[0],
 						name);
-				else
+				else if (components < edev->components)
 					ecomp = &edev->component[components++];
+				else
+					ecomp = ERR_PTR(-EINVAL);
 
 				if (!IS_ERR(ecomp)) {
-					if (addl_desc_ptr)
-						ses_process_descriptor(
-							ecomp,
-							addl_desc_ptr);
+					if (addl_desc_ptr) {
+						max_desc_len = ses_dev->page10_len -
+						    (addl_desc_ptr - ses_dev->page10);
+						if (ses_process_descriptor(ecomp,
+						    addl_desc_ptr,
+						    max_desc_len))
+							addl_desc_ptr = NULL;
+					}
 					if (create)
 						enclosure_component_register(
 							ecomp);
@@ -603,9 +623,11 @@
 			     /* these elements are optional */
 			     type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT ||
 			     type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT ||
-			     type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS))
+			     type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS)) {
 				addl_desc_ptr += addl_desc_ptr[1] + 2;
-
+				if (addl_desc_ptr + 1 >= ses_dev->page10 + ses_dev->page10_len)
+					addl_desc_ptr = NULL;
+			}
 		}
 	}
 	kfree(buf);
@@ -704,6 +726,7 @@
 		    type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE)
 			components += type_ptr[1];
 	}
+
 	ses_dev->page1 = buf;
 	ses_dev->page1_len = len;
 	buf = NULL;
@@ -745,9 +768,11 @@
 		buf = NULL;
 	}
 page2_not_supported:
-	scomp = kcalloc(components, sizeof(struct ses_component), GFP_KERNEL);
-	if (!scomp)
-		goto err_free;
+	if (components > 0) {
+		scomp = kcalloc(components, sizeof(struct ses_component), GFP_KERNEL);
+		if (!scomp)
+			goto err_free;
+	}
 
 	edev = enclosure_register(cdev->parent, dev_name(&sdev->sdev_gendev),
 				  components, &ses_enclosure_callbacks);
@@ -827,7 +852,8 @@
 	kfree(ses_dev->page2);
 	kfree(ses_dev);
 
-	kfree(edev->component[0].scratch);
+	if (edev->components)
+		kfree(edev->component[0].scratch);
 
 	put_device(&edev->edev);
 	enclosure_unregister(edev);
diff --git a/kernel/drivers/scsi/snic/snic_disc.c b/kernel/drivers/scsi/snic/snic_disc.c
index e9ccfb9..e362453 100644
--- a/kernel/drivers/scsi/snic/snic_disc.c
+++ b/kernel/drivers/scsi/snic/snic_disc.c
@@ -318,7 +318,10 @@
 			      ret);
 
 		put_device(&snic->shost->shost_gendev);
-		kfree(tgt);
+		spin_lock_irqsave(snic->shost->host_lock, flags);
+		list_del(&tgt->list);
+		spin_unlock_irqrestore(snic->shost->host_lock, flags);
+		put_device(&tgt->dev);
 		tgt = NULL;
 
 		return tgt;
diff --git a/kernel/drivers/scsi/stex.c b/kernel/drivers/scsi/stex.c
index a3bce11..fa607f2 100644
--- a/kernel/drivers/scsi/stex.c
+++ b/kernel/drivers/scsi/stex.c
@@ -109,7 +109,9 @@
 	TASK_ATTRIBUTE_HEADOFQUEUE		= 0x1,
 	TASK_ATTRIBUTE_ORDERED			= 0x2,
 	TASK_ATTRIBUTE_ACA			= 0x4,
+};
 
+enum {
 	SS_STS_NORMAL				= 0x80000000,
 	SS_STS_DONE				= 0x40000000,
 	SS_STS_HANDSHAKE			= 0x20000000,
@@ -121,7 +123,9 @@
 	SS_I2H_REQUEST_RESET			= 0x2000,
 
 	SS_MU_OPERATIONAL			= 0x80000000,
+};
 
+enum {
 	STEX_CDB_LENGTH				= 16,
 	STATUS_VAR_LEN				= 128,
 
diff --git a/kernel/drivers/scsi/storvsc_drv.c b/kernel/drivers/scsi/storvsc_drv.c
index 3fa8a0c..37ad5f5 100644
--- a/kernel/drivers/scsi/storvsc_drv.c
+++ b/kernel/drivers/scsi/storvsc_drv.c
@@ -1014,6 +1014,22 @@
 			}
 
 			/*
+			 * Check for "Operating parameters have changed"
+			 * due to Hyper-V changing the VHD/VHDX BlockSize
+			 * when adding/removing a differencing disk. This
+			 * causes discard_granularity to change, so do a
+			 * rescan to pick up the new granularity. We don't
+			 * want scsi_report_sense() to output a message
+			 * that a sysadmin wouldn't know what to do with.
+			 */
+			if ((asc == 0x3f) && (ascq != 0x03) &&
+					(ascq != 0x0e)) {
+				process_err_fn = storvsc_device_scan;
+				set_host_byte(scmnd, DID_REQUEUE);
+				goto do_work;
+			}
+
+			/*
 			 * Otherwise, let upper layer deal with the
 			 * error when sense message is present
 			 */
@@ -1521,6 +1537,8 @@
 {
 	blk_queue_rq_timeout(sdevice->request_queue, (storvsc_timeout * HZ));
 
+	/* storvsc devices don't support MAINTENANCE_IN SCSI cmd */
+	sdevice->no_report_opcodes = 1;
 	sdevice->no_write_same = 1;
 
 	/*
@@ -1625,10 +1643,6 @@
  */
 static enum blk_eh_timer_return storvsc_eh_timed_out(struct scsi_cmnd *scmnd)
 {
-#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
-	if (scmnd->device->host->transportt == fc_transport_template)
-		return fc_eh_timed_out(scmnd);
-#endif
 	return BLK_EH_RESET_TIMER;
 }
 
@@ -1740,7 +1754,7 @@
 
 	length = scsi_bufflen(scmnd);
 	payload = (struct vmbus_packet_mpb_array *)&cmd_request->mpb;
-	payload_sz = sizeof(cmd_request->mpb);
+	payload_sz = 0;
 
 	if (sg_count) {
 		unsigned int hvpgoff = 0;
@@ -1748,10 +1762,10 @@
 		unsigned int hvpg_count = HVPFN_UP(offset_in_hvpg + length);
 		u64 hvpfn;
 
-		if (hvpg_count > MAX_PAGE_BUFFER_COUNT) {
+		payload_sz = (hvpg_count * sizeof(u64) +
+			      sizeof(struct vmbus_packet_mpb_array));
 
-			payload_sz = (hvpg_count * sizeof(u64) +
-				      sizeof(struct vmbus_packet_mpb_array));
+		if (hvpg_count > MAX_PAGE_BUFFER_COUNT) {
 			payload = kzalloc(payload_sz, GFP_ATOMIC);
 			if (!payload)
 				return SCSI_MLQUEUE_DEVICE_BUSY;
diff --git a/kernel/drivers/scsi/ufs/ufshcd.c b/kernel/drivers/scsi/ufs/ufshcd.c
index 1812edb..69ea2f9 100644
--- a/kernel/drivers/scsi/ufs/ufshcd.c
+++ b/kernel/drivers/scsi/ufs/ufshcd.c
@@ -731,16 +731,6 @@
 }
 
 /**
- * ufshcd_outstanding_req_clear - Clear a bit in outstanding request field
- * @hba: per adapter instance
- * @tag: position of the bit to be cleared
- */
-static inline void ufshcd_outstanding_req_clear(struct ufs_hba *hba, int tag)
-{
-	clear_bit(tag, &hba->outstanding_reqs);
-}
-
-/**
  * ufshcd_get_lists_status - Check UCRDY, UTRLRDY and UTMRLRDY
  * @reg: Register value of host controller status
  *
@@ -2882,37 +2872,76 @@
 static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
 		struct ufshcd_lrb *lrbp, int max_timeout)
 {
-	int err = 0;
-	unsigned long time_left;
+	unsigned long time_left = msecs_to_jiffies(max_timeout);
 	unsigned long flags;
+	bool pending;
+	int err;
 
+retry:
 	time_left = wait_for_completion_timeout(hba->dev_cmd.complete,
-			msecs_to_jiffies(max_timeout));
+					time_left);
 
 	/* Make sure descriptors are ready before ringing the doorbell */
 	wmb();
-	spin_lock_irqsave(hba->host->host_lock, flags);
-	hba->dev_cmd.complete = NULL;
 	if (likely(time_left)) {
+		/*
+		* The completion handler called complete() and the caller of
+		* this function still owns the @lrbp tag so the code below does
+		* not trigger any race conditions.
+		*/
+		hba->dev_cmd.complete = NULL;
 		err = ufshcd_get_tr_ocs(lrbp);
 		if (!err)
 			err = ufshcd_dev_cmd_completion(hba, lrbp);
-	}
-	spin_unlock_irqrestore(hba->host->host_lock, flags);
-
-	if (!time_left) {
+	} else {
 		err = -ETIMEDOUT;
 		dev_dbg(hba->dev, "%s: dev_cmd request timedout, tag %d\n",
 			__func__, lrbp->task_tag);
-		if (!ufshcd_clear_cmd(hba, lrbp->task_tag))
+		if (ufshcd_clear_cmd(hba, lrbp->task_tag) == 0) {
 			/* successfully cleared the command, retry if needed */
 			err = -EAGAIN;
-		/*
-		 * in case of an error, after clearing the doorbell,
-		 * we also need to clear the outstanding_request
-		 * field in hba
-		 */
-		ufshcd_outstanding_req_clear(hba, lrbp->task_tag);
+			/*
+			* Since clearing the command succeeded we also need to
+			* clear the task tag bit from the outstanding_reqs
+			* variable.
+			*/
+			spin_lock_irqsave(hba->host->host_lock, flags);
+			pending = test_bit(lrbp->task_tag,
+						&hba->outstanding_reqs);
+			if (pending) {
+					hba->dev_cmd.complete = NULL;
+					__clear_bit(lrbp->task_tag,
+							&hba->outstanding_reqs);
+			}
+			spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+			if (!pending) {
+				/*
+				* The completion handler ran while we tried to
+				* clear the command.
+				*/
+				time_left = 1;
+				goto retry;
+			}
+		} else {
+			dev_err(hba->dev, "%s: failed to clear tag %d\n",
+				__func__, lrbp->task_tag);
+			spin_lock_irqsave(hba->host->host_lock, flags);
+			pending = test_bit(lrbp->task_tag,
+					   &hba->outstanding_reqs);
+			if (pending)
+				hba->dev_cmd.complete = NULL;
+			spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+			if (!pending) {
+				/*
+				 * The completion handler ran while we tried to
+				 * clear the command.
+				 */
+				time_left = 1;
+				goto retry;
+			}
+		}
 	}
 
 	return err;
@@ -9485,5 +9514,6 @@
 MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");
 MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>");
 MODULE_DESCRIPTION("Generic UFS host controller driver Core");
+MODULE_SOFTDEP("pre: governor_simpleondemand");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(UFSHCD_DRIVER_VERSION);
diff --git a/kernel/drivers/soc/amlogic/meson-secure-pwrc.c b/kernel/drivers/soc/amlogic/meson-secure-pwrc.c
index 2eeea5e..2f3ca55 100644
--- a/kernel/drivers/soc/amlogic/meson-secure-pwrc.c
+++ b/kernel/drivers/soc/amlogic/meson-secure-pwrc.c
@@ -104,7 +104,7 @@
 	SEC_PD(ACODEC,	0),
 	SEC_PD(AUDIO,	0),
 	SEC_PD(OTP,	0),
-	SEC_PD(DMA,	0),
+	SEC_PD(DMA,	GENPD_FLAG_ALWAYS_ON | GENPD_FLAG_IRQ_SAFE),
 	SEC_PD(SD_EMMC,	0),
 	SEC_PD(RAMA,	0),
 	/* SRAMB is used as ATF runtime memory, and should be always on */
diff --git a/kernel/drivers/soc/fsl/qe/Kconfig b/kernel/drivers/soc/fsl/qe/Kconfig
index 357c580..7afa796 100644
--- a/kernel/drivers/soc/fsl/qe/Kconfig
+++ b/kernel/drivers/soc/fsl/qe/Kconfig
@@ -39,6 +39,7 @@
 
 config QE_USB
 	bool
+	depends on QUICC_ENGINE
 	default y if USB_FSL_QE
 	help
 	  QE USB Controller support
diff --git a/kernel/drivers/soc/qcom/Kconfig b/kernel/drivers/soc/qcom/Kconfig
index 499718e..6a97e8a 100644
--- a/kernel/drivers/soc/qcom/Kconfig
+++ b/kernel/drivers/soc/qcom/Kconfig
@@ -63,6 +63,7 @@
 config QCOM_LLCC
 	tristate "Qualcomm Technologies, Inc. LLCC driver"
 	depends on ARCH_QCOM || COMPILE_TEST
+	select REGMAP_MMIO
 	help
 	  Qualcomm Technologies, Inc. platform specific
 	  Last Level Cache Controller(LLCC) driver for platforms such as,
diff --git a/kernel/drivers/soc/qcom/apr.c b/kernel/drivers/soc/qcom/apr.c
index f736d20..660ee3a 100644
--- a/kernel/drivers/soc/qcom/apr.c
+++ b/kernel/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 @@
  */
 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 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 @@
 	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 @@
 	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 @@
 	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 @@
 
 	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 @@
 {
 	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 @@
 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;
 
-	adev->svc_id = id->svc_id;
-	adev->domain_id = id->domain_id;
-	adev->version = id->svc_version;
+	svc->id = svc_id;
+	svc->pr = apr;
+	svc->priv = adev;
+	svc->dev = dev;
+	spin_lock_init(&svc->lock);
+
+	adev->domain_id = domain_id;
+
 	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,12 +312,20 @@
 	adev->dev.driver = NULL;
 
 	spin_lock(&apr->svcs_lock);
-	idr_alloc(&apr->svcs_idr, adev, id->svc_id,
-		  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);
+	/* Protection domain is optional, it does not exist on older platforms */
+	ret = of_property_read_string_index(np, "qcom,protection-domain",
+					    1, &adev->service_path);
+	if (ret < 0 && ret != -EINVAL) {
+		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));
 
@@ -302,13 +335,14 @@
 		put_device(&adev->dev);
 	}
 
+out:
 	return ret;
 }
 
 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 +374,14 @@
 
 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 +411,13 @@
 				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 +437,7 @@
 
 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 +452,20 @@
 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 +508,7 @@
 
 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 +545,20 @@
 }
 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 +568,7 @@
 
 	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 +578,7 @@
 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/kernel/drivers/soc/qcom/cpr.c b/kernel/drivers/soc/qcom/cpr.c
index 6298561..fac0414 100644
--- a/kernel/drivers/soc/qcom/cpr.c
+++ b/kernel/drivers/soc/qcom/cpr.c
@@ -1743,12 +1743,16 @@
 
 	ret = of_genpd_add_provider_simple(dev->of_node, &drv->pd);
 	if (ret)
-		return ret;
+		goto err_remove_genpd;
 
 	platform_set_drvdata(pdev, drv);
 	cpr_debugfs_init(drv);
 
 	return 0;
+
+err_remove_genpd:
+	pm_genpd_remove(&drv->pd);
+	return ret;
 }
 
 static int cpr_remove(struct platform_device *pdev)
diff --git a/kernel/drivers/soc/qcom/llcc-qcom.c b/kernel/drivers/soc/qcom/llcc-qcom.c
index 2e06f48..c60fe98 100644
--- a/kernel/drivers/soc/qcom/llcc-qcom.c
+++ b/kernel/drivers/soc/qcom/llcc-qcom.c
@@ -476,7 +476,7 @@
 	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,
diff --git a/kernel/drivers/soc/qcom/ocmem.c b/kernel/drivers/soc/qcom/ocmem.c
index 1dfdd0b..8b80c8e 100644
--- a/kernel/drivers/soc/qcom/ocmem.c
+++ b/kernel/drivers/soc/qcom/ocmem.c
@@ -76,8 +76,12 @@
 #define OCMEM_REG_GFX_MPU_START			0x00001004
 #define OCMEM_REG_GFX_MPU_END			0x00001008
 
-#define OCMEM_HW_PROFILE_NUM_PORTS(val)		FIELD_PREP(0x0000000f, (val))
-#define OCMEM_HW_PROFILE_NUM_MACROS(val)	FIELD_PREP(0x00003f00, (val))
+#define OCMEM_HW_VERSION_MAJOR(val)		FIELD_GET(GENMASK(31, 28), val)
+#define OCMEM_HW_VERSION_MINOR(val)		FIELD_GET(GENMASK(27, 16), val)
+#define OCMEM_HW_VERSION_STEP(val)		FIELD_GET(GENMASK(15, 0), val)
+
+#define OCMEM_HW_PROFILE_NUM_PORTS(val)		FIELD_GET(0x0000000f, (val))
+#define OCMEM_HW_PROFILE_NUM_MACROS(val)	FIELD_GET(0x00003f00, (val))
 
 #define OCMEM_HW_PROFILE_LAST_REGN_HALFSIZE	0x00010000
 #define OCMEM_HW_PROFILE_INTERLEAVING		0x00020000
@@ -357,6 +361,12 @@
 		}
 	}
 
+	reg = ocmem_read(ocmem, OCMEM_REG_HW_VERSION);
+	dev_dbg(dev, "OCMEM hardware version: %lu.%lu.%lu\n",
+		OCMEM_HW_VERSION_MAJOR(reg),
+		OCMEM_HW_VERSION_MINOR(reg),
+		OCMEM_HW_VERSION_STEP(reg));
+
 	reg = ocmem_read(ocmem, OCMEM_REG_HW_PROFILE);
 	ocmem->num_ports = OCMEM_HW_PROFILE_NUM_PORTS(reg);
 	ocmem->num_macros = OCMEM_HW_PROFILE_NUM_MACROS(reg);
diff --git a/kernel/drivers/soc/qcom/qmi_encdec.c b/kernel/drivers/soc/qcom/qmi_encdec.c
index 3aaab71..dbc8b4c 100644
--- a/kernel/drivers/soc/qcom/qmi_encdec.c
+++ b/kernel/drivers/soc/qcom/qmi_encdec.c
@@ -534,8 +534,8 @@
 		decoded_bytes += rc;
 	}
 
-	if (string_len > temp_ei->elem_len) {
-		pr_err("%s: String len %d > Max Len %d\n",
+	if (string_len >= temp_ei->elem_len) {
+		pr_err("%s: String len %d >= Max Len %d\n",
 		       __func__, string_len, temp_ei->elem_len);
 		return -ETOOSMALL;
 	} else if (string_len > tlv_len) {
diff --git a/kernel/drivers/soc/rockchip/Kconfig b/kernel/drivers/soc/rockchip/Kconfig
index e618fec..a9d09b3 100644
--- a/kernel/drivers/soc/rockchip/Kconfig
+++ b/kernel/drivers/soc/rockchip/Kconfig
@@ -18,6 +18,14 @@
 
 	  If unsure, say Y.
 
+config ROCKCHIP_DISABLE_UNUSED
+	tristate "Rockchip Disable Unused"
+	default m if GKI_HACKS_TO_FIX
+	help
+	  Disable unused clk and power down after module init.
+
+	  If unsure, say "N".
+
 #
 # Rockchip Soc drivers
 #
@@ -43,6 +51,12 @@
 	  Serial can read from /proc/cpuinfo.
 
 	  If unsure, say N.
+
+config ROCKCHIP_CSU
+	tristate "Rockchip Clock Subunit Driver"
+	depends on ARCH_ROCKCHIP
+	help
+	  This adds the clock subunit driver for Rockchip SoCs.
 
 config ROCKCHIP_GRF
 	tristate "Rockchip General Register Files support"
@@ -158,7 +172,6 @@
 
 config ROCKCHIP_SUSPEND_MODE
 	tristate "Rockchip suspend mode config"
-	depends on ROCKCHIP_SIP
 	help
 	  Say Y here if you want to set the suspend mode to the ATF.
 
diff --git a/kernel/drivers/soc/rockchip/Makefile b/kernel/drivers/soc/rockchip/Makefile
index c4b5c8a..7a1ae8d 100644
--- a/kernel/drivers/soc/rockchip/Makefile
+++ b/kernel/drivers/soc/rockchip/Makefile
@@ -4,6 +4,8 @@
 #
 obj-$(CONFIG_ROCKCHIP_AMP) += rockchip_amp.o
 obj-$(CONFIG_ROCKCHIP_CPUINFO) += rockchip-cpuinfo.o
+obj-$(CONFIG_ROCKCHIP_CSU) += rockchip_csu.o
+obj-$(CONFIG_ROCKCHIP_DISABLE_UNUSED) += rockchip_disable_unused.o
 obj-$(CONFIG_ROCKCHIP_GRF) += grf.o
 obj-$(CONFIG_ROCKCHIP_HW_DECOMPRESS) += rockchip_decompress.o
 obj-$(CONFIG_ROCKCHIP_HW_DECOMPRESS_USER) += rockchip_decompress_user.o
diff --git a/kernel/drivers/soc/rockchip/fiq_debugger/fiq_debugger.c b/kernel/drivers/soc/rockchip/fiq_debugger/fiq_debugger.c
index 1f8e88e..4647144 100644
--- a/kernel/drivers/soc/rockchip/fiq_debugger/fiq_debugger.c
+++ b/kernel/drivers/soc/rockchip/fiq_debugger/fiq_debugger.c
@@ -50,6 +50,7 @@
 #endif
 
 #include <linux/uaccess.h>
+#include <linux/cpuhotplug.h>
 
 #include "fiq_debugger.h"
 #include "fiq_debugger_priv.h"
@@ -148,10 +149,7 @@
 static bool initial_console_enable;
 #endif
 
-#ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
-static struct fiq_debugger_state *state_tf;
-#endif
-
+static struct fiq_debugger_state *g_state;
 static bool fiq_kgdb_enable;
 static bool fiq_debugger_disable;
 
@@ -1077,7 +1075,7 @@
 #ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
 void fiq_debugger_fiq(void *regs, u32 cpu)
 {
-	struct fiq_debugger_state *state = state_tf;
+	struct fiq_debugger_state *state = g_state;
 	bool need_irq;
 
 	if (!state)
@@ -1444,6 +1442,18 @@
 	return 0;
 }
 
+static int fiq_debugger_cpu_offine_migrate_irq(unsigned int cpu)
+{
+	if (g_state && cpu == g_state->current_cpu) {
+		unsigned int new_cpu = cpumask_any_but(cpu_online_mask, cpu);
+
+		if (new_cpu < nr_cpu_ids)
+			g_state->current_cpu = new_cpu;
+	}
+
+	return 0;
+}
+
 static int fiq_debugger_probe(struct platform_device *pdev)
 {
 	int ret;
@@ -1451,6 +1461,7 @@
 	struct fiq_debugger_state *state;
 	int fiq;
 	int uart_irq;
+	enum cpuhp_state cs = -1;
 
 	if (pdev->id >= MAX_FIQ_DEBUGGER_PORTS)
 		return -EINVAL;
@@ -1556,7 +1567,7 @@
 			pr_err("%s: could not install nmi irq handler\n", __func__);
 			irq_clear_status_flags(state->uart_irq, IRQ_NOAUTOEN);
 			ret = request_irq(state->uart_irq, fiq_debugger_uart_irq,
-					  IRQF_NO_SUSPEND, "debug", state);
+					  IRQF_NO_SUSPEND | IRQF_NOBALANCING, "debug", state);
 		} else {
 			enable_nmi(state->uart_irq);
 		}
@@ -1570,6 +1581,15 @@
 		 * can.
 		 */
 		enable_irq_wake(state->uart_irq);
+
+		ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
+						"soc/fiq_debugger",
+						NULL,
+						fiq_debugger_cpu_offine_migrate_irq);
+		if (ret < 0)
+			pr_err("%s: could not setup cpu offine handler\n", __func__);
+		else
+			cs = ret;
 	}
 
 	if (state->signal_irq >= 0) {
@@ -1600,10 +1620,6 @@
 	if (state->no_sleep)
 		fiq_debugger_handle_wakeup(state);
 
-#ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
-	state_tf = state;
-#endif
-
 	if (pdata->uart_init) {
 		ret = pdata->uart_init(pdev);
 		if (ret)
@@ -1630,7 +1646,7 @@
 
 	/* switch to cpu0 default */
 	fiq_debugger_switch_cpu(state, 0);
-
+	g_state = state;
 	return 0;
 
 err_register_irq:
@@ -1641,6 +1657,8 @@
 		clk_disable(state->clk);
 	if (state->clk)
 		clk_put(state->clk);
+	if (cs >= 0)
+		cpuhp_remove_state_nocalls(cs);
 	wakeup_source_remove(&state->debugger_wake_src);
 	__pm_relax(&state->debugger_wake_src);
 	platform_set_drvdata(pdev, NULL);
diff --git a/kernel/drivers/soc/rockchip/fiq_debugger/rk_fiq_debugger.c b/kernel/drivers/soc/rockchip/fiq_debugger/rk_fiq_debugger.c
index 1fb72a5..6dafdde 100644
--- a/kernel/drivers/soc/rockchip/fiq_debugger/rk_fiq_debugger.c
+++ b/kernel/drivers/soc/rockchip/fiq_debugger/rk_fiq_debugger.c
@@ -763,6 +763,11 @@
 	if ((sip_fiq_debugger_is_enabled()) &&
 	    (sip_fiq_debugger_get_target_cpu() == cpu)) {
 		target_cpu = cpumask_any_but(cpu_online_mask, cpu);
+		if (target_cpu >= nr_cpu_ids) {
+			pr_err("%s: migrate fiq fail!\n", __func__);
+			return -EBUSY;
+		}
+
 		sip_fiq_debugger_switch_cpu(target_cpu);
 	}
 
diff --git a/kernel/drivers/soc/rockchip/minidump/minidump_log.c b/kernel/drivers/soc/rockchip/minidump/minidump_log.c
index 4b5ea9e..18b1934 100644
--- a/kernel/drivers/soc/rockchip/minidump/minidump_log.c
+++ b/kernel/drivers/soc/rockchip/minidump/minidump_log.c
@@ -36,7 +36,6 @@
 #ifdef CONFIG_ROCKCHIP_MINIDUMP_PANIC_DUMP
 #include <linux/bits.h>
 #include <linux/sched/prio.h>
-#include <asm/memory.h>
 
 #include "../../../kernel/sched/sched.h"
 
@@ -49,6 +48,7 @@
 #include <linux/module.h>
 #include <linux/cma.h>
 #include <linux/dma-map-ops.h>
+#include <asm-generic/irq_regs.h>
 #ifdef CONFIG_ROCKCHIP_MINIDUMP_PANIC_CPU_CONTEXT
 #include <trace/hooks/debug.h>
 #endif
@@ -149,6 +149,7 @@
 
 static struct md_region note_md_entry;
 static DEFINE_PER_CPU_SHARED_ALIGNED(struct elf_prstatus *, cpu_epr);
+static struct elf_prstatus *epr_hang_task[8];
 
 static int register_stack_entry(struct md_region *ksp_entry, u64 sp, u64 size)
 {
@@ -594,14 +595,15 @@
 
 static void register_note_section(void)
 {
-	int ret = 0, i = 0;
+	int ret = 0, i = 0, j = 0;
 	size_t data_len;
 	Elf_Word *buf;
 	void *buffer_start;
 	struct elf_prstatus *epr;
+	struct user_pt_regs *regs;
 	struct md_region *mdr = &note_md_entry;
 
-	buffer_start = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	buffer_start = kzalloc(PAGE_SIZE * 2, GFP_KERNEL);
 	if (!buffer_start)
 		return;
 
@@ -611,11 +613,26 @@
 
 	buf = (Elf_Word *)mdr->virt_addr;
 	data_len = sizeof(struct elf_prstatus);
+
 	for_each_possible_cpu(i) {
 		buf = append_elf_note(buf, "CORE", NT_PRSTATUS, data_len);
 		epr = (struct elf_prstatus *)buf;
 		epr->pr_pid = i;
 		per_cpu(cpu_epr, i) = epr;
+		regs = (struct user_pt_regs *)&epr->pr_reg;
+		regs->pc = (u64)register_note_section; /* just for fun */
+
+		buf += DIV_ROUND_UP(data_len, sizeof(Elf_Word));
+	}
+
+	j = i;
+	for (; i < 16; i++) {
+		buf = append_elf_note(buf, "TASK", NT_PRSTATUS, data_len);
+		epr = (struct elf_prstatus *)buf;
+		epr->pr_pid = i;
+		epr_hang_task[i - j] = epr;
+		regs = (struct user_pt_regs *)&epr->pr_reg;
+		regs->pc = (u64)register_note_section; /* just for fun */
 		buf += DIV_ROUND_UP(data_len, sizeof(Elf_Word));
 	}
 
@@ -626,17 +643,165 @@
 		pr_err("Failed to add %s entry in Minidump\n", mdr->name);
 }
 
+static int md_register_minidump_entry(char *name, u64 virt_addr,
+				      u64 phys_addr, u64 size)
+{
+	struct md_region md_entry;
+	int ret;
+
+	strscpy(md_entry.name, name, sizeof(md_entry.name));
+	md_entry.virt_addr = virt_addr;
+	md_entry.phys_addr = phys_addr;
+	md_entry.size = size;
+	ret = rk_minidump_add_region(&md_entry);
+	if (ret < 0)
+		pr_err("Failed to add %s entry in Minidump\n", name);
+	return ret;
+}
+
+static struct page *md_vmalloc_to_page(const void *vmalloc_addr)
+{
+	unsigned long addr = (unsigned long) vmalloc_addr;
+	struct page *page = NULL;
+	pgd_t *pgd = pgd_offset_k(addr);
+	p4d_t *p4d;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *ptep, pte;
+
+	if (pgd_none(*pgd))
+		return NULL;
+	p4d = p4d_offset(pgd, addr);
+	if (p4d_none(*p4d))
+		return NULL;
+	pud = pud_offset(p4d, addr);
+
+	if (pud_none(*pud) || pud_bad(*pud))
+		return NULL;
+	pmd = pmd_offset(pud, addr);
+	if (pmd_none(*pmd) || pmd_bad(*pmd))
+		return NULL;
+
+	ptep = pte_offset_map(pmd, addr);
+	pte = *ptep;
+	if (pte_present(pte))
+		page = pte_page(pte);
+	pte_unmap(ptep);
+	return page;
+}
+
+static bool md_is_kernel_address(u64 addr)
+{
+	u32 data;
+	u64 phys_addr = 0;
+	struct page *page;
+
+	if (!is_ttbr1_addr(addr))
+		return false;
+
+	if (addr >= (u64)_text && addr < (u64)_end)
+		return false;
+
+	if (__is_lm_address(addr)) {
+		phys_addr = virt_to_phys((void *)addr);
+	} else if (is_vmalloc_or_module_addr((const void *)addr)) {
+		page = md_vmalloc_to_page((const void *) addr);
+		if (page)
+			phys_addr = page_to_phys(page);
+		else
+			return false;
+	} else {
+		return false;
+	}
+
+	if (!md_is_ddr_address(phys_addr))
+		return false;
+
+	if (aarch64_insn_read((void *)addr, &data))
+		return false;
+	else
+		return true;
+}
+
+static int md_save_page(u64 addr, bool flush)
+{
+	u64 phys_addr, virt_addr;
+	struct page *page;
+	char buf[32];
+	int ret;
+
+	if (md_is_kernel_address(addr)) {
+		if (!md_is_in_the_region(addr)) {
+			virt_addr = addr & PAGE_MASK;
+			sprintf(buf, "%x", (u32)(virt_addr >> 12));
+
+			if (__is_lm_address(virt_addr)) {
+				phys_addr = virt_to_phys((void *)virt_addr);
+			} else if (is_vmalloc_or_module_addr((const void *)virt_addr)) {
+				page = md_vmalloc_to_page((const void *) virt_addr);
+				phys_addr = page_to_phys(page);
+			} else {
+				return -1;
+			}
+
+			ret = md_register_minidump_entry(buf, (uintptr_t)virt_addr,
+							 phys_addr, PAGE_SIZE);
+			if (ret > 0 && flush)
+				rk_md_flush_dcache_area((void *)virt_addr, PAGE_SIZE);
+		} else {
+			if (flush)
+				rk_md_flush_dcache_area((void *)(addr & PAGE_MASK), PAGE_SIZE);
+		}
+		return 0;
+	}
+	return -1;
+}
+
+static void md_save_pages(u64 addr, bool flush)
+{
+	u64 *p, *end;
+
+	if (!md_save_page(addr, flush)) {
+		addr &= ~0x7;
+		p = (u64 *)addr;
+		end = (u64 *)((addr & ~(PAGE_SIZE - 1)) + PAGE_SIZE);
+		while (p < end) {
+			if (!md_is_kernel_address((u64)p))
+				break;
+			md_save_page(*p++, flush);
+		}
+	}
+}
+
 void rk_minidump_update_cpu_regs(struct pt_regs *regs)
 {
 	int cpu = raw_smp_processor_id();
+	struct user_pt_regs *old_regs;
+	int i = 0;
+
 	struct elf_prstatus *epr = per_cpu(cpu_epr, cpu);
 
 	if (!epr)
 		return;
 
+	if (system_state == SYSTEM_RESTART)
+		return;
+
+	old_regs = (struct user_pt_regs *)&epr->pr_reg;
+	/* if epr has been saved, don't save it again in panic notifier*/
+	if (old_regs->sp != 0)
+		return;
+
 	memcpy((void *)&epr->pr_reg, (void *)regs, sizeof(elf_gregset_t));
 	rk_md_flush_dcache_area((void *)&epr->pr_reg, sizeof(elf_gregset_t));
 	rk_md_flush_dcache_area((void *)(regs->sp & ~(PAGE_SIZE - 1)), PAGE_SIZE);
+
+	/* dump sp */
+	md_save_pages(regs->sp, true);
+
+	/*dump x0-x28, x29 is lr, x30 is fp*/
+	for (i = 0; i < 29; i++)
+		md_save_pages(regs->regs[i], true);
 }
 EXPORT_SYMBOL(rk_minidump_update_cpu_regs);
 
@@ -1028,7 +1193,10 @@
 
 	seq_buf_printf(md_cntxt_seq_buf, "PANIC CPU : %d\n",
 				   raw_smp_processor_id());
-	md_reg_context_data(&regs);
+	if (in_interrupt())
+		md_reg_context_data(get_irq_regs());
+	else
+		md_reg_context_data(&regs);
 }
 
 static int md_die_context_notify(struct notifier_block *self,
@@ -1055,6 +1223,43 @@
 	.priority = INT_MAX - 2, /* < rk watchdog die notifier */
 };
 #endif
+
+static int rk_minidump_collect_hang_task(void)
+{
+	struct task_struct *g, *p;
+	struct elf_prstatus *epr;
+	struct user_pt_regs *regs;
+	int idx = 0, i = 0;
+
+	for_each_process_thread(g, p) {
+		touch_nmi_watchdog();
+		touch_all_softlockup_watchdogs();
+		if (p->state == TASK_UNINTERRUPTIBLE && p->state != TASK_IDLE) {
+			epr = epr_hang_task[idx++];
+			regs = (struct user_pt_regs *)&epr->pr_reg;
+			regs->regs[19] = (unsigned long)(p->thread.cpu_context.x19);
+			regs->regs[20] = (unsigned long)(p->thread.cpu_context.x20);
+			regs->regs[21] = (unsigned long)(p->thread.cpu_context.x21);
+			regs->regs[22] = (unsigned long)(p->thread.cpu_context.x22);
+			regs->regs[23] = (unsigned long)(p->thread.cpu_context.x23);
+			regs->regs[24] = (unsigned long)(p->thread.cpu_context.x24);
+			regs->regs[25] = (unsigned long)(p->thread.cpu_context.x25);
+			regs->regs[26] = (unsigned long)(p->thread.cpu_context.x26);
+			regs->regs[27] = (unsigned long)(p->thread.cpu_context.x27);
+			regs->regs[28] = (unsigned long)(p->thread.cpu_context.x28);
+			regs->regs[29] = (unsigned long)(p->thread.cpu_context.fp);
+			regs->sp = (unsigned long)(p->thread.cpu_context.sp);
+			regs->pc = (unsigned long)p->thread.cpu_context.pc;
+			md_save_pages(regs->sp, true);
+			for (i = 19; i < 29; i++)
+				md_save_pages(regs->regs[i], true);
+			rk_md_flush_dcache_area((void *)epr, sizeof(struct elf_prstatus));
+		}
+		if (idx >= 8)
+			return 0;
+	}
+	return 0;
+}
 
 static int md_panic_handler(struct notifier_block *this,
 			    unsigned long event, void *ptr)
@@ -1093,6 +1298,8 @@
 	if (md_dma_buf_procs_addr)
 		md_dma_buf_procs(md_dma_buf_procs_addr, md_dma_buf_procs_size);
 
+	rk_minidump_collect_hang_task();
+
 	rk_minidump_flush_elfheader();
 	md_in_oops_handler = false;
 	return NOTIFY_DONE;
@@ -1102,22 +1309,6 @@
 	.notifier_call = md_panic_handler,
 	.priority = INT_MAX - 2,
 };
-
-static int md_register_minidump_entry(char *name, u64 virt_addr,
-				      u64 phys_addr, u64 size)
-{
-	struct md_region md_entry;
-	int ret;
-
-	strscpy(md_entry.name, name, sizeof(md_entry.name));
-	md_entry.virt_addr = virt_addr;
-	md_entry.phys_addr = phys_addr;
-	md_entry.size = size;
-	ret = rk_minidump_add_region(&md_entry);
-	if (ret < 0)
-		pr_err("Failed to add %s entry in Minidump\n", name);
-	return ret;
-}
 
 static int md_register_panic_entries(int num_pages, char *name,
 				      struct seq_buf **global_buf)
@@ -1249,6 +1440,43 @@
 }
 #endif /* CONFIG_ROCKCHIP_MINIDUMP_PANIC_DUMP */
 
+#ifdef CONFIG_HARDLOCKUP_DETECTOR
+int rk_minidump_hardlock_notify(struct notifier_block *nb, unsigned long event,
+				void *p)
+{
+	struct elf_prstatus *epr;
+	struct user_pt_regs *regs;
+	unsigned long hardlock_cpu = event;
+#ifdef CONFIG_ROCKCHIP_DYN_MINIDUMP_STACK
+	int i = 0;
+	struct md_stack_cpu_data *md_stack_cpu_d;
+	struct md_region *mdr;
+#endif
+
+	if (hardlock_cpu >= num_possible_cpus())
+		return NOTIFY_DONE;
+
+#ifdef CONFIG_ROCKCHIP_DYN_MINIDUMP_STACK
+	md_stack_cpu_d = &per_cpu(md_stack_data, hardlock_cpu);
+	for (i = 0; i < STACK_NUM_PAGES; i++) {
+		mdr = &md_stack_cpu_d->stack_mdr[i];
+		if (md_is_kernel_address(mdr->virt_addr))
+			rk_md_flush_dcache_area((void *)mdr->virt_addr, mdr->size);
+	}
+#endif
+	epr = per_cpu(cpu_epr, hardlock_cpu);
+	if (!epr)
+		return NOTIFY_DONE;
+	regs = (struct user_pt_regs *)&epr->pr_reg;
+	regs->pc = (u64)p;
+#ifdef CONFIG_ROCKCHIP_DYN_MINIDUMP_STACK
+	regs->sp = mdr->virt_addr + mdr->size;
+#endif
+	rk_md_flush_dcache_area((void *)epr, sizeof(struct elf_prstatus));
+	return NOTIFY_OK;
+}
+#endif
+
 int rk_minidump_log_init(void)
 {
 	is_vmap_stack = IS_ENABLED(CONFIG_VMAP_STACK);
diff --git a/kernel/drivers/soc/rockchip/minidump/minidump_memory.c b/kernel/drivers/soc/rockchip/minidump/minidump_memory.c
index 95fc78a..d7f93e2 100644
--- a/kernel/drivers/soc/rockchip/minidump/minidump_memory.c
+++ b/kernel/drivers/soc/rockchip/minidump/minidump_memory.c
@@ -933,7 +933,7 @@
 {
 	char buf[100];
 
-	snprintf(buf, sizeof(buf), "%llu MB\n", md_slabowner_dump_size/SZ_1M);
+	snprintf(buf, sizeof(buf), "%lu MB\n", md_slabowner_dump_size/SZ_1M);
 	return simple_read_from_buffer(ubuf, count, offset, buf, strlen(buf));
 }
 
diff --git a/kernel/drivers/soc/rockchip/minidump/minidump_private.h b/kernel/drivers/soc/rockchip/minidump/minidump_private.h
index 12cf812..f2dadce 100644
--- a/kernel/drivers/soc/rockchip/minidump/minidump_private.h
+++ b/kernel/drivers/soc/rockchip/minidump/minidump_private.h
@@ -86,4 +86,5 @@
 extern void rk_minidump_flush_elfheader(void);
 extern void dump_stack_minidump(u64 sp);
 extern struct md_region *md_get_region(char *name);
+int md_is_in_the_region(u64 addr);
 #endif
diff --git a/kernel/drivers/soc/rockchip/minidump/rk_minidump.c b/kernel/drivers/soc/rockchip/minidump/rk_minidump.c
index 908bb5c..d742b7e 100644
--- a/kernel/drivers/soc/rockchip/minidump/rk_minidump.c
+++ b/kernel/drivers/soc/rockchip/minidump/rk_minidump.c
@@ -72,6 +72,8 @@
 static void __iomem *md_elf_mem;
 static resource_size_t md_elf_size;
 static struct proc_dir_entry *proc_rk_minidump;
+static bool md_is_ddr_address_default(u64 phys_addr);
+bool (*md_is_ddr_address)(u64 virt_addr) = md_is_ddr_address_default;
 
 /* Number of pending entries to be added in ToC regions */
 static unsigned int pendings;
@@ -168,6 +170,8 @@
 	shdr->sh_flags = SHF_WRITE;
 	shdr->sh_offset = minidump_elfheader.elf_offset;
 	shdr->sh_entsize = 0;
+	shdr->sh_addralign = shdr->sh_addr;	/* backup */
+	shdr->sh_entsize = entry->phys_addr;	/* backup */
 
 	if (strstr((const char *)mdr->name, "note"))
 		phdr->p_type = PT_NOTE;
@@ -178,6 +182,7 @@
 	phdr->p_paddr = entry->phys_addr;
 	phdr->p_filesz = phdr->p_memsz =  mdr->region_size;
 	phdr->p_flags = PF_R | PF_W;
+	phdr->p_align = phdr->p_paddr;		/* backup */
 	minidump_elfheader.elf_offset += shdr->sh_size;
 	mdr->md_valid = MD_REGION_VALID;
 	minidump_table.md_ss_toc->ss_region_count++;
@@ -210,6 +215,26 @@
 	}
 
 	return 0;
+}
+
+int md_is_in_the_region(u64 addr)
+{
+	struct md_region *mdr;
+	u32 entries;
+	int i;
+
+	entries = minidump_table.num_regions;
+
+	for (i = 0; i < entries; i++) {
+		mdr = &minidump_table.entry[i];
+		if (mdr->virt_addr <= addr && addr < (mdr->virt_addr + mdr->size))
+			break;
+	}
+
+	if (i < entries)
+		return 1;
+	else
+		return 0;
 }
 
 int rk_minidump_update_region(int regno, const struct md_region *entry)
@@ -254,8 +279,11 @@
 	phdr = elf_program(hdr, regno + 1);
 
 	shdr->sh_addr = (elf_addr_t)entry->virt_addr;
+	shdr->sh_addralign = shdr->sh_addr;	/* backup */
+	shdr->sh_entsize = entry->phys_addr;	/* backup */
 	phdr->p_vaddr = entry->virt_addr;
 	phdr->p_paddr = entry->phys_addr;
+	phdr->p_align = phdr->p_paddr;		/* backup */
 
 err_unlock:
 	read_unlock_irqrestore(&mdt_remove_lock, flags);
@@ -595,6 +623,22 @@
 	.proc_read	= rk_minidump_read_elf,
 };
 
+static bool md_is_ddr_address_rk3588(u64 phys_addr)
+{
+	/* peripheral address space */
+	if (phys_addr >= 0xf0000000 && phys_addr < 0x100000000)
+		return false;
+	/* DDR is up to 32GB */
+	if (phys_addr > 0x800000000)
+		return false;
+	return true;
+}
+
+static bool md_is_ddr_address_default(u64 phys_addr)
+{
+	return true;
+}
+
 static int rk_minidump_driver_probe(struct platform_device *pdev)
 {
 	unsigned int i;
@@ -655,11 +699,17 @@
 		phdr = (Elf64_Phdr *)(md_elf_mem + (ulong)ehdr->e_phoff);
 		phdr += ehdr->e_phnum - 1;
 		md_elf_size = phdr->p_memsz + phdr->p_offset;
-
-		pr_info("Create /proc/rk_md/minidump...\n");
+		if (md_elf_size > r_size)
+			md_elf_size = r_size;
+		pr_info("Create /proc/rk_md/minidump, size:0x%llx...\n", md_elf_size);
 		proc_rk_minidump = proc_create("minidump", 0400, base_dir, &rk_minidump_proc_ops);
+	} else {
+		pr_info("Create /proc/rk_md/minidump fail...\n");
 	}
 
+	if (of_machine_is_compatible("rockchip,rk3588"))
+		md_is_ddr_address = md_is_ddr_address_rk3588;
+
 	/* Check global minidump support initialization */
 	if (!md_global_toc->md_toc_init) {
 		pr_err("System Minidump TOC not initialized\n");
diff --git a/kernel/drivers/soc/rockchip/pm_domains.c b/kernel/drivers/soc/rockchip/pm_domains.c
index 04daba2..6e98b2a 100644
--- a/kernel/drivers/soc/rockchip/pm_domains.c
+++ b/kernel/drivers/soc/rockchip/pm_domains.c
@@ -93,19 +93,26 @@
 #define QOS_SATURATION		0x14
 #define QOS_EXTCONTROL		0x18
 
+#define SHAPING_NBPKTMAX0	0x0
+
 struct rockchip_pm_domain {
 	struct generic_pm_domain genpd;
 	const struct rockchip_domain_info *info;
 	struct rockchip_pmu *pmu;
 	int num_qos;
+	int num_shaping;
 	struct regmap **qos_regmap;
+	struct regmap **shaping_regmap;
 	u32 *qos_save_regs[MAX_QOS_REGS_NUM];
+	u32 *shaping_save_regs;
 	bool *qos_is_need_init[MAX_QOS_REGS_NUM];
+	bool *shaping_is_need_init;
 	int num_clks;
 	struct clk_bulk_data *clks;
 	bool is_ignore_pwr;
 	bool is_qos_saved;
 	bool is_qos_need_init;
+	bool is_shaping_need_init;
 	struct regulator *supply;
 };
 
@@ -124,35 +131,6 @@
 module_param_named(always_on, pm_domain_always_on, bool, 0644);
 MODULE_PARM_DESC(always_on,
 		 "Always keep pm domains power on except for system suspend.");
-
-#ifdef MODULE
-static bool keepon_startup = true;
-static void rockchip_pd_keepon_do_release(void);
-
-static int pd_param_set_keepon_startup(const char *val,
-				       const struct kernel_param *kp)
-{
-	int ret;
-
-	ret = param_set_bool(val, kp);
-	if (ret)
-		return ret;
-
-	if (!keepon_startup)
-		rockchip_pd_keepon_do_release();
-
-	return 0;
-}
-
-static const struct kernel_param_ops pd_keepon_startup_ops = {
-	.set	= pd_param_set_keepon_startup,
-	.get	= param_get_bool,
-};
-
-module_param_cb(keepon_startup, &pd_keepon_startup_ops, &keepon_startup, 0644);
-MODULE_PARM_DESC(keepon_startup,
-		 "Keep pm domains power on during system startup.");
-#endif
 
 static void rockchip_pmu_lock(struct rockchip_pm_domain *pd)
 {
@@ -459,6 +437,45 @@
 }
 EXPORT_SYMBOL(rockchip_pmu_idle_request);
 
+static int rockchip_pmu_save_shaping(struct rockchip_pm_domain *pd)
+{
+	int i;
+
+	for (i = 0; i < pd->num_shaping; i++)
+		regmap_read(pd->shaping_regmap[i], SHAPING_NBPKTMAX0,
+			    &pd->shaping_save_regs[i]);
+
+	return 0;
+}
+
+static int rockchip_pmu_restore_shaping(struct rockchip_pm_domain *pd)
+{
+	int i;
+
+	for (i = 0; i < pd->num_shaping; i++)
+		regmap_write(pd->shaping_regmap[i], SHAPING_NBPKTMAX0,
+			     pd->shaping_save_regs[i]);
+
+	return 0;
+}
+
+static void rockchip_pmu_init_shaping(struct rockchip_pm_domain *pd)
+{
+	int i;
+
+	if (!pd->is_shaping_need_init)
+		return;
+
+	for (i = 0; i < pd->num_shaping; i++)
+		if (pd->shaping_is_need_init[i])
+			regmap_write(pd->shaping_regmap[i], SHAPING_NBPKTMAX0,
+				     pd->shaping_save_regs[i]);
+
+	kfree(pd->shaping_is_need_init);
+	pd->shaping_is_need_init = NULL;
+	pd->is_shaping_need_init = false;
+}
+
 static int rockchip_pmu_save_qos(struct rockchip_pm_domain *pd)
 {
 	int i;
@@ -480,7 +497,8 @@
 			    QOS_EXTCONTROL,
 			    &pd->qos_save_regs[4][i]);
 	}
-	return 0;
+
+	return rockchip_pmu_save_shaping(pd);
 }
 
 static int rockchip_pmu_restore_qos(struct rockchip_pm_domain *pd)
@@ -505,12 +523,14 @@
 			     pd->qos_save_regs[4][i]);
 	}
 
-	return 0;
+	return rockchip_pmu_restore_shaping(pd);
 }
 
 static void rockchip_pmu_init_qos(struct rockchip_pm_domain *pd)
 {
 	int i;
+
+	rockchip_pmu_init_shaping(pd);
 
 	if (!pd->is_qos_need_init)
 		return;
@@ -809,7 +829,7 @@
 
 			if (pd->is_qos_saved)
 				rockchip_pmu_restore_qos(pd);
-			if (pd->is_qos_need_init)
+			if (pd->is_qos_need_init || pd->is_shaping_need_init)
 				rockchip_pmu_init_qos(pd);
 		}
 
@@ -949,8 +969,13 @@
 	if (!pd->is_qos_need_init) {
 		kfree(pd->qos_is_need_init[0]);
 		pd->qos_is_need_init[0] = NULL;
-		return;
 	}
+	if (!pd->is_shaping_need_init) {
+		kfree(pd->shaping_is_need_init);
+		pd->shaping_is_need_init = NULL;
+	}
+	if (!pd->is_qos_need_init && !pd->is_shaping_need_init)
+		return;
 
 	is_pd_on = rockchip_pmu_domain_is_on(pd);
 	if (is_pd_on) {
@@ -982,6 +1007,79 @@
 	}
 
 	return 0;
+}
+
+static int rockchip_pd_of_get_shaping(struct rockchip_pm_domain *pd,
+				      struct device_node *node)
+{
+	struct rockchip_pmu *pmu = pd->pmu;
+	struct device_node *shaping_node;
+	int num_shaping = 0, num_shaping_reg = 0;
+	int error, i;
+	u32 val;
+
+	num_shaping = of_count_phandle_with_args(node, "pm_shaping", NULL);
+
+	for (i = 0; i < num_shaping; i++) {
+		shaping_node = of_parse_phandle(node, "pm_shaping", i);
+		if (shaping_node && of_device_is_available(shaping_node))
+			pd->num_shaping++;
+		of_node_put(shaping_node);
+	}
+
+	if (pd->num_shaping > 0) {
+		pd->shaping_regmap = devm_kcalloc(pmu->dev, pd->num_shaping,
+						  sizeof(*pd->shaping_regmap),
+						  GFP_KERNEL);
+		if (!pd->shaping_regmap)
+			return -ENOMEM;
+		pd->shaping_save_regs = devm_kmalloc(pmu->dev, sizeof(u32) *
+						     pd->num_shaping,
+						     GFP_KERNEL);
+		if (!pd->shaping_save_regs)
+			return -ENOMEM;
+		pd->shaping_is_need_init = kcalloc(pd->num_shaping, sizeof(bool),
+						   GFP_KERNEL);
+		if (!pd->shaping_is_need_init)
+			return -ENOMEM;
+		for (i = 0; i < num_shaping; i++) {
+			shaping_node = of_parse_phandle(node, "pm_shaping", i);
+			if (!shaping_node) {
+				error = -ENODEV;
+				goto err_free_init;
+			}
+			if (of_device_is_available(shaping_node)) {
+				pd->shaping_regmap[num_shaping_reg] =
+					syscon_node_to_regmap(shaping_node);
+				if (IS_ERR(pd->shaping_regmap[num_shaping_reg])) {
+					of_node_put(shaping_node);
+					error =  -ENODEV;
+					goto err_free_init;
+				}
+				if (!of_property_read_u32(shaping_node,
+							  "shaping-init",
+							  &val)) {
+					pd->shaping_save_regs[i] = val;
+					pd->shaping_is_need_init[i] = true;
+					pd->is_shaping_need_init = true;
+				}
+				num_shaping_reg++;
+			}
+			of_node_put(shaping_node);
+			if (num_shaping_reg > pd->num_shaping) {
+				error =  -EINVAL;
+				goto err_free_init;
+			}
+		}
+	}
+
+	return 0;
+
+err_free_init:
+	kfree(pd->shaping_is_need_init);
+	pd->shaping_is_need_init = NULL;
+
+	return error;
 }
 
 static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
@@ -1160,6 +1258,10 @@
 		}
 	}
 
+	error = rockchip_pd_of_get_shaping(pd, node);
+	if (error)
+		goto err_unprepare_clocks;
+
 	if (pd->info->name)
 		pd->genpd.name = pd->info->name;
 	else
@@ -1309,6 +1411,31 @@
 	return error;
 }
 
+#ifdef MODULE
+void rockchip_pd_disable_unused(void)
+{
+	struct generic_pm_domain *genpd;
+	struct rockchip_pm_domain *pd;
+	int i;
+
+	if (!g_pmu)
+		return;
+
+	for (i = 0; i < g_pmu->genpd_data.num_domains; i++) {
+		genpd = g_pmu->genpd_data.domains[i];
+		if (genpd) {
+			pd = to_rockchip_pd(genpd);
+			if (pd->info->always_on)
+				continue;
+			if (pd->info->keepon_startup &&
+			    (genpd->flags & GENPD_FLAG_ALWAYS_ON))
+				genpd->flags &= (~GENPD_FLAG_ALWAYS_ON);
+			queue_work(pm_wq, &genpd->power_off_work);
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(rockchip_pd_disable_unused);
+#else
 static void rockchip_pd_keepon_do_release(void)
 {
 	struct generic_pm_domain *genpd;
@@ -1334,7 +1461,6 @@
 	}
 }
 
-#ifndef MODULE
 static int __init rockchip_pd_keepon_release(void)
 {
 	rockchip_pd_keepon_do_release();
diff --git a/kernel/drivers/soc/rockchip/rk_dmabuf_procfs.c b/kernel/drivers/soc/rockchip/rk_dmabuf_procfs.c
index 943b196..0d82f0a 100644
--- a/kernel/drivers/soc/rockchip/rk_dmabuf_procfs.c
+++ b/kernel/drivers/soc/rockchip/rk_dmabuf_procfs.c
@@ -186,8 +186,10 @@
 	struct proc_dir_entry *root = proc_mkdir("rk_dmabuf", NULL);
 
 	pdev = platform_device_register_full(&dev_info);
-	dma_set_max_seg_size(&pdev->dev, (unsigned int)DMA_BIT_MASK(64));
-	dmabuf_dev = pdev ? &pdev->dev : NULL;
+	if (!IS_ERR(pdev)) {
+		dmabuf_dev = &pdev->dev;
+		dma_set_max_seg_size(dmabuf_dev, (unsigned int)DMA_BIT_MASK(64));
+	}
 
 	proc_create_single("sgt", 0, root, rk_dmabuf_sgt_show);
 	proc_create_single("dev", 0, root, rk_dmabuf_dev_show);
diff --git a/kernel/drivers/soc/rockchip/rockchip-cpuinfo.c b/kernel/drivers/soc/rockchip/rockchip-cpuinfo.c
index 5785d42..02befb1 100644
--- a/kernel/drivers/soc/rockchip/rockchip-cpuinfo.c
+++ b/kernel/drivers/soc/rockchip/rockchip-cpuinfo.c
@@ -57,12 +57,9 @@
 	}
 
 	cell = nvmem_cell_get(dev, "id");
-	if (IS_ERR(cell)) {
-		dev_err(dev, "failed to get id cell: %ld\n", PTR_ERR(cell));
-		if (PTR_ERR(cell) == -EPROBE_DEFER)
-			return PTR_ERR(cell);
-		return PTR_ERR(cell);
-	}
+	if (IS_ERR(cell))
+		return dev_err_probe(dev, PTR_ERR(cell), "failed to get id cell\n");
+
 	efuse_buf = nvmem_cell_read(cell, &len);
 	nvmem_cell_put(cell);
 	if (IS_ERR(efuse_buf))
diff --git a/kernel/drivers/soc/rockchip/rockchip_amp.c b/kernel/drivers/soc/rockchip/rockchip_amp.c
index db52d09..6f5bdc6 100644
--- a/kernel/drivers/soc/rockchip/rockchip_amp.c
+++ b/kernel/drivers/soc/rockchip/rockchip_amp.c
@@ -15,6 +15,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/rockchip/rockchip_sip.h>
 #include <soc/rockchip/rockchip_amp.h>
+#include <linux/irqchip/arm-gic-common.h>
 
 #define RK_CPU_STATUS_OFF		0
 #define RK_CPU_STATUS_ON		1
@@ -24,6 +25,7 @@
 #define GPIO_BANK_NUM			16
 #define GPIO_GROUP_PRIO_MAX		3
 
+#define MAX_GIC_SPI_NUM (1020)
 #define AMP_GIC_DBG(fmt, arg...)	do { if (0) { pr_warn(fmt, ##arg); } } while (0)
 
 enum amp_cpu_ctrl_status {
@@ -55,26 +57,27 @@
 struct amp_gpio_group_s {
 	u32 bank_id;
 	u32 prio;
-	u32 irq_aff[AMP_AFF_MAX_CPU];
+	u64 irq_aff[AMP_AFF_MAX_CPU];
 	u32 irq_id[AMP_AFF_MAX_CPU];
 	u32 en[AMP_AFF_MAX_CPU];
 };
 
 struct amp_irq_cfg_s {
+	u64 aff;
 	u32 prio;
 	u32 cpumask;
-	u32 aff;
 	int amp_flag;
-} irqs_cfg[1024];
+} irqs_cfg[MAX_GIC_SPI_NUM];
 
 static struct amp_gic_ctrl_s {
+	enum gic_type gic_version;
+	u32 spis_num;
 	struct {
 		u32 aff;
 		u32 cpumask;
 		u32 flag;
 	} aff_to_cpumask[AMP_AFF_MAX_CLUSTER][AMP_AFF_MAX_CPU];
-	struct amp_irq_cfg_s irqs_cfg[1024];
-	u32 validmask[1020 / 32 + 1];
+	struct amp_irq_cfg_s irqs_cfg[MAX_GIC_SPI_NUM];
 	struct amp_gpio_group_s gpio_grp[GPIO_BANK_NUM][GPIO_GROUP_PRIO_MAX];
 	u32 gpio_banks;
 } amp_ctrl;
@@ -275,7 +278,12 @@
 	return amp_ctrl.irqs_cfg[irq].cpumask;
 }
 
-static u32 amp_get_cpumask_bit(u32 aff)
+int rockchip_amp_need_init_amp_irq(u32 irq)
+{
+	return amp_ctrl.irqs_cfg[irq].amp_flag;
+}
+
+static u32 amp_get_cpumask_bit(u64 aff)
 {
 	u32 aff_cluster, aff_cpu;
 
@@ -285,18 +293,24 @@
 	if (aff_cpu >= AMP_AFF_MAX_CPU || aff_cluster >= AMP_AFF_MAX_CLUSTER)
 		return 0;
 
-	AMP_GIC_DBG("%s: aff:%d-%d: %x\n", __func__, aff_cluster, aff_cpu,
+	AMP_GIC_DBG("  %s: aff:%d-%d: %x\n", __func__, aff_cluster, aff_cpu,
 		    amp_ctrl.aff_to_cpumask[aff_cluster][aff_cpu].cpumask);
 
 	return amp_ctrl.aff_to_cpumask[aff_cluster][aff_cpu].cpumask;
+}
+
+u64 rockchip_amp_get_irq_aff(u32 irq)
+{
+	return amp_ctrl.irqs_cfg[irq].aff;
 }
 
 static int gic_amp_get_gpio_prio_group_info(struct device_node *np,
 					    struct amp_gic_ctrl_s *amp_ctrl,
 					    int prio_id)
 {
-	u32 gpio_bank, count0, count1, prio, irq_id, irq_aff;
-	int i;
+	u32 gpio_bank, prio, irq_id;
+	u64 irq_aff;
+	int i, count0, count1;
 	struct amp_gpio_group_s *gpio_grp;
 	struct amp_irq_cfg_s *irqs_cfg;
 
@@ -320,7 +334,7 @@
 		    __func__, gpio_bank, prio_id, prio);
 
 	count0 = of_property_count_u32_elems(np, "girq-id");
-	count1 = of_property_count_u32_elems(np, "girq-aff");
+	count1 = of_property_count_u64_elems(np, "girq-aff");
 
 	if (count0 != count1)
 		return -EINVAL;
@@ -330,7 +344,7 @@
 	for (i = 0; i < count0; i++) {
 		of_property_read_u32_index(np, "girq-id", i, &irq_id);
 		gpio_grp->irq_id[i] = irq_id;
-		of_property_read_u32_index(np, "girq-aff", i, &irq_aff);
+		of_property_read_u64_index(np, "girq-aff", i, &irq_aff);
 
 		gpio_grp->irq_aff[i] = irq_aff;
 
@@ -338,18 +352,24 @@
 
 		irqs_cfg = &amp_ctrl->irqs_cfg[irq_id];
 
-		AMP_GIC_DBG(" %s: group cpu-%d, irq-%d: prio-%x, aff-%x en-%d\n",
+		AMP_GIC_DBG(" %s: group cpu-%d, irq-%d: prio-%x, aff-%llx en-%d\n",
 			    __func__, i, gpio_grp->irq_id[i], gpio_grp->prio,
 			    gpio_grp->irq_aff[i], gpio_grp->en[i]);
 
 		if (gpio_grp->en[i]) {
 			irqs_cfg->prio = gpio_grp->prio;
 			irqs_cfg->aff = irq_aff;
-			irqs_cfg->cpumask = amp_get_cpumask_bit(irq_aff);
+			if (amp_ctrl->gic_version == GIC_V2) {
+				irqs_cfg->cpumask = amp_get_cpumask_bit(irq_aff);
+				if (!irqs_cfg->cpumask) {
+					pr_err(" %s: get cpumask error\n", __func__);
+					return -EINVAL;
+				}
+			}
 			irqs_cfg->amp_flag = 1;
 		}
 
-		AMP_GIC_DBG("  %s: irqs_cfg prio-%x aff-%x cpumaks-%x en-%d\n",
+		AMP_GIC_DBG("  %s: prio-%x aff-%llx cpumaks-%x flag-%d\n",
 			    __func__, irqs_cfg->prio, irqs_cfg->aff,
 			    irqs_cfg->cpumask, irqs_cfg->amp_flag);
 	}
@@ -404,33 +424,37 @@
 {
 	const struct property *prop;
 	int count, i;
-	u32 cluster, aff_cpu, aff, cpumask;
+	u32 cluster, aff_cpu;
+	u64 aff, cpumask;
 
+	if (amp_ctrl->gic_version != GIC_V2)
+		return 0;
 	prop = of_find_property(np, "amp-cpu-aff-maskbits", NULL);
+
 	if (!prop)
 		return -1;
 
 	if (!prop->value)
 		return -1;
 
-	count = of_property_count_u32_elems(np, "amp-cpu-aff-maskbits");
+	count = of_property_count_u64_elems(np, "amp-cpu-aff-maskbits");
 	if (count % 2)
 		return -1;
 
 	for (i = 0; i < count / 2; i++) {
-		of_property_read_u32_index(np, "amp-cpu-aff-maskbits",
+		of_property_read_u64_index(np, "amp-cpu-aff-maskbits",
 					   2 * i, &aff);
 		cluster = MPIDR_AFFINITY_LEVEL(aff, 1);
 		aff_cpu = MPIDR_AFFINITY_LEVEL(aff, 0);
 		amp_ctrl->aff_to_cpumask[cluster][aff_cpu].aff = aff;
 
-		of_property_read_u32_index(np, "amp-cpu-aff-maskbits",
+		of_property_read_u64_index(np, "amp-cpu-aff-maskbits",
 					   2 * i + 1, &cpumask);
 
-		amp_ctrl->aff_to_cpumask[cluster][aff_cpu].cpumask = cpumask;
+		amp_ctrl->aff_to_cpumask[cluster][aff_cpu].cpumask = (u32)cpumask;
 
-		AMP_GIC_DBG("cpumask: %d-%d: aff-%d cpumask-%d\n",
-			    cluster, aff_cpu, aff, cpumask);
+		AMP_GIC_DBG("cpumask: %d-%d: aff-%llx cpumask-%d\n",
+			    cluster, aff_cpu, aff, (u32)cpumask);
 
 		if (!cpumask)
 			return -1;
@@ -443,8 +467,9 @@
 				    struct amp_gic_ctrl_s *amp_ctrl)
 {
 	const struct property *prop;
-	int count, i;
-	u32 irq, prio, aff;
+	u32 irq, i;
+	int count;
+	u64 aff, val, prio;
 
 	prop = of_find_property(np, "amp-irqs", NULL);
 	if (!prop)
@@ -453,30 +478,31 @@
 	if (!prop->value)
 		return;
 
-	count = of_property_count_u32_elems(np, "amp-irqs");
+	count = of_property_count_u64_elems(np, "amp-irqs");
 
-	if (count < 0 || count % 3)
+	if (count % 3)
 		return;
 
 	for (i = 0; i < count / 3; i++) {
-		of_property_read_u32_index(np, "amp-irqs", 3 * i, &irq);
-
-		if (irq > 1020)
+		of_property_read_u64_index(np, "amp-irqs", 3 * i, &val);
+		irq = (u32)val;
+		if (irq > amp_ctrl->spis_num)
 			break;
 
-		of_property_read_u32_index(np, "amp-irqs", 3 * i + 1, &prio);
-		of_property_read_u32_index(np, "amp-irqs", 3 * i + 2, &aff);
+		of_property_read_u64_index(np, "amp-irqs", 3 * i + 1, &prio);
+		of_property_read_u64_index(np, "amp-irqs", 3 * i + 2, &aff);
 
-		AMP_GIC_DBG("%s: irq-%d aff-%d prio-%x\n",
+		AMP_GIC_DBG("%s: irq-%d aff-%llx prio-%llx\n",
 			    __func__, irq, aff, prio);
 
-		amp_ctrl->irqs_cfg[irq].prio = prio;
+		amp_ctrl->irqs_cfg[irq].prio = (u32)prio;
 		amp_ctrl->irqs_cfg[irq].aff = aff;
-		amp_ctrl->irqs_cfg[irq].cpumask = amp_get_cpumask_bit(aff);
-
-		if (!amp_ctrl->irqs_cfg[irq].cpumask) {
-			AMP_GIC_DBG("%s: get cpumask error\n", __func__);
-			break;
+		if (amp_ctrl->gic_version == GIC_V2) {
+			amp_ctrl->irqs_cfg[irq].cpumask = amp_get_cpumask_bit(aff);
+			if (!amp_ctrl->irqs_cfg[irq].cpumask) {
+				pr_err("%s: get cpumask error\n", __func__);
+				break;
+			}
 		}
 
 		if (!amp_ctrl->irqs_cfg[irq].aff &&
@@ -485,16 +511,19 @@
 
 		amp_ctrl->irqs_cfg[irq].amp_flag = 1;
 
-		AMP_GIC_DBG("%s: irq-%d aff-%d cpumask-%d pri-%x\n",
+		AMP_GIC_DBG(" %s: irq-%d aff-%llx cpumask-%x pri-%x\n",
 			    __func__, irq, amp_ctrl->irqs_cfg[irq].aff,
 			    amp_ctrl->irqs_cfg[irq].cpumask,
 			    amp_ctrl->irqs_cfg[irq].prio);
 	}
 }
 
-void rockchip_amp_get_gic_info(void)
+void rockchip_amp_get_gic_info(u32 spis_num, enum gic_type gic_version)
 {
 	struct device_node *np;
+
+	amp_ctrl.spis_num = spis_num;
+	amp_ctrl.gic_version = gic_version;
 
 	np = of_find_node_by_name(NULL, "rockchip-amp");
 	if (!np)
@@ -504,6 +533,7 @@
 		pr_err("%s: get amp gic cpu mask error\n", __func__);
 		goto exit;
 	}
+
 	gic_of_get_gpio_group(np, &amp_ctrl);
 	amp_gic_get_irqs_config(np, &amp_ctrl);
 
diff --git a/kernel/drivers/soc/rockchip/rockchip_csu.c b/kernel/drivers/soc/rockchip/rockchip_csu.c
new file mode 100644
index 0000000..04a6a5b
--- /dev/null
+++ b/kernel/drivers/soc/rockchip/rockchip_csu.c
@@ -0,0 +1,377 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023, Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao@rock-chips.com>
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/rockchip/rockchip_sip.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <soc/rockchip/rockchip_csu.h>
+
+struct csu_bus {
+	unsigned int id;
+	unsigned int cfg_val;
+	unsigned int en_mask;
+	unsigned int disable_count;
+};
+
+struct csu_clk {
+	unsigned int clk_id;
+	unsigned int bus_id;
+};
+
+struct rockchip_csu {
+	struct device *dev;
+	struct csu_bus *bus;
+	struct csu_clk *clk;
+	unsigned int bus_cnt;
+	unsigned int clk_cnt;
+};
+
+static struct rockchip_csu *rk_csu;
+static DEFINE_MUTEX(csu_lock);
+
+static int rockchip_csu_sip_config(struct device *dev, u32 bus_id, u32 cfg,
+				   u32 enable_msk)
+{
+	struct arm_smccc_res res;
+
+	dev_dbg(dev, "id=%u, cfg=0x%x, en_mask=0x%x\n", bus_id, cfg, enable_msk);
+	res = sip_smc_bus_config(bus_id, cfg, enable_msk);
+
+	return res.a0;
+}
+
+struct csu_clk *rockchip_csu_get(struct device *dev, const char *name)
+{
+	struct of_phandle_args args;
+	struct csu_clk *clk = ERR_PTR(-ENOENT);
+	unsigned int clk_id = 0;
+	int index = 0, i = 0;
+
+	if (!dev || !dev->of_node)
+		return ERR_PTR(-ENODEV);
+	if (!rk_csu || !rk_csu->bus || !rk_csu->clk)
+		return ERR_PTR(-ENODEV);
+
+	if (name)
+		index = of_property_match_string(dev->of_node,
+						 "rockchip,csu-names",
+						 name);
+	if (of_parse_phandle_with_fixed_args(dev->of_node, "rockchip,csu", 1,
+					     index, &args)) {
+		dev_err(dev, "Missing the phandle args name %s\n", name);
+		return ERR_PTR(-ENODEV);
+	}
+	clk_id = args.args[0];
+
+	for (i = 0; i < rk_csu->clk_cnt; i++) {
+		if (clk_id == rk_csu->clk[i].clk_id) {
+			clk = &rk_csu->clk[i];
+			break;
+		}
+	}
+
+	return clk;
+}
+EXPORT_SYMBOL(rockchip_csu_get);
+
+static int csu_disable(struct csu_clk *clk, bool disable)
+{
+	struct csu_bus *bus = NULL;
+	unsigned int en_mask = 0;
+	int ret = 0;
+
+	if (IS_ERR_OR_NULL(clk))
+		return 0;
+	if (clk->bus_id >= rk_csu->bus_cnt)
+		return 0;
+	bus = &rk_csu->bus[clk->bus_id];
+	if (!bus)
+		return 0;
+
+	mutex_lock(&csu_lock);
+
+	if (disable)
+		bus->disable_count++;
+	else if (bus->disable_count > 0)
+		bus->disable_count--;
+
+	if (bus->disable_count)
+		en_mask = bus->en_mask & CSU_EN_MASK;
+	else
+		en_mask = bus->en_mask;
+
+	ret = rockchip_csu_sip_config(rk_csu->dev, bus->id, bus->cfg_val, en_mask);
+	if (ret)
+		dev_err(rk_csu->dev, "csu sip config disable error\n");
+
+	mutex_unlock(&csu_lock);
+
+	return ret;
+}
+
+int rockchip_csu_enable(struct csu_clk *clk)
+{
+	return csu_disable(clk, false);
+}
+EXPORT_SYMBOL(rockchip_csu_enable);
+
+int rockchip_csu_disable(struct csu_clk *clk)
+{
+	return csu_disable(clk, true);
+}
+EXPORT_SYMBOL(rockchip_csu_disable);
+
+int rockchip_csu_set_div(struct csu_clk *clk, unsigned int div)
+{
+	struct csu_bus *bus = NULL;
+	unsigned int cfg_val = 0;
+	int ret = 0;
+
+	if (IS_ERR_OR_NULL(clk))
+		return 0;
+	if (clk->bus_id >= rk_csu->bus_cnt)
+		return 0;
+	bus = &rk_csu->bus[clk->bus_id];
+	if (!bus)
+		return 0;
+
+	mutex_lock(&csu_lock);
+
+	if (div > CSU_MAX_DIV)
+		div = CSU_MAX_DIV;
+	cfg_val = (bus->cfg_val & ~CSU_DIV_MASK) | ((div - 1) & CSU_DIV_MASK);
+
+	ret = rockchip_csu_sip_config(rk_csu->dev, bus->id, cfg_val, bus->en_mask);
+	if (ret)
+		dev_err(rk_csu->dev, "csu sip config freq error\n");
+
+	mutex_unlock(&csu_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(rockchip_csu_set_div);
+
+static int rockchip_csu_parse_clk(struct rockchip_csu *csu)
+{
+	struct device *dev = csu->dev;
+	struct device_node *np = dev->of_node;
+	char *prop_name = "rockchip,clock";
+	struct csu_clk *tmp;
+	const struct property *prop;
+	int count, i;
+
+	prop = of_find_property(np, prop_name, NULL);
+	if (!prop)
+		return -EINVAL;
+
+	if (!prop->value)
+		return -ENODATA;
+
+	count = of_property_count_u32_elems(np, prop_name);
+	if (count < 0)
+		return -EINVAL;
+
+	if (count % 2)
+		return -EINVAL;
+
+	tmp = devm_kcalloc(dev, count / 2, sizeof(*tmp), GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	for (i = 0; i < count / 2; i++) {
+		of_property_read_u32_index(np, prop_name, 2 * i,
+					   &tmp[i].clk_id);
+		of_property_read_u32_index(np, prop_name, 2 * i + 1,
+					   &tmp[i].bus_id);
+	}
+
+	csu->clk = tmp;
+	csu->clk_cnt = count / 2;
+
+	return 0;
+}
+
+static int rockchip_csu_parse_bus_table(struct rockchip_csu *csu)
+{
+	struct device *dev = csu->dev;
+	struct device_node *np = dev->of_node;
+	char *prop_name = "rockchip,bus";
+	struct csu_bus *tmp;
+	const struct property *prop;
+	int count, i;
+
+	prop = of_find_property(np, prop_name, NULL);
+	if (!prop)
+		return -EINVAL;
+
+	if (!prop->value)
+		return -ENODATA;
+
+	count = of_property_count_u32_elems(np, prop_name);
+	if (count < 0)
+		return -EINVAL;
+
+	if (count % 3)
+		return -EINVAL;
+
+	tmp = devm_kcalloc(dev, count / 3, sizeof(*tmp), GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	for (i = 0; i < count / 3; i++) {
+		of_property_read_u32_index(np, prop_name, 3 * i,
+					   &tmp[i].id);
+		of_property_read_u32_index(np, prop_name, 3 * i + 1,
+					   &tmp[i].cfg_val);
+		of_property_read_u32_index(np, prop_name, 3 * i + 2,
+					   &tmp[i].en_mask);
+	}
+
+	csu->bus = tmp;
+	csu->bus_cnt = count / 3;
+
+	return 0;
+}
+
+static int rockchip_csu_bus_table(struct rockchip_csu *csu)
+{
+	struct device *dev = csu->dev;
+	struct csu_bus *bus;
+	int i;
+
+	if (rockchip_csu_parse_bus_table(csu))
+		return -EINVAL;
+
+	for (i = 0; i < csu->bus_cnt; i++) {
+		bus = &csu->bus[i];
+		if (!bus || !bus->cfg_val) {
+			dev_info(dev, "bus %d cfg-val invalid\n", i);
+			continue;
+		}
+		if (rockchip_csu_sip_config(dev, bus->id, bus->cfg_val, bus->en_mask))
+			dev_err(dev, "csu sip config error\n");
+	}
+
+	return 0;
+}
+
+static int rockchip_csu_bus_node(struct rockchip_csu *csu)
+{
+	struct device *dev = csu->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *child;
+	struct csu_bus *bus;
+	int bus_cnt = 0, i = 0;
+
+	for_each_available_child_of_node(np, child)
+		bus_cnt++;
+	if (bus_cnt <= 0)
+		return 0;
+
+	csu->bus = devm_kcalloc(dev, bus_cnt, sizeof(*csu->bus), GFP_KERNEL);
+	if (!csu->bus)
+		return -ENOMEM;
+	csu->bus_cnt = bus_cnt;
+
+	for_each_available_child_of_node(np, child) {
+		bus = &csu->bus[i++];
+		if (of_property_read_u32_index(child, "bus-id", 0, &bus->id)) {
+			dev_info(dev, "get bus-id error\n");
+			continue;
+		}
+
+		if (of_property_read_u32_index(child, "cfg-val", 0,
+					       &bus->cfg_val)) {
+			dev_info(dev, "get cfg-val error\n");
+			continue;
+		}
+		if (!bus->cfg_val) {
+			dev_info(dev, "cfg-val invalid\n");
+			continue;
+		}
+
+		if (of_property_read_u32_index(child, "enable-msk", 0,
+					       &bus->en_mask)) {
+			dev_info(dev, "get enable_msk error\n");
+			continue;
+		}
+
+		if (rockchip_csu_sip_config(dev, bus->id, bus->cfg_val, bus->en_mask))
+			dev_info(dev, "csu smc config error\n");
+	}
+
+	return 0;
+}
+
+static const struct of_device_id rockchip_csu_of_match[] = {
+	{ .compatible = "rockchip,rk3562-csu", },
+	{ },
+};
+
+MODULE_DEVICE_TABLE(of, rockchip_csu_of_match);
+
+static int rockchip_csu_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct rockchip_csu *csu;
+	int ret = 0;
+
+	csu = devm_kzalloc(dev, sizeof(*csu), GFP_KERNEL);
+	if (!csu)
+		return -ENOMEM;
+
+	csu->dev = dev;
+	platform_set_drvdata(pdev, csu);
+
+	rockchip_csu_parse_clk(csu);
+
+	if (of_find_property(np, "rockchip,bus", NULL))
+		ret = rockchip_csu_bus_table(csu);
+	else
+		ret = rockchip_csu_bus_node(csu);
+	if (!ret)
+		rk_csu = csu;
+
+	return ret;
+}
+
+static struct platform_driver rockchip_csu_driver = {
+	.probe	= rockchip_csu_probe,
+	.driver = {
+		.name	= "rockchip,csu",
+		.of_match_table = rockchip_csu_of_match,
+	},
+};
+
+static int __init rockchip_csu_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&rockchip_csu_driver);
+	if (ret) {
+		pr_err("failed to register csu driver\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void __exit rockchip_csu_exit(void)
+{
+	return platform_driver_unregister(&rockchip_csu_driver);
+}
+
+subsys_initcall(rockchip_csu_init);
+module_exit(rockchip_csu_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Finley Xiao <finley.xiao@rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip clock subunit driver");
diff --git a/kernel/drivers/soc/rockchip/rockchip_debug.c b/kernel/drivers/soc/rockchip/rockchip_debug.c
index 60edc6a..2f9eac2 100644
--- a/kernel/drivers/soc/rockchip/rockchip_debug.c
+++ b/kernel/drivers/soc/rockchip/rockchip_debug.c
@@ -59,6 +59,10 @@
 #include <linux/irq.h>
 #include <linux/delay.h>
 
+#if IS_ENABLED(CONFIG_ROCKCHIP_MINIDUMP)
+#include <soc/rockchip/rk_minidump.h>
+#endif
+
 #include "fiq_debugger/fiq_debugger_priv.h"
 #include "rockchip_debug.h"
 
@@ -85,6 +89,22 @@
 extern struct atomic_notifier_head hardlock_notifier_list;
 extern struct atomic_notifier_head rcu_stall_notifier_list;
 
+static inline void rockchip_debug_serror_enable(void)
+{
+#ifdef CONFIG_ARM64
+	/* enable SError */
+	asm volatile("msr	daifclr, #0x4");
+#endif
+}
+
+static inline void rockchip_debug_serror_disable(void)
+{
+#ifdef CONFIG_ARM64
+	/* disable SError */
+	asm volatile("msr	daifset, #0x4");
+#endif
+}
+
 #if IS_ENABLED(CONFIG_FIQ_DEBUGGER)
 static int rockchip_debug_dump_edpcsr(struct fiq_debugger_output *output)
 {
@@ -96,10 +116,7 @@
 	void __iomem *base;
 	u32 pu = 0, online = 0;
 
-#ifdef CONFIG_ARM64
-	/* disable SError */
-	asm volatile("msr	daifset, #0x4");
-#endif
+	rockchip_debug_serror_disable();
 
 	while (rockchip_cpu_debug[i]) {
 		online = cpu_online(i);
@@ -154,11 +171,7 @@
 		printed = 0;
 	}
 
-#ifdef CONFIG_ARM64
-	/* enable SError */
-	asm volatile("msr	daifclr, #0x4");
-#endif
-
+	rockchip_debug_serror_enable();
 	return NOTIFY_OK;
 }
 
@@ -173,8 +186,7 @@
 	void __iomem *base;
 	u32 pu = 0, online = 0;
 
-	/* disable SError */
-	asm volatile("msr	daifset, #0x4");
+	rockchip_debug_serror_disable();
 
 	while (rockchip_cs_pmu[i]) {
 		online = cpu_online(i);
@@ -233,8 +245,7 @@
 		prev_pc = NULL;
 		printed = 0;
 	}
-	/* enable SError */
-	asm volatile("msr	daifclr, #0x4");
+	rockchip_debug_serror_enable();
 	return NOTIFY_OK;
 }
 #else
@@ -243,7 +254,6 @@
 	return 0;
 }
 #endif
-
 
 int rockchip_debug_dump_pcsr(struct fiq_debugger_output *output)
 {
@@ -267,10 +277,7 @@
 	void __iomem *base;
 	u32 pu = 0;
 
-#ifdef CONFIG_ARM64
-	/* disable SError */
-	asm volatile("msr	daifset, #0x4");
-#endif
+	rockchip_debug_serror_disable();
 
 	/*
 	 * The panic handler will try to shut down the other CPUs.
@@ -324,11 +331,6 @@
 		printed = 0;
 	}
 
-#ifdef CONFIG_ARM64
-	/* enable SError */
-	asm volatile("msr	daifclr, #0x4");
-#endif
-
 	return NOTIFY_OK;
 }
 
@@ -344,8 +346,7 @@
 	void __iomem *base;
 	u32 pu = 0;
 
-	/* disable SError */
-	asm volatile("msr	daifset, #0x4");
+	rockchip_debug_serror_disable();
 
 	/*
 	 * The panic handler will try to shut down the other CPUs.
@@ -403,8 +404,7 @@
 		prev_pc = NULL;
 		printed = 0;
 	}
-	/* enable SError */
-	asm volatile("msr	daifclr, #0x4");
+
 	return NOTIFY_OK;
 }
 #else
@@ -508,8 +508,73 @@
 	rockchip_panic_notify_dump_irqs();
 	return NOTIFY_OK;
 }
+
+static int rockchip_hardlock_notify(struct notifier_block *nb,
+				    unsigned long event, void *p)
+{
+	u64 pmpcsr;
+	int el;
+	u32 pu = 0;
+	void *pc = NULL;
+	void __iomem *base;
+	unsigned long edpcsr;
+	unsigned long cpu = event;
+
+	rockchip_debug_serror_disable();
+
+	pu = (u32)readl(rockchip_cpu_debug[cpu] + EDPRSR) & EDPRSR_PU;
+	if (pu != EDPRSR_PU) {
+		pr_err("CPU%ld power down\n", cpu);
+		return NOTIFY_OK;
+	}
+
+	if (edpcsr_present) {
+		base = rockchip_cpu_debug[cpu];
+		/* Unlock EDLSR.SLK so that EDPCSRhi gets populated */
+		writel(EDLAR_UNLOCK, base + EDLAR);
+		if (sizeof(edpcsr) == 8)
+			edpcsr = ((u64)readl(base + EDPCSR_LO)) |
+				 ((u64)readl(base + EDPCSR_HI) << 32);
+		else
+			edpcsr = (u32)readl(base + EDPCSR_LO);
+
+		/* NOTE: no offset on ARMv8; see DBGDEVID1.PCSROffset */
+		pc = (void *)(edpcsr & ~1);
+	} else {
+		base = rockchip_cs_pmu[cpu];
+		pmpcsr = ((u64)readl(base + PMPCSR_LO)) |
+			 ((u64)readl(base + PMPCSR_HI) << 32);
+		el = (pmpcsr >> 61) & 0x3;
+		if (el == 2)
+			pmpcsr |= 0xff00000000000000;
+		else
+			pmpcsr &= 0x0fffffffffffffff;
+		/* NOTE: no offset on ARMv8; see DBGDEVID1.PCSROffset */
+		pc = (void *)(pmpcsr & ~1);
+	}
+
+	rockchip_debug_serror_enable();
+
+#if IS_ENABLED(CONFIG_ROCKCHIP_MINIDUMP)
+	rk_minidump_hardlock_notify(nb, event, pc);
+#endif
+
+#if !IS_ENABLED(CONFIG_BOOTPARAM_HARDLOCKUP_PANIC)
+	rockchip_panic_notify(nb, event, p);
+#endif
+	return NOTIFY_OK;
+}
+
 static struct notifier_block rockchip_panic_nb = {
 	.notifier_call = rockchip_panic_notify,
+};
+
+static struct notifier_block rockchip_rcu_stall_nb = {
+	.notifier_call = rockchip_panic_notify,
+};
+
+static struct notifier_block rockchip_hardlock_nb = {
+	.notifier_call = rockchip_hardlock_notify,
 };
 
 static const struct of_device_id rockchip_debug_dt_match[] __initconst = {
@@ -527,7 +592,6 @@
 	},
 	{ /* sentinel */ },
 };
-
 
 static int __init rockchip_debug_init(void)
 {
@@ -575,10 +639,10 @@
 	if (IS_ENABLED(CONFIG_NO_GKI)) {
 		if (IS_ENABLED(CONFIG_HARDLOCKUP_DETECTOR))
 			atomic_notifier_chain_register(&hardlock_notifier_list,
-						       &rockchip_panic_nb);
+						       &rockchip_hardlock_nb);
 
 		atomic_notifier_chain_register(&rcu_stall_notifier_list,
-					       &rockchip_panic_nb);
+					       &rockchip_rcu_stall_nb);
 	}
 
 	return 0;
@@ -594,10 +658,10 @@
 	if (IS_ENABLED(CONFIG_NO_GKI)) {
 		if (IS_ENABLED(CONFIG_HARDLOCKUP_DETECTOR))
 			atomic_notifier_chain_unregister(&hardlock_notifier_list,
-							 &rockchip_panic_nb);
+							 &rockchip_hardlock_nb);
 
 		atomic_notifier_chain_unregister(&rcu_stall_notifier_list,
-						 &rockchip_panic_nb);
+						 &rockchip_rcu_stall_nb);
 	}
 
 	while (rockchip_cpu_debug[i])
diff --git a/kernel/drivers/soc/rockchip/rockchip_disable_unused.c b/kernel/drivers/soc/rockchip/rockchip_disable_unused.c
new file mode 100644
index 0000000..5f9a9b3
--- /dev/null
+++ b/kernel/drivers/soc/rockchip/rockchip_disable_unused.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd
+ */
+
+#include <linux/module.h>
+#include <soc/rockchip/pm_domains.h>
+#include <../drivers/clk/rockchip/clk.h>
+
+#ifdef MODULE
+static int __init rockchip_disable_unused_driver_init(void)
+{
+	rockchip_pd_disable_unused();
+	rockchip_clk_disable_unused();
+	rockchip_clk_unprotect();
+
+	return 0;
+}
+module_init(rockchip_disable_unused_driver_init);
+
+MODULE_AUTHOR("Elaine Zhang <zhangqing@rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip driver for disable unused clk and power domain");
+MODULE_LICENSE("GPL");
+#endif
diff --git a/kernel/drivers/soc/rockchip/rockchip_opp_select.c b/kernel/drivers/soc/rockchip/rockchip_opp_select.c
index 8caae5c..6c496ad 100644
--- a/kernel/drivers/soc/rockchip/rockchip_opp_select.c
+++ b/kernel/drivers/soc/rockchip/rockchip_opp_select.c
@@ -12,6 +12,7 @@
 #include <linux/nvmem-consumer.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <linux/rockchip/rockchip_sip.h>
 #include <linux/slab.h>
 #include <linux/soc/rockchip/pvtm.h>
 #include <linux/thermal.h>
@@ -1004,15 +1005,15 @@
 	}
 
 	if (of_property_read_u32(np, "rockchip,pvtpll-len-min-rate", &min_rate))
-		return;
+		goto out;
 	if (of_property_read_u32(np, "rockchip,pvtpll-len-max-rate", &max_rate))
-		return;
+		goto out;
 	if (of_property_read_u32(np, "rockchip,pvtpll-len-margin", &margin))
-		return;
+		goto out;
 
 	opp_table = dev_pm_opp_get_opp_table(info->dev);
 	if (!opp_table)
-		return;
+		goto out;
 	old_rate = clk_get_rate(opp_table->clk);
 	opp_flag = OPP_ADD_LENGTH | ((margin & OPP_LENGTH_MASK) << OPP_LENGTH_SHIFT);
 
@@ -1033,8 +1034,97 @@
 	clk_set_rate(opp_table->clk, old_rate);
 
 	dev_pm_opp_put_opp_table(opp_table);
+out:
+	of_node_put(np);
 }
 EXPORT_SYMBOL(rockchip_pvtpll_add_length);
+
+void rockchip_init_pvtpll_table(struct rockchip_opp_info *info, int bin)
+{
+	struct device_node *np = NULL;
+	struct property *prop = NULL;
+	struct of_phandle_args clkspec = { 0 };
+	struct arm_smccc_res res;
+	char prop_name[NAME_MAX];
+	u32 *value;
+	int count;
+	int ret, i;
+
+	if (!info)
+		return;
+
+	np = of_parse_phandle(info->dev->of_node, "operating-points-v2", 0);
+	if (!np) {
+		dev_warn(info->dev, "OPP-v2 not supported\n");
+		return;
+	}
+
+	ret = of_parse_phandle_with_args(info->dev->of_node, "clocks",
+					"#clock-cells", 0, &clkspec);
+	if (ret)
+		goto out;
+	info->pvtpll_clk_id = clkspec.args[0];
+	of_node_put(clkspec.np);
+
+	res = sip_smc_get_pvtpll_info(PVTPLL_GET_INFO, info->pvtpll_clk_id);
+	if (res.a0)
+		goto out;
+	if (!res.a1)
+		info->pvtpll_low_temp = true;
+
+	if (bin > 0) {
+		snprintf(prop_name, sizeof(prop_name),
+			 "rockchip,pvtpll-table-B%d", bin);
+		prop = of_find_property(np, prop_name, NULL);
+	}
+	if (!prop)
+		sprintf(prop_name, "rockchip,pvtpll-table");
+
+	prop = of_find_property(np, prop_name, NULL);
+	if (!prop)
+		goto out;
+
+	count = of_property_count_u32_elems(np, prop_name);
+	if (count < 0) {
+		dev_err(info->dev, "%s: Invalid %s property (%d)\n",
+			__func__, prop_name, count);
+		goto out;
+	} else if (count % 5) {
+		dev_err(info->dev, "Invalid count of %s\n", prop_name);
+		goto out;
+	}
+
+	value = kmalloc_array(count, sizeof(*value), GFP_KERNEL);
+	if (!value)
+		goto out;
+	ret = of_property_read_u32_array(np, prop_name, value, count);
+	if (ret) {
+		dev_err(info->dev, "%s: error parsing %s: %d\n",
+			__func__, prop_name, ret);
+		goto free_value;
+	}
+
+	for (i = 0; i < count; i += 5) {
+		res = sip_smc_pvtpll_config(PVTPLL_ADJUST_TABLE,
+					    info->pvtpll_clk_id, value[i],
+					    value[i + 1], value[i + 2],
+					    value[i + 3], value[i + 4]);
+		if (res.a0) {
+			dev_err(info->dev,
+				"%s: error cfg clk_id=%u %u %u %u %u %u (%d)\n",
+				__func__, info->pvtpll_clk_id, value[i],
+				value[i + 1], value[i + 2], value[i + 3],
+				value[i + 4], (int)res.a0);
+			goto free_value;
+		}
+	}
+
+free_value:
+	kfree(value);
+out:
+	of_node_put(np);
+}
+EXPORT_SYMBOL(rockchip_init_pvtpll_table);
 
 static int rockchip_get_pvtm_pvtpll(struct device *dev, struct device_node *np,
 				    char *reg_name)
@@ -1186,10 +1276,15 @@
 		snprintf(name, sizeof(name),
 			 "rockchip,p%d-pvtm-voltage-sel", process);
 		prop = of_find_property(np, name, NULL);
-	} else if (bin >= 0) {
+	} else if (bin > 0) {
 		of_property_read_u32(np, "rockchip,pvtm-hw", &hw);
 		if (hw && (hw & BIT(bin))) {
 			sprintf(name, "rockchip,pvtm-voltage-sel-hw");
+			prop = of_find_property(np, name, NULL);
+		}
+		if (!prop) {
+			snprintf(name, sizeof(name),
+				 "rockchip,pvtm-voltage-sel-B%d", bin);
 			prop = of_find_property(np, name, NULL);
 		}
 	}
@@ -1633,6 +1728,10 @@
 	rockchip_adjust_opp_by_irdrop(dev, np, &safe_rate, &max_rate);
 
 	dev_info(dev, "avs=%d\n", avs);
+
+	if (!safe_rate && !scale)
+		goto out_np;
+
 	clk = of_clk_get_by_name(np, NULL);
 	if (IS_ERR(clk)) {
 		if (!safe_rate)
@@ -1646,14 +1745,14 @@
 
 	if (safe_rate)
 		irdrop_scale = rockchip_pll_clk_rate_to_scale(clk, safe_rate);
-	if (max_rate)
-		opp_scale = rockchip_pll_clk_rate_to_scale(clk, max_rate);
 	target_scale = max(irdrop_scale, scale);
 	if (target_scale <= 0)
 		goto out_clk;
 	dev_dbg(dev, "target_scale=%d, irdrop_scale=%d, scale=%d\n",
 		target_scale, irdrop_scale, scale);
 
+	if (max_rate)
+		opp_scale = rockchip_pll_clk_rate_to_scale(clk, max_rate);
 	if (avs == AVS_SCALING_RATE) {
 		ret = rockchip_pll_clk_adaptive_scaling(clk, target_scale);
 		if (ret)
@@ -1838,13 +1937,78 @@
 }
 EXPORT_SYMBOL(rockchip_set_intermediate_rate);
 
+static int rockchip_get_opp_clk(struct device *dev, struct device_node *np,
+				struct rockchip_opp_info *info)
+{
+	struct clk_bulk_data *clks;
+	struct of_phandle_args clkspec;
+	int ret = 0, num_clks = 0, i;
+
+	if (of_find_property(np, "rockchip,opp-clocks", NULL)) {
+		num_clks = of_count_phandle_with_args(np, "rockchip,opp-clocks",
+						      "#clock-cells");
+		if (num_clks <= 0)
+			return 0;
+		clks = devm_kcalloc(dev, num_clks, sizeof(*clks), GFP_KERNEL);
+		if (!clks)
+			return -ENOMEM;
+		for (i = 0; i < num_clks; i++) {
+			ret = of_parse_phandle_with_args(np,
+							 "rockchip,opp-clocks",
+							 "#clock-cells", i,
+							 &clkspec);
+			if (ret < 0) {
+				dev_err(dev, "%s: failed to parse opp clk %d\n",
+					np->name, i);
+				goto error;
+			}
+			clks[i].clk = of_clk_get_from_provider(&clkspec);
+			of_node_put(clkspec.np);
+			if (IS_ERR(clks[i].clk)) {
+				ret = PTR_ERR(clks[i].clk);
+				clks[i].clk = NULL;
+				dev_err(dev, "%s: failed to get opp clk %d\n",
+					np->name, i);
+				goto error;
+			}
+		}
+	} else {
+		num_clks = of_clk_get_parent_count(np);
+		if (num_clks <= 0)
+			return 0;
+		clks = devm_kcalloc(dev, num_clks, sizeof(*clks), GFP_KERNEL);
+		if (!clks)
+			return -ENOMEM;
+		for (i = 0; i < num_clks; i++) {
+			clks[i].clk = of_clk_get(np, i);
+			if (IS_ERR(clks[i].clk)) {
+				ret = PTR_ERR(clks[i].clk);
+				clks[i].clk = NULL;
+				dev_err(dev, "%s: failed to get clk %d\n",
+					np->name, i);
+				goto error;
+			}
+		}
+	}
+	info->clks = clks;
+	info->num_clks = num_clks;
+
+	return 0;
+error:
+	while (--i >= 0)
+		clk_put(clks[i].clk);
+	devm_kfree(dev, clks);
+
+	return ret;
+}
+
 int rockchip_init_opp_table(struct device *dev, struct rockchip_opp_info *info,
 			    char *lkg_name, char *reg_name)
 {
 	struct device_node *np;
 	int bin = -EINVAL, process = -EINVAL;
 	int scale = 0, volt_sel = -EINVAL;
-	int ret = 0, num_clks = 0, i;
+	int ret = 0;
 	u32 freq;
 
 	/* Get OPP descriptor node */
@@ -1857,24 +2021,10 @@
 		goto next;
 	info->dev = dev;
 
-	num_clks = of_clk_get_parent_count(np);
-	if (num_clks > 0) {
-		info->clks = devm_kcalloc(dev, num_clks, sizeof(*info->clks),
-					  GFP_KERNEL);
-		if (!info->clks) {
-			ret = -ENOMEM;
-			goto out;
-		}
-		for (i = 0; i < num_clks; i++) {
-			info->clks[i].clk = of_clk_get(np, i);
-			if (IS_ERR(info->clks[i].clk)) {
-				ret = PTR_ERR(info->clks[i].clk);
-				dev_err(dev, "%s: failed to get clk %d\n",
-					np->name, i);
-				goto out;
-			}
-		}
-		info->num_clks = num_clks;
+	ret = rockchip_get_opp_clk(dev, np, info);
+	if (ret)
+		goto out;
+	if (info->clks) {
 		ret = clk_bulk_prepare_enable(info->num_clks, info->clks);
 		if (ret) {
 			dev_err(dev, "failed to enable opp clks\n");
@@ -1900,6 +2050,7 @@
 
 next:
 	rockchip_get_soc_info(dev, np, &bin, &process);
+	rockchip_init_pvtpll_table(info, bin);
 	rockchip_get_scale_volt_sel(dev, lkg_name, reg_name, bin, process,
 				    &scale, &volt_sel);
 	if (info && info->data && info->data->set_soc_info)
@@ -1925,6 +2076,31 @@
 }
 EXPORT_SYMBOL(rockchip_init_opp_table);
 
+void rockchip_uninit_opp_table(struct device *dev, struct rockchip_opp_info *info)
+{
+	struct opp_table *opp_table;
+
+	if (info) {
+		kfree(info->opp_table);
+		info->opp_table = NULL;
+		devm_kfree(dev, info->clks);
+		info->clks = NULL;
+		devm_kfree(dev, info->volt_rm_tbl);
+		info->volt_rm_tbl = NULL;
+	}
+
+	opp_table = dev_pm_opp_get_opp_table(dev);
+	if (IS_ERR(opp_table))
+		return;
+	dev_pm_opp_of_remove_table(dev);
+	if (opp_table->prop_name)
+		dev_pm_opp_put_prop_name(opp_table);
+	if (opp_table->supported_hw)
+		dev_pm_opp_put_supported_hw(opp_table);
+	dev_pm_opp_put_opp_table(opp_table);
+}
+EXPORT_SYMBOL(rockchip_uninit_opp_table);
+
 MODULE_DESCRIPTION("ROCKCHIP OPP Select");
 MODULE_AUTHOR("Finley Xiao <finley.xiao@rock-chips.com>, Liang Chen <cl@rock-chips.com>");
 MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/soc/rockchip/rockchip_pm_config.c b/kernel/drivers/soc/rockchip/rockchip_pm_config.c
index 13427dd..c319b79 100644
--- a/kernel/drivers/soc/rockchip/rockchip_pm_config.c
+++ b/kernel/drivers/soc/rockchip/rockchip_pm_config.c
@@ -17,6 +17,7 @@
 #include <linux/pm.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
+#include <linux/rockchip/rockchip_pm_config.h>
 #include <linux/rockchip/rockchip_sip.h>
 #include <linux/suspend.h>
 #include <dt-bindings/input/input.h>
@@ -51,11 +52,6 @@
 } on_off_regs_list[RK_PM_STATE_MAX];
 #endif
 
-static struct rk_sleep_config {
-	u32 mode_config;
-	u32 wakeup_config;
-} sleep_config[RK_PM_STATE_MAX];
-
 /* rk_tag related defines */
 #define sleep_tag_next(t)	\
 	((struct rk_sleep_tag *)((__u32 *)(t) + (t)->hdr.size))
@@ -81,7 +77,10 @@
 	struct rk_sleep_tag slp_tags;
 };
 
+struct rk_sleep_config *sleep_config;
+
 static const struct of_device_id pm_match_table[] = {
+	{ .compatible = "rockchip,pm-config",},
 	{ .compatible = "rockchip,pm-px30",},
 	{ .compatible = "rockchip,pm-rk1808",},
 	{ .compatible = "rockchip,pm-rk322x",},
@@ -253,6 +252,18 @@
 
 	return 0;
 }
+
+const struct rk_sleep_config *rockchip_get_cur_sleep_config(void)
+{
+	suspend_state_t suspend_state = mem_sleep_current;
+	enum rk_pm_state state = suspend_state - PM_SUSPEND_MEM;
+
+	if (state >= RK_PM_STATE_MAX)
+		return NULL;
+
+	return &sleep_config[state];
+}
+EXPORT_SYMBOL_GPL(rockchip_get_cur_sleep_config);
 #endif
 
 static int parse_mcu_sleep_config(struct device_node *node)
@@ -364,17 +375,43 @@
 	return ret;
 }
 
+static int parse_io_config(struct device *dev)
+{
+	int ret = 0, cnt;
+	struct device_node *node = dev->of_node;
+	struct rk_sleep_config *config = &sleep_config[RK_PM_MEM];
+
+	cnt = of_property_count_u32_elems(node, "rockchip,sleep-io-config");
+	if (cnt > 0) {
+		/* 0 as the last element of virtual_pwroff_irqs */
+		config->sleep_io_config =
+			devm_kmalloc_array(dev, cnt, sizeof(u32), GFP_KERNEL);
+		if (!config->sleep_io_config) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		ret = of_property_read_u32_array(node, "rockchip,sleep-io-config",
+						 config->sleep_io_config, cnt);
+		if (ret) {
+			dev_err(dev, "get rockchip,sleep-io-config error\n");
+			goto out;
+		}
+
+		config->sleep_io_config_cnt = cnt;
+	} else {
+		dev_dbg(dev, "not set sleep-pin-config\n");
+	}
+
+out:
+	return ret;
+}
+
 static int pm_config_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *match_id;
 	struct device_node *node;
-	struct rk_sleep_config *config = &sleep_config[RK_PM_MEM];
-	u32 pwm_regulator_config = 0;
-	int gpio_temp[10];
-	u32 sleep_debug_en = 0;
-	u32 apios_suspend = 0;
-	u32 io_ret_config = 0;
-	u32 sleep_pin_config[2] = {0};
+	struct rk_sleep_config *config;
 
 	enum of_gpio_flags flags;
 	int i = 0;
@@ -392,6 +429,14 @@
 		return -ENODEV;
 	}
 
+	sleep_config =
+		devm_kmalloc_array(&pdev->dev, RK_PM_STATE_MAX,
+				   sizeof(*sleep_config), GFP_KERNEL);
+	if (!sleep_config)
+		return -ENOMEM;
+
+	config = &sleep_config[RK_PM_MEM];
+
 	if (of_property_read_u32_array(node,
 				       "rockchip,sleep-mode-config",
 				       &config->mode_config, 1))
@@ -408,48 +453,56 @@
 
 	if (of_property_read_u32_array(node,
 				       "rockchip,pwm-regulator-config",
-				       &pwm_regulator_config, 1))
+				       &config->pwm_regulator_config, 1))
 		dev_warn(&pdev->dev, "not set pwm-regulator-config\n");
 	else
 		sip_smc_set_suspend_mode(PWM_REGULATOR_CONFIG,
-					 pwm_regulator_config,
+					 config->pwm_regulator_config,
 					 0);
 
 	length = of_gpio_named_count(node, "rockchip,power-ctrl");
 
 	if (length > 0 && length < 10) {
+		config->power_ctrl_config_cnt = length;
+		config->power_ctrl_config =
+			devm_kmalloc_array(&pdev->dev, length,
+					   sizeof(u32), GFP_KERNEL);
+		if (!config->power_ctrl_config)
+			return -ENOMEM;
+
 		for (i = 0; i < length; i++) {
-			gpio_temp[i] = of_get_named_gpio_flags(node,
-							     "rockchip,power-ctrl",
-							     i,
-							     &flags);
-			if (!gpio_is_valid(gpio_temp[i]))
+			config->power_ctrl_config[i] =
+				of_get_named_gpio_flags(node,
+							"rockchip,power-ctrl",
+							i,
+							&flags);
+			if (!gpio_is_valid(config->power_ctrl_config[i]))
 				break;
 			sip_smc_set_suspend_mode(GPIO_POWER_CONFIG,
 						 i,
-						 gpio_temp[i]);
+						 config->power_ctrl_config[i]);
 		}
 	}
 	sip_smc_set_suspend_mode(GPIO_POWER_CONFIG, i, PM_INVALID_GPIO);
 
 	if (!of_property_read_u32_array(node,
 					"rockchip,sleep-debug-en",
-					&sleep_debug_en, 1))
+					&config->sleep_debug_en, 1))
 		sip_smc_set_suspend_mode(SUSPEND_DEBUG_ENABLE,
-					 sleep_debug_en,
+					 config->sleep_debug_en,
 					 0);
 
 	if (!of_property_read_u32_array(node,
 					"rockchip,apios-suspend",
-					&apios_suspend, 1))
+					&config->apios_suspend, 1))
 		sip_smc_set_suspend_mode(APIOS_SUSPEND_CONFIG,
-					 apios_suspend,
+					 config->apios_suspend,
 					 0);
 
 	if (!of_property_read_u32_array(node,
 					"rockchip,sleep-io-ret-config",
-					&io_ret_config, 1)) {
-		ret = sip_smc_set_suspend_mode(SUSPEND_IO_RET_CONFIG, io_ret_config, 0);
+					&config->io_ret_config, 1)) {
+		ret = sip_smc_set_suspend_mode(SUSPEND_IO_RET_CONFIG, config->io_ret_config, 0);
 		if (ret)
 			dev_warn(&pdev->dev,
 				 "sleep-io-ret-config failed (%d), check parameters or update trust\n",
@@ -458,14 +511,17 @@
 
 	if (!of_property_read_u32_array(node,
 					"rockchip,sleep-pin-config",
-					sleep_pin_config, 2)) {
-		ret = sip_smc_set_suspend_mode(SLEEP_PIN_CONFIG, sleep_pin_config[0], sleep_pin_config[1]);
+					config->sleep_pin_config, 2)) {
+		ret = sip_smc_set_suspend_mode(SLEEP_PIN_CONFIG,
+					       config->sleep_pin_config[0],
+					       config->sleep_pin_config[1]);
 		if (ret)
 			dev_warn(&pdev->dev,
 				 "sleep-pin-config failed (%d), check parameters or update trust\n",
 				 ret);
 	}
 
+	parse_io_config(&pdev->dev);
 	parse_mcu_sleep_config(node);
 
 #ifndef MODULE
diff --git a/kernel/drivers/soc/rockchip/rockchip_system_monitor.c b/kernel/drivers/soc/rockchip/rockchip_system_monitor.c
index 4082565..c2fbb66 100644
--- a/kernel/drivers/soc/rockchip/rockchip_system_monitor.c
+++ b/kernel/drivers/soc/rockchip/rockchip_system_monitor.c
@@ -4,7 +4,6 @@
  * Author: Finley Xiao <finley.xiao@rock-chips.com>
  */
 
-#include <dt-bindings/soc/rockchip-system-status.h>
 #include <linux/clk-provider.h>
 #include <linux/cpu.h>
 #include <linux/cpufreq.h>
@@ -24,6 +23,7 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/reboot.h>
+#include <linux/rockchip/rockchip_sip.h>
 #include <linux/slab.h>
 #include <linux/suspend.h>
 #include <linux/thermal.h>
@@ -246,34 +246,6 @@
 	return video_info;
 }
 
-static struct video_info *rockchip_find_video_info(const char *buf)
-{
-	struct video_info *info, *video_info;
-
-	video_info = rockchip_parse_video_info(buf);
-
-	if (!video_info)
-		return NULL;
-
-	mutex_lock(&video_info_mutex);
-	list_for_each_entry(info, &video_info_list, node) {
-		if (info->width == video_info->width &&
-		    info->height == video_info->height &&
-		    info->ishevc == video_info->ishevc &&
-		    info->videoFramerate == video_info->videoFramerate &&
-		    info->streamBitrate == video_info->streamBitrate) {
-			mutex_unlock(&video_info_mutex);
-			kfree(video_info);
-			return info;
-		}
-	}
-
-	mutex_unlock(&video_info_mutex);
-	kfree(video_info);
-
-	return NULL;
-}
-
 static void rockchip_add_video_info(struct video_info *video_info)
 {
 	if (video_info) {
@@ -285,12 +257,25 @@
 
 static void rockchip_del_video_info(struct video_info *video_info)
 {
-	if (video_info) {
-		mutex_lock(&video_info_mutex);
-		list_del(&video_info->node);
-		mutex_unlock(&video_info_mutex);
-		kfree(video_info);
+	struct video_info *info, *tmp;
+
+	if (!video_info)
+		return;
+
+	mutex_lock(&video_info_mutex);
+	list_for_each_entry_safe(info, tmp, &video_info_list, node) {
+		if (info->width == video_info->width &&
+		    info->height == video_info->height &&
+		    info->ishevc == video_info->ishevc &&
+		    info->videoFramerate == video_info->videoFramerate &&
+		    info->streamBitrate == video_info->streamBitrate) {
+			list_del(&info->node);
+			kfree(info);
+			break;
+		}
 	}
+	kfree(video_info);
+	mutex_unlock(&video_info_mutex);
 }
 
 static void rockchip_update_video_info(void)
@@ -338,7 +323,7 @@
 	switch (buf[0]) {
 	case '0':
 		/* clear video flag */
-		video_info = rockchip_find_video_info(buf);
+		video_info = rockchip_parse_video_info(buf);
 		if (video_info) {
 			rockchip_del_video_info(video_info);
 			rockchip_update_video_info();
@@ -920,6 +905,7 @@
 				     bool is_low)
 {
 	struct monitor_dev_profile *devp = info->devp;
+	struct arm_smccc_res res;
 	int ret = 0;
 
 	dev_dbg(info->dev, "low_temp %d\n", is_low);
@@ -934,6 +920,17 @@
 
 	if (devp->update_volt)
 		devp->update_volt(info);
+
+	if (devp->opp_info && devp->opp_info->pvtpll_low_temp) {
+		res = sip_smc_pvtpll_config(PVTPLL_LOW_TEMP,
+					    devp->opp_info->pvtpll_clk_id,
+					    is_low, 0, 0, 0, 0);
+		if (res.a0)
+			dev_err(info->dev,
+				"%s: error cfg id=%u low temp %d (%d)\n",
+				__func__, devp->opp_info->pvtpll_clk_id,
+				is_low, (int)res.a0);
+	}
 }
 
 static void rockchip_high_temp_adjust(struct monitor_dev_info *info,
@@ -1338,6 +1335,15 @@
 		rockchip_set_intermediate_rate(dev, opp_info, info->clk,
 					       old_rate, new_rate,
 					       true, is_set_clk);
+
+		if (old_volt > new_volt) {
+			ret = regulator_set_voltage(vdd_reg, new_volt, INT_MAX);
+			if (ret) {
+				dev_err(dev, "%s: failed to set volt: %lu\n",
+					__func__, new_volt);
+				goto restore_voltage;
+			}
+		}
 		if (info->regulator_count > 1) {
 			ret = regulator_set_voltage(mem_reg, new_mem_volt,
 						    INT_MAX);
@@ -1347,11 +1353,13 @@
 				goto restore_voltage;
 			}
 		}
-		ret = regulator_set_voltage(vdd_reg, new_volt, INT_MAX);
-		if (ret) {
-			dev_err(dev, "%s: failed to set volt: %lu\n",
-				__func__, new_volt);
-			goto restore_voltage;
+		if (old_volt <= new_volt) {
+			ret = regulator_set_voltage(vdd_reg, new_volt, INT_MAX);
+			if (ret) {
+				dev_err(dev, "%s: failed to set volt: %lu\n",
+					__func__, new_volt);
+				goto restore_voltage;
+			}
 		}
 		rockchip_set_read_margin(dev, opp_info, target_rm, is_set_rm);
 		if (is_set_clk && clk_set_rate(info->clk, new_rate)) {
@@ -1396,9 +1404,12 @@
 	rockchip_get_read_margin(dev, opp_info, old_volt, &target_rm);
 	rockchip_set_read_margin(dev, opp_info, target_rm, is_set_rm);
 restore_voltage:
+	if (old_volt <= new_volt)
+		regulator_set_voltage(vdd_reg, old_volt, INT_MAX);
 	if (info->regulator_count > 1)
 		regulator_set_voltage(mem_reg, old_mem_volt, INT_MAX);
-	regulator_set_voltage(vdd_reg, old_volt, INT_MAX);
+	if (old_volt > new_volt)
+		regulator_set_voltage(vdd_reg, old_volt, INT_MAX);
 disable_clk:
 	rockchip_monitor_disable_opp_clk(dev, opp_info);
 unlock:
diff --git a/kernel/drivers/soc/rockchip/rockchip_thunderboot_mmc.c b/kernel/drivers/soc/rockchip/rockchip_thunderboot_mmc.c
index ba16186..1061881 100644
--- a/kernel/drivers/soc/rockchip/rockchip_thunderboot_mmc.c
+++ b/kernel/drivers/soc/rockchip/rockchip_thunderboot_mmc.c
@@ -2,6 +2,7 @@
 /*
  * Copyright (C) 2020 Rockchip Electronics Co., Ltd.
  */
+#include <linux/clk.h>
 #include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/kthread.h>
@@ -27,6 +28,8 @@
 	struct resource *res;
 	struct device_node *rds, *rdd, *dma;
 	struct device *dev = &pdev->dev;
+	struct clk_bulk_data *clk_bulks;
+	int clk_num;
 	u32 status;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -39,6 +42,18 @@
 	rds = of_parse_phandle(dev->of_node, "memory-region-src", 0);
 	rdd = of_parse_phandle(dev->of_node, "memory-region-dst", 0);
 	dma = of_parse_phandle(dev->of_node, "memory-region-idmac", 0);
+
+	clk_num = clk_bulk_get_all(&pdev->dev, &clk_bulks);
+	if (clk_num >= 0) {
+		ret = clk_bulk_prepare_enable(clk_num, clk_bulks);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to enable clocks\n");
+			return ret;
+		}
+	} else {
+		dev_err(&pdev->dev, "failed to get clks property\\n");
+		return clk_num;
+	}
 
 	if (readl_poll_timeout(regs + SDMMC_STATUS, status,
 			       !(status & (BIT(10) | GENMASK(7, 4))), 100,
@@ -95,6 +110,8 @@
 	}
 
 out:
+	clk_bulk_disable_unprepare(clk_num, clk_bulks);
+	clk_bulk_put_all(clk_num, clk_bulks);
 	of_node_put(rds);
 	of_node_put(rdd);
 	of_node_put(dma);
diff --git a/kernel/drivers/soc/rockchip/rockchip_thunderboot_service.c b/kernel/drivers/soc/rockchip/rockchip_thunderboot_service.c
index d1420d1..6002d64 100644
--- a/kernel/drivers/soc/rockchip/rockchip_thunderboot_service.c
+++ b/kernel/drivers/soc/rockchip/rockchip_thunderboot_service.c
@@ -24,6 +24,7 @@
 	struct reset_control *rsts;
 	phys_addr_t mem_start;
 	size_t mem_size;
+	bool mem_no_free;
 };
 
 static atomic_t mcu_done = ATOMIC_INIT(0);
@@ -89,7 +90,8 @@
 
 		start = phys_to_virt(serv->mem_start);
 		end = start + serv->mem_size;
-		free_reserved_area(start, end, -1, "rtos");
+		if (!serv->mem_no_free)
+			free_reserved_area(start, end, -1, "rtos");
 
 		spin_lock(&lock);
 		if (atomic_read(&mcu_done)) {
@@ -150,6 +152,8 @@
 	if (IS_ERR(serv->rsts) && PTR_ERR(serv->rsts) == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
+	serv->mem_no_free = device_property_read_bool(&pdev->dev, "memory-no-free");
+
 	platform_set_drvdata(pdev, serv);
 
 	mbox_cl = &serv->mbox_cl;
diff --git a/kernel/drivers/soc/ti/knav_qmss_queue.c b/kernel/drivers/soc/ti/knav_qmss_queue.c
index 53e36d4..20c8474 100644
--- a/kernel/drivers/soc/ti/knav_qmss_queue.c
+++ b/kernel/drivers/soc/ti/knav_qmss_queue.c
@@ -67,7 +67,7 @@
  * 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)
@@ -1782,9 +1782,9 @@
 	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);
+		pm_runtime_disable(&pdev->dev);
 		dev_err(dev, "Failed to enable QMSS\n");
 		return ret;
 	}
diff --git a/kernel/drivers/soc/ti/pm33xx.c b/kernel/drivers/soc/ti/pm33xx.c
index dc21aa8..44ec004 100644
--- a/kernel/drivers/soc/ti/pm33xx.c
+++ b/kernel/drivers/soc/ti/pm33xx.c
@@ -19,6 +19,7 @@
 #include <linux/of_address.h>
 #include <linux/platform_data/pm33xx.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/rtc.h>
 #include <linux/rtc/rtc-omap.h>
 #include <linux/sizes.h>
@@ -528,7 +529,7 @@
 
 	ret = am33xx_pm_alloc_sram();
 	if (ret)
-		return ret;
+		goto err_wkup_m3_ipc_put;
 
 	ret = am33xx_pm_rtc_setup();
 	if (ret)
@@ -555,28 +556,41 @@
 	suspend_wfi_flags |= WFI_FLAG_WAKE_M3;
 #endif /* CONFIG_SUSPEND */
 
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(dev);
+		goto err_pm_runtime_disable;
+	}
+
 	ret = pm_ops->init(am33xx_do_sram_idle);
 	if (ret) {
 		dev_err(dev, "Unable to call core pm init!\n");
 		ret = -ENODEV;
-		goto err_put_wkup_m3_ipc;
+		goto err_pm_runtime_put;
 	}
 
 	return 0;
 
-err_put_wkup_m3_ipc:
-	wkup_m3_ipc_put(m3_ipc);
+err_pm_runtime_put:
+	pm_runtime_put_sync(dev);
+err_pm_runtime_disable:
+	pm_runtime_disable(dev);
 err_unsetup_rtc:
 	iounmap(rtc_base_virt);
 	clk_put(rtc_fck);
 err_free_sram:
 	am33xx_pm_free_sram();
 	pm33xx_dev = NULL;
+err_wkup_m3_ipc_put:
+	wkup_m3_ipc_put(m3_ipc);
 	return ret;
 }
 
 static int am33xx_pm_remove(struct platform_device *pdev)
 {
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
 	if (pm_ops->deinit)
 		pm_ops->deinit();
 	suspend_set_ops(NULL);
diff --git a/kernel/drivers/soc/ti/smartreflex.c b/kernel/drivers/soc/ti/smartreflex.c
index 5376f3d..1228a0c 100644
--- a/kernel/drivers/soc/ti/smartreflex.c
+++ b/kernel/drivers/soc/ti/smartreflex.c
@@ -942,6 +942,7 @@
 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);
diff --git a/kernel/drivers/soc/ux500/ux500-soc-id.c b/kernel/drivers/soc/ux500/ux500-soc-id.c
index a9472e0..27d6e25 100644
--- a/kernel/drivers/soc/ux500/ux500-soc-id.c
+++ b/kernel/drivers/soc/ux500/ux500-soc-id.c
@@ -167,20 +167,18 @@
 static const char *db8500_read_soc_id(struct device_node *backupram)
 {
 	void __iomem *base;
-	void __iomem *uid;
 	const char *retstr;
+	u32 uid[5];
 
 	base = of_iomap(backupram, 0);
 	if (!base)
 		return NULL;
-	uid = base + 0x1fc0;
+	memcpy_fromio(uid, base + 0x1fc0, sizeof(uid));
 
 	/* Throw these device-specific numbers into the entropy pool */
-	add_device_randomness(uid, 0x14);
+	add_device_randomness(uid, sizeof(uid));
 	retstr = kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x",
-			 readl((u32 *)uid+0),
-			 readl((u32 *)uid+1), readl((u32 *)uid+2),
-			 readl((u32 *)uid+3), readl((u32 *)uid+4));
+			   uid[0], uid[1], uid[2], uid[3], uid[4]);
 	iounmap(base);
 	return retstr;
 }
diff --git a/kernel/drivers/soundwire/bus.c b/kernel/drivers/soundwire/bus.c
index 3317a02..0e0a190 100644
--- a/kernel/drivers/soundwire/bus.c
+++ b/kernel/drivers/soundwire/bus.c
@@ -797,19 +797,19 @@
 
 	if (status == SDW_SLAVE_UNATTACHED) {
 		dev_dbg(&slave->dev,
-			"%s: initializing completion for Slave %d\n",
+			"%s: initializing enumeration and init completion for Slave %d\n",
 			__func__, slave->dev_num);
 
-		init_completion(&slave->enumeration_complete);
-		init_completion(&slave->initialization_complete);
+		reinit_completion(&slave->enumeration_complete);
+		reinit_completion(&slave->initialization_complete);
 
 	} else if ((status == SDW_SLAVE_ATTACHED) &&
 		   (slave->status == SDW_SLAVE_UNATTACHED)) {
 		dev_dbg(&slave->dev,
-			"%s: signaling completion for Slave %d\n",
+			"%s: signaling enumeration completion for Slave %d\n",
 			__func__, slave->dev_num);
 
-		complete(&slave->enumeration_complete);
+		complete_all(&slave->enumeration_complete);
 	}
 	slave->status = status;
 	mutex_unlock(&slave->bus->bus_lock);
@@ -1734,8 +1734,25 @@
 		if (ret)
 			dev_err(slave->bus->dev,
 				"Update Slave status failed:%d\n", ret);
-		if (attached_initializing)
-			complete(&slave->initialization_complete);
+		if (attached_initializing) {
+			dev_dbg(&slave->dev,
+				"%s: signaling initialization completion for Slave %d\n",
+				__func__, slave->dev_num);
+
+			complete_all(&slave->initialization_complete);
+
+			/*
+			 * If the manager became pm_runtime active, the peripherals will be
+			 * restarted and attach, but their pm_runtime status may remain
+			 * suspended. If the 'update_slave_status' callback initiates
+			 * any sort of deferred processing, this processing would not be
+			 * cancelled on pm_runtime suspend.
+			 * To avoid such zombie states, we queue a request to resume.
+			 * This would be a no-op in case the peripheral was being resumed
+			 * by e.g. the ALSA/ASoC framework.
+			 */
+			pm_request_resume(&slave->dev);
+		}
 	}
 
 	return ret;
diff --git a/kernel/drivers/soundwire/cadence_master.c b/kernel/drivers/soundwire/cadence_master.c
index a324769..18e7d15 100644
--- a/kernel/drivers/soundwire/cadence_master.c
+++ b/kernel/drivers/soundwire/cadence_master.c
@@ -511,6 +511,29 @@
 	return SDW_CMD_OK;
 }
 
+static void cdns_read_response(struct sdw_cdns *cdns)
+{
+	u32 num_resp, cmd_base;
+	int i;
+
+	/* RX_FIFO_AVAIL can be 2 entries more than the FIFO size */
+	BUILD_BUG_ON(ARRAY_SIZE(cdns->response_buf) < CDNS_MCP_CMD_LEN + 2);
+
+	num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT);
+	num_resp &= CDNS_MCP_RX_FIFO_AVAIL;
+	if (num_resp > ARRAY_SIZE(cdns->response_buf)) {
+		dev_warn(cdns->dev, "RX AVAIL %d too long\n", num_resp);
+		num_resp = ARRAY_SIZE(cdns->response_buf);
+	}
+
+	cmd_base = CDNS_MCP_CMD_BASE;
+
+	for (i = 0; i < num_resp; i++) {
+		cdns->response_buf[i] = cdns_readl(cdns, cmd_base);
+		cmd_base += CDNS_MCP_CMD_WORD_LEN;
+	}
+}
+
 static enum sdw_command_response
 _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd,
 	       int offset, int count, bool defer)
@@ -552,6 +575,10 @@
 		dev_err(cdns->dev, "IO transfer timed out, cmd %d device %d addr %x len %d\n",
 			cmd, msg->dev_num, msg->addr, msg->len);
 		msg->len = 0;
+
+		/* Drain anything in the RX_FIFO */
+		cdns_read_response(cdns);
+
 		return SDW_CMD_TIMEOUT;
 	}
 
@@ -719,22 +746,6 @@
 /*
  * IRQ handling
  */
-
-static void cdns_read_response(struct sdw_cdns *cdns)
-{
-	u32 num_resp, cmd_base;
-	int i;
-
-	num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT);
-	num_resp &= CDNS_MCP_RX_FIFO_AVAIL;
-
-	cmd_base = CDNS_MCP_CMD_BASE;
-
-	for (i = 0; i < num_resp; i++) {
-		cdns->response_buf[i] = cdns_readl(cdns, cmd_base);
-		cmd_base += CDNS_MCP_CMD_WORD_LEN;
-	}
-}
 
 static int cdns_update_slave_status(struct sdw_cdns *cdns,
 				    u32 slave0, u32 slave1)
diff --git a/kernel/drivers/soundwire/cadence_master.h b/kernel/drivers/soundwire/cadence_master.h
index 4d1aab5..e7f0108 100644
--- a/kernel/drivers/soundwire/cadence_master.h
+++ b/kernel/drivers/soundwire/cadence_master.h
@@ -8,6 +8,12 @@
 #define SDW_CADENCE_GSYNC_KHZ		4 /* 4 kHz */
 #define SDW_CADENCE_GSYNC_HZ		(SDW_CADENCE_GSYNC_KHZ * 1000)
 
+/*
+ * The Cadence IP supports up to 32 entries in the FIFO, though implementations
+ * can configure the IP to have a smaller FIFO.
+ */
+#define CDNS_MCP_IP_MAX_CMD_LEN		32
+
 /**
  * struct sdw_cdns_pdi: PDI (Physical Data Interface) instance
  *
@@ -119,7 +125,12 @@
 	struct sdw_bus bus;
 	unsigned int instance;
 
-	u32 response_buf[0x80];
+	/*
+	 * The datasheet says the RX FIFO AVAIL can be 2 entries more
+	 * than the FIFO capacity, so allow for this.
+	 */
+	u32 response_buf[CDNS_MCP_IP_MAX_CMD_LEN + 2];
+
 	struct completion tx_complete;
 	struct sdw_defer *defer;
 
diff --git a/kernel/drivers/spi/Kconfig b/kernel/drivers/spi/Kconfig
index 7a2cb27..921667b 100644
--- a/kernel/drivers/spi/Kconfig
+++ b/kernel/drivers/spi/Kconfig
@@ -256,7 +256,6 @@
 	tristate "Baikal-T1 SPI driver for DW SPI core"
 	depends on MIPS_BAIKAL_T1 || COMPILE_TEST
 	select MULTIPLEXER
-	select MUX_MMIO
 	help
 	  Baikal-T1 SoC is equipped with three DW APB SSI-based MMIO SPI
 	  controllers. Two of them are pretty much normal: with IRQ, DMA,
@@ -663,6 +662,17 @@
 	  ROCKCHIP SFC supports DMA and PIO modes. When DMA is not available,
 	  the driver automatically falls back to PIO mode.
 
+config SPI_ROCKCHIP_SLAVE
+	tristate "Rockchip SPI Slave controller driver"
+	depends on ARCH_ROCKCHIP || COMPILE_TEST
+	default SPI_ROCKCHIP if !ROCKCHIP_MINI_KERNEL
+	help
+	  This selects a driver for Rockchip SPI Slave controller.
+
+	  If you say yes to this option, support will be included for Rockchip
+	  SPI Slave controller.
+	  Rockchip SPI Slave controller support DMA transport and IRQ mode.
+
 config SPI_RB4XX
 	tristate "Mikrotik RB4XX SPI master"
 	depends on SPI_MASTER && ATH79
diff --git a/kernel/drivers/spi/Makefile b/kernel/drivers/spi/Makefile
index d3f1082..404e522 100644
--- a/kernel/drivers/spi/Makefile
+++ b/kernel/drivers/spi/Makefile
@@ -94,6 +94,7 @@
 obj-$(CONFIG_SPI_QUP)			+= spi-qup.o
 obj-$(CONFIG_SPI_ROCKCHIP)		+= spi-rockchip.o
 obj-$(CONFIG_SPI_ROCKCHIP_SFC)		+= spi-rockchip-sfc.o
+obj-$(CONFIG_SPI_ROCKCHIP_SLAVE)	+= spi-rockchip-slave.o
 obj-$(CONFIG_SPI_RB4XX)			+= spi-rb4xx.o
 obj-$(CONFIG_SPI_RPCIF)			+= spi-rpc-if.o
 obj-$(CONFIG_SPI_RSPI)			+= spi-rspi.o
diff --git a/kernel/drivers/spi/spi-bcm-qspi.c b/kernel/drivers/spi/spi-bcm-qspi.c
index 766b003..2c734ea 100644
--- a/kernel/drivers/spi/spi-bcm-qspi.c
+++ b/kernel/drivers/spi/spi-bcm-qspi.c
@@ -1369,13 +1369,9 @@
 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 						   "mspi");
 
-	if (res) {
-		qspi->base[MSPI]  = devm_ioremap_resource(dev, res);
-		if (IS_ERR(qspi->base[MSPI]))
-			return PTR_ERR(qspi->base[MSPI]);
-	} else {
-		return 0;
-	}
+	qspi->base[MSPI]  = devm_ioremap_resource(dev, res);
+	if (IS_ERR(qspi->base[MSPI]))
+		return PTR_ERR(qspi->base[MSPI]);
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi");
 	if (res) {
diff --git a/kernel/drivers/spi/spi-bcm63xx-hsspi.c b/kernel/drivers/spi/spi-bcm63xx-hsspi.c
index 1f08d75..02f56fc 100644
--- a/kernel/drivers/spi/spi-bcm63xx-hsspi.c
+++ b/kernel/drivers/spi/spi-bcm63xx-hsspi.c
@@ -21,6 +21,7 @@
 #include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/reset.h>
+#include <linux/pm_runtime.h>
 
 #define HSSPI_GLOBAL_CTRL_REG			0x0
 #define GLOBAL_CTRL_CS_POLARITY_SHIFT		0
@@ -162,6 +163,7 @@
 	int step_size = HSSPI_BUFFER_LEN;
 	const u8 *tx = t->tx_buf;
 	u8 *rx = t->rx_buf;
+	u32 val = 0;
 
 	bcm63xx_hsspi_set_clk(bs, spi, t->speed_hz);
 	bcm63xx_hsspi_set_cs(bs, spi->chip_select, true);
@@ -177,11 +179,16 @@
 		step_size -= HSSPI_OPCODE_LEN;
 
 	if ((opcode == HSSPI_OP_READ && t->rx_nbits == SPI_NBITS_DUAL) ||
-	    (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL))
+	    (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL)) {
 		opcode |= HSSPI_OP_MULTIBIT;
 
-	__raw_writel(1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT |
-		     1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT | 0xff,
+		if (t->rx_nbits == SPI_NBITS_DUAL)
+			val |= 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT;
+		if (t->tx_nbits == SPI_NBITS_DUAL)
+			val |= 1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT;
+	}
+
+	__raw_writel(val | 0xff,
 		     bs->regs + HSSPI_PROFILE_MODE_CTRL_REG(chip_select));
 
 	while (pending > 0) {
@@ -439,13 +446,17 @@
 	if (ret)
 		goto out_put_master;
 
+	pm_runtime_enable(&pdev->dev);
+
 	/* register and we are done */
 	ret = devm_spi_register_master(dev, master);
 	if (ret)
-		goto out_put_master;
+		goto out_pm_disable;
 
 	return 0;
 
+out_pm_disable:
+	pm_runtime_disable(&pdev->dev);
 out_put_master:
 	spi_master_put(master);
 out_disable_pll_clk:
diff --git a/kernel/drivers/spi/spi-bcm63xx.c b/kernel/drivers/spi/spi-bcm63xx.c
index 96d075e..d36384f 100644
--- a/kernel/drivers/spi/spi-bcm63xx.c
+++ b/kernel/drivers/spi/spi-bcm63xx.c
@@ -126,7 +126,7 @@
 	SPI_MSG_DATA_SIZE,
 };
 
-#define BCM63XX_SPI_MAX_PREPEND		15
+#define BCM63XX_SPI_MAX_PREPEND		7
 
 #define BCM63XX_SPI_MAX_CS		8
 #define BCM63XX_SPI_BUS_NUM		0
diff --git a/kernel/drivers/spi/spi-cadence-quadspi.c b/kernel/drivers/spi/spi-cadence-quadspi.c
index 2e1255b..23d50a1 100644
--- a/kernel/drivers/spi/spi-cadence-quadspi.c
+++ b/kernel/drivers/spi/spi-cadence-quadspi.c
@@ -1355,17 +1355,30 @@
 static int cqspi_suspend(struct device *dev)
 {
 	struct cqspi_st *cqspi = dev_get_drvdata(dev);
+	struct spi_master *master = dev_get_drvdata(dev);
+	int ret;
 
+	ret = spi_master_suspend(master);
 	cqspi_controller_enable(cqspi, 0);
-	return 0;
+
+	clk_disable_unprepare(cqspi->clk);
+
+	return ret;
 }
 
 static int cqspi_resume(struct device *dev)
 {
 	struct cqspi_st *cqspi = dev_get_drvdata(dev);
+	struct spi_master *master = dev_get_drvdata(dev);
 
-	cqspi_controller_enable(cqspi, 1);
-	return 0;
+	clk_prepare_enable(cqspi->clk);
+	cqspi_wait_idle(cqspi);
+	cqspi_controller_init(cqspi);
+
+	cqspi->current_cs = -1;
+	cqspi->sclk = 0;
+
+	return spi_master_resume(master);
 }
 
 static const struct dev_pm_ops cqspi__dev_pm_ops = {
diff --git a/kernel/drivers/spi/spi-dw-core.c b/kernel/drivers/spi/spi-dw-core.c
index c33866f..aa116ce 100644
--- a/kernel/drivers/spi/spi-dw-core.c
+++ b/kernel/drivers/spi/spi-dw-core.c
@@ -353,7 +353,7 @@
 	 * will be adjusted at the final stage of the IRQ-based SPI transfer
 	 * execution so not to lose the leftover of the incoming data.
 	 */
-	level = min_t(u16, dws->fifo_len / 2, dws->tx_len);
+	level = min_t(unsigned int, dws->fifo_len / 2, dws->tx_len);
 	dw_writel(dws, DW_SPI_TXFTLR, level);
 	dw_writel(dws, DW_SPI_RXFTLR, level - 1);
 
diff --git a/kernel/drivers/spi/spi-fsl-cpm.c b/kernel/drivers/spi/spi-fsl-cpm.c
index ee90588..7832ce3 100644
--- a/kernel/drivers/spi/spi-fsl-cpm.c
+++ b/kernel/drivers/spi/spi-fsl-cpm.c
@@ -21,6 +21,7 @@
 #include <linux/spi/spi.h>
 #include <linux/types.h>
 #include <linux/platform_device.h>
+#include <linux/byteorder/generic.h>
 
 #include "spi-fsl-cpm.h"
 #include "spi-fsl-lib.h"
@@ -120,6 +121,21 @@
 		mspi->rx_dma = mspi->dma_dummy_rx;
 		mspi->map_rx_dma = 0;
 	}
+	if (t->bits_per_word == 16 && t->tx_buf) {
+		const u16 *src = t->tx_buf;
+		u16 *dst;
+		int i;
+
+		dst = kmalloc(t->len, GFP_KERNEL);
+		if (!dst)
+			return -ENOMEM;
+
+		for (i = 0; i < t->len >> 1; i++)
+			dst[i] = cpu_to_le16p(src + i);
+
+		mspi->tx = dst;
+		mspi->map_tx_dma = 1;
+	}
 
 	if (mspi->map_tx_dma) {
 		void *nonconst_tx = (void *)mspi->tx; /* shut up gcc */
@@ -173,6 +189,13 @@
 	if (mspi->map_rx_dma)
 		dma_unmap_single(dev, mspi->rx_dma, t->len, DMA_FROM_DEVICE);
 	mspi->xfer_in_progress = NULL;
+
+	if (t->bits_per_word == 16 && t->rx_buf) {
+		int i;
+
+		for (i = 0; i < t->len; i += 2)
+			le16_to_cpus(t->rx_buf + i);
+	}
 }
 EXPORT_SYMBOL_GPL(fsl_spi_cpm_bufs_complete);
 
diff --git a/kernel/drivers/spi/spi-fsl-dspi.c b/kernel/drivers/spi/spi-fsl-dspi.c
index fd004c9..0d9201a 100644
--- a/kernel/drivers/spi/spi-fsl-dspi.c
+++ b/kernel/drivers/spi/spi-fsl-dspi.c
@@ -975,7 +975,9 @@
 static int dspi_setup(struct spi_device *spi)
 {
 	struct fsl_dspi *dspi = spi_controller_get_devdata(spi->controller);
+	u32 period_ns = DIV_ROUND_UP(NSEC_PER_SEC, spi->max_speed_hz);
 	unsigned char br = 0, pbr = 0, pcssck = 0, cssck = 0;
+	u32 quarter_period_ns = DIV_ROUND_UP(period_ns, 4);
 	u32 cs_sck_delay = 0, sck_cs_delay = 0;
 	struct fsl_dspi_platform_data *pdata;
 	unsigned char pasc = 0, asc = 0;
@@ -1003,6 +1005,19 @@
 		sck_cs_delay = pdata->sck_cs_delay;
 	}
 
+	/* Since tCSC and tASC apply to continuous transfers too, avoid SCK
+	 * glitches of half a cycle by never allowing tCSC + tASC to go below
+	 * half a SCK period.
+	 */
+	if (cs_sck_delay < quarter_period_ns)
+		cs_sck_delay = quarter_period_ns;
+	if (sck_cs_delay < quarter_period_ns)
+		sck_cs_delay = quarter_period_ns;
+
+	dev_dbg(&spi->dev,
+		"DSPI controller timing params: CS-to-SCK delay %u ns, SCK-to-CS delay %u ns\n",
+		cs_sck_delay, sck_cs_delay);
+
 	clkrate = clk_get_rate(dspi->clk);
 	hz_to_spi_baud(&pbr, &br, spi->max_speed_hz, clkrate);
 
diff --git a/kernel/drivers/spi/spi-fsl-lpspi.c b/kernel/drivers/spi/spi-fsl-lpspi.c
index 5d98611..c5ff6e8 100644
--- a/kernel/drivers/spi/spi-fsl-lpspi.c
+++ b/kernel/drivers/spi/spi-fsl-lpspi.c
@@ -906,9 +906,14 @@
 	ret = fsl_lpspi_dma_init(&pdev->dev, fsl_lpspi, controller);
 	if (ret == -EPROBE_DEFER)
 		goto out_pm_get;
-
 	if (ret < 0)
 		dev_err(&pdev->dev, "dma setup error %d, use pio\n", ret);
+	else
+		/*
+		 * disable LPSPI module IRQ when enable DMA mode successfully,
+		 * to prevent the unexpected LPSPI module IRQ events.
+		 */
+		disable_irq(irq);
 
 	ret = devm_spi_register_controller(&pdev->dev, controller);
 	if (ret < 0) {
diff --git a/kernel/drivers/spi/spi-fsl-spi.c b/kernel/drivers/spi/spi-fsl-spi.c
index bdf94cc..63302e2 100644
--- a/kernel/drivers/spi/spi-fsl-spi.c
+++ b/kernel/drivers/spi/spi-fsl-spi.c
@@ -203,24 +203,6 @@
 	return bits_per_word;
 }
 
-static int mspi_apply_qe_mode_quirks(struct spi_mpc8xxx_cs *cs,
-				struct spi_device *spi,
-				int bits_per_word)
-{
-	/* QE uses Little Endian for words > 8
-	 * so transform all words > 8 into 8 bits
-	 * Unfortnatly that doesn't work for LSB so
-	 * reject these for now */
-	/* Note: 32 bits word, LSB works iff
-	 * tfcr/rfcr is set to CPMFCR_GBL */
-	if (spi->mode & SPI_LSB_FIRST &&
-	    bits_per_word > 8)
-		return -EINVAL;
-	if (bits_per_word > 8)
-		return 8; /* pretend its 8 bits */
-	return bits_per_word;
-}
-
 static int fsl_spi_setup_transfer(struct spi_device *spi,
 					struct spi_transfer *t)
 {
@@ -248,9 +230,6 @@
 		bits_per_word = mspi_apply_cpu_mode_quirks(cs, spi,
 							   mpc8xxx_spi,
 							   bits_per_word);
-	else if (mpc8xxx_spi->flags & SPI_QE)
-		bits_per_word = mspi_apply_qe_mode_quirks(cs, spi,
-							  bits_per_word);
 
 	if (bits_per_word < 0)
 		return bits_per_word;
@@ -368,13 +347,29 @@
 	 * In CPU mode, optimize large byte transfers to use larger
 	 * bits_per_word values to reduce number of interrupts taken.
 	 */
-	if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) {
-		list_for_each_entry(t, &m->transfers, transfer_list) {
+	list_for_each_entry(t, &m->transfers, transfer_list) {
+		if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) {
 			if (t->len < 256 || t->bits_per_word != 8)
 				continue;
 			if ((t->len & 3) == 0)
 				t->bits_per_word = 32;
 			else if ((t->len & 1) == 0)
+				t->bits_per_word = 16;
+		} else {
+			/*
+			 * CPM/QE uses Little Endian for words > 8
+			 * so transform 16 and 32 bits words into 8 bits
+			 * Unfortnatly that doesn't work for LSB so
+			 * reject these for now
+			 * Note: 32 bits word, LSB works iff
+			 * tfcr/rfcr is set to CPMFCR_GBL
+			 */
+			if (m->spi->mode & SPI_LSB_FIRST && t->bits_per_word > 8)
+				return -EINVAL;
+			if (t->bits_per_word == 16 || t->bits_per_word == 32)
+				t->bits_per_word = 8; /* pretend its 8 bits */
+			if (t->bits_per_word == 8 && t->len >= 256 &&
+			    (mpc8xxx_spi->flags & SPI_CPM1))
 				t->bits_per_word = 16;
 		}
 	}
@@ -633,8 +628,14 @@
 	if (mpc8xxx_spi->type == TYPE_GRLIB)
 		fsl_spi_grlib_probe(dev);
 
-	master->bits_per_word_mask =
-		(SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32)) &
+	if (mpc8xxx_spi->flags & SPI_CPM_MODE)
+		master->bits_per_word_mask =
+			(SPI_BPW_RANGE_MASK(4, 8) | SPI_BPW_MASK(16) | SPI_BPW_MASK(32));
+	else
+		master->bits_per_word_mask =
+			(SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32));
+
+	master->bits_per_word_mask &=
 		SPI_BPW_RANGE_MASK(1, mpc8xxx_spi->max_bits_per_word);
 
 	if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE)
diff --git a/kernel/drivers/spi/spi-geni-qcom.c b/kernel/drivers/spi/spi-geni-qcom.c
index 01ef79f..be259c6 100644
--- a/kernel/drivers/spi/spi-geni-qcom.c
+++ b/kernel/drivers/spi/spi-geni-qcom.c
@@ -32,7 +32,7 @@
 #define CS_DEMUX_OUTPUT_SEL	GENMASK(3, 0)
 
 #define SE_SPI_TRANS_CFG	0x25c
-#define CS_TOGGLE		BIT(0)
+#define CS_TOGGLE		BIT(1)
 
 #define SE_SPI_WORD_LEN		0x268
 #define WORD_LEN_MSK		GENMASK(9, 0)
diff --git a/kernel/drivers/spi/spi-gpio.c b/kernel/drivers/spi/spi-gpio.c
index 0584f4d..3ffdab6 100644
--- a/kernel/drivers/spi/spi-gpio.c
+++ b/kernel/drivers/spi/spi-gpio.c
@@ -244,9 +244,19 @@
 	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
diff --git a/kernel/drivers/spi/spi-imx.c b/kernel/drivers/spi/spi-imx.c
index 74b3b6c..21297cc 100644
--- a/kernel/drivers/spi/spi-imx.c
+++ b/kernel/drivers/spi/spi-imx.c
@@ -242,6 +242,18 @@
 	return true;
 }
 
+/*
+ * Note the number of natively supported chip selects for MX51 is 4. Some
+ * devices may have less actual SS pins but the register map supports 4. When
+ * using gpio chip selects the cs values passed into the macros below can go
+ * outside the range 0 - 3. We therefore need to limit the cs value to avoid
+ * corrupting bits outside the allocated locations.
+ *
+ * The simplest way to do this is to just mask the cs bits to 2 bits. This
+ * still allows all 4 native chip selects to work as well as gpio chip selects
+ * (which can use any of the 4 chip select configurations).
+ */
+
 #define MX51_ECSPI_CTRL		0x08
 #define MX51_ECSPI_CTRL_ENABLE		(1 <<  0)
 #define MX51_ECSPI_CTRL_XCH		(1 <<  2)
@@ -250,16 +262,16 @@
 #define MX51_ECSPI_CTRL_DRCTL(drctl)	((drctl) << 16)
 #define MX51_ECSPI_CTRL_POSTDIV_OFFSET	8
 #define MX51_ECSPI_CTRL_PREDIV_OFFSET	12
-#define MX51_ECSPI_CTRL_CS(cs)		((cs) << 18)
+#define MX51_ECSPI_CTRL_CS(cs)		((cs & 3) << 18)
 #define MX51_ECSPI_CTRL_BL_OFFSET	20
 #define MX51_ECSPI_CTRL_BL_MASK		(0xfff << 20)
 
 #define MX51_ECSPI_CONFIG	0x0c
-#define MX51_ECSPI_CONFIG_SCLKPHA(cs)	(1 << ((cs) +  0))
-#define MX51_ECSPI_CONFIG_SCLKPOL(cs)	(1 << ((cs) +  4))
-#define MX51_ECSPI_CONFIG_SBBCTRL(cs)	(1 << ((cs) +  8))
-#define MX51_ECSPI_CONFIG_SSBPOL(cs)	(1 << ((cs) + 12))
-#define MX51_ECSPI_CONFIG_SCLKCTL(cs)	(1 << ((cs) + 20))
+#define MX51_ECSPI_CONFIG_SCLKPHA(cs)	(1 << ((cs & 3) +  0))
+#define MX51_ECSPI_CONFIG_SCLKPOL(cs)	(1 << ((cs & 3) +  4))
+#define MX51_ECSPI_CONFIG_SBBCTRL(cs)	(1 << ((cs & 3) +  8))
+#define MX51_ECSPI_CONFIG_SSBPOL(cs)	(1 << ((cs & 3) + 12))
+#define MX51_ECSPI_CONFIG_SCLKCTL(cs)	(1 << ((cs & 3) + 20))
 
 #define MX51_ECSPI_INT		0x10
 #define MX51_ECSPI_INT_TEEN		(1 <<  0)
@@ -1554,9 +1566,8 @@
 	struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
 	int ret;
 
-	ret = pm_runtime_get_sync(spi_imx->dev);
+	ret = pm_runtime_resume_and_get(spi_imx->dev);
 	if (ret < 0) {
-		pm_runtime_put_noidle(spi_imx->dev);
 		dev_err(spi_imx->dev, "failed to enable clock\n");
 		return ret;
 	}
@@ -1766,13 +1777,10 @@
 	spi_bitbang_stop(&spi_imx->bitbang);
 
 	ret = pm_runtime_get_sync(spi_imx->dev);
-	if (ret < 0) {
-		pm_runtime_put_noidle(spi_imx->dev);
-		dev_err(spi_imx->dev, "failed to enable clock\n");
-		return ret;
-	}
-
-	writel(0, spi_imx->base + MXC_CSPICTRL);
+	if (ret >= 0)
+		writel(0, spi_imx->base + MXC_CSPICTRL);
+	else
+		dev_warn(spi_imx->dev, "failed to enable clock, skip hw disable\n");
 
 	pm_runtime_dont_use_autosuspend(spi_imx->dev);
 	pm_runtime_put_sync(spi_imx->dev);
diff --git a/kernel/drivers/spi/spi-nxp-fspi.c b/kernel/drivers/spi/spi-nxp-fspi.c
index bcc0b5a..90b5fbc 100644
--- a/kernel/drivers/spi/spi-nxp-fspi.c
+++ b/kernel/drivers/spi/spi-nxp-fspi.c
@@ -950,6 +950,13 @@
 	fspi_writel(f, FSPI_AHBCR_PREF_EN | FSPI_AHBCR_RDADDROPT,
 		 base + FSPI_AHBCR);
 
+	/* Reset the FLSHxCR1 registers. */
+	reg = FSPI_FLSHXCR1_TCSH(0x3) | FSPI_FLSHXCR1_TCSS(0x3);
+	fspi_writel(f, reg, base + FSPI_FLSHA1CR1);
+	fspi_writel(f, reg, base + FSPI_FLSHA2CR1);
+	fspi_writel(f, reg, base + FSPI_FLSHB1CR1);
+	fspi_writel(f, reg, base + FSPI_FLSHB2CR1);
+
 	/* AHB Read - Set lut sequence ID for all CS. */
 	fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA1CR2);
 	fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA2CR2);
diff --git a/kernel/drivers/spi/spi-qup.c b/kernel/drivers/spi/spi-qup.c
index f3877ee..2cc9bb4 100644
--- a/kernel/drivers/spi/spi-qup.c
+++ b/kernel/drivers/spi/spi-qup.c
@@ -1030,23 +1030,8 @@
 		return -ENXIO;
 	}
 
-	ret = clk_prepare_enable(cclk);
-	if (ret) {
-		dev_err(dev, "cannot enable core clock\n");
-		return ret;
-	}
-
-	ret = clk_prepare_enable(iclk);
-	if (ret) {
-		clk_disable_unprepare(cclk);
-		dev_err(dev, "cannot enable iface clock\n");
-		return ret;
-	}
-
 	master = spi_alloc_master(dev, sizeof(struct spi_qup));
 	if (!master) {
-		clk_disable_unprepare(cclk);
-		clk_disable_unprepare(iclk);
 		dev_err(dev, "cannot allocate master\n");
 		return -ENOMEM;
 	}
@@ -1092,6 +1077,19 @@
 	spin_lock_init(&controller->lock);
 	init_completion(&controller->done);
 
+	ret = clk_prepare_enable(cclk);
+	if (ret) {
+		dev_err(dev, "cannot enable core clock\n");
+		goto error_dma;
+	}
+
+	ret = clk_prepare_enable(iclk);
+	if (ret) {
+		clk_disable_unprepare(cclk);
+		dev_err(dev, "cannot enable iface clock\n");
+		goto error_dma;
+	}
+
 	iomode = readl_relaxed(base + QUP_IO_M_MODES);
 
 	size = QUP_IO_M_OUTPUT_BLOCK_SIZE(iomode);
@@ -1121,7 +1119,7 @@
 	ret = spi_qup_set_state(controller, QUP_STATE_RESET);
 	if (ret) {
 		dev_err(dev, "cannot set RESET state\n");
-		goto error_dma;
+		goto error_clk;
 	}
 
 	writel_relaxed(0, base + QUP_OPERATIONAL);
@@ -1145,7 +1143,7 @@
 	ret = devm_request_irq(dev, irq, spi_qup_qup_irq,
 			       IRQF_TRIGGER_HIGH, pdev->name, controller);
 	if (ret)
-		goto error_dma;
+		goto error_clk;
 
 	pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
 	pm_runtime_use_autosuspend(dev);
@@ -1160,11 +1158,12 @@
 
 disable_pm:
 	pm_runtime_disable(&pdev->dev);
+error_clk:
+	clk_disable_unprepare(cclk);
+	clk_disable_unprepare(iclk);
 error_dma:
 	spi_qup_release_dma(master);
 error:
-	clk_disable_unprepare(cclk);
-	clk_disable_unprepare(iclk);
 	spi_master_put(master);
 	return ret;
 }
@@ -1276,18 +1275,22 @@
 	struct spi_qup *controller = spi_master_get_devdata(master);
 	int ret;
 
-	ret = pm_runtime_resume_and_get(&pdev->dev);
-	if (ret < 0)
-		return ret;
+	ret = pm_runtime_get_sync(&pdev->dev);
 
-	ret = spi_qup_set_state(controller, QUP_STATE_RESET);
-	if (ret)
-		return ret;
+	if (ret >= 0) {
+		ret = spi_qup_set_state(controller, QUP_STATE_RESET);
+		if (ret)
+			dev_warn(&pdev->dev, "failed to reset controller (%pe)\n",
+				 ERR_PTR(ret));
+
+		clk_disable_unprepare(controller->cclk);
+		clk_disable_unprepare(controller->iclk);
+	} else {
+		dev_warn(&pdev->dev, "failed to resume, skip hw disable (%pe)\n",
+			 ERR_PTR(ret));
+	}
 
 	spi_qup_release_dma(master);
-
-	clk_disable_unprepare(controller->cclk);
-	clk_disable_unprepare(controller->iclk);
 
 	pm_runtime_put_noidle(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
diff --git a/kernel/drivers/spi/spi-rockchip-slave.c b/kernel/drivers/spi/spi-rockchip-slave.c
new file mode 100644
index 0000000..4b06812
--- /dev/null
+++ b/kernel/drivers/spi/spi-rockchip-slave.c
@@ -0,0 +1,1060 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Rockchip SPI Slave Controller Driver
+ *
+ * Copyright (c) 2023, Rockchip Inc.
+ * Author: Jon Lin <Jon.lin@rock-chips.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/clk.h>
+#include <linux/dmaengine.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/pm_runtime.h>
+#include <linux/dma-mapping.h>
+
+#define DRIVER_NAME "rockchip-spi-slave"
+
+/* SPI register offsets */
+#define ROCKCHIP_SPI_CTRLR0			0x0000
+#define ROCKCHIP_SPI_CTRLR1			0x0004
+#define ROCKCHIP_SPI_SSIENR			0x0008
+#define ROCKCHIP_SPI_SER			0x000c
+#define ROCKCHIP_SPI_BAUDR			0x0010
+#define ROCKCHIP_SPI_TXFTLR			0x0014
+#define ROCKCHIP_SPI_RXFTLR			0x0018
+#define ROCKCHIP_SPI_TXFLR			0x001c
+#define ROCKCHIP_SPI_RXFLR			0x0020
+#define ROCKCHIP_SPI_SR				0x0024
+#define ROCKCHIP_SPI_IPR			0x0028
+#define ROCKCHIP_SPI_IMR			0x002c
+#define ROCKCHIP_SPI_ISR			0x0030
+#define ROCKCHIP_SPI_RISR			0x0034
+#define ROCKCHIP_SPI_ICR			0x0038
+#define ROCKCHIP_SPI_DMACR			0x003c
+#define ROCKCHIP_SPI_DMATDLR			0x0040
+#define ROCKCHIP_SPI_DMARDLR			0x0044
+#define ROCKCHIP_SPI_VERSION			0x0048
+#define ROCKCHIP_SPI_TIMEOUT			0x004c
+#define ROCKCHIP_SPI_BYPASS			0x0050
+#define ROCKCHIP_SPI_BYPASS_ENR			0x0054
+#define ROCKCHIP_SPI_TXDR			0x0400
+#define ROCKCHIP_SPI_RXDR			0x0800
+
+/* Bit fields in CTRLR0 */
+#define CR0_DFS_OFFSET				0
+#define CR0_DFS_4BIT				0x0
+#define CR0_DFS_8BIT				0x1
+#define CR0_DFS_16BIT				0x2
+
+#define CR0_SCPH_OFFSET				6
+
+#define CR0_EM_OFFSET				11
+#define CR0_EM_LITTLE					0x0
+#define CR0_EM_BIG					0x1
+
+#define CR0_FBM_OFFSET				12
+#define CR0_FBM_MSB					0x0
+#define CR0_FBM_LSB					0x1
+
+#define CR0_BHT_OFFSET				13
+#define CR0_BHT_16BIT					0x0
+#define CR0_BHT_8BIT					0x1
+
+#define CR0_FRF_OFFSET				16
+#define CR0_FRF_SPI					0x0
+#define CR0_FRF_SSP					0x1
+#define CR0_FRF_MICROWIRE				0x2
+
+#define CR0_XFM_OFFSET				18
+#define CR0_XFM_MASK					(0x03 << SPI_XFM_OFFSET)
+#define CR0_XFM_TR					0x0
+#define CR0_XFM_TO					0x1
+#define CR0_XFM_RO					0x2
+
+#define CR0_OPM_OFFSET				20
+#define CR0_OPM_MASTER					0x0
+#define CR0_OPM_SLAVE					0x1
+
+#define CR0_SOI_OFFSET				23
+
+/* Bit fields in SR, 6bit */
+#define SR_MASK						0x3f
+#define SR_BUSY						(1 << 0)
+#define SR_TF_FULL					(1 << 1)
+#define SR_TF_EMPTY					(1 << 2)
+#define SR_RF_EMPTY					(1 << 3)
+#define SR_RF_FULL					(1 << 4)
+#define SR_SLAVE_TX_BUSY				(1 << 5)
+#define SR_SS_IN_N					(1 << 6)
+
+/* Bit fields in ISR, IMR, ISR, RISR, 5bit */
+#define INT_MASK					0x1f
+#define INT_TF_EMPTY					(1 << 0)
+#define INT_TF_OVERFLOW					(1 << 1)
+#define INT_RF_UNDERFLOW				(1 << 2)
+#define INT_RF_OVERFLOW					(1 << 3)
+#define INT_RF_FULL					(1 << 4)
+#define INT_CS_INACTIVE					(1 << 6)
+
+/* Bit fields in ICR, 4bit */
+#define ICR_MASK					0x0f
+#define ICR_ALL						(1 << 0)
+#define ICR_RF_UNDERFLOW				(1 << 1)
+#define ICR_RF_OVERFLOW					(1 << 2)
+#define ICR_TF_OVERFLOW					(1 << 3)
+
+/* Bit fields in DMACR */
+#define RF_DMA_EN					(1 << 0)
+#define TF_DMA_EN					(1 << 1)
+
+/* Bit fields in TIMEOUT */
+#define TIMEOUT_THRESHOLD_OFFSET		0x0
+#define TIMEOUT_COUNTER_EN				(1 << 16)
+#define TIMEOUT_SINGLE_REQUEST_EN			(1 << 18)
+
+/* Bit fields in BYPASS */
+#define BYPASS_EN					(1 << 0)
+#define BYPASS_INT_TF_EN				(1 << 1)
+#define CLOCK_GATING_NONE				(0x0 << 2)
+#define CLOCK_GATING_SPICLK_INNER			(0x1 << 2)
+#define CLOCK_GATING_SPICLK_EXT				(0x2 << 2)
+#define CLOCK_GATING_ALL_IN_IDLE			(0x3 << 2)
+
+/* Driver state flags */
+#define RXDMA						(1 << 0)
+#define TXDMA						(1 << 1)
+
+/*
+ * SPI_CTRLR1 is 16-bits, so we should support lengths of 0xffff + 1. However,
+ * the controller seems to hang when given 0x10000, so stick with this for now.
+ */
+#define ROCKCHIP_SPI_MAX_TRANLEN		0xffff
+
+#define ROCKCHIP_SPI_VER2_TYPE1			0x05EC0002
+#define ROCKCHIP_SPI_VER2_TYPE2			0x00110002
+#define ROCKCHIP_SPI_VER3			0x03110003
+
+/*
+ * The callback function may not be timely, and even cs has been released, so
+ * some redundancy needs to be done for this.
+ */
+#define ROCKCHIP_SPI_DMA_CB_REDUNDANCY_US	10000
+
+/*
+ * Tclk-invalid-to-cs-deassert
+ */
+#define ROCKCHIP_SPI_CLK_TO_CS_DEASSERT_US	10000
+
+enum rockchip_spi_slave_xfer_mode {
+	ROCKCHIP_SPI_DMA,
+	ROCKCHIP_SPI_IRQ,
+};
+
+struct rockchip_spi {
+	struct device *dev;
+
+	struct clk_bulk_data *clks;
+	unsigned int clk_cnt;
+
+	void __iomem *regs;
+	dma_addr_t dma_addr_rx;
+	dma_addr_t dma_addr_tx;
+	u32 *dma_buf;
+	dma_addr_t dma_phys;
+
+	const void *tx;
+	void *rx;
+	unsigned int tx_left;
+	unsigned int rx_left;
+
+	atomic_t state;
+	struct completion xfer_done;
+
+	u32 version;
+	/*depth of the FIFO buffer */
+	u32 fifo_len;
+	int max_transfer_size;
+	u32 fixed_burst_size;
+	u8 tx_idle_type; /* 0-SR_TF_EMPTY 1-SR_SLAVE_TX_BUSY */
+	u32 dma_timeout;
+
+	u8 n_bytes;
+
+	bool slave_aborted;
+	bool cs_inactive; /* spi slave tansmition stop when cs inactive */
+	struct gpio_desc *ready; /* spi slave transmission ready */
+	struct spi_transfer *xfer; /* Store xfer temporarily */
+	enum rockchip_spi_slave_xfer_mode xfer_mode;
+	bool ext_spi_clk;
+
+	bool verbose;
+	ktime_t dbg_time;
+};
+
+static inline void spi_enable_chip(struct rockchip_spi *rs, bool enable)
+{
+	if (rs->ext_spi_clk)
+		writel_relaxed((enable ? 1U : 0U), rs->regs + ROCKCHIP_SPI_BYPASS_ENR);
+	writel_relaxed((enable ? 1U : 0U), rs->regs + ROCKCHIP_SPI_SSIENR);
+}
+
+static inline void wait_for_tx_idle(struct rockchip_spi *rs)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(5);
+	u32 bit_filed = SR_TF_EMPTY;
+	u32 idle_val = 1;
+
+	/* When using external clock, tx clk can function normally without waiting for idle  */
+	if (rs->ext_spi_clk)
+		return;
+
+	if (rs->tx_idle_type == 1) {
+		bit_filed = SR_SLAVE_TX_BUSY;
+		idle_val = 0;
+	}
+
+	do {
+		if ((readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & bit_filed) == idle_val) {
+			if (bit_filed == SR_TF_EMPTY)
+				udelay(1);
+
+			return;
+		}
+	} while (!time_after(jiffies, timeout));
+	dev_warn(rs->dev, "spi controller is in busy state!\n");
+}
+
+static void rockchip_spi_slave_pio_writer(struct rockchip_spi *rs)
+{
+	u32 tx_free = rs->fifo_len - readl_relaxed(rs->regs + ROCKCHIP_SPI_TXFLR);
+	u32 words = min(rs->tx_left, tx_free);
+
+	rs->tx_left -= words;
+	for (; words; words--) {
+		u32 txw;
+
+		if (rs->n_bytes == 1)
+			txw = *(u8 *)rs->tx;
+		else
+			txw = *(u16 *)rs->tx;
+
+		writel_relaxed(txw, rs->regs + ROCKCHIP_SPI_TXDR);
+		rs->tx += rs->n_bytes;
+	}
+}
+
+static void rockchip_spi_slave_pio_reader(struct rockchip_spi *rs)
+{
+	u32 rx_valid = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR);
+	u32 words = min(rs->rx_left, rx_valid);
+
+	rs->rx_left -= words;
+	for (; words; words--) {
+		u32 rxw = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR);
+
+		if (!rs->rx)
+			continue;
+
+		if (rs->n_bytes == 1)
+			*(u8 *)rs->rx = (u8)rxw;
+		else
+			*(u16 *)rs->rx = (u16)rxw;
+		rs->rx += rs->n_bytes;
+	}
+}
+
+static int rockchop_spi_rx_fifo_flush(struct spi_controller *ctlr)
+{
+	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
+	u32 rx_fifo_left;
+
+	/* Flush rx fifo */
+	rx_fifo_left = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR);
+	for (; rx_fifo_left; rx_fifo_left--)
+		readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR);
+
+	return 0;
+}
+
+static void rockchip_spi_slave_handle_err(struct spi_controller *ctlr)
+{
+	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
+
+	dev_err(rs->dev, "state=%x\n", atomic_read(&rs->state));
+	dev_err(rs->dev, "tx_left=%x\n", rs->tx_left);
+	dev_err(rs->dev, "rx_left=%x\n", rs->rx_left);
+	print_hex_dump(KERN_ERR, "regs ", DUMP_PREFIX_OFFSET, 4, 4, rs->regs, 0x58, 0);
+
+	rockchop_spi_rx_fifo_flush(ctlr);
+
+	if (atomic_read(&rs->state) & TXDMA)
+		dmaengine_terminate_async(ctlr->dma_tx);
+
+	if (atomic_read(&rs->state) & RXDMA)
+		dmaengine_terminate_async(ctlr->dma_rx);
+	atomic_set(&rs->state, 0);
+}
+
+static irqreturn_t rockchip_spi_slave_isr(int irq, void *dev_id)
+{
+	struct spi_controller *ctlr = dev_id;
+	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
+
+	if (rs->xfer_mode == ROCKCHIP_SPI_IRQ) {
+		if (rs->tx_left)
+			rockchip_spi_slave_pio_writer(rs);
+
+		rockchip_spi_slave_pio_reader(rs);
+		if (!rs->rx_left) {
+			writel_relaxed(0, rs->regs + ROCKCHIP_SPI_IMR);
+			writel_relaxed(0xffffffff, rs->regs + ROCKCHIP_SPI_ICR);
+			complete(&rs->xfer_done);
+			return IRQ_HANDLED;
+		}
+	}
+
+	/* When int_cs_inactive comes, spi slave abort */
+	if (rs->cs_inactive && readl_relaxed(rs->regs + ROCKCHIP_SPI_ISR) & INT_CS_INACTIVE) {
+
+		rs->slave_aborted = true;
+		writel_relaxed(0, rs->regs + ROCKCHIP_SPI_IMR);
+		writel_relaxed(0xffffffff, rs->regs + ROCKCHIP_SPI_ICR);
+		complete(&rs->xfer_done);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int rockchip_spi_slave_prepare_irq(struct rockchip_spi *rs,
+				    struct spi_controller *ctlr,
+				    struct spi_transfer *xfer)
+{
+	rs->tx_left = rs->tx ? xfer->len / rs->n_bytes : 0;
+	rs->rx_left = xfer->len / rs->n_bytes;
+
+	writel_relaxed(0xffffffff, rs->regs + ROCKCHIP_SPI_ICR);
+
+	spi_enable_chip(rs, true);
+
+	if (rs->tx_left)
+		rockchip_spi_slave_pio_writer(rs);
+
+	if (rs->cs_inactive)
+		writel_relaxed(INT_RF_FULL | INT_CS_INACTIVE, rs->regs + ROCKCHIP_SPI_IMR);
+	else
+		writel_relaxed(INT_RF_FULL, rs->regs + ROCKCHIP_SPI_IMR);
+	/* 1 means the transfer is in progress */
+	return 1;
+}
+
+static void rockchip_spi_slave_dma_rxcb(void *data)
+{
+	struct spi_controller *ctlr = data;
+	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
+	int state = atomic_fetch_andnot(RXDMA, &rs->state);
+
+	if (state & TXDMA)
+		return;
+
+	complete(&rs->xfer_done);
+}
+
+static void rockchip_spi_slave_dma_txcb(void *data)
+{
+	struct spi_controller *ctlr = data;
+	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
+	int state = atomic_fetch_andnot(TXDMA, &rs->state);
+
+	if (state & RXDMA)
+		return;
+
+	complete(&rs->xfer_done);
+}
+
+static u32 rockchip_spi_slave_calc_burst_size(struct rockchip_spi *rs, u32 data_len)
+{
+	u32 i;
+
+	if (rs->dma_timeout)
+		return rs->fixed_burst_size;
+
+	/* burst size: 1, 2, 4, 8, 16 */
+	for (i = 1; i < 16; i <<= 1) {
+		if (data_len & i)
+			break;
+	}
+
+	return i;
+}
+
+static int rockchip_spi_slave_prepare_dma(struct rockchip_spi *rs,
+		struct spi_controller *ctlr, struct spi_transfer *xfer)
+{
+	struct dma_async_tx_descriptor *rxdesc = NULL, *txdesc = NULL;
+
+	atomic_set(&rs->state, 0);
+
+	if (xfer->rx_buf) {
+		struct dma_slave_config rxconf = {
+			.direction = DMA_DEV_TO_MEM,
+			.src_addr = rs->dma_addr_rx,
+			.src_addr_width = rs->n_bytes,
+			.src_maxburst = rockchip_spi_slave_calc_burst_size(rs, xfer->len / rs->n_bytes),
+		};
+
+		dmaengine_slave_config(ctlr->dma_rx, &rxconf);
+
+		rxdesc = dmaengine_prep_slave_single(ctlr->dma_rx, rs->dma_phys, xfer->len,
+						     DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
+		if (!rxdesc)
+			return -EINVAL;
+
+		rxdesc->callback = rockchip_spi_slave_dma_rxcb;
+		rxdesc->callback_param = ctlr;
+	}
+
+	if (xfer->tx_buf) {
+		struct dma_slave_config txconf = {
+			.direction = DMA_MEM_TO_DEV,
+			.dst_addr = rs->dma_addr_tx,
+			.dst_addr_width = rs->n_bytes,
+			.dst_maxburst = 8,
+		};
+
+		dmaengine_slave_config(ctlr->dma_tx, &txconf);
+
+		memcpy(rs->dma_buf, xfer->tx_buf, xfer->len);
+		txdesc = dmaengine_prep_slave_single(ctlr->dma_tx, rs->dma_phys, xfer->len,
+						     DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
+		if (!txdesc) {
+			if (rxdesc)
+				dmaengine_terminate_sync(ctlr->dma_rx);
+			return -EINVAL;
+		}
+
+		txdesc->callback = rockchip_spi_slave_dma_txcb;
+		txdesc->callback_param = ctlr;
+	}
+
+	/* rx must be started before tx due to spi instinct */
+	if (rxdesc) {
+		atomic_or(RXDMA, &rs->state);
+		ctlr->dma_rx->cookie = dmaengine_submit(rxdesc);
+		dma_async_issue_pending(ctlr->dma_rx);
+	}
+
+	if (rs->cs_inactive)
+		writel_relaxed(INT_CS_INACTIVE, rs->regs + ROCKCHIP_SPI_IMR);
+
+	spi_enable_chip(rs, true);
+
+	if (txdesc) {
+		atomic_or(TXDMA, &rs->state);
+		dmaengine_submit(txdesc);
+		dma_async_issue_pending(ctlr->dma_tx);
+	}
+
+	/* 1 means the transfer is in progress */
+	return 1;
+}
+
+static int rockchip_spi_slave_config(struct rockchip_spi *rs,
+		struct spi_device *spi, struct spi_transfer *xfer)
+{
+	u32 cr0 = CR0_FRF_SPI  << CR0_FRF_OFFSET
+		| CR0_BHT_8BIT << CR0_BHT_OFFSET
+		| CR0_EM_BIG   << CR0_EM_OFFSET
+		| CR0_OPM_SLAVE << CR0_OPM_OFFSET;
+	u32 cr1;
+	u32 dmacr = 0;
+	u32 val = 0;
+
+	rs->slave_aborted = false;
+
+	cr0 |= (spi->mode & 0x3U) << CR0_SCPH_OFFSET;
+	if (spi->mode & SPI_LSB_FIRST)
+		cr0 |= CR0_FBM_LSB << CR0_FBM_OFFSET;
+
+	if (xfer->rx_buf && xfer->tx_buf) {
+		cr0 |= CR0_XFM_TR << CR0_XFM_OFFSET;
+	} else if (xfer->rx_buf) {
+		cr0 |= CR0_XFM_RO << CR0_XFM_OFFSET;
+	} else if (xfer->tx_buf) {
+		/*
+		 * Use the water line of rx fifo in full duplex mode to trigger
+		 * the interruption of tx irq transmission completion.
+		 * For the new version of SPI witch support ext_spi_clk, TX under
+		 * IRQ transmission can only be developed using TR.
+		 */
+		if (rs->xfer_mode == ROCKCHIP_SPI_IRQ)
+			cr0 |= CR0_XFM_TR << CR0_XFM_OFFSET;
+		else
+			cr0 |= CR0_XFM_TO << CR0_XFM_OFFSET;
+	} else {
+		dev_err(rs->dev, "no transmission buffer\n");
+		return -EINVAL;
+	}
+
+	switch (xfer->bits_per_word) {
+	case 4:
+		cr0 |= CR0_DFS_4BIT << CR0_DFS_OFFSET;
+		cr1 = xfer->len - 1;
+		break;
+	case 8:
+		cr0 |= CR0_DFS_8BIT << CR0_DFS_OFFSET;
+		cr1 = xfer->len - 1;
+		break;
+	case 16:
+		cr0 |= CR0_DFS_16BIT << CR0_DFS_OFFSET;
+		cr1 = xfer->len / 2 - 1;
+		if (xfer->len & 0x1) {
+			dev_err(rs->dev, "xfer->len is not aligned with 16bits\n");
+			return -EINVAL;
+		}
+		break;
+	default:
+		/* we only whitelist 4, 8 and 16 bit words in
+		 * ctlr->bits_per_word_mask, so this shouldn't
+		 * happen
+		 */
+		dev_err(rs->dev, "unknown bits per word: %d\n",
+			xfer->bits_per_word);
+		return -EINVAL;
+	}
+
+	if (rs->xfer_mode == ROCKCHIP_SPI_DMA) {
+		if (xfer->tx_buf)
+			dmacr |= TF_DMA_EN;
+		if (xfer->rx_buf)
+			dmacr |= RF_DMA_EN;
+	}
+
+	writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0);
+	writel_relaxed(cr1, rs->regs + ROCKCHIP_SPI_CTRLR1);
+	if (rs->ext_spi_clk) {
+		val = BYPASS_EN | BYPASS_INT_TF_EN | CLOCK_GATING_NONE;
+		writel_relaxed(val, rs->regs + ROCKCHIP_SPI_BYPASS);
+	}
+	if (rs->dma_timeout) {
+		val = TIMEOUT_SINGLE_REQUEST_EN | TIMEOUT_COUNTER_EN |
+			16 << TIMEOUT_THRESHOLD_OFFSET;
+		writel_relaxed(val, rs->regs + ROCKCHIP_SPI_TIMEOUT);
+	}
+
+	/* unfortunately setting the fifo threshold level to generate an
+	 * interrupt exactly when the fifo is full doesn't seem to work,
+	 * so we need the strict inequality here
+	 */
+	if ((xfer->len / rs->n_bytes) < rs->fifo_len)
+		writel_relaxed(xfer->len / rs->n_bytes - 1, rs->regs + ROCKCHIP_SPI_RXFTLR);
+	else
+		writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_RXFTLR);
+
+	writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_DMATDLR);
+	writel_relaxed(rockchip_spi_slave_calc_burst_size(rs, xfer->len / rs->n_bytes) - 1,
+		       rs->regs + ROCKCHIP_SPI_DMARDLR);
+	writel_relaxed(dmacr, rs->regs + ROCKCHIP_SPI_DMACR);
+
+	return 0;
+}
+
+static size_t rockchip_spi_slave_max_transfer_size(struct spi_device *spi)
+{
+	struct rockchip_spi *rs = spi_controller_get_devdata(spi->controller);
+
+	return rs->max_transfer_size;
+}
+
+static int rockchip_spi_slave_transfer_wait(struct spi_controller *ctlr)
+{
+	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
+	int state;
+	int ret = 0;
+
+	if (wait_for_completion_interruptible(&rs->xfer_done)) {
+		dev_dbg(rs->dev, "RK SPI transfer interrupted\n");
+		ret = -EINTR;
+		goto out;
+	}
+
+	if (rs->slave_aborted) {
+		if (rs->xfer_mode == ROCKCHIP_SPI_DMA) {
+			state = atomic_read(&rs->state);
+			reinit_completion(&rs->xfer_done);
+
+			if (state && state == atomic_read(&rs->state) &&
+			    wait_for_completion_interruptible_timeout(&rs->xfer_done,
+				ROCKCHIP_SPI_DMA_CB_REDUNDANCY_US) <= 0) {
+				dev_err(rs->dev, "RK SPI transfer slave abort\n");
+				ret = -EIO;
+				goto out;
+			} else {
+				dev_dbg(rs->dev, "RK SPI transfer slave dma cb lately\n");
+			}
+		} else {
+			dev_err(rs->dev, "RK SPI transfer slave abort\n");
+			ret = -EIO;
+			goto out;
+		}
+
+	}
+
+	if (rs->xfer->tx_buf)
+		wait_for_tx_idle(rs);
+out:
+	if (ret)
+		rockchip_spi_slave_handle_err(ctlr);
+
+	return 0;
+}
+
+static int rockchip_spi_slave_stop(struct spi_controller *ctlr)
+{
+	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
+
+	spi_enable_chip(rs, false);
+
+	return 0;
+}
+
+static int rockchip_spi_slave_do_one_msg(struct spi_controller *ctlr, struct spi_message *m)
+{
+	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
+	struct spi_device *spi = m->spi;
+	struct spi_transfer *xfer;
+	int ret = -EINVAL;
+	bool use_dma;
+	u32 status;
+
+	WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) &&
+		(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY));
+
+	if (rs->cs_inactive) {
+		ret = readl_poll_timeout(rs->regs + ROCKCHIP_SPI_SR, status,
+					 status & SR_SS_IN_N, 20,
+					 ROCKCHIP_SPI_CLK_TO_CS_DEASSERT_US);
+		if (ret) {
+			dev_err(rs->dev, "The cs of spi master is still asserted\n");
+			ret = -EIO;
+			goto out;
+		}
+	}
+
+	list_for_each_entry(xfer, &m->transfers, transfer_list) {
+		if (!xfer->len || (!xfer->tx_buf && !xfer->rx_buf)) {
+			dev_err(rs->dev, "No buffer for transfer\n");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		if (xfer->len > rs->max_transfer_size) {
+			dev_err(rs->dev, "Transfer is too long (%d)\n", xfer->len);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		rs->n_bytes = xfer->bits_per_word <= 8 ? 1 : 2;
+		rs->xfer = xfer;
+
+		use_dma = ctlr->can_dma(ctlr, spi, xfer);
+		if (use_dma)
+			rs->xfer_mode = ROCKCHIP_SPI_DMA;
+		else
+			rs->xfer_mode = ROCKCHIP_SPI_IRQ;
+
+		ret = rockchip_spi_slave_config(rs, spi, xfer);
+		if (ret)
+			goto out;
+
+		rs->tx = xfer->tx_buf;
+		rs->rx = xfer->rx_buf;
+
+		reinit_completion(&rs->xfer_done);
+
+		switch (rs->xfer_mode) {
+		case ROCKCHIP_SPI_DMA:
+			ret = rockchip_spi_slave_prepare_dma(rs, ctlr, xfer);
+			break;
+		default:
+			ret = rockchip_spi_slave_prepare_irq(rs, ctlr, xfer);
+		}
+
+		if (rs->ready) {
+			gpiod_set_value(rs->ready, 0);
+			gpiod_set_value(rs->ready, 1);
+		}
+
+		if (rs->verbose)
+			dev_info(rs->dev, "cur_gap=%lldus\n",
+				 ktime_to_us(ktime_sub(ktime_get(), rs->dbg_time)));
+		if (ret > 0)
+			ret = rockchip_spi_slave_transfer_wait(ctlr);
+		if (rs->verbose)
+			rs->dbg_time = ktime_get();
+
+		rockchip_spi_slave_stop(ctlr);
+
+		if (xfer->rx_buf && rs->xfer_mode == ROCKCHIP_SPI_DMA)
+			memcpy(xfer->rx_buf, rs->dma_buf, xfer->len);
+
+		m->actual_length += xfer->len;
+
+		if (xfer->delay_usecs)
+			udelay(xfer->delay_usecs);
+	}
+
+out:
+	m->status = ret;
+
+	spi_finalize_current_message(ctlr);
+	return 0;
+}
+
+static bool rockchip_spi_slave_can_dma(struct spi_controller *ctlr,
+				 struct spi_device *spi,
+				 struct spi_transfer *xfer)
+{
+	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
+	unsigned int bytes_per_word = xfer->bits_per_word <= 8 ? 1 : 2;
+
+	/* if the numbor of spi words to transfer is less than the fifo
+	 * length we can just fill the fifo and wait for a single irq,
+	 * so don't bother setting up dma
+	 */
+	return xfer->len / bytes_per_word >= rs->fifo_len;
+}
+
+static int rockchip_spi_slave_setup(struct spi_device *spi)
+{
+	struct rockchip_spi *rs = spi_controller_get_devdata(spi->controller);
+	u32 cr0;
+
+	pm_runtime_get_sync(rs->dev);
+
+	cr0 = readl_relaxed(rs->regs + ROCKCHIP_SPI_CTRLR0);
+	cr0 |= ((spi->mode & 0x3) << CR0_SCPH_OFFSET) | CR0_OPM_SLAVE << CR0_OPM_OFFSET;
+	writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0);
+
+	pm_runtime_put(rs->dev);
+
+	return 0;
+}
+
+static int rockchip_spi_slave_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct rockchip_spi *rs;
+	struct spi_controller *ctlr;
+	struct resource *mem;
+	struct device_node *sram_np;
+	struct resource sram_res;
+	u32 val;
+
+	ctlr = spi_alloc_slave(&pdev->dev, sizeof(struct rockchip_spi));
+	if (!ctlr)
+		return -ENOMEM;
+
+	ctlr->rt = true;
+	platform_set_drvdata(pdev, ctlr);
+
+	rs = spi_controller_get_devdata(ctlr);
+
+	/* Get basic io resource and map it */
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	rs->regs = devm_ioremap_resource(&pdev->dev, mem);
+	if (IS_ERR(rs->regs)) {
+		ret =  PTR_ERR(rs->regs);
+		goto err_put_ctlr;
+	}
+
+	if (!has_acpi_companion(&pdev->dev))
+		ret = devm_clk_bulk_get_all(&pdev->dev, &rs->clks);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to get clks\n");
+		goto err_put_ctlr;
+	}
+	rs->clk_cnt = ret;
+
+	if (!has_acpi_companion(&pdev->dev))
+		ret = clk_bulk_prepare_enable(rs->clk_cnt, rs->clks);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to enable clks\n");
+		goto err_put_ctlr;
+	}
+
+	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to set dma mask\n");
+		goto err_put_ctlr;
+	}
+
+	sram_np = of_parse_phandle(pdev->dev.of_node, "rockchip,sram", 0);
+	if (sram_np) {
+		/* get sram start and size */
+		ret = of_address_to_resource(sram_np, 0, &sram_res);
+		if (ret) {
+			dev_err(&pdev->dev, "find sram res error\n");
+			goto err_put_ctlr;
+		}
+
+		rs->max_transfer_size = resource_size(&sram_res);
+		rs->dma_phys = sram_res.start;
+		rs->dma_buf = devm_ioremap_resource(&pdev->dev, &sram_res);
+		if (IS_ERR(rs->dma_buf)) {
+			ret = PTR_ERR(rs->dma_buf);
+			goto err_put_ctlr;
+		}
+		dev_err(&pdev->dev, "set sram_buf\n");
+	} else {
+		rs->max_transfer_size = ROCKCHIP_SPI_MAX_TRANLEN;
+		rs->dma_buf = dma_alloc_coherent(&pdev->dev, rs->max_transfer_size + 1,
+						&rs->dma_phys, GFP_KERNEL);
+		if (!rs->dma_buf) {
+			ret = -ENOMEM;
+			goto err_put_ctlr;
+		}
+	}
+
+	spi_enable_chip(rs, false);
+
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
+		goto err_disable_spiclk;
+
+	ret = devm_request_irq(&pdev->dev, ret, rockchip_spi_slave_isr, 0, dev_name(&pdev->dev), ctlr);
+	if (ret)
+		goto err_disable_spiclk;
+
+	rs->dev = &pdev->dev;
+
+	rs->version = readl_relaxed(rs->regs + ROCKCHIP_SPI_VERSION);
+	rs->verbose = 0;
+
+	device_property_read_u32(&pdev->dev, "rockchip,autosuspend-delay-ms", &val);
+	if (val <= 0)
+		val = (ROCKCHIP_SPI_CLK_TO_CS_DEASSERT_US + 999) / 1000;
+	pm_runtime_set_autosuspend_delay(&pdev->dev, val);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+	ctlr->auto_runtime_pm = true;
+
+	ctlr->bus_num = pdev->id;
+	ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
+	ctlr->dev.of_node = pdev->dev.of_node;
+	ctlr->bits_per_word_mask = SPI_BPW_MASK(16) | SPI_BPW_MASK(8) | SPI_BPW_MASK(4);
+
+	ctlr->setup = rockchip_spi_slave_setup;
+	ctlr->transfer_one_message = rockchip_spi_slave_do_one_msg;
+	ctlr->max_transfer_size = rockchip_spi_slave_max_transfer_size;
+
+	ctlr->dma_tx = dma_request_chan(rs->dev, "tx");
+	if (IS_ERR(ctlr->dma_tx)) {
+		/* Check tx to see if we need defer probing driver */
+		if (PTR_ERR(ctlr->dma_tx) == -EPROBE_DEFER) {
+			ret = -EPROBE_DEFER;
+			goto err_disable_pm_runtime;
+		}
+		dev_warn(rs->dev, "Failed to request TX DMA channel\n");
+		ret = -EINVAL;
+		goto err_disable_spiclk;
+	}
+	ctlr->dma_rx = dma_request_chan(rs->dev, "rx");
+	if (IS_ERR(ctlr->dma_rx)) {
+		if (PTR_ERR(ctlr->dma_rx) == -EPROBE_DEFER) {
+			ret = -EPROBE_DEFER;
+			goto err_free_dma_tx;
+		}
+		dev_warn(rs->dev, "Failed to request RX DMA channel\n");
+		ret = -EINVAL;
+		goto err_free_dma_tx;
+	}
+	rs->dma_addr_tx = mem->start + ROCKCHIP_SPI_TXDR;
+	rs->dma_addr_rx = mem->start + ROCKCHIP_SPI_RXDR;
+	ctlr->can_dma = rockchip_spi_slave_can_dma;
+
+	init_completion(&rs->xfer_done);
+	switch (rs->version) {
+	case ROCKCHIP_SPI_VER3:
+		rs->ext_spi_clk = true;
+		rs->dma_timeout = 16;
+		rs->fixed_burst_size = 16;
+		rs->tx_idle_type = 1;
+		rs->cs_inactive = true;
+		rs->fifo_len = 64;
+		break;
+	case ROCKCHIP_SPI_VER2_TYPE2:
+		rs->tx_idle_type = 1;
+		rs->cs_inactive = true;
+		rs->fifo_len = 64;
+		break;
+	case ROCKCHIP_SPI_VER2_TYPE1:
+		rs->tx_idle_type = 0;
+		rs->cs_inactive = true;
+		rs->fifo_len = 64;
+		break;
+	default:
+		rs->ext_spi_clk = false;
+		rs->dma_timeout = 0;
+		rs->fixed_burst_size = 0;
+		rs->tx_idle_type = 0;
+		rs->cs_inactive = false;
+		rs->fifo_len = 32;
+	}
+
+	if (device_property_read_bool(&pdev->dev, "rockchip,cs-inactive-disable"))
+		rs->cs_inactive = false;
+
+	if (!device_property_read_bool(&pdev->dev, "rockchip,dma-support-req-mix"))
+		rs->dma_timeout = 0;
+
+	rs->ready = devm_gpiod_get_optional(&pdev->dev, "ready", GPIOD_OUT_HIGH);
+	if (IS_ERR(rs->ready)) {
+		ret = PTR_ERR(rs->ready);
+		dev_err(&pdev->dev, "invalid ready-gpios property in node\n");
+		goto err_free_dma_rx;
+	}
+
+	ret = devm_spi_register_controller(&pdev->dev, ctlr);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to register controller\n");
+		goto err_free_dma_rx;
+	}
+
+	dev_info(rs->dev, "slave probed, cs-inactive=%d, ready=%d, ext=%d, dam_buf=%x\n",
+		 rs->cs_inactive, rs->ready ? 1 : 0, rs->ext_spi_clk, (u32)rs->dma_phys);
+
+	return 0;
+
+err_free_dma_rx:
+	dma_release_channel(ctlr->dma_rx);
+err_free_dma_tx:
+	dma_release_channel(ctlr->dma_tx);
+err_disable_pm_runtime:
+	pm_runtime_disable(&pdev->dev);
+err_disable_spiclk:
+	clk_bulk_disable_unprepare(rs->clk_cnt, rs->clks);
+err_put_ctlr:
+	spi_controller_put(ctlr);
+
+	return ret;
+}
+
+static int rockchip_spi_slave_remove(struct platform_device *pdev)
+{
+	struct spi_controller *ctlr = spi_controller_get(platform_get_drvdata(pdev));
+	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
+
+	pm_runtime_get_sync(&pdev->dev);
+
+	clk_bulk_disable_unprepare(rs->clk_cnt, rs->clks);
+
+	pm_runtime_put_noidle(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
+
+	if (ctlr->dma_tx)
+		dma_release_channel(ctlr->dma_tx);
+	if (ctlr->dma_rx)
+		dma_release_channel(ctlr->dma_rx);
+
+	spi_controller_put(ctlr);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int rockchip_spi_slave_runtime_suspend(struct device *dev)
+{
+	struct spi_controller *ctlr = dev_get_drvdata(dev);
+	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
+
+	clk_bulk_disable_unprepare(rs->clk_cnt, rs->clks);
+
+	return 0;
+}
+
+static int rockchip_spi_slave_runtime_resume(struct device *dev)
+{
+	struct spi_controller *ctlr = dev_get_drvdata(dev);
+	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
+
+	return clk_bulk_prepare_enable(rs->clk_cnt, rs->clks);
+}
+#endif /* CONFIG_PM */
+
+#ifdef CONFIG_PM_SLEEP
+static int rockchip_spi_slave_suspend(struct device *dev)
+{
+	int ret;
+	struct spi_controller *ctlr = dev_get_drvdata(dev);
+
+	ret = spi_controller_suspend(ctlr);
+	if (ret < 0)
+		return ret;
+
+	/* Avoid redundant clock disable */
+	if (!pm_runtime_status_suspended(dev))
+		rockchip_spi_slave_runtime_suspend(dev);
+
+	pinctrl_pm_select_sleep_state(dev);
+
+	return 0;
+}
+
+static int rockchip_spi_slave_resume(struct device *dev)
+{
+	int ret;
+	struct spi_controller *ctlr = dev_get_drvdata(dev);
+
+	pinctrl_pm_select_default_state(dev);
+
+	if (!pm_runtime_status_suspended(dev)) {
+		ret = rockchip_spi_slave_runtime_resume(dev);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = spi_controller_resume(ctlr);
+	if (ret < 0)
+		rockchip_spi_slave_runtime_suspend(dev);
+
+	return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops rockchip_spi_slave_pm = {
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(rockchip_spi_slave_suspend, rockchip_spi_slave_resume)
+	SET_RUNTIME_PM_OPS(rockchip_spi_slave_runtime_suspend,
+			   rockchip_spi_slave_runtime_resume, NULL)
+};
+
+static const struct of_device_id rockchip_spi_slave_dt_match[] = {
+	{ .compatible = "rockchip,spi-slave", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, rockchip_spi_slave_dt_match);
+
+static struct platform_driver rockchip_spi_slave_driver = {
+	.driver = {
+		.name	= DRIVER_NAME,
+		.pm = &rockchip_spi_slave_pm,
+		.of_match_table = of_match_ptr(rockchip_spi_slave_dt_match),
+	},
+	.probe = rockchip_spi_slave_probe,
+	.remove = rockchip_spi_slave_remove,
+};
+
+module_platform_driver(rockchip_spi_slave_driver);
+
+MODULE_AUTHOR("Jon Lin <jon.lin@rock-chips.com>");
+MODULE_DESCRIPTION("ROCKCHIP SPI Slave Controller Driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/drivers/spi/spi-rockchip-test.c b/kernel/drivers/spi/spi-rockchip-test.c
index 544d603..f60c721 100644
--- a/kernel/drivers/spi/spi-rockchip-test.c
+++ b/kernel/drivers/spi/spi-rockchip-test.c
@@ -110,8 +110,8 @@
 	return ret;
 }
 
-int spi_write_then_read_slt(int id, const void *txbuf, unsigned n_tx,
-		void *rxbuf, unsigned n_rx)
+int spi_write_then_read_slt(int id, const void *txbuf, unsigned int n_tx,
+		void *rxbuf, unsigned int n_rx)
 {
 	int ret = -1;
 	struct spi_device *spi = NULL;
@@ -301,14 +301,21 @@
 		kfree(txbuf);
 		kfree(rxbuf);
 	} else if (!strcmp(cmd, "config")) {
-		int width;
+		int width, mode;
 
-		sscanf(argv[0], "%d", &width);
+		sscanf(argv[0], "%d", &id);
+		sscanf(argv[1], "%d", &width);
+		sscanf(argv[2], "mode=0x%x", &mode);
 
 		if (width == 16)
 			bit_per_word = 16;
 		else
 			bit_per_word = 8;
+
+		if (mode) {
+			g_spi_test_data[id]->spi->mode = mode;
+			spi_setup(g_spi_test_data[id]->spi);
+		}
 	} else {
 		printk("echo id number size > /dev/spi_misc_test\n");
 		printk("echo write 0 10 255 > /dev/spi_misc_test\n");
@@ -316,7 +323,7 @@
 		printk("echo read 0 10 255 > /dev/spi_misc_test\n");
 		printk("echo loop 0 10 255 > /dev/spi_misc_test\n");
 		printk("echo setspeed 0 1000000 > /dev/spi_misc_test\n");
-		printk("echo config 8 > /dev/spi_misc_test\n");
+		printk("echo config 0 8 mode=0xb > /dev/spi_misc_test\n");
 	}
 
 	return n;
diff --git a/kernel/drivers/spi/spi-rockchip.c b/kernel/drivers/spi/spi-rockchip.c
index b627663..3249334 100644
--- a/kernel/drivers/spi/spi-rockchip.c
+++ b/kernel/drivers/spi/spi-rockchip.c
@@ -478,8 +478,8 @@
 {
 	u32 i;
 
-	/* burst size: 1, 2, 4, 8 */
-	for (i = 1; i < 8; i <<= 1) {
+	/* burst size: 1, 2, 4, 8, 16 */
+	for (i = 1; i < 16; i <<= 1) {
 		if (data_len & i)
 			break;
 	}
@@ -906,6 +906,8 @@
 	cr0 |= ((spi->mode & 0x3) << CR0_SCPH_OFFSET);
 	if (spi->mode & SPI_CS_HIGH)
 		cr0 |= BIT(spi->chip_select) << CR0_SOI_OFFSET;
+	if (spi_controller_is_slave(spi->controller))
+		cr0 |= CR0_OPM_SLAVE << CR0_OPM_OFFSET;
 
 	writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0);
 
diff --git a/kernel/drivers/spi/spi-synquacer.c b/kernel/drivers/spi/spi-synquacer.c
index 47cbe73..dc188f9 100644
--- a/kernel/drivers/spi/spi-synquacer.c
+++ b/kernel/drivers/spi/spi-synquacer.c
@@ -472,10 +472,9 @@
 		read_fifo(sspi);
 	}
 
-	if (status < 0) {
-		dev_err(sspi->dev, "failed to transfer. status: 0x%x\n",
-			status);
-		return status;
+	if (status == 0) {
+		dev_err(sspi->dev, "failed to transfer. Timeout.\n");
+		return -ETIMEDOUT;
 	}
 
 	return 0;
diff --git a/kernel/drivers/spi/spi-tegra20-sflash.c b/kernel/drivers/spi/spi-tegra20-sflash.c
index cfb7de7..62e5083 100644
--- a/kernel/drivers/spi/spi-tegra20-sflash.c
+++ b/kernel/drivers/spi/spi-tegra20-sflash.c
@@ -456,7 +456,11 @@
 		goto exit_free_master;
 	}
 
-	tsd->irq = platform_get_irq(pdev, 0);
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
+		goto exit_free_master;
+	tsd->irq = ret;
+
 	ret = request_irq(tsd->irq, tegra_sflash_isr, 0,
 			dev_name(&pdev->dev), tsd);
 	if (ret < 0) {
diff --git a/kernel/drivers/spi/spi-zynqmp-gqspi.c b/kernel/drivers/spi/spi-zynqmp-gqspi.c
index 3d3ac48..12d9c5d 100644
--- a/kernel/drivers/spi/spi-zynqmp-gqspi.c
+++ b/kernel/drivers/spi/spi-zynqmp-gqspi.c
@@ -1147,11 +1147,16 @@
 	pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
 	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
+
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to pm_runtime_get_sync: %d\n", ret);
+		goto clk_dis_all;
+	}
+
 	/* QSPI controller initializations */
 	zynqmp_qspi_init_hw(xqspi);
 
-	pm_runtime_mark_last_busy(&pdev->dev);
-	pm_runtime_put_autosuspend(&pdev->dev);
 	xqspi->irq = platform_get_irq(pdev, 0);
 	if (xqspi->irq <= 0) {
 		ret = -ENXIO;
@@ -1178,6 +1183,7 @@
 	ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD |
 			    SPI_TX_DUAL | SPI_TX_QUAD;
 	ctlr->dev.of_node = np;
+	ctlr->auto_runtime_pm = true;
 
 	ret = devm_spi_register_controller(&pdev->dev, ctlr);
 	if (ret) {
@@ -1185,11 +1191,15 @@
 		goto clk_dis_all;
 	}
 
+	pm_runtime_mark_last_busy(&pdev->dev);
+	pm_runtime_put_autosuspend(&pdev->dev);
+
 	return 0;
 
 clk_dis_all:
-	pm_runtime_set_suspended(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
+	pm_runtime_put_noidle(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
 	clk_disable_unprepare(xqspi->refclk);
 clk_dis_pclk:
 	clk_disable_unprepare(xqspi->pclk);
@@ -1213,11 +1223,15 @@
 {
 	struct zynqmp_qspi *xqspi = platform_get_drvdata(pdev);
 
+	pm_runtime_get_sync(&pdev->dev);
+
 	zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, 0x0);
+
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_put_noidle(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
 	clk_disable_unprepare(xqspi->refclk);
 	clk_disable_unprepare(xqspi->pclk);
-	pm_runtime_set_suspended(&pdev->dev);
-	pm_runtime_disable(&pdev->dev);
 
 	return 0;
 }
diff --git a/kernel/drivers/spi/spidev-rkslv.c b/kernel/drivers/spi/spidev-rkslv.c
index 0ff4415..9f8cfcc 100644
--- a/kernel/drivers/spi/spidev-rkslv.c
+++ b/kernel/drivers/spi/spidev-rkslv.c
@@ -13,6 +13,8 @@
 #include <linux/slab.h>
 #include <linux/spi/spi.h>
 
+#include <soc/rockchip/rockchip-system-status.h>
+
 #define SPI_OBJ_MAX_XFER_SIZE	0x1040
 #define SPI_OBJ_APP_RAM_SIZE	0x10000
 
@@ -21,6 +23,8 @@
 #define SPI_OBJ_CTRL_CMD_READ	0x3A
 #define SPI_OBJ_CTRL_CMD_WRITE	0x4B
 #define SPI_OBJ_CTRL_CMD_DUPLEX	0x5C
+
+#define SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD  0x20
 
 struct spi_obj_ctrl {
 	u16 cmd;
@@ -38,42 +42,60 @@
 	struct task_struct *tsk;
 	bool tsk_run;
 	struct miscdevice misc_dev;
+
+	/*
+	 * If the DRAM frequency conversion jitters during the transmission process,
+	 * it will cause the DMA to be unable to transport SPI FIFO data in a timely
+	 * manner, resulting in FIFO overflow/underflow.
+	 *
+	 * However, since the command packet length is smaller than FIFO, this
+	 * problem does not exist. So set performance status dynamically for data packet.
+	 */
+	bool dyq_perf;
 };
 
 static u32 bit_per_word = 8;
 
-static int spidev_slv_write(struct spidev_rkslv_data *spidev, const void *txbuf, size_t n)
+static int spidev_slv_write(struct spidev_rkslv_data *spidev, const void *txbuf, size_t len)
 {
-	int ret = -1;
 	struct spi_device *spi = spidev->spi;
 	struct spi_transfer t = {
 			.tx_buf = txbuf,
-			.len = n,
+			.len = len,
 			.bits_per_word = bit_per_word,
 		};
 	struct spi_message m;
+	int ret;
 
 	spi_message_init(&m);
 	spi_message_add_tail(&t, &m);
+	if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD)
+		rockchip_set_system_status(SYS_STATUS_PERFORMANCE);
 	ret = spi_sync(spi, &m);
+	if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD)
+		rockchip_clear_system_status(SYS_STATUS_PERFORMANCE);
 
 	return ret;
 }
 
-static int spidev_slv_read(struct spidev_rkslv_data *spidev, void *rxbuf, size_t n)
+static int spidev_slv_read(struct spidev_rkslv_data *spidev, void *rxbuf, size_t len)
 {
-	int ret = -1;
 	struct spi_device *spi = spidev->spi;
 	struct spi_transfer t = {
 			.rx_buf = rxbuf,
-			.len = n,
+			.len = len,
 			.bits_per_word = bit_per_word,
 		};
 	struct spi_message m;
+	int ret;
 
 	spi_message_init(&m);
 	spi_message_add_tail(&t, &m);
+	if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD)
+		rockchip_set_system_status(SYS_STATUS_PERFORMANCE);
 	ret = spi_sync(spi, &m);
+	if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD)
+		rockchip_clear_system_status(SYS_STATUS_PERFORMANCE);
 
 	return ret;
 }
@@ -88,10 +110,18 @@
 			.len = len,
 		};
 	struct spi_message m;
+	int ret;
 
 	spi_message_init(&m);
 	spi_message_add_tail(&t, &m);
-	return spi_sync(spi, &m);
+
+	if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD)
+		rockchip_set_system_status(SYS_STATUS_PERFORMANCE);
+	ret = spi_sync(spi, &m);
+	if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD)
+		rockchip_clear_system_status(SYS_STATUS_PERFORMANCE);
+
+	return ret;
 }
 
 static ssize_t spidev_rkslv_misc_write(struct file *filp, const char __user *buf,
@@ -318,6 +348,7 @@
 	if (!spidev->tempbuf)
 		return -ENOMEM;
 
+	spidev->dyq_perf = true;
 	spidev->spi = spi;
 	spidev->dev = &spi->dev;
 	dev_set_drvdata(&spi->dev, spidev);
diff --git a/kernel/drivers/spi/spidev.c b/kernel/drivers/spi/spidev.c
index da816d5..e08de32 100644
--- a/kernel/drivers/spi/spidev.c
+++ b/kernel/drivers/spi/spidev.c
@@ -376,12 +376,23 @@
 	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,
@@ -581,7 +592,6 @@
 	if (!spidev->tx_buffer) {
 		spidev->tx_buffer = kmalloc(bufsiz, GFP_KERNEL);
 		if (!spidev->tx_buffer) {
-			dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
 			status = -ENOMEM;
 			goto err_find_dev;
 		}
@@ -590,7 +600,6 @@
 	if (!spidev->rx_buffer) {
 		spidev->rx_buffer = kmalloc(bufsiz, GFP_KERNEL);
 		if (!spidev->rx_buffer) {
-			dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
 			status = -ENOMEM;
 			goto err_alloc_rx_buf;
 		}
diff --git a/kernel/drivers/spmi/spmi.c b/kernel/drivers/spmi/spmi.c
index c16b60f..8ca7e00 100644
--- a/kernel/drivers/spmi/spmi.c
+++ b/kernel/drivers/spmi/spmi.c
@@ -348,7 +348,8 @@
 	const struct spmi_driver *sdrv = to_spmi_driver(dev->driver);
 
 	pm_runtime_get_sync(dev);
-	sdrv->remove(to_spmi_device(dev));
+	if (sdrv->remove)
+		sdrv->remove(to_spmi_device(dev));
 	pm_runtime_put_noidle(dev);
 
 	pm_runtime_disable(dev);
diff --git a/kernel/drivers/staging/comedi/drivers/adv_pci1760.c b/kernel/drivers/staging/comedi/drivers/adv_pci1760.c
index 6de8ab9..d6934b6 100644
--- a/kernel/drivers/staging/comedi/drivers/adv_pci1760.c
+++ b/kernel/drivers/staging/comedi/drivers/adv_pci1760.c
@@ -59,7 +59,7 @@
 #define PCI1760_CMD_CLR_IMB2		0x00	/* Clears IMB2 */
 #define PCI1760_CMD_SET_DO		0x01	/* Set output state */
 #define PCI1760_CMD_GET_DO		0x02	/* Read output status */
-#define PCI1760_CMD_GET_STATUS		0x03	/* Read current status */
+#define PCI1760_CMD_GET_STATUS		0x07	/* Read current status */
 #define PCI1760_CMD_GET_FW_VER		0x0e	/* Read firmware version */
 #define PCI1760_CMD_GET_HW_VER		0x0f	/* Read hardware version */
 #define PCI1760_CMD_SET_PWM_HI(x)	(0x10 + (x) * 2) /* Set "hi" period */
diff --git a/kernel/drivers/staging/emxx_udc/emxx_udc.c b/kernel/drivers/staging/emxx_udc/emxx_udc.c
index 3897f8e..6870a33 100644
--- a/kernel/drivers/staging/emxx_udc/emxx_udc.c
+++ b/kernel/drivers/staging/emxx_udc/emxx_udc.c
@@ -2591,10 +2591,15 @@
 		req->unaligned = false;
 
 	if (req->unaligned) {
-		if (!ep->virt_buf)
+		if (!ep->virt_buf) {
 			ep->virt_buf = dma_alloc_coherent(udc->dev, PAGE_SIZE,
 							  &ep->phys_buf,
 							  GFP_ATOMIC | GFP_DMA);
+			if (!ep->virt_buf) {
+				spin_unlock_irqrestore(&udc->lock, flags);
+				return -ENOMEM;
+			}
+		}
 		if (ep->epnum > 0)  {
 			if (ep->direct == USB_DIR_IN)
 				memcpy(ep->virt_buf, req->req.buf,
diff --git a/kernel/drivers/staging/iio/accel/adis16203.c b/kernel/drivers/staging/iio/accel/adis16203.c
index b68304d..7be44ff 100644
--- a/kernel/drivers/staging/iio/accel/adis16203.c
+++ b/kernel/drivers/staging/iio/accel/adis16203.c
@@ -318,3 +318,4 @@
 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/kernel/drivers/staging/iio/accel/adis16240.c b/kernel/drivers/staging/iio/accel/adis16240.c
index 5064adc..dbbbf81 100644
--- a/kernel/drivers/staging/iio/accel/adis16240.c
+++ b/kernel/drivers/staging/iio/accel/adis16240.c
@@ -445,3 +445,4 @@
 MODULE_DESCRIPTION("Analog Devices Programmable Impact Sensor and Recorder");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("spi:adis16240");
+MODULE_IMPORT_NS(IIO_ADISLIB);
diff --git a/kernel/drivers/staging/iio/resolver/ad2s1210.c b/kernel/drivers/staging/iio/resolver/ad2s1210.c
index 74adb82..a19cfb2 100644
--- a/kernel/drivers/staging/iio/resolver/ad2s1210.c
+++ b/kernel/drivers/staging/iio/resolver/ad2s1210.c
@@ -101,7 +101,7 @@
 static const int ad2s1210_mode_vals[4][2] = {
 	[MOD_POS] = { 0, 0 },
 	[MOD_VEL] = { 0, 1 },
-	[MOD_CONFIG] = { 1, 0 },
+	[MOD_CONFIG] = { 1, 1 },
 };
 
 static inline void ad2s1210_set_mode(enum ad2s1210_mode mode,
diff --git a/kernel/drivers/staging/ks7010/ks_wlan_net.c b/kernel/drivers/staging/ks7010/ks_wlan_net.c
index 09e7b4c..6048822 100644
--- a/kernel/drivers/staging/ks7010/ks_wlan_net.c
+++ b/kernel/drivers/staging/ks7010/ks_wlan_net.c
@@ -1584,8 +1584,10 @@
 			commit |= SME_WEP_FLAG;
 		}
 		if (enc->key_len) {
-			memcpy(&key->key_val[0], &enc->key[0], enc->key_len);
-			key->key_len = enc->key_len;
+			int key_len = clamp_val(enc->key_len, 0, IW_ENCODING_TOKEN_MAX);
+
+			memcpy(&key->key_val[0], &enc->key[0], key_len);
+			key->key_len = key_len;
 			commit |= (SME_WEP_VAL1 << index);
 		}
 		break;
diff --git a/kernel/drivers/staging/media/atomisp/Kconfig b/kernel/drivers/staging/media/atomisp/Kconfig
index 37577bb..1a0b958 100644
--- a/kernel/drivers/staging/media/atomisp/Kconfig
+++ b/kernel/drivers/staging/media/atomisp/Kconfig
@@ -13,6 +13,7 @@
 	tristate "Intel Atom Image Signal Processor Driver"
 	depends on VIDEO_V4L2 && INTEL_ATOMISP
 	depends on PMIC_OPREGION
+	select V4L2_FWNODE
 	select IOSF_MBI
 	select VIDEOBUF_VMALLOC
 	help
diff --git a/kernel/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/kernel/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index 20c19e0..613bd96 100644
--- a/kernel/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/kernel/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -5243,7 +5243,7 @@
 	int (*configure_pp_input)(struct atomisp_sub_device *asd,
 				  unsigned int width, unsigned int height) =
 				      configure_pp_input_nop;
-	u16 stream_index = atomisp_source_pad_to_stream_id(asd, source_pad);
+	u16 stream_index;
 	const struct atomisp_in_fmt_conv *fc;
 	int ret, i;
 
@@ -5252,6 +5252,7 @@
 			__func__, vdev->name);
 		return -EINVAL;
 	}
+	stream_index = atomisp_source_pad_to_stream_id(asd, source_pad);
 
 	v4l2_fh_init(&fh.vfh, vdev);
 
diff --git a/kernel/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/kernel/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
index c9ee850..f038748 100644
--- a/kernel/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
+++ b/kernel/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
@@ -1198,7 +1198,7 @@
 	dev_info(dev, "found _DSM entry for '%s': %s\n", var,
 		 cur->string.pointer);
 	strscpy(out, cur->string.pointer, *out_len);
-	*out_len = strlen(cur->string.pointer);
+	*out_len = strlen(out);
 
 	ACPI_FREE(obj);
 	return 0;
diff --git a/kernel/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/kernel/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index 8a0648f..4615e4c 100644
--- a/kernel/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/kernel/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -1123,7 +1123,7 @@
 	struct ia_css_frame *frame;
 	struct videobuf_vmalloc_memory *vm_mem;
 	u16 source_pad = atomisp_subdev_source_pad(vdev);
-	u16 stream_id = atomisp_source_pad_to_stream_id(asd, source_pad);
+	u16 stream_id;
 	int ret = 0, i = 0;
 
 	if (!asd) {
@@ -1131,6 +1131,7 @@
 			__func__, vdev->name);
 		return -EINVAL;
 	}
+	stream_id = atomisp_source_pad_to_stream_id(asd, source_pad);
 
 	if (req->count == 0) {
 		mutex_lock(&pipe->capq.vb_lock);
diff --git a/kernel/drivers/staging/media/rkvdec/rkvdec.c b/kernel/drivers/staging/media/rkvdec/rkvdec.c
index e384ea8..86483f1 100644
--- a/kernel/drivers/staging/media/rkvdec/rkvdec.c
+++ b/kernel/drivers/staging/media/rkvdec/rkvdec.c
@@ -101,7 +101,7 @@
 			.max_width = 4096,
 			.step_width = 16,
 			.min_height = 48,
-			.max_height = 2304,
+			.max_height = 2560,
 			.step_height = 16,
 		},
 		.ctrls = &rkvdec_h264_ctrls,
@@ -1077,6 +1077,8 @@
 {
 	struct rkvdec_dev *rkvdec = platform_get_drvdata(pdev);
 
+	cancel_delayed_work_sync(&rkvdec->watchdog_work);
+
 	rkvdec_v4l2_cleanup(rkvdec);
 	pm_runtime_disable(&pdev->dev);
 	pm_runtime_dont_use_autosuspend(&pdev->dev);
diff --git a/kernel/drivers/staging/media/tegra-video/csi.c b/kernel/drivers/staging/media/tegra-video/csi.c
index a19c85c..dc5d432 100644
--- a/kernel/drivers/staging/media/tegra-video/csi.c
+++ b/kernel/drivers/staging/media/tegra-video/csi.c
@@ -420,7 +420,7 @@
 	chan->csi = csi;
 	chan->csi_port_num = port_num;
 	chan->numlanes = lanes;
-	chan->of_node = node;
+	chan->of_node = of_node_get(node);
 	chan->numpads = num_pads;
 	if (num_pads & 0x2) {
 		chan->pads[0].flags = MEDIA_PAD_FL_SINK;
@@ -435,6 +435,7 @@
 	chan->mipi = tegra_mipi_request(csi->dev, node);
 	if (IS_ERR(chan->mipi)) {
 		ret = PTR_ERR(chan->mipi);
+		chan->mipi = NULL;
 		dev_err(csi->dev, "failed to get mipi device: %d\n", ret);
 	}
 
@@ -620,6 +621,7 @@
 			media_entity_cleanup(&subdev->entity);
 		}
 
+		of_node_put(chan->of_node);
 		list_del(&chan->list);
 		kfree(chan);
 	}
diff --git a/kernel/drivers/staging/media/tegra-video/csi.h b/kernel/drivers/staging/media/tegra-video/csi.h
index c65ff73..be4ea81 100644
--- a/kernel/drivers/staging/media/tegra-video/csi.h
+++ b/kernel/drivers/staging/media/tegra-video/csi.h
@@ -50,7 +50,7 @@
  * @framerate: active framerate for TPG
  * @h_blank: horizontal blanking for TPG active format
  * @v_blank: vertical blanking for TPG active format
- * @mipi: mipi device for corresponding csi channel pads
+ * @mipi: mipi device for corresponding csi channel pads, or NULL if not applicable (TPG, error)
  * @pixel_rate: active pixel rate from the sensor on this channel
  */
 struct tegra_csi_channel {
diff --git a/kernel/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/kernel/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
index 99c27d6..291f982 100644
--- a/kernel/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
+++ b/kernel/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
@@ -770,6 +770,7 @@
 	else
 		netif_wake_queue(dev);
 
+	priv->bfirst_after_down = false;
 	return 0;
 }
 
diff --git a/kernel/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/kernel/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
index 4628356..916ff50 100644
--- a/kernel/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
+++ b/kernel/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
@@ -185,7 +185,6 @@
 static void _rtl92e_dm_deinit_fsync(struct net_device *dev);
 
 static	void _rtl92e_dm_check_txrateandretrycount(struct net_device *dev);
-static  void _rtl92e_dm_check_ac_dc_power(struct net_device *dev);
 static void _rtl92e_dm_check_fsync(struct net_device *dev);
 static void _rtl92e_dm_check_rf_ctrl_gpio(void *data);
 static void _rtl92e_dm_fsync_timer_callback(struct timer_list *t);
@@ -238,8 +237,6 @@
 	if (priv->being_init_adapter)
 		return;
 
-	_rtl92e_dm_check_ac_dc_power(dev);
-
 	_rtl92e_dm_check_txrateandretrycount(dev);
 	_rtl92e_dm_check_edca_turbo(dev);
 
@@ -256,30 +253,6 @@
 	_rtl92e_dm_send_rssi_to_fw(dev);
 	_rtl92e_dm_cts_to_self(dev);
 }
-
-static void _rtl92e_dm_check_ac_dc_power(struct net_device *dev)
-{
-	struct r8192_priv *priv = rtllib_priv(dev);
-	static char const ac_dc_script[] = "/etc/acpi/wireless-rtl-ac-dc-power.sh";
-	char *argv[] = {(char *)ac_dc_script, DRV_NAME, NULL};
-	static char *envp[] = {"HOME=/",
-			"TERM=linux",
-			"PATH=/usr/bin:/bin",
-			 NULL};
-
-	if (priv->ResetProgress == RESET_TYPE_SILENT) {
-		RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),
-			 "GPIOChangeRFWorkItemCallBack(): Silent Reset!!!!!!!\n");
-		return;
-	}
-
-	if (priv->rtllib->state != RTLLIB_LINKED)
-		return;
-	call_usermodehelper(ac_dc_script, argv, envp, UMH_WAIT_PROC);
-
-	return;
-};
-
 
 void rtl92e_init_adaptive_rate(struct net_device *dev)
 {
@@ -1800,10 +1773,6 @@
 	u8 tmp1byte;
 	enum rt_rf_power_state eRfPowerStateToSet;
 	bool bActuallySet = false;
-	char *argv[3];
-	static char const RadioPowerPath[] = "/etc/acpi/events/RadioPower.sh";
-	static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin",
-			       NULL};
 
 	bActuallySet = false;
 
@@ -1835,14 +1804,6 @@
 		mdelay(1000);
 		priv->bHwRfOffAction = 1;
 		rtl92e_set_rf_state(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
-		if (priv->bHwRadioOff)
-			argv[1] = "RFOFF";
-		else
-			argv[1] = "RFON";
-
-		argv[0] = (char *)RadioPowerPath;
-		argv[2] = NULL;
-		call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
 	}
 }
 
diff --git a/kernel/drivers/staging/rtl8192e/rtllib_rx.c b/kernel/drivers/staging/rtl8192e/rtllib_rx.c
index 6375223..4047945 100644
--- a/kernel/drivers/staging/rtl8192e/rtllib_rx.c
+++ b/kernel/drivers/staging/rtl8192e/rtllib_rx.c
@@ -1490,9 +1490,9 @@
 		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;
 }
diff --git a/kernel/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/kernel/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
index b6fee72..3871437 100644
--- a/kernel/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
+++ b/kernel/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
@@ -954,9 +954,11 @@
 #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;
 	}
 
diff --git a/kernel/drivers/staging/rtl8712/ieee80211.c b/kernel/drivers/staging/rtl8712/ieee80211.c
index b4a0991..8075ed2 100644
--- a/kernel/drivers/staging/rtl8712/ieee80211.c
+++ b/kernel/drivers/staging/rtl8712/ieee80211.c
@@ -181,25 +181,25 @@
 	sz += 2;
 	ie += 2;
 	/*SSID*/
-	ie = r8712_set_ie(ie, _SSID_IE_, dev_network->Ssid.SsidLength,
+	ie = r8712_set_ie(ie, WLAN_EID_SSID, dev_network->Ssid.SsidLength,
 			  dev_network->Ssid.Ssid, &sz);
 	/*supported rates*/
 	set_supported_rate(dev_network->rates, registrypriv->wireless_mode);
 	rate_len = r8712_get_rateset_len(dev_network->rates);
 	if (rate_len > 8) {
-		ie = r8712_set_ie(ie, _SUPPORTEDRATES_IE_, 8,
+		ie = r8712_set_ie(ie, WLAN_EID_SUPP_RATES, 8,
 				  dev_network->rates, &sz);
-		ie = r8712_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8),
+		ie = r8712_set_ie(ie, WLAN_EID_EXT_SUPP_RATES, (rate_len - 8),
 				  (dev_network->rates + 8), &sz);
 	} else {
-		ie = r8712_set_ie(ie, _SUPPORTEDRATES_IE_,
+		ie = r8712_set_ie(ie, WLAN_EID_SUPP_RATES,
 				  rate_len, dev_network->rates, &sz);
 	}
 	/*DS parameter set*/
-	ie = r8712_set_ie(ie, _DSSET_IE_, 1,
+	ie = r8712_set_ie(ie, WLAN_EID_DS_PARAMS, 1,
 			  (u8 *)&dev_network->Configuration.DSConfig, &sz);
 	/*IBSS Parameter Set*/
-	ie = r8712_set_ie(ie, _IBSS_PARA_IE_, 2,
+	ie = r8712_set_ie(ie, WLAN_EID_IBSS_PARAMS, 2,
 			  (u8 *)&dev_network->Configuration.ATIMWindow, &sz);
 	return sz;
 }
diff --git a/kernel/drivers/staging/rtl8712/os_intfs.c b/kernel/drivers/staging/rtl8712/os_intfs.c
index daa3180..5dfc9e3 100644
--- a/kernel/drivers/staging/rtl8712/os_intfs.c
+++ b/kernel/drivers/staging/rtl8712/os_intfs.c
@@ -323,6 +323,7 @@
 	mp871xinit(padapter);
 	init_default_value(padapter);
 	r8712_InitSwLeds(padapter);
+	mutex_init(&padapter->mutex_start);
 	return ret;
 }
 
diff --git a/kernel/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/kernel/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
index 2a661b0..15c6ac5 100644
--- a/kernel/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
+++ b/kernel/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
@@ -236,7 +236,7 @@
 	start = iwe_stream_add_point(info, start, stop, &iwe,
 				     pnetwork->network.Ssid.Ssid);
 	/* parsing HT_CAP_IE */
-	p = r8712_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_,
+	p = r8712_get_ie(&pnetwork->network.IEs[12], WLAN_EID_HT_CAPABILITY,
 			 &ht_ielen, pnetwork->network.IELength - 12);
 	if (p && ht_ielen > 0)
 		ht_cap = true;
@@ -567,7 +567,7 @@
 			while (cnt < ielen) {
 				eid = buf[cnt];
 
-				if ((eid == _VENDOR_SPECIFIC_IE_) &&
+				if ((eid == WLAN_EID_VENDOR_SPECIFIC) &&
 				    (!memcmp(&buf[cnt + 2], wps_oui, 4))) {
 					netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE\n");
 					padapter->securitypriv.wps_ie_len =
@@ -609,7 +609,7 @@
 	if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) ==
 	    true) {
 		/* parsing HT_CAP_IE */
-		p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
+		p = r8712_get_ie(&pcur_bss->IEs[12], WLAN_EID_HT_CAPABILITY,
 				 &ht_ielen, pcur_bss->IELength - 12);
 		if (p && ht_ielen > 0)
 			ht_cap = true;
@@ -1403,7 +1403,7 @@
 	i = 0;
 	if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE))
 		return -ENOLINK;
-	p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen,
+	p = r8712_get_ie(&pcur_bss->IEs[12], WLAN_EID_HT_CAPABILITY, &ht_ielen,
 			 pcur_bss->IELength - 12);
 	if (p && ht_ielen > 0) {
 		ht_cap = true;
diff --git a/kernel/drivers/staging/rtl8712/rtl871x_mlme.c b/kernel/drivers/staging/rtl8712/rtl871x_mlme.c
index 6074383..250cb0c 100644
--- a/kernel/drivers/staging/rtl8712/rtl871x_mlme.c
+++ b/kernel/drivers/staging/rtl8712/rtl871x_mlme.c
@@ -1649,11 +1649,11 @@
 	struct ht_priv *phtpriv = &pmlmepriv->htpriv;
 
 	phtpriv->ht_option = 0;
-	p = r8712_get_ie(in_ie + 12, _HT_CAPABILITY_IE_, &ielen, in_len - 12);
+	p = r8712_get_ie(in_ie + 12, WLAN_EID_HT_CAPABILITY, &ielen, in_len - 12);
 	if (p && (ielen > 0)) {
 		if (pqospriv->qos_option == 0) {
 			out_len = *pout_len;
-			r8712_set_ie(out_ie + out_len, _VENDOR_SPECIFIC_IE_,
+			r8712_set_ie(out_ie + out_len, WLAN_EID_VENDOR_SPECIFIC,
 				     _WMM_IE_Length_, WMM_IE, pout_len);
 			pqospriv->qos_option = 1;
 		}
@@ -1667,7 +1667,7 @@
 				    IEEE80211_HT_CAP_DSSSCCK40);
 		ht_capie.ampdu_params_info = (IEEE80211_HT_AMPDU_PARM_FACTOR &
 				0x03) | (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00);
-		r8712_set_ie(out_ie + out_len, _HT_CAPABILITY_IE_,
+		r8712_set_ie(out_ie + out_len, WLAN_EID_HT_CAPABILITY,
 			     sizeof(struct rtl_ieee80211_ht_cap),
 			     (unsigned char *)&ht_capie, pout_len);
 		phtpriv->ht_option = 1;
@@ -1698,7 +1698,7 @@
 	/*check Max Rx A-MPDU Size*/
 	len = 0;
 	p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs),
-				_HT_CAPABILITY_IE_,
+				WLAN_EID_HT_CAPABILITY,
 				&len, ie_len -
 				sizeof(struct NDIS_802_11_FIXED_IEs));
 	if (p && len > 0) {
@@ -1733,7 +1733,7 @@
 	}
 	len = 0;
 	p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs),
-		   _HT_ADD_INFO_IE_, &len,
+		   WLAN_EID_HT_OPERATION, &len,
 		   ie_len - sizeof(struct NDIS_802_11_FIXED_IEs));
 }
 
diff --git a/kernel/drivers/staging/rtl8712/rtl871x_xmit.c b/kernel/drivers/staging/rtl8712/rtl871x_xmit.c
index fd99782..eb64930 100644
--- a/kernel/drivers/staging/rtl8712/rtl871x_xmit.c
+++ b/kernel/drivers/staging/rtl8712/rtl871x_xmit.c
@@ -22,6 +22,8 @@
 #include "osdep_intf.h"
 #include "usb_ops.h"
 
+#include <linux/usb.h>
+#include <linux/ieee80211.h>
 
 static const u8 P802_1H_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0xf8};
 static const u8 RFC1042_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0x00};
@@ -55,6 +57,7 @@
 	sint i;
 	struct xmit_buf *pxmitbuf;
 	struct xmit_frame *pxframe;
+	int j;
 
 	memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv));
 	spin_lock_init(&pxmitpriv->lock);
@@ -117,11 +120,8 @@
 	_init_queue(&pxmitpriv->pending_xmitbuf_queue);
 	pxmitpriv->pallocated_xmitbuf =
 		kmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4, GFP_ATOMIC);
-	if (!pxmitpriv->pallocated_xmitbuf) {
-		kfree(pxmitpriv->pallocated_frame_buf);
-		pxmitpriv->pallocated_frame_buf = NULL;
-		return -ENOMEM;
-	}
+	if (!pxmitpriv->pallocated_xmitbuf)
+		goto clean_up_frame_buf;
 	pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 -
 			      ((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3);
 	pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
@@ -129,13 +129,17 @@
 		INIT_LIST_HEAD(&pxmitbuf->list);
 		pxmitbuf->pallocated_buf =
 			kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ, GFP_ATOMIC);
-		if (!pxmitbuf->pallocated_buf)
-			return -ENOMEM;
+		if (!pxmitbuf->pallocated_buf) {
+			j = 0;
+			goto clean_up_alloc_buf;
+		}
 		pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ -
 				 ((addr_t) (pxmitbuf->pallocated_buf) &
 				 (XMITBUF_ALIGN_SZ - 1));
-		if (r8712_xmit_resource_alloc(padapter, pxmitbuf))
-			return -ENOMEM;
+		if (r8712_xmit_resource_alloc(padapter, pxmitbuf)) {
+			j = 1;
+			goto clean_up_alloc_buf;
+		}
 		list_add_tail(&pxmitbuf->list,
 				 &(pxmitpriv->free_xmitbuf_queue.queue));
 		pxmitbuf++;
@@ -146,6 +150,28 @@
 	init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
 	tasklet_setup(&pxmitpriv->xmit_tasklet, r8712_xmit_bh);
 	return 0;
+
+clean_up_alloc_buf:
+	if (j) {
+		/* failure happened in r8712_xmit_resource_alloc()
+		 * delete extra pxmitbuf->pallocated_buf
+		 */
+		kfree(pxmitbuf->pallocated_buf);
+	}
+	for (j = 0; j < i; j++) {
+		int k;
+
+		pxmitbuf--;			/* reset pointer */
+		kfree(pxmitbuf->pallocated_buf);
+		for (k = 0; k < 8; k++)		/* delete xmit urb's */
+			usb_free_urb(pxmitbuf->pxmit_urb[k]);
+	}
+	kfree(pxmitpriv->pallocated_xmitbuf);
+	pxmitpriv->pallocated_xmitbuf = NULL;
+clean_up_frame_buf:
+	kfree(pxmitpriv->pallocated_frame_buf);
+	pxmitpriv->pallocated_frame_buf = NULL;
+	return -ENOMEM;
 }
 
 void _free_xmit_priv(struct xmit_priv *pxmitpriv)
@@ -709,7 +735,7 @@
 		break;
 	case AUTO_VCS:
 	default:
-		perp = r8712_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len);
+		perp = r8712_get_ie(ie, WLAN_EID_ERP_INFO, &erp_len, ie_len);
 		if (!perp) {
 			pxmitpriv->vcs = NONE_VCS;
 		} else {
diff --git a/kernel/drivers/staging/rtl8712/usb_intf.c b/kernel/drivers/staging/rtl8712/usb_intf.c
index 68d66c3..67f89ea 100644
--- a/kernel/drivers/staging/rtl8712/usb_intf.c
+++ b/kernel/drivers/staging/rtl8712/usb_intf.c
@@ -570,7 +570,6 @@
 	if (rtl871x_load_fw(padapter))
 		goto deinit_drv_sw;
 	spin_lock_init(&padapter->lock_rx_ff0_filter);
-	mutex_init(&padapter->mutex_start);
 	return 0;
 
 deinit_drv_sw:
diff --git a/kernel/drivers/staging/rtl8712/wifi.h b/kernel/drivers/staging/rtl8712/wifi.h
index 601d4ff..9bb310b 100644
--- a/kernel/drivers/staging/rtl8712/wifi.h
+++ b/kernel/drivers/staging/rtl8712/wifi.h
@@ -374,21 +374,6 @@
 
 #define _FIXED_IE_LENGTH_	_BEACON_IE_OFFSET_
 
-#define _SSID_IE_		0
-#define _SUPPORTEDRATES_IE_	1
-#define _DSSET_IE_		3
-#define _IBSS_PARA_IE_		6
-#define _ERPINFO_IE_		42
-#define _EXT_SUPPORTEDRATES_IE_	50
-
-#define _HT_CAPABILITY_IE_	45
-#define _HT_EXTRA_INFO_IE_	61
-#define _HT_ADD_INFO_IE_	61 /* _HT_EXTRA_INFO_IE_ */
-
-#define _VENDOR_SPECIFIC_IE_	221
-
-#define	_RESERVED47_		47
-
 /* ---------------------------------------------------------------------------
  *			Below is the fixed elements...
  * ---------------------------------------------------------------------------
diff --git a/kernel/drivers/staging/rtl8712/xmit_linux.c b/kernel/drivers/staging/rtl8712/xmit_linux.c
index 1f67d86..9050e51 100644
--- a/kernel/drivers/staging/rtl8712/xmit_linux.c
+++ b/kernel/drivers/staging/rtl8712/xmit_linux.c
@@ -119,6 +119,12 @@
 	for (i = 0; i < 8; i++) {
 		pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
 		if (!pxmitbuf->pxmit_urb[i]) {
+			int k;
+
+			for (k = i - 1; k >= 0; k--) {
+				/* handle allocation errors part way through loop */
+				usb_free_urb(pxmitbuf->pxmit_urb[k]);
+			}
 			netdev_err(padapter->pnetdev, "pxmitbuf->pxmit_urb[i] == NULL\n");
 			return -ENOMEM;
 		}
diff --git a/kernel/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h b/kernel/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h
index fefc664..f5e1ae5 100644
--- a/kernel/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h
+++ b/kernel/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h
@@ -82,7 +82,7 @@
 
 struct vchiq_instance;
 
-extern enum vchiq_status vchiq_initialise(struct vchiq_instance **pinstance);
+extern int vchiq_initialise(struct vchiq_instance **pinstance);
 extern enum vchiq_status vchiq_shutdown(struct vchiq_instance *instance);
 extern enum vchiq_status vchiq_connect(struct vchiq_instance *instance);
 extern enum vchiq_status vchiq_open_service(struct vchiq_instance *instance,
diff --git a/kernel/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/kernel/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index 3d378da..178cf90 100644
--- a/kernel/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/kernel/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -147,12 +147,11 @@
 	unsigned int size, enum vchiq_bulk_dir dir);
 
 #define VCHIQ_INIT_RETRIES 10
-enum vchiq_status vchiq_initialise(struct vchiq_instance **instance_out)
+int vchiq_initialise(struct vchiq_instance **instance_out)
 {
-	enum vchiq_status status = VCHIQ_ERROR;
 	struct vchiq_state *state;
 	struct vchiq_instance *instance = NULL;
-	int i;
+	int i, ret;
 
 	vchiq_log_trace(vchiq_core_log_level, "%s called", __func__);
 
@@ -169,6 +168,7 @@
 	if (i == VCHIQ_INIT_RETRIES) {
 		vchiq_log_error(vchiq_core_log_level,
 			"%s: videocore not initialized\n", __func__);
+		ret = -ENOTCONN;
 		goto failed;
 	} else if (i > 0) {
 		vchiq_log_warning(vchiq_core_log_level,
@@ -180,6 +180,7 @@
 	if (!instance) {
 		vchiq_log_error(vchiq_core_log_level,
 			"%s: error allocating vchiq instance\n", __func__);
+		ret = -ENOMEM;
 		goto failed;
 	}
 
@@ -190,13 +191,13 @@
 
 	*instance_out = instance;
 
-	status = VCHIQ_SUCCESS;
+	ret = 0;
 
 failed:
 	vchiq_log_trace(vchiq_core_log_level,
-		"%s(%p): returning %d", __func__, instance, status);
+		"%s(%p): returning %d", __func__, instance, ret);
 
-	return status;
+	return ret;
 }
 EXPORT_SYMBOL(vchiq_initialise);
 
@@ -2223,6 +2224,7 @@
 	enum vchiq_status status;
 	struct vchiq_instance *instance;
 	unsigned int ka_handle;
+	int ret;
 
 	struct vchiq_service_params_kernel params = {
 		.fourcc      = VCHIQ_MAKE_FOURCC('K', 'E', 'E', 'P'),
@@ -2231,10 +2233,10 @@
 		.version_min = KEEPALIVE_VER_MIN
 	};
 
-	status = vchiq_initialise(&instance);
-	if (status != VCHIQ_SUCCESS) {
+	ret = vchiq_initialise(&instance);
+	if (ret) {
 		vchiq_log_error(vchiq_susp_log_level,
-			"%s vchiq_initialise failed %d", __func__, status);
+			"%s vchiq_initialise failed %d", __func__, ret);
 		goto exit;
 	}
 
@@ -2313,7 +2315,7 @@
 	return VCHIQ_SUCCESS;
 }
 
-enum vchiq_status
+int
 vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service,
 		   enum USE_TYPE_E use_type)
 {
@@ -2373,7 +2375,7 @@
 	return ret;
 }
 
-enum vchiq_status
+int
 vchiq_release_internal(struct vchiq_state *state, struct vchiq_service *service)
 {
 	struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
diff --git a/kernel/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h b/kernel/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
index 0784c50..77d8fb1 100644
--- a/kernel/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
+++ b/kernel/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
@@ -89,10 +89,10 @@
 vchiq_platform_get_arm_state(struct vchiq_state *state);
 
 
-extern enum vchiq_status
+extern int
 vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service,
 		   enum USE_TYPE_E use_type);
-extern enum vchiq_status
+extern int
 vchiq_release_internal(struct vchiq_state *state,
 		       struct vchiq_service *service);
 
diff --git a/kernel/drivers/target/iscsi/iscsi_target.c b/kernel/drivers/target/iscsi/iscsi_target.c
index a237f1c..075e2a6 100644
--- a/kernel/drivers/target/iscsi/iscsi_target.c
+++ b/kernel/drivers/target/iscsi/iscsi_target.c
@@ -4084,9 +4084,12 @@
 	list_for_each_entry_safe(cmd, cmd_tmp, &tmp_list, i_conn_node) {
 		struct se_cmd *se_cmd = &cmd->se_cmd;
 
-		if (se_cmd->se_tfo != NULL) {
-			spin_lock_irq(&se_cmd->t_state_lock);
-			if (se_cmd->transport_state & CMD_T_ABORTED) {
+		if (!se_cmd->se_tfo)
+			continue;
+
+		spin_lock_irq(&se_cmd->t_state_lock);
+		if (se_cmd->transport_state & CMD_T_ABORTED) {
+			if (!(se_cmd->transport_state & CMD_T_TAS))
 				/*
 				 * LIO's abort path owns the cleanup for this,
 				 * so put it back on the list and let
@@ -4094,11 +4097,10 @@
 				 */
 				list_move_tail(&cmd->i_conn_node,
 					       &conn->conn_cmd_list);
-			} else {
-				se_cmd->transport_state |= CMD_T_FABRIC_STOP;
-			}
-			spin_unlock_irq(&se_cmd->t_state_lock);
+		} else {
+			se_cmd->transport_state |= CMD_T_FABRIC_STOP;
 		}
+		spin_unlock_irq(&se_cmd->t_state_lock);
 	}
 	spin_unlock_bh(&conn->cmd_lock);
 
@@ -4383,6 +4385,9 @@
 	iscsit_stop_time2retain_timer(sess);
 	spin_unlock_bh(&se_tpg->session_lock);
 
+	if (sess->sess_ops->ErrorRecoveryLevel == 2)
+		iscsit_free_connection_recovery_entries(sess);
+
 	/*
 	 * transport_deregister_session_configfs() will clear the
 	 * struct se_node_acl->nacl_sess pointer now as a iscsi_np process context
@@ -4409,9 +4414,6 @@
 	}
 
 	transport_deregister_session(sess->se_sess);
-
-	if (sess->sess_ops->ErrorRecoveryLevel == 2)
-		iscsit_free_connection_recovery_entries(sess);
 
 	iscsit_free_all_ooo_cmdsns(sess);
 
diff --git a/kernel/drivers/target/iscsi/iscsi_target_configfs.c b/kernel/drivers/target/iscsi/iscsi_target_configfs.c
index 0fa1d57..3cd671b 100644
--- a/kernel/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/kernel/drivers/target/iscsi/iscsi_target_configfs.c
@@ -508,102 +508,102 @@
 	spin_lock_bh(&se_nacl->nacl_sess_lock);
 	se_sess = se_nacl->nacl_sess;
 	if (!se_sess) {
-		rb += sprintf(page+rb, "No active iSCSI Session for Initiator"
+		rb += sysfs_emit_at(page, rb, "No active iSCSI Session for Initiator"
 			" Endpoint: %s\n", se_nacl->initiatorname);
 	} else {
 		sess = se_sess->fabric_sess_ptr;
 
-		rb += sprintf(page+rb, "InitiatorName: %s\n",
+		rb += sysfs_emit_at(page, rb, "InitiatorName: %s\n",
 			sess->sess_ops->InitiatorName);
-		rb += sprintf(page+rb, "InitiatorAlias: %s\n",
+		rb += sysfs_emit_at(page, rb, "InitiatorAlias: %s\n",
 			sess->sess_ops->InitiatorAlias);
 
-		rb += sprintf(page+rb,
+		rb += sysfs_emit_at(page, rb,
 			      "LIO Session ID: %u   ISID: 0x%6ph  TSIH: %hu  ",
 			      sess->sid, sess->isid, sess->tsih);
-		rb += sprintf(page+rb, "SessionType: %s\n",
+		rb += sysfs_emit_at(page, rb, "SessionType: %s\n",
 				(sess->sess_ops->SessionType) ?
 				"Discovery" : "Normal");
-		rb += sprintf(page+rb, "Session State: ");
+		rb += sysfs_emit_at(page, rb, "Session State: ");
 		switch (sess->session_state) {
 		case TARG_SESS_STATE_FREE:
-			rb += sprintf(page+rb, "TARG_SESS_FREE\n");
+			rb += sysfs_emit_at(page, rb, "TARG_SESS_FREE\n");
 			break;
 		case TARG_SESS_STATE_ACTIVE:
-			rb += sprintf(page+rb, "TARG_SESS_STATE_ACTIVE\n");
+			rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_ACTIVE\n");
 			break;
 		case TARG_SESS_STATE_LOGGED_IN:
-			rb += sprintf(page+rb, "TARG_SESS_STATE_LOGGED_IN\n");
+			rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_LOGGED_IN\n");
 			break;
 		case TARG_SESS_STATE_FAILED:
-			rb += sprintf(page+rb, "TARG_SESS_STATE_FAILED\n");
+			rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_FAILED\n");
 			break;
 		case TARG_SESS_STATE_IN_CONTINUE:
-			rb += sprintf(page+rb, "TARG_SESS_STATE_IN_CONTINUE\n");
+			rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_IN_CONTINUE\n");
 			break;
 		default:
-			rb += sprintf(page+rb, "ERROR: Unknown Session"
+			rb += sysfs_emit_at(page, rb, "ERROR: Unknown Session"
 					" State!\n");
 			break;
 		}
 
-		rb += sprintf(page+rb, "---------------------[iSCSI Session"
+		rb += sysfs_emit_at(page, rb, "---------------------[iSCSI Session"
 				" Values]-----------------------\n");
-		rb += sprintf(page+rb, "  CmdSN/WR  :  CmdSN/WC  :  ExpCmdSN"
+		rb += sysfs_emit_at(page, rb, "  CmdSN/WR  :  CmdSN/WC  :  ExpCmdSN"
 				"  :  MaxCmdSN  :     ITT    :     TTT\n");
 		max_cmd_sn = (u32) atomic_read(&sess->max_cmd_sn);
-		rb += sprintf(page+rb, " 0x%08x   0x%08x   0x%08x   0x%08x"
+		rb += sysfs_emit_at(page, rb, " 0x%08x   0x%08x   0x%08x   0x%08x"
 				"   0x%08x   0x%08x\n",
 			sess->cmdsn_window,
 			(max_cmd_sn - sess->exp_cmd_sn) + 1,
 			sess->exp_cmd_sn, max_cmd_sn,
 			sess->init_task_tag, sess->targ_xfer_tag);
-		rb += sprintf(page+rb, "----------------------[iSCSI"
+		rb += sysfs_emit_at(page, rb, "----------------------[iSCSI"
 				" Connections]-------------------------\n");
 
 		spin_lock(&sess->conn_lock);
 		list_for_each_entry(conn, &sess->sess_conn_list, conn_list) {
-			rb += sprintf(page+rb, "CID: %hu  Connection"
+			rb += sysfs_emit_at(page, rb, "CID: %hu  Connection"
 					" State: ", conn->cid);
 			switch (conn->conn_state) {
 			case TARG_CONN_STATE_FREE:
-				rb += sprintf(page+rb,
+				rb += sysfs_emit_at(page, rb,
 					"TARG_CONN_STATE_FREE\n");
 				break;
 			case TARG_CONN_STATE_XPT_UP:
-				rb += sprintf(page+rb,
+				rb += sysfs_emit_at(page, rb,
 					"TARG_CONN_STATE_XPT_UP\n");
 				break;
 			case TARG_CONN_STATE_IN_LOGIN:
-				rb += sprintf(page+rb,
+				rb += sysfs_emit_at(page, rb,
 					"TARG_CONN_STATE_IN_LOGIN\n");
 				break;
 			case TARG_CONN_STATE_LOGGED_IN:
-				rb += sprintf(page+rb,
+				rb += sysfs_emit_at(page, rb,
 					"TARG_CONN_STATE_LOGGED_IN\n");
 				break;
 			case TARG_CONN_STATE_IN_LOGOUT:
-				rb += sprintf(page+rb,
+				rb += sysfs_emit_at(page, rb,
 					"TARG_CONN_STATE_IN_LOGOUT\n");
 				break;
 			case TARG_CONN_STATE_LOGOUT_REQUESTED:
-				rb += sprintf(page+rb,
+				rb += sysfs_emit_at(page, rb,
 					"TARG_CONN_STATE_LOGOUT_REQUESTED\n");
 				break;
 			case TARG_CONN_STATE_CLEANUP_WAIT:
-				rb += sprintf(page+rb,
+				rb += sysfs_emit_at(page, rb,
 					"TARG_CONN_STATE_CLEANUP_WAIT\n");
 				break;
 			default:
-				rb += sprintf(page+rb,
+				rb += sysfs_emit_at(page, rb,
 					"ERROR: Unknown Connection State!\n");
 				break;
 			}
 
-			rb += sprintf(page+rb, "   Address %pISc %s", &conn->login_sockaddr,
+			rb += sysfs_emit_at(page, rb, "   Address %pISc %s", &conn->login_sockaddr,
 				(conn->network_transport == ISCSI_TCP) ?
 				"TCP" : "SCTP");
-			rb += sprintf(page+rb, "  StatSN: 0x%08x\n",
+			rb += sysfs_emit_at(page, rb, "  StatSN: 0x%08x\n",
 				conn->stat_sn);
 		}
 		spin_unlock(&sess->conn_lock);
diff --git a/kernel/drivers/target/iscsi/iscsi_target_nego.c b/kernel/drivers/target/iscsi/iscsi_target_nego.c
index 8b40f10..3931565 100644
--- a/kernel/drivers/target/iscsi/iscsi_target_nego.c
+++ b/kernel/drivers/target/iscsi/iscsi_target_nego.c
@@ -1079,6 +1079,7 @@
 	iscsi_target_set_sock_callbacks(conn);
 
 	login->np = np;
+	conn->tpg = NULL;
 
 	login_req = (struct iscsi_login_req *) login->req;
 	payload_length = ntoh24(login_req->dlength);
@@ -1148,7 +1149,6 @@
 	 */
 	sessiontype = strncmp(s_buf, DISCOVERY, 9);
 	if (!sessiontype) {
-		conn->tpg = iscsit_global->discovery_tpg;
 		if (!login->leading_connection)
 			goto get_target;
 
@@ -1165,9 +1165,11 @@
 		 * Serialize access across the discovery struct iscsi_portal_group to
 		 * process login attempt.
 		 */
+		conn->tpg = iscsit_global->discovery_tpg;
 		if (iscsit_access_np(np, conn->tpg) < 0) {
 			iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
 				ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
+			conn->tpg = NULL;
 			ret = -1;
 			goto out;
 		}
diff --git a/kernel/drivers/target/iscsi/iscsi_target_parameters.c b/kernel/drivers/target/iscsi/iscsi_target_parameters.c
index 7a461fb..31cd3c0 100644
--- a/kernel/drivers/target/iscsi/iscsi_target_parameters.c
+++ b/kernel/drivers/target/iscsi/iscsi_target_parameters.c
@@ -1262,18 +1262,20 @@
 		return param;
 
 	if (!(param->phase & phase)) {
-		pr_err("Key \"%s\" may not be negotiated during ",
-				param->name);
+		char *phase_name;
+
 		switch (phase) {
 		case PHASE_SECURITY:
-			pr_debug("Security phase.\n");
+			phase_name = "Security";
 			break;
 		case PHASE_OPERATIONAL:
-			pr_debug("Operational phase.\n");
+			phase_name = "Operational";
 			break;
 		default:
-			pr_debug("Unknown phase.\n");
+			phase_name = "Unknown";
 		}
+		pr_err("Key \"%s\" may not be negotiated during %s phase.\n",
+				param->name, phase_name);
 		return NULL;
 	}
 
diff --git a/kernel/drivers/target/target_core_device.c b/kernel/drivers/target/target_core_device.c
index 1eded5c..9aeedcf 100644
--- a/kernel/drivers/target/target_core_device.c
+++ b/kernel/drivers/target/target_core_device.c
@@ -724,10 +724,23 @@
 {
 	struct se_device *dev;
 	struct se_lun *xcopy_lun;
+	int i;
 
 	dev = hba->backend->ops->alloc_device(hba, name);
 	if (!dev)
 		return NULL;
+
+	dev->queues = kcalloc(nr_cpu_ids, sizeof(*dev->queues), GFP_KERNEL);
+	if (!dev->queues) {
+		dev->transport->free_device(dev);
+		return NULL;
+	}
+
+	dev->queue_cnt = nr_cpu_ids;
+	for (i = 0; i < dev->queue_cnt; i++) {
+		INIT_LIST_HEAD(&dev->queues[i].state_list);
+		spin_lock_init(&dev->queues[i].lock);
+	}
 
 	dev->se_hba = hba;
 	dev->transport = hba->backend->ops;
@@ -738,9 +751,7 @@
 	INIT_LIST_HEAD(&dev->dev_sep_list);
 	INIT_LIST_HEAD(&dev->dev_tmr_list);
 	INIT_LIST_HEAD(&dev->delayed_cmd_list);
-	INIT_LIST_HEAD(&dev->state_list);
 	INIT_LIST_HEAD(&dev->qf_cmd_list);
-	spin_lock_init(&dev->execute_task_lock);
 	spin_lock_init(&dev->delayed_cmd_lock);
 	spin_lock_init(&dev->dev_reservation_lock);
 	spin_lock_init(&dev->se_port_lock);
@@ -759,6 +770,7 @@
 	spin_lock_init(&dev->t10_alua.lba_map_lock);
 
 	INIT_WORK(&dev->delayed_cmd_work, target_do_delayed_work);
+	mutex_init(&dev->lun_reset_mutex);
 
 	dev->t10_wwn.t10_dev = dev;
 	dev->t10_alua.t10_dev = dev;
@@ -855,7 +867,6 @@
 EXPORT_SYMBOL(target_to_linux_sector);
 
 struct devices_idr_iter {
-	struct config_item *prev_item;
 	int (*fn)(struct se_device *dev, void *data);
 	void *data;
 };
@@ -865,10 +876,8 @@
 {
 	struct devices_idr_iter *iter = data;
 	struct se_device *dev = p;
+	struct config_item *item;
 	int ret;
-
-	config_item_put(iter->prev_item);
-	iter->prev_item = NULL;
 
 	/*
 	 * We add the device early to the idr, so it can be used
@@ -879,12 +888,13 @@
 	if (!target_dev_configured(dev))
 		return 0;
 
-	iter->prev_item = config_item_get_unless_zero(&dev->dev_group.cg_item);
-	if (!iter->prev_item)
+	item = config_item_get_unless_zero(&dev->dev_group.cg_item);
+	if (!item)
 		return 0;
 	mutex_unlock(&device_mutex);
 
 	ret = iter->fn(dev, iter->data);
+	config_item_put(item);
 
 	mutex_lock(&device_mutex);
 	return ret;
@@ -907,7 +917,6 @@
 	mutex_lock(&device_mutex);
 	ret = idr_for_each(&devices_idr, target_devices_idr_iter, &iter);
 	mutex_unlock(&device_mutex);
-	config_item_put(iter.prev_item);
 	return ret;
 }
 
@@ -1014,6 +1023,7 @@
 	if (dev->transport->free_prot)
 		dev->transport->free_prot(dev);
 
+	kfree(dev->queues);
 	dev->transport->free_device(dev);
 }
 
diff --git a/kernel/drivers/target/target_core_file.c b/kernel/drivers/target/target_core_file.c
index cfa1bbe..3d92f37 100644
--- a/kernel/drivers/target/target_core_file.c
+++ b/kernel/drivers/target/target_core_file.c
@@ -340,7 +340,7 @@
 		len += sg->length;
 	}
 
-	iov_iter_bvec(&iter, READ, bvec, sgl_nents, len);
+	iov_iter_bvec(&iter, is_write, bvec, sgl_nents, len);
 	if (is_write)
 		ret = vfs_iter_write(fd, &iter, &pos, 0);
 	else
@@ -477,7 +477,7 @@
 		len += se_dev->dev_attrib.block_size;
 	}
 
-	iov_iter_bvec(&iter, READ, bvec, nolb, len);
+	iov_iter_bvec(&iter, WRITE, bvec, nolb, len);
 	ret = vfs_iter_write(fd_dev->fd_file, &iter, &pos, 0);
 
 	kfree(bvec);
diff --git a/kernel/drivers/target/target_core_sbc.c b/kernel/drivers/target/target_core_sbc.c
index eaf8551..47c5f26 100644
--- a/kernel/drivers/target/target_core_sbc.c
+++ b/kernel/drivers/target/target_core_sbc.c
@@ -1438,7 +1438,7 @@
 			if (rc) {
 				kunmap_atomic(daddr - dsg->offset);
 				kunmap_atomic(paddr - psg->offset);
-				cmd->bad_sector = sector;
+				cmd->sense_info = sector;
 				return rc;
 			}
 next:
diff --git a/kernel/drivers/target/target_core_tmr.c b/kernel/drivers/target/target_core_tmr.c
index e4513ef..a2b18a9 100644
--- a/kernel/drivers/target/target_core_tmr.c
+++ b/kernel/drivers/target/target_core_tmr.c
@@ -82,8 +82,8 @@
 {
 	struct se_session *sess = se_cmd->se_sess;
 
-	assert_spin_locked(&sess->sess_cmd_lock);
-	WARN_ON_ONCE(!irqs_disabled());
+	lockdep_assert_held(&sess->sess_cmd_lock);
+
 	/*
 	 * If command already reached CMD_T_COMPLETE state within
 	 * target_complete_cmd() or CMD_T_FABRIC_STOP due to shutdown,
@@ -121,57 +121,61 @@
 	unsigned long flags;
 	bool rc;
 	u64 ref_tag;
+	int i;
 
-	spin_lock_irqsave(&dev->execute_task_lock, flags);
-	list_for_each_entry_safe(se_cmd, next, &dev->state_list, state_list) {
+	for (i = 0; i < dev->queue_cnt; i++) {
+		spin_lock_irqsave(&dev->queues[i].lock, flags);
+		list_for_each_entry_safe(se_cmd, next, &dev->queues[i].state_list,
+					 state_list) {
+			if (se_sess != se_cmd->se_sess)
+				continue;
 
-		if (se_sess != se_cmd->se_sess)
-			continue;
+			/*
+			 * skip task management functions, including
+			 * tmr->task_cmd
+			 */
+			if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
+				continue;
 
-		/* skip task management functions, including tmr->task_cmd */
-		if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
-			continue;
+			ref_tag = se_cmd->tag;
+			if (tmr->ref_task_tag != ref_tag)
+				continue;
 
-		ref_tag = se_cmd->tag;
-		if (tmr->ref_task_tag != ref_tag)
-			continue;
+			pr_err("ABORT_TASK: Found referenced %s task_tag: %llu\n",
+			       se_cmd->se_tfo->fabric_name, ref_tag);
 
-		printk("ABORT_TASK: Found referenced %s task_tag: %llu\n",
-			se_cmd->se_tfo->fabric_name, ref_tag);
+			spin_lock(&se_sess->sess_cmd_lock);
+			rc = __target_check_io_state(se_cmd, se_sess, 0);
+			spin_unlock(&se_sess->sess_cmd_lock);
+			if (!rc)
+				continue;
 
-		spin_lock(&se_sess->sess_cmd_lock);
-		rc = __target_check_io_state(se_cmd, se_sess, 0);
-		spin_unlock(&se_sess->sess_cmd_lock);
-		if (!rc)
-			continue;
+			list_move_tail(&se_cmd->state_list, &aborted_list);
+			se_cmd->state_active = false;
+			spin_unlock_irqrestore(&dev->queues[i].lock, flags);
 
-		list_move_tail(&se_cmd->state_list, &aborted_list);
-		se_cmd->state_active = false;
+			/*
+			 * Ensure that this ABORT request is visible to the LU
+			 * RESET code.
+			 */
+			if (!tmr->tmr_dev)
+				WARN_ON_ONCE(transport_lookup_tmr_lun(tmr->task_cmd) < 0);
 
-		spin_unlock_irqrestore(&dev->execute_task_lock, flags);
+			if (dev->transport->tmr_notify)
+				dev->transport->tmr_notify(dev, TMR_ABORT_TASK,
+							   &aborted_list);
 
-		/*
-		 * Ensure that this ABORT request is visible to the LU RESET
-		 * code.
-		 */
-		if (!tmr->tmr_dev)
-			WARN_ON_ONCE(transport_lookup_tmr_lun(tmr->task_cmd) <
-					0);
+			list_del_init(&se_cmd->state_list);
+			target_put_cmd_and_wait(se_cmd);
 
-		if (dev->transport->tmr_notify)
-			dev->transport->tmr_notify(dev, TMR_ABORT_TASK,
-						   &aborted_list);
-
-		list_del_init(&se_cmd->state_list);
-		target_put_cmd_and_wait(se_cmd);
-
-		printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for"
-				" ref_tag: %llu\n", ref_tag);
-		tmr->response = TMR_FUNCTION_COMPLETE;
-		atomic_long_inc(&dev->aborts_complete);
-		return;
+			pr_err("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for ref_tag: %llu\n",
+			       ref_tag);
+			tmr->response = TMR_FUNCTION_COMPLETE;
+			atomic_long_inc(&dev->aborts_complete);
+			return;
+		}
+		spin_unlock_irqrestore(&dev->queues[i].lock, flags);
 	}
-	spin_unlock_irqrestore(&dev->execute_task_lock, flags);
 
 	if (dev->transport->tmr_notify)
 		dev->transport->tmr_notify(dev, TMR_ABORT_TASK, &aborted_list);
@@ -198,14 +202,23 @@
 	 * LUN_RESET tmr..
 	 */
 	spin_lock_irqsave(&dev->se_tmr_lock, flags);
-	if (tmr)
-		list_del_init(&tmr->tmr_list);
 	list_for_each_entry_safe(tmr_p, tmr_pp, &dev->dev_tmr_list, tmr_list) {
+		if (tmr_p == tmr)
+			continue;
+
 		cmd = tmr_p->task_cmd;
 		if (!cmd) {
 			pr_err("Unable to locate struct se_cmd for TMR\n");
 			continue;
 		}
+
+		/*
+		 * We only execute one LUN_RESET at a time so we can't wait
+		 * on them below.
+		 */
+		if (tmr_p->function == TMR_LUN_RESET)
+			continue;
+
 		/*
 		 * If this function was called with a valid pr_res_key
 		 * parameter (eg: for PROUT PREEMPT_AND_ABORT service action
@@ -273,7 +286,7 @@
 	struct se_session *sess;
 	struct se_cmd *cmd, *next;
 	unsigned long flags;
-	int rc;
+	int rc, i;
 
 	/*
 	 * Complete outstanding commands with TASK_ABORTED SAM status.
@@ -297,35 +310,39 @@
 	 * Note that this seems to be independent of TAS (Task Aborted Status)
 	 * in the Control Mode Page.
 	 */
-	spin_lock_irqsave(&dev->execute_task_lock, flags);
-	list_for_each_entry_safe(cmd, next, &dev->state_list, state_list) {
-		/*
-		 * For PREEMPT_AND_ABORT usage, only process commands
-		 * with a matching reservation key.
-		 */
-		if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd))
-			continue;
+	for (i = 0; i < dev->queue_cnt; i++) {
+		spin_lock_irqsave(&dev->queues[i].lock, flags);
+		list_for_each_entry_safe(cmd, next, &dev->queues[i].state_list,
+					 state_list) {
+			/*
+			 * For PREEMPT_AND_ABORT usage, only process commands
+			 * with a matching reservation key.
+			 */
+			if (target_check_cdb_and_preempt(preempt_and_abort_list,
+							 cmd))
+				continue;
 
-		/*
-		 * Not aborting PROUT PREEMPT_AND_ABORT CDB..
-		 */
-		if (prout_cmd == cmd)
-			continue;
+			/*
+			 * Not aborting PROUT PREEMPT_AND_ABORT CDB..
+			 */
+			if (prout_cmd == cmd)
+				continue;
 
-		sess = cmd->se_sess;
-		if (WARN_ON_ONCE(!sess))
-			continue;
+			sess = cmd->se_sess;
+			if (WARN_ON_ONCE(!sess))
+				continue;
 
-		spin_lock(&sess->sess_cmd_lock);
-		rc = __target_check_io_state(cmd, tmr_sess, tas);
-		spin_unlock(&sess->sess_cmd_lock);
-		if (!rc)
-			continue;
+			spin_lock(&sess->sess_cmd_lock);
+			rc = __target_check_io_state(cmd, tmr_sess, tas);
+			spin_unlock(&sess->sess_cmd_lock);
+			if (!rc)
+				continue;
 
-		list_move_tail(&cmd->state_list, &drain_task_list);
-		cmd->state_active = false;
+			list_move_tail(&cmd->state_list, &drain_task_list);
+			cmd->state_active = false;
+		}
+		spin_unlock_irqrestore(&dev->queues[i].lock, flags);
 	}
-	spin_unlock_irqrestore(&dev->execute_task_lock, flags);
 
 	if (dev->transport->tmr_notify)
 		dev->transport->tmr_notify(dev, preempt_and_abort_list ?
@@ -382,14 +399,25 @@
 				tmr_nacl->initiatorname);
 		}
 	}
+
+
+	/*
+	 * We only allow one reset or preempt and abort to execute at a time
+	 * to prevent one call from claiming all the cmds causing a second
+	 * call from returning while cmds it should have waited on are still
+	 * running.
+	 */
+	mutex_lock(&dev->lun_reset_mutex);
+
 	pr_debug("LUN_RESET: %s starting for [%s], tas: %d\n",
 		(preempt_and_abort_list) ? "Preempt" : "TMR",
 		dev->transport->name, tas);
-
 	core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list);
 	core_tmr_drain_state_list(dev, prout_cmd, tmr_sess, tas,
 				preempt_and_abort_list);
 
+	mutex_unlock(&dev->lun_reset_mutex);
+
 	/*
 	 * Clear any legacy SPC-2 reservation when called during
 	 * LOGICAL UNIT RESET
diff --git a/kernel/drivers/target/target_core_transport.c b/kernel/drivers/target/target_core_transport.c
index bca3a32..2e97937 100644
--- a/kernel/drivers/target/target_core_transport.c
+++ b/kernel/drivers/target/target_core_transport.c
@@ -650,12 +650,12 @@
 	if (!dev)
 		return;
 
-	spin_lock_irqsave(&dev->execute_task_lock, flags);
+	spin_lock_irqsave(&dev->queues[cmd->cpuid].lock, flags);
 	if (cmd->state_active) {
 		list_del(&cmd->state_list);
 		cmd->state_active = false;
 	}
-	spin_unlock_irqrestore(&dev->execute_task_lock, flags);
+	spin_unlock_irqrestore(&dev->queues[cmd->cpuid].lock, flags);
 }
 
 /*
@@ -866,10 +866,7 @@
 
 	INIT_WORK(&cmd->work, success ? target_complete_ok_work :
 		  target_complete_failure_work);
-	if (cmd->se_cmd_flags & SCF_USE_CPUID)
-		queue_work_on(cmd->cpuid, target_completion_wq, &cmd->work);
-	else
-		queue_work(target_completion_wq, &cmd->work);
+	queue_work_on(cmd->cpuid, target_completion_wq, &cmd->work);
 }
 EXPORT_SYMBOL(target_complete_cmd);
 
@@ -904,12 +901,13 @@
 	struct se_device *dev = cmd->se_dev;
 	unsigned long flags;
 
-	spin_lock_irqsave(&dev->execute_task_lock, flags);
+	spin_lock_irqsave(&dev->queues[cmd->cpuid].lock, flags);
 	if (!cmd->state_active) {
-		list_add_tail(&cmd->state_list, &dev->state_list);
+		list_add_tail(&cmd->state_list,
+			      &dev->queues[cmd->cpuid].state_list);
 		cmd->state_active = true;
 	}
-	spin_unlock_irqrestore(&dev->execute_task_lock, flags);
+	spin_unlock_irqrestore(&dev->queues[cmd->cpuid].lock, flags);
 }
 
 /*
@@ -1397,6 +1395,9 @@
 	cmd->sense_buffer = sense_buffer;
 	cmd->orig_fe_lun = unpacked_lun;
 
+	if (!(cmd->se_cmd_flags & SCF_USE_CPUID))
+		cmd->cpuid = raw_smp_processor_id();
+
 	cmd->state_active = false;
 }
 EXPORT_SYMBOL(transport_init_se_cmd);
@@ -1614,6 +1615,9 @@
 	BUG_ON(!se_tpg);
 	BUG_ON(se_cmd->se_tfo || se_cmd->se_sess);
 	BUG_ON(in_interrupt());
+
+	if (flags & TARGET_SCF_USE_CPUID)
+		se_cmd->se_cmd_flags |= SCF_USE_CPUID;
 	/*
 	 * Initialize se_cmd for target operation.  From this point
 	 * exceptions are handled by sending exception status via
@@ -1622,11 +1626,6 @@
 	transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess,
 				data_length, data_dir, task_attr, sense,
 				unpacked_lun);
-
-	if (flags & TARGET_SCF_USE_CPUID)
-		se_cmd->se_cmd_flags |= SCF_USE_CPUID;
-	else
-		se_cmd->cpuid = WORK_CPU_UNBOUND;
 
 	if (flags & TARGET_SCF_UNKNOWN_SIZE)
 		se_cmd->unknown_data_length = 1;
@@ -3131,14 +3130,14 @@
 }
 EXPORT_SYMBOL(transport_wait_for_tasks);
 
-struct sense_info {
+struct sense_detail {
 	u8 key;
 	u8 asc;
 	u8 ascq;
-	bool add_sector_info;
+	bool add_sense_info;
 };
 
-static const struct sense_info sense_info_table[] = {
+static const struct sense_detail sense_detail_table[] = {
 	[TCM_NO_SENSE] = {
 		.key = NOT_READY
 	},
@@ -3238,19 +3237,19 @@
 		.key = ABORTED_COMMAND,
 		.asc = 0x10,
 		.ascq = 0x01, /* LOGICAL BLOCK GUARD CHECK FAILED */
-		.add_sector_info = true,
+		.add_sense_info = true,
 	},
 	[TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED] = {
 		.key = ABORTED_COMMAND,
 		.asc = 0x10,
 		.ascq = 0x02, /* LOGICAL BLOCK APPLICATION TAG CHECK FAILED */
-		.add_sector_info = true,
+		.add_sense_info = true,
 	},
 	[TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED] = {
 		.key = ABORTED_COMMAND,
 		.asc = 0x10,
 		.ascq = 0x03, /* LOGICAL BLOCK REFERENCE TAG CHECK FAILED */
-		.add_sector_info = true,
+		.add_sense_info = true,
 	},
 	[TCM_COPY_TARGET_DEVICE_NOT_REACHABLE] = {
 		.key = COPY_ABORTED,
@@ -3298,42 +3297,42 @@
  */
 static void translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason)
 {
-	const struct sense_info *si;
+	const struct sense_detail *sd;
 	u8 *buffer = cmd->sense_buffer;
 	int r = (__force int)reason;
 	u8 key, asc, ascq;
 	bool desc_format = target_sense_desc_format(cmd->se_dev);
 
-	if (r < ARRAY_SIZE(sense_info_table) && sense_info_table[r].key)
-		si = &sense_info_table[r];
+	if (r < ARRAY_SIZE(sense_detail_table) && sense_detail_table[r].key)
+		sd = &sense_detail_table[r];
 	else
-		si = &sense_info_table[(__force int)
+		sd = &sense_detail_table[(__force int)
 				       TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE];
 
-	key = si->key;
+	key = sd->key;
 	if (reason == TCM_CHECK_CONDITION_UNIT_ATTENTION) {
 		if (!core_scsi3_ua_for_check_condition(cmd, &key, &asc,
 						       &ascq)) {
 			cmd->scsi_status = SAM_STAT_BUSY;
 			return;
 		}
-	} else if (si->asc == 0) {
+	} else if (sd->asc == 0) {
 		WARN_ON_ONCE(cmd->scsi_asc == 0);
 		asc = cmd->scsi_asc;
 		ascq = cmd->scsi_ascq;
 	} else {
-		asc = si->asc;
-		ascq = si->ascq;
+		asc = sd->asc;
+		ascq = sd->ascq;
 	}
 
 	cmd->se_cmd_flags |= SCF_EMULATED_TASK_SENSE;
 	cmd->scsi_status = SAM_STAT_CHECK_CONDITION;
 	cmd->scsi_sense_length  = TRANSPORT_SENSE_BUFFER;
 	scsi_build_sense_buffer(desc_format, buffer, key, asc, ascq);
-	if (si->add_sector_info)
+	if (sd->add_sense_info)
 		WARN_ON_ONCE(scsi_set_sense_information(buffer,
 							cmd->scsi_sense_length,
-							cmd->bad_sector) < 0);
+							cmd->sense_info) < 0);
 }
 
 int
diff --git a/kernel/drivers/target/tcm_fc/tfc_cmd.c b/kernel/drivers/target/tcm_fc/tfc_cmd.c
index a7ed566..8936a09 100644
--- a/kernel/drivers/target/tcm_fc/tfc_cmd.c
+++ b/kernel/drivers/target/tcm_fc/tfc_cmd.c
@@ -551,7 +551,7 @@
 	if (target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, fcp->fc_cdb,
 			      &cmd->ft_sense_buffer[0], scsilun_to_int(&fcp->fc_lun),
 			      ntohl(fcp->fc_dl), task_attr, data_dir,
-			      TARGET_SCF_ACK_KREF | TARGET_SCF_USE_CPUID))
+			      TARGET_SCF_ACK_KREF))
 		goto err;
 
 	pr_debug("r_ctl %x target_submit_cmd %p\n", fh->fh_r_ctl, cmd);
diff --git a/kernel/drivers/tee/amdtee/amdtee_if.h b/kernel/drivers/tee/amdtee/amdtee_if.h
index ff48c3e..e2014e2 100644
--- a/kernel/drivers/tee/amdtee/amdtee_if.h
+++ b/kernel/drivers/tee/amdtee/amdtee_if.h
@@ -118,16 +118,18 @@
 
 /**
  * struct tee_cmd_load_ta - load Trusted Application (TA) binary into TEE
- * @low_addr:    [in] bits [31:0] of the physical address of the TA binary
- * @hi_addr:     [in] bits [63:32] of the physical address of the TA binary
- * @size:        [in] size of TA binary in bytes
- * @ta_handle:   [out] return handle of the loaded TA
+ * @low_addr:       [in] bits [31:0] of the physical address of the TA binary
+ * @hi_addr:        [in] bits [63:32] of the physical address of the TA binary
+ * @size:           [in] size of TA binary in bytes
+ * @ta_handle:      [out] return handle of the loaded TA
+ * @return_origin:  [out] origin of return code after TEE processing
  */
 struct tee_cmd_load_ta {
 	u32 low_addr;
 	u32 hi_addr;
 	u32 size;
 	u32 ta_handle;
+	u32 return_origin;
 };
 
 /**
diff --git a/kernel/drivers/tee/amdtee/call.c b/kernel/drivers/tee/amdtee/call.c
index 07f36ac..63d4284 100644
--- a/kernel/drivers/tee/amdtee/call.c
+++ b/kernel/drivers/tee/amdtee/call.c
@@ -423,19 +423,23 @@
 	if (ret) {
 		arg->ret_origin = TEEC_ORIGIN_COMMS;
 		arg->ret = TEEC_ERROR_COMMUNICATION;
-	} else if (arg->ret == TEEC_SUCCESS) {
-		ret = get_ta_refcount(load_cmd.ta_handle);
-		if (!ret) {
-			arg->ret_origin = TEEC_ORIGIN_COMMS;
-			arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
+	} else {
+		arg->ret_origin = load_cmd.return_origin;
 
-			/* Unload the TA on error */
-			unload_cmd.ta_handle = load_cmd.ta_handle;
-			psp_tee_process_cmd(TEE_CMD_ID_UNLOAD_TA,
-					    (void *)&unload_cmd,
-					    sizeof(unload_cmd), &ret);
-		} else {
-			set_session_id(load_cmd.ta_handle, 0, &arg->session);
+		if (arg->ret == TEEC_SUCCESS) {
+			ret = get_ta_refcount(load_cmd.ta_handle);
+			if (!ret) {
+				arg->ret_origin = TEEC_ORIGIN_COMMS;
+				arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
+
+				/* Unload the TA on error */
+				unload_cmd.ta_handle = load_cmd.ta_handle;
+				psp_tee_process_cmd(TEE_CMD_ID_UNLOAD_TA,
+						    (void *)&unload_cmd,
+						    sizeof(unload_cmd), &ret);
+			} else {
+				set_session_id(load_cmd.ta_handle, 0, &arg->session);
+			}
 		}
 	}
 	mutex_unlock(&ta_refcount_mutex);
diff --git a/kernel/drivers/tee/amdtee/core.c b/kernel/drivers/tee/amdtee/core.c
index 297dc62..372d647 100644
--- a/kernel/drivers/tee/amdtee/core.c
+++ b/kernel/drivers/tee/amdtee/core.c
@@ -267,35 +267,34 @@
 		goto out;
 	}
 
+	/* Open session with loaded TA */
+	handle_open_session(arg, &session_info, param);
+	if (arg->ret != TEEC_SUCCESS) {
+		pr_err("open_session failed %d\n", arg->ret);
+		handle_unload_ta(ta_handle);
+		kref_put(&sess->refcount, destroy_session);
+		goto out;
+	}
+
 	/* Find an empty session index for the given TA */
 	spin_lock(&sess->lock);
 	i = find_first_zero_bit(sess->sess_mask, TEE_NUM_SESSIONS);
-	if (i < TEE_NUM_SESSIONS)
+	if (i < TEE_NUM_SESSIONS) {
+		sess->session_info[i] = session_info;
+		set_session_id(ta_handle, i, &arg->session);
 		set_bit(i, sess->sess_mask);
+	}
 	spin_unlock(&sess->lock);
 
 	if (i >= TEE_NUM_SESSIONS) {
 		pr_err("reached maximum session count %d\n", TEE_NUM_SESSIONS);
+		handle_close_session(ta_handle, session_info);
 		handle_unload_ta(ta_handle);
 		kref_put(&sess->refcount, destroy_session);
 		rc = -ENOMEM;
 		goto out;
 	}
 
-	/* Open session with loaded TA */
-	handle_open_session(arg, &session_info, param);
-	if (arg->ret != TEEC_SUCCESS) {
-		pr_err("open_session failed %d\n", arg->ret);
-		spin_lock(&sess->lock);
-		clear_bit(i, sess->sess_mask);
-		spin_unlock(&sess->lock);
-		handle_unload_ta(ta_handle);
-		kref_put(&sess->refcount, destroy_session);
-		goto out;
-	}
-
-	sess->session_info[i] = session_info;
-	set_session_id(ta_handle, i, &arg->session);
 out:
 	free_pages((u64)ta, get_order(ta_size));
 	return rc;
diff --git a/kernel/drivers/thermal/hisi_thermal.c b/kernel/drivers/thermal/hisi_thermal.c
index ee05950..7b1e819 100644
--- a/kernel/drivers/thermal/hisi_thermal.c
+++ b/kernel/drivers/thermal/hisi_thermal.c
@@ -435,10 +435,6 @@
 	data->sensor[0].irq_name = "tsensor_a73";
 	data->sensor[0].data = data;
 
-	data->sensor[1].id = HI3660_LITTLE_SENSOR;
-	data->sensor[1].irq_name = "tsensor_a53";
-	data->sensor[1].data = data;
-
 	return 0;
 }
 
diff --git a/kernel/drivers/thermal/imx8mm_thermal.c b/kernel/drivers/thermal/imx8mm_thermal.c
index 0f4cabd..6be16e0 100644
--- a/kernel/drivers/thermal/imx8mm_thermal.c
+++ b/kernel/drivers/thermal/imx8mm_thermal.c
@@ -65,8 +65,14 @@
 	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;
diff --git a/kernel/drivers/thermal/intel/Kconfig b/kernel/drivers/thermal/intel/Kconfig
index 8025b21..b542757 100644
--- a/kernel/drivers/thermal/intel/Kconfig
+++ b/kernel/drivers/thermal/intel/Kconfig
@@ -60,7 +60,8 @@
 
 config INTEL_BXT_PMIC_THERMAL
 	tristate "Intel Broxton PMIC thermal driver"
-	depends on X86 && INTEL_SOC_PMIC_BXTWC && REGMAP
+	depends on X86 && INTEL_SOC_PMIC_BXTWC
+	select REGMAP
 	help
 	  Select this driver for Intel Broxton PMIC with ADC channels monitoring
 	  system temperature measurements and alerts.
diff --git a/kernel/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c b/kernel/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c
index a337600..6952f4e 100644
--- a/kernel/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c
+++ b/kernel/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c
@@ -44,10 +44,12 @@
 					 int trip, int *temp)
 {
 	struct int34x_thermal_zone *d = zone->devdata;
-	int i;
+	int i, ret = 0;
 
 	if (d->override_ops && d->override_ops->get_trip_temp)
 		return d->override_ops->get_trip_temp(zone, trip, temp);
+
+	mutex_lock(&d->trip_mutex);
 
 	if (trip < d->aux_trip_nr)
 		*temp = d->aux_trips[trip];
@@ -66,10 +68,12 @@
 			}
 		}
 		if (i == INT340X_THERMAL_MAX_ACT_TRIP_COUNT)
-			return -EINVAL;
+			ret = -EINVAL;
 	}
 
-	return 0;
+	mutex_unlock(&d->trip_mutex);
+
+	return ret;
 }
 
 static int int340x_thermal_get_trip_type(struct thermal_zone_device *zone,
@@ -77,10 +81,12 @@
 					 enum thermal_trip_type *type)
 {
 	struct int34x_thermal_zone *d = zone->devdata;
-	int i;
+	int i, ret = 0;
 
 	if (d->override_ops && d->override_ops->get_trip_type)
 		return d->override_ops->get_trip_type(zone, trip, type);
+
+	mutex_lock(&d->trip_mutex);
 
 	if (trip < d->aux_trip_nr)
 		*type = THERMAL_TRIP_PASSIVE;
@@ -99,10 +105,12 @@
 			}
 		}
 		if (i == INT340X_THERMAL_MAX_ACT_TRIP_COUNT)
-			return -EINVAL;
+			ret = -EINVAL;
 	}
 
-	return 0;
+	mutex_unlock(&d->trip_mutex);
+
+	return ret;
 }
 
 static int int340x_thermal_set_trip_temp(struct thermal_zone_device *zone,
@@ -174,6 +182,8 @@
 	int trip_cnt = int34x_zone->aux_trip_nr;
 	int i;
 
+	mutex_lock(&int34x_zone->trip_mutex);
+
 	int34x_zone->crt_trip_id = -1;
 	if (!int340x_thermal_get_trip_config(int34x_zone->adev->handle, "_CRT",
 					     &int34x_zone->crt_temp))
@@ -201,6 +211,8 @@
 		int34x_zone->act_trips[i].valid = true;
 	}
 
+	mutex_unlock(&int34x_zone->trip_mutex);
+
 	return trip_cnt;
 }
 EXPORT_SYMBOL_GPL(int340x_thermal_read_trips);
@@ -223,6 +235,8 @@
 				      GFP_KERNEL);
 	if (!int34x_thermal_zone)
 		return ERR_PTR(-ENOMEM);
+
+	mutex_init(&int34x_thermal_zone->trip_mutex);
 
 	int34x_thermal_zone->adev = adev;
 	int34x_thermal_zone->override_ops = override_ops;
@@ -275,6 +289,7 @@
 	acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table);
 	kfree(int34x_thermal_zone->aux_trips);
 err_trip_alloc:
+	mutex_destroy(&int34x_thermal_zone->trip_mutex);
 	kfree(int34x_thermal_zone);
 	return ERR_PTR(ret);
 }
@@ -286,6 +301,7 @@
 	thermal_zone_device_unregister(int34x_thermal_zone->zone);
 	acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table);
 	kfree(int34x_thermal_zone->aux_trips);
+	mutex_destroy(&int34x_thermal_zone->trip_mutex);
 	kfree(int34x_thermal_zone);
 }
 EXPORT_SYMBOL_GPL(int340x_thermal_zone_remove);
diff --git a/kernel/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h b/kernel/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h
index 3b4971d..8f9872a 100644
--- a/kernel/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h
+++ b/kernel/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h
@@ -32,6 +32,7 @@
 	struct thermal_zone_device_ops *override_ops;
 	void *priv_data;
 	struct acpi_lpat_conversion_table *lpat_table;
+	struct mutex trip_mutex;
 };
 
 struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *,
diff --git a/kernel/drivers/thermal/intel/intel_powerclamp.c b/kernel/drivers/thermal/intel/intel_powerclamp.c
index fb04470..6e7c230 100644
--- a/kernel/drivers/thermal/intel/intel_powerclamp.c
+++ b/kernel/drivers/thermal/intel/intel_powerclamp.c
@@ -57,6 +57,7 @@
 
 static unsigned int target_mwait;
 static struct dentry *debug_dir;
+static bool poll_pkg_cstate_enable;
 
 /* user selected target */
 static unsigned int set_target_ratio;
@@ -261,6 +262,9 @@
 static unsigned int get_compensation(int ratio)
 {
 	unsigned int comp = 0;
+
+	if (!poll_pkg_cstate_enable)
+		return 0;
 
 	/* we only use compensation if all adjacent ones are good */
 	if (ratio == 1 &&
@@ -534,7 +538,8 @@
 	control_cpu = cpumask_first(cpu_online_mask);
 
 	clamping = true;
-	schedule_delayed_work(&poll_pkg_cstate_work, 0);
+	if (poll_pkg_cstate_enable)
+		schedule_delayed_work(&poll_pkg_cstate_work, 0);
 
 	/* start one kthread worker per online cpu */
 	for_each_online_cpu(cpu) {
@@ -603,11 +608,15 @@
 static int powerclamp_get_cur_state(struct thermal_cooling_device *cdev,
 				 unsigned long *state)
 {
-	if (true == clamping)
-		*state = pkg_cstate_ratio_cur;
-	else
+	if (clamping) {
+		if (poll_pkg_cstate_enable)
+			*state = pkg_cstate_ratio_cur;
+		else
+			*state = set_target_ratio;
+	} else {
 		/* to save power, do not poll idle ratio while not clamping */
 		*state = -1; /* indicates invalid state */
+	}
 
 	return 0;
 }
@@ -732,6 +741,9 @@
 		goto exit_unregister;
 	}
 
+	if (topology_max_packages() == 1 && topology_max_die_per_package() == 1)
+		poll_pkg_cstate_enable = true;
+
 	cooling_dev = thermal_cooling_device_register("intel_powerclamp", NULL,
 						&powerclamp_cooling_ops);
 	if (IS_ERR(cooling_dev)) {
diff --git a/kernel/drivers/thermal/intel/intel_quark_dts_thermal.c b/kernel/drivers/thermal/intel/intel_quark_dts_thermal.c
index 3eafc6b..b43fbd5 100644
--- a/kernel/drivers/thermal/intel/intel_quark_dts_thermal.c
+++ b/kernel/drivers/thermal/intel/intel_quark_dts_thermal.c
@@ -415,22 +415,14 @@
 
 static int __init intel_quark_thermal_init(void)
 {
-	int err = 0;
-
 	if (!x86_match_cpu(qrk_thermal_ids) || !iosf_mbi_available())
 		return -ENODEV;
 
 	soc_dts = alloc_soc_dts();
-	if (IS_ERR(soc_dts)) {
-		err = PTR_ERR(soc_dts);
-		goto err_free;
-	}
+	if (IS_ERR(soc_dts))
+		return PTR_ERR(soc_dts);
 
 	return 0;
-
-err_free:
-	free_soc_dts(soc_dts);
-	return err;
 }
 
 static void __exit intel_quark_thermal_exit(void)
diff --git a/kernel/drivers/thermal/intel/intel_soc_dts_iosf.c b/kernel/drivers/thermal/intel/intel_soc_dts_iosf.c
index 4f1a2f7..8d6707e 100644
--- a/kernel/drivers/thermal/intel/intel_soc_dts_iosf.c
+++ b/kernel/drivers/thermal/intel/intel_soc_dts_iosf.c
@@ -404,7 +404,7 @@
 {
 	struct intel_soc_dts_sensors *sensors;
 	bool notification;
-	u32 tj_max;
+	int tj_max;
 	int ret;
 	int i;
 
diff --git a/kernel/drivers/thermal/qcom/tsens-v1.c b/kernel/drivers/thermal/qcom/tsens-v1.c
index 3c19a38..faa4576 100644
--- a/kernel/drivers/thermal/qcom/tsens-v1.c
+++ b/kernel/drivers/thermal/qcom/tsens-v1.c
@@ -78,11 +78,6 @@
 
 #define MSM8976_CAL_SEL_MASK	0x3
 
-#define MSM8976_CAL_DEGC_PT1	30
-#define MSM8976_CAL_DEGC_PT2	120
-#define MSM8976_SLOPE_FACTOR	1000
-#define MSM8976_SLOPE_DEFAULT	3200
-
 /* eeprom layout data for qcs404/405 (v1) */
 #define BASE0_MASK	0x000007f8
 #define BASE1_MASK	0x0007f800
@@ -141,30 +136,6 @@
 
 #define CAL_SEL_MASK	7
 #define CAL_SEL_SHIFT	0
-
-static void compute_intercept_slope_8976(struct tsens_priv *priv,
-			      u32 *p1, u32 *p2, u32 mode)
-{
-	int i;
-
-	priv->sensor[0].slope = 3313;
-	priv->sensor[1].slope = 3275;
-	priv->sensor[2].slope = 3320;
-	priv->sensor[3].slope = 3246;
-	priv->sensor[4].slope = 3279;
-	priv->sensor[5].slope = 3257;
-	priv->sensor[6].slope = 3234;
-	priv->sensor[7].slope = 3269;
-	priv->sensor[8].slope = 3255;
-	priv->sensor[9].slope = 3239;
-	priv->sensor[10].slope = 3286;
-
-	for (i = 0; i < priv->num_sensors; i++) {
-		priv->sensor[i].offset = (p1[i] * MSM8976_SLOPE_FACTOR) -
-				(MSM8976_CAL_DEGC_PT1 *
-				priv->sensor[i].slope);
-	}
-}
 
 static int calibrate_v1(struct tsens_priv *priv)
 {
@@ -291,7 +262,7 @@
 		break;
 	}
 
-	compute_intercept_slope_8976(priv, p1, p2, mode);
+	compute_intercept_slope(priv, p1, p2, mode);
 	kfree(qfprom_cdata);
 
 	return 0;
@@ -362,6 +333,22 @@
 	[TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
 };
 
+static int __init init_8956(struct tsens_priv *priv) {
+	priv->sensor[0].slope = 3313;
+	priv->sensor[1].slope = 3275;
+	priv->sensor[2].slope = 3320;
+	priv->sensor[3].slope = 3246;
+	priv->sensor[4].slope = 3279;
+	priv->sensor[5].slope = 3257;
+	priv->sensor[6].slope = 3234;
+	priv->sensor[7].slope = 3269;
+	priv->sensor[8].slope = 3255;
+	priv->sensor[9].slope = 3239;
+	priv->sensor[10].slope = 3286;
+
+	return init_common(priv);
+}
+
 static const struct tsens_ops ops_generic_v1 = {
 	.init		= init_common,
 	.calibrate	= calibrate_v1,
@@ -374,17 +361,29 @@
 	.fields	= tsens_v1_regfields,
 };
 
+static const struct tsens_ops ops_8956 = {
+	.init		= init_8956,
+	.calibrate	= calibrate_8976,
+	.get_temp	= get_temp_tsens_valid,
+};
+
+struct tsens_plat_data data_8956 = {
+	.num_sensors	= 11,
+	.ops		= &ops_8956,
+	.feat		= &tsens_v1_feat,
+	.fields		= tsens_v1_regfields,
+};
+
 static const struct tsens_ops ops_8976 = {
 	.init		= init_common,
 	.calibrate	= calibrate_8976,
 	.get_temp	= get_temp_tsens_valid,
 };
 
-/* Valid for both MSM8956 and MSM8976. Sensor ID 3 is unused. */
 struct tsens_plat_data data_8976 = {
 	.num_sensors	= 11,
 	.ops		= &ops_8976,
-	.hw_ids		= (unsigned int[]){0, 1, 2, 4, 5, 6, 7, 8, 9, 10},
+	.hw_ids		= (unsigned int[]){0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
 	.feat		= &tsens_v1_feat,
 	.fields		= tsens_v1_regfields,
 };
diff --git a/kernel/drivers/thermal/qcom/tsens.c b/kernel/drivers/thermal/qcom/tsens.c
index cb4f4b5..c73792c 100644
--- a/kernel/drivers/thermal/qcom/tsens.c
+++ b/kernel/drivers/thermal/qcom/tsens.c
@@ -903,6 +903,12 @@
 		.compatible = "qcom,msm8939-tsens",
 		.data = &data_8939,
 	}, {
+		.compatible = "qcom,msm8956-tsens",
+		.data = &data_8956,
+	}, {
+		.compatible = "qcom,msm8960-tsens",
+		.data = &data_8960,
+	}, {
 		.compatible = "qcom,msm8974-tsens",
 		.data = &data_8974,
 	}, {
diff --git a/kernel/drivers/thermal/qcom/tsens.h b/kernel/drivers/thermal/qcom/tsens.h
index f40b625..bbb1e83 100644
--- a/kernel/drivers/thermal/qcom/tsens.h
+++ b/kernel/drivers/thermal/qcom/tsens.h
@@ -588,7 +588,7 @@
 extern struct tsens_plat_data data_8916, data_8939, data_8974;
 
 /* TSENS v1 targets */
-extern struct tsens_plat_data data_tsens_v1, data_8976;
+extern struct tsens_plat_data data_tsens_v1, data_8976, data_8956;
 
 /* TSENS v2 targets */
 extern struct tsens_plat_data data_8996, data_tsens_v2;
diff --git a/kernel/drivers/thermal/sun8i_thermal.c b/kernel/drivers/thermal/sun8i_thermal.c
index f8b1307..e053b06 100644
--- a/kernel/drivers/thermal/sun8i_thermal.c
+++ b/kernel/drivers/thermal/sun8i_thermal.c
@@ -318,6 +318,11 @@
 	return ret;
 }
 
+static void sun8i_ths_reset_control_assert(void *data)
+{
+	reset_control_assert(data);
+}
+
 static int sun8i_ths_resource_init(struct ths_device *tmdev)
 {
 	struct device *dev = tmdev->dev;
@@ -338,47 +343,35 @@
 		if (IS_ERR(tmdev->reset))
 			return PTR_ERR(tmdev->reset);
 
-		tmdev->bus_clk = devm_clk_get(&pdev->dev, "bus");
+		ret = reset_control_deassert(tmdev->reset);
+		if (ret)
+			return ret;
+
+		ret = devm_add_action_or_reset(dev, sun8i_ths_reset_control_assert,
+					       tmdev->reset);
+		if (ret)
+			return ret;
+
+		tmdev->bus_clk = devm_clk_get_enabled(&pdev->dev, "bus");
 		if (IS_ERR(tmdev->bus_clk))
 			return PTR_ERR(tmdev->bus_clk);
 	}
 
 	if (tmdev->chip->has_mod_clk) {
-		tmdev->mod_clk = devm_clk_get(&pdev->dev, "mod");
+		tmdev->mod_clk = devm_clk_get_enabled(&pdev->dev, "mod");
 		if (IS_ERR(tmdev->mod_clk))
 			return PTR_ERR(tmdev->mod_clk);
 	}
 
-	ret = reset_control_deassert(tmdev->reset);
+	ret = clk_set_rate(tmdev->mod_clk, 24000000);
 	if (ret)
 		return ret;
 
-	ret = clk_prepare_enable(tmdev->bus_clk);
-	if (ret)
-		goto assert_reset;
-
-	ret = clk_set_rate(tmdev->mod_clk, 24000000);
-	if (ret)
-		goto bus_disable;
-
-	ret = clk_prepare_enable(tmdev->mod_clk);
-	if (ret)
-		goto bus_disable;
-
 	ret = sun8i_ths_calibrate(tmdev);
 	if (ret)
-		goto mod_disable;
+		return ret;
 
 	return 0;
-
-mod_disable:
-	clk_disable_unprepare(tmdev->mod_clk);
-bus_disable:
-	clk_disable_unprepare(tmdev->bus_clk);
-assert_reset:
-	reset_control_assert(tmdev->reset);
-
-	return ret;
 }
 
 static int sun8i_h3_thermal_init(struct ths_device *tmdev)
@@ -529,17 +522,6 @@
 	return 0;
 }
 
-static int sun8i_ths_remove(struct platform_device *pdev)
-{
-	struct ths_device *tmdev = platform_get_drvdata(pdev);
-
-	clk_disable_unprepare(tmdev->mod_clk);
-	clk_disable_unprepare(tmdev->bus_clk);
-	reset_control_assert(tmdev->reset);
-
-	return 0;
-}
-
 static const struct ths_thermal_chip sun8i_a83t_ths = {
 	.sensor_num = 3,
 	.scale = 705,
@@ -641,7 +623,6 @@
 
 static struct platform_driver ths_driver = {
 	.probe = sun8i_ths_probe,
-	.remove = sun8i_ths_remove,
 	.driver = {
 		.name = "sun8i-thermal",
 		.of_match_table = of_ths_match,
diff --git a/kernel/drivers/thunderbolt/nhi.c b/kernel/drivers/thunderbolt/nhi.c
index db80dc5..fd1b593 100644
--- a/kernel/drivers/thunderbolt/nhi.c
+++ b/kernel/drivers/thunderbolt/nhi.c
@@ -36,7 +36,7 @@
 
 #define NHI_MAILBOX_TIMEOUT	500 /* ms */
 
-static int ring_interrupt_index(struct tb_ring *ring)
+static int ring_interrupt_index(const struct tb_ring *ring)
 {
 	int bit = ring->hop;
 	if (!ring->is_tx)
diff --git a/kernel/drivers/thunderbolt/tunnel.c b/kernel/drivers/thunderbolt/tunnel.c
index 829b6cc..011ab5f 100644
--- a/kernel/drivers/thunderbolt/tunnel.c
+++ b/kernel/drivers/thunderbolt/tunnel.c
@@ -956,7 +956,7 @@
 		return;
 	} else if (!ret) {
 		/* Use maximum link rate if the link valid is not set */
-		ret = usb4_usb3_port_max_link_rate(tunnel->src_port);
+		ret = tb_usb3_max_link_rate(tunnel->dst_port, tunnel->src_port);
 		if (ret < 0) {
 			tb_tunnel_warn(tunnel, "failed to read maximum link rate\n");
 			return;
diff --git a/kernel/drivers/thunderbolt/usb4.c b/kernel/drivers/thunderbolt/usb4.c
index 0b3a77a..5b45c45 100644
--- a/kernel/drivers/thunderbolt/usb4.c
+++ b/kernel/drivers/thunderbolt/usb4.c
@@ -1636,18 +1636,30 @@
 						    int downstream_bw)
 {
 	u32 val, ubw, dbw, scale;
-	int ret;
+	int ret, max_bw;
 
-	/* Read the used scale, hardware default is 0 */
-	ret = tb_port_read(port, &scale, TB_CFG_PORT,
-			   port->cap_adap + ADP_USB3_CS_3, 1);
+	/* Figure out suitable scale */
+	scale = 0;
+	max_bw = max(upstream_bw, downstream_bw);
+	while (scale < 64) {
+		if (mbps_to_usb3_bw(max_bw, scale) < 4096)
+			break;
+		scale++;
+	}
+
+	if (WARN_ON(scale >= 64))
+		return -EINVAL;
+
+	ret = tb_port_write(port, &scale, TB_CFG_PORT,
+			    port->cap_adap + ADP_USB3_CS_3, 1);
 	if (ret)
 		return ret;
 
-	scale &= ADP_USB3_CS_3_SCALE_MASK;
 	ubw = mbps_to_usb3_bw(upstream_bw, scale);
 	dbw = mbps_to_usb3_bw(downstream_bw, scale);
 
+	tb_port_dbg(port, "scaled bandwidth %u/%u, scale %u\n", ubw, dbw, scale);
+
 	ret = tb_port_read(port, &val, TB_CFG_PORT,
 			   port->cap_adap + ADP_USB3_CS_2, 1);
 	if (ret)
diff --git a/kernel/drivers/tty/Kconfig b/kernel/drivers/tty/Kconfig
index 93fd984..eb61b34 100644
--- a/kernel/drivers/tty/Kconfig
+++ b/kernel/drivers/tty/Kconfig
@@ -480,6 +480,18 @@
 
 source "drivers/tty/hvc/Kconfig"
 
+config RPMSG_TTY
+	tristate "RPMSG tty driver"
+	depends on RPMSG
+	help
+	  Say y here to export rpmsg endpoints as tty devices, usually found
+	  in /dev/ttyRPMSGx.
+	  This makes it possible for user-space programs to send and receive
+	  rpmsg messages as a standard tty protocol.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called rpmsg_tty.
+
 endif # TTY
 
 source "drivers/tty/serdev/Kconfig"
diff --git a/kernel/drivers/tty/Makefile b/kernel/drivers/tty/Makefile
index 020b1cd..c2465e7 100644
--- a/kernel/drivers/tty/Makefile
+++ b/kernel/drivers/tty/Makefile
@@ -34,5 +34,6 @@
 obj-$(CONFIG_GOLDFISH_TTY)	+= goldfish.o
 obj-$(CONFIG_MIPS_EJTAG_FDC_TTY) += mips_ejtag_fdc.o
 obj-$(CONFIG_VCC)		+= vcc.o
+obj-$(CONFIG_RPMSG_TTY)		+= rpmsg_tty.o
 
 obj-y += ipwireless/
diff --git a/kernel/drivers/tty/hvc/hvc_xen.c b/kernel/drivers/tty/hvc/hvc_xen.c
index 7948660..6f387a4 100644
--- a/kernel/drivers/tty/hvc/hvc_xen.c
+++ b/kernel/drivers/tty/hvc/hvc_xen.c
@@ -52,17 +52,22 @@
 
 static struct xencons_info *vtermno_to_xencons(int vtermno)
 {
-	struct xencons_info *entry, *n, *ret = NULL;
+	struct xencons_info *entry, *ret = NULL;
+	unsigned long flags;
 
-	if (list_empty(&xenconsoles))
-			return NULL;
+	spin_lock_irqsave(&xencons_lock, flags);
+	if (list_empty(&xenconsoles)) {
+		spin_unlock_irqrestore(&xencons_lock, flags);
+		return NULL;
+	}
 
-	list_for_each_entry_safe(entry, n, &xenconsoles, list) {
+	list_for_each_entry(entry, &xenconsoles, list) {
 		if (entry->vtermno == vtermno) {
 			ret  = entry;
 			break;
 		}
 	}
+	spin_unlock_irqrestore(&xencons_lock, flags);
 
 	return ret;
 }
@@ -223,7 +228,7 @@
 {
 	int r;
 	uint64_t v = 0;
-	unsigned long gfn;
+	unsigned long gfn, flags;
 	struct xencons_info *info;
 
 	if (!xen_hvm_domain())
@@ -258,9 +263,9 @@
 		goto err;
 	info->vtermno = HVC_COOKIE;
 
-	spin_lock(&xencons_lock);
+	spin_lock_irqsave(&xencons_lock, flags);
 	list_add_tail(&info->list, &xenconsoles);
-	spin_unlock(&xencons_lock);
+	spin_unlock_irqrestore(&xencons_lock, flags);
 
 	return 0;
 err:
@@ -283,6 +288,7 @@
 static int xen_pv_console_init(void)
 {
 	struct xencons_info *info;
+	unsigned long flags;
 
 	if (!xen_pv_domain())
 		return -ENODEV;
@@ -299,9 +305,9 @@
 		/* already configured */
 		return 0;
 	}
-	spin_lock(&xencons_lock);
+	spin_lock_irqsave(&xencons_lock, flags);
 	xencons_info_pv_init(info, HVC_COOKIE);
-	spin_unlock(&xencons_lock);
+	spin_unlock_irqrestore(&xencons_lock, flags);
 
 	return 0;
 }
@@ -309,6 +315,7 @@
 static int xen_initial_domain_console_init(void)
 {
 	struct xencons_info *info;
+	unsigned long flags;
 
 	if (!xen_initial_domain())
 		return -ENODEV;
@@ -323,9 +330,9 @@
 	info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0, false);
 	info->vtermno = HVC_COOKIE;
 
-	spin_lock(&xencons_lock);
+	spin_lock_irqsave(&xencons_lock, flags);
 	list_add_tail(&info->list, &xenconsoles);
-	spin_unlock(&xencons_lock);
+	spin_unlock_irqrestore(&xencons_lock, flags);
 
 	return 0;
 }
@@ -380,10 +387,12 @@
 
 static int xen_console_remove(struct xencons_info *info)
 {
+	unsigned long flags;
+
 	xencons_disconnect_backend(info);
-	spin_lock(&xencons_lock);
+	spin_lock_irqsave(&xencons_lock, flags);
 	list_del(&info->list);
-	spin_unlock(&xencons_lock);
+	spin_unlock_irqrestore(&xencons_lock, flags);
 	if (info->xbdev != NULL)
 		xencons_free(info);
 	else {
@@ -464,6 +473,7 @@
 {
 	int ret, devid;
 	struct xencons_info *info;
+	unsigned long flags;
 
 	devid = dev->nodename[strlen(dev->nodename) - 1] - '0';
 	if (devid == 0)
@@ -482,9 +492,9 @@
 	ret = xencons_connect_backend(dev, info);
 	if (ret < 0)
 		goto error;
-	spin_lock(&xencons_lock);
+	spin_lock_irqsave(&xencons_lock, flags);
 	list_add_tail(&info->list, &xenconsoles);
-	spin_unlock(&xencons_lock);
+	spin_unlock_irqrestore(&xencons_lock, flags);
 
 	return 0;
 
@@ -583,10 +593,12 @@
 
 	info->hvc = hvc_alloc(HVC_COOKIE, info->irq, ops, 256);
 	if (IS_ERR(info->hvc)) {
+		unsigned long flags;
+
 		r = PTR_ERR(info->hvc);
-		spin_lock(&xencons_lock);
+		spin_lock_irqsave(&xencons_lock, flags);
 		list_del(&info->list);
-		spin_unlock(&xencons_lock);
+		spin_unlock_irqrestore(&xencons_lock, flags);
 		if (info->irq)
 			unbind_from_irqhandler(info->irq, NULL);
 		kfree(info);
diff --git a/kernel/drivers/tty/n_gsm.c b/kernel/drivers/tty/n_gsm.c
index f506349..94c9634 100644
--- a/kernel/drivers/tty/n_gsm.c
+++ b/kernel/drivers/tty/n_gsm.c
@@ -50,6 +50,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/gsmmux.h>
+#include "tty.h"
 
 static int debug;
 module_param(debug, int, 0600);
@@ -2158,12 +2159,13 @@
 static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
 {
 	int i;
-	struct gsm_dlci *dlci = gsm->dlci[0];
+	struct gsm_dlci *dlci;
 	struct gsm_msg *txq, *ntxq;
 
 	gsm->dead = true;
 	mutex_lock(&gsm->mutex);
 
+	dlci = gsm->dlci[0];
 	if (dlci) {
 		if (disc && dlci->state != DLCI_CLOSED) {
 			gsm_dlci_begin_close(dlci);
@@ -2177,8 +2179,10 @@
 
 	/* Free up any link layer users and finally the control channel */
 	for (i = NUM_DLCI - 1; i >= 0; i--)
-		if (gsm->dlci[i])
+		if (gsm->dlci[i]) {
 			gsm_dlci_release(gsm->dlci[i]);
+			gsm->dlci[i] = NULL;
+		}
 	mutex_unlock(&gsm->mutex);
 	/* Now wipe the queues */
 	tty_ldisc_flush(gsm->tty);
diff --git a/kernel/drivers/tty/n_hdlc.c b/kernel/drivers/tty/n_hdlc.c
index 48c64e6..697199a 100644
--- a/kernel/drivers/tty/n_hdlc.c
+++ b/kernel/drivers/tty/n_hdlc.c
@@ -100,6 +100,7 @@
 
 #include <asm/termios.h>
 #include <linux/uaccess.h>
+#include "tty.h"
 
 /*
  * Buffers for individual HDLC frames
diff --git a/kernel/drivers/tty/n_tty.c b/kernel/drivers/tty/n_tty.c
index 12dde01..8e7931d 100644
--- a/kernel/drivers/tty/n_tty.c
+++ b/kernel/drivers/tty/n_tty.c
@@ -49,6 +49,7 @@
 #include <linux/module.h>
 #include <linux/ratelimit.h>
 #include <linux/vmalloc.h>
+#include "tty.h"
 
 /*
  * Until this number of characters is queued in the xmit buffer, select will
diff --git a/kernel/drivers/tty/pty.c b/kernel/drivers/tty/pty.c
index 16498f5..ca3e5a6 100644
--- a/kernel/drivers/tty/pty.c
+++ b/kernel/drivers/tty/pty.c
@@ -29,6 +29,7 @@
 #include <linux/file.h>
 #include <linux/ioctl.h>
 #include <linux/compat.h>
+#include "tty.h"
 
 #undef TTY_DEBUG_HANGUP
 #ifdef TTY_DEBUG_HANGUP
diff --git a/kernel/drivers/tty/rpmsg_tty.c b/kernel/drivers/tty/rpmsg_tty.c
new file mode 100644
index 0000000..23b99a4
--- /dev/null
+++ b/kernel/drivers/tty/rpmsg_tty.c
@@ -0,0 +1,287 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 STMicroelectronics - All Rights Reserved
+ *
+ * The rpmsg tty driver implements serial communication on the RPMsg bus to makes
+ * possible for user-space programs to send and receive rpmsg messages as a standard
+ * tty protocol.
+ *
+ * The remote processor can instantiate a new tty by requesting a "rpmsg-tty" RPMsg service.
+ * The "rpmsg-tty" service is directly used for data exchange. No flow control is implemented yet.
+ */
+
+#define pr_fmt(fmt)		KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/rpmsg.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+
+#define RPMSG_TTY_NAME	"ttyRPMSG"
+#define MAX_TTY_RPMSG	32
+
+static DEFINE_IDR(tty_idr);	/* tty instance id */
+static DEFINE_MUTEX(idr_lock);	/* protects tty_idr */
+
+static struct tty_driver *rpmsg_tty_driver;
+
+struct rpmsg_tty_port {
+	struct tty_port		port;	 /* TTY port data */
+	int			id;	 /* TTY rpmsg index */
+	struct rpmsg_device	*rpdev;	 /* rpmsg device */
+};
+
+static int rpmsg_tty_cb(struct rpmsg_device *rpdev, void *data, int len, void *priv, u32 src)
+{
+	struct rpmsg_tty_port *cport = dev_get_drvdata(&rpdev->dev);
+	int copied;
+
+	if (!len)
+		return -EINVAL;
+	copied = tty_insert_flip_string(&cport->port, data, len);
+	if (copied != len)
+		dev_err_ratelimited(&rpdev->dev, "Trunc buffer: available space is %d\n", copied);
+	tty_flip_buffer_push(&cport->port);
+
+	return 0;
+}
+
+static int rpmsg_tty_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+	struct rpmsg_tty_port *cport = idr_find(&tty_idr, tty->index);
+	struct tty_port *port;
+
+	tty->driver_data = cport;
+
+	port = tty_port_get(&cport->port);
+	return tty_port_install(port, driver, tty);
+}
+
+static void rpmsg_tty_cleanup(struct tty_struct *tty)
+{
+	tty_port_put(tty->port);
+}
+
+static int rpmsg_tty_open(struct tty_struct *tty, struct file *filp)
+{
+	return tty_port_open(tty->port, tty, filp);
+}
+
+static void rpmsg_tty_close(struct tty_struct *tty, struct file *filp)
+{
+	return tty_port_close(tty->port, tty, filp);
+}
+
+static int rpmsg_tty_write(struct tty_struct *tty, const u8 *buf, int len)
+{
+	struct rpmsg_tty_port *cport = tty->driver_data;
+	struct rpmsg_device *rpdev;
+	int msg_max_size, msg_size;
+	int ret;
+
+	rpdev = cport->rpdev;
+
+	msg_max_size = rpmsg_get_mtu(rpdev->ept);
+	if (msg_max_size < 0)
+		return msg_max_size;
+
+	msg_size = min(len, msg_max_size);
+
+	/*
+	 * Use rpmsg_trysend instead of rpmsg_send to send the message so the caller is not
+	 * hung until a rpmsg buffer is available. In such case rpmsg_trysend returns -ENOMEM.
+	 */
+	ret = rpmsg_trysend(rpdev->ept, (void *)buf, msg_size);
+	if (ret) {
+		dev_dbg_ratelimited(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
+		return ret;
+	}
+
+	return msg_size;
+}
+
+static int rpmsg_tty_write_room(struct tty_struct *tty)
+{
+	struct rpmsg_tty_port *cport = tty->driver_data;
+	int size;
+
+	size = rpmsg_get_mtu(cport->rpdev->ept);
+	if (size < 0)
+		return 0;
+
+	return size;
+}
+
+static void rpmsg_tty_hangup(struct tty_struct *tty)
+{
+	tty_port_hangup(tty->port);
+}
+
+static const struct tty_operations rpmsg_tty_ops = {
+	.install	= rpmsg_tty_install,
+	.open		= rpmsg_tty_open,
+	.close		= rpmsg_tty_close,
+	.write		= rpmsg_tty_write,
+	.write_room	= rpmsg_tty_write_room,
+	.hangup		= rpmsg_tty_hangup,
+	.cleanup	= rpmsg_tty_cleanup,
+};
+
+static struct rpmsg_tty_port *rpmsg_tty_alloc_cport(void)
+{
+	struct rpmsg_tty_port *cport;
+	int ret;
+
+	cport = kzalloc(sizeof(*cport), GFP_KERNEL);
+	if (!cport)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_lock(&idr_lock);
+	ret = idr_alloc(&tty_idr, cport, 0, MAX_TTY_RPMSG, GFP_KERNEL);
+	mutex_unlock(&idr_lock);
+
+	if (ret < 0) {
+		kfree(cport);
+		return ERR_PTR(ret);
+	}
+
+	cport->id = ret;
+
+	return cport;
+}
+
+static void rpmsg_tty_destruct_port(struct tty_port *port)
+{
+	struct rpmsg_tty_port *cport = container_of(port, struct rpmsg_tty_port, port);
+
+	mutex_lock(&idr_lock);
+	idr_remove(&tty_idr, cport->id);
+	mutex_unlock(&idr_lock);
+
+	kfree(cport);
+}
+
+static const struct tty_port_operations rpmsg_tty_port_ops = {
+	.destruct = rpmsg_tty_destruct_port,
+};
+
+
+static int rpmsg_tty_probe(struct rpmsg_device *rpdev)
+{
+	struct rpmsg_tty_port *cport;
+	struct device *dev = &rpdev->dev;
+	struct device *tty_dev;
+	int ret;
+
+	cport = rpmsg_tty_alloc_cport();
+	if (IS_ERR(cport))
+		return dev_err_probe(dev, PTR_ERR(cport), "Failed to alloc tty port\n");
+
+	tty_port_init(&cport->port);
+	cport->port.ops = &rpmsg_tty_port_ops;
+
+	tty_dev = tty_port_register_device(&cport->port, rpmsg_tty_driver,
+					   cport->id, dev);
+	if (IS_ERR(tty_dev)) {
+		ret = dev_err_probe(dev, PTR_ERR(tty_dev), "Failed to register tty port\n");
+		tty_port_put(&cport->port);
+		return ret;
+	}
+
+	cport->rpdev = rpdev;
+
+	dev_set_drvdata(dev, cport);
+
+	dev_dbg(dev, "New channel: 0x%x -> 0x%x: " RPMSG_TTY_NAME "%d\n",
+		rpdev->src, rpdev->dst, cport->id);
+
+	return 0;
+}
+
+static void rpmsg_tty_remove(struct rpmsg_device *rpdev)
+{
+	struct rpmsg_tty_port *cport = dev_get_drvdata(&rpdev->dev);
+
+	dev_dbg(&rpdev->dev, "Removing rpmsg tty device %d\n", cport->id);
+
+	/* User hang up to release the tty */
+	tty_port_tty_hangup(&cport->port, false);
+
+	tty_unregister_device(rpmsg_tty_driver, cport->id);
+
+	tty_port_put(&cport->port);
+}
+
+static struct rpmsg_device_id rpmsg_driver_tty_id_table[] = {
+	{ .name	= "rpmsg-tty" },
+	{ },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_tty_id_table);
+
+static struct rpmsg_driver rpmsg_tty_rpmsg_drv = {
+	.drv.name	= KBUILD_MODNAME,
+	.id_table	= rpmsg_driver_tty_id_table,
+	.probe		= rpmsg_tty_probe,
+	.callback	= rpmsg_tty_cb,
+	.remove		= rpmsg_tty_remove,
+};
+
+static int __init rpmsg_tty_init(void)
+{
+	int ret;
+
+	rpmsg_tty_driver = tty_alloc_driver(MAX_TTY_RPMSG, TTY_DRIVER_REAL_RAW |
+					    TTY_DRIVER_DYNAMIC_DEV);
+	if (IS_ERR(rpmsg_tty_driver))
+		return PTR_ERR(rpmsg_tty_driver);
+
+	rpmsg_tty_driver->driver_name = "rpmsg_tty";
+	rpmsg_tty_driver->name = RPMSG_TTY_NAME;
+	rpmsg_tty_driver->major = 0;
+	rpmsg_tty_driver->type = TTY_DRIVER_TYPE_CONSOLE;
+
+	/* Disable unused mode by default */
+	rpmsg_tty_driver->init_termios = tty_std_termios;
+	rpmsg_tty_driver->init_termios.c_lflag &= ~(ECHO | ICANON);
+	rpmsg_tty_driver->init_termios.c_oflag &= ~(OPOST | ONLCR);
+
+	tty_set_operations(rpmsg_tty_driver, &rpmsg_tty_ops);
+
+	ret = tty_register_driver(rpmsg_tty_driver);
+	if (ret < 0) {
+		pr_err("Couldn't install driver: %d\n", ret);
+		goto error_put;
+	}
+
+	ret = register_rpmsg_driver(&rpmsg_tty_rpmsg_drv);
+	if (ret < 0) {
+		pr_err("Couldn't register driver: %d\n", ret);
+		goto error_unregister;
+	}
+
+	return 0;
+
+error_unregister:
+	tty_unregister_driver(rpmsg_tty_driver);
+
+error_put:
+	tty_driver_kref_put(rpmsg_tty_driver);
+
+	return ret;
+}
+
+static void __exit rpmsg_tty_exit(void)
+{
+	unregister_rpmsg_driver(&rpmsg_tty_rpmsg_drv);
+	tty_unregister_driver(rpmsg_tty_driver);
+	tty_driver_kref_put(rpmsg_tty_driver);
+	idr_destroy(&tty_idr);
+}
+
+module_init(rpmsg_tty_init);
+module_exit(rpmsg_tty_exit);
+
+MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>");
+MODULE_DESCRIPTION("remote processor messaging tty driver");
+MODULE_LICENSE("GPL v2");
diff --git a/kernel/drivers/tty/serial/8250/8250.h b/kernel/drivers/tty/serial/8250/8250.h
index 2e001e2..97df058 100644
--- a/kernel/drivers/tty/serial/8250/8250.h
+++ b/kernel/drivers/tty/serial/8250/8250.h
@@ -342,6 +342,13 @@
 extern void serial8250_rx_dma_flush(struct uart_8250_port *);
 extern int serial8250_request_dma(struct uart_8250_port *);
 extern void serial8250_release_dma(struct uart_8250_port *);
+
+static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)
+{
+	struct uart_8250_dma *dma = p->dma;
+
+	return dma && dma->tx_running;
+}
 #else
 static inline int serial8250_tx_dma(struct uart_8250_port *p)
 {
@@ -363,6 +370,11 @@
 	return -1;
 }
 static inline void serial8250_release_dma(struct uart_8250_port *p) { }
+
+static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)
+{
+	return false;
+}
 #endif
 
 static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)
diff --git a/kernel/drivers/tty/serial/8250/8250_core.c b/kernel/drivers/tty/serial/8250/8250_core.c
index 00f6dc7..0a29e86 100644
--- a/kernel/drivers/tty/serial/8250/8250_core.c
+++ b/kernel/drivers/tty/serial/8250/8250_core.c
@@ -1163,6 +1163,7 @@
 		uart->port.type = PORT_UNKNOWN;
 		uart->port.dev = &serial8250_isa_devs->dev;
 		uart->capabilities = 0;
+		serial8250_init_port(uart);
 		serial8250_apply_quirks(uart);
 		uart_add_one_port(&serial8250_reg, &uart->port);
 	} else {
diff --git a/kernel/drivers/tty/serial/8250/8250_dma.c b/kernel/drivers/tty/serial/8250/8250_dma.c
index d8da062..8cde714 100644
--- a/kernel/drivers/tty/serial/8250/8250_dma.c
+++ b/kernel/drivers/tty/serial/8250/8250_dma.c
@@ -15,6 +15,7 @@
 #define MAX_TX_BYTES		64
 #define MAX_FIFO_SIZE		64
 #define UART_RFL_16550A		0x21
+#define DW_UART_DMASA		0x2a
 #endif
 
 static void __dma_tx_complete(void *param)
@@ -85,19 +86,38 @@
 	struct uart_8250_dma	*dma = p->dma;
 	struct tty_port		*tty_port = &p->port.state->port;
 	struct dma_tx_state	state;
+	enum dma_status		dma_status;
 	int			count;
 
-	dma->rx_running = 0;
-	dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
+	/*
+	 * New DMA Rx can be started during the completion handler before it
+	 * could acquire port's lock and it might still be ongoing. Don't to
+	 * anything in such case.
+	 */
+	dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
+	if (dma_status == DMA_IN_PROGRESS)
+		return;
 
 	count = dma->rx_size - state.residue;
 
 	tty_insert_flip_string(tty_port, dma->rx_buf, count);
 	p->port.icount.rx += count;
+	dma->rx_running = 0;
 
 	tty_flip_buffer_push(tty_port);
 }
 
+static void dma_rx_complete(void *param)
+{
+	struct uart_8250_port *p = param;
+	struct uart_8250_dma *dma = p->dma;
+	unsigned long flags;
+
+	spin_lock_irqsave(&p->port.lock, flags);
+	if (dma->rx_running)
+		__dma_rx_complete(p);
+	spin_unlock_irqrestore(&p->port.lock, flags);
+}
 #endif
 
 int serial8250_tx_dma(struct uart_8250_port *p)
@@ -150,6 +170,10 @@
 	dma_sync_single_for_device(dma->txchan->device->dev, dma->tx_addr,
 				   UART_XMIT_SIZE, DMA_TO_DEVICE);
 
+#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
+	/* Clear uart dma request before start dma */
+	serial_port_out(&p->port, DW_UART_DMASA, 0x1);
+#endif
 	dma_async_issue_pending(dma->txchan);
 	if (dma->tx_err) {
 		dma->tx_err = 0;
@@ -234,7 +258,7 @@
 		return -EBUSY;
 
 	dma->rx_running = 1;
-	desc->callback = __dma_rx_complete;
+	desc->callback = dma_rx_complete;
 	desc->callback_param = p;
 
 	dma->rx_cookie = dmaengine_submit(desc);
diff --git a/kernel/drivers/tty/serial/8250/8250_dwlib.c b/kernel/drivers/tty/serial/8250/8250_dwlib.c
index a0829e1..0dfb868 100644
--- a/kernel/drivers/tty/serial/8250/8250_dwlib.c
+++ b/kernel/drivers/tty/serial/8250/8250_dwlib.c
@@ -80,7 +80,7 @@
 void dw8250_setup_port(struct uart_port *p)
 {
 	struct uart_8250_port *up = up_to_u8250p(p);
-	u32 reg;
+	u32 reg, old_dlf;
 
 	/*
 	 * If the Component Version Register returns zero, we know that
@@ -93,9 +93,11 @@
 	dev_dbg(p->dev, "Designware UART version %c.%c%c\n",
 		(reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff);
 
+	/* Preserve value written by firmware or bootloader  */
+	old_dlf = dw8250_readl_ext(p, DW_UART_DLF);
 	dw8250_writel_ext(p, DW_UART_DLF, ~0U);
 	reg = dw8250_readl_ext(p, DW_UART_DLF);
-	dw8250_writel_ext(p, DW_UART_DLF, 0);
+	dw8250_writel_ext(p, DW_UART_DLF, old_dlf);
 
 	if (reg) {
 		struct dw8250_port_data *d = p->private_data;
diff --git a/kernel/drivers/tty/serial/8250/8250_em.c b/kernel/drivers/tty/serial/8250/8250_em.c
index f8e9999..d94c381 100644
--- a/kernel/drivers/tty/serial/8250/8250_em.c
+++ b/kernel/drivers/tty/serial/8250/8250_em.c
@@ -106,8 +106,8 @@
 	memset(&up, 0, sizeof(up));
 	up.port.mapbase = regs->start;
 	up.port.irq = irq;
-	up.port.type = PORT_UNKNOWN;
-	up.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_IOREMAP;
+	up.port.type = PORT_16750;
+	up.port.flags = UPF_FIXED_PORT | UPF_IOREMAP | UPF_FIXED_TYPE;
 	up.port.dev = &pdev->dev;
 	up.port.private_data = priv;
 
diff --git a/kernel/drivers/tty/serial/8250/8250_exar.c b/kernel/drivers/tty/serial/8250/8250_exar.c
index 2d0e7c7..5c2adf1 100644
--- a/kernel/drivers/tty/serial/8250/8250_exar.c
+++ b/kernel/drivers/tty/serial/8250/8250_exar.c
@@ -40,8 +40,18 @@
 #define PCI_DEVICE_ID_COMMTECH_4224PCIE		0x0020
 #define PCI_DEVICE_ID_COMMTECH_4228PCIE		0x0021
 #define PCI_DEVICE_ID_COMMTECH_4222PCIE		0x0022
+
 #define PCI_DEVICE_ID_EXAR_XR17V4358		0x4358
 #define PCI_DEVICE_ID_EXAR_XR17V8358		0x8358
+
+#define PCI_SUBDEVICE_ID_USR_2980		0x0128
+#define PCI_SUBDEVICE_ID_USR_2981		0x0129
+
+#define PCI_DEVICE_ID_SEALEVEL_710xC		0x1001
+#define PCI_DEVICE_ID_SEALEVEL_720xC		0x1002
+#define PCI_DEVICE_ID_SEALEVEL_740xC		0x1004
+#define PCI_DEVICE_ID_SEALEVEL_780xC		0x1008
+#define PCI_DEVICE_ID_SEALEVEL_716xC		0x1010
 
 #define UART_EXAR_INT0		0x80
 #define UART_EXAR_8XMODE	0x88	/* 8X sampling rate select */
@@ -596,7 +606,14 @@
 
 	maxnr = pci_resource_len(pcidev, bar) >> (board->reg_shift + 3);
 
-	nr_ports = board->num_ports ? board->num_ports : pcidev->device & 0x0f;
+	if (pcidev->vendor == PCI_VENDOR_ID_ACCESSIO)
+		nr_ports = BIT(((pcidev->device & 0x38) >> 3) - 1);
+	else if (board->num_ports)
+		nr_ports = board->num_ports;
+	else if (pcidev->vendor == PCI_VENDOR_ID_SEALEVEL)
+		nr_ports = pcidev->device & 0xff;
+	else
+		nr_ports = pcidev->device & 0x0f;
 
 	priv = devm_kzalloc(&pcidev->dev, struct_size(priv, line, nr_ports), GFP_KERNEL);
 	if (!priv)
@@ -695,22 +712,6 @@
 
 static SIMPLE_DEV_PM_OPS(exar_pci_pm, exar_suspend, exar_resume);
 
-static const struct exar8250_board acces_com_2x = {
-	.num_ports	= 2,
-	.setup		= pci_xr17c154_setup,
-};
-
-static const struct exar8250_board acces_com_4x = {
-	.num_ports	= 4,
-	.setup		= pci_xr17c154_setup,
-};
-
-static const struct exar8250_board acces_com_8x = {
-	.num_ports	= 8,
-	.setup		= pci_xr17c154_setup,
-};
-
-
 static const struct exar8250_board pbn_fastcom335_2 = {
 	.num_ports	= 2,
 	.setup		= pci_fastcom335_setup,
@@ -794,14 +795,23 @@
 		(kernel_ulong_t)&bd			\
 	}
 
+#define USR_DEVICE(devid, sdevid, bd) {			\
+	PCI_DEVICE_SUB(					\
+		PCI_VENDOR_ID_USR,			\
+		PCI_DEVICE_ID_EXAR_##devid,		\
+		PCI_VENDOR_ID_EXAR,			\
+		PCI_SUBDEVICE_ID_USR_##sdevid), 0, 0,	\
+		(kernel_ulong_t)&bd			\
+	}
+
 static const struct pci_device_id exar_pci_tbl[] = {
-	EXAR_DEVICE(ACCESSIO, COM_2S, acces_com_2x),
-	EXAR_DEVICE(ACCESSIO, COM_4S, acces_com_4x),
-	EXAR_DEVICE(ACCESSIO, COM_8S, acces_com_8x),
-	EXAR_DEVICE(ACCESSIO, COM232_8, acces_com_8x),
-	EXAR_DEVICE(ACCESSIO, COM_2SM, acces_com_2x),
-	EXAR_DEVICE(ACCESSIO, COM_4SM, acces_com_4x),
-	EXAR_DEVICE(ACCESSIO, COM_8SM, acces_com_8x),
+	EXAR_DEVICE(ACCESSIO, COM_2S, pbn_exar_XR17C15x),
+	EXAR_DEVICE(ACCESSIO, COM_4S, pbn_exar_XR17C15x),
+	EXAR_DEVICE(ACCESSIO, COM_8S, pbn_exar_XR17C15x),
+	EXAR_DEVICE(ACCESSIO, COM232_8, pbn_exar_XR17C15x),
+	EXAR_DEVICE(ACCESSIO, COM_2SM, pbn_exar_XR17C15x),
+	EXAR_DEVICE(ACCESSIO, COM_4SM, pbn_exar_XR17C15x),
+	EXAR_DEVICE(ACCESSIO, COM_8SM, pbn_exar_XR17C15x),
 
 	CONNECT_DEVICE(XR17C152, UART_2_232, pbn_connect),
 	CONNECT_DEVICE(XR17C154, UART_4_232, pbn_connect),
@@ -817,6 +827,10 @@
 	CONNECT_DEVICE(XR17C158, UART_8_485, pbn_connect),
 
 	IBM_DEVICE(XR17C152, SATURN_SERIAL_ONE_PORT, pbn_exar_ibm_saturn),
+
+	/* USRobotics USR298x-OEM PCI Modems */
+	USR_DEVICE(XR17C152, 2980, pbn_exar_XR17C15x),
+	USR_DEVICE(XR17C152, 2981, pbn_exar_XR17C15x),
 
 	/* Exar Corp. XR17C15[248] Dual/Quad/Octal UART */
 	EXAR_DEVICE(EXAR, XR17C152, pbn_exar_XR17C15x),
@@ -837,6 +851,12 @@
 	EXAR_DEVICE(COMMTECH, 4224PCI335, pbn_fastcom335_4),
 	EXAR_DEVICE(COMMTECH, 2324PCI335, pbn_fastcom335_4),
 	EXAR_DEVICE(COMMTECH, 2328PCI335, pbn_fastcom335_8),
+
+	EXAR_DEVICE(SEALEVEL, 710xC, pbn_exar_XR17V35x),
+	EXAR_DEVICE(SEALEVEL, 720xC, pbn_exar_XR17V35x),
+	EXAR_DEVICE(SEALEVEL, 740xC, pbn_exar_XR17V35x),
+	EXAR_DEVICE(SEALEVEL, 780xC, pbn_exar_XR17V35x),
+	EXAR_DEVICE(SEALEVEL, 716xC, pbn_exar_XR17V35x),
 	{ 0, }
 };
 MODULE_DEVICE_TABLE(pci, exar_pci_tbl);
diff --git a/kernel/drivers/tty/serial/8250/8250_omap.c b/kernel/drivers/tty/serial/8250/8250_omap.c
index 483fff3..e26ac3f 100644
--- a/kernel/drivers/tty/serial/8250/8250_omap.c
+++ b/kernel/drivers/tty/serial/8250/8250_omap.c
@@ -653,6 +653,8 @@
 	if ((lsr & UART_LSR_OE) && up->overrun_backoff_time_ms > 0) {
 		unsigned long delay;
 
+		/* Synchronize UART_IER access against the console. */
+		spin_lock(&port->lock);
 		up->ier = port->serial_in(port, UART_IER);
 		if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) {
 			port->ops->stop_rx(port);
@@ -662,6 +664,7 @@
 			 */
 			cancel_delayed_work(&up->overrun_backoff);
 		}
+		spin_unlock(&port->lock);
 
 		delay = msecs_to_jiffies(up->overrun_backoff_time_ms);
 		schedule_delayed_work(&up->overrun_backoff, delay);
@@ -1469,7 +1472,9 @@
 err:
 	pm_runtime_dont_use_autosuspend(&pdev->dev);
 	pm_runtime_put_sync(&pdev->dev);
+	flush_work(&priv->qos_work);
 	pm_runtime_disable(&pdev->dev);
+	cpu_latency_qos_remove_request(&priv->pm_qos_request);
 	return ret;
 }
 
@@ -1516,25 +1521,35 @@
 {
 	struct omap8250_priv *priv = dev_get_drvdata(dev);
 	struct uart_8250_port *up = serial8250_get_port(priv->line);
+	int err;
 
 	serial8250_suspend_port(priv->line);
 
-	pm_runtime_get_sync(dev);
+	err = pm_runtime_resume_and_get(dev);
+	if (err)
+		return err;
 	if (!device_may_wakeup(dev))
 		priv->wer = 0;
 	serial_out(up, UART_OMAP_WER, priv->wer);
-	pm_runtime_mark_last_busy(dev);
-	pm_runtime_put_autosuspend(dev);
-
+	err = pm_runtime_force_suspend(dev);
 	flush_work(&priv->qos_work);
-	return 0;
+
+	return err;
 }
 
 static int omap8250_resume(struct device *dev)
 {
 	struct omap8250_priv *priv = dev_get_drvdata(dev);
+	int err;
 
+	err = pm_runtime_force_resume(dev);
+	if (err)
+		return err;
 	serial8250_resume_port(priv->line);
+	/* Paired with pm_runtime_resume_and_get() in omap8250_suspend() */
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
 	return 0;
 }
 #else
diff --git a/kernel/drivers/tty/serial/8250/8250_pci.c b/kernel/drivers/tty/serial/8250/8250_pci.c
index b665689..9617f7a 100644
--- a/kernel/drivers/tty/serial/8250/8250_pci.c
+++ b/kernel/drivers/tty/serial/8250/8250_pci.c
@@ -1839,6 +1839,8 @@
 #define PCI_SUBDEVICE_ID_SIIG_DUAL_30	0x2530
 #define PCI_VENDOR_ID_ADVANTECH		0x13fe
 #define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66
+#define PCI_DEVICE_ID_ADVANTECH_PCI1600	0x1600
+#define PCI_DEVICE_ID_ADVANTECH_PCI1600_1611	0x1611
 #define PCI_DEVICE_ID_ADVANTECH_PCI3620	0x3620
 #define PCI_DEVICE_ID_ADVANTECH_PCI3618	0x3618
 #define PCI_DEVICE_ID_ADVANTECH_PCIf618	0xf618
@@ -4185,6 +4187,9 @@
 			 pciserial_resume_one);
 
 static const struct pci_device_id serial_pci_tbl[] = {
+	{	PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI1600,
+		PCI_DEVICE_ID_ADVANTECH_PCI1600_1611, PCI_ANY_ID, 0, 0,
+		pbn_b0_4_921600 },
 	/* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */
 	{	PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620,
 		PCI_DEVICE_ID_ADVANTECH_PCI3620, 0x0001, 0, 0,
diff --git a/kernel/drivers/tty/serial/8250/8250_port.c b/kernel/drivers/tty/serial/8250/8250_port.c
index 61f225a..9eadc7f 100644
--- a/kernel/drivers/tty/serial/8250/8250_port.c
+++ b/kernel/drivers/tty/serial/8250/8250_port.c
@@ -15,6 +15,7 @@
 #include <linux/moduleparam.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
+#include <linux/irq.h>
 #include <linux/console.h>
 #include <linux/gpio/consumer.h>
 #include <linux/sysrq.h>
@@ -1909,6 +1910,7 @@
 	unsigned long flags;
 	struct uart_8250_port *up = up_to_u8250p(port);
 #ifndef CONFIG_ARCH_ROCKCHIP
+	struct tty_port *tport = &port->state->port;
 	bool skip_rx = false;
 #endif
 
@@ -1944,6 +1946,11 @@
 		skip_rx = true;
 
 	if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) {
+		struct irq_data *d;
+
+		d = irq_get_irq_data(port->irq);
+		if (d && irqd_is_wakeup_set(d))
+			pm_wakeup_event(tport->tty->dev, 0);
 		if (!up->dma || handle_rx_dma(up, iir))
 			status = serial8250_rx_chars(up, status);
 	}
@@ -2022,19 +2029,25 @@
 static unsigned int serial8250_tx_empty(struct uart_port *port)
 {
 	struct uart_8250_port *up = up_to_u8250p(port);
+	unsigned int result = 0;
 	unsigned long flags;
 	unsigned int lsr;
 
 	serial8250_rpm_get(up);
 
 	spin_lock_irqsave(&port->lock, flags);
-	lsr = serial_port_in(port, UART_LSR);
-	up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+	if (!serial8250_tx_dma_running(up)) {
+		lsr = serial_port_in(port, UART_LSR);
+		up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+
+		if ((lsr & BOTH_EMPTY) == BOTH_EMPTY)
+			result = TIOCSER_TEMT;
+	}
 	spin_unlock_irqrestore(&port->lock, flags);
 
 	serial8250_rpm_put(up);
 
-	return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0;
+	return result;
 }
 
 unsigned int serial8250_do_get_mctrl(struct uart_port *port)
@@ -3326,6 +3339,7 @@
 	struct uart_port *port = &up->port;
 
 	spin_lock_init(&port->lock);
+	port->pm = NULL;
 	port->ops = &serial8250_pops;
 	port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_8250_CONSOLE);
 
diff --git a/kernel/drivers/tty/serial/8250/8250_tegra.c b/kernel/drivers/tty/serial/8250/8250_tegra.c
index c0ffad1..b6694dd 100644
--- a/kernel/drivers/tty/serial/8250/8250_tegra.c
+++ b/kernel/drivers/tty/serial/8250/8250_tegra.c
@@ -111,13 +111,15 @@
 
 	ret = serial8250_register_8250_port(&port8250);
 	if (ret < 0)
-		goto err_clkdisable;
+		goto err_ctrl_assert;
 
 	platform_set_drvdata(pdev, uart);
 	uart->line = ret;
 
 	return 0;
 
+err_ctrl_assert:
+	reset_control_assert(uart->rst);
 err_clkdisable:
 	clk_disable_unprepare(uart->clk);
 
diff --git a/kernel/drivers/tty/serial/8250/Kconfig b/kernel/drivers/tty/serial/8250/Kconfig
index 136f2b1..b7922c8 100644
--- a/kernel/drivers/tty/serial/8250/Kconfig
+++ b/kernel/drivers/tty/serial/8250/Kconfig
@@ -254,7 +254,9 @@
 	tristate "Aspeed Virtual UART"
 	depends on SERIAL_8250
 	depends on OF
-	depends on REGMAP && MFD_SYSCON
+	depends on MFD_SYSCON
+	depends on ARCH_ASPEED || COMPILE_TEST
+	select REGMAP
 	help
 	  If you want to use the virtual UART (VUART) device on Aspeed
 	  BMC platforms, enable this option. This enables the 16550A-
diff --git a/kernel/drivers/tty/serial/altera_uart.c b/kernel/drivers/tty/serial/altera_uart.c
index 0e487ce..d91f76b 100644
--- a/kernel/drivers/tty/serial/altera_uart.c
+++ b/kernel/drivers/tty/serial/altera_uart.c
@@ -199,9 +199,8 @@
 	 */
 }
 
-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 @@
 	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) {
@@ -274,26 +272,25 @@
 	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)
 {
 	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(pp);
+		altera_uart_rx_chars(port);
 	if (isr & ALTERA_UART_STATUS_TRDY_MSK)
-		altera_uart_tx_chars(pp);
-	spin_unlock(&port->lock);
+		altera_uart_tx_chars(port);
+	spin_unlock_irqrestore(&port->lock, flags);
 
 	return IRQ_RETVAL(isr);
 }
diff --git a/kernel/drivers/tty/serial/amba-pl011.c b/kernel/drivers/tty/serial/amba-pl011.c
index 9900ee3..348d4b2 100644
--- a/kernel/drivers/tty/serial/amba-pl011.c
+++ b/kernel/drivers/tty/serial/amba-pl011.c
@@ -1048,6 +1048,9 @@
  */
 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);
@@ -1757,8 +1760,17 @@
 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)
diff --git a/kernel/drivers/tty/serial/arc_uart.c b/kernel/drivers/tty/serial/arc_uart.c
index 17c3fc3..6f7a7d2 100644
--- a/kernel/drivers/tty/serial/arc_uart.c
+++ b/kernel/drivers/tty/serial/arc_uart.c
@@ -609,10 +609,11 @@
 	}
 	uart->baud = val;
 
-	port->membase = of_iomap(np, 0);
-	if (!port->membase)
+	port->membase = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(port->membase)) {
 		/* No point of dev_err since UART itself is hosed here */
-		return -ENXIO;
+		return PTR_ERR(port->membase);
+	}
 
 	port->irq = irq_of_parse_and_map(np, 0);
 
diff --git a/kernel/drivers/tty/serial/atmel_serial.c b/kernel/drivers/tty/serial/atmel_serial.c
index b7872ad..a1249be 100644
--- a/kernel/drivers/tty/serial/atmel_serial.c
+++ b/kernel/drivers/tty/serial/atmel_serial.c
@@ -873,11 +873,11 @@
 
 	port->icount.tx += atmel_port->tx_len;
 
-	spin_lock_irq(&atmel_port->lock_tx);
+	spin_lock(&atmel_port->lock_tx);
 	async_tx_ack(atmel_port->desc_tx);
 	atmel_port->cookie_tx = -EINVAL;
 	atmel_port->desc_tx = NULL;
-	spin_unlock_irq(&atmel_port->lock_tx);
+	spin_unlock(&atmel_port->lock_tx);
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 		uart_write_wakeup(port);
@@ -2633,13 +2633,7 @@
 	else if (mr == ATMEL_US_PAR_ODD)
 		*parity = 'o';
 
-	/*
-	 * The serial core only rounds down when matching this to a
-	 * supported baud rate. Make sure we don't end up slightly
-	 * lower than one of those, as it would make us fall through
-	 * to a much lower baud rate than we really want.
-	 */
-	*baud = port->uartclk / (16 * (quot - 1));
+	*baud = port->uartclk / (16 * quot);
 }
 
 static int __init atmel_console_setup(struct console *co, char *options)
diff --git a/kernel/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/kernel/drivers/tty/serial/cpm_uart/cpm_uart_core.c
index 4df47d0..f727222 100644
--- a/kernel/drivers/tty/serial/cpm_uart/cpm_uart_core.c
+++ b/kernel/drivers/tty/serial/cpm_uart/cpm_uart_core.c
@@ -1263,19 +1263,14 @@
 {
 	struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index];
 	unsigned long flags;
-	int nolock = oops_in_progress;
 
-	if (unlikely(nolock)) {
+	if (unlikely(oops_in_progress)) {
 		local_irq_save(flags);
-	} else {
-		spin_lock_irqsave(&pinfo->port.lock, flags);
-	}
-
-	cpm_uart_early_write(pinfo, s, count, true);
-
-	if (unlikely(nolock)) {
+		cpm_uart_early_write(pinfo, s, count, true);
 		local_irq_restore(flags);
 	} else {
+		spin_lock_irqsave(&pinfo->port.lock, flags);
+		cpm_uart_early_write(pinfo, s, count, true);
 		spin_unlock_irqrestore(&pinfo->port.lock, flags);
 	}
 }
diff --git a/kernel/drivers/tty/serial/fsl_lpuart.c b/kernel/drivers/tty/serial/fsl_lpuart.c
index 43aca5a..227fb2d 100644
--- a/kernel/drivers/tty/serial/fsl_lpuart.c
+++ b/kernel/drivers/tty/serial/fsl_lpuart.c
@@ -809,11 +809,17 @@
 			struct lpuart_port, port);
 	unsigned long stat = lpuart32_read(port, UARTSTAT);
 	unsigned long sfifo = lpuart32_read(port, UARTFIFO);
+	unsigned long ctrl = lpuart32_read(port, UARTCTRL);
 
 	if (sport->dma_tx_in_progress)
 		return 0;
 
-	if (stat & UARTSTAT_TC && sfifo & UARTFIFO_TXEMPT)
+	/*
+	 * LPUART Transmission Complete Flag may never be set while queuing a break
+	 * character, so avoid checking for transmission complete when UARTCTRL_SBK
+	 * is asserted.
+	 */
+	if ((stat & UARTSTAT_TC && sfifo & UARTFIFO_TXEMPT) || ctrl & UARTCTRL_SBK)
 		return TIOCSER_TEMT;
 
 	return 0;
@@ -1056,8 +1062,8 @@
 		unsigned long sr = lpuart32_read(&sport->port, UARTSTAT);
 
 		if (sr & (UARTSTAT_PE | UARTSTAT_FE)) {
-			/* Read DR to clear the error flags */
-			lpuart32_read(&sport->port, UARTDATA);
+			/* Clear the error flags */
+			lpuart32_write(&sport->port, sr, UARTSTAT);
 
 			if (sr & UARTSTAT_PE)
 				sport->port.icount.parity++;
@@ -1214,7 +1220,7 @@
 	 * 10ms at any baud rate.
 	 */
 	sport->rx_dma_rng_buf_len = (DMA_RX_TIMEOUT * baud /  bits / 1000) * 2;
-	sport->rx_dma_rng_buf_len = (1 << (fls(sport->rx_dma_rng_buf_len) - 1));
+	sport->rx_dma_rng_buf_len = (1 << fls(sport->rx_dma_rng_buf_len));
 	if (sport->rx_dma_rng_buf_len < 16)
 		sport->rx_dma_rng_buf_len = 16;
 
@@ -1278,6 +1284,7 @@
 	struct dma_chan *chan = sport->dma_rx_chan;
 
 	dmaengine_terminate_all(chan);
+	del_timer_sync(&sport->lpuart_timer);
 	dma_unmap_sg(chan->device->dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE);
 	kfree(sport->rx_ring.buf);
 	sport->rx_ring.tail = 0;
@@ -1450,12 +1457,34 @@
 {
 	unsigned long temp;
 
-	temp = lpuart32_read(port, UARTCTRL) & ~UARTCTRL_SBK;
+	temp = lpuart32_read(port, UARTCTRL);
 
-	if (break_state != 0)
-		temp |= UARTCTRL_SBK;
-
-	lpuart32_write(port, temp, UARTCTRL);
+	/*
+	 * LPUART IP now has two known bugs, one is CTS has higher priority than the
+	 * break signal, which causes the break signal sending through UARTCTRL_SBK
+	 * may impacted by the CTS input if the HW flow control is enabled. It
+	 * exists on all platforms we support in this driver.
+	 * Another bug is i.MX8QM LPUART may have an additional break character
+	 * being sent after SBK was cleared.
+	 * To avoid above two bugs, we use Transmit Data Inversion function to send
+	 * the break signal instead of UARTCTRL_SBK.
+	 */
+	if (break_state != 0) {
+		/*
+		 * Disable the transmitter to prevent any data from being sent out
+		 * during break, then invert the TX line to send break.
+		 */
+		temp &= ~UARTCTRL_TE;
+		lpuart32_write(port, temp, UARTCTRL);
+		temp |= UARTCTRL_TXINV;
+		lpuart32_write(port, temp, UARTCTRL);
+	} else {
+		/* Disable the TXINV to turn off break and re-enable transmitter. */
+		temp &= ~UARTCTRL_TXINV;
+		lpuart32_write(port, temp, UARTCTRL);
+		temp |= UARTCTRL_TE;
+		lpuart32_write(port, temp, UARTCTRL);
+	}
 }
 
 static void lpuart_setup_watermark(struct lpuart_port *sport)
@@ -1723,7 +1752,6 @@
 static void lpuart_dma_shutdown(struct lpuart_port *sport)
 {
 	if (sport->lpuart_dma_rx_use) {
-		del_timer_sync(&sport->lpuart_timer);
 		lpuart_dma_rx_free(&sport->port);
 		sport->lpuart_dma_rx_use = false;
 	}
@@ -1874,10 +1902,8 @@
 	 * Since timer function acqures sport->port.lock, need to stop before
 	 * acquring same lock because otherwise del_timer_sync() can deadlock.
 	 */
-	if (old && sport->lpuart_dma_rx_use) {
-		del_timer_sync(&sport->lpuart_timer);
+	if (old && sport->lpuart_dma_rx_use)
 		lpuart_dma_rx_free(&sport->port);
-	}
 
 	spin_lock_irqsave(&sport->port.lock, flags);
 
@@ -2109,10 +2135,8 @@
 	 * Since timer function acqures sport->port.lock, need to stop before
 	 * acquring same lock because otherwise del_timer_sync() can deadlock.
 	 */
-	if (old && sport->lpuart_dma_rx_use) {
-		del_timer_sync(&sport->lpuart_timer);
+	if (old && sport->lpuart_dma_rx_use)
 		lpuart_dma_rx_free(&sport->port);
-	}
 
 	spin_lock_irqsave(&sport->port.lock, flags);
 
@@ -2139,9 +2163,15 @@
 	/* update the per-port timeout */
 	uart_update_timeout(port, termios->c_cflag, baud);
 
-	/* wait transmit engin complete */
-	lpuart32_write(&sport->port, 0, UARTMODIR);
-	lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC);
+	/*
+	 * LPUART Transmission Complete Flag may never be set while queuing a break
+	 * character, so skip waiting for transmission complete when UARTCTRL_SBK is
+	 * asserted.
+	 */
+	if (!(old_ctrl & UARTCTRL_SBK)) {
+		lpuart32_write(&sport->port, 0, UARTMODIR);
+		lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC);
+	}
 
 	/* disable transmit and receive */
 	lpuart32_write(&sport->port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE),
@@ -2559,6 +2589,7 @@
 OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1021a-lpuart", lpuart32_early_console_setup);
 OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1028a-lpuart", ls1028a_early_console_setup);
 OF_EARLYCON_DECLARE(lpuart32, "fsl,imx7ulp-lpuart", lpuart32_imx_early_console_setup);
+OF_EARLYCON_DECLARE(lpuart32, "fsl,imx8ulp-lpuart", lpuart32_imx_early_console_setup);
 OF_EARLYCON_DECLARE(lpuart32, "fsl,imx8qxp-lpuart", lpuart32_imx_early_console_setup);
 EARLYCON_DECLARE(lpuart, lpuart_early_console_setup);
 EARLYCON_DECLARE(lpuart32, lpuart32_early_console_setup);
@@ -2586,6 +2617,7 @@
 	struct device_node *np = pdev->dev.of_node;
 	struct lpuart_port *sport;
 	struct resource *res;
+	irq_handler_t handler;
 	int ret;
 
 	sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
@@ -2658,16 +2690,11 @@
 
 	if (lpuart_is_32(sport)) {
 		lpuart_reg.cons = LPUART32_CONSOLE;
-		ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart32_int, 0,
-					DRIVER_NAME, sport);
+		handler = lpuart32_int;
 	} else {
 		lpuart_reg.cons = LPUART_CONSOLE;
-		ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart_int, 0,
-					DRIVER_NAME, sport);
+		handler = lpuart_int;
 	}
-
-	if (ret)
-		goto failed_irq_request;
 
 	ret = uart_get_rs485_mode(&sport->port);
 	if (ret)
@@ -2684,11 +2711,17 @@
 	if (ret)
 		goto failed_attach_port;
 
+	ret = devm_request_irq(&pdev->dev, sport->port.irq, handler, 0,
+				DRIVER_NAME, sport);
+	if (ret)
+		goto failed_irq_request;
+
 	return 0;
 
+failed_irq_request:
+	uart_remove_one_port(&lpuart_reg, &sport->port);
 failed_get_rs485:
 failed_attach_port:
-failed_irq_request:
 	lpuart_disable_clks(sport);
 	return ret;
 }
@@ -2738,11 +2771,10 @@
 		 * EDMA driver during suspend will forcefully release any
 		 * non-idle DMA channels. If port wakeup is enabled or if port
 		 * is console port or 'no_console_suspend' is set the Rx DMA
-		 * cannot resume as as expected, hence gracefully release the
+		 * cannot resume as expected, hence gracefully release the
 		 * Rx DMA path before suspend and start Rx DMA path on resume.
 		 */
 		if (irq_wake) {
-			del_timer_sync(&sport->lpuart_timer);
 			lpuart_dma_rx_free(&sport->port);
 		}
 
diff --git a/kernel/drivers/tty/serial/lantiq.c b/kernel/drivers/tty/serial/lantiq.c
index 62813e4..ee5fd4d 100644
--- a/kernel/drivers/tty/serial/lantiq.c
+++ b/kernel/drivers/tty/serial/lantiq.c
@@ -274,6 +274,7 @@
 	struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
 
 	spin_lock_irqsave(&ltq_port->lock, flags);
+	__raw_writel(ASC_IRNCR_EIR, port->membase + LTQ_ASC_IRNCR);
 	/* clear any pending interrupts */
 	asc_update_bits(0, ASCWHBSTATE_CLRPE | ASCWHBSTATE_CLRFE |
 		ASCWHBSTATE_CLRROE, port->membase + LTQ_ASC_WHBSTATE);
diff --git a/kernel/drivers/tty/serial/pch_uart.c b/kernel/drivers/tty/serial/pch_uart.c
index 351ad0b..cb68a10 100644
--- a/kernel/drivers/tty/serial/pch_uart.c
+++ b/kernel/drivers/tty/serial/pch_uart.c
@@ -711,6 +711,7 @@
 	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 @@
 			__func__);
 		dma_release_channel(priv->chan_tx);
 		priv->chan_tx = NULL;
+		pci_dev_put(dma_dev);
 		return;
 	}
 
@@ -734,6 +736,8 @@
 	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)
@@ -765,7 +769,7 @@
 	}
 	xmit->tail &= UART_XMIT_SIZE - 1;
 	async_tx_ack(priv->desc_tx);
-	dma_unmap_sg(port->dev, sg, priv->orig_nent, DMA_TO_DEVICE);
+	dma_unmap_sg(port->dev, priv->sg_tx_p, priv->orig_nent, DMA_TO_DEVICE);
 	priv->tx_dma_use = 0;
 	priv->nent = 0;
 	priv->orig_nent = 0;
diff --git a/kernel/drivers/tty/serial/qcom_geni_serial.c b/kernel/drivers/tty/serial/qcom_geni_serial.c
index 0d85b55..7caba23 100644
--- a/kernel/drivers/tty/serial/qcom_geni_serial.c
+++ b/kernel/drivers/tty/serial/qcom_geni_serial.c
@@ -125,6 +125,7 @@
 	u32 tx_fifo_width;
 	u32 rx_fifo_depth;
 	bool setup;
+	unsigned long clk_rate;
 	int (*handle_rx)(struct uart_port *uport, u32 bytes, bool drop);
 	unsigned int baud;
 	void *rx_fifo;
@@ -866,9 +867,10 @@
 	return IRQ_HANDLED;
 }
 
-static void get_tx_fifo_size(struct qcom_geni_serial_port *port)
+static int setup_fifos(struct qcom_geni_serial_port *port)
 {
 	struct uart_port *uport;
+	u32 old_rx_fifo_depth = port->rx_fifo_depth;
 
 	uport = &port->uport;
 	port->tx_fifo_depth = geni_se_get_tx_fifo_depth(&port->se);
@@ -876,6 +878,16 @@
 	port->rx_fifo_depth = geni_se_get_rx_fifo_depth(&port->se);
 	uport->fifosize =
 		(port->tx_fifo_depth * port->tx_fifo_width) / BITS_PER_BYTE;
+
+	if (port->rx_fifo && (old_rx_fifo_depth != port->rx_fifo_depth) && port->rx_fifo_depth) {
+		port->rx_fifo = devm_krealloc(uport->dev, port->rx_fifo,
+					      port->rx_fifo_depth * sizeof(u32),
+					      GFP_KERNEL);
+		if (!port->rx_fifo)
+			return -ENOMEM;
+	}
+
+	return 0;
 }
 
 
@@ -890,6 +902,7 @@
 	u32 rxstale = DEFAULT_BITS_PER_CHAR * STALE_TIMEOUT;
 	u32 proto;
 	u32 pin_swap;
+	int ret;
 
 	proto = geni_se_read_proto(&port->se);
 	if (proto != GENI_SE_UART) {
@@ -899,7 +912,9 @@
 
 	qcom_geni_serial_stop_rx(uport);
 
-	get_tx_fifo_size(port);
+	ret = setup_fifos(port);
+	if (ret)
+		return ret;
 
 	writel(rxstale, uport->membase + SE_UART_RX_STALE_CNT);
 
@@ -1008,6 +1023,7 @@
 		goto out_restart_rx;
 
 	uport->uartclk = clk_rate;
+	port->clk_rate = clk_rate;
 	dev_pm_opp_set_rate(uport->dev, clk_rate);
 	ser_clk_cfg = SER_CLK_EN;
 	ser_clk_cfg |= clk_div << CLK_DIV_SHFT;
@@ -1291,10 +1307,13 @@
 
 	if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF) {
 		geni_icc_enable(&port->se);
+		if (port->clk_rate)
+			dev_pm_opp_set_rate(uport->dev, port->clk_rate);
 		geni_se_resources_on(&port->se);
 	} else if (new_state == UART_PM_STATE_OFF &&
 			old_state == UART_PM_STATE_ON) {
 		geni_se_resources_off(&port->se);
+		dev_pm_opp_set_rate(uport->dev, 0);
 		geni_icc_disable(&port->se);
 	}
 }
@@ -1453,13 +1472,6 @@
 		uart_remove_one_port(drv, uport);
 		goto err;
 	}
-
-	/*
-	 * Set pm_runtime status as ACTIVE so that wakeup_irq gets
-	 * enabled/disabled from dev_pm_arm_wake_irq during system
-	 * suspend/resume respectively.
-	 */
-	pm_runtime_set_active(&pdev->dev);
 
 	if (port->wakeup_irq > 0) {
 		device_init_wakeup(&pdev->dev, true);
diff --git a/kernel/drivers/tty/serial/samsung_tty.c b/kernel/drivers/tty/serial/samsung_tty.c
index 263c332..fa5b132 100644
--- a/kernel/drivers/tty/serial/samsung_tty.c
+++ b/kernel/drivers/tty/serial/samsung_tty.c
@@ -1313,8 +1313,12 @@
 			continue;
 
 		rate = clk_get_rate(clk);
-		if (!rate)
+		if (!rate) {
+			dev_err(ourport->port.dev,
+				"Failed to get clock rate for %s.\n", clkname);
+			clk_put(clk);
 			continue;
+		}
 
 		if (ourport->info->has_divslot) {
 			unsigned long div = rate / req_baud;
@@ -1340,10 +1344,18 @@
 			calc_deviation = -calc_deviation;
 
 		if (calc_deviation < deviation) {
+			/*
+			 * If we find a better clk, release the previous one, if
+			 * any.
+			 */
+			if (!IS_ERR(*best_clk))
+				clk_put(*best_clk);
 			*best_clk = clk;
 			best_quot = quot;
 			*clk_num = cnt;
 			deviation = calc_deviation;
+		} else {
+			clk_put(clk);
 		}
 	}
 
diff --git a/kernel/drivers/tty/serial/sc16is7xx.c b/kernel/drivers/tty/serial/sc16is7xx.c
index 04b4ed5..c681ed5 100644
--- a/kernel/drivers/tty/serial/sc16is7xx.c
+++ b/kernel/drivers/tty/serial/sc16is7xx.c
@@ -1170,9 +1170,18 @@
 		state |= BIT(offset);
 	else
 		state &= ~BIT(offset);
-	sc16is7xx_port_write(port, SC16IS7XX_IOSTATE_REG, state);
+
+	/*
+	 * If we write IOSTATE first, and then IODIR, the output value is not
+	 * transferred to the corresponding I/O pin.
+	 * The datasheet states that each register bit will be transferred to
+	 * the corresponding I/O pin programmed as output when writing to
+	 * IOSTATE. Therefore, configure direction first with IODIR, and then
+	 * set value after with IOSTATE.
+	 */
 	sc16is7xx_port_update(port, SC16IS7XX_IODIR_REG, BIT(offset),
 			      BIT(offset));
+	sc16is7xx_port_write(port, SC16IS7XX_IOSTATE_REG, state);
 
 	return 0;
 }
@@ -1243,25 +1252,6 @@
 	}
 	sched_set_fifo(s->kworker_task);
 
-#ifdef CONFIG_GPIOLIB
-	if (devtype->nr_gpio) {
-		/* Setup GPIO cotroller */
-		s->gpio.owner		 = THIS_MODULE;
-		s->gpio.parent		 = dev;
-		s->gpio.label		 = dev_name(dev);
-		s->gpio.direction_input	 = sc16is7xx_gpio_direction_input;
-		s->gpio.get		 = sc16is7xx_gpio_get;
-		s->gpio.direction_output = sc16is7xx_gpio_direction_output;
-		s->gpio.set		 = sc16is7xx_gpio_set;
-		s->gpio.base		 = -1;
-		s->gpio.ngpio		 = devtype->nr_gpio;
-		s->gpio.can_sleep	 = 1;
-		ret = gpiochip_add_data(&s->gpio, s);
-		if (ret)
-			goto out_thread;
-	}
-#endif
-
 	/* reset device, purging any pending irq / data */
 	regmap_write(s->regmap, SC16IS7XX_IOCONTROL_REG << SC16IS7XX_REG_SHIFT,
 			SC16IS7XX_IOCONTROL_SRESET_BIT);
@@ -1275,6 +1265,12 @@
 		s->p[i].port.fifosize	= SC16IS7XX_FIFO_SIZE;
 		s->p[i].port.flags	= UPF_FIXED_TYPE | UPF_LOW_LATENCY;
 		s->p[i].port.iobase	= i;
+		/*
+		 * Use all ones as membase to make sure uart_configure_port() in
+		 * serial_core.c does not abort for SPI/I2C devices where the
+		 * membase address is not applicable.
+		 */
+		s->p[i].port.membase	= (void __iomem *)~0;
 		s->p[i].port.iotype	= UPIO_PORT;
 		s->p[i].port.uartclk	= freq;
 		s->p[i].port.rs485_config = sc16is7xx_config_rs485;
@@ -1327,6 +1323,25 @@
 				s->p[u].irda_mode = true;
 	}
 
+#ifdef CONFIG_GPIOLIB
+	if (devtype->nr_gpio) {
+		/* Setup GPIO cotroller */
+		s->gpio.owner		 = THIS_MODULE;
+		s->gpio.parent		 = dev;
+		s->gpio.label		 = dev_name(dev);
+		s->gpio.direction_input	 = sc16is7xx_gpio_direction_input;
+		s->gpio.get		 = sc16is7xx_gpio_get;
+		s->gpio.direction_output = sc16is7xx_gpio_direction_output;
+		s->gpio.set		 = sc16is7xx_gpio_set;
+		s->gpio.base		 = -1;
+		s->gpio.ngpio		 = devtype->nr_gpio;
+		s->gpio.can_sleep	 = 1;
+		ret = gpiochip_add_data(&s->gpio, s);
+		if (ret)
+			goto out_thread;
+	}
+#endif
+
 	/*
 	 * Setup interrupt. We first try to acquire the IRQ line as level IRQ.
 	 * If that succeeds, we can allow sharing the interrupt as well.
@@ -1346,18 +1361,19 @@
 	if (!ret)
 		return 0;
 
-out_ports:
-	for (i--; i >= 0; i--) {
-		uart_remove_one_port(&sc16is7xx_uart, &s->p[i].port);
-		clear_bit(s->p[i].port.line, &sc16is7xx_lines);
-	}
-
 #ifdef CONFIG_GPIOLIB
 	if (devtype->nr_gpio)
 		gpiochip_remove(&s->gpio);
 
 out_thread:
 #endif
+
+out_ports:
+	for (i--; i >= 0; i--) {
+		uart_remove_one_port(&sc16is7xx_uart, &s->p[i].port);
+		clear_bit(s->p[i].port.line, &sc16is7xx_lines);
+	}
+
 	kthread_stop(s->kworker_task);
 
 out_clk:
diff --git a/kernel/drivers/tty/serial/serial-tegra.c b/kernel/drivers/tty/serial/serial-tegra.c
index cda7180..fac4d90 100644
--- a/kernel/drivers/tty/serial/serial-tegra.c
+++ b/kernel/drivers/tty/serial/serial-tegra.c
@@ -614,8 +614,9 @@
 	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 @@
 		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;
@@ -992,7 +994,11 @@
 	tup->ier_shadow = 0;
 	tup->current_baud = 0;
 
-	clk_prepare_enable(tup->uart_clk);
+	ret = clk_prepare_enable(tup->uart_clk);
+	if (ret) {
+		dev_err(tup->uport.dev, "could not enable clk\n");
+		return ret;
+	}
 
 	/* Reset the UART controller to clear all previous status.*/
 	reset_control_assert(tup->rst);
diff --git a/kernel/drivers/tty/serial/serial_core.c b/kernel/drivers/tty/serial/serial_core.c
index d674732..76cdf3f 100644
--- a/kernel/drivers/tty/serial/serial_core.c
+++ b/kernel/drivers/tty/serial/serial_core.c
@@ -2244,7 +2244,8 @@
 
 		spin_lock_irq(&uport->lock);
 		ops->stop_tx(uport);
-		ops->set_mctrl(uport, 0);
+		if (!(uport->rs485.flags & SER_RS485_ENABLED))
+			ops->set_mctrl(uport, 0);
 		ops->stop_rx(uport);
 		spin_unlock_irq(&uport->lock);
 
diff --git a/kernel/drivers/tty/serial/sh-sci.c b/kernel/drivers/tty/serial/sh-sci.c
index 8d92472..a7c2854 100644
--- a/kernel/drivers/tty/serial/sh-sci.c
+++ b/kernel/drivers/tty/serial/sh-sci.c
@@ -31,6 +31,7 @@
 #include <linux/ioport.h>
 #include <linux/ktime.h>
 #include <linux/major.h>
+#include <linux/minmax.h>
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/of.h>
@@ -2923,6 +2924,13 @@
 			sci_port->irqs[i] = platform_get_irq(dev, i);
 	}
 
+	/*
+	 * The fourth interrupt on SCI port is transmit end interrupt, so
+	 * shuffle the interrupts.
+	 */
+	if (p->type == PORT_SCI)
+		swap(sci_port->irqs[SCIx_BRI_IRQ], sci_port->irqs[SCIx_TEI_IRQ]);
+
 	/* The SCI generates several interrupts. They can be muxed together or
 	 * connected to different interrupt lines. In the muxed case only one
 	 * interrupt resource is specified as there is only one interrupt ID.
@@ -2988,7 +2996,7 @@
 	port->flags		= UPF_FIXED_PORT | UPF_BOOT_AUTOCONF | p->flags;
 	port->fifosize		= sci_port->params->fifosize;
 
-	if (port->type == PORT_SCI) {
+	if (port->type == PORT_SCI && !dev->dev.of_node) {
 		if (sci_port->reg_size >= 0x20)
 			port->regshift = 2;
 		else
diff --git a/kernel/drivers/tty/serial/sifive.c b/kernel/drivers/tty/serial/sifive.c
index 91952be..c234114 100644
--- a/kernel/drivers/tty/serial/sifive.c
+++ b/kernel/drivers/tty/serial/sifive.c
@@ -844,7 +844,7 @@
 	local_irq_restore(flags);
 }
 
-static int __init sifive_serial_console_setup(struct console *co, char *options)
+static int sifive_serial_console_setup(struct console *co, char *options)
 {
 	struct sifive_serial_port *ssp;
 	int baud = SIFIVE_DEFAULT_BAUD_RATE;
diff --git a/kernel/drivers/tty/serial/sprd_serial.c b/kernel/drivers/tty/serial/sprd_serial.c
index 9a7ae63..a1952e4 100644
--- a/kernel/drivers/tty/serial/sprd_serial.c
+++ b/kernel/drivers/tty/serial/sprd_serial.c
@@ -367,7 +367,7 @@
 	if (sp->rx_dma.virt)
 		dma_free_coherent(sp->port.dev, SPRD_UART_RX_SIZE,
 				  sp->rx_dma.virt, sp->rx_dma.phys_addr);
-
+	sp->rx_dma.virt = NULL;
 }
 
 static int sprd_rx_dma_config(struct uart_port *port, u32 burst)
@@ -1133,7 +1133,7 @@
 static int sprd_clk_init(struct uart_port *uport)
 {
 	struct clk *clk_uart, *clk_parent;
-	struct sprd_uart_port *u = sprd_port[uport->line];
+	struct sprd_uart_port *u = container_of(uport, struct sprd_uart_port, port);
 
 	clk_uart = devm_clk_get(uport->dev, "uart");
 	if (IS_ERR(clk_uart)) {
@@ -1176,22 +1176,22 @@
 {
 	struct resource *res;
 	struct uart_port *up;
+	struct sprd_uart_port *sport;
 	int irq;
 	int index;
 	int ret;
 
 	index = of_alias_get_id(pdev->dev.of_node, "serial");
-	if (index < 0 || index >= ARRAY_SIZE(sprd_port)) {
+	if (index < 0 || index >= UART_NR_MAX) {
 		dev_err(&pdev->dev, "got a wrong serial alias id %d\n", index);
 		return -EINVAL;
 	}
 
-	sprd_port[index] = devm_kzalloc(&pdev->dev, sizeof(*sprd_port[index]),
-					GFP_KERNEL);
-	if (!sprd_port[index])
+	sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
+	if (!sport)
 		return -ENOMEM;
 
-	up = &sprd_port[index]->port;
+	up = &sport->port;
 	up->dev = &pdev->dev;
 	up->line = index;
 	up->type = PORT_SPRD;
@@ -1222,7 +1222,7 @@
 	 * Allocate one dma buffer to prepare for receive transfer, in case
 	 * memory allocation failure at runtime.
 	 */
-	ret = sprd_rx_alloc_buf(sprd_port[index]);
+	ret = sprd_rx_alloc_buf(sport);
 	if (ret)
 		return ret;
 
@@ -1230,17 +1230,27 @@
 		ret = uart_register_driver(&sprd_uart_driver);
 		if (ret < 0) {
 			pr_err("Failed to register SPRD-UART driver\n");
-			return ret;
+			goto free_rx_buf;
 		}
 	}
+
 	sprd_ports_num++;
+	sprd_port[index] = sport;
 
 	ret = uart_add_one_port(&sprd_uart_driver, up);
 	if (ret)
-		sprd_remove(pdev);
+		goto clean_port;
 
 	platform_set_drvdata(pdev, up);
 
+	return 0;
+
+clean_port:
+	sprd_port[index] = NULL;
+	if (--sprd_ports_num == 0)
+		uart_unregister_driver(&sprd_uart_driver);
+free_rx_buf:
+	sprd_rx_free_buf(sport);
 	return ret;
 }
 
diff --git a/kernel/drivers/tty/serial/sunsab.c b/kernel/drivers/tty/serial/sunsab.c
index bab551f..451c723 100644
--- a/kernel/drivers/tty/serial/sunsab.c
+++ b/kernel/drivers/tty/serial/sunsab.c
@@ -1137,7 +1137,13 @@
 		}
 	}
 
-	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)
diff --git a/kernel/drivers/tty/tty.h b/kernel/drivers/tty/tty.h
new file mode 100644
index 0000000..1908f27
--- /dev/null
+++ b/kernel/drivers/tty/tty.h
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * TTY core internal functions
+ */
+
+#ifndef _TTY_INTERNAL_H
+#define _TTY_INTERNAL_H
+
+#define tty_msg(fn, tty, f, ...) \
+	fn("%s %s: " f, tty_driver_name(tty), tty_name(tty), ##__VA_ARGS__)
+
+#define tty_debug(tty, f, ...)	tty_msg(pr_debug, tty, f, ##__VA_ARGS__)
+#define tty_info(tty, f, ...)	tty_msg(pr_info, tty, f, ##__VA_ARGS__)
+#define tty_notice(tty, f, ...)	tty_msg(pr_notice, tty, f, ##__VA_ARGS__)
+#define tty_warn(tty, f, ...)	tty_msg(pr_warn, tty, f, ##__VA_ARGS__)
+#define tty_err(tty, f, ...)	tty_msg(pr_err, tty, f, ##__VA_ARGS__)
+
+#define tty_info_ratelimited(tty, f, ...) \
+		tty_msg(pr_info_ratelimited, tty, f, ##__VA_ARGS__)
+
+/*
+ * Lock subclasses for tty locks
+ *
+ * TTY_LOCK_NORMAL is for normal ttys and master ptys.
+ * TTY_LOCK_SLAVE is for slave ptys only.
+ *
+ * Lock subclasses are necessary for handling nested locking with pty pairs.
+ * tty locks which use nested locking:
+ *
+ * legacy_mutex - Nested tty locks are necessary for releasing pty pairs.
+ *		  The stable lock order is master pty first, then slave pty.
+ * termios_rwsem - The stable lock order is tty_buffer lock->termios_rwsem.
+ *		   Subclassing this lock enables the slave pty to hold its
+ *		   termios_rwsem when claiming the master tty_buffer lock.
+ * tty_buffer lock - slave ptys can claim nested buffer lock when handling
+ *		     signal chars. The stable lock order is slave pty, then
+ *		     master.
+ */
+enum {
+	TTY_LOCK_NORMAL = 0,
+	TTY_LOCK_SLAVE,
+};
+
+/* Values for tty->flow_change */
+#define TTY_THROTTLE_SAFE	1
+#define TTY_UNTHROTTLE_SAFE	2
+
+static inline void __tty_set_flow_change(struct tty_struct *tty, int val)
+{
+	tty->flow_change = val;
+}
+
+static inline void tty_set_flow_change(struct tty_struct *tty, int val)
+{
+	tty->flow_change = val;
+	smp_mb();
+}
+
+int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout);
+void tty_ldisc_unlock(struct tty_struct *tty);
+
+int __tty_check_change(struct tty_struct *tty, int sig);
+int tty_check_change(struct tty_struct *tty);
+void __stop_tty(struct tty_struct *tty);
+void __start_tty(struct tty_struct *tty);
+void tty_write_unlock(struct tty_struct *tty);
+int tty_write_lock(struct tty_struct *tty, int ndelay);
+void tty_vhangup_session(struct tty_struct *tty);
+void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty);
+int tty_signal_session_leader(struct tty_struct *tty, int exit_session);
+void session_clear_tty(struct pid *session);
+void tty_buffer_free_all(struct tty_port *port);
+void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld);
+void tty_buffer_init(struct tty_port *port);
+void tty_buffer_set_lock_subclass(struct tty_port *port);
+bool tty_buffer_restart_work(struct tty_port *port);
+bool tty_buffer_cancel_work(struct tty_port *port);
+void tty_buffer_flush_work(struct tty_port *port);
+speed_t tty_termios_input_baud_rate(struct ktermios *termios);
+void tty_ldisc_hangup(struct tty_struct *tty, bool reset);
+int tty_ldisc_reinit(struct tty_struct *tty, int disc);
+long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+long tty_jobctrl_ioctl(struct tty_struct *tty, struct tty_struct *real_tty,
+		       struct file *file, unsigned int cmd, unsigned long arg);
+void tty_default_fops(struct file_operations *fops);
+struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx);
+int tty_alloc_file(struct file *file);
+void tty_add_file(struct tty_struct *tty, struct file *file);
+void tty_free_file(struct file *file);
+int tty_release(struct inode *inode, struct file *filp);
+
+#define tty_is_writelocked(tty)  (mutex_is_locked(&tty->atomic_write_lock))
+
+int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty);
+void tty_ldisc_release(struct tty_struct *tty);
+int __must_check tty_ldisc_init(struct tty_struct *tty);
+void tty_ldisc_deinit(struct tty_struct *tty);
+
+void tty_sysctl_init(void);
+
+/* tty_audit.c */
+#ifdef CONFIG_AUDIT
+void tty_audit_add_data(struct tty_struct *tty, const void *data, size_t size);
+void tty_audit_tiocsti(struct tty_struct *tty, char ch);
+#else
+static inline void tty_audit_add_data(struct tty_struct *tty, const void *data,
+				      size_t size)
+{
+}
+static inline void tty_audit_tiocsti(struct tty_struct *tty, char ch)
+{
+}
+#endif
+
+ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *);
+
+#endif
diff --git a/kernel/drivers/tty/tty_audit.c b/kernel/drivers/tty/tty_audit.c
index 9f906a5..9b30ede 100644
--- a/kernel/drivers/tty/tty_audit.c
+++ b/kernel/drivers/tty/tty_audit.c
@@ -10,6 +10,7 @@
 #include <linux/audit.h>
 #include <linux/slab.h>
 #include <linux/tty.h>
+#include "tty.h"
 
 struct tty_audit_buf {
 	struct mutex mutex;	/* Protects all data below */
diff --git a/kernel/drivers/tty/tty_baudrate.c b/kernel/drivers/tty/tty_baudrate.c
index 84fec3c..9d0093d 100644
--- a/kernel/drivers/tty/tty_baudrate.c
+++ b/kernel/drivers/tty/tty_baudrate.c
@@ -8,6 +8,7 @@
 #include <linux/termios.h>
 #include <linux/tty.h>
 #include <linux/export.h>
+#include "tty.h"
 
 
 /*
diff --git a/kernel/drivers/tty/tty_buffer.c b/kernel/drivers/tty/tty_buffer.c
index 5bbc2e0..9f23798 100644
--- a/kernel/drivers/tty/tty_buffer.c
+++ b/kernel/drivers/tty/tty_buffer.c
@@ -17,7 +17,7 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/ratelimit.h>
-
+#include "tty.h"
 
 #define MIN_TTYB_SIZE	256
 #define TTYB_ALIGN_MASK	255
diff --git a/kernel/drivers/tty/tty_io.c b/kernel/drivers/tty/tty_io.c
index 669aef7..094e82a 100644
--- a/kernel/drivers/tty/tty_io.c
+++ b/kernel/drivers/tty/tty_io.c
@@ -108,6 +108,7 @@
 
 #include <linux/kmod.h>
 #include <linux/nsproxy.h>
+#include "tty.h"
 
 #undef TTY_DEBUG_HANGUP
 #ifdef TTY_DEBUG_HANGUP
@@ -941,13 +942,13 @@
 	return i;
 }
 
-static void tty_write_unlock(struct tty_struct *tty)
+void tty_write_unlock(struct tty_struct *tty)
 {
 	mutex_unlock(&tty->atomic_write_lock);
 	wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT);
 }
 
-static int tty_write_lock(struct tty_struct *tty, int ndelay)
+int tty_write_lock(struct tty_struct *tty, int ndelay)
 {
 	if (!mutex_trylock(&tty->atomic_write_lock)) {
 		if (ndelay)
@@ -1237,14 +1238,16 @@
 {
 	struct tty_struct *tty;
 
-	if (driver->ops->lookup)
+	if (driver->ops->lookup) {
 		if (!file)
 			tty = ERR_PTR(-EIO);
 		else
 			tty = driver->ops->lookup(driver, file, idx);
-	else
+	} else {
+		if (idx >= driver->num)
+			return ERR_PTR(-EINVAL);
 		tty = driver->ttys[idx];
-
+	}
 	if (!IS_ERR(tty))
 		tty_kref_get(tty);
 	return tty;
diff --git a/kernel/drivers/tty/tty_ioctl.c b/kernel/drivers/tty/tty_ioctl.c
index 803da2d..68b0725 100644
--- a/kernel/drivers/tty/tty_ioctl.c
+++ b/kernel/drivers/tty/tty_ioctl.c
@@ -21,6 +21,7 @@
 #include <linux/bitops.h>
 #include <linux/mutex.h>
 #include <linux/compat.h>
+#include "tty.h"
 
 #include <asm/io.h>
 #include <linux/uaccess.h>
@@ -397,21 +398,42 @@
 	tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
 	tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
 
-	ld = tty_ldisc_ref(tty);
+	if (opt & (TERMIOS_FLUSH|TERMIOS_WAIT)) {
+retry_write_wait:
+		retval = wait_event_interruptible(tty->write_wait, !tty_chars_in_buffer(tty));
+		if (retval < 0)
+			return retval;
 
-	if (ld != NULL) {
-		if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
-			ld->ops->flush_buffer(tty);
-		tty_ldisc_deref(ld);
+		if (tty_write_lock(tty, 0) < 0)
+			goto retry_write_wait;
+
+		/* Racing writer? */
+		if (tty_chars_in_buffer(tty)) {
+			tty_write_unlock(tty);
+			goto retry_write_wait;
+		}
+
+		ld = tty_ldisc_ref(tty);
+		if (ld != NULL) {
+			if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
+				ld->ops->flush_buffer(tty);
+			tty_ldisc_deref(ld);
+		}
+
+		if ((opt & TERMIOS_WAIT) && tty->ops->wait_until_sent) {
+			tty->ops->wait_until_sent(tty, 0);
+			if (signal_pending(current)) {
+				tty_write_unlock(tty);
+				return -ERESTARTSYS;
+			}
+		}
+
+		tty_set_termios(tty, &tmp_termios);
+
+		tty_write_unlock(tty);
+	} else {
+		tty_set_termios(tty, &tmp_termios);
 	}
-
-	if (opt & TERMIOS_WAIT) {
-		tty_wait_until_sent(tty, 0);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-	}
-
-	tty_set_termios(tty, &tmp_termios);
 
 	/* FIXME: Arguably if tmp_termios == tty->termios AND the
 	   actual requested termios was not tmp_termios then we may
diff --git a/kernel/drivers/tty/tty_jobctrl.c b/kernel/drivers/tty/tty_jobctrl.c
index aa6d053..95d6761 100644
--- a/kernel/drivers/tty/tty_jobctrl.c
+++ b/kernel/drivers/tty/tty_jobctrl.c
@@ -11,6 +11,7 @@
 #include <linux/tty.h>
 #include <linux/fcntl.h>
 #include <linux/uaccess.h>
+#include "tty.h"
 
 static int is_ignored(int sig)
 {
diff --git a/kernel/drivers/tty/tty_ldisc.c b/kernel/drivers/tty/tty_ldisc.c
index fe37ec3..c23938b 100644
--- a/kernel/drivers/tty/tty_ldisc.c
+++ b/kernel/drivers/tty/tty_ldisc.c
@@ -19,6 +19,7 @@
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
 #include <linux/ratelimit.h>
+#include "tty.h"
 
 #undef LDISC_DEBUG_HANGUP
 
diff --git a/kernel/drivers/tty/tty_mutex.c b/kernel/drivers/tty/tty_mutex.c
index 2640635..393518a 100644
--- a/kernel/drivers/tty/tty_mutex.c
+++ b/kernel/drivers/tty/tty_mutex.c
@@ -4,6 +4,7 @@
 #include <linux/kallsyms.h>
 #include <linux/semaphore.h>
 #include <linux/sched.h>
+#include "tty.h"
 
 /* Legacy tty mutex glue */
 
diff --git a/kernel/drivers/tty/tty_port.c b/kernel/drivers/tty/tty_port.c
index ea80bf8..cbb56f7 100644
--- a/kernel/drivers/tty/tty_port.c
+++ b/kernel/drivers/tty/tty_port.c
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/serdev.h>
+#include "tty.h"
 
 static int tty_port_default_receive_buf(struct tty_port *port,
 					const unsigned char *p,
diff --git a/kernel/drivers/tty/vt/vc_screen.c b/kernel/drivers/tty/vt/vc_screen.c
index 1850bac..01c9653 100644
--- a/kernel/drivers/tty/vt/vc_screen.c
+++ b/kernel/drivers/tty/vt/vc_screen.c
@@ -386,10 +386,6 @@
 
 	uni_mode = use_unicode(inode);
 	attr = use_attributes(inode);
-	ret = -ENXIO;
-	vc = vcs_vc(inode, &viewed);
-	if (!vc)
-		goto unlock_out;
 
 	ret = -EINVAL;
 	if (pos < 0)
@@ -407,16 +403,20 @@
 		unsigned int this_round, skip = 0;
 		int size;
 
+		vc = vcs_vc(inode, &viewed);
+		if (!vc) {
+			ret = -ENXIO;
+			break;
+		}
+
 		/* Check whether we are above size each round,
 		 * as copy_to_user at the end of this loop
 		 * could sleep.
 		 */
 		size = vcs_size(vc, attr, uni_mode);
 		if (size < 0) {
-			if (read)
-				break;
 			ret = size;
-			goto unlock_out;
+			break;
 		}
 		if (pos >= size)
 			break;
@@ -656,10 +656,17 @@
 			}
 		}
 
-		/* The vcs_size might have changed while we slept to grab
-		 * the user buffer, so recheck.
+		/* The vc might have been freed or vcs_size might have changed
+		 * while we slept to grab the user buffer, so recheck.
 		 * Return data written up to now on failure.
 		 */
+		vc = vcs_vc(inode, &viewed);
+		if (!vc) {
+			if (written)
+				break;
+			ret = -ENXIO;
+			goto unlock_out;
+		}
 		size = vcs_size(vc, attr, false);
 		if (size < 0) {
 			if (written)
diff --git a/kernel/drivers/uio/uio_dmem_genirq.c b/kernel/drivers/uio/uio_dmem_genirq.c
index ec7f66f..9275173 100644
--- a/kernel/drivers/uio/uio_dmem_genirq.c
+++ b/kernel/drivers/uio/uio_dmem_genirq.c
@@ -110,8 +110,10 @@
 	 * 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,20 +127,19 @@
 	 * 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);
 	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;
 }
diff --git a/kernel/drivers/usb/cdns3/cdns3-pci-wrap.c b/kernel/drivers/usb/cdns3/cdns3-pci-wrap.c
index deeea61..1f6320d 100644
--- a/kernel/drivers/usb/cdns3/cdns3-pci-wrap.c
+++ b/kernel/drivers/usb/cdns3/cdns3-pci-wrap.c
@@ -60,6 +60,11 @@
 			return NULL;
 	}
 
+	if (func->devfn != PCI_DEV_FN_HOST_DEVICE &&
+	    func->devfn != PCI_DEV_FN_OTG) {
+		return NULL;
+	}
+
 	return func;
 }
 
diff --git a/kernel/drivers/usb/cdns3/gadget.c b/kernel/drivers/usb/cdns3/gadget.c
index e3a8b6c..210c1d6 100644
--- a/kernel/drivers/usb/cdns3/gadget.c
+++ b/kernel/drivers/usb/cdns3/gadget.c
@@ -2041,7 +2041,7 @@
 	u8 mult = 0;
 	int ret;
 
-	buffering = CDNS3_EP_BUF_SIZE - 1;
+	buffering = priv_dev->ep_buf_size - 1;
 
 	cdns3_configure_dmult(priv_dev, priv_ep);
 
@@ -2060,7 +2060,7 @@
 		break;
 	default:
 		ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_ISOC);
-		mult = CDNS3_EP_ISO_HS_MULT - 1;
+		mult = priv_dev->ep_iso_burst - 1;
 		buffering = mult + 1;
 	}
 
@@ -2076,14 +2076,14 @@
 		mult = 0;
 		max_packet_size = 1024;
 		if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) {
-			maxburst = CDNS3_EP_ISO_SS_BURST - 1;
+			maxburst = priv_dev->ep_iso_burst - 1;
 			buffering = (mult + 1) *
 				    (maxburst + 1);
 
 			if (priv_ep->interval > 1)
 				buffering++;
 		} else {
-			maxburst = CDNS3_EP_BUF_SIZE - 1;
+			maxburst = priv_dev->ep_buf_size - 1;
 		}
 		break;
 	default:
@@ -2097,6 +2097,23 @@
 		priv_ep->trb_burst_size = 64;
 	else
 		priv_ep->trb_burst_size = 16;
+
+	/*
+	 * In versions preceding DEV_VER_V2, for example, iMX8QM, there exit the bugs
+	 * in the DMA. These bugs occur when the trb_burst_size exceeds 16 and the
+	 * address is not aligned to 128 Bytes (which is a product of the 64-bit AXI
+	 * and AXI maximum burst length of 16 or 0xF+1, dma_axi_ctrl0[3:0]). This
+	 * results in data corruption when it crosses the 4K border. The corruption
+	 * specifically occurs from the position (4K - (address & 0x7F)) to 4K.
+	 *
+	 * So force trb_burst_size to 16 at such platform.
+	 */
+	if (priv_dev->dev_ver < DEV_VER_V2)
+		priv_ep->trb_burst_size = 16;
+
+	mult = min_t(u8, mult, EP_CFG_MULT_MAX);
+	buffering = min_t(u8, buffering, EP_CFG_BUFFERING_MAX);
+	maxburst = min_t(u8, maxburst, EP_CFG_MAXBURST_MAX);
 
 	/* onchip buffer is only allocated before configuration */
 	if (!priv_dev->hw_configured_flag) {
@@ -2971,6 +2988,40 @@
 	return 0;
 }
 
+/**
+ * cdns3_gadget_check_config - ensure cdns3 can support the USB configuration
+ * @gadget: pointer to the USB gadget
+ *
+ * Used to record the maximum number of endpoints being used in a USB composite
+ * device. (across all configurations)  This is to be used in the calculation
+ * of the TXFIFO sizes when resizing internal memory for individual endpoints.
+ * It will help ensured that the resizing logic reserves enough space for at
+ * least one max packet.
+ */
+static int cdns3_gadget_check_config(struct usb_gadget *gadget)
+{
+	struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget);
+	struct usb_ep *ep;
+	int n_in = 0;
+	int total;
+
+	list_for_each_entry(ep, &gadget->ep_list, ep_list) {
+		if (ep->claimed && (ep->address & USB_DIR_IN))
+			n_in++;
+	}
+
+	/* 2KB are reserved for EP0, 1KB for out*/
+	total = 2 + n_in + 1;
+
+	if (total > priv_dev->onchip_buffers)
+		return -ENOMEM;
+
+	priv_dev->ep_buf_size = priv_dev->ep_iso_burst =
+			(priv_dev->onchip_buffers - 2) / (n_in + 1);
+
+	return 0;
+}
+
 static const struct usb_gadget_ops cdns3_gadget_ops = {
 	.get_frame = cdns3_gadget_get_frame,
 	.wakeup = cdns3_gadget_wakeup,
@@ -2979,6 +3030,7 @@
 	.udc_start = cdns3_gadget_udc_start,
 	.udc_stop = cdns3_gadget_udc_stop,
 	.match_ep = cdns3_gadget_match_ep,
+	.check_config = cdns3_gadget_check_config,
 };
 
 static void cdns3_free_all_eps(struct cdns3_device *priv_dev)
diff --git a/kernel/drivers/usb/cdns3/gadget.h b/kernel/drivers/usb/cdns3/gadget.h
index 21fa461..3282547 100644
--- a/kernel/drivers/usb/cdns3/gadget.h
+++ b/kernel/drivers/usb/cdns3/gadget.h
@@ -561,15 +561,18 @@
 /* Max burst size (used only in SS mode). */
 #define EP_CFG_MAXBURST_MASK	GENMASK(11, 8)
 #define EP_CFG_MAXBURST(p)	(((p) << 8) & EP_CFG_MAXBURST_MASK)
+#define EP_CFG_MAXBURST_MAX	15
 /* ISO max burst. */
 #define EP_CFG_MULT_MASK	GENMASK(15, 14)
 #define EP_CFG_MULT(p)		(((p) << 14) & EP_CFG_MULT_MASK)
+#define EP_CFG_MULT_MAX		2
 /* ISO max burst. */
 #define EP_CFG_MAXPKTSIZE_MASK	GENMASK(26, 16)
 #define EP_CFG_MAXPKTSIZE(p)	(((p) << 16) & EP_CFG_MAXPKTSIZE_MASK)
 /* Max number of buffered packets. */
 #define EP_CFG_BUFFERING_MASK	GENMASK(31, 27)
 #define EP_CFG_BUFFERING(p)	(((p) << 27) & EP_CFG_BUFFERING_MASK)
+#define EP_CFG_BUFFERING_MAX	15
 
 /* EP_CMD - bitmasks */
 /* Endpoint reset. */
@@ -1093,9 +1096,6 @@
 #define CDNS3_ENDPOINTS_MAX_COUNT	32
 #define CDNS3_EP_ZLP_BUF_SIZE		1024
 
-#define CDNS3_EP_BUF_SIZE		4	/* KB */
-#define CDNS3_EP_ISO_HS_MULT		3
-#define CDNS3_EP_ISO_SS_BURST		3
 #define CDNS3_MAX_NUM_DESCMISS_BUF	32
 #define CDNS3_DESCMIS_BUF_SIZE		2048	/* Bytes */
 #define CDNS3_WA2_NUM_BUFFERS		128
@@ -1330,6 +1330,9 @@
 	/*in KB */
 	u16				onchip_buffers;
 	u16				onchip_used_size;
+
+	u16				ep_buf_size;
+	u16				ep_iso_burst;
 };
 
 void cdns3_set_register_bit(void __iomem *ptr, u32 mask);
diff --git a/kernel/drivers/usb/chipidea/ci.h b/kernel/drivers/usb/chipidea/ci.h
index 0697eb9..7b00b93 100644
--- a/kernel/drivers/usb/chipidea/ci.h
+++ b/kernel/drivers/usb/chipidea/ci.h
@@ -204,6 +204,7 @@
  * @in_lpm: if the core in low power mode
  * @wakeup_int: if wakeup interrupt occur
  * @rev: The revision number for controller
+ * @mutex: protect code from concorrent running when doing role switch
  */
 struct ci_hdrc {
 	struct device			*dev;
@@ -257,6 +258,7 @@
 	bool				in_lpm;
 	bool				wakeup_int;
 	enum ci_revision		rev;
+	struct mutex                    mutex;
 };
 
 static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
diff --git a/kernel/drivers/usb/chipidea/ci_hdrc_imx.c b/kernel/drivers/usb/chipidea/ci_hdrc_imx.c
index f798455..a54c3cf 100644
--- a/kernel/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/kernel/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -70,6 +70,10 @@
 		CI_HDRC_PMQOS,
 };
 
+static const struct ci_hdrc_imx_platform_flag imx8ulp_usb_data = {
+	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
+};
+
 static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
 	{ .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
 	{ .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
@@ -80,6 +84,7 @@
 	{ .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data},
 	{ .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
 	{ .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data},
+	{ .compatible = "fsl,imx8ulp-usb", .data = &imx8ulp_usb_data},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
@@ -170,10 +175,12 @@
 	if (of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI)
 		data->ulpi = 1;
 
-	of_property_read_u32(np, "samsung,picophy-pre-emp-curr-control",
-			&data->emp_curr_control);
-	of_property_read_u32(np, "samsung,picophy-dc-vol-level-adjust",
-			&data->dc_vol_level_adjust);
+	if (of_property_read_u32(np, "samsung,picophy-pre-emp-curr-control",
+			&data->emp_curr_control))
+		data->emp_curr_control = -1;
+	if (of_property_read_u32(np, "samsung,picophy-dc-vol-level-adjust",
+			&data->dc_vol_level_adjust))
+		data->dc_vol_level_adjust = -1;
 
 	return data;
 }
diff --git a/kernel/drivers/usb/chipidea/core.c b/kernel/drivers/usb/chipidea/core.c
index 127b1a6..3d18599 100644
--- a/kernel/drivers/usb/chipidea/core.c
+++ b/kernel/drivers/usb/chipidea/core.c
@@ -966,8 +966,15 @@
 			     strlen(ci->roles[role]->name)))
 			break;
 
-	if (role == CI_ROLE_END || role == ci->role)
+	if (role == CI_ROLE_END)
 		return -EINVAL;
+
+	mutex_lock(&ci->mutex);
+
+	if (role == ci->role) {
+		mutex_unlock(&ci->mutex);
+		return n;
+	}
 
 	pm_runtime_get_sync(dev);
 	disable_irq(ci->irq);
@@ -977,6 +984,7 @@
 		ci_handle_vbus_change(ci);
 	enable_irq(ci->irq);
 	pm_runtime_put_sync(dev);
+	mutex_unlock(&ci->mutex);
 
 	return (ret == 0) ? n : ret;
 }
@@ -1012,6 +1020,7 @@
 		return -ENOMEM;
 
 	spin_lock_init(&ci->lock);
+	mutex_init(&ci->mutex);
 	ci->dev = dev;
 	ci->platdata = dev_get_platdata(dev);
 	ci->imx28_write_fix = !!(ci->platdata->flags &
@@ -1081,7 +1090,7 @@
 	ret = ci_usb_phy_init(ci);
 	if (ret) {
 		dev_err(dev, "unable to init phy: %d\n", ret);
-		return ret;
+		goto ulpi_exit;
 	}
 
 	ci->hw_bank.phys = res->start;
diff --git a/kernel/drivers/usb/chipidea/otg.c b/kernel/drivers/usb/chipidea/otg.c
index d3aada3..9a12868 100644
--- a/kernel/drivers/usb/chipidea/otg.c
+++ b/kernel/drivers/usb/chipidea/otg.c
@@ -166,8 +166,10 @@
 
 static void ci_handle_id_switch(struct ci_hdrc *ci)
 {
-	enum ci_role role = ci_otg_role(ci);
+	enum ci_role role;
 
+	mutex_lock(&ci->mutex);
+	role = ci_otg_role(ci);
 	if (role != ci->role) {
 		dev_dbg(ci->dev, "switching from %s to %s\n",
 			ci_role(ci)->name, ci->roles[role]->name);
@@ -197,6 +199,7 @@
 		if (role == CI_ROLE_GADGET)
 			ci_handle_vbus_change(ci);
 	}
+	mutex_unlock(&ci->mutex);
 }
 /**
  * ci_otg_work - perform otg (vbus/id) event handle
diff --git a/kernel/drivers/usb/chipidea/usbmisc_imx.c b/kernel/drivers/usb/chipidea/usbmisc_imx.c
index 425b291..12fc8c8 100644
--- a/kernel/drivers/usb/chipidea/usbmisc_imx.c
+++ b/kernel/drivers/usb/chipidea/usbmisc_imx.c
@@ -135,7 +135,7 @@
 #define TXVREFTUNE0_MASK		(0xf << 20)
 
 #define MX6_USB_OTG_WAKEUP_BITS (MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP | \
-				 MX6_BM_ID_WAKEUP)
+				 MX6_BM_ID_WAKEUP | MX6SX_BM_DPDM_WAKEUP_EN)
 
 struct usbmisc_ops {
 	/* It's called once when probe a usb device */
@@ -657,13 +657,15 @@
 			usbmisc->base + MX7D_USBNC_USB_CTRL2);
 		/* PHY tuning for signal quality */
 		reg = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG1);
-		if (data->emp_curr_control && data->emp_curr_control <=
+		if (data->emp_curr_control >= 0 &&
+			data->emp_curr_control <=
 			(TXPREEMPAMPTUNE0_MASK >> TXPREEMPAMPTUNE0_BIT)) {
 			reg &= ~TXPREEMPAMPTUNE0_MASK;
 			reg |= (data->emp_curr_control << TXPREEMPAMPTUNE0_BIT);
 		}
 
-		if (data->dc_vol_level_adjust && data->dc_vol_level_adjust <=
+		if (data->dc_vol_level_adjust >= 0 &&
+			data->dc_vol_level_adjust <=
 			(TXVREFTUNE0_MASK >> TXVREFTUNE0_BIT)) {
 			reg &= ~TXVREFTUNE0_MASK;
 			reg |= (data->dc_vol_level_adjust << TXVREFTUNE0_BIT);
diff --git a/kernel/drivers/usb/class/usbtmc.c b/kernel/drivers/usb/class/usbtmc.c
index 49f59d5..76ff182 100644
--- a/kernel/drivers/usb/class/usbtmc.c
+++ b/kernel/drivers/usb/class/usbtmc.c
@@ -1898,6 +1898,8 @@
 
 	if (request.req.wLength > USBTMC_BUFSIZE)
 		return -EMSGSIZE;
+	if (request.req.wLength == 0)	/* Length-0 requests are never IN */
+		request.req.bRequestType &= ~USB_DIR_IN;
 
 	is_in = request.req.bRequestType & USB_DIR_IN;
 
diff --git a/kernel/drivers/usb/common/usb-conn-gpio.c b/kernel/drivers/usb/common/usb-conn-gpio.c
index 068cd2c..9d281f2 100644
--- a/kernel/drivers/usb/common/usb-conn-gpio.c
+++ b/kernel/drivers/usb/common/usb-conn-gpio.c
@@ -42,6 +42,7 @@
 
 	struct power_supply_desc desc;
 	struct power_supply *charger;
+	bool initial_detection;
 };
 
 /*
@@ -86,10 +87,12 @@
 	dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n",
 		info->last_role, role, id, vbus);
 
-	if (info->last_role == role) {
+	if (!info->initial_detection && info->last_role == role) {
 		dev_warn(info->dev, "repeated role: %d\n", role);
 		return;
 	}
+
+	info->initial_detection = false;
 
 	if (info->last_role == USB_ROLE_HOST && info->vbus)
 		regulator_disable(info->vbus);
@@ -278,6 +281,7 @@
 	device_set_wakeup_capable(&pdev->dev, true);
 
 	/* Perform initial detection */
+	info->initial_detection = true;
 	usb_conn_queue_dwork(info, 0);
 
 	return 0;
diff --git a/kernel/drivers/usb/core/buffer.c b/kernel/drivers/usb/core/buffer.c
index 6cf22c2..be87387 100644
--- a/kernel/drivers/usb/core/buffer.c
+++ b/kernel/drivers/usb/core/buffer.c
@@ -170,3 +170,44 @@
 	}
 	dma_free_coherent(hcd->self.sysdev, size, addr, dma);
 }
+
+void *hcd_buffer_alloc_pages(struct usb_hcd *hcd,
+		size_t size, gfp_t mem_flags, dma_addr_t *dma)
+{
+	if (size == 0)
+		return NULL;
+
+	if (hcd->localmem_pool)
+		return gen_pool_dma_alloc_align(hcd->localmem_pool,
+				size, dma, PAGE_SIZE);
+
+	/* some USB hosts just use PIO */
+	if (!hcd_uses_dma(hcd)) {
+		*dma = DMA_MAPPING_ERROR;
+		return (void *)__get_free_pages(mem_flags,
+				get_order(size));
+	}
+
+	return dma_alloc_coherent(hcd->self.sysdev,
+			size, dma, mem_flags);
+}
+
+void hcd_buffer_free_pages(struct usb_hcd *hcd,
+		size_t size, void *addr, dma_addr_t dma)
+{
+	if (!addr)
+		return;
+
+	if (hcd->localmem_pool) {
+		gen_pool_free(hcd->localmem_pool,
+				(unsigned long)addr, size);
+		return;
+	}
+
+	if (!hcd_uses_dma(hcd)) {
+		free_pages((unsigned long)addr, get_order(size));
+		return;
+	}
+
+	dma_free_coherent(hcd->self.sysdev, size, addr, dma);
+}
diff --git a/kernel/drivers/usb/core/devio.c b/kernel/drivers/usb/core/devio.c
index 73b60f0..1b95035 100644
--- a/kernel/drivers/usb/core/devio.c
+++ b/kernel/drivers/usb/core/devio.c
@@ -173,6 +173,7 @@
 static void dec_usb_memory_use_count(struct usb_memory *usbm, int *count)
 {
 	struct usb_dev_state *ps = usbm->ps;
+	struct usb_hcd *hcd = bus_to_hcd(ps->dev->bus);
 	unsigned long flags;
 
 	spin_lock_irqsave(&ps->lock, flags);
@@ -181,8 +182,8 @@
 		list_del(&usbm->memlist);
 		spin_unlock_irqrestore(&ps->lock, flags);
 
-		usb_free_coherent(ps->dev, usbm->size, usbm->mem,
-				usbm->dma_handle);
+		hcd_buffer_free_pages(hcd, usbm->size,
+				usbm->mem, usbm->dma_handle);
 		usbfs_decrease_memory_usage(
 			usbm->size + sizeof(struct usb_memory));
 		kfree(usbm);
@@ -221,7 +222,7 @@
 	size_t size = vma->vm_end - vma->vm_start;
 	void *mem;
 	unsigned long flags;
-	dma_addr_t dma_handle;
+	dma_addr_t dma_handle = DMA_MAPPING_ERROR;
 	int ret;
 
 	ret = usbfs_increase_memory_usage(size + sizeof(struct usb_memory));
@@ -234,8 +235,8 @@
 		goto error_decrease_mem;
 	}
 
-	mem = usb_alloc_coherent(ps->dev, size, GFP_USER | __GFP_NOWARN,
-			&dma_handle);
+	mem = hcd_buffer_alloc_pages(hcd,
+			size, GFP_USER | __GFP_NOWARN, &dma_handle);
 	if (!mem) {
 		ret = -ENOMEM;
 		goto error_free_usbm;
@@ -251,7 +252,14 @@
 	usbm->vma_use_count = 1;
 	INIT_LIST_HEAD(&usbm->memlist);
 
-	if (hcd->localmem_pool || !hcd_uses_dma(hcd)) {
+	/*
+	 * In DMA-unavailable cases, hcd_buffer_alloc_pages allocates
+	 * normal pages and assigns DMA_MAPPING_ERROR to dma_handle. Check
+	 * whether we are in such cases, and then use remap_pfn_range (or
+	 * dma_mmap_coherent) to map normal (or DMA) pages into the user
+	 * space, respectively.
+	 */
+	if (dma_handle == DMA_MAPPING_ERROR) {
 		if (remap_pfn_range(vma, vma->vm_start,
 				    virt_to_phys(usbm->mem) >> PAGE_SHIFT,
 				    size, vma->vm_page_prot) < 0) {
@@ -726,6 +734,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_PM
 /* The following routines apply to the entire device, not interfaces */
 void usbfs_notify_suspend(struct usb_device *udev)
 {
@@ -744,6 +753,7 @@
 	}
 	mutex_unlock(&usbfs_mutex);
 }
+#endif
 
 struct usb_driver usbfs_driver = {
 	.name =		"usbfs",
diff --git a/kernel/drivers/usb/core/hcd.c b/kernel/drivers/usb/core/hcd.c
index bf5e376..1c754aa 100644
--- a/kernel/drivers/usb/core/hcd.c
+++ b/kernel/drivers/usb/core/hcd.c
@@ -982,6 +982,7 @@
 {
 	struct device *parent_dev = hcd->self.controller;
 	struct usb_device *usb_dev = hcd->self.root_hub;
+	struct usb_device_descriptor *descr;
 	const int devnum = 1;
 	int retval;
 
@@ -993,13 +994,16 @@
 	mutex_lock(&usb_bus_idr_lock);
 
 	usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
-	retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
-	if (retval != sizeof usb_dev->descriptor) {
+	descr = usb_get_device_descriptor(usb_dev);
+	if (IS_ERR(descr)) {
+		retval = PTR_ERR(descr);
 		mutex_unlock(&usb_bus_idr_lock);
 		dev_dbg (parent_dev, "can't read %s device descriptor %d\n",
 				dev_name(&usb_dev->dev), retval);
-		return (retval < 0) ? retval : -EMSGSIZE;
+		return retval;
 	}
+	usb_dev->descriptor = *descr;
+	kfree(descr);
 
 	if (le16_to_cpu(usb_dev->descriptor.bcdUSB) >= 0x0201) {
 		retval = usb_get_bos_descriptor(usb_dev);
diff --git a/kernel/drivers/usb/core/hub.c b/kernel/drivers/usb/core/hub.c
index b397f14..37f4225 100644
--- a/kernel/drivers/usb/core/hub.c
+++ b/kernel/drivers/usb/core/hub.c
@@ -42,6 +42,9 @@
 #define USB_PRODUCT_USB5534B			0x5534
 #define USB_VENDOR_CYPRESS			0x04b4
 #define USB_PRODUCT_CY7C65632			0x6570
+#define USB_VENDOR_TEXAS_INSTRUMENTS		0x0451
+#define USB_PRODUCT_TUSB8041_USB3		0x8140
+#define USB_PRODUCT_TUSB8041_USB2		0x8142
 #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND	0x01
 #define HUB_QUIRK_DISABLE_AUTOSUSPEND		0x02
 
@@ -2378,9 +2381,8 @@
  * usb_enumerate_device - Read device configs/intfs/otg (usbcore-internal)
  * @udev: newly addressed device (in ADDRESS state)
  *
- * This is only called by usb_new_device() and usb_authorize_device()
- * and FIXME -- all comments that apply to them apply here wrt to
- * environment.
+ * This is only called by usb_new_device() -- all comments that apply there
+ * apply here wrt to environment.
  *
  * If the device is WUSB and not authorized, we don't attempt to read
  * the string descriptors, as they will be errored out by the device
@@ -2645,12 +2647,17 @@
 	}
 
 	if (usb_dev->wusb) {
-		result = usb_get_device_descriptor(usb_dev, sizeof(usb_dev->descriptor));
-		if (result < 0) {
+		struct usb_device_descriptor *descr;
+
+		descr = usb_get_device_descriptor(usb_dev);
+		if (IS_ERR(descr)) {
+			result = PTR_ERR(descr);
 			dev_err(&usb_dev->dev, "can't re-read device descriptor for "
 				"authorization: %d\n", result);
 			goto error_device_descriptor;
 		}
+		usb_dev->descriptor = *descr;
+		kfree(descr);
 	}
 
 	usb_dev->authorized = 1;
@@ -4593,6 +4600,67 @@
 	return hcd->driver->enable_device(hcd, udev);
 }
 
+/*
+ * Get the bMaxPacketSize0 value during initialization by reading the
+ * device's device descriptor.  Since we don't already know this value,
+ * the transfer is unsafe and it ignores I/O errors, only testing for
+ * reasonable received values.
+ *
+ * For "old scheme" initialization, size will be 8 so we read just the
+ * start of the device descriptor, which should work okay regardless of
+ * the actual bMaxPacketSize0 value.  For "new scheme" initialization,
+ * size will be 64 (and buf will point to a sufficiently large buffer),
+ * which might not be kosher according to the USB spec but it's what
+ * Windows does and what many devices expect.
+ *
+ * Returns: bMaxPacketSize0 or a negative error code.
+ */
+static int get_bMaxPacketSize0(struct usb_device *udev,
+		struct usb_device_descriptor *buf, int size, bool first_time)
+{
+	int i, rc;
+
+	/*
+	 * Retry on all errors; some devices are flakey.
+	 * 255 is for WUSB devices, we actually need to use
+	 * 512 (WUSB1.0[4.8.1]).
+	 */
+	for (i = 0; i < GET_MAXPACKET0_TRIES; ++i) {
+		/* Start with invalid values in case the transfer fails */
+		buf->bDescriptorType = buf->bMaxPacketSize0 = 0;
+		rc = usb_control_msg(udev, usb_rcvaddr0pipe(),
+				USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+				USB_DT_DEVICE << 8, 0,
+				buf, size,
+				initial_descriptor_timeout);
+		switch (buf->bMaxPacketSize0) {
+		case 8: case 16: case 32: case 64: case 9:
+			if (buf->bDescriptorType == USB_DT_DEVICE) {
+				rc = buf->bMaxPacketSize0;
+				break;
+			}
+			fallthrough;
+		default:
+			if (rc >= 0)
+				rc = -EPROTO;
+			break;
+		}
+
+		/*
+		 * Some devices time out if they are powered on
+		 * when already connected. They need a second
+		 * reset, so return early. But only on the first
+		 * attempt, lest we get into a time-out/reset loop.
+		 */
+		if (rc > 0 || (rc == -ETIMEDOUT && first_time &&
+				udev->speed > USB_SPEED_FULL))
+			break;
+	}
+	return rc;
+}
+
+#define GET_DESCRIPTOR_BUFSIZE	64
+
 /* Reset device, (re)assign address, get device descriptor.
  * Device connection must be stable, no more debouncing needed.
  * Returns device in USB_STATE_ADDRESS, except on error.
@@ -4602,10 +4670,17 @@
  * the port lock.  For a newly detected device that is not accessible
  * through any global pointers, it's not necessary to lock the device,
  * but it is still necessary to lock the port.
+ *
+ * For a newly detected device, @dev_descr must be NULL.  The device
+ * descriptor retrieved from the device will then be stored in
+ * @udev->descriptor.  For an already existing device, @dev_descr
+ * must be non-NULL.  The device descriptor will be stored there,
+ * not in @udev->descriptor, because descriptors for registered
+ * devices are meant to be immutable.
  */
 static int
 hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
-		int retry_counter)
+		int retry_counter, struct usb_device_descriptor *dev_descr)
 {
 	struct usb_device	*hdev = hub->hdev;
 	struct usb_hcd		*hcd = bus_to_hcd(hdev->bus);
@@ -4617,6 +4692,13 @@
 	int			devnum = udev->devnum;
 	const char		*driver_name;
 	bool			do_new_scheme;
+	const bool		initial = !dev_descr;
+	int			maxp0;
+	struct usb_device_descriptor	*buf, *descr;
+
+	buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO);
+	if (!buf)
+		return -ENOMEM;
 
 	/* root hub ports have a slightly longer reset period
 	 * (from USB 2.0 spec, section 7.1.7.5)
@@ -4649,32 +4731,34 @@
 	}
 	oldspeed = udev->speed;
 
-	/* USB 2.0 section 5.5.3 talks about ep0 maxpacket ...
-	 * it's fixed size except for full speed devices.
-	 * For Wireless USB devices, ep0 max packet is always 512 (tho
-	 * reported as 0xff in the device descriptor). WUSB1.0[4.8.1].
-	 */
-	switch (udev->speed) {
-	case USB_SPEED_SUPER_PLUS:
-	case USB_SPEED_SUPER:
-	case USB_SPEED_WIRELESS:	/* fixed at 512 */
-		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
-		break;
-	case USB_SPEED_HIGH:		/* fixed at 64 */
-		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
-		break;
-	case USB_SPEED_FULL:		/* 8, 16, 32, or 64 */
-		/* to determine the ep0 maxpacket size, try to read
-		 * the device descriptor to get bMaxPacketSize0 and
-		 * then correct our initial guess.
+	if (initial) {
+		/* USB 2.0 section 5.5.3 talks about ep0 maxpacket ...
+		 * it's fixed size except for full speed devices.
+		 * For Wireless USB devices, ep0 max packet is always 512 (tho
+		 * reported as 0xff in the device descriptor). WUSB1.0[4.8.1].
 		 */
-		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
-		break;
-	case USB_SPEED_LOW:		/* fixed at 8 */
-		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8);
-		break;
-	default:
-		goto fail;
+		switch (udev->speed) {
+		case USB_SPEED_SUPER_PLUS:
+		case USB_SPEED_SUPER:
+		case USB_SPEED_WIRELESS:	/* fixed at 512 */
+			udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
+			break;
+		case USB_SPEED_HIGH:		/* fixed at 64 */
+			udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
+			break;
+		case USB_SPEED_FULL:		/* 8, 16, 32, or 64 */
+			/* to determine the ep0 maxpacket size, try to read
+			 * the device descriptor to get bMaxPacketSize0 and
+			 * then correct our initial guess.
+			 */
+			udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
+			break;
+		case USB_SPEED_LOW:		/* fixed at 8 */
+			udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8);
+			break;
+		default:
+			goto fail;
+		}
 	}
 
 	if (udev->speed == USB_SPEED_WIRELESS)
@@ -4697,22 +4781,24 @@
 	if (udev->speed < USB_SPEED_SUPER)
 		dev_info(&udev->dev,
 				"%s %s USB device number %d using %s\n",
-				(udev->config) ? "reset" : "new", speed,
+				(initial ? "new" : "reset"), speed,
 				devnum, driver_name);
 
-	/* Set up TT records, if needed  */
-	if (hdev->tt) {
-		udev->tt = hdev->tt;
-		udev->ttport = hdev->ttport;
-	} else if (udev->speed != USB_SPEED_HIGH
-			&& hdev->speed == USB_SPEED_HIGH) {
-		if (!hub->tt.hub) {
-			dev_err(&udev->dev, "parent hub has no TT\n");
-			retval = -EINVAL;
-			goto fail;
+	if (initial) {
+		/* Set up TT records, if needed  */
+		if (hdev->tt) {
+			udev->tt = hdev->tt;
+			udev->ttport = hdev->ttport;
+		} else if (udev->speed != USB_SPEED_HIGH
+				&& hdev->speed == USB_SPEED_HIGH) {
+			if (!hub->tt.hub) {
+				dev_err(&udev->dev, "parent hub has no TT\n");
+				retval = -EINVAL;
+				goto fail;
+			}
+			udev->tt = &hub->tt;
+			udev->ttport = port1;
 		}
-		udev->tt = &hub->tt;
-		udev->ttport = port1;
 	}
 
 	/* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
@@ -4731,9 +4817,6 @@
 
 	for (retries = 0; retries < GET_DESCRIPTOR_TRIES; (++retries, msleep(100))) {
 		if (do_new_scheme) {
-			struct usb_device_descriptor *buf;
-			int r = 0;
-
 			retval = hub_enable_device(udev);
 			if (retval < 0) {
 				dev_err(&udev->dev,
@@ -4742,52 +4825,14 @@
 				goto fail;
 			}
 
-#define GET_DESCRIPTOR_BUFSIZE	64
-			buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO);
-			if (!buf) {
-				retval = -ENOMEM;
-				continue;
+			maxp0 = get_bMaxPacketSize0(udev, buf,
+					GET_DESCRIPTOR_BUFSIZE, retries == 0);
+			if (maxp0 > 0 && !initial &&
+					maxp0 != udev->descriptor.bMaxPacketSize0) {
+				dev_err(&udev->dev, "device reset changed ep0 maxpacket size!\n");
+				retval = -ENODEV;
+				goto fail;
 			}
-
-			/* Retry on all errors; some devices are flakey.
-			 * 255 is for WUSB devices, we actually need to use
-			 * 512 (WUSB1.0[4.8.1]).
-			 */
-			for (operations = 0; operations < GET_MAXPACKET0_TRIES;
-					++operations) {
-				buf->bMaxPacketSize0 = 0;
-				r = usb_control_msg(udev, usb_rcvaddr0pipe(),
-					USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
-					USB_DT_DEVICE << 8, 0,
-					buf, GET_DESCRIPTOR_BUFSIZE,
-					initial_descriptor_timeout);
-				switch (buf->bMaxPacketSize0) {
-				case 8: case 16: case 32: case 64: case 255:
-					if (buf->bDescriptorType ==
-							USB_DT_DEVICE) {
-						r = 0;
-						break;
-					}
-					fallthrough;
-				default:
-					if (r == 0)
-						r = -EPROTO;
-					break;
-				}
-				/*
-				 * Some devices time out if they are powered on
-				 * when already connected. They need a second
-				 * reset. But only on the first attempt,
-				 * lest we get into a time out/reset loop
-				 */
-				if (r == 0 || (r == -ETIMEDOUT &&
-						retries == 0 &&
-						udev->speed > USB_SPEED_FULL))
-					break;
-			}
-			udev->descriptor.bMaxPacketSize0 =
-					buf->bMaxPacketSize0;
-			kfree(buf);
 
 			retval = hub_port_reset(hub, port1, udev, delay, false);
 			if (retval < 0)		/* error or disconnect */
@@ -4798,14 +4843,13 @@
 				retval = -ENODEV;
 				goto fail;
 			}
-			if (r) {
-				if (r != -ENODEV)
+			if (maxp0 < 0) {
+				if (maxp0 != -ENODEV)
 					dev_err(&udev->dev, "device descriptor read/64, error %d\n",
-							r);
-				retval = -EMSGSIZE;
+							maxp0);
+				retval = maxp0;
 				continue;
 			}
-#undef GET_DESCRIPTOR_BUFSIZE
 		}
 
 		/*
@@ -4847,18 +4891,22 @@
 				break;
 		}
 
-		retval = usb_get_device_descriptor(udev, 8);
-		if (retval < 8) {
+		/* !do_new_scheme || wusb */
+		maxp0 = get_bMaxPacketSize0(udev, buf, 8, retries == 0);
+		if (maxp0 < 0) {
+			retval = maxp0;
 			if (retval != -ENODEV)
 				dev_err(&udev->dev,
 					"device descriptor read/8, error %d\n",
 					retval);
-			if (retval >= 0)
-				retval = -EMSGSIZE;
 		} else {
 			u32 delay;
 
-			retval = 0;
+			if (!initial && maxp0 != udev->descriptor.bMaxPacketSize0) {
+				dev_err(&udev->dev, "device reset changed ep0 maxpacket size!\n");
+				retval = -ENODEV;
+				goto fail;
+			}
 
 			delay = udev->parent->hub_delay;
 			udev->hub_delay = min_t(u32, delay,
@@ -4877,6 +4925,51 @@
 		goto fail;
 
 	/*
+	 * Check the ep0 maxpacket guess and correct it if necessary.
+	 * maxp0 is the value stored in the device descriptor;
+	 * i is the value it encodes (logarithmic for SuperSpeed or greater).
+	 */
+	i = maxp0;
+	if (udev->speed >= USB_SPEED_SUPER) {
+		if (maxp0 <= 16)
+			i = 1 << maxp0;
+		else
+			i = 0;		/* Invalid */
+	}
+	if (usb_endpoint_maxp(&udev->ep0.desc) == i) {
+		;	/* Initial ep0 maxpacket guess is right */
+	} else if ((udev->speed == USB_SPEED_FULL ||
+				udev->speed == USB_SPEED_HIGH) &&
+			(i == 8 || i == 16 || i == 32 || i == 64)) {
+		/* Initial guess is wrong; use the descriptor's value */
+		if (udev->speed == USB_SPEED_FULL)
+			dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
+		else
+			dev_warn(&udev->dev, "Using ep0 maxpacket: %d\n", i);
+		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);
+		usb_ep0_reinit(udev);
+	} else {
+		/* Initial guess is wrong and descriptor's value is invalid */
+		dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", maxp0);
+		retval = -EMSGSIZE;
+		goto fail;
+	}
+
+	descr = usb_get_device_descriptor(udev);
+	if (IS_ERR(descr)) {
+		retval = PTR_ERR(descr);
+		if (retval != -ENODEV)
+			dev_err(&udev->dev, "device descriptor read/all, error %d\n",
+					retval);
+		goto fail;
+	}
+	if (initial)
+		udev->descriptor = *descr;
+	else
+		*dev_descr = *descr;
+	kfree(descr);
+
+	/*
 	 * Some superspeed devices have finished the link training process
 	 * and attached to a superspeed hub port, but the device descriptor
 	 * got from those devices show they aren't superspeed devices. Warm
@@ -4884,41 +4977,9 @@
 	 */
 	if ((udev->speed >= USB_SPEED_SUPER) &&
 			(le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) {
-		dev_err(&udev->dev, "got a wrong device descriptor, "
-				"warm reset device\n");
-		hub_port_reset(hub, port1, udev,
-				HUB_BH_RESET_TIME, true);
+		dev_err(&udev->dev, "got a wrong device descriptor, warm reset device\n");
+		hub_port_reset(hub, port1, udev, HUB_BH_RESET_TIME, true);
 		retval = -EINVAL;
-		goto fail;
-	}
-
-	if (udev->descriptor.bMaxPacketSize0 == 0xff ||
-			udev->speed >= USB_SPEED_SUPER)
-		i = 512;
-	else
-		i = udev->descriptor.bMaxPacketSize0;
-	if (usb_endpoint_maxp(&udev->ep0.desc) != i) {
-		if (udev->speed == USB_SPEED_LOW ||
-				!(i == 8 || i == 16 || i == 32 || i == 64)) {
-			dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i);
-			retval = -EMSGSIZE;
-			goto fail;
-		}
-		if (udev->speed == USB_SPEED_FULL)
-			dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
-		else
-			dev_warn(&udev->dev, "Using ep0 maxpacket: %d\n", i);
-		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);
-		usb_ep0_reinit(udev);
-	}
-
-	retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);
-	if (retval < (signed)sizeof(udev->descriptor)) {
-		if (retval != -ENODEV)
-			dev_err(&udev->dev, "device descriptor read/all, error %d\n",
-					retval);
-		if (retval >= 0)
-			retval = -ENOMSG;
 		goto fail;
 	}
 
@@ -4942,6 +5003,7 @@
 		hub_port_disable(hub, port1, 0);
 		update_devnum(udev, devnum);	/* for disconnect processing */
 	}
+	kfree(buf);
 	return retval;
 }
 
@@ -5022,7 +5084,7 @@
 
 
 static int descriptors_changed(struct usb_device *udev,
-		struct usb_device_descriptor *old_device_descriptor,
+		struct usb_device_descriptor *new_device_descriptor,
 		struct usb_host_bos *old_bos)
 {
 	int		changed = 0;
@@ -5033,8 +5095,8 @@
 	int		length;
 	char		*buf;
 
-	if (memcmp(&udev->descriptor, old_device_descriptor,
-			sizeof(*old_device_descriptor)) != 0)
+	if (memcmp(&udev->descriptor, new_device_descriptor,
+			sizeof(*new_device_descriptor)) != 0)
 		return 1;
 
 	if ((old_bos && !udev->bos) || (!old_bos && udev->bos))
@@ -5207,7 +5269,7 @@
 		}
 
 		/* reset (non-USB 3.0 devices) and get descriptor */
-		status = hub_port_init(hub, udev, port1, i);
+		status = hub_port_init(hub, udev, port1, i, NULL);
 		if (status < 0)
 			goto loop;
 
@@ -5355,9 +5417,8 @@
 {
 	struct usb_port *port_dev = hub->ports[port1 - 1];
 	struct usb_device *udev = port_dev->child;
-	struct usb_device_descriptor descriptor;
+	struct usb_device_descriptor *descr;
 	int status = -ENODEV;
-	int retval;
 
 	dev_dbg(&port_dev->dev, "status %04x, change %04x, %s\n", portstatus,
 			portchange, portspeed(hub, portstatus));
@@ -5384,23 +5445,20 @@
 			 * changed device descriptors before resuscitating the
 			 * device.
 			 */
-			descriptor = udev->descriptor;
-			retval = usb_get_device_descriptor(udev,
-					sizeof(udev->descriptor));
-			if (retval < 0) {
+			descr = usb_get_device_descriptor(udev);
+			if (IS_ERR(descr)) {
 				dev_dbg(&udev->dev,
-						"can't read device descriptor %d\n",
-						retval);
+						"can't read device descriptor %ld\n",
+						PTR_ERR(descr));
 			} else {
-				if (descriptors_changed(udev, &descriptor,
+				if (descriptors_changed(udev, descr,
 						udev->bos)) {
 					dev_dbg(&udev->dev,
 							"device descriptor has changed\n");
-					/* for disconnect() calls */
-					udev->descriptor = descriptor;
 				} else {
 					status = 0; /* Nothing to do */
 				}
+				kfree(descr);
 			}
 #ifdef CONFIG_PM
 		} else if (udev->state == USB_STATE_SUSPENDED &&
@@ -5717,6 +5775,16 @@
       .idVendor = USB_VENDOR_GENESYS_LOGIC,
       .bInterfaceClass = USB_CLASS_HUB,
       .driver_info = HUB_QUIRK_CHECK_PORT_AUTOSUSPEND},
+    { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+			| USB_DEVICE_ID_MATCH_PRODUCT,
+      .idVendor = USB_VENDOR_TEXAS_INSTRUMENTS,
+      .idProduct = USB_PRODUCT_TUSB8041_USB2,
+      .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND},
+    { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+			| USB_DEVICE_ID_MATCH_PRODUCT,
+      .idVendor = USB_VENDOR_TEXAS_INSTRUMENTS,
+      .idProduct = USB_PRODUCT_TUSB8041_USB3,
+      .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND},
     { .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS,
       .bDeviceClass = USB_CLASS_HUB},
     { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
@@ -5818,7 +5886,7 @@
 	struct usb_device		*parent_hdev = udev->parent;
 	struct usb_hub			*parent_hub;
 	struct usb_hcd			*hcd = bus_to_hcd(udev->bus);
-	struct usb_device_descriptor	descriptor = udev->descriptor;
+	struct usb_device_descriptor	descriptor;
 	struct usb_host_bos		*bos;
 	int				i, j, ret = 0;
 	int				port1 = udev->portnum;
@@ -5860,7 +5928,7 @@
 		/* ep0 maxpacket size may change; let the HCD know about it.
 		 * Other endpoints will be handled by re-enumeration. */
 		usb_ep0_reinit(udev);
-		ret = hub_port_init(parent_hub, udev, port1, i);
+		ret = hub_port_init(parent_hub, udev, port1, i, &descriptor);
 		if (ret >= 0 || ret == -ENOTCONN || ret == -ENODEV)
 			break;
 	}
@@ -5872,7 +5940,6 @@
 	/* Device might have changed firmware (DFU or similar) */
 	if (descriptors_changed(udev, &descriptor, bos)) {
 		dev_info(&udev->dev, "device firmware changed\n");
-		udev->descriptor = descriptor;	/* for disconnect() calls */
 		goto re_enumerate;
 	}
 
diff --git a/kernel/drivers/usb/core/message.c b/kernel/drivers/usb/core/message.c
index dba2bac..d64aaff 100644
--- a/kernel/drivers/usb/core/message.c
+++ b/kernel/drivers/usb/core/message.c
@@ -1039,39 +1039,34 @@
 }
 
 /*
- * usb_get_device_descriptor - (re)reads the device descriptor (usbcore)
- * @dev: the device whose device descriptor is being updated
- * @size: how much of the descriptor to read
+ * usb_get_device_descriptor - read the device descriptor
+ * @udev: the device whose device descriptor should be read
  * Context: !in_interrupt ()
- *
- * Updates the copy of the device descriptor stored in the device structure,
- * which dedicates space for this purpose.
  *
  * Not exported, only for use by the core.  If drivers really want to read
  * the device descriptor directly, they can call usb_get_descriptor() with
  * type = USB_DT_DEVICE and index = 0.
  *
- * This call is synchronous, and may not be used in an interrupt context.
- *
- * Return: The number of bytes received on success, or else the status code
- * returned by the underlying usb_control_msg() call.
+ * Returns: a pointer to a dynamically allocated usb_device_descriptor
+ * structure (which the caller must deallocate), or an ERR_PTR value.
  */
-int usb_get_device_descriptor(struct usb_device *dev, unsigned int size)
+struct usb_device_descriptor *usb_get_device_descriptor(struct usb_device *udev)
 {
 	struct usb_device_descriptor *desc;
 	int ret;
 
-	if (size > sizeof(*desc))
-		return -EINVAL;
 	desc = kmalloc(sizeof(*desc), GFP_NOIO);
 	if (!desc)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
-	ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size);
+	ret = usb_get_descriptor(udev, USB_DT_DEVICE, 0, desc, sizeof(*desc));
+	if (ret == sizeof(*desc))
+		return desc;
+
 	if (ret >= 0)
-		memcpy(&dev->descriptor, desc, size);
+		ret = -EMSGSIZE;
 	kfree(desc);
-	return ret;
+	return ERR_PTR(ret);
 }
 
 /*
diff --git a/kernel/drivers/usb/core/quirks.c b/kernel/drivers/usb/core/quirks.c
index 8510a7d..20337c0 100644
--- a/kernel/drivers/usb/core/quirks.c
+++ b/kernel/drivers/usb/core/quirks.c
@@ -446,6 +446,10 @@
 	/* novation SoundControl XL */
 	{ USB_DEVICE(0x1235, 0x0061), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* Focusrite Scarlett Solo USB */
+	{ USB_DEVICE(0x1235, 0x8211), .driver_info =
+			USB_QUIRK_DISCONNECT_SUSPEND },
+
 	/* Huawei 4G LTE module */
 	{ USB_DEVICE(0x12d1, 0x15bb), .driver_info =
 			USB_QUIRK_DISCONNECT_SUSPEND },
@@ -539,6 +543,9 @@
 	/* DJI CineSSD */
 	{ USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM },
 
+	/* Alcor Link AK9563 SC Reader used in 2022 Lenovo ThinkPads */
+	{ USB_DEVICE(0x2ce3, 0x9563), .driver_info = USB_QUIRK_NO_LPM },
+
 	/* DELL USB GEN2 */
 	{ USB_DEVICE(0x413c, 0xb062), .driver_info = USB_QUIRK_NO_LPM | USB_QUIRK_RESET_RESUME },
 
diff --git a/kernel/drivers/usb/core/sysfs.c b/kernel/drivers/usb/core/sysfs.c
index 8d13419..a2ca38e 100644
--- a/kernel/drivers/usb/core/sysfs.c
+++ b/kernel/drivers/usb/core/sysfs.c
@@ -889,11 +889,7 @@
 	size_t srclen, n;
 	int cfgno;
 	void *src;
-	int retval;
 
-	retval = usb_lock_device_interruptible(udev);
-	if (retval < 0)
-		return -EINTR;
 	/* The binary attribute begins with the device descriptor.
 	 * Following that are the raw descriptor entries for all the
 	 * configurations (config plus subsidiary descriptors).
@@ -918,7 +914,6 @@
 			off -= srclen;
 		}
 	}
-	usb_unlock_device(udev);
 	return count - nleft;
 }
 
diff --git a/kernel/drivers/usb/core/usb-acpi.c b/kernel/drivers/usb/core/usb-acpi.c
index 50b2fc7..8751276 100644
--- a/kernel/drivers/usb/core/usb-acpi.c
+++ b/kernel/drivers/usb/core/usb-acpi.c
@@ -37,6 +37,71 @@
 }
 EXPORT_SYMBOL_GPL(usb_acpi_power_manageable);
 
+#define UUID_USB_CONTROLLER_DSM "ce2ee385-00e6-48cb-9f05-2edb927c4899"
+#define USB_DSM_DISABLE_U1_U2_FOR_PORT	5
+
+/**
+ * usb_acpi_port_lpm_incapable - check if lpm should be disabled for a port.
+ * @hdev: USB device belonging to the usb hub
+ * @index: zero based port index
+ *
+ * Some USB3 ports may not support USB3 link power management U1/U2 states
+ * due to different retimer setup. ACPI provides _DSM method which returns 0x01
+ * if U1 and U2 states should be disabled. Evaluate _DSM with:
+ * Arg0: UUID = ce2ee385-00e6-48cb-9f05-2edb927c4899
+ * Arg1: Revision ID = 0
+ * Arg2: Function Index = 5
+ * Arg3: (empty)
+ *
+ * Return 1 if USB3 port is LPM incapable, negative on error, otherwise 0
+ */
+
+int usb_acpi_port_lpm_incapable(struct usb_device *hdev, int index)
+{
+	union acpi_object *obj;
+	acpi_handle port_handle;
+	int port1 = index + 1;
+	guid_t guid;
+	int ret;
+
+	ret = guid_parse(UUID_USB_CONTROLLER_DSM, &guid);
+	if (ret)
+		return ret;
+
+	port_handle = usb_get_hub_port_acpi_handle(hdev, port1);
+	if (!port_handle) {
+		dev_dbg(&hdev->dev, "port-%d no acpi handle\n", port1);
+		return -ENODEV;
+	}
+
+	if (!acpi_check_dsm(port_handle, &guid, 0,
+			    BIT(USB_DSM_DISABLE_U1_U2_FOR_PORT))) {
+		dev_dbg(&hdev->dev, "port-%d no _DSM function %d\n",
+			port1, USB_DSM_DISABLE_U1_U2_FOR_PORT);
+		return -ENODEV;
+	}
+
+	obj = acpi_evaluate_dsm(port_handle, &guid, 0,
+				USB_DSM_DISABLE_U1_U2_FOR_PORT, NULL);
+
+	if (!obj)
+		return -ENODEV;
+
+	if (obj->type != ACPI_TYPE_INTEGER) {
+		dev_dbg(&hdev->dev, "evaluate port-%d _DSM failed\n", port1);
+		ACPI_FREE(obj);
+		return -EINVAL;
+	}
+
+	if (obj->integer.value == 0x01)
+		ret = 1;
+
+	ACPI_FREE(obj);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(usb_acpi_port_lpm_incapable);
+
 /**
  * usb_acpi_set_power_state - control usb port's power via acpi power
  * resource
diff --git a/kernel/drivers/usb/core/usb.c b/kernel/drivers/usb/core/usb.c
index db4de53..c4cd9d4 100644
--- a/kernel/drivers/usb/core/usb.c
+++ b/kernel/drivers/usb/core/usb.c
@@ -208,6 +208,82 @@
 EXPORT_SYMBOL_GPL(usb_find_common_endpoints_reverse);
 
 /**
+ * usb_find_endpoint() - Given an endpoint address, search for the endpoint's
+ * usb_host_endpoint structure in an interface's current altsetting.
+ * @intf: the interface whose current altsetting should be searched
+ * @ep_addr: the endpoint address (number and direction) to find
+ *
+ * Search the altsetting's list of endpoints for one with the specified address.
+ *
+ * Return: Pointer to the usb_host_endpoint if found, %NULL otherwise.
+ */
+static const struct usb_host_endpoint *usb_find_endpoint(
+		const struct usb_interface *intf, unsigned int ep_addr)
+{
+	int n;
+	const struct usb_host_endpoint *ep;
+
+	n = intf->cur_altsetting->desc.bNumEndpoints;
+	ep = intf->cur_altsetting->endpoint;
+	for (; n > 0; (--n, ++ep)) {
+		if (ep->desc.bEndpointAddress == ep_addr)
+			return ep;
+	}
+	return NULL;
+}
+
+/**
+ * usb_check_bulk_endpoints - Check whether an interface's current altsetting
+ * contains a set of bulk endpoints with the given addresses.
+ * @intf: the interface whose current altsetting should be searched
+ * @ep_addrs: 0-terminated array of the endpoint addresses (number and
+ * direction) to look for
+ *
+ * Search for endpoints with the specified addresses and check their types.
+ *
+ * Return: %true if all the endpoints are found and are bulk, %false otherwise.
+ */
+bool usb_check_bulk_endpoints(
+		const struct usb_interface *intf, const u8 *ep_addrs)
+{
+	const struct usb_host_endpoint *ep;
+
+	for (; *ep_addrs; ++ep_addrs) {
+		ep = usb_find_endpoint(intf, *ep_addrs);
+		if (!ep || !usb_endpoint_xfer_bulk(&ep->desc))
+			return false;
+	}
+	return true;
+}
+EXPORT_SYMBOL_GPL(usb_check_bulk_endpoints);
+
+/**
+ * usb_check_int_endpoints - Check whether an interface's current altsetting
+ * contains a set of interrupt endpoints with the given addresses.
+ * @intf: the interface whose current altsetting should be searched
+ * @ep_addrs: 0-terminated array of the endpoint addresses (number and
+ * direction) to look for
+ *
+ * Search for endpoints with the specified addresses and check their types.
+ *
+ * Return: %true if all the endpoints are found and are interrupt,
+ * %false otherwise.
+ */
+bool usb_check_int_endpoints(
+		const struct usb_interface *intf, const u8 *ep_addrs)
+{
+	const struct usb_host_endpoint *ep;
+
+	for (; *ep_addrs; ++ep_addrs) {
+		ep = usb_find_endpoint(intf, *ep_addrs);
+		if (!ep || !usb_endpoint_xfer_int(&ep->desc))
+			return false;
+	}
+	return true;
+}
+EXPORT_SYMBOL_GPL(usb_check_int_endpoints);
+
+/**
  * usb_find_alt_setting() - Given a configuration, find the alternate setting
  * for the given interface.
  * @config: the configuration to search (not necessarily the current config).
diff --git a/kernel/drivers/usb/core/usb.h b/kernel/drivers/usb/core/usb.h
index 82538da..3bb2e1d 100644
--- a/kernel/drivers/usb/core/usb.h
+++ b/kernel/drivers/usb/core/usb.h
@@ -42,8 +42,8 @@
 		struct usb_endpoint_descriptor *epd);
 extern int usb_remove_device(struct usb_device *udev);
 
-extern int usb_get_device_descriptor(struct usb_device *dev,
-		unsigned int size);
+extern struct usb_device_descriptor *usb_get_device_descriptor(
+		struct usb_device *udev);
 extern int usb_set_isoch_delay(struct usb_device *dev);
 extern int usb_get_bos_descriptor(struct usb_device *dev);
 extern void usb_release_bos_descriptor(struct usb_device *dev);
diff --git a/kernel/drivers/usb/dwc2/platform.c b/kernel/drivers/usb/dwc2/platform.c
index 297a11f..13f305b 100644
--- a/kernel/drivers/usb/dwc2/platform.c
+++ b/kernel/drivers/usb/dwc2/platform.c
@@ -121,13 +121,6 @@
 	return 0;
 }
 
-static void __dwc2_disable_regulators(void *data)
-{
-	struct dwc2_hsotg *hsotg = data;
-
-	regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
-}
-
 static int __dwc2_lowlevel_phy_enable(struct dwc2_hsotg *hsotg)
 {
 	struct platform_device *pdev = to_platform_device(hsotg->dev);
@@ -198,16 +191,10 @@
 
 static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
 {
-	struct platform_device *pdev = to_platform_device(hsotg->dev);
 	int ret;
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
 				    hsotg->supplies);
-	if (ret)
-		return ret;
-
-	ret = devm_add_action_or_reset(&pdev->dev,
-				       __dwc2_disable_regulators, hsotg);
 	if (ret)
 		return ret;
 
@@ -249,7 +236,7 @@
 
 	clk_bulk_disable_unprepare(hsotg->num_clks, hsotg->clks);
 
-	return 0;
+	return regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
 }
 
 /**
@@ -699,7 +686,7 @@
 error:
 	pm_runtime_put_sync(hsotg->dev);
 	pm_runtime_disable(hsotg->dev);
-	if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL)
+	if (hsotg->ll_hw_enabled)
 		dwc2_lowlevel_hw_disable(hsotg);
 	return retval;
 }
diff --git a/kernel/drivers/usb/dwc3/core.c b/kernel/drivers/usb/dwc3/core.c
index 20a7bc7..44a6f11 100644
--- a/kernel/drivers/usb/dwc3/core.c
+++ b/kernel/drivers/usb/dwc3/core.c
@@ -121,8 +121,12 @@
 	int ret;
 	int retries = 1000;
 	u32 reg;
+	u32 desired_dr_role;
 
 	mutex_lock(&dwc->mutex);
+	spin_lock_irqsave(&dwc->lock, flags);
+	desired_dr_role = dwc->desired_dr_role;
+	spin_unlock_irqrestore(&dwc->lock, flags);
 
 	pm_runtime_get_sync(dwc->dev);
 
@@ -141,13 +145,13 @@
 	if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG)
 		dwc3_otg_update(dwc, 0);
 
-	if (!dwc->desired_dr_role)
+	if (!desired_dr_role)
 		goto out;
 
-	if (dwc->desired_dr_role == dwc->current_dr_role)
+	if (desired_dr_role == dwc->current_dr_role)
 		goto out;
 
-	if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev)
+	if (desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev)
 		goto out;
 
 	switch (dwc->current_dr_role) {
@@ -175,7 +179,7 @@
 	 */
 	if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
 			DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
-			dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
+			desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
 		reg = dwc3_readl(dwc->regs, DWC3_GCTL);
 		reg |= DWC3_GCTL_CORESOFTRESET;
 		dwc3_writel(dwc->regs, DWC3_GCTL, reg);
@@ -195,11 +199,11 @@
 
 	spin_lock_irqsave(&dwc->lock, flags);
 
-	dwc3_set_prtcap(dwc, dwc->desired_dr_role);
+	dwc3_set_prtcap(dwc, desired_dr_role);
 
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
-	switch (dwc->desired_dr_role) {
+	switch (desired_dr_role) {
 	case DWC3_GCTL_PRTCAP_HOST:
 		ret = dwc3_host_init(dwc);
 		if (ret) {
@@ -303,9 +307,9 @@
 	/*
 	 * We're resetting only the device side because, if we're in host mode,
 	 * XHCI driver will reset the host block. If dwc3 was configured for
-	 * host-only mode, then we can return early.
+	 * host-only mode or current role is host, then we can return early.
 	 */
-	if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST)
+	if (dwc->dr_mode == USB_DR_MODE_HOST || dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST)
 		return 0;
 
 	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
@@ -992,8 +996,13 @@
 
 	if (!dwc->ulpi_ready) {
 		ret = dwc3_core_ulpi_init(dwc);
-		if (ret)
+		if (ret) {
+			if (ret == -ETIMEDOUT) {
+				dwc3_core_soft_reset(dwc);
+				ret = -EPROBE_DEFER;
+			}
 			goto err0;
+		}
 		dwc->ulpi_ready = true;
 	}
 
@@ -1104,27 +1113,12 @@
 			reg |= DWC3_GUCTL1_PARKMODE_DISABLE_HS;
 #endif
 
-		if (dwc->maximum_speed == USB_SPEED_HIGH ||
-		    dwc->maximum_speed == USB_SPEED_FULL)
+		if (DWC3_VER_IS_WITHIN(DWC3, 290A, ANY) &&
+		    (dwc->maximum_speed == USB_SPEED_HIGH ||
+		     dwc->maximum_speed == USB_SPEED_FULL))
 			reg |= DWC3_GUCTL1_DEV_FORCE_20_CLK_FOR_30_CLK;
 
 		dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
-	}
-
-	if (dwc->dr_mode == USB_DR_MODE_HOST ||
-	    dwc->dr_mode == USB_DR_MODE_OTG) {
-		reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
-
-		/*
-		 * Enable Auto retry Feature to make the controller operating in
-		 * Host mode on seeing transaction errors(CRC errors or internal
-		 * overrun scenerios) on IN transfers to reply to the device
-		 * with a non-terminating retry ACK (i.e, an ACK transcation
-		 * packet with Retry=1 & Nump != 0)
-		 */
-		reg |= DWC3_GUCTL_HSTINAUTORETRY;
-
-		dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
 	}
 
 	/*
@@ -1654,13 +1648,11 @@
 	spin_lock_init(&dwc->lock);
 	mutex_init(&dwc->mutex);
 
+	pm_runtime_get_noresume(dev);
 	pm_runtime_set_active(dev);
 	pm_runtime_use_autosuspend(dev);
 	pm_runtime_set_autosuspend_delay(dev, DWC3_DEFAULT_AUTOSUSPEND_DELAY);
 	pm_runtime_enable(dev);
-	ret = pm_runtime_get_sync(dev);
-	if (ret < 0)
-		goto err1;
 
 	pm_runtime_forbid(dev);
 
@@ -1729,12 +1721,10 @@
 	dwc3_free_event_buffers(dwc);
 
 err2:
-	pm_runtime_allow(&pdev->dev);
-
-err1:
-	pm_runtime_put_sync(&pdev->dev);
-	pm_runtime_disable(&pdev->dev);
-
+	pm_runtime_allow(dev);
+	pm_runtime_disable(dev);
+	pm_runtime_set_suspended(dev);
+	pm_runtime_put_noidle(dev);
 disable_clks:
 	clk_bulk_disable_unprepare(dwc->num_clks, dwc->clks);
 assert_reset:
@@ -1758,8 +1748,14 @@
 	dwc3_core_exit(dwc);
 	dwc3_ulpi_exit(dwc);
 
+	pm_runtime_allow(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 	pm_runtime_put_noidle(&pdev->dev);
+	/*
+	 * HACK: Clear the driver data, which is currently accessed by parent
+	 * glue drivers, before allowing the parent to suspend.
+	 */
+	platform_set_drvdata(pdev, NULL);
 	pm_runtime_set_suspended(&pdev->dev);
 
 	dwc3_free_event_buffers(dwc);
diff --git a/kernel/drivers/usb/dwc3/core.h b/kernel/drivers/usb/dwc3/core.h
index 11ac1e0..4e7863f 100644
--- a/kernel/drivers/usb/dwc3/core.h
+++ b/kernel/drivers/usb/dwc3/core.h
@@ -253,9 +253,6 @@
 #define DWC3_GCTL_GBLHIBERNATIONEN	BIT(1)
 #define DWC3_GCTL_DSBLCLKGTNG		BIT(0)
 
-/* Global User Control Register */
-#define DWC3_GUCTL_HSTINAUTORETRY	BIT(14)
-
 /* Global User Control 1 Register */
 #define DWC3_GUCTL1_DEV_DECOUPLE_L1L2_EVT	BIT(31)
 #define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS	BIT(28)
diff --git a/kernel/drivers/usb/dwc3/debugfs.c b/kernel/drivers/usb/dwc3/debugfs.c
index dc81e83..f0f04d7 100644
--- a/kernel/drivers/usb/dwc3/debugfs.c
+++ b/kernel/drivers/usb/dwc3/debugfs.c
@@ -327,6 +327,11 @@
 	unsigned int		current_mode;
 	unsigned long		flags;
 	u32			reg;
+	int			ret;
+
+	ret = pm_runtime_resume_and_get(dwc->dev);
+	if (ret < 0)
+		return ret;
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	reg = dwc3_readl(dwc->regs, DWC3_GSTS);
@@ -344,6 +349,8 @@
 		break;
 	}
 	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	pm_runtime_put_sync(dwc->dev);
 
 	return 0;
 }
@@ -390,6 +397,11 @@
 	struct dwc3		*dwc = s->private;
 	unsigned long		flags;
 	u32			reg;
+	int			ret;
+
+	ret = pm_runtime_resume_and_get(dwc->dev);
+	if (ret < 0)
+		return ret;
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
@@ -408,6 +420,8 @@
 	default:
 		seq_printf(s, "UNKNOWN %08x\n", DWC3_GCTL_PRTCAP(reg));
 	}
+
+	pm_runtime_put_sync(dwc->dev);
 
 	return 0;
 }
@@ -462,6 +476,11 @@
 	struct dwc3		*dwc = s->private;
 	unsigned long		flags;
 	u32			reg;
+	int			ret;
+
+	ret = pm_runtime_resume_and_get(dwc->dev);
+	if (ret < 0)
+		return ret;
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
@@ -492,6 +511,8 @@
 		seq_printf(s, "UNKNOWN %d\n", reg);
 	}
 
+	pm_runtime_put_sync(dwc->dev);
+
 	return 0;
 }
 
@@ -508,6 +529,7 @@
 	unsigned long		flags;
 	u32			testmode = 0;
 	char			buf[32];
+	int			ret;
 
 	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
 		return -EFAULT;
@@ -525,9 +547,15 @@
 	else
 		testmode = 0;
 
+	ret = pm_runtime_resume_and_get(dwc->dev);
+	if (ret < 0)
+		return ret;
+
 	spin_lock_irqsave(&dwc->lock, flags);
 	dwc3_gadget_set_test_mode(dwc, testmode);
 	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	pm_runtime_put_sync(dwc->dev);
 
 	return count;
 }
@@ -547,12 +575,18 @@
 	enum dwc3_link_state	state;
 	u32			reg;
 	u8			speed;
+	int			ret;
+
+	ret = pm_runtime_resume_and_get(dwc->dev);
+	if (ret < 0)
+		return ret;
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	reg = dwc3_readl(dwc->regs, DWC3_GSTS);
 	if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) {
 		seq_puts(s, "Not available\n");
 		spin_unlock_irqrestore(&dwc->lock, flags);
+		pm_runtime_put_sync(dwc->dev);
 		return 0;
 	}
 
@@ -564,6 +598,8 @@
 		   dwc3_gadget_link_string(state) :
 		   dwc3_gadget_hs_link_string(state));
 	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	pm_runtime_put_sync(dwc->dev);
 
 	return 0;
 }
@@ -583,6 +619,7 @@
 	char			buf[32];
 	u32			reg;
 	u8			speed;
+	int			ret;
 
 	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
 		return -EFAULT;
@@ -602,10 +639,15 @@
 	else
 		return -EINVAL;
 
+	ret = pm_runtime_resume_and_get(dwc->dev);
+	if (ret < 0)
+		return ret;
+
 	spin_lock_irqsave(&dwc->lock, flags);
 	reg = dwc3_readl(dwc->regs, DWC3_GSTS);
 	if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) {
 		spin_unlock_irqrestore(&dwc->lock, flags);
+		pm_runtime_put_sync(dwc->dev);
 		return -EINVAL;
 	}
 
@@ -615,11 +657,14 @@
 	if (speed < DWC3_DSTS_SUPERSPEED &&
 	    state != DWC3_LINK_STATE_RECOV) {
 		spin_unlock_irqrestore(&dwc->lock, flags);
+		pm_runtime_put_sync(dwc->dev);
 		return -EINVAL;
 	}
 
 	dwc3_gadget_set_link_state(dwc, state);
 	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	pm_runtime_put_sync(dwc->dev);
 
 	return count;
 }
@@ -644,6 +689,11 @@
 	unsigned long		flags;
 	u32			mdwidth;
 	u32			val;
+	int			ret;
+
+	ret = pm_runtime_resume_and_get(dwc->dev);
+	if (ret < 0)
+		return ret;
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	val = dwc3_core_fifo_space(dep, DWC3_TXFIFO);
@@ -656,6 +706,8 @@
 	seq_printf(s, "%u\n", val);
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
+	pm_runtime_put_sync(dwc->dev);
+
 	return 0;
 }
 
@@ -666,6 +718,11 @@
 	unsigned long		flags;
 	u32			mdwidth;
 	u32			val;
+	int			ret;
+
+	ret = pm_runtime_resume_and_get(dwc->dev);
+	if (ret < 0)
+		return ret;
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	val = dwc3_core_fifo_space(dep, DWC3_RXFIFO);
@@ -678,6 +735,8 @@
 	seq_printf(s, "%u\n", val);
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
+	pm_runtime_put_sync(dwc->dev);
+
 	return 0;
 }
 
@@ -687,11 +746,18 @@
 	struct dwc3		*dwc = dep->dwc;
 	unsigned long		flags;
 	u32			val;
+	int			ret;
+
+	ret = pm_runtime_resume_and_get(dwc->dev);
+	if (ret < 0)
+		return ret;
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	val = dwc3_core_fifo_space(dep, DWC3_TXREQQ);
 	seq_printf(s, "%u\n", val);
 	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	pm_runtime_put_sync(dwc->dev);
 
 	return 0;
 }
@@ -702,11 +768,18 @@
 	struct dwc3		*dwc = dep->dwc;
 	unsigned long		flags;
 	u32			val;
+	int			ret;
+
+	ret = pm_runtime_resume_and_get(dwc->dev);
+	if (ret < 0)
+		return ret;
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	val = dwc3_core_fifo_space(dep, DWC3_RXREQQ);
 	seq_printf(s, "%u\n", val);
 	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	pm_runtime_put_sync(dwc->dev);
 
 	return 0;
 }
@@ -717,11 +790,18 @@
 	struct dwc3		*dwc = dep->dwc;
 	unsigned long		flags;
 	u32			val;
+	int			ret;
+
+	ret = pm_runtime_resume_and_get(dwc->dev);
+	if (ret < 0)
+		return ret;
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	val = dwc3_core_fifo_space(dep, DWC3_RXINFOQ);
 	seq_printf(s, "%u\n", val);
 	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	pm_runtime_put_sync(dwc->dev);
 
 	return 0;
 }
@@ -732,11 +812,18 @@
 	struct dwc3		*dwc = dep->dwc;
 	unsigned long		flags;
 	u32			val;
+	int			ret;
+
+	ret = pm_runtime_resume_and_get(dwc->dev);
+	if (ret < 0)
+		return ret;
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	val = dwc3_core_fifo_space(dep, DWC3_DESCFETCHQ);
 	seq_printf(s, "%u\n", val);
 	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	pm_runtime_put_sync(dwc->dev);
 
 	return 0;
 }
@@ -747,11 +834,18 @@
 	struct dwc3		*dwc = dep->dwc;
 	unsigned long		flags;
 	u32			val;
+	int			ret;
+
+	ret = pm_runtime_resume_and_get(dwc->dev);
+	if (ret < 0)
+		return ret;
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	val = dwc3_core_fifo_space(dep, DWC3_EVENTQ);
 	seq_printf(s, "%u\n", val);
 	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	pm_runtime_put_sync(dwc->dev);
 
 	return 0;
 }
@@ -797,6 +891,11 @@
 	struct dwc3		*dwc = dep->dwc;
 	unsigned long		flags;
 	int			i;
+	int			ret;
+
+	ret = pm_runtime_resume_and_get(dwc->dev);
+	if (ret < 0)
+		return ret;
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	if (dep->number <= 1) {
@@ -826,6 +925,8 @@
 out:
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
+	pm_runtime_put_sync(dwc->dev);
+
 	return 0;
 }
 
@@ -838,6 +939,11 @@
 	u32			lower_32_bits;
 	u32			upper_32_bits;
 	u32			reg;
+	int			ret;
+
+	ret = pm_runtime_resume_and_get(dwc->dev);
+	if (ret < 0)
+		return ret;
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	reg = DWC3_GDBGLSPMUX_EPSELECT(dep->number);
@@ -849,6 +955,8 @@
 	ep_info = ((u64)upper_32_bits << 32) | lower_32_bits;
 	seq_printf(s, "0x%016llx\n", ep_info);
 	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	pm_runtime_put_sync(dwc->dev);
 
 	return 0;
 }
@@ -911,6 +1019,7 @@
 	dwc->regset->regs = dwc3_regs;
 	dwc->regset->nregs = ARRAY_SIZE(dwc3_regs);
 	dwc->regset->base = dwc->regs - DWC3_GLOBALS_REGS_START;
+	dwc->regset->dev = dwc->dev;
 
 	root = debugfs_create_dir(dev_name(dwc->dev), usb_debug_root);
 	dwc->root = root;
diff --git a/kernel/drivers/usb/dwc3/dwc3-meson-g12a.c b/kernel/drivers/usb/dwc3/dwc3-meson-g12a.c
index d0f9b7c..2d3ca6e 100644
--- a/kernel/drivers/usb/dwc3/dwc3-meson-g12a.c
+++ b/kernel/drivers/usb/dwc3/dwc3-meson-g12a.c
@@ -805,13 +805,16 @@
 
 	ret = dwc3_meson_g12a_otg_init(pdev, priv);
 	if (ret)
-		goto err_phys_power;
+		goto err_plat_depopulate;
 
 	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
 	return 0;
+
+err_plat_depopulate:
+	of_platform_depopulate(dev);
 
 err_phys_power:
 	for (i = 0 ; i < PHY_COUNT ; ++i)
@@ -928,6 +931,12 @@
 			return ret;
 	}
 
+	if (priv->drvdata->usb_post_init) {
+		ret = priv->drvdata->usb_post_init(priv);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
diff --git a/kernel/drivers/usb/dwc3/dwc3-pci.c b/kernel/drivers/usb/dwc3/dwc3-pci.c
index 73c20a9..a431747 100644
--- a/kernel/drivers/usb/dwc3/dwc3-pci.c
+++ b/kernel/drivers/usb/dwc3/dwc3-pci.c
@@ -187,10 +187,12 @@
 
 			/*
 			 * A lot of BYT devices lack ACPI resource entries for
-			 * the GPIOs, add a fallback mapping to the reference
+			 * the GPIOs. If the ACPI entry for the GPIO controller
+			 * is present add a fallback mapping to the reference
 			 * design GPIOs which all boards seem to use.
 			 */
-			gpiod_add_lookup_table(&platform_bytcr_gpios);
+			if (acpi_dev_present("INT33FC", NULL, -1))
+				gpiod_add_lookup_table(&platform_bytcr_gpios);
 
 			/*
 			 * These GPIOs will turn on the USB2 PHY. Note that we have to
diff --git a/kernel/drivers/usb/dwc3/dwc3-qcom.c b/kernel/drivers/usb/dwc3/dwc3-qcom.c
index c711528..4147a9d 100644
--- a/kernel/drivers/usb/dwc3/dwc3-qcom.c
+++ b/kernel/drivers/usb/dwc3/dwc3-qcom.c
@@ -115,7 +115,7 @@
 	readl(base + offset);
 }
 
-static void dwc3_qcom_vbus_overrride_enable(struct dwc3_qcom *qcom, bool enable)
+static void dwc3_qcom_vbus_override_enable(struct dwc3_qcom *qcom, bool enable)
 {
 	if (enable) {
 		dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL,
@@ -136,7 +136,7 @@
 	struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, vbus_nb);
 
 	/* enable vbus override for device mode */
-	dwc3_qcom_vbus_overrride_enable(qcom, event);
+	dwc3_qcom_vbus_override_enable(qcom, event);
 	qcom->mode = event ? USB_DR_MODE_PERIPHERAL : USB_DR_MODE_HOST;
 
 	return NOTIFY_DONE;
@@ -148,7 +148,7 @@
 	struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, host_nb);
 
 	/* disable vbus override in host mode */
-	dwc3_qcom_vbus_overrride_enable(qcom, !event);
+	dwc3_qcom_vbus_override_enable(qcom, !event);
 	qcom->mode = event ? USB_DR_MODE_HOST : USB_DR_MODE_PERIPHERAL;
 
 	return NOTIFY_DONE;
@@ -258,7 +258,8 @@
 	if (IS_ERR(qcom->icc_path_apps)) {
 		dev_err(dev, "failed to get apps-usb path: %ld\n",
 				PTR_ERR(qcom->icc_path_apps));
-		return PTR_ERR(qcom->icc_path_apps);
+		ret = PTR_ERR(qcom->icc_path_apps);
+		goto put_path_ddr;
 	}
 
 	if (usb_get_maximum_speed(&qcom->dwc3->dev) >= USB_SPEED_SUPER ||
@@ -271,17 +272,23 @@
 
 	if (ret) {
 		dev_err(dev, "failed to set bandwidth for usb-ddr path: %d\n", ret);
-		return ret;
+		goto put_path_apps;
 	}
 
 	ret = icc_set_bw(qcom->icc_path_apps,
 		APPS_USB_AVG_BW, APPS_USB_PEAK_BW);
 	if (ret) {
 		dev_err(dev, "failed to set bandwidth for apps-usb path: %d\n", ret);
-		return ret;
+		goto put_path_apps;
 	}
 
 	return 0;
+
+put_path_apps:
+	icc_put(qcom->icc_path_apps);
+put_path_ddr:
+	icc_put(qcom->icc_path_ddr);
+	return ret;
 }
 
 /**
@@ -299,7 +306,16 @@
 /* Only usable in contexts where the role can not change. */
 static bool dwc3_qcom_is_host(struct dwc3_qcom *qcom)
 {
-	struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
+	struct dwc3 *dwc;
+
+	/*
+	 * FIXME: Fix this layering violation.
+	 */
+	dwc = platform_get_drvdata(qcom->dwc3);
+
+	/* Core driver may not have probed yet. */
+	if (!dwc)
+		return false;
 
 	return dwc->xhci;
 }
@@ -715,6 +731,7 @@
 	struct device		*dev = &pdev->dev;
 	struct dwc3_qcom	*qcom;
 	struct resource		*res, *parent_res = NULL;
+	struct resource		local_res;
 	int			ret, i;
 	bool			ignore_pipe_clk;
 
@@ -765,9 +782,8 @@
 	if (np) {
 		parent_res = res;
 	} else {
-		parent_res = kmemdup(res, sizeof(struct resource), GFP_KERNEL);
-		if (!parent_res)
-			return -ENOMEM;
+		memcpy(&local_res, res, sizeof(struct resource));
+		parent_res = &local_res;
 
 		parent_res->start = res->start +
 			qcom->acpi_pdata->qscratch_base_offset;
@@ -779,9 +795,10 @@
 			if (IS_ERR_OR_NULL(qcom->urs_usb)) {
 				dev_err(dev, "failed to create URS USB platdev\n");
 				if (!qcom->urs_usb)
-					return -ENODEV;
+					ret = -ENODEV;
 				else
-					return PTR_ERR(qcom->urs_usb);
+					ret = PTR_ERR(qcom->urs_usb);
+				goto clk_disable;
 			}
 		}
 	}
@@ -825,8 +842,8 @@
 	qcom->mode = usb_get_dr_mode(&qcom->dwc3->dev);
 
 	/* enable vbus override for device mode */
-	if (qcom->mode == USB_DR_MODE_PERIPHERAL)
-		dwc3_qcom_vbus_overrride_enable(qcom, true);
+	if (qcom->mode != USB_DR_MODE_HOST)
+		dwc3_qcom_vbus_override_enable(qcom, true);
 
 	/* register extcon to override sw_vbus on Vbus change later */
 	ret = dwc3_qcom_register_extcon(qcom);
@@ -862,10 +879,14 @@
 static int dwc3_qcom_remove(struct platform_device *pdev)
 {
 	struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
+	struct device_node *np = pdev->dev.of_node;
 	struct device *dev = &pdev->dev;
 	int i;
 
-	of_platform_depopulate(dev);
+	if (np)
+		of_platform_depopulate(&pdev->dev);
+	else
+		platform_device_put(pdev);
 
 	for (i = qcom->num_clocks - 1; i >= 0; i--) {
 		clk_disable_unprepare(qcom->clks[i]);
diff --git a/kernel/drivers/usb/dwc3/gadget.c b/kernel/drivers/usb/dwc3/gadget.c
index f974308..64ad5aa 100644
--- a/kernel/drivers/usb/dwc3/gadget.c
+++ b/kernel/drivers/usb/dwc3/gadget.c
@@ -180,6 +180,7 @@
 	list_del(&req->list);
 	req->remaining = 0;
 	req->needs_extra_trb = false;
+	req->num_trbs = 0;
 
 	if (req->request.status == -EINPROGRESS)
 		req->request.status = status;
@@ -1823,6 +1824,7 @@
  */
 static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt)
 {
+	struct dwc3 *dwc = dep->dwc;
 	struct dwc3_gadget_ep_cmd_params params;
 	u32 cmd;
 	int ret;
@@ -1846,11 +1848,15 @@
 	WARN_ON_ONCE(ret);
 	dep->resource_index = 0;
 
-	if (!interrupt)
+	if (!interrupt) {
+		if (!DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC3, 310A))
+			mdelay(1);
 		dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
-	else
+	} else {
 		dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
+	}
 
+	dep->flags &= ~DWC3_EP_DELAY_STOP;
 	return ret;
 }
 
@@ -2656,30 +2662,17 @@
 static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
 {
 	unsigned long flags;
+	int ret;
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	dwc->connected = false;
 
 	/*
-	 * Per databook, when we want to stop the gadget, if a control transfer
-	 * is still in process, complete it and get the core into setup phase.
+	 * Attempt to end pending SETUP status phase, and not wait for the
+	 * function to do so.
 	 */
-	if (dwc->ep0state != EP0_SETUP_PHASE &&
-	    dwc->ep0state != EP0_UNCONNECTED) {
-		int ret;
-
-		if (dwc->delayed_status)
-			dwc3_ep0_send_delayed_status(dwc);
-
-		reinit_completion(&dwc->ep0_in_setup);
-
-		spin_unlock_irqrestore(&dwc->lock, flags);
-		ret = wait_for_completion_timeout(&dwc->ep0_in_setup,
-				msecs_to_jiffies(DWC3_PULL_UP_TIMEOUT));
-		spin_lock_irqsave(&dwc->lock, flags);
-		if (ret == 0)
-			dev_warn(dwc->dev, "timed out waiting for SETUP phase\n");
-	}
+	if (dwc->delayed_status)
+		dwc3_ep0_send_delayed_status(dwc);
 
 	/*
 	 * In the Synopsys DesignWare Cores USB3 Databook Rev. 3.30a
@@ -2689,8 +2682,35 @@
 	 * bit.
 	 */
 	dwc3_stop_active_transfers(dwc);
-	__dwc3_gadget_stop(dwc);
 	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	/*
+	 * Per databook, when we want to stop the gadget, if a control transfer
+	 * is still in process, complete it and get the core into setup phase.
+	 * In case the host is unresponsive to a SETUP transaction, forcefully
+	 * stall the transfer, and move back to the SETUP phase, so that any
+	 * pending endxfers can be executed.
+	 */
+	if (dwc->ep0state != EP0_SETUP_PHASE &&
+	    dwc->ep0state != EP0_UNCONNECTED) {
+		reinit_completion(&dwc->ep0_in_setup);
+
+		ret = wait_for_completion_timeout(&dwc->ep0_in_setup,
+				msecs_to_jiffies(DWC3_PULL_UP_TIMEOUT));
+		if (ret == 0) {
+			unsigned int    dir;
+
+			dev_warn(dwc->dev, "wait for SETUP phase timed out\n");
+			spin_lock_irqsave(&dwc->lock, flags);
+			dir = !!dwc->ep0_expect_in;
+			if (dwc->ep0state == EP0_DATA_PHASE)
+				dwc3_ep0_end_control_data(dwc, dwc->eps[dir]);
+			else
+				dwc3_ep0_end_control_data(dwc, dwc->eps[!dir]);
+			dwc3_ep0_stall_and_restart(dwc);
+			spin_unlock_irqrestore(&dwc->lock, flags);
+		}
+	}
 
 	/*
 	 * Note: if the GEVNTCOUNT indicates events in the event buffer, the
@@ -2699,7 +2719,19 @@
 	 * remaining event generated by the controller while polling for
 	 * DSTS.DEVCTLHLT.
 	 */
-	return dwc3_gadget_run_stop(dwc, false, false);
+	ret = dwc3_gadget_run_stop(dwc, false, false);
+
+	/*
+	 * Stop the gadget after controller is halted, so that if needed, the
+	 * events to update EP0 state can still occur while the run/stop
+	 * routine polls for the halted state.  DEVTEN is cleared as part of
+	 * gadget stop.
+	 */
+	spin_lock_irqsave(&dwc->lock, flags);
+	__dwc3_gadget_stop(dwc);
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return ret;
 }
 
 static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
@@ -2731,7 +2763,9 @@
 	ret = pm_runtime_get_sync(dwc->dev);
 	if (!ret || ret < 0) {
 		pm_runtime_put(dwc->dev);
-		return 0;
+		if (ret < 0)
+			pm_runtime_set_suspended(dwc->dev);
+		return ret;
 	}
 
 	if (dwc->pullups_connected == is_on) {
@@ -2750,13 +2784,16 @@
 		 * device-initiated disconnect requires a core soft reset
 		 * (DCTL.CSftRst) before enabling the run/stop bit.
 		 */
-		dwc3_core_soft_reset(dwc);
+		ret = dwc3_core_soft_reset(dwc);
+		if (ret)
+			goto done;
 
 		dwc3_event_buffers_setup(dwc);
 		__dwc3_gadget_start(dwc);
 		ret = dwc3_gadget_run_stop(dwc, true, false);
 	}
 
+done:
 	pm_runtime_put(dwc->dev);
 
 	return ret;
@@ -3960,8 +3997,10 @@
 	if (dep->number <= 1 && dwc->ep0state != EP0_DATA_PHASE)
 		return;
 
+	if (interrupt && (dep->flags & DWC3_EP_DELAY_STOP))
+		return;
+
 	if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) ||
-	    (dep->flags & DWC3_EP_DELAY_STOP) ||
 	    (dep->flags & DWC3_EP_END_TRANSFER_PENDING))
 		return;
 
@@ -4001,7 +4040,11 @@
 	 * enabled, the EndTransfer command will have completed upon
 	 * returning from this function.
 	 *
-	 * This mode is NOT available on the DWC_usb31 IP.
+	 * This mode is NOT available on the DWC_usb31 IP.  In this
+	 * case, if the IOC bit is not set, then delay by 1ms
+	 * after issuing the EndTransfer command.  This allows for the
+	 * controller to handle the command completely before DWC3
+	 * remove requests attempts to unmap USB request buffers.
 	 */
 
 	__dwc3_stop_active_transfer(dep, force, interrupt);
@@ -4475,15 +4518,8 @@
 		break;
 	case DWC3_DEVICE_EVENT_SUSPEND:
 		/* It changed to be suspend event for version 2.30a and above */
-		if (!DWC3_VER_IS_PRIOR(DWC3, 230A)) {
-			/*
-			 * Ignore suspend event until the gadget enters into
-			 * USB_STATE_CONFIGURED state.
-			 */
-			if (dwc->gadget->state >= USB_STATE_CONFIGURED)
-				dwc3_gadget_suspend_interrupt(dwc,
-						event->event_info);
-		}
+		if (!DWC3_VER_IS_PRIOR(DWC3, 230A))
+			dwc3_gadget_suspend_interrupt(dwc, event->event_info);
 		break;
 	case DWC3_DEVICE_EVENT_SOF:
 	case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
@@ -4580,9 +4616,14 @@
 	u32 count;
 
 	if (pm_runtime_suspended(dwc->dev)) {
+		dwc->pending_events = true;
+		/*
+		 * Trigger runtime resume. The get() function will be balanced
+		 * after processing the pending events in dwc3_process_pending
+		 * events().
+		 */
 		pm_runtime_get(dwc->dev);
 		disable_irq_nosync(dwc->irq_gadget);
-		dwc->pending_events = true;
 		return IRQ_HANDLED;
 	}
 
@@ -4851,6 +4892,8 @@
 {
 	if (dwc->pending_events) {
 		dwc3_interrupt(dwc->irq_gadget, dwc->ev_buf);
+		dwc3_thread_interrupt(dwc->irq_gadget, dwc->ev_buf);
+		pm_runtime_put(dwc->dev);
 		dwc->pending_events = false;
 		enable_irq(dwc->irq_gadget);
 	}
diff --git a/kernel/drivers/usb/gadget/composite.c b/kernel/drivers/usb/gadget/composite.c
index 9315313..83df30b 100644
--- a/kernel/drivers/usb/gadget/composite.c
+++ b/kernel/drivers/usb/gadget/composite.c
@@ -2447,6 +2447,10 @@
 			usb_gadget_clear_selfpowered(gadget);
 
 		usb_gadget_vbus_draw(gadget, maxpower);
+	} else {
+		maxpower = CONFIG_USB_GADGET_VBUS_DRAW;
+		maxpower = min(maxpower, 100U);
+		usb_gadget_vbus_draw(gadget, maxpower);
 	}
 
 	cdev->suspended = 0;
diff --git a/kernel/drivers/usb/gadget/configfs.c b/kernel/drivers/usb/gadget/configfs.c
index 81f6808..35c6442 100644
--- a/kernel/drivers/usb/gadget/configfs.c
+++ b/kernel/drivers/usb/gadget/configfs.c
@@ -461,6 +461,12 @@
 	 * from another gadget or a random directory.
 	 * Also a function instance can only be linked once.
 	 */
+
+	if (gi->composite.gadget_driver.udc_name) {
+		ret = -EINVAL;
+		goto out;
+	}
+
 	list_for_each_entry(a_fi, &gi->available_func, cfs_list) {
 		if (a_fi == fi)
 			break;
@@ -1549,10 +1555,11 @@
 	int value = -EOPNOTSUPP;
 	struct usb_function_instance *fi;
 
-	if (!android_device)
+	cdev = get_gadget_data(gadget);
+	if (!cdev)
 		return 0;
 
-	gi = dev_get_drvdata(android_device);
+	gi = container_of(cdev, struct gadget_info, cdev);
 	spin_lock_irqsave(&gi->spinlock, flags);
 	cdev = get_gadget_data(gadget);
 	if (!cdev || gi->unbind) {
diff --git a/kernel/drivers/usb/gadget/function/f_fs.c b/kernel/drivers/usb/gadget/function/f_fs.c
index 8514ab7..bae40a7 100644
--- a/kernel/drivers/usb/gadget/function/f_fs.c
+++ b/kernel/drivers/usb/gadget/function/f_fs.c
@@ -3623,6 +3623,7 @@
 	/* Drain any pending AIO completions */
 	drain_workqueue(ffs->io_completion_wq);
 
+	ffs_event_add(ffs, FUNCTIONFS_UNBIND);
 	if (!--opts->refcnt)
 		functionfs_unbind(ffs);
 
@@ -3647,7 +3648,6 @@
 	func->function.ssp_descriptors = NULL;
 	func->interfaces_nums = NULL;
 
-	ffs_event_add(ffs, FUNCTIONFS_UNBIND);
 }
 
 static struct usb_function *ffs_alloc(struct usb_function_instance *fi)
diff --git a/kernel/drivers/usb/gadget/function/f_hid.c b/kernel/drivers/usb/gadget/function/f_hid.c
index 97e927e..e7cf56b 100644
--- a/kernel/drivers/usb/gadget/function/f_hid.c
+++ b/kernel/drivers/usb/gadget/function/f_hid.c
@@ -1292,6 +1292,7 @@
 						 GFP_KERNEL);
 		if (!hidg->report_desc) {
 			put_device(&hidg->dev);
+			--opts->refcnt;
 			mutex_unlock(&opts->lock);
 			return ERR_PTR(-ENOMEM);
 		}
diff --git a/kernel/drivers/usb/gadget/function/f_mass_storage.c b/kernel/drivers/usb/gadget/function/f_mass_storage.c
index 7790fbe..1c7d3da 100644
--- a/kernel/drivers/usb/gadget/function/f_mass_storage.c
+++ b/kernel/drivers/usb/gadget/function/f_mass_storage.c
@@ -951,7 +951,7 @@
 {
 	struct file	*filp = curlun->filp;
 	struct inode	*inode = file_inode(filp);
-	unsigned long	rc;
+	unsigned long __maybe_unused	rc;
 
 	rc = invalidate_mapping_pages(inode->i_mapping, 0, -1);
 	VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc);
diff --git a/kernel/drivers/usb/gadget/function/f_ncm.c b/kernel/drivers/usb/gadget/function/f_ncm.c
index 8551272..00aea45 100644
--- a/kernel/drivers/usb/gadget/function/f_ncm.c
+++ b/kernel/drivers/usb/gadget/function/f_ncm.c
@@ -85,7 +85,9 @@
 /* peak (theoretical) bulk transfer rate in bits-per-second */
 static inline unsigned ncm_bitrate(struct usb_gadget *g)
 {
-	if (gadget_is_superspeed(g) && g->speed >= USB_SPEED_SUPER_PLUS)
+	if (!g)
+		return 0;
+	else if (gadget_is_superspeed(g) && g->speed >= USB_SPEED_SUPER_PLUS)
 		return 4250000000U;
 	else if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER)
 		return 3750000000U;
@@ -1178,7 +1180,8 @@
 			  struct sk_buff_head *list)
 {
 	struct f_ncm	*ncm = func_to_ncm(&port->func);
-	__le16		*tmp = (void *) skb->data;
+	unsigned char	*ntb_ptr = skb->data;
+	__le16		*tmp;
 	unsigned	index, index2;
 	int		ndp_index;
 	unsigned	dg_len, dg_len2;
@@ -1191,6 +1194,10 @@
 	const struct ndp_parser_opts *opts = ncm->parser_opts;
 	unsigned	crc_len = ncm->is_crc ? sizeof(uint32_t) : 0;
 	int		dgram_counter;
+	int		to_process = skb->len;
+
+parse_ntb:
+	tmp = (__le16 *)ntb_ptr;
 
 	/* dwSignature */
 	if (get_unaligned_le32(tmp) != opts->nth_sign) {
@@ -1237,7 +1244,7 @@
 		 * walk through NDP
 		 * dwSignature
 		 */
-		tmp = (void *)(skb->data + ndp_index);
+		tmp = (__le16 *)(ntb_ptr + ndp_index);
 		if (get_unaligned_le32(tmp) != ncm->ndp_sign) {
 			INFO(port->func.config->cdev, "Wrong NDP SIGN\n");
 			goto err;
@@ -1294,11 +1301,11 @@
 			if (ncm->is_crc) {
 				uint32_t crc, crc2;
 
-				crc = get_unaligned_le32(skb->data +
+				crc = get_unaligned_le32(ntb_ptr +
 							 index + dg_len -
 							 crc_len);
 				crc2 = ~crc32_le(~0,
-						 skb->data + index,
+						 ntb_ptr + index,
 						 dg_len - crc_len);
 				if (crc != crc2) {
 					INFO(port->func.config->cdev,
@@ -1325,7 +1332,7 @@
 							 dg_len - crc_len);
 			if (skb2 == NULL)
 				goto err;
-			skb_put_data(skb2, skb->data + index,
+			skb_put_data(skb2, ntb_ptr + index,
 				     dg_len - crc_len);
 
 			skb_queue_tail(list, skb2);
@@ -1338,10 +1345,17 @@
 		} while (ndp_len > 2 * (opts->dgram_item_len * 2));
 	} while (ndp_index);
 
-	dev_consume_skb_any(skb);
-
 	VDBG(port->func.config->cdev,
 	     "Parsed NTB with %d frames\n", dgram_counter);
+
+	to_process -= block_len;
+	if (to_process != 0) {
+		ntb_ptr = (unsigned char *)(ntb_ptr + block_len);
+		goto parse_ntb;
+	}
+
+	dev_consume_skb_any(skb);
+
 	return 0;
 err:
 	skb_queue_purge(list);
diff --git a/kernel/drivers/usb/gadget/function/f_uac2.c b/kernel/drivers/usb/gadget/function/f_uac2.c
index 08726e4..0219cd7 100644
--- a/kernel/drivers/usb/gadget/function/f_uac2.c
+++ b/kernel/drivers/usb/gadget/function/f_uac2.c
@@ -1142,6 +1142,7 @@
 		}
 		std_as_out_if0_desc.bInterfaceNumber = ret;
 		std_as_out_if1_desc.bInterfaceNumber = ret;
+		std_as_out_if1_desc.bNumEndpoints = 1;
 		uac2->as_out_intf = ret;
 		uac2->as_out_alt = 0;
 
diff --git a/kernel/drivers/usb/gadget/function/f_uvc.c b/kernel/drivers/usb/gadget/function/f_uvc.c
index 4b67731..2b7f5be 100644
--- a/kernel/drivers/usb/gadget/function/f_uvc.c
+++ b/kernel/drivers/usb/gadget/function/f_uvc.c
@@ -586,6 +586,7 @@
 	int ret;
 
 	/* TODO reference counting. */
+	memset(&uvc->vdev, 0, sizeof(uvc->vdev));
 	uvc->vdev.v4l2_dev = &uvc->v4l2_dev;
 	uvc->vdev.fops = &uvc_v4l2_fops;
 	uvc->vdev.ioctl_ops = &uvc_v4l2_ioctl_ops;
@@ -1198,10 +1199,14 @@
 {
 	struct usb_composite_dev *cdev = c->cdev;
 	struct uvc_device *uvc = to_uvc(f);
+	struct uvc_video *video = &uvc->video;
 	long wait_ret = 1;
 
 	uvcg_info(f, "%s()\n", __func__);
 
+	if (video->async_wq)
+		destroy_workqueue(video->async_wq);
+
 	/* If we know we're connected via v4l2, then there should be a cleanup
 	 * of the device from userspace either via UVC_EVENT_DISCONNECT or
 	 * though the video device removal uevent. Allow some time for the
diff --git a/kernel/drivers/usb/gadget/function/u_audio.c b/kernel/drivers/usb/gadget/function/u_audio.c
index adde446..cb15ec8 100644
--- a/kernel/drivers/usb/gadget/function/u_audio.c
+++ b/kernel/drivers/usb/gadget/function/u_audio.c
@@ -1692,7 +1692,7 @@
 	uac = g_audio->uac;
 	card = uac->card;
 	if (card)
-		snd_card_free(card);
+		snd_card_free_when_closed(card);
 
 	kfree(uac->p_prm.reqs);
 	kfree(uac->c_prm.reqs);
diff --git a/kernel/drivers/usb/gadget/function/u_ether.c b/kernel/drivers/usb/gadget/function/u_ether.c
index 785e03f..b47f498 100644
--- a/kernel/drivers/usb/gadget/function/u_ether.c
+++ b/kernel/drivers/usb/gadget/function/u_ether.c
@@ -17,6 +17,7 @@
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
+#include <linux/string_helpers.h>
 
 #include "u_ether.h"
 
@@ -975,6 +976,8 @@
 	dev = netdev_priv(net);
 	snprintf(host_addr, len, "%pm", dev->host_mac);
 
+	string_upper(host_addr, host_addr);
+
 	return strlen(host_addr);
 }
 EXPORT_SYMBOL_GPL(gether_get_host_addr_cdc);
diff --git a/kernel/drivers/usb/gadget/function/u_serial.c b/kernel/drivers/usb/gadget/function/u_serial.c
index 1e59204..a4c5baf 100644
--- a/kernel/drivers/usb/gadget/function/u_serial.c
+++ b/kernel/drivers/usb/gadget/function/u_serial.c
@@ -81,6 +81,9 @@
 #define WRITE_BUF_SIZE		8192		/* TX only */
 #define GS_CONSOLE_BUF_SIZE	8192
 
+/* Prevents race conditions while accessing gser->ioport */
+static DEFINE_SPINLOCK(serial_port_lock);
+
 /* console info */
 struct gs_console {
 	struct console		console;
@@ -912,8 +915,11 @@
 	}
 
 	req->length = size;
+
+	spin_unlock_irq(&cons->lock);
 	if (usb_ep_queue(ep, req, GFP_ATOMIC))
 		req->length = 0;
+	spin_lock_irq(&cons->lock);
 }
 
 static void gs_console_work(struct work_struct *work)
@@ -1374,8 +1380,10 @@
 	if (!port)
 		return;
 
+	spin_lock_irqsave(&serial_port_lock, flags);
+
 	/* tell the TTY glue not to do I/O here any more */
-	spin_lock_irqsave(&port->port_lock, flags);
+	spin_lock(&port->port_lock);
 
 	gs_console_disconnect(port);
 
@@ -1390,7 +1398,8 @@
 			tty_hangup(port->port.tty);
 	}
 	port->suspended = false;
-	spin_unlock_irqrestore(&port->port_lock, flags);
+	spin_unlock(&port->port_lock);
+	spin_unlock_irqrestore(&serial_port_lock, flags);
 
 	/* disable endpoints, aborting down any active I/O */
 	usb_ep_disable(gser->out);
@@ -1413,10 +1422,19 @@
 
 void gserial_suspend(struct gserial *gser)
 {
-	struct gs_port	*port = gser->ioport;
+	struct gs_port	*port;
 	unsigned long	flags;
 
-	spin_lock_irqsave(&port->port_lock, flags);
+	spin_lock_irqsave(&serial_port_lock, flags);
+	port = gser->ioport;
+
+	if (!port) {
+		spin_unlock_irqrestore(&serial_port_lock, flags);
+		return;
+	}
+
+	spin_lock(&port->port_lock);
+	spin_unlock(&serial_port_lock);
 	port->suspended = true;
 	spin_unlock_irqrestore(&port->port_lock, flags);
 }
@@ -1424,10 +1442,19 @@
 
 void gserial_resume(struct gserial *gser)
 {
-	struct gs_port *port = gser->ioport;
+	struct gs_port *port;
 	unsigned long	flags;
 
-	spin_lock_irqsave(&port->port_lock, flags);
+	spin_lock_irqsave(&serial_port_lock, flags);
+	port = gser->ioport;
+
+	if (!port) {
+		spin_unlock_irqrestore(&serial_port_lock, flags);
+		return;
+	}
+
+	spin_lock(&port->port_lock);
+	spin_unlock(&serial_port_lock);
 	port->suspended = false;
 	if (!port->start_delayed) {
 		spin_unlock_irqrestore(&port->port_lock, flags);
diff --git a/kernel/drivers/usb/gadget/function/uvc.h b/kernel/drivers/usb/gadget/function/uvc.h
index 9a5507d..d76a23d 100644
--- a/kernel/drivers/usb/gadget/function/uvc.h
+++ b/kernel/drivers/usb/gadget/function/uvc.h
@@ -87,6 +87,7 @@
 	struct usb_ep *ep;
 
 	struct work_struct pump;
+	struct workqueue_struct *async_wq;
 
 	/* Frame parameters */
 	u8 bpp;
diff --git a/kernel/drivers/usb/gadget/function/uvc_configfs.c b/kernel/drivers/usb/gadget/function/uvc_configfs.c
index 4e242f2..e93c78c 100644
--- a/kernel/drivers/usb/gadget/function/uvc_configfs.c
+++ b/kernel/drivers/usb/gadget/function/uvc_configfs.c
@@ -506,11 +506,68 @@
 UVCG_DEFAULT_OUTPUT_ATTR(b_terminal_id, bTerminalID, 8);
 UVCG_DEFAULT_OUTPUT_ATTR(w_terminal_type, wTerminalType, 16);
 UVCG_DEFAULT_OUTPUT_ATTR(b_assoc_terminal, bAssocTerminal, 8);
-UVCG_DEFAULT_OUTPUT_ATTR(b_source_id, bSourceID, 8);
 UVCG_DEFAULT_OUTPUT_ATTR(i_terminal, iTerminal, 8);
 
 #undef UVCG_DEFAULT_OUTPUT_ATTR
 
+static ssize_t uvcg_default_output_b_source_id_show(struct config_item *item,
+						    char *page)
+{
+	struct config_group *group = to_config_group(item);
+	struct f_uvc_opts *opts;
+	struct config_item *opts_item;
+	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
+	struct uvc_output_terminal_descriptor *cd;
+	int result;
+
+	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
+
+	opts_item = group->cg_item.ci_parent->ci_parent->
+			ci_parent->ci_parent;
+	opts = to_f_uvc_opts(opts_item);
+	cd = &opts->uvc_output_terminal;
+
+	mutex_lock(&opts->lock);
+	result = sprintf(page, "%u\n", le8_to_cpu(cd->bSourceID));
+	mutex_unlock(&opts->lock);
+
+	mutex_unlock(su_mutex);
+
+	return result;
+}
+
+static ssize_t uvcg_default_output_b_source_id_store(struct config_item *item,
+						     const char *page, size_t len)
+{
+	struct config_group *group = to_config_group(item);
+	struct f_uvc_opts *opts;
+	struct config_item *opts_item;
+	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
+	struct uvc_output_terminal_descriptor *cd;
+	int result;
+	u8 num;
+
+	result = kstrtou8(page, 0, &num);
+	if (result)
+		return result;
+
+	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
+
+	opts_item = group->cg_item.ci_parent->ci_parent->
+			ci_parent->ci_parent;
+	opts = to_f_uvc_opts(opts_item);
+	cd = &opts->uvc_output_terminal;
+
+	mutex_lock(&opts->lock);
+	cd->bSourceID = num;
+	mutex_unlock(&opts->lock);
+
+	mutex_unlock(su_mutex);
+
+	return len;
+}
+UVC_ATTR(uvcg_default_output_, b_source_id, bSourceID);
+
 static struct configfs_attribute *uvcg_default_output_attrs[] = {
 	&uvcg_default_output_attr_b_terminal_id,
 	&uvcg_default_output_attr_w_terminal_type,
diff --git a/kernel/drivers/usb/gadget/function/uvc_v4l2.c b/kernel/drivers/usb/gadget/function/uvc_v4l2.c
index 3105d5a..d1398ae 100644
--- a/kernel/drivers/usb/gadget/function/uvc_v4l2.c
+++ b/kernel/drivers/usb/gadget/function/uvc_v4l2.c
@@ -174,7 +174,7 @@
 		return ret;
 
 	if (uvc->state == UVC_STATE_STREAMING)
-		schedule_work(&video->pump);
+		queue_work(video->async_wq, &video->pump);
 
 	return ret;
 }
diff --git a/kernel/drivers/usb/gadget/function/uvc_video.c b/kernel/drivers/usb/gadget/function/uvc_video.c
index b69ae5e..278134f 100644
--- a/kernel/drivers/usb/gadget/function/uvc_video.c
+++ b/kernel/drivers/usb/gadget/function/uvc_video.c
@@ -249,7 +249,7 @@
 	spin_unlock_irqrestore(&video->req_lock, flags);
 
 	if (uvc->state == UVC_STATE_STREAMING)
-		schedule_work(&video->pump);
+		queue_work(video->async_wq, &video->pump);
 }
 
 static int
@@ -446,7 +446,7 @@
 	} else
 		video->encode = uvc_video_encode_isoc;
 
-	schedule_work(&video->pump);
+	queue_work(video->async_wq, &video->pump);
 
 	return ret;
 }
@@ -460,6 +460,11 @@
 	spin_lock_init(&video->req_lock);
 	INIT_WORK(&video->pump, uvcg_video_pump);
 
+	/* Allocate a work queue for asynchronous video pump handler. */
+	video->async_wq = alloc_workqueue("uvcgadget", WQ_UNBOUND | WQ_HIGHPRI, 0);
+	if (!video->async_wq)
+		return -EINVAL;
+
 	video->uvc = uvc;
 	video->fcc = V4L2_PIX_FMT_YUYV;
 	video->bpp = 16;
diff --git a/kernel/drivers/usb/gadget/legacy/inode.c b/kernel/drivers/usb/gadget/legacy/inode.c
index cd09747..cbe8016 100644
--- a/kernel/drivers/usb/gadget/legacy/inode.c
+++ b/kernel/drivers/usb/gadget/legacy/inode.c
@@ -229,6 +229,7 @@
  */
 
 static const char *CHIP;
+static DEFINE_MUTEX(sb_mutex);		/* Serialize superblock operations */
 
 /*----------------------------------------------------------------------*/
 
@@ -2012,13 +2013,20 @@
 {
 	struct inode	*inode;
 	struct dev_data	*dev;
+	int		rc;
 
-	if (the_device)
-		return -ESRCH;
+	mutex_lock(&sb_mutex);
+
+	if (the_device) {
+		rc = -ESRCH;
+		goto Done;
+	}
 
 	CHIP = usb_get_gadget_udc_name();
-	if (!CHIP)
-		return -ENODEV;
+	if (!CHIP) {
+		rc = -ENODEV;
+		goto Done;
+	}
 
 	/* superblock */
 	sb->s_blocksize = PAGE_SIZE;
@@ -2055,13 +2063,17 @@
 	 * from binding to a controller.
 	 */
 	the_device = dev;
-	return 0;
+	rc = 0;
+	goto Done;
 
-Enomem:
+ Enomem:
 	kfree(CHIP);
 	CHIP = NULL;
+	rc = -ENOMEM;
 
-	return -ENOMEM;
+ Done:
+	mutex_unlock(&sb_mutex);
+	return rc;
 }
 
 /* "mount -t gadgetfs path /dev/gadget" ends up here */
@@ -2083,6 +2095,7 @@
 static void
 gadgetfs_kill_sb (struct super_block *sb)
 {
+	mutex_lock(&sb_mutex);
 	kill_litter_super (sb);
 	if (the_device) {
 		put_dev (the_device);
@@ -2090,6 +2103,7 @@
 	}
 	kfree(CHIP);
 	CHIP = NULL;
+	mutex_unlock(&sb_mutex);
 }
 
 /*----------------------------------------------------------------------*/
diff --git a/kernel/drivers/usb/gadget/legacy/raw_gadget.c b/kernel/drivers/usb/gadget/legacy/raw_gadget.c
index b496ca9..ddb39e6 100644
--- a/kernel/drivers/usb/gadget/legacy/raw_gadget.c
+++ b/kernel/drivers/usb/gadget/legacy/raw_gadget.c
@@ -309,13 +309,15 @@
 	dev->eps_num = i;
 	spin_unlock_irqrestore(&dev->lock, flags);
 
+	ret = raw_queue_event(dev, USB_RAW_EVENT_CONNECT, 0, NULL);
+	if (ret < 0) {
+		dev_err(&gadget->dev, "failed to queue event\n");
+		set_gadget_data(gadget, NULL);
+		return ret;
+	}
+
 	/* Matches kref_put() in gadget_unbind(). */
 	kref_get(&dev->count);
-
-	ret = raw_queue_event(dev, USB_RAW_EVENT_CONNECT, 0, NULL);
-	if (ret < 0)
-		dev_err(&gadget->dev, "failed to queue event\n");
-
 	return ret;
 }
 
diff --git a/kernel/drivers/usb/gadget/legacy/webcam.c b/kernel/drivers/usb/gadget/legacy/webcam.c
index 71c567b..6d1e79b 100644
--- a/kernel/drivers/usb/gadget/legacy/webcam.c
+++ b/kernel/drivers/usb/gadget/legacy/webcam.c
@@ -293,6 +293,7 @@
 	(const struct uvc_descriptor_header *) &uvc_format_yuv,
 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
+	(const struct uvc_descriptor_header *) &uvc_color_matching,
 	(const struct uvc_descriptor_header *) &uvc_format_mjpg,
 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
@@ -305,6 +306,7 @@
 	(const struct uvc_descriptor_header *) &uvc_format_yuv,
 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
+	(const struct uvc_descriptor_header *) &uvc_color_matching,
 	(const struct uvc_descriptor_header *) &uvc_format_mjpg,
 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
@@ -317,6 +319,7 @@
 	(const struct uvc_descriptor_header *) &uvc_format_yuv,
 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
+	(const struct uvc_descriptor_header *) &uvc_color_matching,
 	(const struct uvc_descriptor_header *) &uvc_format_mjpg,
 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
diff --git a/kernel/drivers/usb/gadget/udc/amd5536udc_pci.c b/kernel/drivers/usb/gadget/udc/amd5536udc_pci.c
index c80f9bd..a36913a 100644
--- a/kernel/drivers/usb/gadget/udc/amd5536udc_pci.c
+++ b/kernel/drivers/usb/gadget/udc/amd5536udc_pci.c
@@ -170,6 +170,9 @@
 		retval = -ENODEV;
 		goto err_probe;
 	}
+
+	udc = dev;
+
 	return 0;
 
 err_probe:
diff --git a/kernel/drivers/usb/gadget/udc/core.c b/kernel/drivers/usb/gadget/udc/core.c
index ef0332a..74bc551 100644
--- a/kernel/drivers/usb/gadget/udc/core.c
+++ b/kernel/drivers/usb/gadget/udc/core.c
@@ -730,11 +730,11 @@
 	}
 
 	ret = gadget->ops->pullup(gadget, 0);
-	if (!ret) {
+	if (!ret)
 		gadget->connected = 0;
-		if (gadget->udc->driver)
-			gadget->udc->driver->disconnect(gadget);
-	}
+
+	if (gadget->udc->driver)
+		gadget->udc->driver->disconnect(gadget);
 
 out:
 	trace_usb_gadget_disconnect(gadget, ret);
@@ -1047,12 +1047,16 @@
 
 /* ------------------------------------------------------------------------- */
 
-static void usb_udc_connect_control(struct usb_udc *udc)
+static int usb_udc_connect_control(struct usb_udc *udc)
 {
+	int ret;
+
 	if (udc->vbus)
-		usb_gadget_connect(udc->gadget);
+		ret = usb_gadget_connect(udc->gadget);
 	else
-		usb_gadget_disconnect(udc->gadget);
+		ret = usb_gadget_disconnect(udc->gadget);
+
+	return ret;
 }
 
 /**
@@ -1507,15 +1511,26 @@
 	if (ret)
 		goto err1;
 	ret = usb_gadget_udc_start(udc);
-	if (ret) {
-		driver->unbind(udc->gadget);
-		goto err1;
-	}
+	if (ret)
+		goto err_start;
+
 	usb_gadget_enable_async_callbacks(udc);
-	usb_udc_connect_control(udc);
+	ret = usb_udc_connect_control(udc);
+	if (ret)
+		goto err_connect_control;
 
 	kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
 	return 0;
+
+err_connect_control:
+	usb_gadget_disable_async_callbacks(udc);
+	if (udc->gadget->irq)
+		synchronize_irq(udc->gadget->irq);
+	usb_gadget_udc_stop(udc);
+
+err_start:
+	driver->unbind(udc->gadget);
+
 err1:
 	if (ret != -EISNAM)
 		dev_err(&udc->dev, "failed to start %s: %d\n",
diff --git a/kernel/drivers/usb/gadget/udc/fotg210-udc.c b/kernel/drivers/usb/gadget/udc/fotg210-udc.c
index 75bf446..11712bc 100644
--- a/kernel/drivers/usb/gadget/udc/fotg210-udc.c
+++ b/kernel/drivers/usb/gadget/udc/fotg210-udc.c
@@ -629,10 +629,10 @@
 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 @@
 
 	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;
diff --git a/kernel/drivers/usb/gadget/udc/fsl_qe_udc.c b/kernel/drivers/usb/gadget/udc/fsl_qe_udc.c
index fa66449..618b0a3 100644
--- a/kernel/drivers/usb/gadget/udc/fsl_qe_udc.c
+++ b/kernel/drivers/usb/gadget/udc/fsl_qe_udc.c
@@ -1950,9 +1950,13 @@
 	} else if ((request_type & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) {
 		/* Get endpoint status */
 		int pipe = index & USB_ENDPOINT_NUMBER_MASK;
-		struct qe_ep *target_ep = &udc->eps[pipe];
+		struct qe_ep *target_ep;
 		u16 usep;
 
+		if (pipe >= USB_MAX_ENDPOINTS)
+			goto stall;
+		target_ep = &udc->eps[pipe];
+
 		/* stall if endpoint doesn't exist */
 		if (!target_ep->ep.desc)
 			goto stall;
diff --git a/kernel/drivers/usb/gadget/udc/renesas_usb3.c b/kernel/drivers/usb/gadget/udc/renesas_usb3.c
index 601829a..a10f41c 100644
--- a/kernel/drivers/usb/gadget/udc/renesas_usb3.c
+++ b/kernel/drivers/usb/gadget/udc/renesas_usb3.c
@@ -2568,6 +2568,7 @@
 	debugfs_remove_recursive(usb3->dentry);
 	device_remove_file(&pdev->dev, &dev_attr_role);
 
+	cancel_work_sync(&usb3->role_work);
 	usb_role_switch_unregister(usb3->role_sw);
 
 	usb_del_gadget_udc(&usb3->gadget);
diff --git a/kernel/drivers/usb/gadget/udc/tegra-xudc.c b/kernel/drivers/usb/gadget/udc/tegra-xudc.c
index 3ebc8c5..c5f0fbb 100644
--- a/kernel/drivers/usb/gadget/udc/tegra-xudc.c
+++ b/kernel/drivers/usb/gadget/udc/tegra-xudc.c
@@ -2154,7 +2154,7 @@
 
 	dev_dbg(xudc->dev, "%s: %u mA\n", __func__, m_a);
 
-	if (xudc->curr_usbphy->chg_type == SDP_TYPE)
+	if (xudc->curr_usbphy && xudc->curr_usbphy->chg_type == SDP_TYPE)
 		ret = usb_phy_set_power(xudc->curr_usbphy, m_a);
 
 	return ret;
@@ -3693,15 +3693,15 @@
 	int err;
 
 	xudc->genpd_dev_device = dev_pm_domain_attach_by_name(dev, "dev");
-	if (IS_ERR_OR_NULL(xudc->genpd_dev_device)) {
-		err = PTR_ERR(xudc->genpd_dev_device) ? : -ENODATA;
+	if (IS_ERR(xudc->genpd_dev_device)) {
+		err = PTR_ERR(xudc->genpd_dev_device);
 		dev_err(dev, "failed to get device power domain: %d\n", err);
 		return err;
 	}
 
 	xudc->genpd_dev_ss = dev_pm_domain_attach_by_name(dev, "ss");
-	if (IS_ERR_OR_NULL(xudc->genpd_dev_ss)) {
-		err = PTR_ERR(xudc->genpd_dev_ss) ? : -ENODATA;
+	if (IS_ERR(xudc->genpd_dev_ss)) {
+		err = PTR_ERR(xudc->genpd_dev_ss);
 		dev_err(dev, "failed to get SuperSpeed power domain: %d\n", err);
 		return err;
 	}
diff --git a/kernel/drivers/usb/host/ehci-fsl.c b/kernel/drivers/usb/host/ehci-fsl.c
index 1e8b59a..c78f71a 100644
--- a/kernel/drivers/usb/host/ehci-fsl.c
+++ b/kernel/drivers/usb/host/ehci-fsl.c
@@ -29,7 +29,7 @@
 #include "ehci-fsl.h"
 
 #define DRIVER_DESC "Freescale EHCI Host controller driver"
-#define DRV_NAME "ehci-fsl"
+#define DRV_NAME "fsl-ehci"
 
 static struct hc_driver __read_mostly fsl_ehci_hc_driver;
 
diff --git a/kernel/drivers/usb/host/ohci-at91.c b/kernel/drivers/usb/host/ohci-at91.c
index 99e994f..2ba3c1b 100644
--- a/kernel/drivers/usb/host/ohci-at91.c
+++ b/kernel/drivers/usb/host/ohci-at91.c
@@ -647,7 +647,13 @@
 	else
 		at91_start_clock(ohci_at91);
 
-	ohci_resume(hcd, false);
+	/*
+	 * According to the comment in ohci_hcd_at91_drv_suspend()
+	 * we need to do a reset if the 48Mhz clock was stopped,
+	 * that is, if ohci_at91->wakeup is clear. Tell ohci_resume()
+	 * to reset in this case by setting its "hibernated" flag.
+	 */
+	ohci_resume(hcd, !ohci_at91->wakeup);
 
 	return 0;
 }
diff --git a/kernel/drivers/usb/host/ohci-platform.c b/kernel/drivers/usb/host/ohci-platform.c
index 4923536..aa9bc2e 100644
--- a/kernel/drivers/usb/host/ohci-platform.c
+++ b/kernel/drivers/usb/host/ohci-platform.c
@@ -216,6 +216,10 @@
 
 	device_wakeup_enable(hcd->self.controller);
 
+	if (of_device_is_compatible(dev->dev.of_node,
+				    "rockchip,rk3588-ohci"))
+		device_enable_async_suspend(hcd->self.controller);
+
 	platform_set_drvdata(dev, hcd);
 
 	return err;
diff --git a/kernel/drivers/usb/host/uhci-pci.c b/kernel/drivers/usb/host/uhci-pci.c
index 9b88745..3316533 100644
--- a/kernel/drivers/usb/host/uhci-pci.c
+++ b/kernel/drivers/usb/host/uhci-pci.c
@@ -119,11 +119,13 @@
 
 	uhci->rh_numports = uhci_count_ports(hcd);
 
-	/* Intel controllers report the OverCurrent bit active on.
-	 * VIA controllers report it active off, so we'll adjust the
-	 * bit value.  (It's not standardized in the UHCI spec.)
+	/*
+	 * Intel controllers report the OverCurrent bit active on.  VIA
+	 * and ZHAOXIN controllers report it active off, so we'll adjust
+	 * the bit value.  (It's not standardized in the UHCI spec.)
 	 */
-	if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_VIA)
+	if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_VIA ||
+			to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_ZHAOXIN)
 		uhci->oc_low = 1;
 
 	/* HP's server management chip requires a longer port reset delay. */
diff --git a/kernel/drivers/usb/host/xhci-debugfs.c b/kernel/drivers/usb/host/xhci-debugfs.c
index dc832dd..bd40cae 100644
--- a/kernel/drivers/usb/host/xhci-debugfs.c
+++ b/kernel/drivers/usb/host/xhci-debugfs.c
@@ -133,6 +133,7 @@
 	regset->regs = regs;
 	regset->nregs = nregs;
 	regset->base = hcd->regs + base;
+	regset->dev = hcd->self.controller;
 
 	debugfs_create_regset32((const char *)rgs->name, 0444, parent, regset);
 }
diff --git a/kernel/drivers/usb/host/xhci-mem.c b/kernel/drivers/usb/host/xhci-mem.c
index 9221838..4c5bf05 100644
--- a/kernel/drivers/usb/host/xhci-mem.c
+++ b/kernel/drivers/usb/host/xhci-mem.c
@@ -2236,7 +2236,7 @@
 {
 	u32 temp, port_offset, port_count;
 	int i;
-	u8 major_revision, minor_revision;
+	u8 major_revision, minor_revision, tmp_minor_revision;
 	struct xhci_hub *rhub;
 	struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
 	struct xhci_port_cap *port_cap;
@@ -2256,6 +2256,15 @@
 		 */
 		if (minor_revision > 0x00 && minor_revision < 0x10)
 			minor_revision <<= 4;
+		/*
+		 * Some zhaoxin's xHCI controller that follow usb3.1 spec
+		 * but only support Gen1.
+		 */
+		if (xhci->quirks & XHCI_ZHAOXIN_HOST) {
+			tmp_minor_revision = minor_revision;
+			minor_revision = 0;
+		}
+
 	} else if (major_revision <= 0x02) {
 		rhub = &xhci->usb2_rhub;
 	} else {
@@ -2265,10 +2274,6 @@
 		/* Ignoring port protocol we can't understand. FIXME */
 		return;
 	}
-	rhub->maj_rev = XHCI_EXT_PORT_MAJOR(temp);
-
-	if (rhub->min_rev < minor_revision)
-		rhub->min_rev = minor_revision;
 
 	/* Port offset and count in the third dword, see section 7.2 */
 	temp = readl(addr + 2);
@@ -2287,8 +2292,6 @@
 	if (xhci->num_port_caps > max_caps)
 		return;
 
-	port_cap->maj_rev = major_revision;
-	port_cap->min_rev = minor_revision;
 	port_cap->psi_count = XHCI_EXT_PORT_PSIC(temp);
 
 	if (port_cap->psi_count) {
@@ -2309,6 +2312,11 @@
 				  XHCI_EXT_PORT_PSIV(port_cap->psi[i - 1])))
 				port_cap->psi_uid_count++;
 
+			if (xhci->quirks & XHCI_ZHAOXIN_HOST &&
+			    major_revision == 0x03 &&
+			    XHCI_EXT_PORT_PSIV(port_cap->psi[i]) >= 5)
+				minor_revision = tmp_minor_revision;
+
 			xhci_dbg(xhci, "PSIV:%d PSIE:%d PLT:%d PFD:%d LP:%d PSIM:%d\n",
 				  XHCI_EXT_PORT_PSIV(port_cap->psi[i]),
 				  XHCI_EXT_PORT_PSIE(port_cap->psi[i]),
@@ -2318,6 +2326,15 @@
 				  XHCI_EXT_PORT_PSIM(port_cap->psi[i]));
 		}
 	}
+
+	rhub->maj_rev = major_revision;
+
+	if (rhub->min_rev < minor_revision)
+		rhub->min_rev = minor_revision;
+
+	port_cap->maj_rev = major_revision;
+	port_cap->min_rev = minor_revision;
+
 	/* cache usb2 port capabilities */
 	if (major_revision < 0x03 && xhci->num_ext_caps < max_caps)
 		xhci->ext_caps[xhci->num_ext_caps++] = temp;
@@ -2568,8 +2585,12 @@
 	 * and our use of dma addresses in the trb_address_map radix tree needs
 	 * TRB_SEGMENT_SIZE alignment, so we pick the greater alignment need.
 	 */
-	xhci->segment_pool = dma_pool_create("xHCI ring segments", dev,
-			TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, xhci->page_size);
+	if (xhci->quirks & XHCI_ZHAOXIN_TRB_FETCH)
+		xhci->segment_pool = dma_pool_create("xHCI ring segments", dev,
+				TRB_SEGMENT_SIZE * 2, TRB_SEGMENT_SIZE * 2, xhci->page_size * 2);
+	else
+		xhci->segment_pool = dma_pool_create("xHCI ring segments", dev,
+				TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, xhci->page_size);
 
 	/* See Table 46 and Note on Figure 55 */
 	xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev,
diff --git a/kernel/drivers/usb/host/xhci-mtk.c b/kernel/drivers/usb/host/xhci-mtk.c
index 09f2ddb..d47bc55 100644
--- a/kernel/drivers/usb/host/xhci-mtk.c
+++ b/kernel/drivers/usb/host/xhci-mtk.c
@@ -536,6 +536,7 @@
 	}
 
 	device_init_wakeup(dev, true);
+	dma_set_max_seg_size(dev, UINT_MAX);
 
 	xhci = hcd_to_xhci(hcd);
 	xhci->main_hcd = hcd;
diff --git a/kernel/drivers/usb/host/xhci-mvebu.c b/kernel/drivers/usb/host/xhci-mvebu.c
index 8ca1a23..eabccf2 100644
--- a/kernel/drivers/usb/host/xhci-mvebu.c
+++ b/kernel/drivers/usb/host/xhci-mvebu.c
@@ -33,7 +33,7 @@
 
 	/* Program each DRAM CS in a seperate window */
 	for (win = 0; win < dram->num_cs; win++) {
-		const struct mbus_dram_window *cs = dram->cs + win;
+		const struct mbus_dram_window *cs = &dram->cs[win];
 
 		writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
 		       (dram->mbus_dram_target_id << 4) | 1,
diff --git a/kernel/drivers/usb/host/xhci-pci.c b/kernel/drivers/usb/host/xhci-pci.c
index 9168b49..9bee82d 100644
--- a/kernel/drivers/usb/host/xhci-pci.c
+++ b/kernel/drivers/usb/host/xhci-pci.c
@@ -327,6 +327,18 @@
 	     pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4))
 		xhci->quirks |= XHCI_NO_SOFT_RETRY;
 
+	if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) {
+		xhci->quirks |= XHCI_ZHAOXIN_HOST;
+
+		if (pdev->device == 0x9202) {
+			xhci->quirks |= XHCI_RESET_ON_RESUME;
+			xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH;
+		}
+
+		if (pdev->device == 0x9203)
+			xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH;
+	}
+
 	/* xHC spec requires PCI devices to support D3hot and D3cold */
 	if (xhci->hci_version >= 0x120)
 		xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
@@ -451,6 +463,8 @@
 	if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW)
 		pm_runtime_allow(&dev->dev);
 
+	dma_set_max_seg_size(&dev->dev, UINT_MAX);
+
 	return 0;
 
 put_usb3_hcd:
diff --git a/kernel/drivers/usb/host/xhci-rcar.c b/kernel/drivers/usb/host/xhci-rcar.c
index 9888ba7..cfafa1c 100644
--- a/kernel/drivers/usb/host/xhci-rcar.c
+++ b/kernel/drivers/usb/host/xhci-rcar.c
@@ -75,7 +75,6 @@
 
 /* For soc_device_attribute */
 #define RCAR_XHCI_FIRMWARE_V2   BIT(0) /* FIRMWARE V2 */
-#define RCAR_XHCI_FIRMWARE_V3   BIT(1) /* FIRMWARE V3 */
 
 static const struct soc_device_attribute rcar_quirks_match[]  = {
 	{
@@ -147,8 +146,6 @@
 
 	if (quirks & RCAR_XHCI_FIRMWARE_V2)
 		firmware_name = XHCI_RCAR_FIRMWARE_NAME_V2;
-	else if (quirks & RCAR_XHCI_FIRMWARE_V3)
-		firmware_name = XHCI_RCAR_FIRMWARE_NAME_V3;
 	else
 		firmware_name = priv->firmware_name;
 
diff --git a/kernel/drivers/usb/host/xhci-ring.c b/kernel/drivers/usb/host/xhci-ring.c
index 00840c1..563fd2f 100644
--- a/kernel/drivers/usb/host/xhci-ring.c
+++ b/kernel/drivers/usb/host/xhci-ring.c
@@ -277,6 +277,26 @@
 	trace_xhci_inc_enq(ring);
 }
 
+static int xhci_num_trbs_to(struct xhci_segment *start_seg, union xhci_trb *start,
+			    struct xhci_segment *end_seg, union xhci_trb *end,
+			    unsigned int num_segs)
+{
+	union xhci_trb *last_on_seg;
+	int num = 0;
+	int i = 0;
+
+	do {
+		if (start_seg == end_seg && end >= start)
+			return num + (end - start);
+		last_on_seg = &start_seg->trbs[TRBS_PER_SEGMENT - 1];
+		num += last_on_seg - start;
+		start_seg = start_seg->next;
+		start = start_seg->trbs;
+	} while (i++ <= num_segs);
+
+	return -EINVAL;
+}
+
 /*
  * Check to see if there's room to enqueue num_trbs on the ring and make sure
  * enqueue pointer will not advance into dequeue segment. See rules above.
@@ -1182,7 +1202,10 @@
 	struct xhci_virt_ep *ep;
 	struct xhci_ring *ring;
 
-	ep = &xhci->devs[slot_id]->eps[ep_index];
+	ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+	if (!ep)
+		return;
+
 	if ((ep->ep_state & EP_HAS_STREAMS) ||
 			(ep->ep_state & EP_GETTING_NO_STREAMS)) {
 		int stream_id;
@@ -2198,6 +2221,7 @@
 		     u32 trb_comp_code)
 {
 	struct xhci_ep_ctx *ep_ctx;
+	int trbs_freed;
 
 	ep_ctx = xhci_get_ep_ctx(xhci, ep->vdev->out_ctx, ep->ep_index);
 
@@ -2269,9 +2293,15 @@
 	}
 
 	/* Update ring dequeue pointer */
+	trbs_freed = xhci_num_trbs_to(ep_ring->deq_seg, ep_ring->dequeue,
+				      td->last_trb_seg, td->last_trb,
+				      ep_ring->num_segs);
+	if (trbs_freed < 0)
+		xhci_dbg(xhci, "Failed to count freed trbs at TD finish\n");
+	else
+		ep_ring->num_trbs_free += trbs_freed;
 	ep_ring->dequeue = td->last_trb;
 	ep_ring->deq_seg = td->last_trb_seg;
-	ep_ring->num_trbs_free += td->num_trbs - 1;
 	inc_deq(xhci, ep_ring);
 
 	return xhci_td_cleanup(xhci, td, ep_ring, td->status);
diff --git a/kernel/drivers/usb/host/xhci-tegra.c b/kernel/drivers/usb/host/xhci-tegra.c
index 246a3d2..ffb0973 100644
--- a/kernel/drivers/usb/host/xhci-tegra.c
+++ b/kernel/drivers/usb/host/xhci-tegra.c
@@ -1042,15 +1042,15 @@
 	int err;
 
 	tegra->genpd_dev_host = dev_pm_domain_attach_by_name(dev, "xusb_host");
-	if (IS_ERR_OR_NULL(tegra->genpd_dev_host)) {
-		err = PTR_ERR(tegra->genpd_dev_host) ? : -ENODATA;
+	if (IS_ERR(tegra->genpd_dev_host)) {
+		err = PTR_ERR(tegra->genpd_dev_host);
 		dev_err(dev, "failed to get host pm-domain: %d\n", err);
 		return err;
 	}
 
 	tegra->genpd_dev_ss = dev_pm_domain_attach_by_name(dev, "xusb_ss");
-	if (IS_ERR_OR_NULL(tegra->genpd_dev_ss)) {
-		err = PTR_ERR(tegra->genpd_dev_ss) ? : -ENODATA;
+	if (IS_ERR(tegra->genpd_dev_ss)) {
+		err = PTR_ERR(tegra->genpd_dev_ss);
 		dev_err(dev, "failed to get superspeed pm-domain: %d\n", err);
 		return err;
 	}
@@ -1175,6 +1175,9 @@
 
 	mutex_unlock(&tegra->lock);
 
+	tegra->otg_usb3_port = tegra_xusb_padctl_get_usb3_companion(tegra->padctl,
+								    tegra->otg_usb2_port);
+
 	if (tegra->host_mode) {
 		/* switch to host mode */
 		if (tegra->otg_usb3_port >= 0) {
@@ -1243,9 +1246,6 @@
 	}
 
 	tegra->otg_usb2_port = tegra_xusb_get_usb2_port(tegra, usbphy);
-	tegra->otg_usb3_port = tegra_xusb_padctl_get_usb3_companion(
-							tegra->padctl,
-							tegra->otg_usb2_port);
 
 	tegra->host_mode = (usbphy->last_event == USB_EVENT_ID) ? true : false;
 
diff --git a/kernel/drivers/usb/host/xhci-trace.h b/kernel/drivers/usb/host/xhci-trace.h
index a5da020..5daf41b 100644
--- a/kernel/drivers/usb/host/xhci-trace.h
+++ b/kernel/drivers/usb/host/xhci-trace.h
@@ -80,20 +80,16 @@
 		__field(dma_addr_t, ctx_dma)
 		__field(u8 *, ctx_va)
 		__field(unsigned, ctx_ep_num)
-		__field(int, slot_id)
 		__dynamic_array(u32, ctx_data,
 			((HCC_64BYTE_CONTEXT(xhci->hcc_params) + 1) * 8) *
 			((ctx->type == XHCI_CTX_TYPE_INPUT) + ep_num + 1))
 	),
 	TP_fast_assign(
-		struct usb_device *udev;
 
-		udev = to_usb_device(xhci_to_hcd(xhci)->self.controller);
 		__entry->ctx_64 = HCC_64BYTE_CONTEXT(xhci->hcc_params);
 		__entry->ctx_type = ctx->type;
 		__entry->ctx_dma = ctx->dma;
 		__entry->ctx_va = ctx->bytes;
-		__entry->slot_id = udev->slot_id;
 		__entry->ctx_ep_num = ep_num;
 		memcpy(__get_dynamic_array(ctx_data), ctx->bytes,
 			((HCC_64BYTE_CONTEXT(xhci->hcc_params) + 1) * 32) *
diff --git a/kernel/drivers/usb/host/xhci.c b/kernel/drivers/usb/host/xhci.c
index cd344c5..f16dcdd 100644
--- a/kernel/drivers/usb/host/xhci.c
+++ b/kernel/drivers/usb/host/xhci.c
@@ -9,6 +9,9 @@
  */
 
 #include <linux/pci.h>
+#ifndef __GENKSYMS__	/* ANDROID: KABI CRC preservation hack */
+#include <linux/iommu.h>
+#endif
 #include <linux/iopoll.h>
 #include <linux/irq.h>
 #include <linux/log2.h>
@@ -223,6 +226,7 @@
 static void xhci_zero_64b_regs(struct xhci_hcd *xhci)
 {
 	struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
+	struct iommu_domain *domain;
 	int err, i;
 	u64 val;
 	u32 intrs;
@@ -241,7 +245,9 @@
 	 * an iommu. Doing anything when there is no iommu is definitely
 	 * unsafe...
 	 */
-	if (!(xhci->quirks & XHCI_ZERO_64B_REGS) || !device_iommu_mapped(dev))
+	domain = iommu_get_domain_for_dev(dev);
+	if (!(xhci->quirks & XHCI_ZERO_64B_REGS) || !domain ||
+	    domain->type == IOMMU_DOMAIN_IDENTITY)
 		return;
 
 	xhci_info(xhci, "Zeroing 64bit base registers, expecting fault\n");
@@ -692,6 +698,8 @@
 	}
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
 			"Finished xhci_run for USB2 roothub");
+
+	set_bit(HCD_FLAG_DEFER_RH_REGISTER, &hcd->flags);
 
 	xhci_dbc_init(xhci);
 
@@ -1258,7 +1266,7 @@
 		 * the first wake signalling failed, give it that chance.
 		 */
 		pending_portevent = xhci_pending_portevent(xhci);
-		if (!pending_portevent) {
+		if (!pending_portevent && !IS_ENABLED(CONFIG_ARCH_ROCKCHIP)) {
 			msleep(120);
 			pending_portevent = xhci_pending_portevent(xhci);
 		}
@@ -3865,6 +3873,7 @@
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 	struct xhci_virt_device *virt_dev;
 	struct xhci_slot_ctx *slot_ctx;
+	unsigned long flags;
 	int i, ret;
 
 	/*
@@ -3893,7 +3902,11 @@
 	}
 	virt_dev->udev = NULL;
 	xhci_disable_slot(xhci, udev->slot_id);
+
+	spin_lock_irqsave(&xhci->lock, flags);
 	xhci_free_virt_device(xhci, udev->slot_id);
+	spin_unlock_irqrestore(&xhci->lock, flags);
+
 }
 
 int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id)
diff --git a/kernel/drivers/usb/host/xhci.h b/kernel/drivers/usb/host/xhci.h
index deebf08..f02b81b 100644
--- a/kernel/drivers/usb/host/xhci.h
+++ b/kernel/drivers/usb/host/xhci.h
@@ -1908,7 +1908,9 @@
 #define XHCI_EP_CTX_BROKEN_DCS	BIT_ULL(42)
 #define XHCI_SUSPEND_RESUME_CLKS	BIT_ULL(43)
 #define XHCI_RESET_TO_DEFAULT	BIT_ULL(44)
-#define XHCI_U2_BROKEN_SUSPEND	BIT_ULL(45)
+#define XHCI_ZHAOXIN_TRB_FETCH	BIT_ULL(45)
+#define XHCI_ZHAOXIN_HOST	BIT_ULL(46)
+#define XHCI_U2_BROKEN_SUSPEND	BIT_ULL(47)
 
 	unsigned int		num_active_eps;
 	unsigned int		limit_active_eps;
diff --git a/kernel/drivers/usb/misc/iowarrior.c b/kernel/drivers/usb/misc/iowarrior.c
index 72a06af..51a5d62 100644
--- a/kernel/drivers/usb/misc/iowarrior.c
+++ b/kernel/drivers/usb/misc/iowarrior.c
@@ -817,7 +817,7 @@
 			break;
 
 		case USB_DEVICE_ID_CODEMERCS_IOW100:
-			dev->report_size = 13;
+			dev->report_size = 12;
 			break;
 		}
 	}
diff --git a/kernel/drivers/usb/misc/sisusbvga/sisusb.c b/kernel/drivers/usb/misc/sisusbvga/sisusb.c
index f08de33..8ed803c 100644
--- a/kernel/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/kernel/drivers/usb/misc/sisusbvga/sisusb.c
@@ -3014,6 +3014,20 @@
 	struct usb_device *dev = interface_to_usbdev(intf);
 	struct sisusb_usb_data *sisusb;
 	int retval = 0, i;
+	static const u8 ep_addresses[] = {
+		SISUSB_EP_GFX_IN | USB_DIR_IN,
+		SISUSB_EP_GFX_OUT | USB_DIR_OUT,
+		SISUSB_EP_GFX_BULK_OUT | USB_DIR_OUT,
+		SISUSB_EP_GFX_LBULK_OUT | USB_DIR_OUT,
+		SISUSB_EP_BRIDGE_IN | USB_DIR_IN,
+		SISUSB_EP_BRIDGE_OUT | USB_DIR_OUT,
+		0};
+
+	/* Are the expected endpoints present? */
+	if (!usb_check_bulk_endpoints(intf, ep_addresses)) {
+		dev_err(&intf->dev, "Invalid USB2VGA device\n");
+		return -EINVAL;
+	}
 
 	dev_info(&dev->dev, "USB2VGA dongle found at address %d\n",
 			dev->devnum);
diff --git a/kernel/drivers/usb/mtu3/mtu3_qmu.c b/kernel/drivers/usb/mtu3/mtu3_qmu.c
index 2ea3157..e655861 100644
--- a/kernel/drivers/usb/mtu3/mtu3_qmu.c
+++ b/kernel/drivers/usb/mtu3/mtu3_qmu.c
@@ -210,6 +210,7 @@
 	return ring->enqueue;
 }
 
+/* @dequeue may be NULL if ring is unallocated or freed */
 static struct qmu_gpd *advance_deq_gpd(struct mtu3_gpd_ring *ring)
 {
 	if (ring->dequeue < ring->end)
@@ -484,7 +485,7 @@
 	dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n",
 		__func__, epnum, gpd, gpd_current, ring->enqueue);
 
-	while (gpd != gpd_current && !GET_GPD_HWO(gpd)) {
+	while (gpd && gpd != gpd_current && !GET_GPD_HWO(gpd)) {
 
 		mreq = next_request(mep);
 
@@ -523,7 +524,7 @@
 	dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n",
 		__func__, epnum, gpd, gpd_current, ring->enqueue);
 
-	while (gpd != gpd_current && !GET_GPD_HWO(gpd)) {
+	while (gpd && gpd != gpd_current && !GET_GPD_HWO(gpd)) {
 
 		mreq = next_request(mep);
 
diff --git a/kernel/drivers/usb/musb/musb_gadget.c b/kernel/drivers/usb/musb/musb_gadget.c
index c273eee..8dc657c 100644
--- a/kernel/drivers/usb/musb/musb_gadget.c
+++ b/kernel/drivers/usb/musb/musb_gadget.c
@@ -1628,8 +1628,6 @@
 {
 	struct musb	*musb = gadget_to_musb(gadget);
 
-	if (!musb->xceiv->set_power)
-		return -EOPNOTSUPP;
 	return usb_phy_set_power(musb->xceiv, mA);
 }
 
diff --git a/kernel/drivers/usb/phy/phy-mxs-usb.c b/kernel/drivers/usb/phy/phy-mxs-usb.c
index 67b39dc..70e2333 100644
--- a/kernel/drivers/usb/phy/phy-mxs-usb.c
+++ b/kernel/drivers/usb/phy/phy-mxs-usb.c
@@ -388,14 +388,8 @@
 
 static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy)
 {
-	void __iomem *base = mxs_phy->phy.io_priv;
-	u32 phyctrl = readl(base + HW_USBPHY_CTRL);
-
-	if (IS_ENABLED(CONFIG_USB_OTG) &&
-			!(phyctrl & BM_USBPHY_CTRL_OTG_ID_VALUE))
-		return true;
-
-	return false;
+	return IS_ENABLED(CONFIG_USB_OTG) &&
+		mxs_phy->phy.last_event == USB_EVENT_ID;
 }
 
 static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
diff --git a/kernel/drivers/usb/phy/phy-tahvo.c b/kernel/drivers/usb/phy/phy-tahvo.c
index a3e043e..d0672b6 100644
--- a/kernel/drivers/usb/phy/phy-tahvo.c
+++ b/kernel/drivers/usb/phy/phy-tahvo.c
@@ -395,7 +395,7 @@
 
 	tu->irq = ret = platform_get_irq(pdev, 0);
 	if (ret < 0)
-		return ret;
+		goto err_remove_phy;
 	ret = request_threaded_irq(tu->irq, NULL, tahvo_usb_vbus_interrupt,
 				   IRQF_ONESHOT,
 				   "tahvo-vbus", tu);
diff --git a/kernel/drivers/usb/roles/class.c b/kernel/drivers/usb/roles/class.c
index 33b637d..5cc2027 100644
--- a/kernel/drivers/usb/roles/class.c
+++ b/kernel/drivers/usb/roles/class.c
@@ -106,10 +106,13 @@
 	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);
 }
 
diff --git a/kernel/drivers/usb/serial/cp210x.c b/kernel/drivers/usb/serial/cp210x.c
index 8a4a0d4..045e241 100644
--- a/kernel/drivers/usb/serial/cp210x.c
+++ b/kernel/drivers/usb/serial/cp210x.c
@@ -64,6 +64,7 @@
 	{ USB_DEVICE(0x0846, 0x1100) }, /* NetGear Managed Switch M4100 series, M5300 series, M7100 series */
 	{ USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */
 	{ USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */
+	{ USB_DEVICE(0x0908, 0x0070) }, /* Siemens SCALANCE LPE-9000 USB Serial Console */
 	{ USB_DEVICE(0x0908, 0x01FF) }, /* Siemens RUGGEDCOM USB Serial Console */
 	{ USB_DEVICE(0x0988, 0x0578) }, /* Teraoka AD2000 */
 	{ USB_DEVICE(0x0B00, 0x3070) }, /* Ingenico 3070 */
@@ -123,6 +124,7 @@
 	{ USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */
 	{ USB_DEVICE(0x10C4, 0x8281) }, /* Nanotec Plug & Drive */
 	{ USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */
+	{ USB_DEVICE(0x10C4, 0x82AA) }, /* Silicon Labs IFS-USB-DATACABLE used with Quint UPS */
 	{ USB_DEVICE(0x10C4, 0x82EF) }, /* CESINEL FALCO 6105 AC Power Supply */
 	{ USB_DEVICE(0x10C4, 0x82F1) }, /* CESINEL MEDCAL EFD Earth Fault Detector */
 	{ USB_DEVICE(0x10C4, 0x82F2) }, /* CESINEL MEDCAL ST Network Analyzer */
diff --git a/kernel/drivers/usb/serial/option.c b/kernel/drivers/usb/serial/option.c
index 5636b8f..83567e6 100644
--- a/kernel/drivers/usb/serial/option.c
+++ b/kernel/drivers/usb/serial/option.c
@@ -248,18 +248,31 @@
 #define QUECTEL_VENDOR_ID			0x2c7c
 /* These Quectel products use Quectel's vendor ID */
 #define QUECTEL_PRODUCT_EC21			0x0121
+#define QUECTEL_PRODUCT_EM061K_LTA		0x0123
+#define QUECTEL_PRODUCT_EM061K_LMS		0x0124
 #define QUECTEL_PRODUCT_EC25			0x0125
+#define QUECTEL_PRODUCT_EM060K_128		0x0128
 #define QUECTEL_PRODUCT_EG91			0x0191
 #define QUECTEL_PRODUCT_EG95			0x0195
 #define QUECTEL_PRODUCT_BG96			0x0296
 #define QUECTEL_PRODUCT_EP06			0x0306
 #define QUECTEL_PRODUCT_EM05G			0x030a
 #define QUECTEL_PRODUCT_EM060K			0x030b
+#define QUECTEL_PRODUCT_EM05G_CS		0x030c
+#define QUECTEL_PRODUCT_EM05GV2			0x030e
+#define QUECTEL_PRODUCT_EM05CN_SG		0x0310
 #define QUECTEL_PRODUCT_EM05G_SG		0x0311
+#define QUECTEL_PRODUCT_EM05CN			0x0312
+#define QUECTEL_PRODUCT_EM05G_GR		0x0313
+#define QUECTEL_PRODUCT_EM05G_RS		0x0314
 #define QUECTEL_PRODUCT_EM12			0x0512
 #define QUECTEL_PRODUCT_RM500Q			0x0800
 #define QUECTEL_PRODUCT_RM520N			0x0801
+#define QUECTEL_PRODUCT_EC200U			0x0901
 #define QUECTEL_PRODUCT_EC200S_CN		0x6002
+#define QUECTEL_PRODUCT_EC200A			0x6005
+#define QUECTEL_PRODUCT_EM061K_LWW		0x6008
+#define QUECTEL_PRODUCT_EM061K_LCN		0x6009
 #define QUECTEL_PRODUCT_EC200T			0x6026
 #define QUECTEL_PRODUCT_RM500K			0x7001
 
@@ -396,6 +409,8 @@
 #define LONGCHEER_VENDOR_ID			0x1c9e
 
 /* 4G Systems products */
+/* This one was sold as the VW and Skoda "Carstick LTE" */
+#define FOUR_G_SYSTEMS_PRODUCT_CARSTICK_LTE	0x7605
 /* This is the 4G XS Stick W14 a.k.a. Mobilcom Debitel Surf-Stick *
  * It seems to contain a Qualcomm QSC6240/6290 chipset            */
 #define FOUR_G_SYSTEMS_PRODUCT_W14		0x9603
@@ -586,6 +601,11 @@
 /* Sierra Wireless products */
 #define SIERRA_VENDOR_ID			0x1199
 #define SIERRA_PRODUCT_EM9191			0x90d3
+
+/* UNISOC (Spreadtrum) products */
+#define UNISOC_VENDOR_ID			0x1782
+/* TOZED LT70-C based on UNISOC SL8563 uses UNISOC's vendor ID */
+#define TOZED_PRODUCT_LT70C			0x4055
 
 /* Device flags */
 
@@ -1134,6 +1154,10 @@
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x90fa),
 	  .driver_info = RSVD(3) },
 	/* u-blox products */
+	{ USB_DEVICE(UBLOX_VENDOR_ID, 0x1311) },	/* u-blox LARA-R6 01B */
+	{ USB_DEVICE(UBLOX_VENDOR_ID, 0x1312),		/* u-blox LARA-R6 01B (RMNET) */
+	  .driver_info = RSVD(4) },
+	{ USB_DEVICE_INTERFACE_CLASS(UBLOX_VENDOR_ID, 0x1313, 0xff) },	/* u-blox LARA-R6 01B (ECM) */
 	{ USB_DEVICE(UBLOX_VENDOR_ID, 0x1341) },	/* u-blox LARA-L6 */
 	{ USB_DEVICE(UBLOX_VENDOR_ID, 0x1342),		/* u-blox LARA-L6 (RMNET) */
 	  .driver_info = RSVD(4) },
@@ -1159,13 +1183,40 @@
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff),
 	  .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) },
+	{ USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05CN, 0xff),
+	  .driver_info = RSVD(6) | ZLP },
+	{ USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05CN_SG, 0xff),
+	  .driver_info = RSVD(6) | ZLP },
 	{ USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G, 0xff),
+	  .driver_info = RSVD(6) | ZLP },
+	{ USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_GR, 0xff),
+	  .driver_info = RSVD(6) | ZLP },
+	{ USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05GV2, 0xff),
+	  .driver_info = RSVD(4) | ZLP },
+	{ USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_CS, 0xff),
+	  .driver_info = RSVD(6) | ZLP },
+	{ USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_RS, 0xff),
 	  .driver_info = RSVD(6) | ZLP },
 	{ USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_SG, 0xff),
 	  .driver_info = RSVD(6) | ZLP },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x30) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x30) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0x00, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x30) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0x00, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LMS, 0xff, 0xff, 0x30) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LMS, 0xff, 0x00, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LMS, 0xff, 0xff, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LTA, 0xff, 0xff, 0x30) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LTA, 0xff, 0x00, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LTA, 0xff, 0xff, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LWW, 0xff, 0xff, 0x30) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LWW, 0xff, 0x00, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LWW, 0xff, 0xff, 0x40) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff),
 	  .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) },
@@ -1180,6 +1231,10 @@
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0xff, 0x30) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0x40) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0900, 0xff, 0, 0), /* RM500U-CN */
+	  .driver_info = ZLP },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200A, 0xff, 0, 0) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200U, 0xff, 0, 0) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) },
@@ -1281,6 +1336,14 @@
 	  .driver_info = NCTRL(0) | RSVD(1) },
 	{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff),	/* Telit FN990 (PCIe) */
 	  .driver_info = RSVD(0) },
+	{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1080, 0xff),	/* Telit FE990 (rmnet) */
+	  .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
+	{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1081, 0xff),	/* Telit FE990 (MBIM) */
+	  .driver_info = NCTRL(0) | RSVD(1) },
+	{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1082, 0xff),	/* Telit FE990 (RNDIS) */
+	  .driver_info = NCTRL(2) | RSVD(3) },
+	{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1083, 0xff),	/* Telit FE990 (ECM) */
+	  .driver_info = NCTRL(0) | RSVD(1) },
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
 	  .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
@@ -1959,6 +2022,8 @@
 	  .driver_info = RSVD(2) },
 	{ USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
 	{ USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
+	{ USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_CARSTICK_LTE),
+	  .driver_info = RSVD(0) },
 	{ USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
 	  .driver_info = NCTRL(0) | NCTRL(1) },
 	{ USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W100),
@@ -2170,6 +2235,10 @@
 	  .driver_info = RSVD(0) | RSVD(1) | RSVD(6) },
 	{ USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe0db, 0xff),			/* Foxconn T99W265 MBIM */
 	  .driver_info = RSVD(3) },
+	{ USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe0ee, 0xff),			/* Foxconn T99W368 MBIM */
+	  .driver_info = RSVD(3) },
+	{ USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe0f0, 0xff),			/* Foxconn T99W373 MBIM */
+	  .driver_info = RSVD(3) },
 	{ USB_DEVICE(0x1508, 0x1001),						/* Fibocom NL668 (IOT version) */
 	  .driver_info = RSVD(4) | RSVD(5) | RSVD(6) },
 	{ USB_DEVICE(0x1782, 0x4d10) },						/* Fibocom L610 (AT mode) */
@@ -2194,6 +2263,7 @@
 	{ USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
 	{ } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
diff --git a/kernel/drivers/usb/serial/usb-serial-simple.c b/kernel/drivers/usb/serial/usb-serial-simple.c
index 4c67478..24b8772 100644
--- a/kernel/drivers/usb/serial/usb-serial-simple.c
+++ b/kernel/drivers/usb/serial/usb-serial-simple.c
@@ -38,22 +38,17 @@
 	{ USB_DEVICE(0x0a21, 0x8001) }	/* MMT-7305WW */
 DEVICE(carelink, CARELINK_IDS);
 
-/* ZIO Motherboard USB driver */
-#define ZIO_IDS()			\
-	{ USB_DEVICE(0x1CBE, 0x0103) }
-DEVICE(zio, ZIO_IDS);
-
-/* Funsoft Serial USB driver */
-#define FUNSOFT_IDS()			\
-	{ USB_DEVICE(0x1404, 0xcddc) }
-DEVICE(funsoft, FUNSOFT_IDS);
-
 /* Infineon Flashloader driver */
 #define FLASHLOADER_IDS()		\
 	{ USB_DEVICE_INTERFACE_CLASS(0x058b, 0x0041, USB_CLASS_CDC_DATA) }, \
 	{ USB_DEVICE(0x8087, 0x0716) }, \
 	{ USB_DEVICE(0x8087, 0x0801) }
 DEVICE(flashloader, FLASHLOADER_IDS);
+
+/* Funsoft Serial USB driver */
+#define FUNSOFT_IDS()			\
+	{ USB_DEVICE(0x1404, 0xcddc) }
+DEVICE(funsoft, FUNSOFT_IDS);
 
 /* Google Serial USB SubClass */
 #define GOOGLE_IDS()						\
@@ -63,15 +58,20 @@
 					0x01) }
 DEVICE(google, GOOGLE_IDS);
 
+/* HP4x (48/49) Generic Serial driver */
+#define HP4X_IDS()			\
+	{ USB_DEVICE(0x03f0, 0x0121) }
+DEVICE(hp4x, HP4X_IDS);
+
+/* KAUFMANN RKS+CAN VCP */
+#define KAUFMANN_IDS()			\
+	{ USB_DEVICE(0x16d0, 0x0870) }
+DEVICE(kaufmann, KAUFMANN_IDS);
+
 /* Libtransistor USB console */
 #define LIBTRANSISTOR_IDS()			\
 	{ USB_DEVICE(0x1209, 0x8b00) }
 DEVICE(libtransistor, LIBTRANSISTOR_IDS);
-
-/* ViVOpay USB Serial Driver */
-#define VIVOPAY_IDS()			\
-	{ USB_DEVICE(0x1d5f, 0x1004) }	/* ViVOpay 8800 */
-DEVICE(vivopay, VIVOPAY_IDS);
 
 /* Motorola USB Phone driver */
 #define MOTO_IDS()			\
@@ -101,10 +101,10 @@
 	{ USB_DEVICE(0x09d7, 0x0100) }	/* NovAtel FlexPack GPS */
 DEVICE_N(novatel_gps, NOVATEL_IDS, 3);
 
-/* HP4x (48/49) Generic Serial driver */
-#define HP4X_IDS()			\
-	{ USB_DEVICE(0x03f0, 0x0121) }
-DEVICE(hp4x, HP4X_IDS);
+/* Siemens USB/MPI adapter */
+#define SIEMENS_IDS()			\
+	{ USB_DEVICE(0x908, 0x0004) }
+DEVICE(siemens_mpi, SIEMENS_IDS);
 
 /* Suunto ANT+ USB Driver */
 #define SUUNTO_IDS()			\
@@ -112,45 +112,52 @@
 	{ USB_DEVICE(0x0fcf, 0x1009) } /* Dynastream ANT USB-m Stick */
 DEVICE(suunto, SUUNTO_IDS);
 
-/* Siemens USB/MPI adapter */
-#define SIEMENS_IDS()			\
-	{ USB_DEVICE(0x908, 0x0004) }
-DEVICE(siemens_mpi, SIEMENS_IDS);
+/* ViVOpay USB Serial Driver */
+#define VIVOPAY_IDS()			\
+	{ USB_DEVICE(0x1d5f, 0x1004) }	/* ViVOpay 8800 */
+DEVICE(vivopay, VIVOPAY_IDS);
+
+/* ZIO Motherboard USB driver */
+#define ZIO_IDS()			\
+	{ USB_DEVICE(0x1CBE, 0x0103) }
+DEVICE(zio, ZIO_IDS);
 
 /* All of the above structures mushed into two lists */
 static struct usb_serial_driver * const serial_drivers[] = {
 	&carelink_device,
-	&zio_device,
-	&funsoft_device,
 	&flashloader_device,
+	&funsoft_device,
 	&google_device,
+	&hp4x_device,
+	&kaufmann_device,
 	&libtransistor_device,
-	&vivopay_device,
 	&moto_modem_device,
 	&motorola_tetra_device,
 	&nokia_device,
 	&novatel_gps_device,
-	&hp4x_device,
-	&suunto_device,
 	&siemens_mpi_device,
+	&suunto_device,
+	&vivopay_device,
+	&zio_device,
 	NULL
 };
 
 static const struct usb_device_id id_table[] = {
 	CARELINK_IDS(),
-	ZIO_IDS(),
-	FUNSOFT_IDS(),
 	FLASHLOADER_IDS(),
+	FUNSOFT_IDS(),
 	GOOGLE_IDS(),
+	HP4X_IDS(),
+	KAUFMANN_IDS(),
 	LIBTRANSISTOR_IDS(),
-	VIVOPAY_IDS(),
 	MOTO_IDS(),
 	MOTOROLA_TETRA_IDS(),
 	NOKIA_IDS(),
 	NOVATEL_IDS(),
-	HP4X_IDS(),
-	SUUNTO_IDS(),
 	SIEMENS_IDS(),
+	SUUNTO_IDS(),
+	VIVOPAY_IDS(),
+	ZIO_IDS(),
 	{ },
 };
 MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/kernel/drivers/usb/storage/alauda.c b/kernel/drivers/usb/storage/alauda.c
index 20b857e..dcc4778 100644
--- a/kernel/drivers/usb/storage/alauda.c
+++ b/kernel/drivers/usb/storage/alauda.c
@@ -318,7 +318,8 @@
 	rc = usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe,
 		command, 0xc0, 0, 1, data, 2);
 
-	usb_stor_dbg(us, "Media status %02X %02X\n", data[0], data[1]);
+	if (rc == USB_STOR_XFER_GOOD)
+		usb_stor_dbg(us, "Media status %02X %02X\n", data[0], data[1]);
 
 	return rc;
 }
@@ -438,6 +439,8 @@
 		+ 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;
@@ -452,9 +455,14 @@
 static int alauda_check_media(struct us_data *us)
 {
 	struct alauda_info *info = (struct alauda_info *) us->extra;
-	unsigned char status[2];
+	unsigned char *status = us->iobuf;
+	int rc;
 
-	alauda_get_media_status(us, status);
+	rc = alauda_get_media_status(us, status);
+	if (rc != USB_STOR_XFER_GOOD) {
+		status[0] = 0xF0;	/* Pretend there's no media */
+		status[1] = 0;
+	}
 
 	/* Check for no media or door open */
 	if ((status[0] & 0x80) || ((status[0] & 0x1F) == 0x10)
diff --git a/kernel/drivers/usb/storage/ene_ub6250.c b/kernel/drivers/usb/storage/ene_ub6250.c
index c9ce1c2..737398f 100644
--- a/kernel/drivers/usb/storage/ene_ub6250.c
+++ b/kernel/drivers/usb/storage/ene_ub6250.c
@@ -938,7 +938,7 @@
 	struct ms_lib_type_extdat ExtraData;
 	struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
 
-	PageBuffer = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL);
+	PageBuffer = kzalloc(MS_BYTES_PER_PAGE * 2, GFP_KERNEL);
 	if (PageBuffer == NULL)
 		return (u32)-1;
 
diff --git a/kernel/drivers/usb/storage/scsiglue.c b/kernel/drivers/usb/storage/scsiglue.c
index a345f29..9cffdd4 100644
--- a/kernel/drivers/usb/storage/scsiglue.c
+++ b/kernel/drivers/usb/storage/scsiglue.c
@@ -411,22 +411,25 @@
  ***********************************************************************/
 
 /* Command timeout and abort */
-static int command_abort(struct scsi_cmnd *srb)
+static int command_abort_matching(struct us_data *us, struct scsi_cmnd *srb_match)
 {
-	struct us_data *us = host_to_us(srb->device->host);
-
-	usb_stor_dbg(us, "%s called\n", __func__);
-
 	/*
 	 * us->srb together with the TIMED_OUT, RESETTING, and ABORTING
 	 * bits are protected by the host lock.
 	 */
 	scsi_lock(us_to_host(us));
 
-	/* Is this command still active? */
-	if (us->srb != srb) {
+	/* is there any active pending command to abort ? */
+	if (!us->srb) {
 		scsi_unlock(us_to_host(us));
 		usb_stor_dbg(us, "-- nothing to abort\n");
+		return SUCCESS;
+	}
+
+	/* Does the command match the passed srb if any ? */
+	if (srb_match && us->srb != srb_match) {
+		scsi_unlock(us_to_host(us));
+		usb_stor_dbg(us, "-- pending command mismatch\n");
 		return FAILED;
 	}
 
@@ -449,6 +452,14 @@
 	return SUCCESS;
 }
 
+static int command_abort(struct scsi_cmnd *srb)
+{
+	struct us_data *us = host_to_us(srb->device->host);
+
+	usb_stor_dbg(us, "%s called\n", __func__);
+	return command_abort_matching(us, srb);
+}
+
 /*
  * This invokes the transport reset mechanism to reset the state of the
  * device
@@ -460,6 +471,9 @@
 
 	usb_stor_dbg(us, "%s called\n", __func__);
 
+	/* abort any pending command before reset */
+	command_abort_matching(us, NULL);
+
 	/* lock the device pointers and do the reset */
 	mutex_lock(&(us->dev_mutex));
 	result = us->transport_reset(us);
diff --git a/kernel/drivers/usb/storage/uas-detect.h b/kernel/drivers/usb/storage/uas-detect.h
index 3f720fa..d73282c 100644
--- a/kernel/drivers/usb/storage/uas-detect.h
+++ b/kernel/drivers/usb/storage/uas-detect.h
@@ -116,6 +116,19 @@
 	if (le16_to_cpu(udev->descriptor.idVendor) == 0x0bc2)
 		flags |= US_FL_NO_ATA_1X;
 
+	/*
+	 * RTL9210-based enclosure from HIKSEMI, MD202 reportedly have issues
+	 * with UAS.  This isn't distinguishable with just idVendor and
+	 * idProduct, use manufacturer and product too.
+	 *
+	 * Reported-by: Hongling Zeng <zenghongling@kylinos.cn>
+	 */
+	if (le16_to_cpu(udev->descriptor.idVendor) == 0x0bda &&
+			le16_to_cpu(udev->descriptor.idProduct) == 0x9210 &&
+			(udev->manufacturer && !strcmp(udev->manufacturer, "HIKSEMI")) &&
+			(udev->product && !strcmp(udev->product, "MD202")))
+		flags |= US_FL_IGNORE_UAS;
+
 	usb_stor_adjust_quirks(udev, &flags);
 
 	if (flags & US_FL_IGNORE_UAS) {
diff --git a/kernel/drivers/usb/storage/unusual_uas.h b/kernel/drivers/usb/storage/unusual_uas.h
index d009e69..4d4fad2 100644
--- a/kernel/drivers/usb/storage/unusual_uas.h
+++ b/kernel/drivers/usb/storage/unusual_uas.h
@@ -89,13 +89,6 @@
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_NO_REPORT_LUNS),
 
-/* Reported-by: Hongling Zeng <zenghongling@kylinos.cn> */
-UNUSUAL_DEV(0x0bda, 0x9210, 0x0000, 0x9999,
-		"Hiksemi",
-		"External HDD",
-		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
-		US_FL_IGNORE_UAS),
-
 /* Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> */
 UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999,
 		"Initio Corporation",
@@ -124,11 +117,12 @@
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_BROKEN_FUA),
 
+/* Reported by: Yaroslav Furman <yaro330@gmail.com> */
 UNUSUAL_DEV(0x152d, 0x0583, 0x0000, 0x9999,
 		"JMicron",
-		"JMS583",
+		"JMS583Gen 2",
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
-		US_FL_BROKEN_FUA | US_FL_NO_REPORT_OPCODES),
+		US_FL_NO_REPORT_OPCODES),
 
 /* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */
 UNUSUAL_DEV(0x154b, 0xf00b, 0x0000, 0x9999,
diff --git a/kernel/drivers/usb/typec/altmodes/displayport.c b/kernel/drivers/usb/typec/altmodes/displayport.c
index 8769cab..bcc1db4 100644
--- a/kernel/drivers/usb/typec/altmodes/displayport.c
+++ b/kernel/drivers/usb/typec/altmodes/displayport.c
@@ -114,8 +114,12 @@
 		if (dp->data.status & DP_STATUS_PREFER_MULTI_FUNC &&
 		    pin_assign & DP_PIN_ASSIGN_MULTI_FUNC_MASK)
 			pin_assign &= DP_PIN_ASSIGN_MULTI_FUNC_MASK;
-		else if (pin_assign & DP_PIN_ASSIGN_DP_ONLY_MASK)
+		else if (pin_assign & DP_PIN_ASSIGN_DP_ONLY_MASK) {
 			pin_assign &= DP_PIN_ASSIGN_DP_ONLY_MASK;
+			/* Default to pin assign C if available */
+			if (pin_assign & BIT(DP_PIN_ASSIGN_C))
+				pin_assign = BIT(DP_PIN_ASSIGN_C);
+		}
 
 		/*
 		 * DFP_U never selects Pin Assignment E when Pin Assignment C
@@ -444,6 +448,18 @@
 	[DP_PIN_ASSIGN_F] = "F",
 };
 
+/*
+ * Helper function to extract a peripheral's currently supported
+ * Pin Assignments from its DisplayPort alternate mode state.
+ */
+static u8 get_current_pin_assignments(struct dp_altmode *dp)
+{
+	if (DP_CONF_CURRENTLY(dp->data.conf) == DP_CONF_DFP_D)
+		return DP_CAP_PIN_ASSIGN_DFP_D(dp->alt->vdo);
+	else
+		return DP_CAP_PIN_ASSIGN_UFP_D(dp->alt->vdo);
+}
+
 static ssize_t
 pin_assignment_store(struct device *dev, struct device_attribute *attr,
 		     const char *buf, size_t size)
@@ -470,7 +486,7 @@
 		goto out_unlock;
 	}
 
-	assignments = DP_CAP_PIN_ASSIGN(dp->alt->vdo);
+	assignments = get_current_pin_assignments(dp);
 
 	if (!(DP_CONF_GET_PIN_ASSIGN(conf) & assignments)) {
 		ret = -EINVAL;
@@ -507,7 +523,7 @@
 
 	cur = get_count_order(DP_CONF_GET_PIN_ASSIGN(dp->data.conf));
 
-	assignments = DP_CAP_PIN_ASSIGN(dp->alt->vdo);
+	assignments = get_current_pin_assignments(dp);
 
 	for (i = 0; assignments; assignments >>= 1, i++) {
 		if (assignments & 1) {
@@ -521,6 +537,10 @@
 	}
 
 	mutex_unlock(&dp->lock);
+
+	/* get_current_pin_assignments can return 0 when no matching pin assignments are found */
+	if (len == 0)
+		len++;
 
 	buf[len - 1] = '\n';
 	return len;
@@ -548,10 +568,10 @@
 	/* FIXME: Port can only be DFP_U. */
 
 	/* Make sure we have compatiple pin configurations */
-	if (!(DP_CAP_DFP_D_PIN_ASSIGN(port->vdo) &
-	      DP_CAP_UFP_D_PIN_ASSIGN(alt->vdo)) &&
-	    !(DP_CAP_UFP_D_PIN_ASSIGN(port->vdo) &
-	      DP_CAP_DFP_D_PIN_ASSIGN(alt->vdo)))
+	if (!(DP_CAP_PIN_ASSIGN_DFP_D(port->vdo) &
+	      DP_CAP_PIN_ASSIGN_UFP_D(alt->vdo)) &&
+	    !(DP_CAP_PIN_ASSIGN_UFP_D(port->vdo) &
+	      DP_CAP_PIN_ASSIGN_DFP_D(alt->vdo)))
 		return -ENODEV;
 
 	ret = sysfs_create_group(&alt->dev.kobj, &dp_altmode_group);
diff --git a/kernel/drivers/usb/typec/bus.c b/kernel/drivers/usb/typec/bus.c
index e8ddb81..7994b46 100644
--- a/kernel/drivers/usb/typec/bus.c
+++ b/kernel/drivers/usb/typec/bus.c
@@ -132,7 +132,7 @@
 	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 */
@@ -152,12 +152,20 @@
  *
  * Notifies the partner of @adev about Attention command.
  */
-void typec_altmode_attention(struct typec_altmode *adev, u32 vdo)
+int typec_altmode_attention(struct typec_altmode *adev, u32 vdo)
 {
-	struct typec_altmode *pdev = &to_altmode(adev)->partner->adev;
+	struct altmode *partner = to_altmode(adev)->partner;
+	struct typec_altmode *pdev;
+
+	if (!partner)
+		return -ENODEV;
+
+	pdev = &partner->adev;
 
 	if (pdev->ops && pdev->ops->attention)
 		pdev->ops->attention(pdev, vdo);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(typec_altmode_attention);
 
diff --git a/kernel/drivers/usb/typec/class.c b/kernel/drivers/usb/typec/class.c
index cb32a83..50247e9 100644
--- a/kernel/drivers/usb/typec/class.c
+++ b/kernel/drivers/usb/typec/class.c
@@ -1984,7 +1984,6 @@
 }
 EXPORT_SYMBOL_GPL(typec_port_register_altmode);
 
-#ifdef CONFIG_NO_GKI
 void typec_port_register_altmodes(struct typec_port *port,
 	const struct typec_altmode_ops *ops, void *drvdata,
 	struct typec_altmode **altmodes, size_t n)
@@ -2038,7 +2037,6 @@
 	}
 }
 EXPORT_SYMBOL_GPL(typec_port_register_altmodes);
-#endif /* CONFIG_NO_GKI */
 
 /**
  * typec_register_port - Register a USB Type-C Port
diff --git a/kernel/drivers/usb/typec/tcpm/tcpci.c b/kernel/drivers/usb/typec/tcpm/tcpci.c
index 17cea37..8fb6aaa 100644
--- a/kernel/drivers/usb/typec/tcpm/tcpci.c
+++ b/kernel/drivers/usb/typec/tcpm/tcpci.c
@@ -642,6 +642,10 @@
 	if (time_after(jiffies, timeout))
 		return -ETIMEDOUT;
 
+	ret = tcpci_write16(tcpci, TCPC_FAULT_STATUS, TCPC_FAULT_STATUS_ALL_REG_RST_TO_DEFAULT);
+	if (ret < 0)
+		return ret;
+
 	/* Handle vendor init */
 	if (tcpci->data->init) {
 		ret = tcpci->data->init(tcpci, tcpci->data);
@@ -844,8 +848,10 @@
 		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;
 }
@@ -854,6 +860,7 @@
 void tcpci_unregister_port(struct tcpci *tcpci)
 {
 	tcpm_unregister_port(tcpci->port);
+	fwnode_handle_put(tcpci->tcpc.fwnode);
 }
 EXPORT_SYMBOL_GPL(tcpci_unregister_port);
 
diff --git a/kernel/drivers/usb/typec/tcpm/tcpci.h b/kernel/drivers/usb/typec/tcpm/tcpci.h
index b2edd45..fa87afb 100644
--- a/kernel/drivers/usb/typec/tcpm/tcpci.h
+++ b/kernel/drivers/usb/typec/tcpm/tcpci.h
@@ -102,6 +102,7 @@
 #define TCPC_POWER_STATUS_SINKING_VBUS	BIT(0)
 
 #define TCPC_FAULT_STATUS		0x1f
+#define TCPC_FAULT_STATUS_ALL_REG_RST_TO_DEFAULT BIT(7)
 
 #define TCPC_ALERT_EXTENDED		0x21
 
diff --git a/kernel/drivers/usb/typec/tcpm/tcpm.c b/kernel/drivers/usb/typec/tcpm/tcpm.c
index 141a143..f474eeb 100644
--- a/kernel/drivers/usb/typec/tcpm/tcpm.c
+++ b/kernel/drivers/usb/typec/tcpm/tcpm.c
@@ -1447,10 +1447,18 @@
 static void tcpm_queue_vdm(struct tcpm_port *port, const u32 header,
 			   const u32 *data, int cnt)
 {
+	u32 vdo_hdr = port->vdo_data[0];
+
 	WARN_ON(!mutex_is_locked(&port->lock));
 
-	/* Make sure we are not still processing a previous VDM packet */
-	WARN_ON(port->vdm_state > VDM_STATE_DONE);
+	/* If is sending discover_identity, handle received message first */
+	if (PD_VDO_SVDM(vdo_hdr) && PD_VDO_CMD(vdo_hdr) == CMD_DISCOVER_IDENT) {
+		port->send_discover = true;
+		mod_send_discover_delayed_work(port, SEND_DISCOVER_RETRY_MS);
+	} else {
+		/* Make sure we are not still processing a previous VDM packet */
+		WARN_ON(port->vdm_state > VDM_STATE_DONE);
+	}
 
 	port->vdo_count = cnt + 1;
 	port->vdo_data[0] = header;
@@ -1540,7 +1548,7 @@
 	 * 0x0000 in the last VDO, so we need to break the Discover SVIDs
 	 * request and return false here.
 	 */
-	return cnt == 7 ? true : false;
+	return cnt == 7;
 abort:
 	tcpm_log(port, "SVID_DISCOVERY_MAX(%d) too low!", SVID_DISCOVERY_MAX);
 	return false;
@@ -1901,7 +1909,8 @@
 			}
 			break;
 		case ADEV_ATTENTION:
-			typec_altmode_attention(adev, p[1]);
+			if (typec_altmode_attention(adev, p[1]))
+				tcpm_log(port, "typec_altmode_attention no port partner altmode");
 			break;
 		}
 	}
@@ -1994,11 +2003,13 @@
 			switch (PD_VDO_CMD(vdo_hdr)) {
 			case CMD_DISCOVER_IDENT:
 				res = tcpm_ams_start(port, DISCOVER_IDENTITY);
-				if (res == 0)
+				if (res == 0) {
 					port->send_discover = false;
-				else if (res == -EAGAIN)
+				} else if (res == -EAGAIN) {
+					port->vdo_data[0] = 0;
 					mod_send_discover_delayed_work(port,
 								       SEND_DISCOVER_RETRY_MS);
+				}
 				break;
 			case CMD_DISCOVER_SVID:
 				res = tcpm_ams_start(port, DISCOVER_SVIDS);
@@ -2081,6 +2092,7 @@
 			unsigned long timeout;
 
 			port->vdm_retries = 0;
+			port->vdo_data[0] = 0;
 			port->vdm_state = VDM_STATE_BUSY;
 			timeout = vdm_ready_timeout(vdo_hdr);
 			mod_vdm_delayed_work(port, timeout);
diff --git a/kernel/drivers/usb/typec/tps6598x.c b/kernel/drivers/usb/typec/tps6598x.c
index 6cb5c8e..4722b7f 100644
--- a/kernel/drivers/usb/typec/tps6598x.c
+++ b/kernel/drivers/usb/typec/tps6598x.c
@@ -564,7 +564,6 @@
 		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 @@
 	}
 
 	i2c_set_clientdata(client, tps);
+	fwnode_handle_put(fwnode);
 
 	return 0;
 
diff --git a/kernel/drivers/usb/typec/ucsi/ucsi.c b/kernel/drivers/usb/typec/ucsi/ucsi.c
index 516d00a..e01182b 100644
--- a/kernel/drivers/usb/typec/ucsi/ucsi.c
+++ b/kernel/drivers/usb/typec/ucsi/ucsi.c
@@ -1203,7 +1203,7 @@
 static int ucsi_init(struct ucsi *ucsi)
 {
 	struct ucsi_connector *con;
-	u64 command;
+	u64 command, ntfy;
 	int ret;
 	int i;
 
@@ -1215,8 +1215,8 @@
 	}
 
 	/* Enable basic notifications */
-	ucsi->ntfy = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR;
-	command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
+	ntfy = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR;
+	command = UCSI_SET_NOTIFICATION_ENABLE | ntfy;
 	ret = ucsi_send_command(ucsi, command, NULL, 0);
 	if (ret < 0)
 		goto err_reset;
@@ -1248,12 +1248,13 @@
 	}
 
 	/* Enable all notifications */
-	ucsi->ntfy = UCSI_ENABLE_NTFY_ALL;
-	command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
+	ntfy = UCSI_ENABLE_NTFY_ALL;
+	command = UCSI_SET_NOTIFICATION_ENABLE | ntfy;
 	ret = ucsi_send_command(ucsi, command, NULL, 0);
 	if (ret < 0)
 		goto err_unregister;
 
+	ucsi->ntfy = ntfy;
 	return 0;
 
 err_unregister:
diff --git a/kernel/drivers/vdpa/mlx5/core/mr.c b/kernel/drivers/vdpa/mlx5/core/mr.c
index 32c9925..1f94ea4 100644
--- a/kernel/drivers/vdpa/mlx5/core/mr.c
+++ b/kernel/drivers/vdpa/mlx5/core/mr.c
@@ -448,7 +448,6 @@
 		unmap_direct_mr(mvdev, dmr);
 		kfree(dmr);
 	}
-	memset(mr, 0, sizeof(*mr));
 	mr->initialized = false;
 out:
 	mutex_unlock(&mr->mkey_mtx);
diff --git a/kernel/drivers/vfio/platform/vfio_platform_common.c b/kernel/drivers/vfio/platform/vfio_platform_common.c
index e83a7cd..e15ef1a 100644
--- a/kernel/drivers/vfio/platform/vfio_platform_common.c
+++ b/kernel/drivers/vfio/platform/vfio_platform_common.c
@@ -72,12 +72,11 @@
 				  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);
diff --git a/kernel/drivers/vfio/vfio_iommu_type1.c b/kernel/drivers/vfio/vfio_iommu_type1.c
index ce50ca9..9b01f88 100644
--- a/kernel/drivers/vfio/vfio_iommu_type1.c
+++ b/kernel/drivers/vfio/vfio_iommu_type1.c
@@ -96,6 +96,7 @@
 	struct task_struct	*task;
 	struct rb_root		pfn_list;	/* Ex-user pinned pfn list */
 	unsigned long		*bitmap;
+	struct mm_struct	*mm;
 };
 
 struct vfio_batch {
@@ -391,8 +392,8 @@
 	if (!npage)
 		return 0;
 
-	mm = async ? get_task_mm(dma->task) : dma->task->mm;
-	if (!mm)
+	mm = dma->mm;
+	if (async && !mmget_not_zero(mm))
 		return -ESRCH; /* process exited */
 
 	ret = mmap_write_lock_killable(mm);
@@ -666,8 +667,8 @@
 	struct mm_struct *mm;
 	int ret;
 
-	mm = get_task_mm(dma->task);
-	if (!mm)
+	mm = dma->mm;
+	if (!mmget_not_zero(mm))
 		return -ENODEV;
 
 	ret = vaddr_get_pfns(mm, vaddr, 1, dma->prot, pfn_base, pages);
@@ -677,7 +678,7 @@
 	ret = 0;
 
 	if (do_accounting && !is_invalid_reserved_pfn(*pfn_base)) {
-		ret = vfio_lock_acct(dma, 1, true);
+		ret = vfio_lock_acct(dma, 1, false);
 		if (ret) {
 			put_pfn(*pfn_base, dma->prot);
 			if (ret == -ENOMEM)
@@ -1031,6 +1032,7 @@
 	vfio_unmap_unpin(iommu, dma, true);
 	vfio_unlink_dma(iommu, dma);
 	put_task_struct(dma->task);
+	mmdrop(dma->mm);
 	vfio_dma_bitmap_free(dma);
 	kfree(dma);
 	iommu->dma_avail++;
@@ -1452,29 +1454,15 @@
 	 * against the locked memory limit and we need to be able to do both
 	 * outside of this call path as pinning can be asynchronous via the
 	 * external interfaces for mdev devices.  RLIMIT_MEMLOCK requires a
-	 * task_struct and VM locked pages requires an mm_struct, however
-	 * holding an indefinite mm reference is not recommended, therefore we
-	 * only hold a reference to a task.  We could hold a reference to
-	 * current, however QEMU uses this call path through vCPU threads,
-	 * which can be killed resulting in a NULL mm and failure in the unmap
-	 * path when called via a different thread.  Avoid this problem by
-	 * using the group_leader as threads within the same group require
-	 * both CLONE_THREAD and CLONE_VM and will therefore use the same
-	 * mm_struct.
-	 *
-	 * Previously we also used the task for testing CAP_IPC_LOCK at the
-	 * time of pinning and accounting, however has_capability() makes use
-	 * of real_cred, a copy-on-write field, so we can't guarantee that it
-	 * matches group_leader, or in fact that it might not change by the
-	 * time it's evaluated.  If a process were to call MAP_DMA with
-	 * CAP_IPC_LOCK but later drop it, it doesn't make sense that they
-	 * possibly see different results for an iommu_mapped vfio_dma vs
-	 * externally mapped.  Therefore track CAP_IPC_LOCK in vfio_dma at the
-	 * time of calling MAP_DMA.
+	 * task_struct. Save the group_leader so that all DMA tracking uses
+	 * the same task, to make debugging easier.  VM locked pages requires
+	 * an mm_struct, so grab the mm in case the task dies.
 	 */
 	get_task_struct(current->group_leader);
 	dma->task = current->group_leader;
 	dma->lock_cap = capable(CAP_IPC_LOCK);
+	dma->mm = current->mm;
+	mmgrab(dma->mm);
 
 	dma->pfn_list = RB_ROOT;
 
@@ -2671,7 +2659,7 @@
 static int vfio_iommu_migration_build_caps(struct vfio_iommu *iommu,
 					   struct vfio_info_cap *caps)
 {
-	struct vfio_iommu_type1_info_cap_migration cap_mig;
+	struct vfio_iommu_type1_info_cap_migration cap_mig = {};
 
 	cap_mig.header.id = VFIO_IOMMU_TYPE1_INFO_CAP_MIGRATION;
 	cap_mig.header.version = 1;
@@ -2998,9 +2986,8 @@
 			!(dma->prot & IOMMU_READ))
 		return -EPERM;
 
-	mm = get_task_mm(dma->task);
-
-	if (!mm)
+	mm = dma->mm;
+	if (!mmget_not_zero(mm))
 		return -EPERM;
 
 	if (kthread)
diff --git a/kernel/drivers/vhost/net.c b/kernel/drivers/vhost/net.c
index 5beb207..b9c8e40 100644
--- a/kernel/drivers/vhost/net.c
+++ b/kernel/drivers/vhost/net.c
@@ -1517,6 +1517,9 @@
 	nvq = &n->vqs[index];
 	mutex_lock(&vq->mutex);
 
+	if (fd == -1)
+		vhost_clear_msg(&n->dev);
+
 	/* Verify that ring has been setup correctly. */
 	if (!vhost_vq_access_ok(vq)) {
 		r = -EFAULT;
diff --git a/kernel/drivers/vhost/vhost.c b/kernel/drivers/vhost/vhost.c
index f41463a..de11036 100644
--- a/kernel/drivers/vhost/vhost.c
+++ b/kernel/drivers/vhost/vhost.c
@@ -669,7 +669,7 @@
 }
 EXPORT_SYMBOL_GPL(vhost_dev_stop);
 
-static void vhost_clear_msg(struct vhost_dev *dev)
+void vhost_clear_msg(struct vhost_dev *dev)
 {
 	struct vhost_msg_node *node, *n;
 
@@ -687,6 +687,7 @@
 
 	spin_unlock(&dev->iotlb_lock);
 }
+EXPORT_SYMBOL_GPL(vhost_clear_msg);
 
 void vhost_dev_cleanup(struct vhost_dev *dev)
 {
@@ -1620,17 +1621,25 @@
 			r = -EFAULT;
 			break;
 		}
-		if (s.num > 0xffff) {
-			r = -EINVAL;
-			break;
+		if (vhost_has_feature(vq, VIRTIO_F_RING_PACKED)) {
+			vq->last_avail_idx = s.num & 0xffff;
+			vq->last_used_idx = (s.num >> 16) & 0xffff;
+		} else {
+			if (s.num > 0xffff) {
+				r = -EINVAL;
+				break;
+			}
+			vq->last_avail_idx = s.num;
 		}
-		vq->last_avail_idx = s.num;
 		/* Forget the cached index value. */
 		vq->avail_idx = vq->last_avail_idx;
 		break;
 	case VHOST_GET_VRING_BASE:
 		s.index = idx;
-		s.num = vq->last_avail_idx;
+		if (vhost_has_feature(vq, VIRTIO_F_RING_PACKED))
+			s.num = (u32)vq->last_avail_idx | ((u32)vq->last_used_idx << 16);
+		else
+			s.num = vq->last_avail_idx;
 		if (copy_to_user(argp, &s, sizeof s))
 			r = -EFAULT;
 		break;
@@ -2041,7 +2050,7 @@
 	struct vhost_dev *dev = vq->dev;
 	struct vhost_iotlb *umem = dev->iotlb ? dev->iotlb : dev->umem;
 	struct iovec *_iov;
-	u64 s = 0;
+	u64 s = 0, last = addr + len - 1;
 	int ret = 0;
 
 	while ((u64)len > s) {
@@ -2051,7 +2060,7 @@
 			break;
 		}
 
-		map = vhost_iotlb_itree_first(umem, addr, addr + len - 1);
+		map = vhost_iotlb_itree_first(umem, addr, last);
 		if (map == NULL || map->start > addr) {
 			if (umem != dev->iotlb) {
 				ret = -EFAULT;
diff --git a/kernel/drivers/vhost/vhost.h b/kernel/drivers/vhost/vhost.h
index b063324..e00347f 100644
--- a/kernel/drivers/vhost/vhost.h
+++ b/kernel/drivers/vhost/vhost.h
@@ -87,13 +87,17 @@
 	/* The routine to call when the Guest pings us, or timeout. */
 	vhost_work_fn_t handle_kick;
 
-	/* Last available index we saw. */
+	/* Last available index we saw.
+	 * Values are limited to 0x7fff, and the high bit is used as
+	 * a wrap counter when using VIRTIO_F_RING_PACKED. */
 	u16 last_avail_idx;
 
 	/* Caches available index value from user. */
 	u16 avail_idx;
 
-	/* Last index we used. */
+	/* Last index we used.
+	 * Values are limited to 0x7fff, and the high bit is used as
+	 * a wrap counter when using VIRTIO_F_RING_PACKED. */
 	u16 last_used_idx;
 
 	/* Used flags */
@@ -183,6 +187,7 @@
 long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp);
 bool vhost_vq_access_ok(struct vhost_virtqueue *vq);
 bool vhost_log_access_ok(struct vhost_dev *);
+void vhost_clear_msg(struct vhost_dev *dev);
 
 int vhost_get_vq_desc(struct vhost_virtqueue *,
 		      struct iovec iov[], unsigned int iov_count,
diff --git a/kernel/drivers/vhost/vringh.c b/kernel/drivers/vhost/vringh.c
index 5a0340c..48f4ec2 100644
--- a/kernel/drivers/vhost/vringh.c
+++ b/kernel/drivers/vhost/vringh.c
@@ -1077,7 +1077,7 @@
 	struct vhost_iotlb_map *map;
 	struct vhost_iotlb *iotlb = vrh->iotlb;
 	int ret = 0;
-	u64 s = 0;
+	u64 s = 0, last = addr + len - 1;
 
 	while (len > s) {
 		u64 size, pa, pfn;
@@ -1087,8 +1087,7 @@
 			break;
 		}
 
-		map = vhost_iotlb_itree_first(iotlb, addr,
-					      addr + len - 1);
+		map = vhost_iotlb_itree_first(iotlb, addr, last);
 		if (!map || map->start > addr) {
 			ret = -EINVAL;
 			break;
diff --git a/kernel/drivers/vhost/vsock.c b/kernel/drivers/vhost/vsock.c
index 00f6267..8c16302 100644
--- a/kernel/drivers/vhost/vsock.c
+++ b/kernel/drivers/vhost/vsock.c
@@ -853,7 +853,14 @@
 				  VSOCK_TRANSPORT_F_H2G);
 	if (ret < 0)
 		return ret;
-	return misc_register(&vhost_vsock_misc);
+
+	ret = misc_register(&vhost_vsock_misc);
+	if (ret) {
+		vsock_core_unregister(&vhost_transport.transport);
+		return ret;
+	}
+
+	return 0;
 };
 
 static void __exit vhost_vsock_exit(void)
diff --git a/kernel/drivers/video/backlight/bd6107.c b/kernel/drivers/video/backlight/bd6107.c
index 515184f..5c67ef8 100644
--- a/kernel/drivers/video/backlight/bd6107.c
+++ b/kernel/drivers/video/backlight/bd6107.c
@@ -104,7 +104,7 @@
 {
 	struct bd6107 *bd = bl_get_data(backlight);
 
-	return bd->pdata->fbdev == NULL || bd->pdata->fbdev == info->dev;
+	return bd->pdata->fbdev == NULL || bd->pdata->fbdev == info->device;
 }
 
 static const struct backlight_ops bd6107_backlight_ops = {
diff --git a/kernel/drivers/video/backlight/gpio_backlight.c b/kernel/drivers/video/backlight/gpio_backlight.c
index 6f78d92..30ec5b6 100644
--- a/kernel/drivers/video/backlight/gpio_backlight.c
+++ b/kernel/drivers/video/backlight/gpio_backlight.c
@@ -35,7 +35,7 @@
 {
 	struct gpio_backlight *gbl = bl_get_data(bl);
 
-	return gbl->fbdev == NULL || gbl->fbdev == info->dev;
+	return gbl->fbdev == NULL || gbl->fbdev == info->device;
 }
 
 static const struct backlight_ops gpio_backlight_ops = {
@@ -87,8 +87,7 @@
 		/* Not booted with device tree or no phandle link to the node */
 		bl->props.power = def_value ? FB_BLANK_UNBLANK
 					    : FB_BLANK_POWERDOWN;
-	else if (gpiod_get_direction(gbl->gpiod) == 0 &&
-		 gpiod_get_value_cansleep(gbl->gpiod) == 0)
+	else if (gpiod_get_value_cansleep(gbl->gpiod) == 0)
 		bl->props.power = FB_BLANK_POWERDOWN;
 	else
 		bl->props.power = FB_BLANK_UNBLANK;
diff --git a/kernel/drivers/video/backlight/lv5207lp.c b/kernel/drivers/video/backlight/lv5207lp.c
index 1842ae9..720ada4 100644
--- a/kernel/drivers/video/backlight/lv5207lp.c
+++ b/kernel/drivers/video/backlight/lv5207lp.c
@@ -67,7 +67,7 @@
 {
 	struct lv5207lp *lv = bl_get_data(backlight);
 
-	return lv->pdata->fbdev == NULL || lv->pdata->fbdev == info->dev;
+	return lv->pdata->fbdev == NULL || lv->pdata->fbdev == info->device;
 }
 
 static const struct backlight_ops lv5207lp_backlight_ops = {
diff --git a/kernel/drivers/video/backlight/pwm_bl.c b/kernel/drivers/video/backlight/pwm_bl.c
index 38ac5fb..c4323e9 100644
--- a/kernel/drivers/video/backlight/pwm_bl.c
+++ b/kernel/drivers/video/backlight/pwm_bl.c
@@ -74,7 +74,7 @@
 	struct pwm_state state;
 
 	pwm_get_state(pb->pwm, &state);
-	if (!pb->enabled)
+	if (!pb->enabled && !state.enabled)
 		return;
 
 	if (pb->enable_gpio)
diff --git a/kernel/drivers/video/fbdev/Kconfig b/kernel/drivers/video/fbdev/Kconfig
index 4f02db6..dd59584 100644
--- a/kernel/drivers/video/fbdev/Kconfig
+++ b/kernel/drivers/video/fbdev/Kconfig
@@ -2014,7 +2014,7 @@
 
 config FB_SH7760
 	bool "SH7760/SH7763/SH7720/SH7721 LCDC support"
-	depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \
+	depends on FB=y && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \
 		|| CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721)
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
@@ -2216,7 +2216,6 @@
 	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
diff --git a/kernel/drivers/video/fbdev/arcfb.c b/kernel/drivers/video/fbdev/arcfb.c
index 1447324..08da436 100644
--- a/kernel/drivers/video/fbdev/arcfb.c
+++ b/kernel/drivers/video/fbdev/arcfb.c
@@ -523,7 +523,7 @@
 
 	info = framebuffer_alloc(sizeof(struct arcfb_par), &dev->dev);
 	if (!info)
-		goto err;
+		goto err_fb_alloc;
 
 	info->screen_base = (char __iomem *)videomemory;
 	info->fbops = &arcfb_ops;
@@ -535,7 +535,7 @@
 
 	if (!dio_addr || !cio_addr || !c2io_addr) {
 		printk(KERN_WARNING "no IO addresses supplied\n");
-		goto err1;
+		goto err_addr;
 	}
 	par->dio_addr = dio_addr;
 	par->cio_addr = cio_addr;
@@ -551,12 +551,12 @@
 			printk(KERN_INFO
 				"arcfb: Failed req IRQ %d\n", par->irq);
 			retval = -EBUSY;
-			goto err1;
+			goto err_addr;
 		}
 	}
 	retval = register_framebuffer(info);
 	if (retval < 0)
-		goto err1;
+		goto err_register_fb;
 	platform_set_drvdata(dev, info);
 	fb_info(info, "Arc frame buffer device, using %dK of video memory\n",
 		videomemorysize >> 10);
@@ -580,9 +580,12 @@
 	}
 
 	return 0;
-err1:
+
+err_register_fb:
+	free_irq(par->irq, info);
+err_addr:
 	framebuffer_release(info);
-err:
+err_fb_alloc:
 	vfree(videomemory);
 	return retval;
 }
diff --git a/kernel/drivers/video/fbdev/au1200fb.c b/kernel/drivers/video/fbdev/au1200fb.c
index c00e01a..80f5411 100644
--- a/kernel/drivers/video/fbdev/au1200fb.c
+++ b/kernel/drivers/video/fbdev/au1200fb.c
@@ -1040,6 +1040,9 @@
 	u32 pixclock;
 	int screen_size, plane;
 
+	if (!var->pixclock)
+		return -EINVAL;
+
 	plane = fbdev->plane;
 
 	/* Make sure that the mode respect all LCD controller and
@@ -1729,6 +1732,9 @@
 
 	/* Now hook interrupt too */
 	irq = platform_get_irq(dev, 0);
+	if (irq < 0)
+		return irq;
+
 	ret = request_irq(irq, au1200fb_handle_irq,
 			  IRQF_SHARED, "lcd", (void *)dev);
 	if (ret) {
diff --git a/kernel/drivers/video/fbdev/core/bitblit.c b/kernel/drivers/video/fbdev/core/bitblit.c
index 9725ecd..8e095b0 100644
--- a/kernel/drivers/video/fbdev/core/bitblit.c
+++ b/kernel/drivers/video/fbdev/core/bitblit.c
@@ -247,6 +247,9 @@
 
 	cursor.set = 0;
 
+	if (!vc->vc_font.data)
+		return;
+
  	c = scr_readw((u16 *) vc->vc_pos);
 	attribute = get_attribute(info, c);
 	src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
diff --git a/kernel/drivers/video/fbdev/core/fbcon.c b/kernel/drivers/video/fbdev/core/fbcon.c
index 2782843..6d58c8a 100644
--- a/kernel/drivers/video/fbdev/core/fbcon.c
+++ b/kernel/drivers/video/fbdev/core/fbcon.c
@@ -2513,9 +2513,12 @@
 	    h > FBCON_SWAP(info->var.rotate, info->var.yres, info->var.xres))
 		return -EINVAL;
 
+	if (font->width > 32 || font->height > 32)
+		return -EINVAL;
+
 	/* Make sure drawing engine can handle the font */
-	if (!(info->pixmap.blit_x & (1 << (font->width - 1))) ||
-	    !(info->pixmap.blit_y & (1 << (font->height - 1))))
+	if (!(info->pixmap.blit_x & BIT(font->width - 1)) ||
+	    !(info->pixmap.blit_y & BIT(font->height - 1)))
 		return -EINVAL;
 
 	/* Make sure driver can handle the font length */
diff --git a/kernel/drivers/video/fbdev/core/fbmem.c b/kernel/drivers/video/fbdev/core/fbmem.c
index d787a34..1704dea 100644
--- a/kernel/drivers/video/fbdev/core/fbmem.c
+++ b/kernel/drivers/video/fbdev/core/fbmem.c
@@ -1117,6 +1117,8 @@
 	case FBIOPUT_VSCREENINFO:
 		if (copy_from_user(&var, argp, sizeof(var)))
 			return -EFAULT;
+		/* only for kernel-internal use */
+		var.activate &= ~FB_ACTIVATE_KD_TEXT;
 		console_lock();
 		lock_fb_info(info);
 		ret = fbcon_modechange_possible(info, &var);
diff --git a/kernel/drivers/video/fbdev/core/modedb.c b/kernel/drivers/video/fbdev/core/modedb.c
index 6473e0d..e78ec7f 100644
--- a/kernel/drivers/video/fbdev/core/modedb.c
+++ b/kernel/drivers/video/fbdev/core/modedb.c
@@ -257,6 +257,11 @@
 	{ NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, 0,
 		FB_VMODE_DOUBLE },
 
+	/* 1920x1080 @ 60 Hz, 67.3 kHz hsync */
+	{ NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5, 0,
+		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+		FB_VMODE_NONINTERLACED },
+
 	/* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
 	{ NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
 		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
diff --git a/kernel/drivers/video/fbdev/core/sysimgblt.c b/kernel/drivers/video/fbdev/core/sysimgblt.c
index a4d05b1..665ef7a 100644
--- a/kernel/drivers/video/fbdev/core/sysimgblt.c
+++ b/kernel/drivers/video/fbdev/core/sysimgblt.c
@@ -188,23 +188,29 @@
 {
 	u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
 	u32 ppw = 32/bpp, spitch = (image->width + 7)/8;
-	u32 bit_mask, end_mask, eorx, shift;
-	const char *s = image->data, *src;
+	u32 bit_mask, eorx, shift;
+	const u8 *s = image->data, *src;
 	u32 *dst;
-	const u32 *tab = NULL;
+	const u32 *tab;
+	size_t tablen;
+	u32 colortab[16];
 	int i, j, k;
 
 	switch (bpp) {
 	case 8:
 		tab = fb_be_math(p) ? cfb_tab8_be : cfb_tab8_le;
+		tablen = 16;
 		break;
 	case 16:
 		tab = fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le;
+		tablen = 4;
 		break;
 	case 32:
-	default:
 		tab = cfb_tab32;
+		tablen = 2;
 		break;
+	default:
+		return;
 	}
 
 	for (i = ppw-1; i--; ) {
@@ -218,20 +224,62 @@
 	eorx = fgx ^ bgx;
 	k = image->width/ppw;
 
+	for (i = 0; i < tablen; ++i)
+		colortab[i] = (tab[i] & eorx) ^ bgx;
+
 	for (i = image->height; i--; ) {
 		dst = dst1;
 		shift = 8;
 		src = s;
 
-		for (j = k; j--; ) {
+		/*
+		 * Manually unroll the per-line copying loop for better
+		 * performance. This works until we processed the last
+		 * completely filled source byte (inclusive).
+		 */
+		switch (ppw) {
+		case 4: /* 8 bpp */
+			for (j = k; j >= 2; j -= 2, ++src) {
+				*dst++ = colortab[(*src >> 4) & bit_mask];
+				*dst++ = colortab[(*src >> 0) & bit_mask];
+			}
+			break;
+		case 2: /* 16 bpp */
+			for (j = k; j >= 4; j -= 4, ++src) {
+				*dst++ = colortab[(*src >> 6) & bit_mask];
+				*dst++ = colortab[(*src >> 4) & bit_mask];
+				*dst++ = colortab[(*src >> 2) & bit_mask];
+				*dst++ = colortab[(*src >> 0) & bit_mask];
+			}
+			break;
+		case 1: /* 32 bpp */
+			for (j = k; j >= 8; j -= 8, ++src) {
+				*dst++ = colortab[(*src >> 7) & bit_mask];
+				*dst++ = colortab[(*src >> 6) & bit_mask];
+				*dst++ = colortab[(*src >> 5) & bit_mask];
+				*dst++ = colortab[(*src >> 4) & bit_mask];
+				*dst++ = colortab[(*src >> 3) & bit_mask];
+				*dst++ = colortab[(*src >> 2) & bit_mask];
+				*dst++ = colortab[(*src >> 1) & bit_mask];
+				*dst++ = colortab[(*src >> 0) & bit_mask];
+			}
+			break;
+		}
+
+		/*
+		 * For image widths that are not a multiple of 8, there
+		 * are trailing pixels left on the current line. Print
+		 * them as well.
+		 */
+		for (; j--; ) {
 			shift -= ppw;
-			end_mask = tab[(*src >> shift) & bit_mask];
-			*dst++ = (end_mask & eorx) ^ bgx;
+			*dst++ = colortab[(*src >> shift) & bit_mask];
 			if (!shift) {
 				shift = 8;
-				src++;
+				++src;
 			}
 		}
+
 		dst1 += p->fix.line_length;
 		s += spitch;
 	}
diff --git a/kernel/drivers/video/fbdev/ep93xx-fb.c b/kernel/drivers/video/fbdev/ep93xx-fb.c
index ba33b4d..04aac2a 100644
--- a/kernel/drivers/video/fbdev/ep93xx-fb.c
+++ b/kernel/drivers/video/fbdev/ep93xx-fb.c
@@ -474,7 +474,6 @@
 	if (!info)
 		return -ENOMEM;
 
-	info->dev = &pdev->dev;
 	platform_set_drvdata(pdev, info);
 	fbi = info->par;
 	fbi->mach_info = mach_info;
diff --git a/kernel/drivers/video/fbdev/geode/lxfb_core.c b/kernel/drivers/video/fbdev/geode/lxfb_core.c
index 66c8126..6c6b6ef 100644
--- a/kernel/drivers/video/fbdev/geode/lxfb_core.c
+++ b/kernel/drivers/video/fbdev/geode/lxfb_core.c
@@ -234,6 +234,9 @@
 
 static int lxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
+	if (!var->pixclock)
+		return -EINVAL;
+
 	if (var->xres > 1920 || var->yres > 1440)
 		return -EINVAL;
 
diff --git a/kernel/drivers/video/fbdev/hyperv_fb.c b/kernel/drivers/video/fbdev/hyperv_fb.c
index 40baa79..f0a66a3 100644
--- a/kernel/drivers/video/fbdev/hyperv_fb.c
+++ b/kernel/drivers/video/fbdev/hyperv_fb.c
@@ -798,12 +798,18 @@
 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/kernel/drivers/video/fbdev/imsttfb.c b/kernel/drivers/video/fbdev/imsttfb.c
index e044117..1b2fb8e 100644
--- a/kernel/drivers/video/fbdev/imsttfb.c
+++ b/kernel/drivers/video/fbdev/imsttfb.c
@@ -1346,7 +1346,7 @@
 	.fb_ioctl 	= imsttfb_ioctl,
 };
 
-static void init_imstt(struct fb_info *info)
+static int init_imstt(struct fb_info *info)
 {
 	struct imstt_par *par = info->par;
 	__u32 i, tmp, *ip, *end;
@@ -1419,7 +1419,7 @@
 	    || !(compute_imstt_regvals(par, info->var.xres, info->var.yres))) {
 		printk("imsttfb: %ux%ux%u not supported\n", info->var.xres, info->var.yres, info->var.bits_per_pixel);
 		framebuffer_release(info);
-		return;
+		return -ENODEV;
 	}
 
 	sprintf(info->fix.id, "IMS TT (%s)", par->ramdac == IBM ? "IBM" : "TVP");
@@ -1455,12 +1455,13 @@
 
 	if (register_framebuffer(info) < 0) {
 		framebuffer_release(info);
-		return;
+		return -ENODEV;
 	}
 
 	tmp = (read_reg_le32(par->dc_regs, SSTATUS) & 0x0f00) >> 8;
 	fb_info(info, "%s frame buffer; %uMB vram; chip version %u\n",
 		info->fix.id, info->fix.smem_len >> 20, tmp);
+	return 0;
 }
 
 static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -1469,6 +1470,7 @@
 	struct imstt_par *par;
 	struct fb_info *info;
 	struct device_node *dp;
+	int ret = -ENOMEM;
 	
 	dp = pci_device_to_OF_node(pdev);
 	if(dp)
@@ -1504,23 +1506,37 @@
 		default:
 			printk(KERN_INFO "imsttfb: Device 0x%x unknown, "
 					 "contact maintainer.\n", pdev->device);
-			release_mem_region(addr, size);
-			framebuffer_release(info);
-			return -ENODEV;
+			ret = -ENODEV;
+			goto error;
 	}
 
 	info->fix.smem_start = addr;
 	info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ?
 					    0x400000 : 0x800000);
+	if (!info->screen_base)
+		goto error;
 	info->fix.mmio_start = addr + 0x800000;
 	par->dc_regs = ioremap(addr + 0x800000, 0x1000);
+	if (!par->dc_regs)
+		goto error;
 	par->cmap_regs_phys = addr + 0x840000;
 	par->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000);
+	if (!par->cmap_regs)
+		goto error;
 	info->pseudo_palette = par->palette;
-	init_imstt(info);
+	ret = init_imstt(info);
+	if (!ret)
+		pci_set_drvdata(pdev, info);
+	return ret;
 
-	pci_set_drvdata(pdev, info);
-	return 0;
+error:
+	if (par->dc_regs)
+		iounmap(par->dc_regs);
+	if (info->screen_base)
+		iounmap(info->screen_base);
+	release_mem_region(addr, size);
+	framebuffer_release(info);
+	return ret;
 }
 
 static void imsttfb_remove(struct pci_dev *pdev)
diff --git a/kernel/drivers/video/fbdev/imxfb.c b/kernel/drivers/video/fbdev/imxfb.c
index 564bd04..d663e08 100644
--- a/kernel/drivers/video/fbdev/imxfb.c
+++ b/kernel/drivers/video/fbdev/imxfb.c
@@ -602,10 +602,10 @@
 	if (var->hsync_len < 1    || var->hsync_len > 64)
 		printk(KERN_ERR "%s: invalid hsync_len %d\n",
 			info->fix.id, var->hsync_len);
-	if (var->left_margin > 255)
+	if (var->left_margin < 3  || var->left_margin > 255)
 		printk(KERN_ERR "%s: invalid left_margin %d\n",
 			info->fix.id, var->left_margin);
-	if (var->right_margin > 255)
+	if (var->right_margin < 1 || var->right_margin > 255)
 		printk(KERN_ERR "%s: invalid right_margin %d\n",
 			info->fix.id, var->right_margin);
 	if (var->yres < 1 || var->yres > ymax_mask)
diff --git a/kernel/drivers/video/fbdev/intelfb/intelfbdrv.c b/kernel/drivers/video/fbdev/intelfb/intelfbdrv.c
index a957996..8a703ad 100644
--- a/kernel/drivers/video/fbdev/intelfb/intelfbdrv.c
+++ b/kernel/drivers/video/fbdev/intelfb/intelfbdrv.c
@@ -1214,6 +1214,9 @@
 
 	dinfo = GET_DINFO(info);
 
+	if (!var->pixclock)
+		return -EINVAL;
+
 	/* update the pitch */
 	if (intelfbhw_validate_mode(dinfo, var) != 0)
 		return -EINVAL;
diff --git a/kernel/drivers/video/fbdev/matrox/matroxfb_base.c b/kernel/drivers/video/fbdev/matrox/matroxfb_base.c
index daaa998..566f748 100644
--- a/kernel/drivers/video/fbdev/matrox/matroxfb_base.c
+++ b/kernel/drivers/video/fbdev/matrox/matroxfb_base.c
@@ -1377,8 +1377,8 @@
 	.lowlevel = &matrox_G100
 };
 static struct video_board vbG200eW = {
-	.maxvram = 0x100000,
-	.maxdisplayable = 0x800000,
+	.maxvram = 0x1000000,
+	.maxdisplayable = 0x0800000,
 	.accelID = FB_ACCEL_MATROX_MGAG200,
 	.lowlevel = &matrox_G100
 };
diff --git a/kernel/drivers/video/fbdev/mmp/hw/mmp_ctrl.c b/kernel/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
index 061a105..27c3ee5 100644
--- a/kernel/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
+++ b/kernel/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
@@ -518,7 +518,9 @@
 		ret = -ENOENT;
 		goto failed;
 	}
-	clk_prepare_enable(ctrl->clk);
+	ret = clk_prepare_enable(ctrl->clk);
+	if (ret)
+		goto failed;
 
 	/* init global regs */
 	ctrl_set_default(ctrl);
diff --git a/kernel/drivers/video/fbdev/nvidia/nvidia.c b/kernel/drivers/video/fbdev/nvidia/nvidia.c
index a372a18..f9c388a 100644
--- a/kernel/drivers/video/fbdev/nvidia/nvidia.c
+++ b/kernel/drivers/video/fbdev/nvidia/nvidia.c
@@ -763,6 +763,8 @@
 	int pitch, err = 0;
 
 	NVTRACE_ENTER();
+	if (!var->pixclock)
+		return -EINVAL;
 
 	var->transp.offset = 0;
 	var->transp.length = 0;
diff --git a/kernel/drivers/video/fbdev/omap/lcd_mipid.c b/kernel/drivers/video/fbdev/omap/lcd_mipid.c
index a75ae0c..d1cd878 100644
--- a/kernel/drivers/video/fbdev/omap/lcd_mipid.c
+++ b/kernel/drivers/video/fbdev/omap/lcd_mipid.c
@@ -563,11 +563,15 @@
 
 	r = mipid_detect(md);
 	if (r < 0)
-		return r;
+		goto free_md;
 
 	omapfb_register_panel(&md->panel);
 
 	return 0;
+
+free_md:
+	kfree(md);
+	return r;
 }
 
 static int mipid_spi_remove(struct spi_device *spi)
diff --git a/kernel/drivers/video/fbdev/pm2fb.c b/kernel/drivers/video/fbdev/pm2fb.c
index c12d46e..87b6a92 100644
--- a/kernel/drivers/video/fbdev/pm2fb.c
+++ b/kernel/drivers/video/fbdev/pm2fb.c
@@ -1529,8 +1529,10 @@
 	}
 
 	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 @@
 	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 @@
 	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[] = {
diff --git a/kernel/drivers/video/fbdev/smscufx.c b/kernel/drivers/video/fbdev/smscufx.c
index 5fa3f1e..b3295cd 100644
--- a/kernel/drivers/video/fbdev/smscufx.c
+++ b/kernel/drivers/video/fbdev/smscufx.c
@@ -1621,7 +1621,7 @@
 	struct usb_device *usbdev;
 	struct ufx_data *dev;
 	struct fb_info *info;
-	int retval;
+	int retval = -ENOMEM;
 	u32 id_rev, fpga_rev;
 
 	/* usb initialization */
@@ -1653,15 +1653,17 @@
 
 	if (!ufx_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
 		dev_err(dev->gdev, "ufx_alloc_urb_list failed\n");
-		goto e_nomem;
+		goto put_ref;
 	}
 
 	/* We don't register a new USB class. Our client interface is fbdev */
 
 	/* allocates framebuffer driver structure, not framebuffer memory */
 	info = framebuffer_alloc(0, &usbdev->dev);
-	if (!info)
-		goto e_nomem;
+	if (!info) {
+		dev_err(dev->gdev, "framebuffer_alloc failed\n");
+		goto free_urb_list;
+	}
 
 	dev->info = info;
 	info->par = dev;
@@ -1704,22 +1706,34 @@
 	check_warn_goto_error(retval, "unable to find common mode for display and adapter");
 
 	retval = ufx_reg_set_bits(dev, 0x4000, 0x00000001);
-	check_warn_goto_error(retval, "error %d enabling graphics engine", retval);
+	if (retval < 0) {
+		dev_err(dev->gdev, "error %d enabling graphics engine", retval);
+		goto setup_modes;
+	}
 
 	/* ready to begin using device */
 	atomic_set(&dev->usb_active, 1);
 
 	dev_dbg(dev->gdev, "checking var");
 	retval = ufx_ops_check_var(&info->var, info);
-	check_warn_goto_error(retval, "error %d ufx_ops_check_var", retval);
+	if (retval < 0) {
+		dev_err(dev->gdev, "error %d ufx_ops_check_var", retval);
+		goto reset_active;
+	}
 
 	dev_dbg(dev->gdev, "setting par");
 	retval = ufx_ops_set_par(info);
-	check_warn_goto_error(retval, "error %d ufx_ops_set_par", retval);
+	if (retval < 0) {
+		dev_err(dev->gdev, "error %d ufx_ops_set_par", retval);
+		goto reset_active;
+	}
 
 	dev_dbg(dev->gdev, "registering framebuffer");
 	retval = register_framebuffer(info);
-	check_warn_goto_error(retval, "error %d register_framebuffer", retval);
+	if (retval < 0) {
+		dev_err(dev->gdev, "error %d register_framebuffer", retval);
+		goto reset_active;
+	}
 
 	dev_info(dev->gdev, "SMSC UDX USB device /dev/fb%d attached. %dx%d resolution."
 		" Using %dK framebuffer memory\n", info->node,
@@ -1727,21 +1741,23 @@
 
 	return 0;
 
-error:
-	fb_dealloc_cmap(&info->cmap);
-destroy_modedb:
+reset_active:
+	atomic_set(&dev->usb_active, 0);
+setup_modes:
 	fb_destroy_modedb(info->monspecs.modedb);
 	vfree(info->screen_base);
 	fb_destroy_modelist(&info->modelist);
+error:
+	fb_dealloc_cmap(&info->cmap);
+destroy_modedb:
 	framebuffer_release(info);
+free_urb_list:
+	if (dev->urbs.count > 0)
+		ufx_free_urb_list(dev);
 put_ref:
 	kref_put(&dev->kref, ufx_free); /* ref for framebuffer */
 	kref_put(&dev->kref, ufx_free); /* last ref from kref_init */
 	return retval;
-
-e_nomem:
-	retval = -ENOMEM;
-	goto put_ref;
 }
 
 static void ufx_usb_disconnect(struct usb_interface *interface)
diff --git a/kernel/drivers/video/fbdev/stifb.c b/kernel/drivers/video/fbdev/stifb.c
index 3feb6e4..63f5178 100644
--- a/kernel/drivers/video/fbdev/stifb.c
+++ b/kernel/drivers/video/fbdev/stifb.c
@@ -922,6 +922,28 @@
 /* ------------------- driver specific functions --------------------------- */
 
 static int
+stifb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	struct stifb_info *fb = container_of(info, struct stifb_info, info);
+
+	if (var->xres != fb->info.var.xres ||
+	    var->yres != fb->info.var.yres ||
+	    var->bits_per_pixel != fb->info.var.bits_per_pixel)
+		return -EINVAL;
+
+	var->xres_virtual = var->xres;
+	var->yres_virtual = var->yres;
+	var->xoffset = 0;
+	var->yoffset = 0;
+	var->grayscale = fb->info.var.grayscale;
+	var->red.length = fb->info.var.red.length;
+	var->green.length = fb->info.var.green.length;
+	var->blue.length = fb->info.var.blue.length;
+
+	return 0;
+}
+
+static int
 stifb_setcolreg(u_int regno, u_int red, u_int green,
 	      u_int blue, u_int transp, struct fb_info *info)
 {
@@ -1145,6 +1167,7 @@
 
 static const struct fb_ops stifb_ops = {
 	.owner		= THIS_MODULE,
+	.fb_check_var	= stifb_check_var,
 	.fb_setcolreg	= stifb_setcolreg,
 	.fb_blank	= stifb_blank,
 	.fb_fillrect	= stifb_fillrect,
@@ -1164,6 +1187,7 @@
 	struct stifb_info *fb;
 	struct fb_info *info;
 	unsigned long sti_rom_address;
+	char modestr[32];
 	char *dev_name;
 	int bpp, xres, yres;
 
@@ -1342,6 +1366,9 @@
 	info->flags = FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT;
 	info->pseudo_palette = &fb->pseudo_palette;
 
+	scnprintf(modestr, sizeof(modestr), "%dx%d-%d", xres, yres, bpp);
+	fb_find_mode(&info->var, info, modestr, NULL, 0, NULL, bpp);
+
 	/* This has to be done !!! */
 	if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0))
 		goto out_err1;
@@ -1386,6 +1413,7 @@
 	iounmap(info->screen_base);
 out_err0:
 	kfree(fb);
+	sti->info = NULL;
 	return -ENXIO;
 }
 
diff --git a/kernel/drivers/video/fbdev/tgafb.c b/kernel/drivers/video/fbdev/tgafb.c
index 666fbe2..98a2977 100644
--- a/kernel/drivers/video/fbdev/tgafb.c
+++ b/kernel/drivers/video/fbdev/tgafb.c
@@ -166,6 +166,9 @@
 {
 	struct tga_par *par = (struct tga_par *)info->par;
 
+	if (!var->pixclock)
+		return -EINVAL;
+
 	if (par->tga_type == TGA_TYPE_8PLANE) {
 		if (var->bits_per_pixel != 8)
 			return -EINVAL;
diff --git a/kernel/drivers/video/fbdev/udlfb.c b/kernel/drivers/video/fbdev/udlfb.c
index d9eec1b..0de7b86 100644
--- a/kernel/drivers/video/fbdev/udlfb.c
+++ b/kernel/drivers/video/fbdev/udlfb.c
@@ -27,6 +27,8 @@
 #include <video/udlfb.h>
 #include "edid.h"
 
+#define OUT_EP_NUM	1	/* The endpoint number we will use */
+
 static const struct fb_fix_screeninfo dlfb_fix = {
 	.id =           "udlfb",
 	.type =         FB_TYPE_PACKED_PIXELS,
@@ -1651,7 +1653,7 @@
 	struct fb_info *info;
 	int retval;
 	struct usb_device *usbdev = interface_to_usbdev(intf);
-	struct usb_endpoint_descriptor *out;
+	static u8 out_ep[] = {OUT_EP_NUM + USB_DIR_OUT, 0};
 
 	/* usb initialization */
 	dlfb = kzalloc(sizeof(*dlfb), GFP_KERNEL);
@@ -1665,9 +1667,9 @@
 	dlfb->udev = usb_get_dev(usbdev);
 	usb_set_intfdata(intf, dlfb);
 
-	retval = usb_find_common_endpoints(intf->cur_altsetting, NULL, &out, NULL, NULL);
-	if (retval) {
-		dev_err(&intf->dev, "Device should have at lease 1 bulk endpoint!\n");
+	if (!usb_check_bulk_endpoints(intf, out_ep)) {
+		dev_err(&intf->dev, "Invalid DisplayLink device!\n");
+		retval = -EINVAL;
 		goto error;
 	}
 
@@ -1926,7 +1928,8 @@
 		}
 
 		/* urb->transfer_buffer_length set to actual before submit */
-		usb_fill_bulk_urb(urb, dlfb->udev, usb_sndbulkpipe(dlfb->udev, 1),
+		usb_fill_bulk_urb(urb, dlfb->udev,
+			usb_sndbulkpipe(dlfb->udev, OUT_EP_NUM),
 			buf, size, dlfb_urb_completion, unode);
 		urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
diff --git a/kernel/drivers/video/fbdev/uvesafb.c b/kernel/drivers/video/fbdev/uvesafb.c
index def14ac..661f127 100644
--- a/kernel/drivers/video/fbdev/uvesafb.c
+++ b/kernel/drivers/video/fbdev/uvesafb.c
@@ -1756,6 +1756,7 @@
 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);
diff --git a/kernel/drivers/video/fbdev/vermilion/vermilion.c b/kernel/drivers/video/fbdev/vermilion/vermilion.c
index ff61605..a543643 100644
--- a/kernel/drivers/video/fbdev/vermilion/vermilion.c
+++ b/kernel/drivers/video/fbdev/vermilion/vermilion.c
@@ -277,8 +277,10 @@
 
 	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;
 }
diff --git a/kernel/drivers/video/fbdev/via/via-core.c b/kernel/drivers/video/fbdev/via/via-core.c
index 89d7507..0363b47 100644
--- a/kernel/drivers/video/fbdev/via/via-core.c
+++ b/kernel/drivers/video/fbdev/via/via-core.c
@@ -725,7 +725,14 @@
 		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)
diff --git a/kernel/drivers/video/rockchip/Kconfig b/kernel/drivers/video/rockchip/Kconfig
index 2b5a072..6548dd3 100644
--- a/kernel/drivers/video/rockchip/Kconfig
+++ b/kernel/drivers/video/rockchip/Kconfig
@@ -5,5 +5,7 @@
 source "drivers/video/rockchip/rve/Kconfig"
 source "drivers/video/rockchip/iep/Kconfig"
 source "drivers/video/rockchip/mpp/Kconfig"
+source "drivers/video/rockchip/mpp_osal/Kconfig"
 source "drivers/video/rockchip/dvbm/Kconfig"
 source "drivers/video/rockchip/vehicle/Kconfig"
+source "drivers/video/rockchip/vtunnel/Kconfig"
diff --git a/kernel/drivers/video/rockchip/Makefile b/kernel/drivers/video/rockchip/Makefile
index 0b8a7bb..867ac56 100644
--- a/kernel/drivers/video/rockchip/Makefile
+++ b/kernel/drivers/video/rockchip/Makefile
@@ -5,5 +5,7 @@
 obj-$(CONFIG_ROCKCHIP_RVE) += rve/
 obj-$(CONFIG_IEP) += iep/
 obj-$(CONFIG_ROCKCHIP_MPP_SERVICE) += mpp/
+obj-$(CONFIG_ROCKCHIP_MPP_OSAL) += mpp_osal/
 obj-$(CONFIG_ROCKCHIP_DVBM) += dvbm/
 obj-$(CONFIG_VIDEO_REVERSE_IMAGE) += vehicle/
+obj-$(CONFIG_ROCKCHIP_VIDEO_TUNNEL) += vtunnel/
diff --git a/kernel/drivers/video/rockchip/mpp/mpp_common.c b/kernel/drivers/video/rockchip/mpp/mpp_common.c
index 0038df8..d43ebf4 100644
--- a/kernel/drivers/video/rockchip/mpp/mpp_common.c
+++ b/kernel/drivers/video/rockchip/mpp/mpp_common.c
@@ -36,12 +36,6 @@
 #include "mpp_common.h"
 #include "mpp_iommu.h"
 
-/* Use 'v' as magic number */
-#define MPP_IOC_MAGIC		'v'
-
-#define MPP_IOC_CFG_V1	_IOW(MPP_IOC_MAGIC, 1, unsigned int)
-#define MPP_IOC_CFG_V2	_IOW(MPP_IOC_MAGIC, 2, unsigned int)
-
 /* input parmater structure for version 1 */
 struct mpp_msg_v1 {
 	__u32 cmd;
@@ -49,14 +43,6 @@
 	__u32 size;
 	__u32 offset;
 	__u64 data_ptr;
-};
-
-#define MPP_BAT_MSG_DONE		(0x00000001)
-
-struct mpp_bat_msg {
-	__u64 flag;
-	__u32 fd;
-	__s32 ret;
 };
 
 #ifdef CONFIG_ROCKCHIP_MPP_PROC_FS
diff --git a/kernel/drivers/video/rockchip/mpp/mpp_common.h b/kernel/drivers/video/rockchip/mpp/mpp_common.h
index a088d62..8daeb08 100644
--- a/kernel/drivers/video/rockchip/mpp/mpp_common.h
+++ b/kernel/drivers/video/rockchip/mpp/mpp_common.h
@@ -24,6 +24,7 @@
 #include <linux/poll.h>
 #include <linux/platform_device.h>
 #include <soc/rockchip/pm_domains.h>
+#include <uapi/linux/rk-mpp.h>
 
 #define MHZ				(1000 * 1000)
 #define MPP_WORK_TIMEOUT_DELAY		(500)
@@ -31,13 +32,6 @@
 #define MPP_MAX_MSG_NUM			(16)
 #define MPP_MAX_REG_TRANS_NUM		(60)
 #define MPP_MAX_TASK_CAPACITY		(16)
-/* define flags for mpp_request */
-#define MPP_FLAGS_MULTI_MSG		(0x00000001)
-#define MPP_FLAGS_LAST_MSG		(0x00000002)
-#define MPP_FLAGS_REG_FD_NO_TRANS	(0x00000004)
-#define MPP_FLAGS_SCL_FD_NO_TRANS	(0x00000008)
-#define MPP_FLAGS_REG_NO_OFFSET		(0x00000010)
-#define MPP_FLAGS_SECURE_MODE		(0x00010000)
 
 /* grf mask for get value */
 #define MPP_GRF_VAL_MASK		(0xFFFF)
@@ -91,45 +85,6 @@
 	MPP_DRIVER_AV1DEC,
 	MPP_DRIVER_VDPP,
 	MPP_DRIVER_BUTT,
-};
-
-/**
- * Command type: keep the same as user space
- */
-enum MPP_DEV_COMMAND_TYPE {
-	MPP_CMD_QUERY_BASE		= 0,
-	MPP_CMD_QUERY_HW_SUPPORT	= MPP_CMD_QUERY_BASE + 0,
-	MPP_CMD_QUERY_HW_ID		= MPP_CMD_QUERY_BASE + 1,
-	MPP_CMD_QUERY_CMD_SUPPORT	= MPP_CMD_QUERY_BASE + 2,
-	MPP_CMD_QUERY_BUTT,
-
-	MPP_CMD_INIT_BASE		= 0x100,
-	MPP_CMD_INIT_CLIENT_TYPE	= MPP_CMD_INIT_BASE + 0,
-	MPP_CMD_INIT_DRIVER_DATA	= MPP_CMD_INIT_BASE + 1,
-	MPP_CMD_INIT_TRANS_TABLE	= MPP_CMD_INIT_BASE + 2,
-	MPP_CMD_INIT_BUTT,
-
-	MPP_CMD_SEND_BASE		= 0x200,
-	MPP_CMD_SET_REG_WRITE		= MPP_CMD_SEND_BASE + 0,
-	MPP_CMD_SET_REG_READ		= MPP_CMD_SEND_BASE + 1,
-	MPP_CMD_SET_REG_ADDR_OFFSET	= MPP_CMD_SEND_BASE + 2,
-	MPP_CMD_SET_RCB_INFO		= MPP_CMD_SEND_BASE + 3,
-	MPP_CMD_SET_SESSION_FD		= MPP_CMD_SEND_BASE + 4,
-	MPP_CMD_SEND_BUTT,
-
-	MPP_CMD_POLL_BASE		= 0x300,
-	MPP_CMD_POLL_HW_FINISH		= MPP_CMD_POLL_BASE + 0,
-	MPP_CMD_POLL_HW_IRQ		= MPP_CMD_POLL_BASE + 1,
-	MPP_CMD_POLL_BUTT,
-
-	MPP_CMD_CONTROL_BASE		= 0x400,
-	MPP_CMD_RESET_SESSION		= MPP_CMD_CONTROL_BASE + 0,
-	MPP_CMD_TRANS_FD_TO_IOVA	= MPP_CMD_CONTROL_BASE + 1,
-	MPP_CMD_RELEASE_FD		= MPP_CMD_CONTROL_BASE + 2,
-	MPP_CMD_SEND_CODEC_INFO		= MPP_CMD_CONTROL_BASE + 3,
-	MPP_CMD_CONTROL_BUTT,
-
-	MPP_CMD_BUTT,
 };
 
 enum MPP_CLOCK_MODE {
@@ -194,15 +149,6 @@
 struct mpp_dma_session;
 struct mpp_taskqueue;
 struct iommu_domain;
-
-/* data common struct for parse out */
-struct mpp_request {
-	__u32 cmd;
-	__u32 flags;
-	__u32 size;
-	__u32 offset;
-	void __user *data;
-};
 
 /* struct use to collect task set and poll message */
 struct mpp_task_msgs {
@@ -544,7 +490,6 @@
 	u32 core_id_max;
 	u32 core_count;
 	unsigned long dev_active_flags;
-	u32 iommu_fault;
 };
 
 struct mpp_reset_group {
diff --git a/kernel/drivers/video/rockchip/mpp/mpp_iommu.c b/kernel/drivers/video/rockchip/mpp/mpp_iommu.c
index 116ec66..1abbfb7 100644
--- a/kernel/drivers/video/rockchip/mpp/mpp_iommu.c
+++ b/kernel/drivers/video/rockchip/mpp/mpp_iommu.c
@@ -463,6 +463,12 @@
 	else
 		mpp_task_dump_hw_reg(mpp);
 
+	/*
+	 * Mask iommu irq, in order for iommu not repeatedly trigger pagefault.
+	 * Until the pagefault task finish by hw timeout.
+	 */
+	rockchip_iommu_mask_irq(mpp->dev);
+
 	return 0;
 }
 
diff --git a/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.c b/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.c
index 9d146c1..a463fc2 100644
--- a/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.c
+++ b/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.c
@@ -1571,6 +1571,7 @@
 	if (dec->ccu->ccu_mode == RKVDEC2_CCU_TASK_SOFT) {
 		mpp->dev_ops->task_worker = rkvdec2_soft_ccu_worker;
 		irq_proc = rkvdec2_soft_ccu_irq;
+		mpp->fault_handler = rkvdec2_soft_ccu_iommu_fault_handle;
 	} else if (dec->ccu->ccu_mode == RKVDEC2_CCU_TASK_HARD) {
 		if (mpp->core_id == 0 && mpp->task_capacity > 1) {
 			dec->link_dec->task_capacity = mpp->task_capacity;
@@ -1580,8 +1581,8 @@
 		}
 		mpp->dev_ops->task_worker = rkvdec2_hard_ccu_worker;
 		irq_proc = rkvdec2_hard_ccu_irq;
+		mpp->fault_handler = rkvdec2_hard_ccu_iommu_fault_handle;
 	}
-	mpp->fault_handler = rkvdec2_ccu_iommu_fault_handle;
 	kthread_init_work(&mpp->work, mpp->dev_ops->task_worker);
 
 	/* get irq request */
diff --git a/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.h b/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.h
index b4429e6..3eabdac 100644
--- a/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.h
+++ b/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.h
@@ -220,12 +220,7 @@
 	u32 task_index;
 	/* mmu info */
 	void __iomem *mmu_base;
-	u32 fault_iova;
 	u32 mmu_fault;
-	u32 mmu0_st;
-	u32 mmu1_st;
-	u32 mmu0_pta;
-	u32 mmu1_pta;
 };
 
 int mpp_set_rcbbuf(struct mpp_dev *mpp, struct mpp_session *session,
diff --git a/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c b/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c
index 0d87eb4..7c5a58d 100644
--- a/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c
+++ b/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c
@@ -1555,7 +1555,7 @@
 		if (mpp->disable)
 			continue;
 
-		dev_info(mpp->dev, "resetting...\n");
+		dev_info(mpp->dev, "resetting for err %#x\n", mpp->irq_status);
 		disable_hardirq(mpp->irq);
 
 		/* foce idle, disconnect core and ccu */
@@ -1618,61 +1618,104 @@
 	return &task->mpp_task;
 }
 
-static void rkvdec2_ccu_check_pagefault_info(struct mpp_dev *mpp)
+static struct mpp_dev *rkvdec2_ccu_dev_match_by_iommu(struct mpp_taskqueue *queue,
+						      struct device *iommu_dev)
 {
-	u32 i = 0;
+	struct mpp_dev *mpp = NULL;
+	struct rkvdec2_dev *dec = NULL;
+	u32 mmu[2] = {0, 0x40};
+	u32 i;
 
-	for (i = 0; i < mpp->queue->core_count; i++) {
-		struct mpp_dev *core = mpp->queue->cores[i];
-		struct rkvdec2_dev *dec = to_rkvdec2_dev(core);
-		void __iomem *mmu_base = dec->mmu_base;
-		u32 mmu0_st;
-		u32 mmu1_st;
-		u32 mmu0_pta;
-		u32 mmu1_pta;
+	for (i = 0; i < queue->core_count; i++) {
+		struct mpp_dev *core = queue->cores[i];
 
-		if (!mmu_base)
-			return;
-
-		#define FAULT_STATUS 0x7e2
-		rkvdec2_ccu_power_on(mpp->queue, dec->ccu);
-
-		mmu0_st = readl(mmu_base + 0x4);
-		mmu1_st = readl(mmu_base + 0x44);
-		mmu0_pta = readl(mmu_base + 0xc);
-		mmu1_pta = readl(mmu_base + 0x4c);
-
-		dec->mmu0_st = mmu0_st;
-		dec->mmu1_st = mmu1_st;
-		dec->mmu0_pta = mmu0_pta;
-		dec->mmu1_pta = mmu1_pta;
-
-		pr_err("core %d mmu0 %08x %08x mm1 %08x %08x\n",
-			core->core_id, mmu0_st, mmu0_pta, mmu1_st, mmu1_pta);
-		if ((mmu0_st & FAULT_STATUS) || (mmu1_st & FAULT_STATUS) ||
-		    mmu0_pta || mmu1_pta) {
-			dec->fault_iova = readl(dec->link_dec->reg_base + 0x4);
-			dec->mmu_fault = 1;
-			pr_err("core %d fault iova %08x\n", core->core_id, dec->fault_iova);
-			rockchip_iommu_mask_irq(core->dev);
-		} else {
-			dec->mmu_fault = 0;
-			dec->fault_iova = 0;
+		if (&core->iommu_info->pdev->dev == iommu_dev) {
+			mpp = core;
+			dec = to_rkvdec2_dev(mpp);
 		}
 	}
+
+	if (!dec || !dec->mmu_base)
+		goto out;
+
+	/* there are two iommus */
+	for (i = 0; i < 2; i++) {
+		u32 status = readl(dec->mmu_base + mmu[i] + 0x4);
+		u32 iova = readl(dec->mmu_base + mmu[i] + 0xc);
+		u32 is_write = (status & BIT(5)) ? 1 : 0;
+
+		if (status && iova)
+			dev_err(iommu_dev, "core %d pagfault at iova %#08x type %s status %#x\n",
+				mpp->core_id, iova, is_write ? "write" : "read", status);
+	}
+out:
+	return mpp;
 }
 
-int rkvdec2_ccu_iommu_fault_handle(struct iommu_domain *iommu,
-				   struct device *iommu_dev,
-				   unsigned long iova, int status, void *arg)
+int rkvdec2_soft_ccu_iommu_fault_handle(struct iommu_domain *iommu,
+					struct device *iommu_dev,
+					unsigned long iova, int status, void *arg)
 {
 	struct mpp_dev *mpp = (struct mpp_dev *)arg;
+	struct mpp_taskqueue *queue = mpp->queue;
+	struct mpp_task *mpp_task;
 
 	mpp_debug_enter();
 
-	rkvdec2_ccu_check_pagefault_info(mpp);
+	mpp = rkvdec2_ccu_dev_match_by_iommu(queue, iommu_dev);
+	if (!mpp) {
+		dev_err(iommu_dev, "iommu fault, but no dev match\n");
+		return 0;
+	}
+	mpp_task = mpp->cur_task;
+	if (mpp_task)
+		mpp_task_dump_mem_region(mpp, mpp_task);
 
-	mpp->queue->iommu_fault = 1;
+	/*
+	 * Mask iommu irq, in order for iommu not repeatedly trigger pagefault.
+	 * Until the pagefault task finish by hw timeout.
+	 */
+	rockchip_iommu_mask_irq(mpp->dev);
+	atomic_inc(&mpp->queue->reset_request);
+	kthread_queue_work(&mpp->queue->worker, &mpp->work);
+
+	mpp_debug_leave();
+
+	return 0;
+}
+
+int rkvdec2_hard_ccu_iommu_fault_handle(struct iommu_domain *iommu,
+					struct device *iommu_dev,
+					unsigned long iova, int status, void *arg)
+{
+	struct mpp_dev *mpp = (struct mpp_dev *)arg;
+	struct mpp_taskqueue *queue = mpp->queue;
+	struct mpp_task *mpp_task = NULL, *n;
+	struct rkvdec2_dev *dec;
+	u32 err_task_iova;
+
+	mpp_debug_enter();
+
+	mpp = rkvdec2_ccu_dev_match_by_iommu(queue, iommu_dev);
+	if (!mpp) {
+		dev_err(iommu_dev, "iommu fault, but no dev match\n");
+		return 0;
+	}
+
+	dec = to_rkvdec2_dev(mpp);
+	err_task_iova = readl(dec->link_dec->reg_base + 0x4);
+	dev_err(mpp->dev, "core %d err task iova %#08x\n", mpp->core_id, err_task_iova);
+	rockchip_iommu_mask_irq(mpp->dev);
+
+	list_for_each_entry_safe(mpp_task, n, &queue->running_list, queue_link) {
+		struct rkvdec2_task *task = to_rkvdec2_task(mpp_task);
+
+		if ((u32)task->table->iova == err_task_iova) {
+			mpp_task_dump_mem_region(mpp, mpp_task);
+			set_bit(TASK_STATE_ABORT, &mpp_task->state);
+			break;
+		}
+	}
 	atomic_inc(&mpp->queue->reset_request);
 	kthread_queue_work(&mpp->queue->worker, &mpp->work);
 
@@ -2041,7 +2084,7 @@
 		ccu_decoded_num = readl(ccu->reg_base + RKVDEC_CCU_DEC_NUM_BASE);
 		ccu_total_dec_num = readl(ccu->reg_base + RKVDEC_CCU_TOTAL_NUM_BASE);
 		mpp_debug(DEBUG_IRQ_CHECK,
-			  "session %d task %d w:h[%d %d] err %d irq_status %08x timeout=%u abort=%u iova %08x next %08x ccu[%d %d]\n",
+			  "session %d task %d w:h[%d %d] err %d irq_status %#x timeout=%u abort=%u iova %08x next %08x ccu[%d %d]\n",
 			  mpp_task->session->index, mpp_task->task_index, task->width,
 			  task->height, !!(irq_status & RKVDEC_INT_ERROR_MASK), irq_status,
 			  timeout_flag, abort_flag, (u32)task->table->iova,
@@ -2055,7 +2098,7 @@
 			cancel_delayed_work(&mpp_task->timeout_work);
 			mpp_task->hw_cycles = tb_reg[hw->tb_reg_cycle];
 			mpp_time_diff_with_hw_time(mpp_task, dec->cycle_clk->real_rate_hz);
-			task->irq_status = irq_status;
+			task->irq_status = irq_status ? irq_status : RKVDEC_ERROR_STA;
 
 			if (irq_status)
 				rkvdec2_hard_ccu_finish(hw, task);
@@ -2081,7 +2124,7 @@
 			/* Wake up the GET thread */
 			wake_up(&mpp_task->wait);
 			if ((irq_status & RKVDEC_INT_ERROR_MASK) || timeout_flag) {
-				pr_err("session %d task %d irq_status %08x timeout=%u abort=%u\n",
+				pr_err("session %d task %d irq_status %#x timeout=%u abort=%u\n",
 					mpp_task->session->index, mpp_task->task_index,
 					irq_status, timeout_flag, abort_flag);
 				atomic_inc(&queue->reset_request);
@@ -2339,51 +2382,6 @@
 	return 0;
 }
 
-static void rkvdec2_hard_ccu_handle_pagefault_task(struct rkvdec2_dev *dec,
-						   struct mpp_task *mpp_task)
-{
-	struct rkvdec2_task *task = to_rkvdec2_task(mpp_task);
-
-	mpp_dbg_ccu("session %d task %d w:h[%d %d] pagefault mmu0[%08x %08x] mmu1[%08x %08x] fault_iova %08x\n",
-		    mpp_task->session->index, mpp_task->task_index,
-		    task->width, task->height, dec->mmu0_st, dec->mmu0_pta,
-		    dec->mmu1_st, dec->mmu1_pta, dec->fault_iova);
-
-	set_bit(TASK_STATE_HANDLE, &mpp_task->state);
-	task->irq_status |= BIT(4);
-	cancel_delayed_work(&mpp_task->timeout_work);
-	rkvdec2_hard_ccu_finish(dec->link_dec->info, task);
-	set_bit(TASK_STATE_FINISH, &mpp_task->state);
-	set_bit(TASK_STATE_DONE, &mpp_task->state);
-	list_move_tail(&task->table->link, &dec->ccu->unused_list);
-	list_del_init(&mpp_task->queue_link);
-	/* Wake up the GET thread */
-	wake_up(&mpp_task->wait);
-	kref_put(&mpp_task->ref, mpp_free_task);
-	dec->mmu_fault = 0;
-	dec->fault_iova = 0;
-}
-
-static void rkvdec2_hard_ccu_pagefault_proc(struct mpp_taskqueue *queue)
-{
-	struct mpp_task *loop = NULL, *n;
-
-	list_for_each_entry_safe(loop, n, &queue->running_list, queue_link) {
-		struct rkvdec2_task *task = to_rkvdec2_task(loop);
-		u32 iova = (u32)task->table->iova;
-		u32 i;
-
-		for (i = 0; i < queue->core_count; i++) {
-			struct mpp_dev *core = queue->cores[i];
-			struct rkvdec2_dev *dec = to_rkvdec2_dev(core);
-
-			if (!dec->mmu_fault || dec->fault_iova != iova)
-				continue;
-			rkvdec2_hard_ccu_handle_pagefault_task(dec, loop);
-		}
-	}
-}
-
 static void rkvdec2_hard_ccu_resend_tasks(struct mpp_dev *mpp, struct mpp_taskqueue *queue)
 {
 	struct rkvdec2_task *task_pre = NULL;
@@ -2463,11 +2461,6 @@
 		/* reset process */
 		rkvdec2_hard_ccu_reset(queue, dec->ccu);
 		atomic_set(&queue->reset_request, 0);
-		/* if iommu pagefault, find the fault task and drop it */
-		if (queue->iommu_fault) {
-			rkvdec2_hard_ccu_pagefault_proc(queue);
-			queue->iommu_fault = 0;
-		}
 
 		/* relink running task iova in list, and resend them to hw */
 		if (!list_empty(&queue->running_list))
diff --git a/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h b/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h
index 7a0c0a0..518927e 100644
--- a/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h
+++ b/kernel/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h
@@ -221,9 +221,9 @@
 int rkvdec2_attach_ccu(struct device *dev, struct rkvdec2_dev *dec);
 int rkvdec2_ccu_link_init(struct platform_device *pdev, struct rkvdec2_dev *dec);
 void *rkvdec2_ccu_alloc_task(struct mpp_session *session, struct mpp_task_msgs *msgs);
-int rkvdec2_ccu_iommu_fault_handle(struct iommu_domain *iommu,
-				   struct device *iommu_dev,
-				   unsigned long iova, int status, void *arg);
+int rkvdec2_soft_ccu_iommu_fault_handle(struct iommu_domain *iommu,
+					struct device *iommu_dev,
+					unsigned long iova, int status, void *arg);
 irqreturn_t rkvdec2_soft_ccu_irq(int irq, void *param);
 void rkvdec2_soft_ccu_worker(struct kthread_work *work_s);
 
@@ -231,5 +231,8 @@
 			    struct rkvdec_link_dev *link_dec);
 irqreturn_t rkvdec2_hard_ccu_irq(int irq, void *param);
 void rkvdec2_hard_ccu_worker(struct kthread_work *work_s);
+int rkvdec2_hard_ccu_iommu_fault_handle(struct iommu_domain *iommu,
+					struct device *iommu_dev,
+					unsigned long iova, int status, void *arg);
 
 #endif
diff --git a/kernel/drivers/video/rockchip/mpp/mpp_rkvenc2.c b/kernel/drivers/video/rockchip/mpp/mpp_rkvenc2.c
index 5bd7054..111c106 100644
--- a/kernel/drivers/video/rockchip/mpp/mpp_rkvenc2.c
+++ b/kernel/drivers/video/rockchip/mpp/mpp_rkvenc2.c
@@ -32,6 +32,7 @@
 #include <soc/rockchip/rockchip_ipa.h>
 #include <soc/rockchip/rockchip_opp_select.h>
 #include <soc/rockchip/rockchip_system_monitor.h>
+#include <soc/rockchip/rockchip_iommu.h>
 
 #include "mpp_debug.h"
 #include "mpp_iommu.h"
@@ -44,6 +45,8 @@
 #define RKVENC_MAX_DCHS_ID			4
 #define RKVENC_MAX_SLICE_FIFO_LEN		256
 #define RKVENC_SCLR_DONE_STA			BIT(2)
+#define RKVENC_WDG				0x38
+#define TIMEOUT_MS				100
 
 #define to_rkvenc_info(info)		\
 		container_of(info, struct rkvenc_hw_info, hw)
@@ -127,6 +130,11 @@
 #define INT_STA_WBUS_ERR_STA	BIT(6)
 #define INT_STA_RBUS_ERR_STA	BIT(7)
 #define INT_STA_WDG_STA		BIT(8)
+
+#define INT_STA_ERROR		(INT_STA_BRSP_OTSD_STA | \
+				INT_STA_WBUS_ERR_STA | \
+				INT_STA_RBUS_ERR_STA | \
+				INT_STA_WDG_STA)
 
 #define DCHS_REG_OFFSET		(0x304)
 #define DCHS_CLASS_OFFSET	(33)
@@ -294,6 +302,7 @@
 #ifdef CONFIG_PM_DEVFREQ
 	struct rockchip_opp_info opp_info;
 	struct monitor_dev_info *mdev_info;
+	struct opp_table *opp_table;
 #endif
 };
 
@@ -1194,6 +1203,7 @@
 	struct rkvenc_task *task = to_rkvenc_task(mpp_task);
 	struct rkvenc_hw_info *hw = enc->hw_info;
 	u32 timing_en = mpp->srv->timing_en;
+	u32 timeout_thd;
 
 	mpp_debug_enter();
 
@@ -1242,11 +1252,18 @@
 	/* init current task */
 	mpp->cur_task = mpp_task;
 
+	/*
+	 * reconfig timeout threshold.
+	 * bit0-bit23,x1024 core clk cycles
+	 */
+	timeout_thd = mpp_read(mpp, RKVENC_WDG) & 0xff000000;
+	timeout_thd |= TIMEOUT_MS * clk_get_rate(enc->core_clk_info.clk) / 1024000;
+	mpp_write(mpp, RKVENC_WDG, timeout_thd);
+
 	mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY);
 
 	/* Flush the register before the start the device */
 	wmb();
-
 	mpp_write(mpp, enc->hw_info->enc_start_base, start_val);
 
 	mpp_task_run_end(mpp_task, timing_en);
@@ -1256,9 +1273,9 @@
 	return 0;
 }
 
-static void rkvenc2_read_slice_len(struct mpp_dev *mpp, struct rkvenc_task *task)
+static void rkvenc2_read_slice_len(struct mpp_dev *mpp, struct rkvenc_task *task,
+				   u32 last)
 {
-	u32 last = mpp_read_relaxed(mpp, 0x002c) & INT_STA_ENC_DONE_STA;
 	u32 sli_num = mpp_read_relaxed(mpp, RKVENC2_REG_SLICE_NUM_BASE);
 	union rkvenc2_slice_len_info slice_info;
 	u32 task_id = task->mpp_task.task_id;
@@ -1298,46 +1315,49 @@
 	struct rkvenc_hw_info *hw = enc->hw_info;
 	struct mpp_task *mpp_task = NULL;
 	struct rkvenc_task *task = NULL;
-	u32 int_clear = 1;
-	u32 irq_mask = 0;
+	u32 irq_status;
 	int ret = IRQ_NONE;
 
 	mpp_debug_enter();
 
-	mpp->irq_status = mpp_read(mpp, hw->int_sta_base);
-	if (!mpp->irq_status)
+	irq_status = mpp_read(mpp, hw->int_sta_base);
+
+	mpp_debug(DEBUG_IRQ_STATUS, "%s irq_status: %08x\n",
+		  dev_name(mpp->dev), irq_status);
+
+	if (!irq_status)
 		return ret;
+
+	/* clear int first */
+	mpp_write(mpp, hw->int_clr_base, irq_status);
+
+	/*
+	 * prevent watch dog irq storm.
+	 * The encoder did not stop working when watchdog interrupt is triggered,
+	 * it still check timeout and trigger watch dog irq.
+	 */
+	if (irq_status & INT_STA_WDG_STA)
+		mpp_write(mpp, hw->int_mask_base, INT_STA_WDG_STA);
 
 	if (mpp->cur_task) {
 		mpp_task = mpp->cur_task;
 		task = to_rkvenc_task(mpp_task);
 	}
 
-	if (mpp->irq_status & INT_STA_ENC_DONE_STA) {
-		if (task) {
-			if (task->task_split)
-				rkvenc2_read_slice_len(mpp, task);
+	/* 1. read slice number and slice length */
+	if (task && task->task_split &&
+	    (irq_status & (INT_STA_SLC_DONE_STA | INT_STA_ENC_DONE_STA))) {
+		mpp_time_part_diff(mpp_task);
+		rkvenc2_read_slice_len(mpp, task, irq_status & INT_STA_ENC_DONE_STA);
+		wake_up(&mpp_task->wait);
+	}
 
-			wake_up(&mpp_task->wait);
-		}
+	/* 2. process slice irq */
+	if (irq_status & INT_STA_SLC_DONE_STA)
+		ret = IRQ_HANDLED;
 
-		irq_mask = INT_STA_ENC_DONE_STA;
-		ret = IRQ_WAKE_THREAD;
-		if (enc->bs_overflow) {
-			mpp->irq_status |= INT_STA_BSF_OFLW_STA;
-			enc->bs_overflow = 0;
-		}
-	} else if (mpp->irq_status & INT_STA_SLC_DONE_STA) {
-		if (task && task->task_split) {
-			mpp_time_part_diff(mpp_task);
-
-			rkvenc2_read_slice_len(mpp, task);
-			wake_up(&mpp_task->wait);
-		}
-
-		irq_mask = INT_STA_ENC_DONE_STA;
-		int_clear = 0;
-	} else if (mpp->irq_status & INT_STA_BSF_OFLW_STA) {
+	/* 3. process bitstream overflow */
+	if (irq_status & INT_STA_BSF_OFLW_STA) {
 		u32 bs_rd = mpp_read(mpp, RKVENC2_REG_ADR_BSBR);
 		u32 bs_wr = mpp_read(mpp, RKVENC2_REG_ST_BSB);
 		u32 bs_top = mpp_read(mpp, RKVENC2_REG_ADR_BSBT);
@@ -1349,33 +1369,43 @@
 		bs_wr += 128;
 		if (bs_wr >= bs_top)
 			bs_wr = bs_bot;
-		/* clear int first */
-		mpp_write(mpp, hw->int_clr_base, mpp->irq_status);
+
 		/* update write addr for enc continue */
 		mpp_write(mpp, RKVENC2_REG_ADR_BSBS, bs_wr);
 		enc->bs_overflow = 1;
-		irq_mask = 0;
-		int_clear = 0;
-		ret = IRQ_HANDLED;
-	} else {
-		dev_err(mpp->dev, "found error status %08x\n", mpp->irq_status);
 
-		irq_mask = mpp->irq_status;
+		ret = IRQ_HANDLED;
+	}
+
+	/* 4. process frame irq */
+	if (irq_status & INT_STA_ENC_DONE_STA) {
+		mpp->irq_status = irq_status;
+
+		if (enc->bs_overflow) {
+			mpp->irq_status |= INT_STA_BSF_OFLW_STA;
+			enc->bs_overflow = 0;
+		}
+
 		ret = IRQ_WAKE_THREAD;
 	}
 
-	if (irq_mask)
-		mpp_write(mpp, hw->int_mask_base, irq_mask);
+	/* 5. process error irq */
+	if (irq_status & INT_STA_ERROR) {
+		mpp->irq_status = irq_status;
 
-	if (int_clear) {
-		mpp_write(mpp, hw->int_clr_base, mpp->irq_status);
-		udelay(5);
-		mpp_write(mpp, hw->int_sta_base, 0);
+		dev_err(mpp->dev, "found error status %08x\n", irq_status);
+
+		ret = IRQ_WAKE_THREAD;
 	}
 
 	mpp_debug_leave();
 
 	return ret;
+}
+
+static int vepu540c_irq(struct mpp_dev *mpp)
+{
+	return rkvenc_irq(mpp);
 }
 
 static int rkvenc_isr(struct mpp_dev *mpp)
@@ -1405,9 +1435,6 @@
 	task->irq_status = mpp->irq_status;
 
 	rkvenc2_update_dchs(enc, task);
-
-	mpp_debug(DEBUG_IRQ_STATUS, "%s irq_status: %08x\n",
-		  dev_name(mpp->dev), task->irq_status);
 
 	if (task->irq_status & enc->hw_info->err_mask) {
 		atomic_inc(&mpp->reset_request);
@@ -1458,7 +1485,7 @@
 	if (task->bs_buf) {
 		u32 bs_size = mpp_read(mpp, 0x4064);
 
-		mpp_dma_buf_sync(task->bs_buf, 0, bs_size / 8 + task->offset_bs,
+		mpp_dma_buf_sync(task->bs_buf, 0, bs_size + task->offset_bs,
 				 DMA_FROM_DEVICE, true);
 	}
 
@@ -1785,16 +1812,19 @@
 		if (IS_ERR(reg_table))
 			return PTR_ERR(reg_table);
 	}
+	enc->opp_table = reg_table;
 
 	clk_table = dev_pm_opp_set_clkname(dev, "clk_core");
-	if (IS_ERR(clk_table))
-		return PTR_ERR(clk_table);
+	if (IS_ERR(clk_table)) {
+		ret = PTR_ERR(clk_table);
+		goto put_opp_reg;
+	}
 
 	rockchip_get_opp_data(rockchip_rkvenc_of_match, &enc->opp_info);
 	ret = rockchip_init_opp_table(dev, &enc->opp_info, "leakage", "venc");
 	if (ret) {
 		dev_err(dev, "failed to init_opp_table\n");
-		return ret;
+		goto put_opp_clk;
 	}
 
 	enc->mdev_info = rockchip_system_monitor_register(dev, &venc_mdevp);
@@ -1803,6 +1833,14 @@
 		enc->mdev_info = NULL;
 	}
 
+	return 0;
+
+put_opp_clk:
+	dev_pm_opp_put_clkname(enc->opp_table);
+put_opp_reg:
+	dev_pm_opp_put_regulators(enc->opp_table);
+	enc->opp_table = NULL;
+
 	return ret;
 }
 
@@ -1810,8 +1848,16 @@
 {
 	struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
 
-	if (enc->mdev_info)
+	if (enc->mdev_info) {
 		rockchip_system_monitor_unregister(enc->mdev_info);
+		enc->mdev_info = NULL;
+	}
+	if (enc->opp_table) {
+		rockchip_uninit_opp_table(mpp->dev, &enc->opp_info);
+		dev_pm_opp_put_clkname(enc->opp_table);
+		dev_pm_opp_put_regulators(enc->opp_table);
+		enc->opp_table = NULL;
+	}
 
 	return 0;
 }
@@ -1880,7 +1926,7 @@
 
 	/* safe reset */
 	mpp_write(mpp, hw->int_mask_base, 0x3FF);
-	mpp_write(mpp, hw->enc_clr_base, 0x1);
+	mpp_write(mpp, hw->enc_clr_base, 0x3);
 	ret = readl_relaxed_poll_timeout(mpp->reg_base + hw->int_sta_base,
 					 rst_status,
 					 rst_status & RKVENC_SCLR_DONE_STA,
@@ -2169,6 +2215,20 @@
 	.dump_session = rkvenc_dump_session,
 };
 
+static struct mpp_dev_ops vepu540c_dev_ops_v2 = {
+	.wait_result = rkvenc2_wait_result,
+	.alloc_task = rkvenc_alloc_task,
+	.run = rkvenc_run,
+	.irq = vepu540c_irq,
+	.isr = rkvenc_isr,
+	.finish = rkvenc_finish,
+	.result = rkvenc_result,
+	.free_task = rkvenc_free_task,
+	.ioctl = rkvenc_control,
+	.init_session = rkvenc_init_session,
+	.free_session = rkvenc_free_session,
+	.dump_session = rkvenc_dump_session,
+};
 
 static const struct mpp_dev_var rkvenc_v2_data = {
 	.device_type = MPP_DEVICE_RKVENC,
@@ -2183,7 +2243,7 @@
 	.hw_info = &rkvenc_540c_hw_info.hw,
 	.trans_info = trans_rkvenc_540c,
 	.hw_ops = &rkvenc_hw_ops,
-	.dev_ops = &rkvenc_dev_ops_v2,
+	.dev_ops = &vepu540c_dev_ops_v2,
 };
 
 static const struct mpp_dev_var rkvenc_ccu_data = {
@@ -2404,13 +2464,32 @@
 {
 	struct mpp_dev *mpp = (struct mpp_dev *)arg;
 	struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
-	struct mpp_task *mpp_task = mpp->cur_task;
+	struct mpp_task *mpp_task;
+	struct rkvenc_ccu *ccu = enc->ccu;
 
+	if (ccu) {
+		struct rkvenc_dev *core = NULL, *n;
+
+		list_for_each_entry_safe(core, n, &ccu->core_list, core_link) {
+			if (core->mpp.iommu_info &&
+			    (&core->mpp.iommu_info->pdev->dev == iommu_dev)) {
+				mpp = &core->mpp;
+				break;
+			}
+		}
+	}
+	mpp_task = mpp->cur_task;
 	dev_info(mpp->dev, "core %d page fault found dchs %08x\n",
 		 mpp->core_id, mpp_read_relaxed(&enc->mpp, DCHS_REG_OFFSET));
 
 	if (mpp_task)
 		mpp_task_dump_mem_region(mpp, mpp_task);
+
+	/*
+	 * Mask iommu irq, in order for iommu not repeatedly trigger pagefault.
+	 * Until the pagefault task finish by hw timeout.
+	 */
+	rockchip_iommu_mask_irq(mpp->dev);
 
 	return 0;
 }
@@ -2455,7 +2534,7 @@
 	ret = devm_request_threaded_irq(dev, mpp->irq,
 					mpp_dev_irq,
 					mpp_dev_isr_sched,
-					IRQF_SHARED,
+					IRQF_ONESHOT,
 					dev_name(dev), mpp);
 	if (ret) {
 		dev_err(dev, "register interrupter runtime failed\n");
diff --git a/kernel/drivers/video/rockchip/mpp/mpp_vepu2.c b/kernel/drivers/video/rockchip/mpp/mpp_vepu2.c
index 395a5b6..fb5f5e5 100644
--- a/kernel/drivers/video/rockchip/mpp/mpp_vepu2.c
+++ b/kernel/drivers/video/rockchip/mpp/mpp_vepu2.c
@@ -22,6 +22,7 @@
 #include <linux/proc_fs.h>
 #include <linux/nospec.h>
 #include <soc/rockchip/pm_domains.h>
+#include <soc/rockchip/rockchip_iommu.h>
 
 #include "mpp_debug.h"
 #include "mpp_common.h"
@@ -882,6 +883,48 @@
 	return 0;
 }
 
+static int vepu2_iommu_fault_handle(struct iommu_domain *iommu, struct device *iommu_dev,
+				    unsigned long iova, int status, void *arg)
+{
+	struct mpp_dev *mpp = (struct mpp_dev *)arg;
+	struct mpp_task *mpp_task;
+	struct vepu_dev *enc = to_vepu_dev(mpp);
+	struct vepu_ccu *ccu = enc->ccu;
+
+	dev_err(iommu_dev, "fault addr 0x%08lx status %x arg %p\n",
+		iova, status, arg);
+
+	if (ccu) {
+		int i;
+		struct mpp_dev *core;
+
+		for (i = 0; i < ccu->core_num; i++) {
+			core = ccu->cores[i];
+			if (core->iommu_info && (&core->iommu_info->pdev->dev == iommu_dev)) {
+				mpp = core;
+				break;
+			}
+		}
+	}
+
+	if (!mpp) {
+		dev_err(iommu_dev, "pagefault without device to handle\n");
+		return 0;
+	}
+	mpp_task = mpp->cur_task;
+	if (mpp_task)
+		mpp_task_dump_mem_region(mpp, mpp_task);
+
+	mpp_task_dump_hw_reg(mpp);
+	/*
+	 * Mask iommu irq, in order for iommu not repeatedly trigger pagefault.
+	 * Until the pagefault task finish by hw timeout.
+	 */
+	rockchip_iommu_mask_irq(mpp->dev);
+
+	return 0;
+}
+
 static struct mpp_hw_ops vepu_v2_hw_ops = {
 	.init = vepu_init,
 	.clk_on = vepu_clk_on,
@@ -1100,6 +1143,7 @@
 		return -EINVAL;
 	}
 
+	mpp->fault_handler = vepu2_iommu_fault_handle;
 	mpp->session_max_buffers = VEPU2_SESSION_MAX_BUFFERS;
 	vepu_procfs_init(mpp);
 	vepu_procfs_ccu_init(mpp);
@@ -1149,6 +1193,7 @@
 		return -EINVAL;
 	}
 
+	mpp->fault_handler = vepu2_iommu_fault_handle;
 	mpp->session_max_buffers = VEPU2_SESSION_MAX_BUFFERS;
 	vepu_procfs_init(mpp);
 	/* register current device to mpp service */
diff --git a/kernel/drivers/video/rockchip/mpp_osal/Kconfig b/kernel/drivers/video/rockchip/mpp_osal/Kconfig
new file mode 100644
index 0000000..75cd702
--- /dev/null
+++ b/kernel/drivers/video/rockchip/mpp_osal/Kconfig
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+config ROCKCHIP_MPP_OSAL
+	bool "mpp osal"
+	depends on CPU_RV1106
+	default y
+	help
+	  rockchip mpp osal adapt for kmpp
diff --git a/kernel/drivers/video/rockchip/mpp_osal/Makefile b/kernel/drivers/video/rockchip/mpp_osal/Makefile
new file mode 100644
index 0000000..f4ca964
--- /dev/null
+++ b/kernel/drivers/video/rockchip/mpp_osal/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+obj-$(CONFIG_ROCKCHIP_MPP_OSAL) += mpp_osal.o
diff --git a/kernel/drivers/video/rockchip/mpp_osal/mpp_osal.c b/kernel/drivers/video/rockchip/mpp_osal/mpp_osal.c
new file mode 100644
index 0000000..a778b19
--- /dev/null
+++ b/kernel/drivers/video/rockchip/mpp_osal/mpp_osal.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd
+ *
+ */
+#include "mpp_osal.h"
+
+struct device_node *mpp_dev_of_node(struct device *dev)
+{
+	return dev_of_node(dev);
+}
+EXPORT_SYMBOL(mpp_dev_of_node);
+
+void mpp_pm_relax(struct device *dev)
+{
+	return pm_relax(dev);
+}
+EXPORT_SYMBOL(mpp_pm_relax);
+
+void mpp_pm_stay_awake(struct device *dev)
+{
+	return pm_stay_awake(dev);
+}
+EXPORT_SYMBOL(mpp_pm_stay_awake);
+
+int mpp_device_init_wakeup(struct device *dev, bool enable)
+{
+	return device_init_wakeup(dev, enable);
+}
+EXPORT_SYMBOL(mpp_device_init_wakeup);
diff --git a/kernel/drivers/video/rockchip/mpp_osal/mpp_osal.h b/kernel/drivers/video/rockchip/mpp_osal/mpp_osal.h
new file mode 100644
index 0000000..d798dfd
--- /dev/null
+++ b/kernel/drivers/video/rockchip/mpp_osal/mpp_osal.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd
+ *
+ */
+
+#ifndef __ROCKCHIP_MPP_OSAL_H__
+#define __ROCKCHIP_MPP_OSAL_H__
+
+#include <linux/platform_device.h>
+#include <linux/pm_wakeup.h>
+
+struct device_node *mpp_dev_of_node(struct device *dev);
+void mpp_pm_relax(struct device *dev);
+void mpp_pm_stay_awake(struct device *dev);
+int mpp_device_init_wakeup(struct device *dev, bool enable);
+
+#endif
diff --git a/kernel/drivers/video/rockchip/rga2/rga2_drv.c b/kernel/drivers/video/rockchip/rga2/rga2_drv.c
index 9aeb89a..ca5218f 100644
--- a/kernel/drivers/video/rockchip/rga2/rga2_drv.c
+++ b/kernel/drivers/video/rockchip/rga2/rga2_drv.c
@@ -76,7 +76,6 @@
 #define RGA2_PHY_PAGE_SIZE	(((8192 * 8192 * 4) / 4096) + 1)
 
 ktime_t rga2_start;
-ktime_t rga2_end;
 int rga2_flag;
 int first_RGA2_proc;
 static int rk3368;
@@ -1179,9 +1178,11 @@
 
 #ifdef CONFIG_ROCKCHIP_RGA2_DEBUGGER
 	if (RGA2_TEST_TIME) {
-		rga2_end = ktime_get();
-		rga2_end = ktime_sub(rga2_end, rga2_start);
-		DBG("sync one cmd end time %d\n", (int)ktime_to_us(rga2_end));
+		ktime_t rga2_cmd_end;
+
+		rga2_cmd_end = ktime_get();
+		rga2_cmd_end = ktime_sub(rga2_cmd_end, rga2_start);
+		DBG("sync one cmd end time %d us\n", (int)ktime_to_us(rga2_cmd_end));
 	}
 #endif
 	if (ret == -ETIMEDOUT && try--) {
@@ -1657,6 +1658,14 @@
 	if (RGA2_INT_FLAG)
 		INFO("irqthread INT[%x],STATS[%x]\n", rga2_read(RGA2_INT),
 		     rga2_read(RGA2_STATUS));
+
+	if (RGA2_TEST_TIME) {
+		ktime_t rga2_hw_end;
+
+		rga2_hw_end = ktime_get();
+		rga2_hw_end = ktime_sub(rga2_hw_end, rga2_start);
+		DBG("RGA hardware cost time %d us\n", (int)ktime_to_us(rga2_hw_end));
+	}
 #endif
 	RGA2_flush_page();
 	mutex_lock(&rga2_service.lock);
diff --git a/kernel/drivers/video/rockchip/rga3/include/rga.h b/kernel/drivers/video/rockchip/rga3/include/rga.h
index 34a9245..2a60a1a 100644
--- a/kernel/drivers/video/rockchip/rga3/include/rga.h
+++ b/kernel/drivers/video/rockchip/rga3/include/rga.h
@@ -86,6 +86,12 @@
 	RGA_SCALE_DOWN_AVG	= 0x1,
 };
 
+enum RGA_SCHEDULER_CORE {
+	RGA_SCHEDULER_RGA3_CORE0 = 1 << 0,
+	RGA_SCHEDULER_RGA3_CORE1 = 1 << 1,
+	RGA_SCHEDULER_RGA2_CORE0 = 1 << 2,
+};
+
 /* RGA process mode enum */
 enum {
 	BITBLT_MODE			= 0x0,
diff --git a/kernel/drivers/video/rockchip/rga3/include/rga_common.h b/kernel/drivers/video/rockchip/rga3/include/rga_common.h
index 67aad7b..32e83cc 100644
--- a/kernel/drivers/video/rockchip/rga3/include/rga_common.h
+++ b/kernel/drivers/video/rockchip/rga3/include/rga_common.h
@@ -37,6 +37,7 @@
 const char *rga_get_blend_mode_str(enum rga_alpha_blend_mode mode);
 const char *rga_get_memory_type_str(uint8_t type);
 const char *rga_get_mmu_type_str(enum rga_mmu mmu_type);
+const char *rga_get_core_name(enum RGA_SCHEDULER_CORE core);
 
 void rga_convert_addr(struct rga_img_info_t *img, bool before_vir_get_channel);
 void rga_swap_pd_mode(struct rga_req *req_rga);
diff --git a/kernel/drivers/video/rockchip/rga3/include/rga_drv.h b/kernel/drivers/video/rockchip/rga3/include/rga_drv.h
index fff02e1..e9743a4 100644
--- a/kernel/drivers/video/rockchip/rga3/include/rga_drv.h
+++ b/kernel/drivers/video/rockchip/rga3/include/rga_drv.h
@@ -87,7 +87,7 @@
 
 #define DRIVER_MAJOR_VERISON		1
 #define DRIVER_MINOR_VERSION		3
-#define DRIVER_REVISION_VERSION		0
+#define DRIVER_REVISION_VERSION		1
 #define DRIVER_PATCH_VERSION
 
 #define DRIVER_VERSION (STR(DRIVER_MAJOR_VERISON) "." STR(DRIVER_MINOR_VERSION) \
@@ -97,7 +97,7 @@
 #define RGA_JOB_TIMEOUT_DELAY		HZ
 #define RGA_RESET_TIMEOUT			1000
 
-#define RGA_MAX_SCHEDULER	3
+#define RGA_MAX_SCHEDULER	RGA_HW_SIZE
 #define RGA_MAX_BUS_CLK		10
 
 #define RGA_BUFFER_POOL_MAX_SIZE	64
diff --git a/kernel/drivers/video/rockchip/rga3/include/rga_hw_config.h b/kernel/drivers/video/rockchip/rga3/include/rga_hw_config.h
index 73f05f7..46f7531 100644
--- a/kernel/drivers/video/rockchip/rga3/include/rga_hw_config.h
+++ b/kernel/drivers/video/rockchip/rga3/include/rga_hw_config.h
@@ -16,20 +16,22 @@
 	RGA_IOMMU	= 2,
 };
 
+enum rga_hw_support_format_index {
+	RGA_RASTER_INDEX,
+	RGA_AFBC16x16_INDEX,
+	RGA_TILE8x8_INDEX,
+	RGA_FORMAT_INDEX_BUTT,
+};
+
 struct rga_win_data {
 	const char *name;
-	const uint32_t *raster_formats;
-	const uint32_t *fbc_formats;
-	const uint32_t *tile_formats;
-	uint32_t num_of_raster_formats;
-	uint32_t num_of_fbc_formats;
-	uint32_t num_of_tile_formats;
+	const uint32_t *formats[RGA_FORMAT_INDEX_BUTT];
+	uint32_t formats_count[RGA_FORMAT_INDEX_BUTT];
 
-	const unsigned int supported_rotations;
-	const unsigned int scale_up_mode;
-	const unsigned int scale_down_mode;
-	const unsigned int rd_mode;
-
+	uint32_t supported_rotations;
+	uint32_t scale_up_mode;
+	uint32_t scale_down_mode;
+	uint32_t rd_mode;
 };
 
 struct rga_rect {
diff --git a/kernel/drivers/video/rockchip/rga3/include/rga_mm.h b/kernel/drivers/video/rockchip/rga3/include/rga_mm.h
index 0bb8e92..d68fd75 100644
--- a/kernel/drivers/video/rockchip/rga3/include/rga_mm.h
+++ b/kernel/drivers/video/rockchip/rga3/include/rga_mm.h
@@ -56,8 +56,8 @@
 int rga_mm_map_job_info(struct rga_job *job);
 void rga_mm_unmap_job_info(struct rga_job *job);
 
-uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer,
-			      struct rga_session *session);
+int rga_mm_import_buffer(struct rga_external_buffer *external_buffer,
+			 struct rga_session *session);
 int rga_mm_release_buffer(uint32_t handle);
 int rga_mm_session_release_buffer(struct rga_session *session);
 
diff --git a/kernel/drivers/video/rockchip/rga3/rga2_reg_info.c b/kernel/drivers/video/rockchip/rga3/rga2_reg_info.c
index 309159d..8792e8d 100644
--- a/kernel/drivers/video/rockchip/rga3/rga2_reg_info.c
+++ b/kernel/drivers/video/rockchip/rga3/rga2_reg_info.c
@@ -2323,6 +2323,7 @@
 	struct rga2_req req;
 	int ret = 0;
 	struct rga_scheduler_t *scheduler = NULL;
+	ktime_t timestamp = ktime_get();
 
 	scheduler = job->scheduler;
 	if (unlikely(scheduler == NULL)) {
@@ -2395,6 +2396,10 @@
 		pr_err("gen reg info error\n");
 		return -EINVAL;
 	}
+
+	if (DEBUGGER_EN(TIME))
+		pr_info("request[%d], generate register cost time %lld us\n",
+			job->request_id, ktime_us_delta(ktime_get(), timestamp));
 
 	return ret;
 }
@@ -2599,8 +2604,8 @@
 			rga_read(RGA2_INT, scheduler));
 
 	if (DEBUGGER_EN(TIME))
-		pr_info("set cmd use time = %lld\n",
-			ktime_us_delta(now, job->timestamp));
+		pr_info("request[%d], set register cost time %lld us\n",
+			job->request_id, ktime_us_delta(now, job->timestamp));
 
 	job->hw_running_time = now;
 	job->hw_recoder_time = now;
diff --git a/kernel/drivers/video/rockchip/rga3/rga3_reg_info.c b/kernel/drivers/video/rockchip/rga3/rga3_reg_info.c
index 5c1945b..2b61833 100644
--- a/kernel/drivers/video/rockchip/rga3/rga3_reg_info.c
+++ b/kernel/drivers/video/rockchip/rga3/rga3_reg_info.c
@@ -1955,6 +1955,7 @@
 	struct rga3_req req;
 	int ret = 0;
 	struct rga_scheduler_t *scheduler = NULL;
+	ktime_t timestamp = ktime_get();
 
 	scheduler = job->scheduler;
 	if (unlikely(scheduler == NULL)) {
@@ -1983,6 +1984,10 @@
 		pr_err("RKA: gen reg info error\n");
 		return -EINVAL;
 	}
+
+	if (DEBUGGER_EN(TIME))
+		pr_info("request[%d], generate register cost time %lld us\n",
+			job->request_id, ktime_us_delta(ktime_get(), timestamp));
 
 	return ret;
 }
@@ -2070,7 +2075,8 @@
 	}
 
 	if (DEBUGGER_EN(TIME))
-		pr_info("set cmd use time = %lld\n", ktime_us_delta(now, job->timestamp));
+		pr_info("request[%d], set register cost time %lld us\n",
+			job->request_id, ktime_us_delta(now, job->timestamp));
 
 	job->hw_running_time = now;
 	job->hw_recoder_time = now;
diff --git a/kernel/drivers/video/rockchip/rga3/rga_common.c b/kernel/drivers/video/rockchip/rga3/rga_common.c
index 6f8b579..80d4821 100644
--- a/kernel/drivers/video/rockchip/rga3/rga_common.c
+++ b/kernel/drivers/video/rockchip/rga3/rga_common.c
@@ -604,6 +604,20 @@
 	}
 }
 
+const char *rga_get_core_name(enum RGA_SCHEDULER_CORE core)
+{
+	switch (core) {
+	case RGA_SCHEDULER_RGA3_CORE0:
+		return "RGA3_core0";
+	case RGA_SCHEDULER_RGA3_CORE1:
+		return "RGA3_core1";
+	case RGA_SCHEDULER_RGA2_CORE0:
+		return "RGA2_core0";
+	default:
+		return "unknown_core";
+	}
+}
+
 void rga_convert_addr(struct rga_img_info_t *img, bool before_vir_get_channel)
 {
 	/*
diff --git a/kernel/drivers/video/rockchip/rga3/rga_drv.c b/kernel/drivers/video/rockchip/rga3/rga_drv.c
index 226fb77..ec3c345 100644
--- a/kernel/drivers/video/rockchip/rga3/rga_drv.c
+++ b/kernel/drivers/video/rockchip/rga3/rga_drv.c
@@ -650,7 +650,7 @@
 		}
 
 		ret = rga_mm_import_buffer(&external_buffer[i], session);
-		if (ret == 0) {
+		if (ret <= 0) {
 			pr_err("buffer[%d] mm import buffer failed! memory = 0x%lx, type = %s(0x%x)\n",
 			       i, (unsigned long)external_buffer[i].memory,
 			       rga_get_memory_type_str(external_buffer[i].type),
@@ -884,11 +884,6 @@
 	rga_req = request->task_list;
 	/* In the BLIT_SYNC/BLIT_ASYNC command, in_fence_fd needs to be set. */
 	request->acquire_fence_fd = rga_req->in_fence_fd;
-
-	if (DEBUGGER_EN(MSG)) {
-		pr_info("Blit mode: request id = %d", user_request.id);
-		rga_cmd_print_debug_info(rga_req);
-	}
 
 	ret = rga_request_submit(request);
 	if (ret < 0) {
diff --git a/kernel/drivers/video/rockchip/rga3/rga_hw_config.c b/kernel/drivers/video/rockchip/rga3/rga_hw_config.c
index 4af4a85..0cf2599 100644
--- a/kernel/drivers/video/rockchip/rga3/rga_hw_config.c
+++ b/kernel/drivers/video/rockchip/rga3/rga_hw_config.c
@@ -175,12 +175,12 @@
 const struct rga_win_data rga3_win_data[] = {
 	{
 		.name = "rga3-win0",
-		.raster_formats = rga3_input_raster_format,
-		.num_of_raster_formats = ARRAY_SIZE(rga3_input_raster_format),
-		.fbc_formats = rga3_fbcd_format,
-		.num_of_fbc_formats = ARRAY_SIZE(rga3_fbcd_format),
-		.tile_formats = rga3_tile_format,
-		.num_of_tile_formats = ARRAY_SIZE(rga3_tile_format),
+		.formats[RGA_RASTER_INDEX] = rga3_input_raster_format,
+		.formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga3_input_raster_format),
+		.formats[RGA_AFBC16x16_INDEX] = rga3_fbcd_format,
+		.formats_count[RGA_AFBC16x16_INDEX] = ARRAY_SIZE(rga3_fbcd_format),
+		.formats[RGA_TILE8x8_INDEX] = rga3_tile_format,
+		.formats_count[RGA_TILE8x8_INDEX] = ARRAY_SIZE(rga3_tile_format),
 		.supported_rotations = RGA_MODE_ROTATE_MASK,
 		.scale_up_mode = RGA_SCALE_UP_BIC,
 		.scale_down_mode = RGA_SCALE_DOWN_AVG,
@@ -190,12 +190,12 @@
 
 	{
 		.name = "rga3-win1",
-		.raster_formats = rga3_input_raster_format,
-		.num_of_raster_formats = ARRAY_SIZE(rga3_input_raster_format),
-		.fbc_formats = rga3_fbcd_format,
-		.num_of_fbc_formats = ARRAY_SIZE(rga3_fbcd_format),
-		.tile_formats = rga3_tile_format,
-		.num_of_tile_formats = ARRAY_SIZE(rga3_tile_format),
+		.formats[RGA_RASTER_INDEX] = rga3_input_raster_format,
+		.formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga3_input_raster_format),
+		.formats[RGA_AFBC16x16_INDEX] = rga3_fbcd_format,
+		.formats_count[RGA_AFBC16x16_INDEX] = ARRAY_SIZE(rga3_fbcd_format),
+		.formats[RGA_TILE8x8_INDEX] = rga3_tile_format,
+		.formats_count[RGA_TILE8x8_INDEX] = ARRAY_SIZE(rga3_tile_format),
 		.supported_rotations = RGA_MODE_ROTATE_MASK,
 		.scale_up_mode = RGA_SCALE_UP_BIC,
 		.scale_down_mode = RGA_SCALE_DOWN_AVG,
@@ -205,12 +205,12 @@
 
 	{
 		.name = "rga3-wr",
-		.raster_formats = rga3_output_raster_format,
-		.num_of_raster_formats = ARRAY_SIZE(rga3_output_raster_format),
-		.fbc_formats = rga3_fbcd_format,
-		.num_of_fbc_formats = ARRAY_SIZE(rga3_fbcd_format),
-		.tile_formats = rga3_tile_format,
-		.num_of_tile_formats = ARRAY_SIZE(rga3_tile_format),
+		.formats[RGA_RASTER_INDEX] = rga3_output_raster_format,
+		.formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga3_output_raster_format),
+		.formats[RGA_AFBC16x16_INDEX] = rga3_fbcd_format,
+		.formats_count[RGA_AFBC16x16_INDEX] = ARRAY_SIZE(rga3_fbcd_format),
+		.formats[RGA_TILE8x8_INDEX] = rga3_tile_format,
+		.formats_count[RGA_TILE8x8_INDEX] = ARRAY_SIZE(rga3_tile_format),
 		.supported_rotations = 0,
 		.scale_up_mode = RGA_SCALE_UP_NONE,
 		.scale_down_mode = RGA_SCALE_DOWN_NONE,
@@ -222,8 +222,8 @@
 const struct rga_win_data rga2e_win_data[] = {
 	{
 		.name = "rga2e-src0",
-		.raster_formats = rga2e_input_raster_format,
-		.num_of_raster_formats = ARRAY_SIZE(rga2e_input_raster_format),
+		.formats[RGA_RASTER_INDEX] = rga2e_input_raster_format,
+		.formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2e_input_raster_format),
 		.supported_rotations = RGA_MODE_ROTATE_MASK,
 		.scale_up_mode = RGA_SCALE_UP_BIC,
 		.scale_down_mode = RGA_SCALE_DOWN_AVG,
@@ -233,8 +233,8 @@
 
 	{
 		.name = "rga2e-src1",
-		.raster_formats = rga2e_input_raster_format,
-		.num_of_raster_formats = ARRAY_SIZE(rga2e_input_raster_format),
+		.formats[RGA_RASTER_INDEX] = rga2e_input_raster_format,
+		.formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2e_input_raster_format),
 		.supported_rotations = RGA_MODE_ROTATE_MASK,
 		.scale_up_mode = RGA_SCALE_UP_BIC,
 		.scale_down_mode = RGA_SCALE_DOWN_AVG,
@@ -244,8 +244,8 @@
 
 	{
 		.name = "rga2-dst",
-		.raster_formats = rga2e_output_raster_format,
-		.num_of_raster_formats = ARRAY_SIZE(rga2e_output_raster_format),
+		.formats[RGA_RASTER_INDEX] = rga2e_output_raster_format,
+		.formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2e_output_raster_format),
 		.supported_rotations = 0,
 		.scale_up_mode = RGA_SCALE_UP_NONE,
 		.scale_down_mode = RGA_SCALE_DOWN_NONE,
diff --git a/kernel/drivers/video/rockchip/rga3/rga_job.c b/kernel/drivers/video/rockchip/rga3/rga_job.c
index 647fc2b..fae613b 100644
--- a/kernel/drivers/video/rockchip/rga3/rga_job.c
+++ b/kernel/drivers/video/rockchip/rga3/rga_job.c
@@ -13,6 +13,7 @@
 #include "rga_mm.h"
 #include "rga_iommu.h"
 #include "rga_debugger.h"
+#include "rga_common.h"
 
 static void rga_job_free(struct rga_job *job)
 {
@@ -40,11 +41,12 @@
 
 static int rga_job_cleanup(struct rga_job *job)
 {
-	if (DEBUGGER_EN(TIME))
-		pr_err("(pid:%d) job clean use time = %lld\n", job->pid,
-			ktime_us_delta(ktime_get(), job->timestamp));
-
 	rga_job_put(job);
+
+	if (DEBUGGER_EN(TIME))
+		pr_info("request[%d], job cleanup total cost time %lld us\n",
+			job->request_id,
+			ktime_us_delta(ktime_get(), job->timestamp));
 
 	return 0;
 }
@@ -272,11 +274,11 @@
 	if (DEBUGGER_EN(DUMP_IMAGE))
 		rga_dump_job_image(job);
 
-	if (DEBUGGER_EN(TIME)) {
-		pr_info("hw use time = %lld\n", ktime_us_delta(now, job->hw_running_time));
-		pr_info("(pid:%d) job done use time = %lld\n", job->pid,
-			ktime_us_delta(now, job->timestamp));
-	}
+	if (DEBUGGER_EN(TIME))
+		pr_info("request[%d], hardware[%s] cost time %lld us\n",
+			job->request_id,
+			rga_get_core_name(scheduler->core),
+			ktime_us_delta(now, job->hw_running_time));
 
 	rga_mm_unmap_job_info(job);
 
@@ -492,7 +494,7 @@
 	return false;
 }
 
-static int rga_request_get_current_mm(struct rga_request *request)
+static struct mm_struct *rga_request_get_current_mm(struct rga_request *request)
 {
 	int i;
 
@@ -500,23 +502,21 @@
 		if (rga_is_need_current_mm(&(request->task_list[i]))) {
 			mmgrab(current->mm);
 			mmget(current->mm);
-			request->current_mm = current->mm;
 
-			break;
+			return current->mm;
 		}
 	}
 
-	return 0;
+	return NULL;
 }
 
-static void rga_request_put_current_mm(struct rga_request *request)
+static void rga_request_put_current_mm(struct mm_struct *mm)
 {
-	if (request->current_mm == NULL)
+	if (mm == NULL)
 		return;
 
-	mmput(request->current_mm);
-	mmdrop(request->current_mm);
-	request->current_mm = NULL;
+	mmput(mm);
+	mmdrop(mm);
 }
 
 static int rga_request_add_acquire_fence_callback(int acquire_fence_fd,
@@ -693,6 +693,7 @@
 static void rga_request_release_abort(struct rga_request *request, int err_code)
 {
 	unsigned long flags;
+	struct mm_struct *current_mm;
 	struct rga_pending_request_manager *request_manager = rga_drvdata->pend_request_manager;
 
 	if (rga_request_scheduler_job_abort(request) > 0)
@@ -707,10 +708,12 @@
 
 	request->is_running = false;
 	request->is_done = false;
-
-	rga_request_put_current_mm(request);
+	current_mm = request->current_mm;
+	request->current_mm = NULL;
 
 	spin_unlock_irqrestore(&request->lock, flags);
+
+	rga_request_put_current_mm(current_mm);
 
 	rga_dma_fence_signal(request->release_fence, err_code);
 
@@ -820,7 +823,14 @@
 	struct rga_job *job;
 
 	for (i = 0; i < request->task_count; i++) {
-		job = rga_job_commit(&(request->task_list[i]), request);
+		struct rga_req *req = &(request->task_list[i]);
+
+		if (DEBUGGER_EN(MSG)) {
+			pr_info("commit request[%d] task[%d]:\n", request->id, i);
+			rga_cmd_print_debug_info(req);
+		}
+
+		job = rga_job_commit(req, request);
 		if (IS_ERR(job)) {
 			pr_err("request[%d] task[%d] job_commit failed.\n", request->id, i);
 			rga_request_release_abort(request, PTR_ERR(job));
@@ -841,12 +851,34 @@
 static void rga_request_acquire_fence_signaled_cb(struct dma_fence *fence,
 						  struct dma_fence_cb *_waiter)
 {
+	int ret;
+	unsigned long flags;
+	struct mm_struct *current_mm;
 	struct rga_fence_waiter *waiter = (struct rga_fence_waiter *)_waiter;
 	struct rga_request *request = (struct rga_request *)waiter->private;
 	struct rga_pending_request_manager *request_manager = rga_drvdata->pend_request_manager;
 
-	if (rga_request_commit(request))
-		pr_err("rga request[%d] commit failed!\n", request->id);
+	ret = rga_request_commit(request);
+	if (ret < 0) {
+		pr_err("acquire_fence callback: rga request[%d] commit failed!\n", request->id);
+
+		spin_lock_irqsave(&request->lock, flags);
+
+		request->is_running = false;
+		current_mm = request->current_mm;
+		request->current_mm = NULL;
+
+		spin_unlock_irqrestore(&request->lock, flags);
+
+		rga_request_put_current_mm(current_mm);
+
+		/*
+		 * Since the callback is called while holding &dma_fence.lock,
+		 * the _locked API is used here.
+		 */
+		if (dma_fence_get_status_locked(request->release_fence) == 0)
+			dma_fence_signal_locked(request->release_fence);
+	}
 
 	mutex_lock(&request_manager->lock);
 	rga_request_put(request);
@@ -859,6 +891,7 @@
 {
 	struct rga_pending_request_manager *request_manager;
 	struct rga_request *request;
+	struct mm_struct *current_mm;
 	int finished_count, failed_count;
 	bool is_finished = false;
 	unsigned long flags;
@@ -895,17 +928,17 @@
 
 	spin_unlock_irqrestore(&request->lock, flags);
 
-	rga_job_cleanup(job);
-
 	if ((failed_count + finished_count) >= request->task_count) {
 		spin_lock_irqsave(&request->lock, flags);
 
 		request->is_running = false;
 		request->is_done = true;
-
-		rga_request_put_current_mm(request);
+		current_mm = request->current_mm;
+		request->current_mm = NULL;
 
 		spin_unlock_irqrestore(&request->lock, flags);
+
+		rga_request_put_current_mm(current_mm);
 
 		rga_dma_fence_signal(request->release_fence, request->ret);
 
@@ -929,6 +962,13 @@
 	rga_request_put(request);
 
 	mutex_unlock(&request_manager->lock);
+
+	if (DEBUGGER_EN(TIME))
+		pr_info("request[%d], job done total cost time %lld us\n",
+			job->request_id,
+			ktime_us_delta(ktime_get(), job->timestamp));
+
+	rga_job_cleanup(job);
 
 	return 0;
 }
@@ -1059,6 +1099,9 @@
 	int ret = 0;
 	unsigned long flags;
 	struct dma_fence *release_fence;
+	struct mm_struct *current_mm;
+
+	current_mm = rga_request_get_current_mm(request);
 
 	spin_lock_irqsave(&request->lock, flags);
 
@@ -1066,14 +1109,16 @@
 		spin_unlock_irqrestore(&request->lock, flags);
 
 		pr_err("can not re-config when request is running\n");
-		return -EFAULT;
+		ret = -EFAULT;
+		goto err_put_current_mm;
 	}
 
 	if (request->task_list == NULL) {
 		spin_unlock_irqrestore(&request->lock, flags);
 
 		pr_err("can not find task list from id[%d]\n", request->id);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto err_put_current_mm;
 	}
 
 	/* Reset */
@@ -1081,8 +1126,7 @@
 	request->is_done = false;
 	request->finished_task_count = 0;
 	request->failed_task_count = 0;
-
-	rga_request_get_current_mm(request);
+	request->current_mm = current_mm;
 
 	/* Unlock after ensuring that the current request will not be resubmitted. */
 	spin_unlock_irqrestore(&request->lock, flags);
@@ -1092,7 +1136,7 @@
 		if (IS_ERR(release_fence)) {
 			pr_err("Can not alloc release fence!\n");
 			ret = IS_ERR(release_fence);
-			goto error_put_current_mm;
+			goto err_reset_request;
 		}
 		request->release_fence = release_fence;
 
@@ -1141,13 +1185,16 @@
 		request->release_fence = NULL;
 	}
 
-error_put_current_mm:
+err_reset_request:
 	spin_lock_irqsave(&request->lock, flags);
 
-	rga_request_put_current_mm(request);
+	request->current_mm = NULL;
 	request->is_running = false;
 
 	spin_unlock_irqrestore(&request->lock, flags);
+
+err_put_current_mm:
+	rga_request_put_current_mm(current_mm);
 
 	return ret;
 }
@@ -1237,6 +1284,7 @@
 static void rga_request_kref_release(struct kref *ref)
 {
 	struct rga_request *request;
+	struct mm_struct *current_mm;
 	unsigned long flags;
 
 	request = container_of(ref, struct rga_request, refcount);
@@ -1246,16 +1294,22 @@
 
 	spin_lock_irqsave(&request->lock, flags);
 
-	rga_request_put_current_mm(request);
 	rga_dma_fence_put(request->release_fence);
+	current_mm = request->current_mm;
+	request->current_mm = NULL;
 
 	if (!request->is_running || request->is_done) {
 		spin_unlock_irqrestore(&request->lock, flags);
+
+		rga_request_put_current_mm(current_mm);
+
 		goto free_request;
 	}
 
 	spin_unlock_irqrestore(&request->lock, flags);
 
+	rga_request_put_current_mm(current_mm);
+
 	rga_request_scheduler_job_abort(request);
 
 free_request:
diff --git a/kernel/drivers/video/rockchip/rga3/rga_mm.c b/kernel/drivers/video/rockchip/rga3/rga_mm.c
index d261833..de7e9a6 100644
--- a/kernel/drivers/video/rockchip/rga3/rga_mm.c
+++ b/kernel/drivers/video/rockchip/rga3/rga_mm.c
@@ -455,6 +455,7 @@
 		phys_addr = sg_phys(buffer->sgt->sgl);
 		if (phys_addr == 0) {
 			pr_err("%s get physical address error!", __func__);
+			ret = -EFAULT;
 			goto unmap_buffer;
 		}
 
@@ -571,6 +572,7 @@
 		phys_addr = sg_phys(sgt->sgl);
 		if (phys_addr == 0) {
 			pr_err("%s get physical address error!", __func__);
+			ret = -EFAULT;
 			goto free_sgt;
 		}
 
@@ -621,8 +623,9 @@
 		if (mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS)
 			break;
 
-		pr_err("Current %s[%d] cannot support virtual address!\n",
+		pr_err("Current %s[%d] cannot support physically discontinuous virtual address!\n",
 		       rga_get_mmu_type_str(scheduler->data->mmu), scheduler->data->mmu);
+		ret = -EOPNOTSUPP;
 		goto free_dma_buffer;
 	}
 
@@ -840,9 +843,15 @@
 	return 0;
 }
 
+static void rga_mm_buffer_destroy(struct rga_internal_buffer *buffer)
+{
+	rga_mm_kref_release_buffer(&buffer->refcount);
+}
+
 static struct rga_internal_buffer *
 rga_mm_lookup_external(struct rga_mm *mm_session,
-		       struct rga_external_buffer *external_buffer)
+		       struct rga_external_buffer *external_buffer,
+		       struct mm_struct *current_mm)
 {
 	int id;
 	struct dma_buf *dma_buf = NULL;
@@ -875,8 +884,12 @@
 				continue;
 
 			if (temp_buffer->virt_addr->addr == external_buffer->memory) {
-				output_buffer = temp_buffer;
-				break;
+				if (temp_buffer->current_mm == current_mm) {
+					output_buffer = temp_buffer;
+					break;
+				}
+
+				continue;
 			}
 		}
 
@@ -1309,7 +1322,8 @@
 		return -EFAULT;
 	}
 
-	if (buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS) {
+	if (buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS &&
+	    scheduler->data->mmu != RGA_IOMMU) {
 		dma_sync_single_for_device(scheduler->dev, buffer->phys_addr, buffer->size, dir);
 	} else {
 		sgt = rga_mm_lookup_sgt(buffer);
@@ -1339,7 +1353,8 @@
 		return -EFAULT;
 	}
 
-	if (buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS) {
+	if (buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS &&
+	    scheduler->data->mmu != RGA_IOMMU) {
 		dma_sync_single_for_cpu(scheduler->dev, buffer->phys_addr, buffer->size, dir);
 	} else {
 		sgt = rga_mm_lookup_sgt(buffer);
@@ -1481,6 +1496,11 @@
 	if (internal_buffer->mm_flag & RGA_MEM_FORCE_FLUSH_CACHE && dir != DMA_NONE)
 		if (rga_mm_sync_dma_sg_for_cpu(internal_buffer, job, dir))
 			pr_err("sync sgt for cpu error!\n");
+
+	if (DEBUGGER_EN(MM)) {
+		pr_info("handle[%d] put info:\n", (int)internal_buffer->handle);
+		rga_mm_dump_buffer(internal_buffer);
+	}
 
 	mutex_lock(&mm->lock);
 	kref_put(&internal_buffer->refcount, rga_mm_kref_release_buffer);
@@ -1981,6 +2001,7 @@
 int rga_mm_map_job_info(struct rga_job *job)
 {
 	int ret;
+	ktime_t timestamp = ktime_get();
 
 	if (job->flags & RGA_JOB_USE_HANDLE) {
 		ret = rga_mm_get_handle_info(job);
@@ -1988,12 +2009,20 @@
 			pr_err("failed to get buffer from handle\n");
 			return ret;
 		}
+
+		if (DEBUGGER_EN(TIME))
+			pr_info("request[%d], get buffer_handle info cost %lld us\n",
+				job->request_id, ktime_us_delta(ktime_get(), timestamp));
 	} else {
 		ret = rga_mm_map_buffer_info(job);
 		if (ret < 0) {
 			pr_err("failed to map buffer\n");
 			return ret;
 		}
+
+		if (DEBUGGER_EN(TIME))
+			pr_info("request[%d], map buffer cost %lld us\n",
+				job->request_id, ktime_us_delta(ktime_get(), timestamp));
 	}
 
 	return 0;
@@ -2001,14 +2030,35 @@
 
 void rga_mm_unmap_job_info(struct rga_job *job)
 {
-	if (job->flags & RGA_JOB_USE_HANDLE)
+	ktime_t timestamp = ktime_get();
+
+	if (job->flags & RGA_JOB_USE_HANDLE) {
 		rga_mm_put_handle_info(job);
-	else
+
+		if (DEBUGGER_EN(TIME))
+			pr_info("request[%d], put buffer_handle info cost %lld us\n",
+				job->request_id, ktime_us_delta(ktime_get(), timestamp));
+	} else {
 		rga_mm_unmap_buffer_info(job);
+
+		if (DEBUGGER_EN(TIME))
+			pr_info("request[%d], unmap buffer cost %lld us\n",
+				job->request_id, ktime_us_delta(ktime_get(), timestamp));
+	}
 }
 
-uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer,
-			      struct rga_session *session)
+/*
+ * rga_mm_import_buffer - Importing external buffer into the RGA driver
+ *
+ * @external_buffer: [in] Parameters of external buffer
+ * @session:         [in] Session of the current process
+ *
+ * returns:
+ * if return value > 0, the buffer import is successful and is the generated
+ * buffer-handle, negative error code on failure.
+ */
+int rga_mm_import_buffer(struct rga_external_buffer *external_buffer,
+			 struct rga_session *session)
 {
 	int ret = 0, new_id;
 	struct rga_mm *mm;
@@ -2017,17 +2067,23 @@
 	mm = rga_drvdata->mm;
 	if (mm == NULL) {
 		pr_err("rga mm is null!\n");
-		return 0;
+		return -EFAULT;
 	}
 
 	mutex_lock(&mm->lock);
 
 	/* first, Check whether to rga_mm */
-	internal_buffer = rga_mm_lookup_external(mm, external_buffer);
+	internal_buffer = rga_mm_lookup_external(mm, external_buffer, current->mm);
 	if (!IS_ERR_OR_NULL(internal_buffer)) {
 		kref_get(&internal_buffer->refcount);
 
 		mutex_unlock(&mm->lock);
+
+		if (DEBUGGER_EN(MM)) {
+			pr_info("import existing buffer:\n");
+			rga_mm_dump_buffer(internal_buffer);
+		}
+
 		return internal_buffer->handle;
 	}
 
@@ -2037,7 +2093,7 @@
 		pr_err("%s alloc internal_buffer error!\n", __func__);
 
 		mutex_unlock(&mm->lock);
-		return 0;
+		return -ENOMEM;
 	}
 
 	ret = rga_mm_map_buffer(external_buffer, internal_buffer, NULL, true);
@@ -2056,6 +2112,7 @@
 	idr_preload_end();
 	if (new_id < 0) {
 		pr_err("internal_buffer alloc id failed!\n");
+		ret = new_id;
 		goto FREE_INTERNAL_BUFFER;
 	}
 
@@ -2074,7 +2131,7 @@
 	mutex_unlock(&mm->lock);
 	kfree(internal_buffer);
 
-	return 0;
+	return ret;
 }
 
 int rga_mm_release_buffer(uint32_t handle)
@@ -2126,9 +2183,9 @@
 
 	idr_for_each_entry(&mm->memory_idr, buffer, i) {
 		if (session == buffer->session) {
-			pr_err("[tgid:%d] Decrement the reference of handle[%d] when the user exits\n",
+			pr_err("[tgid:%d] Destroy handle[%d] when the user exits\n",
 			       session->tgid, buffer->handle);
-			kref_put(&buffer->refcount, rga_mm_kref_release_buffer);
+			rga_mm_buffer_destroy(buffer);
 		}
 	}
 
diff --git a/kernel/drivers/video/rockchip/rga3/rga_policy.c b/kernel/drivers/video/rockchip/rga3/rga_policy.c
index 1afab89..c87ce18 100644
--- a/kernel/drivers/video/rockchip/rga3/rga_policy.c
+++ b/kernel/drivers/video/rockchip/rga3/rga_policy.c
@@ -15,7 +15,7 @@
 #define GET_GCD(n1, n2) \
 	({ \
 		int i; \
-		int gcd = 0; \
+		int gcd = 1; \
 		for (i = 1; i <= (n1) && i <= (n2); i++) { \
 			if ((n1) % i == 0 && (n2) % i == 0) \
 				gcd = i; \
@@ -108,32 +108,34 @@
 		int rd_mode, int format, int win_num)
 {
 	int i;
-	bool matched = false;
+	const uint32_t *formats;
+	uint32_t format_count;
 
-	if (rd_mode == RGA_RASTER_MODE) {
-		for (i = 0; i < data->win[win_num].num_of_raster_formats; i++) {
-			if (format == data->win[win_num].raster_formats[i]) {
-				matched = true;
-				break;
-			}
-		}
-	} else if (rd_mode == RGA_FBC_MODE) {
-		for (i = 0; i < data->win[win_num].num_of_fbc_formats; i++) {
-			if (format == data->win[win_num].fbc_formats[i]) {
-				matched = true;
-				break;
-			}
-		}
-	} else if (rd_mode == RGA_TILE_MODE) {
-		for (i = 0; i < data->win[win_num].num_of_tile_formats; i++) {
-			if (format == data->win[win_num].tile_formats[i]) {
-				matched = true;
-				break;
-			}
-		}
+	switch (rd_mode) {
+	case RGA_RASTER_MODE:
+		formats = data->win[win_num].formats[RGA_RASTER_INDEX];
+		format_count = data->win[win_num].formats_count[RGA_RASTER_INDEX];
+		break;
+	case RGA_FBC_MODE:
+		formats = data->win[win_num].formats[RGA_AFBC16x16_INDEX];
+		format_count = data->win[win_num].formats_count[RGA_AFBC16x16_INDEX];
+		break;
+	case RGA_TILE_MODE:
+		formats = data->win[win_num].formats[RGA_TILE8x8_INDEX];
+		format_count = data->win[win_num].formats_count[RGA_TILE8x8_INDEX];
+		break;
+	default:
+		return false;
 	}
 
-	return matched;
+	if (formats == NULL || format_count == 0)
+		return false;
+
+	for (i = 0; i < format_count; i++)
+		if (format == formats[i])
+			return true;
+
+	return false;
 }
 
 static bool rga_check_align(uint32_t byte_stride_align, uint32_t format, uint16_t w_stride)
diff --git a/kernel/drivers/video/rockchip/rve/include/rve_drv.h b/kernel/drivers/video/rockchip/rve/include/rve_drv.h
index 4fff93f..8d9f188 100644
--- a/kernel/drivers/video/rockchip/rve/include/rve_drv.h
+++ b/kernel/drivers/video/rockchip/rve/include/rve_drv.h
@@ -72,7 +72,7 @@
 
 #define DRIVER_MAJOR_VERSION		1
 #define DRIVER_MINOR_VERSION		0
-#define DRIVER_REVISION_VERSION		4
+#define DRIVER_REVISION_VERSION		5
 
 #define DRIVER_VERSION (STR(DRIVER_MAJOR_VERSION) "." STR(DRIVER_MINOR_VERSION) \
 			"." STR(DRIVER_REVISION_VERSION))
diff --git a/kernel/drivers/video/rockchip/rve/include/rve_reg.h b/kernel/drivers/video/rockchip/rve/include/rve_reg.h
index 5969aa9..05df280 100644
--- a/kernel/drivers/video/rockchip/rve/include/rve_reg.h
+++ b/kernel/drivers/video/rockchip/rve/include/rve_reg.h
@@ -73,7 +73,7 @@
 
 /* mode value */
 #define RVE_LLP_MODE                      0x8000
-#define RVE_LLP_DONE                      0x11
+#define RVE_LLP_DONE                      0x10
 #define RVE_CLEAR_UP_REG6_WROK_STA        0xff0000
 
 void rve_soft_reset(struct rve_scheduler_t *scheduler);
diff --git a/kernel/drivers/video/rockchip/vehicle/vehicle_cif.c b/kernel/drivers/video/rockchip/vehicle/vehicle_cif.c
index 8e83a60..96c2bfb 100644
--- a/kernel/drivers/video/rockchip/vehicle/vehicle_cif.c
+++ b/kernel/drivers/video/rockchip/vehicle/vehicle_cif.c
@@ -37,7 +37,6 @@
 #include <media/v4l2-mediabus.h>
 #include <linux/delay.h>
 #include <linux/pm_runtime.h>
-#include <dt-bindings/soc/rockchip-system-status.h>
 #include <soc/rockchip/rockchip-system-status.h>
 #include <linux/phy/phy.h>
 #include <linux/uaccess.h>
diff --git a/kernel/drivers/video/rockchip/vtunnel/Kconfig b/kernel/drivers/video/rockchip/vtunnel/Kconfig
new file mode 100644
index 0000000..49ad2a5
--- /dev/null
+++ b/kernel/drivers/video/rockchip/vtunnel/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+menu "Rockchip video tunnel support"
+
+config ROCKCHIP_VIDEO_TUNNEL
+	tristate "Rockchip video tunnel device support"
+	depends on ARCH_ROCKCHIP
+	default n
+	help
+	  Rockchip videotunnel device support.
+
+endmenu
diff --git a/kernel/drivers/video/rockchip/vtunnel/Makefile b/kernel/drivers/video/rockchip/vtunnel/Makefile
new file mode 100644
index 0000000..fdfd79a
--- /dev/null
+++ b/kernel/drivers/video/rockchip/vtunnel/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_ROCKCHIP_VIDEO_TUNNEL) += rkvtunnel.o
diff --git a/kernel/drivers/video/rockchip/vtunnel/rkvtunnel.c b/kernel/drivers/video/rockchip/vtunnel/rkvtunnel.c
new file mode 100644
index 0000000..2a879ab
--- /dev/null
+++ b/kernel/drivers/video/rockchip/vtunnel/rkvtunnel.c
@@ -0,0 +1,1527 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) Rockchip Electronics Co., Ltd.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/fdtable.h>
+#include <linux/file.h>
+#include <linux/freezer.h>
+#include <linux/miscdevice.h>
+#include <linux/of.h>
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
+#include <linux/dma-buf.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/kfifo.h>
+#include <linux/debugfs.h>
+#include <linux/random.h>
+#include <linux/sync_file.h>
+#include <linux/sched/task.h>
+#include <linux/sched/clock.h>
+
+#include <asm-generic/bug.h>
+
+#include "rkvtunnel.h"
+
+#define DEVICE_NAME				"rkvtunnel"
+#define RKVT_MAX_NAME_LENGTH			128
+#define RKVT_POOL_SIZE				32
+#define RKVT_MAX_WAIT_MS			4
+#define RKVT_FENCE_WAIT_MS			3000
+
+#define RKVT_DBG_USER				(1U << 0)
+#define RKVT_DBG_BUFFERS			(1U << 1)
+#define RKVT_DBG_CMD				(1U << 2)
+#define RKVT_DBG_FILE				(1U << 3)
+
+#define rkvt_dbg(mask, x...)\
+	do { if (unlikely(vt_dev_dbg & mask)) pr_info(x); } while (0)
+
+enum rkvt_buf_status_e {
+	RKVT_BUF_QUEUE,
+	RKVT_BUF_DEQUEUE,
+	RKVT_BUF_ACQUIRE,
+	RKVT_BUF_RELEASE,
+	RKVT_BUF_FREE,
+	RKVT_BUF_BUTT,
+};
+
+union rkvt_ioc_arg {
+	struct rkvt_alloc_id_data alloc_data;
+	struct rkvt_ctrl_data ctrl_data;
+	struct rkvt_buf_data buffer_data;
+};
+
+struct rkvt_dev {
+	struct device *dev;
+	struct miscdevice mdev;
+	struct mutex inst_lock; /* protect inst_list and ints_idr */
+	struct idr inst_idr;
+	struct list_head list_inst; /* manage all instances */
+
+	struct mutex session_lock; /* protect sessions */
+	struct list_head list_session;
+
+	char *dev_name;
+	int inst_id_generator;
+	atomic64_t cid_generator;
+	struct dentry *debug_root;
+};
+
+struct rkvt_session {
+	struct list_head dev_link;
+	struct rkvt_dev *vt_dev;
+	struct list_head list_inst; /* manage instance in session */
+
+	enum rkvt_caller_e caller;
+	pid_t pid;
+	char name[RKVT_MAX_NAME_LENGTH];
+	char disp_name[RKVT_MAX_NAME_LENGTH];
+	int disp_serial;
+	int cid;
+	struct task_struct *task;
+	struct dentry *debug_root;
+};
+
+struct rkvt_buffer {
+	struct file *file_buf[MAX_BUF_HANDLE_FDS];
+	int fds_pro[MAX_BUF_HANDLE_FDS];
+	int fds_con[MAX_BUF_HANDLE_FDS];
+
+	struct file *ready_render_fence;
+	struct dma_fence *rendered_fence;
+	struct rkvt_session *session_pro;
+	int cid_pro;
+	struct rkvt_buf_base base;
+};
+
+struct rkvt_instance {
+	struct kref ref;
+	int id;
+	struct rkvt_dev *vt_dev;
+
+	struct mutex lock;
+	struct list_head dev_link;
+	struct list_head session_link;
+	struct rkvt_session *consumer;
+	struct rkvt_session *producer;
+	wait_queue_head_t wait_consumer;
+	wait_queue_head_t wait_producer;
+
+	struct dentry *debug_root;
+	int fcount;
+
+	DECLARE_KFIFO_PTR(fifo_to_consumer, struct rkvt_buffer*);
+	DECLARE_KFIFO_PTR(fifo_to_producer, struct rkvt_buffer*);
+
+	struct rkvt_buffer vt_buffers[RKVT_POOL_SIZE];
+
+	atomic64_t buf_id_generator;
+};
+
+static unsigned int vt_dev_dbg;
+
+module_param(vt_dev_dbg, uint, 0644);
+MODULE_PARM_DESC(vt_dev_dbg, "bit switch for vt debug information");
+
+static const char *
+rkvt_dbg_buf_status_to_string(int status)
+{
+	const char *status_str;
+
+	switch (status) {
+	case RKVT_BUF_QUEUE:
+		status_str = "queued";
+		break;
+	case RKVT_BUF_DEQUEUE:
+		status_str = "dequeued";
+		break;
+	case RKVT_BUF_ACQUIRE:
+		status_str = "acquired";
+		break;
+	case RKVT_BUF_RELEASE:
+		status_str = "released";
+		break;
+	case RKVT_BUF_FREE:
+		status_str = "free";
+		break;
+	default:
+		status_str = "unknown";
+	}
+
+	return status_str;
+}
+
+static int rkvt_dbg_instance_show(struct seq_file *s, void *unused)
+{
+	struct rkvt_instance *inst = s->private;
+	int i;
+	int size_to_con;
+	int size_to_pro;
+	int ref_count;
+
+	mutex_lock(&inst->lock);
+	size_to_con = kfifo_len(&inst->fifo_to_consumer);
+	size_to_pro = kfifo_len(&inst->fifo_to_producer);
+	ref_count = kref_read(&inst->ref);
+
+	seq_printf(s, "tunnel (%p) id=%d, ref=%d, fcount=%d\n",
+		   inst, inst->id, ref_count, inst->fcount);
+	seq_puts(s, "-----------------------------------------------\n");
+	if (inst->consumer)
+		seq_printf(s, "consumer session (%s) %p\n",
+			   inst->consumer->disp_name, inst->consumer);
+	if (inst->producer)
+		seq_printf(s, "producer session (%s) %p\n",
+			   inst->producer->disp_name, inst->producer);
+	seq_puts(s, "-----------------------------------------------\n");
+
+	seq_printf(s, "to consumer fifo size:%d\n", size_to_con);
+	seq_printf(s, "to producer fifo size:%d\n", size_to_pro);
+	seq_puts(s, "-----------------------------------------------\n");
+
+	seq_puts(s, "buffers:\n");
+
+	for (i = 0; i < RKVT_POOL_SIZE; i++) {
+		struct rkvt_buffer *buffer = &inst->vt_buffers[i];
+		int status = buffer->base.buf_status;
+
+		seq_printf(s, "    buffer produce_fd[0](%d) status(%s)\n",
+			   buffer->fds_pro[0],
+			   rkvt_dbg_buf_status_to_string(status));
+	}
+	seq_puts(s, "-----------------------------------------------\n");
+	mutex_unlock(&inst->lock);
+
+	return 0;
+}
+
+static int
+rkvt_dbg_instance_open(struct inode *inode, struct file *file)
+{
+	return single_open(file,
+			   rkvt_dbg_instance_show,
+			   inode->i_private);
+}
+
+static const struct file_operations dbg_instance_fops = {
+	.open = rkvt_dbg_instance_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static int rkvt_dbg_session_show(struct seq_file *s, void *unused)
+{
+	struct rkvt_session *session = s->private;
+
+	seq_printf(s, "session(%s) %p role %s cid %d\n",
+		   session->disp_name, session,
+		   session->caller == RKVT_CALLER_PRODUCER ?
+		   "producer" : (session->caller == RKVT_CALLER_CONSUMER ?
+		   "consumer" : "invalid"), session->cid);
+	seq_puts(s, "-----------------------------------------------\n");
+
+	return 0;
+}
+
+static int rkvt_dbg_session_open(struct inode *inode, struct file *file)
+{
+	return single_open(file,
+			   rkvt_dbg_session_show,
+			   inode->i_private);
+}
+
+static const struct file_operations debug_session_fops = {
+	.open = rkvt_dbg_session_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static int __rkvt_close_fd(struct files_struct *files, unsigned int fd)
+{
+	struct file *file;
+	struct fdtable *fdt;
+
+	spin_lock(&files->file_lock);
+
+	fdt = files_fdtable(files);
+	if (fd >= fdt->max_fds)
+		goto out_unlock;
+	file = fdt->fd[fd];
+	if (!file)
+		goto out_unlock;
+
+	rcu_assign_pointer(fdt->fd[fd], NULL);
+	spin_unlock(&files->file_lock);
+
+	put_unused_fd(fd);
+	return filp_close(file, files);
+
+out_unlock:
+	spin_unlock(&files->file_lock);
+	return -EBADF;
+}
+
+static int rkvt_close_fd(struct rkvt_session *session, unsigned int fd)
+{
+	int ret;
+
+	if (!session->task)
+		return -ESRCH;
+
+	ret = __rkvt_close_fd(session->task->files, fd);
+	if (unlikely(ret == -ERESTARTSYS ||
+		     ret == -ERESTARTNOINTR ||
+		     ret == -ERESTARTNOHAND ||
+		     ret == -ERESTART_RESTARTBLOCK))
+		ret = -EINTR;
+
+	return ret;
+}
+
+/* The function is responsible for fifo_to_consumer fifo operation
+ * requires external use of rkvt_instance.lock protection
+ */
+static void rkvt_inst_clear_consumer(struct rkvt_instance *inst)
+{
+	struct rkvt_buffer *buffer = NULL;
+	int i = 0;
+
+	if (!inst)
+		return;
+
+	while (kfifo_get(&inst->fifo_to_consumer, &buffer)) {
+		/* put file */
+		for (i = 0; i < buffer->base.num_fds; i++) {
+			if (buffer->file_buf[i]) {
+				fput(buffer->file_buf[i]);
+				buffer->file_buf[i] = NULL;
+			}
+			inst->fcount--;
+		}
+		if (buffer->ready_render_fence) {
+			fput(buffer->ready_render_fence);
+			buffer->ready_render_fence = NULL;
+		}
+		rkvt_dbg(RKVT_DBG_FILE,
+			 "vt [%d] instance trim file(%p) buffer(%p) ino(%08lu) fcount=%d\n",
+			 inst->id, buffer->file_buf, buffer,
+			 buffer->file_buf[i] ?
+			 file_inode(buffer->file_buf[i])->i_ino : 0,
+			 inst->fcount);
+		if (inst->producer != NULL) {
+			buffer->base.buf_status = RKVT_BUF_RELEASE;
+			kfifo_put(&inst->fifo_to_producer, buffer);
+			wake_up_interruptible(&inst->wait_producer);
+		} else {
+			buffer->base.buf_status = RKVT_BUF_FREE;
+		}
+	}
+}
+
+/* The function is responsible for fifo_to_consumer fifo operation
+ * requires external use of rkvt_instance.lock protection.
+ */
+static void rkvt_inst_clear_producer(struct rkvt_instance *inst)
+{
+	struct rkvt_buffer *buffer = NULL;
+
+	if (!inst)
+		return;
+
+	while (kfifo_get(&inst->fifo_to_producer, &buffer)) {
+		if (buffer->rendered_fence) {
+			dma_fence_put(buffer->rendered_fence);
+			buffer->rendered_fence = NULL;
+		}
+		buffer->base.buf_status = RKVT_BUF_FREE;
+	}
+}
+
+static void rkvt_inst_destroy(struct kref *kref)
+{
+	struct rkvt_instance *inst =
+		container_of(kref, struct rkvt_instance, ref);
+	struct rkvt_dev *vt_dev = inst->vt_dev;
+
+	list_del_init(&inst->dev_link);
+	idr_remove(&vt_dev->inst_idr, inst->id);
+
+	rkvt_dbg(RKVT_DBG_USER, "vt [%d] destroy\n", inst->id);
+
+	mutex_lock(&inst->lock);
+	rkvt_inst_clear_consumer(inst);
+	rkvt_inst_clear_producer(inst);
+	kfifo_free(&inst->fifo_to_consumer);
+	kfifo_free(&inst->fifo_to_producer);
+	mutex_unlock(&inst->lock);
+
+	debugfs_remove_recursive(inst->debug_root);
+
+	devm_kfree(vt_dev->dev, inst);
+}
+
+static struct rkvt_instance *rkvt_inst_create(struct rkvt_dev *vt_dev)
+{
+	struct rkvt_instance *inst;
+	int status;
+	int i;
+
+	inst = devm_kzalloc(vt_dev->dev, sizeof(*inst), GFP_KERNEL);
+	if (!inst)
+		return ERR_PTR(-ENOMEM);
+
+	inst->vt_dev = vt_dev;
+	mutex_init(&inst->lock);
+	INIT_LIST_HEAD(&inst->dev_link);
+	INIT_LIST_HEAD(&inst->session_link);
+	kref_init(&inst->ref);
+
+	status = kfifo_alloc(&inst->fifo_to_consumer,
+			     RKVT_POOL_SIZE, GFP_KERNEL);
+	if (status)
+		goto setup_fail;
+
+	status = kfifo_alloc(&inst->fifo_to_producer,
+			     RKVT_POOL_SIZE, GFP_KERNEL);
+	if (status)
+		goto fifo_alloc_fail;
+
+	init_waitqueue_head(&inst->wait_producer);
+	init_waitqueue_head(&inst->wait_consumer);
+
+	for (i = 0; i < RKVT_POOL_SIZE; i++)
+		inst->vt_buffers[i].base.buf_status = RKVT_BUF_FREE;
+
+	/* insert it to dev instances list */
+	mutex_lock(&vt_dev->inst_lock);
+	list_add_tail(&inst->dev_link, &vt_dev->list_inst);
+	mutex_unlock(&vt_dev->inst_lock);
+
+	return inst;
+fifo_alloc_fail:
+	kfifo_free(&inst->fifo_to_consumer);
+setup_fail:
+	devm_kfree(vt_dev->dev, inst);
+	return ERR_PTR(status);
+}
+
+/* The function protected by rkvt_dev.session_lock by caller */
+static int
+rkvt_get_session_serial(const struct list_head *sessions,
+			const unsigned char *name)
+{
+	int serial = -1;
+	struct rkvt_session *session, *n;
+
+	list_for_each_entry_safe(session, n, sessions, dev_link) {
+		if (strcmp(session->name, name))
+			continue;
+		serial = max(serial, session->disp_serial);
+	}
+
+	return serial + 1;
+}
+
+/* The function protected by rkvt_instance.lock by caller */
+static void
+rkvt_session_trim_locked(struct rkvt_session *session, struct rkvt_instance *inst)
+{
+	if (!session || !inst)
+		return;
+
+	if (inst->producer && inst->producer == session) {
+		rkvt_inst_clear_producer(inst);
+		inst->producer = NULL;
+	}
+
+	if (inst->consumer && inst->consumer == session) {
+		rkvt_inst_clear_consumer(inst);
+		inst->consumer = NULL;
+	}
+}
+
+static int rkvt_inst_trim(struct rkvt_session *session)
+{
+	struct rkvt_dev *vt_dev = session->vt_dev;
+	struct rkvt_instance *inst, *n;
+	int i;
+
+	mutex_lock(&vt_dev->inst_lock);
+	list_for_each_entry_safe(inst, n, &vt_dev->list_inst, dev_link) {
+		mutex_lock(&inst->lock);
+		rkvt_session_trim_locked(session, inst);
+
+		if (!inst->consumer && !inst->producer) {
+			rkvt_inst_clear_producer(inst);
+			rkvt_inst_clear_consumer(inst);
+
+			for (i = 0; i < RKVT_POOL_SIZE; i++)
+				inst->vt_buffers[i].base.buf_status = RKVT_BUF_FREE;
+		}
+		mutex_unlock(&inst->lock);
+	}
+	mutex_unlock(&vt_dev->inst_lock);
+
+	return 0;
+}
+
+static struct rkvt_session *
+rkvt_session_create(struct rkvt_dev *vt_dev, const char *name)
+{
+	struct rkvt_session *session;
+	struct task_struct *task = NULL;
+
+	if (!name) {
+		dev_err(vt_dev->dev, "%s: Name can not be null\n", __func__);
+		return ERR_PTR(-EINVAL);
+	}
+
+	session = devm_kzalloc(vt_dev->dev, sizeof(*session), GFP_KERNEL);
+	if (!session)
+		return ERR_PTR(-ENOMEM);
+
+	get_task_struct(current->group_leader);
+	task_lock(current->group_leader);
+	session->pid = task_pid_nr(current->group_leader);
+
+	if (current->group_leader->flags & PF_KTHREAD) {
+		put_task_struct(current->group_leader);
+		task = NULL;
+	} else {
+		task = current->group_leader;
+	}
+
+	task_unlock(current->group_leader);
+
+	session->vt_dev = vt_dev;
+	session->task = task;
+	session->caller = RKVT_CALLER_BUTT;
+	INIT_LIST_HEAD(&session->dev_link);
+	INIT_LIST_HEAD(&session->list_inst);
+	snprintf(session->name, RKVT_MAX_NAME_LENGTH, "%s", name);
+
+	mutex_lock(&vt_dev->session_lock);
+	session->disp_serial = rkvt_get_session_serial(&vt_dev->list_session, name);
+	snprintf(session->disp_name, RKVT_MAX_NAME_LENGTH, "%s-%d",
+			 name, session->disp_serial);
+
+	list_add_tail(&session->dev_link, &vt_dev->list_session);
+
+	/* add debug fs */
+	session->debug_root = debugfs_create_file(session->disp_name,
+						  0664,
+						  vt_dev->debug_root,
+						  session,
+						  &debug_session_fops);
+
+	mutex_unlock(&vt_dev->session_lock);
+
+	rkvt_dbg(RKVT_DBG_USER, "vt session %s create\n", session->disp_name);
+
+	return session;
+}
+
+static void rkvt_session_destroy(struct rkvt_session *session)
+{
+	struct rkvt_dev *vt_dev = session->vt_dev;
+	struct rkvt_instance *inst = NULL;
+
+	rkvt_dbg(RKVT_DBG_USER, "vt session %s destroy\n", session->disp_name);
+
+	mutex_lock(&vt_dev->inst_lock);
+	while ((inst = list_first_entry_or_null(&session->list_inst,
+						struct rkvt_instance, session_link))) {
+		list_del_init(&inst->session_link);
+		kref_put(&inst->ref, rkvt_inst_destroy);
+	}
+	mutex_unlock(&vt_dev->inst_lock);
+
+	mutex_lock(&vt_dev->session_lock);
+	if (session->task)
+		put_task_struct(session->task);
+	list_del_init(&session->dev_link);
+	debugfs_remove_recursive(session->debug_root);
+	mutex_unlock(&vt_dev->session_lock);
+
+	rkvt_inst_trim(session);
+	devm_kfree(vt_dev->dev, session);
+}
+
+static int rkvt_open(struct inode *inode, struct file *filep)
+{
+	struct miscdevice *miscdev = filep->private_data;
+	struct rkvt_dev *vt_dev = container_of(miscdev, struct rkvt_dev, mdev);
+	struct rkvt_session *session;
+	char debug_name[64];
+
+	snprintf(debug_name, sizeof(debug_name), "%u", task_pid_nr(current->group_leader));
+	session = rkvt_session_create(vt_dev, debug_name);
+	if (IS_ERR(session))
+		return PTR_ERR(session);
+
+	filep->private_data = session;
+
+	return 0;
+}
+
+static int rkvt_release(struct inode *inode, struct file *filep)
+{
+	struct rkvt_session *session = filep->private_data;
+
+	rkvt_session_destroy(session);
+	filep->private_data = NULL;
+
+	return 0;
+}
+
+static int rkvt_get_connected_id(struct rkvt_dev *vt_dev)
+{
+	return atomic64_inc_return(&vt_dev->cid_generator);
+}
+
+static struct rkvt_instance *
+rkvt_inst_get_by_tid(struct rkvt_dev *vt_dev, int id)
+{
+	struct rkvt_instance *inst;
+
+	mutex_lock(&vt_dev->inst_lock);
+	inst = idr_find(&vt_dev->inst_idr, id);
+	if (!inst) {
+		mutex_unlock(&vt_dev->inst_lock);
+		dev_err(vt_dev->dev, "find rkvt [%d] by device idr err, instance is null\n", id);
+		return NULL;
+	}
+	kref_get(&inst->ref);
+	mutex_unlock(&vt_dev->inst_lock);
+
+	return inst;
+}
+
+static void rkvt_inst_put(struct rkvt_instance *inst)
+{
+	struct rkvt_dev *vt_dev;
+
+	if (!inst)
+		return;
+
+	vt_dev = inst->vt_dev;
+
+	mutex_lock(&vt_dev->inst_lock);
+	kref_put(&inst->ref, rkvt_inst_destroy);
+	mutex_unlock(&vt_dev->inst_lock);
+}
+
+static int
+rkvt_connect_proc(struct rkvt_ctrl_data *data, struct rkvt_session *session)
+{
+	struct rkvt_dev *vt_dev = session->vt_dev;
+	struct rkvt_instance *inst;
+	int ret = 0;
+
+	// ref get not put in function end, because connect need hold 1 refs.
+	inst = rkvt_inst_get_by_tid(vt_dev, data->vt_id);
+	if (!inst)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (data->caller == RKVT_CALLER_PRODUCER) {
+		if (inst->producer && inst->producer != session) {
+			dev_err(vt_dev->dev, "Connect to rkvt [%d] err, already has producer\n",
+					data->vt_id);
+			ret = -EINVAL;
+			goto connect_fail;
+		}
+		inst->producer = session;
+	} else if (data->caller == RKVT_CALLER_CONSUMER) {
+		if (inst->consumer && inst->consumer != session) {
+			dev_err(vt_dev->dev, "Connect to rkvt [%d] err, already has consumer\n",
+					data->vt_id);
+			ret = -EINVAL;
+			goto connect_fail;
+		}
+		inst->consumer = session;
+	}
+	mutex_unlock(&inst->lock);
+	session->cid = rkvt_get_connected_id(vt_dev);
+	session->caller = data->caller;
+
+	rkvt_dbg(RKVT_DBG_USER, "rkvt [%d] %s-%d connect, instance ref %d\n",
+		 inst->id,
+		 data->caller == RKVT_CALLER_PRODUCER ? "producer" : "consumer",
+		 session->pid,
+		 kref_read(&inst->ref));
+
+	return 0;
+
+connect_fail:
+	mutex_unlock(&inst->lock);
+	// ref put for rkvt_instance_get_by_tid
+	rkvt_inst_put(inst);
+
+	return ret;
+}
+
+static int
+rkvt_disconnect_proc(struct rkvt_ctrl_data *data, struct rkvt_session *session)
+{
+	struct rkvt_dev *vt_dev = session->vt_dev;
+	struct rkvt_instance *inst;
+
+	inst = rkvt_inst_get_by_tid(vt_dev, data->vt_id);
+	if (!inst)
+		return -EINVAL;
+	if (session->caller != data->caller)
+		goto session_invail;
+
+	mutex_lock(&inst->lock);
+	if (data->caller == RKVT_CALLER_PRODUCER) {
+		if (!inst->producer)
+			goto disconnect_fail;
+		if (inst->producer != session)
+			goto disconnect_fail;
+
+		rkvt_session_trim_locked(session, inst);
+		inst->producer = NULL;
+		wake_up_interruptible(&inst->wait_producer);
+	} else if (data->caller == RKVT_CALLER_CONSUMER) {
+		if (!inst->consumer)
+			goto disconnect_fail;
+		if (inst->consumer != session)
+			goto disconnect_fail;
+
+		rkvt_session_trim_locked(session, inst);
+		inst->consumer = NULL;
+		wake_up_interruptible(&inst->wait_consumer);
+	}
+	mutex_unlock(&inst->lock);
+
+	rkvt_dbg(RKVT_DBG_USER, "rkvt [%d] %s-%d disconnect, instance ref %d\n",
+		 inst->id,
+		 data->caller == RKVT_CALLER_PRODUCER ? "producer" : "consumer",
+		 session->pid,
+		 kref_read(&inst->ref));
+	// ref put for rkvt_instance_get_by_tid
+	rkvt_inst_put(inst);
+	// ref put for connect proc
+	rkvt_inst_put(inst);
+	session->cid = -1;
+
+	return 0;
+
+disconnect_fail:
+	mutex_unlock(&inst->lock);
+session_invail:
+	// ref put for rkvt_instance_get_by_tid
+	rkvt_inst_put(inst);
+
+	return -EINVAL;
+}
+
+static int
+rkvt_reset_proc(struct rkvt_ctrl_data *data, struct rkvt_session *session)
+{
+	struct rkvt_dev *vt_dev = session->vt_dev;
+	struct rkvt_instance *inst;
+	long long read_buf_id;
+
+	inst = rkvt_inst_get_by_tid(vt_dev, data->vt_id);
+	if (!inst)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	rkvt_inst_clear_consumer(inst);
+	rkvt_inst_clear_producer(inst);
+	read_buf_id = atomic64_read(&inst->buf_id_generator);
+	read_buf_id += 0x100;
+	read_buf_id &= ~0xff;
+	atomic64_set(&inst->buf_id_generator, read_buf_id);
+	mutex_unlock(&inst->lock);
+
+	rkvt_inst_put(inst);
+
+	return 0;
+}
+
+static int
+rkvt_has_consumer_proc(struct rkvt_ctrl_data *data, struct rkvt_session *session)
+{
+	struct rkvt_dev *vt_dev = session->vt_dev;
+	struct rkvt_instance *inst;
+
+	inst = rkvt_inst_get_by_tid(vt_dev, data->vt_id);
+	if (!inst)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	data->ctrl_data = inst->consumer != NULL ? 1 : 0;
+	mutex_unlock(&inst->lock);
+
+	rkvt_inst_put(inst);
+
+	return 0;
+}
+
+static int
+rkvt_ctrl_proc(struct rkvt_ctrl_data *data, struct rkvt_session *session)
+{
+	int id = data->vt_id;
+	int ret = 0;
+
+	if (id < 0)
+		return -EINVAL;
+	if (data->caller == RKVT_CALLER_BUTT)
+		return -EINVAL;
+
+	switch (data->ctrl_cmd) {
+	case RKVT_CTRL_CONNECT: {
+		ret = rkvt_connect_proc(data, session);
+		break;
+	}
+	case RKVT_CTRL_DISCONNECT: {
+		ret = rkvt_disconnect_proc(data, session);
+		break;
+	}
+	case RKVT_CTRL_RESET: {
+		ret = rkvt_reset_proc(data, session);
+		break;
+	}
+	case RKVT_CTRL_HAS_CONSUMER: {
+		ret = rkvt_has_consumer_proc(data, session);
+		break;
+	}
+	default:
+		pr_err("unknown rkvt cmd:%d\n", data->ctrl_cmd);
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static struct
+rkvt_buffer *rkvt_buf_get(struct rkvt_instance *inst, int key)
+{
+	struct rkvt_buffer *buffer = NULL;
+	int i;
+
+	mutex_lock(&inst->lock);
+	for (i = 0; i < RKVT_POOL_SIZE; i++) {
+		buffer = &inst->vt_buffers[i];
+
+		if (buffer->base.buf_status == RKVT_BUF_ACQUIRE &&
+		    buffer->fds_con[0] == key)
+			break;
+	}
+	mutex_unlock(&inst->lock);
+
+	return buffer;
+}
+
+static int
+rkvt_has_buf(struct rkvt_instance *inst, enum rkvt_caller_e caller)
+{
+	int ret = 0;
+
+	if (caller == RKVT_CALLER_PRODUCER)
+		ret = !kfifo_is_empty(&inst->fifo_to_producer);
+	else
+		ret = !kfifo_is_empty(&inst->fifo_to_consumer);
+
+	return ret;
+}
+
+static int
+rkvt_query_buf_and_wait(struct rkvt_instance *inst,
+			enum rkvt_caller_e caller,
+			int timeout_ms)
+{
+	int ret;
+	wait_queue_head_t *wait_queue;
+
+	if (caller == RKVT_CALLER_PRODUCER)
+		wait_queue = &inst->wait_producer;
+	else
+		wait_queue = &inst->wait_consumer;
+	if (caller == RKVT_CALLER_PRODUCER &&
+	    !kfifo_is_empty(&inst->fifo_to_producer))
+		return 0;
+	if (caller == RKVT_CALLER_CONSUMER &&
+	    !kfifo_is_empty(&inst->fifo_to_consumer))
+		return 0;
+
+	if (timeout_ms < 0)
+		wait_event_interruptible(*wait_queue,
+					 rkvt_has_buf(inst, caller));
+	else if (timeout_ms > 0) {
+		ret = wait_event_interruptible_timeout(*wait_queue,
+							rkvt_has_buf(inst, caller),
+							msecs_to_jiffies(timeout_ms));
+		/* timeout */
+		if (ret == 0)
+			return -EAGAIN;
+	} else
+		return -EAGAIN;
+
+	if (caller == RKVT_CALLER_PRODUCER &&
+	    kfifo_is_empty(&inst->fifo_to_producer))
+		return -EAGAIN;
+	if (caller == RKVT_CALLER_CONSUMER &&
+	    kfifo_is_empty(&inst->fifo_to_consumer))
+		return -EAGAIN;
+
+	return 0;
+}
+
+static struct rkvt_buffer *rkvt_get_free_buf(struct rkvt_instance *inst)
+{
+	struct rkvt_buffer *buffer = NULL;
+	int i, status;
+
+	mutex_lock(&inst->lock);
+	for (i = 0; i < RKVT_POOL_SIZE; i++) {
+		status = inst->vt_buffers[i].base.buf_status;
+		if (status == RKVT_BUF_FREE || status == RKVT_BUF_DEQUEUE) {
+			buffer = &inst->vt_buffers[i];
+			memset(buffer->file_buf, 0, sizeof(buffer->file_buf));
+			buffer->rendered_fence = NULL;
+			break;
+		}
+	}
+	mutex_unlock(&inst->lock);
+
+	return buffer;
+}
+
+static int
+rkvt_queue_buf(struct rkvt_buf_data *data, struct rkvt_session *session)
+{
+	struct rkvt_dev *vt_dev = session->vt_dev;
+	struct rkvt_instance *inst = NULL;
+	struct rkvt_buf_base *base = NULL;
+	struct rkvt_buffer *buffer = NULL;
+	int i;
+	int ret = 0;
+
+	inst = rkvt_inst_get_by_tid(vt_dev, data->vt_id);
+	if (!inst)
+		return -EINVAL;
+	if (!inst->producer || inst->producer != session) {
+		ret = -EINVAL;
+		goto queue_fail;
+	}
+	if ((data->base.num_fds > MAX_BUF_HANDLE_FDS) ||
+		(data->base.num_ints > MAX_BUF_HANDLE_INTS)) {
+		ret = -EINVAL;
+		goto queue_fail;
+	}
+
+	rkvt_dbg(RKVT_DBG_BUFFERS, "VTQB [%d] start\n", inst->id);
+
+	base = &data->base;
+	buffer = rkvt_get_free_buf(inst);
+	for (i = 0; i < base->num_fds; i++) {
+		buffer->fds_con[i] = -1;
+		buffer->fds_pro[i] = base->fds[i];
+		buffer->file_buf[i] = fget(base->fds[i]);
+
+		if (!buffer->file_buf[i]) {
+			ret = -EBADF;
+			goto buf_fget_fail;
+		}
+
+		inst->fcount++;
+		rkvt_dbg(RKVT_DBG_FILE,
+			"VTQB [%d] fget file(%p) buf(%p) buf session(%p) ino(%08lu) fcount=%d\n",
+			inst->id, buffer->file_buf[i], buffer, buffer->session_pro,
+			buffer->file_buf[i] ? file_inode(buffer->file_buf[i])->i_ino : 0,
+			inst->fcount);
+	}
+
+	if (base->fence_fd >= 0)
+		buffer->ready_render_fence = fget(base->fence_fd);
+
+	// buffer id is empty, generate a new id
+	if (base->buffer_id == 0)
+		base->buffer_id = atomic64_inc_return(&inst->buf_id_generator);
+	buffer->base = *base;
+	buffer->base.buf_status = RKVT_BUF_QUEUE;
+	buffer->session_pro = session;
+	buffer->cid_pro = session->cid;
+
+	mutex_lock(&inst->lock);
+	if (inst->consumer) {
+		kfifo_put(&inst->fifo_to_consumer, buffer);
+	} else {
+		for (i = 0; i < buffer->base.num_fds; i++) {
+			if (buffer->file_buf[i]) {
+				fput(buffer->file_buf[i]);
+				buffer->file_buf[i] = NULL;
+			}
+			inst->fcount--;
+		}
+		if (buffer->ready_render_fence) {
+			fput(buffer->ready_render_fence);
+			buffer->ready_render_fence = NULL;
+		}
+		buffer->base.buf_status = RKVT_BUF_RELEASE;
+		kfifo_put(&inst->fifo_to_producer, buffer);
+	}
+	mutex_unlock(&inst->lock);
+
+	if (inst->consumer)
+		wake_up_interruptible(&inst->wait_consumer);
+	else if (inst->producer)
+		wake_up_interruptible(&inst->wait_producer);
+
+	rkvt_dbg(RKVT_DBG_BUFFERS, "VTQB [%d] pfd[0]:%d end\n", inst->id, buffer->fds_pro[0]);
+
+queue_fail:
+	rkvt_inst_put(inst);
+
+	return ret;
+buf_fget_fail:
+	for (i = 0; i < base->num_fds; i++) {
+		if (buffer->file_buf[i]) {
+			fput(buffer->file_buf[i]);
+			buffer->file_buf[i] = NULL;
+			inst->fcount--;
+		}
+	}
+	rkvt_inst_put(inst);
+
+	return ret;
+}
+
+static int
+rkvt_deque_buf(struct rkvt_buf_data *data, struct rkvt_session *session)
+{
+	struct rkvt_dev *vt_dev = session->vt_dev;
+	struct rkvt_instance *inst = NULL;
+	struct rkvt_buffer *buffer = NULL;
+	int ret = 0;
+	unsigned long long cur_time, wait_time;
+	int i;
+
+	inst = rkvt_inst_get_by_tid(vt_dev, data->vt_id);
+	if (!inst)
+		return -EINVAL;
+	if (!inst->producer || inst->producer != session) {
+		ret = -EINVAL;
+		goto deque_fail;
+	}
+
+	/* empty need wait */
+	ret = rkvt_query_buf_and_wait(inst,
+				      RKVT_CALLER_PRODUCER,
+				      data->timeout_ms);
+	if (ret)
+		goto deque_fail;
+
+	mutex_lock(&inst->lock);
+	ret = kfifo_get(&inst->fifo_to_producer, &buffer);
+	if (!ret || !buffer) {
+		dev_err(vt_dev->dev, "VTDB [%d] got null buffer ret(%d)\n", inst->id, ret);
+		mutex_unlock(&inst->lock);
+		ret = -EAGAIN;
+		goto deque_fail;
+	}
+	mutex_unlock(&inst->lock);
+
+	/* it's previous connect buffer */
+	if (buffer->cid_pro != session->cid) {
+		if (buffer->rendered_fence) {
+			dma_fence_put(buffer->rendered_fence);
+			buffer->rendered_fence = NULL;
+		}
+
+		ret = -EAGAIN;
+		goto deque_fail;
+	}
+
+	if (buffer->rendered_fence) {
+		cur_time = sched_clock();
+		ret = dma_fence_wait_timeout(buffer->rendered_fence, false,
+					     msecs_to_jiffies(RKVT_FENCE_WAIT_MS));
+		wait_time = sched_clock() - cur_time;
+		rkvt_dbg(RKVT_DBG_BUFFERS,
+			 "VTDB [%d] pfd[0]:%d rendered fence:%p fence_wait time %llu\n",
+			 inst->id, buffer->fds_pro[0], buffer->rendered_fence, wait_time);
+
+		if (ret < 0)
+			dev_err(vt_dev->dev, "VTDB [%d] wait fence timeout\n", inst->id);
+
+		dma_fence_put(buffer->rendered_fence);
+		buffer->rendered_fence = NULL;
+	}
+	for (i = 0; i < buffer->base.num_fds; i++)
+		rkvt_dbg(RKVT_DBG_FILE,
+			"VTDB [%d] fget file(%p) buf(%p) buf session(%p) ino(%08lu) fcount=%d\n",
+			inst->id, buffer->file_buf[i],
+			buffer, buffer->session_pro,
+			buffer->file_buf[i] ? file_inode(buffer->file_buf[i])->i_ino : 0,
+			inst->fcount);
+
+	buffer->base.vt_id = inst->id;
+	/* return the buffer */
+	data->base = buffer->base;
+	buffer->base.buf_status = RKVT_BUF_DEQUEUE;
+
+	rkvt_dbg(RKVT_DBG_BUFFERS, "VTDB [%d] end pfd[0]:%d\n", inst->id, buffer->fds_pro[0]);
+
+deque_fail:
+	rkvt_inst_put(inst);
+
+	return ret;
+}
+
+static int
+rkvt_acquire_buf(struct rkvt_buf_data *data, struct rkvt_session *session)
+{
+	struct rkvt_dev *vt_dev = session->vt_dev;
+	struct rkvt_instance *inst = NULL;
+	struct rkvt_buffer *buffer = NULL;
+	int fd, ret = -1;
+	int i;
+
+	inst = rkvt_inst_get_by_tid(vt_dev, data->vt_id);
+	if (!inst)
+		return -EINVAL;
+	if (!inst->consumer || inst->consumer != session) {
+		ret = -EINVAL;
+		goto acquire_fail;
+	}
+	if ((data->base.num_fds > MAX_BUF_HANDLE_FDS) ||
+		(data->base.num_ints > MAX_BUF_HANDLE_INTS)) {
+		ret = -EINVAL;
+		goto acquire_fail;
+	}
+
+	/* empty need wait */
+	ret = rkvt_query_buf_and_wait(inst,
+				      RKVT_CALLER_CONSUMER,
+				      data->timeout_ms);
+	if (ret)
+		goto acquire_fail;
+
+	mutex_lock(&inst->lock);
+	ret = kfifo_get(&inst->fifo_to_consumer, &buffer);
+	mutex_unlock(&inst->lock);
+	if (!ret || !buffer) {
+		dev_err(vt_dev->dev, "VTAB [%d] got null buffer\n", inst->id);
+		ret = -EAGAIN;
+		goto acquire_fail;
+	}
+
+	/* get the fd in consumer */
+	for (i = 0; i < buffer->base.num_fds; i++) {
+		if (buffer->fds_con[i] <= 0) {
+			fd = get_unused_fd_flags(O_CLOEXEC);
+			if (fd < 0)
+				goto no_memory;
+
+			fd_install(fd, buffer->file_buf[i]);
+			buffer->fds_con[i] = fd;
+			buffer->base.fds[i] = fd;
+		}
+	}
+	if (buffer->ready_render_fence) {
+		fd = get_unused_fd_flags(O_CLOEXEC);
+		if (fd < 0)
+			goto no_memory;
+		fd_install(fd, buffer->ready_render_fence);
+		buffer->base.fence_fd = fd;
+		buffer->ready_render_fence = NULL;
+	} else {
+		buffer->base.fence_fd = -1;
+	}
+	buffer->base.vt_id = inst->id;
+	data->base = buffer->base;
+	buffer->base.buf_status = RKVT_BUF_ACQUIRE;
+
+	rkvt_dbg(RKVT_DBG_BUFFERS, "VTAB [%d] pfd[0](%d) buf(%p) buf session(%p)\n",
+			inst->id, buffer->fds_pro[0], buffer, buffer->session_pro);
+
+	rkvt_inst_put(inst);
+
+	return 0;
+
+no_memory:
+	pr_info("VTAB [%d] install fd error\n", inst->id);
+	mutex_lock(&inst->lock);
+	for (i = 0; i < buffer->base.num_fds; i++) {
+		rkvt_dbg(RKVT_DBG_FILE,
+				"VTAB [%d] install fd error file(%p) buf(%p) ino(%08lu) fcount=%d\n",
+				inst->id, buffer->file_buf[i], buffer,
+				file_inode(buffer->file_buf[i])->i_ino, inst->fcount);
+		if (buffer->file_buf[i]) {
+			fput(buffer->file_buf[i]);
+			buffer->file_buf[i] = NULL;
+			inst->fcount--;
+		}
+	}
+	if (buffer->ready_render_fence) {
+		fput(buffer->ready_render_fence);
+		buffer->ready_render_fence = NULL;
+	}
+	buffer->base.buf_status = RKVT_BUF_RELEASE;
+
+	kfifo_put(&inst->fifo_to_producer, buffer);
+	mutex_unlock(&inst->lock);
+	if (inst->producer)
+		wake_up_interruptible(&inst->wait_producer);
+	ret = -ENOMEM;
+
+acquire_fail:
+	rkvt_inst_put(inst);
+
+	return ret;
+}
+
+static int
+rkvt_release_buf(struct rkvt_buf_data *data, struct rkvt_session *session)
+{
+	struct rkvt_dev *vt_dev = session->vt_dev;
+	struct rkvt_instance *inst = NULL;
+	struct rkvt_buf_base *buf_base = NULL;
+	struct rkvt_buffer *buffer = NULL;
+	int i;
+	int ret = 0;
+	long long read_buf_id;
+
+	inst = rkvt_inst_get_by_tid(vt_dev, data->vt_id);
+	if (!inst)
+		return -EINVAL;
+	if (!inst->consumer || inst->consumer != session) {
+		ret = -EINVAL;
+		goto release_fail;
+	}
+
+	buf_base = &data->base;
+	buffer = rkvt_buf_get(inst, buf_base->fds[0]);
+	if (!buffer) {
+		ret = -EINVAL;
+		goto release_fail;
+	}
+
+	if (buf_base->fence_fd >= 0)
+		buffer->rendered_fence = sync_file_get_fence(buf_base->fence_fd);
+
+	if (!buffer->rendered_fence)
+		rkvt_dbg(RKVT_DBG_BUFFERS, "VTRB [%d] rendered fence file is null\n", inst->id);
+
+	/* close the fds in consumer side */
+	for (i = 0; i < buf_base->num_fds; i++) {
+		rkvt_dbg(RKVT_DBG_FILE,
+			"VTRB [%d] file(%p) buf(%p) buf session(%p) ino(%08lu) fcount=%d\n",
+			inst->id, buffer->file_buf[i], buffer, buffer->session_pro,
+			buffer->file_buf[i] ? file_inode(buffer->file_buf[i])->i_ino : 0,
+			inst->fcount);
+		rkvt_close_fd(session, buffer->fds_con[i]);
+		inst->fcount--;
+		buffer->base.fds[i] = buffer->fds_pro[i];
+	}
+	if (buffer->ready_render_fence) {
+		fput(buffer->ready_render_fence);
+		buffer->ready_render_fence = NULL;
+	}
+
+	buffer->base.crop = buf_base->crop;
+	buffer->base.buf_status = RKVT_BUF_RELEASE;
+
+	mutex_lock(&inst->lock);
+	read_buf_id = atomic64_read(&inst->buf_id_generator);
+	/* if producer has disconnect */
+	if (!inst->producer) {
+		rkvt_dbg(RKVT_DBG_BUFFERS, "VTRB [%d], buffer no producer\n", inst->id);
+		buffer->base.buf_status = RKVT_BUF_FREE;
+	} else if ((buffer->base.buffer_id >> 8) != (read_buf_id >> 8)) {
+		dev_err(vt_dev->dev, "VTRB [%d] generation is different. cur(%lld) VS exp(%lld)\n",
+			inst->id, buffer->base.buffer_id >> 8, read_buf_id >> 8);
+		buffer->base.buf_status = RKVT_BUF_FREE;
+	} else {
+		if (buffer->session_pro &&
+		    buffer->session_pro != inst->producer) {
+			rkvt_dbg(RKVT_DBG_BUFFERS,
+				"VTRB [%d] producer not valid, producer(%p), buf session(%p)\n",
+				inst->id, inst->producer, buffer->session_pro);
+			buffer->base.buf_status = RKVT_BUF_FREE;
+		}
+
+		kfifo_put(&inst->fifo_to_producer, buffer);
+	}
+	mutex_unlock(&inst->lock);
+
+	if (inst->producer)
+		wake_up_interruptible(&inst->wait_producer);
+
+	rkvt_dbg(RKVT_DBG_BUFFERS, "VTRB [%d] pfd[0]:%d end\n", inst->id, buffer->fds_pro[0]);
+
+release_fail:
+	rkvt_inst_put(inst);
+
+	return ret;
+}
+
+static int
+rkvt_cancel_buf(struct rkvt_buf_data *data, struct rkvt_session *session)
+{
+	struct rkvt_dev *vt_dev = session->vt_dev;
+	struct rkvt_instance *inst = NULL;
+	struct rkvt_buf_base *buf_base = NULL;
+	struct rkvt_buffer *buffer = NULL;
+	int i;
+
+	inst = rkvt_inst_get_by_tid(vt_dev, data->vt_id);
+	if (!inst)
+		return -EINVAL;
+	if (!inst->producer || inst->producer != session) {
+		rkvt_inst_put(inst);
+		return -EINVAL;
+	}
+
+	rkvt_dbg(RKVT_DBG_BUFFERS, "VTCB [%d] start\n", inst->id);
+
+	buf_base = &data->base;
+	buffer = rkvt_get_free_buf(inst);
+	for (i = 0; i < buf_base->num_fds; i++) {
+		buffer->fds_con[i] = -1;
+		buffer->fds_pro[i] = buf_base->fds[i];
+		rkvt_dbg(RKVT_DBG_FILE,
+			"VTCB [%d] fget file(%p) buf(%p) buf session(%p) fcount=%d\n",
+			inst->id, buffer->file_buf[i], buffer,
+			buffer->session_pro, inst->fcount);
+	}
+	// buffer id is empty, generate a new id
+	if (buf_base->buffer_id == 0)
+		buf_base->buffer_id = atomic64_inc_return(&inst->buf_id_generator);
+	buffer->base = *buf_base;
+	buffer->base.buf_status = RKVT_BUF_RELEASE;
+	buffer->session_pro = session;
+	buffer->cid_pro = session->cid;
+
+	mutex_lock(&inst->lock);
+	kfifo_put(&inst->fifo_to_producer, buffer);
+	mutex_unlock(&inst->lock);
+
+	if (inst->producer)
+		wake_up_interruptible(&inst->wait_producer);
+
+	rkvt_dbg(RKVT_DBG_BUFFERS, "VTCB [%d] pfd[0]:%d end\n", inst->id, buffer->fds_pro[0]);
+	rkvt_inst_put(inst);
+
+	return 0;
+}
+
+static unsigned int rkvt_ioctl_dir(unsigned int cmd)
+{
+	switch (cmd) {
+	case RKVT_IOC_ALLOC_ID:
+	case RKVT_IOC_DEQUE_BUF:
+	case RKVT_IOC_ACQUIRE_BUF:
+	case RKVT_IOC_CTRL:
+		return _IOC_READ;
+	case RKVT_IOC_QUEUE_BUF:
+	case RKVT_IOC_RELEASE_BUF:
+	case RKVT_IOC_CANCEL_BUF:
+	case RKVT_IOC_FREE_ID:
+		return _IOC_WRITE;
+	default:
+		return _IOC_DIR(cmd);
+	}
+}
+
+static long rkvt_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
+{
+	int ret = 0;
+	union rkvt_ioc_arg data;
+	struct rkvt_session *session = filep->private_data;
+	unsigned int dir = rkvt_ioctl_dir(cmd);
+	struct rkvt_dev *vt_dev = session->vt_dev;
+	struct rkvt_instance *inst = NULL;
+
+	rkvt_dbg(RKVT_DBG_CMD, "rkvt ioctl cmd 0x%x size %d in\n", cmd, _IOC_SIZE(cmd));
+
+	if (_IOC_SIZE(cmd) > sizeof(data))
+		return -EINVAL;
+
+	if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(cmd)))
+		return -EFAULT;
+
+	switch (cmd) {
+	case RKVT_IOC_ALLOC_ID: {
+		char name[64];
+
+		inst = rkvt_inst_create(session->vt_dev);
+		if (IS_ERR(inst))
+			return PTR_ERR(inst);
+
+		mutex_lock(&vt_dev->inst_lock);
+		++vt_dev->inst_id_generator;
+		ret = idr_alloc(&vt_dev->inst_idr, inst,
+				vt_dev->inst_id_generator, 0, GFP_KERNEL);
+		mutex_unlock(&vt_dev->inst_lock);
+		if (ret < 0) {
+			rkvt_inst_put(inst);
+			return ret;
+		}
+
+		inst->id = ret;
+		snprintf(name, sizeof(name), "instance-%d", inst->id);
+		inst->debug_root =
+			debugfs_create_file(name, 0664, vt_dev->debug_root,
+					    inst, &dbg_instance_fops);
+
+		mutex_lock(&vt_dev->inst_lock);
+		list_add_tail(&inst->session_link, &session->list_inst);
+		mutex_unlock(&vt_dev->inst_lock);
+
+		data.alloc_data.vt_id = inst->id;
+		rkvt_dbg(RKVT_DBG_USER, "rkvt alloc instance [%d], ref %d\n",
+			 inst->id, kref_read(&inst->ref));
+		break;
+	}
+	case RKVT_IOC_FREE_ID: {
+		inst = rkvt_inst_get_by_tid(vt_dev, data.alloc_data.vt_id);
+		/* to do free id operation check */
+		if (!inst) {
+			dev_err(vt_dev->dev, "destroy unknown videotunnel instance:%d\n",
+			       data.alloc_data.vt_id);
+			ret = -EINVAL;
+		} else {
+			rkvt_dbg(RKVT_DBG_USER, "rkvt free instance [%d], ref %d\n",
+				 inst->id, kref_read(&inst->ref));
+
+			mutex_lock(&vt_dev->inst_lock);
+			list_del_init(&inst->session_link);
+			mutex_unlock(&vt_dev->inst_lock);
+			// ref put for rkvt_instance_get_by_tid
+			rkvt_inst_put(inst);
+			// ref put for kref_init in rkvt_inst_create
+			rkvt_inst_put(inst);
+		}
+		break;
+	}
+	case RKVT_IOC_CTRL:
+		ret = rkvt_ctrl_proc(&data.ctrl_data, session);
+		break;
+	case RKVT_IOC_QUEUE_BUF:
+		ret = rkvt_queue_buf(&data.buffer_data, session);
+		break;
+	case RKVT_IOC_DEQUE_BUF:
+		ret = rkvt_deque_buf(&data.buffer_data, session);
+		break;
+	case RKVT_IOC_RELEASE_BUF:
+		ret = rkvt_release_buf(&data.buffer_data, session);
+		break;
+	case RKVT_IOC_ACQUIRE_BUF:
+		ret = rkvt_acquire_buf(&data.buffer_data, session);
+		break;
+	case RKVT_IOC_CANCEL_BUF:
+		ret = rkvt_cancel_buf(&data.buffer_data, session);
+		break;
+	default:
+		dev_err(vt_dev->dev, "%s: cmd 0x%x not found.\n", __func__, cmd);
+		return -ENOTTY;
+	}
+
+	if (dir & _IOC_READ) {
+		if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd)))
+			return -EFAULT;
+	}
+
+	return ret;
+}
+
+static const struct file_operations vt_fops = {
+	.owner = THIS_MODULE,
+	.open = rkvt_open,
+	.release = rkvt_release,
+	.unlocked_ioctl = rkvt_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = rkvt_ioctl,
+#endif
+};
+
+static int rkvt_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct device *dev = &pdev->dev;
+	struct rkvt_dev *vdev = NULL;
+
+	dev_info(dev, "probe start\n");
+	vdev = devm_kzalloc(dev, sizeof(*vdev), GFP_KERNEL);
+	if (!vdev)
+		return -ENOMEM;
+
+	vdev->dev = dev;
+	vdev->dev_name = DEVICE_NAME;
+	vdev->mdev.minor = MISC_DYNAMIC_MINOR;
+	vdev->mdev.name = DEVICE_NAME;
+	vdev->mdev.fops = &vt_fops;
+	platform_set_drvdata(pdev, vdev);
+
+	ret = misc_register(&vdev->mdev);
+	if (ret) {
+		dev_err(dev, "misc_register fail.\n");
+		return ret;
+	}
+
+	mutex_init(&vdev->inst_lock);
+	mutex_init(&vdev->session_lock);
+	idr_init(&vdev->inst_idr);
+	atomic64_set(&vdev->cid_generator, 0);
+	INIT_LIST_HEAD(&vdev->list_inst);
+	INIT_LIST_HEAD(&vdev->list_session);
+	vdev->debug_root = debugfs_create_dir(DEVICE_NAME, NULL);
+	if (!vdev->debug_root)
+		dev_err(dev, "failed to create debugfs root directory.\n");
+
+	dev_info(dev, "probe success\n");
+
+	return 0;
+}
+
+static int rkvt_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rkvt_dev *vdev = platform_get_drvdata(pdev);
+
+	dev_info(dev, "remove device\n");
+
+	idr_destroy(&vdev->inst_idr);
+	debugfs_remove_recursive(vdev->debug_root);
+	misc_deregister(&vdev->mdev);
+
+	return 0;
+}
+
+static const struct of_device_id rk_vt_match[] = {
+	{
+		.compatible = "rockchip,video-tunnel",
+	},
+	{ },
+};
+
+static struct platform_driver rk_vt_driver = {
+	.probe = rkvt_probe,
+	.remove = rkvt_remove,
+	.driver = {
+		.name = "rk_videotunnel_driver",
+		.owner = THIS_MODULE,
+		.of_match_table = rk_vt_match,
+	},
+};
+
+module_platform_driver(rk_vt_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ROCKCHIP videotunnel driver");
diff --git a/kernel/drivers/video/rockchip/vtunnel/rkvtunnel.h b/kernel/drivers/video/rockchip/vtunnel/rkvtunnel.h
new file mode 100644
index 0000000..1781aa7
--- /dev/null
+++ b/kernel/drivers/video/rockchip/vtunnel/rkvtunnel.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2022 Rockchip Electronics Co., Ltd
+ */
+#ifndef __ROCKCHIP_VIDEO_TUNNEL_H__
+#define __ROCKCHIP_VIDEO_TUNNEL_H__
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define MAX_BUF_HANDLE_FDS		16
+#define MAX_BUF_HANDLE_INTS		128
+
+#define RKVT_IOC_MAGIC			'V'
+#define RKVT_IOWR(nr, type)		_IOWR(RKVT_IOC_MAGIC, nr, type)
+
+#define RKVT_IOC_ALLOC_ID		RKVT_IOWR(0x0, struct rkvt_alloc_id_data)
+#define RKVT_IOC_FREE_ID		RKVT_IOWR(0x1, struct rkvt_alloc_id_data)
+#define RKVT_IOC_CTRL			RKVT_IOWR(0x2, struct rkvt_ctrl_data)
+#define RKVT_IOC_QUEUE_BUF		RKVT_IOWR(0x3, struct rkvt_buf_data)
+#define RKVT_IOC_DEQUE_BUF		RKVT_IOWR(0x4, struct rkvt_buf_data)
+#define RKVT_IOC_CANCEL_BUF		RKVT_IOWR(0x5, struct rkvt_buf_data)
+#define RKVT_IOC_ACQUIRE_BUF		RKVT_IOWR(0x6, struct rkvt_buf_data)
+#define RKVT_IOC_RELEASE_BUF		RKVT_IOWR(0x7, struct rkvt_buf_data)
+
+// caller type
+enum rkvt_caller_e {
+	RKVT_CALLER_PRODUCER,
+	RKVT_CALLER_CONSUMER,
+	RKVT_CALLER_BUTT,
+};
+
+// video tunnel caller control
+enum rkvt_ctrl_cmd_e {
+	RKVT_CTRL_CONNECT,
+	RKVT_CTRL_DISCONNECT,
+	RKVT_CTRL_RESET,
+	RKVT_CTRL_HAS_CONSUMER,
+	RKVT_CTRL_BUTT,
+};
+
+struct rkvt_alloc_id_data {
+	int vt_id;
+};
+
+struct rkvt_ctrl_data {
+	int vt_id;
+	enum rkvt_caller_e caller;
+	enum rkvt_ctrl_cmd_e ctrl_cmd;
+	int ctrl_data;
+};
+
+struct rkvt_rect {
+	int left;
+	int top;
+	int right;
+	int bottom;
+};
+
+struct rkvt_buf_base {
+	int vt_id;
+	int fence_fd;
+	int buf_status;
+	int num_fds;     /* number of file-descriptors at &data[0] */
+	int num_ints;    /* number of ints at &data[numFds] */
+	int reserved;
+	int fds[MAX_BUF_HANDLE_FDS];
+	int ints[MAX_BUF_HANDLE_INTS];
+	int64_t priv_data;
+	uint64_t expected_present_time;
+	uint64_t buffer_id;
+	struct rkvt_rect crop;
+};
+
+struct rkvt_buf_data {
+	int vt_id;
+	int timeout_ms;		/* 0: non block, negative: block, other: timeout ms */
+	struct rkvt_buf_base base;
+};
+
+#endif
diff --git a/kernel/drivers/virtio/virtio_mmio.c b/kernel/drivers/virtio/virtio_mmio.c
index e8ef0c6..136f90d 100644
--- a/kernel/drivers/virtio/virtio_mmio.c
+++ b/kernel/drivers/virtio/virtio_mmio.c
@@ -571,11 +571,9 @@
 {
 	struct virtio_device *vdev =
 			container_of(_d, struct virtio_device, dev);
-	struct virtio_mmio_device *vm_dev =
-			container_of(vdev, struct virtio_mmio_device, vdev);
-	struct platform_device *pdev = vm_dev->pdev;
+	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
 
-	devm_kfree(&pdev->dev, vm_dev);
+	kfree(vm_dev);
 }
 
 /* Platform device */
@@ -586,7 +584,7 @@
 	unsigned long magic;
 	int rc;
 
-	vm_dev = devm_kzalloc(&pdev->dev, sizeof(*vm_dev), GFP_KERNEL);
+	vm_dev = kzalloc(sizeof(*vm_dev), GFP_KERNEL);
 	if (!vm_dev)
 		return -ENOMEM;
 
diff --git a/kernel/drivers/virtio/virtio_ring.c b/kernel/drivers/virtio/virtio_ring.c
index ce325ab..a4ae841 100644
--- a/kernel/drivers/virtio/virtio_ring.c
+++ b/kernel/drivers/virtio/virtio_ring.c
@@ -1190,7 +1190,7 @@
 		}
 	}
 
-	if (i < head)
+	if (i <= head)
 		vq->packed.avail_wrap_counter ^= 1;
 
 	/* We're using some buffers from the free list. */
diff --git a/kernel/drivers/vme/bridges/vme_fake.c b/kernel/drivers/vme/bridges/vme_fake.c
index 6a1bc28..eae7836 100644
--- a/kernel/drivers/vme/bridges/vme_fake.c
+++ b/kernel/drivers/vme/bridges/vme_fake.c
@@ -1073,6 +1073,8 @@
 
 	/* 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.
diff --git a/kernel/drivers/vme/bridges/vme_tsi148.c b/kernel/drivers/vme/bridges/vme_tsi148.c
index 50ae269..5ccda1a 100644
--- a/kernel/drivers/vme/bridges/vme_tsi148.c
+++ b/kernel/drivers/vme/bridges/vme_tsi148.c
@@ -1771,6 +1771,7 @@
 	return 0;
 
 err_dma:
+	list_del(&entry->list);
 err_dest:
 err_source:
 err_align:
diff --git a/kernel/drivers/w1/slaves/w1_therm.c b/kernel/drivers/w1/slaves/w1_therm.c
index 6546d02..3888643 100644
--- a/kernel/drivers/w1/slaves/w1_therm.c
+++ b/kernel/drivers/w1/slaves/w1_therm.c
@@ -1094,29 +1094,26 @@
 
 			w1_write_8(dev_master, W1_CONVERT_TEMP);
 
-			if (strong_pullup) { /*some device need pullup */
+			if (SLAVE_FEATURES(sl) & W1_THERM_POLL_COMPLETION) {
+				ret = w1_poll_completion(dev_master, W1_POLL_CONVERT_TEMP);
+				if (ret) {
+					dev_dbg(&sl->dev, "%s: Timeout\n", __func__);
+					goto mt_unlock;
+				}
+				mutex_unlock(&dev_master->bus_mutex);
+			} else if (!strong_pullup) { /*no device need pullup */
 				sleep_rem = msleep_interruptible(t_conv);
 				if (sleep_rem != 0) {
 					ret = -EINTR;
 					goto mt_unlock;
 				}
 				mutex_unlock(&dev_master->bus_mutex);
-			} else { /*no device need pullup */
-				if (SLAVE_FEATURES(sl) & W1_THERM_POLL_COMPLETION) {
-					ret = w1_poll_completion(dev_master, W1_POLL_CONVERT_TEMP);
-					if (ret) {
-						dev_dbg(&sl->dev, "%s: Timeout\n", __func__);
-						goto mt_unlock;
-					}
-					mutex_unlock(&dev_master->bus_mutex);
-				} else {
-					/* Fixed delay */
-					mutex_unlock(&dev_master->bus_mutex);
-					sleep_rem = msleep_interruptible(t_conv);
-					if (sleep_rem != 0) {
-						ret = -EINTR;
-						goto dec_refcnt;
-					}
+			} else { /*some device need pullup */
+				mutex_unlock(&dev_master->bus_mutex);
+				sleep_rem = msleep_interruptible(t_conv);
+				if (sleep_rem != 0) {
+					ret = -EINTR;
+					goto dec_refcnt;
 				}
 			}
 			ret = read_scratchpad(sl, info);
diff --git a/kernel/drivers/w1/w1.c b/kernel/drivers/w1/w1.c
index 15a2ee3..1c1a943 100644
--- a/kernel/drivers/w1/w1.c
+++ b/kernel/drivers/w1/w1.c
@@ -1131,6 +1131,8 @@
 	/* remainder if it woke up early */
 	unsigned long jremain = 0;
 
+	atomic_inc(&dev->refcnt);
+
 	for (;;) {
 
 		if (!jremain && dev->search_count) {
@@ -1158,8 +1160,10 @@
 		 */
 		mutex_unlock(&dev->list_mutex);
 
-		if (kthread_should_stop())
+		if (kthread_should_stop()) {
+			__set_current_state(TASK_RUNNING);
 			break;
+		}
 
 		/* Only sleep when the search is active. */
 		if (dev->search_count) {
@@ -1224,10 +1228,10 @@
 
 static void __exit w1_fini(void)
 {
-	struct w1_master *dev;
+	struct w1_master *dev, *n;
 
 	/* Set netlink removal messages and some cleanup */
-	list_for_each_entry(dev, &w1_masters, w1_master_entry)
+	list_for_each_entry_safe(dev, n, &w1_masters, w1_master_entry)
 		__w1_remove_master_device(dev);
 
 	w1_fini_netlink();
diff --git a/kernel/drivers/w1/w1_int.c b/kernel/drivers/w1/w1_int.c
index b3e1792..3a71c5e 100644
--- a/kernel/drivers/w1/w1_int.c
+++ b/kernel/drivers/w1/w1_int.c
@@ -51,10 +51,9 @@
 	dev->search_count	= w1_search_count;
 	dev->enable_pullup	= w1_enable_pullup;
 
-	/* 1 for w1_process to decrement
-	 * 1 for __w1_remove_master_device to decrement
+	/* For __w1_remove_master_device to decrement
 	 */
-	atomic_set(&dev->refcnt, 2);
+	atomic_set(&dev->refcnt, 1);
 
 	INIT_LIST_HEAD(&dev->slist);
 	INIT_LIST_HEAD(&dev->async_list);
diff --git a/kernel/drivers/watchdog/at91sam9_wdt.c b/kernel/drivers/watchdog/at91sam9_wdt.c
index 292b5a1..fed7be2 100644
--- a/kernel/drivers/watchdog/at91sam9_wdt.c
+++ b/kernel/drivers/watchdog/at91sam9_wdt.c
@@ -206,10 +206,9 @@
 			 "min heartbeat and max heartbeat might be too close for the system to handle it correctly\n");
 
 	if ((tmp & AT91_WDT_WDFIEN) && wdt->irq) {
-		err = request_irq(wdt->irq, wdt_interrupt,
-				  IRQF_SHARED | IRQF_IRQPOLL |
-				  IRQF_NO_SUSPEND,
-				  pdev->name, wdt);
+		err = devm_request_irq(dev, wdt->irq, wdt_interrupt,
+				       IRQF_SHARED | IRQF_IRQPOLL | IRQF_NO_SUSPEND,
+				       pdev->name, wdt);
 		if (err)
 			return err;
 	}
diff --git a/kernel/drivers/watchdog/diag288_wdt.c b/kernel/drivers/watchdog/diag288_wdt.c
index aafc8d9..370f648 100644
--- a/kernel/drivers/watchdog/diag288_wdt.c
+++ b/kernel/drivers/watchdog/diag288_wdt.c
@@ -86,7 +86,7 @@
 		"1:\n"
 		EX_TABLE(0b, 1b)
 		: "+d" (err) : "d"(__func), "d"(__timeout),
-		  "d"(__action), "d"(__len) : "1", "cc");
+		  "d"(__action), "d"(__len) : "1", "cc", "memory");
 	return err;
 }
 
@@ -272,12 +272,21 @@
 	char ebc_begin[] = {
 		194, 197, 199, 201, 213
 	};
+	char *ebc_cmd;
 
 	watchdog_set_nowayout(&wdt_dev, nowayout_info);
 
 	if (MACHINE_IS_VM) {
-		if (__diag288_vm(WDT_FUNC_INIT, 15,
-				 ebc_begin, sizeof(ebc_begin)) != 0) {
+		ebc_cmd = kmalloc(sizeof(ebc_begin), GFP_KERNEL);
+		if (!ebc_cmd) {
+			pr_err("The watchdog cannot be initialized\n");
+			return -ENOMEM;
+		}
+		memcpy(ebc_cmd, ebc_begin, sizeof(ebc_begin));
+		ret = __diag288_vm(WDT_FUNC_INIT, 15,
+				   ebc_cmd, sizeof(ebc_begin));
+		kfree(ebc_cmd);
+		if (ret != 0) {
 			pr_err("The watchdog cannot be initialized\n");
 			return -EINVAL;
 		}
diff --git a/kernel/drivers/watchdog/dw_wdt.c b/kernel/drivers/watchdog/dw_wdt.c
index 32d0e17..2d261b5 100644
--- a/kernel/drivers/watchdog/dw_wdt.c
+++ b/kernel/drivers/watchdog/dw_wdt.c
@@ -156,6 +156,10 @@
 			break;
 	}
 
+	/* For Coverity check */
+	if (idx == DW_WDT_NUM_TOPS)
+		idx = 0;
+
 	return dw_wdt->timeouts[idx].sec;
 }
 
@@ -178,6 +182,9 @@
 		if (dw_wdt->timeouts[idx].top_val == top_val)
 			break;
 	}
+
+	if (idx == DW_WDT_NUM_TOPS)
+		idx = 0;
 
 	/*
 	 * In IRQ mode due to the two stages counter, the actual timeout is
@@ -638,7 +645,7 @@
 
 	ret = dw_wdt_init_timeouts(dw_wdt, dev);
 	if (ret)
-		goto out_disable_clk;
+		goto out_assert_rst;
 
 	wdd = &dw_wdt->wdd;
 	wdd->ops = &dw_wdt_ops;
@@ -669,12 +676,15 @@
 
 	ret = watchdog_register_device(wdd);
 	if (ret)
-		goto out_disable_pclk;
+		goto out_assert_rst;
 
 	dw_wdt_dbgfs_init(dw_wdt);
 
 	return 0;
 
+out_assert_rst:
+	reset_control_assert(dw_wdt->rst);
+
 out_disable_pclk:
 	clk_disable_unprepare(dw_wdt->pclk);
 
diff --git a/kernel/drivers/watchdog/iTCO_wdt.c b/kernel/drivers/watchdog/iTCO_wdt.c
index a370a18..50c874d 100644
--- a/kernel/drivers/watchdog/iTCO_wdt.c
+++ b/kernel/drivers/watchdog/iTCO_wdt.c
@@ -426,6 +426,20 @@
 	return time_left;
 }
 
+/* Returns true if the watchdog was running */
+static bool iTCO_wdt_set_running(struct iTCO_wdt_private *p)
+{
+	u16 val;
+
+	/* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled */
+	val = inw(TCO1_CNT(p));
+	if (!(val & BIT(11))) {
+		set_bit(WDOG_HW_RUNNING, &p->wddev.status);
+		return true;
+	}
+	return false;
+}
+
 /*
  *	Kernel Interfaces
  */
@@ -514,9 +528,6 @@
 		return -ENODEV;	/* Cannot reset NO_REBOOT bit */
 	}
 
-	/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
-	p->update_no_reboot_bit(p->no_reboot_priv, true);
-
 	if (turn_SMI_watchdog_clear_off >= p->iTCO_version) {
 		/*
 		 * Bit 13: TCO_EN -> 0
@@ -568,8 +579,13 @@
 	watchdog_set_drvdata(&p->wddev, p);
 	platform_set_drvdata(pdev, p);
 
-	/* Make sure the watchdog is not running */
-	iTCO_wdt_stop(&p->wddev);
+	if (!iTCO_wdt_set_running(p)) {
+		/*
+		 * If the watchdog was not running set NO_REBOOT now to
+		 * prevent later reboots.
+		 */
+		p->update_no_reboot_bit(p->no_reboot_priv, true);
+	}
 
 	/* Check that the heartbeat value is within it's range;
 	   if not reset to the default */
diff --git a/kernel/drivers/watchdog/intel-mid_wdt.c b/kernel/drivers/watchdog/intel-mid_wdt.c
index 9b2173f..fb7fae7 100644
--- a/kernel/drivers/watchdog/intel-mid_wdt.c
+++ b/kernel/drivers/watchdog/intel-mid_wdt.c
@@ -203,3 +203,4 @@
 MODULE_AUTHOR("David Cohen <david.a.cohen@linux.intel.com>");
 MODULE_DESCRIPTION("Watchdog Driver for Intel MID platform");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:intel_mid_wdt");
diff --git a/kernel/drivers/watchdog/menz69_wdt.c b/kernel/drivers/watchdog/menz69_wdt.c
index 8973f98..bca0938 100644
--- a/kernel/drivers/watchdog/menz69_wdt.c
+++ b/kernel/drivers/watchdog/menz69_wdt.c
@@ -98,14 +98,6 @@
 	.set_timeout = men_z069_wdt_set_timeout,
 };
 
-static struct watchdog_device men_z069_wdt = {
-	.info = &men_z069_info,
-	.ops = &men_z069_ops,
-	.timeout = MEN_Z069_DEFAULT_TIMEOUT,
-	.min_timeout = 1,
-	.max_timeout = MEN_Z069_WDT_COUNTER_MAX / MEN_Z069_TIMER_FREQ,
-};
-
 static int men_z069_probe(struct mcb_device *dev,
 			  const struct mcb_device_id *id)
 {
@@ -125,15 +117,19 @@
 		goto release_mem;
 
 	drv->mem = mem;
+	drv->wdt.info = &men_z069_info;
+	drv->wdt.ops = &men_z069_ops;
+	drv->wdt.timeout = MEN_Z069_DEFAULT_TIMEOUT;
+	drv->wdt.min_timeout = 1;
+	drv->wdt.max_timeout = MEN_Z069_WDT_COUNTER_MAX / MEN_Z069_TIMER_FREQ;
 
-	drv->wdt = men_z069_wdt;
 	watchdog_init_timeout(&drv->wdt, 0, &dev->dev);
 	watchdog_set_nowayout(&drv->wdt, nowayout);
 	watchdog_set_drvdata(&drv->wdt, drv);
 	drv->wdt.parent = &dev->dev;
 	mcb_set_drvdata(dev, drv);
 
-	return watchdog_register_device(&men_z069_wdt);
+	return watchdog_register_device(&drv->wdt);
 
 release_mem:
 	mcb_release_mem(mem);
diff --git a/kernel/drivers/watchdog/pcwd_usb.c b/kernel/drivers/watchdog/pcwd_usb.c
index 1bdaf17..8202f0a 100644
--- a/kernel/drivers/watchdog/pcwd_usb.c
+++ b/kernel/drivers/watchdog/pcwd_usb.c
@@ -325,7 +325,8 @@
 static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd,
 							int *temperature)
 {
-	unsigned char msb, lsb;
+	unsigned char msb = 0x00;
+	unsigned char lsb = 0x00;
 
 	usb_pcwd_send_command(usb_pcwd, CMD_READ_TEMP, &msb, &lsb);
 
@@ -341,7 +342,8 @@
 static int usb_pcwd_get_timeleft(struct usb_pcwd_private *usb_pcwd,
 								int *time_left)
 {
-	unsigned char msb, lsb;
+	unsigned char msb = 0x00;
+	unsigned char lsb = 0x00;
 
 	/* Read the time that's left before rebooting */
 	/* Note: if the board is not yet armed then we will read 0xFFFF */
diff --git a/kernel/drivers/watchdog/sbsa_gwdt.c b/kernel/drivers/watchdog/sbsa_gwdt.c
index f0f1e3b..4cbe6ba 100644
--- a/kernel/drivers/watchdog/sbsa_gwdt.c
+++ b/kernel/drivers/watchdog/sbsa_gwdt.c
@@ -121,6 +121,7 @@
 	struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
 
 	wdd->timeout = timeout;
+	timeout = clamp_t(unsigned int, timeout, 1, wdd->max_hw_heartbeat_ms / 1000);
 
 	if (action)
 		writel(gwdt->clk * timeout,
diff --git a/kernel/drivers/watchdog/sp5100_tco.c b/kernel/drivers/watchdog/sp5100_tco.c
index a730ecb..0db77c9 100644
--- a/kernel/drivers/watchdog/sp5100_tco.c
+++ b/kernel/drivers/watchdog/sp5100_tco.c
@@ -104,6 +104,10 @@
 	val |= SP5100_WDT_START_STOP_BIT;
 	writel(val, SP5100_WDT_CONTROL(tco->tcobase));
 
+	/* This must be a distinct write. */
+	val |= SP5100_WDT_TRIGGER_BIT;
+	writel(val, SP5100_WDT_CONTROL(tco->tcobase));
+
 	return 0;
 }
 
diff --git a/kernel/drivers/watchdog/watchdog_dev.c b/kernel/drivers/watchdog/watchdog_dev.c
index 2ee0174..f37255c 100644
--- a/kernel/drivers/watchdog/watchdog_dev.c
+++ b/kernel/drivers/watchdog/watchdog_dev.c
@@ -1037,8 +1037,8 @@
 		if (wdd->id == 0) {
 			misc_deregister(&watchdog_miscdev);
 			old_wd_data = NULL;
-			put_device(&wd_data->dev);
 		}
+		put_device(&wd_data->dev);
 		return err;
 	}
 
diff --git a/kernel/drivers/xen/events/events_base.c b/kernel/drivers/xen/events/events_base.c
index fba78da..5289154 100644
--- a/kernel/drivers/xen/events/events_base.c
+++ b/kernel/drivers/xen/events/events_base.c
@@ -33,6 +33,7 @@
 #include <linux/slab.h>
 #include <linux/irqnr.h>
 #include <linux/pci.h>
+#include <linux/rcupdate.h>
 #include <linux/spinlock.h>
 #include <linux/cpuhotplug.h>
 #include <linux/atomic.h>
@@ -94,6 +95,7 @@
 struct irq_info {
 	struct list_head list;
 	struct list_head eoi_list;
+	struct rcu_work rwork;
 	short refcnt;
 	short spurious_cnt;
 	short type;             /* type */
@@ -142,22 +144,12 @@
 static DEFINE_MUTEX(irq_mapping_update_lock);
 
 /*
- * Lock protecting event handling loop against removing event channels.
- * Adding of event channels is no issue as the associated IRQ becomes active
- * only after everything is setup (before request_[threaded_]irq() the handler
- * can't be entered for an event, as the event channel will be unmasked only
- * then).
- */
-static DEFINE_RWLOCK(evtchn_rwlock);
-
-/*
  * Lock hierarchy:
  *
  * irq_mapping_update_lock
- *   evtchn_rwlock
- *     IRQ-desc lock
- *       percpu eoi_list_lock
- *         irq_info->lock
+ *   IRQ-desc lock
+ *     percpu eoi_list_lock
+ *       irq_info->lock
  */
 
 static LIST_HEAD(xen_irq_list_head);
@@ -270,6 +262,22 @@
 		legacy_info_ptrs[irq] = info;
 	else
 		irq_set_chip_data(irq, info);
+}
+
+static void delayed_free_irq(struct work_struct *work)
+{
+	struct irq_info *info = container_of(to_rcu_work(work), struct irq_info,
+					     rwork);
+	unsigned int irq = info->irq;
+
+	/* Remove the info pointer only now, with no potential users left. */
+	set_info_for_irq(irq, NULL);
+
+	kfree(info);
+
+	/* Legacy IRQ descriptors are managed by the arch. */
+	if (irq >= nr_legacy_irqs())
+		irq_free_desc(irq);
 }
 
 /* Constructors for packed IRQ information. */
@@ -606,33 +614,36 @@
 
 	eoi = container_of(to_delayed_work(work), struct lateeoi_work, delayed);
 
-	read_lock_irqsave(&evtchn_rwlock, flags);
+	rcu_read_lock();
 
 	while (true) {
-		spin_lock(&eoi->eoi_list_lock);
+		spin_lock_irqsave(&eoi->eoi_list_lock, flags);
 
 		info = list_first_entry_or_null(&eoi->eoi_list, struct irq_info,
 						eoi_list);
 
-		if (info == NULL || now < info->eoi_time) {
-			spin_unlock(&eoi->eoi_list_lock);
+		if (info == NULL)
+			break;
+
+		if (now < info->eoi_time) {
+			mod_delayed_work_on(info->eoi_cpu, system_wq,
+					    &eoi->delayed,
+					    info->eoi_time - now);
 			break;
 		}
 
 		list_del_init(&info->eoi_list);
 
-		spin_unlock(&eoi->eoi_list_lock);
+		spin_unlock_irqrestore(&eoi->eoi_list_lock, flags);
 
 		info->eoi_time = 0;
 
 		xen_irq_lateeoi_locked(info, false);
 	}
 
-	if (info)
-		mod_delayed_work_on(info->eoi_cpu, system_wq,
-				    &eoi->delayed, info->eoi_time - now);
+	spin_unlock_irqrestore(&eoi->eoi_list_lock, flags);
 
-	read_unlock_irqrestore(&evtchn_rwlock, flags);
+	rcu_read_unlock();
 }
 
 static void xen_cpu_init_eoi(unsigned int cpu)
@@ -647,16 +658,15 @@
 void xen_irq_lateeoi(unsigned int irq, unsigned int eoi_flags)
 {
 	struct irq_info *info;
-	unsigned long flags;
 
-	read_lock_irqsave(&evtchn_rwlock, flags);
+	rcu_read_lock();
 
 	info = info_for_irq(irq);
 
 	if (info)
 		xen_irq_lateeoi_locked(info, eoi_flags & XEN_EOI_FLAG_SPURIOUS);
 
-	read_unlock_irqrestore(&evtchn_rwlock, flags);
+	rcu_read_unlock();
 }
 EXPORT_SYMBOL_GPL(xen_irq_lateeoi);
 
@@ -675,6 +685,7 @@
 
 	info->type = IRQT_UNBOUND;
 	info->refcnt = -1;
+	INIT_RCU_WORK(&info->rwork, delayed_free_irq);
 
 	set_info_for_irq(irq, info);
 
@@ -727,31 +738,18 @@
 static void xen_free_irq(unsigned irq)
 {
 	struct irq_info *info = info_for_irq(irq);
-	unsigned long flags;
 
 	if (WARN_ON(!info))
 		return;
-
-	write_lock_irqsave(&evtchn_rwlock, flags);
 
 	if (!list_empty(&info->eoi_list))
 		lateeoi_list_del(info);
 
 	list_del(&info->list);
 
-	set_info_for_irq(irq, NULL);
-
 	WARN_ON(info->refcnt > 0);
 
-	write_unlock_irqrestore(&evtchn_rwlock, flags);
-
-	kfree(info);
-
-	/* Legacy IRQ descriptors are managed by the arch. */
-	if (irq < nr_legacy_irqs())
-		return;
-
-	irq_free_desc(irq);
+	queue_rcu_work(system_wq, &info->rwork);
 }
 
 static void xen_evtchn_close(evtchn_port_t port)
@@ -1639,7 +1637,14 @@
 	int cpu = smp_processor_id();
 	struct evtchn_loop_ctrl ctrl = { 0 };
 
-	read_lock(&evtchn_rwlock);
+	/*
+	 * When closing an event channel the associated IRQ must not be freed
+	 * until all cpus have left the event handling loop. This is ensured
+	 * by taking the rcu_read_lock() while handling events, as freeing of
+	 * the IRQ is handled via queue_rcu_work() _after_ closing the event
+	 * channel.
+	 */
+	rcu_read_lock();
 
 	do {
 		vcpu_info->evtchn_upcall_pending = 0;
@@ -1652,7 +1657,7 @@
 
 	} while (vcpu_info->evtchn_upcall_pending);
 
-	read_unlock(&evtchn_rwlock);
+	rcu_read_unlock();
 
 	/*
 	 * Increment irq_epoch only now to defer EOIs only for
diff --git a/kernel/drivers/xen/pcpu.c b/kernel/drivers/xen/pcpu.c
index 9cf7085..4581217 100644
--- a/kernel/drivers/xen/pcpu.c
+++ b/kernel/drivers/xen/pcpu.c
@@ -58,6 +58,7 @@
 	struct list_head list;
 	struct device dev;
 	uint32_t cpu_id;
+	uint32_t acpi_id;
 	uint32_t flags;
 };
 
@@ -249,6 +250,7 @@
 
 	INIT_LIST_HEAD(&pcpu->list);
 	pcpu->cpu_id = info->xen_cpuid;
+	pcpu->acpi_id = info->acpi_id;
 	pcpu->flags = info->flags;
 
 	/* Need hold on xen_pcpu_lock before pcpu list manipulations */
@@ -416,3 +418,21 @@
 	return ret;
 }
 arch_initcall(xen_pcpu_init);
+
+#ifdef CONFIG_ACPI
+bool __init xen_processor_present(uint32_t acpi_id)
+{
+	const struct pcpu *pcpu;
+	bool online = false;
+
+	mutex_lock(&xen_pcpu_lock);
+	list_for_each_entry(pcpu, &xen_pcpus, list)
+		if (pcpu->acpi_id == acpi_id) {
+			online = pcpu->flags & XEN_PCPU_FLAGS_ONLINE;
+			break;
+		}
+	mutex_unlock(&xen_pcpu_lock);
+
+	return online;
+}
+#endif
diff --git a/kernel/drivers/xen/privcmd.c b/kernel/drivers/xen/privcmd.c
index cd5f2f0..28537a1 100644
--- a/kernel/drivers/xen/privcmd.c
+++ b/kernel/drivers/xen/privcmd.c
@@ -760,7 +760,7 @@
 		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;
diff --git a/kernel/drivers/xen/pvcalls-back.c b/kernel/drivers/xen/pvcalls-back.c
index a7d293f..3c435e1 100644
--- a/kernel/drivers/xen/pvcalls-back.c
+++ b/kernel/drivers/xen/pvcalls-back.c
@@ -129,13 +129,13 @@
 	if (masked_prod < masked_cons) {
 		vec[0].iov_base = data->in + masked_prod;
 		vec[0].iov_len = wanted;
-		iov_iter_kvec(&msg.msg_iter, WRITE, vec, 1, wanted);
+		iov_iter_kvec(&msg.msg_iter, READ, vec, 1, wanted);
 	} else {
 		vec[0].iov_base = data->in + masked_prod;
 		vec[0].iov_len = array_size - masked_prod;
 		vec[1].iov_base = data->in;
 		vec[1].iov_len = wanted - vec[0].iov_len;
-		iov_iter_kvec(&msg.msg_iter, WRITE, vec, 2, wanted);
+		iov_iter_kvec(&msg.msg_iter, READ, vec, 2, wanted);
 	}
 
 	atomic_set(&map->read, 0);
@@ -188,13 +188,13 @@
 	if (pvcalls_mask(prod, array_size) > pvcalls_mask(cons, array_size)) {
 		vec[0].iov_base = data->out + pvcalls_mask(cons, array_size);
 		vec[0].iov_len = size;
-		iov_iter_kvec(&msg.msg_iter, READ, vec, 1, size);
+		iov_iter_kvec(&msg.msg_iter, WRITE, vec, 1, size);
 	} else {
 		vec[0].iov_base = data->out + pvcalls_mask(cons, array_size);
 		vec[0].iov_len = array_size - pvcalls_mask(cons, array_size);
 		vec[1].iov_base = data->out;
 		vec[1].iov_len = size - vec[0].iov_len;
-		iov_iter_kvec(&msg.msg_iter, READ, vec, 2, size);
+		iov_iter_kvec(&msg.msg_iter, WRITE, vec, 2, size);
 	}
 
 	atomic_set(&map->write, 0);
@@ -321,8 +321,10 @@
 	void *page;
 
 	map = kzalloc(sizeof(*map), GFP_KERNEL);
-	if (map == NULL)
+	if (map == NULL) {
+		sock_release(sock);
 		return NULL;
+	}
 
 	map->fedata = fedata;
 	map->sock = sock;
@@ -414,10 +416,8 @@
 					req->u.connect.ref,
 					req->u.connect.evtchn,
 					sock);
-	if (!map) {
+	if (!map)
 		ret = -EFAULT;
-		sock_release(sock);
-	}
 
 out:
 	rsp = RING_GET_RESPONSE(&fedata->ring, fedata->ring.rsp_prod_pvt++);
@@ -558,7 +558,6 @@
 					sock);
 	if (!map) {
 		ret = -EFAULT;
-		sock_release(sock);
 		goto out_error;
 	}
 
diff --git a/kernel/fs/affs/file.c b/kernel/fs/affs/file.c
index d91b013..c3d89fa 100644
--- a/kernel/fs/affs/file.c
+++ b/kernel/fs/affs/file.c
@@ -879,7 +879,7 @@
 	if (inode->i_size > AFFS_I(inode)->mmu_private) {
 		struct address_space *mapping = inode->i_mapping;
 		struct page *page;
-		void *fsdata;
+		void *fsdata = NULL;
 		loff_t isize = inode->i_size;
 		int res;
 
diff --git a/kernel/fs/afs/dir.c b/kernel/fs/afs/dir.c
index 1597950..a59d629 100644
--- a/kernel/fs/afs/dir.c
+++ b/kernel/fs/afs/dir.c
@@ -1313,6 +1313,7 @@
 	op->dentry	= dentry;
 	op->create.mode	= S_IFDIR | mode;
 	op->create.reason = afs_edit_dir_for_mkdir;
+	op->mtime	= current_time(dir);
 	op->ops		= &afs_mkdir_operation;
 	return afs_do_sync_operation(op);
 }
@@ -1616,6 +1617,7 @@
 	op->dentry	= dentry;
 	op->create.mode	= S_IFREG | mode;
 	op->create.reason = afs_edit_dir_for_create;
+	op->mtime	= current_time(dir);
 	op->ops		= &afs_create_operation;
 	return afs_do_sync_operation(op);
 
@@ -1745,6 +1747,7 @@
 	op->ops			= &afs_symlink_operation;
 	op->create.reason	= afs_edit_dir_for_symlink;
 	op->create.symlink	= content;
+	op->mtime		= current_time(dir);
 	return afs_do_sync_operation(op);
 
 error:
diff --git a/kernel/fs/afs/fs_probe.c b/kernel/fs/afs/fs_probe.c
index 04d42e4..def8036 100644
--- a/kernel/fs/afs/fs_probe.c
+++ b/kernel/fs/afs/fs_probe.c
@@ -360,12 +360,15 @@
 	unsigned long nowj, timer_at, poll_at;
 	bool first_pass = true, set_timer = false;
 
-	if (!net->live)
+	if (!net->live) {
+		afs_dec_servers_outstanding(net);
 		return;
+	}
 
 	_enter("");
 
 	if (list_empty(&net->fs_probe_fast) && list_empty(&net->fs_probe_slow)) {
+		afs_dec_servers_outstanding(net);
 		_leave(" [none]");
 		return;
 	}
diff --git a/kernel/fs/afs/inode.c b/kernel/fs/afs/inode.c
index 826fae2..fdca426 100644
--- a/kernel/fs/afs/inode.c
+++ b/kernel/fs/afs/inode.c
@@ -218,6 +218,7 @@
 			set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
 		}
 		change_size = true;
+		data_changed = true;
 	} else if (vnode->status.type == AFS_FTYPE_DIR) {
 		/* Expected directory change is handled elsewhere so
 		 * that we can locally edit the directory and save on a
diff --git a/kernel/fs/afs/vl_probe.c b/kernel/fs/afs/vl_probe.c
index d1c7068..58452b8 100644
--- a/kernel/fs/afs/vl_probe.c
+++ b/kernel/fs/afs/vl_probe.c
@@ -115,8 +115,8 @@
 		}
 	}
 
-	if (rxrpc_kernel_get_srtt(call->net->socket, call->rxcall, &rtt_us) &&
-	    rtt_us < server->probe.rtt) {
+	rxrpc_kernel_get_srtt(call->net->socket, call->rxcall, &rtt_us);
+	if (rtt_us < server->probe.rtt) {
 		server->probe.rtt = rtt_us;
 		server->rtt = rtt_us;
 		alist->preferred = index;
diff --git a/kernel/fs/aio.c b/kernel/fs/aio.c
index 2a9dfa5..5934ea8 100644
--- a/kernel/fs/aio.c
+++ b/kernel/fs/aio.c
@@ -335,6 +335,9 @@
 	spin_lock(&mm->ioctx_lock);
 	rcu_read_lock();
 	table = rcu_dereference(mm->ioctx_table);
+	if (!table)
+		goto out_unlock;
+
 	for (i = 0; i < table->nr; i++) {
 		struct kioctx *ctx;
 
@@ -348,6 +351,7 @@
 		}
 	}
 
+out_unlock:
 	rcu_read_unlock();
 	spin_unlock(&mm->ioctx_lock);
 	return res;
diff --git a/kernel/fs/attr.c b/kernel/fs/attr.c
index 22aa50c..375692e 100644
--- a/kernel/fs/attr.c
+++ b/kernel/fs/attr.c
@@ -18,6 +18,65 @@
 #include <linux/evm.h>
 #include <linux/ima.h>
 
+#include "internal.h"
+
+/**
+ * setattr_should_drop_sgid - determine whether the setgid bit needs to be
+ *                            removed
+ * @inode:	inode to check
+ *
+ * This function determines whether the setgid bit needs to be removed.
+ * We retain backwards compatibility and require setgid bit to be removed
+ * unconditionally if S_IXGRP is set. Otherwise we have the exact same
+ * requirements as setattr_prepare() and setattr_copy().
+ *
+ * Return: ATTR_KILL_SGID if setgid bit needs to be removed, 0 otherwise.
+ */
+int setattr_should_drop_sgid(const struct inode *inode)
+{
+	umode_t mode = inode->i_mode;
+
+	if (!(mode & S_ISGID))
+		return 0;
+	if (mode & S_IXGRP)
+		return ATTR_KILL_SGID;
+	if (!in_group_or_capable(inode, inode->i_gid))
+		return ATTR_KILL_SGID;
+	return 0;
+}
+
+/**
+ * setattr_should_drop_suidgid - determine whether the set{g,u}id bit needs to
+ *                               be dropped
+ * @inode:	inode to check
+ *
+ * This function determines whether the set{g,u}id bits need to be removed.
+ * If the setuid bit needs to be removed ATTR_KILL_SUID is returned. If the
+ * setgid bit needs to be removed ATTR_KILL_SGID is returned. If both
+ * set{g,u}id bits need to be removed the corresponding mask of both flags is
+ * returned.
+ *
+ * Return: A mask of ATTR_KILL_S{G,U}ID indicating which - if any - setid bits
+ * to remove, 0 otherwise.
+ */
+int setattr_should_drop_suidgid(struct inode *inode)
+{
+	umode_t mode = inode->i_mode;
+	int kill = 0;
+
+	/* suid always must be killed */
+	if (unlikely(mode & S_ISUID))
+		kill = ATTR_KILL_SUID;
+
+	kill |= setattr_should_drop_sgid(inode);
+
+	if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode)))
+		return kill;
+
+	return 0;
+}
+EXPORT_SYMBOL(setattr_should_drop_suidgid);
+
 static bool chown_ok(const struct inode *inode, kuid_t uid)
 {
 	if (uid_eq(current_fsuid(), inode->i_uid) &&
@@ -90,9 +149,8 @@
 		if (!inode_owner_or_capable(inode))
 			return -EPERM;
 		/* Also check the setgid bit! */
-		if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
-				inode->i_gid) &&
-		    !capable_wrt_inode_uidgid(inode, CAP_FSETID))
+		if (!in_group_or_capable(inode, (ia_valid & ATTR_GID) ?
+						attr->ia_gid : inode->i_gid))
 			attr->ia_mode &= ~S_ISGID;
 	}
 
@@ -193,9 +251,7 @@
 		inode->i_ctime = attr->ia_ctime;
 	if (ia_valid & ATTR_MODE) {
 		umode_t mode = attr->ia_mode;
-
-		if (!in_group_p(inode->i_gid) &&
-		    !capable_wrt_inode_uidgid(inode, CAP_FSETID))
+		if (!in_group_or_capable(inode, inode->i_gid))
 			mode &= ~S_ISGID;
 		inode->i_mode = mode;
 	}
@@ -253,9 +309,25 @@
 	}
 
 	if ((ia_valid & ATTR_MODE)) {
-		umode_t amode = attr->ia_mode;
+		/*
+		 * Don't allow changing the mode of symlinks:
+		 *
+		 * (1) The vfs doesn't take the mode of symlinks into account
+		 *     during permission checking.
+		 * (2) This has never worked correctly. Most major filesystems
+		 *     did return EOPNOTSUPP due to interactions with POSIX ACLs
+		 *     but did still updated the mode of the symlink.
+		 *     This inconsistency led system call wrapper providers such
+		 *     as libc to block changing the mode of symlinks with
+		 *     EOPNOTSUPP already.
+		 * (3) To even do this in the first place one would have to use
+		 *     specific file descriptors and quite some effort.
+		 */
+		if (S_ISLNK(inode->i_mode))
+			return -EOPNOTSUPP;
+
 		/* Flag setting protected by i_mutex */
-		if (is_sxid(amode))
+		if (is_sxid(attr->ia_mode))
 			inode->i_flags &= ~S_NOSEC;
 	}
 
@@ -297,7 +369,7 @@
 		}
 	}
 	if (ia_valid & ATTR_KILL_SGID) {
-		if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
+		if (mode & S_ISGID) {
 			if (!(ia_valid & ATTR_MODE)) {
 				ia_valid = attr->ia_valid |= ATTR_MODE;
 				attr->ia_mode = inode->i_mode;
diff --git a/kernel/fs/autofs/waitq.c b/kernel/fs/autofs/waitq.c
index 5ced859..dd47919 100644
--- a/kernel/fs/autofs/waitq.c
+++ b/kernel/fs/autofs/waitq.c
@@ -32,8 +32,9 @@
 		wq->status = -ENOENT; /* Magic is gone - report failure */
 		kfree(wq->name.name);
 		wq->name.name = NULL;
-		wq->wait_ctr--;
 		wake_up_interruptible(&wq->queue);
+		if (!--wq->wait_ctr)
+			kfree(wq);
 		wq = nwq;
 	}
 	fput(sbi->pipe);	/* Close the pipe */
diff --git a/kernel/fs/binfmt_elf_fdpic.c b/kernel/fs/binfmt_elf_fdpic.c
index be4062b..f4f146f 100644
--- a/kernel/fs/binfmt_elf_fdpic.c
+++ b/kernel/fs/binfmt_elf_fdpic.c
@@ -345,10 +345,9 @@
 	/* there's now no turning back... the old userspace image is dead,
 	 * defunct, deceased, etc.
 	 */
+	SET_PERSONALITY(exec_params.hdr);
 	if (elf_check_fdpic(&exec_params.hdr))
-		set_personality(PER_LINUX_FDPIC);
-	else
-		set_personality(PER_LINUX);
+		current->personality |= PER_LINUX_FDPIC;
 	if (elf_read_implies_exec(&exec_params.hdr, executable_stack))
 		current->personality |= READ_IMPLIES_EXEC;
 
@@ -434,8 +433,9 @@
 	current->mm->start_stack = current->mm->start_brk + stack_size;
 #endif
 
-	if (create_elf_fdpic_tables(bprm, current->mm,
-				    &exec_params, &interp_params) < 0)
+	retval = create_elf_fdpic_tables(bprm, current->mm, &exec_params,
+					 &interp_params);
+	if (retval < 0)
 		goto error;
 
 	kdebug("- start_code  %lx", current->mm->start_code);
diff --git a/kernel/fs/binfmt_misc.c b/kernel/fs/binfmt_misc.c
index 3e4791e..83b1992 100644
--- a/kernel/fs/binfmt_misc.c
+++ b/kernel/fs/binfmt_misc.c
@@ -44,10 +44,10 @@
 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;
diff --git a/kernel/fs/btrfs/backref.c b/kernel/fs/btrfs/backref.c
index 7208ba2..d2f77b1 100644
--- a/kernel/fs/btrfs/backref.c
+++ b/kernel/fs/btrfs/backref.c
@@ -432,6 +432,7 @@
 	u64 wanted_disk_byte = ref->wanted_disk_byte;
 	u64 count = 0;
 	u64 data_offset;
+	u8 type;
 
 	if (level != 0) {
 		eb = path->nodes[level];
@@ -486,6 +487,9 @@
 			continue;
 		}
 		fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
+		type = btrfs_file_extent_type(eb, fi);
+		if (type == BTRFS_FILE_EXTENT_INLINE)
+			goto next;
 		disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
 		data_offset = btrfs_file_extent_offset(eb, fi);
 
diff --git a/kernel/fs/btrfs/block-group.c b/kernel/fs/btrfs/block-group.c
index 889a598..c4e3c1a 100644
--- a/kernel/fs/btrfs/block-group.c
+++ b/kernel/fs/btrfs/block-group.c
@@ -77,14 +77,21 @@
 	}
 	allowed &= flags;
 
-	if (allowed & BTRFS_BLOCK_GROUP_RAID6)
+	/* Select the highest-redundancy RAID level. */
+	if (allowed & BTRFS_BLOCK_GROUP_RAID1C4)
+		allowed = BTRFS_BLOCK_GROUP_RAID1C4;
+	else if (allowed & BTRFS_BLOCK_GROUP_RAID6)
 		allowed = BTRFS_BLOCK_GROUP_RAID6;
+	else if (allowed & BTRFS_BLOCK_GROUP_RAID1C3)
+		allowed = BTRFS_BLOCK_GROUP_RAID1C3;
 	else if (allowed & BTRFS_BLOCK_GROUP_RAID5)
 		allowed = BTRFS_BLOCK_GROUP_RAID5;
 	else if (allowed & BTRFS_BLOCK_GROUP_RAID10)
 		allowed = BTRFS_BLOCK_GROUP_RAID10;
 	else if (allowed & BTRFS_BLOCK_GROUP_RAID1)
 		allowed = BTRFS_BLOCK_GROUP_RAID1;
+	else if (allowed & BTRFS_BLOCK_GROUP_DUP)
+		allowed = BTRFS_BLOCK_GROUP_DUP;
 	else if (allowed & BTRFS_BLOCK_GROUP_RAID0)
 		allowed = BTRFS_BLOCK_GROUP_RAID0;
 
@@ -2279,10 +2286,20 @@
 	}
 
 	ret = inc_block_group_ro(cache, 0);
-	if (!do_chunk_alloc || ret == -ETXTBSY)
-		goto unlock_out;
 	if (!ret)
 		goto out;
+	if (ret == -ETXTBSY)
+		goto unlock_out;
+
+	/*
+	 * Skip chunk alloction if the bg is SYSTEM, this is to avoid system
+	 * chunk allocation storm to exhaust the system chunk array.  Otherwise
+	 * we still want to try our best to mark the block group read-only.
+	 */
+	if (!do_chunk_alloc && ret == -ENOSPC &&
+	    (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM))
+		goto unlock_out;
+
 	alloc_flags = btrfs_get_alloc_profile(fs_info, cache->space_info->flags);
 	ret = btrfs_chunk_alloc(trans, alloc_flags, CHUNK_ALLOC_FORCE);
 	if (ret < 0)
diff --git a/kernel/fs/btrfs/block-rsv.c b/kernel/fs/btrfs/block-rsv.c
index bc920af..eb41dc2 100644
--- a/kernel/fs/btrfs/block-rsv.c
+++ b/kernel/fs/btrfs/block-rsv.c
@@ -121,7 +121,8 @@
 	} else {
 		num_bytes = 0;
 	}
-	if (block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) {
+	if (qgroup_to_release_ret &&
+	    block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) {
 		qgroup_to_release = block_rsv->qgroup_rsv_reserved -
 				    block_rsv->qgroup_rsv_size;
 		block_rsv->qgroup_rsv_reserved = block_rsv->qgroup_rsv_size;
diff --git a/kernel/fs/btrfs/ctree.c b/kernel/fs/btrfs/ctree.c
index 5addd1e..814f2f0 100644
--- a/kernel/fs/btrfs/ctree.c
+++ b/kernel/fs/btrfs/ctree.c
@@ -3589,6 +3589,8 @@
 
 	ret = tree_mod_log_eb_copy(split, c, 0, mid, c_nritems - mid);
 	if (ret) {
+		btrfs_tree_unlock(split);
+		free_extent_buffer(split);
 		btrfs_abort_transaction(trans, ret);
 		return ret;
 	}
@@ -3872,6 +3874,7 @@
 
 	if (check_sibling_keys(left, right)) {
 		ret = -EUCLEAN;
+		btrfs_abort_transaction(trans, ret);
 		btrfs_tree_unlock(right);
 		free_extent_buffer(right);
 		return ret;
@@ -4116,6 +4119,7 @@
 
 	if (check_sibling_keys(left, right)) {
 		ret = -EUCLEAN;
+		btrfs_abort_transaction(trans, ret);
 		goto out;
 	}
 	return __push_leaf_left(path, min_data_size,
@@ -5160,10 +5164,12 @@
 int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
 {
 	struct btrfs_key key;
+	struct btrfs_key orig_key;
 	struct btrfs_disk_key found_key;
 	int ret;
 
 	btrfs_item_key_to_cpu(path->nodes[0], &key, 0);
+	orig_key = key;
 
 	if (key.offset > 0) {
 		key.offset--;
@@ -5180,8 +5186,36 @@
 
 	btrfs_release_path(path);
 	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
-	if (ret < 0)
+	if (ret <= 0)
 		return ret;
+
+	/*
+	 * Previous key not found. Even if we were at slot 0 of the leaf we had
+	 * before releasing the path and calling btrfs_search_slot(), we now may
+	 * be in a slot pointing to the same original key - this can happen if
+	 * after we released the path, one of more items were moved from a
+	 * sibling leaf into the front of the leaf we had due to an insertion
+	 * (see push_leaf_right()).
+	 * If we hit this case and our slot is > 0 and just decrement the slot
+	 * so that the caller does not process the same key again, which may or
+	 * may not break the caller, depending on its logic.
+	 */
+	if (path->slots[0] < btrfs_header_nritems(path->nodes[0])) {
+		btrfs_item_key(path->nodes[0], &found_key, path->slots[0]);
+		ret = comp_keys(&found_key, &orig_key);
+		if (ret == 0) {
+			if (path->slots[0] > 0) {
+				path->slots[0]--;
+				return 0;
+			}
+			/*
+			 * At slot 0, same key as before, it means orig_key is
+			 * the lowest, leftmost, key in the tree. We're done.
+			 */
+			return 1;
+		}
+	}
+
 	btrfs_item_key(path->nodes[0], &found_key, 0);
 	ret = comp_keys(&found_key, &key);
 	/*
diff --git a/kernel/fs/btrfs/ctree.h b/kernel/fs/btrfs/ctree.h
index bcc6848..6783186 100644
--- a/kernel/fs/btrfs/ctree.h
+++ b/kernel/fs/btrfs/ctree.h
@@ -529,8 +529,6 @@
 	int bg_extent_count;
 };
 
-bool btrfs_pinned_by_swapfile(struct btrfs_fs_info *fs_info, void *ptr);
-
 enum {
 	BTRFS_FS_BARRIER,
 	BTRFS_FS_CLOSING_START,
diff --git a/kernel/fs/btrfs/delayed-inode.c b/kernel/fs/btrfs/delayed-inode.c
index 04422d9..bcffe78 100644
--- a/kernel/fs/btrfs/delayed-inode.c
+++ b/kernel/fs/btrfs/delayed-inode.c
@@ -1173,20 +1173,33 @@
 		ret = __btrfs_commit_inode_delayed_items(trans, path,
 							 curr_node);
 		if (ret) {
-			btrfs_release_delayed_node(curr_node);
-			curr_node = NULL;
 			btrfs_abort_transaction(trans, ret);
 			break;
 		}
 
 		prev_node = curr_node;
 		curr_node = btrfs_next_delayed_node(curr_node);
+		/*
+		 * See the comment below about releasing path before releasing
+		 * node. If the commit of delayed items was successful the path
+		 * should always be released, but in case of an error, it may
+		 * point to locked extent buffers (a leaf at the very least).
+		 */
+		ASSERT(path->nodes[0] == NULL);
 		btrfs_release_delayed_node(prev_node);
 	}
 
+	/*
+	 * Release the path to avoid a potential deadlock and lockdep splat when
+	 * releasing the delayed node, as that requires taking the delayed node's
+	 * mutex. If another task starts running delayed items before we take
+	 * the mutex, it will first lock the mutex and then it may try to lock
+	 * the same btree path (leaf).
+	 */
+	btrfs_free_path(path);
+
 	if (curr_node)
 		btrfs_release_delayed_node(curr_node);
-	btrfs_free_path(path);
 	trans->block_rsv = block_rsv;
 
 	return ret;
diff --git a/kernel/fs/btrfs/disk-io.c b/kernel/fs/btrfs/disk-io.c
index f2abd8b..0e25a3f 100644
--- a/kernel/fs/btrfs/disk-io.c
+++ b/kernel/fs/btrfs/disk-io.c
@@ -220,7 +220,7 @@
 	crypto_shash_update(shash, kaddr + BTRFS_CSUM_SIZE,
 			    PAGE_SIZE - BTRFS_CSUM_SIZE);
 
-	for (i = 1; i < num_pages; i++) {
+	for (i = 1; i < num_pages && INLINE_EXTENT_BUFFER_PAGES > 1; i++) {
 		kaddr = page_address(buf->pages[i]);
 		crypto_shash_update(shash, kaddr, PAGE_SIZE);
 	}
@@ -2246,6 +2246,26 @@
 
 	fs_info->csum_shash = csum_shash;
 
+	/*
+	 * Check if the checksum implementation is a fast accelerated one.
+	 * As-is this is a bit of a hack and should be replaced once the csum
+	 * implementations provide that information themselves.
+	 */
+	switch (csum_type) {
+	case BTRFS_CSUM_TYPE_CRC32:
+		if (!strstr(crypto_shash_driver_name(csum_shash), "generic"))
+			set_bit(BTRFS_FS_CSUM_IMPL_FAST, &fs_info->flags);
+		break;
+	case BTRFS_CSUM_TYPE_XXHASH:
+		set_bit(BTRFS_FS_CSUM_IMPL_FAST, &fs_info->flags);
+		break;
+	default:
+		break;
+	}
+
+	btrfs_info(fs_info, "using %s (%s) checksum algorithm",
+			btrfs_super_csum_name(csum_type),
+			crypto_shash_driver_name(csum_shash));
 	return 0;
 }
 
@@ -2476,21 +2496,18 @@
 		ret = -EINVAL;
 	}
 
-	if (memcmp(fs_info->fs_devices->fsid, fs_info->super_copy->fsid,
-		   BTRFS_FSID_SIZE)) {
+	if (memcmp(fs_info->fs_devices->fsid, sb->fsid, BTRFS_FSID_SIZE) != 0) {
 		btrfs_err(fs_info,
 		"superblock fsid doesn't match fsid of fs_devices: %pU != %pU",
-			fs_info->super_copy->fsid, fs_info->fs_devices->fsid);
+			  sb->fsid, fs_info->fs_devices->fsid);
 		ret = -EINVAL;
 	}
 
-	if (btrfs_fs_incompat(fs_info, METADATA_UUID) &&
-	    memcmp(fs_info->fs_devices->metadata_uuid,
-		   fs_info->super_copy->metadata_uuid, BTRFS_FSID_SIZE)) {
+	if (memcmp(fs_info->fs_devices->metadata_uuid, btrfs_sb_fsid_ptr(sb),
+		   BTRFS_FSID_SIZE) != 0) {
 		btrfs_err(fs_info,
 "superblock metadata_uuid doesn't match metadata uuid of fs_devices: %pU != %pU",
-			fs_info->super_copy->metadata_uuid,
-			fs_info->fs_devices->metadata_uuid);
+			  btrfs_sb_fsid_ptr(sb), fs_info->fs_devices->metadata_uuid);
 		ret = -EINVAL;
 	}
 
@@ -4518,7 +4535,11 @@
 		 */
 		inode = igrab(&btrfs_inode->vfs_inode);
 		if (inode) {
+			unsigned int nofs_flag;
+
+			nofs_flag = memalloc_nofs_save();
 			invalidate_inode_pages2(inode->i_mapping);
+			memalloc_nofs_restore(nofs_flag);
 			iput(inode);
 		}
 		spin_lock(&root->delalloc_lock);
@@ -4623,7 +4644,12 @@
 
 	inode = cache->io_ctl.inode;
 	if (inode) {
+		unsigned int nofs_flag;
+
+		nofs_flag = memalloc_nofs_save();
 		invalidate_inode_pages2(inode->i_mapping);
+		memalloc_nofs_restore(nofs_flag);
+
 		BTRFS_I(inode)->generation = 0;
 		cache->io_ctl.inode = NULL;
 		iput(inode);
@@ -4763,3 +4789,58 @@
 
 	return 0;
 }
+
+int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid)
+{
+	struct btrfs_path *path;
+	int ret;
+	struct extent_buffer *l;
+	struct btrfs_key search_key;
+	struct btrfs_key found_key;
+	int slot;
+
+	path = btrfs_alloc_path();
+	if (!path)
+		return -ENOMEM;
+
+	search_key.objectid = BTRFS_LAST_FREE_OBJECTID;
+	search_key.type = -1;
+	search_key.offset = (u64)-1;
+	ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
+	if (ret < 0)
+		goto error;
+	BUG_ON(ret == 0); /* Corruption */
+	if (path->slots[0] > 0) {
+		slot = path->slots[0] - 1;
+		l = path->nodes[0];
+		btrfs_item_key_to_cpu(l, &found_key, slot);
+		*objectid = max_t(u64, found_key.objectid,
+				  BTRFS_FIRST_FREE_OBJECTID - 1);
+	} else {
+		*objectid = BTRFS_FIRST_FREE_OBJECTID - 1;
+	}
+	ret = 0;
+error:
+	btrfs_free_path(path);
+	return ret;
+}
+
+int btrfs_find_free_objectid(struct btrfs_root *root, u64 *objectid)
+{
+	int ret;
+	mutex_lock(&root->objectid_mutex);
+
+	if (unlikely(root->highest_objectid >= BTRFS_LAST_FREE_OBJECTID)) {
+		btrfs_warn(root->fs_info,
+			   "the objectid of root %llu reaches its highest value",
+			   root->root_key.objectid);
+		ret = -ENOSPC;
+		goto out;
+	}
+
+	*objectid = ++root->highest_objectid;
+	ret = 0;
+out:
+	mutex_unlock(&root->objectid_mutex);
+	return ret;
+}
diff --git a/kernel/fs/btrfs/disk-io.h b/kernel/fs/btrfs/disk-io.h
index 182540b..e3b9694 100644
--- a/kernel/fs/btrfs/disk-io.h
+++ b/kernel/fs/btrfs/disk-io.h
@@ -131,6 +131,8 @@
 int btree_lock_page_hook(struct page *page, void *data,
 				void (*flush_fn)(void *));
 int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags);
+int btrfs_find_free_objectid(struct btrfs_root *root, u64 *objectid);
+int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid);
 int __init btrfs_end_io_wq_init(void);
 void __cold btrfs_end_io_wq_exit(void);
 
diff --git a/kernel/fs/btrfs/extent-tree.c b/kernel/fs/btrfs/extent-tree.c
index 2842946..4d2f25e 100644
--- a/kernel/fs/btrfs/extent-tree.c
+++ b/kernel/fs/btrfs/extent-tree.c
@@ -857,6 +857,11 @@
 		err = -ENOENT;
 		goto out;
 	} else if (WARN_ON(ret)) {
+		btrfs_print_leaf(path->nodes[0]);
+		btrfs_err(fs_info,
+"extent item not found for insert, bytenr %llu num_bytes %llu parent %llu root_objectid %llu owner %llu offset %llu",
+			  bytenr, num_bytes, parent, root_objectid, owner,
+			  offset);
 		err = -EIO;
 		goto out;
 	}
@@ -1684,6 +1689,11 @@
 		BUG();
 	if (ret && insert_reserved)
 		btrfs_pin_extent(trans, node->bytenr, node->num_bytes, 1);
+	if (ret < 0)
+		btrfs_err(trans->fs_info,
+"failed to run delayed ref for logical %llu num_bytes %llu type %u action %u ref_mod %d: %d",
+			  node->bytenr, node->num_bytes, node->type,
+			  node->action, node->ref_mod, ret);
 	return ret;
 }
 
@@ -1935,8 +1945,6 @@
 		if (ret) {
 			unselect_delayed_ref_head(delayed_refs, locked_ref);
 			btrfs_put_delayed_ref(ref);
-			btrfs_debug(fs_info, "run_one_delayed_ref returned %d",
-				    ret);
 			return ret;
 		}
 
@@ -4135,8 +4143,11 @@
 			ret = 0;
 		}
 
-		if (unlikely(block_group->cached == BTRFS_CACHE_ERROR))
+		if (unlikely(block_group->cached == BTRFS_CACHE_ERROR)) {
+			if (!cache_block_group_error)
+				cache_block_group_error = -EIO;
 			goto loop;
+		}
 
 		bg_ret = NULL;
 		ret = do_allocation(block_group, &ffe_ctl, &bg_ret);
diff --git a/kernel/fs/btrfs/extent_io.c b/kernel/fs/btrfs/extent_io.c
index 5fc65a7..685a375 100644
--- a/kernel/fs/btrfs/extent_io.c
+++ b/kernel/fs/btrfs/extent_io.c
@@ -4034,11 +4034,12 @@
 			free_extent_buffer(eb);
 
 			/*
-			 * the filesystem may choose to bump up nr_to_write.
+			 * The filesystem may choose to bump up nr_to_write.
 			 * We have to make sure to honor the new nr_to_write
-			 * at any time
+			 * at any time.
 			 */
-			nr_to_write_done = wbc->nr_to_write <= 0;
+			nr_to_write_done = (wbc->sync_mode == WB_SYNC_NONE &&
+					    wbc->nr_to_write <= 0);
 		}
 		pagevec_release(&pvec);
 		cond_resched();
@@ -5633,8 +5634,14 @@
 	char *dst = (char *)dstv;
 	unsigned long i = start >> PAGE_SHIFT;
 
-	if (check_eb_range(eb, start, len))
+	if (check_eb_range(eb, start, len)) {
+		/*
+		 * Invalid range hit, reset the memory, so callers won't get
+		 * some random garbage for their uninitialzed memory.
+		 */
+		memset(dstv, 0, len);
 		return;
+	}
 
 	offset = offset_in_page(start);
 
diff --git a/kernel/fs/btrfs/file-item.c b/kernel/fs/btrfs/file-item.c
index 2de1d82..cbea4f5 100644
--- a/kernel/fs/btrfs/file-item.c
+++ b/kernel/fs/btrfs/file-item.c
@@ -602,7 +602,9 @@
 				sums = kvzalloc(btrfs_ordered_sum_size(fs_info,
 						      bytes_left), GFP_KERNEL);
 				memalloc_nofs_restore(nofs_flag);
-				BUG_ON(!sums); /* -ENOMEM */
+				if (!sums)
+					return BLK_STS_RESOURCE;
+
 				sums->len = bytes_left;
 				ordered = btrfs_lookup_ordered_extent(inode,
 								offset);
diff --git a/kernel/fs/btrfs/free-space-cache.c b/kernel/fs/btrfs/free-space-cache.c
index ba28070..4989c60 100644
--- a/kernel/fs/btrfs/free-space-cache.c
+++ b/kernel/fs/btrfs/free-space-cache.c
@@ -794,15 +794,16 @@
 			}
 			spin_lock(&ctl->tree_lock);
 			ret = link_free_space(ctl, e);
-			ctl->total_bitmaps++;
-			ctl->op->recalc_thresholds(ctl);
-			spin_unlock(&ctl->tree_lock);
 			if (ret) {
+				spin_unlock(&ctl->tree_lock);
 				btrfs_err(fs_info,
 					"Duplicate entries in free space cache, dumping");
 				kmem_cache_free(btrfs_free_space_cachep, e);
 				goto free_cache;
 			}
+			ctl->total_bitmaps++;
+			ctl->op->recalc_thresholds(ctl);
+			spin_unlock(&ctl->tree_lock);
 			list_add_tail(&e->list, &bitmaps);
 		}
 
diff --git a/kernel/fs/btrfs/inode-map.c b/kernel/fs/btrfs/inode-map.c
index 76d2e43..c74340d 100644
--- a/kernel/fs/btrfs/inode-map.c
+++ b/kernel/fs/btrfs/inode-map.c
@@ -525,58 +525,3 @@
 	extent_changeset_free(data_reserved);
 	return ret;
 }
-
-int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid)
-{
-	struct btrfs_path *path;
-	int ret;
-	struct extent_buffer *l;
-	struct btrfs_key search_key;
-	struct btrfs_key found_key;
-	int slot;
-
-	path = btrfs_alloc_path();
-	if (!path)
-		return -ENOMEM;
-
-	search_key.objectid = BTRFS_LAST_FREE_OBJECTID;
-	search_key.type = -1;
-	search_key.offset = (u64)-1;
-	ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
-	if (ret < 0)
-		goto error;
-	BUG_ON(ret == 0); /* Corruption */
-	if (path->slots[0] > 0) {
-		slot = path->slots[0] - 1;
-		l = path->nodes[0];
-		btrfs_item_key_to_cpu(l, &found_key, slot);
-		*objectid = max_t(u64, found_key.objectid,
-				  BTRFS_FIRST_FREE_OBJECTID - 1);
-	} else {
-		*objectid = BTRFS_FIRST_FREE_OBJECTID - 1;
-	}
-	ret = 0;
-error:
-	btrfs_free_path(path);
-	return ret;
-}
-
-int btrfs_find_free_objectid(struct btrfs_root *root, u64 *objectid)
-{
-	int ret;
-	mutex_lock(&root->objectid_mutex);
-
-	if (unlikely(root->highest_objectid >= BTRFS_LAST_FREE_OBJECTID)) {
-		btrfs_warn(root->fs_info,
-			   "the objectid of root %llu reaches its highest value",
-			   root->root_key.objectid);
-		ret = -ENOSPC;
-		goto out;
-	}
-
-	*objectid = ++root->highest_objectid;
-	ret = 0;
-out:
-	mutex_unlock(&root->objectid_mutex);
-	return ret;
-}
diff --git a/kernel/fs/btrfs/inode-map.h b/kernel/fs/btrfs/inode-map.h
index 7a96281..629baf9 100644
--- a/kernel/fs/btrfs/inode-map.h
+++ b/kernel/fs/btrfs/inode-map.h
@@ -10,7 +10,4 @@
 int btrfs_save_ino_cache(struct btrfs_root *root,
 			 struct btrfs_trans_handle *trans);
 
-int btrfs_find_free_objectid(struct btrfs_root *root, u64 *objectid);
-int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid);
-
 #endif
diff --git a/kernel/fs/btrfs/inode.c b/kernel/fs/btrfs/inode.c
index 779b774..c900a39 100644
--- a/kernel/fs/btrfs/inode.c
+++ b/kernel/fs/btrfs/inode.c
@@ -6273,7 +6273,7 @@
 	if (IS_ERR(trans))
 		return PTR_ERR(trans);
 
-	err = btrfs_find_free_ino(root, &objectid);
+	err = btrfs_find_free_objectid(root, &objectid);
 	if (err)
 		goto out_unlock;
 
@@ -6337,7 +6337,7 @@
 	if (IS_ERR(trans))
 		return PTR_ERR(trans);
 
-	err = btrfs_find_free_ino(root, &objectid);
+	err = btrfs_find_free_objectid(root, &objectid);
 	if (err)
 		goto out_unlock;
 
@@ -6481,7 +6481,7 @@
 	if (IS_ERR(trans))
 		return PTR_ERR(trans);
 
-	err = btrfs_find_free_ino(root, &objectid);
+	err = btrfs_find_free_objectid(root, &objectid);
 	if (err)
 		goto out_fail;
 
@@ -9135,7 +9135,7 @@
 	u64 objectid;
 	u64 index;
 
-	ret = btrfs_find_free_ino(root, &objectid);
+	ret = btrfs_find_free_objectid(root, &objectid);
 	if (ret)
 		return ret;
 
@@ -9631,7 +9631,7 @@
 	if (IS_ERR(trans))
 		return PTR_ERR(trans);
 
-	err = btrfs_find_free_ino(root, &objectid);
+	err = btrfs_find_free_objectid(root, &objectid);
 	if (err)
 		goto out_unlock;
 
@@ -9962,7 +9962,7 @@
 	if (IS_ERR(trans))
 		return PTR_ERR(trans);
 
-	ret = btrfs_find_free_ino(root, &objectid);
+	ret = btrfs_find_free_objectid(root, &objectid);
 	if (ret)
 		goto out;
 
diff --git a/kernel/fs/btrfs/ioctl.c b/kernel/fs/btrfs/ioctl.c
index a17076a..930126b 100644
--- a/kernel/fs/btrfs/ioctl.c
+++ b/kernel/fs/btrfs/ioctl.c
@@ -2550,6 +2550,13 @@
 				goto out_put;
 			}
 
+			/*
+			 * We don't need the path anymore, so release it and
+			 * avoid deadlocks and lockdep warnings in case
+			 * btrfs_iget() needs to lookup the inode from its root
+			 * btree and lock the same leaf.
+			 */
+			btrfs_release_path(path);
 			temp_inode = btrfs_iget(sb, key2.objectid, root);
 			if (IS_ERR(temp_inode)) {
 				ret = PTR_ERR(temp_inode);
@@ -2569,7 +2576,6 @@
 				goto out_put;
 			}
 
-			btrfs_release_path(path);
 			key.objectid = key.offset;
 			key.offset = (u64)-1;
 			dirid = key.objectid;
@@ -3401,13 +3407,10 @@
 	di_args->bytes_used = btrfs_device_get_bytes_used(dev);
 	di_args->total_bytes = btrfs_device_get_total_bytes(dev);
 	memcpy(di_args->uuid, dev->uuid, sizeof(di_args->uuid));
-	if (dev->name) {
-		strncpy(di_args->path, rcu_str_deref(dev->name),
-				sizeof(di_args->path) - 1);
-		di_args->path[sizeof(di_args->path) - 1] = 0;
-	} else {
+	if (dev->name)
+		strscpy(di_args->path, rcu_str_deref(dev->name), sizeof(di_args->path));
+	else
 		di_args->path[0] = '\0';
-	}
 
 out:
 	rcu_read_unlock();
@@ -3704,6 +3707,11 @@
 	sa = memdup_user(arg, sizeof(*sa));
 	if (IS_ERR(sa))
 		return PTR_ERR(sa);
+
+	if (sa->flags & ~BTRFS_SCRUB_SUPPORTED_FLAGS) {
+		ret = -EOPNOTSUPP;
+		goto out;
+	}
 
 	if (!(sa->flags & BTRFS_SCRUB_READONLY)) {
 		ret = mnt_want_write_file(file);
@@ -4257,7 +4265,9 @@
 	}
 
 	/* update qgroup status and info */
+	mutex_lock(&fs_info->qgroup_ioctl_lock);
 	err = btrfs_run_qgroups(trans);
+	mutex_unlock(&fs_info->qgroup_ioctl_lock);
 	if (err < 0)
 		btrfs_handle_fs_error(fs_info, err,
 				      "failed to update qgroup status and info");
diff --git a/kernel/fs/btrfs/print-tree.c b/kernel/fs/btrfs/print-tree.c
index c62771f..e98ba4e 100644
--- a/kernel/fs/btrfs/print-tree.c
+++ b/kernel/fs/btrfs/print-tree.c
@@ -147,10 +147,10 @@
 			pr_cont("shared data backref parent %llu count %u\n",
 			       offset, btrfs_shared_data_ref_count(eb, sref));
 			/*
-			 * offset is supposed to be a tree block which
-			 * must be aligned to nodesize.
+			 * Offset is supposed to be a tree block which must be
+			 * aligned to sectorsize.
 			 */
-			if (!IS_ALIGNED(offset, eb->fs_info->nodesize))
+			if (!IS_ALIGNED(offset, eb->fs_info->sectorsize))
 				pr_info(
 			"\t\t\t(parent %llu not aligned to sectorsize %u)\n",
 				     offset, eb->fs_info->sectorsize);
diff --git a/kernel/fs/btrfs/qgroup.c b/kernel/fs/btrfs/qgroup.c
index 74cbbb5..a67323c 100644
--- a/kernel/fs/btrfs/qgroup.c
+++ b/kernel/fs/btrfs/qgroup.c
@@ -1202,11 +1202,22 @@
 	int ret = 0;
 
 	/*
-	 * We need to have subvol_sem write locked, to prevent races between
-	 * concurrent tasks trying to disable quotas, because we will unlock
-	 * and relock qgroup_ioctl_lock across BTRFS_FS_QUOTA_ENABLED changes.
+	 * We need to have subvol_sem write locked to prevent races with
+	 * snapshot creation.
 	 */
 	lockdep_assert_held_write(&fs_info->subvol_sem);
+
+	/*
+	 * Lock the cleaner mutex to prevent races with concurrent relocation,
+	 * because relocation may be building backrefs for blocks of the quota
+	 * root while we are deleting the root. This is like dropping fs roots
+	 * of deleted snapshots/subvolumes, we need the same protection.
+	 *
+	 * This also prevents races between concurrent tasks trying to disable
+	 * quotas, because we will unlock and relock qgroup_ioctl_lock across
+	 * BTRFS_FS_QUOTA_ENABLED changes.
+	 */
+	mutex_lock(&fs_info->cleaner_mutex);
 
 	mutex_lock(&fs_info->qgroup_ioctl_lock);
 	if (!fs_info->quota_root)
@@ -1270,7 +1281,9 @@
 		goto out;
 	}
 
+	spin_lock(&fs_info->trans_lock);
 	list_del(&quota_root->dirty_list);
+	spin_unlock(&fs_info->trans_lock);
 
 	btrfs_tree_lock(quota_root->node);
 	btrfs_clean_tree_block(quota_root->node);
@@ -1285,6 +1298,7 @@
 		btrfs_end_transaction(trans);
 	else if (trans)
 		ret = btrfs_end_transaction(trans);
+	mutex_unlock(&fs_info->cleaner_mutex);
 
 	return ret;
 }
@@ -2762,12 +2776,21 @@
 }
 
 /*
- * called from commit_transaction. Writes all changed qgroups to disk.
+ * Writes all changed qgroups to disk.
+ * Called by the transaction commit path and the qgroup assign ioctl.
  */
 int btrfs_run_qgroups(struct btrfs_trans_handle *trans)
 {
 	struct btrfs_fs_info *fs_info = trans->fs_info;
 	int ret = 0;
+
+	/*
+	 * In case we are called from the qgroup assign ioctl, assert that we
+	 * are holding the qgroup_ioctl_lock, otherwise we can race with a quota
+	 * disable operation (ioctl) and access a freed quota root.
+	 */
+	if (trans->transaction->state != TRANS_STATE_COMMIT_DOING)
+		lockdep_assert_held(&fs_info->qgroup_ioctl_lock);
 
 	if (!fs_info->quota_root)
 		return ret;
@@ -3296,6 +3319,7 @@
 	int err = -ENOMEM;
 	int ret = 0;
 	bool stopped = false;
+	bool did_leaf_rescans = false;
 
 	path = btrfs_alloc_path();
 	if (!path)
@@ -3316,6 +3340,7 @@
 		}
 
 		err = qgroup_rescan_leaf(trans, path);
+		did_leaf_rescans = true;
 
 		if (err > 0)
 			btrfs_commit_transaction(trans);
@@ -3336,16 +3361,23 @@
 	mutex_unlock(&fs_info->qgroup_rescan_lock);
 
 	/*
-	 * only update status, since the previous part has already updated the
-	 * qgroup info.
+	 * Only update status, since the previous part has already updated the
+	 * qgroup info, and only if we did any actual work. This also prevents
+	 * race with a concurrent quota disable, which has already set
+	 * fs_info->quota_root to NULL and cleared BTRFS_FS_QUOTA_ENABLED at
+	 * btrfs_quota_disable().
 	 */
-	trans = btrfs_start_transaction(fs_info->quota_root, 1);
-	if (IS_ERR(trans)) {
-		err = PTR_ERR(trans);
+	if (did_leaf_rescans) {
+		trans = btrfs_start_transaction(fs_info->quota_root, 1);
+		if (IS_ERR(trans)) {
+			err = PTR_ERR(trans);
+			trans = NULL;
+			btrfs_err(fs_info,
+				  "fail to start transaction for status update: %d",
+				  err);
+		}
+	} else {
 		trans = NULL;
-		btrfs_err(fs_info,
-			  "fail to start transaction for status update: %d",
-			  err);
 	}
 
 	mutex_lock(&fs_info->qgroup_rescan_lock);
@@ -4356,4 +4388,5 @@
 		ulist_free(entry->old_roots);
 		kfree(entry);
 	}
+	*root = RB_ROOT;
 }
diff --git a/kernel/fs/btrfs/rcu-string.h b/kernel/fs/btrfs/rcu-string.h
index 5c1a617..5c2b66d 100644
--- a/kernel/fs/btrfs/rcu-string.h
+++ b/kernel/fs/btrfs/rcu-string.h
@@ -18,7 +18,11 @@
 					 (len * sizeof(char)), mask);
 	if (!ret)
 		return ret;
-	strncpy(ret->str, src, len);
+	/* Warn if the source got unexpectedly truncated. */
+	if (WARN_ON(strscpy(ret->str, src, len) < 0)) {
+		kfree(ret);
+		return NULL;
+	}
 	return ret;
 }
 
diff --git a/kernel/fs/btrfs/relocation.c b/kernel/fs/btrfs/relocation.c
index c21545c..93db448 100644
--- a/kernel/fs/btrfs/relocation.c
+++ b/kernel/fs/btrfs/relocation.c
@@ -1895,7 +1895,7 @@
 	list_splice(&reloc_roots, &rc->reloc_roots);
 
 	if (!err)
-		btrfs_commit_transaction(trans);
+		err = btrfs_commit_transaction(trans);
 	else
 		btrfs_end_transaction(trans);
 	return err;
@@ -3270,8 +3270,12 @@
 		 */
 		return PTR_ERR(trans);
 	}
-	btrfs_commit_transaction(trans);
-	return 0;
+
+	ret = btrfs_commit_transaction(trans);
+	if (ret)
+		unset_reloc_control(rc);
+
+	return ret;
 }
 
 static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
@@ -3443,7 +3447,9 @@
 		err = PTR_ERR(trans);
 		goto out_free;
 	}
-	btrfs_commit_transaction(trans);
+	ret = btrfs_commit_transaction(trans);
+	if (ret && !err)
+		err = ret;
 out_free:
 	ret = clean_dirty_subvols(rc);
 	if (ret < 0 && !err)
diff --git a/kernel/fs/btrfs/scrub.c b/kernel/fs/btrfs/scrub.c
index 88b9a53..715a032 100644
--- a/kernel/fs/btrfs/scrub.c
+++ b/kernel/fs/btrfs/scrub.c
@@ -3559,13 +3559,20 @@
 		ret = btrfs_inc_block_group_ro(cache, sctx->is_dev_replace);
 		if (ret == 0) {
 			ro_set = 1;
-		} else if (ret == -ENOSPC && !sctx->is_dev_replace) {
+		} else if (ret == -ENOSPC && !sctx->is_dev_replace &&
+			   !(cache->flags & BTRFS_BLOCK_GROUP_RAID56_MASK)) {
 			/*
 			 * btrfs_inc_block_group_ro return -ENOSPC when it
 			 * failed in creating new chunk for metadata.
 			 * It is not a problem for scrub, because
 			 * metadata are always cowed, and our scrub paused
 			 * commit_transactions.
+			 *
+			 * For RAID56 chunks, we have to mark them read-only
+			 * for scrub, as later we would use our own cache
+			 * out of RAID56 realm.
+			 * Thus we want the RAID56 bg to be marked RO to
+			 * prevent RMW from screwing up out cache.
 			 */
 			ro_set = 0;
 		} else if (ret == -ETXTBSY) {
diff --git a/kernel/fs/btrfs/send.c b/kernel/fs/btrfs/send.c
index 4a6ba09..b081b61 100644
--- a/kernel/fs/btrfs/send.c
+++ b/kernel/fs/btrfs/send.c
@@ -7276,10 +7276,10 @@
 	/*
 	 * Check that we don't overflow at later allocations, we request
 	 * clone_sources_count + 1 items, and compare to unsigned long inside
-	 * access_ok.
+	 * access_ok. Also set an upper limit for allocation size so this can't
+	 * easily exhaust memory. Max number of clone sources is about 200K.
 	 */
-	if (arg->clone_sources_count >
-	    ULONG_MAX / sizeof(struct clone_root) - 1) {
+	if (arg->clone_sources_count > SZ_8M / sizeof(struct clone_root)) {
 		ret = -EINVAL;
 		goto out;
 	}
diff --git a/kernel/fs/btrfs/super.c b/kernel/fs/btrfs/super.c
index 310f18d..95b7115 100644
--- a/kernel/fs/btrfs/super.c
+++ b/kernel/fs/btrfs/super.c
@@ -1692,8 +1692,6 @@
 	} else {
 		snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
 		btrfs_sb(s)->bdev_holder = fs_type;
-		if (!strstr(crc32c_impl(), "generic"))
-			set_bit(BTRFS_FS_CSUM_IMPL_FAST, &fs_info->flags);
 		error = btrfs_fill_super(s, fs_devices, data);
 	}
 	if (!error)
@@ -2269,7 +2267,7 @@
 	 * calculated f_bavail.
 	 */
 	if (!mixed && block_rsv->space_info->full &&
-	    total_free_meta - thresh < block_rsv->size)
+	    (total_free_meta < thresh || total_free_meta - thresh < block_rsv->size))
 		buf->f_bavail = 0;
 
 	buf->f_type = BTRFS_SUPER_MAGIC;
diff --git a/kernel/fs/btrfs/transaction.c b/kernel/fs/btrfs/transaction.c
index 8daa9e4..d23047b 100644
--- a/kernel/fs/btrfs/transaction.c
+++ b/kernel/fs/btrfs/transaction.c
@@ -301,10 +301,11 @@
 	spin_unlock(&fs_info->trans_lock);
 
 	/*
-	 * If we are ATTACH, we just want to catch the current transaction,
-	 * and commit it. If there is no transaction, just return ENOENT.
+	 * If we are ATTACH or TRANS_JOIN_NOSTART, we just want to catch the
+	 * current transaction, and commit it. If there is no transaction, just
+	 * return ENOENT.
 	 */
-	if (type == TRANS_ATTACH)
+	if (type == TRANS_ATTACH || type == TRANS_JOIN_NOSTART)
 		return -ENOENT;
 
 	/*
@@ -821,8 +822,13 @@
 
 	trans = start_transaction(root, 0, TRANS_ATTACH,
 				  BTRFS_RESERVE_NO_FLUSH, true);
-	if (trans == ERR_PTR(-ENOENT))
-		btrfs_wait_for_commit(root->fs_info, 0);
+	if (trans == ERR_PTR(-ENOENT)) {
+		int ret;
+
+		ret = btrfs_wait_for_commit(root->fs_info, 0);
+		if (ret)
+			return ERR_PTR(ret);
+	}
 
 	return trans;
 }
@@ -886,6 +892,7 @@
 	}
 
 	wait_for_commit(cur_trans);
+	ret = cur_trans->aborted;
 	btrfs_put_transaction(cur_trans);
 out:
 	return ret;
diff --git a/kernel/fs/btrfs/volumes.c b/kernel/fs/btrfs/volumes.c
index 9191bbb..389493e 100644
--- a/kernel/fs/btrfs/volumes.c
+++ b/kernel/fs/btrfs/volumes.c
@@ -381,6 +381,7 @@
 static void free_fs_devices(struct btrfs_fs_devices *fs_devices)
 {
 	struct btrfs_device *device;
+
 	WARN_ON(fs_devices->opened);
 	while (!list_empty(&fs_devices->devices)) {
 		device = list_entry(fs_devices->devices.next,
@@ -715,6 +716,14 @@
 	blkdev_put(bdev, flags);
 
 	return -EINVAL;
+}
+
+u8 *btrfs_sb_fsid_ptr(struct btrfs_super_block *sb)
+{
+	bool has_metadata_uuid = (btrfs_super_incompat_flags(sb) &
+				  BTRFS_FEATURE_INCOMPAT_METADATA_UUID);
+
+	return has_metadata_uuid ? sb->metadata_uuid : sb->fsid;
 }
 
 /*
@@ -1227,8 +1236,21 @@
 
 	mutex_lock(&uuid_mutex);
 	close_fs_devices(fs_devices);
-	if (!fs_devices->opened)
+	if (!fs_devices->opened) {
 		list_splice_init(&fs_devices->seed_list, &list);
+
+		/*
+		 * If the struct btrfs_fs_devices is not assembled with any
+		 * other device, it can be re-initialized during the next mount
+		 * without the needing device-scan step. Therefore, it can be
+		 * fully freed.
+		 */
+		if (fs_devices->num_devices == 1) {
+			list_del(&fs_devices->fs_list);
+			free_fs_devices(fs_devices);
+		}
+	}
+
 
 	list_for_each_entry_safe(fs_devices, tmp, &list, seed_list) {
 		close_fs_devices(fs_devices);
@@ -1396,8 +1418,17 @@
 	 * later supers, using BTRFS_SUPER_MIRROR_MAX instead
 	 */
 	bytenr = btrfs_sb_offset(0);
-	flags |= FMODE_EXCL;
 
+	/*
+	 * Avoid using flag |= FMODE_EXCL here, as the systemd-udev may
+	 * initiate the device scan which may race with the user's mount
+	 * or mkfs command, resulting in failure.
+	 * Since the device scan is solely for reading purposes, there is
+	 * no need for FMODE_EXCL. Additionally, the devices are read again
+	 * during the mount process. It is ok to get some inconsistent
+	 * values temporarily, as the device paths of the fsid are the only
+	 * required information for assembling the volume.
+	 */
 	bdev = blkdev_get_by_path(path, flags, holder);
 	if (IS_ERR(bdev))
 		return ERR_CAST(bdev);
@@ -1579,7 +1610,7 @@
 			goto out;
 	}
 
-	while (1) {
+	while (search_start < search_end) {
 		l = path->nodes[0];
 		slot = path->slots[0];
 		if (slot >= btrfs_header_nritems(l)) {
@@ -1601,6 +1632,9 @@
 
 		if (key.type != BTRFS_DEV_EXTENT_KEY)
 			goto next;
+
+		if (key.offset > search_end)
+			break;
 
 		if (key.offset > search_start) {
 			hole_size = key.offset - search_start;
@@ -1662,6 +1696,7 @@
 	else
 		ret = 0;
 
+	ASSERT(max_hole_start + max_hole_size <= search_end);
 out:
 	btrfs_free_path(path);
 	*start = max_hole_start;
@@ -4432,8 +4467,7 @@
 		}
 	}
 
-	BUG_ON(fs_info->balance_ctl ||
-		test_bit(BTRFS_FS_BALANCE_RUNNING, &fs_info->flags));
+	ASSERT(!test_bit(BTRFS_FS_BALANCE_RUNNING, &fs_info->flags));
 	atomic_dec(&fs_info->balance_cancel_req);
 	mutex_unlock(&fs_info->balance_mutex);
 	return 0;
diff --git a/kernel/fs/btrfs/volumes.h b/kernel/fs/btrfs/volumes.h
index f217726..b2046e9 100644
--- a/kernel/fs/btrfs/volumes.h
+++ b/kernel/fs/btrfs/volumes.h
@@ -580,4 +580,7 @@
 const char *btrfs_bg_type_to_raid_name(u64 flags);
 int btrfs_verify_dev_extents(struct btrfs_fs_info *fs_info);
 
+bool btrfs_pinned_by_swapfile(struct btrfs_fs_info *fs_info, void *ptr);
+u8 *btrfs_sb_fsid_ptr(struct btrfs_super_block *sb);
+
 #endif
diff --git a/kernel/fs/btrfs/zlib.c b/kernel/fs/btrfs/zlib.c
index 05615a1..673d74d 100644
--- a/kernel/fs/btrfs/zlib.c
+++ b/kernel/fs/btrfs/zlib.c
@@ -63,7 +63,7 @@
 
 	workspacesize = max(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
 			zlib_inflate_workspacesize());
-	workspace->strm.workspace = kvmalloc(workspacesize, GFP_KERNEL);
+	workspace->strm.workspace = kvzalloc(workspacesize, GFP_KERNEL);
 	workspace->level = level;
 	workspace->buf = NULL;
 	/*
diff --git a/kernel/fs/ceph/caps.c b/kernel/fs/ceph/caps.c
index 51562d3..432dc2a 100644
--- a/kernel/fs/ceph/caps.c
+++ b/kernel/fs/ceph/caps.c
@@ -1636,6 +1636,7 @@
 	struct inode *inode = &ci->vfs_inode;
 	struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
 	struct ceph_mds_session *session = NULL;
+	bool need_put = false;
 	int mds;
 
 	dout("ceph_flush_snaps %p\n", inode);
@@ -1687,8 +1688,13 @@
 	}
 	/* we flushed them all; remove this inode from the queue */
 	spin_lock(&mdsc->snap_flush_lock);
+	if (!list_empty(&ci->i_snap_flush_item))
+		need_put = true;
 	list_del_init(&ci->i_snap_flush_item);
 	spin_unlock(&mdsc->snap_flush_lock);
+
+	if (need_put)
+		iput(inode);
 }
 
 /*
@@ -2957,7 +2963,7 @@
 
 	while (true) {
 		flags &= CEPH_FILE_MODE_MASK;
-		if (atomic_read(&fi->num_locks))
+		if (vfs_inode_has_locks(inode))
 			flags |= CHECK_FILELOCK;
 		_got = 0;
 		ret = try_get_cap_refs(inode, need, want, endoff,
@@ -3568,6 +3574,15 @@
 	}
 	BUG_ON(cap->issued & ~cap->implemented);
 
+	/* don't let check_caps skip sending a response to MDS for revoke msgs */
+	if (le32_to_cpu(grant->op) == CEPH_CAP_OP_REVOKE) {
+		cap->mds_wanted = 0;
+		if (cap == ci->i_auth_cap)
+			check_caps = 1; /* check auth cap only */
+		else
+			check_caps = 2; /* check all caps */
+	}
+
 	if (extra_info->inline_version > 0 &&
 	    extra_info->inline_version >= ci->i_inline_version) {
 		ci->i_inline_version = extra_info->inline_version;
diff --git a/kernel/fs/ceph/locks.c b/kernel/fs/ceph/locks.c
index 048a435..674d6ea 100644
--- a/kernel/fs/ceph/locks.c
+++ b/kernel/fs/ceph/locks.c
@@ -32,18 +32,14 @@
 
 static void ceph_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
 {
-	struct ceph_file_info *fi = dst->fl_file->private_data;
 	struct inode *inode = file_inode(dst->fl_file);
 	atomic_inc(&ceph_inode(inode)->i_filelock_ref);
-	atomic_inc(&fi->num_locks);
 }
 
 static void ceph_fl_release_lock(struct file_lock *fl)
 {
-	struct ceph_file_info *fi = fl->fl_file->private_data;
 	struct inode *inode = file_inode(fl->fl_file);
 	struct ceph_inode_info *ci = ceph_inode(inode);
-	atomic_dec(&fi->num_locks);
 	if (atomic_dec_and_test(&ci->i_filelock_ref)) {
 		/* clear error when all locks are released */
 		spin_lock(&ci->i_ceph_lock);
diff --git a/kernel/fs/ceph/mds_client.c b/kernel/fs/ceph/mds_client.c
index fa51872..df1ecb8 100644
--- a/kernel/fs/ceph/mds_client.c
+++ b/kernel/fs/ceph/mds_client.c
@@ -3496,6 +3496,12 @@
 		break;
 
 	case CEPH_SESSION_FLUSHMSG:
+		/* flush cap releases */
+		spin_lock(&session->s_cap_lock);
+		if (session->s_num_cap_releases)
+			ceph_flush_cap_releases(mdsc, session);
+		spin_unlock(&session->s_cap_lock);
+
 		send_flushmsg_ack(mdsc, session, seq);
 		break;
 
@@ -4505,7 +4511,7 @@
 
 	dout("mdsc delayed_work\n");
 
-	if (mdsc->stopping)
+	if (mdsc->stopping >= CEPH_MDSC_STOPPING_FLUSHED)
 		return;
 
 	mutex_lock(&mdsc->mutex);
@@ -4695,7 +4701,7 @@
 void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc)
 {
 	dout("pre_umount\n");
-	mdsc->stopping = 1;
+	mdsc->stopping = CEPH_MDSC_STOPPING_BEGIN;
 
 	ceph_mdsc_iterate_sessions(mdsc, send_flush_mdlog, true);
 	ceph_mdsc_iterate_sessions(mdsc, lock_unlock_session, false);
diff --git a/kernel/fs/ceph/mds_client.h b/kernel/fs/ceph/mds_client.h
index a92e42e..1c95851 100644
--- a/kernel/fs/ceph/mds_client.h
+++ b/kernel/fs/ceph/mds_client.h
@@ -372,6 +372,11 @@
 	int			want;
 };
 
+enum {
+       CEPH_MDSC_STOPPING_BEGIN = 1,
+       CEPH_MDSC_STOPPING_FLUSHED = 2,
+};
+
 /*
  * mds client state
  */
diff --git a/kernel/fs/ceph/metric.c b/kernel/fs/ceph/metric.c
index 9e0a0e2..906e446 100644
--- a/kernel/fs/ceph/metric.c
+++ b/kernel/fs/ceph/metric.c
@@ -130,7 +130,7 @@
 	struct ceph_mds_client *mdsc =
 		container_of(m, struct ceph_mds_client, metric);
 
-	if (mdsc->stopping)
+	if (mdsc->stopping || disable_send_metrics)
 		return;
 
 	if (!m->session || !check_session_state(m->session)) {
diff --git a/kernel/fs/ceph/snap.c b/kernel/fs/ceph/snap.c
index 734873b..db46468 100644
--- a/kernel/fs/ceph/snap.c
+++ b/kernel/fs/ceph/snap.c
@@ -647,8 +647,10 @@
 	     capsnap->size);
 
 	spin_lock(&mdsc->snap_flush_lock);
-	if (list_empty(&ci->i_snap_flush_item))
+	if (list_empty(&ci->i_snap_flush_item)) {
+		ihold(inode);
 		list_add_tail(&ci->i_snap_flush_item, &mdsc->snap_flush_list);
+	}
 	spin_unlock(&mdsc->snap_flush_lock);
 	return 1;  /* caller may want to ceph_flush_snaps */
 }
@@ -1008,6 +1010,19 @@
 				continue;
 			adjust_snap_realm_parent(mdsc, child, realm->ino);
 		}
+	} else {
+		/*
+		 * In the non-split case both 'num_split_inos' and
+		 * 'num_split_realms' should be 0, making this a no-op.
+		 * However the MDS happens to populate 'split_realms' list
+		 * in one of the UPDATE op cases by mistake.
+		 *
+		 * Skip both lists just in case to ensure that 'p' is
+		 * positioned at the start of realm info, as expected by
+		 * ceph_update_snap_trace().
+		 */
+		p += sizeof(u64) * num_split_inos;
+		p += sizeof(u64) * num_split_realms;
 	}
 
 	/*
diff --git a/kernel/fs/ceph/super.c b/kernel/fs/ceph/super.c
index e0562c5..aa8e759 100644
--- a/kernel/fs/ceph/super.c
+++ b/kernel/fs/ceph/super.c
@@ -1222,6 +1222,16 @@
 	ceph_mdsc_pre_umount(fsc->mdsc);
 	flush_fs_workqueues(fsc);
 
+	/*
+	 * Though the kill_anon_super() will finally trigger the
+	 * sync_filesystem() anyway, we still need to do it here
+	 * and then bump the stage of shutdown to stop the work
+	 * queue as earlier as possible.
+	 */
+	sync_filesystem(s);
+
+	fsc->mdsc->stopping = CEPH_MDSC_STOPPING_FLUSHED;
+
 	kill_anon_super(s);
 
 	fsc->client->extra_mon_dispatch = NULL;
diff --git a/kernel/fs/ceph/super.h b/kernel/fs/ceph/super.h
index 4db305f..8716cb6 100644
--- a/kernel/fs/ceph/super.h
+++ b/kernel/fs/ceph/super.h
@@ -772,7 +772,6 @@
 	struct list_head rw_contexts;
 
 	u32 filp_gen;
-	atomic_t num_locks;
 };
 
 struct ceph_dir_file_info {
diff --git a/kernel/fs/char_dev.c b/kernel/fs/char_dev.c
index ba0ded7..3f66729 100644
--- a/kernel/fs/char_dev.c
+++ b/kernel/fs/char_dev.c
@@ -547,7 +547,7 @@
 	}
 
 	rc = device_add(dev);
-	if (rc)
+	if (rc && dev->devt)
 		cdev_del(cdev);
 
 	return rc;
diff --git a/kernel/fs/cifs/cifsfs.c b/kernel/fs/cifs/cifsfs.c
index b582dbf..1754bf5 100644
--- a/kernel/fs/cifs/cifsfs.c
+++ b/kernel/fs/cifs/cifsfs.c
@@ -619,9 +619,15 @@
 	seq_printf(s, ",echo_interval=%lu",
 			tcon->ses->server->echo_interval / HZ);
 
-	/* Only display max_credits if it was overridden on mount */
+	/* Only display the following if overridden on mount */
 	if (tcon->ses->server->max_credits != SMB2_MAX_CREDITS_AVAILABLE)
 		seq_printf(s, ",max_credits=%u", tcon->ses->server->max_credits);
+	if (tcon->ses->server->tcp_nodelay)
+		seq_puts(s, ",tcpnodelay");
+	if (tcon->ses->server->noautotune)
+		seq_puts(s, ",noautotune");
+	if (tcon->ses->server->noblocksnd)
+		seq_puts(s, ",noblocksend");
 
 	if (tcon->snapshot_time)
 		seq_printf(s, ",snapshot=%llu", tcon->snapshot_time);
diff --git a/kernel/fs/cifs/cifsfs.h b/kernel/fs/cifs/cifsfs.h
index e996f0b..59c4141 100644
--- a/kernel/fs/cifs/cifsfs.h
+++ b/kernel/fs/cifs/cifsfs.h
@@ -126,7 +126,10 @@
 #ifdef CONFIG_CIFS_DFS_UPCALL
 extern struct vfsmount *cifs_dfs_d_automount(struct path *path);
 #else
-#define cifs_dfs_d_automount NULL
+static inline struct vfsmount *cifs_dfs_d_automount(struct path *path)
+{
+	return ERR_PTR(-EREMOTE);
+}
 #endif
 
 /* Functions related to symlinks */
diff --git a/kernel/fs/cifs/cifsglob.h b/kernel/fs/cifs/cifsglob.h
index 196285b..92a7628 100644
--- a/kernel/fs/cifs/cifsglob.h
+++ b/kernel/fs/cifs/cifsglob.h
@@ -22,6 +22,8 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <linux/slab.h>
+#include <linux/scatterlist.h>
+#include <linux/mm.h>
 #include <linux/mempool.h>
 #include <linux/workqueue.h>
 #include "cifs_fs_sb.h"
@@ -30,6 +32,7 @@
 #include <linux/scatterlist.h>
 #include <uapi/linux/cifs/cifs_mount.h>
 #include "smb2pdu.h"
+#include "smb2glob.h"
 
 #define CIFS_MAGIC_NUMBER 0xFF534D42      /* the first four bytes of SMB PDUs */
 
@@ -2046,4 +2049,70 @@
 		tcon->share_flags & (SHI1005_FLAGS_DFS | SHI1005_FLAGS_DFS_ROOT);
 }
 
+static inline unsigned int cifs_get_num_sgs(const struct smb_rqst *rqst,
+					    int num_rqst,
+					    const u8 *sig)
+{
+	unsigned int len, skip;
+	unsigned int nents = 0;
+	unsigned long addr;
+	int i, j;
+
+	/* Assumes the first rqst has a transform header as the first iov.
+	 * I.e.
+	 * rqst[0].rq_iov[0]  is transform header
+	 * rqst[0].rq_iov[1+] data to be encrypted/decrypted
+	 * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
+	 */
+	for (i = 0; i < num_rqst; i++) {
+		/*
+		 * The first rqst has a transform header where the
+		 * first 20 bytes are not part of the encrypted blob.
+		 */
+		for (j = 0; j < rqst[i].rq_nvec; j++) {
+			struct kvec *iov = &rqst[i].rq_iov[j];
+
+			skip = (i == 0) && (j == 0) ? 20 : 0;
+			addr = (unsigned long)iov->iov_base + skip;
+			if (unlikely(is_vmalloc_addr((void *)addr))) {
+				len = iov->iov_len - skip;
+				nents += DIV_ROUND_UP(offset_in_page(addr) + len,
+						      PAGE_SIZE);
+			} else {
+				nents++;
+			}
+		}
+		nents += rqst[i].rq_npages;
+	}
+	nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE);
+	return nents;
+}
+
+/* We can not use the normal sg_set_buf() as we will sometimes pass a
+ * stack object as buf.
+ */
+static inline struct scatterlist *cifs_sg_set_buf(struct scatterlist *sg,
+						  const void *buf,
+						  unsigned int buflen)
+{
+	unsigned long addr = (unsigned long)buf;
+	unsigned int off = offset_in_page(addr);
+
+	addr &= PAGE_MASK;
+	if (unlikely(is_vmalloc_addr((void *)addr))) {
+		do {
+			unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off);
+
+			sg_set_page(sg++, vmalloc_to_page((void *)addr), len, off);
+
+			off = 0;
+			addr += PAGE_SIZE;
+			buflen -= len;
+		} while (buflen);
+	} else {
+		sg_set_page(sg++, virt_to_page(addr), buflen, off);
+	}
+	return sg;
+}
+
 #endif	/* _CIFS_GLOB_H */
diff --git a/kernel/fs/cifs/cifsproto.h b/kernel/fs/cifs/cifsproto.h
index a6ca4ed..ca34cc1 100644
--- a/kernel/fs/cifs/cifsproto.h
+++ b/kernel/fs/cifs/cifsproto.h
@@ -602,8 +602,8 @@
 		    struct sdesc **sdesc);
 void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc);
 
-extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
-				unsigned int *len, unsigned int *offset);
+void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page,
+			  unsigned int *len, unsigned int *offset);
 struct cifs_chan *
 cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server);
 int cifs_try_adding_channels(struct cifs_ses *ses);
diff --git a/kernel/fs/cifs/cifssmb.c b/kernel/fs/cifs/cifssmb.c
index c279527..95992c9 100644
--- a/kernel/fs/cifs/cifssmb.c
+++ b/kernel/fs/cifs/cifssmb.c
@@ -4859,8 +4859,13 @@
 		return -ENODEV;
 
 getDFSRetry:
-	rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
-		      (void **) &pSMBr);
+	/*
+	 * Use smb_init_no_reconnect() instead of smb_init() as
+	 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
+	 * causing an infinite recursion.
+	 */
+	rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
+				   (void **)&pSMB, (void **)&pSMBr);
 	if (rc)
 		return rc;
 
diff --git a/kernel/fs/cifs/connect.c b/kernel/fs/cifs/connect.c
index d1c3086..164b985 100644
--- a/kernel/fs/cifs/connect.c
+++ b/kernel/fs/cifs/connect.c
@@ -3038,7 +3038,7 @@
 struct cifs_ses *
 cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
 {
-	int rc = -ENOMEM;
+	int rc = 0;
 	unsigned int xid;
 	struct cifs_ses *ses;
 	struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
@@ -3080,6 +3080,8 @@
 		return ses;
 	}
 
+	rc = -ENOMEM;
+
 	cifs_dbg(FYI, "Existing smb sess not found\n");
 	ses = sesInfoAlloc();
 	if (ses == NULL)
diff --git a/kernel/fs/cifs/file.c b/kernel/fs/cifs/file.c
index 144064d..a567382 100644
--- a/kernel/fs/cifs/file.c
+++ b/kernel/fs/cifs/file.c
@@ -3539,7 +3539,7 @@
 		rdata->got_bytes += result;
 	}
 
-	return rdata->got_bytes > 0 && result != -ECONNABORTED ?
+	return result != -ECONNABORTED && rdata->got_bytes > 0 ?
 						rdata->got_bytes : result;
 }
 
@@ -4302,7 +4302,7 @@
 		rdata->got_bytes += result;
 	}
 
-	return rdata->got_bytes > 0 && result != -ECONNABORTED ?
+	return result != -ECONNABORTED && rdata->got_bytes > 0 ?
 						rdata->got_bytes : result;
 }
 
@@ -4580,9 +4580,9 @@
 
 io_error:
 	kunmap(page);
-	unlock_page(page);
 
 read_complete:
+	unlock_page(page);
 	return rc;
 }
 
diff --git a/kernel/fs/cifs/link.c b/kernel/fs/cifs/link.c
index 85d30fe..4fc6eb8 100644
--- a/kernel/fs/cifs/link.c
+++ b/kernel/fs/cifs/link.c
@@ -471,6 +471,7 @@
 	oparms.disposition = FILE_CREATE;
 	oparms.fid = &fid;
 	oparms.reconnect = false;
+	oparms.mode = 0644;
 
 	rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
 		       NULL, NULL);
diff --git a/kernel/fs/cifs/misc.c b/kernel/fs/cifs/misc.c
index 9d74091..9044b0f 100644
--- a/kernel/fs/cifs/misc.c
+++ b/kernel/fs/cifs/misc.c
@@ -974,8 +974,8 @@
  * Input: rqst - a smb_rqst, page - a page index for rqst
  * Output: *len - the length for this page, *offset - the offset for this page
  */
-void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
-				unsigned int *len, unsigned int *offset)
+void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page,
+			  unsigned int *len, unsigned int *offset)
 {
 	*len = rqst->rq_pagesz;
 	*offset = (page == 0) ? rqst->rq_offset : 0;
diff --git a/kernel/fs/cifs/smb2inode.c b/kernel/fs/cifs/smb2inode.c
index 97cd4df..e118188 100644
--- a/kernel/fs/cifs/smb2inode.c
+++ b/kernel/fs/cifs/smb2inode.c
@@ -236,15 +236,32 @@
 		size[0] = 8; /* sizeof __le64 */
 		data[0] = ptr;
 
-		rc = SMB2_set_info_init(tcon, server,
-					&rqst[num_rqst], COMPOUND_FID,
-					COMPOUND_FID, current->tgid,
-					FILE_END_OF_FILE_INFORMATION,
-					SMB2_O_INFO_FILE, 0, data, size);
+		if (cfile) {
+			rc = SMB2_set_info_init(tcon, server,
+						&rqst[num_rqst],
+						cfile->fid.persistent_fid,
+						cfile->fid.volatile_fid,
+						current->tgid,
+						FILE_END_OF_FILE_INFORMATION,
+						SMB2_O_INFO_FILE, 0,
+						data, size);
+		} else {
+			rc = SMB2_set_info_init(tcon, server,
+						&rqst[num_rqst],
+						COMPOUND_FID,
+						COMPOUND_FID,
+						current->tgid,
+						FILE_END_OF_FILE_INFORMATION,
+						SMB2_O_INFO_FILE, 0,
+						data, size);
+			if (!rc) {
+				smb2_set_next_command(tcon, &rqst[num_rqst]);
+				smb2_set_related(&rqst[num_rqst]);
+			}
+		}
 		if (rc)
 			goto finished;
-		smb2_set_next_command(tcon, &rqst[num_rqst]);
-		smb2_set_related(&rqst[num_rqst++]);
+		num_rqst++;
 		trace_smb3_set_eof_enter(xid, ses->Suid, tcon->tid, full_path);
 		break;
 	case SMB2_OP_SET_INFO:
diff --git a/kernel/fs/cifs/smb2ops.c b/kernel/fs/cifs/smb2ops.c
index 72368b6..015b7b3 100644
--- a/kernel/fs/cifs/smb2ops.c
+++ b/kernel/fs/cifs/smb2ops.c
@@ -593,7 +593,7 @@
 	if (rc == -EOPNOTSUPP) {
 		cifs_dbg(FYI,
 			 "server does not support query network interfaces\n");
-		goto out;
+		ret_data_len = 0;
 	} else if (rc != 0) {
 		cifs_tcon_dbg(VFS, "error %d on ioctl to get interface list\n", rc);
 		goto out;
@@ -859,12 +859,13 @@
 	bool no_cached_open = tcon->nohandlecache;
 	struct cached_fid *cfid = NULL;
 
-	oparms.tcon = tcon;
-	oparms.desired_access = FILE_READ_ATTRIBUTES;
-	oparms.disposition = FILE_OPEN;
-	oparms.create_options = cifs_create_options(cifs_sb, 0);
-	oparms.fid = &fid;
-	oparms.reconnect = false;
+	oparms = (struct cifs_open_parms) {
+		.tcon = tcon,
+		.desired_access = FILE_READ_ATTRIBUTES,
+		.disposition = FILE_OPEN,
+		.create_options = cifs_create_options(cifs_sb, 0),
+		.fid = &fid,
+	};
 
 	if (no_cached_open) {
 		rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
@@ -1783,7 +1784,7 @@
 		pcchunk->SourceOffset = cpu_to_le64(src_off);
 		pcchunk->TargetOffset = cpu_to_le64(dest_off);
 		pcchunk->Length =
-			cpu_to_le32(min_t(u32, len, tcon->max_bytes_chunk));
+			cpu_to_le32(min_t(u64, len, tcon->max_bytes_chunk));
 
 		/* Request server copy to target from src identified by key */
 		kfree(retbuf);
@@ -4164,69 +4165,82 @@
 	memcpy(&tr_hdr->SessionId, &shdr->SessionId, 8);
 }
 
-/* We can not use the normal sg_set_buf() as we will sometimes pass a
- * stack object as buf.
- */
-static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
-				   unsigned int buflen)
+static void *smb2_aead_req_alloc(struct crypto_aead *tfm, const struct smb_rqst *rqst,
+				 int num_rqst, const u8 *sig, u8 **iv,
+				 struct aead_request **req, struct scatterlist **sgl,
+				 unsigned int *num_sgs)
 {
-	void *addr;
-	/*
-	 * VMAP_STACK (at least) puts stack into the vmalloc address space
-	 */
-	if (is_vmalloc_addr(buf))
-		addr = vmalloc_to_page(buf);
-	else
-		addr = virt_to_page(buf);
-	sg_set_page(sg, addr, buflen, offset_in_page(buf));
-}
+	unsigned int req_size = sizeof(**req) + crypto_aead_reqsize(tfm);
+	unsigned int iv_size = crypto_aead_ivsize(tfm);
+	unsigned int len;
+	u8 *p;
 
-/* Assumes the first rqst has a transform header as the first iov.
- * I.e.
- * rqst[0].rq_iov[0]  is transform header
- * rqst[0].rq_iov[1+] data to be encrypted/decrypted
- * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
- */
-static struct scatterlist *
-init_sg(int num_rqst, struct smb_rqst *rqst, u8 *sign)
-{
-	unsigned int sg_len;
-	struct scatterlist *sg;
-	unsigned int i;
-	unsigned int j;
-	unsigned int idx = 0;
-	int skip;
+	*num_sgs = cifs_get_num_sgs(rqst, num_rqst, sig);
 
-	sg_len = 1;
-	for (i = 0; i < num_rqst; i++)
-		sg_len += rqst[i].rq_nvec + rqst[i].rq_npages;
+	len = iv_size;
+	len += crypto_aead_alignmask(tfm) & ~(crypto_tfm_ctx_alignment() - 1);
+	len = ALIGN(len, crypto_tfm_ctx_alignment());
+	len += req_size;
+	len = ALIGN(len, __alignof__(struct scatterlist));
+	len += *num_sgs * sizeof(**sgl);
 
-	sg = kmalloc_array(sg_len, sizeof(struct scatterlist), GFP_KERNEL);
-	if (!sg)
+	p = kmalloc(len, GFP_ATOMIC);
+	if (!p)
 		return NULL;
 
-	sg_init_table(sg, sg_len);
+	*iv = (u8 *)PTR_ALIGN(p, crypto_aead_alignmask(tfm) + 1);
+	*req = (struct aead_request *)PTR_ALIGN(*iv + iv_size,
+						crypto_tfm_ctx_alignment());
+	*sgl = (struct scatterlist *)PTR_ALIGN((u8 *)*req + req_size,
+					       __alignof__(struct scatterlist));
+	return p;
+}
+
+static void *smb2_get_aead_req(struct crypto_aead *tfm, const struct smb_rqst *rqst,
+			       int num_rqst, const u8 *sig, u8 **iv,
+			       struct aead_request **req, struct scatterlist **sgl)
+{
+	unsigned int off, len, skip;
+	struct scatterlist *sg;
+	unsigned int num_sgs;
+	unsigned long addr;
+	int i, j;
+	void *p;
+
+	p = smb2_aead_req_alloc(tfm, rqst, num_rqst, sig, iv, req, sgl, &num_sgs);
+	if (!p)
+		return NULL;
+
+	sg_init_table(*sgl, num_sgs);
+	sg = *sgl;
+
+	/* Assumes the first rqst has a transform header as the first iov.
+	 * I.e.
+	 * rqst[0].rq_iov[0]  is transform header
+	 * rqst[0].rq_iov[1+] data to be encrypted/decrypted
+	 * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
+	 */
 	for (i = 0; i < num_rqst; i++) {
+		/*
+		 * The first rqst has a transform header where the
+		 * first 20 bytes are not part of the encrypted blob.
+		 */
 		for (j = 0; j < rqst[i].rq_nvec; j++) {
-			/*
-			 * The first rqst has a transform header where the
-			 * first 20 bytes are not part of the encrypted blob
-			 */
+			struct kvec *iov = &rqst[i].rq_iov[j];
+
 			skip = (i == 0) && (j == 0) ? 20 : 0;
-			smb2_sg_set_buf(&sg[idx++],
-					rqst[i].rq_iov[j].iov_base + skip,
-					rqst[i].rq_iov[j].iov_len - skip);
-			}
-
+			addr = (unsigned long)iov->iov_base + skip;
+			len = iov->iov_len - skip;
+			sg = cifs_sg_set_buf(sg, (void *)addr, len);
+		}
 		for (j = 0; j < rqst[i].rq_npages; j++) {
-			unsigned int len, offset;
-
-			rqst_page_get_length(&rqst[i], j, &len, &offset);
-			sg_set_page(&sg[idx++], rqst[i].rq_pages[j], len, offset);
+			rqst_page_get_length(&rqst[i], j, &len, &off);
+			sg_set_page(sg++, rqst[i].rq_pages[j], len, off);
 		}
 	}
-	smb2_sg_set_buf(&sg[idx], sign, SMB2_SIGNATURE_SIZE);
-	return sg;
+	cifs_sg_set_buf(sg, sig, SMB2_SIGNATURE_SIZE);
+
+	return p;
 }
 
 static int
@@ -4270,11 +4284,11 @@
 	u8 sign[SMB2_SIGNATURE_SIZE] = {};
 	u8 key[SMB3_ENC_DEC_KEY_SIZE];
 	struct aead_request *req;
-	char *iv;
-	unsigned int iv_len;
+	u8 *iv;
 	DECLARE_CRYPTO_WAIT(wait);
 	struct crypto_aead *tfm;
 	unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
+	void *creq;
 
 	rc = smb2_get_enc_key(server, tr_hdr->SessionId, enc, key);
 	if (rc) {
@@ -4309,30 +4323,13 @@
 		return rc;
 	}
 
-	req = aead_request_alloc(tfm, GFP_KERNEL);
-	if (!req) {
-		cifs_server_dbg(VFS, "%s: Failed to alloc aead request\n", __func__);
+	creq = smb2_get_aead_req(tfm, rqst, num_rqst, sign, &iv, &req, &sg);
+	if (unlikely(!creq))
 		return -ENOMEM;
-	}
 
 	if (!enc) {
 		memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
 		crypt_len += SMB2_SIGNATURE_SIZE;
-	}
-
-	sg = init_sg(num_rqst, rqst, sign);
-	if (!sg) {
-		cifs_server_dbg(VFS, "%s: Failed to init sg\n", __func__);
-		rc = -ENOMEM;
-		goto free_req;
-	}
-
-	iv_len = crypto_aead_ivsize(tfm);
-	iv = kzalloc(iv_len, GFP_KERNEL);
-	if (!iv) {
-		cifs_server_dbg(VFS, "%s: Failed to alloc iv\n", __func__);
-		rc = -ENOMEM;
-		goto free_sg;
 	}
 
 	if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
@@ -4343,6 +4340,7 @@
 		memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
 	}
 
+	aead_request_set_tfm(req, tfm);
 	aead_request_set_crypt(req, sg, sg, crypt_len, iv);
 	aead_request_set_ad(req, assoc_data_len);
 
@@ -4355,11 +4353,7 @@
 	if (!rc && enc)
 		memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
 
-	kfree(iv);
-free_sg:
-	kfree(sg);
-free_req:
-	kfree(req);
+	kfree_sensitive(creq);
 	return rc;
 }
 
diff --git a/kernel/fs/cifs/smb2pdu.c b/kernel/fs/cifs/smb2pdu.c
index 0c4a247..9a80047 100644
--- a/kernel/fs/cifs/smb2pdu.c
+++ b/kernel/fs/cifs/smb2pdu.c
@@ -3925,12 +3925,15 @@
 				(struct smb2_sync_hdr *)rdata->iov[0].iov_base;
 	struct cifs_credits credits = { .value = 0, .instance = 0 };
 	struct smb_rqst rqst = { .rq_iov = &rdata->iov[1],
-				 .rq_nvec = 1,
-				 .rq_pages = rdata->pages,
-				 .rq_offset = rdata->page_offset,
-				 .rq_npages = rdata->nr_pages,
-				 .rq_pagesz = rdata->pagesz,
-				 .rq_tailsz = rdata->tailsz };
+				 .rq_nvec = 1, };
+
+	if (rdata->got_bytes) {
+		rqst.rq_pages = rdata->pages;
+		rqst.rq_offset = rdata->page_offset;
+		rqst.rq_npages = rdata->nr_pages;
+		rqst.rq_pagesz = rdata->pagesz;
+		rqst.rq_tailsz = rdata->tailsz;
+	}
 
 	WARN_ONCE(rdata->server != mid->server,
 		  "rdata server %p != mid server %p",
diff --git a/kernel/fs/cifs/smbdirect.c b/kernel/fs/cifs/smbdirect.c
index b029ed3..bcc6110 100644
--- a/kernel/fs/cifs/smbdirect.c
+++ b/kernel/fs/cifs/smbdirect.c
@@ -1394,6 +1394,7 @@
 	destroy_workqueue(info->workqueue);
 	log_rdma_event(INFO,  "rdma session destroyed\n");
 	kfree(info);
+	server->smbd_conn = NULL;
 }
 
 /*
@@ -1690,6 +1691,7 @@
 
 allocate_mr_failed:
 	/* At this point, need to a full transport shutdown */
+	server->smbd_conn = info;
 	smbd_destroy(server);
 	return NULL;
 
@@ -2238,6 +2240,7 @@
 	atomic_set(&info->mr_ready_count, 0);
 	atomic_set(&info->mr_used_count, 0);
 	init_waitqueue_head(&info->wait_for_mr_cleanup);
+	INIT_WORK(&info->mr_recovery_work, smbd_mr_recovery_work);
 	/* Allocate more MRs (2x) than hardware responder_resources */
 	for (i = 0; i < info->responder_resources * 2; i++) {
 		smbdirect_mr = kzalloc(sizeof(*smbdirect_mr), GFP_KERNEL);
@@ -2265,13 +2268,13 @@
 		list_add_tail(&smbdirect_mr->list, &info->mr_list);
 		atomic_inc(&info->mr_ready_count);
 	}
-	INIT_WORK(&info->mr_recovery_work, smbd_mr_recovery_work);
 	return 0;
 
 out:
 	kfree(smbdirect_mr);
 
 	list_for_each_entry_safe(smbdirect_mr, tmp, &info->mr_list, list) {
+		list_del(&smbdirect_mr->list);
 		ib_dereg_mr(smbdirect_mr->mr);
 		kfree(smbdirect_mr->sgl);
 		kfree(smbdirect_mr);
diff --git a/kernel/fs/cifs/transport.c b/kernel/fs/cifs/transport.c
index b137006..4409f56 100644
--- a/kernel/fs/cifs/transport.c
+++ b/kernel/fs/cifs/transport.c
@@ -312,7 +312,7 @@
 __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
 		struct smb_rqst *rqst)
 {
-	int rc = 0;
+	int rc;
 	struct kvec *iov;
 	int n_vec;
 	unsigned int send_length = 0;
@@ -323,6 +323,7 @@
 	struct msghdr smb_msg = {};
 	__be32 rfc1002_marker;
 
+	cifs_in_send_inc(server);
 	if (cifs_rdma_enabled(server)) {
 		/* return -EAGAIN when connecting or reconnecting */
 		rc = -EAGAIN;
@@ -331,14 +332,17 @@
 		goto smbd_done;
 	}
 
+	rc = -EAGAIN;
 	if (ssocket == NULL)
-		return -EAGAIN;
+		goto out;
 
+	rc = -ERESTARTSYS;
 	if (fatal_signal_pending(current)) {
 		cifs_dbg(FYI, "signal pending before send request\n");
-		return -ERESTARTSYS;
+		goto out;
 	}
 
+	rc = 0;
 	/* cork the socket */
 	tcp_sock_set_cork(ssocket->sk, true);
 
@@ -449,7 +453,8 @@
 			 rc);
 	else if (rc > 0)
 		rc = 0;
-
+out:
+	cifs_in_send_dec(server);
 	return rc;
 }
 
@@ -826,9 +831,7 @@
 	 * I/O response may come back and free the mid entry on another thread.
 	 */
 	cifs_save_when_sent(mid);
-	cifs_in_send_inc(server);
 	rc = smb_send_rqst(server, 1, rqst, flags);
-	cifs_in_send_dec(server);
 
 	if (rc < 0) {
 		revert_current_mid(server, mid->credits);
@@ -1117,9 +1120,7 @@
 		else
 			midQ[i]->callback = cifs_compound_last_callback;
 	}
-	cifs_in_send_inc(server);
 	rc = smb_send_rqst(server, num_rqst, rqst, flags);
-	cifs_in_send_dec(server);
 
 	for (i = 0; i < num_rqst; i++)
 		cifs_save_when_sent(midQ[i]);
@@ -1356,9 +1357,7 @@
 
 	midQ->mid_state = MID_REQUEST_SUBMITTED;
 
-	cifs_in_send_inc(server);
 	rc = smb_send(server, in_buf, len);
-	cifs_in_send_dec(server);
 	cifs_save_when_sent(midQ);
 
 	if (rc < 0)
@@ -1495,9 +1494,7 @@
 	}
 
 	midQ->mid_state = MID_REQUEST_SUBMITTED;
-	cifs_in_send_inc(server);
 	rc = smb_send(server, in_buf, len);
-	cifs_in_send_dec(server);
 	cifs_save_when_sent(midQ);
 
 	if (rc < 0)
diff --git a/kernel/fs/coda/upcall.c b/kernel/fs/coda/upcall.c
index eb3b189..610484c 100644
--- a/kernel/fs/coda/upcall.c
+++ b/kernel/fs/coda/upcall.c
@@ -790,7 +790,7 @@
 	sig_req = kmalloc(sizeof(struct upc_req), GFP_KERNEL);
 	if (!sig_req) goto exit;
 
-	sig_inputArgs = kvzalloc(sizeof(struct coda_in_hdr), GFP_KERNEL);
+	sig_inputArgs = kvzalloc(sizeof(*sig_inputArgs), GFP_KERNEL);
 	if (!sig_inputArgs) {
 		kfree(sig_req);
 		goto exit;
diff --git a/kernel/fs/configfs/dir.c b/kernel/fs/configfs/dir.c
index 86bbd25..101185d 100644
--- a/kernel/fs/configfs/dir.c
+++ b/kernel/fs/configfs/dir.c
@@ -317,6 +317,7 @@
 	return 0;
 
 out_remove:
+	configfs_put(dentry->d_fsdata);
 	configfs_remove_dirent(dentry);
 	return PTR_ERR(inode);
 }
@@ -383,6 +384,7 @@
 	return 0;
 
 out_remove:
+	configfs_put(dentry->d_fsdata);
 	configfs_remove_dirent(dentry);
 	return PTR_ERR(inode);
 }
diff --git a/kernel/fs/debugfs/file.c b/kernel/fs/debugfs/file.c
index 96059af..42bab92 100644
--- a/kernel/fs/debugfs/file.c
+++ b/kernel/fs/debugfs/file.c
@@ -378,8 +378,8 @@
 }
 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,11 +387,27 @@
 	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,
@@ -748,11 +764,11 @@
 	*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/kernel/fs/dlm/lock.c b/kernel/fs/dlm/lock.c
index dde9afb..51ab063 100644
--- a/kernel/fs/dlm/lock.c
+++ b/kernel/fs/dlm/lock.c
@@ -1856,7 +1856,7 @@
 void dlm_scan_timeout(struct dlm_ls *ls)
 {
 	struct dlm_rsb *r;
-	struct dlm_lkb *lkb;
+	struct dlm_lkb *lkb = NULL, *iter;
 	int do_cancel, do_warn;
 	s64 wait_us;
 
@@ -1867,27 +1867,28 @@
 		do_cancel = 0;
 		do_warn = 0;
 		mutex_lock(&ls->ls_timeout_mutex);
-		list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list) {
+		list_for_each_entry(iter, &ls->ls_timeout, lkb_time_list) {
 
 			wait_us = ktime_to_us(ktime_sub(ktime_get(),
-					      		lkb->lkb_timestamp));
+							iter->lkb_timestamp));
 
-			if ((lkb->lkb_exflags & DLM_LKF_TIMEOUT) &&
-			    wait_us >= (lkb->lkb_timeout_cs * 10000))
+			if ((iter->lkb_exflags & DLM_LKF_TIMEOUT) &&
+			    wait_us >= (iter->lkb_timeout_cs * 10000))
 				do_cancel = 1;
 
-			if ((lkb->lkb_flags & DLM_IFL_WATCH_TIMEWARN) &&
+			if ((iter->lkb_flags & DLM_IFL_WATCH_TIMEWARN) &&
 			    wait_us >= dlm_config.ci_timewarn_cs * 10000)
 				do_warn = 1;
 
 			if (!do_cancel && !do_warn)
 				continue;
-			hold_lkb(lkb);
+			hold_lkb(iter);
+			lkb = iter;
 			break;
 		}
 		mutex_unlock(&ls->ls_timeout_mutex);
 
-		if (!do_cancel && !do_warn)
+		if (!lkb)
 			break;
 
 		r = lkb->lkb_resource;
@@ -5241,21 +5242,18 @@
 
 static struct dlm_lkb *find_resend_waiter(struct dlm_ls *ls)
 {
-	struct dlm_lkb *lkb;
-	int found = 0;
+	struct dlm_lkb *lkb = NULL, *iter;
 
 	mutex_lock(&ls->ls_waiters_mutex);
-	list_for_each_entry(lkb, &ls->ls_waiters, lkb_wait_reply) {
-		if (lkb->lkb_flags & DLM_IFL_RESEND) {
-			hold_lkb(lkb);
-			found = 1;
+	list_for_each_entry(iter, &ls->ls_waiters, lkb_wait_reply) {
+		if (iter->lkb_flags & DLM_IFL_RESEND) {
+			hold_lkb(iter);
+			lkb = iter;
 			break;
 		}
 	}
 	mutex_unlock(&ls->ls_waiters_mutex);
 
-	if (!found)
-		lkb = NULL;
 	return lkb;
 }
 
@@ -5914,37 +5912,36 @@
 		     int mode, uint32_t flags, void *name, unsigned int namelen,
 		     unsigned long timeout_cs, uint32_t *lkid)
 {
-	struct dlm_lkb *lkb;
+	struct dlm_lkb *lkb = NULL, *iter;
 	struct dlm_user_args *ua;
 	int found_other_mode = 0;
-	int found = 0;
 	int rv = 0;
 
 	mutex_lock(&ls->ls_orphans_mutex);
-	list_for_each_entry(lkb, &ls->ls_orphans, lkb_ownqueue) {
-		if (lkb->lkb_resource->res_length != namelen)
+	list_for_each_entry(iter, &ls->ls_orphans, lkb_ownqueue) {
+		if (iter->lkb_resource->res_length != namelen)
 			continue;
-		if (memcmp(lkb->lkb_resource->res_name, name, namelen))
+		if (memcmp(iter->lkb_resource->res_name, name, namelen))
 			continue;
-		if (lkb->lkb_grmode != mode) {
+		if (iter->lkb_grmode != mode) {
 			found_other_mode = 1;
 			continue;
 		}
 
-		found = 1;
-		list_del_init(&lkb->lkb_ownqueue);
-		lkb->lkb_flags &= ~DLM_IFL_ORPHAN;
-		*lkid = lkb->lkb_id;
+		lkb = iter;
+		list_del_init(&iter->lkb_ownqueue);
+		iter->lkb_flags &= ~DLM_IFL_ORPHAN;
+		*lkid = iter->lkb_id;
 		break;
 	}
 	mutex_unlock(&ls->ls_orphans_mutex);
 
-	if (!found && found_other_mode) {
+	if (!lkb && found_other_mode) {
 		rv = -EAGAIN;
 		goto out;
 	}
 
-	if (!found) {
+	if (!lkb) {
 		rv = -ENOENT;
 		goto out;
 	}
diff --git a/kernel/fs/dlm/plock.c b/kernel/fs/dlm/plock.c
index a10d2bc..5f2e2fa 100644
--- a/kernel/fs/dlm/plock.c
+++ b/kernel/fs/dlm/plock.c
@@ -19,20 +19,20 @@
 static wait_queue_head_t send_wq;
 static wait_queue_head_t recv_wq;
 
+struct plock_async_data {
+	void *fl;
+	void *file;
+	struct file_lock flc;
+	int (*callback)(struct file_lock *fl, int result);
+};
+
 struct plock_op {
 	struct list_head list;
 	int done;
 	struct dlm_plock_info info;
-	int (*callback)(struct file_lock *fl, int result);
+	/* if set indicates async handling */
+	struct plock_async_data *data;
 };
-
-struct plock_xop {
-	struct plock_op xop;
-	void *fl;
-	void *file;
-	struct file_lock flc;
-};
-
 
 static inline void set_version(struct dlm_plock_info *info)
 {
@@ -58,6 +58,12 @@
 	return 0;
 }
 
+static void dlm_release_plock_op(struct plock_op *op)
+{
+	kfree(op->data);
+	kfree(op);
+}
+
 static void send_op(struct plock_op *op)
 {
 	set_version(&op->info);
@@ -74,8 +80,7 @@
    abandoned waiter.  So, we have to insert the unlock-close when the
    lock call is interrupted. */
 
-static void do_unlock_close(struct dlm_ls *ls, u64 number,
-			    struct file *file, struct file_lock *fl)
+static void do_unlock_close(const struct dlm_plock_info *info)
 {
 	struct plock_op *op;
 
@@ -84,15 +89,12 @@
 		return;
 
 	op->info.optype		= DLM_PLOCK_OP_UNLOCK;
-	op->info.pid		= fl->fl_pid;
-	op->info.fsid		= ls->ls_global_id;
-	op->info.number		= number;
+	op->info.pid		= info->pid;
+	op->info.fsid		= info->fsid;
+	op->info.number		= info->number;
 	op->info.start		= 0;
 	op->info.end		= OFFSET_MAX;
-	if (fl->fl_lmops && fl->fl_lmops->lm_grant)
-		op->info.owner	= (__u64) fl->fl_pid;
-	else
-		op->info.owner	= (__u64)(long) fl->fl_owner;
+	op->info.owner		= info->owner;
 
 	op->info.flags |= DLM_PLOCK_FL_CLOSE;
 	send_op(op);
@@ -101,22 +103,21 @@
 int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
 		   int cmd, struct file_lock *fl)
 {
+	struct plock_async_data *op_data;
 	struct dlm_ls *ls;
 	struct plock_op *op;
-	struct plock_xop *xop;
 	int rv;
 
 	ls = dlm_find_lockspace_local(lockspace);
 	if (!ls)
 		return -EINVAL;
 
-	xop = kzalloc(sizeof(*xop), GFP_NOFS);
-	if (!xop) {
+	op = kzalloc(sizeof(*op), GFP_NOFS);
+	if (!op) {
 		rv = -ENOMEM;
 		goto out;
 	}
 
-	op = &xop->xop;
 	op->info.optype		= DLM_PLOCK_OP_LOCK;
 	op->info.pid		= fl->fl_pid;
 	op->info.ex		= (fl->fl_type == F_WRLCK);
@@ -125,35 +126,45 @@
 	op->info.number		= number;
 	op->info.start		= fl->fl_start;
 	op->info.end		= fl->fl_end;
+	/* async handling */
 	if (fl->fl_lmops && fl->fl_lmops->lm_grant) {
+		op_data = kzalloc(sizeof(*op_data), GFP_NOFS);
+		if (!op_data) {
+			dlm_release_plock_op(op);
+			rv = -ENOMEM;
+			goto out;
+		}
+
 		/* fl_owner is lockd which doesn't distinguish
 		   processes on the nfs client */
 		op->info.owner	= (__u64) fl->fl_pid;
-		op->callback	= fl->fl_lmops->lm_grant;
-		locks_init_lock(&xop->flc);
-		locks_copy_lock(&xop->flc, fl);
-		xop->fl		= fl;
-		xop->file	= file;
+		op_data->callback = fl->fl_lmops->lm_grant;
+		locks_init_lock(&op_data->flc);
+		locks_copy_lock(&op_data->flc, fl);
+		op_data->fl		= fl;
+		op_data->file	= file;
+
+		op->data = op_data;
+
+		send_op(op);
+		rv = FILE_LOCK_DEFERRED;
+		goto out;
 	} else {
 		op->info.owner	= (__u64)(long) fl->fl_owner;
 	}
 
 	send_op(op);
 
-	if (!op->callback) {
-		rv = wait_event_interruptible(recv_wq, (op->done != 0));
-		if (rv == -ERESTARTSYS) {
-			log_debug(ls, "dlm_posix_lock: wait killed %llx",
-				  (unsigned long long)number);
-			spin_lock(&ops_lock);
-			list_del(&op->list);
-			spin_unlock(&ops_lock);
-			kfree(xop);
-			do_unlock_close(ls, number, file, fl);
-			goto out;
-		}
-	} else {
-		rv = FILE_LOCK_DEFERRED;
+	rv = wait_event_killable(recv_wq, (op->done != 0));
+	if (rv == -ERESTARTSYS) {
+		spin_lock(&ops_lock);
+		list_del(&op->list);
+		spin_unlock(&ops_lock);
+		log_debug(ls, "%s: wait interrupted %x %llx pid %d",
+			  __func__, ls->ls_global_id,
+			  (unsigned long long)number, op->info.pid);
+		dlm_release_plock_op(op);
+		do_unlock_close(&op->info);
 		goto out;
 	}
 
@@ -173,7 +184,7 @@
 				  (unsigned long long)number);
 	}
 
-	kfree(xop);
+	dlm_release_plock_op(op);
 out:
 	dlm_put_lockspace(ls);
 	return rv;
@@ -183,11 +194,11 @@
 /* Returns failure iff a successful lock operation should be canceled */
 static int dlm_plock_callback(struct plock_op *op)
 {
+	struct plock_async_data *op_data = op->data;
 	struct file *file;
 	struct file_lock *fl;
 	struct file_lock *flc;
 	int (*notify)(struct file_lock *fl, int result) = NULL;
-	struct plock_xop *xop = (struct plock_xop *)op;
 	int rv = 0;
 
 	spin_lock(&ops_lock);
@@ -199,10 +210,10 @@
 	spin_unlock(&ops_lock);
 
 	/* check if the following 2 are still valid or make a copy */
-	file = xop->file;
-	flc = &xop->flc;
-	fl = xop->fl;
-	notify = op->callback;
+	file = op_data->file;
+	flc = &op_data->flc;
+	fl = op_data->fl;
+	notify = op_data->callback;
 
 	if (op->info.rv) {
 		notify(fl, op->info.rv);
@@ -233,7 +244,7 @@
 	}
 
 out:
-	kfree(xop);
+	dlm_release_plock_op(op);
 	return rv;
 }
 
@@ -303,7 +314,7 @@
 		rv = 0;
 
 out_free:
-	kfree(op);
+	dlm_release_plock_op(op);
 out:
 	dlm_put_lockspace(ls);
 	fl->fl_flags = fl_flags;
@@ -363,13 +374,15 @@
 		locks_init_lock(fl);
 		fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK;
 		fl->fl_flags = FL_POSIX;
-		fl->fl_pid = -op->info.pid;
+		fl->fl_pid = op->info.pid;
+		if (op->info.nodeid != dlm_our_nodeid())
+			fl->fl_pid = -fl->fl_pid;
 		fl->fl_start = op->info.start;
 		fl->fl_end = op->info.end;
 		rv = 0;
 	}
 
-	kfree(op);
+	dlm_release_plock_op(op);
 out:
 	dlm_put_lockspace(ls);
 	return rv;
@@ -392,7 +405,7 @@
 		if (op->info.flags & DLM_PLOCK_FL_CLOSE)
 			list_del(&op->list);
 		else
-			list_move(&op->list, &recv_list);
+			list_move_tail(&op->list, &recv_list);
 		memcpy(&info, &op->info, sizeof(info));
 	}
 	spin_unlock(&ops_lock);
@@ -405,7 +418,7 @@
 	   (the process did not make an unlock call). */
 
 	if (op->info.flags & DLM_PLOCK_FL_CLOSE)
-		kfree(op);
+		dlm_release_plock_op(op);
 
 	if (copy_to_user(u, &info, sizeof(info)))
 		return -EFAULT;
@@ -417,9 +430,9 @@
 static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
 			 loff_t *ppos)
 {
+	struct plock_op *op = NULL, *iter;
 	struct dlm_plock_info info;
-	struct plock_op *op;
-	int found = 0, do_callback = 0;
+	int do_callback = 0;
 
 	if (count != sizeof(info))
 		return -EINVAL;
@@ -430,31 +443,63 @@
 	if (check_version(&info))
 		return -EINVAL;
 
+	/*
+	 * The results for waiting ops (SETLKW) can be returned in any
+	 * order, so match all fields to find the op.  The results for
+	 * non-waiting ops are returned in the order that they were sent
+	 * to userspace, so match the result with the first non-waiting op.
+	 */
 	spin_lock(&ops_lock);
-	list_for_each_entry(op, &recv_list, list) {
-		if (op->info.fsid == info.fsid &&
-		    op->info.number == info.number &&
-		    op->info.owner == info.owner) {
-			list_del_init(&op->list);
-			memcpy(&op->info, &info, sizeof(info));
-			if (op->callback)
-				do_callback = 1;
-			else
-				op->done = 1;
-			found = 1;
-			break;
+	if (info.wait) {
+		list_for_each_entry(iter, &recv_list, list) {
+			if (iter->info.fsid == info.fsid &&
+			    iter->info.number == info.number &&
+			    iter->info.owner == info.owner &&
+			    iter->info.pid == info.pid &&
+			    iter->info.start == info.start &&
+			    iter->info.end == info.end &&
+			    iter->info.ex == info.ex &&
+			    iter->info.wait) {
+				op = iter;
+				break;
+			}
 		}
+	} else {
+		list_for_each_entry(iter, &recv_list, list) {
+			if (!iter->info.wait &&
+			    iter->info.fsid == info.fsid) {
+				op = iter;
+				break;
+			}
+		}
+	}
+
+	if (op) {
+		/* Sanity check that op and info match. */
+		if (info.wait)
+			WARN_ON(op->info.optype != DLM_PLOCK_OP_LOCK);
+		else
+			WARN_ON(op->info.number != info.number ||
+				op->info.owner != info.owner ||
+				op->info.optype != info.optype);
+
+		list_del_init(&op->list);
+		memcpy(&op->info, &info, sizeof(info));
+		if (op->data)
+			do_callback = 1;
+		else
+			op->done = 1;
 	}
 	spin_unlock(&ops_lock);
 
-	if (found) {
+	if (op) {
 		if (do_callback)
 			dlm_plock_callback(op);
 		else
 			wake_up(&recv_wq);
 	} else
-		log_print("dev_write no op %x %llx", info.fsid,
-			  (unsigned long long)info.number);
+		log_print("%s: no op %x %llx", __func__,
+			  info.fsid, (unsigned long long)info.number);
 	return count;
 }
 
diff --git a/kernel/fs/dlm/recover.c b/kernel/fs/dlm/recover.c
index 8928e99..df18f38 100644
--- a/kernel/fs/dlm/recover.c
+++ b/kernel/fs/dlm/recover.c
@@ -732,10 +732,9 @@
 
 static void recover_lvb(struct dlm_rsb *r)
 {
-	struct dlm_lkb *lkb, *high_lkb = NULL;
+	struct dlm_lkb *big_lkb = NULL, *iter, *high_lkb = NULL;
 	uint32_t high_seq = 0;
 	int lock_lvb_exists = 0;
-	int big_lock_exists = 0;
 	int lvblen = r->res_ls->ls_lvblen;
 
 	if (!rsb_flag(r, RSB_NEW_MASTER2) &&
@@ -751,37 +750,37 @@
 	/* we are the new master, so figure out if VALNOTVALID should
 	   be set, and set the rsb lvb from the best lkb available. */
 
-	list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) {
-		if (!(lkb->lkb_exflags & DLM_LKF_VALBLK))
+	list_for_each_entry(iter, &r->res_grantqueue, lkb_statequeue) {
+		if (!(iter->lkb_exflags & DLM_LKF_VALBLK))
 			continue;
 
 		lock_lvb_exists = 1;
 
-		if (lkb->lkb_grmode > DLM_LOCK_CR) {
-			big_lock_exists = 1;
+		if (iter->lkb_grmode > DLM_LOCK_CR) {
+			big_lkb = iter;
 			goto setflag;
 		}
 
-		if (((int)lkb->lkb_lvbseq - (int)high_seq) >= 0) {
-			high_lkb = lkb;
-			high_seq = lkb->lkb_lvbseq;
+		if (((int)iter->lkb_lvbseq - (int)high_seq) >= 0) {
+			high_lkb = iter;
+			high_seq = iter->lkb_lvbseq;
 		}
 	}
 
-	list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue) {
-		if (!(lkb->lkb_exflags & DLM_LKF_VALBLK))
+	list_for_each_entry(iter, &r->res_convertqueue, lkb_statequeue) {
+		if (!(iter->lkb_exflags & DLM_LKF_VALBLK))
 			continue;
 
 		lock_lvb_exists = 1;
 
-		if (lkb->lkb_grmode > DLM_LOCK_CR) {
-			big_lock_exists = 1;
+		if (iter->lkb_grmode > DLM_LOCK_CR) {
+			big_lkb = iter;
 			goto setflag;
 		}
 
-		if (((int)lkb->lkb_lvbseq - (int)high_seq) >= 0) {
-			high_lkb = lkb;
-			high_seq = lkb->lkb_lvbseq;
+		if (((int)iter->lkb_lvbseq - (int)high_seq) >= 0) {
+			high_lkb = iter;
+			high_seq = iter->lkb_lvbseq;
 		}
 	}
 
@@ -790,7 +789,7 @@
 		goto out;
 
 	/* lvb is invalidated if only NL/CR locks remain */
-	if (!big_lock_exists)
+	if (!big_lkb)
 		rsb_set_flag(r, RSB_VALNOTVALID);
 
 	if (!r->res_lvbptr) {
@@ -799,9 +798,9 @@
 			goto out;
 	}
 
-	if (big_lock_exists) {
-		r->res_lvbseq = lkb->lkb_lvbseq;
-		memcpy(r->res_lvbptr, lkb->lkb_lvbptr, lvblen);
+	if (big_lkb) {
+		r->res_lvbseq = big_lkb->lkb_lvbseq;
+		memcpy(r->res_lvbptr, big_lkb->lkb_lvbptr, lvblen);
 	} else if (high_lkb) {
 		r->res_lvbseq = high_lkb->lkb_lvbseq;
 		memcpy(r->res_lvbptr, high_lkb->lkb_lvbptr, lvblen);
diff --git a/kernel/fs/drop_caches.c b/kernel/fs/drop_caches.c
index f00fcc4..345f864 100644
--- a/kernel/fs/drop_caches.c
+++ b/kernel/fs/drop_caches.c
@@ -9,6 +9,7 @@
 #include <linux/writeback.h>
 #include <linux/sysctl.h>
 #include <linux/gfp.h>
+#include <linux/swap.h>
 #include "internal.h"
 
 /* A global variable is a bit ugly, but it keeps the code simple */
@@ -58,6 +59,7 @@
 		static int stfu;
 
 		if (sysctl_drop_caches & 1) {
+			lru_add_drain_all();
 			iterate_supers(drop_pagecache_sb, NULL);
 			count_vm_event(DROP_PAGECACHE);
 		}
diff --git a/kernel/fs/erofs/Kconfig b/kernel/fs/erofs/Kconfig
index d5ac472..8cf3af6 100644
--- a/kernel/fs/erofs/Kconfig
+++ b/kernel/fs/erofs/Kconfig
@@ -77,3 +77,20 @@
 
 	  If you don't want to enable compression feature, say N.
 
+config EROFS_FS_PCPU_KTHREAD
+	bool "EROFS per-cpu decompression kthread workers"
+	depends on EROFS_FS_ZIP
+	help
+	  Saying Y here enables per-CPU kthread workers pool to carry out
+	  async decompression for low latencies on some architectures.
+
+	  If unsure, say N.
+
+config EROFS_FS_PCPU_KTHREAD_HIPRI
+	bool "EROFS high priority per-CPU kthread workers"
+	depends on EROFS_FS_ZIP && EROFS_FS_PCPU_KTHREAD
+	help
+	  This permits EROFS to configure per-CPU kthread workers to run
+	  at higher priority.
+
+	  If unsure, say N.
diff --git a/kernel/fs/erofs/internal.h b/kernel/fs/erofs/internal.h
index 64e1e65..792dc67 100644
--- a/kernel/fs/erofs/internal.h
+++ b/kernel/fs/erofs/internal.h
@@ -254,7 +254,7 @@
 
 	unsigned char datalayout;
 	unsigned char inode_isize;
-	unsigned short xattr_isize;
+	unsigned int xattr_isize;
 
 	unsigned int xattr_shared_count;
 	unsigned int *xattr_shared_xattrs;
diff --git a/kernel/fs/erofs/zdata.c b/kernel/fs/erofs/zdata.c
index 7596db3..8a3f603 100644
--- a/kernel/fs/erofs/zdata.c
+++ b/kernel/fs/erofs/zdata.c
@@ -7,7 +7,7 @@
 #include "zdata.h"
 #include "compress.h"
 #include <linux/prefetch.h>
-
+#include <linux/cpuhotplug.h>
 #include <trace/events/erofs.h>
 
 /*
@@ -125,24 +125,128 @@
 
 static struct workqueue_struct *z_erofs_workqueue __read_mostly;
 
-void z_erofs_exit_zip_subsystem(void)
+#ifdef CONFIG_EROFS_FS_PCPU_KTHREAD
+static struct kthread_worker __rcu **z_erofs_pcpu_workers;
+
+static void erofs_destroy_percpu_workers(void)
 {
-	destroy_workqueue(z_erofs_workqueue);
-	z_erofs_destroy_pcluster_pool();
+	struct kthread_worker *worker;
+	unsigned int cpu;
+
+	for_each_possible_cpu(cpu) {
+		worker = rcu_dereference_protected(
+					z_erofs_pcpu_workers[cpu], 1);
+		rcu_assign_pointer(z_erofs_pcpu_workers[cpu], NULL);
+		if (worker)
+			kthread_destroy_worker(worker);
+	}
+	kfree(z_erofs_pcpu_workers);
 }
 
-static inline int z_erofs_init_workqueue(void)
+static struct kthread_worker *erofs_init_percpu_worker(int cpu)
 {
-	const unsigned int onlinecpus = num_possible_cpus();
+	struct kthread_worker *worker =
+		kthread_create_worker_on_cpu(cpu, 0, "erofs_worker/%u", cpu);
 
-	/*
-	 * no need to spawn too many threads, limiting threads could minimum
-	 * scheduling overhead, perhaps per-CPU threads should be better?
-	 */
-	z_erofs_workqueue = alloc_workqueue("erofs_unzipd",
-					    WQ_UNBOUND | WQ_HIGHPRI,
-					    onlinecpus + onlinecpus / 4);
-	return z_erofs_workqueue ? 0 : -ENOMEM;
+	if (IS_ERR(worker))
+		return worker;
+	if (IS_ENABLED(CONFIG_EROFS_FS_PCPU_KTHREAD_HIPRI))
+		sched_set_fifo_low(worker->task);
+	else
+		sched_set_normal(worker->task, 0);
+	return worker;
+}
+
+static int erofs_init_percpu_workers(void)
+{
+	struct kthread_worker *worker;
+	unsigned int cpu;
+
+	z_erofs_pcpu_workers = kcalloc(num_possible_cpus(),
+			sizeof(struct kthread_worker *), GFP_ATOMIC);
+	if (!z_erofs_pcpu_workers)
+		return -ENOMEM;
+
+	for_each_online_cpu(cpu) {	/* could miss cpu{off,on}line? */
+		worker = erofs_init_percpu_worker(cpu);
+		if (!IS_ERR(worker))
+			rcu_assign_pointer(z_erofs_pcpu_workers[cpu], worker);
+	}
+	return 0;
+}
+#else
+static inline void erofs_destroy_percpu_workers(void) {}
+static inline int erofs_init_percpu_workers(void) { return 0; }
+#endif
+
+#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_EROFS_FS_PCPU_KTHREAD)
+static DEFINE_SPINLOCK(z_erofs_pcpu_worker_lock);
+static enum cpuhp_state erofs_cpuhp_state;
+
+static int erofs_cpu_online(unsigned int cpu)
+{
+	struct kthread_worker *worker, *old;
+
+	worker = erofs_init_percpu_worker(cpu);
+	if (IS_ERR(worker))
+		return PTR_ERR(worker);
+
+	spin_lock(&z_erofs_pcpu_worker_lock);
+	old = rcu_dereference_protected(z_erofs_pcpu_workers[cpu],
+			lockdep_is_held(&z_erofs_pcpu_worker_lock));
+	if (!old)
+		rcu_assign_pointer(z_erofs_pcpu_workers[cpu], worker);
+	spin_unlock(&z_erofs_pcpu_worker_lock);
+	if (old)
+		kthread_destroy_worker(worker);
+	return 0;
+}
+
+static int erofs_cpu_offline(unsigned int cpu)
+{
+	struct kthread_worker *worker;
+
+	spin_lock(&z_erofs_pcpu_worker_lock);
+	worker = rcu_dereference_protected(z_erofs_pcpu_workers[cpu],
+			lockdep_is_held(&z_erofs_pcpu_worker_lock));
+	rcu_assign_pointer(z_erofs_pcpu_workers[cpu], NULL);
+	spin_unlock(&z_erofs_pcpu_worker_lock);
+
+	synchronize_rcu();
+	if (worker)
+		kthread_destroy_worker(worker);
+	return 0;
+}
+
+static int erofs_cpu_hotplug_init(void)
+{
+	int state;
+
+	state = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
+			"fs/erofs:online", erofs_cpu_online, erofs_cpu_offline);
+	if (state < 0)
+		return state;
+
+	erofs_cpuhp_state = state;
+	return 0;
+}
+
+static void erofs_cpu_hotplug_destroy(void)
+{
+	if (erofs_cpuhp_state)
+		cpuhp_remove_state_nocalls(erofs_cpuhp_state);
+}
+#else /* !CONFIG_HOTPLUG_CPU || !CONFIG_EROFS_FS_PCPU_KTHREAD */
+static inline int erofs_cpu_hotplug_init(void) { return 0; }
+static inline void erofs_cpu_hotplug_destroy(void) {}
+#endif
+
+void z_erofs_exit_zip_subsystem(void)
+{
+	erofs_cpu_hotplug_destroy();
+	erofs_destroy_percpu_workers();
+	destroy_workqueue(z_erofs_workqueue);
+	z_erofs_destroy_pcluster_pool();
 }
 
 int __init z_erofs_init_zip_subsystem(void)
@@ -150,10 +254,31 @@
 	int err = z_erofs_create_pcluster_pool();
 
 	if (err)
-		return err;
-	err = z_erofs_init_workqueue();
+		goto out_error_pcluster_pool;
+
+	z_erofs_workqueue = alloc_workqueue("erofs_worker",
+			WQ_UNBOUND | WQ_HIGHPRI, num_possible_cpus());
+	if (!z_erofs_workqueue) {
+		err = -ENOMEM;
+		goto out_error_workqueue_init;
+	}
+
+	err = erofs_init_percpu_workers();
 	if (err)
-		z_erofs_destroy_pcluster_pool();
+		goto out_error_pcpu_worker;
+
+	err = erofs_cpu_hotplug_init();
+	if (err < 0)
+		goto out_error_cpuhp_init;
+	return err;
+
+out_error_cpuhp_init:
+	erofs_destroy_percpu_workers();
+out_error_pcpu_worker:
+	destroy_workqueue(z_erofs_workqueue);
+out_error_workqueue_init:
+	z_erofs_destroy_pcluster_pool();
+out_error_pcluster_pool:
 	return err;
 }
 
@@ -719,9 +844,11 @@
 	tight &= (clt->mode >= COLLECT_PRIMARY_HOOKED &&
 		  clt->mode != COLLECT_PRIMARY_FOLLOWED_NOINPLACE);
 
-	cur = end - min_t(unsigned int, offset + end - map->m_la, end);
+	cur = end - min_t(erofs_off_t, offset + end - map->m_la, end);
 	if (!(map->m_flags & EROFS_MAP_MAPPED)) {
 		zero_user_segment(page, cur, end);
+		++spiltted;
+		tight = false;
 		goto next_part;
 	}
 
@@ -782,6 +909,12 @@
 }
 
 static void z_erofs_decompressqueue_work(struct work_struct *work);
+#ifdef CONFIG_EROFS_FS_PCPU_KTHREAD
+static void z_erofs_decompressqueue_kthread_work(struct kthread_work *work)
+{
+	z_erofs_decompressqueue_work((struct work_struct *)work);
+}
+#endif
 static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io,
 				       bool sync, int bios)
 {
@@ -799,7 +932,22 @@
 		return;
 	/* Use workqueue and sync decompression for atomic contexts only */
 	if (in_atomic() || irqs_disabled()) {
+#ifdef CONFIG_EROFS_FS_PCPU_KTHREAD
+		struct kthread_worker *worker;
+
+		rcu_read_lock();
+		worker = rcu_dereference(
+				z_erofs_pcpu_workers[raw_smp_processor_id()]);
+		if (!worker) {
+			INIT_WORK(&io->u.work, z_erofs_decompressqueue_work);
+			queue_work(z_erofs_workqueue, &io->u.work);
+		} else {
+			kthread_queue_work(worker, &io->u.kthread_work);
+		}
+		rcu_read_unlock();
+#else
 		queue_work(z_erofs_workqueue, &io->u.work);
+#endif
 		sbi->ctx.readahead_sync_decompress = true;
 		return;
 	}
@@ -1207,7 +1355,12 @@
 			*fg = true;
 			goto fg_out;
 		}
+#ifdef CONFIG_EROFS_FS_PCPU_KTHREAD
+		kthread_init_work(&q->u.kthread_work,
+				  z_erofs_decompressqueue_kthread_work);
+#else
 		INIT_WORK(&q->u.work, z_erofs_decompressqueue_work);
+#endif
 	} else {
 fg_out:
 		q = fgq;
@@ -1348,7 +1501,7 @@
 
 	/*
 	 * although background is preferred, no one is pending for submission.
-	 * don't issue workqueue for decompression but drop it directly instead.
+	 * don't issue decompression but drop it directly instead.
 	 */
 	if (!*force_fg && !nr_bios) {
 		kvfree(q[JQ_SUBMIT]);
diff --git a/kernel/fs/erofs/zdata.h b/kernel/fs/erofs/zdata.h
index 60bf396..f2118ce 100644
--- a/kernel/fs/erofs/zdata.h
+++ b/kernel/fs/erofs/zdata.h
@@ -7,6 +7,7 @@
 #ifndef __EROFS_FS_ZDATA_H
 #define __EROFS_FS_ZDATA_H
 
+#include <linux/kthread.h>
 #include "internal.h"
 #include "zpvec.h"
 
@@ -92,6 +93,7 @@
 	union {
 		struct completion done;
 		struct work_struct work;
+		struct kthread_work kthread_work;
 	} u;
 };
 
diff --git a/kernel/fs/erofs/zmap.c b/kernel/fs/erofs/zmap.c
index efaf325..adc4b4b 100644
--- a/kernel/fs/erofs/zmap.c
+++ b/kernel/fs/erofs/zmap.c
@@ -192,6 +192,10 @@
 	case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
 	case Z_EROFS_VLE_CLUSTER_TYPE_HEAD:
 		m->clusterofs = le16_to_cpu(di->di_clusterofs);
+		if (m->clusterofs >= 1 << vi->z_logical_clusterbits) {
+			DBG_BUGON(1);
+			return -EFSCORRUPTED;
+		}
 		m->pblk = le32_to_cpu(di->di_u.blkaddr);
 		break;
 	default:
@@ -225,7 +229,7 @@
 	u8 *in, type;
 	bool big_pcluster;
 
-	if (1 << amortizedshift == 4)
+	if (1 << amortizedshift == 4 && lclusterbits <= 14)
 		vcnt = 2;
 	else if (1 << amortizedshift == 2 && lclusterbits == 12)
 		vcnt = 16;
@@ -318,7 +322,6 @@
 {
 	struct inode *const inode = m->inode;
 	struct erofs_inode *const vi = EROFS_I(inode);
-	const unsigned int lclusterbits = vi->z_logical_clusterbits;
 	const erofs_off_t ebase = ALIGN(iloc(EROFS_I_SB(inode), vi->nid) +
 					vi->inode_isize + vi->xattr_isize, 8) +
 		sizeof(struct z_erofs_map_header);
@@ -327,9 +330,6 @@
 	unsigned int amortizedshift;
 	erofs_off_t pos;
 	int err;
-
-	if (lclusterbits != 12)
-		return -EOPNOTSUPP;
 
 	if (lcn >= totalidx)
 		return -EINVAL;
diff --git a/kernel/fs/eventfd.c b/kernel/fs/eventfd.c
index 4a14295..3673eb8 100644
--- a/kernel/fs/eventfd.c
+++ b/kernel/fs/eventfd.c
@@ -187,11 +187,14 @@
 	return events;
 }
 
-static void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt)
+void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt)
 {
-	*cnt = (ctx->flags & EFD_SEMAPHORE) ? 1 : ctx->count;
+	lockdep_assert_held(&ctx->wqh.lock);
+
+	*cnt = ((ctx->flags & EFD_SEMAPHORE) && ctx->count) ? 1 : ctx->count;
 	ctx->count -= *cnt;
 }
+EXPORT_SYMBOL_GPL(eventfd_ctx_do_read);
 
 /**
  * eventfd_ctx_remove_wait_queue - Read the current counter and removes wait queue.
diff --git a/kernel/fs/eventpoll.c b/kernel/fs/eventpoll.c
index 2c67c59..893047a 100644
--- a/kernel/fs/eventpoll.c
+++ b/kernel/fs/eventpoll.c
@@ -1825,7 +1825,11 @@
 {
 	int ret = default_wake_function(wq_entry, mode, sync, key);
 
-	list_del_init(&wq_entry->entry);
+	/*
+	 * Pairs with list_empty_careful in ep_poll, and ensures future loop
+	 * iterations see the cause of this wakeup.
+	 */
+	list_del_init_careful(&wq_entry->entry);
 	return ret;
 }
 
diff --git a/kernel/fs/exfat/balloc.c b/kernel/fs/exfat/balloc.c
index da2c94c..132943a 100644
--- a/kernel/fs/exfat/balloc.c
+++ b/kernel/fs/exfat/balloc.c
@@ -69,7 +69,7 @@
 	}
 	sbi->map_sectors = ((need_map_size - 1) >>
 			(sb->s_blocksize_bits)) + 1;
-	sbi->vol_amap = kmalloc_array(sbi->map_sectors,
+	sbi->vol_amap = kvmalloc_array(sbi->map_sectors,
 				sizeof(struct buffer_head *), GFP_KERNEL);
 	if (!sbi->vol_amap)
 		return -ENOMEM;
@@ -84,7 +84,7 @@
 			while (j < i)
 				brelse(sbi->vol_amap[j++]);
 
-			kfree(sbi->vol_amap);
+			kvfree(sbi->vol_amap);
 			sbi->vol_amap = NULL;
 			return -EIO;
 		}
@@ -138,7 +138,7 @@
 	for (i = 0; i < sbi->map_sectors; i++)
 		__brelse(sbi->vol_amap[i]);
 
-	kfree(sbi->vol_amap);
+	kvfree(sbi->vol_amap);
 }
 
 int exfat_set_bitmap(struct inode *inode, unsigned int clu, bool sync)
diff --git a/kernel/fs/exfat/dir.c b/kernel/fs/exfat/dir.c
index 09514bf..b5f3bc0 100644
--- a/kernel/fs/exfat/dir.c
+++ b/kernel/fs/exfat/dir.c
@@ -33,6 +33,7 @@
 {
 	int i;
 	struct exfat_entry_set_cache *es;
+	unsigned int uni_len = 0, len;
 
 	es = exfat_get_dentry_set(sb, p_dir, entry, ES_ALL_ENTRIES);
 	if (!es)
@@ -51,7 +52,10 @@
 		if (exfat_get_entry_type(ep) != TYPE_EXTEND)
 			break;
 
-		exfat_extract_uni_name(ep, uniname);
+		len = exfat_extract_uni_name(ep, uniname);
+		uni_len += len;
+		if (len != EXFAT_FILE_NAME_LEN || uni_len >= MAX_NAME_LENGTH)
+			break;
 		uniname += EXFAT_FILE_NAME_LEN;
 	}
 
@@ -102,7 +106,7 @@
 			clu.dir = ei->hint_bmap.clu;
 		}
 
-		while (clu_offset > 0) {
+		while (clu_offset > 0 && clu.dir != EXFAT_EOF_CLUSTER) {
 			if (exfat_get_next_cluster(sb, &(clu.dir)))
 				return -EIO;
 
@@ -148,7 +152,7 @@
 					0);
 
 			*uni_name.name = 0x0;
-			exfat_get_uniname_from_ext_entry(sb, &dir, dentry,
+			exfat_get_uniname_from_ext_entry(sb, &clu, i,
 				uni_name.name);
 			exfat_utf16_to_nls(sb, &uni_name,
 				dir_entry->namebuf.lfn,
@@ -210,7 +214,10 @@
 	exfat_init_namebuf(nb);
 }
 
-/* skip iterating emit_dots when dir is empty */
+/*
+ * Before calling dir_emit*(), sbi->s_lock should be released
+ * because page fault can occur in dir_emit*().
+ */
 #define ITER_POS_FILLED_DOTS    (2)
 static int exfat_iterate(struct file *filp, struct dir_context *ctx)
 {
@@ -225,35 +232,33 @@
 	int err = 0, fake_offset = 0;
 
 	exfat_init_namebuf(nb);
-	mutex_lock(&EXFAT_SB(sb)->s_lock);
 
 	cpos = ctx->pos;
 	if (!dir_emit_dots(filp, ctx))
-		goto unlock;
+		goto out;
 
 	if (ctx->pos == ITER_POS_FILLED_DOTS) {
 		cpos = 0;
 		fake_offset = 1;
 	}
 
-	if (cpos & (DENTRY_SIZE - 1)) {
-		err = -ENOENT;
-		goto unlock;
-	}
+	cpos = round_up(cpos, DENTRY_SIZE);
 
 	/* name buffer should be allocated before use */
 	err = exfat_alloc_namebuf(nb);
 	if (err)
-		goto unlock;
+		goto out;
 get_new:
+	mutex_lock(&EXFAT_SB(sb)->s_lock);
+
 	if (ei->flags == ALLOC_NO_FAT_CHAIN && cpos >= i_size_read(inode))
 		goto end_of_dir;
 
 	err = exfat_readdir(inode, &cpos, &de);
 	if (err) {
 		/*
-		 * At least we tried to read a sector.  Move cpos to next sector
-		 * position (should be aligned).
+		 * At least we tried to read a sector.
+		 * Move cpos to next sector position (should be aligned).
 		 */
 		if (err == -EIO) {
 			cpos += 1 << (sb->s_blocksize_bits);
@@ -276,16 +281,10 @@
 		inum = iunique(sb, EXFAT_ROOT_INO);
 	}
 
-	/*
-	 * Before calling dir_emit(), sb_lock should be released.
-	 * Because page fault can occur in dir_emit() when the size
-	 * of buffer given from user is larger than one page size.
-	 */
 	mutex_unlock(&EXFAT_SB(sb)->s_lock);
 	if (!dir_emit(ctx, nb->lfn, strlen(nb->lfn), inum,
 			(de.attr & ATTR_SUBDIR) ? DT_DIR : DT_REG))
-		goto out_unlocked;
-	mutex_lock(&EXFAT_SB(sb)->s_lock);
+		goto out;
 	ctx->pos = cpos;
 	goto get_new;
 
@@ -293,9 +292,8 @@
 	if (!cpos && fake_offset)
 		cpos = ITER_POS_FILLED_DOTS;
 	ctx->pos = cpos;
-unlock:
 	mutex_unlock(&EXFAT_SB(sb)->s_lock);
-out_unlocked:
+out:
 	/*
 	 * To improve performance, free namebuf after unlock sb_lock.
 	 * If namebuf is not allocated, this function do nothing
@@ -615,6 +613,10 @@
 			bforget(es->bh[i]);
 		else
 			brelse(es->bh[i]);
+
+	if (IS_DYNAMIC_ES(es))
+		kfree(es->bh);
+
 	kfree(es);
 	return err;
 }
@@ -850,6 +852,7 @@
 	/* byte offset in sector */
 	off = EXFAT_BLK_OFFSET(byte_offset, sb);
 	es->start_off = off;
+	es->bh = es->__bh;
 
 	/* sector offset in cluster */
 	sec = EXFAT_B_TO_BLK(byte_offset, sb);
@@ -869,6 +872,16 @@
 	es->num_entries = num_entries;
 
 	num_bh = EXFAT_B_TO_BLK_ROUND_UP(off + num_entries * DENTRY_SIZE, sb);
+	if (num_bh > ARRAY_SIZE(es->__bh)) {
+		es->bh = kmalloc_array(num_bh, sizeof(*es->bh), GFP_KERNEL);
+		if (!es->bh) {
+			brelse(bh);
+			kfree(es);
+			return NULL;
+		}
+		es->bh[0] = bh;
+	}
+
 	for (i = 1; i < num_bh; i++) {
 		/* get the next sector */
 		if (exfat_is_last_sector_in_cluster(sbi, sec)) {
@@ -908,14 +921,19 @@
 };
 
 /*
- * return values:
- *   >= 0	: return dir entiry position with the name in dir
- *   -ENOENT	: entry with the name does not exist
- *   -EIO	: I/O error
+ * @ei:         inode info of parent directory
+ * @p_dir:      directory structure of parent directory
+ * @num_entries:entry size of p_uniname
+ * @hint_opt:   If p_uniname is found, filled with optimized dir/entry
+ *              for traversing cluster chain.
+ * @return:
+ *   >= 0:      file directory entry position where the name exists
+ *   -ENOENT:   entry with the name does not exist
+ *   -EIO:      I/O error
  */
 int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
 		struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname,
-		int num_entries, unsigned int type)
+		int num_entries, unsigned int type, struct exfat_hint *hint_opt)
 {
 	int i, rewind = 0, dentry = 0, end_eidx = 0, num_ext = 0, len;
 	int order, step, name_len = 0;
@@ -992,6 +1010,8 @@
 
 			if (entry_type == TYPE_FILE || entry_type == TYPE_DIR) {
 				step = DIRENT_STEP_FILE;
+				hint_opt->clu = clu.dir;
+				hint_opt->eidx = i;
 				if (type == TYPE_ALL || type == entry_type) {
 					num_ext = ep->dentry.file.num_ext;
 					step = DIRENT_STEP_STRM;
@@ -1026,7 +1046,8 @@
 			if (entry_type == TYPE_EXTEND) {
 				unsigned short entry_uniname[16], unichar;
 
-				if (step != DIRENT_STEP_NAME) {
+				if (step != DIRENT_STEP_NAME ||
+				    name_len >= MAX_NAME_LENGTH) {
 					step = DIRENT_STEP_FILE;
 					continue;
 				}
diff --git a/kernel/fs/exfat/exfat_fs.h b/kernel/fs/exfat/exfat_fs.h
index 2aa02a7..b72c8c4 100644
--- a/kernel/fs/exfat/exfat_fs.h
+++ b/kernel/fs/exfat/exfat_fs.h
@@ -42,7 +42,7 @@
 #define ES_2_ENTRIES		2
 #define ES_ALL_ENTRIES		0
 
-#define DIR_DELETED		0xFFFF0321
+#define DIR_DELETED		0xFFFFFFF7
 
 /* type values */
 #define TYPE_UNUSED		0x0000
@@ -170,9 +170,12 @@
 	bool modified;
 	unsigned int start_off;
 	int num_bh;
-	struct buffer_head *bh[DIR_CACHE_SIZE];
+	struct buffer_head *__bh[DIR_CACHE_SIZE];
+	struct buffer_head **bh;
 	unsigned int num_entries;
 };
+
+#define IS_DYNAMIC_ES(es)	((es)->__bh != (es)->bh)
 
 struct exfat_dir_entry {
 	struct exfat_chain dir;
@@ -458,7 +461,7 @@
 int exfat_calc_num_entries(struct exfat_uni_name *p_uniname);
 int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
 		struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname,
-		int num_entries, unsigned int type);
+		int num_entries, unsigned int type, struct exfat_hint *hint_opt);
 int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu);
 int exfat_find_location(struct super_block *sb, struct exfat_chain *p_dir,
 		int entry, sector_t *sector, int *offset);
diff --git a/kernel/fs/exfat/file.c b/kernel/fs/exfat/file.c
index c819e84..819f472 100644
--- a/kernel/fs/exfat/file.c
+++ b/kernel/fs/exfat/file.c
@@ -250,8 +250,7 @@
 	else
 		mark_inode_dirty(inode);
 
-	inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >>
-				inode->i_blkbits;
+	inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9;
 write_size:
 	aligned_size = i_size_read(inode);
 	if (aligned_size & (blocksize - 1)) {
diff --git a/kernel/fs/exfat/inode.c b/kernel/fs/exfat/inode.c
index 842cdf5..ffc854f 100644
--- a/kernel/fs/exfat/inode.c
+++ b/kernel/fs/exfat/inode.c
@@ -243,8 +243,7 @@
 				return err;
 		} /* end of if != DIR_DELETED */
 
-		inode->i_blocks +=
-			num_to_be_allocated << sbi->sect_per_clus_bits;
+		inode->i_blocks += EXFAT_CLU_TO_B(num_to_be_allocated, sbi) >> 9;
 
 		/*
 		 * Move *clu pointer along FAT chains (hole care) because the
@@ -601,8 +600,7 @@
 
 	exfat_save_attr(inode, info->attr);
 
-	inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >>
-				inode->i_blkbits;
+	inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9;
 	inode->i_mtime = info->mtime;
 	inode->i_ctime = info->mtime;
 	ei->i_crtime = info->crtime;
diff --git a/kernel/fs/exfat/namei.c b/kernel/fs/exfat/namei.c
index 7bafc82..4d54f7e 100644
--- a/kernel/fs/exfat/namei.c
+++ b/kernel/fs/exfat/namei.c
@@ -398,7 +398,7 @@
 		ei->i_size_ondisk += sbi->cluster_size;
 		ei->i_size_aligned += sbi->cluster_size;
 		ei->flags = p_dir->flags;
-		inode->i_blocks += 1 << sbi->sect_per_clus_bits;
+		inode->i_blocks += sbi->cluster_size >> 9;
 	}
 
 	return dentry;
@@ -596,6 +596,8 @@
 	struct exfat_inode_info *ei = EXFAT_I(dir);
 	struct exfat_dentry *ep, *ep2;
 	struct exfat_entry_set_cache *es;
+	/* for optimized dir & entry to prevent long traverse of cluster chain */
+	struct exfat_hint hint_opt;
 
 	if (qname->len == 0)
 		return -ENOENT;
@@ -619,7 +621,7 @@
 
 	/* search the file name for directories */
 	dentry = exfat_find_dir_entry(sb, ei, &cdir, &uni_name,
-			num_entries, TYPE_ALL);
+			num_entries, TYPE_ALL, &hint_opt);
 
 	if (dentry < 0)
 		return dentry; /* -error value */
@@ -628,6 +630,11 @@
 	info->entry = dentry;
 	info->num_subdirs = 0;
 
+	/* adjust cdir to the optimized value */
+	cdir.dir = hint_opt.clu;
+	if (cdir.flags & ALLOC_NO_FAT_CHAIN)
+		cdir.size -= dentry / sbi->dentries_per_clu;
+	dentry = hint_opt.eidx;
 	es = exfat_get_dentry_set(sb, &cdir, dentry, ES_2_ENTRIES);
 	if (!es)
 		return -EIO;
diff --git a/kernel/fs/exfat/super.c b/kernel/fs/exfat/super.c
index 69068a9..b427386 100644
--- a/kernel/fs/exfat/super.c
+++ b/kernel/fs/exfat/super.c
@@ -364,8 +364,7 @@
 	inode->i_op = &exfat_dir_inode_operations;
 	inode->i_fop = &exfat_dir_operations;
 
-	inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >>
-				inode->i_blkbits;
+	inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9;
 	ei->i_pos = ((loff_t)sbi->root_dir << 32) | 0xffffffff;
 	ei->i_size_aligned = i_size_read(inode);
 	ei->i_size_ondisk = i_size_read(inode);
diff --git a/kernel/fs/ext2/ext2.h b/kernel/fs/ext2/ext2.h
index 5136b72..fb2086b 100644
--- a/kernel/fs/ext2/ext2.h
+++ b/kernel/fs/ext2/ext2.h
@@ -68,10 +68,7 @@
  * second extended-fs super-block data in memory
  */
 struct ext2_sb_info {
-	unsigned long s_frag_size;	/* Size of a fragment in bytes */
-	unsigned long s_frags_per_block;/* Number of fragments per block */
 	unsigned long s_inodes_per_block;/* Number of inodes per block */
-	unsigned long s_frags_per_group;/* Number of fragments in a group */
 	unsigned long s_blocks_per_group;/* Number of blocks in a group */
 	unsigned long s_inodes_per_group;/* Number of inodes in a group */
 	unsigned long s_itb_per_group;	/* Number of inode table blocks per group */
@@ -177,21 +174,13 @@
 #define EXT2_MIN_BLOCK_SIZE		1024
 #define	EXT2_MAX_BLOCK_SIZE		4096
 #define EXT2_MIN_BLOCK_LOG_SIZE		  10
+#define EXT2_MAX_BLOCK_LOG_SIZE		  16
 #define EXT2_BLOCK_SIZE(s)		((s)->s_blocksize)
 #define	EXT2_ADDR_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (__u32))
 #define EXT2_BLOCK_SIZE_BITS(s)		((s)->s_blocksize_bits)
 #define	EXT2_ADDR_PER_BLOCK_BITS(s)	(EXT2_SB(s)->s_addr_per_block_bits)
 #define EXT2_INODE_SIZE(s)		(EXT2_SB(s)->s_inode_size)
 #define EXT2_FIRST_INO(s)		(EXT2_SB(s)->s_first_ino)
-
-/*
- * Macro-instructions used to manage fragments
- */
-#define EXT2_MIN_FRAG_SIZE		1024
-#define	EXT2_MAX_FRAG_SIZE		4096
-#define EXT2_MIN_FRAG_LOG_SIZE		  10
-#define EXT2_FRAG_SIZE(s)		(EXT2_SB(s)->s_frag_size)
-#define EXT2_FRAGS_PER_BLOCK(s)		(EXT2_SB(s)->s_frags_per_block)
 
 /*
  * Structure of a blocks group descriptor
diff --git a/kernel/fs/ext2/super.c b/kernel/fs/ext2/super.c
index 0345f8e..758844b 100644
--- a/kernel/fs/ext2/super.c
+++ b/kernel/fs/ext2/super.c
@@ -673,10 +673,9 @@
 		es->s_max_mnt_count = cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT);
 	le16_add_cpu(&es->s_mnt_count, 1);
 	if (test_opt (sb, DEBUG))
-		ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, fs=%lu, gc=%lu, "
+		ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, gc=%lu, "
 			"bpg=%lu, ipg=%lu, mo=%04lx]",
 			EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize,
-			sbi->s_frag_size,
 			sbi->s_groups_count,
 			EXT2_BLOCKS_PER_GROUP(sb),
 			EXT2_INODES_PER_GROUP(sb),
@@ -950,6 +949,13 @@
 		goto failed_mount;
 	}
 
+	if (le32_to_cpu(es->s_log_block_size) >
+	    (EXT2_MAX_BLOCK_LOG_SIZE - BLOCK_SIZE_BITS)) {
+		ext2_msg(sb, KERN_ERR,
+			 "Invalid log block size: %u",
+			 le32_to_cpu(es->s_log_block_size));
+		goto failed_mount;
+	}
 	blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);
 
 	if (test_opt(sb, DAX)) {
@@ -1007,14 +1013,7 @@
 		}
 	}
 
-	sbi->s_frag_size = EXT2_MIN_FRAG_SIZE <<
-				   le32_to_cpu(es->s_log_frag_size);
-	if (sbi->s_frag_size == 0)
-		goto cantfind_ext2;
-	sbi->s_frags_per_block = sb->s_blocksize / sbi->s_frag_size;
-
 	sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
-	sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
 	sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
 
 	sbi->s_inodes_per_block = sb->s_blocksize / EXT2_INODE_SIZE(sb);
@@ -1040,11 +1039,10 @@
 		goto failed_mount;
 	}
 
-	if (sb->s_blocksize != sbi->s_frag_size) {
+	if (es->s_log_frag_size != es->s_log_block_size) {
 		ext2_msg(sb, KERN_ERR,
-			"error: fragsize %lu != blocksize %lu"
-			"(not supported yet)",
-			sbi->s_frag_size, sb->s_blocksize);
+			"error: fragsize log %u != blocksize log %u",
+			le32_to_cpu(es->s_log_frag_size), sb->s_blocksize_bits);
 		goto failed_mount;
 	}
 
@@ -1052,12 +1050,6 @@
 		ext2_msg(sb, KERN_ERR,
 			"error: #blocks per group too big: %lu",
 			sbi->s_blocks_per_group);
-		goto failed_mount;
-	}
-	if (sbi->s_frags_per_group > sb->s_blocksize * 8) {
-		ext2_msg(sb, KERN_ERR,
-			"error: #fragments per group too big: %lu",
-			sbi->s_frags_per_group);
 		goto failed_mount;
 	}
 	if (sbi->s_inodes_per_group < sbi->s_inodes_per_block ||
diff --git a/kernel/fs/ext2/xattr.c b/kernel/fs/ext2/xattr.c
index 841fa6d..f1dc11d 100644
--- a/kernel/fs/ext2/xattr.c
+++ b/kernel/fs/ext2/xattr.c
@@ -694,10 +694,10 @@
 			/* We need to allocate a new block */
 			ext2_fsblk_t goal = ext2_group_first_block_no(sb,
 						EXT2_I(inode)->i_block_group);
-			int block = ext2_new_block(inode, goal, &error);
+			ext2_fsblk_t block = ext2_new_block(inode, goal, &error);
 			if (error)
 				goto cleanup;
-			ea_idebug(inode, "creating block %d", block);
+			ea_idebug(inode, "creating block %lu", block);
 
 			new_bh = sb_getblk(sb, block);
 			if (unlikely(!new_bh)) {
diff --git a/kernel/fs/ext4/acl.c b/kernel/fs/ext4/acl.c
index 68aaed4..76f634d 100644
--- a/kernel/fs/ext4/acl.c
+++ b/kernel/fs/ext4/acl.c
@@ -242,7 +242,6 @@
 	handle = ext4_journal_start(inode, EXT4_HT_XATTR, credits);
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	ext4_fc_start_update(inode);
 
 	if ((type == ACL_TYPE_ACCESS) && acl) {
 		error = posix_acl_update_mode(inode, &mode, &acl);
@@ -260,7 +259,6 @@
 	}
 out_stop:
 	ext4_journal_stop(handle);
-	ext4_fc_stop_update(inode);
 	if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
 		goto retry;
 	return error;
diff --git a/kernel/fs/ext4/balloc.c b/kernel/fs/ext4/balloc.c
index 1afd60f..bdbf130 100644
--- a/kernel/fs/ext4/balloc.c
+++ b/kernel/fs/ext4/balloc.c
@@ -303,6 +303,36 @@
 	return desc;
 }
 
+static ext4_fsblk_t ext4_valid_block_bitmap_padding(struct super_block *sb,
+						    ext4_group_t block_group,
+						    struct buffer_head *bh)
+{
+	ext4_grpblk_t next_zero_bit;
+	unsigned long bitmap_size = sb->s_blocksize * 8;
+	unsigned int offset = num_clusters_in_group(sb, block_group);
+
+	if (bitmap_size <= offset)
+		return 0;
+
+	next_zero_bit = ext4_find_next_zero_bit(bh->b_data, bitmap_size, offset);
+
+	return (next_zero_bit < bitmap_size ? next_zero_bit : 0);
+}
+
+struct ext4_group_info *ext4_get_group_info(struct super_block *sb,
+					    ext4_group_t group)
+{
+	struct ext4_group_info **grp_info;
+	long indexv, indexh;
+
+	if (unlikely(group >= EXT4_SB(sb)->s_groups_count))
+		return NULL;
+	indexv = group >> (EXT4_DESC_PER_BLOCK_BITS(sb));
+	indexh = group & ((EXT4_DESC_PER_BLOCK(sb)) - 1);
+	grp_info = sbi_array_rcu_deref(EXT4_SB(sb), s_group_info, indexv);
+	return grp_info[indexh];
+}
+
 /*
  * Return the block number which was discovered to be invalid, or 0 if
  * the block bitmap is valid.
@@ -377,7 +407,7 @@
 
 	if (buffer_verified(bh))
 		return 0;
-	if (EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
+	if (!grp || EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
 		return -EFSCORRUPTED;
 
 	ext4_lock_group(sb, block_group);
@@ -399,6 +429,15 @@
 			   block_group, blk);
 		ext4_mark_group_bitmap_corrupted(sb, block_group,
 					EXT4_GROUP_INFO_BBITMAP_CORRUPT);
+		return -EFSCORRUPTED;
+	}
+	blk = ext4_valid_block_bitmap_padding(sb, block_group, bh);
+	if (unlikely(blk != 0)) {
+		ext4_unlock_group(sb, block_group);
+		ext4_error(sb, "bg %u: block %llu: padding at end of block bitmap is not set",
+			   block_group, blk);
+		ext4_mark_group_bitmap_corrupted(sb, block_group,
+						 EXT4_GROUP_INFO_BBITMAP_CORRUPT);
 		return -EFSCORRUPTED;
 	}
 	set_buffer_verified(bh);
@@ -864,11 +903,11 @@
 }
 
 /*
- * This function returns the number of file system metadata clusters at
+ * This function returns the number of file system metadata blocks at
  * the beginning of a block group, including the reserved gdt blocks.
  */
-static unsigned ext4_num_base_meta_clusters(struct super_block *sb,
-				     ext4_group_t block_group)
+unsigned int ext4_num_base_meta_blocks(struct super_block *sb,
+				       ext4_group_t block_group)
 {
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	unsigned num;
@@ -886,8 +925,15 @@
 	} else { /* For META_BG_BLOCK_GROUPS */
 		num += ext4_bg_num_gdb(sb, block_group);
 	}
-	return EXT4_NUM_B2C(sbi, num);
+	return num;
 }
+
+static unsigned int ext4_num_base_meta_clusters(struct super_block *sb,
+						ext4_group_t block_group)
+{
+	return EXT4_NUM_B2C(EXT4_SB(sb), ext4_num_base_meta_blocks(sb, block_group));
+}
+
 /**
  *	ext4_inode_to_goal_block - return a hint for block allocation
  *	@inode: inode for block allocation
diff --git a/kernel/fs/ext4/block_validity.c b/kernel/fs/ext4/block_validity.c
index 8e6ca23..295e89d 100644
--- a/kernel/fs/ext4/block_validity.c
+++ b/kernel/fs/ext4/block_validity.c
@@ -217,7 +217,6 @@
 	struct ext4_system_blocks *system_blks;
 	struct ext4_group_desc *gdp;
 	ext4_group_t i;
-	int flex_size = ext4_flex_bg_size(sbi);
 	int ret;
 
 	system_blks = kzalloc(sizeof(*system_blks), GFP_KERNEL);
@@ -225,12 +224,13 @@
 		return -ENOMEM;
 
 	for (i=0; i < ngroups; i++) {
+		unsigned int meta_blks = ext4_num_base_meta_blocks(sb, i);
+
 		cond_resched();
-		if (ext4_bg_has_super(sb, i) &&
-		    ((i < 5) || ((i % flex_size) == 0))) {
+		if (meta_blks != 0) {
 			ret = add_system_zone(system_blks,
 					ext4_group_first_block_no(sb, i),
-					ext4_bg_num_gdb(sb, i) + 1, 0);
+					meta_blks, 0);
 			if (ret)
 				goto err;
 		}
@@ -294,15 +294,10 @@
 		call_rcu(&system_blks->rcu, ext4_destroy_system_zone);
 }
 
-/*
- * Returns 1 if the passed-in block region (start_blk,
- * start_blk+count) is valid; 0 if some part of the block region
- * overlaps with some other filesystem metadata blocks.
- */
-int ext4_inode_block_valid(struct inode *inode, ext4_fsblk_t start_blk,
-			  unsigned int count)
+int ext4_sb_block_valid(struct super_block *sb, struct inode *inode,
+				ext4_fsblk_t start_blk, unsigned int count)
 {
-	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	struct ext4_system_blocks *system_blks;
 	struct ext4_system_zone *entry;
 	struct rb_node *n;
@@ -331,7 +326,9 @@
 		else if (start_blk >= (entry->start_blk + entry->count))
 			n = n->rb_right;
 		else {
-			ret = (entry->ino == inode->i_ino);
+			ret = 0;
+			if (inode)
+				ret = (entry->ino == inode->i_ino);
 			break;
 		}
 	}
@@ -340,6 +337,17 @@
 	return ret;
 }
 
+/*
+ * Returns 1 if the passed-in block region (start_blk,
+ * start_blk+count) is valid; 0 if some part of the block region
+ * overlaps with some other filesystem metadata blocks.
+ */
+int ext4_inode_block_valid(struct inode *inode, ext4_fsblk_t start_blk,
+			  unsigned int count)
+{
+	return ext4_sb_block_valid(inode->i_sb, inode, start_blk, count);
+}
+
 int ext4_check_blockref(const char *function, unsigned int line,
 			struct inode *inode, __le32 *p, unsigned int max)
 {
diff --git a/kernel/fs/ext4/ext4.h b/kernel/fs/ext4/ext4.h
index 666ea80..6709f7a 100644
--- a/kernel/fs/ext4/ext4.h
+++ b/kernel/fs/ext4/ext4.h
@@ -553,7 +553,7 @@
  *
  * It's not paranoia if the Murphy's Law really *is* out to get you.  :-)
  */
-#define TEST_FLAG_VALUE(FLAG) (EXT4_##FLAG##_FL == (1 << EXT4_INODE_##FLAG))
+#define TEST_FLAG_VALUE(FLAG) (EXT4_##FLAG##_FL == (1U << EXT4_INODE_##FLAG))
 #define CHECK_FLAG_VALUE(FLAG) BUILD_BUG_ON(!TEST_FLAG_VALUE(FLAG))
 
 static inline void ext4_check_flag_values(void)
@@ -980,11 +980,13 @@
  *			  where the second inode has larger inode number
  *			  than the first
  *  I_DATA_SEM_QUOTA  - Used for quota inodes only
+ *  I_DATA_SEM_EA     - Used for ea_inodes only
  */
 enum {
 	I_DATA_SEM_NORMAL = 0,
 	I_DATA_SEM_OTHER,
 	I_DATA_SEM_QUOTA,
+	I_DATA_SEM_EA
 };
 
 
@@ -1535,12 +1537,15 @@
 	atomic_t s_bal_success;	/* we found long enough chunks */
 	atomic_t s_bal_allocated;	/* in blocks */
 	atomic_t s_bal_ex_scanned;	/* total extents scanned */
+	atomic_t s_bal_groups_scanned;	/* number of groups scanned */
 	atomic_t s_bal_goals;	/* goal hits */
 	atomic_t s_bal_breaks;	/* too long searches */
 	atomic_t s_bal_2orders;	/* 2^order hits */
-	spinlock_t s_bal_lock;
-	unsigned long s_mb_buddies_generated;
-	unsigned long long s_mb_generation_time;
+	atomic64_t s_bal_cX_groups_considered[4];
+	atomic64_t s_bal_cX_hits[4];
+	atomic64_t s_bal_cX_failed[4];		/* cX loop didn't find blocks */
+	atomic_t s_mb_buddies_generated;	/* number of buddies generated */
+	atomic64_t s_mb_generation_time;
 	atomic_t s_mb_lost_chunks;
 	atomic_t s_mb_preallocated;
 	atomic_t s_mb_discarded;
@@ -1575,7 +1580,7 @@
 	struct task_struct *s_mmp_tsk;
 
 	/* record the last minlen when FITRIM is called. */
-	atomic_t s_last_trim_minblks;
+	unsigned long s_last_trim_minblks;
 
 	/* Reference to checksum algorithm driver via cryptoapi */
 	struct crypto_shash *s_chksum_driver;
@@ -2591,6 +2596,8 @@
 extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
 						    ext4_group_t block_group,
 						    struct buffer_head ** bh);
+extern struct ext4_group_info *ext4_get_group_info(struct super_block *sb,
+						   ext4_group_t group);
 extern int ext4_should_retry_alloc(struct super_block *sb, int *retries);
 
 extern struct buffer_head *ext4_read_block_bitmap_nowait(struct super_block *sb,
@@ -2830,6 +2837,7 @@
 extern const struct seq_operations ext4_mb_seq_groups_ops;
 extern long ext4_mb_stats;
 extern long ext4_mb_max_to_scan;
+extern int ext4_seq_mb_stats_show(struct seq_file *seq, void *offset);
 extern int ext4_mb_init(struct super_block *);
 extern int ext4_mb_release(struct super_block *);
 extern ext4_fsblk_t ext4_mb_new_blocks(handle_t *,
@@ -2887,7 +2895,9 @@
 typedef enum {
 	EXT4_IGET_NORMAL =	0,
 	EXT4_IGET_SPECIAL =	0x0001, /* OK to iget a system inode */
-	EXT4_IGET_HANDLE = 	0x0002	/* Inode # is from a handle */
+	EXT4_IGET_HANDLE = 	0x0002,	/* Inode # is from a handle */
+	EXT4_IGET_BAD =		0x0004, /* Allow to iget a bad inode */
+	EXT4_IGET_EA_INODE =	0x0008	/* Inode should contain an EA value */
 } ext4_iget_flags;
 
 extern struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
@@ -3003,6 +3013,8 @@
 extern void ext4_mark_group_bitmap_corrupted(struct super_block *sb,
 					     ext4_group_t block_group,
 					     unsigned int flags);
+extern unsigned int ext4_num_base_meta_blocks(struct super_block *sb,
+					      ext4_group_t block_group);
 
 extern __printf(6, 7)
 void __ext4_error(struct super_block *, const char *, unsigned int, int, __u64,
@@ -3237,19 +3249,6 @@
 {
 	raw_inode->i_size_lo = cpu_to_le32(i_size);
 	raw_inode->i_size_high = cpu_to_le32(i_size >> 32);
-}
-
-static inline
-struct ext4_group_info *ext4_get_group_info(struct super_block *sb,
-					    ext4_group_t group)
-{
-	 struct ext4_group_info **grp_info;
-	 long indexv, indexh;
-	 BUG_ON(group >= EXT4_SB(sb)->s_groups_count);
-	 indexv = group >> (EXT4_DESC_PER_BLOCK_BITS(sb));
-	 indexh = group & ((EXT4_DESC_PER_BLOCK(sb)) - 1);
-	 grp_info = sbi_array_rcu_deref(EXT4_SB(sb), s_group_info, indexv);
-	 return grp_info[indexh];
 }
 
 /*
@@ -3524,8 +3523,8 @@
 					unsigned int blocksize);
 extern int ext4_handle_dirty_dirblock(handle_t *handle, struct inode *inode,
 				      struct buffer_head *bh);
-extern int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name,
-			 struct inode *inode);
+extern int __ext4_unlink(struct inode *dir, const struct qstr *d_name,
+			 struct inode *inode, struct dentry *dentry);
 extern int __ext4_link(struct inode *dir, struct inode *inode,
 		       struct dentry *dentry);
 
@@ -3574,6 +3573,9 @@
 				  unsigned int count);
 extern int ext4_check_blockref(const char *, unsigned int,
 			       struct inode *, __le32 *, unsigned int);
+extern int ext4_sb_block_valid(struct super_block *sb, struct inode *inode,
+				ext4_fsblk_t start_blk, unsigned int count);
+
 
 /* extents.c */
 struct ext4_ext_path;
diff --git a/kernel/fs/ext4/extents.c b/kernel/fs/ext4/extents.c
index 54750b7..2c2e1cc 100644
--- a/kernel/fs/ext4/extents.c
+++ b/kernel/fs/ext4/extents.c
@@ -4694,7 +4694,6 @@
 		     FALLOC_FL_INSERT_RANGE))
 		return -EOPNOTSUPP;
 
-	ext4_fc_start_update(inode);
 	inode_lock(inode);
 	ret = ext4_convert_inline_data(inode);
 	inode_unlock(inode);
@@ -4764,7 +4763,6 @@
 	inode_unlock(inode);
 	trace_ext4_fallocate_exit(inode, offset, max_blocks, ret);
 exit:
-	ext4_fc_stop_update(inode);
 	return ret;
 }
 
@@ -5802,6 +5800,15 @@
 	struct ext4_extent *extent;
 	ext4_lblk_t first_lblk, first_lclu, last_lclu;
 
+	/*
+	 * if data can be stored inline, the logical cluster isn't
+	 * mapped - no physical clusters have been allocated, and the
+	 * file has no extents
+	 */
+	if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA) ||
+	    ext4_has_inline_data(inode))
+		return 0;
+
 	/* search for the extent closest to the first block in the cluster */
 	path = ext4_find_extent(inode, EXT4_C2B(sbi, lclu), NULL, 0);
 	if (IS_ERR(path)) {
diff --git a/kernel/fs/ext4/extents_status.c b/kernel/fs/ext4/extents_status.c
index 9a3a899..fee54ab 100644
--- a/kernel/fs/ext4/extents_status.c
+++ b/kernel/fs/ext4/extents_status.c
@@ -269,14 +269,12 @@
 
 	/* see if the extent has been cached */
 	es->es_lblk = es->es_len = es->es_pblk = 0;
-	if (tree->cache_es) {
-		es1 = tree->cache_es;
-		if (in_range(lblk, es1->es_lblk, es1->es_len)) {
-			es_debug("%u cached by [%u/%u) %llu %x\n",
-				 lblk, es1->es_lblk, es1->es_len,
-				 ext4_es_pblock(es1), ext4_es_status(es1));
-			goto out;
-		}
+	es1 = READ_ONCE(tree->cache_es);
+	if (es1 && in_range(lblk, es1->es_lblk, es1->es_len)) {
+		es_debug("%u cached by [%u/%u) %llu %x\n",
+			 lblk, es1->es_lblk, es1->es_len,
+			 ext4_es_pblock(es1), ext4_es_status(es1));
+		goto out;
 	}
 
 	es1 = __es_tree_search(&tree->root, lblk);
@@ -295,7 +293,7 @@
 	}
 
 	if (es1 && matching_fn(es1)) {
-		tree->cache_es = es1;
+		WRITE_ONCE(tree->cache_es, es1);
 		es->es_lblk = es1->es_lblk;
 		es->es_len = es1->es_len;
 		es->es_pblk = es1->es_pblk;
@@ -934,14 +932,12 @@
 
 	/* find extent in cache firstly */
 	es->es_lblk = es->es_len = es->es_pblk = 0;
-	if (tree->cache_es) {
-		es1 = tree->cache_es;
-		if (in_range(lblk, es1->es_lblk, es1->es_len)) {
-			es_debug("%u cached by [%u/%u)\n",
-				 lblk, es1->es_lblk, es1->es_len);
-			found = 1;
-			goto out;
-		}
+	es1 = READ_ONCE(tree->cache_es);
+	if (es1 && in_range(lblk, es1->es_lblk, es1->es_len)) {
+		es_debug("%u cached by [%u/%u)\n",
+			 lblk, es1->es_lblk, es1->es_len);
+		found = 1;
+		goto out;
 	}
 
 	node = tree->root.rb_node;
@@ -1372,7 +1368,7 @@
 		if (count_reserved)
 			count_rsvd(inode, lblk, orig_es.es_len - len1 - len2,
 				   &orig_es, &rc);
-		goto out;
+		goto out_get_reserved;
 	}
 
 	if (len1 > 0) {
@@ -1414,6 +1410,7 @@
 		}
 	}
 
+out_get_reserved:
 	if (count_reserved)
 		*reserved = get_rsvd(inode, end, es, &rc);
 out:
diff --git a/kernel/fs/ext4/fast_commit.c b/kernel/fs/ext4/fast_commit.c
index 41dcf21..be768ef 100644
--- a/kernel/fs/ext4/fast_commit.c
+++ b/kernel/fs/ext4/fast_commit.c
@@ -66,7 +66,7 @@
  * Fast Commit Ineligibility
  * -------------------------
  * Not all operations are supported by fast commits today (e.g extended
- * attributes). Fast commit ineligiblity is marked by calling one of the
+ * attributes). Fast commit ineligibility is marked by calling one of the
  * two following functions:
  *
  * - ext4_fc_mark_ineligible(): This makes next fast commit operation to fall
@@ -371,25 +371,33 @@
 	struct __track_dentry_update_args *dentry_update =
 		(struct __track_dentry_update_args *)arg;
 	struct dentry *dentry = dentry_update->dentry;
-	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+	struct inode *dir = dentry->d_parent->d_inode;
+	struct super_block *sb = inode->i_sb;
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
 
 	mutex_unlock(&ei->i_fc_lock);
+
+	if (IS_ENCRYPTED(dir)) {
+		ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_ENCRYPTED_FILENAME);
+		mutex_lock(&ei->i_fc_lock);
+		return -EOPNOTSUPP;
+	}
+
 	node = kmem_cache_alloc(ext4_fc_dentry_cachep, GFP_NOFS);
 	if (!node) {
-		ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_NOMEM);
+		ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM);
 		mutex_lock(&ei->i_fc_lock);
 		return -ENOMEM;
 	}
 
 	node->fcd_op = dentry_update->op;
-	node->fcd_parent = dentry->d_parent->d_inode->i_ino;
+	node->fcd_parent = dir->i_ino;
 	node->fcd_ino = inode->i_ino;
 	if (dentry->d_name.len > DNAME_INLINE_LEN) {
 		node->fcd_name.name = kmalloc(dentry->d_name.len, GFP_NOFS);
 		if (!node->fcd_name.name) {
 			kmem_cache_free(ext4_fc_dentry_cachep, node);
-			ext4_fc_mark_ineligible(inode->i_sb,
-				EXT4_FC_REASON_NOMEM);
+			ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM);
 			mutex_lock(&ei->i_fc_lock);
 			return -ENOMEM;
 		}
@@ -628,6 +636,9 @@
 		*crc = ext4_chksum(sbi, *crc, tl, sizeof(*tl));
 	if (pad_len > 0)
 		ext4_fc_memzero(sb, tl + 1, pad_len, crc);
+	/* Don't leak uninitialized memory in the unused last byte. */
+	*((u8 *)(tl + 1) + pad_len) = 0;
+
 	ext4_fc_submit_bh(sb);
 
 	ret = jbd2_fc_get_buf(EXT4_SB(sb)->s_journal, &bh);
@@ -684,6 +695,8 @@
 	dst += sizeof(tail.fc_tid);
 	tail.fc_crc = cpu_to_le32(crc);
 	ext4_fc_memcpy(sb, dst, &tail.fc_crc, sizeof(tail.fc_crc), NULL);
+	dst += sizeof(tail.fc_crc);
+	memset(dst, 0, bsize - off); /* Don't leak uninitialized memory. */
 
 	ext4_fc_submit_bh(sb);
 
@@ -1287,7 +1300,7 @@
 		return 0;
 	}
 
-	ret = __ext4_unlink(NULL, old_parent, &entry, inode);
+	ret = __ext4_unlink(old_parent, &entry, inode, NULL);
 	/* -ENOENT ok coz it might not exist anymore. */
 	if (ret == -ENOENT)
 		ret = 0;
@@ -2137,17 +2150,17 @@
 	journal->j_fc_cleanup_callback = ext4_fc_cleanup;
 }
 
-static const char *fc_ineligible_reasons[] = {
-	"Extended attributes changed",
-	"Cross rename",
-	"Journal flag changed",
-	"Insufficient memory",
-	"Swap boot",
-	"Resize",
-	"Dir renamed",
-	"Falloc range op",
-	"Data journalling",
-	"FC Commit Failed"
+static const char * const fc_ineligible_reasons[] = {
+	[EXT4_FC_REASON_XATTR] = "Extended attributes changed",
+	[EXT4_FC_REASON_CROSS_RENAME] = "Cross rename",
+	[EXT4_FC_REASON_JOURNAL_FLAG_CHANGE] = "Journal flag changed",
+	[EXT4_FC_REASON_NOMEM] = "Insufficient memory",
+	[EXT4_FC_REASON_SWAP_BOOT] = "Swap boot",
+	[EXT4_FC_REASON_RESIZE] = "Resize",
+	[EXT4_FC_REASON_RENAME_DIR] = "Dir renamed",
+	[EXT4_FC_REASON_FALLOC_RANGE] = "Falloc range op",
+	[EXT4_FC_REASON_INODE_JOURNAL_DATA] = "Data journalling",
+	[EXT4_FC_REASON_ENCRYPTED_FILENAME] = "Encrypted filename",
 };
 
 int ext4_fc_info_show(struct seq_file *seq, void *v)
diff --git a/kernel/fs/ext4/fast_commit.h b/kernel/fs/ext4/fast_commit.h
index d8d0998..4a5f96a 100644
--- a/kernel/fs/ext4/fast_commit.h
+++ b/kernel/fs/ext4/fast_commit.h
@@ -104,6 +104,7 @@
 	EXT4_FC_REASON_FALLOC_RANGE,
 	EXT4_FC_REASON_INODE_JOURNAL_DATA,
 	EXT4_FC_COMMIT_FAILED,
+	EXT4_FC_REASON_ENCRYPTED_FILENAME,
 	EXT4_FC_REASON_MAX
 };
 
diff --git a/kernel/fs/ext4/file.c b/kernel/fs/ext4/file.c
index b41472c..d439834 100644
--- a/kernel/fs/ext4/file.c
+++ b/kernel/fs/ext4/file.c
@@ -262,7 +262,6 @@
 	if (iocb->ki_flags & IOCB_NOWAIT)
 		return -EOPNOTSUPP;
 
-	ext4_fc_start_update(inode);
 	inode_lock(inode);
 	ret = ext4_write_checks(iocb, from);
 	if (ret <= 0)
@@ -274,7 +273,6 @@
 
 out:
 	inode_unlock(inode);
-	ext4_fc_stop_update(inode);
 	if (likely(ret > 0)) {
 		iocb->ki_pos += ret;
 		ret = generic_write_sync(iocb, ret);
@@ -561,9 +559,7 @@
 			goto out;
 		}
 
-		ext4_fc_start_update(inode);
 		ret = ext4_orphan_add(handle, inode);
-		ext4_fc_stop_update(inode);
 		if (ret) {
 			ext4_journal_stop(handle);
 			goto out;
diff --git a/kernel/fs/ext4/fsmap.c b/kernel/fs/ext4/fsmap.c
index 4c2a9fe..0b2e4d3 100644
--- a/kernel/fs/ext4/fsmap.c
+++ b/kernel/fs/ext4/fsmap.c
@@ -486,6 +486,8 @@
 		keys[0].fmr_physical = bofs;
 	if (keys[1].fmr_physical >= eofs)
 		keys[1].fmr_physical = eofs - 1;
+	if (keys[1].fmr_physical < keys[0].fmr_physical)
+		return 0;
 	start_fsb = keys[0].fmr_physical;
 	end_fsb = keys[1].fmr_physical;
 
diff --git a/kernel/fs/ext4/ialloc.c b/kernel/fs/ext4/ialloc.c
index 4dac989..d6c4ea4 100644
--- a/kernel/fs/ext4/ialloc.c
+++ b/kernel/fs/ext4/ialloc.c
@@ -91,7 +91,7 @@
 
 	if (buffer_verified(bh))
 		return 0;
-	if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp))
+	if (!grp || EXT4_MB_GRP_IBITMAP_CORRUPT(grp))
 		return -EFSCORRUPTED;
 
 	ext4_lock_group(sb, block_group);
@@ -293,7 +293,7 @@
 	}
 	if (!(sbi->s_mount_state & EXT4_FC_REPLAY)) {
 		grp = ext4_get_group_info(sb, block_group);
-		if (unlikely(EXT4_MB_GRP_IBITMAP_CORRUPT(grp))) {
+		if (!grp || unlikely(EXT4_MB_GRP_IBITMAP_CORRUPT(grp))) {
 			fatal = -EFSCORRUPTED;
 			goto error_return;
 		}
@@ -1048,7 +1048,7 @@
 			 * Skip groups with already-known suspicious inode
 			 * tables
 			 */
-			if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp))
+			if (!grp || EXT4_MB_GRP_IBITMAP_CORRUPT(grp))
 				goto next_group;
 		}
 
@@ -1183,6 +1183,10 @@
 
 		if (!(sbi->s_mount_state & EXT4_FC_REPLAY)) {
 			grp = ext4_get_group_info(sb, group);
+			if (!grp) {
+				err = -EFSCORRUPTED;
+				goto out;
+			}
 			down_read(&grp->alloc_sem); /*
 						     * protect vs itable
 						     * lazyinit
@@ -1526,7 +1530,7 @@
 	}
 
 	gdp = ext4_get_group_desc(sb, group, &group_desc_bh);
-	if (!gdp)
+	if (!gdp || !grp)
 		goto out;
 
 	/*
diff --git a/kernel/fs/ext4/indirect.c b/kernel/fs/ext4/indirect.c
index 05efa68..c2bb2ff 100644
--- a/kernel/fs/ext4/indirect.c
+++ b/kernel/fs/ext4/indirect.c
@@ -148,6 +148,7 @@
 	struct super_block *sb = inode->i_sb;
 	Indirect *p = chain;
 	struct buffer_head *bh;
+	unsigned int key;
 	int ret = -EIO;
 
 	*err = 0;
@@ -156,7 +157,13 @@
 	if (!p->key)
 		goto no_block;
 	while (--depth) {
-		bh = sb_getblk(sb, le32_to_cpu(p->key));
+		key = le32_to_cpu(p->key);
+		if (key > ext4_blocks_count(EXT4_SB(sb)->s_es)) {
+			/* the block was out of range */
+			ret = -EFSCORRUPTED;
+			goto failure;
+		}
+		bh = sb_getblk(sb, key);
 		if (unlikely(!bh)) {
 			ret = -ENOMEM;
 			goto failure;
@@ -642,6 +649,14 @@
 
 	ext4_update_inode_fsync_trans(handle, inode, 1);
 	count = ar.len;
+
+	/*
+	 * Update reserved blocks/metadata blocks after successful block
+	 * allocation which had been deferred till now.
+	 */
+	if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)
+		ext4_da_update_reserve_space(inode, count, 1);
+
 got_it:
 	map->m_flags |= EXT4_MAP_MAPPED;
 	map->m_pblk = le32_to_cpu(chain[depth-1].key);
@@ -705,7 +720,7 @@
 
 /*
  * Truncate transactions can be complex and absolutely huge.  So we need to
- * be able to restart the transaction at a conventient checkpoint to make
+ * be able to restart the transaction at a convenient checkpoint to make
  * sure we don't overflow the journal.
  *
  * Try to extend this transaction for the purposes of truncation.  If
diff --git a/kernel/fs/ext4/inline.c b/kernel/fs/ext4/inline.c
index e0c639b..58873f3 100644
--- a/kernel/fs/ext4/inline.c
+++ b/kernel/fs/ext4/inline.c
@@ -33,6 +33,7 @@
 	struct ext4_xattr_ibody_header *header;
 	struct ext4_xattr_entry *entry;
 	struct ext4_inode *raw_inode;
+	void *end;
 	int free, min_offs;
 
 	if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
@@ -56,14 +57,23 @@
 	raw_inode = ext4_raw_inode(iloc);
 	header = IHDR(inode, raw_inode);
 	entry = IFIRST(header);
+	end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
 
 	/* Compute min_offs. */
-	for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
+	while (!IS_LAST_ENTRY(entry)) {
+		void *next = EXT4_XATTR_NEXT(entry);
+
+		if (next >= end) {
+			EXT4_ERROR_INODE(inode,
+					 "corrupt xattr in inline inode");
+			return 0;
+		}
 		if (!entry->e_value_inum && entry->e_value_size) {
 			size_t offs = le16_to_cpu(entry->e_value_offs);
 			if (offs < min_offs)
 				min_offs = offs;
 		}
+		entry = next;
 	}
 	free = min_offs -
 		((void *)entry - (void *)IFIRST(header)) - sizeof(__u32);
@@ -158,7 +168,6 @@
 					(void *)ext4_raw_inode(&is.iloc));
 		EXT4_I(inode)->i_inline_size = EXT4_MIN_INLINE_DATA_SIZE +
 				le32_to_cpu(is.s.here->e_value_size);
-		ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
 	}
 out:
 	brelse(is.iloc.bh);
@@ -208,7 +217,7 @@
 /*
  * write the buffer to the inline inode.
  * If 'create' is set, we don't need to do the extra copy in the xattr
- * value since it is already handled by ext4_xattr_ibody_inline_set.
+ * value since it is already handled by ext4_xattr_ibody_set.
  * That saves us one memcpy.
  */
 static void ext4_write_inline_data(struct inode *inode, struct ext4_iloc *iloc,
@@ -290,7 +299,7 @@
 
 	BUG_ON(!is.s.not_found);
 
-	error = ext4_xattr_ibody_inline_set(handle, inode, &i, &is);
+	error = ext4_xattr_ibody_set(handle, inode, &i, &is);
 	if (error) {
 		if (error == -ENOSPC)
 			ext4_clear_inode_state(inode,
@@ -350,7 +359,7 @@
 
 	error = ext4_xattr_ibody_get(inode, i.name_index, i.name,
 				     value, len);
-	if (error == -ENODATA)
+	if (error < 0)
 		goto out;
 
 	BUFFER_TRACE(is.iloc.bh, "get_write_access");
@@ -362,7 +371,7 @@
 	i.value = value;
 	i.value_len = len;
 
-	error = ext4_xattr_ibody_inline_set(handle, inode, &i, &is);
+	error = ext4_xattr_ibody_set(handle, inode, &i, &is);
 	if (error)
 		goto out;
 
@@ -435,7 +444,7 @@
 	if (error)
 		goto out;
 
-	error = ext4_xattr_ibody_inline_set(handle, inode, &i, &is);
+	error = ext4_xattr_ibody_set(handle, inode, &i, &is);
 	if (error)
 		goto out;
 
@@ -813,7 +822,7 @@
  *    clear the inode state safely.
  * 2. The inode has inline data, then we need to read the data, make it
  *    update and dirty so that ext4_da_writepages can handle it. We don't
- *    need to start the journal since the file's metatdata isn't changed now.
+ *    need to start the journal since the file's metadata isn't changed now.
  */
 static int ext4_da_convert_inline_data_to_extent(struct address_space *mapping,
 						 struct inode *inode,
@@ -1187,6 +1196,7 @@
 		ext4_initialize_dirent_tail(dir_block,
 					    inode->i_sb->s_blocksize);
 	set_buffer_uptodate(dir_block);
+	unlock_buffer(dir_block);
 	err = ext4_handle_dirty_dirblock(handle, inode, dir_block);
 	if (err)
 		return err;
@@ -1260,6 +1270,7 @@
 	if (!S_ISDIR(inode->i_mode)) {
 		memcpy(data_bh->b_data, buf, inline_size);
 		set_buffer_uptodate(data_bh);
+		unlock_buffer(data_bh);
 		error = ext4_handle_dirty_metadata(handle,
 						   inode, data_bh);
 	} else {
@@ -1267,7 +1278,6 @@
 						       buf, inline_size);
 	}
 
-	unlock_buffer(data_bh);
 out_restore:
 	if (error)
 		ext4_restore_inline_data(handle, inode, iloc, buf, inline_size);
@@ -1950,8 +1960,7 @@
 			i.value = value;
 			i.value_len = i_size > EXT4_MIN_INLINE_DATA_SIZE ?
 					i_size - EXT4_MIN_INLINE_DATA_SIZE : 0;
-			err = ext4_xattr_ibody_inline_set(handle, inode,
-							  &i, &is);
+			err = ext4_xattr_ibody_set(handle, inode, &i, &is);
 			if (err)
 				goto out_error;
 		}
diff --git a/kernel/fs/ext4/inode.c b/kernel/fs/ext4/inode.c
index 3c8859b..c1c6e0c 100644
--- a/kernel/fs/ext4/inode.c
+++ b/kernel/fs/ext4/inode.c
@@ -180,6 +180,8 @@
 
 	trace_ext4_evict_inode(inode);
 
+	if (EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)
+		ext4_evict_ea_inode(inode);
 	if (inode->i_nlink) {
 		/*
 		 * When journalling data dirty buffers are tracked only in the
@@ -224,13 +226,13 @@
 
 	/*
 	 * For inodes with journalled data, transaction commit could have
-	 * dirtied the inode. Flush worker is ignoring it because of I_FREEING
-	 * flag but we still need to remove the inode from the writeback lists.
+	 * dirtied the inode. And for inodes with dioread_nolock, unwritten
+	 * extents converting worker could merge extents and also have dirtied
+	 * the inode. Flush worker is ignoring it because of I_FREEING flag but
+	 * we still need to remove the inode from the writeback lists.
 	 */
-	if (!list_empty_careful(&inode->i_io_list)) {
-		WARN_ON_ONCE(!ext4_should_journal_data(inode));
+	if (!list_empty_careful(&inode->i_io_list))
 		inode_io_list_del(inode);
-	}
 
 	/*
 	 * Protect us against freezing - iput() caller didn't have to have any
@@ -337,6 +339,12 @@
 	ext4_xattr_inode_array_free(ea_inode_array);
 	return;
 no_delete:
+	/*
+	 * Check out some where else accidentally dirty the evicting inode,
+	 * which may probably cause inode use-after-free issues later.
+	 */
+	WARN_ON_ONCE(!list_empty_careful(&inode->i_io_list));
+
 	if (!list_empty(&EXT4_I(inode)->i_fc_list))
 		ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_NOMEM);
 	ext4_clear_inode(inode);	/* We must guarantee clearing of inode... */
@@ -647,16 +655,6 @@
 			 */
 			ext4_clear_inode_state(inode, EXT4_STATE_EXT_MIGRATE);
 		}
-
-		/*
-		 * Update reserved blocks/metadata blocks after successful
-		 * block allocation which had been deferred till now. We don't
-		 * support fallocate for non extent files. So we can update
-		 * reserve space here.
-		 */
-		if ((retval > 0) &&
-			(flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE))
-			ext4_da_update_reserve_space(inode, retval, 1);
 	}
 
 	if (retval > 0) {
@@ -1307,7 +1305,8 @@
 
 	trace_android_fs_datawrite_end(inode, pos, len);
 	trace_ext4_write_end(inode, pos, len, copied);
-	if (inline_data) {
+	if (inline_data &&
+	    ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) {
 		ret = ext4_write_inline_data_end(inode, pos, len,
 						 copied, page);
 		if (ret < 0) {
@@ -3587,7 +3586,7 @@
 	 */
 	flags &= ~IOMAP_WRITE;
 	ret = ext4_iomap_begin(inode, offset, length, flags, iomap, srcmap);
-	WARN_ON_ONCE(iomap->type != IOMAP_MAPPED);
+	WARN_ON_ONCE(!ret && iomap->type != IOMAP_MAPPED);
 	return ret;
 }
 
@@ -3911,7 +3910,7 @@
  * starting from file offset 'from'.  The range to be zero'd must
  * be contained with in one block.  If the specified range exceeds
  * the end of the block it will be shortened to end of the block
- * that cooresponds to 'from'
+ * that corresponds to 'from'
  */
 static int ext4_block_zero_page_range(handle_t *handle,
 		struct address_space *mapping, loff_t from, loff_t length)
@@ -4317,7 +4316,8 @@
 
 	/* If we zero-out tail of the page, we have to create jinode for jbd2 */
 	if (inode->i_size & (inode->i_sb->s_blocksize - 1)) {
-		if (ext4_inode_attach_jinode(inode) < 0)
+		err = ext4_inode_attach_jinode(inode);
+		if (err)
 			goto out_trace;
 	}
 
@@ -4418,8 +4418,16 @@
 	inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;
 	inode_offset = ((ino - 1) %
 			EXT4_INODES_PER_GROUP(sb));
-	block = ext4_inode_table(sb, gdp) + (inode_offset / inodes_per_block);
 	iloc->offset = (inode_offset % inodes_per_block) * EXT4_INODE_SIZE(sb);
+
+	block = ext4_inode_table(sb, gdp);
+	if ((block <= le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) ||
+	    (block >= ext4_blocks_count(EXT4_SB(sb)->s_es))) {
+		ext4_error(sb, "Invalid inode table block %llu in "
+			   "block_group %u", block, iloc->block_group);
+		return -EFSCORRUPTED;
+	}
+	block += (inode_offset / inodes_per_block);
 
 	bh = sb_getblk(sb, block);
 	if (unlikely(!bh))
@@ -4654,8 +4662,13 @@
 
 	if (EXT4_INODE_HAS_XATTR_SPACE(inode)  &&
 	    *magic == cpu_to_le32(EXT4_XATTR_MAGIC)) {
+		int err;
+
 		ext4_set_inode_state(inode, EXT4_STATE_XATTR);
-		return ext4_find_inline_data_nolock(inode);
+		err = ext4_find_inline_data_nolock(inode);
+		if (!err && ext4_has_inline_data(inode))
+			ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
+		return err;
 	} else
 		EXT4_I(inode)->i_inline_off = 0;
 	return 0;
@@ -4689,6 +4702,24 @@
 		return inode_peek_iversion(inode);
 }
 
+static const char *check_igot_inode(struct inode *inode, ext4_iget_flags flags)
+
+{
+	if (flags & EXT4_IGET_EA_INODE) {
+		if (!(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL))
+			return "missing EA_INODE flag";
+		if (ext4_test_inode_state(inode, EXT4_STATE_XATTR) ||
+		    EXT4_I(inode)->i_file_acl)
+			return "ea_inode with extended attributes";
+	} else {
+		if ((EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL))
+			return "unexpected EA_INODE flag";
+	}
+	if (is_bad_inode(inode) && !(flags & EXT4_IGET_BAD))
+		return "unexpected bad inode w/o EXT4_IGET_BAD";
+	return NULL;
+}
+
 struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
 			  ext4_iget_flags flags, const char *function,
 			  unsigned int line)
@@ -4697,6 +4728,7 @@
 	struct ext4_inode *raw_inode;
 	struct ext4_inode_info *ei;
 	struct inode *inode;
+	const char *err_str;
 	journal_t *journal = EXT4_SB(sb)->s_journal;
 	long ret;
 	loff_t size;
@@ -4720,8 +4752,14 @@
 	inode = iget_locked(sb, ino);
 	if (!inode)
 		return ERR_PTR(-ENOMEM);
-	if (!(inode->i_state & I_NEW))
+	if (!(inode->i_state & I_NEW)) {
+		if ((err_str = check_igot_inode(inode, flags)) != NULL) {
+			ext4_error_inode(inode, function, line, 0, err_str);
+			iput(inode);
+			return ERR_PTR(-EFSCORRUPTED);
+		}
 		return inode;
+	}
 
 	ei = EXT4_I(inode);
 	iloc.bh = NULL;
@@ -4730,13 +4768,6 @@
 	if (ret < 0)
 		goto bad_inode;
 	raw_inode = ext4_raw_inode(&iloc);
-
-	if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) {
-		ext4_error_inode(inode, function, line, 0,
-				 "iget: root inode unallocated");
-		ret = -EFSCORRUPTED;
-		goto bad_inode;
-	}
 
 	if ((flags & EXT4_IGET_HANDLE) &&
 	    (raw_inode->i_links_count == 0) && (raw_inode->i_mode == 0)) {
@@ -4810,11 +4841,16 @@
 	 * NeilBrown 1999oct15
 	 */
 	if (inode->i_nlink == 0) {
-		if ((inode->i_mode == 0 ||
+		if ((inode->i_mode == 0 || flags & EXT4_IGET_SPECIAL ||
 		     !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) &&
 		    ino != EXT4_BOOT_LOADER_INO) {
-			/* this inode is deleted */
-			ret = -ESTALE;
+			/* this inode is deleted or unallocated */
+			if (flags & EXT4_IGET_SPECIAL) {
+				ext4_error_inode(inode, function, line, 0,
+						 "iget: special inode unallocated");
+				ret = -EFSCORRUPTED;
+			} else
+				ret = -ESTALE;
 			goto bad_inode;
 		}
 		/* The only unlinked inodes we let through here have
@@ -4992,8 +5028,13 @@
 	if (IS_CASEFOLDED(inode) && !ext4_has_feature_casefold(inode->i_sb))
 		ext4_error_inode(inode, function, line, 0,
 				 "casefold flag without casefold feature");
-	brelse(iloc.bh);
+	if ((err_str = check_igot_inode(inode, flags)) != NULL) {
+		ext4_error_inode(inode, function, line, 0, err_str);
+		ret = -EFSCORRUPTED;
+		goto bad_inode;
+	}
 
+	brelse(iloc.bh);
 	unlock_new_inode(inode);
 	return inode;
 
@@ -5442,7 +5483,7 @@
 		if (error)
 			return error;
 	}
-	ext4_fc_start_update(inode);
+
 	if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
 	    (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {
 		handle_t *handle;
@@ -5466,7 +5507,6 @@
 
 		if (error) {
 			ext4_journal_stop(handle);
-			ext4_fc_stop_update(inode);
 			return error;
 		}
 		/* Update corresponding info in inode so that everything is in
@@ -5478,7 +5518,6 @@
 		error = ext4_mark_inode_dirty(handle, inode);
 		ext4_journal_stop(handle);
 		if (unlikely(error)) {
-			ext4_fc_stop_update(inode);
 			return error;
 		}
 	}
@@ -5493,12 +5532,10 @@
 			struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
 
 			if (attr->ia_size > sbi->s_bitmap_maxbytes) {
-				ext4_fc_stop_update(inode);
 				return -EFBIG;
 			}
 		}
 		if (!S_ISREG(inode->i_mode)) {
-			ext4_fc_stop_update(inode);
 			return -EINVAL;
 		}
 
@@ -5624,7 +5661,6 @@
 		ext4_std_error(inode->i_sb, error);
 	if (!error)
 		error = rc;
-	ext4_fc_stop_update(inode);
 	return error;
 }
 
@@ -5890,6 +5926,14 @@
 		return 0;
 	}
 
+	/*
+	 * We may need to allocate external xattr block so we need quotas
+	 * initialized. Here we can be called with various locks held so we
+	 * cannot affort to initialize quotas ourselves. So just bail.
+	 */
+	if (dquot_initialize_needed(inode))
+		return -EAGAIN;
+
 	/* try to expand with EAs present */
 	error = ext4_expand_extra_isize_ea(inode, new_extra_isize,
 					   raw_inode, handle);
diff --git a/kernel/fs/ext4/ioctl.c b/kernel/fs/ext4/ioctl.c
index a740d7c..63cb060 100644
--- a/kernel/fs/ext4/ioctl.c
+++ b/kernel/fs/ext4/ioctl.c
@@ -121,7 +121,8 @@
 	blkcnt_t blocks;
 	unsigned short bytes;
 
-	inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL);
+	inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO,
+			EXT4_IGET_SPECIAL | EXT4_IGET_BAD);
 	if (IS_ERR(inode_bl))
 		return PTR_ERR(inode_bl);
 	ei_bl = EXT4_I(inode_bl);
@@ -170,7 +171,7 @@
 	/* Protect extent tree against block allocations via delalloc */
 	ext4_double_down_write_data_sem(inode, inode_bl);
 
-	if (inode_bl->i_nlink == 0) {
+	if (is_bad_inode(inode_bl) || !S_ISREG(inode_bl->i_mode)) {
 		/* this inode has never been used as a BOOT_LOADER */
 		set_nlink(inode_bl, 1);
 		i_uid_write(inode_bl, 0);
@@ -179,6 +180,7 @@
 		ei_bl->i_flags = 0;
 		inode_set_iversion(inode_bl, 1);
 		i_size_write(inode_bl, 0);
+		EXT4_I(inode_bl)->i_disksize = inode_bl->i_size;
 		inode_bl->i_mode = S_IFREG;
 		if (ext4_has_feature_extents(sb)) {
 			ext4_set_inode_flag(inode_bl, EXT4_INODE_EXTENTS);
@@ -494,6 +496,10 @@
 	if (ext4_is_quota_file(inode))
 		return err;
 
+	err = dquot_initialize(inode);
+	if (err)
+		return err;
+
 	err = ext4_get_inode_loc(inode, &iloc);
 	if (err)
 		return err;
@@ -508,10 +514,6 @@
 	} else {
 		brelse(iloc.bh);
 	}
-
-	err = dquot_initialize(inode);
-	if (err)
-		return err;
 
 	handle = ext4_journal_start(inode, EXT4_HT_QUOTA,
 		EXT4_QUOTA_INIT_BLOCKS(sb) +
@@ -610,6 +612,7 @@
 {
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	__u32 flags;
+	int ret;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
@@ -628,7 +631,9 @@
 
 	switch (flags) {
 	case EXT4_GOING_FLAGS_DEFAULT:
-		freeze_bdev(sb->s_bdev);
+		ret = freeze_bdev(sb->s_bdev);
+		if (ret)
+			return ret;
 		set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
 		thaw_bdev(sb->s_bdev);
 		break;
@@ -1326,13 +1331,7 @@
 
 long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
-	long ret;
-
-	ext4_fc_start_update(file_inode(filp));
-	ret = __ext4_ioctl(filp, cmd, arg);
-	ext4_fc_stop_update(file_inode(filp));
-
-	return ret;
+	return __ext4_ioctl(filp, cmd, arg);
 }
 
 #ifdef CONFIG_COMPAT
diff --git a/kernel/fs/ext4/mballoc.c b/kernel/fs/ext4/mballoc.c
index d5ca02a..b35d59d 100644
--- a/kernel/fs/ext4/mballoc.c
+++ b/kernel/fs/ext4/mballoc.c
@@ -16,6 +16,7 @@
 #include <linux/slab.h>
 #include <linux/nospec.h>
 #include <linux/backing-dev.h>
+#include <linux/freezer.h>
 #include <trace/events/ext4.h>
 
 /*
@@ -684,6 +685,8 @@
 	MB_CHECK_ASSERT(e4b->bd_info->bb_fragments == fragments);
 
 	grp = ext4_get_group_info(sb, e4b->bd_group);
+	if (!grp)
+		return NULL;
 	list_for_each(cur, &grp->bb_prealloc_list) {
 		ext4_group_t groupnr;
 		struct ext4_prealloc_space *pa;
@@ -767,9 +770,9 @@
 
 static noinline_for_stack
 void ext4_mb_generate_buddy(struct super_block *sb,
-				void *buddy, void *bitmap, ext4_group_t group)
+			    void *buddy, void *bitmap, ext4_group_t group,
+			    struct ext4_group_info *grp)
 {
-	struct ext4_group_info *grp = ext4_get_group_info(sb, group);
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	ext4_grpblk_t max = EXT4_CLUSTERS_PER_GROUP(sb);
 	ext4_grpblk_t i = 0;
@@ -816,28 +819,8 @@
 	clear_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &(grp->bb_state));
 
 	period = get_cycles() - period;
-	spin_lock(&sbi->s_bal_lock);
-	sbi->s_mb_buddies_generated++;
-	sbi->s_mb_generation_time += period;
-	spin_unlock(&sbi->s_bal_lock);
-}
-
-static void mb_regenerate_buddy(struct ext4_buddy *e4b)
-{
-	int count;
-	int order = 1;
-	void *buddy;
-
-	while ((buddy = mb_find_buddy(e4b, order++, &count))) {
-		ext4_set_bits(buddy, 0, count);
-	}
-	e4b->bd_info->bb_fragments = 0;
-	memset(e4b->bd_info->bb_counters, 0,
-		sizeof(*e4b->bd_info->bb_counters) *
-		(e4b->bd_sb->s_blocksize_bits + 2));
-
-	ext4_mb_generate_buddy(e4b->bd_sb, e4b->bd_buddy,
-		e4b->bd_bitmap, e4b->bd_group);
+	atomic_inc(&sbi->s_mb_buddies_generated);
+	atomic64_add(period, &sbi->s_mb_generation_time);
 }
 
 /* The buddy information is attached the buddy cache inode
@@ -909,6 +892,8 @@
 			break;
 
 		grinfo = ext4_get_group_info(sb, group);
+		if (!grinfo)
+			continue;
 		/*
 		 * If page is uptodate then we came here after online resize
 		 * which added some new uninitialized group info structs, so
@@ -974,6 +959,10 @@
 				group, page->index, i * blocksize);
 			trace_ext4_mb_buddy_bitmap_load(sb, group);
 			grinfo = ext4_get_group_info(sb, group);
+			if (!grinfo) {
+				err = -EFSCORRUPTED;
+				goto out;
+			}
 			grinfo->bb_fragments = 0;
 			memset(grinfo->bb_counters, 0,
 			       sizeof(*grinfo->bb_counters) *
@@ -984,7 +973,7 @@
 			ext4_lock_group(sb, group);
 			/* init the buddy */
 			memset(data, 0xff, blocksize);
-			ext4_mb_generate_buddy(sb, data, incore, group);
+			ext4_mb_generate_buddy(sb, data, incore, group, grinfo);
 			ext4_unlock_group(sb, group);
 			incore = NULL;
 		} else {
@@ -1098,6 +1087,9 @@
 	might_sleep();
 	mb_debug(sb, "init group %u\n", group);
 	this_grp = ext4_get_group_info(sb, group);
+	if (!this_grp)
+		return -EFSCORRUPTED;
+
 	/*
 	 * This ensures that we don't reinit the buddy cache
 	 * page which map to the group from which we are already
@@ -1172,6 +1164,8 @@
 
 	blocks_per_page = PAGE_SIZE / sb->s_blocksize;
 	grp = ext4_get_group_info(sb, group);
+	if (!grp)
+		return -EFSCORRUPTED;
 
 	e4b->bd_blkbits = sb->s_blocksize_bits;
 	e4b->bd_info = grp;
@@ -1512,7 +1506,6 @@
 				sb, e4b->bd_group,
 				EXT4_GROUP_INFO_BBITMAP_CORRUPT);
 		}
-		mb_regenerate_buddy(e4b);
 		goto done;
 	}
 
@@ -1885,7 +1878,9 @@
 	struct ext4_group_info *grp = ext4_get_group_info(ac->ac_sb, group);
 	struct ext4_free_extent ex;
 
-	if (!(ac->ac_flags & EXT4_MB_HINT_TRY_GOAL))
+	if (!grp)
+		return -EFSCORRUPTED;
+	if (!(ac->ac_flags & (EXT4_MB_HINT_TRY_GOAL | EXT4_MB_HINT_GOAL_ONLY)))
 		return 0;
 	if (grp->bb_free == 0)
 		return 0;
@@ -2109,7 +2104,7 @@
 
 	BUG_ON(cr < 0 || cr >= 4);
 
-	if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(grp)))
+	if (unlikely(!grp || EXT4_MB_GRP_BBITMAP_CORRUPT(grp)))
 		return false;
 
 	free = grp->bb_free;
@@ -2172,6 +2167,10 @@
 	ext4_grpblk_t free;
 	int ret = 0;
 
+	if (!grp)
+		return -EFSCORRUPTED;
+	if (sbi->s_mb_stats)
+		atomic64_inc(&sbi->s_bal_cX_groups_considered[ac->ac_criteria]);
 	if (should_lock)
 		ext4_lock_group(sb, group);
 	free = grp->bb_free;
@@ -2242,7 +2241,7 @@
 		 * prefetch once, so we avoid getblk() call, which can
 		 * be expensive.
 		 */
-		if (!EXT4_MB_GRP_TEST_AND_SET_READ(grp) &&
+		if (gdp && grp && !EXT4_MB_GRP_TEST_AND_SET_READ(grp) &&
 		    EXT4_MB_GRP_NEED_INIT(grp) &&
 		    ext4_free_group_clusters(sb, gdp) > 0 &&
 		    !(ext4_has_group_desc_csum(sb) &&
@@ -2286,7 +2285,7 @@
 		group--;
 		grp = ext4_get_group_info(sb, group);
 
-		if (EXT4_MB_GRP_NEED_INIT(grp) &&
+		if (grp && gdp && EXT4_MB_GRP_NEED_INIT(grp) &&
 		    ext4_free_group_clusters(sb, gdp) > 0 &&
 		    !(ext4_has_group_desc_csum(sb) &&
 		      (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)))) {
@@ -2446,6 +2445,9 @@
 			if (ac->ac_status != AC_STATUS_CONTINUE)
 				break;
 		}
+		/* Processed all groups and haven't found blocks */
+		if (sbi->s_mb_stats && i == ngroups)
+			atomic64_inc(&sbi->s_bal_cX_failed[cr]);
 	}
 
 	if (ac->ac_b_ex.fe_len > 0 && ac->ac_status != AC_STATUS_FOUND &&
@@ -2475,6 +2477,9 @@
 			goto repeat;
 		}
 	}
+
+	if (sbi->s_mb_stats && ac->ac_status == AC_STATUS_FOUND)
+		atomic64_inc(&sbi->s_bal_cX_hits[ac->ac_criteria]);
 out:
 	if (!err && ac->ac_status != AC_STATUS_FOUND && first_err)
 		err = first_err;
@@ -2538,6 +2543,8 @@
 		sizeof(struct ext4_group_info);
 
 	grinfo = ext4_get_group_info(sb, group);
+	if (!grinfo)
+		return 0;
 	/* Load the group info in memory only if not already loaded. */
 	if (unlikely(EXT4_MB_GRP_NEED_INIT(grinfo))) {
 		err = ext4_mb_load_buddy(sb, group, &e4b);
@@ -2548,7 +2555,7 @@
 		buddy_loaded = 1;
 	}
 
-	memcpy(&sg, ext4_get_group_info(sb, group), i);
+	memcpy(&sg, grinfo, i);
 
 	if (buddy_loaded)
 		ext4_mb_unload_buddy(&e4b);
@@ -2573,6 +2580,67 @@
 	.stop   = ext4_mb_seq_groups_stop,
 	.show   = ext4_mb_seq_groups_show,
 };
+
+int ext4_seq_mb_stats_show(struct seq_file *seq, void *offset)
+{
+	struct super_block *sb = (struct super_block *)seq->private;
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+	seq_puts(seq, "mballoc:\n");
+	if (!sbi->s_mb_stats) {
+		seq_puts(seq, "\tmb stats collection turned off.\n");
+		seq_puts(seq, "\tTo enable, please write \"1\" to sysfs file mb_stats.\n");
+		return 0;
+	}
+	seq_printf(seq, "\treqs: %u\n", atomic_read(&sbi->s_bal_reqs));
+	seq_printf(seq, "\tsuccess: %u\n", atomic_read(&sbi->s_bal_success));
+
+	seq_printf(seq, "\tgroups_scanned: %u\n",  atomic_read(&sbi->s_bal_groups_scanned));
+
+	seq_puts(seq, "\tcr0_stats:\n");
+	seq_printf(seq, "\t\thits: %llu\n", atomic64_read(&sbi->s_bal_cX_hits[0]));
+	seq_printf(seq, "\t\tgroups_considered: %llu\n",
+		   atomic64_read(&sbi->s_bal_cX_groups_considered[0]));
+	seq_printf(seq, "\t\tuseless_loops: %llu\n",
+		   atomic64_read(&sbi->s_bal_cX_failed[0]));
+
+	seq_puts(seq, "\tcr1_stats:\n");
+	seq_printf(seq, "\t\thits: %llu\n", atomic64_read(&sbi->s_bal_cX_hits[1]));
+	seq_printf(seq, "\t\tgroups_considered: %llu\n",
+		   atomic64_read(&sbi->s_bal_cX_groups_considered[1]));
+	seq_printf(seq, "\t\tuseless_loops: %llu\n",
+		   atomic64_read(&sbi->s_bal_cX_failed[1]));
+
+	seq_puts(seq, "\tcr2_stats:\n");
+	seq_printf(seq, "\t\thits: %llu\n", atomic64_read(&sbi->s_bal_cX_hits[2]));
+	seq_printf(seq, "\t\tgroups_considered: %llu\n",
+		   atomic64_read(&sbi->s_bal_cX_groups_considered[2]));
+	seq_printf(seq, "\t\tuseless_loops: %llu\n",
+		   atomic64_read(&sbi->s_bal_cX_failed[2]));
+
+	seq_puts(seq, "\tcr3_stats:\n");
+	seq_printf(seq, "\t\thits: %llu\n", atomic64_read(&sbi->s_bal_cX_hits[3]));
+	seq_printf(seq, "\t\tgroups_considered: %llu\n",
+		   atomic64_read(&sbi->s_bal_cX_groups_considered[3]));
+	seq_printf(seq, "\t\tuseless_loops: %llu\n",
+		   atomic64_read(&sbi->s_bal_cX_failed[3]));
+	seq_printf(seq, "\textents_scanned: %u\n", atomic_read(&sbi->s_bal_ex_scanned));
+	seq_printf(seq, "\t\tgoal_hits: %u\n", atomic_read(&sbi->s_bal_goals));
+	seq_printf(seq, "\t\t2^n_hits: %u\n", atomic_read(&sbi->s_bal_2orders));
+	seq_printf(seq, "\t\tbreaks: %u\n", atomic_read(&sbi->s_bal_breaks));
+	seq_printf(seq, "\t\tlost: %u\n", atomic_read(&sbi->s_mb_lost_chunks));
+
+	seq_printf(seq, "\tbuddies_generated: %u/%u\n",
+		   atomic_read(&sbi->s_mb_buddies_generated),
+		   ext4_get_groups_count(sb));
+	seq_printf(seq, "\tbuddies_time_used: %llu\n",
+		   atomic64_read(&sbi->s_mb_generation_time));
+	seq_printf(seq, "\tpreallocated: %u\n",
+		   atomic_read(&sbi->s_mb_preallocated));
+	seq_printf(seq, "\tdiscarded: %u\n",
+		   atomic_read(&sbi->s_mb_discarded));
+	return 0;
+}
 
 static struct kmem_cache *get_groupinfo_cache(int blocksize_bits)
 {
@@ -2764,8 +2832,12 @@
 
 err_freebuddy:
 	cachep = get_groupinfo_cache(sb->s_blocksize_bits);
-	while (i-- > 0)
-		kmem_cache_free(cachep, ext4_get_group_info(sb, i));
+	while (i-- > 0) {
+		struct ext4_group_info *grp = ext4_get_group_info(sb, i);
+
+		if (grp)
+			kmem_cache_free(cachep, grp);
+	}
 	i = sbi->s_group_info_size;
 	rcu_read_lock();
 	group_info = rcu_dereference(sbi->s_group_info);
@@ -2874,7 +2946,6 @@
 	} while (i <= sb->s_blocksize_bits + 1);
 
 	spin_lock_init(&sbi->s_md_lock);
-	spin_lock_init(&sbi->s_bal_lock);
 	sbi->s_mb_free_pending = 0;
 	INIT_LIST_HEAD(&sbi->s_freed_data_list);
 
@@ -2973,6 +3044,8 @@
 		for (i = 0; i < ngroups; i++) {
 			cond_resched();
 			grinfo = ext4_get_group_info(sb, i);
+			if (!grinfo)
+				continue;
 			mb_group_bb_bitmap_free(grinfo);
 			ext4_lock_group(sb, i);
 			count = ext4_mb_cleanup_pa(grinfo);
@@ -3002,17 +3075,18 @@
 				atomic_read(&sbi->s_bal_reqs),
 				atomic_read(&sbi->s_bal_success));
 		ext4_msg(sb, KERN_INFO,
-		      "mballoc: %u extents scanned, %u goal hits, "
+		      "mballoc: %u extents scanned, %u groups scanned, %u goal hits, "
 				"%u 2^N hits, %u breaks, %u lost",
 				atomic_read(&sbi->s_bal_ex_scanned),
+				atomic_read(&sbi->s_bal_groups_scanned),
 				atomic_read(&sbi->s_bal_goals),
 				atomic_read(&sbi->s_bal_2orders),
 				atomic_read(&sbi->s_bal_breaks),
 				atomic_read(&sbi->s_mb_lost_chunks));
 		ext4_msg(sb, KERN_INFO,
-		       "mballoc: %lu generated and it took %Lu",
-				sbi->s_mb_buddies_generated,
-				sbi->s_mb_generation_time);
+		       "mballoc: %u generated and it took %llu",
+				atomic_read(&sbi->s_mb_buddies_generated),
+				atomic64_read(&sbi->s_mb_generation_time));
 		ext4_msg(sb, KERN_INFO,
 		       "mballoc: %u preallocated, %u discarded",
 				atomic_read(&sbi->s_mb_preallocated),
@@ -3439,6 +3513,7 @@
 				struct ext4_allocation_request *ar)
 {
 	struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
+	struct ext4_super_block *es = sbi->s_es;
 	int bsbits, max;
 	ext4_lblk_t end;
 	loff_t size, start_off;
@@ -3619,18 +3694,21 @@
 	ac->ac_g_ex.fe_len = EXT4_NUM_B2C(sbi, size);
 
 	/* define goal start in order to merge */
-	if (ar->pright && (ar->lright == (start + size))) {
+	if (ar->pright && (ar->lright == (start + size)) &&
+	    ar->pright >= size &&
+	    ar->pright - size >= le32_to_cpu(es->s_first_data_block)) {
 		/* merge to the right */
 		ext4_get_group_no_and_offset(ac->ac_sb, ar->pright - size,
-						&ac->ac_f_ex.fe_group,
-						&ac->ac_f_ex.fe_start);
+						&ac->ac_g_ex.fe_group,
+						&ac->ac_g_ex.fe_start);
 		ac->ac_flags |= EXT4_MB_HINT_TRY_GOAL;
 	}
-	if (ar->pleft && (ar->lleft + 1 == start)) {
+	if (ar->pleft && (ar->lleft + 1 == start) &&
+	    ar->pleft + 1 < ext4_blocks_count(es)) {
 		/* merge to the left */
 		ext4_get_group_no_and_offset(ac->ac_sb, ar->pleft + 1,
-						&ac->ac_f_ex.fe_group,
-						&ac->ac_f_ex.fe_start);
+						&ac->ac_g_ex.fe_group,
+						&ac->ac_g_ex.fe_start);
 		ac->ac_flags |= EXT4_MB_HINT_TRY_GOAL;
 	}
 
@@ -3642,12 +3720,13 @@
 {
 	struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
 
-	if (sbi->s_mb_stats && ac->ac_g_ex.fe_len > 1) {
+	if (sbi->s_mb_stats && ac->ac_g_ex.fe_len >= 1) {
 		atomic_inc(&sbi->s_bal_reqs);
 		atomic_add(ac->ac_b_ex.fe_len, &sbi->s_bal_allocated);
 		if (ac->ac_b_ex.fe_len >= ac->ac_o_ex.fe_len)
 			atomic_inc(&sbi->s_bal_success);
 		atomic_add(ac->ac_found, &sbi->s_bal_ex_scanned);
+		atomic_add(ac->ac_groups_scanned, &sbi->s_bal_groups_scanned);
 		if (ac->ac_g_ex.fe_start == ac->ac_b_ex.fe_start &&
 				ac->ac_g_ex.fe_group == ac->ac_b_ex.fe_group)
 			atomic_inc(&sbi->s_bal_goals);
@@ -3722,6 +3801,7 @@
 	BUG_ON(start < pa->pa_pstart);
 	BUG_ON(end > pa->pa_pstart + EXT4_C2B(sbi, pa->pa_len));
 	BUG_ON(pa->pa_free < len);
+	BUG_ON(ac->ac_b_ex.fe_len <= 0);
 	pa->pa_free -= len;
 
 	mb_debug(ac->ac_sb, "use %llu/%d from inode pa %p\n", start, len, pa);
@@ -3884,6 +3964,8 @@
 	struct ext4_free_data *entry;
 
 	grp = ext4_get_group_info(sb, group);
+	if (!grp)
+		return;
 	n = rb_first(&(grp->bb_free_root));
 
 	while (n) {
@@ -3910,6 +3992,9 @@
 	ext4_grpblk_t start;
 	int preallocated = 0;
 	int len;
+
+	if (!grp)
+		return;
 
 	/* all form of preallocation discards first load group,
 	 * so the only competing code is preallocation use.
@@ -4046,10 +4131,8 @@
 	pa = ac->ac_pa;
 
 	if (ac->ac_b_ex.fe_len < ac->ac_g_ex.fe_len) {
-		int winl;
-		int wins;
-		int win;
-		int offs;
+		int new_bex_start;
+		int new_bex_end;
 
 		/* we can't allocate as much as normalizer wants.
 		 * so, found space must get proper lstart
@@ -4057,26 +4140,40 @@
 		BUG_ON(ac->ac_g_ex.fe_logical > ac->ac_o_ex.fe_logical);
 		BUG_ON(ac->ac_g_ex.fe_len < ac->ac_o_ex.fe_len);
 
-		/* we're limited by original request in that
-		 * logical block must be covered any way
-		 * winl is window we can move our chunk within */
-		winl = ac->ac_o_ex.fe_logical - ac->ac_g_ex.fe_logical;
+		/*
+		 * Use the below logic for adjusting best extent as it keeps
+		 * fragmentation in check while ensuring logical range of best
+		 * extent doesn't overflow out of goal extent:
+		 *
+		 * 1. Check if best ex can be kept at end of goal and still
+		 *    cover original start
+		 * 2. Else, check if best ex can be kept at start of goal and
+		 *    still cover original start
+		 * 3. Else, keep the best ex at start of original request.
+		 */
+		new_bex_end = ac->ac_g_ex.fe_logical +
+			EXT4_C2B(sbi, ac->ac_g_ex.fe_len);
+		new_bex_start = new_bex_end - EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
+		if (ac->ac_o_ex.fe_logical >= new_bex_start)
+			goto adjust_bex;
 
-		/* also, we should cover whole original request */
-		wins = EXT4_C2B(sbi, ac->ac_b_ex.fe_len - ac->ac_o_ex.fe_len);
+		new_bex_start = ac->ac_g_ex.fe_logical;
+		new_bex_end =
+			new_bex_start + EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
+		if (ac->ac_o_ex.fe_logical < new_bex_end)
+			goto adjust_bex;
 
-		/* the smallest one defines real window */
-		win = min(winl, wins);
+		new_bex_start = ac->ac_o_ex.fe_logical;
+		new_bex_end =
+			new_bex_start + EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
 
-		offs = ac->ac_o_ex.fe_logical %
-			EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
-		if (offs && offs < win)
-			win = offs;
+adjust_bex:
+		ac->ac_b_ex.fe_logical = new_bex_start;
 
-		ac->ac_b_ex.fe_logical = ac->ac_o_ex.fe_logical -
-			EXT4_NUM_B2C(sbi, win);
 		BUG_ON(ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical);
 		BUG_ON(ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len);
+		BUG_ON(new_bex_end > (ac->ac_g_ex.fe_logical +
+				      EXT4_C2B(sbi, ac->ac_g_ex.fe_len)));
 	}
 
 	/* preallocation can change ac_b_ex, thus we store actually
@@ -4102,6 +4199,8 @@
 
 	ei = EXT4_I(ac->ac_inode);
 	grp = ext4_get_group_info(sb, ac->ac_b_ex.fe_group);
+	if (!grp)
+		return;
 
 	pa->pa_obj_lock = &ei->i_prealloc_lock;
 	pa->pa_inode = ac->ac_inode;
@@ -4155,6 +4254,8 @@
 	atomic_add(pa->pa_free, &EXT4_SB(sb)->s_mb_preallocated);
 
 	grp = ext4_get_group_info(sb, ac->ac_b_ex.fe_group);
+	if (!grp)
+		return;
 	lg = ac->ac_lg;
 	BUG_ON(lg == NULL);
 
@@ -4250,7 +4351,11 @@
 	trace_ext4_mb_release_group_pa(sb, pa);
 	BUG_ON(pa->pa_deleted == 0);
 	ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit);
-	BUG_ON(group != e4b->bd_group && pa->pa_len != 0);
+	if (unlikely(group != e4b->bd_group && pa->pa_len != 0)) {
+		ext4_warning(sb, "bad group: expected %u, group %u, pa_start %llu",
+			     e4b->bd_group, group, pa->pa_pstart);
+		return 0;
+	}
 	mb_free_blocks(pa->pa_inode, e4b, bit, pa->pa_len);
 	atomic_add(pa->pa_len, &EXT4_SB(sb)->s_mb_discarded);
 	trace_ext4_mballoc_discard(sb, NULL, group, bit, pa->pa_len);
@@ -4279,6 +4384,8 @@
 	int err;
 	int free = 0;
 
+	if (!grp)
+		return 0;
 	mb_debug(sb, "discard preallocation for group %u\n", group);
 	if (list_empty(&grp->bb_prealloc_list))
 		goto out_dbg;
@@ -4516,6 +4623,9 @@
 		struct ext4_prealloc_space *pa;
 		ext4_grpblk_t start;
 		struct list_head *cur;
+
+		if (!grp)
+			continue;
 		ext4_lock_group(sb, i);
 		list_for_each(cur, &grp->bb_prealloc_list) {
 			pa = list_entry(cur, struct ext4_prealloc_space,
@@ -5303,7 +5413,8 @@
 }
 
 /**
- * ext4_free_blocks() -- Free given blocks and update quota
+ * ext4_mb_clear_bb() -- helper function for freeing blocks.
+ *			Used by ext4_free_blocks()
  * @handle:		handle for this transaction
  * @inode:		inode
  * @bh:			optional buffer of the block to be freed
@@ -5311,13 +5422,14 @@
  * @count:		number of blocks to be freed
  * @flags:		flags used by ext4_free_blocks
  */
-void ext4_free_blocks(handle_t *handle, struct inode *inode,
-		      struct buffer_head *bh, ext4_fsblk_t block,
-		      unsigned long count, int flags)
+static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
+			       ext4_fsblk_t block, unsigned long count,
+			       int flags)
 {
 	struct buffer_head *bitmap_bh = NULL;
 	struct super_block *sb = inode->i_sb;
 	struct ext4_group_desc *gdp;
+	struct ext4_group_info *grp;
 	unsigned int overflow;
 	ext4_grpblk_t bit;
 	struct buffer_head *gd_bh;
@@ -5330,86 +5442,21 @@
 
 	sbi = EXT4_SB(sb);
 
-	if (sbi->s_mount_state & EXT4_FC_REPLAY) {
-		ext4_free_blocks_simple(inode, block, count);
-		return;
-	}
-
-	might_sleep();
-	if (bh) {
-		if (block)
-			BUG_ON(block != bh->b_blocknr);
-		else
-			block = bh->b_blocknr;
-	}
-
 	if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) &&
 	    !ext4_inode_block_valid(inode, block, count)) {
-		ext4_error(sb, "Freeing blocks not in datazone - "
-			   "block = %llu, count = %lu", block, count);
+		ext4_error(sb, "Freeing blocks in system zone - "
+			   "Block = %llu, count = %lu", block, count);
+		/* err = 0. ext4_std_error should be a no op */
 		goto error_return;
 	}
-
-	ext4_debug("freeing block %llu\n", block);
-	trace_ext4_free_blocks(inode, block, count, flags);
-
-	if (bh && (flags & EXT4_FREE_BLOCKS_FORGET)) {
-		BUG_ON(count > 1);
-
-		ext4_forget(handle, flags & EXT4_FREE_BLOCKS_METADATA,
-			    inode, bh, block);
-	}
-
-	/*
-	 * If the extent to be freed does not begin on a cluster
-	 * boundary, we need to deal with partial clusters at the
-	 * beginning and end of the extent.  Normally we will free
-	 * blocks at the beginning or the end unless we are explicitly
-	 * requested to avoid doing so.
-	 */
-	overflow = EXT4_PBLK_COFF(sbi, block);
-	if (overflow) {
-		if (flags & EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER) {
-			overflow = sbi->s_cluster_ratio - overflow;
-			block += overflow;
-			if (count > overflow)
-				count -= overflow;
-			else
-				return;
-		} else {
-			block -= overflow;
-			count += overflow;
-		}
-	}
-	overflow = EXT4_LBLK_COFF(sbi, count);
-	if (overflow) {
-		if (flags & EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER) {
-			if (count > overflow)
-				count -= overflow;
-			else
-				return;
-		} else
-			count += sbi->s_cluster_ratio - overflow;
-	}
-
-	if (!bh && (flags & EXT4_FREE_BLOCKS_FORGET)) {
-		int i;
-		int is_metadata = flags & EXT4_FREE_BLOCKS_METADATA;
-
-		for (i = 0; i < count; i++) {
-			cond_resched();
-			if (is_metadata)
-				bh = sb_find_get_block(inode->i_sb, block + i);
-			ext4_forget(handle, is_metadata, inode, bh, block + i);
-		}
-	}
+	flags |= EXT4_FREE_BLOCKS_VALIDATED;
 
 do_more:
 	overflow = 0;
 	ext4_get_group_no_and_offset(sb, block, &block_group, &bit);
 
-	if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(
-			ext4_get_group_info(sb, block_group))))
+	grp = ext4_get_group_info(sb, block_group);
+	if (unlikely(!grp || EXT4_MB_GRP_BBITMAP_CORRUPT(grp)))
 		return;
 
 	/*
@@ -5420,6 +5467,8 @@
 		overflow = EXT4_C2B(sbi, bit) + count -
 			EXT4_BLOCKS_PER_GROUP(sb);
 		count -= overflow;
+		/* The range changed so it's no longer validated */
+		flags &= ~EXT4_FREE_BLOCKS_VALIDATED;
 	}
 	count_clusters = EXT4_NUM_B2C(sbi, count);
 	bitmap_bh = ext4_read_block_bitmap(sb, block_group);
@@ -5434,13 +5483,8 @@
 		goto error_return;
 	}
 
-	if (in_range(ext4_block_bitmap(sb, gdp), block, count) ||
-	    in_range(ext4_inode_bitmap(sb, gdp), block, count) ||
-	    in_range(block, ext4_inode_table(sb, gdp),
-		     sbi->s_itb_per_group) ||
-	    in_range(block + count - 1, ext4_inode_table(sb, gdp),
-		     sbi->s_itb_per_group)) {
-
+	if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) &&
+	    !ext4_inode_block_valid(inode, block, count)) {
 		ext4_error(sb, "Freeing blocks in system zone - "
 			   "Block = %llu, count = %lu", block, count);
 		/* err = 0. ext4_std_error should be a no op */
@@ -5506,11 +5550,11 @@
 		 * them with group lock_held
 		 */
 		if (test_opt(sb, DISCARD)) {
-			err = ext4_issue_discard(sb, block_group, bit, count,
-						 NULL);
+			err = ext4_issue_discard(sb, block_group, bit,
+						 count_clusters, NULL);
 			if (err && err != -EOPNOTSUPP)
 				ext4_msg(sb, KERN_WARNING, "discard request in"
-					 " group:%d block:%d count:%lu failed"
+					 " group:%u block:%d count:%lu failed"
 					 " with %d", block_group, bit, count,
 					 err);
 		} else
@@ -5562,11 +5606,116 @@
 		block += count;
 		count = overflow;
 		put_bh(bitmap_bh);
+		/* The range changed so it's no longer validated */
+		flags &= ~EXT4_FREE_BLOCKS_VALIDATED;
 		goto do_more;
 	}
 error_return:
 	brelse(bitmap_bh);
 	ext4_std_error(sb, err);
+	return;
+}
+
+/**
+ * ext4_free_blocks() -- Free given blocks and update quota
+ * @handle:		handle for this transaction
+ * @inode:		inode
+ * @bh:			optional buffer of the block to be freed
+ * @block:		starting physical block to be freed
+ * @count:		number of blocks to be freed
+ * @flags:		flags used by ext4_free_blocks
+ */
+void ext4_free_blocks(handle_t *handle, struct inode *inode,
+		      struct buffer_head *bh, ext4_fsblk_t block,
+		      unsigned long count, int flags)
+{
+	struct super_block *sb = inode->i_sb;
+	unsigned int overflow;
+	struct ext4_sb_info *sbi;
+
+	sbi = EXT4_SB(sb);
+
+	if (bh) {
+		if (block)
+			BUG_ON(block != bh->b_blocknr);
+		else
+			block = bh->b_blocknr;
+	}
+
+	if (sbi->s_mount_state & EXT4_FC_REPLAY) {
+		ext4_free_blocks_simple(inode, block, EXT4_NUM_B2C(sbi, count));
+		return;
+	}
+
+	might_sleep();
+
+	if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) &&
+	    !ext4_inode_block_valid(inode, block, count)) {
+		ext4_error(sb, "Freeing blocks not in datazone - "
+			   "block = %llu, count = %lu", block, count);
+		return;
+	}
+	flags |= EXT4_FREE_BLOCKS_VALIDATED;
+
+	ext4_debug("freeing block %llu\n", block);
+	trace_ext4_free_blocks(inode, block, count, flags);
+
+	if (bh && (flags & EXT4_FREE_BLOCKS_FORGET)) {
+		BUG_ON(count > 1);
+
+		ext4_forget(handle, flags & EXT4_FREE_BLOCKS_METADATA,
+			    inode, bh, block);
+	}
+
+	/*
+	 * If the extent to be freed does not begin on a cluster
+	 * boundary, we need to deal with partial clusters at the
+	 * beginning and end of the extent.  Normally we will free
+	 * blocks at the beginning or the end unless we are explicitly
+	 * requested to avoid doing so.
+	 */
+	overflow = EXT4_PBLK_COFF(sbi, block);
+	if (overflow) {
+		if (flags & EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER) {
+			overflow = sbi->s_cluster_ratio - overflow;
+			block += overflow;
+			if (count > overflow)
+				count -= overflow;
+			else
+				return;
+		} else {
+			block -= overflow;
+			count += overflow;
+		}
+		/* The range changed so it's no longer validated */
+		flags &= ~EXT4_FREE_BLOCKS_VALIDATED;
+	}
+	overflow = EXT4_LBLK_COFF(sbi, count);
+	if (overflow) {
+		if (flags & EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER) {
+			if (count > overflow)
+				count -= overflow;
+			else
+				return;
+		} else
+			count += sbi->s_cluster_ratio - overflow;
+		/* The range changed so it's no longer validated */
+		flags &= ~EXT4_FREE_BLOCKS_VALIDATED;
+	}
+
+	if (!bh && (flags & EXT4_FREE_BLOCKS_FORGET)) {
+		int i;
+		int is_metadata = flags & EXT4_FREE_BLOCKS_METADATA;
+
+		for (i = 0; i < count; i++) {
+			cond_resched();
+			if (is_metadata)
+				bh = sb_find_get_block(inode->i_sb, block + i);
+			ext4_forget(handle, is_metadata, inode, bh, block + i);
+		}
+	}
+
+	ext4_mb_clear_bb(handle, inode, block, count, flags);
 	return;
 }
 
@@ -5626,11 +5775,7 @@
 		goto error_return;
 	}
 
-	if (in_range(ext4_block_bitmap(sb, desc), block, count) ||
-	    in_range(ext4_inode_bitmap(sb, desc), block, count) ||
-	    in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) ||
-	    in_range(block + count - 1, ext4_inode_table(sb, desc),
-		     sbi->s_itb_per_group)) {
+	if (!ext4_sb_block_valid(sb, NULL, block, count)) {
 		ext4_error(sb, "Adding blocks in system zones - "
 			   "Block = %llu, count = %lu",
 			   block, count);
@@ -5715,19 +5860,19 @@
  * @sb:		super block for the file system
  * @start:	starting block of the free extent in the alloc. group
  * @count:	number of blocks to TRIM
- * @group:	alloc. group we are working with
  * @e4b:	ext4 buddy for the group
  *
  * Trim "count" blocks starting at "start" in the "group". To assure that no
  * one will allocate those blocks, mark it as used in buddy bitmap. This must
  * be called with under the group lock.
  */
-static int ext4_trim_extent(struct super_block *sb, int start, int count,
-			     ext4_group_t group, struct ext4_buddy *e4b)
+static int ext4_trim_extent(struct super_block *sb,
+		int start, int count, struct ext4_buddy *e4b)
 __releases(bitlock)
 __acquires(bitlock)
 {
 	struct ext4_free_extent ex;
+	ext4_group_t group = e4b->bd_group;
 	int ret = 0;
 
 	trace_ext4_trim_extent(sb, group, start, count);
@@ -5748,6 +5893,71 @@
 	ext4_lock_group(sb, group);
 	mb_free_blocks(NULL, e4b, start, ex.fe_len);
 	return ret;
+}
+
+static ext4_grpblk_t ext4_last_grp_cluster(struct super_block *sb,
+					   ext4_group_t grp)
+{
+	if (grp < ext4_get_groups_count(sb))
+		return EXT4_CLUSTERS_PER_GROUP(sb) - 1;
+	return (ext4_blocks_count(EXT4_SB(sb)->s_es) -
+		ext4_group_first_block_no(sb, grp) - 1) >>
+					EXT4_CLUSTER_BITS(sb);
+}
+
+static bool ext4_trim_interrupted(void)
+{
+	return fatal_signal_pending(current) || freezing(current);
+}
+
+static int ext4_try_to_trim_range(struct super_block *sb,
+		struct ext4_buddy *e4b, ext4_grpblk_t start,
+		ext4_grpblk_t max, ext4_grpblk_t minblocks)
+{
+	ext4_grpblk_t next, count, free_count;
+	bool set_trimmed = false;
+	void *bitmap;
+
+	bitmap = e4b->bd_bitmap;
+	if (start == 0 && max >= ext4_last_grp_cluster(sb, e4b->bd_group))
+		set_trimmed = true;
+	start = max(e4b->bd_info->bb_first_free, start);
+	count = 0;
+	free_count = 0;
+
+	while (start <= max) {
+		start = mb_find_next_zero_bit(bitmap, max + 1, start);
+		if (start > max)
+			break;
+		next = mb_find_next_bit(bitmap, max + 1, start);
+
+		if ((next - start) >= minblocks) {
+			int ret = ext4_trim_extent(sb, start, next - start, e4b);
+
+			if (ret && ret != -EOPNOTSUPP)
+				return count;
+			count += next - start;
+		}
+		free_count += next - start;
+		start = next + 1;
+
+		if (ext4_trim_interrupted())
+			return count;
+
+		if (need_resched()) {
+			ext4_unlock_group(sb, e4b->bd_group);
+			cond_resched();
+			ext4_lock_group(sb, e4b->bd_group);
+		}
+
+		if ((e4b->bd_info->bb_free - free_count) < minblocks)
+			break;
+	}
+
+	if (set_trimmed)
+		EXT4_MB_GRP_SET_TRIMMED(e4b->bd_info);
+
+	return count;
 }
 
 /**
@@ -5773,10 +5983,8 @@
 		   ext4_grpblk_t start, ext4_grpblk_t max,
 		   ext4_grpblk_t minblocks)
 {
-	void *bitmap;
-	ext4_grpblk_t next, count = 0, free_count = 0;
 	struct ext4_buddy e4b;
-	int ret = 0;
+	int ret;
 
 	trace_ext4_trim_all_free(sb, group, start, max);
 
@@ -5786,58 +5994,20 @@
 			     ret, group);
 		return ret;
 	}
-	bitmap = e4b.bd_bitmap;
 
 	ext4_lock_group(sb, group);
-	if (EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) &&
-	    minblocks >= atomic_read(&EXT4_SB(sb)->s_last_trim_minblks))
-		goto out;
 
-	start = (e4b.bd_info->bb_first_free > start) ?
-		e4b.bd_info->bb_first_free : start;
+	if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) ||
+	    minblocks < EXT4_SB(sb)->s_last_trim_minblks)
+		ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks);
+	else
+		ret = 0;
 
-	while (start <= max) {
-		start = mb_find_next_zero_bit(bitmap, max + 1, start);
-		if (start > max)
-			break;
-		next = mb_find_next_bit(bitmap, max + 1, start);
-
-		if ((next - start) >= minblocks) {
-			ret = ext4_trim_extent(sb, start,
-					       next - start, group, &e4b);
-			if (ret && ret != -EOPNOTSUPP)
-				break;
-			ret = 0;
-			count += next - start;
-		}
-		free_count += next - start;
-		start = next + 1;
-
-		if (fatal_signal_pending(current)) {
-			count = -ERESTARTSYS;
-			break;
-		}
-
-		if (need_resched()) {
-			ext4_unlock_group(sb, group);
-			cond_resched();
-			ext4_lock_group(sb, group);
-		}
-
-		if ((e4b.bd_info->bb_free - free_count) < minblocks)
-			break;
-	}
-
-	if (!ret) {
-		ret = count;
-		EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info);
-	}
-out:
 	ext4_unlock_group(sb, group);
 	ext4_mb_unload_buddy(&e4b);
 
 	ext4_debug("trimmed %d blocks in the group %d\n",
-		count, group);
+		ret, group);
 
 	return ret;
 }
@@ -5882,7 +6052,7 @@
 		if (minlen > EXT4_CLUSTERS_PER_GROUP(sb))
 			goto out;
 	}
-	if (end >= max_blks)
+	if (end >= max_blks - 1)
 		end = max_blks - 1;
 	if (end <= first_data_blk)
 		goto out;
@@ -5899,7 +6069,11 @@
 	end = EXT4_CLUSTERS_PER_GROUP(sb) - 1;
 
 	for (group = first_group; group <= last_group; group++) {
+		if (ext4_trim_interrupted())
+			break;
 		grp = ext4_get_group_info(sb, group);
+		if (!grp)
+			continue;
 		/* We only do this if the grp has never been initialized */
 		if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) {
 			ret = ext4_mb_init_group(sb, group, GFP_NOFS);
@@ -5915,10 +6089,9 @@
 		 */
 		if (group == last_group)
 			end = last_cluster;
-
 		if (grp->bb_free >= minlen) {
 			cnt = ext4_trim_all_free(sb, group, first_cluster,
-						end, minlen);
+						 end, minlen);
 			if (cnt < 0) {
 				ret = cnt;
 				break;
@@ -5934,7 +6107,7 @@
 	}
 
 	if (!ret)
-		atomic_set(&EXT4_SB(sb)->s_last_trim_minblks, minlen);
+		EXT4_SB(sb)->s_last_trim_minblks = minlen;
 
 out:
 	range->len = EXT4_C2B(EXT4_SB(sb), trimmed) << sb->s_blocksize_bits;
@@ -5963,8 +6136,7 @@
 
 	ext4_lock_group(sb, group);
 
-	start = (e4b.bd_info->bb_first_free > start) ?
-		e4b.bd_info->bb_first_free : start;
+	start = max(e4b.bd_info->bb_first_free, start);
 	if (end >= EXT4_CLUSTERS_PER_GROUP(sb))
 		end = EXT4_CLUSTERS_PER_GROUP(sb) - 1;
 
diff --git a/kernel/fs/ext4/mballoc.h b/kernel/fs/ext4/mballoc.h
index e75b474..7be6288 100644
--- a/kernel/fs/ext4/mballoc.h
+++ b/kernel/fs/ext4/mballoc.h
@@ -59,7 +59,7 @@
  * by the stream allocator, which purpose is to pack requests
  * as close each to other as possible to produce smooth I/O traffic
  * We use locality group prealloc space for stream request.
- * We can tune the same via /proc/fs/ext4/<parition>/stream_req
+ * We can tune the same via /proc/fs/ext4/<partition>/stream_req
  */
 #define MB_DEFAULT_STREAM_THRESHOLD	16	/* 64K */
 
diff --git a/kernel/fs/ext4/migrate.c b/kernel/fs/ext4/migrate.c
index 4bfe225..b0ea646 100644
--- a/kernel/fs/ext4/migrate.c
+++ b/kernel/fs/ext4/migrate.c
@@ -32,7 +32,7 @@
 	newext.ee_block = cpu_to_le32(lb->first_block);
 	newext.ee_len   = cpu_to_le16(lb->last_block - lb->first_block + 1);
 	ext4_ext_store_pblock(&newext, lb->first_pblock);
-	/* Locking only for convinience since we are operating on temp inode */
+	/* Locking only for convenience since we are operating on temp inode */
 	down_write(&EXT4_I(inode)->i_data_sem);
 	path = ext4_find_extent(inode, lb->first_block, NULL, 0);
 	if (IS_ERR(path)) {
@@ -43,8 +43,8 @@
 
 	/*
 	 * Calculate the credit needed to inserting this extent
-	 * Since we are doing this in loop we may accumalate extra
-	 * credit. But below we try to not accumalate too much
+	 * Since we are doing this in loop we may accumulate extra
+	 * credit. But below we try to not accumulate too much
 	 * of them by restarting the journal.
 	 */
 	needed = ext4_ext_calc_credits_for_single_extent(inode,
diff --git a/kernel/fs/ext4/mmp.c b/kernel/fs/ext4/mmp.c
index bc364c1..7a9a8ed 100644
--- a/kernel/fs/ext4/mmp.c
+++ b/kernel/fs/ext4/mmp.c
@@ -39,26 +39,34 @@
  * Write the MMP block using REQ_SYNC to try to get the block on-disk
  * faster.
  */
-static int write_mmp_block(struct super_block *sb, struct buffer_head *bh)
+static int write_mmp_block_thawed(struct super_block *sb,
+				  struct buffer_head *bh)
 {
 	struct mmp_struct *mmp = (struct mmp_struct *)(bh->b_data);
 
-	/*
-	 * We protect against freezing so that we don't create dirty buffers
-	 * on frozen filesystem.
-	 */
-	sb_start_write(sb);
 	ext4_mmp_csum_set(sb, mmp);
 	lock_buffer(bh);
 	bh->b_end_io = end_buffer_write_sync;
 	get_bh(bh);
 	submit_bh(REQ_OP_WRITE, REQ_SYNC | REQ_META | REQ_PRIO, bh);
 	wait_on_buffer(bh);
-	sb_end_write(sb);
 	if (unlikely(!buffer_uptodate(bh)))
 		return -EIO;
-
 	return 0;
+}
+
+static int write_mmp_block(struct super_block *sb, struct buffer_head *bh)
+{
+	int err;
+
+	/*
+	 * We protect against freezing so that we don't create dirty buffers
+	 * on frozen filesystem.
+	 */
+	sb_start_write(sb);
+	err = write_mmp_block_thawed(sb, bh);
+	sb_end_write(sb);
+	return err;
 }
 
 /*
@@ -290,6 +298,7 @@
 	if (mmp_block < le32_to_cpu(es->s_first_data_block) ||
 	    mmp_block >= ext4_blocks_count(es)) {
 		ext4_warning(sb, "Invalid MMP block in superblock");
+		retval = -EINVAL;
 		goto failed;
 	}
 
@@ -315,6 +324,7 @@
 
 	if (seq == EXT4_MMP_SEQ_FSCK) {
 		dump_mmp_msg(sb, mmp, "fsck is running on the filesystem");
+		retval = -EBUSY;
 		goto failed;
 	}
 
@@ -328,6 +338,7 @@
 
 	if (schedule_timeout_interruptible(HZ * wait_time) != 0) {
 		ext4_warning(sb, "MMP startup interrupted, failing mount\n");
+		retval = -ETIMEDOUT;
 		goto failed;
 	}
 
@@ -338,6 +349,7 @@
 	if (seq != le32_to_cpu(mmp->mmp_seq)) {
 		dump_mmp_msg(sb, mmp,
 			     "Device is already active on another node.");
+		retval = -EBUSY;
 		goto failed;
 	}
 
@@ -348,7 +360,11 @@
 	seq = mmp_new_seq();
 	mmp->mmp_seq = cpu_to_le32(seq);
 
-	retval = write_mmp_block(sb, bh);
+	/*
+	 * On mount / remount we are protected against fs freezing (by s_umount
+	 * semaphore) and grabbing freeze protection upsets lockdep
+	 */
+	retval = write_mmp_block_thawed(sb, bh);
 	if (retval)
 		goto failed;
 
@@ -357,6 +373,7 @@
 	 */
 	if (schedule_timeout_interruptible(HZ * wait_time) != 0) {
 		ext4_warning(sb, "MMP startup interrupted, failing mount");
+		retval = -ETIMEDOUT;
 		goto failed;
 	}
 
@@ -367,6 +384,7 @@
 	if (seq != le32_to_cpu(mmp->mmp_seq)) {
 		dump_mmp_msg(sb, mmp,
 			     "Device is already active on another node.");
+		retval = -EBUSY;
 		goto failed;
 	}
 
@@ -383,6 +401,7 @@
 		EXT4_SB(sb)->s_mmp_tsk = NULL;
 		ext4_warning(sb, "Unable to create kmmpd thread for %s.",
 			     sb->s_id);
+		retval = -ENOMEM;
 		goto failed;
 	}
 
@@ -390,5 +409,5 @@
 
 failed:
 	brelse(bh);
-	return 1;
+	return retval;
 }
diff --git a/kernel/fs/ext4/namei.c b/kernel/fs/ext4/namei.c
index 6d221fa..1b5e8d5 100644
--- a/kernel/fs/ext4/namei.c
+++ b/kernel/fs/ext4/namei.c
@@ -341,17 +341,17 @@
 						   struct buffer_head *bh)
 {
 	struct ext4_dir_entry_tail *t;
+	int blocksize = EXT4_BLOCK_SIZE(inode->i_sb);
 
 #ifdef PARANOID
 	struct ext4_dir_entry *d, *top;
 
 	d = (struct ext4_dir_entry *)bh->b_data;
 	top = (struct ext4_dir_entry *)(bh->b_data +
-		(EXT4_BLOCK_SIZE(inode->i_sb) -
-		 sizeof(struct ext4_dir_entry_tail)));
-	while (d < top && d->rec_len)
+		(blocksize - sizeof(struct ext4_dir_entry_tail)));
+	while (d < top && ext4_rec_len_from_disk(d->rec_len, blocksize))
 		d = (struct ext4_dir_entry *)(((void *)d) +
-		    le16_to_cpu(d->rec_len));
+		    ext4_rec_len_from_disk(d->rec_len, blocksize));
 
 	if (d != top)
 		return NULL;
@@ -362,7 +362,8 @@
 #endif
 
 	if (t->det_reserved_zero1 ||
-	    le16_to_cpu(t->det_rec_len) != sizeof(struct ext4_dir_entry_tail) ||
+	    (ext4_rec_len_from_disk(t->det_rec_len, blocksize) !=
+	     sizeof(struct ext4_dir_entry_tail)) ||
 	    t->det_reserved_zero2 ||
 	    t->det_reserved_ft != EXT4_FT_DIR_CSUM)
 		return NULL;
@@ -443,13 +444,14 @@
 	struct ext4_dir_entry *dp;
 	struct dx_root_info *root;
 	int count_offset;
+	int blocksize = EXT4_BLOCK_SIZE(inode->i_sb);
+	unsigned int rlen = ext4_rec_len_from_disk(dirent->rec_len, blocksize);
 
-	if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb))
+	if (rlen == blocksize)
 		count_offset = 8;
-	else if (le16_to_cpu(dirent->rec_len) == 12) {
+	else if (rlen == 12) {
 		dp = (struct ext4_dir_entry *)(((void *)dirent) + 12);
-		if (le16_to_cpu(dp->rec_len) !=
-		    EXT4_BLOCK_SIZE(inode->i_sb) - 12)
+		if (ext4_rec_len_from_disk(dp->rec_len, blocksize) != blocksize - 12)
 			return NULL;
 		root = (struct dx_root_info *)(((void *)dp + 12));
 		if (root->reserved_zero ||
@@ -1012,7 +1014,7 @@
 	 * If the hash is 1, then continue only if the next page has a
 	 * continuation hash of any value.  This is used for readdir
 	 * handling.  Otherwise, check to see if the hash matches the
-	 * desired contiuation hash.  If it doesn't, return since
+	 * desired continuation hash.  If it doesn't, return since
 	 * there's no point to read in the successive index pages.
 	 */
 	bhash = dx_get_hash(p->at);
@@ -1299,11 +1301,11 @@
 			map_tail--;
 			map_tail->hash = h.hash;
 			map_tail->offs = ((char *) de - base)>>2;
-			map_tail->size = le16_to_cpu(de->rec_len);
+			map_tail->size = ext4_rec_len_from_disk(de->rec_len,
+								blocksize);
 			count++;
 			cond_resched();
 		}
-		/* XXX: do we need to check rec_len == 0 case? -Chris */
 		de = ext4_next_entry(de, blocksize);
 	}
 	return count;
@@ -1580,11 +1582,10 @@
 					     &has_inline_data);
 		if (lblk)
 			*lblk = 0;
-		if (has_inline_data) {
-			if (inlined)
-				*inlined = 1;
+		if (inlined)
+			*inlined = has_inline_data;
+		if (has_inline_data)
 			goto cleanup_and_exit;
-		}
 	}
 
 	if ((namelen <= 2) && (name[0] == '.') &&
@@ -3343,15 +3344,21 @@
 	return retval;
 }
 
-int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name,
-		  struct inode *inode)
+int __ext4_unlink(struct inode *dir, const struct qstr *d_name,
+		  struct inode *inode,
+		  struct dentry *dentry /* NULL during fast_commit recovery */)
 {
 	int retval = -ENOENT;
 	struct buffer_head *bh;
 	struct ext4_dir_entry_2 *de;
+	handle_t *handle;
 	int skip_remove_dentry = 0;
 	ext4_lblk_t lblk;
 
+	/*
+	 * Keep this outside the transaction; it may have to set up the
+	 * directory's encryption key, which isn't GFP_NOFS-safe.
+	 */
 	bh = ext4_find_entry(dir, d_name, &de, NULL, &lblk);
 	if (IS_ERR(bh))
 		return PTR_ERR(bh);
@@ -3368,7 +3375,14 @@
 		if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY)
 			skip_remove_dentry = 1;
 		else
-			goto out;
+			goto out_bh;
+	}
+
+	handle = ext4_journal_start(dir, EXT4_HT_DIR,
+				    EXT4_DATA_TRANS_BLOCKS(dir->i_sb));
+	if (IS_ERR(handle)) {
+		retval = PTR_ERR(handle);
+		goto out_bh;
 	}
 
 	if (IS_DIRSYNC(dir))
@@ -3377,12 +3391,12 @@
 	if (!skip_remove_dentry) {
 		retval = ext4_delete_entry(handle, dir, de, lblk, bh);
 		if (retval)
-			goto out;
+			goto out_handle;
 		dir->i_ctime = dir->i_mtime = current_time(dir);
 		ext4_update_dx_flag(dir);
 		retval = ext4_mark_inode_dirty(handle, dir);
 		if (retval)
-			goto out;
+			goto out_handle;
 	} else {
 		retval = 0;
 	}
@@ -3395,15 +3409,17 @@
 		ext4_orphan_add(handle, inode);
 	inode->i_ctime = current_time(inode);
 	retval = ext4_mark_inode_dirty(handle, inode);
-
-out:
+	if (dentry && !retval)
+		ext4_fc_track_unlink(handle, dentry);
+out_handle:
+	ext4_journal_stop(handle);
+out_bh:
 	brelse(bh);
 	return retval;
 }
 
 static int ext4_unlink(struct inode *dir, struct dentry *dentry)
 {
-	handle_t *handle;
 	int retval;
 
 	if (unlikely(ext4_forced_shutdown(EXT4_SB(dir->i_sb))))
@@ -3421,16 +3437,7 @@
 	if (retval)
 		goto out_trace;
 
-	handle = ext4_journal_start(dir, EXT4_HT_DIR,
-				    EXT4_DATA_TRANS_BLOCKS(dir->i_sb));
-	if (IS_ERR(handle)) {
-		retval = PTR_ERR(handle);
-		goto out_trace;
-	}
-
-	retval = __ext4_unlink(handle, dir, &dentry->d_name, d_inode(dentry));
-	if (!retval)
-		ext4_fc_track_unlink(handle, dentry);
+	retval = __ext4_unlink(dir, &dentry->d_name, d_inode(dentry), dentry);
 #ifdef CONFIG_UNICODE
 	/* VFS negative dentries are incompatible with Encoding and
 	 * Case-insensitiveness. Eventually we'll want avoid
@@ -3441,8 +3448,6 @@
 	if (IS_CASEFOLDED(dir))
 		d_invalidate(dentry);
 #endif
-	if (handle)
-		ext4_journal_stop(handle);
 
 out_trace:
 	trace_ext4_unlink_exit(dentry, retval);
@@ -3795,8 +3800,8 @@
 	 * so the old->de may no longer valid and need to find it again
 	 * before reset old inode info.
 	 */
-	old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, NULL,
-				 NULL);
+	old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de,
+				 &old.inlined, NULL);
 	if (IS_ERR(old.bh))
 		retval = PTR_ERR(old.bh);
 	if (!old.bh)
@@ -3948,6 +3953,9 @@
 	retval = dquot_initialize(old.dir);
 	if (retval)
 		return retval;
+	retval = dquot_initialize(old.inode);
+	if (retval)
+		return retval;
 	retval = dquot_initialize(new.dir);
 	if (retval)
 		return retval;
@@ -3960,10 +3968,11 @@
 			return retval;
 	}
 
-	old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, NULL,
-				&old.lblk);
+	old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de,
+				 &old.inlined, &old.lblk);
 	if (IS_ERR(old.bh))
 		return PTR_ERR(old.bh);
+
 	/*
 	 *  Check for inode number is _not_ due to possible IO errors.
 	 *  We might rmdir the source, keep it as pwd of some process
@@ -4151,6 +4160,7 @@
 	brelse(old.dir_bh);
 	brelse(old.bh);
 	brelse(new.bh);
+
 	return retval;
 }
 
diff --git a/kernel/fs/ext4/page-io.c b/kernel/fs/ext4/page-io.c
index 4569075..a94cc7b 100644
--- a/kernel/fs/ext4/page-io.c
+++ b/kernel/fs/ext4/page-io.c
@@ -416,7 +416,8 @@
 
 static void io_submit_add_bh(struct ext4_io_submit *io,
 			     struct inode *inode,
-			     struct page *page,
+			     struct page *pagecache_page,
+			     struct page *bounce_page,
 			     struct buffer_head *bh)
 {
 	int ret;
@@ -430,10 +431,11 @@
 		io_submit_init_bio(io, bh);
 		io->io_bio->bi_write_hint = inode->i_write_hint;
 	}
-	ret = bio_add_page(io->io_bio, page, bh->b_size, bh_offset(bh));
+	ret = bio_add_page(io->io_bio, bounce_page ?: pagecache_page,
+			   bh->b_size, bh_offset(bh));
 	if (ret != bh->b_size)
 		goto submit_and_retry;
-	wbc_account_cgroup_owner(io->io_wbc, page, bh->b_size);
+	wbc_account_cgroup_owner(io->io_wbc, pagecache_page, bh->b_size);
 	io->io_next_block++;
 }
 
@@ -551,8 +553,7 @@
 	do {
 		if (!buffer_async_write(bh))
 			continue;
-		io_submit_add_bh(io, inode,
-				 bounce_page ? bounce_page : page, bh);
+		io_submit_add_bh(io, inode, page, bounce_page, bh);
 		nr_submitted++;
 		clear_buffer_dirty(bh);
 	} while ((bh = bh->b_this_page) != head);
diff --git a/kernel/fs/ext4/resize.c b/kernel/fs/ext4/resize.c
index c55ba03..51cebc1 100644
--- a/kernel/fs/ext4/resize.c
+++ b/kernel/fs/ext4/resize.c
@@ -1545,8 +1545,8 @@
 		int meta_bg = ext4_has_feature_meta_bg(sb);
 		sector_t old_gdb = 0;
 
-		update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
-			       sizeof(struct ext4_super_block), 0);
+		update_backups(sb, ext4_group_first_block_no(sb, 0),
+			       (char *)es, sizeof(struct ext4_super_block), 0);
 		for (; gdb_num <= gdb_num_end; gdb_num++) {
 			struct buffer_head *gdb_bh;
 
@@ -1753,7 +1753,7 @@
 		if (test_opt(sb, DEBUG))
 			printk(KERN_DEBUG "EXT4-fs: extended group to %llu "
 			       "blocks\n", ext4_blocks_count(es));
-		update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr,
+		update_backups(sb, ext4_group_first_block_no(sb, 0),
 			       (char *)es, sizeof(struct ext4_super_block), 0);
 	}
 	return err;
diff --git a/kernel/fs/ext4/super.c b/kernel/fs/ext4/super.c
index 8904e21..2c0a592 100644
--- a/kernel/fs/ext4/super.c
+++ b/kernel/fs/ext4/super.c
@@ -417,104 +417,6 @@
 #define ext4_get_tstamp(es, tstamp) \
 	__ext4_get_tstamp(&(es)->tstamp, &(es)->tstamp ## _hi)
 
-static void __save_error_info(struct super_block *sb, int error,
-			      __u32 ino, __u64 block,
-			      const char *func, unsigned int line)
-{
-	struct ext4_super_block *es = EXT4_SB(sb)->s_es;
-	int err;
-
-	EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
-	if (bdev_read_only(sb->s_bdev))
-		return;
-	es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
-	ext4_update_tstamp(es, s_last_error_time);
-	strncpy(es->s_last_error_func, func, sizeof(es->s_last_error_func));
-	es->s_last_error_line = cpu_to_le32(line);
-	es->s_last_error_ino = cpu_to_le32(ino);
-	es->s_last_error_block = cpu_to_le64(block);
-	switch (error) {
-	case EIO:
-		err = EXT4_ERR_EIO;
-		break;
-	case ENOMEM:
-		err = EXT4_ERR_ENOMEM;
-		break;
-	case EFSBADCRC:
-		err = EXT4_ERR_EFSBADCRC;
-		break;
-	case 0:
-	case EFSCORRUPTED:
-		err = EXT4_ERR_EFSCORRUPTED;
-		break;
-	case ENOSPC:
-		err = EXT4_ERR_ENOSPC;
-		break;
-	case ENOKEY:
-		err = EXT4_ERR_ENOKEY;
-		break;
-	case EROFS:
-		err = EXT4_ERR_EROFS;
-		break;
-	case EFBIG:
-		err = EXT4_ERR_EFBIG;
-		break;
-	case EEXIST:
-		err = EXT4_ERR_EEXIST;
-		break;
-	case ERANGE:
-		err = EXT4_ERR_ERANGE;
-		break;
-	case EOVERFLOW:
-		err = EXT4_ERR_EOVERFLOW;
-		break;
-	case EBUSY:
-		err = EXT4_ERR_EBUSY;
-		break;
-	case ENOTDIR:
-		err = EXT4_ERR_ENOTDIR;
-		break;
-	case ENOTEMPTY:
-		err = EXT4_ERR_ENOTEMPTY;
-		break;
-	case ESHUTDOWN:
-		err = EXT4_ERR_ESHUTDOWN;
-		break;
-	case EFAULT:
-		err = EXT4_ERR_EFAULT;
-		break;
-	default:
-		err = EXT4_ERR_UNKNOWN;
-	}
-	es->s_last_error_errcode = err;
-	if (!es->s_first_error_time) {
-		es->s_first_error_time = es->s_last_error_time;
-		es->s_first_error_time_hi = es->s_last_error_time_hi;
-		strncpy(es->s_first_error_func, func,
-			sizeof(es->s_first_error_func));
-		es->s_first_error_line = cpu_to_le32(line);
-		es->s_first_error_ino = es->s_last_error_ino;
-		es->s_first_error_block = es->s_last_error_block;
-		es->s_first_error_errcode = es->s_last_error_errcode;
-	}
-	/*
-	 * Start the daily error reporting function if it hasn't been
-	 * started already
-	 */
-	if (!es->s_error_count)
-		mod_timer(&EXT4_SB(sb)->s_err_report, jiffies + 24*60*60*HZ);
-	le32_add_cpu(&es->s_error_count, 1);
-}
-
-static void save_error_info(struct super_block *sb, int error,
-			    __u32 ino, __u64 block,
-			    const char *func, unsigned int line)
-{
-	__save_error_info(sb, error, ino, block, func, line);
-	if (!bdev_read_only(sb->s_bdev))
-		ext4_commit_super(sb, 1);
-}
-
 /*
  * The del_gendisk() function uninitializes the disk-specific data
  * structures, including the bdi structure, without telling anyone
@@ -641,6 +543,89 @@
 {
 	return system_state == SYSTEM_HALT || system_state == SYSTEM_POWER_OFF
 		|| system_state == SYSTEM_RESTART;
+}
+
+struct ext4_err_translation {
+	int code;
+	int errno;
+};
+
+#define EXT4_ERR_TRANSLATE(err) { .code = EXT4_ERR_##err, .errno = err }
+
+static struct ext4_err_translation err_translation[] = {
+	EXT4_ERR_TRANSLATE(EIO),
+	EXT4_ERR_TRANSLATE(ENOMEM),
+	EXT4_ERR_TRANSLATE(EFSBADCRC),
+	EXT4_ERR_TRANSLATE(EFSCORRUPTED),
+	EXT4_ERR_TRANSLATE(ENOSPC),
+	EXT4_ERR_TRANSLATE(ENOKEY),
+	EXT4_ERR_TRANSLATE(EROFS),
+	EXT4_ERR_TRANSLATE(EFBIG),
+	EXT4_ERR_TRANSLATE(EEXIST),
+	EXT4_ERR_TRANSLATE(ERANGE),
+	EXT4_ERR_TRANSLATE(EOVERFLOW),
+	EXT4_ERR_TRANSLATE(EBUSY),
+	EXT4_ERR_TRANSLATE(ENOTDIR),
+	EXT4_ERR_TRANSLATE(ENOTEMPTY),
+	EXT4_ERR_TRANSLATE(ESHUTDOWN),
+	EXT4_ERR_TRANSLATE(EFAULT),
+};
+
+static int ext4_errno_to_code(int errno)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(err_translation); i++)
+		if (err_translation[i].errno == errno)
+			return err_translation[i].code;
+	return EXT4_ERR_UNKNOWN;
+}
+
+static void __save_error_info(struct super_block *sb, int error,
+			      __u32 ino, __u64 block,
+			      const char *func, unsigned int line)
+{
+	struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+
+	EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
+	if (bdev_read_only(sb->s_bdev))
+		return;
+	/* We default to EFSCORRUPTED error... */
+	if (error == 0)
+		error = EFSCORRUPTED;
+	es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
+	ext4_update_tstamp(es, s_last_error_time);
+	strncpy(es->s_last_error_func, func, sizeof(es->s_last_error_func));
+	es->s_last_error_line = cpu_to_le32(line);
+	es->s_last_error_ino = cpu_to_le32(ino);
+	es->s_last_error_block = cpu_to_le64(block);
+	es->s_last_error_errcode = ext4_errno_to_code(error);
+	if (!es->s_first_error_time) {
+		es->s_first_error_time = es->s_last_error_time;
+		es->s_first_error_time_hi = es->s_last_error_time_hi;
+		strncpy(es->s_first_error_func, func,
+			sizeof(es->s_first_error_func));
+		es->s_first_error_line = cpu_to_le32(line);
+		es->s_first_error_ino = es->s_last_error_ino;
+		es->s_first_error_block = es->s_last_error_block;
+		es->s_first_error_errcode = es->s_last_error_errcode;
+	}
+	/*
+	 * Start the daily error reporting function if it hasn't been
+	 * started already
+	 */
+	if (!es->s_error_count)
+		mod_timer(&EXT4_SB(sb)->s_err_report, jiffies + 24*60*60*HZ);
+	le32_add_cpu(&es->s_error_count, 1);
+}
+
+static void save_error_info(struct super_block *sb, int error,
+			    __u32 ino, __u64 block,
+			    const char *func, unsigned int line)
+{
+	__save_error_info(sb, error, ino, block, func, line);
+	if (!bdev_read_only(sb->s_bdev))
+		ext4_commit_super(sb, 1);
 }
 
 /* Deal with the reporting of failure conditions on a filesystem such as
@@ -1026,6 +1011,8 @@
 	struct ext4_group_desc *gdp = ext4_get_group_desc(sb, group, NULL);
 	int ret;
 
+	if (!grp || !gdp)
+		return;
 	if (flags & EXT4_GROUP_INFO_BBITMAP_CORRUPT) {
 		ret = ext4_test_and_set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT,
 					    &grp->bb_state);
@@ -1104,6 +1091,12 @@
 	struct block_device *bdev;
 	bdev = sbi->s_journal_bdev;
 	if (bdev) {
+		/*
+		 * Invalidate the journal device's buffers.  We don't want them
+		 * floating about in memory - the physical journal device may
+		 * hotswapped, and it breaks the `ro-after' testing code.
+		 */
+		invalidate_bdev(bdev);
 		ext4_blkdev_put(bdev);
 		sbi->s_journal_bdev = NULL;
 	}
@@ -1243,13 +1236,7 @@
 	sync_blockdev(sb->s_bdev);
 	invalidate_bdev(sb->s_bdev);
 	if (sbi->s_journal_bdev && sbi->s_journal_bdev != sb->s_bdev) {
-		/*
-		 * Invalidate the journal device's buffers.  We don't want them
-		 * floating about in memory - the physical journal device may
-		 * hotswapped, and it breaks the `ro-after' testing code.
-		 */
 		sync_blockdev(sbi->s_journal_bdev);
-		invalidate_bdev(sbi->s_journal_bdev);
 		ext4_blkdev_remove(sbi);
 	}
 
@@ -1294,6 +1281,7 @@
 		return NULL;
 
 	inode_set_iversion(&ei->vfs_inode, 1);
+	ei->i_flags = 0;
 	spin_lock_init(&ei->i_raw_lock);
 	INIT_LIST_HEAD(&ei->i_prealloc_list);
 	atomic_set(&ei->i_prealloc_active, 0);
@@ -2845,11 +2833,9 @@
 	crc = crc16(crc, (__u8 *)gdp, offset);
 	offset += sizeof(gdp->bg_checksum); /* skip checksum */
 	/* for checksum of struct ext4_group_desc do the rest...*/
-	if (ext4_has_feature_64bit(sb) &&
-	    offset < le16_to_cpu(sbi->s_es->s_desc_size))
+	if (ext4_has_feature_64bit(sb) && offset < sbi->s_desc_size)
 		crc = crc16(crc, (__u8 *)gdp + offset,
-			    le16_to_cpu(sbi->s_es->s_desc_size) -
-				offset);
+			    sbi->s_desc_size - offset);
 
 out:
 	return cpu_to_le16(crc);
@@ -4787,9 +4773,11 @@
 	needs_recovery = (es->s_last_orphan != 0 ||
 			  ext4_has_feature_journal_needs_recovery(sb));
 
-	if (ext4_has_feature_mmp(sb) && !sb_rdonly(sb))
-		if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block)))
+	if (ext4_has_feature_mmp(sb) && !sb_rdonly(sb)) {
+		err = ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block));
+		if (err)
 			goto failed_mount3a;
+	}
 
 	/*
 	 * The first inode we look at is the journal inode.  Don't try
@@ -4803,30 +4791,31 @@
 		   ext4_has_feature_journal_needs_recovery(sb)) {
 		ext4_msg(sb, KERN_ERR, "required journal recovery "
 		       "suppressed and not mounted read-only");
-		goto failed_mount_wq;
+		goto failed_mount3a;
 	} else {
 		/* Nojournal mode, all journal mount options are illegal */
-		if (test_opt2(sb, EXPLICIT_JOURNAL_CHECKSUM)) {
-			ext4_msg(sb, KERN_ERR, "can't mount with "
-				 "journal_checksum, fs mounted w/o journal");
-			goto failed_mount_wq;
-		}
 		if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) {
 			ext4_msg(sb, KERN_ERR, "can't mount with "
 				 "journal_async_commit, fs mounted w/o journal");
-			goto failed_mount_wq;
+			goto failed_mount3a;
+		}
+
+		if (test_opt2(sb, EXPLICIT_JOURNAL_CHECKSUM)) {
+			ext4_msg(sb, KERN_ERR, "can't mount with "
+				 "journal_checksum, fs mounted w/o journal");
+			goto failed_mount3a;
 		}
 		if (sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) {
 			ext4_msg(sb, KERN_ERR, "can't mount with "
 				 "commit=%lu, fs mounted w/o journal",
 				 sbi->s_commit_interval / HZ);
-			goto failed_mount_wq;
+			goto failed_mount3a;
 		}
 		if (EXT4_MOUNT_DATA_FLAGS &
 		    (sbi->s_mount_opt ^ sbi->s_def_mount_opt)) {
 			ext4_msg(sb, KERN_ERR, "can't mount with "
 				 "data=, fs mounted w/o journal");
-			goto failed_mount_wq;
+			goto failed_mount3a;
 		}
 		sbi->s_def_mount_opt &= ~EXT4_MOUNT_JOURNAL_CHECKSUM;
 		clear_opt(sb, JOURNAL_CHECKSUM);
@@ -5206,6 +5195,7 @@
 	brelse(bh);
 	ext4_blkdev_remove(sbi);
 out_fail:
+	invalidate_bdev(sb->s_bdev);
 	sb->s_fs_info = NULL;
 	kfree(sbi->s_blockgroup_lock);
 out_free_base:
@@ -5265,7 +5255,7 @@
 
 	jbd_debug(2, "Journal inode found at %p: %lld bytes\n",
 		  journal_inode, journal_inode->i_size);
-	if (!S_ISREG(journal_inode->i_mode)) {
+	if (!S_ISREG(journal_inode->i_mode) || IS_ENCRYPTED(journal_inode)) {
 		ext4_msg(sb, KERN_ERR, "invalid journal inode");
 		iput(journal_inode);
 		return NULL;
@@ -5796,11 +5786,11 @@
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	unsigned long old_sb_flags, vfs_flags;
 	struct ext4_mount_options old_opts;
-	int enable_quota = 0;
 	ext4_group_t g;
 	unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
 	int err = 0;
 #ifdef CONFIG_QUOTA
+	int enable_quota = 0;
 	int i, j;
 	char *to_free[EXT4_MAXQUOTAS];
 #endif
@@ -5992,26 +5982,16 @@
 				goto restore_opts;
 
 			sb->s_flags &= ~SB_RDONLY;
-			if (ext4_has_feature_mmp(sb))
-				if (ext4_multi_mount_protect(sb,
-						le64_to_cpu(es->s_mmp_block))) {
-					err = -EROFS;
+			if (ext4_has_feature_mmp(sb)) {
+				err = ext4_multi_mount_protect(sb,
+						le64_to_cpu(es->s_mmp_block));
+				if (err)
 					goto restore_opts;
-				}
+			}
+#ifdef CONFIG_QUOTA
 			enable_quota = 1;
+#endif
 		}
-	}
-
-	/*
-	 * Reinitialize lazy itable initialization thread based on
-	 * current settings
-	 */
-	if (sb_rdonly(sb) || !test_opt(sb, INIT_INODE_TABLE))
-		ext4_unregister_li_request(sb);
-	else {
-		ext4_group_t first_not_zeroed;
-		first_not_zeroed = ext4_has_uninit_itable(sb);
-		ext4_register_li_request(sb, first_not_zeroed);
 	}
 
 	/*
@@ -6032,9 +6012,6 @@
 	}
 
 #ifdef CONFIG_QUOTA
-	/* Release old quota file names */
-	for (i = 0; i < EXT4_MAXQUOTAS; i++)
-		kfree(old_opts.s_qf_names[i]);
 	if (enable_quota) {
 		if (sb_any_quota_suspended(sb))
 			dquot_resume(sb, -1);
@@ -6044,9 +6021,24 @@
 				goto restore_opts;
 		}
 	}
+	/* Release old quota file names */
+	for (i = 0; i < EXT4_MAXQUOTAS; i++)
+		kfree(old_opts.s_qf_names[i]);
 #endif
 	if (!test_opt(sb, BLOCK_VALIDITY) && sbi->s_system_blks)
 		ext4_release_system_zone(sb);
+
+	/*
+	 * Reinitialize lazy itable initialization thread based on
+	 * current settings
+	 */
+	if (sb_rdonly(sb) || !test_opt(sb, INIT_INODE_TABLE))
+		ext4_unregister_li_request(sb);
+	else {
+		ext4_group_t first_not_zeroed;
+		first_not_zeroed = ext4_has_uninit_itable(sb);
+		ext4_register_li_request(sb, first_not_zeroed);
+	}
 
 	if (!ext4_has_feature_mmp(sb) || sb_rdonly(sb))
 		ext4_stop_mmpd(sbi);
@@ -6063,6 +6055,13 @@
 	return 0;
 
 restore_opts:
+	/*
+	 * If there was a failing r/w to ro transition, we may need to
+	 * re-enable quota
+	 */
+	if ((sb->s_flags & SB_RDONLY) && !(old_sb_flags & SB_RDONLY) &&
+	    sb_any_quota_suspended(sb))
+		dquot_resume(sb, -1);
 	sb->s_flags = old_sb_flags;
 	sbi->s_mount_opt = old_opts.s_mount_opt;
 	sbi->s_mount_opt2 = old_opts.s_mount_opt2;
@@ -6374,6 +6373,20 @@
 	return err;
 }
 
+static inline bool ext4_check_quota_inum(int type, unsigned long qf_inum)
+{
+	switch (type) {
+	case USRQUOTA:
+		return qf_inum == EXT4_USR_QUOTA_INO;
+	case GRPQUOTA:
+		return qf_inum == EXT4_GRP_QUOTA_INO;
+	case PRJQUOTA:
+		return qf_inum >= EXT4_GOOD_OLD_FIRST_INO;
+	default:
+		BUG();
+	}
+}
+
 static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
 			     unsigned int flags)
 {
@@ -6390,9 +6403,16 @@
 	if (!qf_inums[type])
 		return -EPERM;
 
+	if (!ext4_check_quota_inum(type, qf_inums[type])) {
+		ext4_error(sb, "Bad quota inum: %lu, type: %d",
+				qf_inums[type], type);
+		return -EUCLEAN;
+	}
+
 	qf_inode = ext4_iget(sb, qf_inums[type], EXT4_IGET_SPECIAL);
 	if (IS_ERR(qf_inode)) {
-		ext4_error(sb, "Bad quota inode # %lu", qf_inums[type]);
+		ext4_error(sb, "Bad quota inode: %lu, type: %d",
+				qf_inums[type], type);
 		return PTR_ERR(qf_inode);
 	}
 
@@ -6431,8 +6451,9 @@
 			if (err) {
 				ext4_warning(sb,
 					"Failed to enable quota tracking "
-					"(type=%d, err=%d). Please run "
-					"e2fsck to fix.", type, err);
+					"(type=%d, err=%d, ino=%lu). "
+					"Please run e2fsck to fix.", type,
+					err, qf_inums[type]);
 				for (type--; type >= 0; type--) {
 					struct inode *inode;
 
diff --git a/kernel/fs/ext4/sysfs.c b/kernel/fs/ext4/sysfs.c
index f24bef3..b0bb4a9 100644
--- a/kernel/fs/ext4/sysfs.c
+++ b/kernel/fs/ext4/sysfs.c
@@ -487,6 +487,11 @@
 	complete(&sbi->s_kobj_unregister);
 }
 
+static void ext4_feat_release(struct kobject *kobj)
+{
+	kfree(kobj);
+}
+
 static const struct sysfs_ops ext4_attr_ops = {
 	.show	= ext4_attr_show,
 	.store	= ext4_attr_store,
@@ -501,7 +506,7 @@
 static struct kobj_type ext4_feat_ktype = {
 	.default_groups = ext4_feat_groups,
 	.sysfs_ops	= &ext4_attr_ops,
-	.release	= (void (*)(struct kobject *))kfree,
+	.release	= ext4_feat_release,
 };
 
 static struct kobject *ext4_root;
@@ -534,6 +539,8 @@
 					ext4_fc_info_show, sb);
 		proc_create_seq_data("mb_groups", S_IRUGO, sbi->s_proc,
 				&ext4_mb_seq_groups_ops, sb);
+		proc_create_single_data("mb_stats", 0444, sbi->s_proc,
+				ext4_seq_mb_stats_show, sb);
 	}
 	return 0;
 }
diff --git a/kernel/fs/ext4/verity.c b/kernel/fs/ext4/verity.c
index 35be8e7..e3019f9 100644
--- a/kernel/fs/ext4/verity.c
+++ b/kernel/fs/ext4/verity.c
@@ -79,8 +79,7 @@
 		size_t n = min_t(size_t, count,
 				 PAGE_SIZE - offset_in_page(pos));
 		struct page *page;
-		void *fsdata;
-		void *addr;
+		void *fsdata = NULL;
 		int res;
 
 		res = pagecache_write_begin(NULL, inode->i_mapping, pos, n, 0,
@@ -88,9 +87,7 @@
 		if (res)
 			return res;
 
-		addr = kmap_atomic(page);
-		memcpy(addr + offset_in_page(pos), buf, n);
-		kunmap_atomic(addr);
+		memcpy_to_page(page, offset_in_page(pos), buf, n);
 
 		res = pagecache_write_end(NULL, inode->i_mapping, pos, n, n,
 					  page, fsdata);
diff --git a/kernel/fs/ext4/xattr.c b/kernel/fs/ext4/xattr.c
index 38531c5..5bf858f 100644
--- a/kernel/fs/ext4/xattr.c
+++ b/kernel/fs/ext4/xattr.c
@@ -123,7 +123,11 @@
 #ifdef CONFIG_LOCKDEP
 void ext4_xattr_inode_set_class(struct inode *ea_inode)
 {
+	struct ext4_inode_info *ei = EXT4_I(ea_inode);
+
 	lockdep_set_subclass(&ea_inode->i_rwsem, 1);
+	(void) ei;	/* shut up clang warning if !CONFIG_LOCKDEP */
+	lockdep_set_subclass(&ei->i_data_sem, I_DATA_SEM_EA);
 }
 #endif
 
@@ -386,7 +390,18 @@
 	struct inode *inode;
 	int err;
 
-	inode = ext4_iget(parent->i_sb, ea_ino, EXT4_IGET_NORMAL);
+	/*
+	 * We have to check for this corruption early as otherwise
+	 * iget_locked() could wait indefinitely for the state of our
+	 * parent inode.
+	 */
+	if (parent->i_ino == ea_ino) {
+		ext4_error(parent->i_sb,
+			   "Parent and EA inode have the same ino %lu", ea_ino);
+		return -EFSCORRUPTED;
+	}
+
+	inode = ext4_iget(parent->i_sb, ea_ino, EXT4_IGET_EA_INODE);
 	if (IS_ERR(inode)) {
 		err = PTR_ERR(inode);
 		ext4_error(parent->i_sb,
@@ -394,23 +409,6 @@
 			   err);
 		return err;
 	}
-
-	if (is_bad_inode(inode)) {
-		ext4_error(parent->i_sb,
-			   "error while reading EA inode %lu is_bad_inode",
-			   ea_ino);
-		err = -EIO;
-		goto error;
-	}
-
-	if (!(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) {
-		ext4_error(parent->i_sb,
-			   "EA inode %lu does not have EXT4_EA_INODE_FL flag",
-			    ea_ino);
-		err = -EINVAL;
-		goto error;
-	}
-
 	ext4_xattr_inode_set_class(inode);
 
 	/*
@@ -431,9 +429,21 @@
 
 	*ea_inode = inode;
 	return 0;
-error:
-	iput(inode);
-	return err;
+}
+
+/* Remove entry from mbcache when EA inode is getting evicted */
+void ext4_evict_ea_inode(struct inode *inode)
+{
+	struct mb_cache_entry *oe;
+
+	if (!EA_INODE_CACHE(inode))
+		return;
+	/* Wait for entry to get unused so that we can remove it */
+	while ((oe = mb_cache_entry_delete_or_get(EA_INODE_CACHE(inode),
+			ext4_xattr_inode_get_hash(inode), inode->i_ino))) {
+		mb_cache_entry_wait_unused(oe);
+		mb_cache_entry_put(EA_INODE_CACHE(inode), oe);
+	}
 }
 
 static int
@@ -972,10 +982,8 @@
 static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
 				       int ref_change)
 {
-	struct mb_cache *ea_inode_cache = EA_INODE_CACHE(ea_inode);
 	struct ext4_iloc iloc;
 	s64 ref_count;
-	u32 hash;
 	int ret;
 
 	inode_lock(ea_inode);
@@ -998,14 +1006,6 @@
 
 			set_nlink(ea_inode, 1);
 			ext4_orphan_del(handle, ea_inode);
-
-			if (ea_inode_cache) {
-				hash = ext4_xattr_inode_get_hash(ea_inode);
-				mb_cache_entry_create(ea_inode_cache,
-						      GFP_NOFS, hash,
-						      ea_inode->i_ino,
-						      true /* reusable */);
-			}
 		}
 	} else {
 		WARN_ONCE(ref_count < 0, "EA inode %lu ref_count=%lld",
@@ -1018,12 +1018,6 @@
 
 			clear_nlink(ea_inode);
 			ext4_orphan_add(handle, ea_inode);
-
-			if (ea_inode_cache) {
-				hash = ext4_xattr_inode_get_hash(ea_inode);
-				mb_cache_entry_delete(ea_inode_cache, hash,
-						      ea_inode->i_ino);
-			}
 		}
 	}
 
@@ -1231,6 +1225,7 @@
 	if (error)
 		goto out;
 
+retry_ref:
 	lock_buffer(bh);
 	hash = le32_to_cpu(BHDR(bh)->h_hash);
 	ref = le32_to_cpu(BHDR(bh)->h_refcount);
@@ -1240,9 +1235,18 @@
 		 * This must happen under buffer lock for
 		 * ext4_xattr_block_set() to reliably detect freed block
 		 */
-		if (ea_block_cache)
-			mb_cache_entry_delete(ea_block_cache, hash,
-					      bh->b_blocknr);
+		if (ea_block_cache) {
+			struct mb_cache_entry *oe;
+
+			oe = mb_cache_entry_delete_or_get(ea_block_cache, hash,
+							  bh->b_blocknr);
+			if (oe) {
+				unlock_buffer(bh);
+				mb_cache_entry_wait_unused(oe);
+				mb_cache_entry_put(ea_block_cache, oe);
+				goto retry_ref;
+			}
+		}
 		get_bh(bh);
 		unlock_buffer(bh);
 
@@ -1266,7 +1270,7 @@
 				ce = mb_cache_entry_get(ea_block_cache, hash,
 							bh->b_blocknr);
 				if (ce) {
-					ce->e_reusable = 1;
+					set_bit(MBE_REUSABLE_B, &ce->e_flags);
 					mb_cache_entry_put(ea_block_cache, ce);
 				}
 			}
@@ -1406,6 +1410,13 @@
 	uid_t owner[2] = { i_uid_read(inode), i_gid_read(inode) };
 	int err;
 
+	if (inode->i_sb->s_root == NULL) {
+		ext4_warning(inode->i_sb,
+			     "refuse to create EA inode when umounting");
+		WARN_ON(1);
+		return ERR_PTR(-EINVAL);
+	}
+
 	/*
 	 * Let the next inode be the goal, so we try and allocate the EA inode
 	 * in the same group, or nearby one.
@@ -1425,6 +1436,9 @@
 		if (!err)
 			err = ext4_inode_attach_jinode(ea_inode);
 		if (err) {
+			if (ext4_xattr_inode_dec_ref(handle, ea_inode))
+				ext4_warning_inode(ea_inode,
+					"cleanup dec ref error %d", err);
 			iput(ea_inode);
 			return ERR_PTR(err);
 		}
@@ -1470,11 +1484,11 @@
 
 	while (ce) {
 		ea_inode = ext4_iget(inode->i_sb, ce->e_value,
-				     EXT4_IGET_NORMAL);
-		if (!IS_ERR(ea_inode) &&
-		    !is_bad_inode(ea_inode) &&
-		    (EXT4_I(ea_inode)->i_flags & EXT4_EA_INODE_FL) &&
-		    i_size_read(ea_inode) == value_len &&
+				     EXT4_IGET_EA_INODE);
+		if (IS_ERR(ea_inode))
+			goto next_entry;
+		ext4_xattr_inode_set_class(ea_inode);
+		if (i_size_read(ea_inode) == value_len &&
 		    !ext4_xattr_inode_read(ea_inode, ea_data, value_len) &&
 		    !ext4_xattr_inode_verify_hashes(ea_inode, NULL, ea_data,
 						    value_len) &&
@@ -1484,9 +1498,8 @@
 			kvfree(ea_data);
 			return ea_inode;
 		}
-
-		if (!IS_ERR(ea_inode))
-			iput(ea_inode);
+		iput(ea_inode);
+	next_entry:
 		ce = mb_cache_entry_find_next(ea_inode_cache, ce);
 	}
 	kvfree(ea_data);
@@ -1614,7 +1627,7 @@
 		 * If storing the value in an external inode is an option,
 		 * reserve space for xattr entries/names in the external
 		 * attribute block so that a long value does not occupy the
-		 * whole space and prevent futher entries being added.
+		 * whole space and prevent further entries being added.
 		 */
 		if (ext4_has_feature_ea_inode(inode->i_sb) &&
 		    new_size && is_block &&
@@ -1712,6 +1725,20 @@
 		memmove(here, (void *)here + size,
 			(void *)last - (void *)here + sizeof(__u32));
 		memset(last, 0, size);
+
+		/*
+		 * Update i_inline_off - moved ibody region might contain
+		 * system.data attribute.  Handling a failure here won't
+		 * cause other complications for setting an xattr.
+		 */
+		if (!is_block && ext4_has_inline_data(inode)) {
+			ret = ext4_find_inline_data_nolock(inode);
+			if (ret) {
+				ext4_warning_inode(inode,
+					"unable to update i_inline_off");
+				goto out;
+			}
+		}
 	} else if (s->not_found) {
 		/* Insert new name. */
 		size_t size = EXT4_XATTR_LEN(name_len);
@@ -1851,6 +1878,8 @@
 #define header(x) ((struct ext4_xattr_header *)(x))
 
 	if (s->base) {
+		int offset = (char *)s->here - bs->bh->b_data;
+
 		BUFFER_TRACE(bs->bh, "get_write_access");
 		error = ext4_journal_get_write_access(handle, bs->bh);
 		if (error)
@@ -1865,9 +1894,20 @@
 			 * ext4_xattr_block_set() to reliably detect modified
 			 * block
 			 */
-			if (ea_block_cache)
-				mb_cache_entry_delete(ea_block_cache, hash,
-						      bs->bh->b_blocknr);
+			if (ea_block_cache) {
+				struct mb_cache_entry *oe;
+
+				oe = mb_cache_entry_delete_or_get(ea_block_cache,
+					hash, bs->bh->b_blocknr);
+				if (oe) {
+					/*
+					 * Xattr block is getting reused. Leave
+					 * it alone.
+					 */
+					mb_cache_entry_put(ea_block_cache, oe);
+					goto clone_block;
+				}
+			}
 			ea_bdebug(bs->bh, "modifying in-place");
 			error = ext4_xattr_set_entry(i, s, handle, inode,
 						     true /* is_block */);
@@ -1882,50 +1922,47 @@
 			if (error)
 				goto cleanup;
 			goto inserted;
-		} else {
-			int offset = (char *)s->here - bs->bh->b_data;
+		}
+clone_block:
+		unlock_buffer(bs->bh);
+		ea_bdebug(bs->bh, "cloning");
+		s->base = kmemdup(BHDR(bs->bh), bs->bh->b_size, GFP_NOFS);
+		error = -ENOMEM;
+		if (s->base == NULL)
+			goto cleanup;
+		s->first = ENTRY(header(s->base)+1);
+		header(s->base)->h_refcount = cpu_to_le32(1);
+		s->here = ENTRY(s->base + offset);
+		s->end = s->base + bs->bh->b_size;
 
-			unlock_buffer(bs->bh);
-			ea_bdebug(bs->bh, "cloning");
-			s->base = kmalloc(bs->bh->b_size, GFP_NOFS);
-			error = -ENOMEM;
-			if (s->base == NULL)
+		/*
+		 * If existing entry points to an xattr inode, we need
+		 * to prevent ext4_xattr_set_entry() from decrementing
+		 * ref count on it because the reference belongs to the
+		 * original block. In this case, make the entry look
+		 * like it has an empty value.
+		 */
+		if (!s->not_found && s->here->e_value_inum) {
+			ea_ino = le32_to_cpu(s->here->e_value_inum);
+			error = ext4_xattr_inode_iget(inode, ea_ino,
+				      le32_to_cpu(s->here->e_hash),
+				      &tmp_inode);
+			if (error)
 				goto cleanup;
-			memcpy(s->base, BHDR(bs->bh), bs->bh->b_size);
-			s->first = ENTRY(header(s->base)+1);
-			header(s->base)->h_refcount = cpu_to_le32(1);
-			s->here = ENTRY(s->base + offset);
-			s->end = s->base + bs->bh->b_size;
 
-			/*
-			 * If existing entry points to an xattr inode, we need
-			 * to prevent ext4_xattr_set_entry() from decrementing
-			 * ref count on it because the reference belongs to the
-			 * original block. In this case, make the entry look
-			 * like it has an empty value.
-			 */
-			if (!s->not_found && s->here->e_value_inum) {
-				ea_ino = le32_to_cpu(s->here->e_value_inum);
-				error = ext4_xattr_inode_iget(inode, ea_ino,
-					      le32_to_cpu(s->here->e_hash),
-					      &tmp_inode);
-				if (error)
-					goto cleanup;
-
-				if (!ext4_test_inode_state(tmp_inode,
-						EXT4_STATE_LUSTRE_EA_INODE)) {
-					/*
-					 * Defer quota free call for previous
-					 * inode until success is guaranteed.
-					 */
-					old_ea_inode_quota = le32_to_cpu(
-							s->here->e_value_size);
-				}
-				iput(tmp_inode);
-
-				s->here->e_value_inum = 0;
-				s->here->e_value_size = 0;
+			if (!ext4_test_inode_state(tmp_inode,
+					EXT4_STATE_LUSTRE_EA_INODE)) {
+				/*
+				 * Defer quota free call for previous
+				 * inode until success is guaranteed.
+				 */
+				old_ea_inode_quota = le32_to_cpu(
+						s->here->e_value_size);
 			}
+			iput(tmp_inode);
+
+			s->here->e_value_inum = 0;
+			s->here->e_value_size = 0;
 		}
 	} else {
 		/* Allocate a buffer where we construct the new block. */
@@ -1976,8 +2013,9 @@
 			else {
 				u32 ref;
 
+#ifdef EXT4_XATTR_DEBUG
 				WARN_ON_ONCE(dquot_initialize_needed(inode));
-
+#endif
 				/* The old block is released after updating
 				   the inode. */
 				error = dquot_alloc_block(inode,
@@ -1992,18 +2030,13 @@
 				lock_buffer(new_bh);
 				/*
 				 * We have to be careful about races with
-				 * freeing, rehashing or adding references to
-				 * xattr block. Once we hold buffer lock xattr
-				 * block's state is stable so we can check
-				 * whether the block got freed / rehashed or
-				 * not.  Since we unhash mbcache entry under
-				 * buffer lock when freeing / rehashing xattr
-				 * block, checking whether entry is still
-				 * hashed is reliable. Same rules hold for
-				 * e_reusable handling.
+				 * adding references to xattr block. Once we
+				 * hold buffer lock xattr block's state is
+				 * stable so we can check the additional
+				 * reference fits.
 				 */
-				if (hlist_bl_unhashed(&ce->e_hash_list) ||
-				    !ce->e_reusable) {
+				ref = le32_to_cpu(BHDR(new_bh)->h_refcount) + 1;
+				if (ref > EXT4_XATTR_REFCOUNT_MAX) {
 					/*
 					 * Undo everything and check mbcache
 					 * again.
@@ -2018,10 +2051,9 @@
 					new_bh = NULL;
 					goto inserted;
 				}
-				ref = le32_to_cpu(BHDR(new_bh)->h_refcount) + 1;
 				BHDR(new_bh)->h_refcount = cpu_to_le32(ref);
-				if (ref >= EXT4_XATTR_REFCOUNT_MAX)
-					ce->e_reusable = 0;
+				if (ref == EXT4_XATTR_REFCOUNT_MAX)
+					clear_bit(MBE_REUSABLE_B, &ce->e_flags);
 				ea_bdebug(new_bh, "reusing; refcount now=%d",
 					  ref);
 				ext4_xattr_block_csum_set(inode, new_bh);
@@ -2045,22 +2077,15 @@
 			/* We need to allocate a new block */
 			ext4_fsblk_t goal, block;
 
+#ifdef EXT4_XATTR_DEBUG
 			WARN_ON_ONCE(dquot_initialize_needed(inode));
-
+#endif
 			goal = ext4_group_first_block_no(sb,
 						EXT4_I(inode)->i_block_group);
-
-			/* non-extent files can't have physical blocks past 2^32 */
-			if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
-				goal = goal & EXT4_MAX_BLOCK_FILE_PHYS;
-
 			block = ext4_new_meta_blocks(handle, inode, goal, 0,
 						     NULL, &error);
 			if (error)
 				goto cleanup;
-
-			if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
-				BUG_ON(block > EXT4_MAX_BLOCK_FILE_PHYS);
 
 			ea_idebug(inode, "creating block %llu",
 				  (unsigned long long)block);
@@ -2189,7 +2214,7 @@
 	return 0;
 }
 
-int ext4_xattr_ibody_inline_set(handle_t *handle, struct inode *inode,
+int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
 				struct ext4_xattr_info *i,
 				struct ext4_xattr_ibody_find *is)
 {
@@ -2200,30 +2225,6 @@
 	if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
 		return -ENOSPC;
 
-	error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */);
-	if (error)
-		return error;
-	header = IHDR(inode, ext4_raw_inode(&is->iloc));
-	if (!IS_LAST_ENTRY(s->first)) {
-		header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
-		ext4_set_inode_state(inode, EXT4_STATE_XATTR);
-	} else {
-		header->h_magic = cpu_to_le32(0);
-		ext4_clear_inode_state(inode, EXT4_STATE_XATTR);
-	}
-	return 0;
-}
-
-static int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
-				struct ext4_xattr_info *i,
-				struct ext4_xattr_ibody_find *is)
-{
-	struct ext4_xattr_ibody_header *header;
-	struct ext4_xattr_search *s = &is->s;
-	int error;
-
-	if (EXT4_I(inode)->i_extra_isize == 0)
-		return -ENOSPC;
 	error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */);
 	if (error)
 		return error;
@@ -2552,13 +2553,13 @@
 		.in_inode = !!entry->e_value_inum,
 	};
 	struct ext4_xattr_ibody_header *header = IHDR(inode, raw_inode);
+	int needs_kvfree = 0;
 	int error;
 
 	is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS);
 	bs = kzalloc(sizeof(struct ext4_xattr_block_find), GFP_NOFS);
-	buffer = kmalloc(value_size, GFP_NOFS);
 	b_entry_name = kmalloc(entry->e_name_len + 1, GFP_NOFS);
-	if (!is || !bs || !buffer || !b_entry_name) {
+	if (!is || !bs || !b_entry_name) {
 		error = -ENOMEM;
 		goto out;
 	}
@@ -2570,12 +2571,18 @@
 
 	/* Save the entry name and the entry value */
 	if (entry->e_value_inum) {
+		buffer = kvmalloc(value_size, GFP_NOFS);
+		if (!buffer) {
+			error = -ENOMEM;
+			goto out;
+		}
+		needs_kvfree = 1;
 		error = ext4_xattr_inode_get(inode, entry, buffer, value_size);
 		if (error)
 			goto out;
 	} else {
 		size_t value_offs = le16_to_cpu(entry->e_value_offs);
-		memcpy(buffer, (void *)IFIRST(header) + value_offs, value_size);
+		buffer = (void *)IFIRST(header) + value_offs;
 	}
 
 	memcpy(b_entry_name, entry->e_name, entry->e_name_len);
@@ -2590,25 +2597,26 @@
 	if (error)
 		goto out;
 
-	/* Remove the chosen entry from the inode */
-	error = ext4_xattr_ibody_set(handle, inode, &i, is);
-	if (error)
-		goto out;
-
 	i.value = buffer;
 	i.value_len = value_size;
 	error = ext4_xattr_block_find(inode, &i, bs);
 	if (error)
 		goto out;
 
-	/* Add entry which was removed from the inode into the block */
+	/* Move ea entry from the inode into the block */
 	error = ext4_xattr_block_set(handle, inode, &i, bs);
 	if (error)
 		goto out;
-	error = 0;
+
+	/* Remove the chosen entry from the inode */
+	i.value = NULL;
+	i.value_len = 0;
+	error = ext4_xattr_ibody_set(handle, inode, &i, is);
+
 out:
 	kfree(b_entry_name);
-	kfree(buffer);
+	if (needs_kvfree && buffer)
+		kvfree(buffer);
 	if (is)
 		brelse(is->iloc.bh);
 	if (bs)
@@ -2783,6 +2791,9 @@
 			(void *)header, total_ino);
 	EXT4_I(inode)->i_extra_isize = new_extra_isize;
 
+	if (ext4_has_inline_data(inode))
+		error = ext4_find_inline_data_nolock(inode);
+
 cleanup:
 	if (error && (mnt_count != le16_to_cpu(sbi->s_es->s_mnt_count))) {
 		ext4_warning(inode->i_sb, "Unable to expand inode %lu. Delete some EAs or run e2fsck.",
diff --git a/kernel/fs/ext4/xattr.h b/kernel/fs/ext4/xattr.h
index 87e5863..e5e36bd 100644
--- a/kernel/fs/ext4/xattr.h
+++ b/kernel/fs/ext4/xattr.h
@@ -191,6 +191,7 @@
 
 extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
 			    struct ext4_inode *raw_inode, handle_t *handle);
+extern void ext4_evict_ea_inode(struct inode *inode);
 
 extern const struct xattr_handler *ext4_xattr_handlers[];
 
@@ -199,9 +200,9 @@
 extern int ext4_xattr_ibody_get(struct inode *inode, int name_index,
 				const char *name,
 				void *buffer, size_t buffer_size);
-extern int ext4_xattr_ibody_inline_set(handle_t *handle, struct inode *inode,
-				       struct ext4_xattr_info *i,
-				       struct ext4_xattr_ibody_find *is);
+extern int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
+				struct ext4_xattr_info *i,
+				struct ext4_xattr_ibody_find *is);
 
 extern struct mb_cache *ext4_xattr_create_cache(void);
 extern void ext4_xattr_destroy_cache(struct mb_cache *);
diff --git a/kernel/fs/f2fs/checkpoint.c b/kernel/fs/f2fs/checkpoint.c
index 84c734e..dd764e0 100644
--- a/kernel/fs/f2fs/checkpoint.c
+++ b/kernel/fs/f2fs/checkpoint.c
@@ -315,8 +315,15 @@
 
 	trace_f2fs_writepage(page, META);
 
-	if (unlikely(f2fs_cp_error(sbi)))
+	if (unlikely(f2fs_cp_error(sbi))) {
+		if (is_sbi_flag_set(sbi, SBI_IS_CLOSE)) {
+			ClearPageUptodate(page);
+			dec_page_count(sbi, F2FS_DIRTY_META);
+			unlock_page(page);
+			return 0;
+		}
 		goto redirty_out;
+	}
 	if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
 		goto redirty_out;
 	if (wbc->for_reclaim && page->index < GET_SUM_BLOCK(sbi, 0))
@@ -1288,7 +1295,8 @@
 		if (!get_pages(sbi, type))
 			break;
 
-		if (unlikely(f2fs_cp_error(sbi)))
+		if (unlikely(f2fs_cp_error(sbi) &&
+			!is_sbi_flag_set(sbi, SBI_IS_CLOSE)))
 			break;
 
 		if (type == F2FS_DIRTY_META)
diff --git a/kernel/fs/f2fs/compress.c b/kernel/fs/f2fs/compress.c
index c448eaa..d72fb4f 100644
--- a/kernel/fs/f2fs/compress.c
+++ b/kernel/fs/f2fs/compress.c
@@ -1393,6 +1393,12 @@
 		if (!PageDirty(cc->rpages[i]))
 			goto continue_unlock;
 
+		if (PageWriteback(cc->rpages[i])) {
+			if (wbc->sync_mode == WB_SYNC_NONE)
+				goto continue_unlock;
+			f2fs_wait_on_page_writeback(cc->rpages[i], DATA, true, true);
+		}
+
 		if (!clear_page_dirty_for_io(cc->rpages[i]))
 			goto continue_unlock;
 
diff --git a/kernel/fs/f2fs/data.c b/kernel/fs/f2fs/data.c
index 17ead29..926d4ee 100644
--- a/kernel/fs/f2fs/data.c
+++ b/kernel/fs/f2fs/data.c
@@ -698,7 +698,7 @@
 	}
 
 	if (fio->io_wbc && !is_read_io(fio->op))
-		wbc_account_cgroup_owner(fio->io_wbc, page, PAGE_SIZE);
+		wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE);
 
 	__attach_io_flag(fio);
 	bio_set_op_attrs(bio, fio->op, fio->op_flags);
@@ -829,6 +829,8 @@
 	bool found = false;
 	struct bio *target = bio ? *bio : NULL;
 
+	f2fs_bug_on(sbi, !target && !page);
+
 	for (temp = HOT; temp < NR_TEMP_TYPE && !found; temp++) {
 		struct f2fs_bio_info *io = sbi->write_io[DATA] + temp;
 		struct list_head *head = &io->bio_list;
@@ -908,7 +910,7 @@
 	}
 
 	if (fio->io_wbc)
-		wbc_account_cgroup_owner(fio->io_wbc, page, PAGE_SIZE);
+		wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE);
 
 	inc_page_count(fio->sbi, WB_DATA_TYPE(page));
 
@@ -982,7 +984,7 @@
 	}
 
 	if (fio->io_wbc)
-		wbc_account_cgroup_owner(fio->io_wbc, bio_page, PAGE_SIZE);
+		wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE);
 
 	io->last_block_in_bio = fio->new_blkaddr;
 
@@ -2770,7 +2772,8 @@
 		 * don't drop any dirty dentry pages for keeping lastest
 		 * directory structure.
 		 */
-		if (S_ISDIR(inode->i_mode))
+		if (S_ISDIR(inode->i_mode) &&
+				!is_sbi_flag_set(sbi, SBI_IS_CLOSE))
 			goto redirty_out;
 		goto out;
 	}
@@ -2875,7 +2878,8 @@
 
 	if (unlikely(f2fs_cp_error(sbi))) {
 		f2fs_submit_merged_write(sbi, DATA);
-		f2fs_submit_merged_ipu_write(sbi, bio, NULL);
+		if (bio && *bio)
+			f2fs_submit_merged_ipu_write(sbi, bio, NULL);
 		submitted = NULL;
 	}
 
diff --git a/kernel/fs/f2fs/debug.c b/kernel/fs/f2fs/debug.c
index f33e64a..a549f7b 100644
--- a/kernel/fs/f2fs/debug.c
+++ b/kernel/fs/f2fs/debug.c
@@ -469,12 +469,14 @@
 				si->node_segs, si->bg_node_segs);
 		seq_printf(s, "  - Reclaimed segs : Normal (%d), Idle CB (%d), "
 				"Idle Greedy (%d), Idle AT (%d), "
-				"Urgent High (%d), Urgent Low (%d)\n",
+				"Urgent High (%d), Urgent Mid (%d), "
+				"Urgent Low (%d)\n",
 				si->sbi->gc_reclaimed_segs[GC_NORMAL],
 				si->sbi->gc_reclaimed_segs[GC_IDLE_CB],
 				si->sbi->gc_reclaimed_segs[GC_IDLE_GREEDY],
 				si->sbi->gc_reclaimed_segs[GC_IDLE_AT],
 				si->sbi->gc_reclaimed_segs[GC_URGENT_HIGH],
+				si->sbi->gc_reclaimed_segs[GC_URGENT_MID],
 				si->sbi->gc_reclaimed_segs[GC_URGENT_LOW]);
 		seq_printf(s, "Try to move %d blocks (BG: %d)\n", si->tot_blks,
 				si->bg_data_blks + si->bg_node_blks);
diff --git a/kernel/fs/f2fs/extent_cache.c b/kernel/fs/f2fs/extent_cache.c
index 33eb6de..dadddb3 100644
--- a/kernel/fs/f2fs/extent_cache.c
+++ b/kernel/fs/f2fs/extent_cache.c
@@ -41,41 +41,14 @@
 	}
 }
 
-static bool __may_read_extent_tree(struct inode *inode)
-{
-	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-
-	if (!test_opt(sbi, READ_EXTENT_CACHE))
-		return false;
-	if (is_inode_flag_set(inode, FI_NO_EXTENT))
-		return false;
-	if (is_inode_flag_set(inode, FI_COMPRESSED_FILE) &&
-			 !f2fs_sb_has_readonly(sbi))
-		return false;
-	return S_ISREG(inode->i_mode);
-}
-
-static bool __may_age_extent_tree(struct inode *inode)
-{
-	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-
-	if (!test_opt(sbi, AGE_EXTENT_CACHE))
-		return false;
-	/* don't cache block age info for cold file */
-	if (is_inode_flag_set(inode, FI_COMPRESSED_FILE))
-		return false;
-	if (file_is_cold(inode))
-		return false;
-
-	return S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode);
-}
-
 static bool __init_may_extent_tree(struct inode *inode, enum extent_type type)
 {
 	if (type == EX_READ)
-		return __may_read_extent_tree(inode);
-	else if (type == EX_BLOCK_AGE)
-		return __may_age_extent_tree(inode);
+		return test_opt(F2FS_I_SB(inode), READ_EXTENT_CACHE) &&
+			S_ISREG(inode->i_mode);
+	if (type == EX_BLOCK_AGE)
+		return test_opt(F2FS_I_SB(inode), AGE_EXTENT_CACHE) &&
+			(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode));
 	return false;
 }
 
@@ -88,7 +61,22 @@
 	if (list_empty(&F2FS_I_SB(inode)->s_list))
 		return false;
 
-	return __init_may_extent_tree(inode, type);
+	if (!__init_may_extent_tree(inode, type))
+		return false;
+
+	if (type == EX_READ) {
+		if (is_inode_flag_set(inode, FI_NO_EXTENT))
+			return false;
+		if (is_inode_flag_set(inode, FI_COMPRESSED_FILE) &&
+				 !f2fs_sb_has_readonly(F2FS_I_SB(inode)))
+			return false;
+	} else if (type == EX_BLOCK_AGE) {
+		if (is_inode_flag_set(inode, FI_COMPRESSED_FILE))
+			return false;
+		if (file_is_cold(inode))
+			return false;
+	}
+	return true;
 }
 
 static void __try_update_largest_extent(struct extent_tree *et,
diff --git a/kernel/fs/f2fs/f2fs.h b/kernel/fs/f2fs/f2fs.h
index 28c605f..af70db6 100644
--- a/kernel/fs/f2fs/f2fs.h
+++ b/kernel/fs/f2fs/f2fs.h
@@ -1220,7 +1220,6 @@
 #ifdef CONFIG_BLK_DEV_ZONED
 	unsigned int nr_blkz;		/* Total number of zones */
 	unsigned long *blkz_seq;	/* Bitmap indicating sequential zones */
-	block_t *zone_capacity_blocks;  /* Array of zone capacity in blks */
 #endif
 };
 
@@ -1288,6 +1287,7 @@
 	GC_IDLE_AT,
 	GC_URGENT_HIGH,
 	GC_URGENT_LOW,
+	GC_URGENT_MID,
 	MAX_GC_MODE,
 };
 
@@ -1640,6 +1640,7 @@
 	unsigned int meta_ino_num;		/* meta inode number*/
 	unsigned int log_blocks_per_seg;	/* log2 blocks per segment */
 	unsigned int blocks_per_seg;		/* blocks per segment */
+	unsigned int unusable_blocks_per_sec;	/* unusable blocks per section */
 	unsigned int segs_per_sec;		/* segments per section */
 	unsigned int secs_per_zone;		/* sections per zone */
 	unsigned int total_sections;		/* total section count */
@@ -2758,6 +2759,9 @@
 	if (is_inflight_io(sbi, type))
 		return false;
 
+	if (sbi->gc_mode == GC_URGENT_MID)
+		return true;
+
 	if (sbi->gc_mode == GC_URGENT_LOW &&
 			(type == DISCARD_TIME || type == GC_TIME))
 		return true;
@@ -3782,7 +3786,7 @@
 int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, bool background, bool force,
 			unsigned int segno);
 void f2fs_build_gc_manager(struct f2fs_sb_info *sbi);
-int f2fs_resize_fs(struct f2fs_sb_info *sbi, __u64 block_count);
+int f2fs_resize_fs(struct file *filp, __u64 block_count);
 int __init f2fs_create_garbage_collection_cache(void);
 void f2fs_destroy_garbage_collection_cache(void);
 
diff --git a/kernel/fs/f2fs/file.c b/kernel/fs/f2fs/file.c
index cd13532..ca524c2 100644
--- a/kernel/fs/f2fs/file.c
+++ b/kernel/fs/f2fs/file.c
@@ -629,7 +629,7 @@
 		fofs = f2fs_start_bidx_of_node(ofs_of_node(dn->node_page),
 							dn->inode) + ofs;
 		f2fs_update_read_extent_cache_range(dn, fofs, 0, len);
-		f2fs_update_age_extent_cache_range(dn, fofs, nr_free);
+		f2fs_update_age_extent_cache_range(dn, fofs, len);
 		dec_valid_block_count(sbi, dn->inode, nr_free);
 	}
 	dn->ofs_in_node = ofs;
@@ -1453,6 +1453,7 @@
 	}
 
 	f2fs_update_read_extent_cache_range(dn, start, 0, index - start);
+	f2fs_update_age_extent_cache_range(dn, start, index - start);
 
 	return ret;
 }
@@ -3039,15 +3040,16 @@
 	struct dquot *transfer_to[MAXQUOTAS] = {};
 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
 	struct super_block *sb = sbi->sb;
-	int err = 0;
+	int err;
 
 	transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
-	if (!IS_ERR(transfer_to[PRJQUOTA])) {
-		err = __dquot_transfer(inode, transfer_to);
-		if (err)
-			set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
-		dqput(transfer_to[PRJQUOTA]);
-	}
+	if (IS_ERR(transfer_to[PRJQUOTA]))
+		return PTR_ERR(transfer_to[PRJQUOTA]);
+
+	err = __dquot_transfer(inode, transfer_to);
+	if (err)
+		set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
+	dqput(transfer_to[PRJQUOTA]);
 	return err;
 }
 
@@ -3381,7 +3383,7 @@
 			   sizeof(block_count)))
 		return -EFAULT;
 
-	return f2fs_resize_fs(sbi, block_count);
+	return f2fs_resize_fs(filp, block_count);
 }
 
 static int f2fs_ioc_enable_verity(struct file *filp, unsigned long arg)
diff --git a/kernel/fs/f2fs/gc.c b/kernel/fs/f2fs/gc.c
index ab774c6..600b8ae 100644
--- a/kernel/fs/f2fs/gc.c
+++ b/kernel/fs/f2fs/gc.c
@@ -7,6 +7,7 @@
  */
 #include <linux/fs.h>
 #include <linux/module.h>
+#include <linux/mount.h>
 #include <linux/backing-dev.h>
 #include <linux/init.h>
 #include <linux/f2fs_fs.h>
@@ -90,7 +91,8 @@
 		 * invalidated soon after by user update or deletion.
 		 * So, I'd like to wait some time to collect dirty segments.
 		 */
-		if (sbi->gc_mode == GC_URGENT_HIGH) {
+		if (sbi->gc_mode == GC_URGENT_HIGH ||
+				sbi->gc_mode == GC_URGENT_MID) {
 			wait_ms = gc_th->urgent_sleep_time;
 			f2fs_down_write(&sbi->gc_lock);
 			goto do_gc;
@@ -627,6 +629,54 @@
 	f2fs_bug_on(sbi, !list_empty(&am->victim_list));
 }
 
+static bool f2fs_pin_section(struct f2fs_sb_info *sbi, unsigned int segno)
+{
+	struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
+	unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
+
+	if (!dirty_i->enable_pin_section)
+		return false;
+	if (!test_and_set_bit(secno, dirty_i->pinned_secmap))
+		dirty_i->pinned_secmap_cnt++;
+	return true;
+}
+
+static bool f2fs_pinned_section_exists(struct dirty_seglist_info *dirty_i)
+{
+	return dirty_i->pinned_secmap_cnt;
+}
+
+static bool f2fs_section_is_pinned(struct dirty_seglist_info *dirty_i,
+						unsigned int secno)
+{
+	return dirty_i->enable_pin_section &&
+		f2fs_pinned_section_exists(dirty_i) &&
+		test_bit(secno, dirty_i->pinned_secmap);
+}
+
+static void f2fs_unpin_all_sections(struct f2fs_sb_info *sbi, bool enable)
+{
+	unsigned int bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi));
+
+	if (f2fs_pinned_section_exists(DIRTY_I(sbi))) {
+		memset(DIRTY_I(sbi)->pinned_secmap, 0, bitmap_size);
+		DIRTY_I(sbi)->pinned_secmap_cnt = 0;
+	}
+	DIRTY_I(sbi)->enable_pin_section = enable;
+}
+
+static int f2fs_gc_pinned_control(struct inode *inode, int gc_type,
+							unsigned int segno)
+{
+	if (!f2fs_is_pinned_file(inode))
+		return 0;
+	if (gc_type != FG_GC)
+		return -EBUSY;
+	if (!f2fs_pin_section(F2FS_I_SB(inode), segno))
+		f2fs_pin_file_control(inode, true);
+	return -EAGAIN;
+}
+
 /*
  * This function is called from two paths.
  * One is garbage collection and the other is SSR segment selection.
@@ -766,6 +816,9 @@
 		}
 
 		if (gc_type == BG_GC && test_bit(secno, dirty_i->victim_secmap))
+			goto next;
+
+		if (gc_type == FG_GC && f2fs_section_is_pinned(dirty_i, secno))
 			goto next;
 
 		if (is_atgc) {
@@ -1000,7 +1053,7 @@
 {
 	struct page *node_page;
 	nid_t nid;
-	unsigned int ofs_in_node, max_addrs;
+	unsigned int ofs_in_node, max_addrs, base;
 	block_t source_blkaddr;
 
 	nid = le32_to_cpu(sum->nid);
@@ -1026,11 +1079,18 @@
 		return false;
 	}
 
-	max_addrs = IS_INODE(node_page) ? DEF_ADDRS_PER_INODE :
-						DEF_ADDRS_PER_BLOCK;
-	if (ofs_in_node >= max_addrs) {
-		f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%u, nid:%u, max:%u",
-			ofs_in_node, dni->ino, dni->nid, max_addrs);
+	if (IS_INODE(node_page)) {
+		base = offset_in_addr(F2FS_INODE(node_page));
+		max_addrs = DEF_ADDRS_PER_INODE;
+	} else {
+		base = 0;
+		max_addrs = DEF_ADDRS_PER_BLOCK;
+	}
+
+	if (base + ofs_in_node >= max_addrs) {
+		f2fs_err(sbi, "Inconsistent blkaddr offset: base:%u, ofs_in_node:%u, max:%u, ino:%u, nid:%u",
+			base, ofs_in_node, max_addrs, dni->ino, dni->nid);
+		f2fs_put_page(node_page, 1);
 		return false;
 	}
 
@@ -1189,12 +1249,9 @@
 		goto out;
 	}
 
-	if (f2fs_is_pinned_file(inode)) {
-		if (gc_type == FG_GC)
-			f2fs_pin_file_control(inode, true);
-		err = -EAGAIN;
+	err = f2fs_gc_pinned_control(inode, gc_type, segno);
+	if (err)
 		goto out;
-	}
 
 	set_new_dnode(&dn, inode, NULL, NULL, 0);
 	err = f2fs_get_dnode_of_data(&dn, bidx, LOOKUP_NODE);
@@ -1339,12 +1396,9 @@
 		err = -EAGAIN;
 		goto out;
 	}
-	if (f2fs_is_pinned_file(inode)) {
-		if (gc_type == FG_GC)
-			f2fs_pin_file_control(inode, true);
-		err = -EAGAIN;
+	err = f2fs_gc_pinned_control(inode, gc_type, segno);
+	if (err)
 		goto out;
-	}
 
 	if (gc_type == BG_GC) {
 		if (PageWriteback(page)) {
@@ -1465,9 +1519,17 @@
 		ofs_in_node = le16_to_cpu(entry->ofs_in_node);
 
 		if (phase == 3) {
+			int err;
+
 			inode = f2fs_iget(sb, dni.ino);
 			if (IS_ERR(inode) || is_bad_inode(inode))
 				continue;
+
+			err = f2fs_gc_pinned_control(inode, gc_type, segno);
+			if (err == -EAGAIN) {
+				iput(inode);
+				return submitted;
+			}
 
 			if (!f2fs_down_write_trylock(
 				&F2FS_I(inode)->i_gc_rwsem[WRITE])) {
@@ -1672,8 +1734,9 @@
 				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);
 	}
@@ -1748,9 +1811,17 @@
 		ret = -EINVAL;
 		goto stop;
 	}
+retry:
 	ret = __get_victim(sbi, &segno, gc_type);
-	if (ret)
+	if (ret) {
+		/* allow to search victim from sections has pinned data */
+		if (ret == -ENODATA && gc_type == FG_GC &&
+				f2fs_pinned_section_exists(DIRTY_I(sbi))) {
+			f2fs_unpin_all_sections(sbi, false);
+			goto retry;
+		}
 		goto stop;
+	}
 
 	seg_freed = do_garbage_collect(sbi, segno, &gc_list, gc_type, force);
 	if (gc_type == FG_GC &&
@@ -1800,6 +1871,9 @@
 stop:
 	SIT_I(sbi)->last_victim[ALLOC_NEXT] = 0;
 	SIT_I(sbi)->last_victim[FLUSH_DEVICE] = init_segno;
+
+	if (gc_type == FG_GC)
+		f2fs_unpin_all_sections(sbi, true);
 
 	trace_f2fs_gc_end(sbi->sb, ret, total_freed, sec_freed,
 				get_pages(sbi, F2FS_DIRTY_NODES),
@@ -1991,8 +2065,9 @@
 	}
 }
 
-int f2fs_resize_fs(struct f2fs_sb_info *sbi, __u64 block_count)
+int f2fs_resize_fs(struct file *filp, __u64 block_count)
 {
+	struct f2fs_sb_info *sbi = F2FS_I_SB(file_inode(filp));
 	__u64 old_block_count, shrunk_blocks;
 	struct cp_control cpc = { CP_RESIZE, 0, 0, 0 };
 	unsigned int secs;
@@ -2030,12 +2105,18 @@
 		return -EINVAL;
 	}
 
+	err = mnt_want_write_file(filp);
+	if (err)
+		return err;
+
 	shrunk_blocks = old_block_count - block_count;
 	secs = div_u64(shrunk_blocks, BLKS_PER_SEC(sbi));
 
 	/* stop other GC */
-	if (!f2fs_down_write_trylock(&sbi->gc_lock))
-		return -EAGAIN;
+	if (!f2fs_down_write_trylock(&sbi->gc_lock)) {
+		err = -EAGAIN;
+		goto out_drop_write;
+	}
 
 	/* stop CP to protect MAIN_SEC in free_segment_range */
 	f2fs_lock_op(sbi);
@@ -2055,12 +2136,18 @@
 out_unlock:
 	f2fs_unlock_op(sbi);
 	f2fs_up_write(&sbi->gc_lock);
+out_drop_write:
+	mnt_drop_write_file(filp);
 	if (err)
 		return err;
 
-	set_sbi_flag(sbi, SBI_IS_RESIZEFS);
-
 	freeze_super(sbi->sb);
+
+	if (f2fs_readonly(sbi->sb)) {
+		thaw_super(sbi->sb);
+		return -EROFS;
+	}
+
 	f2fs_down_write(&sbi->gc_lock);
 	f2fs_down_write(&sbi->cp_global_sem);
 
@@ -2075,6 +2162,7 @@
 	if (err)
 		goto out_err;
 
+	set_sbi_flag(sbi, SBI_IS_RESIZEFS);
 	err = free_segment_range(sbi, secs, false);
 	if (err)
 		goto recover_out;
@@ -2098,6 +2186,7 @@
 		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!");
@@ -2110,6 +2199,5 @@
 	f2fs_up_write(&sbi->cp_global_sem);
 	f2fs_up_write(&sbi->gc_lock);
 	thaw_super(sbi->sb);
-	clear_sbi_flag(sbi, SBI_IS_RESIZEFS);
 	return err;
 }
diff --git a/kernel/fs/f2fs/inline.c b/kernel/fs/f2fs/inline.c
index 470b069..0f9b2eb 100644
--- a/kernel/fs/f2fs/inline.c
+++ b/kernel/fs/f2fs/inline.c
@@ -65,7 +65,6 @@
 void f2fs_do_read_inline_data(struct page *page, struct page *ipage)
 {
 	struct inode *inode = page->mapping->host;
-	void *src_addr, *dst_addr;
 
 	if (PageUptodate(page))
 		return;
@@ -75,11 +74,8 @@
 	zero_user_segment(page, MAX_INLINE_DATA(inode), PAGE_SIZE);
 
 	/* Copy the whole inline data block */
-	src_addr = inline_data_addr(inode, ipage);
-	dst_addr = kmap_atomic(page);
-	memcpy(dst_addr, src_addr, MAX_INLINE_DATA(inode));
-	flush_dcache_page(page);
-	kunmap_atomic(dst_addr);
+	memcpy_to_page(page, 0, inline_data_addr(inode, ipage),
+		       MAX_INLINE_DATA(inode));
 	if (!PageUptodate(page))
 		SetPageUptodate(page);
 }
@@ -264,7 +260,6 @@
 
 int f2fs_write_inline_data(struct inode *inode, struct page *page)
 {
-	void *src_addr, *dst_addr;
 	struct dnode_of_data dn;
 	int err;
 
@@ -281,10 +276,8 @@
 	f2fs_bug_on(F2FS_I_SB(inode), page->index);
 
 	f2fs_wait_on_page_writeback(dn.inode_page, NODE, true, true);
-	src_addr = kmap_atomic(page);
-	dst_addr = inline_data_addr(inode, dn.inode_page);
-	memcpy(dst_addr, src_addr, MAX_INLINE_DATA(inode));
-	kunmap_atomic(src_addr);
+	memcpy_from_page(inline_data_addr(inode, dn.inode_page),
+			 page, 0, MAX_INLINE_DATA(inode));
 	set_page_dirty(dn.inode_page);
 
 	f2fs_clear_page_cache_dirty_tag(page);
@@ -445,18 +438,17 @@
 
 	dentry_blk = page_address(page);
 
+	/*
+	 * Start by zeroing the full block, to ensure that all unused space is
+	 * zeroed and no uninitialized memory is leaked to disk.
+	 */
+	memset(dentry_blk, 0, F2FS_BLKSIZE);
+
 	make_dentry_ptr_inline(dir, &src, inline_dentry);
 	make_dentry_ptr_block(dir, &dst, dentry_blk);
 
 	/* copy data from inline dentry block to new dentry block */
 	memcpy(dst.bitmap, src.bitmap, src.nr_bitmap);
-	memset(dst.bitmap + src.nr_bitmap, 0, dst.nr_bitmap - src.nr_bitmap);
-	/*
-	 * we do not need to zero out remainder part of dentry and filename
-	 * field, since we have used bitmap for marking the usage status of
-	 * them, besides, we can also ignore copying/zeroing reserved space
-	 * of dentry block, because them haven't been used so far.
-	 */
 	memcpy(dst.dentry, src.dentry, SIZE_OF_DIR_ENTRY * src.max);
 	memcpy(dst.filename, src.filename, src.max * F2FS_SLOT_LEN);
 
diff --git a/kernel/fs/f2fs/inode.c b/kernel/fs/f2fs/inode.c
index 5bf4f1c..a88c8e7 100644
--- a/kernel/fs/f2fs/inode.c
+++ b/kernel/fs/f2fs/inode.c
@@ -401,11 +401,6 @@
 		fi->i_inline_xattr_size = 0;
 	}
 
-	if (!sanity_check_inode(inode, node_page)) {
-		f2fs_put_page(node_page, 1);
-		return -EFSCORRUPTED;
-	}
-
 	/* check data exist */
 	if (f2fs_has_inline_data(inode) && !f2fs_exist_data(inode))
 		__recover_inline_status(inode, node_page);
@@ -472,6 +467,11 @@
 	f2fs_init_read_extent_tree(inode, node_page);
 	f2fs_init_age_extent_tree(inode);
 
+	if (!sanity_check_inode(inode, node_page)) {
+		f2fs_put_page(node_page, 1);
+		return -EFSCORRUPTED;
+	}
+
 	f2fs_put_page(node_page, 1);
 
 	stat_inc_inline_xattr(inode);
diff --git a/kernel/fs/f2fs/node.c b/kernel/fs/f2fs/node.c
index 230c63c..b2085a2 100644
--- a/kernel/fs/f2fs/node.c
+++ b/kernel/fs/f2fs/node.c
@@ -944,8 +944,10 @@
 	dn->ofs_in_node = 0;
 	f2fs_truncate_data_blocks(dn);
 	err = truncate_node(dn);
-	if (err)
+	if (err) {
+		f2fs_put_page(page, 1);
 		return err;
+	}
 
 	return 1;
 }
diff --git a/kernel/fs/f2fs/segment.c b/kernel/fs/f2fs/segment.c
index 175402b..6661ada 100644
--- a/kernel/fs/f2fs/segment.c
+++ b/kernel/fs/f2fs/segment.c
@@ -1547,7 +1547,7 @@
 		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];
@@ -4713,6 +4713,13 @@
 	dirty_i->victim_secmap = f2fs_kvzalloc(sbi, bitmap_size, GFP_KERNEL);
 	if (!dirty_i->victim_secmap)
 		return -ENOMEM;
+
+	dirty_i->pinned_secmap = f2fs_kvzalloc(sbi, bitmap_size, GFP_KERNEL);
+	if (!dirty_i->pinned_secmap)
+		return -ENOMEM;
+
+	dirty_i->pinned_secmap_cnt = 0;
+	dirty_i->enable_pin_section = true;
 	return 0;
 }
 
@@ -5047,54 +5054,6 @@
 	return 0;
 }
 
-static bool is_conv_zone(struct f2fs_sb_info *sbi, unsigned int zone_idx,
-						unsigned int dev_idx)
-{
-	if (!bdev_is_zoned(FDEV(dev_idx).bdev))
-		return true;
-	return !test_bit(zone_idx, FDEV(dev_idx).blkz_seq);
-}
-
-/* Return the zone index in the given device */
-static unsigned int get_zone_idx(struct f2fs_sb_info *sbi, unsigned int secno,
-					int dev_idx)
-{
-	block_t sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno));
-
-	return (sec_start_blkaddr - FDEV(dev_idx).start_blk) >>
-						sbi->log_blocks_per_blkz;
-}
-
-/*
- * Return the usable segments in a section based on the zone's
- * corresponding zone capacity. Zone is equal to a section.
- */
-static inline unsigned int f2fs_usable_zone_segs_in_sec(
-		struct f2fs_sb_info *sbi, unsigned int segno)
-{
-	unsigned int dev_idx, zone_idx, unusable_segs_in_sec;
-
-	dev_idx = f2fs_target_device_index(sbi, START_BLOCK(sbi, segno));
-	zone_idx = get_zone_idx(sbi, GET_SEC_FROM_SEG(sbi, segno), dev_idx);
-
-	/* Conventional zone's capacity is always equal to zone size */
-	if (is_conv_zone(sbi, zone_idx, dev_idx))
-		return sbi->segs_per_sec;
-
-	/*
-	 * If the zone_capacity_blocks array is NULL, then zone capacity
-	 * is equal to the zone size for all zones
-	 */
-	if (!FDEV(dev_idx).zone_capacity_blocks)
-		return sbi->segs_per_sec;
-
-	/* Get the segment count beyond zone capacity block */
-	unusable_segs_in_sec = (sbi->blocks_per_blkz -
-				FDEV(dev_idx).zone_capacity_blocks[zone_idx]) >>
-				sbi->log_blocks_per_seg;
-	return sbi->segs_per_sec - unusable_segs_in_sec;
-}
-
 /*
  * Return the number of usable blocks in a segment. The number of blocks
  * returned is always equal to the number of blocks in a segment for
@@ -5107,26 +5066,15 @@
 			struct f2fs_sb_info *sbi, unsigned int segno)
 {
 	block_t seg_start, sec_start_blkaddr, sec_cap_blkaddr;
-	unsigned int zone_idx, dev_idx, secno;
+	unsigned int secno;
+
+	if (!sbi->unusable_blocks_per_sec)
+		return sbi->blocks_per_seg;
 
 	secno = GET_SEC_FROM_SEG(sbi, segno);
 	seg_start = START_BLOCK(sbi, segno);
-	dev_idx = f2fs_target_device_index(sbi, seg_start);
-	zone_idx = get_zone_idx(sbi, secno, dev_idx);
-
-	/*
-	 * Conventional zone's capacity is always equal to zone size,
-	 * so, blocks per segment is unchanged.
-	 */
-	if (is_conv_zone(sbi, zone_idx, dev_idx))
-		return sbi->blocks_per_seg;
-
-	if (!FDEV(dev_idx).zone_capacity_blocks)
-		return sbi->blocks_per_seg;
-
 	sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno));
-	sec_cap_blkaddr = sec_start_blkaddr +
-				FDEV(dev_idx).zone_capacity_blocks[zone_idx];
+	sec_cap_blkaddr = sec_start_blkaddr + CAP_BLKS_PER_SEC(sbi);
 
 	/*
 	 * If segment starts before zone capacity and spans beyond
@@ -5158,11 +5106,6 @@
 	return 0;
 }
 
-static inline unsigned int f2fs_usable_zone_segs_in_sec(struct f2fs_sb_info *sbi,
-							unsigned int segno)
-{
-	return 0;
-}
 #endif
 unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
 					unsigned int segno)
@@ -5177,7 +5120,7 @@
 					unsigned int segno)
 {
 	if (f2fs_sb_has_blkzoned(sbi))
-		return f2fs_usable_zone_segs_in_sec(sbi, segno);
+		return CAP_SEGS_PER_SEC(sbi);
 
 	return sbi->segs_per_sec;
 }
@@ -5301,6 +5244,7 @@
 {
 	struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
 
+	kvfree(dirty_i->pinned_secmap);
 	kvfree(dirty_i->victim_secmap);
 }
 
diff --git a/kernel/fs/f2fs/segment.h b/kernel/fs/f2fs/segment.h
index d31eb2f..c5cab29 100644
--- a/kernel/fs/f2fs/segment.h
+++ b/kernel/fs/f2fs/segment.h
@@ -101,6 +101,12 @@
 		GET_SEGNO_FROM_SEG0(sbi, blk_addr)))
 #define BLKS_PER_SEC(sbi)					\
 	((sbi)->segs_per_sec * (sbi)->blocks_per_seg)
+#define CAP_BLKS_PER_SEC(sbi)					\
+	((sbi)->segs_per_sec * (sbi)->blocks_per_seg -		\
+	 (sbi)->unusable_blocks_per_sec)
+#define CAP_SEGS_PER_SEC(sbi)					\
+	((sbi)->segs_per_sec - ((sbi)->unusable_blocks_per_sec >>\
+	(sbi)->log_blocks_per_seg))
 #define GET_SEC_FROM_SEG(sbi, segno)				\
 	(((segno) == -1) ? -1: (segno) / (sbi)->segs_per_sec)
 #define GET_SEG_FROM_SEC(sbi, secno)				\
@@ -295,6 +301,9 @@
 	struct mutex seglist_lock;		/* lock for segment bitmaps */
 	int nr_dirty[NR_DIRTY_TYPE];		/* # of dirty segments */
 	unsigned long *victim_secmap;		/* background GC victims */
+	unsigned long *pinned_secmap;		/* pinned victims from foreground GC */
+	unsigned int pinned_secmap_cnt;		/* count of victims which has pinned data */
+	bool enable_pin_section;		/* enable pinning section */
 };
 
 /* victim selection function for cleaning and SSR */
diff --git a/kernel/fs/f2fs/super.c b/kernel/fs/f2fs/super.c
index 40ba040..78ef3bc 100644
--- a/kernel/fs/f2fs/super.c
+++ b/kernel/fs/f2fs/super.c
@@ -1434,7 +1434,6 @@
 		blkdev_put(FDEV(i).bdev, FMODE_EXCL);
 #ifdef CONFIG_BLK_DEV_ZONED
 		kvfree(FDEV(i).blkz_seq);
-		kfree(FDEV(i).zone_capacity_blocks);
 #endif
 	}
 	kvfree(sbi->devs);
@@ -1932,9 +1931,17 @@
 	return 0;
 }
 
-static void default_options(struct f2fs_sb_info *sbi)
+static void default_options(struct f2fs_sb_info *sbi, bool remount)
 {
 	/* init some FS parameters */
+	if (!remount) {
+		set_opt(sbi, READ_EXTENT_CACHE);
+		clear_opt(sbi, DISABLE_CHECKPOINT);
+
+		if (f2fs_hw_support_discard(sbi) || f2fs_hw_should_discard(sbi))
+			set_opt(sbi, DISCARD);
+	}
+
 	if (f2fs_sb_has_readonly(sbi))
 		F2FS_OPTION(sbi).active_logs = NR_CURSEG_RO_TYPE;
 	else
@@ -1958,14 +1965,11 @@
 	set_opt(sbi, INLINE_XATTR);
 	set_opt(sbi, INLINE_DATA);
 	set_opt(sbi, INLINE_DENTRY);
-	set_opt(sbi, READ_EXTENT_CACHE);
 	set_opt(sbi, NOHEAP);
-	clear_opt(sbi, DISABLE_CHECKPOINT);
 	set_opt(sbi, MERGE_CHECKPOINT);
 	F2FS_OPTION(sbi).unusable_cap = 0;
 	sbi->sb->s_flags |= SB_LAZYTIME;
 	set_opt(sbi, FLUSH_MERGE);
-	set_opt(sbi, DISCARD);
 	if (f2fs_sb_has_blkzoned(sbi))
 		F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS;
 	else
@@ -1999,6 +2003,11 @@
 	}
 	sbi->sb->s_flags |= SB_ACTIVE;
 
+	/* check if we need more GC first */
+	unusable = f2fs_get_unusable_blocks(sbi);
+	if (!f2fs_disable_cp_again(sbi, unusable))
+		goto skip_gc;
+
 	f2fs_update_time(sbi, DISABLE_TIME);
 
 	while (!f2fs_time_over(sbi, DISABLE_TIME)) {
@@ -2024,6 +2033,7 @@
 		goto restore_flag;
 	}
 
+skip_gc:
 	f2fs_down_write(&sbi->gc_lock);
 	cpc.reason = CP_PAUSE;
 	set_sbi_flag(sbi, SBI_CP_DISABLED);
@@ -2123,7 +2133,7 @@
 			clear_sbi_flag(sbi, SBI_NEED_SB_WRITE);
 	}
 
-	default_options(sbi);
+	default_options(sbi, true);
 
 	/* parse mount options */
 	err = parse_options(sb, data, true);
@@ -2333,7 +2343,6 @@
 	size_t toread;
 	loff_t i_size = i_size_read(inode);
 	struct page *page;
-	char *kaddr;
 
 	if (off > i_size)
 		return 0;
@@ -2367,9 +2376,7 @@
 			return -EIO;
 		}
 
-		kaddr = kmap_atomic(page);
-		memcpy(data, kaddr + offset, tocopy);
-		kunmap_atomic(kaddr);
+		memcpy_from_page(data, page, offset, tocopy);
 		f2fs_put_page(page, 1);
 
 		offset = 0;
@@ -2391,7 +2398,6 @@
 	size_t towrite = len;
 	struct page *page;
 	void *fsdata = NULL;
-	char *kaddr;
 	int err = 0;
 	int tocopy;
 
@@ -2411,10 +2417,7 @@
 			break;
 		}
 
-		kaddr = kmap_atomic(page);
-		memcpy(kaddr + offset, data, tocopy);
-		kunmap_atomic(kaddr);
-		flush_dcache_page(page);
+		memcpy_to_page(page, offset, data, tocopy);
 
 		a_ops->write_end(NULL, mapping, off, tocopy, tocopy,
 						page, fsdata);
@@ -3513,24 +3516,29 @@
 #ifdef CONFIG_BLK_DEV_ZONED
 
 struct f2fs_report_zones_args {
+	struct f2fs_sb_info *sbi;
 	struct f2fs_dev_info *dev;
-	bool zone_cap_mismatch;
 };
 
 static int f2fs_report_zone_cb(struct blk_zone *zone, unsigned int idx,
 			      void *data)
 {
 	struct f2fs_report_zones_args *rz_args = data;
+	block_t unusable_blocks = (zone->len - zone->capacity) >>
+					F2FS_LOG_SECTORS_PER_BLOCK;
 
 	if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL)
 		return 0;
 
 	set_bit(idx, rz_args->dev->blkz_seq);
-	rz_args->dev->zone_capacity_blocks[idx] = zone->capacity >>
-						F2FS_LOG_SECTORS_PER_BLOCK;
-	if (zone->len != zone->capacity && !rz_args->zone_cap_mismatch)
-		rz_args->zone_cap_mismatch = true;
-
+	if (!rz_args->sbi->unusable_blocks_per_sec) {
+		rz_args->sbi->unusable_blocks_per_sec = unusable_blocks;
+		return 0;
+	}
+	if (rz_args->sbi->unusable_blocks_per_sec != unusable_blocks) {
+		f2fs_err(rz_args->sbi, "F2FS supports single zone capacity\n");
+		return -EINVAL;
+	}
 	return 0;
 }
 
@@ -3564,26 +3572,13 @@
 	if (!FDEV(devi).blkz_seq)
 		return -ENOMEM;
 
-	/* Get block zones type and zone-capacity */
-	FDEV(devi).zone_capacity_blocks = f2fs_kzalloc(sbi,
-					FDEV(devi).nr_blkz * sizeof(block_t),
-					GFP_KERNEL);
-	if (!FDEV(devi).zone_capacity_blocks)
-		return -ENOMEM;
-
+	rep_zone_arg.sbi = sbi;
 	rep_zone_arg.dev = &FDEV(devi);
-	rep_zone_arg.zone_cap_mismatch = false;
 
 	ret = blkdev_report_zones(bdev, 0, BLK_ALL_ZONES, f2fs_report_zone_cb,
 				  &rep_zone_arg);
 	if (ret < 0)
 		return ret;
-
-	if (!rep_zone_arg.zone_cap_mismatch) {
-		kfree(FDEV(devi).zone_capacity_blocks);
-		FDEV(devi).zone_capacity_blocks = NULL;
-	}
-
 	return 0;
 }
 #endif
@@ -3905,7 +3900,7 @@
 		sbi->s_chksum_seed = f2fs_chksum(sbi, ~0, raw_super->uuid,
 						sizeof(raw_super->uuid));
 
-	default_options(sbi);
+	default_options(sbi, false);
 	/* parse mount options */
 	options = kstrdup((const char *)data, GFP_KERNEL);
 	if (data && !options) {
diff --git a/kernel/fs/f2fs/sysfs.c b/kernel/fs/f2fs/sysfs.c
index a095919..c707b93 100644
--- a/kernel/fs/f2fs/sysfs.c
+++ b/kernel/fs/f2fs/sysfs.c
@@ -466,6 +466,13 @@
 			}
 		} else if (t == 2) {
 			sbi->gc_mode = GC_URGENT_LOW;
+		} else if (t == 3) {
+			sbi->gc_mode = GC_URGENT_MID;
+			if (sbi->gc_thread) {
+				sbi->gc_thread->gc_wake = 1;
+				wake_up_interruptible_all(
+					&sbi->gc_thread->gc_wait_queue_head);
+			}
 		} else {
 			return -EINVAL;
 		}
@@ -496,9 +503,9 @@
 	if (!strcmp(a->attr.name, "iostat_period_ms")) {
 		if (t < MIN_IOSTAT_PERIOD_MS || t > MAX_IOSTAT_PERIOD_MS)
 			return -EINVAL;
-		spin_lock(&sbi->iostat_lock);
+		spin_lock_irq(&sbi->iostat_lock);
 		sbi->iostat_period_ms = (unsigned int)t;
-		spin_unlock(&sbi->iostat_lock);
+		spin_unlock_irq(&sbi->iostat_lock);
 		return count;
 	}
 
diff --git a/kernel/fs/f2fs/verity.c b/kernel/fs/f2fs/verity.c
index 4a9db2d..9e8e42b 100644
--- a/kernel/fs/f2fs/verity.c
+++ b/kernel/fs/f2fs/verity.c
@@ -47,16 +47,13 @@
 		size_t n = min_t(size_t, count,
 				 PAGE_SIZE - offset_in_page(pos));
 		struct page *page;
-		void *addr;
 
 		page = read_mapping_page(inode->i_mapping, pos >> PAGE_SHIFT,
 					 NULL);
 		if (IS_ERR(page))
 			return PTR_ERR(page);
 
-		addr = kmap_atomic(page);
-		memcpy(buf, addr + offset_in_page(pos), n);
-		kunmap_atomic(addr);
+		memcpy_from_page(buf, page, offset_in_page(pos), n);
 
 		put_page(page);
 
@@ -81,8 +78,7 @@
 		size_t n = min_t(size_t, count,
 				 PAGE_SIZE - offset_in_page(pos));
 		struct page *page;
-		void *fsdata;
-		void *addr;
+		void *fsdata = NULL;
 		int res;
 
 		res = pagecache_write_begin(NULL, inode->i_mapping, pos, n, 0,
@@ -90,9 +86,7 @@
 		if (res)
 			return res;
 
-		addr = kmap_atomic(page);
-		memcpy(addr + offset_in_page(pos), buf, n);
-		kunmap_atomic(addr);
+		memcpy_to_page(page, offset_in_page(pos), buf, n);
 
 		res = pagecache_write_end(NULL, inode->i_mapping, pos, n, n,
 					  page, fsdata);
diff --git a/kernel/fs/file.c b/kernel/fs/file.c
index 97a0cd3..d6bc739 100644
--- a/kernel/fs/file.c
+++ b/kernel/fs/file.c
@@ -677,6 +677,7 @@
 	fdt = files_fdtable(files);
 	if (fd >= fdt->max_fds)
 		goto out_unlock;
+	fd = array_index_nospec(fd, fdt->max_fds);
 	file = fdt->fd[fd];
 	if (!file)
 		goto out_unlock;
@@ -1006,16 +1007,30 @@
 	return __fget_light(fd, 0);
 }
 
+/*
+ * Try to avoid f_pos locking. We only need it if the
+ * file is marked for FMODE_ATOMIC_POS, and it can be
+ * accessed multiple ways.
+ *
+ * Always do it for directories, because pidfd_getfd()
+ * can make a file accessible even if it otherwise would
+ * not be, and for directories this is a correctness
+ * issue, not a "POSIX requirement".
+ */
+static inline bool file_needs_f_pos_lock(struct file *file)
+{
+	return (file->f_mode & FMODE_ATOMIC_POS) &&
+		(file_count(file) > 1 || S_ISDIR(file_inode(file)->i_mode));
+}
+
 unsigned long __fdget_pos(unsigned int fd)
 {
 	unsigned long v = __fdget(fd);
 	struct file *file = (struct file *)(v & ~3);
 
-	if (file && (file->f_mode & FMODE_ATOMIC_POS)) {
-		if (file_count(file) > 1) {
-			v |= FDPUT_POS_UNLOCK;
-			mutex_lock(&file->f_pos_lock);
-		}
+	if (file && file_needs_f_pos_lock(file)) {
+		v |= FDPUT_POS_UNLOCK;
+		mutex_lock(&file->f_pos_lock);
 	}
 	return v;
 }
diff --git a/kernel/fs/fs-writeback.c b/kernel/fs/fs-writeback.c
index 87bf2ff..86a1155 100644
--- a/kernel/fs/fs-writeback.c
+++ b/kernel/fs/fs-writeback.c
@@ -700,7 +700,7 @@
 		 * is okay.  The main goal is avoiding keeping an inode on
 		 * the wrong wb for an extended period of time.
 		 */
-		if (hweight32(history) > WB_FRN_HIST_THR_SLOTS)
+		if (hweight16(history) > WB_FRN_HIST_THR_SLOTS)
 			inode_switch_wbs(inode, max_id);
 	}
 
@@ -884,6 +884,16 @@
 			continue;
 		}
 
+		/*
+		 * If wb_tryget fails, the wb has been shutdown, skip it.
+		 *
+		 * Pin @wb so that it stays on @bdi->wb_list.  This allows
+		 * continuing iteration from @wb after dropping and
+		 * regrabbing rcu read lock.
+		 */
+		if (!wb_tryget(wb))
+			continue;
+
 		/* alloc failed, execute synchronously using on-stack fallback */
 		work = &fallback_work;
 		*work = *base_work;
@@ -892,13 +902,6 @@
 		work->done = &fallback_work_done;
 
 		wb_queue_work(wb, work);
-
-		/*
-		 * Pin @wb so that it stays on @bdi->wb_list.  This allows
-		 * continuing iteration from @wb after dropping and
-		 * regrabbing rcu read lock.
-		 */
-		wb_get(wb);
 		last_wb = wb;
 
 		rcu_read_unlock();
diff --git a/kernel/fs/fs_context.c b/kernel/fs/fs_context.c
index 740322d..e6ef7e0 100644
--- a/kernel/fs/fs_context.c
+++ b/kernel/fs/fs_context.c
@@ -543,7 +543,8 @@
 			return -ENOMEM;
 	}
 
-	ctx->legacy_data[size++] = ',';
+	if (size)
+		ctx->legacy_data[size++] = ',';
 	len = strlen(param->key);
 	memcpy(ctx->legacy_data + size, param->key, len);
 	size += len;
diff --git a/kernel/fs/fuse/dir.c b/kernel/fs/fuse/dir.c
index b3730a2..34a4a0e 100644
--- a/kernel/fs/fuse/dir.c
+++ b/kernel/fs/fuse/dir.c
@@ -205,7 +205,7 @@
 	if (inode && fuse_is_bad(inode))
 		goto invalid;
 	else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
-		 (flags & (LOOKUP_EXCL | LOOKUP_REVAL))) {
+		 (flags & (LOOKUP_EXCL | LOOKUP_REVAL | LOOKUP_RENAME_TARGET))) {
 		struct fuse_entry_out outarg;
 		FUSE_ARGS(args);
 		struct fuse_forget_link *forget;
@@ -249,7 +249,7 @@
 			spin_unlock(&fi->lock);
 		}
 		kfree(forget);
-		if (ret == -ENOMEM)
+		if (ret == -ENOMEM || ret == -EINTR)
 			goto out;
 		if (ret || fuse_invalid_attr(&outarg.attr) ||
 		    fuse_stale_inode(inode, outarg.generation, &outarg.attr))
@@ -578,6 +578,7 @@
 	struct fuse_entry_out outentry;
 	struct fuse_inode *fi;
 	struct fuse_file *ff;
+	bool trunc = flags & O_TRUNC;
 
 	/* Userspace expects S_IFREG in create mode */
 	BUG_ON((mode & S_IFMT) != S_IFREG);
@@ -646,6 +647,10 @@
 	} else {
 		file->private_data = ff;
 		fuse_finish_open(inode, file);
+		if (fm->fc->atomic_o_trunc && trunc)
+			truncate_pagecache(inode, 0);
+		else if (!(ff->open_flags & FOPEN_KEEP_CACHE))
+			invalidate_inode_pages2(inode->i_mapping);
 	}
 	return err;
 
diff --git a/kernel/fs/fuse/file.c b/kernel/fs/fuse/file.c
index 34dd646..de1cb5a 100644
--- a/kernel/fs/fuse/file.c
+++ b/kernel/fs/fuse/file.c
@@ -206,14 +206,10 @@
 		fi->attr_version = atomic64_inc_return(&fc->attr_version);
 		i_size_write(inode, 0);
 		spin_unlock(&fi->lock);
-		truncate_pagecache(inode, 0);
 		fuse_invalidate_attr(inode);
 		if (fc->writeback_cache)
 			file_update_time(file);
-	} else if (!(ff->open_flags & FOPEN_KEEP_CACHE)) {
-		invalidate_inode_pages2(inode->i_mapping);
 	}
-
 	if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache)
 		fuse_link_write_file(file);
 }
@@ -236,30 +232,39 @@
 	if (err)
 		return err;
 
-	if (is_wb_truncate || dax_truncate) {
+	if (is_wb_truncate || dax_truncate)
 		inode_lock(inode);
-		fuse_set_nowrite(inode);
-	}
 
 	if (dax_truncate) {
 		down_write(&get_fuse_inode(inode)->i_mmap_sem);
 		err = fuse_dax_break_layouts(inode, 0, 0);
 		if (err)
-			goto out;
+			goto out_inode_unlock;
 	}
+
+	if (is_wb_truncate || dax_truncate)
+		fuse_set_nowrite(inode);
 
 	err = fuse_do_open(fm, get_node_id(inode), file, isdir);
 	if (!err)
 		fuse_finish_open(inode, file);
 
-out:
+	if (is_wb_truncate || dax_truncate)
+		fuse_release_nowrite(inode);
+	if (!err) {
+		struct fuse_file *ff = file->private_data;
+
+		if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC))
+			truncate_pagecache(inode, 0);
+		else if (!(ff->open_flags & FOPEN_KEEP_CACHE))
+			invalidate_inode_pages2(inode->i_mapping);
+	}
 	if (dax_truncate)
 		up_write(&get_fuse_inode(inode)->i_mmap_sem);
 
-	if (is_wb_truncate | dax_truncate) {
-		fuse_release_nowrite(inode);
+out_inode_unlock:
+	if (is_wb_truncate || dax_truncate)
 		inode_unlock(inode);
-	}
 
 	return err;
 }
@@ -784,7 +789,7 @@
 	struct fuse_inode *fi = get_fuse_inode(inode);
 
 	spin_lock(&fi->lock);
-	if (attr_ver == fi->attr_version && size < inode->i_size &&
+	if (attr_ver >= fi->attr_version && size < inode->i_size &&
 	    !test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) {
 		fi->attr_version = atomic64_inc_return(&fc->attr_version);
 		i_size_write(inode, size);
diff --git a/kernel/fs/fuse/fuse_i.h b/kernel/fs/fuse/fuse_i.h
index e20c341..bbbbd8e 100644
--- a/kernel/fs/fuse/fuse_i.h
+++ b/kernel/fs/fuse/fuse_i.h
@@ -571,6 +571,9 @@
 	/** Maxmum number of pages that can be used in a single request */
 	unsigned int max_pages;
 
+	/** Constrain ->max_pages to this value during feature negotiation */
+	unsigned int max_pages_limit;
+
 	/** Input queue */
 	struct fuse_iqueue iq;
 
diff --git a/kernel/fs/fuse/inode.c b/kernel/fs/fuse/inode.c
index 50c595b..47490cc 100644
--- a/kernel/fs/fuse/inode.c
+++ b/kernel/fs/fuse/inode.c
@@ -713,6 +713,7 @@
 	fc->pid_ns = get_pid_ns(task_active_pid_ns(current));
 	fc->user_ns = get_user_ns(user_ns);
 	fc->max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ;
+	fc->max_pages_limit = FUSE_MAX_MAX_PAGES;
 
 	INIT_LIST_HEAD(&fc->mounts);
 	list_add(&fm->fc_entry, &fc->mounts);
@@ -1059,7 +1060,7 @@
 				fc->abort_err = 1;
 			if (arg->flags & FUSE_MAX_PAGES) {
 				fc->max_pages =
-					min_t(unsigned int, FUSE_MAX_MAX_PAGES,
+					min_t(unsigned int, fc->max_pages_limit,
 					max_t(unsigned int, arg->max_pages, 1));
 			}
 			if (IS_ENABLED(CONFIG_FUSE_DAX) &&
@@ -1617,7 +1618,7 @@
 	struct fuse_mount *fm = get_fuse_mount_super(sb);
 	bool last;
 
-	if (fm) {
+	if (sb->s_root) {
 		last = fuse_mount_remove(fm);
 		if (last)
 			fuse_conn_destroy(fm);
diff --git a/kernel/fs/fuse/readdir.c b/kernel/fs/fuse/readdir.c
index d5294e6..14e99ff 100644
--- a/kernel/fs/fuse/readdir.c
+++ b/kernel/fs/fuse/readdir.c
@@ -243,8 +243,16 @@
 			dput(dentry);
 			dentry = alias;
 		}
-		if (IS_ERR(dentry))
+		if (IS_ERR(dentry)) {
+			if (!IS_ERR(inode)) {
+				struct fuse_inode *fi = get_fuse_inode(inode);
+
+				spin_lock(&fi->lock);
+				fi->nlookup--;
+				spin_unlock(&fi->lock);
+			}
 			return PTR_ERR(dentry);
+		}
 	}
 	if (fc->readdirplus_auto)
 		set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state);
diff --git a/kernel/fs/fuse/virtio_fs.c b/kernel/fs/fuse/virtio_fs.c
index 90a574b..86b553c 100644
--- a/kernel/fs/fuse/virtio_fs.c
+++ b/kernel/fs/fuse/virtio_fs.c
@@ -18,6 +18,12 @@
 #include <linux/uio.h>
 #include "fuse_i.h"
 
+/* Used to help calculate the FUSE connection's max_pages limit for a request's
+ * size. Parts of the struct fuse_req are sliced into scattergather lists in
+ * addition to the pages used, so this can help account for that overhead.
+ */
+#define FUSE_HEADER_OVERHEAD    4
+
 /* List of virtio-fs device instances and a lock for the list. Also provides
  * mutual exclusion in device removal and mounting path
  */
@@ -1395,7 +1401,7 @@
 	bool last;
 
 	/* If mount failed, we can still be called without any fc */
-	if (fm) {
+	if (sb->s_root) {
 		last = fuse_mount_remove(fm);
 		if (last)
 			virtio_fs_conn_destroy(fm);
@@ -1428,9 +1434,10 @@
 {
 	struct virtio_fs *fs;
 	struct super_block *sb;
-	struct fuse_conn *fc;
+	struct fuse_conn *fc = NULL;
 	struct fuse_mount *fm;
-	int err;
+	unsigned int virtqueue_size;
+	int err = -EIO;
 
 	/* This gets a reference on virtio_fs object. This ptr gets installed
 	 * in fc->iq->priv. Once fuse_conn is going away, it calls ->put()
@@ -1442,27 +1449,27 @@
 		return -EINVAL;
 	}
 
+	virtqueue_size = virtqueue_get_vring_size(fs->vqs[VQ_REQUEST].vq);
+	if (WARN_ON(virtqueue_size <= FUSE_HEADER_OVERHEAD))
+		goto out_err;
+
+	err = -ENOMEM;
 	fc = kzalloc(sizeof(struct fuse_conn), GFP_KERNEL);
-	if (!fc) {
-		mutex_lock(&virtio_fs_mutex);
-		virtio_fs_put(fs);
-		mutex_unlock(&virtio_fs_mutex);
-		return -ENOMEM;
-	}
+	if (!fc)
+		goto out_err;
 
 	fm = kzalloc(sizeof(struct fuse_mount), GFP_KERNEL);
-	if (!fm) {
-		mutex_lock(&virtio_fs_mutex);
-		virtio_fs_put(fs);
-		mutex_unlock(&virtio_fs_mutex);
-		kfree(fc);
-		return -ENOMEM;
-	}
+	if (!fm)
+		goto out_err;
 
 	fuse_conn_init(fc, fm, fsc->user_ns, &virtio_fs_fiq_ops, fs);
 	fc->release = fuse_free_conn;
 	fc->delete_stale = true;
 	fc->auto_submounts = true;
+
+	/* Tell FUSE to split requests that exceed the virtqueue's size */
+	fc->max_pages_limit = min_t(unsigned int, fc->max_pages_limit,
+				    virtqueue_size - FUSE_HEADER_OVERHEAD);
 
 	fsc->s_fs_info = fm;
 	sb = sget_fc(fsc, virtio_fs_test_super, virtio_fs_set_super);
@@ -1485,6 +1492,13 @@
 	WARN_ON(fsc->root);
 	fsc->root = dget(sb->s_root);
 	return 0;
+
+out_err:
+	kfree(fc);
+	mutex_lock(&virtio_fs_mutex);
+	virtio_fs_put(fs);
+	mutex_unlock(&virtio_fs_mutex);
+	return err;
 }
 
 static const struct fs_context_operations virtio_fs_context_ops = {
diff --git a/kernel/fs/gfs2/aops.c b/kernel/fs/gfs2/aops.c
index cc4f987..a0430da 100644
--- a/kernel/fs/gfs2/aops.c
+++ b/kernel/fs/gfs2/aops.c
@@ -152,7 +152,6 @@
 {
 	struct inode *inode = page->mapping->host;
 	struct gfs2_inode *ip = GFS2_I(inode);
-	struct gfs2_sbd *sdp = GFS2_SB(inode);
 
 	if (PageChecked(page)) {
 		ClearPageChecked(page);
@@ -160,7 +159,7 @@
 			create_empty_buffers(page, inode->i_sb->s_blocksize,
 					     BIT(BH_Dirty)|BIT(BH_Uptodate));
 		}
-		gfs2_page_add_databufs(ip, page, 0, sdp->sd_vfs->s_blocksize);
+		gfs2_page_add_databufs(ip, page, 0, PAGE_SIZE);
 	}
 	return gfs2_write_jdata_page(page, wbc);
 }
@@ -452,8 +451,6 @@
 		return error;
 
 	kaddr = kmap_atomic(page);
-	if (dsize > gfs2_max_stuffed_size(ip))
-		dsize = gfs2_max_stuffed_size(ip);
 	memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
 	memset(kaddr + dsize, 0, PAGE_SIZE - dsize);
 	kunmap_atomic(kaddr);
diff --git a/kernel/fs/gfs2/bmap.c b/kernel/fs/gfs2/bmap.c
index b4fde3a..eaee95d 100644
--- a/kernel/fs/gfs2/bmap.c
+++ b/kernel/fs/gfs2/bmap.c
@@ -69,9 +69,6 @@
 		void *kaddr = kmap(page);
 		u64 dsize = i_size_read(inode);
  
-		if (dsize > gfs2_max_stuffed_size(ip))
-			dsize = gfs2_max_stuffed_size(ip);
-
 		memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
 		memset(kaddr + dsize, 0, PAGE_SIZE - dsize);
 		kunmap(page);
diff --git a/kernel/fs/gfs2/glops.c b/kernel/fs/gfs2/glops.c
index bf539ea..87f8110 100644
--- a/kernel/fs/gfs2/glops.c
+++ b/kernel/fs/gfs2/glops.c
@@ -405,6 +405,7 @@
 
 static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
 {
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	const struct gfs2_dinode *str = buf;
 	struct timespec64 atime;
 	u16 height, depth;
@@ -444,7 +445,7 @@
 	/* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */
 	gfs2_set_inode_flags(&ip->i_inode);
 	height = be16_to_cpu(str->di_height);
-	if (unlikely(height > GFS2_MAX_META_HEIGHT))
+	if (unlikely(height > sdp->sd_max_height))
 		goto corrupt;
 	ip->i_height = (u8)height;
 
@@ -454,6 +455,9 @@
 	ip->i_depth = (u8)depth;
 	ip->i_entries = be32_to_cpu(str->di_entries);
 
+	if (gfs2_is_stuffed(ip) && ip->i_inode.i_size > gfs2_max_stuffed_size(ip))
+		goto corrupt;
+
 	if (S_ISREG(ip->i_inode.i_mode))
 		gfs2_set_aops(&ip->i_inode);
 
diff --git a/kernel/fs/gfs2/super.c b/kernel/fs/gfs2/super.c
index d14b98a..b61de8d 100644
--- a/kernel/fs/gfs2/super.c
+++ b/kernel/fs/gfs2/super.c
@@ -145,8 +145,10 @@
 		return -EIO;
 
 	error = gfs2_find_jhead(sdp->sd_jdesc, &head, false);
-	if (error || gfs2_withdrawn(sdp))
+	if (error) {
+		gfs2_consist(sdp);
 		return error;
+	}
 
 	if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) {
 		gfs2_consist(sdp);
@@ -158,7 +160,9 @@
 	gfs2_log_pointers_init(sdp, head.lh_blkno);
 
 	error = gfs2_quota_init(sdp);
-	if (!error && !gfs2_withdrawn(sdp))
+	if (!error && gfs2_withdrawn(sdp))
+		error = -EIO;
+	if (!error)
 		set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
 	return error;
 }
@@ -1013,7 +1017,14 @@
 {
 	struct gfs2_sbd *sdp = root->d_sb->s_fs_info;
 	struct gfs2_args *args = &sdp->sd_args;
-	int val;
+	unsigned int logd_secs, statfs_slow, statfs_quantum, quota_quantum;
+
+	spin_lock(&sdp->sd_tune.gt_spin);
+	logd_secs = sdp->sd_tune.gt_logd_secs;
+	quota_quantum = sdp->sd_tune.gt_quota_quantum;
+	statfs_quantum = sdp->sd_tune.gt_statfs_quantum;
+	statfs_slow = sdp->sd_tune.gt_statfs_slow;
+	spin_unlock(&sdp->sd_tune.gt_spin);
 
 	if (is_ancestor(root, sdp->sd_master_dir))
 		seq_puts(s, ",meta");
@@ -1068,17 +1079,14 @@
 	}
 	if (args->ar_discard)
 		seq_puts(s, ",discard");
-	val = sdp->sd_tune.gt_logd_secs;
-	if (val != 30)
-		seq_printf(s, ",commit=%d", val);
-	val = sdp->sd_tune.gt_statfs_quantum;
-	if (val != 30)
-		seq_printf(s, ",statfs_quantum=%d", val);
-	else if (sdp->sd_tune.gt_statfs_slow)
+	if (logd_secs != 30)
+		seq_printf(s, ",commit=%d", logd_secs);
+	if (statfs_quantum != 30)
+		seq_printf(s, ",statfs_quantum=%d", statfs_quantum);
+	else if (statfs_slow)
 		seq_puts(s, ",statfs_quantum=0");
-	val = sdp->sd_tune.gt_quota_quantum;
-	if (val != 60)
-		seq_printf(s, ",quota_quantum=%d", val);
+	if (quota_quantum != 60)
+		seq_printf(s, ",quota_quantum=%d", quota_quantum);
 	if (args->ar_statfs_percent)
 		seq_printf(s, ",statfs_percent=%d", args->ar_statfs_percent);
 	if (args->ar_errors != GFS2_ERRORS_DEFAULT) {
@@ -1412,6 +1420,14 @@
 	if (inode->i_nlink || sb_rdonly(sb))
 		goto out;
 
+	/*
+	 * In case of an incomplete mount, gfs2_evict_inode() may be called for
+	 * system files without having an active journal to write to.  In that
+	 * case, skip the filesystem evict.
+	 */
+	if (!sdp->sd_jdesc)
+		goto out;
+
 	gfs2_holder_mark_uninitialized(&gh);
 	ret = evict_should_delete(inode, &gh);
 	if (ret == SHOULD_DEFER_EVICTION)
diff --git a/kernel/fs/hfs/bnode.c b/kernel/fs/hfs/bnode.c
index c0a73a6..397e02a 100644
--- a/kernel/fs/hfs/bnode.c
+++ b/kernel/fs/hfs/bnode.c
@@ -281,6 +281,7 @@
 		tree->node_hash[hash] = node;
 		tree->node_hash_cnt++;
 	} else {
+		hfs_bnode_get(node2);
 		spin_unlock(&tree->hash_lock);
 		kfree(node);
 		wait_event(node2->lock_wq, !test_bit(HFS_BNODE_NEW, &node2->flags));
diff --git a/kernel/fs/hfs/inode.c b/kernel/fs/hfs/inode.c
index f35a37c..6fbde99 100644
--- a/kernel/fs/hfs/inode.c
+++ b/kernel/fs/hfs/inode.c
@@ -454,14 +454,16 @@
 		/* panic? */
 		return -EIO;
 
+	res = -EIO;
+	if (HFS_I(main_inode)->cat_key.CName.len > HFS_NAMELEN)
+		goto out;
 	fd.search_key->cat = HFS_I(main_inode)->cat_key;
 	if (hfs_brec_find(&fd))
-		/* panic? */
 		goto out;
 
 	if (S_ISDIR(main_inode->i_mode)) {
 		if (fd.entrylength < sizeof(struct hfs_cat_dir))
-			/* panic? */;
+			goto out;
 		hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
 			   sizeof(struct hfs_cat_dir));
 		if (rec.type != HFS_CDR_DIR ||
@@ -474,6 +476,8 @@
 		hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
 			    sizeof(struct hfs_cat_dir));
 	} else if (HFS_IS_RSRC(inode)) {
+		if (fd.entrylength < sizeof(struct hfs_cat_file))
+			goto out;
 		hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
 			       sizeof(struct hfs_cat_file));
 		hfs_inode_write_fork(inode, rec.file.RExtRec,
@@ -482,7 +486,7 @@
 				sizeof(struct hfs_cat_file));
 	} else {
 		if (fd.entrylength < sizeof(struct hfs_cat_file))
-			/* panic? */;
+			goto out;
 		hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
 			   sizeof(struct hfs_cat_file));
 		if (rec.type != HFS_CDR_FIL ||
@@ -499,9 +503,10 @@
 		hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
 			    sizeof(struct hfs_cat_file));
 	}
+	res = 0;
 out:
 	hfs_find_exit(&fd);
-	return 0;
+	return res;
 }
 
 static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry,
diff --git a/kernel/fs/hfs/trans.c b/kernel/fs/hfs/trans.c
index 39f5e34..fdb0edb 100644
--- a/kernel/fs/hfs/trans.c
+++ b/kernel/fs/hfs/trans.c
@@ -109,7 +109,7 @@
 	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 = '?';
diff --git a/kernel/fs/hfsplus/hfsplus_fs.h b/kernel/fs/hfsplus/hfsplus_fs.h
index a92de51..c438680 100644
--- a/kernel/fs/hfsplus/hfsplus_fs.h
+++ b/kernel/fs/hfsplus/hfsplus_fs.h
@@ -198,6 +198,8 @@
 #define HFSPLUS_SB_HFSX		3
 #define HFSPLUS_SB_CASEFOLD	4
 #define HFSPLUS_SB_NOBARRIER	5
+#define HFSPLUS_SB_UID		6
+#define HFSPLUS_SB_GID		7
 
 static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb)
 {
diff --git a/kernel/fs/hfsplus/inode.c b/kernel/fs/hfsplus/inode.c
index e3da9e9..7e1d889 100644
--- a/kernel/fs/hfsplus/inode.c
+++ b/kernel/fs/hfsplus/inode.c
@@ -187,11 +187,11 @@
 	mode = be16_to_cpu(perms->mode);
 
 	i_uid_write(inode, be32_to_cpu(perms->owner));
-	if (!i_uid_read(inode) && !mode)
+	if ((test_bit(HFSPLUS_SB_UID, &sbi->flags)) || (!i_uid_read(inode) && !mode))
 		inode->i_uid = sbi->uid;
 
 	i_gid_write(inode, be32_to_cpu(perms->group));
-	if (!i_gid_read(inode) && !mode)
+	if ((test_bit(HFSPLUS_SB_GID, &sbi->flags)) || (!i_gid_read(inode) && !mode))
 		inode->i_gid = sbi->gid;
 
 	if (dir) {
@@ -497,8 +497,11 @@
 	if (type == HFSPLUS_FOLDER) {
 		struct hfsplus_cat_folder *folder = &entry.folder;
 
-		if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
-			/* panic? */;
+		if (fd->entrylength < sizeof(struct hfsplus_cat_folder)) {
+			pr_err("bad catalog folder entry\n");
+			res = -EIO;
+			goto out;
+		}
 		hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
 					sizeof(struct hfsplus_cat_folder));
 		hfsplus_get_perms(inode, &folder->permissions, 1);
@@ -518,8 +521,11 @@
 	} else if (type == HFSPLUS_FILE) {
 		struct hfsplus_cat_file *file = &entry.file;
 
-		if (fd->entrylength < sizeof(struct hfsplus_cat_file))
-			/* panic? */;
+		if (fd->entrylength < sizeof(struct hfsplus_cat_file)) {
+			pr_err("bad catalog file entry\n");
+			res = -EIO;
+			goto out;
+		}
 		hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
 					sizeof(struct hfsplus_cat_file));
 
@@ -550,6 +556,7 @@
 		pr_err("bad catalog entry used to create inode\n");
 		res = -EIO;
 	}
+out:
 	return res;
 }
 
@@ -558,6 +565,7 @@
 	struct inode *main_inode = inode;
 	struct hfs_find_data fd;
 	hfsplus_cat_entry entry;
+	int res = 0;
 
 	if (HFSPLUS_IS_RSRC(inode))
 		main_inode = HFSPLUS_I(inode)->rsrc_inode;
@@ -576,8 +584,11 @@
 	if (S_ISDIR(main_inode->i_mode)) {
 		struct hfsplus_cat_folder *folder = &entry.folder;
 
-		if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
-			/* panic? */;
+		if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) {
+			pr_err("bad catalog folder entry\n");
+			res = -EIO;
+			goto out;
+		}
 		hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
 					sizeof(struct hfsplus_cat_folder));
 		/* simple node checks? */
@@ -602,8 +613,11 @@
 	} else {
 		struct hfsplus_cat_file *file = &entry.file;
 
-		if (fd.entrylength < sizeof(struct hfsplus_cat_file))
-			/* panic? */;
+		if (fd.entrylength < sizeof(struct hfsplus_cat_file)) {
+			pr_err("bad catalog file entry\n");
+			res = -EIO;
+			goto out;
+		}
 		hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
 					sizeof(struct hfsplus_cat_file));
 		hfsplus_inode_write_fork(inode, &file->data_fork);
@@ -624,5 +638,5 @@
 	set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags);
 out:
 	hfs_find_exit(&fd);
-	return 0;
+	return res;
 }
diff --git a/kernel/fs/hfsplus/options.c b/kernel/fs/hfsplus/options.c
index 047e05c..c94a587 100644
--- a/kernel/fs/hfsplus/options.c
+++ b/kernel/fs/hfsplus/options.c
@@ -140,6 +140,8 @@
 			if (!uid_valid(sbi->uid)) {
 				pr_err("invalid uid specified\n");
 				return 0;
+			} else {
+				set_bit(HFSPLUS_SB_UID, &sbi->flags);
 			}
 			break;
 		case opt_gid:
@@ -151,6 +153,8 @@
 			if (!gid_valid(sbi->gid)) {
 				pr_err("invalid gid specified\n");
 				return 0;
+			} else {
+				set_bit(HFSPLUS_SB_GID, &sbi->flags);
 			}
 			break;
 		case opt_part:
diff --git a/kernel/fs/hfsplus/super.c b/kernel/fs/hfsplus/super.c
index 2b0031c..39810b8 100644
--- a/kernel/fs/hfsplus/super.c
+++ b/kernel/fs/hfsplus/super.c
@@ -295,11 +295,11 @@
 		hfsplus_sync_fs(sb, 1);
 	}
 
+	iput(sbi->alloc_file);
+	iput(sbi->hidden_dir);
 	hfs_btree_close(sbi->attr_tree);
 	hfs_btree_close(sbi->cat_tree);
 	hfs_btree_close(sbi->ext_tree);
-	iput(sbi->alloc_file);
-	iput(sbi->hidden_dir);
 	kfree(sbi->s_vhdr_buf);
 	kfree(sbi->s_backup_vhdr_buf);
 	unload_nls(sbi->nls);
diff --git a/kernel/fs/hugetlbfs/inode.c b/kernel/fs/hugetlbfs/inode.c
index a2f43f1..5181e6d 100644
--- a/kernel/fs/hugetlbfs/inode.c
+++ b/kernel/fs/hugetlbfs/inode.c
@@ -1261,7 +1261,7 @@
 
 	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 @@
 
 	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 @@
 
 	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;
diff --git a/kernel/fs/incfs/data_mgmt.c b/kernel/fs/incfs/data_mgmt.c
index fbab68a..6381f8f 100644
--- a/kernel/fs/incfs/data_mgmt.c
+++ b/kernel/fs/incfs/data_mgmt.c
@@ -3,7 +3,6 @@
  * Copyright 2019 Google LLC
  */
 #include <linux/crc32.h>
-#include <linux/delay.h>
 #include <linux/file.h>
 #include <linux/fsverity.h>
 #include <linux/gfp.h>
@@ -1104,25 +1103,10 @@
 	wake_up_all(&mi->mi_blocks_written_notif_wq);
 }
 
-static int usleep_interruptible(u32 us)
-{
-	/* See:
-	 * https://www.kernel.org/doc/Documentation/timers/timers-howto.txt
-	 * for explanation
-	 */
-	if (us < 10) {
-		udelay(us);
-		return 0;
-	} else if (us < 20000) {
-		usleep_range(us, us + us / 10);
-		return 0;
-	} else
-		return msleep_interruptible(us / 1000);
-}
-
 static int wait_for_data_block(struct data_file *df, int block_index,
 			       struct data_file_block *res_block,
-			       struct incfs_read_data_file_timeouts *timeouts)
+			       struct incfs_read_data_file_timeouts *timeouts,
+			       unsigned int *delayed_min_us)
 {
 	struct data_file_block block = {};
 	struct data_file_segment *segment = NULL;
@@ -1130,7 +1114,7 @@
 	struct mount_info *mi = NULL;
 	int error;
 	int wait_res = 0;
-	unsigned int delayed_pending_us = 0, delayed_min_us = 0;
+	unsigned int delayed_pending_us = 0;
 	bool delayed_pending = false;
 
 	if (!df || !res_block)
@@ -1161,8 +1145,7 @@
 	if (is_data_block_present(&block)) {
 		*res_block = block;
 		if (timeouts && timeouts->min_time_us) {
-			delayed_min_us = timeouts->min_time_us;
-			error = usleep_interruptible(delayed_min_us);
+			*delayed_min_us = timeouts->min_time_us;
 			goto out;
 		}
 		return 0;
@@ -1209,13 +1192,9 @@
 	delayed_pending = true;
 	delayed_pending_us = timeouts->max_pending_time_us -
 				jiffies_to_usecs(wait_res);
-	if (timeouts->min_pending_time_us > delayed_pending_us) {
-		delayed_min_us = timeouts->min_pending_time_us -
+	if (timeouts->min_pending_time_us > delayed_pending_us)
+		*delayed_min_us = timeouts->min_pending_time_us -
 					     delayed_pending_us;
-		error = usleep_interruptible(delayed_min_us);
-		if (error)
-			return error;
-	}
 
 	error = down_read_killable(&segment->rwsem);
 	if (error)
@@ -1250,9 +1229,9 @@
 			delayed_pending_us;
 	}
 
-	if (delayed_min_us) {
+	if (delayed_min_us && *delayed_min_us) {
 		mi->mi_reads_delayed_min++;
-		mi->mi_reads_delayed_min_us += delayed_min_us;
+		mi->mi_reads_delayed_min_us += *delayed_min_us;
 	}
 
 	return 0;
@@ -1282,7 +1261,8 @@
 
 ssize_t incfs_read_data_file_block(struct mem_range dst, struct file *f,
 			int index, struct mem_range tmp,
-			struct incfs_read_data_file_timeouts *timeouts)
+			struct incfs_read_data_file_timeouts *timeouts,
+			unsigned int *delayed_min_us)
 {
 	loff_t pos;
 	ssize_t result;
@@ -1301,7 +1281,8 @@
 	mi = df->df_mount_info;
 	bfc = df->df_backing_file_context;
 
-	result = wait_for_data_block(df, index, &block, timeouts);
+	result = wait_for_data_block(df, index, &block, timeouts,
+				     delayed_min_us);
 	if (result < 0)
 		goto out;
 
@@ -1379,7 +1360,8 @@
 }
 
 int incfs_process_new_data_block(struct data_file *df,
-				 struct incfs_fill_block *block, u8 *data)
+				 struct incfs_fill_block *block, u8 *data,
+				 bool *complete)
 {
 	struct mount_info *mi = NULL;
 	struct backing_file_context *bfc = NULL;
@@ -1418,27 +1400,42 @@
 
 	if (error)
 		return error;
-	if (is_data_block_present(&existing_block)) {
+	if (is_data_block_present(&existing_block))
 		/* Block is already present, nothing to do here */
 		return 0;
-	}
 
 	error = down_write_killable(&segment->rwsem);
 	if (error)
 		return error;
 
-	error = mutex_lock_interruptible(&bfc->bc_mutex);
-	if (!error) {
-		error = incfs_write_data_block_to_backing_file(
-			bfc, range(data, block->data_len), block->block_index,
-			df->df_blockmap_off, flags);
-		mutex_unlock(&bfc->bc_mutex);
-	}
-	if (!error) {
-		notify_pending_reads(mi, segment, block->block_index);
-		atomic_inc(&df->df_data_blocks_written);
-	}
+	/* Recheck inside write lock */
+	error = get_data_file_block(df, block->block_index, &existing_block);
+	if (error)
+		goto out_up_write;
 
+	if (is_data_block_present(&existing_block))
+		goto out_up_write;
+
+	error = mutex_lock_interruptible(&bfc->bc_mutex);
+	if (error)
+		goto out_up_write;
+
+	error = incfs_write_data_block_to_backing_file(bfc,
+			range(data, block->data_len), block->block_index,
+			df->df_blockmap_off, flags);
+	if (error)
+		goto out_mutex_unlock;
+
+	if (atomic_inc_return(&df->df_data_blocks_written)
+			>= df->df_data_block_count)
+		*complete = true;
+
+out_mutex_unlock:
+	mutex_unlock(&bfc->bc_mutex);
+	if (!error)
+		notify_pending_reads(mi, segment, block->block_index);
+
+out_up_write:
 	up_write(&segment->rwsem);
 
 	if (error)
diff --git a/kernel/fs/incfs/data_mgmt.h b/kernel/fs/incfs/data_mgmt.h
index 2227913..8bd5c2f 100644
--- a/kernel/fs/incfs/data_mgmt.h
+++ b/kernel/fs/incfs/data_mgmt.h
@@ -429,7 +429,8 @@
 
 ssize_t incfs_read_data_file_block(struct mem_range dst, struct file *f,
 			int index, struct mem_range tmp,
-			struct incfs_read_data_file_timeouts *timeouts);
+			struct incfs_read_data_file_timeouts *timeouts,
+			unsigned int *delayed_min_us);
 
 ssize_t incfs_read_merkle_tree_blocks(struct mem_range dst,
 				      struct data_file *df, size_t offset);
@@ -441,7 +442,8 @@
 int incfs_read_file_signature(struct data_file *df, struct mem_range dst);
 
 int incfs_process_new_data_block(struct data_file *df,
-				 struct incfs_fill_block *block, u8 *data);
+				 struct incfs_fill_block *block, u8 *data,
+				 bool *complete);
 
 int incfs_process_new_hash_block(struct data_file *df,
 				 struct incfs_fill_block *block, u8 *data);
diff --git a/kernel/fs/incfs/pseudo_files.c b/kernel/fs/incfs/pseudo_files.c
index 1b9bf00..d43ccb2 100644
--- a/kernel/fs/incfs/pseudo_files.c
+++ b/kernel/fs/incfs/pseudo_files.c
@@ -916,10 +916,10 @@
 	if (copy_from_user(&args, args_usr_ptr, sizeof(args)))
 		return -EINVAL;
 
-	if (args.timeouts_array_size_out > INCFS_DATA_FILE_BLOCK_SIZE)
+	if (args.timeouts_array_size > INCFS_DATA_FILE_BLOCK_SIZE)
 		return -EINVAL;
 
-	buffer = kzalloc(args.timeouts_array_size_out, GFP_NOFS);
+	buffer = kzalloc(args.timeouts_array_size, GFP_NOFS);
 	if (!buffer)
 		return -ENOMEM;
 
diff --git a/kernel/fs/incfs/sysfs.c b/kernel/fs/incfs/sysfs.c
index 360f03c..ba91c07 100644
--- a/kernel/fs/incfs/sysfs.c
+++ b/kernel/fs/incfs/sysfs.c
@@ -33,11 +33,15 @@
 DECLARE_FEATURE_FLAG(corefs);
 DECLARE_FEATURE_FLAG(zstd);
 DECLARE_FEATURE_FLAG(v2);
+DECLARE_FEATURE_FLAG(bugfix_throttling);
+DECLARE_FEATURE_FLAG(bugfix_inode_eviction);
 
 static struct attribute *attributes[] = {
 	&corefs_attr.attr,
 	&zstd_attr.attr,
 	&v2_attr.attr,
+	&bugfix_throttling_attr.attr,
+	&bugfix_inode_eviction_attr.attr,
 	NULL,
 };
 
diff --git a/kernel/fs/incfs/verity.c b/kernel/fs/incfs/verity.c
index a3dc94b..22308f8 100644
--- a/kernel/fs/incfs/verity.c
+++ b/kernel/fs/incfs/verity.c
@@ -323,7 +323,7 @@
 
 			if (lvl == 0)
 				result = incfs_read_data_file_block(partial_buf,
-						f, i, tmp, NULL);
+						f, i, tmp, NULL, NULL);
 			else {
 				hash_level_offset = hash_offset +
 				       hash_tree->hash_level_suboffset[lvl - 1];
diff --git a/kernel/fs/incfs/vfs.c b/kernel/fs/incfs/vfs.c
index 342998f..f393f17 100644
--- a/kernel/fs/incfs/vfs.c
+++ b/kernel/fs/incfs/vfs.c
@@ -5,6 +5,7 @@
 
 #include <linux/blkdev.h>
 #include <linux/compat.h>
+#include <linux/delay.h>
 #include <linux/file.h>
 #include <linux/fs.h>
 #include <linux/fs_stack.h>
@@ -477,7 +478,8 @@
 
 static int read_single_page_timeouts(struct data_file *df, struct file *f,
 				     int block_index, struct mem_range range,
-				     struct mem_range tmp)
+				     struct mem_range tmp,
+				     unsigned int *delayed_min_us)
 {
 	struct mount_info *mi = df->df_mount_info;
 	struct incfs_read_data_file_timeouts timeouts = {
@@ -509,7 +511,23 @@
 	}
 
 	return incfs_read_data_file_block(range, f, block_index, tmp,
-					  &timeouts);
+					  &timeouts, delayed_min_us);
+}
+
+static int usleep_interruptible(u32 us)
+{
+	/* See:
+	 * https://www.kernel.org/doc/Documentation/timers/timers-howto.txt
+	 * for explanation
+	 */
+	if (us < 10) {
+		udelay(us);
+		return 0;
+	} else if (us < 20000) {
+		usleep_range(us, us + us / 10);
+		return 0;
+	} else
+		return msleep_interruptible(us / 1000);
 }
 
 static int read_single_page(struct file *f, struct page *page)
@@ -522,6 +540,7 @@
 	int result = 0;
 	void *page_start;
 	int block_index;
+	unsigned int delayed_min_us = 0;
 
 	if (!df) {
 		SetPageError(page);
@@ -547,7 +566,8 @@
 		bytes_to_read = min_t(loff_t, size - offset, PAGE_SIZE);
 
 		read_result = read_single_page_timeouts(df, f, block_index,
-					range(page_start, bytes_to_read), tmp);
+					range(page_start, bytes_to_read), tmp,
+					&delayed_min_us);
 
 		free_pages((unsigned long)tmp.data, get_order(tmp.len));
 	} else {
@@ -569,6 +589,8 @@
 	flush_dcache_page(page);
 	kunmap(page);
 	unlock_page(page);
+	if (delayed_min_us)
+		usleep_interruptible(delayed_min_us);
 	return result;
 }
 
@@ -662,8 +684,7 @@
 	dput(file);
 }
 
-static void maybe_delete_incomplete_file(struct file *f,
-					 struct data_file *df)
+static void handle_file_completed(struct file *f, struct data_file *df)
 {
 	struct backing_file_context *bfc;
 	struct mount_info *mi = df->df_mount_info;
@@ -671,9 +692,6 @@
 	struct dentry *incomplete_file_dentry = NULL;
 	const struct cred *old_cred = override_creds(mi->mi_owner);
 	int error;
-
-	if (atomic_read(&df->df_data_blocks_written) < df->df_data_block_count)
-		goto out;
 
 	/* Truncate file to remove any preallocated space */
 	bfc = df->df_backing_file_context;
@@ -733,6 +751,7 @@
 	u8 *data_buf = NULL;
 	ssize_t error = 0;
 	int i = 0;
+	bool complete = false;
 
 	if (!df)
 		return -EBADF;
@@ -774,7 +793,7 @@
 							     data_buf);
 		} else {
 			error = incfs_process_new_data_block(df, &fill_block,
-							     data_buf);
+							data_buf, &complete);
 		}
 		if (error)
 			break;
@@ -783,7 +802,8 @@
 	if (data_buf)
 		free_pages((unsigned long)data_buf, get_order(data_buf_size));
 
-	maybe_delete_incomplete_file(f, df);
+	if (complete)
+		handle_file_completed(f, df);
 
 	/*
 	 * Only report the error if no records were processed, otherwise
@@ -1908,6 +1928,13 @@
 
 	pr_debug("incfs: unmount\n");
 
+	/*
+	 * We must kill the super before freeing mi, since killing the super
+	 * triggers inode eviction, which triggers the final update of the
+	 * backing file, which uses certain information for mi
+	 */
+	kill_anon_super(sb);
+
 	if (mi) {
 		if (mi->mi_backing_dir_path.dentry)
 			dinode = d_inode(mi->mi_backing_dir_path.dentry);
@@ -1923,7 +1950,6 @@
 		incfs_free_mount_info(mi);
 		sb->s_fs_info = NULL;
 	}
-	kill_anon_super(sb);
 }
 
 static int show_options(struct seq_file *m, struct dentry *root)
diff --git a/kernel/fs/inode.c b/kernel/fs/inode.c
index d9c748b..4102cfe 100644
--- a/kernel/fs/inode.c
+++ b/kernel/fs/inode.c
@@ -1016,6 +1016,48 @@
 EXPORT_SYMBOL(discard_new_inode);
 
 /**
+ * lock_two_inodes - lock two inodes (may be regular files but also dirs)
+ *
+ * Lock any non-NULL argument. The caller must make sure that if he is passing
+ * in two directories, one is not ancestor of the other.  Zero, one or two
+ * objects may be locked by this function.
+ *
+ * @inode1: first inode to lock
+ * @inode2: second inode to lock
+ * @subclass1: inode lock subclass for the first lock obtained
+ * @subclass2: inode lock subclass for the second lock obtained
+ */
+void lock_two_inodes(struct inode *inode1, struct inode *inode2,
+		     unsigned subclass1, unsigned subclass2)
+{
+	if (!inode1 || !inode2) {
+		/*
+		 * Make sure @subclass1 will be used for the acquired lock.
+		 * This is not strictly necessary (no current caller cares) but
+		 * let's keep things consistent.
+		 */
+		if (!inode1)
+			swap(inode1, inode2);
+		goto lock;
+	}
+
+	/*
+	 * If one object is directory and the other is not, we must make sure
+	 * to lock directory first as the other object may be its child.
+	 */
+	if (S_ISDIR(inode2->i_mode) == S_ISDIR(inode1->i_mode)) {
+		if (inode1 > inode2)
+			swap(inode1, inode2);
+	} else if (!S_ISDIR(inode1->i_mode))
+		swap(inode1, inode2);
+lock:
+	if (inode1)
+		inode_lock_nested(inode1, subclass1);
+	if (inode2 && inode2 != inode1)
+		inode_lock_nested(inode2, subclass2);
+}
+
+/**
  * lock_two_nondirectories - take two i_mutexes on non-directory objects
  *
  * Lock any non-NULL argument that is not a directory.
@@ -1855,35 +1897,6 @@
 EXPORT_SYMBOL_NS(touch_atime, ANDROID_GKI_VFS_EXPORT_ONLY);
 
 /*
- * The logic we want is
- *
- *	if suid or (sgid and xgrp)
- *		remove privs
- */
-int should_remove_suid(struct dentry *dentry)
-{
-	umode_t mode = d_inode(dentry)->i_mode;
-	int kill = 0;
-
-	/* suid always must be killed */
-	if (unlikely(mode & S_ISUID))
-		kill = ATTR_KILL_SUID;
-
-	/*
-	 * sgid without any exec bits is just a mandatory locking mark; leave
-	 * it alone.  If some exec bits are set, it's a real sgid; kill it.
-	 */
-	if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
-		kill |= ATTR_KILL_SGID;
-
-	if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode)))
-		return kill;
-
-	return 0;
-}
-EXPORT_SYMBOL(should_remove_suid);
-
-/*
  * Return mask of changes for notify_change() that need to be done as a
  * response to write or truncate. Return 0 if nothing has to be changed.
  * Negative value on error (change should be denied).
@@ -1897,7 +1910,7 @@
 	if (IS_NOSEC(inode))
 		return 0;
 
-	mask = should_remove_suid(dentry);
+	mask = setattr_should_drop_suidgid(inode);
 	ret = security_inode_need_killpriv(dentry);
 	if (ret < 0)
 		return ret;
@@ -2147,10 +2160,6 @@
 		/* Directories are special, and always inherit S_ISGID */
 		if (S_ISDIR(mode))
 			mode |= S_ISGID;
-		else if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP) &&
-			 !in_group_p(inode->i_gid) &&
-			 !capable_wrt_inode_uidgid(dir, CAP_FSETID))
-			mode &= ~S_ISGID;
 	} else
 		inode->i_gid = current_fsgid();
 	inode->i_mode = mode;
@@ -2382,3 +2391,48 @@
 	return 0;
 }
 EXPORT_SYMBOL(vfs_ioc_fssetxattr_check);
+
+/**
+ * in_group_or_capable - check whether caller is CAP_FSETID privileged
+ * @inode:	inode to check
+ * @gid:	the new/current gid of @inode
+ *
+ * Check wether @gid is in the caller's group list or if the caller is
+ * privileged with CAP_FSETID over @inode. This can be used to determine
+ * whether the setgid bit can be kept or must be dropped.
+ *
+ * Return: true if the caller is sufficiently privileged, false if not.
+ */
+bool in_group_or_capable(const struct inode *inode, kgid_t gid)
+{
+	if (in_group_p(gid))
+		return true;
+	if (capable_wrt_inode_uidgid(inode, CAP_FSETID))
+		return true;
+	return false;
+}
+
+/**
+ * mode_strip_sgid - handle the sgid bit for non-directories
+ * @dir: parent directory inode
+ * @mode: mode of the file to be created in @dir
+ *
+ * If the @mode of the new file has both the S_ISGID and S_IXGRP bit
+ * raised and @dir has the S_ISGID bit raised ensure that the caller is
+ * either in the group of the parent directory or they have CAP_FSETID
+ * in their user namespace and are privileged over the parent directory.
+ * In all other cases, strip the S_ISGID bit from @mode.
+ *
+ * Return: the new mode to use for the file
+ */
+umode_t mode_strip_sgid(const struct inode *dir, umode_t mode)
+{
+	if ((mode & (S_ISGID | S_IXGRP)) != (S_ISGID | S_IXGRP))
+		return mode;
+	if (S_ISDIR(mode) || !dir || !(dir->i_mode & S_ISGID))
+		return mode;
+	if (in_group_or_capable(dir, dir->i_gid))
+		return mode;
+	return mode & ~S_ISGID;
+}
+EXPORT_SYMBOL(mode_strip_sgid);
diff --git a/kernel/fs/internal.h b/kernel/fs/internal.h
index 06d313b..3919325 100644
--- a/kernel/fs/internal.h
+++ b/kernel/fs/internal.h
@@ -149,6 +149,9 @@
 extern long prune_icache_sb(struct super_block *sb, struct shrink_control *sc);
 extern void inode_add_lru(struct inode *inode);
 extern int dentry_needs_remove_privs(struct dentry *dentry);
+bool in_group_or_capable(const struct inode *inode, kgid_t gid);
+void lock_two_inodes(struct inode *inode1, struct inode *inode2,
+		     unsigned subclass1, unsigned subclass2);
 
 /*
  * fs-writeback.c
@@ -196,3 +199,8 @@
  */
 int do_statx(int dfd, const char __user *filename, unsigned flags,
 	     unsigned int mask, struct statx __user *buffer);
+
+/*
+ * fs/attr.c
+ */
+int setattr_should_drop_sgid(const struct inode *inode);
diff --git a/kernel/fs/jbd2/journal.c b/kernel/fs/jbd2/journal.c
index a076213..f706d93 100644
--- a/kernel/fs/jbd2/journal.c
+++ b/kernel/fs/jbd2/journal.c
@@ -757,6 +757,7 @@
 	}
 	journal->j_flags |= JBD2_FAST_COMMIT_ONGOING;
 	write_unlock(&journal->j_state_lock);
+	jbd2_journal_lock_updates(journal);
 
 	return 0;
 }
@@ -768,6 +769,7 @@
  */
 static int __jbd2_fc_end_commit(journal_t *journal, tid_t tid, bool fallback)
 {
+	jbd2_journal_unlock_updates(journal);
 	if (journal->j_fc_cleanup_callback)
 		journal->j_fc_cleanup_callback(journal, 0);
 	write_lock(&journal->j_state_lock);
diff --git a/kernel/fs/jbd2/transaction.c b/kernel/fs/jbd2/transaction.c
index 8647221..1baf2d6 100644
--- a/kernel/fs/jbd2/transaction.c
+++ b/kernel/fs/jbd2/transaction.c
@@ -984,36 +984,28 @@
 	 * ie. locked but not dirty) or tune2fs (which may actually have
 	 * the buffer dirtied, ugh.)  */
 
-	if (buffer_dirty(bh)) {
+	if (buffer_dirty(bh) && jh->b_transaction) {
+		warn_dirty_buffer(bh);
 		/*
-		 * First question: is this buffer already part of the current
-		 * transaction or the existing committing transaction?
-		 */
-		if (jh->b_transaction) {
-			J_ASSERT_JH(jh,
-				jh->b_transaction == transaction ||
-				jh->b_transaction ==
-					journal->j_committing_transaction);
-			if (jh->b_next_transaction)
-				J_ASSERT_JH(jh, jh->b_next_transaction ==
-							transaction);
-			warn_dirty_buffer(bh);
-		}
-		/*
-		 * In any case we need to clean the dirty flag and we must
-		 * do it under the buffer lock to be sure we don't race
-		 * with running write-out.
+		 * We need to clean the dirty flag and we must do it under the
+		 * buffer lock to be sure we don't race with running write-out.
 		 */
 		JBUFFER_TRACE(jh, "Journalling dirty buffer");
 		clear_buffer_dirty(bh);
+		/*
+		 * The buffer is going to be added to BJ_Reserved list now and
+		 * nothing guarantees jbd2_journal_dirty_metadata() will be
+		 * ever called for it. So we need to set jbddirty bit here to
+		 * make sure the buffer is dirtied and written out when the
+		 * journaling machinery is done with it.
+		 */
 		set_buffer_jbddirty(bh);
 	}
-
-	unlock_buffer(bh);
 
 	error = -EROFS;
 	if (is_handle_aborted(handle)) {
 		spin_unlock(&jh->b_state_lock);
+		unlock_buffer(bh);
 		goto out;
 	}
 	error = 0;
@@ -1023,8 +1015,10 @@
 	 * b_next_transaction points to it
 	 */
 	if (jh->b_transaction == transaction ||
-	    jh->b_next_transaction == transaction)
+	    jh->b_next_transaction == transaction) {
+		unlock_buffer(bh);
 		goto done;
+	}
 
 	/*
 	 * this is the first time this transaction is touching this buffer,
@@ -1048,10 +1042,24 @@
 		 */
 		smp_wmb();
 		spin_lock(&journal->j_list_lock);
+		if (test_clear_buffer_dirty(bh)) {
+			/*
+			 * Execute buffer dirty clearing and jh->b_transaction
+			 * assignment under journal->j_list_lock locked to
+			 * prevent bh being removed from checkpoint list if
+			 * the buffer is in an intermediate state (not dirty
+			 * and jh->b_transaction is NULL).
+			 */
+			JBUFFER_TRACE(jh, "Journalling dirty buffer");
+			set_buffer_jbddirty(bh);
+		}
 		__jbd2_journal_file_buffer(jh, transaction, BJ_Reserved);
 		spin_unlock(&journal->j_list_lock);
+		unlock_buffer(bh);
 		goto done;
 	}
+	unlock_buffer(bh);
+
 	/*
 	 * If there is already a copy-out version of this buffer, then we don't
 	 * need to make another one
@@ -2370,6 +2378,9 @@
 			spin_unlock(&jh->b_state_lock);
 			write_unlock(&journal->j_state_lock);
 			jbd2_journal_put_journal_head(jh);
+			/* Already zapped buffer? Nothing to do... */
+			if (!bh->b_bdev)
+				return 0;
 			return -EBUSY;
 		}
 		/*
diff --git a/kernel/fs/jffs2/build.c b/kernel/fs/jffs2/build.c
index 837cd55..6ae9d6f 100644
--- a/kernel/fs/jffs2/build.c
+++ b/kernel/fs/jffs2/build.c
@@ -211,7 +211,10 @@
 		ic->scan_dents = NULL;
 		cond_resched();
 	}
-	jffs2_build_xattr_subsystem(c);
+	ret = jffs2_build_xattr_subsystem(c);
+	if (ret)
+		goto exit;
+
 	c->flags &= ~JFFS2_SB_FLAG_BUILDING;
 
 	dbg_fsbuild("FS build complete\n");
diff --git a/kernel/fs/jffs2/file.c b/kernel/fs/jffs2/file.c
index bd7d58d..97a3c09 100644
--- a/kernel/fs/jffs2/file.c
+++ b/kernel/fs/jffs2/file.c
@@ -138,19 +138,18 @@
 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
 	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
 	pgoff_t index = pos >> PAGE_SHIFT;
-	uint32_t pageofs = index << PAGE_SHIFT;
 	int ret = 0;
 
 	jffs2_dbg(1, "%s()\n", __func__);
 
-	if (pageofs > inode->i_size) {
-		/* Make new hole frag from old EOF to new page */
+	if (pos > inode->i_size) {
+		/* Make new hole frag from old EOF to new position */
 		struct jffs2_raw_inode ri;
 		struct jffs2_full_dnode *fn;
 		uint32_t alloc_len;
 
-		jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
-			  (unsigned int)inode->i_size, pageofs);
+		jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new position\n",
+			  (unsigned int)inode->i_size, (uint32_t)pos);
 
 		ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
 					  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
@@ -170,10 +169,10 @@
 		ri.mode = cpu_to_jemode(inode->i_mode);
 		ri.uid = cpu_to_je16(i_uid_read(inode));
 		ri.gid = cpu_to_je16(i_gid_read(inode));
-		ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs));
+		ri.isize = cpu_to_je32((uint32_t)pos);
 		ri.atime = ri.ctime = ri.mtime = cpu_to_je32(JFFS2_NOW());
 		ri.offset = cpu_to_je32(inode->i_size);
-		ri.dsize = cpu_to_je32(pageofs - inode->i_size);
+		ri.dsize = cpu_to_je32((uint32_t)pos - inode->i_size);
 		ri.csize = cpu_to_je32(0);
 		ri.compr = JFFS2_COMPR_ZERO;
 		ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
@@ -203,7 +202,7 @@
 			goto out_err;
 		}
 		jffs2_complete_reservation(c);
-		inode->i_size = pageofs;
+		inode->i_size = pos;
 		mutex_unlock(&f->sem);
 	}
 
diff --git a/kernel/fs/jffs2/xattr.c b/kernel/fs/jffs2/xattr.c
index da3e185..acb4492 100644
--- a/kernel/fs/jffs2/xattr.c
+++ b/kernel/fs/jffs2/xattr.c
@@ -772,10 +772,10 @@
 }
 
 #define XREF_TMPHASH_SIZE	(128)
-void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
+int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
 {
 	struct jffs2_xattr_ref *ref, *_ref;
-	struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE];
+	struct jffs2_xattr_ref **xref_tmphash;
 	struct jffs2_xattr_datum *xd, *_xd;
 	struct jffs2_inode_cache *ic;
 	struct jffs2_raw_node_ref *raw;
@@ -784,9 +784,12 @@
 
 	BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
 
+	xref_tmphash = kcalloc(XREF_TMPHASH_SIZE,
+			       sizeof(struct jffs2_xattr_ref *), GFP_KERNEL);
+	if (!xref_tmphash)
+		return -ENOMEM;
+
 	/* Phase.1 : Merge same xref */
-	for (i=0; i < XREF_TMPHASH_SIZE; i++)
-		xref_tmphash[i] = NULL;
 	for (ref=c->xref_temp; ref; ref=_ref) {
 		struct jffs2_xattr_ref *tmp;
 
@@ -884,6 +887,8 @@
 		     "%u of xref (%u dead, %u orphan) found.\n",
 		     xdatum_count, xdatum_unchecked_count, xdatum_orphan_count,
 		     xref_count, xref_dead_count, xref_orphan_count);
+	kfree(xref_tmphash);
+	return 0;
 }
 
 struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
diff --git a/kernel/fs/jffs2/xattr.h b/kernel/fs/jffs2/xattr.h
index 720007b..1b5030a 100644
--- a/kernel/fs/jffs2/xattr.h
+++ b/kernel/fs/jffs2/xattr.h
@@ -71,7 +71,7 @@
 #ifdef CONFIG_JFFS2_FS_XATTR
 
 extern void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c);
-extern void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c);
+extern int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c);
 extern void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c);
 
 extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
@@ -103,7 +103,7 @@
 #else
 
 #define jffs2_init_xattr_subsystem(c)
-#define jffs2_build_xattr_subsystem(c)
+#define jffs2_build_xattr_subsystem(c)		(0)
 #define jffs2_clear_xattr_subsystem(c)
 
 #define jffs2_xattr_do_crccheck_inode(c, ic)
diff --git a/kernel/fs/jfs/jfs_dmap.c b/kernel/fs/jfs/jfs_dmap.c
index 0ce17ea..a9c078f 100644
--- a/kernel/fs/jfs/jfs_dmap.c
+++ b/kernel/fs/jfs/jfs_dmap.c
@@ -155,7 +155,7 @@
 	struct bmap *bmp;
 	struct dbmap_disk *dbmp_le;
 	struct metapage *mp;
-	int i;
+	int i, err;
 
 	/*
 	 * allocate/initialize the in-memory bmap descriptor
@@ -170,20 +170,25 @@
 			   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. */
 	dbmp_le = (struct dbmap_disk *) mp->data;
 	bmp->db_mapsize = le64_to_cpu(dbmp_le->dn_mapsize);
 	bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree);
+
 	bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage);
+	if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE) {
+		err = -EINVAL;
+		goto err_release_metapage;
+	}
+
 	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 +199,17 @@
 	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 ||
+	    bmp->db_agl2size < 0) {
+		err = -EINVAL;
+		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);
@@ -214,6 +230,12 @@
 	BMAP_LOCK_INIT(bmp);
 
 	return (0);
+
+err_release_metapage:
+	release_metapage(mp);
+err_kfree_bmp:
+	kfree(bmp);
+	return err;
 }
 
 
@@ -247,6 +269,7 @@
 
 	/* free the memory for the in-memory bmap. */
 	kfree(bmp);
+	JFS_SBI(ipbmap->i_sb)->bmap = NULL;
 
 	return (0);
 }
@@ -2005,6 +2028,9 @@
 	if (dbFindLeaf((dmtree_t *) & dp->tree, l2nb, &leafidx))
 		return -ENOSPC;
 
+	if (leafidx < 0)
+		return -EIO;
+
 	/* determine the block number within the file system corresponding
 	 * to the leaf at which free space was found.
 	 */
diff --git a/kernel/fs/jfs/jfs_extent.c b/kernel/fs/jfs/jfs_extent.c
index f65bd6b..d4e063d 100644
--- a/kernel/fs/jfs/jfs_extent.c
+++ b/kernel/fs/jfs/jfs_extent.c
@@ -508,6 +508,11 @@
 	 * blocks in the map. in that case, we'll start off with the
 	 * maximum free.
 	 */
+
+	/* give up if no space left */
+	if (bmp->db_maxfreebud == -1)
+		return -ENOSPC;
+
 	max = (s64) 1 << bmp->db_maxfreebud;
 	if (*nblocks >= max && *nblocks > nbperpage)
 		nb = nblks = (max > nbperpage) ? max : nbperpage;
diff --git a/kernel/fs/jfs/jfs_filsys.h b/kernel/fs/jfs/jfs_filsys.h
index b5d702d..33ef13a0 100644
--- a/kernel/fs/jfs/jfs_filsys.h
+++ b/kernel/fs/jfs/jfs_filsys.h
@@ -122,7 +122,9 @@
 #define NUM_INODE_PER_IAG	INOSPERIAG
 
 #define MINBLOCKSIZE		512
+#define L2MINBLOCKSIZE		9
 #define MAXBLOCKSIZE		4096
+#define L2MAXBLOCKSIZE		12
 #define	MAXFILESIZE		((s64)1 << 52)
 
 #define JFS_LINK_MAX		0xffffffff
diff --git a/kernel/fs/jfs/jfs_imap.c b/kernel/fs/jfs/jfs_imap.c
index 937ca07..67c6760 100644
--- a/kernel/fs/jfs/jfs_imap.c
+++ b/kernel/fs/jfs/jfs_imap.c
@@ -195,6 +195,7 @@
 	 * free in-memory control structure
 	 */
 	kfree(imap);
+	JFS_IP(ipimap)->i_imap = NULL;
 
 	return (0);
 }
diff --git a/kernel/fs/jfs/jfs_txnmgr.c b/kernel/fs/jfs/jfs_txnmgr.c
index c8ce7f1..6f6a5b9 100644
--- a/kernel/fs/jfs/jfs_txnmgr.c
+++ b/kernel/fs/jfs/jfs_txnmgr.c
@@ -354,6 +354,11 @@
 	jfs_info("txBegin: flag = 0x%x", flag);
 	log = JFS_SBI(sb)->log;
 
+	if (!log) {
+		jfs_error(sb, "read-only filesystem\n");
+		return 0;
+	}
+
 	TXN_LOCK();
 
 	INCREMENT(TxStat.txBegin);
diff --git a/kernel/fs/jfs/namei.c b/kernel/fs/jfs/namei.c
index 7a55d14..f155ad6 100644
--- a/kernel/fs/jfs/namei.c
+++ b/kernel/fs/jfs/namei.c
@@ -798,6 +798,11 @@
 	if (rc)
 		goto out;
 
+	if (isReadOnly(ip)) {
+		jfs_error(ip->i_sb, "read-only filesystem\n");
+		return -EROFS;
+	}
+
 	tid = txBegin(ip->i_sb, 0);
 
 	mutex_lock_nested(&JFS_IP(dir)->commit_mutex, COMMIT_MUTEX_PARENT);
diff --git a/kernel/fs/kernfs/dir.c b/kernel/fs/kernfs/dir.c
index 8b3c86a..c91ee05 100644
--- a/kernel/fs/kernfs/dir.c
+++ b/kernel/fs/kernfs/dir.c
@@ -679,7 +679,9 @@
 	return kn;
 
  err_out3:
+	spin_lock(&kernfs_idr_lock);
 	idr_remove(&root->ino_idr, (u32)kernfs_ino(kn));
+	spin_unlock(&kernfs_idr_lock);
  err_out2:
 	kmem_cache_free(kernfs_node_cache, kn);
  err_out1:
diff --git a/kernel/fs/libfs.c b/kernel/fs/libfs.c
index 40359a0..3584577 100644
--- a/kernel/fs/libfs.c
+++ b/kernel/fs/libfs.c
@@ -955,8 +955,8 @@
 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 @@
 		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 @@
 	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/kernel/fs/lockd/mon.c b/kernel/fs/lockd/mon.c
index 1d9488c..87a0f20 100644
--- a/kernel/fs/lockd/mon.c
+++ b/kernel/fs/lockd/mon.c
@@ -276,6 +276,9 @@
 {
 	struct nsm_handle *new;
 
+	if (!hostname)
+		return NULL;
+
 	new = kzalloc(sizeof(*new) + hostname_len + 1, GFP_KERNEL);
 	if (unlikely(new == NULL))
 		return NULL;
diff --git a/kernel/fs/locks.c b/kernel/fs/locks.c
index 32c948f..cbb5701 100644
--- a/kernel/fs/locks.c
+++ b/kernel/fs/locks.c
@@ -1339,6 +1339,7 @@
  out:
 	spin_unlock(&ctx->flc_lock);
 	percpu_up_read(&file_rwsem);
+	trace_posix_lock_inode(inode, request, error);
 	/*
 	 * Free any unused locks.
 	 */
@@ -1347,7 +1348,6 @@
 	if (new_fl2)
 		locks_free_lock(new_fl2);
 	locks_dispose_list(&dispose);
-	trace_posix_lock_inode(inode, request, error);
 
 	return error;
 }
@@ -2813,6 +2813,29 @@
 }
 EXPORT_SYMBOL_GPL(vfs_cancel_lock);
 
+/**
+ * vfs_inode_has_locks - are any file locks held on @inode?
+ * @inode: inode to check for locks
+ *
+ * Return true if there are any FL_POSIX or FL_FLOCK locks currently
+ * set on @inode.
+ */
+bool vfs_inode_has_locks(struct inode *inode)
+{
+	struct file_lock_context *ctx;
+	bool ret;
+
+	ctx = smp_load_acquire(&inode->i_flctx);
+	if (!ctx)
+		return false;
+
+	spin_lock(&ctx->flc_lock);
+	ret = !list_empty(&ctx->flc_posix) || !list_empty(&ctx->flc_flock);
+	spin_unlock(&ctx->flc_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(vfs_inode_has_locks);
+
 #ifdef CONFIG_PROC_FS
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
diff --git a/kernel/fs/mbcache.c b/kernel/fs/mbcache.c
index 97c54d3..95b0472 100644
--- a/kernel/fs/mbcache.c
+++ b/kernel/fs/mbcache.c
@@ -11,7 +11,7 @@
 /*
  * Mbcache is a simple key-value store. Keys need not be unique, however
  * key-value pairs are expected to be unique (we use this fact in
- * mb_cache_entry_delete()).
+ * mb_cache_entry_delete_or_get()).
  *
  * Ext2 and ext4 use this cache for deduplication of extended attribute blocks.
  * Ext4 also uses it for deduplication of xattr values stored in inodes.
@@ -90,12 +90,19 @@
 		return -ENOMEM;
 
 	INIT_LIST_HEAD(&entry->e_list);
-	/* One ref for hash, one ref returned */
-	atomic_set(&entry->e_refcnt, 1);
+	/*
+	 * We create entry with two references. One reference is kept by the
+	 * hash table, the other reference is used to protect us from
+	 * mb_cache_entry_delete_or_get() until the entry is fully setup. This
+	 * avoids nesting of cache->c_list_lock into hash table bit locks which
+	 * is problematic for RT.
+	 */
+	atomic_set(&entry->e_refcnt, 2);
 	entry->e_key = key;
 	entry->e_value = value;
-	entry->e_reusable = reusable;
-	entry->e_referenced = 0;
+	entry->e_flags = 0;
+	if (reusable)
+		set_bit(MBE_REUSABLE_B, &entry->e_flags);
 	head = mb_cache_entry_head(cache, key);
 	hlist_bl_lock(head);
 	hlist_bl_for_each_entry(dup, dup_node, head, e_hash_list) {
@@ -107,23 +114,40 @@
 	}
 	hlist_bl_add_head(&entry->e_hash_list, head);
 	hlist_bl_unlock(head);
-
 	spin_lock(&cache->c_list_lock);
 	list_add_tail(&entry->e_list, &cache->c_list);
-	/* Grab ref for LRU list */
-	atomic_inc(&entry->e_refcnt);
 	cache->c_entry_count++;
 	spin_unlock(&cache->c_list_lock);
+	mb_cache_entry_put(cache, entry);
 
 	return 0;
 }
 EXPORT_SYMBOL(mb_cache_entry_create);
 
-void __mb_cache_entry_free(struct mb_cache_entry *entry)
+void __mb_cache_entry_free(struct mb_cache *cache, struct mb_cache_entry *entry)
 {
+	struct hlist_bl_head *head;
+
+	head = mb_cache_entry_head(cache, entry->e_key);
+	hlist_bl_lock(head);
+	hlist_bl_del(&entry->e_hash_list);
+	hlist_bl_unlock(head);
 	kmem_cache_free(mb_entry_cache, entry);
 }
 EXPORT_SYMBOL(__mb_cache_entry_free);
+
+/*
+ * mb_cache_entry_wait_unused - wait to be the last user of the entry
+ *
+ * @entry - entry to work on
+ *
+ * Wait to be the last user of the entry.
+ */
+void mb_cache_entry_wait_unused(struct mb_cache_entry *entry)
+{
+	wait_var_event(&entry->e_refcnt, atomic_read(&entry->e_refcnt) <= 2);
+}
+EXPORT_SYMBOL(mb_cache_entry_wait_unused);
 
 static struct mb_cache_entry *__entry_find(struct mb_cache *cache,
 					   struct mb_cache_entry *entry,
@@ -142,10 +166,10 @@
 	while (node) {
 		entry = hlist_bl_entry(node, struct mb_cache_entry,
 				       e_hash_list);
-		if (entry->e_key == key && entry->e_reusable) {
-			atomic_inc(&entry->e_refcnt);
+		if (entry->e_key == key &&
+		    test_bit(MBE_REUSABLE_B, &entry->e_flags) &&
+		    atomic_inc_not_zero(&entry->e_refcnt))
 			goto out;
-		}
 		node = node->next;
 	}
 	entry = NULL;
@@ -205,10 +229,9 @@
 	head = mb_cache_entry_head(cache, key);
 	hlist_bl_lock(head);
 	hlist_bl_for_each_entry(entry, node, head, e_hash_list) {
-		if (entry->e_key == key && entry->e_value == value) {
-			atomic_inc(&entry->e_refcnt);
+		if (entry->e_key == key && entry->e_value == value &&
+		    atomic_inc_not_zero(&entry->e_refcnt))
 			goto out;
-		}
 	}
 	entry = NULL;
 out:
@@ -217,7 +240,7 @@
 }
 EXPORT_SYMBOL(mb_cache_entry_get);
 
-/* mb_cache_entry_delete - remove a cache entry
+/* mb_cache_entry_delete - try to remove a cache entry
  * @cache - cache we work with
  * @key - key
  * @value - value
@@ -254,6 +277,43 @@
 }
 EXPORT_SYMBOL(mb_cache_entry_delete);
 
+/* mb_cache_entry_delete_or_get - remove a cache entry if it has no users
+ * @cache - cache we work with
+ * @key - key
+ * @value - value
+ *
+ * Remove entry from cache @cache with key @key and value @value. The removal
+ * happens only if the entry is unused. The function returns NULL in case the
+ * entry was successfully removed or there's no entry in cache. Otherwise the
+ * function grabs reference of the entry that we failed to delete because it
+ * still has users and return it.
+ */
+struct mb_cache_entry *mb_cache_entry_delete_or_get(struct mb_cache *cache,
+						    u32 key, u64 value)
+{
+	struct mb_cache_entry *entry;
+
+	entry = mb_cache_entry_get(cache, key, value);
+	if (!entry)
+		return NULL;
+
+	/*
+	 * Drop the ref we got from mb_cache_entry_get() and the initial hash
+	 * ref if we are the last user
+	 */
+	if (atomic_cmpxchg(&entry->e_refcnt, 2, 0) != 2)
+		return entry;
+
+	spin_lock(&cache->c_list_lock);
+	if (!list_empty(&entry->e_list))
+		list_del_init(&entry->e_list);
+	cache->c_entry_count--;
+	spin_unlock(&cache->c_list_lock);
+	__mb_cache_entry_free(cache, entry);
+	return NULL;
+}
+EXPORT_SYMBOL(mb_cache_entry_delete_or_get);
+
 /* mb_cache_entry_touch - cache entry got used
  * @cache - cache the entry belongs to
  * @entry - entry that got used
@@ -263,7 +323,7 @@
 void mb_cache_entry_touch(struct mb_cache *cache,
 			  struct mb_cache_entry *entry)
 {
-	entry->e_referenced = 1;
+	set_bit(MBE_REFERENCED_B, &entry->e_flags);
 }
 EXPORT_SYMBOL(mb_cache_entry_touch);
 
@@ -281,34 +341,24 @@
 				     unsigned long nr_to_scan)
 {
 	struct mb_cache_entry *entry;
-	struct hlist_bl_head *head;
 	unsigned long shrunk = 0;
 
 	spin_lock(&cache->c_list_lock);
 	while (nr_to_scan-- && !list_empty(&cache->c_list)) {
 		entry = list_first_entry(&cache->c_list,
 					 struct mb_cache_entry, e_list);
-		if (entry->e_referenced) {
-			entry->e_referenced = 0;
+		/* Drop initial hash reference if there is no user */
+		if (test_bit(MBE_REFERENCED_B, &entry->e_flags) ||
+		    atomic_cmpxchg(&entry->e_refcnt, 1, 0) != 1) {
+			clear_bit(MBE_REFERENCED_B, &entry->e_flags);
 			list_move_tail(&entry->e_list, &cache->c_list);
 			continue;
 		}
 		list_del_init(&entry->e_list);
 		cache->c_entry_count--;
-		/*
-		 * We keep LRU list reference so that entry doesn't go away
-		 * from under us.
-		 */
 		spin_unlock(&cache->c_list_lock);
-		head = mb_cache_entry_head(cache, entry->e_key);
-		hlist_bl_lock(head);
-		if (!hlist_bl_unhashed(&entry->e_hash_list)) {
-			hlist_bl_del_init(&entry->e_hash_list);
-			atomic_dec(&entry->e_refcnt);
-		}
-		hlist_bl_unlock(head);
-		if (mb_cache_entry_put(cache, entry))
-			shrunk++;
+		__mb_cache_entry_free(cache, entry);
+		shrunk++;
 		cond_resched();
 		spin_lock(&cache->c_list_lock);
 	}
@@ -400,11 +450,6 @@
 	 * point.
 	 */
 	list_for_each_entry_safe(entry, next, &cache->c_list, e_list) {
-		if (!hlist_bl_unhashed(&entry->e_hash_list)) {
-			hlist_bl_del_init(&entry->e_hash_list);
-			atomic_dec(&entry->e_refcnt);
-		} else
-			WARN_ON(1);
 		list_del(&entry->e_list);
 		WARN_ON(atomic_read(&entry->e_refcnt) != 1);
 		mb_cache_entry_put(cache, entry);
diff --git a/kernel/fs/namei.c b/kernel/fs/namei.c
index 887bc1f..83ef3d7 100644
--- a/kernel/fs/namei.c
+++ b/kernel/fs/namei.c
@@ -2724,7 +2724,7 @@
 	dput(path->dentry);
 	path->dentry = parent;
 	child = d_hash_and_lookup(parent, &this);
-	if (!child)
+	if (IS_ERR_OR_NULL(child))
 		return -ENOENT;
 
 	path->dentry = child;
@@ -2866,8 +2866,8 @@
 		return p;
 	}
 
-	inode_lock_nested(p1->d_inode, I_MUTEX_PARENT);
-	inode_lock_nested(p2->d_inode, I_MUTEX_PARENT2);
+	lock_two_inodes(p1->d_inode, p2->d_inode,
+			I_MUTEX_PARENT, I_MUTEX_PARENT2);
 	return NULL;
 }
 EXPORT_SYMBOL(lock_rename);
@@ -2882,6 +2882,63 @@
 }
 EXPORT_SYMBOL(unlock_rename);
 
+/**
+ * mode_strip_umask - handle vfs umask stripping
+ * @dir:	parent directory of the new inode
+ * @mode:	mode of the new inode to be created in @dir
+ *
+ * Umask stripping depends on whether or not the filesystem supports POSIX
+ * ACLs. If the filesystem doesn't support it umask stripping is done directly
+ * in here. If the filesystem does support POSIX ACLs umask stripping is
+ * deferred until the filesystem calls posix_acl_create().
+ *
+ * Returns: mode
+ */
+static inline umode_t mode_strip_umask(const struct inode *dir, umode_t mode)
+{
+	if (!IS_POSIXACL(dir))
+		mode &= ~current_umask();
+	return mode;
+}
+
+/**
+ * vfs_prepare_mode - prepare the mode to be used for a new inode
+ * @dir:	parent directory of the new inode
+ * @mode:	mode of the new inode
+ * @mask_perms:	allowed permission by the vfs
+ * @type:	type of file to be created
+ *
+ * This helper consolidates and enforces vfs restrictions on the @mode of a new
+ * object to be created.
+ *
+ * Umask stripping depends on whether the filesystem supports POSIX ACLs (see
+ * the kernel documentation for mode_strip_umask()). Moving umask stripping
+ * after setgid stripping allows the same ordering for both non-POSIX ACL and
+ * POSIX ACL supporting filesystems.
+ *
+ * Note that it's currently valid for @type to be 0 if a directory is created.
+ * Filesystems raise that flag individually and we need to check whether each
+ * filesystem can deal with receiving S_IFDIR from the vfs before we enforce a
+ * non-zero type.
+ *
+ * Returns: mode to be passed to the filesystem
+ */
+static inline umode_t vfs_prepare_mode(const struct inode *dir, umode_t mode,
+				       umode_t mask_perms, umode_t type)
+{
+	mode = mode_strip_sgid(dir, mode);
+	mode = mode_strip_umask(dir, mode);
+
+	/*
+	 * Apply the vfs mandated allowed permission mask and set the type of
+	 * file to be created before we call into the filesystem.
+	 */
+	mode &= (mask_perms & ~S_IFMT);
+	mode |= (type & S_IFMT);
+
+	return mode;
+}
+
 int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
 		bool want_excl)
 {
@@ -2891,8 +2948,8 @@
 
 	if (!dir->i_op->create)
 		return -EACCES;	/* shouldn't it be ENOSYS? */
-	mode &= S_IALLUGO;
-	mode |= S_IFREG;
+
+	mode = vfs_prepare_mode(dir, mode, S_IALLUGO, S_IFREG);
 	error = security_inode_create(dir, dentry, mode);
 	if (error)
 		return error;
@@ -3156,8 +3213,7 @@
 	if (open_flag & O_CREAT) {
 		if (open_flag & O_EXCL)
 			open_flag &= ~O_TRUNC;
-		if (!IS_POSIXACL(dir->d_inode))
-			mode &= ~current_umask();
+		mode = vfs_prepare_mode(dir->d_inode, mode, mode, mode);
 		if (likely(got_write))
 			create_error = may_o_create(&nd->path, dentry, mode);
 		else
@@ -3370,8 +3426,7 @@
 	child = d_alloc(dentry, &slash_name);
 	if (unlikely(!child))
 		goto out_err;
-	if (!IS_POSIXACL(dir))
-		mode &= ~current_umask();
+	mode = vfs_prepare_mode(dir, mode, mode, mode);
 	error = dir->i_op->tmpfile(dir, child, mode);
 	if (error)
 		goto out_err;
@@ -3632,6 +3687,7 @@
 	if (!dir->i_op->mknod)
 		return -EPERM;
 
+	mode = vfs_prepare_mode(dir, mode, mode, mode);
 	error = devcgroup_inode_mknod(mode, dev);
 	if (error)
 		return error;
@@ -3680,9 +3736,8 @@
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
-	if (!IS_POSIXACL(path.dentry->d_inode))
-		mode &= ~current_umask();
-	error = security_path_mknod(&path, dentry, mode, dev);
+	error = security_path_mknod(&path, dentry,
+			mode_strip_umask(path.dentry->d_inode, mode), dev);
 	if (error)
 		goto out;
 	switch (mode & S_IFMT) {
@@ -3730,7 +3785,7 @@
 	if (!dir->i_op->mkdir)
 		return -EPERM;
 
-	mode &= (S_IRWXUGO|S_ISVTX);
+	mode = vfs_prepare_mode(dir, mode, S_IRWXUGO | S_ISVTX, 0);
 	error = security_inode_mkdir(dir, dentry, mode);
 	if (error)
 		return error;
@@ -3757,9 +3812,8 @@
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
-	if (!IS_POSIXACL(path.dentry->d_inode))
-		mode &= ~current_umask();
-	error = security_path_mkdir(&path, dentry, mode);
+	error = security_path_mkdir(&path, dentry,
+			mode_strip_umask(path.dentry->d_inode, mode));
 	if (!error)
 		error = vfs_mkdir(path.dentry->d_inode, dentry, mode);
 	done_path_create(&path, dentry);
@@ -4294,7 +4348,7 @@
  *	   sb->s_vfs_rename_mutex. We might be more accurate, but that's another
  *	   story.
  *	c) we have to lock _four_ objects - parents and victim (if it exists),
- *	   and source (if it is not a directory).
+ *	   and source.
  *	   And that - after we got ->i_mutex on parents (until then we don't know
  *	   whether the target exists).  Solution: try to be smart with locking
  *	   order for inodes.  We rely on the fact that tree topology may change
@@ -4371,10 +4425,16 @@
 
 	take_dentry_name_snapshot(&old_name, old_dentry);
 	dget(new_dentry);
-	if (!is_dir || (flags & RENAME_EXCHANGE))
-		lock_two_nondirectories(source, target);
-	else if (target)
-		inode_lock(target);
+	/*
+	 * Lock all moved children. Moved directories may need to change parent
+	 * pointer so they need the lock to prevent against concurrent
+	 * directory changes moving parent pointer. For regular files we've
+	 * historically always done this. The lockdep locking subclasses are
+	 * somewhat arbitrary but RENAME_EXCHANGE in particular can swap
+	 * regular files and directories so it's difficult to tell which
+	 * subclasses to use.
+	 */
+	lock_two_inodes(source, target, I_MUTEX_NORMAL, I_MUTEX_NONDIR2);
 
 	error = -EBUSY;
 	if (is_local_mountpoint(old_dentry) || is_local_mountpoint(new_dentry))
@@ -4418,9 +4478,8 @@
 			d_exchange(old_dentry, new_dentry);
 	}
 out:
-	if (!is_dir || (flags & RENAME_EXCHANGE))
-		unlock_two_nondirectories(source, target);
-	else if (target)
+	inode_unlock(source);
+	if (target)
 		inode_unlock(target);
 	dput(new_dentry);
 	if (!error) {
diff --git a/kernel/fs/nfs/blocklayout/dev.c b/kernel/fs/nfs/blocklayout/dev.c
index dec5880..6e3a14f 100644
--- a/kernel/fs/nfs/blocklayout/dev.c
+++ b/kernel/fs/nfs/blocklayout/dev.c
@@ -422,7 +422,7 @@
 	int ret, i;
 
 	d->children = kcalloc(v->concat.volumes_count,
-			sizeof(struct pnfs_block_dev), GFP_KERNEL);
+			sizeof(struct pnfs_block_dev), gfp_mask);
 	if (!d->children)
 		return -ENOMEM;
 
@@ -451,7 +451,7 @@
 	int ret, i;
 
 	d->children = kcalloc(v->stripe.volumes_count,
-			sizeof(struct pnfs_block_dev), GFP_KERNEL);
+			sizeof(struct pnfs_block_dev), gfp_mask);
 	if (!d->children)
 		return -ENOMEM;
 
diff --git a/kernel/fs/nfs/direct.c b/kernel/fs/nfs/direct.c
index c220810..5d86ffa 100644
--- a/kernel/fs/nfs/direct.c
+++ b/kernel/fs/nfs/direct.c
@@ -509,21 +509,47 @@
 	return result;
 }
 
-static void
-nfs_direct_join_group(struct list_head *list, struct inode *inode)
+static void nfs_direct_add_page_head(struct list_head *list,
+				     struct nfs_page *req)
 {
-	struct nfs_page *req, *next;
+	struct nfs_page *head = req->wb_head;
+
+	if (!list_empty(&head->wb_list) || !nfs_lock_request(head))
+		return;
+	if (!list_empty(&head->wb_list)) {
+		nfs_unlock_request(head);
+		return;
+	}
+	list_add(&head->wb_list, list);
+	kref_get(&head->wb_kref);
+	kref_get(&head->wb_kref);
+}
+
+static void nfs_direct_join_group(struct list_head *list,
+				  struct nfs_commit_info *cinfo,
+				  struct inode *inode)
+{
+	struct nfs_page *req, *subreq;
 
 	list_for_each_entry(req, list, wb_list) {
-		if (req->wb_head != req || req->wb_this_page == req)
+		if (req->wb_head != req) {
+			nfs_direct_add_page_head(&req->wb_list, req);
 			continue;
-		for (next = req->wb_this_page;
-				next != req->wb_head;
-				next = next->wb_this_page) {
-			nfs_list_remove_request(next);
-			nfs_release_request(next);
 		}
-		nfs_join_page_group(req, inode);
+		subreq = req->wb_this_page;
+		if (subreq == req)
+			continue;
+		do {
+			/*
+			 * Remove subrequests from this list before freeing
+			 * them in the call to nfs_join_page_group().
+			 */
+			if (!list_empty(&subreq->wb_list)) {
+				nfs_list_remove_request(subreq);
+				nfs_release_request(subreq);
+			}
+		} while ((subreq = subreq->wb_this_page) != req);
+		nfs_join_page_group(req, cinfo, inode);
 	}
 }
 
@@ -549,7 +575,7 @@
 	nfs_init_cinfo_from_dreq(&cinfo, dreq);
 	nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo);
 
-	nfs_direct_join_group(&reqs, dreq->inode);
+	nfs_direct_join_group(&reqs, &cinfo, dreq->inode);
 
 	dreq->count = 0;
 	dreq->max_count = 0;
diff --git a/kernel/fs/nfs/file.c b/kernel/fs/nfs/file.c
index ad856b7..7be1a7f 100644
--- a/kernel/fs/nfs/file.c
+++ b/kernel/fs/nfs/file.c
@@ -487,8 +487,9 @@
 {
 	unsigned long blocks;
 	long long isize;
-	struct rpc_clnt *clnt = NFS_CLIENT(file->f_mapping->host);
-	struct inode *inode = file->f_mapping->host;
+	struct inode *inode = file_inode(file);
+	struct rpc_clnt *clnt = NFS_CLIENT(inode);
+	struct nfs_client *cl = NFS_SERVER(inode)->nfs_client;
 
 	spin_lock(&inode->i_lock);
 	blocks = inode->i_blocks;
@@ -501,14 +502,22 @@
 
 	*span = sis->pages;
 
+
+	if (cl->rpc_ops->enable_swap)
+		cl->rpc_ops->enable_swap(inode);
+
 	return rpc_clnt_swap_activate(clnt);
 }
 
 static void nfs_swap_deactivate(struct file *file)
 {
-	struct rpc_clnt *clnt = NFS_CLIENT(file->f_mapping->host);
+	struct inode *inode = file_inode(file);
+	struct rpc_clnt *clnt = NFS_CLIENT(inode);
+	struct nfs_client *cl = NFS_SERVER(inode)->nfs_client;
 
 	rpc_clnt_swap_deactivate(clnt);
+	if (cl->rpc_ops->disable_swap)
+		cl->rpc_ops->disable_swap(file_inode(file));
 }
 
 const struct address_space_operations nfs_file_aops = {
diff --git a/kernel/fs/nfs/filelayout/filelayout.c b/kernel/fs/nfs/filelayout/filelayout.c
index ae5ed3a..deecfb5 100644
--- a/kernel/fs/nfs/filelayout/filelayout.c
+++ b/kernel/fs/nfs/filelayout/filelayout.c
@@ -783,6 +783,12 @@
 	return &fl->generic_hdr;
 }
 
+static bool
+filelayout_lseg_is_striped(const struct nfs4_filelayout_segment *flseg)
+{
+	return flseg->num_fh > 1;
+}
+
 /*
  * filelayout_pg_test(). Called by nfs_can_coalesce_requests()
  *
@@ -803,6 +809,8 @@
 	size = pnfs_generic_pg_test(pgio, prev, req);
 	if (!size)
 		return 0;
+	else if (!filelayout_lseg_is_striped(FILELAYOUT_LSEG(pgio->pg_lseg)))
+		return size;
 
 	/* see if req and prev are in the same stripe */
 	if (prev) {
diff --git a/kernel/fs/nfs/flexfilelayout/flexfilelayout.c b/kernel/fs/nfs/flexfilelayout/flexfilelayout.c
index a8a0208..e4f2820 100644
--- a/kernel/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/kernel/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -1240,6 +1240,7 @@
 		case -EPFNOSUPPORT:
 		case -EPROTONOSUPPORT:
 		case -EOPNOTSUPP:
+		case -EINVAL:
 		case -ECONNREFUSED:
 		case -ECONNRESET:
 		case -EHOSTDOWN:
diff --git a/kernel/fs/nfs/inode.c b/kernel/fs/nfs/inode.c
index 62e361c..9c57cfa 100644
--- a/kernel/fs/nfs/inode.c
+++ b/kernel/fs/nfs/inode.c
@@ -1906,7 +1906,11 @@
 	nfs_wcc_update_inode(inode, fattr);
 
 	if (pnfs_layoutcommit_outstanding(inode)) {
-		nfsi->cache_validity |= save_cache_validity & NFS_INO_INVALID_ATTR;
+		nfsi->cache_validity |=
+			save_cache_validity &
+			(NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_CTIME |
+			 NFS_INO_INVALID_MTIME | NFS_INO_INVALID_SIZE |
+			 NFS_INO_REVAL_FORCED);
 		cache_revalidated = false;
 	}
 
diff --git a/kernel/fs/nfs/namespace.c b/kernel/fs/nfs/namespace.c
index 2bcbe38..1f03445 100644
--- a/kernel/fs/nfs/namespace.c
+++ b/kernel/fs/nfs/namespace.c
@@ -147,7 +147,7 @@
 	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;
diff --git a/kernel/fs/nfs/nfs2xdr.c b/kernel/fs/nfs/nfs2xdr.c
index 5e6453e..b34196d 100644
--- a/kernel/fs/nfs/nfs2xdr.c
+++ b/kernel/fs/nfs/nfs2xdr.c
@@ -948,7 +948,7 @@
 
 	error = decode_filename_inline(xdr, &entry->name, &entry->len);
 	if (unlikely(error))
-		return -EAGAIN;
+		return error == -ENAMETOOLONG ? -ENAMETOOLONG : -EAGAIN;
 
 	/*
 	 * The type (size and byte order) of nfscookie isn't defined in
diff --git a/kernel/fs/nfs/nfs3xdr.c b/kernel/fs/nfs/nfs3xdr.c
index b5a9379..509f328 100644
--- a/kernel/fs/nfs/nfs3xdr.c
+++ b/kernel/fs/nfs/nfs3xdr.c
@@ -1987,7 +1987,7 @@
 
 	error = decode_inline_filename3(xdr, &entry->name, &entry->len);
 	if (unlikely(error))
-		return -EAGAIN;
+		return error == -ENAMETOOLONG ? -ENAMETOOLONG : -EAGAIN;
 
 	error = decode_cookie3(xdr, &new_cookie);
 	if (unlikely(error))
diff --git a/kernel/fs/nfs/nfs42proc.c b/kernel/fs/nfs/nfs42proc.c
index dad32b1..dfeea71 100644
--- a/kernel/fs/nfs/nfs42proc.c
+++ b/kernel/fs/nfs/nfs42proc.c
@@ -443,8 +443,9 @@
 				continue;
 			}
 			break;
-		} else if (err == -NFS4ERR_OFFLOAD_NO_REQS && !args.sync) {
-			args.sync = true;
+		} else if (err == -NFS4ERR_OFFLOAD_NO_REQS &&
+				args.sync != res.synchronous) {
+			args.sync = res.synchronous;
 			dst_exception.retry = 1;
 			continue;
 		} else if ((err == -ESTALE ||
diff --git a/kernel/fs/nfs/nfs4_fs.h b/kernel/fs/nfs/nfs4_fs.h
index 6d91656..8b41c0b 100644
--- a/kernel/fs/nfs/nfs4_fs.h
+++ b/kernel/fs/nfs/nfs4_fs.h
@@ -42,6 +42,7 @@
 	NFS4CLNT_LEASE_MOVED,
 	NFS4CLNT_DELEGATION_EXPIRED,
 	NFS4CLNT_RUN_MANAGER,
+	NFS4CLNT_MANAGER_AVAILABLE,
 	NFS4CLNT_RECALL_RUNNING,
 	NFS4CLNT_RECALL_ANY_LAYOUT_READ,
 	NFS4CLNT_RECALL_ANY_LAYOUT_RW,
diff --git a/kernel/fs/nfs/nfs4proc.c b/kernel/fs/nfs/nfs4proc.c
index a576b0e..328ef75 100644
--- a/kernel/fs/nfs/nfs4proc.c
+++ b/kernel/fs/nfs/nfs4proc.c
@@ -130,6 +130,11 @@
 	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)
@@ -921,6 +926,7 @@
 out_noaction:
 	return ret;
 session_recover:
+	set_bit(NFS4_SLOT_TBL_DRAINING, &session->fc_slot_table.slot_tbl_state);
 	nfs4_schedule_session_recovery(session, status);
 	dprintk("%s ERROR: %d Reset session\n", __func__, status);
 	nfs41_sequence_free_slot(res);
@@ -1970,8 +1976,7 @@
 	if (!data->rpc_done) {
 		if (data->rpc_status)
 			return ERR_PTR(data->rpc_status);
-		/* cached opens have already been processed */
-		goto update;
+		return nfs4_try_open_cached(data);
 	}
 
 	ret = nfs_refresh_inode(inode, &data->f_attr);
@@ -1980,7 +1985,7 @@
 
 	if (data->o_res.delegation_type != 0)
 		nfs4_opendata_check_deleg(data, state);
-update:
+
 	if (!update_open_stateid(state, &data->o_res.stateid,
 				NULL, data->o_arg.fmode))
 		return ERR_PTR(-EAGAIN);
@@ -2121,18 +2126,18 @@
 }
 
 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);
@@ -2708,10 +2713,15 @@
 	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);
@@ -3793,7 +3803,7 @@
 		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 +4567,7 @@
 		 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 +4926,7 @@
 	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 +4967,7 @@
 	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 +5088,7 @@
 	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);
@@ -5854,9 +5864,8 @@
 out_ok:
 	ret = res.acl_len;
 out_free:
-	for (i = 0; i < npages; i++)
-		if (pages[i])
-			__free_page(pages[i]);
+	while (--i >= 0)
+		__free_page(pages[i]);
 	if (res.acl_scratch)
 		__free_page(res.acl_scratch);
 	kfree(pages);
@@ -7037,8 +7046,15 @@
 		} else if (!nfs4_update_lock_stateid(lsp, &data->res.stateid))
 			goto out_restart;
 		break;
-	case -NFS4ERR_BAD_STATEID:
 	case -NFS4ERR_OLD_STATEID:
+		if (data->arg.new_lock_owner != 0 &&
+			nfs4_refresh_open_old_stateid(&data->arg.open_stateid,
+					lsp->ls_state))
+			goto out_restart;
+		if (nfs4_refresh_lock_old_stateid(&data->arg.lock_stateid, lsp))
+			goto out_restart;
+		fallthrough;
+	case -NFS4ERR_BAD_STATEID:
 	case -NFS4ERR_STALE_STATEID:
 	case -NFS4ERR_EXPIRED:
 		if (data->arg.new_lock_owner != 0) {
@@ -10378,6 +10394,28 @@
 	return error + error2 + error3;
 }
 
+static void nfs4_enable_swap(struct inode *inode)
+{
+	/* The state manager thread must always be running.
+	 * It will notice the client is a swapper, and stay put.
+	 */
+	struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
+
+	nfs4_schedule_state_manager(clp);
+}
+
+static void nfs4_disable_swap(struct inode *inode)
+{
+	/* The state manager thread will now exit once it is
+	 * woken.
+	 */
+	struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
+
+	set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state);
+	clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state);
+	wake_up_var(&clp->cl_state);
+}
+
 static const struct inode_operations nfs4_dir_inode_operations = {
 	.create		= nfs_create,
 	.lookup		= nfs_lookup,
@@ -10454,6 +10492,8 @@
 	.free_client	= nfs4_free_client,
 	.create_server	= nfs4_create_server,
 	.clone_server	= nfs_clone_server,
+	.enable_swap	= nfs4_enable_swap,
+	.disable_swap	= nfs4_disable_swap,
 };
 
 static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
diff --git a/kernel/fs/nfs/nfs4state.c b/kernel/fs/nfs/nfs4state.c
index a77a3d8..afb617a 100644
--- a/kernel/fs/nfs/nfs4state.c
+++ b/kernel/fs/nfs/nfs4state.c
@@ -67,6 +67,8 @@
 
 #define OPENOWNER_POOL_SIZE	8
 
+static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp);
+
 const nfs4_stateid zero_stateid = {
 	{ .data = { 0 } },
 	.type = NFS4_SPECIAL_STATEID_TYPE,
@@ -330,6 +332,8 @@
 	status = nfs4_proc_create_session(clp, cred);
 	if (status != 0)
 		goto out;
+	if (!(clp->cl_exchange_flags & EXCHGID4_FLAG_CONFIRMED_R))
+		nfs4_state_start_reclaim_reboot(clp);
 	nfs41_finish_session_reset(clp);
 	nfs_mark_client_ready(clp, NFS_CS_READY);
 out:
@@ -1208,10 +1212,23 @@
 {
 	struct task_struct *task;
 	char buf[INET6_ADDRSTRLEN + sizeof("-manager") + 1];
+	struct rpc_clnt *clnt = clp->cl_rpcclient;
+	bool swapon = false;
 
 	set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state);
+
+	if (atomic_read(&clnt->cl_swapper)) {
+		swapon = !test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE,
+					   &clp->cl_state);
+		if (!swapon) {
+			wake_up_var(&clp->cl_state);
+			return;
+		}
+	}
+
 	if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
 		return;
+
 	__module_get(THIS_MODULE);
 	refcount_inc(&clp->cl_count);
 
@@ -1226,6 +1243,10 @@
 	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));
+		if (swapon)
+			clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state);
 		nfs4_clear_state_manager_bit(clp);
 		nfs_put_client(clp);
 		module_put(THIS_MODULE);
@@ -2669,6 +2690,13 @@
 		nfs4_end_drain_session(clp);
 		nfs4_clear_state_manager_bit(clp);
 
+		if (test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) &&
+		    !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING,
+				      &clp->cl_state)) {
+			memflags = memalloc_nofs_save();
+			continue;
+		}
+
 		if (!test_and_set_bit(NFS4CLNT_RECALL_RUNNING, &clp->cl_state)) {
 			if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) {
 				nfs_client_return_marked_delegations(clp);
@@ -2678,12 +2706,8 @@
 			clear_bit(NFS4CLNT_RECALL_RUNNING, &clp->cl_state);
 		}
 
-		/* Did we race with an attempt to give us more work? */
-		if (!test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state))
-			return;
-		if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
-			return;
-		memflags = memalloc_nofs_save();
+		return;
+
 	} while (refcount_read(&clp->cl_count) > 1 && !signalled());
 	goto out_drain;
 
@@ -2704,9 +2728,34 @@
 static int nfs4_run_state_manager(void *ptr)
 {
 	struct nfs_client *clp = ptr;
+	struct rpc_clnt *cl = clp->cl_rpcclient;
+
+	while (cl != cl->cl_parent)
+		cl = cl->cl_parent;
 
 	allow_signal(SIGKILL);
+again:
 	nfs4_state_manager(clp);
+
+	if (test_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state) &&
+	    !test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state)) {
+		wait_var_event_interruptible(&clp->cl_state,
+					     test_bit(NFS4CLNT_RUN_MANAGER,
+						      &clp->cl_state));
+		if (!atomic_read(&cl->cl_swapper))
+			clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state);
+		if (refcount_read(&clp->cl_count) > 1 && !signalled() &&
+		    !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state))
+			goto again;
+		/* Either no longer a swapper, or were signalled */
+		clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state);
+	}
+
+	if (refcount_read(&clp->cl_count) > 1 && !signalled() &&
+	    test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) &&
+	    !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state))
+		goto again;
+
 	nfs_put_client(clp);
 	module_put_and_exit(0);
 	return 0;
diff --git a/kernel/fs/nfs/nfs4trace.h b/kernel/fs/nfs/nfs4trace.h
index 484c1da..d862df9 100644
--- a/kernel/fs/nfs/nfs4trace.h
+++ b/kernel/fs/nfs/nfs4trace.h
@@ -584,32 +584,34 @@
 TRACE_DEFINE_ENUM(NFS4CLNT_LEASE_MOVED);
 TRACE_DEFINE_ENUM(NFS4CLNT_DELEGATION_EXPIRED);
 TRACE_DEFINE_ENUM(NFS4CLNT_RUN_MANAGER);
+TRACE_DEFINE_ENUM(NFS4CLNT_MANAGER_AVAILABLE);
 TRACE_DEFINE_ENUM(NFS4CLNT_RECALL_RUNNING);
 TRACE_DEFINE_ENUM(NFS4CLNT_RECALL_ANY_LAYOUT_READ);
 TRACE_DEFINE_ENUM(NFS4CLNT_RECALL_ANY_LAYOUT_RW);
+TRACE_DEFINE_ENUM(NFS4CLNT_DELEGRETURN_DELAYED);
 
 #define show_nfs4_clp_state(state) \
 	__print_flags(state, "|", \
-		{ NFS4CLNT_MANAGER_RUNNING,	"MANAGER_RUNNING" }, \
-		{ NFS4CLNT_CHECK_LEASE,		"CHECK_LEASE" }, \
-		{ NFS4CLNT_LEASE_EXPIRED,	"LEASE_EXPIRED" }, \
-		{ NFS4CLNT_RECLAIM_REBOOT,	"RECLAIM_REBOOT" }, \
-		{ NFS4CLNT_RECLAIM_NOGRACE,	"RECLAIM_NOGRACE" }, \
-		{ NFS4CLNT_DELEGRETURN,		"DELEGRETURN" }, \
-		{ NFS4CLNT_SESSION_RESET,	"SESSION_RESET" }, \
-		{ NFS4CLNT_LEASE_CONFIRM,	"LEASE_CONFIRM" }, \
-		{ NFS4CLNT_SERVER_SCOPE_MISMATCH, \
-						"SERVER_SCOPE_MISMATCH" }, \
-		{ NFS4CLNT_PURGE_STATE,		"PURGE_STATE" }, \
-		{ NFS4CLNT_BIND_CONN_TO_SESSION, \
-						"BIND_CONN_TO_SESSION" }, \
-		{ NFS4CLNT_MOVED,		"MOVED" }, \
-		{ NFS4CLNT_LEASE_MOVED,		"LEASE_MOVED" }, \
-		{ NFS4CLNT_DELEGATION_EXPIRED,	"DELEGATION_EXPIRED" }, \
-		{ NFS4CLNT_RUN_MANAGER,		"RUN_MANAGER" }, \
-		{ NFS4CLNT_RECALL_RUNNING,	"RECALL_RUNNING" }, \
-		{ NFS4CLNT_RECALL_ANY_LAYOUT_READ, "RECALL_ANY_LAYOUT_READ" }, \
-		{ NFS4CLNT_RECALL_ANY_LAYOUT_RW, "RECALL_ANY_LAYOUT_RW" })
+	{ BIT(NFS4CLNT_MANAGER_RUNNING),	"MANAGER_RUNNING" }, \
+	{ BIT(NFS4CLNT_CHECK_LEASE),		"CHECK_LEASE" }, \
+	{ BIT(NFS4CLNT_LEASE_EXPIRED),	"LEASE_EXPIRED" }, \
+	{ BIT(NFS4CLNT_RECLAIM_REBOOT),	"RECLAIM_REBOOT" }, \
+	{ BIT(NFS4CLNT_RECLAIM_NOGRACE),	"RECLAIM_NOGRACE" }, \
+	{ BIT(NFS4CLNT_DELEGRETURN),		"DELEGRETURN" }, \
+	{ BIT(NFS4CLNT_SESSION_RESET),	"SESSION_RESET" }, \
+	{ BIT(NFS4CLNT_LEASE_CONFIRM),	"LEASE_CONFIRM" }, \
+	{ BIT(NFS4CLNT_SERVER_SCOPE_MISMATCH),	"SERVER_SCOPE_MISMATCH" }, \
+	{ BIT(NFS4CLNT_PURGE_STATE),		"PURGE_STATE" }, \
+	{ BIT(NFS4CLNT_BIND_CONN_TO_SESSION),	"BIND_CONN_TO_SESSION" }, \
+	{ BIT(NFS4CLNT_MOVED),		"MOVED" }, \
+	{ BIT(NFS4CLNT_LEASE_MOVED),		"LEASE_MOVED" }, \
+	{ BIT(NFS4CLNT_DELEGATION_EXPIRED),	"DELEGATION_EXPIRED" }, \
+	{ BIT(NFS4CLNT_RUN_MANAGER),		"RUN_MANAGER" }, \
+	{ BIT(NFS4CLNT_MANAGER_AVAILABLE), "MANAGER_AVAILABLE" }, \
+	{ BIT(NFS4CLNT_RECALL_RUNNING),	"RECALL_RUNNING" }, \
+	{ BIT(NFS4CLNT_RECALL_ANY_LAYOUT_READ), "RECALL_ANY_LAYOUT_READ" }, \
+	{ BIT(NFS4CLNT_RECALL_ANY_LAYOUT_RW), "RECALL_ANY_LAYOUT_RW" }, \
+	{ BIT(NFS4CLNT_DELEGRETURN_DELAYED), "DELERETURN_DELAYED" })
 
 TRACE_EVENT(nfs4_state_mgr,
 		TP_PROTO(
diff --git a/kernel/fs/nfs/nfs4xdr.c b/kernel/fs/nfs/nfs4xdr.c
index e2f0e34..f1e5995 100644
--- a/kernel/fs/nfs/nfs4xdr.c
+++ b/kernel/fs/nfs/nfs4xdr.c
@@ -4166,19 +4166,17 @@
 		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) {
-					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;
 				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);
diff --git a/kernel/fs/nfs/pnfs_dev.c b/kernel/fs/nfs/pnfs_dev.c
index 537b80d..d4829f3 100644
--- a/kernel/fs/nfs/pnfs_dev.c
+++ b/kernel/fs/nfs/pnfs_dev.c
@@ -152,7 +152,7 @@
 		set_bit(NFS_DEVICEID_NOCACHE, &d->flags);
 
 out_free_pages:
-	for (i = 0; i < max_pages; i++)
+	while (--i >= 0)
 		__free_page(pages[i]);
 	kfree(pages);
 out_free_pdev:
diff --git a/kernel/fs/nfs/sysfs.c b/kernel/fs/nfs/sysfs.c
index 8cb7075..f7f778e 100644
--- a/kernel/fs/nfs/sysfs.c
+++ b/kernel/fs/nfs/sysfs.c
@@ -18,7 +18,7 @@
 #include "sysfs.h"
 
 struct kobject *nfs_client_kobj;
-static struct kset *nfs_client_kset;
+static struct kset *nfs_kset;
 
 static void nfs_netns_object_release(struct kobject *kobj)
 {
@@ -55,13 +55,13 @@
 
 int nfs_sysfs_init(void)
 {
-	nfs_client_kset = kset_create_and_add("nfs", NULL, fs_kobj);
-	if (!nfs_client_kset)
+	nfs_kset = kset_create_and_add("nfs", NULL, fs_kobj);
+	if (!nfs_kset)
 		return -ENOMEM;
-	nfs_client_kobj = nfs_netns_object_alloc("net", nfs_client_kset, NULL);
+	nfs_client_kobj = nfs_netns_object_alloc("net", nfs_kset, NULL);
 	if  (!nfs_client_kobj) {
-		kset_unregister(nfs_client_kset);
-		nfs_client_kset = NULL;
+		kset_unregister(nfs_kset);
+		nfs_kset = NULL;
 		return -ENOMEM;
 	}
 	return 0;
@@ -70,7 +70,7 @@
 void nfs_sysfs_exit(void)
 {
 	kobject_put(nfs_client_kobj);
-	kset_unregister(nfs_client_kset);
+	kset_unregister(nfs_kset);
 }
 
 static ssize_t nfs_netns_identifier_show(struct kobject *kobj,
@@ -158,7 +158,7 @@
 	p = kzalloc(sizeof(*p), GFP_KERNEL);
 	if (p) {
 		p->net = net;
-		p->kobject.kset = nfs_client_kset;
+		p->kobject.kset = nfs_kset;
 		if (kobject_init_and_add(&p->kobject, &nfs_netns_client_type,
 					parent, "nfs_client") == 0)
 			return p;
diff --git a/kernel/fs/nfs/write.c b/kernel/fs/nfs/write.c
index dc08a0c..d3cd099 100644
--- a/kernel/fs/nfs/write.c
+++ b/kernel/fs/nfs/write.c
@@ -58,7 +58,8 @@
 static const struct nfs_commit_completion_ops nfs_commit_completion_ops;
 static const struct nfs_rw_ops nfs_rw_write_ops;
 static void nfs_inode_remove_request(struct nfs_page *req);
-static void nfs_clear_request_commit(struct nfs_page *req);
+static void nfs_clear_request_commit(struct nfs_commit_info *cinfo,
+				     struct nfs_page *req);
 static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo,
 				      struct inode *inode);
 static struct nfs_page *
@@ -500,8 +501,8 @@
  * the (former) group.  All subrequests are removed from any write or commit
  * lists, unlinked from the group and destroyed.
  */
-void
-nfs_join_page_group(struct nfs_page *head, struct inode *inode)
+void nfs_join_page_group(struct nfs_page *head, struct nfs_commit_info *cinfo,
+			 struct inode *inode)
 {
 	struct nfs_page *subreq;
 	struct nfs_page *destroy_list = NULL;
@@ -531,7 +532,7 @@
 	 * Commit list removal accounting is done after locks are dropped */
 	subreq = head;
 	do {
-		nfs_clear_request_commit(subreq);
+		nfs_clear_request_commit(cinfo, subreq);
 		subreq = subreq->wb_this_page;
 	} while (subreq != head);
 
@@ -565,8 +566,10 @@
 {
 	struct inode *inode = page_file_mapping(page)->host;
 	struct nfs_page *head;
+	struct nfs_commit_info cinfo;
 	int ret;
 
+	nfs_init_cinfo_from_inode(&cinfo, inode);
 	/*
 	 * A reference is taken only on the head request which acts as a
 	 * reference to the whole page group - the group will not be destroyed
@@ -583,7 +586,7 @@
 		return ERR_PTR(ret);
 	}
 
-	nfs_join_page_group(head, inode);
+	nfs_join_page_group(head, &cinfo, inode);
 
 	return head;
 }
@@ -944,18 +947,16 @@
 }
 
 /* Called holding the request lock on @req */
-static void
-nfs_clear_request_commit(struct nfs_page *req)
+static void nfs_clear_request_commit(struct nfs_commit_info *cinfo,
+				     struct nfs_page *req)
 {
 	if (test_bit(PG_CLEAN, &req->wb_flags)) {
 		struct nfs_open_context *ctx = nfs_req_openctx(req);
 		struct inode *inode = d_inode(ctx->dentry);
-		struct nfs_commit_info cinfo;
 
-		nfs_init_cinfo_from_inode(&cinfo, inode);
 		mutex_lock(&NFS_I(inode)->commit_mutex);
-		if (!pnfs_clear_request_commit(req, &cinfo)) {
-			nfs_request_remove_commit_list(req, &cinfo);
+		if (!pnfs_clear_request_commit(req, cinfo)) {
+			nfs_request_remove_commit_list(req, cinfo);
 		}
 		mutex_unlock(&NFS_I(inode)->commit_mutex);
 		nfs_clear_page_commit(req->wb_page);
diff --git a/kernel/fs/nfsd/blocklayoutxdr.c b/kernel/fs/nfsd/blocklayoutxdr.c
index 4425433..2455dc8 100644
--- a/kernel/fs/nfsd/blocklayoutxdr.c
+++ b/kernel/fs/nfsd/blocklayoutxdr.c
@@ -82,6 +82,15 @@
 	int len = sizeof(__be32), ret, i;
 	__be32 *p;
 
+	/*
+	 * See paragraph 5 of RFC 8881 S18.40.3.
+	 */
+	if (!gdp->gd_maxcount) {
+		if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT)
+			return nfserr_resource;
+		return nfs_ok;
+	}
+
 	p = xdr_reserve_space(xdr, len + sizeof(__be32));
 	if (!p)
 		return nfserr_resource;
diff --git a/kernel/fs/nfsd/flexfilelayoutxdr.c b/kernel/fs/nfsd/flexfilelayoutxdr.c
index e81d2a5..bb20532 100644
--- a/kernel/fs/nfsd/flexfilelayoutxdr.c
+++ b/kernel/fs/nfsd/flexfilelayoutxdr.c
@@ -85,6 +85,15 @@
 	int addr_len;
 	__be32 *p;
 
+	/*
+	 * See paragraph 5 of RFC 8881 S18.40.3.
+	 */
+	if (!gdp->gd_maxcount) {
+		if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT)
+			return nfserr_resource;
+		return nfs_ok;
+	}
+
 	/* len + padding for two strings */
 	addr_len = 16 + da->netaddr.netid_len + da->netaddr.addr_len;
 	ver_len = 20;
diff --git a/kernel/fs/nfsd/netns.h b/kernel/fs/nfsd/netns.h
index 7346acd..02d3d2f 100644
--- a/kernel/fs/nfsd/netns.h
+++ b/kernel/fs/nfsd/netns.h
@@ -42,9 +42,6 @@
 	bool grace_ended;
 	time64_t boot_time;
 
-	/* internal mount of the "nfsd" pseudofilesystem: */
-	struct vfsmount *nfsd_mnt;
-
 	struct dentry *nfsd_client_dir;
 
 	/*
@@ -121,6 +118,9 @@
 	wait_queue_head_t ntf_wq;
 	atomic_t ntf_refcnt;
 
+	/* Allow umount to wait for nfsd state cleanup */
+	struct completion nfsd_shutdown_complete;
+
 	/*
 	 * clientid and stateid data for construction of net unique COPY
 	 * stateids.
diff --git a/kernel/fs/nfsd/nfs4callback.c b/kernel/fs/nfsd/nfs4callback.c
index 7325592..f5b7ad0 100644
--- a/kernel/fs/nfsd/nfs4callback.c
+++ b/kernel/fs/nfsd/nfs4callback.c
@@ -875,8 +875,8 @@
 		if (!kcred)
 			return NULL;
 
-		kcred->uid = ses->se_cb_sec.uid;
-		kcred->gid = ses->se_cb_sec.gid;
+		kcred->fsuid = ses->se_cb_sec.uid;
+		kcred->fsgid = ses->se_cb_sec.gid;
 		return kcred;
 	}
 }
@@ -915,11 +915,8 @@
 		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;
 		args.prognumber = clp->cl_cb_session->se_cb_prog;
@@ -939,6 +936,9 @@
 		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);
diff --git a/kernel/fs/nfsd/nfs4layouts.c b/kernel/fs/nfsd/nfs4layouts.c
index a97873f..2673019 100644
--- a/kernel/fs/nfsd/nfs4layouts.c
+++ b/kernel/fs/nfsd/nfs4layouts.c
@@ -322,11 +322,11 @@
 	if (ls->ls_recalled)
 		goto out_unlock;
 
-	ls->ls_recalled = true;
-	atomic_inc(&ls->ls_stid.sc_file->fi_lo_recalls);
 	if (list_empty(&ls->ls_layouts))
 		goto out_unlock;
 
+	ls->ls_recalled = true;
+	atomic_inc(&ls->ls_stid.sc_file->fi_lo_recalls);
 	trace_nfsd_layout_recall(&ls->ls_stid.sc_stateid);
 
 	refcount_inc(&ls->ls_stid.sc_count);
diff --git a/kernel/fs/nfsd/nfs4proc.c b/kernel/fs/nfsd/nfs4proc.c
index 735ee8a..e84996c 100644
--- a/kernel/fs/nfsd/nfs4proc.c
+++ b/kernel/fs/nfsd/nfs4proc.c
@@ -881,8 +881,8 @@
 			     rename->rn_tname, rename->rn_tnamelen);
 	if (status)
 		return status;
-	set_change_info(&rename->rn_sinfo, &cstate->current_fh);
-	set_change_info(&rename->rn_tinfo, &cstate->save_fh);
+	set_change_info(&rename->rn_sinfo, &cstate->save_fh);
+	set_change_info(&rename->rn_tinfo, &cstate->current_fh);
 	return nfs_ok;
 }
 
@@ -1075,8 +1075,10 @@
 	return status;
 out_put_dst:
 	nfsd_file_put(*dst);
+	*dst = NULL;
 out_put_src:
 	nfsd_file_put(*src);
+	*src = NULL;
 	goto out;
 }
 
@@ -1246,13 +1248,6 @@
 	return status;
 }
 
-static void
-nfsd4_interssc_disconnect(struct vfsmount *ss_mnt)
-{
-	nfs_do_sb_deactive(ss_mnt->mnt_sb);
-	mntput(ss_mnt);
-}
-
 /*
  * Verify COPY destination stateid.
  *
@@ -1320,11 +1315,6 @@
 static void
 nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct nfsd_file *src,
 			struct nfsd_file *dst)
-{
-}
-
-static void
-nfsd4_interssc_disconnect(struct vfsmount *ss_mnt)
 {
 }
 
@@ -1469,14 +1459,14 @@
 		copy->nf_src = kzalloc(sizeof(struct nfsd_file), GFP_KERNEL);
 		if (!copy->nf_src) {
 			copy->nfserr = nfserr_serverfault;
-			nfsd4_interssc_disconnect(copy->ss_mnt);
+			/* ss_mnt will be unmounted by the laundromat */
 			goto do_callback;
 		}
 		copy->nf_src->nf_file = nfs42_ssc_open(copy->ss_mnt, &copy->c_fh,
 					      &copy->stateid);
 		if (IS_ERR(copy->nf_src->nf_file)) {
 			copy->nfserr = nfserr_offload_denied;
-			nfsd4_interssc_disconnect(copy->ss_mnt);
+			/* ss_mnt will be unmounted by the laundromat */
 			goto do_callback;
 		}
 	}
@@ -1559,8 +1549,10 @@
 	if (async_copy)
 		cleanup_async_copy(async_copy);
 	status = nfserrno(-ENOMEM);
-	if (!copy->cp_intra)
-		nfsd4_interssc_disconnect(copy->ss_mnt);
+	/*
+	 * source's vfsmount of inter-copy will be unmounted
+	 * by the laundromat
+	 */
 	goto out;
 }
 
diff --git a/kernel/fs/nfsd/nfs4state.c b/kernel/fs/nfsd/nfs4state.c
index 665d0ea..b045be7 100644
--- a/kernel/fs/nfsd/nfs4state.c
+++ b/kernel/fs/nfsd/nfs4state.c
@@ -507,15 +507,26 @@
 	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);
 
-	spin_lock(&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);
+
 	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;
@@ -1134,9 +1145,9 @@
 	WARN_ON(!list_empty(&dp->dl_recall_lru));
 
 	if (clp->cl_minorversion) {
+		spin_lock(&clp->cl_lock);
 		dp->dl_stid.sc_type = NFS4_REVOKED_DELEG_STID;
 		refcount_inc(&dp->dl_stid.sc_count);
-		spin_lock(&clp->cl_lock);
 		list_add(&dp->dl_recall_lru, &clp->cl_revoked);
 		spin_unlock(&clp->cl_lock);
 	}
@@ -2462,9 +2473,11 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 
 	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 @@
 	seq_printf(s, ", ");
 	nfs4_show_fname(s, file);
 	seq_printf(s, " }\n");
-	nfsd_file_put(file);
-
+out:
+	spin_unlock(&nf->fi_lock);
 	return 0;
 }
 
@@ -5641,8 +5656,6 @@
 	if (ZERO_STATEID(stateid) || ONE_STATEID(stateid) ||
 		CLOSE_STATEID(stateid))
 		return status;
-	if (!same_clid(&stateid->si_opaque.so_clid, &cl->cl_clientid))
-		return status;
 	spin_lock(&cl->cl_lock);
 	s = find_stateid_locked(cl, stateid);
 	if (!s)
@@ -7379,14 +7392,9 @@
 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 	int ret;
 
-	ret = get_nfsdfs(net);
+	ret = nfs4_state_create_net(net);
 	if (ret)
 		return ret;
-	ret = nfs4_state_create_net(net);
-	if (ret) {
-		mntput(nn->nfsd_mnt);
-		return ret;
-	}
 	locks_start_grace(net, &nn->nfsd4_manager);
 	nfsd4_client_tracking_init(net);
 	if (nn->track_reclaim_completes && nn->reclaim_str_hashtbl_size == 0)
@@ -7456,7 +7464,6 @@
 
 	nfsd4_client_tracking_exit(net);
 	nfs4_state_destroy_net(net);
-	mntput(nn->nfsd_mnt);
 }
 
 void
diff --git a/kernel/fs/nfsd/nfs4xdr.c b/kernel/fs/nfsd/nfs4xdr.c
index cc605ee..dbfa24c 100644
--- a/kernel/fs/nfsd/nfs4xdr.c
+++ b/kernel/fs/nfsd/nfs4xdr.c
@@ -3405,6 +3405,17 @@
 	case nfserr_noent:
 		xdr_truncate_encode(xdr, start_offset);
 		goto skip_entry;
+	case nfserr_jukebox:
+		/*
+		 * The pseudoroot should only display dentries that lead to
+		 * exports. If we get EJUKEBOX here, then we can't tell whether
+		 * this entry should be included. Just fail the whole READDIR
+		 * with NFS4ERR_DELAY in that case, and hope that the situation
+		 * will resolve itself by the client's next attempt.
+		 */
+		if (cd->rd_fhp->fh_export->ex_flags & NFSEXP_V4ROOT)
+			goto fail;
+		fallthrough;
 	default:
 		/*
 		 * If the client requested the RDATTR_ERROR attribute,
@@ -3694,7 +3705,7 @@
 		p = xdr_reserve_space(xdr, 32);
 		if (!p)
 			return nfserr_resource;
-		*p++ = cpu_to_be32(0);
+		*p++ = cpu_to_be32(open->op_recall);
 
 		/*
 		 * TODO: space_limit's in delegations
@@ -4396,20 +4407,17 @@
 
 	*p++ = cpu_to_be32(gdev->gd_layout_type);
 
-	/* If maxcount is 0 then just update notifications */
-	if (gdev->gd_maxcount != 0) {
-		ops = nfsd4_layout_ops[gdev->gd_layout_type];
-		nfserr = ops->encode_getdeviceinfo(xdr, gdev);
-		if (nfserr) {
-			/*
-			 * We don't bother to burden the layout drivers with
-			 * enforcing gd_maxcount, just tell the client to
-			 * come back with a bigger buffer if it's not enough.
-			 */
-			if (xdr->buf->len + 4 > gdev->gd_maxcount)
-				goto toosmall;
-			return nfserr;
-		}
+	ops = nfsd4_layout_ops[gdev->gd_layout_type];
+	nfserr = ops->encode_getdeviceinfo(xdr, gdev);
+	if (nfserr) {
+		/*
+		 * We don't bother to burden the layout drivers with
+		 * enforcing gd_maxcount, just tell the client to
+		 * come back with a bigger buffer if it's not enough.
+		 */
+		if (xdr->buf->len + 4 > gdev->gd_maxcount)
+			goto toosmall;
+		return nfserr;
 	}
 
 	if (gdev->gd_notify_types) {
diff --git a/kernel/fs/nfsd/nfsctl.c b/kernel/fs/nfsd/nfsctl.c
index 2796ecf..7c36634 100644
--- a/kernel/fs/nfsd/nfsctl.c
+++ b/kernel/fs/nfsd/nfsctl.c
@@ -1417,6 +1417,8 @@
 {
 	struct net *net = sb->s_fs_info;
 
+	nfsd_shutdown_threads(net);
+
 	kill_litter_super(sb);
 	put_net(net);
 }
@@ -1428,18 +1430,6 @@
 	.kill_sb	= nfsd_umount,
 };
 MODULE_ALIAS_FS("nfsd");
-
-int get_nfsdfs(struct net *net)
-{
-	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
-	struct vfsmount *mnt;
-
-	mnt =  vfs_kern_mount(&nfsd_fs_type, SB_KERNMOUNT, "nfsd", NULL);
-	if (IS_ERR(mnt))
-		return PTR_ERR(mnt);
-	nn->nfsd_mnt = mnt;
-	return 0;
-}
 
 #ifdef CONFIG_PROC_FS
 static int create_proc_exports_entry(void)
diff --git a/kernel/fs/nfsd/nfsd.h b/kernel/fs/nfsd/nfsd.h
index cb742e1..4362d29 100644
--- a/kernel/fs/nfsd/nfsd.h
+++ b/kernel/fs/nfsd/nfsd.h
@@ -85,12 +85,11 @@
 int		nfsd_set_nrthreads(int n, int *, struct net *);
 int		nfsd_pool_stats_open(struct inode *, struct file *);
 int		nfsd_pool_stats_release(struct inode *, struct file *);
+void		nfsd_shutdown_threads(struct net *net);
 
 void		nfsd_destroy(struct net *net);
 
 bool		i_am_nfsd(void);
-
-int get_nfsdfs(struct net *);
 
 struct nfsdfs_client {
 	struct kref cl_ref;
diff --git a/kernel/fs/nfsd/nfssvc.c b/kernel/fs/nfsd/nfssvc.c
index 9323e30..2e61a56 100644
--- a/kernel/fs/nfsd/nfssvc.c
+++ b/kernel/fs/nfsd/nfssvc.c
@@ -426,8 +426,8 @@
 {
 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 
-	nfsd_file_cache_shutdown_net(net);
 	nfs4_state_shutdown_net(net);
+	nfsd_file_cache_shutdown_net(net);
 	if (nn->lockd_up) {
 		lockd_down(net);
 		nn->lockd_up = false;
@@ -600,6 +600,37 @@
 	.svo_module		= THIS_MODULE,
 };
 
+static void nfsd_complete_shutdown(struct net *net)
+{
+	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
+
+	WARN_ON(!mutex_is_locked(&nfsd_mutex));
+
+	nn->nfsd_serv = NULL;
+	complete(&nn->nfsd_shutdown_complete);
+}
+
+void nfsd_shutdown_threads(struct net *net)
+{
+	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
+	struct svc_serv *serv;
+
+	mutex_lock(&nfsd_mutex);
+	serv = nn->nfsd_serv;
+	if (serv == NULL) {
+		mutex_unlock(&nfsd_mutex);
+		return;
+	}
+
+	svc_get(serv);
+	/* Kill outstanding nfsd threads */
+	serv->sv_ops->svo_setup(serv, NULL, 0);
+	nfsd_destroy(net);
+	mutex_unlock(&nfsd_mutex);
+	/* Wait for shutdown of nfsd_serv to complete */
+	wait_for_completion(&nn->nfsd_shutdown_complete);
+}
+
 bool i_am_nfsd(void)
 {
 	return kthread_func(current) == nfsd;
@@ -622,11 +653,13 @@
 						&nfsd_thread_sv_ops);
 	if (nn->nfsd_serv == NULL)
 		return -ENOMEM;
+	init_completion(&nn->nfsd_shutdown_complete);
 
 	nn->nfsd_serv->sv_maxconn = nn->max_connections;
 	error = svc_bind(nn->nfsd_serv, net);
 	if (error < 0) {
 		svc_destroy(nn->nfsd_serv);
+		nfsd_complete_shutdown(net);
 		return error;
 	}
 
@@ -675,7 +708,7 @@
 		svc_shutdown_net(nn->nfsd_serv, net);
 	svc_destroy(nn->nfsd_serv);
 	if (destroy)
-		nn->nfsd_serv = NULL;
+		nfsd_complete_shutdown(net);
 }
 
 int nfsd_set_nrthreads(int n, int *nthreads, struct net *net)
diff --git a/kernel/fs/nilfs2/alloc.c b/kernel/fs/nilfs2/alloc.c
index adf3bb0..279d945 100644
--- a/kernel/fs/nilfs2/alloc.c
+++ b/kernel/fs/nilfs2/alloc.c
@@ -205,7 +205,8 @@
 	int ret;
 
 	spin_lock(lock);
-	if (prev->bh && blkoff == prev->blkoff) {
+	if (prev->bh && blkoff == prev->blkoff &&
+	    likely(buffer_uptodate(prev->bh))) {
 		get_bh(prev->bh);
 		*bhp = prev->bh;
 		spin_unlock(lock);
diff --git a/kernel/fs/nilfs2/bmap.c b/kernel/fs/nilfs2/bmap.c
index 5900879..8ebb69c 100644
--- a/kernel/fs/nilfs2/bmap.c
+++ b/kernel/fs/nilfs2/bmap.c
@@ -67,20 +67,28 @@
 
 	down_read(&bmap->b_sem);
 	ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp);
-	if (ret < 0) {
-		ret = nilfs_bmap_convert_error(bmap, __func__, ret);
+	if (ret < 0)
 		goto out;
-	}
+
 	if (NILFS_BMAP_USE_VBN(bmap)) {
 		ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), *ptrp,
 					  &blocknr);
 		if (!ret)
 			*ptrp = blocknr;
+		else if (ret == -ENOENT) {
+			/*
+			 * If there was no valid entry in DAT for the block
+			 * address obtained by b_ops->bop_lookup, then pass
+			 * internal code -EINVAL to nilfs_bmap_convert_error
+			 * to treat it as metadata corruption.
+			 */
+			ret = -EINVAL;
+		}
 	}
 
  out:
 	up_read(&bmap->b_sem);
-	return ret;
+	return nilfs_bmap_convert_error(bmap, __func__, ret);
 }
 
 int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp,
diff --git a/kernel/fs/nilfs2/btnode.c b/kernel/fs/nilfs2/btnode.c
index e00e184..1776121 100644
--- a/kernel/fs/nilfs2/btnode.c
+++ b/kernel/fs/nilfs2/btnode.c
@@ -285,6 +285,14 @@
 	if (nbh == NULL) {	/* blocksize == pagesize */
 		xa_erase_irq(&btnc->i_pages, newkey);
 		unlock_page(ctxt->bh->b_page);
-	} else
-		brelse(nbh);
+	} else {
+		/*
+		 * When canceling a buffer that a prepare operation has
+		 * allocated to copy a node block to another location, use
+		 * nilfs_btnode_delete() to initialize and release the buffer
+		 * so that the buffer flags will not be in an inconsistent
+		 * state when it is reallocated.
+		 */
+		nilfs_btnode_delete(nbh);
+	}
 }
diff --git a/kernel/fs/nilfs2/btree.c b/kernel/fs/nilfs2/btree.c
index 77efd69..65cd599 100644
--- a/kernel/fs/nilfs2/btree.c
+++ b/kernel/fs/nilfs2/btree.c
@@ -480,9 +480,18 @@
 	ret = nilfs_btnode_submit_block(btnc, ptr, 0, REQ_OP_READ, 0, &bh,
 					&submit_ptr);
 	if (ret) {
-		if (ret != -EEXIST)
-			return ret;
-		goto out_check;
+		if (likely(ret == -EEXIST))
+			goto out_check;
+		if (ret == -ENOENT) {
+			/*
+			 * Block address translation failed due to invalid
+			 * value of 'ptr'.  In this case, return internal code
+			 * -EINVAL (broken bmap) to notify bmap layer of fatal
+			 * metadata corruption.
+			 */
+			ret = -EINVAL;
+		}
+		return ret;
 	}
 
 	if (ra) {
diff --git a/kernel/fs/nilfs2/gcinode.c b/kernel/fs/nilfs2/gcinode.c
index aadea66..b0077f5 100644
--- a/kernel/fs/nilfs2/gcinode.c
+++ b/kernel/fs/nilfs2/gcinode.c
@@ -73,10 +73,8 @@
 		struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
 
 		err = nilfs_dat_translate(nilfs->ns_dat, vbn, &pbn);
-		if (unlikely(err)) { /* -EIO, -ENOMEM, -ENOENT */
-			brelse(bh);
+		if (unlikely(err)) /* -EIO, -ENOMEM, -ENOENT */
 			goto failed;
-		}
 	}
 
 	lock_buffer(bh);
@@ -102,6 +100,8 @@
  failed:
 	unlock_page(bh->b_page);
 	put_page(bh->b_page);
+	if (unlikely(err))
+		brelse(bh);
 	return err;
 }
 
diff --git a/kernel/fs/nilfs2/inode.c b/kernel/fs/nilfs2/inode.c
index fb594ed..d144e08 100644
--- a/kernel/fs/nilfs2/inode.c
+++ b/kernel/fs/nilfs2/inode.c
@@ -921,6 +921,7 @@
 	struct nilfs_transaction_info ti;
 	struct super_block *sb = inode->i_sb;
 	struct nilfs_inode_info *ii = NILFS_I(inode);
+	struct the_nilfs *nilfs;
 	int ret;
 
 	if (inode->i_nlink || !ii->i_root || unlikely(is_bad_inode(inode))) {
@@ -932,6 +933,23 @@
 	nilfs_transaction_begin(sb, &ti, 0); /* never fails */
 
 	truncate_inode_pages_final(&inode->i_data);
+
+	nilfs = sb->s_fs_info;
+	if (unlikely(sb_rdonly(sb) || !nilfs->ns_writer)) {
+		/*
+		 * If this inode is about to be disposed after the file system
+		 * has been degraded to read-only due to file system corruption
+		 * or after the writer has been detached, do not make any
+		 * changes that cause writes, just clear it.
+		 * Do this check after read-locking ns_segctor_sem by
+		 * nilfs_transaction_begin() in order to avoid a race with
+		 * the writer detach operation.
+		 */
+		clear_inode(inode);
+		nilfs_clear_inode(inode);
+		nilfs_transaction_abort(sb);
+		return;
+	}
 
 	/* TODO: some of the following operations may fail.  */
 	nilfs_truncate_bmap(ii, 0);
@@ -1009,7 +1027,7 @@
 	int err;
 
 	spin_lock(&nilfs->ns_inode_lock);
-	if (ii->i_bh == NULL) {
+	if (ii->i_bh == NULL || unlikely(!buffer_uptodate(ii->i_bh))) {
 		spin_unlock(&nilfs->ns_inode_lock);
 		err = nilfs_ifile_get_inode_block(ii->i_root->ifile,
 						  inode->i_ino, pbh);
@@ -1018,7 +1036,10 @@
 		spin_lock(&nilfs->ns_inode_lock);
 		if (ii->i_bh == NULL)
 			ii->i_bh = *pbh;
-		else {
+		else if (unlikely(!buffer_uptodate(ii->i_bh))) {
+			__brelse(ii->i_bh);
+			ii->i_bh = *pbh;
+		} else {
 			brelse(*pbh);
 			*pbh = ii->i_bh;
 		}
@@ -1085,9 +1106,17 @@
 
 int __nilfs_mark_inode_dirty(struct inode *inode, int flags)
 {
+	struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
 	struct buffer_head *ibh;
 	int err;
 
+	/*
+	 * Do not dirty inodes after the log writer has been detached
+	 * and its nilfs_root struct has been freed.
+	 */
+	if (unlikely(nilfs_purging(nilfs)))
+		return 0;
+
 	err = nilfs_load_inode_block(inode, &ibh);
 	if (unlikely(err)) {
 		nilfs_warn(inode->i_sb,
diff --git a/kernel/fs/nilfs2/ioctl.c b/kernel/fs/nilfs2/ioctl.c
index 07d26f6..01235fa 100644
--- a/kernel/fs/nilfs2/ioctl.c
+++ b/kernel/fs/nilfs2/ioctl.c
@@ -70,7 +70,7 @@
 	if (argv->v_index > ~(__u64)0 - argv->v_nmembs)
 		return -EINVAL;
 
-	buf = (void *)__get_free_pages(GFP_NOFS, 0);
+	buf = (void *)get_zeroed_page(GFP_NOFS);
 	if (unlikely(!buf))
 		return -ENOMEM;
 	maxmembs = PAGE_SIZE / argv->v_size;
@@ -1129,7 +1129,14 @@
 
 	minseg = range[0] + segbytes - 1;
 	do_div(minseg, segbytes);
+
+	if (range[1] < 4096)
+		goto out;
+
 	maxseg = NILFS_SB2_OFFSET_BYTES(range[1]);
+	if (maxseg < segbytes)
+		goto out;
+
 	do_div(maxseg, segbytes);
 	maxseg--;
 
diff --git a/kernel/fs/nilfs2/page.c b/kernel/fs/nilfs2/page.c
index d1a148f..81992b9 100644
--- a/kernel/fs/nilfs2/page.c
+++ b/kernel/fs/nilfs2/page.c
@@ -369,7 +369,15 @@
 			struct page *page = pvec.pages[i];
 
 			lock_page(page);
-			nilfs_clear_dirty_page(page, silent);
+
+			/*
+			 * This page may have been removed from the address
+			 * space by truncation or invalidation when the lock
+			 * was acquired.  Skip processing in that case.
+			 */
+			if (likely(page->mapping == mapping))
+				nilfs_clear_dirty_page(page, silent);
+
 			unlock_page(page);
 		}
 		pagevec_release(&pvec);
diff --git a/kernel/fs/nilfs2/segbuf.c b/kernel/fs/nilfs2/segbuf.c
index 1a8729e..9f43587 100644
--- a/kernel/fs/nilfs2/segbuf.c
+++ b/kernel/fs/nilfs2/segbuf.c
@@ -101,6 +101,12 @@
 	if (unlikely(!bh))
 		return -ENOMEM;
 
+	lock_buffer(bh);
+	if (!buffer_uptodate(bh)) {
+		memset(bh->b_data, 0, bh->b_size);
+		set_buffer_uptodate(bh);
+	}
+	unlock_buffer(bh);
 	nilfs_segbuf_add_segsum_buffer(segbuf, bh);
 	return 0;
 }
diff --git a/kernel/fs/nilfs2/segment.c b/kernel/fs/nilfs2/segment.c
index 5ee4973..418055a 100644
--- a/kernel/fs/nilfs2/segment.c
+++ b/kernel/fs/nilfs2/segment.c
@@ -435,6 +435,23 @@
 	return 0;
 }
 
+/**
+ * nilfs_segctor_zeropad_segsum - zero pad the rest of the segment summary area
+ * @sci: segment constructor object
+ *
+ * nilfs_segctor_zeropad_segsum() zero-fills unallocated space at the end of
+ * the current segment summary block.
+ */
+static void nilfs_segctor_zeropad_segsum(struct nilfs_sc_info *sci)
+{
+	struct nilfs_segsum_pointer *ssp;
+
+	ssp = sci->sc_blk_cnt > 0 ? &sci->sc_binfo_ptr : &sci->sc_finfo_ptr;
+	if (ssp->offset < ssp->bh->b_size)
+		memset(ssp->bh->b_data + ssp->offset, 0,
+		       ssp->bh->b_size - ssp->offset);
+}
+
 static int nilfs_segctor_feed_segment(struct nilfs_sc_info *sci)
 {
 	sci->sc_nblk_this_inc += sci->sc_curseg->sb_sum.nblocks;
@@ -443,6 +460,7 @@
 				* The current segment is filled up
 				* (internal code)
 				*/
+	nilfs_segctor_zeropad_segsum(sci);
 	sci->sc_curseg = NILFS_NEXT_SEGBUF(sci->sc_curseg);
 	return nilfs_segctor_reset_segment_buffer(sci);
 }
@@ -547,6 +565,7 @@
 		goto retry;
 	}
 	if (unlikely(required)) {
+		nilfs_segctor_zeropad_segsum(sci);
 		err = nilfs_segbuf_extend_segsum(segbuf);
 		if (unlikely(err))
 			goto failed;
@@ -711,6 +730,11 @@
 		struct page *page = pvec.pages[i];
 
 		lock_page(page);
+		if (unlikely(page->mapping != mapping)) {
+			/* Exclude pages removed from the address space */
+			unlock_page(page);
+			continue;
+		}
 		if (!page_has_buffers(page))
 			create_empty_buffers(page, i_blocksize(inode), 0);
 		unlock_page(page);
@@ -965,10 +989,13 @@
 	unsigned int isz, srsz;
 
 	bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root;
+
+	lock_buffer(bh_sr);
 	raw_sr = (struct nilfs_super_root *)bh_sr->b_data;
 	isz = nilfs->ns_inode_size;
 	srsz = NILFS_SR_BYTES(isz);
 
+	raw_sr->sr_sum = 0;  /* Ensure initialization within this update */
 	raw_sr->sr_bytes = cpu_to_le16(srsz);
 	raw_sr->sr_nongc_ctime
 		= cpu_to_le64(nilfs_doing_gc() ?
@@ -982,6 +1009,8 @@
 	nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr +
 				 NILFS_SR_SUFILE_OFFSET(isz), 1);
 	memset((void *)raw_sr + srsz, 0, nilfs->ns_blocksize - srsz);
+	set_buffer_uptodate(bh_sr);
+	unlock_buffer(bh_sr);
 }
 
 static void nilfs_redirty_inodes(struct list_head *head)
@@ -1536,6 +1565,7 @@
 		nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA);
 		sci->sc_stage = prev_stage;
 	}
+	nilfs_segctor_zeropad_segsum(sci);
 	nilfs_segctor_truncate_segments(sci, sci->sc_curseg, nilfs->ns_sufile);
 	return 0;
 
@@ -1763,6 +1793,7 @@
 	list_for_each_entry(segbuf, logs, sb_list) {
 		list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
 				    b_assoc_buffers) {
+			clear_buffer_uptodate(bh);
 			if (bh->b_page != bd_page) {
 				if (bd_page)
 					end_page_writeback(bd_page);
@@ -1774,6 +1805,7 @@
 				    b_assoc_buffers) {
 			clear_buffer_async_write(bh);
 			if (bh == segbuf->sb_super_root) {
+				clear_buffer_uptodate(bh);
 				if (bh->b_page != bd_page) {
 					end_page_writeback(bd_page);
 					bd_page = bh->b_page;
@@ -2023,6 +2055,9 @@
 {
 	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
 	int err;
+
+	if (sb_rdonly(sci->sc_super))
+		return -EROFS;
 
 	nilfs_sc_cstage_set(sci, NILFS_ST_INIT);
 	sci->sc_cno = nilfs->ns_cno;
@@ -2614,11 +2649,10 @@
 	goto loop;
 
  end_thread:
-	spin_unlock(&sci->sc_state_lock);
-
 	/* end sync. */
 	sci->sc_task = NULL;
 	wake_up(&sci->sc_wait_task); /* for nilfs_segctor_kill_thread() */
+	spin_unlock(&sci->sc_state_lock);
 	return 0;
 }
 
@@ -2710,7 +2744,7 @@
 
 		flush_work(&sci->sc_iput_work);
 
-	} while (ret && retrycount-- > 0);
+	} while (ret && ret != -EROFS && retrycount-- > 0);
 }
 
 /**
@@ -2821,6 +2855,7 @@
 		nilfs_segctor_destroy(nilfs->ns_writer);
 		nilfs->ns_writer = NULL;
 	}
+	set_nilfs_purging(nilfs);
 
 	/* Force to free the list of dirty files */
 	spin_lock(&nilfs->ns_inode_lock);
@@ -2833,4 +2868,5 @@
 	up_write(&nilfs->ns_segctor_sem);
 
 	nilfs_dispose_list(nilfs, &garbage_list, 1);
+	clear_nilfs_purging(nilfs);
 }
diff --git a/kernel/fs/nilfs2/sufile.c b/kernel/fs/nilfs2/sufile.c
index 51f4cb0..b3abe69 100644
--- a/kernel/fs/nilfs2/sufile.c
+++ b/kernel/fs/nilfs2/sufile.c
@@ -779,6 +779,15 @@
 			goto out_header;
 
 		sui->ncleansegs -= nsegs - newnsegs;
+
+		/*
+		 * If the sufile is successfully truncated, immediately adjust
+		 * the segment allocation space while locking the semaphore
+		 * "mi_sem" so that nilfs_sufile_alloc() never allocates
+		 * segments in the truncated space.
+		 */
+		sui->allocmax = newnsegs - 1;
+		sui->allocmin = 0;
 	}
 
 	kaddr = kmap_atomic(header_bh->b_page);
diff --git a/kernel/fs/nilfs2/super.c b/kernel/fs/nilfs2/super.c
index b3c094c..4a78cab 100644
--- a/kernel/fs/nilfs2/super.c
+++ b/kernel/fs/nilfs2/super.c
@@ -373,10 +373,31 @@
 		goto out;
 	}
 	nsbp = (void *)nsbh->b_data + offset;
-	memset(nsbp, 0, nilfs->ns_blocksize);
+
+	lock_buffer(nsbh);
+	if (sb2i >= 0) {
+		/*
+		 * The position of the second superblock only changes by 4KiB,
+		 * which is larger than the maximum superblock data size
+		 * (= 1KiB), so there is no need to use memmove() to allow
+		 * overlap between source and destination.
+		 */
+		memcpy(nsbp, nilfs->ns_sbp[sb2i], nilfs->ns_sbsize);
+
+		/*
+		 * Zero fill after copy to avoid overwriting in case of move
+		 * within the same block.
+		 */
+		memset(nsbh->b_data, 0, offset);
+		memset((void *)nsbp + nilfs->ns_sbsize, 0,
+		       nsbh->b_size - offset - nilfs->ns_sbsize);
+	} else {
+		memset(nsbh->b_data, 0, nsbh->b_size);
+	}
+	set_buffer_uptodate(nsbh);
+	unlock_buffer(nsbh);
 
 	if (sb2i >= 0) {
-		memcpy(nsbp, nilfs->ns_sbp[sb2i], nilfs->ns_sbsize);
 		brelse(nilfs->ns_sbh[sb2i]);
 		nilfs->ns_sbh[sb2i] = nsbh;
 		nilfs->ns_sbp[sb2i] = nsbp;
@@ -408,6 +429,15 @@
 	devsize = i_size_read(sb->s_bdev->bd_inode);
 	if (newsize > devsize)
 		goto out;
+
+	/*
+	 * Prevent underflow in second superblock position calculation.
+	 * The exact minimum size check is done in nilfs_sufile_resize().
+	 */
+	if (newsize < 4096) {
+		ret = -ENOSPC;
+		goto out;
+	}
 
 	/*
 	 * Write lock is required to protect some functions depending
@@ -474,6 +504,7 @@
 		up_write(&nilfs->ns_sem);
 	}
 
+	nilfs_sysfs_delete_device_group(nilfs);
 	iput(nilfs->ns_sufile);
 	iput(nilfs->ns_cpfile);
 	iput(nilfs->ns_dat);
@@ -1097,6 +1128,7 @@
 	nilfs_put_root(fsroot);
 
  failed_unload:
+	nilfs_sysfs_delete_device_group(nilfs);
 	iput(nilfs->ns_sufile);
 	iput(nilfs->ns_cpfile);
 	iput(nilfs->ns_dat);
diff --git a/kernel/fs/nilfs2/the_nilfs.c b/kernel/fs/nilfs2/the_nilfs.c
index ce103dd..1566e86 100644
--- a/kernel/fs/nilfs2/the_nilfs.c
+++ b/kernel/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"
@@ -86,7 +87,6 @@
 {
 	might_sleep();
 	if (nilfs_init(nilfs)) {
-		nilfs_sysfs_delete_device_group(nilfs);
 		brelse(nilfs->ns_sbh[0]);
 		brelse(nilfs->ns_sbh[1]);
 	}
@@ -193,6 +193,34 @@
 }
 
 /**
+ * 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
  * @sb: super block isntance used to recover past segment
@@ -245,11 +273,15 @@
 		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;
 		}
 
@@ -271,6 +303,10 @@
 		nilfs_err(sb, "error %d while loading super root", err);
 		goto failed;
 	}
+
+	err = nilfs_sysfs_create_device_group(sb);
+	if (unlikely(err))
+		goto sysfs_error;
 
 	if (valid_fs)
 		goto skip_recovery;
@@ -333,6 +369,9 @@
 	goto failed;
 
  failed_unload:
+	nilfs_sysfs_delete_device_group(nilfs);
+
+ sysfs_error:
 	iput(nilfs->ns_cpfile);
 	iput(nilfs->ns_sufile);
 	iput(nilfs->ns_dat);
@@ -366,6 +405,18 @@
 				  100));
 }
 
+/**
+ * nilfs_max_segment_count - calculate the maximum number of segments
+ * @nilfs: nilfs object
+ */
+static u64 nilfs_max_segment_count(struct the_nilfs *nilfs)
+{
+	u64 max_count = U64_MAX;
+
+	do_div(max_count, nilfs->ns_blocks_per_segment);
+	return min_t(u64, max_count, ULONG_MAX);
+}
+
 void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs)
 {
 	nilfs->ns_nsegments = nsegs;
@@ -375,6 +426,8 @@
 static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
 				   struct nilfs_super_block *sbp)
 {
+	u64 nsegments, nblocks;
+
 	if (le32_to_cpu(sbp->s_rev_level) < NILFS_MIN_SUPP_REV) {
 		nilfs_err(nilfs->ns_sb,
 			  "unsupported revision (superblock rev.=%d.%d, current rev.=%d.%d). Please check the version of mkfs.nilfs(2).",
@@ -418,7 +471,35 @@
 		return -EINVAL;
 	}
 
-	nilfs_set_nsegments(nilfs, le64_to_cpu(sbp->s_nsegments));
+	nsegments = le64_to_cpu(sbp->s_nsegments);
+	if (nsegments > nilfs_max_segment_count(nilfs)) {
+		nilfs_err(nilfs->ns_sb,
+			  "segment count %llu exceeds upper limit (%llu segments)",
+			  (unsigned long long)nsegments,
+			  (unsigned long long)nilfs_max_segment_count(nilfs));
+		return -EINVAL;
+	}
+
+	nblocks = (u64)i_size_read(nilfs->ns_sb->s_bdev->bd_inode) >>
+		nilfs->ns_sb->s_blocksize_bits;
+	if (nblocks) {
+		u64 min_block_count = nsegments * nilfs->ns_blocks_per_segment;
+		/*
+		 * To avoid failing to mount early device images without a
+		 * second superblock, exclude that block count from the
+		 * "min_block_count" calculation.
+		 */
+
+		if (nblocks < min_block_count) {
+			nilfs_err(nilfs->ns_sb,
+				  "total number of segment blocks %llu exceeds device size (%llu blocks)",
+				  (unsigned long long)min_block_count,
+				  (unsigned long long)nblocks);
+			return -EINVAL;
+		}
+	}
+
+	nilfs_set_nsegments(nilfs, nsegments);
 	nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed);
 	return 0;
 }
@@ -443,11 +524,33 @@
 	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)
@@ -489,8 +592,14 @@
 {
 	struct nilfs_super_block **sbp = nilfs->ns_sbp;
 	struct buffer_head **sbh = nilfs->ns_sbh;
-	u64 sb2off = NILFS_SB2_OFFSET_BYTES(nilfs->ns_bdev->bd_inode->i_size);
+	u64 sb2off, devsize = nilfs->ns_bdev->bd_inode->i_size;
 	int valid[2], swp = 0;
+
+	if (devsize < NILFS_SEG_MIN_BLOCKS * NILFS_MIN_BLOCK_SIZE + 4096) {
+		nilfs_err(sb, "device size too small");
+		return -EINVAL;
+	}
+	sb2off = NILFS_SB2_OFFSET_BYTES(devsize);
 
 	sbp[0] = nilfs_read_super_block(sb, NILFS_SB_OFFSET_BYTES, blocksize,
 					&sbh[0]);
@@ -586,9 +695,11 @@
 	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);
@@ -631,10 +742,6 @@
 	nilfs->ns_mount_state = le16_to_cpu(sbp->s_state);
 
 	err = nilfs_store_log_cursor(nilfs, sbp);
-	if (err)
-		goto failed_sbh;
-
-	err = nilfs_sysfs_create_device_group(sb);
 	if (err)
 		goto failed_sbh;
 
diff --git a/kernel/fs/nilfs2/the_nilfs.h b/kernel/fs/nilfs2/the_nilfs.h
index b55cdeb..0191408 100644
--- a/kernel/fs/nilfs2/the_nilfs.h
+++ b/kernel/fs/nilfs2/the_nilfs.h
@@ -29,6 +29,7 @@
 	THE_NILFS_DISCONTINUED,	/* 'next' pointer chain has broken */
 	THE_NILFS_GC_RUNNING,	/* gc process is running */
 	THE_NILFS_SB_DIRTY,	/* super block is dirty */
+	THE_NILFS_PURGING,	/* disposing dirty files for cleanup */
 };
 
 /**
@@ -208,6 +209,7 @@
 THE_NILFS_FNS(DISCONTINUED, discontinued)
 THE_NILFS_FNS(GC_RUNNING, gc_running)
 THE_NILFS_FNS(SB_DIRTY, sb_dirty)
+THE_NILFS_FNS(PURGING, purging)
 
 /*
  * Mount option operations
diff --git a/kernel/fs/notify/fanotify/fanotify_user.c b/kernel/fs/notify/fanotify/fanotify_user.c
index 18e014f..84de9f9 100644
--- a/kernel/fs/notify/fanotify/fanotify_user.c
+++ b/kernel/fs/notify/fanotify/fanotify_user.c
@@ -1090,8 +1090,11 @@
 	return 0;
 }
 
-static int fanotify_events_supported(struct path *path, __u64 mask)
+static int fanotify_events_supported(struct path *path, __u64 mask,
+				     unsigned int flags)
 {
+	unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS;
+
 	/*
 	 * Some filesystems such as 'proc' acquire unusual locks when opening
 	 * files. For them fanotify permission events have high chances of
@@ -1103,6 +1106,21 @@
 	if (mask & FANOTIFY_PERM_EVENTS &&
 	    path->mnt->mnt_sb->s_type->fs_flags & FS_DISALLOW_NOTIFY_PERM)
 		return -EINVAL;
+
+	/*
+	 * mount and sb marks are not allowed on kernel internal pseudo fs,
+	 * like pipe_mnt, because that would subscribe to events on all the
+	 * anonynous pipes in the system.
+	 *
+	 * SB_NOUSER covers all of the internal pseudo fs whose objects are not
+	 * exposed to user's mount namespace, but there are other SB_KERNMOUNT
+	 * fs, like nsfs, debugfs, for which the value of allowing sb and mount
+	 * mark is questionable. For now we leave them alone.
+	 */
+	if (mark_type != FAN_MARK_INODE &&
+	    path->mnt->mnt_sb->s_flags & SB_NOUSER)
+		return -EINVAL;
+
 	return 0;
 }
 
@@ -1218,7 +1236,7 @@
 		goto fput_and_out;
 
 	if (flags & FAN_MARK_ADD) {
-		ret = fanotify_events_supported(&path, mask);
+		ret = fanotify_events_supported(&path, mask, flags);
 		if (ret)
 			goto path_put_and_out;
 	}
diff --git a/kernel/fs/notify/inotify/inotify_fsnotify.c b/kernel/fs/notify/inotify/inotify_fsnotify.c
index 1901d79..66991c7 100644
--- a/kernel/fs/notify/inotify/inotify_fsnotify.c
+++ b/kernel/fs/notify/inotify/inotify_fsnotify.c
@@ -64,7 +64,7 @@
 	struct fsnotify_event *fsn_event;
 	struct fsnotify_group *group = inode_mark->group;
 	int ret;
-	int len = 0;
+	int len = 0, wd;
 	int alloc_len = sizeof(struct inotify_event_info);
 	struct mem_cgroup *old_memcg;
 
@@ -79,6 +79,13 @@
 	i_mark = container_of(inode_mark, struct inotify_inode_mark,
 			      fsn_mark);
 
+	/*
+	 * We can be racing with mark being detached. Don't report event with
+	 * invalid wd.
+	 */
+	wd = READ_ONCE(i_mark->wd);
+	if (wd == -1)
+		return 0;
 	/*
 	 * Whoever is interested in the event, pays for the allocation. Do not
 	 * trigger OOM killer in the target monitoring memcg as it may have
@@ -109,7 +116,7 @@
 	fsn_event = &event->fse;
 	fsnotify_init_event(fsn_event, 0);
 	event->mask = mask;
-	event->wd = i_mark->wd;
+	event->wd = wd;
 	event->sync_cookie = cookie;
 	event->name_len = len;
 	if (len)
diff --git a/kernel/fs/ocfs2/aops.c b/kernel/fs/ocfs2/aops.c
index ad20403..9b23e74 100644
--- a/kernel/fs/ocfs2/aops.c
+++ b/kernel/fs/ocfs2/aops.c
@@ -1981,11 +1981,25 @@
 	}
 
 	if (unlikely(copied < len) && wc->w_target_page) {
+		loff_t new_isize;
+
 		if (!PageUptodate(wc->w_target_page))
 			copied = 0;
 
-		ocfs2_zero_new_buffers(wc->w_target_page, start+copied,
-				       start+len);
+		new_isize = max_t(loff_t, i_size_read(inode), pos + copied);
+		if (new_isize > page_offset(wc->w_target_page))
+			ocfs2_zero_new_buffers(wc->w_target_page, start+copied,
+					       start+len);
+		else {
+			/*
+			 * When page is fully beyond new isize (data copy
+			 * failed), do not bother zeroing the page. Invalidate
+			 * it instead so that writeback does not get confused
+			 * put page & buffer dirty bits into inconsistent
+			 * state.
+			 */
+			block_invalidatepage(wc->w_target_page, 0, PAGE_SIZE);
+		}
 	}
 	if (wc->w_target_page)
 		flush_dcache_page(wc->w_target_page);
diff --git a/kernel/fs/ocfs2/dlmglue.c b/kernel/fs/ocfs2/dlmglue.c
index 3e06e9a..4246569 100644
--- a/kernel/fs/ocfs2/dlmglue.c
+++ b/kernel/fs/ocfs2/dlmglue.c
@@ -3396,10 +3396,12 @@
 	ocfs2_lock_res_free(&osb->osb_nfs_sync_lockres);
 	ocfs2_lock_res_free(&osb->osb_orphan_scan.os_lockres);
 
-	ocfs2_cluster_disconnect(osb->cconn, hangup_pending);
-	osb->cconn = NULL;
+	if (osb->cconn) {
+		ocfs2_cluster_disconnect(osb->cconn, hangup_pending);
+		osb->cconn = NULL;
 
-	ocfs2_dlm_shutdown_debug(osb);
+		ocfs2_dlm_shutdown_debug(osb);
+	}
 }
 
 static int ocfs2_drop_lock(struct ocfs2_super *osb,
diff --git a/kernel/fs/ocfs2/file.c b/kernel/fs/ocfs2/file.c
index 1470b49..df36d84 100644
--- a/kernel/fs/ocfs2/file.c
+++ b/kernel/fs/ocfs2/file.c
@@ -1994,7 +1994,7 @@
 		}
 	}
 
-	if (file && should_remove_suid(file->f_path.dentry)) {
+	if (file && setattr_should_drop_suidgid(file_inode(file))) {
 		ret = __ocfs2_write_remove_suid(inode, di_bh);
 		if (ret) {
 			mlog_errno(ret);
@@ -2103,14 +2103,20 @@
 	struct ocfs2_space_resv sr;
 	int change_size = 1;
 	int cmd = OCFS2_IOC_RESVSP64;
+	int ret = 0;
 
 	if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
 		return -EOPNOTSUPP;
 	if (!ocfs2_writes_unwritten_extents(osb))
 		return -EOPNOTSUPP;
 
-	if (mode & FALLOC_FL_KEEP_SIZE)
+	if (mode & FALLOC_FL_KEEP_SIZE) {
 		change_size = 0;
+	} else {
+		ret = inode_newsize_ok(inode, offset + len);
+		if (ret)
+			return ret;
+	}
 
 	if (mode & FALLOC_FL_PUNCH_HOLE)
 		cmd = OCFS2_IOC_UNRESVSP64;
@@ -2282,7 +2288,7 @@
 		 * inode. There's also the dinode i_size state which
 		 * can be lost via setattr during extending writes (we
 		 * set inode->i_size at the end of a write. */
-		if (should_remove_suid(dentry)) {
+		if (setattr_should_drop_suidgid(inode)) {
 			if (meta_level == 0) {
 				ocfs2_inode_unlock_for_extent_tree(inode,
 								   &di_bh,
diff --git a/kernel/fs/ocfs2/journal.c b/kernel/fs/ocfs2/journal.c
index db52e84..0534800 100644
--- a/kernel/fs/ocfs2/journal.c
+++ b/kernel/fs/ocfs2/journal.c
@@ -159,7 +159,7 @@
 	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/kernel/fs/ocfs2/journal.h b/kernel/fs/ocfs2/journal.h
index bfe611e..eb7a21b 100644
--- a/kernel/fs/ocfs2/journal.h
+++ b/kernel/fs/ocfs2/journal.h
@@ -152,6 +152,7 @@
 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/kernel/fs/ocfs2/move_extents.c b/kernel/fs/ocfs2/move_extents.c
index 758d966..98e77ea 100644
--- a/kernel/fs/ocfs2/move_extents.c
+++ b/kernel/fs/ocfs2/move_extents.c
@@ -107,14 +107,6 @@
 	 */
 	replace_rec.e_flags = ext_flags & ~OCFS2_EXT_REFCOUNTED;
 
-	ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode),
-				      context->et.et_root_bh,
-				      OCFS2_JOURNAL_ACCESS_WRITE);
-	if (ret) {
-		mlog_errno(ret);
-		goto out;
-	}
-
 	ret = ocfs2_split_extent(handle, &context->et, path, index,
 				 &replace_rec, context->meta_ac,
 				 &context->dealloc);
@@ -122,8 +114,6 @@
 		mlog_errno(ret);
 		goto out;
 	}
-
-	ocfs2_journal_dirty(handle, context->et.et_root_bh);
 
 	context->new_phys_cpos = new_p_cpos;
 
@@ -446,7 +436,7 @@
 			bg = (struct ocfs2_group_desc *)gd_bh->b_data;
 
 			if (vict_blkno < (le64_to_cpu(bg->bg_blkno) +
-						le16_to_cpu(bg->bg_bits))) {
+						(le16_to_cpu(bg->bg_bits) << bits_per_unit))) {
 
 				*ret_bh = gd_bh;
 				*vict_bit = (vict_blkno - blkno) >>
@@ -561,6 +551,7 @@
 			last_free_bits++;
 
 		if (last_free_bits == move_len) {
+			i -= move_len;
 			*goal_bit = i;
 			*phys_cpos = base_cpos + i;
 			break;
@@ -1032,18 +1023,19 @@
 
 	context->range = &range;
 
+	/*
+	 * ok, the default theshold for the defragmentation
+	 * is 1M, since our maximum clustersize was 1M also.
+	 * any thought?
+	 */
+	if (!range.me_threshold)
+		range.me_threshold = 1024 * 1024;
+
+	if (range.me_threshold > i_size_read(inode))
+		range.me_threshold = i_size_read(inode);
+
 	if (range.me_flags & OCFS2_MOVE_EXT_FL_AUTO_DEFRAG) {
 		context->auto_defrag = 1;
-		/*
-		 * ok, the default theshold for the defragmentation
-		 * is 1M, since our maximum clustersize was 1M also.
-		 * any thought?
-		 */
-		if (!range.me_threshold)
-			range.me_threshold = 1024 * 1024;
-
-		if (range.me_threshold > i_size_read(inode))
-			range.me_threshold = i_size_read(inode);
 
 		if (range.me_flags & OCFS2_MOVE_EXT_FL_PART_DEFRAG)
 			context->partial = 1;
diff --git a/kernel/fs/ocfs2/namei.c b/kernel/fs/ocfs2/namei.c
index 856474b..5c98813 100644
--- a/kernel/fs/ocfs2/namei.c
+++ b/kernel/fs/ocfs2/namei.c
@@ -198,6 +198,7 @@
 	 * callers. */
 	if (S_ISDIR(mode))
 		set_nlink(inode, 2);
+	mode = mode_strip_sgid(dir, mode);
 	inode_init_owner(inode, dir, mode);
 	status = dquot_initialize(inode);
 	if (status)
@@ -241,6 +242,7 @@
 	int want_meta = 0;
 	int xattr_credits = 0;
 	struct ocfs2_security_xattr_info si = {
+		.name = NULL,
 		.enable = 1,
 	};
 	int did_quota_inode = 0;
@@ -1530,6 +1532,10 @@
 		status = ocfs2_add_entry(handle, new_dentry, old_inode,
 					 OCFS2_I(old_inode)->ip_blkno,
 					 new_dir_bh, &target_insert);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
 	}
 
 	old_inode->i_ctime = current_time(old_inode);
@@ -1800,6 +1806,7 @@
 	int want_clusters = 0;
 	int xattr_credits = 0;
 	struct ocfs2_security_xattr_info si = {
+		.name = NULL,
 		.enable = 1,
 	};
 	int did_quota = 0, did_quota_inode = 0;
diff --git a/kernel/fs/ocfs2/stackglue.c b/kernel/fs/ocfs2/stackglue.c
index 03eacb2..5e272e2 100644
--- a/kernel/fs/ocfs2/stackglue.c
+++ b/kernel/fs/ocfs2/stackglue.c
@@ -705,6 +705,8 @@
 
 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 @@
 		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)
diff --git a/kernel/fs/ocfs2/super.c b/kernel/fs/ocfs2/super.c
index 9eff7ff..111ae7a 100644
--- a/kernel/fs/ocfs2/super.c
+++ b/kernel/fs/ocfs2/super.c
@@ -956,8 +956,10 @@
 	for (type = 0; type < OCFS2_MAXQUOTAS; type++) {
 		if (!sb_has_quota_loaded(sb, type))
 			continue;
-		oinfo = sb_dqinfo(sb, type)->dqi_priv;
-		cancel_delayed_work_sync(&oinfo->dqi_sync_work);
+		if (!sb_has_quota_suspended(sb, type)) {
+			oinfo = sb_dqinfo(sb, type)->dqi_priv;
+			cancel_delayed_work_sync(&oinfo->dqi_sync_work);
+		}
 		inode = igrab(sb->s_dquot.files[type]);
 		/* Turn off quotas. This will remove all dquot structures from
 		 * memory and so they will be automatically synced to global
@@ -985,28 +987,27 @@
 
 	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;
@@ -1023,7 +1024,7 @@
 
 	status = ocfs2_verify_userspace_stack(osb, &parsed_options);
 	if (status)
-		goto read_super_error;
+		goto out_super;
 
 	sb->s_magic = OCFS2_SUPER_MAGIC;
 
@@ -1037,7 +1038,7 @@
 			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
@@ -1046,7 +1047,7 @@
 			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);
@@ -1055,9 +1056,7 @@
 				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);
@@ -1073,10 +1072,8 @@
 	}
 
 	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);
@@ -1090,15 +1087,14 @@
 
 	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,
@@ -1106,7 +1102,7 @@
 	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
@@ -1115,14 +1111,13 @@
 		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;
@@ -1169,17 +1164,22 @@
 
 	return status;
 
-read_super_error:
-	brelse(bh);
+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;
 
-	if (status)
-		mlog_errno(status);
-
-	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;
 }
@@ -1788,11 +1788,10 @@
 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);
 
@@ -1802,44 +1801,58 @@
 		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_check_volume;
+	}
 
-leave:
-	if (unlock_super)
-		ocfs2_super_unlock(osb, 1);
+	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);
+	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;
 }
 
@@ -1912,8 +1925,7 @@
 	    !ocfs2_is_hard_readonly(osb))
 		hangup_needed = 1;
 
-	if (osb->cconn)
-		ocfs2_dlm_shutdown(osb, hangup_needed);
+	ocfs2_dlm_shutdown(osb, hangup_needed);
 
 	ocfs2_blockcheck_stats_debugfs_remove(&osb->osb_ecc_stats);
 	debugfs_remove_recursive(osb->osb_debug_root);
diff --git a/kernel/fs/ocfs2/xattr.c b/kernel/fs/ocfs2/xattr.c
index 0ed0a61..8b7df5e 100644
--- a/kernel/fs/ocfs2/xattr.c
+++ b/kernel/fs/ocfs2/xattr.c
@@ -7261,8 +7261,20 @@
 static int ocfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
 		     void *fs_info)
 {
+	struct ocfs2_security_xattr_info *si = fs_info;
 	const struct xattr *xattr;
 	int err = 0;
+
+	if (si) {
+		si->value = kmemdup(xattr_array->value, xattr_array->value_len,
+				    GFP_KERNEL);
+		if (!si->value)
+			return -ENOMEM;
+
+		si->name = xattr_array->name;
+		si->value_len = xattr_array->value_len;
+		return 0;
+	}
 
 	for (xattr = xattr_array; xattr->name != NULL; xattr++) {
 		err = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
@@ -7279,13 +7291,23 @@
 			    const struct qstr *qstr,
 			    struct ocfs2_security_xattr_info *si)
 {
+	int ret;
+
 	/* check whether ocfs2 support feature xattr */
 	if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb)))
 		return -EOPNOTSUPP;
-	if (si)
-		return security_old_inode_init_security(inode, dir, qstr,
-							&si->name, &si->value,
-							&si->value_len);
+	if (si) {
+		ret = security_inode_init_security(inode, dir, qstr,
+						   &ocfs2_initxattrs, si);
+		/*
+		 * security_inode_init_security() does not return -EOPNOTSUPP,
+		 * we have to check the xattr ourselves.
+		 */
+		if (!ret && !si->name)
+			si->enable = 0;
+
+		return ret;
+	}
 
 	return security_inode_init_security(inode, dir, qstr,
 					    &ocfs2_initxattrs, NULL);
diff --git a/kernel/fs/open.c b/kernel/fs/open.c
index 93e8557..965230a 100644
--- a/kernel/fs/open.c
+++ b/kernel/fs/open.c
@@ -666,10 +666,10 @@
 		newattrs.ia_valid |= ATTR_GID;
 		newattrs.ia_gid = gid;
 	}
-	if (!S_ISDIR(inode->i_mode))
-		newattrs.ia_valid |=
-			ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
 	inode_lock(inode);
+	if (!S_ISDIR(inode->i_mode))
+		newattrs.ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV |
+				     setattr_should_drop_sgid(inode);
 	error = security_path_chown(path, uid, gid);
 	if (!error)
 		error = notify_change(path->dentry, &newattrs, &delegated_inode);
@@ -1112,7 +1112,7 @@
 		lookup_flags |= LOOKUP_IN_ROOT;
 	if (how->resolve & RESOLVE_CACHED) {
 		/* Don't bother even trying for create/truncate/tmpfile open */
-		if (flags & (O_TRUNC | O_CREAT | O_TMPFILE))
+		if (flags & (O_TRUNC | O_CREAT | __O_TMPFILE))
 			return -EAGAIN;
 		lookup_flags |= LOOKUP_CACHED;
 	}
diff --git a/kernel/fs/orangefs/orangefs-debugfs.c b/kernel/fs/orangefs/orangefs-debugfs.c
index 29eaa45..1b508f5 100644
--- a/kernel/fs/orangefs/orangefs-debugfs.c
+++ b/kernel/fs/orangefs/orangefs-debugfs.c
@@ -194,14 +194,9 @@
  */
 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);
@@ -213,15 +208,14 @@
 
 	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);
 }
 
 
 void orangefs_debugfs_cleanup(void)
 {
 	debugfs_remove_recursive(debug_dir);
+	kfree(debug_help_string);
+	debug_help_string = NULL;
 }
 
 /* open ORANGEFS_KMOD_DEBUG_HELP_FILE */
@@ -297,17 +291,12 @@
 /*
  * 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);
@@ -322,13 +311,6 @@
 						  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.*/
@@ -671,6 +653,7 @@
 		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;
diff --git a/kernel/fs/orangefs/orangefs-mod.c b/kernel/fs/orangefs/orangefs-mod.c
index a76a6ba..968bf33 100644
--- a/kernel/fs/orangefs/orangefs-mod.c
+++ b/kernel/fs/orangefs/orangefs-mod.c
@@ -142,7 +142,7 @@
 		gossip_err("%s: could not initialize device subsystem %d!\n",
 			   __func__,
 			   ret);
-		goto cleanup_device;
+		goto cleanup_sysfs;
 	}
 
 	ret = register_filesystem(&orangefs_fs_type);
@@ -153,11 +153,11 @@
 		goto out;
 	}
 
-	orangefs_sysfs_exit();
-
-cleanup_device:
 	orangefs_dev_cleanup();
 
+cleanup_sysfs:
+	orangefs_sysfs_exit();
+
 sysfs_init_failed:
 	orangefs_debugfs_cleanup();
 
diff --git a/kernel/fs/overlayfs/copy_up.c b/kernel/fs/overlayfs/copy_up.c
index 820addb..84f5596 100644
--- a/kernel/fs/overlayfs/copy_up.c
+++ b/kernel/fs/overlayfs/copy_up.c
@@ -475,6 +475,7 @@
 			/* Restore timestamps on parent (best effort) */
 			ovl_set_timestamps(upperdir, &c->pstat);
 			ovl_dentry_set_upper_alias(c->dentry);
+			ovl_dentry_update_reval(c->dentry, upper);
 		}
 	}
 	inode_unlock(udir);
@@ -762,6 +763,7 @@
 		inode_unlock(udir);
 
 		ovl_dentry_set_upper_alias(c->dentry);
+		ovl_dentry_update_reval(c->dentry, ovl_dentry_upper(c->dentry));
 	}
 
 out:
diff --git a/kernel/fs/overlayfs/dir.c b/kernel/fs/overlayfs/dir.c
index c3bc1c7..82e8ab2 100644
--- a/kernel/fs/overlayfs/dir.c
+++ b/kernel/fs/overlayfs/dir.c
@@ -266,8 +266,7 @@
 
 	ovl_dir_modified(dentry->d_parent, false);
 	ovl_dentry_set_upper_alias(dentry);
-	ovl_dentry_update_reval(dentry, newdentry,
-			DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
+	ovl_dentry_init_reval(dentry, newdentry);
 
 	if (!hardlink) {
 		/*
@@ -586,29 +585,43 @@
 			goto out_revert_creds;
 	}
 
-	err = -ENOMEM;
-	override_cred = prepare_creds();
-	if (override_cred) {
+	if (!attr->hardlink) {
+		err = -ENOMEM;
+		override_cred = prepare_creds();
+		if (!override_cred)
+			goto out_revert_creds;
+		/*
+		 * In the creation cases(create, mkdir, mknod, symlink),
+		 * ovl should transfer current's fs{u,g}id to underlying
+		 * fs. Because underlying fs want to initialize its new
+		 * inode owner using current's fs{u,g}id. And in this
+		 * case, the @inode is a new inode that is initialized
+		 * in inode_init_owner() to current's fs{u,g}id. So use
+		 * the inode's i_{u,g}id to override the cred's fs{u,g}id.
+		 *
+		 * But in the other hardlink case, ovl_link() does not
+		 * create a new inode, so just use the ovl mounter's
+		 * fs{u,g}id.
+		 */
 		override_cred->fsuid = inode->i_uid;
 		override_cred->fsgid = inode->i_gid;
-		if (!attr->hardlink) {
-			err = security_dentry_create_files_as(dentry,
-					attr->mode, &dentry->d_name,
-					old_cred ? old_cred : current_cred(),
-					override_cred);
-			if (err) {
-				put_cred(override_cred);
-				goto out_revert_creds;
-			}
+		err = security_dentry_create_files_as(dentry,
+				attr->mode, &dentry->d_name,
+				old_cred ? old_cred : current_cred(),
+				override_cred);
+		if (err) {
+			put_cred(override_cred);
+			goto out_revert_creds;
 		}
 		hold_cred = override_creds(override_cred);
 		put_cred(override_cred);
-
-		if (!ovl_dentry_is_whiteout(dentry))
-			err = ovl_create_upper(dentry, inode, attr);
-		else
-			err = ovl_create_over_whiteout(dentry, inode, attr);
 	}
+
+	if (!ovl_dentry_is_whiteout(dentry))
+		err = ovl_create_upper(dentry, inode, attr);
+	else
+		err = ovl_create_over_whiteout(dentry, inode, attr);
+
 out_revert_creds:
 	ovl_revert_creds(dentry->d_sb, old_cred ?: hold_cred);
 	if (old_cred && hold_cred)
diff --git a/kernel/fs/overlayfs/export.c b/kernel/fs/overlayfs/export.c
index 44118f0..f981283 100644
--- a/kernel/fs/overlayfs/export.c
+++ b/kernel/fs/overlayfs/export.c
@@ -324,8 +324,7 @@
 	if (upper_alias)
 		ovl_dentry_set_upper_alias(dentry);
 
-	ovl_dentry_update_reval(dentry, upper,
-			DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
+	ovl_dentry_init_reval(dentry, upper);
 
 	return d_instantiate_anon(dentry, inode);
 
diff --git a/kernel/fs/overlayfs/file.c b/kernel/fs/overlayfs/file.c
index 719eec7..c5760b5 100644
--- a/kernel/fs/overlayfs/file.c
+++ b/kernel/fs/overlayfs/file.c
@@ -21,7 +21,6 @@
 	struct kiocb iocb;
 	refcount_t ref;
 	struct kiocb *orig_iocb;
-	struct fd fd;
 };
 
 static struct kmem_cache *ovl_aio_request_cachep;
@@ -247,7 +246,7 @@
 static inline void ovl_aio_put(struct ovl_aio_req *aio_req)
 {
 	if (refcount_dec_and_test(&aio_req->ref)) {
-		fdput(aio_req->fd);
+		fput(aio_req->iocb.ki_filp);
 		kmem_cache_free(ovl_aio_request_cachep, aio_req);
 	}
 }
@@ -314,10 +313,9 @@
 		if (!aio_req)
 			goto out;
 
-		aio_req->fd = real;
 		real.flags = 0;
 		aio_req->orig_iocb = iocb;
-		kiocb_clone(&aio_req->iocb, iocb, real.file);
+		kiocb_clone(&aio_req->iocb, iocb, get_file(real.file));
 		aio_req->iocb.ki_complete = ovl_aio_rw_complete;
 		refcount_set(&aio_req->ref, 2);
 		ret = vfs_iocb_iter_read(real.file, &aio_req->iocb, iter);
@@ -387,10 +385,9 @@
 		/* Pacify lockdep, same trick as done in aio_write() */
 		__sb_writers_release(file_inode(real.file)->i_sb,
 				     SB_FREEZE_WRITE);
-		aio_req->fd = real;
 		real.flags = 0;
 		aio_req->orig_iocb = iocb;
-		kiocb_clone(&aio_req->iocb, iocb, real.file);
+		kiocb_clone(&aio_req->iocb, iocb, get_file(real.file));
 		aio_req->iocb.ki_flags = ifl;
 		aio_req->iocb.ki_complete = ovl_aio_rw_complete;
 		refcount_set(&aio_req->ref, 2);
@@ -519,9 +516,16 @@
 	const struct cred *old_cred;
 	int ret;
 
+	inode_lock(inode);
+	/* Update mode */
+	ovl_copyattr(ovl_inode_real(inode), inode);
+	ret = file_remove_privs(file);
+	if (ret)
+		goto out_unlock;
+
 	ret = ovl_real_fdget(file, &real);
 	if (ret)
-		return ret;
+		goto out_unlock;
 
 	old_cred = ovl_override_creds(file_inode(file)->i_sb);
 	ret = vfs_fallocate(real.file, mode, offset, len);
@@ -531,6 +535,9 @@
 	ovl_copyattr(ovl_inode_real(inode), inode);
 
 	fdput(real);
+
+out_unlock:
+	inode_unlock(inode);
 
 	return ret;
 }
@@ -675,14 +682,23 @@
 	const struct cred *old_cred;
 	loff_t ret;
 
+	inode_lock(inode_out);
+	if (op != OVL_DEDUPE) {
+		/* Update mode */
+		ovl_copyattr(ovl_inode_real(inode_out), inode_out);
+		ret = file_remove_privs(file_out);
+		if (ret)
+			goto out_unlock;
+	}
+
 	ret = ovl_real_fdget(file_out, &real_out);
 	if (ret)
-		return ret;
+		goto out_unlock;
 
 	ret = ovl_real_fdget(file_in, &real_in);
 	if (ret) {
 		fdput(real_out);
-		return ret;
+		goto out_unlock;
 	}
 
 	old_cred = ovl_override_creds(file_inode(file_out)->i_sb);
@@ -711,6 +727,9 @@
 	fdput(real_in);
 	fdput(real_out);
 
+out_unlock:
+	inode_unlock(inode_out);
+
 	return ret;
 }
 
diff --git a/kernel/fs/overlayfs/namei.c b/kernel/fs/overlayfs/namei.c
index 30e0ee7..555781e 100644
--- a/kernel/fs/overlayfs/namei.c
+++ b/kernel/fs/overlayfs/namei.c
@@ -1096,8 +1096,7 @@
 			ovl_set_flag(OVL_UPPERDATA, inode);
 	}
 
-	ovl_dentry_update_reval(dentry, upperdentry,
-			DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
+	ovl_dentry_init_reval(dentry, upperdentry);
 
 	ovl_revert_creds(dentry->d_sb, old_cred);
 	if (origin_path) {
diff --git a/kernel/fs/overlayfs/overlayfs.h b/kernel/fs/overlayfs/overlayfs.h
index 6cd8eb7..a9f9923 100644
--- a/kernel/fs/overlayfs/overlayfs.h
+++ b/kernel/fs/overlayfs/overlayfs.h
@@ -260,8 +260,10 @@
 bool ovl_verify_lower(struct super_block *sb);
 struct ovl_entry *ovl_alloc_entry(unsigned int numlower);
 bool ovl_dentry_remote(struct dentry *dentry);
-void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *upperdentry,
-			     unsigned int mask);
+void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *realdentry);
+void ovl_dentry_init_reval(struct dentry *dentry, struct dentry *upperdentry);
+void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry,
+			   unsigned int mask);
 bool ovl_dentry_weird(struct dentry *dentry);
 enum ovl_path_type ovl_path_type(struct dentry *dentry);
 void ovl_path_upper(struct dentry *dentry, struct path *path);
diff --git a/kernel/fs/overlayfs/ovl_entry.h b/kernel/fs/overlayfs/ovl_entry.h
index 200efb3..c5d9a02 100644
--- a/kernel/fs/overlayfs/ovl_entry.h
+++ b/kernel/fs/overlayfs/ovl_entry.h
@@ -31,6 +31,7 @@
 };
 
 struct ovl_layer {
+	/* ovl_free_fs() relies on @mnt being the first member! */
 	struct vfsmount *mnt;
 	/* Trap in ovl inode cache */
 	struct inode *trap;
@@ -41,6 +42,14 @@
 	int fsid;
 };
 
+/*
+ * ovl_free_fs() relies on @mnt being the first member when unmounting
+ * the private mounts created for each layer. Let's check both the
+ * offset and type.
+ */
+static_assert(offsetof(struct ovl_layer, mnt) == 0);
+static_assert(__same_type(typeof_member(struct ovl_layer, mnt), struct vfsmount *));
+
 struct ovl_path {
 	const struct ovl_layer *layer;
 	struct dentry *dentry;
diff --git a/kernel/fs/overlayfs/super.c b/kernel/fs/overlayfs/super.c
index 4a2ce2e..70a20ac 100644
--- a/kernel/fs/overlayfs/super.c
+++ b/kernel/fs/overlayfs/super.c
@@ -144,11 +144,16 @@
 					unsigned int flags, bool weak)
 {
 	struct ovl_entry *oe = dentry->d_fsdata;
+	struct inode *inode = d_inode_rcu(dentry);
 	struct dentry *upper;
 	unsigned int i;
 	int ret = 1;
 
-	upper = ovl_dentry_upper(dentry);
+	/* Careful in RCU mode */
+	if (!inode)
+		return -ECHILD;
+
+	upper = ovl_i_dentry_upper(inode);
 	if (upper)
 		ret = ovl_revalidate_real(upper, flags, weak);
 
@@ -1887,7 +1892,7 @@
 	ovl_dentry_set_flag(OVL_E_CONNECTED, root);
 	ovl_set_upperdata(d_inode(root));
 	ovl_inode_init(d_inode(root), &oip, ino, fsid);
-	ovl_dentry_update_reval(root, upperdentry, DCACHE_OP_WEAK_REVALIDATE);
+	ovl_dentry_init_flags(root, upperdentry, DCACHE_OP_WEAK_REVALIDATE);
 
 	return root;
 }
@@ -2047,7 +2052,7 @@
 	sb->s_xattr = ovl_xattr_handlers;
 	sb->s_fs_info = ofs;
 	sb->s_flags |= SB_POSIXACL;
-	sb->s_iflags |= SB_I_SKIP_SYNC;
+	sb->s_iflags |= SB_I_SKIP_SYNC | SB_I_IMA_UNVERIFIABLE_SIGNATURE;
 
 	err = -ENOMEM;
 	root_dentry = ovl_get_root(sb, upperpath.dentry, oe);
diff --git a/kernel/fs/overlayfs/util.c b/kernel/fs/overlayfs/util.c
index 5edb177..7eba49d 100644
--- a/kernel/fs/overlayfs/util.c
+++ b/kernel/fs/overlayfs/util.c
@@ -98,14 +98,30 @@
 	return oe;
 }
 
+#define OVL_D_REVALIDATE (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE)
+
 bool ovl_dentry_remote(struct dentry *dentry)
 {
-	return dentry->d_flags &
-		(DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
+	return dentry->d_flags & OVL_D_REVALIDATE;
 }
 
-void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *upperdentry,
-			     unsigned int mask)
+void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *realdentry)
+{
+	if (!ovl_dentry_remote(realdentry))
+		return;
+
+	spin_lock(&dentry->d_lock);
+	dentry->d_flags |= realdentry->d_flags & OVL_D_REVALIDATE;
+	spin_unlock(&dentry->d_lock);
+}
+
+void ovl_dentry_init_reval(struct dentry *dentry, struct dentry *upperdentry)
+{
+	return ovl_dentry_init_flags(dentry, upperdentry, OVL_D_REVALIDATE);
+}
+
+void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry,
+			   unsigned int mask)
 {
 	struct ovl_entry *oe = OVL_E(dentry);
 	unsigned int i, flags = 0;
diff --git a/kernel/fs/pnode.c b/kernel/fs/pnode.c
index 1106137..468e4e6 100644
--- a/kernel/fs/pnode.c
+++ b/kernel/fs/pnode.c
@@ -244,7 +244,7 @@
 		}
 		do {
 			struct mount *parent = last_source->mnt_parent;
-			if (last_source == first_source)
+			if (peers(last_source, first_source))
 				break;
 			done = parent->mnt_master == p;
 			if (done && peers(n, parent))
diff --git a/kernel/fs/proc/base.c b/kernel/fs/proc/base.c
index 6325298..8b1ecb5 100644
--- a/kernel/fs/proc/base.c
+++ b/kernel/fs/proc/base.c
@@ -1882,7 +1882,7 @@
 	put_pid(pid);
 }
 
-struct inode *proc_pid_make_inode(struct super_block * sb,
+struct inode *proc_pid_make_inode(struct super_block *sb,
 				  struct task_struct *task, umode_t mode)
 {
 	struct inode * inode;
@@ -1911,11 +1911,6 @@
 
 	/* Let the pid remember us for quick removal */
 	ei->pid = pid;
-	if (S_ISDIR(mode)) {
-		spin_lock(&pid->lock);
-		hlist_add_head_rcu(&ei->sibling_inodes, &pid->inodes);
-		spin_unlock(&pid->lock);
-	}
 
 	task_dump_owner(task, 0, &inode->i_uid, &inode->i_gid);
 	security_task_to_inode(task, inode);
@@ -1926,6 +1921,39 @@
 out_unlock:
 	iput(inode);
 	return NULL;
+}
+
+/*
+ * Generating an inode and adding it into @pid->inodes, so that task will
+ * invalidate inode's dentry before being released.
+ *
+ * This helper is used for creating dir-type entries under '/proc' and
+ * '/proc/<tgid>/task'. Other entries(eg. fd, stat) under '/proc/<tgid>'
+ * can be released by invalidating '/proc/<tgid>' dentry.
+ * In theory, dentries under '/proc/<tgid>/task' can also be released by
+ * invalidating '/proc/<tgid>' dentry, we reserve it to handle single
+ * thread exiting situation: Any one of threads should invalidate its
+ * '/proc/<tgid>/task/<pid>' dentry before released.
+ */
+static struct inode *proc_pid_make_base_inode(struct super_block *sb,
+				struct task_struct *task, umode_t mode)
+{
+	struct inode *inode;
+	struct proc_inode *ei;
+	struct pid *pid;
+
+	inode = proc_pid_make_inode(sb, task, mode);
+	if (!inode)
+		return NULL;
+
+	/* Let proc_flush_pid find this directory inode */
+	ei = PROC_I(inode);
+	pid = ei->pid;
+	spin_lock(&pid->lock);
+	hlist_add_head_rcu(&ei->sibling_inodes, &pid->inodes);
+	spin_unlock(&pid->lock);
+
+	return inode;
 }
 
 int pid_getattr(const struct path *path, struct kstat *stat,
@@ -3345,7 +3373,8 @@
 {
 	struct inode *inode;
 
-	inode = proc_pid_make_inode(dentry->d_sb, task, S_IFDIR | S_IRUGO | S_IXUGO);
+	inode = proc_pid_make_base_inode(dentry->d_sb, task,
+					 S_IFDIR | S_IRUGO | S_IXUGO);
 	if (!inode)
 		return ERR_PTR(-ENOENT);
 
@@ -3510,7 +3539,8 @@
 }
 
 static const struct inode_operations proc_tid_comm_inode_operations = {
-		.permission = proc_tid_comm_permission,
+		.setattr	= proc_setattr,
+		.permission	= proc_tid_comm_permission,
 };
 
 /*
@@ -3643,7 +3673,8 @@
 	struct task_struct *task, const void *ptr)
 {
 	struct inode *inode;
-	inode = proc_pid_make_inode(dentry->d_sb, task, S_IFDIR | S_IRUGO | S_IXUGO);
+	inode = proc_pid_make_base_inode(dentry->d_sb, task,
+					 S_IFDIR | S_IRUGO | S_IXUGO);
 	if (!inode)
 		return ERR_PTR(-ENOENT);
 
diff --git a/kernel/fs/proc/proc_sysctl.c b/kernel/fs/proc/proc_sysctl.c
index 070d2df..c64f0dd 100644
--- a/kernel/fs/proc/proc_sysctl.c
+++ b/kernel/fs/proc/proc_sysctl.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/bpf-cgroup.h>
 #include <linux/mount.h>
+#include <linux/kmemleak.h>
 #include "internal.h"
 
 static const struct dentry_operations proc_sys_dentry_operations;
@@ -27,6 +28,8 @@
 /* shared constants to be used in various sysctls */
 const int sysctl_vals[] = { 0, 1, INT_MAX };
 EXPORT_SYMBOL(sysctl_vals);
+const int android_gki_sysctl_vals[] = { -1, 0, 1, 2, 4, 100, 200, 1000, 3000, INT_MAX };
+EXPORT_SYMBOL(android_gki_sysctl_vals);
 
 /* Support for permanently empty directories */
 
@@ -1105,6 +1108,11 @@
 			err |= sysctl_err(path, table, "array not allowed");
 	}
 
+	if (table->proc_handler == proc_dou8vec_minmax) {
+		if (table->maxlen != sizeof(u8))
+			err |= sysctl_err(path, table, "array not allowed");
+	}
+
 	return err;
 }
 
@@ -1120,6 +1128,7 @@
 		    (table->proc_handler == proc_douintvec) ||
 		    (table->proc_handler == proc_douintvec_minmax) ||
 		    (table->proc_handler == proc_dointvec_minmax) ||
+		    (table->proc_handler == proc_dou8vec_minmax) ||
 		    (table->proc_handler == proc_dointvec_jiffies) ||
 		    (table->proc_handler == proc_dointvec_userhz_jiffies) ||
 		    (table->proc_handler == proc_dointvec_ms_jiffies) ||
@@ -1380,6 +1389,38 @@
 }
 EXPORT_SYMBOL(register_sysctl);
 
+/**
+ * __register_sysctl_init() - register sysctl table to path
+ * @path: path name for sysctl base
+ * @table: This is the sysctl table that needs to be registered to the path
+ * @table_name: The name of sysctl table, only used for log printing when
+ *              registration fails
+ *
+ * The sysctl interface is used by userspace to query or modify at runtime
+ * a predefined value set on a variable. These variables however have default
+ * values pre-set. Code which depends on these variables will always work even
+ * if register_sysctl() fails. If register_sysctl() fails you'd just loose the
+ * ability to query or modify the sysctls dynamically at run time. Chances of
+ * register_sysctl() failing on init are extremely low, and so for both reasons
+ * this function does not return any error as it is used by initialization code.
+ *
+ * Context: Can only be called after your respective sysctl base path has been
+ * registered. So for instance, most base directories are registered early on
+ * init before init levels are processed through proc_sys_init() and
+ * sysctl_init().
+ */
+void __init __register_sysctl_init(const char *path, struct ctl_table *table,
+				 const char *table_name)
+{
+	struct ctl_table_header *hdr = register_sysctl(path, table);
+
+	if (unlikely(!hdr)) {
+		pr_err("failed when register_sysctl %s to %s\n", table_name, path);
+		return;
+	}
+	kmemleak_not_leak(hdr);
+}
+
 static char *append_path(const char *path, char *pos, const char *name)
 {
 	int namelen;
diff --git a/kernel/fs/proc/task_mmu.c b/kernel/fs/proc/task_mmu.c
index 8aa5fb6..9d316d5 100644
--- a/kernel/fs/proc/task_mmu.c
+++ b/kernel/fs/proc/task_mmu.c
@@ -774,9 +774,7 @@
 			page = device_private_entry_to_page(swpent);
 	}
 	if (page) {
-		int mapcount = page_mapcount(page);
-
-		if (mapcount >= 2)
+		if (page_mapcount(page) >= 2 || hugetlb_pmd_shared(pte))
 			mss->shared_hugetlb += huge_page_size(hstate_vma(vma));
 		else
 			mss->private_hugetlb += huge_page_size(hstate_vma(vma));
diff --git a/kernel/fs/proc/task_nommu.c b/kernel/fs/proc/task_nommu.c
index a6d21fc..97f387d 100644
--- a/kernel/fs/proc/task_nommu.c
+++ b/kernel/fs/proc/task_nommu.c
@@ -208,11 +208,16 @@
 		return ERR_PTR(-ESRCH);
 
 	mm = priv->mm;
-	if (!mm || !mmget_not_zero(mm))
+	if (!mm || !mmget_not_zero(mm)) {
+		put_task_struct(priv->task);
+		priv->task = NULL;
 		return NULL;
+	}
 
 	if (mmap_read_lock_killable(mm)) {
 		mmput(mm);
+		put_task_struct(priv->task);
+		priv->task = NULL;
 		return ERR_PTR(-EINTR);
 	}
 
@@ -221,23 +226,21 @@
 		if (n-- == 0)
 			return p;
 
-	mmap_read_unlock(mm);
-	mmput(mm);
 	return NULL;
 }
 
-static void m_stop(struct seq_file *m, void *_vml)
+static void m_stop(struct seq_file *m, void *v)
 {
 	struct proc_maps_private *priv = m->private;
+	struct mm_struct *mm = priv->mm;
 
-	if (!IS_ERR_OR_NULL(_vml)) {
-		mmap_read_unlock(priv->mm);
-		mmput(priv->mm);
-	}
-	if (priv->task) {
-		put_task_struct(priv->task);
-		priv->task = NULL;
-	}
+	if (!priv->task)
+		return;
+
+	mmap_read_unlock(mm);
+	mmput(mm);
+	put_task_struct(priv->task);
+	priv->task = NULL;
 }
 
 static void *m_next(struct seq_file *m, void *_p, loff_t *pos)
diff --git a/kernel/fs/pstore/Kconfig b/kernel/fs/pstore/Kconfig
index d51c746..2d53a6f 100644
--- a/kernel/fs/pstore/Kconfig
+++ b/kernel/fs/pstore/Kconfig
@@ -118,6 +118,7 @@
 config PSTORE_PMSG
 	bool "Log user space messages"
 	depends on PSTORE
+	select RT_MUTEXES
 	help
 	  When the option is enabled, pstore will export a character
 	  interface /dev/pmsg0 to log user space messages. On reboot
diff --git a/kernel/fs/pstore/ram.c b/kernel/fs/pstore/ram.c
index 8aba1de..4db798d 100644
--- a/kernel/fs/pstore/ram.c
+++ b/kernel/fs/pstore/ram.c
@@ -799,10 +799,12 @@
 	int i = 0;
 	struct persistent_ram_zone *prz = NULL;
 
+#ifdef CONFIG_PSTORE_BOOT_LOG
 	for (i = 0; i < cxt->max_boot_log_cnt; i++) {
 		prz = cxt->boot_przs[i];
 		_ramoops_register_ram_zone_info_to_minidump(prz);
 	}
+#endif
 
 	for (i = 0; i < cxt->max_dump_cnt; i++) {
 		prz = cxt->dprzs[i];
@@ -854,6 +856,7 @@
 	/* Make sure we didn't get bogus platform data pointer. */
 	if (!pdata) {
 		pr_err("NULL platform data\n");
+		err = -EINVAL;
 		goto fail_out;
 	}
 
@@ -869,6 +872,7 @@
 			!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;
 	}
 #endif
diff --git a/kernel/fs/pstore/ram_core.c b/kernel/fs/pstore/ram_core.c
index f1acc22..06a00e1 100644
--- a/kernel/fs/pstore/ram_core.c
+++ b/kernel/fs/pstore/ram_core.c
@@ -439,7 +439,11 @@
 		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);
 
 	/*
@@ -514,7 +518,7 @@
 	sig ^= PERSISTENT_RAM_SIG;
 
 	if (prz->buffer->sig == sig) {
-		if (buffer_size(prz) == 0) {
+		if (buffer_size(prz) == 0 && buffer_start(prz) == 0) {
 			pr_debug("found existing empty buffer\n");
 			return 0;
 		}
@@ -587,6 +591,8 @@
 	raw_spin_lock_init(&prz->buffer_lock);
 	prz->flags = flags;
 	prz->label = kstrdup(label, GFP_KERNEL);
+	if (!prz->label)
+		goto err;
 
 	ret = persistent_ram_buffer_map(start, size, prz, memtype);
 	if (ret)
diff --git a/kernel/fs/pstore/zone.c b/kernel/fs/pstore/zone.c
index 3ce8921..b50fc33 100644
--- a/kernel/fs/pstore/zone.c
+++ b/kernel/fs/pstore/zone.c
@@ -761,7 +761,7 @@
 		/* avoid destroying old data, allocate a new one */
 		len = zone->buffer_size + sizeof(*zone->buffer);
 		zone->oldbuf = zone->buffer;
-		zone->buffer = kzalloc(len, GFP_KERNEL);
+		zone->buffer = kzalloc(len, GFP_ATOMIC);
 		if (!zone->buffer) {
 			zone->buffer = zone->oldbuf;
 			return -ENOMEM;
diff --git a/kernel/fs/quota/dquot.c b/kernel/fs/quota/dquot.c
index 65f123d..13a9a17 100644
--- a/kernel/fs/quota/dquot.c
+++ b/kernel/fs/quota/dquot.c
@@ -225,12 +225,21 @@
 
 /*
  * Dquot List Management:
- * The quota code uses four lists for dquot management: the inuse_list,
- * free_dquots, dqi_dirty_list, and dquot_hash[] array. A single dquot
- * structure may be on some of those lists, depending on its current state.
+ * The quota code uses five lists for dquot management: the inuse_list,
+ * releasing_dquots, free_dquots, dqi_dirty_list, and dquot_hash[] array.
+ * A single dquot structure may be on some of those lists, depending on
+ * its current state.
  *
  * All dquots are placed to the end of inuse_list when first created, and this
  * list is used for invalidate operation, which must look at every dquot.
+ *
+ * When the last reference of a dquot will be dropped, the dquot will be
+ * added to releasing_dquots. We'd then queue work item which would call
+ * synchronize_srcu() and after that perform the final cleanup of all the
+ * dquots on the list. Both releasing_dquots and free_dquots use the
+ * dq_free list_head in the dquot struct. When a dquot is removed from
+ * releasing_dquots, a reference count is always subtracted, and if
+ * dq_count == 0 at that point, the dquot will be added to the free_dquots.
  *
  * Unused dquots (dq_count == 0) are added to the free_dquots list when freed,
  * and this list is searched whenever we need an available dquot.  Dquots are
@@ -250,6 +259,7 @@
 
 static LIST_HEAD(inuse_list);
 static LIST_HEAD(free_dquots);
+static LIST_HEAD(releasing_dquots);
 static unsigned int dq_hash_bits, dq_hash_mask;
 static struct hlist_head *dquot_hash;
 
@@ -259,6 +269,9 @@
 static qsize_t inode_get_rsv_space(struct inode *inode);
 static qsize_t __inode_get_rsv_space(struct inode *inode);
 static int __dquot_initialize(struct inode *inode, int type);
+
+static void quota_release_workfn(struct work_struct *work);
+static DECLARE_DELAYED_WORK(quota_release_work, quota_release_workfn);
 
 static inline unsigned int
 hashfn(const struct super_block *sb, struct kqid qid)
@@ -307,12 +320,18 @@
 	dqstats_inc(DQST_FREE_DQUOTS);
 }
 
+static inline void put_releasing_dquots(struct dquot *dquot)
+{
+	list_add_tail(&dquot->dq_free, &releasing_dquots);
+}
+
 static inline void remove_free_dquot(struct dquot *dquot)
 {
 	if (list_empty(&dquot->dq_free))
 		return;
 	list_del_init(&dquot->dq_free);
-	dqstats_dec(DQST_FREE_DQUOTS);
+	if (!atomic_read(&dquot->dq_count))
+		dqstats_dec(DQST_FREE_DQUOTS);
 }
 
 static inline void put_inuse(struct dquot *dquot)
@@ -338,6 +357,11 @@
 	mutex_unlock(&dquot->dq_lock);
 }
 
+static inline int dquot_active(struct dquot *dquot)
+{
+	return test_bit(DQ_ACTIVE_B, &dquot->dq_flags);
+}
+
 static inline int dquot_dirty(struct dquot *dquot)
 {
 	return test_bit(DQ_MOD_B, &dquot->dq_flags);
@@ -353,14 +377,14 @@
 {
 	int ret = 1;
 
-	if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
+	if (!dquot_active(dquot))
 		return 0;
 
 	if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NOLIST_DIRTY)
 		return test_and_set_bit(DQ_MOD_B, &dquot->dq_flags);
 
 	/* If quota is dirty already, we don't have to acquire dq_list_lock */
-	if (test_bit(DQ_MOD_B, &dquot->dq_flags))
+	if (dquot_dirty(dquot))
 		return 1;
 
 	spin_lock(&dq_list_lock);
@@ -442,7 +466,7 @@
 	smp_mb__before_atomic();
 	set_bit(DQ_READ_B, &dquot->dq_flags);
 	/* Instantiate dquot if needed */
-	if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) {
+	if (!dquot_active(dquot) && !dquot->dq_off) {
 		ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot);
 		/* Write the info if needed */
 		if (info_dirty(&dqopt->info[dquot->dq_id.type])) {
@@ -484,7 +508,7 @@
 		goto out_lock;
 	/* Inactive dquot can be only if there was error during read/init
 	 * => we have better not writing it */
-	if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
+	if (dquot_active(dquot))
 		ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot);
 	else
 		ret = -EIO;
@@ -549,6 +573,8 @@
 	struct dquot *dquot, *tmp;
 
 restart:
+	flush_delayed_work(&quota_release_work);
+
 	spin_lock(&dq_list_lock);
 	list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) {
 		if (dquot->dq_sb != sb)
@@ -557,7 +583,13 @@
 			continue;
 		/* Wait for dquot users */
 		if (atomic_read(&dquot->dq_count)) {
-			dqgrab(dquot);
+			/* dquot in releasing_dquots, flush and retry */
+			if (!list_empty(&dquot->dq_free)) {
+				spin_unlock(&dq_list_lock);
+				goto restart;
+			}
+
+			atomic_inc(&dquot->dq_count);
 			spin_unlock(&dq_list_lock);
 			/*
 			 * Once dqput() wakes us up, we know it's time to free
@@ -599,7 +631,7 @@
 
 	spin_lock(&dq_list_lock);
 	list_for_each_entry(dquot, &inuse_list, dq_inuse) {
-		if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
+		if (!dquot_active(dquot))
 			continue;
 		if (dquot->dq_sb != sb)
 			continue;
@@ -614,7 +646,7 @@
 		 * outstanding call and recheck the DQ_ACTIVE_B after that.
 		 */
 		wait_on_dquot(dquot);
-		if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
+		if (dquot_active(dquot)) {
 			ret = fn(dquot, priv);
 			if (ret < 0)
 				goto out;
@@ -629,6 +661,18 @@
 	return ret;
 }
 EXPORT_SYMBOL(dquot_scan_active);
+
+static inline int dquot_write_dquot(struct dquot *dquot)
+{
+	int ret = dquot->dq_sb->dq_op->write_dquot(dquot);
+	if (ret < 0) {
+		quota_error(dquot->dq_sb, "Can't write quota structure "
+			    "(error %d). Quota may get out of sync!", ret);
+		/* Clear dirty bit anyway to avoid infinite loop. */
+		clear_dquot_dirty(dquot);
+	}
+	return ret;
+}
 
 /* Write all dquot structures to quota files */
 int dquot_writeback_dquots(struct super_block *sb, int type)
@@ -653,23 +697,16 @@
 			dquot = list_first_entry(&dirty, struct dquot,
 						 dq_dirty);
 
-			WARN_ON(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags));
+			WARN_ON(!dquot_active(dquot));
 
 			/* Now we have active dquot from which someone is
  			 * holding reference so we can safely just increase
 			 * use count */
 			dqgrab(dquot);
 			spin_unlock(&dq_list_lock);
-			err = sb->dq_op->write_dquot(dquot);
-			if (err) {
-				/*
-				 * Clear dirty bit anyway to avoid infinite
-				 * loop here.
-				 */
-				clear_dquot_dirty(dquot);
-				if (!ret)
-					ret = err;
-			}
+			err = dquot_write_dquot(dquot);
+			if (err && !ret)
+				ret = err;
 			dqput(dquot);
 			spin_lock(&dq_list_lock);
 		}
@@ -763,12 +800,53 @@
 };
 
 /*
+ * Safely release dquot and put reference to dquot.
+ */
+static void quota_release_workfn(struct work_struct *work)
+{
+	struct dquot *dquot;
+	struct list_head rls_head;
+
+	spin_lock(&dq_list_lock);
+	/* Exchange the list head to avoid livelock. */
+	list_replace_init(&releasing_dquots, &rls_head);
+	spin_unlock(&dq_list_lock);
+
+restart:
+	synchronize_srcu(&dquot_srcu);
+	spin_lock(&dq_list_lock);
+	while (!list_empty(&rls_head)) {
+		dquot = list_first_entry(&rls_head, struct dquot, dq_free);
+		/* Dquot got used again? */
+		if (atomic_read(&dquot->dq_count) > 1) {
+			remove_free_dquot(dquot);
+			atomic_dec(&dquot->dq_count);
+			continue;
+		}
+		if (dquot_dirty(dquot)) {
+			spin_unlock(&dq_list_lock);
+			/* Commit dquot before releasing */
+			dquot_write_dquot(dquot);
+			goto restart;
+		}
+		if (dquot_active(dquot)) {
+			spin_unlock(&dq_list_lock);
+			dquot->dq_sb->dq_op->release_dquot(dquot);
+			goto restart;
+		}
+		/* Dquot is inactive and clean, now move it to free list */
+		remove_free_dquot(dquot);
+		atomic_dec(&dquot->dq_count);
+		put_dquot_last(dquot);
+	}
+	spin_unlock(&dq_list_lock);
+}
+
+/*
  * Put reference to dquot
  */
 void dqput(struct dquot *dquot)
 {
-	int ret;
-
 	if (!dquot)
 		return;
 #ifdef CONFIG_QUOTA_DEBUG
@@ -780,7 +858,7 @@
 	}
 #endif
 	dqstats_inc(DQST_DROPS);
-we_slept:
+
 	spin_lock(&dq_list_lock);
 	if (atomic_read(&dquot->dq_count) > 1) {
 		/* We have more than one user... nothing to do */
@@ -792,35 +870,15 @@
 		spin_unlock(&dq_list_lock);
 		return;
 	}
+
 	/* Need to release dquot? */
-	if (dquot_dirty(dquot)) {
-		spin_unlock(&dq_list_lock);
-		/* Commit dquot before releasing */
-		ret = dquot->dq_sb->dq_op->write_dquot(dquot);
-		if (ret < 0) {
-			quota_error(dquot->dq_sb, "Can't write quota structure"
-				    " (error %d). Quota may get out of sync!",
-				    ret);
-			/*
-			 * We clear dirty bit anyway, so that we avoid
-			 * infinite loop here
-			 */
-			clear_dquot_dirty(dquot);
-		}
-		goto we_slept;
-	}
-	if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
-		spin_unlock(&dq_list_lock);
-		dquot->dq_sb->dq_op->release_dquot(dquot);
-		goto we_slept;
-	}
-	atomic_dec(&dquot->dq_count);
 #ifdef CONFIG_QUOTA_DEBUG
 	/* sanity check */
 	BUG_ON(!list_empty(&dquot->dq_free));
 #endif
-	put_dquot_last(dquot);
+	put_releasing_dquots(dquot);
 	spin_unlock(&dq_list_lock);
+	queue_delayed_work(system_unbound_wq, &quota_release_work, 1);
 }
 EXPORT_SYMBOL(dqput);
 
@@ -910,7 +968,7 @@
 	 * already finished or it will be canceled due to dq_count > 1 test */
 	wait_on_dquot(dquot);
 	/* Read the dquot / allocate space in quota file */
-	if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
+	if (!dquot_active(dquot)) {
 		int err;
 
 		err = sb->dq_op->acquire_dquot(dquot);
@@ -1427,7 +1485,7 @@
 	return QUOTA_NL_NOWARN;
 }
 
-static int dquot_active(const struct inode *inode)
+static int inode_quota_active(const struct inode *inode)
 {
 	struct super_block *sb = inode->i_sb;
 
@@ -1450,7 +1508,7 @@
 	qsize_t rsv;
 	int ret = 0;
 
-	if (!dquot_active(inode))
+	if (!inode_quota_active(inode))
 		return 0;
 
 	dquots = i_dquot(inode);
@@ -1558,7 +1616,7 @@
 	struct dquot **dquots;
 	int i;
 
-	if (!dquot_active(inode))
+	if (!inode_quota_active(inode))
 		return false;
 
 	dquots = i_dquot(inode);
@@ -1669,7 +1727,7 @@
 	int reserve = flags & DQUOT_SPACE_RESERVE;
 	struct dquot **dquots;
 
-	if (!dquot_active(inode)) {
+	if (!inode_quota_active(inode)) {
 		if (reserve) {
 			spin_lock(&inode->i_lock);
 			*inode_reserved_space(inode) += number;
@@ -1739,7 +1797,7 @@
 	struct dquot_warn warn[MAXQUOTAS];
 	struct dquot * const *dquots;
 
-	if (!dquot_active(inode))
+	if (!inode_quota_active(inode))
 		return 0;
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
 		warn[cnt].w_type = QUOTA_NL_NOWARN;
@@ -1782,7 +1840,7 @@
 	struct dquot **dquots;
 	int cnt, index;
 
-	if (!dquot_active(inode)) {
+	if (!inode_quota_active(inode)) {
 		spin_lock(&inode->i_lock);
 		*inode_reserved_space(inode) -= number;
 		__inode_add_bytes(inode, number);
@@ -1824,7 +1882,7 @@
 	struct dquot **dquots;
 	int cnt, index;
 
-	if (!dquot_active(inode)) {
+	if (!inode_quota_active(inode)) {
 		spin_lock(&inode->i_lock);
 		*inode_reserved_space(inode) += number;
 		__inode_sub_bytes(inode, number);
@@ -1868,7 +1926,7 @@
 	struct dquot **dquots;
 	int reserve = flags & DQUOT_SPACE_RESERVE, index;
 
-	if (!dquot_active(inode)) {
+	if (!inode_quota_active(inode)) {
 		if (reserve) {
 			spin_lock(&inode->i_lock);
 			*inode_reserved_space(inode) -= number;
@@ -1923,7 +1981,7 @@
 	struct dquot * const *dquots;
 	int index;
 
-	if (!dquot_active(inode))
+	if (!inode_quota_active(inode))
 		return;
 
 	dquots = i_dquot(inode);
@@ -2094,7 +2152,7 @@
 	struct super_block *sb = inode->i_sb;
 	int ret;
 
-	if (!dquot_active(inode))
+	if (!inode_quota_active(inode))
 		return 0;
 
 	if (iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)){
@@ -2319,6 +2377,8 @@
 	struct super_block *sb = inode->i_sb;
 	struct quota_info *dqopt = sb_dqopt(sb);
 
+	if (is_bad_inode(inode))
+		return -EUCLEAN;
 	if (!S_ISREG(inode->i_mode))
 		return -EACCES;
 	if (IS_RDONLY(inode))
@@ -2413,7 +2473,8 @@
 
 	error = add_dquot_ref(sb, type);
 	if (error)
-		dquot_disable(sb, type, flags);
+		dquot_disable(sb, type,
+			      DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
 
 	return error;
 out_fmt:
diff --git a/kernel/fs/ramfs/inode.c b/kernel/fs/ramfs/inode.c
index ee179a8..23d2c33 100644
--- a/kernel/fs/ramfs/inode.c
+++ b/kernel/fs/ramfs/inode.c
@@ -264,7 +264,7 @@
 	return 0;
 }
 
-static void ramfs_kill_sb(struct super_block *sb)
+void ramfs_kill_sb(struct super_block *sb)
 {
 	kfree(sb->s_fs_info);
 	kill_litter_super(sb);
diff --git a/kernel/fs/reiserfs/journal.c b/kernel/fs/reiserfs/journal.c
index df5fc12..cfa4def 100644
--- a/kernel/fs/reiserfs/journal.c
+++ b/kernel/fs/reiserfs/journal.c
@@ -2325,7 +2325,7 @@
 	int i, j;
 
 	bh = __getblk(dev, block, bufsize);
-	if (buffer_uptodate(bh))
+	if (!bh || buffer_uptodate(bh))
 		return (bh);
 
 	if (block + BUFNR > max_block) {
@@ -2335,6 +2335,8 @@
 	j = 1;
 	for (i = 1; i < blocks; i++) {
 		bh = __getblk(dev, block + i, bufsize);
+		if (!bh)
+			break;
 		if (buffer_uptodate(bh)) {
 			brelse(bh);
 			break;
diff --git a/kernel/fs/reiserfs/namei.c b/kernel/fs/reiserfs/namei.c
index 1594687..84cc136 100644
--- a/kernel/fs/reiserfs/namei.c
+++ b/kernel/fs/reiserfs/namei.c
@@ -695,6 +695,7 @@
 
 out_failed:
 	reiserfs_write_unlock(dir->i_sb);
+	reiserfs_security_free(&security);
 	return retval;
 }
 
@@ -778,6 +779,7 @@
 
 out_failed:
 	reiserfs_write_unlock(dir->i_sb);
+	reiserfs_security_free(&security);
 	return retval;
 }
 
@@ -876,6 +878,7 @@
 	retval = journal_end(&th);
 out_failed:
 	reiserfs_write_unlock(dir->i_sb);
+	reiserfs_security_free(&security);
 	return retval;
 }
 
@@ -1191,6 +1194,7 @@
 	retval = journal_end(&th);
 out_failed:
 	reiserfs_write_unlock(parent_dir->i_sb);
+	reiserfs_security_free(&security);
 	return retval;
 }
 
diff --git a/kernel/fs/reiserfs/super.c b/kernel/fs/reiserfs/super.c
index d84c2f2..09ef9b4 100644
--- a/kernel/fs/reiserfs/super.c
+++ b/kernel/fs/reiserfs/super.c
@@ -1437,17 +1437,12 @@
 	unsigned long safe_mask = 0;
 	unsigned int commit_max_age = (unsigned int)-1;
 	struct reiserfs_journal *journal = SB_JOURNAL(s);
-	char *new_opts;
 	int err;
 	char *qf_names[REISERFS_MAXQUOTAS];
 	unsigned int qfmt = 0;
 #ifdef CONFIG_QUOTA
 	int i;
 #endif
-
-	new_opts = kstrdup(arg, GFP_KERNEL);
-	if (arg && !new_opts)
-		return -ENOMEM;
 
 	sync_filesystem(s);
 	reiserfs_write_lock(s);
@@ -1599,7 +1594,6 @@
 out_err_unlock:
 	reiserfs_write_unlock(s);
 out_err:
-	kfree(new_opts);
 	return err;
 }
 
diff --git a/kernel/fs/reiserfs/xattr_security.c b/kernel/fs/reiserfs/xattr_security.c
index eedfa07..b743f7b 100644
--- a/kernel/fs/reiserfs/xattr_security.c
+++ b/kernel/fs/reiserfs/xattr_security.c
@@ -50,6 +50,7 @@
 	int error;
 
 	sec->name = NULL;
+	sec->value = NULL;
 
 	/* Don't add selinux attributes on xattrs - they'll never get used */
 	if (IS_PRIVATE(dir))
@@ -81,11 +82,15 @@
 			    struct inode *inode,
 			    struct reiserfs_security_handle *sec)
 {
+	char xattr_name[XATTR_NAME_MAX + 1] = XATTR_SECURITY_PREFIX;
 	int error;
-	if (strlen(sec->name) < sizeof(XATTR_SECURITY_PREFIX))
+
+	if (XATTR_SECURITY_PREFIX_LEN + strlen(sec->name) > XATTR_NAME_MAX)
 		return -EINVAL;
 
-	error = reiserfs_xattr_set_handle(th, inode, sec->name, sec->value,
+	strlcat(xattr_name, sec->name, sizeof(xattr_name));
+
+	error = reiserfs_xattr_set_handle(th, inode, xattr_name, sec->value,
 					  sec->length, XATTR_CREATE);
 	if (error == -ENODATA || error == -EOPNOTSUPP)
 		error = 0;
@@ -95,7 +100,6 @@
 
 void reiserfs_security_free(struct reiserfs_security_handle *sec)
 {
-	kfree(sec->name);
 	kfree(sec->value);
 	sec->name = NULL;
 	sec->value = NULL;
diff --git a/kernel/fs/squashfs/squashfs_fs.h b/kernel/fs/squashfs/squashfs_fs.h
index b3fdc82..95f8e89 100644
--- a/kernel/fs/squashfs/squashfs_fs.h
+++ b/kernel/fs/squashfs/squashfs_fs.h
@@ -183,7 +183,7 @@
 #define SQUASHFS_ID_BLOCK_BYTES(A)	(SQUASHFS_ID_BLOCKS(A) *\
 					sizeof(u64))
 /* xattr id lookup table defines */
-#define SQUASHFS_XATTR_BYTES(A)		((A) * sizeof(struct squashfs_xattr_id))
+#define SQUASHFS_XATTR_BYTES(A)		(((u64) (A)) * sizeof(struct squashfs_xattr_id))
 
 #define SQUASHFS_XATTR_BLOCK(A)		(SQUASHFS_XATTR_BYTES(A) / \
 					SQUASHFS_METADATA_SIZE)
diff --git a/kernel/fs/squashfs/squashfs_fs_sb.h b/kernel/fs/squashfs/squashfs_fs_sb.h
index 166e988..8f9445e 100644
--- a/kernel/fs/squashfs/squashfs_fs_sb.h
+++ b/kernel/fs/squashfs/squashfs_fs_sb.h
@@ -63,7 +63,7 @@
 	long long				bytes_used;
 	unsigned int				inodes;
 	unsigned int				fragments;
-	int					xattr_ids;
+	unsigned int				xattr_ids;
 	unsigned int				ids;
 };
 #endif
diff --git a/kernel/fs/squashfs/xattr.h b/kernel/fs/squashfs/xattr.h
index d8a270d..f1a463d 100644
--- a/kernel/fs/squashfs/xattr.h
+++ b/kernel/fs/squashfs/xattr.h
@@ -10,12 +10,12 @@
 
 #ifdef CONFIG_SQUASHFS_XATTR
 extern __le64 *squashfs_read_xattr_id_table(struct super_block *, u64,
-		u64 *, int *);
+		u64 *, unsigned int *);
 extern int squashfs_xattr_lookup(struct super_block *, unsigned int, int *,
 		unsigned int *, unsigned long long *);
 #else
 static inline __le64 *squashfs_read_xattr_id_table(struct super_block *sb,
-		u64 start, u64 *xattr_table_start, int *xattr_ids)
+		u64 start, u64 *xattr_table_start, unsigned int *xattr_ids)
 {
 	struct squashfs_xattr_id_table *id_table;
 
diff --git a/kernel/fs/squashfs/xattr_id.c b/kernel/fs/squashfs/xattr_id.c
index 087cab8..c8469c6 100644
--- a/kernel/fs/squashfs/xattr_id.c
+++ b/kernel/fs/squashfs/xattr_id.c
@@ -56,7 +56,7 @@
  * Read uncompressed xattr id lookup table indexes from disk into memory
  */
 __le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 table_start,
-		u64 *xattr_table_start, int *xattr_ids)
+		u64 *xattr_table_start, unsigned int *xattr_ids)
 {
 	struct squashfs_sb_info *msblk = sb->s_fs_info;
 	unsigned int len, indexes;
diff --git a/kernel/fs/statfs.c b/kernel/fs/statfs.c
index 59f3375..d42b44d 100644
--- a/kernel/fs/statfs.c
+++ b/kernel/fs/statfs.c
@@ -130,6 +130,7 @@
 	if (sizeof(buf) == sizeof(*st))
 		memcpy(&buf, st, sizeof(*st));
 	else {
+		memset(&buf, 0, sizeof(buf));
 		if (sizeof buf.f_blocks == 4) {
 			if ((st->f_blocks | st->f_bfree | st->f_bavail |
 			     st->f_bsize | st->f_frsize) &
@@ -158,7 +159,6 @@
 		buf.f_namelen = st->f_namelen;
 		buf.f_frsize = st->f_frsize;
 		buf.f_flags = st->f_flags;
-		memset(buf.f_spare, 0, sizeof(buf.f_spare));
 	}
 	if (copy_to_user(p, &buf, sizeof(buf)))
 		return -EFAULT;
@@ -171,6 +171,7 @@
 	if (sizeof(buf) == sizeof(*st))
 		memcpy(&buf, st, sizeof(*st));
 	else {
+		memset(&buf, 0, sizeof(buf));
 		buf.f_type = st->f_type;
 		buf.f_bsize = st->f_bsize;
 		buf.f_blocks = st->f_blocks;
@@ -182,7 +183,6 @@
 		buf.f_namelen = st->f_namelen;
 		buf.f_frsize = st->f_frsize;
 		buf.f_flags = st->f_flags;
-		memset(buf.f_spare, 0, sizeof(buf.f_spare));
 	}
 	if (copy_to_user(p, &buf, sizeof(buf)))
 		return -EFAULT;
diff --git a/kernel/fs/super.c b/kernel/fs/super.c
index 602d02c..23ad90f 100644
--- a/kernel/fs/super.c
+++ b/kernel/fs/super.c
@@ -906,6 +906,7 @@
 	struct super_block *sb = fc->root->d_sb;
 	int retval;
 	bool remount_ro = false;
+	bool remount_rw = false;
 	bool force = fc->sb_flags & SB_FORCE;
 
 	if (fc->sb_flags_mask & ~MS_RMT_MASK)
@@ -922,7 +923,7 @@
 		if (!(fc->sb_flags & SB_RDONLY) && bdev_read_only(sb->s_bdev))
 			return -EACCES;
 #endif
-
+		remount_rw = !(fc->sb_flags & SB_RDONLY) && sb_rdonly(sb);
 		remount_ro = (fc->sb_flags & SB_RDONLY) && !sb_rdonly(sb);
 	}
 
@@ -952,6 +953,14 @@
 			if (retval)
 				return retval;
 		}
+	} else if (remount_rw) {
+		/*
+		 * We set s_readonly_remount here to protect filesystem's
+		 * reconfigure code from writes from userspace until
+		 * reconfigure finishes.
+		 */
+		sb->s_readonly_remount = 1;
+		smp_wmb();
 	}
 
 	if (fc->ops->reconfigure) {
diff --git a/kernel/fs/sysv/itree.c b/kernel/fs/sysv/itree.c
index bcb67b0..e3d1673 100644
--- a/kernel/fs/sysv/itree.c
+++ b/kernel/fs/sysv/itree.c
@@ -145,6 +145,10 @@
 		 */
 		parent = block_to_cpu(SYSV_SB(inode->i_sb), branch[n-1].key);
 		bh = sb_getblk(inode->i_sb, parent);
+		if (!bh) {
+			sysv_free_block(inode->i_sb, branch[n].key);
+			break;
+		}
 		lock_buffer(bh);
 		memset(bh->b_data, 0, blocksize);
 		branch[n].bh = bh;
@@ -438,7 +442,7 @@
 		res += blocks;
 		direct = 1;
 	}
-	return blocks;
+	return res;
 }
 
 int sysv_getattr(const struct path *path, struct kstat *stat,
diff --git a/kernel/fs/tracefs/inode.c b/kernel/fs/tracefs/inode.c
index 1311e68..c0f288a 100644
--- a/kernel/fs/tracefs/inode.c
+++ b/kernel/fs/tracefs/inode.c
@@ -553,6 +553,9 @@
  */
 struct dentry *tracefs_create_dir(const char *name, struct dentry *parent)
 {
+	if (security_locked_down(LOCKDOWN_TRACEFS))
+		return NULL;
+
 	return __create_dir(name, parent, &simple_dir_inode_operations);
 }
 
diff --git a/kernel/fs/ubifs/budget.c b/kernel/fs/ubifs/budget.c
index c0b84e9..9cb05ef 100644
--- a/kernel/fs/ubifs/budget.c
+++ b/kernel/fs/ubifs/budget.c
@@ -212,11 +212,10 @@
 	subtract_lebs += 1;
 
 	/*
-	 * The GC journal head LEB is not really accessible. And since
-	 * different write types go to different heads, we may count only on
-	 * one head's space.
+	 * Since different write types go to different heads, we should
+	 * reserve one leb for each head.
 	 */
-	subtract_lebs += c->jhead_cnt - 1;
+	subtract_lebs += c->jhead_cnt;
 
 	/* We also reserve one LEB for deletions, which bypass budgeting */
 	subtract_lebs += 1;
@@ -403,7 +402,7 @@
 	dd_growth = req->dirtied_page ? c->bi.page_budget : 0;
 
 	if (req->dirtied_ino)
-		dd_growth += c->bi.inode_budget << (req->dirtied_ino - 1);
+		dd_growth += c->bi.inode_budget * req->dirtied_ino;
 	if (req->mod_dent)
 		dd_growth += c->bi.dent_budget;
 	dd_growth += req->dirtied_ino_d;
diff --git a/kernel/fs/ubifs/dir.c b/kernel/fs/ubifs/dir.c
index e75301f..3ba451a 100644
--- a/kernel/fs/ubifs/dir.c
+++ b/kernel/fs/ubifs/dir.c
@@ -426,6 +426,7 @@
 	mutex_unlock(&dir_ui->ui_mutex);
 
 	ubifs_release_budget(c, &req);
+	fscrypt_free_filename(&nm);
 
 	return 0;
 
@@ -1118,7 +1119,6 @@
 	int err, sz_change, len = strlen(symname);
 	struct fscrypt_str disk_link;
 	struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
-					.new_ino_d = ALIGN(len, 8),
 					.dirtied_ino = 1 };
 	struct fscrypt_name nm;
 
@@ -1134,6 +1134,7 @@
 	 * Budget request settings: new inode, new direntry and changing parent
 	 * directory inode.
 	 */
+	req.new_ino_d = ALIGN(disk_link.len - 1, 8);
 	err = ubifs_budget_space(c, &req);
 	if (err)
 		return err;
@@ -1289,6 +1290,8 @@
 	if (unlink) {
 		ubifs_assert(c, inode_is_locked(new_inode));
 
+		/* Budget for old inode's data when its nlink > 1. */
+		req.dirtied_ino_d = ALIGN(ubifs_inode(new_inode)->data_len, 8);
 		err = ubifs_purge_xattrs(new_inode);
 		if (err)
 			return err;
@@ -1531,6 +1534,10 @@
 		return err;
 	}
 
+	err = ubifs_budget_space(c, &req);
+	if (err)
+		goto out;
+
 	lock_4_inodes(old_dir, new_dir, NULL, NULL);
 
 	time = current_time(old_dir);
@@ -1556,6 +1563,7 @@
 	unlock_4_inodes(old_dir, new_dir, NULL, NULL);
 	ubifs_release_budget(c, &req);
 
+out:
 	fscrypt_free_filename(&fst_nm);
 	fscrypt_free_filename(&snd_nm);
 	return err;
diff --git a/kernel/fs/ubifs/file.c b/kernel/fs/ubifs/file.c
index 354457e..19fdcda 100644
--- a/kernel/fs/ubifs/file.c
+++ b/kernel/fs/ubifs/file.c
@@ -1031,7 +1031,7 @@
 		if (page->index >= synced_i_size >> PAGE_SHIFT) {
 			err = inode->i_sb->s_op->write_inode(inode, NULL);
 			if (err)
-				goto out_unlock;
+				goto out_redirty;
 			/*
 			 * The inode has been written, but the write-buffer has
 			 * not been synchronized, so in case of an unclean
@@ -1059,11 +1059,17 @@
 	if (i_size > synced_i_size) {
 		err = inode->i_sb->s_op->write_inode(inode, NULL);
 		if (err)
-			goto out_unlock;
+			goto out_redirty;
 	}
 
 	return do_writepage(page, len);
-
+out_redirty:
+	/*
+	 * redirty_page_for_writepage() won't call ubifs_dirty_inode() because
+	 * it passes I_DIRTY_PAGES flag while calling __mark_inode_dirty(), so
+	 * there is no need to do space budget for dirty inode.
+	 */
+	redirty_page_for_writepage(wbc, page);
 out_unlock:
 	unlock_page(page);
 	return err;
diff --git a/kernel/fs/ubifs/super.c b/kernel/fs/ubifs/super.c
index 54093d0..5fa3b36 100644
--- a/kernel/fs/ubifs/super.c
+++ b/kernel/fs/ubifs/super.c
@@ -833,7 +833,7 @@
 		INIT_LIST_HEAD(&c->jheads[i].buds_list);
 		err = ubifs_wbuf_init(c, &c->jheads[i].wbuf);
 		if (err)
-			return err;
+			goto out_wbuf;
 
 		c->jheads[i].wbuf.sync_callback = &bud_wbuf_callback;
 		c->jheads[i].wbuf.jhead = i;
@@ -841,7 +841,7 @@
 		c->jheads[i].log_hash = ubifs_hash_get_desc(c);
 		if (IS_ERR(c->jheads[i].log_hash)) {
 			err = PTR_ERR(c->jheads[i].log_hash);
-			goto out;
+			goto out_log_hash;
 		}
 	}
 
@@ -854,9 +854,18 @@
 
 	return 0;
 
-out:
-	while (i--)
+out_log_hash:
+	kfree(c->jheads[i].wbuf.buf);
+	kfree(c->jheads[i].wbuf.inodes);
+
+out_wbuf:
+	while (i--) {
+		kfree(c->jheads[i].wbuf.buf);
+		kfree(c->jheads[i].wbuf.inodes);
 		kfree(c->jheads[i].log_hash);
+	}
+	kfree(c->jheads);
+	c->jheads = NULL;
 
 	return err;
 }
diff --git a/kernel/fs/ubifs/tnc.c b/kernel/fs/ubifs/tnc.c
index 894f1ab..2313c71 100644
--- a/kernel/fs/ubifs/tnc.c
+++ b/kernel/fs/ubifs/tnc.c
@@ -44,6 +44,33 @@
 	NOT_ON_MEDIA = 3,
 };
 
+static void do_insert_old_idx(struct ubifs_info *c,
+			      struct ubifs_old_idx *old_idx)
+{
+	struct ubifs_old_idx *o;
+	struct rb_node **p, *parent = NULL;
+
+	p = &c->old_idx.rb_node;
+	while (*p) {
+		parent = *p;
+		o = rb_entry(parent, struct ubifs_old_idx, rb);
+		if (old_idx->lnum < o->lnum)
+			p = &(*p)->rb_left;
+		else if (old_idx->lnum > o->lnum)
+			p = &(*p)->rb_right;
+		else if (old_idx->offs < o->offs)
+			p = &(*p)->rb_left;
+		else if (old_idx->offs > o->offs)
+			p = &(*p)->rb_right;
+		else {
+			ubifs_err(c, "old idx added twice!");
+			kfree(old_idx);
+		}
+	}
+	rb_link_node(&old_idx->rb, parent, p);
+	rb_insert_color(&old_idx->rb, &c->old_idx);
+}
+
 /**
  * insert_old_idx - record an index node obsoleted since the last commit start.
  * @c: UBIFS file-system description object
@@ -69,35 +96,15 @@
  */
 static int insert_old_idx(struct ubifs_info *c, int lnum, int offs)
 {
-	struct ubifs_old_idx *old_idx, *o;
-	struct rb_node **p, *parent = NULL;
+	struct ubifs_old_idx *old_idx;
 
 	old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS);
 	if (unlikely(!old_idx))
 		return -ENOMEM;
 	old_idx->lnum = lnum;
 	old_idx->offs = offs;
+	do_insert_old_idx(c, old_idx);
 
-	p = &c->old_idx.rb_node;
-	while (*p) {
-		parent = *p;
-		o = rb_entry(parent, struct ubifs_old_idx, rb);
-		if (lnum < o->lnum)
-			p = &(*p)->rb_left;
-		else if (lnum > o->lnum)
-			p = &(*p)->rb_right;
-		else if (offs < o->offs)
-			p = &(*p)->rb_left;
-		else if (offs > o->offs)
-			p = &(*p)->rb_right;
-		else {
-			ubifs_err(c, "old idx added twice!");
-			kfree(old_idx);
-			return 0;
-		}
-	}
-	rb_link_node(&old_idx->rb, parent, p);
-	rb_insert_color(&old_idx->rb, &c->old_idx);
 	return 0;
 }
 
@@ -199,23 +206,6 @@
 	__set_bit(DIRTY_ZNODE, &zn->flags);
 	__clear_bit(COW_ZNODE, &zn->flags);
 
-	ubifs_assert(c, !ubifs_zn_obsolete(znode));
-	__set_bit(OBSOLETE_ZNODE, &znode->flags);
-
-	if (znode->level != 0) {
-		int i;
-		const int n = zn->child_cnt;
-
-		/* The children now have new parent */
-		for (i = 0; i < n; i++) {
-			struct ubifs_zbranch *zbr = &zn->zbranch[i];
-
-			if (zbr->znode)
-				zbr->znode->parent = zn;
-		}
-	}
-
-	atomic_long_inc(&c->dirty_zn_cnt);
 	return zn;
 }
 
@@ -231,6 +221,42 @@
 {
 	c->calc_idx_sz -= ALIGN(dirt, 8);
 	return ubifs_add_dirt(c, lnum, dirt);
+}
+
+/**
+ * replace_znode - replace old znode with new znode.
+ * @c: UBIFS file-system description object
+ * @new_zn: new znode
+ * @old_zn: old znode
+ * @zbr: the branch of parent znode
+ *
+ * Replace old znode with new znode in TNC.
+ */
+static void replace_znode(struct ubifs_info *c, struct ubifs_znode *new_zn,
+			  struct ubifs_znode *old_zn, struct ubifs_zbranch *zbr)
+{
+	ubifs_assert(c, !ubifs_zn_obsolete(old_zn));
+	__set_bit(OBSOLETE_ZNODE, &old_zn->flags);
+
+	if (old_zn->level != 0) {
+		int i;
+		const int n = new_zn->child_cnt;
+
+		/* The children now have new parent */
+		for (i = 0; i < n; i++) {
+			struct ubifs_zbranch *child = &new_zn->zbranch[i];
+
+			if (child->znode)
+				child->znode->parent = new_zn;
+		}
+	}
+
+	zbr->znode = new_zn;
+	zbr->lnum = 0;
+	zbr->offs = 0;
+	zbr->len = 0;
+
+	atomic_long_inc(&c->dirty_zn_cnt);
 }
 
 /**
@@ -265,21 +291,32 @@
 		return zn;
 
 	if (zbr->len) {
-		err = insert_old_idx(c, zbr->lnum, zbr->offs);
-		if (unlikely(err))
-			return ERR_PTR(err);
+		struct ubifs_old_idx *old_idx;
+
+		old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS);
+		if (unlikely(!old_idx)) {
+			err = -ENOMEM;
+			goto out;
+		}
+		old_idx->lnum = zbr->lnum;
+		old_idx->offs = zbr->offs;
+
 		err = add_idx_dirt(c, zbr->lnum, zbr->len);
-	} else
-		err = 0;
+		if (err) {
+			kfree(old_idx);
+			goto out;
+		}
 
-	zbr->znode = zn;
-	zbr->lnum = 0;
-	zbr->offs = 0;
-	zbr->len = 0;
+		do_insert_old_idx(c, old_idx);
+	}
 
-	if (unlikely(err))
-		return ERR_PTR(err);
+	replace_znode(c, zn, znode, zbr);
+
 	return zn;
+
+out:
+	kfree(zn);
+	return ERR_PTR(err);
 }
 
 /**
@@ -3053,6 +3090,21 @@
 		cnext = cnext->cnext;
 		if (ubifs_zn_obsolete(znode))
 			kfree(znode);
+		else if (!ubifs_zn_cow(znode)) {
+			/*
+			 * Don't forget to update clean znode count after
+			 * committing failed, because ubifs will check this
+			 * count while closing tnc. Non-obsolete znode could
+			 * be re-dirtied during committing process, so dirty
+			 * flag is untrustable. The flag 'COW_ZNODE' is set
+			 * for each dirty znode before committing, and it is
+			 * cleared as long as the znode become clean, so we
+			 * can statistic clean znode count according to this
+			 * flag.
+			 */
+			atomic_long_inc(&c->clean_zn_cnt);
+			atomic_long_inc(&ubifs_clean_zn_cnt);
+		}
 	} while (cnext && cnext != c->cnext);
 }
 
diff --git a/kernel/fs/ubifs/ubifs.h b/kernel/fs/ubifs/ubifs.h
index e7e48f3..b66ebab 100644
--- a/kernel/fs/ubifs/ubifs.h
+++ b/kernel/fs/ubifs/ubifs.h
@@ -1594,8 +1594,13 @@
 	return crypto_memneq(expected, got, c->hmac_desc_len);
 }
 
+#ifdef CONFIG_UBIFS_FS_AUTHENTICATION
 void ubifs_bad_hash(const struct ubifs_info *c, const void *node,
 		    const u8 *hash, int lnum, int offs);
+#else
+static inline void ubifs_bad_hash(const struct ubifs_info *c, const void *node,
+				  const u8 *hash, int lnum, int offs) {};
+#endif
 
 int __ubifs_node_check_hash(const struct ubifs_info *c, const void *buf,
 			  const u8 *expected);
diff --git a/kernel/fs/udf/balloc.c b/kernel/fs/udf/balloc.c
index 8e597db..f416b7f 100644
--- a/kernel/fs/udf/balloc.c
+++ b/kernel/fs/udf/balloc.c
@@ -36,18 +36,41 @@
 			     unsigned long bitmap_nr)
 {
 	struct buffer_head *bh = NULL;
-	int retval = 0;
+	int i;
+	int max_bits, off, count;
 	struct kernel_lb_addr loc;
 
 	loc.logicalBlockNum = bitmap->s_extPosition;
 	loc.partitionReferenceNum = UDF_SB(sb)->s_partition;
 
 	bh = udf_tread(sb, udf_get_lb_pblock(sb, &loc, block));
-	if (!bh)
-		retval = -EIO;
-
 	bitmap->s_block_bitmap[bitmap_nr] = bh;
-	return retval;
+	if (!bh)
+		return -EIO;
+
+	/* Check consistency of Space Bitmap buffer. */
+	max_bits = sb->s_blocksize * 8;
+	if (!bitmap_nr) {
+		off = sizeof(struct spaceBitmapDesc) << 3;
+		count = min(max_bits - off, bitmap->s_nr_groups);
+	} else {
+		/*
+		 * Rough check if bitmap number is too big to have any bitmap
+		 * blocks reserved.
+		 */
+		if (bitmap_nr >
+		    (bitmap->s_nr_groups >> (sb->s_blocksize_bits + 3)) + 2)
+			return 0;
+		off = 0;
+		count = bitmap->s_nr_groups - bitmap_nr * max_bits +
+				(sizeof(struct spaceBitmapDesc) << 3);
+		count = min(count, max_bits);
+	}
+
+	for (i = 0; i < count; i++)
+		if (udf_test_bit(i + off, bh->b_data))
+			return -EFSCORRUPTED;
+	return 0;
 }
 
 static int __load_block_bitmap(struct super_block *sb,
diff --git a/kernel/fs/udf/file.c b/kernel/fs/udf/file.c
index ad8eefa..e283a62 100644
--- a/kernel/fs/udf/file.c
+++ b/kernel/fs/udf/file.c
@@ -147,26 +147,24 @@
 		goto out;
 
 	down_write(&iinfo->i_data_sem);
-	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
-		loff_t end = iocb->ki_pos + iov_iter_count(from);
-
-		if (inode->i_sb->s_blocksize <
-				(udf_file_entry_alloc_offset(inode) + end)) {
-			err = udf_expand_file_adinicb(inode);
-			if (err) {
-				inode_unlock(inode);
-				udf_debug("udf_expand_adinicb: err=%d\n", err);
-				return err;
-			}
-		} else {
-			iinfo->i_lenAlloc = max(end, inode->i_size);
-			up_write(&iinfo->i_data_sem);
+	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB &&
+	    inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
+				 iocb->ki_pos + iov_iter_count(from))) {
+		err = udf_expand_file_adinicb(inode);
+		if (err) {
+			inode_unlock(inode);
+			udf_debug("udf_expand_adinicb: err=%d\n", err);
+			return err;
 		}
 	} else
 		up_write(&iinfo->i_data_sem);
 
 	retval = __generic_file_write_iter(iocb, from);
 out:
+	down_write(&iinfo->i_data_sem);
+	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB && retval > 0)
+		iinfo->i_lenAlloc = inode->i_size;
+	up_write(&iinfo->i_data_sem);
 	inode_unlock(inode);
 
 	if (retval > 0) {
diff --git a/kernel/fs/udf/inode.c b/kernel/fs/udf/inode.c
index d32b836..499a273 100644
--- a/kernel/fs/udf/inode.c
+++ b/kernel/fs/udf/inode.c
@@ -57,15 +57,15 @@
 static int udf_sync_inode(struct inode *inode);
 static int udf_alloc_i_data(struct inode *inode, size_t size);
 static sector_t inode_getblk(struct inode *, sector_t, int *, int *);
-static int8_t udf_insert_aext(struct inode *, struct extent_position,
-			      struct kernel_lb_addr, uint32_t);
+static int udf_insert_aext(struct inode *, struct extent_position,
+			   struct kernel_lb_addr, uint32_t);
 static void udf_split_extents(struct inode *, int *, int, udf_pblk_t,
 			      struct kernel_long_ad *, int *);
 static void udf_prealloc_extents(struct inode *, int, int,
 				 struct kernel_long_ad *, int *);
 static void udf_merge_extents(struct inode *, struct kernel_long_ad *, int *);
-static void udf_update_extents(struct inode *, struct kernel_long_ad *, int,
-			       int, struct extent_position *);
+static int udf_update_extents(struct inode *, struct kernel_long_ad *, int,
+			      int, struct extent_position *);
 static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
 
 static void __udf_clear_extent_cache(struct inode *inode)
@@ -438,6 +438,12 @@
 		iinfo->i_next_alloc_goal++;
 	}
 
+	/*
+	 * Block beyond EOF and prealloc extents? Just discard preallocation
+	 * as it is not useful and complicates things.
+	 */
+	if (((loff_t)block) << inode->i_blkbits >= iinfo->i_lenExtents)
+		udf_discard_prealloc(inode);
 	udf_clear_extent_cache(inode);
 	phys = inode_getblk(inode, block, &err, &new);
 	if (!phys)
@@ -487,8 +493,6 @@
 	uint32_t add;
 	int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
 	struct super_block *sb = inode->i_sb;
-	struct kernel_lb_addr prealloc_loc = {};
-	uint32_t prealloc_len = 0;
 	struct udf_inode_info *iinfo;
 	int err;
 
@@ -509,19 +513,6 @@
 			~(sb->s_blocksize - 1);
 	}
 
-	/* Last extent are just preallocated blocks? */
-	if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
-						EXT_NOT_RECORDED_ALLOCATED) {
-		/* Save the extent so that we can reattach it to the end */
-		prealloc_loc = last_ext->extLocation;
-		prealloc_len = last_ext->extLength;
-		/* Mark the extent as a hole */
-		last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
-			(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
-		last_ext->extLocation.logicalBlockNum = 0;
-		last_ext->extLocation.partitionReferenceNum = 0;
-	}
-
 	/* Can we merge with the previous extent? */
 	if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
 					EXT_NOT_RECORDED_NOT_ALLOCATED) {
@@ -534,8 +525,10 @@
 	}
 
 	if (fake) {
-		udf_add_aext(inode, last_pos, &last_ext->extLocation,
-			     last_ext->extLength, 1);
+		err = udf_add_aext(inode, last_pos, &last_ext->extLocation,
+				   last_ext->extLength, 1);
+		if (err < 0)
+			goto out_err;
 		count++;
 	} else {
 		struct kernel_lb_addr tmploc;
@@ -549,7 +542,7 @@
 		 * more extents, we may need to enter possible following
 		 * empty indirect extent.
 		 */
-		if (new_block_bytes || prealloc_len)
+		if (new_block_bytes)
 			udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0);
 	}
 
@@ -569,7 +562,7 @@
 		err = udf_add_aext(inode, last_pos, &last_ext->extLocation,
 				   last_ext->extLength, 1);
 		if (err)
-			return err;
+			goto out_err;
 		count++;
 	}
 	if (new_block_bytes) {
@@ -578,22 +571,11 @@
 		err = udf_add_aext(inode, last_pos, &last_ext->extLocation,
 				   last_ext->extLength, 1);
 		if (err)
-			return err;
+			goto out_err;
 		count++;
 	}
 
 out:
-	/* Do we have some preallocated blocks saved? */
-	if (prealloc_len) {
-		err = udf_add_aext(inode, last_pos, &prealloc_loc,
-				   prealloc_len, 1);
-		if (err)
-			return err;
-		last_ext->extLocation = prealloc_loc;
-		last_ext->extLength = prealloc_len;
-		count++;
-	}
-
 	/* last_pos should point to the last written extent... */
 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
 		last_pos->offset -= sizeof(struct short_ad);
@@ -603,19 +585,28 @@
 		return -EIO;
 
 	return count;
+out_err:
+	/* Remove extents we've created so far */
+	udf_clear_extent_cache(inode);
+	udf_truncate_extents(inode);
+	return err;
 }
 
 /* Extend the final block of the file to final_block_len bytes */
 static void udf_do_extend_final_block(struct inode *inode,
 				      struct extent_position *last_pos,
 				      struct kernel_long_ad *last_ext,
-				      uint32_t final_block_len)
+				      uint32_t new_elen)
 {
-	struct super_block *sb = inode->i_sb;
 	uint32_t added_bytes;
 
-	added_bytes = final_block_len -
-		      (last_ext->extLength & (sb->s_blocksize - 1));
+	/*
+	 * Extent already large enough? It may be already rounded up to block
+	 * size...
+	 */
+	if (new_elen <= (last_ext->extLength & UDF_EXTENT_LENGTH_MASK))
+		return;
+	added_bytes = new_elen - (last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
 	last_ext->extLength += added_bytes;
 	UDF_I(inode)->i_lenExtents += added_bytes;
 
@@ -632,12 +623,12 @@
 	int8_t etype;
 	struct super_block *sb = inode->i_sb;
 	sector_t first_block = newsize >> sb->s_blocksize_bits, offset;
-	unsigned long partial_final_block;
+	loff_t new_elen;
 	int adsize;
 	struct udf_inode_info *iinfo = UDF_I(inode);
 	struct kernel_long_ad extent;
 	int err = 0;
-	int within_final_block;
+	bool within_last_ext;
 
 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
 		adsize = sizeof(struct short_ad);
@@ -646,8 +637,17 @@
 	else
 		BUG();
 
+	/*
+	 * When creating hole in file, just don't bother with preserving
+	 * preallocation. It likely won't be very useful anyway.
+	 */
+	udf_discard_prealloc(inode);
+
 	etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset);
-	within_final_block = (etype != -1);
+	within_last_ext = (etype != -1);
+	/* We don't expect extents past EOF... */
+	WARN_ON_ONCE(within_last_ext &&
+		     elen > ((loff_t)offset + 1) << inode->i_blkbits);
 
 	if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) ||
 	    (epos.bh && epos.offset == sizeof(struct allocExtDesc))) {
@@ -663,19 +663,17 @@
 		extent.extLength |= etype << 30;
 	}
 
-	partial_final_block = newsize & (sb->s_blocksize - 1);
+	new_elen = ((loff_t)offset << inode->i_blkbits) |
+					(newsize & (sb->s_blocksize - 1));
 
 	/* File has extent covering the new size (could happen when extending
 	 * inside a block)?
 	 */
-	if (within_final_block) {
+	if (within_last_ext) {
 		/* Extending file within the last file block */
-		udf_do_extend_final_block(inode, &epos, &extent,
-					  partial_final_block);
+		udf_do_extend_final_block(inode, &epos, &extent, new_elen);
 	} else {
-		loff_t add = ((loff_t)offset << sb->s_blocksize_bits) |
-			     partial_final_block;
-		err = udf_do_extend_file(inode, &epos, &extent, add);
+		err = udf_do_extend_file(inode, &epos, &extent, new_elen);
 	}
 
 	if (err < 0)
@@ -697,7 +695,7 @@
 	struct kernel_lb_addr eloc, tmpeloc;
 	int c = 1;
 	loff_t lbcount = 0, b_off = 0;
-	udf_pblk_t newblocknum, newblock;
+	udf_pblk_t newblocknum, newblock = 0;
 	sector_t offset = 0;
 	int8_t etype;
 	struct udf_inode_info *iinfo = UDF_I(inode);
@@ -776,10 +774,11 @@
 		goto out_free;
 	}
 
-	/* Are we beyond EOF? */
+	/* Are we beyond EOF and preallocated extent? */
 	if (etype == -1) {
 		int ret;
 		loff_t hole_len;
+
 		isBeyondEOF = true;
 		if (count) {
 			if (c)
@@ -799,25 +798,22 @@
 		ret = udf_do_extend_file(inode, &prev_epos, laarr, hole_len);
 		if (ret < 0) {
 			*err = ret;
-			newblock = 0;
 			goto out_free;
 		}
 		c = 0;
 		offset = 0;
 		count += ret;
-		/* We are not covered by a preallocated extent? */
-		if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) !=
-						EXT_NOT_RECORDED_ALLOCATED) {
-			/* Is there any real extent? - otherwise we overwrite
-			 * the fake one... */
-			if (count)
-				c = !c;
-			laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
-				inode->i_sb->s_blocksize;
-			memset(&laarr[c].extLocation, 0x00,
-				sizeof(struct kernel_lb_addr));
-			count++;
-		}
+		/*
+		 * Is there any real extent? - otherwise we overwrite the fake
+		 * one...
+		 */
+		if (count)
+			c = !c;
+		laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
+			inode->i_sb->s_blocksize;
+		memset(&laarr[c].extLocation, 0x00,
+			sizeof(struct kernel_lb_addr));
+		count++;
 		endnum = c + 1;
 		lastblock = 1;
 	} else {
@@ -864,7 +860,6 @@
 				goal, err);
 		if (!newblocknum) {
 			*err = -ENOSPC;
-			newblock = 0;
 			goto out_free;
 		}
 		if (isBeyondEOF)
@@ -890,7 +885,9 @@
 	/* write back the new extents, inserting new extents if the new number
 	 * of extents is greater than the old number, and deleting extents if
 	 * the new number of extents is less than the old number */
-	udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
+	*err = udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
+	if (*err < 0)
+		goto out_free;
 
 	newblock = udf_get_pblock(inode->i_sb, newblocknum,
 				iinfo->i_location.partitionReferenceNum, 0);
@@ -1094,23 +1091,8 @@
 			blocksize - 1) >> blocksize_bits)))) {
 
 			if (((li->extLength & UDF_EXTENT_LENGTH_MASK) +
-				(lip1->extLength & UDF_EXTENT_LENGTH_MASK) +
-				blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) {
-				lip1->extLength = (lip1->extLength -
-						  (li->extLength &
-						   UDF_EXTENT_LENGTH_MASK) +
-						   UDF_EXTENT_LENGTH_MASK) &
-							~(blocksize - 1);
-				li->extLength = (li->extLength &
-						 UDF_EXTENT_FLAG_MASK) +
-						(UDF_EXTENT_LENGTH_MASK + 1) -
-						blocksize;
-				lip1->extLocation.logicalBlockNum =
-					li->extLocation.logicalBlockNum +
-					((li->extLength &
-						UDF_EXTENT_LENGTH_MASK) >>
-						blocksize_bits);
-			} else {
+			     (lip1->extLength & UDF_EXTENT_LENGTH_MASK) +
+			     blocksize - 1) <= UDF_EXTENT_LENGTH_MASK) {
 				li->extLength = lip1->extLength +
 					(((li->extLength &
 						UDF_EXTENT_LENGTH_MASK) +
@@ -1173,21 +1155,30 @@
 	}
 }
 
-static void udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr,
-			       int startnum, int endnum,
-			       struct extent_position *epos)
+static int udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr,
+			      int startnum, int endnum,
+			      struct extent_position *epos)
 {
 	int start = 0, i;
 	struct kernel_lb_addr tmploc;
 	uint32_t tmplen;
+	int err;
 
 	if (startnum > endnum) {
 		for (i = 0; i < (startnum - endnum); i++)
 			udf_delete_aext(inode, *epos);
 	} else if (startnum < endnum) {
 		for (i = 0; i < (endnum - startnum); i++) {
-			udf_insert_aext(inode, *epos, laarr[i].extLocation,
-					laarr[i].extLength);
+			err = udf_insert_aext(inode, *epos,
+					      laarr[i].extLocation,
+					      laarr[i].extLength);
+			/*
+			 * If we fail here, we are likely corrupting the extent
+			 * list and leaking blocks. At least stop early to
+			 * limit the damage.
+			 */
+			if (err < 0)
+				return err;
 			udf_next_aext(inode, epos, &laarr[i].extLocation,
 				      &laarr[i].extLength, 1);
 			start++;
@@ -1199,6 +1190,7 @@
 		udf_write_aext(inode, epos, &laarr[i].extLocation,
 			       laarr[i].extLength, 1);
 	}
+	return 0;
 }
 
 struct buffer_head *udf_bread(struct inode *inode, udf_pblk_t block,
@@ -1401,6 +1393,7 @@
 		ret = -EIO;
 		goto out;
 	}
+	iinfo->i_hidden = hidden_inode;
 	iinfo->i_unique = 0;
 	iinfo->i_lenEAttr = 0;
 	iinfo->i_lenExtents = 0;
@@ -1736,8 +1729,12 @@
 
 	if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0)
 		fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1);
-	else
-		fe->fileLinkCount = cpu_to_le16(inode->i_nlink);
+	else {
+		if (iinfo->i_hidden)
+			fe->fileLinkCount = cpu_to_le16(0);
+		else
+			fe->fileLinkCount = cpu_to_le16(inode->i_nlink);
+	}
 
 	fe->informationLength = cpu_to_le64(inode->i_size);
 
@@ -1908,8 +1905,13 @@
 	if (!inode)
 		return ERR_PTR(-ENOMEM);
 
-	if (!(inode->i_state & I_NEW))
+	if (!(inode->i_state & I_NEW)) {
+		if (UDF_I(inode)->i_hidden != hidden_inode) {
+			iput(inode);
+			return ERR_PTR(-EFSCORRUPTED);
+		}
 		return inode;
+	}
 
 	memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr));
 	err = udf_read_inode(inode, hidden_inode);
@@ -2223,12 +2225,13 @@
 	return etype;
 }
 
-static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos,
-			      struct kernel_lb_addr neloc, uint32_t nelen)
+static int udf_insert_aext(struct inode *inode, struct extent_position epos,
+			   struct kernel_lb_addr neloc, uint32_t nelen)
 {
 	struct kernel_lb_addr oeloc;
 	uint32_t oelen;
 	int8_t etype;
+	int err;
 
 	if (epos.bh)
 		get_bh(epos.bh);
@@ -2238,10 +2241,10 @@
 		neloc = oeloc;
 		nelen = (etype << 30) | oelen;
 	}
-	udf_add_aext(inode, &epos, &neloc, nelen, 1);
+	err = udf_add_aext(inode, &epos, &neloc, nelen, 1);
 	brelse(epos.bh);
 
-	return (nelen >> 30);
+	return err;
 }
 
 int8_t udf_delete_aext(struct inode *inode, struct extent_position epos)
diff --git a/kernel/fs/udf/namei.c b/kernel/fs/udf/namei.c
index aff5ca3..58120d2 100644
--- a/kernel/fs/udf/namei.c
+++ b/kernel/fs/udf/namei.c
@@ -1090,8 +1090,9 @@
 		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 @@
 
 	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);
diff --git a/kernel/fs/udf/super.c b/kernel/fs/udf/super.c
index c31c5c4..3fa6e48 100644
--- a/kernel/fs/udf/super.c
+++ b/kernel/fs/udf/super.c
@@ -147,6 +147,7 @@
 	ei->i_next_alloc_goal = 0;
 	ei->i_strat4096 = 0;
 	ei->i_streamdir = 0;
+	ei->i_hidden = 0;
 	init_rwsem(&ei->i_data_sem);
 	ei->cached_extent.lstart = -1;
 	spin_lock_init(&ei->i_extent_cache_lock);
diff --git a/kernel/fs/udf/truncate.c b/kernel/fs/udf/truncate.c
index 532cda9..036ebd8 100644
--- a/kernel/fs/udf/truncate.c
+++ b/kernel/fs/udf/truncate.c
@@ -120,60 +120,42 @@
 
 void udf_discard_prealloc(struct inode *inode)
 {
-	struct extent_position epos = { NULL, 0, {0, 0} };
+	struct extent_position epos = {};
+	struct extent_position prev_epos = {};
 	struct kernel_lb_addr eloc;
 	uint32_t elen;
 	uint64_t lbcount = 0;
 	int8_t etype = -1, netype;
-	int adsize;
 	struct udf_inode_info *iinfo = UDF_I(inode);
+	int bsize = 1 << inode->i_blkbits;
 
 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB ||
-	    inode->i_size == iinfo->i_lenExtents)
+	    ALIGN(inode->i_size, bsize) == ALIGN(iinfo->i_lenExtents, bsize))
 		return;
-
-	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
-		adsize = sizeof(struct short_ad);
-	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
-		adsize = sizeof(struct long_ad);
-	else
-		adsize = 0;
 
 	epos.block = iinfo->i_location;
 
 	/* Find the last extent in the file */
-	while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) {
-		etype = netype;
+	while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 0)) != -1) {
+		brelse(prev_epos.bh);
+		prev_epos = epos;
+		if (prev_epos.bh)
+			get_bh(prev_epos.bh);
+
+		etype = udf_next_aext(inode, &epos, &eloc, &elen, 1);
 		lbcount += elen;
 	}
 	if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
-		epos.offset -= adsize;
 		lbcount -= elen;
-		extent_trunc(inode, &epos, &eloc, etype, elen, 0);
-		if (!epos.bh) {
-			iinfo->i_lenAlloc =
-				epos.offset -
-				udf_file_entry_alloc_offset(inode);
-			mark_inode_dirty(inode);
-		} else {
-			struct allocExtDesc *aed =
-				(struct allocExtDesc *)(epos.bh->b_data);
-			aed->lengthAllocDescs =
-				cpu_to_le32(epos.offset -
-					    sizeof(struct allocExtDesc));
-			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
-			    UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
-				udf_update_tag(epos.bh->b_data, epos.offset);
-			else
-				udf_update_tag(epos.bh->b_data,
-					       sizeof(struct allocExtDesc));
-			mark_buffer_dirty_inode(epos.bh, inode);
-		}
+		udf_delete_aext(inode, prev_epos);
+		udf_free_blocks(inode->i_sb, inode, &eloc, 0,
+				DIV_ROUND_UP(elen, 1 << inode->i_blkbits));
 	}
 	/* This inode entry is in-memory only and thus we don't have to mark
 	 * the inode dirty */
 	iinfo->i_lenExtents = lbcount;
 	brelse(epos.bh);
+	brelse(prev_epos.bh);
 }
 
 static void udf_update_alloc_ext_desc(struct inode *inode,
diff --git a/kernel/fs/udf/udf_i.h b/kernel/fs/udf/udf_i.h
index 06ff700..312b7c9 100644
--- a/kernel/fs/udf/udf_i.h
+++ b/kernel/fs/udf/udf_i.h
@@ -44,7 +44,8 @@
 	unsigned		i_use : 1;	/* unallocSpaceEntry */
 	unsigned		i_strat4096 : 1;
 	unsigned		i_streamdir : 1;
-	unsigned		reserved : 25;
+	unsigned		i_hidden : 1;	/* hidden system inode */
+	unsigned		reserved : 24;
 	__u8			*i_data;
 	struct kernel_lb_addr	i_locStreamdir;
 	__u64			i_lenStreams;
diff --git a/kernel/fs/udf/udf_sb.h b/kernel/fs/udf/udf_sb.h
index 4fa6205..2205859 100644
--- a/kernel/fs/udf/udf_sb.h
+++ b/kernel/fs/udf/udf_sb.h
@@ -51,6 +51,8 @@
 #define MF_DUPLICATE_MD		0x01
 #define MF_MIRROR_FE_LOADED	0x02
 
+#define EFSCORRUPTED EUCLEAN
+
 struct udf_meta_data {
 	__u32	s_meta_file_loc;
 	__u32	s_mirror_file_loc;
diff --git a/kernel/fs/udf/unicode.c b/kernel/fs/udf/unicode.c
index 6225690..2142cbd 100644
--- a/kernel/fs/udf/unicode.c
+++ b/kernel/fs/udf/unicode.c
@@ -247,7 +247,7 @@
 	}
 
 	if (translate) {
-		if (str_o_len <= 2 && str_o[0] == '.' &&
+		if (str_o_len > 0 && str_o_len <= 2 && str_o[0] == '.' &&
 		    (str_o_len == 1 || str_o[1] == '.'))
 			needsCRC = 1;
 		if (needsCRC) {
diff --git a/kernel/fs/verity/enable.c b/kernel/fs/verity/enable.c
index bed2b10..dbabea7 100644
--- a/kernel/fs/verity/enable.c
+++ b/kernel/fs/verity/enable.c
@@ -391,25 +391,27 @@
 		goto out_drop_write;
 
 	err = enable_verity(filp, &arg);
-	if (err)
-		goto out_allow_write_access;
 
 	/*
-	 * Some pages of the file may have been evicted from pagecache after
-	 * being used in the Merkle tree construction, then read into pagecache
-	 * again by another process reading from the file concurrently.  Since
-	 * these pages didn't undergo verification against the file digest which
-	 * fs-verity now claims to be enforcing, we have to wipe the pagecache
-	 * to ensure that all future reads are verified.
+	 * We no longer drop the inode's pagecache after enabling verity.  This
+	 * used to be done to try to avoid a race condition where pages could be
+	 * evicted after being used in the Merkle tree construction, then
+	 * re-instantiated by a concurrent read.  Such pages are unverified, and
+	 * the backing storage could have filled them with different content, so
+	 * they shouldn't be used to fulfill reads once verity is enabled.
+	 *
+	 * But, dropping the pagecache has a big performance impact, and it
+	 * doesn't fully solve the race condition anyway.  So for those reasons,
+	 * and also because this race condition isn't very important relatively
+	 * speaking (especially for small-ish files, where the chance of a page
+	 * being used, evicted, *and* re-instantiated all while enabling verity
+	 * is quite small), we no longer drop the inode's pagecache.
 	 */
-	filemap_write_and_wait(inode->i_mapping);
-	invalidate_inode_pages2(inode->i_mapping);
 
 	/*
 	 * allow_write_access() is needed to pair with deny_write_access().
 	 * Regardless, the filesystem won't allow writing to verity files.
 	 */
-out_allow_write_access:
 	allow_write_access(filp);
 out_drop_write:
 	mnt_drop_write_file(filp);
diff --git a/kernel/fs/verity/signature.c b/kernel/fs/verity/signature.c
index e33f6c4..f823fb3 100644
--- a/kernel/fs/verity/signature.c
+++ b/kernel/fs/verity/signature.c
@@ -81,6 +81,22 @@
 		return 0;
 	}
 
+	if (fsverity_keyring->keys.nr_leaves_on_tree == 0) {
+		/*
+		 * The ".fs-verity" keyring is empty, due to builtin signatures
+		 * being supported by the kernel but not actually being used.
+		 * In this case, verify_pkcs7_signature() would always return an
+		 * error, usually ENOKEY.  It could also be EBADMSG if the
+		 * PKCS#7 is malformed, but that isn't very important to
+		 * distinguish.  So, just skip to ENOKEY to avoid the attack
+		 * surface of the PKCS#7 parser, which would otherwise be
+		 * reachable by any task able to execute FS_IOC_ENABLE_VERITY.
+		 */
+		fsverity_err(inode,
+			     "fs-verity keyring is empty, rejecting signed file!");
+		return -ENOKEY;
+	}
+
 	d = kzalloc(sizeof(*d) + hash_alg->digest_size, GFP_KERNEL);
 	if (!d)
 		return -ENOMEM;
diff --git a/kernel/fs/verity/verify.c b/kernel/fs/verity/verify.c
index 0adb970..10e4188 100644
--- a/kernel/fs/verity/verify.c
+++ b/kernel/fs/verity/verify.c
@@ -279,15 +279,15 @@
 int __init fsverity_init_workqueue(void)
 {
 	/*
-	 * Use an unbound workqueue to allow bios to be verified in parallel
-	 * even when they happen to complete on the same CPU.  This sacrifices
-	 * locality, but it's worthwhile since hashing is CPU-intensive.
+	 * Use a high-priority workqueue to prioritize verification work, which
+	 * blocks reads from completing, over regular application tasks.
 	 *
-	 * Also use a high-priority workqueue to prioritize verification work,
-	 * which blocks reads from completing, over regular application tasks.
+	 * For performance reasons, don't use an unbound workqueue.  Using an
+	 * unbound workqueue for crypto operations causes excessive scheduler
+	 * latency on ARM64.
 	 */
 	fsverity_read_workqueue = alloc_workqueue("fsverity_read_queue",
-						  WQ_UNBOUND | WQ_HIGHPRI,
+						  WQ_HIGHPRI,
 						  num_online_cpus());
 	if (!fsverity_read_workqueue)
 		return -ENOMEM;
diff --git a/kernel/fs/xattr.c b/kernel/fs/xattr.c
index f157f0b..8d71514 100644
--- a/kernel/fs/xattr.c
+++ b/kernel/fs/xattr.c
@@ -1049,7 +1049,7 @@
 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;
diff --git a/kernel/fs/xfs/libxfs/xfs_btree.c b/kernel/fs/xfs/libxfs/xfs_btree.c
index 24c7d30..0926363 100644
--- a/kernel/fs/xfs/libxfs/xfs_btree.c
+++ b/kernel/fs/xfs/libxfs/xfs_btree.c
@@ -3190,7 +3190,7 @@
 	struct xfs_btree_block	*block;	/* btree block */
 	struct xfs_buf		*bp;	/* buffer for block */
 	union xfs_btree_ptr	nptr;	/* new block ptr */
-	struct xfs_btree_cur	*ncur;	/* new btree cursor */
+	struct xfs_btree_cur	*ncur = NULL;	/* new btree cursor */
 	union xfs_btree_key	nkey;	/* new block key */
 	union xfs_btree_key	*lkey;
 	int			optr;	/* old key/record index */
@@ -3270,7 +3270,7 @@
 #ifdef DEBUG
 	error = xfs_btree_check_block(cur, block, level, bp);
 	if (error)
-		return error;
+		goto error0;
 #endif
 
 	/*
@@ -3290,7 +3290,7 @@
 		for (i = numrecs - ptr; i >= 0; i--) {
 			error = xfs_btree_debug_check_ptr(cur, pp, i, level);
 			if (error)
-				return error;
+				goto error0;
 		}
 
 		xfs_btree_shift_keys(cur, kp, 1, numrecs - ptr + 1);
@@ -3375,6 +3375,8 @@
 	return 0;
 
 error0:
+	if (ncur)
+		xfs_btree_del_cursor(ncur, error);
 	return error;
 }
 
diff --git a/kernel/fs/xfs/xfs_aops.c b/kernel/fs/xfs/xfs_aops.c
index 953de84..e341d65 100644
--- a/kernel/fs/xfs/xfs_aops.c
+++ b/kernel/fs/xfs/xfs_aops.c
@@ -39,33 +39,6 @@
 		XFS_I(ioend->io_inode)->i_d.di_size;
 }
 
-STATIC int
-xfs_setfilesize_trans_alloc(
-	struct iomap_ioend	*ioend)
-{
-	struct xfs_mount	*mp = XFS_I(ioend->io_inode)->i_mount;
-	struct xfs_trans	*tp;
-	int			error;
-
-	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp);
-	if (error)
-		return error;
-
-	ioend->io_private = tp;
-
-	/*
-	 * We may pass freeze protection with a transaction.  So tell lockdep
-	 * we released it.
-	 */
-	__sb_writers_release(ioend->io_inode->i_sb, SB_FREEZE_FS);
-	/*
-	 * We hand off the transaction to the completion thread now, so
-	 * clear the flag here.
-	 */
-	xfs_trans_clear_context(tp);
-	return 0;
-}
-
 /*
  * Update on-disk file size now that data has been written to disk.
  */
@@ -191,12 +164,10 @@
 		error = xfs_reflink_end_cow(ip, offset, size);
 	else if (ioend->io_type == IOMAP_UNWRITTEN)
 		error = xfs_iomap_write_unwritten(ip, offset, size, false);
-	else
-		ASSERT(!xfs_ioend_is_append(ioend) || ioend->io_private);
 
+	if (!error && xfs_ioend_is_append(ioend))
+		error = xfs_setfilesize(ip, ioend->io_offset, ioend->io_size);
 done:
-	if (ioend->io_private)
-		error = xfs_setfilesize_ioend(ioend, error);
 	iomap_finish_ioends(ioend, error);
 	memalloc_nofs_restore(nofs_flag);
 }
@@ -246,7 +217,7 @@
 
 static inline bool xfs_ioend_needs_workqueue(struct iomap_ioend *ioend)
 {
-	return ioend->io_private ||
+	return xfs_ioend_is_append(ioend) ||
 		ioend->io_type == IOMAP_UNWRITTEN ||
 		(ioend->io_flags & IOMAP_F_SHARED);
 }
@@ -258,8 +229,6 @@
 	struct iomap_ioend	*ioend = bio->bi_private;
 	struct xfs_inode	*ip = XFS_I(ioend->io_inode);
 	unsigned long		flags;
-
-	ASSERT(xfs_ioend_needs_workqueue(ioend));
 
 	spin_lock_irqsave(&ip->i_ioend_lock, flags);
 	if (list_empty(&ip->i_ioend_list))
@@ -509,14 +478,6 @@
 		status = xfs_reflink_convert_cow(XFS_I(ioend->io_inode),
 				ioend->io_offset, ioend->io_size);
 	}
-
-	/* Reserve log space if we might write beyond the on-disk inode size. */
-	if (!status &&
-	    ((ioend->io_flags & IOMAP_F_SHARED) ||
-	     ioend->io_type != IOMAP_UNWRITTEN) &&
-	    xfs_ioend_is_append(ioend) &&
-	    !ioend->io_private)
-		status = xfs_setfilesize_trans_alloc(ioend);
 
 	memalloc_nofs_restore(nofs_flag);
 
diff --git a/kernel/fs/xfs/xfs_bmap_util.c b/kernel/fs/xfs/xfs_bmap_util.c
index 7371a7f..fbab104 100644
--- a/kernel/fs/xfs/xfs_bmap_util.c
+++ b/kernel/fs/xfs/xfs_bmap_util.c
@@ -800,9 +800,6 @@
 			quota_flag = XFS_QMOPT_RES_REGBLKS;
 		}
 
-		/*
-		 * Allocate and setup the transaction.
-		 */
 		error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks,
 				resrtextents, 0, &tp);
 
@@ -830,9 +827,9 @@
 		if (error)
 			goto error0;
 
-		/*
-		 * Complete the transaction
-		 */
+		ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
+		xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+
 		error = xfs_trans_commit(tp);
 		xfs_iunlock(ip, XFS_ILOCK_EXCL);
 		if (error)
diff --git a/kernel/fs/xfs/xfs_buf_item_recover.c b/kernel/fs/xfs/xfs_buf_item_recover.c
index b374c9c..a053b0b 100644
--- a/kernel/fs/xfs/xfs_buf_item_recover.c
+++ b/kernel/fs/xfs/xfs_buf_item_recover.c
@@ -924,6 +924,16 @@
 	if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) {
 		trace_xfs_log_recover_buf_skip(log, buf_f);
 		xlog_recover_validate_buf_type(mp, bp, buf_f, NULLCOMMITLSN);
+
+		/*
+		 * We're skipping replay of this buffer log item due to the log
+		 * item LSN being behind the ondisk buffer.  Verify the buffer
+		 * contents since we aren't going to run the write verifier.
+		 */
+		if (bp->b_ops) {
+			bp->b_ops->verify_read(bp);
+			error = bp->b_error;
+		}
 		goto out_release;
 	}
 
diff --git a/kernel/fs/xfs/xfs_extent_busy.c b/kernel/fs/xfs/xfs_extent_busy.c
index 3991e59..ef17c1f 100644
--- a/kernel/fs/xfs/xfs_extent_busy.c
+++ b/kernel/fs/xfs/xfs_extent_busy.c
@@ -344,7 +344,6 @@
 	ASSERT(*len > 0);
 
 	spin_lock(&args->pag->pagb_lock);
-restart:
 	fbno = *bno;
 	flen = *len;
 	rbp = args->pag->pagb_tree.rb_node;
@@ -360,19 +359,6 @@
 			continue;
 		} else if (fbno >= bend) {
 			rbp = rbp->rb_right;
-			continue;
-		}
-
-		/*
-		 * If this is a metadata allocation, try to reuse the busy
-		 * extent instead of trimming the allocation.
-		 */
-		if (!(args->datatype & XFS_ALLOC_USERDATA) &&
-		    !(busyp->flags & XFS_EXTENT_BUSY_DISCARDED)) {
-			if (!xfs_extent_busy_update_extent(args->mp, args->pag,
-							  busyp, fbno, flen,
-							  false))
-				goto restart;
 			continue;
 		}
 
diff --git a/kernel/fs/xfs/xfs_file.c b/kernel/fs/xfs/xfs_file.c
index c904580..3bc6d1e 100644
--- a/kernel/fs/xfs/xfs_file.c
+++ b/kernel/fs/xfs/xfs_file.c
@@ -94,8 +94,6 @@
 		ip->i_d.di_flags &= ~XFS_DIFLAG_PREALLOC;
 
 	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-	if (flags & XFS_PREALLOC_SYNC)
-		xfs_trans_set_sync(tp);
 	return xfs_trans_commit(tp);
 }
 
@@ -852,7 +850,6 @@
 	struct inode		*inode = file_inode(file);
 	struct xfs_inode	*ip = XFS_I(inode);
 	long			error;
-	enum xfs_prealloc_flags	flags = 0;
 	uint			iolock = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
 	loff_t			new_size = 0;
 	bool			do_file_insert = false;
@@ -896,6 +893,10 @@
 		if (error)
 			goto out_unlock;
 	}
+
+	error = file_modified(file);
+	if (error)
+		goto out_unlock;
 
 	if (mode & FALLOC_FL_PUNCH_HOLE) {
 		error = xfs_free_file_space(ip, offset, len);
@@ -946,8 +947,6 @@
 		}
 		do_file_insert = true;
 	} else {
-		flags |= XFS_PREALLOC_SET;
-
 		if (!(mode & FALLOC_FL_KEEP_SIZE) &&
 		    offset + len > i_size_read(inode)) {
 			new_size = offset + len;
@@ -1000,13 +999,6 @@
 		}
 	}
 
-	if (file->f_flags & O_DSYNC)
-		flags |= XFS_PREALLOC_SYNC;
-
-	error = xfs_update_prealloc_flags(ip, flags);
-	if (error)
-		goto out_unlock;
-
 	/* Change file size if needed */
 	if (new_size) {
 		struct iattr iattr;
@@ -1024,8 +1016,14 @@
 	 * leave shifted extents past EOF and hence losing access to
 	 * the data that is contained within them.
 	 */
-	if (do_file_insert)
+	if (do_file_insert) {
 		error = xfs_insert_file_space(ip, offset, len);
+		if (error)
+			goto out_unlock;
+	}
+
+	if (file->f_flags & O_DSYNC)
+		error = xfs_log_force_inode(ip);
 
 out_unlock:
 	xfs_iunlock(ip, iolock);
diff --git a/kernel/fs/xfs/xfs_iops.c b/kernel/fs/xfs/xfs_iops.c
index 6a3026e..69fef29 100644
--- a/kernel/fs/xfs/xfs_iops.c
+++ b/kernel/fs/xfs/xfs_iops.c
@@ -595,37 +595,6 @@
 	return 0;
 }
 
-static void
-xfs_setattr_mode(
-	struct xfs_inode	*ip,
-	struct iattr		*iattr)
-{
-	struct inode		*inode = VFS_I(ip);
-	umode_t			mode = iattr->ia_mode;
-
-	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
-
-	inode->i_mode &= S_IFMT;
-	inode->i_mode |= mode & ~S_IFMT;
-}
-
-void
-xfs_setattr_time(
-	struct xfs_inode	*ip,
-	struct iattr		*iattr)
-{
-	struct inode		*inode = VFS_I(ip);
-
-	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
-
-	if (iattr->ia_valid & ATTR_ATIME)
-		inode->i_atime = iattr->ia_atime;
-	if (iattr->ia_valid & ATTR_CTIME)
-		inode->i_ctime = iattr->ia_ctime;
-	if (iattr->ia_valid & ATTR_MTIME)
-		inode->i_mtime = iattr->ia_mtime;
-}
-
 static int
 xfs_vn_change_ok(
 	struct dentry	*dentry,
@@ -741,16 +710,6 @@
 		}
 
 		/*
-		 * CAP_FSETID overrides the following restrictions:
-		 *
-		 * The set-user-ID and set-group-ID bits of a file will be
-		 * cleared upon successful return from chown()
-		 */
-		if ((inode->i_mode & (S_ISUID|S_ISGID)) &&
-		    !capable(CAP_FSETID))
-			inode->i_mode &= ~(S_ISUID|S_ISGID);
-
-		/*
 		 * Change the ownerships and register quota modifications
 		 * in the transaction.
 		 */
@@ -761,7 +720,6 @@
 				olddquot1 = xfs_qm_vop_chown(tp, ip,
 							&ip->i_udquot, udqp);
 			}
-			inode->i_uid = uid;
 		}
 		if (!gid_eq(igid, gid)) {
 			if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_GQUOTA_ON(mp)) {
@@ -772,15 +730,10 @@
 				olddquot2 = xfs_qm_vop_chown(tp, ip,
 							&ip->i_gdquot, gdqp);
 			}
-			inode->i_gid = gid;
 		}
 	}
 
-	if (mask & ATTR_MODE)
-		xfs_setattr_mode(ip, iattr);
-	if (mask & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME))
-		xfs_setattr_time(ip, iattr);
-
+	setattr_copy(inode, iattr);
 	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 
 	XFS_STATS_INC(mp, xs_ig_attrchg);
@@ -1025,11 +978,8 @@
 		xfs_inode_clear_eofblocks_tag(ip);
 	}
 
-	if (iattr->ia_valid & ATTR_MODE)
-		xfs_setattr_mode(ip, iattr);
-	if (iattr->ia_valid & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME))
-		xfs_setattr_time(ip, iattr);
-
+	ASSERT(!(iattr->ia_valid & (ATTR_UID | ATTR_GID)));
+	setattr_copy(inode, iattr);
 	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 
 	XFS_STATS_INC(mp, xs_ig_attrchg);
diff --git a/kernel/fs/xfs/xfs_iops.h b/kernel/fs/xfs/xfs_iops.h
index 4d24ff3..dd1bd03 100644
--- a/kernel/fs/xfs/xfs_iops.h
+++ b/kernel/fs/xfs/xfs_iops.h
@@ -18,7 +18,6 @@
  */
 #define XFS_ATTR_NOACL		0x01	/* Don't call posix_acl_chmod */
 
-extern void xfs_setattr_time(struct xfs_inode *ip, struct iattr *iattr);
 extern int xfs_setattr_nonsize(struct xfs_inode *ip, struct iattr *vap,
 			       int flags);
 extern int xfs_vn_setattr_nonsize(struct dentry *dentry, struct iattr *vap);
diff --git a/kernel/fs/xfs/xfs_mount.c b/kernel/fs/xfs/xfs_mount.c
index a2a5a0f..402cf82 100644
--- a/kernel/fs/xfs/xfs_mount.c
+++ b/kernel/fs/xfs/xfs_mount.c
@@ -126,7 +126,6 @@
 {
 	struct xfs_perag *pag = container_of(head, struct xfs_perag, rcu_head);
 
-	ASSERT(atomic_read(&pag->pag_ref) == 0);
 	kmem_free(pag);
 }
 
@@ -145,7 +144,7 @@
 		pag = radix_tree_delete(&mp->m_perag_tree, agno);
 		spin_unlock(&mp->m_perag_lock);
 		ASSERT(pag);
-		ASSERT(atomic_read(&pag->pag_ref) == 0);
+		XFS_IS_CORRUPT(pag->pag_mount, atomic_read(&pag->pag_ref) != 0);
 		xfs_iunlink_destroy(pag);
 		xfs_buf_hash_destroy(pag);
 		call_rcu(&pag->rcu_head, __xfs_free_perag);
diff --git a/kernel/fs/xfs/xfs_pnfs.c b/kernel/fs/xfs/xfs_pnfs.c
index f3082a9..053b999 100644
--- a/kernel/fs/xfs/xfs_pnfs.c
+++ b/kernel/fs/xfs/xfs_pnfs.c
@@ -164,10 +164,12 @@
 		 * that the blocks allocated and handed out to the client are
 		 * guaranteed to be present even after a server crash.
 		 */
-		error = xfs_update_prealloc_flags(ip,
-				XFS_PREALLOC_SET | XFS_PREALLOC_SYNC);
+		error = xfs_update_prealloc_flags(ip, XFS_PREALLOC_SET);
+		if (!error)
+			error = xfs_log_force_inode(ip);
 		if (error)
 			goto out_unlock;
+
 	} else {
 		xfs_iunlock(ip, lock_flags);
 	}
@@ -283,7 +285,8 @@
 	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
 	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 
-	xfs_setattr_time(ip, iattr);
+	ASSERT(!(iattr->ia_valid & (ATTR_UID | ATTR_GID)));
+	setattr_copy(inode, iattr);
 	if (update_isize) {
 		i_size_write(inode, iattr->ia_size);
 		ip->i_d.di_size = iattr->ia_size;
diff --git a/kernel/fs/xfs/xfs_qm.c b/kernel/fs/xfs/xfs_qm.c
index 64e5da3..3c17e0c 100644
--- a/kernel/fs/xfs/xfs_qm.c
+++ b/kernel/fs/xfs/xfs_qm.c
@@ -1318,8 +1318,15 @@
 
 	error = xfs_iwalk_threaded(mp, 0, 0, xfs_qm_dqusage_adjust, 0, true,
 			NULL);
-	if (error)
+	if (error) {
+		/*
+		 * The inode walk may have partially populated the dquot
+		 * caches.  We must purge them before disabling quota and
+		 * tearing down the quotainfo, or else the dquots will leak.
+		 */
+		xfs_qm_dqpurge_all(mp, XFS_QMOPT_QUOTALL);
 		goto error_return;
+	}
 
 	/*
 	 * We've made all the changes that we need to make incore.  Flush them
diff --git a/kernel/fs/xfs/xfs_trans_dquot.c b/kernel/fs/xfs/xfs_trans_dquot.c
index 288ea38..5ca210e 100644
--- a/kernel/fs/xfs/xfs_trans_dquot.c
+++ b/kernel/fs/xfs/xfs_trans_dquot.c
@@ -16,6 +16,7 @@
 #include "xfs_quota.h"
 #include "xfs_qm.h"
 #include "xfs_trace.h"
+#include "xfs_error.h"
 
 STATIC void	xfs_trans_alloc_dqinfo(xfs_trans_t *);
 
@@ -708,9 +709,11 @@
 					    XFS_TRANS_DQ_RES_INOS,
 					    ninos);
 	}
-	ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count);
-	ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count);
-	ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);
+
+	if (XFS_IS_CORRUPT(mp, dqp->q_blk.reserved < dqp->q_blk.count) ||
+	    XFS_IS_CORRUPT(mp, dqp->q_rtb.reserved < dqp->q_rtb.count) ||
+	    XFS_IS_CORRUPT(mp, dqp->q_ino.reserved < dqp->q_ino.count))
+		goto error_corrupt;
 
 	xfs_dqunlock(dqp);
 	return 0;
@@ -720,6 +723,10 @@
 	if (xfs_dquot_type(dqp) == XFS_DQTYPE_PROJ)
 		return -ENOSPC;
 	return -EDQUOT;
+error_corrupt:
+	xfs_dqunlock(dqp);
+	xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
+	return -EFSCORRUPTED;
 }
 
 
diff --git a/kernel/fs/zonefs/super.c b/kernel/fs/zonefs/super.c
index 57ab34b..e170da5 100644
--- a/kernel/fs/zonefs/super.c
+++ b/kernel/fs/zonefs/super.c
@@ -394,6 +394,10 @@
 			data_size = zonefs_check_zone_condition(inode, zone,
 								false, false);
 		}
+	} else if (sbi->s_mount_opts & ZONEFS_MNTOPT_ERRORS_RO &&
+		   data_size > isize) {
+		/* Do not expose garbage data */
+		data_size = isize;
 	}
 
 	/*
@@ -772,6 +776,24 @@
 
 	ret = submit_bio_wait(bio);
 
+	/*
+	 * If the file zone was written underneath the file system, the zone
+	 * write pointer may not be where we expect it to be, but the zone
+	 * append write can still succeed. So check manually that we wrote where
+	 * we intended to, that is, at zi->i_wpoffset.
+	 */
+	if (!ret) {
+		sector_t wpsector =
+			zi->i_zsector + (zi->i_wpoffset >> SECTOR_SHIFT);
+
+		if (bio->bi_iter.bi_sector != wpsector) {
+			zonefs_warn(inode->i_sb,
+				"Corrupted write pointer %llu for zone at %llu\n",
+				bio->bi_iter.bi_sector, zi->i_zsector);
+			ret = -EIO;
+		}
+	}
+
 	zonefs_file_write_dio_end_io(iocb, size, ret, 0);
 
 out_release:
diff --git a/kernel/include/acpi/apei.h b/kernel/include/acpi/apei.h
index 680f809..a6ac2e8 100644
--- a/kernel/include/acpi/apei.h
+++ b/kernel/include/acpi/apei.h
@@ -27,14 +27,16 @@
 extern int erst_disable;
 #ifdef CONFIG_ACPI_APEI_GHES
 extern bool ghes_disable;
+void __init ghes_init(void);
 #else
 #define ghes_disable 1
+static inline void ghes_init(void) { }
 #endif
 
 #ifdef CONFIG_ACPI_APEI
 void __init acpi_hest_init(void);
 #else
-static inline void acpi_hest_init(void) { return; }
+static inline void acpi_hest_init(void) { }
 #endif
 
 typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data);
diff --git a/kernel/include/asm-generic/bugs.h b/kernel/include/asm-generic/bugs.h
deleted file mode 100644
index 6902183..0000000
--- a/kernel/include/asm-generic/bugs.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_GENERIC_BUGS_H
-#define __ASM_GENERIC_BUGS_H
-/*
- * This file is included by 'init/main.c' to check for
- * architecture-dependent bugs.
- */
-
-static inline void check_bugs(void) { }
-
-#endif	/* __ASM_GENERIC_BUGS_H */
diff --git a/kernel/include/asm-generic/io.h b/kernel/include/asm-generic/io.h
index 9ea83d8..dcbd410 100644
--- a/kernel/include/asm-generic/io.h
+++ b/kernel/include/asm-generic/io.h
@@ -190,7 +190,7 @@
 	u64 val;
 
 	__io_br();
-	val = __le64_to_cpu(__raw_readq(addr));
+	val = __le64_to_cpu((__le64 __force)__raw_readq(addr));
 	__io_ar(val);
 	return val;
 }
@@ -233,7 +233,7 @@
 static inline void writeq(u64 value, volatile void __iomem *addr)
 {
 	__io_bw();
-	__raw_writeq(__cpu_to_le64(value), addr);
+	__raw_writeq((u64 __force)__cpu_to_le64(value), addr);
 	__io_aw();
 }
 #endif
diff --git a/kernel/include/asm-generic/pgtable-nop4d.h b/kernel/include/asm-generic/pgtable-nop4d.h
index ce2cbb3..2f1d0aa 100644
--- a/kernel/include/asm-generic/pgtable-nop4d.h
+++ b/kernel/include/asm-generic/pgtable-nop4d.h
@@ -42,7 +42,7 @@
 #define __p4d(x)				((p4d_t) { __pgd(x) })
 
 #define pgd_page(pgd)				(p4d_page((p4d_t){ pgd }))
-#define pgd_page_vaddr(pgd)			(p4d_page_vaddr((p4d_t){ pgd }))
+#define pgd_page_vaddr(pgd)			((unsigned long)(p4d_pgtable((p4d_t){ pgd })))
 
 /*
  * allocating and freeing a p4d is trivial: the 1-entry p4d is
diff --git a/kernel/include/asm-generic/pgtable-nopmd.h b/kernel/include/asm-generic/pgtable-nopmd.h
index 3e13acd..10789cf 100644
--- a/kernel/include/asm-generic/pgtable-nopmd.h
+++ b/kernel/include/asm-generic/pgtable-nopmd.h
@@ -51,7 +51,7 @@
 #define __pmd(x)				((pmd_t) { __pud(x) } )
 
 #define pud_page(pud)				(pmd_page((pmd_t){ pud }))
-#define pud_page_vaddr(pud)			(pmd_page_vaddr((pmd_t){ pud }))
+#define pud_pgtable(pud)			((pmd_t *)(pmd_page_vaddr((pmd_t){ pud })))
 
 /*
  * allocating and freeing a pmd is trivial: the 1-entry pmd is
diff --git a/kernel/include/asm-generic/pgtable-nopud.h b/kernel/include/asm-generic/pgtable-nopud.h
index a9d751f..eb70c6d 100644
--- a/kernel/include/asm-generic/pgtable-nopud.h
+++ b/kernel/include/asm-generic/pgtable-nopud.h
@@ -49,7 +49,7 @@
 #define __pud(x)				((pud_t) { __p4d(x) })
 
 #define p4d_page(p4d)				(pud_page((pud_t){ p4d }))
-#define p4d_page_vaddr(p4d)			(pud_page_vaddr((pud_t){ p4d }))
+#define p4d_pgtable(p4d)			((pud_t *)(pud_pgtable((pud_t){ p4d })))
 
 /*
  * allocating and freeing a pud is trivial: the 1-entry pud is
diff --git a/kernel/include/asm-generic/vmlinux.lds.h b/kernel/include/asm-generic/vmlinux.lds.h
index 5317ac9..64d9da1 100644
--- a/kernel/include/asm-generic/vmlinux.lds.h
+++ b/kernel/include/asm-generic/vmlinux.lds.h
@@ -947,7 +947,12 @@
 #define TRACEDATA
 #endif
 
+/*
+ * Discard .note.GNU-stack, which is emitted as PROGBITS by the compiler.
+ * Otherwise, the type of .notes section would become PROGBITS instead of NOTES.
+ */
 #define NOTES								\
+	/DISCARD/ : { *(.note.GNU-stack) }				\
 	.notes : AT(ADDR(.notes) - LOAD_OFFSET) {			\
 		__start_notes = .;					\
 		KEEP(*(.note.*))					\
diff --git a/kernel/include/asm-generic/word-at-a-time.h b/kernel/include/asm-generic/word-at-a-time.h
index 20c93f0..95a1d21 100644
--- a/kernel/include/asm-generic/word-at-a-time.h
+++ b/kernel/include/asm-generic/word-at-a-time.h
@@ -38,7 +38,7 @@
 	return (mask >> 8) ? byte : byte + 1;
 }
 
-static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c)
+static inline unsigned long has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c)
 {
 	unsigned long rhs = val | c->low_bits;
 	*data = rhs;
diff --git a/kernel/include/drm/drm_bridge.h b/kernel/include/drm/drm_bridge.h
index 2195daa..055486e 100644
--- a/kernel/include/drm/drm_bridge.h
+++ b/kernel/include/drm/drm_bridge.h
@@ -427,11 +427,11 @@
 	 *
 	 * The returned array must be allocated with kmalloc() and will be
 	 * freed by the caller. If the allocation fails, NULL should be
-	 * returned. num_output_fmts must be set to the returned array size.
+	 * returned. num_input_fmts must be set to the returned array size.
 	 * Formats listed in the returned array should be listed in decreasing
 	 * preference order (the core will try all formats until it finds one
 	 * that works). When the format is not supported NULL should be
-	 * returned and num_output_fmts should be set to 0.
+	 * returned and num_input_fmts should be set to 0.
 	 *
 	 * This method is called on all elements of the bridge chain as part of
 	 * the bus format negotiation process that happens in
diff --git a/kernel/include/drm/drm_mipi_dsi.h b/kernel/include/drm/drm_mipi_dsi.h
index 952f475..05592c1 100644
--- a/kernel/include/drm/drm_mipi_dsi.h
+++ b/kernel/include/drm/drm_mipi_dsi.h
@@ -295,6 +295,10 @@
 					u16 brightness);
 int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi,
 					u16 *brightness);
+int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi,
+					     u16 brightness);
+int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
+					     u16 *brightness);
 
 /**
  * struct mipi_dsi_driver - DSI driver
diff --git a/kernel/include/dt-bindings/clock/imx8mp-clock.h b/kernel/include/dt-bindings/clock/imx8mp-clock.h
index e8d68fb..d7e5132 100644
--- a/kernel/include/dt-bindings/clock/imx8mp-clock.h
+++ b/kernel/include/dt-bindings/clock/imx8mp-clock.h
@@ -321,8 +321,16 @@
 #define IMX8MP_CLK_AUDIO_AXI			310
 #define IMX8MP_CLK_HSIO_AXI			311
 #define IMX8MP_CLK_MEDIA_ISP			312
+#define IMX8MP_CLK_MEDIA_DISP2_PIX		313
+#define IMX8MP_CLK_CLKOUT1_SEL			314
+#define IMX8MP_CLK_CLKOUT1_DIV			315
+#define IMX8MP_CLK_CLKOUT1			316
+#define IMX8MP_CLK_CLKOUT2_SEL			317
+#define IMX8MP_CLK_CLKOUT2_DIV			318
+#define IMX8MP_CLK_CLKOUT2			319
+#define IMX8MP_CLK_USB_SUSP			320
 
-#define IMX8MP_CLK_END				313
+#define IMX8MP_CLK_END				321
 
 #define IMX8MP_CLK_AUDIOMIX_SAI1_IPG		0
 #define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1		1
diff --git a/kernel/include/dt-bindings/iio/addac/adi,ad74413r.h b/kernel/include/dt-bindings/iio/addac/adi,ad74413r.h
new file mode 100644
index 0000000..204f92b
--- /dev/null
+++ b/kernel/include/dt-bindings/iio/addac/adi,ad74413r.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _DT_BINDINGS_ADI_AD74413R_H
+#define _DT_BINDINGS_ADI_AD74413R_H
+
+#define CH_FUNC_HIGH_IMPEDANCE			0x0
+#define CH_FUNC_VOLTAGE_OUTPUT			0x1
+#define CH_FUNC_CURRENT_OUTPUT			0x2
+#define CH_FUNC_VOLTAGE_INPUT			0x3
+#define CH_FUNC_CURRENT_INPUT_EXT_POWER		0x4
+#define CH_FUNC_CURRENT_INPUT_LOOP_POWER	0x5
+#define CH_FUNC_RESISTANCE_INPUT		0x6
+#define CH_FUNC_DIGITAL_INPUT_LOGIC		0x7
+#define CH_FUNC_DIGITAL_INPUT_LOOP_POWER	0x8
+#define CH_FUNC_CURRENT_INPUT_EXT_POWER_HART	0x9
+#define CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART	0xA
+
+#define CH_FUNC_MIN	CH_FUNC_HIGH_IMPEDANCE
+#define CH_FUNC_MAX	CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART
+
+#endif /* _DT_BINDINGS_ADI_AD74413R_H */
diff --git a/kernel/include/dt-bindings/soc/rockchip,boot-mode.h b/kernel/include/dt-bindings/soc/rockchip,boot-mode.h
index ec4e5dd..a0f63a0 100644
--- a/kernel/include/dt-bindings/soc/rockchip,boot-mode.h
+++ b/kernel/include/dt-bindings/soc/rockchip,boot-mode.h
@@ -22,5 +22,7 @@
 #define BOOT_UMS		(REBOOT_FLAG + 12)
 /* reboot system quiescent */
 #define BOOT_QUIESCENT		(REBOOT_FLAG + 14)
+/* reboot by panic and capture ramdump in uboot through usb */
+#define BOOT_WINUSB		(REBOOT_FLAG + 15)
 
 #endif
diff --git a/kernel/include/dt-bindings/soc/rockchip-csu.h b/kernel/include/dt-bindings/soc/rockchip-csu.h
new file mode 100644
index 0000000..8b04425
--- /dev/null
+++ b/kernel/include/dt-bindings/soc/rockchip-csu.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co. Ltd.
+ * Author: Finley Xiao <finley.xiao@rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_ROCKCHIP_CSU_H
+#define _DT_BINDINGS_ROCKCHIP_CSU_H
+
+#define CSU_GMAC_ACLK		0
+#define CSU_GMAC_PCLK		1
+#define CSU_VOP_ACLK		2
+#define CSU_MCU_CLK		3
+
+#endif
diff --git a/kernel/include/dt-bindings/soc/rockchip-system-status.h b/kernel/include/dt-bindings/soc/rockchip-system-status.h
index 5136481..6a0d198 100644
--- a/kernel/include/dt-bindings/soc/rockchip-system-status.h
+++ b/kernel/include/dt-bindings/soc/rockchip-system-status.h
@@ -37,6 +37,7 @@
 #define SYS_STATUS_HDMIRX	(1 << 18)
 #define SYS_STATUS_VIDEO_SVEP	(1 << 19)
 #define SYS_STATUS_VIDEO_4K_60P	(1 << 20)
+#define SYS_STATUS_DEEP_SUSPEND	(1 << 21)
 
 #define SYS_STATUS_VIDEO	(SYS_STATUS_VIDEO_4K | \
 				 SYS_STATUS_VIDEO_1080P | \
diff --git a/kernel/include/dt-bindings/suspend/rockchip-rv1106.h b/kernel/include/dt-bindings/suspend/rockchip-rv1106.h
new file mode 100644
index 0000000..3e3e6ce
--- /dev/null
+++ b/kernel/include/dt-bindings/suspend/rockchip-rv1106.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __DT_BINDINGS_RV1106_PM_H__
+#define __DT_BINDINGS_RV1106_PM_H__
+/******************************bits ops************************************/
+
+#ifndef BIT
+#define BIT(nr)				(1 << (nr))
+#endif
+
+/* all plls except ddr's pll*/
+#define RKPM_SLP_32K_EXT		BIT(24)
+#define RKPM_SLP_TIME_OUT_WKUP		BIT(25)
+#define RKPM_SLP_PMU_DBG		BIT(26)
+
+/* the wake up source */
+#define RKPM_CPU_WKUP_EN		BIT(0)
+#define RKPM_GPIO_WKUP_EN		BIT(1)
+#define RKPM_SDMMC_WKUP_EN		BIT(2)
+#define RKPM_SDIO_WKUP_EN		BIT(3)
+#define RKPM_USB_WKUP_EN		BIT(4)
+#define RKPM_TIMER_WKUP_EN		BIT(5)
+#define RKPM_TIME_OUT_WKUP_EN		BIT(6)
+#define RKPM_PMU_SFT_WKUP_EN		BIT(7)
+
+/* io config */
+#define RKPM_IO_CFG_IOMUX_SFT		0
+#define RKPM_IO_CFG_GPIO_DIR_SFT	8
+#define RKPM_IO_CFG_GPIO_LVL_SFT	9
+#define RKPM_IO_CFG_PULL_SFT		10
+#define RKPM_IO_CFG_ID_SFT		16
+
+#define RKPM_IO_CFG_IOMUX_MSK		0x3f
+#define RKPM_IO_CFG_GPIO_DIR_MSK	0x1
+#define RKPM_IO_CFG_GPIO_LVL_MSK	0x1
+#define RKPM_IO_CFG_PULL_MSK		0x3
+#define RKPM_IO_CFG_ID_MSK		0xffff
+
+#define RKPM_IO_CFG_IOMUX_GPIO_VAL	0
+#define RKPM_IO_CFG_GPIO_DIR_INPUT_VAL	0
+#define RKPM_IO_CFG_GPIO_DIR_OUTPUT_VAL	1
+#define RKPM_IO_CFG_GPIO_LVL_LOW_VAL	0
+#define RKPM_IO_CFG_GPIO_LVL_HIGH_VAL	1
+#define RKPM_IO_CFG_PULL_NONE_VAL	0
+#define RKPM_IO_CFG_PULL_UP_VAL		1
+#define RKPM_IO_CFG_PULL_DOWN_VAL	2
+
+#define RKPM_IO_CFG_IOMUX(func)		((func) << RKPM_IO_CFG_IOMUX_SFT)
+#define RKPM_IO_CFG_GPIO_DIR_INPUT	\
+	(RKPM_IO_CFG_GPIO_DIR_INPUT_VAL << RKPM_IO_CFG_GPIO_DIR_SFT)
+#define RKPM_IO_CFG_GPIO_DIR_OUTPUT	\
+	(RKPM_IO_CFG_GPIO_DIR_OUTPUT_VAL << RKPM_IO_CFG_GPIO_DIR_SFT)
+#define RKPM_IO_CFG_GPIO_LVL_LOW	\
+	(RKPM_IO_CFG_GPIO_LVL_LOW_VAL << RKPM_IO_CFG_GPIO_LVL_SFT)
+#define RKPM_IO_CFG_GPIO_LVL_HIGH	\
+	(RKPM_IO_CFG_GPIO_LVL_HIGH_VAL << RKPM_IO_CFG_GPIO_LVL_SFT)
+#define RKPM_IO_CFG_PULL_NONE		\
+	(RKPM_IO_CFG_PULL_NONE_VAL << RKPM_IO_CFG_PULL_SFT)
+#define RKPM_IO_CFG_PULL_UP		\
+	(RKPM_IO_CFG_PULL_UP_VAL << RKPM_IO_CFG_PULL_SFT)
+#define RKPM_IO_CFG_PULL_DOWN		\
+	(RKPM_IO_CFG_PULL_DOWN_VAL << RKPM_IO_CFG_PULL_SFT)
+#define RKPM_IO_CFG_ID(id)		((id) << RKPM_IO_CFG_ID_SFT)
+#define RKPM_IO_CFG_IOMUX_GPIO		\
+	RKPM_IO_CFG_IOMUX(RKPM_IO_CFG_IOMUX_GPIO_VAL)
+
+#define RKPM_IO_CFG_GET_IOMUX(cfg)	\
+	(((cfg) >> RKPM_IO_CFG_IOMUX_SFT) & RKPM_IO_CFG_IOMUX_MSK)
+#define RKPM_IO_CFG_GET_GPIO_DIR(cfg)	\
+	(((cfg) >> RKPM_IO_CFG_GPIO_DIR_SFT) & RKPM_IO_CFG_GPIO_DIR_MSK)
+#define RKPM_IO_CFG_GET_GPIO_LVL(cfg)	\
+	(((cfg) >> RKPM_IO_CFG_GPIO_LVL_SFT) & RKPM_IO_CFG_GPIO_LVL_MSK)
+#define RKPM_IO_CFG_GET_PULL(cfg)	\
+	(((cfg) >> RKPM_IO_CFG_PULL_SFT) & RKPM_IO_CFG_PULL_MSK)
+#define RKPM_IO_CFG_GET_ID(cfg)		\
+	(((cfg) >> RKPM_IO_CFG_ID_SFT) & RKPM_IO_CFG_ID_MSK)
+
+#endif
diff --git a/kernel/include/linux/acpi.h b/kernel/include/linux/acpi.h
index b24659f..2cf063e 100644
--- a/kernel/include/linux/acpi.h
+++ b/kernel/include/linux/acpi.h
@@ -1001,6 +1001,7 @@
 int acpi_subsys_runtime_suspend(struct device *dev);
 int acpi_subsys_runtime_resume(struct device *dev);
 int acpi_dev_pm_attach(struct device *dev, bool power_on);
+bool acpi_storage_d3(struct device *dev);
 #else
 static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; }
 static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; }
@@ -1008,6 +1009,10 @@
 {
 	return 0;
 }
+static inline bool acpi_storage_d3(struct device *dev)
+{
+	return false;
+}
 #endif
 
 #if defined(CONFIG_ACPI) && defined(CONFIG_PM_SLEEP)
diff --git a/kernel/include/linux/acpi_iort.h b/kernel/include/linux/acpi_iort.h
index 1a12baa..136dba9 100644
--- a/kernel/include/linux/acpi_iort.h
+++ b/kernel/include/linux/acpi_iort.h
@@ -21,6 +21,7 @@
  */
 #define IORT_SMMU_V3_PMCG_GENERIC        0x00000000 /* Generic SMMUv3 PMCG */
 #define IORT_SMMU_V3_PMCG_HISI_HIP08     0x00000001 /* HiSilicon HIP08 PMCG */
+#define IORT_SMMU_V3_PMCG_HISI_HIP09     0x00000002 /* HiSilicon HIP09 PMCG */
 
 int iort_register_domain_token(int trans_id, phys_addr_t base,
 			       struct fwnode_handle *fw_node);
diff --git a/kernel/include/linux/arm_sdei.h b/kernel/include/linux/arm_sdei.h
index af708fe..8da6559 100644
--- a/kernel/include/linux/arm_sdei.h
+++ b/kernel/include/linux/arm_sdei.h
@@ -93,9 +93,13 @@
 /* For use by arch code when CPU hotplug notifiers are not appropriate. */
 int sdei_mask_local_cpu(void);
 int sdei_unmask_local_cpu(void);
+void __init sdei_init(void);
+void sdei_handler_abort(void);
 #else
 static inline int sdei_mask_local_cpu(void) { return 0; }
 static inline int sdei_unmask_local_cpu(void) { return 0; }
+static inline void sdei_init(void) { }
+static inline void sdei_handler_abort(void) { }
 #endif /* CONFIG_ARM_SDE_INTERFACE */
 
 
diff --git a/kernel/include/linux/blk-crypto.h b/kernel/include/linux/blk-crypto.h
index c495572..d89f521 100644
--- a/kernel/include/linux/blk-crypto.h
+++ b/kernel/include/linux/blk-crypto.h
@@ -104,8 +104,8 @@
 int blk_crypto_start_using_key(const struct blk_crypto_key *key,
 			       struct request_queue *q);
 
-int blk_crypto_evict_key(struct request_queue *q,
-			 const struct blk_crypto_key *key);
+void blk_crypto_evict_key(struct request_queue *q,
+			  const struct blk_crypto_key *key);
 
 bool blk_crypto_config_supported(struct request_queue *q,
 				 const struct blk_crypto_config *cfg);
diff --git a/kernel/include/linux/bootconfig.h b/kernel/include/linux/bootconfig.h
index 6bdd94c..a6dfae4 100644
--- a/kernel/include/linux/bootconfig.h
+++ b/kernel/include/linux/bootconfig.h
@@ -49,7 +49,7 @@
 /* Maximum size of boot config is 32KB - 1 */
 #define XBC_DATA_MAX	(XBC_VALUE - 1)
 
-#define XBC_NODE_MAX	1024
+#define XBC_NODE_MAX	8192
 #define XBC_KEYLEN_MAX	256
 #define XBC_DEPTH_MAX	16
 
diff --git a/kernel/include/linux/bpf.h b/kernel/include/linux/bpf.h
index c24d077..b6a88d8 100644
--- a/kernel/include/linux/bpf.h
+++ b/kernel/include/linux/bpf.h
@@ -740,7 +740,7 @@
 static inline struct bpf_trampoline *bpf_trampoline_get(u64 key,
 							struct bpf_attach_target_info *tgt_info)
 {
-	return ERR_PTR(-EOPNOTSUPP);
+	return NULL;
 }
 static inline void bpf_trampoline_put(struct bpf_trampoline *tr) {}
 #define DEFINE_BPF_DISPATCHER(name)
diff --git a/kernel/include/linux/btf_ids.h b/kernel/include/linux/btf_ids.h
index 57890b3..eca91e7 100644
--- a/kernel/include/linux/btf_ids.h
+++ b/kernel/include/linux/btf_ids.h
@@ -38,7 +38,7 @@
 	____BTF_ID(symbol)
 
 #define __ID(prefix) \
-	__PASTE(prefix, __COUNTER__)
+	__PASTE(__PASTE(prefix, __COUNTER__), __LINE__)
 
 /*
  * The BTF_ID defines unique symbol for each ID pointing
diff --git a/kernel/include/linux/ceph/msgr.h b/kernel/include/linux/ceph/msgr.h
index 9e50aed..7bde0af 100644
--- a/kernel/include/linux/ceph/msgr.h
+++ b/kernel/include/linux/ceph/msgr.h
@@ -61,11 +61,18 @@
  * entity_addr -- network address
  */
 struct ceph_entity_addr {
-	__le32 type;
+	__le32 type;  /* CEPH_ENTITY_ADDR_TYPE_* */
 	__le32 nonce;  /* unique id for process (e.g. pid) */
 	struct sockaddr_storage in_addr;
 } __attribute__ ((packed));
 
+static inline bool ceph_addr_equal_no_type(const struct ceph_entity_addr *lhs,
+					   const struct ceph_entity_addr *rhs)
+{
+	return !memcmp(&lhs->in_addr, &rhs->in_addr, sizeof(lhs->in_addr)) &&
+	       lhs->nonce == rhs->nonce;
+}
+
 struct ceph_entity_inst {
 	struct ceph_entity_name name;
 	struct ceph_entity_addr addr;
diff --git a/kernel/include/linux/cgroup.h b/kernel/include/linux/cgroup.h
index 00b390f..3c0b5b3 100644
--- a/kernel/include/linux/cgroup.h
+++ b/kernel/include/linux/cgroup.h
@@ -455,6 +455,7 @@
 extern spinlock_t css_set_lock;
 #define task_css_set_check(task, __c)					\
 	rcu_dereference_check((task)->cgroups,				\
+		rcu_read_lock_sched_held() ||				\
 		lockdep_is_held(&cgroup_mutex) ||			\
 		lockdep_is_held(&css_set_lock) ||			\
 		((task)->flags & PF_EXITING) || (__c))
@@ -790,11 +791,9 @@
 
 	cpuacct_charge(task, delta_exec);
 
-	rcu_read_lock();
 	cgrp = task_dfl_cgroup(task);
 	if (cgroup_parent(cgrp))
 		__cgroup_account_cputime(cgrp, delta_exec);
-	rcu_read_unlock();
 }
 
 static inline void cgroup_account_cputime_field(struct task_struct *task,
diff --git a/kernel/include/linux/clk.h b/kernel/include/linux/clk.h
index 4ac766d..9489ac4 100644
--- a/kernel/include/linux/clk.h
+++ b/kernel/include/linux/clk.h
@@ -183,6 +183,39 @@
  */
 bool clk_is_match(const struct clk *p, const struct clk *q);
 
+/**
+ * clk_rate_exclusive_get - get exclusivity over the rate control of a
+ *                          producer
+ * @clk: clock source
+ *
+ * This function allows drivers to get exclusive control over the rate of a
+ * provider. It prevents any other consumer to execute, even indirectly,
+ * opereation which could alter the rate of the provider or cause glitches
+ *
+ * If exlusivity is claimed more than once on clock, even by the same driver,
+ * the rate effectively gets locked as exclusivity can't be preempted.
+ *
+ * Must not be called from within atomic context.
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_rate_exclusive_get(struct clk *clk);
+
+/**
+ * clk_rate_exclusive_put - release exclusivity over the rate control of a
+ *                          producer
+ * @clk: clock source
+ *
+ * This function allows drivers to release the exclusivity it previously got
+ * from clk_rate_exclusive_get()
+ *
+ * The caller must balance the number of clk_rate_exclusive_get() and
+ * clk_rate_exclusive_put() calls.
+ *
+ * Must not be called from within atomic context.
+ */
+void clk_rate_exclusive_put(struct clk *clk);
+
 #else
 
 static inline int clk_notifier_register(struct clk *clk,
@@ -235,6 +268,13 @@
 {
 	return p == q;
 }
+
+static inline int clk_rate_exclusive_get(struct clk *clk)
+{
+	return 0;
+}
+
+static inline void clk_rate_exclusive_put(struct clk *clk) {}
 
 #endif
 
@@ -437,6 +477,47 @@
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
 /**
+ * devm_clk_get_prepared - devm_clk_get() + clk_prepare()
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Context: May sleep.
+ *
+ * Return: a struct clk corresponding to the clock producer, or
+ * valid IS_ERR() condition containing errno.  The implementation
+ * uses @dev and @id to determine the clock consumer, and thereby
+ * the clock producer.  (IOW, @id may be identical strings, but
+ * clk_get may return different clock producers depending on @dev.)
+ *
+ * The returned clk (if valid) is prepared. Drivers must however assume
+ * that the clock is not enabled.
+ *
+ * The clock will automatically be unprepared and freed when the device
+ * is unbound from the bus.
+ */
+struct clk *devm_clk_get_prepared(struct device *dev, const char *id);
+
+/**
+ * devm_clk_get_enabled - devm_clk_get() + clk_prepare_enable()
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Context: May sleep.
+ *
+ * Return: a struct clk corresponding to the clock producer, or
+ * valid IS_ERR() condition containing errno.  The implementation
+ * uses @dev and @id to determine the clock consumer, and thereby
+ * the clock producer.  (IOW, @id may be identical strings, but
+ * clk_get may return different clock producers depending on @dev.)
+ *
+ * The returned clk (if valid) is prepared and enabled.
+ *
+ * The clock will automatically be disabled, unprepared and freed
+ * when the device is unbound from the bus.
+ */
+struct clk *devm_clk_get_enabled(struct device *dev, const char *id);
+
+/**
  * devm_clk_get_optional - lookup and obtain a managed reference to an optional
  *			   clock producer.
  * @dev: device for clock "consumer"
@@ -446,6 +527,50 @@
  * In this case, instead of returning -ENOENT, the function returns NULL.
  */
 struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
+/**
+ * devm_clk_get_optional_prepared - devm_clk_get_optional() + clk_prepare()
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Context: May sleep.
+ *
+ * Return: a struct clk corresponding to the clock producer, or
+ * valid IS_ERR() condition containing errno.  The implementation
+ * uses @dev and @id to determine the clock consumer, and thereby
+ * the clock producer.  If no such clk is found, it returns NULL
+ * which serves as a dummy clk.  That's the only difference compared
+ * to devm_clk_get_prepared().
+ *
+ * The returned clk (if valid) is prepared. Drivers must however
+ * assume that the clock is not enabled.
+ *
+ * The clock will automatically be unprepared and freed when the
+ * device is unbound from the bus.
+ */
+struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id);
+
+/**
+ * devm_clk_get_optional_enabled - devm_clk_get_optional() +
+ *                                 clk_prepare_enable()
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Context: May sleep.
+ *
+ * Return: a struct clk corresponding to the clock producer, or
+ * valid IS_ERR() condition containing errno.  The implementation
+ * uses @dev and @id to determine the clock consumer, and thereby
+ * the clock producer.  If no such clk is found, it returns NULL
+ * which serves as a dummy clk.  That's the only difference compared
+ * to devm_clk_get_enabled().
+ *
+ * The returned clk (if valid) is prepared and enabled.
+ *
+ * The clock will automatically be disabled, unprepared and freed
+ * when the device is unbound from the bus.
+ */
+struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id);
 
 /**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
@@ -463,38 +588,6 @@
  */
 struct clk *devm_get_clk_from_child(struct device *dev,
 				    struct device_node *np, const char *con_id);
-/**
- * clk_rate_exclusive_get - get exclusivity over the rate control of a
- *                          producer
- * @clk: clock source
- *
- * This function allows drivers to get exclusive control over the rate of a
- * provider. It prevents any other consumer to execute, even indirectly,
- * opereation which could alter the rate of the provider or cause glitches
- *
- * If exlusivity is claimed more than once on clock, even by the same driver,
- * the rate effectively gets locked as exclusivity can't be preempted.
- *
- * Must not be called from within atomic context.
- *
- * Returns success (0) or negative errno.
- */
-int clk_rate_exclusive_get(struct clk *clk);
-
-/**
- * clk_rate_exclusive_put - release exclusivity over the rate control of a
- *                          producer
- * @clk: clock source
- *
- * This function allows drivers to release the exclusivity it previously got
- * from clk_rate_exclusive_get()
- *
- * The caller must balance the number of clk_rate_exclusive_get() and
- * clk_rate_exclusive_put() calls.
- *
- * Must not be called from within atomic context.
- */
-void clk_rate_exclusive_put(struct clk *clk);
 
 /**
  * clk_enable - inform the system when the clock source should be running.
@@ -791,8 +884,32 @@
 	return NULL;
 }
 
+static inline struct clk *devm_clk_get_prepared(struct device *dev,
+						const char *id)
+{
+	return NULL;
+}
+
+static inline struct clk *devm_clk_get_enabled(struct device *dev,
+					       const char *id)
+{
+	return NULL;
+}
+
 static inline struct clk *devm_clk_get_optional(struct device *dev,
 						const char *id)
+{
+	return NULL;
+}
+
+static inline struct clk *devm_clk_get_optional_prepared(struct device *dev,
+							 const char *id)
+{
+	return NULL;
+}
+
+static inline struct clk *devm_clk_get_optional_enabled(struct device *dev,
+							const char *id)
 {
 	return NULL;
 }
@@ -829,14 +946,6 @@
 static inline void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks) {}
 
 static inline void devm_clk_put(struct device *dev, struct clk *clk) {}
-
-
-static inline int clk_rate_exclusive_get(struct clk *clk)
-{
-	return 0;
-}
-
-static inline void clk_rate_exclusive_put(struct clk *clk) {}
 
 static inline int clk_enable(struct clk *clk)
 {
diff --git a/kernel/include/linux/cpu.h b/kernel/include/linux/cpu.h
index ff057a3..25c6bda 100644
--- a/kernel/include/linux/cpu.h
+++ b/kernel/include/linux/cpu.h
@@ -70,6 +70,10 @@
 					char *buf);
 extern ssize_t cpu_show_retbleed(struct device *dev,
 				 struct device_attribute *attr, char *buf);
+extern ssize_t cpu_show_spec_rstack_overflow(struct device *dev,
+					     struct device_attribute *attr, char *buf);
+extern ssize_t cpu_show_gds(struct device *dev,
+			    struct device_attribute *attr, char *buf);
 
 extern __printf(4, 5)
 struct device *cpu_device_create(struct device *parent, void *drvdata,
@@ -192,6 +196,12 @@
 void arch_cpu_idle_exit(void);
 void arch_cpu_idle_dead(void);
 
+#ifdef CONFIG_ARCH_HAS_CPU_FINALIZE_INIT
+void arch_cpu_finalize_init(void);
+#else
+static inline void arch_cpu_finalize_init(void) { }
+#endif
+
 int cpu_report_state(int cpu);
 int cpu_check_up_prepare(int cpu);
 void cpu_set_state_online(int cpu);
diff --git a/kernel/include/linux/cpuset.h b/kernel/include/linux/cpuset.h
index 8063ae2..616cf86 100644
--- a/kernel/include/linux/cpuset.h
+++ b/kernel/include/linux/cpuset.h
@@ -57,6 +57,10 @@
 extern void cpuset_update_active_cpus(void);
 extern void cpuset_update_active_cpus_affine(int cpu);
 extern void cpuset_wait_for_hotplug(void);
+extern void inc_dl_tasks_cs(struct task_struct *task);
+extern void dec_dl_tasks_cs(struct task_struct *task);
+extern void cpuset_lock(void);
+extern void cpuset_unlock(void);
 extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask);
 extern void cpuset_cpus_allowed_fallback(struct task_struct *p);
 extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
@@ -182,6 +186,11 @@
 
 static inline void cpuset_wait_for_hotplug(void) { }
 
+static inline void inc_dl_tasks_cs(struct task_struct *task) { }
+static inline void dec_dl_tasks_cs(struct task_struct *task) { }
+static inline void cpuset_lock(void) { }
+static inline void cpuset_unlock(void) { }
+
 static inline void cpuset_cpus_allowed(struct task_struct *p,
 				       struct cpumask *mask)
 {
diff --git a/kernel/include/linux/debugfs.h b/kernel/include/linux/debugfs.h
index 2357109..9a87215 100644
--- a/kernel/include/linux/debugfs.h
+++ b/kernel/include/linux/debugfs.h
@@ -45,7 +45,7 @@
 
 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,9 +56,15 @@
 	.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 *);
 
@@ -101,6 +107,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,
@@ -249,6 +257,13 @@
 	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)
 {
diff --git a/kernel/include/linux/device.h b/kernel/include/linux/device.h
index 540a14f..d534e70 100644
--- a/kernel/include/linux/device.h
+++ b/kernel/include/linux/device.h
@@ -828,6 +828,7 @@
 void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode);
 void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode);
 void device_set_of_node_from_dev(struct device *dev, const struct device *dev2);
+void device_set_node(struct device *dev, struct fwnode_handle *fwnode);
 
 static inline int dev_num_vf(struct device *dev)
 {
diff --git a/kernel/include/linux/dim.h b/kernel/include/linux/dim.h
index 6c57339..f343bc9 100644
--- a/kernel/include/linux/dim.h
+++ b/kernel/include/linux/dim.h
@@ -236,8 +236,9 @@
  *
  * Calculate the delta between two samples (in data rates).
  * Takes into consideration counter wrap-around.
+ * Returned boolean indicates whether curr_stats are reliable.
  */
-void dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
+bool dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
 		    struct dim_stats *curr_stats);
 
 /**
diff --git a/kernel/include/linux/dmaengine.h b/kernel/include/linux/dmaengine.h
index 08537ef..875d47d 100644
--- a/kernel/include/linux/dmaengine.h
+++ b/kernel/include/linux/dmaengine.h
@@ -145,6 +145,7 @@
  *		Otherwise, destination is filled contiguously (icg ignored).
  *		Ignored if dst_inc is false.
  * @numf: Number of frames in this template.
+ * @nump: Number of period frames in this template.
  * @frame_size: Number of chunks in a frame i.e, size of sgl[].
  * @sgl: Array of {chunk,icg} pairs that make up a frame.
  */
@@ -157,6 +158,9 @@
 	bool src_sgl;
 	bool dst_sgl;
 	size_t numf;
+#ifdef CONFIG_NO_GKI
+	size_t nump;
+#endif
 	size_t frame_size;
 	struct data_chunk sgl[];
 };
@@ -449,10 +453,6 @@
 	unsigned int slave_id;
 	void *peripheral_config;
 	size_t peripheral_size;
-#ifdef CONFIG_NO_GKI
-	unsigned int src_interlace_size;
-	unsigned int dst_interlace_size;
-#endif
 };
 
 /**
diff --git a/kernel/include/linux/efi.h b/kernel/include/linux/efi.h
index 7feb70d..0849903 100644
--- a/kernel/include/linux/efi.h
+++ b/kernel/include/linux/efi.h
@@ -1108,8 +1108,6 @@
 static inline void efi_check_for_embedded_firmwares(void) { }
 #endif
 
-efi_status_t efi_random_get_seed(void);
-
 void efi_retrieve_tpm2_eventlog(void);
 
 /*
diff --git a/kernel/include/linux/etherdevice.h b/kernel/include/linux/etherdevice.h
index 99209f5..b060514 100644
--- a/kernel/include/linux/etherdevice.h
+++ b/kernel/include/linux/etherdevice.h
@@ -300,6 +300,18 @@
 }
 
 /**
+ * eth_hw_addr_set - Assign Ethernet address to a net_device
+ * @dev: pointer to net_device structure
+ * @addr: address to assign
+ *
+ * Assign given address to the net_device, addr_assign_type is not changed.
+ */
+static inline void eth_hw_addr_set(struct net_device *dev, const u8 *addr)
+{
+	ether_addr_copy(dev->dev_addr, addr);
+}
+
+/**
  * eth_hw_addr_inherit - Copy dev_addr from another net_device
  * @dst: pointer to net_device to copy dev_addr to
  * @src: pointer to net_device to copy dev_addr from
diff --git a/kernel/include/linux/eventfd.h b/kernel/include/linux/eventfd.h
index ce1cf42..c1bd488 100644
--- a/kernel/include/linux/eventfd.h
+++ b/kernel/include/linux/eventfd.h
@@ -42,6 +42,7 @@
 __u64 eventfd_signal_mask(struct eventfd_ctx *ctx, __u64 n, unsigned mask);
 int eventfd_ctx_remove_wait_queue(struct eventfd_ctx *ctx, wait_queue_entry_t *wait,
 				  __u64 *cnt);
+void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt);
 
 DECLARE_PER_CPU(int, eventfd_wake_count);
 
@@ -62,7 +63,7 @@
 	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;
 }
@@ -89,6 +90,11 @@
 	return false;
 }
 
+static inline void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt)
+{
+
+}
+
 #endif
 
 #endif /* _LINUX_EVENTFD_H */
diff --git a/kernel/include/linux/fs.h b/kernel/include/linux/fs.h
index 7297765..7286523 100644
--- a/kernel/include/linux/fs.h
+++ b/kernel/include/linux/fs.h
@@ -1179,6 +1179,7 @@
 extern int vfs_test_lock(struct file *, struct file_lock *);
 extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *);
 extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl);
+bool vfs_inode_has_locks(struct inode *inode);
 extern int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl);
 extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int type);
 extern void lease_get_mtime(struct inode *, struct timespec64 *time);
@@ -1291,6 +1292,11 @@
 	return 0;
 }
 
+static inline bool vfs_inode_has_locks(struct inode *inode)
+{
+	return false;
+}
+
 static inline int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl)
 {
 	return -ENOLCK;
@@ -1376,29 +1382,29 @@
  * sb->s_flags.  Note that these mirror the equivalent MS_* flags where
  * represented in both.
  */
-#define SB_RDONLY	 1	/* Mount read-only */
-#define SB_NOSUID	 2	/* Ignore suid and sgid bits */
-#define SB_NODEV	 4	/* Disallow access to device special files */
-#define SB_NOEXEC	 8	/* Disallow program execution */
-#define SB_SYNCHRONOUS	16	/* Writes are synced at once */
-#define SB_MANDLOCK	64	/* Allow mandatory locks on an FS */
-#define SB_DIRSYNC	128	/* Directory modifications are synchronous */
-#define SB_NOATIME	1024	/* Do not update access times. */
-#define SB_NODIRATIME	2048	/* Do not update directory access times */
-#define SB_SILENT	32768
-#define SB_POSIXACL	(1<<16)	/* VFS does not apply the umask */
-#define SB_INLINECRYPT	(1<<17)	/* Use blk-crypto for encrypted files */
-#define SB_KERNMOUNT	(1<<22) /* this is a kern_mount call */
-#define SB_I_VERSION	(1<<23) /* Update inode I_version field */
-#define SB_LAZYTIME	(1<<25) /* Update the on-disk [acm]times lazily */
+#define SB_RDONLY       BIT(0)	/* Mount read-only */
+#define SB_NOSUID       BIT(1)	/* Ignore suid and sgid bits */
+#define SB_NODEV        BIT(2)	/* Disallow access to device special files */
+#define SB_NOEXEC       BIT(3)	/* Disallow program execution */
+#define SB_SYNCHRONOUS  BIT(4)	/* Writes are synced at once */
+#define SB_MANDLOCK     BIT(6)	/* Allow mandatory locks on an FS */
+#define SB_DIRSYNC      BIT(7)	/* Directory modifications are synchronous */
+#define SB_NOATIME      BIT(10)	/* Do not update access times. */
+#define SB_NODIRATIME   BIT(11)	/* Do not update directory access times */
+#define SB_SILENT       BIT(15)
+#define SB_POSIXACL     BIT(16)	/* VFS does not apply the umask */
+#define SB_INLINECRYPT  BIT(17)	/* Use blk-crypto for encrypted files */
+#define SB_KERNMOUNT    BIT(22)	/* this is a kern_mount call */
+#define SB_I_VERSION    BIT(23)	/* Update inode I_version field */
+#define SB_LAZYTIME     BIT(25)	/* Update the on-disk [acm]times lazily */
 
 /* These sb flags are internal to the kernel */
-#define SB_SUBMOUNT     (1<<26)
-#define SB_FORCE    	(1<<27)
-#define SB_NOSEC	(1<<28)
-#define SB_BORN		(1<<29)
-#define SB_ACTIVE	(1<<30)
-#define SB_NOUSER	(1<<31)
+#define SB_SUBMOUNT     BIT(26)
+#define SB_FORCE        BIT(27)
+#define SB_NOSEC        BIT(28)
+#define SB_BORN         BIT(29)
+#define SB_ACTIVE       BIT(30)
+#define SB_NOUSER       BIT(31)
 
 /* These flags relate to encoding and casefolding */
 #define SB_ENC_STRICT_MODE_FL	(1 << 0)
@@ -1810,6 +1816,7 @@
 extern void inode_init_owner(struct inode *inode, const struct inode *dir,
 			umode_t mode);
 extern bool may_open_dev(const struct path *path);
+umode_t mode_strip_sgid(const struct inode *dir, umode_t mode);
 
 /*
  * This is the "filldir" function type, used by readdir() to let
@@ -3021,7 +3028,7 @@
 extern struct inode *new_inode_pseudo(struct super_block *sb);
 extern struct inode *new_inode(struct super_block *sb);
 extern void free_inode_nonrcu(struct inode *inode);
-extern int should_remove_suid(struct dentry *);
+extern int setattr_should_drop_suidgid(struct inode *);
 extern int file_remove_privs(struct file *);
 
 extern void __insert_inode_hash(struct inode *, unsigned long hashval);
@@ -3414,7 +3421,7 @@
  * 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);			\
@@ -3425,9 +3432,15 @@
 	.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, ...)
@@ -3443,6 +3456,8 @@
 			 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,
@@ -3462,7 +3477,7 @@
 
 static inline bool is_sxid(umode_t mode)
 {
-	return (mode & S_ISUID) || ((mode & S_ISGID) && (mode & S_IXGRP));
+	return mode & (S_ISUID | S_ISGID);
 }
 
 static inline int check_sticky(struct inode *dir, struct inode *inode)
diff --git a/kernel/include/linux/ftrace.h b/kernel/include/linux/ftrace.h
index 1bd3a03..b9dd113 100644
--- a/kernel/include/linux/ftrace.h
+++ b/kernel/include/linux/ftrace.h
@@ -811,7 +811,7 @@
 #define CALLER_ADDR5 ((unsigned long)ftrace_return_address(5))
 #define CALLER_ADDR6 ((unsigned long)ftrace_return_address(6))
 
-static inline unsigned long get_lock_parent_ip(void)
+static __always_inline unsigned long get_lock_parent_ip(void)
 {
 	unsigned long addr = CALLER_ADDR0;
 
diff --git a/kernel/include/linux/highmem.h b/kernel/include/linux/highmem.h
index 220e92c..f5299b5 100644
--- a/kernel/include/linux/highmem.h
+++ b/kernel/include/linux/highmem.h
@@ -334,4 +334,22 @@
 
 #endif
 
+static inline void memcpy_from_page(char *to, struct page *page,
+				    size_t offset, size_t len)
+{
+	char *from = kmap_atomic(page);
+
+	memcpy(to, from + offset, len);
+	kunmap_atomic(from);
+}
+
+static inline void memcpy_to_page(struct page *page, size_t offset,
+				  const char *from, size_t len)
+{
+	char *to = kmap_atomic(page);
+
+	memcpy(to + offset, from, len);
+	kunmap_atomic(to);
+}
+
 #endif /* _LINUX_HIGHMEM_H */
diff --git a/kernel/include/linux/hugetlb.h b/kernel/include/linux/hugetlb.h
index 25a24db..05d9c1e 100644
--- a/kernel/include/linux/hugetlb.h
+++ b/kernel/include/linux/hugetlb.h
@@ -7,6 +7,7 @@
 #include <linux/fs.h>
 #include <linux/hugetlb_inline.h>
 #include <linux/cgroup.h>
+#include <linux/page_ref.h>
 #include <linux/list.h>
 #include <linux/kref.h>
 #include <linux/pgtable.h>
@@ -148,7 +149,7 @@
 						vm_flags_t vm_flags);
 long hugetlb_unreserve_pages(struct inode *inode, long start, long end,
 						long freed);
-bool isolate_huge_page(struct page *page, struct list_head *list);
+int isolate_hugetlb(struct page *page, struct list_head *list);
 void putback_active_hugepage(struct page *page);
 void move_hugetlb_state(struct page *oldpage, struct page *newpage, int reason);
 void free_huge_page(struct page *page);
@@ -334,9 +335,9 @@
 	return NULL;
 }
 
-static inline bool isolate_huge_page(struct page *page, struct list_head *list)
+static inline int isolate_hugetlb(struct page *page, struct list_head *list)
 {
-	return false;
+	return -EBUSY;
 }
 
 static inline void putback_active_hugepage(struct page *page)
@@ -552,7 +553,10 @@
 	if (!page_size_log)
 		return &default_hstate;
 
-	return size_to_hstate(1UL << page_size_log);
+	if (page_size_log < BITS_PER_LONG)
+		return size_to_hstate(1UL << page_size_log);
+
+	return NULL;
 }
 
 static inline struct hstate *hstate_vma(struct vm_area_struct *vma)
@@ -963,4 +967,16 @@
 #define flush_hugetlb_tlb_range(vma, addr, end)	flush_tlb_range(vma, addr, end)
 #endif
 
+#ifdef CONFIG_ARCH_WANT_HUGE_PMD_SHARE
+static inline bool hugetlb_pmd_shared(pte_t *pte)
+{
+	return page_count(virt_to_page(pte)) > 1;
+}
+#else
+static inline bool hugetlb_pmd_shared(pte_t *pte)
+{
+	return false;
+}
+#endif
+
 #endif /* _LINUX_HUGETLB_H */
diff --git a/kernel/include/linux/hyperv.h b/kernel/include/linux/hyperv.h
index 1ce131f..eada4d8 100644
--- a/kernel/include/linux/hyperv.h
+++ b/kernel/include/linux/hyperv.h
@@ -1269,6 +1269,8 @@
 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)
diff --git a/kernel/include/linux/icm4260x.h b/kernel/include/linux/icm4260x.h
new file mode 100644
index 0000000..8917d8b
--- /dev/null
+++ b/kernel/include/linux/icm4260x.h
@@ -0,0 +1,432 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Definitions for icm4260x chip.
+ */
+#ifndef __ICM4260X_ACC_H
+#define __ICM4260X_ACC_H
+
+/* Registers and associated bit definitions */
+/* Bank 0 */
+#define ICM4260X_MISC_1				0x00
+#define ICM4260X_CHIP_CONFIG_REG		0x01
+#define ICM4260X_SIGNAL_PATH_RESET		0x02
+#define ICM4260X_DRIVE_CONFIG_REG1		0x03
+#define ICM4260X_DRIVE_CONFIG_REG2		0x04
+#define ICM4260X_DRIVE_CONFIG_REG3		0x05
+#define ICM4260X_INT_CONFIG_REG			0x06
+#define ICM4260X_ODRGRID0			0x07
+#define ICM4260X_ODRGRID1			0x08
+#define ICM4260X_TEMP_DATA0			0x09
+#define ICM4260X_TEMP_DATA1			0x0a
+#define ICM4260X_ACCEL_DATA_X0			0x0b
+#define ICM4260X_ACCEL_DATA_X1			0x0c
+#define ICM4260X_ACCEL_DATA_Y0			0x0d
+#define ICM4260X_ACCEL_DATA_Y1			0x0e
+#define ICM4260X_ACCEL_DATA_Z0			0x0f
+#define ICM4260X_ACCEL_DATA_Z1			0x10
+#define ICM4260X_GYRO_DATA_X0			0x11
+#define ICM4260X_GYRO_DATA_X1			0x12
+#define ICM4260X_GYRO_DATA_Y0			0x13
+#define ICM4260X_GYRO_DATA_Y1			0x14
+#define ICM4260X_GYRO_DATA_Z0			0x15
+#define ICM4260X_GYRO_DATA_Z1			0x16
+#define ICM4260X_TMST_FSYNC1			0x17
+#define ICM4260X_TMST_FSYNC2			0x18
+#define ICM4260X_ODR_LP_STATUS			0x19
+#define ICM4260X_PWR_MGMT_0			0x1f
+#define ICM4260X_GYRO_CONFIG0			0x20
+#define ICM4260X_ACCEL_CONFIG0			0x21
+#define ICM4260X_TEMP_CONFIG0			0x22
+#define ICM4260X_GYRO_CONFIG1			0x23
+#define ICM4260X_ACCEL_CONFIG1			0x24
+#define ICM4260X_APEX_CONFIG0			0x25
+#define ICM4260X_APEX_CONFIG1			0x26
+#define ICM4260X_WOM_CONFIG			0x27
+#define ICM4260X_FIFO_CONFIG1			0x28
+#define ICM4260X_FIFO_CONFIG2			0x29
+#define ICM4260X_FIFO_CONFIG3			0x2a
+#define ICM4260X_INT_SOURCE0			0x2b
+#define ICM4260X_INT_SOURCE1			0x2c
+#define ICM4260X_INT_SOURCE3			0x2d
+#define ICM4260X_INT_SOURCE4			0x2e
+#define ICM4260X_FIFO_LOST_PKT0			0x2f
+#define ICM4260X_FIFO_LOST_PKT1			0x30
+#define ICM4260X_APEX_DATA0			0x31
+#define ICM4260X_APEX_DATA1			0x32
+#define ICM4260X_APEX_DATA2			0x33
+#define ICM4260X_APEX_DATA3			0x34
+#define ICM4260X_INTF_CONFIG0			0x35
+#define ICM4260X_INTF_CONFIG1			0x36
+#define ICM4260X_INT_STATUS_DRDY		0x39
+#define ICM4260X_INT_STATUS			0x3a
+#define ICM4260X_INT_STATUS2			0x3b
+#define ICM4260X_INT_STATUS3			0x3c
+#define ICM4260X_FIFO_BYTE_COUNT1		0x3d
+#define ICM4260X_FIFO_BYTE_COUNT2		0x3e
+#define ICM4260X_FIFO_DATA_REG			0x3f
+#define ICM4260X_S4S_GYRO_TPH1			0x40
+#define ICM4260X_S4S_GYRO_TPH2			0x41
+#define ICM4260X_S4S_ACCEL_TPH1			0x42
+#define ICM4260X_S4S_ACCEL_TPH2			0x43
+#define ICM4260X_S4S_RR				0x44
+#define ICM4260X_GYR_BIAS_CFG1			0x46
+#define ICM4260X_WHO_AM_I			0x75
+#define ICM4260X_S4S_ST				0x76
+#define ICM4260X_S4S_ST_CLONE			0x77
+#define ICM4260X_S4S_DT				0x78
+#define ICM4260X_BLK_SEL_W			0x79
+#define ICM4260X_MADDR_W			0x7a
+#define ICM4260X_M_W				0x7b
+#define ICM4260X_BLK_SEL_R			0x7c
+#define ICM4260X_MADDR_R			0x7d
+#define ICM4260X_M_R				0x7e
+
+/* MREG_TOP1 */
+#define ICM4260X_TMST_CONFIG1_MREG_TOP1		0x00
+#define ICM4260X_FIFO_CONFIG5_MREG_TOP1		0x01
+#define ICM4260X_FIFO_CONFIG6_MREG_TOP1		0x02
+#define ICM4260X_FSYNC_CONFIG_MREG_TOP1		0x03
+#define ICM4260X_INT_CONFIG0_MREG_TOP1		0x04
+#define ICM4260X_INT_CONFIG1_MREG_TOP1		0x05
+#define ICM4260X_AFSR_CONFIG0_MREG_TOP1		0x07
+#define ICM4260X_AFSR_CONFIG1_MREG_TOP1		0x08
+#define ICM4260X_TBC_RCOSC_MREG_TOP1		0x0d
+#define ICM4260X_TBC_PLL_MREG_TOP1		0x0e
+#define ICM4260X_ST_CONFIG_MREG_TOP1		0x13
+#define ICM4260X_SELFTEST_MREG_TOP1		0x14
+#define ICM4260X_PADS_CONFIG3_MREG_TOP1		0x17
+#define ICM4260X_TEMP_CONFIG1_MREG_TOP1		0x1c
+#define ICM4260X_TEMP_CONFIG3_MREG_TOP1		0x1e
+#define ICM4260X_S4S_CONFIG1_MREG_TOP1		0x1f
+#define ICM4260X_S4S_CONFIG2_MREG_TOP1		0x20
+#define ICM4260X_S4S_FREQ_RATIO1_MREG_TOP1	0x21
+#define ICM4260X_S4S_FREQ_RATIO2_MREG_TOP1	0x22
+#define ICM4260X_INTF_CONFIG6_MREG_TOP1		0x23
+#define ICM4260X_INTF_CONFIG10_MREG_TOP1	0x25
+#define ICM4260X_INTF_CONFIG7_MREG_TOP1		0x28
+#define ICM4260X_OTP_CONFIG_MREG_TOP1		0x2b
+#define ICM4260X_INT_SOURCE6_MREG_TOP1		0x2f
+#define ICM4260X_INT_SOURCE7_MREG_TOP1		0x30
+#define ICM4260X_INT_SOURCE8_MREG_TOP1		0x31
+#define ICM4260X_INT_SOURCE9_MREG_TOP1		0x32
+#define ICM4260X_INT_SOURCE10_MREG_TOP1		0x33
+#define ICM4260X_GYRO_PWR_CFG0_MREG_TOP1	0x38
+#define ICM4260X_ACCEL_CP_CFG0_MREG_TOP1	0x39
+#define ICM4260X_APEX_CONFIG2_MREG_TOP1		0x44
+#define ICM4260X_APEX_CONFIG3_MREG_TOP1		0x45
+#define ICM4260X_APEX_CONFIG4_MREG_TOP1		0x46
+#define ICM4260X_APEX_CONFIG5_MREG_TOP1		0x47
+#define ICM4260X_APEX_CONFIG9_MREG_TOP1		0x48
+#define ICM4260X_APEX_CONFIG10_MREG_TOP1	0x49
+#define ICM4260X_APEX_CONFIG11_MREG_TOP1	0x4a
+#define ICM4260X_APEX_CONFIG12_MREG_TOP1	0x67
+#define ICM4260X_ACCEL_WOM_X_THR_MREG_TOP1	0x4b
+#define ICM4260X_ACCEL_WOM_Y_THR_MREG_TOP1	0x4c
+#define ICM4260X_ACCEL_WOM_Z_THR_MREG_TOP1	0x4d
+#define ICM4260X_GOS_USER0_MREG_TOP1		0x4e
+#define ICM4260X_GOS_USER1_MREG_TOP1		0x4f
+#define ICM4260X_GOS_USER2_MREG_TOP1		0x50
+#define ICM4260X_GOS_USER3_MREG_TOP1		0x51
+#define ICM4260X_GOS_USER4_MREG_TOP1		0x52
+#define ICM4260X_GOS_USER5_MREG_TOP1		0x53
+#define ICM4260X_GOS_USER6_MREG_TOP1		0x54
+#define ICM4260X_GOS_USER7_MREG_TOP1		0x55
+#define ICM4260X_GOS_USER8_MREG_TOP1		0x56
+#define ICM4260X_ST_STATUS1_MREG_TOP1		0x63
+#define ICM4260X_ST_STATUS2_MREG_TOP1		0x64
+
+/* MMEM_TOP */
+#define ICM4260X_XA_ST_DATA_MMEM_TOP		0x5000
+#define ICM4260X_YA_ST_DATA_MMEM_TOP		0x5001
+#define ICM4260X_ZA_ST_DATA_MMEM_TOP		0x5002
+#define ICM4260X_XG_ST_DATA_MMEM_TOP		0x5003
+#define ICM4260X_YG_ST_DATA_MMEM_TOP		0x5004
+#define ICM4260X_ZG_ST_DATA_MMEM_TOP		0x5005
+
+/* MREG_OTP */
+#define ICM4260X_OTP_CTRL7_MREG_OTP		0x2806
+
+/* Bank0 REG_GYRO_CONFIG0/REG_ACCEL_CONFIG0 */
+#define SHIFT_GYRO_FS_SEL			5
+#define SHIFT_ACCEL_FS_SEL			5
+#define SHIFT_ODR_CONF				0
+#define BIT_GYRO_FSR				0x60
+#define BIT_GYRO_ODR				0x0F
+#define BIT_ACCEL_FSR				0x60
+#define ACCEL_FS_SEL				3	//(-2G, +2G)
+#define GYRO_FS_SEL				3	//00~11:2000dps\1000dps\500dps\250dps
+#define BIT_ACCEL_ODR				0x0F
+#define BIT_SENSOR_ODR_800HZ			0x06
+#define BIT_SENSOR_ODR_400HZ			0x07
+#define BIT_SENSOR_ODR_200HZ			0x08
+#define BIT_SENSOR_ODR_100HZ			0x09
+#define BIT_SENSOR_ODR_50HZ			0x0A
+#define BIT_SENSOR_ODR_25HZ			0x0B
+#define BIT_SENSOR_ODR_12HZ			0x0C
+#define BIT_SENSOR_ODR_6HZ			0x0D
+#define BIT_SENSOR_ODR_3HZ			0x0E
+
+/* Bank0 REG_GYRO_CONFIG1 */
+#define BIT_GYR_UI_FLT_BW_BYPASS		0x00
+#define BIT_GYR_UI_FLT_BW_180HZ			0x01
+#define BIT_GYR_UI_FLT_BW_121HZ			0x02
+#define BIT_GYR_UI_FLT_BW_73HZ			0x03
+#define BIT_GYR_UI_FLT_BW_53HZ			0x04
+#define BIT_GYR_UI_FLT_BW_34HZ			0x05
+#define BIT_GYR_UI_FLT_BW_25HZ			0x06
+#define BIT_GYR_UI_FLT_BW_16HZ			0x07
+#define BIT_GYR_UI_AVG_IND_2X			0x00
+#define BIT_GYR_UI_AVG_IND_4X			0x10
+#define BIT_GYR_UI_AVG_IND_8X			0x20
+#define BIT_GYR_UI_AVG_IND_16X			0x30
+#define BIT_GYR_UI_AVG_IND_32X			0x40
+#define BIT_GYR_UI_AVG_IND_64X			0x50
+
+/* Bank0 REG_ACCEL_CONFIG1 */
+#define BIT_ACC_FILT_BW_IND_BYPASS		0x00
+#define BIT_ACC_FILT_BW_IND_180HZ		0x01
+#define BIT_ACC_FILT_BW_IND_121HZ		0x02
+#define BIT_ACC_FILT_BW_IND_73HZ		0x03
+#define BIT_ACC_FILT_BW_IND_53HZ		0x04
+#define BIT_ACC_FILT_BW_IND_34HZ		0x05
+#define BIT_ACC_FILT_BW_IND_25HZ		0x06
+#define BIT_ACC_FILT_BW_IND_16HZ		0x07
+#define BIT_ACC_UI_AVG_IND_2X			0x00
+#define BIT_ACC_UI_AVG_IND_4X			0x10
+#define BIT_ACC_UI_AVG_IND_8X			0x20
+#define BIT_ACC_UI_AVG_IND_16X			0x30
+#define BIT_ACC_UI_AVG_IND_32X			0x40
+#define BIT_ACC_UI_AVG_IND_64X			0x50
+
+/* Bank0 REG_INT_CONFIG_REG */
+#define SHIFT_INT1_MODE				0x02
+#define SHIFT_INT1_DRIVE_CIRCUIT		0x01
+#define SHIFT_INT1_POLARITY			0x00
+
+/* Bank0 REG_PWR_MGMT_0 */
+#define BIT_ACCEL_MODE_OFF			0x00
+#define BIT_ACCEL_MODE_LPM			0x02
+#define BIT_ACCEL_MODE_LNM			0x03
+#define BIT_ACCEL_MODE_MASK			0x03
+#define BIT_GYRO_MODE_OFF			0x00
+#define BIT_GYRO_MODE_STBY			0x04
+#define BIT_GYRO_MODE_LPM			0x08
+#define BIT_GYRO_MODE_LNM			0x0c
+#define BIT_GYRO_MODE_MASK			0x0c
+#define BIT_IDLE				0x10
+#define BIT_ACCEL_LP_CLK_SEL			0x80
+
+/* Bank0 REG_SIGNAL_PATH_RESET */
+#define BIT_FIFO_FLUSH				0x04
+#define BIT_SOFT_RESET_CHIP_CONFIG		0x10
+
+/* Bank0 REG_INTF_CONFIG0 */
+#define BIT_SIFS_CFG_I2C_ONLY			0x02
+#define BIT_SIFS_CFG_SPI_ONLY			0x03
+#define BIT_SENSOR_DATA_ENDIAN			0x10
+#define BIT_FIFO_COUNT_ENDIAN			0x20
+#define BIT_FIFO_COUNT_FORMAT			0x40
+#define BIT_FIFO_SREG_INVALID_IND_DIS		0x80
+
+/* Bank0 REG_INTF_CONFIG1 */
+#define BIT_CLK_SEL_RC				0x00
+#define BIT_CLK_SEL_PLL				0x01
+#define BIT_CLK_SEL_DIS				0x03
+#define BIT_I3C_DDR_EN				0x04
+#define BIT_I3C_SDR_EN				0x08
+#define BIT_GYRO_AFSR_MODE_LFS			0x00
+#define BIT_GYRO_AFSR_MODE_HFS			0x20
+#define BIT_GYRO_AFSR_MODE_DYN			0x40
+
+/* Bank0 REG_FIFO_CONFIG1 */
+#define BIT_FIFO_MODE_NO_BYPASS			0x00
+#define BIT_FIFO_MODE_BYPASS			0x01
+#define BIT_FIFO_MODE_STREAM			0x00
+#define BIT_FIFO_MODE_STOPFULL			0x02
+
+/* Bank 0 REG_INT_SOURCE0 */
+#define BIT_INT_AGC_RDY_INT1_EN			0x01
+#define BIT_INT_FIFO_FULL_INT1_EN		0x02
+#define BIT_INT_FIFO_THS_INT1_EN		0x04
+#define BIT_INT_DRDY_INT_EN			0x08
+#define BIT_INT_RESET_DONE_INT1_EN		0x10
+#define BIT_INT_PLL_RDY_INT1_EN			0x20
+#define BIT_INT_FSYNC_INT1_EN			0x40
+#define BIT_INT_ST_DONE_INT1_EN			0x80
+
+/* Bank 0 REG_INT_SOURCE1 */
+#define BIT_INT_WOM_X_INT1_EN			0x01
+#define BIT_INT_WOM_Y_INT1_EN			0x02
+#define BIT_INT_WOM_Z_INT1_EN			0x04
+#define BIT_INT_WOM_XYZ_INT1_EN (BIT_INT_WOM_X_INT1_EN | \
+		BIT_INT_WOM_Y_INT1_EN | BIT_INT_WOM_Z_INT1_EN)
+#define BIT_INT_SMD_INT1_EN			0x08
+#define BIT_INT_I3C_PROTCL_ERR_INT1_EN		0x40
+
+/* Bank0 REG_INT_STATUS_DRDY */
+#define BIT_INT_STATUS_DRDY			0x01
+
+/* Bank0 REG_INT_STATUS */
+#define BIT_INT_STATUS_AGC_RDY			0x01
+#define BIT_INT_STATUS_FIFO_FULL		0x02
+#define BIT_INT_STATUS_FIFO_THS			0x04
+#define BIT_INT_STATUS_RESET_DONE		0x10
+#define BIT_INT_STATUS_PLL_RDY			0x20
+#define BIT_INT_STATUS_FSYNC			0x40
+#define BIT_INT_STATUS_ST_DONE			0x80
+
+/* Bank0 REG_INT_STATUS2 */
+#define BIT_INT_STATUS_WOM_Z			0x01
+#define BIT_INT_STATUS_WOM_Y			0x02
+#define BIT_INT_STATUS_WOM_X			0x04
+#define BIT_INT_STATUS_WOM_XYZ (BIT_INT_STATUS_WOM_X | \
+		BIT_INT_STATUS_WOM_Y | BIT_INT_STATUS_WOM_Z)
+#define BIT_INT_STATUS_SMD			0x08
+
+/* Bank 0 REG_INT_STATUS3 */
+#define BIT_INT_STATUS_LOWG_DET			0x02
+#define BIT_INT_STATUS_FF_DET			0x04
+#define BIT_INT_STATUS_TILT_DET			0x08
+#define BIT_INT_STATUS_STEP_CNT_OVFL		0x10
+#define BIT_INT_STATUS_STEP_DET			0x20
+
+/* Bank0 REG_WOM_CONFIG */
+#define BIT_WOM_EN_OFF				0x00
+#define BIT_WOM_EN_ON				0x01
+#define BIT_WOM_MODE_INITIAL			0x00
+#define BIT_WOM_MODE_PREV			0x02
+#define BIT_WOM_INT_MODE_OR			0x00
+#define BIT_WOM_INT_MODE_AND			0x04
+#define BIT_WOM_INT_DUR_LEGACY			0x00
+#define BIT_WOM_INT_DUR_2ND			0x08
+#define BIT_WOM_INT_DUR_3RD			0x10
+#define BIT_WOM_INT_DUR_4TH			0x18
+
+/* Bank0 REG_APEX_CONFIG0 */
+#define BIT_DMP_SRAM_RESET_APEX			0x01
+#define BIT_DMP_INIT_EN				0x04
+#define BIT_DMP_POWER_SAVE_EN			0x08
+
+/* Bank0 REG_APEX_CONFIG1 */
+#define BIT_DMP_ODR_25HZ			0x00
+#define BIT_DMP_ODR_50HZ			0x02
+#define BIT_DMP_ODR_100HZ			0x03
+#define BIT_DMP_PEDO_EN				0x08
+#define BIT_DMP_TILT_EN				0x10
+#define BIT_DMP_FF_EN				0x20
+#define BIT_DMP_SMD_EN				0x40
+
+/* REG_OTP_CONFIG_MREG_TOP1 */
+#define BIT_OTP_COPY_NORMAL			0x04
+#define BIT_OTP_COPY_ST_DATA			0x0C
+#define OTP_COPY_MODE_MASK                      0x0C
+
+/* REG_INT_SOURCE6_MREG_TOP1 */
+#define BIT_INT_TLT_DET_INT1_EN			0x08
+#define BIT_INT_STEP_CNT_OVFL_INT1_EN		0x10
+#define BIT_INT_STEP_DET_INT1_EN		0x20
+#define BIT_INT_LOWG_INT1_EN			0x40
+#define BIT_INT_FF_INT1_EN			0x80
+
+/* REG_TMST_CONFIG1_MREG_TOP1 */
+#define BIT_TMST_EN				0x01
+#define BIT_TMST_FSYNC_EN			0x02
+#define BIT_TMST_DELTA_EN			0x04
+#define BIT_TMST_RESOL				0x08
+#define BIT_TMST_ON_SREG_EN			0x10
+#define BIT_ODR_EN_WITHOUT_SENSOR		0x40
+
+/* REG_FIFO_CONFIG5_MREG_TOP1 */
+#define BIT_FIFO_ACCEL_EN			0x01
+#define BIT_FIFO_GYRO_EN			0x02
+#define BIT_FIFO_TMST_FSYNC_EN			0x04
+#define BIT_FIFO_HIRES_EN			0x08
+#define BIT_RESUME_PARTIAL_RD			0x10
+#define BIT_WM_GT_TH				0x20
+
+/* REG_SELFTEST_MREG_TOP1 */
+#define BIT_EN_AX_ST				0x01
+#define BIT_EN_AY_ST				0x02
+#define BIT_EN_AZ_ST				0x04
+#define BIT_EN_GX_ST				0x08
+#define BIT_EN_GY_ST				0x10
+#define BIT_EN_GZ_ST				0x20
+#define BIT_ACCEL_ST_EN				0x40
+#define BIT_GYRO_ST_EN				0x80
+
+/* REG_ST_CONFIG_MREG_TOP1 */
+#define BIT_PD_ACCEL_CP45_ST_REG		0x80
+#define SHIFT_GYRO_ST_LIM			0
+#define SHIFT_ACCEL_ST_LIM			3
+#define SHIFT_ST_NUM_SAMPLE			6
+
+/* REG_ST_STATUS1_MREG_TOP1 */
+#define BIT_DMP_AX_ST_PASS			0x02
+#define BIT_DMP_AY_ST_PASS			0x04
+#define BIT_DMP_AZ_ST_PASS			0x08
+#define BIT_DMP_ACCEL_ST_DONE			0x10
+#define BIT_DMP_ACCEL_ST_PASS			0x20
+
+/* REG_ST_STATUS2_MREG_TOP1 */
+#define BIT_DMP_GX_ST_PASS			0x02
+#define BIT_DMP_GY_ST_PASS			0x04
+#define BIT_DMP_GZ_ST_PASS			0x08
+#define BIT_DMP_GYRO_ST_DONE			0x10
+#define BIT_DMP_GYRO_ST_PASS			0x20
+#define BIT_DMP_ST_INCOMPLETE			0x40
+
+/* REG_OTP_CTRL7_MREG_OTP */
+#define BIT_OTP_RELOAD				0x08
+#define BIT_OTP_PWR_DOWN			0x02
+
+
+/* fifo data packet header */
+#define BIT_FIFO_HEAD_MSG			0x80
+#define BIT_FIFO_HEAD_ACCEL			0x40
+#define BIT_FIFO_HEAD_GYRO			0x20
+#define BIT_FIFO_HEAD_20			0x10
+#define BIT_FIFO_HEAD_TMSP_ODR			0x08
+#define BIT_FIFO_HEAD_TMSP_NO_ODR		0x04
+#define BIT_FIFO_HEAD_TMSP_FSYNC		0x0C
+#define BIT_FIFO_HEAD_ODR_ACCEL			0x02
+#define BIT_FIFO_HEAD_ODR_GYRO			0x01
+
+/* data definitions */
+#define FIFO_PACKET_BYTE_SINGLE			8
+#define FIFO_PACKET_BYTE_6X			16
+#define FIFO_PACKET_BYTE_HIRES			20
+#define FIFO_COUNT_BYTE				2
+
+/* sensor startup time */
+#define INV_ICM43600_GYRO_START_TIME		100
+#define INV_ICM43600_ACCEL_START_TIME		100
+
+/* sensor stop time */
+#define INV_ICM43600_GYRO_STOP_TIME		20
+
+/* M-reg access wait tile */
+#define INV_ICM42607_MCLK_WAIT_US		20
+#define INV_ICM42607_BLK_SEL_WAIT_US		10
+#define INV_ICM42607_MADDR_WAIT_US		10
+#define INV_ICM42607_M_RW_WAIT_US		10
+
+/* temperature sensor */
+#define TEMP_SCALE				100 /* scale by 100 */
+#define TEMP_LSB_PER_DEG			2   /* 2LSB=1degC */
+#define TEMP_OFFSET				25  /* 25 degC */
+
+/*
+ * INT configurations
+ * Polarity: 0 -> Active Low, 1 -> Active High
+ * Drive circuit: 0 -> Open Drain, 1 -> Push-Pull
+ * Mode: 0 -> Pulse, 1 -> Latch
+ */
+#define INT_POLARITY			1
+#define INT_DRIVE_CIRCUIT		1
+#define INT_MODE			0
+
+#define ICM42607_DEVICE_ID		0x61
+#define ICM4260X_PRECISION		16
+#define ICM42607_ADDR			0x68
+
+#endif
diff --git a/kernel/include/linux/if_arp.h b/kernel/include/linux/if_arp.h
index e147ea6..91db78e 100644
--- a/kernel/include/linux/if_arp.h
+++ b/kernel/include/linux/if_arp.h
@@ -52,6 +52,10 @@
 	case ARPHRD_NONE:
 	case ARPHRD_RAWIP:
 	case ARPHRD_PIMREG:
+	/* PPP adds its l2 header automatically in ppp_start_xmit().
+	 * This makes it look like an l3 device to __bpf_redirect() and tcf_mirred_init().
+	 */
+	case ARPHRD_PPP:
 		return false;
 	default:
 		return true;
diff --git a/kernel/include/linux/if_team.h b/kernel/include/linux/if_team.h
index add6079..762c77d 100644
--- a/kernel/include/linux/if_team.h
+++ b/kernel/include/linux/if_team.h
@@ -189,6 +189,8 @@
 	struct net_device *dev; /* associated netdevice */
 	struct team_pcpu_stats __percpu *pcpu_stats;
 
+	const struct header_ops *header_ops_cache;
+
 	struct mutex lock; /* used for overall locking, e.g. port lists write */
 
 	/*
@@ -208,6 +210,7 @@
 	bool queue_override_enabled;
 	struct list_head *qom_lists; /* array of queue override mapping lists */
 	bool port_mtu_change_allowed;
+	bool notifier_ctx;
 	struct {
 		unsigned int count;
 		unsigned int interval; /* in ms */
diff --git a/kernel/include/linux/if_vlan.h b/kernel/include/linux/if_vlan.h
index 41a5183..4e7e72f 100644
--- a/kernel/include/linux/if_vlan.h
+++ b/kernel/include/linux/if_vlan.h
@@ -626,6 +626,23 @@
 	return __vlan_get_protocol(skb, skb->protocol, NULL);
 }
 
+/* This version of __vlan_get_protocol() also pulls mac header in skb->head */
+static inline __be16 vlan_get_protocol_and_depth(struct sk_buff *skb,
+						 __be16 type, int *depth)
+{
+	int maclen;
+
+	type = __vlan_get_protocol(skb, type, &maclen);
+
+	if (type) {
+		if (!pskb_may_pull(skb, maclen))
+			type = 0;
+		else if (depth)
+			*depth = maclen;
+	}
+	return type;
+}
+
 /* A getter for the SKB protocol field which will handle VLAN tags consistently
  * whether VLAN acceleration is enabled or not.
  */
diff --git a/kernel/include/linux/iio/imu/adis.h b/kernel/include/linux/iio/imu/adis.h
index 04e96d6..5f45b78 100644
--- a/kernel/include/linux/iio/imu/adis.h
+++ b/kernel/include/linux/iio/imu/adis.h
@@ -32,6 +32,7 @@
 	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,10 +46,11 @@
  * @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
+ * @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 +79,7 @@
 	unsigned int status_error_mask;
 
 	int (*enable_irq)(struct adis *adis, bool enable);
+	bool unmasked_drdy;
 
 	bool has_paging;
 
@@ -126,12 +129,12 @@
 	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);
 
 /**
@@ -152,9 +155,9 @@
 }
 
 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)
@@ -163,7 +166,7 @@
  * @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);
 }
@@ -175,7 +178,7 @@
  * @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);
 }
@@ -187,7 +190,7 @@
  * @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);
 }
@@ -199,7 +202,7 @@
  * @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;
@@ -218,7 +221,7 @@
  * @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;
@@ -238,7 +241,7 @@
  * @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;
 
@@ -257,7 +260,7 @@
  * @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;
 
@@ -275,7 +278,7 @@
  * @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);
 }
@@ -287,7 +290,7 @@
  * @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);
 }
@@ -299,7 +302,7 @@
  * @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);
 }
@@ -311,7 +314,7 @@
  * @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;
@@ -330,7 +333,7 @@
  * @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;
@@ -401,9 +404,20 @@
 		__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)
 {
@@ -429,8 +443,8 @@
 }
 
 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, \
@@ -479,7 +493,7 @@
 	.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), \
@@ -513,7 +527,7 @@
 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 */
 
@@ -537,7 +551,8 @@
 #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
 
diff --git a/kernel/include/linux/ima.h b/kernel/include/linux/ima.h
index 8fa7bcf..cd8483f 100644
--- a/kernel/include/linux/ima.h
+++ b/kernel/include/linux/ima.h
@@ -18,7 +18,8 @@
 extern int ima_file_check(struct file *file, int mask);
 extern void ima_post_create_tmpfile(struct inode *inode);
 extern void ima_file_free(struct file *file);
-extern int ima_file_mmap(struct file *file, unsigned long prot);
+extern int ima_file_mmap(struct file *file, unsigned long reqprot,
+			 unsigned long prot, unsigned long flags);
 extern int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot);
 extern int ima_load_data(enum kernel_load_data_id id, bool contents);
 extern int ima_post_load_data(char *buf, loff_t size,
@@ -70,7 +71,8 @@
 	return;
 }
 
-static inline int ima_file_mmap(struct file *file, unsigned long prot)
+static inline int ima_file_mmap(struct file *file, unsigned long reqprot,
+				unsigned long prot, unsigned long flags)
 {
 	return 0;
 }
diff --git a/kernel/include/linux/interrupt.h b/kernel/include/linux/interrupt.h
index 386ddf4..6ff7d17 100644
--- a/kernel/include/linux/interrupt.h
+++ b/kernel/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/include/linux/iopoll.h b/kernel/include/linux/iopoll.h
index 2c8860e..0417360 100644
--- a/kernel/include/linux/iopoll.h
+++ b/kernel/include/linux/iopoll.h
@@ -53,6 +53,7 @@
 		} \
 		if (__sleep_us) \
 			usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
+		cpu_relax(); \
 	} \
 	(cond) ? 0 : -ETIMEDOUT; \
 })
@@ -95,6 +96,7 @@
 		} \
 		if (__delay_us) \
 			udelay(__delay_us); \
+		cpu_relax(); \
 	} \
 	(cond) ? 0 : -ETIMEDOUT; \
 })
diff --git a/kernel/include/linux/irq.h b/kernel/include/linux/irq.h
index b2b956d..f07d9f1 100644
--- a/kernel/include/linux/irq.h
+++ b/kernel/include/linux/irq.h
@@ -118,7 +118,7 @@
  * IRQ_SET_MASK_NOCPY	- OK, chip did update irq_common_data.affinity
  * IRQ_SET_MASK_OK_DONE	- Same as IRQ_SET_MASK_OK for core. Special code to
  *			  support stacked irqchips, which indicates skipping
- *			  all descendent irqchips.
+ *			  all descendant irqchips.
  */
 enum {
 	IRQ_SET_MASK_OK = 0,
@@ -304,7 +304,7 @@
 
 /*
  * Must only be called of irqchip.irq_set_affinity() or low level
- * hieararchy domain allocation functions.
+ * hierarchy domain allocation functions.
  */
 static inline void irqd_set_single_target(struct irq_data *d)
 {
diff --git a/kernel/include/linux/irqdesc.h b/kernel/include/linux/irqdesc.h
index 5745491..fdb22e0 100644
--- a/kernel/include/linux/irqdesc.h
+++ b/kernel/include/linux/irqdesc.h
@@ -32,7 +32,7 @@
  * @last_unhandled:	aging timer for unhandled count
  * @irqs_unhandled:	stats field for spurious unhandled interrupts
  * @threads_handled:	stats field for deferred spurious detection of threaded handlers
- * @threads_handled_last: comparator field for deferred spurious detection of theraded handlers
+ * @threads_handled_last: comparator field for deferred spurious detection of threaded handlers
  * @lock:		locking for SMP
  * @affinity_hint:	hint to user space for preferred irq affinity
  * @affinity_notify:	context for notification of affinity changes
diff --git a/kernel/include/linux/irqdomain.h b/kernel/include/linux/irqdomain.h
index d6208a42..1d62f24 100644
--- a/kernel/include/linux/irqdomain.h
+++ b/kernel/include/linux/irqdomain.h
@@ -262,7 +262,11 @@
 }
 
 void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
+#ifdef __GENKSYMS__	/* Android KABI hack to preserve CRC checker */
 struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
+#else
+struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size,
+#endif
 				    irq_hw_number_t hwirq_max, int direct_max,
 				    const struct irq_domain_ops *ops,
 				    void *host_data);
diff --git a/kernel/include/linux/kernel.h b/kernel/include/linux/kernel.h
index c333dc6..d9373fe 100644
--- a/kernel/include/linux/kernel.h
+++ b/kernel/include/linux/kernel.h
@@ -10,6 +10,7 @@
 #include <linux/types.h>
 #include <linux/compiler.h>
 #include <linux/bitops.h>
+#include <linux/kstrtox.h>
 #include <linux/log2.h>
 #include <linux/minmax.h>
 #include <linux/typecheck.h>
@@ -46,6 +47,8 @@
  * @arr: array to be sized
  */
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
+
+#define PTR_IF(cond, ptr)	((cond) ? (ptr) : NULL)
 
 #define u64_to_user_ptr(x) (		\
 {					\
@@ -320,153 +323,12 @@
 __printf(1, 2)
 void panic(const char *fmt, ...) __noreturn __cold;
 void nmi_panic(struct pt_regs *regs, const char *msg);
+void check_panic_on_warn(const char *origin);
 extern void oops_enter(void);
 extern void oops_exit(void);
 extern bool oops_may_print(void);
 void do_exit(long error_code) __noreturn;
 void complete_and_exit(struct completion *, long) __noreturn;
-
-/* Internal, do not use. */
-int __must_check _kstrtoul(const char *s, unsigned int base, unsigned long *res);
-int __must_check _kstrtol(const char *s, unsigned int base, long *res);
-
-int __must_check kstrtoull(const char *s, unsigned int base, unsigned long long *res);
-int __must_check kstrtoll(const char *s, unsigned int base, long long *res);
-
-/**
- * kstrtoul - convert a string to an unsigned long
- * @s: The start of the string. The string must be null-terminated, and may also
- *  include a single newline before its terminating null. The first character
- *  may also be a plus sign, but not a minus sign.
- * @base: The number base to use. The maximum supported base is 16. If base is
- *  given as 0, then the base of the string is automatically detected with the
- *  conventional semantics - If it begins with 0x the number will be parsed as a
- *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
- *  parsed as an octal number. Otherwise it will be parsed as a decimal.
- * @res: Where to write the result of the conversion on success.
- *
- * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
- * Preferred over simple_strtoul(). Return code must be checked.
-*/
-static inline int __must_check kstrtoul(const char *s, unsigned int base, unsigned long *res)
-{
-	/*
-	 * We want to shortcut function call, but
-	 * __builtin_types_compatible_p(unsigned long, unsigned long long) = 0.
-	 */
-	if (sizeof(unsigned long) == sizeof(unsigned long long) &&
-	    __alignof__(unsigned long) == __alignof__(unsigned long long))
-		return kstrtoull(s, base, (unsigned long long *)res);
-	else
-		return _kstrtoul(s, base, res);
-}
-
-/**
- * kstrtol - convert a string to a long
- * @s: The start of the string. The string must be null-terminated, and may also
- *  include a single newline before its terminating null. The first character
- *  may also be a plus sign or a minus sign.
- * @base: The number base to use. The maximum supported base is 16. If base is
- *  given as 0, then the base of the string is automatically detected with the
- *  conventional semantics - If it begins with 0x the number will be parsed as a
- *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
- *  parsed as an octal number. Otherwise it will be parsed as a decimal.
- * @res: Where to write the result of the conversion on success.
- *
- * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
- * Preferred over simple_strtol(). Return code must be checked.
- */
-static inline int __must_check kstrtol(const char *s, unsigned int base, long *res)
-{
-	/*
-	 * We want to shortcut function call, but
-	 * __builtin_types_compatible_p(long, long long) = 0.
-	 */
-	if (sizeof(long) == sizeof(long long) &&
-	    __alignof__(long) == __alignof__(long long))
-		return kstrtoll(s, base, (long long *)res);
-	else
-		return _kstrtol(s, base, res);
-}
-
-int __must_check kstrtouint(const char *s, unsigned int base, unsigned int *res);
-int __must_check kstrtoint(const char *s, unsigned int base, int *res);
-
-static inline int __must_check kstrtou64(const char *s, unsigned int base, u64 *res)
-{
-	return kstrtoull(s, base, res);
-}
-
-static inline int __must_check kstrtos64(const char *s, unsigned int base, s64 *res)
-{
-	return kstrtoll(s, base, res);
-}
-
-static inline int __must_check kstrtou32(const char *s, unsigned int base, u32 *res)
-{
-	return kstrtouint(s, base, res);
-}
-
-static inline int __must_check kstrtos32(const char *s, unsigned int base, s32 *res)
-{
-	return kstrtoint(s, base, res);
-}
-
-int __must_check kstrtou16(const char *s, unsigned int base, u16 *res);
-int __must_check kstrtos16(const char *s, unsigned int base, s16 *res);
-int __must_check kstrtou8(const char *s, unsigned int base, u8 *res);
-int __must_check kstrtos8(const char *s, unsigned int base, s8 *res);
-int __must_check kstrtobool(const char *s, bool *res);
-
-int __must_check kstrtoull_from_user(const char __user *s, size_t count, unsigned int base, unsigned long long *res);
-int __must_check kstrtoll_from_user(const char __user *s, size_t count, unsigned int base, long long *res);
-int __must_check kstrtoul_from_user(const char __user *s, size_t count, unsigned int base, unsigned long *res);
-int __must_check kstrtol_from_user(const char __user *s, size_t count, unsigned int base, long *res);
-int __must_check kstrtouint_from_user(const char __user *s, size_t count, unsigned int base, unsigned int *res);
-int __must_check kstrtoint_from_user(const char __user *s, size_t count, unsigned int base, int *res);
-int __must_check kstrtou16_from_user(const char __user *s, size_t count, unsigned int base, u16 *res);
-int __must_check kstrtos16_from_user(const char __user *s, size_t count, unsigned int base, s16 *res);
-int __must_check kstrtou8_from_user(const char __user *s, size_t count, unsigned int base, u8 *res);
-int __must_check kstrtos8_from_user(const char __user *s, size_t count, unsigned int base, s8 *res);
-int __must_check kstrtobool_from_user(const char __user *s, size_t count, bool *res);
-
-static inline int __must_check kstrtou64_from_user(const char __user *s, size_t count, unsigned int base, u64 *res)
-{
-	return kstrtoull_from_user(s, count, base, res);
-}
-
-static inline int __must_check kstrtos64_from_user(const char __user *s, size_t count, unsigned int base, s64 *res)
-{
-	return kstrtoll_from_user(s, count, base, res);
-}
-
-static inline int __must_check kstrtou32_from_user(const char __user *s, size_t count, unsigned int base, u32 *res)
-{
-	return kstrtouint_from_user(s, count, base, res);
-}
-
-static inline int __must_check kstrtos32_from_user(const char __user *s, size_t count, unsigned int base, s32 *res)
-{
-	return kstrtoint_from_user(s, count, base, res);
-}
-
-/*
- * Use kstrto<foo> instead.
- *
- * NOTE: simple_strto<foo> does not check for the range overflow and,
- *	 depending on the input, may give interesting results.
- *
- * Use these functions if and only if you cannot use kstrto<foo>, because
- * the conversion ends on the first non-digit character, which may be far
- * beyond the supported range. It might be useful to parse the strings like
- * 10x50 or 12:21 without altering original string or temporary buffer in use.
- * Keep in mind above caveat.
- */
-
-extern unsigned long simple_strtoul(const char *,char **,unsigned int);
-extern long simple_strtol(const char *,char **,unsigned int);
-extern unsigned long long simple_strtoull(const char *,char **,unsigned int);
-extern long long simple_strtoll(const char *,char **,unsigned int);
 
 extern int num_to_str(char *buf, int size,
 		      unsigned long long num, unsigned int width);
@@ -519,12 +381,6 @@
 	return (u32)int_sqrt(x);
 }
 #endif
-
-#ifdef CONFIG_SMP
-extern unsigned int sysctl_oops_all_cpu_backtrace;
-#else
-#define sysctl_oops_all_cpu_backtrace 0
-#endif /* CONFIG_SMP */
 
 extern void bust_spinlocks(int yes);
 extern int panic_timeout;
diff --git a/kernel/include/linux/kernel_stat.h b/kernel/include/linux/kernel_stat.h
index 8fff350..1160e20 100644
--- a/kernel/include/linux/kernel_stat.h
+++ b/kernel/include/linux/kernel_stat.h
@@ -73,7 +73,7 @@
 /*
  * Number of interrupts per cpu, since bootup
  */
-static inline unsigned int kstat_cpu_irqs_sum(unsigned int cpu)
+static inline unsigned long kstat_cpu_irqs_sum(unsigned int cpu)
 {
 	return kstat_cpu(cpu).irqs_sum;
 }
diff --git a/kernel/include/linux/kexec.h b/kernel/include/linux/kexec.h
index a1f12e9..3c1deba 100644
--- a/kernel/include/linux/kexec.h
+++ b/kernel/include/linux/kexec.h
@@ -380,8 +380,8 @@
 extern bool kexec_in_progress;
 
 int crash_shrink_memory(unsigned long new_size);
-size_t crash_get_memory_size(void);
 void crash_free_reserved_phys_range(unsigned long begin, unsigned long end);
+ssize_t crash_get_memory_size(void);
 
 void arch_kexec_protect_crashkres(void);
 void arch_kexec_unprotect_crashkres(void);
diff --git a/kernel/include/linux/kprobes.h b/kernel/include/linux/kprobes.h
index 4dbebd3..18b7c40 100644
--- a/kernel/include/linux/kprobes.h
+++ b/kernel/include/linux/kprobes.h
@@ -342,6 +342,8 @@
 					     size_t *length, loff_t *ppos);
 #endif
 extern void wait_for_kprobe_optimizer(void);
+bool optprobe_queued_unopt(struct optimized_kprobe *op);
+bool kprobe_disarmed(struct kprobe *p);
 #else
 static inline void wait_for_kprobe_optimizer(void) { }
 #endif /* CONFIG_OPTPROBES */
diff --git a/kernel/include/linux/kstrtox.h b/kernel/include/linux/kstrtox.h
new file mode 100644
index 0000000..529974e
--- /dev/null
+++ b/kernel/include/linux/kstrtox.h
@@ -0,0 +1,155 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_KSTRTOX_H
+#define _LINUX_KSTRTOX_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+/* Internal, do not use. */
+int __must_check _kstrtoul(const char *s, unsigned int base, unsigned long *res);
+int __must_check _kstrtol(const char *s, unsigned int base, long *res);
+
+int __must_check kstrtoull(const char *s, unsigned int base, unsigned long long *res);
+int __must_check kstrtoll(const char *s, unsigned int base, long long *res);
+
+/**
+ * kstrtoul - convert a string to an unsigned long
+ * @s: The start of the string. The string must be null-terminated, and may also
+ *  include a single newline before its terminating null. The first character
+ *  may also be a plus sign, but not a minus sign.
+ * @base: The number base to use. The maximum supported base is 16. If base is
+ *  given as 0, then the base of the string is automatically detected with the
+ *  conventional semantics - If it begins with 0x the number will be parsed as a
+ *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
+ *  parsed as an octal number. Otherwise it will be parsed as a decimal.
+ * @res: Where to write the result of the conversion on success.
+ *
+ * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
+ * Preferred over simple_strtoul(). Return code must be checked.
+*/
+static inline int __must_check kstrtoul(const char *s, unsigned int base, unsigned long *res)
+{
+	/*
+	 * We want to shortcut function call, but
+	 * __builtin_types_compatible_p(unsigned long, unsigned long long) = 0.
+	 */
+	if (sizeof(unsigned long) == sizeof(unsigned long long) &&
+	    __alignof__(unsigned long) == __alignof__(unsigned long long))
+		return kstrtoull(s, base, (unsigned long long *)res);
+	else
+		return _kstrtoul(s, base, res);
+}
+
+/**
+ * kstrtol - convert a string to a long
+ * @s: The start of the string. The string must be null-terminated, and may also
+ *  include a single newline before its terminating null. The first character
+ *  may also be a plus sign or a minus sign.
+ * @base: The number base to use. The maximum supported base is 16. If base is
+ *  given as 0, then the base of the string is automatically detected with the
+ *  conventional semantics - If it begins with 0x the number will be parsed as a
+ *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
+ *  parsed as an octal number. Otherwise it will be parsed as a decimal.
+ * @res: Where to write the result of the conversion on success.
+ *
+ * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
+ * Preferred over simple_strtol(). Return code must be checked.
+ */
+static inline int __must_check kstrtol(const char *s, unsigned int base, long *res)
+{
+	/*
+	 * We want to shortcut function call, but
+	 * __builtin_types_compatible_p(long, long long) = 0.
+	 */
+	if (sizeof(long) == sizeof(long long) &&
+	    __alignof__(long) == __alignof__(long long))
+		return kstrtoll(s, base, (long long *)res);
+	else
+		return _kstrtol(s, base, res);
+}
+
+int __must_check kstrtouint(const char *s, unsigned int base, unsigned int *res);
+int __must_check kstrtoint(const char *s, unsigned int base, int *res);
+
+static inline int __must_check kstrtou64(const char *s, unsigned int base, u64 *res)
+{
+	return kstrtoull(s, base, res);
+}
+
+static inline int __must_check kstrtos64(const char *s, unsigned int base, s64 *res)
+{
+	return kstrtoll(s, base, res);
+}
+
+static inline int __must_check kstrtou32(const char *s, unsigned int base, u32 *res)
+{
+	return kstrtouint(s, base, res);
+}
+
+static inline int __must_check kstrtos32(const char *s, unsigned int base, s32 *res)
+{
+	return kstrtoint(s, base, res);
+}
+
+int __must_check kstrtou16(const char *s, unsigned int base, u16 *res);
+int __must_check kstrtos16(const char *s, unsigned int base, s16 *res);
+int __must_check kstrtou8(const char *s, unsigned int base, u8 *res);
+int __must_check kstrtos8(const char *s, unsigned int base, s8 *res);
+int __must_check kstrtobool(const char *s, bool *res);
+
+int __must_check kstrtoull_from_user(const char __user *s, size_t count, unsigned int base, unsigned long long *res);
+int __must_check kstrtoll_from_user(const char __user *s, size_t count, unsigned int base, long long *res);
+int __must_check kstrtoul_from_user(const char __user *s, size_t count, unsigned int base, unsigned long *res);
+int __must_check kstrtol_from_user(const char __user *s, size_t count, unsigned int base, long *res);
+int __must_check kstrtouint_from_user(const char __user *s, size_t count, unsigned int base, unsigned int *res);
+int __must_check kstrtoint_from_user(const char __user *s, size_t count, unsigned int base, int *res);
+int __must_check kstrtou16_from_user(const char __user *s, size_t count, unsigned int base, u16 *res);
+int __must_check kstrtos16_from_user(const char __user *s, size_t count, unsigned int base, s16 *res);
+int __must_check kstrtou8_from_user(const char __user *s, size_t count, unsigned int base, u8 *res);
+int __must_check kstrtos8_from_user(const char __user *s, size_t count, unsigned int base, s8 *res);
+int __must_check kstrtobool_from_user(const char __user *s, size_t count, bool *res);
+
+static inline int __must_check kstrtou64_from_user(const char __user *s, size_t count, unsigned int base, u64 *res)
+{
+	return kstrtoull_from_user(s, count, base, res);
+}
+
+static inline int __must_check kstrtos64_from_user(const char __user *s, size_t count, unsigned int base, s64 *res)
+{
+	return kstrtoll_from_user(s, count, base, res);
+}
+
+static inline int __must_check kstrtou32_from_user(const char __user *s, size_t count, unsigned int base, u32 *res)
+{
+	return kstrtouint_from_user(s, count, base, res);
+}
+
+static inline int __must_check kstrtos32_from_user(const char __user *s, size_t count, unsigned int base, s32 *res)
+{
+	return kstrtoint_from_user(s, count, base, res);
+}
+
+/*
+ * Use kstrto<foo> instead.
+ *
+ * NOTE: simple_strto<foo> does not check for the range overflow and,
+ *	 depending on the input, may give interesting results.
+ *
+ * Use these functions if and only if you cannot use kstrto<foo>, because
+ * the conversion ends on the first non-digit character, which may be far
+ * beyond the supported range. It might be useful to parse the strings like
+ * 10x50 or 12:21 without altering original string or temporary buffer in use.
+ * Keep in mind above caveat.
+ */
+
+extern unsigned long simple_strtoul(const char *,char **,unsigned int);
+extern long simple_strtol(const char *,char **,unsigned int);
+extern unsigned long long simple_strtoull(const char *,char **,unsigned int);
+extern long long simple_strtoll(const char *,char **,unsigned int);
+
+static inline int strtobool(const char *s, bool *res)
+{
+	return kstrtobool(s, res);
+}
+
+#endif	/* _LINUX_KSTRTOX_H */
diff --git a/kernel/include/linux/libata.h b/kernel/include/linux/libata.h
index d3600fc..1ceec83 100644
--- a/kernel/include/linux/libata.h
+++ b/kernel/include/linux/libata.h
@@ -187,7 +187,7 @@
 	ATA_LFLAG_NO_LPM	= (1 << 8), /* disable LPM on this link */
 	ATA_LFLAG_RST_ONCE	= (1 << 9), /* limit recovery to one reset */
 	ATA_LFLAG_CHANGED	= (1 << 10), /* LPM state changed on this link */
-	ATA_LFLAG_NO_DB_DELAY	= (1 << 11), /* no debounce delay on link resume */
+	ATA_LFLAG_NO_DEBOUNCE_DELAY = (1 << 11), /* no debounce delay on link resume */
 
 	/* struct ata_port flags */
 	ATA_FLAG_SLAVE_POSS	= (1 << 0), /* host supports slave dev */
@@ -260,6 +260,10 @@
 	ATA_HOST_PARALLEL_SCAN	= (1 << 2),	/* Ports on this host can be scanned in parallel */
 	ATA_HOST_IGNORE_ATA	= (1 << 3),	/* Ignore ATA devices on this host. */
 
+	ATA_HOST_NO_PART	= (1 << 4), /* Host does not support partial */
+	ATA_HOST_NO_SSC		= (1 << 5), /* Host does not support slumber */
+	ATA_HOST_NO_DEVSLP	= (1 << 6), /* Host does not support devslp */
+
 	/* bits 24:31 of host->flags are reserved for LLD specific flags */
 
 	/* various lengths of time */
@@ -293,7 +297,7 @@
 	 * advised to wait only for the following duration before
 	 * doing SRST.
 	 */
-	ATA_TMOUT_PMP_SRST_WAIT	= 5000,
+	ATA_TMOUT_PMP_SRST_WAIT	= 10000,
 
 	/* When the LPM policy is set to ATA_LPM_MAX_POWER, there might
 	 * be a spurious PHY event, so ignore the first PHY event that
diff --git a/kernel/include/linux/mailbox/zynqmp-ipi-message.h b/kernel/include/linux/mailbox/zynqmp-ipi-message.h
index 35ce84c..31d8046 100644
--- a/kernel/include/linux/mailbox/zynqmp-ipi-message.h
+++ b/kernel/include/linux/mailbox/zynqmp-ipi-message.h
@@ -9,7 +9,7 @@
  * @data: message payload
  *
  * This is the structure for data used in mbox_send_message
- * the maximum length of data buffer is fixed to 12 bytes.
+ * the maximum length of data buffer is fixed to 32 bytes.
  * Client is supposed to be aware of this.
  */
 struct zynqmp_ipi_message {
diff --git a/kernel/include/linux/mbcache.h b/kernel/include/linux/mbcache.h
index 20f1e3f..591bc4c 100644
--- a/kernel/include/linux/mbcache.h
+++ b/kernel/include/linux/mbcache.h
@@ -10,16 +10,29 @@
 
 struct mb_cache;
 
+/* Cache entry flags */
+enum {
+	MBE_REFERENCED_B = 0,
+	MBE_REUSABLE_B
+};
+
 struct mb_cache_entry {
 	/* List of entries in cache - protected by cache->c_list_lock */
 	struct list_head	e_list;
-	/* Hash table list - protected by hash chain bitlock */
+	/*
+	 * Hash table list - protected by hash chain bitlock. The entry is
+	 * guaranteed to be hashed while e_refcnt > 0.
+	 */
 	struct hlist_bl_node	e_hash_list;
+	/*
+	 * Entry refcount. Once it reaches zero, entry is unhashed and freed.
+	 * While refcount > 0, the entry is guaranteed to stay in the hash and
+	 * e.g. mb_cache_entry_try_delete() will fail.
+	 */
 	atomic_t		e_refcnt;
 	/* Key in hash - stable during lifetime of the entry */
 	u32			e_key;
-	u32			e_referenced:1;
-	u32			e_reusable:1;
+	unsigned long		e_flags;
 	/* User provided value - stable during lifetime of the entry */
 	u64			e_value;
 };
@@ -29,16 +42,24 @@
 
 int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key,
 			  u64 value, bool reusable);
-void __mb_cache_entry_free(struct mb_cache_entry *entry);
-static inline int mb_cache_entry_put(struct mb_cache *cache,
-				     struct mb_cache_entry *entry)
+void __mb_cache_entry_free(struct mb_cache *cache,
+			   struct mb_cache_entry *entry);
+void mb_cache_entry_wait_unused(struct mb_cache_entry *entry);
+static inline void mb_cache_entry_put(struct mb_cache *cache,
+				      struct mb_cache_entry *entry)
 {
-	if (!atomic_dec_and_test(&entry->e_refcnt))
-		return 0;
-	__mb_cache_entry_free(entry);
-	return 1;
+	unsigned int cnt = atomic_dec_return(&entry->e_refcnt);
+
+	if (cnt > 0) {
+		if (cnt <= 2)
+			wake_up_var(&entry->e_refcnt);
+		return;
+	}
+	__mb_cache_entry_free(cache, entry);
 }
 
+struct mb_cache_entry *mb_cache_entry_delete_or_get(struct mb_cache *cache,
+						    u32 key, u64 value);
 void mb_cache_entry_delete(struct mb_cache *cache, u32 key, u64 value);
 struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *cache, u32 key,
 					  u64 value);
diff --git a/kernel/include/linux/mfd/rk630.h b/kernel/include/linux/mfd/rk630.h
index e979894..53c67e8 100644
--- a/kernel/include/linux/mfd/rk630.h
+++ b/kernel/include/linux/mfd/rk630.h
@@ -17,149 +17,206 @@
 #define HIWORD_MASK(h, l)	((GENMASK((h), (l)) << 16) | GENMASK((h), (l)))
 #define HIWORD_UPDATE(v, h, l)	((((v) << (l)) & GENMASK((h), (l))) | (GENMASK((h), (l)) << 16))
 
-#define GRF_REG(x)                    ((x) + 0x20000)
-#define PLUMAGE_GRF_GPIO0A_IOMUX      GRF_REG(0x0000)
-#define GPIO0A0_SEL_MASK              HIWORD_MASK(1, 0)
-#define GPIO0A0_SEL(x)                HIWORD_UPDATE(x, 1, 0)
-#define GPIO0A1_SEL_MASK              HIWORD_MASK(3, 2)
-#define GPIO0A1_SEL(x)                HIWORD_UPDATE(x, 3, 2)
-#define GPIO0A2_SEL_MASK              HIWORD_MASK(5, 4)
-#define GPIO0A2_SEL(x)                HIWORD_UPDATE(x, 5, 4)
-#define GPIO0A3_SEL_MASK              HIWORD_MASK(7, 6)
-#define GPIO0A3_SEL(x)                HIWORD_UPDATE(x, 7, 6)
-#define GPIO0A4_SEL_MASK              HIWORD_MASK(9, 8)
-#define GPIO0A4_SEL(x)                HIWORD_UPDATE(x, 9, 8)
-#define GPIO0A5_SEL_MASK              HIWORD_MASK(11, 10)
-#define GPIO0A5_SEL(x)                HIWORD_UPDATE(x, 11, 10)
-#define GPIO0A6_SEL_MASK              HIWORD_MASK(13, 12)
-#define GPIO0A6_SEL(x)                HIWORD_UPDATE(x, 13, 12)
-#define GPIO0A7_SEL_MASK              HIWORD_MASK(15, 14)
-#define GPIO0A7_SEL(x)                HIWORD_UPDATE(x, 15, 14)
-#define PLUMAGE_GRF_GPIO0B_IOMUX      GRF_REG(0x0008)
-#define GPIO0B0_SEL_MASK              HIWORD_MASK(1, 0)
-#define GPIO0B0_SEL(x)                HIWORD_UPDATE(x, 1, 0)
-#define PLUMAGE_GRF_GPIO0C_IOMUX      GRF_REG(0x0010)
-#define PLUMAGE_GRF_GPIO0D_IOMUX      GRF_REG(0x0018)
-#define PLUMAGE_GRF_GPIO1A_IOMUX      GRF_REG(0x0020)
-#define PLUMAGE_GRF_GPIO1B_IOMUX      GRF_REG(0x0028)
-#define PLUMAGE_GRF_GPIO0A_P          GRF_REG(0x0080)
-#define PLUMAGE_GRF_GPIO0B_P          GRF_REG(0x0084)
-#define PLUMAGE_GRF_GPIO0C_P          GRF_REG(0x0088)
-#define PLUMAGE_GRF_GPIO0D_P          GRF_REG(0x008C)
-#define PLUMAGE_GRF_GPIO1A_P          GRF_REG(0x0090)
-#define PLUMAGE_GRF_GPIO1B_P          GRF_REG(0x0094)
-#define PLUMAGE_GRF_GPIO1B_SR         GRF_REG(0x00D4)
-#define PLUMAGE_GRF_GPIO1B_E          GRF_REG(0x0154)
-#define PLUMAGE_GRF_SOC_CON0          GRF_REG(0x0400)
-#define SW_TVE_DCLK_POL_MASK          HIWORD_MASK(4, 4)
-#define SW_TVE_DCLK_POL(x)            HIWORD_UPDATE(x, 4, 4)
-#define SW_TVE_DCLK_EN_MASK           HIWORD_MASK(3, 3)
-#define SW_TVE_DCLK_EN(x)             HIWORD_UPDATE(x, 3, 3)
-#define SW_DCLK_UPSAMPLE_EN_MASK      HIWORD_MASK(2, 2)
-#define SW_DCLK_UPSAMPLE_EN(x)        HIWORD_UPDATE(x, 2, 2)
-#define SW_TVE_MODE_MASK              HIWORD_MASK(1, 1)
-#define SW_TVE_MODE(x)                HIWORD_UPDATE(x, 1, 1)
-#define SW_TVE_EN_MASK                HIWORD_MASK(0, 0)
-#define SW_TVE_EN(x)                  HIWORD_UPDATE(x, 0, 0)
-#define PLUMAGE_GRF_SOC_CON1          GRF_REG(0x0404)
-#define PLUMAGE_GRF_SOC_CON2          GRF_REG(0x0408)
-#define PLUMAGE_GRF_SOC_CON3          GRF_REG(0x040C)
-#define VDAC_ENVBG_MASK               HIWORD_MASK(12, 12)
-#define VDAC_ENVBG(x)                 HIWORD_UPDATE(x, 12, 12)
-#define VDAC_ENSC0_MASK               HIWORD_MASK(11, 11)
-#define VDAC_ENSC0(x)                 HIWORD_UPDATE(x, 11, 11)
-#define VDAC_ENEXTREF_MASK            HIWORD_MASK(10, 10)
-#define VDAC_ENEXTREF(x)              HIWORD_UPDATE(x, 10, 10)
-#define VDAC_ENDAC0_MASK              HIWORD_MASK(9, 9)
-#define VDAC_ENDAC0(x)                HIWORD_UPDATE(x, 9, 9)
-#define VDAC_ENCTR2_MASK              HIWORD_MASK(8, 8)
-#define VDAC_ENCTR2(x)                HIWORD_UPDATE(x, 8, 8)
-#define VDAC_ENCTR1_MASK              HIWORD_MASK(7, 7)
-#define VDAC_ENCTR1(x)                HIWORD_UPDATE(x, 7, 7)
-#define VDAC_ENCTR0_MASK              HIWORD_MASK(6, 6)
-#define VDAC_ENCTR0(x)                HIWORD_UPDATE(x, 6, 6)
-#define VDAC_GAIN_MASK                GENMASK(x, 5, 0)
-#define VDAC_GAIN(x)                  HIWORD_UPDATE(x, 5, 0)
-#define PLUMAGE_GRF_SOC_CON4          GRF_REG(0x0410)
-#define PLUMAGE_GRF_SOC_STATUS        GRF_REG(0x0480)
-#define PLUMAGE_GRF_GPIO0_REN0        GRF_REG(0x0500)
-#define PLUMAGE_GRF_GPIO0_REN1        GRF_REG(0x0504)
-#define PLUMAGE_GRF_GPIO1_REN0        GRF_REG(0x0508)
-#define GRF_MAX_REGISTER              PLUMAGE_GRF_GPIO1_REN0
+#define RTC_REG(x)			((x) + 0x60000)
+#define RTC_SET_SECONDS			RTC_REG(0x0)
+#define RTC_SET_MINUTES			RTC_REG(0x4)
+#define RTC_SET_HOURS			RTC_REG(0x8)
+#define RTC_SET_DAYS			RTC_REG(0xc)
+#define RTC_SET_MONTHS			RTC_REG(0x10)
+#define RTC_SET_YEARL			RTC_REG(0x14)
+#define RTC_SET_YEARH			RTC_REG(0x18)
+#define RTC_SET_WEEKS			RTC_REG(0x1c)
+#define RTC_ALARM_SECONDS		RTC_REG(0x20)
+#define RTC_ALARM_MINUTES		RTC_REG(0x24)
+#define RTC_ALARM_HOURS			RTC_REG(0x28)
+#define RTC_ALARM_DAYS			RTC_REG(0x2c)
+#define RTC_ALARM_MONTHS		RTC_REG(0x30)
+#define RTC_ALARM_YEARL			RTC_REG(0x34)
+#define RTC_ALARM_YEARH			RTC_REG(0x38)
+#define RTC_CTRL			RTC_REG(0x3C)
+#define RTC_STATUS0			RTC_REG(0x40)
+#define RTC_STATUS1			RTC_REG(0x44)
+#define RTC_INT0_EN			RTC_REG(0x48)
+#define RTC_INT1_EN			RTC_REG(0x4c)
+#define RTC_MSEC_CTRL			RTC_REG(0x50)
+#define RTC_MSEC_CNT			RTC_REG(0x54)
+#define RTC_COMP_H			RTC_REG(0x58)
+#define RTC_COMP_D			RTC_REG(0x5c)
+#define RTC_COMP_M			RTC_REG(0x60)
+#define RTC_ANALOG_CTRL			RTC_REG(0x64)
+#define RTC_ANALOG_TEST			RTC_REG(0x68)
+#define RTC_LDO_CTRL			RTC_REG(0x6c)
+#define RTC_XO_TRIM0			RTC_REG(0x70)
+#define RTC_XO_TRIM1			RTC_REG(0x74)
+#define RTC_VPTAT_TRIM			RTC_REG(0x78)
+#define RTC_ANALOG_EN			RTC_REG(0x7c)
+#define RTC_CLK32K_TEST			RTC_REG(0x80)
+#define RTC_TEST_ST			RTC_REG(0x84)
+#define RTC_TEST_LEN			RTC_REG(0x88)
+#define RTC_CNT_0			RTC_REG(0x8c)
+#define RTC_CNT_1			RTC_REG(0x90)
+#define RTC_CNT_2			RTC_REG(0x94)
+#define RTC_CNT_3			RTC_REG(0x98)
+#define RTC_MAX_REGISTER		RTC_CNT_3
 
-#define CRU_REG(x)                    ((x) + 0x140000)
-#define CRU_SPLL_CON0                 CRU_REG(0x0000)
-#define POSTDIV1_MASK                 HIWORD_MASK(14, 12)
-#define POSTDIV1(x)                   HIWORD_UPDATE(x, 14, 12)
-#define FBDIV_MASK                    HIWORD_MASK(14, 12)
-#define FBDIV(x)                      HIWORD_UPDATE(x, 14, 12)
-#define CRU_SPLL_CON1                 CRU_REG(0x0004)
-#define PLLPD0_MASK                   HIWORD_MASK(13, 13)
-#define PLLPD0(x)                     HIWORD_UPDATE(x, 13, 13)
-#define PLL_LOCK                      BIT(10)
-#define POSTDIV2_MASK                 HIWORD_MASK(8, 6)
-#define POSTDIV2(x)                   HIWORD_UPDATE(x, 8, 6)
-#define REFDIV_MASK                   HIWORD_MASK(5, 0)
-#define REFDIV(x)                     HIWORD_UPDATE(x, 5, 0)
-#define CRU_SPLL_CON2                 CRU_REG(0x0008)
-#define CRU_MODE_CON                  CRU_REG(0x0020)
-#define CLK_SPLL_MODE_MASK            HIWORD_MASK(2, 0)
-#define CLK_SPLL_MODE(x)              HIWORD_UPDATE(x, 2, 0)
-#define CRU_CLKSEL_CON0               CRU_REG(0x0030)
-#define CRU_CLKSEL_CON1               CRU_REG(0x0034)
-#define DCLK_CVBS_4X_DIV_CON_MASK     HIWORD_MASK(12, 8)
-#define DCLK_CVBS_4X_DIV_CON(x)       HIWORD_UPDATE(x, 12, 8)
-#define CRU_CLKSEL_CON2               CRU_REG(0x0038)
-#define CRU_CLKSEL_CON3               CRU_REG(0x003c)
-#define CRU_GATE_CON0                 CRU_REG(0x0040)
-#define CRU_SOFTRST_CON0              CRU_REG(0x0050)
-#define DRESETN_CVBS_1X_MASK          HIWORD_MASK(10, 10)
-#define DRESETN_CVBS_1X(x)            HIWORD_UPDATE(x, 10, 10)
-#define DRESETN_CVBS_4X_MASK          HIWORD_MASK(9, 9)
-#define DRESETN_CVBS_4X(x)            HIWORD_UPDATE(x, 9, 9)
-#define PRESETN_CVBS_MASK             HIWORD_MASK(8, 8)
-#define PRESETN_CVBS(x)               HIWORD_UPDATE(x, 8, 8)
-#define PRESETN_GRF_MASK              HIWORD_MASK(3, 3)
-#define PRESETN_GRF(x)                HIWORD_UPDATE(x, 3, 3)
-#define CRU_MAX_REGISTER              CRU_SOFTRST_CON0
+#define GRF_REG(x)			((x) + 0x20000)
+#define PLUMAGE_GRF_GPIO0A_IOMUX	GRF_REG(0x0000)
+#define GPIO0A0_SEL_MASK		HIWORD_MASK(1, 0)
+#define GPIO0A0_SEL(x)			HIWORD_UPDATE(x, 1, 0)
+#define GPIO0A1_SEL_MASK		HIWORD_MASK(3, 2)
+#define GPIO0A1_SEL(x)			HIWORD_UPDATE(x, 3, 2)
+#define GPIO0A2_SEL_MASK		HIWORD_MASK(5, 4)
+#define GPIO0A2_SEL(x)			HIWORD_UPDATE(x, 5, 4)
+#define GPIO0A3_SEL_MASK		HIWORD_MASK(7, 6)
+#define GPIO0A3_SEL(x)			HIWORD_UPDATE(x, 7, 6)
+#define GPIO0A4_SEL_MASK		HIWORD_MASK(9, 8)
+#define GPIO0A4_SEL(x)			HIWORD_UPDATE(x, 9, 8)
+#define GPIO0A5_SEL_MASK		HIWORD_MASK(11, 10)
+#define GPIO0A5_SEL(x)			HIWORD_UPDATE(x, 11, 10)
+#define GPIO0A6_SEL_MASK		HIWORD_MASK(13, 12)
+#define GPIO0A6_SEL(x)			HIWORD_UPDATE(x, 13, 12)
+#define GPIO0A7_SEL_MASK		HIWORD_MASK(15, 14)
+#define GPIO0A7_SEL(x)			HIWORD_UPDATE(x, 15, 14)
+#define PLUMAGE_GRF_GPIO0B_IOMUX	GRF_REG(0x0008)
+#define GPIO0B0_SEL_MASK		HIWORD_MASK(1, 0)
+#define GPIO0B0_SEL(x)			HIWORD_UPDATE(x, 1, 0)
+#define PLUMAGE_GRF_GPIO0C_IOMUX	GRF_REG(0x0010)
+#define PLUMAGE_GRF_GPIO0D_IOMUX	GRF_REG(0x0018)
+#define PLUMAGE_GRF_GPIO1A_IOMUX	GRF_REG(0x0020)
+#define PLUMAGE_GRF_GPIO1B_IOMUX	GRF_REG(0x0028)
+#define PLUMAGE_GRF_GPIO0A_P		GRF_REG(0x0080)
+#define PLUMAGE_GRF_GPIO0B_P		GRF_REG(0x0084)
+#define PLUMAGE_GRF_GPIO0C_P		GRF_REG(0x0088)
+#define PLUMAGE_GRF_GPIO0D_P		GRF_REG(0x008C)
+#define PLUMAGE_GRF_GPIO1A_P		GRF_REG(0x0090)
+#define PLUMAGE_GRF_GPIO1B_P		GRF_REG(0x0094)
+#define PLUMAGE_GRF_GPIO1B_SR		GRF_REG(0x00D4)
+#define PLUMAGE_GRF_GPIO1B_E		GRF_REG(0x0154)
+#define PLUMAGE_GRF_SOC_CON0		GRF_REG(0x0400)
+#define RTC_CLAMP_EN_MASK		HIWORD_MASK(13, 13)
+#define RTC_CLAMP_EN(x)			HIWORD_UPDATE(x, 13, 13)
+#define SW_TVE_DCLK_POL_MASK		HIWORD_MASK(4, 4)
+#define SW_TVE_DCLK_POL(x)		HIWORD_UPDATE(x, 4, 4)
+#define SW_TVE_DCLK_POL_MASK		HIWORD_MASK(4, 4)
+#define SW_TVE_DCLK_POL(x)		HIWORD_UPDATE(x, 4, 4)
+#define SW_TVE_DCLK_EN_MASK		HIWORD_MASK(3, 3)
+#define SW_TVE_DCLK_EN(x)		HIWORD_UPDATE(x, 3, 3)
+#define SW_DCLK_UPSAMPLE_EN_MASK	HIWORD_MASK(2, 2)
+#define SW_DCLK_UPSAMPLE_EN(x)		HIWORD_UPDATE(x, 2, 2)
+#define SW_TVE_MODE_MASK		HIWORD_MASK(1, 1)
+#define SW_TVE_MODE(x)			HIWORD_UPDATE(x, 1, 1)
+#define SW_TVE_EN_MASK			HIWORD_MASK(0, 0)
+#define SW_TVE_EN(x)			HIWORD_UPDATE(x, 0, 0)
+#define PLUMAGE_GRF_SOC_CON1		GRF_REG(0x0404)
+#define PLUMAGE_GRF_SOC_CON2		GRF_REG(0x0408)
+#define PLUMAGE_GRF_SOC_CON3		GRF_REG(0x040C)
+#define VDAC_ENVBG_MASK			HIWORD_MASK(12, 12)
+#define VDAC_ENVBG(x)			HIWORD_UPDATE(x, 12, 12)
+#define VDAC_ENSC0_MASK			HIWORD_MASK(11, 11)
+#define VDAC_ENSC0(x)			HIWORD_UPDATE(x, 11, 11)
+#define VDAC_ENEXTREF_MASK		HIWORD_MASK(10, 10)
+#define VDAC_ENEXTREF(x)		HIWORD_UPDATE(x, 10, 10)
+#define VDAC_ENDAC0_MASK		HIWORD_MASK(9, 9)
+#define VDAC_ENDAC0(x)			HIWORD_UPDATE(x, 9, 9)
+#define VDAC_ENCTR2_MASK		HIWORD_MASK(8, 8)
+#define VDAC_ENCTR2(x)			HIWORD_UPDATE(x, 8, 8)
+#define VDAC_ENCTR1_MASK		HIWORD_MASK(7, 7)
+#define VDAC_ENCTR1(x)			HIWORD_UPDATE(x, 7, 7)
+#define VDAC_ENCTR0_MASK		HIWORD_MASK(6, 6)
+#define VDAC_ENCTR0(x)			HIWORD_UPDATE(x, 6, 6)
+#define VDAC_GAIN_MASK			GENMASK(x, 5, 0)
+#define VDAC_GAIN(x)			HIWORD_UPDATE(x, 5, 0)
+#define PLUMAGE_GRF_SOC_CON4		GRF_REG(0x0410)
+#define PLUMAGE_GRF_SOC_STATUS		GRF_REG(0x0480)
+#define PLUMAGE_GRF_GPIO0_REN0		GRF_REG(0x0500)
+#define PLUMAGE_GRF_GPIO0_REN1		GRF_REG(0x0504)
+#define PLUMAGE_GRF_GPIO1_REN0		GRF_REG(0x0508)
+#define PLUMAGE_GRF_RTC_STATUS		GRF_REG(0x0610)
 
-#define TVE_REG(x)                      ((x) + 0x10000)
-#define BT656_DECODER_CTRL              TVE_REG(0x3D00)
-#define BT656_DECODER_CROP              TVE_REG(0x3D04)
-#define BT656_DECODER_SIZE              TVE_REG(0x3D08)
-#define BT656_DECODER_HTOTAL_HS_END     TVE_REG(0x3D0C)
-#define BT656_DECODER_VACT_ST_HACT_ST   TVE_REG(0x3D10)
-#define BT656_DECODER_VTOTAL_VS_END     TVE_REG(0x3D14)
-#define BT656_DECODER_VS_ST_END_F1      TVE_REG(0x3D18)
-#define BT656_DECODER_DBG_REG           TVE_REG(0x3D1C)
-#define TVE_MODE_CTRL                   TVE_REG(0x3E00)
-#define TVE_HOR_TIMING1                 TVE_REG(0x3E04)
-#define TVE_HOR_TIMING2                 TVE_REG(0x3E08)
-#define TVE_HOR_TIMING3                 TVE_REG(0x3E0C)
-#define TVE_SUB_CAR_FRQ                 TVE_REG(0x3E10)
-#define TVE_LUMA_FILTER1                TVE_REG(0x3E14)
-#define TVE_LUMA_FILTER2                TVE_REG(0x3E18)
-#define TVE_LUMA_FILTER3                TVE_REG(0x3E1C)
-#define TVE_LUMA_FILTER4                TVE_REG(0x3E20)
-#define TVE_LUMA_FILTER5                TVE_REG(0x3E24)
-#define TVE_LUMA_FILTER6                TVE_REG(0x3E28)
-#define TVE_LUMA_FILTER7                TVE_REG(0x3E2C)
-#define TVE_LUMA_FILTER8                TVE_REG(0x3E30)
-#define TVE_IMAGE_POSITION              TVE_REG(0x3E34)
-#define TVE_ROUTING                     TVE_REG(0x3E38)
-#define TVE_SYNC_ADJUST                 TVE_REG(0x3E50)
-#define TVE_STATUS                      TVE_REG(0x3E54)
-#define TVE_CTRL                        TVE_REG(0x3E68)
-#define TVE_INTR_STATUS                 TVE_REG(0x3E6C)
-#define TVE_INTR_EN                     TVE_REG(0x3E70)
-#define TVE_INTR_CLR                    TVE_REG(0x3E74)
-#define TVE_COLOR_BUSRT_SAT             TVE_REG(0x3E78)
-#define TVE_CHROMA_BANDWIDTH            TVE_REG(0x3E8C)
-#define TVE_BRIGHTNESS_CONTRAST         TVE_REG(0x3E90)
-#define TVE_ID                          TVE_REG(0x3E98)
-#define TVE_REVISION                    TVE_REG(0x3E9C)
-#define TVE_CLAMP                       TVE_REG(0x3EA0)
-#define TVE_MAX_REGISTER                TVE_CLAMP
+#ifndef GRF_MAX_REGISTER
+#define GRF_MAX_REGISTER		PLUMAGE_GRF_RTC_STATUS
+#endif
+
+#define CRU_REG(x)			((x) + 0x140000)
+#define CRU_SPLL_CON0			CRU_REG(0x0000)
+#define POSTDIV1_MASK			HIWORD_MASK(14, 12)
+#define POSTDIV1(x)			HIWORD_UPDATE(x, 14, 12)
+#define FBDIV_MASK			HIWORD_MASK(14, 12)
+#define FBDIV(x)			HIWORD_UPDATE(x, 14, 12)
+#define CRU_SPLL_CON1			CRU_REG(0x0004)
+#define PLLPD0_MASK			HIWORD_MASK(13, 13)
+#define PLLPD0(x)			HIWORD_UPDATE(x, 13, 13)
+#define PLL_LOCK			BIT(10)
+#define POSTDIV2_MASK			HIWORD_MASK(8, 6)
+#define POSTDIV2(x)			HIWORD_UPDATE(x, 8, 6)
+#define REFDIV_MASK			HIWORD_MASK(5, 0)
+#define REFDIV(x)			HIWORD_UPDATE(x, 5, 0)
+#define CRU_SPLL_CON2			CRU_REG(0x0008)
+#define CRU_MODE_CON			CRU_REG(0x0020)
+#define CLK_SPLL_MODE_MASK		HIWORD_MASK(2, 0)
+#define CLK_SPLL_MODE(x)		HIWORD_UPDATE(x, 2, 0)
+#define CRU_CLKSEL_CON0			CRU_REG(0x0030)
+#define CRU_CLKSEL_CON1			CRU_REG(0x0034)
+#define DCLK_CVBS_4X_DIV_CON_MASK	HIWORD_MASK(12, 8)
+#define DCLK_CVBS_4X_DIV_CON(x)		HIWORD_UPDATE(x, 12, 8)
+#define CRU_CLKSEL_CON2			CRU_REG(0x0038)
+#define CRU_CLKSEL_CON3			CRU_REG(0x003c)
+#define CRU_GATE_CON0			CRU_REG(0x0040)
+#define CRU_SOFTRST_CON0		CRU_REG(0x0050)
+#define DRESETN_CVBS_1X_MASK		HIWORD_MASK(10, 10)
+#define DRESETN_CVBS_1X(x)		HIWORD_UPDATE(x, 10, 10)
+#define DRESETN_CVBS_4X_MASK		HIWORD_MASK(9, 9)
+#define DRESETN_CVBS_4X(x)		HIWORD_UPDATE(x, 9, 9)
+#define PRESETN_CVBS_MASK		HIWORD_MASK(8, 8)
+#define PRESETN_CVBS(x)			HIWORD_UPDATE(x, 8, 8)
+#define PRESETN_GRF_MASK		HIWORD_MASK(3, 3)
+#define PRESETN_GRF(x)			HIWORD_UPDATE(x, 3, 3)
+#define CRU_MAX_REGISTER		CRU_SOFTRST_CON0
+
+#define TVE_REG(x)			((x) + 0x10000)
+#define BT656_DECODER_CTRL		TVE_REG(0x3D00)
+#define BT656_DECODER_CROP		TVE_REG(0x3D04)
+#define BT656_DECODER_SIZE		TVE_REG(0x3D08)
+#define BT656_DECODER_HTOTAL_HS_END	TVE_REG(0x3D0C)
+#define BT656_DECODER_VACT_ST_HACT_ST	TVE_REG(0x3D10)
+#define BT656_DECODER_VTOTAL_VS_END	TVE_REG(0x3D14)
+#define BT656_DECODER_VS_ST_END_F1	TVE_REG(0x3D18)
+#define BT656_DECODER_DBG_REG		TVE_REG(0x3D1C)
+#define TVE_MODE_CTRL			TVE_REG(0x3E00)
+#define TVE_HOR_TIMING1			TVE_REG(0x3E04)
+#define TVE_HOR_TIMING2			TVE_REG(0x3E08)
+#define TVE_HOR_TIMING3			TVE_REG(0x3E0C)
+#define TVE_SUB_CAR_FRQ			TVE_REG(0x3E10)
+#define TVE_LUMA_FILTER1		TVE_REG(0x3E14)
+#define TVE_LUMA_FILTER2		TVE_REG(0x3E18)
+#define TVE_LUMA_FILTER3		TVE_REG(0x3E1C)
+#define TVE_LUMA_FILTER4		TVE_REG(0x3E20)
+#define TVE_LUMA_FILTER5		TVE_REG(0x3E24)
+#define TVE_LUMA_FILTER6		TVE_REG(0x3E28)
+#define TVE_LUMA_FILTER7		TVE_REG(0x3E2C)
+#define TVE_LUMA_FILTER8		TVE_REG(0x3E30)
+#define TVE_IMAGE_POSITION		TVE_REG(0x3E34)
+#define TVE_ROUTING			TVE_REG(0x3E38)
+#define TVE_SYNC_ADJUST			TVE_REG(0x3E50)
+#define TVE_STATUS			TVE_REG(0x3E54)
+#define TVE_CTRL			TVE_REG(0x3E68)
+#define TVE_INTR_STATUS			TVE_REG(0x3E6C)
+#define TVE_INTR_EN			TVE_REG(0x3E70)
+#define TVE_INTR_CLR			TVE_REG(0x3E74)
+#define TVE_COLOR_BUSRT_SAT		TVE_REG(0x3E78)
+#define TVE_CHROMA_BANDWIDTH		TVE_REG(0x3E8C)
+#define TVE_BRIGHTNESS_CONTRAST		TVE_REG(0x3E90)
+#define TVE_ID				TVE_REG(0x3E98)
+#define TVE_REVISION			TVE_REG(0x3E9C)
+#define TVE_CLAMP			TVE_REG(0x3EA0)
+#define TVE_MAX_REGISTER		TVE_CLAMP
+
+/* RK630 IRQ Definitions */
+#define RK630_IRQ_RTC_ALARM		0
+#define RK630_IRQ_SYS_INT		1
+
+#define RK630_IRQ_RTC_ALARM_MSK		BIT(7)
+#define RK630_IRQ_SYS_MSK		BIT(4)
 
 struct rk630 {
 	struct device *dev;
@@ -167,9 +224,14 @@
 	struct regmap *grf;
 	struct regmap *cru;
 	struct regmap *tve;
+	struct regmap *rtc;
 	struct gpio_desc *reset_gpio;
+	int irq;
+	struct regmap_irq_chip_data *irq_data;
+	const struct regmap_irq_chip *regmap_irq_chip;
 };
 
+extern const struct regmap_config rk630_rtc_regmap_config;
 extern const struct regmap_config rk630_grf_regmap_config;
 extern const struct regmap_config rk630_cru_regmap_config;
 extern const struct regmap_config rk630_tve_regmap_config;
diff --git a/kernel/include/linux/mfd/rk806.h b/kernel/include/linux/mfd/rk806.h
index 71e833c..7735121 100644
--- a/kernel/include/linux/mfd/rk806.h
+++ b/kernel/include/linux/mfd/rk806.h
@@ -6,6 +6,7 @@
 #ifndef __LINUX_REGULATOR_RK806_H
 #define __LINUX_REGULATOR_RK806_H
 
+#include <linux/of.h>
 #include <linux/regmap.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
@@ -518,7 +519,8 @@
 	int vb_lo_irq;
 };
 
-extern const struct regmap_config rk806_regmap_config_spi;
+extern const struct regmap_config rk806_regmap_config;
+extern const struct of_device_id rk806_of_match[];
 int rk806_device_init(struct rk806 *rk806);
 int rk806_device_exit(struct rk806 *rk806);
 int rk806_field_write(struct rk806 *rk806,
diff --git a/kernel/include/linux/mhi.h b/kernel/include/linux/mhi.h
index d4841e5..5d9f8c6 100644
--- a/kernel/include/linux/mhi.h
+++ b/kernel/include/linux/mhi.h
@@ -303,6 +303,7 @@
  * @rddm_size: RAM dump size that host should allocate for debugging purpose
  * @sbl_size: SBL image size downloaded through BHIe (optional)
  * @seg_len: BHIe vector size (optional)
+ * @reg_len: Length of the MHI MMIO region (required)
  * @fbc_image: Points to firmware image buffer
  * @rddm_image: Points to RAM dump buffer
  * @mhi_chan: Points to the channel configuration table
@@ -383,6 +384,7 @@
 	size_t rddm_size;
 	size_t sbl_size;
 	size_t seg_len;
+	size_t reg_len;
 	struct image_info *fbc_image;
 	struct image_info *rddm_image;
 	struct mhi_chan *mhi_chan;
diff --git a/kernel/include/linux/mlx5/driver.h b/kernel/include/linux/mlx5/driver.h
index ae88362..4f95b98 100644
--- a/kernel/include/linux/mlx5/driver.h
+++ b/kernel/include/linux/mlx5/driver.h
@@ -644,18 +644,22 @@
 	u8                         enabled;
 };
 
-struct mlx5_clock {
-	struct mlx5_nb             pps_nb;
-	seqlock_t                  lock;
+struct mlx5_timer {
 	struct cyclecounter        cycles;
 	struct timecounter         tc;
-	struct hwtstamp_config     hwtstamp_config;
 	u32                        nominal_c_mult;
 	unsigned long              overflow_period;
 	struct delayed_work        overflow_work;
+};
+
+struct mlx5_clock {
+	struct mlx5_nb             pps_nb;
+	seqlock_t                  lock;
+	struct hwtstamp_config     hwtstamp_config;
 	struct ptp_clock          *ptp;
 	struct ptp_clock_info      ptp_info;
 	struct mlx5_pps            pps_info;
+	struct mlx5_timer          timer;
 };
 
 struct mlx5_dm;
diff --git a/kernel/include/linux/mlx5/mlx5_ifc.h b/kernel/include/linux/mlx5/mlx5_ifc.h
index 6ca9772..88dbb20 100644
--- a/kernel/include/linux/mlx5/mlx5_ifc.h
+++ b/kernel/include/linux/mlx5/mlx5_ifc.h
@@ -8331,7 +8331,8 @@
 	u8         reserved_at_20[0x10];
 	u8         op_mod[0x10];
 
-	u8         reserved_at_40[0x38];
+	u8         reserved_at_40[0x33];
+	u8         flow_counter_bulk_log_size[0x5];
 	u8         flow_counter_bulk[0x8];
 };
 
diff --git a/kernel/include/linux/mmc/host.h b/kernel/include/linux/mmc/host.h
index 6fa9e47..45cbfce 100644
--- a/kernel/include/linux/mmc/host.h
+++ b/kernel/include/linux/mmc/host.h
@@ -503,6 +503,7 @@
 struct device_node;
 
 struct mmc_host *mmc_alloc_host(int extra, struct device *);
+struct mmc_host *devm_mmc_alloc_host(struct device *dev, int extra);
 int mmc_add_host(struct mmc_host *);
 void mmc_remove_host(struct mmc_host *);
 void mmc_free_host(struct mmc_host *);
diff --git a/kernel/include/linux/moduleloader.h b/kernel/include/linux/moduleloader.h
index 9e09d11..1322652 100644
--- a/kernel/include/linux/moduleloader.h
+++ b/kernel/include/linux/moduleloader.h
@@ -39,6 +39,11 @@
  */
 bool module_exit_section(const char *name);
 
+/* Describes whether within_module_init() will consider this an init section
+ * or not. This behaviour changes with CONFIG_MODULE_UNLOAD.
+ */
+bool module_init_layout_section(const char *sname);
+
 /*
  * Apply the given relocation to the (simplified) ELF.  Return -error
  * or 0.
diff --git a/kernel/include/linux/mtd/spinand.h b/kernel/include/linux/mtd/spinand.h
index 04dabc4..011caa6 100644
--- a/kernel/include/linux/mtd/spinand.h
+++ b/kernel/include/linux/mtd/spinand.h
@@ -256,6 +256,7 @@
 extern const struct spinand_manufacturer silicongo_spinand_manufacturer;
 extern const struct spinand_manufacturer skyhigh_spinand_manufacturer;
 extern const struct spinand_manufacturer unim_spinand_manufacturer;
+extern const struct spinand_manufacturer unim_zl_spinand_manufacturer;
 extern const struct spinand_manufacturer winbond_spinand_manufacturer;
 extern const struct spinand_manufacturer xincun_spinand_manufacturer;
 extern const struct spinand_manufacturer xtx_spinand_manufacturer;
diff --git a/kernel/include/linux/netdevice.h b/kernel/include/linux/netdevice.h
index 7e7a003..c795b34 100644
--- a/kernel/include/linux/netdevice.h
+++ b/kernel/include/linux/netdevice.h
@@ -264,9 +264,11 @@
  * relationship HH alignment <= LL alignment.
  */
 #define LL_RESERVED_SPACE(dev) \
-	((((dev)->hard_header_len+(dev)->needed_headroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
+	((((dev)->hard_header_len + READ_ONCE((dev)->needed_headroom)) \
+	  & ~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
 #define LL_RESERVED_SPACE_EXTRA(dev,extra) \
-	((((dev)->hard_header_len+(dev)->needed_headroom+(extra))&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
+	((((dev)->hard_header_len + READ_ONCE((dev)->needed_headroom) + (extra)) \
+	  & ~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
 
 struct header_ops {
 	int	(*create) (struct sk_buff *skb, struct net_device *dev,
@@ -749,8 +751,11 @@
 		/* We only give a hint, preemption can change CPU under us */
 		val |= raw_smp_processor_id();
 
-		if (table->ents[index] != val)
-			table->ents[index] = val;
+		/* The following WRITE_ONCE() is paired with the READ_ONCE()
+		 * here, and another one in get_rps_cpu().
+		 */
+		if (READ_ONCE(table->ents[index]) != val)
+			WRITE_ONCE(table->ents[index], val);
 	}
 }
 
@@ -1780,7 +1785,6 @@
  *	@tipc_ptr:	TIPC specific data
  *	@atalk_ptr:	AppleTalk link
  *	@ip_ptr:	IPv4 specific data
- *	@dn_ptr:	DECnet specific data
  *	@ip6_ptr:	IPv6 specific data
  *	@ax25_ptr:	AX.25 specific data
  *	@ieee80211_ptr:	IEEE 802.11 specific data, assign before registering
@@ -2059,9 +2063,6 @@
 	void 			*atalk_ptr;
 #endif
 	struct in_device __rcu	*ip_ptr;
-#if IS_ENABLED(CONFIG_DECNET)
-	struct dn_dev __rcu     *dn_ptr;
-#endif
 	struct inet6_dev __rcu	*ip6_ptr;
 #if IS_ENABLED(CONFIG_AX25)
 	void			*ax25_ptr;
@@ -4513,6 +4514,24 @@
 void __hw_addr_init(struct netdev_hw_addr_list *list);
 
 /* Functions used for device addresses handling */
+static inline void
+__dev_addr_set(struct net_device *dev, const u8 *addr, size_t len)
+{
+	memcpy(dev->dev_addr, addr, len);
+}
+
+static inline void dev_addr_set(struct net_device *dev, const u8 *addr)
+{
+	__dev_addr_set(dev, addr, dev->addr_len);
+}
+
+static inline void
+dev_addr_mod(struct net_device *dev, unsigned int offset,
+	     const u8 *addr, size_t len)
+{
+	memcpy(&dev->dev_addr[offset], addr, len);
+}
+
 int dev_addr_add(struct net_device *dev, const unsigned char *addr,
 		 unsigned char addr_type);
 int dev_addr_del(struct net_device *dev, const unsigned char *addr,
diff --git a/kernel/include/linux/netfilter.h b/kernel/include/linux/netfilter.h
index a12c285..819aace 100644
--- a/kernel/include/linux/netfilter.h
+++ b/kernel/include/linux/netfilter.h
@@ -240,11 +240,6 @@
 		hook_head = rcu_dereference(net->nf.hooks_bridge[hook]);
 #endif
 		break;
-#if IS_ENABLED(CONFIG_DECNET)
-	case NFPROTO_DECNET:
-		hook_head = rcu_dereference(net->nf.hooks_decnet[hook]);
-		break;
-#endif
 	default:
 		WARN_ON_ONCE(1);
 		break;
diff --git a/kernel/include/linux/netfilter/ipset/ip_set.h b/kernel/include/linux/netfilter/ipset/ip_set.h
index 773943b..9696421 100644
--- a/kernel/include/linux/netfilter/ipset/ip_set.h
+++ b/kernel/include/linux/netfilter/ipset/ip_set.h
@@ -202,7 +202,7 @@
 };
 
 /* Max range where every element is added/deleted in one step */
-#define IPSET_MAX_RANGE		(1<<20)
+#define IPSET_MAX_RANGE		(1<<14)
 
 /* The core set type structure */
 struct ip_set_type {
diff --git a/kernel/include/linux/netfilter/nfnetlink.h b/kernel/include/linux/netfilter/nfnetlink.h
index cdd98d7..b38e1dc 100644
--- a/kernel/include/linux/netfilter/nfnetlink.h
+++ b/kernel/include/linux/netfilter/nfnetlink.h
@@ -42,7 +42,6 @@
 	int (*commit)(struct net *net, struct sk_buff *skb);
 	int (*abort)(struct net *net, struct sk_buff *skb,
 		     enum nfnl_abort_action action);
-	void (*cleanup)(struct net *net);
 	bool (*valid_genid)(struct net *net, u32 genid);
 
 	ANDROID_KABI_RESERVE(1);
diff --git a/kernel/include/linux/netfilter_defs.h b/kernel/include/linux/netfilter_defs.h
index 8dddfb1..a5f7bef 100644
--- a/kernel/include/linux/netfilter_defs.h
+++ b/kernel/include/linux/netfilter_defs.h
@@ -7,14 +7,6 @@
 /* in/out/forward only */
 #define NF_ARP_NUMHOOKS 3
 
-/* max hook is NF_DN_ROUTE (6), also see uapi/linux/netfilter_decnet.h */
-#define NF_DN_NUMHOOKS 7
-
-#if IS_ENABLED(CONFIG_DECNET)
-/* Largest hook number + 1, see uapi/linux/netfilter_decnet.h */
-#define NF_MAX_HOOKS	NF_DN_NUMHOOKS
-#else
 #define NF_MAX_HOOKS	NF_INET_NUMHOOKS
-#endif
 
 #endif
diff --git a/kernel/include/linux/nfs_page.h b/kernel/include/linux/nfs_page.h
index f0373a6..40aa09a 100644
--- a/kernel/include/linux/nfs_page.h
+++ b/kernel/include/linux/nfs_page.h
@@ -145,7 +145,9 @@
 extern	void nfs_unlock_and_release_request(struct nfs_page *);
 extern	struct nfs_page *nfs_page_group_lock_head(struct nfs_page *req);
 extern	int nfs_page_group_lock_subrequests(struct nfs_page *head);
-extern	void nfs_join_page_group(struct nfs_page *head, struct inode *inode);
+extern void nfs_join_page_group(struct nfs_page *head,
+				struct nfs_commit_info *cinfo,
+				struct inode *inode);
 extern int nfs_page_group_lock(struct nfs_page *);
 extern void nfs_page_group_unlock(struct nfs_page *);
 extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int);
diff --git a/kernel/include/linux/nfs_xdr.h b/kernel/include/linux/nfs_xdr.h
index 5491ad5..33442fd 100644
--- a/kernel/include/linux/nfs_xdr.h
+++ b/kernel/include/linux/nfs_xdr.h
@@ -1789,6 +1789,8 @@
 	struct nfs_server *(*create_server)(struct fs_context *);
 	struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *,
 					   struct nfs_fattr *, rpc_authflavor_t);
+	void	(*enable_swap)(struct inode *inode);
+	void	(*disable_swap)(struct inode *inode);
 };
 
 /*
diff --git a/kernel/include/linux/nmi.h b/kernel/include/linux/nmi.h
index f700ff2..0db377f 100644
--- a/kernel/include/linux/nmi.h
+++ b/kernel/include/linux/nmi.h
@@ -197,7 +197,7 @@
 #endif
 
 #if defined(CONFIG_HARDLOCKUP_CHECK_TIMESTAMP) && \
-    defined(CONFIG_HARDLOCKUP_DETECTOR)
+    defined(CONFIG_HARDLOCKUP_DETECTOR_PERF)
 void watchdog_update_hrtimer_threshold(u64 period);
 #else
 static inline void watchdog_update_hrtimer_threshold(u64 period) { }
diff --git a/kernel/include/linux/nospec.h b/kernel/include/linux/nospec.h
index c1e79f7..9f0af4f 100644
--- a/kernel/include/linux/nospec.h
+++ b/kernel/include/linux/nospec.h
@@ -11,6 +11,10 @@
 
 struct task_struct;
 
+#ifndef barrier_nospec
+# define barrier_nospec() do { } while (0)
+#endif
+
 /**
  * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise
  * @index: array element index
diff --git a/kernel/include/linux/nvme-tcp.h b/kernel/include/linux/nvme-tcp.h
index 959e0bd..73364ae 100644
--- a/kernel/include/linux/nvme-tcp.h
+++ b/kernel/include/linux/nvme-tcp.h
@@ -114,8 +114,9 @@
 struct nvme_tcp_term_pdu {
 	struct nvme_tcp_hdr	hdr;
 	__le16			fes;
-	__le32			fei;
-	__u8			rsvd[8];
+	__le16			feil;
+	__le16			feiu;
+	__u8			rsvd[10];
 };
 
 /**
diff --git a/kernel/include/linux/nvme.h b/kernel/include/linux/nvme.h
index bfed36e..f454dd1 100644
--- a/kernel/include/linux/nvme.h
+++ b/kernel/include/linux/nvme.h
@@ -7,6 +7,7 @@
 #ifndef _LINUX_NVME_H
 #define _LINUX_NVME_H
 
+#include <linux/bits.h>
 #include <linux/types.h>
 #include <linux/uuid.h>
 
@@ -528,7 +529,7 @@
 	NVME_CMD_EFFECTS_NCC		= 1 << 2,
 	NVME_CMD_EFFECTS_NIC		= 1 << 3,
 	NVME_CMD_EFFECTS_CCC		= 1 << 4,
-	NVME_CMD_EFFECTS_CSE_MASK	= 3 << 16,
+	NVME_CMD_EFFECTS_CSE_MASK	= GENMASK(18, 16),
 	NVME_CMD_EFFECTS_UUID_SEL	= 1 << 19,
 };
 
@@ -602,6 +603,10 @@
 };
 
 enum {
+	NVME_AER_ERROR_PERSIST_INT_ERR	= 0x03,
+};
+
+enum {
 	NVME_AER_NOTICE_NS_CHANGED	= 0x00,
 	NVME_AER_NOTICE_FW_ACT_STARTING = 0x01,
 	NVME_AER_NOTICE_ANA		= 0x03,
diff --git a/kernel/include/linux/objtool.h b/kernel/include/linux/objtool.h
index 662f193..d17fa7f 100644
--- a/kernel/include/linux/objtool.h
+++ b/kernel/include/linux/objtool.h
@@ -71,6 +71,23 @@
 	static void __used __section(".discard.func_stack_frame_non_standard") \
 		*__func_stack_frame_non_standard_##func = func
 
+/*
+ * STACK_FRAME_NON_STANDARD_FP() is a frame-pointer-specific function ignore
+ * for the case where a function is intentionally missing frame pointer setup,
+ * but otherwise needs objtool/ORC coverage when frame pointers are disabled.
+ */
+#ifdef CONFIG_FRAME_POINTER
+#define STACK_FRAME_NON_STANDARD_FP(func) STACK_FRAME_NON_STANDARD(func)
+#else
+#define STACK_FRAME_NON_STANDARD_FP(func)
+#endif
+
+#define ANNOTATE_NOENDBR					\
+	"986: \n\t"						\
+	".pushsection .discard.noendbr\n\t"			\
+	_ASM_PTR " 986b\n\t"					\
+	".popsection\n\t"
+
 #else /* __ASSEMBLY__ */
 
 /*
@@ -117,6 +134,13 @@
 	.popsection
 .endm
 
+.macro ANNOTATE_NOENDBR
+.Lhere_\@:
+	.pushsection .discard.noendbr
+	.quad	.Lhere_\@
+	.popsection
+.endm
+
 #endif /* __ASSEMBLY__ */
 
 #else /* !CONFIG_STACK_VALIDATION */
@@ -126,10 +150,14 @@
 #define UNWIND_HINT(sp_reg, sp_offset, type, end)	\
 	"\n\t"
 #define STACK_FRAME_NON_STANDARD(func)
+#define STACK_FRAME_NON_STANDARD_FP(func)
+#define ANNOTATE_NOENDBR
 #else
 #define ANNOTATE_INTRA_FUNCTION_CALL
 .macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
 .endm
+.macro ANNOTATE_NOENDBR
+.endm
 #endif
 
 #endif /* CONFIG_STACK_VALIDATION */
diff --git a/kernel/include/linux/page_pinner.h b/kernel/include/linux/page_pinner.h
index ba14d76..6dd0f9d 100644
--- a/kernel/include/linux/page_pinner.h
+++ b/kernel/include/linux/page_pinner.h
@@ -41,6 +41,9 @@
 
 static inline void page_pinner_put_page(struct page *page)
 {
+	if (!static_branch_unlikely(&page_pinner_inited))
+		return;
+
 	if (!static_branch_unlikely(&failure_tracking))
 		return;
 
@@ -49,6 +52,9 @@
 
 static inline void page_pinner_failure_detect(struct page *page)
 {
+	if (!static_branch_unlikely(&page_pinner_inited))
+		return;
+
 	if (!static_branch_unlikely(&failure_tracking))
 		return;
 
diff --git a/kernel/include/linux/pci.h b/kernel/include/linux/pci.h
index 0bd9c16..dead6cc 100644
--- a/kernel/include/linux/pci.h
+++ b/kernel/include/linux/pci.h
@@ -1744,6 +1744,7 @@
 #define pci_dev_put(dev)	do { } while (0)
 
 static inline void pci_set_master(struct pci_dev *dev) { }
+static inline void pci_clear_master(struct pci_dev *dev) { }
 static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; }
 static inline void pci_disable_device(struct pci_dev *dev) { }
 static inline int pcim_enable_device(struct pci_dev *pdev) { return -EIO; }
diff --git a/kernel/include/linux/pci_ids.h b/kernel/include/linux/pci_ids.h
index 07e4354..85d149d 100644
--- a/kernel/include/linux/pci_ids.h
+++ b/kernel/include/linux/pci_ids.h
@@ -3040,6 +3040,8 @@
 #define PCI_DEVICE_ID_INTEL_VMD_9A0B	0x9a0b
 #define PCI_DEVICE_ID_INTEL_S21152BB	0xb152
 
+#define PCI_VENDOR_ID_WANGXUN		0x8088
+
 #define PCI_VENDOR_ID_SCALEMP		0x8686
 #define PCI_DEVICE_ID_SCALEMP_VSMP_CTL	0x1010
 
@@ -3120,6 +3122,8 @@
 
 #define PCI_VENDOR_ID_3COM_2		0xa727
 
+#define PCI_VENDOR_ID_SOLIDRUN		0xd063
+
 #define PCI_VENDOR_ID_DIGIUM		0xd161
 #define PCI_DEVICE_ID_DIGIUM_HFC4S	0xb410
 
diff --git a/kernel/include/linux/percpu-rwsem.h b/kernel/include/linux/percpu-rwsem.h
index 92d172c..55e80d1 100644
--- a/kernel/include/linux/percpu-rwsem.h
+++ b/kernel/include/linux/percpu-rwsem.h
@@ -107,7 +107,6 @@
 
 static inline void percpu_up_read(struct percpu_rw_semaphore *sem)
 {
-	_trace_android_vh_record_pcpu_rwsem_starttime(current, 0);
 	rwsem_release(&sem->dep_map, _RET_IP_);
 
 	preempt_disable();
@@ -130,6 +129,7 @@
 		this_cpu_dec(*sem->read_count);
 		rcuwait_wake_up(&sem->writer);
 	}
+	_trace_android_vh_record_pcpu_rwsem_starttime(current, 0);
 	preempt_enable();
 }
 
diff --git a/kernel/include/linux/perf_event.h b/kernel/include/linux/perf_event.h
index c945510..346d24a 100644
--- a/kernel/include/linux/perf_event.h
+++ b/kernel/include/linux/perf_event.h
@@ -1078,15 +1078,31 @@
 			     struct pt_regs *regs);
 
 static inline bool
-is_default_overflow_handler(struct perf_event *event)
+__is_default_overflow_handler(perf_overflow_handler_t overflow_handler)
 {
-	if (likely(event->overflow_handler == perf_event_output_forward))
+	if (likely(overflow_handler == perf_event_output_forward))
 		return true;
-	if (unlikely(event->overflow_handler == perf_event_output_backward))
+	if (unlikely(overflow_handler == perf_event_output_backward))
 		return true;
 	return false;
 }
 
+#define is_default_overflow_handler(event) \
+	__is_default_overflow_handler((event)->overflow_handler)
+
+#ifdef CONFIG_BPF_SYSCALL
+static inline bool uses_default_overflow_handler(struct perf_event *event)
+{
+	if (likely(is_default_overflow_handler(event)))
+		return true;
+
+	return __is_default_overflow_handler(event->orig_overflow_handler);
+}
+#else
+#define uses_default_overflow_handler(event) \
+	is_default_overflow_handler(event)
+#endif
+
 extern void
 perf_event_header__init_id(struct perf_event_header *header,
 			   struct perf_sample_data *data,
diff --git a/kernel/include/linux/pgtable.h b/kernel/include/linux/pgtable.h
index eb72450..774b9d0 100644
--- a/kernel/include/linux/pgtable.h
+++ b/kernel/include/linux/pgtable.h
@@ -89,7 +89,7 @@
 #ifndef pmd_offset
 static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
 {
-	return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address);
+	return pud_pgtable(*pud) + pmd_index(address);
 }
 #define pmd_offset pmd_offset
 #endif
@@ -97,7 +97,7 @@
 #ifndef pud_offset
 static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address)
 {
-	return (pud_t *)p4d_page_vaddr(*p4d) + pud_index(address);
+	return p4d_pgtable(*p4d) + pud_index(address);
 }
 #define pud_offset pud_offset
 #endif
diff --git a/kernel/include/linux/pipe_fs_i.h b/kernel/include/linux/pipe_fs_i.h
index 5d2705f..7b26a96 100644
--- a/kernel/include/linux/pipe_fs_i.h
+++ b/kernel/include/linux/pipe_fs_i.h
@@ -254,18 +254,14 @@
 
 extern const struct pipe_buf_operations nosteal_pipe_buf_ops;
 
-#ifdef CONFIG_WATCH_QUEUE
 unsigned long account_pipe_buffers(struct user_struct *user,
 				   unsigned long old, unsigned long new);
 bool too_many_pipe_buffers_soft(unsigned long user_bufs);
 bool too_many_pipe_buffers_hard(unsigned long user_bufs);
 bool pipe_is_unprivileged_user(void);
-#endif
 
 /* for F_SETPIPE_SZ and F_GETPIPE_SZ */
-#ifdef CONFIG_WATCH_QUEUE
 int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots);
-#endif
 long pipe_fcntl(struct file *, unsigned int, unsigned long arg);
 struct pipe_inode_info *get_pipe_info(struct file *file, bool for_splice);
 
diff --git a/kernel/include/linux/pm_wakeirq.h b/kernel/include/linux/pm_wakeirq.h
index cd5b62d..e63a63a 100644
--- a/kernel/include/linux/pm_wakeirq.h
+++ b/kernel/include/linux/pm_wakeirq.h
@@ -17,8 +17,8 @@
 #ifdef CONFIG_PM
 
 extern int dev_pm_set_wake_irq(struct device *dev, int irq);
-extern int dev_pm_set_dedicated_wake_irq(struct device *dev,
-					 int irq);
+extern int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq);
+extern int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq);
 extern void dev_pm_clear_wake_irq(struct device *dev);
 extern void dev_pm_enable_wake_irq(struct device *dev);
 extern void dev_pm_disable_wake_irq(struct device *dev);
@@ -35,6 +35,11 @@
 	return 0;
 }
 
+static inline int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq)
+{
+	return 0;
+}
+
 static inline void dev_pm_clear_wake_irq(struct device *dev)
 {
 }
diff --git a/kernel/include/linux/posix-timers.h b/kernel/include/linux/posix-timers.h
index 913aa60..8e28416 100644
--- a/kernel/include/linux/posix-timers.h
+++ b/kernel/include/linux/posix-timers.h
@@ -4,6 +4,7 @@
 
 #include <linux/spinlock.h>
 #include <linux/list.h>
+#include <linux/mutex.h>
 #include <linux/alarmtimer.h>
 #include <linux/timerqueue.h>
 #include <linux/task_work.h>
@@ -63,16 +64,18 @@
  * cpu_timer - Posix CPU timer representation for k_itimer
  * @node:	timerqueue node to queue in the task/sig
  * @head:	timerqueue head on which this timer is queued
- * @task:	Pointer to target task
+ * @pid:	Pointer to target task PID
  * @elist:	List head for the expiry list
  * @firing:	Timer is currently firing
+ * @handling:	Pointer to the task which handles expiry
  */
 struct cpu_timer {
-	struct timerqueue_node	node;
-	struct timerqueue_head	*head;
-	struct pid		*pid;
-	struct list_head	elist;
-	int			firing;
+	struct timerqueue_node		node;
+	struct timerqueue_head		*head;
+	struct pid			*pid;
+	struct list_head		elist;
+	int				firing;
+	struct task_struct __rcu	*handling;
 };
 
 static inline bool cpu_timer_enqueue(struct timerqueue_head *head,
@@ -129,10 +132,12 @@
 /**
  * posix_cputimers_work - Container for task work based posix CPU timer expiry
  * @work:	The task work to be scheduled
+ * @mutex:	Mutex held around expiry in context of this task work
  * @scheduled:  @work has been scheduled already, no further processing
  */
 struct posix_cputimers_work {
 	struct callback_head	work;
+	struct mutex		mutex;
 	unsigned int		scheduled;
 };
 
diff --git a/kernel/include/linux/power/bq27xxx_battery.h b/kernel/include/linux/power/bq27xxx_battery.h
index 8d5f4f4..6396419 100644
--- a/kernel/include/linux/power/bq27xxx_battery.h
+++ b/kernel/include/linux/power/bq27xxx_battery.h
@@ -2,6 +2,8 @@
 #ifndef __LINUX_BQ27X00_BATTERY_H__
 #define __LINUX_BQ27X00_BATTERY_H__
 
+#include <linux/power_supply.h>
+
 enum bq27xxx_chip {
 	BQ27000 = 1, /* bq27000, bq27200 */
 	BQ27010, /* bq27010, bq27210 */
@@ -67,7 +69,9 @@
 	struct bq27xxx_access_methods bus;
 	struct bq27xxx_reg_cache cache;
 	int charge_design_full;
+	bool removed;
 	unsigned long last_update;
+	union power_supply_propval last_status;
 	struct delayed_work work;
 	struct power_supply *bat;
 	struct list_head list;
diff --git a/kernel/include/linux/power_supply.h b/kernel/include/linux/power_supply.h
index c452d59..e85901b 100644
--- a/kernel/include/linux/power_supply.h
+++ b/kernel/include/linux/power_supply.h
@@ -476,8 +476,9 @@
 				int table_len, int temp);
 extern void power_supply_changed(struct power_supply *psy);
 extern int power_supply_am_i_supplied(struct power_supply *psy);
-extern int power_supply_set_input_current_limit_from_supplier(
-					 struct power_supply *psy);
+int power_supply_get_property_from_supplier(struct power_supply *psy,
+					    enum power_supply_property psp,
+					    union power_supply_propval *val);
 extern int power_supply_set_battery_charged(struct power_supply *psy);
 
 #ifdef CONFIG_POWER_SUPPLY
diff --git a/kernel/include/linux/printk.h b/kernel/include/linux/printk.h
index 14d13ec..f976a13 100644
--- a/kernel/include/linux/printk.h
+++ b/kernel/include/linux/printk.h
@@ -627,4 +627,23 @@
 #define print_hex_dump_bytes(prefix_str, prefix_type, buf, len)	\
 	print_hex_dump_debug(prefix_str, prefix_type, 16, 1, buf, len, true)
 
+#ifdef CONFIG_PRINTK
+extern void __printk_safe_enter(void);
+extern void __printk_safe_exit(void);
+/*
+ * The printk_deferred_enter/exit macros are available only as a hack for
+ * some code paths that need to defer all printk console printing. Interrupts
+ * must be disabled for the deferred duration.
+ */
+#define printk_deferred_enter __printk_safe_enter
+#define printk_deferred_exit __printk_safe_exit
+#else
+static inline void printk_deferred_enter(void)
+{
+}
+static inline void printk_deferred_exit(void)
+{
+}
+#endif
+
 #endif
diff --git a/kernel/include/linux/proc_fs.h b/kernel/include/linux/proc_fs.h
index 000cc05..8c89273 100644
--- a/kernel/include/linux/proc_fs.h
+++ b/kernel/include/linux/proc_fs.h
@@ -190,8 +190,10 @@
 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)
 {
diff --git a/kernel/include/linux/pwm-rockchip.h b/kernel/include/linux/pwm-rockchip.h
new file mode 100644
index 0000000..60e42aa
--- /dev/null
+++ b/kernel/include/linux/pwm-rockchip.h
@@ -0,0 +1,187 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef _PWM_ROCKCHIP_H_
+#define _PWM_ROCKCHIP_H_
+
+#include <linux/pwm.h>
+
+/**
+ * enum rockchip_pwm_global_ctrl_cmd - commands for pwm global ctrl
+ * @PWM_GLOBAL_CTRL_JOIN: join the global control group
+ * @PWM_GLOBAL_CTRL_EXIT: exit the global control group
+ * @PWM_GLOBAL_CTRL_GRANT: obtian the permission of global control
+ * @PWM_GLOBAL_CTRL_RECLAIM: reclaim the permission of global control
+ * @PWM_GLOBAL_CTRL_UPDATE: update the configs for all channels in group
+ * @PWM_GLOBAL_CTRL_ENABLE: enable all channels in group
+ * @PWM_GLOBAL_CTRL_DISABLE: disable all channels in group
+ */
+enum rockchip_pwm_global_ctrl_cmd {
+	PWM_GLOBAL_CTRL_JOIN,
+	PWM_GLOBAL_CTRL_EXIT,
+	PWM_GLOBAL_CTRL_GRANT,
+	PWM_GLOBAL_CTRL_RECLAIM,
+	PWM_GLOBAL_CTRL_UPDATE,
+	PWM_GLOBAL_CTRL_ENABLE,
+	PWM_GLOBAL_CTRL_DISABLE,
+};
+
+/**
+ * struct rockchip_pwm_wave_table - wave table config object
+ * @offset: the offset of wave table to set
+ * @len: the length of wave table to set
+ * @table: the values of wave table to set
+ * @
+ */
+struct rockchip_pwm_wave_table {
+	u16 offset;
+	u16 len;
+	u64 *table;
+};
+
+/**
+ * enum rockchip_pwm_wave_table_width_mode - element width of pwm wave table
+ * @PWM_WAVE_TABLE_8BITS_WIDTH: each element in table is 8bits
+ * @PWM_WAVE_TABLE_16BITS_WIDTH: each element in table is 16bits
+ */
+enum rockchip_pwm_wave_table_width_mode {
+	PWM_WAVE_TABLE_8BITS_WIDTH,
+	PWM_WAVE_TABLE_16BITS_WIDTH,
+};
+
+/**
+ * enum rockchip_pwm_wave_update_mode - update mode of wave generator
+ * @PWM_WAVE_INCREASING:
+ *     The wave table address will wrap back to minimum address when increase to
+ *     maximum and then increase again.
+ * @PWM_WAVE_INCREASING_THEN_DECREASING:
+ *     The wave table address will change to decreasing when increasing to the maximum
+ *     address. it will return to increasing when decrease to the minimum value.
+ */
+enum rockchip_pwm_wave_update_mode {
+	PWM_WAVE_INCREASING,
+	PWM_WAVE_INCREASING_THEN_DECREASING,
+};
+
+/**
+ * struct rockchip_pwm_wave_config - wave generator config object
+ * @duty_table: the wave table config of duty
+ * @period_table: the wave table config of period
+ * @enable: enable or disable wave generator
+ * @duty_en: to update duty by duty table or not
+ * @period_en: to update period by period table or not
+ * @width_mode: the width mode of wave table
+ * @update_mode: the update mode of wave generator
+ * @duty_max: the maximum address of duty table
+ * @duty_min: the minimum address of duty table
+ * @period_max: the maximum address of period table
+ * @period_min: the minimum address of period table
+ * @offset: the initial offset address of duty and period
+ * @middle: the middle address of duty and period
+ * @max_hold: the time to stop at maximum address
+ * @min_hold: the time to stop at minimum address
+ * @middle_hold: the time to stop at middle address
+ */
+struct rockchip_pwm_wave_config {
+	struct rockchip_pwm_wave_table *duty_table;
+	struct rockchip_pwm_wave_table *period_table;
+	bool enable;
+	bool duty_en;
+	bool period_en;
+	u16 rpt;
+	u32 width_mode;
+	u32 update_mode;
+	u32 duty_max;
+	u32 duty_min;
+	u32 period_max;
+	u32 period_min;
+	u32 offset;
+	u32 middle;
+	u32 max_hold;
+	u32 min_hold;
+	u32 middle_hold;
+};
+
+#if IS_REACHABLE(CONFIG_PWM_ROCKCHIP)
+/**
+ * rockchip_pwm_set_counter() - setup pwm counter mode
+ * @pwm: PWM device
+ * @enable: enable/disable counter mode
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int rockchip_pwm_set_counter(struct pwm_device *pwm, bool enable);
+
+/**
+ * rockchip_pwm_get_counter_result() - get counter result
+ * @pwm: PWM device
+ * @counter_res: number of input waveforms
+ * @is_clear: clear counter result or not
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int rockchip_pwm_get_counter_result(struct pwm_device *pwm,
+				    unsigned long *counter_res, bool is_clear);
+
+/**
+ * rockchip_pwm_set_freq_meter() - setup pwm frequency meter mode
+ * @pwm: PWM device
+ * @delay_ms: time to wait, in milliseconds, before getting frequency meter result
+ * @freq_hz: parameter in Hz to fill with frequency meter result
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int rockchip_pwm_set_freq_meter(struct pwm_device *pwm, unsigned long delay_ms,
+				unsigned long *freq_hz);
+
+/**
+ * rockchip_pwm_global_ctrl() - execute global control commands
+ * @pwm: PWM device
+ * @cmd: command type to execute
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int rockchip_pwm_global_ctrl(struct pwm_device *pwm, enum rockchip_pwm_global_ctrl_cmd cmd);
+
+/**
+ * rockchip_pwm_set_wave() - setup pwm wave generator mode
+ * @pwm: PWM device
+ * @config: configs of wave generator mode
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int rockchip_pwm_set_wave(struct pwm_device *pwm, struct rockchip_pwm_wave_config *config);
+#else
+static inline int rockchip_pwm_set_counter(struct pwm_device *pwm, bool enable)
+{
+	return 0;
+}
+
+static inline int rockchip_pwm_get_counter_result(struct pwm_device *pwm,
+						  unsigned long *counter_res, bool is_clear)
+{
+	return 0;
+}
+
+static inline int rockchip_pwm_set_freq_meter(struct pwm_device *pwm, unsigned long delay_ms,
+					      unsigned long *freq_hz)
+{
+	return 0;
+}
+
+static inline  int rockchip_pwm_global_ctrl(struct pwm_device *pwm,
+					    enum rockchip_pwm_global_ctrl_cmd cmd)
+{
+	return 0;
+}
+
+static inline int rockchip_pwm_set_wave(struct pwm_device *pwm,
+					struct rockchip_pwm_wave_config *config)
+{
+	return 0;
+}
+#endif
+
+#endif /* _PWM_ROCKCHIP_H_ */
diff --git a/kernel/include/linux/pwm.h b/kernel/include/linux/pwm.h
index b05d417..50d44f7 100644
--- a/kernel/include/linux/pwm.h
+++ b/kernel/include/linux/pwm.h
@@ -74,6 +74,8 @@
 	enum pwm_output_type output_type;
 #ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
 	u64 oneshot_count;
+	u32 oneshot_repeat;
+	u64 duty_offset;
 #endif /* CONFIG_PWM_ROCKCHIP_ONESHOT */
 	bool enabled;
 };
diff --git a/kernel/include/linux/raid_class.h b/kernel/include/linux/raid_class.h
index 5cdfcb8..772d45b 100644
--- a/kernel/include/linux/raid_class.h
+++ b/kernel/include/linux/raid_class.h
@@ -77,7 +77,3 @@
 	
 struct raid_template *raid_class_attach(struct raid_function_template *);
 void raid_class_release(struct raid_template *);
-
-int __must_check raid_component_add(struct raid_template *, struct device *,
-				    struct device *);
-
diff --git a/kernel/include/linux/ramfs.h b/kernel/include/linux/ramfs.h
index 917528d..d506dc6 100644
--- a/kernel/include/linux/ramfs.h
+++ b/kernel/include/linux/ramfs.h
@@ -7,6 +7,7 @@
 struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir,
 	 umode_t mode, dev_t dev);
 extern int ramfs_init_fs_context(struct fs_context *fc);
+extern void ramfs_kill_sb(struct super_block *sb);
 
 #ifdef CONFIG_MMU
 static inline int
diff --git a/kernel/include/linux/random.h b/kernel/include/linux/random.h
index 9246d87..5fdd133 100644
--- a/kernel/include/linux/random.h
+++ b/kernel/include/linux/random.h
@@ -19,14 +19,14 @@
 void add_interrupt_randomness(int irq) __latent_entropy;
 void add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy);
 
-#if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__)
 static inline void add_latent_entropy(void)
 {
+#if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__)
 	add_device_randomness((const void *)&latent_entropy, sizeof(latent_entropy));
-}
 #else
-static inline void add_latent_entropy(void) { }
+	add_device_randomness(NULL, 0);
 #endif
+}
 
 void get_random_bytes(void *buf, int len);
 int __must_check get_random_bytes_arch(void *buf, int len);
diff --git a/kernel/include/linux/rcupdate.h b/kernel/include/linux/rcupdate.h
index 095b3b3..a833efa 100644
--- a/kernel/include/linux/rcupdate.h
+++ b/kernel/include/linux/rcupdate.h
@@ -83,7 +83,7 @@
 
 /* Internal to kernel */
 void rcu_init(void);
-extern int rcu_scheduler_active __read_mostly;
+extern int rcu_scheduler_active;
 void rcu_sched_clock_irq(int user);
 void rcu_report_dead(unsigned int cpu);
 void rcutree_migrate_callbacks(int cpu);
@@ -189,6 +189,7 @@
 
 #define rcu_note_voluntary_context_switch(t) rcu_tasks_qs(t, false)
 void exit_tasks_rcu_start(void);
+void exit_tasks_rcu_stop(void);
 void exit_tasks_rcu_finish(void);
 #else /* #ifdef CONFIG_TASKS_RCU_GENERIC */
 #define rcu_tasks_qs(t, preempt) do { } while (0)
@@ -196,6 +197,7 @@
 #define call_rcu_tasks call_rcu
 #define synchronize_rcu_tasks synchronize_rcu
 static inline void exit_tasks_rcu_start(void) { }
+static inline void exit_tasks_rcu_stop(void) { }
 static inline void exit_tasks_rcu_finish(void) { }
 #endif /* #else #ifdef CONFIG_TASKS_RCU_GENERIC */
 
@@ -306,11 +308,18 @@
  * RCU_LOCKDEP_WARN - emit lockdep splat if specified condition is met
  * @c: condition to check
  * @s: informative message
+ *
+ * This checks debug_lockdep_rcu_enabled() before checking (c) to
+ * prevent early boot splats due to lockdep not yet being initialized,
+ * and rechecks it after checking (c) to prevent false-positive splats
+ * due to races with lockdep being disabled.  See commit 3066820034b5dd
+ * ("rcu: Reject RCU_LOCKDEP_WARN() false positives") for more detail.
  */
 #define RCU_LOCKDEP_WARN(c, s)						\
 	do {								\
 		static bool __section(".data.unlikely") __warned;	\
-		if ((c) && debug_lockdep_rcu_enabled() && !__warned) {	\
+		if (debug_lockdep_rcu_enabled() && (c) &&		\
+		    debug_lockdep_rcu_enabled() && !__warned) {		\
 			__warned = true;				\
 			lockdep_rcu_suspicious(__FILE__, __LINE__, s);	\
 		}							\
diff --git a/kernel/include/linux/rcutree.h b/kernel/include/linux/rcutree.h
index 59eb5cd..a4567b2 100644
--- a/kernel/include/linux/rcutree.h
+++ b/kernel/include/linux/rcutree.h
@@ -60,7 +60,7 @@
 void exit_rcu(void);
 
 void rcu_scheduler_starting(void);
-extern int rcu_scheduler_active __read_mostly;
+extern int rcu_scheduler_active;
 void rcu_end_inkernel_boot(void);
 bool rcu_inkernel_boot_has_ended(void);
 bool rcu_is_watching(void);
diff --git a/kernel/include/linux/regulator/pca9450.h b/kernel/include/linux/regulator/pca9450.h
index 71902f4..0c3edff 100644
--- a/kernel/include/linux/regulator/pca9450.h
+++ b/kernel/include/linux/regulator/pca9450.h
@@ -196,11 +196,11 @@
 
 /* PCA9450_REG_LDO3_VOLT bits */
 #define LDO3_EN_MASK			0xC0
-#define LDO3OUT_MASK			0x0F
+#define LDO3OUT_MASK			0x1F
 
 /* PCA9450_REG_LDO4_VOLT bits */
 #define LDO4_EN_MASK			0xC0
-#define LDO4OUT_MASK			0x0F
+#define LDO4OUT_MASK			0x1F
 
 /* PCA9450_REG_LDO5_VOLT bits */
 #define LDO5L_EN_MASK			0xC0
diff --git a/kernel/include/linux/rmap.h b/kernel/include/linux/rmap.h
index 0a4d49c..5a64e48 100644
--- a/kernel/include/linux/rmap.h
+++ b/kernel/include/linux/rmap.h
@@ -42,13 +42,7 @@
 	 */
 	atomic_t refcount;
 
-	/*
-	 * Count of child anon_vmas and VMAs which points to this anon_vma.
-	 *
-	 * This counter is used for making decision about reusing anon_vma
-	 * instead of forking new one. See comments in function anon_vma_clone.
-	 */
-	unsigned degree;
+	unsigned degree;		/* ANDROID: KABI preservation, DO NOT USE! */
 
 	struct anon_vma *parent;	/* Parent of this anon_vma */
 
@@ -63,6 +57,25 @@
 
 	/* Interval tree of private "related" vmas */
 	struct rb_root_cached rb_root;
+
+	/*
+	 * ANDROID: KABI preservation, it's safe to put these at the end of this structure as it's
+	 * only passed by a pointer everywhere, the size and internal structures are local to the
+	 * core kernel.
+	 */
+#ifndef __GENKSYMS__
+	/*
+	 * Count of child anon_vmas. Equals to the count of all anon_vmas that
+	 * have ->parent pointing to this one, including itself.
+	 *
+	 * This counter is used for making decision about reusing anon_vma
+	 * instead of forking new one. See comments in function anon_vma_clone.
+	 */
+	unsigned long num_children;
+	/* Count of VMAs whose ->anon_vma pointer points to this object. */
+	unsigned long num_active_vmas;
+#endif
+
 };
 
 /*
diff --git a/kernel/include/linux/rockchip/rockchip_pm_config.h b/kernel/include/linux/rockchip/rockchip_pm_config.h
new file mode 100644
index 0000000..2c95b04
--- /dev/null
+++ b/kernel/include/linux/rockchip/rockchip_pm_config.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __ROCKCHIP_PM_CONFIG_H
+#define __ROCKCHIP_PM_CONFIG_H
+
+struct rk_sleep_config {
+	u32 mode_config;
+	u32 wakeup_config;
+	u32 sleep_debug_en;
+	u32 pwm_regulator_config;
+	u32 *power_ctrl_config;
+	u32 power_ctrl_config_cnt;
+	u32 *sleep_io_config;
+	u32 sleep_io_config_cnt;
+	u32 apios_suspend;
+	u32 io_ret_config;
+	u32 sleep_pin_config[2];
+};
+
+#if IS_REACHABLE(CONFIG_ROCKCHIP_SUSPEND_MODE)
+const struct rk_sleep_config *rockchip_get_cur_sleep_config(void);
+#else
+static inline const struct rk_sleep_config *rockchip_get_cur_sleep_config(void)
+{
+	return NULL;
+}
+#endif
+
+#endif /* __ROCKCHIP_PM_CONFIG_H */
diff --git a/kernel/include/linux/rockchip/rockchip_sip.h b/kernel/include/linux/rockchip/rockchip_sip.h
index 717f0e8..70b1493 100644
--- a/kernel/include/linux/rockchip/rockchip_sip.h
+++ b/kernel/include/linux/rockchip/rockchip_sip.h
@@ -57,6 +57,7 @@
 #define SIP_WDT_CFG			0x82000026
 #define SIP_HDMIRX_CFG			0x82000027
 #define SIP_MCU_CFG			0x82000028
+#define SIP_PVTPLL_CFG			0x82000029
 
 #define TRUSTED_OS_HDCPKEY_INIT		0xB7000003
 
@@ -226,6 +227,13 @@
 	HDMIRX_INFO_NOTIFY = 2,
 };
 
+/* SIP_PVTPLL_CFG child configs */
+enum {
+	PVTPLL_GET_INFO = 0,
+	PVTPLL_ADJUST_TABLE = 1,
+	PVTPLL_LOW_TEMP = 2,
+};
+
 struct pt_regs;
 typedef void (*sip_fiq_debugger_uart_irq_tf_cb_t)(struct pt_regs *_pt_regs, unsigned long cpu);
 
@@ -256,6 +264,9 @@
 struct dram_addrmap_info *sip_smc_get_dram_map(void);
 int sip_smc_amp_config(u32 sub_func_id, u32 arg1, u32 arg2, u32 arg3);
 struct arm_smccc_res sip_smc_get_amp_info(u32 sub_func_id, u32 arg1);
+struct arm_smccc_res sip_smc_get_pvtpll_info(u32 sub_func_id, u32 arg1);
+struct arm_smccc_res sip_smc_pvtpll_config(u32 sub_func_id, u32 arg1, u32 arg2,
+					   u32 arg3, u32 arg4, u32 arg5, u32 arg6);
 
 void __iomem *sip_hdcp_request_share_memory(int id);
 struct arm_smccc_res sip_hdcp_config(u32 arg0, u32 arg1, u32 arg2);
@@ -365,6 +376,24 @@
 	return tmp;
 }
 
+static inline struct arm_smccc_res sip_smc_get_pvtpll_info(u32 sub_func_id,
+							   u32 arg1)
+{
+	struct arm_smccc_res tmp = { .a0 = SIP_RET_NOT_SUPPORTED, };
+
+	return tmp;
+}
+
+static inline struct arm_smccc_res sip_smc_pvtpll_config(u32 sub_func_id,
+							 u32 arg1, u32 arg2,
+							 u32 arg3, u32 arg4,
+							 u32 arg5, u32 arg6)
+{
+	struct arm_smccc_res tmp = { .a0 = SIP_RET_NOT_SUPPORTED, };
+
+	return tmp;
+}
+
 static inline void __iomem *sip_hdcp_request_share_memory(int id)
 {
 	return NULL;
diff --git a/kernel/include/linux/rpmsg.h b/kernel/include/linux/rpmsg.h
index 7cbb0fb..f4e0cd6 100644
--- a/kernel/include/linux/rpmsg.h
+++ b/kernel/include/linux/rpmsg.h
@@ -145,6 +145,8 @@
 int rpmsg_get_signals(struct rpmsg_endpoint *ept);
 int rpmsg_set_signals(struct rpmsg_endpoint *ept, u32 set, u32 clear);
 
+ssize_t rpmsg_get_mtu(struct rpmsg_endpoint *ept);
+
 #else
 
 static inline int register_rpmsg_device(struct rpmsg_device *dev)
@@ -269,6 +271,14 @@
 	return -ENXIO;
 }
 
+static inline ssize_t rpmsg_get_mtu(struct rpmsg_endpoint *ept)
+{
+	/* This shouldn't be possible */
+	WARN_ON(1);
+
+	return -ENXIO;
+}
+
 #endif /* IS_ENABLED(CONFIG_RPMSG) */
 
 /* use a macro to avoid include chaining to get THIS_MODULE */
diff --git a/kernel/include/linux/sched.h b/kernel/include/linux/sched.h
index d3cc279..a9427da 100644
--- a/kernel/include/linux/sched.h
+++ b/kernel/include/linux/sched.h
@@ -1687,7 +1687,6 @@
 }
 
 extern int cpuset_cpumask_can_shrink(const struct cpumask *cur, const struct cpumask *trial);
-extern int task_can_attach(struct task_struct *p, const struct cpumask *cs_effective_cpus);
 
 #ifdef CONFIG_RT_SOFTINT_OPTIMIZATION
 extern bool cpupri_check_rt(void);
@@ -1698,6 +1697,9 @@
 }
 #endif
 
+extern int task_can_attach(struct task_struct *p);
+extern int dl_bw_alloc(int cpu, u64 dl_bw);
+extern void dl_bw_free(int cpu, u64 dl_bw);
 #ifdef CONFIG_SMP
 extern void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask);
 extern int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask);
diff --git a/kernel/include/linux/sched/task.h b/kernel/include/linux/sched/task.h
index 5629761..99d4557 100644
--- a/kernel/include/linux/sched/task.h
+++ b/kernel/include/linux/sched/task.h
@@ -61,7 +61,9 @@
 extern void sched_dead(struct task_struct *p);
 
 void __noreturn do_task_dead(void);
+void __noreturn make_task_dead(int signr);
 
+extern void mm_cache_init(void);
 extern void proc_caches_init(void);
 
 extern void fork_init(void);
@@ -88,7 +90,6 @@
 extern pid_t kernel_clone(struct kernel_clone_args *kargs);
 struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node);
 struct task_struct *fork_idle(int);
-struct mm_struct *copy_init_mm(void);
 extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 extern long kernel_wait4(pid_t, int __user *, int, struct rusage *);
 int kernel_wait(pid_t pid, int *stat);
@@ -109,10 +110,36 @@
 }
 
 extern void __put_task_struct(struct task_struct *t);
+extern void __put_task_struct_rcu_cb(struct rcu_head *rhp);
 
 static inline void put_task_struct(struct task_struct *t)
 {
-	if (refcount_dec_and_test(&t->usage))
+	if (!refcount_dec_and_test(&t->usage))
+		return;
+
+	/*
+	 * under PREEMPT_RT, we can't call put_task_struct
+	 * in atomic context because it will indirectly
+	 * acquire sleeping locks.
+	 *
+	 * call_rcu() will schedule delayed_put_task_struct_rcu()
+	 * to be called in process context.
+	 *
+	 * __put_task_struct() is called when
+	 * refcount_dec_and_test(&t->usage) succeeds.
+	 *
+	 * This means that it can't "conflict" with
+	 * put_task_struct_rcu_user() which abuses ->rcu the same
+	 * way; rcu_users has a reference so task->usage can't be
+	 * zero after rcu_users 1 -> 0 transition.
+	 *
+	 * delayed_free_task() also uses ->rcu, but it is only called
+	 * when it fails to fork a process. Therefore, there is no
+	 * way it can conflict with put_task_struct().
+	 */
+	if (IS_ENABLED(CONFIG_PREEMPT_RT) && !preemptible())
+		call_rcu(&t->rcu, __put_task_struct_rcu_cb);
+	else
 		__put_task_struct(t);
 }
 
diff --git a/kernel/include/linux/sched/task_stack.h b/kernel/include/linux/sched/task_stack.h
index d101505..f245759 100644
--- a/kernel/include/linux/sched/task_stack.h
+++ b/kernel/include/linux/sched/task_stack.h
@@ -23,7 +23,7 @@
 
 #define setup_thread_stack(new,old)	do { } while(0)
 
-static inline unsigned long *end_of_stack(const struct task_struct *task)
+static __always_inline unsigned long *end_of_stack(const struct task_struct *task)
 {
 #ifdef CONFIG_STACK_GROWSUP
 	return (unsigned long *)((unsigned long)task->stack + THREAD_SIZE) - 1;
diff --git a/kernel/include/linux/sensor-dev.h b/kernel/include/linux/sensor-dev.h
index 81d3aa1..a29d512 100644
--- a/kernel/include/linux/sensor-dev.h
+++ b/kernel/include/linux/sensor-dev.h
@@ -70,6 +70,7 @@
 	ACCEL_ID_DA215S,
 	ACCEL_ID_DA228E,
 	ACCEL_ID_IAM20680,
+	ACCEL_ID_ICM4260X,
 	COMPASS_ID_ALL,
 	COMPASS_ID_AK8975,
 	COMPASS_ID_AK8963,
@@ -97,6 +98,7 @@
 	GYRO_ID_LSM330,
 	GYRO_ID_ICM2060X,
 	GYRO_ID_IAM20680,
+	GYRO_ID_ICM4260X,
 	LIGHT_ID_ALL,
 	LIGHT_ID_CM3217,
 	LIGHT_ID_CM3218,
diff --git a/kernel/include/linux/seqlock.h b/kernel/include/linux/seqlock.h
index 1ac20d7..0928a60 100644
--- a/kernel/include/linux/seqlock.h
+++ b/kernel/include/linux/seqlock.h
@@ -307,10 +307,10 @@
 	__seqprop_case((s),	mutex,		prop),			\
 	__seqprop_case((s),	ww_mutex,	prop))
 
-#define __seqcount_ptr(s)		__seqprop(s, ptr)
-#define __seqcount_sequence(s)		__seqprop(s, sequence)
-#define __seqcount_lock_preemptible(s)	__seqprop(s, preemptible)
-#define __seqcount_assert_lock_held(s)	__seqprop(s, assert)
+#define seqprop_ptr(s)			__seqprop(s, ptr)
+#define seqprop_sequence(s)		__seqprop(s, sequence)
+#define seqprop_preemptible(s)		__seqprop(s, preemptible)
+#define seqprop_assert(s)		__seqprop(s, assert)
 
 /**
  * __read_seqcount_begin() - begin a seqcount_t read section w/o barrier
@@ -328,13 +328,13 @@
  */
 #define __read_seqcount_begin(s)					\
 ({									\
-	unsigned seq;							\
+	unsigned __seq;							\
 									\
-	while ((seq = __seqcount_sequence(s)) & 1)			\
+	while ((__seq = seqprop_sequence(s)) & 1)			\
 		cpu_relax();						\
 									\
 	kcsan_atomic_next(KCSAN_SEQLOCK_REGION_MAX);			\
-	seq;								\
+	__seq;								\
 })
 
 /**
@@ -345,10 +345,10 @@
  */
 #define raw_read_seqcount_begin(s)					\
 ({									\
-	unsigned seq = __read_seqcount_begin(s);			\
+	unsigned _seq = __read_seqcount_begin(s);			\
 									\
 	smp_rmb();							\
-	seq;								\
+	_seq;								\
 })
 
 /**
@@ -359,7 +359,7 @@
  */
 #define read_seqcount_begin(s)						\
 ({									\
-	seqcount_lockdep_reader_access(__seqcount_ptr(s));		\
+	seqcount_lockdep_reader_access(seqprop_ptr(s));			\
 	raw_read_seqcount_begin(s);					\
 })
 
@@ -376,11 +376,11 @@
  */
 #define raw_read_seqcount(s)						\
 ({									\
-	unsigned seq = __seqcount_sequence(s);				\
+	unsigned __seq = seqprop_sequence(s);				\
 									\
 	smp_rmb();							\
 	kcsan_atomic_next(KCSAN_SEQLOCK_REGION_MAX);			\
-	seq;								\
+	__seq;								\
 })
 
 /**
@@ -425,9 +425,9 @@
  * Return: true if a read section retry is required, else false
  */
 #define __read_seqcount_retry(s, start)					\
-	__read_seqcount_t_retry(__seqcount_ptr(s), start)
+	do___read_seqcount_retry(seqprop_ptr(s), start)
 
-static inline int __read_seqcount_t_retry(const seqcount_t *s, unsigned start)
+static inline int do___read_seqcount_retry(const seqcount_t *s, unsigned start)
 {
 	kcsan_atomic_next(0);
 	return unlikely(READ_ONCE(s->sequence) != start);
@@ -445,12 +445,12 @@
  * Return: true if a read section retry is required, else false
  */
 #define read_seqcount_retry(s, start)					\
-	read_seqcount_t_retry(__seqcount_ptr(s), start)
+	do_read_seqcount_retry(seqprop_ptr(s), start)
 
-static inline int read_seqcount_t_retry(const seqcount_t *s, unsigned start)
+static inline int do_read_seqcount_retry(const seqcount_t *s, unsigned start)
 {
 	smp_rmb();
-	return __read_seqcount_t_retry(s, start);
+	return do___read_seqcount_retry(s, start);
 }
 
 /**
@@ -459,13 +459,13 @@
  */
 #define raw_write_seqcount_begin(s)					\
 do {									\
-	if (__seqcount_lock_preemptible(s))				\
+	if (seqprop_preemptible(s))					\
 		preempt_disable();					\
 									\
-	raw_write_seqcount_t_begin(__seqcount_ptr(s));			\
+	do_raw_write_seqcount_begin(seqprop_ptr(s));			\
 } while (0)
 
-static inline void raw_write_seqcount_t_begin(seqcount_t *s)
+static inline void do_raw_write_seqcount_begin(seqcount_t *s)
 {
 	kcsan_nestable_atomic_begin();
 	s->sequence++;
@@ -478,13 +478,13 @@
  */
 #define raw_write_seqcount_end(s)					\
 do {									\
-	raw_write_seqcount_t_end(__seqcount_ptr(s));			\
+	do_raw_write_seqcount_end(seqprop_ptr(s));			\
 									\
-	if (__seqcount_lock_preemptible(s))				\
+	if (seqprop_preemptible(s))					\
 		preempt_enable();					\
 } while (0)
 
-static inline void raw_write_seqcount_t_end(seqcount_t *s)
+static inline void do_raw_write_seqcount_end(seqcount_t *s)
 {
 	smp_wmb();
 	s->sequence++;
@@ -501,18 +501,18 @@
  */
 #define write_seqcount_begin_nested(s, subclass)			\
 do {									\
-	__seqcount_assert_lock_held(s);					\
+	seqprop_assert(s);						\
 									\
-	if (__seqcount_lock_preemptible(s))				\
+	if (seqprop_preemptible(s))					\
 		preempt_disable();					\
 									\
-	write_seqcount_t_begin_nested(__seqcount_ptr(s), subclass);	\
+	do_write_seqcount_begin_nested(seqprop_ptr(s), subclass);	\
 } while (0)
 
-static inline void write_seqcount_t_begin_nested(seqcount_t *s, int subclass)
+static inline void do_write_seqcount_begin_nested(seqcount_t *s, int subclass)
 {
-	raw_write_seqcount_t_begin(s);
 	seqcount_acquire(&s->dep_map, subclass, 0, _RET_IP_);
+	do_raw_write_seqcount_begin(s);
 }
 
 /**
@@ -528,17 +528,17 @@
  */
 #define write_seqcount_begin(s)						\
 do {									\
-	__seqcount_assert_lock_held(s);					\
+	seqprop_assert(s);						\
 									\
-	if (__seqcount_lock_preemptible(s))				\
+	if (seqprop_preemptible(s))					\
 		preempt_disable();					\
 									\
-	write_seqcount_t_begin(__seqcount_ptr(s));			\
+	do_write_seqcount_begin(seqprop_ptr(s));			\
 } while (0)
 
-static inline void write_seqcount_t_begin(seqcount_t *s)
+static inline void do_write_seqcount_begin(seqcount_t *s)
 {
-	write_seqcount_t_begin_nested(s, 0);
+	do_write_seqcount_begin_nested(s, 0);
 }
 
 /**
@@ -549,16 +549,16 @@
  */
 #define write_seqcount_end(s)						\
 do {									\
-	write_seqcount_t_end(__seqcount_ptr(s));			\
+	do_write_seqcount_end(seqprop_ptr(s));				\
 									\
-	if (__seqcount_lock_preemptible(s))				\
+	if (seqprop_preemptible(s))					\
 		preempt_enable();					\
 } while (0)
 
-static inline void write_seqcount_t_end(seqcount_t *s)
+static inline void do_write_seqcount_end(seqcount_t *s)
 {
 	seqcount_release(&s->dep_map, _RET_IP_);
-	raw_write_seqcount_t_end(s);
+	do_raw_write_seqcount_end(s);
 }
 
 /**
@@ -603,9 +603,9 @@
  *      }
  */
 #define raw_write_seqcount_barrier(s)					\
-	raw_write_seqcount_t_barrier(__seqcount_ptr(s))
+	do_raw_write_seqcount_barrier(seqprop_ptr(s))
 
-static inline void raw_write_seqcount_t_barrier(seqcount_t *s)
+static inline void do_raw_write_seqcount_barrier(seqcount_t *s)
 {
 	kcsan_nestable_atomic_begin();
 	s->sequence++;
@@ -623,9 +623,9 @@
  * will complete successfully and see data older than this.
  */
 #define write_seqcount_invalidate(s)					\
-	write_seqcount_t_invalidate(__seqcount_ptr(s))
+	do_write_seqcount_invalidate(seqprop_ptr(s))
 
-static inline void write_seqcount_t_invalidate(seqcount_t *s)
+static inline void do_write_seqcount_invalidate(seqcount_t *s)
 {
 	smp_wmb();
 	kcsan_nestable_atomic_begin();
@@ -862,9 +862,9 @@
 }
 
 /*
- * For all seqlock_t write side functions, use write_seqcount_*t*_begin()
- * instead of the generic write_seqcount_begin(). This way, no redundant
- * lockdep_assert_held() checks are added.
+ * For all seqlock_t write side functions, use the the internal
+ * do_write_seqcount_begin() instead of generic write_seqcount_begin().
+ * This way, no redundant lockdep_assert_held() checks are added.
  */
 
 /**
@@ -883,7 +883,7 @@
 static inline void write_seqlock(seqlock_t *sl)
 {
 	spin_lock(&sl->lock);
-	write_seqcount_t_begin(&sl->seqcount.seqcount);
+	do_write_seqcount_begin(&sl->seqcount.seqcount);
 }
 
 /**
@@ -895,7 +895,7 @@
  */
 static inline void write_sequnlock(seqlock_t *sl)
 {
-	write_seqcount_t_end(&sl->seqcount.seqcount);
+	do_write_seqcount_end(&sl->seqcount.seqcount);
 	spin_unlock(&sl->lock);
 }
 
@@ -909,7 +909,7 @@
 static inline void write_seqlock_bh(seqlock_t *sl)
 {
 	spin_lock_bh(&sl->lock);
-	write_seqcount_t_begin(&sl->seqcount.seqcount);
+	do_write_seqcount_begin(&sl->seqcount.seqcount);
 }
 
 /**
@@ -922,7 +922,7 @@
  */
 static inline void write_sequnlock_bh(seqlock_t *sl)
 {
-	write_seqcount_t_end(&sl->seqcount.seqcount);
+	do_write_seqcount_end(&sl->seqcount.seqcount);
 	spin_unlock_bh(&sl->lock);
 }
 
@@ -936,7 +936,7 @@
 static inline void write_seqlock_irq(seqlock_t *sl)
 {
 	spin_lock_irq(&sl->lock);
-	write_seqcount_t_begin(&sl->seqcount.seqcount);
+	do_write_seqcount_begin(&sl->seqcount.seqcount);
 }
 
 /**
@@ -948,7 +948,7 @@
  */
 static inline void write_sequnlock_irq(seqlock_t *sl)
 {
-	write_seqcount_t_end(&sl->seqcount.seqcount);
+	do_write_seqcount_end(&sl->seqcount.seqcount);
 	spin_unlock_irq(&sl->lock);
 }
 
@@ -957,7 +957,7 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&sl->lock, flags);
-	write_seqcount_t_begin(&sl->seqcount.seqcount);
+	do_write_seqcount_begin(&sl->seqcount.seqcount);
 	return flags;
 }
 
@@ -986,7 +986,7 @@
 static inline void
 write_sequnlock_irqrestore(seqlock_t *sl, unsigned long flags)
 {
-	write_seqcount_t_end(&sl->seqcount.seqcount);
+	do_write_seqcount_end(&sl->seqcount.seqcount);
 	spin_unlock_irqrestore(&sl->lock, flags);
 }
 
diff --git a/kernel/include/linux/sh_intc.h b/kernel/include/linux/sh_intc.h
index c255273..37ad810 100644
--- a/kernel/include/linux/sh_intc.h
+++ b/kernel/include/linux/sh_intc.h
@@ -97,7 +97,10 @@
 	unsigned int nr_subgroups;
 };
 
-#define _INTC_ARRAY(a) a, __same_type(a, NULL) ? 0 : sizeof(a)/sizeof(*a)
+#define _INTC_SIZEOF_OR_ZERO(a) (_Generic(a,                 \
+                                 typeof(NULL):  0,           \
+                                 default:       sizeof(a)))
+#define _INTC_ARRAY(a) a, _INTC_SIZEOF_OR_ZERO(a)/sizeof(*a)
 
 #define INTC_HW_DESC(vectors, groups, mask_regs,	\
 		     prio_regs,	sense_regs, ack_regs)	\
diff --git a/kernel/include/linux/skbuff.h b/kernel/include/linux/skbuff.h
index f73efb3..01dbdf1 100644
--- a/kernel/include/linux/skbuff.h
+++ b/kernel/include/linux/skbuff.h
@@ -260,6 +260,7 @@
 	u8			pkt_otherhost:1;
 	u8			in_prerouting:1;
 	u8			bridged_dnat:1;
+	u8			sabotage_in_done:1;
 	__u16			frag_max_size;
 	struct net_device	*physindev;
 
@@ -706,6 +707,7 @@
  *	@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
@@ -908,6 +910,10 @@
 	__u16			transport_header;
 	__u16			network_header;
 	__u16			mac_header;
+
+#ifdef CONFIG_KCOV
+	u64			kcov_handle;
+#endif
 
 	/* private: */
 	__u32			headers_end[0];
@@ -4207,9 +4213,6 @@
 #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 */
 };
 
@@ -4320,7 +4323,7 @@
 
 static inline void nf_reset_trace(struct sk_buff *skb)
 {
-#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || defined(CONFIG_NF_TABLES)
+#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || IS_ENABLED(CONFIG_NF_TABLES)
 	skb->nf_trace = 0;
 #endif
 }
@@ -4340,7 +4343,7 @@
 	dst->_nfct = src->_nfct;
 	nf_conntrack_get(skb_nfct(src));
 #endif
-#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || defined(CONFIG_NF_TABLES)
+#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || IS_ENABLED(CONFIG_NF_TABLES)
 	if (copy)
 		dst->nf_trace = src->nf_trace;
 #endif
@@ -4664,35 +4667,27 @@
 #endif
 }
 
-#if IS_ENABLED(CONFIG_KCOV) && IS_ENABLED(CONFIG_SKB_EXTENSIONS)
+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)
 {
-	/* 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/kernel/include/linux/soc/qcom/apr.h b/kernel/include/linux/soc/qcom/apr.h
index 7f0bc3c..6374763 100644
--- a/kernel/include/linux/soc/qcom/apr.h
+++ b/kernel/include/linux/soc/qcom/apr.h
@@ -79,6 +79,15 @@
 #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 @@
 	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);
diff --git a/kernel/include/linux/stmmac.h b/kernel/include/linux/stmmac.h
index 90f8ef6..2dd4b4f 100644
--- a/kernel/include/linux/stmmac.h
+++ b/kernel/include/linux/stmmac.h
@@ -204,6 +204,7 @@
 	int rss_en;
 	int mac_port_sel_speed;
 	bool en_tx_lpi_clockgating;
+	bool rx_clk_runs_in_lpi;
 	int has_xgmac;
 	bool vlan_fail_q_en;
 	u8 vlan_fail_q;
diff --git a/kernel/include/linux/string.h b/kernel/include/linux/string.h
index 016a157..32688d7 100644
--- a/kernel/include/linux/string.h
+++ b/kernel/include/linux/string.h
@@ -2,7 +2,6 @@
 #ifndef _LINUX_STRING_H_
 #define _LINUX_STRING_H_
 
-
 #include <linux/compiler.h>	/* for inline */
 #include <linux/types.h>	/* for size_t */
 #include <linux/stddef.h>	/* for NULL */
@@ -183,12 +182,6 @@
 extern void argv_free(char **argv);
 
 extern bool sysfs_streq(const char *s1, const char *s2);
-extern int kstrtobool(const char *s, bool *res);
-static inline int strtobool(const char *s, bool *res)
-{
-	return kstrtobool(s, res);
-}
-
 int match_string(const char * const *array, size_t n, const char *string);
 int __sysfs_match_string(const char * const *array, size_t n, const char *s);
 
diff --git a/kernel/include/linux/sunrpc/cache.h b/kernel/include/linux/sunrpc/cache.h
index d0965e2..b134b2b 100644
--- a/kernel/include/linux/sunrpc/cache.h
+++ b/kernel/include/linux/sunrpc/cache.h
@@ -14,6 +14,7 @@
 #include <linux/kref.h>
 #include <linux/slab.h>
 #include <linux/atomic.h>
+#include <linux/kstrtox.h>
 #include <linux/proc_fs.h>
 
 /*
diff --git a/kernel/include/linux/sunrpc/rpc_pipe_fs.h b/kernel/include/linux/sunrpc/rpc_pipe_fs.h
index cd188a5..3b35b6f 100644
--- a/kernel/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/kernel/include/linux/sunrpc/rpc_pipe_fs.h
@@ -92,6 +92,11 @@
 				       char __user *, size_t);
 extern int rpc_queue_upcall(struct rpc_pipe *, struct rpc_pipe_msg *);
 
+/* returns true if the msg is in-flight, i.e., already eaten by the peer */
+static inline bool rpc_msg_is_inflight(const struct rpc_pipe_msg *msg) {
+	return (msg->copied != 0 && list_empty(&msg->list));
+}
+
 struct rpc_clnt;
 extern struct dentry *rpc_create_client_dir(struct dentry *, const char *, struct rpc_clnt *);
 extern int rpc_remove_client_dir(struct rpc_clnt *);
diff --git a/kernel/include/linux/sunrpc/sched.h b/kernel/include/linux/sunrpc/sched.h
index df696ef..256dff3 100644
--- a/kernel/include/linux/sunrpc/sched.h
+++ b/kernel/include/linux/sunrpc/sched.h
@@ -90,8 +90,7 @@
 #endif
 	unsigned char		tk_priority : 2,/* Task priority */
 				tk_garb_retry : 2,
-				tk_cred_retry : 2,
-				tk_rebind_retry : 2;
+				tk_cred_retry : 2;
 };
 
 typedef void			(*rpc_action)(struct rpc_task *);
diff --git a/kernel/include/linux/sysctl.h b/kernel/include/linux/sysctl.h
index 51298a4..6ee587d 100644
--- a/kernel/include/linux/sysctl.h
+++ b/kernel/include/linux/sysctl.h
@@ -38,11 +38,19 @@
 struct ctl_dir;
 
 /* Keep the same order as in fs/proc/proc_sysctl.c */
-#define SYSCTL_ZERO	((void *)&sysctl_vals[0])
-#define SYSCTL_ONE	((void *)&sysctl_vals[1])
-#define SYSCTL_INT_MAX	((void *)&sysctl_vals[2])
+#define SYSCTL_NEG_ONE			((void *)&android_gki_sysctl_vals[0])
+#define SYSCTL_ZERO			((void *)&android_gki_sysctl_vals[1])
+#define SYSCTL_ONE			((void *)&android_gki_sysctl_vals[2])
+#define SYSCTL_TWO			((void *)&android_gki_sysctl_vals[3])
+#define SYSCTL_FOUR			((void *)&android_gki_sysctl_vals[4])
+#define SYSCTL_ONE_HUNDRED		((void *)&android_gki_sysctl_vals[5])
+#define SYSCTL_TWO_HUNDRED		((void *)&android_gki_sysctl_vals[6])
+#define SYSCTL_ONE_THOUSAND		((void *)&android_gki_sysctl_vals[7])
+#define SYSCTL_THREE_THOUSAND		((void *)&android_gki_sysctl_vals[8])
+#define SYSCTL_INT_MAX			((void *)&android_gki_sysctl_vals[9])
 
 extern const int sysctl_vals[];
+extern const int android_gki_sysctl_vals[];
 
 typedef int proc_handler(struct ctl_table *ctl, int write, void *buffer,
 		size_t *lenp, loff_t *ppos);
@@ -53,6 +61,8 @@
 int proc_dointvec_minmax(struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_douintvec_minmax(struct ctl_table *table, int write, void *buffer,
 		size_t *lenp, loff_t *ppos);
+int proc_dou8vec_minmax(struct ctl_table *table, int write, void *buffer,
+			size_t *lenp, loff_t *ppos);
 int proc_dointvec_jiffies(struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_dointvec_userhz_jiffies(struct ctl_table *, int, void *, size_t *,
 		loff_t *);
@@ -195,6 +205,9 @@
 void unregister_sysctl_table(struct ctl_table_header * table);
 
 extern int sysctl_init(void);
+extern void __register_sysctl_init(const char *path, struct ctl_table *table,
+				 const char *table_name);
+#define register_sysctl_init(path, table) __register_sysctl_init(path, table, #table)
 void do_sysctl_args(void);
 
 extern int pwrsw_enabled;
diff --git a/kernel/include/linux/tcp.h b/kernel/include/linux/tcp.h
index e079555..6d00e1b 100644
--- a/kernel/include/linux/tcp.h
+++ b/kernel/include/linux/tcp.h
@@ -483,7 +483,7 @@
 	struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue;
 	int somaxconn = READ_ONCE(sock_net(sk)->core.sysctl_somaxconn);
 
-	queue->fastopenq.max_qlen = min_t(unsigned int, backlog, somaxconn);
+	WRITE_ONCE(queue->fastopenq.max_qlen, min_t(unsigned int, backlog, somaxconn));
 }
 
 static inline void tcp_move_syn(struct tcp_sock *tp,
diff --git a/kernel/include/linux/tick.h b/kernel/include/linux/tick.h
index 7340613..a90a8f7 100644
--- a/kernel/include/linux/tick.h
+++ b/kernel/include/linux/tick.h
@@ -211,6 +211,7 @@
 				     enum tick_dep_bits bit);
 extern void tick_nohz_dep_clear_signal(struct signal_struct *signal,
 				       enum tick_dep_bits bit);
+extern bool tick_nohz_cpu_hotpluggable(unsigned int cpu);
 
 /*
  * The below are tick_nohz_[set,clear]_dep() wrappers that optimize off-cases
@@ -275,6 +276,7 @@
 
 static inline void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit) { }
 static inline void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { }
+static inline bool tick_nohz_cpu_hotpluggable(unsigned int cpu) { return true; }
 
 static inline void tick_dep_set(enum tick_dep_bits bit) { }
 static inline void tick_dep_clear(enum tick_dep_bits bit) { }
diff --git a/kernel/include/linux/timerqueue.h b/kernel/include/linux/timerqueue.h
index 9388408..adc80e2 100644
--- a/kernel/include/linux/timerqueue.h
+++ b/kernel/include/linux/timerqueue.h
@@ -35,7 +35,7 @@
 {
 	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)
diff --git a/kernel/include/linux/tpm_eventlog.h b/kernel/include/linux/tpm_eventlog.h
index 20c0ff5..7d68a5c 100644
--- a/kernel/include/linux/tpm_eventlog.h
+++ b/kernel/include/linux/tpm_eventlog.h
@@ -198,8 +198,8 @@
 	 * The loop below will unmap these fields if the log is larger than
 	 * one page, so save them here for reference:
 	 */
-	count = READ_ONCE(event->count);
-	event_type = READ_ONCE(event->event_type);
+	count = event->count;
+	event_type = event->event_type;
 
 	/* Verify that it's the log header */
 	if (event_header->pcr_idx != 0 ||
diff --git a/kernel/include/linux/trace_events.h b/kernel/include/linux/trace_events.h
index c57b793..113b42a 100644
--- a/kernel/include/linux/trace_events.h
+++ b/kernel/include/linux/trace_events.h
@@ -741,7 +741,8 @@
 extern void perf_uprobe_destroy(struct perf_event *event);
 extern int bpf_get_uprobe_info(const struct perf_event *event,
 			       u32 *fd_type, const char **filename,
-			       u64 *probe_offset, bool perf_type_tracepoint);
+			       u64 *probe_offset, u64 *probe_addr,
+			       bool perf_type_tracepoint);
 #endif
 extern int  ftrace_profile_set_filter(struct perf_event *event, int event_id,
 				     char *filter_str);
diff --git a/kernel/include/linux/tracepoint.h b/kernel/include/linux/tracepoint.h
index c51a002..3645be5 100644
--- a/kernel/include/linux/tracepoint.h
+++ b/kernel/include/linux/tracepoint.h
@@ -234,12 +234,11 @@
  * not add unwanted padding between the beginning of the section and the
  * structure. Force alignment to the same alignment as the section start.
  *
- * When lockdep is enabled, we make sure to always do the RCU portions of
- * the tracepoint code, regardless of whether tracing is on. However,
- * don't check if the condition is false, due to interaction with idle
- * instrumentation. This lets us find RCU issues triggered with tracepoints
- * even when this tracepoint is off. This code has no purpose other than
- * poking RCU a bit.
+ * When lockdep is enabled, we make sure to always test if RCU is
+ * "watching" regardless if the tracepoint is enabled or not. Tracepoints
+ * require RCU to be active, and it should always warn at the tracepoint
+ * site if it is not watching, as it will need to be active when the
+ * tracepoint is enabled.
  */
 #define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \
 	extern int __traceiter_##name(data_proto);			\
@@ -253,9 +252,7 @@
 				TP_ARGS(data_args),			\
 				TP_CONDITION(cond), 0);			\
 		if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) {		\
-			rcu_read_lock_sched_notrace();			\
-			rcu_dereference_sched(__tracepoint_##name.funcs);\
-			rcu_read_unlock_sched_notrace();		\
+			WARN_ON_ONCE(!rcu_is_watching());		\
 		}							\
 	}								\
 	__DECLARE_TRACE_RCU(name, PARAMS(proto), PARAMS(args),		\
diff --git a/kernel/include/linux/tty.h b/kernel/include/linux/tty.h
index bd76f2f..74909c3 100644
--- a/kernel/include/linux/tty.h
+++ b/kernel/include/linux/tty.h
@@ -18,30 +18,6 @@
 
 
 /*
- * Lock subclasses for tty locks
- *
- * TTY_LOCK_NORMAL is for normal ttys and master ptys.
- * TTY_LOCK_SLAVE is for slave ptys only.
- *
- * Lock subclasses are necessary for handling nested locking with pty pairs.
- * tty locks which use nested locking:
- *
- * legacy_mutex - Nested tty locks are necessary for releasing pty pairs.
- *		  The stable lock order is master pty first, then slave pty.
- * termios_rwsem - The stable lock order is tty_buffer lock->termios_rwsem.
- *		   Subclassing this lock enables the slave pty to hold its
- *		   termios_rwsem when claiming the master tty_buffer lock.
- * tty_buffer lock - slave ptys can claim nested buffer lock when handling
- *		     signal chars. The stable lock order is slave pty, then
- *		     master.
- */
-
-enum {
-	TTY_LOCK_NORMAL = 0,
-	TTY_LOCK_SLAVE,
-};
-
-/*
  * (Note: the *_driver.minor_start values 1, 64, 128, 192 are
  * hardcoded at present.)
  */
@@ -386,21 +362,6 @@
 #define TTY_LDISC_CHANGING	20	/* Change pending - non-block IO */
 #define TTY_LDISC_HALTED	22	/* Line discipline is halted */
 
-/* Values for tty->flow_change */
-#define TTY_THROTTLE_SAFE 1
-#define TTY_UNTHROTTLE_SAFE 2
-
-static inline void __tty_set_flow_change(struct tty_struct *tty, int val)
-{
-	tty->flow_change = val;
-}
-
-static inline void tty_set_flow_change(struct tty_struct *tty, int val)
-{
-	tty->flow_change = val;
-	smp_mb();
-}
-
 static inline bool tty_io_nonblock(struct tty_struct *tty, struct file *file)
 {
 	return file->f_flags & O_NONBLOCK ||
@@ -431,9 +392,6 @@
 extern struct tty_struct *tty_kopen(dev_t device);
 extern void tty_kclose(struct tty_struct *tty);
 extern int tty_dev_name_to_number(const char *name, dev_t *number);
-extern int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout);
-extern void tty_ldisc_unlock(struct tty_struct *tty);
-extern ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *);
 #else
 static inline void tty_kref_put(struct tty_struct *tty)
 { }
@@ -486,11 +444,7 @@
 
 extern const char *tty_driver_name(const struct tty_struct *tty);
 extern void tty_wait_until_sent(struct tty_struct *tty, long timeout);
-extern int __tty_check_change(struct tty_struct *tty, int sig);
-extern int tty_check_change(struct tty_struct *tty);
-extern void __stop_tty(struct tty_struct *tty);
 extern void stop_tty(struct tty_struct *tty);
-extern void __start_tty(struct tty_struct *tty);
 extern void start_tty(struct tty_struct *tty);
 extern int tty_register_driver(struct tty_driver *driver);
 extern int tty_unregister_driver(struct tty_driver *driver);
@@ -515,23 +469,11 @@
 extern int is_current_pgrp_orphaned(void);
 extern void tty_hangup(struct tty_struct *tty);
 extern void tty_vhangup(struct tty_struct *tty);
-extern void tty_vhangup_session(struct tty_struct *tty);
 extern int tty_hung_up_p(struct file *filp);
 extern void do_SAK(struct tty_struct *tty);
 extern void __do_SAK(struct tty_struct *tty);
-extern void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty);
-extern int tty_signal_session_leader(struct tty_struct *tty, int exit_session);
-extern void session_clear_tty(struct pid *session);
 extern void no_tty(void);
-extern void tty_buffer_free_all(struct tty_port *port);
-extern void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld);
-extern void tty_buffer_init(struct tty_port *port);
-extern void tty_buffer_set_lock_subclass(struct tty_port *port);
-extern bool tty_buffer_restart_work(struct tty_port *port);
-extern bool tty_buffer_cancel_work(struct tty_port *port);
-extern void tty_buffer_flush_work(struct tty_port *port);
 extern speed_t tty_termios_baud_rate(struct ktermios *termios);
-extern speed_t tty_termios_input_baud_rate(struct ktermios *termios);
 extern void tty_termios_encode_baud_rate(struct ktermios *termios,
 						speed_t ibaud, speed_t obaud);
 extern void tty_encode_baud_rate(struct tty_struct *tty,
@@ -559,35 +501,22 @@
 extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *);
 extern void tty_ldisc_deref(struct tty_ldisc *);
 extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *);
-extern void tty_ldisc_hangup(struct tty_struct *tty, bool reset);
-extern int tty_ldisc_reinit(struct tty_struct *tty, int disc);
 extern const struct seq_operations tty_ldiscs_seq_ops;
 
 extern void tty_wakeup(struct tty_struct *tty);
 extern void tty_ldisc_flush(struct tty_struct *tty);
 
-extern long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 extern int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
 			unsigned int cmd, unsigned long arg);
-extern long tty_jobctrl_ioctl(struct tty_struct *tty, struct tty_struct *real_tty,
-			      struct file *file, unsigned int cmd, unsigned long arg);
 extern int tty_perform_flush(struct tty_struct *tty, unsigned long arg);
-extern void tty_default_fops(struct file_operations *fops);
-extern struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx);
-extern int tty_alloc_file(struct file *file);
-extern void tty_add_file(struct tty_struct *tty, struct file *file);
-extern void tty_free_file(struct file *file);
 extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx);
 extern void tty_release_struct(struct tty_struct *tty, int idx);
-extern int tty_release(struct inode *inode, struct file *filp);
 extern void tty_init_termios(struct tty_struct *tty);
 extern void tty_save_termios(struct tty_struct *tty);
 extern int tty_standard_install(struct tty_driver *driver,
 		struct tty_struct *tty);
 
 extern struct mutex tty_mutex;
-
-#define tty_is_writelocked(tty)  (mutex_is_locked(&tty->atomic_write_lock))
 
 extern void tty_port_init(struct tty_port *port);
 extern void tty_port_link_device(struct tty_port *port,
@@ -726,10 +655,6 @@
 extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc);
 extern int tty_unregister_ldisc(int disc);
 extern int tty_set_ldisc(struct tty_struct *tty, int disc);
-extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty);
-extern void tty_ldisc_release(struct tty_struct *tty);
-extern int __must_check tty_ldisc_init(struct tty_struct *tty);
-extern void tty_ldisc_deinit(struct tty_struct *tty);
 extern int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p,
 				 char *f, int count);
 
@@ -743,20 +668,10 @@
 
 /* tty_audit.c */
 #ifdef CONFIG_AUDIT
-extern void tty_audit_add_data(struct tty_struct *tty, const void *data,
-			       size_t size);
 extern void tty_audit_exit(void);
 extern void tty_audit_fork(struct signal_struct *sig);
-extern void tty_audit_tiocsti(struct tty_struct *tty, char ch);
 extern int tty_audit_push(void);
 #else
-static inline void tty_audit_add_data(struct tty_struct *tty, const void *data,
-				      size_t size)
-{
-}
-static inline void tty_audit_tiocsti(struct tty_struct *tty, char ch)
-{
-}
 static inline void tty_audit_exit(void)
 {
 }
@@ -797,17 +712,5 @@
 static inline void proc_tty_register_driver(struct tty_driver *d) {}
 static inline void proc_tty_unregister_driver(struct tty_driver *d) {}
 #endif
-
-#define tty_msg(fn, tty, f, ...) \
-	fn("%s %s: " f, tty_driver_name(tty), tty_name(tty), ##__VA_ARGS__)
-
-#define tty_debug(tty, f, ...)	tty_msg(pr_debug, tty, f, ##__VA_ARGS__)
-#define tty_info(tty, f, ...)	tty_msg(pr_info, tty, f, ##__VA_ARGS__)
-#define tty_notice(tty, f, ...)	tty_msg(pr_notice, tty, f, ##__VA_ARGS__)
-#define tty_warn(tty, f, ...)	tty_msg(pr_warn, tty, f, ##__VA_ARGS__)
-#define tty_err(tty, f, ...)	tty_msg(pr_err, tty, f, ##__VA_ARGS__)
-
-#define tty_info_ratelimited(tty, f, ...) \
-		tty_msg(pr_info_ratelimited, tty, f, ##__VA_ARGS__)
 
 #endif
diff --git a/kernel/include/linux/uaccess.h b/kernel/include/linux/uaccess.h
index c7c6e8b..2066876 100644
--- a/kernel/include/linux/uaccess.h
+++ b/kernel/include/linux/uaccess.h
@@ -348,6 +348,10 @@
 	size_t size = min(ksize, usize);
 	size_t rest = max(ksize, usize) - size;
 
+	/* Double check if ksize is larger than a known object size. */
+	if (WARN_ON_ONCE(ksize > __builtin_object_size(dst, 1)))
+		return -E2BIG;
+
 	/* Deal with trailing bytes. */
 	if (usize < ksize) {
 		memset(dst + size, 0, rest);
diff --git a/kernel/include/linux/units.h b/kernel/include/linux/units.h
index 92c234e..3457179 100644
--- a/kernel/include/linux/units.h
+++ b/kernel/include/linux/units.h
@@ -4,6 +4,22 @@
 
 #include <linux/kernel.h>
 
+/* Metric prefixes in accordance with Système international (d'unités) */
+#define PETA	1000000000000000ULL
+#define TERA	1000000000000ULL
+#define GIGA	1000000000UL
+#define MEGA	1000000UL
+#define KILO	1000UL
+#define HECTO	100UL
+#define DECA	10UL
+#define DECI	10UL
+#define CENTI	100UL
+#define MILLI	1000UL
+#define MICRO	1000000UL
+#define NANO	1000000000UL
+#define PICO	1000000000000ULL
+#define FEMTO	1000000000000000ULL
+
 #define MILLIWATT_PER_WATT	1000L
 #define MICROWATT_PER_MILLIWATT	1000L
 #define MICROWATT_PER_WATT	1000000L
diff --git a/kernel/include/linux/usb.h b/kernel/include/linux/usb.h
index befa271..57c1a53 100644
--- a/kernel/include/linux/usb.h
+++ b/kernel/include/linux/usb.h
@@ -285,6 +285,11 @@
 #define USB_MAXINTERFACES	32
 #define USB_MAXIADS		(USB_MAXINTERFACES/2)
 
+bool usb_check_bulk_endpoints(
+		const struct usb_interface *intf, const u8 *ep_addrs);
+bool usb_check_int_endpoints(
+		const struct usb_interface *intf, const u8 *ep_addrs);
+
 /*
  * USB Resume Timer: Every Host controller driver should drive the resume
  * signalling on the bus for the amount of time defined by this macro.
@@ -773,11 +778,14 @@
 extern int usb_acpi_set_power_state(struct usb_device *hdev, int index,
 	bool enable);
 extern bool usb_acpi_power_manageable(struct usb_device *hdev, int index);
+extern int usb_acpi_port_lpm_incapable(struct usb_device *hdev, int index);
 #else
 static inline int usb_acpi_set_power_state(struct usb_device *hdev, int index,
 	bool enable) { return 0; }
 static inline bool usb_acpi_power_manageable(struct usb_device *hdev, int index)
 	{ return true; }
+static inline int usb_acpi_port_lpm_incapable(struct usb_device *hdev, int index)
+	{ return 0; }
 #endif
 
 /* USB autosuspend and autoresume */
diff --git a/kernel/include/linux/usb/hcd.h b/kernel/include/linux/usb/hcd.h
index d14b39d..42d63c2 100644
--- a/kernel/include/linux/usb/hcd.h
+++ b/kernel/include/linux/usb/hcd.h
@@ -513,6 +513,11 @@
 void hcd_buffer_free(struct usb_bus *bus, size_t size,
 	void *addr, dma_addr_t dma);
 
+void *hcd_buffer_alloc_pages(struct usb_hcd *hcd,
+		size_t size, gfp_t mem_flags, dma_addr_t *dma);
+void hcd_buffer_free_pages(struct usb_hcd *hcd,
+		size_t size, void *addr, dma_addr_t dma);
+
 /* generic bus glue, needed for host controllers that don't use PCI */
 extern irqreturn_t usb_hcd_irq(int irq, void *__hcd);
 
diff --git a/kernel/include/linux/usb/typec.h b/kernel/include/linux/usb/typec.h
index 34cc102..8859426 100644
--- a/kernel/include/linux/usb/typec.h
+++ b/kernel/include/linux/usb/typec.h
@@ -141,17 +141,9 @@
 *typec_port_register_altmode(struct typec_port *port,
 			     const struct typec_altmode_desc *desc);
 
-#ifdef CONFIG_NO_GKI
 void typec_port_register_altmodes(struct typec_port *port,
 	const struct typec_altmode_ops *ops, void *drvdata,
 	struct typec_altmode **altmodes, size_t n);
-#else
-static inline void typec_port_register_altmodes(struct typec_port *port,
-	const struct typec_altmode_ops *ops, void *drvdata,
-	struct typec_altmode **altmodes, size_t n)
-{
-}
-#endif
 
 void typec_unregister_altmode(struct typec_altmode *altmode);
 
diff --git a/kernel/include/linux/usb/typec_altmode.h b/kernel/include/linux/usb/typec_altmode.h
index 6053128..e531f77 100644
--- a/kernel/include/linux/usb/typec_altmode.h
+++ b/kernel/include/linux/usb/typec_altmode.h
@@ -69,7 +69,7 @@
 
 int typec_altmode_enter(struct typec_altmode *altmode, u32 *vdo);
 int typec_altmode_exit(struct typec_altmode *altmode);
-void typec_altmode_attention(struct typec_altmode *altmode, u32 vdo);
+int typec_altmode_attention(struct typec_altmode *altmode, u32 vdo);
 int typec_altmode_vdm(struct typec_altmode *altmode,
 		      const u32 header, const u32 *vdo, int count);
 int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf,
diff --git a/kernel/include/linux/util_macros.h b/kernel/include/linux/util_macros.h
index 72299f2..43db6e4 100644
--- a/kernel/include/linux/util_macros.h
+++ b/kernel/include/linux/util_macros.h
@@ -38,4 +38,16 @@
  */
 #define find_closest_descending(x, a, as) __find_closest(x, a, as, >=)
 
+/**
+ * is_insidevar - check if the @ptr points inside the @var memory range.
+ * @ptr:	the pointer to a memory address.
+ * @var:	the variable which address and size identify the memory range.
+ *
+ * Evaluates to true if the address in @ptr lies within the memory
+ * range allocated to @var.
+ */
+#define is_insidevar(ptr, var)						\
+	((uintptr_t)(ptr) >= (uintptr_t)(var) &&			\
+	 (uintptr_t)(ptr) <  (uintptr_t)(var) + sizeof(var))
+
 #endif
diff --git a/kernel/include/linux/virtio_net.h b/kernel/include/linux/virtio_net.h
index a960de6..6047058 100644
--- a/kernel/include/linux/virtio_net.h
+++ b/kernel/include/linux/virtio_net.h
@@ -148,6 +148,10 @@
 		if (gso_type & SKB_GSO_UDP)
 			nh_off -= thlen;
 
+		/* Kernel has a special handling for GSO_BY_FRAGS. */
+		if (gso_size == GSO_BY_FRAGS)
+			return -EINVAL;
+
 		/* Too small packets are not really GSO ones. */
 		if (skb->len - nh_off > gso_size) {
 			shinfo->gso_size = gso_size;
diff --git a/kernel/include/linux/vt_buffer.h b/kernel/include/linux/vt_buffer.h
index 848db1b..919d999 100644
--- a/kernel/include/linux/vt_buffer.h
+++ b/kernel/include/linux/vt_buffer.h
@@ -16,7 +16,7 @@
 
 #include <linux/string.h>
 
-#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE)
+#if IS_ENABLED(CONFIG_VGA_CONSOLE) || IS_ENABLED(CONFIG_MDA_CONSOLE)
 #include <asm/vga.h>
 #endif
 
diff --git a/kernel/include/linux/workqueue.h b/kernel/include/linux/workqueue.h
index e98cc6d..30905a6 100644
--- a/kernel/include/linux/workqueue.h
+++ b/kernel/include/linux/workqueue.h
@@ -74,7 +74,6 @@
 	WORK_OFFQ_FLAG_BASE	= WORK_STRUCT_COLOR_SHIFT,
 
 	__WORK_OFFQ_CANCELING	= WORK_OFFQ_FLAG_BASE,
-	WORK_OFFQ_CANCELING	= (1 << __WORK_OFFQ_CANCELING),
 
 	/*
 	 * When a work item is off queue, its high bits point to the last
@@ -85,12 +84,6 @@
 	WORK_OFFQ_POOL_SHIFT	= WORK_OFFQ_FLAG_BASE + WORK_OFFQ_FLAG_BITS,
 	WORK_OFFQ_LEFT		= BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT,
 	WORK_OFFQ_POOL_BITS	= WORK_OFFQ_LEFT <= 31 ? WORK_OFFQ_LEFT : 31,
-	WORK_OFFQ_POOL_NONE	= (1LU << WORK_OFFQ_POOL_BITS) - 1,
-
-	/* convenience constants */
-	WORK_STRUCT_FLAG_MASK	= (1UL << WORK_STRUCT_FLAG_BITS) - 1,
-	WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK,
-	WORK_STRUCT_NO_POOL	= (unsigned long)WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT,
 
 	/* bit mask for work_busy() return values */
 	WORK_BUSY_PENDING	= 1 << 0,
@@ -100,6 +93,14 @@
 	WORKER_DESC_LEN		= 24,
 };
 
+/* Convenience constants - of type 'unsigned long', not 'enum'! */
+#define WORK_OFFQ_CANCELING	(1ul << __WORK_OFFQ_CANCELING)
+#define WORK_OFFQ_POOL_NONE	((1ul << WORK_OFFQ_POOL_BITS) - 1)
+#define WORK_STRUCT_NO_POOL	(WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT)
+
+#define WORK_STRUCT_FLAG_MASK    ((1ul << WORK_STRUCT_FLAG_BITS) - 1)
+#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
+
 struct work_struct {
 	atomic_long_t data;
 	struct list_head entry;
diff --git a/kernel/include/media/dvb_net.h b/kernel/include/media/dvb_net.h
index 5e31d37..cc01dff 100644
--- a/kernel/include/media/dvb_net.h
+++ b/kernel/include/media/dvb_net.h
@@ -41,6 +41,9 @@
  * @exit:		flag to indicate when the device is being removed.
  * @demux:		pointer to &struct dmx_demux.
  * @ioctl_mutex:	protect access to this struct.
+ * @remove_mutex:	mutex that avoids a race condition between a callback
+ *			called when the hardware is disconnected and the
+ *			file_operations of dvb_net.
  *
  * Currently, the core supports up to %DVB_NET_DEVICES_MAX (10) network
  * devices.
@@ -53,6 +56,7 @@
 	unsigned int exit:1;
 	struct dmx_demux *demux;
 	struct mutex ioctl_mutex;
+	struct mutex remove_mutex;
 };
 
 /**
diff --git a/kernel/include/media/dvbdev.h b/kernel/include/media/dvbdev.h
index e547cbe..91ff2d5 100644
--- a/kernel/include/media/dvbdev.h
+++ b/kernel/include/media/dvbdev.h
@@ -126,6 +126,7 @@
  * struct dvb_device - represents a DVB device node
  *
  * @list_head:	List head with all DVB devices
+ * @ref:	reference counter
  * @fops:	pointer to struct file_operations
  * @adapter:	pointer to the adapter that holds this device node
  * @type:	type of the device, as defined by &enum dvb_device_type.
@@ -156,6 +157,7 @@
  */
 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;
@@ -186,6 +188,35 @@
 
 	void *priv;
 };
+
+/**
+ * struct dvbdevfops_node - fops nodes registered in dvbdevfops_list
+ *
+ * @fops:		Dynamically allocated fops for ->owner registration
+ * @type:		type of dvb_device
+ * @template:		dvb_device used for registration
+ * @list_head:		list_head for dvbdevfops_list
+ */
+struct dvbdevfops_node {
+	struct file_operations *fops;
+	enum dvb_device_type type;
+	const struct dvb_device *template;
+	struct list_head list_head;
+};
+
+/**
+ * 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_put - 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,28 +262,16 @@
 /**
  * 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
  */
diff --git a/kernel/include/media/v4l2-mem2mem.h b/kernel/include/media/v4l2-mem2mem.h
index 5a91b54..8d52c45 100644
--- a/kernel/include/media/v4l2-mem2mem.h
+++ b/kernel/include/media/v4l2-mem2mem.h
@@ -588,7 +588,14 @@
 static inline
 unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
 {
-	return m2m_ctx->out_q_ctx.num_rdy;
+	unsigned int num_buf_rdy;
+	unsigned long flags;
+
+	spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
+	num_buf_rdy = m2m_ctx->out_q_ctx.num_rdy;
+	spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
+
+	return num_buf_rdy;
 }
 
 /**
@@ -600,7 +607,14 @@
 static inline
 unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
 {
-	return m2m_ctx->cap_q_ctx.num_rdy;
+	unsigned int num_buf_rdy;
+	unsigned long flags;
+
+	spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags);
+	num_buf_rdy = m2m_ctx->cap_q_ctx.num_rdy;
+	spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags);
+
+	return num_buf_rdy;
 }
 
 /**
diff --git a/kernel/include/net/bluetooth/l2cap.h b/kernel/include/net/bluetooth/l2cap.h
index 2645901..86d8b96 100644
--- a/kernel/include/net/bluetooth/l2cap.h
+++ b/kernel/include/net/bluetooth/l2cap.h
@@ -494,6 +494,7 @@
 
 #define L2CAP_ECRED_MIN_MTU		64
 #define L2CAP_ECRED_MIN_MPS		64
+#define L2CAP_ECRED_MAX_CID		5
 
 struct l2cap_ecred_conn_req {
 	__le16 psm;
diff --git a/kernel/include/net/bond_alb.h b/kernel/include/net/bond_alb.h
index 191c36a..9dc082b 100644
--- a/kernel/include/net/bond_alb.h
+++ b/kernel/include/net/bond_alb.h
@@ -156,8 +156,8 @@
 void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave);
 void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link);
 void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave);
-int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
-int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
+netdev_tx_t bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
+netdev_tx_t bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
 struct slave *bond_xmit_alb_slave_get(struct bonding *bond,
 				      struct sk_buff *skb);
 struct slave *bond_xmit_tlb_slave_get(struct bonding *bond,
diff --git a/kernel/include/net/bonding.h b/kernel/include/net/bonding.h
index d9cc3f5..82d128c 100644
--- a/kernel/include/net/bonding.h
+++ b/kernel/include/net/bonding.h
@@ -216,6 +216,7 @@
 	struct   bond_up_slave __rcu *usable_slaves;
 	struct   bond_up_slave __rcu *all_slaves;
 	bool     force_primary;
+	bool     notifier_ctx;
 	s32      slave_cnt; /* never change this value outside the attach/detach wrappers */
 	int     (*recv_probe)(const struct sk_buff *, struct bonding *,
 			      struct slave *);
@@ -697,37 +698,14 @@
 }
 
 /* Caller must hold rcu_read_lock() for read */
-static inline struct slave *bond_slave_has_mac_rcu(struct bonding *bond,
-					       const u8 *mac)
+static inline bool bond_slave_has_mac_rcu(struct bonding *bond, const u8 *mac)
 {
 	struct list_head *iter;
 	struct slave *tmp;
 
 	bond_for_each_slave_rcu(bond, tmp, iter)
 		if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr))
-			return tmp;
-
-	return NULL;
-}
-
-/* Caller must hold rcu_read_lock() for read */
-static inline bool bond_slave_has_mac_rx(struct bonding *bond, const u8 *mac)
-{
-	struct list_head *iter;
-	struct slave *tmp;
-	struct netdev_hw_addr *ha;
-
-	bond_for_each_slave_rcu(bond, tmp, iter)
-		if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr))
 			return true;
-
-	if (netdev_uc_empty(bond->dev))
-		return false;
-
-	netdev_for_each_uc_addr(ha, bond->dev)
-		if (ether_addr_equal_64bits(mac, ha->addr))
-			return true;
-
 	return false;
 }
 
diff --git a/kernel/include/net/cfg80211.h b/kernel/include/net/cfg80211.h
index 7abdf1a..fdfaba0 100644
--- a/kernel/include/net/cfg80211.h
+++ b/kernel/include/net/cfg80211.h
@@ -514,6 +514,9 @@
 	if (WARN_ON(iftype >= NL80211_IFTYPE_MAX))
 		return NULL;
 
+	if (iftype == NL80211_IFTYPE_AP_VLAN)
+		iftype = NL80211_IFTYPE_AP;
+
 	for (i = 0; i < sband->n_iftype_data; i++)  {
 		const struct ieee80211_sband_iftype_data *data =
 			&sband->iftype_data[i];
diff --git a/kernel/include/net/dn.h b/kernel/include/net/dn.h
deleted file mode 100644
index 56ab072..0000000
--- a/kernel/include/net/dn.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _NET_DN_H
-#define _NET_DN_H
-
-#include <linux/dn.h>
-#include <net/sock.h>
-#include <net/flow.h>
-#include <asm/byteorder.h>
-#include <asm/unaligned.h>
-
-struct dn_scp                                   /* Session Control Port */
-{
-        unsigned char           state;
-#define DN_O     1                      /* Open                 */
-#define DN_CR    2                      /* Connect Receive      */
-#define DN_DR    3                      /* Disconnect Reject    */
-#define DN_DRC   4                      /* Discon. Rej. Complete*/
-#define DN_CC    5                      /* Connect Confirm      */
-#define DN_CI    6                      /* Connect Initiate     */
-#define DN_NR    7                      /* No resources         */
-#define DN_NC    8                      /* No communication     */
-#define DN_CD    9                      /* Connect Delivery     */
-#define DN_RJ    10                     /* Rejected             */
-#define DN_RUN   11                     /* Running              */
-#define DN_DI    12                     /* Disconnect Initiate  */
-#define DN_DIC   13                     /* Disconnect Complete  */
-#define DN_DN    14                     /* Disconnect Notificat */
-#define DN_CL    15                     /* Closed               */
-#define DN_CN    16                     /* Closed Notification  */
-
-        __le16          addrloc;
-        __le16          addrrem;
-        __u16          numdat;
-        __u16          numoth;
-        __u16          numoth_rcv;
-        __u16          numdat_rcv;
-        __u16          ackxmt_dat;
-        __u16          ackxmt_oth;
-        __u16          ackrcv_dat;
-        __u16          ackrcv_oth;
-        __u8           flowrem_sw;
-	__u8           flowloc_sw;
-#define DN_SEND         2
-#define DN_DONTSEND     1
-#define DN_NOCHANGE     0
-	__u16		flowrem_dat;
-	__u16		flowrem_oth;
-	__u16		flowloc_dat;
-	__u16		flowloc_oth;
-	__u8		services_rem;
-	__u8		services_loc;
-	__u8		info_rem;
-	__u8		info_loc;
-
-	__u16		segsize_rem;
-	__u16		segsize_loc;
-
-	__u8		nonagle;
-	__u8		multi_ireq;
-	__u8		accept_mode;
-	unsigned long		seg_total; /* Running total of current segment */
-
-	struct optdata_dn     conndata_in;
-	struct optdata_dn     conndata_out;
-	struct optdata_dn     discdata_in;
-	struct optdata_dn     discdata_out;
-        struct accessdata_dn  accessdata;
-
-        struct sockaddr_dn addr; /* Local address  */
-	struct sockaddr_dn peer; /* Remote address */
-
-	/*
-	 * In this case the RTT estimation is not specified in the
-	 * docs, nor is any back off algorithm. Here we follow well
-	 * known tcp algorithms with a few small variations.
-	 *
-	 * snd_window: Max number of packets we send before we wait for
-	 *             an ack to come back. This will become part of a
-	 *             more complicated scheme when we support flow
-	 *             control.
-	 *
-	 * nsp_srtt:   Round-Trip-Time (x8) in jiffies. This is a rolling
-	 *             average.
-	 * nsp_rttvar: Round-Trip-Time-Varience (x4) in jiffies. This is the
-	 *             varience of the smoothed average (but calculated in
-	 *             a simpler way than for normal statistical varience
-	 *             calculations).
-	 *
-	 * nsp_rxtshift: Backoff counter. Value is zero normally, each time
-	 *               a packet is lost is increases by one until an ack
-	 *               is received. Its used to index an array of backoff
-	 *               multipliers.
-	 */
-#define NSP_MIN_WINDOW 1
-#define NSP_MAX_WINDOW (0x07fe)
-	unsigned long max_window;
-	unsigned long snd_window;
-#define NSP_INITIAL_SRTT (HZ)
-	unsigned long nsp_srtt;
-#define NSP_INITIAL_RTTVAR (HZ*3)
-	unsigned long nsp_rttvar;
-#define NSP_MAXRXTSHIFT 12
-	unsigned long nsp_rxtshift;
-
-	/*
-	 * Output queues, one for data, one for otherdata/linkservice
-	 */
-	struct sk_buff_head data_xmit_queue;
-	struct sk_buff_head other_xmit_queue;
-
-	/*
-	 * Input queue for other data
-	 */
-	struct sk_buff_head other_receive_queue;
-	int other_report;
-
-	/*
-	 * Stuff to do with the slow timer
-	 */
-	unsigned long stamp;          /* time of last transmit */
-	unsigned long persist;
-	int (*persist_fxn)(struct sock *sk);
-	unsigned long keepalive;
-	void (*keepalive_fxn)(struct sock *sk);
-
-};
-
-static inline struct dn_scp *DN_SK(struct sock *sk)
-{
-	return (struct dn_scp *)(sk + 1);
-}
-
-/*
- * src,dst : Source and Destination DECnet addresses
- * hops : Number of hops through the network
- * dst_port, src_port : NSP port numbers
- * services, info : Useful data extracted from conninit messages
- * rt_flags : Routing flags byte
- * nsp_flags : NSP layer flags byte
- * segsize : Size of segment
- * segnum : Number, for data, otherdata and linkservice
- * xmit_count : Number of times we've transmitted this skb
- * stamp : Time stamp of most recent transmission, used in RTT calculations
- * iif: Input interface number
- *
- * As a general policy, this structure keeps all addresses in network
- * byte order, and all else in host byte order. Thus dst, src, dst_port
- * and src_port are in network order. All else is in host order.
- * 
- */
-#define DN_SKB_CB(skb) ((struct dn_skb_cb *)(skb)->cb)
-struct dn_skb_cb {
-	__le16 dst;
-	__le16 src;
-	__u16 hops;
-	__le16 dst_port;
-	__le16 src_port;
-	__u8 services;
-	__u8 info;
-	__u8 rt_flags;
-	__u8 nsp_flags;
-	__u16 segsize;
-	__u16 segnum;
-	__u16 xmit_count;
-	unsigned long stamp;
-	int iif;
-};
-
-static inline __le16 dn_eth2dn(unsigned char *ethaddr)
-{
-	return get_unaligned((__le16 *)(ethaddr + 4));
-}
-
-static inline __le16 dn_saddr2dn(struct sockaddr_dn *saddr)
-{
-	return *(__le16 *)saddr->sdn_nodeaddr;
-}
-
-static inline void dn_dn2eth(unsigned char *ethaddr, __le16 addr)
-{
-	__u16 a = le16_to_cpu(addr);
-	ethaddr[0] = 0xAA;
-	ethaddr[1] = 0x00;
-	ethaddr[2] = 0x04;
-	ethaddr[3] = 0x00;
-	ethaddr[4] = (__u8)(a & 0xff);
-	ethaddr[5] = (__u8)(a >> 8);
-}
-
-static inline void dn_sk_ports_copy(struct flowidn *fld, struct dn_scp *scp)
-{
-	fld->fld_sport = scp->addrloc;
-	fld->fld_dport = scp->addrrem;
-}
-
-unsigned int dn_mss_from_pmtu(struct net_device *dev, int mtu);
-void dn_register_sysctl(void);
-void dn_unregister_sysctl(void);
-
-#define DN_MENUVER_ACC 0x01
-#define DN_MENUVER_USR 0x02
-#define DN_MENUVER_PRX 0x04
-#define DN_MENUVER_UIC 0x08
-
-struct sock *dn_sklist_find_listener(struct sockaddr_dn *addr);
-struct sock *dn_find_by_skb(struct sk_buff *skb);
-#define DN_ASCBUF_LEN 9
-char *dn_addr2asc(__u16, char *);
-int dn_destroy_timer(struct sock *sk);
-
-int dn_sockaddr2username(struct sockaddr_dn *addr, unsigned char *buf,
-			 unsigned char type);
-int dn_username2sockaddr(unsigned char *data, int len, struct sockaddr_dn *addr,
-			 unsigned char *type);
-
-void dn_start_slow_timer(struct sock *sk);
-void dn_stop_slow_timer(struct sock *sk);
-
-extern __le16 decnet_address;
-extern int decnet_debug_level;
-extern int decnet_time_wait;
-extern int decnet_dn_count;
-extern int decnet_di_count;
-extern int decnet_dr_count;
-extern int decnet_no_fc_max_cwnd;
-
-extern long sysctl_decnet_mem[3];
-extern int sysctl_decnet_wmem[3];
-extern int sysctl_decnet_rmem[3];
-
-#endif /* _NET_DN_H */
diff --git a/kernel/include/net/dn_dev.h b/kernel/include/net/dn_dev.h
deleted file mode 100644
index 595b4f6..0000000
--- a/kernel/include/net/dn_dev.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _NET_DN_DEV_H
-#define _NET_DN_DEV_H
-
-
-struct dn_dev;
-
-struct dn_ifaddr {
-	struct dn_ifaddr __rcu *ifa_next;
-	struct dn_dev    *ifa_dev;
-	__le16            ifa_local;
-	__le16            ifa_address;
-	__u32             ifa_flags;
-	__u8              ifa_scope;
-	char              ifa_label[IFNAMSIZ];
-	struct rcu_head   rcu;
-};
-
-#define DN_DEV_S_RU  0 /* Run - working normally   */
-#define DN_DEV_S_CR  1 /* Circuit Rejected         */
-#define DN_DEV_S_DS  2 /* Data Link Start          */
-#define DN_DEV_S_RI  3 /* Routing Layer Initialize */
-#define DN_DEV_S_RV  4 /* Routing Layer Verify     */
-#define DN_DEV_S_RC  5 /* Routing Layer Complete   */
-#define DN_DEV_S_OF  6 /* Off                      */
-#define DN_DEV_S_HA  7 /* Halt                     */
-
-
-/*
- * The dn_dev_parms structure contains the set of parameters
- * for each device (hence inclusion in the dn_dev structure)
- * and an array is used to store the default types of supported
- * device (in dn_dev.c).
- *
- * The type field matches the ARPHRD_ constants and is used in
- * searching the list for supported devices when new devices
- * come up.
- *
- * The mode field is used to find out if a device is broadcast,
- * multipoint, or pointopoint. Please note that DECnet thinks
- * different ways about devices to the rest of the kernel
- * so the normal IFF_xxx flags are invalid here. For devices
- * which can be any combination of the previously mentioned
- * attributes, you can set this on a per device basis by
- * installing an up() routine.
- *
- * The device state field, defines the initial state in which the
- * device will come up. In the dn_dev structure, it is the actual
- * state.
- *
- * Things have changed here. I've killed timer1 since it's a user space
- * issue for a user space routing deamon to sort out. The kernel does
- * not need to be bothered with it.
- *
- * Timers:
- * t2 - Rate limit timer, min time between routing and hello messages
- * t3 - Hello timer, send hello messages when it expires
- *
- * Callbacks:
- * up() - Called to initialize device, return value can veto use of
- *        device with DECnet.
- * down() - Called to turn device off when it goes down
- * timer3() - Called once for each ifaddr when timer 3 goes off
- * 
- * sysctl - Hook for sysctl things
- *
- */
-struct dn_dev_parms {
-	int type;	          /* ARPHRD_xxx                         */
-	int mode;	          /* Broadcast, Unicast, Mulitpoint     */
-#define DN_DEV_BCAST  1
-#define DN_DEV_UCAST  2
-#define DN_DEV_MPOINT 4
-	int state;                /* Initial state                      */
-	int forwarding;	          /* 0=EndNode, 1=L1Router, 2=L2Router  */
-	unsigned long t2;         /* Default value of t2                */
-	unsigned long t3;         /* Default value of t3                */
-	int priority;             /* Priority to be a router            */
-	char *name;               /* Name for sysctl                    */
-	int  (*up)(struct net_device *);
-	void (*down)(struct net_device *);
-	void (*timer3)(struct net_device *, struct dn_ifaddr *ifa);
-	void *sysctl;
-};
-
-
-struct dn_dev {
-	struct dn_ifaddr __rcu *ifa_list;
-	struct net_device *dev;
-	struct dn_dev_parms parms;
-	char use_long;
-	struct timer_list timer;
-	unsigned long t3;
-	struct neigh_parms *neigh_parms;
-	__u8 addr[ETH_ALEN];
-	struct neighbour *router; /* Default router on circuit */
-	struct neighbour *peer;   /* Peer on pointopoint links */
-	unsigned long uptime;     /* Time device went up in jiffies */
-};
-
-struct dn_short_packet {
-	__u8    msgflg;
-	__le16 dstnode;
-	__le16 srcnode;
-	__u8   forward;
-} __packed;
-
-struct dn_long_packet {
-	__u8   msgflg;
-	__u8   d_area;
-	__u8   d_subarea;
-	__u8   d_id[6];
-	__u8   s_area;
-	__u8   s_subarea;
-	__u8   s_id[6];
-	__u8   nl2;
-	__u8   visit_ct;
-	__u8   s_class;
-	__u8   pt;
-} __packed;
-
-/*------------------------- DRP - Routing messages ---------------------*/
-
-struct endnode_hello_message {
-	__u8   msgflg;
-	__u8   tiver[3];
-	__u8   id[6];
-	__u8   iinfo;
-	__le16 blksize;
-	__u8   area;
-	__u8   seed[8];
-	__u8   neighbor[6];
-	__le16 timer;
-	__u8   mpd;
-	__u8   datalen;
-	__u8   data[2];
-} __packed;
-
-struct rtnode_hello_message {
-	__u8   msgflg;
-	__u8   tiver[3];
-	__u8   id[6];
-	__u8   iinfo;
-	__le16  blksize;
-	__u8   priority;
-	__u8   area;
-	__le16  timer;
-	__u8   mpd;
-} __packed;
-
-
-void dn_dev_init(void);
-void dn_dev_cleanup(void);
-
-int dn_dev_ioctl(unsigned int cmd, void __user *arg);
-
-void dn_dev_devices_off(void);
-void dn_dev_devices_on(void);
-
-void dn_dev_init_pkt(struct sk_buff *skb);
-void dn_dev_veri_pkt(struct sk_buff *skb);
-void dn_dev_hello(struct sk_buff *skb);
-
-void dn_dev_up(struct net_device *);
-void dn_dev_down(struct net_device *);
-
-int dn_dev_set_default(struct net_device *dev, int force);
-struct net_device *dn_dev_get_default(void);
-int dn_dev_bind_default(__le16 *addr);
-
-int register_dnaddr_notifier(struct notifier_block *nb);
-int unregister_dnaddr_notifier(struct notifier_block *nb);
-
-static inline int dn_dev_islocal(struct net_device *dev, __le16 addr)
-{
-	struct dn_dev *dn_db;
-	struct dn_ifaddr *ifa;
-	int res = 0;
-
-	rcu_read_lock();
-	dn_db = rcu_dereference(dev->dn_ptr);
-	if (dn_db == NULL) {
-		printk(KERN_DEBUG "dn_dev_islocal: Called for non DECnet device\n");
-		goto out;
-	}
-
-	for (ifa = rcu_dereference(dn_db->ifa_list);
-	     ifa != NULL;
-	     ifa = rcu_dereference(ifa->ifa_next))
-		if ((addr ^ ifa->ifa_local) == 0) {
-			res = 1;
-			break;
-		}
-out:
-	rcu_read_unlock();
-	return res;
-}
-
-#endif /* _NET_DN_DEV_H */
diff --git a/kernel/include/net/dn_fib.h b/kernel/include/net/dn_fib.h
deleted file mode 100644
index ccc6e9d..0000000
--- a/kernel/include/net/dn_fib.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _NET_DN_FIB_H
-#define _NET_DN_FIB_H
-
-#include <linux/netlink.h>
-#include <linux/refcount.h>
-
-extern const struct nla_policy rtm_dn_policy[];
-
-struct dn_fib_res {
-	struct fib_rule *r;
-	struct dn_fib_info *fi;
-	unsigned char prefixlen;
-	unsigned char nh_sel;
-	unsigned char type;
-	unsigned char scope;
-};
-
-struct dn_fib_nh {
-	struct net_device	*nh_dev;
-	unsigned int		nh_flags;
-	unsigned char		nh_scope;
-	int			nh_weight;
-	int			nh_power;
-	int			nh_oif;
-	__le16			nh_gw;
-};
-
-struct dn_fib_info {
-	struct dn_fib_info	*fib_next;
-	struct dn_fib_info	*fib_prev;
-	int 			fib_treeref;
-	refcount_t		fib_clntref;
-	int			fib_dead;
-	unsigned int		fib_flags;
-	int			fib_protocol;
-	__le16			fib_prefsrc;
-	__u32			fib_priority;
-	__u32			fib_metrics[RTAX_MAX];
-	int			fib_nhs;
-	int			fib_power;
-	struct dn_fib_nh	fib_nh[0];
-#define dn_fib_dev		fib_nh[0].nh_dev
-};
-
-
-#define DN_FIB_RES_RESET(res)	((res).nh_sel = 0)
-#define DN_FIB_RES_NH(res)	((res).fi->fib_nh[(res).nh_sel])
-
-#define DN_FIB_RES_PREFSRC(res)	((res).fi->fib_prefsrc ? : __dn_fib_res_prefsrc(&res))
-#define DN_FIB_RES_GW(res)	(DN_FIB_RES_NH(res).nh_gw)
-#define DN_FIB_RES_DEV(res)	(DN_FIB_RES_NH(res).nh_dev)
-#define DN_FIB_RES_OIF(res)	(DN_FIB_RES_NH(res).nh_oif)
-
-typedef struct {
-	__le16	datum;
-} dn_fib_key_t;
-
-typedef struct {
-	__le16	datum;
-} dn_fib_hash_t;
-
-typedef struct {
-	__u16	datum;
-} dn_fib_idx_t;
-
-struct dn_fib_node {
-	struct dn_fib_node *fn_next;
-	struct dn_fib_info *fn_info;
-#define DN_FIB_INFO(f) ((f)->fn_info)
-	dn_fib_key_t	fn_key;
-	u8		fn_type;
-	u8		fn_scope;
-	u8		fn_state;
-};
-
-
-struct dn_fib_table {
-	struct hlist_node hlist;
-	u32 n;
-
-	int (*insert)(struct dn_fib_table *t, struct rtmsg *r, 
-			struct nlattr *attrs[], struct nlmsghdr *n,
-			struct netlink_skb_parms *req);
-	int (*delete)(struct dn_fib_table *t, struct rtmsg *r,
-			struct nlattr *attrs[], struct nlmsghdr *n,
-			struct netlink_skb_parms *req);
-	int (*lookup)(struct dn_fib_table *t, const struct flowidn *fld,
-			struct dn_fib_res *res);
-	int (*flush)(struct dn_fib_table *t);
-	int (*dump)(struct dn_fib_table *t, struct sk_buff *skb, struct netlink_callback *cb);
-
-	unsigned char data[];
-};
-
-#ifdef CONFIG_DECNET_ROUTER
-/*
- * dn_fib.c
- */
-void dn_fib_init(void);
-void dn_fib_cleanup(void);
-
-int dn_fib_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
-struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r,
-				       struct nlattr *attrs[],
-				       const struct nlmsghdr *nlh, int *errp);
-int dn_fib_semantic_match(int type, struct dn_fib_info *fi,
-			  const struct flowidn *fld, struct dn_fib_res *res);
-void dn_fib_release_info(struct dn_fib_info *fi);
-void dn_fib_flush(void);
-void dn_fib_select_multipath(const struct flowidn *fld, struct dn_fib_res *res);
-
-/*
- * dn_tables.c
- */
-struct dn_fib_table *dn_fib_get_table(u32 n, int creat);
-struct dn_fib_table *dn_fib_empty_table(void);
-void dn_fib_table_init(void);
-void dn_fib_table_cleanup(void);
-
-/*
- * dn_rules.c
- */
-void dn_fib_rules_init(void);
-void dn_fib_rules_cleanup(void);
-unsigned int dnet_addr_type(__le16 addr);
-int dn_fib_lookup(struct flowidn *fld, struct dn_fib_res *res);
-
-int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb);
-
-void dn_fib_free_info(struct dn_fib_info *fi);
-
-static inline void dn_fib_info_put(struct dn_fib_info *fi)
-{
-	if (refcount_dec_and_test(&fi->fib_clntref))
-		dn_fib_free_info(fi);
-}
-
-static inline void dn_fib_res_put(struct dn_fib_res *res)
-{
-	if (res->fi)
-		dn_fib_info_put(res->fi);
-	if (res->r)
-		fib_rule_put(res->r);
-}
-
-#else /* Endnode */
-
-#define dn_fib_init()  do { } while(0)
-#define dn_fib_cleanup() do { } while(0)
-
-#define dn_fib_lookup(fl, res) (-ESRCH)
-#define dn_fib_info_put(fi) do { } while(0)
-#define dn_fib_select_multipath(fl, res) do { } while(0)
-#define dn_fib_rules_policy(saddr,res,flags) (0)
-#define dn_fib_res_put(res) do { } while(0)
-
-#endif /* CONFIG_DECNET_ROUTER */
-
-static inline __le16 dnet_make_mask(int n)
-{
-	if (n)
-		return cpu_to_le16(~((1 << (16 - n)) - 1));
-	return cpu_to_le16(0);
-}
-
-#endif /* _NET_DN_FIB_H */
diff --git a/kernel/include/net/dn_neigh.h b/kernel/include/net/dn_neigh.h
deleted file mode 100644
index 2e3e779..0000000
--- a/kernel/include/net/dn_neigh.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _NET_DN_NEIGH_H
-#define _NET_DN_NEIGH_H
-
-/*
- * The position of the first two fields of
- * this structure are critical - SJW
- */
-struct dn_neigh {
-        struct neighbour n;
-	__le16 addr;
-        unsigned long flags;
-#define DN_NDFLAG_R1    0x0001 /* Router L1      */
-#define DN_NDFLAG_R2    0x0002 /* Router L2      */
-#define DN_NDFLAG_P3    0x0004 /* Phase III Node */
-        unsigned long blksize;
-	__u8 priority;
-};
-
-void dn_neigh_init(void);
-void dn_neigh_cleanup(void);
-int dn_neigh_router_hello(struct net *net, struct sock *sk, struct sk_buff *skb);
-int dn_neigh_endnode_hello(struct net *net, struct sock *sk, struct sk_buff *skb);
-void dn_neigh_pointopoint_hello(struct sk_buff *skb);
-int dn_neigh_elist(struct net_device *dev, unsigned char *ptr, int n);
-int dn_to_neigh_output(struct net *net, struct sock *sk, struct sk_buff *skb);
-
-extern struct neigh_table dn_neigh_table;
-
-#endif /* _NET_DN_NEIGH_H */
diff --git a/kernel/include/net/dn_nsp.h b/kernel/include/net/dn_nsp.h
deleted file mode 100644
index f83932b..0000000
--- a/kernel/include/net/dn_nsp.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef _NET_DN_NSP_H
-#define _NET_DN_NSP_H
-/******************************************************************************
-    (c) 1995-1998 E.M. Serrat		emserrat@geocities.com
-    
-*******************************************************************************/
-/* dn_nsp.c functions prototyping */
-
-void dn_nsp_send_data_ack(struct sock *sk);
-void dn_nsp_send_oth_ack(struct sock *sk);
-void dn_send_conn_ack(struct sock *sk);
-void dn_send_conn_conf(struct sock *sk, gfp_t gfp);
-void dn_nsp_send_disc(struct sock *sk, unsigned char type,
-		      unsigned short reason, gfp_t gfp);
-void dn_nsp_return_disc(struct sk_buff *skb, unsigned char type,
-			unsigned short reason);
-void dn_nsp_send_link(struct sock *sk, unsigned char lsflags, char fcval);
-void dn_nsp_send_conninit(struct sock *sk, unsigned char flags);
-
-void dn_nsp_output(struct sock *sk);
-int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb,
-			    struct sk_buff_head *q, unsigned short acknum);
-void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, gfp_t gfp,
-		       int oob);
-unsigned long dn_nsp_persist(struct sock *sk);
-int dn_nsp_xmit_timeout(struct sock *sk);
-
-int dn_nsp_rx(struct sk_buff *);
-int dn_nsp_backlog_rcv(struct sock *sk, struct sk_buff *skb);
-
-struct sk_buff *dn_alloc_skb(struct sock *sk, int size, gfp_t pri);
-struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int noblock,
-				  long timeo, int *err);
-
-#define NSP_REASON_OK 0		/* No error */
-#define NSP_REASON_NR 1		/* No resources */
-#define NSP_REASON_UN 2		/* Unrecognised node name */
-#define NSP_REASON_SD 3		/* Node shutting down */
-#define NSP_REASON_ID 4		/* Invalid destination end user */
-#define NSP_REASON_ER 5		/* End user lacks resources */
-#define NSP_REASON_OB 6		/* Object too busy */
-#define NSP_REASON_US 7		/* Unspecified error */
-#define NSP_REASON_TP 8		/* Third-Party abort */
-#define NSP_REASON_EA 9		/* End user has aborted the link */
-#define NSP_REASON_IF 10	/* Invalid node name format */
-#define NSP_REASON_LS 11	/* Local node shutdown */
-#define NSP_REASON_LL 32	/* Node lacks logical-link resources */
-#define NSP_REASON_LE 33	/* End user lacks logical-link resources */
-#define NSP_REASON_UR 34	/* Unacceptable RQSTRID or PASSWORD field */
-#define NSP_REASON_UA 36	/* Unacceptable ACCOUNT field */
-#define NSP_REASON_TM 38	/* End user timed out logical link */
-#define NSP_REASON_NU 39	/* Node unreachable */
-#define NSP_REASON_NL 41	/* No-link message */
-#define NSP_REASON_DC 42	/* Disconnect confirm */
-#define NSP_REASON_IO 43	/* Image data field overflow */
-
-#define NSP_DISCINIT 0x38
-#define NSP_DISCCONF 0x48
-
-/*------------------------- NSP - messages ------------------------------*/
-/* Data Messages */
-/*---------------*/
-
-/* Data Messages    (data segment/interrupt/link service)               */
-
-struct nsp_data_seg_msg {
-	__u8   msgflg;
-	__le16 dstaddr;
-	__le16 srcaddr;
-} __packed;
-
-struct nsp_data_opt_msg {
-	__le16 acknum;
-	__le16 segnum;
-	__le16 lsflgs;
-} __packed;
-
-struct nsp_data_opt_msg1 {
-	__le16 acknum;
-	__le16 segnum;
-} __packed;
-
-
-/* Acknowledgment Message (data/other data)                             */
-struct nsp_data_ack_msg {
-	__u8   msgflg;
-	__le16 dstaddr;
-	__le16 srcaddr;
-	__le16 acknum;
-} __packed;
-
-/* Connect Acknowledgment Message */
-struct  nsp_conn_ack_msg {
-	__u8 msgflg;
-	__le16 dstaddr;
-} __packed;
-
-
-/* Connect Initiate/Retransmit Initiate/Connect Confirm */
-struct  nsp_conn_init_msg {
-	__u8   msgflg;
-#define NSP_CI      0x18            /* Connect Initiate     */
-#define NSP_RCI     0x68            /* Retrans. Conn Init   */
-	__le16 dstaddr;
-	__le16 srcaddr;
-	__u8   services;
-#define NSP_FC_NONE   0x00            /* Flow Control None    */
-#define NSP_FC_SRC    0x04            /* Seg Req. Count       */
-#define NSP_FC_SCMC   0x08            /* Sess. Control Mess   */
-#define NSP_FC_MASK   0x0c            /* FC type mask         */
-	__u8   info;
-	__le16 segsize;
-} __packed;
-
-/* Disconnect Initiate/Disconnect Confirm */
-struct  nsp_disconn_init_msg {
-	__u8   msgflg;
-	__le16 dstaddr;
-	__le16 srcaddr;
-	__le16 reason;
-} __packed;
-
-
-
-struct  srcobj_fmt {
-	__u8   format;
-	__u8   task;
-	__le16 grpcode;
-	__le16 usrcode;
-	__u8   dlen;
-} __packed;
-
-/*
- * A collection of functions for manipulating the sequence
- * numbers used in NSP. Similar in operation to the functions
- * of the same name in TCP.
- */
-static __inline__ int dn_before(__u16 seq1, __u16 seq2)
-{
-        seq1 &= 0x0fff;
-        seq2 &= 0x0fff;
-
-        return (int)((seq1 - seq2) & 0x0fff) > 2048;
-}
-
-
-static __inline__ int dn_after(__u16 seq1, __u16 seq2)
-{
-        seq1 &= 0x0fff;
-        seq2 &= 0x0fff;
-
-        return (int)((seq2 - seq1) & 0x0fff) > 2048;
-}
-
-static __inline__ int dn_equal(__u16 seq1, __u16 seq2)
-{
-        return ((seq1 ^ seq2) & 0x0fff) == 0;
-}
-
-static __inline__ int dn_before_or_equal(__u16 seq1, __u16 seq2)
-{
-	return (dn_before(seq1, seq2) || dn_equal(seq1, seq2));
-}
-
-static __inline__ void seq_add(__u16 *seq, __u16 off)
-{
-        (*seq) += off;
-        (*seq) &= 0x0fff;
-}
-
-static __inline__ int seq_next(__u16 seq1, __u16 seq2)
-{
-	return dn_equal(seq1 + 1, seq2);
-}
-
-/*
- * Can we delay the ack ?
- */
-static __inline__ int sendack(__u16 seq)
-{
-        return (int)((seq & 0x1000) ? 0 : 1);
-}
-
-/*
- * Is socket congested ?
- */
-static __inline__ int dn_congested(struct sock *sk)
-{
-        return atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1);
-}
-
-#define DN_MAX_NSP_DATA_HEADER (11)
-
-#endif /* _NET_DN_NSP_H */
diff --git a/kernel/include/net/dn_route.h b/kernel/include/net/dn_route.h
deleted file mode 100644
index 6f1e94a..0000000
--- a/kernel/include/net/dn_route.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef _NET_DN_ROUTE_H
-#define _NET_DN_ROUTE_H
-
-/******************************************************************************
-    (c) 1995-1998 E.M. Serrat		emserrat@geocities.com
-    
-*******************************************************************************/
-
-struct sk_buff *dn_alloc_skb(struct sock *sk, int size, gfp_t pri);
-int dn_route_output_sock(struct dst_entry __rcu **pprt, struct flowidn *,
-			 struct sock *sk, int flags);
-int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb);
-void dn_rt_cache_flush(int delay);
-int dn_route_rcv(struct sk_buff *skb, struct net_device *dev,
-		 struct packet_type *pt, struct net_device *orig_dev);
-
-/* Masks for flags field */
-#define DN_RT_F_PID 0x07 /* Mask for packet type                      */
-#define DN_RT_F_PF  0x80 /* Padding Follows                           */
-#define DN_RT_F_VER 0x40 /* Version =0 discard packet if ==1          */
-#define DN_RT_F_IE  0x20 /* Intra Ethernet, Reserved in short pkt     */
-#define DN_RT_F_RTS 0x10 /* Packet is being returned to sender        */
-#define DN_RT_F_RQR 0x08 /* Return packet to sender upon non-delivery */
-
-/* Mask for types of routing packets */
-#define DN_RT_PKT_MSK   0x06
-/* Types of routing packets */
-#define DN_RT_PKT_SHORT 0x02 /* Short routing packet */
-#define DN_RT_PKT_LONG  0x06 /* Long routing packet  */
-
-/* Mask for control/routing selection */
-#define DN_RT_PKT_CNTL  0x01 /* Set to 1 if a control packet  */
-/* Types of control packets */
-#define DN_RT_CNTL_MSK  0x0f /* Mask for control packets      */
-#define DN_RT_PKT_INIT  0x01 /* Initialisation packet         */
-#define DN_RT_PKT_VERI  0x03 /* Verification Message          */
-#define DN_RT_PKT_HELO  0x05 /* Hello and Test Message        */
-#define DN_RT_PKT_L1RT  0x07 /* Level 1 Routing Message       */
-#define DN_RT_PKT_L2RT  0x09 /* Level 2 Routing Message       */
-#define DN_RT_PKT_ERTH  0x0b /* Ethernet Router Hello         */
-#define DN_RT_PKT_EEDH  0x0d /* Ethernet EndNode Hello        */
-
-/* Values for info field in hello message */
-#define DN_RT_INFO_TYPE 0x03 /* Type mask                     */
-#define DN_RT_INFO_L1RT 0x02 /* L1 Router                     */
-#define DN_RT_INFO_L2RT 0x01 /* L2 Router                     */
-#define DN_RT_INFO_ENDN 0x03 /* EndNode                       */
-#define DN_RT_INFO_VERI 0x04 /* Verification Reqd.            */
-#define DN_RT_INFO_RJCT 0x08 /* Reject Flag, Reserved         */
-#define DN_RT_INFO_VFLD 0x10 /* Verification Failed, Reserved */
-#define DN_RT_INFO_NOML 0x20 /* No Multicast traffic accepted */
-#define DN_RT_INFO_BLKR 0x40 /* Blocking Requested            */
-
-/*
- * The fl structure is what we used to look up the route.
- * The rt_saddr & rt_daddr entries are the same as key.saddr & key.daddr
- * except for local input routes, where the rt_saddr = fl.fld_dst and
- * rt_daddr = fl.fld_src to allow the route to be used for returning
- * packets to the originating host.
- */
-struct dn_route {
-	struct dst_entry dst;
-	struct dn_route __rcu *dn_next;
-
-	struct neighbour *n;
-
-	struct flowidn fld;
-
-	__le16 rt_saddr;
-	__le16 rt_daddr;
-	__le16 rt_gateway;
-	__le16 rt_local_src;	/* Source used for forwarding packets */
-	__le16 rt_src_map;
-	__le16 rt_dst_map;
-
-	unsigned int rt_flags;
-	unsigned int rt_type;
-};
-
-static inline bool dn_is_input_route(struct dn_route *rt)
-{
-	return rt->fld.flowidn_iif != 0;
-}
-
-static inline bool dn_is_output_route(struct dn_route *rt)
-{
-	return rt->fld.flowidn_iif == 0;
-}
-
-void dn_route_init(void);
-void dn_route_cleanup(void);
-
-#include <net/sock.h>
-#include <linux/if_arp.h>
-
-static inline void dn_rt_send(struct sk_buff *skb)
-{
-	dev_queue_xmit(skb);
-}
-
-static inline void dn_rt_finish_output(struct sk_buff *skb, char *dst, char *src)
-{
-	struct net_device *dev = skb->dev;
-
-	if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK))
-		dst = NULL;
-
-	if (dev_hard_header(skb, dev, ETH_P_DNA_RT, dst, src, skb->len) >= 0)
-		dn_rt_send(skb);
-	else
-		kfree_skb(skb);
-}
-
-#endif /* _NET_DN_ROUTE_H */
diff --git a/kernel/include/net/dst.h b/kernel/include/net/dst.h
index acd15c5..8a74d14 100644
--- a/kernel/include/net/dst.h
+++ b/kernel/include/net/dst.h
@@ -235,12 +235,6 @@
 	}
 }
 
-static inline void dst_hold_and_use(struct dst_entry *dst, unsigned long time)
-{
-	dst_hold(dst);
-	dst_use_noref(dst, time);
-}
-
 static inline struct dst_entry *dst_clone(struct dst_entry *dst)
 {
 	if (dst)
diff --git a/kernel/include/net/ip.h b/kernel/include/net/ip.h
index 5834f2d..c7edd07 100644
--- a/kernel/include/net/ip.h
+++ b/kernel/include/net/ip.h
@@ -57,6 +57,7 @@
 #define IPSKB_DOREDIRECT	BIT(5)
 #define IPSKB_FRAG_PMTU		BIT(6)
 #define IPSKB_L3SLAVE		BIT(7)
+#define IPSKB_MULTIPATH		BIT(9)
 
 	u16			frag_max_size;
 };
@@ -76,6 +77,7 @@
 	__be32			addr;
 	int			oif;
 	struct ip_options_rcu	*opt;
+	__u8			protocol;
 	__u8			ttl;
 	__s16			tos;
 	char			priority;
@@ -96,6 +98,7 @@
 	ipcm->sockc.tsflags = inet->sk.sk_tsflags;
 	ipcm->oif = inet->sk.sk_bound_dev_if;
 	ipcm->addr = inet->inet_saddr;
+	ipcm->protocol = inet->inet_num;
 }
 
 #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
diff --git a/kernel/include/net/ip_tunnels.h b/kernel/include/net/ip_tunnels.h
index c3e55a9..1ddd401 100644
--- a/kernel/include/net/ip_tunnels.h
+++ b/kernel/include/net/ip_tunnels.h
@@ -378,9 +378,11 @@
 static inline u8 ip_tunnel_get_dsfield(const struct iphdr *iph,
 				       const struct sk_buff *skb)
 {
-	if (skb->protocol == htons(ETH_P_IP))
+	__be16 payload_protocol = skb_protocol(skb, true);
+
+	if (payload_protocol == htons(ETH_P_IP))
 		return iph->tos;
-	else if (skb->protocol == htons(ETH_P_IPV6))
+	else if (payload_protocol == htons(ETH_P_IPV6))
 		return ipv6_get_dsfield((const struct ipv6hdr *)iph);
 	else
 		return 0;
@@ -389,9 +391,11 @@
 static inline u8 ip_tunnel_get_ttl(const struct iphdr *iph,
 				       const struct sk_buff *skb)
 {
-	if (skb->protocol == htons(ETH_P_IP))
+	__be16 payload_protocol = skb_protocol(skb, true);
+
+	if (payload_protocol == htons(ETH_P_IP))
 		return iph->ttl;
-	else if (skb->protocol == htons(ETH_P_IPV6))
+	else if (payload_protocol == htons(ETH_P_IPV6))
 		return ((const struct ipv6hdr *)iph)->hop_limit;
 	else
 		return 0;
diff --git a/kernel/include/net/ip_vs.h b/kernel/include/net/ip_vs.h
index d609e95..c02c3bb 100644
--- a/kernel/include/net/ip_vs.h
+++ b/kernel/include/net/ip_vs.h
@@ -549,8 +549,10 @@
 	 */
 	struct ip_vs_app        *app;           /* bound ip_vs_app object */
 	void                    *app_data;      /* Application private data */
-	struct ip_vs_seq        in_seq;         /* incoming seq. struct */
-	struct ip_vs_seq        out_seq;        /* outgoing seq. struct */
+	struct_group(sync_conn_opt,
+		struct ip_vs_seq  in_seq;       /* incoming seq. struct */
+		struct ip_vs_seq  out_seq;      /* outgoing seq. struct */
+	);
 
 	const struct ip_vs_pe	*pe;
 	char			*pe_data;
diff --git a/kernel/include/net/ipv6.h b/kernel/include/net/ipv6.h
index e2b706b..a94488d 100644
--- a/kernel/include/net/ipv6.h
+++ b/kernel/include/net/ipv6.h
@@ -660,12 +660,8 @@
 /* more secured version of ipv6_addr_hash() */
 static inline u32 __ipv6_addr_jhash(const struct in6_addr *a, const u32 initval)
 {
-	u32 v = (__force u32)a->s6_addr32[0] ^ (__force u32)a->s6_addr32[1];
-
-	return jhash_3words(v,
-			    (__force u32)a->s6_addr32[2],
-			    (__force u32)a->s6_addr32[3],
-			    initval);
+	return jhash2((__force const u32 *)a->s6_addr32,
+		      ARRAY_SIZE(a->s6_addr32), initval);
 }
 
 static inline bool ipv6_addr_loopback(const struct in6_addr *a)
@@ -1106,6 +1102,8 @@
 void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info);
 void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu);
 
+void inet6_cleanup_sock(struct sock *sk);
+void inet6_sock_destruct(struct sock *sk);
 int inet6_release(struct socket *sock);
 int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len);
 int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
@@ -1248,7 +1246,7 @@
 	return 0;
 }
 
-static inline int ip6_sock_set_addr_preferences(struct sock *sk, bool val)
+static inline int ip6_sock_set_addr_preferences(struct sock *sk, int val)
 {
 	int ret;
 
diff --git a/kernel/include/net/lwtunnel.h b/kernel/include/net/lwtunnel.h
index 05cfd6f..d4a90ec 100644
--- a/kernel/include/net/lwtunnel.h
+++ b/kernel/include/net/lwtunnel.h
@@ -16,9 +16,12 @@
 #define LWTUNNEL_STATE_INPUT_REDIRECT	BIT(1)
 #define LWTUNNEL_STATE_XMIT_REDIRECT	BIT(2)
 
+/* LWTUNNEL_XMIT_CONTINUE should be distinguishable from dst_output return
+ * values (NET_XMIT_xxx and NETDEV_TX_xxx in linux/netdevice.h) for safety.
+ */
 enum {
 	LWTUNNEL_XMIT_DONE,
-	LWTUNNEL_XMIT_CONTINUE,
+	LWTUNNEL_XMIT_CONTINUE = 0x100,
 };
 
 
diff --git a/kernel/include/net/mptcp.h b/kernel/include/net/mptcp.h
index 753ba7e..3e529d8 100644
--- a/kernel/include/net/mptcp.h
+++ b/kernel/include/net/mptcp.h
@@ -58,8 +58,6 @@
 };
 
 #ifdef CONFIG_MPTCP
-extern struct request_sock_ops mptcp_subflow_request_sock_ops;
-
 void mptcp_init(void);
 
 static inline bool sk_is_mptcp(const struct sock *sk)
@@ -133,6 +131,9 @@
 int mptcp_subflow_init_cookie_req(struct request_sock *req,
 				  const struct sock *sk_listener,
 				  struct sk_buff *skb);
+struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
+					       struct sock *sk_listener,
+					       bool attach_listener);
 #else
 
 static inline void mptcp_init(void)
@@ -208,6 +209,13 @@
 {
 	return 0; /* TCP fallback */
 }
+
+static inline struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
+							     struct sock *sk_listener,
+							     bool attach_listener)
+{
+	return NULL;
+}
 #endif /* CONFIG_MPTCP */
 
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
diff --git a/kernel/include/net/mrp.h b/kernel/include/net/mrp.h
index 1c308c0..a810266 100644
--- a/kernel/include/net/mrp.h
+++ b/kernel/include/net/mrp.h
@@ -120,6 +120,7 @@
 	struct sk_buff		*pdu;
 	struct rb_root		mad;
 	struct rcu_head		rcu;
+	bool			active;
 };
 
 struct mrp_port {
diff --git a/kernel/include/net/neighbour.h b/kernel/include/net/neighbour.h
index 7750ef0..42f74b5 100644
--- a/kernel/include/net/neighbour.h
+++ b/kernel/include/net/neighbour.h
@@ -268,11 +268,6 @@
 
 extern const struct nla_policy nda_policy[];
 
-static inline bool neigh_key_eq16(const struct neighbour *n, const void *pkey)
-{
-	return *(const u16 *)n->primary_key == *(const u16 *)pkey;
-}
-
 static inline bool neigh_key_eq32(const struct neighbour *n, const void *pkey)
 {
 	return *(const u32 *)n->primary_key == *(const u32 *)pkey;
@@ -322,8 +317,6 @@
 int neigh_table_clear(int index, struct neigh_table *tbl);
 struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
 			       struct net_device *dev);
-struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net,
-				     const void *pkey);
 struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey,
 				 struct net_device *dev, bool want_ref);
 static inline struct neighbour *neigh_create(struct neigh_table *tbl,
diff --git a/kernel/include/net/net_namespace.h b/kernel/include/net/net_namespace.h
index eb0e773..9764f4c 100644
--- a/kernel/include/net/net_namespace.h
+++ b/kernel/include/net/net_namespace.h
@@ -237,8 +237,6 @@
 struct net *get_net_ns_by_pid(pid_t pid);
 struct net *get_net_ns_by_fd(int fd);
 
-u64 __net_gen_cookie(struct net *net);
-
 #ifdef CONFIG_SYSCTL
 void ipx_register_sysctl(void);
 void ipx_unregister_sysctl(void);
diff --git a/kernel/include/net/netfilter/ipv4/nf_reject.h b/kernel/include/net/netfilter/ipv4/nf_reject.h
index 40e0e06..d8207a8 100644
--- a/kernel/include/net/netfilter/ipv4/nf_reject.h
+++ b/kernel/include/net/netfilter/ipv4/nf_reject.h
@@ -8,8 +8,8 @@
 #include <net/netfilter/nf_reject.h>
 
 void nf_send_unreach(struct sk_buff *skb_in, int code, int hook);
-void nf_send_reset(struct net *net, struct sk_buff *oldskb, int hook);
-
+void nf_send_reset(struct net *net, struct sock *, struct sk_buff *oldskb,
+		   int hook);
 const struct tcphdr *nf_reject_ip_tcphdr_get(struct sk_buff *oldskb,
 					     struct tcphdr *_oth, int hook);
 struct iphdr *nf_reject_iphdr_put(struct sk_buff *nskb,
diff --git a/kernel/include/net/netfilter/ipv6/nf_reject.h b/kernel/include/net/netfilter/ipv6/nf_reject.h
index 4a3ef9e..86e87bc 100644
--- a/kernel/include/net/netfilter/ipv6/nf_reject.h
+++ b/kernel/include/net/netfilter/ipv6/nf_reject.h
@@ -7,9 +7,8 @@
 
 void nf_send_unreach6(struct net *net, struct sk_buff *skb_in, unsigned char code,
 		      unsigned int hooknum);
-
-void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook);
-
+void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
+		    int hook);
 const struct tcphdr *nf_reject_ip6_tcphdr_get(struct sk_buff *oldskb,
 					      struct tcphdr *otcph,
 					      unsigned int *otcplen, int hook);
diff --git a/kernel/include/net/netfilter/nf_tables.h b/kernel/include/net/netfilter/nf_tables.h
index e66fee9..1d59a10 100644
--- a/kernel/include/net/netfilter/nf_tables.h
+++ b/kernel/include/net/netfilter/nf_tables.h
@@ -28,6 +28,16 @@
 	struct xt_action_param		xt;
 };
 
+static inline struct sock *nft_sk(const struct nft_pktinfo *pkt)
+{
+	return pkt->xt.state->sk;
+}
+
+static inline unsigned int nft_thoff(const struct nft_pktinfo *pkt)
+{
+	return pkt->xt.thoff;
+}
+
 static inline struct net *nft_net(const struct nft_pktinfo *pkt)
 {
 	return pkt->xt.state->net;
@@ -205,7 +215,6 @@
 }
 
 int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest);
-unsigned int nft_parse_register(const struct nlattr *attr);
 int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg);
 
 int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
@@ -374,7 +383,8 @@
 					       const struct nft_set *set,
 					       const struct nft_set_elem *elem,
 					       unsigned int flags);
-
+	void				(*commit)(const struct nft_set *set);
+	void				(*abort)(const struct nft_set *set);
 	u64				(*privsize)(const struct nlattr * const nla[],
 						    const struct nft_set_desc *desc);
 	bool				(*estimate)(const struct nft_set_desc *desc,
@@ -383,7 +393,8 @@
 	int				(*init)(const struct nft_set *set,
 						const struct nft_set_desc *desc,
 						const struct nlattr * const nla[]);
-	void				(*destroy)(const struct nft_set *set);
+	void				(*destroy)(const struct nft_ctx *ctx,
+						   const struct nft_set *set);
 	void				(*gc_init)(const struct nft_set *set);
 
 	unsigned int			elemsize;
@@ -406,6 +417,7 @@
  *
  *	@list: table set list node
  *	@bindings: list of set bindings
+ *	@refs: internal refcounting for async set destruction
  *	@table: table this set belongs to
  *	@net: netnamespace this set belongs to
  * 	@name: name of the set
@@ -427,6 +439,7 @@
  *	@expr: stateful expression
  * 	@ops: set ops
  * 	@flags: set flags
+ *	@dead: set will be freed, never cleared
  *	@genmask: generation mask
  * 	@klen: key length
  * 	@dlen: data length
@@ -435,6 +448,7 @@
 struct nft_set {
 	struct list_head		list;
 	struct list_head		bindings;
+	refcount_t			refs;
 	struct nft_table		*table;
 	possible_net_t			net;
 	char				*name;
@@ -454,9 +468,11 @@
 	u16				udlen;
 	unsigned char			*udata;
 	struct nft_expr			*expr;
+	struct list_head		pending_update;
 	/* runtime data below here */
 	const struct nft_set_ops	*ops ____cacheline_aligned;
-	u16				flags:14,
+	u16				flags:13,
+					dead:1,
 					genmask:2;
 	u8				klen;
 	u8				dlen;
@@ -472,6 +488,11 @@
 static inline void *nft_set_priv(const struct nft_set *set)
 {
 	return (void *)set->data;
+}
+
+static inline bool nft_set_gc_is_pending(const struct nft_set *s)
+{
+	return refcount_read(&s->refs) != 1;
 }
 
 static inline struct nft_set *nft_set_container_of(const void *priv)
@@ -507,6 +528,7 @@
 };
 
 enum nft_trans_phase;
+void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set);
 void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
 			      struct nft_set_binding *binding,
 			      enum nft_trans_phase phase);
@@ -686,62 +708,8 @@
 			u64 timeout, u64 expiration, gfp_t gfp);
 void nft_set_elem_destroy(const struct nft_set *set, void *elem,
 			  bool destroy_expr);
-
-/**
- *	struct nft_set_gc_batch_head - nf_tables set garbage collection batch
- *
- *	@rcu: rcu head
- *	@set: set the elements belong to
- *	@cnt: count of elements
- */
-struct nft_set_gc_batch_head {
-	struct rcu_head			rcu;
-	const struct nft_set		*set;
-	unsigned int			cnt;
-};
-
-#define NFT_SET_GC_BATCH_SIZE	((PAGE_SIZE -				  \
-				  sizeof(struct nft_set_gc_batch_head)) / \
-				 sizeof(void *))
-
-/**
- *	struct nft_set_gc_batch - nf_tables set garbage collection batch
- *
- * 	@head: GC batch head
- * 	@elems: garbage collection elements
- */
-struct nft_set_gc_batch {
-	struct nft_set_gc_batch_head	head;
-	void				*elems[NFT_SET_GC_BATCH_SIZE];
-};
-
-struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
-						gfp_t gfp);
-void nft_set_gc_batch_release(struct rcu_head *rcu);
-
-static inline void nft_set_gc_batch_complete(struct nft_set_gc_batch *gcb)
-{
-	if (gcb != NULL)
-		call_rcu(&gcb->head.rcu, nft_set_gc_batch_release);
-}
-
-static inline struct nft_set_gc_batch *
-nft_set_gc_batch_check(const struct nft_set *set, struct nft_set_gc_batch *gcb,
-		       gfp_t gfp)
-{
-	if (gcb != NULL) {
-		if (gcb->head.cnt + 1 < ARRAY_SIZE(gcb->elems))
-			return gcb;
-		nft_set_gc_batch_complete(gcb);
-	}
-	return nft_set_gc_batch_alloc(set, gfp);
-}
-
-static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb,
-					void *elem)
-{
-	gcb->elems[gcb->head.cnt++] = elem;
-}
+void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
+				const struct nft_set *set, void *elem);
 
 struct nft_expr_ops;
 /**
@@ -777,6 +745,7 @@
 
 enum nft_trans_phase {
 	NFT_TRANS_PREPARE,
+	NFT_TRANS_PREPARE_ERROR,
 	NFT_TRANS_ABORT,
 	NFT_TRANS_COMMIT,
 	NFT_TRANS_RELEASE
@@ -907,7 +876,10 @@
 	return (void *)&rule->data[rule->dlen];
 }
 
-void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *rule);
+void nft_rule_expr_activate(const struct nft_ctx *ctx, struct nft_rule *rule);
+void nft_rule_expr_deactivate(const struct nft_ctx *ctx, struct nft_rule *rule,
+			      enum nft_trans_phase phase);
+void nf_tables_rule_destroy(const struct nft_ctx *ctx, struct nft_rule *rule);
 
 static inline void nft_set_elem_update_expr(const struct nft_set_ext *ext,
 					    struct nft_regs *regs,
@@ -966,6 +938,8 @@
 };
 
 int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain);
+int nf_tables_bind_chain(const struct nft_ctx *ctx, struct nft_chain *chain);
+void nf_tables_unbind_chain(const struct nft_ctx *ctx, struct nft_chain *chain);
 
 enum nft_chain_types {
 	NFT_CHAIN_T_DEFAULT = 0,
@@ -1002,11 +976,17 @@
 int nft_chain_validate_hooks(const struct nft_chain *chain,
                              unsigned int hook_flags);
 
+static inline bool nft_chain_binding(const struct nft_chain *chain)
+{
+	return chain->flags & NFT_CHAIN_BINDING;
+}
+
 static inline bool nft_chain_is_bound(struct nft_chain *chain)
 {
 	return (chain->flags & NFT_CHAIN_BINDING) && chain->bound;
 }
 
+int nft_chain_add(struct nft_table *table, struct nft_chain *chain);
 void nft_chain_del(struct nft_chain *chain);
 void nf_tables_chain_destroy(struct nft_ctx *ctx);
 
@@ -1057,6 +1037,29 @@
 int __nft_release_basechain(struct nft_ctx *ctx);
 
 unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv);
+
+static inline bool nft_use_inc(u32 *use)
+{
+	if (*use == UINT_MAX)
+		return false;
+
+	(*use)++;
+
+	return true;
+}
+
+static inline void nft_use_dec(u32 *use)
+{
+	WARN_ON_ONCE((*use)-- == 0);
+}
+
+/* For error and abort path: restore use counter to previous state. */
+static inline void nft_use_inc_restore(u32 *use)
+{
+	WARN_ON_ONCE(!nft_use_inc(use));
+}
+
+#define nft_use_dec_restore	nft_use_dec
 
 /**
  *	struct nft_table - nf_tables table
@@ -1135,8 +1138,8 @@
 	struct list_head		list;
 	struct rhlist_head		rhlhead;
 	struct nft_object_hash_key	key;
-	u32				genmask:2,
-					use:30;
+	u32				genmask:2;
+	u32				use;
 	u64				handle;
 	u16				udlen;
 	u8				*udata;
@@ -1238,8 +1241,8 @@
 	char				*name;
 	int				hooknum;
 	int				ops_len;
-	u32				genmask:2,
-					use:30;
+	u32				genmask:2;
+	u32				use;
 	u64				handle;
 	/* runtime data below here */
 	struct list_head		hook_list ____cacheline_aligned;
@@ -1375,45 +1378,37 @@
 
 #endif /* IS_ENABLED(CONFIG_NF_TABLES) */
 
-/*
- * We use a free bit in the genmask field to indicate the element
- * is busy, meaning it is currently being processed either by
- * the netlink API or GC.
- *
- * Even though the genmask is only a single byte wide, this works
- * because the extension structure if fully constant once initialized,
- * so there are no non-atomic write accesses unless it is already
- * marked busy.
- */
-#define NFT_SET_ELEM_BUSY_MASK	(1 << 2)
+#define NFT_SET_ELEM_DEAD_MASK	(1 << 2)
 
 #if defined(__LITTLE_ENDIAN_BITFIELD)
-#define NFT_SET_ELEM_BUSY_BIT	2
+#define NFT_SET_ELEM_DEAD_BIT	2
 #elif defined(__BIG_ENDIAN_BITFIELD)
-#define NFT_SET_ELEM_BUSY_BIT	(BITS_PER_LONG - BITS_PER_BYTE + 2)
+#define NFT_SET_ELEM_DEAD_BIT	(BITS_PER_LONG - BITS_PER_BYTE + 2)
 #else
 #error
 #endif
 
-static inline int nft_set_elem_mark_busy(struct nft_set_ext *ext)
+static inline void nft_set_elem_dead(struct nft_set_ext *ext)
 {
 	unsigned long *word = (unsigned long *)ext;
 
 	BUILD_BUG_ON(offsetof(struct nft_set_ext, genmask) != 0);
-	return test_and_set_bit(NFT_SET_ELEM_BUSY_BIT, word);
+	set_bit(NFT_SET_ELEM_DEAD_BIT, word);
 }
 
-static inline void nft_set_elem_clear_busy(struct nft_set_ext *ext)
+static inline int nft_set_elem_is_dead(const struct nft_set_ext *ext)
 {
 	unsigned long *word = (unsigned long *)ext;
 
-	clear_bit(NFT_SET_ELEM_BUSY_BIT, word);
+	BUILD_BUG_ON(offsetof(struct nft_set_ext, genmask) != 0);
+	return test_bit(NFT_SET_ELEM_DEAD_BIT, word);
 }
 
 /**
  *	struct nft_trans - nf_tables object update in transaction
  *
  *	@list: used internally
+ *	@binding_list: list of objects with possible bindings
  *	@msg_type: message type
  *	@put_net: ctx->net needs to be put
  *	@ctx: transaction context
@@ -1421,6 +1416,7 @@
  */
 struct nft_trans {
 	struct list_head		list;
+	struct list_head		binding_list;
 	int				msg_type;
 	bool				put_net;
 	struct nft_ctx			ctx;
@@ -1431,6 +1427,7 @@
 	struct nft_rule			*rule;
 	struct nft_flow_rule		*flow;
 	u32				rule_id;
+	bool				bound;
 };
 
 #define nft_trans_rule(trans)	\
@@ -1439,6 +1436,8 @@
 	(((struct nft_trans_rule *)trans->data)->flow)
 #define nft_trans_rule_id(trans)	\
 	(((struct nft_trans_rule *)trans->data)->rule_id)
+#define nft_trans_rule_bound(trans)	\
+	(((struct nft_trans_rule *)trans->data)->bound)
 
 struct nft_trans_set {
 	struct nft_set			*set;
@@ -1454,13 +1453,17 @@
 	(((struct nft_trans_set *)trans->data)->bound)
 
 struct nft_trans_chain {
+	struct nft_chain		*chain;
 	bool				update;
 	char				*name;
 	struct nft_stats __percpu	*stats;
 	u8				policy;
+	bool				bound;
 	u32				chain_id;
 };
 
+#define nft_trans_chain(trans)	\
+	(((struct nft_trans_chain *)trans->data)->chain)
 #define nft_trans_chain_update(trans)	\
 	(((struct nft_trans_chain *)trans->data)->update)
 #define nft_trans_chain_name(trans)	\
@@ -1469,6 +1472,8 @@
 	(((struct nft_trans_chain *)trans->data)->stats)
 #define nft_trans_chain_policy(trans)	\
 	(((struct nft_trans_chain *)trans->data)->policy)
+#define nft_trans_chain_bound(trans)	\
+	(((struct nft_trans_chain *)trans->data)->bound)
 #define nft_trans_chain_id(trans)	\
 	(((struct nft_trans_chain *)trans->data)->chain_id)
 
@@ -1524,6 +1529,35 @@
 #define nft_trans_flowtable_flags(trans)	\
 	(((struct nft_trans_flowtable *)trans->data)->flags)
 
+#define NFT_TRANS_GC_BATCHCOUNT		256
+
+struct nft_trans_gc {
+	struct list_head	list;
+	struct net		*net;
+	struct nft_set		*set;
+	u32			seq;
+	u16			count;
+	void			*priv[NFT_TRANS_GC_BATCHCOUNT];
+	struct rcu_head		rcu;
+};
+
+struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set,
+					unsigned int gc_seq, gfp_t gfp);
+void nft_trans_gc_destroy(struct nft_trans_gc *trans);
+
+struct nft_trans_gc *nft_trans_gc_queue_async(struct nft_trans_gc *gc,
+					      unsigned int gc_seq, gfp_t gfp);
+void nft_trans_gc_queue_async_done(struct nft_trans_gc *gc);
+
+struct nft_trans_gc *nft_trans_gc_queue_sync(struct nft_trans_gc *gc, gfp_t gfp);
+void nft_trans_gc_queue_sync_done(struct nft_trans_gc *trans);
+
+void nft_trans_gc_elem_add(struct nft_trans_gc *gc, void *priv);
+
+void nft_setelem_data_deactivate(const struct net *net,
+				 const struct nft_set *set,
+				 struct nft_set_elem *elem);
+
 int __init nft_chain_filter_init(void);
 void nft_chain_filter_fini(void);
 
@@ -1535,4 +1569,16 @@
 int nf_msecs_to_jiffies64(const struct nlattr *nla, u64 *result);
 __be64 nf_jiffies64_to_msecs(u64 input);
 
+struct nftables_pernet {
+	struct list_head	tables;
+	struct list_head	commit_list;
+	struct list_head	binding_list;
+	struct list_head	module_list;
+	struct list_head	notify_list;
+	struct mutex		commit_mutex;
+	unsigned int		base_seq;
+	u8			validate_state;
+	unsigned int		gc_seq;
+};
+
 #endif /* _NET_NF_TABLES_H */
diff --git a/kernel/include/net/netfilter/nf_tproxy.h b/kernel/include/net/netfilter/nf_tproxy.h
index 82d0e41..faa108b 100644
--- a/kernel/include/net/netfilter/nf_tproxy.h
+++ b/kernel/include/net/netfilter/nf_tproxy.h
@@ -17,6 +17,13 @@
 	return false;
 }
 
+static inline void nf_tproxy_twsk_deschedule_put(struct inet_timewait_sock *tw)
+{
+	local_bh_disable();
+	inet_twsk_deschedule_put(tw);
+	local_bh_enable();
+}
+
 /* assign a socket to the skb -- consumes sk */
 static inline void nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk)
 {
diff --git a/kernel/include/net/netns/netfilter.h b/kernel/include/net/netns/netfilter.h
index fa26637..6ec6887 100644
--- a/kernel/include/net/netns/netfilter.h
+++ b/kernel/include/net/netns/netfilter.h
@@ -26,9 +26,6 @@
 #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
 	struct nf_hook_entries __rcu *hooks_bridge[NF_INET_NUMHOOKS];
 #endif
-#if IS_ENABLED(CONFIG_DECNET)
-	struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS];
-#endif
 #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
 	bool			defrag_ipv4;
 #endif
diff --git a/kernel/include/net/netns/nftables.h b/kernel/include/net/netns/nftables.h
index ccb84b7..7ccd27f 100644
--- a/kernel/include/net/netns/nftables.h
+++ b/kernel/include/net/netns/nftables.h
@@ -6,14 +6,7 @@
 #include <linux/android_kabi.h>
 
 struct netns_nftables {
-	struct list_head	tables;
-	struct list_head	commit_list;
-	struct list_head	module_list;
-	struct list_head	notify_list;
-	struct mutex		commit_mutex;
-	unsigned int		base_seq;
 	u8			gencursor;
-	u8			validate_state;
 
 	ANDROID_KABI_RESERVE(1);
 };
diff --git a/kernel/include/net/nfc/nfc.h b/kernel/include/net/nfc/nfc.h
index 2cd3a26..32890e4 100644
--- a/kernel/include/net/nfc/nfc.h
+++ b/kernel/include/net/nfc/nfc.h
@@ -266,7 +266,7 @@
 struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp);
 
 int nfc_set_remote_general_bytes(struct nfc_dev *dev,
-				 u8 *gt, u8 gt_len);
+				 const u8 *gt, u8 gt_len);
 u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len);
 
 int nfc_fw_download_done(struct nfc_dev *dev, const char *firmware_name,
@@ -280,7 +280,7 @@
 		       u8 comm_mode, u8 rf_mode);
 
 int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode,
-		     u8 *gb, size_t gb_len);
+		     const u8 *gb, size_t gb_len);
 int nfc_tm_deactivated(struct nfc_dev *dev);
 int nfc_tm_data_received(struct nfc_dev *dev, struct sk_buff *skb);
 
diff --git a/kernel/include/net/pkt_sched.h b/kernel/include/net/pkt_sched.h
index 7e58b44..e186b2b 100644
--- a/kernel/include/net/pkt_sched.h
+++ b/kernel/include/net/pkt_sched.h
@@ -129,12 +129,14 @@
 	}
 }
 
+extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1];
+
 /* Calculate maximal size of packet seen by hard_start_xmit
    routine of this device.
  */
 static inline unsigned int psched_mtu(const struct net_device *dev)
 {
-	return dev->mtu + dev->hard_header_len;
+	return READ_ONCE(dev->mtu) + dev->hard_header_len;
 }
 
 static inline struct net *qdisc_net(struct Qdisc *q)
@@ -179,4 +181,13 @@
 						  *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
diff --git a/kernel/include/net/rpl.h b/kernel/include/net/rpl.h
index 308ef0a..30fe780 100644
--- a/kernel/include/net/rpl.h
+++ b/kernel/include/net/rpl.h
@@ -23,9 +23,6 @@
 static inline void rpl_exit(void) {}
 #endif
 
-/* Worst decompression memory usage ipv6 address (16) + pad 7 */
-#define IPV6_RPL_SRH_WORST_SWAP_SIZE (sizeof(struct in6_addr) + 7)
-
 size_t ipv6_rpl_srh_size(unsigned char n, unsigned char cmpri,
 			 unsigned char cmpre);
 
diff --git a/kernel/include/net/rtnetlink.h b/kernel/include/net/rtnetlink.h
index 4da61c9..5c2a73b 100644
--- a/kernel/include/net/rtnetlink.h
+++ b/kernel/include/net/rtnetlink.h
@@ -166,8 +166,8 @@
 int rtnl_delete_link(struct net_device *dev);
 int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm);
 
-int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len,
-			struct netlink_ext_ack *exterr);
+int rtnl_nla_parse_ifinfomsg(struct nlattr **tb, const struct nlattr *nla_peer,
+			     struct netlink_ext_ack *exterr);
 struct net *rtnl_get_net_ns_capable(struct sock *sk, int netnsid);
 
 #define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind)
diff --git a/kernel/include/net/sch_generic.h b/kernel/include/net/sch_generic.h
index 882d918..c9b9482 100644
--- a/kernel/include/net/sch_generic.h
+++ b/kernel/include/net/sch_generic.h
@@ -1323,9 +1323,11 @@
 void mini_qdisc_pair_block_init(struct mini_Qdisc_pair *miniqp,
 				struct tcf_block *block);
 
-static inline int skb_tc_reinsert(struct sk_buff *skb, struct tcf_result *res)
+/* Make sure qdisc is no longer in SCHED state. */
+static inline void qdisc_synchronize(const struct Qdisc *q)
 {
-	return res->ingress ? netif_receive_skb(skb) : dev_queue_xmit(skb);
+	while (test_bit(__QDISC_STATE_SCHED, &q->state))
+		msleep(1);
 }
 
 #endif
diff --git a/kernel/include/net/scm.h b/kernel/include/net/scm.h
index 1ce365f..585adc1 100644
--- a/kernel/include/net/scm.h
+++ b/kernel/include/net/scm.h
@@ -105,16 +105,27 @@
 		}
 	}
 }
+
+static inline bool scm_has_secdata(struct socket *sock)
+{
+	return test_bit(SOCK_PASSSEC, &sock->flags);
+}
 #else
 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
 { }
+
+static inline bool scm_has_secdata(struct socket *sock)
+{
+	return false;
+}
 #endif /* CONFIG_SECURITY_NETWORK */
 
 static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 				struct scm_cookie *scm, int flags)
 {
 	if (!msg->msg_control) {
-		if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
+		if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp ||
+		    scm_has_secdata(sock))
 			msg->msg_flags |= MSG_CTRUNC;
 		scm_destroy(scm);
 		return;
diff --git a/kernel/include/net/sctp/structs.h b/kernel/include/net/sctp/structs.h
index be9ff04..be59e8d 100644
--- a/kernel/include/net/sctp/structs.h
+++ b/kernel/include/net/sctp/structs.h
@@ -1394,6 +1394,7 @@
 	/* The next stream in line */
 	struct sctp_stream_out_ext *next;
 	__u16 prio;
+	__u16 users;
 };
 
 struct sctp_stream_out_ext {
diff --git a/kernel/include/net/sock.h b/kernel/include/net/sock.h
index c604052..22cd0a0 100644
--- a/kernel/include/net/sock.h
+++ b/kernel/include/net/sock.h
@@ -317,7 +317,7 @@
   *	@sk_tskey: counter to disambiguate concurrent tstamp requests
   *	@sk_zckey: counter to order MSG_ZEROCOPY notifications
   *	@sk_socket: Identd and reporting IO signals
-  *	@sk_user_data: RPC layer private data
+  *	@sk_user_data: RPC layer private data. Write-protected by @sk_callback_lock.
   *	@sk_frag: cached page frag
   *	@sk_peek_off: current peek_offset value
   *	@sk_send_head: front of stuff to transmit
@@ -1092,8 +1092,12 @@
 		 * OR	an additional socket flag
 		 * [1] : sk_state and sk_prot are in the same cache line.
 		 */
-		if (sk->sk_state == TCP_ESTABLISHED)
-			sock_rps_record_flow_hash(sk->sk_rxhash);
+		if (sk->sk_state == TCP_ESTABLISHED) {
+			/* This READ_ONCE() is paired with the WRITE_ONCE()
+			 * from sock_rps_save_rxhash() and sock_rps_reset_rxhash().
+			 */
+			sock_rps_record_flow_hash(READ_ONCE(sk->sk_rxhash));
+		}
 	}
 #endif
 }
@@ -1102,15 +1106,19 @@
 					const struct sk_buff *skb)
 {
 #ifdef CONFIG_RPS
-	if (unlikely(sk->sk_rxhash != skb->hash))
-		sk->sk_rxhash = skb->hash;
+	/* The following WRITE_ONCE() is paired with the READ_ONCE()
+	 * here, and another one in sock_rps_record_flow().
+	 */
+	if (unlikely(READ_ONCE(sk->sk_rxhash) != skb->hash))
+		WRITE_ONCE(sk->sk_rxhash, skb->hash);
 #endif
 }
 
 static inline void sock_rps_reset_rxhash(struct sock *sk)
 {
 #ifdef CONFIG_RPS
-	sk->sk_rxhash = 0;
+	/* Paired with READ_ONCE() in sock_rps_record_flow() */
+	WRITE_ONCE(sk->sk_rxhash, 0);
 #endif
 }
 
@@ -1240,6 +1248,7 @@
 	/*
 	 * Pressure flag: try to collapse.
 	 * Technical note: it is used by multiple contexts non atomically.
+	 * Make sure to use READ_ONCE()/WRITE_ONCE() for all reads/writes.
 	 * All the __sk_mem_schedule() is of this nature: accounting
 	 * is strict, actions are advisory and have some latency.
 	 */
@@ -1353,6 +1362,12 @@
 	return sk->sk_prot->memory_pressure != NULL;
 }
 
+static inline bool sk_under_global_memory_pressure(const struct sock *sk)
+{
+	return sk->sk_prot->memory_pressure &&
+		!!READ_ONCE(*sk->sk_prot->memory_pressure);
+}
+
 static inline bool sk_under_memory_pressure(const struct sock *sk)
 {
 	if (!sk->sk_prot->memory_pressure)
@@ -1362,7 +1377,7 @@
 	    mem_cgroup_under_socket_pressure(sk->sk_memcg))
 		return true;
 
-	return !!*sk->sk_prot->memory_pressure;
+	return !!READ_ONCE(*sk->sk_prot->memory_pressure);
 }
 
 static inline long
@@ -1416,7 +1431,7 @@
 {
 	if (!prot->memory_pressure)
 		return false;
-	return !!*prot->memory_pressure;
+	return !!READ_ONCE(*prot->memory_pressure);
 }
 
 
@@ -1796,7 +1811,12 @@
  *	Default socket callbacks and setup code
  */
 
-/* Initialise core socket variables */
+/* Initialise core socket variables using an explicit uid. */
+void sock_init_data_uid(struct socket *sock, struct sock *sk, kuid_t uid);
+
+/* Initialise core socket variables.
+ * Assumes struct socket *sock is embedded in a struct socket_alloc.
+ */
 void sock_init_data(struct socket *sock, struct sock *sk);
 
 /*
@@ -1936,6 +1956,7 @@
 }
 
 kuid_t sock_i_uid(struct sock *sk);
+unsigned long __sock_i_ino(struct sock *sk);
 unsigned long sock_i_ino(struct sock *sk);
 
 static inline kuid_t sock_net_uid(const struct net *net, const struct sock *sk)
@@ -2264,6 +2285,19 @@
 	return false;
 }
 
+static inline struct sk_buff *skb_clone_and_charge_r(struct sk_buff *skb, struct sock *sk)
+{
+	skb = skb_clone(skb, sk_gfp_mask(sk, GFP_ATOMIC));
+	if (skb) {
+		if (sk_rmem_schedule(sk, skb, skb->truesize)) {
+			skb_set_owner_r(skb, sk);
+			return skb;
+		}
+		__kfree_skb(skb);
+	}
+	return NULL;
+}
+
 void sk_reset_timer(struct sock *sk, struct timer_list *timer,
 		    unsigned long expires);
 
@@ -2538,7 +2572,7 @@
 		__sock_recv_ts_and_drops(msg, sk, skb);
 	else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP)))
 		sock_write_timestamp(sk, skb->tstamp);
-	else if (unlikely(sk->sk_stamp == SK_DEFAULT_STAMP))
+	else if (unlikely(sock_read_timestamp(sk) == SK_DEFAULT_STAMP))
 		sock_write_timestamp(sk, 0);
 }
 
diff --git a/kernel/include/net/tcp.h b/kernel/include/net/tcp.h
index f936fcb..57a4d0b 100644
--- a/kernel/include/net/tcp.h
+++ b/kernel/include/net/tcp.h
@@ -348,13 +348,14 @@
 			struct pipe_inode_info *pipe, size_t len,
 			unsigned int flags);
 
-void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks);
-static inline void tcp_dec_quickack_mode(struct sock *sk,
-					 const unsigned int pkts)
+static inline void tcp_dec_quickack_mode(struct sock *sk)
 {
 	struct inet_connection_sock *icsk = inet_csk(sk);
 
 	if (icsk->icsk_ack.quick) {
+		/* How many ACKs S/ACKing new data have we sent? */
+		const unsigned int pkts = inet_csk_ack_scheduled(sk) ? 1 : 0;
+
 		if (pkts >= icsk->icsk_ack.quick) {
 			icsk->icsk_ack.quick = 0;
 			/* Leaving quickack mode we deflate ATO. */
@@ -392,6 +393,7 @@
 void tcp_init_metrics(struct sock *sk);
 void tcp_metrics_init(void);
 bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst);
+void __tcp_close(struct sock *sk, long timeout);
 void tcp_close(struct sock *sk, long timeout);
 void tcp_init_sock(struct sock *sk);
 void tcp_init_transfer(struct sock *sk, int bpf_op, struct sk_buff *skb);
@@ -1454,25 +1456,38 @@
 static inline int keepalive_intvl_when(const struct tcp_sock *tp)
 {
 	struct net *net = sock_net((struct sock *)tp);
+	int val;
 
-	return tp->keepalive_intvl ? :
-		READ_ONCE(net->ipv4.sysctl_tcp_keepalive_intvl);
+	/* Paired with WRITE_ONCE() in tcp_sock_set_keepintvl()
+	 * and do_tcp_setsockopt().
+	 */
+	val = READ_ONCE(tp->keepalive_intvl);
+
+	return val ? : READ_ONCE(net->ipv4.sysctl_tcp_keepalive_intvl);
 }
 
 static inline int keepalive_time_when(const struct tcp_sock *tp)
 {
 	struct net *net = sock_net((struct sock *)tp);
+	int val;
 
-	return tp->keepalive_time ? :
-		READ_ONCE(net->ipv4.sysctl_tcp_keepalive_time);
+	/* Paired with WRITE_ONCE() in tcp_sock_set_keepidle_locked() */
+	val = READ_ONCE(tp->keepalive_time);
+
+	return val ? : READ_ONCE(net->ipv4.sysctl_tcp_keepalive_time);
 }
 
 static inline int keepalive_probes(const struct tcp_sock *tp)
 {
 	struct net *net = sock_net((struct sock *)tp);
+	int val;
 
-	return tp->keepalive_probes ? :
-		READ_ONCE(net->ipv4.sysctl_tcp_keepalive_probes);
+	/* Paired with WRITE_ONCE() in tcp_sock_set_keepcnt()
+	 * and do_tcp_setsockopt().
+	 */
+	val = READ_ONCE(tp->keepalive_probes);
+
+	return val ? : READ_ONCE(net->ipv4.sysctl_tcp_keepalive_probes);
 }
 
 static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp)
@@ -1981,7 +1996,11 @@
 static inline u32 tcp_notsent_lowat(const struct tcp_sock *tp)
 {
 	struct net *net = sock_net((struct sock *)tp);
-	return tp->notsent_lowat ?: READ_ONCE(net->ipv4.sysctl_tcp_notsent_lowat);
+	u32 val;
+
+	val = READ_ONCE(tp->notsent_lowat);
+
+	return val ?: READ_ONCE(net->ipv4.sysctl_tcp_notsent_lowat);
 }
 
 /* @wake is one when sk_stream_write_space() calls us.
diff --git a/kernel/include/net/udp.h b/kernel/include/net/udp.h
index 388e68c..e2550a4 100644
--- a/kernel/include/net/udp.h
+++ b/kernel/include/net/udp.h
@@ -268,7 +268,7 @@
 }
 
 /* net/ipv4/udp.c */
-void udp_destruct_sock(struct sock *sk);
+void udp_destruct_common(struct sock *sk);
 void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len);
 int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb);
 void udp_skb_destructor(struct sock *sk, struct sk_buff *skb);
diff --git a/kernel/include/net/udplite.h b/kernel/include/net/udplite.h
index 9185e45..c59ba86 100644
--- a/kernel/include/net/udplite.h
+++ b/kernel/include/net/udplite.h
@@ -24,14 +24,6 @@
 	return copy_from_iter_full(to, len, &msg->msg_iter) ? 0 : -EFAULT;
 }
 
-/* Designate sk as UDP-Lite socket */
-static inline int udplite_sk_init(struct sock *sk)
-{
-	udp_init_sock(sk);
-	udp_sk(sk)->pcflag = UDPLITE_BIT;
-	return 0;
-}
-
 /*
  * 	Checksumming routines
  */
diff --git a/kernel/include/net/vxlan.h b/kernel/include/net/vxlan.h
index 08537aa..e149a0b 100644
--- a/kernel/include/net/vxlan.h
+++ b/kernel/include/net/vxlan.h
@@ -327,10 +327,15 @@
 	return features;
 }
 
-/* IP header + UDP + VXLAN + Ethernet header */
-#define VXLAN_HEADROOM (20 + 8 + 8 + 14)
-/* IPv6 header + UDP + VXLAN + Ethernet header */
-#define VXLAN6_HEADROOM (40 + 8 + 8 + 14)
+static inline int vxlan_headroom(u32 flags)
+{
+	/* VXLAN:     IP4/6 header + UDP + VXLAN + Ethernet header */
+	/* VXLAN-GPE: IP4/6 header + UDP + VXLAN */
+	return (flags & VXLAN_F_IPV6 ? sizeof(struct ipv6hdr) :
+				       sizeof(struct iphdr)) +
+	       sizeof(struct udphdr) + sizeof(struct vxlanhdr) +
+	       (flags & VXLAN_F_GPE ? 0 : ETH_HLEN);
+}
 
 static inline struct vxlanhdr *vxlan_hdr(struct sk_buff *skb)
 {
@@ -492,12 +497,12 @@
 }
 
 static inline bool vxlan_fdb_nh_path_select(struct nexthop *nh,
-					    int hash,
+					    u32 hash,
 					    struct vxlan_rdst *rdst)
 {
 	struct fib_nh_common *nhc;
 
-	nhc = nexthop_path_fdb_result(nh, hash);
+	nhc = nexthop_path_fdb_result(nh, hash >> 1);
 	if (unlikely(!nhc))
 		return false;
 
diff --git a/kernel/include/net/xfrm.h b/kernel/include/net/xfrm.h
index 5c022fc..b4121a7 100644
--- a/kernel/include/net/xfrm.h
+++ b/kernel/include/net/xfrm.h
@@ -1029,6 +1029,7 @@
 struct sec_path {
 	int			len;
 	int			olen;
+	int			verified_cnt;
 
 	struct xfrm_state	*xvec[XFRM_MAX_DEPTH];
 	struct xfrm_offload	ovec[XFRM_MAX_OFFLOAD_DEPTH];
diff --git a/kernel/include/net/xsk_buff_pool.h b/kernel/include/net/xsk_buff_pool.h
index c9a47d3..5a63e3b 100644
--- a/kernel/include/net/xsk_buff_pool.h
+++ b/kernel/include/net/xsk_buff_pool.h
@@ -150,13 +150,8 @@
 	if (likely(!cross_pg))
 		return false;
 
-	if (pool->dma_pages_cnt) {
-		return !(pool->dma_pages[addr >> PAGE_SHIFT] &
-			 XSK_NEXT_PG_CONTIG_MASK);
-	}
-
-	/* skb path */
-	return addr + len > pool->addrs_cnt;
+	return pool->dma_pages_cnt &&
+	       !(pool->dma_pages[addr >> PAGE_SHIFT] & XSK_NEXT_PG_CONTIG_MASK);
 }
 
 static inline u64 xp_aligned_extract_addr(struct xsk_buff_pool *pool, u64 addr)
diff --git a/kernel/include/rdma/ib_addr.h b/kernel/include/rdma/ib_addr.h
index b0e636a..8c5c958 100644
--- a/kernel/include/rdma/ib_addr.h
+++ b/kernel/include/rdma/ib_addr.h
@@ -193,29 +193,6 @@
 		return 0;
 }
 
-static inline int iboe_get_rate(struct net_device *dev)
-{
-	struct ethtool_link_ksettings cmd;
-	int err;
-
-	rtnl_lock();
-	err = __ethtool_get_link_ksettings(dev, &cmd);
-	rtnl_unlock();
-	if (err)
-		return IB_RATE_PORT_CURRENT;
-
-	if (cmd.base.speed >= 40000)
-		return IB_RATE_40_GBPS;
-	else if (cmd.base.speed >= 30000)
-		return IB_RATE_30_GBPS;
-	else if (cmd.base.speed >= 20000)
-		return IB_RATE_20_GBPS;
-	else if (cmd.base.speed >= 10000)
-		return IB_RATE_10_GBPS;
-	else
-		return IB_RATE_PORT_CURRENT;
-}
-
 static inline int rdma_link_local_addr(struct in6_addr *addr)
 {
 	if (addr->s6_addr32[0] == htonl(0xfe800000) &&
diff --git a/kernel/include/scsi/libsas.h b/kernel/include/scsi/libsas.h
index e6a4316..daf9b07 100644
--- a/kernel/include/scsi/libsas.h
+++ b/kernel/include/scsi/libsas.h
@@ -474,10 +474,16 @@
 };
 
 enum exec_status {
-	/* The SAM_STAT_.. codes fit in the lower 6 bits, alias some of
-	 * them here to silence 'case value not in enumerated type' warnings
+	/*
+	 * Values 0..0x7f are used to return the SAM_STAT_* codes.  To avoid
+	 * 'case value not in enumerated type' compiler warnings every value
+	 * returned through the exec_status enum needs an alias with the SAS_
+	 * prefix here.
 	 */
-	__SAM_STAT_CHECK_CONDITION = SAM_STAT_CHECK_CONDITION,
+	SAS_SAM_STAT_GOOD = SAM_STAT_GOOD,
+	SAS_SAM_STAT_BUSY = SAM_STAT_BUSY,
+	SAS_SAM_STAT_TASK_ABORTED = SAM_STAT_TASK_ABORTED,
+	SAS_SAM_STAT_CHECK_CONDITION = SAM_STAT_CHECK_CONDITION,
 
 	SAS_DEV_NO_RESPONSE = 0x80,
 	SAS_DATA_UNDERRUN,
diff --git a/kernel/include/scsi/scsi_transport_iscsi.h b/kernel/include/scsi/scsi_transport_iscsi.h
index 037c77f..c4de15f 100644
--- a/kernel/include/scsi/scsi_transport_iscsi.h
+++ b/kernel/include/scsi/scsi_transport_iscsi.h
@@ -236,6 +236,14 @@
 	ISCSI_SESSION_FREE,
 };
 
+enum {
+	ISCSI_SESSION_TARGET_UNBOUND,
+	ISCSI_SESSION_TARGET_ALLOCATED,
+	ISCSI_SESSION_TARGET_SCANNED,
+	ISCSI_SESSION_TARGET_UNBINDING,
+	ISCSI_SESSION_TARGET_MAX,
+};
+
 #define ISCSI_MAX_TARGET -1
 
 struct iscsi_cls_session {
@@ -262,6 +270,7 @@
 	 */
 	pid_t creator;
 	int state;
+	int target_state;			/* session target bind state */
 	int sid;				/* session id */
 	void *dd_data;				/* LLD private data */
 	struct device dev;	/* sysfs transport/container device */
diff --git a/kernel/include/soc/bcm2835/raspberrypi-firmware.h b/kernel/include/soc/bcm2835/raspberrypi-firmware.h
index fdfef7f..73ad784 100644
--- a/kernel/include/soc/bcm2835/raspberrypi-firmware.h
+++ b/kernel/include/soc/bcm2835/raspberrypi-firmware.h
@@ -142,6 +142,8 @@
 			       void *data, size_t tag_size);
 void rpi_firmware_put(struct rpi_firmware *fw);
 struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node);
+struct rpi_firmware *devm_rpi_firmware_get(struct device *dev,
+					   struct device_node *firmware_node);
 #else
 static inline int rpi_firmware_property(struct rpi_firmware *fw, u32 tag,
 					void *data, size_t len)
@@ -160,6 +162,12 @@
 {
 	return NULL;
 }
+
+static inline struct rpi_firmware *devm_rpi_firmware_get(struct device *dev,
+					struct device_node *firmware_node)
+{
+	return NULL;
+}
 #endif
 
 #endif /* __SOC_RASPBERRY_FIRMWARE_H__ */
diff --git a/kernel/include/soc/rockchip/pm_domains.h b/kernel/include/soc/rockchip/pm_domains.h
index fa276ce..0e1fadd 100644
--- a/kernel/include/soc/rockchip/pm_domains.h
+++ b/kernel/include/soc/rockchip/pm_domains.h
@@ -50,4 +50,12 @@
 }
 #endif
 
+#if IS_MODULE(CONFIG_ROCKCHIP_PM_DOMAINS)
+void rockchip_pd_disable_unused(void);
+#else
+static inline void rockchip_pd_disable_unused(void)
+{
+}
+#endif
+
 #endif
diff --git a/kernel/include/soc/rockchip/rk_minidump.h b/kernel/include/soc/rockchip/rk_minidump.h
index e42afda..c9e9efd 100644
--- a/kernel/include/soc/rockchip/rk_minidump.h
+++ b/kernel/include/soc/rockchip/rk_minidump.h
@@ -45,6 +45,8 @@
 int rk_minidump_update_region(int regno, const struct md_region *entry);
 bool rk_minidump_enabled(void);
 void rk_minidump_update_cpu_regs(struct pt_regs *regs);
+int rk_minidump_hardlock_notify(struct notifier_block *nb, unsigned long event,
+				void *p);
 #else
 static inline int rk_minidump_add_region(const struct md_region *entry)
 {
@@ -61,7 +63,13 @@
 }
 static inline bool rk_minidump_enabled(void) { return false; }
 static inline void rk_minidump_update_cpu_regs(struct pt_regs *regs) { return; }
+static inline int rk_minidump_hardlock_notify(struct notifier_block *nb,
+					      unsigned long event, void *p)
+{
+	return 0;
+}
 #endif
 
-extern void rk_md_flush_dcache_area(void *addr, size_t len);
+void rk_md_flush_dcache_area(void *addr, size_t len);
+extern bool (*md_is_ddr_address)(u64 virt_addr);
 #endif /* __RK_MINIDUMP_H */
diff --git a/kernel/include/soc/rockchip/rockchip-system-status.h b/kernel/include/soc/rockchip/rockchip-system-status.h
index e049212..5eb53ff 100644
--- a/kernel/include/soc/rockchip/rockchip-system-status.h
+++ b/kernel/include/soc/rockchip/rockchip-system-status.h
@@ -6,6 +6,8 @@
 #ifndef __SOC_ROCKCHIP_SYSTEM_STATUS_H
 #define __SOC_ROCKCHIP_SYSTEM_STATUS_H
 
+#include <dt-bindings/soc/rockchip-system-status.h>
+
 #if IS_REACHABLE(CONFIG_ROCKCHIP_SYSTEM_MONITOR)
 int rockchip_register_system_status_notifier(struct notifier_block *nb);
 int rockchip_unregister_system_status_notifier(struct notifier_block *nb);
diff --git a/kernel/include/soc/rockchip/rockchip_amp.h b/kernel/include/soc/rockchip/rockchip_amp.h
index 1c37e8b..851c0f4 100644
--- a/kernel/include/soc/rockchip/rockchip_amp.h
+++ b/kernel/include/soc/rockchip/rockchip_amp.h
@@ -9,15 +9,18 @@
 #ifndef _ROCKCHIP_AMP
 #define _ROCKCHIP_AMP
 
+#include <linux/irqchip/arm-gic-common.h>
+
 #if IS_REACHABLE(CONFIG_ROCKCHIP_AMP)
-void rockchip_amp_get_gic_info(void);
+void rockchip_amp_get_gic_info(u32 spis_num, enum gic_type gic_version);
 int rockchip_amp_check_amp_irq(u32 irq);
 u32 rockchip_amp_get_irq_prio(u32 irq);
 u32 rockchip_amp_get_irq_cpumask(u32 irq);
+u64 rockchip_amp_get_irq_aff(u32 irq);
+int rockchip_amp_need_init_amp_irq(u32 irq);
 #else
-#include <linux/irqchip/arm-gic-common.h>
-
-static inline void rockchip_amp_get_gic_info(void)
+static inline void rockchip_amp_get_gic_info(u32 spis_num,
+					     enum gic_type gic_version)
 {
 }
 
@@ -35,5 +38,11 @@
 {
 	return 0;
 }
+
+static inline int rockchip_amp_need_init_amp_irq(u32 irq)
+{
+	return 0;
+}
+
 #endif /* CONFIG_ROCKCHIP_AMP */
 #endif /* _ROCKCHIP_AMP */
diff --git a/kernel/include/soc/rockchip/rockchip_csu.h b/kernel/include/soc/rockchip/rockchip_csu.h
new file mode 100644
index 0000000..4338d68
--- /dev/null
+++ b/kernel/include/soc/rockchip/rockchip_csu.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2023, Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __SOC_ROCKCHIP_CSU_H
+#define __SOC_ROCKCHIP_CSU_H
+
+#include <dt-bindings/soc/rockchip-csu.h>
+
+#define CSU_MAX_DIV		8
+#define CSU_DIV_MASK		0x7
+#define CSU_EN_MASK		0xefff
+
+struct csu_clk;
+
+#if IS_REACHABLE(CONFIG_ROCKCHIP_CSU)
+struct csu_clk *rockchip_csu_get(struct device *dev, const char *name);
+int rockchip_csu_enable(struct csu_clk *clk);
+int rockchip_csu_disable(struct csu_clk *clk);
+int rockchip_csu_set_div(struct csu_clk *clk, unsigned int div);
+#else
+static inline struct csu_clk *
+rockchip_csu_get(struct device *dev, const char *name)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline int rockchip_csu_enable(struct csu_clk *clk)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int rockchip_csu_disable(struct csu_clk *clk)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+rockchip_csu_set_div(struct csu_clk *clk, unsigned int div)
+{
+	return -EOPNOTSUPP;
+}
+#endif
+
+#endif
diff --git a/kernel/include/soc/rockchip/rockchip_dmc.h b/kernel/include/soc/rockchip/rockchip_dmc.h
index 44a976b..f115cdc 100644
--- a/kernel/include/soc/rockchip/rockchip_dmc.h
+++ b/kernel/include/soc/rockchip/rockchip_dmc.h
@@ -55,6 +55,7 @@
 	unsigned long vop_req_rate;
 	unsigned int read_latency;
 	unsigned int auto_freq_en;
+	unsigned int stall_time_ns;
 	bool is_msch_rl_work_started;
 	int (*set_msch_readlatency)(unsigned int rl);
 };
@@ -76,6 +77,7 @@
 int rockchip_dmcfreq_vop_bandwidth_init(struct dmcfreq_common_info *info);
 int rockchip_dmcfreq_vop_bandwidth_request(struct dmcfreq_vop_info *vop_info);
 void rockchip_dmcfreq_vop_bandwidth_update(struct dmcfreq_vop_info *vop_info);
+unsigned int rockchip_dmcfreq_get_stall_time_ns(void);
 #else
 static inline void rockchip_dmcfreq_lock(void)
 {
@@ -118,6 +120,12 @@
 rockchip_dmcfreq_vop_bandwidth_init(struct dmcfreq_common_info *info)
 {
 }
+
+static inline unsigned int
+rockchip_dmcfreq_get_stall_time_ns(void)
+{
+	return 0;
+}
 #endif
 
 #endif
diff --git a/kernel/include/soc/rockchip/rockchip_opp_select.h b/kernel/include/soc/rockchip/rockchip_opp_select.h
index 60f01b4..e7669f2 100644
--- a/kernel/include/soc/rockchip/rockchip_opp_select.h
+++ b/kernel/include/soc/rockchip/rockchip_opp_select.h
@@ -78,6 +78,8 @@
 	u32 low_rm;
 	u32 current_rm;
 	u32 target_rm;
+	u32 pvtpll_clk_id;
+	bool pvtpll_low_temp;
 };
 
 #if IS_ENABLED(CONFIG_ROCKCHIP_OPP)
@@ -87,6 +89,7 @@
 			     int *volt_sel, int *scale_sel);
 void rockchip_pvtpll_calibrate_opp(struct rockchip_opp_info *info);
 void rockchip_pvtpll_add_length(struct rockchip_opp_info *info);
+void rockchip_init_pvtpll_table(struct rockchip_opp_info *info, int bin);
 void rockchip_of_get_pvtm_sel(struct device *dev, struct device_node *np,
 			      char *reg_name, int bin, int process,
 			      int *volt_sel, int *scale_sel);
@@ -130,6 +133,8 @@
 int rockchip_init_opp_table(struct device *dev,
 			    struct rockchip_opp_info *info,
 			    char *lkg_name, char *reg_name);
+void rockchip_uninit_opp_table(struct device *dev,
+			       struct rockchip_opp_info *info);
 #else
 static inline int rockchip_of_get_leakage(struct device *dev, char *lkg_name,
 					  int *leakage)
@@ -149,6 +154,11 @@
 }
 
 static inline void rockchip_pvtpll_add_length(struct rockchip_opp_info *info)
+{
+}
+
+static inline void rockchip_init_pvtpll_table(struct rockchip_opp_info *info,
+					      int bin)
 {
 }
 
@@ -266,6 +276,11 @@
 	return -EOPNOTSUPP;
 }
 
+static inline void rockchip_uninit_opp_table(struct device *dev,
+					     struct rockchip_opp_info *info)
+{
+}
+
 #endif /* CONFIG_ROCKCHIP_OPP */
 
 #endif
diff --git a/kernel/include/soc/rockchip/rockchip_rockit.h b/kernel/include/soc/rockchip/rockchip_rockit.h
index 9d3a34b..760a864 100644
--- a/kernel/include/soc/rockchip/rockchip_rockit.h
+++ b/kernel/include/soc/rockchip/rockchip_rockit.h
@@ -35,6 +35,7 @@
 	int cur_fps;
 	u64 old_time;
 	bool is_discard;
+	struct mutex freebuf_lock;
 };
 
 struct ISP_VIDEO_FRAMES {
@@ -132,6 +133,7 @@
 int rkisp_rockit_get_tb_stream_info(struct rockit_cfg *input_rockit_cfg,
 				    struct rkisp_tb_stream_info *info);
 int rkisp_rockit_free_tb_stream_buf(struct rockit_cfg *input_rockit_cfg);
+int rkisp_rockit_free_stream_buf(struct rockit_cfg *input_rockit_cfg);
 
 void *rkcif_rockit_function_register(void *function, int cmd);
 int rkcif_rockit_get_cifdev(char **name);
@@ -175,6 +177,11 @@
 	return -EINVAL;
 }
 
+static inline int rkisp_rockit_free_stream_buf(struct rockit_cfg *input_rockit_cfg)
+{
+	return -EINVAL;
+}
+
 #endif
 
 #endif
diff --git a/kernel/include/soc/rockchip/rockchip_sip.h b/kernel/include/soc/rockchip/rockchip_sip.h
index 1ae20d8..269cf14 100644
--- a/kernel/include/soc/rockchip/rockchip_sip.h
+++ b/kernel/include/soc/rockchip/rockchip_sip.h
@@ -23,5 +23,6 @@
 #define ROCKCHIP_SIP_CONFIG_DRAM_ECC		0x0d
 #define ROCKCHIP_SIP_CONFIG_DRAM_GET_FREQ_INFO	0x0e
 #define ROCKCHIP_SIP_CONFIG_DRAM_ADDRMAP_GET	0x10
+#define ROCKCHIP_SIP_CONFIG_DRAM_GET_STALL_TIME	0x11
 
 #endif
diff --git a/kernel/include/sound/hdaudio.h b/kernel/include/sound/hdaudio.h
index 6eed61e..496decb 100644
--- a/kernel/include/sound/hdaudio.h
+++ b/kernel/include/sound/hdaudio.h
@@ -562,6 +562,8 @@
 void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start);
 void snd_hdac_stream_clear(struct hdac_stream *azx_dev);
 void snd_hdac_stream_stop(struct hdac_stream *azx_dev);
+void snd_hdac_stop_streams(struct hdac_bus *bus);
+void snd_hdac_stop_streams_and_chip(struct hdac_bus *bus);
 void snd_hdac_stream_reset(struct hdac_stream *azx_dev);
 void snd_hdac_stream_sync_trigger(struct hdac_stream *azx_dev, bool set,
 				  unsigned int streams, unsigned int reg);
diff --git a/kernel/include/sound/hdaudio_ext.h b/kernel/include/sound/hdaudio_ext.h
index 75048ea..ddcb5b2 100644
--- a/kernel/include/sound/hdaudio_ext.h
+++ b/kernel/include/sound/hdaudio_ext.h
@@ -92,7 +92,6 @@
 				  struct hdac_ext_stream *azx_dev, bool decouple);
 void snd_hdac_ext_stream_decouple(struct hdac_bus *bus,
 				struct hdac_ext_stream *azx_dev, bool decouple);
-void snd_hdac_ext_stop_streams(struct hdac_bus *bus);
 
 int snd_hdac_ext_stream_set_spib(struct hdac_bus *bus,
 				 struct hdac_ext_stream *stream, u32 value);
diff --git a/kernel/include/sound/pcm.h b/kernel/include/sound/pcm.h
index 9479142..3821441 100644
--- a/kernel/include/sound/pcm.h
+++ b/kernel/include/sound/pcm.h
@@ -106,24 +106,24 @@
 #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_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	(1<<30)		/* continuous range */
-#define SNDRV_PCM_RATE_KNOT		(1<<31)		/* supports more non-continuos rates */
+#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|\
diff --git a/kernel/include/sound/soc-dapm.h b/kernel/include/sound/soc-dapm.h
index c3039e9..32e93d5 100644
--- a/kernel/include/sound/soc-dapm.h
+++ b/kernel/include/sound/soc-dapm.h
@@ -16,6 +16,7 @@
 #include <sound/asoc.h>
 
 struct device;
+struct snd_pcm_substream;
 struct snd_soc_pcm_runtime;
 struct soc_enum;
 
diff --git a/kernel/include/sound/soc-dpcm.h b/kernel/include/sound/soc-dpcm.h
index 0f6c50b..bd87951 100644
--- a/kernel/include/sound/soc-dpcm.h
+++ b/kernel/include/sound/soc-dpcm.h
@@ -121,6 +121,10 @@
 int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe,
 		struct snd_soc_pcm_runtime *be, int stream);
 
+/* can this BE perform prepare */
+int snd_soc_dpcm_can_be_prepared(struct snd_soc_pcm_runtime *fe,
+				 struct snd_soc_pcm_runtime *be, int stream);
+
 /* is the current PCM operation for this FE ? */
 int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream);
 
diff --git a/kernel/include/target/target_core_base.h b/kernel/include/target/target_core_base.h
index 18a5dcd..e681c71 100644
--- a/kernel/include/target/target_core_base.h
+++ b/kernel/include/target/target_core_base.h
@@ -540,7 +540,11 @@
 	struct scatterlist	*t_prot_sg;
 	unsigned int		t_prot_nents;
 	sense_reason_t		pi_err;
-	sector_t		bad_sector;
+	u64			sense_info;
+	/*
+	 * CPU LIO will execute the cmd on. Defaults to the CPU the cmd is
+	 * initialized on. Drivers can override.
+	 */
 	int			cpuid;
 };
 
@@ -761,6 +765,11 @@
 	struct config_group scsi_lu_group;
 };
 
+struct se_device_queue {
+	struct list_head	state_list;
+	spinlock_t		lock;
+};
+
 struct se_device {
 	/* RELATIVE TARGET PORT IDENTIFER Counter */
 	u16			dev_rpti_counter;
@@ -794,7 +803,6 @@
 	atomic_t		dev_qf_count;
 	u32			export_count;
 	spinlock_t		delayed_cmd_lock;
-	spinlock_t		execute_task_lock;
 	spinlock_t		dev_reservation_lock;
 	unsigned int		dev_reservation_flags;
 #define DRF_SPC2_RESERVATIONS			0x00000001
@@ -814,7 +822,6 @@
 	struct work_struct	qf_work_queue;
 	struct work_struct	delayed_cmd_work;
 	struct list_head	delayed_cmd_list;
-	struct list_head	state_list;
 	struct list_head	qf_cmd_list;
 	/* Pointer to associated SE HBA */
 	struct se_hba		*se_hba;
@@ -841,6 +848,9 @@
 	/* For se_lun->lun_se_dev RCU read-side critical access */
 	u32			hba_index;
 	struct rcu_head		rcu_head;
+	int			queue_cnt;
+	struct se_device_queue	*queues;
+	struct mutex		lun_reset_mutex;
 };
 
 struct se_hba {
diff --git a/kernel/include/trace/events/btrfs.h b/kernel/include/trace/events/btrfs.h
index ecd24c7..041be3c 100644
--- a/kernel/include/trace/events/btrfs.h
+++ b/kernel/include/trace/events/btrfs.h
@@ -95,7 +95,7 @@
 	EM( FLUSH_DELALLOC,		"FLUSH_DELALLOC")		\
 	EM( FLUSH_DELALLOC_WAIT,	"FLUSH_DELALLOC_WAIT")		\
 	EM( FLUSH_DELAYED_REFS_NR,	"FLUSH_DELAYED_REFS_NR")	\
-	EM( FLUSH_DELAYED_REFS,		"FLUSH_ELAYED_REFS")		\
+	EM( FLUSH_DELAYED_REFS,		"FLUSH_DELAYED_REFS")		\
 	EM( ALLOC_CHUNK,		"ALLOC_CHUNK")			\
 	EM( ALLOC_CHUNK_FORCE,		"ALLOC_CHUNK_FORCE")		\
 	EM( RUN_DELAYED_IPUTS,		"RUN_DELAYED_IPUTS")		\
diff --git a/kernel/include/trace/events/ext4.h b/kernel/include/trace/events/ext4.h
index 4973265..1a91d57 100644
--- a/kernel/include/trace/events/ext4.h
+++ b/kernel/include/trace/events/ext4.h
@@ -104,6 +104,7 @@
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_RENAME_DIR);
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_FALLOC_RANGE);
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_INODE_JOURNAL_DATA);
+TRACE_DEFINE_ENUM(EXT4_FC_REASON_ENCRYPTED_FILENAME);
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX);
 
 #define show_fc_reason(reason)						\
@@ -116,7 +117,8 @@
 		{ EXT4_FC_REASON_RESIZE,	"RESIZE"},		\
 		{ EXT4_FC_REASON_RENAME_DIR,	"RENAME_DIR"},		\
 		{ EXT4_FC_REASON_FALLOC_RANGE,	"FALLOC_RANGE"},	\
-		{ EXT4_FC_REASON_INODE_JOURNAL_DATA,	"INODE_JOURNAL_DATA"})
+		{ EXT4_FC_REASON_INODE_JOURNAL_DATA,	"INODE_JOURNAL_DATA"}, \
+		{ EXT4_FC_REASON_ENCRYPTED_FILENAME,	"ENCRYPTED_FILENAME"})
 
 TRACE_EVENT(ext4_other_inode_update_time,
 	TP_PROTO(struct inode *inode, ino_t orig_ino),
@@ -2940,7 +2942,7 @@
 	),
 
 	TP_printk("dev %d,%d fc ineligible reasons:\n"
-		  "%s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u "
+		  "%s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u"
 		  "num_commits:%lu, ineligible: %lu, numblks: %lu",
 		  MAJOR(__entry->dev), MINOR(__entry->dev),
 		  FC_REASON_NAME_STAT(EXT4_FC_REASON_XATTR),
@@ -2952,6 +2954,7 @@
 		  FC_REASON_NAME_STAT(EXT4_FC_REASON_RENAME_DIR),
 		  FC_REASON_NAME_STAT(EXT4_FC_REASON_FALLOC_RANGE),
 		  FC_REASON_NAME_STAT(EXT4_FC_REASON_INODE_JOURNAL_DATA),
+		  FC_REASON_NAME_STAT(EXT4_FC_REASON_ENCRYPTED_FILENAME),
 		  __entry->fc_commits, __entry->fc_ineligible_commits,
 		  __entry->fc_numblks)
 );
diff --git a/kernel/include/trace/events/f2fs.h b/kernel/include/trace/events/f2fs.h
index e927889..92bf715 100644
--- a/kernel/include/trace/events/f2fs.h
+++ b/kernel/include/trace/events/f2fs.h
@@ -520,7 +520,7 @@
 	TP_STRUCT__entry(
 		__field(dev_t,	dev)
 		__field(ino_t,	ino)
-		__field(nid_t,	nid[3])
+		__array(nid_t,	nid, 3)
 		__field(int,	depth)
 		__field(int,	err)
 	),
diff --git a/kernel/include/trace/events/jbd2.h b/kernel/include/trace/events/jbd2.h
index d16a328..b1847e4 100644
--- a/kernel/include/trace/events/jbd2.h
+++ b/kernel/include/trace/events/jbd2.h
@@ -40,7 +40,7 @@
 	TP_STRUCT__entry(
 		__field(	dev_t,	dev			)
 		__field(	char,	sync_commit		  )
-		__field(	int,	transaction		  )
+		__field(	tid_t,	transaction		  )
 	),
 
 	TP_fast_assign(
@@ -49,7 +49,7 @@
 		__entry->transaction	= commit_transaction->t_tid;
 	),
 
-	TP_printk("dev %d,%d transaction %d sync %d",
+	TP_printk("dev %d,%d transaction %u sync %d",
 		  MAJOR(__entry->dev), MINOR(__entry->dev),
 		  __entry->transaction, __entry->sync_commit)
 );
@@ -97,8 +97,8 @@
 	TP_STRUCT__entry(
 		__field(	dev_t,	dev			)
 		__field(	char,	sync_commit		  )
-		__field(	int,	transaction		  )
-		__field(	int,	head		  	  )
+		__field(	tid_t,	transaction		  )
+		__field(	tid_t,	head		  	  )
 	),
 
 	TP_fast_assign(
@@ -108,7 +108,7 @@
 		__entry->head		= journal->j_tail_sequence;
 	),
 
-	TP_printk("dev %d,%d transaction %d sync %d head %d",
+	TP_printk("dev %d,%d transaction %u sync %d head %u",
 		  MAJOR(__entry->dev), MINOR(__entry->dev),
 		  __entry->transaction, __entry->sync_commit, __entry->head)
 );
@@ -134,14 +134,14 @@
 );
 
 DECLARE_EVENT_CLASS(jbd2_handle_start_class,
-	TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
+	TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
 		 unsigned int line_no, int requested_blocks),
 
 	TP_ARGS(dev, tid, type, line_no, requested_blocks),
 
 	TP_STRUCT__entry(
 		__field(		dev_t,	dev		)
-		__field(	unsigned long,	tid		)
+		__field(		tid_t,	tid		)
 		__field(	 unsigned int,	type		)
 		__field(	 unsigned int,	line_no		)
 		__field(		  int,	requested_blocks)
@@ -155,28 +155,28 @@
 		__entry->requested_blocks = requested_blocks;
 	),
 
-	TP_printk("dev %d,%d tid %lu type %u line_no %u "
+	TP_printk("dev %d,%d tid %u type %u line_no %u "
 		  "requested_blocks %d",
 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
 		  __entry->type, __entry->line_no, __entry->requested_blocks)
 );
 
 DEFINE_EVENT(jbd2_handle_start_class, jbd2_handle_start,
-	TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
+	TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
 		 unsigned int line_no, int requested_blocks),
 
 	TP_ARGS(dev, tid, type, line_no, requested_blocks)
 );
 
 DEFINE_EVENT(jbd2_handle_start_class, jbd2_handle_restart,
-	TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
+	TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
 		 unsigned int line_no, int requested_blocks),
 
 	TP_ARGS(dev, tid, type, line_no, requested_blocks)
 );
 
 TRACE_EVENT(jbd2_handle_extend,
-	TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
+	TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
 		 unsigned int line_no, int buffer_credits,
 		 int requested_blocks),
 
@@ -184,7 +184,7 @@
 
 	TP_STRUCT__entry(
 		__field(		dev_t,	dev		)
-		__field(	unsigned long,	tid		)
+		__field(		tid_t,	tid		)
 		__field(	 unsigned int,	type		)
 		__field(	 unsigned int,	line_no		)
 		__field(		  int,	buffer_credits  )
@@ -200,7 +200,7 @@
 		__entry->requested_blocks = requested_blocks;
 	),
 
-	TP_printk("dev %d,%d tid %lu type %u line_no %u "
+	TP_printk("dev %d,%d tid %u type %u line_no %u "
 		  "buffer_credits %d requested_blocks %d",
 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
 		  __entry->type, __entry->line_no, __entry->buffer_credits,
@@ -208,7 +208,7 @@
 );
 
 TRACE_EVENT(jbd2_handle_stats,
-	TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
+	TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
 		 unsigned int line_no, int interval, int sync,
 		 int requested_blocks, int dirtied_blocks),
 
@@ -217,7 +217,7 @@
 
 	TP_STRUCT__entry(
 		__field(		dev_t,	dev		)
-		__field(	unsigned long,	tid		)
+		__field(		tid_t,	tid		)
 		__field(	 unsigned int,	type		)
 		__field(	 unsigned int,	line_no		)
 		__field(		  int,	interval	)
@@ -237,7 +237,7 @@
 		__entry->dirtied_blocks	  = dirtied_blocks;
 	),
 
-	TP_printk("dev %d,%d tid %lu type %u line_no %u interval %d "
+	TP_printk("dev %d,%d tid %u type %u line_no %u interval %d "
 		  "sync %d requested_blocks %d dirtied_blocks %d",
 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
 		  __entry->type, __entry->line_no, __entry->interval,
@@ -246,14 +246,14 @@
 );
 
 TRACE_EVENT(jbd2_run_stats,
-	TP_PROTO(dev_t dev, unsigned long tid,
+	TP_PROTO(dev_t dev, tid_t tid,
 		 struct transaction_run_stats_s *stats),
 
 	TP_ARGS(dev, tid, stats),
 
 	TP_STRUCT__entry(
 		__field(		dev_t,	dev		)
-		__field(	unsigned long,	tid		)
+		__field(		tid_t,	tid		)
 		__field(	unsigned long,	wait		)
 		__field(	unsigned long,	request_delay	)
 		__field(	unsigned long,	running		)
@@ -279,7 +279,7 @@
 		__entry->blocks_logged	= stats->rs_blocks_logged;
 	),
 
-	TP_printk("dev %d,%d tid %lu wait %u request_delay %u running %u "
+	TP_printk("dev %d,%d tid %u wait %u request_delay %u running %u "
 		  "locked %u flushing %u logging %u handle_count %u "
 		  "blocks %u blocks_logged %u",
 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
@@ -294,14 +294,14 @@
 );
 
 TRACE_EVENT(jbd2_checkpoint_stats,
-	TP_PROTO(dev_t dev, unsigned long tid,
+	TP_PROTO(dev_t dev, tid_t tid,
 		 struct transaction_chp_stats_s *stats),
 
 	TP_ARGS(dev, tid, stats),
 
 	TP_STRUCT__entry(
 		__field(		dev_t,	dev		)
-		__field(	unsigned long,	tid		)
+		__field(		tid_t,	tid		)
 		__field(	unsigned long,	chp_time	)
 		__field(		__u32,	forced_to_close	)
 		__field(		__u32,	written		)
@@ -317,7 +317,7 @@
 		__entry->dropped	= stats->cs_dropped;
 	),
 
-	TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u "
+	TP_printk("dev %d,%d tid %u chp_time %u forced_to_close %u "
 		  "written %u dropped %u",
 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
 		  jiffies_to_msecs(__entry->chp_time),
diff --git a/kernel/include/trace/events/qrtr.h b/kernel/include/trace/events/qrtr.h
index b1de14c..441132c 100644
--- a/kernel/include/trace/events/qrtr.h
+++ b/kernel/include/trace/events/qrtr.h
@@ -10,15 +10,16 @@
 
 TRACE_EVENT(qrtr_ns_service_announce_new,
 
-	TP_PROTO(__le32 service, __le32 instance, __le32 node, __le32 port),
+	TP_PROTO(unsigned int service, unsigned int instance,
+		 unsigned int node, unsigned int port),
 
 	TP_ARGS(service, instance, node, port),
 
 	TP_STRUCT__entry(
-		__field(__le32, service)
-		__field(__le32, instance)
-		__field(__le32, node)
-		__field(__le32, port)
+		__field(unsigned int, service)
+		__field(unsigned int, instance)
+		__field(unsigned int, node)
+		__field(unsigned int, port)
 	),
 
 	TP_fast_assign(
@@ -36,15 +37,16 @@
 
 TRACE_EVENT(qrtr_ns_service_announce_del,
 
-	TP_PROTO(__le32 service, __le32 instance, __le32 node, __le32 port),
+	TP_PROTO(unsigned int service, unsigned int instance,
+		 unsigned int node, unsigned int port),
 
 	TP_ARGS(service, instance, node, port),
 
 	TP_STRUCT__entry(
-		__field(__le32, service)
-		__field(__le32, instance)
-		__field(__le32, node)
-		__field(__le32, port)
+		__field(unsigned int, service)
+		__field(unsigned int, instance)
+		__field(unsigned int, node)
+		__field(unsigned int, port)
 	),
 
 	TP_fast_assign(
@@ -62,15 +64,16 @@
 
 TRACE_EVENT(qrtr_ns_server_add,
 
-	TP_PROTO(__le32 service, __le32 instance, __le32 node, __le32 port),
+	TP_PROTO(unsigned int service, unsigned int instance,
+		 unsigned int node, unsigned int port),
 
 	TP_ARGS(service, instance, node, port),
 
 	TP_STRUCT__entry(
-		__field(__le32, service)
-		__field(__le32, instance)
-		__field(__le32, node)
-		__field(__le32, port)
+		__field(unsigned int, service)
+		__field(unsigned int, instance)
+		__field(unsigned int, node)
+		__field(unsigned int, port)
 	),
 
 	TP_fast_assign(
diff --git a/kernel/include/trace/events/rcu.h b/kernel/include/trace/events/rcu.h
index 8476f31..aa3dd15 100644
--- a/kernel/include/trace/events/rcu.h
+++ b/kernel/include/trace/events/rcu.h
@@ -741,7 +741,7 @@
 	TP_ARGS(rcutorturename, rhp, secs, c_old, c),
 
 	TP_STRUCT__entry(
-		__field(char, rcutorturename[RCUTORTURENAME_LEN])
+		__array(char, rcutorturename, RCUTORTURENAME_LEN)
 		__field(struct rcu_head *, rhp)
 		__field(unsigned long, secs)
 		__field(unsigned long, c_old)
diff --git a/kernel/include/trace/events/timer.h b/kernel/include/trace/events/timer.h
index 19abb6c..5c540cc 100644
--- a/kernel/include/trace/events/timer.h
+++ b/kernel/include/trace/events/timer.h
@@ -156,7 +156,11 @@
 		{ HRTIMER_MODE_ABS_SOFT,	"ABS|SOFT"	},	\
 		{ HRTIMER_MODE_REL_SOFT,	"REL|SOFT"	},	\
 		{ HRTIMER_MODE_ABS_PINNED_SOFT,	"ABS|PINNED|SOFT" },	\
-		{ HRTIMER_MODE_REL_PINNED_SOFT,	"REL|PINNED|SOFT" })
+		{ HRTIMER_MODE_REL_PINNED_SOFT,	"REL|PINNED|SOFT" },	\
+		{ HRTIMER_MODE_ABS_HARD,	"ABS|HARD" },		\
+		{ HRTIMER_MODE_REL_HARD,	"REL|HARD" },		\
+		{ HRTIMER_MODE_ABS_PINNED_HARD, "ABS|PINNED|HARD" },	\
+		{ HRTIMER_MODE_REL_PINNED_HARD,	"REL|PINNED|HARD" })
 
 /**
  * hrtimer_init - called when the hrtimer is initialized
@@ -368,7 +372,8 @@
 		tick_dep_name(PERF_EVENTS)		\
 		tick_dep_name(SCHED)			\
 		tick_dep_name(CLOCK_UNSTABLE)		\
-		tick_dep_name_end(RCU)
+		tick_dep_name(RCU)			\
+		tick_dep_name_end(RCU_EXP)
 
 #undef tick_dep_name
 #undef tick_dep_mask_name
diff --git a/kernel/include/trace/events/writeback.h b/kernel/include/trace/events/writeback.h
index 57d7953..453255a 100644
--- a/kernel/include/trace/events/writeback.h
+++ b/kernel/include/trace/events/writeback.h
@@ -67,7 +67,7 @@
 		strscpy_pad(__entry->name,
 			    bdi_dev_name(mapping ? inode_to_bdi(mapping->host) :
 					 NULL), 32);
-		__entry->ino = mapping ? mapping->host->i_ino : 0;
+		__entry->ino = (mapping && mapping->host) ? mapping->host->i_ino : 0;
 		__entry->index = page->index;
 	),
 
diff --git a/kernel/include/trace/hooks/dma_noalias.h b/kernel/include/trace/hooks/dma_noalias.h
deleted file mode 100644
index 2dc7b04..0000000
--- a/kernel/include/trace/hooks/dma_noalias.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM dma_noalias
-
-#define TRACE_INCLUDE_PATH trace/hooks
-
-#if !defined(_TRACE_HOOK_DMA_NOALIAS_H) || defined(TRACE_HEADER_MULTI_READ)
-#define _TRACE_HOOK_DMA_NOALIAS_H
-
-#include <trace/hooks/vendor_hooks.h>
-
-DECLARE_RESTRICTED_HOOK(android_rvh_setup_dma_ops,
-	TP_PROTO(struct device *dev),
-	TP_ARGS(dev), 1);
-
-#endif /*_TRACE_HOOK_DMA_NOALIAS_H */
-
-/* This part must be outside protection */
-#include <trace/define_trace.h>
diff --git a/kernel/include/trace/hooks/dtask.h b/kernel/include/trace/hooks/dtask.h
index 956e842..d8fa440 100644
--- a/kernel/include/trace/hooks/dtask.h
+++ b/kernel/include/trace/hooks/dtask.h
@@ -32,6 +32,15 @@
 DECLARE_HOOK(android_vh_mutex_wait_finish,
 	TP_PROTO(struct mutex *lock),
 	TP_ARGS(lock));
+DECLARE_HOOK(android_vh_mutex_opt_spin_start,
+	TP_PROTO(struct mutex *lock, bool *time_out, int *cnt),
+	TP_ARGS(lock, time_out, cnt));
+DECLARE_HOOK(android_vh_mutex_opt_spin_finish,
+	TP_PROTO(struct mutex *lock, bool taken),
+	TP_ARGS(lock, taken));
+DECLARE_HOOK(android_vh_mutex_can_spin_on_owner,
+	TP_PROTO(struct mutex *lock, int *retval),
+	TP_ARGS(lock, retval));
 
 DECLARE_HOOK(android_vh_rtmutex_wait_start,
 	TP_PROTO(struct rt_mutex *lock),
@@ -52,6 +61,15 @@
 DECLARE_HOOK(android_vh_rwsem_write_wait_finish,
 	TP_PROTO(struct rw_semaphore *sem),
 	TP_ARGS(sem));
+DECLARE_HOOK(android_vh_rwsem_opt_spin_start,
+	TP_PROTO(struct rw_semaphore *sem, bool *time_out, int *cnt, bool chk_only),
+	TP_ARGS(sem, time_out, cnt, chk_only));
+DECLARE_HOOK(android_vh_rwsem_opt_spin_finish,
+	TP_PROTO(struct rw_semaphore *sem, bool taken, bool wlock),
+	TP_ARGS(sem, taken, wlock));
+DECLARE_HOOK(android_vh_rwsem_can_spin_on_owner,
+	TP_PROTO(struct rw_semaphore *sem, bool *ret, bool wlock),
+	TP_ARGS(sem, ret, wlock));
 
 DECLARE_HOOK(android_vh_sched_show_task,
 	TP_PROTO(struct task_struct *task),
@@ -81,6 +99,12 @@
 	TP_PROTO(struct task_struct *tsk, unsigned long settime_jiffies),
 	TP_ARGS(tsk, settime_jiffies));
 
+struct percpu_rw_semaphore;
+DECLARE_HOOK(android_vh_percpu_rwsem_wq_add,
+	TP_PROTO(struct percpu_rw_semaphore *sem, bool reader),
+	TP_ARGS(sem, reader));
+
+
 /* macro versions of hooks are no longer required */
 
 #endif /* _TRACE_HOOK_DTASK_H */
diff --git a/kernel/include/trace/hooks/mm.h b/kernel/include/trace/hooks/mm.h
index a4b855e..2b2459b 100644
--- a/kernel/include/trace/hooks/mm.h
+++ b/kernel/include/trace/hooks/mm.h
@@ -126,6 +126,14 @@
 DECLARE_HOOK(android_vh_vmpressure,
 	TP_PROTO(struct mem_cgroup *memcg, bool *bypass),
 	TP_ARGS(memcg, bypass));
+DECLARE_HOOK(android_vh_dm_bufio_shrink_scan_bypass,
+	TP_PROTO(unsigned long dm_bufio_current_allocated, bool *bypass),
+	TP_ARGS(dm_bufio_current_allocated, bypass));
+DECLARE_HOOK(android_vh_cleanup_old_buffers_bypass,
+	TP_PROTO(unsigned long dm_bufio_current_allocated,
+		unsigned long *max_age_hz,
+		bool *bypass),
+	TP_ARGS(dm_bufio_current_allocated, max_age_hz, bypass));
 DECLARE_HOOK(android_vh_mem_cgroup_alloc,
 	TP_PROTO(struct mem_cgroup *memcg),
 	TP_ARGS(memcg));
@@ -184,6 +192,27 @@
 DECLARE_HOOK(android_vh_cma_drain_all_pages_bypass,
 	TP_PROTO(unsigned int migratetype, bool *bypass),
 	TP_ARGS(migratetype, bypass));
+DECLARE_HOOK(android_vh_free_unref_page_bypass,
+	TP_PROTO(struct page *page, int order, int migratetype, bool *bypass),
+	TP_ARGS(page, order, migratetype, bypass));
+DECLARE_HOOK(android_vh_kvmalloc_node_use_vmalloc,
+	TP_PROTO(size_t size, gfp_t *kmalloc_flags, bool *use_vmalloc),
+	TP_ARGS(size, kmalloc_flags, use_vmalloc));
+DECLARE_HOOK(android_vh_should_alloc_pages_retry,
+	TP_PROTO(gfp_t gfp_mask, int order, int *alloc_flags,
+	int migratetype, struct zone *preferred_zone, struct page **page, bool *should_alloc_retry),
+	TP_ARGS(gfp_mask, order, alloc_flags,
+		migratetype, preferred_zone, page, should_alloc_retry));
+DECLARE_HOOK(android_vh_unreserve_highatomic_bypass,
+	TP_PROTO(bool force, struct zone *zone, bool *skip_unreserve_highatomic),
+	TP_ARGS(force, zone, skip_unreserve_highatomic));
+DECLARE_HOOK(android_vh_pageset_update,
+	TP_PROTO(unsigned long *high, unsigned long *batch),
+	TP_ARGS(high, batch));
+DECLARE_HOOK(android_vh_rmqueue_bulk_bypass,
+	TP_PROTO(unsigned int order, struct per_cpu_pages *pcp, int migratetype,
+		struct list_head *list),
+	TP_ARGS(order, pcp, migratetype, list));
 DECLARE_HOOK(android_vh_pcplist_add_cma_pages_bypass,
 	TP_PROTO(int migratetype, bool *bypass),
 	TP_ARGS(migratetype, bypass));
@@ -193,6 +222,10 @@
 DECLARE_HOOK(android_vh_ra_tuning_max_page,
 	TP_PROTO(struct readahead_control *ractl, unsigned long *max_page),
 	TP_ARGS(ractl, max_page));
+DECLARE_HOOK(android_vh_tune_mmap_readaround,
+	TP_PROTO(unsigned int ra_pages, pgoff_t pgoff,
+		pgoff_t *start, unsigned int *size, unsigned int *async_size),
+	TP_ARGS(ra_pages, pgoff, start, size, async_size));
 DECLARE_RESTRICTED_HOOK(android_rvh_handle_pte_fault_end,
 	TP_PROTO(struct vm_fault *vmf, unsigned long highest_memmap_pfn),
 	TP_ARGS(vmf, highest_memmap_pfn), 1);
@@ -254,18 +287,33 @@
 	TP_PROTO(struct page *page, swp_entry_t *entry,
 		struct swap_slots_cache *cache, bool *found),
 	TP_ARGS(page, entry, cache, found));
+DECLARE_HOOK(android_vh_add_to_avail_list,
+	TP_PROTO(struct swap_info_struct *p, bool *skip),
+	TP_ARGS(p, skip));
+DECLARE_HOOK(android_vh_del_from_avail_list,
+	TP_PROTO(struct swap_info_struct *p, bool *skip),
+	TP_ARGS(p, skip));
+DECLARE_HOOK(android_vh___cgroup_throttle_swaprate,
+	TP_PROTO(int nid, bool *skip),
+	TP_ARGS(nid, skip));
 DECLARE_HOOK(android_vh_madvise_cold_or_pageout,
 	TP_PROTO(struct vm_area_struct *vma, bool *allow_shared),
 	TP_ARGS(vma, allow_shared));
 DECLARE_HOOK(android_vh_page_isolated_for_reclaim,
 	TP_PROTO(struct mm_struct *mm, struct page *page),
 	TP_ARGS(mm, page));
+DECLARE_HOOK(android_vh_should_end_madvise,
+	TP_PROTO(struct mm_struct *mm, bool *skip, bool *pageout),
+	TP_ARGS(mm, skip, pageout));
 DECLARE_HOOK(android_vh_account_swap_pages,
 	TP_PROTO(struct swap_info_struct *si, bool *skip),
 	TP_ARGS(si, skip));
 DECLARE_HOOK(android_vh_unuse_swap_page,
 	TP_PROTO(struct swap_info_struct *si, struct page *page),
 	TP_ARGS(si, page));
+DECLARE_HOOK(android_vh_swap_avail_heads_init,
+	TP_PROTO(struct plist_head *swap_avail_heads),
+	TP_ARGS(swap_avail_heads));
 DECLARE_HOOK(android_vh_init_swap_info_struct,
 	TP_PROTO(struct swap_info_struct *p, struct plist_head *swap_avail_heads),
 	TP_ARGS(p, swap_avail_heads));
@@ -305,6 +353,15 @@
 	TP_PROTO(struct page_vma_mapped_walk *pvmw, struct page *page,
 		struct vm_area_struct *vma, int *referenced),
 	TP_ARGS(pvmw, page, vma, referenced));
+DECLARE_HOOK(android_vh_compact_finished,
+	TP_PROTO(bool *abort_compact),
+	TP_ARGS(abort_compact));
+DECLARE_HOOK(android_vh_madvise_cold_or_pageout_abort,
+	TP_PROTO(struct vm_area_struct *vma, bool *abort_madvise),
+	TP_ARGS(vma, abort_madvise));
+DECLARE_HOOK(android_vh_skip_swapcache,
+	TP_PROTO(swp_entry_t entry, bool *skip),
+	TP_ARGS(entry, skip));
 /* macro versions of hooks are no longer required */
 
 #endif /* _TRACE_HOOK_MM_H */
diff --git a/kernel/include/trace/hooks/wakeupbypass.h b/kernel/include/trace/hooks/wakeupbypass.h
new file mode 100644
index 0000000..a96c887
--- /dev/null
+++ b/kernel/include/trace/hooks/wakeupbypass.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM wakeupbypass
+
+#define TRACE_INCLUDE_PATH trace/hooks
+
+#if !defined(_TRACE_HOOK_WAKEUPBYPASS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_HOOK_WAKEUPBYPASS_H
+#include <trace/hooks/vendor_hooks.h>
+
+DECLARE_HOOK(android_vh_wakeup_bypass,
+	TP_PROTO(int *is_wakeup_bypassed),
+	TP_ARGS(is_wakeup_bypassed));
+
+#endif /* _TRACE_HOOK_WAKEUPBYPASS_H */
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/kernel/include/trace/trace_events.h b/kernel/include/trace/trace_events.h
index d74c076..717d388 100644
--- a/kernel/include/trace/trace_events.h
+++ b/kernel/include/trace/trace_events.h
@@ -400,7 +400,7 @@
 
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 
-#define ALIGN_STRUCTFIELD(type) ((int)(offsetof(struct {char a; type b;}, b)))
+#define ALIGN_STRUCTFIELD(type) ((int)(__alignof__(struct {type b;})))
 
 #undef __field_ext
 #define __field_ext(_type, _item, _filter_type) {			\
diff --git a/kernel/include/uapi/asm-generic/socket.h b/kernel/include/uapi/asm-generic/socket.h
index 77f7c16..6456068 100644
--- a/kernel/include/uapi/asm-generic/socket.h
+++ b/kernel/include/uapi/asm-generic/socket.h
@@ -119,6 +119,8 @@
 
 #define SO_DETACH_REUSEPORT_BPF 68
 
+#define SO_NETNS_COOKIE		71
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
diff --git a/kernel/include/uapi/drm/drm_fourcc.h b/kernel/include/uapi/drm/drm_fourcc.h
index bedc59d..1c10ff5 100644
--- a/kernel/include/uapi/drm/drm_fourcc.h
+++ b/kernel/include/uapi/drm/drm_fourcc.h
@@ -273,6 +273,13 @@
  */
 #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
@@ -780,6 +787,10 @@
  * 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) \
@@ -1059,14 +1070,43 @@
  */
 #define AMLOGIC_FBC_OPTION_MEM_SAVING		(1ULL << 0)
 
+/*
+ * Rockchip modifier format
+ * tiled modifier format, block size: 8x8,4x4_m0 and 4x4_m1,
+ * rfbc modifier format, block size: 64x4
+ *
+ * bit[55,52] for Rockchip drm modifier type
+ */
+#define DRM_FORMAT_MOD_ROCKCHIP_TYPE_SHIFT	52
+#define DRM_FORMAT_MOD_ROCKCHIP_TYPE_MASK	0xf
+#define DRM_FORMAT_MOD_ROCKCHIP_TYPE_TILED	0x0
+#define DRM_FORMAT_MOD_ROCKCHIP_TYPE_RFBC	0x1
+
+/* bit[3,0] for Rockchip drm modifier block size */
 #define ROCKCHIP_TILED_BLOCK_SIZE_MASK		0xf
 #define ROCKCHIP_TILED_BLOCK_SIZE_8x8		(1ULL)
 #define ROCKCHIP_TILED_BLOCK_SIZE_4x4_MODE0	(2ULL)
 #define ROCKCHIP_TILED_BLOCK_SIZE_4x4_MODE1	(3ULL)
 
-#define DRM_FORMAT_MOD_ROCKCHIP_TILED(_mode) fourcc_mod_code(ROCKCHIP, _mode)
+#define ROCKCHIP_RFBC_BLOCK_SIZE_64x4		(1ULL)
 
-#define IS_ROCKCHIP_TILED_MOD(val) (((val) >> 56) == DRM_FORMAT_MOD_VENDOR_ROCKCHIP)
+#define DRM_FORMAT_MOD_ROCKCHIP_CODE(__type, __val) \
+	fourcc_mod_code(ROCKCHIP, ((__u64)(__type) << DRM_FORMAT_MOD_ROCKCHIP_TYPE_SHIFT) | \
+			((__val) & 0x000fffffffffffffULL))
+
+/* Rockchip tiled modifier format */
+#define DRM_FORMAT_MOD_ROCKCHIP_TILED(mode) \
+	DRM_FORMAT_MOD_ROCKCHIP_CODE(DRM_FORMAT_MOD_ROCKCHIP_TYPE_TILED, mode)
+#define IS_ROCKCHIP_TILED_MOD(val) \
+	(((val) >> 56) == DRM_FORMAT_MOD_VENDOR_ROCKCHIP && \
+	 ((val >> DRM_FORMAT_MOD_ROCKCHIP_TYPE_SHIFT) & DRM_FORMAT_MOD_ROCKCHIP_TYPE_MASK) == DRM_FORMAT_MOD_ROCKCHIP_TYPE_TILED)
+
+/* Rockchip rfbc modifier format */
+#define DRM_FORMAT_MOD_ROCKCHIP_RFBC(mode) \
+	DRM_FORMAT_MOD_ROCKCHIP_CODE(DRM_FORMAT_MOD_ROCKCHIP_TYPE_RFBC, mode)
+#define IS_ROCKCHIP_RFBC_MOD(val) \
+	(((val) >> 56) == DRM_FORMAT_MOD_VENDOR_ROCKCHIP && \
+	 ((val >> DRM_FORMAT_MOD_ROCKCHIP_TYPE_SHIFT) & DRM_FORMAT_MOD_ROCKCHIP_TYPE_MASK) == DRM_FORMAT_MOD_ROCKCHIP_TYPE_RFBC)
 
 #if defined(__cplusplus)
 }
diff --git a/kernel/include/uapi/linux/affs_hardblocks.h b/kernel/include/uapi/linux/affs_hardblocks.h
index 5e2fb84..a5aff2e 100644
--- a/kernel/include/uapi/linux/affs_hardblocks.h
+++ b/kernel/include/uapi/linux/affs_hardblocks.h
@@ -7,42 +7,42 @@
 /* Just the needed definitions for the RDB of an Amiga HD. */
 
 struct RigidDiskBlock {
-	__u32	rdb_ID;
+	__be32	rdb_ID;
 	__be32	rdb_SummedLongs;
-	__s32	rdb_ChkSum;
-	__u32	rdb_HostID;
+	__be32	rdb_ChkSum;
+	__be32	rdb_HostID;
 	__be32	rdb_BlockBytes;
-	__u32	rdb_Flags;
-	__u32	rdb_BadBlockList;
+	__be32	rdb_Flags;
+	__be32	rdb_BadBlockList;
 	__be32	rdb_PartitionList;
-	__u32	rdb_FileSysHeaderList;
-	__u32	rdb_DriveInit;
-	__u32	rdb_Reserved1[6];
-	__u32	rdb_Cylinders;
-	__u32	rdb_Sectors;
-	__u32	rdb_Heads;
-	__u32	rdb_Interleave;
-	__u32	rdb_Park;
-	__u32	rdb_Reserved2[3];
-	__u32	rdb_WritePreComp;
-	__u32	rdb_ReducedWrite;
-	__u32	rdb_StepRate;
-	__u32	rdb_Reserved3[5];
-	__u32	rdb_RDBBlocksLo;
-	__u32	rdb_RDBBlocksHi;
-	__u32	rdb_LoCylinder;
-	__u32	rdb_HiCylinder;
-	__u32	rdb_CylBlocks;
-	__u32	rdb_AutoParkSeconds;
-	__u32	rdb_HighRDSKBlock;
-	__u32	rdb_Reserved4;
+	__be32	rdb_FileSysHeaderList;
+	__be32	rdb_DriveInit;
+	__be32	rdb_Reserved1[6];
+	__be32	rdb_Cylinders;
+	__be32	rdb_Sectors;
+	__be32	rdb_Heads;
+	__be32	rdb_Interleave;
+	__be32	rdb_Park;
+	__be32	rdb_Reserved2[3];
+	__be32	rdb_WritePreComp;
+	__be32	rdb_ReducedWrite;
+	__be32	rdb_StepRate;
+	__be32	rdb_Reserved3[5];
+	__be32	rdb_RDBBlocksLo;
+	__be32	rdb_RDBBlocksHi;
+	__be32	rdb_LoCylinder;
+	__be32	rdb_HiCylinder;
+	__be32	rdb_CylBlocks;
+	__be32	rdb_AutoParkSeconds;
+	__be32	rdb_HighRDSKBlock;
+	__be32	rdb_Reserved4;
 	char	rdb_DiskVendor[8];
 	char	rdb_DiskProduct[16];
 	char	rdb_DiskRevision[4];
 	char	rdb_ControllerVendor[8];
 	char	rdb_ControllerProduct[16];
 	char	rdb_ControllerRevision[4];
-	__u32	rdb_Reserved5[10];
+	__be32	rdb_Reserved5[10];
 };
 
 #define	IDNAME_RIGIDDISK	0x5244534B	/* "RDSK" */
@@ -50,16 +50,16 @@
 struct PartitionBlock {
 	__be32	pb_ID;
 	__be32	pb_SummedLongs;
-	__s32	pb_ChkSum;
-	__u32	pb_HostID;
+	__be32	pb_ChkSum;
+	__be32	pb_HostID;
 	__be32	pb_Next;
-	__u32	pb_Flags;
-	__u32	pb_Reserved1[2];
-	__u32	pb_DevFlags;
+	__be32	pb_Flags;
+	__be32	pb_Reserved1[2];
+	__be32	pb_DevFlags;
 	__u8	pb_DriveName[32];
-	__u32	pb_Reserved2[15];
+	__be32	pb_Reserved2[15];
 	__be32	pb_Environment[17];
-	__u32	pb_EReserved[15];
+	__be32	pb_EReserved[15];
 };
 
 #define	IDNAME_PARTITION	0x50415254	/* "PART" */
diff --git a/kernel/include/uapi/linux/auto_dev-ioctl.h b/kernel/include/uapi/linux/auto_dev-ioctl.h
index 62e6253..08be539 100644
--- a/kernel/include/uapi/linux/auto_dev-ioctl.h
+++ b/kernel/include/uapi/linux/auto_dev-ioctl.h
@@ -109,7 +109,7 @@
 		struct args_ismountpoint	ismountpoint;
 	};
 
-	char path[0];
+	char path[];
 };
 
 static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in)
diff --git a/kernel/include/uapi/linux/blkzoned.h b/kernel/include/uapi/linux/blkzoned.h
index 656a326..321965f 100644
--- a/kernel/include/uapi/linux/blkzoned.h
+++ b/kernel/include/uapi/linux/blkzoned.h
@@ -51,13 +51,13 @@
  *
  * The Zone Condition state machine in the ZBC/ZAC standards maps the above
  * deinitions as:
- *   - ZC1: Empty         | BLK_ZONE_EMPTY
+ *   - ZC1: Empty         | BLK_ZONE_COND_EMPTY
  *   - ZC2: Implicit Open | BLK_ZONE_COND_IMP_OPEN
  *   - ZC3: Explicit Open | BLK_ZONE_COND_EXP_OPEN
- *   - ZC4: Closed        | BLK_ZONE_CLOSED
- *   - ZC5: Full          | BLK_ZONE_FULL
- *   - ZC6: Read Only     | BLK_ZONE_READONLY
- *   - ZC7: Offline       | BLK_ZONE_OFFLINE
+ *   - ZC4: Closed        | BLK_ZONE_COND_CLOSED
+ *   - ZC5: Full          | BLK_ZONE_COND_FULL
+ *   - ZC6: Read Only     | BLK_ZONE_COND_READONLY
+ *   - ZC7: Offline       | BLK_ZONE_COND_OFFLINE
  *
  * Conditions 0x5 to 0xC are reserved by the current ZBC/ZAC spec and should
  * be considered invalid.
diff --git a/kernel/include/uapi/linux/bpf.h b/kernel/include/uapi/linux/bpf.h
index 2a23402..36ddfb9 100644
--- a/kernel/include/uapi/linux/bpf.h
+++ b/kernel/include/uapi/linux/bpf.h
@@ -976,7 +976,9 @@
  * 		performed again, if the helper is used in combination with
  * 		direct packet access.
  * 	Return
- * 		0 on success, or a negative error in case of failure.
+ * 		0 on success, or a negative error in case of failure. Positive
+ * 		error indicates a potential drop or congestion in the target
+ * 		device. The particular positive error codes are not defined.
  *
  * u64 bpf_get_current_pid_tgid(void)
  * 	Return
diff --git a/kernel/include/uapi/linux/btrfs.h b/kernel/include/uapi/linux/btrfs.h
index 2c39d15..e65300d 100644
--- a/kernel/include/uapi/linux/btrfs.h
+++ b/kernel/include/uapi/linux/btrfs.h
@@ -181,6 +181,7 @@
 };
 
 #define BTRFS_SCRUB_READONLY	1
+#define BTRFS_SCRUB_SUPPORTED_FLAGS	(BTRFS_SCRUB_READONLY)
 struct btrfs_ioctl_scrub_args {
 	__u64 devid;				/* in */
 	__u64 start;				/* in */
diff --git a/kernel/include/uapi/linux/dn.h b/kernel/include/uapi/linux/dn.h
deleted file mode 100644
index 36ca71b..0000000
--- a/kernel/include/uapi/linux/dn.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _LINUX_DN_H
-#define _LINUX_DN_H
-
-#include <linux/ioctl.h>
-#include <linux/types.h>
-#include <linux/if_ether.h>
-
-/*
-
-	DECnet Data Structures and Constants
-
-*/
-
-/* 
- * DNPROTO_NSP can't be the same as SOL_SOCKET, 
- * so increment each by one (compared to ULTRIX)
- */
-#define DNPROTO_NSP     2                       /* NSP protocol number       */
-#define DNPROTO_ROU     3                       /* Routing protocol number   */
-#define DNPROTO_NML     4                       /* Net mgt protocol number   */
-#define DNPROTO_EVL     5                       /* Evl protocol number (usr) */
-#define DNPROTO_EVR     6                       /* Evl protocol number (evl) */
-#define DNPROTO_NSPT    7                       /* NSP trace protocol number */
-
-
-#define DN_ADDL		2
-#define DN_MAXADDL	2 /* ULTRIX headers have 20 here, but pathworks has 2 */
-#define DN_MAXOPTL	16
-#define DN_MAXOBJL	16
-#define DN_MAXACCL	40
-#define DN_MAXALIASL	128
-#define DN_MAXNODEL	256
-#define DNBUFSIZE	65023
-
-/* 
- * SET/GET Socket options  - must match the DSO_ numbers below
- */
-#define SO_CONDATA      1
-#define SO_CONACCESS    2
-#define SO_PROXYUSR     3
-#define SO_LINKINFO     7
-
-#define DSO_CONDATA     1        /* Set/Get connect data                */
-#define DSO_DISDATA     10       /* Set/Get disconnect data             */
-#define DSO_CONACCESS   2        /* Set/Get connect access data         */
-#define DSO_ACCEPTMODE  4        /* Set/Get accept mode                 */
-#define DSO_CONACCEPT   5        /* Accept deferred connection          */
-#define DSO_CONREJECT   6        /* Reject deferred connection          */
-#define DSO_LINKINFO    7        /* Set/Get link information            */
-#define DSO_STREAM      8        /* Set socket type to stream           */
-#define DSO_SEQPACKET   9        /* Set socket type to sequenced packet */
-#define DSO_MAXWINDOW   11       /* Maximum window size allowed         */
-#define DSO_NODELAY	12       /* Turn off nagle                      */
-#define DSO_CORK        13       /* Wait for more data!                 */
-#define DSO_SERVICES	14       /* NSP Services field                  */
-#define DSO_INFO	15       /* NSP Info field                      */
-#define DSO_MAX         15       /* Maximum option number               */
-
-
-/* LINK States */
-#define LL_INACTIVE	0
-#define LL_CONNECTING	1
-#define LL_RUNNING	2
-#define LL_DISCONNECTING 3
-
-#define ACC_IMMED 0
-#define ACC_DEFER 1
-
-#define SDF_WILD        1                  /* Wild card object          */
-#define SDF_PROXY       2                  /* Addr eligible for proxy   */
-#define SDF_UICPROXY    4                  /* Use uic-based proxy       */
-
-/* Structures */
-
-
-struct dn_naddr {
-	__le16		a_len;
-	__u8 a_addr[DN_MAXADDL]; /* Two bytes little endian */
-};
-
-struct sockaddr_dn {
-	__u16		sdn_family;
-	__u8		sdn_flags;
-	__u8		sdn_objnum;
-	__le16		sdn_objnamel;
-	__u8		sdn_objname[DN_MAXOBJL];
-	struct   dn_naddr	sdn_add;
-};
-#define sdn_nodeaddrl   sdn_add.a_len   /* Node address length  */
-#define sdn_nodeaddr    sdn_add.a_addr  /* Node address         */
-
-
-
-/*
- * DECnet set/get DSO_CONDATA, DSO_DISDATA (optional data) structure
- */
-struct optdata_dn {
-        __le16  opt_status;     /* Extended status return */
-#define opt_sts opt_status
-        __le16  opt_optl;       /* Length of user data    */
-        __u8   opt_data[16];   /* User data              */
-};
-
-struct accessdata_dn {
-	__u8		acc_accl;
-	__u8		acc_acc[DN_MAXACCL];
-	__u8 		acc_passl;
-	__u8		acc_pass[DN_MAXACCL];
-	__u8 		acc_userl;
-	__u8		acc_user[DN_MAXACCL];
-};
-
-/*
- * DECnet logical link information structure
- */
-struct linkinfo_dn {
-        __u16  idn_segsize;    /* Segment size for link */
-        __u8   idn_linkstate;  /* Logical link state    */
-};
-
-/*
- * Ethernet address format (for DECnet)
- */
-union etheraddress {
-        __u8 dne_addr[ETH_ALEN];      /* Full ethernet address */
-  struct {
-                __u8 dne_hiord[4];    /* DECnet HIORD prefix   */
-                __u8 dne_nodeaddr[2]; /* DECnet node address   */
-  } dne_remote;
-};
-
-
-/*
- * DECnet physical socket address format
- */
-struct dn_addr {
-        __le16 dna_family;      /* AF_DECnet               */
-        union etheraddress dna_netaddr; /* DECnet ethernet address */
-};
-
-#define DECNET_IOCTL_BASE 0x89 /* PROTOPRIVATE range */
-
-#define SIOCSNETADDR  _IOW(DECNET_IOCTL_BASE, 0xe0, struct dn_naddr)
-#define SIOCGNETADDR  _IOR(DECNET_IOCTL_BASE, 0xe1, struct dn_naddr)
-#define OSIOCSNETADDR _IOW(DECNET_IOCTL_BASE, 0xe0, int)
-#define OSIOCGNETADDR _IOR(DECNET_IOCTL_BASE, 0xe1, int)
-
-#endif /* _LINUX_DN_H */
diff --git a/kernel/include/uapi/linux/idxd.h b/kernel/include/uapi/linux/idxd.h
index 9d9ecc0..f086c55 100644
--- a/kernel/include/uapi/linux/idxd.h
+++ b/kernel/include/uapi/linux/idxd.h
@@ -188,7 +188,7 @@
 		};
 
 		uint32_t	delta_rec_size;
-		uint32_t	crc_val;
+		uint64_t	crc_val;
 
 		/* DIF check & strip */
 		struct {
diff --git a/kernel/include/uapi/linux/in.h b/kernel/include/uapi/linux/in.h
index d1b3270..3960bc3 100644
--- a/kernel/include/uapi/linux/in.h
+++ b/kernel/include/uapi/linux/in.h
@@ -159,6 +159,8 @@
 #define MCAST_MSFILTER			48
 #define IP_MULTICAST_ALL		49
 #define IP_UNICAST_IF			50
+#define IP_LOCAL_PORT_RANGE		51
+#define IP_PROTOCOL			52
 
 #define MCAST_EXCLUDE	0
 #define MCAST_INCLUDE	1
diff --git a/kernel/include/uapi/linux/ip.h b/kernel/include/uapi/linux/ip.h
index 64beb32..86d7eba 100644
--- a/kernel/include/uapi/linux/ip.h
+++ b/kernel/include/uapi/linux/ip.h
@@ -18,6 +18,7 @@
 #ifndef _UAPI_LINUX_IP_H
 #define _UAPI_LINUX_IP_H
 #include <linux/types.h>
+#include <linux/stddef.h>
 #include <asm/byteorder.h>
 
 #define IPTOS_TOS_MASK		0x1E
diff --git a/kernel/include/uapi/linux/ipv6.h b/kernel/include/uapi/linux/ipv6.h
index bfe9542..2aadbba 100644
--- a/kernel/include/uapi/linux/ipv6.h
+++ b/kernel/include/uapi/linux/ipv6.h
@@ -4,6 +4,7 @@
 
 #include <linux/libc-compat.h>
 #include <linux/types.h>
+#include <linux/stddef.h>
 #include <linux/in6.h>
 #include <asm/byteorder.h>
 
diff --git a/kernel/include/uapi/linux/netfilter/nf_conntrack_sctp.h b/kernel/include/uapi/linux/netfilter/nf_conntrack_sctp.h
index edc6dda..2d6f80d 100644
--- a/kernel/include/uapi/linux/netfilter/nf_conntrack_sctp.h
+++ b/kernel/include/uapi/linux/netfilter/nf_conntrack_sctp.h
@@ -15,7 +15,7 @@
 	SCTP_CONNTRACK_SHUTDOWN_RECD,
 	SCTP_CONNTRACK_SHUTDOWN_ACK_SENT,
 	SCTP_CONNTRACK_HEARTBEAT_SENT,
-	SCTP_CONNTRACK_HEARTBEAT_ACKED,
+	SCTP_CONNTRACK_HEARTBEAT_ACKED,	/* no longer used */
 	SCTP_CONNTRACK_MAX
 };
 
diff --git a/kernel/include/uapi/linux/netfilter/nf_tables.h b/kernel/include/uapi/linux/netfilter/nf_tables.h
index 98272cb..1d8dd58 100644
--- a/kernel/include/uapi/linux/netfilter/nf_tables.h
+++ b/kernel/include/uapi/linux/netfilter/nf_tables.h
@@ -797,11 +797,13 @@
  * @NFT_EXTHDR_OP_IPV6: match against ipv6 extension headers
  * @NFT_EXTHDR_OP_TCP: match against tcp options
  * @NFT_EXTHDR_OP_IPV4: match against ipv4 options
+ * @NFT_EXTHDR_OP_SCTP: match against sctp chunks
  */
 enum nft_exthdr_op {
 	NFT_EXTHDR_OP_IPV6,
 	NFT_EXTHDR_OP_TCPOPT,
 	NFT_EXTHDR_OP_IPV4,
+	NFT_EXTHDR_OP_SCTP,
 	__NFT_EXTHDR_OP_MAX
 };
 #define NFT_EXTHDR_OP_MAX	(__NFT_EXTHDR_OP_MAX - 1)
diff --git a/kernel/include/uapi/linux/netfilter/nfnetlink_cttimeout.h b/kernel/include/uapi/linux/netfilter/nfnetlink_cttimeout.h
index 6b20fb2..aa805e6 100644
--- a/kernel/include/uapi/linux/netfilter/nfnetlink_cttimeout.h
+++ b/kernel/include/uapi/linux/netfilter/nfnetlink_cttimeout.h
@@ -94,7 +94,7 @@
 	CTA_TIMEOUT_SCTP_SHUTDOWN_RECD,
 	CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT,
 	CTA_TIMEOUT_SCTP_HEARTBEAT_SENT,
-	CTA_TIMEOUT_SCTP_HEARTBEAT_ACKED,
+	CTA_TIMEOUT_SCTP_HEARTBEAT_ACKED, /* no longer used */
 	__CTA_TIMEOUT_SCTP_MAX
 };
 #define CTA_TIMEOUT_SCTP_MAX (__CTA_TIMEOUT_SCTP_MAX - 1)
diff --git a/kernel/include/uapi/linux/netfilter_bridge/ebtables.h b/kernel/include/uapi/linux/netfilter_bridge/ebtables.h
index a494cf4..b0caad8 100644
--- a/kernel/include/uapi/linux/netfilter_bridge/ebtables.h
+++ b/kernel/include/uapi/linux/netfilter_bridge/ebtables.h
@@ -182,12 +182,14 @@
 	unsigned char sourcemsk[ETH_ALEN];
 	unsigned char destmac[ETH_ALEN];
 	unsigned char destmsk[ETH_ALEN];
-	/* sizeof ebt_entry + matches */
-	unsigned int watchers_offset;
-	/* sizeof ebt_entry + matches + watchers */
-	unsigned int target_offset;
-	/* sizeof ebt_entry + matches + watchers + target */
-	unsigned int next_offset;
+	__struct_group(/* no tag */, offsets, /* no attrs */,
+		/* sizeof ebt_entry + matches */
+		unsigned int watchers_offset;
+		/* sizeof ebt_entry + matches + watchers */
+		unsigned int target_offset;
+		/* sizeof ebt_entry + matches + watchers + target */
+		unsigned int next_offset;
+	);
 	unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
 };
 
diff --git a/kernel/include/uapi/linux/netfilter_decnet.h b/kernel/include/uapi/linux/netfilter_decnet.h
deleted file mode 100644
index 3c77f54..0000000
--- a/kernel/include/uapi/linux/netfilter_decnet.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef __LINUX_DECNET_NETFILTER_H
-#define __LINUX_DECNET_NETFILTER_H
-
-/* DECnet-specific defines for netfilter. 
- * This file (C) Steve Whitehouse 1999 derived from the
- * ipv4 netfilter header file which is
- * (C)1998 Rusty Russell -- This code is GPL.
- */
-
-#include <linux/netfilter.h>
-
-/* only for userspace compatibility */
-#ifndef __KERNEL__
-
-#include <limits.h> /* for INT_MIN, INT_MAX */
-
-/* kernel define is in netfilter_defs.h */
-#define NF_DN_NUMHOOKS		7
-#endif /* ! __KERNEL__ */
-
-/* DECnet Hooks */
-/* After promisc drops, checksum checks. */
-#define NF_DN_PRE_ROUTING	0
-/* If the packet is destined for this box. */
-#define NF_DN_LOCAL_IN		1
-/* If the packet is destined for another interface. */
-#define NF_DN_FORWARD		2
-/* Packets coming from a local process. */
-#define NF_DN_LOCAL_OUT		3
-/* Packets about to hit the wire. */
-#define NF_DN_POST_ROUTING	4
-/* Input Hello Packets */
-#define NF_DN_HELLO		5
-/* Input Routing Packets */
-#define NF_DN_ROUTE		6
-
-enum nf_dn_hook_priorities {
-	NF_DN_PRI_FIRST = INT_MIN,
-	NF_DN_PRI_CONNTRACK = -200,
-	NF_DN_PRI_MANGLE = -150,
-	NF_DN_PRI_NAT_DST = -100,
-	NF_DN_PRI_FILTER = 0,
-	NF_DN_PRI_NAT_SRC = 100,
-	NF_DN_PRI_DNRTMSG = 200,
-	NF_DN_PRI_LAST = INT_MAX,
-};
-
-struct nf_dn_rtmsg {
-	int nfdn_ifindex;
-};
-
-#define NFDN_RTMSG(r) ((unsigned char *)(r) + NLMSG_ALIGN(sizeof(struct nf_dn_rtmsg)))
-
-#ifndef __KERNEL__
-/* backwards compatibility for userspace */
-#define DNRMG_L1_GROUP 0x01
-#define DNRMG_L2_GROUP 0x02
-#endif
-
-enum {
-	DNRNG_NLGRP_NONE,
-#define DNRNG_NLGRP_NONE	DNRNG_NLGRP_NONE
-	DNRNG_NLGRP_L1,
-#define DNRNG_NLGRP_L1		DNRNG_NLGRP_L1
-	DNRNG_NLGRP_L2,
-#define DNRNG_NLGRP_L2		DNRNG_NLGRP_L2
-	__DNRNG_NLGRP_MAX
-};
-#define DNRNG_NLGRP_MAX	(__DNRNG_NLGRP_MAX - 1)
-
-#endif /*__LINUX_DECNET_NETFILTER_H*/
diff --git a/kernel/include/uapi/linux/netlink.h b/kernel/include/uapi/linux/netlink.h
index 3d94269..49751d5 100644
--- a/kernel/include/uapi/linux/netlink.h
+++ b/kernel/include/uapi/linux/netlink.h
@@ -20,7 +20,7 @@
 #define NETLINK_CONNECTOR	11
 #define NETLINK_NETFILTER	12	/* netfilter subsystem */
 #define NETLINK_IP6_FW		13
-#define NETLINK_DNRTMSG		14	/* DECnet routing messages */
+#define NETLINK_DNRTMSG		14	/* DECnet routing messages (obsolete) */
 #define NETLINK_KOBJECT_UEVENT	15	/* Kernel messages to userspace */
 #define NETLINK_GENERIC		16
 /* leave room for NETLINK_DM (DM Events) */
diff --git a/kernel/include/uapi/linux/rk-camera-module.h b/kernel/include/uapi/linux/rk-camera-module.h
index 7a825af..d25977d 100644
--- a/kernel/include/uapi/linux/rk-camera-module.h
+++ b/kernel/include/uapi/linux/rk-camera-module.h
@@ -183,6 +183,9 @@
 #define RKMODULE_SET_CAPTURE_MODE  \
 	_IOW('V', BASE_VIDIOC_PRIVATE + 40, struct rkmodule_capture_info)
 
+#define RKMODULE_GET_SKIP_FRAME  \
+	_IOR('V', BASE_VIDIOC_PRIVATE + 41, __u32)
+
 struct rkmodule_i2cdev_info {
 	__u8 slave_addr;
 } __attribute__ ((packed));
@@ -638,6 +641,7 @@
 	RKICF_RESET_SRC_ERR_CUTOFF,
 	RKCIF_RESET_SRC_ERR_HOTPLUG,
 	RKCIF_RESET_SRC_ERR_APP,
+	RKCIF_RESET_SRC_ERR_ISP,
 };
 
 struct rkmodule_vicap_reset_info {
diff --git a/kernel/include/uapi/linux/rk-isp2-config.h b/kernel/include/uapi/linux/rk-isp2-config.h
index 9de8ac7..50949e0 100644
--- a/kernel/include/uapi/linux/rk-isp2-config.h
+++ b/kernel/include/uapi/linux/rk-isp2-config.h
@@ -11,7 +11,7 @@
 #include <linux/types.h>
 #include <linux/v4l2-controls.h>
 
-#define RKISP_API_VERSION		KERNEL_VERSION(2, 3, 0)
+#define RKISP_API_VERSION		KERNEL_VERSION(2, 4, 0)
 
 /****************ISP SUBDEV IOCTL*****************************/
 
@@ -1968,6 +1968,12 @@
 	struct rkisp_mipi_luma luma[ISP2X_MIPI_RAW_MAX];
 } __attribute__ ((packed));
 
+enum {
+	RKISP_RTT_MODE_NORMAL = 0,
+	RKISP_RTT_MODE_MULTI_FRAME,
+	RKISP_RTT_MODE_ONE_FRAME,
+};
+
 /**
  * struct rkisp_thunderboot_resmem_head
  */
@@ -1976,15 +1982,20 @@
 	__u16 complete;
 	__u16 frm_total;
 	__u16 hdr_mode;
+	__u16 rtt_mode;
 	__u16 width;
 	__u16 height;
 	__u16 camera_num;
 	__u16 camera_index;
+	__u16 md_flag;
 
 	__u32 exp_time[3];
 	__u32 exp_gain[3];
 	__u32 exp_time_reg[3];
 	__u32 exp_gain_reg[3];
+	__u32 exp_isp_dgain[3];
+	__u32 nr_buf_size;
+	__u32 share_mem_size;
 } __attribute__ ((packed));
 
 /**
diff --git a/kernel/include/uapi/linux/rk-isp32-config.h b/kernel/include/uapi/linux/rk-isp32-config.h
index cabd8c1..ecd4eae 100644
--- a/kernel/include/uapi/linux/rk-isp32-config.h
+++ b/kernel/include/uapi/linux/rk-isp32-config.h
@@ -52,7 +52,7 @@
 #define ISP32_MODULE_CSM		ISP3X_MODULE_CSM
 #define ISP32_MODULE_CGC		ISP3X_MODULE_CGC
 #define ISP32_MODULE_VSM		BIT_ULL(45)
-
+#define ISP32_MODULE_RTT_FST		BIT_ULL(62)
 #define ISP32_MODULE_FORCE		ISP3X_MODULE_FORCE
 
 /* Measurement types */
@@ -70,6 +70,7 @@
 #define ISP32_STAT_DHAZ			ISP3X_STAT_DHAZ
 #define ISP32_STAT_VSM			BIT(18)
 #define ISP32_STAT_INFO2DDR		BIT(19)
+#define ISP32_STAT_RTT_FST		BIT(31)
 
 #define ISP32_MESH_BUF_NUM		ISP3X_MESH_BUF_NUM
 
diff --git a/kernel/include/uapi/linux/rk-mpp.h b/kernel/include/uapi/linux/rk-mpp.h
new file mode 100644
index 0000000..9a24407
--- /dev/null
+++ b/kernel/include/uapi/linux/rk-mpp.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR MIT) */
+/*
+ * Rockchip mpp driver
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef _UAPI_RK_MPP_H
+#define _UAPI_RK_MPP_H
+
+#include <linux/types.h>
+
+/* Use 'v' as magic number */
+#define MPP_IOC_MAGIC			'v'
+
+#define MPP_IOC_CFG_V1			_IOW(MPP_IOC_MAGIC, 1, unsigned int)
+#define MPP_IOC_CFG_V2			_IOW(MPP_IOC_MAGIC, 2, unsigned int)
+
+/**
+ * Command type: keep the same as user space
+ */
+enum MPP_DEV_COMMAND_TYPE {
+	MPP_CMD_QUERY_BASE		= 0,
+	MPP_CMD_QUERY_HW_SUPPORT	= MPP_CMD_QUERY_BASE + 0,
+	MPP_CMD_QUERY_HW_ID		= MPP_CMD_QUERY_BASE + 1,
+	MPP_CMD_QUERY_CMD_SUPPORT	= MPP_CMD_QUERY_BASE + 2,
+	MPP_CMD_QUERY_BUTT,
+
+	MPP_CMD_INIT_BASE		= 0x100,
+	MPP_CMD_INIT_CLIENT_TYPE	= MPP_CMD_INIT_BASE + 0,
+	MPP_CMD_INIT_DRIVER_DATA	= MPP_CMD_INIT_BASE + 1,
+	MPP_CMD_INIT_TRANS_TABLE	= MPP_CMD_INIT_BASE + 2,
+	MPP_CMD_INIT_BUTT,
+
+	MPP_CMD_SEND_BASE		= 0x200,
+	MPP_CMD_SET_REG_WRITE		= MPP_CMD_SEND_BASE + 0,
+	MPP_CMD_SET_REG_READ		= MPP_CMD_SEND_BASE + 1,
+	MPP_CMD_SET_REG_ADDR_OFFSET	= MPP_CMD_SEND_BASE + 2,
+	MPP_CMD_SET_RCB_INFO		= MPP_CMD_SEND_BASE + 3,
+	MPP_CMD_SET_SESSION_FD		= MPP_CMD_SEND_BASE + 4,
+	MPP_CMD_SEND_BUTT,
+
+	MPP_CMD_POLL_BASE		= 0x300,
+	MPP_CMD_POLL_HW_FINISH		= MPP_CMD_POLL_BASE + 0,
+	MPP_CMD_POLL_HW_IRQ		= MPP_CMD_POLL_BASE + 1,
+	MPP_CMD_POLL_BUTT,
+
+	MPP_CMD_CONTROL_BASE		= 0x400,
+	MPP_CMD_RESET_SESSION		= MPP_CMD_CONTROL_BASE + 0,
+	MPP_CMD_TRANS_FD_TO_IOVA	= MPP_CMD_CONTROL_BASE + 1,
+	MPP_CMD_RELEASE_FD		= MPP_CMD_CONTROL_BASE + 2,
+	MPP_CMD_SEND_CODEC_INFO		= MPP_CMD_CONTROL_BASE + 3,
+	MPP_CMD_CONTROL_BUTT,
+
+	MPP_CMD_BUTT,
+};
+
+/* define flags for mpp_request */
+#define MPP_FLAGS_MULTI_MSG		(0x00000001)
+#define MPP_FLAGS_LAST_MSG		(0x00000002)
+#define MPP_FLAGS_REG_FD_NO_TRANS	(0x00000004)
+#define MPP_FLAGS_SCL_FD_NO_TRANS	(0x00000008)
+#define MPP_FLAGS_REG_NO_OFFSET		(0x00000010)
+#define MPP_FLAGS_SECURE_MODE		(0x00010000)
+
+/* data common struct for parse out */
+struct mpp_request {
+	__u32 cmd;
+	__u32 flags;
+	__u32 size;
+	__u32 offset;
+	void __user *data;
+};
+
+#define MPP_BAT_MSG_DONE		(0x00000001)
+
+struct mpp_bat_msg {
+	__u64 flag;
+	__u32 fd;
+	__s32 ret;
+};
+
+#endif /* _UAPI_RK_MPP_H */
diff --git a/kernel/include/uapi/linux/rk-pcie-ep.h b/kernel/include/uapi/linux/rk-pcie-ep.h
index b6e3ac0..d89748e 100644
--- a/kernel/include/uapi/linux/rk-pcie-ep.h
+++ b/kernel/include/uapi/linux/rk-pcie-ep.h
@@ -25,19 +25,26 @@
 #define RKEP_SMODE_APPRDY       0x20
 
 /*
- * rockchip pcie driver elbi ioctrl output data
- */
-struct pcie_ep_user_data {
-	__u64 bar0_phys_addr;
-	__u32 elbi_app_user[11];
-};
-
-/*
  * rockchip driver cache ioctrl input param
  */
 struct pcie_ep_dma_cache_cfg {
 	__u64 addr;
 	__u32 size;
+};
+
+struct pcie_ep_dma_block {
+	__u64 bus_paddr;
+	__u64 local_paddr;
+	__u32 size;
+};
+
+struct pcie_ep_dma_block_req {
+	__u16 vir_id;	/* Default 0 */
+	__u8 chn;
+	__u8 wr;
+	__u32 flag;
+#define PCIE_EP_DMA_BLOCK_FLAG_COHERENT BIT(0)		/* Cache coherent, 1-need, 0-None */
+	struct pcie_ep_dma_block block;
 };
 
 #define	PCIE_EP_OBJ_INFO_MAGIC 0x524B4550
@@ -59,8 +66,14 @@
 	PCIE_EP_MMAP_RESOURCE_BAR0,
 	PCIE_EP_MMAP_RESOURCE_BAR2,
 	PCIE_EP_MMAP_RESOURCE_BAR4,
+	PCIE_EP_MMAP_RESOURCE_USER_MEM,
+	PCIE_EP_MMAP_RESOURCE_RK3568_RC_DBI,
+	PCIE_EP_MMAP_RESOURCE_RK3588_RC_DBI,
 	PCIE_EP_MMAP_RESOURCE_MAX,
 };
+
+#define PCIE_EP_OBJ_INFO_MSI_DATA_NUM	0x8
+#define RKEP_EP_VIRTUAL_ID_MAX		(PCIE_EP_OBJ_INFO_MSI_DATA_NUM * 32) /* 256 virtual_id */
 
 /*
  * rockchip ep device information which is store in BAR0
@@ -72,22 +85,38 @@
 		__u16 mode;
 		__u16 submode;
 	} devmode;
-	__u8 reserved[0x1F4];
+	__u32 msi_data[PCIE_EP_OBJ_INFO_MSI_DATA_NUM];
+	__u8 reserved[0x1D0];
 
 	__u32 irq_type_rc;					/* Generate in ep isr, valid only for rc, clear in rc */
 	struct pcie_ep_obj_irq_dma_status dma_status_rc;	/* Generate in ep isr, valid only for rc, clear in rc */
 	__u32 irq_type_ep;					/* Generate in ep isr, valid only for ep, clear in ep */
 	struct pcie_ep_obj_irq_dma_status dma_status_ep;	/* Generate in ep isr, valid only for ep, clear in ep */
-	__u32 obj_irq_user_data;				/* OBJ_IRQ_USER userspace data */
+	__u32 irq_user_data_rc;					/* Generate in ep, valid only for rc, No need to clear */
+	__u32 irq_user_data_ep;					/* Generate in rc, valid only for ep, No need to clear */
+};
+
+/*
+ * rockchip driver ep_obj poll ioctrl input param
+ */
+struct pcie_ep_obj_poll_virtual_id_cfg {
+	__u32 timeout_ms;
+	__u32 sync;
+	__u32 virtual_id;
+	__u32 poll_status;
 };
 
 #define PCIE_BASE	'P'
-#define PCIE_DMA_GET_ELBI_DATA		_IOR(PCIE_BASE, 0, struct pcie_ep_user_data)
 #define PCIE_DMA_CACHE_INVALIDE		_IOW(PCIE_BASE, 1, struct pcie_ep_dma_cache_cfg)
 #define PCIE_DMA_CACHE_FLUSH		_IOW(PCIE_BASE, 2, struct pcie_ep_dma_cache_cfg)
 #define PCIE_DMA_IRQ_MASK_ALL		_IOW(PCIE_BASE, 3, int)
-#define PCIE_DMA_RAISE_MSI_OBJ_IRQ_USER	_IOW(PCIE_BASE, 4, int)
-#define PCIE_EP_GET_USER_INFO		_IOR(PCIE_BASE, 5, struct pcie_ep_user_data)
-#define PCIE_EP_SET_MMAP_RESOURCE	_IOW(PCIE_BASE, 6, enum pcie_ep_mmap_resource)
+#define PCIE_EP_RAISE_MSI		_IOW(PCIE_BASE, 4, int)
+#define PCIE_EP_SET_MMAP_RESOURCE	_IOW(PCIE_BASE, 6, int)
+#define PCIE_EP_RAISE_ELBI		_IOW(PCIE_BASE, 7, int)
+#define PCIE_EP_REQUEST_VIRTUAL_ID	_IOR(PCIE_BASE, 16, int)
+#define PCIE_EP_RELEASE_VIRTUAL_ID	_IOW(PCIE_BASE, 17, int)
+#define PCIE_EP_RAISE_IRQ_USER		_IOW(PCIE_BASE, 18, int)
+#define PCIE_EP_POLL_IRQ_USER		_IOW(PCIE_BASE, 19, struct pcie_ep_obj_poll_virtual_id_cfg)
+#define PCIE_EP_DMA_XFER_BLOCK		_IOW(PCIE_BASE, 32, struct pcie_ep_dma_block_req)
 
 #endif
diff --git a/kernel/include/uapi/linux/rk_hdmirx_config.h b/kernel/include/uapi/linux/rk_hdmirx_config.h
index a0b7e43..26dcea7 100644
--- a/kernel/include/uapi/linux/rk_hdmirx_config.h
+++ b/kernel/include/uapi/linux/rk_hdmirx_config.h
@@ -82,4 +82,7 @@
 #define RK_HDMIRX_V4L2_EVENT_SIGNAL_LOST \
 	(V4L2_EVENT_PRIVATE_START + 1)
 
+#define RK_HDMIRX_V4L2_EVENT_AUDIOINFO \
+	(V4L2_EVENT_PRIVATE_START + 2)
+
 #endif /* _UAPI_RK_HDMIRX_CONFIG_H */
diff --git a/kernel/include/uapi/linux/rkcif-config.h b/kernel/include/uapi/linux/rkcif-config.h
index a65b5b1..c9b9bbf 100644
--- a/kernel/include/uapi/linux/rkcif-config.h
+++ b/kernel/include/uapi/linux/rkcif-config.h
@@ -36,6 +36,9 @@
 #define RKCIF_CMD_SET_CSI_IDX \
 	_IOW('V', BASE_VIDIOC_PRIVATE + 7, struct rkcif_csi_info)
 
+#define RKCIF_CMD_SET_QUICK_STREAM \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 8, struct rkcif_quick_stream_param)
+
 /* cif memory mode
  * 0: raw12/raw10/raw8 8bit memory compact
  * 1: raw12/raw10 16bit memory one pixel
@@ -79,4 +82,10 @@
 	int dphy_vendor[RKCIF_MAX_CSI_NUM];
 };
 
+struct rkcif_quick_stream_param {
+	int on;
+	__u32 frame_num;
+	int resume_mode;
+};
+
 #endif
diff --git a/kernel/include/uapi/linux/swab.h b/kernel/include/uapi/linux/swab.h
index 7272f85..3736f2f 100644
--- a/kernel/include/uapi/linux/swab.h
+++ b/kernel/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>
 
diff --git a/kernel/include/uapi/linux/sync_file.h b/kernel/include/uapi/linux/sync_file.h
index ee2dcfb..d7f7c04 100644
--- a/kernel/include/uapi/linux/sync_file.h
+++ b/kernel/include/uapi/linux/sync_file.h
@@ -52,7 +52,7 @@
  * @name:	name of fence
  * @status:	status of fence. 1: signaled 0:active <0:error
  * @flags:	sync_file_info flags
- * @num_fences	number of fences in the sync_file
+ * @num_fences:	number of fences in the sync_file
  * @pad:	padding for 64-bit alignment, should always be zero
  * @sync_fence_info: pointer to array of structs sync_fence_info with all
  *		 fences in the sync_file
diff --git a/kernel/include/uapi/linux/usb/video.h b/kernel/include/uapi/linux/usb/video.h
index b82436f..d160d5b 100644
--- a/kernel/include/uapi/linux/usb/video.h
+++ b/kernel/include/uapi/linux/usb/video.h
@@ -179,6 +179,36 @@
 #define UVC_CONTROL_CAP_AUTOUPDATE			(1 << 3)
 #define UVC_CONTROL_CAP_ASYNCHRONOUS			(1 << 4)
 
+/* 3.9.2.6 Color Matching Descriptor Values */
+enum uvc_color_primaries_values {
+	UVC_COLOR_PRIMARIES_UNSPECIFIED,
+	UVC_COLOR_PRIMARIES_BT_709_SRGB,
+	UVC_COLOR_PRIMARIES_BT_470_2_M,
+	UVC_COLOR_PRIMARIES_BT_470_2_B_G,
+	UVC_COLOR_PRIMARIES_SMPTE_170M,
+	UVC_COLOR_PRIMARIES_SMPTE_240M,
+};
+
+enum uvc_transfer_characteristics_values {
+	UVC_TRANSFER_CHARACTERISTICS_UNSPECIFIED,
+	UVC_TRANSFER_CHARACTERISTICS_BT_709,
+	UVC_TRANSFER_CHARACTERISTICS_BT_470_2_M,
+	UVC_TRANSFER_CHARACTERISTICS_BT_470_2_B_G,
+	UVC_TRANSFER_CHARACTERISTICS_SMPTE_170M,
+	UVC_TRANSFER_CHARACTERISTICS_SMPTE_240M,
+	UVC_TRANSFER_CHARACTERISTICS_LINEAR,
+	UVC_TRANSFER_CHARACTERISTICS_SRGB,
+};
+
+enum uvc_matrix_coefficients {
+	UVC_MATRIX_COEFFICIENTS_UNSPECIFIED,
+	UVC_MATRIX_COEFFICIENTS_BT_709,
+	UVC_MATRIX_COEFFICIENTS_FCC,
+	UVC_MATRIX_COEFFICIENTS_BT_470_2_B_G,
+	UVC_MATRIX_COEFFICIENTS_SMPTE_170M,
+	UVC_MATRIX_COEFFICIENTS_SMPTE_240M,
+};
+
 /* ------------------------------------------------------------------------
  * UVC structures
  */
diff --git a/kernel/include/uapi/linux/uvcvideo.h b/kernel/include/uapi/linux/uvcvideo.h
index f80f05b..2140923 100644
--- a/kernel/include/uapi/linux/uvcvideo.h
+++ b/kernel/include/uapi/linux/uvcvideo.h
@@ -86,7 +86,7 @@
  * struct. The first two fields are added by the driver, they can be used for
  * clock synchronisation. The rest is an exact copy of a UVC payload header.
  * Only complete objects with complete buffers are included. Therefore it's
- * always sizeof(meta->ts) + sizeof(meta->sof) + meta->length bytes large.
+ * always sizeof(meta->ns) + sizeof(meta->sof) + meta->length bytes large.
  */
 struct uvc_meta_buf {
 	__u64 ns;
diff --git a/kernel/include/uapi/linux/videodev2.h b/kernel/include/uapi/linux/videodev2.h
index 514db71..47a28d8 100644
--- a/kernel/include/uapi/linux/videodev2.h
+++ b/kernel/include/uapi/linux/videodev2.h
@@ -1648,7 +1648,7 @@
 	__u8	     name[32];		/*  Label */
 	__u32	     type;		/*  Type of input */
 	__u32	     audioset;		/*  Associated audios (bitfield) */
-	__u32        tuner;             /*  enum v4l2_tuner_type */
+	__u32        tuner;             /*  Tuner index */
 	v4l2_std_id  std;
 	__u32	     status;
 	__u32	     capabilities;
diff --git a/kernel/include/uapi/sound/asequencer.h b/kernel/include/uapi/sound/asequencer.h
index a75e14e..dbd60f4 100644
--- a/kernel/include/uapi/sound/asequencer.h
+++ b/kernel/include/uapi/sound/asequencer.h
@@ -344,10 +344,10 @@
 #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 */
diff --git a/kernel/include/uapi/sound/skl-tplg-interface.h b/kernel/include/uapi/sound/skl-tplg-interface.h
index a93c0de..215ce16 100644
--- a/kernel/include/uapi/sound/skl-tplg-interface.h
+++ b/kernel/include/uapi/sound/skl-tplg-interface.h
@@ -66,7 +66,8 @@
 	SKL_CH_CFG_DUAL_MONO = 9,
 	SKL_CH_CFG_I2S_DUAL_STEREO_0 = 10,
 	SKL_CH_CFG_I2S_DUAL_STEREO_1 = 11,
-	SKL_CH_CFG_4_CHANNEL = 12,
+	SKL_CH_CFG_7_1 = 12,
+	SKL_CH_CFG_4_CHANNEL = SKL_CH_CFG_7_1,
 	SKL_CH_CFG_INVALID
 };
 
diff --git a/kernel/include/xen/xen.h b/kernel/include/xen/xen.h
index 43efba0..5a6a2ab 100644
--- a/kernel/include/xen/xen.h
+++ b/kernel/include/xen/xen.h
@@ -61,4 +61,15 @@
 #include <xen/balloon.h>
 #endif
 
+#if defined(CONFIG_XEN_DOM0) && defined(CONFIG_ACPI) && defined(CONFIG_X86)
+bool __init xen_processor_present(uint32_t acpi_id);
+#else
+#include <linux/bug.h>
+static inline bool xen_processor_present(uint32_t acpi_id)
+{
+	BUG();
+	return false;
+}
+#endif
+
 #endif	/* _XEN_XEN_H */
diff --git a/kernel/init/Kconfig b/kernel/init/Kconfig
index 2c92f94..6e011c6 100644
--- a/kernel/init/Kconfig
+++ b/kernel/init/Kconfig
@@ -47,6 +47,18 @@
 	int
 	default $(shell,$(srctree)/scripts/clang-version.sh $(CC))
 
+config AS_IS_GNU
+	def_bool $(success,test "$(as-name)" = GNU)
+
+config AS_IS_LLVM
+	def_bool $(success,test "$(as-name)" = LLVM)
+
+config AS_VERSION
+	int
+	# Use clang version if this is the integrated assembler
+	default CLANG_VERSION if AS_IS_LLVM
+	default $(as-version)
+
 config LLD_VERSION
 	int
 	default $(shell,$(srctree)/scripts/lld-version.sh $(LD))
diff --git a/kernel/init/main.c b/kernel/init/main.c
index 45ca352..02d6bfb 100644
--- a/kernel/init/main.c
+++ b/kernel/init/main.c
@@ -96,13 +96,11 @@
 #include <linux/cache.h>
 #include <linux/rodata_test.h>
 #include <linux/jump_label.h>
-#include <linux/mem_encrypt.h>
 #include <linux/kcsan.h>
 #include <linux/init_syscalls.h>
 #include <linux/stackdepot.h>
 
 #include <asm/io.h>
-#include <asm/bugs.h>
 #include <asm/setup.h>
 #include <asm/sections.h>
 #include <asm/cacheflush.h>
@@ -766,8 +764,6 @@
 }
 #endif
 
-void __init __weak mem_encrypt_init(void) { }
-
 void __init __weak poking_init(void) { }
 
 void __init __weak pgtable_cache_init(void) { }
@@ -835,6 +831,7 @@
 	init_espfix_bsp();
 	/* Should be run after espfix64 is set up. */
 	pti_init();
+	mm_cache_init();
 }
 
 void __init __weak arch_call_rest_init(void)
@@ -915,7 +912,7 @@
 	sort_main_extable();
 	trap_init();
 	mm_init();
-
+	poking_init();
 	ftrace_init();
 
 	/* trace_printk can be enabled here */
@@ -1006,14 +1003,6 @@
 	 */
 	locking_selftest();
 
-	/*
-	 * This needs to be called before any devices perform DMA
-	 * operations that might use the SWIOTLB bounce buffers. It will
-	 * mark the bounce buffers as decrypted so that their usage will
-	 * not cause "plain-text" data to be decrypted when accessed.
-	 */
-	mem_encrypt_init();
-
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start && !initrd_below_start_ok &&
 	    page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
@@ -1030,6 +1019,9 @@
 		late_time_init();
 	sched_clock_init();
 	calibrate_delay();
+
+	arch_cpu_finalize_init();
+
 	pid_idr_init();
 	anon_vma_init();
 #ifdef CONFIG_X86
@@ -1055,9 +1047,6 @@
 	cgroup_init();
 	taskstats_init_early();
 	delayacct_init();
-
-	poking_init();
-	check_bugs();
 
 	acpi_subsystem_init();
 	arch_post_acpi_subsys_init();
diff --git a/kernel/io_uring/io-wq.c b/kernel/io_uring/io-wq.c
index 6031fb3..fe8594a 100644
--- a/kernel/io_uring/io-wq.c
+++ b/kernel/io_uring/io-wq.c
@@ -176,6 +176,16 @@
 		complete(&wq->worker_done);
 }
 
+bool io_wq_worker_stopped(void)
+{
+	struct io_worker *worker = current->pf_io_worker;
+
+	if (WARN_ON_ONCE(!io_wq_current_is_worker()))
+		return true;
+
+	return test_bit(IO_WQ_BIT_EXIT, &worker->wqe->wq->state);
+}
+
 static void io_worker_cancel_cb(struct io_worker *worker)
 {
 	struct io_wqe_acct *acct = io_wqe_get_acct(worker);
@@ -513,7 +523,7 @@
 
 static bool io_flush_signals(void)
 {
-	if (unlikely(test_thread_flag(TIF_NOTIFY_SIGNAL))) {
+	if (test_thread_flag(TIF_NOTIFY_SIGNAL) || current->task_works) {
 		__set_current_state(TASK_RUNNING);
 		tracehook_notify_signal();
 		return true;
@@ -1217,6 +1227,12 @@
 
 		worker = container_of(cb, struct io_worker, create_work);
 		io_worker_cancel_cb(worker);
+		/*
+		 * Only the worker continuation helper has worker allocated and
+		 * hence needs freeing.
+		 */
+		if (cb->func == create_worker_cont)
+			kfree(worker);
 	}
 }
 
diff --git a/kernel/io_uring/io-wq.h b/kernel/io_uring/io-wq.h
index 300a695..a5e9619 100644
--- a/kernel/io_uring/io-wq.h
+++ b/kernel/io_uring/io-wq.h
@@ -140,6 +140,7 @@
 
 int io_wq_cpu_affinity(struct io_wq *wq, cpumask_var_t mask);
 int io_wq_max_workers(struct io_wq *wq, int *new_count);
+bool io_wq_worker_stopped(void);
 
 static inline bool io_wq_is_hashed(struct io_wq_work *work)
 {
diff --git a/kernel/io_uring/io_uring.c b/kernel/io_uring/io_uring.c
index 35a9bcd..a966de4 100644
--- a/kernel/io_uring/io_uring.c
+++ b/kernel/io_uring/io_uring.c
@@ -496,6 +496,7 @@
 	struct file			*file;
 	struct wait_queue_head		*head;
 	__poll_t			events;
+	int				retries;
 	struct wait_queue_entry		wait;
 };
 
@@ -588,7 +589,9 @@
 	int				msg_flags;
 	int				bgid;
 	size_t				len;
+	size_t				done_io;
 	struct io_buffer		*kbuf;
+	void __user			*msg_control;
 };
 
 struct io_open {
@@ -749,6 +752,7 @@
 	REQ_F_CREDS_BIT,
 	REQ_F_REFCOUNT_BIT,
 	REQ_F_ARM_LTIMEOUT_BIT,
+	REQ_F_PARTIAL_IO_BIT,
 	/* keep async read/write and isreg together and in order */
 	REQ_F_NOWAIT_READ_BIT,
 	REQ_F_NOWAIT_WRITE_BIT,
@@ -804,6 +808,8 @@
 	REQ_F_REFCOUNT		= BIT(REQ_F_REFCOUNT_BIT),
 	/* there is a linked timeout that has to be armed */
 	REQ_F_ARM_LTIMEOUT	= BIT(REQ_F_ARM_LTIMEOUT_BIT),
+	/* request has already done partial IO */
+	REQ_F_PARTIAL_IO	= BIT(REQ_F_PARTIAL_IO_BIT),
 };
 
 struct async_poll {
@@ -1098,7 +1104,8 @@
 				     unsigned nr_args);
 static void io_clean_op(struct io_kiocb *req);
 static struct file *io_file_get(struct io_ring_ctx *ctx,
-				struct io_kiocb *req, int fd, bool fixed);
+				struct io_kiocb *req, int fd, bool fixed,
+				unsigned int issue_flags);
 static void __io_queue_sqe(struct io_kiocb *req);
 static void io_rsrc_put_work(struct work_struct *work);
 
@@ -1524,6 +1531,8 @@
 
 static void io_queue_deferred(struct io_ring_ctx *ctx)
 {
+	lockdep_assert_held(&ctx->completion_lock);
+
 	while (!list_empty(&ctx->defer_list)) {
 		struct io_defer_entry *de = list_first_entry(&ctx->defer_list,
 						struct io_defer_entry, list);
@@ -1575,12 +1584,22 @@
 		io_queue_deferred(ctx);
 }
 
-static inline void io_commit_cqring(struct io_ring_ctx *ctx)
+static inline bool io_commit_needs_flush(struct io_ring_ctx *ctx)
 {
-	if (unlikely(ctx->off_timeout_used || ctx->drain_active))
-		__io_commit_cqring_flush(ctx);
+	return ctx->off_timeout_used || ctx->drain_active;
+}
+
+static inline void __io_commit_cqring(struct io_ring_ctx *ctx)
+{
 	/* order cqe stores with ring update */
 	smp_store_release(&ctx->rings->cq.tail, ctx->cached_cq_tail);
+}
+
+static inline void io_commit_cqring(struct io_ring_ctx *ctx)
+{
+	if (unlikely(io_commit_needs_flush(ctx)))
+		__io_commit_cqring_flush(ctx);
+	__io_commit_cqring(ctx);
 }
 
 static inline bool io_sqring_full(struct io_ring_ctx *ctx)
@@ -2205,9 +2224,12 @@
 			}
 			req->io_task_work.func(req, &locked);
 			node = next;
+			if (unlikely(need_resched())) {
+				ctx_flush_and_put(ctx, &locked);
+				ctx = NULL;
+				cond_resched();
+			}
 		} while (node);
-
-		cond_resched();
 	}
 
 	ctx_flush_and_put(ctx, &locked);
@@ -2465,6 +2487,15 @@
 
 static inline bool io_run_task_work(void)
 {
+	/*
+	 * PF_IO_WORKER never returns to userspace, so check here if we have
+	 * notify work that needs processing.
+	 */
+	if (current->flags & PF_IO_WORKER &&
+	    test_thread_flag(TIF_NOTIFY_RESUME)) {
+		__set_current_state(TASK_RUNNING);
+		tracehook_notify_resume(NULL);
+	}
 	if (test_thread_flag(TIF_NOTIFY_SIGNAL) || current->task_works) {
 		__set_current_state(TASK_RUNNING);
 		tracehook_notify_signal();
@@ -2488,17 +2519,36 @@
 
 	io_init_req_batch(&rb);
 	while (!list_empty(done)) {
+		struct io_uring_cqe *cqe;
+		unsigned cflags;
+
 		req = list_first_entry(done, struct io_kiocb, inflight_entry);
 		list_del(&req->inflight_entry);
-
-		io_fill_cqe_req(req, req->result, io_put_rw_kbuf(req));
+		cflags = io_put_rw_kbuf(req);
 		(*nr_events)++;
+
+		cqe = io_get_cqe(ctx);
+		if (cqe) {
+			WRITE_ONCE(cqe->user_data, req->user_data);
+			WRITE_ONCE(cqe->res, req->result);
+			WRITE_ONCE(cqe->flags, cflags);
+		} else {
+			spin_lock(&ctx->completion_lock);
+			io_cqring_event_overflow(ctx, req->user_data,
+							req->result, cflags);
+			spin_unlock(&ctx->completion_lock);
+		}
 
 		if (req_ref_put_and_test(req))
 			io_req_free_batch(&rb, req, &ctx->submit_state);
 	}
 
-	io_commit_cqring(ctx);
+	if (io_commit_needs_flush(ctx)) {
+		spin_lock(&ctx->completion_lock);
+		__io_commit_cqring_flush(ctx);
+		spin_unlock(&ctx->completion_lock);
+	}
+	__io_commit_cqring(ctx);
 	io_cqring_ev_posted_iopoll(ctx);
 	io_req_free_batch_finish(ctx, &rb);
 }
@@ -2625,6 +2675,11 @@
 				break;
 		}
 		ret = io_do_iopoll(ctx, &nr_events, min);
+
+		if (task_sigpending(current)) {
+			ret = -EINTR;
+			goto out;
+		}
 	} while (!ret && nr_events < min && !need_resched());
 out:
 	mutex_unlock(&ctx->uring_lock);
@@ -2692,17 +2747,32 @@
 }
 #endif
 
-static bool __io_complete_rw_common(struct io_kiocb *req, long res)
+/*
+ * Trigger the notifications after having done some IO, and finish the write
+ * accounting, if any.
+ */
+static void io_req_io_end(struct io_kiocb *req)
 {
-	if (req->rw.kiocb.ki_flags & IOCB_WRITE) {
+	struct io_rw *rw = &req->rw;
+
+	if (rw->kiocb.ki_flags & IOCB_WRITE) {
 		kiocb_end_write(req);
 		fsnotify_modify(req->file);
 	} else {
 		fsnotify_access(req->file);
 	}
+}
+
+static bool __io_complete_rw_common(struct io_kiocb *req, long res)
+{
 	if (res != req->result) {
 		if ((res == -EAGAIN || res == -EOPNOTSUPP) &&
 		    io_rw_should_reissue(req)) {
+			/*
+			 * Reissue will start accounting again, finish the
+			 * current cycle.
+			 */
+			io_req_io_end(req);
 			req->flags |= REQ_F_REISSUE;
 			return true;
 		}
@@ -2712,7 +2782,7 @@
 	return false;
 }
 
-static inline int io_fixup_rw_res(struct io_kiocb *req, unsigned res)
+static inline int io_fixup_rw_res(struct io_kiocb *req, long res)
 {
 	struct io_async_rw *io = req->async_data;
 
@@ -2744,12 +2814,10 @@
 	}
 }
 
-static void __io_complete_rw(struct io_kiocb *req, long res, long res2,
-			     unsigned int issue_flags)
+static void io_req_rw_complete(struct io_kiocb *req, bool *locked)
 {
-	if (__io_complete_rw_common(req, res))
-		return;
-	__io_req_complete(req, issue_flags, io_fixup_rw_res(req, res), io_put_rw_kbuf(req));
+	io_req_io_end(req);
+	io_req_task_complete(req, locked);
 }
 
 static void io_complete_rw(struct kiocb *kiocb, long res, long res2)
@@ -2759,7 +2827,7 @@
 	if (__io_complete_rw_common(req, res))
 		return;
 	req->result = io_fixup_rw_res(req, res);
-	req->io_task_work.func = io_req_task_complete;
+	req->io_task_work.func = io_req_rw_complete;
 	io_req_task_work_add(req);
 }
 
@@ -2911,14 +2979,6 @@
 		req->flags |= REQ_F_ISREG;
 
 	kiocb->ki_pos = READ_ONCE(sqe->off);
-	if (kiocb->ki_pos == -1) {
-		if (!(file->f_mode & FMODE_STREAM)) {
-			req->flags |= REQ_F_CUR_POS;
-			kiocb->ki_pos = file->f_pos;
-		} else {
-			kiocb->ki_pos = 0;
-		}
-	}
 	kiocb->ki_hint = ki_hint_validate(file_write_hint(kiocb->ki_filp));
 	kiocb->ki_flags = iocb_flags(kiocb->ki_filp);
 	ret = kiocb_set_rw_flags(kiocb, READ_ONCE(sqe->rw_flags));
@@ -3000,6 +3060,23 @@
 	}
 }
 
+static inline loff_t *io_kiocb_update_pos(struct io_kiocb *req)
+{
+	struct kiocb *kiocb = &req->rw.kiocb;
+
+	if (kiocb->ki_pos != -1)
+		return &kiocb->ki_pos;
+
+	if (!(req->file->f_mode & FMODE_STREAM)) {
+		req->flags |= REQ_F_CUR_POS;
+		kiocb->ki_pos = req->file->f_pos;
+		return &kiocb->ki_pos;
+	}
+
+	kiocb->ki_pos = 0;
+	return NULL;
+}
+
 static void kiocb_done(struct kiocb *kiocb, ssize_t ret,
 		       unsigned int issue_flags)
 {
@@ -3007,10 +3084,20 @@
 
 	if (req->flags & REQ_F_CUR_POS)
 		req->file->f_pos = kiocb->ki_pos;
-	if (ret >= 0 && (kiocb->ki_complete == io_complete_rw))
-		__io_complete_rw(req, ret, 0, issue_flags);
-	else
+	if (ret >= 0 && (kiocb->ki_complete == io_complete_rw)) {
+		if (!__io_complete_rw_common(req, ret)) {
+			/*
+			 * Safe to call io_end from here as we're inline
+			 * from the submission path.
+			 */
+			io_req_io_end(req);
+			__io_req_complete(req, issue_flags,
+					  io_fixup_rw_res(req, ret),
+					  io_put_rw_kbuf(req));
+		}
+	} else {
 		io_rw_done(kiocb, ret);
+	}
 
 	if (req->flags & REQ_F_REISSUE) {
 		req->flags &= ~REQ_F_REISSUE;
@@ -3292,6 +3379,7 @@
 	struct kiocb *kiocb = &req->rw.kiocb;
 	struct file *file = req->file;
 	ssize_t ret = 0;
+	loff_t *ppos;
 
 	/*
 	 * Don't support polled IO through this interface, and we can't
@@ -3302,6 +3390,8 @@
 		return -EOPNOTSUPP;
 	if (kiocb->ki_flags & IOCB_NOWAIT)
 		return -EAGAIN;
+
+	ppos = io_kiocb_ppos(kiocb);
 
 	while (iov_iter_count(iter)) {
 		struct iovec iovec;
@@ -3316,10 +3406,10 @@
 
 		if (rw == READ) {
 			nr = file->f_op->read(file, iovec.iov_base,
-					      iovec.iov_len, io_kiocb_ppos(kiocb));
+					      iovec.iov_len, ppos);
 		} else {
 			nr = file->f_op->write(file, iovec.iov_base,
-					       iovec.iov_len, io_kiocb_ppos(kiocb));
+					       iovec.iov_len, ppos);
 		}
 
 		if (nr < 0) {
@@ -3520,6 +3610,7 @@
 	bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
 	struct iov_iter_state __state, *state;
 	ssize_t ret, ret2;
+	loff_t *ppos;
 
 	if (rw) {
 		iter = &rw->iter;
@@ -3552,7 +3643,9 @@
 		return ret ?: -EAGAIN;
 	}
 
-	ret = rw_verify_area(READ, req->file, io_kiocb_ppos(kiocb), req->result);
+	ppos = io_kiocb_update_pos(req);
+
+	ret = rw_verify_area(READ, req->file, ppos, req->result);
 	if (unlikely(ret)) {
 		kfree(iovec);
 		return ret;
@@ -3656,6 +3749,7 @@
 	bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
 	struct iov_iter_state __state, *state;
 	ssize_t ret, ret2;
+	loff_t *ppos;
 
 	if (rw) {
 		iter = &rw->iter;
@@ -3686,7 +3780,9 @@
 	    (req->flags & REQ_F_ISREG))
 		goto copy_iov;
 
-	ret = rw_verify_area(WRITE, req->file, io_kiocb_ppos(kiocb), req->result);
+	ppos = io_kiocb_update_pos(req);
+
+	ret = rw_verify_area(WRITE, req->file, ppos, req->result);
 	if (unlikely(ret))
 		goto out_free;
 
@@ -3926,7 +4022,7 @@
 		return -EAGAIN;
 
 	in = io_file_get(req->ctx, req, sp->splice_fd_in,
-				  (sp->flags & SPLICE_F_FD_IN_FIXED));
+			 (sp->flags & SPLICE_F_FD_IN_FIXED), issue_flags);
 	if (!in) {
 		ret = -EBADF;
 		goto done;
@@ -3966,7 +4062,7 @@
 		return -EAGAIN;
 
 	in = io_file_get(req->ctx, req, sp->splice_fd_in,
-				  (sp->flags & SPLICE_F_FD_IN_FIXED));
+			 (sp->flags & SPLICE_F_FD_IN_FIXED), issue_flags);
 	if (!in) {
 		ret = -EBADF;
 		goto done;
@@ -4148,9 +4244,11 @@
 	if (issue_flags & IO_URING_F_NONBLOCK) {
 		/*
 		 * Don't bother trying for O_TRUNC, O_CREAT, or O_TMPFILE open,
-		 * it'll always -EAGAIN
+		 * it'll always -EAGAIN. Note that we test for __O_TMPFILE
+		 * because O_TMPFILE includes O_DIRECTORY, which isn't a flag
+		 * we need to force async for.
 		 */
-		if (req->open.how.flags & (O_TRUNC | O_CREAT | O_TMPFILE))
+		if (req->open.how.flags & (O_TRUNC | O_CREAT | __O_TMPFILE))
 			return -EAGAIN;
 		op.lookup_flags |= LOOKUP_CACHED;
 		op.open_flag |= O_NONBLOCK;
@@ -4623,6 +4721,13 @@
 }
 
 #if defined(CONFIG_NET)
+static bool io_net_retry(struct socket *sock, int flags)
+{
+	if (!(flags & MSG_WAITALL))
+		return false;
+	return sock->type == SOCK_STREAM || sock->type == SOCK_SEQPACKET;
+}
+
 static int io_setup_async_msg(struct io_kiocb *req,
 			      struct io_async_msghdr *kmsg)
 {
@@ -4640,8 +4745,10 @@
 	if (async_msg->msg.msg_name)
 		async_msg->msg.msg_name = &async_msg->addr;
 	/* if were using fast_iov, set it to the new one */
-	if (!async_msg->free_iov)
-		async_msg->msg.msg_iter.iov = async_msg->fast_iov;
+	if (!kmsg->free_iov) {
+		size_t fast_idx = kmsg->msg.msg_iter.iov - kmsg->fast_iov;
+		async_msg->msg.msg_iter.iov = &async_msg->fast_iov[fast_idx];
+	}
 
 	return -EAGAIN;
 }
@@ -4649,10 +4756,16 @@
 static int io_sendmsg_copy_hdr(struct io_kiocb *req,
 			       struct io_async_msghdr *iomsg)
 {
+	struct io_sr_msg *sr = &req->sr_msg;
+	int ret;
+
 	iomsg->msg.msg_name = &iomsg->addr;
 	iomsg->free_iov = iomsg->fast_iov;
-	return sendmsg_copy_msghdr(&iomsg->msg, req->sr_msg.umsg,
+	ret = sendmsg_copy_msghdr(&iomsg->msg, req->sr_msg.umsg,
 				   req->sr_msg.msg_flags, &iomsg->free_iov);
+	/* save msg_control as sys_sendmsg() overwrites it */
+	sr->msg_control = iomsg->msg.msg_control;
+	return ret;
 }
 
 static int io_sendmsg_prep_async(struct io_kiocb *req)
@@ -4686,12 +4799,14 @@
 	if (req->ctx->compat)
 		sr->msg_flags |= MSG_CMSG_COMPAT;
 #endif
+	sr->done_io = 0;
 	return 0;
 }
 
 static int io_sendmsg(struct io_kiocb *req, unsigned int issue_flags)
 {
 	struct io_async_msghdr iomsg, *kmsg;
+	struct io_sr_msg *sr = &req->sr_msg;
 	struct socket *sock;
 	unsigned flags;
 	int min_ret = 0;
@@ -4707,6 +4822,8 @@
 		if (ret)
 			return ret;
 		kmsg = &iomsg;
+	} else {
+		kmsg->msg.msg_control = sr->msg_control;
 	}
 
 	flags = req->sr_msg.msg_flags;
@@ -4716,17 +4833,27 @@
 		min_ret = iov_iter_count(&kmsg->msg.msg_iter);
 
 	ret = __sys_sendmsg_sock(sock, &kmsg->msg, flags);
-	if ((issue_flags & IO_URING_F_NONBLOCK) && ret == -EAGAIN)
-		return io_setup_async_msg(req, kmsg);
-	if (ret == -ERESTARTSYS)
-		ret = -EINTR;
 
+	if (ret < min_ret) {
+		if (ret == -EAGAIN && (issue_flags & IO_URING_F_NONBLOCK))
+			return io_setup_async_msg(req, kmsg);
+		if (ret == -ERESTARTSYS)
+			ret = -EINTR;
+		if (ret > 0 && io_net_retry(sock, flags)) {
+			sr->done_io += ret;
+			req->flags |= REQ_F_PARTIAL_IO;
+			return io_setup_async_msg(req, kmsg);
+		}
+		req_set_fail(req);
+	}
 	/* fast path, check for non-NULL to avoid function call */
 	if (kmsg->free_iov)
 		kfree(kmsg->free_iov);
 	req->flags &= ~REQ_F_NEED_CLEANUP;
-	if (ret < min_ret)
-		req_set_fail(req);
+	if (ret >= 0)
+		ret += sr->done_io;
+	else if (sr->done_io)
+		ret = sr->done_io;
 	__io_req_complete(req, issue_flags, ret, 0);
 	return 0;
 }
@@ -4762,13 +4889,24 @@
 
 	msg.msg_flags = flags;
 	ret = sock_sendmsg(sock, &msg);
-	if ((issue_flags & IO_URING_F_NONBLOCK) && ret == -EAGAIN)
-		return -EAGAIN;
-	if (ret == -ERESTARTSYS)
-		ret = -EINTR;
-
-	if (ret < min_ret)
+	if (ret < min_ret) {
+		if (ret == -EAGAIN && (issue_flags & IO_URING_F_NONBLOCK))
+			return -EAGAIN;
+		if (ret == -ERESTARTSYS)
+			ret = -EINTR;
+		if (ret > 0 && io_net_retry(sock, flags)) {
+			sr->len -= ret;
+			sr->buf += ret;
+			sr->done_io += ret;
+			req->flags |= REQ_F_PARTIAL_IO;
+			return -EAGAIN;
+		}
 		req_set_fail(req);
+	}
+	if (ret >= 0)
+		ret += sr->done_io;
+	else if (sr->done_io)
+		ret = sr->done_io;
 	__io_req_complete(req, issue_flags, ret, 0);
 	return 0;
 }
@@ -4904,7 +5042,7 @@
 	sr->umsg = u64_to_user_ptr(READ_ONCE(sqe->addr));
 	sr->len = READ_ONCE(sqe->len);
 	sr->bgid = READ_ONCE(sqe->buf_group);
-	sr->msg_flags = READ_ONCE(sqe->msg_flags) | MSG_NOSIGNAL;
+	sr->msg_flags = READ_ONCE(sqe->msg_flags);
 	if (sr->msg_flags & MSG_DONTWAIT)
 		req->flags |= REQ_F_NOWAIT;
 
@@ -4912,12 +5050,14 @@
 	if (req->ctx->compat)
 		sr->msg_flags |= MSG_CMSG_COMPAT;
 #endif
+	sr->done_io = 0;
 	return 0;
 }
 
 static int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags)
 {
 	struct io_async_msghdr iomsg, *kmsg;
+	struct io_sr_msg *sr = &req->sr_msg;
 	struct socket *sock;
 	struct io_buffer *kbuf;
 	unsigned flags;
@@ -4950,15 +5090,27 @@
 	flags = req->sr_msg.msg_flags;
 	if (force_nonblock)
 		flags |= MSG_DONTWAIT;
-	if (flags & MSG_WAITALL)
+	if (flags & MSG_WAITALL && !kmsg->msg.msg_controllen)
 		min_ret = iov_iter_count(&kmsg->msg.msg_iter);
 
 	ret = __sys_recvmsg_sock(sock, &kmsg->msg, req->sr_msg.umsg,
 					kmsg->uaddr, flags);
-	if (force_nonblock && ret == -EAGAIN)
-		return io_setup_async_msg(req, kmsg);
-	if (ret == -ERESTARTSYS)
-		ret = -EINTR;
+	if (ret < min_ret) {
+		if (ret == -EAGAIN && force_nonblock)
+			return io_setup_async_msg(req, kmsg);
+		if (ret == -ERESTARTSYS)
+			ret = -EINTR;
+		if (ret > 0 && io_net_retry(sock, flags)) {
+			kmsg->msg.msg_controllen = 0;
+			kmsg->msg.msg_control = NULL;
+			sr->done_io += ret;
+			req->flags |= REQ_F_PARTIAL_IO;
+			return io_setup_async_msg(req, kmsg);
+		}
+		req_set_fail(req);
+	} else if ((flags & MSG_WAITALL) && (kmsg->msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC))) {
+		req_set_fail(req);
+	}
 
 	if (req->flags & REQ_F_BUFFER_SELECTED)
 		cflags = io_put_recv_kbuf(req);
@@ -4966,8 +5118,10 @@
 	if (kmsg->free_iov)
 		kfree(kmsg->free_iov);
 	req->flags &= ~REQ_F_NEED_CLEANUP;
-	if (ret < min_ret || ((flags & MSG_WAITALL) && (kmsg->msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC))))
-		req_set_fail(req);
+	if (ret >= 0)
+		ret += sr->done_io;
+	else if (sr->done_io)
+		ret = sr->done_io;
 	__io_req_complete(req, issue_flags, ret, cflags);
 	return 0;
 }
@@ -5014,15 +5168,29 @@
 		min_ret = iov_iter_count(&msg.msg_iter);
 
 	ret = sock_recvmsg(sock, &msg, flags);
-	if (force_nonblock && ret == -EAGAIN)
-		return -EAGAIN;
-	if (ret == -ERESTARTSYS)
-		ret = -EINTR;
+	if (ret < min_ret) {
+		if (ret == -EAGAIN && force_nonblock)
+			return -EAGAIN;
+		if (ret == -ERESTARTSYS)
+			ret = -EINTR;
+		if (ret > 0 && io_net_retry(sock, flags)) {
+			sr->len -= ret;
+			sr->buf += ret;
+			sr->done_io += ret;
+			req->flags |= REQ_F_PARTIAL_IO;
+			return -EAGAIN;
+		}
+		req_set_fail(req);
+	} else if ((flags & MSG_WAITALL) && (msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC))) {
 out_free:
+		req_set_fail(req);
+	}
 	if (req->flags & REQ_F_BUFFER_SELECTED)
 		cflags = io_put_recv_kbuf(req);
-	if (ret < min_ret || ((flags & MSG_WAITALL) && (msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC))))
-		req_set_fail(req);
+	if (ret >= 0)
+		ret += sr->done_io;
+	else if (sr->done_io)
+		ret = sr->done_io;
 	__io_req_complete(req, issue_flags, ret, cflags);
 	return 0;
 }
@@ -5060,9 +5228,6 @@
 	struct file *file;
 	int ret, fd;
 
-	if (req->file->f_flags & O_NONBLOCK)
-		req->flags |= REQ_F_NOWAIT;
-
 	if (!fixed) {
 		fd = __get_unused_fd_flags(accept->flags, accept->nofile);
 		if (unlikely(fd < 0))
@@ -5075,6 +5240,8 @@
 		if (!fixed)
 			put_unused_fd(fd);
 		ret = PTR_ERR(file);
+		/* safe to retry */
+		req->flags |= REQ_F_PARTIAL_IO;
 		if (ret == -EAGAIN && force_nonblock)
 			return -EAGAIN;
 		if (ret == -ERESTARTSYS)
@@ -5419,6 +5586,7 @@
 	if (ret > 0)
 		return;
 
+	io_tw_lock(req->ctx, locked);
 	io_poll_remove_entries(req);
 	spin_lock(&ctx->completion_lock);
 	hash_del(&req->hash_node);
@@ -5631,6 +5799,14 @@
 	IO_APOLL_READY
 };
 
+/*
+ * We can't reliably detect loops in repeated poll triggers and issue
+ * subsequently failing. But rather than fail these immediately, allow a
+ * certain amount of retries before we give up. Given that this condition
+ * should _rarely_ trigger even once, we should be fine with a larger value.
+ */
+#define APOLL_MAX_RETRY		128
+
 static int io_arm_poll_handler(struct io_kiocb *req)
 {
 	const struct io_op_def *def = &io_op_defs[req->opcode];
@@ -5641,8 +5817,6 @@
 	int ret;
 
 	if (!req->file || !file_can_poll(req->file))
-		return IO_APOLL_ABORTED;
-	if (req->flags & REQ_F_POLLED)
 		return IO_APOLL_ABORTED;
 	if (!def->pollin && !def->pollout)
 		return IO_APOLL_ABORTED;
@@ -5658,9 +5832,19 @@
 		mask |= POLLOUT | POLLWRNORM;
 	}
 
-	apoll = kmalloc(sizeof(*apoll), GFP_ATOMIC);
-	if (unlikely(!apoll))
-		return IO_APOLL_ABORTED;
+	if (req->flags & REQ_F_POLLED) {
+		apoll = req->apoll;
+		kfree(apoll->double_poll);
+		if (unlikely(!--apoll->poll.retries)) {
+			apoll->double_poll = NULL;
+			return IO_APOLL_ABORTED;
+		}
+	} else {
+		apoll = kmalloc(sizeof(*apoll), GFP_ATOMIC);
+		if (unlikely(!apoll))
+			return IO_APOLL_ABORTED;
+		apoll->poll.retries = APOLL_MAX_RETRY;
+	}
 	apoll->double_poll = NULL;
 	req->apoll = apoll;
 	req->flags |= REQ_F_POLLED;
@@ -5831,6 +6015,8 @@
 	struct io_kiocb *preq;
 	int ret2, ret = 0;
 
+	io_ring_submit_lock(ctx, !(issue_flags & IO_URING_F_NONBLOCK));
+
 	spin_lock(&ctx->completion_lock);
 	preq = io_poll_find(ctx, req->poll_update.old_user_data, true);
 	if (!preq || !io_poll_disarm(preq)) {
@@ -5862,6 +6048,7 @@
 		req_set_fail(req);
 	/* complete update request, we're done with it */
 	io_req_complete(req, ret);
+	io_ring_submit_unlock(ctx, !(issue_flags & IO_URING_F_NONBLOCK));
 	return 0;
 }
 
@@ -6726,6 +6913,15 @@
 			 */
 			if (ret != -EAGAIN || !(req->ctx->flags & IORING_SETUP_IOPOLL))
 				break;
+			if (io_wq_worker_stopped())
+				break;
+			/*
+			 * If REQ_F_NOWAIT is set, then don't wait or retry with
+			 * poll. -EAGAIN is final for that case.
+			 */
+			if (req->flags & REQ_F_NOWAIT)
+				break;
+
 			cond_resched();
 		} while (1);
 	}
@@ -6763,13 +6959,16 @@
 }
 
 static inline struct file *io_file_get_fixed(struct io_ring_ctx *ctx,
-					     struct io_kiocb *req, int fd)
+					     struct io_kiocb *req, int fd,
+					     unsigned int issue_flags)
 {
-	struct file *file;
+	struct file *file = NULL;
 	unsigned long file_ptr;
 
+	io_ring_submit_lock(ctx, !(issue_flags & IO_URING_F_NONBLOCK));
+
 	if (unlikely((unsigned int)fd >= ctx->nr_user_files))
-		return NULL;
+		goto out;
 	fd = array_index_nospec(fd, ctx->nr_user_files);
 	file_ptr = io_fixed_file_slot(&ctx->file_table, fd)->file_ptr;
 	file = (struct file *) (file_ptr & FFS_MASK);
@@ -6777,6 +6976,8 @@
 	/* mask in overlapping REQ_F and FFS bits */
 	req->flags |= (file_ptr << REQ_F_NOWAIT_READ_BIT);
 	io_req_set_rsrc_node(req);
+out:
+	io_ring_submit_unlock(ctx, !(issue_flags & IO_URING_F_NONBLOCK));
 	return file;
 }
 
@@ -6794,10 +6995,11 @@
 }
 
 static inline struct file *io_file_get(struct io_ring_ctx *ctx,
-				       struct io_kiocb *req, int fd, bool fixed)
+				       struct io_kiocb *req, int fd, bool fixed,
+				       unsigned int issue_flags)
 {
 	if (fixed)
-		return io_file_get_fixed(ctx, req, fd);
+		return io_file_get_fixed(ctx, req, fd, issue_flags);
 	else
 		return io_file_get_normal(ctx, req, fd);
 }
@@ -7019,7 +7221,8 @@
 
 	if (io_op_defs[req->opcode].needs_file) {
 		req->file = io_file_get(ctx, req, READ_ONCE(sqe->fd),
-					(sqe_flags & IOSQE_FIXED_FILE));
+					(sqe_flags & IOSQE_FIXED_FILE),
+					IO_URING_F_NONBLOCK);
 		if (unlikely(!req->file))
 			ret = -EBADF;
 	}
@@ -7447,12 +7650,21 @@
 	return -EINTR;
 }
 
+static bool current_pending_io(void)
+{
+	struct io_uring_task *tctx = current->io_uring;
+
+	if (!tctx)
+		return false;
+	return percpu_counter_read_positive(&tctx->inflight);
+}
+
 /* when returns >0, the caller should retry */
 static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx,
 					  struct io_wait_queue *iowq,
-					  ktime_t timeout)
+					  ktime_t *timeout)
 {
-	int ret;
+	int io_wait, ret;
 
 	/* make sure we run task_work before checking for signals */
 	ret = io_run_task_work_sig();
@@ -7462,9 +7674,19 @@
 	if (test_bit(0, &ctx->check_cq_overflow))
 		return 1;
 
-	if (!schedule_hrtimeout(&timeout, HRTIMER_MODE_ABS))
-		return -ETIME;
-	return 1;
+	/*
+	 * Mark us as being in io_wait if we have pending requests, so cpufreq
+	 * can take into account that the task is waiting for IO - turns out
+	 * to be important for low QD IO.
+	 */
+	io_wait = current->in_iowait;
+	if (current_pending_io())
+		current->in_iowait = 1;
+	ret = 1;
+	if (!schedule_hrtimeout(timeout, HRTIMER_MODE_ABS))
+		ret = -ETIME;
+	current->in_iowait = io_wait;
+	return ret;
 }
 
 /*
@@ -7525,7 +7747,7 @@
 		}
 		prepare_to_wait_exclusive(&ctx->cq_wait, &iowq.wq,
 						TASK_INTERRUPTIBLE);
-		ret = io_cqring_wait_schedule(ctx, &iowq, timeout);
+		ret = io_cqring_wait_schedule(ctx, &iowq, &timeout);
 		finish_wait(&ctx->cq_wait, &iowq.wq);
 		cond_resched();
 	} while (ret > 0);
@@ -8927,14 +9149,17 @@
 	pret = pin_user_pages(ubuf, nr_pages, FOLL_WRITE | FOLL_LONGTERM,
 			      pages, vmas);
 	if (pret == nr_pages) {
+		struct file *file = vmas[0]->vm_file;
+
 		/* don't support file backed memory */
 		for (i = 0; i < nr_pages; i++) {
-			struct vm_area_struct *vma = vmas[i];
-
-			if (vma_is_shmem(vma))
+			if (vmas[i]->vm_file != file) {
+				ret = -EINVAL;
+				break;
+			}
+			if (!file)
 				continue;
-			if (vma->vm_file &&
-			    !is_file_hugepages(vma->vm_file)) {
+			if (!vma_is_shmem(vmas[i]) && !is_file_hugepages(file)) {
 				ret = -EOPNOTSUPP;
 				break;
 			}
@@ -9367,7 +9592,18 @@
 			/* there is little hope left, don't run it too often */
 			interval = HZ * 60;
 		}
-	} while (!wait_for_completion_timeout(&ctx->ref_comp, interval));
+		/*
+		 * This is really an uninterruptible wait, as it has to be
+		 * complete. But it's also run from a kworker, which doesn't
+		 * take signals, so it's fine to make it interruptible. This
+		 * avoids scenarios where we knowingly can wait much longer
+		 * on completions, for example if someone does a SIGSTOP on
+		 * a task that needs to finish task_work to make this loop
+		 * complete. That's a synthetic situation that should not
+		 * cause a stuck task backtrace, and hence a potential panic
+		 * on stuck tasks if that is enabled.
+		 */
+	} while (!wait_for_completion_interruptible_timeout(&ctx->ref_comp, interval));
 
 	init_completion(&exit.completion);
 	init_task_work(&exit.task_work, io_tctx_exit_cb);
@@ -9392,7 +9628,12 @@
 		wake_up_process(node->task);
 
 		mutex_unlock(&ctx->uring_lock);
-		wait_for_completion(&exit.completion);
+		/*
+		 * See comment above for
+		 * wait_for_completion_interruptible_timeout() on why this
+		 * wait is marked as interruptible.
+		 */
+		wait_for_completion_interruptible(&exit.completion);
 		mutex_lock(&ctx->uring_lock);
 	}
 	mutex_unlock(&ctx->uring_lock);
@@ -9444,6 +9685,10 @@
 
 	/* if we failed setting up the ctx, we might not have any rings */
 	io_iopoll_try_reap_events(ctx);
+
+	/* drop cached put refs after potentially doing completions */
+	if (current->io_uring)
+		io_uring_drop_tctx_refs(current);
 
 	INIT_WORK(&ctx->exit_work, io_ring_exit_work);
 	/*
@@ -9556,6 +9801,7 @@
 			while (!list_empty_careful(&ctx->iopoll_list)) {
 				io_iopoll_try_reap_events(ctx);
 				ret = true;
+				cond_resched();
 			}
 		}
 
@@ -10223,7 +10469,7 @@
 	if (!ctx)
 		return -ENOMEM;
 	ctx->compat = in_compat_syscall();
-	if (!capable(CAP_IPC_LOCK))
+	if (!ns_capable_noaudit(&init_user_ns, CAP_IPC_LOCK))
 		ctx->user = get_uid(current_user());
 
 	/*
@@ -10751,8 +10997,6 @@
 		return -ENXIO;
 
 	if (ctx->restricted) {
-		if (opcode >= IORING_REGISTER_LAST)
-			return -EINVAL;
 		opcode = array_index_nospec(opcode, IORING_REGISTER_LAST);
 		if (!test_bit(opcode, ctx->restrictions.register_op))
 			return -EACCES;
@@ -10884,6 +11128,9 @@
 	long ret = -EBADF;
 	struct fd f;
 
+	if (opcode >= IORING_REGISTER_LAST)
+		return -EINVAL;
+
 	f = fdget(fd);
 	if (!f.file)
 		return -EBADF;
diff --git a/kernel/kernel/Makefile b/kernel/kernel/Makefile
index 6ee614d..dfa6fde 100644
--- a/kernel/kernel/Makefile
+++ b/kernel/kernel/Makefile
@@ -56,7 +56,7 @@
 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/kernel/acct.c b/kernel/kernel/acct.c
index f175df8..12f7dac 100644
--- a/kernel/kernel/acct.c
+++ b/kernel/kernel/acct.c
@@ -331,6 +331,8 @@
 		exp++;
 	}
 
+	if (exp > (((comp_t) ~0U) >> MANTSIZE))
+		return (comp_t) ~0U;
 	/*
 	 * Clean it up and polish it off.
 	 */
diff --git a/kernel/kernel/auditsc.c b/kernel/kernel/auditsc.c
index 07e2788..57b982b 100644
--- a/kernel/kernel/auditsc.c
+++ b/kernel/kernel/auditsc.c
@@ -2203,6 +2203,8 @@
 		}
 	}
 
+	cond_resched();
+
 	/* is there a matching child entry? */
 	list_for_each_entry(n, &context->names_list, list) {
 		/* can only match entries that have a name */
diff --git a/kernel/kernel/bpf/bpf_local_storage.c b/kernel/kernel/bpf/bpf_local_storage.c
index 8aaaaef..f753965 100644
--- a/kernel/kernel/bpf/bpf_local_storage.c
+++ b/kernel/kernel/bpf/bpf_local_storage.c
@@ -48,9 +48,19 @@
 	return map->ops->map_owner_storage_ptr(owner);
 }
 
+static bool selem_linked_to_storage_lockless(const struct bpf_local_storage_elem *selem)
+{
+	return !hlist_unhashed_lockless(&selem->snode);
+}
+
 static bool selem_linked_to_storage(const struct bpf_local_storage_elem *selem)
 {
 	return !hlist_unhashed(&selem->snode);
+}
+
+static bool selem_linked_to_map_lockless(const struct bpf_local_storage_elem *selem)
+{
+	return !hlist_unhashed_lockless(&selem->map_node);
 }
 
 static bool selem_linked_to_map(const struct bpf_local_storage_elem *selem)
@@ -140,7 +150,7 @@
 	struct bpf_local_storage *local_storage;
 	bool free_local_storage = false;
 
-	if (unlikely(!selem_linked_to_storage(selem)))
+	if (unlikely(!selem_linked_to_storage_lockless(selem)))
 		/* selem has already been unlinked from sk */
 		return;
 
@@ -167,7 +177,7 @@
 	struct bpf_local_storage_map *smap;
 	struct bpf_local_storage_map_bucket *b;
 
-	if (unlikely(!selem_linked_to_map(selem)))
+	if (unlikely(!selem_linked_to_map_lockless(selem)))
 		/* selem has already be unlinked from smap */
 		return;
 
@@ -365,7 +375,7 @@
 		err = check_flags(old_sdata, map_flags);
 		if (err)
 			return ERR_PTR(err);
-		if (old_sdata && selem_linked_to_storage(SELEM(old_sdata))) {
+		if (old_sdata && selem_linked_to_storage_lockless(SELEM(old_sdata))) {
 			copy_map_value_locked(&smap->map, old_sdata->data,
 					      value, false);
 			return old_sdata;
diff --git a/kernel/kernel/bpf/bpf_lru_list.c b/kernel/kernel/bpf/bpf_lru_list.c
index d99e89f..3dabdd1 100644
--- a/kernel/kernel/bpf/bpf_lru_list.c
+++ b/kernel/kernel/bpf/bpf_lru_list.c
@@ -41,7 +41,12 @@
 /* bpf_lru_node helpers */
 static bool bpf_lru_node_is_ref(const struct bpf_lru_node *node)
 {
-	return node->ref;
+	return READ_ONCE(node->ref);
+}
+
+static void bpf_lru_node_clear_ref(struct bpf_lru_node *node)
+{
+	WRITE_ONCE(node->ref, 0);
 }
 
 static void bpf_lru_list_count_inc(struct bpf_lru_list *l,
@@ -89,7 +94,7 @@
 
 	bpf_lru_list_count_inc(l, tgt_type);
 	node->type = tgt_type;
-	node->ref = 0;
+	bpf_lru_node_clear_ref(node);
 	list_move(&node->list, &l->lists[tgt_type]);
 }
 
@@ -110,7 +115,7 @@
 		bpf_lru_list_count_inc(l, tgt_type);
 		node->type = tgt_type;
 	}
-	node->ref = 0;
+	bpf_lru_node_clear_ref(node);
 
 	/* If the moving node is the next_inactive_rotation candidate,
 	 * move the next_inactive_rotation pointer also.
@@ -353,7 +358,7 @@
 	*(u32 *)((void *)node + lru->hash_offset) = hash;
 	node->cpu = cpu;
 	node->type = BPF_LRU_LOCAL_LIST_T_PENDING;
-	node->ref = 0;
+	bpf_lru_node_clear_ref(node);
 	list_add(&node->list, local_pending_list(loc_l));
 }
 
@@ -419,7 +424,7 @@
 	if (!list_empty(free_list)) {
 		node = list_first_entry(free_list, struct bpf_lru_node, list);
 		*(u32 *)((void *)node + lru->hash_offset) = hash;
-		node->ref = 0;
+		bpf_lru_node_clear_ref(node);
 		__bpf_lru_node_move(l, node, BPF_LRU_LIST_T_INACTIVE);
 	}
 
@@ -522,7 +527,7 @@
 		}
 
 		node->type = BPF_LRU_LOCAL_LIST_T_FREE;
-		node->ref = 0;
+		bpf_lru_node_clear_ref(node);
 		list_move(&node->list, local_free_list(loc_l));
 
 		raw_spin_unlock_irqrestore(&loc_l->lock, flags);
@@ -568,7 +573,7 @@
 
 		node = (struct bpf_lru_node *)(buf + node_offset);
 		node->type = BPF_LRU_LIST_T_FREE;
-		node->ref = 0;
+		bpf_lru_node_clear_ref(node);
 		list_add(&node->list, &l->lists[BPF_LRU_LIST_T_FREE]);
 		buf += elem_size;
 	}
@@ -594,7 +599,7 @@
 		node = (struct bpf_lru_node *)(buf + node_offset);
 		node->cpu = cpu;
 		node->type = BPF_LRU_LIST_T_FREE;
-		node->ref = 0;
+		bpf_lru_node_clear_ref(node);
 		list_add(&node->list, &l->lists[BPF_LRU_LIST_T_FREE]);
 		i++;
 		buf += elem_size;
diff --git a/kernel/kernel/bpf/bpf_lru_list.h b/kernel/kernel/bpf/bpf_lru_list.h
index 4ea227c..8f3c8b2 100644
--- a/kernel/kernel/bpf/bpf_lru_list.h
+++ b/kernel/kernel/bpf/bpf_lru_list.h
@@ -64,11 +64,8 @@
 
 static inline void bpf_lru_node_set_ref(struct bpf_lru_node *node)
 {
-	/* ref is an approximation on access frequency.  It does not
-	 * have to be very accurate.  Hence, no protection is used.
-	 */
-	if (!node->ref)
-		node->ref = 1;
+	if (!READ_ONCE(node->ref))
+		WRITE_ONCE(node->ref, 1);
 }
 
 int bpf_lru_init(struct bpf_lru *lru, bool percpu, u32 hash_offset,
diff --git a/kernel/kernel/bpf/btf.c b/kernel/kernel/bpf/btf.c
index 9232938..06c028b 100644
--- a/kernel/kernel/bpf/btf.c
+++ b/kernel/kernel/bpf/btf.c
@@ -604,31 +604,30 @@
 		offset < btf->hdr.str_len;
 }
 
-static bool __btf_name_char_ok(char c, bool first, bool dot_ok)
+static bool __btf_name_char_ok(char c, bool first)
 {
 	if ((first ? !isalpha(c) :
 		     !isalnum(c)) &&
 	    c != '_' &&
-	    ((c == '.' && !dot_ok) ||
-	      c != '.'))
+	    c != '.')
 		return false;
 	return true;
 }
 
-static bool __btf_name_valid(const struct btf *btf, u32 offset, bool dot_ok)
+static bool __btf_name_valid(const struct btf *btf, u32 offset)
 {
 	/* offset must be valid */
 	const char *src = &btf->strings[offset];
 	const char *src_limit;
 
-	if (!__btf_name_char_ok(*src, true, dot_ok))
+	if (!__btf_name_char_ok(*src, true))
 		return false;
 
 	/* set a limit on identifier length */
 	src_limit = src + KSYM_NAME_LEN;
 	src++;
 	while (*src && src < src_limit) {
-		if (!__btf_name_char_ok(*src, false, dot_ok))
+		if (!__btf_name_char_ok(*src, false))
 			return false;
 		src++;
 	}
@@ -636,17 +635,14 @@
 	return !*src;
 }
 
-/* Only C-style identifier is permitted. This can be relaxed if
- * necessary.
- */
 static bool btf_name_valid_identifier(const struct btf *btf, u32 offset)
 {
-	return __btf_name_valid(btf, offset, false);
+	return __btf_name_valid(btf, offset);
 }
 
 static bool btf_name_valid_section(const struct btf *btf, u32 offset)
 {
-	return __btf_name_valid(btf, offset, true);
+	return __btf_name_valid(btf, offset);
 }
 
 static const char *__btf_name_by_offset(const struct btf *btf, u32 offset)
@@ -3417,7 +3413,7 @@
 	}
 
 	if (!t->name_off ||
-	    !__btf_name_valid(env->btf, t->name_off, true)) {
+	    !__btf_name_valid(env->btf, t->name_off)) {
 		btf_verifier_log_type(env, t, "Invalid name");
 		return -EINVAL;
 	}
@@ -3541,6 +3537,7 @@
 	struct btf *btf = env->btf;
 	u16 i;
 
+	env->resolve_mode = RESOLVE_TBD;
 	for_each_vsi_from(i, v->next_member, v->t, vsi) {
 		u32 var_type_id = vsi->type, type_id, type_size = 0;
 		const struct btf_type *var_type = btf_type_by_id(env->btf,
@@ -3673,6 +3670,11 @@
 			btf_verifier_log_type(env, t, "Invalid arg#%u", i + 1);
 			err = -EINVAL;
 			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 &&
@@ -4268,6 +4270,7 @@
 	if (!ctx_struct)
 		/* should not happen */
 		return NULL;
+again:
 	ctx_tname = btf_name_by_offset(btf_vmlinux, ctx_struct->name_off);
 	if (!ctx_tname) {
 		/* should not happen */
@@ -4281,8 +4284,16 @@
 	 * int socket_filter_bpf_prog(struct __sk_buff *skb)
 	 * { // no fields of skb are ever used }
 	 */
-	if (strcmp(ctx_tname, tname))
-		return NULL;
+	if (strcmp(ctx_tname, tname)) {
+		/* bpf_user_pt_regs_t is a typedef, so resolve it to
+		 * underlying struct and check name again
+		 */
+		if (!btf_type_is_modifier(ctx_struct))
+			return NULL;
+		while (btf_type_is_modifier(ctx_struct))
+			ctx_struct = btf_type_by_id(btf_vmlinux, ctx_struct->type);
+		goto again;
+	}
 	return ctx_type;
 }
 
diff --git a/kernel/kernel/bpf/cgroup.c b/kernel/kernel/bpf/cgroup.c
index 6d92e39..d3593a5 100644
--- a/kernel/kernel/bpf/cgroup.c
+++ b/kernel/kernel/bpf/cgroup.c
@@ -1516,7 +1516,7 @@
 		goto out;
 	}
 
-	if (ctx.optlen > max_optlen || ctx.optlen < 0) {
+	if (optval && (ctx.optlen > max_optlen || ctx.optlen < 0)) {
 		ret = -EFAULT;
 		goto out;
 	}
@@ -1530,8 +1530,11 @@
 	}
 
 	if (ctx.optlen != 0) {
-		if (copy_to_user(optval, ctx.optval, ctx.optlen) ||
-		    put_user(ctx.optlen, optlen)) {
+		if (optval && copy_to_user(optval, ctx.optval, ctx.optlen)) {
+			ret = -EFAULT;
+			goto out;
+		}
+		if (put_user(ctx.optlen, optlen)) {
 			ret = -EFAULT;
 			goto out;
 		}
diff --git a/kernel/kernel/bpf/core.c b/kernel/kernel/bpf/core.c
index 234cf1c..b22447c 100644
--- a/kernel/kernel/bpf/core.c
+++ b/kernel/kernel/bpf/core.c
@@ -32,6 +32,7 @@
 #include <linux/perf_event.h>
 #include <linux/extable.h>
 #include <linux/log2.h>
+#include <linux/nospec.h>
 
 #include <asm/barrier.h>
 #include <asm/unaligned.h>
@@ -827,7 +828,7 @@
 {
 	/* Only used as heuristic here to derive limit. */
 	bpf_jit_limit_max = bpf_jit_alloc_exec_limit();
-	bpf_jit_limit = min_t(u64, round_up(bpf_jit_limit_max >> 2,
+	bpf_jit_limit = min_t(u64, round_up(bpf_jit_limit_max >> 1,
 					    PAGE_SIZE), LONG_MAX);
 	return 0;
 }
@@ -1646,9 +1647,7 @@
 		 * reuse preexisting logic from Spectre v1 mitigation that
 		 * happens to produce the required code on x86 for v4 as well.
 		 */
-#ifdef CONFIG_X86
 		barrier_nospec();
-#endif
 		CONT;
 #define LDST(SIZEOP, SIZE)						\
 	STX_MEM_##SIZEOP:						\
diff --git a/kernel/kernel/bpf/queue_stack_maps.c b/kernel/kernel/bpf/queue_stack_maps.c
index 0ee2347..a047a20 100644
--- a/kernel/kernel/bpf/queue_stack_maps.c
+++ b/kernel/kernel/bpf/queue_stack_maps.c
@@ -111,7 +111,12 @@
 	int err = 0;
 	void *ptr;
 
-	raw_spin_lock_irqsave(&qs->lock, flags);
+	if (in_nmi()) {
+		if (!raw_spin_trylock_irqsave(&qs->lock, flags))
+			return -EBUSY;
+	} else {
+		raw_spin_lock_irqsave(&qs->lock, flags);
+	}
 
 	if (queue_stack_map_is_empty(qs)) {
 		memset(value, 0, qs->map.value_size);
@@ -141,7 +146,12 @@
 	void *ptr;
 	u32 index;
 
-	raw_spin_lock_irqsave(&qs->lock, flags);
+	if (in_nmi()) {
+		if (!raw_spin_trylock_irqsave(&qs->lock, flags))
+			return -EBUSY;
+	} else {
+		raw_spin_lock_irqsave(&qs->lock, flags);
+	}
 
 	if (queue_stack_map_is_empty(qs)) {
 		memset(value, 0, qs->map.value_size);
@@ -206,7 +216,12 @@
 	if (flags & BPF_NOEXIST || flags > BPF_EXIST)
 		return -EINVAL;
 
-	raw_spin_lock_irqsave(&qs->lock, irq_flags);
+	if (in_nmi()) {
+		if (!raw_spin_trylock_irqsave(&qs->lock, irq_flags))
+			return -EBUSY;
+	} else {
+		raw_spin_lock_irqsave(&qs->lock, irq_flags);
+	}
 
 	if (queue_stack_map_is_full(qs)) {
 		if (!replace) {
diff --git a/kernel/kernel/bpf/verifier.c b/kernel/kernel/bpf/verifier.c
index a276f3d..f6a239a 100644
--- a/kernel/kernel/bpf/verifier.c
+++ b/kernel/kernel/bpf/verifier.c
@@ -562,6 +562,20 @@
 				  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 scrub_spilled_slot(u8 *stype)
+{
+	if (*stype != STACK_INVALID)
+		*stype = STACK_MISC;
+}
+
 static void print_verifier_state(struct bpf_verifier_env *env,
 				 const struct bpf_func_state *state)
 {
@@ -666,7 +680,7 @@
 			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]);
@@ -1345,7 +1359,7 @@
 	reg->type = SCALAR_VALUE;
 	reg->var_off = tnum_unknown;
 	reg->frameno = 0;
-	reg->precise = env->subprog_cnt > 1 || !env->bpf_capable;
+	reg->precise = !env->bpf_capable;
 	__mark_reg_unbounded(reg);
 }
 
@@ -1868,8 +1882,6 @@
 		 */
 		if (insn->src_reg != BPF_REG_FP)
 			return 0;
-		if (BPF_SIZE(insn->code) != BPF_DW)
-			return 0;
 
 		/* dreg = *(u64 *)[fp - off] was a fill from the stack.
 		 * that [fp - off] slot contains scalar that needs to be
@@ -1891,8 +1903,6 @@
 			return -ENOTSUPP;
 		/* scalars can only be spilled into stack */
 		if (insn->dst_reg != BPF_REG_FP)
-			return 0;
-		if (BPF_SIZE(insn->code) != BPF_DW)
 			return 0;
 		spi = (-insn->off - 1) / BPF_REG_SIZE;
 		if (spi >= 64) {
@@ -1921,6 +1931,21 @@
 			}
 		} else if (opcode == BPF_EXIT) {
 			return -ENOTSUPP;
+		} else if (BPF_SRC(insn->code) == BPF_X) {
+			if (!(*reg_mask & (dreg | sreg)))
+				return 0;
+			/* dreg <cond> sreg
+			 * Both dreg and sreg need precision before
+			 * this insn. If only sreg was marked precise
+			 * before it would be equally necessary to
+			 * propagate it to dreg.
+			 */
+			*reg_mask |= (sreg | dreg);
+			 /* else dreg <cond> K
+			  * Only dreg still needs precision before
+			  * this insn, so for the K-based conditional
+			  * there is nothing new to be marked.
+			  */
 		}
 	} else if (class == BPF_LD) {
 		if (!(*reg_mask & dreg))
@@ -1998,8 +2023,11 @@
 
 	/* big hammer: mark all scalars precise in this path.
 	 * pop_stack may still get !precise scalars.
+	 * We also skip current state and go straight to first parent state,
+	 * because precision markings in current non-checkpointed state are
+	 * not needed. See why in the comment in __mark_chain_precision below.
 	 */
-	for (; st; st = st->parent)
+	for (st = st->parent; st; st = st->parent) {
 		for (i = 0; i <= st->curframe; i++) {
 			func = st->frame[i];
 			for (j = 0; j < BPF_REG_FP; j++) {
@@ -2009,7 +2037,7 @@
 				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)
@@ -2017,9 +2045,122 @@
 				reg->precise = true;
 			}
 		}
+	}
 }
 
-static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
+static void mark_all_scalars_imprecise(struct bpf_verifier_env *env, struct bpf_verifier_state *st)
+{
+	struct bpf_func_state *func;
+	struct bpf_reg_state *reg;
+	int i, j;
+
+	for (i = 0; i <= st->curframe; i++) {
+		func = st->frame[i];
+		for (j = 0; j < BPF_REG_FP; j++) {
+			reg = &func->regs[j];
+			if (reg->type != SCALAR_VALUE)
+				continue;
+			reg->precise = false;
+		}
+		for (j = 0; j < func->allocated_stack / BPF_REG_SIZE; j++) {
+			if (!is_spilled_reg(&func->stack[j]))
+				continue;
+			reg = &func->stack[j].spilled_ptr;
+			if (reg->type != SCALAR_VALUE)
+				continue;
+			reg->precise = false;
+		}
+	}
+}
+
+/*
+ * __mark_chain_precision() backtracks BPF program instruction sequence and
+ * chain of verifier states making sure that register *regno* (if regno >= 0)
+ * and/or stack slot *spi* (if spi >= 0) are marked as precisely tracked
+ * SCALARS, as well as any other registers and slots that contribute to
+ * a tracked state of given registers/stack slots, depending on specific BPF
+ * assembly instructions (see backtrack_insns() for exact instruction handling
+ * logic). This backtracking relies on recorded jmp_history and is able to
+ * traverse entire chain of parent states. This process ends only when all the
+ * necessary registers/slots and their transitive dependencies are marked as
+ * precise.
+ *
+ * One important and subtle aspect is that precise marks *do not matter* in
+ * the currently verified state (current state). It is important to understand
+ * why this is the case.
+ *
+ * First, note that current state is the state that is not yet "checkpointed",
+ * i.e., it is not yet put into env->explored_states, and it has no children
+ * states as well. It's ephemeral, and can end up either a) being discarded if
+ * compatible explored state is found at some point or BPF_EXIT instruction is
+ * reached or b) checkpointed and put into env->explored_states, branching out
+ * into one or more children states.
+ *
+ * In the former case, precise markings in current state are completely
+ * ignored by state comparison code (see regsafe() for details). Only
+ * checkpointed ("old") state precise markings are important, and if old
+ * state's register/slot is precise, regsafe() assumes current state's
+ * register/slot as precise and checks value ranges exactly and precisely. If
+ * states turn out to be compatible, current state's necessary precise
+ * markings and any required parent states' precise markings are enforced
+ * after the fact with propagate_precision() logic, after the fact. But it's
+ * important to realize that in this case, even after marking current state
+ * registers/slots as precise, we immediately discard current state. So what
+ * actually matters is any of the precise markings propagated into current
+ * state's parent states, which are always checkpointed (due to b) case above).
+ * As such, for scenario a) it doesn't matter if current state has precise
+ * markings set or not.
+ *
+ * Now, for the scenario b), checkpointing and forking into child(ren)
+ * state(s). Note that before current state gets to checkpointing step, any
+ * processed instruction always assumes precise SCALAR register/slot
+ * knowledge: if precise value or range is useful to prune jump branch, BPF
+ * verifier takes this opportunity enthusiastically. Similarly, when
+ * register's value is used to calculate offset or memory address, exact
+ * knowledge of SCALAR range is assumed, checked, and enforced. So, similar to
+ * what we mentioned above about state comparison ignoring precise markings
+ * during state comparison, BPF verifier ignores and also assumes precise
+ * markings *at will* during instruction verification process. But as verifier
+ * assumes precision, it also propagates any precision dependencies across
+ * parent states, which are not yet finalized, so can be further restricted
+ * based on new knowledge gained from restrictions enforced by their children
+ * states. This is so that once those parent states are finalized, i.e., when
+ * they have no more active children state, state comparison logic in
+ * is_state_visited() would enforce strict and precise SCALAR ranges, if
+ * required for correctness.
+ *
+ * To build a bit more intuition, note also that once a state is checkpointed,
+ * the path we took to get to that state is not important. This is crucial
+ * property for state pruning. When state is checkpointed and finalized at
+ * some instruction index, it can be correctly and safely used to "short
+ * circuit" any *compatible* state that reaches exactly the same instruction
+ * index. I.e., if we jumped to that instruction from a completely different
+ * code path than original finalized state was derived from, it doesn't
+ * matter, current state can be discarded because from that instruction
+ * forward having a compatible state will ensure we will safely reach the
+ * exit. States describe preconditions for further exploration, but completely
+ * forget the history of how we got here.
+ *
+ * This also means that even if we needed precise SCALAR range to get to
+ * finalized state, but from that point forward *that same* SCALAR register is
+ * never used in a precise context (i.e., it's precise value is not needed for
+ * correctness), it's correct and safe to mark such register as "imprecise"
+ * (i.e., precise marking set to false). This is what we rely on when we do
+ * not set precise marking in current state. If no child state requires
+ * precision for any given SCALAR register, it's safe to dictate that it can
+ * be imprecise. If any child state does require this register to be precise,
+ * we'll mark it precise later retroactively during precise markings
+ * propagation from child state to parent states.
+ *
+ * Skipping precise marking setting in current state is a mild version of
+ * relying on the above observation. But we can utilize this property even
+ * more aggressively by proactively forgetting any precise marking in the
+ * current state (which we inherited from the parent state), right before we
+ * checkpoint it and branch off into new child state. This is done by
+ * mark_all_scalars_imprecise() to hopefully get more permissive and generic
+ * finalized states which help in short circuiting more future states.
+ */
+static int __mark_chain_precision(struct bpf_verifier_env *env, int frame, int regno,
 				  int spi)
 {
 	struct bpf_verifier_state *st = env->cur_state;
@@ -2036,22 +2177,22 @@
 	if (!env->bpf_capable)
 		return 0;
 
-	func = st->frame[st->curframe];
+	/* Do sanity checks against current state of register and/or stack
+	 * slot, but don't set precise flag in current state, as precision
+	 * tracking in the current state is unnecessary.
+	 */
+	func = st->frame[frame];
 	if (regno >= 0) {
 		reg = &func->regs[regno];
 		if (reg->type != SCALAR_VALUE) {
 			WARN_ONCE(1, "backtracing misuse");
 			return -EFAULT;
 		}
-		if (!reg->precise)
-			new_marks = true;
-		else
-			reg_mask = 0;
-		reg->precise = true;
+		new_marks = true;
 	}
 
 	while (spi >= 0) {
-		if (func->stack[spi].slot_type[0] != STACK_SPILL) {
+		if (!is_spilled_reg(&func->stack[spi])) {
 			stack_mask = 0;
 			break;
 		}
@@ -2060,11 +2201,7 @@
 			stack_mask = 0;
 			break;
 		}
-		if (!reg->precise)
-			new_marks = true;
-		else
-			stack_mask = 0;
-		reg->precise = true;
+		new_marks = true;
 		break;
 	}
 
@@ -2072,12 +2209,42 @@
 		return 0;
 	if (!reg_mask && !stack_mask)
 		return 0;
+
 	for (;;) {
 		DECLARE_BITMAP(mask, 64);
 		u32 history = st->jmp_history_cnt;
 
 		if (env->log.level & BPF_LOG_LEVEL)
 			verbose(env, "last_idx %d first_idx %d\n", last_idx, first_idx);
+
+		if (last_idx < 0) {
+			/* we are at the entry into subprog, which
+			 * is expected for global funcs, but only if
+			 * requested precise registers are R1-R5
+			 * (which are global func's input arguments)
+			 */
+			if (st->curframe == 0 &&
+			    st->frame[0]->subprogno > 0 &&
+			    st->frame[0]->callsite == BPF_MAIN_FUNC &&
+			    stack_mask == 0 && (reg_mask & ~0x3e) == 0) {
+				bitmap_from_u64(mask, reg_mask);
+				for_each_set_bit(i, mask, 32) {
+					reg = &st->frame[0]->regs[i];
+					if (reg->type != SCALAR_VALUE) {
+						reg_mask &= ~(1u << i);
+						continue;
+					}
+					reg->precise = true;
+				}
+				return 0;
+			}
+
+			verbose(env, "BUG backtracing func entry subprog %d reg_mask %x stack_mask %llx\n",
+				st->frame[0]->subprogno, reg_mask, stack_mask);
+			WARN_ONCE(1, "verifier backtracking bug");
+			return -EFAULT;
+		}
+
 		for (i = last_idx;;) {
 			if (skip_first) {
 				err = 0;
@@ -2117,7 +2284,7 @@
 			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];
@@ -2150,7 +2317,7 @@
 				return 0;
 			}
 
-			if (func->stack[i].slot_type[0] != STACK_SPILL) {
+			if (!is_spilled_reg(&func->stack[i])) {
 				stack_mask &= ~(1ull << i);
 				continue;
 			}
@@ -2183,12 +2350,17 @@
 
 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)
@@ -2259,16 +2431,38 @@
 	return reg->type != SCALAR_VALUE;
 }
 
+/* Copy src state preserving dst->parent and dst->live fields */
+static void copy_register_state(struct bpf_reg_state *dst, const struct bpf_reg_state *src)
+{
+	struct bpf_reg_state *parent = dst->parent;
+	enum bpf_reg_liveness live = dst->live;
+
+	*dst = *src;
+	dst->parent = parent;
+	dst->live = live;
+}
+
 static void save_register_state(struct bpf_func_state *state,
-				int spi, struct bpf_reg_state *reg)
+				int spi, struct bpf_reg_state *reg,
+				int size)
 {
 	int i;
 
-	state->stack[spi].spilled_ptr = *reg;
-	state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN;
+	copy_register_state(&state->stack[spi].spilled_ptr, reg);
+	if (size == BPF_REG_SIZE)
+		state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN;
 
-	for (i = 0; i < BPF_REG_SIZE; i++)
-		state->stack[spi].slot_type[i] = STACK_SPILL;
+	for (i = BPF_REG_SIZE; i > BPF_REG_SIZE - size; i--)
+		state->stack[spi].slot_type[i - 1] = STACK_SPILL;
+
+	/* size < 8 bytes spill */
+	for (; i; i--)
+		scrub_spilled_slot(&state->stack[spi].slot_type[i - 1]);
+}
+
+static bool is_bpf_st_mem(struct bpf_insn *insn)
+{
+	return BPF_CLASS(insn->code) == BPF_ST && BPF_MODE(insn->code) == BPF_MEM;
 }
 
 /* check_stack_{read,write}_fixed_off functions track spill/fill of registers,
@@ -2282,8 +2476,9 @@
 {
 	struct bpf_func_state *cur; /* state of the current function */
 	int i, slot = -off - 1, spi = slot / BPF_REG_SIZE, err;
-	u32 dst_reg = env->prog->insnsi[insn_idx].dst_reg;
+	struct bpf_insn *insn = &env->prog->insnsi[insn_idx];
 	struct bpf_reg_state *reg = NULL;
+	u32 dst_reg = insn->dst_reg;
 
 	err = realloc_func_state(state, round_up(slot + 1, BPF_REG_SIZE),
 				 state->acquired_refs, true);
@@ -2306,7 +2501,9 @@
 		bool sanitize = reg && is_spillable_regtype(reg->type);
 
 		for (i = 0; i < size; i++) {
-			if (state->stack[spi].slot_type[i] == STACK_INVALID) {
+			u8 type = state->stack[spi].slot_type[i];
+
+			if (type != STACK_MISC && type != STACK_ZERO) {
 				sanitize = true;
 				break;
 			}
@@ -2316,7 +2513,7 @@
 			env->insn_aux_data[insn_idx].sanitize_stack_spill = true;
 	}
 
-	if (reg && size == BPF_REG_SIZE && register_is_bounded(reg) &&
+	if (reg && !(off % BPF_REG_SIZE) && register_is_bounded(reg) &&
 	    !register_is_null(reg) && env->bpf_capable) {
 		if (dst_reg != BPF_REG_FP) {
 			/* The backtracking logic can only recognize explicit
@@ -2329,7 +2526,17 @@
 			if (err)
 				return err;
 		}
-		save_register_state(state, spi, reg);
+		save_register_state(state, spi, reg, size);
+		/* Break the relation on a narrowing spill. */
+		if (fls64(reg->umax_value) > BITS_PER_BYTE * size)
+			state->stack[spi].spilled_ptr.id = 0;
+	} else if (!reg && !(off % BPF_REG_SIZE) && is_bpf_st_mem(insn) &&
+		   insn->imm != 0 && env->bpf_capable) {
+		struct bpf_reg_state fake_reg = {};
+
+		__mark_reg_known(&fake_reg, (u32)insn->imm);
+		fake_reg.type = SCALAR_VALUE;
+		save_register_state(state, spi, &fake_reg, size);
 	} else if (reg && is_spillable_regtype(reg->type)) {
 		/* register containing pointer is being spilled into stack */
 		if (size != BPF_REG_SIZE) {
@@ -2341,16 +2548,16 @@
 			verbose(env, "cannot spill pointers to stack into stack frame of the caller\n");
 			return -EINVAL;
 		}
-		save_register_state(state, spi, reg);
+		save_register_state(state, spi, reg, size);
 	} else {
 		u8 type = STACK_MISC;
 
 		/* 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;
+				scrub_spilled_slot(&state->stack[spi].slot_type[i]);
 
 		/* only mark the slot as written if all 8 bytes were written
 		 * otherwise read propagation may incorrectly stop too soon
@@ -2364,7 +2571,8 @@
 			state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN;
 
 		/* when we zero initialize stack slots mark them as such */
-		if (reg && register_is_null(reg)) {
+		if ((reg && register_is_null(reg)) ||
+		    (!reg && is_bpf_st_mem(insn) && insn->imm == 0)) {
 			/* backtracking doesn't work for STACK_ZERO yet. */
 			err = mark_chain_precision(env, value_regno);
 			if (err)
@@ -2439,14 +2647,17 @@
 		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);
@@ -2554,35 +2765,56 @@
 	struct bpf_func_state *state = vstate->frame[vstate->curframe];
 	int i, slot = -off - 1, spi = slot / BPF_REG_SIZE;
 	struct bpf_reg_state *reg;
-	u8 *stype;
+	u8 *stype, type;
 
 	stype = reg_state->stack[spi].slot_type;
 	reg = &reg_state->stack[spi].spilled_ptr;
 
-	if (stype[0] == STACK_SPILL) {
-		if (size != BPF_REG_SIZE) {
+	if (is_spilled_reg(&reg_state->stack[spi])) {
+		u8 spill_size = 1;
+
+		for (i = BPF_REG_SIZE - 1; i > 0 && stype[i - 1] == STACK_SPILL; i--)
+			spill_size++;
+
+		if (size != BPF_REG_SIZE || spill_size != BPF_REG_SIZE) {
 			if (reg->type != SCALAR_VALUE) {
 				verbose_linfo(env, env->insn_idx, "; ");
 				verbose(env, "invalid size of register fill\n");
 				return -EACCES;
 			}
-			if (dst_regno >= 0) {
-				mark_reg_unknown(env, state->regs, dst_regno);
-				state->regs[dst_regno].live |= REG_LIVE_WRITTEN;
-			}
+
 			mark_reg_read(env, reg, reg->parent, REG_LIVE_READ64);
-			return 0;
-		}
-		for (i = 1; i < BPF_REG_SIZE; i++) {
-			if (stype[(slot - i) % BPF_REG_SIZE] != STACK_SPILL) {
-				verbose(env, "corrupted spill memory\n");
-				return -EACCES;
+			if (dst_regno < 0)
+				return 0;
+
+			if (!(off % BPF_REG_SIZE) && size == spill_size) {
+				/* The earlier check_reg_arg() has decided the
+				 * subreg_def for this insn.  Save it first.
+				 */
+				s32 subreg_def = state->regs[dst_regno].subreg_def;
+
+				copy_register_state(&state->regs[dst_regno], reg);
+				state->regs[dst_regno].subreg_def = subreg_def;
+			} else {
+				for (i = 0; i < size; i++) {
+					type = stype[(slot - i) % BPF_REG_SIZE];
+					if (type == STACK_SPILL)
+						continue;
+					if (type == STACK_MISC)
+						continue;
+					verbose(env, "invalid read from stack off %d+%d size %d\n",
+						off, i, size);
+					return -EACCES;
+				}
+				mark_reg_unknown(env, state->regs, dst_regno);
 			}
+			state->regs[dst_regno].live |= REG_LIVE_WRITTEN;
+			return 0;
 		}
 
 		if (dst_regno >= 0) {
 			/* restore register state from stack */
-			state->regs[dst_regno] = *reg;
+			copy_register_state(&state->regs[dst_regno], reg);
 			/* mark reg as written since spilled pointer state likely
 			 * has its liveness marks cleared by is_state_visited()
 			 * which resets stack/reg liveness for state transitions
@@ -2601,8 +2833,6 @@
 		}
 		mark_reg_read(env, reg, reg->parent, REG_LIVE_READ64);
 	} else {
-		u8 type;
-
 		for (i = 0; i < size; i++) {
 			type = stype[(slot - i) % BPF_REG_SIZE];
 			if (type == STACK_MISC)
@@ -2704,17 +2934,13 @@
 	}
 	/* Variable offset is prohibited for unprivileged mode for simplicity
 	 * since it requires corresponding support in Spectre masking for stack
-	 * ALU. See also retrieve_ptr_limit().
+	 * ALU. See also retrieve_ptr_limit(). The check in
+	 * check_stack_access_for_ptr_arithmetic() called by
+	 * adjust_ptr_min_max_vals() prevents users from creating stack pointers
+	 * with variable offsets, therefore no check is required here. Further,
+	 * just checking it here would be insufficient as speculative stack
+	 * writes could still lead to unsafe speculative behaviour.
 	 */
-	if (!env->bypass_spec_v1 && var_off) {
-		char tn_buf[48];
-
-		tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
-		verbose(env, "R%d variable offset stack access prohibited for !root, var_off=%s\n",
-				ptr_regno, tn_buf);
-		return -EACCES;
-	}
-
 	if (!var_off) {
 		off += reg->var_off.value;
 		err = check_stack_read_fixed_off(env, state, off, size,
@@ -4078,17 +4304,17 @@
 			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) {
 				__mark_reg_unknown(env, &state->stack[spi].spilled_ptr);
 				for (j = 0; j < BPF_REG_SIZE; j++)
-					state->stack[spi].slot_type[j] = STACK_MISC;
+					scrub_spilled_slot(&state->stack[spi].slot_type[j]);
 			}
 			goto mark;
 		}
@@ -5845,7 +6071,7 @@
 	 */
 	if (!ptr_is_dst_reg) {
 		tmp = *dst_reg;
-		*dst_reg = *ptr_reg;
+		copy_register_state(dst_reg, ptr_reg);
 	}
 	ret = sanitize_speculative_path(env, NULL, env->insn_idx + 1,
 					env->insn_idx);
@@ -6989,6 +7215,11 @@
 				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
@@ -7094,7 +7325,7 @@
 					 * to propagate min/max range.
 					 */
 					src_reg->id = ++env->id_gen;
-				*dst_reg = *src_reg;
+				copy_register_state(dst_reg, src_reg);
 				dst_reg->live |= REG_LIVE_WRITTEN;
 				dst_reg->subreg_def = DEF_NOT_SUBREG;
 			} else {
@@ -7105,7 +7336,7 @@
 						insn->src_reg);
 					return -EACCES;
 				} else if (src_reg->type == SCALAR_VALUE) {
-					*dst_reg = *src_reg;
+					copy_register_state(dst_reg, src_reg);
 					/* Make sure ID is cleared otherwise
 					 * dst_reg min/max could be incorrectly
 					 * propagated into src_reg by find_equal_scalars()
@@ -7925,7 +8156,7 @@
 
 	bpf_for_each_reg_in_vstate(vstate, state, reg, ({
 		if (reg->type == SCALAR_VALUE && reg->id == known_reg->id)
-			*reg = *known_reg;
+			copy_register_state(reg, known_reg);
 	}));
 }
 
@@ -9144,7 +9375,7 @@
 		if (env->explore_alu_limits)
 			return false;
 		if (rcur->type == SCALAR_VALUE) {
-			if (!rold->precise && !rcur->precise)
+			if (!rold->precise)
 				return true;
 			/* new val must satisfy old val knowledge */
 			return range_within(rold, rcur) &&
@@ -9274,9 +9505,9 @@
 			 * 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))
@@ -9467,34 +9698,38 @@
 {
 	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 ||
+			    !(state_reg->live & REG_LIVE_READ))
+				continue;
+			if (env->log.level & BPF_LOG_LEVEL2)
+				verbose(env, "frame %d: propagating r%d\n", fr, i);
+			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 (state->stack[i].slot_type[0] != STACK_SPILL)
-			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 ||
+			    !(state_reg->live & REG_LIVE_READ))
+				continue;
+			if (env->log.level & BPF_LOG_LEVEL2)
+				verbose(env, "frame %d: propagating fp%d\n",
+					fr, (-i - 1) * BPF_REG_SIZE);
+			err = mark_chain_precision_stack_frame(env, fr, i);
+			if (err < 0)
+				return err;
+		}
 	}
 	return 0;
 }
@@ -9672,6 +9907,10 @@
 	env->peak_states++;
 	env->prev_jmps_processed = env->jmps_processed;
 	env->prev_insn_processed = env->insn_processed;
+
+	/* forget precise markings we inherited, see __mark_chain_precision */
+	if (env->bpf_capable)
+		mark_all_scalars_imprecise(env, cur);
 
 	/* add new state to the head of linked list */
 	new = &new_sl->state;
@@ -11070,7 +11309,7 @@
 					insn_buf[cnt++] = BPF_ALU64_IMM(BPF_RSH,
 									insn->dst_reg,
 									shift);
-				insn_buf[cnt++] = BPF_ALU64_IMM(BPF_AND, insn->dst_reg,
+				insn_buf[cnt++] = BPF_ALU32_IMM(BPF_AND, insn->dst_reg,
 								(1ULL << size * 8) - 1);
 			}
 		}
@@ -11771,6 +12010,9 @@
 			0 /* frameno */,
 			subprog);
 
+	state->first_insn_idx = env->subprog_info[subprog].start;
+	state->last_insn_idx = -1;
+
 	regs = state->frame[state->curframe]->regs;
 	if (subprog || env->prog->type == BPF_PROG_TYPE_EXT) {
 		ret = btf_prepare_func_args(env, subprog, regs);
diff --git a/kernel/kernel/cgroup/cgroup.c b/kernel/kernel/cgroup/cgroup.c
index f08f898..193f092 100644
--- a/kernel/kernel/cgroup/cgroup.c
+++ b/kernel/kernel/cgroup/cgroup.c
@@ -56,6 +56,7 @@
 #include <linux/file.h>
 #include <linux/fs_parser.h>
 #include <linux/sched/cputime.h>
+#include <linux/sched/deadline.h>
 #include <linux/psi.h>
 #include <net/sock.h>
 
@@ -1736,7 +1737,7 @@
 {
 	struct cgroup *dcgrp = &dst_root->cgrp;
 	struct cgroup_subsys *ss;
-	int ssid, i, ret;
+	int ssid, ret;
 	u16 dfl_disable_ss_mask = 0;
 
 	lockdep_assert_held(&cgroup_mutex);
@@ -1780,7 +1781,8 @@
 		struct cgroup_root *src_root = ss->root;
 		struct cgroup *scgrp = &src_root->cgrp;
 		struct cgroup_subsys_state *css = cgroup_css(scgrp, ss);
-		struct css_set *cset;
+		struct css_set *cset, *cset_pos;
+		struct css_task_iter *it;
 
 		WARN_ON(!css || cgroup_css(dcgrp, ss));
 
@@ -1798,9 +1800,22 @@
 		css->cgroup = dcgrp;
 
 		spin_lock_irq(&css_set_lock);
-		hash_for_each(css_set_table, i, cset, hlist)
+		WARN_ON(!list_empty(&dcgrp->e_csets[ss->id]));
+		list_for_each_entry_safe(cset, cset_pos, &scgrp->e_csets[ss->id],
+					 e_cset_node[ss->id]) {
 			list_move_tail(&cset->e_cset_node[ss->id],
 				       &dcgrp->e_csets[ss->id]);
+			/*
+			 * all css_sets of scgrp together in same order to dcgrp,
+			 * patch in-flight iterators to preserve correct iteration.
+			 * since the iterator is always advanced right away and
+			 * finished when it->cset_pos meets it->cset_head, so only
+			 * update it->cset_head is enough here.
+			 */
+			list_for_each_entry(it, &cset->task_iters, iters_node)
+				if (it->cset_head == &scgrp->e_csets[ss->id])
+					it->cset_head = &dcgrp->e_csets[ss->id];
+		}
 		spin_unlock_irq(&css_set_lock);
 
 		/* default hierarchy doesn't enable controllers by default */
@@ -4219,6 +4234,7 @@
 		cft->flags |= __CFTYPE_ONLY_ON_DFL;
 	return cgroup_add_cftypes(ss, cfts);
 }
+EXPORT_SYMBOL_GPL(cgroup_add_dfl_cftypes);
 
 /**
  * cgroup_add_legacy_cftypes - add an array of cftypes for legacy hierarchies
@@ -6197,19 +6213,18 @@
 static void cgroup_css_set_put_fork(struct kernel_clone_args *kargs)
 	__releases(&cgroup_threadgroup_rwsem) __releases(&cgroup_mutex)
 {
+	struct cgroup *cgrp = kargs->cgrp;
+	struct css_set *cset = kargs->cset;
+
 	cgroup_threadgroup_change_end(current);
 
+	if (cset) {
+		put_css_set(cset);
+		kargs->cset = NULL;
+	}
+
 	if (kargs->flags & CLONE_INTO_CGROUP) {
-		struct cgroup *cgrp = kargs->cgrp;
-		struct css_set *cset = kargs->cset;
-
 		mutex_unlock(&cgroup_mutex);
-
-		if (cset) {
-			put_css_set(cset);
-			kargs->cset = NULL;
-		}
-
 		if (cgrp) {
 			cgroup_put(cgrp);
 			kargs->cgrp = NULL;
@@ -6372,6 +6387,9 @@
 	list_add_tail(&tsk->cg_list, &cset->dying_tasks);
 	cset->nr_tasks--;
 
+	if (dl_task(tsk))
+		dec_dl_tasks_cs(tsk);
+
 	WARN_ON_ONCE(cgroup_task_frozen(tsk));
 	if (unlikely(cgroup_task_freeze(tsk)))
 		cgroup_update_frozen(task_dfl_cgroup(tsk));
diff --git a/kernel/kernel/cgroup/cpuset.c b/kernel/kernel/cgroup/cpuset.c
index 6820a0c..270310e 100644
--- a/kernel/kernel/cgroup/cpuset.c
+++ b/kernel/kernel/cgroup/cpuset.c
@@ -165,6 +165,14 @@
 	 */
 	int use_parent_ecpus;
 	int child_ecpus_count;
+
+	/*
+	 * number of SCHED_DEADLINE tasks attached to this cpuset, so that we
+	 * know when to rebuild associated root domain bandwidth information.
+	 */
+	int nr_deadline_tasks;
+	int nr_migrate_dl_tasks;
+	u64 sum_migrate_dl_bw;
 };
 
 /*
@@ -208,6 +216,20 @@
 static inline struct cpuset *parent_cs(struct cpuset *cs)
 {
 	return css_cs(cs->css.parent);
+}
+
+void inc_dl_tasks_cs(struct task_struct *p)
+{
+	struct cpuset *cs = task_cs(p);
+
+	cs->nr_deadline_tasks++;
+}
+
+void dec_dl_tasks_cs(struct task_struct *p)
+{
+	struct cpuset *cs = task_cs(p);
+
+	cs->nr_deadline_tasks--;
 }
 
 /* bits in struct cpuset flags field */
@@ -339,6 +361,17 @@
  */
 
 static DEFINE_MUTEX(cpuset_mutex);
+
+void cpuset_lock(void)
+{
+	mutex_lock(&cpuset_mutex);
+}
+
+void cpuset_unlock(void)
+{
+	mutex_unlock(&cpuset_mutex);
+}
+
 static DEFINE_SPINLOCK(callback_lock);
 
 static struct workqueue_struct *cpuset_migrate_mm_wq;
@@ -925,10 +958,13 @@
 	return ndoms;
 }
 
-static void update_tasks_root_domain(struct cpuset *cs)
+static void dl_update_tasks_root_domain(struct cpuset *cs)
 {
 	struct css_task_iter it;
 	struct task_struct *task;
+
+	if (cs->nr_deadline_tasks == 0)
+		return;
 
 	css_task_iter_start(&cs->css, 0, &it);
 
@@ -938,7 +974,7 @@
 	css_task_iter_end(&it);
 }
 
-static void rebuild_root_domains(void)
+static void dl_rebuild_rd_accounting(void)
 {
 	struct cpuset *cs = NULL;
 	struct cgroup_subsys_state *pos_css;
@@ -966,7 +1002,7 @@
 
 		rcu_read_unlock();
 
-		update_tasks_root_domain(cs);
+		dl_update_tasks_root_domain(cs);
 
 		rcu_read_lock();
 		css_put(&cs->css);
@@ -980,7 +1016,7 @@
 {
 	mutex_lock(&sched_domains_mutex);
 	partition_sched_domains_locked(ndoms_new, doms_new, dattr_new);
-	rebuild_root_domains();
+	dl_rebuild_rd_accounting();
 	mutex_unlock(&sched_domains_mutex);
 }
 
@@ -2171,16 +2207,23 @@
 
 static struct cpuset *cpuset_attach_old_cs;
 
+static void reset_migrate_dl_data(struct cpuset *cs)
+{
+	cs->nr_migrate_dl_tasks = 0;
+	cs->sum_migrate_dl_bw = 0;
+}
+
 /* Called by cgroups to determine if a cpuset is usable; cpuset_mutex held */
 static int cpuset_can_attach(struct cgroup_taskset *tset)
 {
 	struct cgroup_subsys_state *css;
-	struct cpuset *cs;
+	struct cpuset *cs, *oldcs;
 	struct task_struct *task;
 	int ret;
 
 	/* used later by cpuset_attach() */
 	cpuset_attach_old_cs = task_cs(cgroup_taskset_first(tset, &css));
+	oldcs = cpuset_attach_old_cs;
 	cs = css_cs(css);
 
 	mutex_lock(&cpuset_mutex);
@@ -2192,14 +2235,39 @@
 		goto out_unlock;
 
 	cgroup_taskset_for_each(task, css, tset) {
-		ret = task_can_attach(task, cs->effective_cpus);
+		ret = task_can_attach(task);
 		if (ret)
 			goto out_unlock;
 		ret = security_task_setscheduler(task);
 		if (ret)
 			goto out_unlock;
+
+		if (dl_task(task)) {
+			cs->nr_migrate_dl_tasks++;
+			cs->sum_migrate_dl_bw += task->dl.dl_bw;
+		}
 	}
 
+	if (!cs->nr_migrate_dl_tasks)
+		goto out_success;
+
+	if (!cpumask_intersects(oldcs->effective_cpus, cs->effective_cpus)) {
+		int cpu = cpumask_any_and(cpu_active_mask, cs->effective_cpus);
+
+		if (unlikely(cpu >= nr_cpu_ids)) {
+			reset_migrate_dl_data(cs);
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+
+		ret = dl_bw_alloc(cpu, cs->sum_migrate_dl_bw);
+		if (ret) {
+			reset_migrate_dl_data(cs);
+			goto out_unlock;
+		}
+	}
+
+out_success:
 	/*
 	 * Mark attach is in progress.  This makes validate_change() fail
 	 * changes which zero cpus/mems_allowed.
@@ -2214,11 +2282,23 @@
 static void cpuset_cancel_attach(struct cgroup_taskset *tset)
 {
 	struct cgroup_subsys_state *css;
+	struct cpuset *cs;
 
 	cgroup_taskset_first(tset, &css);
+	cs = css_cs(css);
 
 	mutex_lock(&cpuset_mutex);
-	css_cs(css)->attach_in_progress--;
+	cs->attach_in_progress--;
+	if (!cs->attach_in_progress)
+		wake_up(&cpuset_attach_wq);
+
+	if (cs->nr_migrate_dl_tasks) {
+		int cpu = cpumask_any(cs->effective_cpus);
+
+		dl_bw_free(cpu, cs->sum_migrate_dl_bw);
+		reset_migrate_dl_data(cs);
+	}
+
 	mutex_unlock(&cpuset_mutex);
 }
 
@@ -2291,6 +2371,12 @@
 
 	cs->old_mems_allowed = cpuset_attach_nodemask_to;
 
+	if (cs->nr_migrate_dl_tasks) {
+		cs->nr_deadline_tasks += cs->nr_migrate_dl_tasks;
+		oldcs->nr_deadline_tasks -= cs->nr_migrate_dl_tasks;
+		reset_migrate_dl_data(cs);
+	}
+
 	cs->attach_in_progress--;
 	if (!cs->attach_in_progress)
 		wake_up(&cpuset_attach_wq);
diff --git a/kernel/kernel/cgroup/namespace.c b/kernel/kernel/cgroup/namespace.c
index 812a61a..d2b4dd7 100644
--- a/kernel/kernel/cgroup/namespace.c
+++ b/kernel/kernel/cgroup/namespace.c
@@ -149,9 +149,3 @@
 	.install	= cgroupns_install,
 	.owner		= cgroupns_owner,
 };
-
-static __init int cgroup_namespaces_init(void)
-{
-	return 0;
-}
-subsys_initcall(cgroup_namespaces_init);
diff --git a/kernel/kernel/compat.c b/kernel/kernel/compat.c
index 05adfd6..f9f7a79 100644
--- a/kernel/kernel/compat.c
+++ b/kernel/kernel/compat.c
@@ -152,7 +152,7 @@
 	if (len & (sizeof(compat_ulong_t)-1))
 		return -EINVAL;
 
-	if (!alloc_cpumask_var(&mask, GFP_KERNEL))
+	if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
 		return -ENOMEM;
 
 	ret = sched_getaffinity(pid, mask);
diff --git a/kernel/kernel/cpu.c b/kernel/kernel/cpu.c
index d2e4b56..09d8ee3 100644
--- a/kernel/kernel/cpu.c
+++ b/kernel/kernel/cpu.c
@@ -45,6 +45,7 @@
 #include <trace/hooks/sched.h>
 #include <trace/hooks/cpu.h>
 
+#include "sched/sched.h"
 #include "smpboot.h"
 
 /**
@@ -1159,8 +1160,6 @@
 }
 EXPORT_SYMBOL_GPL(remove_cpu);
 
-extern int  dl_cpu_busy(int cpu, struct task_struct *p);
-
 int __pause_drain_rq(struct cpumask *cpus)
 {
 	unsigned int cpu;
@@ -1234,7 +1233,7 @@
 	cpumask_and(cpus, cpus, cpu_active_mask);
 
 	for_each_cpu(cpu, cpus) {
-		if (!cpu_online(cpu) || dl_cpu_busy(cpu, NULL) ||
+		if (!cpu_online(cpu) || dl_bw_check_overflow(cpu) ||
 			get_cpu_device(cpu)->offline_disabled == true) {
 			err = -EBUSY;
 			goto err_cpu_maps_update;
@@ -2538,8 +2537,10 @@
 
 	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;
diff --git a/kernel/kernel/dma/debug.c b/kernel/kernel/dma/debug.c
index 4833c6f..2fb8e53 100644
--- a/kernel/kernel/dma/debug.c
+++ b/kernel/kernel/dma/debug.c
@@ -606,15 +606,19 @@
 	return entry;
 }
 
-static void __dma_entry_alloc_check_leak(void)
+/*
+ * This should be called outside of free_entries_lock scope to avoid potential
+ * deadlocks with serial consoles that use DMA.
+ */
+static void __dma_entry_alloc_check_leak(u32 nr_entries)
 {
-	u32 tmp = nr_total_entries % nr_prealloc_entries;
+	u32 tmp = nr_entries % nr_prealloc_entries;
 
 	/* Shout each time we tick over some multiple of the initial pool */
 	if (tmp < DMA_DEBUG_DYNAMIC_ENTRIES) {
 		pr_info("dma_debug_entry pool grown to %u (%u00%%)\n",
-			nr_total_entries,
-			(nr_total_entries / nr_prealloc_entries));
+			nr_entries,
+			(nr_entries / nr_prealloc_entries));
 	}
 }
 
@@ -625,8 +629,10 @@
  */
 static struct dma_debug_entry *dma_entry_alloc(void)
 {
+	bool alloc_check_leak = false;
 	struct dma_debug_entry *entry;
 	unsigned long flags;
+	u32 nr_entries;
 
 	spin_lock_irqsave(&free_entries_lock, flags);
 	if (num_free_entries == 0) {
@@ -636,13 +642,17 @@
 			pr_err("debugging out of memory - disabling\n");
 			return NULL;
 		}
-		__dma_entry_alloc_check_leak();
+		alloc_check_leak = true;
+		nr_entries = nr_total_entries;
 	}
 
 	entry = __dma_entry_alloc();
 
 	spin_unlock_irqrestore(&free_entries_lock, flags);
 
+	if (alloc_check_leak)
+		__dma_entry_alloc_check_leak(nr_entries);
+
 #ifdef CONFIG_STACKTRACE
 	entry->stack_len = stack_trace_save(entry->stack_entries,
 					    ARRAY_SIZE(entry->stack_entries),
diff --git a/kernel/kernel/dma/remap.c b/kernel/kernel/dma/remap.c
index 905c3fa..5bff061 100644
--- a/kernel/kernel/dma/remap.c
+++ b/kernel/kernel/dma/remap.c
@@ -43,13 +43,13 @@
 	void *vaddr;
 	int i;
 
-	pages = kmalloc_array(count, sizeof(struct page *), GFP_KERNEL);
+	pages = kvmalloc_array(count, sizeof(struct page *), GFP_KERNEL);
 	if (!pages)
 		return NULL;
 	for (i = 0; i < count; i++)
 		pages[i] = nth_page(page, i);
 	vaddr = vmap(pages, count, VM_DMA_COHERENT, prot);
-	kfree(pages);
+	kvfree(pages);
 
 	return vaddr;
 }
diff --git a/kernel/kernel/events/core.c b/kernel/kernel/events/core.c
index d3fc75e..80ab33a 100644
--- a/kernel/kernel/events/core.c
+++ b/kernel/kernel/events/core.c
@@ -1192,6 +1192,11 @@
 	return 0;
 }
 
+static int perf_mux_hrtimer_restart_ipi(void *arg)
+{
+	return perf_mux_hrtimer_restart(arg);
+}
+
 void perf_pmu_disable(struct pmu *pmu)
 {
 	int *count = this_cpu_ptr(pmu->pmu_disable_count);
@@ -8665,7 +8670,7 @@
 
 	perf_event_header__init_id(&bpf_event->event_id.header,
 				   &sample, event);
-	ret = perf_output_begin(&handle, data, event,
+	ret = perf_output_begin(&handle, &sample, event,
 				bpf_event->event_id.header.size);
 	if (ret)
 		return;
@@ -8880,8 +8885,8 @@
 		hwc->interrupts = 1;
 	} else {
 		hwc->interrupts++;
-		if (unlikely(throttle
-			     && hwc->interrupts >= max_samples_per_tick)) {
+		if (unlikely(throttle &&
+			     hwc->interrupts > max_samples_per_tick)) {
 			__this_cpu_inc(perf_throttled_count);
 			tick_dep_set_cpu(smp_processor_id(), TICK_DEP_BIT_PERF_EVENTS);
 			hwc->interrupts = MAX_INTERRUPTS;
@@ -10727,8 +10732,7 @@
 		cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu);
 		cpuctx->hrtimer_interval = ns_to_ktime(NSEC_PER_MSEC * timer);
 
-		cpu_function_call(cpu,
-			(remote_function_f)perf_mux_hrtimer_restart, cpuctx);
+		cpu_function_call(cpu, perf_mux_hrtimer_restart_ipi, cpuctx);
 	}
 	cpus_read_unlock();
 	mutex_unlock(&mux_interval_mutex);
@@ -10765,13 +10769,15 @@
 
 	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;
@@ -11575,7 +11581,7 @@
 	/*
 	 * If its not a per-cpu rb, it must be the same task.
 	 */
-	if (output_event->cpu == -1 && output_event->ctx != event->ctx)
+	if (output_event->cpu == -1 && output_event->hw.target != event->hw.target)
 		goto out;
 
 	/*
@@ -11734,12 +11740,12 @@
 	if (flags & ~PERF_FLAG_ALL)
 		return -EINVAL;
 
-	/* Do we allow access to perf_event_open(2) ? */
-	err = security_perf_event_open(&attr, PERF_SECURITY_OPEN);
+	err = perf_copy_attr(attr_uptr, &attr);
 	if (err)
 		return err;
 
-	err = perf_copy_attr(attr_uptr, &attr);
+	/* Do we allow access to perf_event_open(2) ? */
+	err = security_perf_event_open(&attr, PERF_SECURITY_OPEN);
 	if (err)
 		return err;
 
diff --git a/kernel/kernel/exit.c b/kernel/kernel/exit.c
index 86e4031..7231d6a 100644
--- a/kernel/kernel/exit.c
+++ b/kernel/kernel/exit.c
@@ -64,11 +64,58 @@
 #include <linux/rcuwait.h>
 #include <linux/compat.h>
 #include <linux/io_uring.h>
+#include <linux/sysfs.h>
 
 #include <linux/uaccess.h>
 #include <asm/unistd.h>
 #include <asm/mmu_context.h>
 #include <trace/hooks/mm.h>
+
+/*
+ * The default value should be high enough to not crash a system that randomly
+ * crashes its kernel from time to time, but low enough to at least not permit
+ * overflowing 32-bit refcounts or the ldsem writer count.
+ */
+static unsigned int oops_limit = 10000;
+
+#ifdef CONFIG_SYSCTL
+static struct ctl_table kern_exit_table[] = {
+	{
+		.procname       = "oops_limit",
+		.data           = &oops_limit,
+		.maxlen         = sizeof(oops_limit),
+		.mode           = 0644,
+		.proc_handler   = proc_douintvec,
+	},
+	{ }
+};
+
+static __init int kernel_exit_sysctls_init(void)
+{
+	register_sysctl_init("kernel", kern_exit_table);
+	return 0;
+}
+late_initcall(kernel_exit_sysctls_init);
+#endif
+
+static atomic_t oops_count = ATOMIC_INIT(0);
+
+#ifdef CONFIG_SYSFS
+static ssize_t oops_count_show(struct kobject *kobj, struct kobj_attribute *attr,
+			       char *page)
+{
+	return sysfs_emit(page, "%d\n", atomic_read(&oops_count));
+}
+
+static struct kobj_attribute oops_count_attr = __ATTR_RO(oops_count);
+
+static __init int kernel_exit_sysfs_init(void)
+{
+	sysfs_add_file_to_group(kernel_kobj, &oops_count_attr.attr, NULL);
+	return 0;
+}
+late_initcall(kernel_exit_sysfs_init);
+#endif
 
 static void __unhash_process(struct task_struct *p, bool group_dead)
 {
@@ -865,6 +912,31 @@
 }
 EXPORT_SYMBOL_GPL(do_exit);
 
+void __noreturn make_task_dead(int signr)
+{
+	/*
+	 * Take the task off the cpu after something catastrophic has
+	 * happened.
+	 */
+	unsigned int limit;
+
+	/*
+	 * Every time the system oopses, if the oops happens while a reference
+	 * to an object was held, the reference leaks.
+	 * If the oops doesn't also leak memory, repeated oopsing can cause
+	 * reference counters to wrap around (if they're not using refcount_t).
+	 * This means that repeated oopsing can make unexploitable-looking bugs
+	 * exploitable through repeated oopsing.
+	 * To make sure this can't happen, place an upper bound on how often the
+	 * kernel may oops without panic().
+	 */
+	limit = READ_ONCE(oops_limit);
+	if (atomic_inc_return(&oops_count) >= limit && limit)
+		panic("Oopsed too often (kernel.oops_limit is %d)", limit);
+
+	do_exit(signr);
+}
+
 void complete_and_exit(struct completion *comp, long code)
 {
 	if (comp)
diff --git a/kernel/kernel/fail_function.c b/kernel/kernel/fail_function.c
index b0b1ad9..8f3795d 100644
--- a/kernel/kernel/fail_function.c
+++ b/kernel/kernel/fail_function.c
@@ -163,10 +163,7 @@
 
 static void fei_debugfs_remove_attr(struct fei_attr *attr)
 {
-	struct dentry *dir;
-
-	dir = debugfs_lookup(attr->kp.symbol_name, fei_debugfs_dir);
-	debugfs_remove_recursive(dir);
+	debugfs_lookup_and_remove(attr->kp.symbol_name, fei_debugfs_dir);
 }
 
 static int fei_kprobe_handler(struct kprobe *kp, struct pt_regs *regs)
diff --git a/kernel/kernel/fork.c b/kernel/kernel/fork.c
index f73e3e6..c47ad81 100644
--- a/kernel/kernel/fork.c
+++ b/kernel/kernel/fork.c
@@ -448,6 +448,9 @@
 
 void free_task(struct task_struct *tsk)
 {
+#ifdef CONFIG_SECCOMP
+	WARN_ON_ONCE(tsk->seccomp.filter);
+#endif
 	cpufreq_task_times_exit(tsk);
 	scs_release(tsk);
 
@@ -776,6 +779,14 @@
 		free_task(tsk);
 }
 EXPORT_SYMBOL_GPL(__put_task_struct);
+
+void __put_task_struct_rcu_cb(struct rcu_head *rhp)
+{
+	struct task_struct *task = container_of(rhp, struct task_struct, rcu);
+
+	__put_task_struct(task);
+}
+EXPORT_SYMBOL_GPL(__put_task_struct_rcu_cb);
 
 void __init __weak arch_task_cache_init(void) { }
 
@@ -2307,12 +2318,6 @@
 
 	spin_lock(&current->sighand->siglock);
 
-	/*
-	 * Copy seccomp details explicitly here, in case they were changed
-	 * before holding sighand lock.
-	 */
-	copy_seccomp(p);
-
 	rseq_fork(p, clone_flags);
 
 	/* Don't start children in a dying pid namespace */
@@ -2326,6 +2331,14 @@
 		retval = -EINTR;
 		goto bad_fork_cancel_cgroup;
 	}
+
+	/* No more failure paths after this point. */
+
+	/*
+	 * Copy seccomp details explicitly here, in case they were changed
+	 * before holding sighand lock.
+	 */
+	copy_seccomp(p);
 
 	init_task_pid_links(p);
 	if (likely(p->pid)) {
@@ -2476,11 +2489,6 @@
 	}
 
 	return task;
-}
-
-struct mm_struct *copy_init_mm(void)
-{
-	return dup_mm(NULL, &init_mm);
 }
 
 /*
@@ -2787,7 +2795,7 @@
 	 * - make the CLONE_DETACHED bit reuseable for clone3
 	 * - make the CSIGNAL bits reuseable for clone3
 	 */
-	if (kargs->flags & (CLONE_DETACHED | CSIGNAL))
+	if (kargs->flags & (CLONE_DETACHED | (CSIGNAL & (~CLONE_NEWTIME))))
 		return false;
 
 	if ((kargs->flags & (CLONE_SIGHAND | CLONE_CLEAR_SIGHAND)) ==
@@ -2879,10 +2887,27 @@
 	init_waitqueue_head(&sighand->signalfd_wqh);
 }
 
-void __init proc_caches_init(void)
+void __init mm_cache_init(void)
 {
 	unsigned int mm_size;
 
+	/*
+	 * The mm_cpumask is located at the end of mm_struct, and is
+	 * dynamically sized based on the maximum CPU number this system
+	 * can have, taking hotplug into account (nr_cpu_ids).
+	 */
+	mm_size = sizeof(struct mm_struct) + cpumask_size();
+
+	mm_cachep = kmem_cache_create_usercopy("mm_struct",
+			mm_size, ARCH_MIN_MMSTRUCT_ALIGN,
+			SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT,
+			offsetof(struct mm_struct, saved_auxv),
+			sizeof_field(struct mm_struct, saved_auxv),
+			NULL);
+}
+
+void __init proc_caches_init(void)
+{
 	sighand_cachep = kmem_cache_create("sighand_cache",
 			sizeof(struct sighand_struct), 0,
 			SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_TYPESAFE_BY_RCU|
@@ -2900,19 +2925,6 @@
 			SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT,
 			NULL);
 
-	/*
-	 * The mm_cpumask is located at the end of mm_struct, and is
-	 * dynamically sized based on the maximum CPU number this system
-	 * can have, taking hotplug into account (nr_cpu_ids).
-	 */
-	mm_size = sizeof(struct mm_struct) + cpumask_size();
-
-	mm_cachep = kmem_cache_create_usercopy("mm_struct",
-			mm_size, ARCH_MIN_MMSTRUCT_ALIGN,
-			SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT,
-			offsetof(struct mm_struct, saved_auxv),
-			sizeof_field(struct mm_struct, saved_auxv),
-			NULL);
 	vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC|SLAB_ACCOUNT);
 	mmap_init();
 	nsproxy_cache_init();
diff --git a/kernel/kernel/futex/Makefile b/kernel/kernel/futex/Makefile
new file mode 100644
index 0000000..b89ba3f
--- /dev/null
+++ b/kernel/kernel/futex/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += core.o
diff --git a/kernel/kernel/futex.c b/kernel/kernel/futex/core.c
similarity index 98%
rename from kernel/kernel/futex.c
rename to kernel/kernel/futex/core.c
index b223cc5..78cc66b 100644
--- a/kernel/kernel/futex.c
+++ b/kernel/kernel/futex/core.c
@@ -42,7 +42,7 @@
 
 #include <asm/futex.h>
 
-#include "locking/rtmutex_common.h"
+#include "../locking/rtmutex_common.h"
 #include <trace/hooks/futex.h>
 
 /*
@@ -3417,6 +3417,7 @@
 			      bool pi, bool pending_op)
 {
 	u32 uval, nval, mval;
+	pid_t owner;
 	int err;
 
 	/* Futex address must be 32bit aligned */
@@ -3438,6 +3439,10 @@
 	 * 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.
@@ -3446,24 +3451,27 @@
 	 *
 	 *	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.
+	 * 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.
 	 */
-	if (pending_op && !pi && !uval) {
+	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;
 
 	/*
diff --git a/kernel/kernel/gcov/gcc_4_7.c b/kernel/kernel/gcov/gcc_4_7.c
index c699fed..04880d8 100644
--- a/kernel/kernel/gcov/gcc_4_7.c
+++ b/kernel/kernel/gcov/gcc_4_7.c
@@ -85,6 +85,7 @@
  * @version: gcov version magic indicating the gcc version used for compilation
  * @next: list head for a singly-linked list
  * @stamp: uniquifying time stamp
+ * @checksum: unique object checksum
  * @filename: name of the associated gcov data file
  * @merge: merge functions (null for unused counter type)
  * @n_functions: number of instrumented functions
@@ -97,6 +98,10 @@
 	unsigned int version;
 	struct gcov_info *next;
 	unsigned int stamp;
+ /* Since GCC 12.1 a checksum field is added. */
+#if (__GNUC__ >= 12)
+	unsigned int checksum;
+#endif
 	const char *filename;
 	void (*merge[GCOV_COUNTERS])(gcov_type *, unsigned int);
 	unsigned int n_functions;
diff --git a/kernel/kernel/irq/chip.c b/kernel/kernel/irq/chip.c
index 520b9fa..afef871 100644
--- a/kernel/kernel/irq/chip.c
+++ b/kernel/kernel/irq/chip.c
@@ -826,7 +826,7 @@
 		/*
 		 * When another irq arrived while we were handling
 		 * one, we could have masked the irq.
-		 * Renable it, if it was not disabled in meantime.
+		 * Reenable it, if it was not disabled in meantime.
 		 */
 		if (unlikely(desc->istate & IRQS_PENDING)) {
 			if (!irqd_irq_disabled(&desc->irq_data) &&
diff --git a/kernel/kernel/irq/dummychip.c b/kernel/kernel/irq/dummychip.c
index 0b0cdf2..7fe6cff 100644
--- a/kernel/kernel/irq/dummychip.c
+++ b/kernel/kernel/irq/dummychip.c
@@ -13,7 +13,7 @@
 
 /*
  * What should we do if we get a hw irq event on an illegal vector?
- * Each architecture has to answer this themself.
+ * Each architecture has to answer this themselves.
  */
 static void ack_bad(struct irq_data *data)
 {
diff --git a/kernel/kernel/irq/internals.h b/kernel/kernel/irq/internals.h
index e58342a..f1d83a8 100644
--- a/kernel/kernel/irq/internals.h
+++ b/kernel/kernel/irq/internals.h
@@ -52,6 +52,7 @@
  * 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 @@
 	IRQS_SUSPENDED		= 0x00000800,
 	IRQS_TIMINGS		= 0x00001000,
 	IRQS_NMI		= 0x00002000,
+	IRQS_SYSFS		= 0x00004000,
 };
 
 #include "debug.h"
diff --git a/kernel/kernel/irq/irqdesc.c b/kernel/kernel/irq/irqdesc.c
index 2f35de3..67d73af 100644
--- a/kernel/kernel/irq/irqdesc.c
+++ b/kernel/kernel/irq/irqdesc.c
@@ -31,7 +31,7 @@
 	cpulist_parse(str, irq_default_affinity);
 	/*
 	 * Set at least the boot cpu. We don't want to end up with
-	 * bugreports caused by random comandline masks
+	 * bugreports caused by random commandline masks
 	 */
 	cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
 	return 1;
@@ -288,22 +288,25 @@
 	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);
 }
 
diff --git a/kernel/kernel/irq/irqdomain.c b/kernel/kernel/irq/irqdomain.c
index 2c3d494..8c34f6b 100644
--- a/kernel/kernel/irq/irqdomain.c
+++ b/kernel/kernel/irq/irqdomain.c
@@ -25,6 +25,9 @@
 
 static struct irq_domain *irq_default_domain;
 
+static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base,
+					unsigned int nr_irqs, int node, void *arg,
+					bool realloc, const struct irq_affinity_desc *affinity);
 static void irq_domain_check_hierarchy(struct irq_domain *domain);
 
 struct irqchip_fwid {
@@ -53,7 +56,7 @@
  * @name:	Optional user provided domain name
  * @pa:		Optional user-provided physical address
  *
- * Allocate a struct irqchip_fwid, and return a poiner to the embedded
+ * Allocate a struct irqchip_fwid, and return a pointer to the embedded
  * fwnode_handle (or NULL on failure).
  *
  * Note: The types IRQCHIP_FWNODE_NAMED and IRQCHIP_FWNODE_NAMED_ID are
@@ -114,23 +117,12 @@
 }
 EXPORT_SYMBOL_GPL(irq_domain_free_fwnode);
 
-/**
- * __irq_domain_add() - Allocate a new irq_domain data structure
- * @fwnode: firmware node for the interrupt controller
- * @size: Size of linear map; 0 for radix mapping only
- * @hwirq_max: Maximum number of interrupts supported by controller
- * @direct_max: Maximum value of direct maps; Use ~0 for no limit; 0 for no
- *              direct mapping
- * @ops: domain callbacks
- * @host_data: Controller private data pointer
- *
- * Allocates and initializes an irq_domain structure.
- * Returns pointer to IRQ domain, or NULL on failure.
- */
-struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
-				    irq_hw_number_t hwirq_max, int direct_max,
-				    const struct irq_domain_ops *ops,
-				    void *host_data)
+static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
+					      unsigned int size,
+					      irq_hw_number_t hwirq_max,
+					      int direct_max,
+					      const struct irq_domain_ops *ops,
+					      void *host_data)
 {
 	struct irqchip_fwid *fwid;
 	struct irq_domain *domain;
@@ -208,12 +200,44 @@
 	domain->revmap_direct_max_irq = direct_max;
 	irq_domain_check_hierarchy(domain);
 
+	return domain;
+}
+
+static void __irq_domain_publish(struct irq_domain *domain)
+{
 	mutex_lock(&irq_domain_mutex);
 	debugfs_add_domain_dir(domain);
 	list_add(&domain->link, &irq_domain_list);
 	mutex_unlock(&irq_domain_mutex);
 
 	pr_debug("Added domain %s\n", domain->name);
+}
+
+/**
+ * __irq_domain_add() - Allocate a new irq_domain data structure
+ * @fwnode: firmware node for the interrupt controller
+ * @size: Size of linear map; 0 for radix mapping only
+ * @hwirq_max: Maximum number of interrupts supported by controller
+ * @direct_max: Maximum value of direct maps; Use ~0 for no limit; 0 for no
+ *              direct mapping
+ * @ops: domain callbacks
+ * @host_data: Controller private data pointer
+ *
+ * Allocates and initializes an irq_domain structure.
+ * Returns pointer to IRQ domain, or NULL on failure.
+ */
+struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size,
+				    irq_hw_number_t hwirq_max, int direct_max,
+				    const struct irq_domain_ops *ops,
+				    void *host_data)
+{
+	struct irq_domain *domain;
+
+	domain = __irq_domain_create(fwnode, size, hwirq_max, direct_max,
+				     ops, host_data);
+	if (domain)
+		__irq_domain_publish(domain);
+
 	return domain;
 }
 EXPORT_SYMBOL_GPL(__irq_domain_add);
@@ -497,6 +521,9 @@
 		return;
 
 	hwirq = irq_data->hwirq;
+
+	mutex_lock(&irq_domain_mutex);
+
 	irq_set_status_flags(irq, IRQ_NOREQUEST);
 
 	/* remove chip and handler */
@@ -516,10 +543,12 @@
 
 	/* Clear reverse map for this hwirq */
 	irq_domain_clear_mapping(domain, hwirq);
+
+	mutex_unlock(&irq_domain_mutex);
 }
 
-int irq_domain_associate(struct irq_domain *domain, unsigned int virq,
-			 irq_hw_number_t hwirq)
+static int irq_domain_associate_locked(struct irq_domain *domain, unsigned int virq,
+				       irq_hw_number_t hwirq)
 {
 	struct irq_data *irq_data = irq_get_irq_data(virq);
 	int ret;
@@ -532,7 +561,6 @@
 	if (WARN(irq_data->domain, "error: virq%i is already associated", virq))
 		return -EINVAL;
 
-	mutex_lock(&irq_domain_mutex);
 	irq_data->hwirq = hwirq;
 	irq_data->domain = domain;
 	if (domain->ops->map) {
@@ -549,7 +577,6 @@
 			}
 			irq_data->domain = NULL;
 			irq_data->hwirq = 0;
-			mutex_unlock(&irq_domain_mutex);
 			return ret;
 		}
 
@@ -560,11 +587,22 @@
 
 	domain->mapcount++;
 	irq_domain_set_mapping(domain, hwirq, irq_data);
-	mutex_unlock(&irq_domain_mutex);
 
 	irq_clear_status_flags(virq, IRQ_NOREQUEST);
 
 	return 0;
+}
+
+int irq_domain_associate(struct irq_domain *domain, unsigned int virq,
+			 irq_hw_number_t hwirq)
+{
+	int ret;
+
+	mutex_lock(&irq_domain_mutex);
+	ret = irq_domain_associate_locked(domain, virq, hwirq);
+	mutex_unlock(&irq_domain_mutex);
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(irq_domain_associate);
 
@@ -625,6 +663,34 @@
 }
 EXPORT_SYMBOL_GPL(irq_create_direct_mapping);
 
+static unsigned int irq_create_mapping_affinity_locked(struct irq_domain *domain,
+						       irq_hw_number_t hwirq,
+						       const struct irq_affinity_desc *affinity)
+{
+	struct device_node *of_node = irq_domain_get_of_node(domain);
+	int virq;
+
+	pr_debug("irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq);
+
+	/* Allocate a virtual interrupt number */
+	virq = irq_domain_alloc_descs(-1, 1, hwirq, of_node_to_nid(of_node),
+				      affinity);
+	if (virq <= 0) {
+		pr_debug("-> virq allocation failed\n");
+		return 0;
+	}
+
+	if (irq_domain_associate_locked(domain, virq, hwirq)) {
+		irq_free_desc(virq);
+		return 0;
+	}
+
+	pr_debug("irq %lu on domain %s mapped to virtual irq %u\n",
+		hwirq, of_node_full_name(of_node), virq);
+
+	return virq;
+}
+
 /**
  * irq_create_mapping_affinity() - Map a hardware interrupt into linux irq space
  * @domain: domain owning this hardware interrupt or NULL for default domain
@@ -637,47 +703,31 @@
  * on the number returned from that call.
  */
 unsigned int irq_create_mapping_affinity(struct irq_domain *domain,
-				       irq_hw_number_t hwirq,
-				       const struct irq_affinity_desc *affinity)
+					 irq_hw_number_t hwirq,
+					 const struct irq_affinity_desc *affinity)
 {
-	struct device_node *of_node;
 	int virq;
 
-	pr_debug("irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq);
-
-	/* Look for default domain if nececssary */
+	/* Look for default domain if necessary */
 	if (domain == NULL)
 		domain = irq_default_domain;
 	if (domain == NULL) {
 		WARN(1, "%s(, %lx) called with NULL domain\n", __func__, hwirq);
 		return 0;
 	}
-	pr_debug("-> using domain @%p\n", domain);
 
-	of_node = irq_domain_get_of_node(domain);
+	mutex_lock(&irq_domain_mutex);
 
 	/* Check if mapping already exists */
 	virq = irq_find_mapping(domain, hwirq);
 	if (virq) {
-		pr_debug("-> existing mapping on virq %d\n", virq);
-		return virq;
+		pr_debug("existing mapping on virq %d\n", virq);
+		goto out;
 	}
 
-	/* Allocate a virtual interrupt number */
-	virq = irq_domain_alloc_descs(-1, 1, hwirq, of_node_to_nid(of_node),
-				      affinity);
-	if (virq <= 0) {
-		pr_debug("-> virq allocation failed\n");
-		return 0;
-	}
-
-	if (irq_domain_associate(domain, virq, hwirq)) {
-		irq_free_desc(virq);
-		return 0;
-	}
-
-	pr_debug("irq %lu on domain %s mapped to virtual irq %u\n",
-		hwirq, of_node_full_name(of_node), virq);
+	virq = irq_create_mapping_affinity_locked(domain, hwirq, affinity);
+out:
+	mutex_unlock(&irq_domain_mutex);
 
 	return virq;
 }
@@ -781,6 +831,8 @@
 	if (WARN_ON(type & ~IRQ_TYPE_SENSE_MASK))
 		type &= IRQ_TYPE_SENSE_MASK;
 
+	mutex_lock(&irq_domain_mutex);
+
 	/*
 	 * If we've already configured this interrupt,
 	 * don't do it again, or hell will break loose.
@@ -793,7 +845,7 @@
 		 * interrupt number.
 		 */
 		if (type == IRQ_TYPE_NONE || type == irq_get_trigger_type(virq))
-			return virq;
+			goto out;
 
 		/*
 		 * If the trigger type has not been set yet, then set
@@ -801,40 +853,45 @@
 		 */
 		if (irq_get_trigger_type(virq) == IRQ_TYPE_NONE) {
 			irq_data = irq_get_irq_data(virq);
-			if (!irq_data)
-				return 0;
+			if (!irq_data) {
+				virq = 0;
+				goto out;
+			}
 
 			irqd_set_trigger_type(irq_data, type);
-			return virq;
+			goto out;
 		}
 
 		pr_warn("type mismatch, failed to map hwirq-%lu for %s!\n",
 			hwirq, of_node_full_name(to_of_node(fwspec->fwnode)));
-		return 0;
+		virq = 0;
+		goto out;
 	}
 
 	if (irq_domain_is_hierarchy(domain)) {
-		virq = irq_domain_alloc_irqs(domain, 1, NUMA_NO_NODE, fwspec);
-		if (virq <= 0)
-			return 0;
+		virq = irq_domain_alloc_irqs_locked(domain, -1, 1, NUMA_NO_NODE,
+						    fwspec, false, NULL);
+		if (virq <= 0) {
+			virq = 0;
+			goto out;
+		}
 	} else {
 		/* Create mapping */
-		virq = irq_create_mapping(domain, hwirq);
+		virq = irq_create_mapping_affinity_locked(domain, hwirq, NULL);
 		if (!virq)
-			return virq;
+			goto out;
 	}
 
 	irq_data = irq_get_irq_data(virq);
-	if (!irq_data) {
-		if (irq_domain_is_hierarchy(domain))
-			irq_domain_free_irqs(virq, 1);
-		else
-			irq_dispose_mapping(virq);
-		return 0;
+	if (WARN_ON(!irq_data)) {
+		virq = 0;
+		goto out;
 	}
 
 	/* Store trigger type */
 	irqd_set_trigger_type(irq_data, type);
+out:
+	mutex_unlock(&irq_domain_mutex);
 
 	return virq;
 }
@@ -886,7 +943,7 @@
 {
 	struct irq_data *data;
 
-	/* Look for default domain if nececssary */
+	/* Look for default domain if necessary */
 	if (domain == NULL)
 		domain = irq_default_domain;
 	if (domain == NULL)
@@ -1076,12 +1133,15 @@
 	struct irq_domain *domain;
 
 	if (size)
-		domain = irq_domain_create_linear(fwnode, size, ops, host_data);
+		domain = __irq_domain_create(fwnode, size, size, 0, ops, host_data);
 	else
-		domain = irq_domain_create_tree(fwnode, ops, host_data);
+		domain = __irq_domain_create(fwnode, 0, ~0, 0, ops, host_data);
+
 	if (domain) {
 		domain->parent = parent;
 		domain->flags |= flags;
+
+		__irq_domain_publish(domain);
 	}
 
 	return domain;
@@ -1399,39 +1459,11 @@
 	return domain->ops->alloc(domain, irq_base, nr_irqs, arg);
 }
 
-/**
- * __irq_domain_alloc_irqs - Allocate IRQs from domain
- * @domain:	domain to allocate from
- * @irq_base:	allocate specified IRQ number if irq_base >= 0
- * @nr_irqs:	number of IRQs to allocate
- * @node:	NUMA node id for memory allocation
- * @arg:	domain specific argument
- * @realloc:	IRQ descriptors have already been allocated if true
- * @affinity:	Optional irq affinity mask for multiqueue devices
- *
- * Allocate IRQ numbers and initialized all data structures to support
- * hierarchy IRQ domains.
- * Parameter @realloc is mainly to support legacy IRQs.
- * Returns error code or allocated IRQ number
- *
- * The whole process to setup an IRQ has been split into two steps.
- * The first step, __irq_domain_alloc_irqs(), is to allocate IRQ
- * descriptor and required hardware resources. The second step,
- * irq_domain_activate_irq(), is to program hardwares with preallocated
- * resources. In this way, it's easier to rollback when failing to
- * allocate resources.
- */
-int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
-			    unsigned int nr_irqs, int node, void *arg,
-			    bool realloc, const struct irq_affinity_desc *affinity)
+static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base,
+					unsigned int nr_irqs, int node, void *arg,
+					bool realloc, const struct irq_affinity_desc *affinity)
 {
 	int i, ret, virq;
-
-	if (domain == NULL) {
-		domain = irq_default_domain;
-		if (WARN(!domain, "domain is NULL; cannot allocate IRQ\n"))
-			return -EINVAL;
-	}
 
 	if (realloc && irq_base >= 0) {
 		virq = irq_base;
@@ -1451,24 +1483,18 @@
 		goto out_free_desc;
 	}
 
-	mutex_lock(&irq_domain_mutex);
 	ret = irq_domain_alloc_irqs_hierarchy(domain, virq, nr_irqs, arg);
-	if (ret < 0) {
-		mutex_unlock(&irq_domain_mutex);
+	if (ret < 0)
 		goto out_free_irq_data;
-	}
 
 	for (i = 0; i < nr_irqs; i++) {
 		ret = irq_domain_trim_hierarchy(virq + i);
-		if (ret) {
-			mutex_unlock(&irq_domain_mutex);
+		if (ret)
 			goto out_free_irq_data;
-		}
 	}
-	
+
 	for (i = 0; i < nr_irqs; i++)
 		irq_domain_insert_irq(virq + i);
-	mutex_unlock(&irq_domain_mutex);
 
 	return virq;
 
@@ -1476,6 +1502,48 @@
 	irq_domain_free_irq_data(virq, nr_irqs);
 out_free_desc:
 	irq_free_descs(virq, nr_irqs);
+	return ret;
+}
+
+/**
+ * __irq_domain_alloc_irqs - Allocate IRQs from domain
+ * @domain:	domain to allocate from
+ * @irq_base:	allocate specified IRQ number if irq_base >= 0
+ * @nr_irqs:	number of IRQs to allocate
+ * @node:	NUMA node id for memory allocation
+ * @arg:	domain specific argument
+ * @realloc:	IRQ descriptors have already been allocated if true
+ * @affinity:	Optional irq affinity mask for multiqueue devices
+ *
+ * Allocate IRQ numbers and initialized all data structures to support
+ * hierarchy IRQ domains.
+ * Parameter @realloc is mainly to support legacy IRQs.
+ * Returns error code or allocated IRQ number
+ *
+ * The whole process to setup an IRQ has been split into two steps.
+ * The first step, __irq_domain_alloc_irqs(), is to allocate IRQ
+ * descriptor and required hardware resources. The second step,
+ * irq_domain_activate_irq(), is to program the hardware with preallocated
+ * resources. In this way, it's easier to rollback when failing to
+ * allocate resources.
+ */
+int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
+			    unsigned int nr_irqs, int node, void *arg,
+			    bool realloc, const struct irq_affinity_desc *affinity)
+{
+	int ret;
+
+	if (domain == NULL) {
+		domain = irq_default_domain;
+		if (WARN(!domain, "domain is NULL; cannot allocate IRQ\n"))
+			return -EINVAL;
+	}
+
+	mutex_lock(&irq_domain_mutex);
+	ret = irq_domain_alloc_irqs_locked(domain, irq_base, nr_irqs, node, arg,
+					   realloc, affinity);
+	mutex_unlock(&irq_domain_mutex);
+
 	return ret;
 }
 
@@ -1836,6 +1904,13 @@
 	irq_set_handler_data(virq, handler_data);
 }
 
+static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base,
+					unsigned int nr_irqs, int node, void *arg,
+					bool realloc, const struct irq_affinity_desc *affinity)
+{
+	return -EINVAL;
+}
+
 static void irq_domain_check_hierarchy(struct irq_domain *domain)
 {
 }
diff --git a/kernel/kernel/irq/manage.c b/kernel/kernel/irq/manage.c
index 76da8de..87b2fbf 100644
--- a/kernel/kernel/irq/manage.c
+++ b/kernel/kernel/irq/manage.c
@@ -342,7 +342,7 @@
 	 * If the interrupt is not yet activated, just store the affinity
 	 * mask and do not call the chip driver at all. On activation the
 	 * driver has to make sure anyway that the interrupt is in a
-	 * useable state so startup works.
+	 * usable state so startup works.
 	 */
 	if (!IS_ENABLED(CONFIG_IRQ_DOMAIN_HIERARCHY) ||
 	    irqd_is_activated(data) || !irqd_affinity_on_activate(data))
@@ -1000,7 +1000,7 @@
 	 * to IRQS_INPROGRESS and the irq line is masked forever.
 	 *
 	 * This also serializes the state of shared oneshot handlers
-	 * versus "desc->threads_onehsot |= action->thread_mask;" in
+	 * versus "desc->threads_oneshot |= action->thread_mask;" in
 	 * irq_wake_thread(). See the comment there which explains the
 	 * serialization.
 	 */
@@ -1668,7 +1668,8 @@
 			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 {
 			/*
@@ -1877,7 +1878,7 @@
 	/* Last action releases resources */
 	if (!desc->action) {
 		/*
-		 * Reaquire bus lock as irq_release_resources() might
+		 * Reacquire bus lock as irq_release_resources() might
 		 * require it to deallocate resources over the slow bus.
 		 */
 		chip_bus_lock(desc);
@@ -2055,10 +2056,15 @@
 	 * 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;
@@ -2214,7 +2220,8 @@
 
 	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))
diff --git a/kernel/kernel/irq/msi.c b/kernel/kernel/irq/msi.c
index b47d95b..4457f3e 100644
--- a/kernel/kernel/irq/msi.c
+++ b/kernel/kernel/irq/msi.c
@@ -5,7 +5,7 @@
  *
  * This file is licensed under GPLv2.
  *
- * This file contains common code to support Message Signalled Interrupt for
+ * This file contains common code to support Message Signaled Interrupts for
  * PCI compatible and non PCI compatible devices.
  */
 #include <linux/types.h>
diff --git a/kernel/kernel/irq/timings.c b/kernel/kernel/irq/timings.c
index 1f98116..00d45b6 100644
--- a/kernel/kernel/irq/timings.c
+++ b/kernel/kernel/irq/timings.c
@@ -490,7 +490,7 @@
 
 	/*
 	 * The interrupt triggered more than one second apart, that
-	 * ends the sequence as predictible for our purpose. In this
+	 * ends the sequence as predictable for our purpose. In this
 	 * case, assume we have the beginning of a sequence and the
 	 * timestamp is the first value. As it is impossible to
 	 * predict anything at this point, return.
diff --git a/kernel/kernel/kcsan/Makefile b/kernel/kernel/kcsan/Makefile
index 65ca553..a9b0ee6 100644
--- a/kernel/kernel/kcsan/Makefile
+++ b/kernel/kernel/kcsan/Makefile
@@ -13,5 +13,6 @@
 obj-y := core.o debugfs.o report.o
 obj-$(CONFIG_KCSAN_SELFTEST) += selftest.o
 
-CFLAGS_kcsan-test.o := $(CFLAGS_KCSAN) -g -fno-omit-frame-pointer
+CFLAGS_kcsan-test.o := $(CFLAGS_KCSAN) -fno-omit-frame-pointer
+CFLAGS_kcsan_test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
 obj-$(CONFIG_KCSAN_TEST) += kcsan-test.o
diff --git a/kernel/kernel/kcsan/core.c b/kernel/kernel/kcsan/core.c
index 23e7acb..473dc04 100644
--- a/kernel/kernel/kcsan/core.c
+++ b/kernel/kernel/kcsan/core.c
@@ -9,10 +9,12 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
+#include <linux/minmax.h>
 #include <linux/moduleparam.h>
 #include <linux/percpu.h>
 #include <linux/preempt.h>
 #include <linux/sched.h>
+#include <linux/string.h>
 #include <linux/uaccess.h>
 
 #include "atomic.h"
@@ -1033,7 +1035,9 @@
 DEFINE_TSAN_ATOMIC_OPS(8);
 DEFINE_TSAN_ATOMIC_OPS(16);
 DEFINE_TSAN_ATOMIC_OPS(32);
+#ifdef CONFIG_64BIT
 DEFINE_TSAN_ATOMIC_OPS(64);
+#endif
 
 void __tsan_atomic_thread_fence(int memorder);
 void __tsan_atomic_thread_fence(int memorder)
@@ -1045,3 +1049,51 @@
 void __tsan_atomic_signal_fence(int memorder);
 void __tsan_atomic_signal_fence(int memorder) { }
 EXPORT_SYMBOL(__tsan_atomic_signal_fence);
+
+#ifdef __HAVE_ARCH_MEMSET
+void *__tsan_memset(void *s, int c, size_t count);
+noinline void *__tsan_memset(void *s, int c, size_t count)
+{
+	/*
+	 * Instead of not setting up watchpoints where accessed size is greater
+	 * than MAX_ENCODABLE_SIZE, truncate checked size to MAX_ENCODABLE_SIZE.
+	 */
+	size_t check_len = min_t(size_t, count, MAX_ENCODABLE_SIZE);
+
+	check_access(s, check_len, KCSAN_ACCESS_WRITE);
+	return memset(s, c, count);
+}
+#else
+void *__tsan_memset(void *s, int c, size_t count) __alias(memset);
+#endif
+EXPORT_SYMBOL(__tsan_memset);
+
+#ifdef __HAVE_ARCH_MEMMOVE
+void *__tsan_memmove(void *dst, const void *src, size_t len);
+noinline void *__tsan_memmove(void *dst, const void *src, size_t len)
+{
+	size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE);
+
+	check_access(dst, check_len, KCSAN_ACCESS_WRITE);
+	check_access(src, check_len, 0);
+	return memmove(dst, src, len);
+}
+#else
+void *__tsan_memmove(void *dst, const void *src, size_t len) __alias(memmove);
+#endif
+EXPORT_SYMBOL(__tsan_memmove);
+
+#ifdef __HAVE_ARCH_MEMCPY
+void *__tsan_memcpy(void *dst, const void *src, size_t len);
+noinline void *__tsan_memcpy(void *dst, const void *src, size_t len)
+{
+	size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE);
+
+	check_access(dst, check_len, KCSAN_ACCESS_WRITE);
+	check_access(src, check_len, 0);
+	return memcpy(dst, src, len);
+}
+#else
+void *__tsan_memcpy(void *dst, const void *src, size_t len) __alias(memcpy);
+#endif
+EXPORT_SYMBOL(__tsan_memcpy);
diff --git a/kernel/kernel/kcsan/kcsan-test.c b/kernel/kernel/kcsan/kcsan-test.c
index ebe7fd2..8a8ccaf 100644
--- a/kernel/kernel/kcsan/kcsan-test.c
+++ b/kernel/kernel/kcsan/kcsan-test.c
@@ -149,13 +149,17 @@
 	const bool is_assert = (r->access[0].type | r->access[1].type) & KCSAN_ACCESS_ASSERT;
 	bool ret = false;
 	unsigned long flags;
-	typeof(observed.lines) expect;
+	typeof(*observed.lines) *expect;
 	const char *end;
 	char *cur;
 	int i;
 
 	/* Doubled-checked locking. */
 	if (!report_available())
+		return false;
+
+	expect = kmalloc(sizeof(observed.lines), GFP_KERNEL);
+	if (WARN_ON(!expect))
 		return false;
 
 	/* Generate expected report contents. */
@@ -241,6 +245,7 @@
 		strstr(observed.lines[2], expect[1])));
 out:
 	spin_unlock_irqrestore(&observed.lock, flags);
+	kfree(expect);
 	return ret;
 }
 
diff --git a/kernel/kernel/kcsan/report.c b/kernel/kernel/kcsan/report.c
index d3bf87e..069830f 100644
--- a/kernel/kernel/kcsan/report.c
+++ b/kernel/kernel/kcsan/report.c
@@ -630,8 +630,8 @@
 		bool reported = value_change != KCSAN_VALUE_CHANGE_FALSE &&
 				print_report(value_change, type, &ai, other_info);
 
-		if (reported && panic_on_warn)
-			panic("panic_on_warn set ...\n");
+		if (reported)
+			check_panic_on_warn("KCSAN");
 
 		release_report(&flags, other_info);
 	}
diff --git a/kernel/kernel/kexec.c b/kernel/kernel/kexec.c
index c82c6c0..f0f0c65 100644
--- a/kernel/kernel/kexec.c
+++ b/kernel/kernel/kexec.c
@@ -110,6 +110,14 @@
 	unsigned long i;
 	int ret;
 
+	/*
+	 * Because we write directly to the reserved memory region when loading
+	 * crash kernels we need a serialization here to prevent multiple crash
+	 * kernels from attempting to load simultaneously.
+	 */
+	if (!kexec_trylock())
+		return -EBUSY;
+
 	if (flags & KEXEC_ON_CRASH) {
 		dest_image = &kexec_crash_image;
 		if (kexec_crash_image)
@@ -121,7 +129,8 @@
 	if (nr_segments == 0) {
 		/* Uninstall image */
 		kimage_free(xchg(dest_image, NULL));
-		return 0;
+		ret = 0;
+		goto out_unlock;
 	}
 	if (flags & KEXEC_ON_CRASH) {
 		/*
@@ -134,7 +143,7 @@
 
 	ret = kimage_alloc_init(&image, entry, nr_segments, segments, flags);
 	if (ret)
-		return ret;
+		goto out_unlock;
 
 	if (flags & KEXEC_PRESERVE_CONTEXT)
 		image->preserve_context = 1;
@@ -171,6 +180,8 @@
 		arch_kexec_protect_crashkres();
 
 	kimage_free(image);
+out_unlock:
+	kexec_unlock();
 	return ret;
 }
 
@@ -247,20 +258,7 @@
 		((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH_DEFAULT))
 		return -EINVAL;
 
-	/* Because we write directly to the reserved memory
-	 * region when loading crash kernels we need a mutex here to
-	 * prevent multiple crash  kernels from attempting to load
-	 * simultaneously, and to prevent a crash kernel from loading
-	 * over the top of a in use crash kernel.
-	 *
-	 * KISS: always take the mutex.
-	 */
-	if (!mutex_trylock(&kexec_mutex))
-		return -EBUSY;
-
 	result = do_kexec_load(entry, nr_segments, segments, flags);
-
-	mutex_unlock(&kexec_mutex);
 
 	return result;
 }
@@ -301,20 +299,7 @@
 			return -EFAULT;
 	}
 
-	/* Because we write directly to the reserved memory
-	 * region when loading crash kernels we need a mutex here to
-	 * prevent multiple crash  kernels from attempting to load
-	 * simultaneously, and to prevent a crash kernel from loading
-	 * over the top of a in use crash kernel.
-	 *
-	 * KISS: always take the mutex.
-	 */
-	if (!mutex_trylock(&kexec_mutex))
-		return -EBUSY;
-
 	result = do_kexec_load(entry, nr_segments, ksegments, flags);
-
-	mutex_unlock(&kexec_mutex);
 
 	return result;
 }
diff --git a/kernel/kernel/kexec_core.c b/kernel/kernel/kexec_core.c
index c589c7a..3a37fc6 100644
--- a/kernel/kernel/kexec_core.c
+++ b/kernel/kernel/kexec_core.c
@@ -45,7 +45,7 @@
 #include <crypto/sha.h>
 #include "kexec_internal.h"
 
-DEFINE_MUTEX(kexec_mutex);
+atomic_t __kexec_lock = ATOMIC_INIT(0);
 
 /* Per cpu memory for storing cpu states in case of system crash. */
 note_buf_t __percpu *crash_notes;
@@ -943,7 +943,7 @@
  */
 void __noclone __crash_kexec(struct pt_regs *regs)
 {
-	/* Take the kexec_mutex here to prevent sys_kexec_load
+	/* Take the kexec_lock here to prevent sys_kexec_load
 	 * running on one cpu from replacing the crash kernel
 	 * we are using after a panic on a different cpu.
 	 *
@@ -951,7 +951,7 @@
 	 * of memory the xchg(&kexec_crash_image) would be
 	 * sufficient.  But since I reuse the memory...
 	 */
-	if (mutex_trylock(&kexec_mutex)) {
+	if (kexec_trylock()) {
 		if (kexec_crash_image) {
 			struct pt_regs fixed_regs;
 
@@ -960,7 +960,7 @@
 			machine_crash_shutdown(&fixed_regs);
 			machine_kexec(kexec_crash_image);
 		}
-		mutex_unlock(&kexec_mutex);
+		kexec_unlock();
 	}
 }
 STACK_FRAME_NON_STANDARD(__crash_kexec);
@@ -989,14 +989,17 @@
 	}
 }
 
-size_t crash_get_memory_size(void)
+ssize_t crash_get_memory_size(void)
 {
-	size_t size = 0;
+	ssize_t size = 0;
 
-	mutex_lock(&kexec_mutex);
+	if (!kexec_trylock())
+		return -EBUSY;
+
 	if (crashk_res.end != crashk_res.start)
 		size = resource_size(&crashk_res);
-	mutex_unlock(&kexec_mutex);
+
+	kexec_unlock();
 	return size;
 }
 
@@ -1016,7 +1019,8 @@
 	unsigned long old_size;
 	struct resource *ram_res;
 
-	mutex_lock(&kexec_mutex);
+	if (!kexec_trylock())
+		return -EBUSY;
 
 	if (kexec_crash_image) {
 		ret = -ENOENT;
@@ -1025,6 +1029,7 @@
 	start = crashk_res.start;
 	end = crashk_res.end;
 	old_size = (end == 0) ? 0 : end - start + 1;
+	new_size = roundup(new_size, KEXEC_CRASH_MEM_ALIGN);
 	if (new_size >= old_size) {
 		ret = (new_size == old_size) ? 0 : -EINVAL;
 		goto unlock;
@@ -1036,9 +1041,7 @@
 		goto unlock;
 	}
 
-	start = roundup(start, KEXEC_CRASH_MEM_ALIGN);
-	end = roundup(start + new_size, KEXEC_CRASH_MEM_ALIGN);
-
+	end = start + new_size;
 	crash_free_reserved_phys_range(end, crashk_res.end);
 
 	if ((start == end) && (crashk_res.parent != NULL))
@@ -1054,7 +1057,7 @@
 	insert_resource(&iomem_resource, ram_res);
 
 unlock:
-	mutex_unlock(&kexec_mutex);
+	kexec_unlock();
 	return ret;
 }
 
@@ -1126,7 +1129,7 @@
 {
 	int error = 0;
 
-	if (!mutex_trylock(&kexec_mutex))
+	if (!kexec_trylock())
 		return -EBUSY;
 	if (!kexec_image) {
 		error = -EINVAL;
@@ -1201,7 +1204,7 @@
 #endif
 
  Unlock:
-	mutex_unlock(&kexec_mutex);
+	kexec_unlock();
 	return error;
 }
 
diff --git a/kernel/kernel/kexec_file.c b/kernel/kernel/kexec_file.c
index fff1191..804dc50 100644
--- a/kernel/kernel/kexec_file.c
+++ b/kernel/kernel/kexec_file.c
@@ -343,7 +343,7 @@
 
 	image = NULL;
 
-	if (!mutex_trylock(&kexec_mutex))
+	if (!kexec_trylock())
 		return -EBUSY;
 
 	dest_image = &kexec_image;
@@ -415,7 +415,7 @@
 	if ((flags & KEXEC_FILE_ON_CRASH) && kexec_crash_image)
 		arch_kexec_protect_crashkres();
 
-	mutex_unlock(&kexec_mutex);
+	kexec_unlock();
 	kimage_free(image);
 	return ret;
 }
@@ -910,10 +910,22 @@
 		}
 
 		offset = ALIGN(offset, align);
+
+		/*
+		 * Check if the segment contains the entry point, if so,
+		 * calculate the value of image->start based on it.
+		 * If the compiler has produced more than one .text section
+		 * (Eg: .text.hot), they are generally after the main .text
+		 * section, and they shall not be used to calculate
+		 * image->start. So do not re-calculate image->start if it
+		 * is not set to the initial value, and warn the user so they
+		 * have a chance to fix their purgatory's linker script.
+		 */
 		if (sechdrs[i].sh_flags & SHF_EXECINSTR &&
 		    pi->ehdr->e_entry >= sechdrs[i].sh_addr &&
 		    pi->ehdr->e_entry < (sechdrs[i].sh_addr
-					 + sechdrs[i].sh_size)) {
+					 + sechdrs[i].sh_size) &&
+		    !WARN_ON(kbuf->image->start != pi->ehdr->e_entry)) {
 			kbuf->image->start -= sechdrs[i].sh_addr;
 			kbuf->image->start += kbuf->mem + offset;
 		}
diff --git a/kernel/kernel/kexec_internal.h b/kernel/kernel/kexec_internal.h
index 39d30cc..49d4e3a 100644
--- a/kernel/kernel/kexec_internal.h
+++ b/kernel/kernel/kexec_internal.h
@@ -15,7 +15,20 @@
 
 int machine_kexec_post_load(struct kimage *image);
 
-extern struct mutex kexec_mutex;
+/*
+ * Whatever is used to serialize accesses to the kexec_crash_image needs to be
+ * NMI safe, as __crash_kexec() can happen during nmi_panic(), so here we use a
+ * "simple" atomic variable that is acquired with a cmpxchg().
+ */
+extern atomic_t __kexec_lock;
+static inline bool kexec_trylock(void)
+{
+	return atomic_cmpxchg_acquire(&__kexec_lock, 0, 1) == 0;
+}
+static inline void kexec_unlock(void)
+{
+	atomic_set_release(&__kexec_lock, 0);
+}
 
 #ifdef CONFIG_KEXEC_FILE
 #include <linux/purgatory.h>
diff --git a/kernel/kernel/kheaders.c b/kernel/kernel/kheaders.c
index 8f69772..42163c9 100644
--- a/kernel/kernel/kheaders.c
+++ b/kernel/kernel/kheaders.c
@@ -26,15 +26,15 @@
 "	.popsection				\n"
 );
 
-extern char kernel_headers_data;
-extern char kernel_headers_data_end;
+extern char kernel_headers_data[];
+extern char kernel_headers_data_end[];
 
 static ssize_t
 ikheaders_read(struct file *file,  struct kobject *kobj,
 	       struct bin_attribute *bin_attr,
 	       char *buf, loff_t off, size_t len)
 {
-	memcpy(buf, &kernel_headers_data + off, len);
+	memcpy(buf, &kernel_headers_data[off], len);
 	return len;
 }
 
@@ -48,8 +48,8 @@
 
 static int __init ikheaders_init(void)
 {
-	kheaders_attr.size = (&kernel_headers_data_end -
-			      &kernel_headers_data);
+	kheaders_attr.size = (kernel_headers_data_end -
+			      kernel_headers_data);
 	return sysfs_create_bin_file(kernel_kobj, &kheaders_attr);
 }
 
diff --git a/kernel/kernel/kprobes.c b/kernel/kernel/kprobes.c
index 75150e7..f1ea312 100644
--- a/kernel/kernel/kprobes.c
+++ b/kernel/kernel/kprobes.c
@@ -447,8 +447,8 @@
 	return 0;
 }
 
-/* Return true(!0) if the kprobe is disarmed. Note: p must be on hash list */
-static inline int kprobe_disarmed(struct kprobe *p)
+/* Return true if the kprobe is disarmed. Note: p must be on hash list */
+bool kprobe_disarmed(struct kprobe *p)
 {
 	struct optimized_kprobe *op;
 
@@ -652,7 +652,7 @@
 	mutex_unlock(&kprobe_mutex);
 }
 
-static bool optprobe_queued_unopt(struct optimized_kprobe *op)
+bool optprobe_queued_unopt(struct optimized_kprobe *op)
 {
 	struct optimized_kprobe *_op;
 
@@ -1628,6 +1628,17 @@
 	return 0;
 }
 
+static bool is_cfi_preamble_symbol(unsigned long addr)
+{
+	char symbuf[KSYM_NAME_LEN];
+
+	if (lookup_symbol_name(addr, symbuf))
+		return false;
+
+	return str_has_prefix("__cfi_", symbuf) ||
+		str_has_prefix("__pfx_", symbuf);
+}
+
 static int check_kprobe_address_safe(struct kprobe *p,
 				     struct module **probed_mod)
 {
@@ -1646,7 +1657,8 @@
 	    within_kprobe_blacklist((unsigned long) p->addr) ||
 	    jump_label_text_reserved(p->addr, p->addr) ||
 	    static_call_text_reserved(p->addr, p->addr) ||
-	    find_bug((unsigned long)p->addr)) {
+	    find_bug((unsigned long)p->addr) ||
+	    is_cfi_preamble_symbol((unsigned long)p->addr)) {
 		ret = -EINVAL;
 		goto out;
 	}
diff --git a/kernel/kernel/ksysfs.c b/kernel/kernel/ksysfs.c
index 35859da..e20c19e 100644
--- a/kernel/kernel/ksysfs.c
+++ b/kernel/kernel/ksysfs.c
@@ -106,7 +106,12 @@
 static ssize_t kexec_crash_size_show(struct kobject *kobj,
 				       struct kobj_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%zu\n", crash_get_memory_size());
+	ssize_t size = crash_get_memory_size();
+
+	if (size < 0)
+		return size;
+
+	return sprintf(buf, "%zd\n", size);
 }
 static ssize_t kexec_crash_size_store(struct kobject *kobj,
 				   struct kobj_attribute *attr,
diff --git a/kernel/kernel/locking/mutex.c b/kernel/kernel/locking/mutex.c
index 93020a8..943f6c3 100644
--- a/kernel/kernel/locking/mutex.c
+++ b/kernel/kernel/locking/mutex.c
@@ -568,9 +568,16 @@
 			 struct ww_acquire_ctx *ww_ctx, struct mutex_waiter *waiter)
 {
 	bool ret = true;
+	int cnt = 0;
+	bool time_out = false;
 
 	rcu_read_lock();
 	while (__mutex_owner(lock) == owner) {
+		trace_android_vh_mutex_opt_spin_start(lock, &time_out, &cnt);
+		if (time_out) {
+			ret = false;
+			break;
+		}
 		/*
 		 * Ensure we emit the owner->on_cpu, dereference _after_
 		 * checking lock->owner still matches owner. If that fails,
@@ -621,6 +628,7 @@
 	if (owner)
 		retval = owner->on_cpu && !vcpu_is_preempted(task_cpu(owner));
 	rcu_read_unlock();
+	trace_android_vh_mutex_can_spin_on_owner(lock, &retval);
 
 	/*
 	 * If lock->owner is not set, the mutex has been released. Return true
@@ -702,6 +710,7 @@
 	if (!waiter)
 		osq_unlock(&lock->osq);
 
+	trace_android_vh_mutex_opt_spin_finish(lock, true);
 	return true;
 
 
@@ -710,6 +719,7 @@
 		osq_unlock(&lock->osq);
 
 fail:
+	trace_android_vh_mutex_opt_spin_finish(lock, false);
 	/*
 	 * If we fell out of the spin path because of need_resched(),
 	 * reschedule now, before we try-lock the mutex. This avoids getting
@@ -750,12 +760,14 @@
  */
 void __sched mutex_unlock(struct mutex *lock)
 {
-	trace_android_vh_record_mutex_lock_starttime(current, 0);
 #ifndef CONFIG_DEBUG_LOCK_ALLOC
-	if (__mutex_unlock_fast(lock))
+	if (__mutex_unlock_fast(lock)) {
+		trace_android_vh_record_mutex_lock_starttime(current, 0);
 		return;
+	}
 #endif
 	__mutex_unlock_slowpath(lock, _RET_IP_);
+	trace_android_vh_record_mutex_lock_starttime(current, 0);
 }
 EXPORT_SYMBOL(mutex_unlock);
 
diff --git a/kernel/kernel/locking/percpu-rwsem.c b/kernel/kernel/locking/percpu-rwsem.c
index c8a474a..b00db54 100644
--- a/kernel/kernel/locking/percpu-rwsem.c
+++ b/kernel/kernel/locking/percpu-rwsem.c
@@ -166,6 +166,7 @@
 	if (wait) {
 		wq_entry.flags |= WQ_FLAG_EXCLUSIVE | reader * WQ_FLAG_CUSTOM;
 		__add_wait_queue_entry_tail(&sem->waiters, &wq_entry);
+		trace_android_vh_percpu_rwsem_wq_add(sem, reader);
 	}
 	spin_unlock_irq(&sem->waiters.lock);
 
@@ -258,7 +259,6 @@
 
 void percpu_up_write(struct percpu_rw_semaphore *sem)
 {
-	trace_android_vh_record_pcpu_rwsem_starttime(current, 0);
 	rwsem_release(&sem->dep_map, _RET_IP_);
 
 	/*
@@ -284,6 +284,7 @@
 	 * exclusive write lock because its counting.
 	 */
 	rcu_sync_exit(&sem->rss);
+	trace_android_vh_record_pcpu_rwsem_starttime(current, 0);
 }
 EXPORT_SYMBOL_GPL(percpu_up_write);
 
diff --git a/kernel/kernel/locking/rwsem.c b/kernel/kernel/locking/rwsem.c
index d368d1a..acd1fc7 100644
--- a/kernel/kernel/locking/rwsem.c
+++ b/kernel/kernel/locking/rwsem.c
@@ -673,6 +673,7 @@
 		ret = false;
 	rcu_read_unlock();
 	preempt_enable();
+	trace_android_vh_rwsem_can_spin_on_owner(sem, &ret, nonspinnable == RWSEM_WR_NONSPINNABLE);
 
 	lockevent_cond_inc(rwsem_opt_fail, !ret);
 	return ret;
@@ -715,6 +716,8 @@
 	struct task_struct *new, *owner;
 	unsigned long flags, new_flags;
 	enum owner_state state;
+	int cnt = 0;
+	bool time_out = false;
 
 	owner = rwsem_owner_flags(sem, &flags);
 	state = rwsem_owner_state(owner, flags, nonspinnable);
@@ -723,6 +726,9 @@
 
 	rcu_read_lock();
 	for (;;) {
+		trace_android_vh_rwsem_opt_spin_start(sem, &time_out, &cnt, true);
+		if (time_out)
+			break;
 		/*
 		 * When a waiting writer set the handoff flag, it may spin
 		 * on the owner as well. Once that writer acquires the lock,
@@ -786,6 +792,8 @@
 	int prev_owner_state = OWNER_NULL;
 	int loop = 0;
 	u64 rspin_threshold = 0;
+	int cnt = 0;
+	bool time_out = false;
 	unsigned long nonspinnable = wlock ? RWSEM_WR_NONSPINNABLE
 					   : RWSEM_RD_NONSPINNABLE;
 
@@ -803,6 +811,10 @@
 	 */
 	for (;;) {
 		enum owner_state owner_state;
+
+		trace_android_vh_rwsem_opt_spin_start(sem, &time_out, &cnt, false);
+		if (time_out)
+			break;
 
 		owner_state = rwsem_spin_on_owner(sem, nonspinnable);
 		if (!(owner_state & OWNER_SPINNABLE))
@@ -898,6 +910,7 @@
 		cpu_relax();
 	}
 	osq_unlock(&sem->osq);
+	trace_android_vh_rwsem_opt_spin_finish(sem, taken, wlock);
 done:
 	preempt_enable();
 	lockevent_cond_inc(rwsem_opt_fail, !taken);
@@ -1053,6 +1066,8 @@
 			raw_spin_unlock_irq(&sem->wait_lock);
 			rwsem_set_reader_owned(sem);
 			lockevent_inc(rwsem_rlock_fast);
+			trace_android_vh_record_rwsem_lock_starttime(
+							current, jiffies);
 			return sem;
 		}
 		adjustment += RWSEM_FLAG_WAITERS;
diff --git a/kernel/kernel/module.c b/kernel/kernel/module.c
index 91b5084..93fade9 100644
--- a/kernel/kernel/module.c
+++ b/kernel/kernel/module.c
@@ -2285,19 +2285,30 @@
 void *__symbol_get(const char *symbol)
 {
 	struct module *owner;
+	enum mod_license license;
 	const struct kernel_symbol *sym;
 
 	preempt_disable();
-	sym = find_symbol(symbol, &owner, NULL, NULL, true, true);
-	if (sym && strong_try_module_get(owner))
+	sym = find_symbol(symbol, &owner, NULL, &license, true, true);
+	if (!sym)
+		goto fail;
+	if (license != GPL_ONLY) {
+		pr_warn("failing symbol_get of non-GPLONLY symbol %s.\n",
+			symbol);
+		goto fail;
+	}
+	if (strong_try_module_get(owner))
 		sym = NULL;
 	preempt_enable();
 
 	return sym ? (void *)kernel_symbol_value(sym) : NULL;
+fail:
+	preempt_enable();
+	return NULL;
 }
 EXPORT_SYMBOL_GPL(__symbol_get);
 
-static bool module_init_layout_section(const char *sname)
+bool module_init_layout_section(const char *sname)
 {
 #ifndef CONFIG_MODULE_UNLOAD
 	if (module_exit_section(sname))
@@ -3686,7 +3697,8 @@
 	sched_annotate_sleep();
 	mutex_lock(&module_mutex);
 	mod = find_module_all(name, strlen(name), true);
-	ret = !mod || mod->state == MODULE_STATE_LIVE;
+	ret = !mod || mod->state == MODULE_STATE_LIVE
+		|| mod->state == MODULE_STATE_GOING;
 	mutex_unlock(&module_mutex);
 
 	return ret;
@@ -3857,20 +3869,35 @@
 
 	mod->state = MODULE_STATE_UNFORMED;
 
-again:
 	mutex_lock(&module_mutex);
 	old = find_module_all(mod->name, strlen(mod->name), true);
 	if (old != NULL) {
-		if (old->state != MODULE_STATE_LIVE) {
+		if (old->state == MODULE_STATE_COMING
+		    || old->state == MODULE_STATE_UNFORMED) {
 			/* Wait in case it fails to load. */
 			mutex_unlock(&module_mutex);
 			err = wait_event_interruptible(module_wq,
 					       finished_loading(mod->name));
 			if (err)
 				goto out_unlocked;
-			goto again;
+
+			/* The module might have gone in the meantime. */
+			mutex_lock(&module_mutex);
+			old = find_module_all(mod->name, strlen(mod->name),
+					      true);
 		}
-		err = -EEXIST;
+
+		/*
+		 * We are here only when the same module was being loaded. Do
+		 * not try to load it again right now. It prevents long delays
+		 * caused by serialized module load failures. It might happen
+		 * when more devices of the same type trigger load of
+		 * a particular module.
+		 */
+		if (old && old->state == MODULE_STATE_LIVE)
+			err = -EEXIST;
+		else
+			err = -EBUSY;
 		goto out;
 	}
 	mod_update_bounds(mod);
diff --git a/kernel/kernel/padata.c b/kernel/kernel/padata.c
index d4d3ba6..11ca3eb 100644
--- a/kernel/kernel/padata.c
+++ b/kernel/kernel/padata.c
@@ -220,14 +220,16 @@
 	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;
@@ -401,13 +403,16 @@
 	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);
 
 	/*
diff --git a/kernel/kernel/panic.c b/kernel/kernel/panic.c
index 332736a..bc39e2b 100644
--- a/kernel/kernel/panic.c
+++ b/kernel/kernel/panic.c
@@ -31,6 +31,7 @@
 #include <linux/bug.h>
 #include <linux/ratelimit.h>
 #include <linux/debugfs.h>
+#include <linux/sysfs.h>
 #include <asm/sections.h>
 
 #define PANIC_TIMER_STEP 100
@@ -41,7 +42,9 @@
  * Should we dump all CPUs backtraces in an oops event?
  * Defaults to 0, can be changed via sysctl.
  */
-unsigned int __read_mostly sysctl_oops_all_cpu_backtrace;
+static unsigned int __read_mostly sysctl_oops_all_cpu_backtrace;
+#else
+#define sysctl_oops_all_cpu_backtrace 0
 #endif /* CONFIG_SMP */
 
 int panic_on_oops = CONFIG_PANIC_ON_OOPS_VALUE;
@@ -54,6 +57,7 @@
 int panic_on_warn __read_mostly;
 unsigned long panic_on_taint;
 bool panic_on_taint_nousertaint = false;
+static unsigned int warn_limit __read_mostly;
 
 int panic_timeout = CONFIG_PANIC_TIMEOUT;
 EXPORT_SYMBOL_GPL(panic_timeout);
@@ -69,6 +73,56 @@
 ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
 
 EXPORT_SYMBOL(panic_notifier_list);
+
+#ifdef CONFIG_SYSCTL
+static struct ctl_table kern_panic_table[] = {
+#ifdef CONFIG_SMP
+	{
+		.procname       = "oops_all_cpu_backtrace",
+		.data           = &sysctl_oops_all_cpu_backtrace,
+		.maxlen         = sizeof(int),
+		.mode           = 0644,
+		.proc_handler   = proc_dointvec_minmax,
+		.extra1         = SYSCTL_ZERO,
+		.extra2         = SYSCTL_ONE,
+	},
+#endif
+	{
+		.procname       = "warn_limit",
+		.data           = &warn_limit,
+		.maxlen         = sizeof(warn_limit),
+		.mode           = 0644,
+		.proc_handler   = proc_douintvec,
+	},
+	{ }
+};
+
+static __init int kernel_panic_sysctls_init(void)
+{
+	register_sysctl_init("kernel", kern_panic_table);
+	return 0;
+}
+late_initcall(kernel_panic_sysctls_init);
+#endif
+
+static atomic_t warn_count = ATOMIC_INIT(0);
+
+#ifdef CONFIG_SYSFS
+static ssize_t warn_count_show(struct kobject *kobj, struct kobj_attribute *attr,
+			       char *page)
+{
+	return sysfs_emit(page, "%d\n", atomic_read(&warn_count));
+}
+
+static struct kobj_attribute warn_count_attr = __ATTR_RO(warn_count);
+
+static __init int kernel_panic_sysfs_init(void)
+{
+	sysfs_add_file_to_group(kernel_kobj, &warn_count_attr.attr, NULL);
+	return 0;
+}
+late_initcall(kernel_panic_sysfs_init);
+#endif
 
 static long no_blink(int state)
 {
@@ -166,6 +220,19 @@
 		ftrace_dump(DUMP_ALL);
 }
 
+void check_panic_on_warn(const char *origin)
+{
+	unsigned int limit;
+
+	if (panic_on_warn)
+		panic("%s: panic_on_warn set ...\n", origin);
+
+	limit = READ_ONCE(warn_limit);
+	if (atomic_inc_return(&warn_count) >= limit && limit)
+		panic("%s: system warned too often (kernel.warn_limit is %d)",
+		      origin, limit);
+}
+
 /**
  *	panic - halt the system
  *	@fmt: The text string to print
@@ -182,6 +249,16 @@
 	int state = 0;
 	int old_cpu, this_cpu;
 	bool _crash_kexec_post_notifiers = crash_kexec_post_notifiers;
+
+	if (panic_on_warn) {
+		/*
+		 * This thread may hit another WARN() in the panic path.
+		 * Resetting this prevents additional WARN() from panicking the
+		 * system on this thread.  Other threads are blocked by the
+		 * panic_mutex in panic().
+		 */
+		panic_on_warn = 0;
+	}
 
 	/*
 	 * Disable local interrupts. This will prevent panic_smp_self_stop
@@ -594,16 +671,7 @@
 	if (regs)
 		show_regs(regs);
 
-	if (panic_on_warn) {
-		/*
-		 * This thread may hit another WARN() in the panic path.
-		 * Resetting this prevents additional WARN() from panicking the
-		 * system on this thread.  Other threads are blocked by the
-		 * panic_mutex in panic().
-		 */
-		panic_on_warn = 0;
-		panic("panic_on_warn set ...\n");
-	}
+	check_panic_on_warn("kernel");
 
 	if (!regs)
 		dump_stack();
diff --git a/kernel/kernel/pid_namespace.c b/kernel/kernel/pid_namespace.c
index ef8733e..2024368 100644
--- a/kernel/kernel/pid_namespace.c
+++ b/kernel/kernel/pid_namespace.c
@@ -251,7 +251,24 @@
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (pid_ns->pid_allocated == init_pids)
 			break;
+		/*
+		 * Release tasks_rcu_exit_srcu to avoid following deadlock:
+		 *
+		 * 1) TASK A unshare(CLONE_NEWPID)
+		 * 2) TASK A fork() twice -> TASK B (child reaper for new ns)
+		 *    and TASK C
+		 * 3) TASK B exits, kills TASK C, waits for TASK A to reap it
+		 * 4) TASK A calls synchronize_rcu_tasks()
+		 *                   -> synchronize_srcu(tasks_rcu_exit_srcu)
+		 * 5) *DEADLOCK*
+		 *
+		 * It is considered safe to release tasks_rcu_exit_srcu here
+		 * because we assume the current task can not be concurrently
+		 * reaped at this point.
+		 */
+		exit_tasks_rcu_stop();
 		schedule();
+		exit_tasks_rcu_start();
 	}
 	__set_current_state(TASK_RUNNING);
 
diff --git a/kernel/kernel/power/energy_model.c b/kernel/kernel/power/energy_model.c
index 4143012..c2c858c 100644
--- a/kernel/kernel/power/energy_model.c
+++ b/kernel/kernel/power/energy_model.c
@@ -85,10 +85,7 @@
 
 static void em_debug_remove_pd(struct device *dev)
 {
-	struct dentry *debug_dir;
-
-	debug_dir = debugfs_lookup(dev_name(dev), rootdir);
-	debugfs_remove_recursive(debug_dir);
+	debugfs_lookup_and_remove(dev_name(dev), rootdir);
 }
 
 static int __init em_debug_init(void)
diff --git a/kernel/kernel/power/snapshot.c b/kernel/kernel/power/snapshot.c
index 6a71543..c60ed74 100644
--- a/kernel/kernel/power/snapshot.c
+++ b/kernel/kernel/power/snapshot.c
@@ -1685,8 +1685,8 @@
  * /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.
  *
diff --git a/kernel/kernel/printk/printk_ringbuffer.c b/kernel/kernel/printk/printk_ringbuffer.c
index b77c415..8ce46ba 100644
--- a/kernel/kernel/printk/printk_ringbuffer.c
+++ b/kernel/kernel/printk/printk_ringbuffer.c
@@ -1737,7 +1737,7 @@
 	if (!buf || !buf_size)
 		return true;
 
-	data_size = min_t(u16, buf_size, len);
+	data_size = min_t(unsigned int, buf_size, len);
 
 	memcpy(&buf[0], data, data_size); /* LMM(copy_data:A) */
 	return true;
diff --git a/kernel/kernel/rcu/rcuscale.c b/kernel/kernel/rcu/rcuscale.c
index 2819b95..3b9783e 100644
--- a/kernel/kernel/rcu/rcuscale.c
+++ b/kernel/kernel/rcu/rcuscale.c
@@ -49,8 +49,8 @@
 	pr_alert("%s" SCALE_FLAG " %s\n", scale_type, s)
 #define VERBOSE_SCALEOUT_STRING(s) \
 	do { if (verbose) pr_alert("%s" SCALE_FLAG " %s\n", scale_type, s); } while (0)
-#define VERBOSE_SCALEOUT_ERRSTRING(s) \
-	do { if (verbose) pr_alert("%s" SCALE_FLAG "!!! %s\n", scale_type, s); } while (0)
+#define SCALEOUT_ERRSTRING(s) \
+	pr_alert("%s" SCALE_FLAG "!!! %s\n", scale_type, s)
 
 /*
  * The intended use cases for the nreaders and nwriters module parameters
@@ -372,7 +372,7 @@
 	sched_set_fifo_low(current);
 
 	if (holdoff)
-		schedule_timeout_uninterruptible(holdoff * HZ);
+		schedule_timeout_idle(holdoff * HZ);
 
 	/*
 	 * Wait until rcu_end_inkernel_boot() is called for normal GP tests
@@ -457,7 +457,7 @@
 	if (gp_async) {
 		cur_ops->gp_barrier();
 	}
-	writer_n_durations[me] = i_max;
+	writer_n_durations[me] = i_max + 1;
 	torture_kthread_stopping("rcu_scale_writer");
 	return 0;
 }
@@ -468,89 +468,6 @@
 	pr_alert("%s" SCALE_FLAG
 		 "--- %s: nreaders=%d nwriters=%d verbose=%d shutdown=%d\n",
 		 scale_type, tag, nrealreaders, nrealwriters, verbose, shutdown);
-}
-
-static void
-rcu_scale_cleanup(void)
-{
-	int i;
-	int j;
-	int ngps = 0;
-	u64 *wdp;
-	u64 *wdpp;
-
-	/*
-	 * Would like warning at start, but everything is expedited
-	 * during the mid-boot phase, so have to wait till the end.
-	 */
-	if (rcu_gp_is_expedited() && !rcu_gp_is_normal() && !gp_exp)
-		VERBOSE_SCALEOUT_ERRSTRING("All grace periods expedited, no normal ones to measure!");
-	if (rcu_gp_is_normal() && gp_exp)
-		VERBOSE_SCALEOUT_ERRSTRING("All grace periods normal, no expedited ones to measure!");
-	if (gp_exp && gp_async)
-		VERBOSE_SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!");
-
-	if (torture_cleanup_begin())
-		return;
-	if (!cur_ops) {
-		torture_cleanup_end();
-		return;
-	}
-
-	if (reader_tasks) {
-		for (i = 0; i < nrealreaders; i++)
-			torture_stop_kthread(rcu_scale_reader,
-					     reader_tasks[i]);
-		kfree(reader_tasks);
-	}
-
-	if (writer_tasks) {
-		for (i = 0; i < nrealwriters; i++) {
-			torture_stop_kthread(rcu_scale_writer,
-					     writer_tasks[i]);
-			if (!writer_n_durations)
-				continue;
-			j = writer_n_durations[i];
-			pr_alert("%s%s writer %d gps: %d\n",
-				 scale_type, SCALE_FLAG, i, j);
-			ngps += j;
-		}
-		pr_alert("%s%s start: %llu end: %llu duration: %llu gps: %d batches: %ld\n",
-			 scale_type, SCALE_FLAG,
-			 t_rcu_scale_writer_started, t_rcu_scale_writer_finished,
-			 t_rcu_scale_writer_finished -
-			 t_rcu_scale_writer_started,
-			 ngps,
-			 rcuscale_seq_diff(b_rcu_gp_test_finished,
-					   b_rcu_gp_test_started));
-		for (i = 0; i < nrealwriters; i++) {
-			if (!writer_durations)
-				break;
-			if (!writer_n_durations)
-				continue;
-			wdpp = writer_durations[i];
-			if (!wdpp)
-				continue;
-			for (j = 0; j <= writer_n_durations[i]; j++) {
-				wdp = &wdpp[j];
-				pr_alert("%s%s %4d writer-duration: %5d %llu\n",
-					scale_type, SCALE_FLAG,
-					i, j, *wdp);
-				if (j % 100 == 0)
-					schedule_timeout_uninterruptible(1);
-			}
-			kfree(writer_durations[i]);
-		}
-		kfree(writer_tasks);
-		kfree(writer_durations);
-		kfree(writer_n_durations);
-	}
-
-	/* Do torture-type-specific cleanup operations.  */
-	if (cur_ops->cleanup != NULL)
-		cur_ops->cleanup();
-
-	torture_cleanup_end();
 }
 
 /*
@@ -570,21 +487,6 @@
 			nr = 1;
 	}
 	return nr;
-}
-
-/*
- * RCU scalability shutdown kthread.  Just waits to be awakened, then shuts
- * down system.
- */
-static int
-rcu_scale_shutdown(void *arg)
-{
-	wait_event(shutdown_wq,
-		   atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters);
-	smp_mb(); /* Wake before output. */
-	rcu_scale_cleanup();
-	kernel_power_off();
-	return -EINVAL;
 }
 
 /*
@@ -693,8 +595,8 @@
 static int
 kfree_scale_shutdown(void *arg)
 {
-	wait_event(shutdown_wq,
-		   atomic_read(&n_kfree_scale_thread_ended) >= kfree_nrealthreads);
+	wait_event_idle(shutdown_wq,
+			atomic_read(&n_kfree_scale_thread_ended) >= kfree_nrealthreads);
 
 	smp_mb(); /* Wake before output. */
 
@@ -746,6 +648,108 @@
 	torture_init_end();
 	kfree_scale_cleanup();
 	return firsterr;
+}
+
+static void
+rcu_scale_cleanup(void)
+{
+	int i;
+	int j;
+	int ngps = 0;
+	u64 *wdp;
+	u64 *wdpp;
+
+	/*
+	 * Would like warning at start, but everything is expedited
+	 * during the mid-boot phase, so have to wait till the end.
+	 */
+	if (rcu_gp_is_expedited() && !rcu_gp_is_normal() && !gp_exp)
+		SCALEOUT_ERRSTRING("All grace periods expedited, no normal ones to measure!");
+	if (rcu_gp_is_normal() && gp_exp)
+		SCALEOUT_ERRSTRING("All grace periods normal, no expedited ones to measure!");
+	if (gp_exp && gp_async)
+		SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!");
+
+	if (kfree_rcu_test) {
+		kfree_scale_cleanup();
+		return;
+	}
+
+	if (torture_cleanup_begin())
+		return;
+	if (!cur_ops) {
+		torture_cleanup_end();
+		return;
+	}
+
+	if (reader_tasks) {
+		for (i = 0; i < nrealreaders; i++)
+			torture_stop_kthread(rcu_scale_reader,
+					     reader_tasks[i]);
+		kfree(reader_tasks);
+	}
+
+	if (writer_tasks) {
+		for (i = 0; i < nrealwriters; i++) {
+			torture_stop_kthread(rcu_scale_writer,
+					     writer_tasks[i]);
+			if (!writer_n_durations)
+				continue;
+			j = writer_n_durations[i];
+			pr_alert("%s%s writer %d gps: %d\n",
+				 scale_type, SCALE_FLAG, i, j);
+			ngps += j;
+		}
+		pr_alert("%s%s start: %llu end: %llu duration: %llu gps: %d batches: %ld\n",
+			 scale_type, SCALE_FLAG,
+			 t_rcu_scale_writer_started, t_rcu_scale_writer_finished,
+			 t_rcu_scale_writer_finished -
+			 t_rcu_scale_writer_started,
+			 ngps,
+			 rcuscale_seq_diff(b_rcu_gp_test_finished,
+					   b_rcu_gp_test_started));
+		for (i = 0; i < nrealwriters; i++) {
+			if (!writer_durations)
+				break;
+			if (!writer_n_durations)
+				continue;
+			wdpp = writer_durations[i];
+			if (!wdpp)
+				continue;
+			for (j = 0; j < writer_n_durations[i]; j++) {
+				wdp = &wdpp[j];
+				pr_alert("%s%s %4d writer-duration: %5d %llu\n",
+					scale_type, SCALE_FLAG,
+					i, j, *wdp);
+				if (j % 100 == 0)
+					schedule_timeout_uninterruptible(1);
+			}
+			kfree(writer_durations[i]);
+		}
+		kfree(writer_tasks);
+		kfree(writer_durations);
+		kfree(writer_n_durations);
+	}
+
+	/* Do torture-type-specific cleanup operations.  */
+	if (cur_ops->cleanup != NULL)
+		cur_ops->cleanup();
+
+	torture_cleanup_end();
+}
+
+/*
+ * RCU scalability shutdown kthread.  Just waits to be awakened, then shuts
+ * down system.
+ */
+static int
+rcu_scale_shutdown(void *arg)
+{
+	wait_event_idle(shutdown_wq, atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters);
+	smp_mb(); /* Wake before output. */
+	rcu_scale_cleanup();
+	kernel_power_off();
+	return -EINVAL;
 }
 
 static int __init
@@ -803,7 +807,7 @@
 	reader_tasks = kcalloc(nrealreaders, sizeof(reader_tasks[0]),
 			       GFP_KERNEL);
 	if (reader_tasks == NULL) {
-		VERBOSE_SCALEOUT_ERRSTRING("out of memory");
+		SCALEOUT_ERRSTRING("out of memory");
 		firsterr = -ENOMEM;
 		goto unwind;
 	}
@@ -823,7 +827,7 @@
 		kcalloc(nrealwriters, sizeof(*writer_n_durations),
 			GFP_KERNEL);
 	if (!writer_tasks || !writer_durations || !writer_n_durations) {
-		VERBOSE_SCALEOUT_ERRSTRING("out of memory");
+		SCALEOUT_ERRSTRING("out of memory");
 		firsterr = -ENOMEM;
 		goto unwind;
 	}
diff --git a/kernel/kernel/rcu/refscale.c b/kernel/kernel/rcu/refscale.c
index 952595c..dbd6703 100644
--- a/kernel/kernel/rcu/refscale.c
+++ b/kernel/kernel/rcu/refscale.c
@@ -625,7 +625,7 @@
 static int
 ref_scale_shutdown(void *arg)
 {
-	wait_event(shutdown_wq, shutdown_start);
+	wait_event_idle(shutdown_wq, shutdown_start);
 
 	smp_mb(); // Wake before output.
 	ref_scale_cleanup();
@@ -692,12 +692,11 @@
 	VERBOSE_SCALEOUT("Starting %d reader threads\n", nreaders);
 
 	for (i = 0; i < nreaders; i++) {
+		init_waitqueue_head(&reader_tasks[i].wq);
 		firsterr = torture_create_kthread(ref_scale_reader, (void *)i,
 						  reader_tasks[i].task);
 		if (firsterr)
 			goto unwind;
-
-		init_waitqueue_head(&(reader_tasks[i].wq));
 	}
 
 	// Main Task
diff --git a/kernel/kernel/rcu/tasks.h b/kernel/kernel/rcu/tasks.h
index 8b51e6a..0b501c3 100644
--- a/kernel/kernel/rcu/tasks.h
+++ b/kernel/kernel/rcu/tasks.h
@@ -171,8 +171,9 @@
 static void synchronize_rcu_tasks_generic(struct rcu_tasks *rtp)
 {
 	/* Complain if the scheduler has not started.  */
-	WARN_ONCE(rcu_scheduler_active == RCU_SCHEDULER_INACTIVE,
-			 "synchronize_rcu_tasks called too soon");
+	if (WARN_ONCE(rcu_scheduler_active == RCU_SCHEDULER_INACTIVE,
+			 "synchronize_%s() called too soon", rtp->name))
+		return;
 
 	/* Wait for the grace period. */
 	wait_rcu_gp(rtp->call_func);
@@ -416,11 +417,21 @@
 static void rcu_tasks_postscan(struct list_head *hop)
 {
 	/*
-	 * Wait for tasks that are in the process of exiting.  This
-	 * does only part of the job, ensuring that all tasks that were
-	 * previously exiting reach the point where they have disabled
-	 * preemption, allowing the later synchronize_rcu() to finish
-	 * the job.
+	 * Exiting tasks may escape the tasklist scan. Those are vulnerable
+	 * until their final schedule() with TASK_DEAD state. To cope with
+	 * this, divide the fragile exit path part in two intersecting
+	 * read side critical sections:
+	 *
+	 * 1) An _SRCU_ read side starting before calling exit_notify(),
+	 *    which may remove the task from the tasklist, and ending after
+	 *    the final preempt_disable() call in do_exit().
+	 *
+	 * 2) An _RCU_ read side starting with the final preempt_disable()
+	 *    call in do_exit() and ending with the final call to schedule()
+	 *    with TASK_DEAD state.
+	 *
+	 * This handles the part 1). And postgp will handle part 2) with a
+	 * call to synchronize_rcu().
 	 */
 	synchronize_srcu(&tasks_rcu_exit_srcu);
 }
@@ -487,7 +498,10 @@
 	 *
 	 * In addition, this synchronize_rcu() waits for exiting tasks
 	 * to complete their final preempt_disable() region of execution,
-	 * cleaning up after the synchronize_srcu() above.
+	 * cleaning up after synchronize_srcu(&tasks_rcu_exit_srcu),
+	 * enforcing the whole region before tasklist removal until
+	 * the final schedule() with TASK_DEAD state to be an RCU TASKS
+	 * read side critical section.
 	 */
 	synchronize_rcu();
 }
@@ -576,28 +590,43 @@
 }
 #endif /* #ifndef CONFIG_TINY_RCU */
 
-/* Do the srcu_read_lock() for the above synchronize_srcu().  */
+/*
+ * Contribute to protect against tasklist scan blind spot while the
+ * task is exiting and may be removed from the tasklist. See
+ * corresponding synchronize_srcu() for further details.
+ */
 void exit_tasks_rcu_start(void) __acquires(&tasks_rcu_exit_srcu)
 {
-	preempt_disable();
 	current->rcu_tasks_idx = __srcu_read_lock(&tasks_rcu_exit_srcu);
-	preempt_enable();
 }
 
-/* Do the srcu_read_unlock() for the above synchronize_srcu().  */
-void exit_tasks_rcu_finish(void) __releases(&tasks_rcu_exit_srcu)
+/*
+ * Contribute to protect against tasklist scan blind spot while the
+ * task is exiting and may be removed from the tasklist. See
+ * corresponding synchronize_srcu() for further details.
+ */
+void exit_tasks_rcu_stop(void) __releases(&tasks_rcu_exit_srcu)
 {
 	struct task_struct *t = current;
 
-	preempt_disable();
 	__srcu_read_unlock(&tasks_rcu_exit_srcu, t->rcu_tasks_idx);
-	preempt_enable();
-	exit_tasks_rcu_finish_trace(t);
+}
+
+/*
+ * Contribute to protect against tasklist scan blind spot while the
+ * task is exiting and may be removed from the tasklist. See
+ * corresponding synchronize_srcu() for further details.
+ */
+void exit_tasks_rcu_finish(void)
+{
+	exit_tasks_rcu_stop();
+	exit_tasks_rcu_finish_trace(current);
 }
 
 #else /* #ifdef CONFIG_TASKS_RCU */
 static inline void show_rcu_tasks_classic_gp_kthread(void) { }
 void exit_tasks_rcu_start(void) { }
+void exit_tasks_rcu_stop(void) { }
 void exit_tasks_rcu_finish(void) { exit_tasks_rcu_finish_trace(current); }
 #endif /* #else #ifdef CONFIG_TASKS_RCU */
 
@@ -620,9 +649,6 @@
 // Wait for one rude RCU-tasks grace period.
 static void rcu_tasks_rude_wait_gp(struct rcu_tasks *rtp)
 {
-	if (num_online_cpus() <= 1)
-		return;	// Fastpath for only one CPU.
-
 	rtp->n_ipis += cpumask_weight(cpu_online_mask);
 	schedule_on_each_cpu(rcu_tasks_be_rude);
 }
@@ -707,7 +733,7 @@
 #endif /* #ifndef CONFIG_TINY_RCU */
 
 #else /* #ifdef CONFIG_TASKS_RUDE_RCU */
-static void show_rcu_tasks_rude_gp_kthread(void) {}
+static inline void show_rcu_tasks_rude_gp_kthread(void) {}
 #endif /* #else #ifdef CONFIG_TASKS_RUDE_RCU */
 
 ////////////////////////////////////////////////////////////////////////
@@ -775,7 +801,7 @@
 /* If we are the last reader, wake up the grace-period kthread. */
 void rcu_read_unlock_trace_special(struct task_struct *t, int nesting)
 {
-	int nq = t->trc_reader_special.b.need_qs;
+	int nq = READ_ONCE(t->trc_reader_special.b.need_qs);
 
 	if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB) &&
 	    t->trc_reader_special.b.need_mb)
@@ -815,33 +841,25 @@
 
 	// If the task is no longer running on this CPU, leave.
 	if (unlikely(texp != t)) {
-		if (WARN_ON_ONCE(atomic_dec_and_test(&trc_n_readers_need_end)))
-			wake_up(&trc_wait);
 		goto reset_ipi; // Already on holdout list, so will check later.
 	}
 
 	// If the task is not in a read-side critical section, and
 	// if this is the last reader, awaken the grace-period kthread.
-	if (likely(!t->trc_reader_nesting)) {
-		if (WARN_ON_ONCE(atomic_dec_and_test(&trc_n_readers_need_end)))
-			wake_up(&trc_wait);
-		// Mark as checked after decrement to avoid false
-		// positives on the above WARN_ON_ONCE().
+	if (likely(!READ_ONCE(t->trc_reader_nesting))) {
 		WRITE_ONCE(t->trc_reader_checked, true);
 		goto reset_ipi;
 	}
 	// If we are racing with an rcu_read_unlock_trace(), try again later.
-	if (unlikely(t->trc_reader_nesting < 0)) {
-		if (WARN_ON_ONCE(atomic_dec_and_test(&trc_n_readers_need_end)))
-			wake_up(&trc_wait);
+	if (unlikely(READ_ONCE(t->trc_reader_nesting) < 0))
 		goto reset_ipi;
-	}
 	WRITE_ONCE(t->trc_reader_checked, true);
 
 	// Get here if the task is in a read-side critical section.  Set
 	// its state so that it will awaken the grace-period kthread upon
 	// exit from that critical section.
-	WARN_ON_ONCE(t->trc_reader_special.b.need_qs);
+	atomic_inc(&trc_n_readers_need_end); // One more to wait on.
+	WARN_ON_ONCE(READ_ONCE(t->trc_reader_special.b.need_qs));
 	WRITE_ONCE(t->trc_reader_special.b.need_qs, true);
 
 reset_ipi:
@@ -856,7 +874,7 @@
 static bool trc_inspect_reader(struct task_struct *t, void *arg)
 {
 	int cpu = task_cpu(t);
-	bool in_qs = false;
+	int nesting;
 	bool ofl = cpu_is_offline(cpu);
 
 	if (task_curr(t)) {
@@ -876,23 +894,24 @@
 		n_heavy_reader_updates++;
 		if (ofl)
 			n_heavy_reader_ofl_updates++;
-		in_qs = true;
+		nesting = 0;
 	} else {
-		in_qs = likely(!t->trc_reader_nesting);
+		// The task is not running, so C-language access is safe.
+		nesting = t->trc_reader_nesting;
 	}
 
-	// Mark as checked so that the grace-period kthread will
-	// remove it from the holdout list.
-	t->trc_reader_checked = true;
-
-	if (in_qs)
-		return true;  // Already in quiescent state, done!!!
+	// If not exiting a read-side critical section, mark as checked
+	// so that the grace-period kthread will remove it from the
+	// holdout list.
+	t->trc_reader_checked = nesting >= 0;
+	if (nesting <= 0)
+		return !nesting;  // If in QS, done, otherwise try again later.
 
 	// The task is in a read-side critical section, so set up its
 	// state so that it will awaken the grace-period kthread upon exit
 	// from that critical section.
 	atomic_inc(&trc_n_readers_need_end); // One more to wait on.
-	WARN_ON_ONCE(t->trc_reader_special.b.need_qs);
+	WARN_ON_ONCE(READ_ONCE(t->trc_reader_special.b.need_qs));
 	WRITE_ONCE(t->trc_reader_special.b.need_qs, true);
 	return true;
 }
@@ -910,7 +929,7 @@
 	// The current task had better be in a quiescent state.
 	if (t == current) {
 		t->trc_reader_checked = true;
-		WARN_ON_ONCE(t->trc_reader_nesting);
+		WARN_ON_ONCE(READ_ONCE(t->trc_reader_nesting));
 		return;
 	}
 
@@ -933,21 +952,17 @@
 		if (per_cpu(trc_ipi_to_cpu, cpu) || t->trc_ipi_to_cpu >= 0)
 			return;
 
-		atomic_inc(&trc_n_readers_need_end);
 		per_cpu(trc_ipi_to_cpu, cpu) = true;
 		t->trc_ipi_to_cpu = cpu;
 		rcu_tasks_trace.n_ipis++;
-		if (smp_call_function_single(cpu,
-					     trc_read_check_handler, t, 0)) {
+		if (smp_call_function_single(cpu, trc_read_check_handler, t, 0)) {
 			// Just in case there is some other reason for
 			// failure than the target CPU being offline.
+			WARN_ONCE(1, "%s():  smp_call_function_single() failed for CPU: %d\n",
+				  __func__, cpu);
 			rcu_tasks_trace.n_ipis_fails++;
 			per_cpu(trc_ipi_to_cpu, cpu) = false;
-			t->trc_ipi_to_cpu = cpu;
-			if (atomic_dec_and_test(&trc_n_readers_need_end)) {
-				WARN_ON_ONCE(1);
-				wake_up(&trc_wait);
-			}
+			t->trc_ipi_to_cpu = -1;
 		}
 	}
 }
@@ -1020,8 +1035,8 @@
 		 ".I"[READ_ONCE(t->trc_ipi_to_cpu) > 0],
 		 ".i"[is_idle_task(t)],
 		 ".N"[cpu > 0 && tick_nohz_full_cpu(cpu)],
-		 t->trc_reader_nesting,
-		 " N"[!!t->trc_reader_special.b.need_qs],
+		 READ_ONCE(t->trc_reader_nesting),
+		 " N"[!!READ_ONCE(t->trc_reader_special.b.need_qs)],
 		 cpu);
 	sched_show_task(t);
 }
@@ -1068,13 +1083,27 @@
 	}
 }
 
+static void rcu_tasks_trace_empty_fn(void *unused)
+{
+}
+
 /* Wait for grace period to complete and provide ordering. */
 static void rcu_tasks_trace_postgp(struct rcu_tasks *rtp)
 {
+	int cpu;
 	bool firstreport;
 	struct task_struct *g, *t;
 	LIST_HEAD(holdouts);
 	long ret;
+
+	// Wait for any lingering IPI handlers to complete.  Note that
+	// if a CPU has gone offline or transitioned to userspace in the
+	// meantime, all IPI handlers should have been drained beforehand.
+	// Yes, this assumes that CPUs process IPIs in order.  If that ever
+	// changes, there will need to be a recheck and/or timed wait.
+	for_each_online_cpu(cpu)
+		if (smp_load_acquire(per_cpu_ptr(&trc_ipi_to_cpu, cpu)))
+			smp_call_function_single(cpu, rcu_tasks_trace_empty_fn, NULL, 1);
 
 	// Remove the safety count.
 	smp_mb__before_atomic();  // Order vs. earlier atomics
@@ -1115,7 +1144,7 @@
 static void exit_tasks_rcu_finish_trace(struct task_struct *t)
 {
 	WRITE_ONCE(t->trc_reader_checked, true);
-	WARN_ON_ONCE(t->trc_reader_nesting);
+	WARN_ON_ONCE(READ_ONCE(t->trc_reader_nesting));
 	WRITE_ONCE(t->trc_reader_nesting, 0);
 	if (WARN_ON_ONCE(READ_ONCE(t->trc_reader_special.b.need_qs)))
 		rcu_read_unlock_trace_special(t, 0);
diff --git a/kernel/kernel/rcu/tree.c b/kernel/kernel/rcu/tree.c
index b10d6bc..eec8e2f 100644
--- a/kernel/kernel/rcu/tree.c
+++ b/kernel/kernel/rcu/tree.c
@@ -964,6 +964,7 @@
 	}
 	raw_spin_unlock_rcu_node(rdp->mynode);
 }
+NOKPROBE_SYMBOL(__rcu_irq_enter_check_tick);
 #endif /* CONFIG_NO_HZ_FULL */
 
 /**
@@ -1157,7 +1158,7 @@
 	preempt_disable_notrace();
 	rdp = this_cpu_ptr(&rcu_data);
 	rnp = rdp->mynode;
-	if (rdp->grpmask & rcu_rnp_online_cpus(rnp))
+	if (rdp->grpmask & rcu_rnp_online_cpus(rnp) || READ_ONCE(rnp->ofl_seq) & 0x1)
 		ret = true;
 	preempt_enable_notrace();
 	return ret;
@@ -1724,6 +1725,7 @@
  */
 static bool rcu_gp_init(void)
 {
+	unsigned long firstseq;
 	unsigned long flags;
 	unsigned long oldmask;
 	unsigned long mask;
@@ -1767,6 +1769,12 @@
 	 */
 	rcu_state.gp_state = RCU_GP_ONOFF;
 	rcu_for_each_leaf_node(rnp) {
+		smp_mb(); // Pair with barriers used when updating ->ofl_seq to odd values.
+		firstseq = READ_ONCE(rnp->ofl_seq);
+		if (firstseq & 0x1)
+			while (firstseq == READ_ONCE(rnp->ofl_seq))
+				schedule_timeout_idle(1);  // Can't wake unless RCU is watching.
+		smp_mb(); // Pair with barriers used when updating ->ofl_seq to even values.
 		raw_spin_lock(&rcu_state.ofl_lock);
 		raw_spin_lock_irq_rcu_node(rnp);
 		if (rnp->qsmaskinit == rnp->qsmaskinitnext &&
@@ -2650,7 +2658,7 @@
 	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);
@@ -3273,6 +3281,30 @@
 	}
 }
 
+static bool
+need_offload_krc(struct kfree_rcu_cpu *krcp)
+{
+	int i;
+
+	for (i = 0; i < FREE_N_CHANNELS; i++)
+		if (krcp->bkvhead[i])
+			return true;
+
+	return !!krcp->head;
+}
+
+static bool
+need_wait_for_krwp_work(struct kfree_rcu_cpu_work *krwp)
+{
+	int i;
+
+	for (i = 0; i < FREE_N_CHANNELS; i++)
+		if (krwp->bkvhead_free[i])
+			return true;
+
+	return !!krwp->head_free;
+}
+
 /*
  * Schedule the kfree batch RCU work to run in workqueue context after a GP.
  *
@@ -3290,16 +3322,13 @@
 	for (i = 0; i < KFREE_N_BATCHES; i++) {
 		krwp = &(krcp->krw_arr[i]);
 
-		/*
-		 * Try to detach bkvhead or head and attach it over any
-		 * available corresponding free channel. It can be that
-		 * a previous RCU batch is in progress, it means that
-		 * immediately to queue another one is not possible so
-		 * return false to tell caller to retry.
-		 */
-		if ((krcp->bkvhead[0] && !krwp->bkvhead_free[0]) ||
-			(krcp->bkvhead[1] && !krwp->bkvhead_free[1]) ||
-				(krcp->head && !krwp->head_free)) {
+		// Try to detach bulk_head or head and attach it, only when
+		// all channels are free.  Any channel is not free means at krwp
+		// there is on-going rcu work to handle krwp's free business.
+		if (need_wait_for_krwp_work(krwp))
+			continue;
+
+		if (need_offload_krc(krcp)) {
 			// Channel 1 corresponds to SLAB ptrs.
 			// Channel 2 corresponds to vmalloc ptrs.
 			for (j = 0; j < FREE_N_CHANNELS; j++) {
@@ -3326,11 +3355,11 @@
 			 */
 			queue_rcu_work(system_wq, &krwp->rcu_work);
 		}
-
-		// Repeat if any "free" corresponding channel is still busy.
-		if (krcp->bkvhead[0] || krcp->bkvhead[1] || krcp->head)
-			repeat = true;
 	}
+
+	// Repeat if any "free" corresponding channel is still busy.
+	if (need_offload_krc(krcp))
+		repeat = true;
 
 	return !repeat;
 }
@@ -4107,6 +4136,9 @@
 
 	rnp = rdp->mynode;
 	mask = rdp->grpmask;
+	WRITE_ONCE(rnp->ofl_seq, rnp->ofl_seq + 1);
+	WARN_ON_ONCE(!(rnp->ofl_seq & 0x1));
+	smp_mb(); // Pair with rcu_gp_cleanup()'s ->ofl_seq barrier().
 	raw_spin_lock_irqsave_rcu_node(rnp, flags);
 	WRITE_ONCE(rnp->qsmaskinitnext, rnp->qsmaskinitnext | mask);
 	newcpu = !(rnp->expmaskinitnext & mask);
@@ -4124,6 +4156,9 @@
 	} else {
 		raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
 	}
+	smp_mb(); // Pair with rcu_gp_cleanup()'s ->ofl_seq barrier().
+	WRITE_ONCE(rnp->ofl_seq, rnp->ofl_seq + 1);
+	WARN_ON_ONCE(rnp->ofl_seq & 0x1);
 	smp_mb(); /* Ensure RCU read-side usage follows above initialization. */
 }
 
@@ -4150,6 +4185,9 @@
 
 	/* Remove outgoing CPU from mask in the leaf rcu_node structure. */
 	mask = rdp->grpmask;
+	WRITE_ONCE(rnp->ofl_seq, rnp->ofl_seq + 1);
+	WARN_ON_ONCE(!(rnp->ofl_seq & 0x1));
+	smp_mb(); // Pair with rcu_gp_cleanup()'s ->ofl_seq barrier().
 	raw_spin_lock(&rcu_state.ofl_lock);
 	raw_spin_lock_irqsave_rcu_node(rnp, flags); /* Enforce GP memory-order guarantee. */
 	rdp->rcu_ofl_gp_seq = READ_ONCE(rcu_state.gp_seq);
@@ -4162,6 +4200,9 @@
 	WRITE_ONCE(rnp->qsmaskinitnext, rnp->qsmaskinitnext & ~mask);
 	raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
 	raw_spin_unlock(&rcu_state.ofl_lock);
+	smp_mb(); // Pair with rcu_gp_cleanup()'s ->ofl_seq barrier().
+	WRITE_ONCE(rnp->ofl_seq, rnp->ofl_seq + 1);
+	WARN_ON_ONCE(rnp->ofl_seq & 0x1);
 
 	rdp->cpu_started = false;
 }
diff --git a/kernel/kernel/rcu/tree.h b/kernel/kernel/rcu/tree.h
index e4f66b8..6e8c777 100644
--- a/kernel/kernel/rcu/tree.h
+++ b/kernel/kernel/rcu/tree.h
@@ -56,6 +56,7 @@
 				/*  Initialized from ->qsmaskinitnext at the */
 				/*  beginning of each grace period. */
 	unsigned long qsmaskinitnext;
+	unsigned long ofl_seq;	/* CPU-hotplug operation sequence count. */
 				/* Online CPUs for next grace period. */
 	unsigned long expmask;	/* CPUs or groups that need to check in */
 				/*  to allow the current expedited GP */
diff --git a/kernel/kernel/rcu/tree_exp.h b/kernel/kernel/rcu/tree_exp.h
index e4b9fa7..fad86be 100644
--- a/kernel/kernel/rcu/tree_exp.h
+++ b/kernel/kernel/rcu/tree_exp.h
@@ -507,7 +507,10 @@
 				if (rdp->rcu_forced_tick_exp)
 					continue;
 				rdp->rcu_forced_tick_exp = true;
-				tick_dep_set_cpu(cpu, TICK_DEP_BIT_RCU_EXP);
+				preempt_disable();
+				if (cpu_online(cpu))
+					tick_dep_set_cpu(cpu, TICK_DEP_BIT_RCU_EXP);
+				preempt_enable();
 			}
 		}
 		j = READ_ONCE(jiffies_till_first_fqs);
@@ -565,7 +568,9 @@
 				mask = leaf_node_cpu_bit(rnp, cpu);
 				if (!(READ_ONCE(rnp->expmask) & mask))
 					continue;
+				preempt_disable(); // For smp_processor_id() in dump_cpu_task().
 				dump_cpu_task(cpu);
+				preempt_enable();
 			}
 		}
 		jiffies_stall = 3 * rcu_jiffies_till_stall_check() + 3;
@@ -706,9 +711,11 @@
 	int ndetected = 0;
 	struct task_struct *t;
 
-	if (!READ_ONCE(rnp->exp_tasks))
-		return 0;
 	raw_spin_lock_irqsave_rcu_node(rnp, flags);
+	if (!rnp->exp_tasks) {
+		raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
+		return 0;
+	}
 	t = list_entry(rnp->exp_tasks->prev,
 		       struct task_struct, rcu_node_entry);
 	list_for_each_entry_continue(t, &rnp->blkd_tasks, rcu_node_entry) {
diff --git a/kernel/kernel/relay.c b/kernel/kernel/relay.c
index b08d936..f6826de 100644
--- a/kernel/kernel/relay.c
+++ b/kernel/kernel/relay.c
@@ -163,13 +163,13 @@
 {
 	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;
@@ -1077,7 +1077,8 @@
 	size_t subbuf_size = buf->chan->subbuf_size;
 	size_t n_subbufs = buf->chan->n_subbufs;
 	size_t consumed = buf->subbufs_consumed % n_subbufs;
-	size_t read_pos = consumed * subbuf_size + buf->bytes_consumed;
+	size_t read_pos = (consumed * subbuf_size + buf->bytes_consumed)
+			% (n_subbufs * subbuf_size);
 
 	read_subbuf = read_pos / subbuf_size;
 	padding = buf->padding[read_subbuf];
diff --git a/kernel/kernel/resource.c b/kernel/kernel/resource.c
index 817545f..100253d 100644
--- a/kernel/kernel/resource.c
+++ b/kernel/kernel/resource.c
@@ -1293,20 +1293,6 @@
 			continue;
 		}
 
-		/*
-		 * All memory regions added from memory-hotplug path have the
-		 * flag IORESOURCE_SYSTEM_RAM. If the resource does not have
-		 * this flag, we know that we are dealing with a resource coming
-		 * from HMM/devm. HMM/devm use another mechanism to add/release
-		 * a resource. This goes via devm_request_mem_region and
-		 * devm_release_mem_region.
-		 * HMM/devm take care to release their resources when they want,
-		 * so if we are dealing with them, let us just back off here.
-		 */
-		if (!(res->flags & IORESOURCE_SYSRAM)) {
-			break;
-		}
-
 		if (!(res->flags & IORESOURCE_MEM))
 			break;
 
diff --git a/kernel/kernel/scftorture.c b/kernel/kernel/scftorture.c
index 060ee0b..be86207 100644
--- a/kernel/kernel/scftorture.c
+++ b/kernel/kernel/scftorture.c
@@ -158,7 +158,8 @@
 		scfs.n_all_wait += scf_stats_p[i].n_all_wait;
 	}
 	if (atomic_read(&n_errs) || atomic_read(&n_mb_in_errs) ||
-	    atomic_read(&n_mb_out_errs) || atomic_read(&n_alloc_errs))
+	    atomic_read(&n_mb_out_errs) ||
+	    (!IS_ENABLED(CONFIG_KASAN) && atomic_read(&n_alloc_errs)))
 		bangstr = "!!! ";
 	pr_alert("%s %sscf_invoked_count %s: %lld single: %lld/%lld single_ofl: %lld/%lld many: %lld/%lld all: %lld/%lld ",
 		 SCFTORT_FLAG, bangstr, isdone ? "VER" : "ver", invoked_count,
@@ -306,7 +307,8 @@
 		preempt_disable();
 	if (scfsp->scfs_prim == SCF_PRIM_SINGLE || scfsp->scfs_wait) {
 		scfcp = kmalloc(sizeof(*scfcp), GFP_ATOMIC);
-		if (WARN_ON_ONCE(!scfcp)) {
+		if (!scfcp) {
+			WARN_ON_ONCE(!IS_ENABLED(CONFIG_KASAN));
 			atomic_inc(&n_alloc_errs);
 		} else {
 			scfcp->scfc_cpu = -1;
diff --git a/kernel/kernel/sched/core.c b/kernel/kernel/sched/core.c
index 7359375..30ab811 100644
--- a/kernel/kernel/sched/core.c
+++ b/kernel/kernel/sched/core.c
@@ -1018,7 +1018,7 @@
 	if (!(rq->uclamp_flags & UCLAMP_FLAG_IDLE))
 		return;
 
-	WRITE_ONCE(rq->uclamp[clamp_id].value, clamp_value);
+	uclamp_rq_set(rq, clamp_id, clamp_value);
 }
 
 static inline
@@ -1211,8 +1211,8 @@
 	if (bucket->tasks == 1 || uc_se->value > bucket->value)
 		bucket->value = uc_se->value;
 
-	if (uc_se->value > READ_ONCE(uc_rq->value))
-		WRITE_ONCE(uc_rq->value, uc_se->value);
+	if (uc_se->value > uclamp_rq_get(rq, clamp_id))
+		uclamp_rq_set(rq, clamp_id, uc_se->value);
 }
 
 /*
@@ -1278,7 +1278,7 @@
 	if (likely(bucket->tasks))
 		return;
 
-	rq_clamp = READ_ONCE(uc_rq->value);
+	rq_clamp = uclamp_rq_get(rq, clamp_id);
 	/*
 	 * Defensive programming: this should never happen. If it happens,
 	 * e.g. due to future modification, warn and fixup the expected value.
@@ -1286,7 +1286,7 @@
 	SCHED_WARN_ON(bucket->value > rq_clamp);
 	if (bucket->value >= rq_clamp) {
 		bkt_clamp = uclamp_rq_max_value(rq, clamp_id, uc_se->value);
-		WRITE_ONCE(uc_rq->value, bkt_clamp);
+		uclamp_rq_set(rq, clamp_id, bkt_clamp);
 	}
 }
 
@@ -1692,6 +1692,9 @@
 
 void activate_task(struct rq *rq, struct task_struct *p, int flags)
 {
+	if (task_on_rq_migrating(p))
+		flags |= ENQUEUE_MIGRATED;
+
 	enqueue_task(rq, p, flags);
 
 	p->on_rq = TASK_ON_RQ_QUEUED;
@@ -4535,8 +4538,7 @@
 		pr_err("Preemption disabled at:");
 		print_ip_sym(KERN_ERR, preempt_disable_ip);
 	}
-	if (panic_on_warn)
-		panic("scheduling while atomic\n");
+	check_panic_on_warn("scheduling while atomic");
 
 	trace_android_rvh_schedule_bug(prev);
 
@@ -5480,6 +5482,7 @@
 	int reset_on_fork;
 	int queue_flags = DEQUEUE_SAVE | DEQUEUE_MOVE | DEQUEUE_NOCLOCK;
 	struct rq *rq;
+	bool cpuset_locked = false;
 
 	/* The pi code expects interrupts enabled */
 	BUG_ON(pi && in_interrupt());
@@ -5582,6 +5585,15 @@
 	}
 
 	/*
+	 * SCHED_DEADLINE bandwidth accounting relies on stable cpusets
+	 * information.
+	 */
+	if (dl_policy(policy) || dl_policy(p->policy)) {
+		cpuset_locked = true;
+		cpuset_lock();
+	}
+
+	/*
 	 * Make sure no PI-waiters arrive (or leave) while we are
 	 * changing the priority of the task:
 	 *
@@ -5655,6 +5667,8 @@
 	if (unlikely(oldpolicy != -1 && oldpolicy != p->policy)) {
 		policy = oldpolicy = -1;
 		task_rq_unlock(rq, p, &rf);
+		if (cpuset_locked)
+			cpuset_unlock();
 		goto recheck;
 	}
 
@@ -5720,8 +5734,11 @@
 	preempt_disable();
 	task_rq_unlock(rq, p, &rf);
 
-	if (pi)
+	if (pi) {
+		if (cpuset_locked)
+			cpuset_unlock();
 		rt_mutex_adjust_pi(p);
+	}
 
 	/* Run balance callbacks after we've adjusted the PI chain: */
 	balance_callback(rq);
@@ -5731,6 +5748,8 @@
 
 unlock:
 	task_rq_unlock(rq, p, &rf);
+	if (cpuset_locked)
+		cpuset_unlock();
 	return retval;
 }
 
@@ -6344,14 +6363,14 @@
 	if (len & (sizeof(unsigned long)-1))
 		return -EINVAL;
 
-	if (!alloc_cpumask_var(&mask, GFP_KERNEL))
+	if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
 		return -ENOMEM;
 
 	ret = sched_getaffinity(pid, mask);
 	if (ret == 0) {
 		unsigned int retlen = min(len, cpumask_size());
 
-		if (copy_to_user(user_mask_ptr, mask, retlen))
+		if (copy_to_user(user_mask_ptr, cpumask_bits(mask), retlen))
 			ret = -EFAULT;
 		else
 			ret = retlen;
@@ -6872,8 +6891,7 @@
 	return ret;
 }
 
-int task_can_attach(struct task_struct *p,
-		    const struct cpumask *cs_effective_cpus)
+int task_can_attach(struct task_struct *p)
 {
 	int ret = 0;
 
@@ -6886,21 +6904,9 @@
 	 * success of set_cpus_allowed_ptr() on all attached tasks
 	 * before cpus_mask may be changed.
 	 */
-	if (p->flags & PF_NO_SETAFFINITY) {
+	if (p->flags & PF_NO_SETAFFINITY)
 		ret = -EINVAL;
-		goto out;
-	}
 
-	if (dl_task(p) && !cpumask_intersects(task_rq(p)->rd->span,
-					      cs_effective_cpus)) {
-		int cpu = cpumask_any_and(cpu_active_mask, cs_effective_cpus);
-
-		if (unlikely(cpu >= nr_cpu_ids))
-			return -EINVAL;
-		ret = dl_cpu_busy(cpu, p);
-	}
-
-out:
 	return ret;
 }
 
@@ -7228,7 +7234,7 @@
 static int cpuset_cpu_inactive(unsigned int cpu)
 {
 	if (!cpuhp_tasks_frozen) {
-		int ret = dl_cpu_busy(cpu, NULL);
+		int ret = dl_bw_check_overflow(cpu);
 
 		if (ret)
 			return ret;
diff --git a/kernel/kernel/sched/cpuacct.c b/kernel/kernel/sched/cpuacct.c
index 941c28c..8ee2983 100644
--- a/kernel/kernel/sched/cpuacct.c
+++ b/kernel/kernel/sched/cpuacct.c
@@ -21,15 +21,11 @@
 	[CPUACCT_STAT_SYSTEM] = "system",
 };
 
-struct cpuacct_usage {
-	u64	usages[CPUACCT_STAT_NSTATS];
-};
-
 /* track CPU usage of a group of tasks and its child groups */
 struct cpuacct {
 	struct cgroup_subsys_state	css;
 	/* cpuusage holds pointer to a u64-type object on every CPU */
-	struct cpuacct_usage __percpu	*cpuusage;
+	u64 __percpu	*cpuusage;
 	struct kernel_cpustat __percpu	*cpustat;
 };
 
@@ -49,7 +45,7 @@
 	return css_ca(ca->css.parent);
 }
 
-static DEFINE_PER_CPU(struct cpuacct_usage, root_cpuacct_cpuusage);
+static DEFINE_PER_CPU(u64, root_cpuacct_cpuusage);
 static struct cpuacct root_cpuacct = {
 	.cpustat	= &kernel_cpustat,
 	.cpuusage	= &root_cpuacct_cpuusage,
@@ -68,7 +64,7 @@
 	if (!ca)
 		goto out;
 
-	ca->cpuusage = alloc_percpu(struct cpuacct_usage);
+	ca->cpuusage = alloc_percpu(u64);
 	if (!ca->cpuusage)
 		goto out_free_ca;
 
@@ -99,7 +95,8 @@
 static u64 cpuacct_cpuusage_read(struct cpuacct *ca, int cpu,
 				 enum cpuacct_stat_index index)
 {
-	struct cpuacct_usage *cpuusage = per_cpu_ptr(ca->cpuusage, cpu);
+	u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu);
+	u64 *cpustat = per_cpu_ptr(ca->cpustat, cpu)->cpustat;
 	u64 data;
 
 	/*
@@ -115,14 +112,17 @@
 	raw_spin_lock_irq(&cpu_rq(cpu)->lock);
 #endif
 
-	if (index == CPUACCT_STAT_NSTATS) {
-		int i = 0;
-
-		data = 0;
-		for (i = 0; i < CPUACCT_STAT_NSTATS; i++)
-			data += cpuusage->usages[i];
-	} else {
-		data = cpuusage->usages[index];
+	switch (index) {
+	case CPUACCT_STAT_USER:
+		data = cpustat[CPUTIME_USER] + cpustat[CPUTIME_NICE];
+		break;
+	case CPUACCT_STAT_SYSTEM:
+		data = cpustat[CPUTIME_SYSTEM] + cpustat[CPUTIME_IRQ] +
+			cpustat[CPUTIME_SOFTIRQ];
+		break;
+	case CPUACCT_STAT_NSTATS:
+		data = *cpuusage;
+		break;
 	}
 
 #ifndef CONFIG_64BIT
@@ -132,10 +132,14 @@
 	return data;
 }
 
-static void cpuacct_cpuusage_write(struct cpuacct *ca, int cpu, u64 val)
+static void cpuacct_cpuusage_write(struct cpuacct *ca, int cpu)
 {
-	struct cpuacct_usage *cpuusage = per_cpu_ptr(ca->cpuusage, cpu);
-	int i;
+	u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu);
+	u64 *cpustat = per_cpu_ptr(ca->cpustat, cpu)->cpustat;
+
+	/* Don't allow to reset global kernel_cpustat */
+	if (ca == &root_cpuacct)
+		return;
 
 #ifndef CONFIG_64BIT
 	/*
@@ -143,9 +147,10 @@
 	 */
 	raw_spin_lock_irq(&cpu_rq(cpu)->lock);
 #endif
-
-	for (i = 0; i < CPUACCT_STAT_NSTATS; i++)
-		cpuusage->usages[i] = val;
+	*cpuusage = 0;
+	cpustat[CPUTIME_USER] = cpustat[CPUTIME_NICE] = 0;
+	cpustat[CPUTIME_SYSTEM] = cpustat[CPUTIME_IRQ] = 0;
+	cpustat[CPUTIME_SOFTIRQ] = 0;
 
 #ifndef CONFIG_64BIT
 	raw_spin_unlock_irq(&cpu_rq(cpu)->lock);
@@ -196,7 +201,7 @@
 		return -EINVAL;
 
 	for_each_possible_cpu(cpu)
-		cpuacct_cpuusage_write(ca, cpu, 0);
+		cpuacct_cpuusage_write(ca, cpu);
 
 	return 0;
 }
@@ -243,25 +248,10 @@
 	seq_puts(m, "\n");
 
 	for_each_possible_cpu(cpu) {
-		struct cpuacct_usage *cpuusage = per_cpu_ptr(ca->cpuusage, cpu);
-
 		seq_printf(m, "%d", cpu);
-
-		for (index = 0; index < CPUACCT_STAT_NSTATS; index++) {
-#ifndef CONFIG_64BIT
-			/*
-			 * Take rq->lock to make 64-bit read safe on 32-bit
-			 * platforms.
-			 */
-			raw_spin_lock_irq(&cpu_rq(cpu)->lock);
-#endif
-
-			seq_printf(m, " %llu", cpuusage->usages[index]);
-
-#ifndef CONFIG_64BIT
-			raw_spin_unlock_irq(&cpu_rq(cpu)->lock);
-#endif
-		}
+		for (index = 0; index < CPUACCT_STAT_NSTATS; index++)
+			seq_printf(m, " %llu",
+				   cpuacct_cpuusage_read(ca, cpu, index));
 		seq_puts(m, "\n");
 	}
 	return 0;
@@ -338,19 +328,13 @@
  */
 void cpuacct_charge(struct task_struct *tsk, u64 cputime)
 {
+	unsigned int cpu = task_cpu(tsk);
 	struct cpuacct *ca;
-	int index = CPUACCT_STAT_SYSTEM;
-	struct pt_regs *regs = get_irq_regs() ? : task_pt_regs(tsk);
 
-	if (regs && user_mode(regs))
-		index = CPUACCT_STAT_USER;
-
-	rcu_read_lock();
+	lockdep_assert_held(&cpu_rq(cpu)->lock);
 
 	for (ca = task_ca(tsk); ca; ca = parent_ca(ca))
-		__this_cpu_add(ca->cpuusage->usages[index], cputime);
-
-	rcu_read_unlock();
+		*per_cpu_ptr(ca->cpuusage, cpu) += cputime;
 }
 
 /*
diff --git a/kernel/kernel/sched/deadline.c b/kernel/kernel/sched/deadline.c
index fa92656..98c69a7 100644
--- a/kernel/kernel/sched/deadline.c
+++ b/kernel/kernel/sched/deadline.c
@@ -17,6 +17,7 @@
  */
 #include "sched.h"
 #include "pelt.h"
+#include <linux/cpuset.h>
 
 struct dl_bandwidth def_dl_bandwidth;
 
@@ -1847,8 +1848,7 @@
 	deadline_queue_push_tasks(rq);
 }
 
-static struct sched_dl_entity *pick_next_dl_entity(struct rq *rq,
-						   struct dl_rq *dl_rq)
+static struct sched_dl_entity *pick_next_dl_entity(struct dl_rq *dl_rq)
 {
 	struct rb_node *left = rb_first_cached(&dl_rq->root);
 
@@ -1867,7 +1867,7 @@
 	if (!sched_dl_runnable(rq))
 		return NULL;
 
-	dl_se = pick_next_dl_entity(rq, dl_rq);
+	dl_se = pick_next_dl_entity(dl_rq);
 	BUG_ON(!dl_se);
 	p = dl_task_of(dl_se);
 	set_next_task_dl(rq, p, true);
@@ -2421,6 +2421,12 @@
 	if (task_on_rq_queued(p) && p->dl.dl_runtime)
 		task_non_contending(p);
 
+	/*
+	 * In case a task is setscheduled out from SCHED_DEADLINE we need to
+	 * keep track of that on its cpuset (for correct bandwidth tracking).
+	 */
+	dec_dl_tasks_cs(p);
+
 	if (!task_on_rq_queued(p)) {
 		/*
 		 * Inactive timer is armed. However, p is leaving DEADLINE and
@@ -2460,6 +2466,12 @@
 {
 	if (hrtimer_try_to_cancel(&p->dl.inactive_timer) == 1)
 		put_task_struct(p);
+
+	/*
+	 * In case a task is setscheduled to SCHED_DEADLINE we need to keep
+	 * track of that on its cpuset (for correct bandwidth tracking).
+	 */
+	inc_dl_tasks_cs(p);
 
 	/* If p is not queued we will update its parameters at next wakeup. */
 	if (!task_on_rq_queued(p)) {
@@ -2849,26 +2861,38 @@
 	return ret;
 }
 
-int dl_cpu_busy(int cpu, struct task_struct *p)
+enum dl_bw_request {
+	dl_bw_req_check_overflow = 0,
+	dl_bw_req_alloc,
+	dl_bw_req_free
+};
+
+static int dl_bw_manage(enum dl_bw_request req, int cpu, u64 dl_bw)
 {
-	unsigned long flags, cap;
+	unsigned long flags;
 	struct dl_bw *dl_b;
-	bool overflow;
+	bool overflow = 0;
 
 	rcu_read_lock_sched();
 	dl_b = dl_bw_of(cpu);
 	raw_spin_lock_irqsave(&dl_b->lock, flags);
-	cap = dl_bw_capacity(cpu);
-	overflow = __dl_overflow(dl_b, cap, 0, p ? p->dl.dl_bw : 0);
 
-	if (!overflow && p) {
-		/*
-		 * We reserve space for this task in the destination
-		 * root_domain, as we can't fail after this point.
-		 * We will free resources in the source root_domain
-		 * later on (see set_cpus_allowed_dl()).
-		 */
-		__dl_add(dl_b, p->dl.dl_bw, dl_bw_cpus(cpu));
+	if (req == dl_bw_req_free) {
+		__dl_sub(dl_b, dl_bw, dl_bw_cpus(cpu));
+	} else {
+		unsigned long cap = dl_bw_capacity(cpu);
+
+		overflow = __dl_overflow(dl_b, cap, 0, dl_bw);
+
+		if (req == dl_bw_req_alloc && !overflow) {
+			/*
+			 * We reserve space in the destination
+			 * root_domain, as we can't fail after this point.
+			 * We will free resources in the source root_domain
+			 * later on (see set_cpus_allowed_dl()).
+			 */
+			__dl_add(dl_b, dl_bw, dl_bw_cpus(cpu));
+		}
 	}
 
 	raw_spin_unlock_irqrestore(&dl_b->lock, flags);
@@ -2876,6 +2900,21 @@
 
 	return overflow ? -EBUSY : 0;
 }
+
+int dl_bw_check_overflow(int cpu)
+{
+	return dl_bw_manage(dl_bw_req_check_overflow, cpu, 0);
+}
+
+int dl_bw_alloc(int cpu, u64 dl_bw)
+{
+	return dl_bw_manage(dl_bw_req_alloc, cpu, dl_bw);
+}
+
+void dl_bw_free(int cpu, u64 dl_bw)
+{
+	dl_bw_manage(dl_bw_req_free, cpu, dl_bw);
+}
 #endif
 
 #ifdef CONFIG_SCHED_DEBUG
diff --git a/kernel/kernel/sched/fair.c b/kernel/kernel/sched/fair.c
index 8ef2f84..8c74c2f 100644
--- a/kernel/kernel/sched/fair.c
+++ b/kernel/kernel/sched/fair.c
@@ -3938,14 +3938,16 @@
 }
 
 #ifdef CONFIG_UCLAMP_TASK
-static inline unsigned long uclamp_task_util(struct task_struct *p)
+static inline unsigned long uclamp_task_util(struct task_struct *p,
+					     unsigned long uclamp_min,
+					     unsigned long uclamp_max)
 {
-	return clamp(task_util_est(p),
-		     uclamp_eff_value(p, UCLAMP_MIN),
-		     uclamp_eff_value(p, UCLAMP_MAX));
+	return clamp(task_util_est(p), uclamp_min, uclamp_max);
 }
 #else
-static inline unsigned long uclamp_task_util(struct task_struct *p)
+static inline unsigned long uclamp_task_util(struct task_struct *p,
+					     unsigned long uclamp_min,
+					     unsigned long uclamp_max)
 {
 	return task_util_est(p);
 }
@@ -4089,9 +4091,135 @@
 	trace_sched_util_est_se_tp(&p->se);
 }
 
-static inline int task_fits_capacity(struct task_struct *p, long capacity)
+static inline int util_fits_cpu(unsigned long util,
+				unsigned long uclamp_min,
+				unsigned long uclamp_max,
+				int cpu)
 {
-	return fits_capacity(uclamp_task_util(p), capacity);
+	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_cpu(struct task_struct *p, int cpu)
+{
+	unsigned long uclamp_min = uclamp_eff_value(p, UCLAMP_MIN);
+	unsigned long uclamp_max = uclamp_eff_value(p, UCLAMP_MAX);
+	unsigned long util = task_util_est(p);
+	return util_fits_cpu(util, uclamp_min, uclamp_max, cpu);
 }
 
 static inline void update_misfit_status(struct task_struct *p, struct rq *rq)
@@ -4107,7 +4235,7 @@
 		return;
 	}
 
-	if (task_fits_capacity(p, capacity_of(cpu_of(rq)))) {
+	if (task_fits_cpu(p, cpu_of(rq))) {
 		rq->misfit_task_load = 0;
 		return;
 	}
@@ -4168,6 +4296,29 @@
 #endif
 }
 
+static inline bool entity_is_long_sleeper(struct sched_entity *se)
+{
+	struct cfs_rq *cfs_rq;
+	u64 sleep_time;
+
+	if (se->exec_start == 0)
+		return false;
+
+	cfs_rq = cfs_rq_of(se);
+
+	sleep_time = rq_clock_task(rq_of(cfs_rq));
+
+	/* Happen while migrating because of clock task divergence */
+	if (sleep_time <= se->exec_start)
+		return false;
+
+	sleep_time -= se->exec_start;
+	if (sleep_time > ((1ULL << 63) / scale_load_down(NICE_0_LOAD)))
+		return true;
+
+	return false;
+}
+
 static void
 place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
 {
@@ -4196,8 +4347,29 @@
 		vruntime -= thresh;
 	}
 
-	/* ensure we never gain time by being placed backwards. */
-	se->vruntime = max_vruntime(se->vruntime, vruntime);
+	/*
+	 * Pull vruntime of the entity being placed to the base level of
+	 * cfs_rq, to prevent boosting it if placed backwards.
+	 * However, min_vruntime can advance much faster than real time, with
+	 * the extreme being when an entity with the minimal weight always runs
+	 * on the cfs_rq. If the waking entity slept for a long time, its
+	 * vruntime difference from min_vruntime may overflow s64 and their
+	 * comparison may get inversed, so ignore the entity's original
+	 * vruntime in that case.
+	 * The maximal vruntime speedup is given by the ratio of normal to
+	 * minimal weight: scale_load_down(NICE_0_LOAD) / MIN_SHARES.
+	 * When placing a migrated waking entity, its exec_start has been set
+	 * from a different rq. In order to take into account a possible
+	 * divergence between new and prev rq's clocks task because of irq and
+	 * stolen time, we take an additional margin.
+	 * So, cutting off on the sleep time of
+	 *     2^63 / scale_load_down(NICE_0_LOAD) ~ 104 days
+	 * should be safe.
+	 */
+	if (entity_is_long_sleeper(se))
+		se->vruntime = vruntime;
+	else
+		se->vruntime = max_vruntime(se->vruntime, vruntime);
 	trace_android_rvh_place_entity(cfs_rq, se, initial, vruntime);
 }
 
@@ -4294,6 +4466,9 @@
 
 	if (flags & ENQUEUE_WAKEUP)
 		place_entity(cfs_rq, se, 0);
+	/* Entity has migrated, no longer consider this task hot */
+	if (flags & ENQUEUE_MIGRATED)
+		se->exec_start = 0;
 
 	check_schedstat_required();
 	update_stats_enqueue(cfs_rq, se, flags);
@@ -5514,13 +5689,15 @@
 
 static inline bool cpu_overutilized(int cpu)
 {
+	unsigned long rq_util_min = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MIN);
+	unsigned long rq_util_max = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MAX);
 	int overutilized = -1;
 
 	trace_android_rvh_cpu_overutilized(cpu, &overutilized);
 	if (overutilized != -1)
 		return overutilized;
 
-	return !fits_capacity(cpu_util(cpu), capacity_of(cpu));
+	return !util_fits_cpu(cpu_util(cpu), rq_util_min, rq_util_max, cpu);
 }
 
 static inline void update_overutilized_status(struct rq *rq)
@@ -6262,21 +6439,23 @@
 static int
 select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target)
 {
-	unsigned long task_util, best_cap = 0;
+	unsigned long task_util, util_min, util_max, best_cap = 0;
 	int cpu, best_cpu = -1;
 	struct cpumask *cpus;
 
 	cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
 	cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
 
-	task_util = uclamp_task_util(p);
+	task_util = task_util_est(p);
+	util_min = uclamp_eff_value(p, UCLAMP_MIN);
+	util_max = uclamp_eff_value(p, UCLAMP_MAX);
 
 	for_each_cpu_wrap(cpu, cpus, target) {
 		unsigned long cpu_cap = capacity_of(cpu);
 
 		if (!available_idle_cpu(cpu) && !sched_idle_cpu(cpu))
 			continue;
-		if (fits_capacity(task_util, cpu_cap))
+		if (util_fits_cpu(task_util, util_min, util_max, cpu))
 			return cpu;
 
 		if (cpu_cap > best_cap) {
@@ -6288,10 +6467,13 @@
 	return best_cpu;
 }
 
-static inline bool asym_fits_capacity(int task_util, int cpu)
+static inline bool asym_fits_cpu(unsigned long util,
+				 unsigned long util_min,
+				 unsigned long util_max,
+				 int cpu)
 {
 	if (static_branch_unlikely(&sched_asym_cpucapacity))
-		return fits_capacity(task_util, capacity_of(cpu));
+		return util_fits_cpu(util, util_min, util_max, cpu);
 
 	return true;
 }
@@ -6302,7 +6484,7 @@
 static int select_idle_sibling(struct task_struct *p, int prev, int target)
 {
 	struct sched_domain *sd;
-	unsigned long task_util;
+	unsigned long task_util, util_min, util_max;
 	int i, recent_used_cpu;
 
 	/*
@@ -6311,11 +6493,13 @@
 	 */
 	if (static_branch_unlikely(&sched_asym_cpucapacity)) {
 		sync_entity_load_avg(&p->se);
-		task_util = uclamp_task_util(p);
+		task_util = task_util_est(p);
+		util_min = uclamp_eff_value(p, UCLAMP_MIN);
+		util_max = uclamp_eff_value(p, UCLAMP_MAX);
 	}
 
 	if ((available_idle_cpu(target) || sched_idle_cpu(target)) &&
-	    asym_fits_capacity(task_util, target))
+	    asym_fits_cpu(task_util, util_min, util_max, target))
 		return target;
 
 	/*
@@ -6323,7 +6507,7 @@
 	 */
 	if (prev != target && cpus_share_cache(prev, target) &&
 	    (available_idle_cpu(prev) || sched_idle_cpu(prev)) &&
-	    asym_fits_capacity(task_util, prev))
+	    asym_fits_cpu(task_util, util_min, util_max, prev))
 		return prev;
 
 	/*
@@ -6338,7 +6522,7 @@
 	    in_task() &&
 	    prev == smp_processor_id() &&
 	    this_rq()->nr_running <= 1 &&
-	    asym_fits_capacity(task_util, prev)) {
+	    asym_fits_cpu(task_util, util_min, util_max, prev)) {
 		return prev;
 	}
 
@@ -6349,7 +6533,7 @@
 	    cpus_share_cache(recent_used_cpu, target) &&
 	    (available_idle_cpu(recent_used_cpu) || sched_idle_cpu(recent_used_cpu)) &&
 	    cpumask_test_cpu(p->recent_used_cpu, p->cpus_ptr) &&
-	    asym_fits_capacity(task_util, recent_used_cpu)) {
+	    asym_fits_cpu(task_util, util_min, util_max, recent_used_cpu)) {
 		/*
 		 * Replace recent_used_cpu with prev as it is a potential
 		 * candidate for the next wake:
@@ -6682,6 +6866,8 @@
 {
 	unsigned long prev_delta = ULONG_MAX, best_delta = ULONG_MAX;
 	unsigned long best_delta2 = ULONG_MAX;
+	unsigned long p_util_min = uclamp_is_used() ? uclamp_eff_value(p, UCLAMP_MIN) : 0;
+	unsigned long p_util_max = uclamp_is_used() ? uclamp_eff_value(p, UCLAMP_MAX) : 1024;
 	struct root_domain *rd = cpu_rq(smp_processor_id())->rd;
 	int max_spare_cap_cpu_ls = prev_cpu, best_idle_cpu = -1;
 	unsigned long max_spare_cap_ls = 0, target_cap;
@@ -6707,7 +6893,7 @@
 	cpu = smp_processor_id();
 	if (sync && cpu_rq(cpu)->nr_running == 1 &&
 	    cpumask_test_cpu(cpu, p->cpus_ptr) &&
-	    task_fits_capacity(p, capacity_of(cpu))) {
+	    task_fits_cpu(p, cpu)) {
 		rcu_read_unlock();
 		return cpu;
 	}
@@ -6722,7 +6908,7 @@
 	if (!sd)
 		goto fail;
 
-	if (!task_util_est(p))
+	if (!uclamp_task_util(p, p_util_min, p_util_max))
 		goto unlock;
 
 	latency_sensitive = uclamp_latency_sensitive(p);
@@ -6731,6 +6917,8 @@
 
 	for (; pd; pd = pd->next) {
 		unsigned long cur_delta, spare_cap, max_spare_cap = 0;
+		unsigned long rq_util_min, rq_util_max;
+		unsigned long util_min, util_max;
 		unsigned long base_energy_pd;
 		int max_spare_cap_cpu = -1;
 
@@ -6754,8 +6942,26 @@
 			 * much capacity we can get out of the CPU; this is
 			 * aligned with schedutil_cpu_util().
 			 */
-			util = uclamp_rq_util_with(cpu_rq(cpu), util, p);
-			if (!fits_capacity(util, cpu_cap))
+			if (uclamp_is_used()) {
+				if (uclamp_rq_is_idle(cpu_rq(cpu))) {
+					util_min = p_util_min;
+					util_max = p_util_max;
+				} else {
+					/*
+					 * Open code uclamp_rq_util_with() except for
+					 * the clamp() part. Ie: apply max aggregation
+					 * only. util_fits_cpu() logic requires to
+					 * operate on non clamped util but must use the
+					 * max-aggregated uclamp_{min, max}.
+					 */
+					rq_util_min = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MIN);
+					rq_util_max = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MAX);
+
+					util_min = max(rq_util_min, p_util_min);
+					util_max = max(rq_util_max, p_util_max);
+				}
+			}
+			if (!util_fits_cpu(util, util_min, util_max, cpu))
 				continue;
 
 			/* Always use prev_cpu as a candidate. */
@@ -7034,9 +7240,6 @@
 
 	/* Tell new CPU we are migrated */
 	p->se.avg.last_update_time = 0;
-
-	/* We have migrated, no longer consider this task hot */
-	p->se.exec_start = 0;
 
 	update_scan_period(p, new_cpu);
 }
@@ -7983,7 +8186,7 @@
 
 		case migrate_misfit:
 			/* This is not a misfit task */
-			if (task_fits_capacity(p, capacity_of(env->src_cpu)))
+			if (task_fits_cpu(p, env->src_cpu))
 				goto next;
 
 			env->imbalance = 0;
@@ -8926,6 +9129,10 @@
 
 	memset(sgs, 0, sizeof(*sgs));
 
+	/* Assume that task can't fit any CPU of the group */
+	if (sd->flags & SD_ASYM_CPUCAPACITY)
+		sgs->group_misfit_task_load = 1;
+
 	for_each_cpu(i, sched_group_span(group)) {
 		struct rq *rq = cpu_rq(i);
 		unsigned int local;
@@ -8945,12 +9152,12 @@
 		if (!nr_running && idle_cpu_without(i, p))
 			sgs->idle_cpus++;
 
-	}
+		/* Check if task fits in the CPU */
+		if (sd->flags & SD_ASYM_CPUCAPACITY &&
+		    sgs->group_misfit_task_load &&
+		    task_fits_cpu(p, i))
+			sgs->group_misfit_task_load = 0;
 
-	/* Check if task fits in the group */
-	if (sd->flags & SD_ASYM_CPUCAPACITY &&
-	    !task_fits_capacity(p, group->sgc->max_capacity)) {
-		sgs->group_misfit_task_load = 1;
 	}
 
 	sgs->group_capacity = group->sgc->capacity;
@@ -9395,8 +9602,6 @@
 		local->avg_load = (local->group_load * SCHED_CAPACITY_SCALE) /
 				  local->group_capacity;
 
-		sds->avg_load = (sds->total_load * SCHED_CAPACITY_SCALE) /
-				sds->total_capacity;
 		/*
 		 * If the local group is more loaded than the selected
 		 * busiest group don't try to pull any tasks.
@@ -9405,6 +9610,19 @@
 			env->imbalance = 0;
 			return;
 		}
+
+		sds->avg_load = (sds->total_load * SCHED_CAPACITY_SCALE) /
+				sds->total_capacity;
+
+		/*
+		 * If the local group is more loaded than the average system
+		 * load, don't try to pull any tasks.
+		 */
+		if (local->avg_load >= sds->avg_load) {
+			env->imbalance = 0;
+			return;
+		}
+
 	}
 
 	/*
@@ -9837,7 +10055,7 @@
 		.sd		= sd,
 		.dst_cpu	= this_cpu,
 		.dst_rq		= this_rq,
-		.dst_grpmask    = sched_group_span(sd->groups),
+		.dst_grpmask    = group_balance_mask(sd->groups),
 		.idle		= idle,
 		.loop_break	= sched_nr_migrate_break,
 		.cpus		= cpus,
diff --git a/kernel/kernel/sched/loadavg.c b/kernel/kernel/sched/loadavg.c
index b5837e2..d2a6556 100644
--- a/kernel/kernel/sched/loadavg.c
+++ b/kernel/kernel/sched/loadavg.c
@@ -75,7 +75,6 @@
 	loads[1] = (avenrun[1] + offset) << shift;
 	loads[2] = (avenrun[2] + offset) << shift;
 }
-EXPORT_SYMBOL_GPL(get_avenrun);
 
 long calc_load_fold_active(struct rq *this_rq, long adjust)
 {
diff --git a/kernel/kernel/sched/psi.c b/kernel/kernel/sched/psi.c
index e14917c..adcfc82 100644
--- a/kernel/kernel/sched/psi.c
+++ b/kernel/kernel/sched/psi.c
@@ -1225,10 +1225,11 @@
 
 	group = t->group;
 	/*
-	 * Wakeup waiters to stop polling. Can happen if cgroup is deleted
-	 * from under a polling process.
+	 * Wakeup waiters to stop polling and clear the queue to prevent it from
+	 * being accessed later. Can happen if cgroup is deleted from under a
+	 * polling process.
 	 */
-	wake_up_interruptible(&t->event_wait);
+	wake_up_pollfree(&t->event_wait);
 
 	mutex_lock(&group->trigger_lock);
 
diff --git a/kernel/kernel/sched/rt.c b/kernel/kernel/sched/rt.c
index 651f578..de4a16e 100644
--- a/kernel/kernel/sched/rt.c
+++ b/kernel/kernel/sched/rt.c
@@ -1696,8 +1696,7 @@
 	rt_queue_push_tasks(rq);
 }
 
-static struct sched_rt_entity *pick_next_rt_entity(struct rq *rq,
-						   struct rt_rq *rt_rq)
+static struct sched_rt_entity *pick_next_rt_entity(struct rt_rq *rt_rq)
 {
 	struct rt_prio_array *array = &rt_rq->active;
 	struct sched_rt_entity *next = NULL;
@@ -1708,6 +1707,8 @@
 	BUG_ON(idx >= MAX_RT_PRIO);
 
 	queue = array->queue + idx;
+	if (SCHED_WARN_ON(list_empty(queue)))
+		return NULL;
 	next = list_entry(queue->next, struct sched_rt_entity, run_list);
 
 	return next;
@@ -1719,8 +1720,9 @@
 	struct rt_rq *rt_rq  = &rq->rt;
 
 	do {
-		rt_se = pick_next_rt_entity(rq, rt_rq);
-		BUG_ON(!rt_se);
+		rt_se = pick_next_rt_entity(rt_rq);
+		if (unlikely(!rt_se))
+			return NULL;
 		rt_rq = group_rt_rq(rt_se);
 	} while (rt_rq);
 
diff --git a/kernel/kernel/sched/sched.h b/kernel/kernel/sched/sched.h
index 9e798c5..e2eef69 100644
--- a/kernel/kernel/sched/sched.h
+++ b/kernel/kernel/sched/sched.h
@@ -351,7 +351,7 @@
 extern bool __checkparam_dl(const struct sched_attr *attr);
 extern bool dl_param_changed(struct task_struct *p, const struct sched_attr *attr);
 extern int  dl_cpuset_cpumask_can_shrink(const struct cpumask *cur, const struct cpumask *trial);
-extern int  dl_cpu_busy(int cpu, struct task_struct *p);
+extern int  dl_bw_check_overflow(int cpu);
 
 #ifdef CONFIG_CGROUP_SCHED
 
@@ -2459,6 +2459,23 @@
 #ifdef CONFIG_UCLAMP_TASK
 unsigned long uclamp_eff_value(struct task_struct *p, enum uclamp_id clamp_id);
 
+static inline unsigned long uclamp_rq_get(struct rq *rq,
+					  enum uclamp_id clamp_id)
+{
+	return READ_ONCE(rq->uclamp[clamp_id].value);
+}
+
+static inline void uclamp_rq_set(struct rq *rq, enum uclamp_id clamp_id,
+				 unsigned int value)
+{
+	WRITE_ONCE(rq->uclamp[clamp_id].value, value);
+}
+
+static inline bool uclamp_rq_is_idle(struct rq *rq)
+{
+	return rq->uclamp_flags & UCLAMP_FLAG_IDLE;
+}
+
 /**
  * uclamp_rq_util_with - clamp @util with @rq and @p effective uclamp values.
  * @rq:		The rq to clamp against. Must not be NULL.
@@ -2494,12 +2511,12 @@
 		 * Ignore last runnable task's max clamp, as this task will
 		 * reset it. Similarly, no need to read the rq's min clamp.
 		 */
-		if (rq->uclamp_flags & UCLAMP_FLAG_IDLE)
+		if (uclamp_rq_is_idle(rq))
 			goto out;
 	}
 
-	min_util = max_t(unsigned long, min_util, READ_ONCE(rq->uclamp[UCLAMP_MIN].value));
-	max_util = max_t(unsigned long, max_util, READ_ONCE(rq->uclamp[UCLAMP_MAX].value));
+	min_util = max_t(unsigned long, min_util, uclamp_rq_get(rq, UCLAMP_MIN));
+	max_util = max_t(unsigned long, max_util, uclamp_rq_get(rq, UCLAMP_MAX));
 out:
 	/*
 	 * Since CPU's {min,max}_util clamps are MAX aggregated considering
@@ -2530,6 +2547,15 @@
 	return static_branch_likely(&sched_uclamp_used);
 }
 #else /* CONFIG_UCLAMP_TASK */
+static inline unsigned long uclamp_eff_value(struct task_struct *p,
+					     enum uclamp_id clamp_id)
+{
+	if (clamp_id == UCLAMP_MIN)
+		return 0;
+
+	return SCHED_CAPACITY_SCALE;
+}
+
 static inline
 unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util,
 				  struct task_struct *p)
@@ -2546,6 +2572,25 @@
 {
 	return false;
 }
+
+static inline unsigned long uclamp_rq_get(struct rq *rq,
+					  enum uclamp_id clamp_id)
+{
+	if (clamp_id == UCLAMP_MIN)
+		return 0;
+
+	return SCHED_CAPACITY_SCALE;
+}
+
+static inline void uclamp_rq_set(struct rq *rq, enum uclamp_id clamp_id,
+				 unsigned int value)
+{
+}
+
+static inline bool uclamp_rq_is_idle(struct rq *rq)
+{
+	return false;
+}
 #endif /* CONFIG_UCLAMP_TASK */
 
 #ifdef CONFIG_UCLAMP_TASK_GROUP
diff --git a/kernel/kernel/sys.c b/kernel/kernel/sys.c
index 980e3ab..4b02327 100644
--- a/kernel/kernel/sys.c
+++ b/kernel/kernel/sys.c
@@ -644,6 +644,7 @@
 	struct cred *new;
 	int retval;
 	kuid_t kruid, keuid, ksuid;
+	bool ruid_new, euid_new, suid_new;
 
 	kruid = make_kuid(ns, ruid);
 	keuid = make_kuid(ns, euid);
@@ -658,24 +659,28 @@
 	if ((suid != (uid_t) -1) && !uid_valid(ksuid))
 		return -EINVAL;
 
+	old = current_cred();
+
+	/* check for no-op */
+	if ((ruid == (uid_t) -1 || uid_eq(kruid, old->uid)) &&
+	    (euid == (uid_t) -1 || (uid_eq(keuid, old->euid) &&
+				    uid_eq(keuid, old->fsuid))) &&
+	    (suid == (uid_t) -1 || uid_eq(ksuid, old->suid)))
+		return 0;
+
+	ruid_new = ruid != (uid_t) -1        && !uid_eq(kruid, old->uid) &&
+		   !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid);
+	euid_new = euid != (uid_t) -1        && !uid_eq(keuid, old->uid) &&
+		   !uid_eq(keuid, old->euid) && !uid_eq(keuid, old->suid);
+	suid_new = suid != (uid_t) -1        && !uid_eq(ksuid, old->uid) &&
+		   !uid_eq(ksuid, old->euid) && !uid_eq(ksuid, old->suid);
+	if ((ruid_new || euid_new || suid_new) &&
+	    !ns_capable_setid(old->user_ns, CAP_SETUID))
+		return -EPERM;
+
 	new = prepare_creds();
 	if (!new)
 		return -ENOMEM;
-
-	old = current_cred();
-
-	retval = -EPERM;
-	if (!ns_capable_setid(old->user_ns, CAP_SETUID)) {
-		if (ruid != (uid_t) -1        && !uid_eq(kruid, old->uid) &&
-		    !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid))
-			goto error;
-		if (euid != (uid_t) -1        && !uid_eq(keuid, old->uid) &&
-		    !uid_eq(keuid, old->euid) && !uid_eq(keuid, old->suid))
-			goto error;
-		if (suid != (uid_t) -1        && !uid_eq(ksuid, old->uid) &&
-		    !uid_eq(ksuid, old->euid) && !uid_eq(ksuid, old->suid))
-			goto error;
-	}
 
 	if (ruid != (uid_t) -1) {
 		new->uid = kruid;
@@ -736,6 +741,7 @@
 	struct cred *new;
 	int retval;
 	kgid_t krgid, kegid, ksgid;
+	bool rgid_new, egid_new, sgid_new;
 
 	krgid = make_kgid(ns, rgid);
 	kegid = make_kgid(ns, egid);
@@ -748,23 +754,28 @@
 	if ((sgid != (gid_t) -1) && !gid_valid(ksgid))
 		return -EINVAL;
 
+	old = current_cred();
+
+	/* check for no-op */
+	if ((rgid == (gid_t) -1 || gid_eq(krgid, old->gid)) &&
+	    (egid == (gid_t) -1 || (gid_eq(kegid, old->egid) &&
+				    gid_eq(kegid, old->fsgid))) &&
+	    (sgid == (gid_t) -1 || gid_eq(ksgid, old->sgid)))
+		return 0;
+
+	rgid_new = rgid != (gid_t) -1        && !gid_eq(krgid, old->gid) &&
+		   !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid);
+	egid_new = egid != (gid_t) -1        && !gid_eq(kegid, old->gid) &&
+		   !gid_eq(kegid, old->egid) && !gid_eq(kegid, old->sgid);
+	sgid_new = sgid != (gid_t) -1        && !gid_eq(ksgid, old->gid) &&
+		   !gid_eq(ksgid, old->egid) && !gid_eq(ksgid, old->sgid);
+	if ((rgid_new || egid_new || sgid_new) &&
+	    !ns_capable_setid(old->user_ns, CAP_SETGID))
+		return -EPERM;
+
 	new = prepare_creds();
 	if (!new)
 		return -ENOMEM;
-	old = current_cred();
-
-	retval = -EPERM;
-	if (!ns_capable_setid(old->user_ns, CAP_SETGID)) {
-		if (rgid != (gid_t) -1        && !gid_eq(krgid, old->gid) &&
-		    !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid))
-			goto error;
-		if (egid != (gid_t) -1        && !gid_eq(kegid, old->gid) &&
-		    !gid_eq(kegid, old->egid) && !gid_eq(kegid, old->sgid))
-			goto error;
-		if (sgid != (gid_t) -1        && !gid_eq(ksgid, old->gid) &&
-		    !gid_eq(ksgid, old->egid) && !gid_eq(ksgid, old->sgid))
-			goto error;
-	}
 
 	if (rgid != (gid_t) -1)
 		new->gid = krgid;
@@ -1558,6 +1569,8 @@
 
 	if (resource >= RLIM_NLIMITS)
 		return -EINVAL;
+	resource = array_index_nospec(resource, RLIM_NLIMITS);
+
 	if (new_rlim) {
 		if (new_rlim->rlim_cur > new_rlim->rlim_max)
 			return -EINVAL;
diff --git a/kernel/kernel/sysctl.c b/kernel/kernel/sysctl.c
index 5c8a7d6..06b82a3 100644
--- a/kernel/kernel/sysctl.c
+++ b/kernel/kernel/sysctl.c
@@ -114,15 +114,9 @@
 static int sixty = 60;
 #endif
 
-static int __maybe_unused neg_one = -1;
-static int __maybe_unused two = 2;
-static int __maybe_unused four = 4;
 static unsigned long zero_ul;
 static unsigned long one_ul = 1;
 static unsigned long long_max = LONG_MAX;
-static int one_hundred = 100;
-static int two_hundred = 200;
-static int one_thousand = 1000;
 #ifdef CONFIG_PRINTK
 static int ten_thousand = 10000;
 #endif
@@ -1064,6 +1058,65 @@
 				 do_proc_douintvec_minmax_conv, &param);
 }
 
+/**
+ * proc_dou8vec_minmax - read a vector of unsigned chars with min/max values
+ * @table: the sysctl table
+ * @write: %TRUE if this is a write to the sysctl file
+ * @buffer: the user buffer
+ * @lenp: the size of the user buffer
+ * @ppos: file position
+ *
+ * Reads/writes up to table->maxlen/sizeof(u8) unsigned chars
+ * values from/to the user buffer, treated as an ASCII string. Negative
+ * strings are not allowed.
+ *
+ * This routine will ensure the values are within the range specified by
+ * table->extra1 (min) and table->extra2 (max).
+ *
+ * Returns 0 on success or an error on write when the range check fails.
+ */
+int proc_dou8vec_minmax(struct ctl_table *table, int write,
+			void *buffer, size_t *lenp, loff_t *ppos)
+{
+	struct ctl_table tmp;
+	unsigned int min = 0, max = 255U, val;
+	u8 *data = table->data;
+	struct do_proc_douintvec_minmax_conv_param param = {
+		.min = &min,
+		.max = &max,
+	};
+	int res;
+
+	/* Do not support arrays yet. */
+	if (table->maxlen != sizeof(u8))
+		return -EINVAL;
+
+	if (table->extra1) {
+		min = *(unsigned int *) table->extra1;
+		if (min > 255U)
+			return -EINVAL;
+	}
+	if (table->extra2) {
+		max = *(unsigned int *) table->extra2;
+		if (max > 255U)
+			return -EINVAL;
+	}
+
+	tmp = *table;
+
+	tmp.maxlen = sizeof(val);
+	tmp.data = &val;
+	val = READ_ONCE(*data);
+	res = do_proc_douintvec(&tmp, write, buffer, lenp, ppos,
+				do_proc_douintvec_minmax_conv, &param);
+	if (res)
+		return res;
+	if (write)
+		WRITE_ONCE(*data, val);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(proc_dou8vec_minmax);
+
 static int do_proc_dopipe_max_size_conv(unsigned long *lvalp,
 					unsigned int *valp,
 					int write, void *data)
@@ -1615,6 +1668,12 @@
 	return -ENOSYS;
 }
 
+int proc_dou8vec_minmax(struct ctl_table *table, int write,
+			void *buffer, size_t *lenp, loff_t *ppos)
+{
+	return -ENOSYS;
+}
+
 int proc_dointvec_jiffies(struct ctl_table *table, int write,
 		    void *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -1964,7 +2023,7 @@
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &neg_one,
+		.extra1		= SYSCTL_NEG_ONE,
 		.extra2		= SYSCTL_ONE,
 	},
 #endif
@@ -2218,17 +2277,6 @@
 		.proc_handler	= proc_dointvec,
 	},
 #endif
-#ifdef CONFIG_SMP
-	{
-		.procname	= "oops_all_cpu_backtrace",
-		.data		= &sysctl_oops_all_cpu_backtrace,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= SYSCTL_ZERO,
-		.extra2		= SYSCTL_ONE,
-	},
-#endif /* CONFIG_SMP */
 	{
 		.procname	= "pid_max",
 		.data		= &pid_max,
@@ -2306,7 +2354,7 @@
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax_sysadmin,
 		.extra1		= SYSCTL_ZERO,
-		.extra2		= &two,
+		.extra2		= SYSCTL_TWO,
 	},
 #endif
 	{
@@ -2566,7 +2614,7 @@
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &neg_one,
+		.extra1		= SYSCTL_NEG_ONE,
 	},
 #endif
 #ifdef CONFIG_RT_MUTEXES
@@ -2628,7 +2676,7 @@
 		.mode		= 0644,
 		.proc_handler	= perf_cpu_time_max_percent_handler,
 		.extra1		= SYSCTL_ZERO,
-		.extra2		= &one_hundred,
+		.extra2		= SYSCTL_ONE_HUNDRED,
 	},
 	{
 		.procname	= "perf_event_max_stack",
@@ -2646,7 +2694,7 @@
 		.mode		= 0644,
 		.proc_handler	= perf_event_max_stack_handler,
 		.extra1		= SYSCTL_ZERO,
-		.extra2		= &one_thousand,
+		.extra2		= SYSCTL_ONE_THOUSAND,
 	},
 #endif
 	{
@@ -2677,7 +2725,7 @@
 		.mode		= 0644,
 		.proc_handler	= bpf_unpriv_handler,
 		.extra1		= SYSCTL_ZERO,
-		.extra2		= &two,
+		.extra2		= SYSCTL_TWO,
 	},
 	{
 		.procname	= "bpf_stats_enabled",
@@ -2720,7 +2768,7 @@
 		.mode		= 0644,
 		.proc_handler	= overcommit_policy_handler,
 		.extra1		= SYSCTL_ZERO,
-		.extra2		= &two,
+		.extra2		= SYSCTL_TWO,
 	},
 	{
 		.procname	= "panic_on_oom",
@@ -2729,7 +2777,7 @@
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
 		.extra1		= SYSCTL_ZERO,
-		.extra2		= &two,
+		.extra2		= SYSCTL_TWO,
 	},
 	{
 		.procname	= "oom_kill_allocating_task",
@@ -2774,7 +2822,7 @@
 		.mode		= 0644,
 		.proc_handler	= dirty_background_ratio_handler,
 		.extra1		= SYSCTL_ZERO,
-		.extra2		= &one_hundred,
+		.extra2		= SYSCTL_ONE_HUNDRED,
 	},
 	{
 		.procname	= "dirty_background_bytes",
@@ -2791,7 +2839,7 @@
 		.mode		= 0644,
 		.proc_handler	= dirty_ratio_handler,
 		.extra1		= SYSCTL_ZERO,
-		.extra2		= &one_hundred,
+		.extra2		= SYSCTL_ONE_HUNDRED,
 	},
 	{
 		.procname	= "dirty_bytes",
@@ -2831,7 +2879,7 @@
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
 		.extra1		= SYSCTL_ZERO,
-		.extra2		= &two_hundred,
+		.extra2		= SYSCTL_TWO_HUNDRED,
 	},
 #ifdef CONFIG_NUMA
 	{
@@ -2890,7 +2938,7 @@
 		.mode		= 0200,
 		.proc_handler	= drop_caches_sysctl_handler,
 		.extra1		= SYSCTL_ONE,
-		.extra2		= &four,
+		.extra2		= SYSCTL_FOUR,
 	},
 #ifdef CONFIG_COMPACTION
 	{
@@ -2907,7 +2955,7 @@
 		.mode		= 0644,
 		.proc_handler	= compaction_proactiveness_sysctl_handler,
 		.extra1		= SYSCTL_ZERO,
-		.extra2		= &one_hundred,
+		.extra2		= SYSCTL_ONE_HUNDRED,
 	},
 	{
 		.procname	= "extfrag_threshold",
@@ -2952,7 +3000,7 @@
 		.mode		= 0644,
 		.proc_handler	= watermark_scale_factor_sysctl_handler,
 		.extra1		= SYSCTL_ONE,
-		.extra2		= &one_thousand,
+		.extra2		= SYSCTL_THREE_THOUSAND,
 	},
 	{
 		.procname	= "extra_free_kbytes",
@@ -3047,7 +3095,7 @@
 		.mode		= 0644,
 		.proc_handler	= sysctl_min_unmapped_ratio_sysctl_handler,
 		.extra1		= SYSCTL_ZERO,
-		.extra2		= &one_hundred,
+		.extra2		= SYSCTL_ONE_HUNDRED,
 	},
 	{
 		.procname	= "min_slab_ratio",
@@ -3056,7 +3104,7 @@
 		.mode		= 0644,
 		.proc_handler	= sysctl_min_slab_ratio_sysctl_handler,
 		.extra1		= SYSCTL_ZERO,
-		.extra2		= &one_hundred,
+		.extra2		= SYSCTL_ONE_HUNDRED,
 	},
 #endif
 #ifdef CONFIG_SMP
@@ -3339,7 +3387,7 @@
 		.mode		= 0600,
 		.proc_handler	= proc_dointvec_minmax,
 		.extra1		= SYSCTL_ZERO,
-		.extra2		= &two,
+		.extra2		= SYSCTL_TWO,
 	},
 	{
 		.procname	= "protected_regular",
@@ -3348,7 +3396,7 @@
 		.mode		= 0600,
 		.proc_handler	= proc_dointvec_minmax,
 		.extra1		= SYSCTL_ZERO,
-		.extra2		= &two,
+		.extra2		= SYSCTL_TWO,
 	},
 	{
 		.procname	= "suid_dumpable",
@@ -3357,7 +3405,7 @@
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax_coredump,
 		.extra1		= SYSCTL_ZERO,
-		.extra2		= &two,
+		.extra2		= SYSCTL_TWO,
 	},
 #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
 	{
diff --git a/kernel/kernel/time/alarmtimer.c b/kernel/kernel/time/alarmtimer.c
index daeaa71..3a20a9f 100644
--- a/kernel/kernel/time/alarmtimer.c
+++ b/kernel/kernel/time/alarmtimer.c
@@ -33,6 +33,8 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/alarmtimer.h>
 
+#undef CREATE_TRACE_POINTS
+#include <trace/hooks/wakeupbypass.h>
 /**
  * struct alarm_base - Alarm timer bases
  * @lock:		Lock for syncrhonized access to the base
@@ -246,6 +248,7 @@
 	struct rtc_device *rtc;
 	unsigned long flags;
 	struct rtc_time tm;
+	int wakeup_bypass_enabled = 0;
 
 	spin_lock_irqsave(&freezer_delta_lock, flags);
 	min = freezer_delta;
@@ -253,6 +256,10 @@
 	type = freezer_alarmtype;
 	freezer_delta = 0;
 	spin_unlock_irqrestore(&freezer_delta_lock, flags);
+
+	trace_android_vh_wakeup_bypass(&wakeup_bypass_enabled);
+	if (wakeup_bypass_enabled)
+		return 0;
 
 	rtc = alarmtimer_get_rtcdev();
 	/* If we have no rtcdev, just return */
@@ -470,11 +477,35 @@
 }
 EXPORT_SYMBOL_GPL(alarm_forward);
 
-u64 alarm_forward_now(struct alarm *alarm, ktime_t interval)
+static u64 __alarm_forward_now(struct alarm *alarm, ktime_t interval, bool throttle)
 {
 	struct alarm_base *base = &alarm_bases[alarm->type];
+	ktime_t now = base->get_ktime();
 
-	return alarm_forward(alarm, base->get_ktime(), interval);
+	if (IS_ENABLED(CONFIG_HIGH_RES_TIMERS) && throttle) {
+		/*
+		 * Same issue as with posix_timer_fn(). Timers which are
+		 * periodic but the signal is ignored can starve the system
+		 * with a very small interval. The real fix which was
+		 * promised in the context of posix_timer_fn() never
+		 * materialized, but someone should really work on it.
+		 *
+		 * To prevent DOS fake @now to be 1 jiffie out which keeps
+		 * the overrun accounting correct but creates an
+		 * inconsistency vs. timer_gettime(2).
+		 */
+		ktime_t kj = NSEC_PER_SEC / HZ;
+
+		if (interval < kj)
+			now = ktime_add(now, kj);
+	}
+
+	return alarm_forward(alarm, now, interval);
+}
+
+u64 alarm_forward_now(struct alarm *alarm, ktime_t interval)
+{
+	return __alarm_forward_now(alarm, interval, false);
 }
 EXPORT_SYMBOL_GPL(alarm_forward_now);
 
@@ -548,9 +579,10 @@
 	if (posix_timer_event(ptr, si_private) && ptr->it_interval) {
 		/*
 		 * Handle ignored signals and rearm the timer. This will go
-		 * away once we handle ignored signals proper.
+		 * away once we handle ignored signals proper. Ensure that
+		 * small intervals cannot starve the system.
 		 */
-		ptr->it_overrun += alarm_forward_now(alarm, ptr->it_interval);
+		ptr->it_overrun += __alarm_forward_now(alarm, ptr->it_interval, true);
 		++ptr->it_requeue_pending;
 		ptr->it_active = 1;
 		result = ALARMTIMER_RESTART;
diff --git a/kernel/kernel/time/hrtimer.c b/kernel/kernel/time/hrtimer.c
index 544ce87..70deb2f 100644
--- a/kernel/kernel/time/hrtimer.c
+++ b/kernel/kernel/time/hrtimer.c
@@ -2024,6 +2024,7 @@
 	if (!timespec64_valid(&tu))
 		return -EINVAL;
 
+	current->restart_block.fn = do_no_restart_syscall;
 	current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
 	current->restart_block.nanosleep.rmtp = rmtp;
 	return hrtimer_nanosleep(timespec64_to_ktime(tu), HRTIMER_MODE_REL,
@@ -2045,6 +2046,7 @@
 	if (!timespec64_valid(&tu))
 		return -EINVAL;
 
+	current->restart_block.fn = do_no_restart_syscall;
 	current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
 	current->restart_block.nanosleep.compat_rmtp = rmtp;
 	return hrtimer_nanosleep(timespec64_to_ktime(tu), HRTIMER_MODE_REL,
diff --git a/kernel/kernel/time/posix-cpu-timers.c b/kernel/kernel/time/posix-cpu-timers.c
index 5d76edd..bede1e6 100644
--- a/kernel/kernel/time/posix-cpu-timers.c
+++ b/kernel/kernel/time/posix-cpu-timers.c
@@ -782,6 +782,8 @@
 			return expires;
 
 		ctmr->firing = 1;
+		/* See posix_cpu_timer_wait_running() */
+		rcu_assign_pointer(ctmr->handling, current);
 		cpu_timer_dequeue(ctmr);
 		list_add_tail(&ctmr->elist, firing);
 	}
@@ -1097,7 +1099,49 @@
 #ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK
 static void posix_cpu_timers_work(struct callback_head *work)
 {
+	struct posix_cputimers_work *cw = container_of(work, typeof(*cw), work);
+
+	mutex_lock(&cw->mutex);
 	handle_posix_cpu_timers(current);
+	mutex_unlock(&cw->mutex);
+}
+
+/*
+ * Invoked from the posix-timer core when a cancel operation failed because
+ * the timer is marked firing. The caller holds rcu_read_lock(), which
+ * protects the timer and the task which is expiring it from being freed.
+ */
+static void posix_cpu_timer_wait_running(struct k_itimer *timr)
+{
+	struct task_struct *tsk = rcu_dereference(timr->it.cpu.handling);
+
+	/* Has the handling task completed expiry already? */
+	if (!tsk)
+		return;
+
+	/* Ensure that the task cannot go away */
+	get_task_struct(tsk);
+	/* Now drop the RCU protection so the mutex can be locked */
+	rcu_read_unlock();
+	/* Wait on the expiry mutex */
+	mutex_lock(&tsk->posix_cputimers_work.mutex);
+	/* Release it immediately again. */
+	mutex_unlock(&tsk->posix_cputimers_work.mutex);
+	/* Drop the task reference. */
+	put_task_struct(tsk);
+	/* Relock RCU so the callsite is balanced */
+	rcu_read_lock();
+}
+
+static void posix_cpu_timer_wait_running_nsleep(struct k_itimer *timr)
+{
+	/* Ensure that timr->it.cpu.handling task cannot go away */
+	rcu_read_lock();
+	spin_unlock_irq(&timr->it_lock);
+	posix_cpu_timer_wait_running(timr);
+	rcu_read_unlock();
+	/* @timr is on stack and is valid */
+	spin_lock_irq(&timr->it_lock);
 }
 
 /*
@@ -1113,6 +1157,7 @@
 	       sizeof(p->posix_cputimers_work.work));
 	init_task_work(&p->posix_cputimers_work.work,
 		       posix_cpu_timers_work);
+	mutex_init(&p->posix_cputimers_work.mutex);
 	p->posix_cputimers_work.scheduled = false;
 }
 
@@ -1189,6 +1234,18 @@
 	lockdep_posixtimer_enter();
 	handle_posix_cpu_timers(tsk);
 	lockdep_posixtimer_exit();
+}
+
+static void posix_cpu_timer_wait_running(struct k_itimer *timr)
+{
+	cpu_relax();
+}
+
+static void posix_cpu_timer_wait_running_nsleep(struct k_itimer *timr)
+{
+	spin_unlock_irq(&timr->it_lock);
+	cpu_relax();
+	spin_lock_irq(&timr->it_lock);
 }
 
 static inline bool posix_cpu_timers_work_scheduled(struct task_struct *tsk)
@@ -1299,6 +1356,8 @@
 		 */
 		if (likely(cpu_firing >= 0))
 			cpu_timer_fire(timer);
+		/* See posix_cpu_timer_wait_running() */
+		rcu_assign_pointer(timer->it.cpu.handling, NULL);
 		spin_unlock(&timer->it_lock);
 	}
 }
@@ -1434,23 +1493,16 @@
 		expires = cpu_timer_getexpires(&timer.it.cpu);
 		error = posix_cpu_timer_set(&timer, 0, &zero_it, &it);
 		if (!error) {
-			/*
-			 * Timer is now unarmed, deletion can not fail.
-			 */
+			/* Timer is now unarmed, deletion can not fail. */
 			posix_cpu_timer_del(&timer);
+		} else {
+			while (error == TIMER_RETRY) {
+				posix_cpu_timer_wait_running_nsleep(&timer);
+				error = posix_cpu_timer_del(&timer);
+			}
 		}
-		spin_unlock_irq(&timer.it_lock);
 
-		while (error == TIMER_RETRY) {
-			/*
-			 * We need to handle case when timer was or is in the
-			 * middle of firing. In other cases we already freed
-			 * resources.
-			 */
-			spin_lock_irq(&timer.it_lock);
-			error = posix_cpu_timer_del(&timer);
-			spin_unlock_irq(&timer.it_lock);
-		}
+		spin_unlock_irq(&timer.it_lock);
 
 		if ((it.it_value.tv_sec | it.it_value.tv_nsec) == 0) {
 			/*
@@ -1560,6 +1612,7 @@
 	.timer_del		= posix_cpu_timer_del,
 	.timer_get		= posix_cpu_timer_get,
 	.timer_rearm		= posix_cpu_timer_rearm,
+	.timer_wait_running	= posix_cpu_timer_wait_running,
 };
 
 const struct k_clock clock_process = {
diff --git a/kernel/kernel/time/posix-stubs.c b/kernel/kernel/time/posix-stubs.c
index fcb3b21..3783d07 100644
--- a/kernel/kernel/time/posix-stubs.c
+++ b/kernel/kernel/time/posix-stubs.c
@@ -146,6 +146,7 @@
 		return -EINVAL;
 	if (flags & TIMER_ABSTIME)
 		rmtp = NULL;
+	current->restart_block.fn = do_no_restart_syscall;
 	current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
 	current->restart_block.nanosleep.rmtp = rmtp;
 	texp = timespec64_to_ktime(t);
@@ -239,6 +240,7 @@
 		return -EINVAL;
 	if (flags & TIMER_ABSTIME)
 		rmtp = NULL;
+	current->restart_block.fn = do_no_restart_syscall;
 	current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
 	current->restart_block.nanosleep.compat_rmtp = rmtp;
 	texp = timespec64_to_ktime(t);
diff --git a/kernel/kernel/time/posix-timers.c b/kernel/kernel/time/posix-timers.c
index b624788..6d12a72 100644
--- a/kernel/kernel/time/posix-timers.c
+++ b/kernel/kernel/time/posix-timers.c
@@ -846,6 +846,10 @@
 	rcu_read_lock();
 	unlock_timer(timer, *flags);
 
+	/*
+	 * kc->timer_wait_running() might drop RCU lock. So @timer
+	 * cannot be touched anymore after the function returns!
+	 */
 	if (!WARN_ON_ONCE(!kc->timer_wait_running))
 		kc->timer_wait_running(timer);
 
@@ -1033,27 +1037,52 @@
 }
 
 /*
- * return timer owned by the process, used by exit_itimers
+ * Delete a timer if it is armed, remove it from the hash and schedule it
+ * for RCU freeing.
  */
 static void itimer_delete(struct k_itimer *timer)
 {
-retry_delete:
-	spin_lock_irq(&timer->it_lock);
+	unsigned long flags;
 
+	/*
+	 * irqsave is required to make timer_wait_running() work.
+	 */
+	spin_lock_irqsave(&timer->it_lock, flags);
+
+retry_delete:
+	/*
+	 * Even if the timer is not longer accessible from other tasks
+	 * it still might be armed and queued in the underlying timer
+	 * mechanism. Worse, that timer mechanism might run the expiry
+	 * function concurrently.
+	 */
 	if (timer_delete_hook(timer) == TIMER_RETRY) {
-		spin_unlock_irq(&timer->it_lock);
+		/*
+		 * Timer is expired concurrently, prevent livelocks
+		 * and pointless spinning on RT.
+		 *
+		 * timer_wait_running() drops timer::it_lock, which opens
+		 * the possibility for another task to delete the timer.
+		 *
+		 * That's not possible here because this is invoked from
+		 * do_exit() only for the last thread of the thread group.
+		 * So no other task can access and delete that timer.
+		 */
+		if (WARN_ON_ONCE(timer_wait_running(timer, &flags) != timer))
+			return;
+
 		goto retry_delete;
 	}
 	list_del(&timer->list);
 
-	spin_unlock_irq(&timer->it_lock);
+	spin_unlock_irqrestore(&timer->it_lock, flags);
 	release_posix_timer(timer, IT_ID_SET);
 }
 
 /*
- * This is called by do_exit or de_thread, only when nobody else can
- * modify the signal->posix_timers list. Yet we need sighand->siglock
- * to prevent the race with /proc/pid/timers.
+ * Invoked from do_exit() when the last thread of a thread group exits.
+ * At that point no other task can access the timers of the dying
+ * task anymore.
  */
 void exit_itimers(struct task_struct *tsk)
 {
@@ -1063,10 +1092,12 @@
 	if (list_empty(&tsk->signal->posix_timers))
 		return;
 
+	/* Protect against concurrent read via /proc/$PID/timers */
 	spin_lock_irq(&tsk->sighand->siglock);
 	list_replace_init(&tsk->signal->posix_timers, &timers);
 	spin_unlock_irq(&tsk->sighand->siglock);
 
+	/* The timers are not longer accessible via tsk::signal */
 	while (!list_empty(&timers)) {
 		tmr = list_first_entry(&timers, struct k_itimer, list);
 		itimer_delete(tmr);
@@ -1270,6 +1301,7 @@
 		return -EINVAL;
 	if (flags & TIMER_ABSTIME)
 		rmtp = NULL;
+	current->restart_block.fn = do_no_restart_syscall;
 	current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
 	current->restart_block.nanosleep.rmtp = rmtp;
 
@@ -1297,6 +1329,7 @@
 		return -EINVAL;
 	if (flags & TIMER_ABSTIME)
 		rmtp = NULL;
+	current->restart_block.fn = do_no_restart_syscall;
 	current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
 	current->restart_block.nanosleep.compat_rmtp = rmtp;
 
diff --git a/kernel/kernel/time/tick-broadcast.c b/kernel/kernel/time/tick-broadcast.c
index 086d36b..b7b50e2 100644
--- a/kernel/kernel/time/tick-broadcast.c
+++ b/kernel/kernel/time/tick-broadcast.c
@@ -412,7 +412,7 @@
 	bc_local = tick_do_periodic_broadcast();
 
 	if (clockevent_state_oneshot(dev)) {
-		ktime_t next = ktime_add(dev->next_event, tick_period);
+		ktime_t next = ktime_add_ns(dev->next_event, TICK_NSEC);
 
 		clockevents_program_event(dev, next, true);
 	}
diff --git a/kernel/kernel/time/tick-common.c b/kernel/kernel/time/tick-common.c
index 572b4c0..c6a79c4 100644
--- a/kernel/kernel/time/tick-common.c
+++ b/kernel/kernel/time/tick-common.c
@@ -31,7 +31,6 @@
  * Tick next event: keeps track of the tick time
  */
 ktime_t tick_next_period;
-ktime_t tick_period;
 
 /*
  * tick_do_timer_cpu is a timer core internal variable which holds the CPU NR
@@ -89,7 +88,7 @@
 		write_seqcount_begin(&jiffies_seq);
 
 		/* Keep track of the next tick event */
-		tick_next_period = ktime_add(tick_next_period, tick_period);
+		tick_next_period = ktime_add_ns(tick_next_period, TICK_NSEC);
 
 		do_timer(1);
 		write_seqcount_end(&jiffies_seq);
@@ -129,7 +128,7 @@
 		 * Setup the next period for devices, which do not have
 		 * periodic mode:
 		 */
-		next = ktime_add(next, tick_period);
+		next = ktime_add_ns(next, TICK_NSEC);
 
 		if (!clockevents_program_event(dev, next, false))
 			return;
@@ -175,7 +174,7 @@
 		for (;;) {
 			if (!clockevents_program_event(dev, next, false))
 				return;
-			next = ktime_add(next, tick_period);
+			next = ktime_add_ns(next, TICK_NSEC);
 		}
 	}
 }
@@ -220,9 +219,7 @@
 		 */
 		if (tick_do_timer_cpu == TICK_DO_TIMER_BOOT) {
 			tick_do_timer_cpu = cpu;
-
 			tick_next_period = ktime_get();
-			tick_period = NSEC_PER_SEC / HZ;
 #ifdef CONFIG_NO_HZ_FULL
 			/*
 			 * The boot CPU may be nohz_full, in which case set
diff --git a/kernel/kernel/time/tick-internal.h b/kernel/kernel/time/tick-internal.h
index ab9cb68..cd610fa 100644
--- a/kernel/kernel/time/tick-internal.h
+++ b/kernel/kernel/time/tick-internal.h
@@ -15,7 +15,6 @@
 
 DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
 extern ktime_t tick_next_period;
-extern ktime_t tick_period;
 extern int tick_do_timer_cpu __read_mostly;
 
 extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
diff --git a/kernel/kernel/time/tick-sched.c b/kernel/kernel/time/tick-sched.c
index 07969fa..3b9c648 100644
--- a/kernel/kernel/time/tick-sched.c
+++ b/kernel/kernel/time/tick-sched.c
@@ -54,49 +54,67 @@
  */
 static void tick_do_update_jiffies64(ktime_t now)
 {
-	unsigned long ticks = 0;
+	unsigned long ticks = 1;
 	ktime_t delta;
 
 	/*
-	 * Do a quick check without holding jiffies_lock:
-	 * The READ_ONCE() pairs with two updates done later in this function.
+	 * Do a quick check without holding jiffies_lock. The READ_ONCE()
+	 * pairs with the update done later in this function.
+	 *
+	 * This is also an intentional data race which is even safe on
+	 * 32bit in theory. If there is a concurrent update then the check
+	 * might give a random answer. It does not matter because if it
+	 * returns then the concurrent update is already taking care, if it
+	 * falls through then it will pointlessly contend on jiffies_lock.
+	 *
+	 * Though there is one nasty case on 32bit due to store tearing of
+	 * the 64bit value. If the first 32bit store makes the quick check
+	 * return on all other CPUs and the writing CPU context gets
+	 * delayed to complete the second store (scheduled out on virt)
+	 * then jiffies can become stale for up to ~2^32 nanoseconds
+	 * without noticing. After that point all CPUs will wait for
+	 * jiffies lock.
+	 *
+	 * OTOH, this is not any different than the situation with NOHZ=off
+	 * where one CPU is responsible for updating jiffies and
+	 * timekeeping. If that CPU goes out for lunch then all other CPUs
+	 * will operate on stale jiffies until it decides to come back.
 	 */
-	delta = ktime_sub(now, READ_ONCE(last_jiffies_update));
-	if (delta < tick_period)
+	if (ktime_before(now, READ_ONCE(tick_next_period)))
 		return;
 
 	/* Reevaluate with jiffies_lock held */
 	raw_spin_lock(&jiffies_lock);
-	write_seqcount_begin(&jiffies_seq);
-
-	delta = ktime_sub(now, last_jiffies_update);
-	if (delta >= tick_period) {
-
-		delta = ktime_sub(delta, tick_period);
-		/* Pairs with the lockless read in this function. */
-		WRITE_ONCE(last_jiffies_update,
-			   ktime_add(last_jiffies_update, tick_period));
-
-		/* Slow path for long timeouts */
-		if (unlikely(delta >= tick_period)) {
-			s64 incr = ktime_to_ns(tick_period);
-
-			ticks = ktime_divns(delta, incr);
-
-			/* Pairs with the lockless read in this function. */
-			WRITE_ONCE(last_jiffies_update,
-				   ktime_add_ns(last_jiffies_update,
-						incr * ticks));
-		}
-		do_timer(++ticks);
-
-		/* Keep the tick_next_period variable up to date */
-		tick_next_period = ktime_add(last_jiffies_update, tick_period);
-	} else {
-		write_seqcount_end(&jiffies_seq);
+	if (ktime_before(now, tick_next_period)) {
 		raw_spin_unlock(&jiffies_lock);
 		return;
 	}
+
+	write_seqcount_begin(&jiffies_seq);
+
+	delta = ktime_sub(now, tick_next_period);
+	if (unlikely(delta >= TICK_NSEC)) {
+		/* Slow path for long idle sleep times */
+		s64 incr = TICK_NSEC;
+
+		ticks += ktime_divns(delta, incr);
+
+		last_jiffies_update = ktime_add_ns(last_jiffies_update,
+						   incr * ticks);
+	} else {
+		last_jiffies_update = ktime_add_ns(last_jiffies_update,
+						   TICK_NSEC);
+	}
+
+	do_timer(ticks);
+
+	/*
+	 * Keep the tick_next_period variable up to date.  WRITE_ONCE()
+	 * pairs with the READ_ONCE() in the lockless quick check above.
+	 */
+	WRITE_ONCE(tick_next_period,
+		   ktime_add_ns(last_jiffies_update, TICK_NSEC));
+
 	write_seqcount_end(&jiffies_seq);
 	raw_spin_unlock(&jiffies_lock);
 	update_wall_time();
@@ -112,13 +130,26 @@
 	raw_spin_lock(&jiffies_lock);
 	write_seqcount_begin(&jiffies_seq);
 	/* Did we start the jiffies update yet ? */
-	if (last_jiffies_update == 0)
+	if (last_jiffies_update == 0) {
+		u32 rem;
+
+		/*
+		 * Ensure that the tick is aligned to a multiple of
+		 * TICK_NSEC.
+		 */
+		div_u64_rem(tick_next_period, TICK_NSEC, &rem);
+		if (rem)
+			tick_next_period += TICK_NSEC - rem;
+
 		last_jiffies_update = tick_next_period;
+	}
 	period = last_jiffies_update;
 	write_seqcount_end(&jiffies_seq);
 	raw_spin_unlock(&jiffies_lock);
 	return period;
 }
+
+#define MAX_STALLED_JIFFIES 5
 
 static void tick_sched_do_timer(struct tick_sched *ts, ktime_t now)
 {
@@ -147,6 +178,21 @@
 	if (tick_do_timer_cpu == cpu) {
 		tick_do_update_jiffies64(now);
 		trace_android_vh_jiffies_update(NULL);
+	}
+
+	/*
+	 * If jiffies update stalled for too long (timekeeper in stop_machine()
+	 * or VMEXIT'ed for several msecs), force an update.
+	 */
+	if (ts->last_tick_jiffies != jiffies) {
+		ts->stalled_jiffies = 0;
+		ts->last_tick_jiffies = READ_ONCE(jiffies);
+	} else {
+		if (++ts->stalled_jiffies == MAX_STALLED_JIFFIES) {
+			tick_do_update_jiffies64(now);
+			ts->stalled_jiffies = 0;
+			ts->last_tick_jiffies = READ_ONCE(jiffies);
+		}
 	}
 
 	if (ts->inidle)
@@ -213,6 +259,11 @@
 
 	if (val & TICK_DEP_MASK_RCU) {
 		trace_tick_stop(0, TICK_DEP_MASK_RCU);
+		return true;
+	}
+
+	if (val & TICK_DEP_MASK_RCU_EXP) {
+		trace_tick_stop(0, TICK_DEP_MASK_RCU_EXP);
 		return true;
 	}
 
@@ -429,7 +480,7 @@
 	tick_nohz_full_running = true;
 }
 
-static int tick_nohz_cpu_down(unsigned int cpu)
+bool tick_nohz_cpu_hotpluggable(unsigned int cpu)
 {
 	/*
 	 * The tick_do_timer_cpu CPU handles housekeeping duty (unbound
@@ -437,8 +488,13 @@
 	 * CPUs. It must remain online when nohz full is enabled.
 	 */
 	if (tick_nohz_full_running && tick_do_timer_cpu == cpu)
-		return -EBUSY;
-	return 0;
+		return false;
+	return true;
+}
+
+static int tick_nohz_cpu_down(unsigned int cpu)
+{
+	return tick_nohz_cpu_hotpluggable(cpu) ? 0 : -EBUSY;
 }
 
 void __init tick_nohz_init(void)
@@ -663,7 +719,7 @@
 	hrtimer_set_expires(&ts->sched_timer, ts->last_tick);
 
 	/* Forward the time to expire in the future */
-	hrtimer_forward(&ts->sched_timer, now, tick_period);
+	hrtimer_forward(&ts->sched_timer, now, TICK_NSEC);
 
 	if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
 		hrtimer_start_expires(&ts->sched_timer,
@@ -831,6 +887,8 @@
 	if (unlikely(expires == KTIME_MAX)) {
 		if (ts->nohz_mode == NOHZ_MODE_HIGHRES)
 			hrtimer_cancel(&ts->sched_timer);
+		else
+			tick_program_event(KTIME_MAX, 1);
 		return;
 	}
 
@@ -1223,11 +1281,17 @@
 	tick_sched_do_timer(ts, now);
 	tick_sched_handle(ts, regs);
 
-	/* No need to reprogram if we are running tickless  */
-	if (unlikely(ts->tick_stopped))
+	if (unlikely(ts->tick_stopped)) {
+		/*
+		 * The clockevent device is not reprogrammed, so change the
+		 * clock event device to ONESHOT_STOPPED to avoid spurious
+		 * interrupts on devices which might not be truly one shot.
+		 */
+		tick_program_event(KTIME_MAX, 1);
 		return;
+	}
 
-	hrtimer_forward(&ts->sched_timer, now, tick_period);
+	hrtimer_forward(&ts->sched_timer, now, TICK_NSEC);
 	tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1);
 }
 
@@ -1264,7 +1328,7 @@
 	next = tick_init_jiffy_update();
 
 	hrtimer_set_expires(&ts->sched_timer, next);
-	hrtimer_forward_now(&ts->sched_timer, tick_period);
+	hrtimer_forward_now(&ts->sched_timer, TICK_NSEC);
 	tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1);
 	tick_nohz_activate(ts, NOHZ_MODE_LOWRES);
 }
@@ -1330,7 +1394,7 @@
 	if (unlikely(ts->tick_stopped))
 		return HRTIMER_NORESTART;
 
-	hrtimer_forward(timer, now, tick_period);
+	hrtimer_forward(timer, now, TICK_NSEC);
 
 	return HRTIMER_RESTART;
 }
@@ -1364,13 +1428,13 @@
 
 	/* Offset the tick to avert jiffies_lock contention. */
 	if (sched_skew_tick) {
-		u64 offset = ktime_to_ns(tick_period) >> 1;
+		u64 offset = TICK_NSEC >> 1;
 		do_div(offset, num_possible_cpus());
 		offset *= smp_processor_id();
 		hrtimer_add_expires_ns(&ts->sched_timer, offset);
 	}
 
-	hrtimer_forward(&ts->sched_timer, now, tick_period);
+	hrtimer_forward(&ts->sched_timer, now, TICK_NSEC);
 	hrtimer_start_expires(&ts->sched_timer, HRTIMER_MODE_ABS_PINNED_HARD);
 	tick_nohz_activate(ts, NOHZ_MODE_HIGHRES);
 }
diff --git a/kernel/kernel/time/tick-sched.h b/kernel/kernel/time/tick-sched.h
index 4fb0652..1e7ec5c 100644
--- a/kernel/kernel/time/tick-sched.h
+++ b/kernel/kernel/time/tick-sched.h
@@ -49,6 +49,8 @@
  * @timer_expires_base:	Base time clock monotonic for @timer_expires
  * @next_timer:		Expiry time of next expiring timer for debugging purpose only
  * @tick_dep_mask:	Tick dependency mask - is set, if someone needs the tick
+ * @last_tick_jiffies:	Value of jiffies seen on last tick
+ * @stalled_jiffies:	Number of stalled jiffies detected across ticks
  */
 struct tick_sched {
 	struct hrtimer			sched_timer;
@@ -77,6 +79,8 @@
 	u64				next_timer;
 	ktime_t				idle_expires;
 	atomic_t			tick_dep_mask;
+	unsigned long			last_tick_jiffies;
+	unsigned int			stalled_jiffies;
 };
 
 extern struct tick_sched *tick_get_tick_sched(int cpu);
diff --git a/kernel/kernel/torture.c b/kernel/kernel/torture.c
index 1061492..458a5ee 100644
--- a/kernel/kernel/torture.c
+++ b/kernel/kernel/torture.c
@@ -788,7 +788,7 @@
 	VERBOSE_TOROUT_STRING(buf);
 	while (!kthread_should_stop()) {
 		torture_shutdown_absorb(title);
-		schedule_timeout_uninterruptible(1);
+		schedule_timeout_uninterruptible(HZ / 20);
 	}
 }
 EXPORT_SYMBOL_GPL(torture_kthread_stopping);
diff --git a/kernel/kernel/trace/blktrace.c b/kernel/kernel/trace/blktrace.c
index b89ff18..a9456ae 100644
--- a/kernel/kernel/trace/blktrace.c
+++ b/kernel/kernel/trace/blktrace.c
@@ -1602,7 +1602,8 @@
 
 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);
diff --git a/kernel/kernel/trace/bpf_trace.c b/kernel/kernel/trace/bpf_trace.c
index a9e0747..71e0c1b 100644
--- a/kernel/kernel/trace/bpf_trace.c
+++ b/kernel/kernel/trace/bpf_trace.c
@@ -970,7 +970,6 @@
 u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,
 		     void *ctx, u64 ctx_size, bpf_ctx_copy_t ctx_copy)
 {
-	int nest_level = this_cpu_inc_return(bpf_event_output_nest_level);
 	struct perf_raw_frag frag = {
 		.copy		= ctx_copy,
 		.size		= ctx_size,
@@ -987,7 +986,11 @@
 	};
 	struct perf_sample_data *sd;
 	struct pt_regs *regs;
+	int nest_level;
 	u64 ret;
+
+	preempt_disable();
+	nest_level = this_cpu_inc_return(bpf_event_output_nest_level);
 
 	if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(bpf_misc_sds.sds))) {
 		ret = -EBUSY;
@@ -1003,6 +1006,7 @@
 	ret = __bpf_perf_event_output(regs, map, flags, sd);
 out:
 	this_cpu_dec(bpf_event_output_nest_level);
+	preempt_enable();
 	return ret;
 }
 
@@ -1055,6 +1059,7 @@
 
 	work = container_of(entry, struct send_signal_irq_work, irq_work);
 	group_send_sig_info(work->sig, SEND_SIG_PRIV, work->task, work->type);
+	put_task_struct(work->task);
 }
 
 static int bpf_send_signal_common(u32 sig, enum pid_type type)
@@ -1072,6 +1077,9 @@
 		return -EPERM;
 	if (unlikely(!nmi_uaccess_okay()))
 		return -EPERM;
+	/* Task should not be pid=1 to avoid kernel panic. */
+	if (unlikely(is_global_init(current)))
+		return -EPERM;
 
 	if (irqs_disabled()) {
 		/* Do an early check on signal validity. Otherwise,
@@ -1088,7 +1096,7 @@
 		 * to the irq_work. The current task may change when queued
 		 * irq works get executed.
 		 */
-		work->task = current;
+		work->task = get_task_struct(current);
 		work->sig = sig;
 		work->type = type;
 		irq_work_queue(&work->irq_work);
@@ -1124,13 +1132,23 @@
 
 BPF_CALL_3(bpf_d_path, struct path *, path, char *, buf, u32, sz)
 {
+	struct path copy;
 	long len;
 	char *p;
 
 	if (!sz)
 		return 0;
 
-	p = d_path(path, buf, sz);
+	/*
+	 * The path pointer is verified as trusted and safe to use,
+	 * but let's double check it's valid anyway to workaround
+	 * potentially broken verifier.
+	 */
+	len = copy_from_kernel_nofault(&copy, path, sizeof(*path));
+	if (len < 0)
+		return len;
+
+	p = d_path(&copy, buf, sz);
 	if (IS_ERR(p)) {
 		len = PTR_ERR(p);
 	} else {
@@ -2156,7 +2174,7 @@
 #ifdef CONFIG_UPROBE_EVENTS
 		if (flags & TRACE_EVENT_FL_UPROBE)
 			err = bpf_get_uprobe_info(event, fd_type, buf,
-						  probe_offset,
+						  probe_offset, probe_addr,
 						  event->attr.type == PERF_TYPE_TRACEPOINT);
 #endif
 	}
diff --git a/kernel/kernel/trace/ftrace.c b/kernel/kernel/trace/ftrace.c
index d97c189..31fec92 100644
--- a/kernel/kernel/trace/ftrace.c
+++ b/kernel/kernel/trace/ftrace.c
@@ -1091,7 +1091,7 @@
 	struct ftrace_page	*next;
 	struct dyn_ftrace	*records;
 	int			index;
-	int			size;
+	int			order;
 };
 
 #define ENTRY_SIZE sizeof(struct dyn_ftrace)
@@ -1538,7 +1538,8 @@
 	key.flags = end;	/* overload flags, as it is unsigned long */
 
 	for (pg = ftrace_pages_start; pg; pg = pg->next) {
-		if (end < pg->records[0].ip ||
+		if (pg->index == 0 ||
+		    end < pg->records[0].ip ||
 		    start >= (pg->records[pg->index - 1].ip + MCOUNT_INSN_SIZE))
 			continue;
 		rec = bsearch(&key, pg->records, pg->index,
@@ -3187,7 +3188,7 @@
 	ftrace_number_of_groups++;
 
 	cnt = (PAGE_SIZE << order) / ENTRY_SIZE;
-	pg->size = cnt;
+	pg->order = order;
 
 	if (cnt > count)
 		cnt = count;
@@ -3195,12 +3196,27 @@
 	return cnt;
 }
 
+static void ftrace_free_pages(struct ftrace_page *pages)
+{
+	struct ftrace_page *pg = pages;
+
+	while (pg) {
+		if (pg->records) {
+			free_pages((unsigned long)pg->records, pg->order);
+			ftrace_number_of_pages -= 1 << pg->order;
+		}
+		pages = pg->next;
+		kfree(pg);
+		pg = pages;
+		ftrace_number_of_groups--;
+	}
+}
+
 static struct ftrace_page *
 ftrace_allocate_pages(unsigned long num_to_init)
 {
 	struct ftrace_page *start_pg;
 	struct ftrace_page *pg;
-	int order;
 	int cnt;
 
 	if (!num_to_init)
@@ -3234,17 +3250,7 @@
 	return start_pg;
 
  free_pages:
-	pg = start_pg;
-	while (pg) {
-		order = get_count_order(pg->size / ENTRIES_PER_PAGE);
-		if (order >= 0)
-			free_pages((unsigned long)pg->records, order);
-		start_pg = pg->next;
-		kfree(pg);
-		pg = start_pg;
-		ftrace_number_of_pages -= 1 << order;
-		ftrace_number_of_groups--;
-	}
+	ftrace_free_pages(start_pg);
 	pr_info("ftrace: FAILED to allocate memory for functions\n");
 	return NULL;
 }
@@ -5389,12 +5395,15 @@
 		ret = 0;
 	}
 
-	if (unlikely(ret && new_direct)) {
-		direct->count++;
-		list_del_rcu(&new_direct->next);
-		synchronize_rcu_tasks();
-		kfree(new_direct);
-		ftrace_direct_func_count--;
+	if (ret) {
+		direct->addr = old_addr;
+		if (unlikely(new_direct)) {
+			direct->count++;
+			list_del_rcu(&new_direct->next);
+			synchronize_rcu_tasks();
+			kfree(new_direct);
+			ftrace_direct_func_count--;
+		}
 	}
 
  out_unlock:
@@ -6187,9 +6196,11 @@
 			       unsigned long *start,
 			       unsigned long *end)
 {
+	struct ftrace_page *pg_unuse = NULL;
 	struct ftrace_page *start_pg;
 	struct ftrace_page *pg;
 	struct dyn_ftrace *rec;
+	unsigned long skipped = 0;
 	unsigned long count;
 	unsigned long *p;
 	unsigned long addr;
@@ -6235,6 +6246,7 @@
 	p = start;
 	pg = start_pg;
 	while (p < end) {
+		unsigned long end_offset;
 		addr = ftrace_call_adjust(*p++);
 		/*
 		 * Some architecture linkers will pad between
@@ -6242,10 +6254,13 @@
 		 * object files to satisfy alignments.
 		 * Skip any NULL pointers.
 		 */
-		if (!addr)
+		if (!addr) {
+			skipped++;
 			continue;
+		}
 
-		if (pg->index == pg->size) {
+		end_offset = (pg->index+1) * sizeof(pg->records[0]);
+		if (end_offset > PAGE_SIZE << pg->order) {
 			/* We should have allocated enough */
 			if (WARN_ON(!pg->next))
 				break;
@@ -6256,8 +6271,10 @@
 		rec->ip = addr;
 	}
 
-	/* We should have used all pages */
-	WARN_ON(pg->next);
+	if (pg->next) {
+		pg_unuse = pg->next;
+		pg->next = NULL;
+	}
 
 	/* Assign the last page to ftrace_pages */
 	ftrace_pages = pg;
@@ -6279,6 +6296,11 @@
  out:
 	mutex_unlock(&ftrace_lock);
 
+	/* We should have used all pages unless we skipped some */
+	if (pg_unuse) {
+		WARN_ON(!skipped);
+		ftrace_free_pages(pg_unuse);
+	}
 	return ret;
 }
 
@@ -6414,7 +6436,6 @@
 	struct ftrace_page **last_pg;
 	struct ftrace_page *tmp_page = NULL;
 	struct ftrace_page *pg;
-	int order;
 
 	mutex_lock(&ftrace_lock);
 
@@ -6465,12 +6486,12 @@
 		/* Needs to be called outside of ftrace_lock */
 		clear_mod_from_hashes(pg);
 
-		order = get_count_order(pg->size / ENTRIES_PER_PAGE);
-		if (order >= 0)
-			free_pages((unsigned long)pg->records, order);
+		if (pg->records) {
+			free_pages((unsigned long)pg->records, pg->order);
+			ftrace_number_of_pages -= 1 << pg->order;
+		}
 		tmp_page = pg->next;
 		kfree(pg);
-		ftrace_number_of_pages -= 1 << order;
 		ftrace_number_of_groups--;
 	}
 }
@@ -6788,7 +6809,6 @@
 	struct ftrace_mod_map *mod_map = NULL;
 	struct ftrace_init_func *func, *func_next;
 	struct list_head clear_hash;
-	int order;
 
 	INIT_LIST_HEAD(&clear_hash);
 
@@ -6826,10 +6846,10 @@
 		ftrace_update_tot_cnt--;
 		if (!pg->index) {
 			*last_pg = pg->next;
-			order = get_count_order(pg->size / ENTRIES_PER_PAGE);
-			if (order >= 0)
-				free_pages((unsigned long)pg->records, order);
-			ftrace_number_of_pages -= 1 << order;
+			if (pg->records) {
+				free_pages((unsigned long)pg->records, pg->order);
+				ftrace_number_of_pages -= 1 << pg->order;
+			}
 			ftrace_number_of_groups--;
 			kfree(pg);
 			pg = container_of(last_pg, struct ftrace_page, next);
diff --git a/kernel/kernel/trace/kprobe_event_gen_test.c b/kernel/kernel/trace/kprobe_event_gen_test.c
index c736487..e0c420e 100644
--- a/kernel/kernel/trace/kprobe_event_gen_test.c
+++ b/kernel/kernel/trace/kprobe_event_gen_test.c
@@ -146,7 +146,7 @@
 	if (trace_event_file_is_valid(gen_kprobe_test))
 		gen_kprobe_test = NULL;
 	/* We got an error after creating the event, delete it */
-	ret = kprobe_event_delete("gen_kprobe_test");
+	kprobe_event_delete("gen_kprobe_test");
 	goto out;
 }
 
@@ -211,7 +211,7 @@
 	if (trace_event_file_is_valid(gen_kretprobe_test))
 		gen_kretprobe_test = NULL;
 	/* We got an error after creating the event, delete it */
-	ret = kprobe_event_delete("gen_kretprobe_test");
+	kprobe_event_delete("gen_kretprobe_test");
 	goto out;
 }
 
diff --git a/kernel/kernel/trace/ring_buffer.c b/kernel/kernel/trace/ring_buffer.c
index 49ebb8c..0938222 100644
--- a/kernel/kernel/trace/ring_buffer.c
+++ b/kernel/kernel/trace/ring_buffer.c
@@ -355,10 +355,11 @@
 	local_set(&bpage->commit, 0);
 }
 
-/*
- * Also stolen from mm/slob.c. Thanks to Mathieu Desnoyers for pointing
- * this issue out.
- */
+static __always_inline unsigned int rb_page_commit(struct buffer_page *bpage)
+{
+	return local_read(&bpage->page->commit);
+}
+
 static void free_buffer_page(struct buffer_page *bpage)
 {
 	free_page((unsigned long)bpage->page);
@@ -526,6 +527,8 @@
 	rb_time_t			write_stamp;
 	rb_time_t			before_stamp;
 	u64				read_stamp;
+	/* pages removed since last reset */
+	unsigned long			pages_removed;
 	/* ring buffer pages to update, > 0 to add, < 0 to remove */
 	long				nr_pages_to_update;
 	struct list_head		new_pages; /* new pages to add */
@@ -539,6 +542,7 @@
 	unsigned			flags;
 	int				cpus;
 	atomic_t			record_disabled;
+	atomic_t			resizing;
 	cpumask_var_t			cpumask;
 
 	struct lock_class_key		*reader_lock_key;
@@ -561,6 +565,7 @@
 	struct buffer_page		*head_page;
 	struct buffer_page		*cache_reader_page;
 	unsigned long			cache_read;
+	unsigned long			cache_pages_removed;
 	u64				read_stamp;
 	u64				page_stamp;
 	struct ring_buffer_event	*event;
@@ -1004,6 +1009,9 @@
 	if (full) {
 		poll_wait(filp, &work->full_waiters, poll_table);
 		work->full_waiters_pending = true;
+		if (!cpu_buffer->shortest_full ||
+		    cpu_buffer->shortest_full > full)
+			cpu_buffer->shortest_full = full;
 	} else {
 		poll_wait(filp, &work->waiters, poll_table);
 		work->waiters_pending = true;
@@ -1450,19 +1458,6 @@
 }
 
 /**
- * rb_check_list - make sure a pointer to a list has the last bits zero
- */
-static int rb_check_list(struct ring_buffer_per_cpu *cpu_buffer,
-			 struct list_head *list)
-{
-	if (RB_WARN_ON(cpu_buffer, rb_list_head(list->prev) != list->prev))
-		return 1;
-	if (RB_WARN_ON(cpu_buffer, rb_list_head(list->next) != list->next))
-		return 1;
-	return 0;
-}
-
-/**
  * rb_check_pages - integrity check of buffer pages
  * @cpu_buffer: CPU buffer with pages to test
  *
@@ -1471,35 +1466,26 @@
  */
 static int rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer)
 {
-	struct list_head *head = cpu_buffer->pages;
-	struct buffer_page *bpage, *tmp;
+	struct list_head *head = rb_list_head(cpu_buffer->pages);
+	struct list_head *tmp;
 
-	/* Reset the head page if it exists */
-	if (cpu_buffer->head_page)
-		rb_set_head_page(cpu_buffer);
-
-	rb_head_page_deactivate(cpu_buffer);
-
-	if (RB_WARN_ON(cpu_buffer, head->next->prev != head))
-		return -1;
-	if (RB_WARN_ON(cpu_buffer, head->prev->next != head))
+	if (RB_WARN_ON(cpu_buffer,
+			rb_list_head(rb_list_head(head->next)->prev) != head))
 		return -1;
 
-	if (rb_check_list(cpu_buffer, head))
+	if (RB_WARN_ON(cpu_buffer,
+			rb_list_head(rb_list_head(head->prev)->next) != head))
 		return -1;
 
-	list_for_each_entry_safe(bpage, tmp, head, list) {
+	for (tmp = rb_list_head(head->next); tmp != head; tmp = rb_list_head(tmp->next)) {
 		if (RB_WARN_ON(cpu_buffer,
-			       bpage->list.next->prev != &bpage->list))
+				rb_list_head(rb_list_head(tmp->next)->prev) != tmp))
 			return -1;
+
 		if (RB_WARN_ON(cpu_buffer,
-			       bpage->list.prev->next != &bpage->list))
-			return -1;
-		if (rb_check_list(cpu_buffer, &bpage->list))
+				rb_list_head(rb_list_head(tmp->prev)->next) != tmp))
 			return -1;
 	}
-
-	rb_head_page_activate(cpu_buffer);
 
 	return 0;
 }
@@ -1666,6 +1652,8 @@
 	struct list_head *head = cpu_buffer->pages;
 	struct buffer_page *bpage, *tmp;
 
+	irq_work_sync(&cpu_buffer->irq_work.work);
+
 	free_buffer_page(cpu_buffer->reader_page);
 
 	if (head) {
@@ -1772,6 +1760,8 @@
 
 	cpuhp_state_remove_instance(CPUHP_TRACE_RB_PREPARE, &buffer->node);
 
+	irq_work_sync(&buffer->irq_work.work);
+
 	for_each_buffer_cpu(buffer, cpu)
 		rb_free_cpu_buffer(buffer->buffers[cpu]);
 
@@ -1851,6 +1841,8 @@
 		to_remove = rb_list_head(to_remove)->next;
 		head_bit |= (unsigned long)to_remove & RB_PAGE_HEAD;
 	}
+	/* Read iterators need to reset themselves when some pages removed */
+	cpu_buffer->pages_removed += nr_removed;
 
 	next_page = rb_list_head(to_remove)->next;
 
@@ -1871,12 +1863,6 @@
 	if (head_bit)
 		cpu_buffer->head_page = list_entry(next_page,
 						struct buffer_page, list);
-
-	/*
-	 * change read pointer to make sure any read iterators reset
-	 * themselves
-	 */
-	cpu_buffer->read = 0;
 
 	/* pages are removed, resume tracing and then free the pages */
 	atomic_dec(&cpu_buffer->record_disabled);
@@ -1905,7 +1891,7 @@
 			 * Increment overrun to account for the lost events.
 			 */
 			local_add(page_entries, &cpu_buffer->overrun);
-			local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
+			local_sub(rb_page_commit(to_remove_page), &cpu_buffer->entries_bytes);
 			local_inc(&cpu_buffer->pages_lost);
 		}
 
@@ -2060,7 +2046,7 @@
 
 	/* prevent another thread from changing buffer sizes */
 	mutex_lock(&buffer->mutex);
-
+	atomic_inc(&buffer->resizing);
 
 	if (cpu_id == RING_BUFFER_ALL_CPUS) {
 		/*
@@ -2098,6 +2084,8 @@
 				err = -ENOMEM;
 				goto out_err;
 			}
+
+			cond_resched();
 		}
 
 		get_online_cpus();
@@ -2203,6 +2191,7 @@
 		atomic_dec(&buffer->record_disabled);
 	}
 
+	atomic_dec(&buffer->resizing);
 	mutex_unlock(&buffer->mutex);
 	return 0;
 
@@ -2223,6 +2212,7 @@
 		}
 	}
  out_err_unlock:
+	atomic_dec(&buffer->resizing);
 	mutex_unlock(&buffer->mutex);
 	return err;
 }
@@ -2251,11 +2241,6 @@
 			       cpu_buffer->reader_page->read);
 }
 
-static __always_inline unsigned rb_page_commit(struct buffer_page *bpage)
-{
-	return local_read(&bpage->page->commit);
-}
-
 static struct ring_buffer_event *
 rb_iter_head_event(struct ring_buffer_iter *iter)
 {
@@ -2274,6 +2259,11 @@
 	 */
 	commit = rb_page_commit(iter_head_page);
 	smp_rmb();
+
+	/* An event needs to be at least 8 bytes in size */
+	if (iter->head > commit - 8)
+		goto reset;
+
 	event = __rb_page_index(iter_head_page, iter->head);
 	length = rb_event_length(event);
 
@@ -2396,7 +2386,7 @@
 		 * the counters.
 		 */
 		local_add(entries, &cpu_buffer->overrun);
-		local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
+		local_sub(rb_page_commit(next_page), &cpu_buffer->entries_bytes);
 		local_inc(&cpu_buffer->pages_lost);
 
 		/*
@@ -2539,9 +2529,6 @@
 
 	event = __rb_page_index(tail_page, tail);
 
-	/* account for padding bytes */
-	local_add(BUF_PAGE_SIZE - tail, &cpu_buffer->entries_bytes);
-
 	/*
 	 * Save the original length to the meta data.
 	 * This will be used by the reader to add lost event
@@ -2555,7 +2542,8 @@
 	 * write counter enough to allow another writer to slip
 	 * in on this page.
 	 * We put in a discarded commit instead, to make sure
-	 * that this space is not used again.
+	 * that this space is not used again, and this space will
+	 * not be accounted into 'entries_bytes'.
 	 *
 	 * If we are less than the minimum size, we don't need to
 	 * worry about it.
@@ -2579,6 +2567,9 @@
 	event->type_len = RINGBUF_TYPE_PADDING;
 	/* time delta must be non zero */
 	event->time_delta = 1;
+
+	/* account for padding bytes */
+	local_add(BUF_PAGE_SIZE - tail, &cpu_buffer->entries_bytes);
 
 	/* Make sure the padding is visible before the tail_page->write update */
 	smp_wmb();
@@ -2984,6 +2975,10 @@
 		if (RB_WARN_ON(cpu_buffer,
 			       rb_is_reader_page(cpu_buffer->tail_page)))
 			return;
+		/*
+		 * No need for a memory barrier here, as the update
+		 * of the tail_page did it for this page.
+		 */
 		local_set(&cpu_buffer->commit_page->page->commit,
 			  rb_page_write(cpu_buffer->commit_page));
 		rb_inc_page(cpu_buffer, &cpu_buffer->commit_page);
@@ -2993,6 +2988,8 @@
 	while (rb_commit_index(cpu_buffer) !=
 	       rb_page_write(cpu_buffer->commit_page)) {
 
+		/* Make sure the readers see the content of what is committed. */
+		smp_wmb();
 		local_set(&cpu_buffer->commit_page->page->commit,
 			  rb_page_write(cpu_buffer->commit_page));
 		RB_WARN_ON(cpu_buffer,
@@ -3939,7 +3936,7 @@
 EXPORT_SYMBOL_GPL(ring_buffer_oldest_event_ts);
 
 /**
- * ring_buffer_bytes_cpu - get the number of bytes consumed in a cpu buffer
+ * ring_buffer_bytes_cpu - get the number of bytes unconsumed in a cpu buffer
  * @buffer: The ring buffer
  * @cpu: The per CPU buffer to read from.
  */
@@ -4117,6 +4114,7 @@
 
 	iter->cache_reader_page = iter->head_page;
 	iter->cache_read = cpu_buffer->read;
+	iter->cache_pages_removed = cpu_buffer->pages_removed;
 
 	if (iter->head) {
 		iter->read_stamp = cpu_buffer->read_stamp;
@@ -4412,7 +4410,12 @@
 
 	/*
 	 * Make sure we see any padding after the write update
-	 * (see rb_reset_tail())
+	 * (see rb_reset_tail()).
+	 *
+	 * In addition, a writer may be writing on the reader page
+	 * if the page has not been fully filled, so the read barrier
+	 * is also needed to make sure we see the content of what is
+	 * committed by the writer (see rb_set_commit_to_write()).
 	 */
 	smp_rmb();
 
@@ -4441,6 +4444,7 @@
 
 	length = rb_event_length(event);
 	cpu_buffer->reader_page->read += length;
+	cpu_buffer->read_bytes += length;
 }
 
 static void rb_advance_iter(struct ring_buffer_iter *iter)
@@ -4565,12 +4569,13 @@
 	buffer = cpu_buffer->buffer;
 
 	/*
-	 * Check if someone performed a consuming read to
-	 * the buffer. A consuming read invalidates the iterator
-	 * and we need to reset the iterator in this case.
+	 * Check if someone performed a consuming read to the buffer
+	 * or removed some pages from the buffer. In these cases,
+	 * iterator was invalidated and we need to reset it.
 	 */
 	if (unlikely(iter->cache_read != cpu_buffer->read ||
-		     iter->cache_reader_page != cpu_buffer->reader_page))
+		     iter->cache_reader_page != cpu_buffer->reader_page ||
+		     iter->cache_pages_removed != cpu_buffer->pages_removed))
 		rb_iter_reset(iter);
 
  again:
@@ -4961,28 +4966,34 @@
 }
 EXPORT_SYMBOL_GPL(ring_buffer_size);
 
+static void rb_clear_buffer_page(struct buffer_page *page)
+{
+	local_set(&page->write, 0);
+	local_set(&page->entries, 0);
+	rb_init_page(page->page);
+	page->read = 0;
+}
+
 static void
 rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
 {
+	struct buffer_page *page;
+
 	rb_head_page_deactivate(cpu_buffer);
 
 	cpu_buffer->head_page
 		= list_entry(cpu_buffer->pages, struct buffer_page, list);
-	local_set(&cpu_buffer->head_page->write, 0);
-	local_set(&cpu_buffer->head_page->entries, 0);
-	local_set(&cpu_buffer->head_page->page->commit, 0);
-
-	cpu_buffer->head_page->read = 0;
+	rb_clear_buffer_page(cpu_buffer->head_page);
+	list_for_each_entry(page, cpu_buffer->pages, list) {
+		rb_clear_buffer_page(page);
+	}
 
 	cpu_buffer->tail_page = cpu_buffer->head_page;
 	cpu_buffer->commit_page = cpu_buffer->head_page;
 
 	INIT_LIST_HEAD(&cpu_buffer->reader_page->list);
 	INIT_LIST_HEAD(&cpu_buffer->new_pages);
-	local_set(&cpu_buffer->reader_page->write, 0);
-	local_set(&cpu_buffer->reader_page->entries, 0);
-	local_set(&cpu_buffer->reader_page->page->commit, 0);
-	cpu_buffer->reader_page->read = 0;
+	rb_clear_buffer_page(cpu_buffer->reader_page);
 
 	local_set(&cpu_buffer->entries_bytes, 0);
 	local_set(&cpu_buffer->overrun, 0);
@@ -5006,6 +5017,7 @@
 	cpu_buffer->last_overrun = 0;
 
 	rb_head_page_activate(cpu_buffer);
+	cpu_buffer->pages_removed = 0;
 }
 
 /* Must have disabled the cpu buffer then done a synchronize_rcu */
@@ -5058,6 +5070,9 @@
 }
 EXPORT_SYMBOL_GPL(ring_buffer_reset_cpu);
 
+/* Flag to ensure proper resetting of atomic variables */
+#define RESET_BIT	(1 << 30)
+
 /**
  * ring_buffer_reset_cpu - reset a ring buffer per CPU buffer
  * @buffer: The ring buffer to reset a per cpu buffer of
@@ -5074,20 +5089,27 @@
 	for_each_online_buffer_cpu(buffer, cpu) {
 		cpu_buffer = buffer->buffers[cpu];
 
-		atomic_inc(&cpu_buffer->resize_disabled);
+		atomic_add(RESET_BIT, &cpu_buffer->resize_disabled);
 		atomic_inc(&cpu_buffer->record_disabled);
 	}
 
 	/* Make sure all commits have finished */
 	synchronize_rcu();
 
-	for_each_online_buffer_cpu(buffer, cpu) {
+	for_each_buffer_cpu(buffer, cpu) {
 		cpu_buffer = buffer->buffers[cpu];
+
+		/*
+		 * If a CPU came online during the synchronize_rcu(), then
+		 * ignore it.
+		 */
+		if (!(atomic_read(&cpu_buffer->resize_disabled) & RESET_BIT))
+			continue;
 
 		reset_disabled_cpu_buffer(cpu_buffer);
 
 		atomic_dec(&cpu_buffer->record_disabled);
-		atomic_dec(&cpu_buffer->resize_disabled);
+		atomic_sub(RESET_BIT, &cpu_buffer->resize_disabled);
 	}
 
 	mutex_unlock(&buffer->mutex);
@@ -5242,6 +5264,15 @@
 	if (local_read(&cpu_buffer_b->committing))
 		goto out_dec;
 
+	/*
+	 * When resize is in progress, we cannot swap it because
+	 * it will mess the state of the cpu buffer.
+	 */
+	if (atomic_read(&buffer_a->resizing))
+		goto out_dec;
+	if (atomic_read(&buffer_b->resizing))
+		goto out_dec;
+
 	buffer_a->buffers[cpu] = cpu_buffer_b;
 	buffer_b->buffers[cpu] = cpu_buffer_a;
 
@@ -5324,10 +5355,15 @@
  */
 void ring_buffer_free_read_page(struct trace_buffer *buffer, int cpu, void *data)
 {
-	struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
+	struct ring_buffer_per_cpu *cpu_buffer;
 	struct buffer_data_page *bpage = data;
 	struct page *page = virt_to_page(bpage);
 	unsigned long flags;
+
+	if (!buffer || !buffer->buffers || !buffer->buffers[cpu])
+		return;
+
+	cpu_buffer = buffer->buffers[cpu];
 
 	/* If the page is still in use someplace else, we can't reuse it */
 	if (page_ref_count(page) > 1)
@@ -5500,7 +5536,7 @@
 	} else {
 		/* update the entry counter */
 		cpu_buffer->read += rb_page_entries(reader);
-		cpu_buffer->read_bytes += BUF_PAGE_SIZE;
+		cpu_buffer->read_bytes += rb_page_commit(reader);
 
 		/* swap the pages */
 		rb_init_page(bpage);
diff --git a/kernel/kernel/trace/trace.c b/kernel/kernel/trace/trace.c
index 8b1f74e..3992a50 100644
--- a/kernel/kernel/trace/trace.c
+++ b/kernel/kernel/trace/trace.c
@@ -1883,9 +1883,10 @@
 		 * place on this CPU. We fail to record, but we reset
 		 * the max trace buffer (no one writes directly to it)
 		 * and flag that it failed.
+		 * Another reason is resize is in progress.
 		 */
 		trace_array_printk_buf(tr->max_buffer.buffer, _THIS_IP_,
-			"Failed to swap buffers due to commit in progress\n");
+			"Failed to swap buffers due to commit or resize in progress\n");
 	}
 
 	WARN_ON_ONCE(ret && ret != -EAGAIN && ret != -EBUSY);
@@ -2179,9 +2180,11 @@
 }
 
 /* Must have trace_types_lock held */
-void tracing_reset_all_online_cpus(void)
+void tracing_reset_all_online_cpus_unlocked(void)
 {
 	struct trace_array *tr;
+
+	lockdep_assert_held(&trace_types_lock);
 
 	list_for_each_entry(tr, &ftrace_trace_arrays, list) {
 		if (!tr->clear_trace)
@@ -2192,6 +2195,13 @@
 		tracing_reset_online_cpus(&tr->max_buffer);
 #endif
 	}
+}
+
+void tracing_reset_all_online_cpus(void)
+{
+	mutex_lock(&trace_types_lock);
+	tracing_reset_all_online_cpus_unlocked();
+	mutex_unlock(&trace_types_lock);
 }
 
 /*
@@ -3717,8 +3727,15 @@
 	 * will point to the same string as current_trace->name.
 	 */
 	mutex_lock(&trace_types_lock);
-	if (unlikely(tr->current_trace && iter->trace->name != tr->current_trace->name))
+	if (unlikely(tr->current_trace && iter->trace->name != tr->current_trace->name)) {
+		/* Close iter->trace before switching to the new current tracer */
+		if (iter->trace->close)
+			iter->trace->close(iter);
 		*iter->trace = *tr->current_trace;
+		/* Reopen the new current tracer */
+		if (iter->trace->open)
+			iter->trace->open(iter);
+	}
 	mutex_unlock(&trace_types_lock);
 
 #ifdef CONFIG_TRACER_MAX_TRACE
@@ -4477,6 +4494,33 @@
 	return 0;
 }
 
+/*
+ * The private pointer of the inode is the trace_event_file.
+ * Update the tr ref count associated to it.
+ */
+int tracing_open_file_tr(struct inode *inode, struct file *filp)
+{
+	struct trace_event_file *file = inode->i_private;
+	int ret;
+
+	ret = tracing_check_open_get_tr(file->tr);
+	if (ret)
+		return ret;
+
+	filp->private_data = inode->i_private;
+
+	return 0;
+}
+
+int tracing_release_file_tr(struct inode *inode, struct file *filp)
+{
+	struct trace_event_file *file = inode->i_private;
+
+	trace_array_put(file->tr);
+
+	return 0;
+}
+
 static int tracing_release(struct inode *inode, struct file *file)
 {
 	struct trace_array *tr = inode->i_private;
@@ -4706,6 +4750,8 @@
 static const struct file_operations tracing_fops = {
 	.open		= tracing_open,
 	.read		= seq_read,
+	.read_iter	= seq_read_iter,
+	.splice_read	= generic_file_splice_read,
 	.write		= tracing_write_stub,
 	.llseek		= tracing_lseek,
 	.release	= tracing_release,
@@ -4765,11 +4811,17 @@
 				!cpumask_test_cpu(cpu, tracing_cpumask_new)) {
 			atomic_inc(&per_cpu_ptr(tr->array_buffer.data, cpu)->disabled);
 			ring_buffer_record_disable_cpu(tr->array_buffer.buffer, cpu);
+#ifdef CONFIG_TRACER_MAX_TRACE
+			ring_buffer_record_disable_cpu(tr->max_buffer.buffer, cpu);
+#endif
 		}
 		if (!cpumask_test_cpu(cpu, tr->tracing_cpumask) &&
 				cpumask_test_cpu(cpu, tracing_cpumask_new)) {
 			atomic_dec(&per_cpu_ptr(tr->array_buffer.data, cpu)->disabled);
 			ring_buffer_record_enable_cpu(tr->array_buffer.buffer, cpu);
+#ifdef CONFIG_TRACER_MAX_TRACE
+			ring_buffer_record_enable_cpu(tr->max_buffer.buffer, cpu);
+#endif
 		}
 	}
 	arch_spin_unlock(&tr->max_lock);
@@ -6240,6 +6292,7 @@
 	mutex_unlock(&trace_types_lock);
 
 	free_cpumask_var(iter->started);
+	kfree(iter->temp);
 	mutex_destroy(&iter->mutex);
 	kfree(iter);
 
@@ -6372,7 +6425,20 @@
 
 		ret = print_trace_line(iter);
 		if (ret == TRACE_TYPE_PARTIAL_LINE) {
-			/* don't print partial lines */
+			/*
+			 * If one print_trace_line() fills entire trace_seq in one shot,
+			 * trace_seq_to_user() will returns -EBUSY because save_len == 0,
+			 * In this case, we need to consume it, otherwise, loop will peek
+			 * this event next time, resulting in an infinite loop.
+			 */
+			if (save_len == 0) {
+				iter->seq.full = 0;
+				trace_seq_puts(&iter->seq, "[LINE TOO BIG]\n");
+				trace_consume(iter);
+				break;
+			}
+
+			/* In other cases, don't print partial lines */
 			iter->seq.seq.len = save_len;
 			break;
 		}
@@ -7027,6 +7093,11 @@
 	return ret;
 }
 
+static void tracing_swap_cpu_buffer(void *tr)
+{
+	update_max_tr_single((struct trace_array *)tr, current, smp_processor_id());
+}
+
 static ssize_t
 tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
 		       loff_t *ppos)
@@ -7085,13 +7156,15 @@
 			ret = tracing_alloc_snapshot_instance(tr);
 		if (ret < 0)
 			break;
-		local_irq_disable();
 		/* Now, we're going to swap */
-		if (iter->cpu_file == RING_BUFFER_ALL_CPUS)
+		if (iter->cpu_file == RING_BUFFER_ALL_CPUS) {
+			local_irq_disable();
 			update_max_tr(tr, current, smp_processor_id(), NULL);
-		else
-			update_max_tr_single(tr, current, iter->cpu_file);
-		local_irq_enable();
+			local_irq_enable();
+		} else {
+			smp_call_function_single(iter->cpu_file, tracing_swap_cpu_buffer,
+						 (void *)tr, 1);
+		}
 		break;
 	default:
 		if (tr->allocated_snapshot) {
@@ -7180,10 +7253,11 @@
 #endif
 
 static const struct file_operations set_tracer_fops = {
-	.open		= tracing_open_generic,
+	.open		= tracing_open_generic_tr,
 	.read		= tracing_set_trace_read,
 	.write		= tracing_set_trace_write,
 	.llseek		= generic_file_llseek,
+	.release	= tracing_release_generic_tr,
 };
 
 static const struct file_operations tracing_pipe_fops = {
@@ -7506,7 +7580,7 @@
 	.open           = tracing_err_log_open,
 	.write		= tracing_err_log_write,
 	.read           = seq_read,
-	.llseek         = seq_lseek,
+	.llseek         = tracing_lseek,
 	.release        = tracing_err_log_release,
 };
 
@@ -8222,12 +8296,33 @@
 	return cnt;
 }
 
+static int tracing_open_options(struct inode *inode, struct file *filp)
+{
+	struct trace_option_dentry *topt = inode->i_private;
+	int ret;
+
+	ret = tracing_check_open_get_tr(topt->tr);
+	if (ret)
+		return ret;
+
+	filp->private_data = inode->i_private;
+	return 0;
+}
+
+static int tracing_release_options(struct inode *inode, struct file *file)
+{
+	struct trace_option_dentry *topt = file->private_data;
+
+	trace_array_put(topt->tr);
+	return 0;
+}
 
 static const struct file_operations trace_options_fops = {
-	.open = tracing_open_generic,
+	.open = tracing_open_options,
 	.read = trace_options_read,
 	.write = trace_options_write,
 	.llseek	= generic_file_llseek,
+	.release = tracing_release_options,
 };
 
 /*
@@ -8557,9 +8652,6 @@
 	if (val > 100)
 		return -EINVAL;
 
-	if (!val)
-		val = 1;
-
 	tr->buffer_percent = val;
 
 	(*ppos)++;
@@ -8884,6 +8976,7 @@
 	ftrace_destroy_function_files(tr);
 	tracefs_remove(tr->dir);
 	free_trace_buffers(tr);
+	clear_tracing_err_log(tr);
 
 	for (i = 0; i < tr->nr_topts; i++) {
 		kfree(tr->topts[i].topts);
@@ -9706,6 +9799,8 @@
 			static_key_enable(&tracepoint_printk_key.key);
 	}
 	tracer_alloc_buffers();
+
+	init_events();
 }
 
 void __init trace_init(void)
diff --git a/kernel/kernel/trace/trace.h b/kernel/kernel/trace/trace.h
index 8d67f7f..7ac8b93 100644
--- a/kernel/kernel/trace/trace.h
+++ b/kernel/kernel/trace/trace.h
@@ -725,8 +725,11 @@
 void tracing_reset_online_cpus(struct array_buffer *buf);
 void tracing_reset_current(int cpu);
 void tracing_reset_all_online_cpus(void);
+void tracing_reset_all_online_cpus_unlocked(void);
 int tracing_open_generic(struct inode *inode, struct file *filp);
 int tracing_open_generic_tr(struct inode *inode, struct file *filp);
+int tracing_open_file_tr(struct inode *inode, struct file *filp);
+int tracing_release_file_tr(struct inode *inode, struct file *filp);
 bool tracing_is_disabled(void);
 bool tracer_tracing_is_on(struct trace_array *tr);
 void tracer_tracing_on(struct trace_array *tr);
@@ -1673,6 +1676,7 @@
 extern void trace_event_enable_tgid_record(bool enable);
 
 extern int event_trace_init(void);
+extern int init_events(void);
 extern int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr);
 extern int event_trace_del_tracer(struct trace_array *tr);
 extern void __trace_early_add_events(struct trace_array *tr);
diff --git a/kernel/kernel/trace/trace_events.c b/kernel/kernel/trace/trace_events.c
index bac13f2..321cfda 100644
--- a/kernel/kernel/trace/trace_events.c
+++ b/kernel/kernel/trace/trace_events.c
@@ -371,7 +371,6 @@
 {
 	struct trace_event_call *call = file->event_call;
 	struct trace_array *tr = file->tr;
-	unsigned long file_flags = file->flags;
 	int ret = 0;
 	int disable;
 
@@ -395,6 +394,8 @@
 				break;
 			disable = file->flags & EVENT_FILE_FL_SOFT_DISABLED;
 			clear_bit(EVENT_FILE_FL_SOFT_MODE_BIT, &file->flags);
+			/* Disable use of trace_buffered_event */
+			trace_buffered_event_disable();
 		} else
 			disable = !(file->flags & EVENT_FILE_FL_SOFT_MODE);
 
@@ -433,6 +434,8 @@
 			if (atomic_inc_return(&file->sm_ref) > 1)
 				break;
 			set_bit(EVENT_FILE_FL_SOFT_MODE_BIT, &file->flags);
+			/* Enable use of trace_buffered_event */
+			trace_buffered_event_enable();
 		}
 
 		if (!(file->flags & EVENT_FILE_FL_ENABLED)) {
@@ -470,15 +473,6 @@
 			set_bit(EVENT_FILE_FL_WAS_ENABLED_BIT, &file->flags);
 		}
 		break;
-	}
-
-	/* Enable or disable use of trace_buffered_event */
-	if ((file_flags & EVENT_FILE_FL_SOFT_DISABLED) !=
-	    (file->flags & EVENT_FILE_FL_SOFT_DISABLED)) {
-		if (file->flags & EVENT_FILE_FL_SOFT_DISABLED)
-			trace_buffered_event_enable();
-		else
-			trace_buffered_event_disable();
 	}
 
 	return ret;
@@ -1861,9 +1855,10 @@
 };
 
 static const struct file_operations ftrace_enable_fops = {
-	.open = tracing_open_generic,
+	.open = tracing_open_file_tr,
 	.read = event_enable_read,
 	.write = event_enable_write,
+	.release = tracing_release_file_tr,
 	.llseek = default_llseek,
 };
 
@@ -1880,9 +1875,10 @@
 };
 
 static const struct file_operations ftrace_event_filter_fops = {
-	.open = tracing_open_generic,
+	.open = tracing_open_file_tr,
 	.read = event_filter_read,
 	.write = event_filter_write,
+	.release = tracing_release_file_tr,
 	.llseek = default_llseek,
 };
 
@@ -2661,7 +2657,7 @@
 	 * over from this module may be passed to the new module events and
 	 * unexpected results may occur.
 	 */
-	tracing_reset_all_online_cpus();
+	tracing_reset_all_online_cpus_unlocked();
 }
 
 static int trace_module_notify(struct notifier_block *self,
diff --git a/kernel/kernel/trace/trace_events_hist.c b/kernel/kernel/trace/trace_events_hist.c
index fd54168..059a106 100644
--- a/kernel/kernel/trace/trace_events_hist.c
+++ b/kernel/kernel/trace/trace_events_hist.c
@@ -417,7 +417,7 @@
 	 * event param, and is passed to the synthetic event
 	 * invocation.
 	 */
-	unsigned int		var_ref_idx[TRACING_MAP_VARS_MAX];
+	unsigned int		var_ref_idx[SYNTH_FIELDS_MAX];
 	struct synth_event	*synth_event;
 	bool			use_trace_keyword;
 	char			*synth_event_name;
@@ -1087,6 +1087,9 @@
 {
 	const char *field_name = "";
 
+	if (WARN_ON_ONCE(!field))
+		return field_name;
+
 	if (level > 1)
 		return field_name;
 
@@ -1646,6 +1649,8 @@
 		unsigned long fl = flags & ~HIST_FIELD_FL_LOG2;
 		hist_field->fn = hist_field_log2;
 		hist_field->operands[0] = create_hist_field(hist_data, field, fl, NULL);
+		if (!hist_field->operands[0])
+			goto free;
 		hist_field->size = hist_field->operands[0]->size;
 		hist_field->type = kstrdup(hist_field->operands[0]->type, GFP_KERNEL);
 		if (!hist_field->type)
@@ -1846,7 +1851,9 @@
 			return ref_field;
 		}
 	}
-
+	/* Sanity check to avoid out-of-bound write on 'hist_data->var_refs' */
+	if (hist_data->n_var_refs >= TRACING_MAP_VARS_MAX)
+		return NULL;
 	ref_field = create_hist_field(var_field->hist_data, NULL, flags, NULL);
 	if (ref_field) {
 		if (init_var_ref(ref_field, var_field, system, event_name)) {
@@ -3113,6 +3120,7 @@
 	while (params) {
 		if (data->n_params >= SYNTH_FIELDS_MAX) {
 			hist_err(tr, HIST_ERR_TOO_MANY_PARAMS, 0);
+			ret = -EINVAL;
 			goto out;
 		}
 
@@ -3448,6 +3456,10 @@
 	int var_ref_idx, ret = 0;
 
 	lockdep_assert_held(&event_mutex);
+
+	/* Sanity check to avoid out-of-bound write on 'data->var_ref_idx' */
+	if (data->n_params > SYNTH_FIELDS_MAX)
+		return -EINVAL;
 
 	if (data->use_trace_keyword)
 		synth_event_name = data->synth_event_name;
@@ -5805,12 +5817,15 @@
 	if (get_named_trigger_data(trigger_data))
 		goto enable;
 
-	if (has_hist_vars(hist_data))
-		save_hist_vars(hist_data);
-
 	ret = create_actions(hist_data);
 	if (ret)
 		goto out_unreg;
+
+	if (has_hist_vars(hist_data) || hist_data->n_var_refs) {
+		ret = save_hist_vars(hist_data);
+		if (ret)
+			goto out_unreg;
+	}
 
 	ret = tracing_map_init(hist_data->map);
 	if (ret)
@@ -5827,7 +5842,7 @@
 	/* 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;
diff --git a/kernel/kernel/trace/trace_events_inject.c b/kernel/kernel/trace/trace_events_inject.c
index 22bcf7c..149c7dc 100644
--- a/kernel/kernel/trace/trace_events_inject.c
+++ b/kernel/kernel/trace/trace_events_inject.c
@@ -323,7 +323,8 @@
 }
 
 const struct file_operations event_inject_fops = {
-	.open = tracing_open_generic,
+	.open = tracing_open_file_tr,
 	.read = event_inject_read,
 	.write = event_inject_write,
+	.release = tracing_release_file_tr,
 };
diff --git a/kernel/kernel/trace/trace_events_synth.c b/kernel/kernel/trace/trace_events_synth.c
index 18291ab..ee174de 100644
--- a/kernel/kernel/trace/trace_events_synth.c
+++ b/kernel/kernel/trace/trace_events_synth.c
@@ -1363,7 +1363,6 @@
 	mutex_unlock(&event_mutex);
 
 	if (mod) {
-		mutex_lock(&trace_types_lock);
 		/*
 		 * It is safest to reset the ring buffer if the module
 		 * being unloaded registered any events that were
@@ -1375,7 +1374,6 @@
 		 * occur.
 		 */
 		tracing_reset_all_online_cpus();
-		mutex_unlock(&trace_types_lock);
 	}
 
 	return ret;
diff --git a/kernel/kernel/trace/trace_irqsoff.c b/kernel/kernel/trace/trace_irqsoff.c
index ee4571b..619a609 100644
--- a/kernel/kernel/trace/trace_irqsoff.c
+++ b/kernel/kernel/trace/trace_irqsoff.c
@@ -228,7 +228,8 @@
 {
 	if (is_graph(iter->tr))
 		graph_trace_open(iter);
-
+	else
+		iter->private = NULL;
 }
 
 static void irqsoff_trace_close(struct trace_iterator *iter)
diff --git a/kernel/kernel/trace/trace_kprobe.c b/kernel/kernel/trace/trace_kprobe.c
index 41dd173..b882c65 100644
--- a/kernel/kernel/trace/trace_kprobe.c
+++ b/kernel/kernel/trace/trace_kprobe.c
@@ -1332,9 +1332,10 @@
 
 /* Note that we don't verify it, since the code does not come from user space */
 static int
-process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest,
+process_fetch_insn(struct fetch_insn *code, void *rec, void *dest,
 		   void *base)
 {
+	struct pt_regs *regs = rec;
 	unsigned long val;
 
 retry:
diff --git a/kernel/kernel/trace/trace_output.c b/kernel/kernel/trace/trace_output.c
index 000e9dc..b3ee8d9 100644
--- a/kernel/kernel/trace/trace_output.c
+++ b/kernel/kernel/trace/trace_output.c
@@ -1378,7 +1378,7 @@
 	NULL
 };
 
-__init static int init_events(void)
+__init int init_events(void)
 {
 	struct trace_event *event;
 	int i, ret;
@@ -1396,4 +1396,3 @@
 
 	return 0;
 }
-early_initcall(init_events);
diff --git a/kernel/kernel/trace/trace_probe.h b/kernel/kernel/trace/trace_probe.h
index 6d41e20..d4a69b8 100644
--- a/kernel/kernel/trace/trace_probe.h
+++ b/kernel/kernel/trace/trace_probe.h
@@ -301,7 +301,7 @@
 {
 	struct trace_probe_event *tpe = trace_probe_event_from_call(call);
 
-	return list_first_entry(&tpe->probes, struct trace_probe, list);
+	return list_first_entry_or_null(&tpe->probes, struct trace_probe, list);
 }
 
 static inline struct list_head *trace_probe_probe_list(struct trace_probe *tp)
diff --git a/kernel/kernel/trace/trace_probe_tmpl.h b/kernel/kernel/trace/trace_probe_tmpl.h
index e528282..cf14a37 100644
--- a/kernel/kernel/trace/trace_probe_tmpl.h
+++ b/kernel/kernel/trace/trace_probe_tmpl.h
@@ -54,7 +54,7 @@
  * If dest is NULL, don't store result and return required dynamic data size.
  */
 static int
-process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs,
+process_fetch_insn(struct fetch_insn *code, void *rec,
 		   void *dest, void *base);
 static nokprobe_inline int fetch_store_strlen(unsigned long addr);
 static nokprobe_inline int
@@ -143,6 +143,8 @@
 array:
 	/* the last stage: Loop on array */
 	if (code->op == FETCH_OP_LP_ARRAY) {
+		if (ret < 0)
+			ret = 0;
 		total += ret;
 		if (++i < code->param) {
 			code = s3;
@@ -188,7 +190,7 @@
 
 /* Store the value of each argument */
 static nokprobe_inline void
-store_trace_args(void *data, struct trace_probe *tp, struct pt_regs *regs,
+store_trace_args(void *data, struct trace_probe *tp, void *rec,
 		 int header_size, int maxlen)
 {
 	struct probe_arg *arg;
@@ -203,12 +205,14 @@
 		/* Point the dynamic data area if needed */
 		if (unlikely(arg->dynamic))
 			*dl = make_data_loc(maxlen, dyndata - base);
-		ret = process_fetch_insn(arg->code, regs, dl, base);
-		if (unlikely(ret < 0 && arg->dynamic)) {
-			*dl = make_data_loc(0, dyndata - base);
-		} else {
-			dyndata += ret;
-			maxlen -= ret;
+		ret = process_fetch_insn(arg->code, rec, dl, base);
+		if (arg->dynamic) {
+			if (unlikely(ret < 0)) {
+				*dl = make_data_loc(0, dyndata - base);
+			} else {
+				dyndata += ret;
+				maxlen -= ret;
+			}
 		}
 	}
 }
diff --git a/kernel/kernel/trace/trace_sched_wakeup.c b/kernel/kernel/trace/trace_sched_wakeup.c
index 97b10bb..037e1e8 100644
--- a/kernel/kernel/trace/trace_sched_wakeup.c
+++ b/kernel/kernel/trace/trace_sched_wakeup.c
@@ -171,6 +171,8 @@
 {
 	if (is_graph(iter->tr))
 		graph_trace_open(iter);
+	else
+		iter->private = NULL;
 }
 
 static void wakeup_trace_close(struct trace_iterator *iter)
diff --git a/kernel/kernel/trace/trace_uprobe.c b/kernel/kernel/trace/trace_uprobe.c
index 9900d4e..60ff36f 100644
--- a/kernel/kernel/trace/trace_uprobe.c
+++ b/kernel/kernel/trace/trace_uprobe.c
@@ -217,9 +217,10 @@
 
 /* Note that we don't verify it, since the code does not come from user space */
 static int
-process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest,
+process_fetch_insn(struct fetch_insn *code, void *rec, void *dest,
 		   void *base)
 {
+	struct pt_regs *regs = rec;
 	unsigned long val;
 
 	/* 1st stage: get value from context */
@@ -1421,7 +1422,7 @@
 
 int bpf_get_uprobe_info(const struct perf_event *event, u32 *fd_type,
 			const char **filename, u64 *probe_offset,
-			bool perf_type_tracepoint)
+			u64 *probe_addr, bool perf_type_tracepoint)
 {
 	const char *pevent = trace_event_name(event->tp_event);
 	const char *group = event->tp_event->class->system;
@@ -1438,6 +1439,7 @@
 				    : BPF_FD_TYPE_UPROBE;
 	*filename = tu->filename;
 	*probe_offset = tu->offset;
+	*probe_addr = 0;
 	return 0;
 }
 #endif	/* CONFIG_PERF_EVENTS */
diff --git a/kernel/kernel/watch_queue.c b/kernel/kernel/watch_queue.c
index d29731a..7371791 100644
--- a/kernel/kernel/watch_queue.c
+++ b/kernel/kernel/watch_queue.c
@@ -274,6 +274,7 @@
 	if (ret < 0)
 		goto error;
 
+	ret = -ENOMEM;
 	pages = kcalloc(sizeof(struct page *), nr_pages, GFP_KERNEL);
 	if (!pages)
 		goto error;
diff --git a/kernel/kernel/watchdog_hld.c b/kernel/kernel/watchdog_hld.c
index 247bf0b..1e8a49d 100644
--- a/kernel/kernel/watchdog_hld.c
+++ b/kernel/kernel/watchdog_hld.c
@@ -114,13 +114,13 @@
 	/* Ensure the watchdog never gets throttled */
 	event->hw.interrupts = 0;
 
+	if (!watchdog_check_timestamp())
+		return;
+
 	if (__this_cpu_read(watchdog_nmi_touch) == true) {
 		__this_cpu_write(watchdog_nmi_touch, false);
 		return;
 	}
-
-	if (!watchdog_check_timestamp())
-		return;
 
 	/* check for a hardlockup
 	 * This is done by making sure our timer interrupt
diff --git a/kernel/kernel/workqueue.c b/kernel/kernel/workqueue.c
index cb057e3..0bcf043 100644
--- a/kernel/kernel/workqueue.c
+++ b/kernel/kernel/workqueue.c
@@ -687,12 +687,17 @@
 	set_work_data(work, WORK_STRUCT_NO_POOL, 0);
 }
 
+static inline struct pool_workqueue *work_struct_pwq(unsigned long data)
+{
+	return (struct pool_workqueue *)(data & WORK_STRUCT_WQ_DATA_MASK);
+}
+
 static struct pool_workqueue *get_work_pwq(struct work_struct *work)
 {
 	unsigned long data = atomic_long_read(&work->data);
 
 	if (data & WORK_STRUCT_PWQ)
-		return (void *)(data & WORK_STRUCT_WQ_DATA_MASK);
+		return work_struct_pwq(data);
 	else
 		return NULL;
 }
@@ -720,8 +725,7 @@
 	assert_rcu_or_pool_mutex();
 
 	if (data & WORK_STRUCT_PWQ)
-		return ((struct pool_workqueue *)
-			(data & WORK_STRUCT_WQ_DATA_MASK))->pool;
+		return work_struct_pwq(data)->pool;
 
 	pool_id = data >> WORK_OFFQ_POOL_SHIFT;
 	if (pool_id == WORK_OFFQ_POOL_NONE)
@@ -742,8 +746,7 @@
 	unsigned long data = atomic_long_read(&work->data);
 
 	if (data & WORK_STRUCT_PWQ)
-		return ((struct pool_workqueue *)
-			(data & WORK_STRUCT_WQ_DATA_MASK))->pool->id;
+		return work_struct_pwq(data)->pool->id;
 
 	return data >> WORK_OFFQ_POOL_SHIFT;
 }
diff --git a/kernel/lib/Kconfig.debug b/kernel/lib/Kconfig.debug
index 8608332..c0521f0 100644
--- a/kernel/lib/Kconfig.debug
+++ b/kernel/lib/Kconfig.debug
@@ -1931,7 +1931,6 @@
 	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/kernel/lib/clz_ctz.c b/kernel/lib/clz_ctz.c
index 0d3a686..fb8c0c5 100644
--- a/kernel/lib/clz_ctz.c
+++ b/kernel/lib/clz_ctz.c
@@ -28,36 +28,16 @@
 }
 EXPORT_SYMBOL(__clzsi2);
 
-int __weak __clzdi2(long val);
-int __weak __ctzdi2(long val);
-#if BITS_PER_LONG == 32
-
-int __weak __clzdi2(long val)
+int __weak __clzdi2(u64 val);
+int __weak __clzdi2(u64 val)
 {
-	return 32 - fls((int)val);
+	return 64 - fls64(val);
 }
 EXPORT_SYMBOL(__clzdi2);
 
-int __weak __ctzdi2(long val)
+int __weak __ctzdi2(u64 val);
+int __weak __ctzdi2(u64 val)
 {
-	return __ffs((u32)val);
+	return __ffs64(val);
 }
 EXPORT_SYMBOL(__ctzdi2);
-
-#elif BITS_PER_LONG == 64
-
-int __weak __clzdi2(long val)
-{
-	return 64 - fls64((u64)val);
-}
-EXPORT_SYMBOL(__clzdi2);
-
-int __weak __ctzdi2(long val)
-{
-	return __ffs64((u64)val);
-}
-EXPORT_SYMBOL(__ctzdi2);
-
-#else
-#error BITS_PER_LONG not 32 or 64
-#endif
diff --git a/kernel/lib/cpu_rmap.c b/kernel/lib/cpu_rmap.c
index f08d9c5..1833ad7 100644
--- a/kernel/lib/cpu_rmap.c
+++ b/kernel/lib/cpu_rmap.c
@@ -232,7 +232,8 @@
 
 	for (index = 0; index < rmap->used; index++) {
 		glue = rmap->obj[index];
-		irq_set_affinity_notifier(glue->notify.irq, NULL);
+		if (glue)
+			irq_set_affinity_notifier(glue->notify.irq, NULL);
 	}
 
 	cpu_rmap_put(rmap);
@@ -267,6 +268,7 @@
 	struct irq_glue *glue =
 		container_of(ref, struct irq_glue, notify.kref);
 
+	glue->rmap->obj[glue->index] = NULL;
 	cpu_rmap_put(glue->rmap);
 	kfree(glue);
 }
@@ -297,6 +299,7 @@
 	rc = irq_set_affinity_notifier(irq, &glue->notify);
 	if (rc) {
 		cpu_rmap_put(glue->rmap);
+		rmap->obj[glue->index] = NULL;
 		kfree(glue);
 	}
 	return rc;
diff --git a/kernel/lib/debugobjects.c b/kernel/lib/debugobjects.c
index 9e14ae0..4dd9283 100644
--- a/kernel/lib/debugobjects.c
+++ b/kernel/lib/debugobjects.c
@@ -129,7 +129,7 @@
 
 static void fill_pool(void)
 {
-	gfp_t gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
+	gfp_t gfp = __GFP_HIGH | __GFP_NOWARN;
 	struct debug_obj *obj;
 	unsigned long flags;
 
@@ -219,10 +219,6 @@
 	return obj;
 }
 
-/*
- * Allocate a new object. If the pool is empty, switch off the debugger.
- * Must be called with interrupts disabled.
- */
 static struct debug_obj *
 alloc_object(void *addr, struct debug_bucket *b, const struct debug_obj_descr *descr)
 {
@@ -440,6 +436,7 @@
 	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 +444,12 @@
 		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;
@@ -498,6 +501,15 @@
 	const struct debug_obj_descr *descr = obj->descr;
 	static int limit;
 
+	/*
+	 * Don't report if lookup_object_or_alloc() by the current thread
+	 * failed because lookup_object_or_alloc()/debug_objects_oom() by a
+	 * concurrent thread turned off debug_objects_enabled and cleared
+	 * the hash buckets.
+	 */
+	if (!debug_objects_enabled)
+		return;
+
 	if (limit < 5 && descr != descr_test) {
 		void *hint = descr->debug_hint ?
 			descr->debug_hint(obj->object) : NULL;
@@ -548,31 +560,74 @@
 	WARN_ON(1);
 }
 
+static struct debug_obj *lookup_object_or_alloc(void *addr, struct debug_bucket *b,
+						const struct debug_obj_descr *descr,
+						bool onstack, bool alloc_ifstatic)
+{
+	struct debug_obj *obj = lookup_object(addr, b);
+	enum debug_obj_state state = ODEBUG_STATE_NONE;
+
+	if (likely(obj))
+		return obj;
+
+	/*
+	 * debug_object_init() unconditionally allocates untracked
+	 * objects. It does not matter whether it is a static object or
+	 * not.
+	 *
+	 * debug_object_assert_init() and debug_object_activate() allow
+	 * allocation only if the descriptor callback confirms that the
+	 * object is static and considered initialized. For non-static
+	 * objects the allocation needs to be done from the fixup callback.
+	 */
+	if (unlikely(alloc_ifstatic)) {
+		if (!descr->is_static_object || !descr->is_static_object(addr))
+			return ERR_PTR(-ENOENT);
+		/* Statically allocated objects are considered initialized */
+		state = ODEBUG_STATE_INIT;
+	}
+
+	obj = alloc_object(addr, b, descr);
+	if (likely(obj)) {
+		obj->state = state;
+		debug_object_is_on_stack(addr, onstack);
+		return obj;
+	}
+
+	/* Out of memory. Do the cleanup outside of the locked region */
+	debug_objects_enabled = 0;
+	return NULL;
+}
+
+static void debug_objects_fill_pool(void)
+{
+	/*
+	 * On RT enabled kernels the pool refill must happen in preemptible
+	 * context:
+	 */
+	if (!IS_ENABLED(CONFIG_PREEMPT_RT) || preemptible())
+		fill_pool();
+}
+
 static void
 __debug_object_init(void *addr, const struct debug_obj_descr *descr, int onstack)
 {
 	enum debug_obj_state state;
-	bool check_stack = false;
 	struct debug_bucket *db;
 	struct debug_obj *obj;
 	unsigned long flags;
 
-	fill_pool();
+	debug_objects_fill_pool();
 
 	db = get_bucket((unsigned long) addr);
 
 	raw_spin_lock_irqsave(&db->lock, flags);
 
-	obj = lookup_object(addr, db);
-	if (!obj) {
-		obj = alloc_object(addr, db, descr);
-		if (!obj) {
-			debug_objects_enabled = 0;
-			raw_spin_unlock_irqrestore(&db->lock, flags);
-			debug_objects_oom();
-			return;
-		}
-		check_stack = true;
+	obj = lookup_object_or_alloc(addr, db, descr, onstack, false);
+	if (unlikely(!obj)) {
+		raw_spin_unlock_irqrestore(&db->lock, flags);
+		debug_objects_oom();
+		return;
 	}
 
 	switch (obj->state) {
@@ -598,8 +653,6 @@
 	}
 
 	raw_spin_unlock_irqrestore(&db->lock, flags);
-	if (check_stack)
-		debug_object_is_on_stack(addr, onstack);
 }
 
 /**
@@ -639,24 +692,24 @@
  */
 int debug_object_activate(void *addr, const struct debug_obj_descr *descr)
 {
+	struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr };
 	enum debug_obj_state state;
 	struct debug_bucket *db;
 	struct debug_obj *obj;
 	unsigned long flags;
 	int ret;
-	struct debug_obj o = { .object = addr,
-			       .state = ODEBUG_STATE_NOTAVAILABLE,
-			       .descr = descr };
 
 	if (!debug_objects_enabled)
 		return 0;
+
+	debug_objects_fill_pool();
 
 	db = get_bucket((unsigned long) addr);
 
 	raw_spin_lock_irqsave(&db->lock, flags);
 
-	obj = lookup_object(addr, db);
-	if (obj) {
+	obj = lookup_object_or_alloc(addr, db, descr, false, true);
+	if (likely(!IS_ERR_OR_NULL(obj))) {
 		bool print_object = false;
 
 		switch (obj->state) {
@@ -689,24 +742,16 @@
 
 	raw_spin_unlock_irqrestore(&db->lock, flags);
 
-	/*
-	 * We are here when a static object is activated. We
-	 * let the type specific code confirm whether this is
-	 * true or not. if true, we just make sure that the
-	 * static object is tracked in the object tracker. If
-	 * not, this must be a bug, so we try to fix it up.
-	 */
-	if (descr->is_static_object && descr->is_static_object(addr)) {
-		/* track this static object */
-		debug_object_init(addr, descr);
-		debug_object_activate(addr, descr);
-	} else {
-		debug_print_object(&o, "activate");
-		ret = debug_object_fixup(descr->fixup_activate, addr,
-					ODEBUG_STATE_NOTAVAILABLE);
-		return ret ? 0 : -EINVAL;
+	/* If NULL the allocation has hit OOM */
+	if (!obj) {
+		debug_objects_oom();
+		return 0;
 	}
-	return 0;
+
+	/* Object is neither static nor tracked. It's not initialized */
+	debug_print_object(&o, "activate");
+	ret = debug_object_fixup(descr->fixup_activate, addr, ODEBUG_STATE_NOTAVAILABLE);
+	return ret ? 0 : -EINVAL;
 }
 EXPORT_SYMBOL_GPL(debug_object_activate);
 
@@ -860,6 +905,7 @@
  */
 void debug_object_assert_init(void *addr, const struct debug_obj_descr *descr)
 {
+	struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr };
 	struct debug_bucket *db;
 	struct debug_obj *obj;
 	unsigned long flags;
@@ -867,34 +913,25 @@
 	if (!debug_objects_enabled)
 		return;
 
+	debug_objects_fill_pool();
+
 	db = get_bucket((unsigned long) addr);
 
 	raw_spin_lock_irqsave(&db->lock, flags);
+	obj = lookup_object_or_alloc(addr, db, descr, false, true);
+	raw_spin_unlock_irqrestore(&db->lock, flags);
+	if (likely(!IS_ERR_OR_NULL(obj)))
+		return;
 
-	obj = lookup_object(addr, db);
+	/* If NULL the allocation has hit OOM */
 	if (!obj) {
-		struct debug_obj o = { .object = addr,
-				       .state = ODEBUG_STATE_NOTAVAILABLE,
-				       .descr = descr };
-
-		raw_spin_unlock_irqrestore(&db->lock, flags);
-		/*
-		 * Maybe the object is static, and we let the type specific
-		 * code confirm. Track this static object if true, else invoke
-		 * fixup.
-		 */
-		if (descr->is_static_object && descr->is_static_object(addr)) {
-			/* Track this static object */
-			debug_object_init(addr, descr);
-		} else {
-			debug_print_object(&o, "assert_init");
-			debug_object_fixup(descr->fixup_assert_init, addr,
-					   ODEBUG_STATE_NOTAVAILABLE);
-		}
+		debug_objects_oom();
 		return;
 	}
 
-	raw_spin_unlock_irqrestore(&db->lock, flags);
+	/* Object is neither tracked nor static. It's not initialized. */
+	debug_print_object(&o, "assert_init");
+	debug_object_fixup(descr->fixup_assert_init, addr, ODEBUG_STATE_NOTAVAILABLE);
 }
 EXPORT_SYMBOL_GPL(debug_object_assert_init);
 
@@ -1316,6 +1353,8 @@
 		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 +1423,7 @@
 		debug_objects_enabled = 0;
 		kmem_cache_destroy(obj_cache);
 		pr_warn("out of memory.\n");
+		return;
 	} else
 		debug_objects_selftest();
 
diff --git a/kernel/lib/dim/dim.c b/kernel/lib/dim/dim.c
index 38045d6..e89aaf0 100644
--- a/kernel/lib/dim/dim.c
+++ b/kernel/lib/dim/dim.c
@@ -54,7 +54,7 @@
 }
 EXPORT_SYMBOL(dim_park_tired);
 
-void dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
+bool dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
 		    struct dim_stats *curr_stats)
 {
 	/* u32 holds up to 71 minutes, should be enough */
@@ -66,7 +66,7 @@
 			     start->comp_ctr);
 
 	if (!delta_us)
-		return;
+		return false;
 
 	curr_stats->ppms = DIV_ROUND_UP(npkts * USEC_PER_MSEC, delta_us);
 	curr_stats->bpms = DIV_ROUND_UP(nbytes * USEC_PER_MSEC, delta_us);
@@ -79,5 +79,6 @@
 	else
 		curr_stats->cpe_ratio = 0;
 
+	return true;
 }
 EXPORT_SYMBOL(dim_calc_stats);
diff --git a/kernel/lib/dim/net_dim.c b/kernel/lib/dim/net_dim.c
index dae3b51..0e4f3a6 100644
--- a/kernel/lib/dim/net_dim.c
+++ b/kernel/lib/dim/net_dim.c
@@ -227,7 +227,8 @@
 				  dim->start_sample.event_ctr);
 		if (nevents < DIM_NEVENTS)
 			break;
-		dim_calc_stats(&dim->start_sample, &end_sample, &curr_stats);
+		if (!dim_calc_stats(&dim->start_sample, &end_sample, &curr_stats))
+			break;
 		if (net_dim_decision(&curr_stats, dim)) {
 			dim->state = DIM_APPLY_NEW_PROFILE;
 			schedule_work(&dim->work);
diff --git a/kernel/lib/dim/rdma_dim.c b/kernel/lib/dim/rdma_dim.c
index f7e26c7..d32c8b1 100644
--- a/kernel/lib/dim/rdma_dim.c
+++ b/kernel/lib/dim/rdma_dim.c
@@ -88,7 +88,8 @@
 		nevents = curr_sample->event_ctr - dim->start_sample.event_ctr;
 		if (nevents < DIM_NEVENTS)
 			break;
-		dim_calc_stats(&dim->start_sample, curr_sample, &curr_stats);
+		if (!dim_calc_stats(&dim->start_sample, curr_sample, &curr_stats))
+			break;
 		if (rdma_dim_decision(&curr_stats, dim)) {
 			dim->state = DIM_APPLY_NEW_PROFILE;
 			schedule_work(&dim->work);
diff --git a/kernel/lib/errname.c b/kernel/lib/errname.c
index 0c4d3e6..a5799a8 100644
--- a/kernel/lib/errname.c
+++ b/kernel/lib/errname.c
@@ -20,6 +20,7 @@
 	E(EADDRNOTAVAIL),
 	E(EADV),
 	E(EAFNOSUPPORT),
+	E(EAGAIN), /* EWOULDBLOCK */
 	E(EALREADY),
 	E(EBADE),
 	E(EBADF),
@@ -30,15 +31,17 @@
 	E(EBADSLT),
 	E(EBFONT),
 	E(EBUSY),
-#ifdef ECANCELLED
-	E(ECANCELLED),
-#endif
+	E(ECANCELED), /* ECANCELLED */
 	E(ECHILD),
 	E(ECHRNG),
 	E(ECOMM),
 	E(ECONNABORTED),
+	E(ECONNREFUSED), /* EREFUSED */
 	E(ECONNRESET),
+	E(EDEADLK), /* EDEADLOCK */
+#if EDEADLK != EDEADLOCK /* mips, sparc, powerpc */
 	E(EDEADLOCK),
+#endif
 	E(EDESTADDRREQ),
 	E(EDOM),
 	E(EDOTDOT),
@@ -165,14 +168,17 @@
 	E(EUSERS),
 	E(EXDEV),
 	E(EXFULL),
-
-	E(ECANCELED), /* ECANCELLED */
-	E(EAGAIN), /* EWOULDBLOCK */
-	E(ECONNREFUSED), /* EREFUSED */
-	E(EDEADLK), /* EDEADLOCK */
 };
 #undef E
 
+#ifdef EREFUSED /* parisc */
+static_assert(EREFUSED == ECONNREFUSED);
+#endif
+#ifdef ECANCELLED /* parisc */
+static_assert(ECANCELLED == ECANCELED);
+#endif
+static_assert(EAGAIN == EWOULDBLOCK); /* everywhere */
+
 #define E(err) [err - 512 + BUILD_BUG_ON_ZERO(err < 512 || err > 550)] = "-" #err
 static const char *names_512[] = {
 	E(ERESTARTSYS),
diff --git a/kernel/lib/fonts/fonts.c b/kernel/lib/fonts/fonts.c
index 5f4b07b..9738664 100644
--- a/kernel/lib/fonts/fonts.c
+++ b/kernel/lib/fonts/fonts.c
@@ -135,8 +135,8 @@
 		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) {
diff --git a/kernel/lib/idr.c b/kernel/lib/idr.c
index 7ecdfdb..13f2758 100644
--- a/kernel/lib/idr.c
+++ b/kernel/lib/idr.c
@@ -100,7 +100,7 @@
  * @end: The maximum ID (exclusive).
  * @gfp: Memory allocation flags.
  *
- * Allocates an unused ID in the range specified by @nextid and @end.  If
+ * Allocates an unused ID in the range specified by @start and @end.  If
  * @end is <= 0, it is treated as one larger than %INT_MAX.  This allows
  * callers to use @start + N as @end as long as N is within integer range.
  * The search for an unused ID will start at the last ID allocated and will
diff --git a/kernel/lib/iov_iter.c b/kernel/lib/iov_iter.c
index 6505549..6e30113 100644
--- a/kernel/lib/iov_iter.c
+++ b/kernel/lib/iov_iter.c
@@ -467,20 +467,6 @@
 }
 EXPORT_SYMBOL(iov_iter_init);
 
-static void memcpy_from_page(char *to, struct page *page, size_t offset, size_t len)
-{
-	char *from = kmap_atomic(page);
-	memcpy(to, from + offset, len);
-	kunmap_atomic(from);
-}
-
-static void memcpy_to_page(struct page *page, size_t offset, const char *from, size_t len)
-{
-	char *to = kmap_atomic(page);
-	memcpy(to + offset, from, len);
-	kunmap_atomic(to);
-}
-
 static void memzero_page(struct page *page, size_t offset, size_t len)
 {
 	char *addr = kmap_atomic(page);
diff --git a/kernel/lib/kobject.c b/kernel/lib/kobject.c
index ea53b30..cd3e1a9 100644
--- a/kernel/lib/kobject.c
+++ b/kernel/lib/kobject.c
@@ -874,6 +874,11 @@
 	if (!k)
 		return -EINVAL;
 
+	if (!k->kobj.ktype) {
+		pr_err("must have a ktype to be initialized properly!\n");
+		return -EINVAL;
+	}
+
 	kset_init(k);
 	err = kobject_add_internal(&k->kobj);
 	if (err)
diff --git a/kernel/lib/kstrtox.c b/kernel/lib/kstrtox.c
index 8504526..53fa01f 100644
--- a/kernel/lib/kstrtox.c
+++ b/kernel/lib/kstrtox.c
@@ -14,11 +14,12 @@
  */
 #include <linux/ctype.h>
 #include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/math64.h>
 #include <linux/export.h>
+#include <linux/kstrtox.h>
+#include <linux/math64.h>
 #include <linux/types.h>
 #include <linux/uaccess.h>
+
 #include "kstrtox.h"
 
 const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
diff --git a/kernel/lib/lockref.c b/kernel/lib/lockref.c
index 5b34bbd..81ac5f3 100644
--- a/kernel/lib/lockref.c
+++ b/kernel/lib/lockref.c
@@ -24,7 +24,6 @@
 		}								\
 		if (!--retry)							\
 			break;							\
-		cpu_relax();							\
 	}									\
 } while (0)
 
diff --git a/kernel/lib/mpi/mpi-cmp.c b/kernel/lib/mpi/mpi-cmp.c
index c4cfa3f..0835b62 100644
--- a/kernel/lib/mpi/mpi-cmp.c
+++ b/kernel/lib/mpi/mpi-cmp.c
@@ -25,8 +25,12 @@
 	mpi_limb_t limb = v;
 
 	mpi_normalize(u);
-	if (!u->nlimbs && !limb)
-		return 0;
+	if (u->nlimbs == 0) {
+		if (v == 0)
+			return 0;
+		else
+			return -1;
+	}
 	if (u->sign)
 		return -1;
 	if (u->nlimbs > 1)
diff --git a/kernel/lib/mpi/mpicoder.c b/kernel/lib/mpi/mpicoder.c
index 7ea225b..7054311 100644
--- a/kernel/lib/mpi/mpicoder.c
+++ b/kernel/lib/mpi/mpicoder.c
@@ -504,7 +504,8 @@
 
 	while (sg_miter_next(&miter)) {
 		buff = miter.addr;
-		len = miter.length;
+		len = min_t(unsigned, miter.length, nbytes);
+		nbytes -= len;
 
 		for (x = 0; x < len; x++) {
 			a <<= 8;
diff --git a/kernel/lib/nlattr.c b/kernel/lib/nlattr.c
index fe60f9a..aa8fc43 100644
--- a/kernel/lib/nlattr.c
+++ b/kernel/lib/nlattr.c
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/jiffies.h>
+#include <linux/nospec.h>
 #include <linux/skbuff.h>
 #include <linux/string.h>
 #include <linux/types.h>
@@ -369,6 +370,7 @@
 	if (type <= 0 || type > maxtype)
 		return 0;
 
+	type = array_index_nospec(type, maxtype + 1);
 	pt = &policy[type];
 
 	BUG_ON(pt->type > NLA_TYPE_MAX);
@@ -584,6 +586,7 @@
 			}
 			continue;
 		}
+		type = array_index_nospec(type, maxtype + 1);
 		if (policy) {
 			int err = validate_nla(nla, maxtype, policy,
 					       validate, extack, depth);
diff --git a/kernel/lib/notifier-error-inject.c b/kernel/lib/notifier-error-inject.c
index 21016b3..2b24ea6 100644
--- a/kernel/lib/notifier-error-inject.c
+++ b/kernel/lib/notifier-error-inject.c
@@ -15,7 +15,7 @@
 	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,
diff --git a/kernel/lib/parser.c b/kernel/lib/parser.c
index f5b3e5d..5c37d63 100644
--- a/kernel/lib/parser.c
+++ b/kernel/lib/parser.c
@@ -6,6 +6,7 @@
 #include <linux/ctype.h>
 #include <linux/types.h>
 #include <linux/export.h>
+#include <linux/kstrtox.h>
 #include <linux/parser.h>
 #include <linux/slab.h>
 #include <linux/string.h>
diff --git a/kernel/lib/radix-tree.c b/kernel/lib/radix-tree.c
index 3a4da11..cbc6915 100644
--- a/kernel/lib/radix-tree.c
+++ b/kernel/lib/radix-tree.c
@@ -1133,7 +1133,6 @@
 void __rcu **radix_tree_iter_resume(void __rcu **slot,
 					struct radix_tree_iter *iter)
 {
-	slot++;
 	iter->index = __radix_tree_iter_add(iter, 1);
 	iter->next_index = iter->index;
 	iter->tags = 0;
diff --git a/kernel/lib/test_firmware.c b/kernel/lib/test_firmware.c
index 2baa275..25dc9eb 100644
--- a/kernel/lib/test_firmware.c
+++ b/kernel/lib/test_firmware.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/delay.h>
+#include <linux/kstrtox.h>
 #include <linux/kthread.h>
 #include <linux/vmalloc.h>
 #include <linux/efi_embedded_fw.h>
@@ -41,6 +42,7 @@
 	bool sent;
 	const struct firmware *fw;
 	const char *name;
+	const char *fw_buf;
 	struct completion completion;
 	struct task_struct *task;
 	struct device *dev;
@@ -143,8 +145,14 @@
 
 	for (i = 0; i < test_fw_config->num_requests; i++) {
 		req = &test_fw_config->reqs[i];
-		if (req->fw)
+		if (req->fw) {
+			if (req->fw_buf) {
+				kfree_const(req->fw_buf);
+				req->fw_buf = NULL;
+			}
 			release_firmware(req->fw);
+			req->fw = NULL;
+		}
 	}
 
 	vfree(test_fw_config->reqs);
@@ -175,7 +183,7 @@
 {
 	*dst = kstrndup(name, count, gfp);
 	if (!*dst)
-		return -ENOSPC;
+		return -ENOMEM;
 	return count;
 }
 
@@ -313,16 +321,26 @@
 	return len;
 }
 
+static inline int __test_dev_config_update_bool(const char *buf, size_t size,
+				       bool *cfg)
+{
+	int ret;
+
+	if (kstrtobool(buf, cfg) < 0)
+		ret = -EINVAL;
+	else
+		ret = size;
+
+	return ret;
+}
+
 static int test_dev_config_update_bool(const char *buf, size_t size,
 				       bool *cfg)
 {
 	int ret;
 
 	mutex_lock(&test_fw_mutex);
-	if (strtobool(buf, cfg) < 0)
-		ret = -EINVAL;
-	else
-		ret = size;
+	ret = __test_dev_config_update_bool(buf, size, cfg);
 	mutex_unlock(&test_fw_mutex);
 
 	return ret;
@@ -333,7 +351,8 @@
 	return snprintf(buf, PAGE_SIZE, "%d\n", val);
 }
 
-static int test_dev_config_update_size_t(const char *buf,
+static int __test_dev_config_update_size_t(
+					 const char *buf,
 					 size_t size,
 					 size_t *cfg)
 {
@@ -344,9 +363,7 @@
 	if (ret)
 		return ret;
 
-	mutex_lock(&test_fw_mutex);
 	*(size_t *)cfg = new;
-	mutex_unlock(&test_fw_mutex);
 
 	/* Always return full write size even if we didn't consume all */
 	return size;
@@ -362,24 +379,30 @@
 	return snprintf(buf, PAGE_SIZE, "%d\n", val);
 }
 
-static int test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg)
+static int __test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg)
 {
+	u8 val;
 	int ret;
-	long new;
 
-	ret = kstrtol(buf, 10, &new);
+	ret = kstrtou8(buf, 10, &val);
 	if (ret)
 		return ret;
 
-	if (new > U8_MAX)
-		return -EINVAL;
-
-	mutex_lock(&test_fw_mutex);
-	*(u8 *)cfg = new;
-	mutex_unlock(&test_fw_mutex);
+	*(u8 *)cfg = val;
 
 	/* Always return full write size even if we didn't consume all */
 	return size;
+}
+
+static int test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg)
+{
+	int ret;
+
+	mutex_lock(&test_fw_mutex);
+	ret = __test_dev_config_update_u8(buf, size, cfg);
+	mutex_unlock(&test_fw_mutex);
+
+	return ret;
 }
 
 static ssize_t test_dev_config_show_u8(char *buf, u8 val)
@@ -408,10 +431,10 @@
 		mutex_unlock(&test_fw_mutex);
 		goto out;
 	}
-	mutex_unlock(&test_fw_mutex);
 
-	rc = test_dev_config_update_u8(buf, count,
-				       &test_fw_config->num_requests);
+	rc = __test_dev_config_update_u8(buf, count,
+					 &test_fw_config->num_requests);
+	mutex_unlock(&test_fw_mutex);
 
 out:
 	return rc;
@@ -455,10 +478,10 @@
 		mutex_unlock(&test_fw_mutex);
 		goto out;
 	}
-	mutex_unlock(&test_fw_mutex);
 
-	rc = test_dev_config_update_size_t(buf, count,
-					   &test_fw_config->buf_size);
+	rc = __test_dev_config_update_size_t(buf, count,
+					     &test_fw_config->buf_size);
+	mutex_unlock(&test_fw_mutex);
 
 out:
 	return rc;
@@ -485,10 +508,10 @@
 		mutex_unlock(&test_fw_mutex);
 		goto out;
 	}
-	mutex_unlock(&test_fw_mutex);
 
-	rc = test_dev_config_update_size_t(buf, count,
-					   &test_fw_config->file_offset);
+	rc = __test_dev_config_update_size_t(buf, count,
+					     &test_fw_config->file_offset);
+	mutex_unlock(&test_fw_mutex);
 
 out:
 	return rc;
@@ -583,12 +606,14 @@
 
 	name = kstrndup(buf, count, GFP_KERNEL);
 	if (!name)
-		return -ENOSPC;
+		return -ENOMEM;
 
 	pr_info("loading '%s'\n", name);
 
 	mutex_lock(&test_fw_mutex);
 	release_firmware(test_firmware);
+	if (test_fw_config->reqs)
+		__test_release_all_firmware();
 	test_firmware = NULL;
 	rc = request_firmware(&test_firmware, name, dev);
 	if (rc) {
@@ -629,7 +654,7 @@
 
 	name = kstrndup(buf, count, GFP_KERNEL);
 	if (!name)
-		return -ENOSPC;
+		return -ENOMEM;
 
 	pr_info("inserting test platform fw '%s'\n", name);
 	efi_embedded_fw.name = name;
@@ -682,13 +707,15 @@
 
 	name = kstrndup(buf, count, GFP_KERNEL);
 	if (!name)
-		return -ENOSPC;
+		return -ENOMEM;
 
 	pr_info("loading '%s'\n", name);
 
 	mutex_lock(&test_fw_mutex);
 	release_firmware(test_firmware);
 	test_firmware = NULL;
+	if (test_fw_config->reqs)
+		__test_release_all_firmware();
 	rc = request_firmware_nowait(THIS_MODULE, 1, name, dev, GFP_KERNEL,
 				     NULL, trigger_async_request_cb);
 	if (rc) {
@@ -725,12 +752,14 @@
 
 	name = kstrndup(buf, count, GFP_KERNEL);
 	if (!name)
-		return -ENOSPC;
+		return -ENOMEM;
 
 	pr_info("loading '%s' using custom fallback mechanism\n", name);
 
 	mutex_lock(&test_fw_mutex);
 	release_firmware(test_firmware);
+	if (test_fw_config->reqs)
+		__test_release_all_firmware();
 	test_firmware = NULL;
 	rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, name,
 				     dev, GFP_KERNEL, NULL,
@@ -774,7 +803,7 @@
 
 		test_buf = kzalloc(TEST_FIRMWARE_BUF_SIZE, GFP_KERNEL);
 		if (!test_buf)
-			return -ENOSPC;
+			return -ENOMEM;
 
 		if (test_fw_config->partial)
 			req->rc = request_partial_firmware_into_buf
@@ -793,6 +822,8 @@
 						 test_fw_config->buf_size);
 		if (!req->fw)
 			kfree(test_buf);
+		else
+			req->fw_buf = test_buf;
 	} else {
 		req->rc = test_fw_config->req_firmware(&req->fw,
 						       req->name,
@@ -832,6 +863,11 @@
 
 	mutex_lock(&test_fw_mutex);
 
+	if (test_fw_config->reqs) {
+		rc = -EBUSY;
+		goto out_bail;
+	}
+
 	test_fw_config->reqs =
 		vzalloc(array3_size(sizeof(struct test_batched_req),
 				    test_fw_config->num_requests, 2));
@@ -848,6 +884,7 @@
 		req->fw = NULL;
 		req->idx = i;
 		req->name = test_fw_config->name;
+		req->fw_buf = NULL;
 		req->dev = dev;
 		init_completion(&req->completion);
 		req->task = kthread_run(test_fw_run_batch_request, req,
@@ -930,6 +967,11 @@
 
 	mutex_lock(&test_fw_mutex);
 
+	if (test_fw_config->reqs) {
+		rc = -EBUSY;
+		goto out_bail;
+	}
+
 	test_fw_config->reqs =
 		vzalloc(array3_size(sizeof(struct test_batched_req),
 				    test_fw_config->num_requests, 2));
@@ -947,6 +989,7 @@
 	for (i = 0; i < test_fw_config->num_requests; i++) {
 		req = &test_fw_config->reqs[i];
 		req->name = test_fw_config->name;
+		req->fw_buf = NULL;
 		req->fw = NULL;
 		req->idx = i;
 		init_completion(&req->completion);
@@ -1114,6 +1157,7 @@
 
 	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;
diff --git a/kernel/lib/test_kmod.c b/kernel/lib/test_kmod.c
index c637f6b..c282728 100644
--- a/kernel/lib/test_kmod.c
+++ b/kernel/lib/test_kmod.c
@@ -877,20 +877,17 @@
 					    int (*test_sync)(struct kmod_test_device *test_dev))
 {
 	int ret;
-	unsigned long new;
+	unsigned int val;
 	unsigned int old_val;
 
-	ret = kstrtoul(buf, 10, &new);
+	ret = kstrtouint(buf, 10, &val);
 	if (ret)
 		return ret;
-
-	if (new > UINT_MAX)
-		return -EINVAL;
 
 	mutex_lock(&test_dev->config_mutex);
 
 	old_val = *config;
-	*(unsigned int *)config = new;
+	*(unsigned int *)config = val;
 
 	ret = test_sync(test_dev);
 	if (ret) {
@@ -914,18 +911,18 @@
 					     unsigned int min,
 					     unsigned int max)
 {
+	unsigned int val;
 	int ret;
-	unsigned long new;
 
-	ret = kstrtoul(buf, 10, &new);
+	ret = kstrtouint(buf, 10, &val);
 	if (ret)
 		return ret;
 
-	if (new < min || new > max)
+	if (val < min || val > max)
 		return -EINVAL;
 
 	mutex_lock(&test_dev->config_mutex);
-	*config = new;
+	*config = val;
 	mutex_unlock(&test_dev->config_mutex);
 
 	/* Always return full write size even if we didn't consume all */
@@ -936,18 +933,15 @@
 				      const char *buf, size_t size,
 				      int *config)
 {
+	int val;
 	int ret;
-	long new;
 
-	ret = kstrtol(buf, 10, &new);
+	ret = kstrtoint(buf, 10, &val);
 	if (ret)
 		return ret;
 
-	if (new < INT_MIN || new > INT_MAX)
-		return -EINVAL;
-
 	mutex_lock(&test_dev->config_mutex);
-	*config = new;
+	*config = val;
 	mutex_unlock(&test_dev->config_mutex);
 	/* Always return full write size even if we didn't consume all */
 	return size;
diff --git a/kernel/lib/test_meminit.c b/kernel/lib/test_meminit.c
index 3ca717f..0f1a3bd 100644
--- a/kernel/lib/test_meminit.c
+++ b/kernel/lib/test_meminit.c
@@ -86,7 +86,7 @@
 	int failures = 0, num_tests = 0;
 	int i;
 
-	for (i = 0; i < 10; i++)
+	for (i = 0; i < MAX_ORDER; i++)
 		num_tests += do_alloc_pages_order(i, &failures);
 
 	REPORT_FAILURES_IN_FN();
diff --git a/kernel/lib/ts_bm.c b/kernel/lib/ts_bm.c
index 4cf2500..352ae83 100644
--- a/kernel/lib/ts_bm.c
+++ b/kernel/lib/ts_bm.c
@@ -60,10 +60,12 @@
 	struct ts_bm *bm = ts_config_priv(conf);
 	unsigned int i, text_len, consumed = state->offset;
 	const u8 *text;
-	int shift = bm->patlen - 1, bs;
+	int bs;
 	const u8 icase = conf->flags & TS_IGNORECASE;
 
 	for (;;) {
+		int shift = bm->patlen - 1;
+
 		text_len = conf->get_next_block(consumed, &text, conf, state);
 
 		if (unlikely(text_len == 0))
diff --git a/kernel/lib/ubsan.c b/kernel/lib/ubsan.c
index 6e36b16..36780b1 100644
--- a/kernel/lib/ubsan.c
+++ b/kernel/lib/ubsan.c
@@ -151,16 +151,7 @@
 
 	current->in_ubsan--;
 
-	if (panic_on_warn) {
-		/*
-		 * This thread may hit another WARN() in the panic path.
-		 * Resetting this prevents additional WARN() from panicking the
-		 * system on this thread.  Other threads are blocked by the
-		 * panic_mutex in panic().
-		 */
-		panic_on_warn = 0;
-		panic("panic_on_warn set ...\n");
-	}
+	check_panic_on_warn("UBSAN");
 }
 
 void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs)
diff --git a/kernel/lib/usercopy.c b/kernel/lib/usercopy.c
index 7413dd3..7ee63df 100644
--- a/kernel/lib/usercopy.c
+++ b/kernel/lib/usercopy.c
@@ -3,6 +3,7 @@
 #include <linux/fault-inject-usercopy.h>
 #include <linux/instrumented.h>
 #include <linux/uaccess.h>
+#include <linux/nospec.h>
 
 /* out-of-line parts */
 
@@ -12,6 +13,12 @@
 	unsigned long res = n;
 	might_fault();
 	if (!should_fail_usercopy() && likely(access_ok(from, n))) {
+		/*
+		 * Ensure that bad access_ok() speculation will not
+		 * lead to nasty side effects *after* the copy is
+		 * finished:
+		 */
+		barrier_nospec();
 		instrument_copy_from_user(to, from, n);
 		res = raw_copy_from_user(to, from, n);
 	}
diff --git a/kernel/mm/backing-dev.c b/kernel/mm/backing-dev.c
index ca770a7..dd08ab9 100644
--- a/kernel/mm/backing-dev.c
+++ b/kernel/mm/backing-dev.c
@@ -378,6 +378,15 @@
 static DEFINE_SPINLOCK(cgwb_lock);
 static struct workqueue_struct *cgwb_release_wq;
 
+static void cgwb_free_rcu(struct rcu_head *rcu_head)
+{
+	struct bdi_writeback *wb = container_of(rcu_head,
+			struct bdi_writeback, rcu);
+
+	percpu_ref_exit(&wb->refcnt);
+	kfree(wb);
+}
+
 static void cgwb_release_workfn(struct work_struct *work)
 {
 	struct bdi_writeback *wb = container_of(work, struct bdi_writeback,
@@ -395,9 +404,8 @@
 	blkcg_unpin_online(blkcg);
 
 	fprop_local_destroy_percpu(&wb->memcg_completions);
-	percpu_ref_exit(&wb->refcnt);
 	wb_exit(wb);
-	kfree_rcu(wb, rcu);
+	call_rcu(&wb->rcu, cgwb_free_rcu);
 }
 
 static void cgwb_release(struct percpu_ref *refcnt)
diff --git a/kernel/mm/compaction.c b/kernel/mm/compaction.c
index 9922a6f..dc96fad 100644
--- a/kernel/mm/compaction.c
+++ b/kernel/mm/compaction.c
@@ -45,6 +45,11 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/compaction.h>
 
+#undef CREATE_TRACE_POINTS
+#ifndef __GENKSYMS__
+#include <trace/hooks/mm.h>
+#endif
+
 #define block_start_pfn(pfn, order)	round_down(pfn, 1UL << (order))
 #define block_end_pfn(pfn, order)	ALIGN((pfn) + 1, 1UL << (order))
 #define pageblock_start_pfn(pfn)	block_start_pfn(pfn, pageblock_order)
@@ -1270,7 +1275,7 @@
 }
 
 static void
-fast_isolate_around(struct compact_control *cc, unsigned long pfn, unsigned long nr_isolated)
+fast_isolate_around(struct compact_control *cc, unsigned long pfn)
 {
 	unsigned long start_pfn, end_pfn;
 	struct page *page;
@@ -1291,21 +1296,13 @@
 	if (!page)
 		return;
 
-	/* Scan before */
-	if (start_pfn != pfn) {
-		isolate_freepages_block(cc, &start_pfn, pfn, &cc->freepages, 1, false);
-		if (cc->nr_freepages >= cc->nr_migratepages)
-			return;
-	}
-
-	/* Scan after */
-	start_pfn = pfn + nr_isolated;
-	if (start_pfn < end_pfn)
-		isolate_freepages_block(cc, &start_pfn, end_pfn, &cc->freepages, 1, false);
+	isolate_freepages_block(cc, &start_pfn, end_pfn, &cc->freepages, 1, false);
 
 	/* Skip this pageblock in the future as it's full or nearly full */
 	if (cc->nr_freepages < cc->nr_migratepages)
 		set_pageblock_skip(page);
+
+	return;
 }
 
 /* Search orders in round-robin fashion */
@@ -1481,7 +1478,7 @@
 		return cc->free_pfn;
 
 	low_pfn = page_to_pfn(page);
-	fast_isolate_around(cc, low_pfn, nr_isolated);
+	fast_isolate_around(cc, low_pfn);
 	return low_pfn;
 }
 
@@ -1992,6 +1989,7 @@
 	unsigned int order;
 	const int migratetype = cc->migratetype;
 	int ret;
+	bool abort_compact = false;
 
 	/* Compaction run completes if the migrate and free scanner meet */
 	if (compact_scanners_met(cc)) {
@@ -2091,7 +2089,8 @@
 	}
 
 out:
-	if (cc->contended || fatal_signal_pending(current))
+	trace_android_vh_compact_finished(&abort_compact);
+	if (cc->contended || fatal_signal_pending(current) || abort_compact)
 		ret = COMPACT_CONTENDED;
 
 	return ret;
diff --git a/kernel/mm/damon/dbgfs.c b/kernel/mm/damon/dbgfs.c
index f2772fc..819c337 100644
--- a/kernel/mm/damon/dbgfs.c
+++ b/kernel/mm/damon/dbgfs.c
@@ -785,6 +785,7 @@
 static int dbgfs_rm_context(char *name)
 {
 	struct dentry *root, *dir, **new_dirs;
+	struct inode *inode;
 	struct damon_ctx **new_ctxs;
 	int i, j;
 	int ret = 0;
@@ -800,6 +801,12 @@
 	if (!dir)
 		return -ENOENT;
 
+	inode = d_inode(dir);
+	if (!S_ISDIR(inode->i_mode)) {
+		ret = -EINVAL;
+		goto out_dput;
+	}
+
 	new_dirs = kmalloc_array(dbgfs_nr_ctxs - 1, sizeof(*dbgfs_dirs),
 			GFP_KERNEL);
 	if (!new_dirs) {
diff --git a/kernel/mm/filemap.c b/kernel/mm/filemap.c
index aeb45f3..580c1b9 100644
--- a/kernel/mm/filemap.c
+++ b/kernel/mm/filemap.c
@@ -2211,6 +2211,9 @@
 
 	if (unlikely(*ppos >= inode->i_sb->s_maxbytes))
 		return 0;
+	if (unlikely(!iov_iter_count(iter)))
+		return 0;
+
 	iov_iter_truncate(iter, inode->i_sb->s_maxbytes);
 
 	index = *ppos >> PAGE_SHIFT;
@@ -2661,6 +2664,8 @@
 	ra->start = max_t(long, 0, vmf->pgoff - ra->ra_pages / 2);
 	ra->size = ra->ra_pages;
 	ra->async_size = ra->ra_pages / 4;
+	trace_android_vh_tune_mmap_readaround(ra->ra_pages, vmf->pgoff,
+			&ra->start, &ra->size, &ra->async_size);
 	ractl._index = ra->start;
 	do_page_cache_ra(&ractl, ra->size, ra->async_size);
 	return fpin;
@@ -2736,11 +2741,14 @@
 
 	if (vmf->flags & FAULT_FLAG_SPECULATIVE) {
 		page = find_get_page(mapping, offset);
-		if (unlikely(!page) || unlikely(PageReadahead(page)))
+		if (unlikely(!page))
 			return VM_FAULT_RETRY;
 
+		if (unlikely(PageReadahead(page)))
+			goto page_put;
+
 		if (!trylock_page(page))
-			return VM_FAULT_RETRY;
+			goto page_put;
 
 		if (unlikely(compound_head(page)->mapping != mapping))
 			goto page_unlock;
@@ -2772,6 +2780,8 @@
 		return VM_FAULT_LOCKED;
 page_unlock:
 		unlock_page(page);
+page_put:
+		put_page(page);
 		return VM_FAULT_RETRY;
 	}
 
diff --git a/kernel/mm/frame_vector.c b/kernel/mm/frame_vector.c
index 0e589a9..1cd81d3 100644
--- a/kernel/mm/frame_vector.c
+++ b/kernel/mm/frame_vector.c
@@ -29,6 +29,10 @@
  * different type underlying the specified range of virtual addresses.
  * When the function isn't able to map a single page, it returns error.
  *
+ * Note that get_vaddr_frames() cannot follow VM_IO mappings. It used
+ * to be able to do that, but that could (racily) return non-refcounted
+ * pfns.
+ *
  * This function takes care of grabbing mmap_lock as necessary.
  */
 int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
@@ -77,8 +81,6 @@
 			goto out;
 	}
 
-	/* This used to (racily) return non-refcounted pfns. Let people know */
-	WARN_ONCE(1, "get_vaddr_frames() cannot follow VM_IO mapping");
 	vec->nr_frames = 0;
 
 out:
diff --git a/kernel/mm/gup.c b/kernel/mm/gup.c
index 0c8affb..86ce78f 100644
--- a/kernel/mm/gup.c
+++ b/kernel/mm/gup.c
@@ -1645,7 +1645,7 @@
 		 */
 		if (is_migrate_cma_page(head)) {
 			if (PageHuge(head)) {
-				if (!isolate_huge_page(head, &cma_page_list))
+				if (isolate_hugetlb(head, &cma_page_list))
 					isolation_error_count++;
 			} else {
 				if (!PageLRU(head) && drain_allow) {
diff --git a/kernel/mm/huge_memory.c b/kernel/mm/huge_memory.c
index 993816e..14bc799 100644
--- a/kernel/mm/huge_memory.c
+++ b/kernel/mm/huge_memory.c
@@ -1994,7 +1994,7 @@
 {
 	struct mm_struct *mm = vma->vm_mm;
 	pgtable_t pgtable;
-	pmd_t _pmd;
+	pmd_t _pmd, old_pmd;
 	int i;
 
 	/*
@@ -2005,7 +2005,7 @@
 	 *
 	 * See Documentation/vm/mmu_notifier.rst
 	 */
-	pmdp_huge_clear_flush(vma, haddr, pmd);
+	old_pmd = pmdp_huge_clear_flush(vma, haddr, pmd);
 
 	pgtable = pgtable_trans_huge_withdraw(mm, pmd);
 	pmd_populate(mm, &_pmd, pgtable);
@@ -2014,6 +2014,8 @@
 		pte_t *pte, entry;
 		entry = pfn_pte(my_zero_pfn(haddr), vma->vm_page_prot);
 		entry = pte_mkspecial(entry);
+		if (pmd_uffd_wp(old_pmd))
+			entry = pte_mkuffd_wp(entry);
 		pte = pte_offset_map(&_pmd, haddr);
 		VM_BUG_ON(!pte_none(*pte));
 		set_pte_at(mm, haddr, pte, entry);
@@ -2816,6 +2818,9 @@
 	if (PageSwapCache(page))
 		return;
 
+	if (!list_empty(page_deferred_list(page)))
+		return;
+
 	spin_lock_irqsave(&ds_queue->split_queue_lock, flags);
 	if (list_empty(page_deferred_list(page))) {
 		count_vm_event(THP_DEFERRED_SPLIT_PAGE);
diff --git a/kernel/mm/hugetlb.c b/kernel/mm/hugetlb.c
index 035ef50..a4682bb 100644
--- a/kernel/mm/hugetlb.c
+++ b/kernel/mm/hugetlb.c
@@ -78,6 +78,9 @@
 static int num_fault_mutexes;
 struct mutex *hugetlb_fault_mutex_table ____cacheline_aligned_in_smp;
 
+static void hugetlb_unshare_pmds(struct vm_area_struct *vma,
+		unsigned long start, unsigned long end);
+
 static inline bool PageHugeFreed(struct page *head)
 {
 	return page_private(head + 4) == -1UL;
@@ -3698,6 +3701,25 @@
 {
 	if (addr & ~(huge_page_mask(hstate_vma(vma))))
 		return -EINVAL;
+
+	/*
+	 * PMD sharing is only possible for PUD_SIZE-aligned address ranges
+	 * in HugeTLB VMAs. If we will lose PUD_SIZE alignment due to this
+	 * split, unshare PMDs in the PUD_SIZE interval surrounding addr now.
+	 */
+	if (addr & ~PUD_MASK) {
+		/*
+		 * hugetlb_vm_op_split is called right before we attempt to
+		 * split the VMA. We will need to unshare PMDs in the old and
+		 * new VMAs, so let's unshare before we split.
+		 */
+		unsigned long floor = addr & PUD_MASK;
+		unsigned long ceil = floor + PUD_SIZE;
+
+		if (floor >= vma->vm_start && ceil <= vma->vm_end)
+			hugetlb_unshare_pmds(vma, floor, ceil);
+	}
+
 	return 0;
 }
 
@@ -5696,14 +5718,14 @@
 	return pte_page(*(pte_t *)pgd) + ((address & ~PGDIR_MASK) >> PAGE_SHIFT);
 }
 
-bool isolate_huge_page(struct page *page, struct list_head *list)
+int isolate_hugetlb(struct page *page, struct list_head *list)
 {
-	bool ret = true;
+	int ret = 0;
 
 	spin_lock(&hugetlb_lock);
 	if (!PageHeadHuge(page) || !page_huge_active(page) ||
 	    !get_page_unless_zero(page)) {
-		ret = false;
+		ret = -EBUSY;
 		goto unlock;
 	}
 	clear_page_huge_active(page);
@@ -5756,25 +5778,20 @@
 	}
 }
 
-/*
- * This function will unconditionally remove all the shared pmd pgtable entries
- * within the specific vma for a hugetlbfs memory range.
- */
-void hugetlb_unshare_all_pmds(struct vm_area_struct *vma)
+static void hugetlb_unshare_pmds(struct vm_area_struct *vma,
+				   unsigned long start,
+				   unsigned long end)
 {
 	struct hstate *h = hstate_vma(vma);
 	unsigned long sz = huge_page_size(h);
 	struct mm_struct *mm = vma->vm_mm;
 	struct mmu_notifier_range range;
-	unsigned long address, start, end;
+	unsigned long address;
 	spinlock_t *ptl;
 	pte_t *ptep;
 
 	if (!(vma->vm_flags & VM_MAYSHARE))
 		return;
-
-	start = ALIGN(vma->vm_start, PUD_SIZE);
-	end = ALIGN_DOWN(vma->vm_end, PUD_SIZE);
 
 	if (start >= end)
 		return;
@@ -5808,6 +5825,16 @@
 	mmu_notifier_invalidate_range_end(&range);
 }
 
+/*
+ * This function will unconditionally remove all the shared pmd pgtable entries
+ * within the specific vma for a hugetlbfs memory range.
+ */
+void hugetlb_unshare_all_pmds(struct vm_area_struct *vma)
+{
+	hugetlb_unshare_pmds(vma, ALIGN(vma->vm_start, PUD_SIZE),
+			ALIGN_DOWN(vma->vm_end, PUD_SIZE));
+}
+
 #ifdef CONFIG_CMA
 static bool cma_reserve_called __initdata;
 
diff --git a/kernel/mm/kasan/report.c b/kernel/mm/kasan/report.c
index 8fff182..13bdaac 100644
--- a/kernel/mm/kasan/report.c
+++ b/kernel/mm/kasan/report.c
@@ -92,16 +92,8 @@
 	pr_err("==================================================================\n");
 	add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
 	spin_unlock_irqrestore(&report_lock, *flags);
-	if (panic_on_warn && !test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags)) {
-		/*
-		 * This thread may hit another WARN() in the panic path.
-		 * Resetting this prevents additional WARN() from panicking the
-		 * system on this thread.  Other threads are blocked by the
-		 * panic_mutex in panic().
-		 */
-		panic_on_warn = 0;
-		panic("panic_on_warn set ...\n");
-	}
+	if (!test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags))
+		check_panic_on_warn("KASAN");
 #ifdef CONFIG_KASAN_HW_TAGS
 	if (kasan_flag_panic)
 		panic("kasan.fault=panic set ...\n");
diff --git a/kernel/mm/kfence/Makefile b/kernel/mm/kfence/Makefile
index 6872cd5..cb2bcf7 100644
--- a/kernel/mm/kfence/Makefile
+++ b/kernel/mm/kfence/Makefile
@@ -2,5 +2,5 @@
 
 obj-$(CONFIG_KFENCE) := core.o report.o
 
-CFLAGS_kfence_test.o := -g -fno-omit-frame-pointer -fno-optimize-sibling-calls
+CFLAGS_kfence_test.o := -fno-omit-frame-pointer -fno-optimize-sibling-calls
 obj-$(CONFIG_KFENCE_KUNIT_TEST) += kfence_test.o
diff --git a/kernel/mm/khugepaged.c b/kernel/mm/khugepaged.c
index 6ddc276..d0ec863 100644
--- a/kernel/mm/khugepaged.c
+++ b/kernel/mm/khugepaged.c
@@ -623,6 +623,10 @@
 			result = SCAN_PTE_NON_PRESENT;
 			goto out;
 		}
+		if (pte_uffd_wp(pteval)) {
+			result = SCAN_PTE_UFFD_WP;
+			goto out;
+		}
 		page = vm_normal_page(vma, address, pteval);
 		if (unlikely(!page)) {
 			result = SCAN_PAGE_NULL;
@@ -1464,14 +1468,6 @@
 	if (!hugepage_vma_check(vma, vma->vm_flags | VM_HUGEPAGE))
 		return;
 
-	/*
-	 * Symmetry with retract_page_tables(): Exclude MAP_PRIVATE mappings
-	 * that got written to. Without this, we'd have to also lock the
-	 * anon_vma if one exists.
-	 */
-	if (vma->anon_vma)
-		return;
-
 	hpage = find_lock_page(vma->vm_file->f_mapping,
 			       linear_page_index(vma, haddr));
 	if (!hpage)
@@ -1545,6 +1541,10 @@
 	}
 
 	/* step 4: collapse pmd */
+	/* we make no change to anon, but protect concurrent anon page lookup */
+	if (vma->anon_vma)
+		anon_vma_lock_write(vma->anon_vma);
+
 	mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, NULL, mm, haddr,
 				haddr + HPAGE_PMD_SIZE);
 	mmu_notifier_invalidate_range_start(&range);
@@ -1555,6 +1555,8 @@
 	mmu_notifier_invalidate_range_end(&range);
 	pte_free(mm, pmd_pgtable(_pmd));
 
+	if (vma->anon_vma)
+		anon_vma_unlock_write(vma->anon_vma);
 	i_mmap_unlock_write(vma->vm_file->f_mapping);
 
 drop_hpage:
diff --git a/kernel/mm/madvise.c b/kernel/mm/madvise.c
index b3761ca..7071c11 100644
--- a/kernel/mm/madvise.c
+++ b/kernel/mm/madvise.c
@@ -322,8 +322,11 @@
 	struct page *page = NULL;
 	LIST_HEAD(page_list);
 	bool allow_shared = false;
+	bool abort_madvise = false;
+	bool skip = false;
 
-	if (fatal_signal_pending(current))
+	trace_android_vh_madvise_cold_or_pageout_abort(vma, &abort_madvise);
+	if (fatal_signal_pending(current) || abort_madvise)
 		return -EINTR;
 
 	trace_android_vh_madvise_cold_or_pageout(vma, &allow_shared);
@@ -417,6 +420,10 @@
 		if (!page)
 			continue;
 
+		trace_android_vh_should_end_madvise(mm, &skip, &pageout);
+		if (skip)
+			break;
+
 		/*
 		 * Creating a THP page is expensive so split it only if we
 		 * are sure it's worth. Split it if we are only owner.
diff --git a/kernel/mm/memcontrol.c b/kernel/mm/memcontrol.c
index 0501a27..b6f6bfc 100644
--- a/kernel/mm/memcontrol.c
+++ b/kernel/mm/memcontrol.c
@@ -73,6 +73,7 @@
 EXPORT_SYMBOL(memory_cgrp_subsys);
 
 struct mem_cgroup *root_mem_cgroup __read_mostly;
+EXPORT_SYMBOL_GPL(root_mem_cgroup);
 
 /* Active memory cgroup to use from an interrupt context */
 DEFINE_PER_CPU(struct mem_cgroup *, int_active_memcg);
@@ -858,6 +859,7 @@
 	if (!mem_cgroup_disabled())
 		__mod_memcg_lruvec_state(lruvec, idx, val);
 }
+EXPORT_SYMBOL_GPL(__mod_lruvec_state);
 
 void __mod_lruvec_slab_state(void *p, enum node_stat_item idx, int val)
 {
@@ -1442,6 +1444,7 @@
 	if (nr_pages > 0)
 		*lru_size += nr_pages;
 }
+EXPORT_SYMBOL_GPL(mem_cgroup_update_lru_size);
 
 /**
  * mem_cgroup_margin - calculate chargeable space of a memory cgroup
@@ -3963,6 +3966,10 @@
 {
 	struct mem_cgroup *memcg = mem_cgroup_from_css(css);
 
+	pr_warn_once("Cgroup memory moving (move_charge_at_immigrate) is deprecated. "
+		     "Please report your usecase to linux-mm@kvack.org if you "
+		     "depend on this functionality.\n");
+
 	if (val & ~MOVE_MASK)
 		return -EINVAL;
 
@@ -4206,7 +4213,7 @@
 {
 	struct mem_cgroup *memcg = mem_cgroup_from_css(css);
 
-	if (val > 100)
+	if (val > 200)
 		return -EINVAL;
 
 	if (css->parent)
diff --git a/kernel/mm/memfd.c b/kernel/mm/memfd.c
index fae4142..278e563 100644
--- a/kernel/mm/memfd.c
+++ b/kernel/mm/memfd.c
@@ -330,7 +330,8 @@
 
 	if (flags & MFD_ALLOW_SEALING) {
 		file_seals = memfd_file_seals_ptr(file);
-		*file_seals &= ~F_SEAL_SEAL;
+		if (file_seals)
+			*file_seals &= ~F_SEAL_SEAL;
 	}
 
 	fd_install(fd, file);
diff --git a/kernel/mm/memory-failure.c b/kernel/mm/memory-failure.c
index 4bd73d6..9aa2a15 100644
--- a/kernel/mm/memory-failure.c
+++ b/kernel/mm/memory-failure.c
@@ -1690,70 +1690,51 @@
 
 /*
  * Safely get reference count of an arbitrary page.
- * Returns 0 for a free page, -EIO for a zero refcount page
- * that is not free, and 1 for any other page type.
- * For 1 the page is returned with increased page count, otherwise not.
+ * Returns 0 for a free page, 1 for an in-use page, -EIO for a page-type we
+ * cannot handle and -EBUSY if we raced with an allocation.
+ * We only incremented refcount in case the page was already in-use and it is
+ * a known type we can handle.
  */
-static int __get_any_page(struct page *p, unsigned long pfn, int flags)
+static int get_any_page(struct page *p, int flags)
 {
-	int ret;
+	int ret = 0, pass = 0;
+	bool count_increased = false;
 
 	if (flags & MF_COUNT_INCREASED)
-		return 1;
+		count_increased = true;
 
-	/*
-	 * When the target page is a free hugepage, just remove it
-	 * from free hugepage list.
-	 */
-	if (!get_hwpoison_page(p)) {
-		if (PageHuge(p)) {
-			pr_info("%s: %#lx free huge page\n", __func__, pfn);
-			ret = 0;
-		} else if (is_free_buddy_page(p)) {
-			pr_info("%s: %#lx free buddy page\n", __func__, pfn);
-			ret = 0;
-		} else if (page_count(p)) {
-			/* raced with allocation */
+try_again:
+	if (!count_increased && !get_hwpoison_page(p)) {
+		if (page_count(p)) {
+			/* We raced with an allocation, retry. */
+			if (pass++ < 3)
+				goto try_again;
 			ret = -EBUSY;
-		} else {
-			pr_info("%s: %#lx: unknown zero refcount page type %lx\n",
-				__func__, pfn, p->flags);
+		} else if (!PageHuge(p) && !is_free_buddy_page(p)) {
+			/* We raced with put_page, retry. */
+			if (pass++ < 3)
+				goto try_again;
 			ret = -EIO;
 		}
 	} else {
-		/* Not a free page */
-		ret = 1;
-	}
-	return ret;
-}
-
-static int get_any_page(struct page *page, unsigned long pfn, int flags)
-{
-	int ret = __get_any_page(page, pfn, flags);
-
-	if (ret == -EBUSY)
-		ret = __get_any_page(page, pfn, flags);
-
-	if (ret == 1 && !PageHuge(page) &&
-	    !PageLRU(page) && !__PageMovable(page)) {
-		/*
-		 * Try to free it.
-		 */
-		put_page(page);
-		shake_page(page, 1);
-
-		/*
-		 * Did it turn free?
-		 */
-		ret = __get_any_page(page, pfn, 0);
-		if (ret == 1 && !PageLRU(page)) {
-			/* Drop page reference which is from __get_any_page() */
-			put_page(page);
-			pr_info("soft_offline: %#lx: unknown non LRU page type %lx (%pGp)\n",
-				pfn, page->flags, &page->flags);
-			return -EIO;
+		if (PageHuge(p) || PageLRU(p) || __PageMovable(p)) {
+			ret = 1;
+		} else {
+			/*
+			 * A page we cannot handle. Check whether we can turn
+			 * it into something we can handle.
+			 */
+			if (pass++ < 3) {
+				put_page(p);
+				shake_page(p, 1);
+				count_increased = false;
+				goto try_again;
+			}
+			put_page(p);
+			ret = -EIO;
 		}
 	}
+
 	return ret;
 }
 
@@ -1763,7 +1744,7 @@
 	bool lru = PageLRU(page);
 
 	if (PageHuge(page)) {
-		isolated = isolate_huge_page(page, pagelist);
+		isolated = !isolate_hugetlb(page, pagelist);
 	} else {
 		if (lru)
 			isolated = !isolate_lru_page(page);
@@ -1876,14 +1857,10 @@
 	return __soft_offline_page(page);
 }
 
-static int soft_offline_free_page(struct page *page)
+static void put_ref_page(struct page *page)
 {
-	int rc = 0;
-
-	if (!page_handle_poison(page, true, false))
-		rc = -EBUSY;
-
-	return rc;
+	if (page)
+		put_page(page);
 }
 
 /**
@@ -1911,36 +1888,49 @@
 int soft_offline_page(unsigned long pfn, int flags)
 {
 	int ret;
-	struct page *page;
 	bool try_again = true;
+	struct page *page, *ref_page = NULL;
+
+	WARN_ON_ONCE(!pfn_valid(pfn) && (flags & MF_COUNT_INCREASED));
 
 	if (!pfn_valid(pfn))
 		return -ENXIO;
+	if (flags & MF_COUNT_INCREASED)
+		ref_page = pfn_to_page(pfn);
+
 	/* Only online pages can be soft-offlined (esp., not ZONE_DEVICE). */
 	page = pfn_to_online_page(pfn);
-	if (!page)
+	if (!page) {
+		put_ref_page(ref_page);
 		return -EIO;
+	}
 
 	if (PageHWPoison(page)) {
-		pr_info("soft offline: %#lx page already poisoned\n", pfn);
-		if (flags & MF_COUNT_INCREASED)
-			put_page(page);
+		pr_info("%s: %#lx page already poisoned\n", __func__, pfn);
+		put_ref_page(ref_page);
 		return 0;
 	}
 
 retry:
 	get_online_mems();
-	ret = get_any_page(page, pfn, flags);
+	ret = get_any_page(page, flags);
 	put_online_mems();
 
-	if (ret > 0)
+	if (ret > 0) {
 		ret = soft_offline_in_use_page(page);
-	else if (ret == 0)
-		if (soft_offline_free_page(page) && try_again) {
-			try_again = false;
-			flags &= ~MF_COUNT_INCREASED;
-			goto retry;
+	} else if (ret == 0) {
+		if (!page_handle_poison(page, true, false)) {
+			if (try_again) {
+				try_again = false;
+				flags &= ~MF_COUNT_INCREASED;
+				goto retry;
+			}
+			ret = -EBUSY;
 		}
+	} else if (ret == -EIO) {
+		pr_info("%s: %#lx: unknown page type: %lx (%pGp)\n",
+			 __func__, pfn, page->flags, &page->flags);
+	}
 
 	return ret;
 }
diff --git a/kernel/mm/memory.c b/kernel/mm/memory.c
index 834078a..857cfc9 100644
--- a/kernel/mm/memory.c
+++ b/kernel/mm/memory.c
@@ -246,6 +246,16 @@
 			   unsigned long addr)
 {
 	pgtable_t token = pmd_pgtable(*pmd);
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+	/*
+	 * Ensure page table destruction is blocked if __pte_map_lock managed
+	 * to take this lock. Without this barrier tlb_remove_table_rcu can
+	 * destroy ptl after __pte_map_lock locked it and during unlock would
+	 * cause a use-after-free.
+	 */
+	spinlock_t *ptl = pmd_lock(tlb->mm, pmd);
+	spin_unlock(ptl);
+#endif
 	pmd_clear(pmd);
 	pte_free_tlb(tlb, token, addr);
 	mm_dec_nr_ptes(tlb->mm);
@@ -2627,9 +2637,7 @@
 static bool pte_spinlock(struct vm_fault *vmf)
 {
 	bool ret = false;
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 	pmd_t pmdval;
-#endif
 
 	/* Check if vma is still valid */
 	if (!(vmf->flags & FAULT_FLAG_SPECULATIVE)) {
@@ -2644,24 +2652,28 @@
 		goto out;
 	}
 
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 	/*
 	 * We check if the pmd value is still the same to ensure that there
 	 * is not a huge collapse operation in progress in our back.
+	 * It also ensures that pmd was not cleared by pmd_clear in
+	 * free_pte_range and ptl is still valid.
 	 */
 	pmdval = READ_ONCE(*vmf->pmd);
 	if (!pmd_same(pmdval, vmf->orig_pmd)) {
 		trace_spf_pmd_changed(_RET_IP_, vmf->vma, vmf->address);
 		goto out;
 	}
-#endif
 
-	vmf->ptl = pte_lockptr(vmf->vma->vm_mm, vmf->pmd);
+	vmf->ptl = pte_lockptr(vmf->vma->vm_mm, &pmdval);
 	if (unlikely(!spin_trylock(vmf->ptl))) {
 		trace_spf_pte_lock(_RET_IP_, vmf->vma, vmf->address);
 		goto out;
 	}
 
+	/*
+	 * The check below will fail if pte_spinlock passed its ptl barrier
+	 * before we took the ptl lock.
+	 */
 	if (vma_has_changed(vmf)) {
 		spin_unlock(vmf->ptl);
 		trace_spf_vma_changed(_RET_IP_, vmf->vma, vmf->address);
@@ -2679,9 +2691,7 @@
 	bool ret = false;
 	pte_t *pte;
 	spinlock_t *ptl;
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 	pmd_t pmdval;
-#endif
 
 	/*
 	 * The first vma_has_changed() guarantees the page-tables are still
@@ -2696,7 +2706,6 @@
 		goto out;
 	}
 
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 	/*
 	 * We check if the pmd value is still the same to ensure that there
 	 * is not a huge collapse operation in progress in our back.
@@ -2706,7 +2715,6 @@
 		trace_spf_pmd_changed(_RET_IP_, vmf->vma, addr);
 		goto out;
 	}
-#endif
 
 	/*
 	 * Same as pte_offset_map_lock() except that we call
@@ -2715,14 +2723,18 @@
 	 * to invalidate TLB but this CPU has irq disabled.
 	 * Since we are in a speculative patch, accept it could fail
 	 */
-	ptl = pte_lockptr(vmf->vma->vm_mm, vmf->pmd);
-	pte = pte_offset_map(vmf->pmd, addr);
+	ptl = pte_lockptr(vmf->vma->vm_mm, &pmdval);
+	pte = pte_offset_map(&pmdval, addr);
 	if (unlikely(!spin_trylock(ptl))) {
 		pte_unmap(pte);
 		trace_spf_pte_lock(_RET_IP_, vmf->vma, addr);
 		goto out;
 	}
 
+	/*
+	 * The check below will fail if __pte_map_lock_speculative passed its ptl
+	 * barrier before we took the ptl lock.
+	 */
 	if (vma_has_changed(vmf)) {
 		pte_unmap_unlock(pte, ptl);
 		trace_spf_vma_changed(_RET_IP_, vmf->vma, addr);
@@ -3651,8 +3663,10 @@
 
 	if (!page) {
 		struct swap_info_struct *si = swp_swap_info(entry);
+		bool skip_swapcache = false;
 
-		if (data_race(si->flags & SWP_SYNCHRONOUS_IO) &&
+		trace_android_vh_skip_swapcache(entry, &skip_swapcache);
+		if ((data_race(si->flags & SWP_SYNCHRONOUS_IO) || skip_swapcache) &&
 		    __swap_count(entry) == 1) {
 			/* skip swapcache */
 			gfp_t flags = GFP_HIGHUSER_MOVABLE;
diff --git a/kernel/mm/memory_hotplug.c b/kernel/mm/memory_hotplug.c
index 9176bae..386d85f 100644
--- a/kernel/mm/memory_hotplug.c
+++ b/kernel/mm/memory_hotplug.c
@@ -1334,7 +1334,7 @@
 
 		if (PageHuge(page)) {
 			pfn = page_to_pfn(head) + compound_nr(head) - 1;
-			isolate_huge_page(head, &source);
+			isolate_hugetlb(head, &source);
 			continue;
 		} else if (PageTransHuge(page))
 			pfn = page_to_pfn(head) + thp_nr_pages(page) - 1;
@@ -1865,39 +1865,112 @@
 }
 EXPORT_SYMBOL_GPL(remove_memory_subsection);
 
+static int try_offline_memory_block(struct memory_block *mem, void *arg)
+{
+	uint8_t online_type = MMOP_ONLINE_KERNEL;
+	uint8_t **online_types = arg;
+	struct page *page;
+	int rc;
+
+	/*
+	 * Sense the online_type via the zone of the memory block. Offlining
+	 * with multiple zones within one memory block will be rejected
+	 * by offlining code ... so we don't care about that.
+	 */
+	page = pfn_to_online_page(section_nr_to_pfn(mem->start_section_nr));
+	if (page && zone_idx(page_zone(page)) == ZONE_MOVABLE)
+		online_type = MMOP_ONLINE_MOVABLE;
+
+	rc = device_offline(&mem->dev);
+	/*
+	 * Default is MMOP_OFFLINE - change it only if offlining succeeded,
+	 * so try_reonline_memory_block() can do the right thing.
+	 */
+	if (!rc)
+		**online_types = online_type;
+
+	(*online_types)++;
+	/* Ignore if already offline. */
+	return rc < 0 ? rc : 0;
+}
+
+static int try_reonline_memory_block(struct memory_block *mem, void *arg)
+{
+	uint8_t **online_types = arg;
+	int rc;
+
+	if (**online_types != MMOP_OFFLINE) {
+		mem->online_type = **online_types;
+		rc = device_online(&mem->dev);
+		if (rc < 0)
+			pr_warn("%s: Failed to re-online memory: %d",
+				__func__, rc);
+	}
+
+	/* Continue processing all remaining memory blocks. */
+	(*online_types)++;
+	return 0;
+}
+
 /*
- * Try to offline and remove a memory block. Might take a long time to
- * finish in case memory is still in use. Primarily useful for memory devices
- * that logically unplugged all memory (so it's no longer in use) and want to
- * offline + remove the memory block.
+ * Try to offline and remove memory. Might take a long time to finish in case
+ * memory is still in use. Primarily useful for memory devices that logically
+ * unplugged all memory (so it's no longer in use) and want to offline + remove
+ * that memory.
  */
 int offline_and_remove_memory(int nid, u64 start, u64 size)
 {
-	struct memory_block *mem;
-	int rc = -EINVAL;
+	const unsigned long mb_count = size / memory_block_size_bytes();
+	uint8_t *online_types, *tmp;
+	int rc;
 
 	if (!IS_ALIGNED(start, memory_block_size_bytes()) ||
-	    size != memory_block_size_bytes())
-		return rc;
-
-	lock_device_hotplug();
-	mem = find_memory_block(__pfn_to_section(PFN_DOWN(start)));
-	if (mem)
-		rc = device_offline(&mem->dev);
-	/* Ignore if the device is already offline. */
-	if (rc > 0)
-		rc = 0;
+	    !IS_ALIGNED(size, memory_block_size_bytes()) || !size)
+		return -EINVAL;
 
 	/*
-	 * In case we succeeded to offline the memory block, remove it.
+	 * We'll remember the old online type of each memory block, so we can
+	 * try to revert whatever we did when offlining one memory block fails
+	 * after offlining some others succeeded.
+	 */
+	online_types = kmalloc_array(mb_count, sizeof(*online_types),
+				     GFP_KERNEL);
+	if (!online_types)
+		return -ENOMEM;
+	/*
+	 * Initialize all states to MMOP_OFFLINE, so when we abort processing in
+	 * try_offline_memory_block(), we'll skip all unprocessed blocks in
+	 * try_reonline_memory_block().
+	 */
+	memset(online_types, MMOP_OFFLINE, mb_count);
+
+	lock_device_hotplug();
+
+	tmp = online_types;
+	rc = walk_memory_blocks(start, size, &tmp, try_offline_memory_block);
+
+	/*
+	 * In case we succeeded to offline all memory, remove it.
 	 * This cannot fail as it cannot get onlined in the meantime.
 	 */
 	if (!rc) {
 		rc = try_remove_memory(nid, start, size);
-		WARN_ON_ONCE(rc);
+		if (rc)
+			pr_err("%s: Failed to remove memory: %d", __func__, rc);
+	}
+
+	/*
+	 * Rollback what we did. While memory onlining might theoretically fail
+	 * (nacked by a notifier), it barely ever happens.
+	 */
+	if (rc) {
+		tmp = online_types;
+		walk_memory_blocks(start, size, &tmp,
+				   try_reonline_memory_block);
 	}
 	unlock_device_hotplug();
 
+	kfree(online_types);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(offline_and_remove_memory);
diff --git a/kernel/mm/mempolicy.c b/kernel/mm/mempolicy.c
index 142929e..67f75cf 100644
--- a/kernel/mm/mempolicy.c
+++ b/kernel/mm/mempolicy.c
@@ -625,8 +625,9 @@
 
 	/* With MPOL_MF_MOVE, we migrate only unshared hugepage. */
 	if (flags & (MPOL_MF_MOVE_ALL) ||
-	    (flags & MPOL_MF_MOVE && page_mapcount(page) == 1)) {
-		if (!isolate_huge_page(page, qp->pagelist) &&
+	    (flags & MPOL_MF_MOVE && page_mapcount(page) == 1 &&
+	     !hugetlb_pmd_shared(pte))) {
+		if (isolate_hugetlb(page, qp->pagelist) &&
 			(flags & MPOL_MF_STRICT))
 			/*
 			 * Failed to isolate page but allow migrating pages
diff --git a/kernel/mm/migrate.c b/kernel/mm/migrate.c
index 9fec180..ac32427 100644
--- a/kernel/mm/migrate.c
+++ b/kernel/mm/migrate.c
@@ -141,7 +141,7 @@
  *
  * This function shall be used whenever the isolated pageset has been
  * built from lru, balloon, hugetlbfs page. See isolate_migratepages_range()
- * and isolate_huge_page().
+ * and isolate_hugetlb().
  */
 void putback_movable_pages(struct list_head *l)
 {
@@ -1642,8 +1642,9 @@
 
 	if (PageHuge(page)) {
 		if (PageHead(page)) {
-			isolate_huge_page(page, pagelist);
-			err = 1;
+			err = isolate_hugetlb(page, pagelist);
+			if (!err)
+				err = 1;
 		}
 	} else {
 		struct page *head;
diff --git a/kernel/mm/page_alloc.c b/kernel/mm/page_alloc.c
index 3868586..3bcee27 100644
--- a/kernel/mm/page_alloc.c
+++ b/kernel/mm/page_alloc.c
@@ -1614,11 +1614,16 @@
 	unsigned long flags;
 	int migratetype;
 	unsigned long pfn = page_to_pfn(page);
+	bool skip_free_unref_page = false;
 
 	if (!free_pages_prepare(page, order, true, fpi_flags))
 		return;
 
 	migratetype = get_pfnblock_migratetype(page, pfn);
+	trace_android_vh_free_unref_page_bypass(page, order, migratetype, &skip_free_unref_page);
+	if (skip_free_unref_page)
+		return;
+
 	local_irq_save(flags);
 	__count_vm_events(PGFREE, 1 << order);
 	free_one_page(page_zone(page), page, pfn, order, migratetype,
@@ -2797,6 +2802,7 @@
 	struct page *page;
 	int order;
 	bool ret;
+	bool skip_unreserve_highatomic = false;
 
 	for_each_zone_zonelist_nodemask(zone, z, zonelist, ac->highest_zoneidx,
 								ac->nodemask) {
@@ -2806,6 +2812,11 @@
 		 */
 		if (!force && zone->nr_reserved_highatomic <=
 					pageblock_nr_pages)
+			continue;
+
+		trace_android_vh_unreserve_highatomic_bypass(force, zone,
+				&skip_unreserve_highatomic);
+		if (skip_unreserve_highatomic)
 			continue;
 
 		spin_lock_irqsave(&zone->lock, flags);
@@ -3053,6 +3064,10 @@
 	struct list_head *list = &pcp->lists[migratetype];
 
 	if (list_empty(list)) {
+		trace_android_vh_rmqueue_bulk_bypass(order, pcp, migratetype, list);
+		if (!list_empty(list))
+			return list;
+
 		pcp->count += rmqueue_bulk(zone, order,
 				pcp->batch, list,
 				migratetype, alloc_flags);
@@ -3349,8 +3364,15 @@
 {
 	unsigned long flags;
 	unsigned long pfn = page_to_pfn(page);
+	int migratetype;
+	bool skip_free_unref_page = false;
 
 	if (!free_unref_page_prepare(page, pfn))
+		return;
+
+	migratetype = get_pfnblock_migratetype(page, pfn);
+	trace_android_vh_free_unref_page_bypass(page, 0, migratetype, &skip_free_unref_page);
+	if (skip_free_unref_page)
 		return;
 
 	local_irq_save(flags);
@@ -4828,6 +4850,7 @@
 	unsigned int zonelist_iter_cookie;
 	int reserve_flags;
 	unsigned long vh_record;
+	bool should_alloc_retry = false;
 
 	trace_android_vh_alloc_pages_slowpath_begin(gfp_mask, order, &vh_record);
 	/*
@@ -4967,6 +4990,12 @@
 
 	if (page)
 		goto got_pg;
+
+	trace_android_vh_should_alloc_pages_retry(gfp_mask, order,
+		&alloc_flags, ac->migratetype, ac->preferred_zoneref->zone,
+		&page, &should_alloc_retry);
+	if (should_alloc_retry)
+		goto retry;
 
 	/* Try direct reclaim and then allocating */
 	page = __alloc_pages_direct_reclaim(gfp_mask, order, alloc_flags, ac,
@@ -5240,10 +5269,13 @@
 
 void __free_pages(struct page *page, unsigned int order)
 {
+	/* get PageHead before we drop reference */
+	int head = PageHead(page);
+
 	trace_android_vh_free_pages(page, order);
 	if (put_page_testzero(page))
 		free_the_page(page, order);
-	else if (!PageHead(page))
+	else if (!head)
 		while (order-- > 0)
 			free_the_page(page + (1 << order), order);
 }
@@ -6158,7 +6190,21 @@
 	int nid;
 	int __maybe_unused cpu;
 	pg_data_t *self = data;
+	unsigned long flags;
 
+	/*
+	 * Explicitly disable this CPU's interrupts before taking seqlock
+	 * to prevent any IRQ handler from calling into the page allocator
+	 * (e.g. GFP_ATOMIC) that could hit zonelist_iter_begin and livelock.
+	 */
+	local_irq_save(flags);
+	/*
+	 * Explicitly disable this CPU's synchronous printk() before taking
+	 * seqlock to prevent any printk() from trying to hold port->lock, for
+	 * tty_insert_flip_string_and_push_buffer() on other CPU might be
+	 * calling kmalloc(GFP_ATOMIC | __GFP_NOWARN) with port->lock held.
+	 */
+	printk_deferred_enter();
 	write_seqlock(&zonelist_update_seq);
 
 #ifdef CONFIG_NUMA
@@ -6193,6 +6239,8 @@
 	}
 
 	write_sequnlock(&zonelist_update_seq);
+	printk_deferred_exit();
+	local_irq_restore(flags);
 }
 
 static noinline void __init
@@ -6612,6 +6660,7 @@
 static void pageset_update(struct per_cpu_pages *pcp, unsigned long high,
 		unsigned long batch)
 {
+	trace_android_vh_pageset_update(&high, &batch);
        /* start with a fail safe value for batch */
 	pcp->batch = 1;
 	smp_wmb();
diff --git a/kernel/mm/page_ext.c b/kernel/mm/page_ext.c
index 7718f21..7cd4e37 100644
--- a/kernel/mm/page_ext.c
+++ b/kernel/mm/page_ext.c
@@ -155,7 +155,7 @@
 
 /**
  * page_ext_put() - Working with page extended information is done.
- * @page_ext - Page extended information received from page_ext_get().
+ * @page_ext: Page extended information received from page_ext_get().
  *
  * The page extended information of the page may not be valid after this
  * function is called.
diff --git a/kernel/mm/page_owner.c b/kernel/mm/page_owner.c
index 8dd3f27..b3e5f98 100644
--- a/kernel/mm/page_owner.c
+++ b/kernel/mm/page_owner.c
@@ -33,6 +33,7 @@
 
 bool page_owner_enabled;
 DEFINE_STATIC_KEY_FALSE(page_owner_inited);
+EXPORT_SYMBOL_GPL(page_owner_inited);
 
 static depot_stack_handle_t dummy_handle;
 static depot_stack_handle_t failure_handle;
@@ -222,6 +223,7 @@
 	__set_page_owner_handle(page, page_ext, handle, order, gfp_mask);
 	page_ext_put(page_ext);
 }
+EXPORT_SYMBOL_GPL(__set_page_owner);
 
 void __set_page_owner_migrate_reason(struct page *page, int reason)
 {
diff --git a/kernel/mm/page_pinner.c b/kernel/mm/page_pinner.c
index a444584..74543ce 100644
--- a/kernel/mm/page_pinner.c
+++ b/kernel/mm/page_pinner.c
@@ -57,6 +57,7 @@
 
 static bool page_pinner_enabled;
 DEFINE_STATIC_KEY_FALSE(page_pinner_inited);
+EXPORT_SYMBOL(page_pinner_inited);
 
 DEFINE_STATIC_KEY_TRUE(failure_tracking);
 EXPORT_SYMBOL(failure_tracking);
diff --git a/kernel/mm/rmap.c b/kernel/mm/rmap.c
index 033b047..5338a8b 100644
--- a/kernel/mm/rmap.c
+++ b/kernel/mm/rmap.c
@@ -91,7 +91,8 @@
 	anon_vma = kmem_cache_alloc(anon_vma_cachep, GFP_KERNEL);
 	if (anon_vma) {
 		atomic_set(&anon_vma->refcount, 1);
-		anon_vma->degree = 1;	/* Reference for first vma */
+		anon_vma->num_children = 0;
+		anon_vma->num_active_vmas = 0;
 		anon_vma->parent = anon_vma;
 		/*
 		 * Initialise the anon_vma root to point to itself. If called
@@ -199,6 +200,7 @@
 		anon_vma = anon_vma_alloc();
 		if (unlikely(!anon_vma))
 			goto out_enomem_free_avc;
+		anon_vma->num_children++; /* self-parent link for new root */
 		allocated = anon_vma;
 	}
 
@@ -208,8 +210,7 @@
 	if (likely(!vma->anon_vma)) {
 		vma->anon_vma = anon_vma;
 		anon_vma_chain_link(vma, avc, anon_vma);
-		/* vma reference or self-parent link for new root */
-		anon_vma->degree++;
+		anon_vma->num_active_vmas++;
 		allocated = NULL;
 		avc = NULL;
 	}
@@ -294,19 +295,19 @@
 		anon_vma_chain_link(dst, avc, anon_vma);
 
 		/*
-		 * Reuse existing anon_vma if its degree lower than two,
-		 * that means it has no vma and only one anon_vma child.
+		 * Reuse existing anon_vma if it has no vma and only one
+		 * anon_vma child.
 		 *
-		 * Do not chose parent anon_vma, otherwise first child
-		 * will always reuse it. Root anon_vma is never reused:
+		 * Root anon_vma is never reused:
 		 * it has self-parent reference and at least one child.
 		 */
 		if (!dst->anon_vma && src->anon_vma &&
-		    anon_vma != src->anon_vma && anon_vma->degree < 2)
+		    anon_vma->num_children < 2 &&
+		    anon_vma->num_active_vmas == 0)
 			dst->anon_vma = anon_vma;
 	}
 	if (dst->anon_vma)
-		dst->anon_vma->degree++;
+		dst->anon_vma->num_active_vmas++;
 	unlock_anon_vma_root(root);
 	return 0;
 
@@ -356,6 +357,7 @@
 	anon_vma = anon_vma_alloc();
 	if (!anon_vma)
 		goto out_error;
+	anon_vma->num_active_vmas++;
 	avc = anon_vma_chain_alloc(GFP_KERNEL);
 	if (!avc)
 		goto out_error_free_anon_vma;
@@ -376,7 +378,7 @@
 	vma->anon_vma = anon_vma;
 	anon_vma_lock_write(anon_vma);
 	anon_vma_chain_link(vma, avc, anon_vma);
-	anon_vma->parent->degree++;
+	anon_vma->parent->num_children++;
 	anon_vma_unlock_write(anon_vma);
 
 	return 0;
@@ -408,7 +410,7 @@
 		 * to free them outside the lock.
 		 */
 		if (RB_EMPTY_ROOT(&anon_vma->rb_root.rb_root)) {
-			anon_vma->parent->degree--;
+			anon_vma->parent->num_children--;
 			continue;
 		}
 
@@ -416,7 +418,8 @@
 		anon_vma_chain_free(avc);
 	}
 	if (vma->anon_vma)
-		vma->anon_vma->degree--;
+		vma->anon_vma->num_active_vmas--;
+
 	unlock_anon_vma_root(root);
 
 	/*
@@ -427,7 +430,8 @@
 	list_for_each_entry_safe(avc, next, &vma->anon_vma_chain, same_vma) {
 		struct anon_vma *anon_vma = avc->anon_vma;
 
-		VM_WARN_ON(anon_vma->degree);
+		VM_WARN_ON(anon_vma->num_children);
+		VM_WARN_ON(anon_vma->num_active_vmas);
 		put_anon_vma(anon_vma);
 
 		list_del(&avc->same_vma);
@@ -911,6 +915,7 @@
 
 	return rwc.contended ? -1 : pra.referenced;
 }
+EXPORT_SYMBOL_GPL(page_referenced);
 
 static bool page_mkclean_one(struct page *page, struct vm_area_struct *vma,
 			    unsigned long address, void *arg)
diff --git a/kernel/mm/shmem.c b/kernel/mm/shmem.c
index 768c918..b812f26 100644
--- a/kernel/mm/shmem.c
+++ b/kernel/mm/shmem.c
@@ -3424,6 +3424,8 @@
 	unsigned long long size;
 	char *rest;
 	int opt;
+	kuid_t kuid;
+	kgid_t kgid;
 
 	opt = fs_parse(fc, shmem_fs_parameters, param, &result);
 	if (opt < 0)
@@ -3459,14 +3461,32 @@
 		ctx->mode = result.uint_32 & 07777;
 		break;
 	case Opt_uid:
-		ctx->uid = make_kuid(current_user_ns(), result.uint_32);
-		if (!uid_valid(ctx->uid))
+		kuid = make_kuid(current_user_ns(), result.uint_32);
+		if (!uid_valid(kuid))
 			goto bad_value;
+
+		/*
+		 * The requested uid must be representable in the
+		 * filesystem's idmapping.
+		 */
+		if (!kuid_has_mapping(fc->user_ns, kuid))
+			goto bad_value;
+
+		ctx->uid = kuid;
 		break;
 	case Opt_gid:
-		ctx->gid = make_kgid(current_user_ns(), result.uint_32);
-		if (!gid_valid(ctx->gid))
+		kgid = make_kgid(current_user_ns(), result.uint_32);
+		if (!gid_valid(kgid))
 			goto bad_value;
+
+		/*
+		 * The requested gid must be representable in the
+		 * filesystem's idmapping.
+		 */
+		if (!kgid_has_mapping(fc->user_ns, kgid))
+			goto bad_value;
+
+		ctx->gid = kgid;
 		break;
 	case Opt_huge:
 		ctx->huge = result.uint_32;
@@ -4100,7 +4120,7 @@
 	.name		= "tmpfs",
 	.init_fs_context = ramfs_init_fs_context,
 	.parameters	= ramfs_fs_parameters,
-	.kill_sb	= kill_litter_super,
+	.kill_sb	= ramfs_kill_sb,
 	.fs_flags	= FS_USERNS_MOUNT,
 };
 
diff --git a/kernel/mm/swapfile.c b/kernel/mm/swapfile.c
index b3cc174..cc1ce66 100644
--- a/kernel/mm/swapfile.c
+++ b/kernel/mm/swapfile.c
@@ -668,12 +668,19 @@
 {
 	int nid;
 
+	assert_spin_locked(&p->lock);
 	for_each_node(nid)
 		plist_del(&p->avail_lists[nid], &swap_avail_heads[nid]);
 }
 
 static void del_from_avail_list(struct swap_info_struct *p)
 {
+	bool skip = false;
+
+	trace_android_vh_del_from_avail_list(p, &skip);
+	if (skip)
+		return;
+
 	spin_lock(&swap_avail_lock);
 	__del_from_avail_list(p);
 	spin_unlock(&swap_avail_lock);
@@ -699,6 +706,11 @@
 static void add_to_avail_list(struct swap_info_struct *p)
 {
 	int nid;
+	bool skip = false;
+
+	trace_android_vh_add_to_avail_list(p, &skip);
+	if (skip)
+		return;
 
 	spin_lock(&swap_avail_lock);
 	for_each_node(nid) {
@@ -1111,6 +1123,7 @@
 			goto check_out;
 		pr_debug("scan_swap_map of si %d failed to find offset\n",
 			si->type);
+		cond_resched();
 
 		spin_lock(&swap_avail_lock);
 nextsi:
@@ -2629,8 +2642,8 @@
 		spin_unlock(&swap_lock);
 		goto out_dput;
 	}
-	del_from_avail_list(p);
 	spin_lock(&p->lock);
+	del_from_avail_list(p);
 	if (p->prio < 0) {
 		struct swap_info_struct *si = p;
 		int nid;
@@ -3392,6 +3405,8 @@
 	if (swap_flags & SWAP_FLAG_PREFER)
 		prio =
 		  (swap_flags & SWAP_FLAG_PRIO_MASK) >> SWAP_FLAG_PRIO_SHIFT;
+
+	trace_android_vh_swap_avail_heads_init(swap_avail_heads);
 	enable_swap_info(p, prio, swap_map, cluster_info, frontswap_map);
 
 	trace_android_vh_init_swap_info_struct(p, swap_avail_heads);
@@ -3846,6 +3861,7 @@
 {
 	struct swap_info_struct *si, *next;
 	int nid = page_to_nid(page);
+	bool skip = false;
 
 	if (!(gfp_mask & __GFP_IO))
 		return;
@@ -3860,6 +3876,10 @@
 	if (current->throttle_queue)
 		return;
 
+	trace_android_vh___cgroup_throttle_swaprate(nid, &skip);
+	if (skip)
+		return;
+
 	spin_lock(&swap_avail_lock);
 	plist_for_each_entry_safe(si, next, &swap_avail_heads[nid],
 				  avail_lists[nid]) {
diff --git a/kernel/mm/userfaultfd.c b/kernel/mm/userfaultfd.c
index 80da102..fa707e5 100644
--- a/kernel/mm/userfaultfd.c
+++ b/kernel/mm/userfaultfd.c
@@ -63,7 +63,7 @@
 	pte_t _dst_pte, *dst_pte;
 	bool writable = dst_vma->vm_flags & VM_WRITE;
 	bool vm_shared = dst_vma->vm_flags & VM_SHARED;
-	bool page_in_cache = page->mapping;
+	bool page_in_cache = page_mapping(page);
 	spinlock_t *ptl;
 	struct inode *inode;
 	pgoff_t offset, max_off;
diff --git a/kernel/mm/util.c b/kernel/mm/util.c
index 9e2b223..6ed9861 100644
--- a/kernel/mm/util.c
+++ b/kernel/mm/util.c
@@ -29,6 +29,7 @@
 #include "internal.h"
 #ifndef __GENKSYMS__
 #include <trace/hooks/syscall_check.h>
+#include <trace/hooks/mm.h>
 #endif
 
 /**
@@ -587,6 +588,7 @@
 {
 	gfp_t kmalloc_flags = flags;
 	void *ret;
+	bool use_vmalloc = false;
 
 	/*
 	 * vmalloc uses GFP_KERNEL for some internal allocations (e.g page tables)
@@ -594,6 +596,10 @@
 	 */
 	if ((flags & GFP_KERNEL) != GFP_KERNEL)
 		return kmalloc_node(size, flags, node);
+
+	trace_android_vh_kvmalloc_node_use_vmalloc(size, &kmalloc_flags, &use_vmalloc);
+	if (use_vmalloc)
+		goto use_vmalloc_node;
 
 	/*
 	 * We want to attempt a large physically contiguous block first because
@@ -624,6 +630,7 @@
 		return NULL;
 	}
 
+use_vmalloc_node:
 	return __vmalloc_node(size, 1, flags, node,
 			__builtin_return_address(0));
 }
diff --git a/kernel/mm/vmalloc.c b/kernel/mm/vmalloc.c
index 3b56c30..fa1ea48 100644
--- a/kernel/mm/vmalloc.c
+++ b/kernel/mm/vmalloc.c
@@ -2463,6 +2463,10 @@
 		free_vm_area(area);
 		return NULL;
 	}
+
+	flush_cache_vmap((unsigned long)area->addr,
+			 (unsigned long)area->addr + count * PAGE_SIZE);
+
 	return area->addr;
 }
 EXPORT_SYMBOL_GPL(vmap_pfn);
diff --git a/kernel/mm/vmscan.c b/kernel/mm/vmscan.c
index 4a11800..f94f52e 100644
--- a/kernel/mm/vmscan.c
+++ b/kernel/mm/vmscan.c
@@ -1128,6 +1128,7 @@
 	LIST_HEAD(free_pages);
 	unsigned int nr_reclaimed = 0;
 	unsigned int pgactivate = 0;
+	bool page_trylock_result;
 
 	memset(stat, 0, sizeof(*stat));
 	cond_resched();
@@ -1527,6 +1528,18 @@
 			count_memcg_page_event(page, PGACTIVATE);
 		}
 keep_locked:
+		/*
+		 * The page with trylock-bit will be added ret_pages and
+		 * handled in trace_android_vh_handle_failed_page_trylock.
+		 * In the progress[unlock_page, handled], the page carried
+		 * with trylock-bit will cause some error-issues in other
+		 * scene, so clear trylock-bit here.
+		 * trace_android_vh_page_trylock_get_result will clear
+		 * trylock-bit and return if page tyrlock failed in
+		 * reclaim-process. Here we just want to clear trylock-bit
+		 * so that ignore page_trylock_result.
+		 */
+		trace_android_vh_page_trylock_get_result(page, &page_trylock_result);
 		unlock_page(page);
 keep:
 		list_add(&page->lru, &ret_pages);
diff --git a/kernel/net/802/mrp.c b/kernel/net/802/mrp.c
index 35e04cc..c10a432 100644
--- a/kernel/net/802/mrp.c
+++ b/kernel/net/802/mrp.c
@@ -606,7 +606,10 @@
 	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 @@
 	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 @@
 	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 @@
 
 	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.
 	 */
diff --git a/kernel/net/8021q/vlan_dev.c b/kernel/net/8021q/vlan_dev.c
index 86a1c99..8edac93 100644
--- a/kernel/net/8021q/vlan_dev.c
+++ b/kernel/net/8021q/vlan_dev.c
@@ -108,8 +108,8 @@
 	 * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING
 	 * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs...
 	 */
-	if (veth->h_vlan_proto != vlan->vlan_proto ||
-	    vlan->flags & VLAN_FLAG_REORDER_HDR) {
+	if (vlan->flags & VLAN_FLAG_REORDER_HDR ||
+	    veth->h_vlan_proto != vlan->vlan_proto) {
 		u16 vlan_tci;
 		vlan_tci = vlan->vlan_id;
 		vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb->priority);
@@ -365,7 +365,7 @@
 
 	switch (cmd) {
 	case SIOCSHWTSTAMP:
-		if (!net_eq(dev_net(dev), &init_net))
+		if (!net_eq(dev_net(dev), dev_net(real_dev)))
 			break;
 		fallthrough;
 	case SIOCGMIIPHY:
diff --git a/kernel/net/9p/trans_rdma.c b/kernel/net/9p/trans_rdma.c
index 2885ff9..7217bd9 100644
--- a/kernel/net/9p/trans_rdma.c
+++ b/kernel/net/9p/trans_rdma.c
@@ -386,6 +386,7 @@
 	struct p9_trans_rdma *rdma = client->trans;
 	struct ib_recv_wr wr;
 	struct ib_sge sge;
+	int ret;
 
 	c->busa = ib_dma_map_single(rdma->cm_id->device,
 				    c->rc.sdata, client->msize,
@@ -403,7 +404,12 @@
 	wr.wr_cqe = &c->cqe;
 	wr.sg_list = &sge;
 	wr.num_sge = 1;
-	return ib_post_recv(rdma->qp, &wr, NULL);
+
+	ret = ib_post_recv(rdma->qp, &wr, NULL);
+	if (ret)
+		ib_dma_unmap_single(rdma->cm_id->device, c->busa,
+				    client->msize, DMA_FROM_DEVICE);
+	return ret;
 
  error:
 	p9_debug(P9_DEBUG_ERROR, "EIO\n");
@@ -500,7 +506,7 @@
 
 	if (down_interruptible(&rdma->sq_sem)) {
 		err = -EINTR;
-		goto send_error;
+		goto dma_unmap;
 	}
 
 	/* Mark request as `sent' *before* we actually send it,
@@ -510,11 +516,14 @@
 	req->status = REQ_STATUS_SENT;
 	err = ib_post_send(rdma->qp, &wr, NULL);
 	if (err)
-		goto send_error;
+		goto dma_unmap;
 
 	/* Success */
 	return 0;
 
+dma_unmap:
+	ib_dma_unmap_single(rdma->cm_id->device, c->busa,
+			    c->req->tc.size, DMA_TO_DEVICE);
  /* Handle errors that happened during or while preparing the send: */
  send_error:
 	req->status = REQ_STATUS_ERROR;
diff --git a/kernel/net/9p/trans_virtio.c b/kernel/net/9p/trans_virtio.c
index f582351..36b5f72 100644
--- a/kernel/net/9p/trans_virtio.c
+++ b/kernel/net/9p/trans_virtio.c
@@ -394,7 +394,7 @@
 	struct page **in_pages = NULL, **out_pages = NULL;
 	struct virtio_chan *chan = client->trans;
 	struct scatterlist *sgs[4];
-	size_t offs;
+	size_t offs = 0;
 	int need_drop = 0;
 	int kicked = 0;
 
diff --git a/kernel/net/9p/trans_xen.c b/kernel/net/9p/trans_xen.c
index 6c8a33f..da05617 100644
--- a/kernel/net/9p/trans_xen.c
+++ b/kernel/net/9p/trans_xen.c
@@ -300,6 +300,10 @@
 	write_unlock(&xen_9pfs_lock);
 
 	for (i = 0; i < priv->num_rings; i++) {
+		struct xen_9pfs_dataring *ring = &priv->rings[i];
+
+		cancel_work_sync(&ring->work);
+
 		if (!priv->rings[i].intf)
 			break;
 		if (priv->rings[i].irq > 0)
@@ -393,19 +397,24 @@
 	return ret;
 }
 
-static int xen_9pfs_front_probe(struct xenbus_device *dev,
-				const struct xenbus_device_id *id)
+static int xen_9pfs_front_init(struct xenbus_device *dev)
 {
 	int ret, i;
 	struct xenbus_transaction xbt;
-	struct xen_9pfs_front_priv *priv = NULL;
-	char *versions;
+	struct xen_9pfs_front_priv *priv = dev_get_drvdata(&dev->dev);
+	char *versions, *v;
 	unsigned int max_rings, max_ring_order, len = 0;
 
 	versions = xenbus_read(XBT_NIL, dev->otherend, "versions", &len);
 	if (IS_ERR(versions))
 		return PTR_ERR(versions);
-	if (strcmp(versions, "1")) {
+	for (v = versions; *v; v++) {
+		if (simple_strtoul(v, &v, 10) == 1) {
+			v = NULL;
+			break;
+		}
+	}
+	if (v) {
 		kfree(versions);
 		return -EINVAL;
 	}
@@ -420,11 +429,6 @@
 	if (p9_xen_trans.maxsize > XEN_FLEX_RING_SIZE(max_ring_order))
 		p9_xen_trans.maxsize = XEN_FLEX_RING_SIZE(max_ring_order) / 2;
 
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
-	priv->dev = dev;
 	priv->num_rings = XEN_9PFS_NUM_RINGS;
 	priv->rings = kcalloc(priv->num_rings, sizeof(*priv->rings),
 			      GFP_KERNEL);
@@ -483,21 +487,33 @@
 		goto error;
 	}
 
-	write_lock(&xen_9pfs_lock);
-	list_add_tail(&priv->list, &xen_9pfs_devs);
-	write_unlock(&xen_9pfs_lock);
-	dev_set_drvdata(&dev->dev, priv);
-	xenbus_switch_state(dev, XenbusStateInitialised);
-
 	return 0;
 
  error_xenbus:
 	xenbus_transaction_end(xbt, 1);
 	xenbus_dev_fatal(dev, ret, "writing xenstore");
  error:
-	dev_set_drvdata(&dev->dev, NULL);
 	xen_9pfs_front_free(priv);
 	return ret;
+}
+
+static int xen_9pfs_front_probe(struct xenbus_device *dev,
+				const struct xenbus_device_id *id)
+{
+	struct xen_9pfs_front_priv *priv = NULL;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = dev;
+	dev_set_drvdata(&dev->dev, priv);
+
+	write_lock(&xen_9pfs_lock);
+	list_add_tail(&priv->list, &xen_9pfs_devs);
+	write_unlock(&xen_9pfs_lock);
+
+	return 0;
 }
 
 static int xen_9pfs_front_resume(struct xenbus_device *dev)
@@ -518,6 +534,8 @@
 		break;
 
 	case XenbusStateInitWait:
+		if (!xen_9pfs_front_init(dev))
+			xenbus_switch_state(dev, XenbusStateInitialised);
 		break;
 
 	case XenbusStateConnected:
diff --git a/kernel/net/Kconfig b/kernel/net/Kconfig
index d656716..a22c3fb 100644
--- a/kernel/net/Kconfig
+++ b/kernel/net/Kconfig
@@ -204,7 +204,6 @@
 source "net/netfilter/Kconfig"
 source "net/ipv4/netfilter/Kconfig"
 source "net/ipv6/netfilter/Kconfig"
-source "net/decnet/netfilter/Kconfig"
 source "net/bridge/netfilter/Kconfig"
 
 endif
@@ -221,7 +220,6 @@
 source "net/bridge/Kconfig"
 source "net/dsa/Kconfig"
 source "net/8021q/Kconfig"
-source "net/decnet/Kconfig"
 source "net/llc/Kconfig"
 source "drivers/net/appletalk/Kconfig"
 source "net/x25/Kconfig"
diff --git a/kernel/net/Makefile b/kernel/net/Makefile
index 5744bf1..45c03aa 100644
--- a/kernel/net/Makefile
+++ b/kernel/net/Makefile
@@ -39,7 +39,6 @@
 obj-$(CONFIG_STREAM_PARSER)	+= strparser/
 obj-$(CONFIG_ATM)		+= atm/
 obj-$(CONFIG_L2TP)		+= l2tp/
-obj-$(CONFIG_DECNET)		+= decnet/
 obj-$(CONFIG_PHONET)		+= phonet/
 ifneq ($(CONFIG_VLAN_8021Q),)
 obj-y				+= 8021q/
diff --git a/kernel/net/atm/resources.c b/kernel/net/atm/resources.c
index 5323698..3ad39ae 100644
--- a/kernel/net/atm/resources.c
+++ b/kernel/net/atm/resources.c
@@ -403,6 +403,7 @@
 	return error;
 }
 
+#ifdef CONFIG_PROC_FS
 void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos)
 {
 	mutex_lock(&atm_dev_mutex);
@@ -418,3 +419,4 @@
 {
 	return seq_list_next(v, &atm_devs, pos);
 }
+#endif
diff --git a/kernel/net/batman-adv/bat_v_elp.c b/kernel/net/batman-adv/bat_v_elp.c
index 79a7dfc..83586f1 100644
--- a/kernel/net/batman-adv/bat_v_elp.c
+++ b/kernel/net/batman-adv/bat_v_elp.c
@@ -509,7 +509,7 @@
 	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
 	struct batadv_elp_packet *elp_packet;
 	struct batadv_hard_iface *primary_if;
-	struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
+	struct ethhdr *ethhdr;
 	bool res;
 	int ret = NET_RX_DROP;
 
@@ -517,6 +517,7 @@
 	if (!res)
 		goto free_skb;
 
+	ethhdr = eth_hdr(skb);
 	if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
 		goto free_skb;
 
diff --git a/kernel/net/batman-adv/bat_v_ogm.c b/kernel/net/batman-adv/bat_v_ogm.c
index 8c1148f..c451694 100644
--- a/kernel/net/batman-adv/bat_v_ogm.c
+++ b/kernel/net/batman-adv/bat_v_ogm.c
@@ -123,8 +123,10 @@
 {
 	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
 
-	if (hard_iface->if_status != BATADV_IF_ACTIVE)
+	if (hard_iface->if_status != BATADV_IF_ACTIVE) {
+		kfree_skb(skb);
 		return;
+	}
 
 	batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_TX);
 	batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES,
@@ -998,7 +1000,7 @@
 {
 	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
 	struct batadv_ogm2_packet *ogm_packet;
-	struct ethhdr *ethhdr = eth_hdr(skb);
+	struct ethhdr *ethhdr;
 	int ogm_offset;
 	u8 *packet_pos;
 	int ret = NET_RX_DROP;
@@ -1012,6 +1014,7 @@
 	if (!batadv_check_management_packet(skb, if_incoming, BATADV_OGM2_HLEN))
 		goto free_skb;
 
+	ethhdr = eth_hdr(skb);
 	if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
 		goto free_skb;
 
diff --git a/kernel/net/batman-adv/distributed-arp-table.c b/kernel/net/batman-adv/distributed-arp-table.c
index 338e4e9..ddd3b4c 100644
--- a/kernel/net/batman-adv/distributed-arp-table.c
+++ b/kernel/net/batman-adv/distributed-arp-table.c
@@ -102,7 +102,6 @@
  */
 static void batadv_dat_start_timer(struct batadv_priv *bat_priv)
 {
-	INIT_DELAYED_WORK(&bat_priv->dat.work, batadv_dat_purge);
 	queue_delayed_work(batadv_event_workqueue, &bat_priv->dat.work,
 			   msecs_to_jiffies(10000));
 }
@@ -822,6 +821,7 @@
 	if (!bat_priv->dat.hash)
 		return -ENOMEM;
 
+	INIT_DELAYED_WORK(&bat_priv->dat.work, batadv_dat_purge);
 	batadv_dat_start_timer(bat_priv);
 
 	batadv_tvlv_handler_register(bat_priv, batadv_dat_tvlv_ogm_handler_v1,
diff --git a/kernel/net/batman-adv/gateway_common.c b/kernel/net/batman-adv/gateway_common.c
index 16cd945..d65ff10 100644
--- a/kernel/net/batman-adv/gateway_common.c
+++ b/kernel/net/batman-adv/gateway_common.c
@@ -10,7 +10,7 @@
 #include <linux/atomic.h>
 #include <linux/byteorder/generic.h>
 #include <linux/errno.h>
-#include <linux/kernel.h>
+#include <linux/kstrtox.h>
 #include <linux/limits.h>
 #include <linux/math64.h>
 #include <linux/netdevice.h>
diff --git a/kernel/net/batman-adv/hard-interface.c b/kernel/net/batman-adv/hard-interface.c
index fe0898a..fe79bfc 100644
--- a/kernel/net/batman-adv/hard-interface.c
+++ b/kernel/net/batman-adv/hard-interface.c
@@ -632,7 +632,19 @@
  */
 void batadv_update_min_mtu(struct net_device *soft_iface)
 {
-	soft_iface->mtu = batadv_hardif_min_mtu(soft_iface);
+	struct batadv_priv *bat_priv = netdev_priv(soft_iface);
+	int limit_mtu;
+	int mtu;
+
+	mtu = batadv_hardif_min_mtu(soft_iface);
+
+	if (bat_priv->mtu_set_by_user)
+		limit_mtu = bat_priv->mtu_set_by_user;
+	else
+		limit_mtu = ETH_DATA_LEN;
+
+	mtu = min(mtu, limit_mtu);
+	dev_set_mtu(soft_iface, mtu);
 
 	/* Check if the local translate table should be cleaned up to match a
 	 * new (and smaller) MTU.
diff --git a/kernel/net/batman-adv/netlink.c b/kernel/net/batman-adv/netlink.c
index 1214597..931bc3b 100644
--- a/kernel/net/batman-adv/netlink.c
+++ b/kernel/net/batman-adv/netlink.c
@@ -496,7 +496,10 @@
 		attr = info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED];
 
 		atomic_set(&bat_priv->fragmentation, !!nla_get_u8(attr));
+
+		rtnl_lock();
 		batadv_update_min_mtu(bat_priv->soft_iface);
+		rtnl_unlock();
 	}
 
 	if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN]) {
diff --git a/kernel/net/batman-adv/soft-interface.c b/kernel/net/batman-adv/soft-interface.c
index 8f7c778..7ac16d7 100644
--- a/kernel/net/batman-adv/soft-interface.c
+++ b/kernel/net/batman-adv/soft-interface.c
@@ -156,11 +156,14 @@
 
 static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu)
 {
+	struct batadv_priv *bat_priv = netdev_priv(dev);
+
 	/* check ranges */
 	if (new_mtu < 68 || new_mtu > batadv_hardif_min_mtu(dev))
 		return -EINVAL;
 
 	dev->mtu = new_mtu;
+	bat_priv->mtu_set_by_user = new_mtu;
 
 	return 0;
 }
diff --git a/kernel/net/batman-adv/translation-table.c b/kernel/net/batman-adv/translation-table.c
index 5f990a2..9e8ebac 100644
--- a/kernel/net/batman-adv/translation-table.c
+++ b/kernel/net/batman-adv/translation-table.c
@@ -775,7 +775,6 @@
 		if (roamed_back) {
 			batadv_tt_global_free(bat_priv, tt_global,
 					      "Roaming canceled");
-			tt_global = NULL;
 		} else {
 			/* The global entry has to be marked as ROAMING and
 			 * has to be kept for consistency purpose
diff --git a/kernel/net/batman-adv/types.h b/kernel/net/batman-adv/types.h
index 965336a..7d47fe7 100644
--- a/kernel/net/batman-adv/types.h
+++ b/kernel/net/batman-adv/types.h
@@ -1567,6 +1567,12 @@
 	struct net_device *soft_iface;
 
 	/**
+	 * @mtu_set_by_user: MTU was set once by user
+	 * protected by rtnl_lock
+	 */
+	int mtu_set_by_user;
+
+	/**
 	 * @bat_counters: mesh internal traffic statistic counters (see
 	 *  batadv_counters)
 	 */
diff --git a/kernel/net/bluetooth/hci_core.c b/kernel/net/bluetooth/hci_core.c
index 42ba505..8ffcb56 100644
--- a/kernel/net/bluetooth/hci_core.c
+++ b/kernel/net/bluetooth/hci_core.c
@@ -1623,6 +1623,7 @@
 			hdev->flush(hdev);
 
 		if (hdev->sent_cmd) {
+			cancel_delayed_work_sync(&hdev->cmd_timer);
 			kfree_skb(hdev->sent_cmd);
 			hdev->sent_cmd = NULL;
 		}
@@ -2342,9 +2343,9 @@
 
 void hci_link_keys_clear(struct hci_dev *hdev)
 {
-	struct link_key *key;
+	struct link_key *key, *tmp;
 
-	list_for_each_entry(key, &hdev->link_keys, list) {
+	list_for_each_entry_safe(key, tmp, &hdev->link_keys, list) {
 		list_del_rcu(&key->list);
 		kfree_rcu(key, rcu);
 	}
@@ -2352,9 +2353,9 @@
 
 void hci_smp_ltks_clear(struct hci_dev *hdev)
 {
-	struct smp_ltk *k;
+	struct smp_ltk *k, *tmp;
 
-	list_for_each_entry(k, &hdev->long_term_keys, list) {
+	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
 		list_del_rcu(&k->list);
 		kfree_rcu(k, rcu);
 	}
@@ -2362,9 +2363,9 @@
 
 void hci_smp_irks_clear(struct hci_dev *hdev)
 {
-	struct smp_irk *k;
+	struct smp_irk *k, *tmp;
 
-	list_for_each_entry(k, &hdev->identity_resolving_keys, list) {
+	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
 		list_del_rcu(&k->list);
 		kfree_rcu(k, rcu);
 	}
@@ -2372,9 +2373,9 @@
 
 void hci_blocked_keys_clear(struct hci_dev *hdev)
 {
-	struct blocked_key *b;
+	struct blocked_key *b, *tmp;
 
-	list_for_each_entry(b, &hdev->blocked_keys, list) {
+	list_for_each_entry_safe(b, tmp, &hdev->blocked_keys, list) {
 		list_del_rcu(&b->list);
 		kfree_rcu(b, rcu);
 	}
@@ -2684,10 +2685,10 @@
 
 int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
 {
-	struct smp_ltk *k;
+	struct smp_ltk *k, *tmp;
 	int removed = 0;
 
-	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
+	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
 			continue;
 
@@ -2703,9 +2704,9 @@
 
 void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
 {
-	struct smp_irk *k;
+	struct smp_irk *k, *tmp;
 
-	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
+	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
 			continue;
 
@@ -4907,7 +4908,7 @@
 			*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);
 }
diff --git a/kernel/net/bluetooth/hci_event.c b/kernel/net/bluetooth/hci_event.c
index 061ef20..c53fb40 100644
--- a/kernel/net/bluetooth/hci_event.c
+++ b/kernel/net/bluetooth/hci_event.c
@@ -4304,6 +4304,19 @@
 	struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
 	struct hci_conn *conn;
 
+	switch (ev->link_type) {
+	case SCO_LINK:
+	case ESCO_LINK:
+		break;
+	default:
+		/* As per Core 5.3 Vol 4 Part E 7.7.35 (p.2219), Link_Type
+		 * for HCI_Synchronous_Connection_Complete is limited to
+		 * either SCO or eSCO
+		 */
+		bt_dev_err(hdev, "Ignoring connect complete event for invalid link type");
+		return;
+	}
+
 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
 
 	hci_dev_lock(hdev);
diff --git a/kernel/net/bluetooth/hci_sock.c b/kernel/net/bluetooth/hci_sock.c
index 53f85d7..1d00318 100644
--- a/kernel/net/bluetooth/hci_sock.c
+++ b/kernel/net/bluetooth/hci_sock.c
@@ -888,10 +888,6 @@
 	}
 
 	sock_orphan(sk);
-
-	skb_queue_purge(&sk->sk_receive_queue);
-	skb_queue_purge(&sk->sk_write_queue);
-
 	release_sock(sk);
 	sock_put(sk);
 	return 0;
@@ -984,6 +980,34 @@
 
 	BT_DBG("cmd %x arg %lx", cmd, arg);
 
+	/* Make sure the cmd is valid before doing anything */
+	switch (cmd) {
+	case HCIGETDEVLIST:
+	case HCIGETDEVINFO:
+	case HCIGETCONNLIST:
+	case HCIDEVUP:
+	case HCIDEVDOWN:
+	case HCIDEVRESET:
+	case HCIDEVRESTAT:
+	case HCISETSCAN:
+	case HCISETAUTH:
+	case HCISETENCRYPT:
+	case HCISETPTYPE:
+	case HCISETLINKPOL:
+	case HCISETLINKMODE:
+	case HCISETACLMTU:
+	case HCISETSCOMTU:
+	case HCIINQUIRY:
+	case HCISETRAW:
+	case HCIGETCONNINFO:
+	case HCIGETAUTHINFO:
+	case HCIBLOCKADDR:
+	case HCIUNBLOCKADDR:
+		break;
+	default:
+		return -ENOIOCTLCMD;
+	}
+
 	lock_sock(sk);
 
 	if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
@@ -1000,7 +1024,14 @@
 	if (hci_sock_gen_cookie(sk)) {
 		struct sk_buff *skb;
 
-		if (capable(CAP_NET_ADMIN))
+		/* Perform careful checks before setting the HCI_SOCK_TRUSTED
+		 * flag. Make sure that not only the current task but also
+		 * the socket opener has the required capability, since
+		 * privileged programs can be tricked into making ioctl calls
+		 * on HCI sockets, and the socket should not be marked as
+		 * trusted simply because the ioctl caller is privileged.
+		 */
+		if (sk_capable(sk, CAP_NET_ADMIN))
 			hci_sock_set_flag(sk, HCI_SOCK_TRUSTED);
 
 		/* Send event to monitor */
@@ -2012,6 +2043,12 @@
 	return err;
 }
 
+static void hci_sock_destruct(struct sock *sk)
+{
+	skb_queue_purge(&sk->sk_receive_queue);
+	skb_queue_purge(&sk->sk_write_queue);
+}
+
 static const struct proto_ops hci_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,
@@ -2065,6 +2102,7 @@
 
 	sock->state = SS_UNCONNECTED;
 	sk->sk_state = BT_OPEN;
+	sk->sk_destruct = hci_sock_destruct;
 
 	bt_sock_link(&hci_sk_list, sk);
 	return 0;
diff --git a/kernel/net/bluetooth/hidp/core.c b/kernel/net/bluetooth/hidp/core.c
index 0db48c8..b946a63 100644
--- a/kernel/net/bluetooth/hidp/core.c
+++ b/kernel/net/bluetooth/hidp/core.c
@@ -433,7 +433,7 @@
 static void hidp_del_timer(struct hidp_session *session)
 {
 	if (session->idle_to > 0)
-		del_timer(&session->timer);
+		del_timer_sync(&session->timer);
 }
 
 static void hidp_process_report(struct hidp_session *session, int type,
diff --git a/kernel/net/bluetooth/l2cap_core.c b/kernel/net/bluetooth/l2cap_core.c
index e851f80..9cde366 100644
--- a/kernel/net/bluetooth/l2cap_core.c
+++ b/kernel/net/bluetooth/l2cap_core.c
@@ -710,6 +710,17 @@
 }
 EXPORT_SYMBOL_GPL(l2cap_chan_del);
 
+static void __l2cap_chan_list_id(struct l2cap_conn *conn, u16 id,
+				 l2cap_chan_func_t func, void *data)
+{
+	struct l2cap_chan *chan, *l;
+
+	list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
+		if (chan->ident == id)
+			func(chan, data);
+	}
+}
+
 static void __l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func,
 			      void *data)
 {
@@ -777,23 +788,9 @@
 
 static void l2cap_chan_ecred_connect_reject(struct l2cap_chan *chan)
 {
-	struct l2cap_conn *conn = chan->conn;
-	struct l2cap_ecred_conn_rsp rsp;
-	u16 result;
-
-	if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
-		result = L2CAP_CR_LE_AUTHORIZATION;
-	else
-		result = L2CAP_CR_LE_BAD_PSM;
-
 	l2cap_state_change(chan, BT_DISCONN);
 
-	memset(&rsp, 0, sizeof(rsp));
-
-	rsp.result  = cpu_to_le16(result);
-
-	l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
-		       &rsp);
+	__l2cap_ecred_conn_rsp_defer(chan);
 }
 
 static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
@@ -848,7 +845,7 @@
 					break;
 				case L2CAP_MODE_EXT_FLOWCTL:
 					l2cap_chan_ecred_connect_reject(chan);
-					break;
+					return;
 				}
 			}
 		}
@@ -2679,14 +2676,6 @@
 		if (IS_ERR(skb))
 			return PTR_ERR(skb);
 
-		/* Channel lock is released before requesting new skb and then
-		 * reacquired thus we need to recheck channel state.
-		 */
-		if (chan->state != BT_CONNECTED) {
-			kfree_skb(skb);
-			return -ENOTCONN;
-		}
-
 		l2cap_do_send(chan, skb);
 		return len;
 	}
@@ -2731,14 +2720,6 @@
 		if (IS_ERR(skb))
 			return PTR_ERR(skb);
 
-		/* Channel lock is released before requesting new skb and then
-		 * reacquired thus we need to recheck channel state.
-		 */
-		if (chan->state != BT_CONNECTED) {
-			kfree_skb(skb);
-			return -ENOTCONN;
-		}
-
 		l2cap_do_send(chan, skb);
 		err = len;
 		break;
@@ -2758,14 +2739,6 @@
 		 * allocation.
 		 */
 		err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
-
-		/* The channel could have been closed while segmenting,
-		 * check that it is still connected.
-		 */
-		if (chan->state != BT_CONNECTED) {
-			__skb_queue_purge(&seg_queue);
-			err = -ENOTCONN;
-		}
 
 		if (err)
 			break;
@@ -3958,43 +3931,86 @@
 		       &rsp);
 }
 
-void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan)
+static void l2cap_ecred_list_defer(struct l2cap_chan *chan, void *data)
 {
-	struct {
-		struct l2cap_ecred_conn_rsp rsp;
-		__le16 dcid[5];
-	} __packed pdu;
-	struct l2cap_conn *conn = chan->conn;
-	u16 ident = chan->ident;
-	int i = 0;
+	int *result = data;
 
-	if (!ident)
+	if (*result || test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
 		return;
 
-	BT_DBG("chan %p ident %d", chan, ident);
-
-	pdu.rsp.mtu     = cpu_to_le16(chan->imtu);
-	pdu.rsp.mps     = cpu_to_le16(chan->mps);
-	pdu.rsp.credits = cpu_to_le16(chan->rx_credits);
-	pdu.rsp.result  = cpu_to_le16(L2CAP_CR_LE_SUCCESS);
-
-	mutex_lock(&conn->chan_lock);
-
-	list_for_each_entry(chan, &conn->chan_l, list) {
-		if (chan->ident != ident)
-			continue;
-
-		/* Reset ident so only one response is sent */
-		chan->ident = 0;
-
-		/* Include all channels pending with the same ident */
-		pdu.dcid[i++] = cpu_to_le16(chan->scid);
+	switch (chan->state) {
+	case BT_CONNECT2:
+		/* If channel still pending accept add to result */
+		(*result)++;
+		return;
+	case BT_CONNECTED:
+		return;
+	default:
+		/* If not connected or pending accept it has been refused */
+		*result = -ECONNREFUSED;
+		return;
 	}
+}
 
-	mutex_unlock(&conn->chan_lock);
+struct l2cap_ecred_rsp_data {
+	struct {
+		struct l2cap_ecred_conn_rsp rsp;
+		__le16 scid[L2CAP_ECRED_MAX_CID];
+	} __packed pdu;
+	int count;
+};
 
-	l2cap_send_cmd(conn, ident, L2CAP_ECRED_CONN_RSP,
-			sizeof(pdu.rsp) + i * sizeof(__le16), &pdu);
+static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data)
+{
+	struct l2cap_ecred_rsp_data *rsp = data;
+
+	if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
+		return;
+
+	/* Reset ident so only one response is sent */
+	chan->ident = 0;
+
+	/* Include all channels pending with the same ident */
+	if (!rsp->pdu.rsp.result)
+		rsp->pdu.rsp.dcid[rsp->count++] = cpu_to_le16(chan->scid);
+	else
+		l2cap_chan_del(chan, ECONNRESET);
+}
+
+void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan)
+{
+	struct l2cap_conn *conn = chan->conn;
+	struct l2cap_ecred_rsp_data data;
+	u16 id = chan->ident;
+	int result = 0;
+
+	if (!id)
+		return;
+
+	BT_DBG("chan %p id %d", chan, id);
+
+	memset(&data, 0, sizeof(data));
+
+	data.pdu.rsp.mtu     = cpu_to_le16(chan->imtu);
+	data.pdu.rsp.mps     = cpu_to_le16(chan->mps);
+	data.pdu.rsp.credits = cpu_to_le16(chan->rx_credits);
+	data.pdu.rsp.result  = cpu_to_le16(L2CAP_CR_LE_SUCCESS);
+
+	/* Verify that all channels are ready */
+	__l2cap_chan_list_id(conn, id, l2cap_ecred_list_defer, &result);
+
+	if (result > 0)
+		return;
+
+	if (result < 0)
+		data.pdu.rsp.result = cpu_to_le16(L2CAP_CR_LE_AUTHORIZATION);
+
+	/* Build response */
+	__l2cap_chan_list_id(conn, id, l2cap_ecred_rsp_defer, &data);
+
+	l2cap_send_cmd(conn, id, L2CAP_ECRED_CONN_RSP,
+		       sizeof(data.pdu.rsp) + (data.count * sizeof(__le16)),
+		       &data.pdu);
 }
 
 void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
@@ -4287,6 +4303,10 @@
 	result = __le16_to_cpu(rsp->result);
 	status = __le16_to_cpu(rsp->status);
 
+	if (result == L2CAP_CR_SUCCESS && (dcid < L2CAP_CID_DYN_START ||
+					   dcid > L2CAP_CID_DYN_END))
+		return -EPROTO;
+
 	BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
 	       dcid, scid, result, status);
 
@@ -4318,6 +4338,11 @@
 
 	switch (result) {
 	case L2CAP_CR_SUCCESS:
+		if (__l2cap_get_chan_by_dcid(conn, dcid)) {
+			err = -EBADSLT;
+			break;
+		}
+
 		l2cap_state_change(chan, BT_CONFIG);
 		chan->ident = 0;
 		chan->dcid = dcid;
@@ -4631,17 +4656,11 @@
 
 	BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
 
-	mutex_lock(&conn->chan_lock);
-
-	chan = __l2cap_get_chan_by_scid(conn, dcid);
+	chan = l2cap_get_chan_by_scid(conn, dcid);
 	if (!chan) {
-		mutex_unlock(&conn->chan_lock);
 		cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
 		return 0;
 	}
-
-	l2cap_chan_hold(chan);
-	l2cap_chan_lock(chan);
 
 	rsp.dcid = cpu_to_le16(chan->scid);
 	rsp.scid = cpu_to_le16(chan->dcid);
@@ -4649,14 +4668,16 @@
 
 	chan->ops->set_shutdown(chan);
 
+	l2cap_chan_unlock(chan);
+	mutex_lock(&conn->chan_lock);
+	l2cap_chan_lock(chan);
 	l2cap_chan_del(chan, ECONNRESET);
+	mutex_unlock(&conn->chan_lock);
 
 	chan->ops->close(chan);
 
 	l2cap_chan_unlock(chan);
 	l2cap_chan_put(chan);
-
-	mutex_unlock(&conn->chan_lock);
 
 	return 0;
 }
@@ -4677,32 +4698,27 @@
 
 	BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
 
-	mutex_lock(&conn->chan_lock);
-
-	chan = __l2cap_get_chan_by_scid(conn, scid);
+	chan = l2cap_get_chan_by_scid(conn, scid);
 	if (!chan) {
-		mutex_unlock(&conn->chan_lock);
 		return 0;
 	}
-
-	l2cap_chan_hold(chan);
-	l2cap_chan_lock(chan);
 
 	if (chan->state != BT_DISCONN) {
 		l2cap_chan_unlock(chan);
 		l2cap_chan_put(chan);
-		mutex_unlock(&conn->chan_lock);
 		return 0;
 	}
 
+	l2cap_chan_unlock(chan);
+	mutex_lock(&conn->chan_lock);
+	l2cap_chan_lock(chan);
 	l2cap_chan_del(chan, 0);
+	mutex_unlock(&conn->chan_lock);
 
 	chan->ops->close(chan);
 
 	l2cap_chan_unlock(chan);
 	l2cap_chan_put(chan);
-
-	mutex_unlock(&conn->chan_lock);
 
 	return 0;
 }
@@ -5976,7 +5992,7 @@
 	struct l2cap_ecred_conn_req *req = (void *) data;
 	struct {
 		struct l2cap_ecred_conn_rsp rsp;
-		__le16 dcid[5];
+		__le16 dcid[L2CAP_ECRED_MAX_CID];
 	} __packed pdu;
 	struct l2cap_chan *chan, *pchan;
 	u16 mtu, mps;
@@ -5989,6 +6005,14 @@
 		return -EINVAL;
 
 	if (cmd_len < sizeof(*req) || (cmd_len - sizeof(*req)) % sizeof(u16)) {
+		result = L2CAP_CR_LE_INVALID_PARAMS;
+		goto response;
+	}
+
+	cmd_len -= sizeof(*req);
+	num_scid = cmd_len / sizeof(u16);
+
+	if (num_scid > ARRAY_SIZE(pdu.dcid)) {
 		result = L2CAP_CR_LE_INVALID_PARAMS;
 		goto response;
 	}
@@ -6037,8 +6061,6 @@
 	}
 
 	result = L2CAP_CR_LE_SUCCESS;
-	cmd_len -= sizeof(*req);
-	num_scid = cmd_len / sizeof(u16);
 
 	for (i = 0; i < num_scid; i++) {
 		u16 scid = __le16_to_cpu(req->scid[i]);
@@ -6091,6 +6113,7 @@
 		__set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
 
 		chan->ident = cmd->ident;
+		chan->mode = L2CAP_MODE_EXT_FLOWCTL;
 
 		if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
 			l2cap_state_change(chan, BT_CONNECT2);
@@ -6347,9 +6370,14 @@
 	if (!chan)
 		goto done;
 
+	chan = l2cap_chan_hold_unless_zero(chan);
+	if (!chan)
+		goto done;
+
 	l2cap_chan_lock(chan);
 	l2cap_chan_del(chan, ECONNREFUSED);
 	l2cap_chan_unlock(chan);
+	l2cap_chan_put(chan);
 
 done:
 	mutex_unlock(&conn->chan_lock);
diff --git a/kernel/net/bluetooth/l2cap_sock.c b/kernel/net/bluetooth/l2cap_sock.c
index d2c6785..756523e 100644
--- a/kernel/net/bluetooth/l2cap_sock.c
+++ b/kernel/net/bluetooth/l2cap_sock.c
@@ -45,6 +45,7 @@
 static void l2cap_sock_init(struct sock *sk, struct sock *parent);
 static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
 				     int proto, gfp_t prio, int kern);
+static void l2cap_sock_cleanup_listen(struct sock *parent);
 
 bool l2cap_is_socket(struct socket *sock)
 {
@@ -1414,6 +1415,7 @@
 	if (!sk)
 		return 0;
 
+	l2cap_sock_cleanup_listen(sk);
 	bt_sock_unlink(&l2cap_sk_list, sk);
 
 	err = l2cap_sock_shutdown(sock, SHUT_RDWR);
@@ -1623,6 +1625,14 @@
 	if (!skb)
 		return ERR_PTR(err);
 
+	/* Channel lock is released before requesting new skb and then
+	 * reacquired thus we need to recheck channel state.
+	 */
+	if (chan->state != BT_CONNECTED) {
+		kfree_skb(skb);
+		return ERR_PTR(-ENOTCONN);
+	}
+
 	skb->priority = sk->sk_priority;
 
 	bt_cb(skb)->l2cap.chan = chan;
diff --git a/kernel/net/bluetooth/rfcomm/core.c b/kernel/net/bluetooth/rfcomm/core.c
index 7324764..8d6fce9 100644
--- a/kernel/net/bluetooth/rfcomm/core.c
+++ b/kernel/net/bluetooth/rfcomm/core.c
@@ -590,7 +590,7 @@
 
 		ret = rfcomm_dlc_send_frag(d, frag);
 		if (ret < 0) {
-			kfree_skb(frag);
+			dev_kfree_skb_irq(frag);
 			goto unlock;
 		}
 
diff --git a/kernel/net/bpf/test_run.c b/kernel/net/bpf/test_run.c
index 717b01f..7df14a0 100644
--- a/kernel/net/bpf/test_run.c
+++ b/kernel/net/bpf/test_run.c
@@ -442,9 +442,6 @@
 {
 	struct qdisc_skb_cb *cb = (struct qdisc_skb_cb *)skb->cb;
 
-	if (!skb->len)
-		return -EINVAL;
-
 	if (!__skb)
 		return 0;
 
diff --git a/kernel/net/bridge/br_forward.c b/kernel/net/bridge/br_forward.c
index e28ffad..4610f3a 100644
--- a/kernel/net/bridge/br_forward.c
+++ b/kernel/net/bridge/br_forward.c
@@ -43,7 +43,7 @@
 	     skb->protocol == htons(ETH_P_8021AD))) {
 		int depth;
 
-		if (!__vlan_get_protocol(skb, skb->protocol, &depth))
+		if (!vlan_get_protocol_and_depth(skb, skb->protocol, &depth))
 			goto drop;
 
 		skb_set_network_header(skb, depth);
diff --git a/kernel/net/bridge/br_if.c b/kernel/net/bridge/br_if.c
index 1d87bf5..e35488f 100644
--- a/kernel/net/bridge/br_if.c
+++ b/kernel/net/bridge/br_if.c
@@ -157,8 +157,9 @@
 			 * This lets us disable promiscuous mode and write
 			 * this config to hw.
 			 */
-			if (br->auto_cnt == 0 ||
-			    (br->auto_cnt == 1 && br_auto_port(p)))
+			if ((p->dev->priv_flags & IFF_UNICAST_FLT) &&
+			    (br->auto_cnt == 0 ||
+			     (br->auto_cnt == 1 && br_auto_port(p))))
 				br_port_clear_promisc(p);
 			else
 				br_port_set_promisc(p);
diff --git a/kernel/net/bridge/br_netfilter_hooks.c b/kernel/net/bridge/br_netfilter_hooks.c
index a718204..f14beb9 100644
--- a/kernel/net/bridge/br_netfilter_hooks.c
+++ b/kernel/net/bridge/br_netfilter_hooks.c
@@ -868,11 +868,17 @@
 {
 	struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
 
-	if (nf_bridge && !nf_bridge->in_prerouting &&
-	    !netif_is_l3_master(skb->dev) &&
-	    !netif_is_l3_slave(skb->dev)) {
-		state->okfn(state->net, state->sk, skb);
-		return NF_STOLEN;
+	if (nf_bridge) {
+		if (nf_bridge->sabotage_in_done)
+			return NF_ACCEPT;
+
+		if (!nf_bridge->in_prerouting &&
+		    !netif_is_l3_master(skb->dev) &&
+		    !netif_is_l3_slave(skb->dev)) {
+			nf_bridge->sabotage_in_done = 1;
+			state->okfn(state->net, state->sk, skb);
+			return NF_STOLEN;
+		}
 	}
 
 	return NF_ACCEPT;
diff --git a/kernel/net/bridge/br_private_tunnel.h b/kernel/net/bridge/br_private_tunnel.h
index c54cc26..f6c65dc 100644
--- a/kernel/net/bridge/br_private_tunnel.h
+++ b/kernel/net/bridge/br_private_tunnel.h
@@ -27,6 +27,10 @@
 int br_get_vlan_tunnel_info_size(struct net_bridge_vlan_group *vg);
 int br_fill_vlan_tunnel_info(struct sk_buff *skb,
 			     struct net_bridge_vlan_group *vg);
+bool vlan_tunid_inrange(const struct net_bridge_vlan *v_curr,
+			const struct net_bridge_vlan *v_last);
+int br_vlan_tunnel_info(const struct net_bridge_port *p, int cmd,
+			u16 vid, u32 tun_id, bool *changed);
 
 #ifdef CONFIG_BRIDGE_VLAN_FILTERING
 /* br_vlan_tunnel.c */
@@ -43,10 +47,6 @@
 				  struct net_bridge_vlan_group *vg);
 int br_handle_egress_vlan_tunnel(struct sk_buff *skb,
 				 struct net_bridge_vlan *vlan);
-bool vlan_tunid_inrange(const struct net_bridge_vlan *v_curr,
-			const struct net_bridge_vlan *v_last);
-int br_vlan_tunnel_info(const struct net_bridge_port *p, int cmd,
-			u16 vid, u32 tun_id, bool *changed);
 #else
 static inline int vlan_tunnel_init(struct net_bridge_vlan_group *vg)
 {
diff --git a/kernel/net/bridge/br_stp_if.c b/kernel/net/bridge/br_stp_if.c
index ba55851..3326dfc 100644
--- a/kernel/net/bridge/br_stp_if.c
+++ b/kernel/net/bridge/br_stp_if.c
@@ -201,6 +201,9 @@
 {
 	ASSERT_RTNL();
 
+	if (!net_eq(dev_net(br->dev), &init_net))
+		NL_SET_ERR_MSG_MOD(extack, "STP does not work in non-root netns");
+
 	if (br_mrp_enabled(br)) {
 		NL_SET_ERR_MSG_MOD(extack,
 				   "STP can't be enabled if MRP is already enabled");
diff --git a/kernel/net/bridge/netfilter/ebtables.c b/kernel/net/bridge/netfilter/ebtables.c
index 06b80b5..bab1418 100644
--- a/kernel/net/bridge/netfilter/ebtables.c
+++ b/kernel/net/bridge/netfilter/ebtables.c
@@ -1049,7 +1049,7 @@
 
 	audit_log_nfcfg(repl->name, AF_BRIDGE, repl->nentries,
 			AUDIT_XT_OP_REPLACE, GFP_KERNEL);
-	return ret;
+	return 0;
 
 free_unlock:
 	mutex_unlock(&ebt_mutex);
@@ -2001,8 +2001,7 @@
 		return ret;
 
 	offsets[0] = sizeof(struct ebt_entry); /* matches come first */
-	memcpy(&offsets[1], &entry->watchers_offset,
-			sizeof(offsets) - sizeof(offsets[0]));
+	memcpy(&offsets[1], &entry->offsets, sizeof(entry->offsets));
 
 	if (state->buf_kern_start) {
 		buf_start = state->buf_kern_start + state->buf_kern_offset;
diff --git a/kernel/net/caif/caif_socket.c b/kernel/net/caif/caif_socket.c
index 9d26c5e..d35ea92 100644
--- a/kernel/net/caif/caif_socket.c
+++ b/kernel/net/caif/caif_socket.c
@@ -1020,6 +1020,7 @@
 		return;
 	}
 	sk_stream_kill_queues(&cf_sk->sk);
+	WARN_ON(sk->sk_forward_alloc);
 	caif_free_client(&cf_sk->layer);
 }
 
diff --git a/kernel/net/caif/caif_usb.c b/kernel/net/caif/caif_usb.c
index b02e129..24488a4 100644
--- a/kernel/net/caif/caif_usb.c
+++ b/kernel/net/caif/caif_usb.c
@@ -134,6 +134,9 @@
 	struct usb_device *usbdev;
 	int res;
 
+	if (what == NETDEV_UNREGISTER && dev->reg_state >= NETREG_UNREGISTERED)
+		return 0;
+
 	/* Check whether we have a NCM device, and find its VID/PID. */
 	if (!(dev->dev.parent && dev->dev.parent->driver &&
 	      strcmp(dev->dev.parent->driver->name, "cdc_ncm") == 0))
diff --git a/kernel/net/caif/cfctrl.c b/kernel/net/caif/cfctrl.c
index 2809cbd..d8cb4b2 100644
--- a/kernel/net/caif/cfctrl.c
+++ b/kernel/net/caif/cfctrl.c
@@ -269,11 +269,15 @@
 	default:
 		pr_warn("Request setup of bad link type = %d\n",
 			param->linktype);
+		cfpkt_destroy(pkt);
 		return -EINVAL;
 	}
 	req = kzalloc(sizeof(*req), GFP_KERNEL);
-	if (!req)
+	if (!req) {
+		cfpkt_destroy(pkt);
 		return -ENOMEM;
+	}
+
 	req->client_layer = user_layer;
 	req->cmd = CFCTRL_CMD_LINK_SETUP;
 	req->param = *param;
diff --git a/kernel/net/can/bcm.c b/kernel/net/can/bcm.c
index afa82ad..2388c61 100644
--- a/kernel/net/can/bcm.c
+++ b/kernel/net/can/bcm.c
@@ -936,6 +936,8 @@
 
 			cf = op->frames + op->cfsiz * i;
 			err = memcpy_from_msg((u8 *)cf, msg, op->cfsiz);
+			if (err < 0)
+				goto free_op;
 
 			if (op->flags & CAN_FD_FRAME) {
 				if (cf->len > 64)
@@ -945,12 +947,8 @@
 					err = -EINVAL;
 			}
 
-			if (err < 0) {
-				if (op->frames != &op->sframe)
-					kfree(op->frames);
-				kfree(op);
-				return err;
-			}
+			if (err < 0)
+				goto free_op;
 
 			if (msg_head->flags & TX_CP_CAN_ID) {
 				/* copy can_id into frame */
@@ -1021,6 +1019,12 @@
 		bcm_tx_start_timer(op);
 
 	return msg_head->nframes * op->cfsiz + MHSIZ;
+
+free_op:
+	if (op->frames != &op->sframe)
+		kfree(op->frames);
+	kfree(op);
+	return err;
 }
 
 /*
@@ -1517,6 +1521,12 @@
 
 	lock_sock(sk);
 
+#if IS_ENABLED(CONFIG_PROC_FS)
+	/* remove procfs entry */
+	if (net->can.bcmproc_dir && bo->bcm_proc_read)
+		remove_proc_entry(bo->procname, net->can.bcmproc_dir);
+#endif /* CONFIG_PROC_FS */
+
 	list_for_each_entry_safe(op, next, &bo->tx_ops, list)
 		bcm_remove_op(op);
 
@@ -1551,12 +1561,6 @@
 
 	list_for_each_entry_safe(op, next, &bo->rx_ops, list)
 		bcm_remove_op(op);
-
-#if IS_ENABLED(CONFIG_PROC_FS)
-	/* remove procfs entry */
-	if (net->can.bcmproc_dir && bo->bcm_proc_read)
-		remove_proc_entry(bo->procname, net->can.bcmproc_dir);
-#endif /* CONFIG_PROC_FS */
 
 	/* remove device reference */
 	if (bo->bound) {
diff --git a/kernel/net/can/isotp.c b/kernel/net/can/isotp.c
index f2f0bc7..16ebc18 100644
--- a/kernel/net/can/isotp.c
+++ b/kernel/net/can/isotp.c
@@ -990,8 +990,9 @@
 		/* wait for complete transmission of current pdu */
 		wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
 
-		if (sk->sk_err)
-			return -sk->sk_err;
+		err = sock_error(sk);
+		if (err)
+			return err;
 	}
 
 	return size;
@@ -1016,7 +1017,7 @@
 	int noblock = flags & MSG_DONTWAIT;
 	int ret = 0;
 
-	if (flags & ~(MSG_DONTWAIT | MSG_TRUNC | MSG_PEEK))
+	if (flags & ~(MSG_DONTWAIT | MSG_TRUNC | MSG_PEEK | MSG_CMSG_COMPAT))
 		return -EINVAL;
 
 	if (!so->bound)
@@ -1480,6 +1481,21 @@
 	return 0;
 }
 
+static __poll_t isotp_poll(struct file *file, struct socket *sock, poll_table *wait)
+{
+	struct sock *sk = sock->sk;
+	struct isotp_sock *so = isotp_sk(sk);
+
+	__poll_t mask = datagram_poll(file, sock, wait);
+	poll_wait(file, &so->wait, wait);
+
+	/* Check for false positives due to TX state */
+	if ((mask & EPOLLWRNORM) && (so->tx.state != ISOTP_IDLE))
+		mask &= ~(EPOLLOUT | EPOLLWRNORM);
+
+	return mask;
+}
+
 static int isotp_sock_no_ioctlcmd(struct socket *sock, unsigned int cmd,
 				  unsigned long arg)
 {
@@ -1495,7 +1511,7 @@
 	.socketpair = sock_no_socketpair,
 	.accept = sock_no_accept,
 	.getname = isotp_getname,
-	.poll = datagram_poll,
+	.poll = isotp_poll,
 	.ioctl = isotp_sock_no_ioctlcmd,
 	.gettstamp = sock_gettstamp,
 	.listen = sock_no_listen,
diff --git a/kernel/net/can/j1939/address-claim.c b/kernel/net/can/j1939/address-claim.c
index f33c473..ca4ad6c 100644
--- a/kernel/net/can/j1939/address-claim.c
+++ b/kernel/net/can/j1939/address-claim.c
@@ -165,6 +165,46 @@
 	 * leaving this function.
 	 */
 	ecu = j1939_ecu_get_by_name_locked(priv, name);
+
+	if (ecu && ecu->addr == skcb->addr.sa) {
+		/* The ISO 11783-5 standard, in "4.5.2 - Address claim
+		 * requirements", states:
+		 *   d) No CF shall begin, or resume, transmission on the
+		 *      network until 250 ms after it has successfully claimed
+		 *      an address except when responding to a request for
+		 *      address-claimed.
+		 *
+		 * But "Figure 6" and "Figure 7" in "4.5.4.2 - Address-claim
+		 * prioritization" show that the CF begins the transmission
+		 * after 250 ms from the first AC (address-claimed) message
+		 * even if it sends another AC message during that time window
+		 * to resolve the address contention with another CF.
+		 *
+		 * As stated in "4.4.2.3 - Address-claimed message":
+		 *   In order to successfully claim an address, the CF sending
+		 *   an address claimed message shall not receive a contending
+		 *   claim from another CF for at least 250 ms.
+		 *
+		 * As stated in "4.4.3.2 - NAME management (NM) message":
+		 *   1) A commanding CF can
+		 *      d) request that a CF with a specified NAME transmit
+		 *         the address-claimed message with its current NAME.
+		 *   2) A target CF shall
+		 *      d) send an address-claimed message in response to a
+		 *         request for a matching NAME
+		 *
+		 * Taking the above arguments into account, the 250 ms wait is
+		 * requested only during network initialization.
+		 *
+		 * Do not restart the timer on AC message if both the NAME and
+		 * the address match and so if the address has already been
+		 * claimed (timer has expired) or the AC message has been sent
+		 * to resolve the contention with another CF (timer is still
+		 * running).
+		 */
+		goto out_ecu_put;
+	}
+
 	if (!ecu && j1939_address_is_unicast(skcb->addr.sa))
 		ecu = j1939_ecu_create_locked(priv, name);
 
diff --git a/kernel/net/can/j1939/main.c b/kernel/net/can/j1939/main.c
index 9da8fbc..9169ef1 100644
--- a/kernel/net/can/j1939/main.c
+++ b/kernel/net/can/j1939/main.c
@@ -122,7 +122,7 @@
 #define J1939_CAN_ID CAN_EFF_FLAG
 #define J1939_CAN_MASK (CAN_EFF_FLAG | CAN_RTR_FLAG)
 
-static DEFINE_SPINLOCK(j1939_netdev_lock);
+static DEFINE_MUTEX(j1939_netdev_lock);
 
 static struct j1939_priv *j1939_priv_create(struct net_device *ndev)
 {
@@ -216,7 +216,7 @@
 	j1939_can_rx_unregister(priv);
 	j1939_ecu_unmap_all(priv);
 	j1939_priv_set(priv->ndev, NULL);
-	spin_unlock(&j1939_netdev_lock);
+	mutex_unlock(&j1939_netdev_lock);
 }
 
 /* get pointer to priv without increasing ref counter */
@@ -244,9 +244,9 @@
 {
 	struct j1939_priv *priv;
 
-	spin_lock(&j1939_netdev_lock);
+	mutex_lock(&j1939_netdev_lock);
 	priv = j1939_priv_get_by_ndev_locked(ndev);
-	spin_unlock(&j1939_netdev_lock);
+	mutex_unlock(&j1939_netdev_lock);
 
 	return priv;
 }
@@ -256,14 +256,14 @@
 	struct j1939_priv *priv, *priv_new;
 	int ret;
 
-	spin_lock(&j1939_netdev_lock);
+	mutex_lock(&j1939_netdev_lock);
 	priv = j1939_priv_get_by_ndev_locked(ndev);
 	if (priv) {
 		kref_get(&priv->rx_kref);
-		spin_unlock(&j1939_netdev_lock);
+		mutex_unlock(&j1939_netdev_lock);
 		return priv;
 	}
-	spin_unlock(&j1939_netdev_lock);
+	mutex_unlock(&j1939_netdev_lock);
 
 	priv = j1939_priv_create(ndev);
 	if (!priv)
@@ -273,29 +273,31 @@
 	spin_lock_init(&priv->j1939_socks_lock);
 	INIT_LIST_HEAD(&priv->j1939_socks);
 
-	spin_lock(&j1939_netdev_lock);
+	mutex_lock(&j1939_netdev_lock);
 	priv_new = j1939_priv_get_by_ndev_locked(ndev);
 	if (priv_new) {
 		/* Someone was faster than us, use their priv and roll
 		 * back our's.
 		 */
 		kref_get(&priv_new->rx_kref);
-		spin_unlock(&j1939_netdev_lock);
+		mutex_unlock(&j1939_netdev_lock);
 		dev_put(ndev);
 		kfree(priv);
 		return priv_new;
 	}
 	j1939_priv_set(ndev, priv);
-	spin_unlock(&j1939_netdev_lock);
 
 	ret = j1939_can_rx_register(priv);
 	if (ret < 0)
 		goto out_priv_put;
 
+	mutex_unlock(&j1939_netdev_lock);
 	return priv;
 
  out_priv_put:
 	j1939_priv_set(ndev, NULL);
+	mutex_unlock(&j1939_netdev_lock);
+
 	dev_put(ndev);
 	kfree(priv);
 
@@ -304,7 +306,7 @@
 
 void j1939_netdev_stop(struct j1939_priv *priv)
 {
-	kref_put_lock(&priv->rx_kref, __j1939_rx_release, &j1939_netdev_lock);
+	kref_put_mutex(&priv->rx_kref, __j1939_rx_release, &j1939_netdev_lock);
 	j1939_priv_put(priv);
 }
 
diff --git a/kernel/net/can/j1939/socket.c b/kernel/net/can/j1939/socket.c
index 709141a..906a08d 100644
--- a/kernel/net/can/j1939/socket.c
+++ b/kernel/net/can/j1939/socket.c
@@ -798,7 +798,7 @@
 	struct j1939_sk_buff_cb *skcb;
 	int ret = 0;
 
-	if (flags & ~(MSG_DONTWAIT | MSG_ERRQUEUE))
+	if (flags & ~(MSG_DONTWAIT | MSG_ERRQUEUE | MSG_CMSG_COMPAT))
 		return -EINVAL;
 
 	if (flags & MSG_ERRQUEUE)
@@ -1013,6 +1013,11 @@
 
 void j1939_sk_send_loop_abort(struct sock *sk, int err)
 {
+	struct j1939_sock *jsk = j1939_sk(sk);
+
+	if (jsk->state & J1939_SOCK_ERRQUEUE)
+		return;
+
 	sk->sk_err = err;
 
 	sk->sk_error_report(sk);
diff --git a/kernel/net/can/j1939/transport.c b/kernel/net/can/j1939/transport.c
index 78f6a91..5dcbb0b 100644
--- a/kernel/net/can/j1939/transport.c
+++ b/kernel/net/can/j1939/transport.c
@@ -600,7 +600,10 @@
 	/* reserve CAN header */
 	skb_reserve(skb, offsetof(struct can_frame, data));
 
-	memcpy(skb->cb, re_skcb, sizeof(skb->cb));
+	/* skb->cb must be large enough to hold a j1939_sk_buff_cb structure */
+	BUILD_BUG_ON(sizeof(skb->cb) < sizeof(*re_skcb));
+
+	memcpy(skb->cb, re_skcb, sizeof(*re_skcb));
 	skcb = j1939_skb_to_cb(skb);
 	if (swap_src_dst)
 		j1939_skbcb_swap(skcb);
@@ -1087,10 +1090,6 @@
 	bool active;
 
 	j1939_session_list_lock(priv);
-	/* This function should be called with a session ref-count of at
-	 * least 2.
-	 */
-	WARN_ON_ONCE(kref_read(&session->kref) < 2);
 	active = j1939_session_deactivate_locked(session);
 	j1939_session_list_unlock(priv);
 
diff --git a/kernel/net/ceph/mon_client.c b/kernel/net/ceph/mon_client.c
index c4cf252..ef5c174 100644
--- a/kernel/net/ceph/mon_client.c
+++ b/kernel/net/ceph/mon_client.c
@@ -96,9 +96,11 @@
 {
 	int i;
 
-	for (i = 0; i < m->num_mon; i++)
-		if (memcmp(addr, &m->mon_inst[i].addr, sizeof(*addr)) == 0)
+	for (i = 0; i < m->num_mon; i++) {
+		if (ceph_addr_equal_no_type(addr, &m->mon_inst[i].addr))
 			return 1;
+	}
+
 	return 0;
 }
 
diff --git a/kernel/net/ceph/osd_client.c b/kernel/net/ceph/osd_client.c
index 1e9fab7..d594cd5 100644
--- a/kernel/net/ceph/osd_client.c
+++ b/kernel/net/ceph/osd_client.c
@@ -3330,17 +3330,24 @@
 	int ret;
 
 	dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id);
-	ret = wait_for_completion_interruptible(&lreq->reg_commit_wait);
+	ret = wait_for_completion_killable(&lreq->reg_commit_wait);
 	return ret ?: lreq->reg_commit_error;
 }
 
-static int linger_notify_finish_wait(struct ceph_osd_linger_request *lreq)
+static int linger_notify_finish_wait(struct ceph_osd_linger_request *lreq,
+				     unsigned long timeout)
 {
-	int ret;
+	long left;
 
 	dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id);
-	ret = wait_for_completion_interruptible(&lreq->notify_finish_wait);
-	return ret ?: lreq->notify_finish_error;
+	left = wait_for_completion_killable_timeout(&lreq->notify_finish_wait,
+						ceph_timeout_jiffies(timeout));
+	if (left <= 0)
+		left = left ?: -ETIMEDOUT;
+	else
+		left = lreq->notify_finish_error; /* completed */
+
+	return left;
 }
 
 /*
@@ -4888,7 +4895,8 @@
 	linger_submit(lreq);
 	ret = linger_reg_commit_wait(lreq);
 	if (!ret)
-		ret = linger_notify_finish_wait(lreq);
+		ret = linger_notify_finish_wait(lreq,
+				 msecs_to_jiffies(2 * timeout * MSEC_PER_SEC));
 	else
 		dout("lreq %p failed to initiate notify %d\n", lreq, ret);
 
diff --git a/kernel/net/core/bpf_sk_storage.c b/kernel/net/core/bpf_sk_storage.c
index d67d06d..a811fe0 100644
--- a/kernel/net/core/bpf_sk_storage.c
+++ b/kernel/net/core/bpf_sk_storage.c
@@ -446,8 +446,11 @@
 		return ERR_PTR(-EPERM);
 
 	nla_for_each_nested(nla, nla_stgs, rem) {
-		if (nla_type(nla) == SK_DIAG_BPF_STORAGE_REQ_MAP_FD)
+		if (nla_type(nla) == SK_DIAG_BPF_STORAGE_REQ_MAP_FD) {
+			if (nla_len(nla) != sizeof(u32))
+				return ERR_PTR(-EINVAL);
 			nr_maps++;
+		}
 	}
 
 	diag = kzalloc(sizeof(*diag) + sizeof(diag->maps[0]) * nr_maps,
diff --git a/kernel/net/core/datagram.c b/kernel/net/core/datagram.c
index bc92683..9e77695 100644
--- a/kernel/net/core/datagram.c
+++ b/kernel/net/core/datagram.c
@@ -799,18 +799,21 @@
 {
 	struct sock *sk = sock->sk;
 	__poll_t mask;
+	u8 shutdown;
 
 	sock_poll_wait(file, sock, wait);
 	mask = 0;
 
 	/* exceptional events? */
-	if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
+	if (READ_ONCE(sk->sk_err) ||
+	    !skb_queue_empty_lockless(&sk->sk_error_queue))
 		mask |= EPOLLERR |
 			(sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
 
-	if (sk->sk_shutdown & RCV_SHUTDOWN)
+	shutdown = READ_ONCE(sk->sk_shutdown);
+	if (shutdown & RCV_SHUTDOWN)
 		mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
-	if (sk->sk_shutdown == SHUTDOWN_MASK)
+	if (shutdown == SHUTDOWN_MASK)
 		mask |= EPOLLHUP;
 
 	/* readable? */
@@ -819,10 +822,12 @@
 
 	/* Connection-based need to check for termination and startup */
 	if (connection_based(sk)) {
-		if (sk->sk_state == TCP_CLOSE)
+		int state = READ_ONCE(sk->sk_state);
+
+		if (state == TCP_CLOSE)
 			mask |= EPOLLHUP;
 		/* connection hasn't started yet? */
-		if (sk->sk_state == TCP_SYN_SENT)
+		if (state == TCP_SYN_SENT)
 			return mask;
 	}
 
diff --git a/kernel/net/core/dev.c b/kernel/net/core/dev.c
index bc5dcf5..c34511b 100644
--- a/kernel/net/core/dev.c
+++ b/kernel/net/core/dev.c
@@ -2635,6 +2635,8 @@
 	bool active = false;
 	unsigned int nr_ids;
 
+	WARN_ON_ONCE(index >= dev->num_tx_queues);
+
 	if (dev->num_tc) {
 		/* Do not allow XPS on subordinate device directly */
 		num_tc = dev->num_tc;
@@ -3124,8 +3126,10 @@
 {
 	if (in_irq() || irqs_disabled())
 		__dev_kfree_skb_irq(skb, reason);
+	else if (unlikely(reason == SKB_REASON_DROPPED))
+		kfree_skb(skb);
 	else
-		dev_kfree_skb(skb);
+		consume_skb(skb);
 }
 EXPORT_SYMBOL(__dev_kfree_skb_any);
 
@@ -3323,7 +3327,7 @@
 		type = eth->h_proto;
 	}
 
-	return __vlan_get_protocol(skb, type, depth);
+	return vlan_get_protocol_and_depth(skb, type, depth);
 }
 
 /**
@@ -3636,7 +3640,7 @@
 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);
 
@@ -4386,8 +4390,10 @@
 		u32 next_cpu;
 		u32 ident;
 
-		/* First check into global flow table if there is a match */
-		ident = sock_flow_table->ents[hash & sock_flow_table->mask];
+		/* First check into global flow table if there is a match.
+		 * This READ_ONCE() pairs with WRITE_ONCE() from rps_record_sock_flow().
+		 */
+		ident = READ_ONCE(sock_flow_table->ents[hash & sock_flow_table->mask]);
 		if ((ident ^ hash) & ~rps_cpu_mask)
 			goto try_rps;
 
@@ -6114,6 +6120,7 @@
 
 static void napi_skb_free_stolen_head(struct sk_buff *skb)
 {
+	nf_reset_ct(skb);
 	skb_dst_drop(skb);
 	skb_ext_put(skb);
 	kmem_cache_free(skbuff_head_cache, skb);
@@ -10298,9 +10305,7 @@
 		BUG_ON(!list_empty(&dev->ptype_specific));
 		WARN_ON(rcu_access_pointer(dev->ip_ptr));
 		WARN_ON(rcu_access_pointer(dev->ip6_ptr));
-#if IS_ENABLED(CONFIG_DECNET)
-		WARN_ON(dev->dn_ptr);
-#endif
+
 		if (dev->priv_destructor)
 			dev->priv_destructor(dev);
 		if (dev->needs_free_netdev)
diff --git a/kernel/net/core/devlink.c b/kernel/net/core/devlink.c
index 7204775..38666dd 100644
--- a/kernel/net/core/devlink.c
+++ b/kernel/net/core/devlink.c
@@ -3620,7 +3620,7 @@
 			     const struct devlink_param *param,
 			     struct devlink_param_gset_ctx *ctx)
 {
-	if (!param->get || devlink->reload_failed)
+	if (!param->get)
 		return -EOPNOTSUPP;
 	return param->get(devlink, param->id, ctx);
 }
@@ -3629,7 +3629,7 @@
 			     const struct devlink_param *param,
 			     struct devlink_param_gset_ctx *ctx)
 {
-	if (!param->set || devlink->reload_failed)
+	if (!param->set)
 		return -EOPNOTSUPP;
 	return param->set(devlink, param->id, ctx);
 }
@@ -8092,7 +8092,10 @@
 
 static void devlink_port_type_warn(struct work_struct *work)
 {
-	WARN(true, "Type was not set for devlink port.");
+	struct devlink_port *port = container_of(to_delayed_work(work),
+						 struct devlink_port,
+						 type_warn_dw);
+	dev_warn(port->devlink->dev, "Type was not set for devlink port.");
 }
 
 static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
diff --git a/kernel/net/core/filter.c b/kernel/net/core/filter.c
index fc62976..ca9d5de 100644
--- a/kernel/net/core/filter.c
+++ b/kernel/net/core/filter.c
@@ -2125,8 +2125,17 @@
 {
 	unsigned int mlen = skb_network_offset(skb);
 
+	if (unlikely(skb->len <= mlen)) {
+		kfree_skb(skb);
+		return -ERANGE;
+	}
+
 	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
@@ -2146,7 +2155,7 @@
 				 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;
 	}
@@ -3192,15 +3201,18 @@
 
 static int bpf_skb_generic_pop(struct sk_buff *skb, u32 off, u32 len)
 {
+	void *old_data;
+
 	/* skb_ensure_writable() is not needed here, as we're
 	 * already working on an uncloned skb.
 	 */
 	if (unlikely(!pskb_may_pull(skb, off + len)))
 		return -ENOMEM;
 
-	skb_postpull_rcsum(skb, skb->data + off, len);
-	memmove(skb->data + len, skb->data, off);
+	old_data = skb->data;
 	__skb_pull(skb, len);
+	skb_postpull_rcsum(skb, old_data + off, len);
+	memmove(skb->data, old_data, off);
 
 	return 0;
 }
@@ -4624,11 +4636,9 @@
 
 static u64 __bpf_get_netns_cookie(struct sock *sk)
 {
-#ifdef CONFIG_NET_NS
-	return __net_gen_cookie(sk ? sk->sk_net.net : &init_net);
-#else
-	return 0;
-#endif
+	const struct net *net = sk ? sock_net(sk) : &init_net;
+
+	return atomic64_read(&net->net_cookie);
 }
 
 BPF_CALL_1(bpf_get_netns_cookie_sock, struct sock *, ctx)
@@ -5371,7 +5381,7 @@
 		neigh = __ipv6_neigh_lookup_noref_stub(dev, dst);
 	}
 
-	if (!neigh)
+	if (!neigh || !(neigh->nud_state & NUD_VALID))
 		return BPF_FIB_LKUP_RET_NO_NEIGH;
 
 	return bpf_fib_set_fwd_params(params, neigh, dev);
@@ -5484,7 +5494,7 @@
 	 * not needed here.
 	 */
 	neigh = __ipv6_neigh_lookup_noref_stub(dev, dst);
-	if (!neigh)
+	if (!neigh || !(neigh->nud_state & NUD_VALID))
 		return BPF_FIB_LKUP_RET_NO_NEIGH;
 
 	return bpf_fib_set_fwd_params(params, neigh, dev);
@@ -6631,6 +6641,8 @@
 		return -ENETUNREACH;
 	if (unlikely(sk_fullsock(sk) && sk->sk_reuseport))
 		return -ESOCKTNOSUPPORT;
+	if (sk_unhashed(sk))
+		return -EOPNOTSUPP;
 	if (sk_is_refcounted(sk) &&
 	    unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
 		return -ENOENT;
diff --git a/kernel/net/core/flow_dissector.c b/kernel/net/core/flow_dissector.c
index b8d082f..3d51921 100644
--- a/kernel/net/core/flow_dissector.c
+++ b/kernel/net/core/flow_dissector.c
@@ -1589,8 +1589,7 @@
 
 	memset(&keys, 0, sizeof(keys));
 	__skb_flow_dissect(NULL, skb, &flow_keys_dissector_symmetric,
-			   &keys, NULL, 0, 0, 0,
-			   FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
+			   &keys, NULL, 0, 0, 0, 0);
 
 	return __flow_hash_from_keys(&keys, &hashrnd);
 }
diff --git a/kernel/net/core/lwt_bpf.c b/kernel/net/core/lwt_bpf.c
index 3fd207f..f6c327c 100644
--- a/kernel/net/core/lwt_bpf.c
+++ b/kernel/net/core/lwt_bpf.c
@@ -59,9 +59,8 @@
 			ret = BPF_OK;
 		} else {
 			skb_reset_mac_header(skb);
-			ret = skb_do_redirect(skb);
-			if (ret == 0)
-				ret = BPF_REDIRECT;
+			skb_do_redirect(skb);
+			ret = BPF_REDIRECT;
 		}
 		break;
 
@@ -254,7 +253,7 @@
 
 	err = dst_output(dev_net(skb_dst(skb)->dev), skb->sk, skb);
 	if (unlikely(err))
-		return err;
+		return net_xmit_errno(err);
 
 	/* ip[6]_finish_output2 understand LWTUNNEL_XMIT_DONE */
 	return LWTUNNEL_XMIT_DONE;
diff --git a/kernel/net/core/neighbour.c b/kernel/net/core/neighbour.c
index f6f580e..1526742 100644
--- a/kernel/net/core/neighbour.c
+++ b/kernel/net/core/neighbour.c
@@ -242,7 +242,7 @@
 			    (n->nud_state == NUD_NOARP) ||
 			    (tbl->is_multicast &&
 			     tbl->is_multicast(n->primary_key)) ||
-			    time_after(tref, n->updated))
+			    !time_in_range(n->updated, tref, jiffies))
 				remove = true;
 			write_unlock(&n->lock);
 
@@ -262,7 +262,17 @@
 
 static void neigh_add_timer(struct neighbour *n, unsigned long when)
 {
+	/* Use safe distance from the jiffies - LONG_MAX point while timer
+	 * is running in DELAY/PROBE state but still show to user space
+	 * large times in the past.
+	 */
+	unsigned long mint = jiffies - (LONG_MAX - 86400 * HZ);
+
 	neigh_hold(n);
+	if (!time_in_range(n->confirmed, mint, jiffies))
+		n->confirmed = mint;
+	if (time_before(n->used, n->confirmed))
+		n->used = n->confirmed;
 	if (unlikely(mod_timer(&n->timer, when))) {
 		printk("NEIGH: BUG, double timer add, state is %x\n",
 		       n->nud_state);
@@ -560,37 +570,6 @@
 	return n;
 }
 EXPORT_SYMBOL(neigh_lookup);
-
-struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net,
-				     const void *pkey)
-{
-	struct neighbour *n;
-	unsigned int key_len = tbl->key_len;
-	u32 hash_val;
-	struct neigh_hash_table *nht;
-
-	NEIGH_CACHE_STAT_INC(tbl, lookups);
-
-	rcu_read_lock_bh();
-	nht = rcu_dereference_bh(tbl->nht);
-	hash_val = tbl->hash(pkey, NULL, nht->hash_rnd) >> (32 - nht->hash_shift);
-
-	for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
-	     n != NULL;
-	     n = rcu_dereference_bh(n->next)) {
-		if (!memcmp(n->primary_key, pkey, key_len) &&
-		    net_eq(dev_net(n->dev), net)) {
-			if (!refcount_inc_not_zero(&n->refcnt))
-				n = NULL;
-			NEIGH_CACHE_STAT_INC(tbl, hits);
-			break;
-		}
-	}
-
-	rcu_read_unlock_bh();
-	return n;
-}
-EXPORT_SYMBOL(neigh_lookup_nodev);
 
 static struct neighbour *
 ___neigh_create(struct neigh_table *tbl, const void *pkey,
@@ -948,13 +927,17 @@
 				goto next_elt;
 			}
 
-			if (time_before(n->used, n->confirmed))
+			if (time_before(n->used, n->confirmed) &&
+			    time_is_before_eq_jiffies(n->confirmed))
 				n->used = n->confirmed;
 
 			if (refcount_read(&n->refcnt) == 1 &&
 			    (state == NUD_FAILED ||
-			     time_after(jiffies, n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) {
-				*np = n->next;
+			     !time_in_range_open(jiffies, n->used,
+						 n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) {
+				rcu_assign_pointer(*np,
+					rcu_dereference_protected(n->next,
+						lockdep_is_held(&tbl->lock)));
 				neigh_mark_dead(n);
 				write_unlock(&n->lock);
 				neigh_cleanup_and_release(n);
@@ -1789,9 +1772,6 @@
 		break;
 	case AF_INET6:
 		tbl = neigh_tables[NEIGH_ND_TABLE];
-		break;
-	case AF_DECnet:
-		tbl = neigh_tables[NEIGH_DN_TABLE];
 		break;
 	}
 
diff --git a/kernel/net/core/net_namespace.c b/kernel/net/core/net_namespace.c
index a3b7d96..f1258af 100644
--- a/kernel/net/core/net_namespace.c
+++ b/kernel/net/core/net_namespace.c
@@ -72,18 +72,6 @@
 
 DEFINE_COOKIE(net_cookie);
 
-u64 __net_gen_cookie(struct net *net)
-{
-	while (1) {
-		u64 res = atomic64_read(&net->net_cookie);
-
-		if (res)
-			return res;
-		res = gen_cookie_next(&net_cookie);
-		atomic64_cmpxchg(&net->net_cookie, 0, res);
-	}
-}
-
 static struct net_generic *net_alloc_generic(void)
 {
 	struct net_generic *ng;
@@ -155,12 +143,12 @@
 		return 0;
 
 	if (ops->id && ops->size) {
-cleanup:
 		ng = rcu_dereference_protected(net->gen,
 					       lockdep_is_held(&pernet_ops_rwsem));
 		ng->ptr[*ops->id] = NULL;
 	}
 
+cleanup:
 	kfree(data);
 
 out:
@@ -341,6 +329,9 @@
 	refcount_set(&net->count, 1);
 	refcount_set(&net->passive, 1);
 	get_random_bytes(&net->hash_mix, sizeof(u32));
+	preempt_disable();
+	atomic64_set(&net->net_cookie, gen_cookie_next(&net_cookie));
+	preempt_enable();
 	net->dev_base_seq = 1;
 	net->user_ns = user_ns;
 	idr_init(&net->netns_ids);
@@ -1127,10 +1118,6 @@
 		panic("Could not allocate generic netns");
 
 	rcu_assign_pointer(init_net.gen, ng);
-
-	preempt_disable();
-	__net_gen_cookie(&init_net);
-	preempt_enable();
 
 	down_write(&pernet_ops_rwsem);
 	if (setup_net(&init_net, &init_user_ns))
diff --git a/kernel/net/core/netpoll.c b/kernel/net/core/netpoll.c
index 9609482..2ad2251 100644
--- a/kernel/net/core/netpoll.c
+++ b/kernel/net/core/netpoll.c
@@ -137,6 +137,20 @@
 	}
 }
 
+static int netif_local_xmit_active(struct net_device *dev)
+{
+	int i;
+
+	for (i = 0; i < dev->num_tx_queues; i++) {
+		struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
+
+		if (READ_ONCE(txq->xmit_lock_owner) == smp_processor_id())
+			return 1;
+	}
+
+	return 0;
+}
+
 static void poll_one_napi(struct napi_struct *napi)
 {
 	int work;
@@ -183,7 +197,10 @@
 	if (!ni || down_trylock(&ni->dev_lock))
 		return;
 
-	if (!netif_running(dev)) {
+	/* Some drivers will take the same locks in poll and xmit,
+	 * we can't poll if local CPU is already in xmit.
+	 */
+	if (!netif_running(dev) || netif_local_xmit_active(dev)) {
 		up(&ni->dev_lock);
 		return;
 	}
diff --git a/kernel/net/core/rtnetlink.c b/kernel/net/core/rtnetlink.c
index 3c9c2d6..021dcfd 100644
--- a/kernel/net/core/rtnetlink.c
+++ b/kernel/net/core/rtnetlink.c
@@ -929,24 +929,27 @@
 			 nla_total_size(sizeof(struct ifla_vf_rate)) +
 			 nla_total_size(sizeof(struct ifla_vf_link_state)) +
 			 nla_total_size(sizeof(struct ifla_vf_rss_query_en)) +
-			 nla_total_size(0) + /* nest IFLA_VF_STATS */
-			 /* IFLA_VF_STATS_RX_PACKETS */
-			 nla_total_size_64bit(sizeof(__u64)) +
-			 /* IFLA_VF_STATS_TX_PACKETS */
-			 nla_total_size_64bit(sizeof(__u64)) +
-			 /* IFLA_VF_STATS_RX_BYTES */
-			 nla_total_size_64bit(sizeof(__u64)) +
-			 /* IFLA_VF_STATS_TX_BYTES */
-			 nla_total_size_64bit(sizeof(__u64)) +
-			 /* IFLA_VF_STATS_BROADCAST */
-			 nla_total_size_64bit(sizeof(__u64)) +
-			 /* IFLA_VF_STATS_MULTICAST */
-			 nla_total_size_64bit(sizeof(__u64)) +
-			 /* IFLA_VF_STATS_RX_DROPPED */
-			 nla_total_size_64bit(sizeof(__u64)) +
-			 /* IFLA_VF_STATS_TX_DROPPED */
-			 nla_total_size_64bit(sizeof(__u64)) +
 			 nla_total_size(sizeof(struct ifla_vf_trust)));
+		if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) {
+			size += num_vfs *
+				(nla_total_size(0) + /* nest IFLA_VF_STATS */
+				 /* IFLA_VF_STATS_RX_PACKETS */
+				 nla_total_size_64bit(sizeof(__u64)) +
+				 /* IFLA_VF_STATS_TX_PACKETS */
+				 nla_total_size_64bit(sizeof(__u64)) +
+				 /* IFLA_VF_STATS_RX_BYTES */
+				 nla_total_size_64bit(sizeof(__u64)) +
+				 /* IFLA_VF_STATS_TX_BYTES */
+				 nla_total_size_64bit(sizeof(__u64)) +
+				 /* IFLA_VF_STATS_BROADCAST */
+				 nla_total_size_64bit(sizeof(__u64)) +
+				 /* IFLA_VF_STATS_MULTICAST */
+				 nla_total_size_64bit(sizeof(__u64)) +
+				 /* IFLA_VF_STATS_RX_DROPPED */
+				 nla_total_size_64bit(sizeof(__u64)) +
+				 /* IFLA_VF_STATS_TX_DROPPED */
+				 nla_total_size_64bit(sizeof(__u64)));
+		}
 		return size;
 	} else
 		return 0;
@@ -1221,7 +1224,8 @@
 static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
 					       struct net_device *dev,
 					       int vfs_num,
-					       struct nlattr *vfinfo)
+					       struct nlattr *vfinfo,
+					       u32 ext_filter_mask)
 {
 	struct ifla_vf_rss_query_en vf_rss_query_en;
 	struct nlattr *vf, *vfstats, *vfvlanlist;
@@ -1327,33 +1331,35 @@
 		goto nla_put_vf_failure;
 	}
 	nla_nest_end(skb, vfvlanlist);
-	memset(&vf_stats, 0, sizeof(vf_stats));
-	if (dev->netdev_ops->ndo_get_vf_stats)
-		dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num,
-						&vf_stats);
-	vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS);
-	if (!vfstats)
-		goto nla_put_vf_failure;
-	if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS,
-			      vf_stats.rx_packets, IFLA_VF_STATS_PAD) ||
-	    nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS,
-			      vf_stats.tx_packets, IFLA_VF_STATS_PAD) ||
-	    nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES,
-			      vf_stats.rx_bytes, IFLA_VF_STATS_PAD) ||
-	    nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES,
-			      vf_stats.tx_bytes, IFLA_VF_STATS_PAD) ||
-	    nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST,
-			      vf_stats.broadcast, IFLA_VF_STATS_PAD) ||
-	    nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST,
-			      vf_stats.multicast, IFLA_VF_STATS_PAD) ||
-	    nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED,
-			      vf_stats.rx_dropped, IFLA_VF_STATS_PAD) ||
-	    nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED,
-			      vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) {
-		nla_nest_cancel(skb, vfstats);
-		goto nla_put_vf_failure;
+	if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) {
+		memset(&vf_stats, 0, sizeof(vf_stats));
+		if (dev->netdev_ops->ndo_get_vf_stats)
+			dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num,
+							  &vf_stats);
+		vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS);
+		if (!vfstats)
+			goto nla_put_vf_failure;
+		if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS,
+				      vf_stats.rx_packets, IFLA_VF_STATS_PAD) ||
+		    nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS,
+				      vf_stats.tx_packets, IFLA_VF_STATS_PAD) ||
+		    nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES,
+				      vf_stats.rx_bytes, IFLA_VF_STATS_PAD) ||
+		    nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES,
+				      vf_stats.tx_bytes, IFLA_VF_STATS_PAD) ||
+		    nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST,
+				      vf_stats.broadcast, IFLA_VF_STATS_PAD) ||
+		    nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST,
+				      vf_stats.multicast, IFLA_VF_STATS_PAD) ||
+		    nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED,
+				      vf_stats.rx_dropped, IFLA_VF_STATS_PAD) ||
+		    nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED,
+				      vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) {
+			nla_nest_cancel(skb, vfstats);
+			goto nla_put_vf_failure;
+		}
+		nla_nest_end(skb, vfstats);
 	}
-	nla_nest_end(skb, vfstats);
 	nla_nest_end(skb, vf);
 	return 0;
 
@@ -1386,7 +1392,7 @@
 		return -EMSGSIZE;
 
 	for (i = 0; i < num_vfs; i++) {
-		if (rtnl_fill_vfinfo(skb, dev, i, vfinfo))
+		if (rtnl_fill_vfinfo(skb, dev, i, vfinfo, ext_filter_mask))
 			return -EMSGSIZE;
 	}
 
@@ -2155,13 +2161,27 @@
 	return err;
 }
 
-int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len,
-			struct netlink_ext_ack *exterr)
+int rtnl_nla_parse_ifinfomsg(struct nlattr **tb, const struct nlattr *nla_peer,
+			     struct netlink_ext_ack *exterr)
 {
-	return nla_parse_deprecated(tb, IFLA_MAX, head, len, ifla_policy,
+	const struct ifinfomsg *ifmp;
+	const struct nlattr *attrs;
+	size_t len;
+
+	ifmp = nla_data(nla_peer);
+	attrs = nla_data(nla_peer) + sizeof(struct ifinfomsg);
+	len = nla_len(nla_peer) - sizeof(struct ifinfomsg);
+
+	if (ifmp->ifi_index < 0) {
+		NL_SET_ERR_MSG_ATTR(exterr, nla_peer,
+				    "ifindex can't be negative");
+		return -EINVAL;
+	}
+
+	return nla_parse_deprecated(tb, IFLA_MAX, attrs, len, ifla_policy,
 				    exterr);
 }
-EXPORT_SYMBOL(rtnl_nla_parse_ifla);
+EXPORT_SYMBOL(rtnl_nla_parse_ifinfomsg);
 
 struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
 {
@@ -3252,6 +3272,7 @@
 	struct ifinfomsg *ifm;
 	char ifname[IFNAMSIZ];
 	struct nlattr **data;
+	bool link_specified;
 	int err;
 
 #ifdef CONFIG_MODULES
@@ -3272,12 +3293,19 @@
 		ifname[0] = '\0';
 
 	ifm = nlmsg_data(nlh);
-	if (ifm->ifi_index > 0)
+	if (ifm->ifi_index > 0) {
+		link_specified = true;
 		dev = __dev_get_by_index(net, ifm->ifi_index);
-	else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
+	} else if (ifm->ifi_index < 0) {
+		NL_SET_ERR_MSG(extack, "ifindex can't be negative");
+		return -EINVAL;
+	} else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) {
+		link_specified = true;
 		dev = rtnl_dev_get(net, NULL, tb[IFLA_ALT_IFNAME], ifname);
-	else
+	} else {
+		link_specified = false;
 		dev = NULL;
+	}
 
 	master_dev = NULL;
 	m_ops = NULL;
@@ -3380,7 +3408,12 @@
 	}
 
 	if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
-		if (ifm->ifi_index == 0 && tb[IFLA_GROUP])
+		/* No dev found and NLM_F_CREATE not set. Requested dev does not exist,
+		 * or it's for a group
+		*/
+		if (link_specified)
+			return -ENODEV;
+		if (tb[IFLA_GROUP])
 			return rtnl_group_changelink(skb, net,
 						nla_get_u32(tb[IFLA_GROUP]),
 						ifm, extack, tb);
@@ -3883,7 +3916,7 @@
 	ndm->ndm_ifindex = dev->ifindex;
 	ndm->ndm_state   = ndm_state;
 
-	if (nla_put(skb, NDA_LLADDR, ETH_ALEN, addr))
+	if (nla_put(skb, NDA_LLADDR, dev->addr_len, addr))
 		goto nla_put_failure;
 	if (vid)
 		if (nla_put(skb, NDA_VLAN, sizeof(u16), &vid))
@@ -3897,10 +3930,10 @@
 	return -EMSGSIZE;
 }
 
-static inline size_t rtnl_fdb_nlmsg_size(void)
+static inline size_t rtnl_fdb_nlmsg_size(const struct net_device *dev)
 {
 	return NLMSG_ALIGN(sizeof(struct ndmsg)) +
-	       nla_total_size(ETH_ALEN) +	/* NDA_LLADDR */
+	       nla_total_size(dev->addr_len) +	/* NDA_LLADDR */
 	       nla_total_size(sizeof(u16)) +	/* NDA_VLAN */
 	       0;
 }
@@ -3912,7 +3945,7 @@
 	struct sk_buff *skb;
 	int err = -ENOBUFS;
 
-	skb = nlmsg_new(rtnl_fdb_nlmsg_size(), GFP_ATOMIC);
+	skb = nlmsg_new(rtnl_fdb_nlmsg_size(dev), GFP_ATOMIC);
 	if (!skb)
 		goto errout;
 
@@ -4891,13 +4924,17 @@
 	br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
 	if (br_spec) {
 		nla_for_each_nested(attr, br_spec, rem) {
-			if (nla_type(attr) == IFLA_BRIDGE_FLAGS) {
+			if (nla_type(attr) == IFLA_BRIDGE_FLAGS && !have_flags) {
 				if (nla_len(attr) < sizeof(flags))
 					return -EINVAL;
 
 				have_flags = true;
 				flags = nla_get_u16(attr);
-				break;
+			}
+
+			if (nla_type(attr) == IFLA_BRIDGE_MODE) {
+				if (nla_len(attr) < sizeof(u16))
+					return -EINVAL;
 			}
 		}
 	}
diff --git a/kernel/net/core/skbuff.c b/kernel/net/core/skbuff.c
index 382dbdc..0c8b8ab 100644
--- a/kernel/net/core/skbuff.c
+++ b/kernel/net/core/skbuff.c
@@ -660,7 +660,6 @@
 
 void skb_release_head_state(struct sk_buff *skb)
 {
-	nf_reset_ct(skb);
 	skb_dst_drop(skb);
 	if (skb->destructor) {
 		WARN_ON(in_irq());
@@ -2148,6 +2147,9 @@
 				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. :-( */
@@ -3704,9 +3706,14 @@
 
 	skb_push(skb, -skb_network_offset(skb) + offset);
 
+	/* Ensure the head is writeable before touching the shared info */
+	err = skb_unclone(skb, GFP_ATOMIC);
+	if (err)
+		goto err_linearize;
+
 	skb_shinfo(skb)->frag_list = NULL;
 
-	do {
+	while (list_skb) {
 		nskb = list_skb;
 		list_skb = list_skb->next;
 
@@ -3752,8 +3759,7 @@
 		if (skb_needs_linearize(nskb, features) &&
 		    __skb_linearize(nskb))
 			goto err_linearize;
-
-	} while (list_skb);
+	}
 
 	skb->truesize = skb->truesize - delta_truesize;
 	skb->data_len = skb->data_len - delta_len;
@@ -3816,21 +3822,20 @@
 	struct sk_buff *segs = NULL;
 	struct sk_buff *tail = NULL;
 	struct sk_buff *list_skb = skb_shinfo(head_skb)->frag_list;
-	skb_frag_t *frag = skb_shinfo(head_skb)->frags;
 	unsigned int mss = skb_shinfo(head_skb)->gso_size;
 	unsigned int doffset = head_skb->data - skb_mac_header(head_skb);
-	struct sk_buff *frag_skb = head_skb;
 	unsigned int offset = doffset;
 	unsigned int tnl_hlen = skb_tnl_header_len(head_skb);
 	unsigned int partial_segs = 0;
 	unsigned int headroom;
 	unsigned int len = head_skb->len;
+	struct sk_buff *frag_skb;
+	skb_frag_t *frag;
 	__be16 proto;
 	bool csum, sg;
-	int nfrags = skb_shinfo(head_skb)->nr_frags;
 	int err = -ENOMEM;
 	int i = 0;
-	int pos;
+	int nfrags, pos;
 
 	if ((skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY) &&
 	    mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb)) {
@@ -3907,6 +3912,13 @@
 	headroom = skb_headroom(head_skb);
 	pos = skb_headlen(head_skb);
 
+	if (skb_orphan_frags(head_skb, GFP_ATOMIC))
+		return ERR_PTR(-ENOMEM);
+
+	nfrags = skb_shinfo(head_skb)->nr_frags;
+	frag = skb_shinfo(head_skb)->frags;
+	frag_skb = head_skb;
+
 	do {
 		struct sk_buff *nskb;
 		skb_frag_t *nskb_frag;
@@ -3931,6 +3943,10 @@
 		    (skb_headlen(list_skb) == len || sg)) {
 			BUG_ON(skb_headlen(list_skb) > len);
 
+			nskb = skb_clone(list_skb, GFP_ATOMIC);
+			if (unlikely(!nskb))
+				goto err;
+
 			i = 0;
 			nfrags = skb_shinfo(list_skb)->nr_frags;
 			frag = skb_shinfo(list_skb)->frags;
@@ -3949,11 +3965,7 @@
 				frag++;
 			}
 
-			nskb = skb_clone(list_skb, GFP_ATOMIC);
 			list_skb = list_skb->next;
-
-			if (unlikely(!nskb))
-				goto err;
 
 			if (unlikely(pskb_trim(nskb, len))) {
 				kfree_skb(nskb);
@@ -4025,12 +4037,16 @@
 		skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags &
 					      SKBTX_SHARED_FRAG;
 
-		if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
-		    skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
+		if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
 			goto err;
 
 		while (pos < offset + len) {
 			if (i >= nfrags) {
+				if (skb_orphan_frags(list_skb, GFP_ATOMIC) ||
+				    skb_zerocopy_clone(nskb, list_skb,
+						       GFP_ATOMIC))
+					goto err;
+
 				i = 0;
 				nfrags = skb_shinfo(list_skb)->nr_frags;
 				frag = skb_shinfo(list_skb)->frags;
@@ -4044,10 +4060,6 @@
 					i--;
 					frag--;
 				}
-				if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
-				    skb_zerocopy_clone(nskb, frag_skb,
-						       GFP_ATOMIC))
-					goto err;
 
 				list_skb = list_skb->next;
 			}
@@ -4281,9 +4293,6 @@
 #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)
@@ -4300,9 +4309,6 @@
 #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;
 }
@@ -4778,6 +4784,11 @@
 			skb = alloc_skb(0, GFP_ATOMIC);
 	} else {
 		skb = skb_clone(orig_skb, GFP_ATOMIC);
+
+		if (skb_orphan_frags_rx(skb, GFP_ATOMIC)) {
+			kfree_skb(skb);
+			return;
+		}
 	}
 	if (!skb)
 		return;
diff --git a/kernel/net/core/sock.c b/kernel/net/core/sock.c
index 0506590..76c3dfd 100644
--- a/kernel/net/core/sock.c
+++ b/kernel/net/core/sock.c
@@ -691,7 +691,8 @@
 		return false;
 	if (!sk)
 		return true;
-	switch (sk->sk_family) {
+	/* IPV6_ADDRFORM can change sk->sk_family under us. */
+	switch (READ_ONCE(sk->sk_family)) {
 	case AF_INET:
 		return inet_sk(sk)->mc_loop;
 #if IS_ENABLED(CONFIG_IPV6)
@@ -1184,7 +1185,8 @@
 			cmpxchg(&sk->sk_pacing_status,
 				SK_PACING_NONE,
 				SK_PACING_NEEDED);
-		sk->sk_max_pacing_rate = ulval;
+		/* Pairs with READ_ONCE() from sk_getsockopt() */
+		WRITE_ONCE(sk->sk_max_pacing_rate, ulval);
 		sk->sk_pacing_rate = min(sk->sk_pacing_rate, ulval);
 		break;
 		}
@@ -1332,11 +1334,11 @@
 		break;
 
 	case SO_SNDBUF:
-		v.val = sk->sk_sndbuf;
+		v.val = READ_ONCE(sk->sk_sndbuf);
 		break;
 
 	case SO_RCVBUF:
-		v.val = sk->sk_rcvbuf;
+		v.val = READ_ONCE(sk->sk_rcvbuf);
 		break;
 
 	case SO_REUSEADDR:
@@ -1423,7 +1425,7 @@
 		break;
 
 	case SO_RCVLOWAT:
-		v.val = sk->sk_rcvlowat;
+		v.val = READ_ONCE(sk->sk_rcvlowat);
 		break;
 
 	case SO_SNDLOWAT:
@@ -1517,7 +1519,7 @@
 		if (!sock->ops->set_peek_off)
 			return -EOPNOTSUPP;
 
-		v.val = sk->sk_peek_off;
+		v.val = READ_ONCE(sk->sk_peek_off);
 		break;
 	case SO_NOFCS:
 		v.val = sock_flag(sk, SOCK_NOFCS);
@@ -1547,17 +1549,19 @@
 
 #ifdef CONFIG_NET_RX_BUSY_POLL
 	case SO_BUSY_POLL:
-		v.val = sk->sk_ll_usec;
+		v.val = READ_ONCE(sk->sk_ll_usec);
 		break;
 #endif
 
 	case SO_MAX_PACING_RATE:
+		/* The READ_ONCE() pair with the WRITE_ONCE() in sk_setsockopt() */
 		if (sizeof(v.ulval) != sizeof(v.val) && len >= sizeof(v.ulval)) {
 			lv = sizeof(v.ulval);
-			v.ulval = sk->sk_max_pacing_rate;
+			v.ulval = READ_ONCE(sk->sk_max_pacing_rate);
 		} else {
 			/* 32bit version */
-			v.val = min_t(unsigned long, sk->sk_max_pacing_rate, ~0U);
+			v.val = min_t(unsigned long, ~0U,
+				      READ_ONCE(sk->sk_max_pacing_rate));
 		}
 		break;
 
@@ -1611,6 +1615,13 @@
 
 	case SO_BINDTOIFINDEX:
 		v.val = sk->sk_bound_dev_if;
+		break;
+
+	case SO_NETNS_COOKIE:
+		lv = sizeof(u64);
+		if (len != lv)
+			return -EINVAL;
+		v.val64 = atomic64_read(&sock_net(sk)->net_cookie);
 		break;
 
 	default:
@@ -2017,7 +2028,6 @@
 {
 	u32 max_segs = 1;
 
-	sk_dst_set(sk, dst);
 	sk->sk_route_caps = dst->dev->features | sk->sk_route_forced_caps;
 	if (sk->sk_route_caps & NETIF_F_GSO)
 		sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE;
@@ -2032,6 +2042,7 @@
 		}
 	}
 	sk->sk_gso_max_segs = max_segs;
+	sk_dst_set(sk, dst);
 }
 EXPORT_SYMBOL_GPL(sk_setup_caps);
 
@@ -2176,13 +2187,24 @@
 }
 EXPORT_SYMBOL(sock_i_uid);
 
+unsigned long __sock_i_ino(struct sock *sk)
+{
+	unsigned long ino;
+
+	read_lock(&sk->sk_callback_lock);
+	ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0;
+	read_unlock(&sk->sk_callback_lock);
+	return ino;
+}
+EXPORT_SYMBOL(__sock_i_ino);
+
 unsigned long sock_i_ino(struct sock *sk)
 {
 	unsigned long ino;
 
-	read_lock_bh(&sk->sk_callback_lock);
-	ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0;
-	read_unlock_bh(&sk->sk_callback_lock);
+	local_bh_disable();
+	ino = __sock_i_ino(sk);
+	local_bh_enable();
 	return ino;
 }
 EXPORT_SYMBOL(sock_i_ino);
@@ -2301,9 +2323,9 @@
 		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 		if (refcount_read(&sk->sk_wmem_alloc) < READ_ONCE(sk->sk_sndbuf))
 			break;
-		if (sk->sk_shutdown & SEND_SHUTDOWN)
+		if (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN)
 			break;
-		if (sk->sk_err)
+		if (READ_ONCE(sk->sk_err))
 			break;
 		timeo = schedule_timeout(timeo);
 	}
@@ -2331,7 +2353,7 @@
 			goto failure;
 
 		err = -EPIPE;
-		if (sk->sk_shutdown & SEND_SHUTDOWN)
+		if (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN)
 			goto failure;
 
 		if (sk_wmem_alloc_get(sk) < READ_ONCE(sk->sk_sndbuf))
@@ -2711,7 +2733,7 @@
 	if (mem_cgroup_sockets_enabled && sk->sk_memcg)
 		mem_cgroup_uncharge_skmem(sk->sk_memcg, amount);
 
-	if (sk_under_memory_pressure(sk) &&
+	if (sk_under_global_memory_pressure(sk) &&
 	    (sk_memory_allocated(sk) < sk_prot_mem_limits(sk, 0)))
 		sk_leave_memory_pressure(sk);
 }
@@ -2732,7 +2754,7 @@
 
 int sk_set_peek_off(struct sock *sk, int val)
 {
-	sk->sk_peek_off = val;
+	WRITE_ONCE(sk->sk_peek_off, val);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(sk_set_peek_off);
@@ -2979,7 +3001,7 @@
 }
 EXPORT_SYMBOL(sk_stop_timer_sync);
 
-void sock_init_data(struct socket *sock, struct sock *sk)
+void sock_init_data_uid(struct socket *sock, struct sock *sk, kuid_t uid)
 {
 	sk_init_common(sk);
 	sk->sk_send_head	=	NULL;
@@ -2998,11 +3020,10 @@
 		sk->sk_type	=	sock->type;
 		RCU_INIT_POINTER(sk->sk_wq, &sock->wq);
 		sock->sk	=	sk;
-		sk->sk_uid	=	SOCK_INODE(sock)->i_uid;
 	} else {
 		RCU_INIT_POINTER(sk->sk_wq, NULL);
-		sk->sk_uid	=	make_kuid(sock_net(sk)->user_ns, 0);
 	}
+	sk->sk_uid	=	uid;
 
 	rwlock_init(&sk->sk_callback_lock);
 	if (sk->sk_kern_sock)
@@ -3060,6 +3081,16 @@
 	refcount_set(&sk->sk_refcnt, 1);
 	atomic_set(&sk->sk_drops, 0);
 }
+EXPORT_SYMBOL(sock_init_data_uid);
+
+void sock_init_data(struct socket *sock, struct sock *sk)
+{
+	kuid_t uid = sock ?
+		SOCK_INODE(sock)->i_uid :
+		make_kuid(sock_net(sk)->user_ns, 0);
+
+	sock_init_data_uid(sock, sk, uid);
+}
 EXPORT_SYMBOL(sock_init_data);
 
 void lock_sock_nested(struct sock *sk, int subclass)
diff --git a/kernel/net/core/sock_map.c b/kernel/net/core/sock_map.c
index cbf4184..f375ef1 100644
--- a/kernel/net/core/sock_map.c
+++ b/kernel/net/core/sock_map.c
@@ -122,7 +122,6 @@
 	__acquires(&sk->sk_lock.slock)
 {
 	lock_sock(sk);
-	preempt_disable();
 	rcu_read_lock();
 }
 
@@ -130,7 +129,6 @@
 	__releases(&sk->sk_lock.slock)
 {
 	rcu_read_unlock();
-	preempt_enable();
 	release_sock(sk);
 }
 
@@ -358,11 +356,13 @@
 
 		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);
 		}
 	}
 
diff --git a/kernel/net/core/stream.c b/kernel/net/core/stream.c
index a611305..422ee97 100644
--- a/kernel/net/core/stream.c
+++ b/kernel/net/core/stream.c
@@ -73,8 +73,8 @@
 		add_wait_queue(sk_sleep(sk), &wait);
 		sk->sk_write_pending++;
 		done = sk_wait_event(sk, timeo_p,
-				     !sk->sk_err &&
-				     !((1 << sk->sk_state) &
+				     !READ_ONCE(sk->sk_err) &&
+				     !((1 << READ_ONCE(sk->sk_state)) &
 				       ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)), &wait);
 		remove_wait_queue(sk_sleep(sk), &wait);
 		sk->sk_write_pending--;
@@ -87,9 +87,9 @@
  * sk_stream_closing - Return 1 if we still have things to send in our buffers.
  * @sk: socket to verify
  */
-static inline int sk_stream_closing(struct sock *sk)
+static int sk_stream_closing(const struct sock *sk)
 {
-	return (1 << sk->sk_state) &
+	return (1 << READ_ONCE(sk->sk_state)) &
 	       (TCPF_FIN_WAIT1 | TCPF_CLOSING | TCPF_LAST_ACK);
 }
 
@@ -142,8 +142,8 @@
 
 		set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
 		sk->sk_write_pending++;
-		sk_wait_event(sk, &current_timeo, sk->sk_err ||
-						  (sk->sk_shutdown & SEND_SHUTDOWN) ||
+		sk_wait_event(sk, &current_timeo, READ_ONCE(sk->sk_err) ||
+						  (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) ||
 						  (sk_stream_memory_free(sk) &&
 						  !vm_wait), &wait);
 		sk->sk_write_pending--;
@@ -196,6 +196,12 @@
 	/* 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));
 
@@ -203,7 +209,6 @@
 	sk_mem_reclaim(sk);
 
 	WARN_ON(sk->sk_wmem_queued);
-	WARN_ON(sk->sk_forward_alloc);
 
 	/* It is _impossible_ for the backlog to contain anything
 	 * when we get here.  All user references to this socket
diff --git a/kernel/net/dcb/dcbnl.c b/kernel/net/dcb/dcbnl.c
index 2535d3d..c0fb709 100644
--- a/kernel/net/dcb/dcbnl.c
+++ b/kernel/net/dcb/dcbnl.c
@@ -946,7 +946,7 @@
 		return -EOPNOTSUPP;
 
 	ret = nla_parse_nested_deprecated(data, DCB_BCN_ATTR_MAX,
-					  tb[DCB_ATTR_BCN], dcbnl_pfc_up_nest,
+					  tb[DCB_ATTR_BCN], dcbnl_bcn_nest,
 					  NULL);
 	if (ret)
 		return ret;
diff --git a/kernel/net/dccp/dccp.h b/kernel/net/dccp/dccp.h
index c5c1d2b..588731d 100644
--- a/kernel/net/dccp/dccp.h
+++ b/kernel/net/dccp/dccp.h
@@ -283,6 +283,7 @@
 int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
 			 const struct dccp_hdr *dh, const unsigned int len);
 
+void dccp_destruct_common(struct sock *sk);
 int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized);
 void dccp_destroy_sock(struct sock *sk);
 
diff --git a/kernel/net/dccp/ipv4.c b/kernel/net/dccp/ipv4.c
index a2a8b95..f2a0a4e 100644
--- a/kernel/net/dccp/ipv4.c
+++ b/kernel/net/dccp/ipv4.c
@@ -243,12 +243,12 @@
 	int err;
 	struct net *net = dev_net(skb->dev);
 
-	/* Only need dccph_dport & dccph_sport which are the first
-	 * 4 bytes in dccp header.
-	 * Our caller (icmp_socket_deliver()) already pulled 8 bytes for us.
-	 */
-	BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8);
-	BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8);
+	if (!pskb_may_pull(skb, offset + sizeof(*dh)))
+		return -EINVAL;
+	dh = (struct dccp_hdr *)(skb->data + offset);
+	if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh)))
+		return -EINVAL;
+	iph = (struct iphdr *)skb->data;
 	dh = (struct dccp_hdr *)(skb->data + offset);
 
 	sk = __inet_lookup_established(net, &dccp_hashinfo,
diff --git a/kernel/net/dccp/ipv6.c b/kernel/net/dccp/ipv6.c
index 21c61a9..6d6bbd4 100644
--- a/kernel/net/dccp/ipv6.c
+++ b/kernel/net/dccp/ipv6.c
@@ -67,7 +67,7 @@
 static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 			u8 type, u8 code, int offset, __be32 info)
 {
-	const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
+	const struct ipv6hdr *hdr;
 	const struct dccp_hdr *dh;
 	struct dccp_sock *dp;
 	struct ipv6_pinfo *np;
@@ -76,12 +76,12 @@
 	__u64 seq;
 	struct net *net = dev_net(skb->dev);
 
-	/* Only need dccph_dport & dccph_sport which are the first
-	 * 4 bytes in dccp header.
-	 * Our caller (icmpv6_notify()) already pulled 8 bytes for us.
-	 */
-	BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8);
-	BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8);
+	if (!pskb_may_pull(skb, offset + sizeof(*dh)))
+		return -EINVAL;
+	dh = (struct dccp_hdr *)(skb->data + offset);
+	if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh)))
+		return -EINVAL;
+	hdr = (const struct ipv6hdr *)skb->data;
 	dh = (struct dccp_hdr *)(skb->data + offset);
 
 	sk = __inet6_lookup_established(net, &dccp_hashinfo,
@@ -541,11 +541,9 @@
 	*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash), NULL);
 	/* Clone pktoptions received with SYN, if we own the req */
 	if (*own_req && ireq->pktopts) {
-		newnp->pktoptions = skb_clone(ireq->pktopts, GFP_ATOMIC);
+		newnp->pktoptions = skb_clone_and_charge_r(ireq->pktopts, newsk);
 		consume_skb(ireq->pktopts);
 		ireq->pktopts = NULL;
-		if (newnp->pktoptions)
-			skb_set_owner_r(newnp->pktoptions, newsk);
 	}
 
 	return newsk;
@@ -605,7 +603,7 @@
 					       --ANK (980728)
 	 */
 	if (np->rxopt.all)
-		opt_skb = skb_clone(skb, GFP_ATOMIC);
+		opt_skb = skb_clone_and_charge_r(skb, sk);
 
 	if (sk->sk_state == DCCP_OPEN) { /* Fast path */
 		if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len))
@@ -669,7 +667,6 @@
 			np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb));
 		if (ipv6_opt_accepted(sk, opt_skb,
 				      &DCCP_SKB_CB(opt_skb)->header.h6)) {
-			skb_set_owner_r(opt_skb, sk);
 			memmove(IP6CB(opt_skb),
 				&DCCP_SKB_CB(opt_skb)->header.h6,
 				sizeof(struct inet6_skb_parm));
@@ -995,6 +992,12 @@
 	.sockaddr_len	   = sizeof(struct sockaddr_in6),
 };
 
+static void dccp_v6_sk_destruct(struct sock *sk)
+{
+	dccp_destruct_common(sk);
+	inet6_sock_destruct(sk);
+}
+
 /* NOTE: A lot of things set to zero explicitly by call to
  *       sk_alloc() so need not be done here.
  */
@@ -1007,15 +1010,10 @@
 		if (unlikely(!dccp_v6_ctl_sock_initialized))
 			dccp_v6_ctl_sock_initialized = 1;
 		inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops;
+		sk->sk_destruct = dccp_v6_sk_destruct;
 	}
 
 	return err;
-}
-
-static void dccp_v6_destroy_sock(struct sock *sk)
-{
-	dccp_destroy_sock(sk);
-	inet6_destroy_sock(sk);
 }
 
 static struct timewait_sock_ops dccp6_timewait_sock_ops = {
@@ -1040,7 +1038,7 @@
 	.accept		   = inet_csk_accept,
 	.get_port	   = inet_csk_get_port,
 	.shutdown	   = dccp_shutdown,
-	.destroy	   = dccp_v6_destroy_sock,
+	.destroy	   = dccp_destroy_sock,
 	.orphan_count	   = &dccp_orphan_count,
 	.max_header	   = MAX_DCCP_HEADER,
 	.obj_size	   = sizeof(struct dccp6_sock),
diff --git a/kernel/net/dccp/output.c b/kernel/net/dccp/output.c
index 50e6d56..d679032 100644
--- a/kernel/net/dccp/output.c
+++ b/kernel/net/dccp/output.c
@@ -185,7 +185,7 @@
 
 	/* And store cached results */
 	icsk->icsk_pmtu_cookie = pmtu;
-	dp->dccps_mss_cache = cur_mps;
+	WRITE_ONCE(dp->dccps_mss_cache, cur_mps);
 
 	return cur_mps;
 }
diff --git a/kernel/net/dccp/proto.c b/kernel/net/dccp/proto.c
index 834701f..a01c5d9 100644
--- a/kernel/net/dccp/proto.c
+++ b/kernel/net/dccp/proto.c
@@ -171,12 +171,18 @@
 
 EXPORT_SYMBOL_GPL(dccp_packet_name);
 
-static void dccp_sk_destruct(struct sock *sk)
+void dccp_destruct_common(struct sock *sk)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
 
 	ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
 	dp->dccps_hc_tx_ccid = NULL;
+}
+EXPORT_SYMBOL_GPL(dccp_destruct_common);
+
+static void dccp_sk_destruct(struct sock *sk)
+{
+	dccp_destruct_common(sk);
 	inet_sock_destruct(sk);
 }
 
@@ -318,11 +324,15 @@
 __poll_t dccp_poll(struct file *file, struct socket *sock,
 		       poll_table *wait)
 {
-	__poll_t mask;
 	struct sock *sk = sock->sk;
+	__poll_t mask;
+	u8 shutdown;
+	int state;
 
 	sock_poll_wait(file, sock, wait);
-	if (sk->sk_state == DCCP_LISTEN)
+
+	state = inet_sk_state_load(sk);
+	if (state == DCCP_LISTEN)
 		return inet_csk_listen_poll(sk);
 
 	/* Socket is not locked. We are protected from async events
@@ -331,20 +341,21 @@
 	 */
 
 	mask = 0;
-	if (sk->sk_err)
+	if (READ_ONCE(sk->sk_err))
 		mask = EPOLLERR;
+	shutdown = READ_ONCE(sk->sk_shutdown);
 
-	if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == DCCP_CLOSED)
+	if (shutdown == SHUTDOWN_MASK || state == DCCP_CLOSED)
 		mask |= EPOLLHUP;
-	if (sk->sk_shutdown & RCV_SHUTDOWN)
+	if (shutdown & RCV_SHUTDOWN)
 		mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
 
 	/* Connected? */
-	if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) {
+	if ((1 << state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) {
 		if (atomic_read(&sk->sk_rmem_alloc) > 0)
 			mask |= EPOLLIN | EPOLLRDNORM;
 
-		if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
+		if (!(shutdown & SEND_SHUTDOWN)) {
 			if (sk_stream_is_writeable(sk)) {
 				mask |= EPOLLOUT | EPOLLWRNORM;
 			} else {  /* send SIGIO later */
@@ -362,7 +373,6 @@
 	}
 	return mask;
 }
-
 EXPORT_SYMBOL_GPL(dccp_poll);
 
 int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg)
@@ -633,7 +643,7 @@
 		return dccp_getsockopt_service(sk, len,
 					       (__be32 __user *)optval, optlen);
 	case DCCP_SOCKOPT_GET_CUR_MPS:
-		val = dp->dccps_mss_cache;
+		val = READ_ONCE(dp->dccps_mss_cache);
 		break;
 	case DCCP_SOCKOPT_AVAILABLE_CCIDS:
 		return ccid_getsockopt_builtin_ccids(sk, len, optval, optlen);
@@ -742,7 +752,7 @@
 
 	trace_dccp_probe(sk, len);
 
-	if (len > dp->dccps_mss_cache)
+	if (len > READ_ONCE(dp->dccps_mss_cache))
 		return -EMSGSIZE;
 
 	lock_sock(sk);
@@ -775,6 +785,12 @@
 		goto out_discard;
 	}
 
+	/* We need to check dccps_mss_cache after socket is locked. */
+	if (len > dp->dccps_mss_cache) {
+		rc = -EMSGSIZE;
+		goto out_discard;
+	}
+
 	skb_reserve(skb, sk->sk_prot->max_header);
 	rc = memcpy_from_msg(skb_put(skb, len), msg, len);
 	if (rc != 0)
diff --git a/kernel/net/decnet/Kconfig b/kernel/net/decnet/Kconfig
deleted file mode 100644
index 24336bd..0000000
--- a/kernel/net/decnet/Kconfig
+++ /dev/null
@@ -1,43 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# DECnet configuration
-#
-config DECNET
-	tristate "DECnet Support"
-	help
-	  The DECnet networking protocol was used in many products made by
-	  Digital (now Compaq).  It provides reliable stream and sequenced
-	  packet communications over which run a variety of services similar
-	  to those which run over TCP/IP.
-
-	  To find some tools to use with the kernel layer support, please
-	  look at Patrick Caulfield's web site:
-	  <http://linux-decnet.sourceforge.net/>.
-
-	  More detailed documentation is available in
-	  <file:Documentation/networking/decnet.rst>.
-
-	  Be sure to say Y to "/proc file system support" and "Sysctl support"
-	  below when using DECnet, since you will need sysctl support to aid
-	  in configuration at run time.
-
-	  The DECnet code is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module is called decnet.
-
-config DECNET_ROUTER
-	bool "DECnet: router support"
-	depends on DECNET
-	select FIB_RULES
-	help
-	  Add support for turning your DECnet Endnode into a level 1 or 2
-	  router.  This is an experimental, but functional option.  If you
-	  do say Y here, then make sure that you also say Y to "Kernel/User
-	  network link driver", "Routing messages" and "Network packet
-	  filtering".  The first two are required to allow configuration via
-	  rtnetlink (you will need Alexey Kuznetsov's iproute2 package
-	  from <ftp://ftp.tux.org/pub/net/ip-routing/>). The "Network packet
-	  filtering" option will be required for the forthcoming routing daemon
-	  to work.
-
-	  See <file:Documentation/networking/decnet.rst> for more information.
diff --git a/kernel/net/decnet/Makefile b/kernel/net/decnet/Makefile
deleted file mode 100644
index 07b38e4..0000000
--- a/kernel/net/decnet/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-obj-$(CONFIG_DECNET) += decnet.o
-
-decnet-y := af_decnet.o dn_nsp_in.o dn_nsp_out.o \
-	    dn_route.o dn_dev.o dn_neigh.o dn_timer.o
-decnet-$(CONFIG_DECNET_ROUTER) += dn_fib.o dn_rules.o dn_table.o
-decnet-y += sysctl_net_decnet.o
-
-obj-$(CONFIG_NETFILTER) += netfilter/
diff --git a/kernel/net/decnet/README b/kernel/net/decnet/README
deleted file mode 100644
index 60e7ec8..0000000
--- a/kernel/net/decnet/README
+++ /dev/null
@@ -1,8 +0,0 @@
-                       Linux DECnet Project
-                      ======================
-
-The documentation for this kernel subsystem is available in the
-Documentation/networking subdirectory of this distribution and also
-on line at http://www.chygwyn.com/DECnet/
-
-Steve Whitehouse <SteveW@ACM.org>
diff --git a/kernel/net/decnet/af_decnet.c b/kernel/net/decnet/af_decnet.c
deleted file mode 100644
index 7d542eb..0000000
--- a/kernel/net/decnet/af_decnet.c
+++ /dev/null
@@ -1,2400 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-/*
- * DECnet       An implementation of the DECnet protocol suite for the LINUX
- *              operating system.  DECnet is implemented using the  BSD Socket
- *              interface as the means of communication with the user level.
- *
- *              DECnet Socket Layer Interface
- *
- * Authors:     Eduardo Marcelo Serrat <emserrat@geocities.com>
- *              Patrick Caulfield <patrick@pandh.demon.co.uk>
- *
- * Changes:
- *        Steve Whitehouse: Copied from Eduardo Serrat and Patrick Caulfield's
- *                          version of the code. Original copyright preserved
- *                          below.
- *        Steve Whitehouse: Some bug fixes, cleaning up some code to make it
- *                          compatible with my routing layer.
- *        Steve Whitehouse: Merging changes from Eduardo Serrat and Patrick
- *                          Caulfield.
- *        Steve Whitehouse: Further bug fixes, checking module code still works
- *                          with new routing layer.
- *        Steve Whitehouse: Additional set/get_sockopt() calls.
- *        Steve Whitehouse: Fixed TIOCINQ ioctl to be same as Eduardo's new
- *                          code.
- *        Steve Whitehouse: recvmsg() changed to try and behave in a POSIX like
- *                          way. Didn't manage it entirely, but its better.
- *        Steve Whitehouse: ditto for sendmsg().
- *        Steve Whitehouse: A selection of bug fixes to various things.
- *        Steve Whitehouse: Added TIOCOUTQ ioctl.
- *        Steve Whitehouse: Fixes to username2sockaddr & sockaddr2username.
- *        Steve Whitehouse: Fixes to connect() error returns.
- *       Patrick Caulfield: Fixes to delayed acceptance logic.
- *         David S. Miller: New socket locking
- *        Steve Whitehouse: Socket list hashing/locking
- *         Arnaldo C. Melo: use capable, not suser
- *        Steve Whitehouse: Removed unused code. Fix to use sk->allocation
- *                          when required.
- *       Patrick Caulfield: /proc/net/decnet now has object name/number
- *        Steve Whitehouse: Fixed local port allocation, hashed sk list
- *          Matthew Wilcox: Fixes for dn_ioctl()
- *        Steve Whitehouse: New connect/accept logic to allow timeouts and
- *                          prepare for sendpage etc.
- */
-
-
-/******************************************************************************
-    (c) 1995-1998 E.M. Serrat		emserrat@geocities.com
-
-
-HISTORY:
-
-Version           Kernel     Date       Author/Comments
--------           ------     ----       ---------------
-Version 0.0.1     2.0.30    01-dic-97	Eduardo Marcelo Serrat
-					(emserrat@geocities.com)
-
-					First Development of DECnet Socket La-
-					yer for Linux. Only supports outgoing
-					connections.
-
-Version 0.0.2	  2.1.105   20-jun-98   Patrick J. Caulfield
-					(patrick@pandh.demon.co.uk)
-
-					Port to new kernel development version.
-
-Version 0.0.3     2.1.106   25-jun-98   Eduardo Marcelo Serrat
-					(emserrat@geocities.com)
-					_
-					Added support for incoming connections
-					so we can start developing server apps
-					on Linux.
-					-
-					Module Support
-Version 0.0.4     2.1.109   21-jul-98   Eduardo Marcelo Serrat
-				       (emserrat@geocities.com)
-				       _
-					Added support for X11R6.4. Now we can
-					use DECnet transport for X on Linux!!!
-				       -
-Version 0.0.5    2.1.110   01-aug-98   Eduardo Marcelo Serrat
-				       (emserrat@geocities.com)
-				       Removed bugs on flow control
-				       Removed bugs on incoming accessdata
-				       order
-				       -
-Version 0.0.6    2.1.110   07-aug-98   Eduardo Marcelo Serrat
-				       dn_recvmsg fixes
-
-					Patrick J. Caulfield
-				       dn_bind fixes
-*******************************************************************************/
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/sched/signal.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/netdevice.h>
-#include <linux/inet.h>
-#include <linux/route.h>
-#include <linux/netfilter.h>
-#include <linux/seq_file.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <net/flow.h>
-#include <asm/ioctls.h>
-#include <linux/capability.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/jiffies.h>
-#include <net/net_namespace.h>
-#include <net/neighbour.h>
-#include <net/dst.h>
-#include <net/fib_rules.h>
-#include <net/tcp.h>
-#include <net/dn.h>
-#include <net/dn_nsp.h>
-#include <net/dn_dev.h>
-#include <net/dn_route.h>
-#include <net/dn_fib.h>
-#include <net/dn_neigh.h>
-
-struct dn_sock {
-	struct sock sk;
-	struct dn_scp scp;
-};
-
-static void dn_keepalive(struct sock *sk);
-
-#define DN_SK_HASH_SHIFT 8
-#define DN_SK_HASH_SIZE (1 << DN_SK_HASH_SHIFT)
-#define DN_SK_HASH_MASK (DN_SK_HASH_SIZE - 1)
-
-
-static const struct proto_ops dn_proto_ops;
-static DEFINE_RWLOCK(dn_hash_lock);
-static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
-static struct hlist_head dn_wild_sk;
-static atomic_long_t decnet_memory_allocated;
-
-static int __dn_setsockopt(struct socket *sock, int level, int optname,
-		sockptr_t optval, unsigned int optlen, int flags);
-static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags);
-
-static struct hlist_head *dn_find_list(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	if (scp->addr.sdn_flags & SDF_WILD)
-		return hlist_empty(&dn_wild_sk) ? &dn_wild_sk : NULL;
-
-	return &dn_sk_hash[le16_to_cpu(scp->addrloc) & DN_SK_HASH_MASK];
-}
-
-/*
- * Valid ports are those greater than zero and not already in use.
- */
-static int check_port(__le16 port)
-{
-	struct sock *sk;
-
-	if (port == 0)
-		return -1;
-
-	sk_for_each(sk, &dn_sk_hash[le16_to_cpu(port) & DN_SK_HASH_MASK]) {
-		struct dn_scp *scp = DN_SK(sk);
-		if (scp->addrloc == port)
-			return -1;
-	}
-	return 0;
-}
-
-static unsigned short port_alloc(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	static unsigned short port = 0x2000;
-	unsigned short i_port = port;
-
-	while(check_port(cpu_to_le16(++port)) != 0) {
-		if (port == i_port)
-			return 0;
-	}
-
-	scp->addrloc = cpu_to_le16(port);
-
-	return 1;
-}
-
-/*
- * Since this is only ever called from user
- * level, we don't need a write_lock() version
- * of this.
- */
-static int dn_hash_sock(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	struct hlist_head *list;
-	int rv = -EUSERS;
-
-	BUG_ON(sk_hashed(sk));
-
-	write_lock_bh(&dn_hash_lock);
-
-	if (!scp->addrloc && !port_alloc(sk))
-		goto out;
-
-	rv = -EADDRINUSE;
-	if ((list = dn_find_list(sk)) == NULL)
-		goto out;
-
-	sk_add_node(sk, list);
-	rv = 0;
-out:
-	write_unlock_bh(&dn_hash_lock);
-	return rv;
-}
-
-static void dn_unhash_sock(struct sock *sk)
-{
-	write_lock(&dn_hash_lock);
-	sk_del_node_init(sk);
-	write_unlock(&dn_hash_lock);
-}
-
-static void dn_unhash_sock_bh(struct sock *sk)
-{
-	write_lock_bh(&dn_hash_lock);
-	sk_del_node_init(sk);
-	write_unlock_bh(&dn_hash_lock);
-}
-
-static struct hlist_head *listen_hash(struct sockaddr_dn *addr)
-{
-	int i;
-	unsigned int hash = addr->sdn_objnum;
-
-	if (hash == 0) {
-		hash = addr->sdn_objnamel;
-		for(i = 0; i < le16_to_cpu(addr->sdn_objnamel); i++) {
-			hash ^= addr->sdn_objname[i];
-			hash ^= (hash << 3);
-		}
-	}
-
-	return &dn_sk_hash[hash & DN_SK_HASH_MASK];
-}
-
-/*
- * Called to transform a socket from bound (i.e. with a local address)
- * into a listening socket (doesn't need a local port number) and rehashes
- * based upon the object name/number.
- */
-static void dn_rehash_sock(struct sock *sk)
-{
-	struct hlist_head *list;
-	struct dn_scp *scp = DN_SK(sk);
-
-	if (scp->addr.sdn_flags & SDF_WILD)
-		return;
-
-	write_lock_bh(&dn_hash_lock);
-	sk_del_node_init(sk);
-	DN_SK(sk)->addrloc = 0;
-	list = listen_hash(&DN_SK(sk)->addr);
-	sk_add_node(sk, list);
-	write_unlock_bh(&dn_hash_lock);
-}
-
-int dn_sockaddr2username(struct sockaddr_dn *sdn, unsigned char *buf, unsigned char type)
-{
-	int len = 2;
-
-	*buf++ = type;
-
-	switch (type) {
-	case 0:
-		*buf++ = sdn->sdn_objnum;
-		break;
-	case 1:
-		*buf++ = 0;
-		*buf++ = le16_to_cpu(sdn->sdn_objnamel);
-		memcpy(buf, sdn->sdn_objname, le16_to_cpu(sdn->sdn_objnamel));
-		len = 3 + le16_to_cpu(sdn->sdn_objnamel);
-		break;
-	case 2:
-		memset(buf, 0, 5);
-		buf += 5;
-		*buf++ = le16_to_cpu(sdn->sdn_objnamel);
-		memcpy(buf, sdn->sdn_objname, le16_to_cpu(sdn->sdn_objnamel));
-		len = 7 + le16_to_cpu(sdn->sdn_objnamel);
-		break;
-	}
-
-	return len;
-}
-
-/*
- * On reception of usernames, we handle types 1 and 0 for destination
- * addresses only. Types 2 and 4 are used for source addresses, but the
- * UIC, GIC are ignored and they are both treated the same way. Type 3
- * is never used as I've no idea what its purpose might be or what its
- * format is.
- */
-int dn_username2sockaddr(unsigned char *data, int len, struct sockaddr_dn *sdn, unsigned char *fmt)
-{
-	unsigned char type;
-	int size = len;
-	int namel = 12;
-
-	sdn->sdn_objnum = 0;
-	sdn->sdn_objnamel = cpu_to_le16(0);
-	memset(sdn->sdn_objname, 0, DN_MAXOBJL);
-
-	if (len < 2)
-		return -1;
-
-	len -= 2;
-	*fmt = *data++;
-	type = *data++;
-
-	switch (*fmt) {
-	case 0:
-		sdn->sdn_objnum = type;
-		return 2;
-	case 1:
-		namel = 16;
-		break;
-	case 2:
-		len  -= 4;
-		data += 4;
-		break;
-	case 4:
-		len  -= 8;
-		data += 8;
-		break;
-	default:
-		return -1;
-	}
-
-	len -= 1;
-
-	if (len < 0)
-		return -1;
-
-	sdn->sdn_objnamel = cpu_to_le16(*data++);
-	len -= le16_to_cpu(sdn->sdn_objnamel);
-
-	if ((len < 0) || (le16_to_cpu(sdn->sdn_objnamel) > namel))
-		return -1;
-
-	memcpy(sdn->sdn_objname, data, le16_to_cpu(sdn->sdn_objnamel));
-
-	return size - len;
-}
-
-struct sock *dn_sklist_find_listener(struct sockaddr_dn *addr)
-{
-	struct hlist_head *list = listen_hash(addr);
-	struct sock *sk;
-
-	read_lock(&dn_hash_lock);
-	sk_for_each(sk, list) {
-		struct dn_scp *scp = DN_SK(sk);
-		if (sk->sk_state != TCP_LISTEN)
-			continue;
-		if (scp->addr.sdn_objnum) {
-			if (scp->addr.sdn_objnum != addr->sdn_objnum)
-				continue;
-		} else {
-			if (addr->sdn_objnum)
-				continue;
-			if (scp->addr.sdn_objnamel != addr->sdn_objnamel)
-				continue;
-			if (memcmp(scp->addr.sdn_objname, addr->sdn_objname, le16_to_cpu(addr->sdn_objnamel)) != 0)
-				continue;
-		}
-		sock_hold(sk);
-		read_unlock(&dn_hash_lock);
-		return sk;
-	}
-
-	sk = sk_head(&dn_wild_sk);
-	if (sk) {
-		if (sk->sk_state == TCP_LISTEN)
-			sock_hold(sk);
-		else
-			sk = NULL;
-	}
-
-	read_unlock(&dn_hash_lock);
-	return sk;
-}
-
-struct sock *dn_find_by_skb(struct sk_buff *skb)
-{
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	struct sock *sk;
-	struct dn_scp *scp;
-
-	read_lock(&dn_hash_lock);
-	sk_for_each(sk, &dn_sk_hash[le16_to_cpu(cb->dst_port) & DN_SK_HASH_MASK]) {
-		scp = DN_SK(sk);
-		if (cb->src != dn_saddr2dn(&scp->peer))
-			continue;
-		if (cb->dst_port != scp->addrloc)
-			continue;
-		if (scp->addrrem && (cb->src_port != scp->addrrem))
-			continue;
-		sock_hold(sk);
-		goto found;
-	}
-	sk = NULL;
-found:
-	read_unlock(&dn_hash_lock);
-	return sk;
-}
-
-
-
-static void dn_destruct(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	skb_queue_purge(&scp->data_xmit_queue);
-	skb_queue_purge(&scp->other_xmit_queue);
-	skb_queue_purge(&scp->other_receive_queue);
-
-	dst_release(rcu_dereference_protected(sk->sk_dst_cache, 1));
-}
-
-static unsigned long dn_memory_pressure;
-
-static void dn_enter_memory_pressure(struct sock *sk)
-{
-	if (!dn_memory_pressure) {
-		dn_memory_pressure = 1;
-	}
-}
-
-static struct proto dn_proto = {
-	.name			= "NSP",
-	.owner			= THIS_MODULE,
-	.enter_memory_pressure	= dn_enter_memory_pressure,
-	.memory_pressure	= &dn_memory_pressure,
-	.memory_allocated	= &decnet_memory_allocated,
-	.sysctl_mem		= sysctl_decnet_mem,
-	.sysctl_wmem		= sysctl_decnet_wmem,
-	.sysctl_rmem		= sysctl_decnet_rmem,
-	.max_header		= DN_MAX_NSP_DATA_HEADER + 64,
-	.obj_size		= sizeof(struct dn_sock),
-};
-
-static struct sock *dn_alloc_sock(struct net *net, struct socket *sock, gfp_t gfp, int kern)
-{
-	struct dn_scp *scp;
-	struct sock *sk = sk_alloc(net, PF_DECnet, gfp, &dn_proto, kern);
-
-	if  (!sk)
-		goto out;
-
-	if (sock)
-		sock->ops = &dn_proto_ops;
-	sock_init_data(sock, sk);
-
-	sk->sk_backlog_rcv = dn_nsp_backlog_rcv;
-	sk->sk_destruct    = dn_destruct;
-	sk->sk_no_check_tx = 1;
-	sk->sk_family      = PF_DECnet;
-	sk->sk_protocol    = 0;
-	sk->sk_allocation  = gfp;
-	sk->sk_sndbuf	   = READ_ONCE(sysctl_decnet_wmem[1]);
-	sk->sk_rcvbuf	   = READ_ONCE(sysctl_decnet_rmem[1]);
-
-	/* Initialization of DECnet Session Control Port		*/
-	scp = DN_SK(sk);
-	scp->state	= DN_O;		/* Open			*/
-	scp->numdat	= 1;		/* Next data seg to tx	*/
-	scp->numoth	= 1;		/* Next oth data to tx  */
-	scp->ackxmt_dat = 0;		/* Last data seg ack'ed */
-	scp->ackxmt_oth = 0;		/* Last oth data ack'ed */
-	scp->ackrcv_dat = 0;		/* Highest data ack recv*/
-	scp->ackrcv_oth = 0;		/* Last oth data ack rec*/
-	scp->flowrem_sw = DN_SEND;
-	scp->flowloc_sw = DN_SEND;
-	scp->flowrem_dat = 0;
-	scp->flowrem_oth = 1;
-	scp->flowloc_dat = 0;
-	scp->flowloc_oth = 1;
-	scp->services_rem = 0;
-	scp->services_loc = 1 | NSP_FC_NONE;
-	scp->info_rem = 0;
-	scp->info_loc = 0x03; /* NSP version 4.1 */
-	scp->segsize_rem = 230 - DN_MAX_NSP_DATA_HEADER; /* Default: Updated by remote segsize */
-	scp->nonagle = 0;
-	scp->multi_ireq = 1;
-	scp->accept_mode = ACC_IMMED;
-	scp->addr.sdn_family    = AF_DECnet;
-	scp->peer.sdn_family    = AF_DECnet;
-	scp->accessdata.acc_accl = 5;
-	memcpy(scp->accessdata.acc_acc, "LINUX", 5);
-
-	scp->max_window   = NSP_MAX_WINDOW;
-	scp->snd_window   = NSP_MIN_WINDOW;
-	scp->nsp_srtt     = NSP_INITIAL_SRTT;
-	scp->nsp_rttvar   = NSP_INITIAL_RTTVAR;
-	scp->nsp_rxtshift = 0;
-
-	skb_queue_head_init(&scp->data_xmit_queue);
-	skb_queue_head_init(&scp->other_xmit_queue);
-	skb_queue_head_init(&scp->other_receive_queue);
-
-	scp->persist = 0;
-	scp->persist_fxn = NULL;
-	scp->keepalive = 10 * HZ;
-	scp->keepalive_fxn = dn_keepalive;
-
-	dn_start_slow_timer(sk);
-out:
-	return sk;
-}
-
-/*
- * Keepalive timer.
- * FIXME: Should respond to SO_KEEPALIVE etc.
- */
-static void dn_keepalive(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	/*
-	 * By checking the other_data transmit queue is empty
-	 * we are double checking that we are not sending too
-	 * many of these keepalive frames.
-	 */
-	if (skb_queue_empty(&scp->other_xmit_queue))
-		dn_nsp_send_link(sk, DN_NOCHANGE, 0);
-}
-
-
-/*
- * Timer for shutdown/destroyed sockets.
- * When socket is dead & no packets have been sent for a
- * certain amount of time, they are removed by this
- * routine. Also takes care of sending out DI & DC
- * frames at correct times.
- */
-int dn_destroy_timer(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	scp->persist = dn_nsp_persist(sk);
-
-	switch (scp->state) {
-	case DN_DI:
-		dn_nsp_send_disc(sk, NSP_DISCINIT, 0, GFP_ATOMIC);
-		if (scp->nsp_rxtshift >= decnet_di_count)
-			scp->state = DN_CN;
-		return 0;
-
-	case DN_DR:
-		dn_nsp_send_disc(sk, NSP_DISCINIT, 0, GFP_ATOMIC);
-		if (scp->nsp_rxtshift >= decnet_dr_count)
-			scp->state = DN_DRC;
-		return 0;
-
-	case DN_DN:
-		if (scp->nsp_rxtshift < decnet_dn_count) {
-			/* printk(KERN_DEBUG "dn_destroy_timer: DN\n"); */
-			dn_nsp_send_disc(sk, NSP_DISCCONF, NSP_REASON_DC,
-					 GFP_ATOMIC);
-			return 0;
-		}
-	}
-
-	scp->persist = (HZ * decnet_time_wait);
-
-	if (sk->sk_socket)
-		return 0;
-
-	if (time_after_eq(jiffies, scp->stamp + HZ * decnet_time_wait)) {
-		dn_unhash_sock(sk);
-		sock_put(sk);
-		return 1;
-	}
-
-	return 0;
-}
-
-static void dn_destroy_sock(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	scp->nsp_rxtshift = 0; /* reset back off */
-
-	if (sk->sk_socket) {
-		if (sk->sk_socket->state != SS_UNCONNECTED)
-			sk->sk_socket->state = SS_DISCONNECTING;
-	}
-
-	sk->sk_state = TCP_CLOSE;
-
-	switch (scp->state) {
-	case DN_DN:
-		dn_nsp_send_disc(sk, NSP_DISCCONF, NSP_REASON_DC,
-				 sk->sk_allocation);
-		scp->persist_fxn = dn_destroy_timer;
-		scp->persist = dn_nsp_persist(sk);
-		break;
-	case DN_CR:
-		scp->state = DN_DR;
-		goto disc_reject;
-	case DN_RUN:
-		scp->state = DN_DI;
-		fallthrough;
-	case DN_DI:
-	case DN_DR:
-disc_reject:
-		dn_nsp_send_disc(sk, NSP_DISCINIT, 0, sk->sk_allocation);
-		fallthrough;
-	case DN_NC:
-	case DN_NR:
-	case DN_RJ:
-	case DN_DIC:
-	case DN_CN:
-	case DN_DRC:
-	case DN_CI:
-	case DN_CD:
-		scp->persist_fxn = dn_destroy_timer;
-		scp->persist = dn_nsp_persist(sk);
-		break;
-	default:
-		printk(KERN_DEBUG "DECnet: dn_destroy_sock passed socket in invalid state\n");
-		fallthrough;
-	case DN_O:
-		dn_stop_slow_timer(sk);
-
-		dn_unhash_sock_bh(sk);
-		sock_put(sk);
-
-		break;
-	}
-}
-
-char *dn_addr2asc(__u16 addr, char *buf)
-{
-	unsigned short node, area;
-
-	node = addr & 0x03ff;
-	area = addr >> 10;
-	sprintf(buf, "%hd.%hd", area, node);
-
-	return buf;
-}
-
-
-
-static int dn_create(struct net *net, struct socket *sock, int protocol,
-		     int kern)
-{
-	struct sock *sk;
-
-	if (protocol < 0 || protocol > U8_MAX)
-		return -EINVAL;
-
-	if (!net_eq(net, &init_net))
-		return -EAFNOSUPPORT;
-
-	switch (sock->type) {
-	case SOCK_SEQPACKET:
-		if (protocol != DNPROTO_NSP)
-			return -EPROTONOSUPPORT;
-		break;
-	case SOCK_STREAM:
-		break;
-	default:
-		return -ESOCKTNOSUPPORT;
-	}
-
-
-	if ((sk = dn_alloc_sock(net, sock, GFP_KERNEL, kern)) == NULL)
-		return -ENOBUFS;
-
-	sk->sk_protocol = protocol;
-
-	return 0;
-}
-
-
-static int
-dn_release(struct socket *sock)
-{
-	struct sock *sk = sock->sk;
-
-	if (sk) {
-		sock_orphan(sk);
-		sock_hold(sk);
-		lock_sock(sk);
-		dn_destroy_sock(sk);
-		release_sock(sk);
-		sock_put(sk);
-	}
-
-	return 0;
-}
-
-static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
-{
-	struct sock *sk = sock->sk;
-	struct dn_scp *scp = DN_SK(sk);
-	struct sockaddr_dn *saddr = (struct sockaddr_dn *)uaddr;
-	struct net_device *dev, *ldev;
-	int rv;
-
-	if (addr_len != sizeof(struct sockaddr_dn))
-		return -EINVAL;
-
-	if (saddr->sdn_family != AF_DECnet)
-		return -EINVAL;
-
-	if (le16_to_cpu(saddr->sdn_nodeaddrl) && (le16_to_cpu(saddr->sdn_nodeaddrl) != 2))
-		return -EINVAL;
-
-	if (le16_to_cpu(saddr->sdn_objnamel) > DN_MAXOBJL)
-		return -EINVAL;
-
-	if (saddr->sdn_flags & ~SDF_WILD)
-		return -EINVAL;
-
-	if (!capable(CAP_NET_BIND_SERVICE) && (saddr->sdn_objnum ||
-	    (saddr->sdn_flags & SDF_WILD)))
-		return -EACCES;
-
-	if (!(saddr->sdn_flags & SDF_WILD)) {
-		if (le16_to_cpu(saddr->sdn_nodeaddrl)) {
-			rcu_read_lock();
-			ldev = NULL;
-			for_each_netdev_rcu(&init_net, dev) {
-				if (!dev->dn_ptr)
-					continue;
-				if (dn_dev_islocal(dev, dn_saddr2dn(saddr))) {
-					ldev = dev;
-					break;
-				}
-			}
-			rcu_read_unlock();
-			if (ldev == NULL)
-				return -EADDRNOTAVAIL;
-		}
-	}
-
-	rv = -EINVAL;
-	lock_sock(sk);
-	if (sock_flag(sk, SOCK_ZAPPED)) {
-		memcpy(&scp->addr, saddr, addr_len);
-		sock_reset_flag(sk, SOCK_ZAPPED);
-
-		rv = dn_hash_sock(sk);
-		if (rv)
-			sock_set_flag(sk, SOCK_ZAPPED);
-	}
-	release_sock(sk);
-
-	return rv;
-}
-
-
-static int dn_auto_bind(struct socket *sock)
-{
-	struct sock *sk = sock->sk;
-	struct dn_scp *scp = DN_SK(sk);
-	int rv;
-
-	sock_reset_flag(sk, SOCK_ZAPPED);
-
-	scp->addr.sdn_flags  = 0;
-	scp->addr.sdn_objnum = 0;
-
-	/*
-	 * This stuff is to keep compatibility with Eduardo's
-	 * patch. I hope I can dispense with it shortly...
-	 */
-	if ((scp->accessdata.acc_accl != 0) &&
-		(scp->accessdata.acc_accl <= 12)) {
-
-		scp->addr.sdn_objnamel = cpu_to_le16(scp->accessdata.acc_accl);
-		memcpy(scp->addr.sdn_objname, scp->accessdata.acc_acc, le16_to_cpu(scp->addr.sdn_objnamel));
-
-		scp->accessdata.acc_accl = 0;
-		memset(scp->accessdata.acc_acc, 0, 40);
-	}
-	/* End of compatibility stuff */
-
-	scp->addr.sdn_add.a_len = cpu_to_le16(2);
-	rv = dn_dev_bind_default((__le16 *)scp->addr.sdn_add.a_addr);
-	if (rv == 0) {
-		rv = dn_hash_sock(sk);
-		if (rv)
-			sock_set_flag(sk, SOCK_ZAPPED);
-	}
-
-	return rv;
-}
-
-static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	DEFINE_WAIT_FUNC(wait, woken_wake_function);
-	int err;
-
-	if (scp->state != DN_CR)
-		return -EINVAL;
-
-	scp->state = DN_CC;
-	scp->segsize_loc = dst_metric_advmss(__sk_dst_get(sk));
-	dn_send_conn_conf(sk, allocation);
-
-	add_wait_queue(sk_sleep(sk), &wait);
-	for(;;) {
-		release_sock(sk);
-		if (scp->state == DN_CC)
-			*timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, *timeo);
-		lock_sock(sk);
-		err = 0;
-		if (scp->state == DN_RUN)
-			break;
-		err = sock_error(sk);
-		if (err)
-			break;
-		err = sock_intr_errno(*timeo);
-		if (signal_pending(current))
-			break;
-		err = -EAGAIN;
-		if (!*timeo)
-			break;
-	}
-	remove_wait_queue(sk_sleep(sk), &wait);
-	if (err == 0) {
-		sk->sk_socket->state = SS_CONNECTED;
-	} else if (scp->state != DN_CC) {
-		sk->sk_socket->state = SS_UNCONNECTED;
-	}
-	return err;
-}
-
-static int dn_wait_run(struct sock *sk, long *timeo)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	DEFINE_WAIT_FUNC(wait, woken_wake_function);
-	int err = 0;
-
-	if (scp->state == DN_RUN)
-		goto out;
-
-	if (!*timeo)
-		return -EALREADY;
-
-	add_wait_queue(sk_sleep(sk), &wait);
-	for(;;) {
-		release_sock(sk);
-		if (scp->state == DN_CI || scp->state == DN_CC)
-			*timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, *timeo);
-		lock_sock(sk);
-		err = 0;
-		if (scp->state == DN_RUN)
-			break;
-		err = sock_error(sk);
-		if (err)
-			break;
-		err = sock_intr_errno(*timeo);
-		if (signal_pending(current))
-			break;
-		err = -ETIMEDOUT;
-		if (!*timeo)
-			break;
-	}
-	remove_wait_queue(sk_sleep(sk), &wait);
-out:
-	if (err == 0) {
-		sk->sk_socket->state = SS_CONNECTED;
-	} else if (scp->state != DN_CI && scp->state != DN_CC) {
-		sk->sk_socket->state = SS_UNCONNECTED;
-	}
-	return err;
-}
-
-static int __dn_connect(struct sock *sk, struct sockaddr_dn *addr, int addrlen, long *timeo, int flags)
-{
-	struct socket *sock = sk->sk_socket;
-	struct dn_scp *scp = DN_SK(sk);
-	int err = -EISCONN;
-	struct flowidn fld;
-	struct dst_entry *dst;
-
-	if (sock->state == SS_CONNECTED)
-		goto out;
-
-	if (sock->state == SS_CONNECTING) {
-		err = 0;
-		if (scp->state == DN_RUN) {
-			sock->state = SS_CONNECTED;
-			goto out;
-		}
-		err = -ECONNREFUSED;
-		if (scp->state != DN_CI && scp->state != DN_CC) {
-			sock->state = SS_UNCONNECTED;
-			goto out;
-		}
-		return dn_wait_run(sk, timeo);
-	}
-
-	err = -EINVAL;
-	if (scp->state != DN_O)
-		goto out;
-
-	if (addr == NULL || addrlen != sizeof(struct sockaddr_dn))
-		goto out;
-	if (addr->sdn_family != AF_DECnet)
-		goto out;
-	if (addr->sdn_flags & SDF_WILD)
-		goto out;
-
-	if (sock_flag(sk, SOCK_ZAPPED)) {
-		err = dn_auto_bind(sk->sk_socket);
-		if (err)
-			goto out;
-	}
-
-	memcpy(&scp->peer, addr, sizeof(struct sockaddr_dn));
-
-	err = -EHOSTUNREACH;
-	memset(&fld, 0, sizeof(fld));
-	fld.flowidn_oif = sk->sk_bound_dev_if;
-	fld.daddr = dn_saddr2dn(&scp->peer);
-	fld.saddr = dn_saddr2dn(&scp->addr);
-	dn_sk_ports_copy(&fld, scp);
-	fld.flowidn_proto = DNPROTO_NSP;
-	if (dn_route_output_sock(&sk->sk_dst_cache, &fld, sk, flags) < 0)
-		goto out;
-	dst = __sk_dst_get(sk);
-	sk->sk_route_caps = dst->dev->features;
-	sock->state = SS_CONNECTING;
-	scp->state = DN_CI;
-	scp->segsize_loc = dst_metric_advmss(dst);
-
-	dn_nsp_send_conninit(sk, NSP_CI);
-	err = -EINPROGRESS;
-	if (*timeo) {
-		err = dn_wait_run(sk, timeo);
-	}
-out:
-	return err;
-}
-
-static int dn_connect(struct socket *sock, struct sockaddr *uaddr, int addrlen, int flags)
-{
-	struct sockaddr_dn *addr = (struct sockaddr_dn *)uaddr;
-	struct sock *sk = sock->sk;
-	int err;
-	long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
-
-	lock_sock(sk);
-	err = __dn_connect(sk, addr, addrlen, &timeo, 0);
-	release_sock(sk);
-
-	return err;
-}
-
-static inline int dn_check_state(struct sock *sk, struct sockaddr_dn *addr, int addrlen, long *timeo, int flags)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	switch (scp->state) {
-	case DN_RUN:
-		return 0;
-	case DN_CR:
-		return dn_confirm_accept(sk, timeo, sk->sk_allocation);
-	case DN_CI:
-	case DN_CC:
-		return dn_wait_run(sk, timeo);
-	case DN_O:
-		return __dn_connect(sk, addr, addrlen, timeo, flags);
-	}
-
-	return -EINVAL;
-}
-
-
-static void dn_access_copy(struct sk_buff *skb, struct accessdata_dn *acc)
-{
-	unsigned char *ptr = skb->data;
-
-	acc->acc_userl = *ptr++;
-	memcpy(&acc->acc_user, ptr, acc->acc_userl);
-	ptr += acc->acc_userl;
-
-	acc->acc_passl = *ptr++;
-	memcpy(&acc->acc_pass, ptr, acc->acc_passl);
-	ptr += acc->acc_passl;
-
-	acc->acc_accl = *ptr++;
-	memcpy(&acc->acc_acc, ptr, acc->acc_accl);
-
-	skb_pull(skb, acc->acc_accl + acc->acc_passl + acc->acc_userl + 3);
-
-}
-
-static void dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt)
-{
-	unsigned char *ptr = skb->data;
-	u16 len = *ptr++; /* yes, it's 8bit on the wire */
-
-	BUG_ON(len > 16); /* we've checked the contents earlier */
-	opt->opt_optl   = cpu_to_le16(len);
-	opt->opt_status = 0;
-	memcpy(opt->opt_data, ptr, len);
-	skb_pull(skb, len + 1);
-}
-
-static struct sk_buff *dn_wait_for_connect(struct sock *sk, long *timeo)
-{
-	DEFINE_WAIT_FUNC(wait, woken_wake_function);
-	struct sk_buff *skb = NULL;
-	int err = 0;
-
-	add_wait_queue(sk_sleep(sk), &wait);
-	for(;;) {
-		release_sock(sk);
-		skb = skb_dequeue(&sk->sk_receive_queue);
-		if (skb == NULL) {
-			*timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, *timeo);
-			skb = skb_dequeue(&sk->sk_receive_queue);
-		}
-		lock_sock(sk);
-		if (skb != NULL)
-			break;
-		err = -EINVAL;
-		if (sk->sk_state != TCP_LISTEN)
-			break;
-		err = sock_intr_errno(*timeo);
-		if (signal_pending(current))
-			break;
-		err = -EAGAIN;
-		if (!*timeo)
-			break;
-	}
-	remove_wait_queue(sk_sleep(sk), &wait);
-
-	return skb == NULL ? ERR_PTR(err) : skb;
-}
-
-static int dn_accept(struct socket *sock, struct socket *newsock, int flags,
-		     bool kern)
-{
-	struct sock *sk = sock->sk, *newsk;
-	struct sk_buff *skb = NULL;
-	struct dn_skb_cb *cb;
-	unsigned char menuver;
-	int err = 0;
-	unsigned char type;
-	long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
-	struct dst_entry *dst;
-
-	lock_sock(sk);
-
-	if (sk->sk_state != TCP_LISTEN || DN_SK(sk)->state != DN_O) {
-		release_sock(sk);
-		return -EINVAL;
-	}
-
-	skb = skb_dequeue(&sk->sk_receive_queue);
-	if (skb == NULL) {
-		skb = dn_wait_for_connect(sk, &timeo);
-		if (IS_ERR(skb)) {
-			release_sock(sk);
-			return PTR_ERR(skb);
-		}
-	}
-
-	cb = DN_SKB_CB(skb);
-	sk_acceptq_removed(sk);
-	newsk = dn_alloc_sock(sock_net(sk), newsock, sk->sk_allocation, kern);
-	if (newsk == NULL) {
-		release_sock(sk);
-		kfree_skb(skb);
-		return -ENOBUFS;
-	}
-	release_sock(sk);
-
-	dst = skb_dst(skb);
-	sk_dst_set(newsk, dst);
-	skb_dst_set(skb, NULL);
-
-	DN_SK(newsk)->state        = DN_CR;
-	DN_SK(newsk)->addrrem      = cb->src_port;
-	DN_SK(newsk)->services_rem = cb->services;
-	DN_SK(newsk)->info_rem     = cb->info;
-	DN_SK(newsk)->segsize_rem  = cb->segsize;
-	DN_SK(newsk)->accept_mode  = DN_SK(sk)->accept_mode;
-
-	if (DN_SK(newsk)->segsize_rem < 230)
-		DN_SK(newsk)->segsize_rem = 230;
-
-	if ((DN_SK(newsk)->services_rem & NSP_FC_MASK) == NSP_FC_NONE)
-		DN_SK(newsk)->max_window = decnet_no_fc_max_cwnd;
-
-	newsk->sk_state  = TCP_LISTEN;
-	memcpy(&(DN_SK(newsk)->addr), &(DN_SK(sk)->addr), sizeof(struct sockaddr_dn));
-
-	/*
-	 * If we are listening on a wild socket, we don't want
-	 * the newly created socket on the wrong hash queue.
-	 */
-	DN_SK(newsk)->addr.sdn_flags &= ~SDF_WILD;
-
-	skb_pull(skb, dn_username2sockaddr(skb->data, skb->len, &(DN_SK(newsk)->addr), &type));
-	skb_pull(skb, dn_username2sockaddr(skb->data, skb->len, &(DN_SK(newsk)->peer), &type));
-	*(__le16 *)(DN_SK(newsk)->peer.sdn_add.a_addr) = cb->src;
-	*(__le16 *)(DN_SK(newsk)->addr.sdn_add.a_addr) = cb->dst;
-
-	menuver = *skb->data;
-	skb_pull(skb, 1);
-
-	if (menuver & DN_MENUVER_ACC)
-		dn_access_copy(skb, &(DN_SK(newsk)->accessdata));
-
-	if (menuver & DN_MENUVER_USR)
-		dn_user_copy(skb, &(DN_SK(newsk)->conndata_in));
-
-	if (menuver & DN_MENUVER_PRX)
-		DN_SK(newsk)->peer.sdn_flags |= SDF_PROXY;
-
-	if (menuver & DN_MENUVER_UIC)
-		DN_SK(newsk)->peer.sdn_flags |= SDF_UICPROXY;
-
-	kfree_skb(skb);
-
-	memcpy(&(DN_SK(newsk)->conndata_out), &(DN_SK(sk)->conndata_out),
-		sizeof(struct optdata_dn));
-	memcpy(&(DN_SK(newsk)->discdata_out), &(DN_SK(sk)->discdata_out),
-		sizeof(struct optdata_dn));
-
-	lock_sock(newsk);
-	err = dn_hash_sock(newsk);
-	if (err == 0) {
-		sock_reset_flag(newsk, SOCK_ZAPPED);
-		dn_send_conn_ack(newsk);
-
-		/*
-		 * Here we use sk->sk_allocation since although the conn conf is
-		 * for the newsk, the context is the old socket.
-		 */
-		if (DN_SK(newsk)->accept_mode == ACC_IMMED)
-			err = dn_confirm_accept(newsk, &timeo,
-						sk->sk_allocation);
-	}
-	release_sock(newsk);
-	return err;
-}
-
-
-static int dn_getname(struct socket *sock, struct sockaddr *uaddr,int peer)
-{
-	struct sockaddr_dn *sa = (struct sockaddr_dn *)uaddr;
-	struct sock *sk = sock->sk;
-	struct dn_scp *scp = DN_SK(sk);
-
-	lock_sock(sk);
-
-	if (peer) {
-		if ((sock->state != SS_CONNECTED &&
-		     sock->state != SS_CONNECTING) &&
-		    scp->accept_mode == ACC_IMMED) {
-			release_sock(sk);
-			return -ENOTCONN;
-		}
-
-		memcpy(sa, &scp->peer, sizeof(struct sockaddr_dn));
-	} else {
-		memcpy(sa, &scp->addr, sizeof(struct sockaddr_dn));
-	}
-
-	release_sock(sk);
-
-	return sizeof(struct sockaddr_dn);
-}
-
-
-static __poll_t dn_poll(struct file *file, struct socket *sock, poll_table  *wait)
-{
-	struct sock *sk = sock->sk;
-	struct dn_scp *scp = DN_SK(sk);
-	__poll_t mask = datagram_poll(file, sock, wait);
-
-	if (!skb_queue_empty_lockless(&scp->other_receive_queue))
-		mask |= EPOLLRDBAND;
-
-	return mask;
-}
-
-static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
-	struct sock *sk = sock->sk;
-	struct dn_scp *scp = DN_SK(sk);
-	int err = -EOPNOTSUPP;
-	long amount = 0;
-	struct sk_buff *skb;
-	int val;
-
-	switch(cmd)
-	{
-	case SIOCGIFADDR:
-	case SIOCSIFADDR:
-		return dn_dev_ioctl(cmd, (void __user *)arg);
-
-	case SIOCATMARK:
-		lock_sock(sk);
-		val = !skb_queue_empty(&scp->other_receive_queue);
-		if (scp->state != DN_RUN)
-			val = -ENOTCONN;
-		release_sock(sk);
-		return val;
-
-	case TIOCOUTQ:
-		amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
-		if (amount < 0)
-			amount = 0;
-		err = put_user(amount, (int __user *)arg);
-		break;
-
-	case TIOCINQ:
-		lock_sock(sk);
-		skb = skb_peek(&scp->other_receive_queue);
-		if (skb) {
-			amount = skb->len;
-		} else {
-			skb_queue_walk(&sk->sk_receive_queue, skb)
-				amount += skb->len;
-		}
-		release_sock(sk);
-		err = put_user(amount, (int __user *)arg);
-		break;
-
-	default:
-		err = -ENOIOCTLCMD;
-		break;
-	}
-
-	return err;
-}
-
-static int dn_listen(struct socket *sock, int backlog)
-{
-	struct sock *sk = sock->sk;
-	int err = -EINVAL;
-
-	lock_sock(sk);
-
-	if (sock_flag(sk, SOCK_ZAPPED))
-		goto out;
-
-	if ((DN_SK(sk)->state != DN_O) || (sk->sk_state == TCP_LISTEN))
-		goto out;
-
-	sk->sk_max_ack_backlog = backlog;
-	sk->sk_ack_backlog     = 0;
-	sk->sk_state           = TCP_LISTEN;
-	err                 = 0;
-	dn_rehash_sock(sk);
-
-out:
-	release_sock(sk);
-
-	return err;
-}
-
-
-static int dn_shutdown(struct socket *sock, int how)
-{
-	struct sock *sk = sock->sk;
-	struct dn_scp *scp = DN_SK(sk);
-	int err = -ENOTCONN;
-
-	lock_sock(sk);
-
-	if (sock->state == SS_UNCONNECTED)
-		goto out;
-
-	err = 0;
-	if (sock->state == SS_DISCONNECTING)
-		goto out;
-
-	err = -EINVAL;
-	if (scp->state == DN_O)
-		goto out;
-
-	if (how != SHUT_RDWR)
-		goto out;
-
-	sk->sk_shutdown = SHUTDOWN_MASK;
-	dn_destroy_sock(sk);
-	err = 0;
-
-out:
-	release_sock(sk);
-
-	return err;
-}
-
-static int dn_setsockopt(struct socket *sock, int level, int optname,
-		sockptr_t optval, unsigned int optlen)
-{
-	struct sock *sk = sock->sk;
-	int err;
-
-	lock_sock(sk);
-	err = __dn_setsockopt(sock, level, optname, optval, optlen, 0);
-	release_sock(sk);
-#ifdef CONFIG_NETFILTER
-	/* we need to exclude all possible ENOPROTOOPTs except default case */
-	if (err == -ENOPROTOOPT && optname != DSO_LINKINFO &&
-	    optname != DSO_STREAM && optname != DSO_SEQPACKET)
-		err = nf_setsockopt(sk, PF_DECnet, optname, optval, optlen);
-#endif
-
-	return err;
-}
-
-static int __dn_setsockopt(struct socket *sock, int level, int optname,
-		sockptr_t optval, unsigned int optlen, int flags)
-{
-	struct	sock *sk = sock->sk;
-	struct dn_scp *scp = DN_SK(sk);
-	long timeo;
-	union {
-		struct optdata_dn opt;
-		struct accessdata_dn acc;
-		int mode;
-		unsigned long win;
-		int val;
-		unsigned char services;
-		unsigned char info;
-	} u;
-	int err;
-
-	if (optlen && sockptr_is_null(optval))
-		return -EINVAL;
-
-	if (optlen > sizeof(u))
-		return -EINVAL;
-
-	if (copy_from_sockptr(&u, optval, optlen))
-		return -EFAULT;
-
-	switch (optname) {
-	case DSO_CONDATA:
-		if (sock->state == SS_CONNECTED)
-			return -EISCONN;
-		if ((scp->state != DN_O) && (scp->state != DN_CR))
-			return -EINVAL;
-
-		if (optlen != sizeof(struct optdata_dn))
-			return -EINVAL;
-
-		if (le16_to_cpu(u.opt.opt_optl) > 16)
-			return -EINVAL;
-
-		memcpy(&scp->conndata_out, &u.opt, optlen);
-		break;
-
-	case DSO_DISDATA:
-		if (sock->state != SS_CONNECTED &&
-		    scp->accept_mode == ACC_IMMED)
-			return -ENOTCONN;
-
-		if (optlen != sizeof(struct optdata_dn))
-			return -EINVAL;
-
-		if (le16_to_cpu(u.opt.opt_optl) > 16)
-			return -EINVAL;
-
-		memcpy(&scp->discdata_out, &u.opt, optlen);
-		break;
-
-	case DSO_CONACCESS:
-		if (sock->state == SS_CONNECTED)
-			return -EISCONN;
-		if (scp->state != DN_O)
-			return -EINVAL;
-
-		if (optlen != sizeof(struct accessdata_dn))
-			return -EINVAL;
-
-		if ((u.acc.acc_accl > DN_MAXACCL) ||
-		    (u.acc.acc_passl > DN_MAXACCL) ||
-		    (u.acc.acc_userl > DN_MAXACCL))
-			return -EINVAL;
-
-		memcpy(&scp->accessdata, &u.acc, optlen);
-		break;
-
-	case DSO_ACCEPTMODE:
-		if (sock->state == SS_CONNECTED)
-			return -EISCONN;
-		if (scp->state != DN_O)
-			return -EINVAL;
-
-		if (optlen != sizeof(int))
-			return -EINVAL;
-
-		if ((u.mode != ACC_IMMED) && (u.mode != ACC_DEFER))
-			return -EINVAL;
-
-		scp->accept_mode = (unsigned char)u.mode;
-		break;
-
-	case DSO_CONACCEPT:
-		if (scp->state != DN_CR)
-			return -EINVAL;
-		timeo = sock_rcvtimeo(sk, 0);
-		err = dn_confirm_accept(sk, &timeo, sk->sk_allocation);
-		return err;
-
-	case DSO_CONREJECT:
-		if (scp->state != DN_CR)
-			return -EINVAL;
-
-		scp->state = DN_DR;
-		sk->sk_shutdown = SHUTDOWN_MASK;
-		dn_nsp_send_disc(sk, 0x38, 0, sk->sk_allocation);
-		break;
-
-	case DSO_MAXWINDOW:
-		if (optlen != sizeof(unsigned long))
-			return -EINVAL;
-		if (u.win > NSP_MAX_WINDOW)
-			u.win = NSP_MAX_WINDOW;
-		if (u.win == 0)
-			return -EINVAL;
-		scp->max_window = u.win;
-		if (scp->snd_window > u.win)
-			scp->snd_window = u.win;
-		break;
-
-	case DSO_NODELAY:
-		if (optlen != sizeof(int))
-			return -EINVAL;
-		if (scp->nonagle == TCP_NAGLE_CORK)
-			return -EINVAL;
-		scp->nonagle = (u.val == 0) ? 0 : TCP_NAGLE_OFF;
-		/* if (scp->nonagle == 1) { Push pending frames } */
-		break;
-
-	case DSO_CORK:
-		if (optlen != sizeof(int))
-			return -EINVAL;
-		if (scp->nonagle == TCP_NAGLE_OFF)
-			return -EINVAL;
-		scp->nonagle = (u.val == 0) ? 0 : TCP_NAGLE_CORK;
-		/* if (scp->nonagle == 0) { Push pending frames } */
-		break;
-
-	case DSO_SERVICES:
-		if (optlen != sizeof(unsigned char))
-			return -EINVAL;
-		if ((u.services & ~NSP_FC_MASK) != 0x01)
-			return -EINVAL;
-		if ((u.services & NSP_FC_MASK) == NSP_FC_MASK)
-			return -EINVAL;
-		scp->services_loc = u.services;
-		break;
-
-	case DSO_INFO:
-		if (optlen != sizeof(unsigned char))
-			return -EINVAL;
-		if (u.info & 0xfc)
-			return -EINVAL;
-		scp->info_loc = u.info;
-		break;
-
-	case DSO_LINKINFO:
-	case DSO_STREAM:
-	case DSO_SEQPACKET:
-	default:
-		return -ENOPROTOOPT;
-	}
-
-	return 0;
-}
-
-static int dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
-{
-	struct sock *sk = sock->sk;
-	int err;
-
-	lock_sock(sk);
-	err = __dn_getsockopt(sock, level, optname, optval, optlen, 0);
-	release_sock(sk);
-#ifdef CONFIG_NETFILTER
-	if (err == -ENOPROTOOPT && optname != DSO_STREAM &&
-	    optname != DSO_SEQPACKET && optname != DSO_CONACCEPT &&
-	    optname != DSO_CONREJECT) {
-		int len;
-
-		if (get_user(len, optlen))
-			return -EFAULT;
-
-		err = nf_getsockopt(sk, PF_DECnet, optname, optval, &len);
-		if (err >= 0)
-			err = put_user(len, optlen);
-	}
-#endif
-
-	return err;
-}
-
-static int __dn_getsockopt(struct socket *sock, int level,int optname, char __user *optval,int __user *optlen, int flags)
-{
-	struct	sock *sk = sock->sk;
-	struct dn_scp *scp = DN_SK(sk);
-	struct linkinfo_dn link;
-	unsigned int r_len;
-	void *r_data = NULL;
-	unsigned int val;
-
-	if(get_user(r_len , optlen))
-		return -EFAULT;
-
-	switch (optname) {
-	case DSO_CONDATA:
-		if (r_len > sizeof(struct optdata_dn))
-			r_len = sizeof(struct optdata_dn);
-		r_data = &scp->conndata_in;
-		break;
-
-	case DSO_DISDATA:
-		if (r_len > sizeof(struct optdata_dn))
-			r_len = sizeof(struct optdata_dn);
-		r_data = &scp->discdata_in;
-		break;
-
-	case DSO_CONACCESS:
-		if (r_len > sizeof(struct accessdata_dn))
-			r_len = sizeof(struct accessdata_dn);
-		r_data = &scp->accessdata;
-		break;
-
-	case DSO_ACCEPTMODE:
-		if (r_len > sizeof(unsigned char))
-			r_len = sizeof(unsigned char);
-		r_data = &scp->accept_mode;
-		break;
-
-	case DSO_LINKINFO:
-		if (r_len > sizeof(struct linkinfo_dn))
-			r_len = sizeof(struct linkinfo_dn);
-
-		memset(&link, 0, sizeof(link));
-
-		switch (sock->state) {
-		case SS_CONNECTING:
-			link.idn_linkstate = LL_CONNECTING;
-			break;
-		case SS_DISCONNECTING:
-			link.idn_linkstate = LL_DISCONNECTING;
-			break;
-		case SS_CONNECTED:
-			link.idn_linkstate = LL_RUNNING;
-			break;
-		default:
-			link.idn_linkstate = LL_INACTIVE;
-		}
-
-		link.idn_segsize = scp->segsize_rem;
-		r_data = &link;
-		break;
-
-	case DSO_MAXWINDOW:
-		if (r_len > sizeof(unsigned long))
-			r_len = sizeof(unsigned long);
-		r_data = &scp->max_window;
-		break;
-
-	case DSO_NODELAY:
-		if (r_len > sizeof(int))
-			r_len = sizeof(int);
-		val = (scp->nonagle == TCP_NAGLE_OFF);
-		r_data = &val;
-		break;
-
-	case DSO_CORK:
-		if (r_len > sizeof(int))
-			r_len = sizeof(int);
-		val = (scp->nonagle == TCP_NAGLE_CORK);
-		r_data = &val;
-		break;
-
-	case DSO_SERVICES:
-		if (r_len > sizeof(unsigned char))
-			r_len = sizeof(unsigned char);
-		r_data = &scp->services_rem;
-		break;
-
-	case DSO_INFO:
-		if (r_len > sizeof(unsigned char))
-			r_len = sizeof(unsigned char);
-		r_data = &scp->info_rem;
-		break;
-
-	case DSO_STREAM:
-	case DSO_SEQPACKET:
-	case DSO_CONACCEPT:
-	case DSO_CONREJECT:
-	default:
-		return -ENOPROTOOPT;
-	}
-
-	if (r_data) {
-		if (copy_to_user(optval, r_data, r_len))
-			return -EFAULT;
-		if (put_user(r_len, optlen))
-			return -EFAULT;
-	}
-
-	return 0;
-}
-
-
-static int dn_data_ready(struct sock *sk, struct sk_buff_head *q, int flags, int target)
-{
-	struct sk_buff *skb;
-	int len = 0;
-
-	if (flags & MSG_OOB)
-		return !skb_queue_empty(q) ? 1 : 0;
-
-	skb_queue_walk(q, skb) {
-		struct dn_skb_cb *cb = DN_SKB_CB(skb);
-		len += skb->len;
-
-		if (cb->nsp_flags & 0x40) {
-			/* SOCK_SEQPACKET reads to EOM */
-			if (sk->sk_type == SOCK_SEQPACKET)
-				return 1;
-			/* so does SOCK_STREAM unless WAITALL is specified */
-			if (!(flags & MSG_WAITALL))
-				return 1;
-		}
-
-		/* minimum data length for read exceeded */
-		if (len >= target)
-			return 1;
-	}
-
-	return 0;
-}
-
-
-static int dn_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
-		      int flags)
-{
-	struct sock *sk = sock->sk;
-	struct dn_scp *scp = DN_SK(sk);
-	struct sk_buff_head *queue = &sk->sk_receive_queue;
-	size_t target = size > 1 ? 1 : 0;
-	size_t copied = 0;
-	int rv = 0;
-	struct sk_buff *skb, *n;
-	struct dn_skb_cb *cb = NULL;
-	unsigned char eor = 0;
-	long timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
-
-	lock_sock(sk);
-
-	if (sock_flag(sk, SOCK_ZAPPED)) {
-		rv = -EADDRNOTAVAIL;
-		goto out;
-	}
-
-	if (sk->sk_shutdown & RCV_SHUTDOWN) {
-		rv = 0;
-		goto out;
-	}
-
-	rv = dn_check_state(sk, NULL, 0, &timeo, flags);
-	if (rv)
-		goto out;
-
-	if (flags & ~(MSG_CMSG_COMPAT|MSG_PEEK|MSG_OOB|MSG_WAITALL|MSG_DONTWAIT|MSG_NOSIGNAL)) {
-		rv = -EOPNOTSUPP;
-		goto out;
-	}
-
-	if (flags & MSG_OOB)
-		queue = &scp->other_receive_queue;
-
-	if (flags & MSG_WAITALL)
-		target = size;
-
-
-	/*
-	 * See if there is data ready to read, sleep if there isn't
-	 */
-	for(;;) {
-		DEFINE_WAIT_FUNC(wait, woken_wake_function);
-
-		if (sk->sk_err)
-			goto out;
-
-		if (!skb_queue_empty(&scp->other_receive_queue)) {
-			if (!(flags & MSG_OOB)) {
-				msg->msg_flags |= MSG_OOB;
-				if (!scp->other_report) {
-					scp->other_report = 1;
-					goto out;
-				}
-			}
-		}
-
-		if (scp->state != DN_RUN)
-			goto out;
-
-		if (signal_pending(current)) {
-			rv = sock_intr_errno(timeo);
-			goto out;
-		}
-
-		if (dn_data_ready(sk, queue, flags, target))
-			break;
-
-		if (flags & MSG_DONTWAIT) {
-			rv = -EWOULDBLOCK;
-			goto out;
-		}
-
-		add_wait_queue(sk_sleep(sk), &wait);
-		sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
-		sk_wait_event(sk, &timeo, dn_data_ready(sk, queue, flags, target), &wait);
-		sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
-		remove_wait_queue(sk_sleep(sk), &wait);
-	}
-
-	skb_queue_walk_safe(queue, skb, n) {
-		unsigned int chunk = skb->len;
-		cb = DN_SKB_CB(skb);
-
-		if ((chunk + copied) > size)
-			chunk = size - copied;
-
-		if (memcpy_to_msg(msg, skb->data, chunk)) {
-			rv = -EFAULT;
-			break;
-		}
-		copied += chunk;
-
-		if (!(flags & MSG_PEEK))
-			skb_pull(skb, chunk);
-
-		eor = cb->nsp_flags & 0x40;
-
-		if (skb->len == 0) {
-			skb_unlink(skb, queue);
-			kfree_skb(skb);
-			/*
-			 * N.B. Don't refer to skb or cb after this point
-			 * in loop.
-			 */
-			if ((scp->flowloc_sw == DN_DONTSEND) && !dn_congested(sk)) {
-				scp->flowloc_sw = DN_SEND;
-				dn_nsp_send_link(sk, DN_SEND, 0);
-			}
-		}
-
-		if (eor) {
-			if (sk->sk_type == SOCK_SEQPACKET)
-				break;
-			if (!(flags & MSG_WAITALL))
-				break;
-		}
-
-		if (flags & MSG_OOB)
-			break;
-
-		if (copied >= target)
-			break;
-	}
-
-	rv = copied;
-
-
-	if (eor && (sk->sk_type == SOCK_SEQPACKET))
-		msg->msg_flags |= MSG_EOR;
-
-out:
-	if (rv == 0)
-		rv = (flags & MSG_PEEK) ? -sk->sk_err : sock_error(sk);
-
-	if ((rv >= 0) && msg->msg_name) {
-		__sockaddr_check_size(sizeof(struct sockaddr_dn));
-		memcpy(msg->msg_name, &scp->peer, sizeof(struct sockaddr_dn));
-		msg->msg_namelen = sizeof(struct sockaddr_dn);
-	}
-
-	release_sock(sk);
-
-	return rv;
-}
-
-
-static inline int dn_queue_too_long(struct dn_scp *scp, struct sk_buff_head *queue, int flags)
-{
-	unsigned char fctype = scp->services_rem & NSP_FC_MASK;
-	if (skb_queue_len(queue) >= scp->snd_window)
-		return 1;
-	if (fctype != NSP_FC_NONE) {
-		if (flags & MSG_OOB) {
-			if (scp->flowrem_oth == 0)
-				return 1;
-		} else {
-			if (scp->flowrem_dat == 0)
-				return 1;
-		}
-	}
-	return 0;
-}
-
-/*
- * The DECnet spec requires that the "routing layer" accepts packets which
- * are at least 230 bytes in size. This excludes any headers which the NSP
- * layer might add, so we always assume that we'll be using the maximal
- * length header on data packets. The variation in length is due to the
- * inclusion (or not) of the two 16 bit acknowledgement fields so it doesn't
- * make much practical difference.
- */
-unsigned int dn_mss_from_pmtu(struct net_device *dev, int mtu)
-{
-	unsigned int mss = 230 - DN_MAX_NSP_DATA_HEADER;
-	if (dev) {
-		struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
-		mtu -= LL_RESERVED_SPACE(dev);
-		if (dn_db->use_long)
-			mtu -= 21;
-		else
-			mtu -= 6;
-		mtu -= DN_MAX_NSP_DATA_HEADER;
-	} else {
-		/*
-		 * 21 = long header, 16 = guess at MAC header length
-		 */
-		mtu -= (21 + DN_MAX_NSP_DATA_HEADER + 16);
-	}
-	if (mtu > mss)
-		mss = mtu;
-	return mss;
-}
-
-static inline unsigned int dn_current_mss(struct sock *sk, int flags)
-{
-	struct dst_entry *dst = __sk_dst_get(sk);
-	struct dn_scp *scp = DN_SK(sk);
-	int mss_now = min_t(int, scp->segsize_loc, scp->segsize_rem);
-
-	/* Other data messages are limited to 16 bytes per packet */
-	if (flags & MSG_OOB)
-		return 16;
-
-	/* This works out the maximum size of segment we can send out */
-	if (dst) {
-		u32 mtu = dst_mtu(dst);
-		mss_now = min_t(int, dn_mss_from_pmtu(dst->dev, mtu), mss_now);
-	}
-
-	return mss_now;
-}
-
-/*
- * N.B. We get the timeout wrong here, but then we always did get it
- * wrong before and this is another step along the road to correcting
- * it. It ought to get updated each time we pass through the routine,
- * but in practise it probably doesn't matter too much for now.
- */
-static inline struct sk_buff *dn_alloc_send_pskb(struct sock *sk,
-			      unsigned long datalen, int noblock,
-			      int *errcode)
-{
-	struct sk_buff *skb = sock_alloc_send_skb(sk, datalen,
-						   noblock, errcode);
-	if (skb) {
-		skb->protocol = htons(ETH_P_DNA_RT);
-		skb->pkt_type = PACKET_OUTGOING;
-	}
-	return skb;
-}
-
-static int dn_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
-{
-	struct sock *sk = sock->sk;
-	struct dn_scp *scp = DN_SK(sk);
-	size_t mss;
-	struct sk_buff_head *queue = &scp->data_xmit_queue;
-	int flags = msg->msg_flags;
-	int err = 0;
-	size_t sent = 0;
-	int addr_len = msg->msg_namelen;
-	DECLARE_SOCKADDR(struct sockaddr_dn *, addr, msg->msg_name);
-	struct sk_buff *skb = NULL;
-	struct dn_skb_cb *cb;
-	size_t len;
-	unsigned char fctype;
-	long timeo;
-
-	if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE|MSG_CMSG_COMPAT))
-		return -EOPNOTSUPP;
-
-	if (addr_len && (addr_len != sizeof(struct sockaddr_dn)))
-		return -EINVAL;
-
-	lock_sock(sk);
-	timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
-	/*
-	 * The only difference between stream sockets and sequenced packet
-	 * sockets is that the stream sockets always behave as if MSG_EOR
-	 * has been set.
-	 */
-	if (sock->type == SOCK_STREAM) {
-		if (flags & MSG_EOR) {
-			err = -EINVAL;
-			goto out;
-		}
-		flags |= MSG_EOR;
-	}
-
-
-	err = dn_check_state(sk, addr, addr_len, &timeo, flags);
-	if (err)
-		goto out_err;
-
-	if (sk->sk_shutdown & SEND_SHUTDOWN) {
-		err = -EPIPE;
-		if (!(flags & MSG_NOSIGNAL))
-			send_sig(SIGPIPE, current, 0);
-		goto out_err;
-	}
-
-	if ((flags & MSG_TRYHARD) && sk->sk_dst_cache)
-		dst_negative_advice(sk);
-
-	mss = scp->segsize_rem;
-	fctype = scp->services_rem & NSP_FC_MASK;
-
-	mss = dn_current_mss(sk, flags);
-
-	if (flags & MSG_OOB) {
-		queue = &scp->other_xmit_queue;
-		if (size > mss) {
-			err = -EMSGSIZE;
-			goto out;
-		}
-	}
-
-	scp->persist_fxn = dn_nsp_xmit_timeout;
-
-	while(sent < size) {
-		err = sock_error(sk);
-		if (err)
-			goto out;
-
-		if (signal_pending(current)) {
-			err = sock_intr_errno(timeo);
-			goto out;
-		}
-
-		/*
-		 * Calculate size that we wish to send.
-		 */
-		len = size - sent;
-
-		if (len > mss)
-			len = mss;
-
-		/*
-		 * Wait for queue size to go down below the window
-		 * size.
-		 */
-		if (dn_queue_too_long(scp, queue, flags)) {
-			DEFINE_WAIT_FUNC(wait, woken_wake_function);
-
-			if (flags & MSG_DONTWAIT) {
-				err = -EWOULDBLOCK;
-				goto out;
-			}
-
-			add_wait_queue(sk_sleep(sk), &wait);
-			sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
-			sk_wait_event(sk, &timeo,
-				      !dn_queue_too_long(scp, queue, flags), &wait);
-			sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
-			remove_wait_queue(sk_sleep(sk), &wait);
-			continue;
-		}
-
-		/*
-		 * Get a suitably sized skb.
-		 * 64 is a bit of a hack really, but its larger than any
-		 * link-layer headers and has served us well as a good
-		 * guess as to their real length.
-		 */
-		skb = dn_alloc_send_pskb(sk, len + 64 + DN_MAX_NSP_DATA_HEADER,
-					 flags & MSG_DONTWAIT, &err);
-
-		if (err)
-			break;
-
-		if (!skb)
-			continue;
-
-		cb = DN_SKB_CB(skb);
-
-		skb_reserve(skb, 64 + DN_MAX_NSP_DATA_HEADER);
-
-		if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
-			err = -EFAULT;
-			goto out;
-		}
-
-		if (flags & MSG_OOB) {
-			cb->nsp_flags = 0x30;
-			if (fctype != NSP_FC_NONE)
-				scp->flowrem_oth--;
-		} else {
-			cb->nsp_flags = 0x00;
-			if (scp->seg_total == 0)
-				cb->nsp_flags |= 0x20;
-
-			scp->seg_total += len;
-
-			if (((sent + len) == size) && (flags & MSG_EOR)) {
-				cb->nsp_flags |= 0x40;
-				scp->seg_total = 0;
-				if (fctype == NSP_FC_SCMC)
-					scp->flowrem_dat--;
-			}
-			if (fctype == NSP_FC_SRC)
-				scp->flowrem_dat--;
-		}
-
-		sent += len;
-		dn_nsp_queue_xmit(sk, skb, sk->sk_allocation, flags & MSG_OOB);
-		skb = NULL;
-
-		scp->persist = dn_nsp_persist(sk);
-
-	}
-out:
-
-	kfree_skb(skb);
-
-	release_sock(sk);
-
-	return sent ? sent : err;
-
-out_err:
-	err = sk_stream_error(sk, flags, err);
-	release_sock(sk);
-	return err;
-}
-
-static int dn_device_event(struct notifier_block *this, unsigned long event,
-			   void *ptr)
-{
-	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
-
-	if (!net_eq(dev_net(dev), &init_net))
-		return NOTIFY_DONE;
-
-	switch (event) {
-	case NETDEV_UP:
-		dn_dev_up(dev);
-		break;
-	case NETDEV_DOWN:
-		dn_dev_down(dev);
-		break;
-	default:
-		break;
-	}
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block dn_dev_notifier = {
-	.notifier_call = dn_device_event,
-};
-
-static struct packet_type dn_dix_packet_type __read_mostly = {
-	.type =		cpu_to_be16(ETH_P_DNA_RT),
-	.func =		dn_route_rcv,
-};
-
-#ifdef CONFIG_PROC_FS
-struct dn_iter_state {
-	int bucket;
-};
-
-static struct sock *dn_socket_get_first(struct seq_file *seq)
-{
-	struct dn_iter_state *state = seq->private;
-	struct sock *n = NULL;
-
-	for(state->bucket = 0;
-	    state->bucket < DN_SK_HASH_SIZE;
-	    ++state->bucket) {
-		n = sk_head(&dn_sk_hash[state->bucket]);
-		if (n)
-			break;
-	}
-
-	return n;
-}
-
-static struct sock *dn_socket_get_next(struct seq_file *seq,
-				       struct sock *n)
-{
-	struct dn_iter_state *state = seq->private;
-
-	n = sk_next(n);
-	while (!n) {
-		if (++state->bucket >= DN_SK_HASH_SIZE)
-			break;
-		n = sk_head(&dn_sk_hash[state->bucket]);
-	}
-	return n;
-}
-
-static struct sock *socket_get_idx(struct seq_file *seq, loff_t *pos)
-{
-	struct sock *sk = dn_socket_get_first(seq);
-
-	if (sk) {
-		while(*pos && (sk = dn_socket_get_next(seq, sk)))
-			--*pos;
-	}
-	return *pos ? NULL : sk;
-}
-
-static void *dn_socket_get_idx(struct seq_file *seq, loff_t pos)
-{
-	void *rc;
-	read_lock_bh(&dn_hash_lock);
-	rc = socket_get_idx(seq, &pos);
-	if (!rc) {
-		read_unlock_bh(&dn_hash_lock);
-	}
-	return rc;
-}
-
-static void *dn_socket_seq_start(struct seq_file *seq, loff_t *pos)
-{
-	return *pos ? dn_socket_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
-}
-
-static void *dn_socket_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	void *rc;
-
-	if (v == SEQ_START_TOKEN) {
-		rc = dn_socket_get_idx(seq, 0);
-		goto out;
-	}
-
-	rc = dn_socket_get_next(seq, v);
-	if (rc)
-		goto out;
-	read_unlock_bh(&dn_hash_lock);
-out:
-	++*pos;
-	return rc;
-}
-
-static void dn_socket_seq_stop(struct seq_file *seq, void *v)
-{
-	if (v && v != SEQ_START_TOKEN)
-		read_unlock_bh(&dn_hash_lock);
-}
-
-#define IS_NOT_PRINTABLE(x) ((x) < 32 || (x) > 126)
-
-static void dn_printable_object(struct sockaddr_dn *dn, unsigned char *buf)
-{
-	int i;
-
-	switch (le16_to_cpu(dn->sdn_objnamel)) {
-	case 0:
-		sprintf(buf, "%d", dn->sdn_objnum);
-		break;
-	default:
-		for (i = 0; i < le16_to_cpu(dn->sdn_objnamel); i++) {
-			buf[i] = dn->sdn_objname[i];
-			if (IS_NOT_PRINTABLE(buf[i]))
-				buf[i] = '.';
-		}
-		buf[i] = 0;
-	}
-}
-
-static char *dn_state2asc(unsigned char state)
-{
-	switch (state) {
-	case DN_O:
-		return "OPEN";
-	case DN_CR:
-		return "  CR";
-	case DN_DR:
-		return "  DR";
-	case DN_DRC:
-		return " DRC";
-	case DN_CC:
-		return "  CC";
-	case DN_CI:
-		return "  CI";
-	case DN_NR:
-		return "  NR";
-	case DN_NC:
-		return "  NC";
-	case DN_CD:
-		return "  CD";
-	case DN_RJ:
-		return "  RJ";
-	case DN_RUN:
-		return " RUN";
-	case DN_DI:
-		return "  DI";
-	case DN_DIC:
-		return " DIC";
-	case DN_DN:
-		return "  DN";
-	case DN_CL:
-		return "  CL";
-	case DN_CN:
-		return "  CN";
-	}
-
-	return "????";
-}
-
-static inline void dn_socket_format_entry(struct seq_file *seq, struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	char buf1[DN_ASCBUF_LEN];
-	char buf2[DN_ASCBUF_LEN];
-	char local_object[DN_MAXOBJL+3];
-	char remote_object[DN_MAXOBJL+3];
-
-	dn_printable_object(&scp->addr, local_object);
-	dn_printable_object(&scp->peer, remote_object);
-
-	seq_printf(seq,
-		   "%6s/%04X %04d:%04d %04d:%04d %01d %-16s "
-		   "%6s/%04X %04d:%04d %04d:%04d %01d %-16s %4s %s\n",
-		   dn_addr2asc(le16_to_cpu(dn_saddr2dn(&scp->addr)), buf1),
-		   scp->addrloc,
-		   scp->numdat,
-		   scp->numoth,
-		   scp->ackxmt_dat,
-		   scp->ackxmt_oth,
-		   scp->flowloc_sw,
-		   local_object,
-		   dn_addr2asc(le16_to_cpu(dn_saddr2dn(&scp->peer)), buf2),
-		   scp->addrrem,
-		   scp->numdat_rcv,
-		   scp->numoth_rcv,
-		   scp->ackrcv_dat,
-		   scp->ackrcv_oth,
-		   scp->flowrem_sw,
-		   remote_object,
-		   dn_state2asc(scp->state),
-		   ((scp->accept_mode == ACC_IMMED) ? "IMMED" : "DEFER"));
-}
-
-static int dn_socket_seq_show(struct seq_file *seq, void *v)
-{
-	if (v == SEQ_START_TOKEN) {
-		seq_puts(seq, "Local                                              Remote\n");
-	} else {
-		dn_socket_format_entry(seq, v);
-	}
-	return 0;
-}
-
-static const struct seq_operations dn_socket_seq_ops = {
-	.start	= dn_socket_seq_start,
-	.next	= dn_socket_seq_next,
-	.stop	= dn_socket_seq_stop,
-	.show	= dn_socket_seq_show,
-};
-#endif
-
-static const struct net_proto_family	dn_family_ops = {
-	.family =	AF_DECnet,
-	.create =	dn_create,
-	.owner	=	THIS_MODULE,
-};
-
-static const struct proto_ops dn_proto_ops = {
-	.family =	AF_DECnet,
-	.owner =	THIS_MODULE,
-	.release =	dn_release,
-	.bind =		dn_bind,
-	.connect =	dn_connect,
-	.socketpair =	sock_no_socketpair,
-	.accept =	dn_accept,
-	.getname =	dn_getname,
-	.poll =		dn_poll,
-	.ioctl =	dn_ioctl,
-	.listen =	dn_listen,
-	.shutdown =	dn_shutdown,
-	.setsockopt =	dn_setsockopt,
-	.getsockopt =	dn_getsockopt,
-	.sendmsg =	dn_sendmsg,
-	.recvmsg =	dn_recvmsg,
-	.mmap =		sock_no_mmap,
-	.sendpage =	sock_no_sendpage,
-};
-
-MODULE_DESCRIPTION("The Linux DECnet Network Protocol");
-MODULE_AUTHOR("Linux DECnet Project Team");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_NETPROTO(PF_DECnet);
-
-static const char banner[] __initconst = KERN_INFO
-"NET4: DECnet for Linux: V.2.5.68s (C) 1995-2003 Linux DECnet Project Team\n";
-
-static int __init decnet_init(void)
-{
-	int rc;
-
-	printk(banner);
-
-	rc = proto_register(&dn_proto, 1);
-	if (rc != 0)
-		goto out;
-
-	dn_neigh_init();
-	dn_dev_init();
-	dn_route_init();
-	dn_fib_init();
-
-	sock_register(&dn_family_ops);
-	dev_add_pack(&dn_dix_packet_type);
-	register_netdevice_notifier(&dn_dev_notifier);
-
-	proc_create_seq_private("decnet", 0444, init_net.proc_net,
-			&dn_socket_seq_ops, sizeof(struct dn_iter_state),
-			NULL);
-	dn_register_sysctl();
-out:
-	return rc;
-
-}
-module_init(decnet_init);
-
-/*
- * Prevent DECnet module unloading until its fixed properly.
- * Requires an audit of the code to check for memory leaks and
- * initialisation problems etc.
- */
-#if 0
-static void __exit decnet_exit(void)
-{
-	sock_unregister(AF_DECnet);
-	rtnl_unregister_all(PF_DECnet);
-	dev_remove_pack(&dn_dix_packet_type);
-
-	dn_unregister_sysctl();
-
-	unregister_netdevice_notifier(&dn_dev_notifier);
-
-	dn_route_cleanup();
-	dn_dev_cleanup();
-	dn_neigh_cleanup();
-	dn_fib_cleanup();
-
-	remove_proc_entry("decnet", init_net.proc_net);
-
-	proto_unregister(&dn_proto);
-
-	rcu_barrier(); /* Wait for completion of call_rcu()'s */
-}
-module_exit(decnet_exit);
-#endif
diff --git a/kernel/net/decnet/dn_dev.c b/kernel/net/decnet/dn_dev.c
deleted file mode 100644
index 15d4235..0000000
--- a/kernel/net/decnet/dn_dev.c
+++ /dev/null
@@ -1,1435 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * DECnet       An implementation of the DECnet protocol suite for the LINUX
- *              operating system.  DECnet is implemented using the  BSD Socket
- *              interface as the means of communication with the user level.
- *
- *              DECnet Device Layer
- *
- * Authors:     Steve Whitehouse <SteveW@ACM.org>
- *              Eduardo Marcelo Serrat <emserrat@geocities.com>
- *
- * Changes:
- *          Steve Whitehouse : Devices now see incoming frames so they
- *                             can mark on who it came from.
- *          Steve Whitehouse : Fixed bug in creating neighbours. Each neighbour
- *                             can now have a device specific setup func.
- *          Steve Whitehouse : Added /proc/sys/net/decnet/conf/<dev>/
- *          Steve Whitehouse : Fixed bug which sometimes killed timer
- *          Steve Whitehouse : Multiple ifaddr support
- *          Steve Whitehouse : SIOCGIFCONF is now a compile time option
- *          Steve Whitehouse : /proc/sys/net/decnet/conf/<sys>/forwarding
- *          Steve Whitehouse : Removed timer1 - it's a user space issue now
- *         Patrick Caulfield : Fixed router hello message format
- *          Steve Whitehouse : Got rid of constant sizes for blksize for
- *                             devices. All mtu based now.
- */
-
-#include <linux/capability.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/net.h>
-#include <linux/netdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/if_addr.h>
-#include <linux/if_arp.h>
-#include <linux/if_ether.h>
-#include <linux/skbuff.h>
-#include <linux/sysctl.h>
-#include <linux/notifier.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/uaccess.h>
-#include <net/net_namespace.h>
-#include <net/neighbour.h>
-#include <net/dst.h>
-#include <net/flow.h>
-#include <net/fib_rules.h>
-#include <net/netlink.h>
-#include <net/dn.h>
-#include <net/dn_dev.h>
-#include <net/dn_route.h>
-#include <net/dn_neigh.h>
-#include <net/dn_fib.h>
-
-#define DN_IFREQ_SIZE (offsetof(struct ifreq, ifr_ifru) + sizeof(struct sockaddr_dn))
-
-static char dn_rt_all_end_mcast[ETH_ALEN] = {0xAB,0x00,0x00,0x04,0x00,0x00};
-static char dn_rt_all_rt_mcast[ETH_ALEN]  = {0xAB,0x00,0x00,0x03,0x00,0x00};
-static char dn_hiord[ETH_ALEN]            = {0xAA,0x00,0x04,0x00,0x00,0x00};
-static unsigned char dn_eco_version[3]    = {0x02,0x00,0x00};
-
-extern struct neigh_table dn_neigh_table;
-
-/*
- * decnet_address is kept in network order.
- */
-__le16 decnet_address = 0;
-
-static DEFINE_SPINLOCK(dndev_lock);
-static struct net_device *decnet_default_device;
-static BLOCKING_NOTIFIER_HEAD(dnaddr_chain);
-
-static struct dn_dev *dn_dev_create(struct net_device *dev, int *err);
-static void dn_dev_delete(struct net_device *dev);
-static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa);
-
-static int dn_eth_up(struct net_device *);
-static void dn_eth_down(struct net_device *);
-static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa);
-static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa);
-
-static struct dn_dev_parms dn_dev_list[] =  {
-{
-	.type =		ARPHRD_ETHER, /* Ethernet */
-	.mode =		DN_DEV_BCAST,
-	.state =	DN_DEV_S_RU,
-	.t2 =		1,
-	.t3 =		10,
-	.name =		"ethernet",
-	.up =		dn_eth_up,
-	.down = 	dn_eth_down,
-	.timer3 =	dn_send_brd_hello,
-},
-{
-	.type =		ARPHRD_IPGRE, /* DECnet tunneled over GRE in IP */
-	.mode =		DN_DEV_BCAST,
-	.state =	DN_DEV_S_RU,
-	.t2 =		1,
-	.t3 =		10,
-	.name =		"ipgre",
-	.timer3 =	dn_send_brd_hello,
-},
-#if 0
-{
-	.type =		ARPHRD_X25, /* Bog standard X.25 */
-	.mode =		DN_DEV_UCAST,
-	.state =	DN_DEV_S_DS,
-	.t2 =		1,
-	.t3 =		120,
-	.name =		"x25",
-	.timer3 =	dn_send_ptp_hello,
-},
-#endif
-#if 0
-{
-	.type =		ARPHRD_PPP, /* DECnet over PPP */
-	.mode =		DN_DEV_BCAST,
-	.state =	DN_DEV_S_RU,
-	.t2 =		1,
-	.t3 =		10,
-	.name =		"ppp",
-	.timer3 =	dn_send_brd_hello,
-},
-#endif
-{
-	.type =		ARPHRD_DDCMP, /* DECnet over DDCMP */
-	.mode =		DN_DEV_UCAST,
-	.state =	DN_DEV_S_DS,
-	.t2 =		1,
-	.t3 =		120,
-	.name =		"ddcmp",
-	.timer3 =	dn_send_ptp_hello,
-},
-{
-	.type =		ARPHRD_LOOPBACK, /* Loopback interface - always last */
-	.mode =		DN_DEV_BCAST,
-	.state =	DN_DEV_S_RU,
-	.t2 =		1,
-	.t3 =		10,
-	.name =		"loopback",
-	.timer3 =	dn_send_brd_hello,
-}
-};
-
-#define DN_DEV_LIST_SIZE ARRAY_SIZE(dn_dev_list)
-
-#define DN_DEV_PARMS_OFFSET(x) offsetof(struct dn_dev_parms, x)
-
-#ifdef CONFIG_SYSCTL
-
-static int min_t2[] = { 1 };
-static int max_t2[] = { 60 }; /* No max specified, but this seems sensible */
-static int min_t3[] = { 1 };
-static int max_t3[] = { 8191 }; /* Must fit in 16 bits when multiplied by BCT3MULT or T3MULT */
-
-static int min_priority[1];
-static int max_priority[] = { 127 }; /* From DECnet spec */
-
-static int dn_forwarding_proc(struct ctl_table *, int, void *, size_t *,
-		loff_t *);
-static struct dn_dev_sysctl_table {
-	struct ctl_table_header *sysctl_header;
-	struct ctl_table dn_dev_vars[5];
-} dn_dev_sysctl = {
-	NULL,
-	{
-	{
-		.procname = "forwarding",
-		.data = (void *)DN_DEV_PARMS_OFFSET(forwarding),
-		.maxlen = sizeof(int),
-		.mode = 0644,
-		.proc_handler = dn_forwarding_proc,
-	},
-	{
-		.procname = "priority",
-		.data = (void *)DN_DEV_PARMS_OFFSET(priority),
-		.maxlen = sizeof(int),
-		.mode = 0644,
-		.proc_handler = proc_dointvec_minmax,
-		.extra1 = &min_priority,
-		.extra2 = &max_priority
-	},
-	{
-		.procname = "t2",
-		.data = (void *)DN_DEV_PARMS_OFFSET(t2),
-		.maxlen = sizeof(int),
-		.mode = 0644,
-		.proc_handler = proc_dointvec_minmax,
-		.extra1 = &min_t2,
-		.extra2 = &max_t2
-	},
-	{
-		.procname = "t3",
-		.data = (void *)DN_DEV_PARMS_OFFSET(t3),
-		.maxlen = sizeof(int),
-		.mode = 0644,
-		.proc_handler = proc_dointvec_minmax,
-		.extra1 = &min_t3,
-		.extra2 = &max_t3
-	},
-	{ }
-	},
-};
-
-static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *parms)
-{
-	struct dn_dev_sysctl_table *t;
-	int i;
-
-	char path[sizeof("net/decnet/conf/") + IFNAMSIZ];
-
-	t = kmemdup(&dn_dev_sysctl, sizeof(*t), GFP_KERNEL);
-	if (t == NULL)
-		return;
-
-	for(i = 0; i < ARRAY_SIZE(t->dn_dev_vars) - 1; i++) {
-		long offset = (long)t->dn_dev_vars[i].data;
-		t->dn_dev_vars[i].data = ((char *)parms) + offset;
-	}
-
-	snprintf(path, sizeof(path), "net/decnet/conf/%s",
-		dev? dev->name : parms->name);
-
-	t->dn_dev_vars[0].extra1 = (void *)dev;
-
-	t->sysctl_header = register_net_sysctl(&init_net, path, t->dn_dev_vars);
-	if (t->sysctl_header == NULL)
-		kfree(t);
-	else
-		parms->sysctl = t;
-}
-
-static void dn_dev_sysctl_unregister(struct dn_dev_parms *parms)
-{
-	if (parms->sysctl) {
-		struct dn_dev_sysctl_table *t = parms->sysctl;
-		parms->sysctl = NULL;
-		unregister_net_sysctl_table(t->sysctl_header);
-		kfree(t);
-	}
-}
-
-static int dn_forwarding_proc(struct ctl_table *table, int write,
-		void *buffer, size_t *lenp, loff_t *ppos)
-{
-#ifdef CONFIG_DECNET_ROUTER
-	struct net_device *dev = table->extra1;
-	struct dn_dev *dn_db;
-	int err;
-	int tmp, old;
-
-	if (table->extra1 == NULL)
-		return -EINVAL;
-
-	dn_db = rcu_dereference_raw(dev->dn_ptr);
-	old = dn_db->parms.forwarding;
-
-	err = proc_dointvec(table, write, buffer, lenp, ppos);
-
-	if ((err >= 0) && write) {
-		if (dn_db->parms.forwarding < 0)
-			dn_db->parms.forwarding = 0;
-		if (dn_db->parms.forwarding > 2)
-			dn_db->parms.forwarding = 2;
-		/*
-		 * What an ugly hack this is... its works, just. It
-		 * would be nice if sysctl/proc were just that little
-		 * bit more flexible so I don't have to write a special
-		 * routine, or suffer hacks like this - SJW
-		 */
-		tmp = dn_db->parms.forwarding;
-		dn_db->parms.forwarding = old;
-		if (dn_db->parms.down)
-			dn_db->parms.down(dev);
-		dn_db->parms.forwarding = tmp;
-		if (dn_db->parms.up)
-			dn_db->parms.up(dev);
-	}
-
-	return err;
-#else
-	return -EINVAL;
-#endif
-}
-
-#else /* CONFIG_SYSCTL */
-static void dn_dev_sysctl_unregister(struct dn_dev_parms *parms)
-{
-}
-static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *parms)
-{
-}
-
-#endif /* CONFIG_SYSCTL */
-
-static inline __u16 mtu2blksize(struct net_device *dev)
-{
-	u32 blksize = dev->mtu;
-	if (blksize > 0xffff)
-		blksize = 0xffff;
-
-	if (dev->type == ARPHRD_ETHER ||
-	    dev->type == ARPHRD_PPP ||
-	    dev->type == ARPHRD_IPGRE ||
-	    dev->type == ARPHRD_LOOPBACK)
-		blksize -= 2;
-
-	return (__u16)blksize;
-}
-
-static struct dn_ifaddr *dn_dev_alloc_ifa(void)
-{
-	struct dn_ifaddr *ifa;
-
-	ifa = kzalloc(sizeof(*ifa), GFP_KERNEL);
-
-	return ifa;
-}
-
-static void dn_dev_free_ifa(struct dn_ifaddr *ifa)
-{
-	kfree_rcu(ifa, rcu);
-}
-
-static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr __rcu **ifap, int destroy)
-{
-	struct dn_ifaddr *ifa1 = rtnl_dereference(*ifap);
-	unsigned char mac_addr[6];
-	struct net_device *dev = dn_db->dev;
-
-	ASSERT_RTNL();
-
-	*ifap = ifa1->ifa_next;
-
-	if (dn_db->dev->type == ARPHRD_ETHER) {
-		if (ifa1->ifa_local != dn_eth2dn(dev->dev_addr)) {
-			dn_dn2eth(mac_addr, ifa1->ifa_local);
-			dev_mc_del(dev, mac_addr);
-		}
-	}
-
-	dn_ifaddr_notify(RTM_DELADDR, ifa1);
-	blocking_notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1);
-	if (destroy) {
-		dn_dev_free_ifa(ifa1);
-
-		if (dn_db->ifa_list == NULL)
-			dn_dev_delete(dn_db->dev);
-	}
-}
-
-static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
-{
-	struct net_device *dev = dn_db->dev;
-	struct dn_ifaddr *ifa1;
-	unsigned char mac_addr[6];
-
-	ASSERT_RTNL();
-
-	/* Check for duplicates */
-	for (ifa1 = rtnl_dereference(dn_db->ifa_list);
-	     ifa1 != NULL;
-	     ifa1 = rtnl_dereference(ifa1->ifa_next)) {
-		if (ifa1->ifa_local == ifa->ifa_local)
-			return -EEXIST;
-	}
-
-	if (dev->type == ARPHRD_ETHER) {
-		if (ifa->ifa_local != dn_eth2dn(dev->dev_addr)) {
-			dn_dn2eth(mac_addr, ifa->ifa_local);
-			dev_mc_add(dev, mac_addr);
-		}
-	}
-
-	ifa->ifa_next = dn_db->ifa_list;
-	rcu_assign_pointer(dn_db->ifa_list, ifa);
-
-	dn_ifaddr_notify(RTM_NEWADDR, ifa);
-	blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa);
-
-	return 0;
-}
-
-static int dn_dev_set_ifa(struct net_device *dev, struct dn_ifaddr *ifa)
-{
-	struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
-	int rv;
-
-	if (dn_db == NULL) {
-		int err;
-		dn_db = dn_dev_create(dev, &err);
-		if (dn_db == NULL)
-			return err;
-	}
-
-	ifa->ifa_dev = dn_db;
-
-	if (dev->flags & IFF_LOOPBACK)
-		ifa->ifa_scope = RT_SCOPE_HOST;
-
-	rv = dn_dev_insert_ifa(dn_db, ifa);
-	if (rv)
-		dn_dev_free_ifa(ifa);
-	return rv;
-}
-
-
-int dn_dev_ioctl(unsigned int cmd, void __user *arg)
-{
-	char buffer[DN_IFREQ_SIZE];
-	struct ifreq *ifr = (struct ifreq *)buffer;
-	struct sockaddr_dn *sdn = (struct sockaddr_dn *)&ifr->ifr_addr;
-	struct dn_dev *dn_db;
-	struct net_device *dev;
-	struct dn_ifaddr *ifa = NULL;
-	struct dn_ifaddr __rcu **ifap = NULL;
-	int ret = 0;
-
-	if (copy_from_user(ifr, arg, DN_IFREQ_SIZE))
-		return -EFAULT;
-	ifr->ifr_name[IFNAMSIZ-1] = 0;
-
-	dev_load(&init_net, ifr->ifr_name);
-
-	switch (cmd) {
-	case SIOCGIFADDR:
-		break;
-	case SIOCSIFADDR:
-		if (!capable(CAP_NET_ADMIN))
-			return -EACCES;
-		if (sdn->sdn_family != AF_DECnet)
-			return -EINVAL;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	rtnl_lock();
-
-	if ((dev = __dev_get_by_name(&init_net, ifr->ifr_name)) == NULL) {
-		ret = -ENODEV;
-		goto done;
-	}
-
-	if ((dn_db = rtnl_dereference(dev->dn_ptr)) != NULL) {
-		for (ifap = &dn_db->ifa_list;
-		     (ifa = rtnl_dereference(*ifap)) != NULL;
-		     ifap = &ifa->ifa_next)
-			if (strcmp(ifr->ifr_name, ifa->ifa_label) == 0)
-				break;
-	}
-
-	if (ifa == NULL && cmd != SIOCSIFADDR) {
-		ret = -EADDRNOTAVAIL;
-		goto done;
-	}
-
-	switch (cmd) {
-	case SIOCGIFADDR:
-		*((__le16 *)sdn->sdn_nodeaddr) = ifa->ifa_local;
-		if (copy_to_user(arg, ifr, DN_IFREQ_SIZE))
-			ret = -EFAULT;
-		break;
-
-	case SIOCSIFADDR:
-		if (!ifa) {
-			if ((ifa = dn_dev_alloc_ifa()) == NULL) {
-				ret = -ENOBUFS;
-				break;
-			}
-			memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
-		} else {
-			if (ifa->ifa_local == dn_saddr2dn(sdn))
-				break;
-			dn_dev_del_ifa(dn_db, ifap, 0);
-		}
-
-		ifa->ifa_local = ifa->ifa_address = dn_saddr2dn(sdn);
-
-		ret = dn_dev_set_ifa(dev, ifa);
-	}
-done:
-	rtnl_unlock();
-
-	return ret;
-}
-
-struct net_device *dn_dev_get_default(void)
-{
-	struct net_device *dev;
-
-	spin_lock(&dndev_lock);
-	dev = decnet_default_device;
-	if (dev) {
-		if (dev->dn_ptr)
-			dev_hold(dev);
-		else
-			dev = NULL;
-	}
-	spin_unlock(&dndev_lock);
-
-	return dev;
-}
-
-int dn_dev_set_default(struct net_device *dev, int force)
-{
-	struct net_device *old = NULL;
-	int rv = -EBUSY;
-	if (!dev->dn_ptr)
-		return -ENODEV;
-
-	spin_lock(&dndev_lock);
-	if (force || decnet_default_device == NULL) {
-		old = decnet_default_device;
-		decnet_default_device = dev;
-		rv = 0;
-	}
-	spin_unlock(&dndev_lock);
-
-	if (old)
-		dev_put(old);
-	return rv;
-}
-
-static void dn_dev_check_default(struct net_device *dev)
-{
-	spin_lock(&dndev_lock);
-	if (dev == decnet_default_device) {
-		decnet_default_device = NULL;
-	} else {
-		dev = NULL;
-	}
-	spin_unlock(&dndev_lock);
-
-	if (dev)
-		dev_put(dev);
-}
-
-/*
- * Called with RTNL
- */
-static struct dn_dev *dn_dev_by_index(int ifindex)
-{
-	struct net_device *dev;
-	struct dn_dev *dn_dev = NULL;
-
-	dev = __dev_get_by_index(&init_net, ifindex);
-	if (dev)
-		dn_dev = rtnl_dereference(dev->dn_ptr);
-
-	return dn_dev;
-}
-
-static const struct nla_policy dn_ifa_policy[IFA_MAX+1] = {
-	[IFA_ADDRESS]		= { .type = NLA_U16 },
-	[IFA_LOCAL]		= { .type = NLA_U16 },
-	[IFA_LABEL]		= { .type = NLA_STRING,
-				    .len = IFNAMSIZ - 1 },
-	[IFA_FLAGS]		= { .type = NLA_U32 },
-};
-
-static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
-			 struct netlink_ext_ack *extack)
-{
-	struct net *net = sock_net(skb->sk);
-	struct nlattr *tb[IFA_MAX+1];
-	struct dn_dev *dn_db;
-	struct ifaddrmsg *ifm;
-	struct dn_ifaddr *ifa;
-	struct dn_ifaddr __rcu **ifap;
-	int err = -EINVAL;
-
-	if (!netlink_capable(skb, CAP_NET_ADMIN))
-		return -EPERM;
-
-	if (!net_eq(net, &init_net))
-		goto errout;
-
-	err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFA_MAX,
-				     dn_ifa_policy, extack);
-	if (err < 0)
-		goto errout;
-
-	err = -ENODEV;
-	ifm = nlmsg_data(nlh);
-	if ((dn_db = dn_dev_by_index(ifm->ifa_index)) == NULL)
-		goto errout;
-
-	err = -EADDRNOTAVAIL;
-	for (ifap = &dn_db->ifa_list;
-	     (ifa = rtnl_dereference(*ifap)) != NULL;
-	     ifap = &ifa->ifa_next) {
-		if (tb[IFA_LOCAL] &&
-		    nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2))
-			continue;
-
-		if (tb[IFA_LABEL] && nla_strcmp(tb[IFA_LABEL], ifa->ifa_label))
-			continue;
-
-		dn_dev_del_ifa(dn_db, ifap, 1);
-		return 0;
-	}
-
-errout:
-	return err;
-}
-
-static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
-			 struct netlink_ext_ack *extack)
-{
-	struct net *net = sock_net(skb->sk);
-	struct nlattr *tb[IFA_MAX+1];
-	struct net_device *dev;
-	struct dn_dev *dn_db;
-	struct ifaddrmsg *ifm;
-	struct dn_ifaddr *ifa;
-	int err;
-
-	if (!netlink_capable(skb, CAP_NET_ADMIN))
-		return -EPERM;
-
-	if (!net_eq(net, &init_net))
-		return -EINVAL;
-
-	err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFA_MAX,
-				     dn_ifa_policy, extack);
-	if (err < 0)
-		return err;
-
-	if (tb[IFA_LOCAL] == NULL)
-		return -EINVAL;
-
-	ifm = nlmsg_data(nlh);
-	if ((dev = __dev_get_by_index(&init_net, ifm->ifa_index)) == NULL)
-		return -ENODEV;
-
-	if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL) {
-		dn_db = dn_dev_create(dev, &err);
-		if (!dn_db)
-			return err;
-	}
-
-	if ((ifa = dn_dev_alloc_ifa()) == NULL)
-		return -ENOBUFS;
-
-	if (tb[IFA_ADDRESS] == NULL)
-		tb[IFA_ADDRESS] = tb[IFA_LOCAL];
-
-	ifa->ifa_local = nla_get_le16(tb[IFA_LOCAL]);
-	ifa->ifa_address = nla_get_le16(tb[IFA_ADDRESS]);
-	ifa->ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) :
-					 ifm->ifa_flags;
-	ifa->ifa_scope = ifm->ifa_scope;
-	ifa->ifa_dev = dn_db;
-
-	if (tb[IFA_LABEL])
-		nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
-	else
-		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
-
-	err = dn_dev_insert_ifa(dn_db, ifa);
-	if (err)
-		dn_dev_free_ifa(ifa);
-
-	return err;
-}
-
-static inline size_t dn_ifaddr_nlmsg_size(void)
-{
-	return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
-	       + nla_total_size(IFNAMSIZ) /* IFA_LABEL */
-	       + nla_total_size(2) /* IFA_ADDRESS */
-	       + nla_total_size(2) /* IFA_LOCAL */
-	       + nla_total_size(4); /* IFA_FLAGS */
-}
-
-static int dn_nl_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa,
-			     u32 portid, u32 seq, int event, unsigned int flags)
-{
-	struct ifaddrmsg *ifm;
-	struct nlmsghdr *nlh;
-	u32 ifa_flags = ifa->ifa_flags | IFA_F_PERMANENT;
-
-	nlh = nlmsg_put(skb, portid, seq, event, sizeof(*ifm), flags);
-	if (nlh == NULL)
-		return -EMSGSIZE;
-
-	ifm = nlmsg_data(nlh);
-	ifm->ifa_family = AF_DECnet;
-	ifm->ifa_prefixlen = 16;
-	ifm->ifa_flags = ifa_flags;
-	ifm->ifa_scope = ifa->ifa_scope;
-	ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
-
-	if ((ifa->ifa_address &&
-	     nla_put_le16(skb, IFA_ADDRESS, ifa->ifa_address)) ||
-	    (ifa->ifa_local &&
-	     nla_put_le16(skb, IFA_LOCAL, ifa->ifa_local)) ||
-	    (ifa->ifa_label[0] &&
-	     nla_put_string(skb, IFA_LABEL, ifa->ifa_label)) ||
-	     nla_put_u32(skb, IFA_FLAGS, ifa_flags))
-		goto nla_put_failure;
-	nlmsg_end(skb, nlh);
-	return 0;
-
-nla_put_failure:
-	nlmsg_cancel(skb, nlh);
-	return -EMSGSIZE;
-}
-
-static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa)
-{
-	struct sk_buff *skb;
-	int err = -ENOBUFS;
-
-	skb = alloc_skb(dn_ifaddr_nlmsg_size(), GFP_KERNEL);
-	if (skb == NULL)
-		goto errout;
-
-	err = dn_nl_fill_ifaddr(skb, ifa, 0, 0, event, 0);
-	if (err < 0) {
-		/* -EMSGSIZE implies BUG in dn_ifaddr_nlmsg_size() */
-		WARN_ON(err == -EMSGSIZE);
-		kfree_skb(skb);
-		goto errout;
-	}
-	rtnl_notify(skb, &init_net, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL);
-	return;
-errout:
-	if (err < 0)
-		rtnl_set_sk_err(&init_net, RTNLGRP_DECnet_IFADDR, err);
-}
-
-static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
-{
-	struct net *net = sock_net(skb->sk);
-	int idx, dn_idx = 0, skip_ndevs, skip_naddr;
-	struct net_device *dev;
-	struct dn_dev *dn_db;
-	struct dn_ifaddr *ifa;
-
-	if (!net_eq(net, &init_net))
-		return 0;
-
-	skip_ndevs = cb->args[0];
-	skip_naddr = cb->args[1];
-
-	idx = 0;
-	rcu_read_lock();
-	for_each_netdev_rcu(&init_net, dev) {
-		if (idx < skip_ndevs)
-			goto cont;
-		else if (idx > skip_ndevs) {
-			/* Only skip over addresses for first dev dumped
-			 * in this iteration (idx == skip_ndevs) */
-			skip_naddr = 0;
-		}
-
-		if ((dn_db = rcu_dereference(dev->dn_ptr)) == NULL)
-			goto cont;
-
-		for (ifa = rcu_dereference(dn_db->ifa_list), dn_idx = 0; ifa;
-		     ifa = rcu_dereference(ifa->ifa_next), dn_idx++) {
-			if (dn_idx < skip_naddr)
-				continue;
-
-			if (dn_nl_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).portid,
-					      cb->nlh->nlmsg_seq, RTM_NEWADDR,
-					      NLM_F_MULTI) < 0)
-				goto done;
-		}
-cont:
-		idx++;
-	}
-done:
-	rcu_read_unlock();
-	cb->args[0] = idx;
-	cb->args[1] = dn_idx;
-
-	return skb->len;
-}
-
-static int dn_dev_get_first(struct net_device *dev, __le16 *addr)
-{
-	struct dn_dev *dn_db;
-	struct dn_ifaddr *ifa;
-	int rv = -ENODEV;
-
-	rcu_read_lock();
-	dn_db = rcu_dereference(dev->dn_ptr);
-	if (dn_db == NULL)
-		goto out;
-
-	ifa = rcu_dereference(dn_db->ifa_list);
-	if (ifa != NULL) {
-		*addr = ifa->ifa_local;
-		rv = 0;
-	}
-out:
-	rcu_read_unlock();
-	return rv;
-}
-
-/*
- * Find a default address to bind to.
- *
- * This is one of those areas where the initial VMS concepts don't really
- * map onto the Linux concepts, and since we introduced multiple addresses
- * per interface we have to cope with slightly odd ways of finding out what
- * "our address" really is. Mostly it's not a problem; for this we just guess
- * a sensible default. Eventually the routing code will take care of all the
- * nasties for us I hope.
- */
-int dn_dev_bind_default(__le16 *addr)
-{
-	struct net_device *dev;
-	int rv;
-	dev = dn_dev_get_default();
-last_chance:
-	if (dev) {
-		rv = dn_dev_get_first(dev, addr);
-		dev_put(dev);
-		if (rv == 0 || dev == init_net.loopback_dev)
-			return rv;
-	}
-	dev = init_net.loopback_dev;
-	dev_hold(dev);
-	goto last_chance;
-}
-
-static void dn_send_endnode_hello(struct net_device *dev, struct dn_ifaddr *ifa)
-{
-	struct endnode_hello_message *msg;
-	struct sk_buff *skb = NULL;
-	__le16 *pktlen;
-	struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
-
-	if ((skb = dn_alloc_skb(NULL, sizeof(*msg), GFP_ATOMIC)) == NULL)
-		return;
-
-	skb->dev = dev;
-
-	msg = skb_put(skb, sizeof(*msg));
-
-	msg->msgflg  = 0x0D;
-	memcpy(msg->tiver, dn_eco_version, 3);
-	dn_dn2eth(msg->id, ifa->ifa_local);
-	msg->iinfo   = DN_RT_INFO_ENDN;
-	msg->blksize = cpu_to_le16(mtu2blksize(dev));
-	msg->area    = 0x00;
-	memset(msg->seed, 0, 8);
-	memcpy(msg->neighbor, dn_hiord, ETH_ALEN);
-
-	if (dn_db->router) {
-		struct dn_neigh *dn = (struct dn_neigh *)dn_db->router;
-		dn_dn2eth(msg->neighbor, dn->addr);
-	}
-
-	msg->timer   = cpu_to_le16((unsigned short)dn_db->parms.t3);
-	msg->mpd     = 0x00;
-	msg->datalen = 0x02;
-	memset(msg->data, 0xAA, 2);
-
-	pktlen = skb_push(skb, 2);
-	*pktlen = cpu_to_le16(skb->len - 2);
-
-	skb_reset_network_header(skb);
-
-	dn_rt_finish_output(skb, dn_rt_all_rt_mcast, msg->id);
-}
-
-
-#define DRDELAY (5 * HZ)
-
-static int dn_am_i_a_router(struct dn_neigh *dn, struct dn_dev *dn_db, struct dn_ifaddr *ifa)
-{
-	/* First check time since device went up */
-	if (time_before(jiffies, dn_db->uptime + DRDELAY))
-		return 0;
-
-	/* If there is no router, then yes... */
-	if (!dn_db->router)
-		return 1;
-
-	/* otherwise only if we have a higher priority or.. */
-	if (dn->priority < dn_db->parms.priority)
-		return 1;
-
-	/* if we have equal priority and a higher node number */
-	if (dn->priority != dn_db->parms.priority)
-		return 0;
-
-	if (le16_to_cpu(dn->addr) < le16_to_cpu(ifa->ifa_local))
-		return 1;
-
-	return 0;
-}
-
-static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa)
-{
-	int n;
-	struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
-	struct dn_neigh *dn = (struct dn_neigh *)dn_db->router;
-	struct sk_buff *skb;
-	size_t size;
-	unsigned char *ptr;
-	unsigned char *i1, *i2;
-	__le16 *pktlen;
-	char *src;
-
-	if (mtu2blksize(dev) < (26 + 7))
-		return;
-
-	n = mtu2blksize(dev) - 26;
-	n /= 7;
-
-	if (n > 32)
-		n = 32;
-
-	size = 2 + 26 + 7 * n;
-
-	if ((skb = dn_alloc_skb(NULL, size, GFP_ATOMIC)) == NULL)
-		return;
-
-	skb->dev = dev;
-	ptr = skb_put(skb, size);
-
-	*ptr++ = DN_RT_PKT_CNTL | DN_RT_PKT_ERTH;
-	*ptr++ = 2; /* ECO */
-	*ptr++ = 0;
-	*ptr++ = 0;
-	dn_dn2eth(ptr, ifa->ifa_local);
-	src = ptr;
-	ptr += ETH_ALEN;
-	*ptr++ = dn_db->parms.forwarding == 1 ?
-			DN_RT_INFO_L1RT : DN_RT_INFO_L2RT;
-	*((__le16 *)ptr) = cpu_to_le16(mtu2blksize(dev));
-	ptr += 2;
-	*ptr++ = dn_db->parms.priority; /* Priority */
-	*ptr++ = 0; /* Area: Reserved */
-	*((__le16 *)ptr) = cpu_to_le16((unsigned short)dn_db->parms.t3);
-	ptr += 2;
-	*ptr++ = 0; /* MPD: Reserved */
-	i1 = ptr++;
-	memset(ptr, 0, 7); /* Name: Reserved */
-	ptr += 7;
-	i2 = ptr++;
-
-	n = dn_neigh_elist(dev, ptr, n);
-
-	*i2 = 7 * n;
-	*i1 = 8 + *i2;
-
-	skb_trim(skb, (27 + *i2));
-
-	pktlen = skb_push(skb, 2);
-	*pktlen = cpu_to_le16(skb->len - 2);
-
-	skb_reset_network_header(skb);
-
-	if (dn_am_i_a_router(dn, dn_db, ifa)) {
-		struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
-		if (skb2) {
-			dn_rt_finish_output(skb2, dn_rt_all_end_mcast, src);
-		}
-	}
-
-	dn_rt_finish_output(skb, dn_rt_all_rt_mcast, src);
-}
-
-static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa)
-{
-	struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
-
-	if (dn_db->parms.forwarding == 0)
-		dn_send_endnode_hello(dev, ifa);
-	else
-		dn_send_router_hello(dev, ifa);
-}
-
-static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa)
-{
-	int tdlen = 16;
-	int size = dev->hard_header_len + 2 + 4 + tdlen;
-	struct sk_buff *skb = dn_alloc_skb(NULL, size, GFP_ATOMIC);
-	int i;
-	unsigned char *ptr;
-	char src[ETH_ALEN];
-
-	if (skb == NULL)
-		return ;
-
-	skb->dev = dev;
-	skb_push(skb, dev->hard_header_len);
-	ptr = skb_put(skb, 2 + 4 + tdlen);
-
-	*ptr++ = DN_RT_PKT_HELO;
-	*((__le16 *)ptr) = ifa->ifa_local;
-	ptr += 2;
-	*ptr++ = tdlen;
-
-	for(i = 0; i < tdlen; i++)
-		*ptr++ = 0252;
-
-	dn_dn2eth(src, ifa->ifa_local);
-	dn_rt_finish_output(skb, dn_rt_all_rt_mcast, src);
-}
-
-static int dn_eth_up(struct net_device *dev)
-{
-	struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
-
-	if (dn_db->parms.forwarding == 0)
-		dev_mc_add(dev, dn_rt_all_end_mcast);
-	else
-		dev_mc_add(dev, dn_rt_all_rt_mcast);
-
-	dn_db->use_long = 1;
-
-	return 0;
-}
-
-static void dn_eth_down(struct net_device *dev)
-{
-	struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
-
-	if (dn_db->parms.forwarding == 0)
-		dev_mc_del(dev, dn_rt_all_end_mcast);
-	else
-		dev_mc_del(dev, dn_rt_all_rt_mcast);
-}
-
-static void dn_dev_set_timer(struct net_device *dev);
-
-static void dn_dev_timer_func(struct timer_list *t)
-{
-	struct dn_dev *dn_db = from_timer(dn_db, t, timer);
-	struct net_device *dev;
-	struct dn_ifaddr *ifa;
-
-	rcu_read_lock();
-	dev = dn_db->dev;
-	if (dn_db->t3 <= dn_db->parms.t2) {
-		if (dn_db->parms.timer3) {
-			for (ifa = rcu_dereference(dn_db->ifa_list);
-			     ifa;
-			     ifa = rcu_dereference(ifa->ifa_next)) {
-				if (!(ifa->ifa_flags & IFA_F_SECONDARY))
-					dn_db->parms.timer3(dev, ifa);
-			}
-		}
-		dn_db->t3 = dn_db->parms.t3;
-	} else {
-		dn_db->t3 -= dn_db->parms.t2;
-	}
-	rcu_read_unlock();
-	dn_dev_set_timer(dev);
-}
-
-static void dn_dev_set_timer(struct net_device *dev)
-{
-	struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
-
-	if (dn_db->parms.t2 > dn_db->parms.t3)
-		dn_db->parms.t2 = dn_db->parms.t3;
-
-	dn_db->timer.expires = jiffies + (dn_db->parms.t2 * HZ);
-
-	add_timer(&dn_db->timer);
-}
-
-static struct dn_dev *dn_dev_create(struct net_device *dev, int *err)
-{
-	int i;
-	struct dn_dev_parms *p = dn_dev_list;
-	struct dn_dev *dn_db;
-
-	for(i = 0; i < DN_DEV_LIST_SIZE; i++, p++) {
-		if (p->type == dev->type)
-			break;
-	}
-
-	*err = -ENODEV;
-	if (i == DN_DEV_LIST_SIZE)
-		return NULL;
-
-	*err = -ENOBUFS;
-	if ((dn_db = kzalloc(sizeof(struct dn_dev), GFP_ATOMIC)) == NULL)
-		return NULL;
-
-	memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms));
-
-	rcu_assign_pointer(dev->dn_ptr, dn_db);
-	dn_db->dev = dev;
-	timer_setup(&dn_db->timer, dn_dev_timer_func, 0);
-
-	dn_db->uptime = jiffies;
-
-	dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table);
-	if (!dn_db->neigh_parms) {
-		RCU_INIT_POINTER(dev->dn_ptr, NULL);
-		kfree(dn_db);
-		return NULL;
-	}
-
-	if (dn_db->parms.up) {
-		if (dn_db->parms.up(dev) < 0) {
-			neigh_parms_release(&dn_neigh_table, dn_db->neigh_parms);
-			dev->dn_ptr = NULL;
-			kfree(dn_db);
-			return NULL;
-		}
-	}
-
-	dn_dev_sysctl_register(dev, &dn_db->parms);
-
-	dn_dev_set_timer(dev);
-
-	*err = 0;
-	return dn_db;
-}
-
-
-/*
- * This processes a device up event. We only start up
- * the loopback device & ethernet devices with correct
- * MAC addresses automatically. Others must be started
- * specifically.
- *
- * FIXME: How should we configure the loopback address ? If we could dispense
- * with using decnet_address here and for autobind, it will be one less thing
- * for users to worry about setting up.
- */
-
-void dn_dev_up(struct net_device *dev)
-{
-	struct dn_ifaddr *ifa;
-	__le16 addr = decnet_address;
-	int maybe_default = 0;
-	struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
-
-	if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK))
-		return;
-
-	/*
-	 * Need to ensure that loopback device has a dn_db attached to it
-	 * to allow creation of neighbours against it, even though it might
-	 * not have a local address of its own. Might as well do the same for
-	 * all autoconfigured interfaces.
-	 */
-	if (dn_db == NULL) {
-		int err;
-		dn_db = dn_dev_create(dev, &err);
-		if (dn_db == NULL)
-			return;
-	}
-
-	if (dev->type == ARPHRD_ETHER) {
-		if (memcmp(dev->dev_addr, dn_hiord, 4) != 0)
-			return;
-		addr = dn_eth2dn(dev->dev_addr);
-		maybe_default = 1;
-	}
-
-	if (addr == 0)
-		return;
-
-	if ((ifa = dn_dev_alloc_ifa()) == NULL)
-		return;
-
-	ifa->ifa_local = ifa->ifa_address = addr;
-	ifa->ifa_flags = 0;
-	ifa->ifa_scope = RT_SCOPE_UNIVERSE;
-	strcpy(ifa->ifa_label, dev->name);
-
-	dn_dev_set_ifa(dev, ifa);
-
-	/*
-	 * Automagically set the default device to the first automatically
-	 * configured ethernet card in the system.
-	 */
-	if (maybe_default) {
-		dev_hold(dev);
-		if (dn_dev_set_default(dev, 0))
-			dev_put(dev);
-	}
-}
-
-static void dn_dev_delete(struct net_device *dev)
-{
-	struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
-
-	if (dn_db == NULL)
-		return;
-
-	del_timer_sync(&dn_db->timer);
-	dn_dev_sysctl_unregister(&dn_db->parms);
-	dn_dev_check_default(dev);
-	neigh_ifdown(&dn_neigh_table, dev);
-
-	if (dn_db->parms.down)
-		dn_db->parms.down(dev);
-
-	dev->dn_ptr = NULL;
-
-	neigh_parms_release(&dn_neigh_table, dn_db->neigh_parms);
-	neigh_ifdown(&dn_neigh_table, dev);
-
-	if (dn_db->router)
-		neigh_release(dn_db->router);
-	if (dn_db->peer)
-		neigh_release(dn_db->peer);
-
-	kfree(dn_db);
-}
-
-void dn_dev_down(struct net_device *dev)
-{
-	struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
-	struct dn_ifaddr *ifa;
-
-	if (dn_db == NULL)
-		return;
-
-	while ((ifa = rtnl_dereference(dn_db->ifa_list)) != NULL) {
-		dn_dev_del_ifa(dn_db, &dn_db->ifa_list, 0);
-		dn_dev_free_ifa(ifa);
-	}
-
-	dn_dev_delete(dev);
-}
-
-void dn_dev_init_pkt(struct sk_buff *skb)
-{
-}
-
-void dn_dev_veri_pkt(struct sk_buff *skb)
-{
-}
-
-void dn_dev_hello(struct sk_buff *skb)
-{
-}
-
-void dn_dev_devices_off(void)
-{
-	struct net_device *dev;
-
-	rtnl_lock();
-	for_each_netdev(&init_net, dev)
-		dn_dev_down(dev);
-	rtnl_unlock();
-
-}
-
-void dn_dev_devices_on(void)
-{
-	struct net_device *dev;
-
-	rtnl_lock();
-	for_each_netdev(&init_net, dev) {
-		if (dev->flags & IFF_UP)
-			dn_dev_up(dev);
-	}
-	rtnl_unlock();
-}
-
-int register_dnaddr_notifier(struct notifier_block *nb)
-{
-	return blocking_notifier_chain_register(&dnaddr_chain, nb);
-}
-
-int unregister_dnaddr_notifier(struct notifier_block *nb)
-{
-	return blocking_notifier_chain_unregister(&dnaddr_chain, nb);
-}
-
-#ifdef CONFIG_PROC_FS
-static inline int is_dn_dev(struct net_device *dev)
-{
-	return dev->dn_ptr != NULL;
-}
-
-static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos)
-	__acquires(RCU)
-{
-	int i;
-	struct net_device *dev;
-
-	rcu_read_lock();
-
-	if (*pos == 0)
-		return SEQ_START_TOKEN;
-
-	i = 1;
-	for_each_netdev_rcu(&init_net, dev) {
-		if (!is_dn_dev(dev))
-			continue;
-
-		if (i++ == *pos)
-			return dev;
-	}
-
-	return NULL;
-}
-
-static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	struct net_device *dev;
-
-	++*pos;
-
-	dev = v;
-	if (v == SEQ_START_TOKEN)
-		dev = net_device_entry(&init_net.dev_base_head);
-
-	for_each_netdev_continue_rcu(&init_net, dev) {
-		if (!is_dn_dev(dev))
-			continue;
-
-		return dev;
-	}
-
-	return NULL;
-}
-
-static void dn_dev_seq_stop(struct seq_file *seq, void *v)
-	__releases(RCU)
-{
-	rcu_read_unlock();
-}
-
-static char *dn_type2asc(char type)
-{
-	switch (type) {
-	case DN_DEV_BCAST:
-		return "B";
-	case DN_DEV_UCAST:
-		return "U";
-	case DN_DEV_MPOINT:
-		return "M";
-	}
-
-	return "?";
-}
-
-static int dn_dev_seq_show(struct seq_file *seq, void *v)
-{
-	if (v == SEQ_START_TOKEN)
-		seq_puts(seq, "Name     Flags T1   Timer1 T3   Timer3 BlkSize Pri State DevType    Router Peer\n");
-	else {
-		struct net_device *dev = v;
-		char peer_buf[DN_ASCBUF_LEN];
-		char router_buf[DN_ASCBUF_LEN];
-		struct dn_dev *dn_db = rcu_dereference(dev->dn_ptr);
-
-		seq_printf(seq, "%-8s %1s     %04u %04u   %04lu %04lu"
-				"   %04hu    %03d %02x    %-10s %-7s %-7s\n",
-				dev->name,
-				dn_type2asc(dn_db->parms.mode),
-				0, 0,
-				dn_db->t3, dn_db->parms.t3,
-				mtu2blksize(dev),
-				dn_db->parms.priority,
-				dn_db->parms.state, dn_db->parms.name,
-				dn_db->router ? dn_addr2asc(le16_to_cpu(*(__le16 *)dn_db->router->primary_key), router_buf) : "",
-				dn_db->peer ? dn_addr2asc(le16_to_cpu(*(__le16 *)dn_db->peer->primary_key), peer_buf) : "");
-	}
-	return 0;
-}
-
-static const struct seq_operations dn_dev_seq_ops = {
-	.start	= dn_dev_seq_start,
-	.next	= dn_dev_seq_next,
-	.stop	= dn_dev_seq_stop,
-	.show	= dn_dev_seq_show,
-};
-#endif /* CONFIG_PROC_FS */
-
-static int addr[2];
-module_param_array(addr, int, NULL, 0444);
-MODULE_PARM_DESC(addr, "The DECnet address of this machine: area,node");
-
-void __init dn_dev_init(void)
-{
-	if (addr[0] > 63 || addr[0] < 0) {
-		printk(KERN_ERR "DECnet: Area must be between 0 and 63");
-		return;
-	}
-
-	if (addr[1] > 1023 || addr[1] < 0) {
-		printk(KERN_ERR "DECnet: Node must be between 0 and 1023");
-		return;
-	}
-
-	decnet_address = cpu_to_le16((addr[0] << 10) | addr[1]);
-
-	dn_dev_devices_on();
-
-	rtnl_register_module(THIS_MODULE, PF_DECnet, RTM_NEWADDR,
-			     dn_nl_newaddr, NULL, 0);
-	rtnl_register_module(THIS_MODULE, PF_DECnet, RTM_DELADDR,
-			     dn_nl_deladdr, NULL, 0);
-	rtnl_register_module(THIS_MODULE, PF_DECnet, RTM_GETADDR,
-			     NULL, dn_nl_dump_ifaddr, 0);
-
-	proc_create_seq("decnet_dev", 0444, init_net.proc_net, &dn_dev_seq_ops);
-
-#ifdef CONFIG_SYSCTL
-	{
-		int i;
-		for(i = 0; i < DN_DEV_LIST_SIZE; i++)
-			dn_dev_sysctl_register(NULL, &dn_dev_list[i]);
-	}
-#endif /* CONFIG_SYSCTL */
-}
-
-void __exit dn_dev_cleanup(void)
-{
-#ifdef CONFIG_SYSCTL
-	{
-		int i;
-		for(i = 0; i < DN_DEV_LIST_SIZE; i++)
-			dn_dev_sysctl_unregister(&dn_dev_list[i]);
-	}
-#endif /* CONFIG_SYSCTL */
-
-	remove_proc_entry("decnet_dev", init_net.proc_net);
-
-	dn_dev_devices_off();
-}
diff --git a/kernel/net/decnet/dn_fib.c b/kernel/net/decnet/dn_fib.c
deleted file mode 100644
index 77fbf8e..0000000
--- a/kernel/net/decnet/dn_fib.c
+++ /dev/null
@@ -1,799 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * DECnet       An implementation of the DECnet protocol suite for the LINUX
- *              operating system.  DECnet is implemented using the  BSD Socket
- *              interface as the means of communication with the user level.
- *
- *              DECnet Routing Forwarding Information Base (Glue/Info List)
- *
- * Author:      Steve Whitehouse <SteveW@ACM.org>
- *
- *
- * Changes:
- *              Alexey Kuznetsov : SMP locking changes
- *              Steve Whitehouse : Rewrote it... Well to be more correct, I
- *                                 copied most of it from the ipv4 fib code.
- *              Steve Whitehouse : Updated it in style and fixed a few bugs
- *                                 which were fixed in the ipv4 code since
- *                                 this code was copied from it.
- *
- */
-#include <linux/string.h>
-#include <linux/net.h>
-#include <linux/socket.h>
-#include <linux/slab.h>
-#include <linux/sockios.h>
-#include <linux/init.h>
-#include <linux/skbuff.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <linux/proc_fs.h>
-#include <linux/netdevice.h>
-#include <linux/timer.h>
-#include <linux/spinlock.h>
-#include <linux/atomic.h>
-#include <linux/uaccess.h>
-#include <net/neighbour.h>
-#include <net/dst.h>
-#include <net/flow.h>
-#include <net/fib_rules.h>
-#include <net/dn.h>
-#include <net/dn_route.h>
-#include <net/dn_fib.h>
-#include <net/dn_neigh.h>
-#include <net/dn_dev.h>
-#include <net/rtnh.h>
-
-#define RT_MIN_TABLE 1
-
-#define for_fib_info() { struct dn_fib_info *fi;\
-	for(fi = dn_fib_info_list; fi; fi = fi->fib_next)
-#define endfor_fib_info() }
-
-#define for_nexthops(fi) { int nhsel; const struct dn_fib_nh *nh;\
-	for(nhsel = 0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++)
-
-#define change_nexthops(fi) { int nhsel; struct dn_fib_nh *nh;\
-	for(nhsel = 0, nh = (struct dn_fib_nh *)((fi)->fib_nh); nhsel < (fi)->fib_nhs; nh++, nhsel++)
-
-#define endfor_nexthops(fi) }
-
-static DEFINE_SPINLOCK(dn_fib_multipath_lock);
-static struct dn_fib_info *dn_fib_info_list;
-static DEFINE_SPINLOCK(dn_fib_info_lock);
-
-static struct
-{
-	int error;
-	u8 scope;
-} dn_fib_props[RTN_MAX+1] = {
-	[RTN_UNSPEC] =      { .error = 0,       .scope = RT_SCOPE_NOWHERE },
-	[RTN_UNICAST] =     { .error = 0,       .scope = RT_SCOPE_UNIVERSE },
-	[RTN_LOCAL] =       { .error = 0,       .scope = RT_SCOPE_HOST },
-	[RTN_BROADCAST] =   { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE },
-	[RTN_ANYCAST] =     { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE },
-	[RTN_MULTICAST] =   { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE },
-	[RTN_BLACKHOLE] =   { .error = -EINVAL, .scope = RT_SCOPE_UNIVERSE },
-	[RTN_UNREACHABLE] = { .error = -EHOSTUNREACH, .scope = RT_SCOPE_UNIVERSE },
-	[RTN_PROHIBIT] =    { .error = -EACCES, .scope = RT_SCOPE_UNIVERSE },
-	[RTN_THROW] =       { .error = -EAGAIN, .scope = RT_SCOPE_UNIVERSE },
-	[RTN_NAT] =         { .error = 0,       .scope = RT_SCOPE_NOWHERE },
-	[RTN_XRESOLVE] =    { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE },
-};
-
-static int dn_fib_sync_down(__le16 local, struct net_device *dev, int force);
-static int dn_fib_sync_up(struct net_device *dev);
-
-void dn_fib_free_info(struct dn_fib_info *fi)
-{
-	if (fi->fib_dead == 0) {
-		printk(KERN_DEBUG "DECnet: BUG! Attempt to free alive dn_fib_info\n");
-		return;
-	}
-
-	change_nexthops(fi) {
-		if (nh->nh_dev)
-			dev_put(nh->nh_dev);
-		nh->nh_dev = NULL;
-	} endfor_nexthops(fi);
-	kfree(fi);
-}
-
-void dn_fib_release_info(struct dn_fib_info *fi)
-{
-	spin_lock(&dn_fib_info_lock);
-	if (fi && --fi->fib_treeref == 0) {
-		if (fi->fib_next)
-			fi->fib_next->fib_prev = fi->fib_prev;
-		if (fi->fib_prev)
-			fi->fib_prev->fib_next = fi->fib_next;
-		if (fi == dn_fib_info_list)
-			dn_fib_info_list = fi->fib_next;
-		fi->fib_dead = 1;
-		dn_fib_info_put(fi);
-	}
-	spin_unlock(&dn_fib_info_lock);
-}
-
-static inline int dn_fib_nh_comp(const struct dn_fib_info *fi, const struct dn_fib_info *ofi)
-{
-	const struct dn_fib_nh *onh = ofi->fib_nh;
-
-	for_nexthops(fi) {
-		if (nh->nh_oif != onh->nh_oif ||
-			nh->nh_gw != onh->nh_gw ||
-			nh->nh_scope != onh->nh_scope ||
-			nh->nh_weight != onh->nh_weight ||
-			((nh->nh_flags^onh->nh_flags)&~RTNH_F_DEAD))
-				return -1;
-		onh++;
-	} endfor_nexthops(fi);
-	return 0;
-}
-
-static inline struct dn_fib_info *dn_fib_find_info(const struct dn_fib_info *nfi)
-{
-	for_fib_info() {
-		if (fi->fib_nhs != nfi->fib_nhs)
-			continue;
-		if (nfi->fib_protocol == fi->fib_protocol &&
-			nfi->fib_prefsrc == fi->fib_prefsrc &&
-			nfi->fib_priority == fi->fib_priority &&
-			memcmp(nfi->fib_metrics, fi->fib_metrics, sizeof(fi->fib_metrics)) == 0 &&
-			((nfi->fib_flags^fi->fib_flags)&~RTNH_F_DEAD) == 0 &&
-			(nfi->fib_nhs == 0 || dn_fib_nh_comp(fi, nfi) == 0))
-				return fi;
-	} endfor_fib_info();
-	return NULL;
-}
-
-static int dn_fib_count_nhs(const struct nlattr *attr)
-{
-	struct rtnexthop *nhp = nla_data(attr);
-	int nhs = 0, nhlen = nla_len(attr);
-
-	while (rtnh_ok(nhp, nhlen)) {
-		nhs++;
-		nhp = rtnh_next(nhp, &nhlen);
-	}
-
-	/* leftover implies invalid nexthop configuration, discard it */
-	return nhlen > 0 ? 0 : nhs;
-}
-
-static int dn_fib_get_nhs(struct dn_fib_info *fi, const struct nlattr *attr,
-			  const struct rtmsg *r)
-{
-	struct rtnexthop *nhp = nla_data(attr);
-	int nhlen = nla_len(attr);
-
-	change_nexthops(fi) {
-		int attrlen;
-
-		if (!rtnh_ok(nhp, nhlen))
-			return -EINVAL;
-
-		nh->nh_flags  = (r->rtm_flags&~0xFF) | nhp->rtnh_flags;
-		nh->nh_oif    = nhp->rtnh_ifindex;
-		nh->nh_weight = nhp->rtnh_hops + 1;
-
-		attrlen = rtnh_attrlen(nhp);
-		if (attrlen > 0) {
-			struct nlattr *gw_attr;
-
-			gw_attr = nla_find((struct nlattr *) (nhp + 1), attrlen, RTA_GATEWAY);
-			nh->nh_gw = gw_attr ? nla_get_le16(gw_attr) : 0;
-		}
-
-		nhp = rtnh_next(nhp, &nhlen);
-	} endfor_nexthops(fi);
-
-	return 0;
-}
-
-
-static int dn_fib_check_nh(const struct rtmsg *r, struct dn_fib_info *fi, struct dn_fib_nh *nh)
-{
-	int err;
-
-	if (nh->nh_gw) {
-		struct flowidn fld;
-		struct dn_fib_res res;
-
-		if (nh->nh_flags&RTNH_F_ONLINK) {
-			struct net_device *dev;
-
-			if (r->rtm_scope >= RT_SCOPE_LINK)
-				return -EINVAL;
-			if (dnet_addr_type(nh->nh_gw) != RTN_UNICAST)
-				return -EINVAL;
-			if ((dev = __dev_get_by_index(&init_net, nh->nh_oif)) == NULL)
-				return -ENODEV;
-			if (!(dev->flags&IFF_UP))
-				return -ENETDOWN;
-			nh->nh_dev = dev;
-			dev_hold(dev);
-			nh->nh_scope = RT_SCOPE_LINK;
-			return 0;
-		}
-
-		memset(&fld, 0, sizeof(fld));
-		fld.daddr = nh->nh_gw;
-		fld.flowidn_oif = nh->nh_oif;
-		fld.flowidn_scope = r->rtm_scope + 1;
-
-		if (fld.flowidn_scope < RT_SCOPE_LINK)
-			fld.flowidn_scope = RT_SCOPE_LINK;
-
-		if ((err = dn_fib_lookup(&fld, &res)) != 0)
-			return err;
-
-		err = -EINVAL;
-		if (res.type != RTN_UNICAST && res.type != RTN_LOCAL)
-			goto out;
-		nh->nh_scope = res.scope;
-		nh->nh_oif = DN_FIB_RES_OIF(res);
-		nh->nh_dev = DN_FIB_RES_DEV(res);
-		if (nh->nh_dev == NULL)
-			goto out;
-		dev_hold(nh->nh_dev);
-		err = -ENETDOWN;
-		if (!(nh->nh_dev->flags & IFF_UP))
-			goto out;
-		err = 0;
-out:
-		dn_fib_res_put(&res);
-		return err;
-	} else {
-		struct net_device *dev;
-
-		if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK))
-			return -EINVAL;
-
-		dev = __dev_get_by_index(&init_net, nh->nh_oif);
-		if (dev == NULL || dev->dn_ptr == NULL)
-			return -ENODEV;
-		if (!(dev->flags&IFF_UP))
-			return -ENETDOWN;
-		nh->nh_dev = dev;
-		dev_hold(nh->nh_dev);
-		nh->nh_scope = RT_SCOPE_HOST;
-	}
-
-	return 0;
-}
-
-
-struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, struct nlattr *attrs[],
-				       const struct nlmsghdr *nlh, int *errp)
-{
-	int err;
-	struct dn_fib_info *fi = NULL;
-	struct dn_fib_info *ofi;
-	int nhs = 1;
-
-	if (r->rtm_type > RTN_MAX)
-		goto err_inval;
-
-	if (dn_fib_props[r->rtm_type].scope > r->rtm_scope)
-		goto err_inval;
-
-	if (attrs[RTA_MULTIPATH] &&
-	    (nhs = dn_fib_count_nhs(attrs[RTA_MULTIPATH])) == 0)
-		goto err_inval;
-
-	fi = kzalloc(struct_size(fi, fib_nh, nhs), GFP_KERNEL);
-	err = -ENOBUFS;
-	if (fi == NULL)
-		goto failure;
-
-	fi->fib_protocol = r->rtm_protocol;
-	fi->fib_nhs = nhs;
-	fi->fib_flags = r->rtm_flags;
-
-	if (attrs[RTA_PRIORITY])
-		fi->fib_priority = nla_get_u32(attrs[RTA_PRIORITY]);
-
-	if (attrs[RTA_METRICS]) {
-		struct nlattr *attr;
-		int rem;
-
-		nla_for_each_nested(attr, attrs[RTA_METRICS], rem) {
-			int type = nla_type(attr);
-
-			if (type) {
-				if (type > RTAX_MAX || type == RTAX_CC_ALGO ||
-				    nla_len(attr) < 4)
-					goto err_inval;
-
-				fi->fib_metrics[type-1] = nla_get_u32(attr);
-			}
-		}
-	}
-
-	if (attrs[RTA_PREFSRC])
-		fi->fib_prefsrc = nla_get_le16(attrs[RTA_PREFSRC]);
-
-	if (attrs[RTA_MULTIPATH]) {
-		if ((err = dn_fib_get_nhs(fi, attrs[RTA_MULTIPATH], r)) != 0)
-			goto failure;
-
-		if (attrs[RTA_OIF] &&
-		    fi->fib_nh->nh_oif != nla_get_u32(attrs[RTA_OIF]))
-			goto err_inval;
-
-		if (attrs[RTA_GATEWAY] &&
-		    fi->fib_nh->nh_gw != nla_get_le16(attrs[RTA_GATEWAY]))
-			goto err_inval;
-	} else {
-		struct dn_fib_nh *nh = fi->fib_nh;
-
-		if (attrs[RTA_OIF])
-			nh->nh_oif = nla_get_u32(attrs[RTA_OIF]);
-
-		if (attrs[RTA_GATEWAY])
-			nh->nh_gw = nla_get_le16(attrs[RTA_GATEWAY]);
-
-		nh->nh_flags = r->rtm_flags;
-		nh->nh_weight = 1;
-	}
-
-	if (r->rtm_type == RTN_NAT) {
-		if (!attrs[RTA_GATEWAY] || nhs != 1 || attrs[RTA_OIF])
-			goto err_inval;
-
-		fi->fib_nh->nh_gw = nla_get_le16(attrs[RTA_GATEWAY]);
-		goto link_it;
-	}
-
-	if (dn_fib_props[r->rtm_type].error) {
-		if (attrs[RTA_GATEWAY] || attrs[RTA_OIF] || attrs[RTA_MULTIPATH])
-			goto err_inval;
-
-		goto link_it;
-	}
-
-	if (r->rtm_scope > RT_SCOPE_HOST)
-		goto err_inval;
-
-	if (r->rtm_scope == RT_SCOPE_HOST) {
-		struct dn_fib_nh *nh = fi->fib_nh;
-
-		/* Local address is added */
-		if (nhs != 1 || nh->nh_gw)
-			goto err_inval;
-		nh->nh_scope = RT_SCOPE_NOWHERE;
-		nh->nh_dev = dev_get_by_index(&init_net, fi->fib_nh->nh_oif);
-		err = -ENODEV;
-		if (nh->nh_dev == NULL)
-			goto failure;
-	} else {
-		change_nexthops(fi) {
-			if ((err = dn_fib_check_nh(r, fi, nh)) != 0)
-				goto failure;
-		} endfor_nexthops(fi)
-	}
-
-	if (fi->fib_prefsrc) {
-		if (r->rtm_type != RTN_LOCAL || !attrs[RTA_DST] ||
-		    fi->fib_prefsrc != nla_get_le16(attrs[RTA_DST]))
-			if (dnet_addr_type(fi->fib_prefsrc) != RTN_LOCAL)
-				goto err_inval;
-	}
-
-link_it:
-	if ((ofi = dn_fib_find_info(fi)) != NULL) {
-		fi->fib_dead = 1;
-		dn_fib_free_info(fi);
-		ofi->fib_treeref++;
-		return ofi;
-	}
-
-	fi->fib_treeref++;
-	refcount_set(&fi->fib_clntref, 1);
-	spin_lock(&dn_fib_info_lock);
-	fi->fib_next = dn_fib_info_list;
-	fi->fib_prev = NULL;
-	if (dn_fib_info_list)
-		dn_fib_info_list->fib_prev = fi;
-	dn_fib_info_list = fi;
-	spin_unlock(&dn_fib_info_lock);
-	return fi;
-
-err_inval:
-	err = -EINVAL;
-
-failure:
-	*errp = err;
-	if (fi) {
-		fi->fib_dead = 1;
-		dn_fib_free_info(fi);
-	}
-
-	return NULL;
-}
-
-int dn_fib_semantic_match(int type, struct dn_fib_info *fi, const struct flowidn *fld, struct dn_fib_res *res)
-{
-	int err = dn_fib_props[type].error;
-
-	if (err == 0) {
-		if (fi->fib_flags & RTNH_F_DEAD)
-			return 1;
-
-		res->fi = fi;
-
-		switch (type) {
-		case RTN_NAT:
-			DN_FIB_RES_RESET(*res);
-			refcount_inc(&fi->fib_clntref);
-			return 0;
-		case RTN_UNICAST:
-		case RTN_LOCAL:
-			for_nexthops(fi) {
-				if (nh->nh_flags & RTNH_F_DEAD)
-					continue;
-				if (!fld->flowidn_oif ||
-				    fld->flowidn_oif == nh->nh_oif)
-					break;
-			}
-			if (nhsel < fi->fib_nhs) {
-				res->nh_sel = nhsel;
-				refcount_inc(&fi->fib_clntref);
-				return 0;
-			}
-			endfor_nexthops(fi);
-			res->fi = NULL;
-			return 1;
-		default:
-			net_err_ratelimited("DECnet: impossible routing event : dn_fib_semantic_match type=%d\n",
-					    type);
-			res->fi = NULL;
-			return -EINVAL;
-		}
-	}
-	return err;
-}
-
-void dn_fib_select_multipath(const struct flowidn *fld, struct dn_fib_res *res)
-{
-	struct dn_fib_info *fi = res->fi;
-	int w;
-
-	spin_lock_bh(&dn_fib_multipath_lock);
-	if (fi->fib_power <= 0) {
-		int power = 0;
-		change_nexthops(fi) {
-			if (!(nh->nh_flags&RTNH_F_DEAD)) {
-				power += nh->nh_weight;
-				nh->nh_power = nh->nh_weight;
-			}
-		} endfor_nexthops(fi);
-		fi->fib_power = power;
-		if (power < 0) {
-			spin_unlock_bh(&dn_fib_multipath_lock);
-			res->nh_sel = 0;
-			return;
-		}
-	}
-
-	w = jiffies % fi->fib_power;
-
-	change_nexthops(fi) {
-		if (!(nh->nh_flags&RTNH_F_DEAD) && nh->nh_power) {
-			if ((w -= nh->nh_power) <= 0) {
-				nh->nh_power--;
-				fi->fib_power--;
-				res->nh_sel = nhsel;
-				spin_unlock_bh(&dn_fib_multipath_lock);
-				return;
-			}
-		}
-	} endfor_nexthops(fi);
-	res->nh_sel = 0;
-	spin_unlock_bh(&dn_fib_multipath_lock);
-}
-
-static inline u32 rtm_get_table(struct nlattr *attrs[], u8 table)
-{
-	if (attrs[RTA_TABLE])
-		table = nla_get_u32(attrs[RTA_TABLE]);
-
-	return table;
-}
-
-static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh,
-			       struct netlink_ext_ack *extack)
-{
-	struct net *net = sock_net(skb->sk);
-	struct dn_fib_table *tb;
-	struct rtmsg *r = nlmsg_data(nlh);
-	struct nlattr *attrs[RTA_MAX+1];
-	int err;
-
-	if (!netlink_capable(skb, CAP_NET_ADMIN))
-		return -EPERM;
-
-	if (!net_eq(net, &init_net))
-		return -EINVAL;
-
-	err = nlmsg_parse_deprecated(nlh, sizeof(*r), attrs, RTA_MAX,
-				     rtm_dn_policy, extack);
-	if (err < 0)
-		return err;
-
-	tb = dn_fib_get_table(rtm_get_table(attrs, r->rtm_table), 0);
-	if (!tb)
-		return -ESRCH;
-
-	return tb->delete(tb, r, attrs, nlh, &NETLINK_CB(skb));
-}
-
-static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh,
-			       struct netlink_ext_ack *extack)
-{
-	struct net *net = sock_net(skb->sk);
-	struct dn_fib_table *tb;
-	struct rtmsg *r = nlmsg_data(nlh);
-	struct nlattr *attrs[RTA_MAX+1];
-	int err;
-
-	if (!netlink_capable(skb, CAP_NET_ADMIN))
-		return -EPERM;
-
-	if (!net_eq(net, &init_net))
-		return -EINVAL;
-
-	err = nlmsg_parse_deprecated(nlh, sizeof(*r), attrs, RTA_MAX,
-				     rtm_dn_policy, extack);
-	if (err < 0)
-		return err;
-
-	tb = dn_fib_get_table(rtm_get_table(attrs, r->rtm_table), 1);
-	if (!tb)
-		return -ENOBUFS;
-
-	return tb->insert(tb, r, attrs, nlh, &NETLINK_CB(skb));
-}
-
-static void fib_magic(int cmd, int type, __le16 dst, int dst_len, struct dn_ifaddr *ifa)
-{
-	struct dn_fib_table *tb;
-	struct {
-		struct nlmsghdr nlh;
-		struct rtmsg rtm;
-	} req;
-	struct {
-		struct nlattr hdr;
-		__le16 dst;
-	} dst_attr = {
-		.dst = dst,
-	};
-	struct {
-		struct nlattr hdr;
-		__le16 prefsrc;
-	} prefsrc_attr = {
-		.prefsrc = ifa->ifa_local,
-	};
-	struct {
-		struct nlattr hdr;
-		u32 oif;
-	} oif_attr = {
-		.oif = ifa->ifa_dev->dev->ifindex,
-	};
-	struct nlattr *attrs[RTA_MAX+1] = {
-		[RTA_DST] = (struct nlattr *) &dst_attr,
-		[RTA_PREFSRC] = (struct nlattr * ) &prefsrc_attr,
-		[RTA_OIF] = (struct nlattr *) &oif_attr,
-	};
-
-	memset(&req.rtm, 0, sizeof(req.rtm));
-
-	if (type == RTN_UNICAST)
-		tb = dn_fib_get_table(RT_MIN_TABLE, 1);
-	else
-		tb = dn_fib_get_table(RT_TABLE_LOCAL, 1);
-
-	if (tb == NULL)
-		return;
-
-	req.nlh.nlmsg_len = sizeof(req);
-	req.nlh.nlmsg_type = cmd;
-	req.nlh.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_APPEND;
-	req.nlh.nlmsg_pid = 0;
-	req.nlh.nlmsg_seq = 0;
-
-	req.rtm.rtm_dst_len = dst_len;
-	req.rtm.rtm_table = tb->n;
-	req.rtm.rtm_protocol = RTPROT_KERNEL;
-	req.rtm.rtm_scope = (type != RTN_LOCAL ? RT_SCOPE_LINK : RT_SCOPE_HOST);
-	req.rtm.rtm_type = type;
-
-	if (cmd == RTM_NEWROUTE)
-		tb->insert(tb, &req.rtm, attrs, &req.nlh, NULL);
-	else
-		tb->delete(tb, &req.rtm, attrs, &req.nlh, NULL);
-}
-
-static void dn_fib_add_ifaddr(struct dn_ifaddr *ifa)
-{
-
-	fib_magic(RTM_NEWROUTE, RTN_LOCAL, ifa->ifa_local, 16, ifa);
-
-#if 0
-	if (!(dev->flags&IFF_UP))
-		return;
-	/* In the future, we will want to add default routes here */
-
-#endif
-}
-
-static void dn_fib_del_ifaddr(struct dn_ifaddr *ifa)
-{
-	int found_it = 0;
-	struct net_device *dev;
-	struct dn_dev *dn_db;
-	struct dn_ifaddr *ifa2;
-
-	ASSERT_RTNL();
-
-	/* Scan device list */
-	rcu_read_lock();
-	for_each_netdev_rcu(&init_net, dev) {
-		dn_db = rcu_dereference(dev->dn_ptr);
-		if (dn_db == NULL)
-			continue;
-		for (ifa2 = rcu_dereference(dn_db->ifa_list);
-		     ifa2 != NULL;
-		     ifa2 = rcu_dereference(ifa2->ifa_next)) {
-			if (ifa2->ifa_local == ifa->ifa_local) {
-				found_it = 1;
-				break;
-			}
-		}
-	}
-	rcu_read_unlock();
-
-	if (found_it == 0) {
-		fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 16, ifa);
-
-		if (dnet_addr_type(ifa->ifa_local) != RTN_LOCAL) {
-			if (dn_fib_sync_down(ifa->ifa_local, NULL, 0))
-				dn_fib_flush();
-		}
-	}
-}
-
-static void dn_fib_disable_addr(struct net_device *dev, int force)
-{
-	if (dn_fib_sync_down(0, dev, force))
-		dn_fib_flush();
-	dn_rt_cache_flush(0);
-	neigh_ifdown(&dn_neigh_table, dev);
-}
-
-static int dn_fib_dnaddr_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
-	struct dn_ifaddr *ifa = (struct dn_ifaddr *)ptr;
-
-	switch (event) {
-	case NETDEV_UP:
-		dn_fib_add_ifaddr(ifa);
-		dn_fib_sync_up(ifa->ifa_dev->dev);
-		dn_rt_cache_flush(-1);
-		break;
-	case NETDEV_DOWN:
-		dn_fib_del_ifaddr(ifa);
-		if (ifa->ifa_dev && ifa->ifa_dev->ifa_list == NULL) {
-			dn_fib_disable_addr(ifa->ifa_dev->dev, 1);
-		} else {
-			dn_rt_cache_flush(-1);
-		}
-		break;
-	}
-	return NOTIFY_DONE;
-}
-
-static int dn_fib_sync_down(__le16 local, struct net_device *dev, int force)
-{
-	int ret = 0;
-	int scope = RT_SCOPE_NOWHERE;
-
-	if (force)
-		scope = -1;
-
-	for_fib_info() {
-		/*
-		 * This makes no sense for DECnet.... we will almost
-		 * certainly have more than one local address the same
-		 * over all our interfaces. It needs thinking about
-		 * some more.
-		 */
-		if (local && fi->fib_prefsrc == local) {
-			fi->fib_flags |= RTNH_F_DEAD;
-			ret++;
-		} else if (dev && fi->fib_nhs) {
-			int dead = 0;
-
-			change_nexthops(fi) {
-				if (nh->nh_flags&RTNH_F_DEAD)
-					dead++;
-				else if (nh->nh_dev == dev &&
-						nh->nh_scope != scope) {
-					spin_lock_bh(&dn_fib_multipath_lock);
-					nh->nh_flags |= RTNH_F_DEAD;
-					fi->fib_power -= nh->nh_power;
-					nh->nh_power = 0;
-					spin_unlock_bh(&dn_fib_multipath_lock);
-					dead++;
-				}
-			} endfor_nexthops(fi)
-			if (dead == fi->fib_nhs) {
-				fi->fib_flags |= RTNH_F_DEAD;
-				ret++;
-			}
-		}
-	} endfor_fib_info();
-	return ret;
-}
-
-
-static int dn_fib_sync_up(struct net_device *dev)
-{
-	int ret = 0;
-
-	if (!(dev->flags&IFF_UP))
-		return 0;
-
-	for_fib_info() {
-		int alive = 0;
-
-		change_nexthops(fi) {
-			if (!(nh->nh_flags&RTNH_F_DEAD)) {
-				alive++;
-				continue;
-			}
-			if (nh->nh_dev == NULL || !(nh->nh_dev->flags&IFF_UP))
-				continue;
-			if (nh->nh_dev != dev || dev->dn_ptr == NULL)
-				continue;
-			alive++;
-			spin_lock_bh(&dn_fib_multipath_lock);
-			nh->nh_power = 0;
-			nh->nh_flags &= ~RTNH_F_DEAD;
-			spin_unlock_bh(&dn_fib_multipath_lock);
-		} endfor_nexthops(fi);
-
-		if (alive > 0) {
-			fi->fib_flags &= ~RTNH_F_DEAD;
-			ret++;
-		}
-	} endfor_fib_info();
-	return ret;
-}
-
-static struct notifier_block dn_fib_dnaddr_notifier = {
-	.notifier_call = dn_fib_dnaddr_event,
-};
-
-void __exit dn_fib_cleanup(void)
-{
-	dn_fib_table_cleanup();
-	dn_fib_rules_cleanup();
-
-	unregister_dnaddr_notifier(&dn_fib_dnaddr_notifier);
-}
-
-
-void __init dn_fib_init(void)
-{
-	dn_fib_table_init();
-	dn_fib_rules_init();
-
-	register_dnaddr_notifier(&dn_fib_dnaddr_notifier);
-
-	rtnl_register_module(THIS_MODULE, PF_DECnet, RTM_NEWROUTE,
-			     dn_fib_rtm_newroute, NULL, 0);
-	rtnl_register_module(THIS_MODULE, PF_DECnet, RTM_DELROUTE,
-			     dn_fib_rtm_delroute, NULL, 0);
-}
diff --git a/kernel/net/decnet/dn_neigh.c b/kernel/net/decnet/dn_neigh.c
deleted file mode 100644
index 94b306f..0000000
--- a/kernel/net/decnet/dn_neigh.c
+++ /dev/null
@@ -1,605 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * DECnet       An implementation of the DECnet protocol suite for the LINUX
- *              operating system.  DECnet is implemented using the  BSD Socket
- *              interface as the means of communication with the user level.
- *
- *              DECnet Neighbour Functions (Adjacency Database and
- *                                                        On-Ethernet Cache)
- *
- * Author:      Steve Whitehouse <SteveW@ACM.org>
- *
- *
- * Changes:
- *     Steve Whitehouse     : Fixed router listing routine
- *     Steve Whitehouse     : Added error_report functions
- *     Steve Whitehouse     : Added default router detection
- *     Steve Whitehouse     : Hop counts in outgoing messages
- *     Steve Whitehouse     : Fixed src/dst in outgoing messages so
- *                            forwarding now stands a good chance of
- *                            working.
- *     Steve Whitehouse     : Fixed neighbour states (for now anyway).
- *     Steve Whitehouse     : Made error_report functions dummies. This
- *                            is not the right place to return skbs.
- *     Steve Whitehouse     : Convert to seq_file
- *
- */
-
-#include <linux/net.h>
-#include <linux/module.h>
-#include <linux/socket.h>
-#include <linux/if_arp.h>
-#include <linux/slab.h>
-#include <linux/if_ether.h>
-#include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/string.h>
-#include <linux/netfilter_decnet.h>
-#include <linux/spinlock.h>
-#include <linux/seq_file.h>
-#include <linux/rcupdate.h>
-#include <linux/jhash.h>
-#include <linux/atomic.h>
-#include <net/net_namespace.h>
-#include <net/neighbour.h>
-#include <net/dst.h>
-#include <net/flow.h>
-#include <net/dn.h>
-#include <net/dn_dev.h>
-#include <net/dn_neigh.h>
-#include <net/dn_route.h>
-
-static int dn_neigh_construct(struct neighbour *);
-static void dn_neigh_error_report(struct neighbour *, struct sk_buff *);
-static int dn_neigh_output(struct neighbour *neigh, struct sk_buff *skb);
-
-/*
- * Operations for adding the link layer header.
- */
-static const struct neigh_ops dn_neigh_ops = {
-	.family =		AF_DECnet,
-	.error_report =		dn_neigh_error_report,
-	.output =		dn_neigh_output,
-	.connected_output =	dn_neigh_output,
-};
-
-static u32 dn_neigh_hash(const void *pkey,
-			 const struct net_device *dev,
-			 __u32 *hash_rnd)
-{
-	return jhash_2words(*(__u16 *)pkey, 0, hash_rnd[0]);
-}
-
-static bool dn_key_eq(const struct neighbour *neigh, const void *pkey)
-{
-	return neigh_key_eq16(neigh, pkey);
-}
-
-struct neigh_table dn_neigh_table = {
-	.family =			PF_DECnet,
-	.entry_size =			NEIGH_ENTRY_SIZE(sizeof(struct dn_neigh)),
-	.key_len =			sizeof(__le16),
-	.protocol =			cpu_to_be16(ETH_P_DNA_RT),
-	.hash =				dn_neigh_hash,
-	.key_eq =			dn_key_eq,
-	.constructor =			dn_neigh_construct,
-	.id =				"dn_neigh_cache",
-	.parms ={
-		.tbl =			&dn_neigh_table,
-		.reachable_time =	30 * HZ,
-		.data = {
-			[NEIGH_VAR_MCAST_PROBES] = 0,
-			[NEIGH_VAR_UCAST_PROBES] = 0,
-			[NEIGH_VAR_APP_PROBES] = 0,
-			[NEIGH_VAR_RETRANS_TIME] = 1 * HZ,
-			[NEIGH_VAR_BASE_REACHABLE_TIME] = 30 * HZ,
-			[NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ,
-			[NEIGH_VAR_GC_STALETIME] = 60 * HZ,
-			[NEIGH_VAR_QUEUE_LEN_BYTES] = SK_WMEM_MAX,
-			[NEIGH_VAR_PROXY_QLEN] = 0,
-			[NEIGH_VAR_ANYCAST_DELAY] = 0,
-			[NEIGH_VAR_PROXY_DELAY] = 0,
-			[NEIGH_VAR_LOCKTIME] = 1 * HZ,
-		},
-	},
-	.gc_interval =			30 * HZ,
-	.gc_thresh1 =			128,
-	.gc_thresh2 =			512,
-	.gc_thresh3 =			1024,
-};
-
-static int dn_neigh_construct(struct neighbour *neigh)
-{
-	struct net_device *dev = neigh->dev;
-	struct dn_neigh *dn = container_of(neigh, struct dn_neigh, n);
-	struct dn_dev *dn_db;
-	struct neigh_parms *parms;
-
-	rcu_read_lock();
-	dn_db = rcu_dereference(dev->dn_ptr);
-	if (dn_db == NULL) {
-		rcu_read_unlock();
-		return -EINVAL;
-	}
-
-	parms = dn_db->neigh_parms;
-	if (!parms) {
-		rcu_read_unlock();
-		return -EINVAL;
-	}
-
-	__neigh_parms_put(neigh->parms);
-	neigh->parms = neigh_parms_clone(parms);
-	rcu_read_unlock();
-
-	neigh->ops = &dn_neigh_ops;
-	neigh->nud_state = NUD_NOARP;
-	neigh->output = neigh->ops->connected_output;
-
-	if ((dev->type == ARPHRD_IPGRE) || (dev->flags & IFF_POINTOPOINT))
-		memcpy(neigh->ha, dev->broadcast, dev->addr_len);
-	else if ((dev->type == ARPHRD_ETHER) || (dev->type == ARPHRD_LOOPBACK))
-		dn_dn2eth(neigh->ha, dn->addr);
-	else {
-		net_dbg_ratelimited("Trying to create neigh for hw %d\n",
-				    dev->type);
-		return -EINVAL;
-	}
-
-	/*
-	 * Make an estimate of the remote block size by assuming that its
-	 * two less then the device mtu, which it true for ethernet (and
-	 * other things which support long format headers) since there is
-	 * an extra length field (of 16 bits) which isn't part of the
-	 * ethernet headers and which the DECnet specs won't admit is part
-	 * of the DECnet routing headers either.
-	 *
-	 * If we over estimate here its no big deal, the NSP negotiations
-	 * will prevent us from sending packets which are too large for the
-	 * remote node to handle. In any case this figure is normally updated
-	 * by a hello message in most cases.
-	 */
-	dn->blksize = dev->mtu - 2;
-
-	return 0;
-}
-
-static void dn_neigh_error_report(struct neighbour *neigh, struct sk_buff *skb)
-{
-	printk(KERN_DEBUG "dn_neigh_error_report: called\n");
-	kfree_skb(skb);
-}
-
-static int dn_neigh_output(struct neighbour *neigh, struct sk_buff *skb)
-{
-	struct dst_entry *dst = skb_dst(skb);
-	struct dn_route *rt = (struct dn_route *)dst;
-	struct net_device *dev = neigh->dev;
-	char mac_addr[ETH_ALEN];
-	unsigned int seq;
-	int err;
-
-	dn_dn2eth(mac_addr, rt->rt_local_src);
-	do {
-		seq = read_seqbegin(&neigh->ha_lock);
-		err = dev_hard_header(skb, dev, ntohs(skb->protocol),
-				      neigh->ha, mac_addr, skb->len);
-	} while (read_seqretry(&neigh->ha_lock, seq));
-
-	if (err >= 0)
-		err = dev_queue_xmit(skb);
-	else {
-		kfree_skb(skb);
-		err = -EINVAL;
-	}
-	return err;
-}
-
-static int dn_neigh_output_packet(struct net *net, struct sock *sk, struct sk_buff *skb)
-{
-	struct dst_entry *dst = skb_dst(skb);
-	struct dn_route *rt = (struct dn_route *)dst;
-	struct neighbour *neigh = rt->n;
-
-	return neigh->output(neigh, skb);
-}
-
-/*
- * For talking to broadcast devices: Ethernet & PPP
- */
-static int dn_long_output(struct neighbour *neigh, struct sock *sk,
-			  struct sk_buff *skb)
-{
-	struct net_device *dev = neigh->dev;
-	int headroom = dev->hard_header_len + sizeof(struct dn_long_packet) + 3;
-	unsigned char *data;
-	struct dn_long_packet *lp;
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-
-
-	if (skb_headroom(skb) < headroom) {
-		struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom);
-		if (skb2 == NULL) {
-			net_crit_ratelimited("dn_long_output: no memory\n");
-			kfree_skb(skb);
-			return -ENOBUFS;
-		}
-		consume_skb(skb);
-		skb = skb2;
-		net_info_ratelimited("dn_long_output: Increasing headroom\n");
-	}
-
-	data = skb_push(skb, sizeof(struct dn_long_packet) + 3);
-	lp = (struct dn_long_packet *)(data+3);
-
-	*((__le16 *)data) = cpu_to_le16(skb->len - 2);
-	*(data + 2) = 1 | DN_RT_F_PF; /* Padding */
-
-	lp->msgflg   = DN_RT_PKT_LONG|(cb->rt_flags&(DN_RT_F_IE|DN_RT_F_RQR|DN_RT_F_RTS));
-	lp->d_area   = lp->d_subarea = 0;
-	dn_dn2eth(lp->d_id, cb->dst);
-	lp->s_area   = lp->s_subarea = 0;
-	dn_dn2eth(lp->s_id, cb->src);
-	lp->nl2      = 0;
-	lp->visit_ct = cb->hops & 0x3f;
-	lp->s_class  = 0;
-	lp->pt       = 0;
-
-	skb_reset_network_header(skb);
-
-	return NF_HOOK(NFPROTO_DECNET, NF_DN_POST_ROUTING,
-		       &init_net, sk, skb, NULL, neigh->dev,
-		       dn_neigh_output_packet);
-}
-
-/*
- * For talking to pointopoint and multidrop devices: DDCMP and X.25
- */
-static int dn_short_output(struct neighbour *neigh, struct sock *sk,
-			   struct sk_buff *skb)
-{
-	struct net_device *dev = neigh->dev;
-	int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2;
-	struct dn_short_packet *sp;
-	unsigned char *data;
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-
-
-	if (skb_headroom(skb) < headroom) {
-		struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom);
-		if (skb2 == NULL) {
-			net_crit_ratelimited("dn_short_output: no memory\n");
-			kfree_skb(skb);
-			return -ENOBUFS;
-		}
-		consume_skb(skb);
-		skb = skb2;
-		net_info_ratelimited("dn_short_output: Increasing headroom\n");
-	}
-
-	data = skb_push(skb, sizeof(struct dn_short_packet) + 2);
-	*((__le16 *)data) = cpu_to_le16(skb->len - 2);
-	sp = (struct dn_short_packet *)(data+2);
-
-	sp->msgflg     = DN_RT_PKT_SHORT|(cb->rt_flags&(DN_RT_F_RQR|DN_RT_F_RTS));
-	sp->dstnode    = cb->dst;
-	sp->srcnode    = cb->src;
-	sp->forward    = cb->hops & 0x3f;
-
-	skb_reset_network_header(skb);
-
-	return NF_HOOK(NFPROTO_DECNET, NF_DN_POST_ROUTING,
-		       &init_net, sk, skb, NULL, neigh->dev,
-		       dn_neigh_output_packet);
-}
-
-/*
- * For talking to DECnet phase III nodes
- * Phase 3 output is the same as short output, execpt that
- * it clears the area bits before transmission.
- */
-static int dn_phase3_output(struct neighbour *neigh, struct sock *sk,
-			    struct sk_buff *skb)
-{
-	struct net_device *dev = neigh->dev;
-	int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2;
-	struct dn_short_packet *sp;
-	unsigned char *data;
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-
-	if (skb_headroom(skb) < headroom) {
-		struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom);
-		if (skb2 == NULL) {
-			net_crit_ratelimited("dn_phase3_output: no memory\n");
-			kfree_skb(skb);
-			return -ENOBUFS;
-		}
-		consume_skb(skb);
-		skb = skb2;
-		net_info_ratelimited("dn_phase3_output: Increasing headroom\n");
-	}
-
-	data = skb_push(skb, sizeof(struct dn_short_packet) + 2);
-	*((__le16 *)data) = cpu_to_le16(skb->len - 2);
-	sp = (struct dn_short_packet *)(data + 2);
-
-	sp->msgflg   = DN_RT_PKT_SHORT|(cb->rt_flags&(DN_RT_F_RQR|DN_RT_F_RTS));
-	sp->dstnode  = cb->dst & cpu_to_le16(0x03ff);
-	sp->srcnode  = cb->src & cpu_to_le16(0x03ff);
-	sp->forward  = cb->hops & 0x3f;
-
-	skb_reset_network_header(skb);
-
-	return NF_HOOK(NFPROTO_DECNET, NF_DN_POST_ROUTING,
-		       &init_net, sk, skb, NULL, neigh->dev,
-		       dn_neigh_output_packet);
-}
-
-int dn_to_neigh_output(struct net *net, struct sock *sk, struct sk_buff *skb)
-{
-	struct dst_entry *dst = skb_dst(skb);
-	struct dn_route *rt = (struct dn_route *) dst;
-	struct neighbour *neigh = rt->n;
-	struct dn_neigh *dn = container_of(neigh, struct dn_neigh, n);
-	struct dn_dev *dn_db;
-	bool use_long;
-
-	rcu_read_lock();
-	dn_db = rcu_dereference(neigh->dev->dn_ptr);
-	if (dn_db == NULL) {
-		rcu_read_unlock();
-		return -EINVAL;
-	}
-	use_long = dn_db->use_long;
-	rcu_read_unlock();
-
-	if (dn->flags & DN_NDFLAG_P3)
-		return dn_phase3_output(neigh, sk, skb);
-	if (use_long)
-		return dn_long_output(neigh, sk, skb);
-	else
-		return dn_short_output(neigh, sk, skb);
-}
-
-/*
- * Unfortunately, the neighbour code uses the device in its hash
- * function, so we don't get any advantage from it. This function
- * basically does a neigh_lookup(), but without comparing the device
- * field. This is required for the On-Ethernet cache
- */
-
-/*
- * Pointopoint link receives a hello message
- */
-void dn_neigh_pointopoint_hello(struct sk_buff *skb)
-{
-	kfree_skb(skb);
-}
-
-/*
- * Ethernet router hello message received
- */
-int dn_neigh_router_hello(struct net *net, struct sock *sk, struct sk_buff *skb)
-{
-	struct rtnode_hello_message *msg = (struct rtnode_hello_message *)skb->data;
-
-	struct neighbour *neigh;
-	struct dn_neigh *dn;
-	struct dn_dev *dn_db;
-	__le16 src;
-
-	src = dn_eth2dn(msg->id);
-
-	neigh = __neigh_lookup(&dn_neigh_table, &src, skb->dev, 1);
-
-	dn = container_of(neigh, struct dn_neigh, n);
-
-	if (neigh) {
-		write_lock(&neigh->lock);
-
-		neigh->used = jiffies;
-		dn_db = rcu_dereference(neigh->dev->dn_ptr);
-
-		if (!(neigh->nud_state & NUD_PERMANENT)) {
-			neigh->updated = jiffies;
-
-			if (neigh->dev->type == ARPHRD_ETHER)
-				memcpy(neigh->ha, &eth_hdr(skb)->h_source, ETH_ALEN);
-
-			dn->blksize  = le16_to_cpu(msg->blksize);
-			dn->priority = msg->priority;
-
-			dn->flags &= ~DN_NDFLAG_P3;
-
-			switch (msg->iinfo & DN_RT_INFO_TYPE) {
-			case DN_RT_INFO_L1RT:
-				dn->flags &=~DN_NDFLAG_R2;
-				dn->flags |= DN_NDFLAG_R1;
-				break;
-			case DN_RT_INFO_L2RT:
-				dn->flags |= DN_NDFLAG_R2;
-			}
-		}
-
-		/* Only use routers in our area */
-		if ((le16_to_cpu(src)>>10) == (le16_to_cpu((decnet_address))>>10)) {
-			if (!dn_db->router) {
-				dn_db->router = neigh_clone(neigh);
-			} else {
-				if (msg->priority > ((struct dn_neigh *)dn_db->router)->priority)
-					neigh_release(xchg(&dn_db->router, neigh_clone(neigh)));
-			}
-		}
-		write_unlock(&neigh->lock);
-		neigh_release(neigh);
-	}
-
-	kfree_skb(skb);
-	return 0;
-}
-
-/*
- * Endnode hello message received
- */
-int dn_neigh_endnode_hello(struct net *net, struct sock *sk, struct sk_buff *skb)
-{
-	struct endnode_hello_message *msg = (struct endnode_hello_message *)skb->data;
-	struct neighbour *neigh;
-	struct dn_neigh *dn;
-	__le16 src;
-
-	src = dn_eth2dn(msg->id);
-
-	neigh = __neigh_lookup(&dn_neigh_table, &src, skb->dev, 1);
-
-	dn = container_of(neigh, struct dn_neigh, n);
-
-	if (neigh) {
-		write_lock(&neigh->lock);
-
-		neigh->used = jiffies;
-
-		if (!(neigh->nud_state & NUD_PERMANENT)) {
-			neigh->updated = jiffies;
-
-			if (neigh->dev->type == ARPHRD_ETHER)
-				memcpy(neigh->ha, &eth_hdr(skb)->h_source, ETH_ALEN);
-			dn->flags   &= ~(DN_NDFLAG_R1 | DN_NDFLAG_R2);
-			dn->blksize  = le16_to_cpu(msg->blksize);
-			dn->priority = 0;
-		}
-
-		write_unlock(&neigh->lock);
-		neigh_release(neigh);
-	}
-
-	kfree_skb(skb);
-	return 0;
-}
-
-static char *dn_find_slot(char *base, int max, int priority)
-{
-	int i;
-	unsigned char *min = NULL;
-
-	base += 6; /* skip first id */
-
-	for(i = 0; i < max; i++) {
-		if (!min || (*base < *min))
-			min = base;
-		base += 7; /* find next priority */
-	}
-
-	if (!min)
-		return NULL;
-
-	return (*min < priority) ? (min - 6) : NULL;
-}
-
-struct elist_cb_state {
-	struct net_device *dev;
-	unsigned char *ptr;
-	unsigned char *rs;
-	int t, n;
-};
-
-static void neigh_elist_cb(struct neighbour *neigh, void *_info)
-{
-	struct elist_cb_state *s = _info;
-	struct dn_neigh *dn;
-
-	if (neigh->dev != s->dev)
-		return;
-
-	dn = container_of(neigh, struct dn_neigh, n);
-	if (!(dn->flags & (DN_NDFLAG_R1|DN_NDFLAG_R2)))
-		return;
-
-	if (s->t == s->n)
-		s->rs = dn_find_slot(s->ptr, s->n, dn->priority);
-	else
-		s->t++;
-	if (s->rs == NULL)
-		return;
-
-	dn_dn2eth(s->rs, dn->addr);
-	s->rs += 6;
-	*(s->rs) = neigh->nud_state & NUD_CONNECTED ? 0x80 : 0x0;
-	*(s->rs) |= dn->priority;
-	s->rs++;
-}
-
-int dn_neigh_elist(struct net_device *dev, unsigned char *ptr, int n)
-{
-	struct elist_cb_state state;
-
-	state.dev = dev;
-	state.t = 0;
-	state.n = n;
-	state.ptr = ptr;
-	state.rs = ptr;
-
-	neigh_for_each(&dn_neigh_table, neigh_elist_cb, &state);
-
-	return state.t;
-}
-
-
-#ifdef CONFIG_PROC_FS
-
-static inline void dn_neigh_format_entry(struct seq_file *seq,
-					 struct neighbour *n)
-{
-	struct dn_neigh *dn = container_of(n, struct dn_neigh, n);
-	char buf[DN_ASCBUF_LEN];
-
-	read_lock(&n->lock);
-	seq_printf(seq, "%-7s %s%s%s   %02x    %02d  %07ld %-8s\n",
-		   dn_addr2asc(le16_to_cpu(dn->addr), buf),
-		   (dn->flags&DN_NDFLAG_R1) ? "1" : "-",
-		   (dn->flags&DN_NDFLAG_R2) ? "2" : "-",
-		   (dn->flags&DN_NDFLAG_P3) ? "3" : "-",
-		   dn->n.nud_state,
-		   refcount_read(&dn->n.refcnt),
-		   dn->blksize,
-		   (dn->n.dev) ? dn->n.dev->name : "?");
-	read_unlock(&n->lock);
-}
-
-static int dn_neigh_seq_show(struct seq_file *seq, void *v)
-{
-	if (v == SEQ_START_TOKEN) {
-		seq_puts(seq, "Addr    Flags State Use Blksize Dev\n");
-	} else {
-		dn_neigh_format_entry(seq, v);
-	}
-
-	return 0;
-}
-
-static void *dn_neigh_seq_start(struct seq_file *seq, loff_t *pos)
-{
-	return neigh_seq_start(seq, pos, &dn_neigh_table,
-			       NEIGH_SEQ_NEIGH_ONLY);
-}
-
-static const struct seq_operations dn_neigh_seq_ops = {
-	.start = dn_neigh_seq_start,
-	.next  = neigh_seq_next,
-	.stop  = neigh_seq_stop,
-	.show  = dn_neigh_seq_show,
-};
-#endif
-
-void __init dn_neigh_init(void)
-{
-	neigh_table_init(NEIGH_DN_TABLE, &dn_neigh_table);
-	proc_create_net("decnet_neigh", 0444, init_net.proc_net,
-			&dn_neigh_seq_ops, sizeof(struct neigh_seq_state));
-}
-
-void __exit dn_neigh_cleanup(void)
-{
-	remove_proc_entry("decnet_neigh", init_net.proc_net);
-	neigh_table_clear(NEIGH_DN_TABLE, &dn_neigh_table);
-}
diff --git a/kernel/net/decnet/dn_nsp_in.c b/kernel/net/decnet/dn_nsp_in.c
deleted file mode 100644
index c97bdca..0000000
--- a/kernel/net/decnet/dn_nsp_in.c
+++ /dev/null
@@ -1,906 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * DECnet       An implementation of the DECnet protocol suite for the LINUX
- *              operating system.  DECnet is implemented using the  BSD Socket
- *              interface as the means of communication with the user level.
- *
- *              DECnet Network Services Protocol (Input)
- *
- * Author:      Eduardo Marcelo Serrat <emserrat@geocities.com>
- *
- * Changes:
- *
- *    Steve Whitehouse:  Split into dn_nsp_in.c and dn_nsp_out.c from
- *                       original dn_nsp.c.
- *    Steve Whitehouse:  Updated to work with my new routing architecture.
- *    Steve Whitehouse:  Add changes from Eduardo Serrat's patches.
- *    Steve Whitehouse:  Put all ack handling code in a common routine.
- *    Steve Whitehouse:  Put other common bits into dn_nsp_rx()
- *    Steve Whitehouse:  More checks on skb->len to catch bogus packets
- *                       Fixed various race conditions and possible nasties.
- *    Steve Whitehouse:  Now handles returned conninit frames.
- *     David S. Miller:  New socket locking
- *    Steve Whitehouse:  Fixed lockup when socket filtering was enabled.
- *         Paul Koning:  Fix to push CC sockets into RUN when acks are
- *                       received.
- *    Steve Whitehouse:
- *   Patrick Caulfield:  Checking conninits for correctness & sending of error
- *                       responses.
- *    Steve Whitehouse:  Added backlog congestion level return codes.
- *   Patrick Caulfield:
- *    Steve Whitehouse:  Added flow control support (outbound)
- *    Steve Whitehouse:  Prepare for nonlinear skbs
- */
-
-/******************************************************************************
-    (c) 1995-1998 E.M. Serrat		emserrat@geocities.com
-
-*******************************************************************************/
-
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/netdevice.h>
-#include <linux/inet.h>
-#include <linux/route.h>
-#include <linux/slab.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/termios.h>
-#include <linux/interrupt.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/netfilter_decnet.h>
-#include <net/neighbour.h>
-#include <net/dst.h>
-#include <net/dn.h>
-#include <net/dn_nsp.h>
-#include <net/dn_dev.h>
-#include <net/dn_route.h>
-
-extern int decnet_log_martians;
-
-static void dn_log_martian(struct sk_buff *skb, const char *msg)
-{
-	if (decnet_log_martians) {
-		char *devname = skb->dev ? skb->dev->name : "???";
-		struct dn_skb_cb *cb = DN_SKB_CB(skb);
-		net_info_ratelimited("DECnet: Martian packet (%s) dev=%s src=0x%04hx dst=0x%04hx srcport=0x%04hx dstport=0x%04hx\n",
-				     msg, devname,
-				     le16_to_cpu(cb->src),
-				     le16_to_cpu(cb->dst),
-				     le16_to_cpu(cb->src_port),
-				     le16_to_cpu(cb->dst_port));
-	}
-}
-
-/*
- * For this function we've flipped the cross-subchannel bit
- * if the message is an otherdata or linkservice message. Thus
- * we can use it to work out what to update.
- */
-static void dn_ack(struct sock *sk, struct sk_buff *skb, unsigned short ack)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	unsigned short type = ((ack >> 12) & 0x0003);
-	int wakeup = 0;
-
-	switch (type) {
-	case 0: /* ACK - Data */
-		if (dn_after(ack, scp->ackrcv_dat)) {
-			scp->ackrcv_dat = ack & 0x0fff;
-			wakeup |= dn_nsp_check_xmit_queue(sk, skb,
-							  &scp->data_xmit_queue,
-							  ack);
-		}
-		break;
-	case 1: /* NAK - Data */
-		break;
-	case 2: /* ACK - OtherData */
-		if (dn_after(ack, scp->ackrcv_oth)) {
-			scp->ackrcv_oth = ack & 0x0fff;
-			wakeup |= dn_nsp_check_xmit_queue(sk, skb,
-							  &scp->other_xmit_queue,
-							  ack);
-		}
-		break;
-	case 3: /* NAK - OtherData */
-		break;
-	}
-
-	if (wakeup && !sock_flag(sk, SOCK_DEAD))
-		sk->sk_state_change(sk);
-}
-
-/*
- * This function is a universal ack processor.
- */
-static int dn_process_ack(struct sock *sk, struct sk_buff *skb, int oth)
-{
-	__le16 *ptr = (__le16 *)skb->data;
-	int len = 0;
-	unsigned short ack;
-
-	if (skb->len < 2)
-		return len;
-
-	if ((ack = le16_to_cpu(*ptr)) & 0x8000) {
-		skb_pull(skb, 2);
-		ptr++;
-		len += 2;
-		if ((ack & 0x4000) == 0) {
-			if (oth)
-				ack ^= 0x2000;
-			dn_ack(sk, skb, ack);
-		}
-	}
-
-	if (skb->len < 2)
-		return len;
-
-	if ((ack = le16_to_cpu(*ptr)) & 0x8000) {
-		skb_pull(skb, 2);
-		len += 2;
-		if ((ack & 0x4000) == 0) {
-			if (oth)
-				ack ^= 0x2000;
-			dn_ack(sk, skb, ack);
-		}
-	}
-
-	return len;
-}
-
-
-/**
- * dn_check_idf - Check an image data field format is correct.
- * @pptr: Pointer to pointer to image data
- * @len: Pointer to length of image data
- * @max: The maximum allowed length of the data in the image data field
- * @follow_on: Check that this many bytes exist beyond the end of the image data
- *
- * Returns: 0 if ok, -1 on error
- */
-static inline int dn_check_idf(unsigned char **pptr, int *len, unsigned char max, unsigned char follow_on)
-{
-	unsigned char *ptr = *pptr;
-	unsigned char flen = *ptr++;
-
-	(*len)--;
-	if (flen > max)
-		return -1;
-	if ((flen + follow_on) > *len)
-		return -1;
-
-	*len -= flen;
-	*pptr = ptr + flen;
-	return 0;
-}
-
-/*
- * Table of reason codes to pass back to node which sent us a badly
- * formed message, plus text messages for the log. A zero entry in
- * the reason field means "don't reply" otherwise a disc init is sent with
- * the specified reason code.
- */
-static struct {
-	unsigned short reason;
-	const char *text;
-} ci_err_table[] = {
- { 0,             "CI: Truncated message" },
- { NSP_REASON_ID, "CI: Destination username error" },
- { NSP_REASON_ID, "CI: Destination username type" },
- { NSP_REASON_US, "CI: Source username error" },
- { 0,             "CI: Truncated at menuver" },
- { 0,             "CI: Truncated before access or user data" },
- { NSP_REASON_IO, "CI: Access data format error" },
- { NSP_REASON_IO, "CI: User data format error" }
-};
-
-/*
- * This function uses a slightly different lookup method
- * to find its sockets, since it searches on object name/number
- * rather than port numbers. Various tests are done to ensure that
- * the incoming data is in the correct format before it is queued to
- * a socket.
- */
-static struct sock *dn_find_listener(struct sk_buff *skb, unsigned short *reason)
-{
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	struct nsp_conn_init_msg *msg = (struct nsp_conn_init_msg *)skb->data;
-	struct sockaddr_dn dstaddr;
-	struct sockaddr_dn srcaddr;
-	unsigned char type = 0;
-	int dstlen;
-	int srclen;
-	unsigned char *ptr;
-	int len;
-	int err = 0;
-	unsigned char menuver;
-
-	memset(&dstaddr, 0, sizeof(struct sockaddr_dn));
-	memset(&srcaddr, 0, sizeof(struct sockaddr_dn));
-
-	/*
-	 * 1. Decode & remove message header
-	 */
-	cb->src_port = msg->srcaddr;
-	cb->dst_port = msg->dstaddr;
-	cb->services = msg->services;
-	cb->info     = msg->info;
-	cb->segsize  = le16_to_cpu(msg->segsize);
-
-	if (!pskb_may_pull(skb, sizeof(*msg)))
-		goto err_out;
-
-	skb_pull(skb, sizeof(*msg));
-
-	len = skb->len;
-	ptr = skb->data;
-
-	/*
-	 * 2. Check destination end username format
-	 */
-	dstlen = dn_username2sockaddr(ptr, len, &dstaddr, &type);
-	err++;
-	if (dstlen < 0)
-		goto err_out;
-
-	err++;
-	if (type > 1)
-		goto err_out;
-
-	len -= dstlen;
-	ptr += dstlen;
-
-	/*
-	 * 3. Check source end username format
-	 */
-	srclen = dn_username2sockaddr(ptr, len, &srcaddr, &type);
-	err++;
-	if (srclen < 0)
-		goto err_out;
-
-	len -= srclen;
-	ptr += srclen;
-	err++;
-	if (len < 1)
-		goto err_out;
-
-	menuver = *ptr;
-	ptr++;
-	len--;
-
-	/*
-	 * 4. Check that optional data actually exists if menuver says it does
-	 */
-	err++;
-	if ((menuver & (DN_MENUVER_ACC | DN_MENUVER_USR)) && (len < 1))
-		goto err_out;
-
-	/*
-	 * 5. Check optional access data format
-	 */
-	err++;
-	if (menuver & DN_MENUVER_ACC) {
-		if (dn_check_idf(&ptr, &len, 39, 1))
-			goto err_out;
-		if (dn_check_idf(&ptr, &len, 39, 1))
-			goto err_out;
-		if (dn_check_idf(&ptr, &len, 39, (menuver & DN_MENUVER_USR) ? 1 : 0))
-			goto err_out;
-	}
-
-	/*
-	 * 6. Check optional user data format
-	 */
-	err++;
-	if (menuver & DN_MENUVER_USR) {
-		if (dn_check_idf(&ptr, &len, 16, 0))
-			goto err_out;
-	}
-
-	/*
-	 * 7. Look up socket based on destination end username
-	 */
-	return dn_sklist_find_listener(&dstaddr);
-err_out:
-	dn_log_martian(skb, ci_err_table[err].text);
-	*reason = ci_err_table[err].reason;
-	return NULL;
-}
-
-
-static void dn_nsp_conn_init(struct sock *sk, struct sk_buff *skb)
-{
-	if (sk_acceptq_is_full(sk)) {
-		kfree_skb(skb);
-		return;
-	}
-
-	sk_acceptq_added(sk);
-	skb_queue_tail(&sk->sk_receive_queue, skb);
-	sk->sk_state_change(sk);
-}
-
-static void dn_nsp_conn_conf(struct sock *sk, struct sk_buff *skb)
-{
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	struct dn_scp *scp = DN_SK(sk);
-	unsigned char *ptr;
-
-	if (skb->len < 4)
-		goto out;
-
-	ptr = skb->data;
-	cb->services = *ptr++;
-	cb->info = *ptr++;
-	cb->segsize = le16_to_cpu(*(__le16 *)ptr);
-
-	if ((scp->state == DN_CI) || (scp->state == DN_CD)) {
-		scp->persist = 0;
-		scp->addrrem = cb->src_port;
-		sk->sk_state = TCP_ESTABLISHED;
-		scp->state = DN_RUN;
-		scp->services_rem = cb->services;
-		scp->info_rem = cb->info;
-		scp->segsize_rem = cb->segsize;
-
-		if ((scp->services_rem & NSP_FC_MASK) == NSP_FC_NONE)
-			scp->max_window = decnet_no_fc_max_cwnd;
-
-		if (skb->len > 0) {
-			u16 dlen = *skb->data;
-			if ((dlen <= 16) && (dlen <= skb->len)) {
-				scp->conndata_in.opt_optl = cpu_to_le16(dlen);
-				skb_copy_from_linear_data_offset(skb, 1,
-					      scp->conndata_in.opt_data, dlen);
-			}
-		}
-		dn_nsp_send_link(sk, DN_NOCHANGE, 0);
-		if (!sock_flag(sk, SOCK_DEAD))
-			sk->sk_state_change(sk);
-	}
-
-out:
-	kfree_skb(skb);
-}
-
-static void dn_nsp_conn_ack(struct sock *sk, struct sk_buff *skb)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	if (scp->state == DN_CI) {
-		scp->state = DN_CD;
-		scp->persist = 0;
-	}
-
-	kfree_skb(skb);
-}
-
-static void dn_nsp_disc_init(struct sock *sk, struct sk_buff *skb)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	unsigned short reason;
-
-	if (skb->len < 2)
-		goto out;
-
-	reason = le16_to_cpu(*(__le16 *)skb->data);
-	skb_pull(skb, 2);
-
-	scp->discdata_in.opt_status = cpu_to_le16(reason);
-	scp->discdata_in.opt_optl   = 0;
-	memset(scp->discdata_in.opt_data, 0, 16);
-
-	if (skb->len > 0) {
-		u16 dlen = *skb->data;
-		if ((dlen <= 16) && (dlen <= skb->len)) {
-			scp->discdata_in.opt_optl = cpu_to_le16(dlen);
-			skb_copy_from_linear_data_offset(skb, 1, scp->discdata_in.opt_data, dlen);
-		}
-	}
-
-	scp->addrrem = cb->src_port;
-	sk->sk_state = TCP_CLOSE;
-
-	switch (scp->state) {
-	case DN_CI:
-	case DN_CD:
-		scp->state = DN_RJ;
-		sk->sk_err = ECONNREFUSED;
-		break;
-	case DN_RUN:
-		sk->sk_shutdown |= SHUTDOWN_MASK;
-		scp->state = DN_DN;
-		break;
-	case DN_DI:
-		scp->state = DN_DIC;
-		break;
-	}
-
-	if (!sock_flag(sk, SOCK_DEAD)) {
-		if (sk->sk_socket->state != SS_UNCONNECTED)
-			sk->sk_socket->state = SS_DISCONNECTING;
-		sk->sk_state_change(sk);
-	}
-
-	/*
-	 * It appears that its possible for remote machines to send disc
-	 * init messages with no port identifier if we are in the CI and
-	 * possibly also the CD state. Obviously we shouldn't reply with
-	 * a message if we don't know what the end point is.
-	 */
-	if (scp->addrrem) {
-		dn_nsp_send_disc(sk, NSP_DISCCONF, NSP_REASON_DC, GFP_ATOMIC);
-	}
-	scp->persist_fxn = dn_destroy_timer;
-	scp->persist = dn_nsp_persist(sk);
-
-out:
-	kfree_skb(skb);
-}
-
-/*
- * disc_conf messages are also called no_resources or no_link
- * messages depending upon the "reason" field.
- */
-static void dn_nsp_disc_conf(struct sock *sk, struct sk_buff *skb)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	unsigned short reason;
-
-	if (skb->len != 2)
-		goto out;
-
-	reason = le16_to_cpu(*(__le16 *)skb->data);
-
-	sk->sk_state = TCP_CLOSE;
-
-	switch (scp->state) {
-	case DN_CI:
-		scp->state = DN_NR;
-		break;
-	case DN_DR:
-		if (reason == NSP_REASON_DC)
-			scp->state = DN_DRC;
-		if (reason == NSP_REASON_NL)
-			scp->state = DN_CN;
-		break;
-	case DN_DI:
-		scp->state = DN_DIC;
-		break;
-	case DN_RUN:
-		sk->sk_shutdown |= SHUTDOWN_MASK;
-		fallthrough;
-	case DN_CC:
-		scp->state = DN_CN;
-	}
-
-	if (!sock_flag(sk, SOCK_DEAD)) {
-		if (sk->sk_socket->state != SS_UNCONNECTED)
-			sk->sk_socket->state = SS_DISCONNECTING;
-		sk->sk_state_change(sk);
-	}
-
-	scp->persist_fxn = dn_destroy_timer;
-	scp->persist = dn_nsp_persist(sk);
-
-out:
-	kfree_skb(skb);
-}
-
-static void dn_nsp_linkservice(struct sock *sk, struct sk_buff *skb)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	unsigned short segnum;
-	unsigned char lsflags;
-	signed char fcval;
-	int wake_up = 0;
-	char *ptr = skb->data;
-	unsigned char fctype = scp->services_rem & NSP_FC_MASK;
-
-	if (skb->len != 4)
-		goto out;
-
-	segnum = le16_to_cpu(*(__le16 *)ptr);
-	ptr += 2;
-	lsflags = *(unsigned char *)ptr++;
-	fcval = *ptr;
-
-	/*
-	 * Here we ignore erronous packets which should really
-	 * should cause a connection abort. It is not critical
-	 * for now though.
-	 */
-	if (lsflags & 0xf8)
-		goto out;
-
-	if (seq_next(scp->numoth_rcv, segnum)) {
-		seq_add(&scp->numoth_rcv, 1);
-		switch(lsflags & 0x04) { /* FCVAL INT */
-		case 0x00: /* Normal Request */
-			switch(lsflags & 0x03) { /* FCVAL MOD */
-			case 0x00: /* Request count */
-				if (fcval < 0) {
-					unsigned char p_fcval = -fcval;
-					if ((scp->flowrem_dat > p_fcval) &&
-					    (fctype == NSP_FC_SCMC)) {
-						scp->flowrem_dat -= p_fcval;
-					}
-				} else if (fcval > 0) {
-					scp->flowrem_dat += fcval;
-					wake_up = 1;
-				}
-				break;
-			case 0x01: /* Stop outgoing data */
-				scp->flowrem_sw = DN_DONTSEND;
-				break;
-			case 0x02: /* Ok to start again */
-				scp->flowrem_sw = DN_SEND;
-				dn_nsp_output(sk);
-				wake_up = 1;
-			}
-			break;
-		case 0x04: /* Interrupt Request */
-			if (fcval > 0) {
-				scp->flowrem_oth += fcval;
-				wake_up = 1;
-			}
-			break;
-		}
-		if (wake_up && !sock_flag(sk, SOCK_DEAD))
-			sk->sk_state_change(sk);
-	}
-
-	dn_nsp_send_oth_ack(sk);
-
-out:
-	kfree_skb(skb);
-}
-
-/*
- * Copy of sock_queue_rcv_skb (from sock.h) without
- * bh_lock_sock() (its already held when this is called) which
- * also allows data and other data to be queued to a socket.
- */
-static __inline__ int dn_queue_skb(struct sock *sk, struct sk_buff *skb, int sig, struct sk_buff_head *queue)
-{
-	int err;
-
-	/* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
-	   number of warnings when compiling with -W --ANK
-	 */
-	if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
-	    (unsigned int)sk->sk_rcvbuf) {
-		err = -ENOMEM;
-		goto out;
-	}
-
-	err = sk_filter(sk, skb);
-	if (err)
-		goto out;
-
-	skb_set_owner_r(skb, sk);
-	skb_queue_tail(queue, skb);
-
-	if (!sock_flag(sk, SOCK_DEAD))
-		sk->sk_data_ready(sk);
-out:
-	return err;
-}
-
-static void dn_nsp_otherdata(struct sock *sk, struct sk_buff *skb)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	unsigned short segnum;
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	int queued = 0;
-
-	if (skb->len < 2)
-		goto out;
-
-	cb->segnum = segnum = le16_to_cpu(*(__le16 *)skb->data);
-	skb_pull(skb, 2);
-
-	if (seq_next(scp->numoth_rcv, segnum)) {
-
-		if (dn_queue_skb(sk, skb, SIGURG, &scp->other_receive_queue) == 0) {
-			seq_add(&scp->numoth_rcv, 1);
-			scp->other_report = 0;
-			queued = 1;
-		}
-	}
-
-	dn_nsp_send_oth_ack(sk);
-out:
-	if (!queued)
-		kfree_skb(skb);
-}
-
-static void dn_nsp_data(struct sock *sk, struct sk_buff *skb)
-{
-	int queued = 0;
-	unsigned short segnum;
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	struct dn_scp *scp = DN_SK(sk);
-
-	if (skb->len < 2)
-		goto out;
-
-	cb->segnum = segnum = le16_to_cpu(*(__le16 *)skb->data);
-	skb_pull(skb, 2);
-
-	if (seq_next(scp->numdat_rcv, segnum)) {
-		if (dn_queue_skb(sk, skb, SIGIO, &sk->sk_receive_queue) == 0) {
-			seq_add(&scp->numdat_rcv, 1);
-			queued = 1;
-		}
-
-		if ((scp->flowloc_sw == DN_SEND) && dn_congested(sk)) {
-			scp->flowloc_sw = DN_DONTSEND;
-			dn_nsp_send_link(sk, DN_DONTSEND, 0);
-		}
-	}
-
-	dn_nsp_send_data_ack(sk);
-out:
-	if (!queued)
-		kfree_skb(skb);
-}
-
-/*
- * If one of our conninit messages is returned, this function
- * deals with it. It puts the socket into the NO_COMMUNICATION
- * state.
- */
-static void dn_returned_conn_init(struct sock *sk, struct sk_buff *skb)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	if (scp->state == DN_CI) {
-		scp->state = DN_NC;
-		sk->sk_state = TCP_CLOSE;
-		if (!sock_flag(sk, SOCK_DEAD))
-			sk->sk_state_change(sk);
-	}
-
-	kfree_skb(skb);
-}
-
-static int dn_nsp_no_socket(struct sk_buff *skb, unsigned short reason)
-{
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	int ret = NET_RX_DROP;
-
-	/* Must not reply to returned packets */
-	if (cb->rt_flags & DN_RT_F_RTS)
-		goto out;
-
-	if ((reason != NSP_REASON_OK) && ((cb->nsp_flags & 0x0c) == 0x08)) {
-		switch (cb->nsp_flags & 0x70) {
-		case 0x10:
-		case 0x60: /* (Retransmitted) Connect Init */
-			dn_nsp_return_disc(skb, NSP_DISCINIT, reason);
-			ret = NET_RX_SUCCESS;
-			break;
-		case 0x20: /* Connect Confirm */
-			dn_nsp_return_disc(skb, NSP_DISCCONF, reason);
-			ret = NET_RX_SUCCESS;
-			break;
-		}
-	}
-
-out:
-	kfree_skb(skb);
-	return ret;
-}
-
-static int dn_nsp_rx_packet(struct net *net, struct sock *sk2,
-			    struct sk_buff *skb)
-{
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	struct sock *sk = NULL;
-	unsigned char *ptr = (unsigned char *)skb->data;
-	unsigned short reason = NSP_REASON_NL;
-
-	if (!pskb_may_pull(skb, 2))
-		goto free_out;
-
-	skb_reset_transport_header(skb);
-	cb->nsp_flags = *ptr++;
-
-	if (decnet_debug_level & 2)
-		printk(KERN_DEBUG "dn_nsp_rx: Message type 0x%02x\n", (int)cb->nsp_flags);
-
-	if (cb->nsp_flags & 0x83)
-		goto free_out;
-
-	/*
-	 * Filter out conninits and useless packet types
-	 */
-	if ((cb->nsp_flags & 0x0c) == 0x08) {
-		switch (cb->nsp_flags & 0x70) {
-		case 0x00: /* NOP */
-		case 0x70: /* Reserved */
-		case 0x50: /* Reserved, Phase II node init */
-			goto free_out;
-		case 0x10:
-		case 0x60:
-			if (unlikely(cb->rt_flags & DN_RT_F_RTS))
-				goto free_out;
-			sk = dn_find_listener(skb, &reason);
-			goto got_it;
-		}
-	}
-
-	if (!pskb_may_pull(skb, 3))
-		goto free_out;
-
-	/*
-	 * Grab the destination address.
-	 */
-	cb->dst_port = *(__le16 *)ptr;
-	cb->src_port = 0;
-	ptr += 2;
-
-	/*
-	 * If not a connack, grab the source address too.
-	 */
-	if (pskb_may_pull(skb, 5)) {
-		cb->src_port = *(__le16 *)ptr;
-		ptr += 2;
-		skb_pull(skb, 5);
-	}
-
-	/*
-	 * Returned packets...
-	 * Swap src & dst and look up in the normal way.
-	 */
-	if (unlikely(cb->rt_flags & DN_RT_F_RTS)) {
-		swap(cb->dst_port, cb->src_port);
-		swap(cb->dst, cb->src);
-	}
-
-	/*
-	 * Find the socket to which this skb is destined.
-	 */
-	sk = dn_find_by_skb(skb);
-got_it:
-	if (sk != NULL) {
-		struct dn_scp *scp = DN_SK(sk);
-
-		/* Reset backoff */
-		scp->nsp_rxtshift = 0;
-
-		/*
-		 * We linearize everything except data segments here.
-		 */
-		if (cb->nsp_flags & ~0x60) {
-			if (unlikely(skb_linearize(skb)))
-				goto free_out;
-		}
-
-		return sk_receive_skb(sk, skb, 0);
-	}
-
-	return dn_nsp_no_socket(skb, reason);
-
-free_out:
-	kfree_skb(skb);
-	return NET_RX_DROP;
-}
-
-int dn_nsp_rx(struct sk_buff *skb)
-{
-	return NF_HOOK(NFPROTO_DECNET, NF_DN_LOCAL_IN,
-		       &init_net, NULL, skb, skb->dev, NULL,
-		       dn_nsp_rx_packet);
-}
-
-/*
- * This is the main receive routine for sockets. It is called
- * from the above when the socket is not busy, and also from
- * sock_release() when there is a backlog queued up.
- */
-int dn_nsp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-
-	if (cb->rt_flags & DN_RT_F_RTS) {
-		if (cb->nsp_flags == 0x18 || cb->nsp_flags == 0x68)
-			dn_returned_conn_init(sk, skb);
-		else
-			kfree_skb(skb);
-		return NET_RX_SUCCESS;
-	}
-
-	/*
-	 * Control packet.
-	 */
-	if ((cb->nsp_flags & 0x0c) == 0x08) {
-		switch (cb->nsp_flags & 0x70) {
-		case 0x10:
-		case 0x60:
-			dn_nsp_conn_init(sk, skb);
-			break;
-		case 0x20:
-			dn_nsp_conn_conf(sk, skb);
-			break;
-		case 0x30:
-			dn_nsp_disc_init(sk, skb);
-			break;
-		case 0x40:
-			dn_nsp_disc_conf(sk, skb);
-			break;
-		}
-
-	} else if (cb->nsp_flags == 0x24) {
-		/*
-		 * Special for connacks, 'cos they don't have
-		 * ack data or ack otherdata info.
-		 */
-		dn_nsp_conn_ack(sk, skb);
-	} else {
-		int other = 1;
-
-		/* both data and ack frames can kick a CC socket into RUN */
-		if ((scp->state == DN_CC) && !sock_flag(sk, SOCK_DEAD)) {
-			scp->state = DN_RUN;
-			sk->sk_state = TCP_ESTABLISHED;
-			sk->sk_state_change(sk);
-		}
-
-		if ((cb->nsp_flags & 0x1c) == 0)
-			other = 0;
-		if (cb->nsp_flags == 0x04)
-			other = 0;
-
-		/*
-		 * Read out ack data here, this applies equally
-		 * to data, other data, link serivce and both
-		 * ack data and ack otherdata.
-		 */
-		dn_process_ack(sk, skb, other);
-
-		/*
-		 * If we've some sort of data here then call a
-		 * suitable routine for dealing with it, otherwise
-		 * the packet is an ack and can be discarded.
-		 */
-		if ((cb->nsp_flags & 0x0c) == 0) {
-
-			if (scp->state != DN_RUN)
-				goto free_out;
-
-			switch (cb->nsp_flags) {
-			case 0x10: /* LS */
-				dn_nsp_linkservice(sk, skb);
-				break;
-			case 0x30: /* OD */
-				dn_nsp_otherdata(sk, skb);
-				break;
-			default:
-				dn_nsp_data(sk, skb);
-			}
-
-		} else { /* Ack, chuck it out here */
-free_out:
-			kfree_skb(skb);
-		}
-	}
-
-	return NET_RX_SUCCESS;
-}
diff --git a/kernel/net/decnet/dn_nsp_out.c b/kernel/net/decnet/dn_nsp_out.c
deleted file mode 100644
index 00f2ed7..0000000
--- a/kernel/net/decnet/dn_nsp_out.c
+++ /dev/null
@@ -1,695 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * DECnet       An implementation of the DECnet protocol suite for the LINUX
- *              operating system.  DECnet is implemented using the  BSD Socket
- *              interface as the means of communication with the user level.
- *
- *              DECnet Network Services Protocol (Output)
- *
- * Author:      Eduardo Marcelo Serrat <emserrat@geocities.com>
- *
- * Changes:
- *
- *    Steve Whitehouse:  Split into dn_nsp_in.c and dn_nsp_out.c from
- *                       original dn_nsp.c.
- *    Steve Whitehouse:  Updated to work with my new routing architecture.
- *    Steve Whitehouse:  Added changes from Eduardo Serrat's patches.
- *    Steve Whitehouse:  Now conninits have the "return" bit set.
- *    Steve Whitehouse:  Fixes to check alloc'd skbs are non NULL!
- *                       Moved output state machine into one function
- *    Steve Whitehouse:  New output state machine
- *         Paul Koning:  Connect Confirm message fix.
- *      Eduardo Serrat:  Fix to stop dn_nsp_do_disc() sending malformed packets.
- *    Steve Whitehouse:  dn_nsp_output() and friends needed a spring clean
- *    Steve Whitehouse:  Moved dn_nsp_send() in here from route.h
- */
-
-/******************************************************************************
-    (c) 1995-1998 E.M. Serrat		emserrat@geocities.com
-
-*******************************************************************************/
-
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/netdevice.h>
-#include <linux/inet.h>
-#include <linux/route.h>
-#include <linux/slab.h>
-#include <net/sock.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/termios.h>
-#include <linux/interrupt.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/if_packet.h>
-#include <net/neighbour.h>
-#include <net/dst.h>
-#include <net/flow.h>
-#include <net/dn.h>
-#include <net/dn_nsp.h>
-#include <net/dn_dev.h>
-#include <net/dn_route.h>
-
-
-static int nsp_backoff[NSP_MAXRXTSHIFT + 1] = { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 };
-
-static void dn_nsp_send(struct sk_buff *skb)
-{
-	struct sock *sk = skb->sk;
-	struct dn_scp *scp = DN_SK(sk);
-	struct dst_entry *dst;
-	struct flowidn fld;
-
-	skb_reset_transport_header(skb);
-	scp->stamp = jiffies;
-
-	dst = sk_dst_check(sk, 0);
-	if (dst) {
-try_again:
-		skb_dst_set(skb, dst);
-		dst_output(&init_net, skb->sk, skb);
-		return;
-	}
-
-	memset(&fld, 0, sizeof(fld));
-	fld.flowidn_oif = sk->sk_bound_dev_if;
-	fld.saddr = dn_saddr2dn(&scp->addr);
-	fld.daddr = dn_saddr2dn(&scp->peer);
-	dn_sk_ports_copy(&fld, scp);
-	fld.flowidn_proto = DNPROTO_NSP;
-	if (dn_route_output_sock(&sk->sk_dst_cache, &fld, sk, 0) == 0) {
-		dst = sk_dst_get(sk);
-		sk->sk_route_caps = dst->dev->features;
-		goto try_again;
-	}
-
-	sk->sk_err = EHOSTUNREACH;
-	if (!sock_flag(sk, SOCK_DEAD))
-		sk->sk_state_change(sk);
-}
-
-
-/*
- * If sk == NULL, then we assume that we are supposed to be making
- * a routing layer skb. If sk != NULL, then we are supposed to be
- * creating an skb for the NSP layer.
- *
- * The eventual aim is for each socket to have a cached header size
- * for its outgoing packets, and to set hdr from this when sk != NULL.
- */
-struct sk_buff *dn_alloc_skb(struct sock *sk, int size, gfp_t pri)
-{
-	struct sk_buff *skb;
-	int hdr = 64;
-
-	if ((skb = alloc_skb(size + hdr, pri)) == NULL)
-		return NULL;
-
-	skb->protocol = htons(ETH_P_DNA_RT);
-	skb->pkt_type = PACKET_OUTGOING;
-
-	if (sk)
-		skb_set_owner_w(skb, sk);
-
-	skb_reserve(skb, hdr);
-
-	return skb;
-}
-
-/*
- * Calculate persist timer based upon the smoothed round
- * trip time and the variance. Backoff according to the
- * nsp_backoff[] array.
- */
-unsigned long dn_nsp_persist(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	unsigned long t = ((scp->nsp_srtt >> 2) + scp->nsp_rttvar) >> 1;
-
-	t *= nsp_backoff[scp->nsp_rxtshift];
-
-	if (t < HZ) t = HZ;
-	if (t > (600*HZ)) t = (600*HZ);
-
-	if (scp->nsp_rxtshift < NSP_MAXRXTSHIFT)
-		scp->nsp_rxtshift++;
-
-	/* printk(KERN_DEBUG "rxtshift %lu, t=%lu\n", scp->nsp_rxtshift, t); */
-
-	return t;
-}
-
-/*
- * This is called each time we get an estimate for the rtt
- * on the link.
- */
-static void dn_nsp_rtt(struct sock *sk, long rtt)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	long srtt = (long)scp->nsp_srtt;
-	long rttvar = (long)scp->nsp_rttvar;
-	long delta;
-
-	/*
-	 * If the jiffies clock flips over in the middle of timestamp
-	 * gathering this value might turn out negative, so we make sure
-	 * that is it always positive here.
-	 */
-	if (rtt < 0)
-		rtt = -rtt;
-	/*
-	 * Add new rtt to smoothed average
-	 */
-	delta = ((rtt << 3) - srtt);
-	srtt += (delta >> 3);
-	if (srtt >= 1)
-		scp->nsp_srtt = (unsigned long)srtt;
-	else
-		scp->nsp_srtt = 1;
-
-	/*
-	 * Add new rtt varience to smoothed varience
-	 */
-	delta >>= 1;
-	rttvar += ((((delta>0)?(delta):(-delta)) - rttvar) >> 2);
-	if (rttvar >= 1)
-		scp->nsp_rttvar = (unsigned long)rttvar;
-	else
-		scp->nsp_rttvar = 1;
-
-	/* printk(KERN_DEBUG "srtt=%lu rttvar=%lu\n", scp->nsp_srtt, scp->nsp_rttvar); */
-}
-
-/**
- * dn_nsp_clone_and_send - Send a data packet by cloning it
- * @skb: The packet to clone and transmit
- * @gfp: memory allocation flag
- *
- * Clone a queued data or other data packet and transmit it.
- *
- * Returns: The number of times the packet has been sent previously
- */
-static inline unsigned int dn_nsp_clone_and_send(struct sk_buff *skb,
-					     gfp_t gfp)
-{
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	struct sk_buff *skb2;
-	int ret = 0;
-
-	if ((skb2 = skb_clone(skb, gfp)) != NULL) {
-		ret = cb->xmit_count;
-		cb->xmit_count++;
-		cb->stamp = jiffies;
-		skb2->sk = skb->sk;
-		dn_nsp_send(skb2);
-	}
-
-	return ret;
-}
-
-/**
- * dn_nsp_output - Try and send something from socket queues
- * @sk: The socket whose queues are to be investigated
- *
- * Try and send the packet on the end of the data and other data queues.
- * Other data gets priority over data, and if we retransmit a packet we
- * reduce the window by dividing it in two.
- *
- */
-void dn_nsp_output(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	struct sk_buff *skb;
-	unsigned int reduce_win = 0;
-
-	/*
-	 * First we check for otherdata/linkservice messages
-	 */
-	if ((skb = skb_peek(&scp->other_xmit_queue)) != NULL)
-		reduce_win = dn_nsp_clone_and_send(skb, GFP_ATOMIC);
-
-	/*
-	 * If we may not send any data, we don't.
-	 * If we are still trying to get some other data down the
-	 * channel, we don't try and send any data.
-	 */
-	if (reduce_win || (scp->flowrem_sw != DN_SEND))
-		goto recalc_window;
-
-	if ((skb = skb_peek(&scp->data_xmit_queue)) != NULL)
-		reduce_win = dn_nsp_clone_and_send(skb, GFP_ATOMIC);
-
-	/*
-	 * If we've sent any frame more than once, we cut the
-	 * send window size in half. There is always a minimum
-	 * window size of one available.
-	 */
-recalc_window:
-	if (reduce_win) {
-		scp->snd_window >>= 1;
-		if (scp->snd_window < NSP_MIN_WINDOW)
-			scp->snd_window = NSP_MIN_WINDOW;
-	}
-}
-
-int dn_nsp_xmit_timeout(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	dn_nsp_output(sk);
-
-	if (!skb_queue_empty(&scp->data_xmit_queue) ||
-	    !skb_queue_empty(&scp->other_xmit_queue))
-		scp->persist = dn_nsp_persist(sk);
-
-	return 0;
-}
-
-static inline __le16 *dn_mk_common_header(struct dn_scp *scp, struct sk_buff *skb, unsigned char msgflag, int len)
-{
-	unsigned char *ptr = skb_push(skb, len);
-
-	BUG_ON(len < 5);
-
-	*ptr++ = msgflag;
-	*((__le16 *)ptr) = scp->addrrem;
-	ptr += 2;
-	*((__le16 *)ptr) = scp->addrloc;
-	ptr += 2;
-	return (__le16 __force *)ptr;
-}
-
-static __le16 *dn_mk_ack_header(struct sock *sk, struct sk_buff *skb, unsigned char msgflag, int hlen, int other)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	unsigned short acknum = scp->numdat_rcv & 0x0FFF;
-	unsigned short ackcrs = scp->numoth_rcv & 0x0FFF;
-	__le16 *ptr;
-
-	BUG_ON(hlen < 9);
-
-	scp->ackxmt_dat = acknum;
-	scp->ackxmt_oth = ackcrs;
-	acknum |= 0x8000;
-	ackcrs |= 0x8000;
-
-	/* If this is an "other data/ack" message, swap acknum and ackcrs */
-	if (other)
-		swap(acknum, ackcrs);
-
-	/* Set "cross subchannel" bit in ackcrs */
-	ackcrs |= 0x2000;
-
-	ptr = dn_mk_common_header(scp, skb, msgflag, hlen);
-
-	*ptr++ = cpu_to_le16(acknum);
-	*ptr++ = cpu_to_le16(ackcrs);
-
-	return ptr;
-}
-
-static __le16 *dn_nsp_mk_data_header(struct sock *sk, struct sk_buff *skb, int oth)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	__le16 *ptr = dn_mk_ack_header(sk, skb, cb->nsp_flags, 11, oth);
-
-	if (unlikely(oth)) {
-		cb->segnum = scp->numoth;
-		seq_add(&scp->numoth, 1);
-	} else {
-		cb->segnum = scp->numdat;
-		seq_add(&scp->numdat, 1);
-	}
-	*(ptr++) = cpu_to_le16(cb->segnum);
-
-	return ptr;
-}
-
-void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb,
-			gfp_t gfp, int oth)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	unsigned long t = ((scp->nsp_srtt >> 2) + scp->nsp_rttvar) >> 1;
-
-	cb->xmit_count = 0;
-	dn_nsp_mk_data_header(sk, skb, oth);
-
-	/*
-	 * Slow start: If we have been idle for more than
-	 * one RTT, then reset window to min size.
-	 */
-	if ((jiffies - scp->stamp) > t)
-		scp->snd_window = NSP_MIN_WINDOW;
-
-	if (oth)
-		skb_queue_tail(&scp->other_xmit_queue, skb);
-	else
-		skb_queue_tail(&scp->data_xmit_queue, skb);
-
-	if (scp->flowrem_sw != DN_SEND)
-		return;
-
-	dn_nsp_clone_and_send(skb, gfp);
-}
-
-
-int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff_head *q, unsigned short acknum)
-{
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	struct dn_scp *scp = DN_SK(sk);
-	struct sk_buff *skb2, *n, *ack = NULL;
-	int wakeup = 0;
-	int try_retrans = 0;
-	unsigned long reftime = cb->stamp;
-	unsigned long pkttime;
-	unsigned short xmit_count;
-	unsigned short segnum;
-
-	skb_queue_walk_safe(q, skb2, n) {
-		struct dn_skb_cb *cb2 = DN_SKB_CB(skb2);
-
-		if (dn_before_or_equal(cb2->segnum, acknum))
-			ack = skb2;
-
-		/* printk(KERN_DEBUG "ack: %s %04x %04x\n", ack ? "ACK" : "SKIP", (int)cb2->segnum, (int)acknum); */
-
-		if (ack == NULL)
-			continue;
-
-		/* printk(KERN_DEBUG "check_xmit_queue: %04x, %d\n", acknum, cb2->xmit_count); */
-
-		/* Does _last_ packet acked have xmit_count > 1 */
-		try_retrans = 0;
-		/* Remember to wake up the sending process */
-		wakeup = 1;
-		/* Keep various statistics */
-		pkttime = cb2->stamp;
-		xmit_count = cb2->xmit_count;
-		segnum = cb2->segnum;
-		/* Remove and drop ack'ed packet */
-		skb_unlink(ack, q);
-		kfree_skb(ack);
-		ack = NULL;
-
-		/*
-		 * We don't expect to see acknowledgements for packets we
-		 * haven't sent yet.
-		 */
-		WARN_ON(xmit_count == 0);
-
-		/*
-		 * If the packet has only been sent once, we can use it
-		 * to calculate the RTT and also open the window a little
-		 * further.
-		 */
-		if (xmit_count == 1) {
-			if (dn_equal(segnum, acknum))
-				dn_nsp_rtt(sk, (long)(pkttime - reftime));
-
-			if (scp->snd_window < scp->max_window)
-				scp->snd_window++;
-		}
-
-		/*
-		 * Packet has been sent more than once. If this is the last
-		 * packet to be acknowledged then we want to send the next
-		 * packet in the send queue again (assumes the remote host does
-		 * go-back-N error control).
-		 */
-		if (xmit_count > 1)
-			try_retrans = 1;
-	}
-
-	if (try_retrans)
-		dn_nsp_output(sk);
-
-	return wakeup;
-}
-
-void dn_nsp_send_data_ack(struct sock *sk)
-{
-	struct sk_buff *skb = NULL;
-
-	if ((skb = dn_alloc_skb(sk, 9, GFP_ATOMIC)) == NULL)
-		return;
-
-	skb_reserve(skb, 9);
-	dn_mk_ack_header(sk, skb, 0x04, 9, 0);
-	dn_nsp_send(skb);
-}
-
-void dn_nsp_send_oth_ack(struct sock *sk)
-{
-	struct sk_buff *skb = NULL;
-
-	if ((skb = dn_alloc_skb(sk, 9, GFP_ATOMIC)) == NULL)
-		return;
-
-	skb_reserve(skb, 9);
-	dn_mk_ack_header(sk, skb, 0x14, 9, 1);
-	dn_nsp_send(skb);
-}
-
-
-void dn_send_conn_ack (struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	struct sk_buff *skb = NULL;
-	struct nsp_conn_ack_msg *msg;
-
-	if ((skb = dn_alloc_skb(sk, 3, sk->sk_allocation)) == NULL)
-		return;
-
-	msg = skb_put(skb, 3);
-	msg->msgflg = 0x24;
-	msg->dstaddr = scp->addrrem;
-
-	dn_nsp_send(skb);
-}
-
-static int dn_nsp_retrans_conn_conf(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	if (scp->state == DN_CC)
-		dn_send_conn_conf(sk, GFP_ATOMIC);
-
-	return 0;
-}
-
-void dn_send_conn_conf(struct sock *sk, gfp_t gfp)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	struct sk_buff *skb = NULL;
-	struct nsp_conn_init_msg *msg;
-	__u8 len = (__u8)le16_to_cpu(scp->conndata_out.opt_optl);
-
-	if ((skb = dn_alloc_skb(sk, 50 + len, gfp)) == NULL)
-		return;
-
-	msg = skb_put(skb, sizeof(*msg));
-	msg->msgflg = 0x28;
-	msg->dstaddr = scp->addrrem;
-	msg->srcaddr = scp->addrloc;
-	msg->services = scp->services_loc;
-	msg->info = scp->info_loc;
-	msg->segsize = cpu_to_le16(scp->segsize_loc);
-
-	skb_put_u8(skb, len);
-
-	if (len > 0)
-		skb_put_data(skb, scp->conndata_out.opt_data, len);
-
-
-	dn_nsp_send(skb);
-
-	scp->persist = dn_nsp_persist(sk);
-	scp->persist_fxn = dn_nsp_retrans_conn_conf;
-}
-
-
-static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg,
-			unsigned short reason, gfp_t gfp,
-			struct dst_entry *dst,
-			int ddl, unsigned char *dd, __le16 rem, __le16 loc)
-{
-	struct sk_buff *skb = NULL;
-	int size = 7 + ddl + ((msgflg == NSP_DISCINIT) ? 1 : 0);
-	unsigned char *msg;
-
-	if ((dst == NULL) || (rem == 0)) {
-		net_dbg_ratelimited("DECnet: dn_nsp_do_disc: BUG! Please report this to SteveW@ACM.org rem=%u dst=%p\n",
-				    le16_to_cpu(rem), dst);
-		return;
-	}
-
-	if ((skb = dn_alloc_skb(sk, size, gfp)) == NULL)
-		return;
-
-	msg = skb_put(skb, size);
-	*msg++ = msgflg;
-	*(__le16 *)msg = rem;
-	msg += 2;
-	*(__le16 *)msg = loc;
-	msg += 2;
-	*(__le16 *)msg = cpu_to_le16(reason);
-	msg += 2;
-	if (msgflg == NSP_DISCINIT)
-		*msg++ = ddl;
-
-	if (ddl) {
-		memcpy(msg, dd, ddl);
-	}
-
-	/*
-	 * This doesn't go via the dn_nsp_send() function since we need
-	 * to be able to send disc packets out which have no socket
-	 * associations.
-	 */
-	skb_dst_set(skb, dst_clone(dst));
-	dst_output(&init_net, skb->sk, skb);
-}
-
-
-void dn_nsp_send_disc(struct sock *sk, unsigned char msgflg,
-			unsigned short reason, gfp_t gfp)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	int ddl = 0;
-
-	if (msgflg == NSP_DISCINIT)
-		ddl = le16_to_cpu(scp->discdata_out.opt_optl);
-
-	if (reason == 0)
-		reason = le16_to_cpu(scp->discdata_out.opt_status);
-
-	dn_nsp_do_disc(sk, msgflg, reason, gfp, __sk_dst_get(sk), ddl,
-		scp->discdata_out.opt_data, scp->addrrem, scp->addrloc);
-}
-
-
-void dn_nsp_return_disc(struct sk_buff *skb, unsigned char msgflg,
-			unsigned short reason)
-{
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	int ddl = 0;
-	gfp_t gfp = GFP_ATOMIC;
-
-	dn_nsp_do_disc(NULL, msgflg, reason, gfp, skb_dst(skb), ddl,
-			NULL, cb->src_port, cb->dst_port);
-}
-
-
-void dn_nsp_send_link(struct sock *sk, unsigned char lsflags, char fcval)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	struct sk_buff *skb;
-	unsigned char *ptr;
-	gfp_t gfp = GFP_ATOMIC;
-
-	if ((skb = dn_alloc_skb(sk, DN_MAX_NSP_DATA_HEADER + 2, gfp)) == NULL)
-		return;
-
-	skb_reserve(skb, DN_MAX_NSP_DATA_HEADER);
-	ptr = skb_put(skb, 2);
-	DN_SKB_CB(skb)->nsp_flags = 0x10;
-	*ptr++ = lsflags;
-	*ptr = fcval;
-
-	dn_nsp_queue_xmit(sk, skb, gfp, 1);
-
-	scp->persist = dn_nsp_persist(sk);
-	scp->persist_fxn = dn_nsp_xmit_timeout;
-}
-
-static int dn_nsp_retrans_conninit(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	if (scp->state == DN_CI)
-		dn_nsp_send_conninit(sk, NSP_RCI);
-
-	return 0;
-}
-
-void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg)
-{
-	struct dn_scp *scp = DN_SK(sk);
-	struct nsp_conn_init_msg *msg;
-	unsigned char aux;
-	unsigned char menuver;
-	struct dn_skb_cb *cb;
-	unsigned char type = 1;
-	gfp_t allocation = (msgflg == NSP_CI) ? sk->sk_allocation : GFP_ATOMIC;
-	struct sk_buff *skb = dn_alloc_skb(sk, 200, allocation);
-
-	if (!skb)
-		return;
-
-	cb  = DN_SKB_CB(skb);
-	msg = skb_put(skb, sizeof(*msg));
-
-	msg->msgflg	= msgflg;
-	msg->dstaddr	= 0x0000;		/* Remote Node will assign it*/
-
-	msg->srcaddr	= scp->addrloc;
-	msg->services	= scp->services_loc;	/* Requested flow control    */
-	msg->info	= scp->info_loc;	/* Version Number            */
-	msg->segsize	= cpu_to_le16(scp->segsize_loc);	/* Max segment size  */
-
-	if (scp->peer.sdn_objnum)
-		type = 0;
-
-	skb_put(skb, dn_sockaddr2username(&scp->peer,
-					  skb_tail_pointer(skb), type));
-	skb_put(skb, dn_sockaddr2username(&scp->addr,
-					  skb_tail_pointer(skb), 2));
-
-	menuver = DN_MENUVER_ACC | DN_MENUVER_USR;
-	if (scp->peer.sdn_flags & SDF_PROXY)
-		menuver |= DN_MENUVER_PRX;
-	if (scp->peer.sdn_flags & SDF_UICPROXY)
-		menuver |= DN_MENUVER_UIC;
-
-	skb_put_u8(skb, menuver);	/* Menu Version		*/
-
-	aux = scp->accessdata.acc_userl;
-	skb_put_u8(skb, aux);
-	if (aux > 0)
-		skb_put_data(skb, scp->accessdata.acc_user, aux);
-
-	aux = scp->accessdata.acc_passl;
-	skb_put_u8(skb, aux);
-	if (aux > 0)
-		skb_put_data(skb, scp->accessdata.acc_pass, aux);
-
-	aux = scp->accessdata.acc_accl;
-	skb_put_u8(skb, aux);
-	if (aux > 0)
-		skb_put_data(skb, scp->accessdata.acc_acc, aux);
-
-	aux = (__u8)le16_to_cpu(scp->conndata_out.opt_optl);
-	skb_put_u8(skb, aux);
-	if (aux > 0)
-		skb_put_data(skb, scp->conndata_out.opt_data, aux);
-
-	scp->persist = dn_nsp_persist(sk);
-	scp->persist_fxn = dn_nsp_retrans_conninit;
-
-	cb->rt_flags = DN_RT_F_RQR;
-
-	dn_nsp_send(skb);
-}
diff --git a/kernel/net/decnet/dn_route.c b/kernel/net/decnet/dn_route.c
deleted file mode 100644
index 4cac31d..0000000
--- a/kernel/net/decnet/dn_route.c
+++ /dev/null
@@ -1,1923 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * DECnet       An implementation of the DECnet protocol suite for the LINUX
- *              operating system.  DECnet is implemented using the  BSD Socket
- *              interface as the means of communication with the user level.
- *
- *              DECnet Routing Functions (Endnode and Router)
- *
- * Authors:     Steve Whitehouse <SteveW@ACM.org>
- *              Eduardo Marcelo Serrat <emserrat@geocities.com>
- *
- * Changes:
- *              Steve Whitehouse : Fixes to allow "intra-ethernet" and
- *                                 "return-to-sender" bits on outgoing
- *                                 packets.
- *		Steve Whitehouse : Timeouts for cached routes.
- *              Steve Whitehouse : Use dst cache for input routes too.
- *              Steve Whitehouse : Fixed error values in dn_send_skb.
- *              Steve Whitehouse : Rework routing functions to better fit
- *                                 DECnet routing design
- *              Alexey Kuznetsov : New SMP locking
- *              Steve Whitehouse : More SMP locking changes & dn_cache_dump()
- *              Steve Whitehouse : Prerouting NF hook, now really is prerouting.
- *				   Fixed possible skb leak in rtnetlink funcs.
- *              Steve Whitehouse : Dave Miller's dynamic hash table sizing and
- *                                 Alexey Kuznetsov's finer grained locking
- *                                 from ipv4/route.c.
- *              Steve Whitehouse : Routing is now starting to look like a
- *                                 sensible set of code now, mainly due to
- *                                 my copying the IPv4 routing code. The
- *                                 hooks here are modified and will continue
- *                                 to evolve for a while.
- *              Steve Whitehouse : Real SMP at last :-) Also new netfilter
- *                                 stuff. Look out raw sockets your days
- *                                 are numbered!
- *              Steve Whitehouse : Added return-to-sender functions. Added
- *                                 backlog congestion level return codes.
- *		Steve Whitehouse : Fixed bug where routes were set up with
- *                                 no ref count on net devices.
- *              Steve Whitehouse : RCU for the route cache
- *              Steve Whitehouse : Preparations for the flow cache
- *              Steve Whitehouse : Prepare for nonlinear skbs
- */
-
-/******************************************************************************
-    (c) 1995-1998 E.M. Serrat		emserrat@geocities.com
-
-*******************************************************************************/
-
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/netdevice.h>
-#include <linux/inet.h>
-#include <linux/route.h>
-#include <linux/in_route.h>
-#include <linux/slab.h>
-#include <net/sock.h>
-#include <linux/mm.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/init.h>
-#include <linux/rtnetlink.h>
-#include <linux/string.h>
-#include <linux/netfilter_decnet.h>
-#include <linux/rcupdate.h>
-#include <linux/times.h>
-#include <linux/export.h>
-#include <asm/errno.h>
-#include <net/net_namespace.h>
-#include <net/netlink.h>
-#include <net/neighbour.h>
-#include <net/dst.h>
-#include <net/flow.h>
-#include <net/fib_rules.h>
-#include <net/dn.h>
-#include <net/dn_dev.h>
-#include <net/dn_nsp.h>
-#include <net/dn_route.h>
-#include <net/dn_neigh.h>
-#include <net/dn_fib.h>
-
-struct dn_rt_hash_bucket
-{
-	struct dn_route __rcu *chain;
-	spinlock_t lock;
-};
-
-extern struct neigh_table dn_neigh_table;
-
-
-static unsigned char dn_hiord_addr[6] = {0xAA,0x00,0x04,0x00,0x00,0x00};
-
-static const int dn_rt_min_delay = 2 * HZ;
-static const int dn_rt_max_delay = 10 * HZ;
-static const int dn_rt_mtu_expires = 10 * 60 * HZ;
-
-static unsigned long dn_rt_deadline;
-
-static int dn_dst_gc(struct dst_ops *ops);
-static struct dst_entry *dn_dst_check(struct dst_entry *, __u32);
-static unsigned int dn_dst_default_advmss(const struct dst_entry *dst);
-static unsigned int dn_dst_mtu(const struct dst_entry *dst);
-static void dn_dst_destroy(struct dst_entry *);
-static void dn_dst_ifdown(struct dst_entry *, struct net_device *dev, int how);
-static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
-static void dn_dst_link_failure(struct sk_buff *);
-static void dn_dst_update_pmtu(struct dst_entry *dst, struct sock *sk,
-			       struct sk_buff *skb , u32 mtu,
-			       bool confirm_neigh);
-static void dn_dst_redirect(struct dst_entry *dst, struct sock *sk,
-			    struct sk_buff *skb);
-static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst,
-					     struct sk_buff *skb,
-					     const void *daddr);
-static int dn_route_input(struct sk_buff *);
-static void dn_run_flush(struct timer_list *unused);
-
-static struct dn_rt_hash_bucket *dn_rt_hash_table;
-static unsigned int dn_rt_hash_mask;
-
-static struct timer_list dn_route_timer;
-static DEFINE_TIMER(dn_rt_flush_timer, dn_run_flush);
-int decnet_dst_gc_interval = 2;
-
-static struct dst_ops dn_dst_ops = {
-	.family =		PF_DECnet,
-	.gc_thresh =		128,
-	.gc =			dn_dst_gc,
-	.check =		dn_dst_check,
-	.default_advmss =	dn_dst_default_advmss,
-	.mtu =			dn_dst_mtu,
-	.cow_metrics =		dst_cow_metrics_generic,
-	.destroy =		dn_dst_destroy,
-	.ifdown =		dn_dst_ifdown,
-	.negative_advice =	dn_dst_negative_advice,
-	.link_failure =		dn_dst_link_failure,
-	.update_pmtu =		dn_dst_update_pmtu,
-	.redirect =		dn_dst_redirect,
-	.neigh_lookup =		dn_dst_neigh_lookup,
-};
-
-static void dn_dst_destroy(struct dst_entry *dst)
-{
-	struct dn_route *rt = (struct dn_route *) dst;
-
-	if (rt->n)
-		neigh_release(rt->n);
-	dst_destroy_metrics_generic(dst);
-}
-
-static void dn_dst_ifdown(struct dst_entry *dst, struct net_device *dev, int how)
-{
-	if (how) {
-		struct dn_route *rt = (struct dn_route *) dst;
-		struct neighbour *n = rt->n;
-
-		if (n && n->dev == dev) {
-			n->dev = dev_net(dev)->loopback_dev;
-			dev_hold(n->dev);
-			dev_put(dev);
-		}
-	}
-}
-
-static __inline__ unsigned int dn_hash(__le16 src, __le16 dst)
-{
-	__u16 tmp = (__u16 __force)(src ^ dst);
-	tmp ^= (tmp >> 3);
-	tmp ^= (tmp >> 5);
-	tmp ^= (tmp >> 10);
-	return dn_rt_hash_mask & (unsigned int)tmp;
-}
-
-static void dn_dst_check_expire(struct timer_list *unused)
-{
-	int i;
-	struct dn_route *rt;
-	struct dn_route __rcu **rtp;
-	unsigned long now = jiffies;
-	unsigned long expire = 120 * HZ;
-
-	for (i = 0; i <= dn_rt_hash_mask; i++) {
-		rtp = &dn_rt_hash_table[i].chain;
-
-		spin_lock(&dn_rt_hash_table[i].lock);
-		while ((rt = rcu_dereference_protected(*rtp,
-						lockdep_is_held(&dn_rt_hash_table[i].lock))) != NULL) {
-			if (atomic_read(&rt->dst.__refcnt) > 1 ||
-			    (now - rt->dst.lastuse) < expire) {
-				rtp = &rt->dn_next;
-				continue;
-			}
-			*rtp = rt->dn_next;
-			rt->dn_next = NULL;
-			dst_dev_put(&rt->dst);
-			dst_release(&rt->dst);
-		}
-		spin_unlock(&dn_rt_hash_table[i].lock);
-
-		if ((jiffies - now) > 0)
-			break;
-	}
-
-	mod_timer(&dn_route_timer, now + decnet_dst_gc_interval * HZ);
-}
-
-static int dn_dst_gc(struct dst_ops *ops)
-{
-	struct dn_route *rt;
-	struct dn_route __rcu **rtp;
-	int i;
-	unsigned long now = jiffies;
-	unsigned long expire = 10 * HZ;
-
-	for (i = 0; i <= dn_rt_hash_mask; i++) {
-
-		spin_lock_bh(&dn_rt_hash_table[i].lock);
-		rtp = &dn_rt_hash_table[i].chain;
-
-		while ((rt = rcu_dereference_protected(*rtp,
-						lockdep_is_held(&dn_rt_hash_table[i].lock))) != NULL) {
-			if (atomic_read(&rt->dst.__refcnt) > 1 ||
-			    (now - rt->dst.lastuse) < expire) {
-				rtp = &rt->dn_next;
-				continue;
-			}
-			*rtp = rt->dn_next;
-			rt->dn_next = NULL;
-			dst_dev_put(&rt->dst);
-			dst_release(&rt->dst);
-			break;
-		}
-		spin_unlock_bh(&dn_rt_hash_table[i].lock);
-	}
-
-	return 0;
-}
-
-/*
- * The decnet standards don't impose a particular minimum mtu, what they
- * do insist on is that the routing layer accepts a datagram of at least
- * 230 bytes long. Here we have to subtract the routing header length from
- * 230 to get the minimum acceptable mtu. If there is no neighbour, then we
- * assume the worst and use a long header size.
- *
- * We update both the mtu and the advertised mss (i.e. the segment size we
- * advertise to the other end).
- */
-static void dn_dst_update_pmtu(struct dst_entry *dst, struct sock *sk,
-			       struct sk_buff *skb, u32 mtu,
-			       bool confirm_neigh)
-{
-	struct dn_route *rt = (struct dn_route *) dst;
-	struct neighbour *n = rt->n;
-	u32 min_mtu = 230;
-	struct dn_dev *dn;
-
-	dn = n ? rcu_dereference_raw(n->dev->dn_ptr) : NULL;
-
-	if (dn && dn->use_long == 0)
-		min_mtu -= 6;
-	else
-		min_mtu -= 21;
-
-	if (dst_metric(dst, RTAX_MTU) > mtu && mtu >= min_mtu) {
-		if (!(dst_metric_locked(dst, RTAX_MTU))) {
-			dst_metric_set(dst, RTAX_MTU, mtu);
-			dst_set_expires(dst, dn_rt_mtu_expires);
-		}
-		if (!(dst_metric_locked(dst, RTAX_ADVMSS))) {
-			u32 mss = mtu - DN_MAX_NSP_DATA_HEADER;
-			u32 existing_mss = dst_metric_raw(dst, RTAX_ADVMSS);
-			if (!existing_mss || existing_mss > mss)
-				dst_metric_set(dst, RTAX_ADVMSS, mss);
-		}
-	}
-}
-
-static void dn_dst_redirect(struct dst_entry *dst, struct sock *sk,
-			    struct sk_buff *skb)
-{
-}
-
-/*
- * When a route has been marked obsolete. (e.g. routing cache flush)
- */
-static struct dst_entry *dn_dst_check(struct dst_entry *dst, __u32 cookie)
-{
-	return NULL;
-}
-
-static struct dst_entry *dn_dst_negative_advice(struct dst_entry *dst)
-{
-	dst_release(dst);
-	return NULL;
-}
-
-static void dn_dst_link_failure(struct sk_buff *skb)
-{
-}
-
-static inline int compare_keys(struct flowidn *fl1, struct flowidn *fl2)
-{
-	return ((fl1->daddr ^ fl2->daddr) |
-		(fl1->saddr ^ fl2->saddr) |
-		(fl1->flowidn_mark ^ fl2->flowidn_mark) |
-		(fl1->flowidn_scope ^ fl2->flowidn_scope) |
-		(fl1->flowidn_oif ^ fl2->flowidn_oif) |
-		(fl1->flowidn_iif ^ fl2->flowidn_iif)) == 0;
-}
-
-static int dn_insert_route(struct dn_route *rt, unsigned int hash, struct dn_route **rp)
-{
-	struct dn_route *rth;
-	struct dn_route __rcu **rthp;
-	unsigned long now = jiffies;
-
-	rthp = &dn_rt_hash_table[hash].chain;
-
-	spin_lock_bh(&dn_rt_hash_table[hash].lock);
-	while ((rth = rcu_dereference_protected(*rthp,
-						lockdep_is_held(&dn_rt_hash_table[hash].lock))) != NULL) {
-		if (compare_keys(&rth->fld, &rt->fld)) {
-			/* Put it first */
-			*rthp = rth->dn_next;
-			rcu_assign_pointer(rth->dn_next,
-					   dn_rt_hash_table[hash].chain);
-			rcu_assign_pointer(dn_rt_hash_table[hash].chain, rth);
-
-			dst_hold_and_use(&rth->dst, now);
-			spin_unlock_bh(&dn_rt_hash_table[hash].lock);
-
-			dst_release_immediate(&rt->dst);
-			*rp = rth;
-			return 0;
-		}
-		rthp = &rth->dn_next;
-	}
-
-	rcu_assign_pointer(rt->dn_next, dn_rt_hash_table[hash].chain);
-	rcu_assign_pointer(dn_rt_hash_table[hash].chain, rt);
-
-	dst_hold_and_use(&rt->dst, now);
-	spin_unlock_bh(&dn_rt_hash_table[hash].lock);
-	*rp = rt;
-	return 0;
-}
-
-static void dn_run_flush(struct timer_list *unused)
-{
-	int i;
-	struct dn_route *rt, *next;
-
-	for (i = 0; i < dn_rt_hash_mask; i++) {
-		spin_lock_bh(&dn_rt_hash_table[i].lock);
-
-		if ((rt = xchg((struct dn_route **)&dn_rt_hash_table[i].chain, NULL)) == NULL)
-			goto nothing_to_declare;
-
-		for(; rt; rt = next) {
-			next = rcu_dereference_raw(rt->dn_next);
-			RCU_INIT_POINTER(rt->dn_next, NULL);
-			dst_dev_put(&rt->dst);
-			dst_release(&rt->dst);
-		}
-
-nothing_to_declare:
-		spin_unlock_bh(&dn_rt_hash_table[i].lock);
-	}
-}
-
-static DEFINE_SPINLOCK(dn_rt_flush_lock);
-
-void dn_rt_cache_flush(int delay)
-{
-	unsigned long now = jiffies;
-	int user_mode = !in_interrupt();
-
-	if (delay < 0)
-		delay = dn_rt_min_delay;
-
-	spin_lock_bh(&dn_rt_flush_lock);
-
-	if (del_timer(&dn_rt_flush_timer) && delay > 0 && dn_rt_deadline) {
-		long tmo = (long)(dn_rt_deadline - now);
-
-		if (user_mode && tmo < dn_rt_max_delay - dn_rt_min_delay)
-			tmo = 0;
-
-		if (delay > tmo)
-			delay = tmo;
-	}
-
-	if (delay <= 0) {
-		spin_unlock_bh(&dn_rt_flush_lock);
-		dn_run_flush(NULL);
-		return;
-	}
-
-	if (dn_rt_deadline == 0)
-		dn_rt_deadline = now + dn_rt_max_delay;
-
-	dn_rt_flush_timer.expires = now + delay;
-	add_timer(&dn_rt_flush_timer);
-	spin_unlock_bh(&dn_rt_flush_lock);
-}
-
-/**
- * dn_return_short - Return a short packet to its sender
- * @skb: The packet to return
- *
- */
-static int dn_return_short(struct sk_buff *skb)
-{
-	struct dn_skb_cb *cb;
-	unsigned char *ptr;
-	__le16 *src;
-	__le16 *dst;
-
-	/* Add back headers */
-	skb_push(skb, skb->data - skb_network_header(skb));
-
-	if ((skb = skb_unshare(skb, GFP_ATOMIC)) == NULL)
-		return NET_RX_DROP;
-
-	cb = DN_SKB_CB(skb);
-	/* Skip packet length and point to flags */
-	ptr = skb->data + 2;
-	*ptr++ = (cb->rt_flags & ~DN_RT_F_RQR) | DN_RT_F_RTS;
-
-	dst = (__le16 *)ptr;
-	ptr += 2;
-	src = (__le16 *)ptr;
-	ptr += 2;
-	*ptr = 0; /* Zero hop count */
-
-	swap(*src, *dst);
-
-	skb->pkt_type = PACKET_OUTGOING;
-	dn_rt_finish_output(skb, NULL, NULL);
-	return NET_RX_SUCCESS;
-}
-
-/**
- * dn_return_long - Return a long packet to its sender
- * @skb: The long format packet to return
- *
- */
-static int dn_return_long(struct sk_buff *skb)
-{
-	struct dn_skb_cb *cb;
-	unsigned char *ptr;
-	unsigned char *src_addr, *dst_addr;
-	unsigned char tmp[ETH_ALEN];
-
-	/* Add back all headers */
-	skb_push(skb, skb->data - skb_network_header(skb));
-
-	if ((skb = skb_unshare(skb, GFP_ATOMIC)) == NULL)
-		return NET_RX_DROP;
-
-	cb = DN_SKB_CB(skb);
-	/* Ignore packet length and point to flags */
-	ptr = skb->data + 2;
-
-	/* Skip padding */
-	if (*ptr & DN_RT_F_PF) {
-		char padlen = (*ptr & ~DN_RT_F_PF);
-		ptr += padlen;
-	}
-
-	*ptr++ = (cb->rt_flags & ~DN_RT_F_RQR) | DN_RT_F_RTS;
-	ptr += 2;
-	dst_addr = ptr;
-	ptr += 8;
-	src_addr = ptr;
-	ptr += 6;
-	*ptr = 0; /* Zero hop count */
-
-	/* Swap source and destination */
-	memcpy(tmp, src_addr, ETH_ALEN);
-	memcpy(src_addr, dst_addr, ETH_ALEN);
-	memcpy(dst_addr, tmp, ETH_ALEN);
-
-	skb->pkt_type = PACKET_OUTGOING;
-	dn_rt_finish_output(skb, dst_addr, src_addr);
-	return NET_RX_SUCCESS;
-}
-
-/**
- * dn_route_rx_packet - Try and find a route for an incoming packet
- * @net: The applicable net namespace
- * @sk: Socket packet transmitted on
- * @skb: The packet to find a route for
- *
- * Returns: result of input function if route is found, error code otherwise
- */
-static int dn_route_rx_packet(struct net *net, struct sock *sk, struct sk_buff *skb)
-{
-	struct dn_skb_cb *cb;
-	int err;
-
-	if ((err = dn_route_input(skb)) == 0)
-		return dst_input(skb);
-
-	cb = DN_SKB_CB(skb);
-	if (decnet_debug_level & 4) {
-		char *devname = skb->dev ? skb->dev->name : "???";
-
-		printk(KERN_DEBUG
-			"DECnet: dn_route_rx_packet: rt_flags=0x%02x dev=%s len=%d src=0x%04hx dst=0x%04hx err=%d type=%d\n",
-			(int)cb->rt_flags, devname, skb->len,
-			le16_to_cpu(cb->src), le16_to_cpu(cb->dst),
-			err, skb->pkt_type);
-	}
-
-	if ((skb->pkt_type == PACKET_HOST) && (cb->rt_flags & DN_RT_F_RQR)) {
-		switch (cb->rt_flags & DN_RT_PKT_MSK) {
-		case DN_RT_PKT_SHORT:
-			return dn_return_short(skb);
-		case DN_RT_PKT_LONG:
-			return dn_return_long(skb);
-		}
-	}
-
-	kfree_skb(skb);
-	return NET_RX_DROP;
-}
-
-static int dn_route_rx_long(struct sk_buff *skb)
-{
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	unsigned char *ptr = skb->data;
-
-	if (!pskb_may_pull(skb, 21)) /* 20 for long header, 1 for shortest nsp */
-		goto drop_it;
-
-	skb_pull(skb, 20);
-	skb_reset_transport_header(skb);
-
-	/* Destination info */
-	ptr += 2;
-	cb->dst = dn_eth2dn(ptr);
-	if (memcmp(ptr, dn_hiord_addr, 4) != 0)
-		goto drop_it;
-	ptr += 6;
-
-
-	/* Source info */
-	ptr += 2;
-	cb->src = dn_eth2dn(ptr);
-	if (memcmp(ptr, dn_hiord_addr, 4) != 0)
-		goto drop_it;
-	ptr += 6;
-	/* Other junk */
-	ptr++;
-	cb->hops = *ptr++; /* Visit Count */
-
-	return NF_HOOK(NFPROTO_DECNET, NF_DN_PRE_ROUTING,
-		       &init_net, NULL, skb, skb->dev, NULL,
-		       dn_route_rx_packet);
-
-drop_it:
-	kfree_skb(skb);
-	return NET_RX_DROP;
-}
-
-
-
-static int dn_route_rx_short(struct sk_buff *skb)
-{
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	unsigned char *ptr = skb->data;
-
-	if (!pskb_may_pull(skb, 6)) /* 5 for short header + 1 for shortest nsp */
-		goto drop_it;
-
-	skb_pull(skb, 5);
-	skb_reset_transport_header(skb);
-
-	cb->dst = *(__le16 *)ptr;
-	ptr += 2;
-	cb->src = *(__le16 *)ptr;
-	ptr += 2;
-	cb->hops = *ptr & 0x3f;
-
-	return NF_HOOK(NFPROTO_DECNET, NF_DN_PRE_ROUTING,
-		       &init_net, NULL, skb, skb->dev, NULL,
-		       dn_route_rx_packet);
-
-drop_it:
-	kfree_skb(skb);
-	return NET_RX_DROP;
-}
-
-static int dn_route_discard(struct net *net, struct sock *sk, struct sk_buff *skb)
-{
-	/*
-	 * I know we drop the packet here, but thats considered success in
-	 * this case
-	 */
-	kfree_skb(skb);
-	return NET_RX_SUCCESS;
-}
-
-static int dn_route_ptp_hello(struct net *net, struct sock *sk, struct sk_buff *skb)
-{
-	dn_dev_hello(skb);
-	dn_neigh_pointopoint_hello(skb);
-	return NET_RX_SUCCESS;
-}
-
-int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
-{
-	struct dn_skb_cb *cb;
-	unsigned char flags = 0;
-	__u16 len = le16_to_cpu(*(__le16 *)skb->data);
-	struct dn_dev *dn = rcu_dereference(dev->dn_ptr);
-	unsigned char padlen = 0;
-
-	if (!net_eq(dev_net(dev), &init_net))
-		goto dump_it;
-
-	if (dn == NULL)
-		goto dump_it;
-
-	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
-		goto out;
-
-	if (!pskb_may_pull(skb, 3))
-		goto dump_it;
-
-	skb_pull(skb, 2);
-
-	if (len > skb->len)
-		goto dump_it;
-
-	skb_trim(skb, len);
-
-	flags = *skb->data;
-
-	cb = DN_SKB_CB(skb);
-	cb->stamp = jiffies;
-	cb->iif = dev->ifindex;
-
-	/*
-	 * If we have padding, remove it.
-	 */
-	if (flags & DN_RT_F_PF) {
-		padlen = flags & ~DN_RT_F_PF;
-		if (!pskb_may_pull(skb, padlen + 1))
-			goto dump_it;
-		skb_pull(skb, padlen);
-		flags = *skb->data;
-	}
-
-	skb_reset_network_header(skb);
-
-	/*
-	 * Weed out future version DECnet
-	 */
-	if (flags & DN_RT_F_VER)
-		goto dump_it;
-
-	cb->rt_flags = flags;
-
-	if (decnet_debug_level & 1)
-		printk(KERN_DEBUG
-			"dn_route_rcv: got 0x%02x from %s [%d %d %d]\n",
-			(int)flags, dev->name, len, skb->len,
-			padlen);
-
-	if (flags & DN_RT_PKT_CNTL) {
-		if (unlikely(skb_linearize(skb)))
-			goto dump_it;
-
-		switch (flags & DN_RT_CNTL_MSK) {
-		case DN_RT_PKT_INIT:
-			dn_dev_init_pkt(skb);
-			break;
-		case DN_RT_PKT_VERI:
-			dn_dev_veri_pkt(skb);
-			break;
-		}
-
-		if (dn->parms.state != DN_DEV_S_RU)
-			goto dump_it;
-
-		switch (flags & DN_RT_CNTL_MSK) {
-		case DN_RT_PKT_HELO:
-			return NF_HOOK(NFPROTO_DECNET, NF_DN_HELLO,
-				       &init_net, NULL, skb, skb->dev, NULL,
-				       dn_route_ptp_hello);
-
-		case DN_RT_PKT_L1RT:
-		case DN_RT_PKT_L2RT:
-			return NF_HOOK(NFPROTO_DECNET, NF_DN_ROUTE,
-				       &init_net, NULL, skb, skb->dev, NULL,
-				       dn_route_discard);
-		case DN_RT_PKT_ERTH:
-			return NF_HOOK(NFPROTO_DECNET, NF_DN_HELLO,
-				       &init_net, NULL, skb, skb->dev, NULL,
-				       dn_neigh_router_hello);
-
-		case DN_RT_PKT_EEDH:
-			return NF_HOOK(NFPROTO_DECNET, NF_DN_HELLO,
-				       &init_net, NULL, skb, skb->dev, NULL,
-				       dn_neigh_endnode_hello);
-		}
-	} else {
-		if (dn->parms.state != DN_DEV_S_RU)
-			goto dump_it;
-
-		skb_pull(skb, 1); /* Pull flags */
-
-		switch (flags & DN_RT_PKT_MSK) {
-		case DN_RT_PKT_LONG:
-			return dn_route_rx_long(skb);
-		case DN_RT_PKT_SHORT:
-			return dn_route_rx_short(skb);
-		}
-	}
-
-dump_it:
-	kfree_skb(skb);
-out:
-	return NET_RX_DROP;
-}
-
-static int dn_output(struct net *net, struct sock *sk, struct sk_buff *skb)
-{
-	struct dst_entry *dst = skb_dst(skb);
-	struct dn_route *rt = (struct dn_route *)dst;
-	struct net_device *dev = dst->dev;
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-
-	int err = -EINVAL;
-
-	if (rt->n == NULL)
-		goto error;
-
-	skb->dev = dev;
-
-	cb->src = rt->rt_saddr;
-	cb->dst = rt->rt_daddr;
-
-	/*
-	 * Always set the Intra-Ethernet bit on all outgoing packets
-	 * originated on this node. Only valid flag from upper layers
-	 * is return-to-sender-requested. Set hop count to 0 too.
-	 */
-	cb->rt_flags &= ~DN_RT_F_RQR;
-	cb->rt_flags |= DN_RT_F_IE;
-	cb->hops = 0;
-
-	return NF_HOOK(NFPROTO_DECNET, NF_DN_LOCAL_OUT,
-		       &init_net, sk, skb, NULL, dev,
-		       dn_to_neigh_output);
-
-error:
-	net_dbg_ratelimited("dn_output: This should not happen\n");
-
-	kfree_skb(skb);
-
-	return err;
-}
-
-static int dn_forward(struct sk_buff *skb)
-{
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	struct dst_entry *dst = skb_dst(skb);
-	struct dn_dev *dn_db = rcu_dereference(dst->dev->dn_ptr);
-	struct dn_route *rt;
-	int header_len;
-	struct net_device *dev = skb->dev;
-
-	if (skb->pkt_type != PACKET_HOST)
-		goto drop;
-
-	/* Ensure that we have enough space for headers */
-	rt = (struct dn_route *)skb_dst(skb);
-	header_len = dn_db->use_long ? 21 : 6;
-	if (skb_cow(skb, LL_RESERVED_SPACE(rt->dst.dev)+header_len))
-		goto drop;
-
-	/*
-	 * Hop count exceeded.
-	 */
-	if (++cb->hops > 30)
-		goto drop;
-
-	skb->dev = rt->dst.dev;
-
-	/*
-	 * If packet goes out same interface it came in on, then set
-	 * the Intra-Ethernet bit. This has no effect for short
-	 * packets, so we don't need to test for them here.
-	 */
-	cb->rt_flags &= ~DN_RT_F_IE;
-	if (rt->rt_flags & RTCF_DOREDIRECT)
-		cb->rt_flags |= DN_RT_F_IE;
-
-	return NF_HOOK(NFPROTO_DECNET, NF_DN_FORWARD,
-		       &init_net, NULL, skb, dev, skb->dev,
-		       dn_to_neigh_output);
-
-drop:
-	kfree_skb(skb);
-	return NET_RX_DROP;
-}
-
-/*
- * Used to catch bugs. This should never normally get
- * called.
- */
-static int dn_rt_bug_out(struct net *net, struct sock *sk, struct sk_buff *skb)
-{
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-
-	net_dbg_ratelimited("dn_rt_bug: skb from:%04x to:%04x\n",
-			    le16_to_cpu(cb->src), le16_to_cpu(cb->dst));
-
-	kfree_skb(skb);
-
-	return NET_RX_DROP;
-}
-
-static int dn_rt_bug(struct sk_buff *skb)
-{
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-
-	net_dbg_ratelimited("dn_rt_bug: skb from:%04x to:%04x\n",
-			    le16_to_cpu(cb->src), le16_to_cpu(cb->dst));
-
-	kfree_skb(skb);
-
-	return NET_RX_DROP;
-}
-
-static unsigned int dn_dst_default_advmss(const struct dst_entry *dst)
-{
-	return dn_mss_from_pmtu(dst->dev, dst_mtu(dst));
-}
-
-static unsigned int dn_dst_mtu(const struct dst_entry *dst)
-{
-	unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
-
-	return mtu ? : dst->dev->mtu;
-}
-
-static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst,
-					     struct sk_buff *skb,
-					     const void *daddr)
-{
-	return __neigh_lookup_errno(&dn_neigh_table, daddr, dst->dev);
-}
-
-static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
-{
-	struct dn_fib_info *fi = res->fi;
-	struct net_device *dev = rt->dst.dev;
-	unsigned int mss_metric;
-	struct neighbour *n;
-
-	if (fi) {
-		if (DN_FIB_RES_GW(*res) &&
-		    DN_FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
-			rt->rt_gateway = DN_FIB_RES_GW(*res);
-		dst_init_metrics(&rt->dst, fi->fib_metrics, true);
-	}
-	rt->rt_type = res->type;
-
-	if (dev != NULL && rt->n == NULL) {
-		n = __neigh_lookup_errno(&dn_neigh_table, &rt->rt_gateway, dev);
-		if (IS_ERR(n))
-			return PTR_ERR(n);
-		rt->n = n;
-	}
-
-	if (dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu)
-		dst_metric_set(&rt->dst, RTAX_MTU, rt->dst.dev->mtu);
-	mss_metric = dst_metric_raw(&rt->dst, RTAX_ADVMSS);
-	if (mss_metric) {
-		unsigned int mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->dst));
-		if (mss_metric > mss)
-			dst_metric_set(&rt->dst, RTAX_ADVMSS, mss);
-	}
-	return 0;
-}
-
-static inline int dn_match_addr(__le16 addr1, __le16 addr2)
-{
-	__u16 tmp = le16_to_cpu(addr1) ^ le16_to_cpu(addr2);
-	int match = 16;
-	while(tmp) {
-		tmp >>= 1;
-		match--;
-	}
-	return match;
-}
-
-static __le16 dnet_select_source(const struct net_device *dev, __le16 daddr, int scope)
-{
-	__le16 saddr = 0;
-	struct dn_dev *dn_db;
-	struct dn_ifaddr *ifa;
-	int best_match = 0;
-	int ret;
-
-	rcu_read_lock();
-	dn_db = rcu_dereference(dev->dn_ptr);
-	for (ifa = rcu_dereference(dn_db->ifa_list);
-	     ifa != NULL;
-	     ifa = rcu_dereference(ifa->ifa_next)) {
-		if (ifa->ifa_scope > scope)
-			continue;
-		if (!daddr) {
-			saddr = ifa->ifa_local;
-			break;
-		}
-		ret = dn_match_addr(daddr, ifa->ifa_local);
-		if (ret > best_match)
-			saddr = ifa->ifa_local;
-		if (best_match == 0)
-			saddr = ifa->ifa_local;
-	}
-	rcu_read_unlock();
-
-	return saddr;
-}
-
-static inline __le16 __dn_fib_res_prefsrc(struct dn_fib_res *res)
-{
-	return dnet_select_source(DN_FIB_RES_DEV(*res), DN_FIB_RES_GW(*res), res->scope);
-}
-
-static inline __le16 dn_fib_rules_map_destination(__le16 daddr, struct dn_fib_res *res)
-{
-	__le16 mask = dnet_make_mask(res->prefixlen);
-	return (daddr&~mask)|res->fi->fib_nh->nh_gw;
-}
-
-static int dn_route_output_slow(struct dst_entry **pprt, const struct flowidn *oldflp, int try_hard)
-{
-	struct flowidn fld = {
-		.daddr = oldflp->daddr,
-		.saddr = oldflp->saddr,
-		.flowidn_scope = RT_SCOPE_UNIVERSE,
-		.flowidn_mark = oldflp->flowidn_mark,
-		.flowidn_iif = LOOPBACK_IFINDEX,
-		.flowidn_oif = oldflp->flowidn_oif,
-	};
-	struct dn_route *rt = NULL;
-	struct net_device *dev_out = NULL, *dev;
-	struct neighbour *neigh = NULL;
-	unsigned int hash;
-	unsigned int flags = 0;
-	struct dn_fib_res res = { .fi = NULL, .type = RTN_UNICAST };
-	int err;
-	int free_res = 0;
-	__le16 gateway = 0;
-
-	if (decnet_debug_level & 16)
-		printk(KERN_DEBUG
-		       "dn_route_output_slow: dst=%04x src=%04x mark=%d"
-		       " iif=%d oif=%d\n", le16_to_cpu(oldflp->daddr),
-		       le16_to_cpu(oldflp->saddr),
-		       oldflp->flowidn_mark, LOOPBACK_IFINDEX,
-		       oldflp->flowidn_oif);
-
-	/* If we have an output interface, verify its a DECnet device */
-	if (oldflp->flowidn_oif) {
-		dev_out = dev_get_by_index(&init_net, oldflp->flowidn_oif);
-		err = -ENODEV;
-		if (dev_out && dev_out->dn_ptr == NULL) {
-			dev_put(dev_out);
-			dev_out = NULL;
-		}
-		if (dev_out == NULL)
-			goto out;
-	}
-
-	/* If we have a source address, verify that its a local address */
-	if (oldflp->saddr) {
-		err = -EADDRNOTAVAIL;
-
-		if (dev_out) {
-			if (dn_dev_islocal(dev_out, oldflp->saddr))
-				goto source_ok;
-			dev_put(dev_out);
-			goto out;
-		}
-		rcu_read_lock();
-		for_each_netdev_rcu(&init_net, dev) {
-			if (!dev->dn_ptr)
-				continue;
-			if (!dn_dev_islocal(dev, oldflp->saddr))
-				continue;
-			if ((dev->flags & IFF_LOOPBACK) &&
-			    oldflp->daddr &&
-			    !dn_dev_islocal(dev, oldflp->daddr))
-				continue;
-
-			dev_out = dev;
-			break;
-		}
-		rcu_read_unlock();
-		if (dev_out == NULL)
-			goto out;
-		dev_hold(dev_out);
-source_ok:
-		;
-	}
-
-	/* No destination? Assume its local */
-	if (!fld.daddr) {
-		fld.daddr = fld.saddr;
-
-		if (dev_out)
-			dev_put(dev_out);
-		err = -EINVAL;
-		dev_out = init_net.loopback_dev;
-		if (!dev_out->dn_ptr)
-			goto out;
-		err = -EADDRNOTAVAIL;
-		dev_hold(dev_out);
-		if (!fld.daddr) {
-			fld.daddr =
-			fld.saddr = dnet_select_source(dev_out, 0,
-						       RT_SCOPE_HOST);
-			if (!fld.daddr)
-				goto out;
-		}
-		fld.flowidn_oif = LOOPBACK_IFINDEX;
-		res.type = RTN_LOCAL;
-		goto make_route;
-	}
-
-	if (decnet_debug_level & 16)
-		printk(KERN_DEBUG
-		       "dn_route_output_slow: initial checks complete."
-		       " dst=%04x src=%04x oif=%d try_hard=%d\n",
-		       le16_to_cpu(fld.daddr), le16_to_cpu(fld.saddr),
-		       fld.flowidn_oif, try_hard);
-
-	/*
-	 * N.B. If the kernel is compiled without router support then
-	 * dn_fib_lookup() will evaluate to non-zero so this if () block
-	 * will always be executed.
-	 */
-	err = -ESRCH;
-	if (try_hard || (err = dn_fib_lookup(&fld, &res)) != 0) {
-		struct dn_dev *dn_db;
-		if (err != -ESRCH)
-			goto out;
-		/*
-		 * Here the fallback is basically the standard algorithm for
-		 * routing in endnodes which is described in the DECnet routing
-		 * docs
-		 *
-		 * If we are not trying hard, look in neighbour cache.
-		 * The result is tested to ensure that if a specific output
-		 * device/source address was requested, then we honour that
-		 * here
-		 */
-		if (!try_hard) {
-			neigh = neigh_lookup_nodev(&dn_neigh_table, &init_net, &fld.daddr);
-			if (neigh) {
-				if ((oldflp->flowidn_oif &&
-				    (neigh->dev->ifindex != oldflp->flowidn_oif)) ||
-				    (oldflp->saddr &&
-				    (!dn_dev_islocal(neigh->dev,
-						     oldflp->saddr)))) {
-					neigh_release(neigh);
-					neigh = NULL;
-				} else {
-					if (dev_out)
-						dev_put(dev_out);
-					if (dn_dev_islocal(neigh->dev, fld.daddr)) {
-						dev_out = init_net.loopback_dev;
-						res.type = RTN_LOCAL;
-					} else {
-						dev_out = neigh->dev;
-					}
-					dev_hold(dev_out);
-					goto select_source;
-				}
-			}
-		}
-
-		/* Not there? Perhaps its a local address */
-		if (dev_out == NULL)
-			dev_out = dn_dev_get_default();
-		err = -ENODEV;
-		if (dev_out == NULL)
-			goto out;
-		dn_db = rcu_dereference_raw(dev_out->dn_ptr);
-		if (!dn_db)
-			goto e_inval;
-		/* Possible improvement - check all devices for local addr */
-		if (dn_dev_islocal(dev_out, fld.daddr)) {
-			dev_put(dev_out);
-			dev_out = init_net.loopback_dev;
-			dev_hold(dev_out);
-			res.type = RTN_LOCAL;
-			goto select_source;
-		}
-		/* Not local either.... try sending it to the default router */
-		neigh = neigh_clone(dn_db->router);
-		BUG_ON(neigh && neigh->dev != dev_out);
-
-		/* Ok then, we assume its directly connected and move on */
-select_source:
-		if (neigh)
-			gateway = ((struct dn_neigh *)neigh)->addr;
-		if (gateway == 0)
-			gateway = fld.daddr;
-		if (fld.saddr == 0) {
-			fld.saddr = dnet_select_source(dev_out, gateway,
-						       res.type == RTN_LOCAL ?
-						       RT_SCOPE_HOST :
-						       RT_SCOPE_LINK);
-			if (fld.saddr == 0 && res.type != RTN_LOCAL)
-				goto e_addr;
-		}
-		fld.flowidn_oif = dev_out->ifindex;
-		goto make_route;
-	}
-	free_res = 1;
-
-	if (res.type == RTN_NAT)
-		goto e_inval;
-
-	if (res.type == RTN_LOCAL) {
-		if (!fld.saddr)
-			fld.saddr = fld.daddr;
-		if (dev_out)
-			dev_put(dev_out);
-		dev_out = init_net.loopback_dev;
-		dev_hold(dev_out);
-		if (!dev_out->dn_ptr)
-			goto e_inval;
-		fld.flowidn_oif = dev_out->ifindex;
-		if (res.fi)
-			dn_fib_info_put(res.fi);
-		res.fi = NULL;
-		goto make_route;
-	}
-
-	if (res.fi->fib_nhs > 1 && fld.flowidn_oif == 0)
-		dn_fib_select_multipath(&fld, &res);
-
-	/*
-	 * We could add some logic to deal with default routes here and
-	 * get rid of some of the special casing above.
-	 */
-
-	if (!fld.saddr)
-		fld.saddr = DN_FIB_RES_PREFSRC(res);
-
-	if (dev_out)
-		dev_put(dev_out);
-	dev_out = DN_FIB_RES_DEV(res);
-	dev_hold(dev_out);
-	fld.flowidn_oif = dev_out->ifindex;
-	gateway = DN_FIB_RES_GW(res);
-
-make_route:
-	if (dev_out->flags & IFF_LOOPBACK)
-		flags |= RTCF_LOCAL;
-
-	rt = dst_alloc(&dn_dst_ops, dev_out, 0, DST_OBSOLETE_NONE, 0);
-	if (rt == NULL)
-		goto e_nobufs;
-
-	rt->dn_next = NULL;
-	memset(&rt->fld, 0, sizeof(rt->fld));
-	rt->fld.saddr        = oldflp->saddr;
-	rt->fld.daddr        = oldflp->daddr;
-	rt->fld.flowidn_oif  = oldflp->flowidn_oif;
-	rt->fld.flowidn_iif  = 0;
-	rt->fld.flowidn_mark = oldflp->flowidn_mark;
-
-	rt->rt_saddr      = fld.saddr;
-	rt->rt_daddr      = fld.daddr;
-	rt->rt_gateway    = gateway ? gateway : fld.daddr;
-	rt->rt_local_src  = fld.saddr;
-
-	rt->rt_dst_map    = fld.daddr;
-	rt->rt_src_map    = fld.saddr;
-
-	rt->n = neigh;
-	neigh = NULL;
-
-	rt->dst.lastuse = jiffies;
-	rt->dst.output  = dn_output;
-	rt->dst.input   = dn_rt_bug;
-	rt->rt_flags      = flags;
-	if (flags & RTCF_LOCAL)
-		rt->dst.input = dn_nsp_rx;
-
-	err = dn_rt_set_next_hop(rt, &res);
-	if (err)
-		goto e_neighbour;
-
-	hash = dn_hash(rt->fld.saddr, rt->fld.daddr);
-	/* dn_insert_route() increments dst->__refcnt */
-	dn_insert_route(rt, hash, (struct dn_route **)pprt);
-
-done:
-	if (neigh)
-		neigh_release(neigh);
-	if (free_res)
-		dn_fib_res_put(&res);
-	if (dev_out)
-		dev_put(dev_out);
-out:
-	return err;
-
-e_addr:
-	err = -EADDRNOTAVAIL;
-	goto done;
-e_inval:
-	err = -EINVAL;
-	goto done;
-e_nobufs:
-	err = -ENOBUFS;
-	goto done;
-e_neighbour:
-	dst_release_immediate(&rt->dst);
-	goto e_nobufs;
-}
-
-
-/*
- * N.B. The flags may be moved into the flowi at some future stage.
- */
-static int __dn_route_output_key(struct dst_entry **pprt, const struct flowidn *flp, int flags)
-{
-	unsigned int hash = dn_hash(flp->saddr, flp->daddr);
-	struct dn_route *rt = NULL;
-
-	if (!(flags & MSG_TRYHARD)) {
-		rcu_read_lock_bh();
-		for (rt = rcu_dereference_bh(dn_rt_hash_table[hash].chain); rt;
-			rt = rcu_dereference_bh(rt->dn_next)) {
-			if ((flp->daddr == rt->fld.daddr) &&
-			    (flp->saddr == rt->fld.saddr) &&
-			    (flp->flowidn_mark == rt->fld.flowidn_mark) &&
-			    dn_is_output_route(rt) &&
-			    (rt->fld.flowidn_oif == flp->flowidn_oif)) {
-				dst_hold_and_use(&rt->dst, jiffies);
-				rcu_read_unlock_bh();
-				*pprt = &rt->dst;
-				return 0;
-			}
-		}
-		rcu_read_unlock_bh();
-	}
-
-	return dn_route_output_slow(pprt, flp, flags);
-}
-
-static int dn_route_output_key(struct dst_entry **pprt, struct flowidn *flp, int flags)
-{
-	int err;
-
-	err = __dn_route_output_key(pprt, flp, flags);
-	if (err == 0 && flp->flowidn_proto) {
-		*pprt = xfrm_lookup(&init_net, *pprt,
-				    flowidn_to_flowi(flp), NULL, 0);
-		if (IS_ERR(*pprt)) {
-			err = PTR_ERR(*pprt);
-			*pprt = NULL;
-		}
-	}
-	return err;
-}
-
-int dn_route_output_sock(struct dst_entry __rcu **pprt, struct flowidn *fl, struct sock *sk, int flags)
-{
-	int err;
-
-	err = __dn_route_output_key(pprt, fl, flags & MSG_TRYHARD);
-	if (err == 0 && fl->flowidn_proto) {
-		*pprt = xfrm_lookup(&init_net, *pprt,
-				    flowidn_to_flowi(fl), sk, 0);
-		if (IS_ERR(*pprt)) {
-			err = PTR_ERR(*pprt);
-			*pprt = NULL;
-		}
-	}
-	return err;
-}
-
-static int dn_route_input_slow(struct sk_buff *skb)
-{
-	struct dn_route *rt = NULL;
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	struct net_device *in_dev = skb->dev;
-	struct net_device *out_dev = NULL;
-	struct dn_dev *dn_db;
-	struct neighbour *neigh = NULL;
-	unsigned int hash;
-	int flags = 0;
-	__le16 gateway = 0;
-	__le16 local_src = 0;
-	struct flowidn fld = {
-		.daddr = cb->dst,
-		.saddr = cb->src,
-		.flowidn_scope = RT_SCOPE_UNIVERSE,
-		.flowidn_mark = skb->mark,
-		.flowidn_iif = skb->dev->ifindex,
-	};
-	struct dn_fib_res res = { .fi = NULL, .type = RTN_UNREACHABLE };
-	int err = -EINVAL;
-	int free_res = 0;
-
-	dev_hold(in_dev);
-
-	if ((dn_db = rcu_dereference(in_dev->dn_ptr)) == NULL)
-		goto out;
-
-	/* Zero source addresses are not allowed */
-	if (fld.saddr == 0)
-		goto out;
-
-	/*
-	 * In this case we've just received a packet from a source
-	 * outside ourselves pretending to come from us. We don't
-	 * allow it any further to prevent routing loops, spoofing and
-	 * other nasties. Loopback packets already have the dst attached
-	 * so this only affects packets which have originated elsewhere.
-	 */
-	err  = -ENOTUNIQ;
-	if (dn_dev_islocal(in_dev, cb->src))
-		goto out;
-
-	err = dn_fib_lookup(&fld, &res);
-	if (err) {
-		if (err != -ESRCH)
-			goto out;
-		/*
-		 * Is the destination us ?
-		 */
-		if (!dn_dev_islocal(in_dev, cb->dst))
-			goto e_inval;
-
-		res.type = RTN_LOCAL;
-	} else {
-		__le16 src_map = fld.saddr;
-		free_res = 1;
-
-		out_dev = DN_FIB_RES_DEV(res);
-		if (out_dev == NULL) {
-			net_crit_ratelimited("Bug in dn_route_input_slow() No output device\n");
-			goto e_inval;
-		}
-		dev_hold(out_dev);
-
-		if (res.r)
-			src_map = fld.saddr; /* no NAT support for now */
-
-		gateway = DN_FIB_RES_GW(res);
-		if (res.type == RTN_NAT) {
-			fld.daddr = dn_fib_rules_map_destination(fld.daddr, &res);
-			dn_fib_res_put(&res);
-			free_res = 0;
-			if (dn_fib_lookup(&fld, &res))
-				goto e_inval;
-			free_res = 1;
-			if (res.type != RTN_UNICAST)
-				goto e_inval;
-			flags |= RTCF_DNAT;
-			gateway = fld.daddr;
-		}
-		fld.saddr = src_map;
-	}
-
-	switch(res.type) {
-	case RTN_UNICAST:
-		/*
-		 * Forwarding check here, we only check for forwarding
-		 * being turned off, if you want to only forward intra
-		 * area, its up to you to set the routing tables up
-		 * correctly.
-		 */
-		if (dn_db->parms.forwarding == 0)
-			goto e_inval;
-
-		if (res.fi->fib_nhs > 1 && fld.flowidn_oif == 0)
-			dn_fib_select_multipath(&fld, &res);
-
-		/*
-		 * Check for out_dev == in_dev. We use the RTCF_DOREDIRECT
-		 * flag as a hint to set the intra-ethernet bit when
-		 * forwarding. If we've got NAT in operation, we don't do
-		 * this optimisation.
-		 */
-		if (out_dev == in_dev && !(flags & RTCF_NAT))
-			flags |= RTCF_DOREDIRECT;
-
-		local_src = DN_FIB_RES_PREFSRC(res);
-
-	case RTN_BLACKHOLE:
-	case RTN_UNREACHABLE:
-		break;
-	case RTN_LOCAL:
-		flags |= RTCF_LOCAL;
-		fld.saddr = cb->dst;
-		fld.daddr = cb->src;
-
-		/* Routing tables gave us a gateway */
-		if (gateway)
-			goto make_route;
-
-		/* Packet was intra-ethernet, so we know its on-link */
-		if (cb->rt_flags & DN_RT_F_IE) {
-			gateway = cb->src;
-			goto make_route;
-		}
-
-		/* Use the default router if there is one */
-		neigh = neigh_clone(dn_db->router);
-		if (neigh) {
-			gateway = ((struct dn_neigh *)neigh)->addr;
-			goto make_route;
-		}
-
-		/* Close eyes and pray */
-		gateway = cb->src;
-		goto make_route;
-	default:
-		goto e_inval;
-	}
-
-make_route:
-	rt = dst_alloc(&dn_dst_ops, out_dev, 1, DST_OBSOLETE_NONE, 0);
-	if (rt == NULL)
-		goto e_nobufs;
-
-	rt->dn_next = NULL;
-	memset(&rt->fld, 0, sizeof(rt->fld));
-	rt->rt_saddr      = fld.saddr;
-	rt->rt_daddr      = fld.daddr;
-	rt->rt_gateway    = fld.daddr;
-	if (gateway)
-		rt->rt_gateway = gateway;
-	rt->rt_local_src  = local_src ? local_src : rt->rt_saddr;
-
-	rt->rt_dst_map    = fld.daddr;
-	rt->rt_src_map    = fld.saddr;
-
-	rt->fld.saddr        = cb->src;
-	rt->fld.daddr        = cb->dst;
-	rt->fld.flowidn_oif  = 0;
-	rt->fld.flowidn_iif  = in_dev->ifindex;
-	rt->fld.flowidn_mark = fld.flowidn_mark;
-
-	rt->n = neigh;
-	rt->dst.lastuse = jiffies;
-	rt->dst.output = dn_rt_bug_out;
-	switch (res.type) {
-	case RTN_UNICAST:
-		rt->dst.input = dn_forward;
-		break;
-	case RTN_LOCAL:
-		rt->dst.output = dn_output;
-		rt->dst.input = dn_nsp_rx;
-		rt->dst.dev = in_dev;
-		flags |= RTCF_LOCAL;
-		break;
-	default:
-	case RTN_UNREACHABLE:
-	case RTN_BLACKHOLE:
-		rt->dst.input = dst_discard;
-	}
-	rt->rt_flags = flags;
-
-	err = dn_rt_set_next_hop(rt, &res);
-	if (err)
-		goto e_neighbour;
-
-	hash = dn_hash(rt->fld.saddr, rt->fld.daddr);
-	/* dn_insert_route() increments dst->__refcnt */
-	dn_insert_route(rt, hash, &rt);
-	skb_dst_set(skb, &rt->dst);
-
-done:
-	if (neigh)
-		neigh_release(neigh);
-	if (free_res)
-		dn_fib_res_put(&res);
-	dev_put(in_dev);
-	if (out_dev)
-		dev_put(out_dev);
-out:
-	return err;
-
-e_inval:
-	err = -EINVAL;
-	goto done;
-
-e_nobufs:
-	err = -ENOBUFS;
-	goto done;
-
-e_neighbour:
-	dst_release_immediate(&rt->dst);
-	goto done;
-}
-
-static int dn_route_input(struct sk_buff *skb)
-{
-	struct dn_route *rt;
-	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	unsigned int hash = dn_hash(cb->src, cb->dst);
-
-	if (skb_dst(skb))
-		return 0;
-
-	rcu_read_lock();
-	for(rt = rcu_dereference(dn_rt_hash_table[hash].chain); rt != NULL;
-	    rt = rcu_dereference(rt->dn_next)) {
-		if ((rt->fld.saddr == cb->src) &&
-		    (rt->fld.daddr == cb->dst) &&
-		    (rt->fld.flowidn_oif == 0) &&
-		    (rt->fld.flowidn_mark == skb->mark) &&
-		    (rt->fld.flowidn_iif == cb->iif)) {
-			dst_hold_and_use(&rt->dst, jiffies);
-			rcu_read_unlock();
-			skb_dst_set(skb, (struct dst_entry *)rt);
-			return 0;
-		}
-	}
-	rcu_read_unlock();
-
-	return dn_route_input_slow(skb);
-}
-
-static int dn_rt_fill_info(struct sk_buff *skb, u32 portid, u32 seq,
-			   int event, int nowait, unsigned int flags)
-{
-	struct dn_route *rt = (struct dn_route *)skb_dst(skb);
-	struct rtmsg *r;
-	struct nlmsghdr *nlh;
-	long expires;
-
-	nlh = nlmsg_put(skb, portid, seq, event, sizeof(*r), flags);
-	if (!nlh)
-		return -EMSGSIZE;
-
-	r = nlmsg_data(nlh);
-	r->rtm_family = AF_DECnet;
-	r->rtm_dst_len = 16;
-	r->rtm_src_len = 0;
-	r->rtm_tos = 0;
-	r->rtm_table = RT_TABLE_MAIN;
-	r->rtm_type = rt->rt_type;
-	r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED;
-	r->rtm_scope = RT_SCOPE_UNIVERSE;
-	r->rtm_protocol = RTPROT_UNSPEC;
-
-	if (rt->rt_flags & RTCF_NOTIFY)
-		r->rtm_flags |= RTM_F_NOTIFY;
-
-	if (nla_put_u32(skb, RTA_TABLE, RT_TABLE_MAIN) < 0 ||
-	    nla_put_le16(skb, RTA_DST, rt->rt_daddr) < 0)
-		goto errout;
-
-	if (rt->fld.saddr) {
-		r->rtm_src_len = 16;
-		if (nla_put_le16(skb, RTA_SRC, rt->fld.saddr) < 0)
-			goto errout;
-	}
-	if (rt->dst.dev &&
-	    nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex) < 0)
-		goto errout;
-
-	/*
-	 * Note to self - change this if input routes reverse direction when
-	 * they deal only with inputs and not with replies like they do
-	 * currently.
-	 */
-	if (nla_put_le16(skb, RTA_PREFSRC, rt->rt_local_src) < 0)
-		goto errout;
-
-	if (rt->rt_daddr != rt->rt_gateway &&
-	    nla_put_le16(skb, RTA_GATEWAY, rt->rt_gateway) < 0)
-		goto errout;
-
-	if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
-		goto errout;
-
-	expires = rt->dst.expires ? rt->dst.expires - jiffies : 0;
-	if (rtnl_put_cacheinfo(skb, &rt->dst, 0, expires,
-			       rt->dst.error) < 0)
-		goto errout;
-
-	if (dn_is_input_route(rt) &&
-	    nla_put_u32(skb, RTA_IIF, rt->fld.flowidn_iif) < 0)
-		goto errout;
-
-	nlmsg_end(skb, nlh);
-	return 0;
-
-errout:
-	nlmsg_cancel(skb, nlh);
-	return -EMSGSIZE;
-}
-
-const struct nla_policy rtm_dn_policy[RTA_MAX + 1] = {
-	[RTA_DST]		= { .type = NLA_U16 },
-	[RTA_SRC]		= { .type = NLA_U16 },
-	[RTA_IIF]		= { .type = NLA_U32 },
-	[RTA_OIF]		= { .type = NLA_U32 },
-	[RTA_GATEWAY]		= { .type = NLA_U16 },
-	[RTA_PRIORITY]		= { .type = NLA_U32 },
-	[RTA_PREFSRC]		= { .type = NLA_U16 },
-	[RTA_METRICS]		= { .type = NLA_NESTED },
-	[RTA_MULTIPATH]		= { .type = NLA_NESTED },
-	[RTA_TABLE]		= { .type = NLA_U32 },
-	[RTA_MARK]		= { .type = NLA_U32 },
-};
-
-/*
- * This is called by both endnodes and routers now.
- */
-static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
-			     struct netlink_ext_ack *extack)
-{
-	struct net *net = sock_net(in_skb->sk);
-	struct rtmsg *rtm = nlmsg_data(nlh);
-	struct dn_route *rt = NULL;
-	struct dn_skb_cb *cb;
-	int err;
-	struct sk_buff *skb;
-	struct flowidn fld;
-	struct nlattr *tb[RTA_MAX+1];
-
-	if (!net_eq(net, &init_net))
-		return -EINVAL;
-
-	err = nlmsg_parse_deprecated(nlh, sizeof(*rtm), tb, RTA_MAX,
-				     rtm_dn_policy, extack);
-	if (err < 0)
-		return err;
-
-	memset(&fld, 0, sizeof(fld));
-	fld.flowidn_proto = DNPROTO_NSP;
-
-	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
-	if (skb == NULL)
-		return -ENOBUFS;
-	skb_reset_mac_header(skb);
-	cb = DN_SKB_CB(skb);
-
-	if (tb[RTA_SRC])
-		fld.saddr = nla_get_le16(tb[RTA_SRC]);
-
-	if (tb[RTA_DST])
-		fld.daddr = nla_get_le16(tb[RTA_DST]);
-
-	if (tb[RTA_IIF])
-		fld.flowidn_iif = nla_get_u32(tb[RTA_IIF]);
-
-	if (fld.flowidn_iif) {
-		struct net_device *dev;
-		dev = __dev_get_by_index(&init_net, fld.flowidn_iif);
-		if (!dev || !dev->dn_ptr) {
-			kfree_skb(skb);
-			return -ENODEV;
-		}
-		skb->protocol = htons(ETH_P_DNA_RT);
-		skb->dev = dev;
-		cb->src = fld.saddr;
-		cb->dst = fld.daddr;
-		local_bh_disable();
-		err = dn_route_input(skb);
-		local_bh_enable();
-		memset(cb, 0, sizeof(struct dn_skb_cb));
-		rt = (struct dn_route *)skb_dst(skb);
-		if (!err && -rt->dst.error)
-			err = rt->dst.error;
-	} else {
-		if (tb[RTA_OIF])
-			fld.flowidn_oif = nla_get_u32(tb[RTA_OIF]);
-
-		err = dn_route_output_key((struct dst_entry **)&rt, &fld, 0);
-	}
-
-	skb->dev = NULL;
-	if (err)
-		goto out_free;
-	skb_dst_set(skb, &rt->dst);
-	if (rtm->rtm_flags & RTM_F_NOTIFY)
-		rt->rt_flags |= RTCF_NOTIFY;
-
-	err = dn_rt_fill_info(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq, RTM_NEWROUTE, 0, 0);
-	if (err < 0) {
-		err = -EMSGSIZE;
-		goto out_free;
-	}
-
-	return rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).portid);
-
-out_free:
-	kfree_skb(skb);
-	return err;
-}
-
-/*
- * For routers, this is called from dn_fib_dump, but for endnodes its
- * called directly from the rtnetlink dispatch table.
- */
-int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb)
-{
-	struct net *net = sock_net(skb->sk);
-	struct dn_route *rt;
-	int h, s_h;
-	int idx, s_idx;
-	struct rtmsg *rtm;
-
-	if (!net_eq(net, &init_net))
-		return 0;
-
-	if (nlmsg_len(cb->nlh) < sizeof(struct rtmsg))
-		return -EINVAL;
-
-	rtm = nlmsg_data(cb->nlh);
-	if (!(rtm->rtm_flags & RTM_F_CLONED))
-		return 0;
-
-	s_h = cb->args[0];
-	s_idx = idx = cb->args[1];
-	for(h = 0; h <= dn_rt_hash_mask; h++) {
-		if (h < s_h)
-			continue;
-		if (h > s_h)
-			s_idx = 0;
-		rcu_read_lock_bh();
-		for(rt = rcu_dereference_bh(dn_rt_hash_table[h].chain), idx = 0;
-			rt;
-			rt = rcu_dereference_bh(rt->dn_next), idx++) {
-			if (idx < s_idx)
-				continue;
-			skb_dst_set(skb, dst_clone(&rt->dst));
-			if (dn_rt_fill_info(skb, NETLINK_CB(cb->skb).portid,
-					cb->nlh->nlmsg_seq, RTM_NEWROUTE,
-					1, NLM_F_MULTI) < 0) {
-				skb_dst_drop(skb);
-				rcu_read_unlock_bh();
-				goto done;
-			}
-			skb_dst_drop(skb);
-		}
-		rcu_read_unlock_bh();
-	}
-
-done:
-	cb->args[0] = h;
-	cb->args[1] = idx;
-	return skb->len;
-}
-
-#ifdef CONFIG_PROC_FS
-struct dn_rt_cache_iter_state {
-	int bucket;
-};
-
-static struct dn_route *dn_rt_cache_get_first(struct seq_file *seq)
-{
-	struct dn_route *rt = NULL;
-	struct dn_rt_cache_iter_state *s = seq->private;
-
-	for(s->bucket = dn_rt_hash_mask; s->bucket >= 0; --s->bucket) {
-		rcu_read_lock_bh();
-		rt = rcu_dereference_bh(dn_rt_hash_table[s->bucket].chain);
-		if (rt)
-			break;
-		rcu_read_unlock_bh();
-	}
-	return rt;
-}
-
-static struct dn_route *dn_rt_cache_get_next(struct seq_file *seq, struct dn_route *rt)
-{
-	struct dn_rt_cache_iter_state *s = seq->private;
-
-	rt = rcu_dereference_bh(rt->dn_next);
-	while (!rt) {
-		rcu_read_unlock_bh();
-		if (--s->bucket < 0)
-			break;
-		rcu_read_lock_bh();
-		rt = rcu_dereference_bh(dn_rt_hash_table[s->bucket].chain);
-	}
-	return rt;
-}
-
-static void *dn_rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
-{
-	struct dn_route *rt = dn_rt_cache_get_first(seq);
-
-	if (rt) {
-		while(*pos && (rt = dn_rt_cache_get_next(seq, rt)))
-			--*pos;
-	}
-	return *pos ? NULL : rt;
-}
-
-static void *dn_rt_cache_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	struct dn_route *rt = dn_rt_cache_get_next(seq, v);
-	++*pos;
-	return rt;
-}
-
-static void dn_rt_cache_seq_stop(struct seq_file *seq, void *v)
-{
-	if (v)
-		rcu_read_unlock_bh();
-}
-
-static int dn_rt_cache_seq_show(struct seq_file *seq, void *v)
-{
-	struct dn_route *rt = v;
-	char buf1[DN_ASCBUF_LEN], buf2[DN_ASCBUF_LEN];
-
-	seq_printf(seq, "%-8s %-7s %-7s %04d %04d %04d\n",
-		   rt->dst.dev ? rt->dst.dev->name : "*",
-		   dn_addr2asc(le16_to_cpu(rt->rt_daddr), buf1),
-		   dn_addr2asc(le16_to_cpu(rt->rt_saddr), buf2),
-		   atomic_read(&rt->dst.__refcnt),
-		   rt->dst.__use, 0);
-	return 0;
-}
-
-static const struct seq_operations dn_rt_cache_seq_ops = {
-	.start	= dn_rt_cache_seq_start,
-	.next	= dn_rt_cache_seq_next,
-	.stop	= dn_rt_cache_seq_stop,
-	.show	= dn_rt_cache_seq_show,
-};
-#endif /* CONFIG_PROC_FS */
-
-void __init dn_route_init(void)
-{
-	int i, goal, order;
-
-	dn_dst_ops.kmem_cachep =
-		kmem_cache_create("dn_dst_cache", sizeof(struct dn_route), 0,
-				  SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
-	dst_entries_init(&dn_dst_ops);
-	timer_setup(&dn_route_timer, dn_dst_check_expire, 0);
-	dn_route_timer.expires = jiffies + decnet_dst_gc_interval * HZ;
-	add_timer(&dn_route_timer);
-
-	goal = totalram_pages() >> (26 - PAGE_SHIFT);
-
-	for(order = 0; (1UL << order) < goal; order++)
-		/* NOTHING */;
-
-	/*
-	 * Only want 1024 entries max, since the table is very, very unlikely
-	 * to be larger than that.
-	 */
-	while(order && ((((1UL << order) * PAGE_SIZE) /
-				sizeof(struct dn_rt_hash_bucket)) >= 2048))
-		order--;
-
-	do {
-		dn_rt_hash_mask = (1UL << order) * PAGE_SIZE /
-			sizeof(struct dn_rt_hash_bucket);
-		while(dn_rt_hash_mask & (dn_rt_hash_mask - 1))
-			dn_rt_hash_mask--;
-		dn_rt_hash_table = (struct dn_rt_hash_bucket *)
-			__get_free_pages(GFP_ATOMIC, order);
-	} while (dn_rt_hash_table == NULL && --order > 0);
-
-	if (!dn_rt_hash_table)
-		panic("Failed to allocate DECnet route cache hash table\n");
-
-	printk(KERN_INFO
-		"DECnet: Routing cache hash table of %u buckets, %ldKbytes\n",
-		dn_rt_hash_mask,
-		(long)(dn_rt_hash_mask*sizeof(struct dn_rt_hash_bucket))/1024);
-
-	dn_rt_hash_mask--;
-	for(i = 0; i <= dn_rt_hash_mask; i++) {
-		spin_lock_init(&dn_rt_hash_table[i].lock);
-		dn_rt_hash_table[i].chain = NULL;
-	}
-
-	dn_dst_ops.gc_thresh = (dn_rt_hash_mask + 1);
-
-	proc_create_seq_private("decnet_cache", 0444, init_net.proc_net,
-			&dn_rt_cache_seq_ops,
-			sizeof(struct dn_rt_cache_iter_state), NULL);
-
-#ifdef CONFIG_DECNET_ROUTER
-	rtnl_register_module(THIS_MODULE, PF_DECnet, RTM_GETROUTE,
-			     dn_cache_getroute, dn_fib_dump, 0);
-#else
-	rtnl_register_module(THIS_MODULE, PF_DECnet, RTM_GETROUTE,
-			     dn_cache_getroute, dn_cache_dump, 0);
-#endif
-}
-
-void __exit dn_route_cleanup(void)
-{
-	del_timer(&dn_route_timer);
-	dn_run_flush(NULL);
-
-	remove_proc_entry("decnet_cache", init_net.proc_net);
-	dst_entries_destroy(&dn_dst_ops);
-}
diff --git a/kernel/net/decnet/dn_rules.c b/kernel/net/decnet/dn_rules.c
deleted file mode 100644
index 4a4e3c1..0000000
--- a/kernel/net/decnet/dn_rules.c
+++ /dev/null
@@ -1,258 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/*
- * DECnet       An implementation of the DECnet protocol suite for the LINUX
- *              operating system.  DECnet is implemented using the  BSD Socket
- *              interface as the means of communication with the user level.
- *
- *              DECnet Routing Forwarding Information Base (Rules)
- *
- * Author:      Steve Whitehouse <SteveW@ACM.org>
- *              Mostly copied from Alexey Kuznetsov's ipv4/fib_rules.c
- *
- *
- * Changes:
- *              Steve Whitehouse <steve@chygwyn.com>
- *              Updated for Thomas Graf's generic rules
- *
- */
-#include <linux/net.h>
-#include <linux/init.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <linux/netdevice.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <linux/rcupdate.h>
-#include <linux/export.h>
-#include <net/neighbour.h>
-#include <net/dst.h>
-#include <net/flow.h>
-#include <net/fib_rules.h>
-#include <net/dn.h>
-#include <net/dn_fib.h>
-#include <net/dn_neigh.h>
-#include <net/dn_dev.h>
-#include <net/dn_route.h>
-
-static struct fib_rules_ops *dn_fib_rules_ops;
-
-struct dn_fib_rule
-{
-	struct fib_rule		common;
-	unsigned char		dst_len;
-	unsigned char		src_len;
-	__le16			src;
-	__le16			srcmask;
-	__le16			dst;
-	__le16			dstmask;
-	__le16			srcmap;
-	u8			flags;
-};
-
-
-int dn_fib_lookup(struct flowidn *flp, struct dn_fib_res *res)
-{
-	struct fib_lookup_arg arg = {
-		.result = res,
-	};
-	int err;
-
-	err = fib_rules_lookup(dn_fib_rules_ops,
-			       flowidn_to_flowi(flp), 0, &arg);
-	res->r = arg.rule;
-
-	return err;
-}
-
-static int dn_fib_rule_action(struct fib_rule *rule, struct flowi *flp,
-			      int flags, struct fib_lookup_arg *arg)
-{
-	struct flowidn *fld = &flp->u.dn;
-	int err = -EAGAIN;
-	struct dn_fib_table *tbl;
-
-	switch(rule->action) {
-	case FR_ACT_TO_TBL:
-		break;
-
-	case FR_ACT_UNREACHABLE:
-		err = -ENETUNREACH;
-		goto errout;
-
-	case FR_ACT_PROHIBIT:
-		err = -EACCES;
-		goto errout;
-
-	case FR_ACT_BLACKHOLE:
-	default:
-		err = -EINVAL;
-		goto errout;
-	}
-
-	tbl = dn_fib_get_table(rule->table, 0);
-	if (tbl == NULL)
-		goto errout;
-
-	err = tbl->lookup(tbl, fld, (struct dn_fib_res *)arg->result);
-	if (err > 0)
-		err = -EAGAIN;
-errout:
-	return err;
-}
-
-static const struct nla_policy dn_fib_rule_policy[FRA_MAX+1] = {
-	FRA_GENERIC_POLICY,
-};
-
-static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
-{
-	struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
-	struct flowidn *fld = &fl->u.dn;
-	__le16 daddr = fld->daddr;
-	__le16 saddr = fld->saddr;
-
-	if (((saddr ^ r->src) & r->srcmask) ||
-	    ((daddr ^ r->dst) & r->dstmask))
-		return 0;
-
-	return 1;
-}
-
-static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
-				 struct fib_rule_hdr *frh,
-				 struct nlattr **tb,
-				 struct netlink_ext_ack *extack)
-{
-	int err = -EINVAL;
-	struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
-
-	if (frh->tos) {
-		NL_SET_ERR_MSG(extack, "Invalid tos value");
-		goto  errout;
-	}
-
-	if (rule->table == RT_TABLE_UNSPEC) {
-		if (rule->action == FR_ACT_TO_TBL) {
-			struct dn_fib_table *table;
-
-			table = dn_fib_empty_table();
-			if (table == NULL) {
-				err = -ENOBUFS;
-				goto errout;
-			}
-
-			rule->table = table->n;
-		}
-	}
-
-	if (frh->src_len)
-		r->src = nla_get_le16(tb[FRA_SRC]);
-
-	if (frh->dst_len)
-		r->dst = nla_get_le16(tb[FRA_DST]);
-
-	r->src_len = frh->src_len;
-	r->srcmask = dnet_make_mask(r->src_len);
-	r->dst_len = frh->dst_len;
-	r->dstmask = dnet_make_mask(r->dst_len);
-	err = 0;
-errout:
-	return err;
-}
-
-static int dn_fib_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
-			       struct nlattr **tb)
-{
-	struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
-
-	if (frh->src_len && (r->src_len != frh->src_len))
-		return 0;
-
-	if (frh->dst_len && (r->dst_len != frh->dst_len))
-		return 0;
-
-	if (frh->src_len && (r->src != nla_get_le16(tb[FRA_SRC])))
-		return 0;
-
-	if (frh->dst_len && (r->dst != nla_get_le16(tb[FRA_DST])))
-		return 0;
-
-	return 1;
-}
-
-unsigned int dnet_addr_type(__le16 addr)
-{
-	struct flowidn fld = { .daddr = addr };
-	struct dn_fib_res res;
-	unsigned int ret = RTN_UNICAST;
-	struct dn_fib_table *tb = dn_fib_get_table(RT_TABLE_LOCAL, 0);
-
-	res.r = NULL;
-
-	if (tb) {
-		if (!tb->lookup(tb, &fld, &res)) {
-			ret = res.type;
-			dn_fib_res_put(&res);
-		}
-	}
-	return ret;
-}
-
-static int dn_fib_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
-			    struct fib_rule_hdr *frh)
-{
-	struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
-
-	frh->dst_len = r->dst_len;
-	frh->src_len = r->src_len;
-	frh->tos = 0;
-
-	if ((r->dst_len &&
-	     nla_put_le16(skb, FRA_DST, r->dst)) ||
-	    (r->src_len &&
-	     nla_put_le16(skb, FRA_SRC, r->src)))
-		goto nla_put_failure;
-	return 0;
-
-nla_put_failure:
-	return -ENOBUFS;
-}
-
-static void dn_fib_rule_flush_cache(struct fib_rules_ops *ops)
-{
-	dn_rt_cache_flush(-1);
-}
-
-static const struct fib_rules_ops __net_initconst dn_fib_rules_ops_template = {
-	.family		= AF_DECnet,
-	.rule_size	= sizeof(struct dn_fib_rule),
-	.addr_size	= sizeof(u16),
-	.action		= dn_fib_rule_action,
-	.match		= dn_fib_rule_match,
-	.configure	= dn_fib_rule_configure,
-	.compare	= dn_fib_rule_compare,
-	.fill		= dn_fib_rule_fill,
-	.flush_cache	= dn_fib_rule_flush_cache,
-	.nlgroup	= RTNLGRP_DECnet_RULE,
-	.policy		= dn_fib_rule_policy,
-	.owner		= THIS_MODULE,
-	.fro_net	= &init_net,
-};
-
-void __init dn_fib_rules_init(void)
-{
-	dn_fib_rules_ops =
-		fib_rules_register(&dn_fib_rules_ops_template, &init_net);
-	BUG_ON(IS_ERR(dn_fib_rules_ops));
-	BUG_ON(fib_default_rule_add(dn_fib_rules_ops, 0x7fff,
-			            RT_TABLE_MAIN, 0));
-}
-
-void __exit dn_fib_rules_cleanup(void)
-{
-	rtnl_lock();
-	fib_rules_unregister(dn_fib_rules_ops);
-	rtnl_unlock();
-	rcu_barrier();
-}
diff --git a/kernel/net/decnet/dn_table.c b/kernel/net/decnet/dn_table.c
deleted file mode 100644
index 4086f9c..0000000
--- a/kernel/net/decnet/dn_table.c
+++ /dev/null
@@ -1,929 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * DECnet       An implementation of the DECnet protocol suite for the LINUX
- *              operating system.  DECnet is implemented using the  BSD Socket
- *              interface as the means of communication with the user level.
- *
- *              DECnet Routing Forwarding Information Base (Routing Tables)
- *
- * Author:      Steve Whitehouse <SteveW@ACM.org>
- *              Mostly copied from the IPv4 routing code
- *
- *
- * Changes:
- *
- */
-#include <linux/string.h>
-#include <linux/net.h>
-#include <linux/socket.h>
-#include <linux/slab.h>
-#include <linux/sockios.h>
-#include <linux/init.h>
-#include <linux/skbuff.h>
-#include <linux/rtnetlink.h>
-#include <linux/proc_fs.h>
-#include <linux/netdevice.h>
-#include <linux/timer.h>
-#include <linux/spinlock.h>
-#include <linux/atomic.h>
-#include <linux/uaccess.h>
-#include <linux/route.h> /* RTF_xxx */
-#include <net/neighbour.h>
-#include <net/netlink.h>
-#include <net/tcp.h>
-#include <net/dst.h>
-#include <net/flow.h>
-#include <net/fib_rules.h>
-#include <net/dn.h>
-#include <net/dn_route.h>
-#include <net/dn_fib.h>
-#include <net/dn_neigh.h>
-#include <net/dn_dev.h>
-
-struct dn_zone
-{
-	struct dn_zone		*dz_next;
-	struct dn_fib_node 	**dz_hash;
-	int			dz_nent;
-	int			dz_divisor;
-	u32			dz_hashmask;
-#define DZ_HASHMASK(dz)	((dz)->dz_hashmask)
-	int			dz_order;
-	__le16			dz_mask;
-#define DZ_MASK(dz)	((dz)->dz_mask)
-};
-
-struct dn_hash
-{
-	struct dn_zone	*dh_zones[17];
-	struct dn_zone	*dh_zone_list;
-};
-
-#define dz_key_0(key)		((key).datum = 0)
-
-#define for_nexthops(fi) { int nhsel; const struct dn_fib_nh *nh;\
-	for(nhsel = 0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++)
-
-#define endfor_nexthops(fi) }
-
-#define DN_MAX_DIVISOR 1024
-#define DN_S_ZOMBIE 1
-#define DN_S_ACCESSED 2
-
-#define DN_FIB_SCAN(f, fp) \
-for( ; ((f) = *(fp)) != NULL; (fp) = &(f)->fn_next)
-
-#define DN_FIB_SCAN_KEY(f, fp, key) \
-for( ; ((f) = *(fp)) != NULL && dn_key_eq((f)->fn_key, (key)); (fp) = &(f)->fn_next)
-
-#define RT_TABLE_MIN 1
-#define DN_FIB_TABLE_HASHSZ 256
-static struct hlist_head dn_fib_table_hash[DN_FIB_TABLE_HASHSZ];
-static DEFINE_RWLOCK(dn_fib_tables_lock);
-
-static struct kmem_cache *dn_hash_kmem __read_mostly;
-static int dn_fib_hash_zombies;
-
-static inline dn_fib_idx_t dn_hash(dn_fib_key_t key, struct dn_zone *dz)
-{
-	u16 h = le16_to_cpu(key.datum)>>(16 - dz->dz_order);
-	h ^= (h >> 10);
-	h ^= (h >> 6);
-	h &= DZ_HASHMASK(dz);
-	return *(dn_fib_idx_t *)&h;
-}
-
-static inline dn_fib_key_t dz_key(__le16 dst, struct dn_zone *dz)
-{
-	dn_fib_key_t k;
-	k.datum = dst & DZ_MASK(dz);
-	return k;
-}
-
-static inline struct dn_fib_node **dn_chain_p(dn_fib_key_t key, struct dn_zone *dz)
-{
-	return &dz->dz_hash[dn_hash(key, dz).datum];
-}
-
-static inline struct dn_fib_node *dz_chain(dn_fib_key_t key, struct dn_zone *dz)
-{
-	return dz->dz_hash[dn_hash(key, dz).datum];
-}
-
-static inline int dn_key_eq(dn_fib_key_t a, dn_fib_key_t b)
-{
-	return a.datum == b.datum;
-}
-
-static inline int dn_key_leq(dn_fib_key_t a, dn_fib_key_t b)
-{
-	return a.datum <= b.datum;
-}
-
-static inline void dn_rebuild_zone(struct dn_zone *dz,
-				   struct dn_fib_node **old_ht,
-				   int old_divisor)
-{
-	struct dn_fib_node *f, **fp, *next;
-	int i;
-
-	for(i = 0; i < old_divisor; i++) {
-		for(f = old_ht[i]; f; f = next) {
-			next = f->fn_next;
-			for(fp = dn_chain_p(f->fn_key, dz);
-				*fp && dn_key_leq((*fp)->fn_key, f->fn_key);
-				fp = &(*fp)->fn_next)
-				/* NOTHING */;
-			f->fn_next = *fp;
-			*fp = f;
-		}
-	}
-}
-
-static void dn_rehash_zone(struct dn_zone *dz)
-{
-	struct dn_fib_node **ht, **old_ht;
-	int old_divisor, new_divisor;
-	u32 new_hashmask;
-
-	old_divisor = dz->dz_divisor;
-
-	switch (old_divisor) {
-	case 16:
-		new_divisor = 256;
-		new_hashmask = 0xFF;
-		break;
-	default:
-		printk(KERN_DEBUG "DECnet: dn_rehash_zone: BUG! %d\n",
-		       old_divisor);
-		fallthrough;
-	case 256:
-		new_divisor = 1024;
-		new_hashmask = 0x3FF;
-		break;
-	}
-
-	ht = kcalloc(new_divisor, sizeof(struct dn_fib_node*), GFP_KERNEL);
-	if (ht == NULL)
-		return;
-
-	write_lock_bh(&dn_fib_tables_lock);
-	old_ht = dz->dz_hash;
-	dz->dz_hash = ht;
-	dz->dz_hashmask = new_hashmask;
-	dz->dz_divisor = new_divisor;
-	dn_rebuild_zone(dz, old_ht, old_divisor);
-	write_unlock_bh(&dn_fib_tables_lock);
-	kfree(old_ht);
-}
-
-static void dn_free_node(struct dn_fib_node *f)
-{
-	dn_fib_release_info(DN_FIB_INFO(f));
-	kmem_cache_free(dn_hash_kmem, f);
-}
-
-
-static struct dn_zone *dn_new_zone(struct dn_hash *table, int z)
-{
-	int i;
-	struct dn_zone *dz = kzalloc(sizeof(struct dn_zone), GFP_KERNEL);
-	if (!dz)
-		return NULL;
-
-	if (z) {
-		dz->dz_divisor = 16;
-		dz->dz_hashmask = 0x0F;
-	} else {
-		dz->dz_divisor = 1;
-		dz->dz_hashmask = 0;
-	}
-
-	dz->dz_hash = kcalloc(dz->dz_divisor, sizeof(struct dn_fib_node *), GFP_KERNEL);
-	if (!dz->dz_hash) {
-		kfree(dz);
-		return NULL;
-	}
-
-	dz->dz_order = z;
-	dz->dz_mask = dnet_make_mask(z);
-
-	for(i = z + 1; i <= 16; i++)
-		if (table->dh_zones[i])
-			break;
-
-	write_lock_bh(&dn_fib_tables_lock);
-	if (i>16) {
-		dz->dz_next = table->dh_zone_list;
-		table->dh_zone_list = dz;
-	} else {
-		dz->dz_next = table->dh_zones[i]->dz_next;
-		table->dh_zones[i]->dz_next = dz;
-	}
-	table->dh_zones[z] = dz;
-	write_unlock_bh(&dn_fib_tables_lock);
-	return dz;
-}
-
-
-static int dn_fib_nh_match(struct rtmsg *r, struct nlmsghdr *nlh, struct nlattr *attrs[], struct dn_fib_info *fi)
-{
-	struct rtnexthop *nhp;
-	int nhlen;
-
-	if (attrs[RTA_PRIORITY] &&
-	    nla_get_u32(attrs[RTA_PRIORITY]) != fi->fib_priority)
-		return 1;
-
-	if (attrs[RTA_OIF] || attrs[RTA_GATEWAY]) {
-		if ((!attrs[RTA_OIF] || nla_get_u32(attrs[RTA_OIF]) == fi->fib_nh->nh_oif) &&
-		    (!attrs[RTA_GATEWAY]  || nla_get_le16(attrs[RTA_GATEWAY]) != fi->fib_nh->nh_gw))
-			return 0;
-		return 1;
-	}
-
-	if (!attrs[RTA_MULTIPATH])
-		return 0;
-
-	nhp = nla_data(attrs[RTA_MULTIPATH]);
-	nhlen = nla_len(attrs[RTA_MULTIPATH]);
-
-	for_nexthops(fi) {
-		int attrlen = nhlen - sizeof(struct rtnexthop);
-		__le16 gw;
-
-		if (attrlen < 0 || (nhlen -= nhp->rtnh_len) < 0)
-			return -EINVAL;
-		if (nhp->rtnh_ifindex && nhp->rtnh_ifindex != nh->nh_oif)
-			return 1;
-		if (attrlen) {
-			struct nlattr *gw_attr;
-
-			gw_attr = nla_find((struct nlattr *) (nhp + 1), attrlen, RTA_GATEWAY);
-			gw = gw_attr ? nla_get_le16(gw_attr) : 0;
-
-			if (gw && gw != nh->nh_gw)
-				return 1;
-		}
-		nhp = RTNH_NEXT(nhp);
-	} endfor_nexthops(fi);
-
-	return 0;
-}
-
-static inline size_t dn_fib_nlmsg_size(struct dn_fib_info *fi)
-{
-	size_t payload = NLMSG_ALIGN(sizeof(struct rtmsg))
-			 + nla_total_size(4) /* RTA_TABLE */
-			 + nla_total_size(2) /* RTA_DST */
-			 + nla_total_size(4) /* RTA_PRIORITY */
-			 + nla_total_size(TCP_CA_NAME_MAX); /* RTAX_CC_ALGO */
-
-	/* space for nested metrics */
-	payload += nla_total_size((RTAX_MAX * nla_total_size(4)));
-
-	if (fi->fib_nhs) {
-		/* Also handles the special case fib_nhs == 1 */
-
-		/* each nexthop is packed in an attribute */
-		size_t nhsize = nla_total_size(sizeof(struct rtnexthop));
-
-		/* may contain a gateway attribute */
-		nhsize += nla_total_size(4);
-
-		/* all nexthops are packed in a nested attribute */
-		payload += nla_total_size(fi->fib_nhs * nhsize);
-	}
-
-	return payload;
-}
-
-static int dn_fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
-			u32 tb_id, u8 type, u8 scope, void *dst, int dst_len,
-			struct dn_fib_info *fi, unsigned int flags)
-{
-	struct rtmsg *rtm;
-	struct nlmsghdr *nlh;
-
-	nlh = nlmsg_put(skb, portid, seq, event, sizeof(*rtm), flags);
-	if (!nlh)
-		return -EMSGSIZE;
-
-	rtm = nlmsg_data(nlh);
-	rtm->rtm_family = AF_DECnet;
-	rtm->rtm_dst_len = dst_len;
-	rtm->rtm_src_len = 0;
-	rtm->rtm_tos = 0;
-	rtm->rtm_table = tb_id;
-	rtm->rtm_flags = fi->fib_flags;
-	rtm->rtm_scope = scope;
-	rtm->rtm_type  = type;
-	rtm->rtm_protocol = fi->fib_protocol;
-
-	if (nla_put_u32(skb, RTA_TABLE, tb_id) < 0)
-		goto errout;
-
-	if (rtm->rtm_dst_len &&
-	    nla_put(skb, RTA_DST, 2, dst) < 0)
-		goto errout;
-
-	if (fi->fib_priority &&
-	    nla_put_u32(skb, RTA_PRIORITY, fi->fib_priority) < 0)
-		goto errout;
-
-	if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0)
-		goto errout;
-
-	if (fi->fib_nhs == 1) {
-		if (fi->fib_nh->nh_gw &&
-		    nla_put_le16(skb, RTA_GATEWAY, fi->fib_nh->nh_gw) < 0)
-			goto errout;
-
-		if (fi->fib_nh->nh_oif &&
-		    nla_put_u32(skb, RTA_OIF, fi->fib_nh->nh_oif) < 0)
-			goto errout;
-	}
-
-	if (fi->fib_nhs > 1) {
-		struct rtnexthop *nhp;
-		struct nlattr *mp_head;
-
-		mp_head = nla_nest_start_noflag(skb, RTA_MULTIPATH);
-		if (!mp_head)
-			goto errout;
-
-		for_nexthops(fi) {
-			if (!(nhp = nla_reserve_nohdr(skb, sizeof(*nhp))))
-				goto errout;
-
-			nhp->rtnh_flags = nh->nh_flags & 0xFF;
-			nhp->rtnh_hops = nh->nh_weight - 1;
-			nhp->rtnh_ifindex = nh->nh_oif;
-
-			if (nh->nh_gw &&
-			    nla_put_le16(skb, RTA_GATEWAY, nh->nh_gw) < 0)
-				goto errout;
-
-			nhp->rtnh_len = skb_tail_pointer(skb) - (unsigned char *)nhp;
-		} endfor_nexthops(fi);
-
-		nla_nest_end(skb, mp_head);
-	}
-
-	nlmsg_end(skb, nlh);
-	return 0;
-
-errout:
-	nlmsg_cancel(skb, nlh);
-	return -EMSGSIZE;
-}
-
-
-static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, u32 tb_id,
-			struct nlmsghdr *nlh, struct netlink_skb_parms *req)
-{
-	struct sk_buff *skb;
-	u32 portid = req ? req->portid : 0;
-	int err = -ENOBUFS;
-
-	skb = nlmsg_new(dn_fib_nlmsg_size(DN_FIB_INFO(f)), GFP_KERNEL);
-	if (skb == NULL)
-		goto errout;
-
-	err = dn_fib_dump_info(skb, portid, nlh->nlmsg_seq, event, tb_id,
-			       f->fn_type, f->fn_scope, &f->fn_key, z,
-			       DN_FIB_INFO(f), 0);
-	if (err < 0) {
-		/* -EMSGSIZE implies BUG in dn_fib_nlmsg_size() */
-		WARN_ON(err == -EMSGSIZE);
-		kfree_skb(skb);
-		goto errout;
-	}
-	rtnl_notify(skb, &init_net, portid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
-	return;
-errout:
-	if (err < 0)
-		rtnl_set_sk_err(&init_net, RTNLGRP_DECnet_ROUTE, err);
-}
-
-static __inline__ int dn_hash_dump_bucket(struct sk_buff *skb,
-				struct netlink_callback *cb,
-				struct dn_fib_table *tb,
-				struct dn_zone *dz,
-				struct dn_fib_node *f)
-{
-	int i, s_i;
-
-	s_i = cb->args[4];
-	for(i = 0; f; i++, f = f->fn_next) {
-		if (i < s_i)
-			continue;
-		if (f->fn_state & DN_S_ZOMBIE)
-			continue;
-		if (dn_fib_dump_info(skb, NETLINK_CB(cb->skb).portid,
-				cb->nlh->nlmsg_seq,
-				RTM_NEWROUTE,
-				tb->n,
-				(f->fn_state & DN_S_ZOMBIE) ? 0 : f->fn_type,
-				f->fn_scope, &f->fn_key, dz->dz_order,
-				f->fn_info, NLM_F_MULTI) < 0) {
-			cb->args[4] = i;
-			return -1;
-		}
-	}
-	cb->args[4] = i;
-	return skb->len;
-}
-
-static __inline__ int dn_hash_dump_zone(struct sk_buff *skb,
-				struct netlink_callback *cb,
-				struct dn_fib_table *tb,
-				struct dn_zone *dz)
-{
-	int h, s_h;
-
-	s_h = cb->args[3];
-	for(h = 0; h < dz->dz_divisor; h++) {
-		if (h < s_h)
-			continue;
-		if (h > s_h)
-			memset(&cb->args[4], 0, sizeof(cb->args) - 4*sizeof(cb->args[0]));
-		if (dz->dz_hash == NULL || dz->dz_hash[h] == NULL)
-			continue;
-		if (dn_hash_dump_bucket(skb, cb, tb, dz, dz->dz_hash[h]) < 0) {
-			cb->args[3] = h;
-			return -1;
-		}
-	}
-	cb->args[3] = h;
-	return skb->len;
-}
-
-static int dn_fib_table_dump(struct dn_fib_table *tb, struct sk_buff *skb,
-				struct netlink_callback *cb)
-{
-	int m, s_m;
-	struct dn_zone *dz;
-	struct dn_hash *table = (struct dn_hash *)tb->data;
-
-	s_m = cb->args[2];
-	read_lock(&dn_fib_tables_lock);
-	for(dz = table->dh_zone_list, m = 0; dz; dz = dz->dz_next, m++) {
-		if (m < s_m)
-			continue;
-		if (m > s_m)
-			memset(&cb->args[3], 0, sizeof(cb->args) - 3*sizeof(cb->args[0]));
-
-		if (dn_hash_dump_zone(skb, cb, tb, dz) < 0) {
-			cb->args[2] = m;
-			read_unlock(&dn_fib_tables_lock);
-			return -1;
-		}
-	}
-	read_unlock(&dn_fib_tables_lock);
-	cb->args[2] = m;
-
-	return skb->len;
-}
-
-int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb)
-{
-	struct net *net = sock_net(skb->sk);
-	unsigned int h, s_h;
-	unsigned int e = 0, s_e;
-	struct dn_fib_table *tb;
-	int dumped = 0;
-
-	if (!net_eq(net, &init_net))
-		return 0;
-
-	if (nlmsg_len(cb->nlh) >= sizeof(struct rtmsg) &&
-		((struct rtmsg *)nlmsg_data(cb->nlh))->rtm_flags&RTM_F_CLONED)
-			return dn_cache_dump(skb, cb);
-
-	s_h = cb->args[0];
-	s_e = cb->args[1];
-
-	for (h = s_h; h < DN_FIB_TABLE_HASHSZ; h++, s_h = 0) {
-		e = 0;
-		hlist_for_each_entry(tb, &dn_fib_table_hash[h], hlist) {
-			if (e < s_e)
-				goto next;
-			if (dumped)
-				memset(&cb->args[2], 0, sizeof(cb->args) -
-						 2 * sizeof(cb->args[0]));
-			if (tb->dump(tb, skb, cb) < 0)
-				goto out;
-			dumped = 1;
-next:
-			e++;
-		}
-	}
-out:
-	cb->args[1] = e;
-	cb->args[0] = h;
-
-	return skb->len;
-}
-
-static int dn_fib_table_insert(struct dn_fib_table *tb, struct rtmsg *r, struct nlattr *attrs[],
-			       struct nlmsghdr *n, struct netlink_skb_parms *req)
-{
-	struct dn_hash *table = (struct dn_hash *)tb->data;
-	struct dn_fib_node *new_f, *f, **fp, **del_fp;
-	struct dn_zone *dz;
-	struct dn_fib_info *fi;
-	int z = r->rtm_dst_len;
-	int type = r->rtm_type;
-	dn_fib_key_t key;
-	int err;
-
-	if (z > 16)
-		return -EINVAL;
-
-	dz = table->dh_zones[z];
-	if (!dz && !(dz = dn_new_zone(table, z)))
-		return -ENOBUFS;
-
-	dz_key_0(key);
-	if (attrs[RTA_DST]) {
-		__le16 dst = nla_get_le16(attrs[RTA_DST]);
-		if (dst & ~DZ_MASK(dz))
-			return -EINVAL;
-		key = dz_key(dst, dz);
-	}
-
-	if ((fi = dn_fib_create_info(r, attrs, n, &err)) == NULL)
-		return err;
-
-	if (dz->dz_nent > (dz->dz_divisor << 2) &&
-			dz->dz_divisor > DN_MAX_DIVISOR &&
-			(z==16 || (1<<z) > dz->dz_divisor))
-		dn_rehash_zone(dz);
-
-	fp = dn_chain_p(key, dz);
-
-	DN_FIB_SCAN(f, fp) {
-		if (dn_key_leq(key, f->fn_key))
-			break;
-	}
-
-	del_fp = NULL;
-
-	if (f && (f->fn_state & DN_S_ZOMBIE) &&
-			dn_key_eq(f->fn_key, key)) {
-		del_fp = fp;
-		fp = &f->fn_next;
-		f = *fp;
-		goto create;
-	}
-
-	DN_FIB_SCAN_KEY(f, fp, key) {
-		if (fi->fib_priority <= DN_FIB_INFO(f)->fib_priority)
-			break;
-	}
-
-	if (f && dn_key_eq(f->fn_key, key) &&
-			fi->fib_priority == DN_FIB_INFO(f)->fib_priority) {
-		struct dn_fib_node **ins_fp;
-
-		err = -EEXIST;
-		if (n->nlmsg_flags & NLM_F_EXCL)
-			goto out;
-
-		if (n->nlmsg_flags & NLM_F_REPLACE) {
-			del_fp = fp;
-			fp = &f->fn_next;
-			f = *fp;
-			goto replace;
-		}
-
-		ins_fp = fp;
-		err = -EEXIST;
-
-		DN_FIB_SCAN_KEY(f, fp, key) {
-			if (fi->fib_priority != DN_FIB_INFO(f)->fib_priority)
-				break;
-			if (f->fn_type == type &&
-			    f->fn_scope == r->rtm_scope &&
-			    DN_FIB_INFO(f) == fi)
-				goto out;
-		}
-
-		if (!(n->nlmsg_flags & NLM_F_APPEND)) {
-			fp = ins_fp;
-			f = *fp;
-		}
-	}
-
-create:
-	err = -ENOENT;
-	if (!(n->nlmsg_flags & NLM_F_CREATE))
-		goto out;
-
-replace:
-	err = -ENOBUFS;
-	new_f = kmem_cache_zalloc(dn_hash_kmem, GFP_KERNEL);
-	if (new_f == NULL)
-		goto out;
-
-	new_f->fn_key = key;
-	new_f->fn_type = type;
-	new_f->fn_scope = r->rtm_scope;
-	DN_FIB_INFO(new_f) = fi;
-
-	new_f->fn_next = f;
-	write_lock_bh(&dn_fib_tables_lock);
-	*fp = new_f;
-	write_unlock_bh(&dn_fib_tables_lock);
-	dz->dz_nent++;
-
-	if (del_fp) {
-		f = *del_fp;
-		write_lock_bh(&dn_fib_tables_lock);
-		*del_fp = f->fn_next;
-		write_unlock_bh(&dn_fib_tables_lock);
-
-		if (!(f->fn_state & DN_S_ZOMBIE))
-			dn_rtmsg_fib(RTM_DELROUTE, f, z, tb->n, n, req);
-		if (f->fn_state & DN_S_ACCESSED)
-			dn_rt_cache_flush(-1);
-		dn_free_node(f);
-		dz->dz_nent--;
-	} else {
-		dn_rt_cache_flush(-1);
-	}
-
-	dn_rtmsg_fib(RTM_NEWROUTE, new_f, z, tb->n, n, req);
-
-	return 0;
-out:
-	dn_fib_release_info(fi);
-	return err;
-}
-
-
-static int dn_fib_table_delete(struct dn_fib_table *tb, struct rtmsg *r, struct nlattr *attrs[],
-			       struct nlmsghdr *n, struct netlink_skb_parms *req)
-{
-	struct dn_hash *table = (struct dn_hash*)tb->data;
-	struct dn_fib_node **fp, **del_fp, *f;
-	int z = r->rtm_dst_len;
-	struct dn_zone *dz;
-	dn_fib_key_t key;
-	int matched;
-
-
-	if (z > 16)
-		return -EINVAL;
-
-	if ((dz = table->dh_zones[z]) == NULL)
-		return -ESRCH;
-
-	dz_key_0(key);
-	if (attrs[RTA_DST]) {
-		__le16 dst = nla_get_le16(attrs[RTA_DST]);
-		if (dst & ~DZ_MASK(dz))
-			return -EINVAL;
-		key = dz_key(dst, dz);
-	}
-
-	fp = dn_chain_p(key, dz);
-
-	DN_FIB_SCAN(f, fp) {
-		if (dn_key_eq(f->fn_key, key))
-			break;
-		if (dn_key_leq(key, f->fn_key))
-			return -ESRCH;
-	}
-
-	matched = 0;
-	del_fp = NULL;
-	DN_FIB_SCAN_KEY(f, fp, key) {
-		struct dn_fib_info *fi = DN_FIB_INFO(f);
-
-		if (f->fn_state & DN_S_ZOMBIE)
-			return -ESRCH;
-
-		matched++;
-
-		if (del_fp == NULL &&
-				(!r->rtm_type || f->fn_type == r->rtm_type) &&
-				(r->rtm_scope == RT_SCOPE_NOWHERE || f->fn_scope == r->rtm_scope) &&
-				(!r->rtm_protocol ||
-					fi->fib_protocol == r->rtm_protocol) &&
-				dn_fib_nh_match(r, n, attrs, fi) == 0)
-			del_fp = fp;
-	}
-
-	if (del_fp) {
-		f = *del_fp;
-		dn_rtmsg_fib(RTM_DELROUTE, f, z, tb->n, n, req);
-
-		if (matched != 1) {
-			write_lock_bh(&dn_fib_tables_lock);
-			*del_fp = f->fn_next;
-			write_unlock_bh(&dn_fib_tables_lock);
-
-			if (f->fn_state & DN_S_ACCESSED)
-				dn_rt_cache_flush(-1);
-			dn_free_node(f);
-			dz->dz_nent--;
-		} else {
-			f->fn_state |= DN_S_ZOMBIE;
-			if (f->fn_state & DN_S_ACCESSED) {
-				f->fn_state &= ~DN_S_ACCESSED;
-				dn_rt_cache_flush(-1);
-			}
-			if (++dn_fib_hash_zombies > 128)
-				dn_fib_flush();
-		}
-
-		return 0;
-	}
-
-	return -ESRCH;
-}
-
-static inline int dn_flush_list(struct dn_fib_node **fp, int z, struct dn_hash *table)
-{
-	int found = 0;
-	struct dn_fib_node *f;
-
-	while((f = *fp) != NULL) {
-		struct dn_fib_info *fi = DN_FIB_INFO(f);
-
-		if (fi && ((f->fn_state & DN_S_ZOMBIE) || (fi->fib_flags & RTNH_F_DEAD))) {
-			write_lock_bh(&dn_fib_tables_lock);
-			*fp = f->fn_next;
-			write_unlock_bh(&dn_fib_tables_lock);
-
-			dn_free_node(f);
-			found++;
-			continue;
-		}
-		fp = &f->fn_next;
-	}
-
-	return found;
-}
-
-static int dn_fib_table_flush(struct dn_fib_table *tb)
-{
-	struct dn_hash *table = (struct dn_hash *)tb->data;
-	struct dn_zone *dz;
-	int found = 0;
-
-	dn_fib_hash_zombies = 0;
-	for(dz = table->dh_zone_list; dz; dz = dz->dz_next) {
-		int i;
-		int tmp = 0;
-		for(i = dz->dz_divisor-1; i >= 0; i--)
-			tmp += dn_flush_list(&dz->dz_hash[i], dz->dz_order, table);
-		dz->dz_nent -= tmp;
-		found += tmp;
-	}
-
-	return found;
-}
-
-static int dn_fib_table_lookup(struct dn_fib_table *tb, const struct flowidn *flp, struct dn_fib_res *res)
-{
-	int err;
-	struct dn_zone *dz;
-	struct dn_hash *t = (struct dn_hash *)tb->data;
-
-	read_lock(&dn_fib_tables_lock);
-	for(dz = t->dh_zone_list; dz; dz = dz->dz_next) {
-		struct dn_fib_node *f;
-		dn_fib_key_t k = dz_key(flp->daddr, dz);
-
-		for(f = dz_chain(k, dz); f; f = f->fn_next) {
-			if (!dn_key_eq(k, f->fn_key)) {
-				if (dn_key_leq(k, f->fn_key))
-					break;
-				else
-					continue;
-			}
-
-			f->fn_state |= DN_S_ACCESSED;
-
-			if (f->fn_state&DN_S_ZOMBIE)
-				continue;
-
-			if (f->fn_scope < flp->flowidn_scope)
-				continue;
-
-			err = dn_fib_semantic_match(f->fn_type, DN_FIB_INFO(f), flp, res);
-
-			if (err == 0) {
-				res->type = f->fn_type;
-				res->scope = f->fn_scope;
-				res->prefixlen = dz->dz_order;
-				goto out;
-			}
-			if (err < 0)
-				goto out;
-		}
-	}
-	err = 1;
-out:
-	read_unlock(&dn_fib_tables_lock);
-	return err;
-}
-
-
-struct dn_fib_table *dn_fib_get_table(u32 n, int create)
-{
-	struct dn_fib_table *t;
-	unsigned int h;
-
-	if (n < RT_TABLE_MIN)
-		return NULL;
-
-	if (n > RT_TABLE_MAX)
-		return NULL;
-
-	h = n & (DN_FIB_TABLE_HASHSZ - 1);
-	rcu_read_lock();
-	hlist_for_each_entry_rcu(t, &dn_fib_table_hash[h], hlist) {
-		if (t->n == n) {
-			rcu_read_unlock();
-			return t;
-		}
-	}
-	rcu_read_unlock();
-
-	if (!create)
-		return NULL;
-
-	if (in_interrupt()) {
-		net_dbg_ratelimited("DECnet: BUG! Attempt to create routing table from interrupt\n");
-		return NULL;
-	}
-
-	t = kzalloc(sizeof(struct dn_fib_table) + sizeof(struct dn_hash),
-		    GFP_KERNEL);
-	if (t == NULL)
-		return NULL;
-
-	t->n = n;
-	t->insert = dn_fib_table_insert;
-	t->delete = dn_fib_table_delete;
-	t->lookup = dn_fib_table_lookup;
-	t->flush  = dn_fib_table_flush;
-	t->dump = dn_fib_table_dump;
-	hlist_add_head_rcu(&t->hlist, &dn_fib_table_hash[h]);
-
-	return t;
-}
-
-struct dn_fib_table *dn_fib_empty_table(void)
-{
-	u32 id;
-
-	for(id = RT_TABLE_MIN; id <= RT_TABLE_MAX; id++)
-		if (dn_fib_get_table(id, 0) == NULL)
-			return dn_fib_get_table(id, 1);
-	return NULL;
-}
-
-void dn_fib_flush(void)
-{
-	int flushed = 0;
-	struct dn_fib_table *tb;
-	unsigned int h;
-
-	for (h = 0; h < DN_FIB_TABLE_HASHSZ; h++) {
-		hlist_for_each_entry(tb, &dn_fib_table_hash[h], hlist)
-			flushed += tb->flush(tb);
-	}
-
-	if (flushed)
-		dn_rt_cache_flush(-1);
-}
-
-void __init dn_fib_table_init(void)
-{
-	dn_hash_kmem = kmem_cache_create("dn_fib_info_cache",
-					sizeof(struct dn_fib_info),
-					0, SLAB_HWCACHE_ALIGN,
-					NULL);
-}
-
-void __exit dn_fib_table_cleanup(void)
-{
-	struct dn_fib_table *t;
-	struct hlist_node *next;
-	unsigned int h;
-
-	write_lock(&dn_fib_tables_lock);
-	for (h = 0; h < DN_FIB_TABLE_HASHSZ; h++) {
-		hlist_for_each_entry_safe(t, next, &dn_fib_table_hash[h],
-					  hlist) {
-			hlist_del(&t->hlist);
-			kfree(t);
-		}
-	}
-	write_unlock(&dn_fib_tables_lock);
-}
diff --git a/kernel/net/decnet/dn_timer.c b/kernel/net/decnet/dn_timer.c
deleted file mode 100644
index aa41558..0000000
--- a/kernel/net/decnet/dn_timer.c
+++ /dev/null
@@ -1,104 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * DECnet       An implementation of the DECnet protocol suite for the LINUX
- *              operating system.  DECnet is implemented using the  BSD Socket
- *              interface as the means of communication with the user level.
- *
- *              DECnet Socket Timer Functions
- *
- * Author:      Steve Whitehouse <SteveW@ACM.org>
- *
- *
- * Changes:
- *       Steve Whitehouse      : Made keepalive timer part of the same
- *                               timer idea.
- *       Steve Whitehouse      : Added checks for sk->sock_readers
- *       David S. Miller       : New socket locking
- *       Steve Whitehouse      : Timer grabs socket ref.
- */
-#include <linux/net.h>
-#include <linux/socket.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/timer.h>
-#include <linux/spinlock.h>
-#include <net/sock.h>
-#include <linux/atomic.h>
-#include <linux/jiffies.h>
-#include <net/flow.h>
-#include <net/dn.h>
-
-/*
- * Slow timer is for everything else (n * 500mS)
- */
-
-#define SLOW_INTERVAL (HZ/2)
-
-static void dn_slow_timer(struct timer_list *t);
-
-void dn_start_slow_timer(struct sock *sk)
-{
-	timer_setup(&sk->sk_timer, dn_slow_timer, 0);
-	sk_reset_timer(sk, &sk->sk_timer, jiffies + SLOW_INTERVAL);
-}
-
-void dn_stop_slow_timer(struct sock *sk)
-{
-	sk_stop_timer(sk, &sk->sk_timer);
-}
-
-static void dn_slow_timer(struct timer_list *t)
-{
-	struct sock *sk = from_timer(sk, t, sk_timer);
-	struct dn_scp *scp = DN_SK(sk);
-
-	bh_lock_sock(sk);
-
-	if (sock_owned_by_user(sk)) {
-		sk_reset_timer(sk, &sk->sk_timer, jiffies + HZ / 10);
-		goto out;
-	}
-
-	/*
-	 * The persist timer is the standard slow timer used for retransmits
-	 * in both connection establishment and disconnection as well as
-	 * in the RUN state. The different states are catered for by changing
-	 * the function pointer in the socket. Setting the timer to a value
-	 * of zero turns it off. We allow the persist_fxn to turn the
-	 * timer off in a permant way by returning non-zero, so that
-	 * timer based routines may remove sockets. This is why we have a
-	 * sock_hold()/sock_put() around the timer to prevent the socket
-	 * going away in the middle.
-	 */
-	if (scp->persist && scp->persist_fxn) {
-		if (scp->persist <= SLOW_INTERVAL) {
-			scp->persist = 0;
-
-			if (scp->persist_fxn(sk))
-				goto out;
-		} else {
-			scp->persist -= SLOW_INTERVAL;
-		}
-	}
-
-	/*
-	 * Check for keepalive timeout. After the other timer 'cos if
-	 * the previous timer caused a retransmit, we don't need to
-	 * do this. scp->stamp is the last time that we sent a packet.
-	 * The keepalive function sends a link service packet to the
-	 * other end. If it remains unacknowledged, the standard
-	 * socket timers will eventually shut the socket down. Each
-	 * time we do this, scp->stamp will be updated, thus
-	 * we won't try and send another until scp->keepalive has passed
-	 * since the last successful transmission.
-	 */
-	if (scp->keepalive && scp->keepalive_fxn && (scp->state == DN_RUN)) {
-		if (time_after_eq(jiffies, scp->stamp + scp->keepalive))
-			scp->keepalive_fxn(sk);
-	}
-
-	sk_reset_timer(sk, &sk->sk_timer, jiffies + SLOW_INTERVAL);
-out:
-	bh_unlock_sock(sk);
-	sock_put(sk);
-}
diff --git a/kernel/net/decnet/netfilter/Kconfig b/kernel/net/decnet/netfilter/Kconfig
deleted file mode 100644
index 14ec4ef..0000000
--- a/kernel/net/decnet/netfilter/Kconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# DECnet netfilter configuration
-#
-
-menu "DECnet: Netfilter Configuration"
-	depends on DECNET && NETFILTER
-	depends on NETFILTER_ADVANCED
-
-config DECNET_NF_GRABULATOR
-	tristate "Routing message grabulator (for userland routing daemon)"
-	help
-	  Enable this module if you want to use the userland DECnet routing
-	  daemon. You will also need to enable routing support for DECnet
-	  unless you just want to monitor routing messages from other nodes.
-
-endmenu
diff --git a/kernel/net/decnet/netfilter/Makefile b/kernel/net/decnet/netfilter/Makefile
deleted file mode 100644
index 429c842..0000000
--- a/kernel/net/decnet/netfilter/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for DECnet netfilter modules
-#
-
-obj-$(CONFIG_DECNET_NF_GRABULATOR) += dn_rtmsg.o
diff --git a/kernel/net/decnet/netfilter/dn_rtmsg.c b/kernel/net/decnet/netfilter/dn_rtmsg.c
deleted file mode 100644
index 26a9193..0000000
--- a/kernel/net/decnet/netfilter/dn_rtmsg.c
+++ /dev/null
@@ -1,158 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * DECnet       An implementation of the DECnet protocol suite for the LINUX
- *              operating system.  DECnet is implemented using the  BSD Socket
- *              interface as the means of communication with the user level.
- *
- *              DECnet Routing Message Grabulator
- *
- *              (C) 2000 ChyGwyn Limited  -  https://www.chygwyn.com/
- *
- * Author:      Steven Whitehouse <steve@chygwyn.com>
- */
-#include <linux/module.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/netfilter.h>
-#include <linux/spinlock.h>
-#include <net/netlink.h>
-#include <linux/netfilter_decnet.h>
-
-#include <net/sock.h>
-#include <net/flow.h>
-#include <net/dn.h>
-#include <net/dn_route.h>
-
-static struct sock *dnrmg = NULL;
-
-
-static struct sk_buff *dnrmg_build_message(struct sk_buff *rt_skb, int *errp)
-{
-	struct sk_buff *skb = NULL;
-	size_t size;
-	sk_buff_data_t old_tail;
-	struct nlmsghdr *nlh;
-	unsigned char *ptr;
-	struct nf_dn_rtmsg *rtm;
-
-	size = NLMSG_ALIGN(rt_skb->len) +
-	       NLMSG_ALIGN(sizeof(struct nf_dn_rtmsg));
-	skb = nlmsg_new(size, GFP_ATOMIC);
-	if (!skb) {
-		*errp = -ENOMEM;
-		return NULL;
-	}
-	old_tail = skb->tail;
-	nlh = nlmsg_put(skb, 0, 0, 0, size, 0);
-	if (!nlh) {
-		kfree_skb(skb);
-		*errp = -ENOMEM;
-		return NULL;
-	}
-	rtm = (struct nf_dn_rtmsg *)nlmsg_data(nlh);
-	rtm->nfdn_ifindex = rt_skb->dev->ifindex;
-	ptr = NFDN_RTMSG(rtm);
-	skb_copy_from_linear_data(rt_skb, ptr, rt_skb->len);
-	nlh->nlmsg_len = skb->tail - old_tail;
-	return skb;
-}
-
-static void dnrmg_send_peer(struct sk_buff *skb)
-{
-	struct sk_buff *skb2;
-	int status = 0;
-	int group = 0;
-	unsigned char flags = *skb->data;
-
-	switch (flags & DN_RT_CNTL_MSK) {
-	case DN_RT_PKT_L1RT:
-		group = DNRNG_NLGRP_L1;
-		break;
-	case DN_RT_PKT_L2RT:
-		group = DNRNG_NLGRP_L2;
-		break;
-	default:
-		return;
-	}
-
-	skb2 = dnrmg_build_message(skb, &status);
-	if (skb2 == NULL)
-		return;
-	NETLINK_CB(skb2).dst_group = group;
-	netlink_broadcast(dnrmg, skb2, 0, group, GFP_ATOMIC);
-}
-
-
-static unsigned int dnrmg_hook(void *priv,
-			struct sk_buff *skb,
-			const struct nf_hook_state *state)
-{
-	dnrmg_send_peer(skb);
-	return NF_ACCEPT;
-}
-
-
-#define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err), NULL); return; } while (0)
-
-static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
-{
-	struct nlmsghdr *nlh = nlmsg_hdr(skb);
-
-	if (skb->len < sizeof(*nlh) ||
-	    nlh->nlmsg_len < sizeof(*nlh) ||
-	    skb->len < nlh->nlmsg_len)
-		return;
-
-	if (!netlink_capable(skb, CAP_NET_ADMIN))
-		RCV_SKB_FAIL(-EPERM);
-
-	/* Eventually we might send routing messages too */
-
-	RCV_SKB_FAIL(-EINVAL);
-}
-
-static const struct nf_hook_ops dnrmg_ops = {
-	.hook		= dnrmg_hook,
-	.pf		= NFPROTO_DECNET,
-	.hooknum	= NF_DN_ROUTE,
-	.priority	= NF_DN_PRI_DNRTMSG,
-};
-
-static int __init dn_rtmsg_init(void)
-{
-	int rv = 0;
-	struct netlink_kernel_cfg cfg = {
-		.groups	= DNRNG_NLGRP_MAX,
-		.input	= dnrmg_receive_user_skb,
-	};
-
-	dnrmg = netlink_kernel_create(&init_net, NETLINK_DNRTMSG, &cfg);
-	if (dnrmg == NULL) {
-		printk(KERN_ERR "dn_rtmsg: Cannot create netlink socket");
-		return -ENOMEM;
-	}
-
-	rv = nf_register_net_hook(&init_net, &dnrmg_ops);
-	if (rv) {
-		netlink_kernel_release(dnrmg);
-	}
-
-	return rv;
-}
-
-static void __exit dn_rtmsg_fini(void)
-{
-	nf_unregister_net_hook(&init_net, &dnrmg_ops);
-	netlink_kernel_release(dnrmg);
-}
-
-
-MODULE_DESCRIPTION("DECnet Routing Message Grabulator");
-MODULE_AUTHOR("Steven Whitehouse <steve@chygwyn.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_DNRTMSG);
-
-module_init(dn_rtmsg_init);
-module_exit(dn_rtmsg_fini);
diff --git a/kernel/net/decnet/sysctl_net_decnet.c b/kernel/net/decnet/sysctl_net_decnet.c
deleted file mode 100644
index 67b5ab2..0000000
--- a/kernel/net/decnet/sysctl_net_decnet.c
+++ /dev/null
@@ -1,362 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * DECnet       An implementation of the DECnet protocol suite for the LINUX
- *              operating system.  DECnet is implemented using the  BSD Socket
- *              interface as the means of communication with the user level.
- *
- *              DECnet sysctl support functions
- *
- * Author:      Steve Whitehouse <SteveW@ACM.org>
- *
- *
- * Changes:
- * Steve Whitehouse - C99 changes and default device handling
- * Steve Whitehouse - Memory buffer settings, like the tcp ones
- *
- */
-#include <linux/mm.h>
-#include <linux/sysctl.h>
-#include <linux/fs.h>
-#include <linux/netdevice.h>
-#include <linux/string.h>
-#include <net/neighbour.h>
-#include <net/dst.h>
-#include <net/flow.h>
-
-#include <linux/uaccess.h>
-
-#include <net/dn.h>
-#include <net/dn_dev.h>
-#include <net/dn_route.h>
-
-
-int decnet_debug_level;
-int decnet_time_wait = 30;
-int decnet_dn_count = 1;
-int decnet_di_count = 3;
-int decnet_dr_count = 3;
-int decnet_log_martians = 1;
-int decnet_no_fc_max_cwnd = NSP_MIN_WINDOW;
-
-/* Reasonable defaults, I hope, based on tcp's defaults */
-long sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 };
-int sysctl_decnet_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 };
-int sysctl_decnet_rmem[3] = { 4 * 1024, 87380, 87380 * 2 };
-
-#ifdef CONFIG_SYSCTL
-extern int decnet_dst_gc_interval;
-static int min_decnet_time_wait[] = { 5 };
-static int max_decnet_time_wait[] = { 600 };
-static int min_state_count[] = { 1 };
-static int max_state_count[] = { NSP_MAXRXTSHIFT };
-static int min_decnet_dst_gc_interval[] = { 1 };
-static int max_decnet_dst_gc_interval[] = { 60 };
-static int min_decnet_no_fc_max_cwnd[] = { NSP_MIN_WINDOW };
-static int max_decnet_no_fc_max_cwnd[] = { NSP_MAX_WINDOW };
-static char node_name[7] = "???";
-
-static struct ctl_table_header *dn_table_header = NULL;
-
-/*
- * ctype.h :-)
- */
-#define ISNUM(x) (((x) >= '0') && ((x) <= '9'))
-#define ISLOWER(x) (((x) >= 'a') && ((x) <= 'z'))
-#define ISUPPER(x) (((x) >= 'A') && ((x) <= 'Z'))
-#define ISALPHA(x) (ISLOWER(x) || ISUPPER(x))
-#define INVALID_END_CHAR(x) (ISNUM(x) || ISALPHA(x))
-
-static void strip_it(char *str)
-{
-	for(;;) {
-		switch (*str) {
-		case ' ':
-		case '\n':
-		case '\r':
-		case ':':
-			*str = 0;
-			fallthrough;
-		case 0:
-			return;
-		}
-		str++;
-	}
-}
-
-/*
- * Simple routine to parse an ascii DECnet address
- * into a network order address.
- */
-static int parse_addr(__le16 *addr, char *str)
-{
-	__u16 area, node;
-
-	while(*str && !ISNUM(*str)) str++;
-
-	if (*str == 0)
-		return -1;
-
-	area = (*str++ - '0');
-	if (ISNUM(*str)) {
-		area *= 10;
-		area += (*str++ - '0');
-	}
-
-	if (*str++ != '.')
-		return -1;
-
-	if (!ISNUM(*str))
-		return -1;
-
-	node = *str++ - '0';
-	if (ISNUM(*str)) {
-		node *= 10;
-		node += (*str++ - '0');
-	}
-	if (ISNUM(*str)) {
-		node *= 10;
-		node += (*str++ - '0');
-	}
-	if (ISNUM(*str)) {
-		node *= 10;
-		node += (*str++ - '0');
-	}
-
-	if ((node > 1023) || (area > 63))
-		return -1;
-
-	if (INVALID_END_CHAR(*str))
-		return -1;
-
-	*addr = cpu_to_le16((area << 10) | node);
-
-	return 0;
-}
-
-static int dn_node_address_handler(struct ctl_table *table, int write,
-		void *buffer, size_t *lenp, loff_t *ppos)
-{
-	char addr[DN_ASCBUF_LEN];
-	size_t len;
-	__le16 dnaddr;
-
-	if (!*lenp || (*ppos && !write)) {
-		*lenp = 0;
-		return 0;
-	}
-
-	if (write) {
-		len = (*lenp < DN_ASCBUF_LEN) ? *lenp : (DN_ASCBUF_LEN-1);
-		memcpy(addr, buffer, len);
-		addr[len] = 0;
-		strip_it(addr);
-
-		if (parse_addr(&dnaddr, addr))
-			return -EINVAL;
-
-		dn_dev_devices_off();
-
-		decnet_address = dnaddr;
-
-		dn_dev_devices_on();
-
-		*ppos += len;
-
-		return 0;
-	}
-
-	dn_addr2asc(le16_to_cpu(decnet_address), addr);
-	len = strlen(addr);
-	addr[len++] = '\n';
-
-	if (len > *lenp)
-		len = *lenp;
-	memcpy(buffer, addr, len);
-	*lenp = len;
-	*ppos += len;
-
-	return 0;
-}
-
-static int dn_def_dev_handler(struct ctl_table *table, int write,
-		void *buffer, size_t *lenp, loff_t *ppos)
-{
-	size_t len;
-	struct net_device *dev;
-	char devname[17];
-
-	if (!*lenp || (*ppos && !write)) {
-		*lenp = 0;
-		return 0;
-	}
-
-	if (write) {
-		if (*lenp > 16)
-			return -E2BIG;
-
-		memcpy(devname, buffer, *lenp);
-		devname[*lenp] = 0;
-		strip_it(devname);
-
-		dev = dev_get_by_name(&init_net, devname);
-		if (dev == NULL)
-			return -ENODEV;
-
-		if (dev->dn_ptr == NULL) {
-			dev_put(dev);
-			return -ENODEV;
-		}
-
-		if (dn_dev_set_default(dev, 1)) {
-			dev_put(dev);
-			return -ENODEV;
-		}
-		*ppos += *lenp;
-
-		return 0;
-	}
-
-	dev = dn_dev_get_default();
-	if (dev == NULL) {
-		*lenp = 0;
-		return 0;
-	}
-
-	strcpy(devname, dev->name);
-	dev_put(dev);
-	len = strlen(devname);
-	devname[len++] = '\n';
-
-	if (len > *lenp) len = *lenp;
-
-	memcpy(buffer, devname, len);
-	*lenp = len;
-	*ppos += len;
-
-	return 0;
-}
-
-static struct ctl_table dn_table[] = {
-	{
-		.procname = "node_address",
-		.maxlen = 7,
-		.mode = 0644,
-		.proc_handler = dn_node_address_handler,
-	},
-	{
-		.procname = "node_name",
-		.data = node_name,
-		.maxlen = 7,
-		.mode = 0644,
-		.proc_handler = proc_dostring,
-	},
-	{
-		.procname = "default_device",
-		.maxlen = 16,
-		.mode = 0644,
-		.proc_handler = dn_def_dev_handler,
-	},
-	{
-		.procname = "time_wait",
-		.data = &decnet_time_wait,
-		.maxlen = sizeof(int),
-		.mode = 0644,
-		.proc_handler = proc_dointvec_minmax,
-		.extra1 = &min_decnet_time_wait,
-		.extra2 = &max_decnet_time_wait
-	},
-	{
-		.procname = "dn_count",
-		.data = &decnet_dn_count,
-		.maxlen = sizeof(int),
-		.mode = 0644,
-		.proc_handler = proc_dointvec_minmax,
-		.extra1 = &min_state_count,
-		.extra2 = &max_state_count
-	},
-	{
-		.procname = "di_count",
-		.data = &decnet_di_count,
-		.maxlen = sizeof(int),
-		.mode = 0644,
-		.proc_handler = proc_dointvec_minmax,
-		.extra1 = &min_state_count,
-		.extra2 = &max_state_count
-	},
-	{
-		.procname = "dr_count",
-		.data = &decnet_dr_count,
-		.maxlen = sizeof(int),
-		.mode = 0644,
-		.proc_handler = proc_dointvec_minmax,
-		.extra1 = &min_state_count,
-		.extra2 = &max_state_count
-	},
-	{
-		.procname = "dst_gc_interval",
-		.data = &decnet_dst_gc_interval,
-		.maxlen = sizeof(int),
-		.mode = 0644,
-		.proc_handler = proc_dointvec_minmax,
-		.extra1 = &min_decnet_dst_gc_interval,
-		.extra2 = &max_decnet_dst_gc_interval
-	},
-	{
-		.procname = "no_fc_max_cwnd",
-		.data = &decnet_no_fc_max_cwnd,
-		.maxlen = sizeof(int),
-		.mode = 0644,
-		.proc_handler = proc_dointvec_minmax,
-		.extra1 = &min_decnet_no_fc_max_cwnd,
-		.extra2 = &max_decnet_no_fc_max_cwnd
-	},
-       {
-		.procname = "decnet_mem",
-		.data = &sysctl_decnet_mem,
-		.maxlen = sizeof(sysctl_decnet_mem),
-		.mode = 0644,
-		.proc_handler = proc_doulongvec_minmax
-	},
-	{
-		.procname = "decnet_rmem",
-		.data = &sysctl_decnet_rmem,
-		.maxlen = sizeof(sysctl_decnet_rmem),
-		.mode = 0644,
-		.proc_handler = proc_dointvec,
-	},
-	{
-		.procname = "decnet_wmem",
-		.data = &sysctl_decnet_wmem,
-		.maxlen = sizeof(sysctl_decnet_wmem),
-		.mode = 0644,
-		.proc_handler = proc_dointvec,
-	},
-	{
-		.procname = "debug",
-		.data = &decnet_debug_level,
-		.maxlen = sizeof(int),
-		.mode = 0644,
-		.proc_handler = proc_dointvec,
-	},
-	{ }
-};
-
-void dn_register_sysctl(void)
-{
-	dn_table_header = register_net_sysctl(&init_net, "net/decnet", dn_table);
-}
-
-void dn_unregister_sysctl(void)
-{
-	unregister_net_sysctl_table(dn_table_header);
-}
-
-#else  /* CONFIG_SYSCTL */
-void dn_unregister_sysctl(void)
-{
-}
-void dn_register_sysctl(void)
-{
-}
-
-#endif
diff --git a/kernel/net/dsa/tag_sja1105.c b/kernel/net/dsa/tag_sja1105.c
index 5049601..0787616 100644
--- a/kernel/net/dsa/tag_sja1105.c
+++ b/kernel/net/dsa/tag_sja1105.c
@@ -48,8 +48,8 @@
 	 * a unified unpacking command for both device series.
 	 */
 	packing(buf,     &meta->tstamp,     31, 0, 4, UNPACK, 0);
-	packing(buf + 4, &meta->dmac_byte_4, 7, 0, 1, UNPACK, 0);
-	packing(buf + 5, &meta->dmac_byte_3, 7, 0, 1, UNPACK, 0);
+	packing(buf + 4, &meta->dmac_byte_3, 7, 0, 1, UNPACK, 0);
+	packing(buf + 5, &meta->dmac_byte_4, 7, 0, 1, UNPACK, 0);
 	packing(buf + 6, &meta->source_port, 7, 0, 1, UNPACK, 0);
 	packing(buf + 7, &meta->switch_id,   7, 0, 1, UNPACK, 0);
 }
diff --git a/kernel/net/ethtool/ioctl.c b/kernel/net/ethtool/ioctl.c
index 80d2a00..12bf740 100644
--- a/kernel/net/ethtool/ioctl.c
+++ b/kernel/net/ethtool/ioctl.c
@@ -1966,7 +1966,8 @@
 	} 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();
@@ -2051,7 +2052,8 @@
 		return n_stats;
 	if (n_stats > S32_MAX / sizeof(u64))
 		return -ENOMEM;
-	WARN_ON_ONCE(!n_stats);
+	if (WARN_ON_ONCE(!n_stats))
+		return -EOPNOTSUPP;
 
 	if (copy_from_user(&stats, useraddr, sizeof(stats)))
 		return -EFAULT;
diff --git a/kernel/net/hsr/hsr_device.c b/kernel/net/hsr/hsr_device.c
index fec1b01..84e6ef4 100644
--- a/kernel/net/hsr/hsr_device.c
+++ b/kernel/net/hsr/hsr_device.c
@@ -219,7 +219,9 @@
 		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);
@@ -232,7 +234,7 @@
 	.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 +246,7 @@
 	 * 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 +254,9 @@
 
 	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 +278,9 @@
 {
 	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,21 +289,10 @@
 		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));
@@ -314,17 +300,14 @@
 	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++;
-		hsr_tag->sequence_nr = htons(hsr->sequence_nr);
-		hsr->sequence_nr++;
 	} else {
 		hsr_stag->sequence_nr = htons(hsr->sequence_nr);
 		hsr->sequence_nr++;
 	}
-	spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
 
 	hsr_stag->HSR_TLV_type = type;
 	/* TODO: Why 12 in HSRv0? */
@@ -335,11 +318,13 @@
 	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_bh(&hsr->seqnr_lock);
 		return;
+	}
 
 	hsr_forward_skb(skb, master);
-
+	spin_unlock_bh(&hsr->seqnr_lock);
 	return;
 }
 
@@ -349,12 +334,9 @@
 	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;
-	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;
@@ -366,7 +348,7 @@
 	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;
@@ -376,20 +358,13 @@
 	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)) {
-		spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
+	if (skb_put_padto(skb, ETH_ZLEN)) {
+		spin_unlock_bh(&hsr->seqnr_lock);
 		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);
+	spin_unlock_bh(&hsr->seqnr_lock);
 }
 
 /* Announce (supervision frame) timer function
@@ -468,7 +443,7 @@
 	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/kernel/net/hsr/hsr_forward.c b/kernel/net/hsr/hsr_forward.c
index cb9b54a..2a02cb2 100644
--- a/kernel/net/hsr/hsr_forward.c
+++ b/kernel/net/hsr/hsr_forward.c
@@ -186,6 +186,7 @@
 	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 @@
 	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;
 }
@@ -435,7 +437,6 @@
 {
 	struct hsr_port *port = frame->port_rcv;
 	struct hsr_priv *hsr = port->hsr;
-	unsigned long irqflags;
 
 	frame->skb_hsr = NULL;
 	frame->skb_prp = NULL;
@@ -445,17 +446,20 @@
 		frame->is_from_san = true;
 	} else {
 		/* Sequence nr for the master node */
-		spin_lock_irqsave(&hsr->seqnr_lock, irqflags);
+		lockdep_assert_held(&hsr->seqnr_lock);
 		frame->sequence_nr = hsr->sequence_nr;
 		hsr->sequence_nr++;
-		spin_unlock_irqrestore(&hsr->seqnr_lock, irqflags);
 	}
 }
 
 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))
@@ -527,6 +531,7 @@
 		proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto;
 		/* FIXME: */
 		netdev_warn_once(skb->dev, "VLAN not yet supported");
+		return -EINVAL;
 	}
 
 	frame->is_from_san = false;
@@ -545,11 +550,13 @@
 {
 	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 +571,7 @@
 	return;
 
 out_drop:
+	rcu_read_unlock();
 	port->dev->stats.tx_dropped++;
 	kfree_skb(skb);
 }
diff --git a/kernel/net/hsr/hsr_framereg.c b/kernel/net/hsr/hsr_framereg.c
index 805f974..afc97d6 100644
--- a/kernel/net/hsr/hsr_framereg.c
+++ b/kernel/net/hsr/hsr_framereg.c
@@ -159,6 +159,7 @@
 		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 @@
 		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 @@
 		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);
@@ -377,7 +380,7 @@
 	node_dst = find_node_by_addr_A(&port->hsr->node_db,
 				       eth_hdr(skb)->h_dest);
 	if (!node_dst) {
-		if (net_ratelimit())
+		if (port->hsr->prot_version != PRP_V1 && net_ratelimit())
 			netdev_err(skb->dev, "%s: Unknown node\n", __func__);
 		return;
 	}
@@ -413,13 +416,17 @@
 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/kernel/net/hsr/hsr_framereg.h b/kernel/net/hsr/hsr_framereg.h
index d9628e7..5a771cb 100644
--- a/kernel/net/hsr/hsr_framereg.h
+++ b/kernel/net/hsr/hsr_framereg.h
@@ -69,6 +69,8 @@
 
 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 */
diff --git a/kernel/net/ipv4/af_inet.c b/kernel/net/ipv4/af_inet.c
index b9f4fe8..769902f 100644
--- a/kernel/net/ipv4/af_inet.c
+++ b/kernel/net/ipv4/af_inet.c
@@ -888,7 +888,7 @@
 		   EPOLLHUP, even on eg. unconnected UDP sockets -- RR */
 		fallthrough;
 	default:
-		sk->sk_shutdown |= how;
+		WRITE_ONCE(sk->sk_shutdown, sk->sk_shutdown | how);
 		if (sk->sk_prot->shutdown)
 			sk->sk_prot->shutdown(sk, how);
 		break;
diff --git a/kernel/net/ipv4/devinet.c b/kernel/net/ipv4/devinet.c
index 88b6120..da1ca80 100644
--- a/kernel/net/ipv4/devinet.c
+++ b/kernel/net/ipv4/devinet.c
@@ -351,14 +351,14 @@
 {
 	struct in_ifaddr *promote = NULL;
 	struct in_ifaddr *ifa, *ifa1;
-	struct in_ifaddr *last_prim;
+	struct in_ifaddr __rcu **last_prim;
 	struct in_ifaddr *prev_prom = NULL;
 	int do_promote = IN_DEV_PROMOTE_SECONDARIES(in_dev);
 
 	ASSERT_RTNL();
 
 	ifa1 = rtnl_dereference(*ifap);
-	last_prim = rtnl_dereference(in_dev->ifa_list);
+	last_prim = ifap;
 	if (in_dev->dead)
 		goto no_promotions;
 
@@ -372,7 +372,7 @@
 		while ((ifa = rtnl_dereference(*ifap1)) != NULL) {
 			if (!(ifa->ifa_flags & IFA_F_SECONDARY) &&
 			    ifa1->ifa_scope <= ifa->ifa_scope)
-				last_prim = ifa;
+				last_prim = &ifa->ifa_next;
 
 			if (!(ifa->ifa_flags & IFA_F_SECONDARY) ||
 			    ifa1->ifa_mask != ifa->ifa_mask ||
@@ -436,9 +436,9 @@
 
 			rcu_assign_pointer(prev_prom->ifa_next, next_sec);
 
-			last_sec = rtnl_dereference(last_prim->ifa_next);
+			last_sec = rtnl_dereference(*last_prim);
 			rcu_assign_pointer(promote->ifa_next, last_sec);
-			rcu_assign_pointer(last_prim->ifa_next, promote);
+			rcu_assign_pointer(*last_prim, promote);
 		}
 
 		promote->ifa_flags &= ~IFA_F_SECONDARY;
diff --git a/kernel/net/ipv4/esp4.c b/kernel/net/ipv4/esp4.c
index 7010faa..a16d177 100644
--- a/kernel/net/ipv4/esp4.c
+++ b/kernel/net/ipv4/esp4.c
@@ -1134,7 +1134,7 @@
 	err = crypto_aead_setkey(aead, key, keylen);
 
 free_key:
-	kfree(key);
+	kfree_sensitive(key);
 
 error:
 	return err;
diff --git a/kernel/net/ipv4/esp4_offload.c b/kernel/net/ipv4/esp4_offload.c
index 8425767..dc50764 100644
--- a/kernel/net/ipv4/esp4_offload.c
+++ b/kernel/net/ipv4/esp4_offload.c
@@ -338,6 +338,9 @@
 
 	secpath_reset(skb);
 
+	if (skb_needs_linearize(skb, skb->dev->features) &&
+	    __skb_linearize(skb))
+		return -ENOMEM;
 	return 0;
 }
 
diff --git a/kernel/net/ipv4/fib_frontend.c b/kernel/net/ipv4/fib_frontend.c
index 5f786ef..41f890b 100644
--- a/kernel/net/ipv4/fib_frontend.c
+++ b/kernel/net/ipv4/fib_frontend.c
@@ -573,6 +573,9 @@
 			cfg->fc_scope = RT_SCOPE_UNIVERSE;
 	}
 
+	if (!cfg->fc_table)
+		cfg->fc_table = RT_TABLE_MAIN;
+
 	if (cmd == SIOCDELRT)
 		return 0;
 
diff --git a/kernel/net/ipv4/fib_semantics.c b/kernel/net/ipv4/fib_semantics.c
index ab9fcc6..ed20d6a 100644
--- a/kernel/net/ipv4/fib_semantics.c
+++ b/kernel/net/ipv4/fib_semantics.c
@@ -30,6 +30,7 @@
 #include <linux/slab.h>
 #include <linux/netlink.h>
 #include <linux/hash.h>
+#include <linux/nospec.h>
 
 #include <net/arp.h>
 #include <net/ip.h>
@@ -277,7 +278,8 @@
 				hlist_del(&nexthop_nh->nh_hash);
 			} endfor_nexthops(fi)
 		}
-		fi->fib_dead = 1;
+		/* Paired with READ_ONCE() from fib_table_lookup() */
+		WRITE_ONCE(fi->fib_dead, 1);
 		fib_info_put(fi);
 	}
 	spin_unlock_bh(&fib_info_lock);
@@ -1021,6 +1023,7 @@
 		if (type > RTAX_MAX)
 			return false;
 
+		type = array_index_nospec(type, RTAX_MAX + 1);
 		if (type == RTAX_CC_ALGO) {
 			char tmp[TCP_CA_NAME_MAX];
 			bool ecn_ca = false;
@@ -1597,6 +1600,7 @@
 link_it:
 	ofi = fib_find_info(fi);
 	if (ofi) {
+		/* fib_table_lookup() should not see @fi yet. */
 		fi->fib_dead = 1;
 		free_fib_info(fi);
 		ofi->fib_treeref++;
@@ -1635,6 +1639,7 @@
 
 failure:
 	if (fi) {
+		/* fib_table_lookup() should not see @fi yet. */
 		fi->fib_dead = 1;
 		free_fib_info(fi);
 	}
diff --git a/kernel/net/ipv4/fib_trie.c b/kernel/net/ipv4/fib_trie.c
index d11fb16..456240d 100644
--- a/kernel/net/ipv4/fib_trie.c
+++ b/kernel/net/ipv4/fib_trie.c
@@ -1534,7 +1534,8 @@
 		}
 		if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos)
 			continue;
-		if (fi->fib_dead)
+		/* Paired with WRITE_ONCE() in fib_release_info() */
+		if (READ_ONCE(fi->fib_dead))
 			continue;
 		if (fa->fa_info->fib_scope < flp->flowi4_scope)
 			continue;
diff --git a/kernel/net/ipv4/icmp.c b/kernel/net/ipv4/icmp.c
index a1aacf5..0bbc047 100644
--- a/kernel/net/ipv4/icmp.c
+++ b/kernel/net/ipv4/icmp.c
@@ -755,6 +755,11 @@
 		room = 576;
 	room -= sizeof(struct iphdr) + icmp_param.replyopts.opt.opt.optlen;
 	room -= sizeof(struct icmphdr);
+	/* Guard against tiny mtu. We need to include at least one
+	 * IP network header for this message to make any sense.
+	 */
+	if (room <= (int)sizeof(struct iphdr))
+		goto ende;
 
 	icmp_param.data_len = skb_in->len - icmp_param.offset;
 	if (icmp_param.data_len > room)
diff --git a/kernel/net/ipv4/igmp.c b/kernel/net/ipv4/igmp.c
index 46196b5..b82b959 100644
--- a/kernel/net/ipv4/igmp.c
+++ b/kernel/net/ipv4/igmp.c
@@ -353,8 +353,9 @@
 	struct flowi4 fl4;
 	int hlen = LL_RESERVED_SPACE(dev);
 	int tlen = dev->needed_tailroom;
-	unsigned int size = mtu;
+	unsigned int size;
 
+	size = min(mtu, IP_MAX_MTU);
 	while (1) {
 		skb = alloc_skb(size + hlen + tlen,
 				GFP_ATOMIC | __GFP_NOWARN);
diff --git a/kernel/net/ipv4/inet_connection_sock.c b/kernel/net/ipv4/inet_connection_sock.c
index c4303cb..4fbc23e 100644
--- a/kernel/net/ipv4/inet_connection_sock.c
+++ b/kernel/net/ipv4/inet_connection_sock.c
@@ -147,10 +147,14 @@
 	 */
 
 	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 ||
@@ -912,11 +916,25 @@
 }
 EXPORT_SYMBOL(inet_csk_prepare_forced_close);
 
+static int inet_ulp_can_listen(const struct sock *sk)
+{
+	const struct inet_connection_sock *icsk = inet_csk(sk);
+
+	if (icsk->icsk_ulp_ops && !icsk->icsk_ulp_ops->clone)
+		return -EINVAL;
+
+	return 0;
+}
+
 int inet_csk_listen_start(struct sock *sk, int backlog)
 {
 	struct inet_connection_sock *icsk = inet_csk(sk);
 	struct inet_sock *inet = inet_sk(sk);
-	int err = -EADDRINUSE;
+	int err;
+
+	err = inet_ulp_can_listen(sk);
+	if (unlikely(err))
+		return err;
 
 	reqsk_queue_alloc(&icsk->icsk_accept_queue);
 
@@ -928,6 +946,7 @@
 	 * It is OK, because this socket enters to hash table only
 	 * after validation is complete.
 	 */
+	err = -EADDRINUSE;
 	inet_sk_state_store(sk, TCP_LISTEN);
 	if (!sk->sk_prot->get_port(sk, inet->inet_num)) {
 		inet->inet_sport = htons(inet->inet_num);
diff --git a/kernel/net/ipv4/inet_hashtables.c b/kernel/net/ipv4/inet_hashtables.c
index 2ec518c..5650565 100644
--- a/kernel/net/ipv4/inet_hashtables.c
+++ b/kernel/net/ipv4/inet_hashtables.c
@@ -747,17 +747,7 @@
 	u32 index;
 
 	if (port) {
-		head = &hinfo->bhash[inet_bhashfn(net, port,
-						  hinfo->bhash_size)];
-		tb = inet_csk(sk)->icsk_bind_hash;
-		spin_lock_bh(&head->lock);
-		if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
-			inet_ehash_nolisten(sk, NULL, NULL);
-			spin_unlock_bh(&head->lock);
-			return 0;
-		}
-		spin_unlock(&head->lock);
-		/* No definite answer... Walk to established hash table */
+		local_bh_disable();
 		ret = check_established(death_row, sk, port, NULL);
 		local_bh_enable();
 		return ret;
diff --git a/kernel/net/ipv4/ip_gre.c b/kernel/net/ipv4/ip_gre.c
index 65ead8a..9d1a506 100644
--- a/kernel/net/ipv4/ip_gre.c
+++ b/kernel/net/ipv4/ip_gre.c
@@ -547,7 +547,7 @@
 		truncate = true;
 	}
 
-	nhoff = skb_network_header(skb) - skb_mac_header(skb);
+	nhoff = skb_network_offset(skb);
 	if (skb->protocol == htons(ETH_P_IP) &&
 	    (ntohs(ip_hdr(skb)->tot_len) > skb->len - nhoff))
 		truncate = true;
@@ -556,7 +556,7 @@
 		int thoff;
 
 		if (skb_transport_header_was_set(skb))
-			thoff = skb_transport_header(skb) - skb_mac_header(skb);
+			thoff = skb_transport_offset(skb);
 		else
 			thoff = nhoff + sizeof(struct ipv6hdr);
 		if (ntohs(ipv6_hdr(skb)->payload_len) > skb->len - thoff)
diff --git a/kernel/net/ipv4/ip_input.c b/kernel/net/ipv4/ip_input.c
index f6b3237..c9add07 100644
--- a/kernel/net/ipv4/ip_input.c
+++ b/kernel/net/ipv4/ip_input.c
@@ -561,7 +561,8 @@
 static struct sk_buff *ip_extract_route_hint(const struct net *net,
 					     struct sk_buff *skb, int rt_type)
 {
-	if (fib4_has_custom_rules(net) || rt_type == RTN_BROADCAST)
+	if (fib4_has_custom_rules(net) || rt_type == RTN_BROADCAST ||
+	    IPCB(skb)->flags & IPSKB_MULTIPATH)
 		return NULL;
 
 	return skb;
diff --git a/kernel/net/ipv4/ip_output.c b/kernel/net/ipv4/ip_output.c
index 0dbf950..1580804 100644
--- a/kernel/net/ipv4/ip_output.c
+++ b/kernel/net/ipv4/ip_output.c
@@ -223,7 +223,7 @@
 	if (lwtunnel_xmit_redirect(dst->lwtstate)) {
 		int res = lwtunnel_xmit(skb);
 
-		if (res < 0 || res == LWTUNNEL_XMIT_DONE)
+		if (res != LWTUNNEL_XMIT_CONTINUE)
 			return res;
 	}
 
@@ -1564,9 +1564,19 @@
 	cork->dst = NULL;
 	skb_dst_set(skb, &rt->dst);
 
-	if (iph->protocol == IPPROTO_ICMP)
-		icmp_out_count(net, ((struct icmphdr *)
-			skb_transport_header(skb))->type);
+	if (iph->protocol == IPPROTO_ICMP) {
+		u8 icmp_type;
+
+		/* For such sockets, transhdrlen is zero when do ip_append_data(),
+		 * so icmphdr does not in skb linear region and can not get icmp_type
+		 * by icmp_hdr(skb)->type.
+		 */
+		if (sk->sk_type == SOCK_RAW && !inet_sk(sk)->hdrincl)
+			icmp_type = fl4->fl4_icmp_type;
+		else
+			icmp_type = icmp_hdr(skb)->type;
+		icmp_out_count(net, icmp_type);
+	}
 
 	ip_cork_release(cork);
 out:
diff --git a/kernel/net/ipv4/ip_sockglue.c b/kernel/net/ipv4/ip_sockglue.c
index 4cc39c6..1b35afd 100644
--- a/kernel/net/ipv4/ip_sockglue.c
+++ b/kernel/net/ipv4/ip_sockglue.c
@@ -317,7 +317,14 @@
 			ipc->tos = val;
 			ipc->priority = rt_tos2priority(ipc->tos);
 			break;
-
+		case IP_PROTOCOL:
+			if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
+				return -EINVAL;
+			val = *(int *)CMSG_DATA(cmsg);
+			if (val < 1 || val > 255)
+				return -EINVAL;
+			ipc->protocol = val;
+			break;
 		default:
 			return -EINVAL;
 		}
@@ -1724,6 +1731,9 @@
 	case IP_MINTTL:
 		val = inet->min_ttl;
 		break;
+	case IP_PROTOCOL:
+		val = inet_sk(sk)->inet_num;
+		break;
 	default:
 		release_sock(sk);
 		return -ENOPROTOOPT;
diff --git a/kernel/net/ipv4/ip_tunnel.c b/kernel/net/ipv4/ip_tunnel.c
index be75b40..99f70b9 100644
--- a/kernel/net/ipv4/ip_tunnel.c
+++ b/kernel/net/ipv4/ip_tunnel.c
@@ -613,10 +613,10 @@
 	}
 
 	headroom += LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len;
-	if (headroom > dev->needed_headroom)
-		dev->needed_headroom = headroom;
+	if (headroom > READ_ONCE(dev->needed_headroom))
+		WRITE_ONCE(dev->needed_headroom, headroom);
 
-	if (skb_cow_head(skb, dev->needed_headroom)) {
+	if (skb_cow_head(skb, READ_ONCE(dev->needed_headroom))) {
 		ip_rt_put(rt);
 		goto tx_dropped;
 	}
@@ -797,10 +797,10 @@
 
 	max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr)
 			+ rt->dst.header_len + ip_encap_hlen(&tunnel->encap);
-	if (max_headroom > dev->needed_headroom)
-		dev->needed_headroom = max_headroom;
+	if (max_headroom > READ_ONCE(dev->needed_headroom))
+		WRITE_ONCE(dev->needed_headroom, max_headroom);
 
-	if (skb_cow_head(skb, dev->needed_headroom)) {
+	if (skb_cow_head(skb, READ_ONCE(dev->needed_headroom))) {
 		ip_rt_put(rt);
 		dev->stats.tx_dropped++;
 		kfree_skb(skb);
diff --git a/kernel/net/ipv4/ip_tunnel_core.c b/kernel/net/ipv4/ip_tunnel_core.c
index 4b74c67..da9a55c 100644
--- a/kernel/net/ipv4/ip_tunnel_core.c
+++ b/kernel/net/ipv4/ip_tunnel_core.c
@@ -224,7 +224,7 @@
 		.un.frag.__unused	= 0,
 		.un.frag.mtu		= ntohs(mtu),
 	};
-	icmph->checksum = ip_compute_csum(icmph, len);
+	icmph->checksum = csum_fold(skb_checksum(skb, 0, len, 0));
 	skb_reset_transport_header(skb);
 
 	niph = skb_push(skb, sizeof(*niph));
diff --git a/kernel/net/ipv4/ip_vti.c b/kernel/net/ipv4/ip_vti.c
index 84a818b..90f349b 100644
--- a/kernel/net/ipv4/ip_vti.c
+++ b/kernel/net/ipv4/ip_vti.c
@@ -285,12 +285,12 @@
 
 	switch (skb->protocol) {
 	case htons(ETH_P_IP):
-		xfrm_decode_session(skb, &fl, AF_INET);
 		memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
+		xfrm_decode_session(skb, &fl, AF_INET);
 		break;
 	case htons(ETH_P_IPV6):
-		xfrm_decode_session(skb, &fl, AF_INET6);
 		memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
+		xfrm_decode_session(skb, &fl, AF_INET6);
 		break;
 	default:
 		goto tx_err;
diff --git a/kernel/net/ipv4/metrics.c b/kernel/net/ipv4/metrics.c
index 3205d5f..4966ac2 100644
--- a/kernel/net/ipv4/metrics.c
+++ b/kernel/net/ipv4/metrics.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 #include <linux/netlink.h>
+#include <linux/nospec.h>
 #include <linux/rtnetlink.h>
 #include <linux/types.h>
 #include <net/ip.h>
@@ -28,6 +29,7 @@
 			return -EINVAL;
 		}
 
+		type = array_index_nospec(type, RTAX_MAX + 1);
 		if (type == RTAX_CC_ALGO) {
 			char tmp[TCP_CA_NAME_MAX];
 
diff --git a/kernel/net/ipv4/netfilter/ip_tables.c b/kernel/net/ipv4/netfilter/ip_tables.c
index f77ea0d..ec98161 100644
--- a/kernel/net/ipv4/netfilter/ip_tables.c
+++ b/kernel/net/ipv4/netfilter/ip_tables.c
@@ -1044,7 +1044,6 @@
 	struct xt_counters *counters;
 	struct ipt_entry *iter;
 
-	ret = 0;
 	counters = xt_counters_alloc(num_counters);
 	if (!counters) {
 		ret = -ENOMEM;
@@ -1090,7 +1089,7 @@
 		net_warn_ratelimited("iptables: counters copy to user failed while replacing table\n");
 	}
 	vfree(counters);
-	return ret;
+	return 0;
 
  put_module:
 	module_put(t->me);
diff --git a/kernel/net/ipv4/netfilter/ipt_REJECT.c b/kernel/net/ipv4/netfilter/ipt_REJECT.c
index e16b98e..4b88407 100644
--- a/kernel/net/ipv4/netfilter/ipt_REJECT.c
+++ b/kernel/net/ipv4/netfilter/ipt_REJECT.c
@@ -56,7 +56,8 @@
 		nf_send_unreach(skb, ICMP_PKT_FILTERED, hook);
 		break;
 	case IPT_TCP_RESET:
-		nf_send_reset(xt_net(par), skb, hook);
+		nf_send_reset(xt_net(par), par->state->sk, skb, hook);
+		break;
 	case IPT_ICMP_ECHOREPLY:
 		/* Doesn't happen. */
 		break;
diff --git a/kernel/net/ipv4/netfilter/nf_reject_ipv4.c b/kernel/net/ipv4/netfilter/nf_reject_ipv4.c
index 93b0773..efe14a6 100644
--- a/kernel/net/ipv4/netfilter/nf_reject_ipv4.c
+++ b/kernel/net/ipv4/netfilter/nf_reject_ipv4.c
@@ -112,7 +112,8 @@
 }
 
 /* Send RST reply */
-void nf_send_reset(struct net *net, struct sk_buff *oldskb, int hook)
+void nf_send_reset(struct net *net, struct sock *sk, struct sk_buff *oldskb,
+		   int hook)
 {
 	struct net_device *br_indev __maybe_unused;
 	struct sk_buff *nskb;
@@ -144,8 +145,7 @@
 	niph = nf_reject_iphdr_put(nskb, oldskb, IPPROTO_TCP,
 				   ip4_dst_hoplimit(skb_dst(nskb)));
 	nf_reject_ip_tcphdr_put(nskb, oldskb, oth);
-
-	if (ip_route_me_harder(net, nskb->sk, nskb, RTN_UNSPEC))
+	if (ip_route_me_harder(net, sk, nskb, RTN_UNSPEC))
 		goto free_nskb;
 
 	niph = ip_hdr(nskb);
diff --git a/kernel/net/ipv4/netfilter/nf_tproxy_ipv4.c b/kernel/net/ipv4/netfilter/nf_tproxy_ipv4.c
index b2bae0b..61cb234 100644
--- a/kernel/net/ipv4/netfilter/nf_tproxy_ipv4.c
+++ b/kernel/net/ipv4/netfilter/nf_tproxy_ipv4.c
@@ -38,7 +38,7 @@
 					    hp->source, lport ? lport : hp->dest,
 					    skb->dev, NF_TPROXY_LOOKUP_LISTENER);
 		if (sk2) {
-			inet_twsk_deschedule_put(inet_twsk(sk));
+			nf_tproxy_twsk_deschedule_put(inet_twsk(sk));
 			sk = sk2;
 		}
 	}
diff --git a/kernel/net/ipv4/netfilter/nft_reject_ipv4.c b/kernel/net/ipv4/netfilter/nft_reject_ipv4.c
index e408f81..55fc23a 100644
--- a/kernel/net/ipv4/netfilter/nft_reject_ipv4.c
+++ b/kernel/net/ipv4/netfilter/nft_reject_ipv4.c
@@ -27,7 +27,8 @@
 		nf_send_unreach(pkt->skb, priv->icmp_code, nft_hook(pkt));
 		break;
 	case NFT_REJECT_TCP_RST:
-		nf_send_reset(nft_net(pkt), pkt->skb, nft_hook(pkt));
+		nf_send_reset(nft_net(pkt), nft_sk(pkt), pkt->skb,
+			      nft_hook(pkt));
 		break;
 	default:
 		break;
diff --git a/kernel/net/ipv4/raw.c b/kernel/net/ipv4/raw.c
index 4899ebe..650da4d 100644
--- a/kernel/net/ipv4/raw.c
+++ b/kernel/net/ipv4/raw.c
@@ -559,6 +559,9 @@
 	}
 
 	ipcm_init_sk(&ipc, inet);
+	/* Keep backward compat */
+	if (hdrincl)
+		ipc.protocol = IPPROTO_RAW;
 
 	if (msg->msg_controllen) {
 		err = ip_cmsg_send(sk, msg, &ipc, false);
@@ -626,7 +629,7 @@
 
 	flowi4_init_output(&fl4, ipc.oif, ipc.sockc.mark, tos,
 			   RT_SCOPE_UNIVERSE,
-			   hdrincl ? IPPROTO_RAW : sk->sk_protocol,
+			   hdrincl ? ipc.protocol : sk->sk_protocol,
 			   inet_sk_flowi_flags(sk) |
 			    (hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
 			   daddr, saddr, 0, 0, sk->sk_uid);
diff --git a/kernel/net/ipv4/route.c b/kernel/net/ipv4/route.c
index 216f76b..3159ad0 100644
--- a/kernel/net/ipv4/route.c
+++ b/kernel/net/ipv4/route.c
@@ -1240,6 +1240,7 @@
 
 static void ipv4_send_dest_unreach(struct sk_buff *skb)
 {
+	struct net_device *dev;
 	struct ip_options opt;
 	int res;
 
@@ -1257,7 +1258,8 @@
 		opt.optlen = ip_hdr(skb)->ihl * 4 - sizeof(struct iphdr);
 
 		rcu_read_lock();
-		res = __ip_options_compile(dev_net(skb->dev), &opt, skb, NULL);
+		dev = skb->dev ? skb->dev : skb_rtable(skb)->dst.dev;
+		res = __ip_options_compile(dev_net(dev), &opt, skb, NULL);
 		rcu_read_unlock();
 
 		if (res)
@@ -2058,6 +2060,7 @@
 		int h = fib_multipath_hash(res->fi->fib_net, NULL, skb, hkeys);
 
 		fib_select_multipath(res, h);
+		IPCB(skb)->flags |= IPSKB_MULTIPATH;
 	}
 #endif
 
diff --git a/kernel/net/ipv4/syncookies.c b/kernel/net/ipv4/syncookies.c
index 41afc91..542b667 100644
--- a/kernel/net/ipv4/syncookies.c
+++ b/kernel/net/ipv4/syncookies.c
@@ -290,12 +290,11 @@
 	struct tcp_request_sock *treq;
 	struct request_sock *req;
 
-#ifdef CONFIG_MPTCP
 	if (sk_is_mptcp(sk))
-		ops = &mptcp_subflow_request_sock_ops;
-#endif
+		req = mptcp_subflow_reqsk_alloc(ops, sk, false);
+	else
+		req = inet_reqsk_alloc(ops, sk, false);
 
-	req = inet_reqsk_alloc(ops, sk, false);
 	if (!req)
 		return NULL;
 
diff --git a/kernel/net/ipv4/sysctl_net_ipv4.c b/kernel/net/ipv4/sysctl_net_ipv4.c
index 070fd06..3e3542b 100644
--- a/kernel/net/ipv4/sysctl_net_ipv4.c
+++ b/kernel/net/ipv4/sysctl_net_ipv4.c
@@ -31,7 +31,6 @@
 static int two = 2;
 static int four = 4;
 static int thousand = 1000;
-static int gso_max_segs = GSO_MAX_SEGS;
 static int tcp_retr1_max = 255;
 static int ip_local_port_range_min[] = { 1, 1 };
 static int ip_local_port_range_max[] = { 65535, 65535 };
@@ -1197,7 +1196,6 @@
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
 		.extra1		= SYSCTL_ONE,
-		.extra2		= &gso_max_segs,
 	},
 	{
 		.procname	= "tcp_min_rtt_wlen",
diff --git a/kernel/net/ipv4/tcp.c b/kernel/net/ipv4/tcp.c
index 90c5e69..9e3ed6d 100644
--- a/kernel/net/ipv4/tcp.c
+++ b/kernel/net/ipv4/tcp.c
@@ -434,6 +434,7 @@
 
 	/* There's a bubble in the pipe until at least the first ACK. */
 	tp->app_limited = ~0U;
+	tp->rate_app_limited = 1;
 
 	/* See draft-stevens-tcpca-spec-01 for discussion of the
 	 * initialization of these values.
@@ -507,6 +508,7 @@
 	__poll_t mask;
 	struct sock *sk = sock->sk;
 	const struct tcp_sock *tp = tcp_sk(sk);
+	u8 shutdown;
 	int state;
 
 	sock_poll_wait(file, sock, wait);
@@ -549,9 +551,10 @@
 	 * NOTE. Check for TCP_CLOSE is added. The goal is to prevent
 	 * blocking on fresh not-connected or disconnected socket. --ANK
 	 */
-	if (sk->sk_shutdown == SHUTDOWN_MASK || state == TCP_CLOSE)
+	shutdown = READ_ONCE(sk->sk_shutdown);
+	if (shutdown == SHUTDOWN_MASK || state == TCP_CLOSE)
 		mask |= EPOLLHUP;
-	if (sk->sk_shutdown & RCV_SHUTDOWN)
+	if (shutdown & RCV_SHUTDOWN)
 		mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
 
 	/* Connected or passive Fast Open socket? */
@@ -567,7 +570,7 @@
 		if (tcp_stream_is_readable(tp, target, sk))
 			mask |= EPOLLIN | EPOLLRDNORM;
 
-		if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
+		if (!(shutdown & SEND_SHUTDOWN)) {
 			if (__sk_stream_is_writeable(sk, 1)) {
 				mask |= EPOLLOUT | EPOLLWRNORM;
 			} else {  /* send SIGIO later */
@@ -2488,14 +2491,13 @@
 	return too_many_orphans || out_of_socket_memory;
 }
 
-void tcp_close(struct sock *sk, long timeout)
+void __tcp_close(struct sock *sk, long timeout)
 {
 	struct sk_buff *skb;
 	int data_was_unread = 0;
 	int state;
 
-	lock_sock(sk);
-	sk->sk_shutdown = SHUTDOWN_MASK;
+	WRITE_ONCE(sk->sk_shutdown, SHUTDOWN_MASK);
 
 	if (sk->sk_state == TCP_LISTEN) {
 		tcp_set_state(sk, TCP_CLOSE);
@@ -2658,6 +2660,12 @@
 out:
 	bh_unlock_sock(sk);
 	local_bh_enable();
+}
+
+void tcp_close(struct sock *sk, long timeout)
+{
+	lock_sock(sk);
+	__tcp_close(sk, timeout);
 	release_sock(sk);
 	sock_put(sk);
 }
@@ -2755,7 +2763,7 @@
 	if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
 		inet_reset_saddr(sk);
 
-	sk->sk_shutdown = 0;
+	WRITE_ONCE(sk->sk_shutdown, 0);
 	sock_reset_flag(sk, SOCK_DONE);
 	tp->srtt_us = 0;
 	tp->mdev_us = jiffies_to_usecs(TCP_TIMEOUT_INIT);
@@ -2816,6 +2824,7 @@
 	tp->last_oow_ack_time = 0;
 	/* There's a bubble in the pipe until at least the first ACK. */
 	tp->app_limited = ~0U;
+	tp->rate_app_limited = 1;
 	tp->rack.mstamp = 0;
 	tp->rack.advanced = 0;
 	tp->rack.reo_wnd_steps = 1;
@@ -3045,7 +3054,7 @@
 void tcp_sock_set_user_timeout(struct sock *sk, u32 val)
 {
 	lock_sock(sk);
-	inet_csk(sk)->icsk_user_timeout = val;
+	WRITE_ONCE(inet_csk(sk)->icsk_user_timeout, val);
 	release_sock(sk);
 }
 EXPORT_SYMBOL(tcp_sock_set_user_timeout);
@@ -3057,7 +3066,8 @@
 	if (val < 1 || val > MAX_TCP_KEEPIDLE)
 		return -EINVAL;
 
-	tp->keepalive_time = val * HZ;
+	/* Paired with WRITE_ONCE() in keepalive_time_when() */
+	WRITE_ONCE(tp->keepalive_time, val * HZ);
 	if (sock_flag(sk, SOCK_KEEPOPEN) &&
 	    !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) {
 		u32 elapsed = keepalive_time_elapsed(tp);
@@ -3089,7 +3099,7 @@
 		return -EINVAL;
 
 	lock_sock(sk);
-	tcp_sk(sk)->keepalive_intvl = val * HZ;
+	WRITE_ONCE(tcp_sk(sk)->keepalive_intvl, val * HZ);
 	release_sock(sk);
 	return 0;
 }
@@ -3101,7 +3111,8 @@
 		return -EINVAL;
 
 	lock_sock(sk);
-	tcp_sk(sk)->keepalive_probes = val;
+	/* Paired with READ_ONCE() in keepalive_probes() */
+	WRITE_ONCE(tcp_sk(sk)->keepalive_probes, val);
 	release_sock(sk);
 	return 0;
 }
@@ -3287,13 +3298,13 @@
 		if (val < 1 || val > MAX_TCP_KEEPINTVL)
 			err = -EINVAL;
 		else
-			tp->keepalive_intvl = val * HZ;
+			WRITE_ONCE(tp->keepalive_intvl, val * HZ);
 		break;
 	case TCP_KEEPCNT:
 		if (val < 1 || val > MAX_TCP_KEEPCNT)
 			err = -EINVAL;
 		else
-			tp->keepalive_probes = val;
+			WRITE_ONCE(tp->keepalive_probes, val);
 		break;
 	case TCP_SYNCNT:
 		if (val < 1 || val > MAX_TCP_SYNCNT)
@@ -3312,18 +3323,18 @@
 
 	case TCP_LINGER2:
 		if (val < 0)
-			tp->linger2 = -1;
+			WRITE_ONCE(tp->linger2, -1);
 		else if (val > TCP_FIN_TIMEOUT_MAX / HZ)
-			tp->linger2 = TCP_FIN_TIMEOUT_MAX;
+			WRITE_ONCE(tp->linger2, TCP_FIN_TIMEOUT_MAX);
 		else
-			tp->linger2 = val * HZ;
+			WRITE_ONCE(tp->linger2, val * HZ);
 		break;
 
 	case TCP_DEFER_ACCEPT:
 		/* Translate value in seconds to number of retransmits */
-		icsk->icsk_accept_queue.rskq_defer_accept =
-			secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ,
-					TCP_RTO_MAX / HZ);
+		WRITE_ONCE(icsk->icsk_accept_queue.rskq_defer_accept,
+			   secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ,
+					   TCP_RTO_MAX / HZ));
 		break;
 
 	case TCP_WINDOW_CLAMP:
@@ -3355,7 +3366,7 @@
 		if (val < 0)
 			err = -EINVAL;
 		else
-			icsk->icsk_user_timeout = val;
+			WRITE_ONCE(icsk->icsk_user_timeout, val);
 		break;
 
 	case TCP_FASTOPEN:
@@ -3399,7 +3410,7 @@
 		err = tcp_repair_set_window(tp, optval, optlen);
 		break;
 	case TCP_NOTSENT_LOWAT:
-		tp->notsent_lowat = val;
+		WRITE_ONCE(tp->notsent_lowat, val);
 		sk->sk_write_space(sk);
 		break;
 	case TCP_INQ:
@@ -3411,7 +3422,7 @@
 	case TCP_TX_DELAY:
 		if (val)
 			tcp_enable_tx_delay();
-		tp->tcp_tx_delay = val;
+		WRITE_ONCE(tp->tcp_tx_delay, val);
 		break;
 	default:
 		err = -ENOPROTOOPT;
@@ -3683,7 +3694,8 @@
 	switch (optname) {
 	case TCP_MAXSEG:
 		val = tp->mss_cache;
-		if (!val && ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)))
+		if (tp->rx_opt.user_mss &&
+		    ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)))
 			val = tp->rx_opt.user_mss;
 		if (tp->repair)
 			val = tp->rx_opt.mss_clamp;
@@ -3707,13 +3719,14 @@
 		val = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries;
 		break;
 	case TCP_LINGER2:
-		val = tp->linger2;
+		val = READ_ONCE(tp->linger2);
 		if (val >= 0)
 			val = (val ? : READ_ONCE(net->ipv4.sysctl_tcp_fin_timeout)) / HZ;
 		break;
 	case TCP_DEFER_ACCEPT:
-		val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept,
-				      TCP_TIMEOUT_INIT / HZ, TCP_RTO_MAX / HZ);
+		val = READ_ONCE(icsk->icsk_accept_queue.rskq_defer_accept);
+		val = retrans_to_secs(val, TCP_TIMEOUT_INIT / HZ,
+				      TCP_RTO_MAX / HZ);
 		break;
 	case TCP_WINDOW_CLAMP:
 		val = tp->window_clamp;
@@ -3849,11 +3862,11 @@
 		break;
 
 	case TCP_USER_TIMEOUT:
-		val = icsk->icsk_user_timeout;
+		val = READ_ONCE(icsk->icsk_user_timeout);
 		break;
 
 	case TCP_FASTOPEN:
-		val = icsk->icsk_accept_queue.fastopenq.max_qlen;
+		val = READ_ONCE(icsk->icsk_accept_queue.fastopenq.max_qlen);
 		break;
 
 	case TCP_FASTOPEN_CONNECT:
@@ -3865,14 +3878,14 @@
 		break;
 
 	case TCP_TX_DELAY:
-		val = tp->tcp_tx_delay;
+		val = READ_ONCE(tp->tcp_tx_delay);
 		break;
 
 	case TCP_TIMESTAMP:
 		val = tcp_time_stamp_raw() + tp->tsoffset;
 		break;
 	case TCP_NOTSENT_LOWAT:
-		val = tp->notsent_lowat;
+		val = READ_ONCE(tp->notsent_lowat);
 		break;
 	case TCP_INQ:
 		val = tp->recvmsg_inq;
@@ -4141,7 +4154,7 @@
 	if (req)
 		reqsk_fastopen_remove(sk, req, false);
 
-	sk->sk_shutdown = SHUTDOWN_MASK;
+	WRITE_ONCE(sk->sk_shutdown, SHUTDOWN_MASK);
 
 	if (!sock_flag(sk, SOCK_DEAD))
 		sk->sk_state_change(sk);
diff --git a/kernel/net/ipv4/tcp_bpf.c b/kernel/net/ipv4/tcp_bpf.c
index 809ee0f..d0ca1fc 100644
--- a/kernel/net/ipv4/tcp_bpf.c
+++ b/kernel/net/ipv4/tcp_bpf.c
@@ -6,6 +6,7 @@
 #include <linux/bpf.h>
 #include <linux/init.h>
 #include <linux/wait.h>
+#include <linux/util_macros.h>
 
 #include <net/inet_common.h>
 #include <net/tls.h>
@@ -125,8 +126,11 @@
 		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);
 
@@ -258,7 +262,7 @@
 	sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
 	ret = sk_wait_event(sk, &timeo,
 			    !list_empty(&psock->ingress_msg) ||
-			    !skb_queue_empty(&sk->sk_receive_queue), &wait);
+			    !skb_queue_empty_lockless(&sk->sk_receive_queue), &wait);
 	sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
 	remove_wait_queue(sk_sleep(sk), &wait);
 	return ret;
@@ -316,7 +320,7 @@
 	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 +351,7 @@
 	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:
@@ -638,10 +643,9 @@
  */
 void tcp_bpf_clone(const struct sock *sk, struct sock *newsk)
 {
-	int family = sk->sk_family == AF_INET6 ? TCP_BPF_IPV6 : TCP_BPF_IPV4;
 	struct proto *prot = newsk->sk_prot;
 
-	if (prot == &tcp_bpf_prots[family][TCP_BPF_BASE])
+	if (is_insidevar(prot, tcp_bpf_prots))
 		newsk->sk_prot = sk->sk_prot_creator;
 }
 #endif /* CONFIG_BPF_STREAM_PARSER */
diff --git a/kernel/net/ipv4/tcp_fastopen.c b/kernel/net/ipv4/tcp_fastopen.c
index 39fb037..92d63cf 100644
--- a/kernel/net/ipv4/tcp_fastopen.c
+++ b/kernel/net/ipv4/tcp_fastopen.c
@@ -312,6 +312,7 @@
 static bool tcp_fastopen_queue_check(struct sock *sk)
 {
 	struct fastopen_queue *fastopenq;
+	int max_qlen;
 
 	/* Make sure the listener has enabled fastopen, and we don't
 	 * exceed the max # of pending TFO requests allowed before trying
@@ -324,10 +325,11 @@
 	 * temporarily vs a server not supporting Fast Open at all.
 	 */
 	fastopenq = &inet_csk(sk)->icsk_accept_queue.fastopenq;
-	if (fastopenq->max_qlen == 0)
+	max_qlen = READ_ONCE(fastopenq->max_qlen);
+	if (max_qlen == 0)
 		return false;
 
-	if (fastopenq->qlen >= fastopenq->max_qlen) {
+	if (fastopenq->qlen >= max_qlen) {
 		struct request_sock *req1;
 		spin_lock(&fastopenq->lock);
 		req1 = fastopenq->rskq_rst_head;
diff --git a/kernel/net/ipv4/tcp_input.c b/kernel/net/ipv4/tcp_input.c
index 4a3926c..46836e4 100644
--- a/kernel/net/ipv4/tcp_input.c
+++ b/kernel/net/ipv4/tcp_input.c
@@ -243,6 +243,19 @@
 		if (unlikely(len > icsk->icsk_ack.rcv_mss +
 				   MAX_TCP_OPTION_SPACE))
 			tcp_gro_dev_warn(sk, skb, len);
+		/* If the skb has a len of exactly 1*MSS and has the PSH bit
+		 * set then it is likely the end of an application write. So
+		 * more data may not be arriving soon, and yet the data sender
+		 * may be waiting for an ACK if cwnd-bound or using TX zero
+		 * copy. So we set ICSK_ACK_PUSHED here so that
+		 * tcp_cleanup_rbuf() will send an ACK immediately if the app
+		 * reads all of the data and is not ping-pong. If len > MSS
+		 * then this logic does not matter (and does not hurt) because
+		 * tcp_cleanup_rbuf() will always ACK immediately if the app
+		 * reads data and there is more than an MSS of unACKed data.
+		 */
+		if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_PSH)
+			icsk->icsk_ack.pending |= ICSK_ACK_PUSHED;
 	} else {
 		/* Otherwise, we make more careful check taking into account,
 		 * that SACKs block is variable.
@@ -287,7 +300,7 @@
 		icsk->icsk_ack.quick = quickacks;
 }
 
-void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks)
+static void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks)
 {
 	struct inet_connection_sock *icsk = inet_csk(sk);
 
@@ -295,7 +308,6 @@
 	inet_csk_exit_pingpong_mode(sk);
 	icsk->icsk_ack.ato = TCP_ATO_MIN;
 }
-EXPORT_SYMBOL(tcp_enter_quickack_mode);
 
 /* Send ACKs quickly, if "quick" count is not exhausted
  * and the session is not interactive.
@@ -3561,8 +3573,11 @@
 static bool __tcp_oow_rate_limited(struct net *net, int mib_idx,
 				   u32 *last_oow_ack_time)
 {
-	if (*last_oow_ack_time) {
-		s32 elapsed = (s32)(tcp_jiffies32 - *last_oow_ack_time);
+	/* Paired with the WRITE_ONCE() in this function. */
+	u32 val = READ_ONCE(*last_oow_ack_time);
+
+	if (val) {
+		s32 elapsed = (s32)(tcp_jiffies32 - val);
 
 		if (0 <= elapsed &&
 		    elapsed < READ_ONCE(net->ipv4.sysctl_tcp_invalid_ratelimit)) {
@@ -3571,7 +3586,10 @@
 		}
 	}
 
-	*last_oow_ack_time = tcp_jiffies32;
+	/* Paired with the prior READ_ONCE() and with itself,
+	 * as we might be lockless.
+	 */
+	WRITE_ONCE(*last_oow_ack_time, tcp_jiffies32);
 
 	return false;	/* not rate-limited: go ahead, send dupack now! */
 }
@@ -4324,7 +4342,7 @@
 
 	inet_csk_schedule_ack(sk);
 
-	sk->sk_shutdown |= RCV_SHUTDOWN;
+	WRITE_ONCE(sk->sk_shutdown, sk->sk_shutdown | RCV_SHUTDOWN);
 	sock_set_flag(sk, SOCK_DONE);
 
 	switch (sk->sk_state) {
@@ -6506,7 +6524,7 @@
 			break;
 
 		tcp_set_state(sk, TCP_FIN_WAIT2);
-		sk->sk_shutdown |= SEND_SHUTDOWN;
+		WRITE_ONCE(sk->sk_shutdown, sk->sk_shutdown | SEND_SHUTDOWN);
 
 		sk_dst_confirm(sk);
 
diff --git a/kernel/net/ipv4/tcp_ipv4.c b/kernel/net/ipv4/tcp_ipv4.c
index 8bd7b1e..45939b6 100644
--- a/kernel/net/ipv4/tcp_ipv4.c
+++ b/kernel/net/ipv4/tcp_ipv4.c
@@ -951,7 +951,7 @@
 			tcp_rsk(req)->rcv_nxt,
 			req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale,
 			tcp_time_stamp_raw() + tcp_rsk(req)->ts_off,
-			req->ts_recent,
+			READ_ONCE(req->ts_recent),
 			0,
 			tcp_md5_do_lookup(sk, l3index, addr, AF_INET),
 			inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0,
diff --git a/kernel/net/ipv4/tcp_metrics.c b/kernel/net/ipv4/tcp_metrics.c
index f3ca6ee..a707fa1 100644
--- a/kernel/net/ipv4/tcp_metrics.c
+++ b/kernel/net/ipv4/tcp_metrics.c
@@ -40,7 +40,7 @@
 
 struct tcp_metrics_block {
 	struct tcp_metrics_block __rcu	*tcpm_next;
-	possible_net_t			tcpm_net;
+	struct net			*tcpm_net;
 	struct inetpeer_addr		tcpm_saddr;
 	struct inetpeer_addr		tcpm_daddr;
 	unsigned long			tcpm_stamp;
@@ -51,34 +51,38 @@
 	struct rcu_head			rcu_head;
 };
 
-static inline struct net *tm_net(struct tcp_metrics_block *tm)
+static inline struct net *tm_net(const struct tcp_metrics_block *tm)
 {
-	return read_pnet(&tm->tcpm_net);
+	/* Paired with the WRITE_ONCE() in tcpm_new() */
+	return READ_ONCE(tm->tcpm_net);
 }
 
 static bool tcp_metric_locked(struct tcp_metrics_block *tm,
 			      enum tcp_metric_index idx)
 {
-	return tm->tcpm_lock & (1 << idx);
+	/* Paired with WRITE_ONCE() in tcpm_suck_dst() */
+	return READ_ONCE(tm->tcpm_lock) & (1 << idx);
 }
 
-static u32 tcp_metric_get(struct tcp_metrics_block *tm,
+static u32 tcp_metric_get(const struct tcp_metrics_block *tm,
 			  enum tcp_metric_index idx)
 {
-	return tm->tcpm_vals[idx];
+	/* Paired with WRITE_ONCE() in tcp_metric_set() */
+	return READ_ONCE(tm->tcpm_vals[idx]);
 }
 
 static void tcp_metric_set(struct tcp_metrics_block *tm,
 			   enum tcp_metric_index idx,
 			   u32 val)
 {
-	tm->tcpm_vals[idx] = val;
+	/* Paired with READ_ONCE() in tcp_metric_get() */
+	WRITE_ONCE(tm->tcpm_vals[idx], val);
 }
 
 static bool addr_same(const struct inetpeer_addr *a,
 		      const struct inetpeer_addr *b)
 {
-	return inetpeer_addr_cmp(a, b) == 0;
+	return (a->family == b->family) && !inetpeer_addr_cmp(a, b);
 }
 
 struct tcpm_hash_bucket {
@@ -89,6 +93,7 @@
 static unsigned int		tcp_metrics_hash_log __read_mostly;
 
 static DEFINE_SPINLOCK(tcp_metrics_lock);
+static DEFINE_SEQLOCK(fastopen_seqlock);
 
 static void tcpm_suck_dst(struct tcp_metrics_block *tm,
 			  const struct dst_entry *dst,
@@ -97,7 +102,7 @@
 	u32 msval;
 	u32 val;
 
-	tm->tcpm_stamp = jiffies;
+	WRITE_ONCE(tm->tcpm_stamp, jiffies);
 
 	val = 0;
 	if (dst_metric_locked(dst, RTAX_RTT))
@@ -110,30 +115,42 @@
 		val |= 1 << TCP_METRIC_CWND;
 	if (dst_metric_locked(dst, RTAX_REORDERING))
 		val |= 1 << TCP_METRIC_REORDERING;
-	tm->tcpm_lock = val;
+	/* Paired with READ_ONCE() in tcp_metric_locked() */
+	WRITE_ONCE(tm->tcpm_lock, val);
 
 	msval = dst_metric_raw(dst, RTAX_RTT);
-	tm->tcpm_vals[TCP_METRIC_RTT] = msval * USEC_PER_MSEC;
+	tcp_metric_set(tm, TCP_METRIC_RTT, msval * USEC_PER_MSEC);
 
 	msval = dst_metric_raw(dst, RTAX_RTTVAR);
-	tm->tcpm_vals[TCP_METRIC_RTTVAR] = msval * USEC_PER_MSEC;
-	tm->tcpm_vals[TCP_METRIC_SSTHRESH] = dst_metric_raw(dst, RTAX_SSTHRESH);
-	tm->tcpm_vals[TCP_METRIC_CWND] = dst_metric_raw(dst, RTAX_CWND);
-	tm->tcpm_vals[TCP_METRIC_REORDERING] = dst_metric_raw(dst, RTAX_REORDERING);
+	tcp_metric_set(tm, TCP_METRIC_RTTVAR, msval * USEC_PER_MSEC);
+	tcp_metric_set(tm, TCP_METRIC_SSTHRESH,
+		       dst_metric_raw(dst, RTAX_SSTHRESH));
+	tcp_metric_set(tm, TCP_METRIC_CWND,
+		       dst_metric_raw(dst, RTAX_CWND));
+	tcp_metric_set(tm, TCP_METRIC_REORDERING,
+		       dst_metric_raw(dst, RTAX_REORDERING));
 	if (fastopen_clear) {
+		write_seqlock(&fastopen_seqlock);
 		tm->tcpm_fastopen.mss = 0;
 		tm->tcpm_fastopen.syn_loss = 0;
 		tm->tcpm_fastopen.try_exp = 0;
 		tm->tcpm_fastopen.cookie.exp = false;
 		tm->tcpm_fastopen.cookie.len = 0;
+		write_sequnlock(&fastopen_seqlock);
 	}
 }
 
 #define TCP_METRICS_TIMEOUT		(60 * 60 * HZ)
 
-static void tcpm_check_stamp(struct tcp_metrics_block *tm, struct dst_entry *dst)
+static void tcpm_check_stamp(struct tcp_metrics_block *tm,
+			     const struct dst_entry *dst)
 {
-	if (tm && unlikely(time_after(jiffies, tm->tcpm_stamp + TCP_METRICS_TIMEOUT)))
+	unsigned long limit;
+
+	if (!tm)
+		return;
+	limit = READ_ONCE(tm->tcpm_stamp) + TCP_METRICS_TIMEOUT;
+	if (unlikely(time_after(jiffies, limit)))
 		tcpm_suck_dst(tm, dst, false);
 }
 
@@ -174,20 +191,23 @@
 		oldest = deref_locked(tcp_metrics_hash[hash].chain);
 		for (tm = deref_locked(oldest->tcpm_next); tm;
 		     tm = deref_locked(tm->tcpm_next)) {
-			if (time_before(tm->tcpm_stamp, oldest->tcpm_stamp))
+			if (time_before(READ_ONCE(tm->tcpm_stamp),
+					READ_ONCE(oldest->tcpm_stamp)))
 				oldest = tm;
 		}
 		tm = oldest;
 	} else {
-		tm = kmalloc(sizeof(*tm), GFP_ATOMIC);
+		tm = kzalloc(sizeof(*tm), GFP_ATOMIC);
 		if (!tm)
 			goto out_unlock;
 	}
-	write_pnet(&tm->tcpm_net, net);
+	/* Paired with the READ_ONCE() in tm_net() */
+	WRITE_ONCE(tm->tcpm_net, net);
+
 	tm->tcpm_saddr = *saddr;
 	tm->tcpm_daddr = *daddr;
 
-	tcpm_suck_dst(tm, dst, true);
+	tcpm_suck_dst(tm, dst, reclaim);
 
 	if (likely(!reclaim)) {
 		tm->tcpm_next = tcp_metrics_hash[hash].chain;
@@ -434,7 +454,7 @@
 					       tp->reordering);
 		}
 	}
-	tm->tcpm_stamp = jiffies;
+	WRITE_ONCE(tm->tcpm_stamp, jiffies);
 out_unlock:
 	rcu_read_unlock();
 }
@@ -538,8 +558,6 @@
 
 	return ret;
 }
-
-static DEFINE_SEQLOCK(fastopen_seqlock);
 
 void tcp_fastopen_cache_get(struct sock *sk, u16 *mss,
 			    struct tcp_fastopen_cookie *cookie)
@@ -647,7 +665,7 @@
 	}
 
 	if (nla_put_msecs(msg, TCP_METRICS_ATTR_AGE,
-			  jiffies - tm->tcpm_stamp,
+			  jiffies - READ_ONCE(tm->tcpm_stamp),
 			  TCP_METRICS_ATTR_PAD) < 0)
 		goto nla_put_failure;
 
@@ -658,7 +676,7 @@
 		if (!nest)
 			goto nla_put_failure;
 		for (i = 0; i < TCP_METRIC_MAX_KERNEL + 1; i++) {
-			u32 val = tm->tcpm_vals[i];
+			u32 val = tcp_metric_get(tm, i);
 
 			if (!val)
 				continue;
diff --git a/kernel/net/ipv4/tcp_minisocks.c b/kernel/net/ipv4/tcp_minisocks.c
index e423123..01e2762 100644
--- a/kernel/net/ipv4/tcp_minisocks.c
+++ b/kernel/net/ipv4/tcp_minisocks.c
@@ -523,7 +523,7 @@
 	newtp->max_window = newtp->snd_wnd;
 
 	if (newtp->rx_opt.tstamp_ok) {
-		newtp->rx_opt.ts_recent = req->ts_recent;
+		newtp->rx_opt.ts_recent = READ_ONCE(req->ts_recent);
 		newtp->rx_opt.ts_recent_stamp = ktime_get_seconds();
 		newtp->tcp_header_len = sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED;
 	} else {
@@ -565,6 +565,9 @@
  * validation and inside tcp_v4_reqsk_send_ack(). Can we do better?
  *
  * We don't need to initialize tmp_opt.sack_ok as we don't use the results
+ *
+ * Note: If @fastopen is true, this can be called from process context.
+ *       Otherwise, this is from BH context.
  */
 
 struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
@@ -583,7 +586,7 @@
 		tcp_parse_options(sock_net(sk), skb, &tmp_opt, 0, NULL);
 
 		if (tmp_opt.saw_tstamp) {
-			tmp_opt.ts_recent = req->ts_recent;
+			tmp_opt.ts_recent = READ_ONCE(req->ts_recent);
 			if (tmp_opt.rcv_tsecr)
 				tmp_opt.rcv_tsecr -= tcp_rsk(req)->ts_off;
 			/* We do not store true stamp, but it is not required,
@@ -717,14 +720,17 @@
 					  &tcp_rsk(req)->last_oow_ack_time))
 			req->rsk_ops->send_ack(sk, skb, req);
 		if (paws_reject)
-			__NET_INC_STATS(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED);
+			NET_INC_STATS(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED);
 		return NULL;
 	}
 
 	/* In sequence, PAWS is OK. */
 
+	/* TODO: We probably should defer ts_recent change once
+	 * we take ownership of @req.
+	 */
 	if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_nxt))
-		req->ts_recent = tmp_opt.rcv_tsval;
+		WRITE_ONCE(req->ts_recent, tmp_opt.rcv_tsval);
 
 	if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) {
 		/* Truncate SYN, it is out of window starting
@@ -736,7 +742,7 @@
 	 *	   "fourth, check the SYN bit"
 	 */
 	if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) {
-		__TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS);
+		TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS);
 		goto embryonic_reset;
 	}
 
diff --git a/kernel/net/ipv4/tcp_output.c b/kernel/net/ipv4/tcp_output.c
index e5f8c8d..c2b1657 100644
--- a/kernel/net/ipv4/tcp_output.c
+++ b/kernel/net/ipv4/tcp_output.c
@@ -177,8 +177,7 @@
 }
 
 /* Account for an ACK we sent. */
-static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts,
-				      u32 rcv_nxt)
+static inline void tcp_event_ack_sent(struct sock *sk, u32 rcv_nxt)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 
@@ -192,7 +191,7 @@
 
 	if (unlikely(rcv_nxt != tp->rcv_nxt))
 		return;  /* Special ACK sent by DCTCP to reflect ECN */
-	tcp_dec_quickack_mode(sk, pkts);
+	tcp_dec_quickack_mode(sk);
 	inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
 }
 
@@ -874,7 +873,7 @@
 	if (likely(ireq->tstamp_ok)) {
 		opts->options |= OPTION_TS;
 		opts->tsval = tcp_skb_timestamp(skb) + tcp_rsk(req)->ts_off;
-		opts->tsecr = req->ts_recent;
+		opts->tsecr = READ_ONCE(req->ts_recent);
 		remaining -= TCPOLEN_TSTAMP_ALIGNED;
 	}
 	if (likely(ireq->sack_ok)) {
@@ -1374,7 +1373,7 @@
 			   sk, skb);
 
 	if (likely(tcb->tcp_flags & TCPHDR_ACK))
-		tcp_event_ack_sent(sk, tcp_skb_pcount(skb), rcv_nxt);
+		tcp_event_ack_sent(sk, rcv_nxt);
 
 	if (skb->len != tcp_header_size) {
 		tcp_event_data_sent(tp, sk);
@@ -3609,7 +3608,7 @@
 	th->window = htons(min(req->rsk_rcv_wnd, 65535U));
 	tcp_options_write((__be32 *)(th + 1), NULL, &opts);
 	th->doff = (tcp_header_size >> 2);
-	__TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS);
+	TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS);
 
 #ifdef CONFIG_TCP_MD5SIG
 	/* Okay, we have all we need - do the md5 hash if needed */
diff --git a/kernel/net/ipv4/tcp_timer.c b/kernel/net/ipv4/tcp_timer.c
index 888683f..3d01126 100644
--- a/kernel/net/ipv4/tcp_timer.c
+++ b/kernel/net/ipv4/tcp_timer.c
@@ -433,6 +433,22 @@
 			  TCP_TIMEOUT_INIT << req->num_timeout, TCP_RTO_MAX);
 }
 
+static bool tcp_rtx_probe0_timed_out(const struct sock *sk,
+				     const struct sk_buff *skb)
+{
+	const struct tcp_sock *tp = tcp_sk(sk);
+	const int timeout = TCP_RTO_MAX * 2;
+	u32 rcv_delta, rtx_delta;
+
+	rcv_delta = inet_csk(sk)->icsk_timeout - tp->rcv_tstamp;
+	if (rcv_delta <= timeout)
+		return false;
+
+	rtx_delta = (u32)msecs_to_jiffies(tcp_time_stamp(tp) -
+			(tp->retrans_stamp ?: tcp_skb_timestamp(skb)));
+
+	return rtx_delta > timeout;
+}
 
 /**
  *  tcp_retransmit_timer() - The TCP retransmit timeout handler
@@ -498,7 +514,7 @@
 					    tp->snd_una, tp->snd_nxt);
 		}
 #endif
-		if (tcp_jiffies32 - tp->rcv_tstamp > TCP_RTO_MAX) {
+		if (tcp_rtx_probe0_timed_out(sk, skb)) {
 			tcp_write_err(sk);
 			goto out;
 		}
@@ -578,7 +594,9 @@
 	    tcp_stream_is_thin(tp) &&
 	    icsk->icsk_retransmits <= TCP_THIN_LINEAR_RETRIES) {
 		icsk->icsk_backoff = 0;
-		icsk->icsk_rto = min(__tcp_set_rto(tp), TCP_RTO_MAX);
+		icsk->icsk_rto = clamp(__tcp_set_rto(tp),
+				       tcp_rto_min(sk),
+				       TCP_RTO_MAX);
 	} else {
 		/* Use normal (exponential) backoff */
 		icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX);
diff --git a/kernel/net/ipv4/tcp_ulp.c b/kernel/net/ipv4/tcp_ulp.c
index 7c27aa6..8e135af 100644
--- a/kernel/net/ipv4/tcp_ulp.c
+++ b/kernel/net/ipv4/tcp_ulp.c
@@ -136,6 +136,10 @@
 	if (icsk->icsk_ulp_ops)
 		goto out_err;
 
+	err = -ENOTCONN;
+	if (!ulp_ops->clone && sk->sk_state == TCP_LISTEN)
+		goto out_err;
+
 	err = ulp_ops->init(sk);
 	if (err)
 		goto out_err;
diff --git a/kernel/net/ipv4/udp.c b/kernel/net/ipv4/udp.c
index 3c1283c..22862b0 100644
--- a/kernel/net/ipv4/udp.c
+++ b/kernel/net/ipv4/udp.c
@@ -444,14 +444,24 @@
 		score = compute_score(sk, net, saddr, sport,
 				      daddr, hnum, dif, sdif);
 		if (score > badness) {
-			result = lookup_reuseport(net, sk, skb,
-						  saddr, sport, daddr, hnum);
+			badness = score;
+			result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum);
+			if (!result) {
+				result = sk;
+				continue;
+			}
+
 			/* Fall back to scoring if group has connections */
-			if (result && !reuseport_has_conns(sk))
+			if (!reuseport_has_conns(sk))
 				return result;
 
-			result = result ? : sk;
-			badness = score;
+			/* Reuseport logic returned an error, keep original score. */
+			if (IS_ERR(result))
+				continue;
+
+			badness = compute_score(result, net, saddr, sport,
+						daddr, hnum, dif, sdif);
+
 		}
 	}
 	return result;
@@ -1584,7 +1594,7 @@
 }
 EXPORT_SYMBOL_GPL(__udp_enqueue_schedule_skb);
 
-void udp_destruct_sock(struct sock *sk)
+void udp_destruct_common(struct sock *sk)
 {
 	/* reclaim completely the forward allocated memory */
 	struct udp_sock *up = udp_sk(sk);
@@ -1597,10 +1607,14 @@
 		kfree_skb(skb);
 	}
 	udp_rmem_release(sk, total, 0, true);
+}
+EXPORT_SYMBOL_GPL(udp_destruct_common);
 
+static void udp_destruct_sock(struct sock *sk)
+{
+	udp_destruct_common(sk);
 	inet_sock_destruct(sk);
 }
-EXPORT_SYMBOL_GPL(udp_destruct_sock);
 
 int udp_init_sock(struct sock *sk)
 {
@@ -1608,7 +1622,6 @@
 	sk->sk_destruct = udp_destruct_sock;
 	return 0;
 }
-EXPORT_SYMBOL_GPL(udp_init_sock);
 
 void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len)
 {
diff --git a/kernel/net/ipv4/udp_tunnel_core.c b/kernel/net/ipv4/udp_tunnel_core.c
index 3eecba0..d70f683 100644
--- a/kernel/net/ipv4/udp_tunnel_core.c
+++ b/kernel/net/ipv4/udp_tunnel_core.c
@@ -194,6 +194,7 @@
 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);
 }
diff --git a/kernel/net/ipv4/udplite.c b/kernel/net/ipv4/udplite.c
index bd8773b..edf82a4 100644
--- a/kernel/net/ipv4/udplite.c
+++ b/kernel/net/ipv4/udplite.c
@@ -17,6 +17,14 @@
 struct udp_table 	udplite_table __read_mostly;
 EXPORT_SYMBOL(udplite_table);
 
+/* Designate sk as UDP-Lite socket */
+static int udplite_sk_init(struct sock *sk)
+{
+	udp_init_sock(sk);
+	udp_sk(sk)->pcflag = UDPLITE_BIT;
+	return 0;
+}
+
 static int udplite_rcv(struct sk_buff *skb)
 {
 	return __udp4_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE);
@@ -54,6 +62,8 @@
 	.get_port	   = udp_v4_get_port,
 	.memory_allocated  = &udp_memory_allocated,
 	.sysctl_mem	   = sysctl_udp_mem,
+	.sysctl_wmem_offset = offsetof(struct net, ipv4.sysctl_udp_wmem_min),
+	.sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_udp_rmem_min),
 	.obj_size	   = sizeof(struct udp_sock),
 	.h.udp_table	   = &udplite_table,
 };
diff --git a/kernel/net/ipv4/xfrm4_input.c b/kernel/net/ipv4/xfrm4_input.c
index ad2afee..eac206a 100644
--- a/kernel/net/ipv4/xfrm4_input.c
+++ b/kernel/net/ipv4/xfrm4_input.c
@@ -164,6 +164,7 @@
 	kfree_skb(skb);
 	return 0;
 }
+EXPORT_SYMBOL(xfrm4_udp_encap_rcv);
 
 int xfrm4_rcv(struct sk_buff *skb)
 {
diff --git a/kernel/net/ipv6/addrconf.c b/kernel/net/ipv6/addrconf.c
index be75bf8..9fd77b2 100644
--- a/kernel/net/ipv6/addrconf.c
+++ b/kernel/net/ipv6/addrconf.c
@@ -318,9 +318,8 @@
 static void addrconf_mod_rs_timer(struct inet6_dev *idev,
 				  unsigned long when)
 {
-	if (!timer_pending(&idev->rs_timer))
+	if (!mod_timer(&idev->rs_timer, jiffies + when))
 		in6_dev_hold(idev);
-	mod_timer(&idev->rs_timer, jiffies + when);
 }
 
 static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp,
@@ -1364,7 +1363,7 @@
 	 * idev->desync_factor if it's larger
 	 */
 	cnf_temp_preferred_lft = READ_ONCE(idev->cnf.temp_prefered_lft);
-	max_desync_factor = min_t(__u32,
+	max_desync_factor = min_t(long,
 				  idev->cnf.max_desync_factor,
 				  cnf_temp_preferred_lft - regen_advance);
 
@@ -2580,12 +2579,18 @@
 			ipv6_ifa_notify(0, ift);
 	}
 
-	if ((create || list_empty(&idev->tempaddr_list)) &&
-	    idev->cnf.use_tempaddr > 0) {
+	/* Also create a temporary address if it's enabled but no temporary
+	 * address currently exists.
+	 * However, we get called with valid_lft == 0, prefered_lft == 0, create == false
+	 * as part of cleanup (ie. deleting the mngtmpaddr).
+	 * We don't want that to result in creating a new temporary ip address.
+	 */
+	if (list_empty(&idev->tempaddr_list) && (valid_lft || prefered_lft))
+		create = true;
+
+	if (create && idev->cnf.use_tempaddr > 0) {
 		/* When a new public address is created as described
 		 * in [ADDRCONF], also create a new temporary address.
-		 * Also create a temporary address if it's enabled but
-		 * no temporary address currently exists.
 		 */
 		read_unlock_bh(&idev->lock);
 		ipv6_create_tempaddr(ifp, false);
diff --git a/kernel/net/ipv6/af_inet6.c b/kernel/net/ipv6/af_inet6.c
index bf3dfe2..002f3da 100644
--- a/kernel/net/ipv6/af_inet6.c
+++ b/kernel/net/ipv6/af_inet6.c
@@ -107,6 +107,13 @@
 	return (struct ipv6_pinfo *)(((u8 *)sk) + offset);
 }
 
+void inet6_sock_destruct(struct sock *sk)
+{
+	inet6_cleanup_sock(sk);
+	inet_sock_destruct(sk);
+}
+EXPORT_SYMBOL_GPL(inet6_sock_destruct);
+
 static int inet6_create(struct net *net, struct socket *sock, int protocol,
 			int kern)
 {
@@ -199,7 +206,7 @@
 			inet->hdrincl = 1;
 	}
 
-	sk->sk_destruct		= inet_sock_destruct;
+	sk->sk_destruct		= inet6_sock_destruct;
 	sk->sk_family		= PF_INET6;
 	sk->sk_protocol		= protocol;
 
@@ -505,6 +512,12 @@
 }
 EXPORT_SYMBOL_GPL(inet6_destroy_sock);
 
+void inet6_cleanup_sock(struct sock *sk)
+{
+	inet6_destroy_sock(sk);
+}
+EXPORT_SYMBOL_GPL(inet6_cleanup_sock);
+
 /*
  *	This does both peername and sockname.
  */
diff --git a/kernel/net/ipv6/datagram.c b/kernel/net/ipv6/datagram.c
index f4559e5..a30ff5d 100644
--- a/kernel/net/ipv6/datagram.c
+++ b/kernel/net/ipv6/datagram.c
@@ -51,7 +51,7 @@
 	fl6->flowi6_mark = sk->sk_mark;
 	fl6->fl6_dport = inet->inet_dport;
 	fl6->fl6_sport = inet->inet_sport;
-	fl6->flowlabel = np->flow_label;
+	fl6->flowlabel = ip6_make_flowinfo(np->tclass, np->flow_label);
 	fl6->flowi6_uid = sk->sk_uid;
 
 	if (!fl6->flowi6_oif)
diff --git a/kernel/net/ipv6/esp6_offload.c b/kernel/net/ipv6/esp6_offload.c
index 7608be0..87dbd53 100644
--- a/kernel/net/ipv6/esp6_offload.c
+++ b/kernel/net/ipv6/esp6_offload.c
@@ -372,6 +372,9 @@
 
 	secpath_reset(skb);
 
+	if (skb_needs_linearize(skb, skb->dev->features) &&
+	    __skb_linearize(skb))
+		return -ENOMEM;
 	return 0;
 }
 
diff --git a/kernel/net/ipv6/exthdrs.c b/kernel/net/ipv6/exthdrs.c
index 4932dea..cdad901 100644
--- a/kernel/net/ipv6/exthdrs.c
+++ b/kernel/net/ipv6/exthdrs.c
@@ -552,24 +552,6 @@
 		return -1;
 	}
 
-	if (skb_cloned(skb)) {
-		if (pskb_expand_head(skb, IPV6_RPL_SRH_WORST_SWAP_SIZE, 0,
-				     GFP_ATOMIC)) {
-			__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
-					IPSTATS_MIB_OUTDISCARDS);
-			kfree_skb(skb);
-			return -1;
-		}
-	} else {
-		err = skb_cow_head(skb, IPV6_RPL_SRH_WORST_SWAP_SIZE);
-		if (unlikely(err)) {
-			kfree_skb(skb);
-			return -1;
-		}
-	}
-
-	hdr = (struct ipv6_rpl_sr_hdr *)skb_transport_header(skb);
-
 	if (!pskb_may_pull(skb, ipv6_rpl_srh_size(n, hdr->cmpri,
 						  hdr->cmpre))) {
 		kfree_skb(skb);
@@ -615,6 +597,17 @@
 	skb_pull(skb, ((hdr->hdrlen + 1) << 3));
 	skb_postpull_rcsum(skb, oldhdr,
 			   sizeof(struct ipv6hdr) + ((hdr->hdrlen + 1) << 3));
+	if (unlikely(!hdr->segments_left)) {
+		if (pskb_expand_head(skb, sizeof(struct ipv6hdr) + ((chdr->hdrlen + 1) << 3), 0,
+				     GFP_ATOMIC)) {
+			__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_OUTDISCARDS);
+			kfree_skb(skb);
+			kfree(buf);
+			return -1;
+		}
+
+		oldhdr = ipv6_hdr(skb);
+	}
 	skb_push(skb, ((chdr->hdrlen + 1) << 3) + sizeof(struct ipv6hdr));
 	skb_reset_network_header(skb);
 	skb_mac_header_rebuild(skb);
diff --git a/kernel/net/ipv6/exthdrs_core.c b/kernel/net/ipv6/exthdrs_core.c
index da46c42..49e31e4 100644
--- a/kernel/net/ipv6/exthdrs_core.c
+++ b/kernel/net/ipv6/exthdrs_core.c
@@ -143,6 +143,8 @@
 			optlen = 1;
 			break;
 		default:
+			if (len < 2)
+				goto bad;
 			optlen = nh[offset + 1] + 2;
 			if (optlen > len)
 				goto bad;
diff --git a/kernel/net/ipv6/icmp.c b/kernel/net/ipv6/icmp.c
index fd1f896..d01165b 100644
--- a/kernel/net/ipv6/icmp.c
+++ b/kernel/net/ipv6/icmp.c
@@ -429,7 +429,10 @@
 	if (unlikely(dev->ifindex == LOOPBACK_IFINDEX || netif_is_l3_master(skb->dev))) {
 		const struct rt6_info *rt6 = skb_rt6_info(skb);
 
-		if (rt6)
+		/* The destination could be an external IP in Ext Hdr (SRv6, RPL, etc.),
+		 * and ip6_null_entry could be set to skb if no route is found.
+		 */
+		if (rt6 && rt6->rt6i_idev)
 			dev = rt6->rt6i_idev->dev;
 	}
 
diff --git a/kernel/net/ipv6/ila/ila_xlat.c b/kernel/net/ipv6/ila/ila_xlat.c
index a1ac0e3..1636685 100644
--- a/kernel/net/ipv6/ila/ila_xlat.c
+++ b/kernel/net/ipv6/ila/ila_xlat.c
@@ -477,6 +477,7 @@
 
 	rcu_read_lock();
 
+	ret = -ESRCH;
 	ila = ila_lookup_by_params(&xp, ilan);
 	if (ila) {
 		ret = ila_dump_info(ila,
diff --git a/kernel/net/ipv6/ip6_gre.c b/kernel/net/ipv6/ip6_gre.c
index 0010f9e..2df1036 100644
--- a/kernel/net/ipv6/ip6_gre.c
+++ b/kernel/net/ipv6/ip6_gre.c
@@ -955,11 +955,12 @@
 		goto tx_err;
 
 	if (skb->len > dev->mtu + dev->hard_header_len) {
-		pskb_trim(skb, dev->mtu + dev->hard_header_len);
+		if (pskb_trim(skb, dev->mtu + dev->hard_header_len))
+			goto tx_err;
 		truncate = true;
 	}
 
-	nhoff = skb_network_header(skb) - skb_mac_header(skb);
+	nhoff = skb_network_offset(skb);
 	if (skb->protocol == htons(ETH_P_IP) &&
 	    (ntohs(ip_hdr(skb)->tot_len) > skb->len - nhoff))
 		truncate = true;
@@ -968,7 +969,7 @@
 		int thoff;
 
 		if (skb_transport_header_was_set(skb))
-			thoff = skb_transport_header(skb) - skb_mac_header(skb);
+			thoff = skb_transport_offset(skb);
 		else
 			thoff = nhoff + sizeof(struct ipv6hdr);
 		if (ntohs(ipv6_hdr(skb)->payload_len) > skb->len - thoff)
@@ -1015,12 +1016,14 @@
 					    ntohl(tun_id),
 					    ntohl(md->u.index), truncate,
 					    false);
+			proto = htons(ETH_P_ERSPAN);
 		} else if (md->version == 2) {
 			erspan_build_header_v2(skb,
 					       ntohl(tun_id),
 					       md->u.md2.dir,
 					       get_hwid(&md->u.md2),
 					       truncate, false);
+			proto = htons(ETH_P_ERSPAN2);
 		} else {
 			goto tx_err;
 		}
@@ -1043,24 +1046,25 @@
 			break;
 		}
 
-		if (t->parms.erspan_ver == 1)
+		if (t->parms.erspan_ver == 1) {
 			erspan_build_header(skb, ntohl(t->parms.o_key),
 					    t->parms.index,
 					    truncate, false);
-		else if (t->parms.erspan_ver == 2)
+			proto = htons(ETH_P_ERSPAN);
+		} else if (t->parms.erspan_ver == 2) {
 			erspan_build_header_v2(skb, ntohl(t->parms.o_key),
 					       t->parms.dir,
 					       t->parms.hwid,
 					       truncate, false);
-		else
+			proto = htons(ETH_P_ERSPAN2);
+		} else {
 			goto tx_err;
+		}
 
 		fl6.daddr = t->parms.raddr;
 	}
 
 	/* Push GRE header. */
-	proto = (t->parms.erspan_ver == 1) ? htons(ETH_P_ERSPAN)
-					   : htons(ETH_P_ERSPAN2);
 	gre_build_header(skb, 8, TUNNEL_SEQ, proto, 0, htonl(atomic_fetch_inc(&t->o_seqno)));
 
 	/* TooBig packet may have updated dst->dev's mtu */
diff --git a/kernel/net/ipv6/ip6_output.c b/kernel/net/ipv6/ip6_output.c
index e427f50..58b5ab5 100644
--- a/kernel/net/ipv6/ip6_output.c
+++ b/kernel/net/ipv6/ip6_output.c
@@ -131,7 +131,7 @@
 	if (lwtunnel_xmit_redirect(dst->lwtstate)) {
 		int res = lwtunnel_xmit(skb);
 
-		if (res < 0 || res == LWTUNNEL_XMIT_DONE)
+		if (res != LWTUNNEL_XMIT_CONTINUE)
 			return res;
 	}
 
@@ -1925,8 +1925,13 @@
 	IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
 	if (proto == IPPROTO_ICMPV6) {
 		struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
+		u8 icmp6_type;
 
-		ICMP6MSGOUT_INC_STATS(net, idev, icmp6_hdr(skb)->icmp6_type);
+		if (sk->sk_socket->type == SOCK_RAW && !inet_sk(sk)->hdrincl)
+			icmp6_type = fl6->fl6_icmp_type;
+		else
+			icmp6_type = icmp6_hdr(skb)->icmp6_type;
+		ICMP6MSGOUT_INC_STATS(net, idev, icmp6_type);
 		ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
 	}
 
diff --git a/kernel/net/ipv6/ip6_tunnel.c b/kernel/net/ipv6/ip6_tunnel.c
index 0d4cab9..a03a322 100644
--- a/kernel/net/ipv6/ip6_tunnel.c
+++ b/kernel/net/ipv6/ip6_tunnel.c
@@ -1267,8 +1267,8 @@
 	 */
 	max_headroom = LL_RESERVED_SPACE(dst->dev) + sizeof(struct ipv6hdr)
 			+ dst->header_len + t->hlen;
-	if (max_headroom > dev->needed_headroom)
-		dev->needed_headroom = max_headroom;
+	if (max_headroom > READ_ONCE(dev->needed_headroom))
+		WRITE_ONCE(dev->needed_headroom, max_headroom);
 
 	err = ip6_tnl_encap(skb, t, &proto, fl6);
 	if (err)
diff --git a/kernel/net/ipv6/ip6_vti.c b/kernel/net/ipv6/ip6_vti.c
index 99f2dc8..162ba06 100644
--- a/kernel/net/ipv6/ip6_vti.c
+++ b/kernel/net/ipv6/ip6_vti.c
@@ -567,12 +567,12 @@
 		    vti6_addr_conflict(t, ipv6_hdr(skb)))
 			goto tx_err;
 
-		xfrm_decode_session(skb, &fl, AF_INET6);
 		memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
+		xfrm_decode_session(skb, &fl, AF_INET6);
 		break;
 	case htons(ETH_P_IP):
-		xfrm_decode_session(skb, &fl, AF_INET);
 		memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
+		xfrm_decode_session(skb, &fl, AF_INET);
 		break;
 	default:
 		goto tx_err;
diff --git a/kernel/net/ipv6/ip6mr.c b/kernel/net/ipv6/ip6mr.c
index 5f0ac47..c758d0c 100644
--- a/kernel/net/ipv6/ip6mr.c
+++ b/kernel/net/ipv6/ip6mr.c
@@ -1069,7 +1069,7 @@
 		   And all this only to mangle msg->im6_msgtype and
 		   to set msg->im6_mbz to "mbz" :-)
 		 */
-		skb_push(skb, -skb_network_offset(pkt));
+		__skb_pull(skb, skb_network_offset(pkt));
 
 		skb_push(skb, sizeof(*msg));
 		skb_reset_transport_header(skb);
diff --git a/kernel/net/ipv6/ipv6_sockglue.c b/kernel/net/ipv6/ipv6_sockglue.c
index 2017257..7b4b457 100644
--- a/kernel/net/ipv6/ipv6_sockglue.c
+++ b/kernel/net/ipv6/ipv6_sockglue.c
@@ -429,9 +429,6 @@
 		if (optlen < sizeof(int))
 			goto e_inval;
 		if (val == PF_INET) {
-			struct ipv6_txoptions *opt;
-			struct sk_buff *pktopt;
-
 			if (sk->sk_type == SOCK_RAW)
 				break;
 
@@ -462,7 +459,6 @@
 				break;
 			}
 
-			fl6_free_socklist(sk);
 			__ipv6_sock_mc_close(sk);
 			__ipv6_sock_ac_close(sk);
 
@@ -497,14 +493,14 @@
 				sk->sk_socket->ops = &inet_dgram_ops;
 				sk->sk_family = PF_INET;
 			}
-			opt = xchg((__force struct ipv6_txoptions **)&np->opt,
-				   NULL);
-			if (opt) {
-				atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
-				txopt_put(opt);
-			}
-			pktopt = xchg(&np->pktoptions, NULL);
-			kfree_skb(pktopt);
+
+			/* Disable all options not to allocate memory anymore,
+			 * but there is still a race.  See the lockless path
+			 * in udpv6_sendmsg() and ipv6_local_rxpmtu().
+			 */
+			np->rxopt.all = 0;
+
+			inet6_cleanup_sock(sk);
 
 			/*
 			 * ... and add it to the refcnt debug socks count
diff --git a/kernel/net/ipv6/ndisc.c b/kernel/net/ipv6/ndisc.c
index 7671747..ac1e510 100644
--- a/kernel/net/ipv6/ndisc.c
+++ b/kernel/net/ipv6/ndisc.c
@@ -196,7 +196,8 @@
 static inline int ndisc_is_useropt(const struct net_device *dev,
 				   struct nd_opt_hdr *opt)
 {
-	return opt->nd_opt_type == ND_OPT_RDNSS ||
+	return opt->nd_opt_type == ND_OPT_PREFIX_INFO ||
+		opt->nd_opt_type == ND_OPT_RDNSS ||
 		opt->nd_opt_type == ND_OPT_DNSSL ||
 		opt->nd_opt_type == ND_OPT_CAPTIVE_PORTAL ||
 		opt->nd_opt_type == ND_OPT_PREF64 ||
diff --git a/kernel/net/ipv6/netfilter/ip6_tables.c b/kernel/net/ipv6/netfilter/ip6_tables.c
index d36168b..99bb11d 100644
--- a/kernel/net/ipv6/netfilter/ip6_tables.c
+++ b/kernel/net/ipv6/netfilter/ip6_tables.c
@@ -1062,7 +1062,6 @@
 	struct xt_counters *counters;
 	struct ip6t_entry *iter;
 
-	ret = 0;
 	counters = xt_counters_alloc(num_counters);
 	if (!counters) {
 		ret = -ENOMEM;
@@ -1108,7 +1107,7 @@
 		net_warn_ratelimited("ip6tables: counters copy to user failed while replacing table\n");
 	}
 	vfree(counters);
-	return ret;
+	return 0;
 
  put_module:
 	module_put(t->me);
diff --git a/kernel/net/ipv6/netfilter/ip6t_REJECT.c b/kernel/net/ipv6/netfilter/ip6t_REJECT.c
index 3ac5485..a35019d 100644
--- a/kernel/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/kernel/net/ipv6/netfilter/ip6t_REJECT.c
@@ -61,7 +61,7 @@
 		/* Do nothing */
 		break;
 	case IP6T_TCP_RESET:
-		nf_send_reset6(net, skb, xt_hooknum(par));
+		nf_send_reset6(net, par->state->sk, skb, xt_hooknum(par));
 		break;
 	case IP6T_ICMP6_POLICY_FAIL:
 		nf_send_unreach6(net, skb, ICMPV6_POLICY_FAIL, xt_hooknum(par));
diff --git a/kernel/net/ipv6/netfilter/nf_reject_ipv6.c b/kernel/net/ipv6/netfilter/nf_reject_ipv6.c
index bf95513..832d9f9 100644
--- a/kernel/net/ipv6/netfilter/nf_reject_ipv6.c
+++ b/kernel/net/ipv6/netfilter/nf_reject_ipv6.c
@@ -141,7 +141,8 @@
 	return 0;
 }
 
-void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook)
+void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
+		    int hook)
 {
 	struct net_device *br_indev __maybe_unused;
 	struct sk_buff *nskb;
@@ -233,7 +234,7 @@
 		dev_queue_xmit(nskb);
 	} else
 #endif
-		ip6_local_out(net, nskb->sk, nskb);
+		ip6_local_out(net, sk, nskb);
 }
 EXPORT_SYMBOL_GPL(nf_send_reset6);
 
diff --git a/kernel/net/ipv6/netfilter/nf_tproxy_ipv6.c b/kernel/net/ipv6/netfilter/nf_tproxy_ipv6.c
index 6bac68f..3fe4f15 100644
--- a/kernel/net/ipv6/netfilter/nf_tproxy_ipv6.c
+++ b/kernel/net/ipv6/netfilter/nf_tproxy_ipv6.c
@@ -63,7 +63,7 @@
 					    lport ? lport : hp->dest,
 					    skb->dev, NF_TPROXY_LOOKUP_LISTENER);
 		if (sk2) {
-			inet_twsk_deschedule_put(inet_twsk(sk));
+			nf_tproxy_twsk_deschedule_put(inet_twsk(sk));
 			sk = sk2;
 		}
 	}
diff --git a/kernel/net/ipv6/netfilter/nft_reject_ipv6.c b/kernel/net/ipv6/netfilter/nft_reject_ipv6.c
index c1098a1..ed69c76 100644
--- a/kernel/net/ipv6/netfilter/nft_reject_ipv6.c
+++ b/kernel/net/ipv6/netfilter/nft_reject_ipv6.c
@@ -28,7 +28,8 @@
 				 nft_hook(pkt));
 		break;
 	case NFT_REJECT_TCP_RST:
-		nf_send_reset6(nft_net(pkt), pkt->skb, nft_hook(pkt));
+		nf_send_reset6(nft_net(pkt), nft_sk(pkt), pkt->skb,
+			       nft_hook(pkt));
 		break;
 	default:
 		break;
diff --git a/kernel/net/ipv6/ping.c b/kernel/net/ipv6/ping.c
index 135e3a0..7fab29f 100644
--- a/kernel/net/ipv6/ping.c
+++ b/kernel/net/ipv6/ping.c
@@ -22,11 +22,6 @@
 #include <linux/proc_fs.h>
 #include <net/ping.h>
 
-static void ping_v6_destroy(struct sock *sk)
-{
-	inet6_destroy_sock(sk);
-}
-
 /* Compatibility glue so we can support IPv6 when it's compiled as a module */
 static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
 				 int *addr_len)
@@ -101,7 +96,8 @@
 	addr_type = ipv6_addr_type(daddr);
 	if ((__ipv6_addr_needs_scope_id(addr_type) && !oif) ||
 	    (addr_type & IPV6_ADDR_MAPPED) ||
-	    (oif && sk->sk_bound_dev_if && oif != sk->sk_bound_dev_if))
+	    (oif && sk->sk_bound_dev_if && oif != sk->sk_bound_dev_if &&
+	     l3mdev_master_ifindex_by_index(sock_net(sk), oif) != sk->sk_bound_dev_if))
 		return -EINVAL;
 
 	/* TODO: use ip6_datagram_send_ctl to get options from cmsg */
@@ -171,7 +167,6 @@
 	.owner =	THIS_MODULE,
 	.init =		ping_init_sock,
 	.close =	ping_close,
-	.destroy =	ping_v6_destroy,
 	.connect =	ip6_datagram_connect_v6_only,
 	.disconnect =	__udp_disconnect,
 	.setsockopt =	ipv6_setsockopt,
diff --git a/kernel/net/ipv6/raw.c b/kernel/net/ipv6/raw.c
index 31eb54e..7ff06fa 100644
--- a/kernel/net/ipv6/raw.c
+++ b/kernel/net/ipv6/raw.c
@@ -539,6 +539,7 @@
 static int rawv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
 				     struct raw6_sock *rp)
 {
+	struct ipv6_txoptions *opt;
 	struct sk_buff *skb;
 	int err = 0;
 	int offset;
@@ -556,6 +557,9 @@
 
 	offset = rp->offset;
 	total_len = inet_sk(sk)->cork.base.length;
+	opt = inet6_sk(sk)->cork.opt;
+	total_len -= opt ? opt->opt_flen : 0;
+
 	if (offset >= total_len - 1) {
 		err = -EINVAL;
 		ip6_flush_pending_frames(sk);
@@ -824,7 +828,8 @@
 
 		if (!proto)
 			proto = inet->inet_num;
-		else if (proto != inet->inet_num)
+		else if (proto != inet->inet_num &&
+			 inet->inet_num != IPPROTO_RAW)
 			return -EINVAL;
 
 		if (proto > 255)
@@ -1207,8 +1212,6 @@
 	lock_sock(sk);
 	ip6_flush_pending_frames(sk);
 	release_sock(sk);
-
-	inet6_destroy_sock(sk);
 }
 
 static int rawv6_init_sk(struct sock *sk)
diff --git a/kernel/net/ipv6/route.c b/kernel/net/ipv6/route.c
index 2b9053e..84115d5 100644
--- a/kernel/net/ipv6/route.c
+++ b/kernel/net/ipv6/route.c
@@ -5401,16 +5401,17 @@
 		nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_nlmsg_size,
 					 &nexthop_len);
 	} else {
+		struct fib6_info *sibling, *next_sibling;
 		struct fib6_nh *nh = f6i->fib6_nh;
 
 		nexthop_len = 0;
 		if (f6i->fib6_nsiblings) {
-			nexthop_len = nla_total_size(0)	 /* RTA_MULTIPATH */
-				    + NLA_ALIGN(sizeof(struct rtnexthop))
-				    + nla_total_size(16) /* RTA_GATEWAY */
-				    + lwtunnel_get_encap_size(nh->fib_nh_lws);
+			rt6_nh_nlmsg_size(nh, &nexthop_len);
 
-			nexthop_len *= f6i->fib6_nsiblings;
+			list_for_each_entry_safe(sibling, next_sibling,
+						 &f6i->fib6_siblings, fib6_siblings) {
+				rt6_nh_nlmsg_size(sibling->fib6_nh, &nexthop_len);
+			}
 		}
 		nexthop_len += lwtunnel_get_encap_size(nh->fib_nh_lws);
 	}
diff --git a/kernel/net/ipv6/rpl.c b/kernel/net/ipv6/rpl.c
index 307f336..3b03864 100644
--- a/kernel/net/ipv6/rpl.c
+++ b/kernel/net/ipv6/rpl.c
@@ -32,7 +32,8 @@
 size_t ipv6_rpl_srh_size(unsigned char n, unsigned char cmpri,
 			 unsigned char cmpre)
 {
-	return (n * IPV6_PFXTAIL_LEN(cmpri)) + IPV6_PFXTAIL_LEN(cmpre);
+	return sizeof(struct ipv6_rpl_sr_hdr) + (n * IPV6_PFXTAIL_LEN(cmpri)) +
+		IPV6_PFXTAIL_LEN(cmpre);
 }
 
 void ipv6_rpl_srh_decompress(struct ipv6_rpl_sr_hdr *outhdr,
diff --git a/kernel/net/ipv6/sit.c b/kernel/net/ipv6/sit.c
index 1ce486a..9806bd5 100644
--- a/kernel/net/ipv6/sit.c
+++ b/kernel/net/ipv6/sit.c
@@ -1094,12 +1094,13 @@
 
 static void ipip6_tunnel_bind_dev(struct net_device *dev)
 {
+	struct ip_tunnel *tunnel = netdev_priv(dev);
+	int t_hlen = tunnel->hlen + sizeof(struct iphdr);
 	struct net_device *tdev = NULL;
-	struct ip_tunnel *tunnel;
+	int hlen = LL_MAX_HEADER;
 	const struct iphdr *iph;
 	struct flowi4 fl4;
 
-	tunnel = netdev_priv(dev);
 	iph = &tunnel->parms.iph;
 
 	if (iph->daddr) {
@@ -1122,14 +1123,15 @@
 		tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
 
 	if (tdev && !netif_is_l3_master(tdev)) {
-		int t_hlen = tunnel->hlen + sizeof(struct iphdr);
 		int mtu;
 
 		mtu = tdev->mtu - t_hlen;
 		if (mtu < IPV6_MIN_MTU)
 			mtu = IPV6_MIN_MTU;
 		WRITE_ONCE(dev->mtu, mtu);
+		hlen = tdev->hard_header_len + tdev->needed_headroom;
 	}
+	dev->needed_headroom = t_hlen + hlen;
 }
 
 static void ipip6_tunnel_update(struct ip_tunnel *t, struct ip_tunnel_parm *p,
diff --git a/kernel/net/ipv6/tcp_ipv6.c b/kernel/net/ipv6/tcp_ipv6.c
index c599e14..a68f75d 100644
--- a/kernel/net/ipv6/tcp_ipv6.c
+++ b/kernel/net/ipv6/tcp_ipv6.c
@@ -269,6 +269,7 @@
 	fl6.flowi6_proto = IPPROTO_TCP;
 	fl6.daddr = sk->sk_v6_daddr;
 	fl6.saddr = saddr ? *saddr : np->saddr;
+	fl6.flowlabel = ip6_make_flowinfo(np->tclass, np->flow_label);
 	fl6.flowi6_oif = sk->sk_bound_dev_if;
 	fl6.flowi6_mark = sk->sk_mark;
 	fl6.fl6_dport = usin->sin6_port;
@@ -1147,7 +1148,7 @@
 			tcp_rsk(req)->rcv_nxt,
 			req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale,
 			tcp_time_stamp_raw() + tcp_rsk(req)->ts_off,
-			req->ts_recent, sk->sk_bound_dev_if,
+			READ_ONCE(req->ts_recent), sk->sk_bound_dev_if,
 			tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr, l3index),
 			ipv6_get_dsfield(ipv6_hdr(skb)), 0, sk->sk_priority);
 }
@@ -1406,14 +1407,11 @@
 
 		/* Clone pktoptions received with SYN, if we own the req */
 		if (ireq->pktopts) {
-			newnp->pktoptions = skb_clone(ireq->pktopts,
-						      sk_gfp_mask(sk, GFP_ATOMIC));
+			newnp->pktoptions = skb_clone_and_charge_r(ireq->pktopts, newsk);
 			consume_skb(ireq->pktopts);
 			ireq->pktopts = NULL;
-			if (newnp->pktoptions) {
+			if (newnp->pktoptions)
 				tcp_v6_restore_cb(newnp->pktoptions);
-				skb_set_owner_r(newnp->pktoptions, newsk);
-			}
 		}
 	} else {
 		if (!req_unhash && found_dup_sk) {
@@ -1481,7 +1479,7 @@
 					       --ANK (980728)
 	 */
 	if (np->rxopt.all)
-		opt_skb = skb_clone(skb, sk_gfp_mask(sk, GFP_ATOMIC));
+		opt_skb = skb_clone_and_charge_r(skb, sk);
 
 	if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
 		struct dst_entry *dst;
@@ -1563,7 +1561,6 @@
 		if (np->repflow)
 			np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb));
 		if (ipv6_opt_accepted(sk, opt_skb, &TCP_SKB_CB(opt_skb)->header.h6)) {
-			skb_set_owner_r(opt_skb, sk);
 			tcp_v6_restore_cb(opt_skb);
 			opt_skb = xchg(&np->pktoptions, opt_skb);
 		} else {
@@ -1939,12 +1936,6 @@
 	return 0;
 }
 
-static void tcp_v6_destroy_sock(struct sock *sk)
-{
-	tcp_v4_destroy_sock(sk);
-	inet6_destroy_sock(sk);
-}
-
 #ifdef CONFIG_PROC_FS
 /* Proc filesystem TCPv6 sock list dumping. */
 static void get_openreq6(struct seq_file *seq,
@@ -2137,7 +2128,7 @@
 	.accept			= inet_csk_accept,
 	.ioctl			= tcp_ioctl,
 	.init			= tcp_v6_init_sock,
-	.destroy		= tcp_v6_destroy_sock,
+	.destroy		= tcp_v4_destroy_sock,
 	.shutdown		= tcp_shutdown,
 	.setsockopt		= tcp_setsockopt,
 	.getsockopt		= tcp_getsockopt,
diff --git a/kernel/net/ipv6/udp.c b/kernel/net/ipv6/udp.c
index 1805cc5..5385037 100644
--- a/kernel/net/ipv6/udp.c
+++ b/kernel/net/ipv6/udp.c
@@ -54,6 +54,19 @@
 #include <trace/events/skb.h>
 #include "udp_impl.h"
 
+static void udpv6_destruct_sock(struct sock *sk)
+{
+	udp_destruct_common(sk);
+	inet6_sock_destruct(sk);
+}
+
+int udpv6_init_sock(struct sock *sk)
+{
+	skb_queue_head_init(&udp_sk(sk)->reader_queue);
+	sk->sk_destruct = udpv6_destruct_sock;
+	return 0;
+}
+
 static u32 udp6_ehashfn(const struct net *net,
 			const struct in6_addr *laddr,
 			const u16 lport,
@@ -74,7 +87,7 @@
 	fhash = __ipv6_addr_jhash(faddr, udp_ipv6_hash_secret);
 
 	return __inet6_ehashfn(lhash, lport, fhash, fport,
-			       udp_ipv6_hash_secret + net_hash_mix(net));
+			       udp6_ehash_secret + net_hash_mix(net));
 }
 
 int udp_v6_get_port(struct sock *sk, unsigned short snum)
@@ -176,14 +189,23 @@
 		score = compute_score(sk, net, saddr, sport,
 				      daddr, hnum, dif, sdif);
 		if (score > badness) {
-			result = lookup_reuseport(net, sk, skb,
-						  saddr, sport, daddr, hnum);
+			badness = score;
+			result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum);
+			if (!result) {
+				result = sk;
+				continue;
+			}
+
 			/* Fall back to scoring if group has connections */
-			if (result && !reuseport_has_conns(sk))
+			if (!reuseport_has_conns(sk))
 				return result;
 
-			result = result ? : sk;
-			badness = score;
+			/* Reuseport logic returned an error, keep original score. */
+			if (IS_ERR(result))
+				continue;
+
+			badness = compute_score(sk, net, saddr, sport,
+						daddr, hnum, dif, sdif);
 		}
 	}
 	return result;
@@ -1340,9 +1362,11 @@
 			msg->msg_name = &sin;
 			msg->msg_namelen = sizeof(sin);
 do_udp_sendmsg:
-			if (__ipv6_only_sock(sk))
-				return -ENETUNREACH;
-			return udp_sendmsg(sk, msg, len);
+			err = __ipv6_only_sock(sk) ?
+				-ENETUNREACH : udp_sendmsg(sk, msg, len);
+			msg->msg_name = sin6;
+			msg->msg_namelen = addr_len;
+			return err;
 		}
 	}
 
@@ -1615,8 +1639,6 @@
 			udp_encap_disable();
 		}
 	}
-
-	inet6_destroy_sock(sk);
 }
 
 /*
@@ -1700,7 +1722,7 @@
 	.connect		= ip6_datagram_connect,
 	.disconnect		= udp_disconnect,
 	.ioctl			= udp_ioctl,
-	.init			= udp_init_sock,
+	.init			= udpv6_init_sock,
 	.destroy		= udpv6_destroy_sock,
 	.setsockopt		= udpv6_setsockopt,
 	.getsockopt		= udpv6_getsockopt,
diff --git a/kernel/net/ipv6/udp_impl.h b/kernel/net/ipv6/udp_impl.h
index b2fcc46..e497768 100644
--- a/kernel/net/ipv6/udp_impl.h
+++ b/kernel/net/ipv6/udp_impl.h
@@ -12,6 +12,7 @@
 int __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, u8, u8, int,
 		   __be32, struct udp_table *);
 
+int udpv6_init_sock(struct sock *sk);
 int udp_v6_get_port(struct sock *sk, unsigned short snum);
 void udp_v6_rehash(struct sock *sk);
 
diff --git a/kernel/net/ipv6/udplite.c b/kernel/net/ipv6/udplite.c
index fbb700d..26199f7 100644
--- a/kernel/net/ipv6/udplite.c
+++ b/kernel/net/ipv6/udplite.c
@@ -12,6 +12,13 @@
 #include <linux/proc_fs.h>
 #include "udp_impl.h"
 
+static int udplitev6_sk_init(struct sock *sk)
+{
+	udpv6_init_sock(sk);
+	udp_sk(sk)->pcflag = UDPLITE_BIT;
+	return 0;
+}
+
 static int udplitev6_rcv(struct sk_buff *skb)
 {
 	return __udp6_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE);
@@ -38,7 +45,7 @@
 	.connect	   = ip6_datagram_connect,
 	.disconnect	   = udp_disconnect,
 	.ioctl		   = udp_ioctl,
-	.init		   = udplite_sk_init,
+	.init		   = udplitev6_sk_init,
 	.destroy	   = udpv6_destroy_sock,
 	.setsockopt	   = udpv6_setsockopt,
 	.getsockopt	   = udpv6_getsockopt,
@@ -50,6 +57,8 @@
 	.get_port	   = udp_v6_get_port,
 	.memory_allocated  = &udp_memory_allocated,
 	.sysctl_mem	   = sysctl_udp_mem,
+	.sysctl_wmem_offset = offsetof(struct net, ipv4.sysctl_udp_wmem_min),
+	.sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_udp_rmem_min),
 	.obj_size	   = sizeof(struct udp6_sock),
 	.h.udp_table	   = &udplite_table,
 };
diff --git a/kernel/net/ipv6/xfrm6_input.c b/kernel/net/ipv6/xfrm6_input.c
index 04cbeef..4907ab2 100644
--- a/kernel/net/ipv6/xfrm6_input.c
+++ b/kernel/net/ipv6/xfrm6_input.c
@@ -86,6 +86,9 @@
 	__be32 *udpdata32;
 	__u16 encap_type = up->encap_type;
 
+	if (skb->protocol == htons(ETH_P_IP))
+		return xfrm4_udp_encap_rcv(sk, skb);
+
 	/* if this is not encapsulated socket, then just return now */
 	if (!encap_type)
 		return 1;
diff --git a/kernel/net/iucv/iucv.c b/kernel/net/iucv/iucv.c
index 349c6ac..6f84978 100644
--- a/kernel/net/iucv/iucv.c
+++ b/kernel/net/iucv/iucv.c
@@ -83,7 +83,7 @@
 	u16 ippathid;
 	u8  ipflags1;
 	u8  iptype;
-	u32 res2[8];
+	u32 res2[9];
 };
 
 struct iucv_irq_list {
diff --git a/kernel/net/kcm/kcmsock.c b/kernel/net/kcm/kcmsock.c
index 32b516a..39b3c7f 100644
--- a/kernel/net/kcm/kcmsock.c
+++ b/kernel/net/kcm/kcmsock.c
@@ -1064,15 +1064,18 @@
 out_error:
 	kcm_push(kcm);
 
-	if (copied && sock->type == SOCK_SEQPACKET) {
+	if (sock->type == SOCK_SEQPACKET) {
 		/* Wrote some bytes before encountering an
 		 * error, return partial success.
 		 */
-		goto partial_message;
-	}
-
-	if (head != kcm->seq_skb)
+		if (copied)
+			goto partial_message;
+		if (head != kcm->seq_skb)
+			kfree_skb(head);
+	} else {
 		kfree_skb(head);
+		kcm->seq_skb = NULL;
+	}
 
 	err = sk_stream_error(sk, msg->msg_flags, err);
 
@@ -1982,6 +1985,8 @@
 	 * that all multiplexors and psocks have been destroyed.
 	 */
 	WARN_ON(!list_empty(&knet->mux_list));
+
+	mutex_destroy(&knet->mutex);
 }
 
 static struct pernet_operations kcm_net_ops = {
diff --git a/kernel/net/key/af_key.c b/kernel/net/key/af_key.c
index 8bc7d39..f428549 100644
--- a/kernel/net/key/af_key.c
+++ b/kernel/net/key/af_key.c
@@ -1852,9 +1852,9 @@
 	if (ext_hdrs[SADB_X_EXT_FILTER - 1]) {
 		struct sadb_x_filter *xfilter = ext_hdrs[SADB_X_EXT_FILTER - 1];
 
-		if ((xfilter->sadb_x_filter_splen >=
+		if ((xfilter->sadb_x_filter_splen >
 			(sizeof(xfrm_address_t) << 3)) ||
-		    (xfilter->sadb_x_filter_dplen >=
+		    (xfilter->sadb_x_filter_dplen >
 			(sizeof(xfrm_address_t) << 3))) {
 			mutex_unlock(&pfk->dump_lock);
 			return -EINVAL;
@@ -1944,7 +1944,8 @@
 }
 
 static int
-parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
+parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_policy *pol,
+		   struct sadb_x_ipsecrequest *rq)
 {
 	struct net *net = xp_net(xp);
 	struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr;
@@ -1962,9 +1963,12 @@
 	if ((mode = pfkey_mode_to_xfrm(rq->sadb_x_ipsecrequest_mode)) < 0)
 		return -EINVAL;
 	t->mode = mode;
-	if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_USE)
+	if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_USE) {
+		if ((mode == XFRM_MODE_TUNNEL || mode == XFRM_MODE_BEET) &&
+		    pol->sadb_x_policy_dir == IPSEC_DIR_OUTBOUND)
+			return -EINVAL;
 		t->optional = 1;
-	else if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_UNIQUE) {
+	} else if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_UNIQUE) {
 		t->reqid = rq->sadb_x_ipsecrequest_reqid;
 		if (t->reqid > IPSEC_MANUAL_REQID_MAX)
 			t->reqid = 0;
@@ -2006,7 +2010,7 @@
 		    rq->sadb_x_ipsecrequest_len < sizeof(*rq))
 			return -EINVAL;
 
-		if ((err = parse_ipsecrequest(xp, rq)) < 0)
+		if ((err = parse_ipsecrequest(xp, pol, rq)) < 0)
 			return err;
 		len -= rq->sadb_x_ipsecrequest_len;
 		rq = (void*)((u8*)rq + rq->sadb_x_ipsecrequest_len);
diff --git a/kernel/net/l2tp/l2tp_core.c b/kernel/net/l2tp/l2tp_core.c
index dc8987e..a4b793d 100644
--- a/kernel/net/l2tp/l2tp_core.c
+++ b/kernel/net/l2tp/l2tp_core.c
@@ -104,9 +104,9 @@
 /* per-net private data for this module */
 static unsigned int l2tp_net_id;
 struct l2tp_net {
-	struct list_head l2tp_tunnel_list;
-	/* Lock for write access to l2tp_tunnel_list */
-	spinlock_t l2tp_tunnel_list_lock;
+	/* Lock for write access to l2tp_tunnel_idr */
+	spinlock_t l2tp_tunnel_idr_lock;
+	struct idr l2tp_tunnel_idr;
 	struct hlist_head l2tp_session_hlist[L2TP_HASH_SIZE_2];
 	/* Lock for write access to l2tp_session_hlist */
 	spinlock_t l2tp_session_hlist_lock;
@@ -208,13 +208,10 @@
 	struct l2tp_tunnel *tunnel;
 
 	rcu_read_lock_bh();
-	list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
-		if (tunnel->tunnel_id == tunnel_id &&
-		    refcount_inc_not_zero(&tunnel->ref_count)) {
-			rcu_read_unlock_bh();
-
-			return tunnel;
-		}
+	tunnel = idr_find(&pn->l2tp_tunnel_idr, tunnel_id);
+	if (tunnel && refcount_inc_not_zero(&tunnel->ref_count)) {
+		rcu_read_unlock_bh();
+		return tunnel;
 	}
 	rcu_read_unlock_bh();
 
@@ -224,13 +221,14 @@
 
 struct l2tp_tunnel *l2tp_tunnel_get_nth(const struct net *net, int nth)
 {
-	const struct l2tp_net *pn = l2tp_pernet(net);
+	struct l2tp_net *pn = l2tp_pernet(net);
+	unsigned long tunnel_id, tmp;
 	struct l2tp_tunnel *tunnel;
 	int count = 0;
 
 	rcu_read_lock_bh();
-	list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
-		if (++count > nth &&
+	idr_for_each_entry_ul(&pn->l2tp_tunnel_idr, tunnel, tmp, tunnel_id) {
+		if (tunnel && ++count > nth &&
 		    refcount_inc_not_zero(&tunnel->ref_count)) {
 			rcu_read_unlock_bh();
 			return tunnel;
@@ -1043,7 +1041,7 @@
 	IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED);
 	nf_reset_ct(skb);
 
-	bh_lock_sock(sk);
+	bh_lock_sock_nested(sk);
 	if (sock_owned_by_user(sk)) {
 		kfree_skb(skb);
 		ret = NET_XMIT_DROP;
@@ -1150,8 +1148,10 @@
 	}
 
 	/* Remove hooks into tunnel socket */
+	write_lock_bh(&sk->sk_callback_lock);
 	sk->sk_destruct = tunnel->old_sk_destruct;
 	sk->sk_user_data = NULL;
+	write_unlock_bh(&sk->sk_callback_lock);
 
 	/* Call the original destructor */
 	if (sk->sk_destruct)
@@ -1227,6 +1227,15 @@
 		l2tp_tunnel_delete(tunnel);
 }
 
+static void l2tp_tunnel_remove(struct net *net, struct l2tp_tunnel *tunnel)
+{
+	struct l2tp_net *pn = l2tp_pernet(net);
+
+	spin_lock_bh(&pn->l2tp_tunnel_idr_lock);
+	idr_remove(&pn->l2tp_tunnel_idr, tunnel->tunnel_id);
+	spin_unlock_bh(&pn->l2tp_tunnel_idr_lock);
+}
+
 /* Workqueue tunnel deletion function */
 static void l2tp_tunnel_del_work(struct work_struct *work)
 {
@@ -1234,7 +1243,6 @@
 						  del_work);
 	struct sock *sk = tunnel->sock;
 	struct socket *sock = sk->sk_socket;
-	struct l2tp_net *pn;
 
 	l2tp_tunnel_closeall(tunnel);
 
@@ -1248,12 +1256,7 @@
 		}
 	}
 
-	/* Remove the tunnel struct from the tunnel list */
-	pn = l2tp_pernet(tunnel->l2tp_net);
-	spin_lock_bh(&pn->l2tp_tunnel_list_lock);
-	list_del_rcu(&tunnel->list);
-	spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
-
+	l2tp_tunnel_remove(tunnel->l2tp_net, tunnel);
 	/* drop initial ref */
 	l2tp_tunnel_dec_refcount(tunnel);
 
@@ -1384,8 +1387,6 @@
 	return err;
 }
 
-static struct lock_class_key l2tp_socket_class;
-
 int l2tp_tunnel_create(int fd, int version, u32 tunnel_id, u32 peer_tunnel_id,
 		       struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp)
 {
@@ -1455,11 +1456,18 @@
 int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
 			 struct l2tp_tunnel_cfg *cfg)
 {
-	struct l2tp_tunnel *tunnel_walk;
-	struct l2tp_net *pn;
+	struct l2tp_net *pn = l2tp_pernet(net);
+	u32 tunnel_id = tunnel->tunnel_id;
 	struct socket *sock;
 	struct sock *sk;
 	int ret;
+
+	spin_lock_bh(&pn->l2tp_tunnel_idr_lock);
+	ret = idr_alloc_u32(&pn->l2tp_tunnel_idr, NULL, &tunnel_id, tunnel_id,
+			    GFP_ATOMIC);
+	spin_unlock_bh(&pn->l2tp_tunnel_idr_lock);
+	if (ret)
+		return ret == -ENOSPC ? -EEXIST : ret;
 
 	if (tunnel->fd < 0) {
 		ret = l2tp_tunnel_sock_create(net, tunnel->tunnel_id,
@@ -1471,30 +1479,16 @@
 		sock = sockfd_lookup(tunnel->fd, &ret);
 		if (!sock)
 			goto err;
-
-		ret = l2tp_validate_socket(sock->sk, net, tunnel->encap);
-		if (ret < 0)
-			goto err_sock;
 	}
-
-	tunnel->l2tp_net = net;
-	pn = l2tp_pernet(net);
 
 	sk = sock->sk;
-	sock_hold(sk);
-	tunnel->sock = sk;
-
-	spin_lock_bh(&pn->l2tp_tunnel_list_lock);
-	list_for_each_entry(tunnel_walk, &pn->l2tp_tunnel_list, list) {
-		if (tunnel_walk->tunnel_id == tunnel->tunnel_id) {
-			spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
-			sock_put(sk);
-			ret = -EEXIST;
-			goto err_sock;
-		}
-	}
-	list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
-	spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
+	lock_sock(sk);
+	write_lock_bh(&sk->sk_callback_lock);
+	ret = l2tp_validate_socket(sk, net, tunnel->encap);
+	if (ret < 0)
+		goto err_inval_sock;
+	rcu_assign_sk_user_data(sk, tunnel);
+	write_unlock_bh(&sk->sk_callback_lock);
 
 	if (tunnel->encap == L2TP_ENCAPTYPE_UDP) {
 		struct udp_tunnel_sock_cfg udp_cfg = {
@@ -1505,15 +1499,20 @@
 		};
 
 		setup_udp_tunnel_sock(net, sock, &udp_cfg);
-	} else {
-		sk->sk_user_data = tunnel;
 	}
 
 	tunnel->old_sk_destruct = sk->sk_destruct;
 	sk->sk_destruct = &l2tp_tunnel_destruct;
-	lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class,
-				   "l2tp_sock");
 	sk->sk_allocation = GFP_ATOMIC;
+	release_sock(sk);
+
+	sock_hold(sk);
+	tunnel->sock = sk;
+	tunnel->l2tp_net = net;
+
+	spin_lock_bh(&pn->l2tp_tunnel_idr_lock);
+	idr_replace(&pn->l2tp_tunnel_idr, tunnel, tunnel->tunnel_id);
+	spin_unlock_bh(&pn->l2tp_tunnel_idr_lock);
 
 	trace_register_tunnel(tunnel);
 
@@ -1522,12 +1521,16 @@
 
 	return 0;
 
-err_sock:
+err_inval_sock:
+	write_unlock_bh(&sk->sk_callback_lock);
+	release_sock(sk);
+
 	if (tunnel->fd < 0)
 		sock_release(sock);
 	else
 		sockfd_put(sock);
 err:
+	l2tp_tunnel_remove(net, tunnel);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(l2tp_tunnel_register);
@@ -1641,8 +1644,8 @@
 	struct l2tp_net *pn = net_generic(net, l2tp_net_id);
 	int hash;
 
-	INIT_LIST_HEAD(&pn->l2tp_tunnel_list);
-	spin_lock_init(&pn->l2tp_tunnel_list_lock);
+	idr_init(&pn->l2tp_tunnel_idr);
+	spin_lock_init(&pn->l2tp_tunnel_idr_lock);
 
 	for (hash = 0; hash < L2TP_HASH_SIZE_2; hash++)
 		INIT_HLIST_HEAD(&pn->l2tp_session_hlist[hash]);
@@ -1656,11 +1659,13 @@
 {
 	struct l2tp_net *pn = l2tp_pernet(net);
 	struct l2tp_tunnel *tunnel = NULL;
+	unsigned long tunnel_id, tmp;
 	int hash;
 
 	rcu_read_lock_bh();
-	list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
-		l2tp_tunnel_delete(tunnel);
+	idr_for_each_entry_ul(&pn->l2tp_tunnel_idr, tunnel, tmp, tunnel_id) {
+		if (tunnel)
+			l2tp_tunnel_delete(tunnel);
 	}
 	rcu_read_unlock_bh();
 
@@ -1670,6 +1675,7 @@
 
 	for (hash = 0; hash < L2TP_HASH_SIZE_2; hash++)
 		WARN_ON_ONCE(!hlist_empty(&pn->l2tp_session_hlist[hash]));
+	idr_destroy(&pn->l2tp_tunnel_idr);
 }
 
 static struct pernet_operations l2tp_net_ops = {
diff --git a/kernel/net/l2tp/l2tp_ip6.c b/kernel/net/l2tp/l2tp_ip6.c
index d54dbd0..9746c62 100644
--- a/kernel/net/l2tp/l2tp_ip6.c
+++ b/kernel/net/l2tp/l2tp_ip6.c
@@ -255,8 +255,6 @@
 
 	if (tunnel)
 		l2tp_tunnel_delete(tunnel);
-
-	inet6_destroy_sock(sk);
 }
 
 static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
@@ -510,7 +508,6 @@
 	 */
 	if (len > INT_MAX - transhdrlen)
 		return -EMSGSIZE;
-	ulen = len + transhdrlen;
 
 	/* Mirror BSD error message compatibility */
 	if (msg->msg_flags & MSG_OOB)
@@ -631,6 +628,7 @@
 
 back_from_confirm:
 	lock_sock(sk);
+	ulen = len + skb_queue_empty(&sk->sk_write_queue) ? transhdrlen : 0;
 	err = ip6_append_data(sk, ip_generic_getfrag, msg,
 			      ulen, transhdrlen, &ipc6,
 			      &fl6, (struct rt6_info *)dst,
diff --git a/kernel/net/l2tp/l2tp_ppp.c b/kernel/net/l2tp/l2tp_ppp.c
index aea85f9..5ecc0f2 100644
--- a/kernel/net/l2tp/l2tp_ppp.c
+++ b/kernel/net/l2tp/l2tp_ppp.c
@@ -651,6 +651,65 @@
 	return mtu - PPPOL2TP_HEADER_OVERHEAD;
 }
 
+static struct l2tp_tunnel *pppol2tp_tunnel_get(struct net *net,
+					       const struct l2tp_connect_info *info,
+					       bool *new_tunnel)
+{
+	struct l2tp_tunnel *tunnel;
+	int error;
+
+	*new_tunnel = false;
+
+	tunnel = l2tp_tunnel_get(net, info->tunnel_id);
+
+	/* Special case: create tunnel context if session_id and
+	 * peer_session_id is 0. Otherwise look up tunnel using supplied
+	 * tunnel id.
+	 */
+	if (!info->session_id && !info->peer_session_id) {
+		if (!tunnel) {
+			struct l2tp_tunnel_cfg tcfg = {
+				.encap = L2TP_ENCAPTYPE_UDP,
+			};
+
+			/* Prevent l2tp_tunnel_register() from trying to set up
+			 * a kernel socket.
+			 */
+			if (info->fd < 0)
+				return ERR_PTR(-EBADF);
+
+			error = l2tp_tunnel_create(info->fd,
+						   info->version,
+						   info->tunnel_id,
+						   info->peer_tunnel_id, &tcfg,
+						   &tunnel);
+			if (error < 0)
+				return ERR_PTR(error);
+
+			l2tp_tunnel_inc_refcount(tunnel);
+			error = l2tp_tunnel_register(tunnel, net, &tcfg);
+			if (error < 0) {
+				kfree(tunnel);
+				return ERR_PTR(error);
+			}
+
+			*new_tunnel = true;
+		}
+	} else {
+		/* Error if we can't find the tunnel */
+		if (!tunnel)
+			return ERR_PTR(-ENOENT);
+
+		/* Error if socket is not prepped */
+		if (!tunnel->sock) {
+			l2tp_tunnel_dec_refcount(tunnel);
+			return ERR_PTR(-ENOENT);
+		}
+	}
+
+	return tunnel;
+}
+
 /* connect() handler. Attach a PPPoX socket to a tunnel UDP socket
  */
 static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
@@ -664,7 +723,6 @@
 	struct pppol2tp_session *ps;
 	struct l2tp_session_cfg cfg = { 0, };
 	bool drop_refcnt = false;
-	bool drop_tunnel = false;
 	bool new_session = false;
 	bool new_tunnel = false;
 	int error;
@@ -672,6 +730,14 @@
 	error = pppol2tp_sockaddr_get_info(uservaddr, sockaddr_len, &info);
 	if (error < 0)
 		return error;
+
+	/* Don't bind if tunnel_id is 0 */
+	if (!info.tunnel_id)
+		return -EINVAL;
+
+	tunnel = pppol2tp_tunnel_get(sock_net(sk), &info, &new_tunnel);
+	if (IS_ERR(tunnel))
+		return PTR_ERR(tunnel);
 
 	lock_sock(sk);
 
@@ -684,62 +750,6 @@
 	error = -EALREADY;
 	if (sk->sk_user_data)
 		goto end; /* socket is already attached */
-
-	/* Don't bind if tunnel_id is 0 */
-	error = -EINVAL;
-	if (!info.tunnel_id)
-		goto end;
-
-	tunnel = l2tp_tunnel_get(sock_net(sk), info.tunnel_id);
-	if (tunnel)
-		drop_tunnel = true;
-
-	/* Special case: create tunnel context if session_id and
-	 * peer_session_id is 0. Otherwise look up tunnel using supplied
-	 * tunnel id.
-	 */
-	if (!info.session_id && !info.peer_session_id) {
-		if (!tunnel) {
-			struct l2tp_tunnel_cfg tcfg = {
-				.encap = L2TP_ENCAPTYPE_UDP,
-			};
-
-			/* Prevent l2tp_tunnel_register() from trying to set up
-			 * a kernel socket.
-			 */
-			if (info.fd < 0) {
-				error = -EBADF;
-				goto end;
-			}
-
-			error = l2tp_tunnel_create(info.fd,
-						   info.version,
-						   info.tunnel_id,
-						   info.peer_tunnel_id, &tcfg,
-						   &tunnel);
-			if (error < 0)
-				goto end;
-
-			l2tp_tunnel_inc_refcount(tunnel);
-			error = l2tp_tunnel_register(tunnel, sock_net(sk),
-						     &tcfg);
-			if (error < 0) {
-				kfree(tunnel);
-				goto end;
-			}
-			drop_tunnel = true;
-			new_tunnel = true;
-		}
-	} else {
-		/* Error if we can't find the tunnel */
-		error = -ENOENT;
-		if (!tunnel)
-			goto end;
-
-		/* Error if socket is not prepped */
-		if (!tunnel->sock)
-			goto end;
-	}
 
 	if (tunnel->peer_tunnel_id == 0)
 		tunnel->peer_tunnel_id = info.peer_tunnel_id;
@@ -841,8 +851,7 @@
 	}
 	if (drop_refcnt)
 		l2tp_session_dec_refcount(session);
-	if (drop_tunnel)
-		l2tp_tunnel_dec_refcount(tunnel);
+	l2tp_tunnel_dec_refcount(tunnel);
 	release_sock(sk);
 
 	return error;
diff --git a/kernel/net/llc/af_llc.c b/kernel/net/llc/af_llc.c
index 99a37c4..01e2669 100644
--- a/kernel/net/llc/af_llc.c
+++ b/kernel/net/llc/af_llc.c
@@ -582,7 +582,8 @@
 
 	add_wait_queue(sk_sleep(sk), &wait);
 	while (1) {
-		if (sk_wait_event(sk, &timeout, sk->sk_state == TCP_CLOSE, &wait))
+		if (sk_wait_event(sk, &timeout,
+				  READ_ONCE(sk->sk_state) == TCP_CLOSE, &wait))
 			break;
 		rc = -ERESTARTSYS;
 		if (signal_pending(current))
@@ -602,7 +603,8 @@
 
 	add_wait_queue(sk_sleep(sk), &wait);
 	while (1) {
-		if (sk_wait_event(sk, &timeout, sk->sk_state != TCP_SYN_SENT, &wait))
+		if (sk_wait_event(sk, &timeout,
+				  READ_ONCE(sk->sk_state) != TCP_SYN_SENT, &wait))
 			break;
 		if (signal_pending(current) || !timeout)
 			break;
@@ -621,7 +623,7 @@
 	while (1) {
 		rc = 0;
 		if (sk_wait_event(sk, &timeout,
-				  (sk->sk_shutdown & RCV_SHUTDOWN) ||
+				  (READ_ONCE(sk->sk_shutdown) & RCV_SHUTDOWN) ||
 				  (!llc_data_accept_state(llc->state) &&
 				   !llc->remote_busy_flag &&
 				   !llc->p_flag), &wait))
diff --git a/kernel/net/llc/llc_input.c b/kernel/net/llc/llc_input.c
index c309b72..7cac441 100644
--- a/kernel/net/llc/llc_input.c
+++ b/kernel/net/llc/llc_input.c
@@ -163,9 +163,6 @@
 	void (*sta_handler)(struct sk_buff *skb);
 	void (*sap_handler)(struct llc_sap *sap, struct sk_buff *skb);
 
-	if (!net_eq(dev_net(dev), &init_net))
-		goto drop;
-
 	/*
 	 * When the interface is in promisc. mode, drop all the crap that it
 	 * receives, do not try to analyse it.
diff --git a/kernel/net/mac80211/agg-tx.c b/kernel/net/mac80211/agg-tx.c
index 4b4ab19..92e5812 100644
--- a/kernel/net/mac80211/agg-tx.c
+++ b/kernel/net/mac80211/agg-tx.c
@@ -491,7 +491,7 @@
 {
 	struct tid_ampdu_tx *tid_tx;
 	struct ieee80211_local *local = sta->local;
-	struct ieee80211_sub_if_data *sdata = sta->sdata;
+	struct ieee80211_sub_if_data *sdata;
 	struct ieee80211_ampdu_params params = {
 		.sta = &sta->sta,
 		.action = IEEE80211_AMPDU_TX_START,
@@ -521,6 +521,7 @@
 	 */
 	synchronize_net();
 
+	sdata = sta->sdata;
 	params.ssn = sta->tid_seq[tid] >> 4;
 	ret = drv_ampdu_action(local, sdata, &params);
 	tid_tx->ssn = params.ssn;
@@ -534,6 +535,9 @@
 		 */
 		set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state);
 	} else if (ret) {
+		if (!sdata)
+			return;
+
 		ht_dbg(sdata,
 		       "BA request denied - HW unavailable for %pM tid %d\n",
 		       sta->sta.addr, tid);
diff --git a/kernel/net/mac80211/driver-ops.c b/kernel/net/mac80211/driver-ops.c
index 48322e4..120bd9c 100644
--- a/kernel/net/mac80211/driver-ops.c
+++ b/kernel/net/mac80211/driver-ops.c
@@ -331,6 +331,9 @@
 
 	might_sleep();
 
+	if (!sdata)
+		return -EIO;
+
 	sdata = get_bss_sdata(sdata);
 	if (!check_sdata_in_driver(sdata))
 		return -EIO;
diff --git a/kernel/net/mac80211/ieee80211_i.h b/kernel/net/mac80211/ieee80211_i.h
index 63499db..bd349ae 100644
--- a/kernel/net/mac80211/ieee80211_i.h
+++ b/kernel/net/mac80211/ieee80211_i.h
@@ -644,6 +644,26 @@
 	struct cfg80211_csa_settings settings;
 };
 
+/**
+ * struct mesh_table
+ *
+ * @known_gates: list of known mesh gates and their mpaths by the station. The
+ * gate's mpath may or may not be resolved and active.
+ * @gates_lock: protects updates to known_gates
+ * @rhead: the rhashtable containing struct mesh_paths, keyed by dest addr
+ * @walk_head: linked list containing all mesh_path objects
+ * @walk_lock: lock protecting walk_head
+ * @entries: number of entries in the table
+ */
+struct mesh_table {
+	struct hlist_head known_gates;
+	spinlock_t gates_lock;
+	struct rhashtable rhead;
+	struct hlist_head walk_head;
+	spinlock_t walk_lock;
+	atomic_t entries;		/* Up to MAX_MESH_NEIGHBOURS */
+};
+
 struct ieee80211_if_mesh {
 	struct timer_list housekeeping_timer;
 	struct timer_list mesh_path_timer;
@@ -718,8 +738,8 @@
 	/* offset from skb->data while building IE */
 	int meshconf_offset;
 
-	struct mesh_table *mesh_paths;
-	struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */
+	struct mesh_table mesh_paths;
+	struct mesh_table mpp_paths; /* Store paths for MPP&MAP */
 	int mesh_paths_generation;
 	int mpp_paths_generation;
 };
diff --git a/kernel/net/mac80211/mesh.h b/kernel/net/mac80211/mesh.h
index 40492d1..b2b717a 100644
--- a/kernel/net/mac80211/mesh.h
+++ b/kernel/net/mac80211/mesh.h
@@ -127,26 +127,6 @@
 	u32 path_change_count;
 };
 
-/**
- * struct mesh_table
- *
- * @known_gates: list of known mesh gates and their mpaths by the station. The
- * gate's mpath may or may not be resolved and active.
- * @gates_lock: protects updates to known_gates
- * @rhead: the rhashtable containing struct mesh_paths, keyed by dest addr
- * @walk_head: linked list containging all mesh_path objects
- * @walk_lock: lock protecting walk_head
- * @entries: number of entries in the table
- */
-struct mesh_table {
-	struct hlist_head known_gates;
-	spinlock_t gates_lock;
-	struct rhashtable rhead;
-	struct hlist_head walk_head;
-	spinlock_t walk_lock;
-	atomic_t entries;		/* Up to MAX_MESH_NEIGHBOURS */
-};
-
 /* Recent multicast cache */
 /* RMC_BUCKETS must be a power of 2, maximum 256 */
 #define RMC_BUCKETS		256
@@ -308,7 +288,7 @@
 void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta);
 void mesh_path_flush_pending(struct mesh_path *mpath);
 void mesh_path_tx_pending(struct mesh_path *mpath);
-int mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata);
+void mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata);
 void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata);
 int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr);
 void mesh_path_timer(struct timer_list *t);
diff --git a/kernel/net/mac80211/mesh_pathtbl.c b/kernel/net/mac80211/mesh_pathtbl.c
index c2b051e..d936ef0 100644
--- a/kernel/net/mac80211/mesh_pathtbl.c
+++ b/kernel/net/mac80211/mesh_pathtbl.c
@@ -47,32 +47,24 @@
 	mesh_path_free_rcu(tbl, mpath);
 }
 
-static struct mesh_table *mesh_table_alloc(void)
+static void mesh_table_init(struct mesh_table *tbl)
 {
-	struct mesh_table *newtbl;
+	INIT_HLIST_HEAD(&tbl->known_gates);
+	INIT_HLIST_HEAD(&tbl->walk_head);
+	atomic_set(&tbl->entries,  0);
+	spin_lock_init(&tbl->gates_lock);
+	spin_lock_init(&tbl->walk_lock);
 
-	newtbl = kmalloc(sizeof(struct mesh_table), GFP_ATOMIC);
-	if (!newtbl)
-		return NULL;
-
-	INIT_HLIST_HEAD(&newtbl->known_gates);
-	INIT_HLIST_HEAD(&newtbl->walk_head);
-	atomic_set(&newtbl->entries,  0);
-	spin_lock_init(&newtbl->gates_lock);
-	spin_lock_init(&newtbl->walk_lock);
-	if (rhashtable_init(&newtbl->rhead, &mesh_rht_params)) {
-		kfree(newtbl);
-		return NULL;
-	}
-
-	return newtbl;
+	/* rhashtable_init() may fail only in case of wrong
+	 * mesh_rht_params
+	 */
+	WARN_ON(rhashtable_init(&tbl->rhead, &mesh_rht_params));
 }
 
 static void mesh_table_free(struct mesh_table *tbl)
 {
 	rhashtable_free_and_destroy(&tbl->rhead,
 				    mesh_path_rht_free, tbl);
-	kfree(tbl);
 }
 
 /**
@@ -238,13 +230,13 @@
 struct mesh_path *
 mesh_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst)
 {
-	return mpath_lookup(sdata->u.mesh.mesh_paths, dst, sdata);
+	return mpath_lookup(&sdata->u.mesh.mesh_paths, dst, sdata);
 }
 
 struct mesh_path *
 mpp_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst)
 {
-	return mpath_lookup(sdata->u.mesh.mpp_paths, dst, sdata);
+	return mpath_lookup(&sdata->u.mesh.mpp_paths, dst, sdata);
 }
 
 static struct mesh_path *
@@ -281,7 +273,7 @@
 struct mesh_path *
 mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
 {
-	return __mesh_path_lookup_by_idx(sdata->u.mesh.mesh_paths, idx);
+	return __mesh_path_lookup_by_idx(&sdata->u.mesh.mesh_paths, idx);
 }
 
 /**
@@ -296,7 +288,7 @@
 struct mesh_path *
 mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
 {
-	return __mesh_path_lookup_by_idx(sdata->u.mesh.mpp_paths, idx);
+	return __mesh_path_lookup_by_idx(&sdata->u.mesh.mpp_paths, idx);
 }
 
 /**
@@ -309,7 +301,7 @@
 	int err;
 
 	rcu_read_lock();
-	tbl = mpath->sdata->u.mesh.mesh_paths;
+	tbl = &mpath->sdata->u.mesh.mesh_paths;
 
 	spin_lock_bh(&mpath->state_lock);
 	if (mpath->is_gate) {
@@ -418,7 +410,7 @@
 	if (!new_mpath)
 		return ERR_PTR(-ENOMEM);
 
-	tbl = sdata->u.mesh.mesh_paths;
+	tbl = &sdata->u.mesh.mesh_paths;
 	spin_lock_bh(&tbl->walk_lock);
 	mpath = rhashtable_lookup_get_insert_fast(&tbl->rhead,
 						  &new_mpath->rhash,
@@ -460,7 +452,7 @@
 		return -ENOMEM;
 
 	memcpy(new_mpath->mpp, mpp, ETH_ALEN);
-	tbl = sdata->u.mesh.mpp_paths;
+	tbl = &sdata->u.mesh.mpp_paths;
 
 	spin_lock_bh(&tbl->walk_lock);
 	ret = rhashtable_lookup_insert_fast(&tbl->rhead,
@@ -489,7 +481,7 @@
 void mesh_plink_broken(struct sta_info *sta)
 {
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
-	struct mesh_table *tbl = sdata->u.mesh.mesh_paths;
+	struct mesh_table *tbl = &sdata->u.mesh.mesh_paths;
 	static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 	struct mesh_path *mpath;
 
@@ -548,7 +540,7 @@
 void mesh_path_flush_by_nexthop(struct sta_info *sta)
 {
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
-	struct mesh_table *tbl = sdata->u.mesh.mesh_paths;
+	struct mesh_table *tbl = &sdata->u.mesh.mesh_paths;
 	struct mesh_path *mpath;
 	struct hlist_node *n;
 
@@ -563,7 +555,7 @@
 static void mpp_flush_by_proxy(struct ieee80211_sub_if_data *sdata,
 			       const u8 *proxy)
 {
-	struct mesh_table *tbl = sdata->u.mesh.mpp_paths;
+	struct mesh_table *tbl = &sdata->u.mesh.mpp_paths;
 	struct mesh_path *mpath;
 	struct hlist_node *n;
 
@@ -597,8 +589,8 @@
  */
 void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
 {
-	table_flush_by_iface(sdata->u.mesh.mesh_paths);
-	table_flush_by_iface(sdata->u.mesh.mpp_paths);
+	table_flush_by_iface(&sdata->u.mesh.mesh_paths);
+	table_flush_by_iface(&sdata->u.mesh.mpp_paths);
 }
 
 /**
@@ -644,7 +636,7 @@
 	/* flush relevant mpp entries first */
 	mpp_flush_by_proxy(sdata, addr);
 
-	err = table_path_del(sdata->u.mesh.mesh_paths, sdata, addr);
+	err = table_path_del(&sdata->u.mesh.mesh_paths, sdata, addr);
 	sdata->u.mesh.mesh_paths_generation++;
 	return err;
 }
@@ -682,7 +674,7 @@
 	struct mesh_path *gate;
 	bool copy = false;
 
-	tbl = sdata->u.mesh.mesh_paths;
+	tbl = &sdata->u.mesh.mesh_paths;
 
 	rcu_read_lock();
 	hlist_for_each_entry_rcu(gate, &tbl->known_gates, gate_list) {
@@ -762,29 +754,10 @@
 	mesh_path_tx_pending(mpath);
 }
 
-int mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata)
+void mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata)
 {
-	struct mesh_table *tbl_path, *tbl_mpp;
-	int ret;
-
-	tbl_path = mesh_table_alloc();
-	if (!tbl_path)
-		return -ENOMEM;
-
-	tbl_mpp = mesh_table_alloc();
-	if (!tbl_mpp) {
-		ret = -ENOMEM;
-		goto free_path;
-	}
-
-	sdata->u.mesh.mesh_paths = tbl_path;
-	sdata->u.mesh.mpp_paths = tbl_mpp;
-
-	return 0;
-
-free_path:
-	mesh_table_free(tbl_path);
-	return ret;
+	mesh_table_init(&sdata->u.mesh.mesh_paths);
+	mesh_table_init(&sdata->u.mesh.mpp_paths);
 }
 
 static
@@ -806,12 +779,12 @@
 
 void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
 {
-	mesh_path_tbl_expire(sdata, sdata->u.mesh.mesh_paths);
-	mesh_path_tbl_expire(sdata, sdata->u.mesh.mpp_paths);
+	mesh_path_tbl_expire(sdata, &sdata->u.mesh.mesh_paths);
+	mesh_path_tbl_expire(sdata, &sdata->u.mesh.mpp_paths);
 }
 
 void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata)
 {
-	mesh_table_free(sdata->u.mesh.mesh_paths);
-	mesh_table_free(sdata->u.mesh.mpp_paths);
+	mesh_table_free(&sdata->u.mesh.mesh_paths);
+	mesh_table_free(&sdata->u.mesh.mpp_paths);
 }
diff --git a/kernel/net/mac80211/sta_info.c b/kernel/net/mac80211/sta_info.c
index cee39ae..2e84360 100644
--- a/kernel/net/mac80211/sta_info.c
+++ b/kernel/net/mac80211/sta_info.c
@@ -1040,7 +1040,8 @@
 	list_del_rcu(&sta->list);
 	sta->removed = true;
 
-	drv_sta_pre_rcu_remove(local, sta->sdata, sta);
+	if (sta->uploaded)
+		drv_sta_pre_rcu_remove(local, sta->sdata, sta);
 
 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
 	    rcu_access_pointer(sdata->u.vlan.sta) == sta)
@@ -2159,7 +2160,7 @@
 
 static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
 {
-	u16 rate = READ_ONCE(sta_get_last_rx_stats(sta)->last_rate);
+	u32 rate = READ_ONCE(sta_get_last_rx_stats(sta)->last_rate);
 
 	if (rate == STA_STATS_RATE_INVALID)
 		return -EINVAL;
diff --git a/kernel/net/mac80211/trace.h b/kernel/net/mac80211/trace.h
index 8972390..5ddaa7c 100644
--- a/kernel/net/mac80211/trace.h
+++ b/kernel/net/mac80211/trace.h
@@ -67,7 +67,7 @@
 			__entry->min_freq_offset = (c)->chan ? (c)->chan->freq_offset : 0;	\
 			__entry->min_chan_width = (c)->width;				\
 			__entry->min_center_freq1 = (c)->center_freq1;			\
-			__entry->freq1_offset = (c)->freq1_offset;			\
+			__entry->min_freq1_offset = (c)->freq1_offset;			\
 			__entry->min_center_freq2 = (c)->center_freq2;
 #define MIN_CHANDEF_PR_FMT	" min_control:%d.%03d MHz min_width:%d min_center: %d.%03d/%d MHz"
 #define MIN_CHANDEF_PR_ARG	__entry->min_control_freq, __entry->min_freq_offset,	\
diff --git a/kernel/net/mac80211/wme.c b/kernel/net/mac80211/wme.c
index b9404b0..eb79f68 100644
--- a/kernel/net/mac80211/wme.c
+++ b/kernel/net/mac80211/wme.c
@@ -141,12 +141,14 @@
 u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
 			     struct sta_info *sta, struct sk_buff *skb)
 {
+	const struct ethhdr *eth = (void *)skb->data;
 	struct mac80211_qos_map *qos_map;
 	bool qos;
 
 	/* all mesh/ocb stations are required to support WME */
-	if (sta && (sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
-		    sdata->vif.type == NL80211_IFTYPE_OCB))
+	if ((sdata->vif.type == NL80211_IFTYPE_MESH_POINT &&
+	    !is_multicast_ether_addr(eth->h_dest)) ||
+	    (sdata->vif.type == NL80211_IFTYPE_OCB && sta))
 		qos = true;
 	else if (sta)
 		qos = sta->sta.wme;
diff --git a/kernel/net/mpls/af_mpls.c b/kernel/net/mpls/af_mpls.c
index 7239814..1dcbdab 100644
--- a/kernel/net/mpls/af_mpls.c
+++ b/kernel/net/mpls/af_mpls.c
@@ -1427,6 +1427,7 @@
 free:
 	kfree(table);
 out:
+	mdev->sysctl = NULL;
 	return -ENOBUFS;
 }
 
@@ -1436,6 +1437,9 @@
 	struct net *net = dev_net(dev);
 	struct ctl_table *table;
 
+	if (!mdev->sysctl)
+		return;
+
 	table = mdev->sysctl->ctl_table_arg;
 	unregister_net_sysctl_table(mdev->sysctl);
 	kfree(table);
diff --git a/kernel/net/mptcp/protocol.c b/kernel/net/mptcp/protocol.c
index e61c858..72d944e 100644
--- a/kernel/net/mptcp/protocol.c
+++ b/kernel/net/mptcp/protocol.c
@@ -2863,12 +2863,6 @@
 
 static struct proto mptcp_v6_prot;
 
-static void mptcp_v6_destroy(struct sock *sk)
-{
-	mptcp_destroy(sk);
-	inet6_destroy_sock(sk);
-}
-
 static struct inet_protosw mptcp_v6_protosw = {
 	.type		= SOCK_STREAM,
 	.protocol	= IPPROTO_MPTCP,
@@ -2884,7 +2878,6 @@
 	mptcp_v6_prot = mptcp_prot;
 	strcpy(mptcp_v6_prot.name, "MPTCPv6");
 	mptcp_v6_prot.slab = NULL;
-	mptcp_v6_prot.destroy = mptcp_v6_destroy;
 	mptcp_v6_prot.obj_size = sizeof(struct mptcp6_sock);
 
 	err = proto_register(&mptcp_v6_prot, 1);
diff --git a/kernel/net/mptcp/subflow.c b/kernel/net/mptcp/subflow.c
index 2e92384..6075192 100644
--- a/kernel/net/mptcp/subflow.c
+++ b/kernel/net/mptcp/subflow.c
@@ -40,7 +40,6 @@
 		sock_put((struct sock *)subflow_req->msk);
 
 	mptcp_token_destroy_request(req);
-	tcp_request_sock_ops.destructor(req);
 }
 
 static void subflow_generate_hmac(u64 key1, u64 key2, u32 nonce1, u32 nonce2,
@@ -276,7 +275,6 @@
 	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
 	struct sock *sk = subflow->conn;
 
-	tcp_set_state(ssk, TCP_CLOSE);
 	tcp_send_active_reset(ssk, GFP_ATOMIC);
 	tcp_done(ssk);
 	if (!test_and_set_bit(MPTCP_WORK_CLOSE_SUBFLOW, &mptcp_sk(sk)->flags) &&
@@ -359,9 +357,8 @@
 	mptcp_subflow_reset(sk);
 }
 
-struct request_sock_ops mptcp_subflow_request_sock_ops;
-EXPORT_SYMBOL_GPL(mptcp_subflow_request_sock_ops);
-static struct tcp_request_sock_ops subflow_request_sock_ipv4_ops;
+static struct request_sock_ops mptcp_subflow_v4_request_sock_ops __ro_after_init;
+static struct tcp_request_sock_ops subflow_request_sock_ipv4_ops __ro_after_init;
 
 static int subflow_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 {
@@ -373,7 +370,7 @@
 	if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
 		goto drop;
 
-	return tcp_conn_request(&mptcp_subflow_request_sock_ops,
+	return tcp_conn_request(&mptcp_subflow_v4_request_sock_ops,
 				&subflow_request_sock_ipv4_ops,
 				sk, skb);
 drop:
@@ -381,10 +378,17 @@
 	return 0;
 }
 
+static void subflow_v4_req_destructor(struct request_sock *req)
+{
+	subflow_req_destructor(req);
+	tcp_request_sock_ops.destructor(req);
+}
+
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
-static struct tcp_request_sock_ops subflow_request_sock_ipv6_ops;
-static struct inet_connection_sock_af_ops subflow_v6_specific;
-static struct inet_connection_sock_af_ops subflow_v6m_specific;
+static struct request_sock_ops mptcp_subflow_v6_request_sock_ops __ro_after_init;
+static struct tcp_request_sock_ops subflow_request_sock_ipv6_ops __ro_after_init;
+static struct inet_connection_sock_af_ops subflow_v6_specific __ro_after_init;
+static struct inet_connection_sock_af_ops subflow_v6m_specific __ro_after_init;
 
 static int subflow_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 {
@@ -403,14 +407,35 @@
 		return 0;
 	}
 
-	return tcp_conn_request(&mptcp_subflow_request_sock_ops,
+	return tcp_conn_request(&mptcp_subflow_v6_request_sock_ops,
 				&subflow_request_sock_ipv6_ops, sk, skb);
 
 drop:
 	tcp_listendrop(sk);
 	return 0; /* don't send reset */
 }
+
+static void subflow_v6_req_destructor(struct request_sock *req)
+{
+	subflow_req_destructor(req);
+	tcp6_request_sock_ops.destructor(req);
+}
 #endif
+
+struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
+					       struct sock *sk_listener,
+					       bool attach_listener)
+{
+	if (ops->family == AF_INET)
+		ops = &mptcp_subflow_v4_request_sock_ops;
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	else if (ops->family == AF_INET6)
+		ops = &mptcp_subflow_v6_request_sock_ops;
+#endif
+
+	return inet_reqsk_alloc(ops, sk_listener, attach_listener);
+}
+EXPORT_SYMBOL(mptcp_subflow_reqsk_alloc);
 
 /* validate hmac received in third ACK */
 static bool subflow_hmac_valid(const struct request_sock *req,
@@ -636,7 +661,7 @@
 	return child;
 }
 
-static struct inet_connection_sock_af_ops subflow_specific;
+static struct inet_connection_sock_af_ops subflow_specific __ro_after_init;
 
 enum mapping_status {
 	MAPPING_OK,
@@ -1017,7 +1042,7 @@
 	}
 }
 
-static struct inet_connection_sock_af_ops *
+static const struct inet_connection_sock_af_ops *
 subflow_default_af_ops(struct sock *sk)
 {
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
@@ -1032,7 +1057,7 @@
 {
 	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
 	struct inet_connection_sock *icsk = inet_csk(sk);
-	struct inet_connection_sock_af_ops *target;
+	const struct inet_connection_sock_af_ops *target;
 
 	target = mapped ? &subflow_v6m_specific : subflow_default_af_ops(sk);
 
@@ -1377,7 +1402,6 @@
 static int subflow_ops_init(struct request_sock_ops *subflow_ops)
 {
 	subflow_ops->obj_size = sizeof(struct mptcp_subflow_request_sock);
-	subflow_ops->slab_name = "request_sock_subflow";
 
 	subflow_ops->slab = kmem_cache_create(subflow_ops->slab_name,
 					      subflow_ops->obj_size, 0,
@@ -1387,16 +1411,17 @@
 	if (!subflow_ops->slab)
 		return -ENOMEM;
 
-	subflow_ops->destructor = subflow_req_destructor;
-
 	return 0;
 }
 
 void __init mptcp_subflow_init(void)
 {
-	mptcp_subflow_request_sock_ops = tcp_request_sock_ops;
-	if (subflow_ops_init(&mptcp_subflow_request_sock_ops) != 0)
-		panic("MPTCP: failed to init subflow request sock ops\n");
+	mptcp_subflow_v4_request_sock_ops = tcp_request_sock_ops;
+	mptcp_subflow_v4_request_sock_ops.slab_name = "request_sock_subflow_v4";
+	mptcp_subflow_v4_request_sock_ops.destructor = subflow_v4_req_destructor;
+
+	if (subflow_ops_init(&mptcp_subflow_v4_request_sock_ops) != 0)
+		panic("MPTCP: failed to init subflow v4 request sock ops\n");
 
 	subflow_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops;
 	subflow_request_sock_ipv4_ops.init_req = subflow_v4_init_req;
@@ -1407,6 +1432,20 @@
 	subflow_specific.sk_rx_dst_set = subflow_finish_connect;
 
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	/* In struct mptcp_subflow_request_sock, we assume the TCP request sock
+	 * structures for v4 and v6 have the same size. It should not changed in
+	 * the future but better to make sure to be warned if it is no longer
+	 * the case.
+	 */
+	BUILD_BUG_ON(sizeof(struct tcp_request_sock) != sizeof(struct tcp6_request_sock));
+
+	mptcp_subflow_v6_request_sock_ops = tcp6_request_sock_ops;
+	mptcp_subflow_v6_request_sock_ops.slab_name = "request_sock_subflow_v6";
+	mptcp_subflow_v6_request_sock_ops.destructor = subflow_v6_req_destructor;
+
+	if (subflow_ops_init(&mptcp_subflow_v6_request_sock_ops) != 0)
+		panic("MPTCP: failed to init subflow v6 request sock ops\n");
+
 	subflow_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops;
 	subflow_request_sock_ipv6_ops.init_req = subflow_v6_init_req;
 
diff --git a/kernel/net/ncsi/ncsi-aen.c b/kernel/net/ncsi/ncsi-aen.c
index b635c19..f8854bf 100644
--- a/kernel/net/ncsi/ncsi-aen.c
+++ b/kernel/net/ncsi/ncsi-aen.c
@@ -89,6 +89,11 @@
 	if ((had_link == has_link) || chained)
 		return 0;
 
+	if (had_link)
+		netif_carrier_off(ndp->ndev.dev);
+	else
+		netif_carrier_on(ndp->ndev.dev);
+
 	if (!ndp->multi_package && !nc->package->multi_channel) {
 		if (had_link) {
 			ndp->flags |= NCSI_DEV_RESHUFFLE;
@@ -165,6 +170,7 @@
 	nc->state = NCSI_CHANNEL_INACTIVE;
 	list_add_tail_rcu(&nc->link, &ndp->channel_queue);
 	spin_unlock_irqrestore(&ndp->lock, flags);
+	nc->modes[NCSI_MODE_TX_ENABLE].enable = 0;
 
 	return ncsi_process_next_channel(ndp);
 }
diff --git a/kernel/net/netfilter/core.c b/kernel/net/netfilter/core.c
index 60332fd..d0c7c39 100644
--- a/kernel/net/netfilter/core.c
+++ b/kernel/net/netfilter/core.c
@@ -300,12 +300,6 @@
 		if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv6) <= hooknum))
 			return NULL;
 		return net->nf.hooks_ipv6 + hooknum;
-#if IS_ENABLED(CONFIG_DECNET)
-	case NFPROTO_DECNET:
-		if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_decnet) <= hooknum))
-			return NULL;
-		return net->nf.hooks_decnet + hooknum;
-#endif
 	default:
 		WARN_ON_ONCE(1);
 		return NULL;
@@ -674,9 +668,11 @@
 
 	rcu_read_lock();
 	ct_hook = rcu_dereference(nf_ct_hook);
-	BUG_ON(ct_hook == NULL);
-	ct_hook->destroy(nfct);
+	if (ct_hook)
+		ct_hook->destroy(nfct);
 	rcu_read_unlock();
+
+	WARN_ON(!ct_hook);
 }
 EXPORT_SYMBOL(nf_conntrack_destroy);
 
@@ -722,10 +718,6 @@
 #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
 	__netfilter_net_init(net->nf.hooks_bridge, ARRAY_SIZE(net->nf.hooks_bridge));
 #endif
-#if IS_ENABLED(CONFIG_DECNET)
-	__netfilter_net_init(net->nf.hooks_decnet, ARRAY_SIZE(net->nf.hooks_decnet));
-#endif
-
 #ifdef CONFIG_PROC_FS
 	net->nf.proc_netfilter = proc_net_mkdir(net, "netfilter",
 						net->proc_net);
diff --git a/kernel/net/netfilter/ipset/ip_set_bitmap_ip.c b/kernel/net/netfilter/ipset/ip_set_bitmap_ip.c
index a8ce04a..e4fa00a 100644
--- a/kernel/net/netfilter/ipset/ip_set_bitmap_ip.c
+++ b/kernel/net/netfilter/ipset/ip_set_bitmap_ip.c
@@ -308,8 +308,8 @@
 			return -IPSET_ERR_BITMAP_RANGE;
 
 		pr_debug("mask_bits %u, netmask %u\n", mask_bits, netmask);
-		hosts = 2 << (32 - netmask - 1);
-		elements = 2 << (netmask - mask_bits - 1);
+		hosts = 2U << (32 - netmask - 1);
+		elements = 2UL << (netmask - mask_bits - 1);
 	}
 	if (elements > IPSET_BITMAP_MAX_RANGE + 1)
 		return -IPSET_ERR_BITMAP_RANGE_SIZE;
diff --git a/kernel/net/netfilter/ipset/ip_set_core.c b/kernel/net/netfilter/ipset/ip_set_core.c
index c17a7dd..26613e3 100644
--- a/kernel/net/netfilter/ipset/ip_set_core.c
+++ b/kernel/net/netfilter/ipset/ip_set_core.c
@@ -683,6 +683,14 @@
  * a separate reference counter
  */
 static void
+__ip_set_get_netlink(struct ip_set *set)
+{
+	write_lock_bh(&ip_set_ref_lock);
+	set->ref_netlink++;
+	write_unlock_bh(&ip_set_ref_lock);
+}
+
+static void
 __ip_set_put_netlink(struct ip_set *set)
 {
 	write_lock_bh(&ip_set_ref_lock);
@@ -1704,13 +1712,22 @@
 	bool eexist = flags & IPSET_FLAG_EXIST, retried = false;
 
 	do {
+		if (retried) {
+			__ip_set_get_netlink(set);
+			nfnl_unlock(NFNL_SUBSYS_IPSET);
+			cond_resched();
+			nfnl_lock(NFNL_SUBSYS_IPSET);
+			__ip_set_put_netlink(set);
+		}
+
 		ip_set_lock(set);
 		ret = set->variant->uadt(set, tb, adt, &lineno, flags, retried);
 		ip_set_unlock(set);
 		retried = true;
-	} while (ret == -EAGAIN &&
-		 set->variant->resize &&
-		 (ret = set->variant->resize(set, retried)) == 0);
+	} while (ret == -ERANGE ||
+		 (ret == -EAGAIN &&
+		  set->variant->resize &&
+		  (ret = set->variant->resize(set, retried)) == 0));
 
 	if (!ret || (ret == -IPSET_ERR_EXIST && eexist))
 		return 0;
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ip.c b/kernel/net/netfilter/ipset/ip_set_hash_ip.c
index d7a81b2..8720dc3 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_ip.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_ip.c
@@ -97,11 +97,11 @@
 hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
 	      enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
 {
-	const struct hash_ip4 *h = set->data;
+	struct hash_ip4 *h = set->data;
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	struct hash_ip4_elem e = { 0 };
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
-	u32 ip = 0, ip_to = 0, hosts;
+	u32 ip = 0, ip_to = 0, hosts, i = 0;
 	int ret = 0;
 
 	if (tb[IPSET_ATTR_LINENO])
@@ -146,14 +146,14 @@
 
 	hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1);
 
-	/* 64bit division is not allowed on 32bit */
-	if (((u64)ip_to - ip + 1) >> (32 - h->netmask) > IPSET_MAX_RANGE)
-		return -ERANGE;
-
 	if (retried)
 		ip = ntohl(h->next.ip);
-	for (; ip <= ip_to;) {
+	for (; ip <= ip_to; i++) {
 		e.ip = htonl(ip);
+		if (i > IPSET_MAX_RANGE) {
+			hash_ip4_data_next(&h->next, &e);
+			return -ERANGE;
+		}
 		ret = adtfn(set, &e, &ext, &ext, flags);
 		if (ret && !ip_set_eexist(ret, flags))
 			return ret;
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ipmark.c b/kernel/net/netfilter/ipset/ip_set_hash_ipmark.c
index eefce34..cbb05cb 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_ipmark.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_ipmark.c
@@ -96,11 +96,11 @@
 hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
 		  enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
 {
-	const struct hash_ipmark4 *h = set->data;
+	struct hash_ipmark4 *h = set->data;
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	struct hash_ipmark4_elem e = { };
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
-	u32 ip, ip_to = 0;
+	u32 ip, ip_to = 0, i = 0;
 	int ret;
 
 	if (tb[IPSET_ATTR_LINENO])
@@ -147,13 +147,14 @@
 		ip_set_mask_from_to(ip, ip_to, cidr);
 	}
 
-	if (((u64)ip_to - ip + 1) > IPSET_MAX_RANGE)
-		return -ERANGE;
-
 	if (retried)
 		ip = ntohl(h->next.ip);
-	for (; ip <= ip_to; ip++) {
+	for (; ip <= ip_to; ip++, i++) {
 		e.ip = htonl(ip);
+		if (i > IPSET_MAX_RANGE) {
+			hash_ipmark4_data_next(&h->next, &e);
+			return -ERANGE;
+		}
 		ret = adtfn(set, &e, &ext, &ext, flags);
 
 		if (ret && !ip_set_eexist(ret, flags))
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ipport.c b/kernel/net/netfilter/ipset/ip_set_hash_ipport.c
index 4a54e9e..c560f78 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_ipport.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_ipport.c
@@ -104,11 +104,11 @@
 hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
 		  enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
 {
-	const struct hash_ipport4 *h = set->data;
+	struct hash_ipport4 *h = set->data;
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	struct hash_ipport4_elem e = { .ip = 0 };
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
-	u32 ip, ip_to = 0, p = 0, port, port_to;
+	u32 ip, ip_to = 0, p = 0, port, port_to, i = 0;
 	bool with_ports = false;
 	int ret;
 
@@ -172,17 +172,18 @@
 			swap(port, port_to);
 	}
 
-	if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
-		return -ERANGE;
-
 	if (retried)
 		ip = ntohl(h->next.ip);
 	for (; ip <= ip_to; ip++) {
 		p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
 						       : port;
-		for (; p <= port_to; p++) {
+		for (; p <= port_to; p++, i++) {
 			e.ip = htonl(ip);
 			e.port = htons(p);
+			if (i > IPSET_MAX_RANGE) {
+				hash_ipport4_data_next(&h->next, &e);
+				return -ERANGE;
+			}
 			ret = adtfn(set, &e, &ext, &ext, flags);
 
 			if (ret && !ip_set_eexist(ret, flags))
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c b/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c
index 09737de..b7eb8d1 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c
@@ -107,11 +107,11 @@
 hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
 		    enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
 {
-	const struct hash_ipportip4 *h = set->data;
+	struct hash_ipportip4 *h = set->data;
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	struct hash_ipportip4_elem e = { .ip = 0 };
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
-	u32 ip, ip_to = 0, p = 0, port, port_to;
+	u32 ip, ip_to = 0, p = 0, port, port_to, i = 0;
 	bool with_ports = false;
 	int ret;
 
@@ -179,17 +179,18 @@
 			swap(port, port_to);
 	}
 
-	if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
-		return -ERANGE;
-
 	if (retried)
 		ip = ntohl(h->next.ip);
 	for (; ip <= ip_to; ip++) {
 		p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
 						       : port;
-		for (; p <= port_to; p++) {
+		for (; p <= port_to; p++, i++) {
 			e.ip = htonl(ip);
 			e.port = htons(p);
+			if (i > IPSET_MAX_RANGE) {
+				hash_ipportip4_data_next(&h->next, &e);
+				return -ERANGE;
+			}
 			ret = adtfn(set, &e, &ext, &ext, flags);
 
 			if (ret && !ip_set_eexist(ret, flags))
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c b/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c
index 0268537..16c5641 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c
@@ -159,12 +159,12 @@
 hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 		     enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
 {
-	const struct hash_ipportnet4 *h = set->data;
+	struct hash_ipportnet4 *h = set->data;
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	struct hash_ipportnet4_elem e = { .cidr = HOST_MASK - 1 };
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
 	u32 ip = 0, ip_to = 0, p = 0, port, port_to;
-	u32 ip2_from = 0, ip2_to = 0, ip2;
+	u32 ip2_from = 0, ip2_to = 0, ip2, i = 0;
 	bool with_ports = false;
 	u8 cidr;
 	int ret;
@@ -252,9 +252,6 @@
 			swap(port, port_to);
 	}
 
-	if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
-		return -ERANGE;
-
 	ip2_to = ip2_from;
 	if (tb[IPSET_ATTR_IP2_TO]) {
 		ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to);
@@ -281,9 +278,15 @@
 		for (; p <= port_to; p++) {
 			e.port = htons(p);
 			do {
+				i++;
 				e.ip2 = htonl(ip2);
 				ip2 = ip_set_range_to_cidr(ip2, ip2_to, &cidr);
 				e.cidr = cidr - 1;
+				if (i > IPSET_MAX_RANGE) {
+					hash_ipportnet4_data_next(&h->next,
+								  &e);
+					return -ERANGE;
+				}
 				ret = adtfn(set, &e, &ext, &ext, flags);
 
 				if (ret && !ip_set_eexist(ret, flags))
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_net.c b/kernel/net/netfilter/ipset/ip_set_hash_net.c
index 9d1beaa..5ab5873 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_net.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_net.c
@@ -135,11 +135,11 @@
 hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
 	       enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
 {
-	const struct hash_net4 *h = set->data;
+	struct hash_net4 *h = set->data;
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	struct hash_net4_elem e = { .cidr = HOST_MASK };
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
-	u32 ip = 0, ip_to = 0, ipn, n = 0;
+	u32 ip = 0, ip_to = 0, i = 0;
 	int ret;
 
 	if (tb[IPSET_ATTR_LINENO])
@@ -187,19 +187,16 @@
 		if (ip + UINT_MAX == ip_to)
 			return -IPSET_ERR_HASH_RANGE;
 	}
-	ipn = ip;
-	do {
-		ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr);
-		n++;
-	} while (ipn++ < ip_to);
-
-	if (n > IPSET_MAX_RANGE)
-		return -ERANGE;
 
 	if (retried)
 		ip = ntohl(h->next.ip);
 	do {
+		i++;
 		e.ip = htonl(ip);
+		if (i > IPSET_MAX_RANGE) {
+			hash_net4_data_next(&h->next, &e);
+			return -ERANGE;
+		}
 		ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
 		ret = adtfn(set, &e, &ext, &ext, flags);
 		if (ret && !ip_set_eexist(ret, flags))
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_netiface.c b/kernel/net/netfilter/ipset/ip_set_hash_netiface.c
index c3ada9c..7ef2403 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_netiface.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -201,7 +201,7 @@
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	struct hash_netiface4_elem e = { .cidr = HOST_MASK, .elem = 1 };
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
-	u32 ip = 0, ip_to = 0, ipn, n = 0;
+	u32 ip = 0, ip_to = 0, i = 0;
 	int ret;
 
 	if (tb[IPSET_ATTR_LINENO])
@@ -255,19 +255,16 @@
 	} else {
 		ip_set_mask_from_to(ip, ip_to, e.cidr);
 	}
-	ipn = ip;
-	do {
-		ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr);
-		n++;
-	} while (ipn++ < ip_to);
-
-	if (n > IPSET_MAX_RANGE)
-		return -ERANGE;
 
 	if (retried)
 		ip = ntohl(h->next.ip);
 	do {
+		i++;
 		e.ip = htonl(ip);
+		if (i > IPSET_MAX_RANGE) {
+			hash_netiface4_data_next(&h->next, &e);
+			return -ERANGE;
+		}
 		ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
 		ret = adtfn(set, &e, &ext, &ext, flags);
 
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_netnet.c b/kernel/net/netfilter/ipset/ip_set_hash_netnet.c
index b1411bc..15f4b02 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_netnet.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_netnet.c
@@ -162,13 +162,12 @@
 hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 		  enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
 {
-	const struct hash_netnet4 *h = set->data;
+	struct hash_netnet4 *h = set->data;
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	struct hash_netnet4_elem e = { };
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
 	u32 ip = 0, ip_to = 0;
-	u32 ip2 = 0, ip2_from = 0, ip2_to = 0, ipn;
-	u64 n = 0, m = 0;
+	u32 ip2 = 0, ip2_from = 0, ip2_to = 0, i = 0;
 	int ret;
 
 	if (tb[IPSET_ATTR_LINENO])
@@ -244,19 +243,6 @@
 	} else {
 		ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]);
 	}
-	ipn = ip;
-	do {
-		ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr[0]);
-		n++;
-	} while (ipn++ < ip_to);
-	ipn = ip2_from;
-	do {
-		ipn = ip_set_range_to_cidr(ipn, ip2_to, &e.cidr[1]);
-		m++;
-	} while (ipn++ < ip2_to);
-
-	if (n*m > IPSET_MAX_RANGE)
-		return -ERANGE;
 
 	if (retried) {
 		ip = ntohl(h->next.ip[0]);
@@ -269,7 +255,12 @@
 		e.ip[0] = htonl(ip);
 		ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]);
 		do {
+			i++;
 			e.ip[1] = htonl(ip2);
+			if (i > IPSET_MAX_RANGE) {
+				hash_netnet4_data_next(&h->next, &e);
+				return -ERANGE;
+			}
 			ip2 = ip_set_range_to_cidr(ip2, ip2_to, &e.cidr[1]);
 			ret = adtfn(set, &e, &ext, &ext, flags);
 			if (ret && !ip_set_eexist(ret, flags))
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_netport.c b/kernel/net/netfilter/ipset/ip_set_hash_netport.c
index d26d135..e73ba50 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_netport.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_netport.c
@@ -153,12 +153,11 @@
 hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
 		   enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
 {
-	const struct hash_netport4 *h = set->data;
+	struct hash_netport4 *h = set->data;
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	struct hash_netport4_elem e = { .cidr = HOST_MASK - 1 };
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
-	u32 port, port_to, p = 0, ip = 0, ip_to = 0, ipn;
-	u64 n = 0;
+	u32 port, port_to, p = 0, ip = 0, ip_to = 0, i = 0;
 	bool with_ports = false;
 	u8 cidr;
 	int ret;
@@ -235,14 +234,6 @@
 	} else {
 		ip_set_mask_from_to(ip, ip_to, e.cidr + 1);
 	}
-	ipn = ip;
-	do {
-		ipn = ip_set_range_to_cidr(ipn, ip_to, &cidr);
-		n++;
-	} while (ipn++ < ip_to);
-
-	if (n*(port_to - port + 1) > IPSET_MAX_RANGE)
-		return -ERANGE;
 
 	if (retried) {
 		ip = ntohl(h->next.ip);
@@ -254,8 +245,12 @@
 		e.ip = htonl(ip);
 		ip = ip_set_range_to_cidr(ip, ip_to, &cidr);
 		e.cidr = cidr - 1;
-		for (; p <= port_to; p++) {
+		for (; p <= port_to; p++, i++) {
 			e.port = htons(p);
+			if (i > IPSET_MAX_RANGE) {
+				hash_netport4_data_next(&h->next, &e);
+				return -ERANGE;
+			}
 			ret = adtfn(set, &e, &ext, &ext, flags);
 			if (ret && !ip_set_eexist(ret, flags))
 				return ret;
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_netportnet.c b/kernel/net/netfilter/ipset/ip_set_hash_netportnet.c
index 6446f4f..b8ec2c4 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_netportnet.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_netportnet.c
@@ -35,6 +35,7 @@
 #define IP_SET_HASH_WITH_PROTO
 #define IP_SET_HASH_WITH_NETS
 #define IPSET_NET_COUNT 2
+#define IP_SET_HASH_WITH_NET0
 
 /* IPv4 variant */
 
@@ -172,17 +173,26 @@
 	return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
 }
 
+static u32
+hash_netportnet4_range_to_cidr(u32 from, u32 to, u8 *cidr)
+{
+	if (from == 0 && to == UINT_MAX) {
+		*cidr = 0;
+		return to;
+	}
+	return ip_set_range_to_cidr(from, to, cidr);
+}
+
 static int
 hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 		      enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
 {
-	const struct hash_netportnet4 *h = set->data;
+	struct hash_netportnet4 *h = set->data;
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	struct hash_netportnet4_elem e = { };
 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
 	u32 ip = 0, ip_to = 0, p = 0, port, port_to;
-	u32 ip2_from = 0, ip2_to = 0, ip2, ipn;
-	u64 n = 0, m = 0;
+	u32 ip2_from = 0, ip2_to = 0, ip2, i = 0;
 	bool with_ports = false;
 	int ret;
 
@@ -284,19 +294,6 @@
 	} else {
 		ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]);
 	}
-	ipn = ip;
-	do {
-		ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr[0]);
-		n++;
-	} while (ipn++ < ip_to);
-	ipn = ip2_from;
-	do {
-		ipn = ip_set_range_to_cidr(ipn, ip2_to, &e.cidr[1]);
-		m++;
-	} while (ipn++ < ip2_to);
-
-	if (n*m*(port_to - port + 1) > IPSET_MAX_RANGE)
-		return -ERANGE;
 
 	if (retried) {
 		ip = ntohl(h->next.ip[0]);
@@ -309,13 +306,19 @@
 
 	do {
 		e.ip[0] = htonl(ip);
-		ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]);
+		ip = hash_netportnet4_range_to_cidr(ip, ip_to, &e.cidr[0]);
 		for (; p <= port_to; p++) {
 			e.port = htons(p);
 			do {
+				i++;
 				e.ip[1] = htonl(ip2);
-				ip2 = ip_set_range_to_cidr(ip2, ip2_to,
-							   &e.cidr[1]);
+				if (i > IPSET_MAX_RANGE) {
+					hash_netportnet4_data_next(&h->next,
+								   &e);
+					return -ERANGE;
+				}
+				ip2 = hash_netportnet4_range_to_cidr(ip2,
+							ip2_to, &e.cidr[1]);
 				ret = adtfn(set, &e, &ext, &ext, flags);
 				if (ret && !ip_set_eexist(ret, flags))
 					return ret;
diff --git a/kernel/net/netfilter/ipvs/ip_vs_ctl.c b/kernel/net/netfilter/ipvs/ip_vs_ctl.c
index 29ec3ef..d0b64c3 100644
--- a/kernel/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/kernel/net/netfilter/ipvs/ip_vs_ctl.c
@@ -1802,6 +1802,7 @@
 proc_do_sync_threshold(struct ctl_table *table, int write,
 		       void *buffer, size_t *lenp, loff_t *ppos)
 {
+	struct netns_ipvs *ipvs = table->extra2;
 	int *valp = table->data;
 	int val[2];
 	int rc;
@@ -1811,6 +1812,7 @@
 		.mode = table->mode,
 	};
 
+	mutex_lock(&ipvs->sync_mutex);
 	memcpy(val, valp, sizeof(val));
 	rc = proc_dointvec(&tmp, write, buffer, lenp, ppos);
 	if (write) {
@@ -1820,6 +1822,7 @@
 		else
 			memcpy(valp, val, sizeof(val));
 	}
+	mutex_unlock(&ipvs->sync_mutex);
 	return rc;
 }
 
@@ -4077,6 +4080,7 @@
 	ipvs->sysctl_sync_threshold[0] = DEFAULT_SYNC_THRESHOLD;
 	ipvs->sysctl_sync_threshold[1] = DEFAULT_SYNC_PERIOD;
 	tbl[idx].data = &ipvs->sysctl_sync_threshold;
+	tbl[idx].extra2 = ipvs;
 	tbl[idx++].maxlen = sizeof(ipvs->sysctl_sync_threshold);
 	ipvs->sysctl_sync_refresh_period = DEFAULT_SYNC_REFRESH_PERIOD;
 	tbl[idx++].data = &ipvs->sysctl_sync_refresh_period;
diff --git a/kernel/net/netfilter/ipvs/ip_vs_sync.c b/kernel/net/netfilter/ipvs/ip_vs_sync.c
index daab857..e45ffa7 100644
--- a/kernel/net/netfilter/ipvs/ip_vs_sync.c
+++ b/kernel/net/netfilter/ipvs/ip_vs_sync.c
@@ -603,7 +603,7 @@
 	if (cp->flags & IP_VS_CONN_F_SEQ_MASK) {
 		struct ip_vs_sync_conn_options *opt =
 			(struct ip_vs_sync_conn_options *)&s[1];
-		memcpy(opt, &cp->in_seq, sizeof(*opt));
+		memcpy(opt, &cp->sync_conn_opt, sizeof(*opt));
 	}
 
 	m->nr_conns++;
@@ -1507,8 +1507,8 @@
 	}
 
 	get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->mcfg, id);
-	result = sock->ops->connect(sock, (struct sockaddr *) &mcast_addr,
-				    salen, 0);
+	result = kernel_connect(sock, (struct sockaddr *)&mcast_addr,
+				salen, 0);
 	if (result < 0) {
 		pr_err("Error connecting to the multicast addr\n");
 		goto error;
diff --git a/kernel/net/netfilter/ipvs/ip_vs_xmit.c b/kernel/net/netfilter/ipvs/ip_vs_xmit.c
index d2e5a8f..cd2130e 100644
--- a/kernel/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/kernel/net/netfilter/ipvs/ip_vs_xmit.c
@@ -1225,6 +1225,7 @@
 	skb->transport_header = skb->network_header;
 
 	skb_set_inner_ipproto(skb, next_protocol);
+	skb_set_inner_mac_header(skb, skb_inner_network_offset(skb));
 
 	if (tun_type == IP_VS_CONN_F_TUNNEL_TYPE_GUE) {
 		bool check = false;
@@ -1373,6 +1374,7 @@
 	skb->transport_header = skb->network_header;
 
 	skb_set_inner_ipproto(skb, next_protocol);
+	skb_set_inner_mac_header(skb, skb_inner_network_offset(skb));
 
 	if (tun_type == IP_VS_CONN_F_TUNNEL_TYPE_GUE) {
 		bool check = false;
diff --git a/kernel/net/netfilter/nf_conntrack_core.c b/kernel/net/netfilter/nf_conntrack_core.c
index b74f6e5..1ae96f8 100644
--- a/kernel/net/netfilter/nf_conntrack_core.c
+++ b/kernel/net/netfilter/nf_conntrack_core.c
@@ -2076,6 +2076,9 @@
 		return 0;
 
 	helper = rcu_dereference(help->helper);
+	if (!helper)
+		return 0;
+
 	if (!(helper->flags & NF_CT_HELPER_F_USERSPACE))
 		return 0;
 
diff --git a/kernel/net/netfilter/nf_conntrack_helper.c b/kernel/net/netfilter/nf_conntrack_helper.c
index 118f415..32cc91f 100644
--- a/kernel/net/netfilter/nf_conntrack_helper.c
+++ b/kernel/net/netfilter/nf_conntrack_helper.c
@@ -404,6 +404,9 @@
 	BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES);
 	BUG_ON(strlen(me->name) > NF_CT_HELPER_NAME_LEN - 1);
 
+	if (!nf_ct_helper_hash)
+		return -ENOENT;
+
 	if (me->expect_policy->max_expected > NF_CT_EXPECT_MAX_CNT)
 		return -EINVAL;
 
@@ -587,4 +590,5 @@
 {
 	nf_ct_extend_unregister(&helper_extend);
 	kvfree(nf_ct_helper_hash);
+	nf_ct_helper_hash = NULL;
 }
diff --git a/kernel/net/netfilter/nf_conntrack_netlink.c b/kernel/net/netfilter/nf_conntrack_netlink.c
index 2efdc50..ceb7c98 100644
--- a/kernel/net/netfilter/nf_conntrack_netlink.c
+++ b/kernel/net/netfilter/nf_conntrack_netlink.c
@@ -317,11 +317,12 @@
 }
 
 #ifdef CONFIG_NF_CONNTRACK_MARK
-static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
+static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct,
+			       bool dump)
 {
 	u32 mark = READ_ONCE(ct->mark);
 
-	if (!mark)
+	if (!mark && !dump)
 		return 0;
 
 	if (nla_put_be32(skb, CTA_MARK, htonl(mark)))
@@ -332,7 +333,7 @@
 	return -1;
 }
 #else
-#define ctnetlink_dump_mark(a, b) (0)
+#define ctnetlink_dump_mark(a, b, c) (0)
 #endif
 
 #ifdef CONFIG_NF_CONNTRACK_SECMARK
@@ -537,7 +538,7 @@
 static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct)
 {
 	if (ctnetlink_dump_status(skb, ct) < 0 ||
-	    ctnetlink_dump_mark(skb, ct) < 0 ||
+	    ctnetlink_dump_mark(skb, ct, true) < 0 ||
 	    ctnetlink_dump_secctx(skb, ct) < 0 ||
 	    ctnetlink_dump_id(skb, ct) < 0 ||
 	    ctnetlink_dump_use(skb, ct) < 0 ||
@@ -816,8 +817,7 @@
 	}
 
 #ifdef CONFIG_NF_CONNTRACK_MARK
-	if (events & (1 << IPCT_MARK) &&
-	    ctnetlink_dump_mark(skb, ct) < 0)
+	if (ctnetlink_dump_mark(skb, ct, events & (1 << IPCT_MARK)))
 		goto nla_put_failure;
 #endif
 	nlmsg_end(skb, nlh);
@@ -1493,9 +1493,6 @@
 
 static int ctnetlink_flush_iterate(struct nf_conn *ct, void *data)
 {
-	if (test_bit(IPS_OFFLOAD_BIT, &ct->status))
-		return 0;
-
 	return ctnetlink_filter_match(ct, data);
 }
 
@@ -1560,11 +1557,6 @@
 		return -ENOENT;
 
 	ct = nf_ct_tuplehash_to_ctrack(h);
-
-	if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) {
-		nf_ct_put(ct);
-		return -EBUSY;
-	}
 
 	if (cda[CTA_ID]) {
 		__be32 id = nla_get_be32(cda[CTA_ID]);
@@ -2359,12 +2351,15 @@
 
 	err = nf_conntrack_hash_check_insert(ct);
 	if (err < 0)
-		goto err2;
+		goto err3;
 
 	rcu_read_unlock();
 
 	return ct;
 
+err3:
+	if (ct->master)
+		nf_ct_put(ct->master);
 err2:
 	rcu_read_unlock();
 err1:
@@ -2731,7 +2726,7 @@
 		goto nla_put_failure;
 
 #ifdef CONFIG_NF_CONNTRACK_MARK
-	if (ctnetlink_dump_mark(skb, ct) < 0)
+	if (ctnetlink_dump_mark(skb, ct, true) < 0)
 		goto nla_put_failure;
 #endif
 	if (ctnetlink_dump_labels(skb, ct) < 0)
@@ -2973,7 +2968,9 @@
 	return -1;
 }
 
+#if IS_ENABLED(CONFIG_NF_NAT)
 static const union nf_inet_addr any_addr;
+#endif
 
 static __be32 nf_expect_get_id(const struct nf_conntrack_expect *exp)
 {
@@ -3463,10 +3460,12 @@
 	return 0;
 }
 
+#if IS_ENABLED(CONFIG_NF_NAT)
 static const struct nla_policy exp_nat_nla_policy[CTA_EXPECT_NAT_MAX+1] = {
 	[CTA_EXPECT_NAT_DIR]	= { .type = NLA_U32 },
 	[CTA_EXPECT_NAT_TUPLE]	= { .type = NLA_NESTED },
 };
+#endif
 
 static int
 ctnetlink_parse_expect_nat(const struct nlattr *attr,
diff --git a/kernel/net/netfilter/nf_conntrack_proto_dccp.c b/kernel/net/netfilter/nf_conntrack_proto_dccp.c
index 94001eb..a9ae292 100644
--- a/kernel/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/kernel/net/netfilter/nf_conntrack_proto_dccp.c
@@ -431,9 +431,19 @@
 		       struct sk_buff *skb, unsigned int dataoff,
 		       const struct nf_hook_state *state)
 {
+	static const unsigned long require_seq48 = 1 << DCCP_PKT_REQUEST |
+						   1 << DCCP_PKT_RESPONSE |
+						   1 << DCCP_PKT_CLOSEREQ |
+						   1 << DCCP_PKT_CLOSE |
+						   1 << DCCP_PKT_RESET |
+						   1 << DCCP_PKT_SYNC |
+						   1 << DCCP_PKT_SYNCACK;
 	unsigned int dccp_len = skb->len - dataoff;
 	unsigned int cscov;
 	const char *msg;
+	u8 type;
+
+	BUILD_BUG_ON(DCCP_PKT_INVALID >= BITS_PER_LONG);
 
 	if (dh->dccph_doff * 4 < sizeof(struct dccp_hdr) ||
 	    dh->dccph_doff * 4 > dccp_len) {
@@ -458,15 +468,45 @@
 		goto out_invalid;
 	}
 
-	if (dh->dccph_type >= DCCP_PKT_INVALID) {
+	type = dh->dccph_type;
+	if (type >= DCCP_PKT_INVALID) {
 		msg = "nf_ct_dccp: reserved packet type ";
 		goto out_invalid;
 	}
+
+	if (test_bit(type, &require_seq48) && !dh->dccph_x) {
+		msg = "nf_ct_dccp: type lacks 48bit sequence numbers";
+		goto out_invalid;
+	}
+
 	return false;
 out_invalid:
 	nf_l4proto_log_invalid(skb, state->net, state->pf,
 			       IPPROTO_DCCP, "%s", msg);
 	return true;
+}
+
+struct nf_conntrack_dccp_buf {
+	struct dccp_hdr dh;	 /* generic header part */
+	struct dccp_hdr_ext ext; /* optional depending dh->dccph_x */
+	union {			 /* depends on header type */
+		struct dccp_hdr_ack_bits ack;
+		struct dccp_hdr_request req;
+		struct dccp_hdr_response response;
+		struct dccp_hdr_reset rst;
+	} u;
+};
+
+static struct dccp_hdr *
+dccp_header_pointer(const struct sk_buff *skb, int offset, const struct dccp_hdr *dh,
+		    struct nf_conntrack_dccp_buf *buf)
+{
+	unsigned int hdrlen = __dccp_hdr_len(dh);
+
+	if (hdrlen > sizeof(*buf))
+		return NULL;
+
+	return skb_header_pointer(skb, offset, hdrlen, buf);
 }
 
 int nf_conntrack_dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
@@ -475,18 +515,24 @@
 			     const struct nf_hook_state *state)
 {
 	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
-	struct dccp_hdr _dh, *dh;
+	struct nf_conntrack_dccp_buf _dh;
 	u_int8_t type, old_state, new_state;
 	enum ct_dccp_roles role;
 	unsigned int *timeouts;
+	struct dccp_hdr *dh;
 
-	dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
+	dh = skb_header_pointer(skb, dataoff, sizeof(*dh), &_dh.dh);
 	if (!dh)
 		return NF_DROP;
 
 	if (dccp_error(dh, skb, dataoff, state))
 		return -NF_ACCEPT;
 
+	/* pull again, including possible 48 bit sequences and subtype header */
+	dh = dccp_header_pointer(skb, dataoff, dh, &_dh);
+	if (!dh)
+		return NF_DROP;
+
 	type = dh->dccph_type;
 	if (!nf_ct_is_confirmed(ct) && !dccp_new(ct, skb, dh))
 		return -NF_ACCEPT;
diff --git a/kernel/net/netfilter/nf_conntrack_proto_icmpv6.c b/kernel/net/netfilter/nf_conntrack_proto_icmpv6.c
index facd8c6..f1a87de 100644
--- a/kernel/net/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/kernel/net/netfilter/nf_conntrack_proto_icmpv6.c
@@ -130,6 +130,56 @@
 			       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 @@
 		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/kernel/net/netfilter/nf_conntrack_proto_sctp.c b/kernel/net/netfilter/nf_conntrack_proto_sctp.c
index 7626f3e..21cbaf6 100644
--- a/kernel/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/kernel/net/netfilter/nf_conntrack_proto_sctp.c
@@ -27,22 +27,16 @@
 #include <net/netfilter/nf_conntrack_ecache.h>
 #include <net/netfilter/nf_conntrack_timeout.h>
 
-/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
-   closely.  They're more complex. --RR
-
-   And so for me for SCTP :D -Kiran */
-
 static const char *const sctp_conntrack_names[] = {
-	"NONE",
-	"CLOSED",
-	"COOKIE_WAIT",
-	"COOKIE_ECHOED",
-	"ESTABLISHED",
-	"SHUTDOWN_SENT",
-	"SHUTDOWN_RECD",
-	"SHUTDOWN_ACK_SENT",
-	"HEARTBEAT_SENT",
-	"HEARTBEAT_ACKED",
+	[SCTP_CONNTRACK_NONE]			= "NONE",
+	[SCTP_CONNTRACK_CLOSED]			= "CLOSED",
+	[SCTP_CONNTRACK_COOKIE_WAIT]		= "COOKIE_WAIT",
+	[SCTP_CONNTRACK_COOKIE_ECHOED]		= "COOKIE_ECHOED",
+	[SCTP_CONNTRACK_ESTABLISHED]		= "ESTABLISHED",
+	[SCTP_CONNTRACK_SHUTDOWN_SENT]		= "SHUTDOWN_SENT",
+	[SCTP_CONNTRACK_SHUTDOWN_RECD]		= "SHUTDOWN_RECD",
+	[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT]	= "SHUTDOWN_ACK_SENT",
+	[SCTP_CONNTRACK_HEARTBEAT_SENT]		= "HEARTBEAT_SENT",
 };
 
 #define SECS  * HZ
@@ -54,12 +48,11 @@
 	[SCTP_CONNTRACK_CLOSED]			= 10 SECS,
 	[SCTP_CONNTRACK_COOKIE_WAIT]		= 3 SECS,
 	[SCTP_CONNTRACK_COOKIE_ECHOED]		= 3 SECS,
-	[SCTP_CONNTRACK_ESTABLISHED]		= 5 DAYS,
-	[SCTP_CONNTRACK_SHUTDOWN_SENT]		= 300 SECS / 1000,
-	[SCTP_CONNTRACK_SHUTDOWN_RECD]		= 300 SECS / 1000,
+	[SCTP_CONNTRACK_ESTABLISHED]		= 210 SECS,
+	[SCTP_CONNTRACK_SHUTDOWN_SENT]		= 3 SECS,
+	[SCTP_CONNTRACK_SHUTDOWN_RECD]		= 3 SECS,
 	[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT]	= 3 SECS,
 	[SCTP_CONNTRACK_HEARTBEAT_SENT]		= 30 SECS,
-	[SCTP_CONNTRACK_HEARTBEAT_ACKED]	= 210 SECS,
 };
 
 #define	SCTP_FLAG_HEARTBEAT_VTAG_FAILED	1
@@ -73,7 +66,6 @@
 #define	sSR SCTP_CONNTRACK_SHUTDOWN_RECD
 #define	sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
 #define	sHS SCTP_CONNTRACK_HEARTBEAT_SENT
-#define	sHA SCTP_CONNTRACK_HEARTBEAT_ACKED
 #define	sIV SCTP_CONNTRACK_MAX
 
 /*
@@ -96,9 +88,6 @@
 CLOSED            - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
 		    the SHUTDOWN chunk. Connection is closed.
 HEARTBEAT_SENT    - We have seen a HEARTBEAT in a new flow.
-HEARTBEAT_ACKED   - We have seen a HEARTBEAT-ACK in the direction opposite to
-		    that of the HEARTBEAT chunk. Secondary connection is
-		    established.
 */
 
 /* TODO
@@ -115,33 +104,33 @@
 static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = {
 	{
 /*	ORIGINAL	*/
-/*                  sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA */
-/* init         */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCW, sHA},
-/* init_ack     */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},
-/* abort        */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
-/* shutdown     */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA, sCL, sSS},
-/* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA, sSA, sHA},
-/* error        */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},/* Can't have Stale cookie*/
-/* cookie_echo  */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA, sCL, sHA},/* 5.2.4 - Big TODO */
-/* cookie_ack   */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},/* Can't come in orig dir */
-/* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL, sCL, sHA},
-/* heartbeat    */ {sHS, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA},
-/* heartbeat_ack*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA}
+/*                  sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS */
+/* init         */ {sCL, sCL, sCW, sCE, sES, sCL, sCL, sSA, sCW},
+/* init_ack     */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},
+/* abort        */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
+/* shutdown     */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA, sCL},
+/* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA, sSA},
+/* error        */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},/* Can't have Stale cookie*/
+/* cookie_echo  */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA, sCL},/* 5.2.4 - Big TODO */
+/* cookie_ack   */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},/* Can't come in orig dir */
+/* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL, sCL},
+/* heartbeat    */ {sHS, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS},
+/* heartbeat_ack*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS},
 	},
 	{
 /*	REPLY	*/
-/*                  sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA */
-/* init         */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},/* INIT in sCL Big TODO */
-/* init_ack     */ {sIV, sCW, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},
-/* abort        */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV, sCL},
-/* shutdown     */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA, sIV, sSR},
-/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA, sIV, sHA},
-/* error        */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA, sIV, sHA},
-/* cookie_echo  */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},/* Can't come in reply dir */
-/* cookie_ack   */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA, sIV, sHA},
-/* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL, sIV, sHA},
-/* heartbeat    */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA},
-/* heartbeat_ack*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHA, sHA}
+/*                  sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS */
+/* init         */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV},/* INIT in sCL Big TODO */
+/* init_ack     */ {sIV, sCW, sCW, sCE, sES, sSS, sSR, sSA, sIV},
+/* abort        */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV},
+/* shutdown     */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA, sIV},
+/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA, sIV},
+/* error        */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA, sIV},
+/* cookie_echo  */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV},/* Can't come in reply dir */
+/* cookie_ack   */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA, sIV},
+/* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL, sIV},
+/* heartbeat    */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS},
+/* heartbeat_ack*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sES},
 	}
 };
 
@@ -412,22 +401,29 @@
 	for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
 		/* Special cases of Verification tag check (Sec 8.5.1) */
 		if (sch->type == SCTP_CID_INIT) {
-			/* Sec 8.5.1 (A) */
+			/* (A) vtag MUST be zero */
 			if (sh->vtag != 0)
 				goto out_unlock;
 		} else if (sch->type == SCTP_CID_ABORT) {
-			/* Sec 8.5.1 (B) */
-			if (sh->vtag != ct->proto.sctp.vtag[dir] &&
-			    sh->vtag != ct->proto.sctp.vtag[!dir])
+			/* (B) vtag MUST match own vtag if T flag is unset OR
+			 * MUST match peer's vtag if T flag is set
+			 */
+			if ((!(sch->flags & SCTP_CHUNK_FLAG_T) &&
+			     sh->vtag != ct->proto.sctp.vtag[dir]) ||
+			    ((sch->flags & SCTP_CHUNK_FLAG_T) &&
+			     sh->vtag != ct->proto.sctp.vtag[!dir]))
 				goto out_unlock;
 		} else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
-			/* Sec 8.5.1 (C) */
-			if (sh->vtag != ct->proto.sctp.vtag[dir] &&
-			    sh->vtag != ct->proto.sctp.vtag[!dir] &&
-			    sch->flags & SCTP_CHUNK_FLAG_T)
+			/* (C) vtag MUST match own vtag if T flag is unset OR
+			 * MUST match peer's vtag if T flag is set
+			 */
+			if ((!(sch->flags & SCTP_CHUNK_FLAG_T) &&
+			     sh->vtag != ct->proto.sctp.vtag[dir]) ||
+			    ((sch->flags & SCTP_CHUNK_FLAG_T) &&
+			     sh->vtag != ct->proto.sctp.vtag[!dir]))
 				goto out_unlock;
 		} else if (sch->type == SCTP_CID_COOKIE_ECHO) {
-			/* Sec 8.5.1 (D) */
+			/* (D) vtag must be same as init_vtag as found in INIT_ACK */
 			if (sh->vtag != ct->proto.sctp.vtag[dir])
 				goto out_unlock;
 		} else if (sch->type == SCTP_CID_HEARTBEAT) {
@@ -501,8 +497,12 @@
 		}
 
 		ct->proto.sctp.state = new_state;
-		if (old_state != new_state)
+		if (old_state != new_state) {
 			nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
+			if (new_state == SCTP_CONNTRACK_ESTABLISHED &&
+			    !test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
+				nf_conntrack_event_cache(IPCT_ASSURED, ct);
+		}
 	}
 	spin_unlock_bh(&ct->lock);
 
@@ -515,14 +515,6 @@
 		timeouts = nf_sctp_pernet(nf_ct_net(ct))->timeouts;
 
 	nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
-
-	if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
-	    dir == IP_CT_DIR_REPLY &&
-	    new_state == SCTP_CONNTRACK_ESTABLISHED) {
-		pr_debug("Setting assured bit\n");
-		set_bit(IPS_ASSURED_BIT, &ct->status);
-		nf_conntrack_event_cache(IPCT_ASSURED, ct);
-	}
 
 	return NF_ACCEPT;
 
diff --git a/kernel/net/netfilter/nf_conntrack_proto_tcp.c b/kernel/net/netfilter/nf_conntrack_proto_tcp.c
index 3f785bd..c1d02c0 100644
--- a/kernel/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/kernel/net/netfilter/nf_conntrack_proto_tcp.c
@@ -1158,6 +1158,16 @@
 			nf_ct_kill_acct(ct, ctinfo, skb);
 			return NF_ACCEPT;
 		}
+
+		if (index == TCP_SYN_SET && old_state == TCP_CONNTRACK_SYN_SENT) {
+			/* do not renew timeout on SYN retransmit.
+			 *
+			 * Else port reuse by client or NAT middlebox can keep
+			 * entry alive indefinitely (including nat info).
+			 */
+			return NF_ACCEPT;
+		}
+
 		/* ESTABLISHED without SEEN_REPLY, i.e. mid-connection
 		 * pickup with loose=1. Avoid large ESTABLISHED timeout.
 		 */
diff --git a/kernel/net/netfilter/nf_conntrack_sip.c b/kernel/net/netfilter/nf_conntrack_sip.c
index 78fd912..751df19 100644
--- a/kernel/net/netfilter/nf_conntrack_sip.c
+++ b/kernel/net/netfilter/nf_conntrack_sip.c
@@ -611,7 +611,7 @@
 	start += strlen(name);
 	*val = simple_strtoul(start, &end, 0);
 	if (start == end)
-		return 0;
+		return -1;
 	if (matchoff && matchlen) {
 		*matchoff = start - dptr;
 		*matchlen = end - start;
diff --git a/kernel/net/netfilter/nf_conntrack_standalone.c b/kernel/net/netfilter/nf_conntrack_standalone.c
index a7f88cd..b613de9 100644
--- a/kernel/net/netfilter/nf_conntrack_standalone.c
+++ b/kernel/net/netfilter/nf_conntrack_standalone.c
@@ -583,7 +583,6 @@
 	NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_SHUTDOWN_RECD,
 	NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT,
 	NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_HEARTBEAT_SENT,
-	NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_HEARTBEAT_ACKED,
 #endif
 #ifdef CONFIG_NF_CT_PROTO_DCCP
 	NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_REQUEST,
@@ -853,12 +852,6 @@
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
-	[NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_HEARTBEAT_ACKED] = {
-		.procname       = "nf_conntrack_sctp_timeout_heartbeat_acked",
-		.maxlen         = sizeof(unsigned int),
-		.mode           = 0644,
-		.proc_handler   = proc_dointvec_jiffies,
-	},
 #endif
 #ifdef CONFIG_NF_CT_PROTO_DCCP
 	[NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_REQUEST] = {
@@ -987,7 +980,6 @@
 	XASSIGN(SHUTDOWN_RECD, sn);
 	XASSIGN(SHUTDOWN_ACK_SENT, sn);
 	XASSIGN(HEARTBEAT_SENT, sn);
-	XASSIGN(HEARTBEAT_ACKED, sn);
 #undef XASSIGN
 #endif
 }
@@ -1178,11 +1170,12 @@
 	nf_conntrack_htable_size_user = nf_conntrack_htable_size;
 #endif
 
+	nf_conntrack_init_end();
+
 	ret = register_pernet_subsys(&nf_conntrack_net_ops);
 	if (ret < 0)
 		goto out_pernet;
 
-	nf_conntrack_init_end();
 	return 0;
 
 out_pernet:
diff --git a/kernel/net/netfilter/nf_flow_table_offload.c b/kernel/net/netfilter/nf_flow_table_offload.c
index 28306cb..746ca77 100644
--- a/kernel/net/netfilter/nf_flow_table_offload.c
+++ b/kernel/net/netfilter/nf_flow_table_offload.c
@@ -305,12 +305,12 @@
 				     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);
 	}
 }
 
diff --git a/kernel/net/netfilter/nf_tables_api.c b/kernel/net/netfilter/nf_tables_api.c
index 2143eda..78b268b 100644
--- a/kernel/net/netfilter/nf_tables_api.c
+++ b/kernel/net/netfilter/nf_tables_api.c
@@ -21,15 +21,20 @@
 #include <net/netfilter/nf_tables.h>
 #include <net/netfilter/nf_tables_offload.h>
 #include <net/net_namespace.h>
+#include <net/netns/generic.h>
 #include <net/sock.h>
 
 #define NFT_MODULE_AUTOLOAD_LIMIT (MODULE_NAME_LEN - sizeof("nft-expr-255-"))
+
+unsigned int nf_tables_net_id __read_mostly;
 
 static LIST_HEAD(nf_tables_expressions);
 static LIST_HEAD(nf_tables_objects);
 static LIST_HEAD(nf_tables_flowtables);
 static LIST_HEAD(nf_tables_destroy_list);
+static LIST_HEAD(nf_tables_gc_list);
 static DEFINE_SPINLOCK(nf_tables_destroy_list_lock);
+static DEFINE_SPINLOCK(nf_tables_gc_list_lock);
 static u64 table_handle;
 
 enum {
@@ -103,7 +108,9 @@
 
 static void nft_validate_state_update(struct net *net, u8 new_validate_state)
 {
-	switch (net->nft.validate_state) {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
+
+	switch (nft_net->validate_state) {
 	case NFT_VALIDATE_SKIP:
 		WARN_ON_ONCE(new_validate_state == NFT_VALIDATE_DO);
 		break;
@@ -114,10 +121,13 @@
 			return;
 	}
 
-	net->nft.validate_state = new_validate_state;
+	nft_net->validate_state = new_validate_state;
 }
 static void nf_tables_trans_destroy_work(struct work_struct *w);
 static DECLARE_WORK(trans_destroy_work, nf_tables_trans_destroy_work);
+
+static void nft_trans_gc_work(struct work_struct *work);
+static DECLARE_WORK(trans_gc_work, nft_trans_gc_work);
 
 static void nft_ctx_init(struct nft_ctx *ctx,
 			 struct net *net,
@@ -150,6 +160,7 @@
 		return NULL;
 
 	INIT_LIST_HEAD(&trans->list);
+	INIT_LIST_HEAD(&trans->binding_list);
 	trans->msg_type = msg_type;
 	trans->ctx	= *ctx;
 
@@ -162,32 +173,107 @@
 	return nft_trans_alloc_gfp(ctx, msg_type, size, GFP_KERNEL);
 }
 
-static void nft_trans_destroy(struct nft_trans *trans)
+static void nft_trans_list_del(struct nft_trans *trans)
 {
 	list_del(&trans->list);
+	list_del(&trans->binding_list);
+}
+
+static void nft_trans_destroy(struct nft_trans *trans)
+{
+	nft_trans_list_del(trans);
 	kfree(trans);
 }
 
-static void nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set)
+static void __nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set,
+				 bool bind)
 {
+	struct nftables_pernet *nft_net;
 	struct net *net = ctx->net;
 	struct nft_trans *trans;
 
 	if (!nft_set_is_anonymous(set))
 		return;
 
-	list_for_each_entry_reverse(trans, &net->nft.commit_list, list) {
+	nft_net = net_generic(net, nf_tables_net_id);
+	list_for_each_entry_reverse(trans, &nft_net->commit_list, list) {
 		switch (trans->msg_type) {
 		case NFT_MSG_NEWSET:
 			if (nft_trans_set(trans) == set)
-				nft_trans_set_bound(trans) = true;
+				nft_trans_set_bound(trans) = bind;
 			break;
 		case NFT_MSG_NEWSETELEM:
 			if (nft_trans_elem_set(trans) == set)
-				nft_trans_elem_set_bound(trans) = true;
+				nft_trans_elem_set_bound(trans) = bind;
 			break;
 		}
 	}
+}
+
+static void nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set)
+{
+	return __nft_set_trans_bind(ctx, set, true);
+}
+
+static void nft_set_trans_unbind(const struct nft_ctx *ctx, struct nft_set *set)
+{
+	return __nft_set_trans_bind(ctx, set, false);
+}
+
+static void __nft_chain_trans_bind(const struct nft_ctx *ctx,
+				   struct nft_chain *chain, bool bind)
+{
+	struct nftables_pernet *nft_net;
+	struct net *net = ctx->net;
+	struct nft_trans *trans;
+
+	if (!nft_chain_binding(chain))
+		return;
+
+	nft_net = net_generic(net, nf_tables_net_id);
+	list_for_each_entry_reverse(trans, &nft_net->commit_list, list) {
+		switch (trans->msg_type) {
+		case NFT_MSG_NEWCHAIN:
+			if (nft_trans_chain(trans) == chain)
+				nft_trans_chain_bound(trans) = bind;
+			break;
+		case NFT_MSG_NEWRULE:
+			if (trans->ctx.chain == chain)
+				nft_trans_rule_bound(trans) = bind;
+			break;
+		}
+	}
+}
+
+static void nft_chain_trans_bind(const struct nft_ctx *ctx,
+				 struct nft_chain *chain)
+{
+	__nft_chain_trans_bind(ctx, chain, true);
+}
+
+int nf_tables_bind_chain(const struct nft_ctx *ctx, struct nft_chain *chain)
+{
+	if (!nft_chain_binding(chain))
+		return 0;
+
+	if (nft_chain_binding(ctx->chain))
+		return -EOPNOTSUPP;
+
+	if (chain->bound)
+		return -EBUSY;
+
+	if (!nft_use_inc(&chain->use))
+		return -EMFILE;
+
+	chain->bound = true;
+	nft_chain_trans_bind(ctx, chain);
+
+	return 0;
+}
+
+void nf_tables_unbind_chain(const struct nft_ctx *ctx, struct nft_chain *chain)
+{
+	__nft_chain_trans_bind(ctx, chain, false);
 }
 
 static int nft_netdev_register_hooks(struct net *net,
@@ -217,12 +303,18 @@
 }
 
 static void nft_netdev_unregister_hooks(struct net *net,
-					struct list_head *hook_list)
+					struct list_head *hook_list,
+					bool release_netdev)
 {
-	struct nft_hook *hook;
+	struct nft_hook *hook, *next;
 
-	list_for_each_entry(hook, hook_list, list)
+	list_for_each_entry_safe(hook, next, hook_list, list) {
 		nf_unregister_net_hook(net, &hook->ops);
+		if (release_netdev) {
+			list_del(&hook->list);
+			kfree_rcu(hook, rcu);
+		}
+	}
 }
 
 static int nf_tables_register_hook(struct net *net,
@@ -248,9 +340,10 @@
 	return nf_register_net_hook(net, &basechain->ops);
 }
 
-static void nf_tables_unregister_hook(struct net *net,
-				      const struct nft_table *table,
-				      struct nft_chain *chain)
+static void __nf_tables_unregister_hook(struct net *net,
+					const struct nft_table *table,
+					struct nft_chain *chain,
+					bool release_netdev)
 {
 	struct nft_base_chain *basechain;
 	const struct nf_hook_ops *ops;
@@ -265,9 +358,38 @@
 		return basechain->type->ops_unregister(net, ops);
 
 	if (nft_base_chain_netdev(table->family, basechain->ops.hooknum))
-		nft_netdev_unregister_hooks(net, &basechain->hook_list);
+		nft_netdev_unregister_hooks(net, &basechain->hook_list,
+					    release_netdev);
 	else
 		nf_unregister_net_hook(net, &basechain->ops);
+}
+
+static void nf_tables_unregister_hook(struct net *net,
+				      const struct nft_table *table,
+				      struct nft_chain *chain)
+{
+	return __nf_tables_unregister_hook(net, table, chain, false);
+}
+
+static void nft_trans_commit_list_add_tail(struct net *net, struct nft_trans *trans)
+{
+	struct nftables_pernet *nft_net;
+
+	nft_net = net_generic(net, nf_tables_net_id);
+
+	switch (trans->msg_type) {
+	case NFT_MSG_NEWSET:
+		if (nft_set_is_anonymous(nft_trans_set(trans)))
+			list_add_tail(&trans->binding_list, &nft_net->binding_list);
+		break;
+	case NFT_MSG_NEWCHAIN:
+		if (!nft_trans_chain_update(trans) &&
+		    nft_chain_binding(nft_trans_chain(trans)))
+			list_add_tail(&trans->binding_list, &nft_net->binding_list);
+		break;
+	}
+
+	list_add_tail(&trans->list, &nft_net->commit_list);
 }
 
 static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
@@ -281,7 +403,7 @@
 	if (msg_type == NFT_MSG_NEWTABLE)
 		nft_activate_next(ctx->net, ctx->table);
 
-	list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+	nft_trans_commit_list_add_tail(ctx->net, trans);
 	return 0;
 }
 
@@ -313,8 +435,9 @@
 				ntohl(nla_get_be32(ctx->nla[NFTA_CHAIN_ID]));
 		}
 	}
+	nft_trans_chain(trans) = ctx->chain;
+	nft_trans_commit_list_add_tail(ctx->net, trans);
 
-	list_add_tail(&trans->list, &ctx->net->nft.commit_list);
 	return trans;
 }
 
@@ -326,14 +449,13 @@
 	if (IS_ERR(trans))
 		return PTR_ERR(trans);
 
-	ctx->table->use--;
+	nft_use_dec(&ctx->table->use);
 	nft_deactivate_next(ctx->net, ctx->chain);
 
 	return 0;
 }
 
-static void nft_rule_expr_activate(const struct nft_ctx *ctx,
-				   struct nft_rule *rule)
+void nft_rule_expr_activate(const struct nft_ctx *ctx, struct nft_rule *rule)
 {
 	struct nft_expr *expr;
 
@@ -346,9 +468,8 @@
 	}
 }
 
-static void nft_rule_expr_deactivate(const struct nft_ctx *ctx,
-				     struct nft_rule *rule,
-				     enum nft_trans_phase phase)
+void nft_rule_expr_deactivate(const struct nft_ctx *ctx, struct nft_rule *rule,
+			      enum nft_trans_phase phase)
 {
 	struct nft_expr *expr;
 
@@ -367,7 +488,7 @@
 	/* You cannot delete the same rule twice */
 	if (nft_is_active_next(ctx->net, rule)) {
 		nft_deactivate_next(ctx->net, rule);
-		ctx->chain->use--;
+		nft_use_dec(&ctx->chain->use);
 		return 0;
 	}
 	return -ENOENT;
@@ -387,7 +508,7 @@
 			ntohl(nla_get_be32(ctx->nla[NFTA_RULE_ID]));
 	}
 	nft_trans_rule(trans) = rule;
-	list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+	nft_trans_commit_list_add_tail(ctx->net, trans);
 
 	return trans;
 }
@@ -453,9 +574,30 @@
 		nft_activate_next(ctx->net, set);
 	}
 	nft_trans_set(trans) = set;
-	list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+	nft_trans_commit_list_add_tail(ctx->net, trans);
 
 	return 0;
+}
+
+static int nft_mapelem_deactivate(const struct nft_ctx *ctx,
+				  struct nft_set *set,
+				  const struct nft_set_iter *iter,
+				  struct nft_set_elem *elem)
+{
+	nft_setelem_data_deactivate(ctx->net, set, elem);
+
+	return 0;
+}
+
+static void nft_map_deactivate(const struct nft_ctx *ctx, struct nft_set *set)
+{
+	struct nft_set_iter iter = {
+		.genmask	= nft_genmask_next(ctx->net),
+		.fn		= nft_mapelem_deactivate,
+	};
+
+	set->ops->walk(ctx, set, &iter);
+	WARN_ON_ONCE(iter.err);
 }
 
 static int nft_delset(const struct nft_ctx *ctx, struct nft_set *set)
@@ -466,8 +608,11 @@
 	if (err < 0)
 		return err;
 
+	if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
+		nft_map_deactivate(ctx, set);
+
 	nft_deactivate_next(ctx->net, set);
-	ctx->table->use--;
+	nft_use_dec(&ctx->table->use);
 
 	return err;
 }
@@ -485,7 +630,7 @@
 		nft_activate_next(ctx->net, obj);
 
 	nft_trans_obj(trans) = obj;
-	list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+	nft_trans_commit_list_add_tail(ctx->net, trans);
 
 	return 0;
 }
@@ -499,7 +644,7 @@
 		return err;
 
 	nft_deactivate_next(ctx->net, obj);
-	ctx->table->use--;
+	nft_use_dec(&ctx->table->use);
 
 	return err;
 }
@@ -519,7 +664,7 @@
 
 	INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans));
 	nft_trans_flowtable(trans) = flowtable;
-	list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+	nft_trans_commit_list_add_tail(ctx->net, trans);
 
 	return 0;
 }
@@ -534,7 +679,7 @@
 		return err;
 
 	nft_deactivate_next(ctx->net, flowtable);
-	ctx->table->use--;
+	nft_use_dec(&ctx->table->use);
 
 	return err;
 }
@@ -547,13 +692,15 @@
 					  const struct nlattr *nla,
 					  u8 family, u8 genmask)
 {
+	struct nftables_pernet *nft_net;
 	struct nft_table *table;
 
 	if (nla == NULL)
 		return ERR_PTR(-EINVAL);
 
-	list_for_each_entry_rcu(table, &net->nft.tables, list,
-				lockdep_is_held(&net->nft.commit_mutex)) {
+	nft_net = net_generic(net, nf_tables_net_id);
+	list_for_each_entry_rcu(table, &nft_net->tables, list,
+				lockdep_is_held(&nft_net->commit_mutex)) {
 		if (!nla_strcmp(nla, table->name) &&
 		    table->family == family &&
 		    nft_active_genmask(table, genmask))
@@ -567,9 +714,11 @@
 						   const struct nlattr *nla,
 						   u8 genmask)
 {
+	struct nftables_pernet *nft_net;
 	struct nft_table *table;
 
-	list_for_each_entry(table, &net->nft.tables, list) {
+	nft_net = net_generic(net, nf_tables_net_id);
+	list_for_each_entry(table, &nft_net->tables, list) {
 		if (be64_to_cpu(nla_get_be64(nla)) == table->handle &&
 		    nft_active_genmask(table, genmask))
 			return table;
@@ -621,6 +770,7 @@
 static int nft_request_module(struct net *net, const char *fmt, ...)
 {
 	char module_name[MODULE_NAME_LEN];
+	struct nftables_pernet *nft_net;
 	struct nft_module_request *req;
 	va_list args;
 	int ret;
@@ -631,7 +781,8 @@
 	if (ret >= MODULE_NAME_LEN)
 		return 0;
 
-	list_for_each_entry(req, &net->nft.module_list, list) {
+	nft_net = net_generic(net, nf_tables_net_id);
+	list_for_each_entry(req, &nft_net->module_list, list) {
 		if (!strcmp(req->module, module_name)) {
 			if (req->done)
 				return 0;
@@ -647,7 +798,7 @@
 
 	req->done = false;
 	strlcpy(req->module, module_name, MODULE_NAME_LEN);
-	list_add_tail(&req->list, &net->nft.module_list);
+	list_add_tail(&req->list, &nft_net->module_list);
 
 	return -EAGAIN;
 }
@@ -685,7 +836,9 @@
 
 static __be16 nft_base_seq(const struct net *net)
 {
-	return htons(net->nft.base_seq & 0xffff);
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
+
+	return htons(nft_net->base_seq & 0xffff);
 }
 
 static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
@@ -743,6 +896,7 @@
 
 static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
 {
+	struct nftables_pernet *nft_net;
 	struct sk_buff *skb;
 	int err;
 
@@ -761,7 +915,8 @@
 		goto err;
 	}
 
-	nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
+	nft_net = net_generic(ctx->net, nf_tables_net_id);
+	nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
 	return;
 err:
 	nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
@@ -771,15 +926,17 @@
 				 struct netlink_callback *cb)
 {
 	const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
+	struct nftables_pernet *nft_net;
 	const struct nft_table *table;
 	unsigned int idx = 0, s_idx = cb->args[0];
 	struct net *net = sock_net(skb->sk);
 	int family = nfmsg->nfgen_family;
 
 	rcu_read_lock();
-	cb->seq = net->nft.base_seq;
+	nft_net = net_generic(net, nf_tables_net_id);
+	cb->seq = nft_net->base_seq;
 
-	list_for_each_entry_rcu(table, &net->nft.tables, list) {
+	list_for_each_entry_rcu(table, &nft_net->tables, list) {
 		if (family != NFPROTO_UNSPEC && family != table->family)
 			continue;
 
@@ -954,7 +1111,7 @@
 		goto err;
 
 	nft_trans_table_update(trans) = true;
-	list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+	nft_trans_commit_list_add_tail(ctx->net, trans);
 	return 0;
 err:
 	nft_trans_destroy(trans);
@@ -1017,6 +1174,7 @@
 			      const struct nlattr * const nla[],
 			      struct netlink_ext_ack *extack)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
 	u8 genmask = nft_genmask_next(net);
 	int family = nfmsg->nfgen_family;
@@ -1026,7 +1184,7 @@
 	u32 flags = 0;
 	int err;
 
-	lockdep_assert_held(&net->nft.commit_mutex);
+	lockdep_assert_held(&nft_net->commit_mutex);
 	attr = nla[NFTA_TABLE_NAME];
 	table = nft_table_lookup(net, attr, family, genmask);
 	if (IS_ERR(table)) {
@@ -1084,7 +1242,7 @@
 	if (err < 0)
 		goto err_trans;
 
-	list_add_tail_rcu(&table->list, &net->nft.tables);
+	list_add_tail_rcu(&table->list, &nft_net->tables);
 	return 0;
 err_trans:
 	rhltable_destroy(&table->chains_ht);
@@ -1110,7 +1268,7 @@
 		if (!nft_is_active_next(ctx->net, chain))
 			continue;
 
-		if (nft_chain_is_bound(chain))
+		if (nft_chain_binding(chain))
 			continue;
 
 		ctx->chain = chain;
@@ -1124,8 +1282,7 @@
 		if (!nft_is_active_next(ctx->net, set))
 			continue;
 
-		if (nft_set_is_anonymous(set) &&
-		    !list_empty(&set->bindings))
+		if (nft_set_is_anonymous(set))
 			continue;
 
 		err = nft_delset(ctx, set);
@@ -1155,7 +1312,7 @@
 		if (!nft_is_active_next(ctx->net, chain))
 			continue;
 
-		if (nft_chain_is_bound(chain))
+		if (nft_chain_binding(chain))
 			continue;
 
 		ctx->chain = chain;
@@ -1172,11 +1329,12 @@
 
 static int nft_flush(struct nft_ctx *ctx, int family)
 {
+	struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
 	struct nft_table *table, *nt;
 	const struct nlattr * const *nla = ctx->nla;
 	int err = 0;
 
-	list_for_each_entry_safe(table, nt, &ctx->net->nft.tables, list) {
+	list_for_each_entry_safe(table, nt, &nft_net->tables, list) {
 		if (family != AF_UNSPEC && table->family != family)
 			continue;
 
@@ -1291,7 +1449,9 @@
 static bool lockdep_commit_lock_is_held(const struct net *net)
 {
 #ifdef CONFIG_PROVE_LOCKING
-	return lockdep_is_held(&net->nft.commit_mutex);
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
+
+	return lockdep_is_held(&nft_net->commit_mutex);
 #else
 	return true;
 #endif
@@ -1494,6 +1654,7 @@
 
 static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
 {
+	struct nftables_pernet *nft_net;
 	struct sk_buff *skb;
 	int err;
 
@@ -1513,7 +1674,8 @@
 		goto err;
 	}
 
-	nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
+	nft_net = net_generic(ctx->net, nf_tables_net_id);
+	nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
 	return;
 err:
 	nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
@@ -1528,11 +1690,13 @@
 	unsigned int idx = 0, s_idx = cb->args[0];
 	struct net *net = sock_net(skb->sk);
 	int family = nfmsg->nfgen_family;
+	struct nftables_pernet *nft_net;
 
 	rcu_read_lock();
-	cb->seq = net->nft.base_seq;
+	nft_net = net_generic(net, nf_tables_net_id);
+	cb->seq = nft_net->base_seq;
 
-	list_for_each_entry_rcu(table, &net->nft.tables, list) {
+	list_for_each_entry_rcu(table, &nft_net->tables, list) {
 		if (family != NFPROTO_UNSPEC && family != table->family)
 			continue;
 
@@ -1847,11 +2011,12 @@
 				struct nft_chain_hook *hook, u8 family,
 				bool autoload)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	struct nlattr *ha[NFTA_HOOK_MAX + 1];
 	const struct nft_chain_type *type;
 	int err;
 
-	lockdep_assert_held(&net->nft.commit_mutex);
+	lockdep_assert_held(&nft_net->commit_mutex);
 	lockdep_nfnl_nft_mutex_not_held();
 
 	err = nla_parse_nested_deprecated(ha, NFTA_HOOK_MAX,
@@ -1981,7 +2146,7 @@
 	return 0;
 }
 
-static int nft_chain_add(struct nft_table *table, struct nft_chain *chain)
+int nft_chain_add(struct nft_table *table, struct nft_chain *chain)
 {
 	int err;
 
@@ -2009,9 +2174,6 @@
 	struct nft_chain *chain;
 	struct nft_rule **rules;
 	int err;
-
-	if (table->use == UINT_MAX)
-		return -EOVERFLOW;
 
 	if (nla[NFTA_CHAIN_HOOK]) {
 		struct nft_stats __percpu *stats = NULL;
@@ -2108,6 +2270,11 @@
 	if (err < 0)
 		goto err_destroy_chain;
 
+	if (!nft_use_inc(&table->use)) {
+		err = -EMFILE;
+		goto err_use;
+	}
+
 	trans = nft_trans_chain_add(ctx, NFT_MSG_NEWCHAIN);
 	if (IS_ERR(trans)) {
 		err = PTR_ERR(trans);
@@ -2124,10 +2291,11 @@
 		goto err_unregister_hook;
 	}
 
-	table->use++;
-
 	return 0;
+
 err_unregister_hook:
+	nft_use_dec_restore(&table->use);
+err_use:
 	nf_tables_unregister_hook(net, table, chain);
 err_destroy_chain:
 	nf_tables_chain_destroy(ctx);
@@ -2244,6 +2412,7 @@
 
 	if (nla[NFTA_CHAIN_HANDLE] &&
 	    nla[NFTA_CHAIN_NAME]) {
+		struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
 		struct nft_trans *tmp;
 		char *name;
 
@@ -2253,7 +2422,7 @@
 			goto err;
 
 		err = -EEXIST;
-		list_for_each_entry(tmp, &ctx->net->nft.commit_list, list) {
+		list_for_each_entry(tmp, &nft_net->commit_list, list) {
 			if (tmp->msg_type == NFT_MSG_NEWCHAIN &&
 			    tmp->ctx.table == table &&
 			    nft_trans_chain_update(tmp) &&
@@ -2267,7 +2436,7 @@
 
 		nft_trans_chain_name(trans) = name;
 	}
-	list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+	nft_trans_commit_list_add_tail(ctx->net, trans);
 
 	return 0;
 err:
@@ -2278,17 +2447,19 @@
 
 static struct nft_chain *nft_chain_lookup_byid(const struct net *net,
 					       const struct nft_table *table,
-					       const struct nlattr *nla)
+					       const struct nlattr *nla, u8 genmask)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	u32 id = ntohl(nla_get_be32(nla));
 	struct nft_trans *trans;
 
-	list_for_each_entry(trans, &net->nft.commit_list, list) {
+	list_for_each_entry(trans, &nft_net->commit_list, list) {
 		struct nft_chain *chain = trans->ctx.chain;
 
 		if (trans->msg_type == NFT_MSG_NEWCHAIN &&
 		    chain->table == table &&
-		    id == nft_trans_chain_id(trans))
+		    id == nft_trans_chain_id(trans) &&
+		    nft_active_genmask(chain, genmask))
 			return chain;
 	}
 	return ERR_PTR(-ENOENT);
@@ -2299,6 +2470,7 @@
 			      const struct nlattr * const nla[],
 			      struct netlink_ext_ack *extack)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
 	u8 genmask = nft_genmask_next(net);
 	int family = nfmsg->nfgen_family;
@@ -2310,7 +2482,7 @@
 	u64 handle = 0;
 	u32 flags = 0;
 
-	lockdep_assert_held(&net->nft.commit_mutex);
+	lockdep_assert_held(&nft_net->commit_mutex);
 
 	table = nft_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, genmask);
 	if (IS_ERR(table)) {
@@ -2426,6 +2598,9 @@
 		NL_SET_BAD_ATTR(extack, attr);
 		return PTR_ERR(chain);
 	}
+
+	if (nft_chain_binding(chain))
+		return -EOPNOTSUPP;
 
 	if (nlh->nlmsg_flags & NLM_F_NONREC &&
 	    chain->use > 0)
@@ -2848,6 +3023,7 @@
 static void nf_tables_rule_notify(const struct nft_ctx *ctx,
 				  const struct nft_rule *rule, int event)
 {
+	struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
 	struct sk_buff *skb;
 	int err;
 
@@ -2867,7 +3043,7 @@
 		goto err;
 	}
 
-	nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
+	nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
 	return;
 err:
 	nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
@@ -2925,11 +3101,13 @@
 	unsigned int idx = 0;
 	struct net *net = sock_net(skb->sk);
 	int family = nfmsg->nfgen_family;
+	struct nftables_pernet *nft_net;
 
 	rcu_read_lock();
-	cb->seq = net->nft.base_seq;
+	nft_net = net_generic(net, nf_tables_net_id);
+	cb->seq = nft_net->base_seq;
 
-	list_for_each_entry_rcu(table, &net->nft.tables, list) {
+	list_for_each_entry_rcu(table, &nft_net->tables, list) {
 		if (family != NFPROTO_UNSPEC && family != table->family)
 			continue;
 
@@ -3076,8 +3254,7 @@
 	return err;
 }
 
-static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
-				   struct nft_rule *rule)
+void nf_tables_rule_destroy(const struct nft_ctx *ctx, struct nft_rule *rule)
 {
 	struct nft_expr *expr, *next;
 
@@ -3094,7 +3271,7 @@
 	kfree(rule);
 }
 
-void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *rule)
+static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *rule)
 {
 	nft_rule_expr_deactivate(ctx, rule, NFT_TRANS_RELEASE);
 	nf_tables_rule_destroy(ctx, rule);
@@ -3145,6 +3322,8 @@
 		err = nft_chain_validate(&ctx, chain);
 		if (err < 0)
 			return err;
+
+		cond_resched();
 	}
 
 	return 0;
@@ -3161,6 +3340,7 @@
 			     const struct nlattr * const nla[],
 			     struct netlink_ext_ack *extack)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
 	u8 genmask = nft_genmask_next(net);
 	struct nft_expr_info *info = NULL;
@@ -3178,7 +3358,7 @@
 	int err, rem;
 	u64 handle, pos_handle;
 
-	lockdep_assert_held(&net->nft.commit_mutex);
+	lockdep_assert_held(&nft_net->commit_mutex);
 
 	table = nft_table_lookup(net, nla[NFTA_RULE_TABLE], family, genmask);
 	if (IS_ERR(table)) {
@@ -3193,11 +3373,10 @@
 			NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN]);
 			return PTR_ERR(chain);
 		}
-		if (nft_chain_is_bound(chain))
-			return -EOPNOTSUPP;
 
 	} else if (nla[NFTA_RULE_CHAIN_ID]) {
-		chain = nft_chain_lookup_byid(net, table, nla[NFTA_RULE_CHAIN_ID]);
+		chain = nft_chain_lookup_byid(net, table, nla[NFTA_RULE_CHAIN_ID],
+					      genmask);
 		if (IS_ERR(chain)) {
 			NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN_ID]);
 			return PTR_ERR(chain);
@@ -3205,6 +3384,9 @@
 	} else {
 		return -EINVAL;
 	}
+
+	if (nft_chain_is_bound(chain))
+		return -EOPNOTSUPP;
 
 	if (nla[NFTA_RULE_HANDLE]) {
 		handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_HANDLE]));
@@ -3227,9 +3409,6 @@
 		    nlh->nlmsg_flags & NLM_F_REPLACE)
 			return -EINVAL;
 		handle = nf_tables_alloc_handle(table);
-
-		if (chain->use == UINT_MAX)
-			return -EOVERFLOW;
 
 		if (nla[NFTA_RULE_POSITION]) {
 			pos_handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_POSITION]));
@@ -3316,16 +3495,26 @@
 		expr = nft_expr_next(expr);
 	}
 
+	if (!nft_use_inc(&chain->use)) {
+		err = -EMFILE;
+		goto err2;
+	}
+
 	if (nlh->nlmsg_flags & NLM_F_REPLACE) {
+		if (nft_chain_binding(chain)) {
+			err = -EOPNOTSUPP;
+			goto err_destroy_flow_rule;
+		}
+
 		trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
 		if (trans == NULL) {
 			err = -ENOMEM;
-			goto err2;
+			goto err_destroy_flow_rule;
 		}
 		err = nft_delrule(&ctx, old_rule);
 		if (err < 0) {
 			nft_trans_destroy(trans);
-			goto err2;
+			goto err_destroy_flow_rule;
 		}
 
 		list_add_tail_rcu(&rule->list, &old_rule->list);
@@ -3333,7 +3522,7 @@
 		trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
 		if (!trans) {
 			err = -ENOMEM;
-			goto err2;
+			goto err_destroy_flow_rule;
 		}
 
 		if (nlh->nlmsg_flags & NLM_F_APPEND) {
@@ -3349,9 +3538,8 @@
 		}
 	}
 	kvfree(info);
-	chain->use++;
 
-	if (net->nft.validate_state == NFT_VALIDATE_DO)
+	if (nft_net->validate_state == NFT_VALIDATE_DO)
 		return nft_table_validate(net, table);
 
 	if (chain->flags & NFT_CHAIN_HW_OFFLOAD) {
@@ -3363,8 +3551,12 @@
 	}
 
 	return 0;
+
+err_destroy_flow_rule:
+	nft_use_dec_restore(&chain->use);
 err2:
-	nf_tables_rule_release(&ctx, rule);
+	nft_rule_expr_deactivate(&ctx, rule, NFT_TRANS_PREPARE_ERROR);
+	nf_tables_rule_destroy(&ctx, rule);
 err1:
 	for (i = 0; i < n; i++) {
 		if (info[i].ops) {
@@ -3381,10 +3573,11 @@
 					     const struct nft_chain *chain,
 					     const struct nlattr *nla)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	u32 id = ntohl(nla_get_be32(nla));
 	struct nft_trans *trans;
 
-	list_for_each_entry(trans, &net->nft.commit_list, list) {
+	list_for_each_entry(trans, &nft_net->commit_list, list) {
 		struct nft_rule *rule = nft_trans_rule(trans);
 
 		if (trans->msg_type == NFT_MSG_NEWRULE &&
@@ -3421,7 +3614,7 @@
 			NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN]);
 			return PTR_ERR(chain);
 		}
-		if (nft_chain_is_bound(chain))
+		if (nft_chain_binding(chain))
 			return -EOPNOTSUPP;
 	}
 
@@ -3450,6 +3643,8 @@
 	} else {
 		list_for_each_entry(chain, &table->chains, list) {
 			if (!nft_is_active_next(net, chain))
+				continue;
+			if (nft_chain_binding(chain))
 				continue;
 
 			ctx.chain = chain;
@@ -3497,13 +3692,14 @@
 		   const struct nft_set_desc *desc,
 		   enum nft_set_policies policy)
 {
+	struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
 	const struct nft_set_ops *ops, *bops;
 	struct nft_set_estimate est, best;
 	const struct nft_set_type *type;
 	u32 flags = 0;
 	int i;
 
-	lockdep_assert_held(&ctx->net->nft.commit_mutex);
+	lockdep_assert_held(&nft_net->commit_mutex);
 	lockdep_nfnl_nft_mutex_not_held();
 
 	if (nla[NFTA_SET_FLAGS] != NULL)
@@ -3641,10 +3837,11 @@
 					   const struct nft_table *table,
 					   const struct nlattr *nla, u8 genmask)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	struct nft_trans *trans;
 	u32 id = ntohl(nla_get_be32(nla));
 
-	list_for_each_entry(trans, &net->nft.commit_list, list) {
+	list_for_each_entry(trans, &nft_net->commit_list, list) {
 		if (trans->msg_type == NFT_MSG_NEWSET) {
 			struct nft_set *set = nft_trans_set(trans);
 
@@ -3867,6 +4064,7 @@
 				 const struct nft_set *set, int event,
 			         gfp_t gfp_flags)
 {
+	struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
 	struct sk_buff *skb;
 	u32 portid = ctx->portid;
 	int err;
@@ -3885,7 +4083,7 @@
 		goto err;
 	}
 
-	nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
+	nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
 	return;
 err:
 	nfnetlink_set_err(ctx->net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
@@ -3898,14 +4096,16 @@
 	struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2];
 	struct net *net = sock_net(skb->sk);
 	struct nft_ctx *ctx = cb->data, ctx_set;
+	struct nftables_pernet *nft_net;
 
 	if (cb->args[1])
 		return skb->len;
 
 	rcu_read_lock();
-	cb->seq = net->nft.base_seq;
+	nft_net = net_generic(net, nf_tables_net_id);
+	cb->seq = nft_net->base_seq;
 
-	list_for_each_entry_rcu(table, &net->nft.tables, list) {
+	list_for_each_entry_rcu(table, &nft_net->tables, list) {
 		if (ctx->family != NFPROTO_UNSPEC &&
 		    ctx->family != table->family)
 			continue;
@@ -4269,9 +4469,15 @@
 	alloc_size = sizeof(*set) + size + udlen;
 	if (alloc_size < size || alloc_size > INT_MAX)
 		return -ENOMEM;
+
+	if (!nft_use_inc(&table->use))
+		return -EMFILE;
+
 	set = kvzalloc(alloc_size, GFP_KERNEL);
-	if (!set)
-		return -ENOMEM;
+	if (!set) {
+		err = -ENOMEM;
+		goto err_alloc;
+	}
 
 	name = nla_strdup(nla[NFTA_SET_NAME], GFP_KERNEL);
 	if (!name) {
@@ -4291,6 +4497,7 @@
 	}
 
 	INIT_LIST_HEAD(&set->bindings);
+	refcount_set(&set->refs, 1);
 	set->table = table;
 	write_pnet(&set->net, net);
 	set->ops = ops;
@@ -4326,25 +4533,37 @@
 	}
 
 	set->handle = nf_tables_alloc_handle(table);
+	INIT_LIST_HEAD(&set->pending_update);
 
 	err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set);
 	if (err < 0)
 		goto err_set_expr_alloc;
 
 	list_add_tail_rcu(&set->list, &table->sets);
-	table->use++;
+
 	return 0;
 
 err_set_expr_alloc:
 	if (set->expr)
 		nft_expr_destroy(&ctx, set->expr);
 
-	ops->destroy(set);
+	ops->destroy(&ctx, set);
 err_set_init:
 	kfree(set->name);
 err_set_name:
 	kvfree(set);
+err_alloc:
+	nft_use_dec_restore(&table->use);
+
 	return err;
+}
+
+static void nft_set_put(struct nft_set *set)
+{
+	if (refcount_dec_and_test(&set->refs)) {
+		kfree(set->name);
+		kvfree(set);
+	}
 }
 
 static void nft_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
@@ -4355,9 +4574,8 @@
 	if (set->expr)
 		nft_expr_destroy(ctx, set->expr);
 
-	set->ops->destroy(set);
-	kfree(set->name);
-	kvfree(set);
+	set->ops->destroy(ctx, set);
+	nft_set_put(set);
 }
 
 static int nf_tables_delset(struct net *net, struct sock *nlsk,
@@ -4409,10 +4627,9 @@
 				       enum nft_data_types type,
 				       unsigned int len);
 
-static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
-					struct nft_set *set,
-					const struct nft_set_iter *iter,
-					struct nft_set_elem *elem)
+static int nft_setelem_data_validate(const struct nft_ctx *ctx,
+				     struct nft_set *set,
+				     struct nft_set_elem *elem)
 {
 	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
 	enum nft_registers dreg;
@@ -4424,14 +4641,19 @@
 					   set->dlen);
 }
 
+static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
+					struct nft_set *set,
+					const struct nft_set_iter *iter,
+					struct nft_set_elem *elem)
+{
+	return nft_setelem_data_validate(ctx, set, elem);
+}
+
 int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
 		       struct nft_set_binding *binding)
 {
 	struct nft_set_binding *i;
 	struct nft_set_iter iter;
-
-	if (set->use == UINT_MAX)
-		return -EOVERFLOW;
 
 	if (!list_empty(&set->bindings) && nft_set_is_anonymous(set))
 		return -EBUSY;
@@ -4457,10 +4679,12 @@
 			return iter.err;
 	}
 bind:
+	if (!nft_use_inc(&set->use))
+		return -EMFILE;
+
 	binding->chain = ctx->chain;
 	list_add_tail_rcu(&binding->list, &set->bindings);
 	nft_set_trans_bind(ctx, set);
-	set->use++;
 
 	return 0;
 }
@@ -4479,17 +4703,74 @@
 	}
 }
 
+static void nft_setelem_data_activate(const struct net *net,
+				      const struct nft_set *set,
+				      struct nft_set_elem *elem);
+
+static int nft_mapelem_activate(const struct nft_ctx *ctx,
+				struct nft_set *set,
+				const struct nft_set_iter *iter,
+				struct nft_set_elem *elem)
+{
+	nft_setelem_data_activate(ctx->net, set, elem);
+
+	return 0;
+}
+
+static void nft_map_activate(const struct nft_ctx *ctx, struct nft_set *set)
+{
+	struct nft_set_iter iter = {
+		.genmask	= nft_genmask_next(ctx->net),
+		.fn		= nft_mapelem_activate,
+	};
+
+	set->ops->walk(ctx, set, &iter);
+	WARN_ON_ONCE(iter.err);
+}
+
+void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set)
+{
+	if (nft_set_is_anonymous(set)) {
+		if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
+			nft_map_activate(ctx, set);
+
+		nft_clear(ctx->net, set);
+	}
+
+	nft_use_inc_restore(&set->use);
+}
+EXPORT_SYMBOL_GPL(nf_tables_activate_set);
+
 void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
 			      struct nft_set_binding *binding,
 			      enum nft_trans_phase phase)
 {
 	switch (phase) {
+	case NFT_TRANS_PREPARE_ERROR:
+		nft_set_trans_unbind(ctx, set);
+		if (nft_set_is_anonymous(set))
+			nft_deactivate_next(ctx->net, set);
+		else
+			list_del_rcu(&binding->list);
+
+		nft_use_dec(&set->use);
+		break;
 	case NFT_TRANS_PREPARE:
-		set->use--;
+		if (nft_set_is_anonymous(set)) {
+			if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
+				nft_map_deactivate(ctx, set);
+
+			nft_deactivate_next(ctx->net, set);
+		}
+		nft_use_dec(&set->use);
 		return;
 	case NFT_TRANS_ABORT:
 	case NFT_TRANS_RELEASE:
-		set->use--;
+		if (nft_set_is_anonymous(set) &&
+		    set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
+			nft_map_deactivate(ctx, set);
+
+		nft_use_dec(&set->use);
 		fallthrough;
 	default:
 		nf_tables_unbind_set(ctx, set, binding,
@@ -4679,7 +4960,11 @@
 				  const struct nft_set_iter *iter,
 				  struct nft_set_elem *elem)
 {
+	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
 	struct nft_set_dump_args *args;
+
+	if (nft_set_elem_expired(ext))
+		return 0;
 
 	args = container_of(iter, struct nft_set_dump_args, iter);
 	return nf_tables_fill_setelem(args->skb, set, elem);
@@ -4694,6 +4979,7 @@
 {
 	struct nft_set_dump_ctx *dump_ctx = cb->data;
 	struct net *net = sock_net(skb->sk);
+	struct nftables_pernet *nft_net;
 	struct nft_table *table;
 	struct nft_set *set;
 	struct nft_set_dump_args args;
@@ -4704,7 +4990,8 @@
 	int event;
 
 	rcu_read_lock();
-	list_for_each_entry_rcu(table, &net->nft.tables, list) {
+	nft_net = net_generic(net, nf_tables_net_id);
+	list_for_each_entry_rcu(table, &nft_net->tables, list) {
 		if (dump_ctx->ctx.family != NFPROTO_UNSPEC &&
 		    dump_ctx->ctx.family != table->family)
 			continue;
@@ -4983,6 +5270,7 @@
 				     const struct nft_set_elem *elem,
 				     int event, u16 flags)
 {
+	struct nftables_pernet *nft_net;
 	struct net *net = ctx->net;
 	u32 portid = ctx->portid;
 	struct sk_buff *skb;
@@ -5002,7 +5290,8 @@
 		goto err;
 	}
 
-	nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
+	nft_net = net_generic(net, nf_tables_net_id);
+	nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
 	return;
 err:
 	nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
@@ -5091,6 +5380,7 @@
 	}
 }
 
+/* Drop references and destroy. Called from gc, dynset and abort path. */
 void nft_set_elem_destroy(const struct nft_set *set, void *elem,
 			  bool destroy_expr)
 {
@@ -5107,16 +5397,16 @@
 		nft_set_elem_expr_destroy(&ctx, nft_set_ext_expr(ext));
 
 	if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
-		(*nft_set_ext_obj(ext))->use--;
+		nft_use_dec(&(*nft_set_ext_obj(ext))->use);
 	kfree(elem);
 }
 EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
 
-/* Only called from commit path, nft_set_elem_deactivate() already deals with
- * the refcounting from the preparation phase.
+/* Destroy element. References have been already dropped in the preparation
+ * path via nft_setelem_data_deactivate().
  */
-static void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
-				       const struct nft_set *set, void *elem)
+void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
+				const struct nft_set *set, void *elem)
 {
 	struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
 
@@ -5281,8 +5571,16 @@
 				     set->objtype, genmask);
 		if (IS_ERR(obj)) {
 			err = PTR_ERR(obj);
+			obj = NULL;
 			goto err_parse_key_end;
 		}
+
+		if (!nft_use_inc(&obj->use)) {
+			err = -EMFILE;
+			obj = NULL;
+			goto err_parse_key_end;
+		}
+
 		nft_set_ext_add(&tmpl, NFT_SET_EXT_OBJREF);
 	}
 
@@ -5347,10 +5645,8 @@
 		udata->len = ulen - 1;
 		nla_memcpy(&udata->data, nla[NFTA_SET_ELEM_USERDATA], ulen);
 	}
-	if (obj) {
+	if (obj)
 		*nft_set_ext_obj(ext) = obj;
-		obj->use++;
-	}
 
 	err = nft_set_elem_expr_setup(ctx, ext, expr);
 	if (err < 0)
@@ -5363,7 +5659,8 @@
 		goto err_elem_expr;
 	}
 
-	ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
+	ext->genmask = nft_genmask_cur(ctx->net);
+
 	err = set->ops->insert(ctx->net, set, &elem, &ext2);
 	if (err) {
 		if (err == -EEXIST) {
@@ -5398,7 +5695,7 @@
 	}
 
 	nft_trans_elem(trans) = elem;
-	list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+	nft_trans_commit_list_add_tail(ctx->net, trans);
 	return 0;
 
 err_set_full:
@@ -5406,14 +5703,14 @@
 err_element_clash:
 	kfree(trans);
 err_elem_expr:
-	if (obj)
-		obj->use--;
-
 	nf_tables_set_elem_destroy(ctx, set, elem.priv);
 err_parse_data:
 	if (nla[NFTA_SET_ELEM_DATA] != NULL)
 		nft_data_release(&elem.data.val, desc.type);
 err_parse_key_end:
+	if (obj)
+		nft_use_dec_restore(&obj->use);
+
 	nft_data_release(&elem.key_end.val, NFT_DATA_VALUE);
 err_parse_key:
 	nft_data_release(&elem.key.val, NFT_DATA_VALUE);
@@ -5429,6 +5726,7 @@
 				const struct nlattr * const nla[],
 				struct netlink_ext_ack *extack)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	u8 genmask = nft_genmask_next(net);
 	const struct nlattr *attr;
 	struct nft_set *set;
@@ -5448,7 +5746,8 @@
 	if (IS_ERR(set))
 		return PTR_ERR(set);
 
-	if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
+	if (!list_empty(&set->bindings) &&
+	    (set->flags & (NFT_SET_CONSTANT | NFT_SET_ANONYMOUS)))
 		return -EBUSY;
 
 	nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
@@ -5457,7 +5756,7 @@
 			return err;
 	}
 
-	if (net->nft.validate_state == NFT_VALIDATE_DO)
+	if (nft_net->validate_state == NFT_VALIDATE_DO)
 		return nft_table_validate(net, ctx.table);
 
 	return 0;
@@ -5477,50 +5776,40 @@
 void nft_data_hold(const struct nft_data *data, enum nft_data_types type)
 {
 	struct nft_chain *chain;
-	struct nft_rule *rule;
 
 	if (type == NFT_DATA_VERDICT) {
 		switch (data->verdict.code) {
 		case NFT_JUMP:
 		case NFT_GOTO:
 			chain = data->verdict.chain;
-			chain->use++;
-
-			if (!nft_chain_is_bound(chain))
-				break;
-
-			chain->table->use++;
-			list_for_each_entry(rule, &chain->rules, list)
-				chain->use++;
-
-			nft_chain_add(chain->table, chain);
+			nft_use_inc_restore(&chain->use);
 			break;
 		}
 	}
 }
 
-static void nft_set_elem_activate(const struct net *net,
-				  const struct nft_set *set,
-				  struct nft_set_elem *elem)
+static void nft_setelem_data_activate(const struct net *net,
+				      const struct nft_set *set,
+				      struct nft_set_elem *elem)
 {
 	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
 
 	if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
 		nft_data_hold(nft_set_ext_data(ext), set->dtype);
 	if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
-		(*nft_set_ext_obj(ext))->use++;
+		nft_use_inc_restore(&(*nft_set_ext_obj(ext))->use);
 }
 
-static void nft_set_elem_deactivate(const struct net *net,
-				    const struct nft_set *set,
-				    struct nft_set_elem *elem)
+void nft_setelem_data_deactivate(const struct net *net,
+				 const struct nft_set *set,
+				 struct nft_set_elem *elem)
 {
 	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
 
 	if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
 		nft_data_release(nft_set_ext_data(ext), set->dtype);
 	if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
-		(*nft_set_ext_obj(ext))->use--;
+		nft_use_dec(&(*nft_set_ext_obj(ext))->use);
 }
 
 static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
@@ -5590,10 +5879,10 @@
 	kfree(elem.priv);
 	elem.priv = priv;
 
-	nft_set_elem_deactivate(ctx->net, set, &elem);
+	nft_setelem_data_deactivate(ctx->net, set, &elem);
 
 	nft_trans_elem(trans) = elem;
-	list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+	nft_trans_commit_list_add_tail(ctx->net, trans);
 	return 0;
 
 fail_ops:
@@ -5624,10 +5913,10 @@
 	}
 	set->ndeact++;
 
-	nft_set_elem_deactivate(ctx->net, set, elem);
+	nft_setelem_data_deactivate(ctx->net, set, elem);
 	nft_trans_elem_set(trans) = set;
 	nft_trans_elem(trans) = *elem;
-	list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+	nft_trans_commit_list_add_tail(ctx->net, trans);
 
 	return 0;
 err1:
@@ -5654,7 +5943,11 @@
 	set = nft_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET], genmask);
 	if (IS_ERR(set))
 		return PTR_ERR(set);
-	if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
+
+	if (nft_set_is_anonymous(set))
+		return -EOPNOTSUPP;
+
+	if (!list_empty(&set->bindings) && (set->flags & NFT_SET_CONSTANT))
 		return -EBUSY;
 
 	if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) {
@@ -5675,29 +5968,6 @@
 		set->ndeact++;
 	}
 	return err;
-}
-
-void nft_set_gc_batch_release(struct rcu_head *rcu)
-{
-	struct nft_set_gc_batch *gcb;
-	unsigned int i;
-
-	gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu);
-	for (i = 0; i < gcb->head.cnt; i++)
-		nft_set_elem_destroy(gcb->head.set, gcb->elems[i], true);
-	kfree(gcb);
-}
-
-struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
-						gfp_t gfp)
-{
-	struct nft_set_gc_batch *gcb;
-
-	gcb = kzalloc(sizeof(*gcb), gfp);
-	if (gcb == NULL)
-		return gcb;
-	gcb->head.set = set;
-	return gcb;
 }
 
 /*
@@ -5924,7 +6194,7 @@
 	nft_trans_obj(trans) = obj;
 	nft_trans_obj_update(trans) = true;
 	nft_trans_obj_newobj(trans) = newobj;
-	list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+	nft_trans_commit_list_add_tail(ctx->net, trans);
 
 	return 0;
 
@@ -5985,9 +6255,14 @@
 
 	nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
 
+	if (!nft_use_inc(&table->use))
+		return -EMFILE;
+
 	type = nft_obj_type_get(net, objtype);
-	if (IS_ERR(type))
-		return PTR_ERR(type);
+	if (IS_ERR(type)) {
+		err = PTR_ERR(type);
+		goto err_type;
+	}
 
 	obj = nft_obj_init(&ctx, type, nla[NFTA_OBJ_DATA]);
 	if (IS_ERR(obj)) {
@@ -6021,7 +6296,7 @@
 		goto err_obj_ht;
 
 	list_add_tail_rcu(&obj->list, &table->objects);
-	table->use++;
+
 	return 0;
 err_obj_ht:
 	/* queued in transaction log */
@@ -6037,6 +6312,9 @@
 	kfree(obj);
 err_init:
 	module_put(type->owner);
+err_type:
+	nft_use_dec_restore(&table->use);
+
 	return err;
 }
 
@@ -6087,6 +6365,7 @@
 	struct nft_obj_filter *filter = cb->data;
 	struct net *net = sock_net(skb->sk);
 	int family = nfmsg->nfgen_family;
+	struct nftables_pernet *nft_net;
 	struct nft_object *obj;
 	bool reset = false;
 
@@ -6094,9 +6373,10 @@
 		reset = true;
 
 	rcu_read_lock();
-	cb->seq = net->nft.base_seq;
+	nft_net = net_generic(net, nf_tables_net_id);
+	cb->seq = nft_net->base_seq;
 
-	list_for_each_entry_rcu(table, &net->nft.tables, list) {
+	list_for_each_entry_rcu(table, &nft_net->tables, list) {
 		if (family != NFPROTO_UNSPEC && family != table->family)
 			continue;
 
@@ -6119,7 +6399,7 @@
 				char *buf = kasprintf(GFP_ATOMIC,
 						      "%s:%u",
 						      table->name,
-						      net->nft.base_seq);
+						      nft_net->base_seq);
 
 				audit_log_nfcfg(buf,
 						family,
@@ -6240,8 +6520,11 @@
 		reset = true;
 
 	if (reset) {
-		char *buf = kasprintf(GFP_ATOMIC, "%s:%u",
-				      table->name, net->nft.base_seq);
+		const struct nftables_pernet *nft_net;
+		char *buf;
+
+		nft_net = net_generic(net, nf_tables_net_id);
+		buf = kasprintf(GFP_ATOMIC, "%s:%u", table->name, nft_net->base_seq);
 
 		audit_log_nfcfg(buf,
 				family,
@@ -6326,10 +6609,11 @@
 		    struct nft_object *obj, u32 portid, u32 seq, int event,
 		    int family, int report, gfp_t gfp)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	struct sk_buff *skb;
 	int err;
 	char *buf = kasprintf(gfp, "%s:%u",
-			      table->name, net->nft.base_seq);
+			      table->name, nft_net->base_seq);
 
 	audit_log_nfcfg(buf,
 			family,
@@ -6355,7 +6639,7 @@
 		goto err;
 	}
 
-	nft_notify_enqueue(skb, report, &net->nft.notify_list);
+	nft_notify_enqueue(skb, report, &nft_net->notify_list);
 	return;
 err:
 	nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
@@ -6417,10 +6701,11 @@
 				    enum nft_trans_phase phase)
 {
 	switch (phase) {
+	case NFT_TRANS_PREPARE_ERROR:
 	case NFT_TRANS_PREPARE:
 	case NFT_TRANS_ABORT:
 	case NFT_TRANS_RELEASE:
-		flowtable->use--;
+		nft_use_dec(&flowtable->use);
 		fallthrough;
 	default:
 		return;
@@ -6560,13 +6845,25 @@
 				    FLOW_BLOCK_UNBIND);
 }
 
+static void __nft_unregister_flowtable_net_hooks(struct net *net,
+						 struct list_head *hook_list,
+					         bool release_netdev)
+{
+	struct nft_hook *hook, *next;
+
+	list_for_each_entry_safe(hook, next, hook_list, list) {
+		nf_unregister_net_hook(net, &hook->ops);
+		if (release_netdev) {
+			list_del(&hook->list);
+			kfree_rcu(hook, rcu);
+		}
+	}
+}
+
 static void nft_unregister_flowtable_net_hooks(struct net *net,
 					       struct list_head *hook_list)
 {
-	struct nft_hook *hook;
-
-	list_for_each_entry(hook, hook_list, list)
-		nf_unregister_net_hook(net, &hook->ops);
+	__nft_unregister_flowtable_net_hooks(net, hook_list, false);
 }
 
 static int nft_register_flowtable_net_hooks(struct net *net,
@@ -6691,7 +6988,7 @@
 	INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans));
 	list_splice(&flowtable_hook.list, &nft_trans_flowtable_hooks(trans));
 
-	list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+	nft_trans_commit_list_add_tail(ctx->net, trans);
 
 	return 0;
 
@@ -6757,9 +7054,14 @@
 
 	nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
 
+	if (!nft_use_inc(&table->use))
+		return -EMFILE;
+
 	flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL);
-	if (!flowtable)
-		return -ENOMEM;
+	if (!flowtable) {
+		err = -ENOMEM;
+		goto flowtable_alloc;
+	}
 
 	flowtable->table = table;
 	flowtable->handle = nf_tables_alloc_handle(table);
@@ -6814,7 +7116,6 @@
 		goto err5;
 
 	list_add_tail_rcu(&flowtable->list, &table->flowtables);
-	table->use++;
 
 	return 0;
 err5:
@@ -6831,6 +7132,9 @@
 	kfree(flowtable->name);
 err1:
 	kfree(flowtable);
+flowtable_alloc:
+	nft_use_dec_restore(&table->use);
+
 	return err;
 }
 
@@ -6881,7 +7185,7 @@
 	list_splice(&flowtable_del_list, &nft_trans_flowtable_hooks(trans));
 	nft_flowtable_hook_release(&flowtable_hook);
 
-	list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+	nft_trans_commit_list_add_tail(ctx->net, trans);
 
 	return 0;
 
@@ -7007,12 +7311,14 @@
 	struct net *net = sock_net(skb->sk);
 	int family = nfmsg->nfgen_family;
 	struct nft_flowtable *flowtable;
+	struct nftables_pernet *nft_net;
 	const struct nft_table *table;
 
 	rcu_read_lock();
-	cb->seq = net->nft.base_seq;
+	nft_net = net_generic(net, nf_tables_net_id);
+	cb->seq = nft_net->base_seq;
 
-	list_for_each_entry_rcu(table, &net->nft.tables, list) {
+	list_for_each_entry_rcu(table, &nft_net->tables, list) {
 		if (family != NFPROTO_UNSPEC && family != table->family)
 			continue;
 
@@ -7147,6 +7453,7 @@
 				       struct list_head *hook_list,
 				       int event)
 {
+	struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
 	struct sk_buff *skb;
 	int err;
 
@@ -7166,7 +7473,7 @@
 		goto err;
 	}
 
-	nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
+	nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
 	return;
 err:
 	nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
@@ -7191,6 +7498,7 @@
 static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net,
 				   u32 portid, u32 seq)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	struct nlmsghdr *nlh;
 	char buf[TASK_COMM_LEN];
 	int event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWGEN);
@@ -7200,7 +7508,7 @@
 	if (!nlh)
 		goto nla_put_failure;
 
-	if (nla_put_be32(skb, NFTA_GEN_ID, htonl(net->nft.base_seq)) ||
+	if (nla_put_be32(skb, NFTA_GEN_ID, htonl(nft_net->base_seq)) ||
 	    nla_put_be32(skb, NFTA_GEN_PROC_PID, htonl(task_pid_nr(current))) ||
 	    nla_put_string(skb, NFTA_GEN_PROC_NAME, get_task_comm(buf, current)))
 		goto nla_put_failure;
@@ -7235,6 +7543,7 @@
 {
 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct nft_flowtable *flowtable;
+	struct nftables_pernet *nft_net;
 	struct nft_table *table;
 	struct net *net;
 
@@ -7242,13 +7551,14 @@
 		return 0;
 
 	net = dev_net(dev);
-	mutex_lock(&net->nft.commit_mutex);
-	list_for_each_entry(table, &net->nft.tables, list) {
+	nft_net = net_generic(net, nf_tables_net_id);
+	mutex_lock(&nft_net->commit_mutex);
+	list_for_each_entry(table, &nft_net->tables, list) {
 		list_for_each_entry(flowtable, &table->flowtables, list) {
 			nft_flowtable_event(event, dev, flowtable);
 		}
 	}
-	mutex_unlock(&net->nft.commit_mutex);
+	mutex_unlock(&nft_net->commit_mutex);
 
 	return NOTIFY_DONE;
 }
@@ -7429,19 +7739,22 @@
 
 static int nf_tables_validate(struct net *net)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	struct nft_table *table;
 
-	switch (net->nft.validate_state) {
+	switch (nft_net->validate_state) {
 	case NFT_VALIDATE_SKIP:
 		break;
 	case NFT_VALIDATE_NEED:
 		nft_validate_state_update(net, NFT_VALIDATE_DO);
 		fallthrough;
 	case NFT_VALIDATE_DO:
-		list_for_each_entry(table, &net->nft.tables, list) {
+		list_for_each_entry(table, &nft_net->tables, list) {
 			if (nft_table_validate(net, table) < 0)
 				return -EAGAIN;
 		}
+
+		nft_validate_state_update(net, NFT_VALIDATE_SKIP);
 		break;
 	}
 
@@ -7569,7 +7882,7 @@
 	synchronize_rcu();
 
 	list_for_each_entry_safe(trans, next, &head, list) {
-		list_del(&trans->list);
+		nft_trans_list_del(trans);
 		nft_commit_release(trans);
 	}
 }
@@ -7613,9 +7926,10 @@
 
 static void nf_tables_commit_chain_prepare_cancel(struct net *net)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	struct nft_trans *trans, *next;
 
-	list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
+	list_for_each_entry_safe(trans, next, &nft_net->commit_list, list) {
 		struct nft_chain *chain = trans->ctx.chain;
 
 		if (trans->msg_type == NFT_MSG_NEWRULE ||
@@ -7711,12 +8025,197 @@
 	list_del_rcu(&chain->list);
 }
 
+static void nft_trans_gc_setelem_remove(struct nft_ctx *ctx,
+					struct nft_trans_gc *trans)
+{
+	void **priv = trans->priv;
+	unsigned int i;
+
+	for (i = 0; i < trans->count; i++) {
+		struct nft_set_elem elem = {
+			.priv = priv[i],
+		};
+
+		nft_setelem_data_deactivate(ctx->net, trans->set, &elem);
+		trans->set->ops->remove(trans->net, trans->set, &elem);
+	}
+}
+
+void nft_trans_gc_destroy(struct nft_trans_gc *trans)
+{
+	nft_set_put(trans->set);
+	put_net(trans->net);
+	kfree(trans);
+}
+
+static void nft_trans_gc_trans_free(struct rcu_head *rcu)
+{
+	struct nft_set_elem elem = {};
+	struct nft_trans_gc *trans;
+	struct nft_ctx ctx = {};
+	unsigned int i;
+
+	trans = container_of(rcu, struct nft_trans_gc, rcu);
+	ctx.net = read_pnet(&trans->set->net);
+
+	for (i = 0; i < trans->count; i++) {
+		elem.priv = trans->priv[i];
+		atomic_dec(&trans->set->nelems);
+
+		nf_tables_set_elem_destroy(&ctx, trans->set, elem.priv);
+	}
+
+	nft_trans_gc_destroy(trans);
+}
+
+static bool nft_trans_gc_work_done(struct nft_trans_gc *trans)
+{
+	struct nftables_pernet *nft_net;
+	struct nft_ctx ctx = {};
+
+	nft_net = net_generic(trans->net, nf_tables_net_id);
+
+	mutex_lock(&nft_net->commit_mutex);
+
+	/* Check for race with transaction, otherwise this batch refers to
+	 * stale objects that might not be there anymore. Skip transaction if
+	 * set has been destroyed from control plane transaction in case gc
+	 * worker loses race.
+	 */
+	if (READ_ONCE(nft_net->gc_seq) != trans->seq || trans->set->dead) {
+		mutex_unlock(&nft_net->commit_mutex);
+		return false;
+	}
+
+	ctx.net = trans->net;
+	ctx.table = trans->set->table;
+
+	nft_trans_gc_setelem_remove(&ctx, trans);
+	mutex_unlock(&nft_net->commit_mutex);
+
+	return true;
+}
+
+static void nft_trans_gc_work(struct work_struct *work)
+{
+	struct nft_trans_gc *trans, *next;
+	LIST_HEAD(trans_gc_list);
+
+	spin_lock(&nf_tables_gc_list_lock);
+	list_splice_init(&nf_tables_gc_list, &trans_gc_list);
+	spin_unlock(&nf_tables_gc_list_lock);
+
+	list_for_each_entry_safe(trans, next, &trans_gc_list, list) {
+		list_del(&trans->list);
+		if (!nft_trans_gc_work_done(trans)) {
+			nft_trans_gc_destroy(trans);
+			continue;
+		}
+		call_rcu(&trans->rcu, nft_trans_gc_trans_free);
+	}
+}
+
+struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set,
+					unsigned int gc_seq, gfp_t gfp)
+{
+	struct net *net = read_pnet(&set->net);
+	struct nft_trans_gc *trans;
+
+	trans = kzalloc(sizeof(*trans), gfp);
+	if (!trans)
+		return NULL;
+
+	trans->net = maybe_get_net(net);
+	if (!trans->net) {
+		kfree(trans);
+		return NULL;
+	}
+
+	refcount_inc(&set->refs);
+	trans->set = set;
+	trans->seq = gc_seq;
+
+	return trans;
+}
+
+void nft_trans_gc_elem_add(struct nft_trans_gc *trans, void *priv)
+{
+	trans->priv[trans->count++] = priv;
+}
+
+static void nft_trans_gc_queue_work(struct nft_trans_gc *trans)
+{
+	spin_lock(&nf_tables_gc_list_lock);
+	list_add_tail(&trans->list, &nf_tables_gc_list);
+	spin_unlock(&nf_tables_gc_list_lock);
+
+	schedule_work(&trans_gc_work);
+}
+
+static int nft_trans_gc_space(struct nft_trans_gc *trans)
+{
+	return NFT_TRANS_GC_BATCHCOUNT - trans->count;
+}
+
+struct nft_trans_gc *nft_trans_gc_queue_async(struct nft_trans_gc *gc,
+					      unsigned int gc_seq, gfp_t gfp)
+{
+	struct nft_set *set;
+
+	if (nft_trans_gc_space(gc))
+		return gc;
+
+	set = gc->set;
+	nft_trans_gc_queue_work(gc);
+
+	return nft_trans_gc_alloc(set, gc_seq, gfp);
+}
+
+void nft_trans_gc_queue_async_done(struct nft_trans_gc *trans)
+{
+	if (trans->count == 0) {
+		nft_trans_gc_destroy(trans);
+		return;
+	}
+
+	nft_trans_gc_queue_work(trans);
+}
+
+struct nft_trans_gc *nft_trans_gc_queue_sync(struct nft_trans_gc *gc, gfp_t gfp)
+{
+	struct nft_set *set;
+
+	if (WARN_ON_ONCE(!lockdep_commit_lock_is_held(gc->net)))
+		return NULL;
+
+	if (nft_trans_gc_space(gc))
+		return gc;
+
+	set = gc->set;
+	call_rcu(&gc->rcu, nft_trans_gc_trans_free);
+
+	return nft_trans_gc_alloc(set, 0, gfp);
+}
+
+void nft_trans_gc_queue_sync_done(struct nft_trans_gc *trans)
+{
+	WARN_ON_ONCE(!lockdep_commit_lock_is_held(trans->net));
+
+	if (trans->count == 0) {
+		nft_trans_gc_destroy(trans);
+		return;
+	}
+
+	call_rcu(&trans->rcu, nft_trans_gc_trans_free);
+}
+
 static void nf_tables_module_autoload_cleanup(struct net *net)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	struct nft_module_request *req, *next;
 
-	WARN_ON_ONCE(!list_empty(&net->nft.commit_list));
-	list_for_each_entry_safe(req, next, &net->nft.module_list, list) {
+	WARN_ON_ONCE(!list_empty(&nft_net->commit_list));
+	list_for_each_entry_safe(req, next, &nft_net->module_list, list) {
 		WARN_ON_ONCE(!req->done);
 		list_del(&req->list);
 		kfree(req);
@@ -7725,6 +8224,7 @@
 
 static void nf_tables_commit_release(struct net *net)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	struct nft_trans *trans;
 
 	/* all side effects have to be made visible.
@@ -7734,35 +8234,36 @@
 	 * Memory reclaim happens asynchronously from work queue
 	 * to prevent expensive synchronize_rcu() in commit phase.
 	 */
-	if (list_empty(&net->nft.commit_list)) {
+	if (list_empty(&nft_net->commit_list)) {
 		nf_tables_module_autoload_cleanup(net);
-		mutex_unlock(&net->nft.commit_mutex);
+		mutex_unlock(&nft_net->commit_mutex);
 		return;
 	}
 
-	trans = list_last_entry(&net->nft.commit_list,
+	trans = list_last_entry(&nft_net->commit_list,
 				struct nft_trans, list);
 	get_net(trans->ctx.net);
 	WARN_ON_ONCE(trans->put_net);
 
 	trans->put_net = true;
 	spin_lock(&nf_tables_destroy_list_lock);
-	list_splice_tail_init(&net->nft.commit_list, &nf_tables_destroy_list);
+	list_splice_tail_init(&nft_net->commit_list, &nf_tables_destroy_list);
 	spin_unlock(&nf_tables_destroy_list_lock);
 
 	nf_tables_module_autoload_cleanup(net);
 	schedule_work(&trans_destroy_work);
 
-	mutex_unlock(&net->nft.commit_mutex);
+	mutex_unlock(&nft_net->commit_mutex);
 }
 
 static void nft_commit_notify(struct net *net, u32 portid)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	struct sk_buff *batch_skb = NULL, *nskb, *skb;
 	unsigned char *data;
 	int len;
 
-	list_for_each_entry_safe(skb, nskb, &net->nft.notify_list, list) {
+	list_for_each_entry_safe(skb, nskb, &nft_net->notify_list, list) {
 		if (!batch_skb) {
 new_batch:
 			batch_skb = skb;
@@ -7788,7 +8289,7 @@
 			       NFT_CB(batch_skb).report, GFP_KERNEL);
 	}
 
-	WARN_ON_ONCE(!list_empty(&net->nft.notify_list));
+	WARN_ON_ONCE(!list_empty(&nft_net->notify_list));
 }
 
 static int nf_tables_commit_audit_alloc(struct list_head *adl,
@@ -7852,18 +8353,71 @@
 	}
 }
 
+static void nft_set_commit_update(struct list_head *set_update_list)
+{
+	struct nft_set *set, *next;
+
+	list_for_each_entry_safe(set, next, set_update_list, pending_update) {
+		list_del_init(&set->pending_update);
+
+		if (!set->ops->commit)
+			continue;
+
+		set->ops->commit(set);
+	}
+}
+
+static unsigned int nft_gc_seq_begin(struct nftables_pernet *nft_net)
+{
+	unsigned int gc_seq;
+
+	/* Bump gc counter, it becomes odd, this is the busy mark. */
+	gc_seq = READ_ONCE(nft_net->gc_seq);
+	WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
+
+	return gc_seq;
+}
+
+static void nft_gc_seq_end(struct nftables_pernet *nft_net, unsigned int gc_seq)
+{
+	WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
+}
+
 static int nf_tables_commit(struct net *net, struct sk_buff *skb)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	struct nft_trans *trans, *next;
+	LIST_HEAD(set_update_list);
 	struct nft_trans_elem *te;
 	struct nft_chain *chain;
 	struct nft_table *table;
+	unsigned int gc_seq;
 	LIST_HEAD(adl);
 	int err;
 
-	if (list_empty(&net->nft.commit_list)) {
-		mutex_unlock(&net->nft.commit_mutex);
+	if (list_empty(&nft_net->commit_list)) {
+		mutex_unlock(&nft_net->commit_mutex);
 		return 0;
+	}
+
+	list_for_each_entry(trans, &nft_net->binding_list, binding_list) {
+		switch (trans->msg_type) {
+		case NFT_MSG_NEWSET:
+			if (nft_set_is_anonymous(nft_trans_set(trans)) &&
+			    !nft_trans_set_bound(trans)) {
+				pr_warn_once("nftables ruleset with unbound set\n");
+				return -EINVAL;
+			}
+			break;
+		case NFT_MSG_NEWCHAIN:
+			if (!nft_trans_chain_update(trans) &&
+			    nft_chain_binding(nft_trans_chain(trans)) &&
+			    !nft_trans_chain_bound(trans)) {
+				pr_warn_once("nftables ruleset with unbound chain\n");
+				return -EINVAL;
+			}
+			break;
+		}
 	}
 
 	/* 0. Validate ruleset, otherwise roll back for error reporting. */
@@ -7875,7 +8429,7 @@
 		return err;
 
 	/* 1.  Allocate space for next generation rules_gen_X[] */
-	list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
+	list_for_each_entry_safe(trans, next, &nft_net->commit_list, list) {
 		int ret;
 
 		ret = nf_tables_commit_audit_alloc(&adl, trans->ctx.table);
@@ -7898,7 +8452,7 @@
 	}
 
 	/* step 2.  Make rules_gen_X visible to packet path */
-	list_for_each_entry(table, &net->nft.tables, list) {
+	list_for_each_entry(table, &nft_net->tables, list) {
 		list_for_each_entry(chain, &table->chains, list)
 			nf_tables_commit_chain(net, chain);
 	}
@@ -7907,12 +8461,15 @@
 	 * Bump generation counter, invalidate any dump in progress.
 	 * Cannot fail after this point.
 	 */
-	while (++net->nft.base_seq == 0);
+	while (++nft_net->base_seq == 0)
+		;
+
+	gc_seq = nft_gc_seq_begin(nft_net);
 
 	/* step 3. Start new generation, rules_gen_X now in use. */
 	net->nft.gencursor = nft_gencursor_next(net);
 
-	list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
+	list_for_each_entry_safe(trans, next, &nft_net->commit_list, list) {
 		nf_tables_commit_audit_collect(&adl, trans->ctx.table,
 					       trans->msg_type);
 		switch (trans->msg_type) {
@@ -7981,13 +8538,14 @@
 			 */
 			if (nft_set_is_anonymous(nft_trans_set(trans)) &&
 			    !list_empty(&nft_trans_set(trans)->bindings))
-				trans->ctx.table->use--;
+				nft_use_dec(&trans->ctx.table->use);
 
 			nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
 					     NFT_MSG_NEWSET, GFP_KERNEL);
 			nft_trans_destroy(trans);
 			break;
 		case NFT_MSG_DELSET:
+			nft_trans_set(trans)->dead = 1;
 			list_del_rcu(&nft_trans_set(trans)->list);
 			nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
 					     NFT_MSG_DELSET, GFP_KERNEL);
@@ -7999,6 +8557,11 @@
 			nf_tables_setelem_notify(&trans->ctx, te->set,
 						 &te->elem,
 						 NFT_MSG_NEWSETELEM, 0);
+			if (te->set->ops->commit &&
+			    list_empty(&te->set->pending_update)) {
+				list_add_tail(&te->set->pending_update,
+					      &set_update_list);
+			}
 			nft_trans_destroy(trans);
 			break;
 		case NFT_MSG_DELSETELEM:
@@ -8010,6 +8573,11 @@
 			te->set->ops->remove(net, te->set, &te->elem);
 			atomic_dec(&te->set->nelems);
 			te->set->ndeact--;
+			if (te->set->ops->commit &&
+			    list_empty(&te->set->pending_update)) {
+				list_add_tail(&te->set->pending_update,
+					      &set_update_list);
+			}
 			break;
 		case NFT_MSG_NEWOBJ:
 			if (nft_trans_obj_update(trans)) {
@@ -8070,9 +8638,13 @@
 		}
 	}
 
+	nft_set_commit_update(&set_update_list);
+
 	nft_commit_notify(net, NETLINK_CB(skb).portid);
 	nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
-	nf_tables_commit_audit_log(&adl, net->nft.base_seq);
+	nf_tables_commit_audit_log(&adl, nft_net->base_seq);
+
+	nft_gc_seq_end(nft_net, gc_seq);
 	nf_tables_commit_release(net);
 
 	return 0;
@@ -8080,17 +8652,18 @@
 
 static void nf_tables_module_autoload(struct net *net)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	struct nft_module_request *req, *next;
 	LIST_HEAD(module_list);
 
-	list_splice_init(&net->nft.module_list, &module_list);
-	mutex_unlock(&net->nft.commit_mutex);
+	list_splice_init(&nft_net->module_list, &module_list);
+	mutex_unlock(&nft_net->commit_mutex);
 	list_for_each_entry_safe(req, next, &module_list, list) {
 		request_module("%s", req->module);
 		req->done = true;
 	}
-	mutex_lock(&net->nft.commit_mutex);
-	list_splice(&module_list, &net->nft.module_list);
+	mutex_lock(&nft_net->commit_mutex);
+	list_splice(&module_list, &nft_net->module_list);
 }
 
 static void nf_tables_abort_release(struct nft_trans *trans)
@@ -8125,16 +8698,32 @@
 	kfree(trans);
 }
 
+static void nft_set_abort_update(struct list_head *set_update_list)
+{
+	struct nft_set *set, *next;
+
+	list_for_each_entry_safe(set, next, set_update_list, pending_update) {
+		list_del_init(&set->pending_update);
+
+		if (!set->ops->abort)
+			continue;
+
+		set->ops->abort(set);
+	}
+}
+
 static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	struct nft_trans *trans, *next;
+	LIST_HEAD(set_update_list);
 	struct nft_trans_elem *te;
 
 	if (action == NFNL_ABORT_VALIDATE &&
 	    nf_tables_validate(net) < 0)
 		return -EAGAIN;
 
-	list_for_each_entry_safe_reverse(trans, next, &net->nft.commit_list,
+	list_for_each_entry_safe_reverse(trans, next, &nft_net->commit_list,
 					 list) {
 		switch (trans->msg_type) {
 		case NFT_MSG_NEWTABLE:
@@ -8159,11 +8748,11 @@
 				kfree(nft_trans_chain_name(trans));
 				nft_trans_destroy(trans);
 			} else {
-				if (nft_chain_is_bound(trans->ctx.chain)) {
+				if (nft_trans_chain_bound(trans)) {
 					nft_trans_destroy(trans);
 					break;
 				}
-				trans->ctx.table->use--;
+				nft_use_dec_restore(&trans->ctx.table->use);
 				nft_chain_del(trans->ctx.chain);
 				nf_tables_unregister_hook(trans->ctx.net,
 							  trans->ctx.table,
@@ -8171,25 +8760,29 @@
 			}
 			break;
 		case NFT_MSG_DELCHAIN:
-			trans->ctx.table->use++;
+			nft_use_inc_restore(&trans->ctx.table->use);
 			nft_clear(trans->ctx.net, trans->ctx.chain);
 			nft_trans_destroy(trans);
 			break;
 		case NFT_MSG_NEWRULE:
-			trans->ctx.chain->use--;
+			if (nft_trans_rule_bound(trans)) {
+				nft_trans_destroy(trans);
+				break;
+			}
+			nft_use_dec_restore(&trans->ctx.chain->use);
 			list_del_rcu(&nft_trans_rule(trans)->list);
 			nft_rule_expr_deactivate(&trans->ctx,
 						 nft_trans_rule(trans),
 						 NFT_TRANS_ABORT);
 			break;
 		case NFT_MSG_DELRULE:
-			trans->ctx.chain->use++;
+			nft_use_inc_restore(&trans->ctx.chain->use);
 			nft_clear(trans->ctx.net, nft_trans_rule(trans));
 			nft_rule_expr_activate(&trans->ctx, nft_trans_rule(trans));
 			nft_trans_destroy(trans);
 			break;
 		case NFT_MSG_NEWSET:
-			trans->ctx.table->use--;
+			nft_use_dec_restore(&trans->ctx.table->use);
 			if (nft_trans_set_bound(trans)) {
 				nft_trans_destroy(trans);
 				break;
@@ -8197,8 +8790,11 @@
 			list_del_rcu(&nft_trans_set(trans)->list);
 			break;
 		case NFT_MSG_DELSET:
-			trans->ctx.table->use++;
+			nft_use_inc_restore(&trans->ctx.table->use);
 			nft_clear(trans->ctx.net, nft_trans_set(trans));
+			if (nft_trans_set(trans)->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
+				nft_map_activate(&trans->ctx, nft_trans_set(trans));
+
 			nft_trans_destroy(trans);
 			break;
 		case NFT_MSG_NEWSETELEM:
@@ -8209,14 +8805,25 @@
 			te = (struct nft_trans_elem *)trans->data;
 			te->set->ops->remove(net, te->set, &te->elem);
 			atomic_dec(&te->set->nelems);
+
+			if (te->set->ops->abort &&
+			    list_empty(&te->set->pending_update)) {
+				list_add_tail(&te->set->pending_update,
+					      &set_update_list);
+			}
 			break;
 		case NFT_MSG_DELSETELEM:
 			te = (struct nft_trans_elem *)trans->data;
 
-			nft_set_elem_activate(net, te->set, &te->elem);
+			nft_setelem_data_activate(net, te->set, &te->elem);
 			te->set->ops->activate(net, te->set, &te->elem);
 			te->set->ndeact--;
 
+			if (te->set->ops->abort &&
+			    list_empty(&te->set->pending_update)) {
+				list_add_tail(&te->set->pending_update,
+					      &set_update_list);
+			}
 			nft_trans_destroy(trans);
 			break;
 		case NFT_MSG_NEWOBJ:
@@ -8224,12 +8831,12 @@
 				nft_obj_destroy(&trans->ctx, nft_trans_obj_newobj(trans));
 				nft_trans_destroy(trans);
 			} else {
-				trans->ctx.table->use--;
+				nft_use_dec_restore(&trans->ctx.table->use);
 				nft_obj_del(nft_trans_obj(trans));
 			}
 			break;
 		case NFT_MSG_DELOBJ:
-			trans->ctx.table->use++;
+			nft_use_inc_restore(&trans->ctx.table->use);
 			nft_clear(trans->ctx.net, nft_trans_obj(trans));
 			nft_trans_destroy(trans);
 			break;
@@ -8238,7 +8845,7 @@
 				nft_unregister_flowtable_net_hooks(net,
 						&nft_trans_flowtable_hooks(trans));
 			} else {
-				trans->ctx.table->use--;
+				nft_use_dec_restore(&trans->ctx.table->use);
 				list_del_rcu(&nft_trans_flowtable(trans)->list);
 				nft_unregister_flowtable_net_hooks(net,
 						&nft_trans_flowtable(trans)->hook_list);
@@ -8249,7 +8856,7 @@
 				list_splice(&nft_trans_flowtable_hooks(trans),
 					    &nft_trans_flowtable(trans)->hook_list);
 			} else {
-				trans->ctx.table->use++;
+				nft_use_inc_restore(&trans->ctx.table->use);
 				nft_clear(trans->ctx.net, nft_trans_flowtable(trans));
 			}
 			nft_trans_destroy(trans);
@@ -8257,11 +8864,13 @@
 		}
 	}
 
+	nft_set_abort_update(&set_update_list);
+
 	synchronize_rcu();
 
 	list_for_each_entry_safe_reverse(trans, next,
-					 &net->nft.commit_list, list) {
-		list_del(&trans->list);
+					 &nft_net->commit_list, list) {
+		nft_trans_list_del(trans);
 		nf_tables_abort_release(trans);
 	}
 
@@ -8273,30 +8882,32 @@
 	return 0;
 }
 
-static void nf_tables_cleanup(struct net *net)
-{
-	nft_validate_state_update(net, NFT_VALIDATE_SKIP);
-}
-
 static int nf_tables_abort(struct net *net, struct sk_buff *skb,
 			   enum nfnl_abort_action action)
 {
-	int ret = __nf_tables_abort(net, action);
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
+	unsigned int gc_seq;
+	int ret;
 
-	mutex_unlock(&net->nft.commit_mutex);
+	gc_seq = nft_gc_seq_begin(nft_net);
+	ret = __nf_tables_abort(net, action);
+	nft_gc_seq_end(nft_net, gc_seq);
+
+	mutex_unlock(&nft_net->commit_mutex);
 
 	return ret;
 }
 
 static bool nf_tables_valid_genid(struct net *net, u32 genid)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	bool genid_ok;
 
-	mutex_lock(&net->nft.commit_mutex);
+	mutex_lock(&nft_net->commit_mutex);
 
-	genid_ok = genid == 0 || net->nft.base_seq == genid;
+	genid_ok = genid == 0 || nft_net->base_seq == genid;
 	if (!genid_ok)
-		mutex_unlock(&net->nft.commit_mutex);
+		mutex_unlock(&nft_net->commit_mutex);
 
 	/* else, commit mutex has to be released by commit or abort function */
 	return genid_ok;
@@ -8309,7 +8920,6 @@
 	.cb		= nf_tables_cb,
 	.commit		= nf_tables_commit,
 	.abort		= nf_tables_abort,
-	.cleanup	= nf_tables_cleanup,
 	.valid_genid	= nf_tables_valid_genid,
 	.owner		= THIS_MODULE,
 };
@@ -8472,28 +9082,24 @@
 }
 EXPORT_SYMBOL_GPL(nft_parse_u32_check);
 
-/**
- *	nft_parse_register - parse a register value from a netlink attribute
- *
- *	@attr: netlink attribute
- *
- *	Parse and translate a register value from a netlink attribute.
- *	Registers used to be 128 bit wide, these register numbers will be
- *	mapped to the corresponding 32 bit register numbers.
- */
-unsigned int nft_parse_register(const struct nlattr *attr)
+static int nft_parse_register(const struct nlattr *attr, u32 *preg)
 {
 	unsigned int reg;
 
 	reg = ntohl(nla_get_be32(attr));
 	switch (reg) {
 	case NFT_REG_VERDICT...NFT_REG_4:
-		return reg * NFT_REG_SIZE / NFT_REG32_SIZE;
+		*preg = reg * NFT_REG_SIZE / NFT_REG32_SIZE;
+		break;
+	case NFT_REG32_00...NFT_REG32_15:
+		*preg = reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
+		break;
 	default:
-		return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
+		return -ERANGE;
 	}
+
+	return 0;
 }
-EXPORT_SYMBOL_GPL(nft_parse_register);
 
 /**
  *	nft_dump_register - dump a register value to a netlink attribute
@@ -8543,7 +9149,10 @@
 	u32 reg;
 	int err;
 
-	reg = nft_parse_register(attr);
+	err = nft_parse_register(attr, &reg);
+	if (err < 0)
+		return err;
+
 	err = nft_validate_register_load(reg, len);
 	if (err < 0)
 		return err;
@@ -8612,7 +9221,10 @@
 	int err;
 	u32 reg;
 
-	reg = nft_parse_register(attr);
+	err = nft_parse_register(attr, &reg);
+	if (err < 0)
+		return err;
+
 	err = nft_validate_register_store(ctx, reg, data, type, len);
 	if (err < 0)
 		return err;
@@ -8644,6 +9256,9 @@
 
 	if (!tb[NFTA_VERDICT_CODE])
 		return -EINVAL;
+
+	/* zero padding hole for memcmp */
+	memset(data, 0, sizeof(*data));
 	data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
 
 	switch (data->verdict.code) {
@@ -8669,7 +9284,8 @@
 						 genmask);
 		} else if (tb[NFTA_VERDICT_CHAIN_ID]) {
 			chain = nft_chain_lookup_byid(ctx->net, ctx->table,
-						      tb[NFTA_VERDICT_CHAIN_ID]);
+						      tb[NFTA_VERDICT_CHAIN_ID],
+						      genmask);
 			if (IS_ERR(chain))
 				return PTR_ERR(chain);
 		} else {
@@ -8685,8 +9301,9 @@
 		if (desc->flags & NFT_DATA_DESC_SETELEM &&
 		    chain->flags & NFT_CHAIN_BINDING)
 			return -EINVAL;
+		if (!nft_use_inc(&chain->use))
+			return -EMFILE;
 
-		chain->use++;
 		data->verdict.chain = chain;
 		break;
 	}
@@ -8699,22 +9316,12 @@
 static void nft_verdict_uninit(const struct nft_data *data)
 {
 	struct nft_chain *chain;
-	struct nft_rule *rule;
 
 	switch (data->verdict.code) {
 	case NFT_JUMP:
 	case NFT_GOTO:
 		chain = data->verdict.chain;
-		chain->use--;
-
-		if (!nft_chain_is_bound(chain))
-			break;
-
-		chain->table->use--;
-		list_for_each_entry(rule, &chain->rules, list)
-			chain->use--;
-
-		nft_chain_del(chain);
+		nft_use_dec(&chain->use);
 		break;
 	}
 }
@@ -8883,32 +9490,41 @@
 	nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
 	list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
 		list_del(&rule->list);
-		ctx->chain->use--;
+		nft_use_dec(&ctx->chain->use);
 		nf_tables_rule_release(ctx, rule);
 	}
 	nft_chain_del(ctx->chain);
-	ctx->table->use--;
+	nft_use_dec(&ctx->table->use);
 	nf_tables_chain_destroy(ctx);
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(__nft_release_basechain);
 
-static void __nft_release_hooks(struct net *net)
+static void __nft_release_hook(struct net *net, struct nft_table *table)
 {
-	struct nft_table *table;
+	struct nft_flowtable *flowtable;
 	struct nft_chain *chain;
 
-	list_for_each_entry(table, &net->nft.tables, list) {
-		list_for_each_entry(chain, &table->chains, list)
-			nf_tables_unregister_hook(net, table, chain);
-	}
+	list_for_each_entry(chain, &table->chains, list)
+		__nf_tables_unregister_hook(net, table, chain, true);
+	list_for_each_entry(flowtable, &table->flowtables, list)
+		__nft_unregister_flowtable_net_hooks(net, &flowtable->hook_list,
+						     true);
 }
 
-static void __nft_release_tables(struct net *net)
+static void __nft_release_hooks(struct net *net)
+{
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
+	struct nft_table *table;
+
+	list_for_each_entry(table, &nft_net->tables, list)
+		__nft_release_hook(net, table);
+}
+
+static void __nft_release_table(struct net *net, struct nft_table *table)
 {
 	struct nft_flowtable *flowtable, *nf;
-	struct nft_table *table, *nt;
 	struct nft_chain *chain, *nc;
 	struct nft_object *obj, *ne;
 	struct nft_rule *rule, *nr;
@@ -8918,77 +9534,115 @@
 		.family	= NFPROTO_NETDEV,
 	};
 
-	list_for_each_entry_safe(table, nt, &net->nft.tables, list) {
-		ctx.family = table->family;
-		ctx.table = table;
-		list_for_each_entry(chain, &table->chains, list) {
-			ctx.chain = chain;
-			list_for_each_entry_safe(rule, nr, &chain->rules, list) {
-				list_del(&rule->list);
-				chain->use--;
-				nf_tables_rule_release(&ctx, rule);
-			}
+	ctx.family = table->family;
+	ctx.table = table;
+	list_for_each_entry(chain, &table->chains, list) {
+		if (nft_chain_binding(chain))
+			continue;
+
+		ctx.chain = chain;
+		list_for_each_entry_safe(rule, nr, &chain->rules, list) {
+			list_del(&rule->list);
+			nft_use_dec(&chain->use);
+			nf_tables_rule_release(&ctx, rule);
 		}
-		list_for_each_entry_safe(flowtable, nf, &table->flowtables, list) {
-			list_del(&flowtable->list);
-			table->use--;
-			nf_tables_flowtable_destroy(flowtable);
-		}
-		list_for_each_entry_safe(set, ns, &table->sets, list) {
-			list_del(&set->list);
-			table->use--;
-			nft_set_destroy(&ctx, set);
-		}
-		list_for_each_entry_safe(obj, ne, &table->objects, list) {
-			nft_obj_del(obj);
-			table->use--;
-			nft_obj_destroy(&ctx, obj);
-		}
-		list_for_each_entry_safe(chain, nc, &table->chains, list) {
-			ctx.chain = chain;
-			nft_chain_del(chain);
-			table->use--;
-			nf_tables_chain_destroy(&ctx);
-		}
-		list_del(&table->list);
-		nf_tables_table_destroy(&ctx);
 	}
+	list_for_each_entry_safe(flowtable, nf, &table->flowtables, list) {
+		list_del(&flowtable->list);
+		nft_use_dec(&table->use);
+		nf_tables_flowtable_destroy(flowtable);
+	}
+	list_for_each_entry_safe(set, ns, &table->sets, list) {
+		list_del(&set->list);
+		nft_use_dec(&table->use);
+		if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
+			nft_map_deactivate(&ctx, set);
+
+		nft_set_destroy(&ctx, set);
+	}
+	list_for_each_entry_safe(obj, ne, &table->objects, list) {
+		nft_obj_del(obj);
+		nft_use_dec(&table->use);
+		nft_obj_destroy(&ctx, obj);
+	}
+	list_for_each_entry_safe(chain, nc, &table->chains, list) {
+		ctx.chain = chain;
+		nft_chain_del(chain);
+		nft_use_dec(&table->use);
+		nf_tables_chain_destroy(&ctx);
+	}
+	list_del(&table->list);
+	nf_tables_table_destroy(&ctx);
+}
+
+static void __nft_release_tables(struct net *net)
+{
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
+	struct nft_table *table, *nt;
+
+	list_for_each_entry_safe(table, nt, &nft_net->tables, list)
+		__nft_release_table(net, table);
 }
 
 static int __net_init nf_tables_init_net(struct net *net)
 {
-	INIT_LIST_HEAD(&net->nft.tables);
-	INIT_LIST_HEAD(&net->nft.commit_list);
-	INIT_LIST_HEAD(&net->nft.module_list);
-	INIT_LIST_HEAD(&net->nft.notify_list);
-	mutex_init(&net->nft.commit_mutex);
-	net->nft.base_seq = 1;
-	net->nft.validate_state = NFT_VALIDATE_SKIP;
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
+
+	INIT_LIST_HEAD(&nft_net->tables);
+	INIT_LIST_HEAD(&nft_net->commit_list);
+	INIT_LIST_HEAD(&nft_net->binding_list);
+	INIT_LIST_HEAD(&nft_net->module_list);
+	INIT_LIST_HEAD(&nft_net->notify_list);
+	mutex_init(&nft_net->commit_mutex);
+	nft_net->base_seq = 1;
+	nft_net->validate_state = NFT_VALIDATE_SKIP;
+	nft_net->gc_seq = 0;
 
 	return 0;
 }
 
 static void __net_exit nf_tables_pre_exit_net(struct net *net)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
+
+	mutex_lock(&nft_net->commit_mutex);
 	__nft_release_hooks(net);
+	mutex_unlock(&nft_net->commit_mutex);
 }
 
 static void __net_exit nf_tables_exit_net(struct net *net)
 {
-	mutex_lock(&net->nft.commit_mutex);
-	if (!list_empty(&net->nft.commit_list))
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
+	unsigned int gc_seq;
+
+	mutex_lock(&nft_net->commit_mutex);
+
+	gc_seq = nft_gc_seq_begin(nft_net);
+
+	if (!list_empty(&nft_net->commit_list))
 		__nf_tables_abort(net, NFNL_ABORT_NONE);
 	__nft_release_tables(net);
-	mutex_unlock(&net->nft.commit_mutex);
-	WARN_ON_ONCE(!list_empty(&net->nft.tables));
-	WARN_ON_ONCE(!list_empty(&net->nft.module_list));
-	WARN_ON_ONCE(!list_empty(&net->nft.notify_list));
+
+	nft_gc_seq_end(nft_net, gc_seq);
+
+	mutex_unlock(&nft_net->commit_mutex);
+	WARN_ON_ONCE(!list_empty(&nft_net->tables));
+	WARN_ON_ONCE(!list_empty(&nft_net->module_list));
+	WARN_ON_ONCE(!list_empty(&nft_net->notify_list));
+}
+
+static void nf_tables_exit_batch(struct list_head *net_exit_list)
+{
+	flush_work(&trans_gc_work);
 }
 
 static struct pernet_operations nf_tables_net_ops = {
 	.init		= nf_tables_init_net,
 	.pre_exit	= nf_tables_pre_exit_net,
 	.exit		= nf_tables_exit_net,
+	.exit_batch	= nf_tables_exit_batch,
+	.id		= &nf_tables_net_id,
+	.size		= sizeof(struct nftables_pernet),
 };
 
 static int __init nf_tables_module_init(void)
@@ -9051,6 +9705,7 @@
 	nft_chain_filter_fini();
 	nft_chain_route_fini();
 	unregister_pernet_subsys(&nf_tables_net_ops);
+	cancel_work_sync(&trans_gc_work);
 	cancel_work_sync(&trans_destroy_work);
 	rcu_barrier();
 	rhltable_destroy(&nft_objname_ht);
diff --git a/kernel/net/netfilter/nf_tables_core.c b/kernel/net/netfilter/nf_tables_core.c
index 9dc1842..b0d711d 100644
--- a/kernel/net/netfilter/nf_tables_core.c
+++ b/kernel/net/netfilter/nf_tables_core.c
@@ -125,7 +125,7 @@
 	else {
 		if (!pkt->tprot_set)
 			return false;
-		ptr = skb_network_header(skb) + pkt->xt.thoff;
+		ptr = skb_network_header(skb) + nft_thoff(pkt);
 	}
 
 	ptr += priv->offset;
diff --git a/kernel/net/netfilter/nf_tables_offload.c b/kernel/net/netfilter/nf_tables_offload.c
index 4e99b17..5cfbb29 100644
--- a/kernel/net/netfilter/nf_tables_offload.c
+++ b/kernel/net/netfilter/nf_tables_offload.c
@@ -7,6 +7,8 @@
 #include <net/netfilter/nf_tables_offload.h>
 #include <net/pkt_cls.h>
 
+extern unsigned int nf_tables_net_id;
+
 static struct nft_flow_rule *nft_flow_rule_alloc(int num_actions)
 {
 	struct nft_flow_rule *flow;
@@ -371,16 +373,18 @@
 	struct nft_base_chain *basechain = block_cb->indr.data;
 	struct net_device *dev = block_cb->indr.dev;
 	struct netlink_ext_ack extack = {};
+	struct nftables_pernet *nft_net;
 	struct net *net = dev_net(dev);
 	struct flow_block_offload bo;
 
 	nft_flow_block_offload_init(&bo, dev_net(dev), FLOW_BLOCK_UNBIND,
 				    basechain, &extack);
-	mutex_lock(&net->nft.commit_mutex);
+	nft_net = net_generic(net, nf_tables_net_id);
+	mutex_lock(&nft_net->commit_mutex);
 	list_del(&block_cb->driver_list);
 	list_move(&block_cb->list, &bo.cb_list);
 	nft_flow_offload_unbind(&bo, basechain);
-	mutex_unlock(&net->nft.commit_mutex);
+	mutex_unlock(&nft_net->commit_mutex);
 }
 
 static int nft_indr_block_offload_cmd(struct nft_base_chain *basechain,
@@ -476,9 +480,10 @@
 static void nft_flow_rule_offload_abort(struct net *net,
 					struct nft_trans *trans)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	int err = 0;
 
-	list_for_each_entry_continue_reverse(trans, &net->nft.commit_list, list) {
+	list_for_each_entry_continue_reverse(trans, &nft_net->commit_list, list) {
 		if (trans->ctx.family != NFPROTO_NETDEV)
 			continue;
 
@@ -524,11 +529,12 @@
 
 int nft_flow_rule_offload_commit(struct net *net)
 {
+	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	struct nft_trans *trans;
 	int err = 0;
 	u8 policy;
 
-	list_for_each_entry(trans, &net->nft.commit_list, list) {
+	list_for_each_entry(trans, &nft_net->commit_list, list) {
 		if (trans->ctx.family != NFPROTO_NETDEV)
 			continue;
 
@@ -580,7 +586,7 @@
 		}
 	}
 
-	list_for_each_entry(trans, &net->nft.commit_list, list) {
+	list_for_each_entry(trans, &nft_net->commit_list, list) {
 		if (trans->ctx.family != NFPROTO_NETDEV)
 			continue;
 
@@ -600,15 +606,15 @@
 	return err;
 }
 
-static struct nft_chain *__nft_offload_get_chain(struct net_device *dev)
+static struct nft_chain *__nft_offload_get_chain(const struct nftables_pernet *nft_net,
+						 struct net_device *dev)
 {
 	struct nft_base_chain *basechain;
-	struct net *net = dev_net(dev);
 	struct nft_hook *hook, *found;
 	const struct nft_table *table;
 	struct nft_chain *chain;
 
-	list_for_each_entry(table, &net->nft.tables, list) {
+	list_for_each_entry(table, &nft_net->tables, list) {
 		if (table->family != NFPROTO_NETDEV)
 			continue;
 
@@ -640,19 +646,21 @@
 				    unsigned long event, void *ptr)
 {
 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+	struct nftables_pernet *nft_net;
 	struct net *net = dev_net(dev);
 	struct nft_chain *chain;
 
 	if (event != NETDEV_UNREGISTER)
 		return NOTIFY_DONE;
 
-	mutex_lock(&net->nft.commit_mutex);
-	chain = __nft_offload_get_chain(dev);
+	nft_net = net_generic(net, nf_tables_net_id);
+	mutex_lock(&nft_net->commit_mutex);
+	chain = __nft_offload_get_chain(nft_net, dev);
 	if (chain)
 		nft_flow_block_chain(nft_base_chain(chain), dev,
 				     FLOW_BLOCK_UNBIND);
 
-	mutex_unlock(&net->nft.commit_mutex);
+	mutex_unlock(&nft_net->commit_mutex);
 
 	return NOTIFY_DONE;
 }
diff --git a/kernel/net/netfilter/nf_tables_trace.c b/kernel/net/netfilter/nf_tables_trace.c
index 0cf3278..e4fe2f0 100644
--- a/kernel/net/netfilter/nf_tables_trace.c
+++ b/kernel/net/netfilter/nf_tables_trace.c
@@ -113,17 +113,17 @@
 	int off = skb_network_offset(skb);
 	unsigned int len, nh_end;
 
-	nh_end = pkt->tprot_set ? pkt->xt.thoff : skb->len;
+	nh_end = pkt->tprot_set ? nft_thoff(pkt) : skb->len;
 	len = min_t(unsigned int, nh_end - skb_network_offset(skb),
 		    NFT_TRACETYPE_NETWORK_HSIZE);
 	if (trace_fill_header(nlskb, NFTA_TRACE_NETWORK_HEADER, skb, off, len))
 		return -1;
 
 	if (pkt->tprot_set) {
-		len = min_t(unsigned int, skb->len - pkt->xt.thoff,
+		len = min_t(unsigned int, skb->len - nft_thoff(pkt),
 			    NFT_TRACETYPE_TRANSPORT_HSIZE);
 		if (trace_fill_header(nlskb, NFTA_TRACE_TRANSPORT_HEADER, skb,
-				      pkt->xt.thoff, len))
+				      nft_thoff(pkt), len))
 			return -1;
 	}
 
diff --git a/kernel/net/netfilter/nfnetlink.c b/kernel/net/netfilter/nfnetlink.c
index d3df66a..bec9ac8 100644
--- a/kernel/net/netfilter/nfnetlink.c
+++ b/kernel/net/netfilter/nfnetlink.c
@@ -473,7 +473,8 @@
 			 * processed, this avoids that the same error is
 			 * reported several times when replaying the batch.
 			 */
-			if (nfnl_err_add(&err_list, nlh, err, &extack) < 0) {
+			if (err == -ENOMEM ||
+			    nfnl_err_add(&err_list, nlh, err, &extack) < 0) {
 				/* We failed to enqueue an error, reset the
 				 * list of errors and send OOM to userspace
 				 * pointing to the batch header.
@@ -530,8 +531,6 @@
 			goto replay_abort;
 		}
 	}
-	if (ss->cleanup)
-		ss->cleanup(net);
 
 	nfnl_err_deliver(&err_list, oskb);
 	kfree_skb(skb);
diff --git a/kernel/net/netfilter/nfnetlink_log.c b/kernel/net/netfilter/nfnetlink_log.c
index f087baa..26ab279 100644
--- a/kernel/net/netfilter/nfnetlink_log.c
+++ b/kernel/net/netfilter/nfnetlink_log.c
@@ -583,9 +583,9 @@
 			goto nla_put_failure;
 	}
 
-	if (hooknum <= NF_INET_FORWARD && skb->tstamp) {
+	if (hooknum <= NF_INET_FORWARD) {
 		struct nfulnl_msg_packet_timestamp ts;
-		struct timespec64 kts = ktime_to_timespec64(skb->tstamp);
+		struct timespec64 kts = ktime_to_timespec64(skb->tstamp ?: ktime_get_real());
 		ts.sec = cpu_to_be64(kts.tv_sec);
 		ts.usec = cpu_to_be64(kts.tv_nsec / NSEC_PER_USEC);
 
diff --git a/kernel/net/netfilter/nfnetlink_osf.c b/kernel/net/netfilter/nfnetlink_osf.c
index 51e3953..573a372 100644
--- a/kernel/net/netfilter/nfnetlink_osf.c
+++ b/kernel/net/netfilter/nfnetlink_osf.c
@@ -316,6 +316,14 @@
 
 	f = nla_data(osf_attrs[OSF_ATTR_FINGER]);
 
+	if (f->opt_num > ARRAY_SIZE(f->opt))
+		return -EINVAL;
+
+	if (!memchr(f->genre, 0, MAXGENRELEN) ||
+	    !memchr(f->subtype, 0, MAXGENRELEN) ||
+	    !memchr(f->version, 0, MAXGENRELEN))
+		return -EINVAL;
+
 	kf = kmalloc(sizeof(struct nf_osf_finger), GFP_KERNEL);
 	if (!kf)
 		return -ENOMEM;
@@ -440,3 +448,4 @@
 module_exit(nfnl_osf_fini);
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_OSF);
diff --git a/kernel/net/netfilter/nft_byteorder.c b/kernel/net/netfilter/nft_byteorder.c
index 9d5947a..7b0b8fe 100644
--- a/kernel/net/netfilter/nft_byteorder.c
+++ b/kernel/net/netfilter/nft_byteorder.c
@@ -30,11 +30,11 @@
 	const struct nft_byteorder *priv = nft_expr_priv(expr);
 	u32 *src = &regs->data[priv->sreg];
 	u32 *dst = &regs->data[priv->dreg];
-	union { u32 u32; u16 u16; } *s, *d;
+	u16 *s16, *d16;
 	unsigned int i;
 
-	s = (void *)src;
-	d = (void *)dst;
+	s16 = (void *)src;
+	d16 = (void *)dst;
 
 	switch (priv->size) {
 	case 8: {
@@ -61,11 +61,11 @@
 		switch (priv->op) {
 		case NFT_BYTEORDER_NTOH:
 			for (i = 0; i < priv->len / 4; i++)
-				d[i].u32 = ntohl((__force __be32)s[i].u32);
+				dst[i] = ntohl((__force __be32)src[i]);
 			break;
 		case NFT_BYTEORDER_HTON:
 			for (i = 0; i < priv->len / 4; i++)
-				d[i].u32 = (__force __u32)htonl(s[i].u32);
+				dst[i] = (__force __u32)htonl(src[i]);
 			break;
 		}
 		break;
@@ -73,11 +73,11 @@
 		switch (priv->op) {
 		case NFT_BYTEORDER_NTOH:
 			for (i = 0; i < priv->len / 2; i++)
-				d[i].u16 = ntohs((__force __be16)s[i].u16);
+				d16[i] = ntohs((__force __be16)s16[i]);
 			break;
 		case NFT_BYTEORDER_HTON:
 			for (i = 0; i < priv->len / 2; i++)
-				d[i].u16 = (__force __u16)htons(s[i].u16);
+				d16[i] = (__force __u16)htons(s16[i]);
 			break;
 		}
 		break;
diff --git a/kernel/net/netfilter/nft_chain_filter.c b/kernel/net/netfilter/nft_chain_filter.c
index ff8528a..7a9aa57 100644
--- a/kernel/net/netfilter/nft_chain_filter.c
+++ b/kernel/net/netfilter/nft_chain_filter.c
@@ -2,6 +2,7 @@
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <net/net_namespace.h>
+#include <net/netns/generic.h>
 #include <net/netfilter/nf_tables.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv6.h>
@@ -9,6 +10,8 @@
 #include <linux/netfilter_arp.h>
 #include <net/netfilter/nf_tables_ipv4.h>
 #include <net/netfilter/nf_tables_ipv6.h>
+
+extern unsigned int nf_tables_net_id;
 
 #ifdef CONFIG_NF_TABLES_IPV4
 static unsigned int nft_do_chain_ipv4(void *priv,
@@ -355,6 +358,7 @@
 				  unsigned long event, void *ptr)
 {
 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+	struct nftables_pernet *nft_net;
 	struct nft_table *table;
 	struct nft_chain *chain, *nr;
 	struct nft_ctx ctx = {
@@ -365,8 +369,9 @@
 	    event != NETDEV_CHANGENAME)
 		return NOTIFY_DONE;
 
-	mutex_lock(&ctx.net->nft.commit_mutex);
-	list_for_each_entry(table, &ctx.net->nft.tables, list) {
+	nft_net = net_generic(ctx.net, nf_tables_net_id);
+	mutex_lock(&nft_net->commit_mutex);
+	list_for_each_entry(table, &nft_net->tables, list) {
 		if (table->family != NFPROTO_NETDEV)
 			continue;
 
@@ -380,7 +385,7 @@
 			nft_netdev_event(event, dev, &ctx);
 		}
 	}
-	mutex_unlock(&ctx.net->nft.commit_mutex);
+	mutex_unlock(&nft_net->commit_mutex);
 
 	return NOTIFY_DONE;
 }
diff --git a/kernel/net/netfilter/nft_dynset.c b/kernel/net/netfilter/nft_dynset.c
index 8c45e01..408b7f5 100644
--- a/kernel/net/netfilter/nft_dynset.c
+++ b/kernel/net/netfilter/nft_dynset.c
@@ -11,6 +11,9 @@
 #include <linux/netfilter/nf_tables.h>
 #include <net/netfilter/nf_tables.h>
 #include <net/netfilter/nf_tables_core.h>
+#include <net/netns/generic.h>
+
+extern unsigned int nf_tables_net_id;
 
 struct nft_dynset {
 	struct nft_set			*set;
@@ -106,13 +109,14 @@
 			   const struct nft_expr *expr,
 			   const struct nlattr * const tb[])
 {
+	struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
 	struct nft_dynset *priv = nft_expr_priv(expr);
 	u8 genmask = nft_genmask_next(ctx->net);
 	struct nft_set *set;
 	u64 timeout;
 	int err;
 
-	lockdep_assert_held(&ctx->net->nft.commit_mutex);
+	lockdep_assert_held(&nft_net->commit_mutex);
 
 	if (tb[NFTA_DYNSET_SET_NAME] == NULL ||
 	    tb[NFTA_DYNSET_OP] == NULL ||
@@ -133,6 +137,9 @@
 				    tb[NFTA_DYNSET_SET_ID], genmask);
 	if (IS_ERR(set))
 		return PTR_ERR(set);
+
+	if (set->flags & NFT_SET_OBJECT)
+		return -EOPNOTSUPP;
 
 	if (set->ops->update == NULL)
 		return -EOPNOTSUPP;
@@ -233,7 +240,7 @@
 {
 	struct nft_dynset *priv = nft_expr_priv(expr);
 
-	priv->set->use++;
+	nf_tables_activate_set(ctx, priv->set);
 }
 
 static void nft_dynset_destroy(const struct nft_ctx *ctx,
diff --git a/kernel/net/netfilter/nft_exthdr.c b/kernel/net/netfilter/nft_exthdr.c
index 670dd14..cb69a29 100644
--- a/kernel/net/netfilter/nft_exthdr.c
+++ b/kernel/net/netfilter/nft_exthdr.c
@@ -10,8 +10,10 @@
 #include <linux/netlink.h>
 #include <linux/netfilter.h>
 #include <linux/netfilter/nf_tables.h>
+#include <linux/sctp.h>
 #include <net/netfilter/nf_tables_core.h>
 #include <net/netfilter/nf_tables.h>
+#include <net/sctp/sctp.h>
 #include <net/tcp.h>
 
 struct nft_exthdr {
@@ -31,6 +33,14 @@
 		return 1;
 	else
 		return opt[offset + 1];
+}
+
+static int nft_skb_copy_to_reg(const struct sk_buff *skb, int offset, u32 *dest, unsigned int len)
+{
+	if (len % NFT_REG32_SIZE)
+		dest[len / NFT_REG32_SIZE] = 0;
+
+	return skb_copy_bits(skb, offset, dest, len);
 }
 
 static void nft_exthdr_ipv6_eval(const struct nft_expr *expr,
@@ -54,8 +64,7 @@
 	}
 	offset += priv->offset;
 
-	dest[priv->len / NFT_REG32_SIZE] = 0;
-	if (skb_copy_bits(pkt->skb, offset, dest, priv->len) < 0)
+	if (nft_skb_copy_to_reg(pkt->skb, offset, dest, priv->len) < 0)
 		goto err;
 	return;
 err:
@@ -151,8 +160,7 @@
 	}
 	offset += priv->offset;
 
-	dest[priv->len / NFT_REG32_SIZE] = 0;
-	if (skb_copy_bits(pkt->skb, offset, dest, priv->len) < 0)
+	if (nft_skb_copy_to_reg(pkt->skb, offset, dest, priv->len) < 0)
 		goto err;
 	return;
 err:
@@ -168,7 +176,7 @@
 	if (!pkt->tprot_set || pkt->tprot != IPPROTO_TCP)
 		return NULL;
 
-	tcph = skb_header_pointer(pkt->skb, pkt->xt.thoff, sizeof(*tcph), buffer);
+	tcph = skb_header_pointer(pkt->skb, nft_thoff(pkt), sizeof(*tcph), buffer);
 	if (!tcph)
 		return NULL;
 
@@ -176,7 +184,7 @@
 	if (*tcphdr_len < sizeof(*tcph) || *tcphdr_len > len)
 		return NULL;
 
-	return skb_header_pointer(pkt->skb, pkt->xt.thoff, *tcphdr_len, buffer);
+	return skb_header_pointer(pkt->skb, nft_thoff(pkt), *tcphdr_len, buffer);
 }
 
 static void nft_exthdr_tcp_eval(const struct nft_expr *expr,
@@ -208,7 +216,8 @@
 		if (priv->flags & NFT_EXTHDR_F_PRESENT) {
 			*dest = 1;
 		} else {
-			dest[priv->len / NFT_REG32_SIZE] = 0;
+			if (priv->len % NFT_REG32_SIZE)
+				dest[priv->len / NFT_REG32_SIZE] = 0;
 			memcpy(dest, opt + offset, priv->len);
 		}
 
@@ -234,9 +243,14 @@
 
 	tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, &tcphdr_len);
 	if (!tcph)
-		return;
+		goto err;
 
+	if (skb_ensure_writable(pkt->skb, nft_thoff(pkt) + tcphdr_len))
+		goto err;
+
+	tcph = (struct tcphdr *)(pkt->skb->data + nft_thoff(pkt));
 	opt = (u8 *)tcph;
+
 	for (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) {
 		union {
 			__be16 v16;
@@ -249,16 +263,7 @@
 			continue;
 
 		if (i + optl > tcphdr_len || priv->len + priv->offset > optl)
-			return;
-
-		if (skb_ensure_writable(pkt->skb,
-					pkt->xt.thoff + i + priv->len))
-			return;
-
-		tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff,
-					      &tcphdr_len);
-		if (!tcph)
-			return;
+			goto err;
 
 		offset = i + priv->offset;
 
@@ -301,6 +306,107 @@
 
 		return;
 	}
+	return;
+err:
+	regs->verdict.code = NFT_BREAK;
+}
+
+static void nft_exthdr_tcp_strip_eval(const struct nft_expr *expr,
+				      struct nft_regs *regs,
+				      const struct nft_pktinfo *pkt)
+{
+	u8 buff[sizeof(struct tcphdr) + MAX_TCP_OPTION_SPACE];
+	struct nft_exthdr *priv = nft_expr_priv(expr);
+	unsigned int i, tcphdr_len, optl;
+	struct tcphdr *tcph;
+	u8 *opt;
+
+	tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, &tcphdr_len);
+	if (!tcph)
+		goto err;
+
+	if (skb_ensure_writable(pkt->skb, nft_thoff(pkt) + tcphdr_len))
+		goto drop;
+
+	tcph = (struct tcphdr *)(pkt->skb->data + nft_thoff(pkt));
+	opt = (u8 *)tcph;
+
+	for (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) {
+		unsigned int j;
+
+		optl = optlen(opt, i);
+		if (priv->type != opt[i])
+			continue;
+
+		if (i + optl > tcphdr_len)
+			goto drop;
+
+		for (j = 0; j < optl; ++j) {
+			u16 n = TCPOPT_NOP;
+			u16 o = opt[i+j];
+
+			if ((i + j) % 2 == 0) {
+				o <<= 8;
+				n <<= 8;
+			}
+			inet_proto_csum_replace2(&tcph->check, pkt->skb, htons(o),
+						 htons(n), false);
+		}
+		memset(opt + i, TCPOPT_NOP, optl);
+		return;
+	}
+
+	/* option not found, continue. This allows to do multiple
+	 * option removals per rule.
+	 */
+	return;
+err:
+	regs->verdict.code = NFT_BREAK;
+	return;
+drop:
+	/* can't remove, no choice but to drop */
+	regs->verdict.code = NF_DROP;
+}
+
+static void nft_exthdr_sctp_eval(const struct nft_expr *expr,
+				 struct nft_regs *regs,
+				 const struct nft_pktinfo *pkt)
+{
+	unsigned int offset = nft_thoff(pkt) + sizeof(struct sctphdr);
+	struct nft_exthdr *priv = nft_expr_priv(expr);
+	u32 *dest = &regs->data[priv->dreg];
+	const struct sctp_chunkhdr *sch;
+	struct sctp_chunkhdr _sch;
+
+	if (pkt->tprot != IPPROTO_SCTP)
+		goto err;
+
+	do {
+		sch = skb_header_pointer(pkt->skb, offset, sizeof(_sch), &_sch);
+		if (!sch || !sch->length)
+			break;
+
+		if (sch->type == priv->type) {
+			if (priv->flags & NFT_EXTHDR_F_PRESENT) {
+				nft_reg_store8(dest, true);
+				return;
+			}
+			if (priv->offset + priv->len > ntohs(sch->length) ||
+			    offset + ntohs(sch->length) > pkt->skb->len)
+				break;
+
+			if (nft_skb_copy_to_reg(pkt->skb, offset + priv->offset,
+						dest, priv->len) < 0)
+				break;
+			return;
+		}
+		offset += SCTP_PAD4(ntohs(sch->length));
+	} while (offset < pkt->skb->len);
+err:
+	if (priv->flags & NFT_EXTHDR_F_PRESENT)
+		nft_reg_store8(dest, false);
+	else
+		regs->verdict.code = NFT_BREAK;
 }
 
 static const struct nla_policy nft_exthdr_policy[NFTA_EXTHDR_MAX + 1] = {
@@ -410,6 +516,28 @@
 				       priv->len);
 }
 
+static int nft_exthdr_tcp_strip_init(const struct nft_ctx *ctx,
+				     const struct nft_expr *expr,
+				     const struct nlattr * const tb[])
+{
+	struct nft_exthdr *priv = nft_expr_priv(expr);
+
+	if (tb[NFTA_EXTHDR_SREG] ||
+	    tb[NFTA_EXTHDR_DREG] ||
+	    tb[NFTA_EXTHDR_FLAGS] ||
+	    tb[NFTA_EXTHDR_OFFSET] ||
+	    tb[NFTA_EXTHDR_LEN])
+		return -EINVAL;
+
+	if (!tb[NFTA_EXTHDR_TYPE])
+		return -EINVAL;
+
+	priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
+	priv->op = NFT_EXTHDR_OP_TCPOPT;
+
+	return 0;
+}
+
 static int nft_exthdr_ipv4_init(const struct nft_ctx *ctx,
 				const struct nft_expr *expr,
 				const struct nlattr * const tb[])
@@ -470,6 +598,13 @@
 	return nft_exthdr_dump_common(skb, priv);
 }
 
+static int nft_exthdr_dump_strip(struct sk_buff *skb, const struct nft_expr *expr)
+{
+	const struct nft_exthdr *priv = nft_expr_priv(expr);
+
+	return nft_exthdr_dump_common(skb, priv);
+}
+
 static const struct nft_expr_ops nft_exthdr_ipv6_ops = {
 	.type		= &nft_exthdr_type,
 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_exthdr)),
@@ -502,6 +637,22 @@
 	.dump		= nft_exthdr_dump_set,
 };
 
+static const struct nft_expr_ops nft_exthdr_tcp_strip_ops = {
+	.type		= &nft_exthdr_type,
+	.size		= NFT_EXPR_SIZE(sizeof(struct nft_exthdr)),
+	.eval		= nft_exthdr_tcp_strip_eval,
+	.init		= nft_exthdr_tcp_strip_init,
+	.dump		= nft_exthdr_dump_strip,
+};
+
+static const struct nft_expr_ops nft_exthdr_sctp_ops = {
+	.type		= &nft_exthdr_type,
+	.size		= NFT_EXPR_SIZE(sizeof(struct nft_exthdr)),
+	.eval		= nft_exthdr_sctp_eval,
+	.init		= nft_exthdr_init,
+	.dump		= nft_exthdr_dump,
+};
+
 static const struct nft_expr_ops *
 nft_exthdr_select_ops(const struct nft_ctx *ctx,
 		      const struct nlattr * const tb[])
@@ -521,7 +672,7 @@
 			return &nft_exthdr_tcp_set_ops;
 		if (tb[NFTA_EXTHDR_DREG])
 			return &nft_exthdr_tcp_ops;
-		break;
+		return &nft_exthdr_tcp_strip_ops;
 	case NFT_EXTHDR_OP_IPV6:
 		if (tb[NFTA_EXTHDR_DREG])
 			return &nft_exthdr_ipv6_ops;
@@ -532,6 +683,10 @@
 				return &nft_exthdr_ipv4_ops;
 		}
 		break;
+	case NFT_EXTHDR_OP_SCTP:
+		if (tb[NFTA_EXTHDR_DREG])
+			return &nft_exthdr_sctp_ops;
+		break;
 	}
 
 	return ERR_PTR(-EOPNOTSUPP);
diff --git a/kernel/net/netfilter/nft_flow_offload.c b/kernel/net/netfilter/nft_flow_offload.c
index 3a6c84f..a44340d 100644
--- a/kernel/net/netfilter/nft_flow_offload.c
+++ b/kernel/net/netfilter/nft_flow_offload.c
@@ -90,7 +90,7 @@
 
 	switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) {
 	case IPPROTO_TCP:
-		tcph = skb_header_pointer(pkt->skb, pkt->xt.thoff,
+		tcph = skb_header_pointer(pkt->skb, nft_thoff(pkt),
 					  sizeof(_tcph), &_tcph);
 		if (unlikely(!tcph || tcph->fin || tcph->rst))
 			goto out;
@@ -174,8 +174,10 @@
 	if (IS_ERR(flowtable))
 		return PTR_ERR(flowtable);
 
+	if (!nft_use_inc(&flowtable->use))
+		return -EMFILE;
+
 	priv->flowtable = flowtable;
-	flowtable->use++;
 
 	return nf_ct_netns_get(ctx->net, ctx->family);
 }
@@ -194,7 +196,7 @@
 {
 	struct nft_flow_offload *priv = nft_expr_priv(expr);
 
-	priv->flowtable->use++;
+	nft_use_inc_restore(&priv->flowtable->use);
 }
 
 static void nft_flow_offload_destroy(const struct nft_ctx *ctx,
diff --git a/kernel/net/netfilter/nft_immediate.c b/kernel/net/netfilter/nft_immediate.c
index fcdbc5e..7d5b63c 100644
--- a/kernel/net/netfilter/nft_immediate.c
+++ b/kernel/net/netfilter/nft_immediate.c
@@ -76,11 +76,9 @@
 		switch (priv->data.verdict.code) {
 		case NFT_JUMP:
 		case NFT_GOTO:
-			if (nft_chain_is_bound(chain)) {
-				err = -EBUSY;
-				goto err1;
-			}
-			chain->bound = true;
+			err = nf_tables_bind_chain(ctx, chain);
+			if (err < 0)
+				return err;
 			break;
 		default:
 			break;
@@ -98,8 +96,47 @@
 				   const struct nft_expr *expr)
 {
 	const struct nft_immediate_expr *priv = nft_expr_priv(expr);
+	const struct nft_data *data = &priv->data;
+	struct nft_ctx chain_ctx;
+	struct nft_chain *chain;
+	struct nft_rule *rule;
+
+	if (priv->dreg == NFT_REG_VERDICT) {
+		switch (data->verdict.code) {
+		case NFT_JUMP:
+		case NFT_GOTO:
+			chain = data->verdict.chain;
+			if (!nft_chain_binding(chain))
+				break;
+
+			chain_ctx = *ctx;
+			chain_ctx.chain = chain;
+
+			list_for_each_entry(rule, &chain->rules, list)
+				nft_rule_expr_activate(&chain_ctx, rule);
+
+			nft_clear(ctx->net, chain);
+			break;
+		default:
+			break;
+		}
+	}
 
 	return nft_data_hold(&priv->data, nft_dreg_to_type(priv->dreg));
+}
+
+static void nft_immediate_chain_deactivate(const struct nft_ctx *ctx,
+					   struct nft_chain *chain,
+					   enum nft_trans_phase phase)
+{
+	struct nft_ctx chain_ctx;
+	struct nft_rule *rule;
+
+	chain_ctx = *ctx;
+	chain_ctx.chain = chain;
+
+	list_for_each_entry(rule, &chain->rules, list)
+		nft_rule_expr_deactivate(&chain_ctx, rule, phase);
 }
 
 static void nft_immediate_deactivate(const struct nft_ctx *ctx,
@@ -107,6 +144,38 @@
 				     enum nft_trans_phase phase)
 {
 	const struct nft_immediate_expr *priv = nft_expr_priv(expr);
+	const struct nft_data *data = &priv->data;
+	struct nft_chain *chain;
+
+	if (priv->dreg == NFT_REG_VERDICT) {
+		switch (data->verdict.code) {
+		case NFT_JUMP:
+		case NFT_GOTO:
+			chain = data->verdict.chain;
+			if (!nft_chain_binding(chain))
+				break;
+
+			switch (phase) {
+			case NFT_TRANS_PREPARE_ERROR:
+				nf_tables_unbind_chain(ctx, chain);
+				nft_deactivate_next(ctx->net, chain);
+				break;
+			case NFT_TRANS_PREPARE:
+				nft_immediate_chain_deactivate(ctx, chain, phase);
+				nft_deactivate_next(ctx->net, chain);
+				break;
+			default:
+				nft_immediate_chain_deactivate(ctx, chain, phase);
+				nft_chain_del(chain);
+				chain->bound = false;
+				nft_use_dec(&chain->table->use);
+				break;
+			}
+			break;
+		default:
+			break;
+		}
+	}
 
 	if (phase == NFT_TRANS_COMMIT)
 		return;
@@ -131,15 +200,27 @@
 	case NFT_GOTO:
 		chain = data->verdict.chain;
 
-		if (!nft_chain_is_bound(chain))
+		if (!nft_chain_binding(chain))
 			break;
 
+		/* Rule construction failed, but chain is already bound:
+		 * let the transaction records release this chain and its rules.
+		 */
+		if (chain->bound) {
+			nft_use_dec(&chain->use);
+			break;
+		}
+
+		/* Rule has been deleted, release chain and its rules. */
 		chain_ctx = *ctx;
 		chain_ctx.chain = chain;
 
-		list_for_each_entry_safe(rule, n, &chain->rules, list)
-			nf_tables_rule_release(&chain_ctx, rule);
-
+		nft_use_dec(&chain->use);
+		list_for_each_entry_safe(rule, n, &chain->rules, list) {
+			nft_use_dec(&chain->use);
+			list_del(&rule->list);
+			nf_tables_rule_destroy(&chain_ctx, rule);
+		}
 		nf_tables_chain_destroy(&chain_ctx);
 		break;
 	default:
diff --git a/kernel/net/netfilter/nft_lookup.c b/kernel/net/netfilter/nft_lookup.c
index b0f558b..8bc008f 100644
--- a/kernel/net/netfilter/nft_lookup.c
+++ b/kernel/net/netfilter/nft_lookup.c
@@ -132,7 +132,7 @@
 {
 	struct nft_lookup *priv = nft_expr_priv(expr);
 
-	priv->set->use++;
+	nf_tables_activate_set(ctx, priv->set);
 }
 
 static void nft_lookup_destroy(const struct nft_ctx *ctx,
diff --git a/kernel/net/netfilter/nft_masq.c b/kernel/net/netfilter/nft_masq.c
index 9953e80..1818dbf 100644
--- a/kernel/net/netfilter/nft_masq.c
+++ b/kernel/net/netfilter/nft_masq.c
@@ -43,7 +43,7 @@
 			 const struct nft_expr *expr,
 			 const struct nlattr * const tb[])
 {
-	u32 plen = sizeof_field(struct nf_nat_range, min_addr.all);
+	u32 plen = sizeof_field(struct nf_nat_range, min_proto.all);
 	struct nft_masq *priv = nft_expr_priv(expr);
 	int err;
 
diff --git a/kernel/net/netfilter/nft_nat.c b/kernel/net/netfilter/nft_nat.c
index db8f911..cd4eb49 100644
--- a/kernel/net/netfilter/nft_nat.c
+++ b/kernel/net/netfilter/nft_nat.c
@@ -226,7 +226,7 @@
 		priv->flags |= NF_NAT_RANGE_MAP_IPS;
 	}
 
-	plen = sizeof_field(struct nf_nat_range, min_addr.all);
+	plen = sizeof_field(struct nf_nat_range, min_proto.all);
 	if (tb[NFTA_NAT_REG_PROTO_MIN]) {
 		err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MIN],
 					      &priv->sreg_proto_min, plen);
diff --git a/kernel/net/netfilter/nft_objref.c b/kernel/net/netfilter/nft_objref.c
index bc104d3..30d0b0a 100644
--- a/kernel/net/netfilter/nft_objref.c
+++ b/kernel/net/netfilter/nft_objref.c
@@ -41,8 +41,10 @@
 	if (IS_ERR(obj))
 		return -ENOENT;
 
+	if (!nft_use_inc(&obj->use))
+		return -EMFILE;
+
 	nft_objref_priv(expr) = obj;
-	obj->use++;
 
 	return 0;
 }
@@ -71,7 +73,7 @@
 	if (phase == NFT_TRANS_COMMIT)
 		return;
 
-	obj->use--;
+	nft_use_dec(&obj->use);
 }
 
 static void nft_objref_activate(const struct nft_ctx *ctx,
@@ -79,7 +81,7 @@
 {
 	struct nft_object *obj = nft_objref_priv(expr);
 
-	obj->use++;
+	nft_use_inc_restore(&obj->use);
 }
 
 static struct nft_expr_type nft_objref_type;
@@ -180,7 +182,7 @@
 {
 	struct nft_objref_map *priv = nft_expr_priv(expr);
 
-	priv->set->use++;
+	nf_tables_activate_set(ctx, priv->set);
 }
 
 static void nft_objref_map_destroy(const struct nft_ctx *ctx,
diff --git a/kernel/net/netfilter/nft_payload.c b/kernel/net/netfilter/nft_payload.c
index 551e0d6..b2b63c3 100644
--- a/kernel/net/netfilter/nft_payload.c
+++ b/kernel/net/netfilter/nft_payload.c
@@ -62,7 +62,7 @@
 			return false;
 
 		if (offset + len > VLAN_ETH_HLEN + vlan_hlen)
-			ethlen -= offset + len - VLAN_ETH_HLEN + vlan_hlen;
+			ethlen -= offset + len - VLAN_ETH_HLEN - vlan_hlen;
 
 		memcpy(dst_u8, vlanh + offset - vlan_hlen, ethlen);
 
@@ -110,7 +110,7 @@
 	case NFT_PAYLOAD_TRANSPORT_HEADER:
 		if (!pkt->tprot_set)
 			goto err;
-		offset = pkt->xt.thoff;
+		offset = nft_thoff(pkt);
 		break;
 	default:
 		BUG();
@@ -510,7 +510,7 @@
 		*l4csum_offset = offsetof(struct tcphdr, check);
 		break;
 	case IPPROTO_UDP:
-		if (!nft_payload_udp_checksum(skb, pkt->xt.thoff))
+		if (!nft_payload_udp_checksum(skb, nft_thoff(pkt)))
 			return -1;
 		fallthrough;
 	case IPPROTO_UDPLITE:
@@ -523,7 +523,7 @@
 		return -1;
 	}
 
-	*l4csum_offset += pkt->xt.thoff;
+	*l4csum_offset += nft_thoff(pkt);
 	return 0;
 }
 
@@ -615,7 +615,7 @@
 	case NFT_PAYLOAD_TRANSPORT_HEADER:
 		if (!pkt->tprot_set)
 			goto err;
-		offset = pkt->xt.thoff;
+		offset = nft_thoff(pkt);
 		break;
 	default:
 		BUG();
@@ -646,7 +646,7 @@
 	if (priv->csum_type == NFT_PAYLOAD_CSUM_SCTP &&
 	    pkt->tprot == IPPROTO_SCTP &&
 	    skb->ip_summed != CHECKSUM_PARTIAL) {
-		if (nft_payload_csum_sctp(skb, pkt->xt.thoff))
+		if (nft_payload_csum_sctp(skb, nft_thoff(pkt)))
 			goto err;
 	}
 
diff --git a/kernel/net/netfilter/nft_redir.c b/kernel/net/netfilter/nft_redir.c
index ba09890..e64f531 100644
--- a/kernel/net/netfilter/nft_redir.c
+++ b/kernel/net/netfilter/nft_redir.c
@@ -48,7 +48,7 @@
 	unsigned int plen;
 	int err;
 
-	plen = sizeof_field(struct nf_nat_range, min_addr.all);
+	plen = sizeof_field(struct nf_nat_range, min_proto.all);
 	if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
 		err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MIN],
 					      &priv->sreg_proto_min, plen);
@@ -232,7 +232,7 @@
 	.name		= "redir",
 	.ops		= &nft_redir_inet_ops,
 	.policy		= nft_redir_policy,
-	.maxattr	= NFTA_MASQ_MAX,
+	.maxattr	= NFTA_REDIR_MAX,
 	.owner		= THIS_MODULE,
 };
 
diff --git a/kernel/net/netfilter/nft_reject_inet.c b/kernel/net/netfilter/nft_reject_inet.c
index cf8f264..c00b94a 100644
--- a/kernel/net/netfilter/nft_reject_inet.c
+++ b/kernel/net/netfilter/nft_reject_inet.c
@@ -28,7 +28,8 @@
 					nft_hook(pkt));
 			break;
 		case NFT_REJECT_TCP_RST:
-			nf_send_reset(nft_net(pkt), pkt->skb, nft_hook(pkt));
+			nf_send_reset(nft_net(pkt), nft_sk(pkt),
+				      pkt->skb, nft_hook(pkt));
 			break;
 		case NFT_REJECT_ICMPX_UNREACH:
 			nf_send_unreach(pkt->skb,
@@ -44,7 +45,8 @@
 					 priv->icmp_code, nft_hook(pkt));
 			break;
 		case NFT_REJECT_TCP_RST:
-			nf_send_reset6(nft_net(pkt), pkt->skb, nft_hook(pkt));
+			nf_send_reset6(nft_net(pkt), nft_sk(pkt),
+				       pkt->skb, nft_hook(pkt));
 			break;
 		case NFT_REJECT_ICMPX_UNREACH:
 			nf_send_unreach6(nft_net(pkt), pkt->skb,
diff --git a/kernel/net/netfilter/nft_set_bitmap.c b/kernel/net/netfilter/nft_set_bitmap.c
index 2a81ea4..3c63f8a 100644
--- a/kernel/net/netfilter/nft_set_bitmap.c
+++ b/kernel/net/netfilter/nft_set_bitmap.c
@@ -270,13 +270,14 @@
 	return 0;
 }
 
-static void nft_bitmap_destroy(const struct nft_set *set)
+static void nft_bitmap_destroy(const struct nft_ctx *ctx,
+			       const struct nft_set *set)
 {
 	struct nft_bitmap *priv = nft_set_priv(set);
 	struct nft_bitmap_elem *be, *n;
 
 	list_for_each_entry_safe(be, n, &priv->list, head)
-		nft_set_elem_destroy(set, be, true);
+		nf_tables_set_elem_destroy(ctx, set, be);
 }
 
 static bool nft_bitmap_estimate(const struct nft_set_desc *desc, u32 features,
diff --git a/kernel/net/netfilter/nft_set_hash.c b/kernel/net/netfilter/nft_set_hash.c
index a5cfb32..f0a9ad1 100644
--- a/kernel/net/netfilter/nft_set_hash.c
+++ b/kernel/net/netfilter/nft_set_hash.c
@@ -17,6 +17,9 @@
 #include <linux/netfilter.h>
 #include <linux/netfilter/nf_tables.h>
 #include <net/netfilter/nf_tables_core.h>
+#include <net/netns/generic.h>
+
+extern unsigned int nf_tables_net_id;
 
 /* We target a hash table size of 4, element hint is 75% of final size */
 #define NFT_RHASH_ELEMENT_HINT 3
@@ -58,6 +61,8 @@
 	const struct nft_rhash_elem *he = ptr;
 
 	if (memcmp(nft_set_ext_key(&he->ext), x->key, x->set->klen))
+		return 1;
+	if (nft_set_elem_is_dead(&he->ext))
 		return 1;
 	if (nft_set_elem_expired(&he->ext))
 		return 1;
@@ -187,7 +192,6 @@
 	struct nft_rhash_elem *he = elem->priv;
 
 	nft_set_elem_change_active(net, set, &he->ext);
-	nft_set_elem_clear_busy(&he->ext);
 }
 
 static bool nft_rhash_flush(const struct net *net,
@@ -195,12 +199,9 @@
 {
 	struct nft_rhash_elem *he = priv;
 
-	if (!nft_set_elem_mark_busy(&he->ext) ||
-	    !nft_is_active(net, &he->ext)) {
-		nft_set_elem_change_active(net, set, &he->ext);
-		return true;
-	}
-	return false;
+	nft_set_elem_change_active(net, set, &he->ext);
+
+	return true;
 }
 
 static void *nft_rhash_deactivate(const struct net *net,
@@ -217,9 +218,8 @@
 
 	rcu_read_lock();
 	he = rhashtable_lookup(&priv->ht, &arg, nft_rhash_params);
-	if (he != NULL &&
-	    !nft_rhash_flush(net, set, he))
-		he = NULL;
+	if (he)
+		nft_set_elem_change_active(net, set, &he->ext);
 
 	rcu_read_unlock();
 
@@ -251,7 +251,9 @@
 	if (he == NULL)
 		return false;
 
-	return rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params) == 0;
+	nft_set_elem_dead(&he->ext);
+
+	return true;
 }
 
 static void nft_rhash_walk(const struct nft_ctx *ctx, struct nft_set *set,
@@ -277,8 +279,6 @@
 
 		if (iter->count < iter->skip)
 			goto cont;
-		if (nft_set_elem_expired(&he->ext))
-			goto cont;
 		if (!nft_set_elem_active(&he->ext, iter->genmask))
 			goto cont;
 
@@ -297,49 +297,75 @@
 
 static void nft_rhash_gc(struct work_struct *work)
 {
+	struct nftables_pernet *nft_net;
 	struct nft_set *set;
 	struct nft_rhash_elem *he;
 	struct nft_rhash *priv;
-	struct nft_set_gc_batch *gcb = NULL;
 	struct rhashtable_iter hti;
+	struct nft_trans_gc *gc;
+	struct net *net;
+	u32 gc_seq;
 
 	priv = container_of(work, struct nft_rhash, gc_work.work);
 	set  = nft_set_container_of(priv);
+	net  = read_pnet(&set->net);
+	nft_net = net_generic(net, nf_tables_net_id);
+	gc_seq = READ_ONCE(nft_net->gc_seq);
+
+	if (nft_set_gc_is_pending(set))
+		goto done;
+
+	gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL);
+	if (!gc)
+		goto done;
 
 	rhashtable_walk_enter(&priv->ht, &hti);
 	rhashtable_walk_start(&hti);
 
 	while ((he = rhashtable_walk_next(&hti))) {
 		if (IS_ERR(he)) {
-			if (PTR_ERR(he) != -EAGAIN)
-				break;
-			continue;
+			nft_trans_gc_destroy(gc);
+			gc = NULL;
+			goto try_later;
 		}
+
+		/* Ruleset has been updated, try later. */
+		if (READ_ONCE(nft_net->gc_seq) != gc_seq) {
+			nft_trans_gc_destroy(gc);
+			gc = NULL;
+			goto try_later;
+		}
+
+		if (nft_set_elem_is_dead(&he->ext))
+			goto dead_elem;
 
 		if (nft_set_ext_exists(&he->ext, NFT_SET_EXT_EXPR)) {
 			struct nft_expr *expr = nft_set_ext_expr(&he->ext);
 
 			if (expr->ops->gc &&
 			    expr->ops->gc(read_pnet(&set->net), expr))
-				goto gc;
+				goto needs_gc_run;
 		}
+
 		if (!nft_set_elem_expired(&he->ext))
 			continue;
-gc:
-		if (nft_set_elem_mark_busy(&he->ext))
-			continue;
+needs_gc_run:
+		nft_set_elem_dead(&he->ext);
+dead_elem:
+		gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
+		if (!gc)
+			goto try_later;
 
-		gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
-		if (gcb == NULL)
-			break;
-		rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params);
-		atomic_dec(&set->nelems);
-		nft_set_gc_batch_add(gcb, he);
+		nft_trans_gc_elem_add(gc, he);
 	}
+
+try_later:
 	rhashtable_walk_stop(&hti);
 	rhashtable_walk_exit(&hti);
 
-	nft_set_gc_batch_complete(gcb);
+	if (gc)
+		nft_trans_gc_queue_async_done(gc);
+done:
 	queue_delayed_work(system_power_efficient_wq, &priv->gc_work,
 			   nft_set_gc_interval(set));
 }
@@ -374,25 +400,36 @@
 		return err;
 
 	INIT_DEFERRABLE_WORK(&priv->gc_work, nft_rhash_gc);
-	if (set->flags & NFT_SET_TIMEOUT)
+	if (set->flags & (NFT_SET_TIMEOUT | NFT_SET_EVAL))
 		nft_rhash_gc_init(set);
 
 	return 0;
 }
 
+struct nft_rhash_ctx {
+	const struct nft_ctx	ctx;
+	const struct nft_set	*set;
+};
+
 static void nft_rhash_elem_destroy(void *ptr, void *arg)
 {
-	nft_set_elem_destroy(arg, ptr, true);
+	struct nft_rhash_ctx *rhash_ctx = arg;
+
+	nf_tables_set_elem_destroy(&rhash_ctx->ctx, rhash_ctx->set, ptr);
 }
 
-static void nft_rhash_destroy(const struct nft_set *set)
+static void nft_rhash_destroy(const struct nft_ctx *ctx,
+			      const struct nft_set *set)
 {
 	struct nft_rhash *priv = nft_set_priv(set);
+	struct nft_rhash_ctx rhash_ctx = {
+		.ctx	= *ctx,
+		.set	= set,
+	};
 
 	cancel_delayed_work_sync(&priv->gc_work);
-	rcu_barrier();
 	rhashtable_free_and_destroy(&priv->ht, nft_rhash_elem_destroy,
-				    (void *)set);
+				    (void *)&rhash_ctx);
 }
 
 /* Number of buckets is stored in u32, so cap our result to 1U<<31 */
@@ -621,7 +658,8 @@
 	return 0;
 }
 
-static void nft_hash_destroy(const struct nft_set *set)
+static void nft_hash_destroy(const struct nft_ctx *ctx,
+			     const struct nft_set *set)
 {
 	struct nft_hash *priv = nft_set_priv(set);
 	struct nft_hash_elem *he;
@@ -631,7 +669,7 @@
 	for (i = 0; i < priv->buckets; i++) {
 		hlist_for_each_entry_safe(he, next, &priv->table[i], node) {
 			hlist_del_rcu(&he->node);
-			nft_set_elem_destroy(set, he, true);
+			nf_tables_set_elem_destroy(ctx, set, he);
 		}
 	}
 }
diff --git a/kernel/net/netfilter/nft_set_pipapo.c b/kernel/net/netfilter/nft_set_pipapo.c
index 30cf067..fbfcc32 100644
--- a/kernel/net/netfilter/nft_set_pipapo.c
+++ b/kernel/net/netfilter/nft_set_pipapo.c
@@ -566,8 +566,9 @@
 			goto out;
 
 		if (last) {
-			if (nft_set_elem_expired(&f->mt[b].e->ext) ||
-			    (genmask &&
+			if (nft_set_elem_expired(&f->mt[b].e->ext))
+				goto next_match;
+			if ((genmask &&
 			     !nft_set_elem_active(&f->mt[b].e->ext, genmask)))
 				goto next_match;
 
@@ -901,11 +902,13 @@
 static int pipapo_insert(struct nft_pipapo_field *f, const uint8_t *k,
 			 int mask_bits)
 {
-	int rule = f->rules++, group, ret, bit_offset = 0;
+	int rule = f->rules, group, ret, bit_offset = 0;
 
-	ret = pipapo_resize(f, f->rules - 1, f->rules);
+	ret = pipapo_resize(f, f->rules, f->rules + 1);
 	if (ret)
 		return ret;
+
+	f->rules++;
 
 	for (group = 0; group < f->groups; group++) {
 		int i, v;
@@ -1051,7 +1054,9 @@
 			step++;
 			if (step >= len) {
 				if (!masks) {
-					pipapo_insert(f, base, 0);
+					err = pipapo_insert(f, base, 0);
+					if (err < 0)
+						return err;
 					masks = 1;
 				}
 				goto out;
@@ -1233,6 +1238,9 @@
 			ret = pipapo_insert(f, start, f->groups * f->bb);
 		else
 			ret = pipapo_expand(f, start, end, f->groups * f->bb);
+
+		if (ret < 0)
+			return ret;
 
 		if (f->bsize > bsize_max)
 			bsize_max = f->bsize;
@@ -1529,15 +1537,32 @@
 	}
 }
 
+static void nft_pipapo_gc_deactivate(struct net *net, struct nft_set *set,
+				     struct nft_pipapo_elem *e)
+{
+	struct nft_set_elem elem = {
+		.priv   = e,
+	};
+
+	nft_setelem_data_deactivate(net, set, &elem);
+}
+
 /**
  * pipapo_gc() - Drop expired entries from set, destroy start and end elements
- * @set:	nftables API set representation
+ * @_set:	nftables API set representation
  * @m:		Matching data
  */
-static void pipapo_gc(const struct nft_set *set, struct nft_pipapo_match *m)
+static void pipapo_gc(const struct nft_set *_set, struct nft_pipapo_match *m)
 {
+	struct nft_set *set = (struct nft_set *) _set;
 	struct nft_pipapo *priv = nft_set_priv(set);
+	struct net *net = read_pnet(&set->net);
 	int rules_f0, first_rule = 0;
+	struct nft_trans_gc *gc;
+
+	gc = nft_trans_gc_alloc(set, 0, GFP_KERNEL);
+	if (!gc)
+		return;
 
 	while ((rules_f0 = pipapo_rules_same_key(m->f, first_rule))) {
 		union nft_pipapo_map_bucket rulemap[NFT_PIPAPO_MAX_FIELDS];
@@ -1562,13 +1587,19 @@
 		f--;
 		i--;
 		e = f->mt[rulemap[i].to].e;
-		if (nft_set_elem_expired(&e->ext) &&
-		    !nft_set_elem_mark_busy(&e->ext)) {
+		/* synchronous gc never fails, there is no need to set on
+		 * NFT_SET_ELEM_DEAD_BIT.
+		 */
+		if (nft_set_elem_expired(&e->ext)) {
 			priv->dirty = true;
-			pipapo_drop(m, rulemap);
 
-			rcu_barrier();
-			nft_set_elem_destroy(set, e, true);
+			gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
+			if (!gc)
+				return;
+
+			nft_pipapo_gc_deactivate(net, set, e);
+			pipapo_drop(m, rulemap);
+			nft_trans_gc_elem_add(gc, e);
 
 			/* And check again current first rule, which is now the
 			 * first we haven't checked.
@@ -1578,7 +1609,10 @@
 		}
 	}
 
-	priv->last_gc = jiffies;
+	if (gc) {
+		nft_trans_gc_queue_sync_done(gc);
+		priv->last_gc = jiffies;
+	}
 }
 
 /**
@@ -1596,16 +1630,9 @@
 	}
 }
 
-/**
- * pipapo_reclaim_match - RCU callback to free fields from old matching data
- * @rcu:	RCU head
- */
-static void pipapo_reclaim_match(struct rcu_head *rcu)
+static void pipapo_free_match(struct nft_pipapo_match *m)
 {
-	struct nft_pipapo_match *m;
 	int i;
-
-	m = container_of(rcu, struct nft_pipapo_match, rcu);
 
 	for_each_possible_cpu(i)
 		kfree(*per_cpu_ptr(m->scratch, i));
@@ -1621,7 +1648,19 @@
 }
 
 /**
- * pipapo_commit() - Replace lookup data with current working copy
+ * pipapo_reclaim_match - RCU callback to free fields from old matching data
+ * @rcu:	RCU head
+ */
+static void pipapo_reclaim_match(struct rcu_head *rcu)
+{
+	struct nft_pipapo_match *m;
+
+	m = container_of(rcu, struct nft_pipapo_match, rcu);
+	pipapo_free_match(m);
+}
+
+/**
+ * nft_pipapo_commit() - Replace lookup data with current working copy
  * @set:	nftables API set representation
  *
  * While at it, check if we should perform garbage collection on the working
@@ -1631,7 +1670,7 @@
  * We also need to create a new working copy for subsequent insertions and
  * deletions.
  */
-static void pipapo_commit(const struct nft_set *set)
+static void nft_pipapo_commit(const struct nft_set *set)
 {
 	struct nft_pipapo *priv = nft_set_priv(set);
 	struct nft_pipapo_match *new_clone, *old;
@@ -1656,6 +1695,26 @@
 	priv->clone = new_clone;
 }
 
+static void nft_pipapo_abort(const struct nft_set *set)
+{
+	struct nft_pipapo *priv = nft_set_priv(set);
+	struct nft_pipapo_match *new_clone, *m;
+
+	if (!priv->dirty)
+		return;
+
+	m = rcu_dereference(priv->match);
+
+	new_clone = pipapo_clone(m);
+	if (IS_ERR(new_clone))
+		return;
+
+	priv->dirty = false;
+
+	pipapo_free_match(priv->clone);
+	priv->clone = new_clone;
+}
+
 /**
  * nft_pipapo_activate() - Mark element reference as active given key, commit
  * @net:	Network namespace
@@ -1663,8 +1722,7 @@
  * @elem:	nftables API element representation containing key data
  *
  * On insertion, elements are added to a copy of the matching data currently
- * in use for lookups, and not directly inserted into current lookup data, so
- * we'll take care of that by calling pipapo_commit() here. Both
+ * in use for lookups, and not directly inserted into current lookup data. Both
  * nft_pipapo_insert() and nft_pipapo_activate() are called once for each
  * element, hence we can't purpose either one as a real commit operation.
  */
@@ -1672,16 +1730,9 @@
 				const struct nft_set *set,
 				const struct nft_set_elem *elem)
 {
-	struct nft_pipapo_elem *e;
-
-	e = pipapo_get(net, set, (const u8 *)elem->key.val.data, 0);
-	if (IS_ERR(e))
-		return;
+	struct nft_pipapo_elem *e = elem->priv;
 
 	nft_set_elem_change_active(net, set, &e->ext);
-	nft_set_elem_clear_busy(&e->ext);
-
-	pipapo_commit(set);
 }
 
 /**
@@ -1893,10 +1944,6 @@
 
 	data = (const u8 *)nft_set_ext_key(&e->ext);
 
-	e = pipapo_get(net, set, data, 0);
-	if (IS_ERR(e))
-		return;
-
 	while ((rules_f0 = pipapo_rules_same_key(m->f, first_rule))) {
 		union nft_pipapo_map_bucket rulemap[NFT_PIPAPO_MAX_FIELDS];
 		const u8 *match_start, *match_end;
@@ -1904,7 +1951,11 @@
 		int i, start, rules_fx;
 
 		match_start = data;
-		match_end = (const u8 *)nft_set_ext_key_end(&e->ext)->data;
+
+		if (nft_set_ext_exists(&e->ext, NFT_SET_EXT_KEY_END))
+			match_end = (const u8 *)nft_set_ext_key_end(&e->ext)->data;
+		else
+			match_end = data;
 
 		start = first_rule;
 		rules_fx = rules_f0;
@@ -1927,7 +1978,6 @@
 		if (i == m->field_count) {
 			priv->dirty = true;
 			pipapo_drop(m, rulemap);
-			pipapo_commit(set);
 			return;
 		}
 
@@ -1949,12 +1999,16 @@
 			    struct nft_set_iter *iter)
 {
 	struct nft_pipapo *priv = nft_set_priv(set);
+	struct net *net = read_pnet(&set->net);
 	struct nft_pipapo_match *m;
 	struct nft_pipapo_field *f;
 	int i, r;
 
 	rcu_read_lock();
-	m = rcu_dereference(priv->match);
+	if (iter->genmask == nft_genmask_cur(net))
+		m = rcu_dereference(priv->match);
+	else
+		m = priv->clone;
 
 	if (unlikely(!m))
 		goto out;
@@ -1973,8 +2027,6 @@
 			goto cont;
 
 		e = f->mt[r].e;
-		if (nft_set_elem_expired(&e->ext))
-			goto cont;
 
 		elem.priv = e;
 
@@ -2123,10 +2175,12 @@
 
 /**
  * nft_set_pipapo_match_destroy() - Destroy elements from key mapping array
+ * @ctx:	context
  * @set:	nftables API set representation
  * @m:		matching data pointing to key mapping array
  */
-static void nft_set_pipapo_match_destroy(const struct nft_set *set,
+static void nft_set_pipapo_match_destroy(const struct nft_ctx *ctx,
+					 const struct nft_set *set,
 					 struct nft_pipapo_match *m)
 {
 	struct nft_pipapo_field *f;
@@ -2143,15 +2197,17 @@
 
 		e = f->mt[r].e;
 
-		nft_set_elem_destroy(set, e, true);
+		nf_tables_set_elem_destroy(ctx, set, e);
 	}
 }
 
 /**
  * nft_pipapo_destroy() - Free private data for set and all committed elements
+ * @ctx:	context
  * @set:	nftables API set representation
  */
-static void nft_pipapo_destroy(const struct nft_set *set)
+static void nft_pipapo_destroy(const struct nft_ctx *ctx,
+			       const struct nft_set *set)
 {
 	struct nft_pipapo *priv = nft_set_priv(set);
 	struct nft_pipapo_match *m;
@@ -2161,7 +2217,7 @@
 	if (m) {
 		rcu_barrier();
 
-		nft_set_pipapo_match_destroy(set, m);
+		nft_set_pipapo_match_destroy(ctx, set, m);
 
 #ifdef NFT_PIPAPO_ALIGN
 		free_percpu(m->scratch_aligned);
@@ -2178,7 +2234,7 @@
 		m = priv->clone;
 
 		if (priv->dirty)
-			nft_set_pipapo_match_destroy(set, m);
+			nft_set_pipapo_match_destroy(ctx, set, m);
 
 #ifdef NFT_PIPAPO_ALIGN
 		free_percpu(priv->clone->scratch_aligned);
@@ -2226,6 +2282,8 @@
 		.init		= nft_pipapo_init,
 		.destroy	= nft_pipapo_destroy,
 		.gc_init	= nft_pipapo_gc_init,
+		.commit		= nft_pipapo_commit,
+		.abort		= nft_pipapo_abort,
 		.elemsize	= offsetof(struct nft_pipapo_elem, ext),
 	},
 };
@@ -2248,6 +2306,8 @@
 		.init		= nft_pipapo_init,
 		.destroy	= nft_pipapo_destroy,
 		.gc_init	= nft_pipapo_gc_init,
+		.commit		= nft_pipapo_commit,
+		.abort		= nft_pipapo_abort,
 		.elemsize	= offsetof(struct nft_pipapo_elem, ext),
 	},
 };
diff --git a/kernel/net/netfilter/nft_set_rbtree.c b/kernel/net/netfilter/nft_set_rbtree.c
index 94a5446..17abf17 100644
--- a/kernel/net/netfilter/nft_set_rbtree.c
+++ b/kernel/net/netfilter/nft_set_rbtree.c
@@ -14,6 +14,9 @@
 #include <linux/netfilter.h>
 #include <linux/netfilter/nf_tables.h>
 #include <net/netfilter/nf_tables_core.h>
+#include <net/netns/generic.h>
+
+extern unsigned int nf_tables_net_id;
 
 struct nft_rbtree {
 	struct rb_root		root;
@@ -38,10 +41,18 @@
 	return !nft_rbtree_interval_end(rbe);
 }
 
-static bool nft_rbtree_equal(const struct nft_set *set, const void *this,
-			     const struct nft_rbtree_elem *interval)
+static int nft_rbtree_cmp(const struct nft_set *set,
+			  const struct nft_rbtree_elem *e1,
+			  const struct nft_rbtree_elem *e2)
 {
-	return memcmp(this, nft_set_ext_key(&interval->ext), set->klen) == 0;
+	return memcmp(nft_set_ext_key(&e1->ext), nft_set_ext_key(&e2->ext),
+		      set->klen);
+}
+
+static bool nft_rbtree_elem_expired(const struct nft_rbtree_elem *rbe)
+{
+	return nft_set_elem_expired(&rbe->ext) ||
+	       nft_set_elem_is_dead(&rbe->ext);
 }
 
 static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set,
@@ -52,7 +63,6 @@
 	const struct nft_rbtree_elem *rbe, *interval = NULL;
 	u8 genmask = nft_genmask_cur(net);
 	const struct rb_node *parent;
-	const void *this;
 	int d;
 
 	parent = rcu_dereference_raw(priv->root.rb_node);
@@ -62,12 +72,11 @@
 
 		rbe = rb_entry(parent, struct nft_rbtree_elem, node);
 
-		this = nft_set_ext_key(&rbe->ext);
-		d = memcmp(this, key, set->klen);
+		d = memcmp(nft_set_ext_key(&rbe->ext), key, set->klen);
 		if (d < 0) {
 			parent = rcu_dereference_raw(parent->rb_left);
 			if (interval &&
-			    nft_rbtree_equal(set, this, interval) &&
+			    !nft_rbtree_cmp(set, rbe, interval) &&
 			    nft_rbtree_interval_end(rbe) &&
 			    nft_rbtree_interval_start(interval))
 				continue;
@@ -80,7 +89,7 @@
 				continue;
 			}
 
-			if (nft_set_elem_expired(&rbe->ext))
+			if (nft_rbtree_elem_expired(rbe))
 				return false;
 
 			if (nft_rbtree_interval_end(rbe)) {
@@ -98,7 +107,7 @@
 
 	if (set->flags & NFT_SET_INTERVAL && interval != NULL &&
 	    nft_set_elem_active(&interval->ext, genmask) &&
-	    !nft_set_elem_expired(&interval->ext) &&
+	    !nft_rbtree_elem_expired(interval) &&
 	    nft_rbtree_interval_start(interval)) {
 		*ext = &interval->ext;
 		return true;
@@ -214,153 +223,262 @@
 	return rbe;
 }
 
+static void nft_rbtree_gc_remove(struct net *net, struct nft_set *set,
+				 struct nft_rbtree *priv,
+				 struct nft_rbtree_elem *rbe)
+{
+	struct nft_set_elem elem = {
+		.priv   = rbe,
+	};
+
+	nft_setelem_data_deactivate(net, set, &elem);
+	rb_erase(&rbe->node, &priv->root);
+}
+
+static const struct nft_rbtree_elem *
+nft_rbtree_gc_elem(const struct nft_set *__set, struct nft_rbtree *priv,
+		   struct nft_rbtree_elem *rbe, u8 genmask)
+{
+	struct nft_set *set = (struct nft_set *)__set;
+	struct rb_node *prev = rb_prev(&rbe->node);
+	struct net *net = read_pnet(&set->net);
+	struct nft_rbtree_elem *rbe_prev;
+	struct nft_trans_gc *gc;
+
+	gc = nft_trans_gc_alloc(set, 0, GFP_ATOMIC);
+	if (!gc)
+		return ERR_PTR(-ENOMEM);
+
+	/* search for end interval coming before this element.
+	 * end intervals don't carry a timeout extension, they
+	 * are coupled with the interval start element.
+	 */
+	while (prev) {
+		rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node);
+		if (nft_rbtree_interval_end(rbe_prev) &&
+		    nft_set_elem_active(&rbe_prev->ext, genmask))
+			break;
+
+		prev = rb_prev(prev);
+	}
+
+	rbe_prev = NULL;
+	if (prev) {
+		rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node);
+		nft_rbtree_gc_remove(net, set, priv, rbe_prev);
+
+		/* There is always room in this trans gc for this element,
+		 * memory allocation never actually happens, hence, the warning
+		 * splat in such case. No need to set NFT_SET_ELEM_DEAD_BIT,
+		 * this is synchronous gc which never fails.
+		 */
+		gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
+		if (WARN_ON_ONCE(!gc))
+			return ERR_PTR(-ENOMEM);
+
+		nft_trans_gc_elem_add(gc, rbe_prev);
+	}
+
+	nft_rbtree_gc_remove(net, set, priv, rbe);
+	gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
+	if (WARN_ON_ONCE(!gc))
+		return ERR_PTR(-ENOMEM);
+
+	nft_trans_gc_elem_add(gc, rbe);
+
+	nft_trans_gc_queue_sync_done(gc);
+
+	return rbe_prev;
+}
+
+static bool nft_rbtree_update_first(const struct nft_set *set,
+				    struct nft_rbtree_elem *rbe,
+				    struct rb_node *first)
+{
+	struct nft_rbtree_elem *first_elem;
+
+	first_elem = rb_entry(first, struct nft_rbtree_elem, node);
+	/* this element is closest to where the new element is to be inserted:
+	 * update the first element for the node list path.
+	 */
+	if (nft_rbtree_cmp(set, rbe, first_elem) < 0)
+		return true;
+
+	return false;
+}
+
 static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
 			       struct nft_rbtree_elem *new,
 			       struct nft_set_ext **ext)
 {
-	bool overlap = false, dup_end_left = false, dup_end_right = false;
+	struct nft_rbtree_elem *rbe, *rbe_le = NULL, *rbe_ge = NULL;
+	struct rb_node *node, *next, *parent, **p, *first = NULL;
 	struct nft_rbtree *priv = nft_set_priv(set);
+	u8 cur_genmask = nft_genmask_cur(net);
 	u8 genmask = nft_genmask_next(net);
-	struct nft_rbtree_elem *rbe;
-	struct rb_node *parent, **p;
 	int d;
 
-	/* Detect overlaps as we descend the tree. Set the flag in these cases:
-	 *
-	 * a1. _ _ __>|  ?_ _ __|  (insert end before existing end)
-	 * a2. _ _ ___|  ?_ _ _>|  (insert end after existing end)
-	 * a3. _ _ ___? >|_ _ __|  (insert start before existing end)
-	 *
-	 * and clear it later on, as we eventually reach the points indicated by
-	 * '?' above, in the cases described below. We'll always meet these
-	 * later, locally, due to tree ordering, and overlaps for the intervals
-	 * that are the closest together are always evaluated last.
-	 *
-	 * b1. _ _ __>|  !_ _ __|  (insert end before existing start)
-	 * b2. _ _ ___|  !_ _ _>|  (insert end after existing start)
-	 * b3. _ _ ___! >|_ _ __|  (insert start after existing end, as a leaf)
-	 *            '--' no nodes falling in this range
-	 * b4.          >|_ _   !  (insert start before existing start)
-	 *
-	 * Case a3. resolves to b3.:
-	 * - if the inserted start element is the leftmost, because the '0'
-	 *   element in the tree serves as end element
-	 * - otherwise, if an existing end is found immediately to the left. If
-	 *   there are existing nodes in between, we need to further descend the
-	 *   tree before we can conclude the new start isn't causing an overlap
-	 *
-	 * or to b4., which, preceded by a3., means we already traversed one or
-	 * more existing intervals entirely, from the right.
-	 *
-	 * For a new, rightmost pair of elements, we'll hit cases b3. and b2.,
-	 * in that order.
-	 *
-	 * The flag is also cleared in two special cases:
-	 *
-	 * b5. |__ _ _!|<_ _ _   (insert start right before existing end)
-	 * b6. |__ _ >|!__ _ _   (insert end right after existing start)
-	 *
-	 * which always happen as last step and imply that no further
-	 * overlapping is possible.
-	 *
-	 * Another special case comes from the fact that start elements matching
-	 * an already existing start element are allowed: insertion is not
-	 * performed but we return -EEXIST in that case, and the error will be
-	 * cleared by the caller if NLM_F_EXCL is not present in the request.
-	 * This way, request for insertion of an exact overlap isn't reported as
-	 * error to userspace if not desired.
-	 *
-	 * However, if the existing start matches a pre-existing start, but the
-	 * end element doesn't match the corresponding pre-existing end element,
-	 * we need to report a partial overlap. This is a local condition that
-	 * can be noticed without need for a tracking flag, by checking for a
-	 * local duplicated end for a corresponding start, from left and right,
-	 * separately.
+	/* Descend the tree to search for an existing element greater than the
+	 * key value to insert that is greater than the new element. This is the
+	 * first element to walk the ordered elements to find possible overlap.
 	 */
-
 	parent = NULL;
 	p = &priv->root.rb_node;
 	while (*p != NULL) {
 		parent = *p;
 		rbe = rb_entry(parent, struct nft_rbtree_elem, node);
-		d = memcmp(nft_set_ext_key(&rbe->ext),
-			   nft_set_ext_key(&new->ext),
-			   set->klen);
+		d = nft_rbtree_cmp(set, rbe, new);
+
 		if (d < 0) {
 			p = &parent->rb_left;
-
-			if (nft_rbtree_interval_start(new)) {
-				if (nft_rbtree_interval_end(rbe) &&
-				    nft_set_elem_active(&rbe->ext, genmask) &&
-				    !nft_set_elem_expired(&rbe->ext) && !*p)
-					overlap = false;
-			} else {
-				if (dup_end_left && !*p)
-					return -ENOTEMPTY;
-
-				overlap = nft_rbtree_interval_end(rbe) &&
-					  nft_set_elem_active(&rbe->ext,
-							      genmask) &&
-					  !nft_set_elem_expired(&rbe->ext);
-
-				if (overlap) {
-					dup_end_right = true;
-					continue;
-				}
-			}
 		} else if (d > 0) {
+			if (!first ||
+			    nft_rbtree_update_first(set, rbe, first))
+				first = &rbe->node;
+
 			p = &parent->rb_right;
-
-			if (nft_rbtree_interval_end(new)) {
-				if (dup_end_right && !*p)
-					return -ENOTEMPTY;
-
-				overlap = nft_rbtree_interval_end(rbe) &&
-					  nft_set_elem_active(&rbe->ext,
-							      genmask) &&
-					  !nft_set_elem_expired(&rbe->ext);
-
-				if (overlap) {
-					dup_end_left = true;
-					continue;
-				}
-			} else if (nft_set_elem_active(&rbe->ext, genmask) &&
-				   !nft_set_elem_expired(&rbe->ext)) {
-				overlap = nft_rbtree_interval_end(rbe);
-			}
 		} else {
-			if (nft_rbtree_interval_end(rbe) &&
-			    nft_rbtree_interval_start(new)) {
+			if (nft_rbtree_interval_end(rbe))
 				p = &parent->rb_left;
-
-				if (nft_set_elem_active(&rbe->ext, genmask) &&
-				    !nft_set_elem_expired(&rbe->ext))
-					overlap = false;
-			} else if (nft_rbtree_interval_start(rbe) &&
-				   nft_rbtree_interval_end(new)) {
+			else
 				p = &parent->rb_right;
-
-				if (nft_set_elem_active(&rbe->ext, genmask) &&
-				    !nft_set_elem_expired(&rbe->ext))
-					overlap = false;
-			} else if (nft_set_elem_active(&rbe->ext, genmask) &&
-				   !nft_set_elem_expired(&rbe->ext)) {
-				*ext = &rbe->ext;
-				return -EEXIST;
-			} else {
-				overlap = false;
-				if (nft_rbtree_interval_end(rbe))
-					p = &parent->rb_left;
-				else
-					p = &parent->rb_right;
-			}
 		}
-
-		dup_end_left = dup_end_right = false;
 	}
 
-	if (overlap)
+	if (!first)
+		first = rb_first(&priv->root);
+
+	/* Detect overlap by going through the list of valid tree nodes.
+	 * Values stored in the tree are in reversed order, starting from
+	 * highest to lowest value.
+	 */
+	for (node = first; node != NULL; node = next) {
+		next = rb_next(node);
+
+		rbe = rb_entry(node, struct nft_rbtree_elem, node);
+
+		if (!nft_set_elem_active(&rbe->ext, genmask))
+			continue;
+
+		/* perform garbage collection to avoid bogus overlap reports
+		 * but skip new elements in this transaction.
+		 */
+		if (nft_set_elem_expired(&rbe->ext) &&
+		    nft_set_elem_active(&rbe->ext, cur_genmask)) {
+			const struct nft_rbtree_elem *removed_end;
+
+			removed_end = nft_rbtree_gc_elem(set, priv, rbe, genmask);
+			if (IS_ERR(removed_end))
+				return PTR_ERR(removed_end);
+
+			if (removed_end == rbe_le || removed_end == rbe_ge)
+				return -EAGAIN;
+
+			continue;
+		}
+
+		d = nft_rbtree_cmp(set, rbe, new);
+		if (d == 0) {
+			/* Matching end element: no need to look for an
+			 * overlapping greater or equal element.
+			 */
+			if (nft_rbtree_interval_end(rbe)) {
+				rbe_le = rbe;
+				break;
+			}
+
+			/* first element that is greater or equal to key value. */
+			if (!rbe_ge) {
+				rbe_ge = rbe;
+				continue;
+			}
+
+			/* this is a closer more or equal element, update it. */
+			if (nft_rbtree_cmp(set, rbe_ge, new) != 0) {
+				rbe_ge = rbe;
+				continue;
+			}
+
+			/* element is equal to key value, make sure flags are
+			 * the same, an existing more or equal start element
+			 * must not be replaced by more or equal end element.
+			 */
+			if ((nft_rbtree_interval_start(new) &&
+			     nft_rbtree_interval_start(rbe_ge)) ||
+			    (nft_rbtree_interval_end(new) &&
+			     nft_rbtree_interval_end(rbe_ge))) {
+				rbe_ge = rbe;
+				continue;
+			}
+		} else if (d > 0) {
+			/* annotate element greater than the new element. */
+			rbe_ge = rbe;
+			continue;
+		} else if (d < 0) {
+			/* annotate element less than the new element. */
+			rbe_le = rbe;
+			break;
+		}
+	}
+
+	/* - new start element matching existing start element: full overlap
+	 *   reported as -EEXIST, cleared by caller if NLM_F_EXCL is not given.
+	 */
+	if (rbe_ge && !nft_rbtree_cmp(set, new, rbe_ge) &&
+	    nft_rbtree_interval_start(rbe_ge) == nft_rbtree_interval_start(new)) {
+		*ext = &rbe_ge->ext;
+		return -EEXIST;
+	}
+
+	/* - new end element matching existing end element: full overlap
+	 *   reported as -EEXIST, cleared by caller if NLM_F_EXCL is not given.
+	 */
+	if (rbe_le && !nft_rbtree_cmp(set, new, rbe_le) &&
+	    nft_rbtree_interval_end(rbe_le) == nft_rbtree_interval_end(new)) {
+		*ext = &rbe_le->ext;
+		return -EEXIST;
+	}
+
+	/* - new start element with existing closest, less or equal key value
+	 *   being a start element: partial overlap, reported as -ENOTEMPTY.
+	 *   Anonymous sets allow for two consecutive start element since they
+	 *   are constant, skip them to avoid bogus overlap reports.
+	 */
+	if (!nft_set_is_anonymous(set) && rbe_le &&
+	    nft_rbtree_interval_start(rbe_le) && nft_rbtree_interval_start(new))
 		return -ENOTEMPTY;
+
+	/* - new end element with existing closest, less or equal key value
+	 *   being a end element: partial overlap, reported as -ENOTEMPTY.
+	 */
+	if (rbe_le &&
+	    nft_rbtree_interval_end(rbe_le) && nft_rbtree_interval_end(new))
+		return -ENOTEMPTY;
+
+	/* - new end element with existing closest, greater or equal key value
+	 *   being an end element: partial overlap, reported as -ENOTEMPTY
+	 */
+	if (rbe_ge &&
+	    nft_rbtree_interval_end(rbe_ge) && nft_rbtree_interval_end(new))
+		return -ENOTEMPTY;
+
+	/* Accepted element: pick insertion point depending on key value */
+	parent = NULL;
+	p = &priv->root.rb_node;
+	while (*p != NULL) {
+		parent = *p;
+		rbe = rb_entry(parent, struct nft_rbtree_elem, node);
+		d = nft_rbtree_cmp(set, rbe, new);
+
+		if (d < 0)
+			p = &parent->rb_left;
+		else if (d > 0)
+			p = &parent->rb_right;
+		else if (nft_rbtree_interval_end(rbe))
+			p = &parent->rb_left;
+		else
+			p = &parent->rb_right;
+	}
 
 	rb_link_node_rcu(&new->node, parent, p);
 	rb_insert_color(&new->node, &priv->root);
@@ -375,11 +493,18 @@
 	struct nft_rbtree_elem *rbe = elem->priv;
 	int err;
 
-	write_lock_bh(&priv->lock);
-	write_seqcount_begin(&priv->count);
-	err = __nft_rbtree_insert(net, set, rbe, ext);
-	write_seqcount_end(&priv->count);
-	write_unlock_bh(&priv->lock);
+	do {
+		if (fatal_signal_pending(current))
+			return -EINTR;
+
+		cond_resched();
+
+		write_lock_bh(&priv->lock);
+		write_seqcount_begin(&priv->count);
+		err = __nft_rbtree_insert(net, set, rbe, ext);
+		write_seqcount_end(&priv->count);
+		write_unlock_bh(&priv->lock);
+	} while (err == -EAGAIN);
 
 	return err;
 }
@@ -405,7 +530,6 @@
 	struct nft_rbtree_elem *rbe = elem->priv;
 
 	nft_set_elem_change_active(net, set, &rbe->ext);
-	nft_set_elem_clear_busy(&rbe->ext);
 }
 
 static bool nft_rbtree_flush(const struct net *net,
@@ -413,12 +537,9 @@
 {
 	struct nft_rbtree_elem *rbe = priv;
 
-	if (!nft_set_elem_mark_busy(&rbe->ext) ||
-	    !nft_is_active(net, &rbe->ext)) {
-		nft_set_elem_change_active(net, set, &rbe->ext);
-		return true;
-	}
-	return false;
+	nft_set_elem_change_active(net, set, &rbe->ext);
+
+	return true;
 }
 
 static void *nft_rbtree_deactivate(const struct net *net,
@@ -475,8 +596,6 @@
 
 		if (iter->count < iter->skip)
 			goto cont;
-		if (nft_set_elem_expired(&rbe->ext))
-			goto cont;
 		if (!nft_set_elem_active(&rbe->ext, iter->genmask))
 			goto cont;
 
@@ -495,58 +614,80 @@
 
 static void nft_rbtree_gc(struct work_struct *work)
 {
-	struct nft_rbtree_elem *rbe, *rbe_end = NULL, *rbe_prev = NULL;
-	struct nft_set_gc_batch *gcb = NULL;
+	struct nft_rbtree_elem *rbe, *rbe_end = NULL;
+	struct nftables_pernet *nft_net;
 	struct nft_rbtree *priv;
+	struct nft_trans_gc *gc;
 	struct rb_node *node;
 	struct nft_set *set;
+	unsigned int gc_seq;
+	struct net *net;
 
 	priv = container_of(work, struct nft_rbtree, gc_work.work);
 	set  = nft_set_container_of(priv);
+	net  = read_pnet(&set->net);
+	nft_net = net_generic(net, nf_tables_net_id);
+	gc_seq	= READ_ONCE(nft_net->gc_seq);
 
-	write_lock_bh(&priv->lock);
-	write_seqcount_begin(&priv->count);
+	if (nft_set_gc_is_pending(set))
+		goto done;
+
+	gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL);
+	if (!gc)
+		goto done;
+
+	read_lock_bh(&priv->lock);
 	for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) {
+
+		/* Ruleset has been updated, try later. */
+		if (READ_ONCE(nft_net->gc_seq) != gc_seq) {
+			nft_trans_gc_destroy(gc);
+			gc = NULL;
+			goto try_later;
+		}
+
 		rbe = rb_entry(node, struct nft_rbtree_elem, node);
 
+		if (nft_set_elem_is_dead(&rbe->ext))
+			goto dead_elem;
+
+		/* elements are reversed in the rbtree for historical reasons,
+		 * from highest to lowest value, that is why end element is
+		 * always visited before the start element.
+		 */
 		if (nft_rbtree_interval_end(rbe)) {
 			rbe_end = rbe;
 			continue;
 		}
 		if (!nft_set_elem_expired(&rbe->ext))
 			continue;
-		if (nft_set_elem_mark_busy(&rbe->ext))
+
+		nft_set_elem_dead(&rbe->ext);
+
+		if (!rbe_end)
 			continue;
 
-		if (rbe_prev) {
-			rb_erase(&rbe_prev->node, &priv->root);
-			rbe_prev = NULL;
-		}
-		gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
-		if (!gcb)
-			break;
+		nft_set_elem_dead(&rbe_end->ext);
 
-		atomic_dec(&set->nelems);
-		nft_set_gc_batch_add(gcb, rbe);
-		rbe_prev = rbe;
+		gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
+		if (!gc)
+			goto try_later;
 
-		if (rbe_end) {
-			atomic_dec(&set->nelems);
-			nft_set_gc_batch_add(gcb, rbe_end);
-			rb_erase(&rbe_end->node, &priv->root);
-			rbe_end = NULL;
-		}
-		node = rb_next(node);
-		if (!node)
-			break;
+		nft_trans_gc_elem_add(gc, rbe_end);
+		rbe_end = NULL;
+dead_elem:
+		gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
+		if (!gc)
+			goto try_later;
+
+		nft_trans_gc_elem_add(gc, rbe);
 	}
-	if (rbe_prev)
-		rb_erase(&rbe_prev->node, &priv->root);
-	write_seqcount_end(&priv->count);
-	write_unlock_bh(&priv->lock);
+try_later:
+	read_unlock_bh(&priv->lock);
 
-	nft_set_gc_batch_complete(gcb);
-
+	if (gc)
+		nft_trans_gc_queue_async_done(gc);
+done:
 	queue_delayed_work(system_power_efficient_wq, &priv->gc_work,
 			   nft_set_gc_interval(set));
 }
@@ -575,7 +716,8 @@
 	return 0;
 }
 
-static void nft_rbtree_destroy(const struct nft_set *set)
+static void nft_rbtree_destroy(const struct nft_ctx *ctx,
+			       const struct nft_set *set)
 {
 	struct nft_rbtree *priv = nft_set_priv(set);
 	struct nft_rbtree_elem *rbe;
@@ -586,7 +728,7 @@
 	while ((node = priv->root.rb_node) != NULL) {
 		rb_erase(node, &priv->root);
 		rbe = rb_entry(node, struct nft_rbtree_elem, node);
-		nft_set_elem_destroy(set, rbe, true);
+		nf_tables_set_elem_destroy(ctx, set, rbe);
 	}
 }
 
diff --git a/kernel/net/netfilter/nft_synproxy.c b/kernel/net/netfilter/nft_synproxy.c
index 59c4dfa..1133e06 100644
--- a/kernel/net/netfilter/nft_synproxy.c
+++ b/kernel/net/netfilter/nft_synproxy.c
@@ -109,7 +109,7 @@
 {
 	struct synproxy_options opts = {};
 	struct sk_buff *skb = pkt->skb;
-	int thoff = pkt->xt.thoff;
+	int thoff = nft_thoff(pkt);
 	const struct tcphdr *tcp;
 	struct tcphdr _tcph;
 
@@ -123,7 +123,7 @@
 		return;
 	}
 
-	tcp = skb_header_pointer(skb, pkt->xt.thoff,
+	tcp = skb_header_pointer(skb, thoff,
 				 sizeof(struct tcphdr),
 				 &_tcph);
 	if (!tcp) {
diff --git a/kernel/net/netfilter/nft_tproxy.c b/kernel/net/netfilter/nft_tproxy.c
index 37c728b..f8d277e 100644
--- a/kernel/net/netfilter/nft_tproxy.c
+++ b/kernel/net/netfilter/nft_tproxy.c
@@ -88,9 +88,9 @@
 	const struct nft_tproxy *priv = nft_expr_priv(expr);
 	struct sk_buff *skb = pkt->skb;
 	const struct ipv6hdr *iph = ipv6_hdr(skb);
-	struct in6_addr taddr;
-	int thoff = pkt->xt.thoff;
+	int thoff = nft_thoff(pkt);
 	struct udphdr _hdr, *hp;
+	struct in6_addr taddr;
 	__be16 tport = 0;
 	struct sock *sk;
 	int l4proto;
@@ -289,6 +289,13 @@
 	return 0;
 }
 
+static int nft_tproxy_validate(const struct nft_ctx *ctx,
+			       const struct nft_expr *expr,
+			       const struct nft_data **data)
+{
+	return nft_chain_validate_hooks(ctx->chain, 1 << NF_INET_PRE_ROUTING);
+}
+
 static struct nft_expr_type nft_tproxy_type;
 static const struct nft_expr_ops nft_tproxy_ops = {
 	.type		= &nft_tproxy_type,
@@ -296,6 +303,7 @@
 	.eval		= nft_tproxy_eval,
 	.init		= nft_tproxy_init,
 	.dump		= nft_tproxy_dump,
+	.validate	= nft_tproxy_validate,
 };
 
 static struct nft_expr_type nft_tproxy_type __read_mostly = {
diff --git a/kernel/net/netfilter/xt_osf.c b/kernel/net/netfilter/xt_osf.c
index e1990ba..dc94858 100644
--- a/kernel/net/netfilter/xt_osf.c
+++ b/kernel/net/netfilter/xt_osf.c
@@ -71,4 +71,3 @@
 MODULE_DESCRIPTION("Passive OS fingerprint matching.");
 MODULE_ALIAS("ipt_osf");
 MODULE_ALIAS("ip6t_osf");
-MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_OSF);
diff --git a/kernel/net/netfilter/xt_sctp.c b/kernel/net/netfilter/xt_sctp.c
index 680015b..d4bf089 100644
--- a/kernel/net/netfilter/xt_sctp.c
+++ b/kernel/net/netfilter/xt_sctp.c
@@ -150,6 +150,8 @@
 {
 	const struct xt_sctp_info *info = par->matchinfo;
 
+	if (info->flag_count > ARRAY_SIZE(info->flag_info))
+		return -EINVAL;
 	if (info->flags & ~XT_SCTP_VALID_FLAGS)
 		return -EINVAL;
 	if (info->invflags & ~XT_SCTP_VALID_FLAGS)
diff --git a/kernel/net/netfilter/xt_u32.c b/kernel/net/netfilter/xt_u32.c
index 177b40d..117d461 100644
--- a/kernel/net/netfilter/xt_u32.c
+++ b/kernel/net/netfilter/xt_u32.c
@@ -96,11 +96,32 @@
 	return ret ^ data->invert;
 }
 
+static int u32_mt_checkentry(const struct xt_mtchk_param *par)
+{
+	const struct xt_u32 *data = par->matchinfo;
+	const struct xt_u32_test *ct;
+	unsigned int i;
+
+	if (data->ntests > ARRAY_SIZE(data->tests))
+		return -EINVAL;
+
+	for (i = 0; i < data->ntests; ++i) {
+		ct = &data->tests[i];
+
+		if (ct->nnums > ARRAY_SIZE(ct->location) ||
+		    ct->nvalues > ARRAY_SIZE(ct->value))
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
 static struct xt_match xt_u32_mt_reg __read_mostly = {
 	.name       = "u32",
 	.revision   = 0,
 	.family     = NFPROTO_UNSPEC,
 	.match      = u32_mt,
+	.checkentry = u32_mt_checkentry,
 	.matchsize  = sizeof(struct xt_u32),
 	.me         = THIS_MODULE,
 };
diff --git a/kernel/net/netlabel/netlabel_kapi.c b/kernel/net/netlabel/netlabel_kapi.c
index 91b35b7..96059c9 100644
--- a/kernel/net/netlabel/netlabel_kapi.c
+++ b/kernel/net/netlabel/netlabel_kapi.c
@@ -857,7 +857,8 @@
 
 	offset -= iter->startbit;
 	idx = offset / NETLBL_CATMAP_MAPSIZE;
-	iter->bitmap[idx] |= bitmap << (offset % NETLBL_CATMAP_MAPSIZE);
+	iter->bitmap[idx] |= (NETLBL_CATMAP_MAPTYPE)bitmap
+			     << (offset % NETLBL_CATMAP_MAPSIZE);
 
 	return 0;
 }
diff --git a/kernel/net/netlink/af_netlink.c b/kernel/net/netlink/af_netlink.c
index d96a610..9737c32 100644
--- a/kernel/net/netlink/af_netlink.c
+++ b/kernel/net/netlink/af_netlink.c
@@ -570,7 +570,9 @@
 	if (nlk_sk(sk)->bound)
 		goto err;
 
-	nlk_sk(sk)->portid = portid;
+	/* portid can be read locklessly from netlink_getname(). */
+	WRITE_ONCE(nlk_sk(sk)->portid, portid);
+
 	sock_hold(sk);
 
 	err = __netlink_insert(table, sk);
@@ -1079,9 +1081,11 @@
 		return -EINVAL;
 
 	if (addr->sa_family == AF_UNSPEC) {
-		sk->sk_state	= NETLINK_UNCONNECTED;
-		nlk->dst_portid	= 0;
-		nlk->dst_group  = 0;
+		/* paired with READ_ONCE() in netlink_getsockbyportid() */
+		WRITE_ONCE(sk->sk_state, NETLINK_UNCONNECTED);
+		/* dst_portid and dst_group can be read locklessly */
+		WRITE_ONCE(nlk->dst_portid, 0);
+		WRITE_ONCE(nlk->dst_group, 0);
 		return 0;
 	}
 	if (addr->sa_family != AF_NETLINK)
@@ -1102,9 +1106,11 @@
 		err = netlink_autobind(sock);
 
 	if (err == 0) {
-		sk->sk_state	= NETLINK_CONNECTED;
-		nlk->dst_portid = nladdr->nl_pid;
-		nlk->dst_group  = ffs(nladdr->nl_groups);
+		/* paired with READ_ONCE() in netlink_getsockbyportid() */
+		WRITE_ONCE(sk->sk_state, NETLINK_CONNECTED);
+		/* dst_portid and dst_group can be read locklessly */
+		WRITE_ONCE(nlk->dst_portid, nladdr->nl_pid);
+		WRITE_ONCE(nlk->dst_group, ffs(nladdr->nl_groups));
 	}
 
 	return err;
@@ -1121,10 +1127,12 @@
 	nladdr->nl_pad = 0;
 
 	if (peer) {
-		nladdr->nl_pid = nlk->dst_portid;
-		nladdr->nl_groups = netlink_group_mask(nlk->dst_group);
+		/* Paired with WRITE_ONCE() in netlink_connect() */
+		nladdr->nl_pid = READ_ONCE(nlk->dst_portid);
+		nladdr->nl_groups = netlink_group_mask(READ_ONCE(nlk->dst_group));
 	} else {
-		nladdr->nl_pid = nlk->portid;
+		/* Paired with WRITE_ONCE() in netlink_insert() */
+		nladdr->nl_pid = READ_ONCE(nlk->portid);
 		netlink_lock_table();
 		nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0;
 		netlink_unlock_table();
@@ -1151,8 +1159,9 @@
 
 	/* Don't bother queuing skb if kernel socket has no input function */
 	nlk = nlk_sk(sock);
-	if (sock->sk_state == NETLINK_CONNECTED &&
-	    nlk->dst_portid != nlk_sk(ssk)->portid) {
+	/* dst_portid and sk_state can be changed in netlink_connect() */
+	if (READ_ONCE(sock->sk_state) == NETLINK_CONNECTED &&
+	    READ_ONCE(nlk->dst_portid) != nlk_sk(ssk)->portid) {
 		sock_put(sock);
 		return ERR_PTR(-ECONNREFUSED);
 	}
@@ -1593,6 +1602,7 @@
 int netlink_set_err(struct sock *ssk, u32 portid, u32 group, int code)
 {
 	struct netlink_set_err_data info;
+	unsigned long flags;
 	struct sock *sk;
 	int ret = 0;
 
@@ -1602,12 +1612,12 @@
 	/* sk->sk_err wants a positive error value */
 	info.code = -code;
 
-	read_lock(&nl_table_lock);
+	read_lock_irqsave(&nl_table_lock, flags);
 
 	sk_for_each_bound(sk, &nl_table[ssk->sk_protocol].mc_list)
 		ret += do_one_set_err(sk, &info);
 
-	read_unlock(&nl_table_lock);
+	read_unlock_irqrestore(&nl_table_lock, flags);
 	return ret;
 }
 EXPORT_SYMBOL(netlink_set_err);
@@ -1735,7 +1745,8 @@
 {
 	struct sock *sk = sock->sk;
 	struct netlink_sock *nlk = nlk_sk(sk);
-	int len, val, err;
+	unsigned int flag;
+	int len, val;
 
 	if (level != SOL_NETLINK)
 		return -ENOPROTOOPT;
@@ -1747,39 +1758,17 @@
 
 	switch (optname) {
 	case NETLINK_PKTINFO:
-		if (len < sizeof(int))
-			return -EINVAL;
-		len = sizeof(int);
-		val = nlk->flags & NETLINK_F_RECV_PKTINFO ? 1 : 0;
-		if (put_user(len, optlen) ||
-		    put_user(val, optval))
-			return -EFAULT;
-		err = 0;
+		flag = NETLINK_F_RECV_PKTINFO;
 		break;
 	case NETLINK_BROADCAST_ERROR:
-		if (len < sizeof(int))
-			return -EINVAL;
-		len = sizeof(int);
-		val = nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR ? 1 : 0;
-		if (put_user(len, optlen) ||
-		    put_user(val, optval))
-			return -EFAULT;
-		err = 0;
+		flag = NETLINK_F_BROADCAST_SEND_ERROR;
 		break;
 	case NETLINK_NO_ENOBUFS:
-		if (len < sizeof(int))
-			return -EINVAL;
-		len = sizeof(int);
-		val = nlk->flags & NETLINK_F_RECV_NO_ENOBUFS ? 1 : 0;
-		if (put_user(len, optlen) ||
-		    put_user(val, optval))
-			return -EFAULT;
-		err = 0;
+		flag = NETLINK_F_RECV_NO_ENOBUFS;
 		break;
 	case NETLINK_LIST_MEMBERSHIPS: {
-		int pos, idx, shift;
+		int pos, idx, shift, err = 0;
 
-		err = 0;
 		netlink_lock_table();
 		for (pos = 0; pos * 8 < nlk->ngroups; pos += sizeof(u32)) {
 			if (len - pos < sizeof(u32))
@@ -1793,43 +1782,35 @@
 				break;
 			}
 		}
-		if (put_user(ALIGN(nlk->ngroups / 8, sizeof(u32)), optlen))
+		if (put_user(ALIGN(BITS_TO_BYTES(nlk->ngroups), sizeof(u32)), optlen))
 			err = -EFAULT;
 		netlink_unlock_table();
-		break;
+		return err;
 	}
 	case NETLINK_CAP_ACK:
-		if (len < sizeof(int))
-			return -EINVAL;
-		len = sizeof(int);
-		val = nlk->flags & NETLINK_F_CAP_ACK ? 1 : 0;
-		if (put_user(len, optlen) ||
-		    put_user(val, optval))
-			return -EFAULT;
-		err = 0;
+		flag = NETLINK_F_CAP_ACK;
 		break;
 	case NETLINK_EXT_ACK:
-		if (len < sizeof(int))
-			return -EINVAL;
-		len = sizeof(int);
-		val = nlk->flags & NETLINK_F_EXT_ACK ? 1 : 0;
-		if (put_user(len, optlen) || put_user(val, optval))
-			return -EFAULT;
-		err = 0;
+		flag = NETLINK_F_EXT_ACK;
 		break;
 	case NETLINK_GET_STRICT_CHK:
-		if (len < sizeof(int))
-			return -EINVAL;
-		len = sizeof(int);
-		val = nlk->flags & NETLINK_F_STRICT_CHK ? 1 : 0;
-		if (put_user(len, optlen) || put_user(val, optval))
-			return -EFAULT;
-		err = 0;
+		flag = NETLINK_F_STRICT_CHK;
 		break;
 	default:
-		err = -ENOPROTOOPT;
+		return -ENOPROTOOPT;
 	}
-	return err;
+
+	if (len < sizeof(int))
+		return -EINVAL;
+
+	len = sizeof(int);
+	val = nlk->flags & flag ? 1 : 0;
+
+	if (put_user(len, optlen) ||
+	    copy_to_user(optval, &val, len))
+		return -EFAULT;
+
+	return 0;
 }
 
 static void netlink_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb)
@@ -1888,8 +1869,9 @@
 			goto out;
 		netlink_skb_flags |= NETLINK_SKB_DST;
 	} else {
-		dst_portid = nlk->dst_portid;
-		dst_group = nlk->dst_group;
+		/* Paired with WRITE_ONCE() in netlink_connect() */
+		dst_portid = READ_ONCE(nlk->dst_portid);
+		dst_group = READ_ONCE(nlk->dst_group);
 	}
 
 	/* Paired with WRITE_ONCE() in netlink_insert() */
@@ -2011,7 +1993,7 @@
 
 	skb_free_datagram(sk, skb);
 
-	if (nlk->cb_running &&
+	if (READ_ONCE(nlk->cb_running) &&
 	    atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
 		ret = netlink_dump(sk);
 		if (ret) {
@@ -2323,7 +2305,7 @@
 	if (cb->done)
 		cb->done(cb);
 
-	nlk->cb_running = false;
+	WRITE_ONCE(nlk->cb_running, false);
 	module = cb->module;
 	skb = cb->skb;
 	mutex_unlock(nlk->cb_mutex);
@@ -2386,7 +2368,7 @@
 			goto error_put;
 	}
 
-	nlk->cb_running = true;
+	WRITE_ONCE(nlk->cb_running, true);
 	nlk->dump_done_errno = INT_MAX;
 
 	mutex_unlock(nlk->cb_mutex);
@@ -2672,7 +2654,7 @@
 			   nlk->groups ? (u32)nlk->groups[0] : 0,
 			   sk_rmem_alloc_get(s),
 			   sk_wmem_alloc_get(s),
-			   nlk->cb_running,
+			   READ_ONCE(nlk->cb_running),
 			   refcount_read(&s->sk_refcnt),
 			   atomic_read(&s->sk_drops),
 			   sock_i_ino(s)
diff --git a/kernel/net/netlink/diag.c b/kernel/net/netlink/diag.c
index c6255ea..e4f21b1 100644
--- a/kernel/net/netlink/diag.c
+++ b/kernel/net/netlink/diag.c
@@ -94,6 +94,7 @@
 	struct net *net = sock_net(skb->sk);
 	struct netlink_diag_req *req;
 	struct netlink_sock *nlsk;
+	unsigned long flags;
 	struct sock *sk;
 	int num = 2;
 	int ret = 0;
@@ -152,7 +153,7 @@
 	num++;
 
 mc_list:
-	read_lock(&nl_table_lock);
+	read_lock_irqsave(&nl_table_lock, flags);
 	sk_for_each_bound(sk, &tbl->mc_list) {
 		if (sk_hashed(sk))
 			continue;
@@ -167,13 +168,13 @@
 				 NETLINK_CB(cb->skb).portid,
 				 cb->nlh->nlmsg_seq,
 				 NLM_F_MULTI,
-				 sock_i_ino(sk)) < 0) {
+				 __sock_i_ino(sk)) < 0) {
 			ret = 1;
 			break;
 		}
 		num++;
 	}
-	read_unlock(&nl_table_lock);
+	read_unlock_irqrestore(&nl_table_lock, flags);
 
 done:
 	cb->args[0] = num;
diff --git a/kernel/net/netrom/af_netrom.c b/kernel/net/netrom/af_netrom.c
index e5c8a29..2474716 100644
--- a/kernel/net/netrom/af_netrom.c
+++ b/kernel/net/netrom/af_netrom.c
@@ -400,6 +400,11 @@
 	struct sock *sk = sock->sk;
 
 	lock_sock(sk);
+	if (sock->state != SS_UNCONNECTED) {
+		release_sock(sk);
+		return -EINVAL;
+	}
+
 	if (sk->sk_state != TCP_LISTEN) {
 		memset(&nr_sk(sk)->user_addr, 0, AX25_ADDR_LEN);
 		sk->sk_max_ack_backlog = backlog;
@@ -655,6 +660,11 @@
 		goto out_release;
 	}
 
+	if (sock->state == SS_CONNECTING) {
+		err = -EALREADY;
+		goto out_release;
+	}
+
 	sk->sk_state   = TCP_CLOSE;
 	sock->state = SS_UNCONNECTED;
 
diff --git a/kernel/net/netrom/nr_subr.c b/kernel/net/netrom/nr_subr.c
index 3f99b43..e2d2af9 100644
--- a/kernel/net/netrom/nr_subr.c
+++ b/kernel/net/netrom/nr_subr.c
@@ -123,7 +123,7 @@
 	unsigned char  *dptr;
 	int len, timeout;
 
-	len = NR_NETWORK_LEN + NR_TRANSPORT_LEN;
+	len = NR_TRANSPORT_LEN;
 
 	switch (frametype & 0x0F) {
 	case NR_CONNREQ:
@@ -141,7 +141,8 @@
 		return;
 	}
 
-	if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
+	skb = alloc_skb(NR_NETWORK_LEN + len, GFP_ATOMIC);
+	if (!skb)
 		return;
 
 	/*
@@ -149,7 +150,7 @@
 	 */
 	skb_reserve(skb, NR_NETWORK_LEN);
 
-	dptr = skb_put(skb, skb_tailroom(skb));
+	dptr = skb_put(skb, len);
 
 	switch (frametype & 0x0F) {
 	case NR_CONNREQ:
diff --git a/kernel/net/netrom/nr_timer.c b/kernel/net/netrom/nr_timer.c
index a8da88d..4e7c968 100644
--- a/kernel/net/netrom/nr_timer.c
+++ b/kernel/net/netrom/nr_timer.c
@@ -121,6 +121,7 @@
 		   is accepted() it isn't 'dead' so doesn't get removed. */
 		if (sock_flag(sk, SOCK_DESTROY) ||
 		    (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) {
+			sock_hold(sk);
 			bh_unlock_sock(sk);
 			nr_destroy_socket(sk);
 			goto out;
diff --git a/kernel/net/nfc/core.c b/kernel/net/nfc/core.c
index 2ef5636..10a3d74 100644
--- a/kernel/net/nfc/core.c
+++ b/kernel/net/nfc/core.c
@@ -634,7 +634,7 @@
 	return rc;
 }
 
-int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len)
+int nfc_set_remote_general_bytes(struct nfc_dev *dev, const u8 *gb, u8 gb_len)
 {
 	pr_debug("dev_name=%s gb_len=%d\n", dev_name(&dev->dev), gb_len);
 
@@ -663,7 +663,7 @@
 EXPORT_SYMBOL(nfc_tm_data_received);
 
 int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode,
-		     u8 *gb, size_t gb_len)
+		     const u8 *gb, size_t gb_len)
 {
 	int rc;
 
diff --git a/kernel/net/nfc/hci/llc_shdlc.c b/kernel/net/nfc/hci/llc_shdlc.c
index 0eb4ddc..02909e3 100644
--- a/kernel/net/nfc/hci/llc_shdlc.c
+++ b/kernel/net/nfc/hci/llc_shdlc.c
@@ -123,7 +123,7 @@
 		return ((y >= x) || (y < z)) ? true : false;
 }
 
-static struct sk_buff *llc_shdlc_alloc_skb(struct llc_shdlc *shdlc,
+static struct sk_buff *llc_shdlc_alloc_skb(const struct llc_shdlc *shdlc,
 					   int payload_len)
 {
 	struct sk_buff *skb;
@@ -137,7 +137,7 @@
 }
 
 /* immediately sends an S frame. */
-static int llc_shdlc_send_s_frame(struct llc_shdlc *shdlc,
+static int llc_shdlc_send_s_frame(const struct llc_shdlc *shdlc,
 				  enum sframe_type sframe_type, int nr)
 {
 	int r;
@@ -159,7 +159,7 @@
 }
 
 /* immediately sends an U frame. skb may contain optional payload */
-static int llc_shdlc_send_u_frame(struct llc_shdlc *shdlc,
+static int llc_shdlc_send_u_frame(const struct llc_shdlc *shdlc,
 				  struct sk_buff *skb,
 				  enum uframe_modifier uframe_modifier)
 {
@@ -361,7 +361,7 @@
 	wake_up(shdlc->connect_wq);
 }
 
-static int llc_shdlc_connect_initiate(struct llc_shdlc *shdlc)
+static int llc_shdlc_connect_initiate(const struct llc_shdlc *shdlc)
 {
 	struct sk_buff *skb;
 
@@ -377,7 +377,7 @@
 	return llc_shdlc_send_u_frame(shdlc, skb, U_FRAME_RSET);
 }
 
-static int llc_shdlc_connect_send_ua(struct llc_shdlc *shdlc)
+static int llc_shdlc_connect_send_ua(const struct llc_shdlc *shdlc)
 {
 	struct sk_buff *skb;
 
diff --git a/kernel/net/nfc/llcp.h b/kernel/net/nfc/llcp.h
index 97853c9..a81893b 100644
--- a/kernel/net/nfc/llcp.h
+++ b/kernel/net/nfc/llcp.h
@@ -202,7 +202,6 @@
 void nfc_llcp_sock_unlink(struct llcp_sock_list *l, struct sock *s);
 void nfc_llcp_socket_remote_param_init(struct nfc_llcp_sock *sock);
 struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev);
-struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local);
 int nfc_llcp_local_put(struct nfc_llcp_local *local);
 u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local,
 			 struct nfc_llcp_sock *sock);
@@ -221,15 +220,15 @@
 
 /* TLV API */
 int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
-			  u8 *tlv_array, u16 tlv_array_len);
+			  const u8 *tlv_array, u16 tlv_array_len);
 int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
-				  u8 *tlv_array, u16 tlv_array_len);
+				  const u8 *tlv_array, u16 tlv_array_len);
 
 /* Commands API */
 void nfc_llcp_recv(void *data, struct sk_buff *skb, int err);
-u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length);
+u8 *nfc_llcp_build_tlv(u8 type, const u8 *value, u8 value_length, u8 *tlv_length);
 struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdres_tlv(u8 tid, u8 sap);
-struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, char *uri,
+struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, const char *uri,
 						  size_t uri_len);
 void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp);
 void nfc_llcp_free_sdp_tlv_list(struct hlist_head *sdp_head);
diff --git a/kernel/net/nfc/llcp_commands.c b/kernel/net/nfc/llcp_commands.c
index 475061c..5b8754a 100644
--- a/kernel/net/nfc/llcp_commands.c
+++ b/kernel/net/nfc/llcp_commands.c
@@ -15,7 +15,7 @@
 #include "nfc.h"
 #include "llcp.h"
 
-static u8 llcp_tlv_length[LLCP_TLV_MAX] = {
+static const u8 llcp_tlv_length[LLCP_TLV_MAX] = {
 	0,
 	1, /* VERSION */
 	2, /* MIUX */
@@ -29,7 +29,7 @@
 
 };
 
-static u8 llcp_tlv8(u8 *tlv, u8 type)
+static u8 llcp_tlv8(const u8 *tlv, u8 type)
 {
 	if (tlv[0] != type || tlv[1] != llcp_tlv_length[tlv[0]])
 		return 0;
@@ -37,7 +37,7 @@
 	return tlv[2];
 }
 
-static u16 llcp_tlv16(u8 *tlv, u8 type)
+static u16 llcp_tlv16(const u8 *tlv, u8 type)
 {
 	if (tlv[0] != type || tlv[1] != llcp_tlv_length[tlv[0]])
 		return 0;
@@ -46,37 +46,37 @@
 }
 
 
-static u8 llcp_tlv_version(u8 *tlv)
+static u8 llcp_tlv_version(const u8 *tlv)
 {
 	return llcp_tlv8(tlv, LLCP_TLV_VERSION);
 }
 
-static u16 llcp_tlv_miux(u8 *tlv)
+static u16 llcp_tlv_miux(const u8 *tlv)
 {
 	return llcp_tlv16(tlv, LLCP_TLV_MIUX) & 0x7ff;
 }
 
-static u16 llcp_tlv_wks(u8 *tlv)
+static u16 llcp_tlv_wks(const u8 *tlv)
 {
 	return llcp_tlv16(tlv, LLCP_TLV_WKS);
 }
 
-static u16 llcp_tlv_lto(u8 *tlv)
+static u16 llcp_tlv_lto(const u8 *tlv)
 {
 	return llcp_tlv8(tlv, LLCP_TLV_LTO);
 }
 
-static u8 llcp_tlv_opt(u8 *tlv)
+static u8 llcp_tlv_opt(const u8 *tlv)
 {
 	return llcp_tlv8(tlv, LLCP_TLV_OPT);
 }
 
-static u8 llcp_tlv_rw(u8 *tlv)
+static u8 llcp_tlv_rw(const u8 *tlv)
 {
 	return llcp_tlv8(tlv, LLCP_TLV_RW) & 0xf;
 }
 
-u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length)
+u8 *nfc_llcp_build_tlv(u8 type, const u8 *value, u8 value_length, u8 *tlv_length)
 {
 	u8 *tlv, length;
 
@@ -130,7 +130,7 @@
 	return sdres;
 }
 
-struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, char *uri,
+struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, const char *uri,
 						  size_t uri_len)
 {
 	struct nfc_llcp_sdp_tlv *sdreq;
@@ -190,9 +190,10 @@
 }
 
 int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
-			  u8 *tlv_array, u16 tlv_array_len)
+			  const u8 *tlv_array, u16 tlv_array_len)
 {
-	u8 *tlv = tlv_array, type, length, offset = 0;
+	const u8 *tlv = tlv_array;
+	u8 type, length, offset = 0;
 
 	pr_debug("TLV array length %d\n", tlv_array_len);
 
@@ -239,9 +240,10 @@
 }
 
 int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
-				  u8 *tlv_array, u16 tlv_array_len)
+				  const u8 *tlv_array, u16 tlv_array_len)
 {
-	u8 *tlv = tlv_array, type, length, offset = 0;
+	const u8 *tlv = tlv_array;
+	u8 type, length, offset = 0;
 
 	pr_debug("TLV array length %d\n", tlv_array_len);
 
@@ -295,7 +297,7 @@
 	return pdu;
 }
 
-static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv,
+static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, const u8 *tlv,
 				    u8 tlv_length)
 {
 	/* XXX Add an skb length check */
@@ -359,6 +361,7 @@
 	struct sk_buff *skb;
 	struct nfc_llcp_local *local;
 	u16 size = 0;
+	int err;
 
 	pr_debug("Sending SYMM\n");
 
@@ -370,8 +373,10 @@
 	size += dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE;
 
 	skb = alloc_skb(size, GFP_KERNEL);
-	if (skb == NULL)
-		return -ENOMEM;
+	if (skb == NULL) {
+		err = -ENOMEM;
+		goto out;
+	}
 
 	skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE);
 
@@ -381,17 +386,22 @@
 
 	nfc_llcp_send_to_raw_sock(local, skb, NFC_DIRECTION_TX);
 
-	return nfc_data_exchange(dev, local->target_idx, skb,
+	err = nfc_data_exchange(dev, local->target_idx, skb,
 				 nfc_llcp_recv, local);
+out:
+	nfc_llcp_local_put(local);
+	return err;
 }
 
 int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
 {
 	struct nfc_llcp_local *local;
 	struct sk_buff *skb;
-	u8 *service_name_tlv = NULL, service_name_tlv_length;
-	u8 *miux_tlv = NULL, miux_tlv_length;
-	u8 *rw_tlv = NULL, rw_tlv_length, rw;
+	const u8 *service_name_tlv = NULL;
+	const u8 *miux_tlv = NULL;
+	const u8 *rw_tlv = NULL;
+	u8 service_name_tlv_length = 0;
+	u8 miux_tlv_length,  rw_tlv_length, rw;
 	int err;
 	u16 size = 0;
 	__be16 miux;
@@ -465,8 +475,9 @@
 {
 	struct nfc_llcp_local *local;
 	struct sk_buff *skb;
-	u8 *miux_tlv = NULL, miux_tlv_length;
-	u8 *rw_tlv = NULL, rw_tlv_length, rw;
+	const u8 *miux_tlv = NULL;
+	const u8 *rw_tlv = NULL;
+	u8 miux_tlv_length, rw_tlv_length, rw;
 	int err;
 	u16 size = 0;
 	__be16 miux;
diff --git a/kernel/net/nfc/llcp_core.c b/kernel/net/nfc/llcp_core.c
index cc99751..b110757 100644
--- a/kernel/net/nfc/llcp_core.c
+++ b/kernel/net/nfc/llcp_core.c
@@ -17,6 +17,8 @@
 static u8 llcp_magic[3] = {0x46, 0x66, 0x6d};
 
 static LIST_HEAD(llcp_devices);
+/* Protects llcp_devices list */
+static DEFINE_SPINLOCK(llcp_devices_lock);
 
 static void nfc_llcp_rx_skb(struct nfc_llcp_local *local, struct sk_buff *skb);
 
@@ -143,7 +145,7 @@
 	write_unlock(&local->raw_sockets.lock);
 }
 
-struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
+static struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
 {
 	kref_get(&local->ref);
 
@@ -159,6 +161,7 @@
 	cancel_work_sync(&local->rx_work);
 	cancel_work_sync(&local->timeout_work);
 	kfree_skb(local->rx_pending);
+	local->rx_pending = NULL;
 	del_timer_sync(&local->sdreq_timer);
 	cancel_work_sync(&local->sdreq_timeout_work);
 	nfc_llcp_free_sdp_tlv_list(&local->pending_sdreqs);
@@ -170,7 +173,6 @@
 
 	local = container_of(ref, struct nfc_llcp_local, ref);
 
-	list_del(&local->list);
 	local_cleanup(local);
 	kfree(local);
 }
@@ -283,12 +285,33 @@
 struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev)
 {
 	struct nfc_llcp_local *local;
+	struct nfc_llcp_local *res = NULL;
 
+	spin_lock(&llcp_devices_lock);
 	list_for_each_entry(local, &llcp_devices, list)
-		if (local->dev == dev)
-			return local;
+		if (local->dev == dev) {
+			res = nfc_llcp_local_get(local);
+			break;
+		}
+	spin_unlock(&llcp_devices_lock);
 
-	pr_debug("No device found\n");
+	return res;
+}
+
+static struct nfc_llcp_local *nfc_llcp_remove_local(struct nfc_dev *dev)
+{
+	struct nfc_llcp_local *local, *tmp;
+
+	spin_lock(&llcp_devices_lock);
+	list_for_each_entry_safe(local, tmp, &llcp_devices, list)
+		if (local->dev == dev) {
+			list_del(&local->list);
+			spin_unlock(&llcp_devices_lock);
+			return local;
+		}
+	spin_unlock(&llcp_devices_lock);
+
+	pr_warn("Shutting down device not found\n");
 
 	return NULL;
 }
@@ -301,7 +324,7 @@
 	"urn:nfc:sn:snep",
 };
 
-static int nfc_llcp_wks_sap(char *service_name, size_t service_name_len)
+static int nfc_llcp_wks_sap(const char *service_name, size_t service_name_len)
 {
 	int sap, num_wks;
 
@@ -325,7 +348,7 @@
 
 static
 struct nfc_llcp_sock *nfc_llcp_sock_from_sn(struct nfc_llcp_local *local,
-					    u8 *sn, size_t sn_len)
+					    const u8 *sn, size_t sn_len)
 {
 	struct sock *sk;
 	struct nfc_llcp_sock *llcp_sock, *tmp_sock;
@@ -522,7 +545,7 @@
 {
 	u8 *gb_cur, version, version_length;
 	u8 lto_length, wks_length, miux_length;
-	u8 *version_tlv = NULL, *lto_tlv = NULL,
+	const u8 *version_tlv = NULL, *lto_tlv = NULL,
 	   *wks_tlv = NULL, *miux_tlv = NULL;
 	__be16 wks = cpu_to_be16(local->local_wks);
 	u8 gb_len = 0;
@@ -609,12 +632,15 @@
 
 	*general_bytes_len = local->gb_len;
 
+	nfc_llcp_local_put(local);
+
 	return local->gb;
 }
 
-int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len)
+int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len)
 {
 	struct nfc_llcp_local *local;
+	int err;
 
 	if (gb_len < 3 || gb_len > NFC_MAX_GT_LEN)
 		return -EINVAL;
@@ -631,35 +657,39 @@
 
 	if (memcmp(local->remote_gb, llcp_magic, 3)) {
 		pr_err("MAC does not support LLCP\n");
-		return -EINVAL;
+		err = -EINVAL;
+		goto out;
 	}
 
-	return nfc_llcp_parse_gb_tlv(local,
+	err = nfc_llcp_parse_gb_tlv(local,
 				     &local->remote_gb[3],
 				     local->remote_gb_len - 3);
+out:
+	nfc_llcp_local_put(local);
+	return err;
 }
 
-static u8 nfc_llcp_dsap(struct sk_buff *pdu)
+static u8 nfc_llcp_dsap(const struct sk_buff *pdu)
 {
 	return (pdu->data[0] & 0xfc) >> 2;
 }
 
-static u8 nfc_llcp_ptype(struct sk_buff *pdu)
+static u8 nfc_llcp_ptype(const struct sk_buff *pdu)
 {
 	return ((pdu->data[0] & 0x03) << 2) | ((pdu->data[1] & 0xc0) >> 6);
 }
 
-static u8 nfc_llcp_ssap(struct sk_buff *pdu)
+static u8 nfc_llcp_ssap(const struct sk_buff *pdu)
 {
 	return pdu->data[1] & 0x3f;
 }
 
-static u8 nfc_llcp_ns(struct sk_buff *pdu)
+static u8 nfc_llcp_ns(const struct sk_buff *pdu)
 {
 	return pdu->data[2] >> 4;
 }
 
-static u8 nfc_llcp_nr(struct sk_buff *pdu)
+static u8 nfc_llcp_nr(const struct sk_buff *pdu)
 {
 	return pdu->data[2] & 0xf;
 }
@@ -801,7 +831,7 @@
 }
 
 static struct nfc_llcp_sock *nfc_llcp_sock_get_sn(struct nfc_llcp_local *local,
-						  u8 *sn, size_t sn_len)
+						  const u8 *sn, size_t sn_len)
 {
 	struct nfc_llcp_sock *llcp_sock;
 
@@ -815,9 +845,10 @@
 	return llcp_sock;
 }
 
-static u8 *nfc_llcp_connect_sn(struct sk_buff *skb, size_t *sn_len)
+static const u8 *nfc_llcp_connect_sn(const struct sk_buff *skb, size_t *sn_len)
 {
-	u8 *tlv = &skb->data[2], type, length;
+	u8 type, length;
+	const u8 *tlv = &skb->data[2];
 	size_t tlv_array_len = skb->len - LLCP_HEADER_SIZE, offset = 0;
 
 	while (offset < tlv_array_len) {
@@ -875,7 +906,7 @@
 }
 
 static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
-				  struct sk_buff *skb)
+				  const struct sk_buff *skb)
 {
 	struct sock *new_sk, *parent;
 	struct nfc_llcp_sock *sock, *new_sock;
@@ -893,7 +924,7 @@
 			goto fail;
 		}
 	} else {
-		u8 *sn;
+		const u8 *sn;
 		size_t sn_len;
 
 		sn = nfc_llcp_connect_sn(skb, &sn_len);
@@ -1112,7 +1143,7 @@
 }
 
 static void nfc_llcp_recv_disc(struct nfc_llcp_local *local,
-			       struct sk_buff *skb)
+			       const struct sk_buff *skb)
 {
 	struct nfc_llcp_sock *llcp_sock;
 	struct sock *sk;
@@ -1155,7 +1186,8 @@
 	nfc_llcp_sock_put(llcp_sock);
 }
 
-static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb)
+static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
+			     const struct sk_buff *skb)
 {
 	struct nfc_llcp_sock *llcp_sock;
 	struct sock *sk;
@@ -1188,7 +1220,8 @@
 	nfc_llcp_sock_put(llcp_sock);
 }
 
-static void nfc_llcp_recv_dm(struct nfc_llcp_local *local, struct sk_buff *skb)
+static void nfc_llcp_recv_dm(struct nfc_llcp_local *local,
+			     const struct sk_buff *skb)
 {
 	struct nfc_llcp_sock *llcp_sock;
 	struct sock *sk;
@@ -1226,12 +1259,13 @@
 }
 
 static void nfc_llcp_recv_snl(struct nfc_llcp_local *local,
-			      struct sk_buff *skb)
+			      const struct sk_buff *skb)
 {
 	struct nfc_llcp_sock *llcp_sock;
-	u8 dsap, ssap, *tlv, type, length, tid, sap;
+	u8 dsap, ssap, type, length, tid, sap;
+	const u8 *tlv;
 	u16 tlv_len, offset;
-	char *service_name;
+	const char *service_name;
 	size_t service_name_len;
 	struct nfc_llcp_sdp_tlv *sdp;
 	HLIST_HEAD(llc_sdres_list);
@@ -1522,6 +1556,8 @@
 
 	__nfc_llcp_recv(local, skb);
 
+	nfc_llcp_local_put(local);
+
 	return 0;
 }
 
@@ -1538,6 +1574,8 @@
 
 	/* Close and purge all existing sockets */
 	nfc_llcp_socket_release(local, true, 0);
+
+	nfc_llcp_local_put(local);
 }
 
 void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
@@ -1563,6 +1601,8 @@
 		mod_timer(&local->link_timer,
 			  jiffies + msecs_to_jiffies(local->remote_lto));
 	}
+
+	nfc_llcp_local_put(local);
 }
 
 int nfc_llcp_register_device(struct nfc_dev *ndev)
@@ -1606,14 +1646,16 @@
 	timer_setup(&local->sdreq_timer, nfc_llcp_sdreq_timer, 0);
 	INIT_WORK(&local->sdreq_timeout_work, nfc_llcp_sdreq_timeout_work);
 
+	spin_lock(&llcp_devices_lock);
 	list_add(&local->list, &llcp_devices);
+	spin_unlock(&llcp_devices_lock);
 
 	return 0;
 }
 
 void nfc_llcp_unregister_device(struct nfc_dev *dev)
 {
-	struct nfc_llcp_local *local = nfc_llcp_find_local(dev);
+	struct nfc_llcp_local *local = nfc_llcp_remove_local(dev);
 
 	if (local == NULL) {
 		pr_debug("No such device\n");
diff --git a/kernel/net/nfc/llcp_sock.c b/kernel/net/nfc/llcp_sock.c
index 0b93a17..6e1fba2 100644
--- a/kernel/net/nfc/llcp_sock.c
+++ b/kernel/net/nfc/llcp_sock.c
@@ -99,7 +99,7 @@
 	}
 
 	llcp_sock->dev = dev;
-	llcp_sock->local = nfc_llcp_local_get(local);
+	llcp_sock->local = local;
 	llcp_sock->nfc_protocol = llcp_addr.nfc_protocol;
 	llcp_sock->service_name_len = min_t(unsigned int,
 					    llcp_addr.service_name_len,
@@ -181,7 +181,7 @@
 	}
 
 	llcp_sock->dev = dev;
-	llcp_sock->local = nfc_llcp_local_get(local);
+	llcp_sock->local = local;
 	llcp_sock->nfc_protocol = llcp_addr.nfc_protocol;
 
 	nfc_llcp_sock_link(&local->raw_sockets, sk);
@@ -698,24 +698,22 @@
 	if (dev->dep_link_up == false) {
 		ret = -ENOLINK;
 		device_unlock(&dev->dev);
-		goto put_dev;
+		goto sock_llcp_put_local;
 	}
 	device_unlock(&dev->dev);
 
 	if (local->rf_mode == NFC_RF_INITIATOR &&
 	    addr->target_idx != local->target_idx) {
 		ret = -ENOLINK;
-		goto put_dev;
+		goto sock_llcp_put_local;
 	}
 
 	llcp_sock->dev = dev;
-	llcp_sock->local = nfc_llcp_local_get(local);
+	llcp_sock->local = local;
 	llcp_sock->ssap = nfc_llcp_get_local_ssap(local);
 	if (llcp_sock->ssap == LLCP_SAP_MAX) {
-		nfc_llcp_local_put(llcp_sock->local);
-		llcp_sock->local = NULL;
 		ret = -ENOMEM;
-		goto put_dev;
+		goto sock_llcp_nullify;
 	}
 
 	llcp_sock->reserved_ssap = llcp_sock->ssap;
@@ -760,8 +758,13 @@
 
 sock_llcp_release:
 	nfc_llcp_put_ssap(local, llcp_sock->ssap);
-	nfc_llcp_local_put(llcp_sock->local);
+
+sock_llcp_nullify:
 	llcp_sock->local = NULL;
+	llcp_sock->dev = NULL;
+
+sock_llcp_put_local:
+	nfc_llcp_local_put(local);
 
 put_dev:
 	nfc_put_device(dev);
diff --git a/kernel/net/nfc/netlink.c b/kernel/net/nfc/netlink.c
index b8939eb..1c5b3ce 100644
--- a/kernel/net/nfc/netlink.c
+++ b/kernel/net/nfc/netlink.c
@@ -1039,10 +1039,13 @@
 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 	if (!msg) {
 		rc = -ENOMEM;
-		goto exit;
+		goto put_local;
 	}
 
 	rc = nfc_genl_send_params(msg, local, info->snd_portid, info->snd_seq);
+
+put_local:
+	nfc_llcp_local_put(local);
 
 exit:
 	device_unlock(&dev->dev);
@@ -1105,7 +1108,7 @@
 	if (info->attrs[NFC_ATTR_LLC_PARAM_LTO]) {
 		if (dev->dep_link_up) {
 			rc = -EINPROGRESS;
-			goto exit;
+			goto put_local;
 		}
 
 		local->lto = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_LTO]);
@@ -1116,6 +1119,9 @@
 
 	if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX])
 		local->miux = cpu_to_be16(miux);
+
+put_local:
+	nfc_llcp_local_put(local);
 
 exit:
 	device_unlock(&dev->dev);
@@ -1172,7 +1178,7 @@
 
 		if (rc != 0) {
 			rc = -EINVAL;
-			goto exit;
+			goto put_local;
 		}
 
 		if (!sdp_attrs[NFC_SDP_ATTR_URI])
@@ -1191,7 +1197,7 @@
 		sdreq = nfc_llcp_build_sdreq_tlv(tid, uri, uri_len);
 		if (sdreq == NULL) {
 			rc = -ENOMEM;
-			goto exit;
+			goto put_local;
 		}
 
 		tlvs_len += sdreq->tlv_len;
@@ -1201,10 +1207,14 @@
 
 	if (hlist_empty(&sdreq_list)) {
 		rc = -EINVAL;
-		goto exit;
+		goto put_local;
 	}
 
 	rc = nfc_llcp_send_snl_sdreq(local, &sdreq_list, tlvs_len);
+
+put_local:
+	nfc_llcp_local_put(local);
+
 exit:
 	device_unlock(&dev->dev);
 
@@ -1442,8 +1452,12 @@
 	rc = dev->ops->se_io(dev, se_idx, apdu,
 			apdu_length, cb, cb_context);
 
+	device_unlock(&dev->dev);
+	return rc;
+
 error:
 	device_unlock(&dev->dev);
+	kfree(cb_context);
 	return rc;
 }
 
@@ -1497,6 +1511,7 @@
 	u32 dev_idx, se_idx;
 	u8 *apdu;
 	size_t apdu_len;
+	int rc;
 
 	if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
 	    !info->attrs[NFC_ATTR_SE_INDEX] ||
@@ -1510,25 +1525,37 @@
 	if (!dev)
 		return -ENODEV;
 
-	if (!dev->ops || !dev->ops->se_io)
-		return -ENOTSUPP;
+	if (!dev->ops || !dev->ops->se_io) {
+		rc = -EOPNOTSUPP;
+		goto put_dev;
+	}
 
 	apdu_len = nla_len(info->attrs[NFC_ATTR_SE_APDU]);
-	if (apdu_len == 0)
-		return -EINVAL;
+	if (apdu_len == 0) {
+		rc = -EINVAL;
+		goto put_dev;
+	}
 
 	apdu = nla_data(info->attrs[NFC_ATTR_SE_APDU]);
-	if (!apdu)
-		return -EINVAL;
+	if (!apdu) {
+		rc = -EINVAL;
+		goto put_dev;
+	}
 
 	ctx = kzalloc(sizeof(struct se_io_ctx), GFP_KERNEL);
-	if (!ctx)
-		return -ENOMEM;
+	if (!ctx) {
+		rc = -ENOMEM;
+		goto put_dev;
+	}
 
 	ctx->dev_idx = dev_idx;
 	ctx->se_idx = se_idx;
 
-	return nfc_se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
+	rc = nfc_se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
+
+put_dev:
+	nfc_put_device(dev);
+	return rc;
 }
 
 static int nfc_genl_vendor_cmd(struct sk_buff *skb,
@@ -1551,14 +1578,21 @@
 	subcmd = nla_get_u32(info->attrs[NFC_ATTR_VENDOR_SUBCMD]);
 
 	dev = nfc_get_device(dev_idx);
-	if (!dev || !dev->vendor_cmds || !dev->n_vendor_cmds)
+	if (!dev)
 		return -ENODEV;
+
+	if (!dev->vendor_cmds || !dev->n_vendor_cmds) {
+		err = -ENODEV;
+		goto put_dev;
+	}
 
 	if (info->attrs[NFC_ATTR_VENDOR_DATA]) {
 		data = nla_data(info->attrs[NFC_ATTR_VENDOR_DATA]);
 		data_len = nla_len(info->attrs[NFC_ATTR_VENDOR_DATA]);
-		if (data_len == 0)
-			return -EINVAL;
+		if (data_len == 0) {
+			err = -EINVAL;
+			goto put_dev;
+		}
 	} else {
 		data = NULL;
 		data_len = 0;
@@ -1573,10 +1607,14 @@
 		dev->cur_cmd_info = info;
 		err = cmd->doit(dev, data, data_len);
 		dev->cur_cmd_info = NULL;
-		return err;
+		goto put_dev;
 	}
 
-	return -EOPNOTSUPP;
+	err = -EOPNOTSUPP;
+
+put_dev:
+	nfc_put_device(dev);
+	return err;
 }
 
 /* message building helper */
diff --git a/kernel/net/nfc/nfc.h b/kernel/net/nfc/nfc.h
index 889fefd..0b1e646 100644
--- a/kernel/net/nfc/nfc.h
+++ b/kernel/net/nfc/nfc.h
@@ -48,10 +48,11 @@
 			u8 comm_mode, u8 rf_mode);
 int nfc_llcp_register_device(struct nfc_dev *dev);
 void nfc_llcp_unregister_device(struct nfc_dev *dev);
-int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len);
+int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len);
 u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len);
 int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb);
 struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev);
+int nfc_llcp_local_put(struct nfc_llcp_local *local);
 int __init nfc_llcp_init(void);
 void nfc_llcp_exit(void);
 void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp);
diff --git a/kernel/net/nsh/nsh.c b/kernel/net/nsh/nsh.c
index e9ca007..0f23e5e 100644
--- a/kernel/net/nsh/nsh.c
+++ b/kernel/net/nsh/nsh.c
@@ -77,13 +77,12 @@
 				       netdev_features_t features)
 {
 	struct sk_buff *segs = ERR_PTR(-EINVAL);
+	u16 mac_offset = skb->mac_header;
 	unsigned int nsh_len, mac_len;
 	__be16 proto;
-	int nhoff;
 
 	skb_reset_network_header(skb);
 
-	nhoff = skb->network_header - skb->mac_header;
 	mac_len = skb->mac_len;
 
 	if (unlikely(!pskb_may_pull(skb, NSH_BASE_HDR_LEN)))
@@ -108,15 +107,14 @@
 	segs = skb_mac_gso_segment(skb, features);
 	if (IS_ERR_OR_NULL(segs)) {
 		skb_gso_error_unwind(skb, htons(ETH_P_NSH), nsh_len,
-				     skb->network_header - nhoff,
-				     mac_len);
+				     mac_offset, mac_len);
 		goto out;
 	}
 
 	for (skb = segs; skb; skb = skb->next) {
 		skb->protocol = htons(ETH_P_NSH);
 		__skb_push(skb, nsh_len);
-		skb_set_mac_header(skb, -nhoff);
+		skb->mac_header = mac_offset;
 		skb->network_header = skb->mac_header + mac_len;
 		skb->mac_len = mac_len;
 	}
diff --git a/kernel/net/openvswitch/datapath.c b/kernel/net/openvswitch/datapath.c
index 7ed97dc..b625ab5 100644
--- a/kernel/net/openvswitch/datapath.c
+++ b/kernel/net/openvswitch/datapath.c
@@ -933,6 +933,7 @@
 	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,30 +961,32 @@
 	}
 
 	/* Extract key. */
-	ovs_match_init(&match, &new_flow->key, false, &mask);
+	key = kzalloc(sizeof(*key), GFP_KERNEL);
+	if (!key) {
+		error = -ENOMEM;
+		goto err_kfree_flow;
+	}
+
+	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;
+		goto err_kfree_key;
+
+	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);
+		goto err_kfree_key;
 
 	/* Validate actions. */
 	error = ovs_nla_copy_actions(net, a[OVS_FLOW_ATTR_ACTIONS],
 				     &new_flow->key, &acts, log);
 	if (error) {
 		OVS_NLERR(log, "Flow actions may not be safe on all matching packets.");
-		goto err_kfree_flow;
+		goto err_kfree_key;
 	}
 
 	reply = ovs_flow_cmd_alloc_info(acts, &new_flow->id, info, false,
@@ -1004,7 +1007,7 @@
 	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 @@
 
 	if (reply)
 		ovs_notify(&dp_flow_genl_family, reply, info);
+
+	kfree(key);
 	return 0;
 
 err_unlock_ovs:
@@ -1081,6 +1086,8 @@
 	kfree_skb(reply);
 err_kfree_acts:
 	ovs_nla_free_flow_actions(acts);
+err_kfree_key:
+	kfree(key);
 err_kfree_flow:
 	ovs_flow_free(new_flow, false);
 error:
diff --git a/kernel/net/openvswitch/meter.c b/kernel/net/openvswitch/meter.c
index e594b4d..0cf3dda 100644
--- a/kernel/net/openvswitch/meter.c
+++ b/kernel/net/openvswitch/meter.c
@@ -450,7 +450,7 @@
 
 	err = attach_meter(meter_tbl, meter);
 	if (err)
-		goto exit_unlock;
+		goto exit_free_old_meter;
 
 	ovs_unlock();
 
@@ -473,6 +473,8 @@
 	genlmsg_end(reply, ovs_reply_header);
 	return genlmsg_reply(reply, info);
 
+exit_free_old_meter:
+	ovs_meter_free(old_meter);
 exit_unlock:
 	ovs_unlock();
 	nlmsg_free(reply);
diff --git a/kernel/net/packet/af_packet.c b/kernel/net/packet/af_packet.c
index eaa030e..bbdb32a 100644
--- a/kernel/net/packet/af_packet.c
+++ b/kernel/net/packet/af_packet.c
@@ -269,7 +269,8 @@
 
 static bool packet_use_direct_xmit(const struct packet_sock *po)
 {
-	return po->xmit == packet_direct_xmit;
+	/* Paired with WRITE_ONCE() in packet_setsockopt() */
+	return READ_ONCE(po->xmit) == packet_direct_xmit;
 }
 
 static u16 packet_pick_tx_queue(struct sk_buff *skb)
@@ -365,18 +366,20 @@
 {
 	union tpacket_uhdr h;
 
+	/* WRITE_ONCE() are paired with READ_ONCE() in __packet_get_status */
+
 	h.raw = frame;
 	switch (po->tp_version) {
 	case TPACKET_V1:
-		h.h1->tp_status = status;
+		WRITE_ONCE(h.h1->tp_status, status);
 		flush_dcache_page(pgv_to_page(&h.h1->tp_status));
 		break;
 	case TPACKET_V2:
-		h.h2->tp_status = status;
+		WRITE_ONCE(h.h2->tp_status, status);
 		flush_dcache_page(pgv_to_page(&h.h2->tp_status));
 		break;
 	case TPACKET_V3:
-		h.h3->tp_status = status;
+		WRITE_ONCE(h.h3->tp_status, status);
 		flush_dcache_page(pgv_to_page(&h.h3->tp_status));
 		break;
 	default:
@@ -393,17 +396,19 @@
 
 	smp_rmb();
 
+	/* READ_ONCE() are paired with WRITE_ONCE() in __packet_set_status */
+
 	h.raw = frame;
 	switch (po->tp_version) {
 	case TPACKET_V1:
 		flush_dcache_page(pgv_to_page(&h.h1->tp_status));
-		return h.h1->tp_status;
+		return READ_ONCE(h.h1->tp_status);
 	case TPACKET_V2:
 		flush_dcache_page(pgv_to_page(&h.h2->tp_status));
-		return h.h2->tp_status;
+		return READ_ONCE(h.h2->tp_status);
 	case TPACKET_V3:
 		flush_dcache_page(pgv_to_page(&h.h3->tp_status));
-		return h.h3->tp_status;
+		return READ_ONCE(h.h3->tp_status);
 	default:
 		WARN(1, "TPACKET version not supported.\n");
 		BUG();
@@ -1885,11 +1890,19 @@
 
 static void packet_parse_headers(struct sk_buff *skb, struct socket *sock)
 {
+	int depth;
+
 	if ((!skb->protocol || skb->protocol == htons(ETH_P_ALL)) &&
 	    sock->type == SOCK_RAW) {
 		skb_reset_mac_header(skb);
 		skb->protocol = dev_parse_header_protocol(skb);
 	}
+
+	/* Move network header to the right position for VLAN tagged packets */
+	if (likely(skb->dev->type == ARPHRD_ETHER) &&
+	    eth_type_vlan(skb->protocol) &&
+	    vlan_get_protocol_and_depth(skb, skb->protocol, &depth) != 0)
+		skb_set_network_header(skb, depth);
 
 	skb_probe_transport_header(skb);
 }
@@ -1985,7 +1998,7 @@
 		goto retry;
 	}
 
-	if (!dev_validate_header(dev, skb->data, len)) {
+	if (!dev_validate_header(dev, skb->data, len) || !skb->len) {
 		err = -EINVAL;
 		goto out_unlock;
 	}
@@ -2135,7 +2148,7 @@
 	sll = &PACKET_SKB_CB(skb)->sa.ll;
 	sll->sll_hatype = dev->type;
 	sll->sll_pkttype = skb->pkt_type;
-	if (unlikely(po->origdev))
+	if (unlikely(packet_sock_flag(po, PACKET_SOCK_ORIGDEV)))
 		sll->sll_ifindex = orig_dev->ifindex;
 	else
 		sll->sll_ifindex = dev->ifindex;
@@ -2408,7 +2421,7 @@
 	sll->sll_hatype = dev->type;
 	sll->sll_protocol = skb->protocol;
 	sll->sll_pkttype = skb->pkt_type;
-	if (unlikely(po->origdev))
+	if (unlikely(packet_sock_flag(po, PACKET_SOCK_ORIGDEV)))
 		sll->sll_ifindex = orig_dev->ifindex;
 	else
 		sll->sll_ifindex = dev->ifindex;
@@ -2815,7 +2828,8 @@
 		packet_inc_pending(&po->tx_ring);
 
 		status = TP_STATUS_SEND_REQUEST;
-		err = po->xmit(skb);
+		/* Paired with WRITE_ONCE() in packet_setsockopt() */
+		err = READ_ONCE(po->xmit)(skb);
 		if (unlikely(err != 0)) {
 			if (err > 0)
 				err = net_xmit_errno(err);
@@ -3005,6 +3019,11 @@
 	skb->mark = sockc.mark;
 	skb->tstamp = sockc.transmit_time;
 
+	if (unlikely(extra_len == 4))
+		skb->no_fcs = 1;
+
+	packet_parse_headers(skb, sock);
+
 	if (has_vnet_hdr) {
 		err = virtio_net_hdr_to_skb(skb, &vnet_hdr, vio_le());
 		if (err)
@@ -3013,12 +3032,8 @@
 		virtio_net_hdr_set_proto(skb, &vnet_hdr);
 	}
 
-	packet_parse_headers(skb, sock);
-
-	if (unlikely(extra_len == 4))
-		skb->no_fcs = 1;
-
-	err = po->xmit(skb);
+	/* Paired with WRITE_ONCE() in packet_setsockopt() */
+	err = READ_ONCE(po->xmit)(skb);
 	if (unlikely(err != 0)) {
 		if (err > 0)
 			err = net_xmit_errno(err);
@@ -3146,6 +3161,9 @@
 
 	lock_sock(sk);
 	spin_lock(&po->bind_lock);
+	if (!proto)
+		proto = po->num;
+
 	rcu_read_lock();
 
 	if (po->fanout) {
@@ -3248,7 +3266,7 @@
 	memcpy(name, uaddr->sa_data, sizeof(uaddr->sa_data));
 	name[sizeof(uaddr->sa_data)] = 0;
 
-	return packet_do_bind(sk, name, 0, pkt_sk(sk)->num);
+	return packet_do_bind(sk, name, 0, 0);
 }
 
 static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
@@ -3265,8 +3283,7 @@
 	if (sll->sll_family != AF_PACKET)
 		return -EINVAL;
 
-	return packet_do_bind(sk, NULL, sll->sll_ifindex,
-			      sll->sll_protocol ? : pkt_sk(sk)->num);
+	return packet_do_bind(sk, NULL, sll->sll_ifindex, sll->sll_protocol);
 }
 
 static struct proto packet_proto = {
@@ -3472,7 +3489,7 @@
 		memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, copy_len);
 	}
 
-	if (pkt_sk(sk)->auxdata) {
+	if (packet_sock_flag(pkt_sk(sk), PACKET_SOCK_AUXDATA)) {
 		struct tpacket_auxdata aux;
 
 		aux.tp_status = TP_STATUS_USER;
@@ -3856,9 +3873,7 @@
 		if (copy_from_sockptr(&val, optval, sizeof(val)))
 			return -EFAULT;
 
-		lock_sock(sk);
-		po->auxdata = !!val;
-		release_sock(sk);
+		packet_sock_flag_set(po, PACKET_SOCK_AUXDATA, val);
 		return 0;
 	}
 	case PACKET_ORIGDEV:
@@ -3870,9 +3885,7 @@
 		if (copy_from_sockptr(&val, optval, sizeof(val)))
 			return -EFAULT;
 
-		lock_sock(sk);
-		po->origdev = !!val;
-		release_sock(sk);
+		packet_sock_flag_set(po, PACKET_SOCK_ORIGDEV, val);
 		return 0;
 	}
 	case PACKET_VNET_HDR:
@@ -3969,7 +3982,8 @@
 		if (copy_from_sockptr(&val, optval, sizeof(val)))
 			return -EFAULT;
 
-		po->xmit = val ? packet_direct_xmit : dev_queue_xmit;
+		/* Paired with all lockless reads of po->xmit */
+		WRITE_ONCE(po->xmit, val ? packet_direct_xmit : dev_queue_xmit);
 		return 0;
 	}
 	default:
@@ -4020,10 +4034,10 @@
 
 		break;
 	case PACKET_AUXDATA:
-		val = po->auxdata;
+		val = packet_sock_flag(po, PACKET_SOCK_AUXDATA);
 		break;
 	case PACKET_ORIGDEV:
-		val = po->origdev;
+		val = packet_sock_flag(po, PACKET_SOCK_ORIGDEV);
 		break;
 	case PACKET_VNET_HDR:
 		val = po->has_vnet_hdr;
diff --git a/kernel/net/packet/diag.c b/kernel/net/packet/diag.c
index 07812ae..a68a845 100644
--- a/kernel/net/packet/diag.c
+++ b/kernel/net/packet/diag.c
@@ -23,9 +23,9 @@
 	pinfo.pdi_flags = 0;
 	if (po->running)
 		pinfo.pdi_flags |= PDI_RUNNING;
-	if (po->auxdata)
+	if (packet_sock_flag(po, PACKET_SOCK_AUXDATA))
 		pinfo.pdi_flags |= PDI_AUXDATA;
-	if (po->origdev)
+	if (packet_sock_flag(po, PACKET_SOCK_ORIGDEV))
 		pinfo.pdi_flags |= PDI_ORIGDEV;
 	if (po->has_vnet_hdr)
 		pinfo.pdi_flags |= PDI_VNETHDR;
@@ -143,7 +143,7 @@
 	rp = nlmsg_data(nlh);
 	rp->pdiag_family = AF_PACKET;
 	rp->pdiag_type = sk->sk_type;
-	rp->pdiag_num = ntohs(po->num);
+	rp->pdiag_num = ntohs(READ_ONCE(po->num));
 	rp->pdiag_ino = sk_ino;
 	sock_diag_save_cookie(sk, rp->pdiag_cookie);
 
diff --git a/kernel/net/packet/internal.h b/kernel/net/packet/internal.h
index 7af1e91..3938cb4 100644
--- a/kernel/net/packet/internal.h
+++ b/kernel/net/packet/internal.h
@@ -116,10 +116,9 @@
 	int			copy_thresh;
 	spinlock_t		bind_lock;
 	struct mutex		pg_vec_lock;
+	unsigned long		flags;
 	unsigned int		running;	/* bind_lock must be held */
-	unsigned int		auxdata:1,	/* writer must hold sock lock */
-				origdev:1,
-				has_vnet_hdr:1,
+	unsigned int		has_vnet_hdr:1, /* writer must hold sock lock */
 				tp_loss:1,
 				tp_tx_has_off:1;
 	int			pressure;
@@ -144,4 +143,25 @@
 	return (struct packet_sock *)sk;
 }
 
+enum packet_sock_flags {
+	PACKET_SOCK_ORIGDEV,
+	PACKET_SOCK_AUXDATA,
+};
+
+static inline void packet_sock_flag_set(struct packet_sock *po,
+					enum packet_sock_flags flag,
+					bool val)
+{
+	if (val)
+		set_bit(flag, &po->flags);
+	else
+		clear_bit(flag, &po->flags);
+}
+
+static inline bool packet_sock_flag(const struct packet_sock *po,
+				    enum packet_sock_flags flag)
+{
+	return test_bit(flag, &po->flags);
+}
+
 #endif
diff --git a/kernel/net/qrtr/Makefile b/kernel/net/qrtr/Makefile
index 1b1411d..8e0605f 100644
--- a/kernel/net/qrtr/Makefile
+++ b/kernel/net/qrtr/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_QRTR) := qrtr.o ns.o
+obj-$(CONFIG_QRTR) += qrtr.o
+qrtr-y	:= af_qrtr.o ns.o
 
 obj-$(CONFIG_QRTR_SMD) += qrtr-smd.o
 qrtr-smd-y	:= smd.o
diff --git a/kernel/net/qrtr/qrtr.c b/kernel/net/qrtr/af_qrtr.c
similarity index 98%
rename from kernel/net/qrtr/qrtr.c
rename to kernel/net/qrtr/af_qrtr.c
index 13448ca..71c2295 100644
--- a/kernel/net/qrtr/qrtr.c
+++ b/kernel/net/qrtr/af_qrtr.c
@@ -388,10 +388,12 @@
 	struct qrtr_node *node;
 	unsigned long flags;
 
+	mutex_lock(&qrtr_node_lock);
 	spin_lock_irqsave(&qrtr_nodes_lock, flags);
 	node = radix_tree_lookup(&qrtr_nodes, nid);
 	node = qrtr_node_acquire(node);
 	spin_unlock_irqrestore(&qrtr_nodes_lock, flags);
+	mutex_unlock(&qrtr_node_lock);
 
 	return node;
 }
@@ -490,6 +492,11 @@
 	if (!size || len != ALIGN(size, 4) + hdrlen)
 		goto err;
 
+	if ((cb->type == QRTR_TYPE_NEW_SERVER ||
+	     cb->type == QRTR_TYPE_RESUME_TX) &&
+	    size < sizeof(struct qrtr_ctrl_pkt))
+		goto err;
+
 	if (cb->dst_port != QRTR_PORT_CTRL && cb->type != QRTR_TYPE_DATA &&
 	    cb->type != QRTR_TYPE_RESUME_TX)
 		goto err;
@@ -498,6 +505,14 @@
 
 	qrtr_node_assign(node, cb->src_node);
 
+	if (cb->type == QRTR_TYPE_NEW_SERVER) {
+		/* Remote node endpoint can bridge other distant nodes */
+		const struct qrtr_ctrl_pkt *pkt;
+
+		pkt = data + hdrlen;
+		qrtr_node_assign(node, le32_to_cpu(pkt->server.node));
+	}
+
 	if (cb->type == QRTR_TYPE_RESUME_TX) {
 		qrtr_tx_resume(node, skb);
 	} else {
diff --git a/kernel/net/qrtr/ns.c b/kernel/net/qrtr/ns.c
index e760d4a..713e994 100644
--- a/kernel/net/qrtr/ns.c
+++ b/kernel/net/qrtr/ns.c
@@ -83,7 +83,10 @@
 
 	node->id = node_id;
 
-	radix_tree_insert(&nodes, node_id, node);
+	if (radix_tree_insert(&nodes, node_id, node)) {
+		kfree(node);
+		return NULL;
+	}
 
 	return node;
 }
@@ -270,7 +273,7 @@
 	return NULL;
 }
 
-static int server_del(struct qrtr_node *node, unsigned int port)
+static int server_del(struct qrtr_node *node, unsigned int port, bool bcast)
 {
 	struct qrtr_lookup *lookup;
 	struct qrtr_server *srv;
@@ -283,7 +286,7 @@
 	radix_tree_delete(&node->servers, port);
 
 	/* Broadcast the removal of local servers */
-	if (srv->node == qrtr_ns.local_node)
+	if (srv->node == qrtr_ns.local_node && bcast)
 		service_announce_del(&qrtr_ns.bcast_sq, srv);
 
 	/* Announce the service's disappearance to observers */
@@ -369,7 +372,7 @@
 		}
 		slot = radix_tree_iter_resume(slot, &iter);
 		rcu_read_unlock();
-		server_del(node, srv->port);
+		server_del(node, srv->port, true);
 		rcu_read_lock();
 	}
 	rcu_read_unlock();
@@ -455,10 +458,13 @@
 		kfree(lookup);
 	}
 
-	/* Remove the server belonging to this port */
+	/* Remove the server belonging to this port but don't broadcast
+	 * DEL_SERVER. Neighbours would've already removed the server belonging
+	 * to this port due to the DEL_CLIENT broadcast from qrtr_port_remove().
+	 */
 	node = node_get(node_id);
 	if (node)
-		server_del(node, port);
+		server_del(node, port, false);
 
 	/* Advertise the removal of this client to all local servers */
 	local_node = node_get(qrtr_ns.local_node);
@@ -571,7 +577,7 @@
 	if (!node)
 		return -ENOENT;
 
-	return server_del(node, port);
+	return server_del(node, port, true);
 }
 
 static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from,
diff --git a/kernel/net/rds/message.c b/kernel/net/rds/message.c
index 799034e..8fa3d19 100644
--- a/kernel/net/rds/message.c
+++ b/kernel/net/rds/message.c
@@ -104,9 +104,9 @@
 	spin_lock_irqsave(&q->lock, flags);
 	head = &q->zcookie_head;
 	if (!list_empty(head)) {
-		info = list_entry(head, struct rds_msg_zcopy_info,
-				  rs_zcookie_next);
-		if (info && rds_zcookie_add(info, cookie)) {
+		info = list_first_entry(head, struct rds_msg_zcopy_info,
+					rs_zcookie_next);
+		if (rds_zcookie_add(info, cookie)) {
 			spin_unlock_irqrestore(&q->lock, flags);
 			kfree(rds_info_from_znotifier(znotif));
 			/* caller invokes rds_wake_sk_sleep() */
@@ -118,7 +118,7 @@
 	ck = &info->zcookies;
 	memset(ck, 0, sizeof(*ck));
 	WARN_ON(!rds_zcookie_add(info, cookie));
-	list_add_tail(&q->zcookie_head, &info->rs_zcookie_next);
+	list_add_tail(&info->rs_zcookie_next, &q->zcookie_head);
 
 	spin_unlock_irqrestore(&q->lock, flags);
 	/* caller invokes rds_wake_sk_sleep() */
diff --git a/kernel/net/rds/rdma_transport.c b/kernel/net/rds/rdma_transport.c
index 5f741e5..bb38124 100644
--- a/kernel/net/rds/rdma_transport.c
+++ b/kernel/net/rds/rdma_transport.c
@@ -86,10 +86,12 @@
 		break;
 
 	case RDMA_CM_EVENT_ADDR_RESOLVED:
-		rdma_set_service_type(cm_id, conn->c_tos);
-		/* XXX do we need to clean up if this fails? */
-		ret = rdma_resolve_route(cm_id,
+		if (conn) {
+			rdma_set_service_type(cm_id, conn->c_tos);
+			/* XXX do we need to clean up if this fails? */
+			ret = rdma_resolve_route(cm_id,
 					 RDS_RDMA_RESOLVE_TIMEOUT_MS);
+		}
 		break;
 
 	case RDMA_CM_EVENT_ROUTE_RESOLVED:
diff --git a/kernel/net/rds/tcp_connect.c b/kernel/net/rds/tcp_connect.c
index 4e64598..2f38dac 100644
--- a/kernel/net/rds/tcp_connect.c
+++ b/kernel/net/rds/tcp_connect.c
@@ -169,7 +169,7 @@
 	 * own the socket
 	 */
 	rds_tcp_set_callbacks(sock, cp);
-	ret = sock->ops->connect(sock, addr, addrlen, O_NONBLOCK);
+	ret = kernel_connect(sock, addr, addrlen, O_NONBLOCK);
 
 	rdsdebug("connect to address %pI6c returned %d\n", &conn->c_faddr, ret);
 	if (ret == -EINPROGRESS)
diff --git a/kernel/net/rose/af_rose.c b/kernel/net/rose/af_rose.c
index 29a208e..86c93cf 100644
--- a/kernel/net/rose/af_rose.c
+++ b/kernel/net/rose/af_rose.c
@@ -487,6 +487,12 @@
 {
 	struct sock *sk = sock->sk;
 
+	lock_sock(sk);
+	if (sock->state != SS_UNCONNECTED) {
+		release_sock(sk);
+		return -EINVAL;
+	}
+
 	if (sk->sk_state != TCP_LISTEN) {
 		struct rose_sock *rose = rose_sk(sk);
 
@@ -496,8 +502,10 @@
 		memset(rose->dest_digis, 0, AX25_ADDR_LEN * ROSE_MAX_DIGIS);
 		sk->sk_max_ack_backlog = backlog;
 		sk->sk_state           = TCP_LISTEN;
+		release_sock(sk);
 		return 0;
 	}
+	release_sock(sk);
 
 	return -EOPNOTSUPP;
 }
diff --git a/kernel/net/rxrpc/output.c b/kernel/net/rxrpc/output.c
index 9683617..08c117b 100644
--- a/kernel/net/rxrpc/output.c
+++ b/kernel/net/rxrpc/output.c
@@ -93,7 +93,7 @@
 	*_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);
diff --git a/kernel/net/rxrpc/sendmsg.c b/kernel/net/rxrpc/sendmsg.c
index eef3c14..1882fea 100644
--- a/kernel/net/rxrpc/sendmsg.c
+++ b/kernel/net/rxrpc/sendmsg.c
@@ -733,7 +733,7 @@
 			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;
 		}
 	}
@@ -753,7 +753,7 @@
 		fallthrough;
 	case 1:
 		if (p.call.timeouts.hard > 0) {
-			j = msecs_to_jiffies(p.call.timeouts.hard);
+			j = p.call.timeouts.hard * HZ;
 			now = jiffies;
 			j += now;
 			WRITE_ONCE(call->expect_term_by, j);
diff --git a/kernel/net/sched/Kconfig b/kernel/net/sched/Kconfig
index bc4e5da..2046c16 100644
--- a/kernel/net/sched/Kconfig
+++ b/kernel/net/sched/Kconfig
@@ -503,17 +503,6 @@
 	  To compile this code as a module, choose M here: the
 	  module will be called cls_basic.
 
-config NET_CLS_TCINDEX
-	tristate "Traffic-Control Index (TCINDEX)"
-	select NET_CLS
-	help
-	  Say Y here if you want to be able to classify packets based on
-	  traffic control indices. You will want this feature if you want
-	  to implement Differentiated Services together with DSMARK.
-
-	  To compile this code as a module, choose M here: the
-	  module will be called cls_tcindex.
-
 config NET_CLS_ROUTE4
 	tristate "Routing decision (ROUTE)"
 	depends on INET
@@ -558,34 +547,6 @@
 	depends on NET_CLS_U32
 	help
 	  Say Y here to be able to use netfilter marks as u32 key.
-
-config NET_CLS_RSVP
-	tristate "IPv4 Resource Reservation Protocol (RSVP)"
-	select NET_CLS
-	help
-	  The Resource Reservation Protocol (RSVP) permits end systems to
-	  request a minimum and maximum data flow rate for a connection; this
-	  is important for real time data such as streaming sound or video.
-
-	  Say Y here if you want to be able to classify outgoing packets based
-	  on their RSVP requests.
-
-	  To compile this code as a module, choose M here: the
-	  module will be called cls_rsvp.
-
-config NET_CLS_RSVP6
-	tristate "IPv6 Resource Reservation Protocol (RSVP6)"
-	select NET_CLS
-	help
-	  The Resource Reservation Protocol (RSVP) permits end systems to
-	  request a minimum and maximum data flow rate for a connection; this
-	  is important for real time data such as streaming sound or video.
-
-	  Say Y here if you want to be able to classify outgoing packets based
-	  on their RSVP requests and you are using the IPv6 protocol.
-
-	  To compile this code as a module, choose M here: the
-	  module will be called cls_rsvp6.
 
 config NET_CLS_FLOW
 	tristate "Flow classifier"
diff --git a/kernel/net/sched/Makefile b/kernel/net/sched/Makefile
index 66bbf9a..df2bcd7 100644
--- a/kernel/net/sched/Makefile
+++ b/kernel/net/sched/Makefile
@@ -68,9 +68,6 @@
 obj-$(CONFIG_NET_CLS_U32)	+= cls_u32.o
 obj-$(CONFIG_NET_CLS_ROUTE4)	+= cls_route.o
 obj-$(CONFIG_NET_CLS_FW)	+= cls_fw.o
-obj-$(CONFIG_NET_CLS_RSVP)	+= cls_rsvp.o
-obj-$(CONFIG_NET_CLS_TCINDEX)	+= cls_tcindex.o
-obj-$(CONFIG_NET_CLS_RSVP6)	+= cls_rsvp6.o
 obj-$(CONFIG_NET_CLS_BASIC)	+= cls_basic.o
 obj-$(CONFIG_NET_CLS_FLOW)	+= cls_flow.o
 obj-$(CONFIG_NET_CLS_CGROUP)	+= cls_cgroup.o
diff --git a/kernel/net/sched/act_bpf.c b/kernel/net/sched/act_bpf.c
index a4c7ba3..78f1cd7 100644
--- a/kernel/net/sched/act_bpf.c
+++ b/kernel/net/sched/act_bpf.c
@@ -307,7 +307,7 @@
 	ret = tcf_idr_check_alloc(tn, &index, act, bind);
 	if (!ret) {
 		ret = tcf_idr_create(tn, index, est, act,
-				     &act_bpf_ops, bind, true, 0);
+				     &act_bpf_ops, bind, true, flags);
 		if (ret < 0) {
 			tcf_idr_cleanup(tn, index);
 			return ret;
diff --git a/kernel/net/sched/act_connmark.c b/kernel/net/sched/act_connmark.c
index 31d268e..b6576a2 100644
--- a/kernel/net/sched/act_connmark.c
+++ b/kernel/net/sched/act_connmark.c
@@ -124,7 +124,7 @@
 	ret = tcf_idr_check_alloc(tn, &index, a, bind);
 	if (!ret) {
 		ret = tcf_idr_create(tn, index, est, a,
-				     &act_connmark_ops, bind, false, 0);
+				     &act_connmark_ops, bind, false, flags);
 		if (ret) {
 			tcf_idr_cleanup(tn, index);
 			return ret;
diff --git a/kernel/net/sched/act_ctinfo.c b/kernel/net/sched/act_ctinfo.c
index 06c74f2..5aa0058 100644
--- a/kernel/net/sched/act_ctinfo.c
+++ b/kernel/net/sched/act_ctinfo.c
@@ -92,7 +92,7 @@
 	cp = rcu_dereference_bh(ca->params);
 
 	tcf_lastuse_update(&ca->tcf_tm);
-	bstats_update(&ca->tcf_bstats, skb);
+	tcf_action_update_bstats(&ca->common, skb);
 	action = READ_ONCE(ca->tcf_action);
 
 	wlen = skb_network_offset(skb);
@@ -211,8 +211,8 @@
 	index = actparm->index;
 	err = tcf_idr_check_alloc(tn, &index, a, bind);
 	if (!err) {
-		ret = tcf_idr_create(tn, index, est, a,
-				     &act_ctinfo_ops, bind, false, 0);
+		ret = tcf_idr_create_from_flags(tn, index, est, a,
+						&act_ctinfo_ops, bind, flags);
 		if (ret) {
 			tcf_idr_cleanup(tn, index);
 			return ret;
diff --git a/kernel/net/sched/act_gate.c b/kernel/net/sched/act_gate.c
index a78cb79..0e7568a 100644
--- a/kernel/net/sched/act_gate.c
+++ b/kernel/net/sched/act_gate.c
@@ -357,7 +357,7 @@
 
 	if (!err) {
 		ret = tcf_idr_create(tn, index, est, a,
-				     &act_gate_ops, bind, false, 0);
+				     &act_gate_ops, bind, false, flags);
 		if (ret) {
 			tcf_idr_cleanup(tn, index);
 			return ret;
diff --git a/kernel/net/sched/act_ife.c b/kernel/net/sched/act_ife.c
index a2ddea0..99548b2 100644
--- a/kernel/net/sched/act_ife.c
+++ b/kernel/net/sched/act_ife.c
@@ -553,7 +553,7 @@
 
 	if (!exists) {
 		ret = tcf_idr_create(tn, index, est, a, &act_ife_ops,
-				     bind, true, 0);
+				     bind, true, flags);
 		if (ret) {
 			tcf_idr_cleanup(tn, index);
 			kfree(p);
diff --git a/kernel/net/sched/act_ipt.c b/kernel/net/sched/act_ipt.c
index 8dc3bec..080f295 100644
--- a/kernel/net/sched/act_ipt.c
+++ b/kernel/net/sched/act_ipt.c
@@ -144,7 +144,7 @@
 
 	if (!exists) {
 		ret = tcf_idr_create(tn, index, est, a, ops, bind,
-				     false, 0);
+				     false, flags);
 		if (ret) {
 			tcf_idr_cleanup(tn, index);
 			return ret;
diff --git a/kernel/net/sched/act_mirred.c b/kernel/net/sched/act_mirred.c
index 24d561d..91a1946 100644
--- a/kernel/net/sched/act_mirred.c
+++ b/kernel/net/sched/act_mirred.c
@@ -28,8 +28,8 @@
 static LIST_HEAD(mirred_list);
 static DEFINE_SPINLOCK(mirred_list_lock);
 
-#define MIRRED_RECURSION_LIMIT    4
-static DEFINE_PER_CPU(unsigned int, mirred_rec_level);
+#define MIRRED_NEST_LIMIT    4
+static DEFINE_PER_CPU(unsigned int, mirred_nest_level);
 
 static bool tcf_mirred_is_act_redirect(int action)
 {
@@ -206,6 +206,25 @@
 	return err;
 }
 
+static bool is_mirred_nested(void)
+{
+	return unlikely(__this_cpu_read(mirred_nest_level) > 1);
+}
+
+static int tcf_mirred_forward(bool want_ingress, struct sk_buff *skb)
+{
+	int err;
+
+	if (!want_ingress)
+		err = dev_queue_xmit(skb);
+	else if (is_mirred_nested())
+		err = netif_rx(skb);
+	else
+		err = netif_receive_skb(skb);
+
+	return err;
+}
+
 static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a,
 			  struct tcf_result *res)
 {
@@ -213,7 +232,7 @@
 	struct sk_buff *skb2 = skb;
 	bool m_mac_header_xmit;
 	struct net_device *dev;
-	unsigned int rec_level;
+	unsigned int nest_level;
 	int retval, err = 0;
 	bool use_reinsert;
 	bool want_ingress;
@@ -224,11 +243,11 @@
 	int mac_len;
 	bool at_nh;
 
-	rec_level = __this_cpu_inc_return(mirred_rec_level);
-	if (unlikely(rec_level > MIRRED_RECURSION_LIMIT)) {
+	nest_level = __this_cpu_inc_return(mirred_nest_level);
+	if (unlikely(nest_level > MIRRED_NEST_LIMIT)) {
 		net_warn_ratelimited("Packet exceeded mirred recursion limit on dev %s\n",
 				     netdev_name(skb->dev));
-		__this_cpu_dec(mirred_rec_level);
+		__this_cpu_dec(mirred_nest_level);
 		return TC_ACT_SHOT;
 	}
 
@@ -244,7 +263,7 @@
 		goto out;
 	}
 
-	if (unlikely(!(dev->flags & IFF_UP))) {
+	if (unlikely(!(dev->flags & IFF_UP)) || !netif_carrier_ok(dev)) {
 		net_notice_ratelimited("tc mirred to Houston: device %s is down\n",
 				       dev->name);
 		goto out;
@@ -295,25 +314,22 @@
 		/* let's the caller reinsert the packet, if possible */
 		if (use_reinsert) {
 			res->ingress = want_ingress;
-			if (skb_tc_reinsert(skb, res))
+			err = tcf_mirred_forward(res->ingress, skb);
+			if (err)
 				tcf_action_inc_overlimit_qstats(&m->common);
-			__this_cpu_dec(mirred_rec_level);
+			__this_cpu_dec(mirred_nest_level);
 			return TC_ACT_CONSUMED;
 		}
 	}
 
-	if (!want_ingress)
-		err = dev_queue_xmit(skb2);
-	else
-		err = netif_receive_skb(skb2);
-
+	err = tcf_mirred_forward(want_ingress, skb2);
 	if (err) {
 out:
 		tcf_action_inc_overlimit_qstats(&m->common);
 		if (tcf_mirred_is_act_redirect(m_eaction))
 			retval = TC_ACT_SHOT;
 	}
-	__this_cpu_dec(mirred_rec_level);
+	__this_cpu_dec(mirred_nest_level);
 
 	return retval;
 }
diff --git a/kernel/net/sched/act_mpls.c b/kernel/net/sched/act_mpls.c
index d1486ea..47b963d 100644
--- a/kernel/net/sched/act_mpls.c
+++ b/kernel/net/sched/act_mpls.c
@@ -133,6 +133,11 @@
 {
 	const u32 *label = nla_data(attr);
 
+	if (nla_len(attr) != sizeof(*label)) {
+		NL_SET_ERR_MSG_MOD(extack, "Invalid MPLS label length");
+		return -EINVAL;
+	}
+
 	if (*label & ~MPLS_LABEL_MASK || *label == MPLS_LABEL_IMPLNULL) {
 		NL_SET_ERR_MSG_MOD(extack, "MPLS label out of range");
 		return -EINVAL;
@@ -144,7 +149,8 @@
 static const struct nla_policy mpls_policy[TCA_MPLS_MAX + 1] = {
 	[TCA_MPLS_PARMS]	= NLA_POLICY_EXACT_LEN(sizeof(struct tc_mpls)),
 	[TCA_MPLS_PROTO]	= { .type = NLA_U16 },
-	[TCA_MPLS_LABEL]	= NLA_POLICY_VALIDATE_FN(NLA_U32, valid_label),
+	[TCA_MPLS_LABEL]	= NLA_POLICY_VALIDATE_FN(NLA_BINARY,
+							 valid_label),
 	[TCA_MPLS_TC]		= NLA_POLICY_RANGE(NLA_U8, 0, 7),
 	[TCA_MPLS_TTL]		= NLA_POLICY_MIN(NLA_U8, 1),
 	[TCA_MPLS_BOS]		= NLA_POLICY_RANGE(NLA_U8, 0, 1),
@@ -248,7 +254,7 @@
 
 	if (!exists) {
 		ret = tcf_idr_create(tn, index, est, a,
-				     &act_mpls_ops, bind, true, 0);
+				     &act_mpls_ops, bind, true, flags);
 		if (ret) {
 			tcf_idr_cleanup(tn, index);
 			return ret;
diff --git a/kernel/net/sched/act_nat.c b/kernel/net/sched/act_nat.c
index 1ebd2a8..8466dc2 100644
--- a/kernel/net/sched/act_nat.c
+++ b/kernel/net/sched/act_nat.c
@@ -61,7 +61,7 @@
 	err = tcf_idr_check_alloc(tn, &index, a, bind);
 	if (!err) {
 		ret = tcf_idr_create(tn, index, est, a,
-				     &act_nat_ops, bind, false, 0);
+				     &act_nat_ops, bind, false, flags);
 		if (ret) {
 			tcf_idr_cleanup(tn, index);
 			return ret;
diff --git a/kernel/net/sched/act_pedit.c b/kernel/net/sched/act_pedit.c
index 0d5463d..a44101b 100644
--- a/kernel/net/sched/act_pedit.c
+++ b/kernel/net/sched/act_pedit.c
@@ -26,6 +26,7 @@
 
 static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = {
 	[TCA_PEDIT_PARMS]	= { .len = sizeof(struct tc_pedit) },
+	[TCA_PEDIT_PARMS_EX]	= { .len = sizeof(struct tc_pedit) },
 	[TCA_PEDIT_KEYS_EX]   = { .type = NLA_NESTED },
 };
 
@@ -189,7 +190,7 @@
 	err = tcf_idr_check_alloc(tn, &index, a, bind);
 	if (!err) {
 		ret = tcf_idr_create(tn, index, est, a,
-				     &act_pedit_ops, bind, false, 0);
+				     &act_pedit_ops, bind, false, flags);
 		if (ret) {
 			tcf_idr_cleanup(tn, index);
 			goto out_free;
diff --git a/kernel/net/sched/act_police.c b/kernel/net/sched/act_police.c
index 3807335..c30cd3e 100644
--- a/kernel/net/sched/act_police.c
+++ b/kernel/net/sched/act_police.c
@@ -87,7 +87,7 @@
 
 	if (!exists) {
 		ret = tcf_idr_create(tn, index, NULL, a,
-				     &act_police_ops, bind, true, 0);
+				     &act_police_ops, bind, true, flags);
 		if (ret) {
 			tcf_idr_cleanup(tn, index);
 			return ret;
diff --git a/kernel/net/sched/act_sample.c b/kernel/net/sched/act_sample.c
index 3ebf9ed..6988a9c 100644
--- a/kernel/net/sched/act_sample.c
+++ b/kernel/net/sched/act_sample.c
@@ -54,8 +54,8 @@
 					  sample_policy, NULL);
 	if (ret < 0)
 		return ret;
-	if (!tb[TCA_SAMPLE_PARMS] || !tb[TCA_SAMPLE_RATE] ||
-	    !tb[TCA_SAMPLE_PSAMPLE_GROUP])
+
+	if (!tb[TCA_SAMPLE_PARMS])
 		return -EINVAL;
 
 	parm = nla_data(tb[TCA_SAMPLE_PARMS]);
@@ -69,7 +69,7 @@
 
 	if (!exists) {
 		ret = tcf_idr_create(tn, index, est, a,
-				     &act_sample_ops, bind, true, 0);
+				     &act_sample_ops, bind, true, flags);
 		if (ret) {
 			tcf_idr_cleanup(tn, index);
 			return ret;
@@ -79,6 +79,13 @@
 		tcf_idr_release(*a, bind);
 		return -EEXIST;
 	}
+
+	if (!tb[TCA_SAMPLE_RATE] || !tb[TCA_SAMPLE_PSAMPLE_GROUP]) {
+		NL_SET_ERR_MSG(extack, "sample rate and group are required");
+		err = -EINVAL;
+		goto release_idr;
+	}
+
 	err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
 	if (err < 0)
 		goto release_idr;
diff --git a/kernel/net/sched/act_simple.c b/kernel/net/sched/act_simple.c
index a4f3d0f..b9bbc87 100644
--- a/kernel/net/sched/act_simple.c
+++ b/kernel/net/sched/act_simple.c
@@ -128,7 +128,7 @@
 
 	if (!exists) {
 		ret = tcf_idr_create(tn, index, est, a,
-				     &act_simp_ops, bind, false, 0);
+				     &act_simp_ops, bind, false, flags);
 		if (ret) {
 			tcf_idr_cleanup(tn, index);
 			return ret;
diff --git a/kernel/net/sched/act_skbedit.c b/kernel/net/sched/act_skbedit.c
index e5f3fb8..a5661f2 100644
--- a/kernel/net/sched/act_skbedit.c
+++ b/kernel/net/sched/act_skbedit.c
@@ -176,7 +176,7 @@
 
 	if (!exists) {
 		ret = tcf_idr_create(tn, index, est, a,
-				     &act_skbedit_ops, bind, true, 0);
+				     &act_skbedit_ops, bind, true, act_flags);
 		if (ret) {
 			tcf_idr_cleanup(tn, index);
 			return ret;
diff --git a/kernel/net/sched/act_skbmod.c b/kernel/net/sched/act_skbmod.c
index 8d17a54..aa98dca 100644
--- a/kernel/net/sched/act_skbmod.c
+++ b/kernel/net/sched/act_skbmod.c
@@ -147,7 +147,7 @@
 
 	if (!exists) {
 		ret = tcf_idr_create(tn, index, est, a,
-				     &act_skbmod_ops, bind, true, 0);
+				     &act_skbmod_ops, bind, true, flags);
 		if (ret) {
 			tcf_idr_cleanup(tn, index);
 			return ret;
diff --git a/kernel/net/sched/cls_api.c b/kernel/net/sched/cls_api.c
index c410a73..beedd0d 100644
--- a/kernel/net/sched/cls_api.c
+++ b/kernel/net/sched/cls_api.c
@@ -41,8 +41,6 @@
 #include <net/tc_act/tc_gate.h>
 #include <net/flow_offload.h>
 
-extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1];
-
 /* The list of all installed classifier types */
 static LIST_HEAD(tcf_proto_base);
 
@@ -535,8 +533,8 @@
 {
 	struct tcf_block *block = chain->block;
 	const struct tcf_proto_ops *tmplt_ops;
+	unsigned int refcnt, non_act_refcnt;
 	bool free_block = false;
-	unsigned int refcnt;
 	void *tmplt_priv;
 
 	mutex_lock(&block->lock);
@@ -556,13 +554,15 @@
 	 * save these to temporary variables.
 	 */
 	refcnt = --chain->refcnt;
+	non_act_refcnt = refcnt - chain->action_refcnt;
 	tmplt_ops = chain->tmplt_ops;
 	tmplt_priv = chain->tmplt_priv;
 
-	/* The last dropped non-action reference will trigger notification. */
-	if (refcnt - chain->action_refcnt == 0 && !by_act) {
-		tc_chain_notify_delete(tmplt_ops, tmplt_priv, chain->index,
-				       block, NULL, 0, 0, false);
+	if (non_act_refcnt == chain->explicitly_created && !by_act) {
+		if (non_act_refcnt == 0)
+			tc_chain_notify_delete(tmplt_ops, tmplt_priv,
+					       chain->index, block, NULL, 0, 0,
+					       false);
 		/* Last reference to chain, no need to lock. */
 		chain->flushing = false;
 	}
@@ -1466,6 +1466,7 @@
 
 err_unroll:
 	list_for_each_entry_safe(block_cb, next, &bo->cb_list, list) {
+		list_del(&block_cb->driver_list);
 		if (i-- > 0) {
 			list_del(&block_cb->list);
 			tcf_block_playback_offloads(block, block_cb->cb,
@@ -2773,6 +2774,7 @@
 		return PTR_ERR(ops);
 	if (!ops->tmplt_create || !ops->tmplt_destroy || !ops->tmplt_dump) {
 		NL_SET_ERR_MSG(extack, "Chain templates are not supported with specified classifier");
+		module_put(ops->owner);
 		return -EOPNOTSUPP;
 	}
 
diff --git a/kernel/net/sched/cls_flower.c b/kernel/net/sched/cls_flower.c
index 35ee6d8..dcf21d9 100644
--- a/kernel/net/sched/cls_flower.c
+++ b/kernel/net/sched/cls_flower.c
@@ -778,6 +778,16 @@
 		       TCA_FLOWER_KEY_PORT_SRC_MAX, &mask->tp_range.tp_max.src,
 		       TCA_FLOWER_UNSPEC, sizeof(key->tp_range.tp_max.src));
 
+	if (mask->tp_range.tp_min.dst != mask->tp_range.tp_max.dst) {
+		NL_SET_ERR_MSG(extack,
+			       "Both min and max destination ports must be specified");
+		return -EINVAL;
+	}
+	if (mask->tp_range.tp_min.src != mask->tp_range.tp_max.src) {
+		NL_SET_ERR_MSG(extack,
+			       "Both min and max source ports must be specified");
+		return -EINVAL;
+	}
 	if (mask->tp_range.tp_min.dst && mask->tp_range.tp_max.dst &&
 	    ntohs(key->tp_range.tp_max.dst) <=
 	    ntohs(key->tp_range.tp_min.dst)) {
@@ -1086,6 +1096,9 @@
 	if (option_len > sizeof(struct geneve_opt))
 		data_len = option_len - sizeof(struct geneve_opt);
 
+	if (key->enc_opts.len > FLOW_DIS_TUN_OPTS_MAX - 4)
+		return -ERANGE;
+
 	opt = (struct geneve_opt *)&key->enc_opts.data[key->enc_opts.len];
 	memset(opt, 0xff, option_len);
 	opt->length = data_len / 4;
diff --git a/kernel/net/sched/cls_fw.c b/kernel/net/sched/cls_fw.c
index ec94529..08c41f1 100644
--- a/kernel/net/sched/cls_fw.c
+++ b/kernel/net/sched/cls_fw.c
@@ -210,11 +210,6 @@
 	if (err < 0)
 		return err;
 
-	if (tb[TCA_FW_CLASSID]) {
-		f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]);
-		tcf_bind_filter(tp, &f->res, base);
-	}
-
 	if (tb[TCA_FW_INDEV]) {
 		int ret;
 		ret = tcf_change_indev(net, tb[TCA_FW_INDEV], extack);
@@ -230,6 +225,11 @@
 			return err;
 	} else if (head->mask != 0xFFFFFFFF)
 		return err;
+
+	if (tb[TCA_FW_CLASSID]) {
+		f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]);
+		tcf_bind_filter(tp, &f->res, base);
+	}
 
 	return 0;
 }
@@ -266,7 +266,6 @@
 			return -ENOBUFS;
 
 		fnew->id = f->id;
-		fnew->res = f->res;
 		fnew->ifindex = f->ifindex;
 		fnew->tp = f->tp;
 
diff --git a/kernel/net/sched/cls_route.c b/kernel/net/sched/cls_route.c
index b775e68..1ad4b3e 100644
--- a/kernel/net/sched/cls_route.c
+++ b/kernel/net/sched/cls_route.c
@@ -511,7 +511,6 @@
 	if (fold) {
 		f->id = fold->id;
 		f->iif = fold->iif;
-		f->res = fold->res;
 		f->handle = fold->handle;
 
 		f->tp = fold->tp;
diff --git a/kernel/net/sched/cls_rsvp.c b/kernel/net/sched/cls_rsvp.c
deleted file mode 100644
index de1c1d4..0000000
--- a/kernel/net/sched/cls_rsvp.c
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * net/sched/cls_rsvp.c	Special RSVP packet classifier for IPv4.
- *
- * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/skbuff.h>
-#include <net/ip.h>
-#include <net/netlink.h>
-#include <net/act_api.h>
-#include <net/pkt_cls.h>
-
-#define RSVP_DST_LEN	1
-#define RSVP_ID		"rsvp"
-#define RSVP_OPS	cls_rsvp_ops
-
-#include "cls_rsvp.h"
-MODULE_LICENSE("GPL");
diff --git a/kernel/net/sched/cls_rsvp.h b/kernel/net/sched/cls_rsvp.h
deleted file mode 100644
index d36949d..0000000
--- a/kernel/net/sched/cls_rsvp.h
+++ /dev/null
@@ -1,777 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * net/sched/cls_rsvp.h	Template file for RSVPv[46] classifiers.
- *
- * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
- */
-
-/*
-   Comparing to general packet classification problem,
-   RSVP needs only sevaral relatively simple rules:
-
-   * (dst, protocol) are always specified,
-     so that we are able to hash them.
-   * src may be exact, or may be wildcard, so that
-     we can keep a hash table plus one wildcard entry.
-   * source port (or flow label) is important only if src is given.
-
-   IMPLEMENTATION.
-
-   We use a two level hash table: The top level is keyed by
-   destination address and protocol ID, every bucket contains a list
-   of "rsvp sessions", identified by destination address, protocol and
-   DPI(="Destination Port ID"): triple (key, mask, offset).
-
-   Every bucket has a smaller hash table keyed by source address
-   (cf. RSVP flowspec) and one wildcard entry for wildcard reservations.
-   Every bucket is again a list of "RSVP flows", selected by
-   source address and SPI(="Source Port ID" here rather than
-   "security parameter index"): triple (key, mask, offset).
-
-
-   NOTE 1. All the packets with IPv6 extension headers (but AH and ESP)
-   and all fragmented packets go to the best-effort traffic class.
-
-
-   NOTE 2. Two "port id"'s seems to be redundant, rfc2207 requires
-   only one "Generalized Port Identifier". So that for classic
-   ah, esp (and udp,tcp) both *pi should coincide or one of them
-   should be wildcard.
-
-   At first sight, this redundancy is just a waste of CPU
-   resources. But DPI and SPI add the possibility to assign different
-   priorities to GPIs. Look also at note 4 about tunnels below.
-
-
-   NOTE 3. One complication is the case of tunneled packets.
-   We implement it as following: if the first lookup
-   matches a special session with "tunnelhdr" value not zero,
-   flowid doesn't contain the true flow ID, but the tunnel ID (1...255).
-   In this case, we pull tunnelhdr bytes and restart lookup
-   with tunnel ID added to the list of keys. Simple and stupid 8)8)
-   It's enough for PIMREG and IPIP.
-
-
-   NOTE 4. Two GPIs make it possible to parse even GRE packets.
-   F.e. DPI can select ETH_P_IP (and necessary flags to make
-   tunnelhdr correct) in GRE protocol field and SPI matches
-   GRE key. Is it not nice? 8)8)
-
-
-   Well, as result, despite its simplicity, we get a pretty
-   powerful classification engine.  */
-
-
-struct rsvp_head {
-	u32			tmap[256/32];
-	u32			hgenerator;
-	u8			tgenerator;
-	struct rsvp_session __rcu *ht[256];
-	struct rcu_head		rcu;
-};
-
-struct rsvp_session {
-	struct rsvp_session __rcu	*next;
-	__be32				dst[RSVP_DST_LEN];
-	struct tc_rsvp_gpi		dpi;
-	u8				protocol;
-	u8				tunnelid;
-	/* 16 (src,sport) hash slots, and one wildcard source slot */
-	struct rsvp_filter __rcu	*ht[16 + 1];
-	struct rcu_head			rcu;
-};
-
-
-struct rsvp_filter {
-	struct rsvp_filter __rcu	*next;
-	__be32				src[RSVP_DST_LEN];
-	struct tc_rsvp_gpi		spi;
-	u8				tunnelhdr;
-
-	struct tcf_result		res;
-	struct tcf_exts			exts;
-
-	u32				handle;
-	struct rsvp_session		*sess;
-	struct rcu_work			rwork;
-};
-
-static inline unsigned int hash_dst(__be32 *dst, u8 protocol, u8 tunnelid)
-{
-	unsigned int h = (__force __u32)dst[RSVP_DST_LEN - 1];
-
-	h ^= h>>16;
-	h ^= h>>8;
-	return (h ^ protocol ^ tunnelid) & 0xFF;
-}
-
-static inline unsigned int hash_src(__be32 *src)
-{
-	unsigned int h = (__force __u32)src[RSVP_DST_LEN-1];
-
-	h ^= h>>16;
-	h ^= h>>8;
-	h ^= h>>4;
-	return h & 0xF;
-}
-
-#define RSVP_APPLY_RESULT()				\
-{							\
-	int r = tcf_exts_exec(skb, &f->exts, res);	\
-	if (r < 0)					\
-		continue;				\
-	else if (r > 0)					\
-		return r;				\
-}
-
-static int rsvp_classify(struct sk_buff *skb, const struct tcf_proto *tp,
-			 struct tcf_result *res)
-{
-	struct rsvp_head *head = rcu_dereference_bh(tp->root);
-	struct rsvp_session *s;
-	struct rsvp_filter *f;
-	unsigned int h1, h2;
-	__be32 *dst, *src;
-	u8 protocol;
-	u8 tunnelid = 0;
-	u8 *xprt;
-#if RSVP_DST_LEN == 4
-	struct ipv6hdr *nhptr;
-
-	if (!pskb_network_may_pull(skb, sizeof(*nhptr)))
-		return -1;
-	nhptr = ipv6_hdr(skb);
-#else
-	struct iphdr *nhptr;
-
-	if (!pskb_network_may_pull(skb, sizeof(*nhptr)))
-		return -1;
-	nhptr = ip_hdr(skb);
-#endif
-restart:
-
-#if RSVP_DST_LEN == 4
-	src = &nhptr->saddr.s6_addr32[0];
-	dst = &nhptr->daddr.s6_addr32[0];
-	protocol = nhptr->nexthdr;
-	xprt = ((u8 *)nhptr) + sizeof(struct ipv6hdr);
-#else
-	src = &nhptr->saddr;
-	dst = &nhptr->daddr;
-	protocol = nhptr->protocol;
-	xprt = ((u8 *)nhptr) + (nhptr->ihl<<2);
-	if (ip_is_fragment(nhptr))
-		return -1;
-#endif
-
-	h1 = hash_dst(dst, protocol, tunnelid);
-	h2 = hash_src(src);
-
-	for (s = rcu_dereference_bh(head->ht[h1]); s;
-	     s = rcu_dereference_bh(s->next)) {
-		if (dst[RSVP_DST_LEN-1] == s->dst[RSVP_DST_LEN - 1] &&
-		    protocol == s->protocol &&
-		    !(s->dpi.mask &
-		      (*(u32 *)(xprt + s->dpi.offset) ^ s->dpi.key)) &&
-#if RSVP_DST_LEN == 4
-		    dst[0] == s->dst[0] &&
-		    dst[1] == s->dst[1] &&
-		    dst[2] == s->dst[2] &&
-#endif
-		    tunnelid == s->tunnelid) {
-
-			for (f = rcu_dereference_bh(s->ht[h2]); f;
-			     f = rcu_dereference_bh(f->next)) {
-				if (src[RSVP_DST_LEN-1] == f->src[RSVP_DST_LEN - 1] &&
-				    !(f->spi.mask & (*(u32 *)(xprt + f->spi.offset) ^ f->spi.key))
-#if RSVP_DST_LEN == 4
-				    &&
-				    src[0] == f->src[0] &&
-				    src[1] == f->src[1] &&
-				    src[2] == f->src[2]
-#endif
-				    ) {
-					*res = f->res;
-					RSVP_APPLY_RESULT();
-
-matched:
-					if (f->tunnelhdr == 0)
-						return 0;
-
-					tunnelid = f->res.classid;
-					nhptr = (void *)(xprt + f->tunnelhdr - sizeof(*nhptr));
-					goto restart;
-				}
-			}
-
-			/* And wildcard bucket... */
-			for (f = rcu_dereference_bh(s->ht[16]); f;
-			     f = rcu_dereference_bh(f->next)) {
-				*res = f->res;
-				RSVP_APPLY_RESULT();
-				goto matched;
-			}
-			return -1;
-		}
-	}
-	return -1;
-}
-
-static void rsvp_replace(struct tcf_proto *tp, struct rsvp_filter *n, u32 h)
-{
-	struct rsvp_head *head = rtnl_dereference(tp->root);
-	struct rsvp_session *s;
-	struct rsvp_filter __rcu **ins;
-	struct rsvp_filter *pins;
-	unsigned int h1 = h & 0xFF;
-	unsigned int h2 = (h >> 8) & 0xFF;
-
-	for (s = rtnl_dereference(head->ht[h1]); s;
-	     s = rtnl_dereference(s->next)) {
-		for (ins = &s->ht[h2], pins = rtnl_dereference(*ins); ;
-		     ins = &pins->next, pins = rtnl_dereference(*ins)) {
-			if (pins->handle == h) {
-				RCU_INIT_POINTER(n->next, pins->next);
-				rcu_assign_pointer(*ins, n);
-				return;
-			}
-		}
-	}
-
-	/* Something went wrong if we are trying to replace a non-existant
-	 * node. Mind as well halt instead of silently failing.
-	 */
-	BUG_ON(1);
-}
-
-static void *rsvp_get(struct tcf_proto *tp, u32 handle)
-{
-	struct rsvp_head *head = rtnl_dereference(tp->root);
-	struct rsvp_session *s;
-	struct rsvp_filter *f;
-	unsigned int h1 = handle & 0xFF;
-	unsigned int h2 = (handle >> 8) & 0xFF;
-
-	if (h2 > 16)
-		return NULL;
-
-	for (s = rtnl_dereference(head->ht[h1]); s;
-	     s = rtnl_dereference(s->next)) {
-		for (f = rtnl_dereference(s->ht[h2]); f;
-		     f = rtnl_dereference(f->next)) {
-			if (f->handle == handle)
-				return f;
-		}
-	}
-	return NULL;
-}
-
-static int rsvp_init(struct tcf_proto *tp)
-{
-	struct rsvp_head *data;
-
-	data = kzalloc(sizeof(struct rsvp_head), GFP_KERNEL);
-	if (data) {
-		rcu_assign_pointer(tp->root, data);
-		return 0;
-	}
-	return -ENOBUFS;
-}
-
-static void __rsvp_delete_filter(struct rsvp_filter *f)
-{
-	tcf_exts_destroy(&f->exts);
-	tcf_exts_put_net(&f->exts);
-	kfree(f);
-}
-
-static void rsvp_delete_filter_work(struct work_struct *work)
-{
-	struct rsvp_filter *f = container_of(to_rcu_work(work),
-					     struct rsvp_filter,
-					     rwork);
-	rtnl_lock();
-	__rsvp_delete_filter(f);
-	rtnl_unlock();
-}
-
-static void rsvp_delete_filter(struct tcf_proto *tp, struct rsvp_filter *f)
-{
-	tcf_unbind_filter(tp, &f->res);
-	/* all classifiers are required to call tcf_exts_destroy() after rcu
-	 * grace period, since converted-to-rcu actions are relying on that
-	 * in cleanup() callback
-	 */
-	if (tcf_exts_get_net(&f->exts))
-		tcf_queue_work(&f->rwork, rsvp_delete_filter_work);
-	else
-		__rsvp_delete_filter(f);
-}
-
-static void rsvp_destroy(struct tcf_proto *tp, bool rtnl_held,
-			 struct netlink_ext_ack *extack)
-{
-	struct rsvp_head *data = rtnl_dereference(tp->root);
-	int h1, h2;
-
-	if (data == NULL)
-		return;
-
-	for (h1 = 0; h1 < 256; h1++) {
-		struct rsvp_session *s;
-
-		while ((s = rtnl_dereference(data->ht[h1])) != NULL) {
-			RCU_INIT_POINTER(data->ht[h1], s->next);
-
-			for (h2 = 0; h2 <= 16; h2++) {
-				struct rsvp_filter *f;
-
-				while ((f = rtnl_dereference(s->ht[h2])) != NULL) {
-					rcu_assign_pointer(s->ht[h2], f->next);
-					rsvp_delete_filter(tp, f);
-				}
-			}
-			kfree_rcu(s, rcu);
-		}
-	}
-	kfree_rcu(data, rcu);
-}
-
-static int rsvp_delete(struct tcf_proto *tp, void *arg, bool *last,
-		       bool rtnl_held, struct netlink_ext_ack *extack)
-{
-	struct rsvp_head *head = rtnl_dereference(tp->root);
-	struct rsvp_filter *nfp, *f = arg;
-	struct rsvp_filter __rcu **fp;
-	unsigned int h = f->handle;
-	struct rsvp_session __rcu **sp;
-	struct rsvp_session *nsp, *s = f->sess;
-	int i, h1;
-
-	fp = &s->ht[(h >> 8) & 0xFF];
-	for (nfp = rtnl_dereference(*fp); nfp;
-	     fp = &nfp->next, nfp = rtnl_dereference(*fp)) {
-		if (nfp == f) {
-			RCU_INIT_POINTER(*fp, f->next);
-			rsvp_delete_filter(tp, f);
-
-			/* Strip tree */
-
-			for (i = 0; i <= 16; i++)
-				if (s->ht[i])
-					goto out;
-
-			/* OK, session has no flows */
-			sp = &head->ht[h & 0xFF];
-			for (nsp = rtnl_dereference(*sp); nsp;
-			     sp = &nsp->next, nsp = rtnl_dereference(*sp)) {
-				if (nsp == s) {
-					RCU_INIT_POINTER(*sp, s->next);
-					kfree_rcu(s, rcu);
-					goto out;
-				}
-			}
-
-			break;
-		}
-	}
-
-out:
-	*last = true;
-	for (h1 = 0; h1 < 256; h1++) {
-		if (rcu_access_pointer(head->ht[h1])) {
-			*last = false;
-			break;
-		}
-	}
-
-	return 0;
-}
-
-static unsigned int gen_handle(struct tcf_proto *tp, unsigned salt)
-{
-	struct rsvp_head *data = rtnl_dereference(tp->root);
-	int i = 0xFFFF;
-
-	while (i-- > 0) {
-		u32 h;
-
-		if ((data->hgenerator += 0x10000) == 0)
-			data->hgenerator = 0x10000;
-		h = data->hgenerator|salt;
-		if (!rsvp_get(tp, h))
-			return h;
-	}
-	return 0;
-}
-
-static int tunnel_bts(struct rsvp_head *data)
-{
-	int n = data->tgenerator >> 5;
-	u32 b = 1 << (data->tgenerator & 0x1F);
-
-	if (data->tmap[n] & b)
-		return 0;
-	data->tmap[n] |= b;
-	return 1;
-}
-
-static void tunnel_recycle(struct rsvp_head *data)
-{
-	struct rsvp_session __rcu **sht = data->ht;
-	u32 tmap[256/32];
-	int h1, h2;
-
-	memset(tmap, 0, sizeof(tmap));
-
-	for (h1 = 0; h1 < 256; h1++) {
-		struct rsvp_session *s;
-		for (s = rtnl_dereference(sht[h1]); s;
-		     s = rtnl_dereference(s->next)) {
-			for (h2 = 0; h2 <= 16; h2++) {
-				struct rsvp_filter *f;
-
-				for (f = rtnl_dereference(s->ht[h2]); f;
-				     f = rtnl_dereference(f->next)) {
-					if (f->tunnelhdr == 0)
-						continue;
-					data->tgenerator = f->res.classid;
-					tunnel_bts(data);
-				}
-			}
-		}
-	}
-
-	memcpy(data->tmap, tmap, sizeof(tmap));
-}
-
-static u32 gen_tunnel(struct rsvp_head *data)
-{
-	int i, k;
-
-	for (k = 0; k < 2; k++) {
-		for (i = 255; i > 0; i--) {
-			if (++data->tgenerator == 0)
-				data->tgenerator = 1;
-			if (tunnel_bts(data))
-				return data->tgenerator;
-		}
-		tunnel_recycle(data);
-	}
-	return 0;
-}
-
-static const struct nla_policy rsvp_policy[TCA_RSVP_MAX + 1] = {
-	[TCA_RSVP_CLASSID]	= { .type = NLA_U32 },
-	[TCA_RSVP_DST]		= { .len = RSVP_DST_LEN * sizeof(u32) },
-	[TCA_RSVP_SRC]		= { .len = RSVP_DST_LEN * sizeof(u32) },
-	[TCA_RSVP_PINFO]	= { .len = sizeof(struct tc_rsvp_pinfo) },
-};
-
-static int rsvp_change(struct net *net, struct sk_buff *in_skb,
-		       struct tcf_proto *tp, unsigned long base,
-		       u32 handle,
-		       struct nlattr **tca,
-		       void **arg, bool ovr, bool rtnl_held,
-		       struct netlink_ext_ack *extack)
-{
-	struct rsvp_head *data = rtnl_dereference(tp->root);
-	struct rsvp_filter *f, *nfp;
-	struct rsvp_filter __rcu **fp;
-	struct rsvp_session *nsp, *s;
-	struct rsvp_session __rcu **sp;
-	struct tc_rsvp_pinfo *pinfo = NULL;
-	struct nlattr *opt = tca[TCA_OPTIONS];
-	struct nlattr *tb[TCA_RSVP_MAX + 1];
-	struct tcf_exts e;
-	unsigned int h1, h2;
-	__be32 *dst;
-	int err;
-
-	if (opt == NULL)
-		return handle ? -EINVAL : 0;
-
-	err = nla_parse_nested_deprecated(tb, TCA_RSVP_MAX, opt, rsvp_policy,
-					  NULL);
-	if (err < 0)
-		return err;
-
-	err = tcf_exts_init(&e, net, TCA_RSVP_ACT, TCA_RSVP_POLICE);
-	if (err < 0)
-		return err;
-	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr, true,
-				extack);
-	if (err < 0)
-		goto errout2;
-
-	f = *arg;
-	if (f) {
-		/* Node exists: adjust only classid */
-		struct rsvp_filter *n;
-
-		if (f->handle != handle && handle)
-			goto errout2;
-
-		n = kmemdup(f, sizeof(*f), GFP_KERNEL);
-		if (!n) {
-			err = -ENOMEM;
-			goto errout2;
-		}
-
-		err = tcf_exts_init(&n->exts, net, TCA_RSVP_ACT,
-				    TCA_RSVP_POLICE);
-		if (err < 0) {
-			kfree(n);
-			goto errout2;
-		}
-
-		if (tb[TCA_RSVP_CLASSID]) {
-			n->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID]);
-			tcf_bind_filter(tp, &n->res, base);
-		}
-
-		tcf_exts_change(&n->exts, &e);
-		rsvp_replace(tp, n, handle);
-		return 0;
-	}
-
-	/* Now more serious part... */
-	err = -EINVAL;
-	if (handle)
-		goto errout2;
-	if (tb[TCA_RSVP_DST] == NULL)
-		goto errout2;
-
-	err = -ENOBUFS;
-	f = kzalloc(sizeof(struct rsvp_filter), GFP_KERNEL);
-	if (f == NULL)
-		goto errout2;
-
-	err = tcf_exts_init(&f->exts, net, TCA_RSVP_ACT, TCA_RSVP_POLICE);
-	if (err < 0)
-		goto errout;
-	h2 = 16;
-	if (tb[TCA_RSVP_SRC]) {
-		memcpy(f->src, nla_data(tb[TCA_RSVP_SRC]), sizeof(f->src));
-		h2 = hash_src(f->src);
-	}
-	if (tb[TCA_RSVP_PINFO]) {
-		pinfo = nla_data(tb[TCA_RSVP_PINFO]);
-		f->spi = pinfo->spi;
-		f->tunnelhdr = pinfo->tunnelhdr;
-	}
-	if (tb[TCA_RSVP_CLASSID])
-		f->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID]);
-
-	dst = nla_data(tb[TCA_RSVP_DST]);
-	h1 = hash_dst(dst, pinfo ? pinfo->protocol : 0, pinfo ? pinfo->tunnelid : 0);
-
-	err = -ENOMEM;
-	if ((f->handle = gen_handle(tp, h1 | (h2<<8))) == 0)
-		goto errout;
-
-	if (f->tunnelhdr) {
-		err = -EINVAL;
-		if (f->res.classid > 255)
-			goto errout;
-
-		err = -ENOMEM;
-		if (f->res.classid == 0 &&
-		    (f->res.classid = gen_tunnel(data)) == 0)
-			goto errout;
-	}
-
-	for (sp = &data->ht[h1];
-	     (s = rtnl_dereference(*sp)) != NULL;
-	     sp = &s->next) {
-		if (dst[RSVP_DST_LEN-1] == s->dst[RSVP_DST_LEN-1] &&
-		    pinfo && pinfo->protocol == s->protocol &&
-		    memcmp(&pinfo->dpi, &s->dpi, sizeof(s->dpi)) == 0 &&
-#if RSVP_DST_LEN == 4
-		    dst[0] == s->dst[0] &&
-		    dst[1] == s->dst[1] &&
-		    dst[2] == s->dst[2] &&
-#endif
-		    pinfo->tunnelid == s->tunnelid) {
-
-insert:
-			/* OK, we found appropriate session */
-
-			fp = &s->ht[h2];
-
-			f->sess = s;
-			if (f->tunnelhdr == 0)
-				tcf_bind_filter(tp, &f->res, base);
-
-			tcf_exts_change(&f->exts, &e);
-
-			fp = &s->ht[h2];
-			for (nfp = rtnl_dereference(*fp); nfp;
-			     fp = &nfp->next, nfp = rtnl_dereference(*fp)) {
-				__u32 mask = nfp->spi.mask & f->spi.mask;
-
-				if (mask != f->spi.mask)
-					break;
-			}
-			RCU_INIT_POINTER(f->next, nfp);
-			rcu_assign_pointer(*fp, f);
-
-			*arg = f;
-			return 0;
-		}
-	}
-
-	/* No session found. Create new one. */
-
-	err = -ENOBUFS;
-	s = kzalloc(sizeof(struct rsvp_session), GFP_KERNEL);
-	if (s == NULL)
-		goto errout;
-	memcpy(s->dst, dst, sizeof(s->dst));
-
-	if (pinfo) {
-		s->dpi = pinfo->dpi;
-		s->protocol = pinfo->protocol;
-		s->tunnelid = pinfo->tunnelid;
-	}
-	sp = &data->ht[h1];
-	for (nsp = rtnl_dereference(*sp); nsp;
-	     sp = &nsp->next, nsp = rtnl_dereference(*sp)) {
-		if ((nsp->dpi.mask & s->dpi.mask) != s->dpi.mask)
-			break;
-	}
-	RCU_INIT_POINTER(s->next, nsp);
-	rcu_assign_pointer(*sp, s);
-
-	goto insert;
-
-errout:
-	tcf_exts_destroy(&f->exts);
-	kfree(f);
-errout2:
-	tcf_exts_destroy(&e);
-	return err;
-}
-
-static void rsvp_walk(struct tcf_proto *tp, struct tcf_walker *arg,
-		      bool rtnl_held)
-{
-	struct rsvp_head *head = rtnl_dereference(tp->root);
-	unsigned int h, h1;
-
-	if (arg->stop)
-		return;
-
-	for (h = 0; h < 256; h++) {
-		struct rsvp_session *s;
-
-		for (s = rtnl_dereference(head->ht[h]); s;
-		     s = rtnl_dereference(s->next)) {
-			for (h1 = 0; h1 <= 16; h1++) {
-				struct rsvp_filter *f;
-
-				for (f = rtnl_dereference(s->ht[h1]); f;
-				     f = rtnl_dereference(f->next)) {
-					if (arg->count < arg->skip) {
-						arg->count++;
-						continue;
-					}
-					if (arg->fn(tp, f, arg) < 0) {
-						arg->stop = 1;
-						return;
-					}
-					arg->count++;
-				}
-			}
-		}
-	}
-}
-
-static int rsvp_dump(struct net *net, struct tcf_proto *tp, void *fh,
-		     struct sk_buff *skb, struct tcmsg *t, bool rtnl_held)
-{
-	struct rsvp_filter *f = fh;
-	struct rsvp_session *s;
-	struct nlattr *nest;
-	struct tc_rsvp_pinfo pinfo;
-
-	if (f == NULL)
-		return skb->len;
-	s = f->sess;
-
-	t->tcm_handle = f->handle;
-
-	nest = nla_nest_start_noflag(skb, TCA_OPTIONS);
-	if (nest == NULL)
-		goto nla_put_failure;
-
-	if (nla_put(skb, TCA_RSVP_DST, sizeof(s->dst), &s->dst))
-		goto nla_put_failure;
-	pinfo.dpi = s->dpi;
-	pinfo.spi = f->spi;
-	pinfo.protocol = s->protocol;
-	pinfo.tunnelid = s->tunnelid;
-	pinfo.tunnelhdr = f->tunnelhdr;
-	pinfo.pad = 0;
-	if (nla_put(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo))
-		goto nla_put_failure;
-	if (f->res.classid &&
-	    nla_put_u32(skb, TCA_RSVP_CLASSID, f->res.classid))
-		goto nla_put_failure;
-	if (((f->handle >> 8) & 0xFF) != 16 &&
-	    nla_put(skb, TCA_RSVP_SRC, sizeof(f->src), f->src))
-		goto nla_put_failure;
-
-	if (tcf_exts_dump(skb, &f->exts) < 0)
-		goto nla_put_failure;
-
-	nla_nest_end(skb, nest);
-
-	if (tcf_exts_dump_stats(skb, &f->exts) < 0)
-		goto nla_put_failure;
-	return skb->len;
-
-nla_put_failure:
-	nla_nest_cancel(skb, nest);
-	return -1;
-}
-
-static void rsvp_bind_class(void *fh, u32 classid, unsigned long cl, void *q,
-			    unsigned long base)
-{
-	struct rsvp_filter *f = fh;
-
-	if (f && f->res.classid == classid) {
-		if (cl)
-			__tcf_bind_filter(q, &f->res, base);
-		else
-			__tcf_unbind_filter(q, &f->res);
-	}
-}
-
-static struct tcf_proto_ops RSVP_OPS __read_mostly = {
-	.kind		=	RSVP_ID,
-	.classify	=	rsvp_classify,
-	.init		=	rsvp_init,
-	.destroy	=	rsvp_destroy,
-	.get		=	rsvp_get,
-	.change		=	rsvp_change,
-	.delete		=	rsvp_delete,
-	.walk		=	rsvp_walk,
-	.dump		=	rsvp_dump,
-	.bind_class	=	rsvp_bind_class,
-	.owner		=	THIS_MODULE,
-};
-
-static int __init init_rsvp(void)
-{
-	return register_tcf_proto_ops(&RSVP_OPS);
-}
-
-static void __exit exit_rsvp(void)
-{
-	unregister_tcf_proto_ops(&RSVP_OPS);
-}
-
-module_init(init_rsvp)
-module_exit(exit_rsvp)
diff --git a/kernel/net/sched/cls_rsvp6.c b/kernel/net/sched/cls_rsvp6.c
deleted file mode 100644
index 6407884..0000000
--- a/kernel/net/sched/cls_rsvp6.c
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * net/sched/cls_rsvp6.c	Special RSVP packet classifier for IPv6.
- *
- * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ipv6.h>
-#include <linux/skbuff.h>
-#include <net/act_api.h>
-#include <net/pkt_cls.h>
-#include <net/netlink.h>
-
-#define RSVP_DST_LEN	4
-#define RSVP_ID		"rsvp6"
-#define RSVP_OPS	cls_rsvp6_ops
-
-#include "cls_rsvp.h"
-MODULE_LICENSE("GPL");
diff --git a/kernel/net/sched/cls_tcindex.c b/kernel/net/sched/cls_tcindex.c
deleted file mode 100644
index e9a8a2c..0000000
--- a/kernel/net/sched/cls_tcindex.c
+++ /dev/null
@@ -1,738 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * net/sched/cls_tcindex.c	Packet classifier for skb->tc_index
- *
- * Written 1998,1999 by Werner Almesberger, EPFL ICA
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/refcount.h>
-#include <net/act_api.h>
-#include <net/netlink.h>
-#include <net/pkt_cls.h>
-#include <net/sch_generic.h>
-
-/*
- * Passing parameters to the root seems to be done more awkwardly than really
- * necessary. At least, u32 doesn't seem to use such dirty hacks. To be
- * verified. FIXME.
- */
-
-#define PERFECT_HASH_THRESHOLD	64	/* use perfect hash if not bigger */
-#define DEFAULT_HASH_SIZE	64	/* optimized for diffserv */
-
-
-struct tcindex_data;
-
-struct tcindex_filter_result {
-	struct tcf_exts		exts;
-	struct tcf_result	res;
-	struct tcindex_data	*p;
-	struct rcu_work		rwork;
-};
-
-struct tcindex_filter {
-	u16 key;
-	struct tcindex_filter_result result;
-	struct tcindex_filter __rcu *next;
-	struct rcu_work rwork;
-};
-
-
-struct tcindex_data {
-	struct tcindex_filter_result *perfect; /* perfect hash; NULL if none */
-	struct tcindex_filter __rcu **h; /* imperfect hash; */
-	struct tcf_proto *tp;
-	u16 mask;		/* AND key with mask */
-	u32 shift;		/* shift ANDed key to the right */
-	u32 hash;		/* hash table size; 0 if undefined */
-	u32 alloc_hash;		/* allocated size */
-	u32 fall_through;	/* 0: only classify if explicit match */
-	refcount_t refcnt;	/* a temporary refcnt for perfect hash */
-	struct rcu_work rwork;
-};
-
-static inline int tcindex_filter_is_set(struct tcindex_filter_result *r)
-{
-	return tcf_exts_has_actions(&r->exts) || r->res.classid;
-}
-
-static void tcindex_data_get(struct tcindex_data *p)
-{
-	refcount_inc(&p->refcnt);
-}
-
-static void tcindex_data_put(struct tcindex_data *p)
-{
-	if (refcount_dec_and_test(&p->refcnt)) {
-		kfree(p->perfect);
-		kfree(p->h);
-		kfree(p);
-	}
-}
-
-static struct tcindex_filter_result *tcindex_lookup(struct tcindex_data *p,
-						    u16 key)
-{
-	if (p->perfect) {
-		struct tcindex_filter_result *f = p->perfect + key;
-
-		return tcindex_filter_is_set(f) ? f : NULL;
-	} else if (p->h) {
-		struct tcindex_filter __rcu **fp;
-		struct tcindex_filter *f;
-
-		fp = &p->h[key % p->hash];
-		for (f = rcu_dereference_bh_rtnl(*fp);
-		     f;
-		     fp = &f->next, f = rcu_dereference_bh_rtnl(*fp))
-			if (f->key == key)
-				return &f->result;
-	}
-
-	return NULL;
-}
-
-
-static int tcindex_classify(struct sk_buff *skb, const struct tcf_proto *tp,
-			    struct tcf_result *res)
-{
-	struct tcindex_data *p = rcu_dereference_bh(tp->root);
-	struct tcindex_filter_result *f;
-	int key = (skb->tc_index & p->mask) >> p->shift;
-
-	pr_debug("tcindex_classify(skb %p,tp %p,res %p),p %p\n",
-		 skb, tp, res, p);
-
-	f = tcindex_lookup(p, key);
-	if (!f) {
-		struct Qdisc *q = tcf_block_q(tp->chain->block);
-
-		if (!p->fall_through)
-			return -1;
-		res->classid = TC_H_MAKE(TC_H_MAJ(q->handle), key);
-		res->class = 0;
-		pr_debug("alg 0x%x\n", res->classid);
-		return 0;
-	}
-	*res = f->res;
-	pr_debug("map 0x%x\n", res->classid);
-
-	return tcf_exts_exec(skb, &f->exts, res);
-}
-
-
-static void *tcindex_get(struct tcf_proto *tp, u32 handle)
-{
-	struct tcindex_data *p = rtnl_dereference(tp->root);
-	struct tcindex_filter_result *r;
-
-	pr_debug("tcindex_get(tp %p,handle 0x%08x)\n", tp, handle);
-	if (p->perfect && handle >= p->alloc_hash)
-		return NULL;
-	r = tcindex_lookup(p, handle);
-	return r && tcindex_filter_is_set(r) ? r : NULL;
-}
-
-static int tcindex_init(struct tcf_proto *tp)
-{
-	struct tcindex_data *p;
-
-	pr_debug("tcindex_init(tp %p)\n", tp);
-	p = kzalloc(sizeof(struct tcindex_data), GFP_KERNEL);
-	if (!p)
-		return -ENOMEM;
-
-	p->mask = 0xffff;
-	p->hash = DEFAULT_HASH_SIZE;
-	p->fall_through = 1;
-	refcount_set(&p->refcnt, 1); /* Paired with tcindex_destroy_work() */
-
-	rcu_assign_pointer(tp->root, p);
-	return 0;
-}
-
-static void __tcindex_destroy_rexts(struct tcindex_filter_result *r)
-{
-	tcf_exts_destroy(&r->exts);
-	tcf_exts_put_net(&r->exts);
-	tcindex_data_put(r->p);
-}
-
-static void tcindex_destroy_rexts_work(struct work_struct *work)
-{
-	struct tcindex_filter_result *r;
-
-	r = container_of(to_rcu_work(work),
-			 struct tcindex_filter_result,
-			 rwork);
-	rtnl_lock();
-	__tcindex_destroy_rexts(r);
-	rtnl_unlock();
-}
-
-static void __tcindex_destroy_fexts(struct tcindex_filter *f)
-{
-	tcf_exts_destroy(&f->result.exts);
-	tcf_exts_put_net(&f->result.exts);
-	kfree(f);
-}
-
-static void tcindex_destroy_fexts_work(struct work_struct *work)
-{
-	struct tcindex_filter *f = container_of(to_rcu_work(work),
-						struct tcindex_filter,
-						rwork);
-
-	rtnl_lock();
-	__tcindex_destroy_fexts(f);
-	rtnl_unlock();
-}
-
-static int tcindex_delete(struct tcf_proto *tp, void *arg, bool *last,
-			  bool rtnl_held, struct netlink_ext_ack *extack)
-{
-	struct tcindex_data *p = rtnl_dereference(tp->root);
-	struct tcindex_filter_result *r = arg;
-	struct tcindex_filter __rcu **walk;
-	struct tcindex_filter *f = NULL;
-
-	pr_debug("tcindex_delete(tp %p,arg %p),p %p\n", tp, arg, p);
-	if (p->perfect) {
-		if (!r->res.class)
-			return -ENOENT;
-	} else {
-		int i;
-
-		for (i = 0; i < p->hash; i++) {
-			walk = p->h + i;
-			for (f = rtnl_dereference(*walk); f;
-			     walk = &f->next, f = rtnl_dereference(*walk)) {
-				if (&f->result == r)
-					goto found;
-			}
-		}
-		return -ENOENT;
-
-found:
-		rcu_assign_pointer(*walk, rtnl_dereference(f->next));
-	}
-	tcf_unbind_filter(tp, &r->res);
-	/* all classifiers are required to call tcf_exts_destroy() after rcu
-	 * grace period, since converted-to-rcu actions are relying on that
-	 * in cleanup() callback
-	 */
-	if (f) {
-		if (tcf_exts_get_net(&f->result.exts))
-			tcf_queue_work(&f->rwork, tcindex_destroy_fexts_work);
-		else
-			__tcindex_destroy_fexts(f);
-	} else {
-		tcindex_data_get(p);
-
-		if (tcf_exts_get_net(&r->exts))
-			tcf_queue_work(&r->rwork, tcindex_destroy_rexts_work);
-		else
-			__tcindex_destroy_rexts(r);
-	}
-
-	*last = false;
-	return 0;
-}
-
-static void tcindex_destroy_work(struct work_struct *work)
-{
-	struct tcindex_data *p = container_of(to_rcu_work(work),
-					      struct tcindex_data,
-					      rwork);
-
-	tcindex_data_put(p);
-}
-
-static inline int
-valid_perfect_hash(struct tcindex_data *p)
-{
-	return  p->hash > (p->mask >> p->shift);
-}
-
-static const struct nla_policy tcindex_policy[TCA_TCINDEX_MAX + 1] = {
-	[TCA_TCINDEX_HASH]		= { .type = NLA_U32 },
-	[TCA_TCINDEX_MASK]		= { .type = NLA_U16 },
-	[TCA_TCINDEX_SHIFT]		= { .type = NLA_U32 },
-	[TCA_TCINDEX_FALL_THROUGH]	= { .type = NLA_U32 },
-	[TCA_TCINDEX_CLASSID]		= { .type = NLA_U32 },
-};
-
-static int tcindex_filter_result_init(struct tcindex_filter_result *r,
-				      struct tcindex_data *p,
-				      struct net *net)
-{
-	memset(r, 0, sizeof(*r));
-	r->p = p;
-	return tcf_exts_init(&r->exts, net, TCA_TCINDEX_ACT,
-			     TCA_TCINDEX_POLICE);
-}
-
-static void tcindex_free_perfect_hash(struct tcindex_data *cp);
-
-static void tcindex_partial_destroy_work(struct work_struct *work)
-{
-	struct tcindex_data *p = container_of(to_rcu_work(work),
-					      struct tcindex_data,
-					      rwork);
-
-	rtnl_lock();
-	if (p->perfect)
-		tcindex_free_perfect_hash(p);
-	kfree(p);
-	rtnl_unlock();
-}
-
-static void tcindex_free_perfect_hash(struct tcindex_data *cp)
-{
-	int i;
-
-	for (i = 0; i < cp->hash; i++)
-		tcf_exts_destroy(&cp->perfect[i].exts);
-	kfree(cp->perfect);
-}
-
-static int tcindex_alloc_perfect_hash(struct net *net, struct tcindex_data *cp)
-{
-	int i, err = 0;
-
-	cp->perfect = kcalloc(cp->hash, sizeof(struct tcindex_filter_result),
-			      GFP_KERNEL | __GFP_NOWARN);
-	if (!cp->perfect)
-		return -ENOMEM;
-
-	for (i = 0; i < cp->hash; i++) {
-		err = tcf_exts_init(&cp->perfect[i].exts, net,
-				    TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
-		if (err < 0)
-			goto errout;
-		cp->perfect[i].p = cp;
-	}
-
-	return 0;
-
-errout:
-	tcindex_free_perfect_hash(cp);
-	return err;
-}
-
-static int
-tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
-		  u32 handle, struct tcindex_data *p,
-		  struct tcindex_filter_result *r, struct nlattr **tb,
-		  struct nlattr *est, bool ovr, struct netlink_ext_ack *extack)
-{
-	struct tcindex_filter_result new_filter_result, *old_r = r;
-	struct tcindex_data *cp = NULL, *oldp;
-	struct tcindex_filter *f = NULL; /* make gcc behave */
-	struct tcf_result cr = {};
-	int err, balloc = 0;
-	struct tcf_exts e;
-
-	err = tcf_exts_init(&e, net, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
-	if (err < 0)
-		return err;
-	err = tcf_exts_validate(net, tp, tb, est, &e, ovr, true, extack);
-	if (err < 0)
-		goto errout;
-
-	err = -ENOMEM;
-	/* tcindex_data attributes must look atomic to classifier/lookup so
-	 * allocate new tcindex data and RCU assign it onto root. Keeping
-	 * perfect hash and hash pointers from old data.
-	 */
-	cp = kzalloc(sizeof(*cp), GFP_KERNEL);
-	if (!cp)
-		goto errout;
-
-	cp->mask = p->mask;
-	cp->shift = p->shift;
-	cp->hash = p->hash;
-	cp->alloc_hash = p->alloc_hash;
-	cp->fall_through = p->fall_through;
-	cp->tp = tp;
-	refcount_set(&cp->refcnt, 1); /* Paired with tcindex_destroy_work() */
-
-	if (tb[TCA_TCINDEX_HASH])
-		cp->hash = nla_get_u32(tb[TCA_TCINDEX_HASH]);
-
-	if (tb[TCA_TCINDEX_MASK])
-		cp->mask = nla_get_u16(tb[TCA_TCINDEX_MASK]);
-
-	if (tb[TCA_TCINDEX_SHIFT]) {
-		cp->shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]);
-		if (cp->shift > 16) {
-			err = -EINVAL;
-			goto errout;
-		}
-	}
-	if (!cp->hash) {
-		/* Hash not specified, use perfect hash if the upper limit
-		 * of the hashing index is below the threshold.
-		 */
-		if ((cp->mask >> cp->shift) < PERFECT_HASH_THRESHOLD)
-			cp->hash = (cp->mask >> cp->shift) + 1;
-		else
-			cp->hash = DEFAULT_HASH_SIZE;
-	}
-
-	if (p->perfect) {
-		int i;
-
-		if (tcindex_alloc_perfect_hash(net, cp) < 0)
-			goto errout;
-		cp->alloc_hash = cp->hash;
-		for (i = 0; i < min(cp->hash, p->hash); i++)
-			cp->perfect[i].res = p->perfect[i].res;
-		balloc = 1;
-	}
-	cp->h = p->h;
-
-	err = tcindex_filter_result_init(&new_filter_result, cp, net);
-	if (err < 0)
-		goto errout_alloc;
-	if (old_r)
-		cr = r->res;
-
-	err = -EBUSY;
-
-	/* Hash already allocated, make sure that we still meet the
-	 * requirements for the allocated hash.
-	 */
-	if (cp->perfect) {
-		if (!valid_perfect_hash(cp) ||
-		    cp->hash > cp->alloc_hash)
-			goto errout_alloc;
-	} else if (cp->h && cp->hash != cp->alloc_hash) {
-		goto errout_alloc;
-	}
-
-	err = -EINVAL;
-	if (tb[TCA_TCINDEX_FALL_THROUGH])
-		cp->fall_through = nla_get_u32(tb[TCA_TCINDEX_FALL_THROUGH]);
-
-	if (!cp->perfect && !cp->h)
-		cp->alloc_hash = cp->hash;
-
-	/* Note: this could be as restrictive as if (handle & ~(mask >> shift))
-	 * but then, we'd fail handles that may become valid after some future
-	 * mask change. While this is extremely unlikely to ever matter,
-	 * the check below is safer (and also more backwards-compatible).
-	 */
-	if (cp->perfect || valid_perfect_hash(cp))
-		if (handle >= cp->alloc_hash)
-			goto errout_alloc;
-
-
-	err = -ENOMEM;
-	if (!cp->perfect && !cp->h) {
-		if (valid_perfect_hash(cp)) {
-			if (tcindex_alloc_perfect_hash(net, cp) < 0)
-				goto errout_alloc;
-			balloc = 1;
-		} else {
-			struct tcindex_filter __rcu **hash;
-
-			hash = kcalloc(cp->hash,
-				       sizeof(struct tcindex_filter *),
-				       GFP_KERNEL);
-
-			if (!hash)
-				goto errout_alloc;
-
-			cp->h = hash;
-			balloc = 2;
-		}
-	}
-
-	if (cp->perfect)
-		r = cp->perfect + handle;
-	else
-		r = tcindex_lookup(cp, handle) ? : &new_filter_result;
-
-	if (r == &new_filter_result) {
-		f = kzalloc(sizeof(*f), GFP_KERNEL);
-		if (!f)
-			goto errout_alloc;
-		f->key = handle;
-		f->next = NULL;
-		err = tcindex_filter_result_init(&f->result, cp, net);
-		if (err < 0) {
-			kfree(f);
-			goto errout_alloc;
-		}
-	}
-
-	if (tb[TCA_TCINDEX_CLASSID]) {
-		cr.classid = nla_get_u32(tb[TCA_TCINDEX_CLASSID]);
-		tcf_bind_filter(tp, &cr, base);
-	}
-
-	if (old_r && old_r != r) {
-		err = tcindex_filter_result_init(old_r, cp, net);
-		if (err < 0) {
-			kfree(f);
-			goto errout_alloc;
-		}
-	}
-
-	oldp = p;
-	r->res = cr;
-	tcf_exts_change(&r->exts, &e);
-
-	rcu_assign_pointer(tp->root, cp);
-
-	if (r == &new_filter_result) {
-		struct tcindex_filter *nfp;
-		struct tcindex_filter __rcu **fp;
-
-		f->result.res = r->res;
-		tcf_exts_change(&f->result.exts, &r->exts);
-
-		fp = cp->h + (handle % cp->hash);
-		for (nfp = rtnl_dereference(*fp);
-		     nfp;
-		     fp = &nfp->next, nfp = rtnl_dereference(*fp))
-				; /* nothing */
-
-		rcu_assign_pointer(*fp, f);
-	} else {
-		tcf_exts_destroy(&new_filter_result.exts);
-	}
-
-	if (oldp)
-		tcf_queue_work(&oldp->rwork, tcindex_partial_destroy_work);
-	return 0;
-
-errout_alloc:
-	if (balloc == 1)
-		tcindex_free_perfect_hash(cp);
-	else if (balloc == 2)
-		kfree(cp->h);
-	tcf_exts_destroy(&new_filter_result.exts);
-errout:
-	kfree(cp);
-	tcf_exts_destroy(&e);
-	return err;
-}
-
-static int
-tcindex_change(struct net *net, struct sk_buff *in_skb,
-	       struct tcf_proto *tp, unsigned long base, u32 handle,
-	       struct nlattr **tca, void **arg, bool ovr,
-	       bool rtnl_held, struct netlink_ext_ack *extack)
-{
-	struct nlattr *opt = tca[TCA_OPTIONS];
-	struct nlattr *tb[TCA_TCINDEX_MAX + 1];
-	struct tcindex_data *p = rtnl_dereference(tp->root);
-	struct tcindex_filter_result *r = *arg;
-	int err;
-
-	pr_debug("tcindex_change(tp %p,handle 0x%08x,tca %p,arg %p),opt %p,"
-	    "p %p,r %p,*arg %p\n",
-	    tp, handle, tca, arg, opt, p, r, *arg);
-
-	if (!opt)
-		return 0;
-
-	err = nla_parse_nested_deprecated(tb, TCA_TCINDEX_MAX, opt,
-					  tcindex_policy, NULL);
-	if (err < 0)
-		return err;
-
-	return tcindex_set_parms(net, tp, base, handle, p, r, tb,
-				 tca[TCA_RATE], ovr, extack);
-}
-
-static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker,
-			 bool rtnl_held)
-{
-	struct tcindex_data *p = rtnl_dereference(tp->root);
-	struct tcindex_filter *f, *next;
-	int i;
-
-	pr_debug("tcindex_walk(tp %p,walker %p),p %p\n", tp, walker, p);
-	if (p->perfect) {
-		for (i = 0; i < p->hash; i++) {
-			if (!p->perfect[i].res.class)
-				continue;
-			if (walker->count >= walker->skip) {
-				if (walker->fn(tp, p->perfect + i, walker) < 0) {
-					walker->stop = 1;
-					return;
-				}
-			}
-			walker->count++;
-		}
-	}
-	if (!p->h)
-		return;
-	for (i = 0; i < p->hash; i++) {
-		for (f = rtnl_dereference(p->h[i]); f; f = next) {
-			next = rtnl_dereference(f->next);
-			if (walker->count >= walker->skip) {
-				if (walker->fn(tp, &f->result, walker) < 0) {
-					walker->stop = 1;
-					return;
-				}
-			}
-			walker->count++;
-		}
-	}
-}
-
-static void tcindex_destroy(struct tcf_proto *tp, bool rtnl_held,
-			    struct netlink_ext_ack *extack)
-{
-	struct tcindex_data *p = rtnl_dereference(tp->root);
-	int i;
-
-	pr_debug("tcindex_destroy(tp %p),p %p\n", tp, p);
-
-	if (p->perfect) {
-		for (i = 0; i < p->hash; i++) {
-			struct tcindex_filter_result *r = p->perfect + i;
-
-			/* tcf_queue_work() does not guarantee the ordering we
-			 * want, so we have to take this refcnt temporarily to
-			 * ensure 'p' is freed after all tcindex_filter_result
-			 * here. Imperfect hash does not need this, because it
-			 * uses linked lists rather than an array.
-			 */
-			tcindex_data_get(p);
-
-			tcf_unbind_filter(tp, &r->res);
-			if (tcf_exts_get_net(&r->exts))
-				tcf_queue_work(&r->rwork,
-					       tcindex_destroy_rexts_work);
-			else
-				__tcindex_destroy_rexts(r);
-		}
-	}
-
-	for (i = 0; p->h && i < p->hash; i++) {
-		struct tcindex_filter *f, *next;
-		bool last;
-
-		for (f = rtnl_dereference(p->h[i]); f; f = next) {
-			next = rtnl_dereference(f->next);
-			tcindex_delete(tp, &f->result, &last, rtnl_held, NULL);
-		}
-	}
-
-	tcf_queue_work(&p->rwork, tcindex_destroy_work);
-}
-
-
-static int tcindex_dump(struct net *net, struct tcf_proto *tp, void *fh,
-			struct sk_buff *skb, struct tcmsg *t, bool rtnl_held)
-{
-	struct tcindex_data *p = rtnl_dereference(tp->root);
-	struct tcindex_filter_result *r = fh;
-	struct nlattr *nest;
-
-	pr_debug("tcindex_dump(tp %p,fh %p,skb %p,t %p),p %p,r %p\n",
-		 tp, fh, skb, t, p, r);
-	pr_debug("p->perfect %p p->h %p\n", p->perfect, p->h);
-
-	nest = nla_nest_start_noflag(skb, TCA_OPTIONS);
-	if (nest == NULL)
-		goto nla_put_failure;
-
-	if (!fh) {
-		t->tcm_handle = ~0; /* whatever ... */
-		if (nla_put_u32(skb, TCA_TCINDEX_HASH, p->hash) ||
-		    nla_put_u16(skb, TCA_TCINDEX_MASK, p->mask) ||
-		    nla_put_u32(skb, TCA_TCINDEX_SHIFT, p->shift) ||
-		    nla_put_u32(skb, TCA_TCINDEX_FALL_THROUGH, p->fall_through))
-			goto nla_put_failure;
-		nla_nest_end(skb, nest);
-	} else {
-		if (p->perfect) {
-			t->tcm_handle = r - p->perfect;
-		} else {
-			struct tcindex_filter *f;
-			struct tcindex_filter __rcu **fp;
-			int i;
-
-			t->tcm_handle = 0;
-			for (i = 0; !t->tcm_handle && i < p->hash; i++) {
-				fp = &p->h[i];
-				for (f = rtnl_dereference(*fp);
-				     !t->tcm_handle && f;
-				     fp = &f->next, f = rtnl_dereference(*fp)) {
-					if (&f->result == r)
-						t->tcm_handle = f->key;
-				}
-			}
-		}
-		pr_debug("handle = %d\n", t->tcm_handle);
-		if (r->res.class &&
-		    nla_put_u32(skb, TCA_TCINDEX_CLASSID, r->res.classid))
-			goto nla_put_failure;
-
-		if (tcf_exts_dump(skb, &r->exts) < 0)
-			goto nla_put_failure;
-		nla_nest_end(skb, nest);
-
-		if (tcf_exts_dump_stats(skb, &r->exts) < 0)
-			goto nla_put_failure;
-	}
-
-	return skb->len;
-
-nla_put_failure:
-	nla_nest_cancel(skb, nest);
-	return -1;
-}
-
-static void tcindex_bind_class(void *fh, u32 classid, unsigned long cl,
-			       void *q, unsigned long base)
-{
-	struct tcindex_filter_result *r = fh;
-
-	if (r && r->res.classid == classid) {
-		if (cl)
-			__tcf_bind_filter(q, &r->res, base);
-		else
-			__tcf_unbind_filter(q, &r->res);
-	}
-}
-
-static struct tcf_proto_ops cls_tcindex_ops __read_mostly = {
-	.kind		=	"tcindex",
-	.classify	=	tcindex_classify,
-	.init		=	tcindex_init,
-	.destroy	=	tcindex_destroy,
-	.get		=	tcindex_get,
-	.change		=	tcindex_change,
-	.delete		=	tcindex_delete,
-	.walk		=	tcindex_walk,
-	.dump		=	tcindex_dump,
-	.bind_class	=	tcindex_bind_class,
-	.owner		=	THIS_MODULE,
-};
-
-static int __init init_tcindex(void)
-{
-	return register_tcf_proto_ops(&cls_tcindex_ops);
-}
-
-static void __exit exit_tcindex(void)
-{
-	unregister_tcf_proto_ops(&cls_tcindex_ops);
-}
-
-module_init(init_tcindex)
-module_exit(exit_tcindex)
-MODULE_LICENSE("GPL");
diff --git a/kernel/net/sched/cls_u32.c b/kernel/net/sched/cls_u32.c
index da042bc..b2d2ba5 100644
--- a/kernel/net/sched/cls_u32.c
+++ b/kernel/net/sched/cls_u32.c
@@ -716,11 +716,17 @@
 			 struct nlattr *est, bool ovr,
 			 struct netlink_ext_ack *extack)
 {
-	int err;
+	int err, ifindex = -1;
 
 	err = tcf_exts_validate(net, tp, tb, est, &n->exts, ovr, true, extack);
 	if (err < 0)
 		return err;
+
+	if (tb[TCA_U32_INDEV]) {
+		ifindex = tcf_change_indev(net, tb[TCA_U32_INDEV], extack);
+		if (ifindex < 0)
+			return -EINVAL;
+	}
 
 	if (tb[TCA_U32_LINK]) {
 		u32 handle = nla_get_u32(tb[TCA_U32_LINK]);
@@ -756,13 +762,9 @@
 		tcf_bind_filter(tp, &n->res, base);
 	}
 
-	if (tb[TCA_U32_INDEV]) {
-		int ret;
-		ret = tcf_change_indev(net, tb[TCA_U32_INDEV], extack);
-		if (ret < 0)
-			return -EINVAL;
-		n->ifindex = ret;
-	}
+	if (ifindex >= 0)
+		n->ifindex = ifindex;
+
 	return 0;
 }
 
@@ -810,7 +812,6 @@
 
 	new->ifindex = n->ifindex;
 	new->fshift = n->fshift;
-	new->res = n->res;
 	new->flags = n->flags;
 	RCU_INIT_POINTER(new->ht_down, ht);
 
@@ -997,18 +998,62 @@
 		return -EINVAL;
 	}
 
+	/* At this point, we need to derive the new handle that will be used to
+	 * uniquely map the identity of this table match entry. The
+	 * identity of the entry that we need to construct is 32 bits made of:
+	 *     htid(12b):bucketid(8b):node/entryid(12b)
+	 *
+	 * At this point _we have the table(ht)_ in which we will insert this
+	 * entry. We carry the table's id in variable "htid".
+	 * Note that earlier code picked the ht selection either by a) the user
+	 * providing the htid specified via TCA_U32_HASH attribute or b) when
+	 * no such attribute is passed then the root ht, is default to at ID
+	 * 0x[800][00][000]. Rule: the root table has a single bucket with ID 0.
+	 * If OTOH the user passed us the htid, they may also pass a bucketid of
+	 * choice. 0 is fine. For example a user htid is 0x[600][01][000] it is
+	 * indicating hash bucketid of 1. Rule: the entry/node ID _cannot_ be
+	 * passed via the htid, so even if it was non-zero it will be ignored.
+	 *
+	 * We may also have a handle, if the user passed one. The handle also
+	 * carries the same addressing of htid(12b):bucketid(8b):node/entryid(12b).
+	 * Rule: the bucketid on the handle is ignored even if one was passed;
+	 * rather the value on "htid" is always assumed to be the bucketid.
+	 */
 	if (handle) {
+		/* Rule: The htid from handle and tableid from htid must match */
 		if (TC_U32_HTID(handle) && TC_U32_HTID(handle ^ htid)) {
 			NL_SET_ERR_MSG_MOD(extack, "Handle specified hash table address mismatch");
 			return -EINVAL;
 		}
-		handle = htid | TC_U32_NODE(handle);
-		err = idr_alloc_u32(&ht->handle_idr, NULL, &handle, handle,
-				    GFP_KERNEL);
-		if (err)
-			return err;
-	} else
+		/* Ok, so far we have a valid htid(12b):bucketid(8b) but we
+		 * need to finalize the table entry identification with the last
+		 * part - the node/entryid(12b)). Rule: Nodeid _cannot be 0_ for
+		 * entries. Rule: nodeid of 0 is reserved only for tables(see
+		 * earlier code which processes TC_U32_DIVISOR attribute).
+		 * Rule: The nodeid can only be derived from the handle (and not
+		 * htid).
+		 * Rule: if the handle specified zero for the node id example
+		 * 0x60000000, then pick a new nodeid from the pool of IDs
+		 * this hash table has been allocating from.
+		 * If OTOH it is specified (i.e for example the user passed a
+		 * handle such as 0x60000123), then we use it generate our final
+		 * handle which is used to uniquely identify the match entry.
+		 */
+		if (!TC_U32_NODE(handle)) {
+			handle = gen_new_kid(ht, htid);
+		} else {
+			handle = htid | TC_U32_NODE(handle);
+			err = idr_alloc_u32(&ht->handle_idr, NULL, &handle,
+					    handle, GFP_KERNEL);
+			if (err)
+				return err;
+		}
+	} else {
+		/* The user did not give us a handle; lets just generate one
+		 * from the table's pool of nodeids.
+		 */
 		handle = gen_new_kid(ht, htid);
+	}
 
 	if (tb[TCA_U32_SEL] == NULL) {
 		NL_SET_ERR_MSG_MOD(extack, "Selector not specified");
diff --git a/kernel/net/sched/ematch.c b/kernel/net/sched/ematch.c
index f885bea..b715410 100644
--- a/kernel/net/sched/ematch.c
+++ b/kernel/net/sched/ematch.c
@@ -255,6 +255,8 @@
 			 * 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;
diff --git a/kernel/net/sched/sch_api.c b/kernel/net/sched/sch_api.c
index d8ffe41..5c2d230 100644
--- a/kernel/net/sched/sch_api.c
+++ b/kernel/net/sched/sch_api.c
@@ -1044,12 +1044,12 @@
 
 	if (parent == NULL) {
 		unsigned int i, num_q, ingress;
+		struct netdev_queue *dev_queue;
 
 		ingress = 0;
 		num_q = dev->num_tx_queues;
 		if ((q && q->flags & TCQ_F_INGRESS) ||
 		    (new && new->flags & TCQ_F_INGRESS)) {
-			num_q = 1;
 			ingress = 1;
 			if (!dev_ingress_queue(dev)) {
 				NL_SET_ERR_MSG(extack, "Device does not have an ingress queue");
@@ -1065,18 +1065,18 @@
 		if (new && new->ops->attach)
 			goto skip;
 
-		for (i = 0; i < num_q; i++) {
-			struct netdev_queue *dev_queue = dev_ingress_queue(dev);
-
-			if (!ingress)
+		if (!ingress) {
+			for (i = 0; i < num_q; i++) {
 				dev_queue = netdev_get_tx_queue(dev, i);
+				old = dev_graft_qdisc(dev_queue, new);
 
-			old = dev_graft_qdisc(dev_queue, new);
-			if (new && i > 0)
-				qdisc_refcount_inc(new);
-
-			if (!ingress)
+				if (new && i > 0)
+					qdisc_refcount_inc(new);
 				qdisc_put(old);
+			}
+		} else {
+			dev_queue = dev_ingress_queue(dev);
+			old = dev_graft_qdisc(dev_queue, new);
 		}
 
 skip:
@@ -1112,6 +1112,11 @@
 		if (!cl) {
 			NL_SET_ERR_MSG(extack, "Specified class not found");
 			return -ENOENT;
+		}
+
+		if (new && new->ops == &noqueue_qdisc_ops) {
+			NL_SET_ERR_MSG(extack, "Cannot assign noqueue to a class");
+			return -EINVAL;
 		}
 
 		err = cops->graft(parent, cl, new, &old, extack);
@@ -1218,7 +1223,12 @@
 	sch->parent = parent;
 
 	if (handle == TC_H_INGRESS) {
-		sch->flags |= TCQ_F_INGRESS;
+		if (!(sch->flags & TCQ_F_INGRESS)) {
+			NL_SET_ERR_MSG(extack,
+				       "Specified parent ID is reserved for ingress and clsact Qdiscs");
+			err = -EINVAL;
+			goto err_out3;
+		}
 		handle = TC_H_MAKE(TC_H_INGRESS, 0);
 	} else {
 		if (handle == 0) {
@@ -1503,10 +1513,28 @@
 	return 0;
 }
 
+static bool req_create_or_replace(struct nlmsghdr *n)
+{
+	return (n->nlmsg_flags & NLM_F_CREATE &&
+		n->nlmsg_flags & NLM_F_REPLACE);
+}
+
+static bool req_create_exclusive(struct nlmsghdr *n)
+{
+	return (n->nlmsg_flags & NLM_F_CREATE &&
+		n->nlmsg_flags & NLM_F_EXCL);
+}
+
+static bool req_change(struct nlmsghdr *n)
+{
+	return (!(n->nlmsg_flags & NLM_F_CREATE) &&
+		!(n->nlmsg_flags & NLM_F_REPLACE) &&
+		!(n->nlmsg_flags & NLM_F_EXCL));
+}
+
 /*
  * Create/change qdisc.
  */
-
 static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
 			   struct netlink_ext_ack *extack)
 {
@@ -1579,10 +1607,19 @@
 					NL_SET_ERR_MSG(extack, "Invalid qdisc name");
 					return -EINVAL;
 				}
+				if (q->flags & TCQ_F_INGRESS) {
+					NL_SET_ERR_MSG(extack,
+						       "Cannot regraft ingress or clsact Qdiscs");
+					return -EINVAL;
+				}
 				if (q == p ||
 				    (p && check_loop(q, p, 0))) {
 					NL_SET_ERR_MSG(extack, "Qdisc parent/child loop detected");
 					return -ELOOP;
+				}
+				if (clid == TC_H_INGRESS) {
+					NL_SET_ERR_MSG(extack, "Ingress cannot graft directly");
+					return -EINVAL;
 				}
 				qdisc_refcount_inc(q);
 				goto graft;
@@ -1594,27 +1631,35 @@
 				 *
 				 *   We know, that some child q is already
 				 *   attached to this parent and have choice:
-				 *   either to change it or to create/graft new one.
+				 *   1) change it or 2) create/graft new one.
+				 *   If the requested qdisc kind is different
+				 *   than the existing one, then we choose graft.
+				 *   If they are the same then this is "change"
+				 *   operation - just let it fallthrough..
 				 *
 				 *   1. We are allowed to create/graft only
-				 *   if CREATE and REPLACE flags are set.
+				 *   if the request is explicitly stating
+				 *   "please create if it doesn't exist".
 				 *
-				 *   2. If EXCL is set, requestor wanted to say,
-				 *   that qdisc tcm_handle is not expected
+				 *   2. If the request is to exclusive create
+				 *   then the qdisc tcm_handle is not expected
 				 *   to exist, so that we choose create/graft too.
 				 *
 				 *   3. The last case is when no flags are set.
+				 *   This will happen when for example tc
+				 *   utility issues a "change" command.
 				 *   Alas, it is sort of hole in API, we
 				 *   cannot decide what to do unambiguously.
-				 *   For now we select create/graft, if
-				 *   user gave KIND, which does not match existing.
+				 *   For now we select create/graft.
 				 */
-				if ((n->nlmsg_flags & NLM_F_CREATE) &&
-				    (n->nlmsg_flags & NLM_F_REPLACE) &&
-				    ((n->nlmsg_flags & NLM_F_EXCL) ||
-				     (tca[TCA_KIND] &&
-				      nla_strcmp(tca[TCA_KIND], q->ops->id))))
-					goto create_n_graft;
+				if (tca[TCA_KIND] &&
+				    nla_strcmp(tca[TCA_KIND], q->ops->id)) {
+					if (req_create_or_replace(n) ||
+					    req_create_exclusive(n))
+						goto create_n_graft;
+					else if (req_change(n))
+						goto create_n_graft2;
+				}
 			}
 		}
 	} else {
@@ -1648,6 +1693,7 @@
 		NL_SET_ERR_MSG(extack, "Qdisc not found. To create specify NLM_F_CREATE flag");
 		return -ENOENT;
 	}
+create_n_graft2:
 	if (clid == TC_H_INGRESS) {
 		if (dev_ingress_queue(dev)) {
 			q = qdisc_create(dev, dev_ingress_queue(dev), p,
diff --git a/kernel/net/sched/sch_atm.c b/kernel/net/sched/sch_atm.c
index 794c737..95967ce 100644
--- a/kernel/net/sched/sch_atm.c
+++ b/kernel/net/sched/sch_atm.c
@@ -396,10 +396,13 @@
 				result = tcf_classify(skb, fl, &res, true);
 				if (result < 0)
 					continue;
+				if (result == TC_ACT_SHOT)
+					goto done;
+
 				flow = (struct atm_flow_data *)res.class;
 				if (!flow)
 					flow = lookup_flow(sch, res.classid);
-				goto done;
+				goto drop;
 			}
 		}
 		flow = NULL;
diff --git a/kernel/net/sched/sch_cbq.c b/kernel/net/sched/sch_cbq.c
index 9a3dff0..3da5eb3 100644
--- a/kernel/net/sched/sch_cbq.c
+++ b/kernel/net/sched/sch_cbq.c
@@ -231,6 +231,8 @@
 		result = tcf_classify(skb, fl, &res, true);
 		if (!fl || result < 0)
 			goto fallback;
+		if (result == TC_ACT_SHOT)
+			return NULL;
 
 		cl = (void *)res.class;
 		if (!cl) {
@@ -251,8 +253,6 @@
 		case TC_ACT_TRAP:
 			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 			fallthrough;
-		case TC_ACT_SHOT:
-			return NULL;
 		case TC_ACT_RECLASSIFY:
 			return cbq_reclassify(skb, cl);
 		}
diff --git a/kernel/net/sched/sch_fq.c b/kernel/net/sched/sch_fq.c
index 2fb76fc..5a12741 100644
--- a/kernel/net/sched/sch_fq.c
+++ b/kernel/net/sched/sch_fq.c
@@ -779,13 +779,17 @@
 	return 0;
 }
 
+static struct netlink_range_validation iq_range = {
+	.max = INT_MAX,
+};
+
 static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = {
 	[TCA_FQ_UNSPEC]			= { .strict_start_type = TCA_FQ_TIMER_SLACK },
 
 	[TCA_FQ_PLIMIT]			= { .type = NLA_U32 },
 	[TCA_FQ_FLOW_PLIMIT]		= { .type = NLA_U32 },
 	[TCA_FQ_QUANTUM]		= { .type = NLA_U32 },
-	[TCA_FQ_INITIAL_QUANTUM]	= { .type = NLA_U32 },
+	[TCA_FQ_INITIAL_QUANTUM]	= NLA_POLICY_FULL_RANGE(NLA_U32, &iq_range),
 	[TCA_FQ_RATE_ENABLE]		= { .type = NLA_U32 },
 	[TCA_FQ_FLOW_DEFAULT_RATE]	= { .type = NLA_U32 },
 	[TCA_FQ_FLOW_MAX_RATE]		= { .type = NLA_U32 },
diff --git a/kernel/net/sched/sch_fq_pie.c b/kernel/net/sched/sch_fq_pie.c
index cf04f70..a5b6315 100644
--- a/kernel/net/sched/sch_fq_pie.c
+++ b/kernel/net/sched/sch_fq_pie.c
@@ -61,6 +61,7 @@
 	struct pie_params p_params;
 	u32 ecn_prob;
 	u32 flows_cnt;
+	u32 flows_cursor;
 	u32 quantum;
 	u32 memory_limit;
 	u32 new_flow_count;
@@ -201,6 +202,11 @@
 	return NET_XMIT_CN;
 }
 
+static struct netlink_range_validation fq_pie_q_range = {
+	.min = 1,
+	.max = 1 << 20,
+};
+
 static const struct nla_policy fq_pie_policy[TCA_FQ_PIE_MAX + 1] = {
 	[TCA_FQ_PIE_LIMIT]		= {.type = NLA_U32},
 	[TCA_FQ_PIE_FLOWS]		= {.type = NLA_U32},
@@ -208,7 +214,8 @@
 	[TCA_FQ_PIE_TUPDATE]		= {.type = NLA_U32},
 	[TCA_FQ_PIE_ALPHA]		= {.type = NLA_U32},
 	[TCA_FQ_PIE_BETA]		= {.type = NLA_U32},
-	[TCA_FQ_PIE_QUANTUM]		= {.type = NLA_U32},
+	[TCA_FQ_PIE_QUANTUM]		=
+			NLA_POLICY_FULL_RANGE(NLA_U32, &fq_pie_q_range),
 	[TCA_FQ_PIE_MEMORY_LIMIT]	= {.type = NLA_U32},
 	[TCA_FQ_PIE_ECN_PROB]		= {.type = NLA_U32},
 	[TCA_FQ_PIE_ECN]		= {.type = NLA_U32},
@@ -372,21 +379,31 @@
 static void fq_pie_timer(struct timer_list *t)
 {
 	struct fq_pie_sched_data *q = from_timer(q, t, adapt_timer);
+	unsigned long next, tupdate;
 	struct Qdisc *sch = q->sch;
 	spinlock_t *root_lock; /* to lock qdisc for probability calculations */
-	u32 idx;
+	int max_cnt, i;
 
 	root_lock = qdisc_lock(qdisc_root_sleeping(sch));
 	spin_lock(root_lock);
 
-	for (idx = 0; idx < q->flows_cnt; idx++)
-		pie_calculate_probability(&q->p_params, &q->flows[idx].vars,
-					  q->flows[idx].backlog);
+	/* Limit this expensive loop to 2048 flows per round. */
+	max_cnt = min_t(int, q->flows_cnt - q->flows_cursor, 2048);
+	for (i = 0; i < max_cnt; i++) {
+		pie_calculate_probability(&q->p_params,
+					  &q->flows[q->flows_cursor].vars,
+					  q->flows[q->flows_cursor].backlog);
+		q->flows_cursor++;
+	}
 
-	/* reset the timer to fire after 'tupdate' jiffies. */
-	if (q->p_params.tupdate)
-		mod_timer(&q->adapt_timer, jiffies + q->p_params.tupdate);
-
+	tupdate = q->p_params.tupdate;
+	next = 0;
+	if (q->flows_cursor >= q->flows_cnt) {
+		q->flows_cursor = 0;
+		next = tupdate;
+	}
+	if (tupdate)
+		mod_timer(&q->adapt_timer, jiffies + next);
 	spin_unlock(root_lock);
 }
 
diff --git a/kernel/net/sched/sch_hfsc.c b/kernel/net/sched/sch_hfsc.c
index cdc43a0..6076294 100644
--- a/kernel/net/sched/sch_hfsc.c
+++ b/kernel/net/sched/sch_hfsc.c
@@ -1012,6 +1012,10 @@
 		if (parent == NULL)
 			return -ENOENT;
 	}
+	if (!(parent->cl_flags & HFSC_FSC) && parent != &q->root) {
+		NL_SET_ERR_MSG(extack, "Invalid parent - parent class must have FSC");
+		return -EINVAL;
+	}
 
 	if (classid == 0 || TC_H_MAJ(classid ^ sch->handle) != 0)
 		return -EINVAL;
diff --git a/kernel/net/sched/sch_htb.c b/kernel/net/sched/sch_htb.c
index c3ba018..ff84ed5 100644
--- a/kernel/net/sched/sch_htb.c
+++ b/kernel/net/sched/sch_htb.c
@@ -405,7 +405,10 @@
 	while (cl->cmode == HTB_MAY_BORROW && p && mask) {
 		m = mask;
 		while (m) {
-			int prio = ffz(~m);
+			unsigned int prio = ffz(~m);
+
+			if (WARN_ON_ONCE(prio >= ARRAY_SIZE(p->inner.clprio)))
+				break;
 			m &= ~(1 << prio);
 
 			if (p->inner.clprio[prio].feed.rb_node)
diff --git a/kernel/net/sched/sch_ingress.c b/kernel/net/sched/sch_ingress.c
index 8483812..e43a454 100644
--- a/kernel/net/sched/sch_ingress.c
+++ b/kernel/net/sched/sch_ingress.c
@@ -80,6 +80,9 @@
 	struct net_device *dev = qdisc_dev(sch);
 	int err;
 
+	if (sch->parent != TC_H_INGRESS)
+		return -EOPNOTSUPP;
+
 	net_inc_ingress_queue();
 
 	mini_qdisc_pair_init(&q->miniqp, sch, &dev->miniq_ingress);
@@ -100,6 +103,9 @@
 static void ingress_destroy(struct Qdisc *sch)
 {
 	struct ingress_sched_data *q = qdisc_priv(sch);
+
+	if (sch->parent != TC_H_INGRESS)
+		return;
 
 	tcf_block_put_ext(q->block, sch, &q->block_info);
 	net_dec_ingress_queue();
@@ -134,7 +140,7 @@
 	.cl_ops			=	&ingress_class_ops,
 	.id			=	"ingress",
 	.priv_size		=	sizeof(struct ingress_sched_data),
-	.static_flags		=	TCQ_F_CPUSTATS,
+	.static_flags		=	TCQ_F_INGRESS | TCQ_F_CPUSTATS,
 	.init			=	ingress_init,
 	.destroy		=	ingress_destroy,
 	.dump			=	ingress_dump,
@@ -219,6 +225,9 @@
 	struct net_device *dev = qdisc_dev(sch);
 	int err;
 
+	if (sch->parent != TC_H_CLSACT)
+		return -EOPNOTSUPP;
+
 	net_inc_ingress_queue();
 	net_inc_egress_queue();
 
@@ -248,6 +257,9 @@
 {
 	struct clsact_sched_data *q = qdisc_priv(sch);
 
+	if (sch->parent != TC_H_CLSACT)
+		return;
+
 	tcf_block_put_ext(q->egress_block, sch, &q->egress_block_info);
 	tcf_block_put_ext(q->ingress_block, sch, &q->ingress_block_info);
 
@@ -269,7 +281,7 @@
 	.cl_ops			=	&clsact_class_ops,
 	.id			=	"clsact",
 	.priv_size		=	sizeof(struct clsact_sched_data),
-	.static_flags		=	TCQ_F_CPUSTATS,
+	.static_flags		=	TCQ_F_INGRESS | TCQ_F_CPUSTATS,
 	.init			=	clsact_init,
 	.destroy		=	clsact_destroy,
 	.dump			=	ingress_dump,
diff --git a/kernel/net/sched/sch_mqprio.c b/kernel/net/sched/sch_mqprio.c
index 5eb3b1b..e0074be 100644
--- a/kernel/net/sched/sch_mqprio.c
+++ b/kernel/net/sched/sch_mqprio.c
@@ -130,6 +130,97 @@
 	return 0;
 }
 
+static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt,
+			       struct nlattr *opt,
+			       struct netlink_ext_ack *extack)
+{
+	struct mqprio_sched *priv = qdisc_priv(sch);
+	struct nlattr *tb[TCA_MQPRIO_MAX + 1];
+	struct nlattr *attr;
+	int i, rem, err;
+
+	err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy,
+			 sizeof(*qopt));
+	if (err < 0)
+		return err;
+
+	if (!qopt->hw) {
+		NL_SET_ERR_MSG(extack,
+			       "mqprio TCA_OPTIONS can only contain netlink attributes in hardware mode");
+		return -EINVAL;
+	}
+
+	if (tb[TCA_MQPRIO_MODE]) {
+		priv->flags |= TC_MQPRIO_F_MODE;
+		priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]);
+	}
+
+	if (tb[TCA_MQPRIO_SHAPER]) {
+		priv->flags |= TC_MQPRIO_F_SHAPER;
+		priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]);
+	}
+
+	if (tb[TCA_MQPRIO_MIN_RATE64]) {
+		if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) {
+			NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MIN_RATE64],
+					    "min_rate accepted only when shaper is in bw_rlimit mode");
+			return -EINVAL;
+		}
+		i = 0;
+		nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64],
+				    rem) {
+			if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64) {
+				NL_SET_ERR_MSG_ATTR(extack, attr,
+						    "Attribute type expected to be TCA_MQPRIO_MIN_RATE64");
+				return -EINVAL;
+			}
+
+			if (nla_len(attr) != sizeof(u64)) {
+				NL_SET_ERR_MSG_ATTR(extack, attr,
+						    "Attribute TCA_MQPRIO_MIN_RATE64 expected to have 8 bytes length");
+				return -EINVAL;
+			}
+
+			if (i >= qopt->num_tc)
+				break;
+			priv->min_rate[i] = *(u64 *)nla_data(attr);
+			i++;
+		}
+		priv->flags |= TC_MQPRIO_F_MIN_RATE;
+	}
+
+	if (tb[TCA_MQPRIO_MAX_RATE64]) {
+		if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) {
+			NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MAX_RATE64],
+					    "max_rate accepted only when shaper is in bw_rlimit mode");
+			return -EINVAL;
+		}
+		i = 0;
+		nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64],
+				    rem) {
+			if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64) {
+				NL_SET_ERR_MSG_ATTR(extack, attr,
+						    "Attribute type expected to be TCA_MQPRIO_MAX_RATE64");
+				return -EINVAL;
+			}
+
+			if (nla_len(attr) != sizeof(u64)) {
+				NL_SET_ERR_MSG_ATTR(extack, attr,
+						    "Attribute TCA_MQPRIO_MAX_RATE64 expected to have 8 bytes length");
+				return -EINVAL;
+			}
+
+			if (i >= qopt->num_tc)
+				break;
+			priv->max_rate[i] = *(u64 *)nla_data(attr);
+			i++;
+		}
+		priv->flags |= TC_MQPRIO_F_MAX_RATE;
+	}
+
+	return 0;
+}
+
 static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
 		       struct netlink_ext_ack *extack)
 {
@@ -139,9 +230,6 @@
 	struct Qdisc *qdisc;
 	int i, err = -EOPNOTSUPP;
 	struct tc_mqprio_qopt *qopt = NULL;
-	struct nlattr *tb[TCA_MQPRIO_MAX + 1];
-	struct nlattr *attr;
-	int rem;
 	int len;
 
 	BUILD_BUG_ON(TC_MAX_QUEUE != TC_QOPT_MAX_QUEUE);
@@ -166,55 +254,9 @@
 
 	len = nla_len(opt) - NLA_ALIGN(sizeof(*qopt));
 	if (len > 0) {
-		err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy,
-				 sizeof(*qopt));
-		if (err < 0)
+		err = mqprio_parse_nlattr(sch, qopt, opt, extack);
+		if (err)
 			return err;
-
-		if (!qopt->hw)
-			return -EINVAL;
-
-		if (tb[TCA_MQPRIO_MODE]) {
-			priv->flags |= TC_MQPRIO_F_MODE;
-			priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]);
-		}
-
-		if (tb[TCA_MQPRIO_SHAPER]) {
-			priv->flags |= TC_MQPRIO_F_SHAPER;
-			priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]);
-		}
-
-		if (tb[TCA_MQPRIO_MIN_RATE64]) {
-			if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
-				return -EINVAL;
-			i = 0;
-			nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64],
-					    rem) {
-				if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64)
-					return -EINVAL;
-				if (i >= qopt->num_tc)
-					break;
-				priv->min_rate[i] = *(u64 *)nla_data(attr);
-				i++;
-			}
-			priv->flags |= TC_MQPRIO_F_MIN_RATE;
-		}
-
-		if (tb[TCA_MQPRIO_MAX_RATE64]) {
-			if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
-				return -EINVAL;
-			i = 0;
-			nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64],
-					    rem) {
-				if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64)
-					return -EINVAL;
-				if (i >= qopt->num_tc)
-					break;
-				priv->max_rate[i] = *(u64 *)nla_data(attr);
-				i++;
-			}
-			priv->flags |= TC_MQPRIO_F_MAX_RATE;
-		}
 	}
 
 	/* pre-allocate qdisc, attachment can't fail */
diff --git a/kernel/net/sched/sch_netem.c b/kernel/net/sched/sch_netem.c
index adc5407..08aaa6e 100644
--- a/kernel/net/sched/sch_netem.c
+++ b/kernel/net/sched/sch_netem.c
@@ -773,12 +773,10 @@
  * signed 16 bit values.
  */
 
-static int get_dist_table(struct Qdisc *sch, struct disttable **tbl,
-			  const struct nlattr *attr)
+static int get_dist_table(struct disttable **tbl, const struct nlattr *attr)
 {
 	size_t n = nla_len(attr)/sizeof(__s16);
 	const __s16 *data = nla_data(attr);
-	spinlock_t *root_lock;
 	struct disttable *d;
 	int i;
 
@@ -793,13 +791,7 @@
 	for (i = 0; i < n; i++)
 		d->table[i] = data[i];
 
-	root_lock = qdisc_root_sleeping_lock(sch);
-
-	spin_lock_bh(root_lock);
-	swap(*tbl, d);
-	spin_unlock_bh(root_lock);
-
-	dist_free(d);
+	*tbl = d;
 	return 0;
 }
 
@@ -956,6 +948,8 @@
 {
 	struct netem_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_NETEM_MAX + 1];
+	struct disttable *delay_dist = NULL;
+	struct disttable *slot_dist = NULL;
 	struct tc_netem_qopt *qopt;
 	struct clgstate old_clg;
 	int old_loss_model = CLG_RANDOM;
@@ -969,6 +963,19 @@
 	if (ret < 0)
 		return ret;
 
+	if (tb[TCA_NETEM_DELAY_DIST]) {
+		ret = get_dist_table(&delay_dist, tb[TCA_NETEM_DELAY_DIST]);
+		if (ret)
+			goto table_free;
+	}
+
+	if (tb[TCA_NETEM_SLOT_DIST]) {
+		ret = get_dist_table(&slot_dist, tb[TCA_NETEM_SLOT_DIST]);
+		if (ret)
+			goto table_free;
+	}
+
+	sch_tree_lock(sch);
 	/* backup q->clg and q->loss_model */
 	old_clg = q->clg;
 	old_loss_model = q->loss_model;
@@ -977,26 +984,17 @@
 		ret = get_loss_clg(q, tb[TCA_NETEM_LOSS]);
 		if (ret) {
 			q->loss_model = old_loss_model;
-			return ret;
+			q->clg = old_clg;
+			goto unlock;
 		}
 	} else {
 		q->loss_model = CLG_RANDOM;
 	}
 
-	if (tb[TCA_NETEM_DELAY_DIST]) {
-		ret = get_dist_table(sch, &q->delay_dist,
-				     tb[TCA_NETEM_DELAY_DIST]);
-		if (ret)
-			goto get_table_failure;
-	}
-
-	if (tb[TCA_NETEM_SLOT_DIST]) {
-		ret = get_dist_table(sch, &q->slot_dist,
-				     tb[TCA_NETEM_SLOT_DIST]);
-		if (ret)
-			goto get_table_failure;
-	}
-
+	if (delay_dist)
+		swap(q->delay_dist, delay_dist);
+	if (slot_dist)
+		swap(q->slot_dist, slot_dist);
 	sch->limit = qopt->limit;
 
 	q->latency = PSCHED_TICKS2NS(qopt->latency);
@@ -1044,15 +1042,12 @@
 	/* capping jitter to the range acceptable by tabledist() */
 	q->jitter = min_t(s64, abs(q->jitter), INT_MAX);
 
-	return ret;
+unlock:
+	sch_tree_unlock(sch);
 
-get_table_failure:
-	/* recover clg and loss_model, in case of
-	 * q->clg and q->loss_model were modified
-	 * in get_loss_clg()
-	 */
-	q->clg = old_clg;
-	q->loss_model = old_loss_model;
+table_free:
+	dist_free(delay_dist);
+	dist_free(slot_dist);
 	return ret;
 }
 
diff --git a/kernel/net/sched/sch_plug.c b/kernel/net/sched/sch_plug.c
index cbc2ebc..339990b 100644
--- a/kernel/net/sched/sch_plug.c
+++ b/kernel/net/sched/sch_plug.c
@@ -210,7 +210,7 @@
 	.priv_size   =       sizeof(struct plug_sched_data),
 	.enqueue     =       plug_enqueue,
 	.dequeue     =       plug_dequeue,
-	.peek        =       qdisc_peek_head,
+	.peek        =       qdisc_peek_dequeued,
 	.init        =       plug_init,
 	.change      =       plug_change,
 	.reset       =	     qdisc_reset_queue,
diff --git a/kernel/net/sched/sch_qfq.c b/kernel/net/sched/sch_qfq.c
index 1d1d81a..ebf9f47 100644
--- a/kernel/net/sched/sch_qfq.c
+++ b/kernel/net/sched/sch_qfq.c
@@ -113,6 +113,7 @@
 
 #define QFQ_MTU_SHIFT		16	/* to support TSO/GSO */
 #define QFQ_MIN_LMAX		512	/* see qfq_slot_insert */
+#define QFQ_MAX_LMAX		(1UL << QFQ_MTU_SHIFT)
 
 #define QFQ_MAX_AGG_CLASSES	8 /* max num classes per aggregate allowed */
 
@@ -214,9 +215,14 @@
 	return container_of(clc, struct qfq_class, common);
 }
 
+static struct netlink_range_validation lmax_range = {
+	.min = QFQ_MIN_LMAX,
+	.max = QFQ_MAX_LMAX,
+};
+
 static const struct nla_policy qfq_policy[TCA_QFQ_MAX + 1] = {
-	[TCA_QFQ_WEIGHT] = { .type = NLA_U32 },
-	[TCA_QFQ_LMAX] = { .type = NLA_U32 },
+	[TCA_QFQ_WEIGHT] = NLA_POLICY_RANGE(NLA_U32, 1, QFQ_MAX_WEIGHT),
+	[TCA_QFQ_LMAX] = NLA_POLICY_FULL_RANGE(NLA_U32, &lmax_range),
 };
 
 /*
@@ -375,8 +381,13 @@
 			   u32 lmax)
 {
 	struct qfq_sched *q = qdisc_priv(sch);
-	struct qfq_aggregate *new_agg = qfq_find_agg(q, lmax, weight);
+	struct qfq_aggregate *new_agg;
 
+	/* 'lmax' can range from [QFQ_MIN_LMAX, pktlen + stab overhead] */
+	if (lmax > QFQ_MAX_LMAX)
+		return -EINVAL;
+
+	new_agg = qfq_find_agg(q, lmax, weight);
 	if (new_agg == NULL) { /* create new aggregate */
 		new_agg = kzalloc(sizeof(*new_agg), GFP_ATOMIC);
 		if (new_agg == NULL)
@@ -408,27 +419,26 @@
 	}
 
 	err = nla_parse_nested_deprecated(tb, TCA_QFQ_MAX, tca[TCA_OPTIONS],
-					  qfq_policy, NULL);
+					  qfq_policy, extack);
 	if (err < 0)
 		return err;
 
-	if (tb[TCA_QFQ_WEIGHT]) {
+	if (tb[TCA_QFQ_WEIGHT])
 		weight = nla_get_u32(tb[TCA_QFQ_WEIGHT]);
-		if (!weight || weight > (1UL << QFQ_MAX_WSHIFT)) {
-			pr_notice("qfq: invalid weight %u\n", weight);
-			return -EINVAL;
-		}
-	} else
+	else
 		weight = 1;
 
 	if (tb[TCA_QFQ_LMAX]) {
 		lmax = nla_get_u32(tb[TCA_QFQ_LMAX]);
-		if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) {
-			pr_notice("qfq: invalid max length %u\n", lmax);
+	} else {
+		/* MTU size is user controlled */
+		lmax = psched_mtu(qdisc_dev(sch));
+		if (lmax < QFQ_MIN_LMAX || lmax > QFQ_MAX_LMAX) {
+			NL_SET_ERR_MSG_MOD(extack,
+					   "MTU size out of bounds for qfq");
 			return -EINVAL;
 		}
-	} else
-		lmax = psched_mtu(qdisc_dev(sch));
+	}
 
 	inv_w = ONE_FP / weight;
 	weight = ONE_FP / inv_w;
@@ -969,10 +979,13 @@
 }
 
 /* Dequeue head packet of the head class in the DRR queue of the aggregate. */
-static void agg_dequeue(struct qfq_aggregate *agg,
-			struct qfq_class *cl, unsigned int len)
+static struct sk_buff *agg_dequeue(struct qfq_aggregate *agg,
+				   struct qfq_class *cl, unsigned int len)
 {
-	qdisc_dequeue_peeked(cl->qdisc);
+	struct sk_buff *skb = qdisc_dequeue_peeked(cl->qdisc);
+
+	if (!skb)
+		return NULL;
 
 	cl->deficit -= (int) len;
 
@@ -982,6 +995,8 @@
 		cl->deficit += agg->lmax;
 		list_move_tail(&cl->alist, &agg->active);
 	}
+
+	return skb;
 }
 
 static inline struct sk_buff *qfq_peek_skb(struct qfq_aggregate *agg,
@@ -1127,11 +1142,18 @@
 	if (!skb)
 		return NULL;
 
-	qdisc_qstats_backlog_dec(sch, skb);
 	sch->q.qlen--;
+
+	skb = agg_dequeue(in_serv_agg, cl, len);
+
+	if (!skb) {
+		sch->q.qlen++;
+		return NULL;
+	}
+
+	qdisc_qstats_backlog_dec(sch, skb);
 	qdisc_bstats_update(sch, skb);
 
-	agg_dequeue(in_serv_agg, cl, len);
 	/* If lmax is lowered, through qfq_change_class, for a class
 	 * owning pending packets with larger size than the new value
 	 * of lmax, then the following condition may hold.
diff --git a/kernel/net/sched/sch_taprio.c b/kernel/net/sched/sch_taprio.c
index 7f33b31..2d842f3 100644
--- a/kernel/net/sched/sch_taprio.c
+++ b/kernel/net/sched/sch_taprio.c
@@ -1621,6 +1621,7 @@
 	int i;
 
 	hrtimer_cancel(&q->advance_timer);
+
 	if (q->qdiscs) {
 		for (i = 0; i < dev->num_tx_queues; i++)
 			if (q->qdiscs[i])
@@ -1642,6 +1643,7 @@
 	 * happens in qdisc_create(), after taprio_init() has been called.
 	 */
 	hrtimer_cancel(&q->advance_timer);
+	qdisc_synchronize(sch);
 
 	taprio_disable_offload(dev, q, NULL);
 
@@ -1904,14 +1906,12 @@
 
 static struct Qdisc *taprio_leaf(struct Qdisc *sch, unsigned long cl)
 {
-	struct taprio_sched *q = qdisc_priv(sch);
-	struct net_device *dev = qdisc_dev(sch);
-	unsigned int ntx = cl - 1;
+	struct netdev_queue *dev_queue = taprio_queue_get(sch, cl);
 
-	if (ntx >= dev->num_tx_queues)
+	if (!dev_queue)
 		return NULL;
 
-	return q->qdiscs[ntx];
+	return dev_queue->qdisc_sleeping;
 }
 
 static unsigned long taprio_find(struct Qdisc *sch, u32 classid)
diff --git a/kernel/net/sctp/associola.c b/kernel/net/sctp/associola.c
index 2d4ec61..765eb61 100644
--- a/kernel/net/sctp/associola.c
+++ b/kernel/net/sctp/associola.c
@@ -1151,8 +1151,7 @@
 		/* Add any peer addresses from the new association. */
 		list_for_each_entry(trans, &new->peer.transport_addr_list,
 				    transports)
-			if (!sctp_assoc_lookup_paddr(asoc, &trans->ipaddr) &&
-			    !sctp_assoc_add_peer(asoc, &trans->ipaddr,
+			if (!sctp_assoc_add_peer(asoc, &trans->ipaddr,
 						 GFP_ATOMIC, trans->state))
 				return -ENOMEM;
 
diff --git a/kernel/net/sctp/bind_addr.c b/kernel/net/sctp/bind_addr.c
index 59e653b..6b95d3b 100644
--- a/kernel/net/sctp/bind_addr.c
+++ b/kernel/net/sctp/bind_addr.c
@@ -73,6 +73,12 @@
 		}
 	}
 
+	/* If somehow no addresses were found that can be used with this
+	 * scope, it's an error.
+	 */
+	if (list_empty(&dest->address_list))
+		error = -ENETUNREACH;
+
 out:
 	if (error)
 		sctp_bind_addr_clean(dest);
diff --git a/kernel/net/sctp/diag.c b/kernel/net/sctp/diag.c
index 68ff82f..07d0ada 100644
--- a/kernel/net/sctp/diag.c
+++ b/kernel/net/sctp/diag.c
@@ -349,11 +349,9 @@
 	struct sctp_comm_param *commp = p;
 	struct sock *sk = ep->base.sk;
 	const struct inet_diag_req_v2 *r = commp->r;
-	struct sctp_association *assoc =
-		list_entry(ep->asocs.next, struct sctp_association, asocs);
 
 	/* find the ep only once through the transports by this condition */
-	if (tsp->asoc != assoc)
+	if (!list_is_first(&tsp->asoc->asocs, &ep->asocs))
 		return 0;
 
 	if (r->sdiag_family != AF_UNSPEC && sk->sk_family != r->sdiag_family)
diff --git a/kernel/net/sctp/proc.c b/kernel/net/sctp/proc.c
index 982a87b..963b945 100644
--- a/kernel/net/sctp/proc.c
+++ b/kernel/net/sctp/proc.c
@@ -284,7 +284,7 @@
 		assoc->init_retries, assoc->shutdown_retries,
 		assoc->rtx_data_chunks,
 		refcount_read(&sk->sk_wmem_alloc),
-		sk->sk_wmem_queued,
+		READ_ONCE(sk->sk_wmem_queued),
 		sk->sk_sndbuf,
 		sk->sk_rcvbuf);
 	seq_printf(seq, "\n");
diff --git a/kernel/net/sctp/sm_sideeffect.c b/kernel/net/sctp/sm_sideeffect.c
index d4e5969..30e9914 100644
--- a/kernel/net/sctp/sm_sideeffect.c
+++ b/kernel/net/sctp/sm_sideeffect.c
@@ -1241,7 +1241,10 @@
 	default:
 		pr_err("impossible disposition %d in state %d, event_type %d, event_id %d\n",
 		       status, state, event_type, subtype.chunk);
-		BUG();
+		error = status;
+		if (error >= 0)
+			error = -EINVAL;
+		WARN_ON_ONCE(1);
 		break;
 	}
 
diff --git a/kernel/net/sctp/sm_statefuns.c b/kernel/net/sctp/sm_statefuns.c
index ee0b2b0..1e82c51 100644
--- a/kernel/net/sctp/sm_statefuns.c
+++ b/kernel/net/sctp/sm_statefuns.c
@@ -4379,7 +4379,7 @@
 				    SCTP_AUTH_NEW_KEY, GFP_ATOMIC);
 
 		if (!ev)
-			return -ENOMEM;
+			return SCTP_DISPOSITION_NOMEM;
 
 		sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
 				SCTP_ULPEVENT(ev));
diff --git a/kernel/net/sctp/socket.c b/kernel/net/sctp/socket.c
index 2fca282..1b4a56f 100644
--- a/kernel/net/sctp/socket.c
+++ b/kernel/net/sctp/socket.c
@@ -68,7 +68,7 @@
 #include <net/sctp/stream_sched.h>
 
 /* Forward declarations for internal helper functions. */
-static bool sctp_writeable(struct sock *sk);
+static bool sctp_writeable(const struct sock *sk);
 static void sctp_wfree(struct sk_buff *skb);
 static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
 				size_t msg_len);
@@ -97,7 +97,7 @@
 
 static void sctp_enter_memory_pressure(struct sock *sk)
 {
-	sctp_memory_pressure = 1;
+	WRITE_ONCE(sctp_memory_pressure, 1);
 }
 
 
@@ -138,7 +138,7 @@
 
 	refcount_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
 	asoc->sndbuf_used += chunk->skb->truesize + sizeof(struct sctp_chunk);
-	sk->sk_wmem_queued += chunk->skb->truesize + sizeof(struct sctp_chunk);
+	sk_wmem_queued_add(sk, chunk->skb->truesize + sizeof(struct sctp_chunk));
 	sk_mem_charge(sk, chunk->skb->truesize);
 }
 
@@ -362,9 +362,9 @@
 	struct net *net = sock_net(&sp->inet.sk);
 
 	if (net->sctp.default_auto_asconf) {
-		spin_lock(&net->sctp.addr_wq_lock);
+		spin_lock_bh(&net->sctp.addr_wq_lock);
 		list_add_tail(&sp->auto_asconf_list, &net->sctp.auto_asconf_splist);
-		spin_unlock(&net->sctp.addr_wq_lock);
+		spin_unlock_bh(&net->sctp.addr_wq_lock);
 		sp->do_auto_asconf = 1;
 	}
 }
@@ -1836,6 +1836,10 @@
 		err = sctp_wait_for_sndbuf(asoc, &timeo, msg_len);
 		if (err)
 			goto err;
+		if (unlikely(sinfo->sinfo_stream >= asoc->stream.outcnt)) {
+			err = -EINVAL;
+			goto err;
+		}
 	}
 
 	if (sctp_state(asoc, CLOSED)) {
@@ -2453,6 +2457,7 @@
 			if (trans) {
 				trans->hbinterval =
 				    msecs_to_jiffies(params->spp_hbinterval);
+				sctp_transport_reset_hb_timer(trans);
 			} else if (asoc) {
 				asoc->hbinterval =
 				    msecs_to_jiffies(params->spp_hbinterval);
@@ -4996,13 +5001,17 @@
 }
 
 /* Triggered when there are no references on the socket anymore */
-static void sctp_destruct_sock(struct sock *sk)
+static void sctp_destruct_common(struct sock *sk)
 {
 	struct sctp_sock *sp = sctp_sk(sk);
 
 	/* Free up the HMAC transform. */
 	crypto_free_shash(sp->hmac);
+}
 
+static void sctp_destruct_sock(struct sock *sk)
+{
+	sctp_destruct_common(sk);
 	inet_sock_destruct(sk);
 }
 
@@ -8881,7 +8890,7 @@
 	struct sock *sk = asoc->base.sk;
 
 	sk_mem_uncharge(sk, skb->truesize);
-	sk->sk_wmem_queued -= skb->truesize + sizeof(struct sctp_chunk);
+	sk_wmem_queued_add(sk, -(skb->truesize + sizeof(struct sctp_chunk)));
 	asoc->sndbuf_used -= skb->truesize + sizeof(struct sctp_chunk);
 	WARN_ON(refcount_sub_and_test(sizeof(struct sctp_chunk),
 				      &sk->sk_wmem_alloc));
@@ -9036,9 +9045,9 @@
  * UDP-style sockets or TCP-style sockets, this code should work.
  *  - Daisy
  */
-static bool sctp_writeable(struct sock *sk)
+static bool sctp_writeable(const struct sock *sk)
 {
-	return sk->sk_sndbuf > sk->sk_wmem_queued;
+	return READ_ONCE(sk->sk_sndbuf) > READ_ONCE(sk->sk_wmem_queued);
 }
 
 /* Wait for an association to go into ESTABLISHED state. If timeout is 0,
@@ -9196,7 +9205,7 @@
 	sctp_sk(newsk)->reuse = sp->reuse;
 
 	newsk->sk_shutdown = sk->sk_shutdown;
-	newsk->sk_destruct = sctp_destruct_sock;
+	newsk->sk_destruct = sk->sk_destruct;
 	newsk->sk_family = sk->sk_family;
 	newsk->sk_protocol = IPPROTO_SCTP;
 	newsk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
@@ -9428,11 +9437,20 @@
 
 #if IS_ENABLED(CONFIG_IPV6)
 
-#include <net/transp_v6.h>
-static void sctp_v6_destroy_sock(struct sock *sk)
+static void sctp_v6_destruct_sock(struct sock *sk)
 {
-	sctp_destroy_sock(sk);
-	inet6_destroy_sock(sk);
+	sctp_destruct_common(sk);
+	inet6_sock_destruct(sk);
+}
+
+static int sctp_v6_init_sock(struct sock *sk)
+{
+	int ret = sctp_init_sock(sk);
+
+	if (!ret)
+		sk->sk_destruct = sctp_v6_destruct_sock;
+
+	return ret;
 }
 
 struct proto sctpv6_prot = {
@@ -9442,8 +9460,8 @@
 	.disconnect	= sctp_disconnect,
 	.accept		= sctp_accept,
 	.ioctl		= sctp_ioctl,
-	.init		= sctp_init_sock,
-	.destroy	= sctp_v6_destroy_sock,
+	.init		= sctp_v6_init_sock,
+	.destroy	= sctp_destroy_sock,
 	.shutdown	= sctp_shutdown,
 	.setsockopt	= sctp_setsockopt,
 	.getsockopt	= sctp_getsockopt,
diff --git a/kernel/net/sctp/stream_interleave.c b/kernel/net/sctp/stream_interleave.c
index 6b13f73..e3aad75 100644
--- a/kernel/net/sctp/stream_interleave.c
+++ b/kernel/net/sctp/stream_interleave.c
@@ -1162,7 +1162,8 @@
 
 #define _sctp_walk_ifwdtsn(pos, chunk, end) \
 	for (pos = chunk->subh.ifwdtsn_hdr->skip; \
-	     (void *)pos < (void *)chunk->subh.ifwdtsn_hdr->skip + (end); pos++)
+	     (void *)pos <= (void *)chunk->subh.ifwdtsn_hdr->skip + (end) - \
+			    sizeof(struct sctp_ifwdtsn_skip); pos++)
 
 #define sctp_walk_ifwdtsn(pos, ch) \
 	_sctp_walk_ifwdtsn((pos), (ch), ntohs((ch)->chunk_hdr->length) - \
diff --git a/kernel/net/sctp/stream_sched_prio.c b/kernel/net/sctp/stream_sched_prio.c
index 4fc9f29..7dd9f8b 100644
--- a/kernel/net/sctp/stream_sched_prio.c
+++ b/kernel/net/sctp/stream_sched_prio.c
@@ -25,6 +25,18 @@
 
 static void sctp_sched_prio_unsched_all(struct sctp_stream *stream);
 
+static struct sctp_stream_priorities *sctp_sched_prio_head_get(struct sctp_stream_priorities *p)
+{
+	p->users++;
+	return p;
+}
+
+static void sctp_sched_prio_head_put(struct sctp_stream_priorities *p)
+{
+	if (p && --p->users == 0)
+		kfree(p);
+}
+
 static struct sctp_stream_priorities *sctp_sched_prio_new_head(
 			struct sctp_stream *stream, int prio, gfp_t gfp)
 {
@@ -38,6 +50,7 @@
 	INIT_LIST_HEAD(&p->active);
 	p->next = NULL;
 	p->prio = prio;
+	p->users = 1;
 
 	return p;
 }
@@ -53,7 +66,7 @@
 	 */
 	list_for_each_entry(p, &stream->prio_list, prio_sched) {
 		if (p->prio == prio)
-			return p;
+			return sctp_sched_prio_head_get(p);
 		if (p->prio > prio)
 			break;
 	}
@@ -70,7 +83,7 @@
 			 */
 			break;
 		if (p->prio == prio)
-			return p;
+			return sctp_sched_prio_head_get(p);
 	}
 
 	/* If not even there, allocate a new one. */
@@ -154,32 +167,21 @@
 	struct sctp_stream_out_ext *soute = sout->ext;
 	struct sctp_stream_priorities *prio_head, *old;
 	bool reschedule = false;
-	int i;
+
+	old = soute->prio_head;
+	if (old && old->prio == prio)
+		return 0;
 
 	prio_head = sctp_sched_prio_get_head(stream, prio, gfp);
 	if (!prio_head)
 		return -ENOMEM;
 
 	reschedule = sctp_sched_prio_unsched(soute);
-	old = soute->prio_head;
 	soute->prio_head = prio_head;
 	if (reschedule)
 		sctp_sched_prio_sched(stream, soute);
 
-	if (!old)
-		/* Happens when we set the priority for the first time */
-		return 0;
-
-	for (i = 0; i < stream->outcnt; i++) {
-		soute = SCTP_SO(stream, i)->ext;
-		if (soute && soute->prio_head == old)
-			/* It's still in use, nothing else to do here. */
-			return 0;
-	}
-
-	/* No hits, we are good to free it. */
-	kfree(old);
-
+	sctp_sched_prio_head_put(old);
 	return 0;
 }
 
@@ -206,20 +208,8 @@
 
 static void sctp_sched_prio_free_sid(struct sctp_stream *stream, __u16 sid)
 {
-	struct sctp_stream_priorities *prio = SCTP_SO(stream, sid)->ext->prio_head;
-	int i;
-
-	if (!prio)
-		return;
-
+	sctp_sched_prio_head_put(SCTP_SO(stream, sid)->ext->prio_head);
 	SCTP_SO(stream, sid)->ext->prio_head = NULL;
-	for (i = 0; i < stream->outcnt; i++) {
-		if (SCTP_SO(stream, i)->ext &&
-		    SCTP_SO(stream, i)->ext->prio_head == prio)
-			return;
-	}
-
-	kfree(prio);
 }
 
 static void sctp_sched_prio_free(struct sctp_stream *stream)
diff --git a/kernel/net/sctp/sysctl.c b/kernel/net/sctp/sysctl.c
index c16c809..e4af050 100644
--- a/kernel/net/sctp/sysctl.c
+++ b/kernel/net/sctp/sysctl.c
@@ -79,17 +79,18 @@
 	{ /* 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,13 +99,40 @@
 		.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),
 		.mode		= 0644,
 		.proc_handler	= proc_sctp_do_rto_max,
 		.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
 	},
 	{
@@ -201,24 +229,6 @@
 		.proc_handler	= proc_dointvec_minmax,
 		.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",
@@ -489,6 +499,11 @@
 	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);
diff --git a/kernel/net/smc/af_smc.c b/kernel/net/smc/af_smc.c
index 41cbc7c..8ab8492 100644
--- a/kernel/net/smc/af_smc.c
+++ b/kernel/net/smc/af_smc.c
@@ -1988,16 +1988,14 @@
 {
 	struct sock *sk = sock->sk;
 	struct smc_sock *smc;
-	int rc = -EPIPE;
+	int rc;
 
 	smc = smc_sk(sk);
 	lock_sock(sk);
-	if ((sk->sk_state != SMC_ACTIVE) &&
-	    (sk->sk_state != SMC_APPCLOSEWAIT1) &&
-	    (sk->sk_state != SMC_INIT))
-		goto out;
 
+	/* SMC does not support connect with fastopen */
 	if (msg->msg_flags & MSG_FASTOPEN) {
+		/* not connected yet, fallback */
 		if (sk->sk_state == SMC_INIT && !smc->connect_nonblock) {
 			smc_switch_to_fallback(smc);
 			smc->fallback_rsn = SMC_CLC_DECL_OPTUNSUPP;
@@ -2005,6 +2003,11 @@
 			rc = -EINVAL;
 			goto out;
 		}
+	} else if ((sk->sk_state != SMC_ACTIVE) &&
+		   (sk->sk_state != SMC_APPCLOSEWAIT1) &&
+		   (sk->sk_state != SMC_INIT)) {
+		rc = -EPIPE;
+		goto out;
 	}
 
 	if (smc->use_fallback)
diff --git a/kernel/net/smc/smc_cdc.c b/kernel/net/smc/smc_cdc.c
index 94503f3..9125d28 100644
--- a/kernel/net/smc/smc_cdc.c
+++ b/kernel/net/smc/smc_cdc.c
@@ -104,6 +104,9 @@
 	union smc_host_cursor cfed;
 	int rc;
 
+	if (unlikely(!READ_ONCE(conn->sndbuf_desc)))
+		return -ENOBUFS;
+
 	smc_cdc_add_pending_send(conn, pend);
 
 	conn->tx_cdc_seq++;
diff --git a/kernel/net/smc/smc_close.c b/kernel/net/smc/smc_close.c
index 84102db..149a59e 100644
--- a/kernel/net/smc/smc_close.c
+++ b/kernel/net/smc/smc_close.c
@@ -64,8 +64,8 @@
 
 		rc = sk_wait_event(sk, &timeout,
 				   !smc_tx_prepared_sends(&smc->conn) ||
-				   sk->sk_err == ECONNABORTED ||
-				   sk->sk_err == ECONNRESET ||
+				   READ_ONCE(sk->sk_err) == ECONNABORTED ||
+				   READ_ONCE(sk->sk_err) == ECONNRESET ||
 				   smc->conn.killed,
 				   &wait);
 		if (rc)
diff --git a/kernel/net/smc/smc_core.c b/kernel/net/smc/smc_core.c
index bf485a2..ab9ecdd 100644
--- a/kernel/net/smc/smc_core.c
+++ b/kernel/net/smc/smc_core.c
@@ -912,7 +912,7 @@
 	if (lgr->terminating)
 		return;	/* lgr already terminating */
 	/* cancel free_work sync, will terminate when lgr->freeing is set */
-	cancel_delayed_work_sync(&lgr->free_work);
+	cancel_delayed_work(&lgr->free_work);
 	lgr->terminating = 1;
 
 	/* kill remaining link group connections */
@@ -1101,6 +1101,7 @@
 {
 	struct smc_link_group *lgr, *n;
 
+	spin_lock_bh(&smc_lgr_list.lock);
 	list_for_each_entry_safe(lgr, n, &smc_lgr_list.list, list) {
 		struct smc_link *link;
 
@@ -1115,6 +1116,7 @@
 		if (link)
 			smc_llc_add_link_local(link);
 	}
+	spin_unlock_bh(&smc_lgr_list.lock);
 }
 
 /* link is down - switch connections to alternate link,
diff --git a/kernel/net/smc/smc_llc.c b/kernel/net/smc/smc_llc.c
index 0ef15f8..d5ee961 100644
--- a/kernel/net/smc/smc_llc.c
+++ b/kernel/net/smc/smc_llc.c
@@ -716,6 +716,8 @@
 	addc_llc->num_rkeys = *num_rkeys_todo;
 	n = *num_rkeys_todo;
 	for (i = 0; i < min_t(u8, n, SMC_LLC_RKEYS_PER_CONT_MSG); i++) {
+		while (*buf_pos && !(*buf_pos)->used)
+			*buf_pos = smc_llc_get_next_rmb(lgr, buf_lst, *buf_pos);
 		if (!*buf_pos) {
 			addc_llc->num_rkeys = addc_llc->num_rkeys -
 					      *num_rkeys_todo;
@@ -731,8 +733,6 @@
 
 		(*num_rkeys_todo)--;
 		*buf_pos = smc_llc_get_next_rmb(lgr, buf_lst, *buf_pos);
-		while (*buf_pos && !(*buf_pos)->used)
-			*buf_pos = smc_llc_get_next_rmb(lgr, buf_lst, *buf_pos);
 	}
 	addc_llc->hd.common.type = SMC_LLC_ADD_LINK_CONT;
 	addc_llc->hd.length = sizeof(struct smc_llc_msg_add_link_cont);
diff --git a/kernel/net/smc/smc_rx.c b/kernel/net/smc/smc_rx.c
index 7f7e983..3757aff 100644
--- a/kernel/net/smc/smc_rx.c
+++ b/kernel/net/smc/smc_rx.c
@@ -203,9 +203,9 @@
 	sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
 	add_wait_queue(sk_sleep(sk), &wait);
 	rc = sk_wait_event(sk, timeo,
-			   sk->sk_err ||
+			   READ_ONCE(sk->sk_err) ||
 			   cflags->peer_conn_abort ||
-			   sk->sk_shutdown & RCV_SHUTDOWN ||
+			   READ_ONCE(sk->sk_shutdown) & RCV_SHUTDOWN ||
 			   conn->killed ||
 			   fcrit(conn),
 			   &wait);
diff --git a/kernel/net/smc/smc_tx.c b/kernel/net/smc/smc_tx.c
index 52ef1fc..2429f9f 100644
--- a/kernel/net/smc/smc_tx.c
+++ b/kernel/net/smc/smc_tx.c
@@ -110,8 +110,8 @@
 			break; /* at least 1 byte of free & no urgent data */
 		set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
 		sk_wait_event(sk, &timeo,
-			      sk->sk_err ||
-			      (sk->sk_shutdown & SEND_SHUTDOWN) ||
+			      READ_ONCE(sk->sk_err) ||
+			      (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) ||
 			      smc_cdc_rxed_any_close(conn) ||
 			      (atomic_read(&conn->sndbuf_space) &&
 			       !conn->urg_tx_pend),
diff --git a/kernel/net/socket.c b/kernel/net/socket.c
index 938ab3a..7e25598 100644
--- a/kernel/net/socket.c
+++ b/kernel/net/socket.c
@@ -656,6 +656,14 @@
 	return ret;
 }
 
+static int __sock_sendmsg(struct socket *sock, struct msghdr *msg)
+{
+	int err = security_socket_sendmsg(sock, msg,
+					  msg_data_left(msg));
+
+	return err ?: sock_sendmsg_nosec(sock, msg);
+}
+
 /**
  *	sock_sendmsg - send a message through @sock
  *	@sock: socket
@@ -666,10 +674,19 @@
  */
 int sock_sendmsg(struct socket *sock, struct msghdr *msg)
 {
-	int err = security_socket_sendmsg(sock, msg,
-					  msg_data_left(msg));
+	struct sockaddr_storage *save_addr = (struct sockaddr_storage *)msg->msg_name;
+	struct sockaddr_storage address;
+	int ret;
 
-	return err ?: sock_sendmsg_nosec(sock, msg);
+	if (msg->msg_name) {
+		memcpy(&address, msg->msg_name, msg->msg_namelen);
+		msg->msg_name = &address;
+	}
+
+	ret = __sock_sendmsg(sock, msg);
+	msg->msg_name = save_addr;
+
+	return ret;
 }
 EXPORT_SYMBOL(sock_sendmsg);
 
@@ -996,7 +1013,7 @@
 	if (sock->type == SOCK_SEQPACKET)
 		msg.msg_flags |= MSG_EOR;
 
-	res = sock_sendmsg(sock, &msg);
+	res = __sock_sendmsg(sock, &msg);
 	*from = msg.msg_iter;
 	return res;
 }
@@ -1984,7 +2001,7 @@
 	if (sock->file->f_flags & O_NONBLOCK)
 		flags |= MSG_DONTWAIT;
 	msg.msg_flags = flags;
-	err = sock_sendmsg(sock, &msg);
+	err = __sock_sendmsg(sock, &msg);
 
 out_put:
 	fput_light(sock->file, fput_needed);
@@ -2354,7 +2371,7 @@
 		err = sock_sendmsg_nosec(sock, msg_sys);
 		goto out_freectl;
 	}
-	err = sock_sendmsg(sock, msg_sys);
+	err = __sock_sendmsg(sock, msg_sys);
 	/*
 	 * If this is sendmmsg() and sending to current destination address was
 	 * successful, remember it.
@@ -2765,7 +2782,7 @@
 		 * error to return on the next call or if the
 		 * app asks about it using getsockopt(SO_ERROR).
 		 */
-		sock->sk->sk_err = -err;
+		WRITE_ONCE(sock->sk->sk_err, -err);
 	}
 out_put:
 	fput_light(sock->file, fput_needed);
@@ -3465,7 +3482,11 @@
 int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
 		   int flags)
 {
-	return sock->ops->connect(sock, addr, addrlen, flags);
+	struct sockaddr_storage address;
+
+	memcpy(&address, addr, addrlen);
+
+	return sock->ops->connect(sock, (struct sockaddr *)&address, addrlen, flags);
 }
 EXPORT_SYMBOL(kernel_connect);
 
diff --git a/kernel/net/sunrpc/auth_gss/auth_gss.c b/kernel/net/sunrpc/auth_gss/auth_gss.c
index 5f42aa5..2ff66a6 100644
--- a/kernel/net/sunrpc/auth_gss/auth_gss.c
+++ b/kernel/net/sunrpc/auth_gss/auth_gss.c
@@ -301,7 +301,7 @@
 	list_for_each_entry(pos, &pipe->in_downcall, list) {
 		if (!uid_eq(pos->uid, uid))
 			continue;
-		if (auth && pos->auth->service != auth->service)
+		if (pos->auth->service != auth->service)
 			continue;
 		refcount_inc(&pos->count);
 		return pos;
@@ -685,6 +685,21 @@
 	return err;
 }
 
+static struct gss_upcall_msg *
+gss_find_downcall(struct rpc_pipe *pipe, kuid_t uid)
+{
+	struct gss_upcall_msg *pos;
+	list_for_each_entry(pos, &pipe->in_downcall, list) {
+		if (!uid_eq(pos->uid, uid))
+			continue;
+		if (!rpc_msg_is_inflight(&pos->msg))
+			continue;
+		refcount_inc(&pos->count);
+		return pos;
+	}
+	return NULL;
+}
+
 #define MSG_BUF_MAXSIZE 1024
 
 static ssize_t
@@ -731,7 +746,7 @@
 	err = -ENOENT;
 	/* Find a matching upcall */
 	spin_lock(&pipe->lock);
-	gss_msg = __gss_find_upcall(pipe, uid, NULL);
+	gss_msg = gss_find_downcall(pipe, uid);
 	if (gss_msg == NULL) {
 		spin_unlock(&pipe->lock);
 		goto err_put_ctx;
diff --git a/kernel/net/sunrpc/auth_gss/svcauth_gss.c b/kernel/net/sunrpc/auth_gss/svcauth_gss.c
index f5111d6..406ff7f 100644
--- a/kernel/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/kernel/net/sunrpc/auth_gss/svcauth_gss.c
@@ -1156,18 +1156,23 @@
 		return res;
 
 	inlen = svc_getnl(argv);
-	if (inlen > (argv->iov_len + rqstp->rq_arg.page_len))
+	if (inlen > (argv->iov_len + rqstp->rq_arg.page_len)) {
+		kfree(in_handle->data);
 		return SVC_DENIED;
+	}
 
 	pages = DIV_ROUND_UP(inlen, PAGE_SIZE);
 	in_token->pages = kcalloc(pages, sizeof(struct page *), GFP_KERNEL);
-	if (!in_token->pages)
+	if (!in_token->pages) {
+		kfree(in_handle->data);
 		return SVC_DENIED;
+	}
 	in_token->page_base = 0;
 	in_token->page_len = inlen;
 	for (i = 0; i < pages; i++) {
 		in_token->pages[i] = alloc_page(GFP_KERNEL);
 		if (!in_token->pages[i]) {
+			kfree(in_handle->data);
 			gss_free_in_token_pages(in_token);
 			return SVC_DENIED;
 		}
diff --git a/kernel/net/sunrpc/clnt.c b/kernel/net/sunrpc/clnt.c
index 78c6648..c7c1754 100644
--- a/kernel/net/sunrpc/clnt.c
+++ b/kernel/net/sunrpc/clnt.c
@@ -1361,7 +1361,7 @@
 		break;
 	default:
 		err = -EAFNOSUPPORT;
-		goto out;
+		goto out_release;
 	}
 	if (err < 0) {
 		dprintk("RPC:       can't bind UDP socket (%d)\n", err);
@@ -1967,9 +1967,6 @@
 			status = -EOPNOTSUPP;
 			break;
 		}
-		if (task->tk_rebind_retry == 0)
-			break;
-		task->tk_rebind_retry--;
 		rpc_delay(task, 3*HZ);
 		goto retry_timeout;
 	case -ENOBUFS:
@@ -2357,8 +2354,7 @@
 		goto out_exit;
 	}
 	task->tk_action = call_encode;
-	if (status != -ECONNRESET && status != -ECONNABORTED)
-		rpc_check_timeout(task);
+	rpc_check_timeout(task);
 	return;
 out_exit:
 	rpc_call_rpcerror(task, status);
@@ -2633,6 +2629,7 @@
 	case rpc_autherr_rejectedverf:
 	case rpcsec_gsserr_credproblem:
 	case rpcsec_gsserr_ctxproblem:
+		rpcauth_invalcred(task);
 		if (!task->tk_cred_retry)
 			break;
 		task->tk_cred_retry--;
@@ -3026,6 +3023,8 @@
 int
 rpc_clnt_swap_activate(struct rpc_clnt *clnt)
 {
+	while (clnt != clnt->cl_parent)
+		clnt = clnt->cl_parent;
 	if (atomic_inc_return(&clnt->cl_swapper) == 1)
 		return rpc_clnt_iterate_for_each_xprt(clnt,
 				rpc_clnt_swap_activate_callback, NULL);
@@ -3045,6 +3044,8 @@
 void
 rpc_clnt_swap_deactivate(struct rpc_clnt *clnt)
 {
+	while (clnt != clnt->cl_parent)
+		clnt = clnt->cl_parent;
 	if (atomic_dec_if_positive(&clnt->cl_swapper) == 0)
 		rpc_clnt_iterate_for_each_xprt(clnt,
 				rpc_clnt_swap_deactivate_callback, NULL);
diff --git a/kernel/net/sunrpc/sched.c b/kernel/net/sunrpc/sched.c
index f0f55fb..a008909 100644
--- a/kernel/net/sunrpc/sched.c
+++ b/kernel/net/sunrpc/sched.c
@@ -796,7 +796,6 @@
 	/* Initialize retry counters */
 	task->tk_garb_retry = 2;
 	task->tk_cred_retry = 2;
-	task->tk_rebind_retry = 2;
 
 	/* starting timestamp */
 	task->tk_start = ktime_get();
diff --git a/kernel/net/sunrpc/svc.c b/kernel/net/sunrpc/svc.c
index d38788c..495ebe7 100644
--- a/kernel/net/sunrpc/svc.c
+++ b/kernel/net/sunrpc/svc.c
@@ -800,6 +800,7 @@
 static int
 svc_stop_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
 {
+	struct svc_rqst	*rqstp;
 	struct task_struct *task;
 	unsigned int state = serv->sv_nrthreads-1;
 
@@ -808,7 +809,10 @@
 		task = choose_victim(serv, pool, &state);
 		if (task == NULL)
 			break;
-		kthread_stop(task);
+		rqstp = kthread_data(task);
+		/* Did we lose a race to svo_function threadfn? */
+		if (kthread_stop(task) == -EINTR)
+			svc_exit_thread(rqstp);
 		nrservs++;
 	} while (nrservs < 0);
 	return 0;
@@ -991,7 +995,7 @@
 #endif
 	}
 
-	trace_svc_register(progname, version, protocol, port, family, error);
+	trace_svc_register(progname, version, family, protocol, port, error);
 	return error;
 }
 
diff --git a/kernel/net/sunrpc/svcauth_unix.c b/kernel/net/sunrpc/svcauth_unix.c
index 97c0bdd..60754a2 100644
--- a/kernel/net/sunrpc/svcauth_unix.c
+++ b/kernel/net/sunrpc/svcauth_unix.c
@@ -424,14 +424,23 @@
 	return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS);
 }
 
+static void unix_gid_free(struct rcu_head *rcu)
+{
+	struct unix_gid *ug = container_of(rcu, struct unix_gid, rcu);
+	struct cache_head *item = &ug->h;
+
+	if (test_bit(CACHE_VALID, &item->flags) &&
+	    !test_bit(CACHE_NEGATIVE, &item->flags))
+		put_group_info(ug->gi);
+	kfree(ug);
+}
+
 static void unix_gid_put(struct kref *kref)
 {
 	struct cache_head *item = container_of(kref, struct cache_head, ref);
 	struct unix_gid *ug = container_of(item, struct unix_gid, h);
-	if (test_bit(CACHE_VALID, &item->flags) &&
-	    !test_bit(CACHE_NEGATIVE, &item->flags))
-		put_group_info(ug->gi);
-	kfree_rcu(ug, rcu);
+
+	call_rcu(&ug->rcu, unix_gid_free);
 }
 
 static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew)
diff --git a/kernel/net/sunrpc/svcsock.c b/kernel/net/sunrpc/svcsock.c
index 6d5bb8b..3d5ee04 100644
--- a/kernel/net/sunrpc/svcsock.c
+++ b/kernel/net/sunrpc/svcsock.c
@@ -692,12 +692,6 @@
 {
 	struct svc_sock	*svsk = (struct svc_sock *)sk->sk_user_data;
 
-	if (svsk) {
-		/* Refer to svc_setup_socket() for details. */
-		rmb();
-		svsk->sk_odata(sk);
-	}
-
 	/*
 	 * This callback may called twice when a new connection
 	 * is established as a child socket inherits everything
@@ -706,13 +700,18 @@
 	 *    when one of child sockets become ESTABLISHED.
 	 * 2) data_ready method of the child socket may be called
 	 *    when it receives data before the socket is accepted.
-	 * In case of 2, we should ignore it silently.
+	 * In case of 2, we should ignore it silently and DO NOT
+	 * dereference svsk.
 	 */
-	if (sk->sk_state == TCP_LISTEN) {
-		if (svsk) {
-			set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags);
-			svc_xprt_enqueue(&svsk->sk_xprt);
-		}
+	if (sk->sk_state != TCP_LISTEN)
+		return;
+
+	if (svsk) {
+		/* Refer to svc_setup_socket() for details. */
+		rmb();
+		svsk->sk_odata(sk);
+		set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags);
+		svc_xprt_enqueue(&svsk->sk_xprt);
 	}
 }
 
diff --git a/kernel/net/sunrpc/xprtrdma/verbs.c b/kernel/net/sunrpc/xprtrdma/verbs.c
index dcc1992..d015576 100644
--- a/kernel/net/sunrpc/xprtrdma/verbs.c
+++ b/kernel/net/sunrpc/xprtrdma/verbs.c
@@ -866,7 +866,7 @@
 	return req;
 
 out3:
-	kfree(req->rl_sendbuf);
+	rpcrdma_regbuf_free(req->rl_sendbuf);
 out2:
 	kfree(req);
 out1:
@@ -972,9 +972,6 @@
 	if (!rep->rr_rdmabuf)
 		goto out_free;
 
-	if (!rpcrdma_regbuf_dma_map(r_xprt, rep->rr_rdmabuf))
-		goto out_free_regbuf;
-
 	xdr_buf_init(&rep->rr_hdrbuf, rdmab_data(rep->rr_rdmabuf),
 		     rdmab_length(rep->rr_rdmabuf));
 	rep->rr_cqe.done = rpcrdma_wc_receive;
@@ -987,8 +984,6 @@
 	list_add(&rep->rr_all, &r_xprt->rx_buf.rb_all_reps);
 	return rep;
 
-out_free_regbuf:
-	rpcrdma_regbuf_free(rep->rr_rdmabuf);
 out_free:
 	kfree(rep);
 out:
@@ -1425,6 +1420,10 @@
 			rep = rpcrdma_rep_create(r_xprt, temp);
 		if (!rep)
 			break;
+		if (!rpcrdma_regbuf_dma_map(r_xprt, rep->rr_rdmabuf)) {
+			rpcrdma_rep_put(buf, rep);
+			break;
+		}
 
 		trace_xprtrdma_post_recv(rep);
 		rep->rr_recv_wr.next = wr;
diff --git a/kernel/net/tipc/bearer.c b/kernel/net/tipc/bearer.c
index 72c31ef..43bfe8a 100644
--- a/kernel/net/tipc/bearer.c
+++ b/kernel/net/tipc/bearer.c
@@ -1229,7 +1229,7 @@
 	struct tipc_nl_msg msg;
 	struct tipc_media *media;
 	struct sk_buff *rep;
-	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
+	struct nlattr *attrs[TIPC_NLA_MEDIA_MAX + 1];
 
 	if (!info->attrs[TIPC_NLA_MEDIA])
 		return -EINVAL;
@@ -1278,7 +1278,7 @@
 	int err;
 	char *name;
 	struct tipc_media *m;
-	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
+	struct nlattr *attrs[TIPC_NLA_MEDIA_MAX + 1];
 
 	if (!info->attrs[TIPC_NLA_MEDIA])
 		return -EINVAL;
diff --git a/kernel/net/tipc/bearer.h b/kernel/net/tipc/bearer.h
index bc00231..6bf4550 100644
--- a/kernel/net/tipc/bearer.h
+++ b/kernel/net/tipc/bearer.h
@@ -93,7 +93,8 @@
  * @raw2addr: convert from raw addr format to media addr format
  * @priority: default link (and bearer) priority
  * @tolerance: default time (in ms) before declaring link failure
- * @window: default window (in packets) before declaring link congestion
+ * @min_win: minimum window (in packets) before declaring link congestion
+ * @max_win: maximum window (in packets) before declaring link congestion
  * @mtu: max packet size bearer can support for media type not dependent on
  * underlying device MTU
  * @type_id: TIPC media identifier
@@ -138,12 +139,15 @@
  * @pt: packet type for bearer
  * @rcu: rcu struct for tipc_bearer
  * @priority: default link priority for bearer
- * @window: default window size for bearer
+ * @min_win: minimum window (in packets) before declaring link congestion
+ * @max_win: maximum window (in packets) before declaring link congestion
  * @tolerance: default link tolerance for bearer
  * @domain: network domain to which links can be established
  * @identity: array index of this bearer within TIPC bearer array
- * @link_req: ptr to (optional) structure making periodic link setup requests
+ * @disc: ptr to link setup request
  * @net_plane: network plane ('A' through 'H') currently associated with bearer
+ * @up: bearer up flag (bit 0)
+ * @refcnt: tipc_bearer reference counter
  *
  * Note: media-specific code is responsible for initialization of the fields
  * indicated below when a bearer is enabled; TIPC's generic bearer code takes
diff --git a/kernel/net/tipc/crypto.c b/kernel/net/tipc/crypto.c
index de63d6d..b5aa0a8 100644
--- a/kernel/net/tipc/crypto.c
+++ b/kernel/net/tipc/crypto.c
@@ -1445,14 +1445,14 @@
 	struct tipc_crypto *tx = tipc_net(net)->crypto_tx;
 	struct tipc_key key;
 
-	spin_lock(&tx->lock);
+	spin_lock_bh(&tx->lock);
 	key = tx->key;
 	WARN_ON(!key.active || tx_key != key.active);
 
 	/* Free the active key */
 	tipc_crypto_key_set_state(tx, key.passive, 0, key.pending);
 	tipc_crypto_key_detach(tx->aead[key.active], &tx->lock);
-	spin_unlock(&tx->lock);
+	spin_unlock_bh(&tx->lock);
 
 	pr_warn("%s: key is revoked\n", tx->name);
 	return -EKEYREVOKED;
@@ -1964,7 +1964,8 @@
 
 	skb_reset_network_header(*skb);
 	skb_pull(*skb, tipc_ehdr_size(ehdr));
-	pskb_trim(*skb, (*skb)->len - aead->authsize);
+	if (pskb_trim(*skb, (*skb)->len - aead->authsize))
+		goto free_skb;
 
 	/* Validate TIPCv2 message */
 	if (unlikely(!tipc_msg_validate(skb))) {
diff --git a/kernel/net/tipc/crypto.h b/kernel/net/tipc/crypto.h
index e71193b..ce7d4cc 100644
--- a/kernel/net/tipc/crypto.h
+++ b/kernel/net/tipc/crypto.h
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-/**
+/*
  * net/tipc/crypto.h: Include file for TIPC crypto
  *
  * Copyright (c) 2019, Ericsson AB
@@ -53,7 +53,7 @@
 #define TIPC_AES_GCM_IV_SIZE		12
 #define TIPC_AES_GCM_TAG_SIZE		16
 
-/**
+/*
  * TIPC crypto modes:
  * - CLUSTER_KEY:
  *	One single key is used for both TX & RX in all nodes in the cluster.
@@ -69,7 +69,7 @@
 extern int sysctl_tipc_max_tfms __read_mostly;
 extern int sysctl_tipc_key_exchange_enabled __read_mostly;
 
-/**
+/*
  * TIPC encryption message format:
  *
  *     3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
diff --git a/kernel/net/tipc/name_distr.h b/kernel/net/tipc/name_distr.h
index 0923231..e231e69 100644
--- a/kernel/net/tipc/name_distr.h
+++ b/kernel/net/tipc/name_distr.h
@@ -46,7 +46,7 @@
  * @type: name sequence type
  * @lower: name sequence lower bound
  * @upper: name sequence upper bound
- * @ref: publishing port reference
+ * @port: publishing port reference
  * @key: publication key
  *
  * ===> All fields are stored in network byte order. <===
diff --git a/kernel/net/tipc/name_table.h b/kernel/net/tipc/name_table.h
index 8064e19..5a82a01 100644
--- a/kernel/net/tipc/name_table.h
+++ b/kernel/net/tipc/name_table.h
@@ -60,8 +60,8 @@
  * @key: publication key, unique across the cluster
  * @id: publication id
  * @binding_node: all publications from the same node which bound this one
- * - Remote publications: in node->publ_list
- *   Used by node/name distr to withdraw publications when node is lost
+ * - Remote publications: in node->publ_list;
+ * Used by node/name distr to withdraw publications when node is lost
  * - Local/node scope publications: in name_table->node_scope list
  * - Local/cluster scope publications: in name_table->cluster_scope list
  * @binding_sock: all publications from the same socket which bound this one
@@ -92,13 +92,16 @@
 
 /**
  * struct name_table - table containing all existing port name publications
- * @seq_hlist: name sequence hash lists
+ * @services: name sequence hash lists
  * @node_scope: all local publications with node scope
  *               - used by name_distr during re-init of name table
  * @cluster_scope: all local publications with cluster scope
  *               - used by name_distr to send bulk updates to new nodes
  *               - used by name_distr during re-init of name table
+ * @cluster_scope_lock: lock for accessing @cluster_scope
  * @local_publ_count: number of publications issued by this node
+ * @rc_dests: destination node counter
+ * @snd_nxt: next sequence number to be used
  */
 struct name_table {
 	struct hlist_head services[TIPC_NAMETBL_SIZE];
diff --git a/kernel/net/tipc/node.c b/kernel/net/tipc/node.c
index 7589f2a..9e3cfeb 100644
--- a/kernel/net/tipc/node.c
+++ b/kernel/net/tipc/node.c
@@ -567,7 +567,7 @@
 				 n->capabilities, &n->bc_entry.inputq1,
 				 &n->bc_entry.namedq, snd_l, &n->bc_entry.link)) {
 		pr_warn("Broadcast rcv link creation failed, no memory\n");
-		kfree(n);
+		tipc_node_put(n);
 		n = NULL;
 		goto exit;
 	}
@@ -1152,8 +1152,9 @@
 	bool addr_match = false;
 	bool sign_match = false;
 	bool link_up = false;
+	bool link_is_reset = false;
 	bool accept_addr = false;
-	bool reset = true;
+	bool reset = false;
 	char *if_name;
 	unsigned long intv;
 	u16 session;
@@ -1173,14 +1174,14 @@
 	/* Prepare to validate requesting node's signature and media address */
 	l = le->link;
 	link_up = l && tipc_link_is_up(l);
+	link_is_reset = l && tipc_link_is_reset(l);
 	addr_match = l && !memcmp(&le->maddr, maddr, sizeof(*maddr));
 	sign_match = (signature == n->signature);
 
 	/* These three flags give us eight permutations: */
 
 	if (sign_match && addr_match && link_up) {
-		/* All is fine. Do nothing. */
-		reset = false;
+		/* All is fine. Ignore requests. */
 		/* Peer node is not a container/local namespace */
 		if (!n->peer_hash_mix)
 			n->peer_hash_mix = hash_mixes;
@@ -1205,6 +1206,7 @@
 		 */
 		accept_addr = true;
 		*respond = true;
+		reset = true;
 	} else if (!sign_match && addr_match && link_up) {
 		/* Peer node rebooted. Two possibilities:
 		 *  - Delayed re-discovery; this link endpoint has already
@@ -1236,6 +1238,7 @@
 		n->signature = signature;
 		accept_addr = true;
 		*respond = true;
+		reset = true;
 	}
 
 	if (!accept_addr)
@@ -1264,6 +1267,7 @@
 		tipc_link_fsm_evt(l, LINK_RESET_EVT);
 		if (n->state == NODE_FAILINGOVER)
 			tipc_link_fsm_evt(l, LINK_FAILOVER_BEGIN_EVT);
+		link_is_reset = tipc_link_is_reset(l);
 		le->link = l;
 		n->link_cnt++;
 		tipc_node_calculate_timer(n, l);
@@ -1276,7 +1280,7 @@
 	memcpy(&le->maddr, maddr, sizeof(*maddr));
 exit:
 	tipc_node_write_unlock(n);
-	if (reset && l && !tipc_link_is_reset(l))
+	if (reset && !link_is_reset)
 		tipc_node_link_down(n, b->identity, false);
 	tipc_node_put(n);
 }
diff --git a/kernel/net/tipc/socket.c b/kernel/net/tipc/socket.c
index 8f3c9fb..7cf9b40 100644
--- a/kernel/net/tipc/socket.c
+++ b/kernel/net/tipc/socket.c
@@ -300,9 +300,9 @@
 		tipc_sk_respond(sk, skb, error);
 }
 
-static bool tipc_sk_connected(struct sock *sk)
+static bool tipc_sk_connected(const struct sock *sk)
 {
-	return sk->sk_state == TIPC_ESTABLISHED;
+	return READ_ONCE(sk->sk_state) == TIPC_ESTABLISHED;
 }
 
 /* tipc_sk_type_connectionless - check if the socket is datagram socket
diff --git a/kernel/net/tipc/subscr.h b/kernel/net/tipc/subscr.h
index 6ebbec1..63bdce9 100644
--- a/kernel/net/tipc/subscr.h
+++ b/kernel/net/tipc/subscr.h
@@ -47,12 +47,15 @@
 
 /**
  * struct tipc_subscription - TIPC network topology subscription object
- * @subscriber: pointer to its subscriber
- * @seq: name sequence associated with subscription
+ * @kref: reference count for this subscription
+ * @net: network namespace associated with subscription
  * @timer: timer governing subscription duration (optional)
- * @nameseq_list: adjacent subscriptions in name sequence's subscription list
+ * @service_list: adjacent subscriptions in name sequence's subscription list
  * @sub_list: adjacent subscriptions in subscriber's subscription list
  * @evt: template for events generated by subscription
+ * @conid: connection identifier of topology server
+ * @inactive: true if this subscription is inactive
+ * @lock: serialize up/down and timer events
  */
 struct tipc_subscription {
 	struct kref kref;
@@ -63,7 +66,7 @@
 	struct tipc_event evt;
 	int conid;
 	bool inactive;
-	spinlock_t lock; /* serialize up/down and timer events */
+	spinlock_t lock;
 };
 
 struct tipc_subscription *tipc_sub_subscribe(struct net *net,
diff --git a/kernel/net/tls/tls_main.c b/kernel/net/tls/tls_main.c
index e537085..7ee3c8b 100644
--- a/kernel/net/tls/tls_main.c
+++ b/kernel/net/tls/tls_main.c
@@ -92,7 +92,8 @@
 			break;
 		}
 
-		if (sk_wait_event(sk, timeo, !sk->sk_write_pending, &wait))
+		if (sk_wait_event(sk, timeo,
+				  !READ_ONCE(sk->sk_write_pending), &wait))
 			break;
 	}
 	remove_wait_queue(sk_sleep(sk), &wait);
@@ -386,13 +387,11 @@
 			rc = -EINVAL;
 			goto out;
 		}
-		lock_sock(sk);
 		memcpy(crypto_info_aes_gcm_128->iv,
 		       cctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
 		       TLS_CIPHER_AES_GCM_128_IV_SIZE);
 		memcpy(crypto_info_aes_gcm_128->rec_seq, cctx->rec_seq,
 		       TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
-		release_sock(sk);
 		if (copy_to_user(optval,
 				 crypto_info_aes_gcm_128,
 				 sizeof(*crypto_info_aes_gcm_128)))
@@ -410,13 +409,11 @@
 			rc = -EINVAL;
 			goto out;
 		}
-		lock_sock(sk);
 		memcpy(crypto_info_aes_gcm_256->iv,
 		       cctx->iv + TLS_CIPHER_AES_GCM_256_SALT_SIZE,
 		       TLS_CIPHER_AES_GCM_256_IV_SIZE);
 		memcpy(crypto_info_aes_gcm_256->rec_seq, cctx->rec_seq,
 		       TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
-		release_sock(sk);
 		if (copy_to_user(optval,
 				 crypto_info_aes_gcm_256,
 				 sizeof(*crypto_info_aes_gcm_256)))
@@ -436,6 +433,8 @@
 {
 	int rc = 0;
 
+	lock_sock(sk);
+
 	switch (optname) {
 	case TLS_TX:
 	case TLS_RX:
@@ -446,6 +445,9 @@
 		rc = -ENOPROTOOPT;
 		break;
 	}
+
+	release_sock(sk);
+
 	return rc;
 }
 
diff --git a/kernel/net/tls/tls_sw.c b/kernel/net/tls/tls_sw.c
index 21f20c3..50eae66 100644
--- a/kernel/net/tls/tls_sw.c
+++ b/kernel/net/tls/tls_sw.c
@@ -810,7 +810,7 @@
 	psock = sk_psock_get(sk);
 	if (!psock || !policy) {
 		err = tls_push_record(sk, flags, record_type);
-		if (err && sk->sk_err == EBADMSG) {
+		if (err && err != -EINPROGRESS && sk->sk_err == EBADMSG) {
 			*copied -= sk_msg_free(sk, msg);
 			tls_free_open_rec(sk);
 			err = -sk->sk_err;
@@ -839,7 +839,7 @@
 	switch (psock->eval) {
 	case __SK_PASS:
 		err = tls_push_record(sk, flags, record_type);
-		if (err && sk->sk_err == EBADMSG) {
+		if (err && err != -EINPROGRESS && sk->sk_err == EBADMSG) {
 			*copied -= sk_msg_free(sk, msg);
 			tls_free_open_rec(sk);
 			err = -sk->sk_err;
@@ -949,7 +949,9 @@
 			       MSG_CMSG_COMPAT))
 		return -EOPNOTSUPP;
 
-	mutex_lock(&tls_ctx->tx_lock);
+	ret = mutex_lock_interruptible(&tls_ctx->tx_lock);
+	if (ret)
+		return ret;
 	lock_sock(sk);
 
 	if (unlikely(msg->msg_controllen)) {
@@ -1283,7 +1285,9 @@
 		      MSG_SENDPAGE_NOTLAST | MSG_SENDPAGE_NOPOLICY))
 		return -EOPNOTSUPP;
 
-	mutex_lock(&tls_ctx->tx_lock);
+	ret = mutex_lock_interruptible(&tls_ctx->tx_lock);
+	if (ret)
+		return ret;
 	lock_sock(sk);
 	ret = tls_sw_do_sendpage(sk, page, offset, size, flags);
 	release_sock(sk);
@@ -2266,11 +2270,19 @@
 
 	if (!test_and_clear_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask))
 		return;
-	mutex_lock(&tls_ctx->tx_lock);
-	lock_sock(sk);
-	tls_tx_records(sk, -1);
-	release_sock(sk);
-	mutex_unlock(&tls_ctx->tx_lock);
+
+	if (mutex_trylock(&tls_ctx->tx_lock)) {
+		lock_sock(sk);
+		tls_tx_records(sk, -1);
+		release_sock(sk);
+		mutex_unlock(&tls_ctx->tx_lock);
+	} else if (!test_and_set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) {
+		/* Someone is holding the tx_lock, they will likely run Tx
+		 * and cancel the work on their way out of the lock section.
+		 * Schedule a long delay just in case.
+		 */
+		schedule_delayed_work(&ctx->tx_work.work, msecs_to_jiffies(10));
+	}
 }
 
 void tls_sw_write_space(struct sock *sk, struct tls_context *ctx)
diff --git a/kernel/net/unix/af_unix.c b/kernel/net/unix/af_unix.c
index 2aa01af..440ab64 100644
--- a/kernel/net/unix/af_unix.c
+++ b/kernel/net/unix/af_unix.c
@@ -529,7 +529,7 @@
 	/* Clear state */
 	unix_state_lock(sk);
 	sock_orphan(sk);
-	sk->sk_shutdown = SHUTDOWN_MASK;
+	WRITE_ONCE(sk->sk_shutdown, SHUTDOWN_MASK);
 	path	     = u->path;
 	u->path.dentry = NULL;
 	u->path.mnt = NULL;
@@ -547,7 +547,7 @@
 		if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
 			unix_state_lock(skpair);
 			/* No more writes */
-			skpair->sk_shutdown = SHUTDOWN_MASK;
+			WRITE_ONCE(skpair->sk_shutdown, SHUTDOWN_MASK);
 			if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
 				skpair->sk_err = ECONNRESET;
 			unix_state_unlock(skpair);
@@ -587,7 +587,7 @@
 	 *	  What the above comment does talk about? --ANK(980817)
 	 */
 
-	if (unix_tot_inflight)
+	if (READ_ONCE(unix_tot_inflight))
 		unix_gc();		/* Garbage collect fds */
 }
 
@@ -697,7 +697,7 @@
 	if (mutex_lock_interruptible(&u->iolock))
 		return -EINTR;
 
-	sk->sk_peek_off = val;
+	WRITE_ONCE(sk->sk_peek_off, val);
 	mutex_unlock(&u->iolock);
 
 	return 0;
@@ -1236,7 +1236,7 @@
 
 	sched = !sock_flag(other, SOCK_DEAD) &&
 		!(other->sk_shutdown & RCV_SHUTDOWN) &&
-		unix_recvq_full(other);
+		unix_recvq_full_lockless(other);
 
 	unix_state_unlock(other);
 
@@ -2008,6 +2008,7 @@
 
 	if (false) {
 alloc_skb:
+		spin_unlock(&other->sk_receive_queue.lock);
 		unix_state_unlock(other);
 		mutex_unlock(&unix_sk(other)->iolock);
 		newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
@@ -2047,6 +2048,7 @@
 		init_scm = false;
 	}
 
+	spin_lock(&other->sk_receive_queue.lock);
 	skb = skb_peek_tail(&other->sk_receive_queue);
 	if (tail && tail == skb) {
 		skb = newskb;
@@ -2077,14 +2079,11 @@
 	refcount_add(size, &sk->sk_wmem_alloc);
 
 	if (newskb) {
-		err = unix_scm_to_skb(&scm, skb, false);
-		if (err)
-			goto err_state_unlock;
-		spin_lock(&other->sk_receive_queue.lock);
+		unix_scm_to_skb(&scm, skb, false);
 		__skb_queue_tail(&other->sk_receive_queue, newskb);
-		spin_unlock(&other->sk_receive_queue.lock);
 	}
 
+	spin_unlock(&other->sk_receive_queue.lock);
 	unix_state_unlock(other);
 	mutex_unlock(&unix_sk(other)->iolock);
 
@@ -2581,7 +2580,7 @@
 	++mode;
 
 	unix_state_lock(sk);
-	sk->sk_shutdown |= mode;
+	WRITE_ONCE(sk->sk_shutdown, sk->sk_shutdown | mode);
 	other = unix_peer(sk);
 	if (other)
 		sock_hold(other);
@@ -2598,7 +2597,7 @@
 		if (mode&SEND_SHUTDOWN)
 			peer_mode |= RCV_SHUTDOWN;
 		unix_state_lock(other);
-		other->sk_shutdown |= peer_mode;
+		WRITE_ONCE(other->sk_shutdown, other->sk_shutdown | peer_mode);
 		unix_state_unlock(other);
 		other->sk_state_change(other);
 		if (peer_mode == SHUTDOWN_MASK)
@@ -2717,16 +2716,18 @@
 {
 	struct sock *sk = sock->sk;
 	__poll_t mask;
+	u8 shutdown;
 
 	sock_poll_wait(file, sock, wait);
 	mask = 0;
+	shutdown = READ_ONCE(sk->sk_shutdown);
 
 	/* exceptional events? */
 	if (sk->sk_err)
 		mask |= EPOLLERR;
-	if (sk->sk_shutdown == SHUTDOWN_MASK)
+	if (shutdown == SHUTDOWN_MASK)
 		mask |= EPOLLHUP;
-	if (sk->sk_shutdown & RCV_SHUTDOWN)
+	if (shutdown & RCV_SHUTDOWN)
 		mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
 
 	/* readable? */
@@ -2754,18 +2755,20 @@
 	struct sock *sk = sock->sk, *other;
 	unsigned int writable;
 	__poll_t mask;
+	u8 shutdown;
 
 	sock_poll_wait(file, sock, wait);
 	mask = 0;
+	shutdown = READ_ONCE(sk->sk_shutdown);
 
 	/* exceptional events? */
 	if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
 		mask |= EPOLLERR |
 			(sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
 
-	if (sk->sk_shutdown & RCV_SHUTDOWN)
+	if (shutdown & RCV_SHUTDOWN)
 		mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
-	if (sk->sk_shutdown == SHUTDOWN_MASK)
+	if (shutdown == SHUTDOWN_MASK)
 		mask |= EPOLLHUP;
 
 	/* readable? */
diff --git a/kernel/net/unix/scm.c b/kernel/net/unix/scm.c
index aa27a02..e8e2a00 100644
--- a/kernel/net/unix/scm.c
+++ b/kernel/net/unix/scm.c
@@ -63,7 +63,7 @@
 		/* Paired with READ_ONCE() in wait_for_unix_gc() */
 		WRITE_ONCE(unix_tot_inflight, unix_tot_inflight + 1);
 	}
-	user->unix_inflight++;
+	WRITE_ONCE(user->unix_inflight, user->unix_inflight + 1);
 	spin_unlock(&unix_gc_lock);
 }
 
@@ -84,7 +84,7 @@
 		/* Paired with READ_ONCE() in wait_for_unix_gc() */
 		WRITE_ONCE(unix_tot_inflight, unix_tot_inflight - 1);
 	}
-	user->unix_inflight--;
+	WRITE_ONCE(user->unix_inflight, user->unix_inflight - 1);
 	spin_unlock(&unix_gc_lock);
 }
 
@@ -98,7 +98,7 @@
 {
 	struct user_struct *user = current_user();
 
-	if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE)))
+	if (unlikely(READ_ONCE(user->unix_inflight) > task_rlimit(p, RLIMIT_NOFILE)))
 		return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
 	return false;
 }
diff --git a/kernel/net/vmw_vsock/af_vsock.c b/kernel/net/vmw_vsock/af_vsock.c
index ab9fe75..06dddb5 100644
--- a/kernel/net/vmw_vsock/af_vsock.c
+++ b/kernel/net/vmw_vsock/af_vsock.c
@@ -1367,7 +1367,7 @@
 			vsock_transport_cancel_pkt(vsk);
 			vsock_remove_connected(vsk);
 			goto out_wait;
-		} else if (timeout == 0) {
+		} else if ((sk->sk_state != TCP_ESTABLISHED) && (timeout == 0)) {
 			err = -ETIMEDOUT;
 			sk->sk_state = TCP_CLOSE;
 			sock->state = SS_UNCONNECTED;
diff --git a/kernel/net/vmw_vsock/vmci_transport.c b/kernel/net/vmw_vsock/vmci_transport.c
index 1c9ecb1..6ac5a96 100644
--- a/kernel/net/vmw_vsock/vmci_transport.c
+++ b/kernel/net/vmw_vsock/vmci_transport.c
@@ -1710,7 +1710,11 @@
 	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);
diff --git a/kernel/net/wireless/nl80211.c b/kernel/net/wireless/nl80211.c
index 2bd8196..dcf6c84 100644
--- a/kernel/net/wireless/nl80211.c
+++ b/kernel/net/wireless/nl80211.c
@@ -12684,7 +12684,7 @@
 		return -ERANGE;
 	if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN &&
 	    !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
-	      nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KCK_EXT_LEN))
+	      nla_len(tb[NL80211_REKEY_DATA_KCK]) == NL80211_KCK_EXT_LEN))
 		return -ERANGE;
 
 	rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
diff --git a/kernel/net/wireless/reg.c b/kernel/net/wireless/reg.c
index a1e64d9..9029726 100644
--- a/kernel/net/wireless/reg.c
+++ b/kernel/net/wireless/reg.c
@@ -4185,8 +4185,10 @@
 		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);
diff --git a/kernel/net/wireless/scan.c b/kernel/net/wireless/scan.c
index d09daba..f596919 100644
--- a/kernel/net/wireless/scan.c
+++ b/kernel/net/wireless/scan.c
@@ -262,117 +262,152 @@
 }
 EXPORT_SYMBOL(cfg80211_is_element_inherited);
 
-static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
-				  const u8 *subelement, size_t subie_len,
-				  u8 *new_ie, gfp_t gfp)
+static size_t cfg80211_copy_elem_with_frags(const struct element *elem,
+					    const u8 *ie, size_t ie_len,
+					    u8 **pos, u8 *buf, size_t buf_len)
 {
-	u8 *pos, *tmp;
-	const u8 *tmp_old, *tmp_new;
-	const struct element *non_inherit_elem;
-	u8 *sub_copy;
-
-	/* copy subelement as we need to change its content to
-	 * mark an ie after it is processed.
-	 */
-	sub_copy = kmemdup(subelement, subie_len, gfp);
-	if (!sub_copy)
+	if (WARN_ON((u8 *)elem < ie || elem->data > ie + ie_len ||
+		    elem->data + elem->datalen > ie + ie_len))
 		return 0;
 
-	pos = &new_ie[0];
+	if (elem->datalen + 2 > buf + buf_len - *pos)
+		return 0;
 
-	/* set new ssid */
-	tmp_new = cfg80211_find_ie(WLAN_EID_SSID, sub_copy, subie_len);
-	if (tmp_new) {
-		memcpy(pos, tmp_new, tmp_new[1] + 2);
-		pos += (tmp_new[1] + 2);
+	memcpy(*pos, elem, elem->datalen + 2);
+	*pos += elem->datalen + 2;
+
+	/* Finish if it is not fragmented  */
+	if (elem->datalen != 255)
+		return *pos - buf;
+
+	ie_len = ie + ie_len - elem->data - elem->datalen;
+	ie = (const u8 *)elem->data + elem->datalen;
+
+	for_each_element(elem, ie, ie_len) {
+		if (elem->id != WLAN_EID_FRAGMENT)
+			break;
+
+		if (elem->datalen + 2 > buf + buf_len - *pos)
+			return 0;
+
+		memcpy(*pos, elem, elem->datalen + 2);
+		*pos += elem->datalen + 2;
+
+		if (elem->datalen != 255)
+			break;
 	}
 
-	/* get non inheritance list if exists */
-	non_inherit_elem =
-		cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
-				       sub_copy, subie_len);
+	return *pos - buf;
+}
 
-	/* go through IEs in ie (skip SSID) and subelement,
-	 * merge them into new_ie
+static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
+				  const u8 *subie, size_t subie_len,
+				  u8 *new_ie, size_t new_ie_len)
+{
+	const struct element *non_inherit_elem, *parent, *sub;
+	u8 *pos = new_ie;
+	u8 id, ext_id;
+	unsigned int match_len;
+
+	non_inherit_elem = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
+						  subie, subie_len);
+
+	/* We copy the elements one by one from the parent to the generated
+	 * elements.
+	 * If they are not inherited (included in subie or in the non
+	 * inheritance element), then we copy all occurrences the first time
+	 * we see this element type.
 	 */
-	tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
-	tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie;
+	for_each_element(parent, ie, ielen) {
+		if (parent->id == WLAN_EID_FRAGMENT)
+			continue;
 
-	while (tmp_old + 2 - ie <= ielen &&
-	       tmp_old + tmp_old[1] + 2 - ie <= ielen) {
-		if (tmp_old[0] == 0) {
-			tmp_old++;
+		if (parent->id == WLAN_EID_EXTENSION) {
+			if (parent->datalen < 1)
+				continue;
+
+			id = WLAN_EID_EXTENSION;
+			ext_id = parent->data[0];
+			match_len = 1;
+		} else {
+			id = parent->id;
+			match_len = 0;
+		}
+
+		/* Find first occurrence in subie */
+		sub = cfg80211_find_elem_match(id, subie, subie_len,
+					       &ext_id, match_len, 0);
+
+		/* Copy from parent if not in subie and inherited */
+		if (!sub &&
+		    cfg80211_is_element_inherited(parent, non_inherit_elem)) {
+			if (!cfg80211_copy_elem_with_frags(parent,
+							   ie, ielen,
+							   &pos, new_ie,
+							   new_ie_len))
+				return 0;
+
 			continue;
 		}
 
-		if (tmp_old[0] == WLAN_EID_EXTENSION)
-			tmp = (u8 *)cfg80211_find_ext_ie(tmp_old[2], sub_copy,
-							 subie_len);
-		else
-			tmp = (u8 *)cfg80211_find_ie(tmp_old[0], sub_copy,
-						     subie_len);
+		/* Already copied if an earlier element had the same type */
+		if (cfg80211_find_elem_match(id, ie, (u8 *)parent - ie,
+					     &ext_id, match_len, 0))
+			continue;
 
-		if (!tmp) {
-			const struct element *old_elem = (void *)tmp_old;
+		/* Not inheriting, copy all similar elements from subie */
+		while (sub) {
+			if (!cfg80211_copy_elem_with_frags(sub,
+							   subie, subie_len,
+							   &pos, new_ie,
+							   new_ie_len))
+				return 0;
 
-			/* ie in old ie but not in subelement */
-			if (cfg80211_is_element_inherited(old_elem,
-							  non_inherit_elem)) {
-				memcpy(pos, tmp_old, tmp_old[1] + 2);
-				pos += tmp_old[1] + 2;
-			}
-		} else {
-			/* ie in transmitting ie also in subelement,
-			 * copy from subelement and flag the ie in subelement
-			 * as copied (by setting eid field to WLAN_EID_SSID,
-			 * which is skipped anyway).
-			 * For vendor ie, compare OUI + type + subType to
-			 * determine if they are the same ie.
-			 */
-			if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) {
-				if (tmp_old[1] >= 5 && tmp[1] >= 5 &&
-				    !memcmp(tmp_old + 2, tmp + 2, 5)) {
-					/* same vendor ie, copy from
-					 * subelement
-					 */
-					memcpy(pos, tmp, tmp[1] + 2);
-					pos += tmp[1] + 2;
-					tmp[0] = WLAN_EID_SSID;
-				} else {
-					memcpy(pos, tmp_old, tmp_old[1] + 2);
-					pos += tmp_old[1] + 2;
-				}
-			} else {
-				/* copy ie from subelement into new ie */
-				memcpy(pos, tmp, tmp[1] + 2);
-				pos += tmp[1] + 2;
-				tmp[0] = WLAN_EID_SSID;
-			}
+			sub = cfg80211_find_elem_match(id,
+						       sub->data + sub->datalen,
+						       subie_len + subie -
+						       (sub->data +
+							sub->datalen),
+						       &ext_id, match_len, 0);
 		}
-
-		if (tmp_old + tmp_old[1] + 2 - ie == ielen)
-			break;
-
-		tmp_old += tmp_old[1] + 2;
 	}
 
-	/* go through subelement again to check if there is any ie not
-	 * copied to new ie, skip ssid, capability, bssid-index ie
+	/* The above misses elements that are included in subie but not in the
+	 * parent, so do a pass over subie and append those.
+	 * Skip the non-tx BSSID caps and non-inheritance element.
 	 */
-	tmp_new = sub_copy;
-	while (tmp_new + 2 - sub_copy <= subie_len &&
-	       tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
-		if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP ||
-		      tmp_new[0] == WLAN_EID_SSID)) {
-			memcpy(pos, tmp_new, tmp_new[1] + 2);
-			pos += tmp_new[1] + 2;
+	for_each_element(sub, subie, subie_len) {
+		if (sub->id == WLAN_EID_NON_TX_BSSID_CAP)
+			continue;
+
+		if (sub->id == WLAN_EID_FRAGMENT)
+			continue;
+
+		if (sub->id == WLAN_EID_EXTENSION) {
+			if (sub->datalen < 1)
+				continue;
+
+			id = WLAN_EID_EXTENSION;
+			ext_id = sub->data[0];
+			match_len = 1;
+
+			if (ext_id == WLAN_EID_EXT_NON_INHERITANCE)
+				continue;
+		} else {
+			id = sub->id;
+			match_len = 0;
 		}
-		if (tmp_new + tmp_new[1] + 2 - sub_copy == subie_len)
-			break;
-		tmp_new += tmp_new[1] + 2;
+
+		/* Processed if one was included in the parent */
+		if (cfg80211_find_elem_match(id, ie, ielen,
+					     &ext_id, match_len, 0))
+			continue;
+
+		if (!cfg80211_copy_elem_with_frags(sub, subie, subie_len,
+						   &pos, new_ie, new_ie_len))
+			return 0;
 	}
 
-	kfree(sub_copy);
 	return pos - new_ie;
 }
 
@@ -606,7 +641,7 @@
 
 	ret = cfg80211_calc_short_ssid(ies, &ssid_elem, &s_ssid_tmp);
 	if (ret)
-		return ret;
+		return 0;
 
 	/* RNR IE may contain more than one NEIGHBOR_AP_INFO */
 	while (pos + sizeof(*ap_info) <= end) {
@@ -2170,7 +2205,7 @@
 			new_ie_len = cfg80211_gen_new_ie(ie, ielen,
 							 profile,
 							 profile_len, new_ie,
-							 gfp);
+							 IEEE80211_MAX_DATA_LEN);
 			if (!new_ie_len)
 				continue;
 
diff --git a/kernel/net/wireless/sme.c b/kernel/net/wireless/sme.c
index 060e365..f7e2e17 100644
--- a/kernel/net/wireless/sme.c
+++ b/kernel/net/wireless/sme.c
@@ -269,6 +269,15 @@
 	rtnl_unlock();
 }
 
+static void cfg80211_step_auth_next(struct cfg80211_conn *conn,
+				    struct cfg80211_bss *bss)
+{
+	memcpy(conn->bssid, bss->bssid, ETH_ALEN);
+	conn->params.bssid = conn->bssid;
+	conn->params.channel = bss->channel;
+	conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
+}
+
 /* Returned bss is reference counted and must be cleaned up appropriately. */
 static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
 {
@@ -286,10 +295,7 @@
 	if (!bss)
 		return NULL;
 
-	memcpy(wdev->conn->bssid, bss->bssid, ETH_ALEN);
-	wdev->conn->params.bssid = wdev->conn->bssid;
-	wdev->conn->params.channel = bss->channel;
-	wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
+	cfg80211_step_auth_next(wdev->conn, bss);
 	schedule_work(&rdev->conn_work);
 
 	return bss;
@@ -568,7 +574,12 @@
 	wdev->conn->params.ssid_len = wdev->ssid_len;
 
 	/* see if we have the bss already */
-	bss = cfg80211_get_conn_bss(wdev);
+	bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel,
+			       wdev->conn->params.bssid,
+			       wdev->conn->params.ssid,
+			       wdev->conn->params.ssid_len,
+			       wdev->conn_bss_type,
+			       IEEE80211_PRIVACY(wdev->conn->params.privacy));
 
 	if (prev_bssid) {
 		memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN);
@@ -579,6 +590,7 @@
 	if (bss) {
 		enum nl80211_timeout_reason treason;
 
+		cfg80211_step_auth_next(wdev->conn, bss);
 		err = cfg80211_conn_do_work(wdev, &treason);
 		cfg80211_put_bss(wdev->wiphy, bss);
 	} else {
@@ -1245,6 +1257,13 @@
 	} else {
 		if (WARN_ON(connkeys))
 			return -EINVAL;
+
+		/* connect can point to wdev->wext.connect which
+		 * can hold key data from a previous connection
+		 */
+		connect->key = NULL;
+		connect->key_len = 0;
+		connect->key_idx = 0;
 	}
 
 	wdev->connect_keys = connkeys;
diff --git a/kernel/net/wireless/wext-core.c b/kernel/net/wireless/wext-core.c
index 76a80a4..a57f54b 100644
--- a/kernel/net/wireless/wext-core.c
+++ b/kernel/net/wireless/wext-core.c
@@ -796,6 +796,12 @@
 		}
 	}
 
+	/* Sanity-check to ensure we never end up _allocating_ zero
+	 * bytes of data for extra.
+	 */
+	if (extra_size <= 0)
+		return -EFAULT;
+
 	/* kzalloc() ensures NULL-termination for essid_compat. */
 	extra = kzalloc(extra_size, GFP_KERNEL);
 	if (!extra)
diff --git a/kernel/net/x25/af_x25.c b/kernel/net/x25/af_x25.c
index d231d46..161dc19 100644
--- a/kernel/net/x25/af_x25.c
+++ b/kernel/net/x25/af_x25.c
@@ -492,6 +492,12 @@
 	int rc = -EOPNOTSUPP;
 
 	lock_sock(sk);
+	if (sock->state != SS_UNCONNECTED) {
+		rc = -EINVAL;
+		release_sock(sk);
+		return rc;
+	}
+
 	if (sk->sk_state != TCP_LISTEN) {
 		memset(&x25_sk(sk)->dest_addr, 0, X25_ADDR_LEN);
 		sk->sk_max_ack_backlog = backlog;
diff --git a/kernel/net/xdp/xdp_umem.c b/kernel/net/xdp/xdp_umem.c
index 56a28a6..42b19fe 100644
--- a/kernel/net/xdp/xdp_umem.c
+++ b/kernel/net/xdp/xdp_umem.c
@@ -153,10 +153,11 @@
 
 static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
 {
-	u32 npgs_rem, chunk_size = mr->chunk_size, headroom = mr->headroom;
 	bool unaligned_chunks = mr->flags & XDP_UMEM_UNALIGNED_CHUNK_FLAG;
-	u64 npgs, addr = mr->addr, size = mr->len;
-	unsigned int chunks, chunks_rem;
+	u32 chunk_size = mr->chunk_size, headroom = mr->headroom;
+	u64 addr = mr->addr, size = mr->len;
+	u32 chunks_rem, npgs_rem;
+	u64 chunks, npgs;
 	int err;
 
 	if (chunk_size < XDP_UMEM_MIN_CHUNK_SIZE || chunk_size > PAGE_SIZE) {
@@ -191,8 +192,8 @@
 	if (npgs > U32_MAX)
 		return -EINVAL;
 
-	chunks = (unsigned int)div_u64_rem(size, chunk_size, &chunks_rem);
-	if (chunks == 0)
+	chunks = div_u64_rem(size, chunk_size, &chunks_rem);
+	if (!chunks || chunks > U32_MAX)
 		return -EINVAL;
 
 	if (!unaligned_chunks && chunks_rem)
@@ -205,7 +206,7 @@
 	umem->headroom = headroom;
 	umem->chunk_size = chunk_size;
 	umem->chunks = chunks;
-	umem->npgs = (u32)npgs;
+	umem->npgs = npgs;
 	umem->pgs = NULL;
 	umem->user = NULL;
 	umem->flags = mr->flags;
diff --git a/kernel/net/xdp/xsk.c b/kernel/net/xdp/xsk.c
index 691841d..d04f91f 100644
--- a/kernel/net/xdp/xsk.c
+++ b/kernel/net/xdp/xsk.c
@@ -667,6 +667,7 @@
 	struct sock *sk = sock->sk;
 	struct xdp_sock *xs = xdp_sk(sk);
 	struct net_device *dev;
+	int bound_dev_if;
 	u32 flags, qid;
 	int err = 0;
 
@@ -680,6 +681,10 @@
 		      XDP_USE_NEED_WAKEUP))
 		return -EINVAL;
 
+	bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
+	if (bound_dev_if && bound_dev_if != sxdp->sxdp_ifindex)
+		return -EINVAL;
+
 	rtnl_lock();
 	mutex_lock(&xs->mutex);
 	if (xs->state != XSK_READY) {
diff --git a/kernel/net/xdp/xsk_queue.h b/kernel/net/xdp/xsk_queue.h
index 3c7ce60..a76d437 100644
--- a/kernel/net/xdp/xsk_queue.h
+++ b/kernel/net/xdp/xsk_queue.h
@@ -155,6 +155,7 @@
 		return false;
 
 	if (base_addr >= pool->addrs_cnt || addr >= pool->addrs_cnt ||
+	    addr + desc->len > pool->addrs_cnt ||
 	    xp_desc_crosses_non_contig_pg(pool, addr, desc->len))
 		return false;
 
diff --git a/kernel/net/xfrm/Makefile b/kernel/net/xfrm/Makefile
index 494aa74..08a2870 100644
--- a/kernel/net/xfrm/Makefile
+++ b/kernel/net/xfrm/Makefile
@@ -3,6 +3,8 @@
 # Makefile for the XFRM subsystem.
 #
 
+xfrm_interface-$(CONFIG_XFRM_INTERFACE) += xfrm_interface_core.o
+
 obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_hash.o \
 		      xfrm_input.o xfrm_output.o \
 		      xfrm_sysctl.o xfrm_replay.o xfrm_device.o
diff --git a/kernel/net/xfrm/xfrm_compat.c b/kernel/net/xfrm/xfrm_compat.c
index 2bf2693..2d5e0ed 100644
--- a/kernel/net/xfrm/xfrm_compat.c
+++ b/kernel/net/xfrm/xfrm_compat.c
@@ -5,6 +5,7 @@
  * Based on code and translator idea by: Florian Westphal <fw@strlen.de>
  */
 #include <linux/compat.h>
+#include <linux/nospec.h>
 #include <linux/xfrm.h>
 #include <net/xfrm.h>
 
@@ -107,7 +108,7 @@
 	[XFRMA_ALG_COMP]	= { .len = sizeof(struct xfrm_algo) },
 	[XFRMA_ENCAP]		= { .len = sizeof(struct xfrm_encap_tmpl) },
 	[XFRMA_TMPL]		= { .len = sizeof(struct xfrm_user_tmpl) },
-	[XFRMA_SEC_CTX]		= { .len = sizeof(struct xfrm_sec_ctx) },
+	[XFRMA_SEC_CTX]		= { .len = sizeof(struct xfrm_user_sec_ctx) },
 	[XFRMA_LTIME_VAL]	= { .len = sizeof(struct xfrm_lifetime_cur) },
 	[XFRMA_REPLAY_VAL]	= { .len = sizeof(struct xfrm_replay_state) },
 	[XFRMA_REPLAY_THRESH]	= { .type = NLA_U32 },
@@ -300,7 +301,7 @@
 	nla_for_each_attr(nla, attrs, len, remaining) {
 		int err;
 
-		switch (type) {
+		switch (nlh_src->nlmsg_type) {
 		case XFRM_MSG_NEWSPDINFO:
 			err = xfrm_nla_cpy(dst, nla, nla_len(nla));
 			break;
@@ -435,6 +436,7 @@
 		NL_SET_ERR_MSG(extack, "Bad attribute");
 		return -EOPNOTSUPP;
 	}
+	type = array_index_nospec(type, XFRMA_MAX + 1);
 	if (nla_len(nla) < compat_policy[type].len) {
 		NL_SET_ERR_MSG(extack, "Attribute bad length");
 		return -EOPNOTSUPP;
diff --git a/kernel/net/xfrm/xfrm_input.c b/kernel/net/xfrm/xfrm_input.c
index 77e8203..f3bccab 100644
--- a/kernel/net/xfrm/xfrm_input.c
+++ b/kernel/net/xfrm/xfrm_input.c
@@ -129,6 +129,7 @@
 	memset(sp->ovec, 0, sizeof(sp->ovec));
 	sp->olen = 0;
 	sp->len = 0;
+	sp->verified_cnt = 0;
 
 	return sp;
 }
@@ -277,8 +278,7 @@
 		goto out;
 
 	if (x->props.flags & XFRM_STATE_DECAP_DSCP)
-		ipv6_copy_dscp(ipv6_get_dsfield(ipv6_hdr(skb)),
-			       ipipv6_hdr(skb));
+		ipv6_copy_dscp(XFRM_MODE_SKB_CB(skb)->tos, ipipv6_hdr(skb));
 	if (!(x->props.flags & XFRM_STATE_NOECN))
 		ipip6_ecn_decapsulate(skb);
 
diff --git a/kernel/net/xfrm/xfrm_interface.c b/kernel/net/xfrm/xfrm_interface_core.c
similarity index 94%
rename from kernel/net/xfrm/xfrm_interface.c
rename to kernel/net/xfrm/xfrm_interface_core.c
index da518b4..4eeec33 100644
--- a/kernel/net/xfrm/xfrm_interface.c
+++ b/kernel/net/xfrm/xfrm_interface_core.c
@@ -207,6 +207,52 @@
 	skb->mark = 0;
 }
 
+static int xfrmi_input(struct sk_buff *skb, int nexthdr, __be32 spi,
+		       int encap_type, unsigned short family)
+{
+	struct sec_path *sp;
+
+	sp = skb_sec_path(skb);
+	if (sp && (sp->len || sp->olen) &&
+	    !xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family))
+		goto discard;
+
+	XFRM_SPI_SKB_CB(skb)->family = family;
+	if (family == AF_INET) {
+		XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
+		XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
+	} else {
+		XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
+		XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
+	}
+
+	return xfrm_input(skb, nexthdr, spi, encap_type);
+discard:
+	kfree_skb(skb);
+	return 0;
+}
+
+static int xfrmi4_rcv(struct sk_buff *skb)
+{
+	return xfrmi_input(skb, ip_hdr(skb)->protocol, 0, 0, AF_INET);
+}
+
+static int xfrmi6_rcv(struct sk_buff *skb)
+{
+	return xfrmi_input(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
+			   0, 0, AF_INET6);
+}
+
+static int xfrmi4_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
+{
+	return xfrmi_input(skb, nexthdr, spi, encap_type, AF_INET);
+}
+
+static int xfrmi6_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
+{
+	return xfrmi_input(skb, nexthdr, spi, encap_type, AF_INET6);
+}
+
 static int xfrmi_rcv_cb(struct sk_buff *skb, int err)
 {
 	const struct xfrm_mode *inner_mode;
@@ -357,8 +403,8 @@
 
 	switch (skb->protocol) {
 	case htons(ETH_P_IPV6):
-		xfrm_decode_session(skb, &fl, AF_INET6);
 		memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
+		xfrm_decode_session(skb, &fl, AF_INET6);
 		if (!dst) {
 			fl.u.ip6.flowi6_oif = dev->ifindex;
 			fl.u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
@@ -372,8 +418,8 @@
 		}
 		break;
 	case htons(ETH_P_IP):
-		xfrm_decode_session(skb, &fl, AF_INET);
 		memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
+		xfrm_decode_session(skb, &fl, AF_INET);
 		if (!dst) {
 			struct rtable *rt;
 
@@ -780,8 +826,8 @@
 };
 
 static struct xfrm6_protocol xfrmi_esp6_protocol __read_mostly = {
-	.handler	=	xfrm6_rcv,
-	.input_handler	=	xfrm_input,
+	.handler	=	xfrmi6_rcv,
+	.input_handler	=	xfrmi6_input,
 	.cb_handler	=	xfrmi_rcv_cb,
 	.err_handler	=	xfrmi6_err,
 	.priority	=	10,
@@ -831,8 +877,8 @@
 #endif
 
 static struct xfrm4_protocol xfrmi_esp4_protocol __read_mostly = {
-	.handler	=	xfrm4_rcv,
-	.input_handler	=	xfrm_input,
+	.handler	=	xfrmi4_rcv,
+	.input_handler	=	xfrmi4_input,
 	.cb_handler	=	xfrmi_rcv_cb,
 	.err_handler	=	xfrmi4_err,
 	.priority	=	10,
diff --git a/kernel/net/xfrm/xfrm_policy.c b/kernel/net/xfrm/xfrm_policy.c
index 7b9d21d..71f6a6d 100644
--- a/kernel/net/xfrm/xfrm_policy.c
+++ b/kernel/net/xfrm/xfrm_policy.c
@@ -3240,7 +3240,7 @@
 
 static inline int
 xfrm_state_ok(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x,
-	      unsigned short family)
+	      unsigned short family, u32 if_id)
 {
 	if (xfrm_state_kern(x))
 		return tmpl->optional && !xfrm_state_addr_cmp(tmpl, x, tmpl->encap_family);
@@ -3251,7 +3251,8 @@
 		(tmpl->allalgs || (tmpl->aalgos & (1<<x->props.aalgo)) ||
 		 !(xfrm_id_proto_match(tmpl->id.proto, IPSEC_PROTO_ANY))) &&
 		!(x->props.mode != XFRM_MODE_TRANSPORT &&
-		  xfrm_state_addr_cmp(tmpl, x, family));
+		  xfrm_state_addr_cmp(tmpl, x, family)) &&
+		(if_id == 0 || if_id == x->if_id);
 }
 
 /*
@@ -3263,7 +3264,7 @@
  */
 static inline int
 xfrm_policy_ok(const struct xfrm_tmpl *tmpl, const struct sec_path *sp, int start,
-	       unsigned short family)
+	       unsigned short family, u32 if_id)
 {
 	int idx = start;
 
@@ -3273,9 +3274,16 @@
 	} else
 		start = -1;
 	for (; idx < sp->len; idx++) {
-		if (xfrm_state_ok(tmpl, sp->xvec[idx], family))
+		if (xfrm_state_ok(tmpl, sp->xvec[idx], family, if_id))
 			return ++idx;
 		if (sp->xvec[idx]->props.mode != XFRM_MODE_TRANSPORT) {
+			if (idx < sp->verified_cnt) {
+				/* Secpath entry previously verified, consider optional and
+				 * continue searching
+				 */
+				continue;
+			}
+
 			if (start == -1)
 				start = -2-idx;
 			break;
@@ -3671,6 +3679,7 @@
 				tpp[ti++] = &pols[pi]->xfrm_vec[i];
 		}
 		xfrm_nr = ti;
+
 		if (npols > 1) {
 			xfrm_tmpl_sort(stp, tpp, xfrm_nr, family);
 			tpp = stp;
@@ -3681,9 +3690,12 @@
 		 * Order is _important_. Later we will implement
 		 * some barriers, but at the moment barriers
 		 * are implied between each two transformations.
+		 * Upon success, marks secpath entries as having been
+		 * verified to allow them to be skipped in future policy
+		 * checks (e.g. nested tunnels).
 		 */
 		for (i = xfrm_nr-1, k = 0; i >= 0; i--) {
-			k = xfrm_policy_ok(tpp[i], sp, k, family);
+			k = xfrm_policy_ok(tpp[i], sp, k, family, if_id);
 			if (k < 0) {
 				if (k < -1)
 					/* "-2 - errored_index" returned */
@@ -3699,6 +3711,8 @@
 		}
 
 		xfrm_pols_put(pols, npols);
+		sp->verified_cnt = k;
+
 		return 1;
 	}
 	XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLBLOCK);
diff --git a/kernel/net/xfrm/xfrm_state.c b/kernel/net/xfrm/xfrm_state.c
index 5f4b51e..ef6aa54 100644
--- a/kernel/net/xfrm/xfrm_state.c
+++ b/kernel/net/xfrm/xfrm_state.c
@@ -2593,9 +2593,6 @@
 		if (inner_mode == NULL)
 			goto error;
 
-		if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL))
-			goto error;
-
 		x->inner_mode = *inner_mode;
 
 		if (x->props.family == AF_INET)
diff --git a/kernel/net/xfrm/xfrm_user.c b/kernel/net/xfrm/xfrm_user.c
index b7f95fd..7156aae 100644
--- a/kernel/net/xfrm/xfrm_user.c
+++ b/kernel/net/xfrm/xfrm_user.c
@@ -522,7 +522,7 @@
 	struct nlattr *et = attrs[XFRMA_ETIMER_THRESH];
 	struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH];
 
-	if (re) {
+	if (re && x->replay_esn && x->preplay_esn) {
 		struct xfrm_replay_state_esn *replay_esn;
 		replay_esn = nla_data(re);
 		memcpy(x->replay_esn, replay_esn,
@@ -1049,6 +1049,15 @@
 					 sizeof(*filter), GFP_KERNEL);
 			if (filter == NULL)
 				return -ENOMEM;
+
+			/* see addr_match(), (prefix length >> 5) << 2
+			 * will be used to compare xfrm_address_t
+			 */
+			if (filter->splen > (sizeof(xfrm_address_t) << 3) ||
+			    filter->dplen > (sizeof(xfrm_address_t) << 3)) {
+				kfree(filter);
+				return -EINVAL;
+			}
 		}
 
 		if (attrs[XFRMA_PROTO])
@@ -2624,7 +2633,7 @@
 	[XFRMA_ALG_COMP]	= { .len = sizeof(struct xfrm_algo) },
 	[XFRMA_ENCAP]		= { .len = sizeof(struct xfrm_encap_tmpl) },
 	[XFRMA_TMPL]		= { .len = sizeof(struct xfrm_user_tmpl) },
-	[XFRMA_SEC_CTX]		= { .len = sizeof(struct xfrm_sec_ctx) },
+	[XFRMA_SEC_CTX]		= { .len = sizeof(struct xfrm_user_sec_ctx) },
 	[XFRMA_LTIME_VAL]	= { .len = sizeof(struct xfrm_lifetime_cur) },
 	[XFRMA_REPLAY_VAL]	= { .len = sizeof(struct xfrm_replay_state) },
 	[XFRMA_REPLAY_THRESH]	= { .type = NLA_U32 },
diff --git a/kernel/samples/bpf/hbm.c b/kernel/samples/bpf/hbm.c
index ff4c533..8e48489 100644
--- a/kernel/samples/bpf/hbm.c
+++ b/kernel/samples/bpf/hbm.c
@@ -308,6 +308,7 @@
 		fout = fopen(fname, "w");
 		fprintf(fout, "id:%d\n", cg_id);
 		fprintf(fout, "ERROR: Could not lookup queue_stats\n");
+		fclose(fout);
 	} else if (stats_flag && qstats.lastPacketTime >
 		   qstats.firstPacketTime) {
 		long long delta_us = (qstats.lastPacketTime -
diff --git a/kernel/samples/bpf/tcp_basertt_kern.c b/kernel/samples/bpf/tcp_basertt_kern.c
index 8dfe09a..822b074 100644
--- a/kernel/samples/bpf/tcp_basertt_kern.c
+++ b/kernel/samples/bpf/tcp_basertt_kern.c
@@ -47,7 +47,7 @@
 		case BPF_SOCK_OPS_BASE_RTT:
 			n = bpf_getsockopt(skops, SOL_TCP, TCP_CONGESTION,
 					   cong, sizeof(cong));
-			if (!n && !__builtin_memcmp(cong, nv, sizeof(nv)+1)) {
+			if (!n && !__builtin_memcmp(cong, nv, sizeof(nv))) {
 				/* Set base_rtt to 80us */
 				rv = 80;
 			} else if (n) {
diff --git a/kernel/samples/bpf/tracex6_kern.c b/kernel/samples/bpf/tracex6_kern.c
index acad571..fd602c2 100644
--- a/kernel/samples/bpf/tracex6_kern.c
+++ b/kernel/samples/bpf/tracex6_kern.c
@@ -2,6 +2,8 @@
 #include <linux/version.h>
 #include <uapi/linux/bpf.h>
 #include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+#include <bpf/bpf_core_read.h>
 
 struct {
 	__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
@@ -45,13 +47,24 @@
 	return 0;
 }
 
-SEC("kprobe/htab_map_lookup_elem")
-int bpf_prog2(struct pt_regs *ctx)
+/*
+ * Since *_map_lookup_elem can't be expected to trigger bpf programs
+ * due to potential deadlocks (bpf_disable_instrumentation), this bpf
+ * program will be attached to bpf_map_copy_value (which is called
+ * from map_lookup_elem) and will only filter the hashtable type.
+ */
+SEC("kprobe/bpf_map_copy_value")
+int BPF_KPROBE(bpf_prog2, struct bpf_map *map)
 {
 	u32 key = bpf_get_smp_processor_id();
 	struct bpf_perf_event_value *val, buf;
+	enum bpf_map_type type;
 	int error;
 
+	type = BPF_CORE_READ(map, map_type);
+	if (type != BPF_MAP_TYPE_HASH)
+		return 0;
+
 	error = bpf_perf_event_read_value(&counters, key, &buf, sizeof(buf));
 	if (error)
 		return 0;
diff --git a/kernel/samples/ftrace/ftrace-direct-too.c b/kernel/samples/ftrace/ftrace-direct-too.c
index 3927cb8..4bdd679 100644
--- a/kernel/samples/ftrace/ftrace-direct-too.c
+++ b/kernel/samples/ftrace/ftrace-direct-too.c
@@ -4,14 +4,14 @@
 #include <linux/mm.h> /* for handle_mm_fault() */
 #include <linux/ftrace.h>
 
-extern void my_direct_func(struct vm_area_struct *vma,
-			   unsigned long address, unsigned int flags);
+extern void my_direct_func(struct vm_area_struct *vma, unsigned long address,
+			   unsigned int flags, struct pt_regs *regs);
 
-void my_direct_func(struct vm_area_struct *vma,
-			unsigned long address, unsigned int flags)
+void my_direct_func(struct vm_area_struct *vma, unsigned long address,
+		    unsigned int flags, struct pt_regs *regs)
 {
-	trace_printk("handle mm fault vma=%p address=%lx flags=%x\n",
-		     vma, address, flags);
+	trace_printk("handle mm fault vma=%p address=%lx flags=%x regs=%p\n",
+		     vma, address, flags, regs);
 }
 
 extern void my_tramp(void *);
@@ -26,7 +26,9 @@
 "	pushq %rdi\n"
 "	pushq %rsi\n"
 "	pushq %rdx\n"
+"	pushq %rcx\n"
 "	call my_direct_func\n"
+"	popq %rcx\n"
 "	popq %rdx\n"
 "	popq %rsi\n"
 "	popq %rdi\n"
diff --git a/kernel/samples/hw_breakpoint/data_breakpoint.c b/kernel/samples/hw_breakpoint/data_breakpoint.c
index 418c46f..b99322f 100644
--- a/kernel/samples/hw_breakpoint/data_breakpoint.c
+++ b/kernel/samples/hw_breakpoint/data_breakpoint.c
@@ -70,7 +70,9 @@
 static void __exit hw_break_module_exit(void)
 {
 	unregister_wide_hw_breakpoint(sample_hbp);
-	symbol_put(ksym_name);
+#ifdef CONFIG_MODULE_UNLOAD
+	__symbol_put(ksym_name);
+#endif
 	printk(KERN_INFO "HW Breakpoint for %s write uninstalled\n", ksym_name);
 }
 
diff --git a/kernel/samples/vfio-mdev/mdpy-fb.c b/kernel/samples/vfio-mdev/mdpy-fb.c
index 9ec93d9..4eb7aa1 100644
--- a/kernel/samples/vfio-mdev/mdpy-fb.c
+++ b/kernel/samples/vfio-mdev/mdpy-fb.c
@@ -109,7 +109,7 @@
 
 	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 @@
 err_release_regions:
 	pci_release_regions(pdev);
 
+err_disable_dev:
+	pci_disable_device(pdev);
+
 	return ret;
 }
 
@@ -199,7 +202,10 @@
 	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[] = {
diff --git a/kernel/scripts/Kconfig.include b/kernel/scripts/Kconfig.include
index a5fe72c..6d37cb7 100644
--- a/kernel/scripts/Kconfig.include
+++ b/kernel/scripts/Kconfig.include
@@ -42,6 +42,12 @@
 # Fail if the linker is gold as it's not capable of linking the kernel proper
 $(error-if,$(success, $(LD) -v | grep -q gold), gold linker '$(LD)' not supported)
 
+# Get the assembler name, version, and error out if it is not supported.
+as-info := $(shell,$(srctree)/scripts/as-version.sh $(CC) $(CLANG_FLAGS))
+$(error-if,$(success,test -z "$(as-info)"),Sorry$(comma) this assembler is not supported.)
+as-name := $(shell,set -- $(as-info) && echo $1)
+as-version := $(shell,set -- $(as-info) && echo $2)
+
 # machine bit flags
 #  $(m32-flag): -m32 if the compiler supports it, or an empty string otherwise.
 #  $(m64-flag): -m64 if the compiler supports it, or an empty string otherwise.
diff --git a/kernel/scripts/as-version.sh b/kernel/scripts/as-version.sh
new file mode 100755
index 0000000..532270b
--- /dev/null
+++ b/kernel/scripts/as-version.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Print the assembler name and its version in a 5 or 6-digit form.
+# Also, perform the minimum version check.
+# (If it is the integrated assembler, return 0 as the version, and
+# skip the version check.)
+
+set -e
+
+# Convert the version string x.y.z to a canonical 5 or 6-digit form.
+get_canonical_version()
+{
+	IFS=.
+	set -- $1
+
+	# If the 2nd or 3rd field is missing, fill it with a zero.
+	#
+	# The 4th field, if present, is ignored.
+	# This occurs in development snapshots as in 2.35.1.20201116
+	echo $((10000 * $1 + 100 * ${2:-0} + ${3:-0}))
+}
+
+# Clang fails to handle -Wa,--version unless -fno-integrated-as is given.
+# We check -fintegrated-as, expecting it is explicitly passed in for the
+# integrated assembler case.
+check_integrated_as()
+{
+	while [ $# -gt 0 ]; do
+		if [ "$1" = -fintegrated-as ]; then
+			# For the integrated assembler, we do not check the
+			# version here. It is the same as the clang version, and
+			# it has been already checked by scripts/cc-version.sh.
+			echo LLVM 0
+			exit 0
+		fi
+		shift
+	done
+}
+
+check_integrated_as "$@"
+
+orig_args="$@"
+
+# Get the first line of the --version output.
+IFS='
+'
+set -- $(LC_ALL=C "$@" -Wa,--version -c -x assembler /dev/null -o /dev/null 2>/dev/null)
+
+# Split the line on spaces.
+IFS=' '
+set -- $1
+
+if [ "$1" = GNU -a "$2" = assembler ]; then
+	shift $(($# - 1))
+	version=$1
+	name=GNU
+else
+	echo "$orig_args: unknown assembler invoked" >&2
+	exit 1
+fi
+
+# Some distributions append a package release number, as in 2.34-4.fc32
+# Trim the hyphen and any characters that follow.
+version=${version%-*}
+
+cversion=$(get_canonical_version $version)
+
+echo $name $cversion
diff --git a/kernel/scripts/asn1_compiler.c b/kernel/scripts/asn1_compiler.c
index adabd41..985fb81 100644
--- a/kernel/scripts/asn1_compiler.c
+++ b/kernel/scripts/asn1_compiler.c
@@ -625,7 +625,7 @@
 	p = strrchr(argv[1], '/');
 	p = p ? p + 1 : argv[1];
 	grammar_name = strdup(p);
-	if (!p) {
+	if (!grammar_name) {
 		perror(NULL);
 		exit(1);
 	}
diff --git a/kernel/scripts/checkkconfigsymbols.py b/kernel/scripts/checkkconfigsymbols.py
index 1548f9c..6979724 100755
--- a/kernel/scripts/checkkconfigsymbols.py
+++ b/kernel/scripts/checkkconfigsymbols.py
@@ -113,7 +113,7 @@
     return args
 
 
-def main():
+def print_undefined_symbols():
     """Main function of this module."""
     args = parse_options()
 
@@ -472,5 +472,16 @@
     return defined, references
 
 
+def main():
+    try:
+        print_undefined_symbols()
+    except BrokenPipeError:
+        # Python flushes standard streams on exit; redirect remaining output
+        # to devnull to avoid another BrokenPipeError at shutdown
+        devnull = os.open(os.devnull, os.O_WRONLY)
+        os.dup2(devnull, sys.stdout.fileno())
+        sys.exit(1)  # Python exits with error code 1 on EPIPE
+
+
 if __name__ == "__main__":
     main()
diff --git a/kernel/scripts/clang-tools/run-clang-tools.py b/kernel/scripts/clang-tools/run-clang-tools.py
index f754415..f426991 100755
--- a/kernel/scripts/clang-tools/run-clang-tools.py
+++ b/kernel/scripts/clang-tools/run-clang-tools.py
@@ -60,14 +60,21 @@
 
 
 def main():
-    args = parse_arguments()
+    try:
+        args = parse_arguments()
 
-    lock = multiprocessing.Lock()
-    pool = multiprocessing.Pool(initializer=init, initargs=(lock, args))
-    # Read JSON data into the datastore variable
-    with open(args.path, "r") as f:
-        datastore = json.load(f)
-        pool.map(run_analysis, datastore)
+        lock = multiprocessing.Lock()
+        pool = multiprocessing.Pool(initializer=init, initargs=(lock, args))
+        # Read JSON data into the datastore variable
+        with open(args.path, "r") as f:
+            datastore = json.load(f)
+            pool.map(run_analysis, datastore)
+    except BrokenPipeError:
+        # Python flushes standard streams on exit; redirect remaining output
+        # to devnull to avoid another BrokenPipeError at shutdown
+        devnull = os.open(os.devnull, os.O_WRONLY)
+        os.dup2(devnull, sys.stdout.fileno())
+        sys.exit(1)  # Python exits with error code 1 on EPIPE
 
 
 if __name__ == "__main__":
diff --git a/kernel/scripts/diffconfig b/kernel/scripts/diffconfig
index d5da5fa..43f0f3d 100755
--- a/kernel/scripts/diffconfig
+++ b/kernel/scripts/diffconfig
@@ -65,7 +65,7 @@
         else:
             print(" %s %s -> %s" % (config, value, new_value))
 
-def main():
+def show_diff():
     global merge_style
 
     # parse command line args
@@ -129,4 +129,16 @@
     for config in new:
         print_config("+", config, None, b[config])
 
-main()
+def main():
+    try:
+        show_diff()
+    except BrokenPipeError:
+        # Python flushes standard streams on exit; redirect remaining output
+        # to devnull to avoid another BrokenPipeError at shutdown
+        devnull = os.open(os.devnull, os.O_WRONLY)
+        os.dup2(devnull, sys.stdout.fileno())
+        sys.exit(1)  # Python exits with error code 1 on EPIPE
+
+
+if __name__ == '__main__':
+    main()
diff --git a/kernel/scripts/dummy-tools/gcc b/kernel/scripts/dummy-tools/gcc
index 346757a..485427f 100755
--- a/kernel/scripts/dummy-tools/gcc
+++ b/kernel/scripts/dummy-tools/gcc
@@ -67,6 +67,12 @@
 	fi
 fi
 
+# To set CONFIG_AS_IS_GNU
+if arg_contain -Wa,--version "$@"; then
+	echo "GNU assembler (scripts/dummy-tools) 2.50"
+	exit 0
+fi
+
 if arg_contain -S "$@"; then
 	# For scripts/gcc-x86-*-has-stack-protector.sh
 	if arg_contain -fstack-protector "$@"; then
diff --git a/kernel/scripts/gcc-plugins/gcc-common.h b/kernel/scripts/gcc-plugins/gcc-common.h
index 9ad76b7..6d4563b 100644
--- a/kernel/scripts/gcc-plugins/gcc-common.h
+++ b/kernel/scripts/gcc-plugins/gcc-common.h
@@ -108,7 +108,13 @@
 #include "varasm.h"
 #include "stor-layout.h"
 #include "internal-fn.h"
+#endif
+
+#include "gimple.h"
+
+#if BUILDING_GCC_VERSION >= 4009
 #include "gimple-expr.h"
+#include "gimple-iterator.h"
 #include "gimple-fold.h"
 #include "context.h"
 #include "tree-ssa-alias.h"
@@ -124,13 +130,10 @@
 #include "gimplify.h"
 #endif
 
-#include "gimple.h"
-
 #if BUILDING_GCC_VERSION >= 4009
 #include "tree-ssa-operands.h"
 #include "tree-phinodes.h"
 #include "tree-cfg.h"
-#include "gimple-iterator.h"
 #include "gimple-ssa.h"
 #include "ssa-iterators.h"
 #endif
diff --git a/kernel/scripts/gdb/linux/clk.py b/kernel/scripts/gdb/linux/clk.py
index 061aecf..7a01fdc 100644
--- a/kernel/scripts/gdb/linux/clk.py
+++ b/kernel/scripts/gdb/linux/clk.py
@@ -41,6 +41,8 @@
             self.show_subtree(child, level + 1)
 
     def invoke(self, arg, from_tty):
+        if utils.gdb_eval_or_none("clk_root_list") is None:
+            raise gdb.GdbError("No clocks registered")
         gdb.write("                                 enable  prepare  protect               \n")
         gdb.write("   clock                          count    count    count        rate   \n")
         gdb.write("------------------------------------------------------------------------\n")
diff --git a/kernel/scripts/gdb/linux/genpd.py b/kernel/scripts/gdb/linux/genpd.py
index 39cd1ab..b53649c 100644
--- a/kernel/scripts/gdb/linux/genpd.py
+++ b/kernel/scripts/gdb/linux/genpd.py
@@ -5,7 +5,7 @@
 import gdb
 import sys
 
-from linux.utils import CachedType
+from linux.utils import CachedType, gdb_eval_or_none
 from linux.lists import list_for_each_entry
 
 generic_pm_domain_type = CachedType('struct generic_pm_domain')
@@ -70,6 +70,8 @@
             gdb.write('    %-50s  %s\n' % (kobj_path, rtpm_status_str(dev)))
 
     def invoke(self, arg, from_tty):
+        if gdb_eval_or_none("&gpd_list") is None:
+            raise gdb.GdbError("No power domain(s) registered")
         gdb.write('domain                          status          children\n');
         gdb.write('    /device                                             runtime status\n');
         gdb.write('----------------------------------------------------------------------\n');
diff --git a/kernel/scripts/gdb/linux/timerlist.py b/kernel/scripts/gdb/linux/timerlist.py
index 071d0dd..51def84 100644
--- a/kernel/scripts/gdb/linux/timerlist.py
+++ b/kernel/scripts/gdb/linux/timerlist.py
@@ -73,7 +73,7 @@
     ts = cpus.per_cpu(tick_sched_ptr, cpu)
 
     text = "cpu: {}\n".format(cpu)
-    for i in xrange(max_clock_bases):
+    for i in range(max_clock_bases):
         text += " clock {}:\n".format(i)
         text += print_base(cpu_base['clock_base'][i])
 
@@ -158,6 +158,8 @@
     num_bytes = (nr_cpu_ids + 7) / 8
     buf = utils.read_memoryview(inf, bits, num_bytes).tobytes()
     buf = binascii.b2a_hex(buf)
+    if type(buf) is not str:
+        buf=buf.decode()
 
     chunks = []
     i = num_bytes
diff --git a/kernel/scripts/gdb/linux/utils.py b/kernel/scripts/gdb/linux/utils.py
index ff7c179..db59f98 100644
--- a/kernel/scripts/gdb/linux/utils.py
+++ b/kernel/scripts/gdb/linux/utils.py
@@ -89,7 +89,10 @@
 
 
 def read_memoryview(inf, start, length):
-    return memoryview(inf.read_memory(start, length))
+    m = inf.read_memory(start, length)
+    if type(m) is memoryview:
+        return m
+    return memoryview(m)
 
 
 def read_u16(buffer, offset):
diff --git a/kernel/scripts/kconfig/preprocess.c b/kernel/scripts/kconfig/preprocess.c
index 748da57..d1f5bcf 100644
--- a/kernel/scripts/kconfig/preprocess.c
+++ b/kernel/scripts/kconfig/preprocess.c
@@ -396,6 +396,9 @@
 
 		p++;
 	}
+
+	if (new_argc >= FUNCTION_MAX_ARGS)
+		pperror("too many function arguments");
 	new_argv[new_argc++] = prev;
 
 	/*
diff --git a/kernel/scripts/mod/file2alias.c b/kernel/scripts/mod/file2alias.c
index 2417dd1..da4df53 100644
--- a/kernel/scripts/mod/file2alias.c
+++ b/kernel/scripts/mod/file2alias.c
@@ -1490,7 +1490,7 @@
 	/* First handle the "special" cases */
 	if (sym_is(name, namelen, "usb"))
 		do_usb_table(symval, sym->st_size, mod);
-	if (sym_is(name, namelen, "of"))
+	else if (sym_is(name, namelen, "of"))
 		do_of_table(symval, sym->st_size, mod);
 	else if (sym_is(name, namelen, "pnp"))
 		do_pnp_device_entry(symval, sym->st_size, mod);
diff --git a/kernel/scripts/mod/modpost.c b/kernel/scripts/mod/modpost.c
index 0cb8de4..8a481e1 100644
--- a/kernel/scripts/mod/modpost.c
+++ b/kernel/scripts/mod/modpost.c
@@ -1309,6 +1309,10 @@
 	if (relsym->st_name != 0)
 		return relsym;
 
+	/*
+	 * Strive to find a better symbol name, but the resulting name may not
+	 * match the symbol referenced in the original code.
+	 */
 	relsym_secindex = get_secindex(elf, relsym);
 	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
 		if (get_secindex(elf, sym) != relsym_secindex)
@@ -1613,7 +1617,7 @@
 
 static int is_executable_section(struct elf_info* elf, unsigned int section_index)
 {
-	if (section_index > elf->num_sections)
+	if (section_index >= elf->num_sections)
 		fatal("section_index is outside elf->num_sections!\n");
 
 	return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR);
@@ -1788,19 +1792,33 @@
 #define	R_ARM_THM_JUMP19	51
 #endif
 
+static int32_t sign_extend32(int32_t value, int index)
+{
+	uint8_t shift = 31 - index;
+
+	return (int32_t)(value << shift) >> shift;
+}
+
 static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
 {
 	unsigned int r_typ = ELF_R_TYPE(r->r_info);
+	Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info);
+	void *loc = reloc_location(elf, sechdr, r);
+	uint32_t inst;
+	int32_t offset;
 
 	switch (r_typ) {
 	case R_ARM_ABS32:
-		/* From ARM ABI: (S + A) | T */
-		r->r_addend = (int)(long)
-			      (elf->symtab_start + ELF_R_SYM(r->r_info));
+		inst = TO_NATIVE(*(uint32_t *)loc);
+		r->r_addend = inst + sym->st_value;
 		break;
 	case R_ARM_PC24:
 	case R_ARM_CALL:
 	case R_ARM_JUMP24:
+		inst = TO_NATIVE(*(uint32_t *)loc);
+		offset = sign_extend32((inst & 0x00ffffff) << 2, 25);
+		r->r_addend = offset + sym->st_value + 8;
+		break;
 	case R_ARM_THM_CALL:
 	case R_ARM_THM_JUMP24:
 	case R_ARM_THM_JUMP19:
diff --git a/kernel/scripts/package/mkdebian b/kernel/scripts/package/mkdebian
index 60a2a63..32d528a 100755
--- a/kernel/scripts/package/mkdebian
+++ b/kernel/scripts/package/mkdebian
@@ -236,7 +236,7 @@
 	KBUILD_BUILD_VERSION=${revision} -f \$(srctree)/Makefile intdeb-pkg
 
 clean:
-	rm -rf debian/*tmp debian/files
+	rm -rf debian/files debian/linux-*
 	\$(MAKE) clean
 
 binary: binary-arch
diff --git a/kernel/scripts/recordmcount.c b/kernel/scripts/recordmcount.c
index cce12e1..ec692af 100644
--- a/kernel/scripts/recordmcount.c
+++ b/kernel/scripts/recordmcount.c
@@ -102,6 +102,7 @@
 {
 	size_t cnt = count;
 	off_t idx = 0;
+	void *p = NULL;
 
 	file_updated = 1;
 
@@ -109,7 +110,10 @@
 		off_t aoffset = (file_ptr + count) - file_end;
 
 		if (aoffset > file_append_size) {
-			file_append = realloc(file_append, aoffset);
+			p = realloc(file_append, aoffset);
+			if (!p)
+				free(file_append);
+			file_append = p;
 			file_append_size = aoffset;
 		}
 		if (!file_append) {
diff --git a/kernel/scripts/tags.sh b/kernel/scripts/tags.sh
index fd96734..d17801c 100755
--- a/kernel/scripts/tags.sh
+++ b/kernel/scripts/tags.sh
@@ -32,6 +32,13 @@
 	ignore="$ignore ( -path ${tree}tools ) -prune -o"
 fi
 
+# gtags(1) refuses to index any file outside of its current working dir.
+# If gtags indexing is requested and the build output directory is not
+# the kernel source tree, index all files in absolute-path form.
+if [[ "$1" == "gtags" && -n "${tree}" ]]; then
+	tree=$(realpath "$tree")/
+fi
+
 # Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH
 if [ "${ALLSOURCE_ARCHS}" = "" ]; then
 	ALLSOURCE_ARCHS=${SRCARCH}
@@ -95,10 +102,13 @@
 
 all_compiled_sources()
 {
-	realpath -es $([ -z "$KBUILD_ABS_SRCTREE" ] && echo --relative-to=.) \
-		include/generated/autoconf.h $(find $ignore -name "*.cmd" -exec \
-		grep -Poh '(?(?=^source_.* \K).*|(?=^  \K\S).*(?= \\))' {} \+ |
-		awk '!a[$0]++') | sort -u
+	{
+		echo include/generated/autoconf.h
+		find $ignore -name "*.cmd" -exec \
+			sed -n -E 's/^source_.* (.*)/\1/p; s/^  (\S.*) \\/\1/p' {} \+ |
+		awk '!a[$0]++'
+	} | xargs realpath -es $([ -z "$KBUILD_ABS_SRCTREE" ] && echo --relative-to=.) |
+	sort -u
 }
 
 all_target_sources()
@@ -128,7 +138,7 @@
 
 dogtags()
 {
-	all_target_sources | gtags -i -f -
+	all_target_sources | gtags -i -C "${tree:-.}" -f - "$PWD"
 }
 
 # Basic regular expressions with an optional /kind-spec/ for ctags and
diff --git a/kernel/scripts/tracing/ftrace-bisect.sh b/kernel/scripts/tracing/ftrace-bisect.sh
index 9267011..bb4f592 100755
--- a/kernel/scripts/tracing/ftrace-bisect.sh
+++ b/kernel/scripts/tracing/ftrace-bisect.sh
@@ -12,7 +12,7 @@
 #   (note, if this is a problem with function_graph tracing, then simply
 #    replace "function" with "function_graph" in the following steps).
 #
-#  # cd /sys/kernel/debug/tracing
+#  # cd /sys/kernel/tracing
 #  # echo schedule > set_ftrace_filter
 #  # echo function > current_tracer
 #
@@ -20,14 +20,32 @@
 #
 #  # echo nop > current_tracer
 #
-#  # cat available_filter_functions > ~/full-file
+# Starting with v5.1 this can be done with numbers, making it much faster:
+#
+# The old (slow) way, for kernels before v5.1.
+#
+# [old-way] # cat available_filter_functions > ~/full-file
+#
+# [old-way] *** Note ***  this process will take several minutes to update the
+# [old-way] filters. Setting multiple functions is an O(n^2) operation, and we
+# [old-way] are dealing with thousands of functions. So go have coffee, talk
+# [old-way] with your coworkers, read facebook. And eventually, this operation
+# [old-way] will end.
+#
+# The new way (using numbers) is an O(n) operation, and usually takes less than a second.
+#
+# seq `wc -l available_filter_functions | cut -d' ' -f1` > ~/full-file
+#
+# This will create a sequence of numbers that match the functions in
+# available_filter_functions, and when echoing in a number into the
+# set_ftrace_filter file, it will enable the corresponding function in
+# O(1) time. Making enabling all functions O(n) where n is the number of
+# functions to enable.
+#
+# For either the new or old way, the rest of the operations remain the same.
+#
 #  # ftrace-bisect ~/full-file ~/test-file ~/non-test-file
 #  # cat ~/test-file > set_ftrace_filter
-#
-# *** Note *** this will take several minutes. Setting multiple functions is
-# an O(n^2) operation, and we are dealing with thousands of functions. So go
-# have  coffee, talk with your coworkers, read facebook. And eventually, this
-# operation will end.
 #
 #  # echo function > current_tracer
 #
@@ -35,7 +53,7 @@
 #
 #   Reboot back to test kernel.
 #
-#     # cd /sys/kernel/debug/tracing
+#     # cd /sys/kernel/tracing
 #     # mv ~/test-file ~/full-file
 #
 # If it didn't crash.
diff --git a/kernel/security/apparmor/apparmorfs.c b/kernel/security/apparmor/apparmorfs.c
index c173f6f..49d97b3 100644
--- a/kernel/security/apparmor/apparmorfs.c
+++ b/kernel/security/apparmor/apparmorfs.c
@@ -867,8 +867,10 @@
 	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;
 }
diff --git a/kernel/security/apparmor/lsm.c b/kernel/security/apparmor/lsm.c
index ffeaee5..585edcc 100644
--- a/kernel/security/apparmor/lsm.c
+++ b/kernel/security/apparmor/lsm.c
@@ -1161,10 +1161,10 @@
 #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),
 };
diff --git a/kernel/security/apparmor/policy.c b/kernel/security/apparmor/policy.c
index 4c010c9..fcf2257 100644
--- a/kernel/security/apparmor/policy.c
+++ b/kernel/security/apparmor/policy.c
@@ -1125,7 +1125,7 @@
 
 	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);
diff --git a/kernel/security/apparmor/policy_ns.c b/kernel/security/apparmor/policy_ns.c
index 70921d9..53d24cf 100644
--- a/kernel/security/apparmor/policy_ns.c
+++ b/kernel/security/apparmor/policy_ns.c
@@ -121,7 +121,7 @@
 	return ns;
 
 fail_unconfined:
-	kfree_sensitive(ns->base.hname);
+	aa_policy_destroy(&ns->base);
 fail_ns:
 	kfree_sensitive(ns);
 	return NULL;
diff --git a/kernel/security/apparmor/policy_unpack.c b/kernel/security/apparmor/policy_unpack.c
index 556ef65..10896d6 100644
--- a/kernel/security/apparmor/policy_unpack.c
+++ b/kernel/security/apparmor/policy_unpack.c
@@ -909,8 +909,13 @@
 				goto fail;
 			}
 
-			rhashtable_insert_fast(profile->data, &data->head,
-					       profile->data->p);
+			if (rhashtable_insert_fast(profile->data, &data->head,
+						   profile->data->p)) {
+				kfree_sensitive(data->key);
+				kfree_sensitive(data);
+				info = "failed to insert data to table";
+				goto fail;
+			}
 		}
 
 		if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
@@ -964,7 +969,7 @@
 	 * 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;
diff --git a/kernel/security/device_cgroup.c b/kernel/security/device_cgroup.c
index 04375df..fe5cb76 100644
--- a/kernel/security/device_cgroup.c
+++ b/kernel/security/device_cgroup.c
@@ -81,6 +81,17 @@
 	return -ENOMEM;
 }
 
+static void dev_exceptions_move(struct list_head *dest, struct list_head *orig)
+{
+	struct dev_exception_item *ex, *tmp;
+
+	lockdep_assert_held(&devcgroup_mutex);
+
+	list_for_each_entry_safe(ex, tmp, orig, list) {
+		list_move_tail(&ex->list, dest);
+	}
+}
+
 /*
  * called under devcgroup_mutex
  */
@@ -603,11 +614,13 @@
 	int count, rc = 0;
 	struct dev_exception_item ex;
 	struct dev_cgroup *parent = css_to_devcgroup(devcgroup->css.parent);
+	struct dev_cgroup tmp_devcgrp;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
 	memset(&ex, 0, sizeof(ex));
+	memset(&tmp_devcgrp, 0, sizeof(tmp_devcgrp));
 	b = buffer;
 
 	switch (*b) {
@@ -619,15 +632,27 @@
 
 			if (!may_allow_all(parent))
 				return -EPERM;
-			dev_exception_clean(devcgroup);
-			devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
-			if (!parent)
+			if (!parent) {
+				devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
+				dev_exception_clean(devcgroup);
 				break;
+			}
 
-			rc = dev_exceptions_copy(&devcgroup->exceptions,
-						 &parent->exceptions);
+			INIT_LIST_HEAD(&tmp_devcgrp.exceptions);
+			rc = dev_exceptions_copy(&tmp_devcgrp.exceptions,
+						 &devcgroup->exceptions);
 			if (rc)
 				return rc;
+			dev_exception_clean(devcgroup);
+			rc = dev_exceptions_copy(&devcgroup->exceptions,
+						 &parent->exceptions);
+			if (rc) {
+				dev_exceptions_move(&devcgroup->exceptions,
+						    &tmp_devcgrp.exceptions);
+				return rc;
+			}
+			devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
+			dev_exception_clean(&tmp_devcgrp);
 			break;
 		case DEVCG_DENY:
 			if (css_has_online_children(&devcgroup->css))
diff --git a/kernel/security/integrity/digsig.c b/kernel/security/integrity/digsig.c
index 0f518dc..de442af 100644
--- a/kernel/security/integrity/digsig.c
+++ b/kernel/security/integrity/digsig.c
@@ -120,6 +120,7 @@
 {
 	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 @@
 	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,
diff --git a/kernel/security/integrity/evm/evm_main.c b/kernel/security/integrity/evm/evm_main.c
index c4e9a70..37ed819 100644
--- a/kernel/security/integrity/evm/evm_main.c
+++ b/kernel/security/integrity/evm/evm_main.c
@@ -473,7 +473,9 @@
 
 /**
  * evm_inode_setattr - prevent updating an invalid EVM extended attribute
+ * @idmap: idmap of the mount
  * @dentry: pointer to the affected dentry
+ * @attr: iattr structure containing the new file attributes
  *
  * Permit update of file attributes when files have a valid EVM signature,
  * except in the case of them having an immutable portable signature.
diff --git a/kernel/security/integrity/iint.c b/kernel/security/integrity/iint.c
index 0ba0184..9ed2d5b 100644
--- a/kernel/security/integrity/iint.c
+++ b/kernel/security/integrity/iint.c
@@ -43,12 +43,10 @@
 		else if (inode > iint->inode)
 			n = n->rb_right;
 		else
-			break;
+			return iint;
 	}
-	if (!n)
-		return NULL;
 
-	return iint;
+	return NULL;
 }
 
 /*
@@ -121,10 +119,15 @@
 		parent = *p;
 		test_iint = rb_entry(parent, struct integrity_iint_cache,
 				     rb_node);
-		if (inode < test_iint->inode)
+		if (inode < test_iint->inode) {
 			p = &(*p)->rb_left;
-		else
+		} else if (inode > test_iint->inode) {
 			p = &(*p)->rb_right;
+		} else {
+			write_unlock(&integrity_iint_lock);
+			kmem_cache_free(iint_cache, iint);
+			return test_iint;
+		}
 	}
 
 	iint->inode = inode;
diff --git a/kernel/security/integrity/ima/Kconfig b/kernel/security/integrity/ima/Kconfig
index 755af0b..d0d3ff5 100644
--- a/kernel/security/integrity/ima/Kconfig
+++ b/kernel/security/integrity/ima/Kconfig
@@ -8,7 +8,7 @@
 	select CRYPTO_HMAC
 	select CRYPTO_SHA1
 	select CRYPTO_HASH_INFO
-	select TCG_TPM if HAS_IOMEM && !UML
+	select TCG_TPM if HAS_IOMEM
 	select TCG_TIS if TCG_TPM && X86
 	select TCG_CRB if TCG_TPM && ACPI
 	select TCG_IBMVTPM if TCG_TPM && PPC_PSERIES
@@ -29,9 +29,11 @@
 	  to learn more about IMA.
 	  If unsure, say N.
 
+if IMA
+
 config IMA_KEXEC
 	bool "Enable carrying the IMA measurement list across a soft boot"
-	depends on IMA && TCG_TPM && HAVE_IMA_KEXEC
+	depends on TCG_TPM && HAVE_IMA_KEXEC
 	default n
 	help
 	   TPM PCRs are only reset on a hard reboot.  In order to validate
@@ -43,7 +45,6 @@
 
 config IMA_MEASURE_PCR_IDX
 	int
-	depends on IMA
 	range 8 14
 	default 10
 	help
@@ -53,7 +54,7 @@
 
 config IMA_LSM_RULES
 	bool
-	depends on IMA && AUDIT && (SECURITY_SELINUX || SECURITY_SMACK || SECURITY_APPARMOR)
+	depends on AUDIT && (SECURITY_SELINUX || SECURITY_SMACK || SECURITY_APPARMOR)
 	default y
 	help
 	  Disabling this option will disregard LSM based policy rules.
@@ -61,7 +62,6 @@
 choice
 	prompt "Default template"
 	default IMA_NG_TEMPLATE
-	depends on IMA
 	help
 	  Select the default IMA measurement template.
 
@@ -80,14 +80,12 @@
 
 config IMA_DEFAULT_TEMPLATE
 	string
-	depends on IMA
 	default "ima-ng" if IMA_NG_TEMPLATE
 	default "ima-sig" if IMA_SIG_TEMPLATE
 
 choice
 	prompt "Default integrity hash algorithm"
 	default IMA_DEFAULT_HASH_SHA1
-	depends on IMA
 	help
 	   Select the default hash algorithm used for the measurement
 	   list, integrity appraisal and audit log.  The compiled default
@@ -117,7 +115,6 @@
 
 config IMA_DEFAULT_HASH
 	string
-	depends on IMA
 	default "sha1" if IMA_DEFAULT_HASH_SHA1
 	default "sha256" if IMA_DEFAULT_HASH_SHA256
 	default "sha512" if IMA_DEFAULT_HASH_SHA512
@@ -126,7 +123,6 @@
 
 config IMA_WRITE_POLICY
 	bool "Enable multiple writes to the IMA policy"
-	depends on IMA
 	default n
 	help
 	  IMA policy can now be updated multiple times.  The new rules get
@@ -137,7 +133,6 @@
 
 config IMA_READ_POLICY
 	bool "Enable reading back the current IMA policy"
-	depends on IMA
 	default y if IMA_WRITE_POLICY
 	default n if !IMA_WRITE_POLICY
 	help
@@ -147,7 +142,6 @@
 
 config IMA_APPRAISE
 	bool "Appraise integrity measurements"
-	depends on IMA
 	default n
 	help
 	  This option enables local measurement integrity appraisal.
@@ -248,18 +242,6 @@
 	   The modsig keyword can be used in the IMA policy to allow a hook
 	   to accept such signatures.
 
-config IMA_TRUSTED_KEYRING
-	bool "Require all keys on the .ima keyring be signed (deprecated)"
-	depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING
-	depends on INTEGRITY_ASYMMETRIC_KEYS
-	select INTEGRITY_TRUSTED_KEYRING
-	default y
-	help
-	   This option requires that all keys added to the .ima
-	   keyring be signed by a key on the system trusted keyring.
-
-	   This option is deprecated in favor of INTEGRITY_TRUSTED_KEYRING
-
 config IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
 	bool "Permit keys validly signed by a built-in or secondary CA cert (EXPERIMENTAL)"
 	depends on SYSTEM_TRUSTED_KEYRING
@@ -280,7 +262,7 @@
 config IMA_BLACKLIST_KEYRING
 	bool "Create IMA machine owner blacklist keyrings (EXPERIMENTAL)"
 	depends on SYSTEM_TRUSTED_KEYRING
-	depends on IMA_TRUSTED_KEYRING
+	depends on INTEGRITY_TRUSTED_KEYRING
 	default n
 	help
 	   This option creates an IMA blacklist keyring, which contains all
@@ -290,7 +272,7 @@
 
 config IMA_LOAD_X509
 	bool "Load X509 certificate onto the '.ima' trusted keyring"
-	depends on IMA_TRUSTED_KEYRING
+	depends on INTEGRITY_TRUSTED_KEYRING
 	default n
 	help
 	   File signature verification is based on the public keys
@@ -315,7 +297,6 @@
 
 config IMA_MEASURE_ASYMMETRIC_KEYS
 	bool
-	depends on IMA
 	depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
 	default y
 
@@ -331,3 +312,5 @@
        help
           This option is selected by architectures to enable secure and/or
           trusted boot based on IMA runtime policies.
+
+endif
diff --git a/kernel/security/integrity/ima/ima_main.c b/kernel/security/integrity/ima/ima_main.c
index 2d1af88..dd4b28b 100644
--- a/kernel/security/integrity/ima/ima_main.c
+++ b/kernel/security/integrity/ima/ima_main.c
@@ -378,7 +378,9 @@
 /**
  * ima_file_mmap - based on policy, collect/store measurement.
  * @file: pointer to the file to be measured (May be NULL)
- * @prot: contains the protection that will be applied by the kernel.
+ * @reqprot: protection requested by the application
+ * @prot: protection that will be applied by the kernel
+ * @flags: operational flags
  *
  * Measure files being mmapped executable based on the ima_must_measure()
  * policy decision.
@@ -386,7 +388,8 @@
  * On success return 0.  On integrity appraisal error, assuming the file
  * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
  */
-int ima_file_mmap(struct file *file, unsigned long prot)
+int ima_file_mmap(struct file *file, unsigned long reqprot,
+		  unsigned long prot, unsigned long flags)
 {
 	u32 secid;
 
@@ -743,6 +746,7 @@
 			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/kernel/security/integrity/ima/ima_modsig.c b/kernel/security/integrity/ima/ima_modsig.c
index fb25723..3e7bee3 100644
--- a/kernel/security/integrity/ima/ima_modsig.c
+++ b/kernel/security/integrity/ima/ima_modsig.c
@@ -89,6 +89,9 @@
 
 /**
  * ima_collect_modsig - Calculate the file hash without the appended signature.
+ * @modsig: parsed module signature
+ * @buf: data to verify the signature on
+ * @size: data size
  *
  * Since the modsig is part of the file contents, the hash used in its signature
  * isn't the same one ordinarily calculated by IMA. Therefore PKCS7 code
diff --git a/kernel/security/integrity/ima/ima_policy.c b/kernel/security/integrity/ima/ima_policy.c
index 18569ad..1c403e8 100644
--- a/kernel/security/integrity/ima/ima_policy.c
+++ b/kernel/security/integrity/ima/ima_policy.c
@@ -370,12 +370,6 @@
 
 		nentry->lsm[i].type = entry->lsm[i].type;
 		nentry->lsm[i].args_p = entry->lsm[i].args_p;
-		/*
-		 * Remove the reference from entry so that the associated
-		 * memory will not be freed during a later call to
-		 * ima_lsm_free_rule(entry).
-		 */
-		entry->lsm[i].args_p = NULL;
 
 		ima_filter_rule_init(nentry->lsm[i].type, Audit_equal,
 				     nentry->lsm[i].args_p,
@@ -389,6 +383,7 @@
 
 static int ima_lsm_update_rule(struct ima_rule_entry *entry)
 {
+	int i;
 	struct ima_rule_entry *nentry;
 
 	nentry = ima_lsm_copy_rule(entry);
@@ -403,7 +398,8 @@
 	 * references and the entry itself. All other memory refrences will now
 	 * be owned by nentry.
 	 */
-	ima_lsm_free_rule(entry);
+	for (i = 0; i < MAX_LSM_RULES; i++)
+		ima_filter_rule_free(entry->lsm[i].rule);
 	kfree(entry);
 
 	return 0;
@@ -503,6 +499,9 @@
 			    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,34 +544,55 @@
 		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;
 }
 
 /*
@@ -608,6 +628,7 @@
  * @secid: LSM secid of the task to be validated
  * @func: IMA hook identifier
  * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
+ * @flags: IMA actions to consider (e.g. IMA_MEASURE | IMA_APPRAISE)
  * @pcr: set the pcr to extend
  * @template_desc: the template that should be used for this rule
  * @keyring: the keyring name, if given, to be used to check in the policy.
@@ -802,6 +823,7 @@
 		add_rules(default_measurement_rules,
 			  ARRAY_SIZE(default_measurement_rules),
 			  IMA_DEFAULT_POLICY);
+		break;
 	default:
 		break;
 	}
@@ -1494,7 +1516,7 @@
 
 /**
  * ima_parse_add_rule - add a rule to ima_policy_rules
- * @rule - ima measurement policy rule
+ * @rule: ima measurement policy rule
  *
  * Avoid locking by allowing just one writer at a time in ima_write_policy()
  * Returns the length of the rule parsed, an error code on failure
diff --git a/kernel/security/integrity/ima/ima_template.c b/kernel/security/integrity/ima/ima_template.c
index f64c01d..e5d941f 100644
--- a/kernel/security/integrity/ima/ima_template.c
+++ b/kernel/security/integrity/ima/ima_template.c
@@ -220,11 +220,11 @@
 	}
 
 	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;
 	}
 
@@ -290,8 +290,11 @@
 
 	template_desc->name = "";
 	template_desc->fmt = kstrdup(template_name, GFP_KERNEL);
-	if (!template_desc->fmt)
+	if (!template_desc->fmt) {
+		kfree(template_desc);
+		template_desc = NULL;
 		goto out;
+	}
 
 	spin_lock(&template_list);
 	list_add_tail_rcu(&template_desc->list, &defined_templates);
diff --git a/kernel/security/integrity/platform_certs/load_uefi.c b/kernel/security/integrity/platform_certs/load_uefi.c
index 185c609..d2f2c39 100644
--- a/kernel/security/integrity/platform_certs/load_uefi.c
+++ b/kernel/security/integrity/platform_certs/load_uefi.c
@@ -34,6 +34,7 @@
 	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacPro7,1") },
 	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,1") },
 	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,2") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMacPro1,1") },
 	{ }
 };
 
diff --git a/kernel/security/keys/keyctl.c b/kernel/security/keys/keyctl.c
index 61a614c..e3ffaf5 100644
--- a/kernel/security/keys/keyctl.c
+++ b/kernel/security/keys/keyctl.c
@@ -980,14 +980,19 @@
 	ret = -EACCES;
 	down_write(&key->sem);
 
-	if (!capable(CAP_SYS_ADMIN)) {
+	{
+		bool is_privileged_op = false;
+
 		/* only the sysadmin can chown a key to some other UID */
 		if (user != (uid_t) -1 && !uid_eq(key->uid, uid))
-			goto error_put;
+			is_privileged_op = true;
 
 		/* only the sysadmin can set the key's GID to a group other
 		 * than one of those that the current process subscribes to */
 		if (group != (gid_t) -1 && !gid_eq(gid, key->gid) && !in_group_p(gid))
+			is_privileged_op = true;
+
+		if (is_privileged_op && !capable(CAP_SYS_ADMIN))
 			goto error_put;
 	}
 
@@ -1088,7 +1093,7 @@
 	down_write(&key->sem);
 
 	/* if we're not the sysadmin, we can only change a key that we own */
-	if (capable(CAP_SYS_ADMIN) || uid_eq(key->uid, current_fsuid())) {
+	if (uid_eq(key->uid, current_fsuid()) || capable(CAP_SYS_ADMIN)) {
 		key->perm = perm;
 		notify_key(key, NOTIFY_KEY_SETATTR, 0);
 		ret = 0;
diff --git a/kernel/security/keys/request_key.c b/kernel/security/keys/request_key.c
index 2da4404..a7673ad 100644
--- a/kernel/security/keys/request_key.c
+++ b/kernel/security/keys/request_key.c
@@ -38,9 +38,12 @@
 #ifdef CONFIG_KEYS_REQUEST_CACHE
 	struct task_struct *t = current;
 
-	key_put(t->cached_requested_key);
-	t->cached_requested_key = key_get(key);
-	set_tsk_thread_flag(t, TIF_NOTIFY_RESUME);
+	/* Do not cache key if it is a kernel thread */
+	if (!(t->flags & PF_KTHREAD)) {
+		key_put(t->cached_requested_key);
+		t->cached_requested_key = key_get(key);
+		set_tsk_thread_flag(t, TIF_NOTIFY_RESUME);
+	}
 #endif
 }
 
@@ -398,17 +401,21 @@
 	set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
 
 	if (dest_keyring) {
-		ret = __key_link_lock(dest_keyring, &ctx->index_key);
+		ret = __key_link_lock(dest_keyring, &key->index_key);
 		if (ret < 0)
 			goto link_lock_failed;
-		ret = __key_link_begin(dest_keyring, &ctx->index_key, &edit);
-		if (ret < 0)
-			goto link_prealloc_failed;
 	}
 
-	/* attach the key to the destination keyring under lock, but we do need
+	/*
+	 * Attach the key to the destination keyring under lock, but we do need
 	 * to do another check just in case someone beat us to it whilst we
-	 * waited for locks */
+	 * waited for locks.
+	 *
+	 * The caller might specify a comparison function which looks for keys
+	 * that do not exactly match but are still equivalent from the caller's
+	 * perspective. The __key_link_begin() operation must be done only after
+	 * an actual key is determined.
+	 */
 	mutex_lock(&key_construction_mutex);
 
 	rcu_read_lock();
@@ -417,12 +424,16 @@
 	if (!IS_ERR(key_ref))
 		goto key_already_present;
 
-	if (dest_keyring)
+	if (dest_keyring) {
+		ret = __key_link_begin(dest_keyring, &key->index_key, &edit);
+		if (ret < 0)
+			goto link_alloc_failed;
 		__key_link(dest_keyring, key, &edit);
+	}
 
 	mutex_unlock(&key_construction_mutex);
 	if (dest_keyring)
-		__key_link_end(dest_keyring, &ctx->index_key, edit);
+		__key_link_end(dest_keyring, &key->index_key, edit);
 	mutex_unlock(&user->cons_lock);
 	*_key = key;
 	kleave(" = 0 [%d]", key_serial(key));
@@ -435,10 +446,13 @@
 	mutex_unlock(&key_construction_mutex);
 	key = key_ref_to_ptr(key_ref);
 	if (dest_keyring) {
+		ret = __key_link_begin(dest_keyring, &key->index_key, &edit);
+		if (ret < 0)
+			goto link_alloc_failed_unlocked;
 		ret = __key_link_check_live_key(dest_keyring, key);
 		if (ret == 0)
 			__key_link(dest_keyring, key, &edit);
-		__key_link_end(dest_keyring, &ctx->index_key, edit);
+		__key_link_end(dest_keyring, &key->index_key, edit);
 		if (ret < 0)
 			goto link_check_failed;
 	}
@@ -453,8 +467,10 @@
 	kleave(" = %d [linkcheck]", ret);
 	return ret;
 
-link_prealloc_failed:
-	__key_link_end(dest_keyring, &ctx->index_key, edit);
+link_alloc_failed:
+	mutex_unlock(&key_construction_mutex);
+link_alloc_failed_unlocked:
+	__key_link_end(dest_keyring, &key->index_key, edit);
 link_lock_failed:
 	mutex_unlock(&user->cons_lock);
 	key_put(key);
diff --git a/kernel/security/keys/trusted-keys/trusted_tpm2.c b/kernel/security/keys/trusted-keys/trusted_tpm2.c
index 4c19d3a..65f6885 100644
--- a/kernel/security/keys/trusted-keys/trusted_tpm2.c
+++ b/kernel/security/keys/trusted-keys/trusted_tpm2.c
@@ -21,7 +21,7 @@
 };
 
 /**
- * tpm_buf_append_auth() - append TPMS_AUTH_COMMAND to the buffer.
+ * tpm2_buf_append_auth() - append TPMS_AUTH_COMMAND to the buffer.
  *
  * @buf: an allocated tpm_buf instance
  * @session_handle: session handle
diff --git a/kernel/security/loadpin/loadpin.c b/kernel/security/loadpin/loadpin.c
index b12f7d9..5fce105 100644
--- a/kernel/security/loadpin/loadpin.c
+++ b/kernel/security/loadpin/loadpin.c
@@ -118,20 +118,10 @@
 	}
 }
 
-static int loadpin_read_file(struct file *file, enum kernel_read_file_id id,
-			     bool contents)
+static int loadpin_check(struct file *file, enum kernel_read_file_id id)
 {
 	struct super_block *load_root;
 	const char *origin = kernel_read_file_id_str(id);
-
-	/*
-	 * If we will not know that we'll be seeing the full contents
-	 * then we cannot trust a load will be complete and unchanged
-	 * off disk. Treat all contents=false hooks as if there were
-	 * no associated file struct.
-	 */
-	if (!contents)
-		file = NULL;
 
 	/* If the file id is excluded, ignore the pinning. */
 	if ((unsigned int)id < ARRAY_SIZE(ignore_read_file_id) &&
@@ -187,9 +177,25 @@
 	return 0;
 }
 
+static int loadpin_read_file(struct file *file, enum kernel_read_file_id id,
+			     bool contents)
+{
+	/*
+	 * LoadPin only cares about the _origin_ of a file, not its
+	 * contents, so we can ignore the "are full contents available"
+	 * argument here.
+	 */
+	return loadpin_check(file, id);
+}
+
 static int loadpin_load_data(enum kernel_load_data_id id, bool contents)
 {
-	return loadpin_read_file(NULL, (enum kernel_read_file_id) id, contents);
+	/*
+	 * LoadPin only cares about the _origin_ of a file, not its
+	 * contents, so a NULL file is passed, and we can ignore the
+	 * state of "contents".
+	 */
+	return loadpin_check(NULL, (enum kernel_read_file_id) id);
 }
 
 static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = {
diff --git a/kernel/security/security.c b/kernel/security/security.c
index 615c42b..2964588 100644
--- a/kernel/security/security.c
+++ b/kernel/security/security.c
@@ -1506,12 +1506,13 @@
 int security_mmap_file(struct file *file, unsigned long prot,
 			unsigned long flags)
 {
+	unsigned long prot_adj = mmap_prot(file, prot);
 	int ret;
-	ret = call_int_hook(mmap_file, 0, file, prot,
-					mmap_prot(file, prot), flags);
+
+	ret = call_int_hook(mmap_file, 0, file, prot, prot_adj, flags);
 	if (ret)
 		return ret;
-	return ima_file_mmap(file, prot);
+	return ima_file_mmap(file, prot, prot_adj, flags);
 }
 
 int security_mmap_addr(unsigned long addr)
diff --git a/kernel/security/selinux/Makefile b/kernel/security/selinux/Makefile
index 8e8102b..d6651c7 100644
--- a/kernel/security/selinux/Makefile
+++ b/kernel/security/selinux/Makefile
@@ -23,8 +23,12 @@
 $(addprefix $(obj)/,$(selinux-y)): $(obj)/flask.h
 
 quiet_cmd_flask = GEN     $(obj)/flask.h $(obj)/av_permissions.h
-      cmd_flask = scripts/selinux/genheaders/genheaders $(obj)/flask.h $(obj)/av_permissions.h
+      cmd_flask = $< $(obj)/flask.h $(obj)/av_permissions.h
 
 targets += flask.h av_permissions.h
-$(obj)/flask.h: $(src)/include/classmap.h FORCE
+# once make >= 4.3 is required, we can use grouped targets in the rule below,
+# which basically involves adding both headers and a '&' before the colon, see
+# the example below:
+#   $(obj)/flask.h $(obj)/av_permissions.h &: scripts/selinux/...
+$(obj)/flask.h: scripts/selinux/genheaders/genheaders FORCE
 	$(call if_changed,flask)
diff --git a/kernel/security/selinux/ss/policydb.c b/kernel/security/selinux/ss/policydb.c
index ef30a84..9e5998c 100644
--- a/kernel/security/selinux/ss/policydb.c
+++ b/kernel/security/selinux/ss/policydb.c
@@ -2011,6 +2011,7 @@
 		if (!datum)
 			goto out;
 
+		datum->next = NULL;
 		*dst = datum;
 
 		/* ebitmap_read() will at least init the bitmap */
@@ -2023,7 +2024,6 @@
 			goto out;
 
 		datum->otype = le32_to_cpu(buf[0]);
-		datum->next = NULL;
 
 		dst = &datum->next;
 	}
diff --git a/kernel/security/smack/smack.h b/kernel/security/smack/smack.h
index a9768b1..b518791 100644
--- a/kernel/security/smack/smack.h
+++ b/kernel/security/smack/smack.h
@@ -120,6 +120,7 @@
 struct task_smack {
 	struct smack_known	*smk_task;	/* label for access control */
 	struct smack_known	*smk_forked;	/* label when forked */
+	struct smack_known	*smk_transmuted;/* label when transmuted */
 	struct list_head	smk_rules;	/* per task access rules */
 	struct mutex		smk_rules_lock;	/* lock for the rules */
 	struct list_head	smk_relabel;	/* transit allowed labels */
diff --git a/kernel/security/smack/smack_lsm.c b/kernel/security/smack/smack_lsm.c
index d24b970..24f8e89 100644
--- a/kernel/security/smack/smack_lsm.c
+++ b/kernel/security/smack/smack_lsm.c
@@ -973,8 +973,9 @@
 				     const struct qstr *qstr, const char **name,
 				     void **value, size_t *len)
 {
+	struct task_smack *tsp = smack_cred(current_cred());
 	struct inode_smack *issp = smack_inode(inode);
-	struct smack_known *skp = smk_of_current();
+	struct smack_known *skp = smk_of_task(tsp);
 	struct smack_known *isp = smk_of_inode(inode);
 	struct smack_known *dsp = smk_of_inode(dir);
 	int may;
@@ -983,20 +984,34 @@
 		*name = XATTR_SMACK_SUFFIX;
 
 	if (value && len) {
-		rcu_read_lock();
-		may = smk_access_entry(skp->smk_known, dsp->smk_known,
-				       &skp->smk_rules);
-		rcu_read_unlock();
+		/*
+		 * If equal, transmuting already occurred in
+		 * smack_dentry_create_files_as(). No need to check again.
+		 */
+		if (tsp->smk_task != tsp->smk_transmuted) {
+			rcu_read_lock();
+			may = smk_access_entry(skp->smk_known, dsp->smk_known,
+					       &skp->smk_rules);
+			rcu_read_unlock();
+		}
 
 		/*
-		 * If the access rule allows transmutation and
-		 * the directory requests transmutation then
-		 * by all means transmute.
+		 * In addition to having smk_task equal to smk_transmuted,
+		 * if the access rule allows transmutation and the directory
+		 * requests transmutation then by all means transmute.
 		 * Mark the inode as changed.
 		 */
-		if (may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
-		    smk_inode_transmutable(dir)) {
-			isp = dsp;
+		if ((tsp->smk_task == tsp->smk_transmuted) ||
+		    (may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
+		     smk_inode_transmutable(dir))) {
+			/*
+			 * The caller of smack_dentry_create_files_as()
+			 * should have overridden the current cred, so the
+			 * inode label was already set correctly in
+			 * smack_inode_alloc_security().
+			 */
+			if (tsp->smk_task != tsp->smk_transmuted)
+				isp = dsp;
 			issp->smk_flags |= SMK_INODE_CHANGED;
 		}
 
@@ -1430,10 +1445,19 @@
 	struct super_block *sbp;
 	struct inode *ip = (struct inode *)inode;
 	struct smack_known *isp;
+	struct inode_smack *ispp;
+	size_t label_len;
+	char *label = NULL;
 
-	if (strcmp(name, XATTR_SMACK_SUFFIX) == 0)
+	if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
 		isp = smk_of_inode(inode);
-	else {
+	} else if (strcmp(name, XATTR_SMACK_TRANSMUTE) == 0) {
+		ispp = smack_inode(inode);
+		if (ispp->smk_flags & SMK_INODE_TRANSMUTE)
+			label = TRANS_TRUE;
+		else
+			label = "";
+	} else {
 		/*
 		 * The rest of the Smack xattrs are only on sockets.
 		 */
@@ -1455,13 +1479,18 @@
 			return -EOPNOTSUPP;
 	}
 
+	if (!label)
+		label = isp->smk_known;
+
+	label_len = strlen(label);
+
 	if (alloc) {
-		*buffer = kstrdup(isp->smk_known, GFP_KERNEL);
+		*buffer = kstrdup(label, GFP_KERNEL);
 		if (*buffer == NULL)
 			return -ENOMEM;
 	}
 
-	return strlen(isp->smk_known);
+	return label_len;
 }
 
 
@@ -4635,7 +4664,7 @@
 	/*
 	 * Get label from overlay inode and set it in create_sid
 	 */
-	isp = smack_inode(d_inode(dentry->d_parent));
+	isp = smack_inode(d_inode(dentry));
 	skp = isp->smk_inode;
 	tsp->smk_task = skp;
 	*new = new_creds;
@@ -4686,8 +4715,10 @@
 		 * providing access is transmuting use the containing
 		 * directory label instead of the process label.
 		 */
-		if (may > 0 && (may & MAY_TRANSMUTE))
+		if (may > 0 && (may & MAY_TRANSMUTE)) {
 			ntsp->smk_task = isp->smk_inode;
+			ntsp->smk_transmuted = ntsp->smk_task;
+		}
 	}
 	return 0;
 }
diff --git a/kernel/security/smack/smackfs.c b/kernel/security/smack/smackfs.c
index 3eabcc4..8403c91 100644
--- a/kernel/security/smack/smackfs.c
+++ b/kernel/security/smack/smackfs.c
@@ -895,7 +895,7 @@
 	}
 
 	ret = sscanf(rule, "%d", &catlen);
-	if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM)
+	if (ret != 1 || catlen < 0 || catlen > SMACK_CIPSO_MAXCATNUM)
 		goto out;
 
 	if (format == SMK_FIXED24_FMT &&
diff --git a/kernel/security/tomoyo/Makefile b/kernel/security/tomoyo/Makefile
index cca5a30..221eaad 100644
--- a/kernel/security/tomoyo/Makefile
+++ b/kernel/security/tomoyo/Makefile
@@ -10,7 +10,7 @@
 quiet_cmd_policy  = POLICY  $@
       cmd_policy  = ($(call do_policy,profile); $(call do_policy,exception_policy); $(call do_policy,domain_policy); $(call do_policy,manager); $(call do_policy,stat)) >$@
 
-$(obj)/builtin-policy.h: $(wildcard $(obj)/policy/*.conf $(src)/policy/*.conf.default) FORCE
+$(obj)/builtin-policy.h: $(wildcard $(obj)/policy/*.conf $(srctree)/$(src)/policy/*.conf.default) FORCE
 	$(call if_changed,policy)
 
 $(obj)/common.o: $(obj)/builtin-policy.h
diff --git a/kernel/sound/Kconfig b/kernel/sound/Kconfig
index 3678541..aaf2022 100644
--- a/kernel/sound/Kconfig
+++ b/kernel/sound/Kconfig
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 menuconfig SOUND
 	tristate "Sound card support"
-	depends on HAS_IOMEM
+	depends on HAS_IOMEM || UML
 	help
 	  If you have a sound card in your computer, i.e. if it can say more
 	  than an occasional beep, say Y.
diff --git a/kernel/sound/core/jack.c b/kernel/sound/core/jack.c
index dc2e06a..ddfee8b 100644
--- a/kernel/sound/core/jack.c
+++ b/kernel/sound/core/jack.c
@@ -348,6 +348,7 @@
 {
 	struct snd_jack_kctl *jack_kctl;
 #ifdef CONFIG_SND_JACK_INPUT_DEV
+	struct input_dev *idev;
 	int i;
 #endif
 
@@ -359,26 +360,28 @@
 					    status & jack_kctl->mask_bits);
 
 #ifdef CONFIG_SND_JACK_INPUT_DEV
-	if (!jack->input_dev)
+	idev = input_get_device(jack->input_dev);
+	if (!idev)
 		return;
 
 	for (i = 0; i < ARRAY_SIZE(jack->key); i++) {
 		int testbit = SND_JACK_BTN_0 >> i;
 
 		if (jack->type & testbit)
-			input_report_key(jack->input_dev, jack->key[i],
+			input_report_key(idev, jack->key[i],
 					 status & testbit);
 	}
 
 	for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) {
 		int testbit = 1 << i;
 		if (jack->type & testbit)
-			input_report_switch(jack->input_dev,
+			input_report_switch(idev,
 					    jack_switch_types[i],
 					    status & testbit);
 	}
 
-	input_sync(jack->input_dev);
+	input_sync(idev);
+	input_put_device(idev);
 #endif /* CONFIG_SND_JACK_INPUT_DEV */
 }
 EXPORT_SYMBOL(snd_jack_report);
diff --git a/kernel/sound/core/oss/pcm_plugin.h b/kernel/sound/core/oss/pcm_plugin.h
index 46e273b..50a6b50 100644
--- a/kernel/sound/core/oss/pcm_plugin.h
+++ b/kernel/sound/core/oss/pcm_plugin.h
@@ -141,6 +141,14 @@
 
 void *snd_pcm_plug_buf_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t size);
 void snd_pcm_plug_buf_unlock(struct snd_pcm_substream *plug, void *ptr);
+#else
+
+static inline snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size) { return drv_size; }
+static inline snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size) { return clt_size; }
+static inline int snd_pcm_plug_slave_format(int format, const struct snd_mask *format_mask) { return format; }
+
+#endif
+
 snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream,
 				     const char *ptr, snd_pcm_uframes_t size,
 				     int in_kernel);
@@ -150,14 +158,6 @@
 				      void **bufs, snd_pcm_uframes_t frames);
 snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream,
 				     void **bufs, snd_pcm_uframes_t frames);
-
-#else
-
-static inline snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size) { return drv_size; }
-static inline snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size) { return clt_size; }
-static inline int snd_pcm_plug_slave_format(int format, const struct snd_mask *format_mask) { return format; }
-
-#endif
 
 #ifdef PLUGIN_DEBUG
 #define pdprintf(fmt, args...) printk(KERN_DEBUG "plugin: " fmt, ##args)
diff --git a/kernel/sound/core/pcm_compat.c b/kernel/sound/core/pcm_compat.c
index a226d8f..fd644a3 100644
--- a/kernel/sound/core/pcm_compat.c
+++ b/kernel/sound/core/pcm_compat.c
@@ -252,10 +252,14 @@
 		goto error;
 	}
 
-	if (refine)
+	if (refine) {
 		err = snd_pcm_hw_refine(substream, data);
-	else
+		if (err < 0)
+			goto error;
+		err = fixup_unreferenced_params(substream, data);
+	} else {
 		err = snd_pcm_hw_params(substream, data);
+	}
 	if (err < 0)
 		goto error;
 	if (copy_to_user(data32, data, sizeof(*data32)) ||
diff --git a/kernel/sound/core/pcm_memory.c b/kernel/sound/core/pcm_memory.c
index 1918838..3e60a33 100644
--- a/kernel/sound/core/pcm_memory.c
+++ b/kernel/sound/core/pcm_memory.c
@@ -31,20 +31,51 @@
 module_param(max_alloc_per_card, ulong, 0644);
 MODULE_PARM_DESC(max_alloc_per_card, "Max total allocation bytes per card.");
 
+static void __update_allocated_size(struct snd_card *card, ssize_t bytes)
+{
+	card->total_pcm_alloc_bytes += bytes;
+}
+
+static void update_allocated_size(struct snd_card *card, ssize_t bytes)
+{
+	mutex_lock(&card->memory_mutex);
+	__update_allocated_size(card, bytes);
+	mutex_unlock(&card->memory_mutex);
+}
+
+static void decrease_allocated_size(struct snd_card *card, size_t bytes)
+{
+	mutex_lock(&card->memory_mutex);
+	WARN_ON(card->total_pcm_alloc_bytes < bytes);
+	__update_allocated_size(card, -(ssize_t)bytes);
+	mutex_unlock(&card->memory_mutex);
+}
+
 static int do_alloc_pages(struct snd_card *card, int type, struct device *dev,
 			  size_t size, struct snd_dma_buffer *dmab)
 {
 	int err;
 
+	/* check and reserve the requested size */
+	mutex_lock(&card->memory_mutex);
 	if (max_alloc_per_card &&
-	    card->total_pcm_alloc_bytes + size > max_alloc_per_card)
+	    card->total_pcm_alloc_bytes + size > max_alloc_per_card) {
+		mutex_unlock(&card->memory_mutex);
 		return -ENOMEM;
+	}
+	__update_allocated_size(card, size);
+	mutex_unlock(&card->memory_mutex);
 
 	err = snd_dma_alloc_pages(type, dev, size, dmab);
 	if (!err) {
-		mutex_lock(&card->memory_mutex);
-		card->total_pcm_alloc_bytes += dmab->bytes;
-		mutex_unlock(&card->memory_mutex);
+		/* the actual allocation size might be bigger than requested,
+		 * and we need to correct the account
+		 */
+		if (dmab->bytes != size)
+			update_allocated_size(card, dmab->bytes - size);
+	} else {
+		/* take back on allocation failure */
+		decrease_allocated_size(card, size);
 	}
 	return err;
 }
@@ -53,10 +84,7 @@
 {
 	if (!dmab->area)
 		return;
-	mutex_lock(&card->memory_mutex);
-	WARN_ON(card->total_pcm_alloc_bytes < dmab->bytes);
-	card->total_pcm_alloc_bytes -= dmab->bytes;
-	mutex_unlock(&card->memory_mutex);
+	decrease_allocated_size(card, dmab->bytes);
 	snd_dma_free_pages(dmab);
 	dmab->area = NULL;
 }
diff --git a/kernel/sound/core/pcm_native.c b/kernel/sound/core/pcm_native.c
index 6cc7c2a..9425fcd 100644
--- a/kernel/sound/core/pcm_native.c
+++ b/kernel/sound/core/pcm_native.c
@@ -1413,8 +1413,10 @@
 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,
diff --git a/kernel/sound/core/seq/oss/seq_oss_midi.c b/kernel/sound/core/seq/oss/seq_oss_midi.c
index f73ee07..be80ce7 100644
--- a/kernel/sound/core/seq/oss/seq_oss_midi.c
+++ b/kernel/sound/core/seq/oss/seq_oss_midi.c
@@ -37,6 +37,7 @@
 	struct snd_midi_event *coder;	/* MIDI event coder */
 	struct seq_oss_devinfo *devinfo;	/* assigned OSSseq device */
 	snd_use_lock_t use_lock;
+	struct mutex open_mutex;
 };
 
 
@@ -171,6 +172,7 @@
 	mdev->flags = pinfo->capability;
 	mdev->opened = 0;
 	snd_use_lock_init(&mdev->use_lock);
+	mutex_init(&mdev->open_mutex);
 
 	/* copy and truncate the name of synth device */
 	strlcpy(mdev->name, pinfo->name, sizeof(mdev->name));
@@ -319,14 +321,16 @@
 	int perm;
 	struct seq_oss_midi *mdev;
 	struct snd_seq_port_subscribe subs;
+	int err;
 
 	if ((mdev = get_mididev(dp, dev)) == NULL)
 		return -ENODEV;
 
+	mutex_lock(&mdev->open_mutex);
 	/* already used? */
 	if (mdev->opened && mdev->devinfo != dp) {
-		snd_use_lock_free(&mdev->use_lock);
-		return -EBUSY;
+		err = -EBUSY;
+		goto unlock;
 	}
 
 	perm = 0;
@@ -336,14 +340,14 @@
 		perm |= PERM_READ;
 	perm &= mdev->flags;
 	if (perm == 0) {
-		snd_use_lock_free(&mdev->use_lock);
-		return -ENXIO;
+		err = -ENXIO;
+		goto unlock;
 	}
 
 	/* already opened? */
 	if ((mdev->opened & perm) == perm) {
-		snd_use_lock_free(&mdev->use_lock);
-		return 0;
+		err = 0;
+		goto unlock;
 	}
 
 	perm &= ~mdev->opened;
@@ -368,13 +372,17 @@
 	}
 
 	if (! mdev->opened) {
-		snd_use_lock_free(&mdev->use_lock);
-		return -ENXIO;
+		err = -ENXIO;
+		goto unlock;
 	}
 
 	mdev->devinfo = dp;
+	err = 0;
+
+ unlock:
+	mutex_unlock(&mdev->open_mutex);
 	snd_use_lock_free(&mdev->use_lock);
-	return 0;
+	return err;
 }
 
 /*
@@ -388,10 +396,9 @@
 
 	if ((mdev = get_mididev(dp, dev)) == NULL)
 		return -ENODEV;
-	if (! mdev->opened || mdev->devinfo != dp) {
-		snd_use_lock_free(&mdev->use_lock);
-		return 0;
-	}
+	mutex_lock(&mdev->open_mutex);
+	if (!mdev->opened || mdev->devinfo != dp)
+		goto unlock;
 
 	memset(&subs, 0, sizeof(subs));
 	if (mdev->opened & PERM_WRITE) {
@@ -410,6 +417,8 @@
 	mdev->opened = 0;
 	mdev->devinfo = NULL;
 
+ unlock:
+	mutex_unlock(&mdev->open_mutex);
 	snd_use_lock_free(&mdev->use_lock);
 	return 0;
 }
diff --git a/kernel/sound/drivers/mts64.c b/kernel/sound/drivers/mts64.c
index 9c708b6..2573149 100644
--- a/kernel/sound/drivers/mts64.c
+++ b/kernel/sound/drivers/mts64.c
@@ -816,6 +816,9 @@
 	u8 status, data;
 	struct snd_rawmidi_substream *substream;
 
+	if (!mts)
+		return;
+
 	spin_lock(&mts->lock);
 	ret = mts64_read(mts->pardev->port);
 	data = ret & 0x00ff;
diff --git a/kernel/sound/firewire/digi00x/digi00x-stream.c b/kernel/sound/firewire/digi00x/digi00x-stream.c
index 405d690..62a54f5 100644
--- a/kernel/sound/firewire/digi00x/digi00x-stream.c
+++ b/kernel/sound/firewire/digi00x/digi00x-stream.c
@@ -259,8 +259,10 @@
 		return err;
 
 	err = init_stream(dg00x, &dg00x->tx_stream);
-	if (err < 0)
+	if (err < 0) {
 		destroy_stream(dg00x, &dg00x->rx_stream);
+		return err;
+	}
 
 	err = amdtp_domain_init(&dg00x->domain);
 	if (err < 0) {
diff --git a/kernel/sound/firewire/tascam/tascam-stream.c b/kernel/sound/firewire/tascam/tascam-stream.c
index eb07e1d..47de972 100644
--- a/kernel/sound/firewire/tascam/tascam-stream.c
+++ b/kernel/sound/firewire/tascam/tascam-stream.c
@@ -475,7 +475,7 @@
 
 		err = amdtp_domain_start(&tscm->domain, 0);
 		if (err < 0)
-			return err;
+			goto error;
 
 		if (!amdtp_stream_wait_callback(&tscm->rx_stream,
 						CALLBACK_TIMEOUT) ||
diff --git a/kernel/sound/hda/ext/hdac_ext_stream.c b/kernel/sound/hda/ext/hdac_ext_stream.c
index 1e6e4cf..4276dae 100644
--- a/kernel/sound/hda/ext/hdac_ext_stream.c
+++ b/kernel/sound/hda/ext/hdac_ext_stream.c
@@ -475,23 +475,6 @@
 }
 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_get_spbmaxfifo);
 
-
-/**
- * snd_hdac_ext_stop_streams - stop all stream if running
- * @bus: HD-audio core bus
- */
-void snd_hdac_ext_stop_streams(struct hdac_bus *bus)
-{
-	struct hdac_stream *stream;
-
-	if (bus->chip_init) {
-		list_for_each_entry(stream, &bus->stream_list, list)
-			snd_hdac_stream_stop(stream);
-		snd_hdac_bus_stop_chip(bus);
-	}
-}
-EXPORT_SYMBOL_GPL(snd_hdac_ext_stop_streams);
-
 /**
  * snd_hdac_ext_stream_drsm_enable - enable DMA resume for a stream
  * @bus: HD-audio core bus
diff --git a/kernel/sound/hda/hdac_device.c b/kernel/sound/hda/hdac_device.c
index b7e5032..bfd8585 100644
--- a/kernel/sound/hda/hdac_device.c
+++ b/kernel/sound/hda/hdac_device.c
@@ -611,7 +611,7 @@
 int snd_hdac_keep_power_up(struct hdac_device *codec)
 {
 	if (!atomic_inc_not_zero(&codec->in_pm)) {
-		int ret = pm_runtime_get_if_in_use(&codec->dev);
+		int ret = pm_runtime_get_if_active(&codec->dev, true);
 		if (!ret)
 			return -1;
 		if (ret < 0)
diff --git a/kernel/sound/hda/hdac_regmap.c b/kernel/sound/hda/hdac_regmap.c
index d75f31e..bf35acc 100644
--- a/kernel/sound/hda/hdac_regmap.c
+++ b/kernel/sound/hda/hdac_regmap.c
@@ -597,10 +597,9 @@
  */
 void snd_hdac_regmap_sync(struct hdac_device *codec)
 {
-	if (codec->regmap) {
-		mutex_lock(&codec->regmap_lock);
+	mutex_lock(&codec->regmap_lock);
+	if (codec->regmap)
 		regcache_sync(codec->regmap);
-		mutex_unlock(&codec->regmap_lock);
-	}
+	mutex_unlock(&codec->regmap_lock);
 }
 EXPORT_SYMBOL_GPL(snd_hdac_regmap_sync);
diff --git a/kernel/sound/hda/hdac_stream.c b/kernel/sound/hda/hdac_stream.c
index ce77a53..1e0f61a 100644
--- a/kernel/sound/hda/hdac_stream.c
+++ b/kernel/sound/hda/hdac_stream.c
@@ -143,6 +143,33 @@
 EXPORT_SYMBOL_GPL(snd_hdac_stream_stop);
 
 /**
+ * snd_hdac_stop_streams - stop all streams
+ * @bus: HD-audio core bus
+ */
+void snd_hdac_stop_streams(struct hdac_bus *bus)
+{
+	struct hdac_stream *stream;
+
+	list_for_each_entry(stream, &bus->stream_list, list)
+		snd_hdac_stream_stop(stream);
+}
+EXPORT_SYMBOL_GPL(snd_hdac_stop_streams);
+
+/**
+ * snd_hdac_stop_streams_and_chip - stop all streams and chip if running
+ * @bus: HD-audio core bus
+ */
+void snd_hdac_stop_streams_and_chip(struct hdac_bus *bus)
+{
+
+	if (bus->chip_init) {
+		snd_hdac_stop_streams(bus);
+		snd_hdac_bus_stop_chip(bus);
+	}
+}
+EXPORT_SYMBOL_GPL(snd_hdac_stop_streams_and_chip);
+
+/**
  * snd_hdac_stream_reset - reset a stream
  * @azx_dev: HD-audio core stream to reset
  */
diff --git a/kernel/sound/hda/intel-dsp-config.c b/kernel/sound/hda/intel-dsp-config.c
index 2a5ba9d..801c89a 100644
--- a/kernel/sound/hda/intel-dsp-config.c
+++ b/kernel/sound/hda/intel-dsp-config.c
@@ -359,6 +359,23 @@
 	},
 #endif
 
+/* Meteor Lake */
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_METEORLAKE)
+	/* Meteorlake-P */
+	{
+		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
+		.device = 0x7e28,
+	},
+#endif
+
+/* Lunar Lake */
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_LUNARLAKE)
+	/* Lunarlake-P */
+	{
+		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
+		.device = PCI_DEVICE_ID_INTEL_HDA_LNL_P,
+	},
+#endif
 };
 
 static const struct config_entry *snd_intel_dsp_find_config
diff --git a/kernel/sound/i2c/cs8427.c b/kernel/sound/i2c/cs8427.c
index 8634d4f..e8c4c39 100644
--- a/kernel/sound/i2c/cs8427.c
+++ b/kernel/sound/i2c/cs8427.c
@@ -553,10 +553,13 @@
 	if (snd_BUG_ON(!cs8427))
 		return -ENXIO;
 	chip = cs8427->private_data;
-	if (active)
+	if (active) {
 		memcpy(chip->playback.pcm_status,
 		       chip->playback.def_status, 24);
-	chip->playback.pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+		chip->playback.pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+	} else {
+		chip->playback.pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+	}
 	snd_ctl_notify(cs8427->bus->card,
 		       SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
 		       &chip->playback.pcm_ctl->id);
diff --git a/kernel/sound/oss/dmasound/dmasound.h b/kernel/sound/oss/dmasound/dmasound.h
index c1c52b4..ad8ce6a 100644
--- a/kernel/sound/oss/dmasound/dmasound.h
+++ b/kernel/sound/oss/dmasound/dmasound.h
@@ -88,11 +88,7 @@
      */
 
 extern int dmasound_init(void);
-#ifdef MODULE
 extern void dmasound_deinit(void);
-#else
-#define dmasound_deinit()	do { } while (0)
-#endif
 
 /* description of the set-up applies to either hard or soft settings */
 
@@ -114,9 +110,7 @@
     void *(*dma_alloc)(unsigned int, gfp_t);
     void (*dma_free)(void *, unsigned int);
     int (*irqinit)(void);
-#ifdef MODULE
     void (*irqcleanup)(void);
-#endif
     void (*init)(void);
     void (*silence)(void);
     int (*setFormat)(int);
diff --git a/kernel/sound/oss/dmasound/dmasound_core.c b/kernel/sound/oss/dmasound/dmasound_core.c
index 38f25e9..7454b05 100644
--- a/kernel/sound/oss/dmasound/dmasound_core.c
+++ b/kernel/sound/oss/dmasound/dmasound_core.c
@@ -206,12 +206,10 @@
 
 MODULE_LICENSE("GPL");
 
-#ifdef MODULE
 static int sq_unit = -1;
 static int mixer_unit = -1;
 static int state_unit = -1;
 static int irq_installed;
-#endif /* MODULE */
 
 /* control over who can modify resources shared between play/record */
 static fmode_t shared_resource_owner;
@@ -391,9 +389,6 @@
 
 static void mixer_init(void)
 {
-#ifndef MODULE
-	int mixer_unit;
-#endif
 	mixer_unit = register_sound_mixer(&mixer_fops, -1);
 	if (mixer_unit < 0)
 		return;
@@ -1176,9 +1171,6 @@
 static int sq_init(void)
 {
 	const struct file_operations *fops = &sq_fops;
-#ifndef MODULE
-	int sq_unit;
-#endif
 
 	sq_unit = register_sound_dsp(fops, -1);
 	if (sq_unit < 0) {
@@ -1380,9 +1372,6 @@
 
 static int state_init(void)
 {
-#ifndef MODULE
-	int state_unit;
-#endif
 	state_unit = register_sound_special(&state_fops, SND_DEV_STATUS);
 	if (state_unit < 0)
 		return state_unit ;
@@ -1400,10 +1389,9 @@
 int dmasound_init(void)
 {
 	int res ;
-#ifdef MODULE
+
 	if (irq_installed)
 		return -EBUSY;
-#endif
 
 	/* Set up sound queue, /dev/audio and /dev/dsp. */
 
@@ -1422,9 +1410,7 @@
 		printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n");
 		return -ENODEV;
 	}
-#ifdef MODULE
 	irq_installed = 1;
-#endif
 
 	printk(KERN_INFO "%s DMA sound driver rev %03d installed\n",
 		dmasound.mach.name, (DMASOUND_CORE_REVISION<<4) +
@@ -1437,8 +1423,6 @@
 		numWriteBufs, writeBufSize) ;
 	return 0;
 }
-
-#ifdef MODULE
 
 void dmasound_deinit(void)
 {
@@ -1458,9 +1442,7 @@
 		unregister_sound_dsp(sq_unit);
 }
 
-#else /* !MODULE */
-
-static int dmasound_setup(char *str)
+static int __maybe_unused dmasound_setup(char *str)
 {
 	int ints[6], size;
 
@@ -1502,8 +1484,6 @@
 }
 
 __setup("dmasound=", dmasound_setup);
-
-#endif /* !MODULE */
 
     /*
      *  Conversion tables
@@ -1591,9 +1571,7 @@
 
 EXPORT_SYMBOL(dmasound);
 EXPORT_SYMBOL(dmasound_init);
-#ifdef MODULE
 EXPORT_SYMBOL(dmasound_deinit);
-#endif
 EXPORT_SYMBOL(dmasound_write_sq);
 EXPORT_SYMBOL(dmasound_catchRadius);
 #ifdef HAS_8BIT_TABLES
diff --git a/kernel/sound/pci/ac97/ac97_codec.c b/kernel/sound/pci/ac97/ac97_codec.c
index cd66632..d894dcd 100644
--- a/kernel/sound/pci/ac97/ac97_codec.c
+++ b/kernel/sound/pci/ac97/ac97_codec.c
@@ -2007,10 +2007,9 @@
 		.dev_disconnect =	snd_ac97_dev_disconnect,
 	};
 
-	if (rac97)
-		*rac97 = NULL;
-	if (snd_BUG_ON(!bus || !template))
+	if (snd_BUG_ON(!bus || !template || !rac97))
 		return -EINVAL;
+	*rac97 = NULL;
 	if (snd_BUG_ON(template->num >= 4))
 		return -EINVAL;
 	if (bus->codec[template->num])
diff --git a/kernel/sound/pci/asihpi/hpi6205.c b/kernel/sound/pci/asihpi/hpi6205.c
index 3d6914c..4cdaeef 100644
--- a/kernel/sound/pci/asihpi/hpi6205.c
+++ b/kernel/sound/pci/asihpi/hpi6205.c
@@ -430,7 +430,7 @@
 		pao = hpi_find_adapter(phm->adapter_index);
 	} else {
 		/* subsys messages don't address an adapter */
-		_HPI_6205(NULL, phm, phr);
+		phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
 		return;
 	}
 
diff --git a/kernel/sound/pci/asihpi/hpioctl.c b/kernel/sound/pci/asihpi/hpioctl.c
index bb31b7f..477a5b4 100644
--- a/kernel/sound/pci/asihpi/hpioctl.c
+++ b/kernel/sound/pci/asihpi/hpioctl.c
@@ -361,7 +361,7 @@
 		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;
diff --git a/kernel/sound/pci/emu10k1/emufx.c b/kernel/sound/pci/emu10k1/emufx.c
index 4e76ed0..e17b93b 100644
--- a/kernel/sound/pci/emu10k1/emufx.c
+++ b/kernel/sound/pci/emu10k1/emufx.c
@@ -1560,14 +1560,8 @@
 	gpr += 2;
 
 	/* Master volume (will be renamed later) */
-	A_OP(icode, &ptr, iMAC0, A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS));
-	A_OP(icode, &ptr, iMAC0, A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS));
-	A_OP(icode, &ptr, iMAC0, A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS));
-	A_OP(icode, &ptr, iMAC0, A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS));
-	A_OP(icode, &ptr, iMAC0, A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS));
-	A_OP(icode, &ptr, iMAC0, A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS));
-	A_OP(icode, &ptr, iMAC0, A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS));
-	A_OP(icode, &ptr, iMAC0, A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS));
+	for (z = 0; z < 8; z++)
+		A_OP(icode, &ptr, iMAC0, A_GPR(playback+z+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+z+SND_EMU10K1_PLAYBACK_CHANNELS));
 	snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
 	gpr += 2;
 
@@ -1651,102 +1645,14 @@
 			dev_dbg(emu->card->dev, "emufx.c: gpr=0x%x, tmp=0x%x\n",
 			       gpr, tmp);
 			*/
-			/* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */
-			/* A_P16VIN(0) is delayed by one sample,
-			 * so all other A_P16VIN channels will need to also be delayed
-			 */
-			/* Left ADC in. 1 of 2 */
 			snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) );
-			/* Right ADC in 1 of 2 */
-			gpr_map[gpr++] = 0x00000000;
-			/* Delaying by one sample: instead of copying the input
-			 * value A_P16VIN to output A_FXBUS2 as in the first channel,
-			 * we use an auxiliary register, delaying the value by one
-			 * sample
-			 */
-			snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) );
-			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000);
-			gpr_map[gpr++] = 0x00000000;
-			snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) );
-			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000);
-			gpr_map[gpr++] = 0x00000000;
-			snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) );
-			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000);
-			/* For 96kHz mode */
-			/* Left ADC in. 2 of 2 */
-			gpr_map[gpr++] = 0x00000000;
-			snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) );
-			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000);
-			/* Right ADC in 2 of 2 */
-			gpr_map[gpr++] = 0x00000000;
-			snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) );
-			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000);
-			gpr_map[gpr++] = 0x00000000;
-			snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) );
-			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000);
-			gpr_map[gpr++] = 0x00000000;
-			snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) );
-			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000);
-			/* Pavel Hofman - we still have voices, A_FXBUS2s, and
-			 * A_P16VINs available -
-			 * let's add 8 more capture channels - total of 16
-			 */
-			gpr_map[gpr++] = 0x00000000;
-			snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-								  bit_shifter16,
-								  A_GPR(gpr - 1),
-								  A_FXBUS2(0x10));
-			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8),
-			     A_C_00000000, A_C_00000000);
-			gpr_map[gpr++] = 0x00000000;
-			snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-								  bit_shifter16,
-								  A_GPR(gpr - 1),
-								  A_FXBUS2(0x12));
-			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9),
-			     A_C_00000000, A_C_00000000);
-			gpr_map[gpr++] = 0x00000000;
-			snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-								  bit_shifter16,
-								  A_GPR(gpr - 1),
-								  A_FXBUS2(0x14));
-			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa),
-			     A_C_00000000, A_C_00000000);
-			gpr_map[gpr++] = 0x00000000;
-			snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-								  bit_shifter16,
-								  A_GPR(gpr - 1),
-								  A_FXBUS2(0x16));
-			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb),
-			     A_C_00000000, A_C_00000000);
-			gpr_map[gpr++] = 0x00000000;
-			snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-								  bit_shifter16,
-								  A_GPR(gpr - 1),
-								  A_FXBUS2(0x18));
-			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc),
-			     A_C_00000000, A_C_00000000);
-			gpr_map[gpr++] = 0x00000000;
-			snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-								  bit_shifter16,
-								  A_GPR(gpr - 1),
-								  A_FXBUS2(0x1a));
-			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd),
-			     A_C_00000000, A_C_00000000);
-			gpr_map[gpr++] = 0x00000000;
-			snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-								  bit_shifter16,
-								  A_GPR(gpr - 1),
-								  A_FXBUS2(0x1c));
-			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe),
-			     A_C_00000000, A_C_00000000);
-			gpr_map[gpr++] = 0x00000000;
-			snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-								  bit_shifter16,
-								  A_GPR(gpr - 1),
-								  A_FXBUS2(0x1e));
-			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf),
-			     A_C_00000000, A_C_00000000);
+			/* A_P16VIN(0) is delayed by one sample, so all other A_P16VIN channels
+			 * will need to also be delayed; we use an auxiliary register for that. */
+			for (z = 1; z < 0x10; z++) {
+				snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr), A_FXBUS2(z * 2) );
+				A_OP(icode, &ptr, iACC3, A_GPR(gpr), A_P16VIN(z), A_C_00000000, A_C_00000000);
+				gpr_map[gpr++] = 0x00000000;
+			}
 		}
 
 #if 0
diff --git a/kernel/sound/pci/emu10k1/emupcm.c b/kernel/sound/pci/emu10k1/emupcm.c
index 8d2c101..1c4388b 100644
--- a/kernel/sound/pci/emu10k1/emupcm.c
+++ b/kernel/sound/pci/emu10k1/emupcm.c
@@ -1232,7 +1232,7 @@
 {
 	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 
-	emu->capture_interrupt = NULL;
+	emu->capture_mic_interrupt = NULL;
 	emu->pcm_capture_mic_substream = NULL;
 	return 0;
 }
@@ -1340,7 +1340,7 @@
 {
 	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 
-	emu->capture_interrupt = NULL;
+	emu->capture_efx_interrupt = NULL;
 	emu->pcm_capture_efx_substream = NULL;
 	return 0;
 }
diff --git a/kernel/sound/pci/hda/hda_bind.c b/kernel/sound/pci/hda/hda_bind.c
index 4efbcc4..0a83afa 100644
--- a/kernel/sound/pci/hda/hda_bind.c
+++ b/kernel/sound/pci/hda/hda_bind.c
@@ -143,6 +143,7 @@
 
  error:
 	snd_hda_codec_cleanup_for_unbind(codec);
+	codec->preset = NULL;
 	return err;
 }
 
@@ -159,6 +160,7 @@
 	if (codec->patch_ops.free)
 		codec->patch_ops.free(codec);
 	snd_hda_codec_cleanup_for_unbind(codec);
+	codec->preset = NULL;
 	module_put(dev->driver->owner);
 	return 0;
 }
diff --git a/kernel/sound/pci/hda/hda_codec.c b/kernel/sound/pci/hda/hda_codec.c
index 3928110..fc4a64a 100644
--- a/kernel/sound/pci/hda/hda_codec.c
+++ b/kernel/sound/pci/hda/hda_codec.c
@@ -784,7 +784,6 @@
 	snd_array_free(&codec->cvt_setups);
 	snd_array_free(&codec->spdif_out);
 	snd_array_free(&codec->verbs);
-	codec->preset = NULL;
 	codec->follower_dig_outs = NULL;
 	codec->spdif_status_reset = 0;
 	snd_array_free(&codec->mixers);
diff --git a/kernel/sound/pci/hda/hda_controller.c b/kernel/sound/pci/hda/hda_controller.c
index 3de7dc3..ea76395 100644
--- a/kernel/sound/pci/hda/hda_controller.c
+++ b/kernel/sound/pci/hda/hda_controller.c
@@ -1045,10 +1045,8 @@
 void azx_stop_all_streams(struct azx *chip)
 {
 	struct hdac_bus *bus = azx_bus(chip);
-	struct hdac_stream *s;
 
-	list_for_each_entry(s, &bus->stream_list, list)
-		snd_hdac_stream_stop(s);
+	snd_hdac_stop_streams(bus);
 }
 EXPORT_SYMBOL_GPL(azx_stop_all_streams);
 
diff --git a/kernel/sound/pci/hda/hda_generic.c b/kernel/sound/pci/hda/hda_generic.c
index 8ee3be7..35113fa 100644
--- a/kernel/sound/pci/hda/hda_generic.c
+++ b/kernel/sound/pci/hda/hda_generic.c
@@ -1153,8 +1153,8 @@
 	return path && path->ctls[ctl_type];
 }
 
-static const char * const channel_name[4] = {
-	"Front", "Surround", "CLFE", "Side"
+static const char * const channel_name[] = {
+	"Front", "Surround", "CLFE", "Side", "Back",
 };
 
 /* give some appropriate ctl name prefix for the given line out channel */
@@ -1180,7 +1180,7 @@
 
 	/* multi-io channels */
 	if (ch >= cfg->line_outs)
-		return channel_name[ch];
+		goto fixed_name;
 
 	switch (cfg->line_out_type) {
 	case AUTO_PIN_SPEAKER_OUT:
@@ -1232,6 +1232,7 @@
 	if (cfg->line_outs == 1 && !spec->multi_ios)
 		return "Line Out";
 
+ fixed_name:
 	if (ch >= ARRAY_SIZE(channel_name)) {
 		snd_BUG();
 		return "PCM";
diff --git a/kernel/sound/pci/hda/hda_intel.c b/kernel/sound/pci/hda/hda_intel.c
index 494bfd2..dfef761 100644
--- a/kernel/sound/pci/hda/hda_intel.c
+++ b/kernel/sound/pci/hda/hda_intel.c
@@ -264,6 +264,7 @@
 	AZX_DRIVER_ATI,
 	AZX_DRIVER_ATIHDMI,
 	AZX_DRIVER_ATIHDMI_NS,
+	AZX_DRIVER_GFHDMI,
 	AZX_DRIVER_VIA,
 	AZX_DRIVER_SIS,
 	AZX_DRIVER_ULI,
@@ -365,14 +366,15 @@
 #define needs_eld_notify_link(chip)	false
 #endif
 
-#define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \
+#define CONTROLLER_IN_GPU(pci) (((pci)->vendor == 0x8086) &&         \
+				       (((pci)->device == 0x0a0c) || \
 					((pci)->device == 0x0c0c) || \
 					((pci)->device == 0x0d0c) || \
 					((pci)->device == 0x160c) || \
 					((pci)->device == 0x490d) || \
 					((pci)->device == 0x4f90) || \
 					((pci)->device == 0x4f91) || \
-					((pci)->device == 0x4f92))
+					((pci)->device == 0x4f92)))
 
 #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
 
@@ -385,6 +387,7 @@
 	[AZX_DRIVER_ATI] = "HDA ATI SB",
 	[AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
 	[AZX_DRIVER_ATIHDMI_NS] = "HDA ATI HDMI",
+	[AZX_DRIVER_GFHDMI] = "HDA GF HDMI",
 	[AZX_DRIVER_VIA] = "HDA VIA VT82xx",
 	[AZX_DRIVER_SIS] = "HDA SIS966",
 	[AZX_DRIVER_ULI] = "HDA ULI M5461",
@@ -1782,6 +1785,12 @@
 	}
 
 	switch (chip->driver_type) {
+	/*
+	 * increase the bdl size for Glenfly Gpus for hardware
+	 * limitation on hdac interrupt interval
+	 */
+	case AZX_DRIVER_GFHDMI:
+		return 128;
 	case AZX_DRIVER_ICH:
 	case AZX_DRIVER_PCH:
 		return 1;
@@ -1901,6 +1910,12 @@
 		pci_write_config_dword(pci, PCI_BASE_ADDRESS_1, 0);
 	}
 #endif
+	/*
+	 * Fix response write request not synced to memory when handle
+	 * hdac interrupt on Glenfly Gpus
+	 */
+	if (chip->driver_type == AZX_DRIVER_GFHDMI)
+		bus->polling_mode = 1;
 
 	err = pci_request_regions(pci, "ICH HD audio");
 	if (err < 0)
@@ -2010,6 +2025,7 @@
 			chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
 			chip->capture_streams = ATIHDMI_NUM_CAPTURE;
 			break;
+		case AZX_DRIVER_GFHDMI:
 		case AZX_DRIVER_GENERIC:
 		default:
 			chip->playback_streams = ICH6_NUM_PLAYBACK;
@@ -2255,6 +2271,7 @@
 	SND_PCI_QUIRK(0x8086, 0x2068, "Intel NUC7i3BNB", 0),
 	/* https://bugzilla.kernel.org/show_bug.cgi?id=198611 */
 	SND_PCI_QUIRK(0x17aa, 0x2227, "Lenovo X1 Carbon 3rd Gen", 0),
+	SND_PCI_QUIRK(0x17aa, 0x316e, "Lenovo ThinkCentre M70q", 0),
 	/* https://bugzilla.redhat.com/show_bug.cgi?id=1689623 */
 	SND_PCI_QUIRK(0x17aa, 0x367b, "Lenovo IdeaCentre B550", 0),
 	/* https://bugzilla.redhat.com/show_bug.cgi?id=1572975 */
@@ -2755,6 +2772,12 @@
 	{ PCI_DEVICE(0x1002, 0xab38),
 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
 	  AZX_DCAPS_PM_RUNTIME },
+	/* GLENFLY */
+	{ PCI_DEVICE(0x6766, PCI_ANY_ID),
+	  .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
+	  .class_mask = 0xffffff,
+	  .driver_data = AZX_DRIVER_GFHDMI | AZX_DCAPS_POSFIX_LPIB |
+	  AZX_DCAPS_NO_MSI | AZX_DCAPS_NO_64BIT },
 	/* VIA VT8251/VT8237A */
 	{ PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA },
 	/* VIA GFX VT7122/VX900 */
diff --git a/kernel/sound/pci/hda/patch_ca0132.c b/kernel/sound/pci/hda/patch_ca0132.c
index 82f14c3..6d67cca 100644
--- a/kernel/sound/pci/hda/patch_ca0132.c
+++ b/kernel/sound/pci/hda/patch_ca0132.c
@@ -1272,6 +1272,7 @@
 	SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI),
 	SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", QUIRK_R3DI),
 	SND_PCI_QUIRK(0x3842, 0x1038, "EVGA X99 Classified", QUIRK_R3DI),
+	SND_PCI_QUIRK(0x3842, 0x104b, "EVGA X299 Dark", QUIRK_R3DI),
 	SND_PCI_QUIRK(0x3842, 0x1055, "EVGA Z390 DARK", QUIRK_R3DI),
 	SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D),
 	SND_PCI_QUIRK(0x1102, 0x0018, "Recon3D", QUIRK_R3D),
@@ -2331,7 +2332,7 @@
 static int dspio_alloc_dma_chan(struct hda_codec *codec, unsigned int *dma_chan)
 {
 	int status = 0;
-	unsigned int size = sizeof(dma_chan);
+	unsigned int size = sizeof(*dma_chan);
 
 	codec_dbg(codec, "     dspio_alloc_dma_chan() -- begin\n");
 	status = dspio_scp(codec, MASTERCONTROL, 0x20,
@@ -4108,8 +4109,10 @@
 
 	for (i = 0; i < TUNING_CTLS_COUNT; i++)
 		if (nid == ca0132_tuning_ctls[i].nid)
-			break;
+			goto found;
 
+	return -EINVAL;
+found:
 	snd_hda_power_up(codec);
 	dspio_set_param(codec, ca0132_tuning_ctls[i].mid, 0x20,
 			ca0132_tuning_ctls[i].req,
diff --git a/kernel/sound/pci/hda/patch_conexant.c b/kernel/sound/pci/hda/patch_conexant.c
index 2bd0a58..e35c470 100644
--- a/kernel/sound/pci/hda/patch_conexant.c
+++ b/kernel/sound/pci/hda/patch_conexant.c
@@ -973,7 +973,10 @@
 	SND_PCI_QUIRK(0x17aa, 0x3905, "Lenovo G50-30", CXT_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK(0x17aa, 0x390b, "Lenovo G50-80", CXT_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
-	SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_PINCFG_LENOVO_NOTEBOOK),
+	/* NOTE: we'd need to extend the quirk for 17aa:3977 as the same
+	 * PCI SSID is used on multiple Lenovo models
+	 */
+	SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo G50-70", CXT_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", CXT_FIXUP_THINKPAD_ACPI),
@@ -996,6 +999,7 @@
 	{ .id = CXT_FIXUP_MUTE_LED_GPIO, .name = "mute-led-gpio" },
 	{ .id = CXT_FIXUP_HP_ZBOOK_MUTE_LED, .name = "hp-zbook-mute-led" },
 	{ .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" },
+	{ .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" },
 	{}
 };
 
@@ -1117,6 +1121,7 @@
 	HDA_CODEC_ENTRY(0x14f11f86, "CX8070", patch_conexant_auto),
 	HDA_CODEC_ENTRY(0x14f12008, "CX8200", patch_conexant_auto),
 	HDA_CODEC_ENTRY(0x14f120d0, "CX11970", patch_conexant_auto),
+	HDA_CODEC_ENTRY(0x14f120d1, "SN6180", patch_conexant_auto),
 	HDA_CODEC_ENTRY(0x14f15045, "CX20549 (Venice)", patch_conexant_auto),
 	HDA_CODEC_ENTRY(0x14f15047, "CX20551 (Waikiki)", patch_conexant_auto),
 	HDA_CODEC_ENTRY(0x14f15051, "CX20561 (Hermosa)", patch_conexant_auto),
diff --git a/kernel/sound/pci/hda/patch_hdmi.c b/kernel/sound/pci/hda/patch_hdmi.c
index b1c57c6..c19afe4 100644
--- a/kernel/sound/pci/hda/patch_hdmi.c
+++ b/kernel/sound/pci/hda/patch_hdmi.c
@@ -1965,6 +1965,8 @@
 static const struct snd_pci_quirk force_connect_list[] = {
 	SND_PCI_QUIRK(0x103c, 0x870f, "HP", 1),
 	SND_PCI_QUIRK(0x103c, 0x871a, "HP", 1),
+	SND_PCI_QUIRK(0x103c, 0x8711, "HP", 1),
+	SND_PCI_QUIRK(0x103c, 0x8715, "HP", 1),
 	SND_PCI_QUIRK(0x1462, 0xec94, "MS-7C94", 1),
 	{}
 };
@@ -4285,6 +4287,22 @@
 	return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID);
 }
 
+static int patch_gf_hdmi(struct hda_codec *codec)
+{
+	int err;
+
+	err = patch_generic_hdmi(codec);
+	if (err)
+		return err;
+
+	/*
+	 * Glenfly GPUs have two codecs, stream switches from one codec to
+	 * another, need to do actual clean-ups in codec_cleanup_stream
+	 */
+	codec->no_sticky_stream = 1;
+	return 0;
+}
+
 /*
  * patch entries
  */
@@ -4372,8 +4390,19 @@
 HDA_CODEC_ENTRY(0x10de009e, "GPU 9e HDMI/DP",	patch_nvhdmi),
 HDA_CODEC_ENTRY(0x10de009f, "GPU 9f HDMI/DP",	patch_nvhdmi),
 HDA_CODEC_ENTRY(0x10de00a0, "GPU a0 HDMI/DP",	patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de00a3, "GPU a3 HDMI/DP",	patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de00a4, "GPU a4 HDMI/DP",	patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de00a5, "GPU a5 HDMI/DP",	patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de00a6, "GPU a6 HDMI/DP",	patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de00a7, "GPU a7 HDMI/DP",	patch_nvhdmi),
 HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI",	patch_nvhdmi_2ch),
 HDA_CODEC_ENTRY(0x10de8067, "MCP67/68 HDMI",	patch_nvhdmi_2ch),
+HDA_CODEC_ENTRY(0x67663d82, "Arise 82 HDMI/DP",	patch_gf_hdmi),
+HDA_CODEC_ENTRY(0x67663d83, "Arise 83 HDMI/DP",	patch_gf_hdmi),
+HDA_CODEC_ENTRY(0x67663d84, "Arise 84 HDMI/DP",	patch_gf_hdmi),
+HDA_CODEC_ENTRY(0x67663d85, "Arise 85 HDMI/DP",	patch_gf_hdmi),
+HDA_CODEC_ENTRY(0x67663d86, "Arise 86 HDMI/DP",	patch_gf_hdmi),
+HDA_CODEC_ENTRY(0x67663d87, "Arise 87 HDMI/DP",	patch_gf_hdmi),
 HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP",	patch_via_hdmi),
 HDA_CODEC_ENTRY(0x11069f81, "VX900 HDMI/DP",	patch_via_hdmi),
 HDA_CODEC_ENTRY(0x11069f84, "VX11 HDMI/DP",	patch_generic_hdmi),
diff --git a/kernel/sound/pci/hda/patch_realtek.c b/kernel/sound/pci/hda/patch_realtek.c
index 8011b45..adfab80 100644
--- a/kernel/sound/pci/hda/patch_realtek.c
+++ b/kernel/sound/pci/hda/patch_realtek.c
@@ -121,6 +121,7 @@
 	unsigned int ultra_low_power:1;
 	unsigned int has_hs_key:1;
 	unsigned int no_internal_mic_pin:1;
+	unsigned int en_3kpull_low:1;
 
 	/* for PLL fix */
 	hda_nid_t pll_nid;
@@ -827,7 +828,7 @@
 			alc_setup_gpio(codec, 0x02);
 			break;
 		case 7:
-			alc_setup_gpio(codec, 0x03);
+			alc_setup_gpio(codec, 0x04);
 			break;
 		case 5:
 		default:
@@ -2632,6 +2633,7 @@
 	SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
 	SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
 	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
+	SND_PCI_QUIRK(0x1558, 0x3702, "Clevo X370SN[VW]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
 	SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
 	SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
 	SND_PCI_QUIRK(0x1558, 0x65d2, "Clevo PB51R[CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
@@ -3561,6 +3563,15 @@
 	hda_nid_t hp_pin = alc_get_hp_pin(spec);
 	bool hp_pin_sense;
 
+	if (spec->ultra_low_power) {
+		alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1);
+		alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2);
+		alc_update_coef_idx(codec, 0x08, 7<<4, 0);
+		alc_update_coef_idx(codec, 0x3b, 1<<15, 0);
+		alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
+		msleep(30);
+	}
+
 	if (!hp_pin)
 		hp_pin = 0x21;
 
@@ -3572,14 +3583,6 @@
 		msleep(2);
 
 	alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
-	if (spec->ultra_low_power) {
-		alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1);
-		alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2);
-		alc_update_coef_idx(codec, 0x08, 7<<4, 0);
-		alc_update_coef_idx(codec, 0x3b, 1<<15, 0);
-		alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
-		msleep(30);
-	}
 
 	snd_hda_codec_write(codec, hp_pin, 0,
 			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
@@ -3615,6 +3618,7 @@
 	if (!hp_pin)
 		hp_pin = 0x21;
 
+	alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
 	hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
 
 	if (hp_pin_sense)
@@ -3631,8 +3635,7 @@
 	/* If disable 3k pulldown control for alc257, the Mic detection will not work correctly
 	 * when booting with headset plugged. So skip setting it for the codec alc257
 	 */
-	if (codec->core.vendor_id != 0x10ec0236 &&
-	    codec->core.vendor_id != 0x10ec0257)
+	if (spec->en_3kpull_low)
 		alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
 
 	if (!spec->no_shutup_pins)
@@ -3661,6 +3664,13 @@
 	hda_nid_t hp_pin = alc_get_hp_pin(spec);
 	bool hp1_pin_sense, hp2_pin_sense;
 
+	if (spec->ultra_low_power) {
+		alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
+		alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
+		alc_update_coef_idx(codec, 0x33, 1<<11, 0);
+		msleep(30);
+	}
+
 	if (!hp_pin)
 		hp_pin = 0x21;
 	msleep(30);
@@ -3672,12 +3682,6 @@
 		msleep(2);
 
 	alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
-	if (spec->ultra_low_power) {
-		alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
-		alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
-		alc_update_coef_idx(codec, 0x33, 1<<11, 0);
-		msleep(30);
-	}
 
 	if (hp1_pin_sense || spec->ultra_low_power)
 		snd_hda_codec_write(codec, hp_pin, 0,
@@ -4555,6 +4559,21 @@
 	}
 }
 
+static void alc236_fixup_hp_mute_led_coefbit2(struct hda_codec *codec,
+					  const struct hda_fixup *fix, int action)
+{
+	struct alc_spec *spec = codec->spec;
+
+	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+		spec->mute_led_polarity = 0;
+		spec->mute_led_coef.idx = 0x07;
+		spec->mute_led_coef.mask = 1;
+		spec->mute_led_coef.on = 1;
+		spec->mute_led_coef.off = 0;
+		snd_hda_gen_add_mute_led_cdev(codec, coef_mute_led_set);
+	}
+}
+
 /* turn on/off mic-mute LED per capture hook by coef bit */
 static int coef_micmute_led_set(struct led_classdev *led_cdev,
 				enum led_brightness brightness)
@@ -4581,6 +4600,16 @@
 	}
 }
 
+static void alc285_fixup_hp_gpio_micmute_led(struct hda_codec *codec,
+				const struct hda_fixup *fix, int action)
+{
+	struct alc_spec *spec = codec->spec;
+
+	if (action == HDA_FIXUP_ACT_PRE_PROBE)
+		spec->micmute_led_polarity = 1;
+	alc_fixup_hp_gpio_led(codec, action, 0, 0x04);
+}
+
 static void alc236_fixup_hp_coef_micmute_led(struct hda_codec *codec,
 				const struct hda_fixup *fix, int action)
 {
@@ -4600,6 +4629,13 @@
 {
 	alc285_fixup_hp_mute_led_coefbit(codec, fix, action);
 	alc285_fixup_hp_coef_micmute_led(codec, fix, action);
+}
+
+static void alc285_fixup_hp_spectre_x360_mute_led(struct hda_codec *codec,
+				const struct hda_fixup *fix, int action)
+{
+	alc285_fixup_hp_mute_led_coefbit(codec, fix, action);
+	alc285_fixup_hp_gpio_micmute_led(codec, fix, action);
 }
 
 static void alc236_fixup_hp_mute_led(struct hda_codec *codec,
@@ -6654,6 +6690,34 @@
 	}
 }
 
+static void alc295_fixup_dell_inspiron_top_speakers(struct hda_codec *codec,
+					  const struct hda_fixup *fix, int action)
+{
+	static const struct hda_pintbl pincfgs[] = {
+		{ 0x14, 0x90170151 },
+		{ 0x17, 0x90170150 },
+		{ }
+	};
+	static const hda_nid_t conn[] = { 0x02, 0x03 };
+	static const hda_nid_t preferred_pairs[] = {
+		0x14, 0x02,
+		0x17, 0x03,
+		0x21, 0x02,
+		0
+	};
+	struct alc_spec *spec = codec->spec;
+
+	alc_fixup_no_shutup(codec, fix, action);
+
+	switch (action) {
+	case HDA_FIXUP_ACT_PRE_PROBE:
+		snd_hda_apply_pincfgs(codec, pincfgs);
+		snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
+		spec->gen.preferred_dacs = preferred_pairs;
+		break;
+	}
+}
+
 enum {
 	ALC269_FIXUP_GPIO2,
 	ALC269_FIXUP_SONY_VAIO,
@@ -6828,6 +6892,8 @@
 	ALC285_FIXUP_ASUS_G533Z_PINS,
 	ALC285_FIXUP_HP_GPIO_LED,
 	ALC285_FIXUP_HP_MUTE_LED,
+	ALC285_FIXUP_HP_SPECTRE_X360_MUTE_LED,
+	ALC236_FIXUP_HP_MUTE_LED_COEFBIT2,
 	ALC236_FIXUP_HP_GPIO_LED,
 	ALC236_FIXUP_HP_MUTE_LED,
 	ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF,
@@ -6884,6 +6950,8 @@
 	ALC285_FIXUP_LEGION_Y9000X_SPEAKERS,
 	ALC285_FIXUP_LEGION_Y9000X_AUTOMUTE,
 	ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED,
+	ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS,
+	ALC236_FIXUP_DELL_DUAL_CODECS,
 };
 
 /* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -8194,6 +8262,14 @@
 		.type = HDA_FIXUP_FUNC,
 		.v.func = alc285_fixup_hp_mute_led,
 	},
+	[ALC285_FIXUP_HP_SPECTRE_X360_MUTE_LED] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc285_fixup_hp_spectre_x360_mute_led,
+	},
+	[ALC236_FIXUP_HP_MUTE_LED_COEFBIT2] = {
+	    .type = HDA_FIXUP_FUNC,
+	    .v.func = alc236_fixup_hp_mute_led_coefbit2,
+	},
 	[ALC236_FIXUP_HP_GPIO_LED] = {
 		.type = HDA_FIXUP_FUNC,
 		.v.func = alc236_fixup_hp_gpio_led,
@@ -8704,6 +8780,18 @@
 		.chained = true,
 		.chain_id = ALC285_FIXUP_HP_MUTE_LED,
 	},
+	[ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc295_fixup_dell_inspiron_top_speakers,
+		.chained = true,
+		.chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
+	},
+	[ALC236_FIXUP_DELL_DUAL_CODECS] = {
+		.type = HDA_FIXUP_PINS,
+		.v.func = alc1220_fixup_gb_dual_codecs,
+		.chained = true,
+		.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+	},
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -8745,6 +8833,7 @@
 	SND_PCI_QUIRK(0x1025, 0x142b, "Acer Swift SF314-42", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1025, 0x1466, "Acer Aspire A515-56", ALC255_FIXUP_ACER_HEADPHONE_AND_MIC),
+	SND_PCI_QUIRK(0x1025, 0x1534, "Acer Predator PH315-54", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
 	SND_PCI_QUIRK(0x1028, 0x053c, "Dell Latitude E5430", ALC292_FIXUP_DELL_E7X),
 	SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
@@ -8803,6 +8892,15 @@
 	SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x0b19, "Dell XPS 15 9520", ALC289_FIXUP_DUAL_SPK),
 	SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK),
+	SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
+	SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
+	SND_PCI_QUIRK(0x1028, 0x0c03, "Dell Precision 5340", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
+	SND_PCI_QUIRK(0x1028, 0x0c19, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
+	SND_PCI_QUIRK(0x1028, 0x0c1a, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
+	SND_PCI_QUIRK(0x1028, 0x0c1b, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
+	SND_PCI_QUIRK(0x1028, 0x0c1c, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
+	SND_PCI_QUIRK(0x1028, 0x0c1d, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
+	SND_PCI_QUIRK(0x1028, 0x0c1e, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
 	SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
@@ -8867,7 +8965,7 @@
 	SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x103c, 0x8077, "HP", ALC256_FIXUP_HP_HEADSET_MIC),
 	SND_PCI_QUIRK(0x103c, 0x8158, "HP", ALC256_FIXUP_HP_HEADSET_MIC),
-	SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
+	SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC295_FIXUP_HP_X360),
 	SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
 	SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
 	SND_PCI_QUIRK(0x103c, 0x827f, "HP x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
@@ -8885,6 +8983,7 @@
 	SND_PCI_QUIRK(0x103c, 0x86c7, "HP Envy AiO 32", ALC274_FIXUP_HP_ENVY_GPIO),
 	SND_PCI_QUIRK(0x103c, 0x86e7, "HP Spectre x360 15-eb0xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1),
 	SND_PCI_QUIRK(0x103c, 0x86e8, "HP Spectre x360 15-eb0xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1),
+	SND_PCI_QUIRK(0x103c, 0x86f9, "HP Spectre x360 13-aw0xxx", ALC285_FIXUP_HP_SPECTRE_X360_MUTE_LED),
 	SND_PCI_QUIRK(0x103c, 0x8716, "HP Elite Dragonfly G2 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
 	SND_PCI_QUIRK(0x103c, 0x8720, "HP EliteBook x360 1040 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
 	SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED),
@@ -8916,6 +9015,7 @@
 	SND_PCI_QUIRK(0x103c, 0x880d, "HP EliteBook 830 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
 	SND_PCI_QUIRK(0x103c, 0x8811, "HP Spectre x360 15-eb1xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1),
 	SND_PCI_QUIRK(0x103c, 0x8812, "HP Spectre x360 15-eb1xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1),
+	SND_PCI_QUIRK(0x103c, 0x881d, "HP 250 G8 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
 	SND_PCI_QUIRK(0x103c, 0x8846, "HP EliteBook 850 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
 	SND_PCI_QUIRK(0x103c, 0x8847, "HP EliteBook x360 830 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
 	SND_PCI_QUIRK(0x103c, 0x884b, "HP EliteBook 840 Aero G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
@@ -8925,6 +9025,7 @@
 	SND_PCI_QUIRK(0x103c, 0x886d, "HP ZBook Fury 17.3 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
 	SND_PCI_QUIRK(0x103c, 0x8870, "HP ZBook Fury 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
 	SND_PCI_QUIRK(0x103c, 0x8873, "HP ZBook Studio 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
+	SND_PCI_QUIRK(0x103c, 0x887a, "HP Laptop 15s-eq2xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
 	SND_PCI_QUIRK(0x103c, 0x888d, "HP ZBook Power 15.6 inch G8 Mobile Workstation PC", ALC236_FIXUP_HP_GPIO_LED),
 	SND_PCI_QUIRK(0x103c, 0x8895, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED),
 	SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED),
@@ -8966,6 +9067,7 @@
 	SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
 	SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+	SND_PCI_QUIRK(0x1043, 0x1c62, "ASUS GU603", ALC289_FIXUP_ASUS_GA401),
 	SND_PCI_QUIRK(0x1043, 0x1c92, "ASUS ROG Strix G15", ALC285_FIXUP_ASUS_G533Z_PINS),
 	SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
 	SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401),
@@ -9013,6 +9115,8 @@
 	SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", ALC298_FIXUP_SAMSUNG_AMP),
 	SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_AMP),
 	SND_PCI_QUIRK(0x144d, 0xc832, "Samsung Galaxy Book Flex Alpha (NP730QCJ)", ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
+	SND_PCI_QUIRK(0x144d, 0xca03, "Samsung Galaxy Book2 Pro 360 (NP930QED)", ALC298_FIXUP_SAMSUNG_AMP),
+	SND_PCI_QUIRK(0x144d, 0xc868, "Samsung Galaxy Book2 Pro (NP930XED)", ALC298_FIXUP_SAMSUNG_AMP),
 	SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
 	SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
 	SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
@@ -9056,6 +9160,7 @@
 	SND_PCI_QUIRK(0x1558, 0x7716, "Clevo NS50PU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x7717, "Clevo NS70PU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x7718, "Clevo L140PU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+	SND_PCI_QUIRK(0x1558, 0x7724, "Clevo L140AU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x8228, "Clevo NR40BU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x8520, "Clevo NH50D[CD]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x8521, "Clevo NH77D[CD]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
@@ -9174,6 +9279,7 @@
 	SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
 	SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
 	SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
+	SND_PCI_QUIRK(0x17aa, 0x9e56, "Lenovo ZhaoYang CF4620Z", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK),
 	SND_PCI_QUIRK(0x1849, 0xa233, "Positivo Master C6300", ALC269_FIXUP_HEADSET_MIC),
 	SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
@@ -9184,6 +9290,7 @@
 	SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
 	SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802),
 	SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X),
+	SND_PCI_QUIRK(0x1c6c, 0x1251, "Positivo N14KP6-TG", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1d05, 0x1132, "TongFang PHxTxX1", ALC256_FIXUP_SET_COEF_DEFAULTS),
 	SND_PCI_QUIRK(0x1d05, 0x1096, "TongFang GMxMRxx", ALC269_FIXUP_NO_SHUTUP),
 	SND_PCI_QUIRK(0x1d05, 0x1100, "TongFang GKxNRxx", ALC269_FIXUP_NO_SHUTUP),
@@ -9899,6 +10006,7 @@
 	spec = codec->spec;
 	spec->gen.shared_mic_vref_pin = 0x18;
 	codec->power_save_node = 0;
+	spec->en_3kpull_low = true;
 
 #ifdef CONFIG_PM
 	codec->patch_ops.suspend = alc269_suspend;
@@ -9981,12 +10089,16 @@
 		spec->shutup = alc256_shutup;
 		spec->init_hook = alc256_init;
 		spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
+		if (codec->core.vendor_id == 0x10ec0236 &&
+		    codec->bus->pci->vendor != PCI_VENDOR_ID_AMD)
+			spec->en_3kpull_low = false;
 		break;
 	case 0x10ec0257:
 		spec->codec_variant = ALC269_TYPE_ALC257;
 		spec->shutup = alc256_shutup;
 		spec->init_hook = alc256_init;
 		spec->gen.mixer_nid = 0;
+		spec->en_3kpull_low = false;
 		break;
 	case 0x10ec0215:
 	case 0x10ec0245:
@@ -10514,6 +10626,17 @@
 	}
 }
 
+static void alc897_fixup_lenovo_headset_mode(struct hda_codec *codec,
+				     const struct hda_fixup *fix, int action)
+{
+	struct alc_spec *spec = codec->spec;
+
+	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
+		spec->gen.hp_automute_hook = alc897_hp_automute_hook;
+	}
+}
+
 static const struct coef_fw alc668_coefs[] = {
 	WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03,    0x0),
 	WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06,    0x0), WRITE_COEF(0x07, 0x0f80),
@@ -10597,6 +10720,9 @@
 	ALC897_FIXUP_LENOVO_HEADSET_MIC,
 	ALC897_FIXUP_HEADSET_MIC_PIN,
 	ALC897_FIXUP_HP_HSMIC_VERB,
+	ALC897_FIXUP_LENOVO_HEADSET_MODE,
+	ALC897_FIXUP_HEADSET_MIC_PIN2,
+	ALC897_FIXUP_UNIS_H3C_X500S,
 };
 
 static const struct hda_fixup alc662_fixups[] = {
@@ -11023,6 +11149,26 @@
 			{ }
 		},
 	},
+	[ALC897_FIXUP_LENOVO_HEADSET_MODE] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc897_fixup_lenovo_headset_mode,
+	},
+	[ALC897_FIXUP_HEADSET_MIC_PIN2] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = (const struct hda_pintbl[]) {
+			{ 0x1a, 0x01a11140 }, /* use as headset mic, without its own jack detect */
+			{ }
+		},
+		.chained = true,
+		.chain_id = ALC897_FIXUP_LENOVO_HEADSET_MODE
+	},
+	[ALC897_FIXUP_UNIS_H3C_X500S] = {
+		.type = HDA_FIXUP_VERBS,
+		.v.verbs = (const struct hda_verb[]) {
+			{ 0x14, AC_VERB_SET_EAPD_BTLENABLE, 0 },
+			{}
+		},
+	},
 };
 
 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -11048,8 +11194,11 @@
 	SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
+	SND_PCI_QUIRK(0x103c, 0x870c, "HP", ALC897_FIXUP_HP_HSMIC_VERB),
 	SND_PCI_QUIRK(0x103c, 0x8719, "HP", ALC897_FIXUP_HP_HSMIC_VERB),
+	SND_PCI_QUIRK(0x103c, 0x872b, "HP", ALC897_FIXUP_HP_HSMIC_VERB),
 	SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2),
+	SND_PCI_QUIRK(0x103c, 0x8768, "HP Slim Desktop S01", ALC671_FIXUP_HP_HEADSET_MIC2),
 	SND_PCI_QUIRK(0x103c, 0x877e, "HP 288 Pro G6", ALC671_FIXUP_HP_HEADSET_MIC2),
 	SND_PCI_QUIRK(0x103c, 0x885f, "HP 288 Pro G8", ALC671_FIXUP_HP_HEADSET_MIC2),
 	SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
@@ -11071,10 +11220,14 @@
 	SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
 	SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
 	SND_PCI_QUIRK(0x17aa, 0x1057, "Lenovo P360", ALC897_FIXUP_HEADSET_MIC_PIN),
+	SND_PCI_QUIRK(0x17aa, 0x1064, "Lenovo P3 Tower", ALC897_FIXUP_HEADSET_MIC_PIN),
 	SND_PCI_QUIRK(0x17aa, 0x32ca, "Lenovo ThinkCentre M80", ALC897_FIXUP_HEADSET_MIC_PIN),
 	SND_PCI_QUIRK(0x17aa, 0x32cb, "Lenovo ThinkCentre M70", ALC897_FIXUP_HEADSET_MIC_PIN),
 	SND_PCI_QUIRK(0x17aa, 0x32cf, "Lenovo ThinkCentre M950", ALC897_FIXUP_HEADSET_MIC_PIN),
 	SND_PCI_QUIRK(0x17aa, 0x32f7, "Lenovo ThinkCentre M90", ALC897_FIXUP_HEADSET_MIC_PIN),
+	SND_PCI_QUIRK(0x17aa, 0x3321, "Lenovo ThinkCentre M70 Gen4", ALC897_FIXUP_HEADSET_MIC_PIN),
+	SND_PCI_QUIRK(0x17aa, 0x331b, "Lenovo ThinkCentre M90 Gen4", ALC897_FIXUP_HEADSET_MIC_PIN),
+	SND_PCI_QUIRK(0x17aa, 0x3742, "Lenovo TianYi510Pro-14IOB", ALC897_FIXUP_HEADSET_MIC_PIN2),
 	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
 	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
 	SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
@@ -11082,6 +11235,7 @@
 	SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
 	SND_PCI_QUIRK(0x1b35, 0x1234, "CZC ET26", ALC662_FIXUP_CZC_ET26),
 	SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
+	SND_PCI_QUIRK(0x1c6c, 0x1239, "Compaq N14JP6-V2", ALC897_FIXUP_HP_HSMIC_VERB),
 
 #if 0
 	/* Below is a quirk table taken from the old code.
@@ -11176,6 +11330,7 @@
 	{.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"},
 	{.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
 	{.id = ALC669_FIXUP_ACER_ASPIRE_ETHOS, .name = "aspire-ethos"},
+	{.id = ALC897_FIXUP_UNIS_H3C_X500S, .name = "unis-h3c-x500s"},
 	{}
 };
 
diff --git a/kernel/sound/pci/hda/patch_sigmatel.c b/kernel/sound/pci/hda/patch_sigmatel.c
index 6fc0c4e..76c5a2b 100644
--- a/kernel/sound/pci/hda/patch_sigmatel.c
+++ b/kernel/sound/pci/hda/patch_sigmatel.c
@@ -1707,6 +1707,7 @@
 };
 
 static const struct hda_pintbl ref92hd73xx_pin_configs[] = {
+	// Port A-H
 	{ 0x0a, 0x02214030 },
 	{ 0x0b, 0x02a19040 },
 	{ 0x0c, 0x01a19020 },
@@ -1715,9 +1716,12 @@
 	{ 0x0f, 0x01014010 },
 	{ 0x10, 0x01014020 },
 	{ 0x11, 0x01014030 },
+	// CD in
 	{ 0x12, 0x02319040 },
+	// Digial Mic ins
 	{ 0x13, 0x90a000f0 },
 	{ 0x14, 0x90a000f0 },
+	// Digital outs
 	{ 0x22, 0x01452050 },
 	{ 0x23, 0x01452050 },
 	{}
@@ -1758,6 +1762,7 @@
 };
 
 static const struct hda_pintbl intel_dg45id_pin_configs[] = {
+	// Analog outputs
 	{ 0x0a, 0x02214230 },
 	{ 0x0b, 0x02A19240 },
 	{ 0x0c, 0x01013214 },
@@ -1765,6 +1770,9 @@
 	{ 0x0e, 0x01A19250 },
 	{ 0x0f, 0x01011212 },
 	{ 0x10, 0x01016211 },
+	// Digital output
+	{ 0x22, 0x01451380 },
+	{ 0x23, 0x40f000f0 },
 	{}
 };
 
@@ -1955,6 +1963,8 @@
 				"DFI LanParty", STAC_92HD73XX_REF),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
 				"DFI LanParty", STAC_92HD73XX_REF),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5001,
+				"Intel DP45SG", STAC_92HD73XX_INTEL),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5002,
 				"Intel DG45ID", STAC_92HD73XX_INTEL),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5003,
diff --git a/kernel/sound/pci/hda/patch_via.c b/kernel/sound/pci/hda/patch_via.c
index a188901..29abc96 100644
--- a/kernel/sound/pci/hda/patch_via.c
+++ b/kernel/sound/pci/hda/patch_via.c
@@ -821,6 +821,9 @@
 		return 0;
 	nums = snd_hda_get_connections(codec, spec->gen.mixer_nid, conn,
 				       ARRAY_SIZE(conn) - 1);
+	if (nums < 0)
+		return nums;
+
 	for (i = 0; i < nums; i++) {
 		if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT)
 			return 0;
diff --git a/kernel/sound/pci/ice1712/aureon.c b/kernel/sound/pci/ice1712/aureon.c
index 9a30f6d..40a0e00 100644
--- a/kernel/sound/pci/ice1712/aureon.c
+++ b/kernel/sound/pci/ice1712/aureon.c
@@ -1892,6 +1892,7 @@
 		unsigned char id;
 		snd_ice1712_save_gpio_status(ice);
 		id = aureon_cs8415_get(ice, CS8415_ID);
+		snd_ice1712_restore_gpio_status(ice);
 		if (id != 0x41)
 			dev_info(ice->card->dev,
 				 "No CS8415 chip. Skipping CS8415 controls.\n");
@@ -1909,7 +1910,6 @@
 					kctl->id.device = ice->pcm->device;
 			}
 		}
-		snd_ice1712_restore_gpio_status(ice);
 	}
 
 	return 0;
diff --git a/kernel/sound/pci/lx6464es/lx_core.c b/kernel/sound/pci/lx6464es/lx_core.c
index f884f5a..a49a325 100644
--- a/kernel/sound/pci/lx6464es/lx_core.c
+++ b/kernel/sound/pci/lx6464es/lx_core.c
@@ -493,12 +493,11 @@
 		dev_dbg(chip->card->dev,
 			"CMD_08_ASK_BUFFERS: needed %d, freed %d\n",
 			    *r_needed, *r_freed);
-		for (i = 0; i < MAX_STREAM_BUFFER; ++i) {
-			for (i = 0; i != chip->rmh.stat_len; ++i)
-				dev_dbg(chip->card->dev,
-					"  stat[%d]: %x, %x\n", i,
-					    chip->rmh.stat[i],
-					    chip->rmh.stat[i] & MASK_DATA_SIZE);
+		for (i = 0; i < MAX_STREAM_BUFFER && i < chip->rmh.stat_len;
+		     ++i) {
+			dev_dbg(chip->card->dev, "  stat[%d]: %x, %x\n", i,
+				chip->rmh.stat[i],
+				chip->rmh.stat[i] & MASK_DATA_SIZE);
 		}
 	}
 
diff --git a/kernel/sound/pci/ymfpci/ymfpci.c b/kernel/sound/pci/ymfpci/ymfpci.c
index 9b0d18a..27fd10b 100644
--- a/kernel/sound/pci/ymfpci/ymfpci.c
+++ b/kernel/sound/pci/ymfpci/ymfpci.c
@@ -78,7 +78,8 @@
 
 		if (io_port == 1) {
 			/* auto-detect */
-			if (!(io_port = pci_resource_start(chip->pci, 2)))
+			io_port = pci_resource_start(chip->pci, 2);
+			if (!io_port)
 				return -ENODEV;
 		}
 	} else {
@@ -87,7 +88,8 @@
 			for (io_port = 0x201; io_port <= 0x205; io_port++) {
 				if (io_port == 0x203)
 					continue;
-				if ((r = request_region(io_port, 1, "YMFPCI gameport")) != NULL)
+				r = request_region(io_port, 1, "YMFPCI gameport");
+				if (r)
 					break;
 			}
 			if (!r) {
@@ -108,10 +110,13 @@
 		}
 	}
 
-	if (!r && !(r = request_region(io_port, 1, "YMFPCI gameport"))) {
-		dev_err(chip->card->dev,
-			"joystick port %#x is in use.\n", io_port);
-		return -EBUSY;
+	if (!r) {
+		r = request_region(io_port, 1, "YMFPCI gameport");
+		if (!r) {
+			dev_err(chip->card->dev,
+				"joystick port %#x is in use.\n", io_port);
+			return -EBUSY;
+		}
 	}
 
 	chip->gameport = gp = gameport_allocate_port();
@@ -199,8 +204,9 @@
 			/* auto-detect */
 			fm_port[dev] = pci_resource_start(pci, 1);
 		}
-		if (fm_port[dev] > 0 &&
-		    (fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) {
+		if (fm_port[dev] > 0)
+			fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3");
+		if (fm_res) {
 			legacy_ctrl |= YMFPCI_LEGACY_FMEN;
 			pci_write_config_word(pci, PCIR_DSXG_FMBASE, fm_port[dev]);
 		}
@@ -208,8 +214,9 @@
 			/* auto-detect */
 			mpu_port[dev] = pci_resource_start(pci, 1) + 0x20;
 		}
-		if (mpu_port[dev] > 0 &&
-		    (mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) {
+		if (mpu_port[dev] > 0)
+			mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401");
+		if (mpu_res) {
 			legacy_ctrl |= YMFPCI_LEGACY_MEN;
 			pci_write_config_word(pci, PCIR_DSXG_MPU401BASE, mpu_port[dev]);
 		}
@@ -221,8 +228,9 @@
 		case 0x3a8: legacy_ctrl2 |= 3; break;
 		default: fm_port[dev] = 0; break;
 		}
-		if (fm_port[dev] > 0 &&
-		    (fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) {
+		if (fm_port[dev] > 0)
+			fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3");
+		if (fm_res) {
 			legacy_ctrl |= YMFPCI_LEGACY_FMEN;
 		} else {
 			legacy_ctrl2 &= ~YMFPCI_LEGACY2_FMIO;
@@ -235,8 +243,9 @@
 		case 0x334: legacy_ctrl2 |= 3 << 4; break;
 		default: mpu_port[dev] = 0; break;
 		}
-		if (mpu_port[dev] > 0 &&
-		    (mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) {
+		if (mpu_port[dev] > 0)
+			mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401");
+		if (mpu_res) {
 			legacy_ctrl |= YMFPCI_LEGACY_MEN;
 		} else {
 			legacy_ctrl2 &= ~YMFPCI_LEGACY2_MPUIO;
@@ -250,9 +259,8 @@
 	pci_read_config_word(pci, PCIR_DSXG_LEGACY, &old_legacy_ctrl);
 	pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
 	pci_write_config_word(pci, PCIR_DSXG_ELEGACY, legacy_ctrl2);
-	if ((err = snd_ymfpci_create(card, pci,
-				     old_legacy_ctrl,
-			 	     &chip)) < 0) {
+	err = snd_ymfpci_create(card, pci, old_legacy_ctrl, &chip);
+	if (err  < 0) {
 		release_and_free_resource(mpu_res);
 		release_and_free_resource(fm_res);
 		goto free_card;
@@ -293,11 +301,12 @@
 		goto free_card;
 
 	if (chip->mpu_res) {
-		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI,
-					       mpu_port[dev],
-					       MPU401_INFO_INTEGRATED |
-					       MPU401_INFO_IRQ_HOOK,
-					       -1, &chip->rawmidi)) < 0) {
+		err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI,
+					  mpu_port[dev],
+					  MPU401_INFO_INTEGRATED |
+					  MPU401_INFO_IRQ_HOOK,
+					  -1, &chip->rawmidi);
+		if (err < 0) {
 			dev_warn(card->dev,
 				 "cannot initialize MPU401 at 0x%lx, skipping...\n",
 				 mpu_port[dev]);
@@ -306,18 +315,22 @@
 		}
 	}
 	if (chip->fm_res) {
-		if ((err = snd_opl3_create(card,
-					   fm_port[dev],
-					   fm_port[dev] + 2,
-					   OPL3_HW_OPL3, 1, &opl3)) < 0) {
+		err = snd_opl3_create(card,
+				      fm_port[dev],
+				      fm_port[dev] + 2,
+				      OPL3_HW_OPL3, 1, &opl3);
+		if (err < 0) {
 			dev_warn(card->dev,
 				 "cannot initialize FM OPL3 at 0x%lx, skipping...\n",
 				 fm_port[dev]);
 			legacy_ctrl &= ~YMFPCI_LEGACY_FMEN;
 			pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
-		} else if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
-			dev_err(card->dev, "cannot create opl3 hwdep\n");
-			goto free_card;
+		} else {
+			err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+			if (err < 0) {
+				dev_err(card->dev, "cannot create opl3 hwdep\n");
+				goto free_card;
+			}
 		}
 	}
 
diff --git a/kernel/sound/pci/ymfpci/ymfpci_main.c b/kernel/sound/pci/ymfpci/ymfpci_main.c
index cacc6a9..0cd9b40 100644
--- a/kernel/sound/pci/ymfpci/ymfpci_main.c
+++ b/kernel/sound/pci/ymfpci/ymfpci_main.c
@@ -292,7 +292,8 @@
 	struct snd_ymfpci_pcm *ypcm;
 	u32 pos, delta;
 	
-	if ((ypcm = voice->ypcm) == NULL)
+	ypcm = voice->ypcm;
+	if (!ypcm)
 		return;
 	if (ypcm->substream == NULL)
 		return;
@@ -628,7 +629,8 @@
 	struct snd_ymfpci_pcm *ypcm = runtime->private_data;
 	int err;
 
-	if ((err = snd_ymfpci_pcm_voice_alloc(ypcm, params_channels(hw_params))) < 0)
+	err = snd_ymfpci_pcm_voice_alloc(ypcm, params_channels(hw_params));
+	if (err < 0)
 		return err;
 	return 0;
 }
@@ -932,7 +934,8 @@
 	struct snd_ymfpci_pcm *ypcm;
 	int err;
 	
-	if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
+	err = snd_ymfpci_playback_open_1(substream);
+	if (err < 0)
 		return err;
 	ypcm = runtime->private_data;
 	ypcm->output_front = 1;
@@ -954,7 +957,8 @@
 	struct snd_ymfpci_pcm *ypcm;
 	int err;
 	
-	if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
+	err = snd_ymfpci_playback_open_1(substream);
+	if (err < 0)
 		return err;
 	ypcm = runtime->private_data;
 	ypcm->output_front = 0;
@@ -982,7 +986,8 @@
 	struct snd_ymfpci_pcm *ypcm;
 	int err;
 	
-	if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
+	err = snd_ymfpci_playback_open_1(substream);
+	if (err < 0)
 		return err;
 	ypcm = runtime->private_data;
 	ypcm->output_front = 0;
@@ -1124,7 +1129,8 @@
 	struct snd_pcm *pcm;
 	int err;
 
-	if ((err = snd_pcm_new(chip->card, "YMFPCI", device, 32, 1, &pcm)) < 0)
+	err = snd_pcm_new(chip->card, "YMFPCI", device, 32, 1, &pcm);
+	if (err < 0)
 		return err;
 	pcm->private_data = chip;
 
@@ -1157,7 +1163,8 @@
 	struct snd_pcm *pcm;
 	int err;
 
-	if ((err = snd_pcm_new(chip->card, "YMFPCI - PCM2", device, 0, 1, &pcm)) < 0)
+	err = snd_pcm_new(chip->card, "YMFPCI - PCM2", device, 0, 1, &pcm);
+	if (err < 0)
 		return err;
 	pcm->private_data = chip;
 
@@ -1190,7 +1197,8 @@
 	struct snd_pcm *pcm;
 	int err;
 
-	if ((err = snd_pcm_new(chip->card, "YMFPCI - IEC958", device, 1, 0, &pcm)) < 0)
+	err = snd_pcm_new(chip->card, "YMFPCI - IEC958", device, 1, 0, &pcm);
+	if (err < 0)
 		return err;
 	pcm->private_data = chip;
 
@@ -1230,7 +1238,8 @@
 	struct snd_pcm *pcm;
 	int err;
 
-	if ((err = snd_pcm_new(chip->card, "YMFPCI - Rear", device, 1, 0, &pcm)) < 0)
+	err = snd_pcm_new(chip->card, "YMFPCI - Rear", device, 1, 0, &pcm);
+	if (err < 0)
 		return err;
 	pcm->private_data = chip;
 
@@ -1785,7 +1794,8 @@
 		.read = snd_ymfpci_codec_read,
 	};
 
-	if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
+	err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus);
+	if (err < 0)
 		return err;
 	chip->ac97_bus->private_free = snd_ymfpci_mixer_free_ac97_bus;
 	chip->ac97_bus->no_vra = 1; /* YMFPCI doesn't need VRA */
@@ -1793,7 +1803,8 @@
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = chip;
 	ac97.private_free = snd_ymfpci_mixer_free_ac97;
-	if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
+	err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97);
+	if (err < 0)
 		return err;
 
 	/* to be sure */
@@ -1801,7 +1812,8 @@
 			     AC97_EA_VRA|AC97_EA_VRM, 0);
 
 	for (idx = 0; idx < ARRAY_SIZE(snd_ymfpci_controls); idx++) {
-		if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip))) < 0)
+		err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip));
+		if (err < 0)
 			return err;
 	}
 	if (chip->ac97->ext_id & AC97_EI_SDAC) {
@@ -1814,27 +1826,37 @@
 	/* add S/PDIF control */
 	if (snd_BUG_ON(!chip->pcm_spdif))
 		return -ENXIO;
-	if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_default, chip))) < 0)
+	kctl = snd_ctl_new1(&snd_ymfpci_spdif_default, chip);
+	err = snd_ctl_add(chip->card, kctl);
+	if (err < 0)
 		return err;
 	kctl->id.device = chip->pcm_spdif->device;
-	if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_mask, chip))) < 0)
+	kctl = snd_ctl_new1(&snd_ymfpci_spdif_mask, chip);
+	err = snd_ctl_add(chip->card, kctl);
+	if (err < 0)
 		return err;
 	kctl->id.device = chip->pcm_spdif->device;
-	if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_stream, chip))) < 0)
+	kctl = snd_ctl_new1(&snd_ymfpci_spdif_stream, chip);
+	err = snd_ctl_add(chip->card, kctl);
+	if (err < 0)
 		return err;
 	kctl->id.device = chip->pcm_spdif->device;
 	chip->spdif_pcm_ctl = kctl;
 
 	/* direct recording source */
-	if (chip->device_id == PCI_DEVICE_ID_YAMAHA_754 &&
-	    (err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_drec_source, chip))) < 0)
-		return err;
+	if (chip->device_id == PCI_DEVICE_ID_YAMAHA_754) {
+		kctl = snd_ctl_new1(&snd_ymfpci_drec_source, chip);
+		err = snd_ctl_add(chip->card, kctl);
+		if (err < 0)
+			return err;
+	}
 
 	/*
 	 * shared rear/line-in
 	 */
 	if (rear_switch) {
-		if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_rear_shared, chip))) < 0)
+		err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_rear_shared, chip));
+		if (err < 0)
 			return err;
 	}
 
@@ -1847,7 +1869,8 @@
 		kctl->id.device = chip->pcm->device;
 		kctl->id.subdevice = idx;
 		kctl->private_value = (unsigned long)substream;
-		if ((err = snd_ctl_add(chip->card, kctl)) < 0)
+		err = snd_ctl_add(chip->card, kctl);
+		if (err < 0)
 			return err;
 		chip->pcm_mixer[idx].left = 0x8000;
 		chip->pcm_mixer[idx].right = 0x8000;
@@ -1928,7 +1951,8 @@
 	tid.card = chip->card->number;
 	tid.device = device;
 	tid.subdevice = 0;
-	if ((err = snd_timer_new(chip->card, "YMFPCI", &tid, &timer)) >= 0) {
+	err = snd_timer_new(chip->card, "YMFPCI", &tid, &timer);
+	if (err >= 0) {
 		strcpy(timer->name, "YMFPCI timer");
 		timer->private_data = chip;
 		timer->hw = snd_ymfpci_timer_hw;
@@ -2140,7 +2164,7 @@
 	chip->work_base = ptr;
 	chip->work_base_addr = ptr_addr;
 	
-	snd_BUG_ON(ptr + chip->work_size !=
+	snd_BUG_ON(ptr + PAGE_ALIGN(chip->work_size) !=
 		   chip->work_ptr.area + chip->work_ptr.bytes);
 
 	snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, chip->bank_base_playback_addr);
@@ -2334,7 +2358,8 @@
 	*rchip = NULL;
 
 	/* enable PCI device */
-	if ((err = pci_enable_device(pci)) < 0)
+	err = pci_enable_device(pci);
+	if (err < 0)
 		return err;
 
 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -2357,7 +2382,8 @@
 	pci_set_master(pci);
 	chip->src441_used = -1;
 
-	if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) {
+	chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI");
+	if (!chip->res_reg_area) {
 		dev_err(chip->card->dev,
 			"unable to grab memory region 0x%lx-0x%lx\n",
 			chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);
diff --git a/kernel/sound/soc/atmel/atmel-i2s.c b/kernel/sound/soc/atmel/atmel-i2s.c
index d870f56..0341b31 100644
--- a/kernel/sound/soc/atmel/atmel-i2s.c
+++ b/kernel/sound/soc/atmel/atmel-i2s.c
@@ -163,11 +163,14 @@
 
 #define I2S_MCK_12M288		12288000UL
 #define I2S_MCK_11M2896		11289600UL
+#define I2S_MCK_6M144		6144000UL
 
 /* mck = (32 * (imckfs+1) / (imckdiv+1)) * fs */
 static const struct atmel_i2s_gck_param gck_params[] = {
+	/* mck = 6.144Mhz */
+	{  8000, I2S_MCK_6M144,  1, 47},	/* mck =  768 fs */
+
 	/* mck = 12.288MHz */
-	{  8000, I2S_MCK_12M288, 0, 47},	/* mck = 1536 fs */
 	{ 16000, I2S_MCK_12M288, 1, 47},	/* mck =  768 fs */
 	{ 24000, I2S_MCK_12M288, 3, 63},	/* mck =  512 fs */
 	{ 32000, I2S_MCK_12M288, 3, 47},	/* mck =  384 fs */
diff --git a/kernel/sound/soc/atmel/mchp-spdifrx.c b/kernel/sound/soc/atmel/mchp-spdifrx.c
index 46f3407..39a3c2a 100644
--- a/kernel/sound/soc/atmel/mchp-spdifrx.c
+++ b/kernel/sound/soc/atmel/mchp-spdifrx.c
@@ -56,7 +56,7 @@
 /* Validity Bit Mode */
 #define SPDIFRX_MR_VBMODE_MASK		GENAMSK(1, 1)
 #define SPDIFRX_MR_VBMODE_ALWAYS_LOAD \
-	(0 << 1)	/* Load sample regardles of validity bit value */
+	(0 << 1)	/* Load sample regardless of validity bit value */
 #define SPDIFRX_MR_VBMODE_DISCARD_IF_VB1 \
 	(1 << 1)	/* Load sample only if validity bit is 0 */
 
@@ -217,7 +217,6 @@
 struct mchp_spdifrx_user_data {
 	unsigned char data[SPDIFRX_UD_BITS / 8];
 	struct completion done;
-	spinlock_t lock;	/* protect access to user data */
 };
 
 struct mchp_spdifrx_mixer_control {
@@ -231,13 +230,13 @@
 struct mchp_spdifrx_dev {
 	struct snd_dmaengine_dai_dma_data	capture;
 	struct mchp_spdifrx_mixer_control	control;
-	spinlock_t				blockend_lock;	/* protect access to blockend_refcount */
-	int					blockend_refcount;
+	struct mutex				mlock;
 	struct device				*dev;
 	struct regmap				*regmap;
 	struct clk				*pclk;
 	struct clk				*gclk;
 	unsigned int				fmt;
+	unsigned int				trigger_enabled;
 	unsigned int				gclk_enabled:1;
 };
 
@@ -275,37 +274,11 @@
 	}
 }
 
-/* called from non-atomic context only */
-static void mchp_spdifrx_isr_blockend_en(struct mchp_spdifrx_dev *dev)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&dev->blockend_lock, flags);
-	dev->blockend_refcount++;
-	/* don't enable BLOCKEND interrupt if it's already enabled */
-	if (dev->blockend_refcount == 1)
-		regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_BLOCKEND);
-	spin_unlock_irqrestore(&dev->blockend_lock, flags);
-}
-
-/* called from atomic/non-atomic context */
-static void mchp_spdifrx_isr_blockend_dis(struct mchp_spdifrx_dev *dev)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&dev->blockend_lock, flags);
-	dev->blockend_refcount--;
-	/* don't enable BLOCKEND interrupt if it's already enabled */
-	if (dev->blockend_refcount == 0)
-		regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND);
-	spin_unlock_irqrestore(&dev->blockend_lock, flags);
-}
-
 static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id)
 {
 	struct mchp_spdifrx_dev *dev = dev_id;
 	struct mchp_spdifrx_mixer_control *ctrl = &dev->control;
-	u32 sr, imr, pending, idr = 0;
+	u32 sr, imr, pending;
 	irqreturn_t ret = IRQ_NONE;
 	int ch;
 
@@ -320,13 +293,10 @@
 
 	if (pending & SPDIFRX_IR_BLOCKEND) {
 		for (ch = 0; ch < SPDIFRX_CHANNELS; ch++) {
-			spin_lock(&ctrl->user_data[ch].lock);
 			mchp_spdifrx_channel_user_data_read(dev, ch);
-			spin_unlock(&ctrl->user_data[ch].lock);
-
 			complete(&ctrl->user_data[ch].done);
 		}
-		mchp_spdifrx_isr_blockend_dis(dev);
+		regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND);
 		ret = IRQ_HANDLED;
 	}
 
@@ -334,7 +304,7 @@
 		if (pending & SPDIFRX_IR_CSC(ch)) {
 			mchp_spdifrx_channel_status_read(dev, ch);
 			complete(&ctrl->ch_stat[ch].done);
-			idr |= SPDIFRX_IR_CSC(ch);
+			regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_CSC(ch));
 			ret = IRQ_HANDLED;
 		}
 	}
@@ -344,8 +314,6 @@
 		ret = IRQ_HANDLED;
 	}
 
-	regmap_write(dev->regmap, SPDIFRX_IDR, idr);
-
 	return ret;
 }
 
@@ -353,47 +321,40 @@
 				struct snd_soc_dai *dai)
 {
 	struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
-	u32 mr;
-	int running;
-	int ret;
-
-	regmap_read(dev->regmap, SPDIFRX_MR, &mr);
-	running = !!(mr & SPDIFRX_MR_RXEN_ENABLE);
+	int ret = 0;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		if (!running) {
-			mr &= ~SPDIFRX_MR_RXEN_MASK;
-			mr |= SPDIFRX_MR_RXEN_ENABLE;
-			/* enable overrun interrupts */
-			regmap_write(dev->regmap, SPDIFRX_IER,
-				     SPDIFRX_IR_OVERRUN);
-		}
+		mutex_lock(&dev->mlock);
+		/* Enable overrun interrupts */
+		regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_OVERRUN);
+
+		/* Enable receiver. */
+		regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK,
+				   SPDIFRX_MR_RXEN_ENABLE);
+		dev->trigger_enabled = true;
+		mutex_unlock(&dev->mlock);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		if (running) {
-			mr &= ~SPDIFRX_MR_RXEN_MASK;
-			mr |= SPDIFRX_MR_RXEN_DISABLE;
-			/* disable overrun interrupts */
-			regmap_write(dev->regmap, SPDIFRX_IDR,
-				     SPDIFRX_IR_OVERRUN);
-		}
+		mutex_lock(&dev->mlock);
+		/* Disable overrun interrupts */
+		regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_OVERRUN);
+
+		/* Disable receiver. */
+		regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK,
+				   SPDIFRX_MR_RXEN_DISABLE);
+		dev->trigger_enabled = false;
+		mutex_unlock(&dev->mlock);
 		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
 	}
 
-	ret = regmap_write(dev->regmap, SPDIFRX_MR, mr);
-	if (ret) {
-		dev_err(dev->dev, "unable to enable/disable RX: %d\n", ret);
-		return ret;
-	}
-
-	return 0;
+	return ret;
 }
 
 static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream,
@@ -401,7 +362,7 @@
 				  struct snd_soc_dai *dai)
 {
 	struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
-	u32 mr;
+	u32 mr = 0;
 	int ret;
 
 	dev_dbg(dev->dev, "%s() rate=%u format=%#x width=%u channels=%u\n",
@@ -411,13 +372,6 @@
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		dev_err(dev->dev, "Playback is not supported\n");
 		return -EINVAL;
-	}
-
-	regmap_read(dev->regmap, SPDIFRX_MR, &mr);
-
-	if (mr & SPDIFRX_MR_RXEN_ENABLE) {
-		dev_err(dev->dev, "PCM already running\n");
-		return -EBUSY;
 	}
 
 	if (params_channels(params) != SPDIFRX_CHANNELS) {
@@ -445,6 +399,13 @@
 		return -EINVAL;
 	}
 
+	mutex_lock(&dev->mlock);
+	if (dev->trigger_enabled) {
+		dev_err(dev->dev, "PCM already running\n");
+		ret = -EBUSY;
+		goto unlock;
+	}
+
 	if (dev->gclk_enabled) {
 		clk_disable_unprepare(dev->gclk);
 		dev->gclk_enabled = 0;
@@ -455,19 +416,24 @@
 		dev_err(dev->dev,
 			"unable to set gclk min rate: rate %u * ratio %u + 1\n",
 			params_rate(params), SPDIFRX_GCLK_RATIO_MIN);
-		return ret;
+		goto unlock;
 	}
 	ret = clk_prepare_enable(dev->gclk);
 	if (ret) {
 		dev_err(dev->dev, "unable to enable gclk: %d\n", ret);
-		return ret;
+		goto unlock;
 	}
 	dev->gclk_enabled = 1;
 
 	dev_dbg(dev->dev, "GCLK range min set to %d\n",
 		params_rate(params) * SPDIFRX_GCLK_RATIO_MIN + 1);
 
-	return regmap_write(dev->regmap, SPDIFRX_MR, mr);
+	ret = regmap_write(dev->regmap, SPDIFRX_MR, mr);
+
+unlock:
+	mutex_unlock(&dev->mlock);
+
+	return ret;
 }
 
 static int mchp_spdifrx_hw_free(struct snd_pcm_substream *substream,
@@ -475,10 +441,12 @@
 {
 	struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
 
+	mutex_lock(&dev->mlock);
 	if (dev->gclk_enabled) {
 		clk_disable_unprepare(dev->gclk);
 		dev->gclk_enabled = 0;
 	}
+	mutex_unlock(&dev->mlock);
 	return 0;
 }
 
@@ -515,22 +483,51 @@
 {
 	struct mchp_spdifrx_mixer_control *ctrl = &dev->control;
 	struct mchp_spdifrx_ch_stat *ch_stat = &ctrl->ch_stat[channel];
-	int ret;
+	int ret = 0;
 
-	regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_CSC(channel));
-	/* check for new data available */
-	ret = wait_for_completion_interruptible_timeout(&ch_stat->done,
-							msecs_to_jiffies(100));
-	/* IP might not be started or valid stream might not be prezent */
-	if (ret < 0) {
-		dev_dbg(dev->dev, "channel status for channel %d timeout\n",
-			channel);
+	mutex_lock(&dev->mlock);
+
+	/*
+	 * We may reach this point with both clocks enabled but the receiver
+	 * still disabled. To void waiting for completion and return with
+	 * timeout check the dev->trigger_enabled.
+	 *
+	 * To retrieve data:
+	 * - if the receiver is enabled CSC IRQ will update the data in software
+	 *   caches (ch_stat->data)
+	 * - otherwise we just update it here the software caches with latest
+	 *   available information and return it; in this case we don't need
+	 *   spin locking as the IRQ is disabled and will not be raised from
+	 *   anywhere else.
+	 */
+
+	if (dev->trigger_enabled) {
+		reinit_completion(&ch_stat->done);
+		regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_CSC(channel));
+		/* Check for new data available */
+		ret = wait_for_completion_interruptible_timeout(&ch_stat->done,
+								msecs_to_jiffies(100));
+		/* Valid stream might not be present */
+		if (ret <= 0) {
+			dev_dbg(dev->dev, "channel status for channel %d timeout\n",
+				channel);
+			regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_CSC(channel));
+			ret = ret ? : -ETIMEDOUT;
+			goto unlock;
+		} else {
+			ret = 0;
+		}
+	} else {
+		/* Update software cache with latest channel status. */
+		mchp_spdifrx_channel_status_read(dev, channel);
 	}
 
 	memcpy(uvalue->value.iec958.status, ch_stat->data,
 	       sizeof(ch_stat->data));
 
-	return 0;
+unlock:
+	mutex_unlock(&dev->mlock);
+	return ret;
 }
 
 static int mchp_spdifrx_cs1_get(struct snd_kcontrol *kcontrol,
@@ -564,29 +561,49 @@
 				       int channel,
 				       struct snd_ctl_elem_value *uvalue)
 {
-	unsigned long flags;
 	struct mchp_spdifrx_mixer_control *ctrl = &dev->control;
 	struct mchp_spdifrx_user_data *user_data = &ctrl->user_data[channel];
-	int ret;
+	int ret = 0;
 
-	reinit_completion(&user_data->done);
-	mchp_spdifrx_isr_blockend_en(dev);
-	ret = wait_for_completion_interruptible_timeout(&user_data->done,
-							msecs_to_jiffies(100));
-	/* IP might not be started or valid stream might not be prezent */
-	if (ret <= 0) {
-		dev_dbg(dev->dev, "user data for channel %d timeout\n",
-			channel);
-		mchp_spdifrx_isr_blockend_dis(dev);
-		return ret;
+	mutex_lock(&dev->mlock);
+
+	/*
+	 * We may reach this point with both clocks enabled but the receiver
+	 * still disabled. To void waiting for completion to just timeout we
+	 * check here the dev->trigger_enabled flag.
+	 *
+	 * To retrieve data:
+	 * - if the receiver is enabled we need to wait for blockend IRQ to read
+	 *   data to and update it for us in software caches
+	 * - otherwise reading the SPDIFRX_CHUD() registers is enough.
+	 */
+
+	if (dev->trigger_enabled) {
+		reinit_completion(&user_data->done);
+		regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_BLOCKEND);
+		ret = wait_for_completion_interruptible_timeout(&user_data->done,
+								msecs_to_jiffies(100));
+		/* Valid stream might not be present. */
+		if (ret <= 0) {
+			dev_dbg(dev->dev, "user data for channel %d timeout\n",
+				channel);
+			regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND);
+			ret = ret ? : -ETIMEDOUT;
+			goto unlock;
+		} else {
+			ret = 0;
+		}
+	} else {
+		/* Update software cache with last available data. */
+		mchp_spdifrx_channel_user_data_read(dev, channel);
 	}
 
-	spin_lock_irqsave(&user_data->lock, flags);
 	memcpy(uvalue->value.iec958.subcode, user_data->data,
 	       sizeof(user_data->data));
-	spin_unlock_irqrestore(&user_data->lock, flags);
 
-	return 0;
+unlock:
+	mutex_unlock(&dev->mlock);
+	return ret;
 }
 
 static int mchp_spdifrx_subcode_ch1_get(struct snd_kcontrol *kcontrol,
@@ -627,9 +644,23 @@
 	u32 val;
 	bool ulock_old = ctrl->ulock;
 
-	regmap_read(dev->regmap, SPDIFRX_RSR, &val);
-	ctrl->ulock = !(val & SPDIFRX_RSR_ULOCK);
+	mutex_lock(&dev->mlock);
+
+	/*
+	 * The RSR.ULOCK has wrong value if both pclk and gclk are enabled
+	 * and the receiver is disabled. Thus we take into account the
+	 * dev->trigger_enabled here to return a real status.
+	 */
+	if (dev->trigger_enabled) {
+		regmap_read(dev->regmap, SPDIFRX_RSR, &val);
+		ctrl->ulock = !(val & SPDIFRX_RSR_ULOCK);
+	} else {
+		ctrl->ulock = 0;
+	}
+
 	uvalue->value.integer.value[0] = ctrl->ulock;
+
+	mutex_unlock(&dev->mlock);
 
 	return ulock_old != ctrl->ulock;
 }
@@ -643,8 +674,22 @@
 	u32 val;
 	bool badf_old = ctrl->badf;
 
-	regmap_read(dev->regmap, SPDIFRX_RSR, &val);
-	ctrl->badf = !!(val & SPDIFRX_RSR_BADF);
+	mutex_lock(&dev->mlock);
+
+	/*
+	 * The RSR.ULOCK has wrong value if both pclk and gclk are enabled
+	 * and the receiver is disabled. Thus we take into account the
+	 * dev->trigger_enabled here to return a real status.
+	 */
+	if (dev->trigger_enabled) {
+		regmap_read(dev->regmap, SPDIFRX_RSR, &val);
+		ctrl->badf = !!(val & SPDIFRX_RSR_BADF);
+	} else {
+		ctrl->badf = 0;
+	}
+
+	mutex_unlock(&dev->mlock);
+
 	uvalue->value.integer.value[0] = ctrl->badf;
 
 	return badf_old != ctrl->badf;
@@ -656,11 +701,48 @@
 	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
 	struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
 	struct mchp_spdifrx_mixer_control *ctrl = &dev->control;
-	u32 val;
+	u32 val = ~0U, loops = 10;
+	int ret;
 	bool signal_old = ctrl->signal;
 
-	regmap_read(dev->regmap, SPDIFRX_RSR, &val);
-	ctrl->signal = !(val & SPDIFRX_RSR_NOSIGNAL);
+	mutex_lock(&dev->mlock);
+
+	/*
+	 * To get the signal we need to have receiver enabled. This
+	 * could be enabled also from trigger() function thus we need to
+	 * take care of not disabling the receiver when it runs.
+	 */
+	if (!dev->trigger_enabled) {
+		ret = clk_prepare_enable(dev->gclk);
+		if (ret)
+			goto unlock;
+
+		regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK,
+				   SPDIFRX_MR_RXEN_ENABLE);
+
+		/* Wait for RSR.ULOCK bit. */
+		while (--loops) {
+			regmap_read(dev->regmap, SPDIFRX_RSR, &val);
+			if (!(val & SPDIFRX_RSR_ULOCK))
+				break;
+			usleep_range(100, 150);
+		}
+
+		regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK,
+				   SPDIFRX_MR_RXEN_DISABLE);
+
+		clk_disable_unprepare(dev->gclk);
+	} else {
+		regmap_read(dev->regmap, SPDIFRX_RSR, &val);
+	}
+
+unlock:
+	mutex_unlock(&dev->mlock);
+
+	if (!(val & SPDIFRX_RSR_ULOCK))
+		ctrl->signal = !(val & SPDIFRX_RSR_NOSIGNAL);
+	else
+		ctrl->signal = 0;
 	uvalue->value.integer.value[0] = ctrl->signal;
 
 	return signal_old != ctrl->signal;
@@ -685,18 +767,32 @@
 	u32 val;
 	int rate;
 
-	regmap_read(dev->regmap, SPDIFRX_RSR, &val);
+	mutex_lock(&dev->mlock);
 
-	/* if the receiver is not locked, ISF data is invalid */
-	if (val & SPDIFRX_RSR_ULOCK || !(val & SPDIFRX_RSR_IFS_MASK)) {
+	/*
+	 * The RSR.ULOCK has wrong value if both pclk and gclk are enabled
+	 * and the receiver is disabled. Thus we take into account the
+	 * dev->trigger_enabled here to return a real status.
+	 */
+	if (dev->trigger_enabled) {
+		regmap_read(dev->regmap, SPDIFRX_RSR, &val);
+		/* If the receiver is not locked, ISF data is invalid. */
+		if (val & SPDIFRX_RSR_ULOCK || !(val & SPDIFRX_RSR_IFS_MASK)) {
+			ucontrol->value.integer.value[0] = 0;
+			goto unlock;
+		}
+	} else {
+		/* Reveicer is not locked, IFS data is invalid. */
 		ucontrol->value.integer.value[0] = 0;
-		return 0;
+		goto unlock;
 	}
 
 	rate = clk_get_rate(dev->gclk);
 
 	ucontrol->value.integer.value[0] = rate / (32 * SPDIFRX_RSR_IFS(val));
 
+unlock:
+	mutex_unlock(&dev->mlock);
 	return 0;
 }
 
@@ -808,11 +904,9 @@
 		     SPDIFRX_MR_AUTORST_NOACTION |
 		     SPDIFRX_MR_PACK_DISABLED);
 
-	dev->blockend_refcount = 0;
 	for (ch = 0; ch < SPDIFRX_CHANNELS; ch++) {
 		init_completion(&ctrl->ch_stat[ch].done);
 		init_completion(&ctrl->user_data[ch].done);
-		spin_lock_init(&ctrl->user_data[ch].lock);
 	}
 
 	/* Add controls */
@@ -827,7 +921,7 @@
 	struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
 
 	/* Disable interrupts */
-	regmap_write(dev->regmap, SPDIFRX_IDR, 0xFF);
+	regmap_write(dev->regmap, SPDIFRX_IDR, GENMASK(14, 0));
 
 	clk_disable_unprepare(dev->pclk);
 
@@ -912,7 +1006,17 @@
 			"failed to get the PMC generated clock: %d\n", err);
 		return err;
 	}
-	spin_lock_init(&dev->blockend_lock);
+
+	/*
+	 * Signal control need a valid rate on gclk. hw_params() configures
+	 * it propertly but requesting signal before any hw_params() has been
+	 * called lead to invalid value returned for signal. Thus, configure
+	 * gclk at a valid rate, here, in initialization, to simplify the
+	 * control path.
+	 */
+	clk_set_min_rate(dev->gclk, 48000 * SPDIFRX_GCLK_RATIO_MIN + 1);
+
+	mutex_init(&dev->mlock);
 
 	dev->dev = &pdev->dev;
 	dev->regmap = regmap;
diff --git a/kernel/sound/soc/atmel/mchp-spdiftx.c b/kernel/sound/soc/atmel/mchp-spdiftx.c
index 0d2e3fa..bcca1cf 100644
--- a/kernel/sound/soc/atmel/mchp-spdiftx.c
+++ b/kernel/sound/soc/atmel/mchp-spdiftx.c
@@ -80,7 +80,7 @@
 #define SPDIFTX_MR_VALID1			BIT(24)
 #define SPDIFTX_MR_VALID2			BIT(25)
 
-/* Disable Null Frame on underrrun */
+/* Disable Null Frame on underrun */
 #define SPDIFTX_MR_DNFR_MASK		GENMASK(27, 27)
 #define SPDIFTX_MR_DNFR_INVALID		(0 << 27)
 #define SPDIFTX_MR_DNFR_VALID		(1 << 27)
diff --git a/kernel/sound/soc/atmel/tse850-pcm5142.c b/kernel/sound/soc/atmel/tse850-pcm5142.c
index 59e2edb..50c3dc6 100644
--- a/kernel/sound/soc/atmel/tse850-pcm5142.c
+++ b/kernel/sound/soc/atmel/tse850-pcm5142.c
@@ -23,7 +23,7 @@
 //   IN2 +---o--+------------+--o---+ OUT2
 //               loop2 relays
 //
-// The 'loop1' gpio pin controlls two relays, which are either in loop
+// The 'loop1' gpio pin controls two relays, which are either in loop
 // position, meaning that input and output are directly connected, or
 // they are in mixer position, meaning that the signal is passed through
 // the 'Sum' mixer. Similarly for 'loop2'.
diff --git a/kernel/sound/soc/codecs/Kconfig b/kernel/sound/soc/codecs/Kconfig
index cb3b581..836c9e1 100644
--- a/kernel/sound/soc/codecs/Kconfig
+++ b/kernel/sound/soc/codecs/Kconfig
@@ -164,6 +164,7 @@
 	imply SND_SOC_RK3528
 	imply SND_SOC_RK730
 	imply SND_SOC_RK817
+	imply SND_SOC_ROCKCHIP_SPI_CODEC
 	imply SND_SOC_RT274
 	imply SND_SOC_RT286
 	imply SND_SOC_RT298
@@ -1170,6 +1171,15 @@
 	default m if SND_SOC_RT286=m
 	default m if SND_SOC_RT298=m
 
+config SND_SOC_ROCKCHIP_SPI_CODEC
+	tristate "SPI CODEC"
+	depends on ARCH_ROCKCHIP
+	depends on SPI_MASTER
+	select REGMAP_SPI
+	help
+	  Enable support for a remote audio dsp which act as a codec.
+	  Control the adsp by spi.
+
 config SND_SOC_RT274
 	tristate
 	depends on I2C
@@ -1393,6 +1403,7 @@
 config SND_SOC_STAC9766
 	tristate
 	depends on SND_SOC_AC97_BUS
+	select REGMAP_AC97
 
 config SND_SOC_STI_SAS
 	tristate "codec Audio support for STI SAS codec"
@@ -1804,7 +1815,7 @@
 config SND_SOC_ZL38060
 	tristate "Microsemi ZL38060 Connected Home Audio Processor"
 	depends on SPI_MASTER
-	select GPIOLIB
+	depends on GPIOLIB
 	select REGMAP
 	help
 	  Support for ZL38060 Connected Home Audio Processor from Microsemi,
diff --git a/kernel/sound/soc/codecs/Makefile b/kernel/sound/soc/codecs/Makefile
index fd3e686..f27f7ff 100644
--- a/kernel/sound/soc/codecs/Makefile
+++ b/kernel/sound/soc/codecs/Makefile
@@ -175,6 +175,7 @@
 snd-soc-rk-dsm-objs := rk_dsm.o
 snd-soc-rl6231-objs := rl6231.o
 snd-soc-rl6347a-objs := rl6347a.o
+snd-soc-rockchip-spi-codec-objs := rockchip-spi-codec.o
 snd-soc-rt1011-objs := rt1011.o
 snd-soc-rt1015-objs := rt1015.o
 snd-soc-rt1015p-objs := rt1015p.o
@@ -503,6 +504,7 @@
 obj-$(CONFIG_SND_SOC_RK_DSM)	+= snd-soc-rk-dsm.o
 obj-$(CONFIG_SND_SOC_RL6231)	+= snd-soc-rl6231.o
 obj-$(CONFIG_SND_SOC_RL6347A)	+= snd-soc-rl6347a.o
+obj-$(CONFIG_SND_SOC_ROCKCHIP_SPI_CODEC)	+= snd-soc-rockchip-spi-codec.o
 obj-$(CONFIG_SND_SOC_RT1011)	+= snd-soc-rt1011.o
 obj-$(CONFIG_SND_SOC_RT1015)	+= snd-soc-rt1015.o
 obj-$(CONFIG_SND_SOC_RT1015P)	+= snd-soc-rt1015p.o
diff --git a/kernel/sound/soc/codecs/adau7118.c b/kernel/sound/soc/codecs/adau7118.c
index 841229d..305f294 100644
--- a/kernel/sound/soc/codecs/adau7118.c
+++ b/kernel/sound/soc/codecs/adau7118.c
@@ -445,22 +445,6 @@
 	.non_legacy_dai_naming	= 1,
 };
 
-static void adau7118_regulator_disable(void *data)
-{
-	struct adau7118_data *st = data;
-	int ret;
-	/*
-	 * If we fail to disable DVDD, don't bother in trying IOVDD. We
-	 * actually don't want to be left in the situation where DVDD
-	 * is enabled and IOVDD is disabled.
-	 */
-	ret = regulator_disable(st->dvdd);
-	if (ret)
-		return;
-
-	regulator_disable(st->iovdd);
-}
-
 static int adau7118_regulator_setup(struct adau7118_data *st)
 {
 	st->iovdd = devm_regulator_get(st->dev, "iovdd");
@@ -482,8 +466,7 @@
 		regcache_cache_only(st->map, true);
 	}
 
-	return devm_add_action_or_reset(st->dev, adau7118_regulator_disable,
-					st);
+	return 0;
 }
 
 static int adau7118_parset_dt(const struct adau7118_data *st)
diff --git a/kernel/sound/soc/codecs/cs42l51-i2c.c b/kernel/sound/soc/codecs/cs42l51-i2c.c
index 70260e0..3ff7336 100644
--- a/kernel/sound/soc/codecs/cs42l51-i2c.c
+++ b/kernel/sound/soc/codecs/cs42l51-i2c.c
@@ -19,6 +19,12 @@
 };
 MODULE_DEVICE_TABLE(i2c, cs42l51_i2c_id);
 
+const struct of_device_id cs42l51_of_match[] = {
+	{ .compatible = "cirrus,cs42l51", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, cs42l51_of_match);
+
 static int cs42l51_i2c_probe(struct i2c_client *i2c,
 			     const struct i2c_device_id *id)
 {
diff --git a/kernel/sound/soc/codecs/cs42l51.c b/kernel/sound/soc/codecs/cs42l51.c
index c61b17d..4b026e1 100644
--- a/kernel/sound/soc/codecs/cs42l51.c
+++ b/kernel/sound/soc/codecs/cs42l51.c
@@ -825,13 +825,6 @@
 }
 EXPORT_SYMBOL_GPL(cs42l51_resume);
 
-const struct of_device_id cs42l51_of_match[] = {
-	{ .compatible = "cirrus,cs42l51", },
-	{ }
-};
-MODULE_DEVICE_TABLE(of, cs42l51_of_match);
-EXPORT_SYMBOL_GPL(cs42l51_of_match);
-
 MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
 MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
 MODULE_LICENSE("GPL");
diff --git a/kernel/sound/soc/codecs/cs42l51.h b/kernel/sound/soc/codecs/cs42l51.h
index 9d06cf7..4f13c38 100644
--- a/kernel/sound/soc/codecs/cs42l51.h
+++ b/kernel/sound/soc/codecs/cs42l51.h
@@ -16,7 +16,6 @@
 int cs42l51_remove(struct device *dev);
 int __maybe_unused cs42l51_suspend(struct device *dev);
 int __maybe_unused cs42l51_resume(struct device *dev);
-extern const struct of_device_id cs42l51_of_match[];
 
 #define CS42L51_CHIP_ID			0x1B
 #define CS42L51_CHIP_REV_A		0x00
diff --git a/kernel/sound/soc/codecs/cs42l56.c b/kernel/sound/soc/codecs/cs42l56.c
index d41e031..3c5ec47 100644
--- a/kernel/sound/soc/codecs/cs42l56.c
+++ b/kernel/sound/soc/codecs/cs42l56.c
@@ -1193,18 +1193,12 @@
 	if (pdata) {
 		cs42l56->pdata = *pdata;
 	} else {
-		pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata),
-				     GFP_KERNEL);
-		if (!pdata)
-			return -ENOMEM;
-
 		if (i2c_client->dev.of_node) {
 			ret = cs42l56_handle_of_data(i2c_client,
 						     &cs42l56->pdata);
 			if (ret != 0)
 				return ret;
 		}
-		cs42l56->pdata = *pdata;
 	}
 
 	if (cs42l56->pdata.gpio_nreset) {
diff --git a/kernel/sound/soc/codecs/da7219-aad.c b/kernel/sound/soc/codecs/da7219-aad.c
index 48081d7..b316d61 100644
--- a/kernel/sound/soc/codecs/da7219-aad.c
+++ b/kernel/sound/soc/codecs/da7219-aad.c
@@ -347,11 +347,15 @@
 	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 	u8 events[DA7219_AAD_IRQ_REG_MAX];
 	u8 statusa;
-	int i, report = 0, mask = 0;
+	int i, ret, report = 0, mask = 0;
 
 	/* Read current IRQ events */
-	regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
-			 events, DA7219_AAD_IRQ_REG_MAX);
+	ret = regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
+			       events, DA7219_AAD_IRQ_REG_MAX);
+	if (ret) {
+		dev_warn_ratelimited(component->dev, "Failed to read IRQ events: %d\n", ret);
+		return IRQ_NONE;
+	}
 
 	if (!events[DA7219_AAD_IRQ_REG_A] && !events[DA7219_AAD_IRQ_REG_B])
 		return IRQ_NONE;
@@ -854,6 +858,8 @@
 			}
 		}
 	}
+
+	synchronize_irq(da7219_aad->irq);
 }
 
 void da7219_aad_resume(struct snd_soc_component *component)
diff --git a/kernel/sound/soc/codecs/es8316.c b/kernel/sound/soc/codecs/es8316.c
index 6094590..dafbf73 100644
--- a/kernel/sound/soc/codecs/es8316.c
+++ b/kernel/sound/soc/codecs/es8316.c
@@ -52,7 +52,12 @@
 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv, -9600, 50, 1);
 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_max_gain_tlv, -650, 150, 0);
 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_min_gain_tlv, -1200, 150, 0);
-static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_target_tlv, -1650, 150, 0);
+
+static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(alc_target_tlv,
+	0, 10, TLV_DB_SCALE_ITEM(-1650, 150, 0),
+	11, 11, TLV_DB_SCALE_ITEM(-150, 0, 0),
+);
+
 static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(hpmixer_gain_tlv,
 	0, 4, TLV_DB_SCALE_ITEM(-1200, 150, 0),
 	8, 11, TLV_DB_SCALE_ITEM(-450, 150, 0),
@@ -115,7 +120,7 @@
 		       alc_max_gain_tlv),
 	SOC_SINGLE_TLV("ALC Capture Min Volume", ES8316_ADC_ALC2, 0, 28, 0,
 		       alc_min_gain_tlv),
-	SOC_SINGLE_TLV("ALC Capture Target Volume", ES8316_ADC_ALC3, 4, 10, 0,
+	SOC_SINGLE_TLV("ALC Capture Target Volume", ES8316_ADC_ALC3, 4, 11, 0,
 		       alc_target_tlv),
 	SOC_SINGLE("ALC Capture Hold Time", ES8316_ADC_ALC3, 0, 10, 0),
 	SOC_SINGLE("ALC Capture Decay Time", ES8316_ADC_ALC4, 4, 10, 0),
@@ -148,7 +153,7 @@
 		"dmic data at high level",
 		"dmic data at low level",
 };
-static const unsigned int es8316_dmic_values[] = { 0, 1, 2 };
+static const unsigned int es8316_dmic_values[] = { 0, 2, 3 };
 static const struct soc_enum es8316_dmic_src_enum =
 	SOC_VALUE_ENUM_SINGLE(ES8316_ADC_DMIC, 0, 3,
 			      ARRAY_SIZE(es8316_dmic_txt),
@@ -364,13 +369,11 @@
 	int count = 0;
 
 	es8316->sysclk = freq;
+	es8316->sysclk_constraints.list = NULL;
+	es8316->sysclk_constraints.count = 0;
 
-	if (freq == 0) {
-		es8316->sysclk_constraints.list = NULL;
-		es8316->sysclk_constraints.count = 0;
-
+	if (freq == 0)
 		return 0;
-	}
 
 	ret = clk_set_rate(es8316->mclk, freq);
 	if (ret)
@@ -386,8 +389,10 @@
 			es8316->allowed_rates[count++] = freq / ratio;
 	}
 
-	es8316->sysclk_constraints.list = es8316->allowed_rates;
-	es8316->sysclk_constraints.count = count;
+	if (count) {
+		es8316->sysclk_constraints.list = es8316->allowed_rates;
+		es8316->sysclk_constraints.count = count;
+	}
 
 	return 0;
 }
@@ -807,15 +812,14 @@
 	es8316->irq = i2c_client->irq;
 	mutex_init(&es8316->lock);
 
-	ret = devm_request_threaded_irq(dev, es8316->irq, NULL, es8316_irq,
-					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
-					"es8316", es8316);
-	if (ret == 0) {
-		/* Gets re-enabled by es8316_set_jack() */
-		disable_irq(es8316->irq);
-	} else {
-		dev_warn(dev, "Failed to get IRQ %d: %d\n", es8316->irq, ret);
-		es8316->irq = -ENXIO;
+	if (es8316->irq > 0) {
+		ret = devm_request_threaded_irq(dev, es8316->irq, NULL, es8316_irq,
+						IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN,
+						"es8316", es8316);
+		if (ret) {
+			dev_warn(dev, "Failed to get IRQ %d: %d\n", es8316->irq, ret);
+			es8316->irq = -ENXIO;
+		}
 	}
 
 	return devm_snd_soc_register_component(&i2c_client->dev,
diff --git a/kernel/sound/soc/codecs/nau8824.c b/kernel/sound/soc/codecs/nau8824.c
index a95fe3f..9b22219 100644
--- a/kernel/sound/soc/codecs/nau8824.c
+++ b/kernel/sound/soc/codecs/nau8824.c
@@ -1896,6 +1896,30 @@
 		},
 		.driver_data = (void *)(NAU8824_JD_ACTIVE_HIGH),
 	},
+	{
+		/* Positivo CW14Q01P */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Positivo Tecnologia SA"),
+			DMI_MATCH(DMI_BOARD_NAME, "CW14Q01P"),
+		},
+		.driver_data = (void *)(NAU8824_JD_ACTIVE_HIGH),
+	},
+	{
+		/* Positivo K1424G */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Positivo Tecnologia SA"),
+			DMI_MATCH(DMI_BOARD_NAME, "K1424G"),
+		},
+		.driver_data = (void *)(NAU8824_JD_ACTIVE_HIGH),
+	},
+	{
+		/* Positivo N14ZP74G */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Positivo Tecnologia SA"),
+			DMI_MATCH(DMI_BOARD_NAME, "N14ZP74G"),
+		},
+		.driver_data = (void *)(NAU8824_JD_ACTIVE_HIGH),
+	},
 	{}
 };
 
diff --git a/kernel/sound/soc/codecs/pcm512x.c b/kernel/sound/soc/codecs/pcm512x.c
index 8153d3d..3677e90 100644
--- a/kernel/sound/soc/codecs/pcm512x.c
+++ b/kernel/sound/soc/codecs/pcm512x.c
@@ -1599,7 +1599,7 @@
 			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 @@
 			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 @@
 			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
diff --git a/kernel/sound/soc/codecs/rk817_codec.c b/kernel/sound/soc/codecs/rk817_codec.c
index ef06558..8c767ce 100644
--- a/kernel/sound/soc/codecs/rk817_codec.c
+++ b/kernel/sound/soc/codecs/rk817_codec.c
@@ -422,7 +422,7 @@
 		}
 
 		snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
-					      ADC_DIG_CLK_MASK, DAC_DIG_CLK_DIS);
+					      ADC_DIG_CLK_MASK, ADC_DIG_CLK_DIS);
 		usleep_range(2000, 2500);
 		snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
 					      ADC_DIG_CLK_MASK, ADC_DIG_CLK_EN);
@@ -1034,7 +1034,7 @@
 	return 0;
 }
 
-static int rk817_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
+static int rk817_digital_mute_dac(struct snd_soc_dai *dai, int mute, int stream)
 {
 	struct snd_soc_component *component = dai->component;
 	struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component);
@@ -1056,7 +1056,11 @@
 					      DAC_DIG_CLK_EN, DAC_DIG_CLK_DIS);
 		snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
 					      DAC_DIG_CLK_EN, DAC_DIG_CLK_EN);
+		snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
+					      I2SRX_EN_MASK, I2SRX_DIS);
 	} else {
+		snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
+					      I2SRX_EN_MASK, I2SRX_EN);
 		snd_soc_component_update_bits(component,
 					      RK817_CODEC_DDAC_MUTE_MIXCTL,
 					      DACMT_ENABLE, DACMT_DISABLE);
@@ -1106,6 +1110,28 @@
 	return 0;
 }
 
+static int rk817_digital_mute_adc(struct snd_soc_dai *dai, int mute, int stream)
+{
+	struct snd_soc_component *component = dai->component;
+
+	if (mute)
+		snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
+					      I2STX_EN_MASK, I2STX_DIS);
+	else
+		snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
+					      I2STX_EN_MASK, I2STX_EN);
+
+	return 0;
+}
+
+static int rk817_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
+{
+	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+		return rk817_digital_mute_dac(dai, mute, stream);
+	else
+		return rk817_digital_mute_adc(dai, mute, stream);
+}
+
 #define RK817_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\
 			      SNDRV_PCM_RATE_16000 |	\
 			      SNDRV_PCM_RATE_32000 |	\
@@ -1150,7 +1176,6 @@
 	.set_sysclk	= rk817_set_dai_sysclk,
 	.mute_stream	= rk817_digital_mute,
 	.shutdown	= rk817_codec_shutdown,
-	.no_capture_mute = 1,
 };
 
 static struct snd_soc_dai_driver rk817_dai[] = {
diff --git a/kernel/sound/soc/codecs/rk817_codec.h b/kernel/sound/soc/codecs/rk817_codec.h
index c5df0af..89e095c 100644
--- a/kernel/sound/soc/codecs/rk817_codec.h
+++ b/kernel/sound/soc/codecs/rk817_codec.h
@@ -81,7 +81,7 @@
 #define ADC_DIG_CLK_MASK		(0xf << 4)
 #define ADC_DIG_CLK_SFT			4
 #define ADC_DIG_CLK_DIS			(0x0 << 4)
-#define ADC_DIG_CLK_EN			(0xf << 4)
+#define ADC_DIG_CLK_EN			(0xe << 4)
 
 #define I2STX_CKE_EN			(0x1 << 6)
 #define I2STX_CKE_DIS			(0x0 << 6)
@@ -89,7 +89,15 @@
 #define DAC_DIG_CLK_MASK		(0xf << 0)
 #define DAC_DIG_CLK_SFT			0
 #define DAC_DIG_CLK_DIS			(0x0 << 0)
-#define DAC_DIG_CLK_EN			(0xf << 0)
+#define DAC_DIG_CLK_EN			(0xe << 0)
+
+#define I2STX_EN_MASK			BIT(4)
+#define I2STX_EN			BIT(4)
+#define I2STX_DIS			0
+
+#define I2SRX_EN_MASK			BIT(0)
+#define I2SRX_EN			BIT(0)
+#define I2SRX_DIS			0
 
 /* RK817_CODEC_APLL_CFG5 */
 #define PLL_PW_DOWN			(0x01 << 0)
diff --git a/kernel/sound/soc/codecs/rockchip-spi-codec.c b/kernel/sound/soc/codecs/rockchip-spi-codec.c
new file mode 100644
index 0000000..6011e94
--- /dev/null
+++ b/kernel/sound/soc/codecs/rockchip-spi-codec.c
@@ -0,0 +1,370 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip Audio CODEC Driver for remote dsp
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co.,Ltd
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+#include "rockchip-spi-codec.h"
+
+#define TDM_CH_MAX		(32)
+#define TDM_CH_ID(n)	(n)
+#define VOL_MAX	(0x27)
+#define VOL_MIN	(0x00)
+
+struct spi_codec_private {
+	struct device *dev;
+	struct regmap *regmap;
+	struct spi_device *spi;
+	struct snd_soc_component *component;
+	struct spi_codec_protocol_packet *packet;
+	struct mutex lock;
+	struct gpio_desc *reset_gpio;
+	int tdm_volume[TDM_CH_MAX];
+	int tdm_mute[TDM_CH_MAX];
+};
+
+static const DECLARE_TLV_DB_SCALE(playback_tlv, -1000, 100, 0);
+
+#define SPICODEC_CH_VOLUME(name, ch)				\
+	SOC_SINGLE_EXT_TLV(name, ch, VOL_MIN, VOL_MAX, 0X00,	\
+			   spi_codec_ext_ch_volume_get,		\
+			   spi_codec_ext_ch_volume_put, playback_tlv)
+
+#define SPICODEC_CH_MUTE(name, ch)				\
+	SOC_SINGLE_BOOL_EXT(name, ch,			\
+			    spi_codec_ext_ch_mute_get,	\
+			    spi_codec_ext_ch_mute_put)
+
+static inline struct spi_device *soc_component_to_spi(struct snd_soc_component *c)
+{
+	return container_of(c->dev, struct spi_device, dev);
+}
+
+static int spi_codec_cmd_request_unlock(struct spi_codec_private *spi_priv,
+					unsigned int cmd_type,
+					unsigned int *payload,
+					unsigned int payload_len,
+					unsigned int address)
+{
+	struct spi_device *spi = spi_priv->spi;
+	unsigned int packet_size, num, loop;
+
+	if (!spi)
+		return -ENODEV;
+
+	packet_size = sizeof(struct spi_codec_protocol_packet);
+
+	spi_priv->packet->cmd_begin = SS_CMD_BEGIN;
+	spi_priv->packet->cmd_type  = cmd_type;
+
+	loop = roundup(payload_len, PAYLOAD_MAX) / PAYLOAD_MAX;
+
+	spi_priv->packet->crc = 0;
+	spi_priv->packet->address = address;
+
+	for (num = 0; num < loop; num++) {
+		if (num == loop - 1) {
+			spi_priv->packet->payload_len = payload_len % PAYLOAD_MAX;
+			spi_priv->packet->cmd_end = SS_CMD_END;
+		} else {
+			spi_priv->packet->payload_len = PAYLOAD_MAX;
+			spi_priv->packet->cmd_end = SS_CMD_PARTIAL_END;
+		}
+
+		memcpy(spi_priv->packet->payload, payload + num * PAYLOAD_MAX,
+		       spi_priv->packet->payload_len);
+
+		if (spi_write(spi, spi_priv->packet, packet_size)) {
+			dev_err(&spi->dev, "ERR:spi write failed\n");
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static int spi_codec_set_parameter(struct spi_codec_private *spi_priv,
+				   unsigned int cmd_type,
+				   unsigned int *payload,
+				   unsigned int payload_len,
+				   unsigned int address)
+{
+	int ret;
+
+	mutex_lock(&spi_priv->lock);
+	ret = spi_codec_cmd_request_unlock(spi_priv, cmd_type, payload,
+					   payload_len, address);
+	mutex_unlock(&spi_priv->lock);
+
+	return ret;
+}
+
+static int spi_codec_ext_ch_volume_get(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct spi_codec_private *priv = snd_soc_component_get_drvdata(component);
+	struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
+	unsigned int ch = mc->reg;
+
+	ucontrol->value.integer.value[0] = priv->tdm_volume[ch];
+
+	return 0;
+}
+
+static int spi_codec_ext_ch_volume_put(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct spi_codec_private *priv = snd_soc_component_get_drvdata(component);
+	struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
+	unsigned int ch = mc->reg;
+
+	priv->tdm_volume[ch] = ucontrol->value.integer.value[0];
+
+	spi_codec_set_parameter(priv, SS_CMD_BLOCK_PARAMETER_SAFE,
+				&priv->tdm_volume[ch], sizeof(priv->tdm_volume[ch]),
+				TDM_CH_ID(ch));
+
+	return 0;
+}
+
+static int spi_codec_ext_ch_mute_get(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct spi_codec_private *priv = snd_soc_component_get_drvdata(component);
+	struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
+	unsigned int ch = mc->reg;
+
+	ucontrol->value.integer.value[0] = priv->tdm_mute[ch];
+
+	return 0;
+}
+
+static int spi_codec_ext_ch_mute_put(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct spi_codec_private *priv = snd_soc_component_get_drvdata(component);
+	struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
+	unsigned int ch = mc->reg;
+
+	priv->tdm_mute[ch] = ucontrol->value.integer.value[0];
+
+	spi_codec_set_parameter(priv, SS_CMD_BLOCK_PARAMETER_SAFE,
+				&priv->tdm_mute[ch], sizeof(priv->tdm_mute[ch]),
+				TDM_CH_ID(TDM_CH_MAX + ch));
+
+	return 0;
+}
+
+static int spi_codec_startup(struct snd_pcm_substream *substream,
+			     struct snd_soc_dai *dai)
+{
+	return 0;
+}
+
+static void spi_codec_shutdown(struct snd_pcm_substream *substream,
+			       struct snd_soc_dai *dai)
+{
+}
+
+static int spi_codec_hw_params(struct snd_pcm_substream *substream,
+			       struct snd_pcm_hw_params *params,
+			       struct snd_soc_dai *dai)
+{
+	return 0;
+}
+
+static int spi_codec_hw_free(struct snd_pcm_substream *substream,
+			     struct snd_soc_dai *dai)
+{
+	return 0;
+}
+
+static int spi_codec_set_sysclk(struct snd_soc_dai *cpu_dai, int stream,
+				unsigned int freq, int dir)
+{
+	return 0;
+}
+
+static int spi_codec_set_fmt(struct snd_soc_dai *cpu_dai,
+			     unsigned int fmt)
+{
+	return 0;
+}
+
+static int spi_codec_trigger(struct snd_pcm_substream *substream,
+			     int cmd, struct snd_soc_dai *dai)
+{
+	return 0;
+}
+
+static const struct snd_soc_dai_ops spi_codec_dai_ops = {
+	.startup	= spi_codec_startup,
+	.shutdown	= spi_codec_shutdown,
+	.hw_params	= spi_codec_hw_params,
+	.hw_free	= spi_codec_hw_free,
+	.set_sysclk	= spi_codec_set_sysclk,
+	.set_fmt	= spi_codec_set_fmt,
+	.trigger	= spi_codec_trigger,
+};
+
+static struct snd_soc_dai_driver spi_codec_dai = {
+	.name = "spi_codec",
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 1,
+		.channels_max = 384,
+		.rates = SNDRV_PCM_RATE_8000_384000,
+		.formats = (SNDRV_PCM_FMTBIT_S8 |
+			    SNDRV_PCM_FMTBIT_S16_LE |
+			    SNDRV_PCM_FMTBIT_S20_3LE |
+			    SNDRV_PCM_FMTBIT_S24_LE |
+			    SNDRV_PCM_FMTBIT_S32_LE),
+	},
+	.capture = {
+		.stream_name = "Capture",
+		.channels_min = 1,
+		.channels_max = 384,
+		.rates = SNDRV_PCM_RATE_8000_384000,
+		.formats = (SNDRV_PCM_FMTBIT_S8 |
+			    SNDRV_PCM_FMTBIT_S16_LE |
+			    SNDRV_PCM_FMTBIT_S20_3LE |
+			    SNDRV_PCM_FMTBIT_S24_LE |
+			    SNDRV_PCM_FMTBIT_S32_LE),
+	},
+	.ops = &spi_codec_dai_ops,
+};
+
+static int spi_codec_comp_probe(struct snd_soc_component *component)
+{
+	struct spi_device *spi = container_of(component->dev, struct spi_device, dev);
+	struct spi_codec_private *spi_priv = dev_get_drvdata(&spi->dev);
+
+	snd_soc_component_set_drvdata(component, spi_priv);
+
+	return 0;
+}
+
+static void spi_codec_comp_remove(struct snd_soc_component *component)
+{
+}
+
+static const struct snd_soc_dapm_widget spi_codec_dapm_widgets[] = {
+};
+
+static const struct snd_soc_dapm_route spi_codec_dapm_routes[] = {
+};
+
+static const struct snd_kcontrol_new spi_codec_snd_controls[] = {
+	SPICODEC_CH_VOLUME("CHN0 Playback Vol", 0),
+	SPICODEC_CH_VOLUME("CHN1 Playback Vol", 1),
+	SPICODEC_CH_VOLUME("CHN2 Playback Vol", 2),
+	SPICODEC_CH_VOLUME("CHN3 Playback Vol", 3),
+	SPICODEC_CH_VOLUME("CHN4 Playback Vol", 4),
+	SPICODEC_CH_VOLUME("CHN5 Playback Vol", 5),
+	SPICODEC_CH_VOLUME("CHN6 Playback Vol", 6),
+	SPICODEC_CH_VOLUME("CHN7 Playback Vol", 7),
+	SPICODEC_CH_MUTE("CHN0 Playback Mute", 0),
+	SPICODEC_CH_MUTE("CHN1 Playback Mute", 1),
+	SPICODEC_CH_MUTE("CHN2 Playback Mute", 2),
+	SPICODEC_CH_MUTE("CHN3 Playback Mute", 3),
+	SPICODEC_CH_MUTE("CHN4 Playback Mute", 4),
+	SPICODEC_CH_MUTE("CHN5 Playback Mute", 5),
+	SPICODEC_CH_MUTE("CHN6 Playback Mute", 6),
+	SPICODEC_CH_MUTE("CHN7 Playback Mute", 7),
+};
+
+static const struct snd_soc_component_driver spi_codec_component = {
+	.probe			= spi_codec_comp_probe,
+	.remove			= spi_codec_comp_remove,
+	.dapm_widgets		= spi_codec_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(spi_codec_dapm_widgets),
+	.dapm_routes		= spi_codec_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(spi_codec_dapm_routes),
+	.controls		= spi_codec_snd_controls,
+	.num_controls		= ARRAY_SIZE(spi_codec_snd_controls),
+};
+
+static int spi_codec_probe(struct spi_device *spi)
+{
+	struct device *dev = &spi->dev;
+	struct spi_codec_private *spi_priv;
+	int ret = 0;
+
+	spi_priv = devm_kzalloc(dev, sizeof(*spi_priv), GFP_KERNEL);
+	if (!spi_priv)
+		return -ENOMEM;
+
+	spi_priv->packet = devm_kzalloc(dev, sizeof(*spi_priv->packet), GFP_KERNEL);
+	if (!spi_priv->packet)
+		return -ENOMEM;
+
+	spi_priv->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_IN);
+	if (!IS_ERR_OR_NULL(spi_priv->reset_gpio)) {
+		if (!gpiod_get_value_cansleep(spi_priv->reset_gpio)) {
+			dev_err(dev, "the remote dsp should be powered!\n");
+			return -EINVAL;
+		}
+	}
+
+	mutex_init(&spi_priv->lock);
+
+	spi->bits_per_word = 8;
+	ret = spi_setup(spi);
+	if (ret < 0) {
+		dev_err(dev, "ERR:fail to setup spi\n");
+		return -EINVAL;
+	}
+
+	spi_priv->spi = spi;
+	spi_priv->dev = dev;
+	dev_set_drvdata(dev, spi_priv);
+
+	ret = devm_snd_soc_register_component(dev, &spi_codec_component,
+					      &spi_codec_dai, 1);
+
+	return ret;
+}
+
+static int spi_codec_remove(struct spi_device *spi)
+{
+	return 0;
+}
+
+static const struct of_device_id spi_codec_device_id[] = {
+	{ .compatible = "rockchip,spi-codec", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, spi_codec_device_id);
+
+static struct spi_driver spi_codec_driver = {
+	.driver		= {
+		.name	= "spi_codec",
+		.owner = THIS_MODULE,
+			.of_match_table = of_match_ptr(spi_codec_device_id),
+	},
+	.probe		= spi_codec_probe,
+	.remove		= spi_codec_remove,
+};
+module_spi_driver(spi_codec_driver);
+
+MODULE_AUTHOR("Jun Zeng <jun.zeng@rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip SPI Codec Driver");
+MODULE_LICENSE("GPL");
diff --git a/kernel/sound/soc/codecs/rockchip-spi-codec.h b/kernel/sound/soc/codecs/rockchip-spi-codec.h
new file mode 100644
index 0000000..a0b13e9
--- /dev/null
+++ b/kernel/sound/soc/codecs/rockchip-spi-codec.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * spi-codec.h - Rockchip Spi-Codec Driver
+ *
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __SPI_CODEC_H__
+#define __SPI_CODEC_H__
+
+#define PAYLOAD_MAX				(4096)
+
+#define SS_CMD_BEGIN				(0xF4190BE6UL)
+
+#define SS_CMD_PROGRAM				(0xFAAD0552UL)
+#define SS_CMD_PARAMETER_SAFE			(0xA5015AFEUL)
+#define SS_CMD_BLOCK_PARAMETER_SAFE		(0x4EA5B15AUL)
+#define SS_CMD_BLOCK_PARAMETER_NO_SAFE		(0xFFA1F05EUL)
+
+#define SS_CMD_END				(0xF1D20E2DUL)
+#define SS_CMD_PARTIAL_END			(0xE1D21E2DUL)
+
+#define SS_CMD_READ_REQUEST			(0xF3D20C2DUL)
+#define SS_CMD_BK_MIPS_VALUE			(0x00CE6319UL)
+#define SS_CMD_BK_ERROR_CODE			(0x00F7E808UL)
+#define SS_CMD_BK_READ_VALUE			(0x00BC543AUL)
+#define SS_CMD_BK_ACKNOWLEDGE			(0x00000000UL)
+#define SS_CMD_BK_VERSION_INFO			(0x003EDC12UL)
+
+struct spi_codec_protocol_packet {
+	unsigned int cmd_begin;
+
+	/* indicates the nature of payload */
+	unsigned int cmd_type;
+
+	/* payload data length */
+	unsigned int payload_len;
+	unsigned int payload[PAYLOAD_MAX];
+
+	/* payload or entire packet */
+	unsigned int crc;
+
+	/* parameter id */
+	unsigned int address;
+
+	unsigned int cmd_end;
+};
+
+#endif
diff --git a/kernel/sound/soc/codecs/rt298.c b/kernel/sound/soc/codecs/rt298.c
index dc0273a..1ca0621 100644
--- a/kernel/sound/soc/codecs/rt298.c
+++ b/kernel/sound/soc/codecs/rt298.c
@@ -1168,6 +1168,13 @@
 			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")
+		}
+	},
 	{ }
 };
 
diff --git a/kernel/sound/soc/codecs/rt5665.c b/kernel/sound/soc/codecs/rt5665.c
index 8a915cd..8b73c2d 100644
--- a/kernel/sound/soc/codecs/rt5665.c
+++ b/kernel/sound/soc/codecs/rt5665.c
@@ -4472,6 +4472,8 @@
 	struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 
 	regmap_write(rt5665->regmap, RT5665_RESET, 0);
+
+	regulator_bulk_disable(ARRAY_SIZE(rt5665->supplies), rt5665->supplies);
 }
 
 #ifdef CONFIG_PM
diff --git a/kernel/sound/soc/codecs/rt5670.c b/kernel/sound/soc/codecs/rt5670.c
index 47ce074..5822760 100644
--- a/kernel/sound/soc/codecs/rt5670.c
+++ b/kernel/sound/soc/codecs/rt5670.c
@@ -3192,8 +3192,6 @@
 	if (ret < 0)
 		goto err;
 
-	pm_runtime_put(&i2c->dev);
-
 	return 0;
 err:
 	pm_runtime_disable(&i2c->dev);
diff --git a/kernel/sound/soc/codecs/rt5682-sdw.c b/kernel/sound/soc/codecs/rt5682-sdw.c
index c9868dd..b0a35e3 100644
--- a/kernel/sound/soc/codecs/rt5682-sdw.c
+++ b/kernel/sound/soc/codecs/rt5682-sdw.c
@@ -413,9 +413,11 @@
 		usleep_range(30000, 30005);
 		loop--;
 	}
+
 	if (val != DEVICE_ID) {
 		dev_err(dev, "Device with ID register %x is not rt5682\n", val);
-		return -ENODEV;
+		ret = -ENODEV;
+		goto err_nodev;
 	}
 
 	rt5682_calibrate(rt5682);
@@ -486,10 +488,11 @@
 	rt5682->hw_init = true;
 	rt5682->first_hw_init = true;
 
+err_nodev:
 	pm_runtime_mark_last_busy(&slave->dev);
 	pm_runtime_put_autosuspend(&slave->dev);
 
-	dev_dbg(&slave->dev, "%s hw_init complete\n", __func__);
+	dev_dbg(&slave->dev, "%s hw_init complete: %d\n", __func__, ret);
 
 	return ret;
 }
diff --git a/kernel/sound/soc/codecs/rt711-sdw.h b/kernel/sound/soc/codecs/rt711-sdw.h
index 43b2b98..6acf985 100644
--- a/kernel/sound/soc/codecs/rt711-sdw.h
+++ b/kernel/sound/soc/codecs/rt711-sdw.h
@@ -267,7 +267,9 @@
 	{ 0x8393, 0x00 },
 	{ 0x7319, 0x00 },
 	{ 0x8399, 0x00 },
+	{ 0x752008, 0xa807 },
 	{ 0x752009, 0x1029 },
+	{ 0x75200b, 0x7770 },
 	{ 0x752011, 0x007a },
 	{ 0x75201a, 0x8003 },
 	{ 0x752045, 0x5289 },
diff --git a/kernel/sound/soc/codecs/rt711.c b/kernel/sound/soc/codecs/rt711.c
index 93d86f7..abc480d 100644
--- a/kernel/sound/soc/codecs/rt711.c
+++ b/kernel/sound/soc/codecs/rt711.c
@@ -389,6 +389,36 @@
 				RT711_HP_JD_FINAL_RESULT_CTL_JD12,
 				RT711_HP_JD_FINAL_RESULT_CTL_JD12);
 			break;
+		case RT711_JD2_100K:
+			rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
+				RT711_JD_CTL2, RT711_JD2_2PORT_100K_DECODE | RT711_JD2_1PORT_TYPE_DECODE |
+				RT711_HP_JD_SEL_JD2 | RT711_JD1_2PORT_TYPE_100K_DECODE,
+				RT711_JD2_2PORT_100K_DECODE_HP | RT711_JD2_1PORT_JD_HP |
+				RT711_HP_JD_SEL_JD2 | RT711_JD1_2PORT_JD_RESERVED);
+			rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
+				RT711_CC_DET1,
+				RT711_HP_JD_FINAL_RESULT_CTL_JD12,
+				RT711_HP_JD_FINAL_RESULT_CTL_JD12);
+			break;
+		case RT711_JD2_1P8V_1PORT:
+			rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
+				RT711_JD_CTL1, RT711_JD2_DIGITAL_JD_MODE_SEL,
+				RT711_JD2_1_JD_MODE);
+			rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
+				RT711_JD_CTL2, RT711_JD2_1PORT_TYPE_DECODE |
+				RT711_HP_JD_SEL_JD2,
+				RT711_JD2_1PORT_JD_HP |
+				RT711_HP_JD_SEL_JD2);
+			rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
+				RT711_JD_CTL4, RT711_JD2_PAD_PULL_UP_MASK |
+				RT711_JD2_MODE_SEL_MASK,
+				RT711_JD2_PAD_PULL_UP |
+				RT711_JD2_MODE2_1P8V_1PORT);
+			rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
+				RT711_CC_DET1,
+				RT711_HP_JD_FINAL_RESULT_CTL_JD12,
+				RT711_HP_JD_FINAL_RESULT_CTL_JD12);
+			break;
 		default:
 			dev_warn(rt711->component->dev, "Wrong JD source\n");
 			break;
diff --git a/kernel/sound/soc/codecs/rt711.h b/kernel/sound/soc/codecs/rt711.h
index ca0f581..5f2ba13 100644
--- a/kernel/sound/soc/codecs/rt711.h
+++ b/kernel/sound/soc/codecs/rt711.h
@@ -52,7 +52,9 @@
 
 /* Index (NID:20h) */
 #define RT711_DAC_DC_CALI_CTL1				0x00
+#define RT711_JD_CTL1				0x08
 #define RT711_JD_CTL2				0x09
+#define RT711_JD_CTL4				0x0b
 #define RT711_CC_DET1				0x11
 #define RT711_PARA_VERB_CTL				0x1a
 #define RT711_COMBO_JACK_AUTO_CTL1				0x45
@@ -171,10 +173,33 @@
 /* DAC DC offset calibration control-1 (0x00)(NID:20h) */
 #define RT711_DAC_DC_CALI_TRIGGER (0x1 << 15)
 
+/* jack detect control 1 (0x08)(NID:20h) */
+#define RT711_JD2_DIGITAL_JD_MODE_SEL (0x1 << 1)
+#define RT711_JD2_1_JD_MODE (0x0 << 1)
+#define RT711_JD2_2_JD_MODE (0x1 << 1)
+
 /* jack detect control 2 (0x09)(NID:20h) */
 #define RT711_JD2_2PORT_200K_DECODE_HP (0x1 << 13)
+#define RT711_JD2_2PORT_100K_DECODE (0x1 << 12)
+#define RT711_JD2_2PORT_100K_DECODE_HP (0x0 << 12)
 #define RT711_HP_JD_SEL_JD1 (0x0 << 1)
 #define RT711_HP_JD_SEL_JD2 (0x1 << 1)
+#define RT711_JD2_1PORT_TYPE_DECODE (0x3 << 10)
+#define RT711_JD2_1PORT_JD_LINE2 (0x0 << 10)
+#define RT711_JD2_1PORT_JD_HP (0x1 << 10)
+#define RT711_JD2_1PORT_JD_LINE1 (0x2 << 10)
+#define RT711_JD1_2PORT_TYPE_100K_DECODE (0x1 << 0)
+#define RT711_JD1_2PORT_JD_RESERVED (0x0 << 0)
+#define RT711_JD1_2PORT_JD_LINE1 (0x1 << 0)
+
+/* jack detect control 4 (0x0b)(NID:20h) */
+#define RT711_JD2_PAD_PULL_UP_MASK (0x1 << 3)
+#define RT711_JD2_PAD_NOT_PULL_UP (0x0 << 3)
+#define RT711_JD2_PAD_PULL_UP (0x1 << 3)
+#define RT711_JD2_MODE_SEL_MASK (0x3 << 0)
+#define RT711_JD2_MODE0_2PORT (0x0 << 0)
+#define RT711_JD2_MODE1_3P3V_1PORT (0x1 << 0)
+#define RT711_JD2_MODE2_1P8V_1PORT (0x2 << 0)
 
 /* CC DET1 (0x11)(NID:20h) */
 #define RT711_HP_JD_FINAL_RESULT_CTL_JD12 (0x1 << 10)
@@ -215,7 +240,9 @@
 enum rt711_jd_src {
 	RT711_JD_NULL,
 	RT711_JD1,
-	RT711_JD2
+	RT711_JD2,
+	RT711_JD2_100K,
+	RT711_JD2_1P8V_1PORT
 };
 
 int rt711_io_init(struct device *dev, struct sdw_slave *slave);
diff --git a/kernel/sound/soc/codecs/ssm2602.c b/kernel/sound/soc/codecs/ssm2602.c
index 9051602..c7a90c3 100644
--- a/kernel/sound/soc/codecs/ssm2602.c
+++ b/kernel/sound/soc/codecs/ssm2602.c
@@ -53,6 +53,18 @@
 	{ .reg = 0x09, .def = 0x0000 }
 };
 
+/*
+ * ssm2602 register patch
+ * Workaround for playback distortions after power up: activates digital
+ * core, and then powers on output, DAC, and whole chip at the same time
+ */
+
+static const struct reg_sequence ssm2602_patch[] = {
+	{ SSM2602_ACTIVE, 0x01 },
+	{ SSM2602_PWR,    0x07 },
+	{ SSM2602_RESET,  0x00 },
+};
+
 
 /*Appending several "None"s just for OSS mixer use*/
 static const char *ssm2602_input_select[] = {
@@ -589,6 +601,9 @@
 		return ret;
 	}
 
+	regmap_register_patch(ssm2602->regmap, ssm2602_patch,
+			      ARRAY_SIZE(ssm2602_patch));
+
 	/* set the update bits */
 	regmap_update_bits(ssm2602->regmap, SSM2602_LINVOL,
 			    LINVOL_LRIN_BOTH, LINVOL_LRIN_BOTH);
diff --git a/kernel/sound/soc/codecs/tlv320adcx140.c b/kernel/sound/soc/codecs/tlv320adcx140.c
index 53a8024..a6241a0 100644
--- a/kernel/sound/soc/codecs/tlv320adcx140.c
+++ b/kernel/sound/soc/codecs/tlv320adcx140.c
@@ -870,7 +870,7 @@
 
 	gpio_count = device_property_count_u32(adcx140->dev,
 			"ti,gpio-config");
-	if (gpio_count == 0)
+	if (gpio_count <= 0)
 		return 0;
 
 	if (gpio_count != ADCX140_NUM_GPIO_CFGS)
diff --git a/kernel/sound/soc/codecs/wm8904.c b/kernel/sound/soc/codecs/wm8904.c
index 1c360ba..c90e776 100644
--- a/kernel/sound/soc/codecs/wm8904.c
+++ b/kernel/sound/soc/codecs/wm8904.c
@@ -697,6 +697,7 @@
 	int dcs_mask;
 	int dcs_l, dcs_r;
 	int dcs_l_reg, dcs_r_reg;
+	int an_out_reg;
 	int timeout;
 	int pwr_reg;
 
@@ -712,6 +713,7 @@
 		dcs_mask = WM8904_DCS_ENA_CHAN_0 | WM8904_DCS_ENA_CHAN_1;
 		dcs_r_reg = WM8904_DC_SERVO_8;
 		dcs_l_reg = WM8904_DC_SERVO_9;
+		an_out_reg = WM8904_ANALOGUE_OUT1_LEFT;
 		dcs_l = 0;
 		dcs_r = 1;
 		break;
@@ -720,6 +722,7 @@
 		dcs_mask = WM8904_DCS_ENA_CHAN_2 | WM8904_DCS_ENA_CHAN_3;
 		dcs_r_reg = WM8904_DC_SERVO_6;
 		dcs_l_reg = WM8904_DC_SERVO_7;
+		an_out_reg = WM8904_ANALOGUE_OUT2_LEFT;
 		dcs_l = 2;
 		dcs_r = 3;
 		break;
@@ -792,6 +795,10 @@
 		snd_soc_component_update_bits(component, reg,
 				    WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
 				    WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP);
+
+		/* Update volume, requires PGA to be powered */
+		val = snd_soc_component_read(component, an_out_reg);
+		snd_soc_component_write(component, an_out_reg, val);
 		break;
 
 	case SND_SOC_DAPM_POST_PMU:
@@ -2299,6 +2306,9 @@
 	regmap_update_bits(wm8904->regmap, WM8904_BIAS_CONTROL_0,
 			    WM8904_POBCTRL, 0);
 
+	/* Fill the cache for the ADC test register */
+	regmap_read(wm8904->regmap, WM8904_ADC_TEST_0, &val);
+
 	/* Can leave the device powered off until we need it */
 	regcache_cache_only(wm8904->regmap, true);
 	regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
diff --git a/kernel/sound/soc/codecs/wm8994.c b/kernel/sound/soc/codecs/wm8994.c
index f578841..d3a7480 100644
--- a/kernel/sound/soc/codecs/wm8994.c
+++ b/kernel/sound/soc/codecs/wm8994.c
@@ -3853,7 +3853,12 @@
 	} else {
 		dev_dbg(component->dev, "Jack not detected\n");
 
+		/* Release wm8994->accdet_lock to avoid deadlock:
+		 * cancel_delayed_work_sync() takes wm8994->mic_work internal
+		 * lock and wm1811_mic_work takes wm8994->accdet_lock */
+		mutex_unlock(&wm8994->accdet_lock);
 		cancel_delayed_work_sync(&wm8994->mic_work);
+		mutex_lock(&wm8994->accdet_lock);
 
 		snd_soc_component_update_bits(component, WM8958_MICBIAS2,
 				    WM8958_MICB2_DISCH, WM8958_MICB2_DISCH);
diff --git a/kernel/sound/soc/codecs/wsa881x.c b/kernel/sound/soc/codecs/wsa881x.c
index 601525c..ce1f910 100644
--- a/kernel/sound/soc/codecs/wsa881x.c
+++ b/kernel/sound/soc/codecs/wsa881x.c
@@ -646,7 +646,6 @@
 	.readable_reg = wsa881x_readable_register,
 	.reg_format_endian = REGMAP_ENDIAN_NATIVE,
 	.val_format_endian = REGMAP_ENDIAN_NATIVE,
-	.can_multi_write = true,
 };
 
 enum {
diff --git a/kernel/sound/soc/dwc/dwc-i2s.c b/kernel/sound/soc/dwc/dwc-i2s.c
index 36da0f0..8e58347 100644
--- a/kernel/sound/soc/dwc/dwc-i2s.c
+++ b/kernel/sound/soc/dwc/dwc-i2s.c
@@ -132,13 +132,13 @@
 
 		/* Error Handling: TX */
 		if (isr[i] & ISR_TXFO) {
-			dev_err(dev->dev, "TX overrun (ch_id=%d)\n", i);
+			dev_err_ratelimited(dev->dev, "TX overrun (ch_id=%d)\n", i);
 			irq_valid = true;
 		}
 
 		/* Error Handling: TX */
 		if (isr[i] & ISR_RXFO) {
-			dev_err(dev->dev, "RX overrun (ch_id=%d)\n", i);
+			dev_err_ratelimited(dev->dev, "RX overrun (ch_id=%d)\n", i);
 			irq_valid = true;
 		}
 	}
@@ -181,30 +181,6 @@
 		i2s_write_reg(dev->i2s_base, CER, 0);
 		i2s_write_reg(dev->i2s_base, IER, 0);
 	}
-}
-
-static int dw_i2s_startup(struct snd_pcm_substream *substream,
-		struct snd_soc_dai *cpu_dai)
-{
-	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
-	union dw_i2s_snd_dma_data *dma_data = NULL;
-
-	if (!(dev->capability & DWC_I2S_RECORD) &&
-			(substream->stream == SNDRV_PCM_STREAM_CAPTURE))
-		return -EINVAL;
-
-	if (!(dev->capability & DWC_I2S_PLAY) &&
-			(substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
-		return -EINVAL;
-
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		dma_data = &dev->play_dma_data;
-	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
-		dma_data = &dev->capture_dma_data;
-
-	snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)dma_data);
-
-	return 0;
 }
 
 static void dw_i2s_config(struct dw_i2s_dev *dev, int stream)
@@ -305,12 +281,6 @@
 	return 0;
 }
 
-static void dw_i2s_shutdown(struct snd_pcm_substream *substream,
-		struct snd_soc_dai *dai)
-{
-	snd_soc_dai_set_dma_data(dai, substream, NULL);
-}
-
 static int dw_i2s_prepare(struct snd_pcm_substream *substream,
 			  struct snd_soc_dai *dai)
 {
@@ -382,8 +352,6 @@
 }
 
 static const struct snd_soc_dai_ops dw_i2s_dai_ops = {
-	.startup	= dw_i2s_startup,
-	.shutdown	= dw_i2s_shutdown,
 	.hw_params	= dw_i2s_hw_params,
 	.prepare	= dw_i2s_prepare,
 	.trigger	= dw_i2s_trigger,
@@ -624,6 +592,14 @@
 
 }
 
+static int dw_i2s_dai_probe(struct snd_soc_dai *dai)
+{
+	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+	snd_soc_dai_init_dma_data(dai, &dev->play_dma_data, &dev->capture_dma_data);
+	return 0;
+}
+
 static int dw_i2s_probe(struct platform_device *pdev)
 {
 	const struct i2s_platform_data *pdata = pdev->dev.platform_data;
@@ -642,6 +618,7 @@
 		return -ENOMEM;
 
 	dw_i2s_dai->ops = &dw_i2s_dai_ops;
+	dw_i2s_dai->probe = dw_i2s_dai_probe;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	dev->i2s_base = devm_ioremap_resource(&pdev->dev, res);
diff --git a/kernel/sound/soc/fsl/fsl-asoc-card.c b/kernel/sound/soc/fsl/fsl-asoc-card.c
index 7cd14d6..9a756d0 100644
--- a/kernel/sound/soc/fsl/fsl-asoc-card.c
+++ b/kernel/sound/soc/fsl/fsl-asoc-card.c
@@ -117,11 +117,11 @@
 
 static const struct snd_soc_dapm_route audio_map_ac97[] = {
 	/* 1st half -- Normal DAPM routes */
-	{"Playback",  NULL, "AC97 Playback"},
-	{"AC97 Capture",  NULL, "Capture"},
+	{"AC97 Playback",  NULL, "CPU AC97 Playback"},
+	{"CPU AC97 Capture",  NULL, "AC97 Capture"},
 	/* 2nd half -- ASRC DAPM routes */
-	{"AC97 Playback",  NULL, "ASRC-Playback"},
-	{"ASRC-Capture",  NULL, "AC97 Capture"},
+	{"CPU AC97 Playback",  NULL, "ASRC-Playback"},
+	{"ASRC-Capture",  NULL, "CPU AC97 Capture"},
 };
 
 static const struct snd_soc_dapm_route audio_map_tx[] = {
diff --git a/kernel/sound/soc/fsl/fsl_asrc_dma.c b/kernel/sound/soc/fsl/fsl_asrc_dma.c
index 29f91cd..9b2a986 100644
--- a/kernel/sound/soc/fsl/fsl_asrc_dma.c
+++ b/kernel/sound/soc/fsl/fsl_asrc_dma.c
@@ -207,14 +207,19 @@
 		be_chan = soc_component_to_pcm(component_be)->chan[substream->stream];
 		tmp_chan = be_chan;
 	}
-	if (!tmp_chan)
-		tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx");
+	if (!tmp_chan) {
+		tmp_chan = dma_request_chan(dev_be, tx ? "tx" : "rx");
+		if (IS_ERR(tmp_chan)) {
+			dev_err(dev, "failed to request DMA channel for Back-End\n");
+			return -EINVAL;
+		}
+	}
 
 	/*
 	 * An EDMA DEV_TO_DEV channel is fixed and bound with DMA event of each
 	 * peripheral, unlike SDMA channel that is allocated dynamically. So no
 	 * need to configure dma_request and dma_request2, but get dma_chan of
-	 * Back-End device directly via dma_request_slave_channel.
+	 * Back-End device directly via dma_request_chan.
 	 */
 	if (!asrc->use_edma) {
 		/* Get DMA request of Back-End */
diff --git a/kernel/sound/soc/fsl/fsl_micfil.c b/kernel/sound/soc/fsl/fsl_micfil.c
index 6c79460..97f83c6 100644
--- a/kernel/sound/soc/fsl/fsl_micfil.c
+++ b/kernel/sound/soc/fsl/fsl_micfil.c
@@ -87,21 +87,21 @@
 
 static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
 	SOC_SINGLE_SX_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL,
-			  MICFIL_OUTGAIN_CHX_SHIFT(0), 0xF, 0x7, gain_tlv),
+			  MICFIL_OUTGAIN_CHX_SHIFT(0), 0x8, 0xF, gain_tlv),
 	SOC_SINGLE_SX_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL,
-			  MICFIL_OUTGAIN_CHX_SHIFT(1), 0xF, 0x7, gain_tlv),
+			  MICFIL_OUTGAIN_CHX_SHIFT(1), 0x8, 0xF, gain_tlv),
 	SOC_SINGLE_SX_TLV("CH2 Volume", REG_MICFIL_OUT_CTRL,
-			  MICFIL_OUTGAIN_CHX_SHIFT(2), 0xF, 0x7, gain_tlv),
+			  MICFIL_OUTGAIN_CHX_SHIFT(2), 0x8, 0xF, gain_tlv),
 	SOC_SINGLE_SX_TLV("CH3 Volume", REG_MICFIL_OUT_CTRL,
-			  MICFIL_OUTGAIN_CHX_SHIFT(3), 0xF, 0x7, gain_tlv),
+			  MICFIL_OUTGAIN_CHX_SHIFT(3), 0x8, 0xF, gain_tlv),
 	SOC_SINGLE_SX_TLV("CH4 Volume", REG_MICFIL_OUT_CTRL,
-			  MICFIL_OUTGAIN_CHX_SHIFT(4), 0xF, 0x7, gain_tlv),
+			  MICFIL_OUTGAIN_CHX_SHIFT(4), 0x8, 0xF, gain_tlv),
 	SOC_SINGLE_SX_TLV("CH5 Volume", REG_MICFIL_OUT_CTRL,
-			  MICFIL_OUTGAIN_CHX_SHIFT(5), 0xF, 0x7, gain_tlv),
+			  MICFIL_OUTGAIN_CHX_SHIFT(5), 0x8, 0xF, gain_tlv),
 	SOC_SINGLE_SX_TLV("CH6 Volume", REG_MICFIL_OUT_CTRL,
-			  MICFIL_OUTGAIN_CHX_SHIFT(6), 0xF, 0x7, gain_tlv),
+			  MICFIL_OUTGAIN_CHX_SHIFT(6), 0x8, 0xF, gain_tlv),
 	SOC_SINGLE_SX_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL,
-			  MICFIL_OUTGAIN_CHX_SHIFT(7), 0xF, 0x7, gain_tlv),
+			  MICFIL_OUTGAIN_CHX_SHIFT(7), 0x8, 0xF, gain_tlv),
 	SOC_ENUM_EXT("MICFIL Quality Select",
 		     fsl_micfil_quality_enum,
 		     snd_soc_get_enum_double, snd_soc_put_enum_double),
diff --git a/kernel/sound/soc/fsl/fsl_mqs.c b/kernel/sound/soc/fsl/fsl_mqs.c
index 0d4efbe..c334396 100644
--- a/kernel/sound/soc/fsl/fsl_mqs.c
+++ b/kernel/sound/soc/fsl/fsl_mqs.c
@@ -204,10 +204,10 @@
 		}
 
 		mqs_priv->regmap = syscon_node_to_regmap(gpr_np);
+		of_node_put(gpr_np);
 		if (IS_ERR(mqs_priv->regmap)) {
 			dev_err(&pdev->dev, "failed to get gpr regmap\n");
-			ret = PTR_ERR(mqs_priv->regmap);
-			goto err_free_gpr_np;
+			return PTR_ERR(mqs_priv->regmap);
 		}
 	} else {
 		regs = devm_platform_ioremap_resource(pdev, 0);
@@ -236,8 +236,7 @@
 	if (IS_ERR(mqs_priv->mclk)) {
 		dev_err(&pdev->dev, "failed to get the clock: %ld\n",
 			PTR_ERR(mqs_priv->mclk));
-		ret = PTR_ERR(mqs_priv->mclk);
-		goto err_free_gpr_np;
+		return PTR_ERR(mqs_priv->mclk);
 	}
 
 	dev_set_drvdata(&pdev->dev, mqs_priv);
@@ -246,13 +245,9 @@
 	ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_fsl_mqs,
 			&fsl_mqs_dai, 1);
 	if (ret)
-		goto err_free_gpr_np;
+		return ret;
+
 	return 0;
-
-err_free_gpr_np:
-	of_node_put(gpr_np);
-
-	return ret;
 }
 
 static int fsl_mqs_remove(struct platform_device *pdev)
diff --git a/kernel/sound/soc/fsl/fsl_sai.c b/kernel/sound/soc/fsl/fsl_sai.c
index 3e5c1ea..03731d1 100644
--- a/kernel/sound/soc/fsl/fsl_sai.c
+++ b/kernel/sound/soc/fsl/fsl_sai.c
@@ -230,6 +230,7 @@
 	if (!sai->is_lsb_first)
 		val_cr4 |= FSL_SAI_CR4_MF;
 
+	sai->is_dsp_mode = false;
 	/* DAI mode */
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
@@ -551,7 +552,7 @@
 	u32 xcsr, count = 100;
 
 	regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
-			   FSL_SAI_CSR_TERE, 0);
+			   FSL_SAI_CSR_TERE | FSL_SAI_CSR_BCE, 0);
 
 	/* TERE will remain set till the end of current frame */
 	do {
diff --git a/kernel/sound/soc/fsl/fsl_sai.h b/kernel/sound/soc/fsl/fsl_sai.h
index 8923c68..691847d 100644
--- a/kernel/sound/soc/fsl/fsl_sai.h
+++ b/kernel/sound/soc/fsl/fsl_sai.h
@@ -87,6 +87,7 @@
 /* SAI Transmit/Receive Control Register */
 #define FSL_SAI_CSR_TERE	BIT(31)
 #define FSL_SAI_CSR_SE		BIT(30)
+#define FSL_SAI_CSR_BCE		BIT(28)
 #define FSL_SAI_CSR_FR		BIT(25)
 #define FSL_SAI_CSR_SR		BIT(24)
 #define FSL_SAI_CSR_xF_SHIFT	16
diff --git a/kernel/sound/soc/fsl/fsl_spdif.c b/kernel/sound/soc/fsl/fsl_spdif.c
index d01e8d5..64b85b7 100644
--- a/kernel/sound/soc/fsl/fsl_spdif.c
+++ b/kernel/sound/soc/fsl/fsl_spdif.c
@@ -612,6 +612,8 @@
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		regmap_update_bits(regmap, REG_SPDIF_SCR, dmaen, 0);
 		regmap_update_bits(regmap, REG_SPDIF_SIE, intr, 0);
+		regmap_write(regmap, REG_SPDIF_STL, 0x0);
+		regmap_write(regmap, REG_SPDIF_STR, 0x0);
 		break;
 	default:
 		return -EINVAL;
diff --git a/kernel/sound/soc/fsl/fsl_ssi.c b/kernel/sound/soc/fsl/fsl_ssi.c
index 1d774c8..94229ce 100644
--- a/kernel/sound/soc/fsl/fsl_ssi.c
+++ b/kernel/sound/soc/fsl/fsl_ssi.c
@@ -1161,14 +1161,14 @@
 	.symmetric_channels = 1,
 	.probe = fsl_ssi_dai_probe,
 	.playback = {
-		.stream_name = "AC97 Playback",
+		.stream_name = "CPU AC97 Playback",
 		.channels_min = 2,
 		.channels_max = 2,
 		.rates = SNDRV_PCM_RATE_8000_48000,
 		.formats = SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S20,
 	},
 	.capture = {
-		.stream_name = "AC97 Capture",
+		.stream_name = "CPU AC97 Capture",
 		.channels_min = 2,
 		.channels_max = 2,
 		.rates = SNDRV_PCM_RATE_48000,
diff --git a/kernel/sound/soc/fsl/imx-audmix.c b/kernel/sound/soc/fsl/imx-audmix.c
index cbdc0a2..bb2aab1 100644
--- a/kernel/sound/soc/fsl/imx-audmix.c
+++ b/kernel/sound/soc/fsl/imx-audmix.c
@@ -230,6 +230,8 @@
 
 		dai_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%s",
 					  fe_name_pref, args.np->full_name + 1);
+		if (!dai_name)
+			return -ENOMEM;
 
 		dev_info(pdev->dev.parent, "DAI FE name:%s\n", dai_name);
 
@@ -238,6 +240,8 @@
 			capture_dai_name =
 				devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s",
 					       dai_name, "CPU-Capture");
+			if (!capture_dai_name)
+				return -ENOMEM;
 		}
 
 		priv->dai[i].cpus = &dlc[0];
@@ -268,6 +272,8 @@
 				       "AUDMIX-Playback-%d", i);
 		be_cp = devm_kasprintf(&pdev->dev, GFP_KERNEL,
 				       "AUDMIX-Capture-%d", i);
+		if (!be_name || !be_pb || !be_cp)
+			return -ENOMEM;
 
 		priv->dai[num_dai + i].cpus = &dlc[3];
 		priv->dai[num_dai + i].codecs = &dlc[4];
@@ -295,6 +301,9 @@
 		priv->dapm_routes[i].source =
 			devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s",
 				       dai_name, "CPU-Playback");
+		if (!priv->dapm_routes[i].source)
+			return -ENOMEM;
+
 		priv->dapm_routes[i].sink = be_pb;
 		priv->dapm_routes[num_dai + i].source   = be_pb;
 		priv->dapm_routes[num_dai + i].sink     = be_cp;
@@ -313,7 +322,7 @@
 	if (IS_ERR(priv->cpu_mclk)) {
 		ret = PTR_ERR(priv->cpu_mclk);
 		dev_err(&cpu_pdev->dev, "failed to get DAI mclk1: %d\n", ret);
-		return -EINVAL;
+		return ret;
 	}
 
 	priv->audmix_pdev = audmix_pdev;
diff --git a/kernel/sound/soc/generic/audio-graph-card.c b/kernel/sound/soc/generic/audio-graph-card.c
index bfbee2d..84510ca 100644
--- a/kernel/sound/soc/generic/audio-graph-card.c
+++ b/kernel/sound/soc/generic/audio-graph-card.c
@@ -466,8 +466,10 @@
 			of_node_put(codec_ep);
 			of_node_put(codec_port);
 
-			if (ret < 0)
+			if (ret < 0) {
+				of_node_put(cpu_ep);
 				return ret;
+			}
 
 			codec_port_old = codec_port;
 		}
diff --git a/kernel/sound/soc/generic/simple-card.c b/kernel/sound/soc/generic/simple-card.c
index d916ec6..ac97e8b 100644
--- a/kernel/sound/soc/generic/simple-card.c
+++ b/kernel/sound/soc/generic/simple-card.c
@@ -410,6 +410,7 @@
 
 			if (ret < 0) {
 				of_node_put(codec);
+				of_node_put(plat);
 				of_node_put(np);
 				goto error;
 			}
diff --git a/kernel/sound/soc/intel/boards/bytcr_rt5640.c b/kernel/sound/soc/intel/boards/bytcr_rt5640.c
index 3020a99..9a5ab96 100644
--- a/kernel/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/kernel/sound/soc/intel/boards/bytcr_rt5640.c
@@ -393,6 +393,18 @@
 
 /* Please keep this list alphabetically sorted */
 static const struct dmi_system_id byt_rt5640_quirk_table[] = {
+	{	/* Acer Iconia One 7 B1-750 */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "VESPA2"),
+		},
+		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
+					BYT_RT5640_JD_SRC_JD1_IN4P |
+					BYT_RT5640_OVCD_TH_1500UA |
+					BYT_RT5640_OVCD_SF_0P75 |
+					BYT_RT5640_SSP0_AIF1 |
+					BYT_RT5640_MCLK_EN),
+	},
 	{	/* Acer Iconia Tab 8 W1-810 */
 		.matches = {
 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
@@ -431,6 +443,21 @@
 					BYT_RT5640_MCLK_EN),
 	},
 	{
+		/* Advantech MICA-071 */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Advantech"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"),
+		},
+		/* OVCD Th = 1500uA to reliable detect head-phones vs -set */
+		.driver_data = (void *)(BYT_RT5640_IN3_MAP |
+					BYT_RT5640_JD_SRC_JD2_IN4N |
+					BYT_RT5640_OVCD_TH_1500UA |
+					BYT_RT5640_OVCD_SF_0P75 |
+					BYT_RT5640_MONO_SPEAKER |
+					BYT_RT5640_DIFF_MIC |
+					BYT_RT5640_MCLK_EN),
+	},
+	{
 		.matches = {
 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 80 Cesium"),
diff --git a/kernel/sound/soc/intel/boards/sof_rt5682.c b/kernel/sound/soc/intel/boards/sof_rt5682.c
index 1f94fa5..5883d1f 100644
--- a/kernel/sound/soc/intel/boards/sof_rt5682.c
+++ b/kernel/sound/soc/intel/boards/sof_rt5682.c
@@ -704,6 +704,9 @@
 		links[id].num_platforms = ARRAY_SIZE(platform_component);
 		links[id].nonatomic = true;
 		links[id].dpcm_playback = 1;
+		/* feedback stream or firmware-generated echo reference */
+		links[id].dpcm_capture = 1;
+
 		links[id].no_pcm = 1;
 		links[id].cpus = &cpus[id];
 		links[id].num_cpus = 1;
diff --git a/kernel/sound/soc/intel/boards/sof_sdw.c b/kernel/sound/soc/intel/boards/sof_sdw.c
index 2554855..2b58bb8 100644
--- a/kernel/sound/soc/intel/boards/sof_sdw.c
+++ b/kernel/sound/soc/intel/boards/sof_sdw.c
@@ -13,8 +13,9 @@
 #include <sound/soc.h>
 #include <sound/soc-acpi.h>
 #include "sof_sdw_common.h"
+#include "../../codecs/rt711.h"
 
-unsigned long sof_sdw_quirk = SOF_RT711_JD_SRC_JD1;
+unsigned long sof_sdw_quirk = RT711_JD1;
 static int quirk_override = -1;
 module_param_named(quirk, quirk_override, int, 0444);
 MODULE_PARM_DESC(quirk, "Board-specific quirk override");
@@ -63,7 +64,7 @@
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6")
 		},
-		.driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
+		.driver_data = (void *)(RT711_JD2 |
 					SOF_RT715_DAI_ID_FIX),
 	},
 	{
@@ -73,7 +74,7 @@
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983")
 		},
-		.driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
+		.driver_data = (void *)(RT711_JD2 |
 					SOF_RT715_DAI_ID_FIX),
 	},
 	{
@@ -82,7 +83,7 @@
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"),
 		},
-		.driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
+		.driver_data = (void *)(RT711_JD2 |
 					SOF_RT715_DAI_ID_FIX |
 					SOF_SDW_FOUR_SPK),
 	},
@@ -92,7 +93,7 @@
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"),
 		},
-		.driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
+		.driver_data = (void *)(RT711_JD2 |
 					SOF_RT715_DAI_ID_FIX |
 					SOF_SDW_FOUR_SPK),
 	},
@@ -114,7 +115,7 @@
 				  "Tiger Lake Client Platform"),
 		},
 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
-					SOF_RT711_JD_SRC_JD1 |
+					RT711_JD1 |
 					SOF_SDW_PCH_DMIC |
 					SOF_SSP_PORT(SOF_I2S_SSP2)),
 	},
@@ -125,7 +126,7 @@
 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E")
 		},
 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
-					SOF_RT711_JD_SRC_JD2 |
+					RT711_JD2 |
 					SOF_RT715_DAI_ID_FIX),
 	},
 	{
@@ -135,7 +136,7 @@
 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E")
 		},
 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
-					SOF_RT711_JD_SRC_JD2 |
+					RT711_JD2 |
 					SOF_RT715_DAI_ID_FIX |
 					SOF_SDW_FOUR_SPK),
 	},
@@ -173,7 +174,7 @@
 		},
 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
 					SOF_SDW_PCH_DMIC |
-					SOF_RT711_JD_SRC_JD2),
+					RT711_JD2),
 	},
 	/* TigerLake-SDCA devices */
 	{
@@ -183,7 +184,7 @@
 			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32")
 		},
 		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
-					SOF_RT711_JD_SRC_JD2 |
+					RT711_JD2 |
 					SOF_RT715_DAI_ID_FIX |
 					SOF_SDW_FOUR_SPK),
 	},
@@ -194,11 +195,36 @@
 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"),
 		},
-		.driver_data = (void *)(SOF_RT711_JD_SRC_JD1 |
+		.driver_data = (void *)(RT711_JD1 |
 					SOF_SDW_TGL_HDMI |
 					SOF_RT715_DAI_ID_FIX |
 					SOF_SDW_PCH_DMIC),
 	},
+	{
+		.callback = sof_sdw_quirk_cb,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Meteor Lake Client Platform"),
+		},
+		.driver_data = (void *)(RT711_JD2_100K),
+	},
+	{
+		.callback = sof_sdw_quirk_cb,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Rex"),
+		},
+		.driver_data = (void *)(SOF_SDW_PCH_DMIC),
+	},
+	/* LunarLake devices */
+	{
+		.callback = sof_sdw_quirk_cb,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Lunar Lake Client Platform"),
+		},
+		.driver_data = (void *)(RT711_JD2_100K),
+	},
 	{}
 };
 
diff --git a/kernel/sound/soc/intel/boards/sof_sdw_common.h b/kernel/sound/soc/intel/boards/sof_sdw_common.h
index ea60e8e..8016005 100644
--- a/kernel/sound/soc/intel/boards/sof_sdw_common.h
+++ b/kernel/sound/soc/intel/boards/sof_sdw_common.h
@@ -23,11 +23,6 @@
 #define SDW_MAX_GROUPS 9
 
 enum {
-	SOF_RT711_JD_SRC_JD1 = 1,
-	SOF_RT711_JD_SRC_JD2 = 2,
-};
-
-enum {
 	SOF_PRE_TGL_HDMI_COUNT = 3,
 	SOF_TGL_HDMI_COUNT = 4,
 };
diff --git a/kernel/sound/soc/intel/skylake/skl.c b/kernel/sound/soc/intel/skylake/skl.c
index 8b99372..2085e12 100644
--- a/kernel/sound/soc/intel/skylake/skl.c
+++ b/kernel/sound/soc/intel/skylake/skl.c
@@ -439,7 +439,7 @@
 
 	skl->init_done = 0; /* to be sure */
 
-	snd_hdac_ext_stop_streams(bus);
+	snd_hdac_stop_streams_and_chip(bus);
 
 	if (bus->irq >= 0)
 		free_irq(bus->irq, (void *)bus);
@@ -1100,7 +1100,10 @@
 	if (!skl->init_done)
 		return;
 
-	snd_hdac_ext_stop_streams(bus);
+	snd_hdac_stop_streams(bus);
+	snd_hdac_ext_bus_link_power_down_all(bus);
+	skl_dsp_sleep(skl->dsp);
+
 	list_for_each_entry(s, &bus->stream_list, list) {
 		stream = stream_to_hdac_ext_stream(s);
 		snd_hdac_ext_stream_decouple(bus, stream, false);
diff --git a/kernel/sound/soc/jz4740/jz4740-i2s.c b/kernel/sound/soc/jz4740/jz4740-i2s.c
index 0793e28..fb6476b 100644
--- a/kernel/sound/soc/jz4740/jz4740-i2s.c
+++ b/kernel/sound/soc/jz4740/jz4740-i2s.c
@@ -59,7 +59,8 @@
 #define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
 #define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10)
 #define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9)
-#define JZ_AIC_CTRL_FLUSH		BIT(8)
+#define JZ_AIC_CTRL_TFLUSH		BIT(8)
+#define JZ_AIC_CTRL_RFLUSH		BIT(7)
 #define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6)
 #define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5)
 #define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4)
@@ -94,6 +95,8 @@
 struct i2s_soc_info {
 	enum jz47xx_i2s_version version;
 	struct snd_soc_dai_driver *dai;
+
+	bool shared_fifo_flush;
 };
 
 struct jz4740_i2s {
@@ -122,19 +125,44 @@
 	writel(value, i2s->base + reg);
 }
 
+static inline void jz4740_i2s_set_bits(const struct jz4740_i2s *i2s,
+	unsigned int reg, uint32_t bits)
+{
+	uint32_t value = jz4740_i2s_read(i2s, reg);
+	value |= bits;
+	jz4740_i2s_write(i2s, reg, value);
+}
+
 static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *dai)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-	uint32_t conf, ctrl;
+	uint32_t conf;
 	int ret;
+
+	/*
+	 * When we can flush FIFOs independently, only flush the FIFO
+	 * that is starting up. We can do this when the DAI is active
+	 * because it does not disturb other active substreams.
+	 */
+	if (!i2s->soc_info->shared_fifo_flush) {
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_TFLUSH);
+		else
+			jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_RFLUSH);
+	}
 
 	if (snd_soc_dai_active(dai))
 		return 0;
 
-	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
-	ctrl |= JZ_AIC_CTRL_FLUSH;
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
+	/*
+	 * When there is a shared flush bit for both FIFOs, the TFLUSH
+	 * bit flushes both FIFOs. Flushing while the DAI is active would
+	 * cause FIFO underruns in other active substreams so we have to
+	 * guard this behind the snd_soc_dai_active() check.
+	 */
+	if (i2s->soc_info->shared_fifo_flush)
+		jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_TFLUSH);
 
 	ret = clk_prepare_enable(i2s->clk_i2s);
 	if (ret)
@@ -467,6 +495,7 @@
 static const struct i2s_soc_info jz4740_i2s_soc_info = {
 	.version = JZ_I2S_JZ4740,
 	.dai = &jz4740_i2s_dai,
+	.shared_fifo_flush = true,
 };
 
 static const struct i2s_soc_info jz4760_i2s_soc_info = {
diff --git a/kernel/sound/soc/kirkwood/kirkwood-dma.c b/kernel/sound/soc/kirkwood/kirkwood-dma.c
index e037826..2d41e6a 100644
--- a/kernel/sound/soc/kirkwood/kirkwood-dma.c
+++ b/kernel/sound/soc/kirkwood/kirkwood-dma.c
@@ -86,7 +86,7 @@
 
 	/* try to find matching cs for current dma address */
 	for (i = 0; i < dram->num_cs; i++) {
-		const struct mbus_dram_window *cs = dram->cs + i;
+		const struct mbus_dram_window *cs = &dram->cs[i];
 		if ((cs->base & 0xffff0000) < (dma & 0xffff0000)) {
 			writel(cs->base & 0xffff0000,
 				base + KIRKWOOD_AUDIO_WIN_BASE_REG(win));
diff --git a/kernel/sound/soc/mediatek/common/mtk-btcvsd.c b/kernel/sound/soc/mediatek/common/mtk-btcvsd.c
index 86e982e..e1f57b0 100644
--- a/kernel/sound/soc/mediatek/common/mtk-btcvsd.c
+++ b/kernel/sound/soc/mediatek/common/mtk-btcvsd.c
@@ -1038,11 +1038,9 @@
 	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 */
diff --git a/kernel/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c b/kernel/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
index 7e7bda7..3f6d965 100644
--- a/kernel/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+++ b/kernel/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
@@ -1054,6 +1054,7 @@
 	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)
@@ -1074,12 +1075,6 @@
 	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))
@@ -1142,23 +1137,62 @@
 	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_cleanup_components;
+	}
+
+	ret = snd_soc_component_initialize(comp_hdmi,
+					   &mt8173_afe_hdmi_dai_component,
+					   &pdev->dev);
+	if (ret)
+		goto err_cleanup_components;
+
+#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;
+
+	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_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 +1200,8 @@
 
 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);
diff --git a/kernel/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/kernel/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
index 390da5b..9421b91 100644
--- a/kernel/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+++ b/kernel/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
@@ -200,14 +200,16 @@
 	if (!mt8173_rt5650_rt5514_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node) {
 		dev_err(&pdev->dev,
 			"Property 'audio-codec' missing or invalid\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 	mt8173_rt5650_rt5514_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node =
 		of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 1);
 	if (!mt8173_rt5650_rt5514_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node) {
 		dev_err(&pdev->dev,
 			"Property 'audio-codec' missing or invalid\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 	mt8173_rt5650_rt5514_codec_conf[0].dlc.of_node =
 		mt8173_rt5650_rt5514_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node;
@@ -219,6 +221,7 @@
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
 
+out:
 	of_node_put(platform_node);
 	return ret;
 }
diff --git a/kernel/sound/soc/meson/axg-spdifin.c b/kernel/sound/soc/meson/axg-spdifin.c
index d0d09f9..7aaded1 100644
--- a/kernel/sound/soc/meson/axg-spdifin.c
+++ b/kernel/sound/soc/meson/axg-spdifin.c
@@ -112,34 +112,6 @@
 	return 0;
 }
 
-static int axg_spdifin_startup(struct snd_pcm_substream *substream,
-			       struct snd_soc_dai *dai)
-{
-	struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai);
-	int ret;
-
-	ret = clk_prepare_enable(priv->refclk);
-	if (ret) {
-		dev_err(dai->dev,
-			"failed to enable spdifin reference clock\n");
-		return ret;
-	}
-
-	regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN,
-			   SPDIFIN_CTRL0_EN);
-
-	return 0;
-}
-
-static void axg_spdifin_shutdown(struct snd_pcm_substream *substream,
-				 struct snd_soc_dai *dai)
-{
-	struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai);
-
-	regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, 0);
-	clk_disable_unprepare(priv->refclk);
-}
-
 static void axg_spdifin_write_mode_param(struct regmap *map, int mode,
 					 unsigned int val,
 					 unsigned int num_per_reg,
@@ -251,25 +223,38 @@
 	ret = axg_spdifin_sample_mode_config(dai, priv);
 	if (ret) {
 		dev_err(dai->dev, "mode configuration failed\n");
-		clk_disable_unprepare(priv->pclk);
-		return ret;
+		goto pclk_err;
 	}
 
+	ret = clk_prepare_enable(priv->refclk);
+	if (ret) {
+		dev_err(dai->dev,
+			"failed to enable spdifin reference clock\n");
+		goto pclk_err;
+	}
+
+	regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN,
+			   SPDIFIN_CTRL0_EN);
+
 	return 0;
+
+pclk_err:
+	clk_disable_unprepare(priv->pclk);
+	return ret;
 }
 
 static int axg_spdifin_dai_remove(struct snd_soc_dai *dai)
 {
 	struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai);
 
+	regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, 0);
+	clk_disable_unprepare(priv->refclk);
 	clk_disable_unprepare(priv->pclk);
 	return 0;
 }
 
 static const struct snd_soc_dai_ops axg_spdifin_ops = {
 	.prepare	= axg_spdifin_prepare,
-	.startup	= axg_spdifin_startup,
-	.shutdown	= axg_spdifin_shutdown,
 };
 
 static int axg_spdifin_iec958_info(struct snd_kcontrol *kcontrol,
diff --git a/kernel/sound/soc/meson/axg-tdm-formatter.c b/kernel/sound/soc/meson/axg-tdm-formatter.c
index cab7fa2..4834cfd 100644
--- a/kernel/sound/soc/meson/axg-tdm-formatter.c
+++ b/kernel/sound/soc/meson/axg-tdm-formatter.c
@@ -30,27 +30,32 @@
 					struct axg_tdm_stream *ts,
 					unsigned int offset)
 {
-	unsigned int val, ch = ts->channels;
-	unsigned long mask;
-	int i, j;
+	unsigned int ch = ts->channels;
+	u32 val[AXG_TDM_NUM_LANES];
+	int i, j, k;
+
+	/*
+	 * We need to mimick the slot distribution used by the HW to keep the
+	 * channel placement consistent regardless of the number of channel
+	 * in the stream. This is why the odd algorithm below is used.
+	 */
+	memset(val, 0, sizeof(*val) * AXG_TDM_NUM_LANES);
 
 	/*
 	 * Distribute the channels of the stream over the available slots
-	 * of each TDM lane
+	 * of each TDM lane. We need to go over the 32 slots ...
 	 */
-	for (i = 0; i < AXG_TDM_NUM_LANES; i++) {
-		val = 0;
-		mask = ts->mask[i];
-
-		for (j = find_first_bit(&mask, 32);
-		     (j < 32) && ch;
-		     j = find_next_bit(&mask, 32, j + 1)) {
-			val |= 1 << j;
-			ch -= 1;
+	for (i = 0; (i < 32) && ch; i += 2) {
+		/* ... of all the lanes ... */
+		for (j = 0; j < AXG_TDM_NUM_LANES; j++) {
+			/* ... then distribute the channels in pairs */
+			for (k = 0; k < 2; k++) {
+				if ((BIT(i + k) & ts->mask[j]) && ch) {
+					val[j] |= BIT(i + k);
+					ch -= 1;
+				}
+			}
 		}
-
-		regmap_write(map, offset, val);
-		offset += regmap_get_reg_stride(map);
 	}
 
 	/*
@@ -63,6 +68,11 @@
 		return -EINVAL;
 	}
 
+	for (i = 0; i < AXG_TDM_NUM_LANES; i++) {
+		regmap_write(map, offset, val[i]);
+		offset += regmap_get_reg_stride(map);
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(axg_tdm_formatter_set_channel_masks);
diff --git a/kernel/sound/soc/pxa/mmp-pcm.c b/kernel/sound/soc/pxa/mmp-pcm.c
index 53fc49e..0791737 100644
--- a/kernel/sound/soc/pxa/mmp-pcm.c
+++ b/kernel/sound/soc/pxa/mmp-pcm.c
@@ -98,7 +98,7 @@
 
 	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;
 	}
diff --git a/kernel/sound/soc/qcom/lpass-cpu.c b/kernel/sound/soc/qcom/lpass-cpu.c
index ecd6c04..9e70c19 100644
--- a/kernel/sound/soc/qcom/lpass-cpu.c
+++ b/kernel/sound/soc/qcom/lpass-cpu.c
@@ -816,10 +816,11 @@
 					struct lpass_data *data)
 {
 	struct device_node *node;
-	int ret, id;
+	int ret, i, id;
 
 	/* Allow all channels by default for backwards compatibility */
-	for (id = 0; id < data->variant->num_dai; id++) {
+	for (i = 0; i < data->variant->num_dai; i++) {
+		id = data->variant->dai_driver[i].id;
 		data->mi2s_playback_sd_mode[id] = LPAIF_I2SCTL_MODE_8CH;
 		data->mi2s_capture_sd_mode[id] = LPAIF_I2SCTL_MODE_8CH;
 	}
diff --git a/kernel/sound/soc/qcom/lpass-sc7180.c b/kernel/sound/soc/qcom/lpass-sc7180.c
index c647e62..cb4e901 100644
--- a/kernel/sound/soc/qcom/lpass-sc7180.c
+++ b/kernel/sound/soc/qcom/lpass-sc7180.c
@@ -129,6 +129,9 @@
 
 	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++)
diff --git a/kernel/sound/soc/rockchip/Kconfig b/kernel/sound/soc/rockchip/Kconfig
index 337ead6..623cace 100644
--- a/kernel/sound/soc/rockchip/Kconfig
+++ b/kernel/sound/soc/rockchip/Kconfig
@@ -8,8 +8,12 @@
 	  select the audio interfaces to support below.
 
 config SND_SOC_ROCKCHIP_DLP
-	tristate "Rockchip Digital Loopback Driver"
+	tristate
+
+config SND_SOC_ROCKCHIP_DLP_PCM
+	tristate "Rockchip Digital Loopback PCM Driver"
 	depends on SND_SOC_ROCKCHIP
+	select SND_SOC_ROCKCHIP_DLP
 	help
 	  Say Y or M if you want to add support for DLP driver for
 	  Rockchip DMA-Based Digital Loopback.
@@ -42,6 +46,7 @@
 config SND_SOC_ROCKCHIP_MULTI_DAIS
 	tristate "Rockchip Multi-DAIS Device Driver"
 	depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP
+	select SND_SOC_ROCKCHIP_DLP
 	help
 	  Say Y or M if you want to add support for Multi-dais driver for
 	  Rockchip.
diff --git a/kernel/sound/soc/rockchip/Makefile b/kernel/sound/soc/rockchip/Makefile
index 873b628..ca8dfb5 100644
--- a/kernel/sound/soc/rockchip/Makefile
+++ b/kernel/sound/soc/rockchip/Makefile
@@ -1,6 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 # ROCKCHIP Platform Support
+snd-soc-rockchip-objs := rockchip_utils.o
 snd-soc-rockchip-dlp-objs := rockchip_dlp.o
+snd-soc-rockchip-dlp-pcm-objs := rockchip_dlp_pcm.o
 snd-soc-rockchip-i2s-objs := rockchip_i2s.o
 snd-soc-rockchip-i2s-tdm-objs := rockchip_i2s_tdm.o
 snd-soc-rockchip-multi-dais-objs := rockchip_multi_dais.o rockchip_multi_dais_pcm.o
@@ -16,7 +18,9 @@
 snd-soc-rockchip-vad-$(CONFIG_ARM) += vad_preprocess_arm.o
 endif
 
+obj-$(CONFIG_SND_SOC_ROCKCHIP) += snd-soc-rockchip.o
 obj-$(CONFIG_SND_SOC_ROCKCHIP_DLP) += snd-soc-rockchip-dlp.o
+obj-$(CONFIG_SND_SOC_ROCKCHIP_DLP_PCM) += snd-soc-rockchip-dlp-pcm.o
 obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-rockchip-i2s.o
 obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S_TDM) += snd-soc-rockchip-i2s-tdm.o
 obj-$(CONFIG_SND_SOC_ROCKCHIP_MULTI_DAIS) += snd-soc-rockchip-multi-dais.o
diff --git a/kernel/sound/soc/rockchip/rockchip_dlp.c b/kernel/sound/soc/rockchip/rockchip_dlp.c
index f954a32..f0d1f41 100644
--- a/kernel/sound/soc/rockchip/rockchip_dlp.c
+++ b/kernel/sound/soc/rockchip/rockchip_dlp.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Rockchip DLP (Digital Loopback) Driver
  *
@@ -11,28 +11,15 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
-#include <linux/dma-mapping.h>
-#include <linux/of.h>
 
-#include <sound/dmaengine_pcm.h>
 #include "rockchip_dlp.h"
 
-#ifdef DLP_DBG
-#define dlp_info(args...)		pr_info(args)
-#else
-#define dlp_info(args...)		no_printk(args)
-#endif
-
-#define SND_DMAENGINE_DLP_DRV_NAME	"snd_dmaengine_dlp"
 #define PBUF_CNT			2
-
-static unsigned int prealloc_buffer_size_kbytes = 512;
-module_param(prealloc_buffer_size_kbytes, uint, 0444);
-MODULE_PARM_DESC(prealloc_buffer_size_kbytes, "Preallocate DMA buffer size (KB).");
 
 /* MUST: dlp_text should be match to enum dlp_mode */
 static const char *const dlp_text[] = {
@@ -55,74 +42,43 @@
 	"16CH: 8 Mics + 8 Loopbacks",
 };
 
-enum dlp_mode {
-	DLP_MODE_DISABLED,
-	DLP_MODE_2CH_1LP_1MIC,		/* replace cap-ch-0   with play-ch-0 */
-	DLP_MODE_2CH_1MIC_1LP,		/* replace cap-ch-1   with play-ch-1 */
-	DLP_MODE_2CH_1MIC_1LP_MIX,	/* replace cap-ch-1   with play-ch-all-mix */
-	DLP_MODE_2CH_2LP,		/* replace cap-ch-0~1 with play-ch-0~1 */
-	DLP_MODE_4CH_2MIC_2LP,		/* replace cap-ch-2~3 with play-ch-0~1 */
-	DLP_MODE_4CH_2MIC_1LP_MIX,	/* replace cap-ch-3   with play-ch-all-mix */
-	DLP_MODE_4CH_4LP,		/* replace cap-ch-0~3 with play-ch-0~3 */
-	DLP_MODE_6CH_4MIC_2LP,		/* replace cap-ch-4~5 with play-ch-0~1 */
-	DLP_MODE_6CH_4MIC_1LP_MIX,	/* replace cap-ch-4   with play-ch-all-mix */
-	DLP_MODE_6CH_6LP,		/* replace cap-ch-0~5 with play-ch-0~5 */
-	DLP_MODE_8CH_6MIC_2LP,		/* replace cap-ch-6~7 with play-ch-0~1 */
-	DLP_MODE_8CH_6MIC_1LP_MIX,	/* replace cap-ch-6   with play-ch-all-mix */
-	DLP_MODE_8CH_8LP,		/* replace cap-ch-0~7 with play-ch-0~7 */
-	DLP_MODE_10CH_8MIC_2LP,		/* replace cap-ch-8~9 with play-ch-0~1 */
-	DLP_MODE_10CH_8MIC_1LP_MIX,	/* replace cap-ch-8   with play-ch-all-mix */
-	DLP_MODE_16CH_8MIC_8LP,		/* replace cap-ch-8~f with play-ch-8~f */
-};
-
-struct dmaengine_dlp_runtime_data;
-struct dmaengine_dlp {
-	struct device *dev;
-	struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
-	const struct snd_dlp_config *config;
-	struct snd_soc_component component;
-	struct list_head ref_list;
-	enum dlp_mode mode;
-	struct dmaengine_dlp_runtime_data *pref;
-	spinlock_t lock;
-	spinlock_t pref_lock;
-};
-
-struct dmaengine_dlp_runtime_data {
-	struct dmaengine_dlp *parent;
-	struct dmaengine_dlp_runtime_data *ref;
-	struct dma_chan *dma_chan;
-	struct kref refcount;
-	struct list_head node;
-	dma_cookie_t cookie;
-
-	char *buf;
-	snd_pcm_uframes_t buf_sz;
-	snd_pcm_uframes_t period_sz;
-	snd_pcm_uframes_t hw_ptr;
-	snd_pcm_sframes_t hw_ptr_delta; /* play-ptr - cap-ptr */
-	unsigned long period_elapsed;
-	unsigned int frame_bytes;
-	unsigned int channels;
-	unsigned int buf_ofs;
-	int stream;
-};
-
-static inline void dlp_activate(struct dmaengine_dlp *dlp)
+static inline void drd_buf_free(struct dlp_runtime_data *drd)
 {
-	spin_lock(&dlp->lock);
-	dlp->component.active++;
-	spin_unlock(&dlp->lock);
+	if (drd && drd->buf) {
+		dev_dbg(drd->parent->dev, "%s: stream[%d]: 0x%px\n",
+			__func__, drd->stream, drd->buf);
+		kvfree(drd->buf);
+		drd->buf = NULL;
+	}
 }
 
-static inline void dlp_deactivate(struct dmaengine_dlp *dlp)
+static inline int drd_buf_alloc(struct dlp_runtime_data *drd, int size)
 {
-	spin_lock(&dlp->lock);
-	dlp->component.active--;
-	spin_unlock(&dlp->lock);
+	if (drd) {
+		if (snd_BUG_ON(drd->buf))
+			return -EINVAL;
+
+		drd->buf = kvzalloc(size, GFP_KERNEL);
+		if (!drd->buf)
+			return -ENOMEM;
+		dev_dbg(drd->parent->dev, "%s: stream[%d]: 0x%px\n",
+			__func__, drd->stream, drd->buf);
+	}
+
+	return 0;
 }
 
-static inline bool dlp_mode_channels_match(struct dmaengine_dlp *dlp,
+static inline void dlp_activate(struct dlp *dlp)
+{
+	atomic_inc(&dlp->active);
+}
+
+static inline void dlp_deactivate(struct dlp *dlp)
+{
+	atomic_dec(&dlp->active);
+}
+
+static inline bool dlp_mode_channels_match(struct dlp *dlp,
 					   int ch, int *expected)
 {
 	*expected = 0;
@@ -163,183 +119,135 @@
 	}
 }
 
-static inline ssize_t dlp_channels_to_bytes(struct dmaengine_dlp_runtime_data *prtd,
-					    int channels)
-{
-	return (prtd->frame_bytes / prtd->channels) * channels;
-}
-
-static inline ssize_t dlp_frames_to_bytes(struct dmaengine_dlp_runtime_data *prtd,
-					  snd_pcm_sframes_t size)
-{
-	return size * prtd->frame_bytes;
-}
-
-static inline snd_pcm_sframes_t dlp_bytes_to_frames(struct dmaengine_dlp_runtime_data *prtd,
-						    ssize_t size)
-{
-	return size / prtd->frame_bytes;
-}
-
-static inline struct dmaengine_dlp *soc_component_to_dlp(struct snd_soc_component *p)
-{
-	return container_of(p, struct dmaengine_dlp, component);
-}
-
-static inline struct dmaengine_dlp_runtime_data *substream_to_prtd(
-	const struct snd_pcm_substream *substream)
-{
-	if (!substream->runtime)
-		return NULL;
-
-	return substream->runtime->private_data;
-}
-
-static struct dma_chan *snd_dmaengine_dlp_get_chan(struct snd_pcm_substream *substream)
-{
-	struct dmaengine_dlp_runtime_data *prtd = substream_to_prtd(substream);
-
-	return prtd->dma_chan;
-}
-
-static struct device *dmaengine_dma_dev(struct dmaengine_dlp *dlp,
-	struct snd_pcm_substream *substream)
-{
-	if (!dlp->chan[substream->stream])
-		return NULL;
-
-	return dlp->chan[substream->stream]->device->dev;
-}
-
-static int dlp_get_offset_size(struct dmaengine_dlp_runtime_data *prtd,
+static int dlp_get_offset_size(struct dlp_runtime_data *drd,
 			       enum dlp_mode mode, int *ofs, int *size, bool *mix)
 {
-	bool is_playback = prtd->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	bool is_playback = drd->stream == SNDRV_PCM_STREAM_PLAYBACK;
 	int ret = 0;
 
 	switch (mode) {
 	case DLP_MODE_2CH_1LP_1MIC:
 		*ofs = 0;
-		*size = dlp_channels_to_bytes(prtd, 1);
+		*size = dlp_channels_to_bytes(drd, 1);
 		break;
 	case DLP_MODE_2CH_1MIC_1LP:
-		*ofs = dlp_channels_to_bytes(prtd, 1);
-		*size = dlp_channels_to_bytes(prtd, 1);
+		*ofs = dlp_channels_to_bytes(drd, 1);
+		*size = dlp_channels_to_bytes(drd, 1);
 		break;
 	case DLP_MODE_2CH_1MIC_1LP_MIX:
 		if (is_playback) {
 			*ofs = 0;
-			*size = dlp_frames_to_bytes(prtd, 1);
+			*size = dlp_frames_to_bytes(drd, 1);
 			if (mix)
 				*mix = true;
 		} else {
-			*ofs = dlp_channels_to_bytes(prtd, 1);
-			*size = dlp_channels_to_bytes(prtd, 1);
+			*ofs = dlp_channels_to_bytes(drd, 1);
+			*size = dlp_channels_to_bytes(drd, 1);
 		}
 		break;
 	case DLP_MODE_2CH_2LP:
 		*ofs = 0;
-		*size = dlp_channels_to_bytes(prtd, 2);
+		*size = dlp_channels_to_bytes(drd, 2);
 		break;
 	case DLP_MODE_4CH_2MIC_2LP:
 		if (is_playback) {
 			*ofs = 0;
-			*size = dlp_channels_to_bytes(prtd, 2);
+			*size = dlp_channels_to_bytes(drd, 2);
 		} else {
-			*ofs = dlp_channels_to_bytes(prtd, 2);
-			*size = dlp_channels_to_bytes(prtd, 2);
+			*ofs = dlp_channels_to_bytes(drd, 2);
+			*size = dlp_channels_to_bytes(drd, 2);
 		}
 		break;
 	case DLP_MODE_4CH_2MIC_1LP_MIX:
 		if (is_playback) {
 			*ofs = 0;
-			*size = dlp_frames_to_bytes(prtd, 1);
+			*size = dlp_frames_to_bytes(drd, 1);
 			if (mix)
 				*mix = true;
 		} else {
-			*ofs = dlp_channels_to_bytes(prtd, 2);
-			*size = dlp_channels_to_bytes(prtd, 1);
+			*ofs = dlp_channels_to_bytes(drd, 2);
+			*size = dlp_channels_to_bytes(drd, 1);
 		}
 		break;
 	case DLP_MODE_4CH_4LP:
 		*ofs = 0;
-		*size = dlp_channels_to_bytes(prtd, 4);
+		*size = dlp_channels_to_bytes(drd, 4);
 		break;
 	case DLP_MODE_6CH_4MIC_2LP:
 		if (is_playback) {
 			*ofs = 0;
-			*size = dlp_channels_to_bytes(prtd, 2);
+			*size = dlp_channels_to_bytes(drd, 2);
 		} else {
-			*ofs = dlp_channels_to_bytes(prtd, 4);
-			*size = dlp_channels_to_bytes(prtd, 2);
+			*ofs = dlp_channels_to_bytes(drd, 4);
+			*size = dlp_channels_to_bytes(drd, 2);
 		}
 		break;
 	case DLP_MODE_6CH_4MIC_1LP_MIX:
 		if (is_playback) {
 			*ofs = 0;
-			*size = dlp_frames_to_bytes(prtd, 1);
+			*size = dlp_frames_to_bytes(drd, 1);
 			if (mix)
 				*mix = true;
 		} else {
-			*ofs = dlp_channels_to_bytes(prtd, 4);
-			*size = dlp_channels_to_bytes(prtd, 1);
+			*ofs = dlp_channels_to_bytes(drd, 4);
+			*size = dlp_channels_to_bytes(drd, 1);
 		}
 		break;
 	case DLP_MODE_6CH_6LP:
 		*ofs = 0;
-		*size = dlp_channels_to_bytes(prtd, 6);
+		*size = dlp_channels_to_bytes(drd, 6);
 		break;
 	case DLP_MODE_8CH_6MIC_2LP:
 		if (is_playback) {
 			*ofs = 0;
-			*size = dlp_channels_to_bytes(prtd, 2);
+			*size = dlp_channels_to_bytes(drd, 2);
 		} else {
-			*ofs = dlp_channels_to_bytes(prtd, 6);
-			*size = dlp_channels_to_bytes(prtd, 2);
+			*ofs = dlp_channels_to_bytes(drd, 6);
+			*size = dlp_channels_to_bytes(drd, 2);
 		}
 		break;
 	case DLP_MODE_8CH_6MIC_1LP_MIX:
 		if (is_playback) {
 			*ofs = 0;
-			*size = dlp_frames_to_bytes(prtd, 1);
+			*size = dlp_frames_to_bytes(drd, 1);
 			if (mix)
 				*mix = true;
 		} else {
-			*ofs = dlp_channels_to_bytes(prtd, 6);
-			*size = dlp_channels_to_bytes(prtd, 1);
+			*ofs = dlp_channels_to_bytes(drd, 6);
+			*size = dlp_channels_to_bytes(drd, 1);
 		}
 		break;
 	case DLP_MODE_8CH_8LP:
 		*ofs = 0;
-		*size = dlp_channels_to_bytes(prtd, 8);
+		*size = dlp_channels_to_bytes(drd, 8);
 		break;
 	case DLP_MODE_10CH_8MIC_2LP:
 		if (is_playback) {
 			*ofs = 0;
-			*size = dlp_channels_to_bytes(prtd, 2);
+			*size = dlp_channels_to_bytes(drd, 2);
 		} else {
-			*ofs = dlp_channels_to_bytes(prtd, 8);
-			*size = dlp_channels_to_bytes(prtd, 2);
+			*ofs = dlp_channels_to_bytes(drd, 8);
+			*size = dlp_channels_to_bytes(drd, 2);
 		}
 		break;
 	case DLP_MODE_10CH_8MIC_1LP_MIX:
 		if (is_playback) {
 			*ofs = 0;
-			*size = dlp_frames_to_bytes(prtd, 1);
+			*size = dlp_frames_to_bytes(drd, 1);
 			if (mix)
 				*mix = true;
 		} else {
-			*ofs = dlp_channels_to_bytes(prtd, 8);
-			*size = dlp_channels_to_bytes(prtd, 1);
+			*ofs = dlp_channels_to_bytes(drd, 8);
+			*size = dlp_channels_to_bytes(drd, 1);
 		}
 		break;
 	case DLP_MODE_16CH_8MIC_8LP:
 		if (is_playback) {
 			*ofs = 0;
-			*size = dlp_channels_to_bytes(prtd, 8);
+			*size = dlp_channels_to_bytes(drd, 8);
 		} else {
-			*ofs = dlp_channels_to_bytes(prtd, 8);
-			*size = dlp_channels_to_bytes(prtd, 8);
+			*ofs = dlp_channels_to_bytes(drd, 8);
+			*size = dlp_channels_to_bytes(drd, 8);
 		}
 		break;
 	default:
@@ -353,22 +261,22 @@
 	return ret;
 }
 
-static int dlp_mix_frame_buffer(struct dmaengine_dlp_runtime_data *prtd, void *buf)
+static int dlp_mix_frame_buffer(struct dlp_runtime_data *drd, void *buf)
 {
-	int sample_bytes = dlp_channels_to_bytes(prtd, 1);
+	int sample_bytes = dlp_channels_to_bytes(drd, 1);
 	int16_t *p16 = (int16_t *)buf, v16 = 0;
 	int32_t *p32 = (int32_t *)buf, v32 = 0;
 	int i = 0;
 
 	switch (sample_bytes) {
 	case 2:
-		for (i = 0; i < prtd->channels; i++)
-			v16 += (p16[i] / prtd->channels);
+		for (i = 0; i < drd->channels; i++)
+			v16 += (p16[i] / drd->channels);
 		p16[0] = v16;
 		break;
 	case 4:
-		for (i = 0; i < prtd->channels; i++)
-			v32 += (p32[i] / prtd->channels);
+		for (i = 0; i < drd->channels; i++)
+			v32 += (p32[i] / drd->channels);
 		p32[0] = v32;
 		break;
 	default:
@@ -378,17 +286,209 @@
 	return 0;
 }
 
-static int dmaengine_dlp_hw_params(struct snd_soc_component *component,
-				   struct snd_pcm_substream *substream,
-				   struct snd_pcm_hw_params *params)
+static inline int drd_init_from(struct dlp_runtime_data *drd, struct dlp_runtime_data *src)
 {
-	struct dmaengine_dlp *dlp = soc_component_to_dlp(component);
-	struct dmaengine_dlp_runtime_data *prtd = substream_to_prtd(substream);
-	struct dma_chan *chan = snd_dmaengine_dlp_get_chan(substream);
-	struct dma_slave_config slave_config;
+	memset(drd, 0x0, sizeof(*drd));
+
+	drd->parent = src->parent;
+	drd->buf_sz = src->buf_sz;
+	drd->period_sz = src->period_sz;
+	drd->frame_bytes = src->frame_bytes;
+	drd->channels = src->channels;
+	drd->stream = src->stream;
+
+	INIT_LIST_HEAD(&drd->node);
+	kref_init(&drd->refcount);
+
+	dev_dbg(drd->parent->dev, "%s: drd: 0x%px\n", __func__, drd);
+
+	return 0;
+}
+
+static void drd_avl_list_add(struct dlp *dlp, struct dlp_runtime_data *drd)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dlp->lock, flags);
+	list_add(&drd->node, &dlp->drd_avl_list);
+	dlp->drd_avl_count++;
+	spin_unlock_irqrestore(&dlp->lock, flags);
+}
+
+static struct dlp_runtime_data *drd_avl_list_get(struct dlp *dlp)
+{
+	struct dlp_runtime_data *drd = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dlp->lock, flags);
+	if (!list_empty(&dlp->drd_avl_list)) {
+		drd = list_first_entry(&dlp->drd_avl_list, struct dlp_runtime_data, node);
+		list_del(&drd->node);
+		dlp->drd_avl_count--;
+	}
+	spin_unlock_irqrestore(&dlp->lock, flags);
+
+	return drd;
+}
+
+static void drd_release(struct kref *ref)
+{
+	struct dlp_runtime_data *drd =
+		container_of(ref, struct dlp_runtime_data, refcount);
+
+	dev_dbg(drd->parent->dev, "%s: drd: 0x%px\n", __func__, drd);
+
+	drd_buf_free(drd);
+	/* move to available list */
+	drd_avl_list_add(drd->parent, drd);
+}
+
+static inline struct dlp_runtime_data *drd_get(struct dlp_runtime_data *drd)
+{
+	if (!drd)
+		return NULL;
+
+	return kref_get_unless_zero(&drd->refcount) ? drd : NULL;
+}
+
+static inline void drd_put(struct dlp_runtime_data *drd)
+{
+	if (!drd)
+		return;
+
+	kref_put(&drd->refcount, drd_release);
+}
+
+static void drd_rdy_list_add(struct dlp *dlp, struct dlp_runtime_data *drd)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dlp->lock, flags);
+	list_add(&drd->node, &dlp->drd_rdy_list);
+	spin_unlock_irqrestore(&dlp->lock, flags);
+}
+
+static struct dlp_runtime_data *drd_rdy_list_get(struct dlp *dlp)
+{
+	struct dlp_runtime_data *drd = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dlp->lock, flags);
+	if (!list_empty(&dlp->drd_rdy_list)) {
+		/* the newest one */
+		drd = list_first_entry(&dlp->drd_rdy_list, struct dlp_runtime_data, node);
+		list_del(&drd->node);
+	}
+	spin_unlock_irqrestore(&dlp->lock, flags);
+
+	return drd;
+}
+
+static bool drd_rdy_list_found(struct dlp *dlp, struct dlp_runtime_data *drd)
+{
+	struct dlp_runtime_data *_drd;
+	unsigned long flags;
+	bool found = false;
+
+	if (!drd)
+		return false;
+
+	spin_lock_irqsave(&dlp->lock, flags);
+	list_for_each_entry(_drd, &dlp->drd_rdy_list, node) {
+		if (_drd == drd) {
+			found = true;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&dlp->lock, flags);
+
+	return found;
+}
+
+static void drd_rdy_list_free(struct dlp *dlp)
+{
+	struct list_head drd_list;
+	struct dlp_runtime_data *drd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dlp->lock, flags);
+	list_replace_init(&dlp->drd_rdy_list, &drd_list);
+	spin_unlock_irqrestore(&dlp->lock, flags);
+
+	while (!list_empty(&drd_list)) {
+		drd = list_first_entry(&drd_list, struct dlp_runtime_data, node);
+		list_del(&drd->node);
+		drd_put(drd);
+	}
+}
+
+static void drd_ref_list_add(struct dlp *dlp, struct dlp_runtime_data *drd)
+{
+	unsigned long flags;
+
+	/* push valid playback into ref list */
+	spin_lock_irqsave(&dlp->lock, flags);
+	list_add_tail(&drd->node, &dlp->drd_ref_list);
+	spin_unlock_irqrestore(&dlp->lock, flags);
+}
+
+static struct dlp_runtime_data *drd_ref_list_first(struct dlp *dlp)
+{
+	struct dlp_runtime_data *drd = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dlp->lock, flags);
+	if (!list_empty(&dlp->drd_ref_list))
+		drd = list_first_entry(&dlp->drd_ref_list, struct dlp_runtime_data, node);
+	spin_unlock_irqrestore(&dlp->lock, flags);
+
+	return drd;
+}
+
+static struct dlp_runtime_data *drd_ref_list_del(struct dlp *dlp,
+						 struct dlp_runtime_data *drd)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dlp->lock, flags);
+	list_del(&drd->node);
+	spin_unlock_irqrestore(&dlp->lock, flags);
+
+	return drd;
+}
+
+static void drd_ref_list_free(struct dlp *dlp)
+{
+	struct list_head drd_list;
+	struct dlp_runtime_data *drd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dlp->lock, flags);
+	list_replace_init(&dlp->drd_ref_list, &drd_list);
+	spin_unlock_irqrestore(&dlp->lock, flags);
+
+	while (!list_empty(&drd_list)) {
+		drd = list_first_entry(&drd_list, struct dlp_runtime_data, node);
+		list_del(&drd->node);
+
+		if (!atomic_read(&drd->stop))
+			drd_rdy_list_add(dlp, drd);
+		else
+			drd_put(drd);
+	}
+}
+
+int dlp_hw_params(struct snd_soc_component *component,
+		  struct snd_pcm_substream *substream,
+		  struct snd_pcm_hw_params *params)
+{
+	struct dlp *dlp = soc_component_to_dlp(component);
+	struct dlp_runtime_data *drd = substream_to_drd(substream);
 	bool is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 	int ch_req = params_channels(params), ch_exp = 0;
-	int ret;
+
+	if (unlikely(!dlp || !drd))
+		return -EINVAL;
 
 	/* mode should match to channels */
 	if (!is_playback && !dlp_mode_channels_match(dlp, ch_req, &ch_exp)) {
@@ -398,292 +498,150 @@
 		return -EINVAL;
 	}
 
-	memset(&slave_config, 0, sizeof(slave_config));
-
-	ret = snd_dmaengine_pcm_prepare_slave_config(substream, params, &slave_config);
-	if (ret)
-		return ret;
-
-	ret = dmaengine_slave_config(chan, &slave_config);
-	if (ret)
-		return ret;
-
-	prtd->frame_bytes = snd_pcm_format_size(params_format(params),
-						params_channels(params));
-	prtd->period_sz = params_period_size(params);
-	prtd->buf_sz = params_buffer_size(params);
-	prtd->channels = params_channels(params);
+	drd->frame_bytes = snd_pcm_format_size(params_format(params),
+					       params_channels(params));
+	drd->period_sz = params_period_size(params);
+	drd->buf_sz = params_buffer_size(params);
+	drd->channels = params_channels(params);
 
 	if (is_playback)
-		prtd->buf_sz *= PBUF_CNT;
+		drd->buf_sz *= PBUF_CNT;
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(dlp_hw_params);
 
-static int
-dmaengine_pcm_set_runtime_hwparams(struct snd_soc_component *component,
-				   struct snd_pcm_substream *substream)
+int dlp_open(struct dlp *dlp, struct dlp_runtime_data *drd,
+	     struct snd_pcm_substream *substream)
 {
-	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
-	struct dmaengine_dlp *dlp = soc_component_to_dlp(component);
-	struct device *dma_dev = dmaengine_dma_dev(dlp, substream);
-	struct dma_chan *chan = dlp->chan[substream->stream];
-	struct snd_dmaengine_dai_dma_data *dma_data;
-	struct snd_pcm_hardware hw;
-
-	if (rtd->num_cpus > 1) {
-		dev_err(rtd->dev,
-			"%s doesn't support Multi CPU yet\n", __func__);
+	if (unlikely(!dlp || !drd))
 		return -EINVAL;
-	}
 
-	dma_data = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream);
+	drd->parent = dlp;
+	drd->stream = substream->stream;
 
-	memset(&hw, 0, sizeof(hw));
-	hw.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
-			SNDRV_PCM_INFO_INTERLEAVED;
-	hw.periods_min = 2;
-	hw.periods_max = UINT_MAX;
-	hw.period_bytes_min = 256;
-	hw.period_bytes_max = dma_get_max_seg_size(dma_dev);
-	hw.buffer_bytes_max = SIZE_MAX;
-	hw.fifo_size = dma_data->fifo_size;
-
-	/**
-	 * FIXME: Remove the return value check to align with the code
-	 * before adding snd_dmaengine_pcm_refine_runtime_hwparams
-	 * function.
-	 */
-	snd_dmaengine_pcm_refine_runtime_hwparams(substream,
-						  dma_data,
-						  &hw,
-						  chan);
-
-	return snd_soc_set_runtime_hwparams(substream, &hw);
-}
-
-static int dmaengine_dlp_open(struct snd_soc_component *component,
-			      struct snd_pcm_substream *substream)
-{
-	struct dmaengine_dlp *dlp = soc_component_to_dlp(component);
-	struct dma_chan *chan = dlp->chan[substream->stream];
-	struct dmaengine_dlp_runtime_data *prtd;
-	int ret;
-
-	if (!chan)
-		return -ENXIO;
-
-	ret = dmaengine_pcm_set_runtime_hwparams(component, substream);
-	if (ret)
-		return ret;
-
-	ret = snd_pcm_hw_constraint_integer(substream->runtime,
-					    SNDRV_PCM_HW_PARAM_PERIODS);
-	if (ret < 0)
-		return ret;
-
-	prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
-	if (!prtd)
-		return -ENOMEM;
-
-	dlp_info("PRTD-CREATE: 0x%px (%s)\n",
-		 prtd, substream->stream ? "C" : "P");
-
-	kref_init(&prtd->refcount);
-	prtd->parent = dlp;
-	prtd->stream = substream->stream;
-	prtd->dma_chan = chan;
-
-	substream->runtime->private_data = prtd;
+	substream->runtime->private_data = drd;
 
 	dlp_activate(dlp);
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(dlp_open);
 
-static void dmaengine_free_prtd(struct kref *ref)
+int dlp_close(struct dlp *dlp, struct dlp_runtime_data *drd,
+	      struct snd_pcm_substream *substream)
 {
-	struct dmaengine_dlp_runtime_data *prtd =
-		container_of(ref, struct dmaengine_dlp_runtime_data, refcount);
-
-	dlp_info("PRTD-FREE: 0x%px\n", prtd);
-
-	kfree(prtd->buf);
-	kfree(prtd);
-}
-
-static void free_ref_list(struct snd_soc_component *component)
-{
-	struct dmaengine_dlp *dlp = soc_component_to_dlp(component);
-	struct dmaengine_dlp_runtime_data *prtd, *_pt;
-
-	spin_lock(&dlp->lock);
-	list_for_each_entry_safe(prtd, _pt, &dlp->ref_list, node) {
-		list_del(&prtd->node);
-		kref_put(&prtd->refcount, dmaengine_free_prtd);
-	}
-	spin_unlock(&dlp->lock);
-}
-
-static int dmaengine_dlp_close(struct snd_soc_component *component,
-			       struct snd_pcm_substream *substream)
-{
-	struct dmaengine_dlp *dlp = soc_component_to_dlp(component);
-	struct dmaengine_dlp_runtime_data *prtd = substream_to_prtd(substream);
-
-	dmaengine_synchronize(prtd->dma_chan);
+	if (unlikely(!dlp || !drd))
+		return -EINVAL;
 
 	/*
-	 * kref put should be after hw_ptr updated when stop,
-	 * ops->trigger: SNDRV_PCM_TRIGGER_STOP -> ops->close
-	 * obviously, it is!
+	 * In case: open -> hw_params -> prepare -> close flow
+	 * should check and free all.
 	 */
-	kref_put(&prtd->refcount, dmaengine_free_prtd);
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		drd_put(dlp->drd_pb_shadow);
+		dlp->drd_pb_shadow = NULL;
+	} else {
+		drd_buf_free(drd);
+	}
 
 	dlp_deactivate(dlp);
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(dlp_close);
 
-static snd_pcm_uframes_t dmaengine_dlp_pointer(
-	struct snd_soc_component *component,
-	struct snd_pcm_substream *substream)
+void dlp_dma_complete(struct dlp *dlp, struct dlp_runtime_data *drd)
 {
-	struct dmaengine_dlp_runtime_data *prtd = substream_to_prtd(substream);
-	struct dma_tx_state state;
-	unsigned int buf_size;
-	unsigned int pos = 0;
-
-	dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state);
-	buf_size = snd_pcm_lib_buffer_bytes(substream);
-	if (state.residue > 0 && state.residue <= buf_size)
-		pos = buf_size - state.residue;
-
-	return dlp_bytes_to_frames(prtd, pos);
-}
-
-static void dmaengine_dlp_dma_complete(void *arg)
-{
-	struct snd_pcm_substream *substream = arg;
-	struct dmaengine_dlp_runtime_data *prtd = substream_to_prtd(substream);
-	struct dmaengine_dlp *dlp = prtd->parent;
-
-	if (!substream->runtime)
+	if (unlikely(!dlp || !drd))
 		return;
 
-	spin_lock(&dlp->lock);
-	prtd->period_elapsed++;
-	prtd->hw_ptr = prtd->period_elapsed * prtd->period_sz;
-	spin_unlock(&dlp->lock);
-	snd_pcm_period_elapsed(substream);
+	atomic64_inc(&drd->period_elapsed);
 }
+EXPORT_SYMBOL_GPL(dlp_dma_complete);
 
-static int dmaengine_dlp_prepare_and_submit(struct snd_pcm_substream *substream)
+int dlp_start(struct snd_soc_component *component,
+	      struct snd_pcm_substream *substream,
+	      struct device *dev,
+	      dma_pointer_f dma_pointer)
 {
-	struct dmaengine_dlp_runtime_data *prtd = substream_to_prtd(substream);
-	struct dma_chan *chan = prtd->dma_chan;
-	struct dma_async_tx_descriptor *desc;
-	enum dma_transfer_direction direction;
-	unsigned long flags = DMA_CTRL_ACK;
-
-	direction = snd_pcm_substream_to_dma_direction(substream);
-
-	if (!substream->runtime->no_period_wakeup)
-		flags |= DMA_PREP_INTERRUPT;
-
-	desc = dmaengine_prep_dma_cyclic(chan,
-		substream->runtime->dma_addr,
-		snd_pcm_lib_buffer_bytes(substream),
-		snd_pcm_lib_period_bytes(substream), direction, flags);
-
-	if (!desc)
-		return -ENOMEM;
-
-	desc->callback = dmaengine_dlp_dma_complete;
-	desc->callback_param = substream;
-	prtd->cookie = dmaengine_submit(desc);
-
-	return 0;
-}
-
-static int dmaengine_dlp_setup(struct snd_soc_component *component,
-			       struct snd_pcm_substream *substream)
-{
-	struct dmaengine_dlp *dlp = soc_component_to_dlp(component);
+	struct dlp *dlp = soc_component_to_dlp(component);
 	int bstream = SNDRV_PCM_STREAM_LAST - substream->stream;
 	struct snd_pcm_str *bro = &substream->pcm->streams[bstream];
 	struct snd_pcm_substream *bsubstream = bro->substream;
-	struct dmaengine_dlp_runtime_data *prtd = substream_to_prtd(substream);
-	struct dmaengine_dlp_runtime_data *brtd = substream_to_prtd(bsubstream);
-	struct dmaengine_dlp_runtime_data *pref = dlp->pref;
+	struct dlp_runtime_data *adrd = substream_to_drd(substream);
+	struct dlp_runtime_data *bdrd = substream_to_drd(bsubstream);
+	struct dlp_runtime_data *drd_ref;
 	bool is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
-	snd_pcm_uframes_t a = 0, b = 0, fifo_a = 0, fifo_b = 0;
+	uint64_t a = 0, b = 0;
+	snd_pcm_uframes_t fifo_a = 0, fifo_b = 0;
 	snd_pcm_sframes_t delta = 0;
+
+	if (unlikely(!dlp || !adrd || !dma_pointer))
+		return -EINVAL;
 
 	if (dlp->mode == DLP_MODE_DISABLED)
 		return -EINVAL;
 
-	fifo_a = dlp->config->get_fifo_count(dlp->dev, substream->stream);
-	a = dmaengine_dlp_pointer(component, substream);
+	fifo_a = dlp->config->get_fifo_count(dev, substream);
+	a = dma_pointer(component, substream) % adrd->period_sz;
 
 	if (bsubstream->runtime && snd_pcm_running(bsubstream)) {
-		fifo_b = dlp->config->get_fifo_count(dlp->dev, bstream);
-		b = dmaengine_dlp_pointer(component, bsubstream);
+		if (unlikely(!bdrd))
+			return -EINVAL;
 
-		spin_lock(&dlp->lock);
-		if (!pref) {
-			spin_unlock(&dlp->lock);
+		fifo_b = dlp->config->get_fifo_count(dev, bsubstream);
+		b = dma_pointer(component, bsubstream) % bdrd->period_sz;
+
+		drd_ref = drd_rdy_list_get(dlp);
+		if (unlikely(!drd_ref)) {
+			dev_err(dev, "Failed to get rdy drd\n");
 			return -EINVAL;
 		}
 
-		a = (prtd->period_elapsed * prtd->period_sz) + (a % prtd->period_sz);
-		b = (brtd->period_elapsed * brtd->period_sz) + (b % brtd->period_sz);
+		a += (atomic64_read(&adrd->period_elapsed) * adrd->period_sz);
+		b += (atomic64_read(&bdrd->period_elapsed) * bdrd->period_sz);
 
-		fifo_a = dlp_bytes_to_frames(prtd, fifo_a * 4);
-		fifo_b = dlp_bytes_to_frames(brtd, fifo_b * 4);
+		fifo_a = dlp_bytes_to_frames(adrd, fifo_a * 4);
+		fifo_b = dlp_bytes_to_frames(bdrd, fifo_b * 4);
 
 		delta = is_playback ? (a - fifo_a) - (b + fifo_b) : (b - fifo_b) - (a + fifo_a);
 
-		pref->hw_ptr_delta = delta;
-		kref_get(&pref->refcount);
-		/* push valid playback into ref list */
-		list_add_tail(&pref->node, &dlp->ref_list);
+		drd_ref->hw_ptr_delta = delta;
 
-		spin_unlock(&dlp->lock);
+		drd_ref_list_add(dlp, drd_ref);
 	}
 
 	if (is_playback)
-		dlp_info("START-P: DMA-P: %lu, DMA-C: %lu, FIFO-P: %lu, FIFO-C: %lu, DELTA: %ld\n",
-			 a, b, fifo_a, fifo_b, delta);
+		dev_dbg(dev, "START-P: DMA-P: %llu, DMA-C: %llu, FIFO-P: %lu, FIFO-C: %lu, DELTA: %ld\n",
+			a, b, fifo_a, fifo_b, delta);
 	else
-		dlp_info("START-C: DMA-P: %lu, DMA-C: %lu, FIFO-P: %lu, FIFO-C: %lu, DELTA: %ld\n",
-			 b, a, fifo_b, fifo_a, delta);
+		dev_dbg(dev, "START-C: DMA-P: %llu, DMA-C: %llu, FIFO-P: %lu, FIFO-C: %lu, DELTA: %ld\n",
+			b, a, fifo_b, fifo_a, delta);
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(dlp_start);
 
-static void dmaengine_dlp_release(struct snd_soc_component *component,
-				  struct snd_pcm_substream *substream)
+void dlp_stop(struct snd_soc_component *component,
+	      struct snd_pcm_substream *substream,
+	      dma_pointer_f dma_pointer)
 {
-	struct dmaengine_dlp *dlp = soc_component_to_dlp(component);
-	struct dmaengine_dlp_runtime_data *prtd = substream_to_prtd(substream);
-	struct dmaengine_dlp_runtime_data *pref = dlp->pref;
+	struct dlp *dlp = soc_component_to_dlp(component);
+	struct dlp_runtime_data *drd = substream_to_drd(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	snd_pcm_uframes_t appl_ptr, hw_ptr;
+	uint64_t appl_ptr, hw_ptr;
+
+	if (unlikely(!dlp || !drd || !runtime || !dma_pointer))
+		return;
 
 	if (dlp->mode == DLP_MODE_DISABLED)
 		return;
 
 	/* any data in FIFOs will be gone ,so don't care */
 	appl_ptr = READ_ONCE(runtime->control->appl_ptr);
-	hw_ptr = dmaengine_dlp_pointer(component, substream);
-	spin_lock(&dlp->lock);
-	hw_ptr = (prtd->period_elapsed * prtd->period_sz) + (hw_ptr % prtd->period_sz);
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		pref->hw_ptr = min(hw_ptr, appl_ptr);
-	prtd->period_elapsed = 0;
-	prtd->hw_ptr = 0;
-	spin_unlock(&dlp->lock);
+	hw_ptr = dma_pointer(component, substream) % drd->period_sz;
+	hw_ptr += (atomic64_read(&drd->period_elapsed) * drd->period_sz);
 
 	/*
 	 * playback:
@@ -694,187 +652,98 @@
 	 * anyway, we should use the smaller one, obviously, it's hw_ptr.
 	 */
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		spin_lock(&dlp->pref_lock);
-		kref_put(&pref->refcount, dmaengine_free_prtd);
-		dlp->pref = NULL;
-		spin_unlock(&dlp->pref_lock);
-		dlp_info("STOP-P: applptr: %lu, hwptr: %lu\n", appl_ptr, hw_ptr);
+		if (dlp->drd_pb_shadow) {
+			dlp->drd_pb_shadow->hw_ptr = min(hw_ptr, appl_ptr);
+			atomic_set(&dlp->drd_pb_shadow->stop, 1);
+		}
+		drd_rdy_list_free(dlp);
 	} else {
 		/* free residue playback ref list for capture when stop */
-		free_ref_list(component);
-		dlp_info("STOP-C: applptr: %lu, hwptr: %lu\n", appl_ptr, hw_ptr);
-	}
-}
-
-static int dmaengine_dlp_trigger(struct snd_soc_component *component,
-				 struct snd_pcm_substream *substream, int cmd)
-{
-	struct dmaengine_dlp_runtime_data *prtd = substream_to_prtd(substream);
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	int ret;
-
-	switch (cmd) {
-	case SNDRV_PCM_TRIGGER_START:
-		ret = dmaengine_dlp_prepare_and_submit(substream);
-		if (ret)
-			return ret;
-		dma_async_issue_pending(prtd->dma_chan);
-		dmaengine_dlp_setup(component, substream);
-		break;
-	case SNDRV_PCM_TRIGGER_RESUME:
-	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		dmaengine_resume(prtd->dma_chan);
-		break;
-	case SNDRV_PCM_TRIGGER_SUSPEND:
-		if (runtime->info & SNDRV_PCM_INFO_PAUSE) {
-			dmaengine_pause(prtd->dma_chan);
-		} else {
-			dmaengine_dlp_release(component, substream);
-			dmaengine_terminate_async(prtd->dma_chan);
-		}
-		break;
-	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		dmaengine_pause(prtd->dma_chan);
-		break;
-	case SNDRV_PCM_TRIGGER_STOP:
-		dmaengine_dlp_release(component, substream);
-		dmaengine_terminate_async(prtd->dma_chan);
-		break;
-	default:
-		return -EINVAL;
+		drd_ref_list_free(dlp);
 	}
 
-	return 0;
+	atomic64_set(&drd->period_elapsed, 0);
+
+	dev_dbg(dlp->dev, "STOP-%s: applptr: %llu, hwptr: %llu\n",
+		substream->stream ? "C" : "P", appl_ptr, hw_ptr);
 }
-
-static int dmaengine_dlp_new(struct snd_soc_component *component,
-			     struct snd_soc_pcm_runtime *rtd)
-{
-	struct dmaengine_dlp *dlp = soc_component_to_dlp(component);
-	struct snd_pcm_substream *substream;
-	size_t prealloc_buffer_size;
-	size_t max_buffer_size;
-	unsigned int i;
-
-	prealloc_buffer_size = prealloc_buffer_size_kbytes * 1024;
-	max_buffer_size = SIZE_MAX;
-
-	for_each_pcm_streams(i) {
-		substream = rtd->pcm->streams[i].substream;
-		if (!substream)
-			continue;
-
-		if (!dlp->chan[i]) {
-			dev_err(component->dev,
-				"Missing dma channel for stream: %d\n", i);
-			return -EINVAL;
-		}
-
-		snd_pcm_set_managed_buffer(substream,
-				SNDRV_DMA_TYPE_DEV_IRAM,
-				dmaengine_dma_dev(dlp, substream),
-				prealloc_buffer_size,
-				max_buffer_size);
-
-		if (rtd->pcm->streams[i].pcm->name[0] == '\0') {
-			strscpy_pad(rtd->pcm->streams[i].pcm->name,
-				    rtd->pcm->streams[i].pcm->id,
-				    sizeof(rtd->pcm->streams[i].pcm->name));
-		}
-	}
-
-	return 0;
-}
-
-static struct dmaengine_dlp_runtime_data *get_ref(struct snd_soc_component *component)
-{
-	struct dmaengine_dlp *dlp = soc_component_to_dlp(component);
-	struct dmaengine_dlp_runtime_data *pref = NULL;
-
-	spin_lock(&dlp->lock);
-	if (!list_empty(&dlp->ref_list)) {
-		pref = list_first_entry(&dlp->ref_list, struct dmaengine_dlp_runtime_data, node);
-		list_del(&pref->node);
-	}
-	spin_unlock(&dlp->lock);
-
-	return pref;
-}
+EXPORT_SYMBOL_GPL(dlp_stop);
 
 static int process_capture(struct snd_soc_component *component,
 			   struct snd_pcm_substream *substream,
 			   unsigned long hwoff,
 			   void __user *buf, unsigned long bytes)
 {
-	struct dmaengine_dlp *dlp = soc_component_to_dlp(component);
+	struct dlp *dlp = soc_component_to_dlp(component);
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct dmaengine_dlp_runtime_data *prtd = substream_to_prtd(substream);
-	struct dmaengine_dlp_runtime_data *pref = NULL;
-	void *dma_ptr = runtime->dma_area + hwoff;
-	snd_pcm_sframes_t frames = dlp_bytes_to_frames(prtd, bytes);
+	struct dlp_runtime_data *drd = substream_to_drd(substream);
+	struct dlp_runtime_data *drd_ref = NULL;
+	snd_pcm_sframes_t frames = 0;
 	snd_pcm_sframes_t frames_consumed = 0, frames_residue = 0, frames_tmp = 0;
 	snd_pcm_sframes_t ofs = 0;
 	snd_pcm_uframes_t appl_ptr;
-	char *cbuf = prtd->buf, *pbuf = NULL;
 	int ofs_cap, ofs_play, size_cap, size_play;
 	int i = 0, j = 0, ret = 0;
 	bool free_ref = false, mix = false;
+	char *cbuf = NULL, *pbuf = NULL;
+	void *dma_ptr;
+
+	if (unlikely(!drd || !runtime || !buf))
+		return -EINVAL;
+
+	frames = dlp_bytes_to_frames(drd, bytes);
+	dma_ptr = runtime->dma_area + hwoff;
+	cbuf = drd->buf;
 
 	appl_ptr = READ_ONCE(runtime->control->appl_ptr);
 
 	memcpy(cbuf, dma_ptr, bytes);
 #ifdef DLP_DBG
 	/* DBG: mark STUB in ch-REC for trace each read */
-	memset(cbuf, 0x22, dlp_channels_to_bytes(prtd, 1));
+	memset(cbuf, 0x22, dlp_channels_to_bytes(drd, 1));
 #endif
-	ret = dlp_get_offset_size(prtd, dlp->mode, &ofs_cap, &size_cap, NULL);
+	ret = dlp_get_offset_size(drd, dlp->mode, &ofs_cap, &size_cap, NULL);
 	if (ret) {
-		dlp_info("fail to get dlp cap offset\n");
+		dev_err(dlp->dev, "Failed to get dlp cap offset\n");
 		return -EINVAL;
 	}
 
 	/* clear channel-LP_CHN */
 	for (i = 0; i < frames; i++) {
-		cbuf = prtd->buf + dlp_frames_to_bytes(prtd, i) + ofs_cap;
+		cbuf = drd->buf + dlp_frames_to_bytes(drd, i) + ofs_cap;
 		memset(cbuf, 0x0, size_cap);
 	}
 
 start:
-	if (!prtd->ref)
-		prtd->ref = get_ref(component);
-	pref = prtd->ref;
-
-	/* do nothing if play stop */
-	if (!pref)
+	drd_ref = drd_get(drd_ref_list_first(dlp));
+	if (!drd_ref)
 		return 0;
 
-	ret = dlp_get_offset_size(pref, dlp->mode, &ofs_play, &size_play, &mix);
+	ret = dlp_get_offset_size(drd_ref, dlp->mode, &ofs_play, &size_play, &mix);
 	if (ret) {
-		dlp_info("fail to get dlp play offset\n");
-		return 0;
+		dev_err(dlp->dev, "Failed to get dlp play offset\n");
+		goto _drd_put;
 	}
 
-	ofs = appl_ptr + pref->hw_ptr_delta;
+	ofs = appl_ptr + drd_ref->hw_ptr_delta;
 
 	/*
-	 * if playback stop, kref_put ref, and we can check this to
-	 * know if playback stopped, then free prtd->ref if data consumed.
-	 *
+	 * if playback stop, process the data tail and then
+	 * free drd_ref if data consumed.
 	 */
-	if (kref_read(&pref->refcount) == 1) {
-		if (ofs >= pref->hw_ptr) {
-			kref_put(&pref->refcount, dmaengine_free_prtd);
-			prtd->ref = NULL;
-			return 0;
-		} else if ((ofs + frames) > pref->hw_ptr) {
-			dlp_info("applptr: %8lu, ofs': %7ld, refhwptr: %lu, frames: %lu (*)\n",
-				 appl_ptr, ofs, pref->hw_ptr, frames);
+	if (atomic_read(&drd_ref->stop)) {
+		if (ofs >= drd_ref->hw_ptr) {
+			drd_put(drd_ref_list_del(dlp, drd_ref));
+			goto _drd_put;
+		} else if ((ofs + frames) > drd_ref->hw_ptr) {
+			dev_dbg(dlp->dev, "applptr: %8lu, ofs': %7ld, refhwptr: %lld, frames: %ld (*)\n",
+				appl_ptr, ofs, drd_ref->hw_ptr, frames);
 			/*
 			 * should ignore the data that after play stop
 			 * and care about if the next ref start in the
 			 * same window
 			 */
-			frames_tmp = pref->hw_ptr - ofs;
+			frames_tmp = drd_ref->hw_ptr - ofs;
 			frames_residue = frames - frames_tmp;
 			frames = frames_tmp;
 			free_ref = true;
@@ -891,27 +760,29 @@
 	 *
 	 */
 	if ((ofs + frames) <= 0)
-		return 0;
+		goto _drd_put;
 
 	/* skip if ofs < 0 and fixup ofs */
 	j = 0;
 	if (ofs < 0) {
-		dlp_info("applptr: %8lu, ofs: %8ld, frames: %lu (*)\n",
-			 appl_ptr, ofs, frames);
+		dev_dbg(dlp->dev, "applptr: %8lu, ofs: %8ld, frames: %ld (*)\n",
+			appl_ptr, ofs, frames);
 		j = -ofs;
 		frames += ofs;
 		ofs = 0;
+		appl_ptr += j;
 	}
 
-	ofs %= pref->buf_sz;
+	ofs %= drd_ref->buf_sz;
 
-	dlp_info("applptr: %8lu, ofs: %8ld, frames: %lu\n", appl_ptr, ofs, frames);
+	dev_dbg(dlp->dev, "applptr: %8lu, ofs: %8ld, frames: %5ld, refc: %u\n",
+		appl_ptr, ofs, frames, kref_read(&drd_ref->refcount));
 
 	for (i = 0; i < frames; i++, j++) {
-		cbuf = prtd->buf + dlp_frames_to_bytes(prtd, j + frames_consumed) + ofs_cap;
-		pbuf = pref->buf + dlp_frames_to_bytes(pref, ((i + ofs) % pref->buf_sz)) + ofs_play;
+		cbuf = drd->buf + dlp_frames_to_bytes(drd, j + frames_consumed) + ofs_cap;
+		pbuf = drd_ref->buf + dlp_frames_to_bytes(drd_ref, ((i + ofs) % drd_ref->buf_sz)) + ofs_play;
 		if (mix)
-			dlp_mix_frame_buffer(pref, pbuf);
+			dlp_mix_frame_buffer(drd_ref, pbuf);
 		memcpy(cbuf, pbuf, size_cap);
 	}
 
@@ -919,8 +790,9 @@
 	frames_consumed += frames;
 
 	if (free_ref) {
-		kref_put(&pref->refcount, dmaengine_free_prtd);
-		prtd->ref = NULL;
+		drd_put(drd_ref_list_del(dlp, drd_ref));
+		drd_put(drd_ref);
+		drd_ref = NULL;
 		free_ref = false;
 		if (frames_residue) {
 			frames = frames_residue;
@@ -928,6 +800,10 @@
 			goto start;
 		}
 	}
+
+_drd_put:
+	drd_put(drd_ref);
+	drd_ref = NULL;
 
 	return 0;
 }
@@ -937,40 +813,37 @@
 			    unsigned long hwoff,
 			    void __user *buf, unsigned long bytes)
 {
-	struct dmaengine_dlp *dlp = soc_component_to_dlp(component);
-	struct dmaengine_dlp_runtime_data *pref;
+	struct dlp *dlp = soc_component_to_dlp(component);
+	struct dlp_runtime_data *drd;
 	char *pbuf;
 	int ret = 0;
 
-	spin_lock(&dlp->pref_lock);
-	pref = dlp->pref;
-	if (!pref) {
-		ret = -EFAULT;
-		goto err_unlock;
-	}
+	drd = drd_get(dlp->drd_pb_shadow);
+	if (!drd)
+		return 0;
 
-	pbuf = pref->buf + pref->buf_ofs;
+	pbuf = drd->buf + drd->buf_ofs;
 
 	if (copy_from_user(pbuf, buf, bytes)) {
 		ret = -EFAULT;
-		goto err_unlock;
+		goto err_put;
 	}
 
-	pref->buf_ofs += bytes;
-	pref->buf_ofs %= dlp_frames_to_bytes(pref, pref->buf_sz);
+	drd->buf_ofs += bytes;
+	drd->buf_ofs %= dlp_frames_to_bytes(drd, drd->buf_sz);
 
-err_unlock:
-	spin_unlock(&dlp->pref_lock);
+err_put:
+	drd_put(drd);
 
 	return ret;
 }
 
-static int dmaengine_dlp_process(struct snd_soc_component *component,
-				 struct snd_pcm_substream *substream,
-				 unsigned long hwoff,
-				 void __user *buf, unsigned long bytes)
+static int dlp_process(struct snd_soc_component *component,
+		       struct snd_pcm_substream *substream,
+		       unsigned long hwoff,
+		       void __user *buf, unsigned long bytes)
 {
-	struct dmaengine_dlp *dlp = soc_component_to_dlp(component);
+	struct dlp *dlp = soc_component_to_dlp(component);
 	int ret = 0;
 
 	if (dlp->mode == DLP_MODE_DISABLED)
@@ -984,25 +857,30 @@
 	return ret;
 }
 
-static int dmaengine_dlp_copy_user(struct snd_soc_component *component,
-				   struct snd_pcm_substream *substream,
-				   int channel, unsigned long hwoff,
-				   void __user *buf, unsigned long bytes)
+int dlp_copy_user(struct snd_soc_component *component,
+		  struct snd_pcm_substream *substream,
+		  int channel, unsigned long hwoff,
+		  void __user *buf, unsigned long bytes)
 {
-	struct dmaengine_dlp_runtime_data *prtd = substream_to_prtd(substream);
+	struct dlp_runtime_data *drd = substream_to_drd(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	bool is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
-	void *dma_ptr = runtime->dma_area + hwoff +
-			channel * (runtime->dma_bytes / runtime->channels);
+	void *dma_ptr;
 	int ret;
+
+	if (unlikely(!drd || !runtime || !buf))
+		return -EINVAL;
+
+	dma_ptr = runtime->dma_area + hwoff +
+		  channel * (runtime->dma_bytes / runtime->channels);
 
 	if (is_playback)
 		if (copy_from_user(dma_ptr, buf, bytes))
 			return -EFAULT;
 
-	ret = dmaengine_dlp_process(component, substream, hwoff, buf, bytes);
+	ret = dlp_process(component, substream, hwoff, buf, bytes);
 	if (!ret)
-		dma_ptr = prtd->buf;
+		dma_ptr = drd->buf;
 
 	if (!is_playback)
 		if (copy_to_user(buf, dma_ptr, bytes))
@@ -1010,30 +888,33 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(dlp_copy_user);
 
 static SOC_ENUM_SINGLE_EXT_DECL(dlp_mode, dlp_text);
 
-static int dmaengine_dlp_mode_get(struct snd_kcontrol *kcontrol,
-				  struct snd_ctl_elem_value *ucontrol)
+static int dlp_mode_get(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
-	struct dmaengine_dlp *dlp = soc_component_to_dlp(component);
+	struct dlp *dlp = soc_component_to_dlp(component);
 
 	ucontrol->value.enumerated.item[0] = dlp->mode;
 
 	return 0;
 }
 
-static int dmaengine_dlp_mode_put(struct snd_kcontrol *kcontrol,
-				  struct snd_ctl_elem_value *ucontrol)
+static int dlp_mode_put(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
-	struct dmaengine_dlp *dlp = soc_component_to_dlp(component);
+	struct dlp *dlp = soc_component_to_dlp(component);
 	unsigned int mode = ucontrol->value.enumerated.item[0];
 
 	/* MUST: do not update mode while stream is running */
-	if (snd_soc_component_active(component))
+	if (atomic_read(&dlp->active)) {
+		dev_err(dlp->dev, "Should set this mode before pcm open\n");
 		return -EPERM;
+	}
 
 	if (mode == dlp->mode)
 		return 0;
@@ -1043,207 +924,141 @@
 	return 1;
 }
 
-static const struct snd_kcontrol_new dmaengine_dlp_controls[] = {
+static const struct snd_kcontrol_new dlp_controls[] = {
 	SOC_ENUM_EXT("Software Digital Loopback Mode", dlp_mode,
-		     dmaengine_dlp_mode_get,
-		     dmaengine_dlp_mode_put),
+		     dlp_mode_get, dlp_mode_put),
 };
 
-static int dmaengine_dlp_prepare(struct snd_soc_component *component,
-				  struct snd_pcm_substream *substream)
+int dlp_prepare(struct snd_soc_component *component,
+		struct snd_pcm_substream *substream)
 {
-	struct dmaengine_dlp *dlp = soc_component_to_dlp(component);
-	struct dmaengine_dlp_runtime_data *prtd = substream_to_prtd(substream);
-	struct dmaengine_dlp_runtime_data *pref = NULL;
-	int buf_bytes = dlp_frames_to_bytes(prtd, prtd->buf_sz);
-
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		pref = kmemdup(prtd, sizeof(*prtd), GFP_KERNEL);
-		if (!pref)
-			return -ENOMEM;
-
-		kref_init(&pref->refcount);
-		pref->buf_ofs = 0;
-		pref->buf = kzalloc(buf_bytes, GFP_KERNEL);
-		if (!pref->buf) {
-			kfree(pref);
-			return -ENOMEM;
-		}
-
-		spin_lock(&dlp->pref_lock);
-		dlp->pref = pref;
-		spin_unlock(&dlp->pref_lock);
-		dlp_info("PREF-CREATE: 0x%px\n", pref);
-	} else {
-		prtd->buf = kzalloc(buf_bytes, GFP_KERNEL);
-		if (!prtd->buf)
-			return -ENOMEM;
-	}
-
-	return 0;
-}
-static const struct snd_soc_component_driver dmaengine_dlp_component = {
-	.name		= SND_DMAENGINE_DLP_DRV_NAME,
-	.probe_order	= SND_SOC_COMP_ORDER_LATE,
-	.open		= dmaengine_dlp_open,
-	.close		= dmaengine_dlp_close,
-	.hw_params	= dmaengine_dlp_hw_params,
-	.prepare	= dmaengine_dlp_prepare,
-	.trigger	= dmaengine_dlp_trigger,
-	.pointer	= dmaengine_dlp_pointer,
-	.copy_user	= dmaengine_dlp_copy_user,
-	.pcm_construct	= dmaengine_dlp_new,
-	.controls	= dmaengine_dlp_controls,
-	.num_controls	= ARRAY_SIZE(dmaengine_dlp_controls),
-};
-
-static const char * const dmaengine_pcm_dma_channel_names[] = {
-	[SNDRV_PCM_STREAM_PLAYBACK] = "tx",
-	[SNDRV_PCM_STREAM_CAPTURE] = "rx",
-};
-
-static int dmaengine_pcm_request_chan_of(struct dmaengine_dlp *dlp,
-	struct device *dev, const struct snd_dmaengine_pcm_config *config)
-{
-	unsigned int i;
-	const char *name;
-	struct dma_chan *chan;
-
-	for_each_pcm_streams(i) {
-		name = dmaengine_pcm_dma_channel_names[i];
-		chan = dma_request_chan(dev, name);
-		if (IS_ERR(chan)) {
-			/*
-			 * Only report probe deferral errors, channels
-			 * might not be present for devices that
-			 * support only TX or only RX.
-			 */
-			if (PTR_ERR(chan) == -EPROBE_DEFER)
-				return -EPROBE_DEFER;
-			dlp->chan[i] = NULL;
-		} else {
-			dlp->chan[i] = chan;
-		}
-	}
-
-	return 0;
-}
-
-static void dmaengine_pcm_release_chan(struct dmaengine_dlp *dlp)
-{
-	unsigned int i;
-
-	for_each_pcm_streams(i) {
-		if (!dlp->chan[i])
-			continue;
-		dma_release_channel(dlp->chan[i]);
-	}
-}
-
-/**
- * snd_dmaengine_dlp_register - Register a dmaengine based DLP device
- * @dev: The parent device for the DLP device
- * @config: Platform specific DLP configuration
- */
-static int snd_dmaengine_dlp_register(struct device *dev,
-	const struct snd_dlp_config *config)
-{
-	const struct snd_soc_component_driver *driver;
-	struct dmaengine_dlp *dlp;
+	struct dlp *dlp = soc_component_to_dlp(component);
+	struct dlp_runtime_data *drd = substream_to_drd(substream);
+	struct dlp_runtime_data *drd_new = NULL;
+	int buf_bytes, last_buf_bytes;
 	int ret;
 
-	dlp = kzalloc(sizeof(*dlp), GFP_KERNEL);
-	if (!dlp)
-		return -ENOMEM;
+	if (unlikely(!dlp || !drd))
+		return -EINVAL;
+
+	if (dlp->mode == DLP_MODE_DISABLED)
+		return 0;
+
+	buf_bytes = dlp_frames_to_bytes(drd, drd->buf_sz);
+	last_buf_bytes = dlp_frames_to_bytes(drd, drd->last_buf_sz);
+
+	if (substream->runtime->status->state == SNDRV_PCM_STATE_XRUN)
+		dev_dbg(dlp->dev, "stream[%d]: prepare from XRUN\n",
+			substream->stream);
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		dev_dbg(dlp->dev, "avl count: %d\n", dlp->drd_avl_count);
+		if (snd_BUG_ON(!dlp->drd_avl_count))
+			return -EINVAL;
+
+		/*
+		 * There might be multiple calls hw_params -> prepare
+		 * before start stream, so, should check buf size status
+		 * to determine whether to re-create buf or do nothing.
+		 */
+		if (drd_rdy_list_found(dlp, dlp->drd_pb_shadow)) {
+			if (buf_bytes == last_buf_bytes)
+				return 0;
+
+			drd_rdy_list_free(dlp);
+		}
+
+		/* release the old one, re-create for new params */
+		drd_put(dlp->drd_pb_shadow);
+		dlp->drd_pb_shadow = NULL;
+
+		drd_new = drd_avl_list_get(dlp);
+		if (!drd_new)
+			return -ENOMEM;
+
+		drd_init_from(drd_new, drd);
+
+		ret = drd_buf_alloc(drd_new, buf_bytes);
+		if (ret)
+			return -ENOMEM;
+
+		if (snd_BUG_ON(!drd_get(drd_new)))
+			return -EINVAL;
+
+		drd_rdy_list_add(dlp, drd_new);
+
+		dlp->drd_pb_shadow = drd_new;
+	} else {
+		/*
+		 * There might be multiple calls hw_params -> prepare
+		 * before start stream, so, should check buf size status
+		 * to determine whether to re-create buf or do nothing.
+		 */
+		if (drd->buf && buf_bytes == last_buf_bytes)
+			return 0;
+
+		drd_buf_free(drd);
+
+		ret = drd_buf_alloc(drd, buf_bytes);
+		if (ret)
+			return ret;
+	}
+
+	/* update last after all done success */
+	drd->last_buf_sz = drd->buf_sz;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dlp_prepare);
+
+int dlp_probe(struct snd_soc_component *component)
+{
+	snd_soc_add_component_controls(component, dlp_controls,
+				       ARRAY_SIZE(dlp_controls));
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dlp_probe);
+
+int dlp_register(struct dlp *dlp, struct device *dev,
+		 const struct snd_soc_component_driver *driver,
+		 const struct snd_dlp_config *config)
+{
+	struct dlp_runtime_data *drd;
+	int ret = 0, i = 0;
+
+	if (unlikely(!dlp || !dev || !driver || !config))
+		return -EINVAL;
 
 	dlp->dev = dev;
 	dlp->config = config;
 
-	INIT_LIST_HEAD(&dlp->ref_list);
-	spin_lock_init(&dlp->lock);
-	spin_lock_init(&dlp->pref_lock);
-
 #ifdef CONFIG_DEBUG_FS
 	dlp->component.debugfs_prefix = "dma";
 #endif
-	ret = dmaengine_pcm_request_chan_of(dlp, dev, NULL);
-	if (ret)
-		goto err_free_dma;
+	INIT_LIST_HEAD(&dlp->drd_avl_list);
+	INIT_LIST_HEAD(&dlp->drd_rdy_list);
+	INIT_LIST_HEAD(&dlp->drd_ref_list);
 
-	driver = &dmaengine_dlp_component;
+	dlp->drd_avl_count = ARRAY_SIZE(dlp->drds);
+
+	for (i = 0; i < dlp->drd_avl_count; i++) {
+		drd = &dlp->drds[i];
+		list_add_tail(&drd->node, &dlp->drd_avl_list);
+	}
+
+	spin_lock_init(&dlp->lock);
+	atomic_set(&dlp->active, 0);
 
 	ret = snd_soc_component_initialize(&dlp->component, driver, dev);
 	if (ret)
-		goto err_free_dma;
+		return ret;
 
 	ret = snd_soc_add_component(&dlp->component, NULL, 0);
-	if (ret)
-		goto err_free_dma;
-
-	return 0;
-
-err_free_dma:
-	dmaengine_pcm_release_chan(dlp);
-	kfree(dlp);
-	return ret;
-}
-
-/**
- * snd_dmaengine_dlp_unregister - Removes a dmaengine based DLP device
- * @dev: Parent device the DLP was register with
- *
- * Removes a dmaengine based DLP device previously registered with
- * snd_dmaengine_dlp_register.
- */
-static void snd_dmaengine_dlp_unregister(struct device *dev)
-{
-	struct snd_soc_component *component;
-	struct dmaengine_dlp *dlp;
-
-	component = snd_soc_lookup_component(dev, SND_DMAENGINE_DLP_DRV_NAME);
-	if (!component)
-		return;
-
-	dlp = soc_component_to_dlp(component);
-
-	snd_soc_unregister_component_by_driver(dev, component->driver);
-	dmaengine_pcm_release_chan(dlp);
-	kfree(dlp);
-}
-
-static void devm_dmaengine_dlp_release(struct device *dev, void *res)
-{
-	snd_dmaengine_dlp_unregister(*(struct device **)res);
-}
-
-/**
- * devm_snd_dmaengine_dlp_register - resource managed dmaengine DLP registration
- * @dev: The parent device for the DLP device
- * @config: Platform specific DLP configuration
- *
- * Register a dmaengine based DLP device with automatic unregistration when the
- * device is unregistered.
- */
-int devm_snd_dmaengine_dlp_register(struct device *dev,
-	const struct snd_dlp_config *config)
-{
-	struct device **ptr;
-	int ret;
-
-	ptr = devres_alloc(devm_dmaengine_dlp_release, sizeof(*ptr), GFP_KERNEL);
-	if (!ptr)
-		return -ENOMEM;
-
-	ret = snd_dmaengine_dlp_register(dev, config);
-	if (ret == 0) {
-		*ptr = dev;
-		devres_add(dev, ptr);
-	} else {
-		devres_free(ptr);
-	}
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(devm_snd_dmaengine_dlp_register);
+EXPORT_SYMBOL_GPL(dlp_register);
 
+MODULE_DESCRIPTION("Rockchip Digital Loopback Core Driver");
+MODULE_AUTHOR("Sugar Zhang <sugar.zhang@rock-chips.com>");
 MODULE_LICENSE("GPL");
diff --git a/kernel/sound/soc/rockchip/rockchip_dlp.h b/kernel/sound/soc/rockchip/rockchip_dlp.h
index 6235482..e3c6d24 100644
--- a/kernel/sound/soc/rockchip/rockchip_dlp.h
+++ b/kernel/sound/soc/rockchip/rockchip_dlp.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
 /*
  * Rockchip DLP (Digital Loopback) driver
  *
@@ -10,19 +10,125 @@
 #ifndef _ROCKCHIP_DLP_H
 #define _ROCKCHIP_DLP_H
 
-struct snd_dlp_config {
-	int (*get_fifo_count)(struct device *dev, int stream);
+#include "rockchip_dlp_pcm.h"
+
+#define DLP_MAX_DRDS	8
+
+/* MUST: enum dlp_mode should be match to dlp_text */
+enum dlp_mode {
+	DLP_MODE_DISABLED,
+	DLP_MODE_2CH_1LP_1MIC,		/* replace cap-ch-0   with play-ch-0 */
+	DLP_MODE_2CH_1MIC_1LP,		/* replace cap-ch-1   with play-ch-1 */
+	DLP_MODE_2CH_1MIC_1LP_MIX,	/* replace cap-ch-1   with play-ch-all-mix */
+	DLP_MODE_2CH_2LP,		/* replace cap-ch-0~1 with play-ch-0~1 */
+	DLP_MODE_4CH_2MIC_2LP,		/* replace cap-ch-2~3 with play-ch-0~1 */
+	DLP_MODE_4CH_2MIC_1LP_MIX,	/* replace cap-ch-3   with play-ch-all-mix */
+	DLP_MODE_4CH_4LP,		/* replace cap-ch-0~3 with play-ch-0~3 */
+	DLP_MODE_6CH_4MIC_2LP,		/* replace cap-ch-4~5 with play-ch-0~1 */
+	DLP_MODE_6CH_4MIC_1LP_MIX,	/* replace cap-ch-4   with play-ch-all-mix */
+	DLP_MODE_6CH_6LP,		/* replace cap-ch-0~5 with play-ch-0~5 */
+	DLP_MODE_8CH_6MIC_2LP,		/* replace cap-ch-6~7 with play-ch-0~1 */
+	DLP_MODE_8CH_6MIC_1LP_MIX,	/* replace cap-ch-6   with play-ch-all-mix */
+	DLP_MODE_8CH_8LP,		/* replace cap-ch-0~7 with play-ch-0~7 */
+	DLP_MODE_10CH_8MIC_2LP,		/* replace cap-ch-8~9 with play-ch-0~1 */
+	DLP_MODE_10CH_8MIC_1LP_MIX,	/* replace cap-ch-8   with play-ch-all-mix */
+	DLP_MODE_16CH_8MIC_8LP,		/* replace cap-ch-8~f with play-ch-8~f */
 };
 
-#if IS_REACHABLE(CONFIG_SND_SOC_ROCKCHIP_DLP)
-int devm_snd_dmaengine_dlp_register(struct device *dev,
-	const struct snd_dlp_config *config);
-#else
-static inline int devm_snd_dmaengine_dlp_register(struct device *dev,
-	const struct snd_dlp_config *config)
+struct dlp;
+
+struct dlp_runtime_data {
+	struct dlp *parent;
+	struct kref refcount;
+	struct list_head node;
+	char *buf;
+	snd_pcm_uframes_t buf_sz;
+	snd_pcm_uframes_t last_buf_sz;
+	snd_pcm_uframes_t period_sz;
+	int64_t hw_ptr;
+	int64_t hw_ptr_delta; /* play-ptr - cap-ptr */
+	atomic64_t period_elapsed;
+	atomic_t stop;
+	unsigned int frame_bytes;
+	unsigned int channels;
+	unsigned int buf_ofs;
+	int stream;
+};
+
+struct dlp {
+	struct device *dev;
+	struct list_head drd_avl_list;
+	struct list_head drd_rdy_list;
+	struct list_head drd_ref_list;
+	struct dlp_runtime_data drds[DLP_MAX_DRDS];
+	struct dlp_runtime_data *drd_pb_shadow;
+	struct snd_soc_component component;
+	const struct snd_dlp_config *config;
+	enum dlp_mode mode;
+	int drd_avl_count;
+	atomic_t active;
+	spinlock_t lock;
+};
+
+typedef snd_pcm_uframes_t (*dma_pointer_f)(struct snd_soc_component *component,
+					   struct snd_pcm_substream *substream);
+
+static inline struct dlp *soc_component_to_dlp(struct snd_soc_component *p)
 {
-	return -ENOSYS;
+	return container_of(p, struct dlp, component);
 }
-#endif
+
+static inline struct dlp_runtime_data *substream_to_drd(
+	const struct snd_pcm_substream *substream)
+{
+	if (!substream->runtime)
+		return NULL;
+
+	return substream->runtime->private_data;
+}
+
+static inline ssize_t dlp_channels_to_bytes(struct dlp_runtime_data *drd,
+					    int channels)
+{
+	return (drd->frame_bytes / drd->channels) * channels;
+}
+
+static inline ssize_t dlp_frames_to_bytes(struct dlp_runtime_data *drd,
+					  snd_pcm_sframes_t size)
+{
+	return size * drd->frame_bytes;
+}
+
+static inline snd_pcm_sframes_t dlp_bytes_to_frames(struct dlp_runtime_data *drd,
+						    ssize_t size)
+{
+	return size / drd->frame_bytes;
+}
+
+void dlp_dma_complete(struct dlp *dlp, struct dlp_runtime_data *drd);
+int dlp_open(struct dlp *dlp, struct dlp_runtime_data *drd,
+	     struct snd_pcm_substream *substream);
+int dlp_close(struct dlp *dlp, struct dlp_runtime_data *drd,
+	      struct snd_pcm_substream *substream);
+int dlp_hw_params(struct snd_soc_component *component,
+		  struct snd_pcm_substream *substream,
+		  struct snd_pcm_hw_params *params);
+int dlp_start(struct snd_soc_component *component,
+	      struct snd_pcm_substream *substream,
+	      struct device *dev,
+	      dma_pointer_f dma_pointer);
+void dlp_stop(struct snd_soc_component *component,
+	      struct snd_pcm_substream *substream,
+	      dma_pointer_f dma_pointer);
+int dlp_copy_user(struct snd_soc_component *component,
+		  struct snd_pcm_substream *substream,
+		  int channel, unsigned long hwoff,
+		  void __user *buf, unsigned long bytes);
+int dlp_prepare(struct snd_soc_component *component,
+		struct snd_pcm_substream *substream);
+int dlp_probe(struct snd_soc_component *component);
+int dlp_register(struct dlp *dlp, struct device *dev,
+		 const struct snd_soc_component_driver *driver,
+		 const struct snd_dlp_config *config);
 
 #endif
diff --git a/kernel/sound/soc/rockchip/rockchip_dlp_pcm.c b/kernel/sound/soc/rockchip/rockchip_dlp_pcm.c
new file mode 100644
index 0000000..fb55d71
--- /dev/null
+++ b/kernel/sound/soc/rockchip/rockchip_dlp_pcm.c
@@ -0,0 +1,516 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Rockchip DLP (Digital Loopback) Driver
+ *
+ * Copyright (c) 2022 Rockchip Electronics Co. Ltd.
+ * Author: Sugar Zhang <sugar.zhang@rock-chips.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/dmaengine.h>
+#include <linux/slab.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+
+#include <sound/dmaengine_pcm.h>
+
+#include "rockchip_dlp.h"
+
+#define SND_DMAENGINE_DLP_DRV_NAME	"snd_dmaengine_dlp"
+
+static unsigned int prealloc_buffer_size_kbytes = 512;
+module_param(prealloc_buffer_size_kbytes, uint, 0444);
+MODULE_PARM_DESC(prealloc_buffer_size_kbytes, "Preallocate DMA buffer size (KB).");
+
+struct dmaengine_dlp {
+	struct dlp dlp;
+	struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
+};
+
+struct dmaengine_dlp_runtime_data {
+	struct dlp_runtime_data drd;
+	struct dma_chan *dma_chan;
+	dma_cookie_t cookie;
+};
+
+static inline struct dmaengine_dlp *soc_component_to_ddlp(struct snd_soc_component *p)
+{
+	return container_of(soc_component_to_dlp(p), struct dmaengine_dlp, dlp);
+}
+
+static inline struct dmaengine_dlp_runtime_data *substream_to_ddrd(
+	const struct snd_pcm_substream *substream)
+{
+	struct dlp_runtime_data *drd = substream_to_drd(substream);
+
+	if (!drd)
+		return NULL;
+
+	return container_of(drd, struct dmaengine_dlp_runtime_data, drd);
+}
+
+static struct dma_chan *snd_dmaengine_dlp_get_chan(struct snd_pcm_substream *substream)
+{
+	struct dmaengine_dlp_runtime_data *ddrd = substream_to_ddrd(substream);
+
+	return ddrd ? ddrd->dma_chan : NULL;
+}
+
+static struct device *dmaengine_dma_dev(struct dmaengine_dlp *ddlp,
+					struct snd_pcm_substream *substream)
+{
+	if (!ddlp->chan[substream->stream])
+		return NULL;
+
+	return ddlp->chan[substream->stream]->device->dev;
+}
+
+static int dmaengine_dlp_hw_params(struct snd_soc_component *component,
+				   struct snd_pcm_substream *substream,
+				   struct snd_pcm_hw_params *params)
+{
+	struct dma_chan *chan = snd_dmaengine_dlp_get_chan(substream);
+	struct dma_slave_config slave_config;
+	int ret;
+
+	memset(&slave_config, 0, sizeof(slave_config));
+
+	ret = snd_dmaengine_pcm_prepare_slave_config(substream, params, &slave_config);
+	if (ret)
+		return ret;
+
+	ret = dmaengine_slave_config(chan, &slave_config);
+	if (ret)
+		return ret;
+
+	ret = dlp_hw_params(component, substream, params);
+
+	return ret;
+}
+
+static int
+dmaengine_pcm_set_runtime_hwparams(struct snd_soc_component *component,
+				   struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct dmaengine_dlp *ddlp = soc_component_to_ddlp(component);
+	struct device *dma_dev = dmaengine_dma_dev(ddlp, substream);
+	struct dma_chan *chan = ddlp->chan[substream->stream];
+	struct snd_dmaengine_dai_dma_data *dma_data;
+	struct snd_pcm_hardware hw;
+
+	if (rtd->num_cpus > 1) {
+		dev_err(rtd->dev,
+			"%s doesn't support Multi CPU yet\n", __func__);
+		return -EINVAL;
+	}
+
+	dma_data = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream);
+
+	memset(&hw, 0, sizeof(hw));
+	hw.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+		  SNDRV_PCM_INFO_INTERLEAVED;
+	hw.periods_min = 2;
+	hw.periods_max = UINT_MAX;
+	hw.period_bytes_min = 256;
+	hw.period_bytes_max = dma_get_max_seg_size(dma_dev);
+	hw.buffer_bytes_max = SIZE_MAX;
+	hw.fifo_size = dma_data->fifo_size;
+
+	snd_dmaengine_pcm_refine_runtime_hwparams(substream, dma_data,
+						  &hw, chan);
+
+	return snd_soc_set_runtime_hwparams(substream, &hw);
+}
+
+static int dmaengine_dlp_open(struct snd_soc_component *component,
+			      struct snd_pcm_substream *substream)
+{
+	struct dmaengine_dlp *ddlp = soc_component_to_ddlp(component);
+	struct dma_chan *chan = ddlp->chan[substream->stream];
+	struct dmaengine_dlp_runtime_data *ddrd;
+	int ret;
+
+	if (!chan)
+		return -ENXIO;
+
+	ret = dmaengine_pcm_set_runtime_hwparams(component, substream);
+	if (ret)
+		return ret;
+
+	ret = snd_pcm_hw_constraint_integer(substream->runtime,
+					    SNDRV_PCM_HW_PARAM_PERIODS);
+	if (ret < 0)
+		return ret;
+
+	ddrd = kzalloc(sizeof(*ddrd), GFP_KERNEL);
+	if (!ddrd)
+		return -ENOMEM;
+
+	ddrd->dma_chan = chan;
+
+	dlp_open(&ddlp->dlp, &ddrd->drd, substream);
+
+	return 0;
+}
+
+static int dmaengine_dlp_close(struct snd_soc_component *component,
+			       struct snd_pcm_substream *substream)
+{
+	struct dmaengine_dlp *ddlp = soc_component_to_ddlp(component);
+	struct dmaengine_dlp_runtime_data *ddrd = substream_to_ddrd(substream);
+
+	if (unlikely(!ddlp || !ddrd))
+		return -EINVAL;
+
+	dmaengine_synchronize(ddrd->dma_chan);
+
+	dlp_close(&ddlp->dlp, &ddrd->drd, substream);
+
+	kfree(ddrd);
+
+	return 0;
+}
+
+static snd_pcm_uframes_t dmaengine_dlp_pointer(struct snd_soc_component *component,
+					       struct snd_pcm_substream *substream)
+{
+	struct dmaengine_dlp_runtime_data *ddrd = substream_to_ddrd(substream);
+	struct dma_tx_state state;
+	unsigned int buf_size;
+	unsigned int pos = 0;
+
+	if (unlikely(!ddrd))
+		return 0;
+
+	dmaengine_tx_status(ddrd->dma_chan, ddrd->cookie, &state);
+	buf_size = snd_pcm_lib_buffer_bytes(substream);
+	if (state.residue > 0 && state.residue <= buf_size)
+		pos = buf_size - state.residue;
+
+	return dlp_bytes_to_frames(&ddrd->drd, pos);
+}
+
+static void dmaengine_dlp_dma_complete(void *arg)
+{
+	struct snd_pcm_substream *substream = arg;
+	struct dlp_runtime_data *drd;
+	struct dlp *dlp;
+
+	snd_pcm_stream_lock_irq(substream);
+	if (!substream->runtime) {
+		snd_pcm_stream_unlock_irq(substream);
+		return;
+	}
+
+	drd = substream_to_drd(substream);
+	dlp = drd->parent;
+
+	dlp_dma_complete(dlp, drd);
+	snd_pcm_stream_unlock_irq(substream);
+
+	snd_pcm_period_elapsed(substream);
+}
+
+static int dmaengine_dlp_prepare_and_submit(struct snd_pcm_substream *substream)
+{
+	struct dmaengine_dlp_runtime_data *ddrd = substream_to_ddrd(substream);
+	struct dma_chan *chan;
+	struct dma_async_tx_descriptor *desc;
+	enum dma_transfer_direction direction;
+	unsigned long flags = DMA_CTRL_ACK;
+
+	if (unlikely(!ddrd))
+		return -EINVAL;
+
+	chan = ddrd->dma_chan;
+	direction = snd_pcm_substream_to_dma_direction(substream);
+
+	if (!substream->runtime->no_period_wakeup)
+		flags |= DMA_PREP_INTERRUPT;
+
+	desc = dmaengine_prep_dma_cyclic(chan, substream->runtime->dma_addr,
+					 snd_pcm_lib_buffer_bytes(substream),
+					 snd_pcm_lib_period_bytes(substream),
+					 direction, flags);
+
+	if (!desc)
+		return -ENOMEM;
+
+	desc->callback = dmaengine_dlp_dma_complete;
+	desc->callback_param = substream;
+	ddrd->cookie = dmaengine_submit(desc);
+
+	return 0;
+}
+
+static int dmaengine_dlp_start(struct snd_soc_component *component,
+			       struct snd_pcm_substream *substream)
+{
+	struct dlp *dlp = soc_component_to_dlp(component);
+
+	return dlp_start(component, substream, dlp->dev, dmaengine_dlp_pointer);
+}
+
+static void dmaengine_dlp_stop(struct snd_soc_component *component,
+				  struct snd_pcm_substream *substream)
+{
+	dlp_stop(component, substream, dmaengine_dlp_pointer);
+}
+
+static int dmaengine_dlp_trigger(struct snd_soc_component *component,
+				 struct snd_pcm_substream *substream, int cmd)
+{
+	struct dmaengine_dlp_runtime_data *ddrd = substream_to_ddrd(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int ret;
+
+	if (unlikely(!ddrd))
+		return -EINVAL;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		ret = dmaengine_dlp_prepare_and_submit(substream);
+		if (ret)
+			return ret;
+		dma_async_issue_pending(ddrd->dma_chan);
+		dmaengine_dlp_start(component, substream);
+		break;
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		dmaengine_resume(ddrd->dma_chan);
+		break;
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+		if (runtime->info & SNDRV_PCM_INFO_PAUSE) {
+			dmaengine_pause(ddrd->dma_chan);
+		} else {
+			dmaengine_dlp_stop(component, substream);
+			dmaengine_terminate_async(ddrd->dma_chan);
+		}
+		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		dmaengine_pause(ddrd->dma_chan);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		dmaengine_dlp_stop(component, substream);
+		dmaengine_terminate_async(ddrd->dma_chan);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int dmaengine_dlp_new(struct snd_soc_component *component,
+			     struct snd_soc_pcm_runtime *rtd)
+{
+	struct dmaengine_dlp *ddlp = soc_component_to_ddlp(component);
+	struct snd_pcm_substream *substream;
+	size_t prealloc_buffer_size;
+	size_t max_buffer_size;
+	unsigned int i;
+
+	prealloc_buffer_size = prealloc_buffer_size_kbytes * 1024;
+	max_buffer_size = SIZE_MAX;
+
+	for_each_pcm_streams(i) {
+		substream = rtd->pcm->streams[i].substream;
+		if (!substream)
+			continue;
+
+		if (!ddlp->chan[i]) {
+			dev_err(component->dev,
+				"Missing dma channel for stream: %d\n", i);
+			return -EINVAL;
+		}
+
+		snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV_IRAM,
+					   dmaengine_dma_dev(ddlp, substream),
+					   prealloc_buffer_size,
+					   max_buffer_size);
+
+		if (rtd->pcm->streams[i].pcm->name[0] == '\0') {
+			strscpy_pad(rtd->pcm->streams[i].pcm->name,
+				    rtd->pcm->streams[i].pcm->id,
+				    sizeof(rtd->pcm->streams[i].pcm->name));
+		}
+	}
+
+	return 0;
+}
+
+static int dmaengine_dlp_copy_user(struct snd_soc_component *component,
+				   struct snd_pcm_substream *substream,
+				   int channel, unsigned long hwoff,
+				   void __user *buf, unsigned long bytes)
+{
+	return dlp_copy_user(component, substream, channel, hwoff, buf, bytes);
+}
+
+static int dmaengine_dlp_prepare(struct snd_soc_component *component,
+				 struct snd_pcm_substream *substream)
+{
+	return dlp_prepare(component, substream);
+}
+
+static int dmaengine_dlp_probe(struct snd_soc_component *component)
+{
+	return dlp_probe(component);
+}
+
+static const struct snd_soc_component_driver dmaengine_dlp_component = {
+	.name		= SND_DMAENGINE_DLP_DRV_NAME,
+	.probe_order	= SND_SOC_COMP_ORDER_LATE,
+	.probe		= dmaengine_dlp_probe,
+	.open		= dmaengine_dlp_open,
+	.close		= dmaengine_dlp_close,
+	.hw_params	= dmaengine_dlp_hw_params,
+	.prepare	= dmaengine_dlp_prepare,
+	.trigger	= dmaengine_dlp_trigger,
+	.pointer	= dmaengine_dlp_pointer,
+	.copy_user	= dmaengine_dlp_copy_user,
+	.pcm_construct	= dmaengine_dlp_new,
+};
+
+static const char * const dmaengine_pcm_dma_channel_names[] = {
+	[SNDRV_PCM_STREAM_PLAYBACK] = "tx",
+	[SNDRV_PCM_STREAM_CAPTURE] = "rx",
+};
+
+static int dmaengine_pcm_request_chan_of(struct dmaengine_dlp *ddlp,
+	struct device *dev, const struct snd_dmaengine_pcm_config *config)
+{
+	unsigned int i;
+	const char *name;
+	struct dma_chan *chan;
+
+	for_each_pcm_streams(i) {
+		name = dmaengine_pcm_dma_channel_names[i];
+		chan = dma_request_chan(dev, name);
+		if (IS_ERR(chan)) {
+			/*
+			 * Only report probe deferral errors, channels
+			 * might not be present for devices that
+			 * support only TX or only RX.
+			 */
+			if (PTR_ERR(chan) == -EPROBE_DEFER)
+				return -EPROBE_DEFER;
+			ddlp->chan[i] = NULL;
+		} else {
+			ddlp->chan[i] = chan;
+		}
+	}
+
+	return 0;
+}
+
+static void dmaengine_pcm_release_chan(struct dmaengine_dlp *ddlp)
+{
+	unsigned int i;
+
+	for_each_pcm_streams(i) {
+		if (!ddlp->chan[i])
+			continue;
+		dma_release_channel(ddlp->chan[i]);
+	}
+}
+
+/**
+ * snd_dmaengine_dlp_register - Register a dmaengine based DLP device
+ * @dev: The parent device for the DLP device
+ * @config: Platform specific DLP configuration
+ */
+static int snd_dmaengine_dlp_register(struct device *dev,
+				      const struct snd_dlp_config *config)
+{
+	struct dmaengine_dlp *ddlp;
+	int ret;
+
+	ddlp = kzalloc(sizeof(*ddlp), GFP_KERNEL);
+	if (!ddlp)
+		return -ENOMEM;
+
+	ret = dmaengine_pcm_request_chan_of(ddlp, dev, NULL);
+	if (ret)
+		goto err_free_dma;
+
+	ret = dlp_register(&ddlp->dlp, dev, &dmaengine_dlp_component, config);
+	if (ret)
+		goto err_free_dma;
+
+	return 0;
+
+err_free_dma:
+	dmaengine_pcm_release_chan(ddlp);
+	kfree(ddlp);
+	return ret;
+}
+
+/**
+ * snd_dmaengine_dlp_unregister - Removes a dmaengine based DLP device
+ * @dev: Parent device the DLP was register with
+ *
+ * Removes a dmaengine based DLP device previously registered with
+ * snd_dmaengine_dlp_register.
+ */
+static void snd_dmaengine_dlp_unregister(struct device *dev)
+{
+	struct snd_soc_component *component;
+	struct dmaengine_dlp *ddlp;
+
+	component = snd_soc_lookup_component(dev, SND_DMAENGINE_DLP_DRV_NAME);
+	if (!component)
+		return;
+
+	ddlp = soc_component_to_ddlp(component);
+
+	snd_soc_unregister_component_by_driver(dev, component->driver);
+	dmaengine_pcm_release_chan(ddlp);
+
+	kfree(ddlp);
+}
+
+static void devm_dmaengine_dlp_stop(struct device *dev, void *res)
+{
+	snd_dmaengine_dlp_unregister(*(struct device **)res);
+}
+
+/**
+ * devm_snd_dmaengine_dlp_register - resource managed dmaengine DLP registration
+ * @dev: The parent device for the DLP device
+ * @config: Platform specific DLP configuration
+ *
+ * Register a dmaengine based DLP device with automatic unregistration when the
+ * device is unregistered.
+ */
+int devm_snd_dmaengine_dlp_register(struct device *dev,
+				    const struct snd_dlp_config *config)
+{
+	struct device **ptr;
+	int ret;
+
+	ptr = devres_alloc(devm_dmaengine_dlp_stop, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return -ENOMEM;
+
+	ret = snd_dmaengine_dlp_register(dev, config);
+	if (ret == 0) {
+		*ptr = dev;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(devm_snd_dmaengine_dlp_register);
+
+MODULE_DESCRIPTION("Rockchip Digital Loopback PCM Driver");
+MODULE_AUTHOR("Sugar Zhang <sugar.zhang@rock-chips.com>");
+MODULE_LICENSE("GPL");
diff --git a/kernel/sound/soc/rockchip/rockchip_dlp_pcm.h b/kernel/sound/soc/rockchip/rockchip_dlp_pcm.h
new file mode 100644
index 0000000..3fa80ba
--- /dev/null
+++ b/kernel/sound/soc/rockchip/rockchip_dlp_pcm.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Rockchip DLP (Digital Loopback) PCM driver
+ *
+ * Copyright (C) 2022 Rockchip Electronics Co., Ltd
+ * Author: Sugar Zhang <sugar.zhang@rock-chips.com>
+ *
+ */
+
+#ifndef _ROCKCHIP_DLP_PCM_H
+#define _ROCKCHIP_DLP_PCM_H
+
+struct snd_dlp_config {
+	int (*get_fifo_count)(struct device *dev, struct snd_pcm_substream *substream);
+};
+
+#if IS_REACHABLE(CONFIG_SND_SOC_ROCKCHIP_DLP_PCM)
+int devm_snd_dmaengine_dlp_register(struct device *dev,
+	const struct snd_dlp_config *config);
+#else
+static inline int devm_snd_dmaengine_dlp_register(struct device *dev,
+	const struct snd_dlp_config *config)
+{
+	return -ENOSYS;
+}
+#endif
+
+#endif
diff --git a/kernel/sound/soc/rockchip/rockchip_i2s.c b/kernel/sound/soc/rockchip/rockchip_i2s.c
index 4e27cbd..587d80b 100644
--- a/kernel/sound/soc/rockchip/rockchip_i2s.c
+++ b/kernel/sound/soc/rockchip/rockchip_i2s.c
@@ -21,6 +21,8 @@
 #include <sound/dmaengine_pcm.h>
 
 #include "rockchip_i2s.h"
+#include "rockchip_dlp_pcm.h"
+#include "rockchip_utils.h"
 
 #define DRV_NAME "rockchip-i2s"
 
@@ -333,6 +335,25 @@
 	return ret;
 }
 
+static void rockchip_i2s_get_performance(struct snd_pcm_substream *substream,
+					 struct snd_pcm_hw_params *params,
+					 struct snd_soc_dai *dai,
+					 unsigned int csr)
+{
+	struct rk_i2s_dev *i2s = to_info(dai);
+	unsigned int tdl;
+	int fifo;
+
+	regmap_read(i2s->regmap, I2S_DMACR, &tdl);
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		fifo = I2S_DMACR_TDL_V(tdl) * I2S_TXCR_CSR_V(csr);
+	else
+		fifo = I2S_DMACR_RDL_V(tdl) * I2S_RXCR_CSR_V(csr);
+
+	rockchip_utils_get_performance(substream, params, dai, fifo);
+}
+
 static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
 				  struct snd_pcm_hw_params *params,
 				  struct snd_soc_dai *dai)
@@ -400,6 +421,8 @@
 		return -EINVAL;
 	}
 
+	rockchip_i2s_get_performance(substream, params, dai, val);
+
 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 		regmap_update_bits(i2s->regmap, I2S_RXCR,
 				   I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK,
@@ -437,6 +460,14 @@
 			   I2S_DMACR_TDL(16));
 	regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,
 			   I2S_DMACR_RDL(16));
+
+	return 0;
+}
+
+static int rockchip_i2s_hw_free(struct snd_pcm_substream *substream,
+				struct snd_soc_dai *dai)
+{
+	rockchip_utils_put_performance(substream, dai);
 
 	return 0;
 }
@@ -571,8 +602,8 @@
 static int rockchip_i2s_clk_compensation_get(struct snd_kcontrol *kcontrol,
 					     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
-	struct rk_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);
+	struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
+	struct rk_i2s_dev *i2s = snd_soc_component_get_drvdata(compnt);
 
 	ucontrol->value.integer.value[0] = i2s->clk_ppm;
 
@@ -582,8 +613,8 @@
 static int rockchip_i2s_clk_compensation_put(struct snd_kcontrol *kcontrol,
 					     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
-	struct rk_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);
+	struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
+	struct rk_i2s_dev *i2s = snd_soc_component_get_drvdata(compnt);
 	int ppm = ucontrol->value.integer.value[0];
 
 	if ((ucontrol->value.integer.value[0] < CLK_PPM_MIN) ||
@@ -646,6 +677,7 @@
 	.startup = rockchip_i2s_startup,
 	.shutdown = rockchip_i2s_shutdown,
 	.hw_params = rockchip_i2s_hw_params,
+	.hw_free = rockchip_i2s_hw_free,
 	.set_bclk_ratio	= rockchip_i2s_set_bclk_ratio,
 	.set_sysclk = rockchip_i2s_set_sysclk,
 	.set_fmt = rockchip_i2s_set_fmt,
@@ -798,7 +830,8 @@
 	case I2S_CLR:
 	case I2S_TXDR:
 	case I2S_RXDR:
-	case I2S_FIFOLR:
+	case I2S_TXFIFOLR:
+	case I2S_RXFIFOLR:
 	case I2S_INTSR:
 		return true;
 	default:
@@ -811,7 +844,8 @@
 	switch (reg) {
 	case I2S_INTSR:
 	case I2S_CLR:
-	case I2S_FIFOLR:
+	case I2S_TXFIFOLR:
+	case I2S_RXFIFOLR:
 	case I2S_TXDR:
 	case I2S_RXDR:
 		return true;
@@ -938,7 +972,7 @@
 		i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 		i2s->playback_dma_data.maxburst = 8;
 
-		if (!of_property_read_u32(node, "rockchip,playback-channels", &val)) {
+		if (!device_property_read_u32(i2s->dev, "rockchip,playback-channels", &val)) {
 			if (val >= 2 && val <= 8)
 				dai->playback.channels_max = val;
 		}
@@ -960,14 +994,14 @@
 		i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 		i2s->capture_dma_data.maxburst = 8;
 
-		if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) {
+		if (!device_property_read_u32(i2s->dev, "rockchip,capture-channels", &val)) {
 			if (val >= 2 && val <= 8)
 				dai->capture.channels_max = val;
 		}
 	}
 
 	i2s->clk_trcm = I2S_CKR_TRCM_TXRX;
-	if (!of_property_read_u32(node, "rockchip,clk-trcm", &val)) {
+	if (!device_property_read_u32(i2s->dev, "rockchip,clk-trcm", &val)) {
 		if (val >= 0 && val <= 2) {
 			i2s->clk_trcm = val << I2S_CKR_TRCM_SHIFT;
 			if (i2s->clk_trcm)
@@ -1015,6 +1049,36 @@
 
 	return 0;
 }
+
+static int rockchip_i2s_get_fifo_count(struct device *dev,
+				       struct snd_pcm_substream *substream)
+{
+	struct rk_i2s_dev *i2s = dev_get_drvdata(dev);
+	unsigned int tx, rx;
+	int val = 0;
+
+	regmap_read(i2s->regmap, I2S_TXFIFOLR, &tx);
+	regmap_read(i2s->regmap, I2S_RXFIFOLR, &rx);
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		val = I2S_FIFOLR_XFL3(tx) +
+		      I2S_FIFOLR_XFL2(tx) +
+		      I2S_FIFOLR_XFL1(tx) +
+		      I2S_FIFOLR_XFL0(tx);
+	else
+		/* XFL4 is compatible for old version */
+		val = I2S_FIFOLR_XFL4(tx) +
+		      I2S_FIFOLR_XFL3(rx) +
+		      I2S_FIFOLR_XFL2(rx) +
+		      I2S_FIFOLR_XFL1(rx) +
+		      I2S_FIFOLR_XFL0(rx);
+
+	return val;
+}
+
+static const struct snd_dlp_config dconfig = {
+	.get_fifo_count = rockchip_i2s_get_fifo_count,
+};
 
 static int rockchip_i2s_probe(struct platform_device *pdev)
 {
@@ -1067,7 +1131,7 @@
 	dev_set_drvdata(&pdev->dev, i2s);
 
 	i2s->mclk_calibrate =
-		of_property_read_bool(node, "rockchip,mclk-calibrate");
+		device_property_read_bool(&pdev->dev, "rockchip,mclk-calibrate");
 	if (i2s->mclk_calibrate) {
 		i2s->mclk_root = devm_clk_get(&pdev->dev, "i2s_clk_root");
 		if (IS_ERR(i2s->mclk_root))
@@ -1136,12 +1200,16 @@
 		goto err_suspend;
 	}
 
-	if (of_property_read_bool(node, "rockchip,no-dmaengine")) {
+	if (device_property_read_bool(&pdev->dev, "rockchip,no-dmaengine")) {
 		dev_info(&pdev->dev, "Used for Multi-DAI\n");
 		return 0;
 	}
 
-	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+	if (device_property_read_bool(&pdev->dev, "rockchip,digital-loopback"))
+		ret = devm_snd_dmaengine_dlp_register(&pdev->dev, &dconfig);
+	else
+		ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+
 	if (ret) {
 		dev_err(&pdev->dev, "Could not register PCM\n");
 		goto err_suspend;
diff --git a/kernel/sound/soc/rockchip/rockchip_i2s.h b/kernel/sound/soc/rockchip/rockchip_i2s.h
index 251851b..748cf7b 100644
--- a/kernel/sound/soc/rockchip/rockchip_i2s.h
+++ b/kernel/sound/soc/rockchip/rockchip_i2s.h
@@ -18,8 +18,9 @@
 #define I2S_TXCR_RCNT_SHIFT	17
 #define I2S_TXCR_RCNT_MASK	(0x3f << I2S_TXCR_RCNT_SHIFT)
 #define I2S_TXCR_CSR_SHIFT	15
-#define I2S_TXCR_CSR(x)		(x << I2S_TXCR_CSR_SHIFT)
 #define I2S_TXCR_CSR_MASK	(3 << I2S_TXCR_CSR_SHIFT)
+#define I2S_TXCR_CSR(x)		(x << I2S_TXCR_CSR_SHIFT)
+#define I2S_TXCR_CSR_V(v)	((((v) & I2S_TXCR_CSR_MASK) >> 15) + 1)
 #define I2S_TXCR_HWT		BIT(14)
 #define I2S_TXCR_SJM_SHIFT	12
 #define I2S_TXCR_SJM_R		(0 << I2S_TXCR_SJM_SHIFT)
@@ -48,8 +49,9 @@
  * receive operation control register
 */
 #define I2S_RXCR_CSR_SHIFT	15
-#define I2S_RXCR_CSR(x)		(x << I2S_RXCR_CSR_SHIFT)
 #define I2S_RXCR_CSR_MASK	(3 << I2S_RXCR_CSR_SHIFT)
+#define I2S_RXCR_CSR(x)		(x << I2S_RXCR_CSR_SHIFT)
+#define I2S_RXCR_CSR_V(v)	((((v) & I2S_RXCR_CSR_MASK) >> 15) + 1)
 #define I2S_RXCR_HWT		BIT(14)
 #define I2S_RXCR_SJM_SHIFT	12
 #define I2S_RXCR_SJM_R		(0 << I2S_RXCR_SJM_SHIFT)
@@ -132,14 +134,16 @@
 #define I2S_DMACR_RDE_DISABLE	(0 << I2S_DMACR_RDE_SHIFT)
 #define I2S_DMACR_RDE_ENABLE	(1 << I2S_DMACR_RDE_SHIFT)
 #define I2S_DMACR_RDL_SHIFT	16
-#define I2S_DMACR_RDL(x)	((x - 1) << I2S_DMACR_RDL_SHIFT)
 #define I2S_DMACR_RDL_MASK	(0x1f << I2S_DMACR_RDL_SHIFT)
+#define I2S_DMACR_RDL(x)	((x - 1) << I2S_DMACR_RDL_SHIFT)
+#define I2S_DMACR_RDL_V(v)	((((v) & I2S_DMACR_RDL_MASK) >> 16) + 1)
 #define I2S_DMACR_TDE_SHIFT	8
 #define I2S_DMACR_TDE_DISABLE	(0 << I2S_DMACR_TDE_SHIFT)
 #define I2S_DMACR_TDE_ENABLE	(1 << I2S_DMACR_TDE_SHIFT)
 #define I2S_DMACR_TDL_SHIFT	0
-#define I2S_DMACR_TDL(x)	((x) << I2S_DMACR_TDL_SHIFT)
 #define I2S_DMACR_TDL_MASK	(0x1f << I2S_DMACR_TDL_SHIFT)
+#define I2S_DMACR_TDL(x)	((x) << I2S_DMACR_TDL_SHIFT)
+#define I2S_DMACR_TDL_V(v)	(((v) & I2S_DMACR_TDL_MASK) >> 0)
 
 /*
  * INTCR
@@ -229,7 +233,7 @@
 #define I2S_TXCR	(0x0000)
 #define I2S_RXCR	(0x0004)
 #define I2S_CKR		(0x0008)
-#define I2S_FIFOLR	(0x000c)
+#define I2S_TXFIFOLR	(0x000c)
 #define I2S_DMACR	(0x0010)
 #define I2S_INTCR	(0x0014)
 #define I2S_INTSR	(0x0018)
@@ -237,6 +241,7 @@
 #define I2S_CLR		(0x0020)
 #define I2S_TXDR	(0x0024)
 #define I2S_RXDR	(0x0028)
+#define I2S_RXFIFOLR	(0x002c)
 
 /* io direction cfg register */
 #define I2S_IO_DIRECTION_MASK	(7)
@@ -245,4 +250,11 @@
 #define I2S_IO_4CH_OUT_6CH_IN	(6)
 #define I2S_IO_2CH_OUT_8CH_IN	(7)
 
+/* XFL4 is compatible for old version */
+#define I2S_FIFOLR_XFL4(v)	(((v) & GENMASK(29, 24)) >> 24)
+#define I2S_FIFOLR_XFL3(v)	(((v) & GENMASK(23, 18)) >> 18)
+#define I2S_FIFOLR_XFL2(v)	(((v) & GENMASK(17, 12)) >> 12)
+#define I2S_FIFOLR_XFL1(v)	(((v) & GENMASK(11, 6)) >> 6)
+#define I2S_FIFOLR_XFL0(v)	(((v) & GENMASK(5, 0)) >> 0)
+
 #endif /* _ROCKCHIP_IIS_H */
diff --git a/kernel/sound/soc/rockchip/rockchip_i2s_tdm.c b/kernel/sound/soc/rockchip/rockchip_i2s_tdm.c
index b0c4ce0..612c263 100644
--- a/kernel/sound/soc/rockchip/rockchip_i2s_tdm.c
+++ b/kernel/sound/soc/rockchip/rockchip_i2s_tdm.c
@@ -28,7 +28,8 @@
 #include <sound/dmaengine_pcm.h>
 
 #include "rockchip_i2s_tdm.h"
-#include "rockchip_dlp.h"
+#include "rockchip_dlp_pcm.h"
+#include "rockchip_utils.h"
 
 #define DRV_NAME "rockchip-i2s-tdm"
 
@@ -1678,6 +1679,25 @@
 	return ret;
 }
 
+static void rockchip_i2s_tdm_get_performance(struct snd_pcm_substream *substream,
+					     struct snd_pcm_hw_params *params,
+					     struct snd_soc_dai *dai,
+					     unsigned int csr)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+	unsigned int tdl;
+	int fifo;
+
+	regmap_read(i2s_tdm->regmap, I2S_DMACR, &tdl);
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		fifo = I2S_DMACR_TDL_V(tdl) * I2S_TXCR_CSR_V(csr);
+	else
+		fifo = I2S_DMACR_RDL_V(tdl) * I2S_RXCR_CSR_V(csr);
+
+	rockchip_utils_get_performance(substream, params, dai, fifo);
+}
+
 static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
 				      struct snd_pcm_hw_params *params,
 				      struct snd_soc_dai *dai)
@@ -1740,6 +1760,8 @@
 	if (ret < 0)
 		goto err;
 
+	rockchip_i2s_tdm_get_performance(substream, params, dai, ret);
+
 	val |= ret;
 	if (!is_params_dirty(substream, dai, div_bclk, div_lrck, val))
 		return 0;
@@ -1753,6 +1775,13 @@
 
 err:
 	return ret;
+}
+static int rockchip_i2s_tdm_hw_free(struct snd_pcm_substream *substream,
+				    struct snd_soc_dai *dai)
+{
+	rockchip_utils_put_performance(substream, dai);
+
+	return 0;
 }
 
 static int rockchip_i2s_tdm_trigger(struct snd_pcm_substream *substream,
@@ -1817,8 +1846,8 @@
 static int rockchip_i2s_tdm_clk_compensation_get(struct snd_kcontrol *kcontrol,
 						 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
-	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = i2s_tdm->clk_ppm;
 
@@ -1828,8 +1857,8 @@
 static int rockchip_i2s_tdm_clk_compensation_put(struct snd_kcontrol *kcontrol,
 						 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
-	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
 	int ret = 0, ppm = 0;
 
 	if ((ucontrol->value.integer.value[0] < CLK_PPM_MIN) ||
@@ -2119,6 +2148,7 @@
 	.startup = rockchip_i2s_tdm_startup,
 	.shutdown = rockchip_i2s_tdm_shutdown,
 	.hw_params = rockchip_i2s_tdm_hw_params,
+	.hw_free = rockchip_i2s_tdm_hw_free,
 	.set_sysclk = rockchip_i2s_tdm_set_sysclk,
 	.set_fmt = rockchip_i2s_tdm_set_fmt,
 	.set_tdm_slot = rockchip_dai_tdm_slot,
@@ -2548,12 +2578,13 @@
 	return rockchip_i2s_tdm_path_prepare(i2s_tdm, np, 1);
 }
 
-static int rockchip_i2s_tdm_get_fifo_count(struct device *dev, int stream)
+static int rockchip_i2s_tdm_get_fifo_count(struct device *dev,
+					   struct snd_pcm_substream *substream)
 {
 	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
 	int val = 0;
 
-	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		regmap_read(i2s_tdm->regmap, I2S_TXFIFOLR, &val);
 	else
 		regmap_read(i2s_tdm->regmap, I2S_RXFIFOLR, &val);
@@ -2640,6 +2671,29 @@
 		 mclk_rate, bclk_rate, DEFAULT_FS);
 
 	return 0;
+}
+
+static int rockchip_i2s_tdm_register_platform(struct device *dev)
+{
+	int ret = 0;
+
+	if (device_property_read_bool(dev, "rockchip,no-dmaengine")) {
+		dev_info(dev, "Used for Multi-DAI\n");
+		return 0;
+	}
+
+	if (device_property_read_bool(dev, "rockchip,digital-loopback")) {
+		ret = devm_snd_dmaengine_dlp_register(dev, &dconfig);
+		if (ret)
+			dev_err(dev, "Could not register DLP\n");
+		return ret;
+	}
+
+	ret = devm_snd_dmaengine_pcm_register(dev, NULL, 0);
+	if (ret)
+		dev_err(dev, "Could not register PCM\n");
+
+	return ret;
 }
 
 static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
@@ -2919,28 +2973,16 @@
 			goto err_pm_disable;
 	}
 
+	ret = rockchip_i2s_tdm_register_platform(&pdev->dev);
+	if (ret)
+		goto err_suspend;
+
 	ret = devm_snd_soc_register_component(&pdev->dev,
 					      &rockchip_i2s_tdm_component,
 					      soc_dai, 1);
-
 	if (ret) {
 		dev_err(&pdev->dev, "Could not register DAI\n");
 		goto err_suspend;
-	}
-
-	if (of_property_read_bool(node, "rockchip,no-dmaengine")) {
-		dev_info(&pdev->dev, "Used for Multi-DAI\n");
-		return 0;
-	}
-
-	if (of_property_read_bool(node, "rockchip,digital-loopback"))
-		ret = devm_snd_dmaengine_dlp_register(&pdev->dev, &dconfig);
-	else
-		ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
-
-	if (ret) {
-		dev_err(&pdev->dev, "Could not register PCM\n");
-		return ret;
 	}
 
 	return 0;
diff --git a/kernel/sound/soc/rockchip/rockchip_i2s_tdm.h b/kernel/sound/soc/rockchip/rockchip_i2s_tdm.h
index 2a8c489..904afe0 100644
--- a/kernel/sound/soc/rockchip/rockchip_i2s_tdm.h
+++ b/kernel/sound/soc/rockchip/rockchip_i2s_tdm.h
@@ -24,8 +24,9 @@
 #define I2S_TXCR_RCNT_SHIFT	17
 #define I2S_TXCR_RCNT_MASK	(0x3f << I2S_TXCR_RCNT_SHIFT)
 #define I2S_TXCR_CSR_SHIFT	15
-#define I2S_TXCR_CSR(x)		((x) << I2S_TXCR_CSR_SHIFT)
 #define I2S_TXCR_CSR_MASK	(3 << I2S_TXCR_CSR_SHIFT)
+#define I2S_TXCR_CSR(x)		((x) << I2S_TXCR_CSR_SHIFT)
+#define I2S_TXCR_CSR_V(v)	((((v) & I2S_TXCR_CSR_MASK) >> 15) + 1)
 #define I2S_TXCR_HWT		BIT(14)
 #define I2S_TXCR_SJM_SHIFT	12
 #define I2S_TXCR_SJM_R		(0 << I2S_TXCR_SJM_SHIFT)
@@ -59,8 +60,9 @@
 #define I2S_RXCR_PATH_MASK(x)	(0x3 << I2S_RXCR_PATH_SHIFT(x))
 #define I2S_RXCR_PATH(x, v)	((v) << I2S_RXCR_PATH_SHIFT(x))
 #define I2S_RXCR_CSR_SHIFT	15
-#define I2S_RXCR_CSR(x)		((x) << I2S_RXCR_CSR_SHIFT)
 #define I2S_RXCR_CSR_MASK	(3 << I2S_RXCR_CSR_SHIFT)
+#define I2S_RXCR_CSR(x)		((x) << I2S_RXCR_CSR_SHIFT)
+#define I2S_RXCR_CSR_V(v)	((((v) & I2S_RXCR_CSR_MASK) >> 15) + 1)
 #define I2S_RXCR_HWT		BIT(14)
 #define I2S_RXCR_SJM_SHIFT	12
 #define I2S_RXCR_SJM_R		(0 << I2S_RXCR_SJM_SHIFT)
@@ -147,16 +149,18 @@
 #define I2S_DMACR_RDE_MASK	(1 << I2S_DMACR_RDE_SHIFT)
 #define I2S_DMACR_RDE(x)	((x) << I2S_DMACR_RDE_SHIFT)
 #define I2S_DMACR_RDL_SHIFT	16
-#define I2S_DMACR_RDL(x)	(((x) - 1) << I2S_DMACR_RDL_SHIFT)
 #define I2S_DMACR_RDL_MASK	(0x1f << I2S_DMACR_RDL_SHIFT)
+#define I2S_DMACR_RDL(x)	(((x) - 1) << I2S_DMACR_RDL_SHIFT)
+#define I2S_DMACR_RDL_V(v)	((((v) & I2S_DMACR_RDL_MASK) >> 16) + 1)
 #define I2S_DMACR_TDE_SHIFT	8
 #define I2S_DMACR_TDE_DISABLE	(0 << I2S_DMACR_TDE_SHIFT)
 #define I2S_DMACR_TDE_ENABLE	(1 << I2S_DMACR_TDE_SHIFT)
 #define I2S_DMACR_TDE_MASK	(1 << I2S_DMACR_TDE_SHIFT)
 #define I2S_DMACR_TDE(x)	((x) << I2S_DMACR_TDE_SHIFT)
 #define I2S_DMACR_TDL_SHIFT	0
-#define I2S_DMACR_TDL(x)	((x) << I2S_DMACR_TDL_SHIFT)
 #define I2S_DMACR_TDL_MASK	(0x1f << I2S_DMACR_TDL_SHIFT)
+#define I2S_DMACR_TDL(x)	((x) << I2S_DMACR_TDL_SHIFT)
+#define I2S_DMACR_TDL_V(v)	(((v) & I2S_DMACR_TDL_MASK) >> 0)
 
 /*
  * INTCR
diff --git a/kernel/sound/soc/rockchip/rockchip_multi_dais.c b/kernel/sound/soc/rockchip/rockchip_multi_dais.c
index d4994f6..4b9bb34 100644
--- a/kernel/sound/soc/rockchip/rockchip_multi_dais.c
+++ b/kernel/sound/soc/rockchip/rockchip_multi_dais.c
@@ -30,6 +30,13 @@
 	return snd_soc_dai_get_drvdata(dai);
 }
 
+static inline unsigned int *mdais_channel_maps(struct rk_mdais_dev *mdais,
+					       struct snd_pcm_substream *substream)
+{
+	return substream->stream ? mdais->capture_channel_maps :
+				   mdais->playback_channel_maps;
+}
+
 static void hw_refine_channels(struct snd_pcm_hw_params *params,
 			       unsigned int channel)
 {
@@ -54,26 +61,51 @@
 	if (IS_ERR(cparams))
 		return PTR_ERR(cparams);
 
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		channel_maps = mdais->playback_channel_maps;
-	else
-		channel_maps = mdais->capture_channel_maps;
+	channel_maps = mdais_channel_maps(mdais, substream);
 
 	for (i = 0; i < mdais->num_dais; i++) {
 		child = mdais->dais[i].dai;
-		if (channel_maps[i])
-			hw_refine_channels(cparams, channel_maps[i]);
+		if (!channel_maps[i])
+			continue;
+
+		hw_refine_channels(cparams, channel_maps[i]);
 		if (child->driver->ops && child->driver->ops->hw_params) {
 			ret = child->driver->ops->hw_params(substream, cparams, child);
 			if (ret < 0) {
-				dev_err(dai->dev, "ASoC: can't set %s hw params: %d\n",
+				dev_err(dai->dev, "Failed to set %s hw params: %d\n",
 					dai->name, ret);
-				return ret;
+				break;
 			}
 		}
 	}
 
 	kfree(cparams);
+
+	return ret;
+}
+
+static int rockchip_mdais_hw_free(struct snd_pcm_substream *substream,
+				  struct snd_soc_dai *dai)
+{
+	struct rk_mdais_dev *mdais = to_info(dai);
+	struct snd_soc_dai *child;
+	unsigned int *channel_maps;
+	int ret = 0, i = 0;
+
+	channel_maps = mdais_channel_maps(mdais, substream);
+
+	for (i = 0; i < mdais->num_dais; i++) {
+		child = mdais->dais[i].dai;
+		if (!channel_maps[i])
+			continue;
+
+		if (child->driver->ops && child->driver->ops->hw_free) {
+			ret = child->driver->ops->hw_free(substream, child);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
 	return 0;
 }
 
@@ -85,10 +117,7 @@
 	unsigned int *channel_maps;
 	int ret = 0, i = 0;
 
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		channel_maps = mdais->playback_channel_maps;
-	else
-		channel_maps = mdais->capture_channel_maps;
+	channel_maps = mdais_channel_maps(mdais, substream);
 
 	for (i = 0; i < mdais->num_dais; i++) {
 		/* skip DAIs which have no channel mapping */
@@ -112,9 +141,15 @@
 {
 	struct rk_mdais_dev *mdais = to_info(dai);
 	struct snd_soc_dai *child;
+	unsigned int *channel_maps;
 	int ret = 0, i = 0;
 
+	channel_maps = mdais_channel_maps(mdais, substream);
+
 	for (i = 0; i < mdais->num_dais; i++) {
+		if (!channel_maps[i])
+			continue;
+
 		child = mdais->dais[i].dai;
 		if (child->driver->ops && child->driver->ops->startup) {
 			ret = child->driver->ops->startup(substream, child);
@@ -131,9 +166,15 @@
 {
 	struct rk_mdais_dev *mdais = to_info(dai);
 	struct snd_soc_dai *child;
+	unsigned int *channel_maps;
 	int i = 0;
 
+	channel_maps = mdais_channel_maps(mdais, substream);
+
 	for (i = 0; i < mdais->num_dais; i++) {
+		if (!channel_maps[i])
+			continue;
+
 		child = mdais->dais[i].dai;
 		if (child->driver->ops && child->driver->ops->shutdown) {
 			child->driver->ops->shutdown(substream, child);
@@ -146,9 +187,15 @@
 {
 	struct rk_mdais_dev *mdais = to_info(dai);
 	struct snd_soc_dai *child;
+	unsigned int *channel_maps;
 	int ret = 0, i = 0;
 
+	channel_maps = mdais_channel_maps(mdais, substream);
+
 	for (i = 0; i < mdais->num_dais; i++) {
+		if (!channel_maps[i])
+			continue;
+
 		child = mdais->dais[i].dai;
 		if (child->driver->ops && child->driver->ops->prepare) {
 			ret = child->driver->ops->prepare(substream, child);
@@ -242,7 +289,7 @@
 			ret = child->driver->probe(child);
 			if (ret < 0) {
 				dev_err(child->dev,
-					"ASoC: failed to probe DAI %s: %d\n",
+					"Failed to probe DAI %s: %d\n",
 					child->name, ret);
 				return ret;
 			}
@@ -263,6 +310,7 @@
 
 static const struct snd_soc_dai_ops rockchip_mdais_dai_ops = {
 	.hw_params = rockchip_mdais_hw_params,
+	.hw_free = rockchip_mdais_hw_free,
 	.set_sysclk = rockchip_mdais_set_sysclk,
 	.set_fmt = rockchip_mdais_set_fmt,
 	.set_tdm_slot = rockchip_mdais_tdm_slot,
diff --git a/kernel/sound/soc/rockchip/rockchip_multi_dais_pcm.c b/kernel/sound/soc/rockchip/rockchip_multi_dais_pcm.c
index 88daa5d..0e8955a 100644
--- a/kernel/sound/soc/rockchip/rockchip_multi_dais_pcm.c
+++ b/kernel/sound/soc/rockchip/rockchip_multi_dais_pcm.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * ALSA SoC Audio Layer - Rockchip Multi-DAIS-PCM driver
  *
@@ -16,23 +16,44 @@
 #include <sound/soc.h>
 
 #include "rockchip_multi_dais.h"
+#include "rockchip_dlp.h"
 
-#define MAX_FIFO_SIZE	32 /* max fifo size in frames */
-#define SND_DMAENGINE_MPCM_DRV_NAME "snd_dmaengine_mpcm"
+#define I2S_TXFIFOLR			0xc
+#define I2S_RXFIFOLR			0x2c
+#define SAI_TXFIFOLR			0x1c
+#define SAI_RXFIFOLR			0x20
+
+/* XFL4 is compatible for old version */
+#define I2S_FIFOLR_XFL4(v)		(((v) & GENMASK(29, 24)) >> 24)
+#define I2S_FIFOLR_XFL3(v)		(((v) & GENMASK(23, 18)) >> 18)
+#define I2S_FIFOLR_XFL2(v)		(((v) & GENMASK(17, 12)) >> 12)
+#define I2S_FIFOLR_XFL1(v)		(((v) & GENMASK(11, 6)) >> 6)
+#define I2S_FIFOLR_XFL0(v)		(((v) & GENMASK(5, 0)) >> 0)
+
+/* XFIFOLR: Transfer / Receive FIFO Level Register */
+#define SAI_FIFOLR_XFL3(v)		(((v) & GENMASK(23, 18)) >> 18)
+#define SAI_FIFOLR_XFL2(v)		(((v) & GENMASK(17, 12)) >> 12)
+#define SAI_FIFOLR_XFL1(v)		(((v) & GENMASK(11, 6)) >> 6)
+#define SAI_FIFOLR_XFL0(v)		(((v) & GENMASK(5, 0)) >> 0)
+
+#define MAX_FIFO_SIZE			32 /* max fifo size in frames */
+#define SND_DMAENGINE_MPCM_DRV_NAME	"snd_dmaengine_mpcm"
 
 static unsigned int prealloc_buffer_size_kbytes = 512;
 module_param(prealloc_buffer_size_kbytes, uint, 0444);
 MODULE_PARM_DESC(prealloc_buffer_size_kbytes, "Preallocate DMA buffer size (KB).");
 
 struct dmaengine_mpcm {
+	struct dlp dlp;
 	struct rk_mdais_dev *mdais;
 	struct dma_chan *tx_chans[MAX_DAIS];
 	struct dma_chan *rx_chans[MAX_DAIS];
-	struct snd_soc_component component;
 };
 
 struct dmaengine_mpcm_runtime_data {
+	struct dlp_runtime_data drd;
 	struct dma_chan *chans[MAX_DAIS];
+	struct dma_interleaved_template *xt;
 	dma_cookie_t cookies[MAX_DAIS];
 	unsigned int *channel_maps;
 	int num_chans;
@@ -48,12 +69,17 @@
 static inline struct dmaengine_mpcm_runtime_data *substream_to_prtd(
 	const struct snd_pcm_substream *substream)
 {
-	return substream->runtime->private_data;
+	struct dlp_runtime_data *drd = substream_to_drd(substream);
+
+	if (!drd)
+		return NULL;
+
+	return container_of(drd, struct dmaengine_mpcm_runtime_data, drd);
 }
 
 static struct dmaengine_mpcm *soc_component_to_mpcm(struct snd_soc_component *p)
 {
-	return container_of(p, struct dmaengine_mpcm, component);
+	return container_of(soc_component_to_dlp(p), struct dmaengine_mpcm, dlp);
 }
 
 static struct dma_chan *to_chan(struct dmaengine_mpcm *pcm,
@@ -105,7 +131,20 @@
 {
 	struct snd_pcm_substream *substream = arg;
 #ifdef CONFIG_SND_SOC_ROCKCHIP_VAD
-	struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
+	struct dmaengine_mpcm_runtime_data *prtd;
+#endif
+	struct dlp_runtime_data *drd;
+	struct dlp *dlp;
+
+	snd_pcm_stream_lock_irq(substream);
+	if (!substream->runtime) {
+		snd_pcm_stream_unlock_irq(substream);
+		return;
+	}
+#ifdef CONFIG_SND_SOC_ROCKCHIP_VAD
+	prtd = substream_to_prtd(substream);
+	if (unlikely(!prtd))
+		return;
 
 	if (snd_pcm_vad_attached(substream) &&
 	    substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
@@ -120,12 +159,21 @@
 		prtd->pos = 0;
 
 #endif
+	drd = substream_to_drd(substream);
+	dlp = drd->parent;
+
+	dlp_dma_complete(dlp, drd);
+	snd_pcm_stream_unlock_irq(substream);
+
 	snd_pcm_period_elapsed(substream);
 }
 
 static void dmaengine_mpcm_get_master_chan(struct dmaengine_mpcm_runtime_data *prtd)
 {
 	int i;
+
+	if (unlikely(!prtd))
+		return;
 
 	for (i = prtd->num_chans; i > 0; i--) {
 		if (prtd->chans[i - 1]) {
@@ -135,33 +183,76 @@
 	}
 }
 
+static int dmaengine_config_interleaved(struct snd_pcm_substream *substream,
+					struct dma_interleaved_template *xt,
+					int offset, int sample_bytes, int nump, int numf)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int frame_bytes;
+
+	frame_bytes = frames_to_bytes(runtime, 1);
+
+	xt->frame_size = 1;
+	xt->sgl[0].size = sample_bytes;
+	xt->sgl[0].icg = frame_bytes - sample_bytes;
+
+#ifdef CONFIG_NO_GKI
+	xt->nump = nump;
+#endif
+	xt->numf = numf;
+
+	xt->dir = snd_pcm_substream_to_dma_direction(substream);
+
+	if (xt->dir == DMA_MEM_TO_DEV) {
+		xt->src_start = runtime->dma_addr + offset;
+		xt->src_inc = true;
+		xt->src_sgl = true;
+		xt->dst_inc = false;
+		xt->dst_sgl = false;
+	} else {
+		xt->dst_start = runtime->dma_addr + offset;
+		xt->src_inc = false;
+		xt->src_sgl = false;
+		xt->dst_inc = true;
+		xt->dst_sgl = true;
+	}
+
+	return 0;
+}
+
 static int dmaengine_mpcm_prepare_and_submit(struct snd_pcm_substream *substream)
 {
 	struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct dma_async_tx_descriptor *desc = NULL;
-	enum dma_transfer_direction direction;
+	struct dma_interleaved_template *xt;
 	unsigned long flags = DMA_CTRL_ACK;
-	unsigned int *maps = prtd->channel_maps;
-	int offset, buffer_bytes, period_bytes;
+	unsigned int *maps;
+	int offset;
 	int i;
 
-	direction = snd_pcm_substream_to_dma_direction(substream);
+	if (unlikely(!prtd || !runtime))
+		return -EINVAL;
 
 	if (!substream->runtime->no_period_wakeup)
 		flags |= DMA_PREP_INTERRUPT;
 
 	prtd->pos = 0;
 	offset = 0;
-	period_bytes = snd_pcm_lib_period_bytes(substream);
-	buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
+
+	xt = prtd->xt;
+	maps = prtd->channel_maps;
 	for (i = 0; i < prtd->num_chans; i++) {
 		if (!prtd->chans[i])
 			continue;
-		desc = dmaengine_prep_dma_cyclic(prtd->chans[i],
-						 runtime->dma_addr + offset,
-						 buffer_bytes, period_bytes,
-						 direction, flags);
+
+		dmaengine_config_interleaved(substream, xt, offset,
+					     samples_to_bytes(runtime, maps[i]),
+					     runtime->period_size,
+					     runtime->buffer_size);
+
+		desc = dmaengine_prep_interleaved_dma(prtd->chans[i], xt,
+						      flags | DMA_PREP_REPEAT);
 
 		if (!desc)
 			return -ENOMEM;
@@ -185,6 +276,9 @@
 {
 	int i;
 
+	if (unlikely(!prtd))
+		return;
+
 	for (i = 0; i < prtd->num_chans; i++) {
 		if (prtd->chans[i])
 			dma_async_issue_pending(prtd->chans[i]);
@@ -194,6 +288,9 @@
 static void mpcm_dmaengine_resume(struct dmaengine_mpcm_runtime_data *prtd)
 {
 	int i;
+
+	if (unlikely(!prtd))
+		return;
 
 	for (i = 0; i < prtd->num_chans; i++) {
 		if (prtd->chans[i])
@@ -205,6 +302,9 @@
 {
 	int i;
 
+	if (unlikely(!prtd))
+		return;
+
 	for (i = 0; i < prtd->num_chans; i++) {
 		if (prtd->chans[i])
 			dmaengine_pause(prtd->chans[i]);
@@ -214,6 +314,9 @@
 static void mpcm_dmaengine_terminate_all(struct dmaengine_mpcm_runtime_data *prtd)
 {
 	int i;
+
+	if (unlikely(!prtd))
+		return;
 
 	for (i = 0; i < prtd->num_chans; i++) {
 		if (prtd->chans[i])
@@ -228,6 +331,9 @@
 	struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
 	unsigned int pos, size;
 	void *buf;
+
+	if (unlikely(!prtd))
+		return;
 
 	if (snd_pcm_vad_attached(substream) &&
 	    substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
@@ -249,33 +355,39 @@
 }
 
 static int __mpcm_prepare_single_and_submit(struct snd_pcm_substream *substream,
-					    dma_addr_t buf_start, int size)
+					    int buf_offset, int size)
 {
 	struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
+	struct dma_interleaved_template *xt;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct dma_async_tx_descriptor *desc;
-	enum dma_transfer_direction direction;
 	unsigned long flags = DMA_CTRL_ACK;
-	unsigned int *maps = prtd->channel_maps;
+	unsigned int *maps;
 	int offset, i;
 	bool callback = false;
 
-	direction = snd_pcm_substream_to_dma_direction(substream);
+	if (unlikely(!prtd || !runtime))
+		return -EINVAL;
 
 	if (!substream->runtime->no_period_wakeup)
 		flags |= DMA_PREP_INTERRUPT;
 
-	offset = 0;
+	offset = buf_offset;
+	xt = prtd->xt;
+	maps = prtd->channel_maps;
 	for (i = 0; i < prtd->num_chans; i++) {
 		if (!prtd->chans[i])
 			continue;
-		desc = dmaengine_prep_slave_single(prtd->chans[i],
-						   buf_start + offset,
-						   size,
-						   direction, flags);
 
+		dmaengine_config_interleaved(substream, xt, offset,
+					     samples_to_bytes(runtime, maps[i]),
+					     0,
+					     bytes_to_frames(runtime, size));
+
+		desc = dmaengine_prep_interleaved_dma(prtd->chans[i], xt, flags);
 		if (!desc)
 			return -ENOMEM;
+
 		if (!callback) {
 			desc->callback = dmaengine_mpcm_single_dma_complete;
 			desc->callback_param = substream;
@@ -298,6 +410,9 @@
 	int offset, i, count, ret;
 	int buffer_bytes, period_bytes, residue_bytes;
 
+	if (unlikely(!prtd))
+		return -EINVAL;
+
 	direction = snd_pcm_substream_to_dma_direction(substream);
 
 	if (!substream->runtime->no_period_wakeup)
@@ -316,15 +431,15 @@
 	pr_debug("%s: offset: %d, buffer_bytes: %d\n", __func__, offset, buffer_bytes);
 	pr_debug("%s: count: %d, residue_bytes: %d\n", __func__, count, residue_bytes);
 	for (i = 0; i < count; i++) {
-		ret = __mpcm_prepare_single_and_submit(substream, buf_start,
+		ret = __mpcm_prepare_single_and_submit(substream, offset,
 						       period_bytes);
 		if (ret)
 			return ret;
-		buf_start += period_bytes;
+		offset += period_bytes;
 	}
 
 	if (residue_bytes) {
-		ret = __mpcm_prepare_single_and_submit(substream, buf_start,
+		ret = __mpcm_prepare_single_and_submit(substream, offset,
 						       residue_bytes);
 		if (ret)
 			return ret;
@@ -334,12 +449,50 @@
 }
 #endif
 
-static int snd_dmaengine_mpcm_trigger(struct snd_soc_component *component,
-				      struct snd_pcm_substream *substream, int cmd)
+static snd_pcm_uframes_t dmaengine_mpcm_raw_pointer(struct snd_soc_component *component,
+						    struct snd_pcm_substream *substream)
+{
+	struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
+	struct dma_tx_state state;
+	unsigned int buf_size;
+	unsigned int pos = 0;
+	unsigned int master;
+
+	if (unlikely(!prtd))
+		return 0;
+
+	master = prtd->master_chan;
+	buf_size = snd_pcm_lib_buffer_bytes(substream);
+	dmaengine_tx_status(prtd->chans[master], prtd->cookies[master], &state);
+	if (state.residue > 0 && state.residue <= buf_size)
+		pos = buf_size - state.residue;
+
+	return bytes_to_frames(substream->runtime, pos);
+}
+
+static int dmaengine_mpcm_dlp_start(struct snd_soc_component *component,
+				    struct snd_pcm_substream *substream)
+{
+	struct dmaengine_mpcm *pcm = soc_component_to_mpcm(component);
+
+	return dlp_start(component, substream, pcm->mdais->dev, dmaengine_mpcm_raw_pointer);
+}
+
+static void dmaengine_mpcm_dlp_stop(struct snd_soc_component *component,
+				       struct snd_pcm_substream *substream)
+{
+	dlp_stop(component, substream, dmaengine_mpcm_raw_pointer);
+}
+
+static int dmaengine_mpcm_trigger(struct snd_soc_component *component,
+				  struct snd_pcm_substream *substream, int cmd)
 {
 	struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	int ret;
+
+	if (unlikely(!prtd || !runtime))
+		return -EINVAL;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -355,16 +508,19 @@
 		if (ret)
 			return ret;
 		mpcm_dma_async_issue_pending(prtd);
+		dmaengine_mpcm_dlp_start(component, substream);
 		break;
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		mpcm_dmaengine_resume(prtd);
 		break;
 	case SNDRV_PCM_TRIGGER_SUSPEND:
-		if (runtime->info & SNDRV_PCM_INFO_PAUSE)
+		if (runtime->info & SNDRV_PCM_INFO_PAUSE) {
 			mpcm_dmaengine_pause(prtd);
-		else
+		} else {
+			dmaengine_mpcm_dlp_stop(component, substream);
 			mpcm_dmaengine_terminate_all(prtd);
+		}
 		prtd->start_flag = false;
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
@@ -372,6 +528,7 @@
 		prtd->start_flag = false;
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
+		dmaengine_mpcm_dlp_stop(component, substream);
 		mpcm_dmaengine_terminate_all(prtd);
 		prtd->start_flag = false;
 		break;
@@ -423,22 +580,12 @@
 		sz = snd_pcm_format_size(format, maps[i]);
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 			chan = pcm->tx_chans[i];
-#ifdef CONFIG_NO_GKI
-			if (sz) {
-				slave_config.src_interlace_size = frame_bytes - sz;
-				if (slave_config.src_interlace_size)
-					slave_config.dst_maxburst = sz / slave_config.dst_addr_width;
-			}
-#endif
+			if (sz && (frame_bytes - sz) > 0)
+				slave_config.dst_maxburst = sz / slave_config.dst_addr_width;
 		} else {
 			chan = pcm->rx_chans[i];
-#ifdef CONFIG_NO_GKI
-			if (sz) {
-				slave_config.dst_interlace_size = frame_bytes - sz;
-				if (slave_config.dst_interlace_size)
-					slave_config.src_maxburst = sz / slave_config.src_addr_width;
-			}
-#endif
+			if (sz && (frame_bytes - sz) > 0)
+				slave_config.src_maxburst = sz / slave_config.src_addr_width;
 		}
 		if (!chan)
 			continue;
@@ -447,6 +594,11 @@
 		if (ret)
 			return ret;
 	}
+
+	ret = dlp_hw_params(component, substream, params);
+	if (ret)
+		return ret;
+
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
 }
 
@@ -467,12 +619,12 @@
 	int ret;
 
 	chan = to_chan(pcm, substream);
-	if (!chan)
+	if (!chan || !dma_dev)
 		return -EINVAL;
 
 	memset(&hw, 0, sizeof(hw));
 	hw.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
-			SNDRV_PCM_INFO_INTERLEAVED;
+		  SNDRV_PCM_INFO_INTERLEAVED;
 	hw.periods_min = 2;
 	hw.periods_max = UINT_MAX;
 	hw.period_bytes_min = 256;
@@ -542,6 +694,13 @@
 	if (!prtd)
 		return -ENOMEM;
 
+	prtd->xt = kzalloc(sizeof(struct dma_interleaved_template) +
+			   sizeof(struct data_chunk), GFP_KERNEL);
+	if (!prtd->xt) {
+		kfree(prtd);
+		return -ENOMEM;
+	}
+
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		prtd->channel_maps = pcm->mdais->playback_channel_maps;
 		for (i = 0; i < pcm->mdais->num_dais; i++)
@@ -554,7 +713,8 @@
 
 	prtd->num_chans = pcm->mdais->num_dais;
 	prtd->start_flag = false;
-	substream->runtime->private_data = prtd;
+
+	dlp_open(&pcm->dlp, &prtd->drd, substream);
 
 	return 0;
 }
@@ -563,6 +723,7 @@
 {
 	struct dmaengine_mpcm *pcm = soc_component_to_mpcm(component);
 	struct snd_pcm_substream *substream;
+	struct device *dma_dev;
 	size_t prealloc_buffer_size;
 	size_t max_buffer_size;
 	unsigned int i;
@@ -575,9 +736,15 @@
 		if (!substream)
 			continue;
 
+		dma_dev = dmaengine_dma_dev(pcm, substream);
+		if (!dma_dev) {
+			dev_err(component->dev, "No chan found, should assign 'rockchip,no-dmaengine' in DT\n");
+			return -EINVAL;
+		}
+
 		snd_pcm_lib_preallocate_pages(substream,
 					      SNDRV_DMA_TYPE_DEV_IRAM,
-					      dmaengine_dma_dev(pcm, substream),
+					      dma_dev,
 					      prealloc_buffer_size,
 					      max_buffer_size);
 	}
@@ -594,8 +761,12 @@
 	snd_pcm_uframes_t frames;
 	unsigned int buf_size;
 	unsigned int pos = 0;
-	unsigned int master = prtd->master_chan;
+	unsigned int master;
 
+	if (unlikely(!prtd || !runtime))
+		return 0;
+
+	master = prtd->master_chan;
 	buf_size = snd_pcm_lib_buffer_bytes(substream);
 	dmaengine_tx_status(prtd->chans[master], prtd->cookies[master], &state);
 	if (state.residue > 0 && state.residue <= buf_size)
@@ -640,24 +811,54 @@
 static int dmaengine_mpcm_close(struct snd_soc_component *component,
 				struct snd_pcm_substream *substream)
 {
+	struct dmaengine_mpcm *pcm = soc_component_to_mpcm(component);
 	struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
 
+	if (unlikely(!prtd))
+		return -EINVAL;
+
+	dlp_close(&pcm->dlp, &prtd->drd, substream);
+
+	kfree(prtd->xt);
 	kfree(prtd);
 
 	return 0;
 }
 
+static int dmaengine_mpcm_copy_user(struct snd_soc_component *component,
+				    struct snd_pcm_substream *substream,
+				    int channel, unsigned long hwoff,
+				    void __user *buf, unsigned long bytes)
+{
+	return dlp_copy_user(component, substream, channel, hwoff, buf, bytes);
+}
+
+
+static int dmaengine_mpcm_prepare(struct snd_soc_component *component,
+				  struct snd_pcm_substream *substream)
+{
+	return dlp_prepare(component, substream);
+}
+
+static int dmaengine_mpcm_probe(struct snd_soc_component *component)
+{
+	return dlp_probe(component);
+}
+
 static const struct snd_soc_component_driver dmaengine_mpcm_platform = {
 	.name		= SND_DMAENGINE_MPCM_DRV_NAME,
 	.probe_order	= SND_SOC_COMP_ORDER_LATE,
+	.probe		= dmaengine_mpcm_probe,
 	.pcm_construct	= dmaengine_mpcm_new,
 	.open		= dmaengine_mpcm_open,
 	.close		= dmaengine_mpcm_close,
 	.ioctl		= dmaengine_mpcm_ioctl,
 	.hw_params	= dmaengine_mpcm_hw_params,
 	.hw_free	= dmaengine_mpcm_hw_free,
-	.trigger	= snd_dmaengine_mpcm_trigger,
+	.prepare	= dmaengine_mpcm_prepare,
+	.trigger	= dmaengine_mpcm_trigger,
 	.pointer	= dmaengine_mpcm_pointer,
+	.copy_user	= dmaengine_mpcm_copy_user,
 };
 
 static void dmaengine_mpcm_release_chan(struct dmaengine_mpcm *pcm)
@@ -671,6 +872,55 @@
 			dma_release_channel(pcm->rx_chans[i]);
 	}
 }
+
+static int dmaengine_mpcm_get_fifo_count(struct device *dev,
+					 struct snd_pcm_substream *substream)
+{
+	struct rk_mdais_dev *mdais = dev_get_drvdata(dev);
+	struct dmaengine_mpcm_runtime_data *prtd = substream_to_prtd(substream);
+	struct snd_soc_component *component;
+	unsigned int tx, rx, reg;
+	int val = 0;
+
+	if (unlikely(!prtd))
+		return -EINVAL;
+
+	component = mdais->dais[prtd->master_chan].dai->component;
+	if (unlikely(!component))
+		return -EINVAL;
+
+	if (strstr(dev_driver_string(component->dev), "i2s")) {
+		/* compatible for both I2S and I2STDM controller */
+		tx = snd_soc_component_read(component, I2S_TXFIFOLR);
+		rx = snd_soc_component_read(component, I2S_RXFIFOLR);
+
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			val = I2S_FIFOLR_XFL3(tx) +
+			      I2S_FIFOLR_XFL2(tx) +
+			      I2S_FIFOLR_XFL1(tx) +
+			      I2S_FIFOLR_XFL0(tx);
+		else
+			/* XFL4 is compatible for old version */
+			val = I2S_FIFOLR_XFL4(tx) +
+			      I2S_FIFOLR_XFL3(rx) +
+			      I2S_FIFOLR_XFL2(rx) +
+			      I2S_FIFOLR_XFL1(rx) +
+			      I2S_FIFOLR_XFL0(rx);
+	} else if (strstr(dev_driver_string(component->dev), "sai")) {
+		reg = substream->stream ? SAI_RXFIFOLR : SAI_TXFIFOLR;
+
+		val = SAI_FIFOLR_XFL3(reg) +
+		      SAI_FIFOLR_XFL2(reg) +
+		      SAI_FIFOLR_XFL1(reg) +
+		      SAI_FIFOLR_XFL0(reg);
+	}
+
+	return val;
+}
+
+static const struct snd_dlp_config dconfig = {
+	.get_fifo_count = dmaengine_mpcm_get_fifo_count,
+};
 
 int snd_dmaengine_mpcm_register(struct rk_mdais_dev *mdais)
 {
@@ -689,9 +939,6 @@
 	if (!pcm)
 		return -ENOMEM;
 
-#ifdef CONFIG_DEBUG_FS
-	pcm->component.debugfs_prefix = "dma";
-#endif
 	pcm->mdais = mdais;
 	for (i = 0; i < num; i++) {
 		child = mdais->dais[i].dev;
@@ -710,12 +957,7 @@
 		}
 	}
 
-	ret = snd_soc_component_initialize(&pcm->component, &dmaengine_mpcm_platform,
-					   dev);
-	if (ret)
-		goto err_free_dma;
-
-	ret = snd_soc_add_component(&pcm->component, NULL, 0);
+	ret = dlp_register(&pcm->dlp, dev, &dmaengine_mpcm_platform, &dconfig);
 	if (ret)
 		goto err_free_dma;
 
diff --git a/kernel/sound/soc/rockchip/rockchip_multicodecs.c b/kernel/sound/soc/rockchip/rockchip_multicodecs.c
index f7982ad..e4b0a15 100644
--- a/kernel/sound/soc/rockchip/rockchip_multicodecs.c
+++ b/kernel/sound/soc/rockchip/rockchip_multicodecs.c
@@ -456,9 +456,6 @@
 				dev_err(card->dev, "Failed to request headset detect irq");
 				return ret;
 			}
-
-			queue_delayed_work(system_power_efficient_wq,
-					   &mc_data->handler, msecs_to_jiffies(50));
 		}
 	}
 
@@ -590,7 +587,7 @@
 	struct device_node *node;
 	struct input_dev *input;
 	u32 val;
-	int count, value;
+	int count, value, irq;
 	int ret = 0, i = 0, idx = 0;
 	const char *prefix = "rockchip,";
 
@@ -722,7 +719,7 @@
 
 		input = devm_input_allocate_device(&pdev->dev);
 		if (IS_ERR(input)) {
-			dev_err(&pdev->dev, "failed to allocate input device\n");
+			dev_err(&pdev->dev, "Failed to allocate input device\n");
 			return PTR_ERR(input);
 		}
 
@@ -745,7 +742,7 @@
 		mc_data->input = input;
 		ret = mc_keys_setup_polling(mc_data, mc_keys_poll);
 		if (ret) {
-			dev_err(&pdev->dev, "Unable to set up polling: %d\n", ret);
+			dev_err(&pdev->dev, "Failed to set up polling: %d\n", ret);
 			return ret;
 		}
 
@@ -754,7 +751,7 @@
 
 		ret = input_register_device(mc_data->input);
 		if (ret) {
-			dev_err(&pdev->dev, "Unable to register input device: %d\n", ret);
+			dev_err(&pdev->dev, "Failed to register input device: %d\n", ret);
 			return ret;
 		}
 	}
@@ -779,33 +776,51 @@
 
 	mc_data->extcon = devm_extcon_dev_allocate(&pdev->dev, headset_extcon_cable);
 	if (IS_ERR(mc_data->extcon)) {
-		dev_err(&pdev->dev, "allocate extcon failed\n");
+		dev_err(&pdev->dev, "Failed to allocate extcon\n");
 		return PTR_ERR(mc_data->extcon);
 	}
 
 	ret = devm_extcon_dev_register(&pdev->dev, mc_data->extcon);
 	if (ret) {
-		dev_err(&pdev->dev, "failed to register extcon: %d\n", ret);
+		dev_err(&pdev->dev, "Failed to register extcon: %d\n", ret);
 		return ret;
 	}
 
-	ret = snd_soc_of_parse_audio_routing(card, "rockchip,audio-routing");
-	if (ret < 0)
-		dev_warn(&pdev->dev, "Audio routing invalid/unspecified\n");
+	snd_soc_of_parse_audio_routing(card, "rockchip,audio-routing");
 
 	snd_soc_card_set_drvdata(card, mc_data);
+	platform_set_drvdata(pdev, card);
 
 	ret = devm_snd_soc_register_card(&pdev->dev, card);
-	if (ret == -EPROBE_DEFER)
-		return -EPROBE_DEFER;
 	if (ret) {
-		dev_err(&pdev->dev, "card register failed %d\n", ret);
+		dev_err(&pdev->dev, "Failed to register card: %d\n", ret);
 		return ret;
 	}
 
-	platform_set_drvdata(pdev, card);
+	irq = gpiod_to_irq(mc_data->hp_det_gpio);
+	if (irq >= 0)
+		queue_delayed_work(system_power_efficient_wq,
+				   &mc_data->handler, msecs_to_jiffies(50));
 
 	return ret;
+}
+
+static int rk_multicodec_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+	struct multicodecs_data *mc_data = snd_soc_card_get_drvdata(card);
+
+	cancel_delayed_work_sync(&mc_data->handler);
+
+	return 0;
+}
+
+static void rk_multicodec_shutdown(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+	struct multicodecs_data *mc_data = snd_soc_card_get_drvdata(card);
+
+	cancel_delayed_work_sync(&mc_data->handler);
 }
 
 static const struct of_device_id rockchip_multicodecs_of_match[] = {
@@ -817,6 +832,8 @@
 
 static struct platform_driver rockchip_multicodecs_driver = {
 	.probe = rk_multicodecs_probe,
+	.remove = rk_multicodec_remove,
+	.shutdown = rk_multicodec_shutdown,
 	.driver = {
 		.name = DRV_NAME,
 		.pm = &snd_soc_pm_ops,
diff --git a/kernel/sound/soc/rockchip/rockchip_pdm.c b/kernel/sound/soc/rockchip/rockchip_pdm.c
index 43c954d..ad5e8b7 100644
--- a/kernel/sound/soc/rockchip/rockchip_pdm.c
+++ b/kernel/sound/soc/rockchip/rockchip_pdm.c
@@ -31,8 +31,10 @@
 #define PDM_FILTER_DELAY_MS_MIN		(20)
 #define PDM_FILTER_DELAY_MS_MAX		(1000)
 #define PDM_CLK_SHIFT_PPM_MAX		(1000000) /* 1 ppm */
-#define CLK_PPM_MIN		(-1000)
-#define CLK_PPM_MAX		(1000)
+#define CLK_PPM_MIN			(-1000)
+#define CLK_PPM_MAX			(1000)
+
+#define QUIRK_ALWAYS_ON			BIT(0)
 
 enum rk_pdm_version {
 	RK_PDM_RK3229,
@@ -56,6 +58,7 @@
 	enum rk_pdm_version version;
 	unsigned int clk_root_rate;
 	unsigned int clk_root_initial_rate;
+	unsigned int quirks;
 	int clk_ppm;
 	bool clk_calibrate;
 };
@@ -95,6 +98,16 @@
 	{ 4, 12000 },
 	{ 4, 11025 },
 	{ 4, 8000 },
+};
+
+static const struct pdm_of_quirks {
+	char *quirk;
+	int id;
+} of_quirks[] = {
+	{
+		.quirk = "rockchip,always-on",
+		.id = QUIRK_ALWAYS_ON,
+	},
 };
 
 static unsigned int get_pdm_clk(struct rk_pdm_dev *pdm, unsigned int sr,
@@ -508,8 +521,8 @@
 static int rockchip_pdm_start_delay_get(struct snd_kcontrol *kcontrol,
 					struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
-	struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct rk_pdm_dev *pdm = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = pdm->start_delay_ms;
 
@@ -519,8 +532,8 @@
 static int rockchip_pdm_start_delay_put(struct snd_kcontrol *kcontrol,
 					struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
-	struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct rk_pdm_dev *pdm = snd_soc_component_get_drvdata(component);
 
 	if ((ucontrol->value.integer.value[0] < PDM_START_DELAY_MS_MIN) ||
 	    (ucontrol->value.integer.value[0] > PDM_START_DELAY_MS_MAX))
@@ -546,8 +559,8 @@
 static int rockchip_pdm_filter_delay_get(struct snd_kcontrol *kcontrol,
 					 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
-	struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct rk_pdm_dev *pdm = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = pdm->filter_delay_ms;
 
@@ -557,8 +570,8 @@
 static int rockchip_pdm_filter_delay_put(struct snd_kcontrol *kcontrol,
 					 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
-	struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct rk_pdm_dev *pdm = snd_soc_component_get_drvdata(component);
 
 	if ((ucontrol->value.integer.value[0] < PDM_FILTER_DELAY_MS_MIN) ||
 	    (ucontrol->value.integer.value[0] > PDM_FILTER_DELAY_MS_MAX))
@@ -577,11 +590,22 @@
 static SOC_ENUM_SINGLE_DECL(rpath1_enum, PDM_CLK_CTRL, 10, rpaths_text);
 static SOC_ENUM_SINGLE_DECL(rpath0_enum, PDM_CLK_CTRL, 8, rpaths_text);
 
+static const char * const hpf_cutoff_text[] = {
+	"3.79Hz", "60Hz", "243Hz", "493Hz",
+};
+
+static SOC_ENUM_SINGLE_DECL(hpf_cutoff_enum, PDM_HPF_CTRL,
+			    0, hpf_cutoff_text);
+
 static const struct snd_kcontrol_new rockchip_pdm_controls[] = {
 	SOC_ENUM("Receive PATH3 Source Select", rpath3_enum),
 	SOC_ENUM("Receive PATH2 Source Select", rpath2_enum),
 	SOC_ENUM("Receive PATH1 Source Select", rpath1_enum),
 	SOC_ENUM("Receive PATH0 Source Select", rpath0_enum),
+
+	SOC_ENUM("HPF Cutoff", hpf_cutoff_enum),
+	SOC_SINGLE("HPFL Switch", PDM_HPF_CTRL, 3, 1, 0),
+	SOC_SINGLE("HPFR Switch", PDM_HPF_CTRL, 2, 1, 0),
 
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -616,8 +640,8 @@
 					     struct snd_ctl_elem_value *ucontrol)
 
 {
-	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
-	struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct rk_pdm_dev *pdm = snd_soc_component_get_drvdata(component);
 
 	ucontrol->value.integer.value[0] = pdm->clk_ppm;
 
@@ -627,8 +651,8 @@
 static int rockchip_pdm_clk_compensation_put(struct snd_kcontrol *kcontrol,
 					     struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
-	struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
+	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+	struct rk_pdm_dev *pdm = snd_soc_component_get_drvdata(component);
 
 	int ppm = ucontrol->value.integer.value[0];
 
@@ -946,6 +970,29 @@
 	return 0;
 }
 
+static int rockchip_pdm_keep_clk_always_on(struct rk_pdm_dev *pdm)
+{
+	pm_runtime_forbid(pdm->dev);
+
+	dev_info(pdm->dev, "CLK-ALWAYS-ON: samplerate: %d\n", PDM_DEFAULT_RATE);
+
+	return 0;
+}
+
+static int rockchip_pdm_parse_quirks(struct rk_pdm_dev *pdm)
+{
+	int ret = 0, i = 0;
+
+	for (i = 0; i < ARRAY_SIZE(of_quirks); i++)
+		if (device_property_read_bool(pdm->dev, of_quirks[i].quirk))
+			pdm->quirks |= of_quirks[i].id;
+
+	if (pdm->quirks & QUIRK_ALWAYS_ON)
+		ret = rockchip_pdm_keep_clk_always_on(pdm);
+
+	return ret;
+}
+
 static int rockchip_pdm_probe(struct platform_device *pdev)
 {
 	struct device_node *node = pdev->dev.of_node;
@@ -1027,6 +1074,10 @@
 	if (ret != 0 && ret != -ENOENT)
 		goto err_clk;
 
+	ret = rockchip_pdm_parse_quirks(pdm);
+	if (ret)
+		goto err_clk;
+
 	/*
 	 * MUST: after pm_runtime_enable step, any register R/W
 	 * should be wrapped with pm_runtime_get_sync/put.
diff --git a/kernel/sound/soc/rockchip/rockchip_sai.c b/kernel/sound/soc/rockchip/rockchip_sai.c
index 6609c1f..c3e0006 100644
--- a/kernel/sound/soc/rockchip/rockchip_sai.c
+++ b/kernel/sound/soc/rockchip/rockchip_sai.c
@@ -19,10 +19,12 @@
 #include <sound/tlv.h>
 
 #include "rockchip_sai.h"
+#include "rockchip_dlp_pcm.h"
+#include "rockchip_utils.h"
 
 #define DRV_NAME		"rockchip-sai"
 
-#define CLK_SHIFT_RATE_HZ_MAX	1 /* 1 Hz */
+#define CLK_SHIFT_RATE_HZ_MAX	5
 #define FW_RATIO_MAX		8
 #define FW_RATIO_MIN		1
 #define MAXBURST_PER_FIFO	8
@@ -422,23 +424,27 @@
 {
 	struct rk_sai_dev *sai = snd_soc_dai_get_drvdata(dai);
 	struct snd_dmaengine_dai_dma_data *dma_data;
-	unsigned int mclk_rate, bclk_rate, div_bclk;
+	unsigned int mclk_rate, mclk_req_rate, bclk_rate, div_bclk;
 	unsigned int ch_per_lane, lanes, slot_width;
-	unsigned int val, fscr, reg;
+	unsigned int val, fscr, reg, fifo;
 
 	dma_data = snd_soc_dai_get_dma_data(dai, substream);
 	dma_data->maxburst = MAXBURST_PER_FIFO * params_channels(params) / 2;
 
 	lanes = rockchip_sai_lanes_auto(params, dai);
 
+	regmap_read(sai->regmap, SAI_DMACR, &val);
+
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		reg = SAI_TXCR;
 		if (sai->tx_lanes)
 			lanes = sai->tx_lanes;
+		fifo = SAI_DMACR_TDL_V(val) * lanes;
 	} else {
 		reg = SAI_RXCR;
 		if (sai->rx_lanes)
 			lanes = sai->rx_lanes;
+		fifo = SAI_DMACR_TDL_V(val) * lanes;
 	}
 
 	switch (params_format(params)) {
@@ -497,18 +503,29 @@
 		if (sai->is_clk_auto)
 			clk_set_rate(sai->mclk, bclk_rate);
 		mclk_rate = clk_get_rate(sai->mclk);
-		if (mclk_rate < bclk_rate - CLK_SHIFT_RATE_HZ_MAX ||
-		    mclk_rate > bclk_rate + CLK_SHIFT_RATE_HZ_MAX) {
+		div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);
+		mclk_req_rate = bclk_rate * div_bclk;
+
+		if (mclk_rate < mclk_req_rate - CLK_SHIFT_RATE_HZ_MAX ||
+		    mclk_rate > mclk_req_rate + CLK_SHIFT_RATE_HZ_MAX) {
 			dev_err(sai->dev, "Mismatch mclk: %u, expected %u (+/- %dHz)\n",
-				mclk_rate, bclk_rate, CLK_SHIFT_RATE_HZ_MAX);
+				mclk_rate, mclk_req_rate, CLK_SHIFT_RATE_HZ_MAX);
 			return -EINVAL;
 		}
-
-		div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);
 
 		regmap_update_bits(sai->regmap, SAI_CKR, SAI_CKR_MDIV_MASK,
 				   SAI_CKR_MDIV(div_bclk));
 	}
+
+	rockchip_utils_get_performance(substream, params, dai, fifo);
+
+	return 0;
+}
+
+static int rockchip_sai_hw_free(struct snd_pcm_substream *substream,
+				struct snd_soc_dai *dai)
+{
+	rockchip_utils_put_performance(substream, dai);
 
 	return 0;
 }
@@ -639,6 +656,7 @@
 	.startup = rockchip_sai_startup,
 	.shutdown = rockchip_sai_shutdown,
 	.hw_params = rockchip_sai_hw_params,
+	.hw_free = rockchip_sai_hw_free,
 	.set_sysclk = rockchip_sai_set_sysclk,
 	.set_fmt = rockchip_sai_set_fmt,
 	.prepare = rockchip_sai_prepare,
@@ -879,39 +897,39 @@
 	"From PATH0", "From PATH1", "From PATH2", "From PATH3" };
 
 /* TXCR */
-static SOC_ENUM_SINGLE_DECL(tsft_enum, SAI_TXCR, 22, edge_shift_text);
+static SOC_ENUM_SINGLE_DECL(__maybe_unused tsft_enum, SAI_TXCR, 22, edge_shift_text);
 static const struct soc_enum tx_lanes_enum =
 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tx_lanes_text), tx_lanes_text);
-static SOC_ENUM_SINGLE_DECL(tsjm_enum, SAI_TXCR, 19, sjm_text);
-static SOC_ENUM_SINGLE_DECL(tfbm_enum, SAI_TXCR, 18, fbm_text);
-static SOC_ENUM_SINGLE_DECL(tvdj_enum, SAI_TXCR, 10, vdj_text);
-static SOC_ENUM_SINGLE_DECL(tsbw_enum, SAI_TXCR,  5, sbw_text);
+static SOC_ENUM_SINGLE_DECL(__maybe_unused tsjm_enum, SAI_TXCR, 19, sjm_text);
+static SOC_ENUM_SINGLE_DECL(__maybe_unused tfbm_enum, SAI_TXCR, 18, fbm_text);
+static SOC_ENUM_SINGLE_DECL(__maybe_unused tvdj_enum, SAI_TXCR, 10, vdj_text);
+static SOC_ENUM_SINGLE_DECL(__maybe_unused tsbw_enum, SAI_TXCR,  5, sbw_text);
 
 /* FSCR */
-static SOC_ENUM_SINGLE_DECL(edge_enum, SAI_FSCR, 24, edge_text);
-static const struct soc_enum fpw_enum =
+static SOC_ENUM_SINGLE_DECL(__maybe_unused edge_enum, SAI_FSCR, 24, edge_text);
+static const struct soc_enum __maybe_unused fpw_enum =
 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(fpw_text), fpw_text);
-static const struct soc_enum fw_ratio_enum =
+static const struct soc_enum __maybe_unused fw_ratio_enum =
 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(fw_ratio_text), fw_ratio_text);
 
 /* RXCR */
-static SOC_ENUM_SINGLE_DECL(rsft_enum, SAI_RXCR, 22, edge_shift_text);
+static SOC_ENUM_SINGLE_DECL(__maybe_unused rsft_enum, SAI_RXCR, 22, edge_shift_text);
 static const struct soc_enum rx_lanes_enum =
 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_lanes_text), rx_lanes_text);
-static SOC_ENUM_SINGLE_DECL(rsjm_enum, SAI_RXCR, 19, sjm_text);
-static SOC_ENUM_SINGLE_DECL(rfbm_enum, SAI_RXCR, 18, fbm_text);
-static SOC_ENUM_SINGLE_DECL(rvdj_enum, SAI_RXCR, 10, vdj_text);
-static SOC_ENUM_SINGLE_DECL(rsbw_enum, SAI_RXCR,  5, sbw_text);
+static SOC_ENUM_SINGLE_DECL(__maybe_unused rsjm_enum, SAI_RXCR, 19, sjm_text);
+static SOC_ENUM_SINGLE_DECL(__maybe_unused rfbm_enum, SAI_RXCR, 18, fbm_text);
+static SOC_ENUM_SINGLE_DECL(__maybe_unused rvdj_enum, SAI_RXCR, 10, vdj_text);
+static SOC_ENUM_SINGLE_DECL(__maybe_unused rsbw_enum, SAI_RXCR,  5, sbw_text);
 
 /* MONO_CR */
 static SOC_ENUM_SINGLE_DECL(rmono_switch, SAI_MONO_CR, 1, mono_text);
 static SOC_ENUM_SINGLE_DECL(tmono_switch, SAI_MONO_CR, 0, mono_text);
 
 /* CKR */
-static const struct soc_enum mss_switch =
+static const struct soc_enum __maybe_unused mss_switch =
 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mss_text), mss_text);
-static SOC_ENUM_SINGLE_DECL(sp_switch,  SAI_CKR, 1, ckp_text);
-static SOC_ENUM_SINGLE_DECL(fp_switch,  SAI_CKR, 0, ckp_text);
+static SOC_ENUM_SINGLE_DECL(__maybe_unused sp_switch,  SAI_CKR, 1, ckp_text);
+static SOC_ENUM_SINGLE_DECL(__maybe_unused fp_switch,  SAI_CKR, 0, ckp_text);
 
 /* PATH_SEL */
 static SOC_ENUM_SINGLE_DECL(lp3_enum, SAI_PATH_SEL, 28, lpx_text);
@@ -1344,6 +1362,29 @@
 	return ret;
 }
 
+static int rockchip_sai_get_fifo_count(struct device *dev,
+				       struct snd_pcm_substream *substream)
+{
+	struct rk_sai_dev *sai = dev_get_drvdata(dev);
+	int val = 0;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		regmap_read(sai->regmap, SAI_TXFIFOLR, &val);
+	else
+		regmap_read(sai->regmap, SAI_RXFIFOLR, &val);
+
+	val = ((val & SAI_FIFOLR_XFL3_MASK) >> SAI_FIFOLR_XFL3_SHIFT) +
+	      ((val & SAI_FIFOLR_XFL2_MASK) >> SAI_FIFOLR_XFL2_SHIFT) +
+	      ((val & SAI_FIFOLR_XFL1_MASK) >> SAI_FIFOLR_XFL1_SHIFT) +
+	      ((val & SAI_FIFOLR_XFL0_MASK) >> SAI_FIFOLR_XFL0_SHIFT);
+
+	return val;
+}
+
+static const struct snd_dlp_config dconfig = {
+	.get_fifo_count = rockchip_sai_get_fifo_count,
+};
+
 static int rockchip_sai_probe(struct platform_device *pdev)
 {
 	struct device_node *node = pdev->dev.of_node;
@@ -1438,7 +1479,11 @@
 		return 0;
 	}
 
-	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+	if (device_property_read_bool(&pdev->dev, "rockchip,digital-loopback"))
+		ret = devm_snd_dmaengine_dlp_register(&pdev->dev, &dconfig);
+	else
+		ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+
 	if (ret)
 		goto err_runtime_suspend;
 
diff --git a/kernel/sound/soc/rockchip/rockchip_sai.h b/kernel/sound/soc/rockchip/rockchip_sai.h
index c720fc8..58e3aa5 100644
--- a/kernel/sound/soc/rockchip/rockchip_sai.h
+++ b/kernel/sound/soc/rockchip/rockchip_sai.h
@@ -97,10 +97,12 @@
 #define SAI_DMACR_RDE(x)		((x) << 24)
 #define SAI_DMACR_RDL_MASK		GENMASK(20, 16)
 #define SAI_DMACR_RDL(x)		((x - 1) << 16)
+#define SAI_DMACR_RDL_V(v)		((((v) & SAI_DMACR_RDL_MASK) >> 16) + 1)
 #define SAI_DMACR_TDE_MASK		BIT(8)
 #define SAI_DMACR_TDE(x)		((x) << 8)
 #define SAI_DMACR_TDL_MASK		GENMASK(4, 0)
 #define SAI_DMACR_TDL(x)		((x) << 0)
+#define SAI_DMACR_TDL_V(v)		(((v) & SAI_DMACR_TDL_MASK) >> 0)
 
 /* INTCR Interrupt Ctrl Register */
 #define SAI_INTCR_RXOIC			BIT(18)
@@ -120,6 +122,16 @@
 #define SAI_XSHIFT_SEL_MASK		GENMASK(23, 0)
 #define SAI_XSHIFT_SEL(x)		(x)
 
+/* XFIFOLR: Transfer / Receive FIFO Level Register */
+#define SAI_FIFOLR_XFL3_SHIFT		18
+#define SAI_FIFOLR_XFL3_MASK		GENMASK(23, 18)
+#define SAI_FIFOLR_XFL2_SHIFT		12
+#define SAI_FIFOLR_XFL2_MASK		GENMASK(17, 12)
+#define SAI_FIFOLR_XFL1_SHIFT		6
+#define SAI_FIFOLR_XFL1_MASK		GENMASK(11, 6)
+#define SAI_FIFOLR_XFL0_SHIFT		0
+#define SAI_FIFOLR_XFL0_MASK		GENMASK(5, 0)
+
 /* SAI Registers */
 #define SAI_TXCR			(0x0000)
 #define SAI_FSCR			(0x0004)
diff --git a/kernel/sound/soc/rockchip/rockchip_spdif.c b/kernel/sound/soc/rockchip/rockchip_spdif.c
index af5203b..04d26d1 100644
--- a/kernel/sound/soc/rockchip/rockchip_spdif.c
+++ b/kernel/sound/soc/rockchip/rockchip_spdif.c
@@ -109,6 +109,7 @@
 
 	ret = clk_prepare_enable(spdif->hclk);
 	if (ret) {
+		clk_disable_unprepare(spdif->mclk);
 		dev_err(spdif->dev, "hclk clock enable failed %d\n", ret);
 		return ret;
 	}
diff --git a/kernel/sound/soc/rockchip/rockchip_utils.c b/kernel/sound/soc/rockchip/rockchip_utils.c
new file mode 100644
index 0000000..6e81dab
--- /dev/null
+++ b/kernel/sound/soc/rockchip/rockchip_utils.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Rockchip Utils API
+ *
+ * Copyright (c) 2023 Rockchip Electronics Co. Ltd.
+ */
+
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <soc/rockchip/rockchip_dmc.h>
+#include <soc/rockchip/rockchip-system-status.h>
+#include <sound/pcm_params.h>
+#include <sound/dmaengine_pcm.h>
+#include "rockchip_utils.h"
+
+#define DMC_STALL_TIME_US_DEFAULT	100
+#define TIME_MARGIN_US			20
+
+static DEFINE_MUTEX(list_mutex);
+static LIST_HEAD(substream_ref_list);
+
+struct substream_ref {
+	struct list_head node;
+	struct snd_pcm_substream *substream;
+};
+
+static int substream_ref_new(struct snd_pcm_substream *substream)
+{
+	struct substream_ref *ref = NULL;
+	bool found = false;
+	int ret = 0;
+
+	mutex_lock(&list_mutex);
+	list_for_each_entry(ref, &substream_ref_list, node) {
+		if (ref->substream == substream) {
+			found = true;
+			break;
+		}
+	}
+
+	if (found) {
+		ret = -EEXIST;
+		goto _err_unlock;
+	}
+
+	ref = kzalloc(sizeof(*ref), GFP_KERNEL);
+	if (!ref) {
+		ret = -ENOMEM;
+		goto _err_unlock;
+	}
+
+	ref->substream = substream;
+
+	list_add(&ref->node, &substream_ref_list);
+
+_err_unlock:
+	mutex_unlock(&list_mutex);
+
+	return ret;
+}
+
+static bool substream_ref_found(struct snd_pcm_substream *substream)
+{
+	struct substream_ref *ref = NULL, *_ref = NULL;
+	bool found = false;
+
+	mutex_lock(&list_mutex);
+	list_for_each_entry_safe(ref, _ref, &substream_ref_list, node) {
+		if (ref->substream == substream) {
+			list_del(&ref->node);
+			found = true;
+			break;
+		}
+	}
+	mutex_unlock(&list_mutex);
+
+	if (found)
+		kfree(ref);
+
+	return found;
+}
+
+static bool fifo_bigger_than_stall(struct snd_pcm_substream *substream,
+				   struct snd_pcm_hw_params *params,
+				   struct snd_soc_dai *dai,
+				   int fifo_word)
+{
+	unsigned int rate = params_rate(params);
+	unsigned int channels = params_channels(params);
+	int width = params_physical_width(params);
+	int fifo_time, stall_time, data_word;
+
+	dev_dbg(dai->dev, "stream[%d]: %px, rate: %u, channels: %u, width: %d\n",
+		substream->stream, substream, rate, channels, width);
+
+	stall_time = rockchip_dmcfreq_get_stall_time_ns() / 1000;
+	if (!stall_time)
+		stall_time = DMC_STALL_TIME_US_DEFAULT;
+
+	stall_time += TIME_MARGIN_US;
+
+	data_word = rate * channels * width / 32;
+
+	if (!fifo_word || !data_word)
+		return true;
+
+	fifo_time = 1000000 * fifo_word / data_word;
+
+	dev_dbg(dai->dev, "data: %d, fifo: %d, fifo time: %d us, stall time: %d us\n",
+		data_word, fifo_word, fifo_time, stall_time);
+
+	return (fifo_time > stall_time);
+}
+
+void rockchip_utils_get_performance(struct snd_pcm_substream *substream,
+				    struct snd_pcm_hw_params *params,
+				    struct snd_soc_dai *dai,
+				    int fifo_word)
+{
+	might_sleep();
+
+	if (fifo_bigger_than_stall(substream, params, dai, fifo_word))
+		return;
+
+	if (substream_ref_new(substream))
+		return;
+
+	dev_dbg(dai->dev, "%s: stream[%d]: %px\n",
+		__func__, substream->stream, substream);
+
+	rockchip_set_system_status(SYS_STATUS_PERFORMANCE);
+}
+EXPORT_SYMBOL_GPL(rockchip_utils_get_performance);
+
+void rockchip_utils_put_performance(struct snd_pcm_substream *substream,
+				    struct snd_soc_dai *dai)
+{
+	might_sleep();
+
+	if (!substream_ref_found(substream))
+		return;
+
+	dev_dbg(dai->dev, "%s: stream[%d]: %px\n",
+		__func__, substream->stream, substream);
+
+	rockchip_clear_system_status(SYS_STATUS_PERFORMANCE);
+}
+EXPORT_SYMBOL_GPL(rockchip_utils_put_performance);
+
+MODULE_LICENSE("GPL");
diff --git a/kernel/sound/soc/rockchip/rockchip_utils.h b/kernel/sound/soc/rockchip/rockchip_utils.h
new file mode 100644
index 0000000..24280b2
--- /dev/null
+++ b/kernel/sound/soc/rockchip/rockchip_utils.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Rockchip Utils API
+ *
+ * Copyright (c) 2023 Rockchip Electronics Co. Ltd.
+ */
+
+#ifndef _ROCKCHIP_UTILS_H
+#define _ROCKCHIP_UTILS_H
+
+void rockchip_utils_get_performance(struct snd_pcm_substream *substream,
+				    struct snd_pcm_hw_params *params,
+				    struct snd_soc_dai *dai,
+				    int fifo_word);
+void rockchip_utils_put_performance(struct snd_pcm_substream *substream,
+				    struct snd_soc_dai *dai);
+
+#endif /* _ROCKCHIP_UTILS_H */
diff --git a/kernel/sound/soc/soc-compress.c b/kernel/sound/soc/soc-compress.c
index d0f3ff8..8f4ebb1 100644
--- a/kernel/sound/soc/soc-compress.c
+++ b/kernel/sound/soc/soc-compress.c
@@ -822,7 +822,7 @@
 		rtd->fe_compr = 1;
 		if (rtd->dai_link->dpcm_playback)
 			be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
-		else if (rtd->dai_link->dpcm_capture)
+		if (rtd->dai_link->dpcm_capture)
 			be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
 		memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
 	} else {
diff --git a/kernel/sound/soc/soc-pcm.c b/kernel/sound/soc/soc-pcm.c
index 1f200bf..bc7fe00 100644
--- a/kernel/sound/soc/soc-pcm.c
+++ b/kernel/sound/soc/soc-pcm.c
@@ -2336,6 +2336,9 @@
 		if (!snd_soc_dpcm_be_can_update(fe, be, stream))
 			continue;
 
+		if (!snd_soc_dpcm_can_be_prepared(fe, be, stream))
+			continue;
+
 		if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
 		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) &&
 		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND) &&
@@ -2978,3 +2981,20 @@
 	return snd_soc_dpcm_check_state(fe, be, stream, state, ARRAY_SIZE(state));
 }
 EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params);
+
+/*
+ * We can only prepare a BE DAI if any of it's FE are not prepared,
+ * running or paused for the specified stream direction.
+ */
+int snd_soc_dpcm_can_be_prepared(struct snd_soc_pcm_runtime *fe,
+				 struct snd_soc_pcm_runtime *be, int stream)
+{
+	const enum snd_soc_dpcm_state state[] = {
+		SND_SOC_DPCM_STATE_START,
+		SND_SOC_DPCM_STATE_PAUSED,
+		SND_SOC_DPCM_STATE_PREPARE,
+	};
+
+	return snd_soc_dpcm_check_state(fe, be, stream, state, ARRAY_SIZE(state));
+}
+EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_prepared);
diff --git a/kernel/sound/soc/sof/intel/hda-dai.c b/kernel/sound/soc/sof/intel/hda-dai.c
index ef31631..ba5cb48 100644
--- a/kernel/sound/soc/sof/intel/hda-dai.c
+++ b/kernel/sound/soc/sof/intel/hda-dai.c
@@ -212,6 +212,10 @@
 	int stream_tag;
 	int ret;
 
+	link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name);
+	if (!link)
+		return -EINVAL;
+
 	/* get stored dma data if resuming from system suspend */
 	link_dev = snd_soc_dai_get_dma_data(dai, substream);
 	if (!link_dev) {
@@ -231,10 +235,6 @@
 				  substream->stream);
 	if (ret < 0)
 		return ret;
-
-	link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name);
-	if (!link)
-		return -EINVAL;
 
 	/* set the stream tag in the codec dai dma params */
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
diff --git a/kernel/sound/synth/emux/emux_nrpn.c b/kernel/sound/synth/emux/emux_nrpn.c
index 7eed579..a7d8318 100644
--- a/kernel/sound/synth/emux/emux_nrpn.c
+++ b/kernel/sound/synth/emux/emux_nrpn.c
@@ -349,6 +349,9 @@
 snd_emux_xg_control(struct snd_emux_port *port, struct snd_midi_channel *chan,
 		    int param)
 {
+	if (param >= ARRAY_SIZE(chan->control))
+		return -EINVAL;
+
 	return send_converted_effect(xg_effects, ARRAY_SIZE(xg_effects),
 				     port, chan, param,
 				     chan->control[param],
diff --git a/kernel/sound/usb/caiaq/input.c b/kernel/sound/usb/caiaq/input.c
index 1e2cf2f..84f26dc 100644
--- a/kernel/sound/usb/caiaq/input.c
+++ b/kernel/sound/usb/caiaq/input.c
@@ -804,6 +804,7 @@
 
 	default:
 		/* no input methods supported on this device */
+		ret = -EINVAL;
 		goto exit_free_idev;
 	}
 
diff --git a/kernel/sound/usb/format.c b/kernel/sound/usb/format.c
index e8a63ea..29ed301 100644
--- a/kernel/sound/usb/format.c
+++ b/kernel/sound/usb/format.c
@@ -40,8 +40,12 @@
 	case UAC_VERSION_1:
 	default: {
 		struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
-		if (format >= 64)
-			return 0; /* invalid format */
+		if (format >= 64) {
+			usb_audio_info(chip,
+				       "%u:%d: invalid format type 0x%llx is detected, processed as PCM\n",
+				       fp->iface, fp->altsetting, format);
+			format = UAC_FORMAT_TYPE_I_PCM;
+		}
 		sample_width = fmt->bBitResolution;
 		sample_bytes = fmt->bSubframeSize;
 		format = 1ULL << format;
@@ -415,6 +419,7 @@
 	case USB_ID(0x0e41, 0x4248): /* Line6 Helix >= fw 2.82 */
 	case USB_ID(0x0e41, 0x4249): /* Line6 Helix Rack >= fw 2.82 */
 	case USB_ID(0x0e41, 0x424a): /* Line6 Helix LT >= fw 2.82 */
+	case USB_ID(0x0e41, 0x424b): /* Line6 Pod Go */
 	case USB_ID(0x19f7, 0x0011): /* Rode Rodecaster Pro */
 		return set_fixed_rate(fp, 48000, SNDRV_PCM_RATE_48000);
 	}
diff --git a/kernel/sound/usb/line6/driver.c b/kernel/sound/usb/line6/driver.c
index 59faa5a..b67617b 100644
--- a/kernel/sound/usb/line6/driver.c
+++ b/kernel/sound/usb/line6/driver.c
@@ -304,7 +304,8 @@
 		for (;;) {
 			done =
 				line6_midibuf_read(mb, line6->buffer_message,
-						LINE6_MIDI_MESSAGE_MAXLEN);
+						   LINE6_MIDI_MESSAGE_MAXLEN,
+						   LINE6_MIDIBUF_READ_RX);
 
 			if (done <= 0)
 				break;
diff --git a/kernel/sound/usb/line6/midi.c b/kernel/sound/usb/line6/midi.c
index ba0e2b7..0838632 100644
--- a/kernel/sound/usb/line6/midi.c
+++ b/kernel/sound/usb/line6/midi.c
@@ -44,7 +44,8 @@
 	int req, done;
 
 	for (;;) {
-		req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size);
+		req = min3(line6_midibuf_bytes_free(mb), line6->max_packet_size,
+			   LINE6_FALLBACK_MAXPACKETSIZE);
 		done = snd_rawmidi_transmit_peek(substream, chunk, req);
 
 		if (done == 0)
@@ -56,7 +57,8 @@
 
 	for (;;) {
 		done = line6_midibuf_read(mb, chunk,
-					  LINE6_FALLBACK_MAXPACKETSIZE);
+					  LINE6_FALLBACK_MAXPACKETSIZE,
+					  LINE6_MIDIBUF_READ_TX);
 
 		if (done == 0)
 			break;
diff --git a/kernel/sound/usb/line6/midibuf.c b/kernel/sound/usb/line6/midibuf.c
index 6a70463..e7f830f 100644
--- a/kernel/sound/usb/line6/midibuf.c
+++ b/kernel/sound/usb/line6/midibuf.c
@@ -9,6 +9,7 @@
 
 #include "midibuf.h"
 
+
 static int midibuf_message_length(unsigned char code)
 {
 	int message_length;
@@ -20,12 +21,7 @@
 
 		message_length = length[(code >> 4) - 8];
 	} else {
-		/*
-		   Note that according to the MIDI specification 0xf2 is
-		   the "Song Position Pointer", but this is used by Line 6
-		   to send sysex messages to the host.
-		 */
-		static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
+		static const int length[] = { -1, 2, 2, 2, -1, -1, 1, 1, 1, -1,
 			1, 1, 1, -1, 1, 1
 		};
 		message_length = length[code & 0x0f];
@@ -125,7 +121,7 @@
 }
 
 int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
-		       int length)
+		       int length, int read_type)
 {
 	int bytes_used;
 	int length1, length2;
@@ -148,9 +144,22 @@
 
 	length1 = this->size - this->pos_read;
 
-	/* check MIDI command length */
 	command = this->buf[this->pos_read];
+	/*
+	   PODxt always has status byte lower nibble set to 0010,
+	   when it means to send 0000, so we correct if here so
+	   that control/program changes come on channel 1 and
+	   sysex message status byte is correct
+	 */
+	if (read_type == LINE6_MIDIBUF_READ_RX) {
+		if (command == 0xb2 || command == 0xc2 || command == 0xf2) {
+			unsigned char fixed = command & 0xf0;
+			this->buf[this->pos_read] = fixed;
+			command = fixed;
+		}
+	}
 
+	/* check MIDI command length */
 	if (command & 0x80) {
 		midi_length = midibuf_message_length(command);
 		this->command_prev = command;
diff --git a/kernel/sound/usb/line6/midibuf.h b/kernel/sound/usb/line6/midibuf.h
index 124a8f9..542e8d8 100644
--- a/kernel/sound/usb/line6/midibuf.h
+++ b/kernel/sound/usb/line6/midibuf.h
@@ -8,6 +8,9 @@
 #ifndef MIDIBUF_H
 #define MIDIBUF_H
 
+#define LINE6_MIDIBUF_READ_TX 0
+#define LINE6_MIDIBUF_READ_RX 1
+
 struct midi_buffer {
 	unsigned char *buf;
 	int size;
@@ -23,7 +26,7 @@
 extern int line6_midibuf_ignore(struct midi_buffer *mb, int length);
 extern int line6_midibuf_init(struct midi_buffer *mb, int size, int split);
 extern int line6_midibuf_read(struct midi_buffer *mb, unsigned char *data,
-			      int length);
+			      int length, int read_type);
 extern void line6_midibuf_reset(struct midi_buffer *mb);
 extern int line6_midibuf_write(struct midi_buffer *mb, unsigned char *data,
 			       int length);
diff --git a/kernel/sound/usb/line6/pod.c b/kernel/sound/usb/line6/pod.c
index 16e6443..54be5ac 100644
--- a/kernel/sound/usb/line6/pod.c
+++ b/kernel/sound/usb/line6/pod.c
@@ -159,8 +159,9 @@
 	.bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
 };
 
+
 static const char pod_version_header[] = {
-	0xf2, 0x7e, 0x7f, 0x06, 0x02
+	0xf0, 0x7e, 0x7f, 0x06, 0x02
 };
 
 static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
diff --git a/kernel/sound/usb/quirks-table.h b/kernel/sound/usb/quirks-table.h
index 6a78813b..97fe2fa 100644
--- a/kernel/sound/usb/quirks-table.h
+++ b/kernel/sound/usb/quirks-table.h
@@ -76,6 +76,8 @@
 { USB_DEVICE_VENDOR_SPEC(0x041e, 0x3f0a) },
 /* E-Mu 0204 USB */
 { USB_DEVICE_VENDOR_SPEC(0x041e, 0x3f19) },
+/* Ktmicro Usb_audio device */
+{ USB_DEVICE_VENDOR_SPEC(0x31b2, 0x0011) },
 
 /*
  * Creative Technology, Ltd Live! Cam Sync HD [VF0770]
@@ -3795,6 +3797,35 @@
 		}
 	}
 },
+{
+	/* Advanced modes of the Mythware XA001AU.
+	 * For the standard mode, Mythware XA001AU has ID ffad:a001
+	 */
+	USB_DEVICE_VENDOR_SPEC(0xffad, 0xa001),
+	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+		.vendor_name = "Mythware",
+		.product_name = "XA001AU",
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const struct snd_usb_audio_quirk[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_IGNORE_INTERFACE,
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_AUDIO_STANDARD_INTERFACE,
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_AUDIO_STANDARD_INTERFACE,
+			},
+			{
+				.ifnum = -1
+			}
+		}
+	}
+},
 
 #undef USB_DEVICE_VENDOR_SPEC
 #undef USB_AUDIO_DEVICE
diff --git a/kernel/tools/arch/parisc/include/uapi/asm/mman.h b/kernel/tools/arch/parisc/include/uapi/asm/mman.h
index 506c06a..4cc88a6 100644
--- a/kernel/tools/arch/parisc/include/uapi/asm/mman.h
+++ b/kernel/tools/arch/parisc/include/uapi/asm/mman.h
@@ -1,20 +1,20 @@
 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 #ifndef TOOLS_ARCH_PARISC_UAPI_ASM_MMAN_FIX_H
 #define TOOLS_ARCH_PARISC_UAPI_ASM_MMAN_FIX_H
-#define MADV_DODUMP	70
+#define MADV_DODUMP	17
 #define MADV_DOFORK	11
-#define MADV_DONTDUMP   69
+#define MADV_DONTDUMP   16
 #define MADV_DONTFORK	10
 #define MADV_DONTNEED   4
 #define MADV_FREE	8
-#define MADV_HUGEPAGE	67
-#define MADV_MERGEABLE   65
-#define MADV_NOHUGEPAGE	68
+#define MADV_HUGEPAGE	14
+#define MADV_MERGEABLE  12
+#define MADV_NOHUGEPAGE 15
 #define MADV_NORMAL     0
 #define MADV_RANDOM     1
 #define MADV_REMOVE	9
 #define MADV_SEQUENTIAL 2
-#define MADV_UNMERGEABLE 66
+#define MADV_UNMERGEABLE 13
 #define MADV_WILLNEED   3
 #define MAP_ANONYMOUS	0x10
 #define MAP_DENYWRITE	0x0800
diff --git a/kernel/tools/arch/x86/include/asm/cpufeatures.h b/kernel/tools/arch/x86/include/asm/cpufeatures.h
index ec53f52..2ae4d74 100644
--- a/kernel/tools/arch/x86/include/asm/cpufeatures.h
+++ b/kernel/tools/arch/x86/include/asm/cpufeatures.h
@@ -13,8 +13,8 @@
 /*
  * Defines x86 CPU feature bits
  */
-#define NCAPINTS			19	   /* N 32-bit words worth of info */
-#define NBUGINTS			1	   /* N 32-bit bug flags */
+#define NCAPINTS			20	   /* N 32-bit words worth of info */
+#define NBUGINTS			2	   /* N 32-bit bug flags */
 
 /*
  * Note: If the comment begins with a quoted string, that string is used
@@ -96,7 +96,7 @@
 #define X86_FEATURE_SYSCALL32		( 3*32+14) /* "" syscall in IA32 userspace */
 #define X86_FEATURE_SYSENTER32		( 3*32+15) /* "" sysenter in IA32 userspace */
 #define X86_FEATURE_REP_GOOD		( 3*32+16) /* REP microcode works well */
-#define X86_FEATURE_SME_COHERENT	( 3*32+17) /* "" AMD hardware-enforced cache coherency */
+/* FREE!                                ( 3*32+17) */
 #define X86_FEATURE_LFENCE_RDTSC	( 3*32+18) /* "" LFENCE synchronizes RDTSC */
 #define X86_FEATURE_ACC_POWER		( 3*32+19) /* AMD Accumulated Power Mechanism */
 #define X86_FEATURE_NOPL		( 3*32+20) /* The NOPL (0F 1F) instructions */
@@ -201,7 +201,7 @@
 #define X86_FEATURE_INVPCID_SINGLE	( 7*32+ 7) /* Effectively INVPCID && CR4.PCIDE=1 */
 #define X86_FEATURE_HW_PSTATE		( 7*32+ 8) /* AMD HW-PState */
 #define X86_FEATURE_PROC_FEEDBACK	( 7*32+ 9) /* AMD ProcFeedbackInterface */
-#define X86_FEATURE_SME			( 7*32+10) /* AMD Secure Memory Encryption */
+/* FREE!                                ( 7*32+10) */
 #define X86_FEATURE_PTI			( 7*32+11) /* Kernel Page Table Isolation enabled */
 #define X86_FEATURE_KERNEL_IBRS		( 7*32+12) /* "" Set/clear IBRS on kernel entry/exit */
 #define X86_FEATURE_RSB_VMEXIT		( 7*32+13) /* "" Fill RSB on VM-Exit */
@@ -211,7 +211,7 @@
 #define X86_FEATURE_SSBD		( 7*32+17) /* Speculative Store Bypass Disable */
 #define X86_FEATURE_MBA			( 7*32+18) /* Memory Bandwidth Allocation */
 #define X86_FEATURE_RSB_CTXSW		( 7*32+19) /* "" Fill RSB on context switches */
-#define X86_FEATURE_SEV			( 7*32+20) /* AMD Secure Encrypted Virtualization */
+/* FREE!                                ( 7*32+20) */
 #define X86_FEATURE_USE_IBPB		( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */
 #define X86_FEATURE_USE_IBRS_FW		( 7*32+22) /* "" Use IBRS during runtime firmware calls */
 #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE	( 7*32+23) /* "" Disable Speculative Store Bypass. */
@@ -236,7 +236,6 @@
 #define X86_FEATURE_EPT_AD		( 8*32+17) /* Intel Extended Page Table access-dirty bit */
 #define X86_FEATURE_VMCALL		( 8*32+18) /* "" Hypervisor supports the VMCALL instruction */
 #define X86_FEATURE_VMW_VMMCALL		( 8*32+19) /* "" VMware prefers VMMCALL hypercall instruction */
-#define X86_FEATURE_SEV_ES		( 8*32+20) /* AMD Secure Encrypted Virtualization - Encrypted State */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (EBX), word 9 */
 #define X86_FEATURE_FSGSBASE		( 9*32+ 0) /* RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions*/
@@ -299,6 +298,7 @@
 #define X86_FEATURE_RSB_VMEXIT_LITE	(11*32+17) /* "" Fill RSB on VM-Exit when EIBRS is enabled */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
+#define X86_FEATURE_AVX_VNNI		(12*32+ 4) /* AVX VNNI instructions */
 #define X86_FEATURE_AVX512_BF16		(12*32+ 5) /* AVX512 BFLOAT16 instructions */
 
 /* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */
@@ -343,6 +343,7 @@
 #define X86_FEATURE_AVIC		(15*32+13) /* Virtual Interrupt Controller */
 #define X86_FEATURE_V_VMSAVE_VMLOAD	(15*32+15) /* Virtual VMSAVE VMLOAD */
 #define X86_FEATURE_VGIF		(15*32+16) /* Virtual GIF */
+#define X86_FEATURE_SVME_ADDR_CHK	(15*32+28) /* "" SVME addr check */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (ECX), word 16 */
 #define X86_FEATURE_AVX512VBMI		(16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/
@@ -389,6 +390,13 @@
 #define X86_FEATURE_CORE_CAPABILITIES	(18*32+30) /* "" IA32_CORE_CAPABILITIES MSR */
 #define X86_FEATURE_SPEC_CTRL_SSBD	(18*32+31) /* "" Speculative Store Bypass Disable */
 
+/* AMD-defined memory encryption features, CPUID level 0x8000001f (EAX), word 19 */
+#define X86_FEATURE_SME			(19*32+ 0) /* AMD Secure Memory Encryption */
+#define X86_FEATURE_SEV			(19*32+ 1) /* AMD Secure Encrypted Virtualization */
+#define X86_FEATURE_VM_PAGE_FLUSH	(19*32+ 2) /* "" VM Page Flush MSR is supported */
+#define X86_FEATURE_SEV_ES		(19*32+ 3) /* AMD Secure Encrypted Virtualization - Encrypted State */
+#define X86_FEATURE_SME_COHERENT	(19*32+10) /* "" AMD hardware-enforced cache coherency */
+
 /*
  * BUG word(s)
  */
diff --git a/kernel/tools/arch/x86/include/asm/disabled-features.h b/kernel/tools/arch/x86/include/asm/disabled-features.h
index d109c5e..a50f075 100644
--- a/kernel/tools/arch/x86/include/asm/disabled-features.h
+++ b/kernel/tools/arch/x86/include/asm/disabled-features.h
@@ -104,6 +104,7 @@
 			 DISABLE_ENQCMD)
 #define DISABLED_MASK17	0
 #define DISABLED_MASK18	0
-#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
+#define DISABLED_MASK19	0
+#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 20)
 
 #endif /* _ASM_X86_DISABLED_FEATURES_H */
diff --git a/kernel/tools/arch/x86/include/asm/required-features.h b/kernel/tools/arch/x86/include/asm/required-features.h
index 3ff0d48..b2d504f 100644
--- a/kernel/tools/arch/x86/include/asm/required-features.h
+++ b/kernel/tools/arch/x86/include/asm/required-features.h
@@ -101,6 +101,7 @@
 #define REQUIRED_MASK16	0
 #define REQUIRED_MASK17	0
 #define REQUIRED_MASK18	0
-#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
+#define REQUIRED_MASK19	0
+#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 20)
 
 #endif /* _ASM_X86_REQUIRED_FEATURES_H */
diff --git a/kernel/tools/bootconfig/test-bootconfig.sh b/kernel/tools/bootconfig/test-bootconfig.sh
index baed891..e36f178 100755
--- a/kernel/tools/bootconfig/test-bootconfig.sh
+++ b/kernel/tools/bootconfig/test-bootconfig.sh
@@ -87,10 +87,14 @@
 
 echo "Max node number check"
 
-echo -n > $TEMPCONF
-for i in `seq 1 1024` ; do
-   echo "node$i" >> $TEMPCONF
-done
+awk '
+BEGIN {
+  for (i = 0; i < 26; i += 1)
+      printf("%c\n", 65 + i % 26)
+  for (i = 26; i < 8192; i += 1)
+      printf("%c%c%c\n", 65 + i % 26, 65 + (i / 26) % 26, 65 + (i / 26 / 26))
+}
+' > $TEMPCONF
 xpass $BOOTCONF -a $TEMPCONF $INITRD
 
 echo "badnode" >> $TEMPCONF
diff --git a/kernel/tools/bpf/bpftool/feature.c b/kernel/tools/bpf/bpftool/feature.c
index 359960a..5f0b139 100644
--- a/kernel/tools/bpf/bpftool/feature.c
+++ b/kernel/tools/bpf/bpftool/feature.c
@@ -135,12 +135,12 @@
 
 /* Probing functions */
 
-static int read_procfs(const char *path)
+static long read_procfs(const char *path)
 {
 	char *endptr, *line = NULL;
 	size_t len = 0;
 	FILE *fd;
-	int res;
+	long res;
 
 	fd = fopen(path, "r");
 	if (!fd)
@@ -162,7 +162,7 @@
 
 static void probe_unprivileged_disabled(void)
 {
-	int res;
+	long res;
 
 	/* No support for C-style ouptut */
 
@@ -181,14 +181,14 @@
 			printf("Unable to retrieve required privileges for bpf() syscall\n");
 			break;
 		default:
-			printf("bpf() syscall restriction has unknown value %d\n", res);
+			printf("bpf() syscall restriction has unknown value %ld\n", res);
 		}
 	}
 }
 
 static void probe_jit_enable(void)
 {
-	int res;
+	long res;
 
 	/* No support for C-style ouptut */
 
@@ -210,7 +210,7 @@
 			printf("Unable to retrieve JIT-compiler status\n");
 			break;
 		default:
-			printf("JIT-compiler status has unknown value %d\n",
+			printf("JIT-compiler status has unknown value %ld\n",
 			       res);
 		}
 	}
@@ -218,7 +218,7 @@
 
 static void probe_jit_harden(void)
 {
-	int res;
+	long res;
 
 	/* No support for C-style ouptut */
 
@@ -240,7 +240,7 @@
 			printf("Unable to retrieve JIT hardening status\n");
 			break;
 		default:
-			printf("JIT hardening status has unknown value %d\n",
+			printf("JIT hardening status has unknown value %ld\n",
 			       res);
 		}
 	}
@@ -248,7 +248,7 @@
 
 static void probe_jit_kallsyms(void)
 {
-	int res;
+	long res;
 
 	/* No support for C-style ouptut */
 
@@ -267,14 +267,14 @@
 			printf("Unable to retrieve JIT kallsyms export status\n");
 			break;
 		default:
-			printf("JIT kallsyms exports status has unknown value %d\n", res);
+			printf("JIT kallsyms exports status has unknown value %ld\n", res);
 		}
 	}
 }
 
 static void probe_jit_limit(void)
 {
-	int res;
+	long res;
 
 	/* No support for C-style ouptut */
 
@@ -287,7 +287,7 @@
 			printf("Unable to retrieve global memory limit for JIT compiler for unprivileged users\n");
 			break;
 		default:
-			printf("Global memory limit for JIT compiler for unprivileged users is %d bytes\n", res);
+			printf("Global memory limit for JIT compiler for unprivileged users is %ld bytes\n", res);
 		}
 	}
 }
diff --git a/kernel/tools/bpf/bpftool/json_writer.c b/kernel/tools/bpf/bpftool/json_writer.c
index 7fea83b..bca5dd0 100644
--- a/kernel/tools/bpf/bpftool/json_writer.c
+++ b/kernel/tools/bpf/bpftool/json_writer.c
@@ -80,9 +80,6 @@
 		case '"':
 			fputs("\\\"", self->out);
 			break;
-		case '\'':
-			fputs("\\\'", self->out);
-			break;
 		default:
 			putc(*str, self->out);
 		}
diff --git a/kernel/tools/bpf/bpftool/prog.c b/kernel/tools/bpf/bpftool/prog.c
index 5925369..d2bcce6 100644
--- a/kernel/tools/bpf/bpftool/prog.c
+++ b/kernel/tools/bpf/bpftool/prog.c
@@ -1912,10 +1912,38 @@
 	profile_perf_event_cnt = 0;
 }
 
+static int profile_open_perf_event(int mid, int cpu, int map_fd)
+{
+	int pmu_fd;
+
+	pmu_fd = syscall(__NR_perf_event_open, &metrics[mid].attr,
+			 -1 /*pid*/, cpu, -1 /*group_fd*/, 0);
+	if (pmu_fd < 0) {
+		if (errno == ENODEV) {
+			p_info("cpu %d may be offline, skip %s profiling.",
+				cpu, metrics[mid].name);
+			profile_perf_event_cnt++;
+			return 0;
+		}
+		return -1;
+	}
+
+	if (bpf_map_update_elem(map_fd,
+				&profile_perf_event_cnt,
+				&pmu_fd, BPF_ANY) ||
+	    ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0)) {
+		close(pmu_fd);
+		return -1;
+	}
+
+	profile_perf_events[profile_perf_event_cnt++] = pmu_fd;
+	return 0;
+}
+
 static int profile_open_perf_events(struct profiler_bpf *obj)
 {
 	unsigned int cpu, m;
-	int map_fd, pmu_fd;
+	int map_fd;
 
 	profile_perf_events = calloc(
 		sizeof(int), obj->rodata->num_cpu * obj->rodata->num_metric);
@@ -1934,17 +1962,11 @@
 		if (!metrics[m].selected)
 			continue;
 		for (cpu = 0; cpu < obj->rodata->num_cpu; cpu++) {
-			pmu_fd = syscall(__NR_perf_event_open, &metrics[m].attr,
-					 -1/*pid*/, cpu, -1/*group_fd*/, 0);
-			if (pmu_fd < 0 ||
-			    bpf_map_update_elem(map_fd, &profile_perf_event_cnt,
-						&pmu_fd, BPF_ANY) ||
-			    ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0)) {
+			if (profile_open_perf_event(m, cpu, map_fd)) {
 				p_err("failed to create event %s on cpu %d",
 				      metrics[m].name, cpu);
 				return -1;
 			}
-			profile_perf_events[profile_perf_event_cnt++] = pmu_fd;
 		}
 	}
 	return 0;
diff --git a/kernel/tools/bpf/bpftool/skeleton/profiler.bpf.c b/kernel/tools/bpf/bpftool/skeleton/profiler.bpf.c
index ce5b65e..2f80edc 100644
--- a/kernel/tools/bpf/bpftool/skeleton/profiler.bpf.c
+++ b/kernel/tools/bpf/bpftool/skeleton/profiler.bpf.c
@@ -4,6 +4,12 @@
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_tracing.h>
 
+struct bpf_perf_event_value___local {
+	__u64 counter;
+	__u64 enabled;
+	__u64 running;
+} __attribute__((preserve_access_index));
+
 /* map of perf event fds, num_cpu * num_metric entries */
 struct {
 	__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
@@ -15,14 +21,14 @@
 struct {
 	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
 	__uint(key_size, sizeof(u32));
-	__uint(value_size, sizeof(struct bpf_perf_event_value));
+	__uint(value_size, sizeof(struct bpf_perf_event_value___local));
 } fentry_readings SEC(".maps");
 
 /* accumulated readings */
 struct {
 	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
 	__uint(key_size, sizeof(u32));
-	__uint(value_size, sizeof(struct bpf_perf_event_value));
+	__uint(value_size, sizeof(struct bpf_perf_event_value___local));
 } accum_readings SEC(".maps");
 
 /* sample counts, one per cpu */
@@ -39,7 +45,7 @@
 SEC("fentry/XXX")
 int BPF_PROG(fentry_XXX)
 {
-	struct bpf_perf_event_value *ptrs[MAX_NUM_MATRICS];
+	struct bpf_perf_event_value___local *ptrs[MAX_NUM_MATRICS];
 	u32 key = bpf_get_smp_processor_id();
 	u32 i;
 
@@ -53,10 +59,10 @@
 	}
 
 	for (i = 0; i < num_metric && i < MAX_NUM_MATRICS; i++) {
-		struct bpf_perf_event_value reading;
+		struct bpf_perf_event_value___local reading;
 		int err;
 
-		err = bpf_perf_event_read_value(&events, key, &reading,
+		err = bpf_perf_event_read_value(&events, key, (void *)&reading,
 						sizeof(reading));
 		if (err)
 			return 0;
@@ -68,14 +74,14 @@
 }
 
 static inline void
-fexit_update_maps(u32 id, struct bpf_perf_event_value *after)
+fexit_update_maps(u32 id, struct bpf_perf_event_value___local *after)
 {
-	struct bpf_perf_event_value *before, diff;
+	struct bpf_perf_event_value___local *before, diff;
 
 	before = bpf_map_lookup_elem(&fentry_readings, &id);
 	/* only account samples with a valid fentry_reading */
 	if (before && before->counter) {
-		struct bpf_perf_event_value *accum;
+		struct bpf_perf_event_value___local *accum;
 
 		diff.counter = after->counter - before->counter;
 		diff.enabled = after->enabled - before->enabled;
@@ -93,7 +99,7 @@
 SEC("fexit/XXX")
 int BPF_PROG(fexit_XXX)
 {
-	struct bpf_perf_event_value readings[MAX_NUM_MATRICS];
+	struct bpf_perf_event_value___local readings[MAX_NUM_MATRICS];
 	u32 cpu = bpf_get_smp_processor_id();
 	u32 i, zero = 0;
 	int err;
@@ -102,7 +108,8 @@
 	/* read all events before updating the maps, to reduce error */
 	for (i = 0; i < num_metric && i < MAX_NUM_MATRICS; i++) {
 		err = bpf_perf_event_read_value(&events, cpu + i * num_cpu,
-						readings + i, sizeof(*readings));
+						(void *)(readings + i),
+						sizeof(*readings));
 		if (err)
 			return 0;
 	}
diff --git a/kernel/tools/bpf/bpftool/xlated_dumper.c b/kernel/tools/bpf/bpftool/xlated_dumper.c
index 8608cd6..13d614b 100644
--- a/kernel/tools/bpf/bpftool/xlated_dumper.c
+++ b/kernel/tools/bpf/bpftool/xlated_dumper.c
@@ -363,8 +363,15 @@
 	struct bpf_insn *insn_start = buf_start;
 	struct bpf_insn *insn_end = buf_end;
 	struct bpf_insn *cur = insn_start;
+	bool double_insn = false;
 
 	for (; cur <= insn_end; cur++) {
+		if (double_insn) {
+			double_insn = false;
+			continue;
+		}
+		double_insn = cur->code == (BPF_LD | BPF_IMM | BPF_DW);
+
 		printf("% 4d: ", (int)(cur - insn_start + start_idx));
 		print_bpf_insn(&cbs, cur, true);
 		if (cur != insn_end)
diff --git a/kernel/tools/gpio/gpio-event-mon.c b/kernel/tools/gpio/gpio-event-mon.c
index 84ae103..367c106 100644
--- a/kernel/tools/gpio/gpio-event-mon.c
+++ b/kernel/tools/gpio/gpio-event-mon.c
@@ -86,6 +86,7 @@
 			gpiotools_test_bit(values.bits, i));
 	}
 
+	i = 0;
 	while (1) {
 		struct gpio_v2_line_event event;
 
diff --git a/kernel/tools/gpio/lsgpio.c b/kernel/tools/gpio/lsgpio.c
index 5a05a45..85a2aa2 100644
--- a/kernel/tools/gpio/lsgpio.c
+++ b/kernel/tools/gpio/lsgpio.c
@@ -90,7 +90,7 @@
 	for (i = 0; i < info->num_attrs; i++) {
 		if (info->attrs[i].id == GPIO_V2_LINE_ATTR_ID_DEBOUNCE)
 			fprintf(stdout, ", debounce_period=%dusec",
-				info->attrs[0].debounce_period_us);
+				info->attrs[i].debounce_period_us);
 	}
 }
 
diff --git a/kernel/tools/hv/vmbus_testing b/kernel/tools/hv/vmbus_testing
index e721290..4467979 100755
--- a/kernel/tools/hv/vmbus_testing
+++ b/kernel/tools/hv/vmbus_testing
@@ -164,7 +164,7 @@
 def get_all_devices_test_status(file_map):
 
         for device in file_map:
-                if (get_test_state(locate_state(device, file_map)) is 1):
+                if (get_test_state(locate_state(device, file_map)) == 1):
                         print("Testing = ON for: {}"
                               .format(device.split("/")[5]))
                 else:
@@ -203,7 +203,7 @@
 def set_test_state(state_path, state_value, quiet):
 
         write_test_files(state_path, state_value)
-        if (get_test_state(state_path) is 1):
+        if (get_test_state(state_path) == 1):
                 if (not quiet):
                         print("Testing = ON for device: {}"
                               .format(state_path.split("/")[5]))
diff --git a/kernel/tools/iio/iio_utils.c b/kernel/tools/iio/iio_utils.c
index d66b18c..4836099 100644
--- a/kernel/tools/iio/iio_utils.c
+++ b/kernel/tools/iio/iio_utils.c
@@ -262,6 +262,7 @@
 			if (fscanf(sysfsfp, "%f", output) != 1)
 				ret = errno ? -errno : -ENODATA;
 
+			fclose(sysfsfp);
 			break;
 		}
 error_free_filename:
@@ -342,9 +343,9 @@
 			}
 
 			sysfsfp = fopen(filename, "r");
+			free(filename);
 			if (!sysfsfp) {
 				ret = -errno;
-				free(filename);
 				goto error_close_dir;
 			}
 
@@ -354,7 +355,6 @@
 				if (fclose(sysfsfp))
 					perror("build_channel_array(): Failed to close file");
 
-				free(filename);
 				goto error_close_dir;
 			}
 			if (ret == 1)
@@ -362,11 +362,9 @@
 
 			if (fclose(sysfsfp)) {
 				ret = -errno;
-				free(filename);
 				goto error_close_dir;
 			}
 
-			free(filename);
 		}
 
 	*ci_array = malloc(sizeof(**ci_array) * (*counter));
@@ -392,9 +390,9 @@
 			}
 
 			sysfsfp = fopen(filename, "r");
+			free(filename);
 			if (!sysfsfp) {
 				ret = -errno;
-				free(filename);
 				count--;
 				goto error_cleanup_array;
 			}
@@ -402,20 +400,17 @@
 			errno = 0;
 			if (fscanf(sysfsfp, "%i", &current_enabled) != 1) {
 				ret = errno ? -errno : -ENODATA;
-				free(filename);
 				count--;
 				goto error_cleanup_array;
 			}
 
 			if (fclose(sysfsfp)) {
 				ret = -errno;
-				free(filename);
 				count--;
 				goto error_cleanup_array;
 			}
 
 			if (!current_enabled) {
-				free(filename);
 				count--;
 				continue;
 			}
@@ -426,7 +421,6 @@
 						strlen(ent->d_name) -
 						strlen("_en"));
 			if (!current->name) {
-				free(filename);
 				ret = -ENOMEM;
 				count--;
 				goto error_cleanup_array;
@@ -436,7 +430,6 @@
 			ret = iioutils_break_up_name(current->name,
 						     &current->generic_name);
 			if (ret) {
-				free(filename);
 				free(current->name);
 				count--;
 				goto error_cleanup_array;
@@ -447,17 +440,16 @@
 				       scan_el_dir,
 				       current->name);
 			if (ret < 0) {
-				free(filename);
 				ret = -ENOMEM;
 				goto error_cleanup_array;
 			}
 
 			sysfsfp = fopen(filename, "r");
+			free(filename);
 			if (!sysfsfp) {
 				ret = -errno;
-				fprintf(stderr, "failed to open %s\n",
-					filename);
-				free(filename);
+				fprintf(stderr, "failed to open %s/%s_index\n",
+					scan_el_dir, current->name);
 				goto error_cleanup_array;
 			}
 
@@ -467,17 +459,14 @@
 				if (fclose(sysfsfp))
 					perror("build_channel_array(): Failed to close file");
 
-				free(filename);
 				goto error_cleanup_array;
 			}
 
 			if (fclose(sysfsfp)) {
 				ret = -errno;
-				free(filename);
 				goto error_cleanup_array;
 			}
 
-			free(filename);
 			/* Find the scale */
 			ret = iioutils_get_param_float(&current->scale,
 						       "scale",
diff --git a/kernel/tools/include/linux/btf_ids.h b/kernel/tools/include/linux/btf_ids.h
index 57890b3..eca91e7 100644
--- a/kernel/tools/include/linux/btf_ids.h
+++ b/kernel/tools/include/linux/btf_ids.h
@@ -38,7 +38,7 @@
 	____BTF_ID(symbol)
 
 #define __ID(prefix) \
-	__PASTE(prefix, __COUNTER__)
+	__PASTE(__PASTE(prefix, __COUNTER__), __LINE__)
 
 /*
  * The BTF_ID defines unique symbol for each ID pointing
diff --git a/kernel/tools/include/linux/objtool.h b/kernel/tools/include/linux/objtool.h
index 662f193..d17fa7f 100644
--- a/kernel/tools/include/linux/objtool.h
+++ b/kernel/tools/include/linux/objtool.h
@@ -71,6 +71,23 @@
 	static void __used __section(".discard.func_stack_frame_non_standard") \
 		*__func_stack_frame_non_standard_##func = func
 
+/*
+ * STACK_FRAME_NON_STANDARD_FP() is a frame-pointer-specific function ignore
+ * for the case where a function is intentionally missing frame pointer setup,
+ * but otherwise needs objtool/ORC coverage when frame pointers are disabled.
+ */
+#ifdef CONFIG_FRAME_POINTER
+#define STACK_FRAME_NON_STANDARD_FP(func) STACK_FRAME_NON_STANDARD(func)
+#else
+#define STACK_FRAME_NON_STANDARD_FP(func)
+#endif
+
+#define ANNOTATE_NOENDBR					\
+	"986: \n\t"						\
+	".pushsection .discard.noendbr\n\t"			\
+	_ASM_PTR " 986b\n\t"					\
+	".popsection\n\t"
+
 #else /* __ASSEMBLY__ */
 
 /*
@@ -117,6 +134,13 @@
 	.popsection
 .endm
 
+.macro ANNOTATE_NOENDBR
+.Lhere_\@:
+	.pushsection .discard.noendbr
+	.quad	.Lhere_\@
+	.popsection
+.endm
+
 #endif /* __ASSEMBLY__ */
 
 #else /* !CONFIG_STACK_VALIDATION */
@@ -126,10 +150,14 @@
 #define UNWIND_HINT(sp_reg, sp_offset, type, end)	\
 	"\n\t"
 #define STACK_FRAME_NON_STANDARD(func)
+#define STACK_FRAME_NON_STANDARD_FP(func)
+#define ANNOTATE_NOENDBR
 #else
 #define ANNOTATE_INTRA_FUNCTION_CALL
 .macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
 .endm
+.macro ANNOTATE_NOENDBR
+.endm
 #endif
 
 #endif /* CONFIG_STACK_VALIDATION */
diff --git a/kernel/tools/include/uapi/linux/bpf.h b/kernel/tools/include/uapi/linux/bpf.h
index 7943e74..fd1a4d8 100644
--- a/kernel/tools/include/uapi/linux/bpf.h
+++ b/kernel/tools/include/uapi/linux/bpf.h
@@ -976,7 +976,9 @@
  * 		performed again, if the helper is used in combination with
  * 		direct packet access.
  * 	Return
- * 		0 on success, or a negative error in case of failure.
+ * 		0 on success, or a negative error in case of failure. Positive
+ * 		error indicates a potential drop or congestion in the target
+ * 		device. The particular positive error codes are not defined.
  *
  * u64 bpf_get_current_pid_tgid(void)
  * 	Return
diff --git a/kernel/tools/lib/bpf/bpf.h b/kernel/tools/lib/bpf/bpf.h
index 875dde2..92a3eaa 100644
--- a/kernel/tools/lib/bpf/bpf.h
+++ b/kernel/tools/lib/bpf/bpf.h
@@ -241,8 +241,15 @@
 				 __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 */
diff --git a/kernel/tools/lib/bpf/bpf_helpers.h b/kernel/tools/lib/bpf/bpf_helpers.h
index 72b2511..1c389b0 100644
--- a/kernel/tools/lib/bpf/bpf_helpers.h
+++ b/kernel/tools/lib/bpf/bpf_helpers.h
@@ -42,16 +42,21 @@
 /*
  * Helper macro to manipulate data structures
  */
-#ifndef offsetof
-#define offsetof(TYPE, MEMBER)	((unsigned long)&((TYPE *)0)->MEMBER)
-#endif
-#ifndef container_of
+
+/* offsetof() definition that uses __builtin_offset() might not preserve field
+ * offset CO-RE relocation properly, so force-redefine offsetof() using
+ * old-school approach which works with CO-RE correctly
+ */
+#undef offsetof
+#define offsetof(type, member)	((unsigned long)&((type *)0)->member)
+
+/* redefined container_of() to ensure we use the above offsetof() macro */
+#undef container_of
 #define container_of(ptr, type, member)				\
 	({							\
 		void *__mptr = (void *)(ptr);			\
 		((type *)(__mptr - offsetof(type, member)));	\
 	})
-#endif
 
 /*
  * Helper macro to throw a compilation error if __bpf_unreachable() gets
diff --git a/kernel/tools/lib/bpf/btf.c b/kernel/tools/lib/bpf/btf.c
index e6f644c..f7c48b1 100644
--- a/kernel/tools/lib/bpf/btf.c
+++ b/kernel/tools/lib/bpf/btf.c
@@ -614,8 +614,21 @@
 			if (align <= 0)
 				return align;
 			max_align = max(max_align, align);
+
+			/* if field offset isn't aligned according to field
+			 * type's alignment, then struct must be packed
+			 */
+			if (btf_member_bitfield_size(t, i) == 0 &&
+			    (m->offset % (8 * align)) != 0)
+				return 1;
 		}
 
+		/* if struct/union size isn't a multiple of its alignment,
+		 * then struct must be packed
+		 */
+		if ((t->size % max_align) != 0)
+			return 1;
+
 		return max_align;
 	}
 	default:
diff --git a/kernel/tools/lib/bpf/btf_dump.c b/kernel/tools/lib/bpf/btf_dump.c
index bd22853..61aa2c4 100644
--- a/kernel/tools/lib/bpf/btf_dump.c
+++ b/kernel/tools/lib/bpf/btf_dump.c
@@ -188,6 +188,17 @@
 	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 @@
 	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);
 }
@@ -781,13 +792,8 @@
 				 const struct btf_type *t)
 {
 	const struct btf_member *m;
-	int align, i, bit_sz;
+	int max_align = 1, align, i, bit_sz;
 	__u16 vlen;
-
-	align = btf__align_of(btf, id);
-	/* size of a non-packed struct has to be a multiple of its alignment*/
-	if (align && t->size % align)
-		return true;
 
 	m = btf_members(t);
 	vlen = btf_vlen(t);
@@ -797,8 +803,11 @@
 		bit_sz = btf_member_bitfield_size(t, i);
 		if (align && bit_sz == 0 && m->offset % (8 * align) != 0)
 			return true;
+		max_align = max(align, max_align);
 	}
-
+	/* size of a non-packed struct has to be a multiple of its alignment */
+	if (t->size % max_align != 0)
+		return true;
 	/*
 	 * if original struct was marked as packed, but its layout is
 	 * naturally aligned, we'll detect that it's not packed
@@ -806,44 +815,97 @@
 	return false;
 }
 
-static int chip_away_bits(int total, int at_most)
-{
-	return total % at_most ? : at_most;
-}
-
 static void btf_dump_emit_bit_padding(const struct btf_dump *d,
-				      int cur_off, int m_off, int m_bit_sz,
-				      int align, int lvl)
+				      int cur_off, int next_off, int next_align,
+				      bool in_bitfield, int lvl)
 {
-	int off_diff = m_off - cur_off;
-	int ptr_bits = d->ptr_sz * 8;
+	const struct {
+		const char *name;
+		int bits;
+	} pads[] = {
+		{"long", d->ptr_sz * 8}, {"int", 32}, {"short", 16}, {"char", 8}
+	};
+	int new_off, pad_bits, bits, i;
+	const char *pad_type;
 
-	if (off_diff <= 0)
-		/* no gap */
-		return;
-	if (m_bit_sz == 0 && off_diff < align * 8)
-		/* natural padding will take care of a gap */
-		return;
+	if (cur_off >= next_off)
+		return; /* no gap */
 
-	while (off_diff > 0) {
-		const char *pad_type;
-		int pad_bits;
+	/* For filling out padding we want to take advantage of
+	 * natural alignment rules to minimize unnecessary explicit
+	 * padding. First, we find the largest type (among long, int,
+	 * short, or char) that can be used to force naturally aligned
+	 * boundary. Once determined, we'll use such type to fill in
+	 * the remaining padding gap. In some cases we can rely on
+	 * compiler filling some gaps, but sometimes we need to force
+	 * alignment to close natural alignment with markers like
+	 * `long: 0` (this is always the case for bitfields).  Note
+	 * that even if struct itself has, let's say 4-byte alignment
+	 * (i.e., it only uses up to int-aligned types), using `long:
+	 * X;` explicit padding doesn't actually change struct's
+	 * overall alignment requirements, but compiler does take into
+	 * account that type's (long, in this example) natural
+	 * alignment requirements when adding implicit padding. We use
+	 * this fact heavily and don't worry about ruining correct
+	 * struct alignment requirement.
+	 */
+	for (i = 0; i < ARRAY_SIZE(pads); i++) {
+		pad_bits = pads[i].bits;
+		pad_type = pads[i].name;
 
-		if (ptr_bits > 32 && off_diff > 32) {
-			pad_type = "long";
-			pad_bits = chip_away_bits(off_diff, ptr_bits);
-		} else if (off_diff > 16) {
-			pad_type = "int";
-			pad_bits = chip_away_bits(off_diff, 32);
-		} else if (off_diff > 8) {
-			pad_type = "short";
-			pad_bits = chip_away_bits(off_diff, 16);
-		} else {
-			pad_type = "char";
-			pad_bits = chip_away_bits(off_diff, 8);
+		new_off = roundup(cur_off, pad_bits);
+		if (new_off <= next_off)
+			break;
+	}
+
+	if (new_off > cur_off && new_off <= next_off) {
+		/* We need explicit `<type>: 0` aligning mark if next
+		 * field is right on alignment offset and its
+		 * alignment requirement is less strict than <type>'s
+		 * alignment (so compiler won't naturally align to the
+		 * offset we expect), or if subsequent `<type>: X`,
+		 * will actually completely fit in the remaining hole,
+		 * making compiler basically ignore `<type>: X`
+		 * completely.
+		 */
+		if (in_bitfield ||
+		    (new_off == next_off && roundup(cur_off, next_align * 8) != new_off) ||
+		    (new_off != next_off && next_off - new_off <= new_off - cur_off))
+			/* but for bitfields we'll emit explicit bit count */
+			btf_dump_printf(d, "\n%s%s: %d;", pfx(lvl), pad_type,
+					in_bitfield ? new_off - cur_off : 0);
+		cur_off = new_off;
+	}
+
+	/* Now we know we start at naturally aligned offset for a chosen
+	 * padding type (long, int, short, or char), and so the rest is just
+	 * a straightforward filling of remaining padding gap with full
+	 * `<type>: sizeof(<type>);` markers, except for the last one, which
+	 * might need smaller than sizeof(<type>) padding.
+	 */
+	while (cur_off != next_off) {
+		bits = min(next_off - cur_off, pad_bits);
+		if (bits == pad_bits) {
+			btf_dump_printf(d, "\n%s%s: %d;", pfx(lvl), pad_type, pad_bits);
+			cur_off += bits;
+			continue;
 		}
-		btf_dump_printf(d, "\n%s%s: %d;", pfx(lvl), pad_type, pad_bits);
-		off_diff -= pad_bits;
+		/* For the remainder padding that doesn't cover entire
+		 * pad_type bit length, we pick the smallest necessary type.
+		 * This is pure aesthetics, we could have just used `long`,
+		 * but having smallest necessary one communicates better the
+		 * scale of the padding gap.
+		 */
+		for (i = ARRAY_SIZE(pads) - 1; i >= 0; i--) {
+			pad_type = pads[i].name;
+			pad_bits = pads[i].bits;
+			if (pad_bits < bits)
+				continue;
+
+			btf_dump_printf(d, "\n%s%s: %d;", pfx(lvl), pad_type, bits);
+			cur_off += bits;
+			break;
+		}
 	}
 }
 
@@ -862,9 +924,11 @@
 {
 	const struct btf_member *m = btf_members(t);
 	bool is_struct = btf_is_struct(t);
-	int align, i, packed, off = 0;
+	bool packed, prev_bitfield = false;
+	int align, i, off = 0;
 	__u16 vlen = btf_vlen(t);
 
+	align = btf__align_of(d->btf, id);
 	packed = is_struct ? btf_is_struct_packed(d->btf, id, t) : 0;
 
 	btf_dump_printf(d, "%s%s%s {",
@@ -874,37 +938,47 @@
 
 	for (i = 0; i < vlen; i++, m++) {
 		const char *fname;
-		int m_off, m_sz;
+		int m_off, m_sz, m_align;
+		bool in_bitfield;
 
 		fname = btf_name_of(d, m->name_off);
 		m_sz = btf_member_bitfield_size(t, i);
 		m_off = btf_member_bit_offset(t, i);
-		align = packed ? 1 : btf__align_of(d->btf, m->type);
+		m_align = packed ? 1 : btf__align_of(d->btf, m->type);
 
-		btf_dump_emit_bit_padding(d, off, m_off, m_sz, align, lvl + 1);
+		in_bitfield = prev_bitfield && m_sz != 0;
+
+		btf_dump_emit_bit_padding(d, off, m_off, m_align, in_bitfield, lvl + 1);
 		btf_dump_printf(d, "\n%s", pfx(lvl + 1));
 		btf_dump_emit_type_decl(d, m->type, fname, lvl + 1);
 
 		if (m_sz) {
 			btf_dump_printf(d, ": %d", m_sz);
 			off = m_off + m_sz;
+			prev_bitfield = true;
 		} else {
 			m_sz = max((__s64)0, btf__resolve_size(d->btf, m->type));
 			off = m_off + m_sz * 8;
+			prev_bitfield = false;
 		}
+
 		btf_dump_printf(d, ";");
 	}
 
 	/* pad at the end, if necessary */
-	if (is_struct) {
-		align = packed ? 1 : btf__align_of(d->btf, id);
-		btf_dump_emit_bit_padding(d, off, t->size * 8, 0, align,
-					  lvl + 1);
-	}
+	if (is_struct)
+		btf_dump_emit_bit_padding(d, off, t->size * 8, align, false, lvl + 1);
 
-	if (vlen)
+	/*
+	 * Keep `struct empty {}` on a single line,
+	 * only print newline when there are regular or padding fields.
+	 */
+	if (vlen || t->size) {
 		btf_dump_printf(d, "\n");
-	btf_dump_printf(d, "%s}", pfx(lvl));
+		btf_dump_printf(d, "%s}", pfx(lvl));
+	} else {
+		btf_dump_printf(d, "}");
+	}
 	if (packed)
 		btf_dump_printf(d, " __attribute__((packed))");
 }
@@ -1392,11 +1466,23 @@
 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;
 }
diff --git a/kernel/tools/lib/bpf/libbpf.c b/kernel/tools/lib/bpf/libbpf.c
index 66d7f8d..015ed82 100644
--- a/kernel/tools/lib/bpf/libbpf.c
+++ b/kernel/tools/lib/bpf/libbpf.c
@@ -3479,6 +3479,9 @@
 	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];
diff --git a/kernel/tools/lib/bpf/nlattr.c b/kernel/tools/lib/bpf/nlattr.c
index b607fa9..1a04299 100644
--- a/kernel/tools/lib/bpf/nlattr.c
+++ b/kernel/tools/lib/bpf/nlattr.c
@@ -178,7 +178,7 @@
 		hlen += nlmsg_len(&err->msg);
 
 	attr = (struct nlattr *) ((void *) err + hlen);
-	alen = nlh->nlmsg_len - hlen;
+	alen = (void *)nlh + nlh->nlmsg_len - (void *)attr;
 
 	if (libbpf_nla_parse(tb, NLMSGERR_ATTR_MAX, attr, alen,
 			     extack_policy) != 0) {
diff --git a/kernel/tools/objtool/arch.h b/kernel/tools/objtool/arch.h
index 580ce18..7584029 100644
--- a/kernel/tools/objtool/arch.h
+++ b/kernel/tools/objtool/arch.h
@@ -90,6 +90,7 @@
 
 bool arch_is_retpoline(struct symbol *sym);
 bool arch_is_rethunk(struct symbol *sym);
+bool arch_is_embedded_insn(struct symbol *sym);
 
 int arch_rewrite_retpolines(struct objtool_file *file);
 
diff --git a/kernel/tools/objtool/arch/x86/decode.c b/kernel/tools/objtool/arch/x86/decode.c
index d8f4770..9d2af67 100644
--- a/kernel/tools/objtool/arch/x86/decode.c
+++ b/kernel/tools/objtool/arch/x86/decode.c
@@ -654,3 +654,9 @@
 {
 	return !strcmp(sym->name, "__x86_return_thunk");
 }
+
+bool arch_is_embedded_insn(struct symbol *sym)
+{
+	return !strcmp(sym->name, "retbleed_return_thunk") ||
+	       !strcmp(sym->name, "srso_safe_ret");
+}
diff --git a/kernel/tools/objtool/check.c b/kernel/tools/objtool/check.c
index 836c919..d2bd5c0 100644
--- a/kernel/tools/objtool/check.c
+++ b/kernel/tools/objtool/check.c
@@ -168,6 +168,7 @@
 		"panic",
 		"do_exit",
 		"do_task_dead",
+		"make_task_dead",
 		"__module_put_and_exit",
 		"complete_and_exit",
 		"__reiserfs_panic",
@@ -175,10 +176,11 @@
 		"fortify_panic",
 		"usercopy_abort",
 		"machine_real_restart",
-		"rewind_stack_do_exit",
+		"rewind_stack_and_make_dead",
 		"kunit_try_catch_throw",
 		"xen_start_kernel",
 		"cpu_bringup_and_idle",
+		"stop_this_cpu",
 	};
 
 	if (!func)
@@ -196,7 +198,7 @@
 		return false;
 
 	insn = find_insn(file, func->sec, func->offset);
-	if (!insn->func)
+	if (!insn || !insn->func)
 		return false;
 
 	func_for_each_insn(file, func, insn) {
@@ -367,7 +369,7 @@
 
 		if (!strcmp(sec->name, ".noinstr.text") ||
 		    !strcmp(sec->name, ".entry.text") ||
-		    !strncmp(sec->name, ".text.__x86.", 12))
+		    !strncmp(sec->name, ".text..__x86.", 13))
 			sec->noinstr = true;
 
 		for (offset = 0; offset < sec->len; offset += insn->len) {
@@ -570,6 +572,7 @@
 		if (strncmp(key_name, STATIC_CALL_TRAMP_PREFIX_STR,
 			    STATIC_CALL_TRAMP_PREFIX_LEN)) {
 			WARN("static_call: trampoline name malformed: %s", key_name);
+			free(key_name);
 			return -1;
 		}
 		tmp = key_name + STATIC_CALL_TRAMP_PREFIX_LEN - STATIC_CALL_KEY_PREFIX_LEN;
@@ -579,6 +582,7 @@
 		if (!key_sym) {
 			if (!module) {
 				WARN("static_call: can't find static_call_key symbol: %s", tmp);
+				free(key_name);
 				return -1;
 			}
 
@@ -845,6 +849,16 @@
 	"__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",
@@ -895,6 +909,8 @@
 	"__tsan_atomic64_compare_exchange_val",
 	"__tsan_atomic_thread_fence",
 	"__tsan_atomic_signal_fence",
+	"__tsan_unaligned_read16",
+	"__tsan_unaligned_write16",
 	/* KCOV */
 	"write_comp_data",
 	"check_kcov_mode",
@@ -973,12 +989,29 @@
 	return 0;
 }
 
+/*
+ * Symbols that replace INSN_CALL_DYNAMIC, every (tail) call to such a symbol
+ * will be added to the .retpoline_sites section.
+ */
 __weak bool arch_is_retpoline(struct symbol *sym)
 {
 	return false;
 }
 
+/*
+ * Symbols that replace INSN_RETURN, every (tail) call to such a symbol
+ * will be added to the .return_sites section.
+ */
 __weak bool arch_is_rethunk(struct symbol *sym)
+{
+	return false;
+}
+
+/*
+ * Symbols that are embedded inside other instructions, because sometimes crazy
+ * code exists. These are mostly ignored for validation purposes.
+ */
+__weak bool arch_is_embedded_insn(struct symbol *sym)
 {
 	return false;
 }
@@ -1230,14 +1263,14 @@
 				continue;
 
 			/*
-			 * This is a special case for zen_untrain_ret().
+			 * This is a special case for retbleed_untrain_ret().
 			 * It jumps to __x86_return_thunk(), but objtool
 			 * can't find the thunk's starting RET
 			 * instruction, because the RET is also in the
 			 * middle of another instruction.  Objtool only
 			 * knows about the outer instruction.
 			 */
-			if (sym && sym->return_thunk) {
+			if (sym && sym->embedded_insn) {
 				add_return_call(file, insn, false);
 				continue;
 			}
@@ -2039,6 +2072,9 @@
 			if (arch_is_rethunk(func))
 				func->return_thunk = true;
 
+			if (arch_is_embedded_insn(func))
+				func->embedded_insn = true;
+
 			if (!strcmp(func->name, "__fentry__"))
 				func->fentry = true;
 
@@ -2148,12 +2184,17 @@
 	return 0;
 }
 
-static bool is_fentry_call(struct instruction *insn)
+static bool is_special_call(struct instruction *insn)
 {
-	if (insn->type == INSN_CALL &&
-	    insn->call_dest &&
-	    insn->call_dest->fentry)
-		return true;
+	if (insn->type == INSN_CALL) {
+		struct symbol *dest = insn->call_dest;
+
+		if (!dest)
+			return false;
+
+		if (dest->fentry)
+			return true;
+	}
 
 	return false;
 }
@@ -3027,7 +3068,7 @@
 			if (ret)
 				return ret;
 
-			if (!no_fp && func && !is_fentry_call(insn) &&
+			if (!no_fp && func && !is_special_call(insn) &&
 			    !has_valid_stack_frame(&state)) {
 				WARN_FUNC("call without frame pointer save/setup",
 					  sec, insn->offset);
diff --git a/kernel/tools/objtool/elf.h b/kernel/tools/objtool/elf.h
index a1863eb..19446d9 100644
--- a/kernel/tools/objtool/elf.h
+++ b/kernel/tools/objtool/elf.h
@@ -61,6 +61,7 @@
 	u8 return_thunk      : 1;
 	u8 fentry            : 1;
 	u8 kcov              : 1;
+	u8 embedded_insn     : 1;
 };
 
 struct reloc {
diff --git a/kernel/tools/perf/Makefile.config b/kernel/tools/perf/Makefile.config
index 3e7706c..89905b4 100644
--- a/kernel/tools/perf/Makefile.config
+++ b/kernel/tools/perf/Makefile.config
@@ -824,33 +824,36 @@
   endif
 endif
 
-ifeq ($(feature-libbfd), 1)
-  EXTLIBS += -lbfd -lopcodes
-else
-  # we are on a system that requires -liberty and (maybe) -lz
-  # to link against -lbfd; test each case individually here
 
-  # call all detections now so we get correct
-  # status in VF output
-  $(call feature_check,libbfd-liberty)
-  $(call feature_check,libbfd-liberty-z)
-
-  ifeq ($(feature-libbfd-liberty), 1)
-    EXTLIBS += -lbfd -lopcodes -liberty
-    FEATURE_CHECK_LDFLAGS-disassembler-four-args += -liberty -ldl
+ifndef NO_LIBBFD
+  ifeq ($(feature-libbfd), 1)
+    EXTLIBS += -lbfd -lopcodes
   else
-    ifeq ($(feature-libbfd-liberty-z), 1)
-      EXTLIBS += -lbfd -lopcodes -liberty -lz
-      FEATURE_CHECK_LDFLAGS-disassembler-four-args += -liberty -lz -ldl
-    endif
-  endif
-  $(call feature_check,disassembler-four-args)
-endif
+    # we are on a system that requires -liberty and (maybe) -lz
+    # to link against -lbfd; test each case individually here
 
-ifeq ($(feature-libbfd-buildid), 1)
-  CFLAGS += -DHAVE_LIBBFD_BUILDID_SUPPORT
-else
-  msg := $(warning Old version of libbfd/binutils things like PE executable profiling will not be available);
+    # call all detections now so we get correct
+    # status in VF output
+    $(call feature_check,libbfd-liberty)
+    $(call feature_check,libbfd-liberty-z)
+
+    ifeq ($(feature-libbfd-liberty), 1)
+      EXTLIBS += -lbfd -lopcodes -liberty
+      FEATURE_CHECK_LDFLAGS-disassembler-four-args += -liberty -ldl
+    else
+      ifeq ($(feature-libbfd-liberty-z), 1)
+        EXTLIBS += -lbfd -lopcodes -liberty -lz
+        FEATURE_CHECK_LDFLAGS-disassembler-four-args += -liberty -lz -ldl
+      endif
+    endif
+    $(call feature_check,disassembler-four-args)
+  endif
+
+  ifeq ($(feature-libbfd-buildid), 1)
+    CFLAGS += -DHAVE_LIBBFD_BUILDID_SUPPORT
+  else
+    msg := $(warning Old version of libbfd/binutils things like PE executable profiling will not be available);
+  endif
 endif
 
 ifdef NO_DEMANGLE
diff --git a/kernel/tools/perf/bench/bench.h b/kernel/tools/perf/bench/bench.h
index eac36af..9a56a44 100644
--- a/kernel/tools/perf/bench/bench.h
+++ b/kernel/tools/perf/bench/bench.h
@@ -10,25 +10,13 @@
  * The madvise transparent hugepage constants were added in glibc
  * 2.13. For compatibility with older versions of glibc, define these
  * tokens if they are not already defined.
- *
- * PA-RISC uses different madvise values from other architectures and
- * needs to be special-cased.
  */
-#ifdef __hppa__
-# ifndef MADV_HUGEPAGE
-#  define MADV_HUGEPAGE		67
-# endif
-# ifndef MADV_NOHUGEPAGE
-#  define MADV_NOHUGEPAGE	68
-# endif
-#else
 # ifndef MADV_HUGEPAGE
 #  define MADV_HUGEPAGE		14
 # endif
 # ifndef MADV_NOHUGEPAGE
 #  define MADV_NOHUGEPAGE	15
 # endif
-#endif
 
 int bench_numa(int argc, const char **argv);
 int bench_sched_messaging(int argc, const char **argv);
diff --git a/kernel/tools/perf/builtin-bench.c b/kernel/tools/perf/builtin-bench.c
index 62a7b74..fb30294 100644
--- a/kernel/tools/perf/builtin-bench.c
+++ b/kernel/tools/perf/builtin-bench.c
@@ -21,6 +21,7 @@
 #include "builtin.h"
 #include "bench/bench.h"
 
+#include <locale.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -225,7 +226,6 @@
 		if (!bench->fn)
 			break;
 		printf("# Running %s/%s benchmark...\n", coll->name, bench->name);
-		fflush(stdout);
 
 		argv[1] = bench->name;
 		run_bench(coll->name, bench->name, bench->fn, 1, argv);
@@ -245,6 +245,10 @@
 {
 	struct collection *coll;
 	int ret = 0;
+
+	/* Unbuffered output */
+	setvbuf(stdout, NULL, _IONBF, 0);
+	setlocale(LC_ALL, "");
 
 	if (argc < 2) {
 		/* No collection specified. */
@@ -299,7 +303,6 @@
 
 			if (bench_format == BENCH_FORMAT_DEFAULT)
 				printf("# Running '%s/%s' benchmark:\n", coll->name, bench->name);
-			fflush(stdout);
 			ret = run_bench(coll->name, bench->name, bench->fn, argc-1, argv+1);
 			goto end;
 		}
diff --git a/kernel/tools/perf/builtin-sched.c b/kernel/tools/perf/builtin-sched.c
index d3b5f5f..02e5774 100644
--- a/kernel/tools/perf/builtin-sched.c
+++ b/kernel/tools/perf/builtin-sched.c
@@ -670,7 +670,7 @@
 	err = pthread_attr_init(&attr);
 	BUG_ON(err);
 	err = pthread_attr_setstacksize(&attr,
-			(size_t) max(16 * 1024, PTHREAD_STACK_MIN));
+			(size_t) max(16 * 1024, (int)PTHREAD_STACK_MIN));
 	BUG_ON(err);
 	err = pthread_mutex_lock(&sched->start_work_mutex);
 	BUG_ON(err);
diff --git a/kernel/tools/perf/builtin-script.c b/kernel/tools/perf/builtin-script.c
index 5109d01..85befba 100644
--- a/kernel/tools/perf/builtin-script.c
+++ b/kernel/tools/perf/builtin-script.c
@@ -295,8 +295,7 @@
 	return (struct evsel_script *)evsel->priv;
 }
 
-static struct evsel_script *perf_evsel_script__new(struct evsel *evsel,
-							struct perf_data *data)
+static struct evsel_script *evsel_script__new(struct evsel *evsel, struct perf_data *data)
 {
 	struct evsel_script *es = zalloc(sizeof(*es));
 
@@ -316,7 +315,7 @@
 	return NULL;
 }
 
-static void perf_evsel_script__delete(struct evsel_script *es)
+static void evsel_script__delete(struct evsel_script *es)
 {
 	zfree(&es->filename);
 	fclose(es->fp);
@@ -324,7 +323,7 @@
 	free(es);
 }
 
-static int perf_evsel_script__fprintf(struct evsel_script *es, FILE *fp)
+static int evsel_script__fprintf(struct evsel_script *es, FILE *fp)
 {
 	struct stat st;
 
@@ -2147,6 +2146,9 @@
 	return 0;
 }
 
+// Used when scr->per_event_dump is not set
+static struct evsel_script es_stdout;
+
 static int process_attr(struct perf_tool *tool, union perf_event *event,
 			struct evlist **pevlist)
 {
@@ -2155,7 +2157,6 @@
 	struct evsel *evsel, *pos;
 	u64 sample_type;
 	int err;
-	static struct evsel_script *es;
 
 	err = perf_event__process_attr(tool, event, pevlist);
 	if (err)
@@ -2165,15 +2166,13 @@
 	evsel = evlist__last(*pevlist);
 
 	if (!evsel->priv) {
-		if (scr->per_event_dump) {
-			evsel->priv = perf_evsel_script__new(evsel,
-						scr->session->data);
-		} else {
-			es = zalloc(sizeof(*es));
-			if (!es)
+		if (scr->per_event_dump) { 
+			evsel->priv = evsel_script__new(evsel, scr->session->data);
+			if (!evsel->priv)
 				return -ENOMEM;
-			es->fp = stdout;
-			evsel->priv = es;
+		} else { // Replicate what is done in perf_script__setup_per_event_dump()
+			es_stdout.fp = stdout;
+			evsel->priv = &es_stdout;
 		}
 	}
 
@@ -2422,7 +2421,7 @@
 	evlist__for_each_entry(evlist, evsel) {
 		if (!evsel->priv)
 			break;
-		perf_evsel_script__delete(evsel->priv);
+		evsel_script__delete(evsel->priv);
 		evsel->priv = NULL;
 	}
 }
@@ -2442,7 +2441,7 @@
 		if (evsel->priv != NULL)
 			continue;
 
-		evsel->priv = perf_evsel_script__new(evsel, script->session->data);
+		evsel->priv = evsel_script__new(evsel, script->session->data);
 		if (evsel->priv == NULL)
 			goto out_err_fclose;
 	}
@@ -2457,7 +2456,6 @@
 static int perf_script__setup_per_event_dump(struct perf_script *script)
 {
 	struct evsel *evsel;
-	static struct evsel_script es_stdout;
 
 	if (script->per_event_dump)
 		return perf_script__fopen_per_event_dump(script);
@@ -2477,8 +2475,8 @@
 	evlist__for_each_entry(script->session->evlist, evsel) {
 		struct evsel_script *es = evsel->priv;
 
-		perf_evsel_script__fprintf(es, stdout);
-		perf_evsel_script__delete(es);
+		evsel_script__fprintf(es, stdout);
+		evsel_script__delete(es);
 		evsel->priv = NULL;
 	}
 }
diff --git a/kernel/tools/perf/builtin-top.c b/kernel/tools/perf/builtin-top.c
index 7c64134..ee30372 100644
--- a/kernel/tools/perf/builtin-top.c
+++ b/kernel/tools/perf/builtin-top.c
@@ -1743,6 +1743,7 @@
 	top.session = perf_session__new(NULL, false, NULL);
 	if (IS_ERR(top.session)) {
 		status = PTR_ERR(top.session);
+		top.session = NULL;
 		goto out_delete_evlist;
 	}
 
diff --git a/kernel/tools/perf/builtin-trace.c b/kernel/tools/perf/builtin-trace.c
index de80534..8de0d0a 100644
--- a/kernel/tools/perf/builtin-trace.c
+++ b/kernel/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 @@
 		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 bpf_map_syscall_entry {
 	bool	enabled;
-	u16	string_args_len[6];
+	u16	string_args_len[RAW_SYSCALL_ARGS_NUM];
 };
 
 /*
@@ -1641,7 +1643,7 @@
 {
 	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));
@@ -1774,11 +1776,11 @@
 #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;
@@ -1792,11 +1794,18 @@
 		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))
-		return -ENOMEM;
-
-	if (IS_ERR(sc->tp_format))
+	/*
+	 * 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;
 
 	sc->args = sc->tp_format->format.fields;
 	/*
@@ -2114,11 +2123,8 @@
 	    (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];
 
diff --git a/kernel/tools/perf/perf-completion.sh b/kernel/tools/perf/perf-completion.sh
index fdf75d4..978249d 100644
--- a/kernel/tools/perf/perf-completion.sh
+++ b/kernel/tools/perf/perf-completion.sh
@@ -165,7 +165,12 @@
 
 		local cur1=${COMP_WORDS[COMP_CWORD]}
 		local raw_evts=$($cmd list --raw-dump)
-		local arr s tmp result
+		local arr s tmp result cpu_evts
+
+		# aarch64 doesn't have /sys/bus/event_source/devices/cpu/events
+		if [[ `uname -m` != aarch64 ]]; then
+			cpu_evts=$(ls /sys/bus/event_source/devices/cpu/events)
+		fi
 
 		if [[ "$cur1" == */* && ${cur1#*/} =~ ^[A-Z] ]]; then
 			OLD_IFS="$IFS"
@@ -183,9 +188,9 @@
 				fi
 			done
 
-			evts=${result}" "$(ls /sys/bus/event_source/devices/cpu/events)
+			evts=${result}" "${cpu_evts}
 		else
-			evts=${raw_evts}" "$(ls /sys/bus/event_source/devices/cpu/events)
+			evts=${raw_evts}" "${cpu_evts}
 		fi
 
 		if [[ "$cur1" == , ]]; then
diff --git a/kernel/tools/perf/pmu-events/Build b/kernel/tools/perf/pmu-events/Build
index 215ba30..a055dee 100644
--- a/kernel/tools/perf/pmu-events/Build
+++ b/kernel/tools/perf/pmu-events/Build
@@ -6,10 +6,13 @@
 JDIR		=  pmu-events/arch/$(SRCARCH)
 JSON		=  $(shell [ -d $(JDIR) ] &&				\
 			find $(JDIR) -name '*.json' -o -name 'mapfile.csv')
+JDIR_TEST	=  pmu-events/arch/test
+JSON_TEST	=  $(shell [ -d $(JDIR_TEST) ] &&			\
+			find $(JDIR_TEST) -name '*.json')
 
 #
 # Locate/process JSON files in pmu-events/arch/
 # directory and create tables in pmu-events.c.
 #
-$(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JEVENTS)
+$(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JSON_TEST) $(JEVENTS)
 	$(Q)$(call echo-cmd,gen)$(JEVENTS) $(SRCARCH) pmu-events/arch $(OUTPUT)pmu-events/pmu-events.c $(V)
diff --git a/kernel/tools/perf/pmu-events/arch/powerpc/power9/other.json b/kernel/tools/perf/pmu-events/arch/powerpc/power9/other.json
index 3f69422..f10bd55 100644
--- a/kernel/tools/perf/pmu-events/arch/powerpc/power9/other.json
+++ b/kernel/tools/perf/pmu-events/arch/powerpc/power9/other.json
@@ -1417,7 +1417,7 @@
   {
     "EventCode": "0x45054",
     "EventName": "PM_FMA_CMPL",
-    "BriefDescription": "two flops operation completed (fmadd, fnmadd, fmsub, fnmsub) Scalar instructions only. "
+    "BriefDescription": "two flops operation completed (fmadd, fnmadd, fmsub, fnmsub) Scalar instructions only."
   },
   {
     "EventCode": "0x201E8",
@@ -2017,7 +2017,7 @@
   {
     "EventCode": "0xC0BC",
     "EventName": "PM_LSU_FLUSH_OTHER",
-    "BriefDescription": "Other LSU flushes including: Sync (sync ack from L2 caused search of LRQ for oldest snooped load, This will either signal a Precise Flush of the oldest snooped loa or a Flush Next PPC); Data Valid Flush Next (several cases of this, one example is store and reload are lined up such that a store-hit-reload scenario exists and the CDF has already launched and has gotten bad/stale data); Bad Data Valid Flush Next (might be a few cases of this, one example is a larxa (D$ hit) return data and dval but can't allocate to LMQ (LMQ full or other reason). Already gave dval but can't watch it for snoop_hit_larx. Need to take the “bad dval” back and flush all younger ops)"
+    "BriefDescription": "Other LSU flushes including: Sync (sync ack from L2 caused search of LRQ for oldest snooped load, This will either signal a Precise Flush of the oldest snooped loa or a Flush Next PPC); Data Valid Flush Next (several cases of this, one example is store and reload are lined up such that a store-hit-reload scenario exists and the CDF has already launched and has gotten bad/stale data); Bad Data Valid Flush Next (might be a few cases of this, one example is a larxa (D$ hit) return data and dval but can't allocate to LMQ (LMQ full or other reason). Already gave dval but can't watch it for snoop_hit_larx. Need to take the 'bad dval' back and flush all younger ops)"
   },
   {
     "EventCode": "0x5094",
diff --git a/kernel/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json b/kernel/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json
index d0265f2..723bffa 100644
--- a/kernel/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json
+++ b/kernel/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json
@@ -442,7 +442,7 @@
   {
     "EventCode": "0x4D052",
     "EventName": "PM_2FLOP_CMPL",
-    "BriefDescription": "DP vector version of fmul, fsub, fcmp, fsel, fabs, fnabs, fres ,fsqrte, fneg "
+    "BriefDescription": "DP vector version of fmul, fsub, fcmp, fsel, fabs, fnabs, fres ,fsqrte, fneg"
   },
   {
     "EventCode": "0x1F142",
diff --git a/kernel/tools/perf/tests/builtin-test.c b/kernel/tools/perf/tests/builtin-test.c
index 132bdb3..73c911d 100644
--- a/kernel/tools/perf/tests/builtin-test.c
+++ b/kernel/tools/perf/tests/builtin-test.c
@@ -793,6 +793,9 @@
         if (ret < 0)
                 return ret;
 
+	/* Unbuffered output */
+	setvbuf(stdout, NULL, _IONBF, 0);
+
 	argc = parse_options_subcommand(argc, argv, test_options, test_subcommands, test_usage, 0);
 	if (argc >= 1 && !strcmp(argv[0], "list"))
 		return perf_test__list(argc - 1, argv + 1);
diff --git a/kernel/tools/perf/tests/shell/test_uprobe_from_different_cu.sh b/kernel/tools/perf/tests/shell/test_uprobe_from_different_cu.sh
new file mode 100644
index 0000000..319f36e
--- /dev/null
+++ b/kernel/tools/perf/tests/shell/test_uprobe_from_different_cu.sh
@@ -0,0 +1,83 @@
+#!/bin/bash
+# test perf probe of function from different CU
+# SPDX-License-Identifier: GPL-2.0
+
+set -e
+
+# skip if there's no gcc
+if ! [ -x "$(command -v gcc)" ]; then
+        echo "failed: no gcc compiler"
+        exit 2
+fi
+
+temp_dir=$(mktemp -d /tmp/perf-uprobe-different-cu-sh.XXXXXXXXXX)
+
+cleanup()
+{
+	trap - EXIT TERM INT
+	if [[ "${temp_dir}" =~ ^/tmp/perf-uprobe-different-cu-sh.*$ ]]; then
+		echo "--- Cleaning up ---"
+		perf probe -x ${temp_dir}/testfile -d foo || true
+		rm -f "${temp_dir}/"*
+		rmdir "${temp_dir}"
+	fi
+}
+
+trap_cleanup()
+{
+        cleanup
+        exit 1
+}
+
+trap trap_cleanup EXIT TERM INT
+
+cat > ${temp_dir}/testfile-foo.h << EOF
+struct t
+{
+  int *p;
+  int c;
+};
+
+extern int foo (int i, struct t *t);
+EOF
+
+cat > ${temp_dir}/testfile-foo.c << EOF
+#include "testfile-foo.h"
+
+int
+foo (int i, struct t *t)
+{
+  int j, res = 0;
+  for (j = 0; j < i && j < t->c; j++)
+    res += t->p[j];
+
+  return res;
+}
+EOF
+
+cat > ${temp_dir}/testfile-main.c << EOF
+#include "testfile-foo.h"
+
+static struct t g;
+
+int
+main (int argc, char **argv)
+{
+  int i;
+  int j[argc];
+  g.c = argc;
+  g.p = j;
+  for (i = 0; i < argc; i++)
+    j[i] = (int) argv[i][0];
+  return foo (3, &g);
+}
+EOF
+
+gcc -g -Og -flto -c ${temp_dir}/testfile-foo.c -o ${temp_dir}/testfile-foo.o
+gcc -g -Og -c ${temp_dir}/testfile-main.c -o ${temp_dir}/testfile-main.o
+gcc -g -Og -o ${temp_dir}/testfile ${temp_dir}/testfile-foo.o ${temp_dir}/testfile-main.o
+
+perf probe -x ${temp_dir}/testfile --funcs foo
+perf probe -x ${temp_dir}/testfile foo
+
+cleanup
diff --git a/kernel/tools/perf/ui/browsers/hists.c b/kernel/tools/perf/ui/browsers/hists.c
index b0e1880..f2586e4 100644
--- a/kernel/tools/perf/ui/browsers/hists.c
+++ b/kernel/tools/perf/ui/browsers/hists.c
@@ -407,11 +407,6 @@
 	return container_of(ms, struct callchain_list, ms)->has_children;
 }
 
-static bool hist_browser__he_selection_unfolded(struct hist_browser *browser)
-{
-	return browser->he_selection ? browser->he_selection->unfolded : false;
-}
-
 static bool hist_browser__selection_unfolded(struct hist_browser *browser)
 {
 	struct hist_entry *he = browser->he_selection;
@@ -584,8 +579,8 @@
 	return n;
 }
 
-static void __hist_entry__set_folding(struct hist_entry *he,
-				      struct hist_browser *hb, bool unfold)
+static void hist_entry__set_folding(struct hist_entry *he,
+				    struct hist_browser *hb, bool unfold)
 {
 	hist_entry__init_have_children(he);
 	he->unfolded = unfold ? he->has_children : false;
@@ -603,34 +598,12 @@
 		he->nr_rows = 0;
 }
 
-static void hist_entry__set_folding(struct hist_entry *he,
-				    struct hist_browser *browser, bool unfold)
-{
-	double percent;
-
-	percent = hist_entry__get_percent_limit(he);
-	if (he->filtered || percent < browser->min_pcnt)
-		return;
-
-	__hist_entry__set_folding(he, browser, unfold);
-
-	if (!he->depth || unfold)
-		browser->nr_hierarchy_entries++;
-	if (he->leaf)
-		browser->nr_callchain_rows += he->nr_rows;
-	else if (unfold && !hist_entry__has_hierarchy_children(he, browser->min_pcnt)) {
-		browser->nr_hierarchy_entries++;
-		he->has_no_entry = true;
-		he->nr_rows = 1;
-	} else
-		he->has_no_entry = false;
-}
-
 static void
 __hist_browser__set_folding(struct hist_browser *browser, bool unfold)
 {
 	struct rb_node *nd;
 	struct hist_entry *he;
+	double percent;
 
 	nd = rb_first_cached(&browser->hists->entries);
 	while (nd) {
@@ -640,6 +613,21 @@
 		nd = __rb_hierarchy_next(nd, HMD_FORCE_CHILD);
 
 		hist_entry__set_folding(he, browser, unfold);
+
+		percent = hist_entry__get_percent_limit(he);
+		if (he->filtered || percent < browser->min_pcnt)
+			continue;
+
+		if (!he->depth || unfold)
+			browser->nr_hierarchy_entries++;
+		if (he->leaf)
+			browser->nr_callchain_rows += he->nr_rows;
+		else if (unfold && !hist_entry__has_hierarchy_children(he, browser->min_pcnt)) {
+			browser->nr_hierarchy_entries++;
+			he->has_no_entry = true;
+			he->nr_rows = 1;
+		} else
+			he->has_no_entry = false;
 	}
 }
 
@@ -659,8 +647,10 @@
 	if (!browser->he_selection)
 		return;
 
-	hist_entry__set_folding(browser->he_selection, browser, unfold);
-	browser->b.nr_entries = hist_browser__nr_entries(browser);
+	if (unfold == browser->he_selection->unfolded)
+		return;
+
+	hist_browser__toggle_fold(browser);
 }
 
 static void ui_browser__warn_lost_events(struct ui_browser *browser)
@@ -731,8 +721,8 @@
 		hist_browser__set_folding(browser, true);
 		break;
 	case 'e':
-		/* Expand the selected entry. */
-		hist_browser__set_folding_selected(browser, !hist_browser__he_selection_unfolded(browser));
+		/* Toggle expand/collapse the selected entry. */
+		hist_browser__toggle_fold(browser);
 		break;
 	case 'H':
 		browser->show_headers = !browser->show_headers;
@@ -1778,7 +1768,7 @@
 	hists_browser__scnprintf_hierarchy_headers(browser, headers,
 						   sizeof(headers));
 
-	ui_browser__gotorc(&browser->b, 0, 0);
+	ui_browser__gotorc_title(&browser->b, 0, 0);
 	ui_browser__set_color(&browser->b, HE_COLORSET_ROOT);
 	ui_browser__write_nstring(&browser->b, headers, browser->b.width + 1);
 }
diff --git a/kernel/tools/perf/util/Build b/kernel/tools/perf/util/Build
index 0cf2735..0f9732d 100644
--- a/kernel/tools/perf/util/Build
+++ b/kernel/tools/perf/util/Build
@@ -253,6 +253,12 @@
 else
   bison_flags += -w
 endif
+
+BISON_LT_381 := $(shell expr $(shell $(BISON) --version | grep bison | sed -e 's/.\+ \([0-9]\+\).\([0-9]\+\).\([0-9]\+\)/\1\2\3/g') \< 381)
+ifeq ($(BISON_LT_381),1)
+  bison_flags += -DYYNOMEM=YYABORT
+endif
+
 CFLAGS_parse-events-bison.o += $(bison_flags)
 CFLAGS_pmu-bison.o          += -DYYLTYPE_IS_TRIVIAL=0 $(bison_flags)
 CFLAGS_expr-bison.o         += -DYYLTYPE_IS_TRIVIAL=0 $(bison_flags)
diff --git a/kernel/tools/perf/util/annotate.c b/kernel/tools/perf/util/annotate.c
index 3081894..c9078ce 100644
--- a/kernel/tools/perf/util/annotate.c
+++ b/kernel/tools/perf/util/annotate.c
@@ -1718,8 +1718,11 @@
 	perf_exe(tpath, sizeof(tpath));
 
 	bfdf = bfd_openr(tpath, NULL);
-	assert(bfdf);
-	assert(bfd_check_format(bfdf, bfd_object));
+	if (bfdf == NULL)
+		abort();
+
+	if (!bfd_check_format(bfdf, bfd_object))
+		abort();
 
 	s = open_memstream(&buf, &buf_size);
 	if (!s) {
@@ -1767,7 +1770,8 @@
 #else
 	disassemble = disassembler(bfdf);
 #endif
-	assert(disassemble);
+	if (disassemble == NULL)
+		abort();
 
 	fflush(s);
 	do {
diff --git a/kernel/tools/perf/util/auxtrace.c b/kernel/tools/perf/util/auxtrace.c
index d96e86d..41dd4c2 100644
--- a/kernel/tools/perf/util/auxtrace.c
+++ b/kernel/tools/perf/util/auxtrace.c
@@ -2279,6 +2279,7 @@
 			       char type, u64 start)
 {
 	struct sym_args *args = arg;
+	u64 size;
 
 	if (!kallsyms__is_function(type))
 		return 0;
@@ -2288,7 +2289,9 @@
 		args->start = start;
 	}
 	/* Don't know exactly where the kernel ends, so we add a page */
-	args->size = round_up(start, page_size) + page_size - args->start;
+	size = round_up(start, page_size) + page_size - args->start;
+	if (size > args->size)
+		args->size = size;
 
 	return 0;
 }
@@ -2449,7 +2452,7 @@
 				*size = sym->start - *start;
 			if (idx > 0) {
 				if (*size)
-					return 1;
+					return 0;
 			} else if (dso_sym_match(sym, sym_name, &cnt, idx)) {
 				print_duplicate_syms(dso, sym_name);
 				return -EINVAL;
diff --git a/kernel/tools/perf/util/data.c b/kernel/tools/perf/util/data.c
index 4875408..29d32ba 100644
--- a/kernel/tools/perf/util/data.c
+++ b/kernel/tools/perf/util/data.c
@@ -127,6 +127,7 @@
 		file->size = st.st_size;
 	}
 
+	closedir(dir);
 	if (!files)
 		return -EINVAL;
 
@@ -135,6 +136,7 @@
 	return 0;
 
 out_err:
+	closedir(dir);
 	close_dir(files, nr);
 	return ret;
 }
diff --git a/kernel/tools/perf/util/debug.c b/kernel/tools/perf/util/debug.c
index 0af163a..854dd3d 100644
--- a/kernel/tools/perf/util/debug.c
+++ b/kernel/tools/perf/util/debug.c
@@ -207,6 +207,10 @@
 		opt++;
 	}
 
+	/* For debug variables that are used as bool types, set to 0. */
+	redirect_to_stderr = 0;
+	debug_peo_args = 0;
+
 	return 0;
 }
 
diff --git a/kernel/tools/perf/util/dwarf-aux.c b/kernel/tools/perf/util/dwarf-aux.c
index 4343356..443374a 100644
--- a/kernel/tools/perf/util/dwarf-aux.c
+++ b/kernel/tools/perf/util/dwarf-aux.c
@@ -308,21 +308,8 @@
 {
 	Dwarf_Attribute attr;
 
-	if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
+	if (dwarf_attr_integrate(tp_die, attr_name, &attr) == NULL ||
 	    dwarf_formudata(&attr, result) != 0)
-		return -ENOENT;
-
-	return 0;
-}
-
-/* Get attribute and translate it as a sdata */
-static int die_get_attr_sdata(Dwarf_Die *tp_die, unsigned int attr_name,
-			      Dwarf_Sword *result)
-{
-	Dwarf_Attribute attr;
-
-	if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
-	    dwarf_formsdata(&attr, result) != 0)
 		return -ENOENT;
 
 	return 0;
@@ -467,9 +454,9 @@
 /* Get the call file index number in CU DIE */
 static int die_get_call_fileno(Dwarf_Die *in_die)
 {
-	Dwarf_Sword idx;
+	Dwarf_Word idx;
 
-	if (die_get_attr_sdata(in_die, DW_AT_call_file, &idx) == 0)
+	if (die_get_attr_udata(in_die, DW_AT_call_file, &idx) == 0)
 		return (int)idx;
 	else
 		return -ENOENT;
@@ -478,9 +465,9 @@
 /* Get the declared file index number in CU DIE */
 static int die_get_decl_fileno(Dwarf_Die *pdie)
 {
-	Dwarf_Sword idx;
+	Dwarf_Word idx;
 
-	if (die_get_attr_sdata(pdie, DW_AT_decl_file, &idx) == 0)
+	if (die_get_attr_udata(pdie, DW_AT_decl_file, &idx) == 0)
 		return (int)idx;
 	else
 		return -ENOENT;
@@ -1094,7 +1081,7 @@
 	ret = die_get_typename(vr_die, buf);
 	if (ret < 0) {
 		pr_debug("Failed to get type, make it unknown.\n");
-		ret = strbuf_add(buf, " (unknown_type)", 14);
+		ret = strbuf_add(buf, "(unknown_type)", 14);
 	}
 
 	return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die));
diff --git a/kernel/tools/perf/util/header.c b/kernel/tools/perf/util/header.c
index be850e9..dd06770 100644
--- a/kernel/tools/perf/util/header.c
+++ b/kernel/tools/perf/util/header.c
@@ -3987,7 +3987,8 @@
 			     union perf_event *event,
 			     struct evlist **pevlist)
 {
-	u32 i, ids, n_ids;
+	u32 i, n_ids;
+	u64 *ids;
 	struct evsel *evsel;
 	struct evlist *evlist = *pevlist;
 
@@ -4003,9 +4004,8 @@
 
 	evlist__add(evlist, evsel);
 
-	ids = event->header.size;
-	ids -= (void *)&event->attr.id - (void *)event;
-	n_ids = ids / sizeof(u64);
+	n_ids = event->header.size - sizeof(event->header) - event->attr.attr.size;
+	n_ids = n_ids / sizeof(u64);
 	/*
 	 * We don't have the cpu and thread maps on the header, so
 	 * for allocating the perf_sample_id table we fake 1 cpu and
@@ -4014,8 +4014,9 @@
 	if (perf_evsel__alloc_id(&evsel->core, 1, n_ids))
 		return -ENOMEM;
 
+	ids = (void *)&event->attr.attr + event->attr.attr.size;
 	for (i = 0; i < n_ids; i++) {
-		perf_evlist__id_add(&evlist->core, &evsel->core, 0, i, event->attr.id[i]);
+		perf_evlist__id_add(&evlist->core, &evsel->core, 0, i, ids[i]);
 	}
 
 	return 0;
diff --git a/kernel/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/kernel/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
index e4c485f..48fda1a 100644
--- a/kernel/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/kernel/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -1639,6 +1639,8 @@
 
 	decoder->cbr = cbr;
 	decoder->cbr_cyc_to_tsc = decoder->max_non_turbo_ratio_fp / cbr;
+	decoder->cyc_ref_timestamp = decoder->timestamp;
+	decoder->cycle_cnt = 0;
 
 	intel_pt_mtc_cyc_cnt_cbr(decoder);
 }
diff --git a/kernel/tools/perf/util/llvm-utils.c b/kernel/tools/perf/util/llvm-utils.c
index 0bf6b4d..570cde4 100644
--- a/kernel/tools/perf/util/llvm-utils.c
+++ b/kernel/tools/perf/util/llvm-utils.c
@@ -525,14 +525,37 @@
 
 	pr_debug("llvm compiling command template: %s\n", template);
 
+	/*
+	 * Below, substitute control characters for values that can cause the
+	 * echo to misbehave, then substitute the values back.
+	 */
 	err = -ENOMEM;
-	if (asprintf(&command_echo, "echo -n \"%s\"", template) < 0)
+	if (asprintf(&command_echo, "echo -n \a%s\a", template) < 0)
 		goto errout;
 
+#define SWAP_CHAR(a, b) do { if (*p == a) *p = b; } while (0)
+	for (char *p = command_echo; *p; p++) {
+		SWAP_CHAR('<', '\001');
+		SWAP_CHAR('>', '\002');
+		SWAP_CHAR('"', '\003');
+		SWAP_CHAR('\'', '\004');
+		SWAP_CHAR('|', '\005');
+		SWAP_CHAR('&', '\006');
+		SWAP_CHAR('\a', '"');
+	}
 	err = read_from_pipe(command_echo, (void **) &command_out, NULL);
 	if (err)
 		goto errout;
 
+	for (char *p = command_out; *p; p++) {
+		SWAP_CHAR('\001', '<');
+		SWAP_CHAR('\002', '>');
+		SWAP_CHAR('\003', '"');
+		SWAP_CHAR('\004', '\'');
+		SWAP_CHAR('\005', '|');
+		SWAP_CHAR('\006', '&');
+	}
+#undef SWAP_CHAR
 	pr_debug("llvm compiling command : %s\n", command_out);
 
 	err = read_from_pipe(template, &obj_buf, &obj_buf_sz);
diff --git a/kernel/tools/perf/util/pmu.c b/kernel/tools/perf/util/pmu.c
index ac45da0..d322305 100644
--- a/kernel/tools/perf/util/pmu.c
+++ b/kernel/tools/perf/util/pmu.c
@@ -1670,7 +1670,7 @@
 	return 0;
 
 free_name:
-	zfree(caps->name);
+	zfree(&caps->name);
 free_caps:
 	free(caps);
 
diff --git a/kernel/tools/perf/util/sort.c b/kernel/tools/perf/util/sort.c
index 5e9e964..4280610 100644
--- a/kernel/tools/perf/util/sort.c
+++ b/kernel/tools/perf/util/sort.c
@@ -873,8 +873,7 @@
 static int64_t
 sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right)
 {
-	struct addr_map_symbol *from_l = &left->branch_info->from;
-	struct addr_map_symbol *from_r = &right->branch_info->from;
+	struct addr_map_symbol *from_l, *from_r;
 
 	if (!left->branch_info || !right->branch_info)
 		return cmp_null(left->branch_info, right->branch_info);
diff --git a/kernel/tools/perf/util/symbol-elf.c b/kernel/tools/perf/util/symbol-elf.c
index 3e423a9..b171d13 100644
--- a/kernel/tools/perf/util/symbol-elf.c
+++ b/kernel/tools/perf/util/symbol-elf.c
@@ -548,7 +548,7 @@
 				size_t sz = min(size, descsz);
 				memcpy(bf, ptr, sz);
 				memset(bf + sz, 0, size - sz);
-				err = descsz;
+				err = sz;
 				break;
 			}
 		}
@@ -1247,7 +1247,7 @@
 			   (!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",
diff --git a/kernel/tools/power/cpupower/Makefile b/kernel/tools/power/cpupower/Makefile
index c7bcddb..3b15944 100644
--- a/kernel/tools/power/cpupower/Makefile
+++ b/kernel/tools/power/cpupower/Makefile
@@ -270,14 +270,14 @@
 	$(MAKE) -C bench O=$(OUTPUT) clean
 
 
-install-lib:
+install-lib: libcpupower
 	$(INSTALL) -d $(DESTDIR)${libdir}
 	$(CP) $(OUTPUT)libcpupower.so* $(DESTDIR)${libdir}/
 	$(INSTALL) -d $(DESTDIR)${includedir}
 	$(INSTALL_DATA) lib/cpufreq.h $(DESTDIR)${includedir}/cpufreq.h
 	$(INSTALL_DATA) lib/cpuidle.h $(DESTDIR)${includedir}/cpuidle.h
 
-install-tools:
+install-tools: $(OUTPUT)cpupower
 	$(INSTALL) -d $(DESTDIR)${bindir}
 	$(INSTALL_PROGRAM) $(OUTPUT)cpupower $(DESTDIR)${bindir}
 	$(INSTALL) -d $(DESTDIR)${bash_completion_dir}
@@ -293,14 +293,14 @@
 	$(INSTALL_DATA) -D man/cpupower-info.1 $(DESTDIR)${mandir}/man1/cpupower-info.1
 	$(INSTALL_DATA) -D man/cpupower-monitor.1 $(DESTDIR)${mandir}/man1/cpupower-monitor.1
 
-install-gmo:
+install-gmo: create-gmo
 	$(INSTALL) -d $(DESTDIR)${localedir}
 	for HLANG in $(LANGUAGES); do \
 		echo '$(INSTALL_DATA) -D $(OUTPUT)po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo'; \
 		$(INSTALL_DATA) -D $(OUTPUT)po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \
 	done;
 
-install-bench:
+install-bench: compile-bench
 	@#DESTDIR must be set from outside to survive
 	@sbindir=$(sbindir) bindir=$(bindir) docdir=$(docdir) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT) install
 
diff --git a/kernel/tools/power/cpupower/bench/Makefile b/kernel/tools/power/cpupower/bench/Makefile
index f68b4bc..d9d9923 100644
--- a/kernel/tools/power/cpupower/bench/Makefile
+++ b/kernel/tools/power/cpupower/bench/Makefile
@@ -27,7 +27,7 @@
 
 all: $(OUTPUT)cpufreq-bench
 
-install:
+install: $(OUTPUT)cpufreq-bench
 	mkdir -p $(DESTDIR)/$(sbindir)
 	mkdir -p $(DESTDIR)/$(bindir)
 	mkdir -p $(DESTDIR)/$(docdir)
diff --git a/kernel/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/kernel/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
index e7d48cb..ae6af35 100644
--- a/kernel/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
+++ b/kernel/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
@@ -70,8 +70,8 @@
  */
 static unsigned long max_frequency;
 
-static unsigned long long tsc_at_measure_start;
-static unsigned long long tsc_at_measure_end;
+static unsigned long long *tsc_at_measure_start;
+static unsigned long long *tsc_at_measure_end;
 static unsigned long long *mperf_previous_count;
 static unsigned long long *aperf_previous_count;
 static unsigned long long *mperf_current_count;
@@ -169,7 +169,7 @@
 	aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];
 
 	if (max_freq_mode == MAX_FREQ_TSC_REF) {
-		tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
+		tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu];
 		*percent = 100.0 * mperf_diff / tsc_diff;
 		dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n",
 		       mperf_cstates[id].name, mperf_diff, tsc_diff);
@@ -206,7 +206,7 @@
 
 	if (max_freq_mode == MAX_FREQ_TSC_REF) {
 		/* Calculate max_freq from TSC count */
-		tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
+		tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu];
 		time_diff = timespec_diff_us(time_start, time_end);
 		max_frequency = tsc_diff / time_diff;
 	}
@@ -225,33 +225,27 @@
 static int mperf_start(void)
 {
 	int cpu;
-	unsigned long long dbg;
 
 	clock_gettime(CLOCK_REALTIME, &time_start);
-	mperf_get_tsc(&tsc_at_measure_start);
 
-	for (cpu = 0; cpu < cpu_count; cpu++)
+	for (cpu = 0; cpu < cpu_count; cpu++) {
+		mperf_get_tsc(&tsc_at_measure_start[cpu]);
 		mperf_init_stats(cpu);
+	}
 
-	mperf_get_tsc(&dbg);
-	dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start);
 	return 0;
 }
 
 static int mperf_stop(void)
 {
-	unsigned long long dbg;
 	int cpu;
 
-	for (cpu = 0; cpu < cpu_count; cpu++)
+	for (cpu = 0; cpu < cpu_count; cpu++) {
 		mperf_measure_stats(cpu);
+		mperf_get_tsc(&tsc_at_measure_end[cpu]);
+	}
 
-	mperf_get_tsc(&tsc_at_measure_end);
 	clock_gettime(CLOCK_REALTIME, &time_end);
-
-	mperf_get_tsc(&dbg);
-	dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end);
-
 	return 0;
 }
 
@@ -353,7 +347,8 @@
 	aperf_previous_count = calloc(cpu_count, sizeof(unsigned long long));
 	mperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
 	aperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
-
+	tsc_at_measure_start = calloc(cpu_count, sizeof(unsigned long long));
+	tsc_at_measure_end = calloc(cpu_count, sizeof(unsigned long long));
 	mperf_monitor.name_len = strlen(mperf_monitor.name);
 	return &mperf_monitor;
 }
@@ -364,6 +359,8 @@
 	free(aperf_previous_count);
 	free(mperf_current_count);
 	free(aperf_current_count);
+	free(tsc_at_measure_start);
+	free(tsc_at_measure_end);
 	free(is_valid);
 }
 
diff --git a/kernel/tools/power/x86/turbostat/turbostat.8 b/kernel/tools/power/x86/turbostat/turbostat.8
index f6b7e85..71e3f3a 100644
--- a/kernel/tools/power/x86/turbostat/turbostat.8
+++ b/kernel/tools/power/x86/turbostat/turbostat.8
@@ -294,6 +294,8 @@
 
 # chmod +r /dev/cpu/*/msr
 
+# chmod +r /dev/cpu_dma_latency
+
 .B "turbostat "
 reads hardware counters, but doesn't write them.
 So it will not interfere with the OS or other programs, including
diff --git a/kernel/tools/power/x86/turbostat/turbostat.c b/kernel/tools/power/x86/turbostat/turbostat.c
index ef65f7e..d33c9d4 100644
--- a/kernel/tools/power/x86/turbostat/turbostat.c
+++ b/kernel/tools/power/x86/turbostat/turbostat.c
@@ -5004,7 +5004,7 @@
 
 	retval = read(fd, (void *)&value, sizeof(int));
 	if (retval != sizeof(int)) {
-		warn("read %s\n", path);
+		warn("read failed %s\n", path);
 		close(fd);
 		return;
 	}
diff --git a/kernel/tools/testing/ktest/ktest.pl b/kernel/tools/testing/ktest/ktest.pl
index 4e24509..ea26f2b 100755
--- a/kernel/tools/testing/ktest/ktest.pl
+++ b/kernel/tools/testing/ktest/ktest.pl
@@ -178,6 +178,7 @@
 my $store_successes;
 my $test_name;
 my $timeout;
+my $run_timeout;
 my $connect_timeout;
 my $config_bisect_exec;
 my $booted_timeout;
@@ -340,6 +341,7 @@
     "STORE_SUCCESSES"		=> \$store_successes,
     "TEST_NAME"			=> \$test_name,
     "TIMEOUT"			=> \$timeout,
+    "RUN_TIMEOUT"		=> \$run_timeout,
     "CONNECT_TIMEOUT"		=> \$connect_timeout,
     "CONFIG_BISECT_EXEC"	=> \$config_bisect_exec,
     "BOOTED_TIMEOUT"		=> \$booted_timeout,
@@ -1433,7 +1435,8 @@
 
 	# Still need to wait for the reboot to finish
 	wait_for_monitor($time, $reboot_success_line);
-
+    }
+    if ($powercycle || $time) {
 	end_monitor;
     }
 }
@@ -1799,6 +1802,14 @@
     $command =~ s/\$SSH_USER/$ssh_user/g;
     $command =~ s/\$MACHINE/$machine/g;
 
+    if (!defined($timeout)) {
+	$timeout = $run_timeout;
+    }
+
+    if (!defined($timeout)) {
+	$timeout = -1; # tell wait_for_input to wait indefinitely
+    }
+
     doprint("$command ... ");
     $start_time = time;
 
@@ -1825,13 +1836,10 @@
 
     while (1) {
 	my $fp = \*CMD;
-	if (defined($timeout)) {
-	    doprint "timeout = $timeout\n";
-	}
 	my $line = wait_for_input($fp, $timeout);
 	if (!defined($line)) {
 	    my $now = time;
-	    if (defined($timeout) && (($now - $start_time) >= $timeout)) {
+	    if ($timeout >= 0 && (($now - $start_time) >= $timeout)) {
 		doprint "Hit timeout of $timeout, killing process\n";
 		$hit_timeout = 1;
 		kill 9, $pid;
@@ -1912,7 +1920,7 @@
 
 sub _get_grub_index {
 
-    my ($command, $target, $skip) = @_;
+    my ($command, $target, $skip, $submenu) = @_;
 
     return if (defined($grub_number) && defined($last_grub_menu) &&
 	       $last_grub_menu eq $grub_menu && defined($last_machine) &&
@@ -1929,11 +1937,16 @@
 
     my $found = 0;
 
+    my $submenu_number = 0;
+
     while (<IN>) {
 	if (/$target/) {
 	    $grub_number++;
 	    $found = 1;
 	    last;
+	} elsif (defined($submenu) && /$submenu/) {
+		$submenu_number++;
+		$grub_number = -1;
 	} elsif (/$skip/) {
 	    $grub_number++;
 	}
@@ -1942,6 +1955,9 @@
 
     dodie "Could not find '$grub_menu' through $command on $machine"
 	if (!$found);
+    if ($submenu_number > 0) {
+	$grub_number = "$submenu_number>$grub_number";
+    }
     doprint "$grub_number\n";
     $last_grub_menu = $grub_menu;
     $last_machine = $machine;
@@ -1952,6 +1968,7 @@
     my $command;
     my $target;
     my $skip;
+    my $submenu;
     my $grub_menu_qt;
 
     if ($reboot_type !~ /^grub/) {
@@ -1966,8 +1983,9 @@
 	$skip = '^\s*title\s';
     } elsif ($reboot_type eq "grub2") {
 	$command = "cat $grub_file";
-	$target = '^menuentry.*' . $grub_menu_qt;
-	$skip = '^menuentry\s|^submenu\s';
+	$target = '^\s*menuentry.*' . $grub_menu_qt;
+	$skip = '^\s*menuentry';
+	$submenu = '^\s*submenu\s';
     } elsif ($reboot_type eq "grub2bls") {
         $command = $grub_bls_get;
         $target = '^title=.*' . $grub_menu_qt;
@@ -1976,7 +1994,7 @@
 	return;
     }
 
-    _get_grub_index($command, $target, $skip);
+    _get_grub_index($command, $target, $skip, $submenu);
 }
 
 sub wait_for_input
@@ -1992,6 +2010,11 @@
 
     if (!defined($time)) {
 	$time = $timeout;
+    }
+
+    if ($time < 0) {
+	# Negative number means wait indefinitely
+	undef $time;
     }
 
     $rin = '';
@@ -2040,7 +2063,7 @@
     if ($reboot_type eq "grub") {
 	run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
     } elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) {
-	run_ssh "$grub_reboot $grub_number";
+	run_ssh "$grub_reboot \"'$grub_number'\"";
     } elsif ($reboot_type eq "syslinux") {
 	run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
     } elsif (defined $reboot_script) {
@@ -3763,9 +3786,10 @@
     # .config to make sure it is missing the config that
     # we had before
     my %configs = %min_configs;
-    delete $configs{$config};
+    $configs{$config} = "# $config is not set";
     make_new_config ((values %configs), (values %keep_configs));
     make_oldconfig;
+    delete $configs{$config};
     undef %configs;
     assign_configs \%configs, $output_config;
 
@@ -4272,6 +4296,9 @@
 }
 
 sub cancel_test {
+    if ($monitor_cnt) {
+	end_monitor;
+    }
     if ($email_when_canceled) {
 	my $name = get_test_name;
         send_email("KTEST: Your [$name] test was cancelled",
diff --git a/kernel/tools/testing/ktest/sample.conf b/kernel/tools/testing/ktest/sample.conf
index 5e7d1d7..65957a9 100644
--- a/kernel/tools/testing/ktest/sample.conf
+++ b/kernel/tools/testing/ktest/sample.conf
@@ -809,6 +809,11 @@
 # is issued instead of a reboot.
 # CONNECT_TIMEOUT = 25
 
+# The timeout in seconds for how long to wait for any running command
+# to timeout. If not defined, it will let it go indefinitely.
+# (default undefined)
+#RUN_TIMEOUT = 600
+
 # In between tests, a reboot of the box may occur, and this
 # is the time to wait for the console after it stops producing
 # output. Some machines may not produce a large lag on reboot
diff --git a/kernel/tools/testing/radix-tree/regression1.c b/kernel/tools/testing/radix-tree/regression1.c
index a61c7bc..63f468b 100644
--- a/kernel/tools/testing/radix-tree/regression1.c
+++ b/kernel/tools/testing/radix-tree/regression1.c
@@ -177,7 +177,7 @@
 	nr_threads = 2;
 	pthread_barrier_init(&worker_barrier, NULL, nr_threads);
 
-	threads = malloc(nr_threads * sizeof(pthread_t *));
+	threads = malloc(nr_threads * sizeof(*threads));
 
 	for (i = 0; i < nr_threads; i++) {
 		arg = i;
diff --git a/kernel/tools/testing/selftests/Makefile b/kernel/tools/testing/selftests/Makefile
index 5074c8b..81fc7d1 100644
--- a/kernel/tools/testing/selftests/Makefile
+++ b/kernel/tools/testing/selftests/Makefile
@@ -104,19 +104,27 @@
 override LDFLAGS =
 endif
 
-ifneq ($(O),)
-	BUILD := $(O)/kselftest
+top_srcdir ?= ../../..
+
+ifeq ("$(origin O)", "command line")
+  KBUILD_OUTPUT := $(O)
+endif
+
+ifneq ($(KBUILD_OUTPUT),)
+  # Make's built-in functions such as $(abspath ...), $(realpath ...) cannot
+  # expand a shell special character '~'. We use a somewhat tedious way here.
+  abs_objtree := $(shell cd $(top_srcdir) && mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) && pwd)
+  $(if $(abs_objtree),, \
+    $(error failed to create output directory "$(KBUILD_OUTPUT)"))
+  # $(realpath ...) resolves symlinks
+  abs_objtree := $(realpath $(abs_objtree))
+  BUILD := $(abs_objtree)/kselftest
 else
-	ifneq ($(KBUILD_OUTPUT),)
-		BUILD := $(KBUILD_OUTPUT)/kselftest
-	else
-		BUILD := $(shell pwd)
-		DEFAULT_INSTALL_HDR_PATH := 1
-	endif
+  BUILD := $(CURDIR)
+  DEFAULT_INSTALL_HDR_PATH := 1
 endif
 
 # Prepare for headers install
-top_srcdir ?= ../../..
 include $(top_srcdir)/scripts/subarch.include
 ARCH           ?= $(SUBARCH)
 export KSFT_KHDR_INSTALL_DONE := 1
diff --git a/kernel/tools/testing/selftests/bpf/Makefile b/kernel/tools/testing/selftests/bpf/Makefile
index 1d91555..a845724 100644
--- a/kernel/tools/testing/selftests/bpf/Makefile
+++ b/kernel/tools/testing/selftests/bpf/Makefile
@@ -119,8 +119,6 @@
 # NOTE: Semicolon at the end is critical to override lib.mk's default static
 # rule for binaries.
 $(notdir $(TEST_GEN_PROGS)						\
-	 $(TEST_PROGS)							\
-	 $(TEST_PROGS_EXTENDED)						\
 	 $(TEST_GEN_PROGS_EXTENDED)					\
 	 $(TEST_CUSTOM_PROGS)): %: $(OUTPUT)/% ;
 
diff --git a/kernel/tools/testing/selftests/bpf/benchs/run_bench_rename.sh b/kernel/tools/testing/selftests/bpf/benchs/run_bench_rename.sh
index 16f774b..7b281db 100755
--- a/kernel/tools/testing/selftests/bpf/benchs/run_bench_rename.sh
+++ b/kernel/tools/testing/selftests/bpf/benchs/run_bench_rename.sh
@@ -2,7 +2,7 @@
 
 set -eufo pipefail
 
-for i in base kprobe kretprobe rawtp fentry fexit fmodret
+for i in base kprobe kretprobe rawtp fentry fexit
 do
 	summary=$(sudo ./bench -w2 -d5 -a rename-$i | tail -n1 | cut -d'(' -f1 | cut -d' ' -f3-)
 	printf "%-10s: %s\n" $i "$summary"
diff --git a/kernel/tools/testing/selftests/bpf/prog_tests/align.c b/kernel/tools/testing/selftests/bpf/prog_tests/align.c
index 5861446..7996ec0 100644
--- a/kernel/tools/testing/selftests/bpf/prog_tests/align.c
+++ b/kernel/tools/testing/selftests/bpf/prog_tests/align.c
@@ -2,7 +2,7 @@
 #include <test_progs.h>
 
 #define MAX_INSNS	512
-#define MAX_MATCHES	16
+#define MAX_MATCHES	24
 
 struct bpf_reg_match {
 	unsigned int line;
@@ -267,6 +267,7 @@
 			 */
 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
 			BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
+			BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
@@ -280,6 +281,7 @@
 			BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
 			BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
+			BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 4),
 			BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
@@ -311,44 +313,52 @@
 			{15, "R4=pkt(id=1,off=18,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"},
 			{15, "R5=pkt(id=1,off=14,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"},
 			/* Variable offset is added to R5 packet pointer,
-			 * resulting in auxiliary alignment of 4.
+			 * resulting in auxiliary alignment of 4. To avoid BPF
+			 * verifier's precision backtracking logging
+			 * interfering we also have a no-op R4 = R5
+			 * instruction to validate R5 state. We also check
+			 * that R4 is what it should be in such case.
 			 */
-			{18, "R5_w=pkt(id=2,off=0,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
+			{19, "R4_w=pkt(id=2,off=0,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
+			{19, "R5_w=pkt(id=2,off=0,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
 			/* Constant offset is added to R5, resulting in
 			 * reg->off of 14.
 			 */
-			{19, "R5_w=pkt(id=2,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
+			{20, "R5_w=pkt(id=2,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
 			/* At the time the word size load is performed from R5,
 			 * its total fixed offset is NET_IP_ALIGN + reg->off
 			 * (14) which is 16.  Then the variable offset is 4-byte
 			 * aligned, so the total offset is 4-byte aligned and
 			 * meets the load's requirements.
 			 */
-			{23, "R4=pkt(id=2,off=18,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"},
-			{23, "R5=pkt(id=2,off=14,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"},
+			{24, "R4=pkt(id=2,off=18,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"},
+			{24, "R5=pkt(id=2,off=14,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"},
 			/* Constant offset is added to R5 packet pointer,
 			 * resulting in reg->off value of 14.
 			 */
-			{26, "R5_w=pkt(id=0,off=14,r=8"},
+			{27, "R5_w=pkt(id=0,off=14,r=8"},
 			/* Variable offset is added to R5, resulting in a
-			 * variable offset of (4n).
+			 * variable offset of (4n). See comment for insn #19
+			 * for R4 = R5 trick.
 			 */
-			{27, "R5_w=pkt(id=3,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
+			{29, "R4_w=pkt(id=3,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
+			{29, "R5_w=pkt(id=3,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
 			/* Constant is added to R5 again, setting reg->off to 18. */
-			{28, "R5_w=pkt(id=3,off=18,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
+			{30, "R5_w=pkt(id=3,off=18,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
 			/* And once more we add a variable; resulting var_off
 			 * is still (4n), fixed offset is not changed.
 			 * Also, we create a new reg->id.
 			 */
-			{29, "R5_w=pkt(id=4,off=18,r=0,umax_value=2040,var_off=(0x0; 0x7fc)"},
+			{32, "R4_w=pkt(id=4,off=18,r=0,umax_value=2040,var_off=(0x0; 0x7fc)"},
+			{32, "R5_w=pkt(id=4,off=18,r=0,umax_value=2040,var_off=(0x0; 0x7fc)"},
 			/* At the time the word size load is performed from R5,
 			 * its total fixed offset is NET_IP_ALIGN + reg->off (18)
 			 * which is 20.  Then the variable offset is (4n), so
 			 * the total offset is 4-byte aligned and meets the
 			 * load's requirements.
 			 */
-			{33, "R4=pkt(id=4,off=22,r=22,umax_value=2040,var_off=(0x0; 0x7fc)"},
-			{33, "R5=pkt(id=4,off=18,r=22,umax_value=2040,var_off=(0x0; 0x7fc)"},
+			{35, "R4=pkt(id=4,off=22,r=22,umax_value=2040,var_off=(0x0; 0x7fc)"},
+			{35, "R5=pkt(id=4,off=18,r=22,umax_value=2040,var_off=(0x0; 0x7fc)"},
 		},
 	},
 	{
diff --git a/kernel/tools/testing/selftests/bpf/prog_tests/btf.c b/kernel/tools/testing/selftests/bpf/prog_tests/btf.c
index 48b0115..28d2226 100644
--- a/kernel/tools/testing/selftests/bpf/prog_tests/btf.c
+++ b/kernel/tools/testing/selftests/bpf/prog_tests/btf.c
@@ -882,6 +882,34 @@
 	.btf_load_err = true,
 	.err_str = "Invalid elem",
 },
+{
+	.descr = "var after datasec, ptr followed by modifier",
+	.raw_types = {
+		/* .bss section */				/* [1] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2),
+			sizeof(void*)+4),
+		BTF_VAR_SECINFO_ENC(4, 0, sizeof(void*)),
+		BTF_VAR_SECINFO_ENC(6, sizeof(void*), 4),
+		/* int */					/* [2] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* int* */					/* [3] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
+		BTF_VAR_ENC(NAME_TBD, 3, 0),			/* [4] */
+		/* const int */					/* [5] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
+		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0a\0b\0c\0",
+	.str_sec_size = sizeof("\0a\0b\0c\0"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = sizeof(void*)+4,
+	.key_type_id = 0,
+	.value_type_id = 1,
+	.max_entries = 1,
+},
 /* Test member exceeds the size of struct.
  *
  * struct A {
diff --git a/kernel/tools/testing/selftests/bpf/prog_tests/cg_storage_multi.c b/kernel/tools/testing/selftests/bpf/prog_tests/cg_storage_multi.c
index 643dfa3..48dc582 100644
--- a/kernel/tools/testing/selftests/bpf/prog_tests/cg_storage_multi.c
+++ b/kernel/tools/testing/selftests/bpf/prog_tests/cg_storage_multi.c
@@ -56,8 +56,9 @@
 
 static bool connect_send(const char *cgroup_path)
 {
-	bool res = true;
 	int server_fd = -1, client_fd = -1;
+	char message[] = "message";
+	bool res = true;
 
 	if (join_cgroup(cgroup_path))
 		goto out_clean;
@@ -70,7 +71,10 @@
 	if (client_fd < 0)
 		goto out_clean;
 
-	if (send(client_fd, "message", strlen("message"), 0) < 0)
+	if (send(client_fd, &message, sizeof(message), 0) < 0)
+		goto out_clean;
+
+	if (read(server_fd, &message, sizeof(message)) < 0)
 		goto out_clean;
 
 	res = false;
diff --git a/kernel/tools/testing/selftests/bpf/prog_tests/sk_assign.c b/kernel/tools/testing/selftests/bpf/prog_tests/sk_assign.c
index 3a46909..e09c523 100644
--- a/kernel/tools/testing/selftests/bpf/prog_tests/sk_assign.c
+++ b/kernel/tools/testing/selftests/bpf/prog_tests/sk_assign.c
@@ -29,7 +29,23 @@
 static bool
 configure_stack(void)
 {
+	char tc_version[128];
 	char tc_cmd[BUFSIZ];
+	char *prog;
+	FILE *tc;
+
+	/* Check whether tc is built with libbpf. */
+	tc = popen("tc -V", "r");
+	if (CHECK_FAIL(!tc))
+		return false;
+	if (CHECK_FAIL(!fgets(tc_version, sizeof(tc_version), tc)))
+		return false;
+	if (strstr(tc_version, ", libbpf "))
+		prog = "test_sk_assign_libbpf.o";
+	else
+		prog = "test_sk_assign.o";
+	if (CHECK_FAIL(pclose(tc)))
+		return false;
 
 	/* Move to a new networking namespace */
 	if (CHECK_FAIL(unshare(CLONE_NEWNET)))
@@ -46,8 +62,8 @@
 	/* Load qdisc, BPF program */
 	if (CHECK_FAIL(system("tc qdisc add dev lo clsact")))
 		return false;
-	sprintf(tc_cmd, "%s %s %s %s", "tc filter add dev lo ingress bpf",
-		       "direct-action object-file ./test_sk_assign.o",
+	sprintf(tc_cmd, "%s %s %s %s %s", "tc filter add dev lo ingress bpf",
+		       "direct-action object-file", prog,
 		       "section classifier/sk_assign_test",
 		       (env.verbosity < VERBOSE_VERY) ? " 2>/dev/null" : "verbose");
 	if (CHECK(system(tc_cmd), "BPF load failed;",
@@ -129,15 +145,12 @@
 static ssize_t
 rcv_msg(int srv_client, int type)
 {
-	struct sockaddr_storage ss;
 	char buf[BUFSIZ];
-	socklen_t slen;
 
 	if (type == SOCK_STREAM)
 		return read(srv_client, &buf, sizeof(buf));
 	else
-		return recvfrom(srv_client, &buf, sizeof(buf), 0,
-				(struct sockaddr *)&ss, &slen);
+		return recvfrom(srv_client, &buf, sizeof(buf), 0, NULL, NULL);
 }
 
 static int
diff --git a/kernel/tools/testing/selftests/bpf/progs/btf_dump_test_case_bitfields.c b/kernel/tools/testing/selftests/bpf/progs/btf_dump_test_case_bitfields.c
index 8f44767..22a7cd8 100644
--- a/kernel/tools/testing/selftests/bpf/progs/btf_dump_test_case_bitfields.c
+++ b/kernel/tools/testing/selftests/bpf/progs/btf_dump_test_case_bitfields.c
@@ -53,7 +53,7 @@
  */
 /* ------ END-EXPECTED-OUTPUT ------ */
 struct bitfield_mixed_with_others {
-	long: 4; /* char is enough as a backing field */
+	char: 4; /* char is enough as a backing field */
 	int a: 4;
 	/* 8-bit implicit padding */
 	short b; /* combined with previous bitfield */
diff --git a/kernel/tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c b/kernel/tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c
index 1cef3be..22dbd12 100644
--- a/kernel/tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c
+++ b/kernel/tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c
@@ -58,7 +58,81 @@
 	} __attribute__((packed));
 };
 
-/*------ END-EXPECTED-OUTPUT ------ */
+/* ----- START-EXPECTED-OUTPUT ----- */
+/*
+ *struct nested_packed_but_aligned_struct {
+ *	int x1;
+ *	int x2;
+ *};
+ *
+ *struct outer_implicitly_packed_struct {
+ *	char y1;
+ *	struct nested_packed_but_aligned_struct y2;
+ *} __attribute__((packed));
+ *
+ */
+/* ------ END-EXPECTED-OUTPUT ------ */
+
+struct nested_packed_but_aligned_struct {
+	int x1;
+	int x2;
+} __attribute__((packed));
+
+struct outer_implicitly_packed_struct {
+	char y1;
+	struct nested_packed_but_aligned_struct y2;
+};
+/* ----- START-EXPECTED-OUTPUT ----- */
+/*
+ *struct usb_ss_ep_comp_descriptor {
+ *	char: 8;
+ *	char bDescriptorType;
+ *	char bMaxBurst;
+ *	short wBytesPerInterval;
+ *};
+ *
+ *struct usb_host_endpoint {
+ *	long: 64;
+ *	char: 8;
+ *	struct usb_ss_ep_comp_descriptor ss_ep_comp;
+ *	long: 0;
+ *} __attribute__((packed));
+ *
+ */
+/* ------ END-EXPECTED-OUTPUT ------ */
+
+struct usb_ss_ep_comp_descriptor {
+	char: 8;
+	char bDescriptorType;
+	char bMaxBurst;
+	int: 0;
+	short wBytesPerInterval;
+} __attribute__((packed));
+
+struct usb_host_endpoint {
+	long: 64;
+	char: 8;
+	struct usb_ss_ep_comp_descriptor ss_ep_comp;
+	long: 0;
+};
+
+/* ----- START-EXPECTED-OUTPUT ----- */
+struct nested_packed_struct {
+	int a;
+	char b;
+} __attribute__((packed));
+
+struct outer_nonpacked_struct {
+	short a;
+	struct nested_packed_struct b;
+};
+
+struct outer_packed_struct {
+	short a;
+	struct nested_packed_struct b;
+} __attribute__((packed));
+
+/* ------ END-EXPECTED-OUTPUT ------ */
 
 int f(struct {
 	struct packed_trailing_space _1;
@@ -69,6 +143,10 @@
 	union union_is_never_packed _6;
 	union union_does_not_need_packing _7;
 	union jump_code_union _8;
+	struct outer_implicitly_packed_struct _9;
+	struct usb_host_endpoint _10;
+	struct outer_nonpacked_struct _11;
+	struct outer_packed_struct _12;
 } *_)
 {
 	return 0;
diff --git a/kernel/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c b/kernel/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c
index 35c5128..0b3cdff 100644
--- a/kernel/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c
+++ b/kernel/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c
@@ -19,7 +19,7 @@
 /*
  *struct padded_explicitly {
  *	int a;
- *	int: 32;
+ *	long: 0;
  *	int b;
  *};
  *
@@ -28,41 +28,28 @@
 
 struct padded_explicitly {
 	int a;
-	int: 1; /* algo will explicitly pad with full 32 bits here */
+	int: 1; /* algo will emit aligning `long: 0;` here */
 	int b;
 };
 
 /* ----- START-EXPECTED-OUTPUT ----- */
-/*
- *struct padded_a_lot {
- *	int a;
- *	long: 32;
- *	long: 64;
- *	long: 64;
- *	int b;
- *};
- *
- */
-/* ------ END-EXPECTED-OUTPUT ------ */
-
 struct padded_a_lot {
 	int a;
-	/* 32 bit of implicit padding here, which algo will make explicit */
 	long: 64;
 	long: 64;
 	int b;
 };
+
+/* ------ END-EXPECTED-OUTPUT ------ */
 
 /* ----- START-EXPECTED-OUTPUT ----- */
 /*
  *struct padded_cache_line {
  *	int a;
- *	long: 32;
  *	long: 64;
  *	long: 64;
  *	long: 64;
  *	int b;
- *	long: 32;
  *	long: 64;
  *	long: 64;
  *	long: 64;
@@ -85,7 +72,7 @@
  *struct zone {
  *	int a;
  *	short b;
- *	short: 16;
+ *	long: 0;
  *	struct zone_padding __pad__;
  *};
  *
@@ -102,12 +89,160 @@
 	struct zone_padding __pad__;
 };
 
+/* ----- START-EXPECTED-OUTPUT ----- */
+struct padding_wo_named_members {
+	long: 64;
+	long: 64;
+};
+
+struct padding_weird_1 {
+	int a;
+	long: 64;
+	short: 16;
+	short b;
+};
+
+/* ------ END-EXPECTED-OUTPUT ------ */
+
+/* ----- START-EXPECTED-OUTPUT ----- */
+/*
+ *struct padding_weird_2 {
+ *	long: 56;
+ *	char a;
+ *	long: 56;
+ *	char b;
+ *	char: 8;
+ *};
+ *
+ */
+/* ------ END-EXPECTED-OUTPUT ------ */
+struct padding_weird_2 {
+	int: 32;	/* these paddings will be collapsed into `long: 56;` */
+	short: 16;
+	char: 8;
+	char a;
+	int: 32;	/* these paddings will be collapsed into `long: 56;` */
+	short: 16;
+	char: 8;
+	char b;
+	char: 8;
+};
+
+/* ----- START-EXPECTED-OUTPUT ----- */
+struct exact_1byte {
+	char x;
+};
+
+struct padded_1byte {
+	char: 8;
+};
+
+struct exact_2bytes {
+	short x;
+};
+
+struct padded_2bytes {
+	short: 16;
+};
+
+struct exact_4bytes {
+	int x;
+};
+
+struct padded_4bytes {
+	int: 32;
+};
+
+struct exact_8bytes {
+	long x;
+};
+
+struct padded_8bytes {
+	long: 64;
+};
+
+struct ff_periodic_effect {
+	int: 32;
+	short magnitude;
+	long: 0;
+	short phase;
+	long: 0;
+	int: 32;
+	int custom_len;
+	short *custom_data;
+};
+
+struct ib_wc {
+	long: 64;
+	long: 64;
+	int: 32;
+	int byte_len;
+	void *qp;
+	union {} ex;
+	long: 64;
+	int slid;
+	int wc_flags;
+	long: 64;
+	char smac[6];
+	long: 0;
+	char network_hdr_type;
+};
+
+struct acpi_object_method {
+	long: 64;
+	char: 8;
+	char type;
+	short reference_count;
+	char flags;
+	short: 0;
+	char: 8;
+	char sync_level;
+	long: 64;
+	void *node;
+	void *aml_start;
+	union {} dispatch;
+	long: 64;
+	int aml_length;
+};
+
+struct nested_unpacked {
+	int x;
+};
+
+struct nested_packed {
+	struct nested_unpacked a;
+	char c;
+} __attribute__((packed));
+
+struct outer_mixed_but_unpacked {
+	struct nested_packed b1;
+	short a1;
+	struct nested_packed b2;
+};
+
+/* ------ END-EXPECTED-OUTPUT ------ */
+
 int f(struct {
 	struct padded_implicitly _1;
 	struct padded_explicitly _2;
 	struct padded_a_lot _3;
 	struct padded_cache_line _4;
 	struct zone _5;
+	struct padding_wo_named_members _6;
+	struct padding_weird_1 _7;
+	struct padding_weird_2 _8;
+	struct exact_1byte _100;
+	struct padded_1byte _101;
+	struct exact_2bytes _102;
+	struct padded_2bytes _103;
+	struct exact_4bytes _104;
+	struct padded_4bytes _105;
+	struct exact_8bytes _106;
+	struct padded_8bytes _107;
+	struct ff_periodic_effect _200;
+	struct ib_wc _201;
+	struct acpi_object_method _202;
+	struct outer_mixed_but_unpacked _203;
 } *_)
 {
 	return 0;
diff --git a/kernel/tools/testing/selftests/bpf/progs/connect4_prog.c b/kernel/tools/testing/selftests/bpf/progs/connect4_prog.c
index a943d39..38ab1ce 100644
--- a/kernel/tools/testing/selftests/bpf/progs/connect4_prog.c
+++ b/kernel/tools/testing/selftests/bpf/progs/connect4_prog.c
@@ -33,7 +33,7 @@
 
 int _version SEC("version") = 1;
 
-__attribute__ ((noinline))
+__attribute__ ((noinline)) __weak
 int do_bind(struct bpf_sock_addr *ctx)
 {
 	struct sockaddr_in sa = {};
diff --git a/kernel/tools/testing/selftests/bpf/progs/test_cls_redirect.h b/kernel/tools/testing/selftests/bpf/progs/test_cls_redirect.h
index 76eab0a..233b089 100644
--- a/kernel/tools/testing/selftests/bpf/progs/test_cls_redirect.h
+++ b/kernel/tools/testing/selftests/bpf/progs/test_cls_redirect.h
@@ -12,6 +12,15 @@
 #include <linux/ipv6.h>
 #include <linux/udp.h>
 
+/* offsetof() is used in static asserts, and the libbpf-redefined CO-RE
+ * friendly version breaks compilation for older clang versions <= 15
+ * when invoked in a static assert.  Restore original here.
+ */
+#ifdef offsetof
+#undef offsetof
+#define offsetof(type, member) __builtin_offsetof(type, member)
+#endif
+
 struct gre_base_hdr {
 	uint16_t flags;
 	uint16_t protocol;
diff --git a/kernel/tools/testing/selftests/bpf/progs/test_sk_assign.c b/kernel/tools/testing/selftests/bpf/progs/test_sk_assign.c
index 1ecd987..77fd42f 100644
--- a/kernel/tools/testing/selftests/bpf/progs/test_sk_assign.c
+++ b/kernel/tools/testing/selftests/bpf/progs/test_sk_assign.c
@@ -16,6 +16,16 @@
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_endian.h>
 
+#if defined(IPROUTE2_HAVE_LIBBPF)
+/* Use a new-style map definition. */
+struct {
+	__uint(type, BPF_MAP_TYPE_SOCKMAP);
+	__type(key, int);
+	__type(value, __u64);
+	__uint(pinning, LIBBPF_PIN_BY_NAME);
+	__uint(max_entries, 1);
+} server_map SEC(".maps");
+#else
 /* Pin map under /sys/fs/bpf/tc/globals/<map name> */
 #define PIN_GLOBAL_NS 2
 
@@ -35,6 +45,7 @@
 	.max_elem = 1,
 	.pinning = PIN_GLOBAL_NS,
 };
+#endif
 
 int _version SEC("version") = 1;
 char _license[] SEC("license") = "GPL";
diff --git a/kernel/tools/testing/selftests/bpf/progs/test_sk_assign_libbpf.c b/kernel/tools/testing/selftests/bpf/progs/test_sk_assign_libbpf.c
new file mode 100644
index 0000000..dcf46ad
--- /dev/null
+++ b/kernel/tools/testing/selftests/bpf/progs/test_sk_assign_libbpf.c
@@ -0,0 +1,3 @@
+// SPDX-License-Identifier: GPL-2.0
+#define IPROUTE2_HAVE_LIBBPF
+#include "test_sk_assign.c"
diff --git a/kernel/tools/testing/selftests/bpf/test_verifier.c b/kernel/tools/testing/selftests/bpf/test_verifier.c
index 0fb92d9..961c17b 100644
--- a/kernel/tools/testing/selftests/bpf/test_verifier.c
+++ b/kernel/tools/testing/selftests/bpf/test_verifier.c
@@ -50,7 +50,7 @@
 #define MAX_INSNS	BPF_MAXINSNS
 #define MAX_TEST_INSNS	1000000
 #define MAX_FIXUPS	8
-#define MAX_NR_MAPS	20
+#define MAX_NR_MAPS	21
 #define MAX_TEST_RUNS	8
 #define POINTER_VALUE	0xcafe4all
 #define TEST_DATA_LEN	64
@@ -87,6 +87,7 @@
 	int fixup_sk_storage_map[MAX_FIXUPS];
 	int fixup_map_event_output[MAX_FIXUPS];
 	int fixup_map_reuseport_array[MAX_FIXUPS];
+	int fixup_map_ringbuf[MAX_FIXUPS];
 	const char *errstr;
 	const char *errstr_unpriv;
 	uint32_t insn_processed;
@@ -640,6 +641,7 @@
 	int *fixup_sk_storage_map = test->fixup_sk_storage_map;
 	int *fixup_map_event_output = test->fixup_map_event_output;
 	int *fixup_map_reuseport_array = test->fixup_map_reuseport_array;
+	int *fixup_map_ringbuf = test->fixup_map_ringbuf;
 
 	if (test->fill_helper) {
 		test->fill_insns = calloc(MAX_TEST_INSNS, sizeof(struct bpf_insn));
@@ -817,6 +819,14 @@
 			fixup_map_reuseport_array++;
 		} while (*fixup_map_reuseport_array);
 	}
+	if (*fixup_map_ringbuf) {
+		map_fds[20] = create_map(BPF_MAP_TYPE_RINGBUF, 0,
+					   0, 4096);
+		do {
+			prog[*fixup_map_ringbuf].imm = map_fds[20];
+			fixup_map_ringbuf++;
+		} while (*fixup_map_ringbuf);
+	}
 }
 
 struct libcap {
diff --git a/kernel/tools/testing/selftests/bpf/verifier/bounds_mix_sign_unsign.c b/kernel/tools/testing/selftests/bpf/verifier/bounds_mix_sign_unsign.c
index c2aa6f2..bf82b92 100644
--- a/kernel/tools/testing/selftests/bpf/verifier/bounds_mix_sign_unsign.c
+++ b/kernel/tools/testing/selftests/bpf/verifier/bounds_mix_sign_unsign.c
@@ -1,13 +1,14 @@
 {
 	"bounds checks mixing signed and unsigned, positive bounds",
 	.insns = {
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
 	BPF_MOV64_IMM(BPF_REG_2, 2),
 	BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 3),
@@ -17,20 +18,21 @@
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_EXIT_INSN(),
 	},
-	.fixup_map_hash_8b = { 3 },
+	.fixup_map_hash_8b = { 5 },
 	.errstr = "unbounded min value",
 	.result = REJECT,
 },
 {
 	"bounds checks mixing signed and unsigned",
 	.insns = {
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
 	BPF_MOV64_IMM(BPF_REG_2, -1),
 	BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
@@ -40,20 +42,21 @@
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_EXIT_INSN(),
 	},
-	.fixup_map_hash_8b = { 3 },
+	.fixup_map_hash_8b = { 5 },
 	.errstr = "unbounded min value",
 	.result = REJECT,
 },
 {
 	"bounds checks mixing signed and unsigned, variant 2",
 	.insns = {
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
 	BPF_MOV64_IMM(BPF_REG_2, -1),
 	BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
@@ -65,20 +68,21 @@
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_EXIT_INSN(),
 	},
-	.fixup_map_hash_8b = { 3 },
+	.fixup_map_hash_8b = { 5 },
 	.errstr = "unbounded min value",
 	.result = REJECT,
 },
 {
 	"bounds checks mixing signed and unsigned, variant 3",
 	.insns = {
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
 	BPF_MOV64_IMM(BPF_REG_2, -1),
 	BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 4),
@@ -89,20 +93,21 @@
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_EXIT_INSN(),
 	},
-	.fixup_map_hash_8b = { 3 },
+	.fixup_map_hash_8b = { 5 },
 	.errstr = "unbounded min value",
 	.result = REJECT,
 },
 {
 	"bounds checks mixing signed and unsigned, variant 4",
 	.insns = {
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
 	BPF_MOV64_IMM(BPF_REG_2, 1),
 	BPF_ALU64_REG(BPF_AND, BPF_REG_1, BPF_REG_2),
@@ -112,19 +117,20 @@
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_EXIT_INSN(),
 	},
-	.fixup_map_hash_8b = { 3 },
+	.fixup_map_hash_8b = { 5 },
 	.result = ACCEPT,
 },
 {
 	"bounds checks mixing signed and unsigned, variant 5",
 	.insns = {
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
 	BPF_MOV64_IMM(BPF_REG_2, -1),
 	BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
@@ -135,17 +141,20 @@
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_EXIT_INSN(),
 	},
-	.fixup_map_hash_8b = { 3 },
+	.fixup_map_hash_8b = { 5 },
 	.errstr = "unbounded min value",
 	.result = REJECT,
 },
 {
 	"bounds checks mixing signed and unsigned, variant 6",
 	.insns = {
+	BPF_MOV64_REG(BPF_REG_9, BPF_REG_1),
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
+	BPF_MOV64_REG(BPF_REG_1, BPF_REG_9),
 	BPF_MOV64_IMM(BPF_REG_2, 0),
 	BPF_MOV64_REG(BPF_REG_3, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, -512),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -16),
 	BPF_MOV64_IMM(BPF_REG_6, -1),
 	BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_6, 5),
@@ -163,13 +172,14 @@
 {
 	"bounds checks mixing signed and unsigned, variant 7",
 	.insns = {
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
 	BPF_MOV64_IMM(BPF_REG_2, 1024 * 1024 * 1024),
 	BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
@@ -179,19 +189,20 @@
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_EXIT_INSN(),
 	},
-	.fixup_map_hash_8b = { 3 },
+	.fixup_map_hash_8b = { 5 },
 	.result = ACCEPT,
 },
 {
 	"bounds checks mixing signed and unsigned, variant 8",
 	.insns = {
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
 	BPF_MOV64_IMM(BPF_REG_2, -1),
 	BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
@@ -203,20 +214,21 @@
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_EXIT_INSN(),
 	},
-	.fixup_map_hash_8b = { 3 },
+	.fixup_map_hash_8b = { 5 },
 	.errstr = "unbounded min value",
 	.result = REJECT,
 },
 {
 	"bounds checks mixing signed and unsigned, variant 9",
 	.insns = {
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
 	BPF_LD_IMM64(BPF_REG_2, -9223372036854775808ULL),
 	BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
@@ -228,19 +240,20 @@
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_EXIT_INSN(),
 	},
-	.fixup_map_hash_8b = { 3 },
+	.fixup_map_hash_8b = { 5 },
 	.result = ACCEPT,
 },
 {
 	"bounds checks mixing signed and unsigned, variant 10",
 	.insns = {
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
 	BPF_MOV64_IMM(BPF_REG_2, 0),
 	BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
@@ -252,20 +265,21 @@
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_EXIT_INSN(),
 	},
-	.fixup_map_hash_8b = { 3 },
+	.fixup_map_hash_8b = { 5 },
 	.errstr = "unbounded min value",
 	.result = REJECT,
 },
 {
 	"bounds checks mixing signed and unsigned, variant 11",
 	.insns = {
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
 	BPF_MOV64_IMM(BPF_REG_2, -1),
 	BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
@@ -278,20 +292,21 @@
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_EXIT_INSN(),
 	},
-	.fixup_map_hash_8b = { 3 },
+	.fixup_map_hash_8b = { 5 },
 	.errstr = "unbounded min value",
 	.result = REJECT,
 },
 {
 	"bounds checks mixing signed and unsigned, variant 12",
 	.insns = {
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
 	BPF_MOV64_IMM(BPF_REG_2, -6),
 	BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
@@ -303,20 +318,21 @@
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_EXIT_INSN(),
 	},
-	.fixup_map_hash_8b = { 3 },
+	.fixup_map_hash_8b = { 5 },
 	.errstr = "unbounded min value",
 	.result = REJECT,
 },
 {
 	"bounds checks mixing signed and unsigned, variant 13",
 	.insns = {
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
 	BPF_MOV64_IMM(BPF_REG_2, 2),
 	BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
@@ -331,7 +347,7 @@
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_EXIT_INSN(),
 	},
-	.fixup_map_hash_8b = { 3 },
+	.fixup_map_hash_8b = { 5 },
 	.errstr = "unbounded min value",
 	.result = REJECT,
 },
@@ -340,13 +356,14 @@
 	.insns = {
 	BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_1,
 		    offsetof(struct __sk_buff, mark)),
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
 	BPF_MOV64_IMM(BPF_REG_2, -1),
 	BPF_MOV64_IMM(BPF_REG_8, 2),
@@ -360,20 +377,21 @@
 	BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, -3),
 	BPF_JMP_IMM(BPF_JA, 0, 0, -7),
 	},
-	.fixup_map_hash_8b = { 4 },
+	.fixup_map_hash_8b = { 6 },
 	.errstr = "unbounded min value",
 	.result = REJECT,
 },
 {
 	"bounds checks mixing signed and unsigned, variant 15",
 	.insns = {
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
 	BPF_MOV64_IMM(BPF_REG_2, -6),
 	BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
@@ -387,7 +405,7 @@
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_EXIT_INSN(),
 	},
-	.fixup_map_hash_8b = { 3 },
+	.fixup_map_hash_8b = { 5 },
 	.errstr = "unbounded min value",
 	.result = REJECT,
 },
diff --git a/kernel/tools/testing/selftests/bpf/verifier/search_pruning.c b/kernel/tools/testing/selftests/bpf/verifier/search_pruning.c
index 7e50cb8..7e36078 100644
--- a/kernel/tools/testing/selftests/bpf/verifier/search_pruning.c
+++ b/kernel/tools/testing/selftests/bpf/verifier/search_pruning.c
@@ -154,3 +154,39 @@
 	.result_unpriv = ACCEPT,
 	.insn_processed = 15,
 },
+/* The test performs a conditional 64-bit write to a stack location
+ * fp[-8], this is followed by an unconditional 8-bit write to fp[-8],
+ * then data is read from fp[-8]. This sequence is unsafe.
+ *
+ * The test would be mistakenly marked as safe w/o dst register parent
+ * preservation in verifier.c:copy_register_state() function.
+ *
+ * Note the usage of BPF_F_TEST_STATE_FREQ to force creation of the
+ * checkpoint state after conditional 64-bit assignment.
+ */
+{
+	"write tracking and register parent chain bug",
+	.insns = {
+	/* r6 = ktime_get_ns() */
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
+	/* r0 = ktime_get_ns() */
+	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
+	/* if r0 > r6 goto +1 */
+	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_6, 1),
+	/* *(u64 *)(r10 - 8) = 0xdeadbeef */
+	BPF_ST_MEM(BPF_DW, BPF_REG_FP, -8, 0xdeadbeef),
+	/* r1 = 42 */
+	BPF_MOV64_IMM(BPF_REG_1, 42),
+	/* *(u8 *)(r10 - 8) = r1 */
+	BPF_STX_MEM(BPF_B, BPF_REG_FP, BPF_REG_1, -8),
+	/* r2 = *(u64 *)(r10 - 8) */
+	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_FP, -8),
+	/* exit(0) */
+	BPF_MOV64_IMM(BPF_REG_0, 0),
+	BPF_EXIT_INSN(),
+	},
+	.flags = BPF_F_TEST_STATE_FREQ,
+	.errstr = "invalid read from stack off -8+1 size 8",
+	.result = REJECT,
+},
diff --git a/kernel/tools/testing/selftests/bpf/verifier/spill_fill.c b/kernel/tools/testing/selftests/bpf/verifier/spill_fill.c
index 45d43bf..0b94389 100644
--- a/kernel/tools/testing/selftests/bpf/verifier/spill_fill.c
+++ b/kernel/tools/testing/selftests/bpf/verifier/spill_fill.c
@@ -29,6 +29,36 @@
 	.result_unpriv = ACCEPT,
 },
 {
+	"check valid spill/fill, ptr to mem",
+	.insns = {
+	/* reserve 8 byte ringbuf memory */
+	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+	BPF_LD_MAP_FD(BPF_REG_1, 0),
+	BPF_MOV64_IMM(BPF_REG_2, 8),
+	BPF_MOV64_IMM(BPF_REG_3, 0),
+	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_reserve),
+	/* store a pointer to the reserved memory in R6 */
+	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
+	/* check whether the reservation was successful */
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
+	/* spill R6(mem) into the stack */
+	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
+	/* fill it back in R7 */
+	BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_10, -8),
+	/* should be able to access *(R7) = 0 */
+	BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 0),
+	/* submit the reserved ringbuf memory */
+	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
+	BPF_MOV64_IMM(BPF_REG_2, 0),
+	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_submit),
+	BPF_MOV64_IMM(BPF_REG_0, 0),
+	BPF_EXIT_INSN(),
+	},
+	.fixup_map_ringbuf = { 1 },
+	.result = ACCEPT,
+	.result_unpriv = ACCEPT,
+},
+{
 	"check corrupted spill/fill",
 	.insns = {
 	/* spill R1(ctx) into stack */
diff --git a/kernel/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/kernel/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
index 40909c2..2c81e01 100755
--- a/kernel/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
+++ b/kernel/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
@@ -16,6 +16,18 @@
 DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV_NAME/
 DL_HANDLE=netdevsim/$DEV_NAME
 
+wait_for_devlink()
+{
+	"$@" | grep -q $DL_HANDLE
+}
+
+devlink_wait()
+{
+	local timeout=$1
+
+	busywait "$timeout" wait_for_devlink devlink dev
+}
+
 fw_flash_test()
 {
 	RET=0
@@ -255,6 +267,9 @@
 	ip netns del testns2
 	ip netns del testns1
 
+	# Wait until netns async cleanup is done.
+	devlink_wait 2000
+
 	log_test "netns reload test"
 }
 
@@ -346,6 +361,9 @@
 
 	ip netns del testns2
 	ip netns del testns1
+
+	# Wait until netns async cleanup is done.
+	devlink_wait 2000
 
 	log_test "resource test"
 }
@@ -495,8 +513,8 @@
 
 	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"
diff --git a/kernel/tools/testing/selftests/efivarfs/efivarfs.sh b/kernel/tools/testing/selftests/efivarfs/efivarfs.sh
index a90f394..d374878 100755
--- a/kernel/tools/testing/selftests/efivarfs/efivarfs.sh
+++ b/kernel/tools/testing/selftests/efivarfs/efivarfs.sh
@@ -87,6 +87,11 @@
 {
 	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
 }
 
diff --git a/kernel/tools/testing/selftests/ftrace/ftracetest b/kernel/tools/testing/selftests/ftrace/ftracetest
index 8ec1922..55314cd 100755
--- a/kernel/tools/testing/selftests/ftrace/ftracetest
+++ b/kernel/tools/testing/selftests/ftrace/ftracetest
@@ -30,6 +30,9 @@
 # kselftest skip code is 4
 err_skip=4
 
+# umount required
+UMOUNT_DIR=""
+
 # cgroup RT scheduling prevents chrt commands from succeeding, which
 # induces failures in test wakeup tests.  Disable for the duration of
 # the tests.
@@ -44,6 +47,9 @@
 
 cleanup() {
   echo $sched_rt_runtime_orig > $sched_rt_runtime
+  if [ -n "${UMOUNT_DIR}" ]; then
+    umount ${UMOUNT_DIR} ||:
+  fi
 }
 
 errexit() { # message
@@ -155,11 +161,13 @@
 	    mount -t tracefs nodev /sys/kernel/tracing ||
 	      errexit "Failed to mount /sys/kernel/tracing"
 	    TRACING_DIR="/sys/kernel/tracing"
+	    UMOUNT_DIR=${TRACING_DIR}
 	# If debugfs exists, then so does /sys/kernel/debug
 	elif [ -d "/sys/kernel/debug" ]; then
 	    mount -t debugfs nodev /sys/kernel/debug ||
 	      errexit "Failed to mount /sys/kernel/debug"
 	    TRACING_DIR="/sys/kernel/debug/tracing"
+	    UMOUNT_DIR=${TRACING_DIR}
 	else
 	    err_ret=$err_skip
 	    errexit "debugfs and tracefs are not configured in this kernel"
diff --git a/kernel/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc b/kernel/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
index 3145b0f..d9b8127 100644
--- a/kernel/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
+++ b/kernel/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
@@ -38,11 +38,18 @@
 
 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() {
diff --git a/kernel/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc b/kernel/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc
index 0eb47fb..42422e4 100644
--- a/kernel/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc
+++ b/kernel/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc
@@ -39,7 +39,7 @@
 
 instance_set() {
         while :; do
-                echo 1 > foo/events/sched/sched_switch
+                echo 1 > foo/events/sched/sched_switch/enable
         done 2> /dev/null
 }
 
diff --git a/kernel/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic_event_syntax_errors.tc b/kernel/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic_event_syntax_errors.tc
index 955e3ce..ada594f 100644
--- a/kernel/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic_event_syntax_errors.tc
+++ b/kernel/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic_event_syntax_errors.tc
@@ -1,38 +1,19 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test synthetic_events syntax parser errors
-# requires: synthetic_events error_log "char name[]' >> synthetic_events":README
+# requires: synthetic_events error_log
 
 check_error() { # command-with-error-pos-by-^
     ftrace_errlog_check 'synthetic_events' "$1" 'synthetic_events'
 }
 
-check_dyn_error() { # command-with-error-pos-by-^
-    ftrace_errlog_check 'synthetic_events' "$1" 'dynamic_events'
-}
-
 check_error 'myevent ^chr arg'			# INVALID_TYPE
-check_error 'myevent ^unsigned arg'		# INCOMPLETE_TYPE
-
-check_error 'myevent char ^str]; int v'		# BAD_NAME
-check_error '^mye-vent char str[]'		# BAD_NAME
-check_error 'myevent char ^st-r[]'		# BAD_NAME
-
-check_error 'myevent char str;^[]'		# INVALID_FIELD
-check_error 'myevent char str; ^int'		# INVALID_FIELD
-
-check_error 'myevent char ^str[; int v'		# INVALID_ARRAY_SPEC
-check_error 'myevent char ^str[kdjdk]'		# INVALID_ARRAY_SPEC
-check_error 'myevent char ^str[257]'		# INVALID_ARRAY_SPEC
-
-check_error '^mye;vent char str[]'		# INVALID_CMD
-check_error '^myevent ; char str[]'		# INVALID_CMD
-check_error '^myevent; char str[]'		# INVALID_CMD
-check_error '^myevent ;char str[]'		# INVALID_CMD
-check_error '^; char str[]'			# INVALID_CMD
-check_error '^;myevent char str[]'		# INVALID_CMD
-check_error '^myevent'				# INVALID_CMD
-
-check_dyn_error '^s:junk/myevent char str['	# INVALID_DYN_CMD
+check_error 'myevent ^char str[];; int v'	# INVALID_TYPE
+check_error 'myevent char ^str]; int v'		# INVALID_NAME
+check_error 'myevent char ^str;[]'		# INVALID_NAME
+check_error 'myevent ^char str[; int v'		# INVALID_TYPE
+check_error '^mye;vent char str[]'		# BAD_NAME
+check_error 'myevent char str[]; ^int'		# INVALID_FIELD
+check_error '^myevent'				# INCOMPLETE_CMD
 
 exit 0
diff --git a/kernel/tools/testing/selftests/intel_pstate/aperf.c b/kernel/tools/testing/selftests/intel_pstate/aperf.c
index f6cd03a..a8acf39 100644
--- a/kernel/tools/testing/selftests/intel_pstate/aperf.c
+++ b/kernel/tools/testing/selftests/intel_pstate/aperf.c
@@ -10,7 +10,11 @@
 #include <sched.h>
 #include <errno.h>
 #include <string.h>
+#include <time.h>
 #include "../kselftest.h"
+
+#define MSEC_PER_SEC	1000L
+#define NSEC_PER_MSEC	1000000L
 
 void usage(char *name) {
 	printf ("Usage: %s cpunum\n", name);
@@ -22,7 +26,7 @@
 	long long tsc, old_tsc, new_tsc;
 	long long aperf, old_aperf, new_aperf;
 	long long mperf, old_mperf, new_mperf;
-	struct timeb before, after;
+	struct timespec before, after;
 	long long int start, finish, total;
 	cpu_set_t cpuset;
 
@@ -55,7 +59,10 @@
 		return 1;
 	}
 
-	ftime(&before);
+	if (clock_gettime(CLOCK_MONOTONIC, &before) < 0) {
+		perror("clock_gettime");
+		return 1;
+	}
 	pread(fd, &old_tsc,  sizeof(old_tsc), 0x10);
 	pread(fd, &old_aperf,  sizeof(old_mperf), 0xe7);
 	pread(fd, &old_mperf,  sizeof(old_aperf), 0xe8);
@@ -64,7 +71,10 @@
 		sqrt(i);
 	}
 
-	ftime(&after);
+	if (clock_gettime(CLOCK_MONOTONIC, &after) < 0) {
+		perror("clock_gettime");
+		return 1;
+	}
 	pread(fd, &new_tsc,  sizeof(new_tsc), 0x10);
 	pread(fd, &new_aperf,  sizeof(new_mperf), 0xe7);
 	pread(fd, &new_mperf,  sizeof(new_aperf), 0xe8);
@@ -73,11 +83,11 @@
 	aperf = new_aperf-old_aperf;
 	mperf = new_mperf-old_mperf;
 
-	start = before.time*1000 + before.millitm;
-	finish = after.time*1000 + after.millitm;
+	start = before.tv_sec*MSEC_PER_SEC + before.tv_nsec/NSEC_PER_MSEC;
+	finish = after.tv_sec*MSEC_PER_SEC + after.tv_nsec/NSEC_PER_MSEC;
 	total = finish - start;
 
-	printf("runTime: %4.2f\n", 1.0*total/1000);
+	printf("runTime: %4.2f\n", 1.0*total/MSEC_PER_SEC);
 	printf("freq: %7.0f\n", tsc / (1.0*aperf / (1.0 * mperf)) / total);
 	return 0;
 }
diff --git a/kernel/tools/testing/selftests/kselftest/runner.sh b/kernel/tools/testing/selftests/kselftest/runner.sh
index cc9c846..83616f0 100644
--- a/kernel/tools/testing/selftests/kselftest/runner.sh
+++ b/kernel/tools/testing/selftests/kselftest/runner.sh
@@ -33,9 +33,10 @@
 {
 	# Make sure tests will time out if utility is available.
 	if [ -x /usr/bin/timeout ] ; then
-		/usr/bin/timeout --foreground "$kselftest_timeout" "$1"
+		/usr/bin/timeout --foreground "$kselftest_timeout" \
+			/usr/bin/timeout "$kselftest_timeout" $1
 	else
-		"$1"
+		$1
 	fi
 }
 
@@ -65,17 +66,25 @@
 
 	TEST_HDR_MSG="selftests: $DIR: $BASENAME_TEST"
 	echo "# $TEST_HDR_MSG"
-	if [ ! -x "$TEST" ]; then
-		echo -n "# Warning: file $TEST is "
-		if [ ! -e "$TEST" ]; then
-			echo "missing!"
-		else
-			echo "not executable, correct this."
-		fi
+	if [ ! -e "$TEST" ]; then
+		echo "# Warning: file $TEST is missing!"
 		echo "not ok $test_num $TEST_HDR_MSG"
 	else
+		cmd="./$BASENAME_TEST"
+		if [ ! -x "$TEST" ]; then
+			echo "# Warning: file $TEST is not executable"
+
+			if [ $(head -n 1 "$TEST" | cut -c -2) = "#!" ]
+			then
+				interpreter=$(head -n 1 "$TEST" | cut -c 3-)
+				cmd="$interpreter ./$BASENAME_TEST"
+			else
+				echo "not ok $test_num $TEST_HDR_MSG"
+				return
+			fi
+		fi
 		cd `dirname $TEST` > /dev/null
-		((((( tap_timeout ./$BASENAME_TEST 2>&1; echo $? >&3) |
+		((((( tap_timeout "$cmd" 2>&1; echo $? >&3) |
 			tap_prefix >&4) 3>&1) |
 			(read xs; exit $xs)) 4>>"$logfile" &&
 		echo "ok $test_num $TEST_HDR_MSG") ||
diff --git a/kernel/tools/testing/selftests/kselftest_deps.sh b/kernel/tools/testing/selftests/kselftest_deps.sh
index bbc0464..e6010de 100755
--- a/kernel/tools/testing/selftests/kselftest_deps.sh
+++ b/kernel/tools/testing/selftests/kselftest_deps.sh
@@ -46,11 +46,11 @@
 print_targets=0
 
 while getopts "p" arg; do
-    case $arg in
-        p)
+	case $arg in
+		p)
 		print_targets=1
 	shift;;
-    esac
+	esac
 done
 
 if [ $# -eq 0 ]
@@ -92,6 +92,10 @@
 # Get all TARGETS from selftests Makefile
 targets=$(egrep "^TARGETS +|^TARGETS =" Makefile | cut -d "=" -f2)
 
+# Initially, in LDLIBS related lines, the dep checker needs
+# to ignore lines containing the following strings:
+filter="\$(VAR_LDLIBS)\|pkg-config\|PKG_CONFIG\|IOURING_EXTRA_LIBS"
+
 # Single test case
 if [ $# -eq 2 ]
 then
@@ -100,6 +104,8 @@
 	l1_test $test
 	l2_test $test
 	l3_test $test
+	l4_test $test
+	l5_test $test
 
 	print_results $1 $2
 	exit $?
@@ -113,7 +119,7 @@
 # Append space at the end of the list to append more tests.
 
 l1_tests=$(grep -r --include=Makefile "^LDLIBS" | \
-		grep -v "VAR_LDLIBS" | awk -F: '{print $1}')
+		grep -v "$filter" | awk -F: '{print $1}' | uniq)
 
 # Level 2: LDLIBS set dynamically.
 #
@@ -126,7 +132,7 @@
 # Append space at the end of the list to append more tests.
 
 l2_tests=$(grep -r --include=Makefile ": LDLIBS" | \
-		grep -v "VAR_LDLIBS" | awk -F: '{print $1}')
+		grep -v "$filter" | awk -F: '{print $1}' | uniq)
 
 # Level 3
 # gpio,  memfd and others use pkg-config to find mount and fuse libs
@@ -140,11 +146,32 @@
 #	VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null)
 
 l3_tests=$(grep -r --include=Makefile "^VAR_LDLIBS" | \
-		grep -v "pkg-config" | awk -F: '{print $1}')
+		grep -v "pkg-config\|PKG_CONFIG" | awk -F: '{print $1}' | uniq)
 
-#echo $l1_tests
-#echo $l2_1_tests
-#echo $l3_tests
+# Level 4
+# some tests may fall back to default using `|| echo -l<libname>`
+# if pkg-config doesn't find the libs, instead of using VAR_LDLIBS
+# as per level 3 checks.
+# e.g:
+# netfilter/Makefile
+#	LDLIBS += $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl)
+l4_tests=$(grep -r --include=Makefile "^LDLIBS" | \
+		grep "pkg-config\|PKG_CONFIG" | awk -F: '{print $1}' | uniq)
+
+# Level 5
+# some tests may use IOURING_EXTRA_LIBS to add extra libs to LDLIBS,
+# which in turn may be defined in a sub-Makefile
+# e.g.:
+# mm/Makefile
+#	$(OUTPUT)/gup_longterm: LDLIBS += $(IOURING_EXTRA_LIBS)
+l5_tests=$(grep -r --include=Makefile "LDLIBS +=.*\$(IOURING_EXTRA_LIBS)" | \
+	awk -F: '{print $1}' | uniq)
+
+#echo l1_tests $l1_tests
+#echo l2_tests $l2_tests
+#echo l3_tests $l3_tests
+#echo l4_tests $l4_tests
+#echo l5_tests $l5_tests
 
 all_tests
 print_results $1 $2
@@ -166,24 +193,32 @@
 	for test in $l3_tests; do
 		l3_test $test
 	done
+
+	for test in $l4_tests; do
+		l4_test $test
+	done
+
+	for test in $l5_tests; do
+		l5_test $test
+	done
 }
 
 # Use same parsing used for l1_tests and pick libraries this time.
 l1_test()
 {
 	test_libs=$(grep --include=Makefile "^LDLIBS" $test | \
-			grep -v "VAR_LDLIBS" | \
+			grep -v "$filter" | \
 			sed -e 's/\:/ /' | \
 			sed -e 's/+/ /' | cut -d "=" -f 2)
 
 	check_libs $test $test_libs
 }
 
-# Use same parsing used for l2__tests and pick libraries this time.
+# Use same parsing used for l2_tests and pick libraries this time.
 l2_test()
 {
 	test_libs=$(grep --include=Makefile ": LDLIBS" $test | \
-			grep -v "VAR_LDLIBS" | \
+			grep -v "$filter" | \
 			sed -e 's/\:/ /' | sed -e 's/+/ /' | \
 			cut -d "=" -f 2)
 
@@ -199,6 +234,24 @@
 	check_libs $test $test_libs
 }
 
+l4_test()
+{
+	test_libs=$(grep --include=Makefile "^VAR_LDLIBS\|^LDLIBS" $test | \
+			grep "\(pkg-config\|PKG_CONFIG\).*|| echo " | \
+			sed -e 's/.*|| echo //' | sed -e 's/)$//')
+
+	check_libs $test $test_libs
+}
+
+l5_test()
+{
+	tests=$(find $(dirname "$test") -type f -name "*.mk")
+	test_libs=$(grep "^IOURING_EXTRA_LIBS +\?=" $tests | \
+			cut -d "=" -f 2)
+
+	check_libs $test $test_libs
+}
+
 check_libs()
 {
 
diff --git a/kernel/tools/testing/selftests/kselftest_harness.h b/kernel/tools/testing/selftests/kselftest_harness.h
index 3e7b2e5..2fadc99 100644
--- a/kernel/tools/testing/selftests/kselftest_harness.h
+++ b/kernel/tools/testing/selftests/kselftest_harness.h
@@ -910,7 +910,11 @@
 		fprintf(TH_LOG_STREAM,
 			"# %s: Test terminated by timeout\n", t->name);
 	} else if (WIFEXITED(status)) {
-		if (t->termsig != -1) {
+		if (WEXITSTATUS(status) == 255) {
+			/* SKIP */
+			t->passed = 1;
+			t->skip = 1;
+		} else if (t->termsig != -1) {
 			t->passed = 0;
 			fprintf(TH_LOG_STREAM,
 				"# %s: Test exited normally instead of by signal (code: %d)\n",
@@ -921,11 +925,6 @@
 			/* Success */
 			case 0:
 				t->passed = 1;
-				break;
-			/* SKIP */
-			case 255:
-				t->passed = 1;
-				t->skip = 1;
 				break;
 			/* Other failure, assume step report. */
 			default:
diff --git a/kernel/tools/testing/selftests/lib.mk b/kernel/tools/testing/selftests/lib.mk
index b7217b5..56e360e 100644
--- a/kernel/tools/testing/selftests/lib.mk
+++ b/kernel/tools/testing/selftests/lib.mk
@@ -128,6 +128,11 @@
 clean:
 	$(CLEAN)
 
+# Enables to extend CFLAGS and LDFLAGS from command line, e.g.
+# make USERCFLAGS=-Werror USERLDFLAGS=-static
+CFLAGS += $(USERCFLAGS)
+LDFLAGS += $(USERLDFLAGS)
+
 # When make O= with kselftest target from main level
 # the following aren't defined.
 #
diff --git a/kernel/tools/testing/selftests/memfd/fuse_test.c b/kernel/tools/testing/selftests/memfd/fuse_test.c
index b018e83..cda6316 100644
--- a/kernel/tools/testing/selftests/memfd/fuse_test.c
+++ b/kernel/tools/testing/selftests/memfd/fuse_test.c
@@ -22,6 +22,7 @@
 #include <linux/falloc.h>
 #include <linux/fcntl.h>
 #include <linux/memfd.h>
+#include <linux/types.h>
 #include <sched.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/kernel/tools/testing/selftests/net/devlink_port_split.py b/kernel/tools/testing/selftests/net/devlink_port_split.py
index 834066d..f0fbd73 100755
--- a/kernel/tools/testing/selftests/net/devlink_port_split.py
+++ b/kernel/tools/testing/selftests/net/devlink_port_split.py
@@ -57,6 +57,8 @@
         assert stderr == ""
         ports = json.loads(stdout)['port']
 
+        validate_devlink_output(ports, 'flavour')
+
         for port in ports:
             if dev in port:
                 if ports[port]['flavour'] == 'physical':
@@ -218,6 +220,27 @@
     unsplit(port.bus_info)
 
 
+def validate_devlink_output(devlink_data, target_property=None):
+    """
+    Determine if test should be skipped by checking:
+      1. devlink_data contains values
+      2. The target_property exist in devlink_data
+    """
+    skip_reason = None
+    if any(devlink_data.values()):
+        if target_property:
+            skip_reason = "{} not found in devlink output, test skipped".format(target_property)
+            for key in devlink_data:
+                if target_property in devlink_data[key]:
+                    skip_reason = None
+    else:
+        skip_reason = 'devlink output is empty, test skipped'
+
+    if skip_reason:
+        print(skip_reason)
+        sys.exit(KSFT_SKIP)
+
+
 def make_parser():
     parser = argparse.ArgumentParser(description='A test for port splitting.')
     parser.add_argument('--dev',
@@ -238,6 +261,7 @@
         stdout, stderr = run_command(cmd)
         assert stderr == ""
 
+        validate_devlink_output(json.loads(stdout))
         devs = json.loads(stdout)['dev']
         dev = list(devs.keys())[0]
 
@@ -249,6 +273,7 @@
 
     ports = devlink_ports(dev)
 
+    found_max_lanes = False
     for port in ports.if_names:
         max_lanes = get_max_lanes(port.name)
 
@@ -271,6 +296,11 @@
                 split_splittable_port(port, lane, max_lanes, dev)
 
                 lane //= 2
+        found_max_lanes = True
+
+    if not found_max_lanes:
+        print(f"Test not started, no port of device {dev} reports max_lanes")
+        sys.exit(KSFT_SKIP)
 
 
 if __name__ == "__main__":
diff --git a/kernel/tools/testing/selftests/net/fcnal-test.sh b/kernel/tools/testing/selftests/net/fcnal-test.sh
index 4a11ea2..e13b0fb 100755
--- a/kernel/tools/testing/selftests/net/fcnal-test.sh
+++ b/kernel/tools/testing/selftests/net/fcnal-test.sh
@@ -81,6 +81,13 @@
 
 which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping)
 
+# Check if FIPS mode is enabled
+if [ -f /proc/sys/crypto/fips_enabled ]; then
+	fips_enabled=`cat /proc/sys/crypto/fips_enabled`
+else
+	fips_enabled=0
+fi
+
 ################################################################################
 # utilities
 
@@ -1139,7 +1146,7 @@
 	run_cmd nettest -d ${NSA_DEV} -r ${a}
 	log_test_addr ${a} $? 1 "No server, device client, local conn"
 
-	ipv4_tcp_md5_novrf
+	[ "$fips_enabled" = "1" ] || ipv4_tcp_md5_novrf
 }
 
 ipv4_tcp_vrf()
@@ -1193,9 +1200,11 @@
 	log_test_addr ${a} $? 1 "Global server, local connection"
 
 	# run MD5 tests
-	setup_vrf_dup
-	ipv4_tcp_md5
-	cleanup_vrf_dup
+	if [ "$fips_enabled" = "0" ]; then
+		setup_vrf_dup
+		ipv4_tcp_md5
+		cleanup_vrf_dup
+	fi
 
 	#
 	# enable VRF global server
@@ -2611,7 +2620,7 @@
 		log_test_addr ${a} $? 1 "No server, device client, local conn"
 	done
 
-	ipv6_tcp_md5_novrf
+	[ "$fips_enabled" = "1" ] || ipv6_tcp_md5_novrf
 }
 
 ipv6_tcp_vrf()
@@ -2681,9 +2690,11 @@
 	log_test_addr ${a} $? 1 "Global server, local connection"
 
 	# run MD5 tests
-	setup_vrf_dup
-	ipv6_tcp_md5
-	cleanup_vrf_dup
+	if [ "$fips_enabled" = "0" ]; then
+		setup_vrf_dup
+		ipv6_tcp_md5
+		cleanup_vrf_dup
+	fi
 
 	#
 	# enable VRF global server
diff --git a/kernel/tools/testing/selftests/net/fib_tests.sh b/kernel/tools/testing/selftests/net/fib_tests.sh
index 0f3bf90..1681016 100755
--- a/kernel/tools/testing/selftests/net/fib_tests.sh
+++ b/kernel/tools/testing/selftests/net/fib_tests.sh
@@ -68,7 +68,7 @@
 cleanup()
 {
 	$IP link del dev dummy0 &> /dev/null
-	ip netns del ns1
+	ip netns del ns1 &> /dev/null
 	ip netns del ns2 &> /dev/null
 }
 
@@ -1773,6 +1773,8 @@
 ################################################################################
 # main
 
+trap cleanup EXIT
+
 while getopts :t:pPhv o
 do
 	case $o in
diff --git a/kernel/tools/testing/selftests/net/forwarding/ethtool.sh b/kernel/tools/testing/selftests/net/forwarding/ethtool.sh
index dbb9fcf..aa2eafb 100755
--- a/kernel/tools/testing/selftests/net/forwarding/ethtool.sh
+++ b/kernel/tools/testing/selftests/net/forwarding/ethtool.sh
@@ -286,6 +286,8 @@
 	ethtool -s $h1 autoneg on
 }
 
+skip_on_veth
+
 trap cleanup EXIT
 
 setup_prepare
diff --git a/kernel/tools/testing/selftests/net/forwarding/ethtool_extended_state.sh b/kernel/tools/testing/selftests/net/forwarding/ethtool_extended_state.sh
index 4b42dfd..baf831d 100755
--- a/kernel/tools/testing/selftests/net/forwarding/ethtool_extended_state.sh
+++ b/kernel/tools/testing/selftests/net/forwarding/ethtool_extended_state.sh
@@ -95,6 +95,8 @@
 	ip link set dev $swp3 down
 }
 
+skip_on_veth
+
 setup_prepare
 
 tests_run
diff --git a/kernel/tools/testing/selftests/net/forwarding/lib.sh b/kernel/tools/testing/selftests/net/forwarding/lib.sh
index 54020d0..dfb41db 100644
--- a/kernel/tools/testing/selftests/net/forwarding/lib.sh
+++ b/kernel/tools/testing/selftests/net/forwarding/lib.sh
@@ -69,6 +69,17 @@
 	fi
 }
 
+skip_on_veth()
+{
+	local kind=$(ip -j -d link show dev ${NETIFS[p1]} |
+		jq -r '.[].linkinfo.info_kind')
+
+	if [[ $kind == veth ]]; then
+		echo "SKIP: Test cannot be run with veth pairs"
+		exit $ksft_skip
+	fi
+}
+
 if [[ "$(id -u)" -ne 0 ]]; then
 	echo "SKIP: need root privileges"
 	exit 0
@@ -120,6 +131,11 @@
 
 	for ((i = 1; i <= NUM_NETIFS; ++i)); do
 		local j=$((i+1))
+
+		if [ -z ${NETIFS[p$i]} ]; then
+			echo "SKIP: Cannot create interface. Name not specified"
+			exit $ksft_skip
+		fi
 
 		ip link show dev ${NETIFS[p$i]} &> /dev/null
 		if [[ $? -ne 0 ]]; then
@@ -731,14 +747,14 @@
 	local value=$1; shift
 
 	SYSCTL_ORIG[$key]=$(sysctl -n $key)
-	sysctl -qw $key=$value
+	sysctl -qw $key="$value"
 }
 
 sysctl_restore()
 {
 	local key=$1; shift
 
-	sysctl -qw $key=${SYSCTL_ORIG["$key"]}
+	sysctl -qw $key="${SYSCTL_ORIG[$key]}"
 }
 
 forwarding_enable()
diff --git a/kernel/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh b/kernel/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh
index 472bd02..b501b36 100755
--- a/kernel/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh
+++ b/kernel/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh
@@ -72,7 +72,8 @@
 
 	RET=0
 
-	mirror_install $swp1 ingress $tundev "matchall $tcflags"
+	mirror_install $swp1 ingress $tundev \
+		"prot ip flower $tcflags ip_prot icmp"
 	tc filter add dev $h3 ingress pref 77 prot $prot \
 		flower ip_ttl 50 action pass
 
diff --git a/kernel/tools/testing/selftests/net/forwarding/settings b/kernel/tools/testing/selftests/net/forwarding/settings
new file mode 100644
index 0000000..e7b9417
--- /dev/null
+++ b/kernel/tools/testing/selftests/net/forwarding/settings
@@ -0,0 +1 @@
+timeout=0
diff --git a/kernel/tools/testing/selftests/net/forwarding/tc_actions.sh b/kernel/tools/testing/selftests/net/forwarding/tc_actions.sh
index d9eca22..1e27031 100755
--- a/kernel/tools/testing/selftests/net/forwarding/tc_actions.sh
+++ b/kernel/tools/testing/selftests/net/forwarding/tc_actions.sh
@@ -3,7 +3,7 @@
 
 ALL_TESTS="gact_drop_and_ok_test mirred_egress_redirect_test \
 	mirred_egress_mirror_test matchall_mirred_egress_mirror_test \
-	gact_trap_test"
+	gact_trap_test mirred_egress_to_ingress_tcp_test"
 NUM_NETIFS=4
 source tc_common.sh
 source lib.sh
@@ -153,6 +153,52 @@
 	log_test "trap ($tcflags)"
 }
 
+mirred_egress_to_ingress_tcp_test()
+{
+	local tmpfile=$(mktemp) tmpfile1=$(mktemp)
+
+	RET=0
+	dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$tmpfile
+	tc filter add dev $h1 protocol ip pref 100 handle 100 egress flower \
+		$tcflags ip_proto tcp src_ip 192.0.2.1 dst_ip 192.0.2.2 \
+			action ct commit nat src addr 192.0.2.2 pipe \
+			action ct clear pipe \
+			action ct commit nat dst addr 192.0.2.1 pipe \
+			action ct clear pipe \
+			action skbedit ptype host pipe \
+			action mirred ingress redirect dev $h1
+	tc filter add dev $h1 protocol ip pref 101 handle 101 egress flower \
+		$tcflags ip_proto icmp \
+			action mirred ingress redirect dev $h1
+	tc filter add dev $h1 protocol ip pref 102 handle 102 ingress flower \
+		ip_proto icmp \
+			action drop
+
+	ip vrf exec v$h1 nc --recv-only -w10 -l -p 12345 -o $tmpfile1  &
+	local rpid=$!
+	ip vrf exec v$h1 nc -w1 --send-only 192.0.2.2 12345 <$tmpfile
+	wait -n $rpid
+	cmp -s $tmpfile $tmpfile1
+	check_err $? "server output check failed"
+
+	$MZ $h1 -c 10 -p 64 -a $h1mac -b $h1mac -A 192.0.2.1 -B 192.0.2.1 \
+		-t icmp "ping,id=42,seq=5" -q
+	tc_check_packets "dev $h1 egress" 101 10
+	check_err $? "didn't mirred redirect ICMP"
+	tc_check_packets "dev $h1 ingress" 102 10
+	check_err $? "didn't drop mirred ICMP"
+	local overlimits=$(tc_rule_stats_get ${h1} 101 egress .overlimits)
+	test ${overlimits} = 10
+	check_err $? "wrong overlimits, expected 10 got ${overlimits}"
+
+	tc filter del dev $h1 egress protocol ip pref 100 handle 100 flower
+	tc filter del dev $h1 egress protocol ip pref 101 handle 101 flower
+	tc filter del dev $h1 ingress protocol ip pref 102 handle 102 flower
+
+	rm -f $tmpfile $tmpfile1
+	log_test "mirred_egress_to_ingress_tcp ($tcflags)"
+}
+
 setup_prepare()
 {
 	h1=${NETIFS[p1]}
diff --git a/kernel/tools/testing/selftests/net/forwarding/tc_flower.sh b/kernel/tools/testing/selftests/net/forwarding/tc_flower.sh
index b11d8e6..b7cdf75 100755
--- a/kernel/tools/testing/selftests/net/forwarding/tc_flower.sh
+++ b/kernel/tools/testing/selftests/net/forwarding/tc_flower.sh
@@ -49,8 +49,8 @@
 	tc_check_packets "dev $h2 ingress" 101 1
 	check_fail $? "Matched on a wrong filter"
 
-	tc_check_packets "dev $h2 ingress" 102 1
-	check_err $? "Did not match on correct filter"
+	tc_check_packets "dev $h2 ingress" 102 0
+	check_fail $? "Did not match on correct filter"
 
 	tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
 	tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
@@ -75,8 +75,8 @@
 	tc_check_packets "dev $h2 ingress" 101 1
 	check_fail $? "Matched on a wrong filter"
 
-	tc_check_packets "dev $h2 ingress" 102 1
-	check_err $? "Did not match on correct filter"
+	tc_check_packets "dev $h2 ingress" 102 0
+	check_fail $? "Did not match on correct filter"
 
 	tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
 	tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
diff --git a/kernel/tools/testing/selftests/net/mptcp/Makefile b/kernel/tools/testing/selftests/net/mptcp/Makefile
index 00bb158..7072ef1 100644
--- a/kernel/tools/testing/selftests/net/mptcp/Makefile
+++ b/kernel/tools/testing/selftests/net/mptcp/Makefile
@@ -10,7 +10,7 @@
 
 TEST_GEN_FILES = mptcp_connect pm_nl_ctl
 
-TEST_FILES := settings
+TEST_FILES := mptcp_lib.sh settings
 
 EXTRA_CLEAN := *.pcap
 
diff --git a/kernel/tools/testing/selftests/net/mptcp/config b/kernel/tools/testing/selftests/net/mptcp/config
index 741a1c4..8867c40 100644
--- a/kernel/tools/testing/selftests/net/mptcp/config
+++ b/kernel/tools/testing/selftests/net/mptcp/config
@@ -1,3 +1,4 @@
+CONFIG_KALLSYMS=y
 CONFIG_MPTCP=y
 CONFIG_IPV6=y
 CONFIG_MPTCP_IPV6=y
@@ -5,3 +6,4 @@
 CONFIG_INET_MPTCP_DIAG=m
 CONFIG_VETH=y
 CONFIG_NET_SCH_NETEM=m
+CONFIG_SYN_COOKIES=y
diff --git a/kernel/tools/testing/selftests/net/mptcp/diag.sh b/kernel/tools/testing/selftests/net/mptcp/diag.sh
index 39edce4..34577d4 100755
--- a/kernel/tools/testing/selftests/net/mptcp/diag.sh
+++ b/kernel/tools/testing/selftests/net/mptcp/diag.sh
@@ -1,6 +1,8 @@
 #!/bin/bash
 # SPDX-License-Identifier: GPL-2.0
 
+. "$(dirname "${0}")/mptcp_lib.sh"
+
 rndh=$(printf %x $sec)-$(mktemp -u XXXXXX)
 ns="ns1-$rndh"
 ksft_skip=4
@@ -28,6 +30,8 @@
 	done
 }
 
+mptcp_lib_check_mptcp
+
 ip -Version > /dev/null 2>&1
 if [ $? -ne 0 ];then
 	echo "SKIP: Could not run test without ip tool"
diff --git a/kernel/tools/testing/selftests/net/mptcp/mptcp_connect.sh b/kernel/tools/testing/selftests/net/mptcp/mptcp_connect.sh
index 987a914..fb89298 100755
--- a/kernel/tools/testing/selftests/net/mptcp/mptcp_connect.sh
+++ b/kernel/tools/testing/selftests/net/mptcp/mptcp_connect.sh
@@ -1,6 +1,8 @@
 #!/bin/bash
 # SPDX-License-Identifier: GPL-2.0
 
+. "$(dirname "${0}")/mptcp_lib.sh"
+
 time_start=$(date +%s)
 
 optstring="S:R:d:e:l:r:h4cm:f:t"
@@ -131,6 +133,8 @@
 	done
 }
 
+mptcp_lib_check_mptcp
+
 ip -Version > /dev/null 2>&1
 if [ $? -ne 0 ];then
 	echo "SKIP: Could not run test without ip tool"
diff --git a/kernel/tools/testing/selftests/net/mptcp/mptcp_join.sh b/kernel/tools/testing/selftests/net/mptcp/mptcp_join.sh
index 08f53d8..d205828 100755
--- a/kernel/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/kernel/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -1,6 +1,8 @@
 #!/bin/bash
 # SPDX-License-Identifier: GPL-2.0
 
+. "$(dirname "${0}")/mptcp_lib.sh"
+
 ret=0
 sin=""
 sout=""
@@ -88,6 +90,8 @@
 	fi
 done
 
+mptcp_lib_check_mptcp
+
 ip -Version > /dev/null 2>&1
 if [ $? -ne 0 ];then
 	echo "SKIP: Could not run test without ip tool"
@@ -124,6 +128,22 @@
 		echo "$listener_ns -> $connect_addr connectivity [ FAIL ]" 1>&2
 		ret=1
 	fi
+}
+
+# $1: ns ; $2: counter
+get_counter()
+{
+	local ns="${1}"
+	local counter="${2}"
+	local count
+
+	count=$(ip netns exec ${ns} nstat -asz "${counter}" | awk 'NR==1 {next} {print $2}')
+	if [ -z "${count}" ]; then
+		mptcp_lib_fail_if_expected_feature "${counter} counter"
+		return 1
+	fi
+
+	echo "${count}"
 }
 
 do_transfer()
@@ -287,9 +307,10 @@
 	local dump_stats
 
 	printf "%02u %-36s %s" "$TEST_COUNT" "$msg" "syn"
-	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinSynRx | awk '{print $2}'`
-	[ -z "$count" ] && count=0
-	if [ "$count" != "$syn_nr" ]; then
+	count=$(get_counter ${ns1} "MPTcpExtMPJoinSynRx")
+	if [ -z "$count" ]; then
+		echo -n "[skip]"
+	elif [ "$count" != "$syn_nr" ]; then
 		echo "[fail] got $count JOIN[s] syn expected $syn_nr"
 		ret=1
 		dump_stats=1
@@ -298,9 +319,10 @@
 	fi
 
 	echo -n " - synack"
-	count=`ip netns exec $ns2 nstat -as | grep MPTcpExtMPJoinSynAckRx | awk '{print $2}'`
-	[ -z "$count" ] && count=0
-	if [ "$count" != "$syn_ack_nr" ]; then
+	count=$(get_counter ${ns2} "MPTcpExtMPJoinSynAckRx")
+	if [ -z "$count" ]; then
+		echo -n "[skip]"
+	elif [ "$count" != "$syn_ack_nr" ]; then
 		echo "[fail] got $count JOIN[s] synack expected $syn_ack_nr"
 		ret=1
 		dump_stats=1
@@ -309,9 +331,10 @@
 	fi
 
 	echo -n " - ack"
-	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinAckRx | awk '{print $2}'`
-	[ -z "$count" ] && count=0
-	if [ "$count" != "$ack_nr" ]; then
+	count=$(get_counter ${ns1} "MPTcpExtMPJoinAckRx")
+	if [ -z "$count" ]; then
+		echo "[skip]"
+	elif [ "$count" != "$ack_nr" ]; then
 		echo "[fail] got $count JOIN[s] ack expected $ack_nr"
 		ret=1
 		dump_stats=1
@@ -334,9 +357,10 @@
 	local dump_stats
 
 	printf "%-39s %s" " " "add"
-	count=`ip netns exec $ns2 nstat -as | grep MPTcpExtAddAddr | awk '{print $2}'`
-	[ -z "$count" ] && count=0
-	if [ "$count" != "$add_nr" ]; then
+	count=$(get_counter ${ns2} "MPTcpExtAddAddr")
+	if [ -z "$count" ]; then
+		echo -n "[skip]"
+	elif [ "$count" != "$add_nr" ]; then
 		echo "[fail] got $count ADD_ADDR[s] expected $add_nr"
 		ret=1
 		dump_stats=1
@@ -345,9 +369,10 @@
 	fi
 
 	echo -n " - echo  "
-	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtEchoAdd | awk '{print $2}'`
-	[ -z "$count" ] && count=0
-	if [ "$count" != "$echo_nr" ]; then
+	count=$(get_counter ${ns1} "MPTcpExtEchoAdd")
+	if [ -z "$count" ]; then
+		echo "[skip]"
+	elif [ "$count" != "$echo_nr" ]; then
 		echo "[fail] got $count ADD_ADDR echo[s] expected $echo_nr"
 		ret=1
 		dump_stats=1
@@ -371,9 +396,10 @@
 	local dump_stats
 
 	printf "%-39s %s" " " "rm "
-	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtRmAddr | awk '{print $2}'`
-	[ -z "$count" ] && count=0
-	if [ "$count" != "$rm_addr_nr" ]; then
+	count=$(get_counter ${ns1} "MPTcpExtRmAddr")
+	if [ -z "$count" ]; then
+		echo -n "[skip]"
+	elif [ "$count" != "$rm_addr_nr" ]; then
 		echo "[fail] got $count RM_ADDR[s] expected $rm_addr_nr"
 		ret=1
 		dump_stats=1
@@ -382,9 +408,10 @@
 	fi
 
 	echo -n " - sf    "
-	count=`ip netns exec $ns2 nstat -as | grep MPTcpExtRmSubflow | awk '{print $2}'`
-	[ -z "$count" ] && count=0
-	if [ "$count" != "$rm_subflow_nr" ]; then
+	count=$(get_counter ${ns2} "MPTcpExtRmSubflow")
+	if [ -z "$count" ]; then
+		echo "[skip]"
+	elif [ "$count" != "$rm_subflow_nr" ]; then
 		echo "[fail] got $count RM_SUBFLOW[s] expected $rm_subflow_nr"
 		ret=1
 		dump_stats=1
diff --git a/kernel/tools/testing/selftests/net/mptcp/mptcp_lib.sh b/kernel/tools/testing/selftests/net/mptcp/mptcp_lib.sh
new file mode 100644
index 0000000..f32045b
--- /dev/null
+++ b/kernel/tools/testing/selftests/net/mptcp/mptcp_lib.sh
@@ -0,0 +1,104 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+readonly KSFT_FAIL=1
+readonly KSFT_SKIP=4
+
+# SELFTESTS_MPTCP_LIB_EXPECT_ALL_FEATURES env var can be set when validating all
+# features using the last version of the kernel and the selftests to make sure
+# a test is not being skipped by mistake.
+mptcp_lib_expect_all_features() {
+	[ "${SELFTESTS_MPTCP_LIB_EXPECT_ALL_FEATURES:-}" = "1" ]
+}
+
+# $1: msg
+mptcp_lib_fail_if_expected_feature() {
+	if mptcp_lib_expect_all_features; then
+		echo "ERROR: missing feature: ${*}"
+		exit ${KSFT_FAIL}
+	fi
+
+	return 1
+}
+
+# $1: file
+mptcp_lib_has_file() {
+	local f="${1}"
+
+	if [ -f "${f}" ]; then
+		return 0
+	fi
+
+	mptcp_lib_fail_if_expected_feature "${f} file not found"
+}
+
+mptcp_lib_check_mptcp() {
+	if ! mptcp_lib_has_file "/proc/sys/net/mptcp/enabled"; then
+		echo "SKIP: MPTCP support is not available"
+		exit ${KSFT_SKIP}
+	fi
+}
+
+mptcp_lib_check_kallsyms() {
+	if ! mptcp_lib_has_file "/proc/kallsyms"; then
+		echo "SKIP: CONFIG_KALLSYMS is missing"
+		exit ${KSFT_SKIP}
+	fi
+}
+
+# Internal: use mptcp_lib_kallsyms_has() instead
+__mptcp_lib_kallsyms_has() {
+	local sym="${1}"
+
+	mptcp_lib_check_kallsyms
+
+	grep -q " ${sym}" /proc/kallsyms
+}
+
+# $1: part of a symbol to look at, add '$' at the end for full name
+mptcp_lib_kallsyms_has() {
+	local sym="${1}"
+
+	if __mptcp_lib_kallsyms_has "${sym}"; then
+		return 0
+	fi
+
+	mptcp_lib_fail_if_expected_feature "${sym} symbol not found"
+}
+
+# $1: part of a symbol to look at, add '$' at the end for full name
+mptcp_lib_kallsyms_doesnt_have() {
+	local sym="${1}"
+
+	if ! __mptcp_lib_kallsyms_has "${sym}"; then
+		return 0
+	fi
+
+	mptcp_lib_fail_if_expected_feature "${sym} symbol has been found"
+}
+
+# !!!AVOID USING THIS!!!
+# Features might not land in the expected version and features can be backported
+#
+# $1: kernel version, e.g. 6.3
+mptcp_lib_kversion_ge() {
+	local exp_maj="${1%.*}"
+	local exp_min="${1#*.}"
+	local v maj min
+
+	# If the kernel has backported features, set this env var to 1:
+	if [ "${SELFTESTS_MPTCP_LIB_NO_KVERSION_CHECK:-}" = "1" ]; then
+		return 0
+	fi
+
+	v=$(uname -r | cut -d'.' -f1,2)
+	maj=${v%.*}
+	min=${v#*.}
+
+	if   [ "${maj}" -gt "${exp_maj}" ] ||
+	   { [ "${maj}" -eq "${exp_maj}" ] && [ "${min}" -ge "${exp_min}" ]; }; then
+		return 0
+	fi
+
+	mptcp_lib_fail_if_expected_feature "kernel version ${1} lower than ${v}"
+}
diff --git a/kernel/tools/testing/selftests/net/mptcp/pm_netlink.sh b/kernel/tools/testing/selftests/net/mptcp/pm_netlink.sh
index 15f4f46..fff6f74 100755
--- a/kernel/tools/testing/selftests/net/mptcp/pm_netlink.sh
+++ b/kernel/tools/testing/selftests/net/mptcp/pm_netlink.sh
@@ -1,6 +1,8 @@
 #!/bin/bash
 # SPDX-License-Identifier: GPL-2.0
 
+. "$(dirname "${0}")/mptcp_lib.sh"
+
 ksft_skip=4
 ret=0
 
@@ -33,6 +35,8 @@
 	rm -f $err
 	ip netns del $ns1
 }
+
+mptcp_lib_check_mptcp
 
 ip -Version > /dev/null 2>&1
 if [ $? -ne 0 ];then
@@ -69,8 +73,12 @@
 }
 
 check "ip netns exec $ns1 ./pm_nl_ctl dump" "" "defaults addr list"
-check "ip netns exec $ns1 ./pm_nl_ctl limits" "accept 0
+
+default_limits="$(ip netns exec $ns1 ./pm_nl_ctl limits)"
+if mptcp_lib_expect_all_features; then
+	check "ip netns exec $ns1 ./pm_nl_ctl limits" "accept 0
 subflows 0" "defaults limits"
+fi
 
 ip netns exec $ns1 ./pm_nl_ctl add 10.0.1.1
 ip netns exec $ns1 ./pm_nl_ctl add 10.0.1.2 flags subflow dev lo
@@ -116,12 +124,10 @@
 check "ip netns exec $ns1 ./pm_nl_ctl dump" "" "flush addrs"
 
 ip netns exec $ns1 ./pm_nl_ctl limits 9 1
-check "ip netns exec $ns1 ./pm_nl_ctl limits" "accept 0
-subflows 0" "rcv addrs above hard limit"
+check "ip netns exec $ns1 ./pm_nl_ctl limits" "$default_limits" "rcv addrs above hard limit"
 
 ip netns exec $ns1 ./pm_nl_ctl limits 1 9
-check "ip netns exec $ns1 ./pm_nl_ctl limits" "accept 0
-subflows 0" "subflows above hard limit"
+check "ip netns exec $ns1 ./pm_nl_ctl limits" "$default_limits" "subflows above hard limit"
 
 ip netns exec $ns1 ./pm_nl_ctl limits 8 8
 check "ip netns exec $ns1 ./pm_nl_ctl limits" "accept 8
diff --git a/kernel/tools/testing/selftests/net/mptcp/simult_flows.sh b/kernel/tools/testing/selftests/net/mptcp/simult_flows.sh
index 8fcb289..b51afba 100755
--- a/kernel/tools/testing/selftests/net/mptcp/simult_flows.sh
+++ b/kernel/tools/testing/selftests/net/mptcp/simult_flows.sh
@@ -1,6 +1,8 @@
 #!/bin/bash
 # SPDX-License-Identifier: GPL-2.0
 
+. "$(dirname "${0}")/mptcp_lib.sh"
+
 rndh=$(printf %x $sec)-$(mktemp -u XXXXXX)
 ns1="ns1-$rndh"
 ns2="ns2-$rndh"
@@ -31,6 +33,8 @@
 	done
 }
 
+mptcp_lib_check_mptcp
+
 ip -Version > /dev/null 2>&1
 if [ $? -ne 0 ];then
 	echo "SKIP: Could not run test without ip tool"
diff --git a/kernel/tools/testing/selftests/net/rtnetlink.sh b/kernel/tools/testing/selftests/net/rtnetlink.sh
index c3a9059..cbf166d 100755
--- a/kernel/tools/testing/selftests/net/rtnetlink.sh
+++ b/kernel/tools/testing/selftests/net/rtnetlink.sh
@@ -835,6 +835,7 @@
 	fi
 
 	# clean up any leftovers
+	echo 0 > /sys/bus/netdevsim/del_device
 	$probed && rmmod netdevsim
 
 	if [ $ret -ne 0 ]; then
diff --git a/kernel/tools/testing/selftests/net/tls.c b/kernel/tools/testing/selftests/net/tls.c
index b599f1f..44a25a9 100644
--- a/kernel/tools/testing/selftests/net/tls.c
+++ b/kernel/tools/testing/selftests/net/tls.c
@@ -384,11 +384,12 @@
 
 		msg.msg_iov = &vec;
 		msg.msg_iovlen = 1;
-		EXPECT_EQ(sendmsg(self->cfd, &msg, 0), send_len);
+		EXPECT_EQ(sendmsg(self->fd, &msg, 0), send_len);
 	}
 
-	while (recvs++ < sends)
-		EXPECT_NE(recv(self->fd, mem, send_len, 0), -1);
+	while (recvs++ < sends) {
+		EXPECT_NE(recv(self->cfd, mem, send_len, 0), -1);
+	}
 
 	free(mem);
 }
@@ -416,9 +417,9 @@
 	msg.msg_iov = vec;
 	msg.msg_iovlen = iov_len;
 
-	EXPECT_EQ(sendmsg(self->cfd, &msg, 0), total_len);
+	EXPECT_EQ(sendmsg(self->fd, &msg, 0), total_len);
 	buf = malloc(total_len);
-	EXPECT_NE(recv(self->fd, buf, total_len, 0), -1);
+	EXPECT_NE(recv(self->cfd, buf, total_len, 0), -1);
 	for (i = 0; i < iov_len; i++) {
 		EXPECT_EQ(memcmp(test_strs[i], buf + len_cmp,
 				 strlen(test_strs[i])),
diff --git a/kernel/tools/testing/selftests/net/udpgso_bench.sh b/kernel/tools/testing/selftests/net/udpgso_bench.sh
index dc932fd..640bc43 100755
--- a/kernel/tools/testing/selftests/net/udpgso_bench.sh
+++ b/kernel/tools/testing/selftests/net/udpgso_bench.sh
@@ -7,6 +7,7 @@
 readonly YELLOW='\033[0;33m'
 readonly RED='\033[0;31m'
 readonly NC='\033[0m' # No Color
+readonly TESTPORT=8000
 
 readonly KSFT_PASS=0
 readonly KSFT_FAIL=1
@@ -56,11 +57,26 @@
 
 run_one() {
 	local -r args=$@
+	local nr_socks=0
+	local i=0
+	local -r timeout=10
 
-	./udpgso_bench_rx &
-	./udpgso_bench_rx -t &
+	./udpgso_bench_rx -p "$TESTPORT" &
+	./udpgso_bench_rx -p "$TESTPORT" -t &
 
-	./udpgso_bench_tx ${args}
+	# Wait for the above test program to get ready to receive connections.
+	while [ "$i" -lt "$timeout" ]; do
+		nr_socks="$(ss -lnHi | grep -c "\*:${TESTPORT}")"
+		[ "$nr_socks" -eq 2 ] && break
+		i=$((i + 1))
+		sleep 1
+	done
+	if [ "$nr_socks" -ne 2 ]; then
+		echo "timed out while waiting for udpgso_bench_rx"
+		exit 1
+	fi
+
+	./udpgso_bench_tx -p "$TESTPORT" ${args}
 }
 
 run_in_netns() {
diff --git a/kernel/tools/testing/selftests/net/udpgso_bench_rx.c b/kernel/tools/testing/selftests/net/udpgso_bench_rx.c
index 6a19342..f35a924 100644
--- a/kernel/tools/testing/selftests/net/udpgso_bench_rx.c
+++ b/kernel/tools/testing/selftests/net/udpgso_bench_rx.c
@@ -214,11 +214,10 @@
 
 static int recv_msg(int fd, char *buf, int len, int *gso_size)
 {
-	char control[CMSG_SPACE(sizeof(uint16_t))] = {0};
+	char control[CMSG_SPACE(sizeof(int))] = {0};
 	struct msghdr msg = {0};
 	struct iovec iov = {0};
 	struct cmsghdr *cmsg;
-	uint16_t *gsosizeptr;
 	int ret;
 
 	iov.iov_base = buf;
@@ -237,8 +236,7 @@
 		     cmsg = CMSG_NXTHDR(&msg, cmsg)) {
 			if (cmsg->cmsg_level == SOL_UDP
 			    && cmsg->cmsg_type == UDP_GRO) {
-				gsosizeptr = (uint16_t *) CMSG_DATA(cmsg);
-				*gso_size = *gsosizeptr;
+				*gso_size = *(int *)CMSG_DATA(cmsg);
 				break;
 			}
 		}
@@ -250,7 +248,7 @@
 static void do_flush_udp(int fd)
 {
 	static char rbuf[ETH_MAX_MTU];
-	int ret, len, gso_size, budget = 256;
+	int ret, len, gso_size = 0, budget = 256;
 
 	len = cfg_read_all ? sizeof(rbuf) : 0;
 	while (budget--) {
@@ -336,6 +334,8 @@
 			cfg_verify = true;
 			cfg_read_all = true;
 			break;
+		default:
+			exit(1);
 		}
 	}
 
diff --git a/kernel/tools/testing/selftests/net/udpgso_bench_tx.c b/kernel/tools/testing/selftests/net/udpgso_bench_tx.c
index f1fdaa2..4773927 100644
--- a/kernel/tools/testing/selftests/net/udpgso_bench_tx.c
+++ b/kernel/tools/testing/selftests/net/udpgso_bench_tx.c
@@ -62,6 +62,7 @@
 static int	cfg_port	= 8000;
 static int	cfg_runtime_ms	= -1;
 static bool	cfg_poll;
+static int	cfg_poll_loop_timeout_ms = 2000;
 static bool	cfg_segment;
 static bool	cfg_sendmmsg;
 static bool	cfg_tcp;
@@ -235,16 +236,17 @@
 	}
 }
 
-static void flush_errqueue(int fd, const bool do_poll)
+static void flush_errqueue(int fd, const bool do_poll,
+			   unsigned long poll_timeout, const bool poll_err)
 {
 	if (do_poll) {
 		struct pollfd fds = {0};
 		int ret;
 
 		fds.fd = fd;
-		ret = poll(&fds, 1, 500);
+		ret = poll(&fds, 1, poll_timeout);
 		if (ret == 0) {
-			if (cfg_verbose)
+			if ((cfg_verbose) && (poll_err))
 				fprintf(stderr, "poll timeout\n");
 		} else if (ret < 0) {
 			error(1, errno, "poll");
@@ -252,6 +254,20 @@
 	}
 
 	flush_errqueue_recv(fd);
+}
+
+static void flush_errqueue_retry(int fd, unsigned long num_sends)
+{
+	unsigned long tnow, tstop;
+	bool first_try = true;
+
+	tnow = gettimeofday_ms();
+	tstop = tnow + cfg_poll_loop_timeout_ms;
+	do {
+		flush_errqueue(fd, true, tstop - tnow, first_try);
+		first_try = false;
+		tnow = gettimeofday_ms();
+	} while ((stat_zcopies != num_sends) && (tnow < tstop));
 }
 
 static int send_tcp(int fd, char *data)
@@ -413,7 +429,8 @@
 
 static void usage(const char *filepath)
 {
-	error(1, 0, "Usage: %s [-46acmHPtTuvz] [-C cpu] [-D dst ip] [-l secs] [-M messagenr] [-p port] [-s sendsize] [-S gsosize]",
+	error(1, 0, "Usage: %s [-46acmHPtTuvz] [-C cpu] [-D dst ip] [-l secs] "
+		    "[-L secs] [-M messagenr] [-p port] [-s sendsize] [-S gsosize]",
 		    filepath);
 }
 
@@ -423,7 +440,7 @@
 	int max_len, hdrlen;
 	int c;
 
-	while ((c = getopt(argc, argv, "46acC:D:Hl:mM:p:s:PS:tTuvz")) != -1) {
+	while ((c = getopt(argc, argv, "46acC:D:Hl:L:mM:p:s:PS:tTuvz")) != -1) {
 		switch (c) {
 		case '4':
 			if (cfg_family != PF_UNSPEC)
@@ -451,6 +468,9 @@
 			break;
 		case 'l':
 			cfg_runtime_ms = strtoul(optarg, NULL, 10) * 1000;
+			break;
+		case 'L':
+			cfg_poll_loop_timeout_ms = strtoul(optarg, NULL, 10) * 1000;
 			break;
 		case 'm':
 			cfg_sendmmsg = true;
@@ -490,6 +510,8 @@
 		case 'z':
 			cfg_zerocopy = true;
 			break;
+		default:
+			exit(1);
 		}
 	}
 
@@ -677,7 +699,7 @@
 			num_sends += send_udp(fd, buf[i]);
 		num_msgs++;
 		if ((cfg_zerocopy && ((num_msgs & 0xF) == 0)) || cfg_tx_tstamp)
-			flush_errqueue(fd, cfg_poll);
+			flush_errqueue(fd, cfg_poll, 500, true);
 
 		if (cfg_msg_nr && num_msgs >= cfg_msg_nr)
 			break;
@@ -696,7 +718,7 @@
 	} while (!interrupted && (cfg_runtime_ms == -1 || tnow < tstop));
 
 	if (cfg_zerocopy || cfg_tx_tstamp)
-		flush_errqueue(fd, true);
+		flush_errqueue_retry(fd, num_sends);
 
 	if (close(fd))
 		error(1, errno, "close");
diff --git a/kernel/tools/testing/selftests/net/vrf-xfrm-tests.sh b/kernel/tools/testing/selftests/net/vrf-xfrm-tests.sh
index 184da81..452638a 100755
--- a/kernel/tools/testing/selftests/net/vrf-xfrm-tests.sh
+++ b/kernel/tools/testing/selftests/net/vrf-xfrm-tests.sh
@@ -264,60 +264,60 @@
 	ip -netns host1 xfrm state add src ${HOST1_4} dst ${HOST2_4} \
 	    proto esp spi ${SPI_1} reqid 0 mode tunnel \
 	    replay-window 4 replay-oseq 0x4 \
-	    auth-trunc 'hmac(md5)' ${AUTH_1} 96 \
-	    enc 'cbc(des3_ede)' ${ENC_1} \
+	    auth-trunc 'hmac(sha1)' ${AUTH_1} 96 \
+	    enc 'cbc(aes)' ${ENC_1} \
 	    sel src ${h1_4} dst ${h2_4} ${devarg}
 
 	ip -netns host2 xfrm state add src ${HOST1_4} dst ${HOST2_4} \
 	    proto esp spi ${SPI_1} reqid 0 mode tunnel \
 	    replay-window 4 replay-oseq 0x4 \
-	    auth-trunc 'hmac(md5)' ${AUTH_1} 96 \
-	    enc 'cbc(des3_ede)' ${ENC_1} \
+	    auth-trunc 'hmac(sha1)' ${AUTH_1} 96 \
+	    enc 'cbc(aes)' ${ENC_1} \
 	    sel src ${h1_4} dst ${h2_4}
 
 
 	ip -netns host1 xfrm state add src ${HOST2_4} dst ${HOST1_4} \
 	    proto esp spi ${SPI_2} reqid 0 mode tunnel \
 	    replay-window 4 replay-oseq 0x4 \
-	    auth-trunc 'hmac(md5)' ${AUTH_2} 96 \
-	    enc 'cbc(des3_ede)' ${ENC_2} \
+	    auth-trunc 'hmac(sha1)' ${AUTH_2} 96 \
+	    enc 'cbc(aes)' ${ENC_2} \
 	    sel src ${h2_4} dst ${h1_4} ${devarg}
 
 	ip -netns host2 xfrm state add src ${HOST2_4} dst ${HOST1_4} \
 	    proto esp spi ${SPI_2} reqid 0 mode tunnel \
 	    replay-window 4 replay-oseq 0x4 \
-	    auth-trunc 'hmac(md5)' ${AUTH_2} 96 \
-	    enc 'cbc(des3_ede)' ${ENC_2} \
+	    auth-trunc 'hmac(sha1)' ${AUTH_2} 96 \
+	    enc 'cbc(aes)' ${ENC_2} \
 	    sel src ${h2_4} dst ${h1_4}
 
 
 	ip -6 -netns host1 xfrm state add src ${HOST1_6} dst ${HOST2_6} \
 	    proto esp spi ${SPI_1} reqid 0 mode tunnel \
 	    replay-window 4 replay-oseq 0x4 \
-	    auth-trunc 'hmac(md5)' ${AUTH_1} 96 \
-	    enc 'cbc(des3_ede)' ${ENC_1} \
+	    auth-trunc 'hmac(sha1)' ${AUTH_1} 96 \
+	    enc 'cbc(aes)' ${ENC_1} \
 	    sel src ${h1_6} dst ${h2_6} ${devarg}
 
 	ip -6 -netns host2 xfrm state add src ${HOST1_6} dst ${HOST2_6} \
 	    proto esp spi ${SPI_1} reqid 0 mode tunnel \
 	    replay-window 4 replay-oseq 0x4 \
-	    auth-trunc 'hmac(md5)' ${AUTH_1} 96 \
-	    enc 'cbc(des3_ede)' ${ENC_1} \
+	    auth-trunc 'hmac(sha1)' ${AUTH_1} 96 \
+	    enc 'cbc(aes)' ${ENC_1} \
 	    sel src ${h1_6} dst ${h2_6}
 
 
 	ip -6 -netns host1 xfrm state add src ${HOST2_6} dst ${HOST1_6} \
 	    proto esp spi ${SPI_2} reqid 0 mode tunnel \
 	    replay-window 4 replay-oseq 0x4 \
-	    auth-trunc 'hmac(md5)' ${AUTH_2} 96 \
-	    enc 'cbc(des3_ede)' ${ENC_2} \
+	    auth-trunc 'hmac(sha1)' ${AUTH_2} 96 \
+	    enc 'cbc(aes)' ${ENC_2} \
 	    sel src ${h2_6} dst ${h1_6} ${devarg}
 
 	ip -6 -netns host2 xfrm state add src ${HOST2_6} dst ${HOST1_6} \
 	    proto esp spi ${SPI_2} reqid 0 mode tunnel \
 	    replay-window 4 replay-oseq 0x4 \
-	    auth-trunc 'hmac(md5)' ${AUTH_2} 96 \
-	    enc 'cbc(des3_ede)' ${ENC_2} \
+	    auth-trunc 'hmac(sha1)' ${AUTH_2} 96 \
+	    enc 'cbc(aes)' ${ENC_2} \
 	    sel src ${h2_6} dst ${h1_6}
 }
 
diff --git a/kernel/tools/testing/selftests/netfilter/conntrack_icmp_related.sh b/kernel/tools/testing/selftests/netfilter/conntrack_icmp_related.sh
index b48e183..76645aa 100755
--- a/kernel/tools/testing/selftests/netfilter/conntrack_icmp_related.sh
+++ b/kernel/tools/testing/selftests/netfilter/conntrack_icmp_related.sh
@@ -35,6 +35,8 @@
 	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 @@
 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 @@
 	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
diff --git a/kernel/tools/testing/selftests/netfilter/nft_nat.sh b/kernel/tools/testing/selftests/netfilter/nft_nat.sh
index 4e15e81..67697d8 100755
--- a/kernel/tools/testing/selftests/netfilter/nft_nat.sh
+++ b/kernel/tools/testing/selftests/netfilter/nft_nat.sh
@@ -404,6 +404,8 @@
 	echo SERVER-$family | ip netns exec "$ns1" timeout 5 socat -u STDIN TCP-LISTEN:2000 &
 	sc_s=$!
 
+	sleep 1
+
 	result=$(ip netns exec "$ns0" timeout 1 socat TCP:$daddr:2000 STDOUT)
 
 	if [ "$result" = "SERVER-inet" ];then
diff --git a/kernel/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c b/kernel/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
index fbbdffd..f20d1c1 100644
--- a/kernel/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
+++ b/kernel/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
@@ -24,6 +24,7 @@
 	rc = read(fd, buf, sizeof(buf));
 	if (rc == -1) {
 		perror("read() failed");
+		close(fd);
 		return 1;
 	}
 	close(fd);
@@ -65,8 +66,10 @@
 		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;
diff --git a/kernel/tools/testing/selftests/proc/proc-uptime-002.c b/kernel/tools/testing/selftests/proc/proc-uptime-002.c
index e7ceabe..7d0aa22 100644
--- a/kernel/tools/testing/selftests/proc/proc-uptime-002.c
+++ b/kernel/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 @@
 		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);
diff --git a/kernel/tools/testing/selftests/ptp/testptp.c b/kernel/tools/testing/selftests/ptp/testptp.c
index f7911aa..aa474fe 100644
--- a/kernel/tools/testing/selftests/ptp/testptp.c
+++ b/kernel/tools/testing/selftests/ptp/testptp.c
@@ -492,11 +492,11 @@
 			interval = t2 - t1;
 			offset = (t2 + t1) / 2 - tp;
 
-			printf("system time: %lld.%u\n",
+			printf("system time: %lld.%09u\n",
 				(pct+2*i)->sec, (pct+2*i)->nsec);
-			printf("phc    time: %lld.%u\n",
+			printf("phc    time: %lld.%09u\n",
 				(pct+2*i+1)->sec, (pct+2*i+1)->nsec);
-			printf("system time: %lld.%u\n",
+			printf("system time: %lld.%09u\n",
 				(pct+2*i+2)->sec, (pct+2*i+2)->nsec);
 			printf("system/phc clock time offset is %" PRId64 " ns\n"
 			       "system     clock time delay  is %" PRId64 " ns\n",
diff --git a/kernel/tools/testing/selftests/rcutorture/bin/console-badness.sh b/kernel/tools/testing/selftests/rcutorture/bin/console-badness.sh
index 0e4c0b2..80ae7f0 100755
--- a/kernel/tools/testing/selftests/rcutorture/bin/console-badness.sh
+++ b/kernel/tools/testing/selftests/rcutorture/bin/console-badness.sh
@@ -13,4 +13,5 @@
 egrep 'Badness|WARNING:|Warn|BUG|===========|Call Trace:|Oops:|detected stalls on CPUs/tasks:|self-detected stall on CPU|Stall ended before state dump start|\?\?\? Writer stall state|rcu_.*kthread starved for|!!!' |
 grep -v 'ODEBUG: ' |
 grep -v 'This means that this is a DEBUG kernel and it is' |
-grep -v 'Warning: unable to open an initial console'
+grep -v 'Warning: unable to open an initial console' |
+grep -v 'NOHZ tick-stop error: Non-RCU local softirq work is pending, handler'
diff --git a/kernel/tools/testing/selftests/resctrl/cache.c b/kernel/tools/testing/selftests/resctrl/cache.c
index 5922cc1..b3c0e85 100644
--- a/kernel/tools/testing/selftests/resctrl/cache.c
+++ b/kernel/tools/testing/selftests/resctrl/cache.c
@@ -89,21 +89,19 @@
 static int get_llc_perf(unsigned long *llc_perf_miss)
 {
 	__u64 total_misses;
+	int ret;
 
 	/* Stop counters after one span to get miss rate */
 
 	ioctl(fd_lm, PERF_EVENT_IOC_DISABLE, 0);
 
-	if (read(fd_lm, &rf_cqm, sizeof(struct read_format)) == -1) {
+	ret = read(fd_lm, &rf_cqm, sizeof(struct read_format));
+	if (ret == -1) {
 		perror("Could not get llc misses through perf");
-
 		return -1;
 	}
 
 	total_misses = rf_cqm.values[0].value;
-
-	close(fd_lm);
-
 	*llc_perf_miss = total_misses;
 
 	return 0;
@@ -256,17 +254,23 @@
 					 memflush, operation, resctrl_val)) {
 				fprintf(stderr, "Error-running fill buffer\n");
 				ret = -1;
-				break;
+				goto pe_close;
 			}
 
 			sleep(1);
 			ret = measure_cache_vals(param, bm_pid);
 			if (ret)
-				break;
+				goto pe_close;
+
+			close(fd_lm);
 		} else {
 			break;
 		}
 	}
 
 	return ret;
+
+pe_close:
+	close(fd_lm);
+	return ret;
 }
diff --git a/kernel/tools/testing/selftests/resctrl/fill_buf.c b/kernel/tools/testing/selftests/resctrl/fill_buf.c
index 56ccbea..ab1d913 100644
--- a/kernel/tools/testing/selftests/resctrl/fill_buf.c
+++ b/kernel/tools/testing/selftests/resctrl/fill_buf.c
@@ -68,6 +68,8 @@
 	size_t s64;
 
 	void *p = memalign(PAGE_SIZE, s);
+	if (!p)
+		return NULL;
 
 	p64 = (uint64_t *)p;
 	s64 = s / sizeof(uint64_t);
@@ -182,12 +184,13 @@
 	else
 		ret = fill_cache_write(start_ptr, end_ptr, resctrl_val);
 
+	free(startptr);
+
 	if (ret) {
 		printf("\n Error in fill cache read/write...\n");
 		return -1;
 	}
 
-	free(startptr);
 
 	return 0;
 }
diff --git a/kernel/tools/testing/selftests/resctrl/mba_test.c b/kernel/tools/testing/selftests/resctrl/mba_test.c
index 6449fbd..6cfddd1 100644
--- a/kernel/tools/testing/selftests/resctrl/mba_test.c
+++ b/kernel/tools/testing/selftests/resctrl/mba_test.c
@@ -28,6 +28,7 @@
 	struct resctrl_val_param *p;
 	char allocation_str[64];
 	va_list param;
+	int ret;
 
 	va_start(param, num);
 	p = va_arg(param, struct resctrl_val_param *);
@@ -45,7 +46,11 @@
 
 	sprintf(allocation_str, "%d", allocation);
 
-	write_schemata(p->ctrlgrp, allocation_str, p->cpu_no, p->resctrl_val);
+	ret = write_schemata(p->ctrlgrp, allocation_str, p->cpu_no,
+			     p->resctrl_val);
+	if (ret < 0)
+		return ret;
+
 	allocation -= ALLOCATION_STEP;
 
 	return 0;
diff --git a/kernel/tools/testing/selftests/resctrl/resctrl.h b/kernel/tools/testing/selftests/resctrl/resctrl.h
index 36da613..c38f2d5 100644
--- a/kernel/tools/testing/selftests/resctrl/resctrl.h
+++ b/kernel/tools/testing/selftests/resctrl/resctrl.h
@@ -33,6 +33,7 @@
 	do {					\
 		perror(err_msg);		\
 		kill(ppid, SIGKILL);		\
+		umount_resctrlfs();		\
 		exit(EXIT_FAILURE);		\
 	} while (0)
 
diff --git a/kernel/tools/testing/selftests/rseq/Makefile b/kernel/tools/testing/selftests/rseq/Makefile
index 215e106..82ceca6 100644
--- a/kernel/tools/testing/selftests/rseq/Makefile
+++ b/kernel/tools/testing/selftests/rseq/Makefile
@@ -4,8 +4,10 @@
 CLANG_FLAGS += -no-integrated-as
 endif
 
+top_srcdir = ../../../..
+
 CFLAGS += -O2 -Wall -g -I./ -I../../../../usr/include/ -L$(OUTPUT) -Wl,-rpath=./ \
-	  $(CLANG_FLAGS)
+	  $(CLANG_FLAGS) -I$(top_srcdir)/tools/include
 LDLIBS += -lpthread -ldl
 
 # Own dependencies because we only want to build against 1st prerequisite, but
diff --git a/kernel/tools/testing/selftests/rseq/rseq.c b/kernel/tools/testing/selftests/rseq/rseq.c
index 986b945..e20191f 100644
--- a/kernel/tools/testing/selftests/rseq/rseq.c
+++ b/kernel/tools/testing/selftests/rseq/rseq.c
@@ -29,12 +29,22 @@
 #include <dlfcn.h>
 #include <stddef.h>
 
+#include <linux/compiler.h>
+
 #include "../kselftest.h"
 #include "rseq.h"
 
-static const ptrdiff_t *libc_rseq_offset_p;
-static const unsigned int *libc_rseq_size_p;
-static const unsigned int *libc_rseq_flags_p;
+/*
+ * Define weak versions to play nice with binaries that are statically linked
+ * against a libc that doesn't support registering its own rseq.
+ */
+__weak ptrdiff_t __rseq_offset;
+__weak unsigned int __rseq_size;
+__weak unsigned int __rseq_flags;
+
+static const ptrdiff_t *libc_rseq_offset_p = &__rseq_offset;
+static const unsigned int *libc_rseq_size_p = &__rseq_size;
+static const unsigned int *libc_rseq_flags_p = &__rseq_flags;
 
 /* Offset from the thread pointer to the rseq area.  */
 ptrdiff_t rseq_offset;
@@ -108,10 +118,19 @@
 static __attribute__((constructor))
 void rseq_init(void)
 {
-	libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset");
-	libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size");
-	libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags");
-	if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p) {
+	/*
+	 * If the libc's registered rseq size isn't already valid, it may be
+	 * because the binary is dynamically linked and not necessarily due to
+	 * libc not having registered a restartable sequence.  Try to find the
+	 * symbols if that's the case.
+	 */
+	if (!*libc_rseq_size_p) {
+		libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset");
+		libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size");
+		libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags");
+	}
+	if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p &&
+			*libc_rseq_size_p != 0) {
 		/* rseq registration owned by glibc */
 		rseq_offset = *libc_rseq_offset_p;
 		rseq_size = *libc_rseq_size_p;
diff --git a/kernel/tools/testing/selftests/sigaltstack/current_stack_pointer.h b/kernel/tools/testing/selftests/sigaltstack/current_stack_pointer.h
new file mode 100644
index 0000000..ea9bdf3
--- /dev/null
+++ b/kernel/tools/testing/selftests/sigaltstack/current_stack_pointer.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#if __alpha__
+register unsigned long sp asm("$30");
+#elif __arm__ || __aarch64__ || __csky__ || __m68k__ || __mips__ || __riscv
+register unsigned long sp asm("sp");
+#elif __i386__
+register unsigned long sp asm("esp");
+#elif __loongarch64
+register unsigned long sp asm("$sp");
+#elif __ppc__
+register unsigned long sp asm("r1");
+#elif __s390x__
+register unsigned long sp asm("%15");
+#elif __sh__
+register unsigned long sp asm("r15");
+#elif __x86_64__
+register unsigned long sp asm("rsp");
+#elif __XTENSA__
+register unsigned long sp asm("a1");
+#else
+#error "implement current_stack_pointer equivalent"
+#endif
diff --git a/kernel/tools/testing/selftests/sigaltstack/sas.c b/kernel/tools/testing/selftests/sigaltstack/sas.c
index 8934a37..41646c2 100644
--- a/kernel/tools/testing/selftests/sigaltstack/sas.c
+++ b/kernel/tools/testing/selftests/sigaltstack/sas.c
@@ -19,6 +19,7 @@
 #include <errno.h>
 
 #include "../kselftest.h"
+#include "current_stack_pointer.h"
 
 #ifndef SS_AUTODISARM
 #define SS_AUTODISARM  (1U << 31)
@@ -39,12 +40,6 @@
 	int err;
 	stack_t stk;
 	struct stk_data *p;
-
-#if __s390x__
-	register unsigned long sp asm("%15");
-#else
-	register unsigned long sp asm("sp");
-#endif
 
 	if (sp < (unsigned long)sstack ||
 			sp >= (unsigned long)sstack + SIGSTKSZ) {
diff --git a/kernel/tools/testing/selftests/tc-testing/config b/kernel/tools/testing/selftests/tc-testing/config
index b71828d..5f581c3 100644
--- a/kernel/tools/testing/selftests/tc-testing/config
+++ b/kernel/tools/testing/selftests/tc-testing/config
@@ -5,6 +5,7 @@
 CONFIG_NF_CONNTRACK_MARK=y
 CONFIG_NF_CONNTRACK_ZONES=y
 CONFIG_NF_CONNTRACK_LABELS=y
+CONFIG_NF_FLOW_TABLE=m
 CONFIG_NF_NAT=m
 
 CONFIG_NET_SCHED=y
diff --git a/kernel/tools/testing/selftests/tc-testing/settings b/kernel/tools/testing/selftests/tc-testing/settings
new file mode 100644
index 0000000..e220626
--- /dev/null
+++ b/kernel/tools/testing/selftests/tc-testing/settings
@@ -0,0 +1 @@
+timeout=900
diff --git a/kernel/tools/testing/selftests/wireguard/netns.sh b/kernel/tools/testing/selftests/wireguard/netns.sh
index 8a9461a..93e4441 100755
--- a/kernel/tools/testing/selftests/wireguard/netns.sh
+++ b/kernel/tools/testing/selftests/wireguard/netns.sh
@@ -502,10 +502,32 @@
 n1 ping -W 1 -c 1 192.168.241.2
 [[ $(n2 wg show wg0 endpoints) == "$pub1	10.0.0.3:1" ]]
 
-ip1 link del veth1
-ip1 link del veth3
-ip1 link del wg0
-ip2 link del wg0
+ip1 link del dev veth3
+ip1 link del dev wg0
+ip2 link del dev wg0
+
+# Make sure persistent keep alives are sent when an adapter comes up
+ip1 link add dev wg0 type wireguard
+n1 wg set wg0 private-key <(echo "$key1") peer "$pub2" endpoint 10.0.0.1:1 persistent-keepalive 1
+read _ _ tx_bytes < <(n1 wg show wg0 transfer)
+[[ $tx_bytes -eq 0 ]]
+ip1 link set dev wg0 up
+read _ _ tx_bytes < <(n1 wg show wg0 transfer)
+[[ $tx_bytes -gt 0 ]]
+ip1 link del dev wg0
+# This should also happen even if the private key is set later
+ip1 link add dev wg0 type wireguard
+n1 wg set wg0 peer "$pub2" endpoint 10.0.0.1:1 persistent-keepalive 1
+read _ _ tx_bytes < <(n1 wg show wg0 transfer)
+[[ $tx_bytes -eq 0 ]]
+ip1 link set dev wg0 up
+read _ _ tx_bytes < <(n1 wg show wg0 transfer)
+[[ $tx_bytes -eq 0 ]]
+n1 wg set wg0 private-key <(echo "$key1")
+read _ _ tx_bytes < <(n1 wg show wg0 transfer)
+[[ $tx_bytes -gt 0 ]]
+ip1 link del dev veth1
+ip1 link del dev wg0
 
 # We test that Netlink/IPC is working properly by doing things that usually cause split responses
 ip0 link add dev wg0 type wireguard
diff --git a/kernel/tools/virtio/linux/bug.h b/kernel/tools/virtio/linux/bug.h
index b14c2c3..74aef96 100644
--- a/kernel/tools/virtio/linux/bug.h
+++ b/kernel/tools/virtio/linux/bug.h
@@ -1,11 +1,9 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef BUG_H
-#define BUG_H
+#ifndef _LINUX_BUG_H
+#define _LINUX_BUG_H
 
 #define BUG_ON(__BUG_ON_cond) assert(!(__BUG_ON_cond))
 
-#define BUILD_BUG_ON(x)
-
 #define BUG() abort()
 
-#endif /* BUG_H */
+#endif /* _LINUX_BUG_H */
diff --git a/kernel/tools/virtio/linux/build_bug.h b/kernel/tools/virtio/linux/build_bug.h
new file mode 100644
index 0000000..cdbb75e
--- /dev/null
+++ b/kernel/tools/virtio/linux/build_bug.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_BUILD_BUG_H
+#define _LINUX_BUILD_BUG_H
+
+#define BUILD_BUG_ON(x)
+
+#endif	/* _LINUX_BUILD_BUG_H */
diff --git a/kernel/tools/virtio/linux/cpumask.h b/kernel/tools/virtio/linux/cpumask.h
new file mode 100644
index 0000000..307da69
--- /dev/null
+++ b/kernel/tools/virtio/linux/cpumask.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_CPUMASK_H
+#define _LINUX_CPUMASK_H
+
+#include <linux/kernel.h>
+
+#endif /* _LINUX_CPUMASK_H */
diff --git a/kernel/tools/virtio/linux/gfp.h b/kernel/tools/virtio/linux/gfp.h
new file mode 100644
index 0000000..43d146f
--- /dev/null
+++ b/kernel/tools/virtio/linux/gfp.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_GFP_H
+#define __LINUX_GFP_H
+
+#include <linux/topology.h>
+
+#endif
diff --git a/kernel/tools/virtio/linux/kernel.h b/kernel/tools/virtio/linux/kernel.h
index 315e85c..063ccc8 100644
--- a/kernel/tools/virtio/linux/kernel.h
+++ b/kernel/tools/virtio/linux/kernel.h
@@ -10,6 +10,7 @@
 #include <stdarg.h>
 
 #include <linux/compiler.h>
+#include <linux/log2.h>
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/printk.h>
diff --git a/kernel/tools/virtio/linux/kmsan.h b/kernel/tools/virtio/linux/kmsan.h
new file mode 100644
index 0000000..272b5aa
--- /dev/null
+++ b/kernel/tools/virtio/linux/kmsan.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_KMSAN_H
+#define _LINUX_KMSAN_H
+
+#include <linux/gfp.h>
+
+inline void kmsan_handle_dma(struct page *page, size_t offset, size_t size,
+			     enum dma_data_direction dir)
+{
+}
+
+#endif /* _LINUX_KMSAN_H */
diff --git a/kernel/tools/virtio/linux/scatterlist.h b/kernel/tools/virtio/linux/scatterlist.h
index 369ee30..74d9e18 100644
--- a/kernel/tools/virtio/linux/scatterlist.h
+++ b/kernel/tools/virtio/linux/scatterlist.h
@@ -2,6 +2,7 @@
 #ifndef SCATTERLIST_H
 #define SCATTERLIST_H
 #include <linux/kernel.h>
+#include <linux/bug.h>
 
 struct scatterlist {
 	unsigned long	page_link;
diff --git a/kernel/tools/virtio/linux/topology.h b/kernel/tools/virtio/linux/topology.h
new file mode 100644
index 0000000..910794a
--- /dev/null
+++ b/kernel/tools/virtio/linux/topology.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_TOPOLOGY_H
+#define _LINUX_TOPOLOGY_H
+
+#include <linux/cpumask.h>
+
+#endif /* _LINUX_TOPOLOGY_H */
diff --git a/kernel/tools/virtio/vringh_test.c b/kernel/tools/virtio/vringh_test.c
index fa87b58..98ff808 100644
--- a/kernel/tools/virtio/vringh_test.c
+++ b/kernel/tools/virtio/vringh_test.c
@@ -308,6 +308,7 @@
 
 		gvdev.vdev.features = features;
 		INIT_LIST_HEAD(&gvdev.vdev.vqs);
+		spin_lock_init(&gvdev.vdev.vqs_list_lock);
 		gvdev.to_host_fd = to_host[1];
 		gvdev.notifies = 0;
 
@@ -455,6 +456,7 @@
 	getrange = getrange_iov;
 	vdev.features = 0;
 	INIT_LIST_HEAD(&vdev.vqs);
+	spin_lock_init(&vdev.vqs_list_lock);
 
 	while (argv[1]) {
 		if (strcmp(argv[1], "--indirect") == 0)
diff --git a/kernel/virt/kvm/coalesced_mmio.c b/kernel/virt/kvm/coalesced_mmio.c
index d5bebb3..ce6f3b9 100644
--- a/kernel/virt/kvm/coalesced_mmio.c
+++ b/kernel/virt/kvm/coalesced_mmio.c
@@ -187,15 +187,17 @@
 			r = kvm_io_bus_unregister_dev(kvm,
 				zone->pio ? KVM_PIO_BUS : KVM_MMIO_BUS, &dev->dev);
 
+			kvm_iodevice_destructor(&dev->dev);
+
 			/*
 			 * On failure, unregister destroys all devices on the
 			 * bus _except_ the target device, i.e. coalesced_zones
-			 * has been modified.  No need to restart the walk as
-			 * there aren't any zones left.
+			 * has been modified.  Bail after destroying the target
+			 * device, there's no need to restart the walk as there
+			 * aren't any zones left.
 			 */
 			if (r)
 				break;
-			kvm_iodevice_destructor(&dev->dev);
 		}
 	}
 
diff --git a/kernel/virt/kvm/kvm_main.c b/kernel/virt/kvm/kvm_main.c
index 564d5c1..356fd5d 100644
--- a/kernel/virt/kvm/kvm_main.c
+++ b/kernel/virt/kvm/kvm_main.c
@@ -154,6 +154,8 @@
 static unsigned long long kvm_createvm_count;
 static unsigned long long kvm_active_vms;
 
+static DEFINE_PER_CPU(cpumask_var_t, cpu_kick_mask);
+
 __weak void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
 						   unsigned long start, unsigned long end)
 {
@@ -248,9 +250,13 @@
 {
 }
 
-static inline bool kvm_kick_many_cpus(const struct cpumask *cpus, bool wait)
+static inline bool kvm_kick_many_cpus(cpumask_var_t tmp, bool wait)
 {
-	if (unlikely(!cpus))
+	const struct cpumask *cpus;
+
+	if (likely(cpumask_available(tmp)))
+		cpus = tmp;
+	else
 		cpus = cpu_online_mask;
 
 	if (cpumask_empty(cpus))
@@ -260,30 +266,57 @@
 	return true;
 }
 
+static void kvm_make_vcpu_request(struct kvm *kvm, struct kvm_vcpu *vcpu,
+				  unsigned int req, cpumask_var_t tmp,
+				  int current_cpu)
+{
+	int cpu;
+
+	kvm_make_request(req, vcpu);
+
+	if (!(req & KVM_REQUEST_NO_WAKEUP) && kvm_vcpu_wake_up(vcpu))
+		return;
+
+	/*
+	 * tmp can be "unavailable" if cpumasks are allocated off stack as
+	 * allocation of the mask is deliberately not fatal and is handled by
+	 * falling back to kicking all online CPUs.
+	 */
+	if (!cpumask_available(tmp))
+		return;
+
+	/*
+	 * Note, the vCPU could get migrated to a different pCPU at any point
+	 * after kvm_request_needs_ipi(), which could result in sending an IPI
+	 * to the previous pCPU.  But, that's OK because the purpose of the IPI
+	 * is to ensure the vCPU returns to OUTSIDE_GUEST_MODE, which is
+	 * satisfied if the vCPU migrates. Entering READING_SHADOW_PAGE_TABLES
+	 * after this point is also OK, as the requirement is only that KVM wait
+	 * for vCPUs that were reading SPTEs _before_ any changes were
+	 * finalized. See kvm_vcpu_kick() for more details on handling requests.
+	 */
+	if (kvm_request_needs_ipi(vcpu, req)) {
+		cpu = READ_ONCE(vcpu->cpu);
+		if (cpu != -1 && cpu != current_cpu)
+			__cpumask_set_cpu(cpu, tmp);
+	}
+}
+
 bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req,
 				 struct kvm_vcpu *except,
 				 unsigned long *vcpu_bitmap, cpumask_var_t tmp)
 {
-	int i, cpu, me;
 	struct kvm_vcpu *vcpu;
+	int i, me;
 	bool called;
 
 	me = get_cpu();
 
-	kvm_for_each_vcpu(i, vcpu, kvm) {
-		if ((vcpu_bitmap && !test_bit(i, vcpu_bitmap)) ||
-		    vcpu == except)
+	for_each_set_bit(i, vcpu_bitmap, KVM_MAX_VCPUS) {
+		vcpu = kvm_get_vcpu(kvm, i);
+		if (!vcpu || vcpu == except)
 			continue;
-
-		kvm_make_request(req, vcpu);
-		cpu = vcpu->cpu;
-
-		if (!(req & KVM_REQUEST_NO_WAKEUP) && kvm_vcpu_wake_up(vcpu))
-			continue;
-
-		if (tmp != NULL && cpu != -1 && cpu != me &&
-		    kvm_request_needs_ipi(vcpu, req))
-			__cpumask_set_cpu(cpu, tmp);
+		kvm_make_vcpu_request(kvm, vcpu, req, tmp, me);
 	}
 
 	called = kvm_kick_many_cpus(tmp, !!(req & KVM_REQUEST_WAIT));
@@ -295,14 +328,25 @@
 bool kvm_make_all_cpus_request_except(struct kvm *kvm, unsigned int req,
 				      struct kvm_vcpu *except)
 {
-	cpumask_var_t cpus;
+	struct kvm_vcpu *vcpu;
+	struct cpumask *cpus;
 	bool called;
+	int i, me;
 
-	zalloc_cpumask_var(&cpus, GFP_ATOMIC);
+	me = get_cpu();
 
-	called = kvm_make_vcpus_request_mask(kvm, req, except, NULL, cpus);
+	cpus = this_cpu_cpumask_var_ptr(cpu_kick_mask);
+	cpumask_clear(cpus);
 
-	free_cpumask_var(cpus);
+	kvm_for_each_vcpu(i, vcpu, kvm) {
+		if (vcpu == except)
+			continue;
+		kvm_make_vcpu_request(kvm, vcpu, req, cpus, me);
+	}
+
+	called = kvm_kick_many_cpus(cpus, !!(req & KVM_REQUEST_WAIT));
+	put_cpu();
+
 	return called;
 }
 
@@ -2937,16 +2981,24 @@
  */
 void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
 {
-	int me;
-	int cpu = vcpu->cpu;
+	int me, cpu;
 
 	if (kvm_vcpu_wake_up(vcpu))
 		return;
 
+	/*
+	 * Note, the vCPU could get migrated to a different pCPU at any point
+	 * after kvm_arch_vcpu_should_kick(), which could result in sending an
+	 * IPI to the previous pCPU.  But, that's ok because the purpose of the
+	 * IPI is to force the vCPU to leave IN_GUEST_MODE, and migrating the
+	 * vCPU also requires it to leave IN_GUEST_MODE.
+	 */
 	me = get_cpu();
-	if (cpu != me && (unsigned)cpu < nr_cpu_ids && cpu_online(cpu))
-		if (kvm_arch_vcpu_should_kick(vcpu))
+	if (kvm_arch_vcpu_should_kick(vcpu)) {
+		cpu = READ_ONCE(vcpu->cpu);
+		if (cpu != me && (unsigned)cpu < nr_cpu_ids && cpu_online(cpu))
 			smp_send_reschedule(cpu);
+	}
 	put_cpu();
 }
 EXPORT_SYMBOL_GPL(kvm_vcpu_kick);
@@ -4952,19 +5004,21 @@
 		goto out_free_3;
 	}
 
+	for_each_possible_cpu(cpu) {
+		if (!alloc_cpumask_var_node(&per_cpu(cpu_kick_mask, cpu),
+					    GFP_KERNEL, cpu_to_node(cpu))) {
+			r = -ENOMEM;
+			goto out_free_4;
+		}
+	}
+
 	r = kvm_async_pf_init();
 	if (r)
-		goto out_free;
+		goto out_free_4;
 
 	kvm_chardev_ops.owner = module;
 	kvm_vm_fops.owner = module;
 	kvm_vcpu_fops.owner = module;
-
-	r = misc_register(&kvm_dev);
-	if (r) {
-		pr_err("kvm: misc device register failed\n");
-		goto out_unreg;
-	}
 
 	register_syscore_ops(&kvm_syscore_ops);
 
@@ -4974,13 +5028,28 @@
 	kvm_init_debug();
 
 	r = kvm_vfio_ops_init();
-	WARN_ON(r);
+	if (WARN_ON_ONCE(r))
+		goto err_vfio;
+
+	/*
+	 * Registration _must_ be the very last thing done, as this exposes
+	 * /dev/kvm to userspace, i.e. all infrastructure must be setup!
+	 */
+	r = misc_register(&kvm_dev);
+	if (r) {
+		pr_err("kvm: misc device register failed\n");
+		goto err_register;
+	}
 
 	return 0;
 
-out_unreg:
+err_register:
+	kvm_vfio_ops_exit();
+err_vfio:
 	kvm_async_pf_deinit();
-out_free:
+out_free_4:
+	for_each_possible_cpu(cpu)
+		free_cpumask_var(per_cpu(cpu_kick_mask, cpu));
 	kmem_cache_destroy(kvm_vcpu_cache);
 out_free_3:
 	unregister_reboot_notifier(&kvm_reboot_notifier);
@@ -5000,8 +5069,18 @@
 
 void kvm_exit(void)
 {
-	debugfs_remove_recursive(kvm_debugfs_dir);
+	int cpu;
+
+	/*
+	 * Note, unregistering /dev/kvm doesn't strictly need to come first,
+	 * fops_get(), a.k.a. try_module_get(), prevents acquiring references
+	 * to KVM while the module is being stopped.
+	 */
 	misc_deregister(&kvm_dev);
+
+	debugfs_remove_recursive(kvm_debugfs_dir);
+	for_each_possible_cpu(cpu)
+		free_cpumask_var(per_cpu(cpu_kick_mask, cpu));
 	kmem_cache_destroy(kvm_vcpu_cache);
 	kvm_async_pf_deinit();
 	unregister_syscore_ops(&kvm_syscore_ops);
diff --git a/mk-rootfs.sh b/mk-rootfs.sh
index 9fa307e..ce53da8 100755
--- a/mk-rootfs.sh
+++ b/mk-rootfs.sh
@@ -1,8 +1,8 @@
 #!/bin/bash -e
 #TARGET_ROOTFS_DIR=/home/data/rootfs/rk356x/ubuntu20-lxde/lxde_ubuntu20_rootfs
 #TARGET_ROOTFS_DIR=/home/data/rootfs/rk356x/debian10/rk3568_likong
-#TARGET_ROOTFS_DIR=/home/data/rootfs/rk356x/debian11/debian11_rootfs
-TARGET_ROOTFS_DIR=/home/data/rootfs/rk356x/debian10/debian_rootfs_jrty
+TARGET_ROOTFS_DIR=/home/data/rootfs/rk356x/debian11/debian11_5.10
+#TARGET_ROOTFS_DIR=/home/data/rootfs/rk356x/debian10/debian_rootfs_jrty
 MOUNTPOINT=./temp
 ROOTFSIMAGE=rootfs.ext4
 OUT=$PWD/tools/linux/Linux_Pack_Firmware/rockdev/Image/
diff --git a/rockdev/baseparameter b/rockdev/baseparameter
index d4988d2..2a68a95 100644
--- a/rockdev/baseparameter
+++ b/rockdev/baseparameter
Binary files differ

--
Gitblit v1.6.2